From 1982d871475ffb8c2c160a96916a76fdcb6eb11c Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 18 Jan 2025 15:37:14 -0500 Subject: [PATCH 0001/3801] Merge commit '3383cfbd3572465febc7a8f816a46304373de46a' into sync-from-portable-simd-2025-01-18 --- .github/workflows/ci.yml | 125 +++++----- .github/workflows/doc.yml | 2 +- .gitignore | 1 + Cargo.toml | 6 + Cross.toml | 2 + crates/core_simd/Cargo.toml | 3 +- crates/core_simd/src/lane_count.rs | 8 +- crates/core_simd/src/lib.rs | 4 +- crates/core_simd/src/masks.rs | 42 ---- crates/core_simd/src/masks/bitmask.rs | 17 -- crates/core_simd/src/masks/full_masks.rs | 58 +---- crates/core_simd/src/ops.rs | 25 +- crates/core_simd/src/simd/cmp/eq.rs | 2 +- crates/core_simd/src/simd/num/float.rs | 30 ++- crates/core_simd/src/simd/num/int.rs | 43 +++- crates/core_simd/src/simd/num/uint.rs | 42 +++- crates/core_simd/src/simd/ptr/const_ptr.rs | 21 ++ crates/core_simd/src/simd/ptr/mut_ptr.rs | 21 ++ crates/core_simd/src/swizzle.rs | 257 ++++++++++++++++++++- crates/core_simd/src/swizzle_dyn.rs | 59 ++++- crates/core_simd/src/vector.rs | 43 +++- crates/core_simd/src/vendor.rs | 3 + crates/core_simd/src/vendor/loongarch64.rs | 31 +++ crates/core_simd/tests/layout.rs | 35 +++ crates/core_simd/tests/masks.rs | 43 ---- crates/core_simd/tests/ops_macros.rs | 38 +++ crates/core_simd/tests/swizzle.rs | 18 ++ crates/test_helpers/Cargo.toml | 3 - crates/test_helpers/src/lib.rs | 216 ++++++++--------- rust-toolchain.toml | 3 + subtree-sync.sh | 52 +++++ 31 files changed, 865 insertions(+), 388 deletions(-) create mode 100644 Cross.toml create mode 100644 crates/core_simd/src/vendor/loongarch64.rs create mode 100644 crates/core_simd/tests/layout.rs create mode 100644 rust-toolchain.toml create mode 100755 subtree-sync.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b292be2d6f99..3984d8f0d8d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,7 @@ on: env: CARGO_NET_RETRY: 10 RUSTUP_MAX_RETRIES: 10 + PROPTEST_CASES: 64 jobs: rustfmt: @@ -16,12 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - rustup component add rustfmt + - uses: actions/checkout@v4 - name: Run rustfmt run: cargo fmt --all -- --check @@ -37,7 +33,9 @@ jobs: - i686-unknown-linux-gnu - i586-unknown-linux-gnu - aarch64-unknown-linux-gnu + - arm64ec-pc-windows-msvc - armv7-unknown-linux-gnueabihf + - loongarch64-unknown-linux-gnu # non-nightly since https://github.com/rust-lang/rust/pull/113274 # - mips-unknown-linux-gnu # - mips64-unknown-linux-gnuabi64 @@ -49,13 +47,9 @@ jobs: - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - rustup target add ${{ matrix.target }} - rustup component add clippy + run: rustup target add ${{ matrix.target }} - name: Run Clippy run: cargo clippy --all-targets --target ${{ matrix.target }} @@ -65,26 +59,19 @@ jobs: strategy: fail-fast: false matrix: - target: [x86_64-pc-windows-msvc, i686-pc-windows-msvc, i586-pc-windows-msvc, x86_64-unknown-linux-gnu, x86_64-apple-darwin] + target: [x86_64-pc-windows-msvc, i686-pc-windows-msvc, i586-pc-windows-msvc, x86_64-unknown-linux-gnu] # `default` means we use the default target config for the target, # `native` means we run with `-Ctarget-cpu=native`, and anything else is # an arg to `-Ctarget-feature` target_feature: [default, native, +sse3, +ssse3, +sse4.1, +sse4.2, +avx, +avx2] exclude: - # The macos runners seem to only reliably support up to `avx`. - - { target: x86_64-apple-darwin, target_feature: +avx2 } - # These features are statically known to be present for all 64 bit - # macs, and thus are covered by the `default` test - - { target: x86_64-apple-darwin, target_feature: +sse3 } - - { target: x86_64-apple-darwin, target_feature: +ssse3 } # -Ctarget-cpu=native sounds like bad-news if target != host - { target: i686-pc-windows-msvc, target_feature: native } - { target: i586-pc-windows-msvc, target_feature: native } include: # Populate the `matrix.os` field - - { target: x86_64-apple-darwin, os: macos-latest } - { target: x86_64-unknown-linux-gnu, os: ubuntu-latest } - { target: x86_64-pc-windows-msvc, os: windows-latest } - { target: i686-pc-windows-msvc, os: windows-latest } @@ -98,12 +85,9 @@ jobs: # avx512vl, but occasionally doesn't. Maybe one day we can enable it. steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - rustup target add ${{ matrix.target }} + run: rustup target add ${{ matrix.target }} - name: Configure RUSTFLAGS shell: bash @@ -145,6 +129,35 @@ jobs: run: cargo doc --verbose --target=${{ matrix.target }} env: RUSTDOCFLAGS: -Dwarnings + + macos-tests: + name: ${{ matrix.target }} + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + target: + - aarch64-apple-darwin + - x86_64-apple-darwin + steps: + - uses: actions/checkout@v4 + - name: Setup Rust + run: rustup target add ${{ matrix.target }} + + - name: Configure RUSTFLAGS + shell: bash + run: echo "RUSTFLAGS=-Dwarnings" >> $GITHUB_ENV + + - name: Test (debug) + run: cargo test --verbose --target=${{ matrix.target }} + + - name: Test (release) + run: cargo test --verbose --target=${{ matrix.target }} --release + + - name: Generate docs + run: cargo doc --verbose --target=${{ matrix.target }} + env: + RUSTDOCFLAGS: -Dwarnings wasm-tests: name: "wasm (firefox, ${{ matrix.name }})" @@ -155,11 +168,7 @@ jobs: - { name: default, RUSTFLAGS: "" } - { name: simd128, RUSTFLAGS: "-C target-feature=+simd128" } steps: - - uses: actions/checkout@v2 - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly + - uses: actions/checkout@v4 - name: Install wasm-pack run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - name: Test (debug) @@ -174,6 +183,8 @@ jobs: cross-tests: name: "${{ matrix.target_feature }} on ${{ matrix.target }} (via cross)" runs-on: ubuntu-latest + env: + PROPTEST_CASES: 16 strategy: fail-fast: false @@ -185,6 +196,7 @@ jobs: - powerpc-unknown-linux-gnu - powerpc64le-unknown-linux-gnu # includes altivec by default - riscv64gc-unknown-linux-gnu + - loongarch64-unknown-linux-gnu # MIPS uses a nonstandard binary representation for NaNs which makes it worth testing # non-nightly since https://github.com/rust-lang/rust/pull/113274 # - mips-unknown-linux-gnu @@ -201,24 +213,14 @@ jobs: # - { target: riscv64gc-unknown-linux-gnu, target_feature: "+v,+zvl128b" } steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - rustup target add ${{ matrix.target }} - rustup component add rust-src + run: rustup target add ${{ matrix.target }} - name: Install Cross - # Equivalent to `cargo install cross`, but downloading a prebuilt - # binary. Ideally we wouldn't hardcode a version, but the version number - # being part of the tarball means we can't just use the download/latest - # URL :( + # Install the latest git version for newer targets. run: | - CROSS_URL=https://github.com/cross-rs/cross/releases/download/v0.2.5/cross-x86_64-unknown-linux-gnu.tar.gz - mkdir -p "$HOME/.bin" - curl -sfSL --retry-delay 10 --retry 5 "${CROSS_URL}" | tar zxf - -C "$HOME/.bin" - echo "$HOME/.bin" >> $GITHUB_PATH + cargo install cross --git https://github.com/cross-rs/cross --rev 4090beca3cfffa44371a5bba524de3a578aa46c3 - name: Configure Emulated CPUs run: | @@ -242,34 +244,11 @@ jobs: - name: Test (release) run: cross test --verbose --target=${{ matrix.target }} --release - features: - name: "Test cargo features (${{ matrix.simd }} × ${{ matrix.features }})" + miri: runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - simd: - - "" - - "avx512" - features: - - "" - - "--features std" - - "--features all_lane_counts" - - "--all-features" - + env: + PROPTEST_CASES: 16 steps: - - uses: actions/checkout@v2 - - name: Setup Rust - run: | - rustup update nightly --no-self-update - rustup default nightly - - name: Detect AVX512 - run: echo "CPU_FEATURE=$(lscpu | grep -o avx512[a-z]* | sed s/avx/+avx/ | tr '\n' ',' )" >> $GITHUB_ENV - - name: Check build - if: ${{ matrix.simd == '' }} - run: RUSTFLAGS="-Dwarnings" cargo test --all-targets --no-default-features ${{ matrix.features }} - - name: Check AVX - if: ${{ matrix.simd == 'avx512' && contains(env.CPU_FEATURE, 'avx512') }} - run: | - echo "Found AVX features: $CPU_FEATURE" - RUSTFLAGS="-Dwarnings -Ctarget-feature=$CPU_FEATURE" cargo test --all-targets --no-default-features ${{ matrix.features }} + - uses: actions/checkout@v4 + - name: Test (Miri) + run: cargo miri test diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 9d1fa66ccb59..22c2cb3f67f1 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v1 + uses: actions/checkout@v4 - name: Setup Rust run: | diff --git a/.gitignore b/.gitignore index ea8c4bf7f35f..9673e52dcadb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +git-subtree.sh diff --git a/Cargo.toml b/Cargo.toml index d1732aaec2f9..21d4584a9f4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,9 @@ members = [ "crates/std_float", "crates/test_helpers", ] + +[profile.test.package."*"] +opt-level = 2 + +[profile.test.package.test_helpers] +opt-level = 2 diff --git a/Cross.toml b/Cross.toml new file mode 100644 index 000000000000..d21e76b92dd1 --- /dev/null +++ b/Cross.toml @@ -0,0 +1,2 @@ +[build.env] +passthrough = ["PROPTEST_CASES"] diff --git a/crates/core_simd/Cargo.toml b/crates/core_simd/Cargo.toml index b4a8fd70f4c0..a7a6d43b11d3 100644 --- a/crates/core_simd/Cargo.toml +++ b/crates/core_simd/Cargo.toml @@ -9,10 +9,9 @@ categories = ["hardware-support", "no-std"] license = "MIT OR Apache-2.0" [features] -default = ["as_crate"] +default = ["as_crate", "std"] as_crate = [] std = [] -all_lane_counts = [] [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen = "0.2" diff --git a/crates/core_simd/src/lane_count.rs b/crates/core_simd/src/lane_count.rs index 4cd7265ed671..280b27bc9bc6 100644 --- a/crates/core_simd/src/lane_count.rs +++ b/crates/core_simd/src/lane_count.rs @@ -33,10 +33,8 @@ macro_rules! supported_lane_count { }; } -supported_lane_count!(1, 2, 4, 8, 16, 32, 64); -#[cfg(feature = "all_lane_counts")] supported_lane_count!( - 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63 + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 ); diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index 992a7705e3c5..7f57847c9c23 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -1,7 +1,6 @@ #![no_std] #![feature( - const_refs_to_cell, - const_mut_refs, + const_eval_select, convert_float_to_int, core_intrinsics, decl_macro, @@ -26,6 +25,7 @@ all(target_arch = "arm", target_feature = "v7"), feature(stdarch_arm_neon_intrinsics) )] +#![cfg_attr(target_arch = "loongarch64", feature(stdarch_loongarch))] #![cfg_attr( any(target_arch = "powerpc", target_arch = "powerpc64"), feature(stdarch_powerpc) diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index 04de3a968276..b763a7c75a5a 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -308,48 +308,6 @@ where Self(mask_impl::Mask::from_bitmask_integer(bitmask)) } - /// Creates a bitmask vector from a mask. - /// - /// Each bit is set if the corresponding element in the mask is `true`. - /// The remaining bits are unset. - /// - /// The bits are packed into the first N bits of the vector: - /// ``` - /// # #![feature(portable_simd)] - /// # #[cfg(feature = "as_crate")] use core_simd::simd; - /// # #[cfg(not(feature = "as_crate"))] use core::simd; - /// # use simd::mask32x8; - /// let mask = mask32x8::from_array([true, false, true, false, false, false, true, false]); - /// assert_eq!(mask.to_bitmask_vector()[0], 0b01000101); - /// ``` - #[inline] - #[must_use = "method returns a new integer and does not mutate the original value"] - pub fn to_bitmask_vector(self) -> Simd { - self.0.to_bitmask_vector() - } - - /// Creates a mask from a bitmask vector. - /// - /// For each bit, if it is set, the corresponding element in the mask is set to `true`. - /// - /// The bits are packed into the first N bits of the vector: - /// ``` - /// # #![feature(portable_simd)] - /// # #[cfg(feature = "as_crate")] use core_simd::simd; - /// # #[cfg(not(feature = "as_crate"))] use core::simd; - /// # use simd::{mask32x8, u8x8}; - /// let bitmask = u8x8::from_array([0b01000101, 0, 0, 0, 0, 0, 0, 0]); - /// assert_eq!( - /// mask32x8::from_bitmask_vector(bitmask), - /// mask32x8::from_array([true, false, true, false, false, false, true, false]), - /// ); - /// ``` - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn from_bitmask_vector(bitmask: Simd) -> Self { - Self(mask_impl::Mask::from_bitmask_vector(bitmask)) - } - /// Finds the index of the first set element. /// /// ``` diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index 96c553426ee7..db4312d5bf88 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -122,23 +122,6 @@ where unsafe { Self(core::intrinsics::simd::simd_bitmask(value), PhantomData) } } - #[inline] - #[must_use = "method returns a new vector and does not mutate the original value"] - pub fn to_bitmask_vector(self) -> Simd { - let mut bitmask = Simd::splat(0); - bitmask.as_mut_array()[..self.0.as_ref().len()].copy_from_slice(self.0.as_ref()); - bitmask - } - - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn from_bitmask_vector(bitmask: Simd) -> Self { - let mut bytes = as SupportedLaneCount>::BitMask::default(); - let len = bytes.as_ref().len(); - bytes.as_mut().copy_from_slice(&bitmask.as_array()[..len]); - Self(bytes, PhantomData) - } - #[inline] pub fn to_bitmask_integer(self) -> u64 { let mut bitmask = [0u8; 8]; diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index 87f031a9f367..2d01946b5747 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -140,62 +140,6 @@ where unsafe { Mask(core::intrinsics::simd::simd_cast(self.0)) } } - #[inline] - #[must_use = "method returns a new vector and does not mutate the original value"] - pub fn to_bitmask_vector(self) -> Simd { - let mut bitmask = Simd::splat(0); - - // Safety: Bytes is the right size array - unsafe { - // Compute the bitmask - let mut bytes: as SupportedLaneCount>::BitMask = - core::intrinsics::simd::simd_bitmask(self.0); - - // LLVM assumes bit order should match endianness - if cfg!(target_endian = "big") { - for x in bytes.as_mut() { - *x = x.reverse_bits() - } - if N % 8 > 0 { - bytes.as_mut()[N / 8] >>= 8 - N % 8; - } - } - - bitmask.as_mut_array()[..bytes.as_ref().len()].copy_from_slice(bytes.as_ref()); - } - - bitmask - } - - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn from_bitmask_vector(bitmask: Simd) -> Self { - let mut bytes = as SupportedLaneCount>::BitMask::default(); - - // Safety: Bytes is the right size array - unsafe { - let len = bytes.as_ref().len(); - bytes.as_mut().copy_from_slice(&bitmask.as_array()[..len]); - - // LLVM assumes bit order should match endianness - if cfg!(target_endian = "big") { - for x in bytes.as_mut() { - *x = x.reverse_bits(); - } - if N % 8 > 0 { - bytes.as_mut()[N / 8] >>= 8 - N % 8; - } - } - - // Compute the regular mask - Self::from_int_unchecked(core::intrinsics::simd::simd_select_bitmask( - bytes, - Self::splat(true).to_int(), - Self::splat(false).to_int(), - )) - } - } - #[inline] unsafe fn to_bitmask_impl(self) -> U where @@ -283,7 +227,7 @@ where } #[inline] - #[must_use = "method returns a new vector and does not mutate the original value"] + #[must_use = "method returns a new bool and does not mutate the original value"] pub fn all(self) -> bool { // Safety: use `self` as an integer vector unsafe { core::intrinsics::simd::simd_reduce_all(self.to_int()) } diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index dd7303a97b19..d3bd14a34027 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -77,7 +77,7 @@ macro_rules! int_divrem_guard { ( $lhs:ident, $rhs:ident, { const PANIC_ZERO: &'static str = $zero:literal; - $simd_call:ident + $simd_call:ident, $op:tt }, $int:ident ) => { if $rhs.simd_eq(Simd::splat(0 as _)).any() { @@ -96,8 +96,23 @@ macro_rules! int_divrem_guard { // Nice base case to make it easy to const-fold away the other branch. $rhs }; - // Safety: $lhs and rhs are vectors - unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) } + + // aarch64 div fails for arbitrary `v % 0`, mod fails when rhs is MIN, for non-powers-of-two + // these operations aren't vectorized on aarch64 anyway + #[cfg(target_arch = "aarch64")] + { + let mut out = Simd::splat(0 as _); + for i in 0..Self::LEN { + out[i] = $lhs[i] $op rhs[i]; + } + out + } + + #[cfg(not(target_arch = "aarch64"))] + { + // Safety: $lhs and rhs are vectors + unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) } + } } }; } @@ -205,14 +220,14 @@ for_base_ops! { impl Div::div { int_divrem_guard { const PANIC_ZERO: &'static str = "attempt to divide by zero"; - simd_div + simd_div, / } } impl Rem::rem { int_divrem_guard { const PANIC_ZERO: &'static str = "attempt to calculate the remainder with a divisor of zero"; - simd_rem + simd_rem, % } } diff --git a/crates/core_simd/src/simd/cmp/eq.rs b/crates/core_simd/src/simd/cmp/eq.rs index 5b4615ce51d7..93989ce91b89 100644 --- a/crates/core_simd/src/simd/cmp/eq.rs +++ b/crates/core_simd/src/simd/cmp/eq.rs @@ -12,7 +12,7 @@ pub trait SimdPartialEq { #[must_use = "method returns a new mask and does not mutate the original value"] fn simd_eq(self, other: Self) -> Self::Mask; - /// Test if each element is equal to the corresponding element in `other`. + /// Test if each element is not equal to the corresponding element in `other`. #[must_use = "method returns a new mask and does not mutate the original value"] fn simd_ne(self, other: Self) -> Self::Mask; } diff --git a/crates/core_simd/src/simd/num/float.rs b/crates/core_simd/src/simd/num/float.rs index 59e43851ea8d..79954b937b39 100644 --- a/crates/core_simd/src/simd/num/float.rs +++ b/crates/core_simd/src/simd/num/float.rs @@ -255,6 +255,7 @@ macro_rules! impl_trait { type Bits = Simd<$bits_ty, N>; type Cast = Simd; + #[cfg(not(target_arch = "aarch64"))] #[inline] fn cast(self) -> Self::Cast { @@ -262,6 +263,33 @@ macro_rules! impl_trait { unsafe { core::intrinsics::simd::simd_as(self) } } + // https://github.com/llvm/llvm-project/issues/94694 + #[cfg(target_arch = "aarch64")] + #[inline] + fn cast(self) -> Self::Cast + { + const { assert!(N <= 64) }; + if N <= 2 || N == 4 || N == 8 || N == 16 || N == 32 || N == 64 { + // Safety: supported types are guaranteed by SimdCast + unsafe { core::intrinsics::simd::simd_as(self) } + } else if N < 4 { + let x = self.resize::<4>(Default::default()).cast(); + x.resize::(x[0]) + } else if N < 8 { + let x = self.resize::<8>(Default::default()).cast(); + x.resize::(x[0]) + } else if N < 16 { + let x = self.resize::<16>(Default::default()).cast(); + x.resize::(x[0]) + } else if N < 32 { + let x = self.resize::<32>(Default::default()).cast(); + x.resize::(x[0]) + } else { + let x = self.resize::<64>(Default::default()).cast(); + x.resize::(x[0]) + } + } + #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces unsafe fn to_int_unchecked(self) -> Self::Cast @@ -391,7 +419,7 @@ macro_rules! impl_trait { self.as_array().iter().sum() } else { // Safety: `self` is a float vector - unsafe { core::intrinsics::simd::simd_reduce_add_ordered(self, 0.) } + unsafe { core::intrinsics::simd::simd_reduce_add_ordered(self, -0.) } } } diff --git a/crates/core_simd/src/simd/num/int.rs b/crates/core_simd/src/simd/num/int.rs index d7598d9ceaf9..3a51235ff954 100644 --- a/crates/core_simd/src/simd/num/int.rs +++ b/crates/core_simd/src/simd/num/int.rs @@ -1,6 +1,6 @@ use super::sealed::Sealed; use crate::simd::{ - cmp::SimdPartialOrd, num::SimdUint, LaneCount, Mask, Simd, SimdCast, SimdElement, + cmp::SimdOrd, cmp::SimdPartialOrd, num::SimdUint, LaneCount, Mask, Simd, SimdCast, SimdElement, SupportedLaneCount, }; @@ -70,11 +70,27 @@ pub trait SimdInt: Copy + Sealed { /// # #[cfg(not(feature = "as_crate"))] use core::simd; /// # use simd::prelude::*; /// use core::i32::{MIN, MAX}; - /// let xs = Simd::from_array([MIN, MIN +1, -5, 0]); + /// let xs = Simd::from_array([MIN, MIN + 1, -5, 0]); /// assert_eq!(xs.abs(), Simd::from_array([MIN, MAX, 5, 0])); /// ``` fn abs(self) -> Self; + /// Lanewise absolute difference. + /// Every element becomes the absolute difference of `self` and `second`. + /// + /// # Examples + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::prelude::*; + /// use core::i32::{MIN, MAX}; + /// let a = Simd::from_array([MIN, MAX, 100, -100]); + /// let b = Simd::from_array([MAX, MIN, -80, -120]); + /// assert_eq!(a.abs_diff(b), Simd::from_array([u32::MAX, u32::MAX, 180, 20])); + /// ``` + fn abs_diff(self, second: Self) -> Self::Unsigned; + /// Lanewise saturating absolute value, implemented in Rust. /// As abs(), except the MIN value becomes MAX instead of itself. /// @@ -203,6 +219,12 @@ pub trait SimdInt: Copy + Sealed { /// The least significant bit becomes the most significant bit, second least-significant bit becomes second most-significant bit, etc. fn reverse_bits(self) -> Self; + /// Returns the number of ones in the binary representation of each element. + fn count_ones(self) -> Self::Unsigned; + + /// Returns the number of zeros in the binary representation of each element. + fn count_zeros(self) -> Self::Unsigned; + /// Returns the number of leading zeros in the binary representation of each element. fn leading_zeros(self) -> Self::Unsigned; @@ -259,6 +281,13 @@ macro_rules! impl_trait { (self^m) - m } + #[inline] + fn abs_diff(self, second: Self) -> Self::Unsigned { + let max = self.simd_max(second); + let min = self.simd_min(second); + (max - min).cast() + } + #[inline] fn saturating_abs(self) -> Self { // arith shift for -1 or 0 mask based on sign bit, giving 2s complement @@ -344,6 +373,16 @@ macro_rules! impl_trait { unsafe { core::intrinsics::simd::simd_bitreverse(self) } } + #[inline] + fn count_ones(self) -> Self::Unsigned { + self.cast::<$unsigned>().count_ones() + } + + #[inline] + fn count_zeros(self) -> Self::Unsigned { + self.cast::<$unsigned>().count_zeros() + } + #[inline] fn leading_zeros(self) -> Self::Unsigned { self.cast::<$unsigned>().leading_zeros() diff --git a/crates/core_simd/src/simd/num/uint.rs b/crates/core_simd/src/simd/num/uint.rs index 53dd97f501c6..1ab2d8c7b731 100644 --- a/crates/core_simd/src/simd/num/uint.rs +++ b/crates/core_simd/src/simd/num/uint.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount}; +use crate::simd::{cmp::SimdOrd, LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount}; /// Operations on SIMD vectors of unsigned integers. pub trait SimdUint: Copy + Sealed { @@ -57,6 +57,22 @@ pub trait SimdUint: Copy + Sealed { /// assert_eq!(sat, Simd::splat(0)); fn saturating_sub(self, second: Self) -> Self; + /// Lanewise absolute difference. + /// Every element becomes the absolute difference of `self` and `second`. + /// + /// # Examples + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::prelude::*; + /// use core::u32::MAX; + /// let a = Simd::from_array([0, MAX, 100, 20]); + /// let b = Simd::from_array([MAX, 0, 80, 200]); + /// assert_eq!(a.abs_diff(b), Simd::from_array([MAX, MAX, 20, 180])); + /// ``` + fn abs_diff(self, second: Self) -> Self; + /// Returns the sum of the elements of the vector, with wrapping addition. fn reduce_sum(self) -> Self::Scalar; @@ -85,6 +101,12 @@ pub trait SimdUint: Copy + Sealed { /// The least significant bit becomes the most significant bit, second least-significant bit becomes second most-significant bit, etc. fn reverse_bits(self) -> Self; + /// Returns the number of ones in the binary representation of each element. + fn count_ones(self) -> Self; + + /// Returns the number of zeros in the binary representation of each element. + fn count_zeros(self) -> Self; + /// Returns the number of leading zeros in the binary representation of each element. fn leading_zeros(self) -> Self; @@ -138,6 +160,13 @@ macro_rules! impl_trait { unsafe { core::intrinsics::simd::simd_saturating_sub(self, second) } } + #[inline] + fn abs_diff(self, second: Self) -> Self { + let max = self.simd_max(second); + let min = self.simd_min(second); + max - min + } + #[inline] fn reduce_sum(self) -> Self::Scalar { // Safety: `self` is an integer vector @@ -192,6 +221,17 @@ macro_rules! impl_trait { unsafe { core::intrinsics::simd::simd_bitreverse(self) } } + #[inline] + fn count_ones(self) -> Self { + // Safety: `self` is an integer vector + unsafe { core::intrinsics::simd::simd_ctpop(self) } + } + + #[inline] + fn count_zeros(self) -> Self { + (!self).count_ones() + } + #[inline] fn leading_zeros(self) -> Self { // Safety: `self` is an integer vector diff --git a/crates/core_simd/src/simd/ptr/const_ptr.rs b/crates/core_simd/src/simd/ptr/const_ptr.rs index be635ea640b8..47383809ffba 100644 --- a/crates/core_simd/src/simd/ptr/const_ptr.rs +++ b/crates/core_simd/src/simd/ptr/const_ptr.rs @@ -42,6 +42,19 @@ pub trait SimdConstPtr: Copy + Sealed { /// Equivalent to calling [`pointer::addr`] on each element. fn addr(self) -> Self::Usize; + /// Converts an address to a pointer without giving it any provenance. + /// + /// Without provenance, this pointer is not associated with any actual allocation. Such a + /// no-provenance pointer may be used for zero-sized memory accesses (if suitably aligned), but + /// non-zero-sized memory accesses with a no-provenance pointer are UB. No-provenance pointers + /// are little more than a usize address in disguise. + /// + /// This is different from [`Self::with_exposed_provenance`], which creates a pointer that picks up a + /// previously exposed provenance. + /// + /// Equivalent to calling [`core::ptr::without_provenance`] on each element. + fn without_provenance(addr: Self::Usize) -> Self; + /// Creates a new pointer with the given address. /// /// This performs the same operation as a cast, but copies the *address-space* and @@ -118,6 +131,14 @@ where unsafe { core::mem::transmute_copy(&self) } } + #[inline] + fn without_provenance(addr: Self::Usize) -> Self { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // SAFETY: Integer-to-pointer transmutes are valid (if you are okay with not getting any + // provenance). + unsafe { core::mem::transmute_copy(&addr) } + } + #[inline] fn with_addr(self, addr: Self::Usize) -> Self { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. diff --git a/crates/core_simd/src/simd/ptr/mut_ptr.rs b/crates/core_simd/src/simd/ptr/mut_ptr.rs index f6823a949e32..3f20eef21a31 100644 --- a/crates/core_simd/src/simd/ptr/mut_ptr.rs +++ b/crates/core_simd/src/simd/ptr/mut_ptr.rs @@ -39,6 +39,19 @@ pub trait SimdMutPtr: Copy + Sealed { /// Equivalent to calling [`pointer::addr`] on each element. fn addr(self) -> Self::Usize; + /// Converts an address to a pointer without giving it any provenance. + /// + /// Without provenance, this pointer is not associated with any actual allocation. Such a + /// no-provenance pointer may be used for zero-sized memory accesses (if suitably aligned), but + /// non-zero-sized memory accesses with a no-provenance pointer are UB. No-provenance pointers + /// are little more than a usize address in disguise. + /// + /// This is different from [`Self::with_exposed_provenance`], which creates a pointer that picks up a + /// previously exposed provenance. + /// + /// Equivalent to calling [`core::ptr::without_provenance`] on each element. + fn without_provenance(addr: Self::Usize) -> Self; + /// Creates a new pointer with the given address. /// /// This performs the same operation as a cast, but copies the *address-space* and @@ -115,6 +128,14 @@ where unsafe { core::mem::transmute_copy(&self) } } + #[inline] + fn without_provenance(addr: Self::Usize) -> Self { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // SAFETY: Integer-to-pointer transmutes are valid (if you are okay with not getting any + // provenance). + unsafe { core::mem::transmute_copy(&addr) } + } + #[inline] fn with_addr(self, addr: Self::Usize) -> Self { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. diff --git a/crates/core_simd/src/swizzle.rs b/crates/core_simd/src/swizzle.rs index d62642fb9061..42425ef37e50 100644 --- a/crates/core_simd/src/swizzle.rs +++ b/crates/core_simd/src/swizzle.rs @@ -155,8 +155,7 @@ pub trait Swizzle { /// Creates a new mask from the elements of `mask`. /// - /// Element `i` of the output is `concat[Self::INDEX[i]]`, where `concat` is the concatenation of - /// `first` and `second`. + /// Element `i` of the output is `mask[Self::INDEX[i]]`. #[inline] #[must_use = "method returns a new mask and does not mutate the original inputs"] fn swizzle_mask(mask: Mask) -> Mask @@ -260,6 +259,50 @@ where Rotate::::swizzle(self) } + /// Shifts the vector elements to the left by `OFFSET`, filling in with + /// `padding` from the right. + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn shift_elements_left(self, padding: T) -> Self { + struct Shift; + + impl Swizzle for Shift { + const INDEX: [usize; N] = const { + let mut index = [N; N]; + let mut i = 0; + while i + OFFSET < N { + index[i] = i + OFFSET; + i += 1; + } + index + }; + } + + Shift::::concat_swizzle(self, Simd::splat(padding)) + } + + /// Shifts the vector elements to the right by `OFFSET`, filling in with + /// `padding` from the left. + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn shift_elements_right(self, padding: T) -> Self { + struct Shift; + + impl Swizzle for Shift { + const INDEX: [usize; N] = const { + let mut index = [N; N]; + let mut i = OFFSET; + while i < N { + index[i] = i - OFFSET; + i += 1; + } + index + }; + } + + Shift::::concat_swizzle(self, Simd::splat(padding)) + } + /// Interleave two vectors. /// /// The resulting vectors contain elements taken alternatively from `self` and `other`, first @@ -320,7 +363,9 @@ where /// /// ``` /// # #![feature(portable_simd)] - /// # use core::simd::Simd; + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::Simd; /// let a = Simd::from_array([0, 4, 1, 5]); /// let b = Simd::from_array([2, 6, 3, 7]); /// let (x, y) = a.deinterleave(b); @@ -391,4 +436,210 @@ where } Resize::::concat_swizzle(self, Simd::splat(value)) } + + /// Extract a vector from another vector. + /// + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::u32x4; + /// let x = u32x4::from_array([0, 1, 2, 3]); + /// assert_eq!(x.extract::<1, 2>().to_array(), [1, 2]); + /// ``` + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn extract(self) -> Simd + where + LaneCount: SupportedLaneCount, + { + struct Extract; + impl Swizzle for Extract { + const INDEX: [usize; LEN] = const { + assert!(START + LEN <= N, "index out of bounds"); + let mut index = [0; LEN]; + let mut i = 0; + while i < LEN { + index[i] = START + i; + i += 1; + } + index + }; + } + Extract::::swizzle(self) + } +} + +impl Mask +where + T: MaskElement, + LaneCount: SupportedLaneCount, +{ + /// Reverse the order of the elements in the mask. + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn reverse(self) -> Self { + // Safety: swizzles are safe for masks + unsafe { Self::from_int_unchecked(self.to_int().reverse()) } + } + + /// Rotates the mask such that the first `OFFSET` elements of the slice move to the end + /// while the last `self.len() - OFFSET` elements move to the front. After calling `rotate_elements_left`, + /// the element previously at index `OFFSET` will become the first element in the slice. + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn rotate_elements_left(self) -> Self { + // Safety: swizzles are safe for masks + unsafe { Self::from_int_unchecked(self.to_int().rotate_elements_left::()) } + } + + /// Rotates the mask such that the first `self.len() - OFFSET` elements of the mask move to + /// the end while the last `OFFSET` elements move to the front. After calling `rotate_elements_right`, + /// the element previously at index `self.len() - OFFSET` will become the first element in the slice. + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn rotate_elements_right(self) -> Self { + // Safety: swizzles are safe for masks + unsafe { Self::from_int_unchecked(self.to_int().rotate_elements_right::()) } + } + + /// Shifts the mask elements to the left by `OFFSET`, filling in with + /// `padding` from the right. + #[inline] + #[must_use = "method returns a new mask and does not mutate the original inputs"] + pub fn shift_elements_left(self, padding: bool) -> Self { + // Safety: swizzles are safe for masks + unsafe { + Self::from_int_unchecked(self.to_int().shift_elements_left::(if padding { + T::TRUE + } else { + T::FALSE + })) + } + } + + /// Shifts the mask elements to the right by `OFFSET`, filling in with + /// `padding` from the left. + #[inline] + #[must_use = "method returns a new mask and does not mutate the original inputs"] + pub fn shift_elements_right(self, padding: bool) -> Self { + // Safety: swizzles are safe for masks + unsafe { + Self::from_int_unchecked(self.to_int().shift_elements_right::(if padding { + T::TRUE + } else { + T::FALSE + })) + } + } + + /// Interleave two masks. + /// + /// The resulting masks contain elements taken alternatively from `self` and `other`, first + /// filling the first result, and then the second. + /// + /// The reverse of this operation is [`Mask::deinterleave`]. + /// + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::mask32x4; + /// let a = mask32x4::from_array([false, true, false, true]); + /// let b = mask32x4::from_array([false, false, true, true]); + /// let (x, y) = a.interleave(b); + /// assert_eq!(x.to_array(), [false, false, true, false]); + /// assert_eq!(y.to_array(), [false, true, true, true]); + /// ``` + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn interleave(self, other: Self) -> (Self, Self) { + let (lo, hi) = self.to_int().interleave(other.to_int()); + // Safety: swizzles are safe for masks + unsafe { (Self::from_int_unchecked(lo), Self::from_int_unchecked(hi)) } + } + + /// Deinterleave two masks. + /// + /// The first result takes every other element of `self` and then `other`, starting with + /// the first element. + /// + /// The second result takes every other element of `self` and then `other`, starting with + /// the second element. + /// + /// The reverse of this operation is [`Mask::interleave`]. + /// + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::mask32x4; + /// let a = mask32x4::from_array([false, true, false, true]); + /// let b = mask32x4::from_array([false, false, true, true]); + /// let (x, y) = a.deinterleave(b); + /// assert_eq!(x.to_array(), [false, false, false, true]); + /// assert_eq!(y.to_array(), [true, true, false, true]); + /// ``` + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn deinterleave(self, other: Self) -> (Self, Self) { + let (even, odd) = self.to_int().deinterleave(other.to_int()); + // Safety: swizzles are safe for masks + unsafe { + ( + Self::from_int_unchecked(even), + Self::from_int_unchecked(odd), + ) + } + } + + /// Resize a mask. + /// + /// If `M` > `N`, extends the length of a mask, setting the new elements to `value`. + /// If `M` < `N`, truncates the mask to the first `M` elements. + /// + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::mask32x4; + /// let x = mask32x4::from_array([false, true, true, false]); + /// assert_eq!(x.resize::<8>(true).to_array(), [false, true, true, false, true, true, true, true]); + /// assert_eq!(x.resize::<2>(true).to_array(), [false, true]); + /// ``` + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn resize(self, value: bool) -> Mask + where + LaneCount: SupportedLaneCount, + { + // Safety: swizzles are safe for masks + unsafe { + Mask::::from_int_unchecked(self.to_int().resize::(if value { + T::TRUE + } else { + T::FALSE + })) + } + } + + /// Extract a vector from another vector. + /// + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::mask32x4; + /// let x = mask32x4::from_array([false, true, true, false]); + /// assert_eq!(x.extract::<1, 2>().to_array(), [true, true]); + /// ``` + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + pub fn extract(self) -> Mask + where + LaneCount: SupportedLaneCount, + { + // Safety: swizzles are safe for masks + unsafe { Mask::::from_int_unchecked(self.to_int().extract::()) } + } } diff --git a/crates/core_simd/src/swizzle_dyn.rs b/crates/core_simd/src/swizzle_dyn.rs index 3b6388d0f275..773bd028bae0 100644 --- a/crates/core_simd/src/swizzle_dyn.rs +++ b/crates/core_simd/src/swizzle_dyn.rs @@ -59,15 +59,40 @@ where target_endian = "little" ))] 16 => transize(vqtbl1q_u8, self, idxs), + #[cfg(all( + target_arch = "arm", + target_feature = "v7", + target_feature = "neon", + target_endian = "little" + ))] + 16 => transize(armv7_neon_swizzle_u8x16, self, idxs), #[cfg(all(target_feature = "avx2", not(target_feature = "avx512vbmi")))] 32 => transize(avx2_pshufb, self, idxs), #[cfg(all(target_feature = "avx512vl", target_feature = "avx512vbmi"))] - 32 => transize(x86::_mm256_permutexvar_epi8, zeroing_idxs(idxs), self), - // Notable absence: avx512bw shuffle - // If avx512bw is available, odds of avx512vbmi are good - // FIXME: initial AVX512VBMI variant didn't actually pass muster - // #[cfg(target_feature = "avx512vbmi")] - // 64 => transize(x86::_mm512_permutexvar_epi8, self, idxs), + 32 => { + // Unlike vpshufb, vpermb doesn't zero out values in the result based on the index high bit + let swizzler = |bytes, idxs| { + let mask = x86::_mm256_cmp_epu8_mask::<{ x86::_MM_CMPINT_LT }>( + idxs, + Simd::::splat(N as u8).into(), + ); + x86::_mm256_maskz_permutexvar_epi8(mask, idxs, bytes) + }; + transize(swizzler, self, idxs) + } + // Notable absence: avx512bw pshufb shuffle + #[cfg(all(target_feature = "avx512vl", target_feature = "avx512vbmi"))] + 64 => { + // Unlike vpshufb, vpermb doesn't zero out values in the result based on the index high bit + let swizzler = |bytes, idxs| { + let mask = x86::_mm512_cmp_epu8_mask::<{ x86::_MM_CMPINT_LT }>( + idxs, + Simd::::splat(N as u8).into(), + ); + x86::_mm512_maskz_permutexvar_epi8(mask, idxs, bytes) + }; + transize(swizzler, self, idxs) + } _ => { let mut array = [0; N]; for (i, k) in idxs.to_array().into_iter().enumerate() { @@ -82,6 +107,28 @@ where } } +/// armv7 neon supports swizzling `u8x16` by swizzling two u8x8 blocks +/// with a u8x8x2 lookup table. +/// +/// # Safety +/// This requires armv7 neon to work +#[cfg(all( + target_arch = "arm", + target_feature = "v7", + target_feature = "neon", + target_endian = "little" +))] +unsafe fn armv7_neon_swizzle_u8x16(bytes: Simd, idxs: Simd) -> Simd { + use core::arch::arm::{uint8x8x2_t, vcombine_u8, vget_high_u8, vget_low_u8, vtbl2_u8}; + // SAFETY: Caller promised arm neon support + unsafe { + let bytes = uint8x8x2_t(vget_low_u8(bytes.into()), vget_high_u8(bytes.into())); + let lo = vtbl2_u8(bytes, vget_low_u8(idxs.into())); + let hi = vtbl2_u8(bytes, vget_high_u8(idxs.into())); + vcombine_u8(lo, hi).into() + } +} + /// "vpshufb like it was meant to be" on AVX2 /// /// # Safety diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index 3e2391691496..9c4dd36c24fe 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -99,7 +99,7 @@ use crate::simd::{ // directly constructing an instance of the type (i.e. `let vector = Simd(array)`) should be // avoided, as it will likely become illegal on `#[repr(simd)]` structs in the future. It also // causes rustc to emit illegal LLVM IR in some cases. -#[repr(simd)] +#[repr(simd, packed)] pub struct Simd([T; N]) where LaneCount: SupportedLaneCount, @@ -144,14 +144,32 @@ where /// assert_eq!(v.as_array(), &[8, 8, 8, 8]); /// ``` #[inline] - pub fn splat(value: T) -> Self { - // This is preferred over `[value; N]`, since it's explicitly a splat: - // https://github.com/rust-lang/rust/issues/97804 - struct Splat; - impl Swizzle for Splat { - const INDEX: [usize; N] = [0; N]; + #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] + pub const fn splat(value: T) -> Self { + const fn splat_const(value: T) -> Simd + where + T: SimdElement, + LaneCount: SupportedLaneCount, + { + Simd::from_array([value; N]) } - Splat::swizzle::(Simd::::from([value])) + + fn splat_rt(value: T) -> Simd + where + T: SimdElement, + LaneCount: SupportedLaneCount, + { + // This is preferred over `[value; N]`, since it's explicitly a splat: + // https://github.com/rust-lang/rust/issues/97804 + struct Splat; + impl Swizzle for Splat { + const INDEX: [usize; N] = [0; N]; + } + + Splat::swizzle::(Simd::::from([value])) + } + + core::intrinsics::const_eval_select((value,), splat_const, splat_rt) } /// Returns an array reference containing the entire SIMD vector. @@ -425,6 +443,9 @@ where /// /// When the element is disabled, that memory location is not accessed and the corresponding /// value from `or` is passed through. + /// + /// # Safety + /// Enabled loads must not exceed the length of `slice`. #[must_use] #[inline] pub unsafe fn load_select_unchecked( @@ -442,6 +463,9 @@ where /// /// When the element is disabled, that memory location is not accessed and the corresponding /// value from `or` is passed through. + /// + /// # Safety + /// Enabled `ptr` elements must be safe to read as if by `std::ptr::read`. #[must_use] #[inline] pub unsafe fn load_select_ptr( @@ -924,6 +948,7 @@ where } } +/// Lexicographic order. For the SIMD elementwise minimum and maximum, use simd_min and simd_max instead. impl PartialOrd for Simd where LaneCount: SupportedLaneCount, @@ -943,6 +968,7 @@ where { } +/// Lexicographic order. For the SIMD elementwise minimum and maximum, use simd_min and simd_max instead. impl Ord for Simd where LaneCount: SupportedLaneCount, @@ -1195,6 +1221,7 @@ fn lane_indices() -> Simd where LaneCount: SupportedLaneCount, { + #![allow(clippy::needless_range_loop)] let mut index = [0; N]; for i in 0..N { index[i] = i; diff --git a/crates/core_simd/src/vendor.rs b/crates/core_simd/src/vendor.rs index 1a34a3a8de5c..57536e4fc77d 100644 --- a/crates/core_simd/src/vendor.rs +++ b/crates/core_simd/src/vendor.rs @@ -29,3 +29,6 @@ mod arm; #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] mod powerpc; + +#[cfg(target_arch = "loongarch64")] +mod loongarch64; diff --git a/crates/core_simd/src/vendor/loongarch64.rs b/crates/core_simd/src/vendor/loongarch64.rs new file mode 100644 index 000000000000..1290bc166b2b --- /dev/null +++ b/crates/core_simd/src/vendor/loongarch64.rs @@ -0,0 +1,31 @@ +use crate::simd::*; +use core::arch::loongarch64::*; + +from_transmute! { unsafe u8x16 => v16u8 } +from_transmute! { unsafe u8x32 => v32u8 } +from_transmute! { unsafe i8x16 => v16i8 } +from_transmute! { unsafe i8x32 => v32i8 } + +from_transmute! { unsafe u16x8 => v8u16 } +from_transmute! { unsafe u16x16 => v16u16 } +from_transmute! { unsafe i16x8 => v8i16 } +from_transmute! { unsafe i16x16 => v16i16 } + +from_transmute! { unsafe u32x4 => v4u32 } +from_transmute! { unsafe u32x8 => v8u32 } +from_transmute! { unsafe i32x4 => v4i32 } +from_transmute! { unsafe i32x8 => v8i32 } +from_transmute! { unsafe f32x4 => v4f32 } +from_transmute! { unsafe f32x8 => v8f32 } + +from_transmute! { unsafe u64x2 => v2u64 } +from_transmute! { unsafe u64x4 => v4u64 } +from_transmute! { unsafe i64x2 => v2i64 } +from_transmute! { unsafe i64x4 => v4i64 } +from_transmute! { unsafe f64x2 => v2f64 } +from_transmute! { unsafe f64x4 => v4f64 } + +from_transmute! { unsafe usizex2 => v2u64 } +from_transmute! { unsafe usizex4 => v4u64 } +from_transmute! { unsafe isizex2 => v2i64 } +from_transmute! { unsafe isizex4 => v4i64 } diff --git a/crates/core_simd/tests/layout.rs b/crates/core_simd/tests/layout.rs new file mode 100644 index 000000000000..24114c2d261e --- /dev/null +++ b/crates/core_simd/tests/layout.rs @@ -0,0 +1,35 @@ +#![feature(portable_simd)] + +macro_rules! layout_tests { + { $($mod:ident, $ty:ty,)* } => { + $( + mod $mod { + test_helpers::test_lanes! { + fn no_padding() { + assert_eq!( + core::mem::size_of::>(), + core::mem::size_of::<[$ty; LANES]>(), + ); + } + } + } + )* + } +} + +layout_tests! { + i8, i8, + i16, i16, + i32, i32, + i64, i64, + isize, isize, + u8, u8, + u16, u16, + u32, u32, + u64, u64, + usize, usize, + f32, f32, + f64, f64, + mut_ptr, *mut (), + const_ptr, *const (), +} diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs index fc6a3476b7c6..48786d02440b 100644 --- a/crates/core_simd/tests/masks.rs +++ b/crates/core_simd/tests/masks.rs @@ -99,7 +99,6 @@ macro_rules! test_mask_api { assert_eq!(Mask::<$type, 2>::from_bitmask(bitmask), mask); } - #[cfg(feature = "all_lane_counts")] #[test] fn roundtrip_bitmask_conversion_odd() { let values = [ @@ -134,48 +133,6 @@ macro_rules! test_mask_api { cast_impl::(); cast_impl::(); } - - #[test] - fn roundtrip_bitmask_vector_conversion() { - use core_simd::simd::ToBytes; - let values = [ - true, false, false, true, false, false, true, false, - true, true, false, false, false, false, false, true, - ]; - let mask = Mask::<$type, 16>::from_array(values); - let bitmask = mask.to_bitmask_vector(); - assert_eq!(bitmask.resize::<2>(0).to_ne_bytes()[..2], [0b01001001, 0b10000011]); - assert_eq!(Mask::<$type, 16>::from_bitmask_vector(bitmask), mask); - } - - // rust-lang/portable-simd#379 - #[test] - fn roundtrip_bitmask_vector_conversion_small() { - use core_simd::simd::ToBytes; - let values = [ - true, false, true, true - ]; - let mask = Mask::<$type, 4>::from_array(values); - let bitmask = mask.to_bitmask_vector(); - assert_eq!(bitmask.resize::<1>(0).to_ne_bytes()[0], 0b00001101); - assert_eq!(Mask::<$type, 4>::from_bitmask_vector(bitmask), mask); - } - - /* FIXME doesn't work with non-powers-of-two, yet - // rust-lang/portable-simd#379 - #[cfg(feature = "all_lane_counts")] - #[test] - fn roundtrip_bitmask_vector_conversion_odd() { - use core_simd::simd::ToBytes; - let values = [ - true, false, true, false, true, true, false, false, false, true, true, - ]; - let mask = Mask::<$type, 11>::from_array(values); - let bitmask = mask.to_bitmask_vector(); - assert_eq!(bitmask.resize::<2>(0).to_ne_bytes()[..2], [0b00110101, 0b00000110]); - assert_eq!(Mask::<$type, 11>::from_bitmask_vector(bitmask), mask); - } - */ } } } diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs index aa565a137527..6de78f51e59d 100644 --- a/crates/core_simd/tests/ops_macros.rs +++ b/crates/core_simd/tests/ops_macros.rs @@ -216,6 +216,22 @@ macro_rules! impl_common_integer_tests { ) } + fn count_ones() { + test_helpers::test_unary_elementwise( + &$vector::::count_ones, + &|x| x.count_ones() as _, + &|_| true, + ) + } + + fn count_zeros() { + test_helpers::test_unary_elementwise( + &$vector::::count_zeros, + &|x| x.count_zeros() as _, + &|_| true, + ) + } + fn leading_zeros() { test_helpers::test_unary_elementwise( &$vector::::leading_zeros, @@ -307,6 +323,14 @@ macro_rules! impl_signed_tests { assert_eq!(a % b, Vector::::splat(0)); } + fn abs_diff() { + test_helpers::test_binary_elementwise( + &Vector::::abs_diff, + &Scalar::abs_diff, + &|_, _| true, + ) + } + fn simd_min() { use core_simd::simd::cmp::SimdOrd; let a = Vector::::splat(Scalar::MIN); @@ -419,6 +443,14 @@ macro_rules! impl_unsigned_tests { &|_| true, ); } + + fn abs_diff() { + test_helpers::test_binary_elementwise( + &Vector::::abs_diff, + &Scalar::abs_diff, + &|_, _| true, + ) + } } impl_binary_op_test!(Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); @@ -495,6 +527,9 @@ macro_rules! impl_float_tests { } fn is_normal() { + // Arm v7 Neon violates float opsem re: subnormals, see + // https://github.com/rust-lang/portable-simd/issues/439 + #[cfg(not(target_arch = "arm"))] test_helpers::test_unary_mask_elementwise( &Vector::::is_normal, &Scalar::is_normal, @@ -503,6 +538,9 @@ macro_rules! impl_float_tests { } fn is_subnormal() { + // Arm v7 Neon violates float opsem re: subnormals, see + // https://github.com/rust-lang/portable-simd/issues/439 + #[cfg(not(target_arch = "arm"))] test_helpers::test_unary_mask_elementwise( &Vector::::is_subnormal, &Scalar::is_subnormal, diff --git a/crates/core_simd/tests/swizzle.rs b/crates/core_simd/tests/swizzle.rs index 522d71439b77..7001e5f6bf87 100644 --- a/crates/core_simd/tests/swizzle.rs +++ b/crates/core_simd/tests/swizzle.rs @@ -48,6 +48,24 @@ fn rotate() { assert_eq!(a.rotate_elements_right::<5>().to_array(), [4, 1, 2, 3]); } +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn shift() { + let a = Simd::from_array([1, 2, 3, 4]); + assert_eq!(a.shift_elements_left::<0>(0).to_array(), [1, 2, 3, 4]); + assert_eq!(a.shift_elements_left::<1>(0).to_array(), [2, 3, 4, 0]); + assert_eq!(a.shift_elements_left::<2>(9).to_array(), [3, 4, 9, 9]); + assert_eq!(a.shift_elements_left::<3>(8).to_array(), [4, 8, 8, 8]); + assert_eq!(a.shift_elements_left::<4>(7).to_array(), [7, 7, 7, 7]); + assert_eq!(a.shift_elements_left::<5>(6).to_array(), [6, 6, 6, 6]); + assert_eq!(a.shift_elements_right::<0>(0).to_array(), [1, 2, 3, 4]); + assert_eq!(a.shift_elements_right::<1>(0).to_array(), [0, 1, 2, 3]); + assert_eq!(a.shift_elements_right::<2>(-1).to_array(), [-1, -1, 1, 2]); + assert_eq!(a.shift_elements_right::<3>(-2).to_array(), [-2, -2, -2, 1]); + assert_eq!(a.shift_elements_right::<4>(-3).to_array(), [-3, -3, -3, -3]); + assert_eq!(a.shift_elements_right::<5>(-4).to_array(), [-4, -4, -4, -4]); +} + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn interleave() { diff --git a/crates/test_helpers/Cargo.toml b/crates/test_helpers/Cargo.toml index 23dae7c93381..a5359b9abc84 100644 --- a/crates/test_helpers/Cargo.toml +++ b/crates/test_helpers/Cargo.toml @@ -6,6 +6,3 @@ publish = false [dependencies] proptest = { version = "0.10", default-features = false, features = ["alloc"] } - -[features] -all_lane_counts = [] diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 51b860a86356..197c920e11ea 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -539,32 +539,22 @@ macro_rules! test_lanes { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]; lanes_1 1; lanes_2 2; - lanes_4 4; - ); - - #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow - $crate::test_lanes_helper!( - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]; - lanes_8 8; - lanes_16 16; - lanes_32 32; - lanes_64 64; - ); - - #[cfg(feature = "all_lane_counts")] - $crate::test_lanes_helper!( - // test some odd and even non-power-of-2 lengths on miri - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]; + // Cover an odd and an even non-power-of-2 length in Miri. + // (Even non-power-of-2 vectors have alignment between element + // and vector size, so we want to cover that case as well.) lanes_3 3; - lanes_5 5; + lanes_6 6; ); - #[cfg(feature = "all_lane_counts")] #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow $crate::test_lanes_helper!( #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]; + lanes_4 4; + lanes_5 5; + lanes_7 7; + lanes_8 8; lanes_9 9; lanes_10 10; lanes_11 11; @@ -572,52 +562,55 @@ macro_rules! test_lanes { lanes_13 13; lanes_14 14; lanes_15 15; + lanes_16 16; lanes_17 17; - lanes_18 18; - lanes_19 19; - lanes_20 20; - lanes_21 21; - lanes_22 22; - lanes_23 23; + //lanes_18 18; + //lanes_19 19; + //lanes_20 20; + //lanes_21 21; + //lanes_22 22; + //lanes_23 23; lanes_24 24; - lanes_25 25; - lanes_26 26; - lanes_27 27; - lanes_28 28; - lanes_29 29; - lanes_30 30; - lanes_31 31; - lanes_33 33; - lanes_34 34; - lanes_35 35; - lanes_36 36; - lanes_37 37; - lanes_38 38; - lanes_39 39; - lanes_40 40; - lanes_41 41; - lanes_42 42; - lanes_43 43; - lanes_44 44; - lanes_45 45; - lanes_46 46; + //lanes_25 25; + //lanes_26 26; + //lanes_27 27; + //lanes_28 28; + //lanes_29 29; + //lanes_30 30; + //lanes_31 31; + lanes_32 32; + //lanes_33 33; + //lanes_34 34; + //lanes_35 35; + //lanes_36 36; + //lanes_37 37; + //lanes_38 38; + //lanes_39 39; + //lanes_40 40; + //lanes_41 41; + //lanes_42 42; + //lanes_43 43; + //lanes_44 44; + //lanes_45 45; + //lanes_46 46; lanes_47 47; - lanes_48 48; - lanes_49 49; - lanes_50 50; - lanes_51 51; - lanes_52 52; - lanes_53 53; - lanes_54 54; - lanes_55 55; + //lanes_48 48; + //lanes_49 49; + //lanes_50 50; + //lanes_51 51; + //lanes_52 52; + //lanes_53 53; + //lanes_54 54; + //lanes_55 55; lanes_56 56; lanes_57 57; - lanes_58 58; - lanes_59 59; - lanes_60 60; - lanes_61 61; - lanes_62 62; + //lanes_58 58; + //lanes_59 59; + //lanes_60 60; + //lanes_61 61; + //lanes_62 62; lanes_63 63; + lanes_64 64; ); } )* @@ -639,36 +632,24 @@ macro_rules! test_lanes_panic { core_simd::simd::LaneCount<$lanes>: core_simd::simd::SupportedLaneCount, $body + // test some odd and even non-power-of-2 lengths on miri $crate::test_lanes_helper!( #[should_panic]; lanes_1 1; lanes_2 2; - lanes_4 4; - ); - - #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow - $crate::test_lanes_helper!( - #[should_panic]; - lanes_8 8; - lanes_16 16; - lanes_32 32; - lanes_64 64; - ); - - #[cfg(feature = "all_lane_counts")] - $crate::test_lanes_helper!( - // test some odd and even non-power-of-2 lengths on miri - #[should_panic]; lanes_3 3; - lanes_5 5; + lanes_6 6; ); - #[cfg(feature = "all_lane_counts")] #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow $crate::test_lanes_helper!( #[should_panic]; + lanes_4 4; + lanes_5 5; + lanes_7 7; + lanes_8 8; lanes_9 9; lanes_10 10; lanes_11 11; @@ -676,52 +657,55 @@ macro_rules! test_lanes_panic { lanes_13 13; lanes_14 14; lanes_15 15; + lanes_16 16; lanes_17 17; - lanes_18 18; - lanes_19 19; - lanes_20 20; - lanes_21 21; - lanes_22 22; - lanes_23 23; + //lanes_18 18; + //lanes_19 19; + //lanes_20 20; + //lanes_21 21; + //lanes_22 22; + //lanes_23 23; lanes_24 24; - lanes_25 25; - lanes_26 26; - lanes_27 27; - lanes_28 28; - lanes_29 29; - lanes_30 30; - lanes_31 31; - lanes_33 33; - lanes_34 34; - lanes_35 35; - lanes_36 36; - lanes_37 37; - lanes_38 38; - lanes_39 39; - lanes_40 40; - lanes_41 41; - lanes_42 42; - lanes_43 43; - lanes_44 44; - lanes_45 45; - lanes_46 46; + //lanes_25 25; + //lanes_26 26; + //lanes_27 27; + //lanes_28 28; + //lanes_29 29; + //lanes_30 30; + //lanes_31 31; + lanes_32 32; + //lanes_33 33; + //lanes_34 34; + //lanes_35 35; + //lanes_36 36; + //lanes_37 37; + //lanes_38 38; + //lanes_39 39; + //lanes_40 40; + //lanes_41 41; + //lanes_42 42; + //lanes_43 43; + //lanes_44 44; + //lanes_45 45; + //lanes_46 46; lanes_47 47; - lanes_48 48; - lanes_49 49; - lanes_50 50; - lanes_51 51; - lanes_52 52; - lanes_53 53; - lanes_54 54; - lanes_55 55; + //lanes_48 48; + //lanes_49 49; + //lanes_50 50; + //lanes_51 51; + //lanes_52 52; + //lanes_53 53; + //lanes_54 54; + //lanes_55 55; lanes_56 56; lanes_57 57; - lanes_58 58; - lanes_59 59; - lanes_60 60; - lanes_61 61; - lanes_62 62; + //lanes_58 58; + //lanes_59 59; + //lanes_60 60; + //lanes_61 61; + //lanes_62 62; lanes_63 63; + lanes_64 64; ); } )* diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000000..d17c6d2e8894 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "nightly-2025-01-16" +components = ["rustfmt", "clippy", "miri", "rust-src"] diff --git a/subtree-sync.sh b/subtree-sync.sh new file mode 100755 index 000000000000..18360077623b --- /dev/null +++ b/subtree-sync.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +set -eou pipefail + +git fetch origin +pushd $2 +git fetch origin +popd + +if [ "$(git rev-parse --show-prefix)" != "" ]; then + echo "Run this script from the git root" >&2 + exit 1 +fi + +if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/master)" ]; then + echo "$(pwd) is not at origin/master" >&2 + exit 1 +fi + +if [ ! -f library/portable-simd/git-subtree.sh ]; then + curl -sS https://raw.githubusercontent.com/bjorn3/git/tqc-subtree-portable/contrib/subtree/git-subtree.sh -o library/portable-simd/git-subtree.sh + chmod +x library/portable-simd/git-subtree.sh +fi + +today=$(date +%Y-%m-%d) + +case $1 in + "push") + upstream=rust-upstream-$today + merge=sync-from-rust-$today + + pushd $2 + git checkout master + git pull + popd + + library/portable-simd/git-subtree.sh push -P library/portable-simd $2 $upstream + + pushd $2 + git checkout -B $merge origin/master + git merge $upstream + popd + echo "Branch \`$merge\` created in \`$2\`. You may need to resolve merge conflicts." + ;; + "pull") + branch=sync-from-portable-simd-$today + + git checkout -B $branch + echo "Creating branch \`$branch\`... You may need to resolve merge conflicts." + library/portable-simd/git-subtree.sh pull -P library/portable-simd $2 origin/master + ;; +esac From 02a28b29e2d1ab50b8d80c18018c33402cefc054 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 12 Feb 2025 10:35:32 +0100 Subject: [PATCH 0002/3801] Remove ignored `#[must_use]` attributes from portable-simd The `#[must_use]` attribute has no effect when applied to methods in trait implementations. --- crates/core_simd/src/masks.rs | 13 ------------- crates/core_simd/src/masks/full_masks.rs | 5 ----- crates/core_simd/src/ops.rs | 1 - crates/core_simd/src/ops/deref.rs | 3 --- crates/core_simd/src/ops/unary.rs | 2 -- crates/core_simd/src/simd/num/float.rs | 1 - 6 files changed, 25 deletions(-) diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index b763a7c75a5a..19d45f4d3b31 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -401,7 +401,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a defaulted mask with all elements set to false (0)"] fn default() -> Self { Self::splat(false) } @@ -413,7 +412,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new bool and does not mutate the original value"] fn eq(&self, other: &Self) -> bool { self.0 == other.0 } @@ -425,7 +423,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new Ordering and does not mutate the original value"] fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(&other.0) } @@ -451,7 +448,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Self) -> Self { Self(self.0 & rhs.0) } @@ -464,7 +460,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: bool) -> Self { self & Self::splat(rhs) } @@ -477,7 +472,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Mask) -> Mask { Mask::splat(self) & rhs } @@ -490,7 +484,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Self) -> Self { Self(self.0 | rhs.0) } @@ -503,7 +496,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: bool) -> Self { self | Self::splat(rhs) } @@ -516,7 +508,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Mask) -> Mask { Mask::splat(self) | rhs } @@ -529,7 +520,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Self) -> Self::Output { Self(self.0 ^ rhs.0) } @@ -542,7 +532,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: bool) -> Self::Output { self ^ Self::splat(rhs) } @@ -555,7 +544,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Mask) -> Self::Output { Mask::splat(self) ^ rhs } @@ -568,7 +556,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(self) -> Self::Output { Self(!self.0) } diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index 2d01946b5747..387b508c4b4e 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -21,7 +21,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn clone(&self) -> Self { *self } @@ -252,7 +251,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Self) -> Self { // Safety: `self` is an integer vector unsafe { Self(core::intrinsics::simd::simd_and(self.0, rhs.0)) } @@ -266,7 +264,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Self) -> Self { // Safety: `self` is an integer vector unsafe { Self(core::intrinsics::simd::simd_or(self.0, rhs.0)) } @@ -280,7 +277,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Self) -> Self { // Safety: `self` is an integer vector unsafe { Self(core::intrinsics::simd::simd_xor(self.0, rhs.0)) } @@ -294,7 +290,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(self) -> Self::Output { Self::splat(true) ^ self } diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index d3bd14a34027..4ac64a253a3b 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -135,7 +135,6 @@ macro_rules! for_base_types { type Output = $out; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] // TODO: only useful for int Div::div, but we hope that this // will essentially always get inlined anyway. #[track_caller] diff --git a/crates/core_simd/src/ops/deref.rs b/crates/core_simd/src/ops/deref.rs index 0ff76cfba39b..913cbbe977c4 100644 --- a/crates/core_simd/src/ops/deref.rs +++ b/crates/core_simd/src/ops/deref.rs @@ -18,7 +18,6 @@ macro_rules! deref_lhs { type Output = Simd; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] fn $call(self, rhs: $simd) -> Self::Output { (*self).$call(rhs) } @@ -39,7 +38,6 @@ macro_rules! deref_rhs { type Output = Simd; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] fn $call(self, rhs: &$simd) -> Self::Output { self.$call(*rhs) } @@ -71,7 +69,6 @@ macro_rules! deref_ops { type Output = $simd; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] fn $call(self, rhs: &'rhs $simd) -> Self::Output { (*self).$call(*rhs) } diff --git a/crates/core_simd/src/ops/unary.rs b/crates/core_simd/src/ops/unary.rs index bdae96332a3a..412a5b801171 100644 --- a/crates/core_simd/src/ops/unary.rs +++ b/crates/core_simd/src/ops/unary.rs @@ -11,7 +11,6 @@ macro_rules! neg { type Output = Self; #[inline] - #[must_use = "operator returns a new vector without mutating the input"] fn neg(self) -> Self::Output { // Safety: `self` is a signed vector unsafe { core::intrinsics::simd::simd_neg(self) } @@ -46,7 +45,6 @@ macro_rules! not { type Output = Self; #[inline] - #[must_use = "operator returns a new vector without mutating the input"] fn not(self) -> Self::Output { self ^ (Simd::splat(!(0 as $scalar))) } diff --git a/crates/core_simd/src/simd/num/float.rs b/crates/core_simd/src/simd/num/float.rs index 79954b937b39..db705dfe2022 100644 --- a/crates/core_simd/src/simd/num/float.rs +++ b/crates/core_simd/src/simd/num/float.rs @@ -371,7 +371,6 @@ macro_rules! impl_trait { } #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn is_normal(self) -> Self::Mask { !(self.abs().simd_eq(Self::splat(0.0)) | self.is_nan() | self.is_subnormal() | self.is_infinite()) } From aaf8ff1f9ec9b7049a7896a3c278f9e990306cb8 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Wed, 19 Mar 2025 00:58:47 -0400 Subject: [PATCH 0003/3801] Merge commit 'c14f2fc3eb69c164d8bf8d36d91ebd60bd5261e6' into sync-from-portable-simd-2025-03-19 --- beginners-guide.md | 4 +- crates/core_simd/Cargo.toml | 2 +- crates/core_simd/src/lib.rs | 6 ++- crates/core_simd/src/masks/bitmask.rs | 22 +++++------ crates/core_simd/src/masks/full_masks.rs | 20 +++++----- crates/core_simd/src/ops.rs | 2 +- crates/core_simd/src/simd/cmp/eq.rs | 2 +- crates/core_simd/src/simd/cmp/ord.rs | 2 +- crates/core_simd/src/simd/num/float.rs | 9 +++-- crates/core_simd/src/simd/num/int.rs | 4 +- crates/core_simd/src/simd/num/uint.rs | 2 +- crates/core_simd/src/simd/prelude.rs | 3 +- crates/core_simd/src/simd/ptr/const_ptr.rs | 2 +- crates/core_simd/src/simd/ptr/mut_ptr.rs | 2 +- crates/core_simd/src/swizzle.rs | 44 ++++++++++++++++++++++ crates/core_simd/src/to_bytes.rs | 2 +- crates/core_simd/src/vector.rs | 4 +- crates/core_simd/tests/layout.rs | 4 +- crates/core_simd/tests/pointers.rs | 2 +- crates/core_simd/tests/round.rs | 2 +- crates/test_helpers/src/subnormals.rs | 2 +- 21 files changed, 96 insertions(+), 46 deletions(-) diff --git a/beginners-guide.md b/beginners-guide.md index 17ade06ae80f..dc08d847ced5 100644 --- a/beginners-guide.md +++ b/beginners-guide.md @@ -80,12 +80,12 @@ Most of the portable SIMD API is designed to allow the user to gloss over the de Fortunately, most SIMD types have a fairly predictable size. `i32x4` is bit-equivalent to `[i32; 4]` and so can be bitcast to it, e.g. using [`mem::transmute`], though the API usually offers a safe cast you can use instead. -However, this is not the same as alignment. Computer architectures generally prefer aligned accesses, especially when moving data between memory and vector registers, and while some support specialized operations that can bend the rules to help with this, unaligned access is still typically slow, or even undefined behavior. In addition, different architectures can require different alignments when interacting with their native SIMD types. For this reason, any `#[repr(simd)]` type has a non-portable alignment. If it is necessary to directly interact with the alignment of these types, it should be via [`mem::align_of`]. +However, this is not the same as alignment. Computer architectures generally prefer aligned accesses, especially when moving data between memory and vector registers, and while some support specialized operations that can bend the rules to help with this, unaligned access is still typically slow, or even undefined behavior. In addition, different architectures can require different alignments when interacting with their native SIMD types. For this reason, any `#[repr(simd)]` type has a non-portable alignment. If it is necessary to directly interact with the alignment of these types, it should be via [`align_of`]. When working with slices, data correctly aligned for SIMD can be acquired using the [`as_simd`] and [`as_simd_mut`] methods of the slice primitive. [`mem::transmute`]: https://doc.rust-lang.org/core/mem/fn.transmute.html -[`mem::align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html +[`align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html [`as_simd`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_simd [`as_simd_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_simd_mut diff --git a/crates/core_simd/Cargo.toml b/crates/core_simd/Cargo.toml index a7a6d43b11d3..537ce459c07c 100644 --- a/crates/core_simd/Cargo.toml +++ b/crates/core_simd/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "core_simd" version = "0.1.0" -edition = "2021" +edition = "2024" homepage = "https://github.com/rust-lang/portable-simd" repository = "https://github.com/rust-lang/portable-simd" keywords = ["core", "simd", "intrinsics"] diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index 7f57847c9c23..717b882b64ba 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -35,7 +35,11 @@ feature(stdarch_x86_avx512) )] #![warn(missing_docs, clippy::missing_inline_in_public_items)] // basically all items, really -#![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)] +#![deny( + unsafe_op_in_unsafe_fn, + unreachable_pub, + clippy::undocumented_unsafe_blocks +)] #![doc(test(attr(deny(warnings))))] #![allow(internal_features)] #![unstable(feature = "portable_simd", issue = "86656")] diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index db4312d5bf88..8221d8f17e90 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; /// A mask where each lane is represented by a single bit. #[repr(transparent)] -pub struct Mask( +pub(crate) struct Mask( as SupportedLaneCount>::BitMask, PhantomData, ) @@ -78,7 +78,7 @@ where { #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn splat(value: bool) -> Self { + pub(crate) fn splat(value: bool) -> Self { let mut mask = as SupportedLaneCount>::BitMask::default(); if value { mask.as_mut().fill(u8::MAX) @@ -93,12 +93,12 @@ where #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub unsafe fn test_unchecked(&self, lane: usize) -> bool { + pub(crate) unsafe fn test_unchecked(&self, lane: usize) -> bool { (self.0.as_ref()[lane / 8] >> (lane % 8)) & 0x1 > 0 } #[inline] - pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { + pub(crate) unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { unsafe { self.0.as_mut()[lane / 8] ^= ((value ^ self.test_unchecked(lane)) as u8) << (lane % 8) } @@ -106,7 +106,7 @@ where #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - pub fn to_int(self) -> Simd { + pub(crate) fn to_int(self) -> Simd { unsafe { core::intrinsics::simd::simd_select_bitmask( self.0, @@ -118,19 +118,19 @@ where #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub unsafe fn from_int_unchecked(value: Simd) -> Self { + pub(crate) unsafe fn from_int_unchecked(value: Simd) -> Self { unsafe { Self(core::intrinsics::simd::simd_bitmask(value), PhantomData) } } #[inline] - pub fn to_bitmask_integer(self) -> u64 { + pub(crate) fn to_bitmask_integer(self) -> u64 { let mut bitmask = [0u8; 8]; bitmask[..self.0.as_ref().len()].copy_from_slice(self.0.as_ref()); u64::from_ne_bytes(bitmask) } #[inline] - pub fn from_bitmask_integer(bitmask: u64) -> Self { + pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self { let mut bytes = as SupportedLaneCount>::BitMask::default(); let len = bytes.as_mut().len(); bytes @@ -141,7 +141,7 @@ where #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn convert(self) -> Mask + pub(crate) fn convert(self) -> Mask where U: MaskElement, { @@ -151,13 +151,13 @@ where #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub fn any(self) -> bool { + pub(crate) fn any(self) -> bool { self != Self::splat(false) } #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub fn all(self) -> bool { + pub(crate) fn all(self) -> bool { self == Self::splat(true) } } diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index 387b508c4b4e..4e98db4070a9 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -3,7 +3,7 @@ use crate::simd::{LaneCount, MaskElement, Simd, SupportedLaneCount}; #[repr(transparent)] -pub struct Mask(Simd) +pub(crate) struct Mask(Simd) where T: MaskElement, LaneCount: SupportedLaneCount; @@ -80,7 +80,7 @@ macro_rules! impl_reverse_bits { #[inline(always)] fn reverse_bits(self, n: usize) -> Self { let rev = <$int>::reverse_bits(self); - let bitsize = core::mem::size_of::<$int>() * 8; + let bitsize = size_of::<$int>() * 8; if n < bitsize { // Shift things back to the right rev >> (bitsize - n) @@ -102,36 +102,36 @@ where { #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn splat(value: bool) -> Self { + pub(crate) fn splat(value: bool) -> Self { Self(Simd::splat(if value { T::TRUE } else { T::FALSE })) } #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub unsafe fn test_unchecked(&self, lane: usize) -> bool { + pub(crate) unsafe fn test_unchecked(&self, lane: usize) -> bool { T::eq(self.0[lane], T::TRUE) } #[inline] - pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { + pub(crate) unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { self.0[lane] = if value { T::TRUE } else { T::FALSE } } #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - pub fn to_int(self) -> Simd { + pub(crate) fn to_int(self) -> Simd { self.0 } #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub unsafe fn from_int_unchecked(value: Simd) -> Self { + pub(crate) unsafe fn from_int_unchecked(value: Simd) -> Self { Self(value) } #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn convert(self) -> Mask + pub(crate) fn convert(self) -> Mask where U: MaskElement, { @@ -220,14 +220,14 @@ where #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub fn any(self) -> bool { + pub(crate) fn any(self) -> bool { // Safety: use `self` as an integer vector unsafe { core::intrinsics::simd::simd_reduce_any(self.to_int()) } } #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub fn all(self) -> bool { + pub(crate) fn all(self) -> bool { // Safety: use `self` as an integer vector unsafe { core::intrinsics::simd::simd_reduce_all(self.to_int()) } } diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index 4ac64a253a3b..f36e8d01a73b 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -1,4 +1,4 @@ -use crate::simd::{cmp::SimdPartialEq, LaneCount, Simd, SimdElement, SupportedLaneCount}; +use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount, cmp::SimdPartialEq}; use core::ops::{Add, Mul}; use core::ops::{BitAnd, BitOr, BitXor}; use core::ops::{Div, Rem, Sub}; diff --git a/crates/core_simd/src/simd/cmp/eq.rs b/crates/core_simd/src/simd/cmp/eq.rs index 93989ce91b89..2312ba401fa7 100644 --- a/crates/core_simd/src/simd/cmp/eq.rs +++ b/crates/core_simd/src/simd/cmp/eq.rs @@ -1,6 +1,6 @@ use crate::simd::{ - ptr::{SimdConstPtr, SimdMutPtr}, LaneCount, Mask, Simd, SimdElement, SupportedLaneCount, + ptr::{SimdConstPtr, SimdMutPtr}, }; /// Parallel `PartialEq`. diff --git a/crates/core_simd/src/simd/cmp/ord.rs b/crates/core_simd/src/simd/cmp/ord.rs index 899f00a83164..e813e7613032 100644 --- a/crates/core_simd/src/simd/cmp/ord.rs +++ b/crates/core_simd/src/simd/cmp/ord.rs @@ -1,7 +1,7 @@ use crate::simd::{ + LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, ptr::{SimdConstPtr, SimdMutPtr}, - LaneCount, Mask, Simd, SupportedLaneCount, }; /// Parallel `PartialOrd`. diff --git a/crates/core_simd/src/simd/num/float.rs b/crates/core_simd/src/simd/num/float.rs index db705dfe2022..b5972c47373b 100644 --- a/crates/core_simd/src/simd/num/float.rs +++ b/crates/core_simd/src/simd/num/float.rs @@ -1,7 +1,7 @@ use super::sealed::Sealed; use crate::simd::{ - cmp::{SimdPartialEq, SimdPartialOrd}, LaneCount, Mask, Simd, SimdCast, SimdElement, SupportedLaneCount, + cmp::{SimdPartialEq, SimdPartialOrd}, }; /// Operations on SIMD vectors of floats. @@ -263,7 +263,8 @@ macro_rules! impl_trait { unsafe { core::intrinsics::simd::simd_as(self) } } - // https://github.com/llvm/llvm-project/issues/94694 + // workaround for https://github.com/llvm/llvm-project/issues/94694 (fixed in LLVM 20) + // tracked in: https://github.com/rust-lang/rust/issues/135982 #[cfg(target_arch = "aarch64")] #[inline] fn cast(self) -> Self::Cast @@ -302,14 +303,14 @@ macro_rules! impl_trait { #[inline] fn to_bits(self) -> Simd<$bits_ty, N> { - assert_eq!(core::mem::size_of::(), core::mem::size_of::()); + assert_eq!(size_of::(), size_of::()); // Safety: transmuting between vector types is safe unsafe { core::mem::transmute_copy(&self) } } #[inline] fn from_bits(bits: Simd<$bits_ty, N>) -> Self { - assert_eq!(core::mem::size_of::(), core::mem::size_of::()); + assert_eq!(size_of::(), size_of::()); // Safety: transmuting between vector types is safe unsafe { core::mem::transmute_copy(&bits) } } diff --git a/crates/core_simd/src/simd/num/int.rs b/crates/core_simd/src/simd/num/int.rs index 3a51235ff954..d25050c3e4b4 100644 --- a/crates/core_simd/src/simd/num/int.rs +++ b/crates/core_simd/src/simd/num/int.rs @@ -1,7 +1,7 @@ use super::sealed::Sealed; use crate::simd::{ - cmp::SimdOrd, cmp::SimdPartialOrd, num::SimdUint, LaneCount, Mask, Simd, SimdCast, SimdElement, - SupportedLaneCount, + LaneCount, Mask, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd, + cmp::SimdPartialOrd, num::SimdUint, }; /// Operations on SIMD vectors of signed integers. diff --git a/crates/core_simd/src/simd/num/uint.rs b/crates/core_simd/src/simd/num/uint.rs index 1ab2d8c7b731..45d978068b66 100644 --- a/crates/core_simd/src/simd/num/uint.rs +++ b/crates/core_simd/src/simd/num/uint.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{cmp::SimdOrd, LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount}; +use crate::simd::{LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd}; /// Operations on SIMD vectors of unsigned integers. pub trait SimdUint: Copy + Sealed { diff --git a/crates/core_simd/src/simd/prelude.rs b/crates/core_simd/src/simd/prelude.rs index 4b7c744c0132..e5d7a2aeb73d 100644 --- a/crates/core_simd/src/simd/prelude.rs +++ b/crates/core_simd/src/simd/prelude.rs @@ -7,10 +7,11 @@ #[doc(no_inline)] pub use super::{ + Mask, Simd, cmp::{SimdOrd, SimdPartialEq, SimdPartialOrd}, num::{SimdFloat, SimdInt, SimdUint}, ptr::{SimdConstPtr, SimdMutPtr}, - simd_swizzle, Mask, Simd, + simd_swizzle, }; #[rustfmt::skip] diff --git a/crates/core_simd/src/simd/ptr/const_ptr.rs b/crates/core_simd/src/simd/ptr/const_ptr.rs index 47383809ffba..36452e7ae920 100644 --- a/crates/core_simd/src/simd/ptr/const_ptr.rs +++ b/crates/core_simd/src/simd/ptr/const_ptr.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{cmp::SimdPartialEq, num::SimdUint, LaneCount, Mask, Simd, SupportedLaneCount}; +use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, num::SimdUint}; /// Operations on SIMD vectors of constant pointers. pub trait SimdConstPtr: Copy + Sealed { diff --git a/crates/core_simd/src/simd/ptr/mut_ptr.rs b/crates/core_simd/src/simd/ptr/mut_ptr.rs index 3f20eef21a31..c644f390c20a 100644 --- a/crates/core_simd/src/simd/ptr/mut_ptr.rs +++ b/crates/core_simd/src/simd/ptr/mut_ptr.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{cmp::SimdPartialEq, num::SimdUint, LaneCount, Mask, Simd, SupportedLaneCount}; +use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, num::SimdUint}; /// Operations on SIMD vectors of mutable pointers. pub trait SimdMutPtr: Copy + Sealed { diff --git a/crates/core_simd/src/swizzle.rs b/crates/core_simd/src/swizzle.rs index 42425ef37e50..dbdd6ef40eba 100644 --- a/crates/core_simd/src/swizzle.rs +++ b/crates/core_simd/src/swizzle.rs @@ -214,6 +214,17 @@ where /// Rotates the vector such that the first `OFFSET` elements of the slice move to the end /// while the last `self.len() - OFFSET` elements move to the front. After calling `rotate_elements_left`, /// the element previously at index `OFFSET` will become the first element in the slice. + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let a = Simd::from_array([0, 1, 2, 3]); + /// let x = a.rotate_elements_left::<3>(); + /// assert_eq!(x.to_array(), [3, 0, 1, 2]); + /// + /// let y = a.rotate_elements_left::<7>(); + /// assert_eq!(y.to_array(), [3, 0, 1, 2]); + /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn rotate_elements_left(self) -> Self { @@ -238,6 +249,17 @@ where /// Rotates the vector such that the first `self.len() - OFFSET` elements of the vector move to /// the end while the last `OFFSET` elements move to the front. After calling `rotate_elements_right`, /// the element previously at index `self.len() - OFFSET` will become the first element in the slice. + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let a = Simd::from_array([0, 1, 2, 3]); + /// let x = a.rotate_elements_right::<3>(); + /// assert_eq!(x.to_array(), [1, 2, 3, 0]); + /// + /// let y = a.rotate_elements_right::<7>(); + /// assert_eq!(y.to_array(), [1, 2, 3, 0]); + /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn rotate_elements_right(self) -> Self { @@ -261,6 +283,17 @@ where /// Shifts the vector elements to the left by `OFFSET`, filling in with /// `padding` from the right. + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let a = Simd::from_array([0, 1, 2, 3]); + /// let x = a.shift_elements_left::<3>(255); + /// assert_eq!(x.to_array(), [3, 255, 255, 255]); + /// + /// let y = a.shift_elements_left::<7>(255); + /// assert_eq!(y.to_array(), [255, 255, 255, 255]); + /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn shift_elements_left(self, padding: T) -> Self { @@ -283,6 +316,17 @@ where /// Shifts the vector elements to the right by `OFFSET`, filling in with /// `padding` from the left. + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let a = Simd::from_array([0, 1, 2, 3]); + /// let x = a.shift_elements_right::<3>(255); + /// assert_eq!(x.to_array(), [255, 255, 255, 0]); + /// + /// let y = a.shift_elements_right::<7>(255); + /// assert_eq!(y.to_array(), [255, 255, 255, 255]); + /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn shift_elements_right(self, padding: T) -> Self { diff --git a/crates/core_simd/src/to_bytes.rs b/crates/core_simd/src/to_bytes.rs index 4833ea9e1136..fee2cc06c5b0 100644 --- a/crates/core_simd/src/to_bytes.rs +++ b/crates/core_simd/src/to_bytes.rs @@ -1,6 +1,6 @@ use crate::simd::{ - num::{SimdFloat, SimdInt, SimdUint}, LaneCount, Simd, SimdElement, SupportedLaneCount, + num::{SimdFloat, SimdInt, SimdUint}, }; mod sealed { diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index 9c4dd36c24fe..d76a6cd52bfc 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -1,8 +1,8 @@ use crate::simd::{ + LaneCount, Mask, MaskElement, SupportedLaneCount, Swizzle, cmp::SimdPartialOrd, num::SimdUint, ptr::{SimdConstPtr, SimdMutPtr}, - LaneCount, Mask, MaskElement, SupportedLaneCount, Swizzle, }; /// A SIMD vector with the shape of `[T; N]` but the operations of `T`. @@ -83,7 +83,7 @@ use crate::simd::{ /// converting `[T]` to `[Simd]`, and allows soundly operating on an aligned SIMD body, /// but it may cost more time when handling the scalar head and tail. /// If these are not enough, it is most ideal to design data structures to be already aligned -/// to `mem::align_of::>()` before using `unsafe` Rust to read or write. +/// to `align_of::>()` before using `unsafe` Rust to read or write. /// Other ways to compensate for these facts, like materializing `Simd` to or from an array first, /// are handled by safe methods like [`Simd::from_array`] and [`Simd::from_slice`]. /// diff --git a/crates/core_simd/tests/layout.rs b/crates/core_simd/tests/layout.rs index 24114c2d261e..3b4666249b0d 100644 --- a/crates/core_simd/tests/layout.rs +++ b/crates/core_simd/tests/layout.rs @@ -7,8 +7,8 @@ macro_rules! layout_tests { test_helpers::test_lanes! { fn no_padding() { assert_eq!( - core::mem::size_of::>(), - core::mem::size_of::<[$ty; LANES]>(), + size_of::>(), + size_of::<[$ty; LANES]>(), ); } } diff --git a/crates/core_simd/tests/pointers.rs b/crates/core_simd/tests/pointers.rs index d7db4e82b3ca..6e74c2d18b1e 100644 --- a/crates/core_simd/tests/pointers.rs +++ b/crates/core_simd/tests/pointers.rs @@ -1,8 +1,8 @@ #![feature(portable_simd)] use core_simd::simd::{ - ptr::{SimdConstPtr, SimdMutPtr}, Simd, + ptr::{SimdConstPtr, SimdMutPtr}, }; macro_rules! common_tests { diff --git a/crates/core_simd/tests/round.rs b/crates/core_simd/tests/round.rs index 847766ec41ed..4c1ac3c36f89 100644 --- a/crates/core_simd/tests/round.rs +++ b/crates/core_simd/tests/round.rs @@ -58,7 +58,7 @@ macro_rules! float_rounding_test { // all of the mantissa digits set to 1, pushed up to the MSB. const ALL_MANTISSA_BITS: IntScalar = ((1 << ::MANTISSA_DIGITS) - 1); const MAX_REPRESENTABLE_VALUE: Scalar = - (ALL_MANTISSA_BITS << (core::mem::size_of::() * 8 - ::MANTISSA_DIGITS as usize - 1)) as Scalar; + (ALL_MANTISSA_BITS << (size_of::() * 8 - ::MANTISSA_DIGITS as usize - 1)) as Scalar; let mut runner = test_helpers::make_runner(); runner.run( diff --git a/crates/test_helpers/src/subnormals.rs b/crates/test_helpers/src/subnormals.rs index ec0f1fb24b93..b5f19ba47b81 100644 --- a/crates/test_helpers/src/subnormals.rs +++ b/crates/test_helpers/src/subnormals.rs @@ -12,7 +12,7 @@ macro_rules! impl_float { $( impl FlushSubnormals for $ty { fn flush(self) -> Self { - let is_f32 = core::mem::size_of::() == 4; + let is_f32 = size_of::() == 4; let ppc_flush = is_f32 && cfg!(all( any(target_arch = "powerpc", all(target_arch = "powerpc64", target_endian = "big")), target_feature = "altivec", From cdac23c86a06003d37ad102edbdc74c8d3d9f933 Mon Sep 17 00:00:00 2001 From: Cornelius Roemer Date: Mon, 7 Apr 2025 18:13:32 +0200 Subject: [PATCH 0004/3801] Fix grammar in beginners-guide.md --- beginners-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beginners-guide.md b/beginners-guide.md index dc08d847ced5..4250a18315a6 100644 --- a/beginners-guide.md +++ b/beginners-guide.md @@ -25,7 +25,7 @@ SIMD has a few special vocabulary terms you should know: * **Scalar:** "Scalar" in mathematical contexts refers to values that can be represented as a single element, mostly numbers like 6, 3.14, or -2. It can also be used to describe "scalar operations" that use strictly scalar values, like addition. This term is mostly used to differentiate between vectorized operations that use SIMD instructions and scalar operations that don't. -* **Lane:** A single element position within a vector is called a lane. If you have `N` lanes available then they're numbered from `0` to `N-1` when referring to them, again like an array. The biggest difference between an array element and a vector lane is that in general is *relatively costly* to access an individual lane value. On most architectures, the vector has to be pushed out of the SIMD register onto the stack, then an individual lane is accessed while it's on the stack (and possibly the stack value is read back into a register). For this reason, when working with SIMD you should avoid reading or writing the value of an individual lane during hot loops. +* **Lane:** A single element position within a vector is called a lane. If you have `N` lanes available then they're numbered from `0` to `N-1` when referring to them, again like an array. The biggest difference between an array element and a vector lane is that in general it is *relatively costly* to access an individual lane value. On most architectures, the vector has to be pushed out of the SIMD register onto the stack, then an individual lane is accessed while it's on the stack (and possibly the stack value is read back into a register). For this reason, when working with SIMD you should avoid reading or writing the value of an individual lane during hot loops. * **Bit Widths:** When talking about SIMD, the bit widths used are the bit size of the vectors involved, *not* the individual elements. So "128-bit SIMD" has 128-bit vectors, and that might be `f32x4`, `i32x4`, `i16x8`, or other variations. While 128-bit SIMD is the most common, there's also 64-bit, 256-bit, and even 512-bit on the newest CPUs. From 108bfc13febf252b41daeb0f833865b70ef24d8d Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Fri, 30 May 2025 15:32:46 +0300 Subject: [PATCH 0005/3801] Update opaque-types-type-alias-impl-trait.md 1. Clarify that there is a single concrete type for an opaque type 2. Clarify that defining a type alias to an opaque type is an unstable feature 3. Add complete example 4. Clarify that defining an associate type as opaque is an unstable feature 5. Add another complete example --- .../src/opaque-types-type-alias-impl-trait.md | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md index 956f568285a0..0f0e8e87c321 100644 --- a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md +++ b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md @@ -12,15 +12,16 @@ type Foo = impl Bar; This declares an opaque type named `Foo`, of which the only information is that it implements `Bar`. Therefore, any of `Bar`'s interface can be used on a `Foo`, -but nothing else (regardless of whether it implements any other traits). +but nothing else (regardless of whether the concrete type implements any other traits). Since there needs to be a concrete background type, -you can (as of January 2021) express that type +you can (as of May 2025) express that type by using the opaque type in a "defining use site". ```rust,ignore struct Struct; impl Bar for Struct { /* stuff */ } +#[define_opaque(Foo)] fn foo() -> Foo { Struct } @@ -28,6 +29,27 @@ fn foo() -> Foo { Any other "defining use site" needs to produce the exact same type. +Note that defining a type alias to an opaque type is an unstable feature. +To use it, you need `nightly` and the annotations `#![feature(type_alias_impl_trait)]` on the file and `#[define_opaque(Foo)]` on the method that links the opaque type to the concrete type. +Complete example: + +```rust +#![feature(type_alias_impl_trait)] + +trait Bar { /* stuff */ } + +type Foo = impl Bar; + +struct Struct; + +impl Bar for Struct { /* stuff */ } + +#[define_opaque(Foo)] +fn foo() -> Foo { + Struct +} +``` + ## Defining use site(s) Currently only the return value of a function can be a defining use site @@ -61,3 +83,28 @@ impl Baz for Quux { fn foo() -> Self::Foo { ... } } ``` + +For this you would also need to use `nightly` and the (different) `#![feature(impl_trait_in_assoc_type)]` annotation. +Note that you don't need a `#[define_opaque(Foo)]` on the method anymore. +Complete example: + +``` +#![feature(impl_trait_in_assoc_type)] + +trait Bar {} +struct Zap; + +impl Bar for Zap {} + +trait Baz { + type Foo; + fn foo() -> Self::Foo; +} + +struct Quux; + +impl Baz for Quux { + type Foo = impl Bar; + fn foo() -> Self::Foo { Zap } +} +``` From 6951b685b8d8bd42b88765432e125959cb5fbdd8 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Wed, 11 Jun 2025 17:45:38 -0400 Subject: [PATCH 0006/3801] Remove usize/isize `From` impls for vendor vector types Remove usize/isize impls from - `loongarch64.rs` - `wasm32.rs` - `x86.rs` --- crates/core_simd/src/vendor/loongarch64.rs | 5 ----- crates/core_simd/src/vendor/wasm32.rs | 14 -------------- crates/core_simd/src/vendor/x86.rs | 22 ---------------------- 3 files changed, 41 deletions(-) diff --git a/crates/core_simd/src/vendor/loongarch64.rs b/crates/core_simd/src/vendor/loongarch64.rs index 1290bc166b2b..13dda4769aba 100644 --- a/crates/core_simd/src/vendor/loongarch64.rs +++ b/crates/core_simd/src/vendor/loongarch64.rs @@ -24,8 +24,3 @@ from_transmute! { unsafe i64x2 => v2i64 } from_transmute! { unsafe i64x4 => v4i64 } from_transmute! { unsafe f64x2 => v2f64 } from_transmute! { unsafe f64x4 => v4f64 } - -from_transmute! { unsafe usizex2 => v2u64 } -from_transmute! { unsafe usizex4 => v4u64 } -from_transmute! { unsafe isizex2 => v2i64 } -from_transmute! { unsafe isizex4 => v4i64 } diff --git a/crates/core_simd/src/vendor/wasm32.rs b/crates/core_simd/src/vendor/wasm32.rs index ef3baf885b0f..1fdb2bc86d34 100644 --- a/crates/core_simd/src/vendor/wasm32.rs +++ b/crates/core_simd/src/vendor/wasm32.rs @@ -14,17 +14,3 @@ from_transmute! { unsafe f32x4 => v128 } from_transmute! { unsafe u64x2 => v128 } from_transmute! { unsafe i64x2 => v128 } from_transmute! { unsafe f64x2 => v128 } - -#[cfg(target_pointer_width = "32")] -mod p32 { - use super::*; - from_transmute! { unsafe usizex4 => v128 } - from_transmute! { unsafe isizex4 => v128 } -} - -#[cfg(target_pointer_width = "64")] -mod p64 { - use super::*; - from_transmute! { unsafe usizex2 => v128 } - from_transmute! { unsafe isizex2 => v128 } -} diff --git a/crates/core_simd/src/vendor/x86.rs b/crates/core_simd/src/vendor/x86.rs index 66aaf90eef59..eae42e6fd0d0 100644 --- a/crates/core_simd/src/vendor/x86.rs +++ b/crates/core_simd/src/vendor/x86.rs @@ -39,25 +39,3 @@ from_transmute! { unsafe i64x8 => __m512i } from_transmute! { unsafe f64x2 => __m128d } from_transmute! { unsafe f64x4 => __m256d } from_transmute! { unsafe f64x8 => __m512d } - -#[cfg(target_pointer_width = "32")] -mod p32 { - use super::*; - from_transmute! { unsafe usizex4 => __m128i } - from_transmute! { unsafe usizex8 => __m256i } - from_transmute! { unsafe Simd => __m512i } - from_transmute! { unsafe isizex4 => __m128i } - from_transmute! { unsafe isizex8 => __m256i } - from_transmute! { unsafe Simd => __m512i } -} - -#[cfg(target_pointer_width = "64")] -mod p64 { - use super::*; - from_transmute! { unsafe usizex2 => __m128i } - from_transmute! { unsafe usizex4 => __m256i } - from_transmute! { unsafe usizex8 => __m512i } - from_transmute! { unsafe isizex2 => __m128i } - from_transmute! { unsafe isizex4 => __m256i } - from_transmute! { unsafe isizex8 => __m512i } -} From 97a3a5008470239510262f378350132da358edaf Mon Sep 17 00:00:00 2001 From: ltdk Date: Thu, 12 Jun 2025 12:03:40 -0400 Subject: [PATCH 0007/3801] Add const to as_mut_array, copy_to_slice --- crates/core_simd/src/vector.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index d76a6cd52bfc..984a356c6552 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -195,7 +195,7 @@ where /// Returns a mutable array reference containing the entire SIMD vector. #[inline] - pub fn as_mut_array(&mut self) -> &mut [T; N] { + pub const fn as_mut_array(&mut self) -> &mut [T; N] { // SAFETY: `Simd` is just an overaligned `[T; N]` with // potential padding at the end, so pointer casting to a // `&mut [T; N]` is safe. @@ -324,7 +324,7 @@ where /// ``` #[inline] #[track_caller] - pub fn copy_to_slice(self, slice: &mut [T]) { + pub const fn copy_to_slice(self, slice: &mut [T]) { assert!( slice.len() >= Self::LEN, "slice length must be at least the number of elements" From a85790961605af9967fe5b76c45671c37c17f56b Mon Sep 17 00:00:00 2001 From: ltdk Date: Fri, 13 Jun 2025 00:38:09 -0400 Subject: [PATCH 0008/3801] Make Mask::splat const --- crates/core_simd/src/lane_count.rs | 15 ++++++++++++++- crates/core_simd/src/masks.rs | 3 ++- crates/core_simd/src/masks/bitmask.rs | 23 +++++++++++------------ crates/core_simd/src/masks/full_masks.rs | 3 ++- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/crates/core_simd/src/lane_count.rs b/crates/core_simd/src/lane_count.rs index 280b27bc9bc6..c62b9d3b7d9b 100644 --- a/crates/core_simd/src/lane_count.rs +++ b/crates/core_simd/src/lane_count.rs @@ -18,7 +18,11 @@ impl LaneCount { /// Only SIMD vectors with supported lane counts are constructable. pub trait SupportedLaneCount: Sealed { #[doc(hidden)] - type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>; + type BitMask: Copy + AsRef<[u8]> + AsMut<[u8]>; + #[doc(hidden)] + const EMPTY_BIT_MASK: Self::BitMask; + #[doc(hidden)] + const FULL_BIT_MASK: Self::BitMask; } impl Sealed for LaneCount {} @@ -28,6 +32,15 @@ macro_rules! supported_lane_count { $( impl SupportedLaneCount for LaneCount<$lanes> { type BitMask = [u8; ($lanes + 7) / 8]; + const EMPTY_BIT_MASK: Self::BitMask = [0; ($lanes + 7) / 8]; + const FULL_BIT_MASK: Self::BitMask = { + const LEN: usize = ($lanes + 7) / 8; + let mut array = [!0u8; LEN]; + if $lanes % 8 > 0 { + array[LEN - 1] = (!0) >> (8 - $lanes % 8); + } + array + }; } )+ }; diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index 19d45f4d3b31..2b6be3676279 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -139,7 +139,8 @@ where { /// Constructs a mask by setting all elements to the given value. #[inline] - pub fn splat(value: bool) -> Self { + #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] + pub const fn splat(value: bool) -> Self { Self(mask_impl::Mask::splat(value)) } diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index 8221d8f17e90..ef03ec7f7159 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -78,17 +78,16 @@ where { #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) fn splat(value: bool) -> Self { - let mut mask = as SupportedLaneCount>::BitMask::default(); - if value { - mask.as_mut().fill(u8::MAX) - } else { - mask.as_mut().fill(u8::MIN) - } - if N % 8 > 0 { - *mask.as_mut().last_mut().unwrap() &= u8::MAX >> (8 - N % 8); - } - Self(mask, PhantomData) + #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] + pub(crate) const fn splat(value: bool) -> Self { + Self( + if value { + as SupportedLaneCount>::FULL_BIT_MASK + } else { + as SupportedLaneCount>::EMPTY_BIT_MASK + }, + PhantomData, + ) } #[inline] @@ -131,7 +130,7 @@ where #[inline] pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self { - let mut bytes = as SupportedLaneCount>::BitMask::default(); + let mut bytes = as SupportedLaneCount>::BitMask::EMPTY_BIT_MASK; let len = bytes.as_mut().len(); bytes .as_mut() diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index 4e98db4070a9..ddd7fb69b189 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -102,7 +102,8 @@ where { #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) fn splat(value: bool) -> Self { + #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] + pub(crate) const fn splat(value: bool) -> Self { Self(Simd::splat(if value { T::TRUE } else { T::FALSE })) } From b47a091b7df34d0a95913974419076c67a91643d Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 4 Jul 2025 14:22:09 +0000 Subject: [PATCH 0009/3801] clippy fix: use div_ceil --- crates/core_simd/src/lane_count.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/core_simd/src/lane_count.rs b/crates/core_simd/src/lane_count.rs index c62b9d3b7d9b..839195c38eda 100644 --- a/crates/core_simd/src/lane_count.rs +++ b/crates/core_simd/src/lane_count.rs @@ -8,7 +8,7 @@ pub struct LaneCount; impl LaneCount { /// The number of bytes in a bitmask with this many lanes. - pub const BITMASK_LEN: usize = (N + 7) / 8; + pub const BITMASK_LEN: usize = N.div_ceil(8); } /// Statically guarantees that a lane count is marked as supported. @@ -31,13 +31,12 @@ macro_rules! supported_lane_count { ($($lanes:literal),+) => { $( impl SupportedLaneCount for LaneCount<$lanes> { - type BitMask = [u8; ($lanes + 7) / 8]; - const EMPTY_BIT_MASK: Self::BitMask = [0; ($lanes + 7) / 8]; + type BitMask = [u8; Self::BITMASK_LEN]; + const EMPTY_BIT_MASK: Self::BitMask = [0; Self::BITMASK_LEN]; const FULL_BIT_MASK: Self::BitMask = { - const LEN: usize = ($lanes + 7) / 8; - let mut array = [!0u8; LEN]; + let mut array = [!0u8; Self::BITMASK_LEN]; if $lanes % 8 > 0 { - array[LEN - 1] = (!0) >> (8 - $lanes % 8); + array[Self::BITMASK_LEN - 1] = (!0) >> (8 - $lanes % 8); } array }; From 5a26848a5aa9fbaf75eed785acb40fc0010a38ba Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 5 Jul 2025 08:36:27 +0200 Subject: [PATCH 0010/3801] use `div_ceil` instead of manual logic --- crates/core_simd/src/lane_count.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core_simd/src/lane_count.rs b/crates/core_simd/src/lane_count.rs index 280b27bc9bc6..bbdfd5f5f3ed 100644 --- a/crates/core_simd/src/lane_count.rs +++ b/crates/core_simd/src/lane_count.rs @@ -8,7 +8,7 @@ pub struct LaneCount; impl LaneCount { /// The number of bytes in a bitmask with this many lanes. - pub const BITMASK_LEN: usize = (N + 7) / 8; + pub const BITMASK_LEN: usize = N.div_ceil(8); } /// Statically guarantees that a lane count is marked as supported. From 3a0909c7677e0903145fb84a66683d5989eb7b69 Mon Sep 17 00:00:00 2001 From: burgerindividual Date: Mon, 4 Aug 2025 11:29:22 -0400 Subject: [PATCH 0011/3801] Fix incorrect reference to EMPTY_BIT_MASK --- crates/core_simd/src/masks/bitmask.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index ef03ec7f7159..780162c5b4bb 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -130,7 +130,7 @@ where #[inline] pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self { - let mut bytes = as SupportedLaneCount>::BitMask::EMPTY_BIT_MASK; + let mut bytes = as SupportedLaneCount>::EMPTY_BIT_MASK; let len = bytes.as_mut().len(); bytes .as_mut() From b8955c5656e0805847549ac6043d6ae89f7fc0cc Mon Sep 17 00:00:00 2001 From: binarycat Date: Tue, 8 Jul 2025 14:09:34 -0500 Subject: [PATCH 0012/3801] core: add Option::get_or_try_insert_with Co-authored-by: kennytm --- library/core/src/option.rs | 45 +++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index ed070fbd2274..da753f36b16a 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -578,7 +578,7 @@ use crate::iter::{self, FusedIterator, TrustedLen}; use crate::marker::Destruct; -use crate::ops::{self, ControlFlow, Deref, DerefMut}; +use crate::ops::{self, ControlFlow, Deref, DerefMut, Residual, Try}; use crate::panicking::{panic, panic_display}; use crate::pin::Pin; use crate::{cmp, convert, hint, mem, slice}; @@ -1807,6 +1807,49 @@ impl Option { unsafe { self.as_mut().unwrap_unchecked() } } + /// If the option is `None`, calls the closure and inserts its output if successful. + /// + /// If the closure returns a residual value such as `Err` or `None`, + /// that residual value is returned and nothing is inserted. + /// + /// If the option is `Some`, nothing is inserted. + /// + /// Unless a residual is returned, a mutable reference to the value + /// of the option will be output. + /// + /// # Examples + /// + /// ``` + /// #![feature(option_get_or_try_insert_with)] + /// let mut o1: Option = None; + /// let mut o2: Option = None; + /// + /// let number = "12345"; + /// + /// assert_eq!(o1.get_or_try_insert_with(|| number.parse()).copied(), Ok(12345)); + /// assert!(o2.get_or_try_insert_with(|| number.parse()).is_err()); + /// assert_eq!(o1, Some(12345)); + /// assert_eq!(o2, None); + /// ``` + #[inline] + #[unstable(feature = "option_get_or_try_insert_with", issue = "143648")] + pub fn get_or_try_insert_with<'a, R, F>( + &'a mut self, + f: F, + ) -> >::TryType + where + F: FnOnce() -> R, + R: Try>, + { + if let None = self { + *self = Some(f()?); + } + // SAFETY: a `None` variant for `self` would have been replaced by a `Some` + // variant in the code above. + + Try::from_output(unsafe { self.as_mut().unwrap_unchecked() }) + } + ///////////////////////////////////////////////////////////////////////// // Misc ///////////////////////////////////////////////////////////////////////// From 6d2e82b254fef19f51a45cf92c62e2b8d3ce3c6c Mon Sep 17 00:00:00 2001 From: Lee ByeongJun Date: Tue, 12 Aug 2025 07:49:05 +0900 Subject: [PATCH 0013/3801] update rotate operation doc --- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index eb0a5336a1f1..82275d8833a4 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -493,9 +493,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } sym::bitreverse => self.bit_reverse(width, args[0].immediate()), sym::rotate_left | sym::rotate_right => { - // TODO(antoyo): implement using algorithm from: + // Using optimized branchless algorithm from: // https://blog.regehr.org/archives/1063 - // for other platforms. + // This implementation uses the pattern (x<>(-n&(width-1))) + // which generates efficient code for other platforms. let is_left = name == sym::rotate_left; let val = args[0].immediate(); let raw_shift = args[1].immediate(); From fe0db9c71d4c259e5cba5b1f506c89c3846c734e Mon Sep 17 00:00:00 2001 From: Lee ByeongJun Date: Tue, 12 Aug 2025 07:49:05 +0900 Subject: [PATCH 0014/3801] update rotate operation doc --- src/intrinsic/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index eb0a5336a1f1..82275d8833a4 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -493,9 +493,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } sym::bitreverse => self.bit_reverse(width, args[0].immediate()), sym::rotate_left | sym::rotate_right => { - // TODO(antoyo): implement using algorithm from: + // Using optimized branchless algorithm from: // https://blog.regehr.org/archives/1063 - // for other platforms. + // This implementation uses the pattern (x<>(-n&(width-1))) + // which generates efficient code for other platforms. let is_left = name == sym::rotate_left; let val = args[0].immediate(); let raw_shift = args[1].immediate(); From 0e05f58e6284da68f68412fc6dee00d32517f17b Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 12 Aug 2025 11:40:37 +0800 Subject: [PATCH 0015/3801] Fix guess renamed macro braces --- .../ide-completion/src/render/macro_.rs | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs index 35fe407b2e68..6efa8a84553e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs @@ -46,12 +46,17 @@ fn render( ctx.source_range() }; - let (name, escaped_name) = - (name.as_str(), name.display(ctx.db(), completion.edition).to_smolstr()); + let orig_name = macro_.name(ctx.db()); + let (name, orig_name, escaped_name) = ( + name.as_str(), + orig_name.as_str(), + name.display(ctx.db(), completion.edition).to_smolstr(), + ); let docs = ctx.docs(macro_); let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default(); let is_fn_like = macro_.is_fn_like(completion.db); - let (bra, ket) = if is_fn_like { guess_macro_braces(name, docs_str) } else { ("", "") }; + let (bra, ket) = + if is_fn_like { guess_macro_braces(name, orig_name, docs_str) } else { ("", "") }; let needs_bang = is_fn_like && !is_use_path && !has_macro_bang; @@ -109,9 +114,13 @@ fn banged_name(name: &str) -> SmolStr { SmolStr::from_iter([name, "!"]) } -fn guess_macro_braces(macro_name: &str, docs: &str) -> (&'static str, &'static str) { +fn guess_macro_braces( + macro_name: &str, + orig_name: &str, + docs: &str, +) -> (&'static str, &'static str) { let mut votes = [0, 0, 0]; - for (idx, s) in docs.match_indices(¯o_name) { + for (idx, s) in docs.match_indices(macro_name).chain(docs.match_indices(orig_name)) { let (before, after) = (&docs[..idx], &docs[idx + s.len()..]); // Ensure to match the full word if after.starts_with('!') @@ -240,7 +249,25 @@ fn main() { $0 } macro_rules! foo { () => {} } fn main() { foo! {$0} } "#, - ) + ); + + check_edit( + "bar!", + r#" +/// `foo![]` +#[macro_export] +macro_rules! foo { () => {} } +pub use crate::foo as bar; +fn main() { $0 } +"#, + r#" +/// `foo![]` +#[macro_export] +macro_rules! foo { () => {} } +pub use crate::foo as bar; +fn main() { bar![$0] } +"#, + ); } #[test] From 4fa62c6f40c201f0d04c14fb715bca0d7cf5bf4c Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 12 Aug 2025 10:54:36 +0800 Subject: [PATCH 0016/3801] Add guess braces doc `T![]` for `T_` --- .../rust-analyzer/crates/parser/src/syntax_kind/generated.rs | 1 + src/tools/rust-analyzer/xtask/src/codegen/grammar.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index 3a8041d2df9e..2805242ca95e 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -1007,6 +1007,7 @@ impl SyntaxKind { Some(tok) } } +#[doc = r" `T![]`"] #[macro_export] macro_rules ! T_ { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [global_asm] => { $ crate :: SyntaxKind :: GLOBAL_ASM_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [naked_asm] => { $ crate :: SyntaxKind :: NAKED_ASM_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [safe] => { $ crate :: SyntaxKind :: SAFE_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; [frontmatter] => { $ crate :: SyntaxKind :: FRONTMATTER } ; } impl ::core::marker::Copy for SyntaxKind {} diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs index 824b38fc872d..effe150e21f4 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs @@ -659,6 +659,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String { } } + /// `T![]` #[macro_export] macro_rules! T_ { #([#punctuation_values] => { $crate::SyntaxKind::#punctuation };)* From 4816e420d066d52c5de02a7318ca511809faffa9 Mon Sep 17 00:00:00 2001 From: Benjamin Brienen Date: Sun, 17 Aug 2025 01:37:36 +0200 Subject: [PATCH 0017/3801] Remove conflicting advice --- .../docs/book/src/contributing/style.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/style.md b/src/tools/rust-analyzer/docs/book/src/contributing/style.md index fe09fb6c2fd5..0c58a83a1d48 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/style.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/style.md @@ -236,22 +236,6 @@ In the "Good" version, the precondition check and usage are checked in the same **Rationale:** non-local code properties degrade under change. -When checking a boolean precondition, prefer `if !invariant` to `if negated_invariant`: - -```rust -// GOOD -if !(idx < len) { - return None; -} - -// BAD -if idx >= len { - return None; -} -``` - -**Rationale:** it's useful to see the invariant relied upon by the rest of the function clearly spelled out. - ## Control Flow As a special case of the previous rule, do not hide control flow inside functions, push it to the caller: From 3f01c753fd24607e20de083a407a5e9275f1ec78 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Sun, 17 Aug 2025 20:36:53 -0400 Subject: [PATCH 0018/3801] Update nightly toolchain and fix broken examples Update examples to remove features that have been stabilized --- crates/core_simd/examples/dot_product.rs | 34 ++++++++++++------- crates/core_simd/examples/matrix_inversion.rs | 2 +- rust-toolchain.toml | 2 +- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/crates/core_simd/examples/dot_product.rs b/crates/core_simd/examples/dot_product.rs index 75d152ae7f0e..4ef32bfa60b5 100644 --- a/crates/core_simd/examples/dot_product.rs +++ b/crates/core_simd/examples/dot_product.rs @@ -1,8 +1,6 @@ //! Code taken from the `packed_simd` crate. //! Run this code with `cargo test --example dot_product`. -#![feature(array_chunks)] -#![feature(slice_as_chunks)] // Add these imports to use the stdsimd library #![feature(portable_simd)] use core_simd::simd::prelude::*; @@ -33,7 +31,7 @@ pub fn dot_prod_scalar_1(a: &[f32], b: &[f32]) -> f32 { } // We now move on to the SIMD implementations: notice the following constructs: -// `array_chunks::<4>`: mapping this over the vector will let use construct SIMD vectors +// `as_chunks::<4>`: mapping this over the vector will let us construct SIMD vectors // `f32x4::from_array`: construct the SIMD vector from a slice // `(a * b).reduce_sum()`: Multiply both f32x4 vectors together, and then reduce them. // This approach essentially uses SIMD to produce a vector of length N/4 of all the products, @@ -42,9 +40,11 @@ pub fn dot_prod_scalar_1(a: &[f32], b: &[f32]) -> f32 { pub fn dot_prod_simd_0(a: &[f32], b: &[f32]) -> f32 { assert_eq!(a.len(), b.len()); // TODO handle remainder when a.len() % 4 != 0 - a.array_chunks::<4>() + a.as_chunks::<4>() + .0 + .iter() .map(|&a| f32x4::from_array(a)) - .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .zip(b.as_chunks::<4>().0.iter().map(|&b| f32x4::from_array(b))) .map(|(a, b)| (a * b).reduce_sum()) .sum() } @@ -60,9 +60,11 @@ pub fn dot_prod_simd_0(a: &[f32], b: &[f32]) -> f32 { pub fn dot_prod_simd_1(a: &[f32], b: &[f32]) -> f32 { assert_eq!(a.len(), b.len()); // TODO handle remainder when a.len() % 4 != 0 - a.array_chunks::<4>() + a.as_chunks::<4>() + .0 + .iter() .map(|&a| f32x4::from_array(a)) - .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .zip(b.as_chunks::<4>().0.iter().map(|&b| f32x4::from_array(b))) .fold(f32x4::splat(0.0), |acc, zipped| acc + zipped.0 * zipped.1) .reduce_sum() } @@ -74,9 +76,11 @@ pub fn dot_prod_simd_2(a: &[f32], b: &[f32]) -> f32 { assert_eq!(a.len(), b.len()); // TODO handle remainder when a.len() % 4 != 0 let mut res = f32x4::splat(0.0); - a.array_chunks::<4>() + a.as_chunks::<4>() + .0 + .iter() .map(|&a| f32x4::from_array(a)) - .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .zip(b.as_chunks::<4>().0.iter().map(|&b| f32x4::from_array(b))) .for_each(|(a, b)| { res = a.mul_add(b, res); }); @@ -113,9 +117,11 @@ pub fn dot_prod_simd_3(a: &[f32], b: &[f32]) -> f32 { // next example. pub fn dot_prod_simd_4(a: &[f32], b: &[f32]) -> f32 { let mut sum = a - .array_chunks::<4>() + .as_chunks::<4>() + .0 + .iter() .map(|&a| f32x4::from_array(a)) - .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .zip(b.as_chunks::<4>().0.iter().map(|&b| f32x4::from_array(b))) .map(|(a, b)| a * b) .fold(f32x4::splat(0.0), std::ops::Add::add) .reduce_sum(); @@ -131,9 +137,11 @@ pub fn dot_prod_simd_4(a: &[f32], b: &[f32]) -> f32 { // This version allocates a single `XMM` register for accumulation, and the folds don't allocate on top of that. // Notice the use of `mul_add`, which can do a multiply and an add operation ber iteration. pub fn dot_prod_simd_5(a: &[f32], b: &[f32]) -> f32 { - a.array_chunks::<4>() + a.as_chunks::<4>() + .0 + .iter() .map(|&a| f32x4::from_array(a)) - .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .zip(b.as_chunks::<4>().0.iter().map(|&b| f32x4::from_array(b))) .fold(f32x4::splat(0.), |acc, (a, b)| a.mul_add(b, acc)) .reduce_sum() } diff --git a/crates/core_simd/examples/matrix_inversion.rs b/crates/core_simd/examples/matrix_inversion.rs index bad86414401d..ad2eea9153e0 100644 --- a/crates/core_simd/examples/matrix_inversion.rs +++ b/crates/core_simd/examples/matrix_inversion.rs @@ -1,7 +1,7 @@ //! 4x4 matrix inverse // Code ported from the `packed_simd` crate // Run this code with `cargo test --example matrix_inversion` -#![feature(array_chunks, portable_simd)] +#![feature(portable_simd)] use core_simd::simd::prelude::*; // Gotta define our own 4x4 matrix since Rust doesn't ship multidim arrays yet :^) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d17c6d2e8894..df4bd75ecfe2 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-01-16" +channel = "nightly-2025-08-17" components = ["rustfmt", "clippy", "miri", "rust-src"] From 28e79b143328822ac43d9d72f5f0fbf60479c0a5 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Sun, 17 Aug 2025 21:42:22 -0400 Subject: [PATCH 0019/3801] Update Cargo.lock --- Cargo.lock | 267 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 206 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1584c704fb22..d7accf71ab69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,12 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "autocfg" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" @@ -16,31 +16,30 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "core_simd" @@ -55,45 +54,59 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "log" -version = "0.4.20" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "minicov" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b" +dependencies = [ + "cc", + "walkdir", +] [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -114,9 +127,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -167,10 +180,25 @@ dependencies = [ ] [[package]] -name = "scoped-tls" -version = "1.0.1" +name = "rustversion" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "std_float" @@ -184,9 +212,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.29" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -202,29 +230,40 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -233,21 +272,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -255,9 +295,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -268,19 +308,21 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-bindgen-test" -version = "0.3.37" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" +checksum = "66c8d5e33ca3b6d9fa3b4676d774c5778031d27a578c2b007f905acf816152c3" dependencies = [ - "console_error_panic_hook", "js-sys", - "scoped-tls", + "minicov", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test-macro", @@ -288,20 +330,123 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.37" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" +checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b" dependencies = [ "proc-macro2", "quote", + "syn", ] [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", ] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] From 07e9de0f6d73d5c9ffc87dbdc496687fc2ad7200 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Sun, 17 Aug 2025 21:46:26 -0400 Subject: [PATCH 0020/3801] Remove `i586-pc-windows-msvc` from CI --- .github/workflows/ci.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3984d8f0d8d9..96881687af05 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: strategy: fail-fast: false matrix: - target: [x86_64-pc-windows-msvc, i686-pc-windows-msvc, i586-pc-windows-msvc, x86_64-unknown-linux-gnu] + target: [x86_64-pc-windows-msvc, i686-pc-windows-msvc, x86_64-unknown-linux-gnu] # `default` means we use the default target config for the target, # `native` means we run with `-Ctarget-cpu=native`, and anything else is # an arg to `-Ctarget-feature` @@ -68,18 +68,12 @@ jobs: exclude: # -Ctarget-cpu=native sounds like bad-news if target != host - { target: i686-pc-windows-msvc, target_feature: native } - - { target: i586-pc-windows-msvc, target_feature: native } include: # Populate the `matrix.os` field - { target: x86_64-unknown-linux-gnu, os: ubuntu-latest } - { target: x86_64-pc-windows-msvc, os: windows-latest } - { target: i686-pc-windows-msvc, os: windows-latest } - - { target: i586-pc-windows-msvc, os: windows-latest } - - # These are globally available on all the other targets. - - { target: i586-pc-windows-msvc, target_feature: +sse, os: windows-latest } - - { target: i586-pc-windows-msvc, target_feature: +sse2, os: windows-latest } # Annoyingly, the x86_64-unknown-linux-gnu runner *almost* always has # avx512vl, but occasionally doesn't. Maybe one day we can enable it. @@ -129,7 +123,7 @@ jobs: run: cargo doc --verbose --target=${{ matrix.target }} env: RUSTDOCFLAGS: -Dwarnings - + macos-tests: name: ${{ matrix.target }} runs-on: macos-latest From 323484c8278886ffe58e8d355107a5b59ffd85cd Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Mon, 18 Aug 2025 00:42:20 -0400 Subject: [PATCH 0021/3801] Add no-extra-rounding-error flag to Miri CI config --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96881687af05..5344efe1db0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -244,5 +244,10 @@ jobs: PROPTEST_CASES: 16 steps: - uses: actions/checkout@v4 + - name: Download and install nightly + run: | + rustup toolchain install nightly --component miri,rust-src + rustup override set nightly + cargo miri setup - name: Test (Miri) - run: cargo miri test + run: MIRIFLAGS="-Zmiri-no-extra-rounding-error" cargo miri test From c43c8d25a8c4f7035d4265e672f41848effbe615 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Mon, 18 Aug 2025 01:31:25 -0400 Subject: [PATCH 0022/3801] Check some float ops approximately --- Cargo.lock | 10 +++ crates/std_float/tests/float.rs | 29 +++++++- crates/test_helpers/Cargo.toml | 1 + crates/test_helpers/src/approxeq.rs | 110 ++++++++++++++++++++++++++++ crates/test_helpers/src/lib.rs | 76 +++++++++++++++++++ 5 files changed, 222 insertions(+), 4 deletions(-) create mode 100644 crates/test_helpers/src/approxeq.rs diff --git a/Cargo.lock b/Cargo.lock index d7accf71ab69..5a5f0d8907ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,15 @@ dependencies = [ "wasm-bindgen-test", ] +[[package]] +name = "float-cmp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" +dependencies = [ + "num-traits", +] + [[package]] name = "js-sys" version = "0.3.77" @@ -225,6 +234,7 @@ dependencies = [ name = "test_helpers" version = "0.1.0" dependencies = [ + "float-cmp", "proptest", ] diff --git a/crates/std_float/tests/float.rs b/crates/std_float/tests/float.rs index c66c968f8c66..c608ba49564e 100644 --- a/crates/std_float/tests/float.rs +++ b/crates/std_float/tests/float.rs @@ -16,15 +16,33 @@ macro_rules! unary_test { } } -macro_rules! binary_test { +macro_rules! unary_approx_test { { $scalar:tt, $($func:tt),+ } => { test_helpers::test_lanes! { $( fn $func() { - test_helpers::test_binary_elementwise( + test_helpers::test_unary_elementwise_approx( + &core_simd::simd::Simd::<$scalar, LANES>::$func, + &$scalar::$func, + &|_| true, + 8, + ) + } + )* + } + } +} + +macro_rules! binary_approx_test { + { $scalar:tt, $($func:tt),+ } => { + test_helpers::test_lanes! { + $( + fn $func() { + test_helpers::test_binary_elementwise_approx( &core_simd::simd::Simd::<$scalar, LANES>::$func, &$scalar::$func, &|_, _| true, + 16, ) } )* @@ -53,10 +71,13 @@ macro_rules! impl_tests { mod $scalar { use std_float::StdFloat; - unary_test! { $scalar, sqrt, sin, cos, exp, exp2, ln, log2, log10, ceil, floor, round, trunc } - binary_test! { $scalar, log } + unary_test! { $scalar, sqrt, ceil, floor, round, trunc } ternary_test! { $scalar, mul_add } + // https://github.com/rust-lang/miri/issues/3555 + unary_approx_test! { $scalar, sin, cos, exp, exp2, ln, log2, log10 } + binary_approx_test! { $scalar, log } + test_helpers::test_lanes! { fn fract() { test_helpers::test_unary_elementwise_flush_subnormals( diff --git a/crates/test_helpers/Cargo.toml b/crates/test_helpers/Cargo.toml index a5359b9abc84..408bb04c7aa4 100644 --- a/crates/test_helpers/Cargo.toml +++ b/crates/test_helpers/Cargo.toml @@ -6,3 +6,4 @@ publish = false [dependencies] proptest = { version = "0.10", default-features = false, features = ["alloc"] } +float-cmp = "0.10" diff --git a/crates/test_helpers/src/approxeq.rs b/crates/test_helpers/src/approxeq.rs new file mode 100644 index 000000000000..57b43a16bc6f --- /dev/null +++ b/crates/test_helpers/src/approxeq.rs @@ -0,0 +1,110 @@ +//! Compare numeric types approximately. + +use float_cmp::Ulps; + +pub trait ApproxEq { + fn approxeq(&self, other: &Self, _ulps: i64) -> bool; + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result; +} + +impl ApproxEq for bool { + fn approxeq(&self, other: &Self, _ulps: i64) -> bool { + self == other + } + + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:?}", self) + } +} + +macro_rules! impl_integer_approxeq { + { $($type:ty),* } => { + $( + impl ApproxEq for $type { + fn approxeq(&self, other: &Self, _ulps: i64) -> bool { + self == other + } + + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:?} ({:x})", self, self) + } + } + )* + }; +} + +impl_integer_approxeq! { u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize } + +macro_rules! impl_float_approxeq { + { $($type:ty),* } => { + $( + impl ApproxEq for $type { + fn approxeq(&self, other: &Self, ulps: i64) -> bool { + if self.is_nan() && other.is_nan() { + true + } else { + (self.ulps(other) as i64).abs() <= ulps + } + } + + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:?} ({:x})", self, self.to_bits()) + } + } + )* + }; +} + +impl_float_approxeq! { f32, f64 } + +impl ApproxEq for [T; N] { + fn approxeq(&self, other: &Self, ulps: i64) -> bool { + self.iter() + .zip(other.iter()) + .fold(true, |value, (left, right)| { + value && left.approxeq(right, ulps) + }) + } + + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + #[repr(transparent)] + struct Wrapper<'a, T: ApproxEq>(&'a T); + + impl core::fmt::Debug for Wrapper<'_, T> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.fmt(f) + } + } + + f.debug_list() + .entries(self.iter().map(|x| Wrapper(x))) + .finish() + } +} + +#[doc(hidden)] +pub struct ApproxEqWrapper<'a, T>(pub &'a T, pub i64); + +impl PartialEq for ApproxEqWrapper<'_, T> { + fn eq(&self, other: &T) -> bool { + self.0.approxeq(other, self.1) + } +} + +impl core::fmt::Debug for ApproxEqWrapper<'_, T> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.fmt(f) + } +} + +#[macro_export] +macro_rules! prop_assert_approxeq { + { $a:expr, $b:expr, $ulps:expr $(,)? } => { + { + use $crate::approxeq::ApproxEqWrapper; + let a = $a; + let b = $b; + proptest::prop_assert_eq!(ApproxEqWrapper(&a, $ulps), b); + } + }; +} diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 197c920e11ea..35401a9ddb40 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -12,6 +12,9 @@ pub mod wasm; #[macro_use] pub mod biteq; +#[macro_use] +pub mod approxeq; + pub mod subnormals; use subnormals::FlushSubnormals; @@ -185,6 +188,41 @@ pub fn test_unary_elementwise( + fv: &dyn Fn(Vector) -> VectorResult, + fs: &dyn Fn(Scalar) -> ScalarResult, + check: &dyn Fn([Scalar; LANES]) -> bool, + ulps: i64, +) where + Scalar: Copy + core::fmt::Debug + DefaultStrategy, + ScalarResult: Copy + approxeq::ApproxEq + core::fmt::Debug + DefaultStrategy, + Vector: Into<[Scalar; LANES]> + From<[Scalar; LANES]> + Copy, + VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, +{ + test_1(&|x: [Scalar; LANES]| { + proptest::prop_assume!(check(x)); + let result_1: [ScalarResult; LANES] = fv(x.into()).into(); + let result_2: [ScalarResult; LANES] = x + .iter() + .copied() + .map(fs) + .collect::>() + .try_into() + .unwrap(); + crate::prop_assert_approxeq!(result_1, result_2, ulps); + Ok(()) + }); +} + /// Test a unary vector function against a unary scalar function, applied elementwise. /// /// Where subnormals are flushed, use approximate equality. @@ -290,6 +328,44 @@ pub fn test_binary_elementwise< }); } +/// Test a binary vector function against a binary scalar function, applied elementwise. +pub fn test_binary_elementwise_approx< + Scalar1, + Scalar2, + ScalarResult, + Vector1, + Vector2, + VectorResult, + const LANES: usize, +>( + fv: &dyn Fn(Vector1, Vector2) -> VectorResult, + fs: &dyn Fn(Scalar1, Scalar2) -> ScalarResult, + check: &dyn Fn([Scalar1; LANES], [Scalar2; LANES]) -> bool, + ulps: i64, +) where + Scalar1: Copy + core::fmt::Debug + DefaultStrategy, + Scalar2: Copy + core::fmt::Debug + DefaultStrategy, + ScalarResult: Copy + approxeq::ApproxEq + core::fmt::Debug + DefaultStrategy, + Vector1: Into<[Scalar1; LANES]> + From<[Scalar1; LANES]> + Copy, + Vector2: Into<[Scalar2; LANES]> + From<[Scalar2; LANES]> + Copy, + VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, +{ + test_2(&|x: [Scalar1; LANES], y: [Scalar2; LANES]| { + proptest::prop_assume!(check(x, y)); + let result_1: [ScalarResult; LANES] = fv(x.into(), y.into()).into(); + let result_2: [ScalarResult; LANES] = x + .iter() + .copied() + .zip(y.iter().copied()) + .map(|(x, y)| fs(x, y)) + .collect::>() + .try_into() + .unwrap(); + crate::prop_assert_approxeq!(result_1, result_2, ulps); + Ok(()) + }); +} + /// Test a binary vector function against a binary scalar function, applied elementwise. /// /// Where subnormals are flushed, use approximate equality. From b902397bc20e1d0fa5ffe2939b3b9082f2f5b658 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Mon, 18 Aug 2025 01:33:28 -0400 Subject: [PATCH 0023/3801] Clippy isn't aware of repr(simd, packed) --- crates/core_simd/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index 717b882b64ba..9d7dfd2ab351 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -41,7 +41,7 @@ clippy::undocumented_unsafe_blocks )] #![doc(test(attr(deny(warnings))))] -#![allow(internal_features)] +#![allow(internal_features, clippy::repr_packed_without_abi)] #![unstable(feature = "portable_simd", issue = "86656")] //! Portable SIMD module. From 1ce33dd37dd87dc566e0f9ea5b2e15e17c458ee5 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Mon, 18 Aug 2025 01:34:11 -0400 Subject: [PATCH 0024/3801] Revert "Add no-extra-rounding-error flag to Miri CI config" This reverts commit 323484c8278886ffe58e8d355107a5b59ffd85cd. --- .github/workflows/ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5344efe1db0e..96881687af05 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -244,10 +244,5 @@ jobs: PROPTEST_CASES: 16 steps: - uses: actions/checkout@v4 - - name: Download and install nightly - run: | - rustup toolchain install nightly --component miri,rust-src - rustup override set nightly - cargo miri setup - name: Test (Miri) - run: MIRIFLAGS="-Zmiri-no-extra-rounding-error" cargo miri test + run: cargo miri test From 61c45c164a7a9ebf3107eb6d8735514ee3221053 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Fri, 8 Aug 2025 16:31:47 +0800 Subject: [PATCH 0025/3801] loongarch64: Use unified data types for SIMD intrinsics --- crates/core_simd/src/vendor/loongarch64.rs | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/core_simd/src/vendor/loongarch64.rs b/crates/core_simd/src/vendor/loongarch64.rs index 13dda4769aba..1f84cdb971ec 100644 --- a/crates/core_simd/src/vendor/loongarch64.rs +++ b/crates/core_simd/src/vendor/loongarch64.rs @@ -1,26 +1,26 @@ use crate::simd::*; use core::arch::loongarch64::*; -from_transmute! { unsafe u8x16 => v16u8 } -from_transmute! { unsafe u8x32 => v32u8 } -from_transmute! { unsafe i8x16 => v16i8 } -from_transmute! { unsafe i8x32 => v32i8 } +from_transmute! { unsafe u8x16 => m128i } +from_transmute! { unsafe u8x32 => m256i } +from_transmute! { unsafe i8x16 => m128i } +from_transmute! { unsafe i8x32 => m256i } -from_transmute! { unsafe u16x8 => v8u16 } -from_transmute! { unsafe u16x16 => v16u16 } -from_transmute! { unsafe i16x8 => v8i16 } -from_transmute! { unsafe i16x16 => v16i16 } +from_transmute! { unsafe u16x8 => m128i } +from_transmute! { unsafe u16x16 => m256i } +from_transmute! { unsafe i16x8 => m128i } +from_transmute! { unsafe i16x16 => m256i } -from_transmute! { unsafe u32x4 => v4u32 } -from_transmute! { unsafe u32x8 => v8u32 } -from_transmute! { unsafe i32x4 => v4i32 } -from_transmute! { unsafe i32x8 => v8i32 } -from_transmute! { unsafe f32x4 => v4f32 } -from_transmute! { unsafe f32x8 => v8f32 } +from_transmute! { unsafe u32x4 => m128i } +from_transmute! { unsafe u32x8 => m256i } +from_transmute! { unsafe i32x4 => m128i } +from_transmute! { unsafe i32x8 => m256i } +from_transmute! { unsafe f32x4 => m128 } +from_transmute! { unsafe f32x8 => m256 } -from_transmute! { unsafe u64x2 => v2u64 } -from_transmute! { unsafe u64x4 => v4u64 } -from_transmute! { unsafe i64x2 => v2i64 } -from_transmute! { unsafe i64x4 => v4i64 } -from_transmute! { unsafe f64x2 => v2f64 } -from_transmute! { unsafe f64x4 => v4f64 } +from_transmute! { unsafe u64x2 => m128i } +from_transmute! { unsafe u64x4 => m256i } +from_transmute! { unsafe i64x2 => m128i } +from_transmute! { unsafe i64x4 => m256i } +from_transmute! { unsafe f64x2 => m128d } +from_transmute! { unsafe f64x4 => m256d } From 09186d3f811c97eb0d77c74089e6bdccfa1cae8a Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 30 Aug 2025 22:25:50 +0800 Subject: [PATCH 0026/3801] Fix nested if-let for merge_nested_if ```rust fn f() { $0if let Some(x) = y { if x == 4 { 1 } } } ``` -> ```rust fn f() { if let Some(x) = y && x == 4 { 1 } } ``` --- .../src/handlers/merge_nested_if.rs | 42 ++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs index 73cb8204f209..b3487bb62364 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs @@ -1,4 +1,3 @@ -use ide_db::syntax_helpers::node_ext::is_pattern_cond; use syntax::{ T, ast::{self, AstNode, BinaryOp}, @@ -39,10 +38,6 @@ pub(crate) fn merge_nested_if(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt } let cond = expr.condition()?; - //should not apply for if-let - if is_pattern_cond(cond.clone()) { - return None; - } let cond_range = cond.syntax().text_range(); @@ -62,9 +57,6 @@ pub(crate) fn merge_nested_if(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt return None; } let nested_if_cond = nested_if_to_merge.condition()?; - if is_pattern_cond(nested_if_cond.clone()) { - return None; - } let nested_if_then_branch = nested_if_to_merge.then_branch()?; let then_branch_range = then_branch.syntax().text_range(); @@ -171,6 +163,24 @@ mod tests { ) } + #[test] + fn merge_nested_if_test8() { + check_assist( + merge_nested_if, + "fn f() { i$0f let Some(x) = y { if x == 4 { 1 } } }", + "fn f() { if let Some(x) = y && x == 4 { 1 } }", + ) + } + + #[test] + fn merge_nested_if_test9() { + check_assist( + merge_nested_if, + "fn f() { i$0f y == 0 { if let Some(x) = y { 1 } } }", + "fn f() { if y == 0 && let Some(x) = y { 1 } }", + ) + } + #[test] fn merge_nested_if_do_not_apply_to_if_with_else_branch() { check_assist_not_applicable( @@ -187,22 +197,6 @@ mod tests { ) } - #[test] - fn merge_nested_if_do_not_apply_to_if_let() { - check_assist_not_applicable( - merge_nested_if, - "fn f() { i$0f let Some(x) = y { if x == 4 { 1 } } }", - ) - } - - #[test] - fn merge_nested_if_do_not_apply_to_nested_if_let() { - check_assist_not_applicable( - merge_nested_if, - "fn f() { i$0f y == 0 { if let Some(x) = y { 1 } } }", - ) - } - #[test] fn merge_nested_if_do_not_apply_to_if_with_else_branch_and_nested_if() { check_assist_not_applicable( From ccd7b34bb98a3349ee98c5c01cac18986c67a097 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 30 Aug 2025 22:40:13 +0800 Subject: [PATCH 0027/3801] Fix indent for merge_nested_if **Input**: ```rust fn f() { i$0f x == 3 { if y == 4 { 1 } } } ``` **Before this PR**: ```rust fn f() { if x == 3 && y == 4 { 1 } } ``` **After this PR**: ```rust fn f() { if x == 3 && y == 4 { 1 } } ``` --- .../src/handlers/merge_nested_if.rs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs index 73cb8204f209..a997e06fb442 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_nested_if.rs @@ -1,7 +1,7 @@ use ide_db::syntax_helpers::node_ext::is_pattern_cond; use syntax::{ T, - ast::{self, AstNode, BinaryOp}, + ast::{self, AstNode, BinaryOp, edit::AstNodeEdit}, }; use crate::{ @@ -67,7 +67,6 @@ pub(crate) fn merge_nested_if(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt } let nested_if_then_branch = nested_if_to_merge.then_branch()?; - let then_branch_range = then_branch.syntax().text_range(); acc.add(AssistId::refactor_rewrite("merge_nested_if"), "Merge nested if", if_range, |edit| { let cond_text = if has_logic_op_or(&cond) { @@ -85,7 +84,7 @@ pub(crate) fn merge_nested_if(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt let replace_cond = format!("{cond_text} && {nested_if_cond_text}"); edit.replace(cond_range, replace_cond); - edit.replace(then_branch_range, nested_if_then_branch.syntax().text()); + edit.replace_ast(then_branch, nested_if_then_branch.dedent(1.into())); }) } @@ -112,8 +111,20 @@ mod tests { fn merge_nested_if_test1() { check_assist( merge_nested_if, - "fn f() { i$0f x == 3 { if y == 4 { 1 } } }", - "fn f() { if x == 3 && y == 4 { 1 } }", + " + fn f() { + i$0f x == 3 { + if y == 4 { + 1 + } + } + }", + " + fn f() { + if x == 3 && y == 4 { + 1 + } + }", ) } From 8a50a15d72524b5802e45ae23fa6574d3132de6f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sun, 31 Aug 2025 00:04:22 +0200 Subject: [PATCH 0028/3801] make sentence more clear --- src/doc/rustc-dev-guide/src/tests/compiletest.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index 4980ed845d6d..cda5c1bcec71 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -90,7 +90,8 @@ The following test suites are available, with links for more information: | `rustdoc-ui` | Check terminal output of `rustdoc` ([see also](ui.md)) | Some rustdoc-specific tests can also be found in `ui/rustdoc/`. -These check rustdoc-related or -specific lints that (also) run as part of `rustc`, not (only) `rustdoc`. +These tests ensure that lints that are emitted as part of executing rustdoc +are also run when executing rustc. Run-make tests pertaining to rustdoc are typically named `run-make/rustdoc-*/`. [rustdoc-html-tests]: ../rustdoc-internals/rustdoc-test-suite.md From 402c045f7a8f2085dd6552e63d4b6ae26049e9f9 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Tue, 2 Sep 2025 21:34:04 +0200 Subject: [PATCH 0029/3801] docs(std): add missing closing code block fences in doc comments --- crates/core_simd/src/simd/num/int.rs | 1 + crates/core_simd/src/simd/num/uint.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/core_simd/src/simd/num/int.rs b/crates/core_simd/src/simd/num/int.rs index d25050c3e4b4..e7253313f036 100644 --- a/crates/core_simd/src/simd/num/int.rs +++ b/crates/core_simd/src/simd/num/int.rs @@ -58,6 +58,7 @@ pub trait SimdInt: Copy + Sealed { /// let sat = x.saturating_sub(max); /// assert_eq!(unsat, Simd::from_array([1, MAX, MIN, 0])); /// assert_eq!(sat, Simd::from_array([MIN, MIN, MIN, 0])); + /// ``` fn saturating_sub(self, second: Self) -> Self; /// Lanewise absolute value, implemented in Rust. diff --git a/crates/core_simd/src/simd/num/uint.rs b/crates/core_simd/src/simd/num/uint.rs index 45d978068b66..e3ba8658bd80 100644 --- a/crates/core_simd/src/simd/num/uint.rs +++ b/crates/core_simd/src/simd/num/uint.rs @@ -55,6 +55,7 @@ pub trait SimdUint: Copy + Sealed { /// let sat = x.saturating_sub(max); /// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0])); /// assert_eq!(sat, Simd::splat(0)); + /// ``` fn saturating_sub(self, second: Self) -> Self; /// Lanewise absolute difference. From 97d0f6d75368d7c4fad7d715ffb950e68df89773 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 3 Sep 2025 17:26:55 +0800 Subject: [PATCH 0030/3801] Add LetStmt doc for convert_to_guarded_return --- .../src/handlers/convert_to_guarded_return.rs | 15 ++++++++++++++ .../crates/ide-assists/src/tests/generated.rs | 20 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index 2ea032fb62ba..003686d17ce4 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -43,6 +43,21 @@ use crate::{ // bar(); // } // ``` +// --- +// ``` +// //- minicore: option +// fn foo() -> Option { None } +// fn main() { +// $0let x = foo(); +// } +// ``` +// -> +// ``` +// fn foo() -> Option { None } +// fn main() { +// let Some(x) = foo() else { return }; +// } +// ``` pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { if let Some(let_stmt) = ctx.find_node_at_offset() { let_stmt_to_guarded_return(let_stmt, acc, ctx) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 91348be97eb7..88d54ba80a6e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -736,6 +736,26 @@ fn main() { ) } +#[test] +fn doctest_convert_to_guarded_return_1() { + check_doc_test( + "convert_to_guarded_return", + r#####" +//- minicore: option +fn foo() -> Option { None } +fn main() { + $0let x = foo(); +} +"#####, + r#####" +fn foo() -> Option { None } +fn main() { + let Some(x) = foo() else { return }; +} +"#####, + ) +} + #[test] fn doctest_convert_tuple_return_type_to_struct() { check_doc_test( From 1e62d4c87cec532abf267cd5a7cb0342f8369ed1 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Fri, 5 Sep 2025 14:29:26 -0400 Subject: [PATCH 0031/3801] Rename `Mask::to_int` to `Mask::to_simd` --- crates/core_simd/src/masks.rs | 8 ++++---- crates/core_simd/src/masks/bitmask.rs | 2 +- crates/core_simd/src/masks/full_masks.rs | 8 ++++---- crates/core_simd/src/select.rs | 2 +- crates/core_simd/src/simd/cmp/eq.rs | 4 ++-- crates/core_simd/src/simd/cmp/ord.rs | 8 ++++---- crates/core_simd/src/swizzle.rs | 22 +++++++++++----------- crates/core_simd/src/vector.rs | 8 ++++---- crates/core_simd/tests/masks.rs | 2 +- 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index 2b6be3676279..b42cca7c977d 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -175,7 +175,7 @@ where // This would be hypothetically valid as an "in-place" transmute, // but these are "dependently-sized" types, so copy elision it is! unsafe { - let mut bytes: Simd = core::intrinsics::simd::simd_cast(self.to_int()); + let mut bytes: Simd = core::intrinsics::simd::simd_cast(self.to_simd()); bytes &= Simd::splat(1i8); mem::transmute_copy(&bytes) } @@ -214,8 +214,8 @@ where /// represents `true`. #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - pub fn to_int(self) -> Simd { - self.0.to_int() + pub fn to_simd(self) -> Simd { + self.0.to_simd() } /// Converts the mask to a mask of any other element size. @@ -352,7 +352,7 @@ where // Safety: the input and output are integer vectors let index: Simd = unsafe { core::intrinsics::simd::simd_cast(index) }; - let masked_index = self.select(index, Self::splat(true).to_int()); + let masked_index = self.select(index, Self::splat(true).to_simd()); // Safety: the input and output are integer vectors let masked_index: Simd = diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index 780162c5b4bb..4211789da708 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -105,7 +105,7 @@ where #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - pub(crate) fn to_int(self) -> Simd { + pub(crate) fn to_simd(self) -> Simd { unsafe { core::intrinsics::simd::simd_select_bitmask( self.0, diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index ddd7fb69b189..a5382f0ff739 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -120,7 +120,7 @@ where #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - pub(crate) fn to_int(self) -> Simd { + pub(crate) fn to_simd(self) -> Simd { self.0 } @@ -145,7 +145,7 @@ where where LaneCount: SupportedLaneCount, { - let resized = self.to_int().resize::(T::FALSE); + let resized = self.to_simd().resize::(T::FALSE); // Safety: `resized` is an integer vector with length M, which must match T let bitmask: U = unsafe { core::intrinsics::simd::simd_bitmask(resized) }; @@ -223,14 +223,14 @@ where #[must_use = "method returns a new bool and does not mutate the original value"] pub(crate) fn any(self) -> bool { // Safety: use `self` as an integer vector - unsafe { core::intrinsics::simd::simd_reduce_any(self.to_int()) } + unsafe { core::intrinsics::simd::simd_reduce_any(self.to_simd()) } } #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] pub(crate) fn all(self) -> bool { // Safety: use `self` as an integer vector - unsafe { core::intrinsics::simd::simd_reduce_all(self.to_int()) } + unsafe { core::intrinsics::simd::simd_reduce_all(self.to_simd()) } } } diff --git a/crates/core_simd/src/select.rs b/crates/core_simd/src/select.rs index f33aa261a928..a2db455a5268 100644 --- a/crates/core_simd/src/select.rs +++ b/crates/core_simd/src/select.rs @@ -28,7 +28,7 @@ where { // Safety: The mask has been cast to a vector of integers, // and the operands to select between are vectors of the same type and length. - unsafe { core::intrinsics::simd::simd_select(self.to_int(), true_values, false_values) } + unsafe { core::intrinsics::simd::simd_select(self.to_simd(), true_values, false_values) } } /// Choose elements from two masks. diff --git a/crates/core_simd/src/simd/cmp/eq.rs b/crates/core_simd/src/simd/cmp/eq.rs index 2312ba401fa7..3c483f3f94a3 100644 --- a/crates/core_simd/src/simd/cmp/eq.rs +++ b/crates/core_simd/src/simd/cmp/eq.rs @@ -59,14 +59,14 @@ macro_rules! impl_mask { fn simd_eq(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_eq(self.to_int(), other.to_int())) } + unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_eq(self.to_simd(), other.to_simd())) } } #[inline] fn simd_ne(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_ne(self.to_int(), other.to_int())) } + unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_ne(self.to_simd(), other.to_simd())) } } } )* diff --git a/crates/core_simd/src/simd/cmp/ord.rs b/crates/core_simd/src/simd/cmp/ord.rs index e813e7613032..6eb3e360bdeb 100644 --- a/crates/core_simd/src/simd/cmp/ord.rs +++ b/crates/core_simd/src/simd/cmp/ord.rs @@ -163,28 +163,28 @@ macro_rules! impl_mask { fn simd_lt(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_lt(self.to_int(), other.to_int())) } + unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_lt(self.to_simd(), other.to_simd())) } } #[inline] fn simd_le(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_le(self.to_int(), other.to_int())) } + unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_le(self.to_simd(), other.to_simd())) } } #[inline] fn simd_gt(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_gt(self.to_int(), other.to_int())) } + unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_gt(self.to_simd(), other.to_simd())) } } #[inline] fn simd_ge(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_ge(self.to_int(), other.to_int())) } + unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_ge(self.to_simd(), other.to_simd())) } } } diff --git a/crates/core_simd/src/swizzle.rs b/crates/core_simd/src/swizzle.rs index dbdd6ef40eba..b6af2ded1cce 100644 --- a/crates/core_simd/src/swizzle.rs +++ b/crates/core_simd/src/swizzle.rs @@ -165,7 +165,7 @@ pub trait Swizzle { LaneCount: SupportedLaneCount, { // SAFETY: all elements of this mask come from another mask - unsafe { Mask::from_int_unchecked(Self::swizzle(mask.to_int())) } + unsafe { Mask::from_int_unchecked(Self::swizzle(mask.to_simd())) } } /// Creates a new mask from the elements of `first` and `second`. @@ -181,7 +181,7 @@ pub trait Swizzle { LaneCount: SupportedLaneCount, { // SAFETY: all elements of this mask come from another mask - unsafe { Mask::from_int_unchecked(Self::concat_swizzle(first.to_int(), second.to_int())) } + unsafe { Mask::from_int_unchecked(Self::concat_swizzle(first.to_simd(), second.to_simd())) } } } @@ -524,7 +524,7 @@ where #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn reverse(self) -> Self { // Safety: swizzles are safe for masks - unsafe { Self::from_int_unchecked(self.to_int().reverse()) } + unsafe { Self::from_int_unchecked(self.to_simd().reverse()) } } /// Rotates the mask such that the first `OFFSET` elements of the slice move to the end @@ -534,7 +534,7 @@ where #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn rotate_elements_left(self) -> Self { // Safety: swizzles are safe for masks - unsafe { Self::from_int_unchecked(self.to_int().rotate_elements_left::()) } + unsafe { Self::from_int_unchecked(self.to_simd().rotate_elements_left::()) } } /// Rotates the mask such that the first `self.len() - OFFSET` elements of the mask move to @@ -544,7 +544,7 @@ where #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn rotate_elements_right(self) -> Self { // Safety: swizzles are safe for masks - unsafe { Self::from_int_unchecked(self.to_int().rotate_elements_right::()) } + unsafe { Self::from_int_unchecked(self.to_simd().rotate_elements_right::()) } } /// Shifts the mask elements to the left by `OFFSET`, filling in with @@ -554,7 +554,7 @@ where pub fn shift_elements_left(self, padding: bool) -> Self { // Safety: swizzles are safe for masks unsafe { - Self::from_int_unchecked(self.to_int().shift_elements_left::(if padding { + Self::from_int_unchecked(self.to_simd().shift_elements_left::(if padding { T::TRUE } else { T::FALSE @@ -569,7 +569,7 @@ where pub fn shift_elements_right(self, padding: bool) -> Self { // Safety: swizzles are safe for masks unsafe { - Self::from_int_unchecked(self.to_int().shift_elements_right::(if padding { + Self::from_int_unchecked(self.to_simd().shift_elements_right::(if padding { T::TRUE } else { T::FALSE @@ -598,7 +598,7 @@ where #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn interleave(self, other: Self) -> (Self, Self) { - let (lo, hi) = self.to_int().interleave(other.to_int()); + let (lo, hi) = self.to_simd().interleave(other.to_simd()); // Safety: swizzles are safe for masks unsafe { (Self::from_int_unchecked(lo), Self::from_int_unchecked(hi)) } } @@ -627,7 +627,7 @@ where #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn deinterleave(self, other: Self) -> (Self, Self) { - let (even, odd) = self.to_int().deinterleave(other.to_int()); + let (even, odd) = self.to_simd().deinterleave(other.to_simd()); // Safety: swizzles are safe for masks unsafe { ( @@ -659,7 +659,7 @@ where { // Safety: swizzles are safe for masks unsafe { - Mask::::from_int_unchecked(self.to_int().resize::(if value { + Mask::::from_int_unchecked(self.to_simd().resize::(if value { T::TRUE } else { T::FALSE @@ -684,6 +684,6 @@ where LaneCount: SupportedLaneCount, { // Safety: swizzles are safe for masks - unsafe { Mask::::from_int_unchecked(self.to_int().extract::()) } + unsafe { Mask::::from_int_unchecked(self.to_simd().extract::()) } } } diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index 984a356c6552..1f15c9f85c71 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -474,7 +474,7 @@ where or: Self, ) -> Self { // SAFETY: The safety of reading elements through `ptr` is ensured by the caller. - unsafe { core::intrinsics::simd::simd_masked_load(enable.to_int(), ptr, or) } + unsafe { core::intrinsics::simd::simd_masked_load(enable.to_simd(), ptr, or) } } /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector. @@ -652,7 +652,7 @@ where or: Self, ) -> Self { // Safety: The caller is responsible for upholding all invariants - unsafe { core::intrinsics::simd::simd_gather(or, source, enable.to_int()) } + unsafe { core::intrinsics::simd::simd_gather(or, source, enable.to_simd()) } } /// Conditionally write contiguous elements to `slice`. The `enable` mask controls @@ -723,7 +723,7 @@ where #[inline] pub unsafe fn store_select_ptr(self, ptr: *mut T, enable: Mask<::Mask, N>) { // SAFETY: The safety of writing elements through `ptr` is ensured by the caller. - unsafe { core::intrinsics::simd::simd_masked_store(enable.to_int(), ptr, self) } + unsafe { core::intrinsics::simd::simd_masked_store(enable.to_simd(), ptr, self) } } /// Writes the values in a SIMD vector to potentially discontiguous indices in `slice`. @@ -882,7 +882,7 @@ where #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn scatter_select_ptr(self, dest: Simd<*mut T, N>, enable: Mask) { // Safety: The caller is responsible for upholding all invariants - unsafe { core::intrinsics::simd::simd_scatter(self, dest, enable.to_int()) } + unsafe { core::intrinsics::simd::simd_scatter(self, dest, enable.to_simd()) } } } diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs index 48786d02440b..be7c5a27e86f 100644 --- a/crates/core_simd/tests/masks.rs +++ b/crates/core_simd/tests/masks.rs @@ -65,7 +65,7 @@ macro_rules! test_mask_api { fn roundtrip_int_conversion() { let values = [true, false, false, true, false, false, true, false]; let mask = Mask::<$type, 8>::from_array(values); - let int = mask.to_int(); + let int = mask.to_simd(); assert_eq!(int.to_array(), [-1, 0, 0, -1, 0, 0, -1, 0]); assert_eq!(Mask::<$type, 8>::from_int(int), mask); } From 42409f05bf162f4fac8e7010892c08539ccfa034 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Fri, 5 Sep 2025 14:30:44 -0400 Subject: [PATCH 0032/3801] Rename `Mask::from_int` to `Mask::from_simd` --- crates/core_simd/src/masks.rs | 2 +- crates/core_simd/tests/masks.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index b42cca7c977d..022003ef4dcc 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -204,7 +204,7 @@ where #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] #[track_caller] - pub fn from_int(value: Simd) -> Self { + pub fn from_simd(value: Simd) -> Self { assert!(T::valid(value), "all values must be either 0 or -1",); // Safety: the validity has been checked unsafe { Self::from_int_unchecked(value) } diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs index be7c5a27e86f..53fb2367b605 100644 --- a/crates/core_simd/tests/masks.rs +++ b/crates/core_simd/tests/masks.rs @@ -67,7 +67,7 @@ macro_rules! test_mask_api { let mask = Mask::<$type, 8>::from_array(values); let int = mask.to_simd(); assert_eq!(int.to_array(), [-1, 0, 0, -1, 0, 0, -1, 0]); - assert_eq!(Mask::<$type, 8>::from_int(int), mask); + assert_eq!(Mask::<$type, 8>::from_simd(int), mask); } #[test] From 3a70dd6a69e0eb4b7d72e812cf32204ba2e7669c Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Fri, 5 Sep 2025 14:32:40 -0400 Subject: [PATCH 0033/3801] Rename `Mask::from_int_unchecked` to `Mask::from_simd_unchecked` --- crates/core_simd/src/masks.rs | 8 ++++---- crates/core_simd/src/masks/bitmask.rs | 2 +- crates/core_simd/src/masks/full_masks.rs | 4 ++-- crates/core_simd/src/simd/cmp/eq.rs | 8 ++++---- crates/core_simd/src/simd/cmp/ord.rs | 24 +++++++++++----------- crates/core_simd/src/swizzle.rs | 26 +++++++++++++----------- crates/core_simd/src/vector.rs | 4 ++-- 7 files changed, 39 insertions(+), 37 deletions(-) diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index 022003ef4dcc..ca1e3db8b46f 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -157,7 +157,7 @@ where let bytes: [u8; N] = mem::transmute_copy(&array); let bools: Simd = core::intrinsics::simd::simd_ne(Simd::from_array(bytes), Simd::splat(0u8)); - Mask::from_int_unchecked(core::intrinsics::simd::simd_cast(bools)) + Mask::from_simd_unchecked(core::intrinsics::simd::simd_cast(bools)) } } @@ -188,11 +188,11 @@ where /// All elements must be either 0 or -1. #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub unsafe fn from_int_unchecked(value: Simd) -> Self { + pub unsafe fn from_simd_unchecked(value: Simd) -> Self { // Safety: the caller must confirm this invariant unsafe { core::intrinsics::assume(::valid(value)); - Self(mask_impl::Mask::from_int_unchecked(value)) + Self(mask_impl::Mask::from_simd_unchecked(value)) } } @@ -207,7 +207,7 @@ where pub fn from_simd(value: Simd) -> Self { assert!(T::valid(value), "all values must be either 0 or -1",); // Safety: the validity has been checked - unsafe { Self::from_int_unchecked(value) } + unsafe { Self::from_simd_unchecked(value) } } /// Converts the mask to a vector of integers, where 0 represents `false` and -1 diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index 4211789da708..83ee88c372ab 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -117,7 +117,7 @@ where #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) unsafe fn from_int_unchecked(value: Simd) -> Self { + pub(crate) unsafe fn from_simd_unchecked(value: Simd) -> Self { unsafe { Self(core::intrinsics::simd::simd_bitmask(value), PhantomData) } } diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index a5382f0ff739..5ad2c1d1eaf6 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -126,7 +126,7 @@ where #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) unsafe fn from_int_unchecked(value: Simd) -> Self { + pub(crate) unsafe fn from_simd_unchecked(value: Simd) -> Self { Self(value) } @@ -180,7 +180,7 @@ where }; // SAFETY: `mask` only contains `T::TRUE` or `T::FALSE` - unsafe { Self::from_int_unchecked(mask.resize::(T::FALSE)) } + unsafe { Self::from_simd_unchecked(mask.resize::(T::FALSE)) } } #[inline] diff --git a/crates/core_simd/src/simd/cmp/eq.rs b/crates/core_simd/src/simd/cmp/eq.rs index 3c483f3f94a3..789fc0bb9424 100644 --- a/crates/core_simd/src/simd/cmp/eq.rs +++ b/crates/core_simd/src/simd/cmp/eq.rs @@ -30,14 +30,14 @@ macro_rules! impl_number { fn simd_eq(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_eq(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_eq(self, other)) } } #[inline] fn simd_ne(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_ne(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ne(self, other)) } } } )* @@ -59,14 +59,14 @@ macro_rules! impl_mask { fn simd_eq(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_eq(self.to_simd(), other.to_simd())) } + unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_eq(self.to_simd(), other.to_simd())) } } #[inline] fn simd_ne(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_ne(self.to_simd(), other.to_simd())) } + unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ne(self.to_simd(), other.to_simd())) } } } )* diff --git a/crates/core_simd/src/simd/cmp/ord.rs b/crates/core_simd/src/simd/cmp/ord.rs index 6eb3e360bdeb..4b2d0b55feba 100644 --- a/crates/core_simd/src/simd/cmp/ord.rs +++ b/crates/core_simd/src/simd/cmp/ord.rs @@ -56,28 +56,28 @@ macro_rules! impl_integer { fn simd_lt(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_lt(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_lt(self, other)) } } #[inline] fn simd_le(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_le(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_le(self, other)) } } #[inline] fn simd_gt(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_gt(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_gt(self, other)) } } #[inline] fn simd_ge(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_ge(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ge(self, other)) } } } @@ -122,28 +122,28 @@ macro_rules! impl_float { fn simd_lt(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_lt(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_lt(self, other)) } } #[inline] fn simd_le(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_le(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_le(self, other)) } } #[inline] fn simd_gt(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_gt(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_gt(self, other)) } } #[inline] fn simd_ge(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Mask::from_int_unchecked(core::intrinsics::simd::simd_ge(self, other)) } + unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ge(self, other)) } } } )* @@ -163,28 +163,28 @@ macro_rules! impl_mask { fn simd_lt(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_lt(self.to_simd(), other.to_simd())) } + unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_lt(self.to_simd(), other.to_simd())) } } #[inline] fn simd_le(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_le(self.to_simd(), other.to_simd())) } + unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_le(self.to_simd(), other.to_simd())) } } #[inline] fn simd_gt(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_gt(self.to_simd(), other.to_simd())) } + unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_gt(self.to_simd(), other.to_simd())) } } #[inline] fn simd_ge(self, other: Self) -> Self::Mask { // Safety: `self` is a vector, and the result of the comparison // is always a valid mask. - unsafe { Self::from_int_unchecked(core::intrinsics::simd::simd_ge(self.to_simd(), other.to_simd())) } + unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ge(self.to_simd(), other.to_simd())) } } } diff --git a/crates/core_simd/src/swizzle.rs b/crates/core_simd/src/swizzle.rs index b6af2ded1cce..81085a9ee4a3 100644 --- a/crates/core_simd/src/swizzle.rs +++ b/crates/core_simd/src/swizzle.rs @@ -165,7 +165,7 @@ pub trait Swizzle { LaneCount: SupportedLaneCount, { // SAFETY: all elements of this mask come from another mask - unsafe { Mask::from_int_unchecked(Self::swizzle(mask.to_simd())) } + unsafe { Mask::from_simd_unchecked(Self::swizzle(mask.to_simd())) } } /// Creates a new mask from the elements of `first` and `second`. @@ -181,7 +181,9 @@ pub trait Swizzle { LaneCount: SupportedLaneCount, { // SAFETY: all elements of this mask come from another mask - unsafe { Mask::from_int_unchecked(Self::concat_swizzle(first.to_simd(), second.to_simd())) } + unsafe { + Mask::from_simd_unchecked(Self::concat_swizzle(first.to_simd(), second.to_simd())) + } } } @@ -524,7 +526,7 @@ where #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn reverse(self) -> Self { // Safety: swizzles are safe for masks - unsafe { Self::from_int_unchecked(self.to_simd().reverse()) } + unsafe { Self::from_simd_unchecked(self.to_simd().reverse()) } } /// Rotates the mask such that the first `OFFSET` elements of the slice move to the end @@ -534,7 +536,7 @@ where #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn rotate_elements_left(self) -> Self { // Safety: swizzles are safe for masks - unsafe { Self::from_int_unchecked(self.to_simd().rotate_elements_left::()) } + unsafe { Self::from_simd_unchecked(self.to_simd().rotate_elements_left::()) } } /// Rotates the mask such that the first `self.len() - OFFSET` elements of the mask move to @@ -544,7 +546,7 @@ where #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn rotate_elements_right(self) -> Self { // Safety: swizzles are safe for masks - unsafe { Self::from_int_unchecked(self.to_simd().rotate_elements_right::()) } + unsafe { Self::from_simd_unchecked(self.to_simd().rotate_elements_right::()) } } /// Shifts the mask elements to the left by `OFFSET`, filling in with @@ -554,7 +556,7 @@ where pub fn shift_elements_left(self, padding: bool) -> Self { // Safety: swizzles are safe for masks unsafe { - Self::from_int_unchecked(self.to_simd().shift_elements_left::(if padding { + Self::from_simd_unchecked(self.to_simd().shift_elements_left::(if padding { T::TRUE } else { T::FALSE @@ -569,7 +571,7 @@ where pub fn shift_elements_right(self, padding: bool) -> Self { // Safety: swizzles are safe for masks unsafe { - Self::from_int_unchecked(self.to_simd().shift_elements_right::(if padding { + Self::from_simd_unchecked(self.to_simd().shift_elements_right::(if padding { T::TRUE } else { T::FALSE @@ -600,7 +602,7 @@ where pub fn interleave(self, other: Self) -> (Self, Self) { let (lo, hi) = self.to_simd().interleave(other.to_simd()); // Safety: swizzles are safe for masks - unsafe { (Self::from_int_unchecked(lo), Self::from_int_unchecked(hi)) } + unsafe { (Self::from_simd_unchecked(lo), Self::from_simd_unchecked(hi)) } } /// Deinterleave two masks. @@ -631,8 +633,8 @@ where // Safety: swizzles are safe for masks unsafe { ( - Self::from_int_unchecked(even), - Self::from_int_unchecked(odd), + Self::from_simd_unchecked(even), + Self::from_simd_unchecked(odd), ) } } @@ -659,7 +661,7 @@ where { // Safety: swizzles are safe for masks unsafe { - Mask::::from_int_unchecked(self.to_simd().resize::(if value { + Mask::::from_simd_unchecked(self.to_simd().resize::(if value { T::TRUE } else { T::FALSE @@ -684,6 +686,6 @@ where LaneCount: SupportedLaneCount, { // Safety: swizzles are safe for masks - unsafe { Mask::::from_int_unchecked(self.to_simd().extract::()) } + unsafe { Mask::::from_simd_unchecked(self.to_simd().extract::()) } } } diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index 1f15c9f85c71..c00cfcdd41ff 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -926,7 +926,7 @@ where let mask = unsafe { let tfvec: Simd<::Mask, N> = core::intrinsics::simd::simd_eq(*self, *other); - Mask::from_int_unchecked(tfvec) + Mask::from_simd_unchecked(tfvec) }; // Two vectors are equal if all elements are equal when compared elementwise @@ -940,7 +940,7 @@ where let mask = unsafe { let tfvec: Simd<::Mask, N> = core::intrinsics::simd::simd_ne(*self, *other); - Mask::from_int_unchecked(tfvec) + Mask::from_simd_unchecked(tfvec) }; // Two vectors are non-equal if any elements are non-equal when compared elementwise From 32ba8edf03c233640569c1f9a0bf4529c3a6608c Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Fri, 12 Sep 2025 22:03:51 -0400 Subject: [PATCH 0034/3801] Remove poor-performing bitmasks, add Select trait, and enable select on integer bitmasks (#482) --- crates/core_simd/src/masks.rs | 123 +++++++--- crates/core_simd/src/masks/bitmask.rs | 231 ------------------ crates/core_simd/src/masks/full_masks.rs | 297 ----------------------- crates/core_simd/src/mod.rs | 1 + crates/core_simd/src/ops.rs | 2 +- crates/core_simd/src/select.rs | 199 +++++++++++---- crates/core_simd/src/simd/cmp/ord.rs | 6 +- crates/core_simd/src/simd/num/float.rs | 2 +- crates/core_simd/src/simd/num/int.rs | 2 +- crates/core_simd/src/swizzle_dyn.rs | 4 +- 10 files changed, 248 insertions(+), 619 deletions(-) delete mode 100644 crates/core_simd/src/masks/bitmask.rs delete mode 100644 crates/core_simd/src/masks/full_masks.rs diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index ca1e3db8b46f..7baa96475910 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -2,20 +2,33 @@ //! Types representing #![allow(non_camel_case_types)] -#[cfg_attr( - not(all(target_arch = "x86_64", target_feature = "avx512f")), - path = "masks/full_masks.rs" -)] -#[cfg_attr( - all(target_arch = "x86_64", target_feature = "avx512f"), - path = "masks/bitmask.rs" -)] -mod mask_impl; - -use crate::simd::{LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount}; +use crate::simd::{LaneCount, Select, Simd, SimdCast, SimdElement, SupportedLaneCount}; use core::cmp::Ordering; use core::{fmt, mem}; +pub(crate) trait FixEndianness { + fn fix_endianness(self) -> Self; +} + +macro_rules! impl_fix_endianness { + { $($int:ty),* } => { + $( + impl FixEndianness for $int { + #[inline(always)] + fn fix_endianness(self) -> Self { + if cfg!(target_endian = "big") { + <$int>::reverse_bits(self) + } else { + self + } + } + } + )* + } +} + +impl_fix_endianness! { u8, u16, u32, u64 } + mod sealed { use super::*; @@ -109,7 +122,7 @@ impl_element! { isize, usize } /// and/or Rust versions, and code should not assume that it is equivalent to /// `[T; N]`. #[repr(transparent)] -pub struct Mask(mask_impl::Mask) +pub struct Mask(Simd) where T: MaskElement, LaneCount: SupportedLaneCount; @@ -141,7 +154,7 @@ where #[inline] #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] pub const fn splat(value: bool) -> Self { - Self(mask_impl::Mask::splat(value)) + Self(Simd::splat(if value { T::TRUE } else { T::FALSE })) } /// Converts an array of bools to a SIMD mask. @@ -192,8 +205,8 @@ where // Safety: the caller must confirm this invariant unsafe { core::intrinsics::assume(::valid(value)); - Self(mask_impl::Mask::from_simd_unchecked(value)) } + Self(value) } /// Converts a vector of integers to a mask, where 0 represents `false` and -1 @@ -215,14 +228,15 @@ where #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] pub fn to_simd(self) -> Simd { - self.0.to_simd() + self.0 } /// Converts the mask to a mask of any other element size. #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] pub fn cast(self) -> Mask { - Mask(self.0.convert()) + // Safety: mask elements are integers + unsafe { Mask(core::intrinsics::simd::simd_as(self.0)) } } /// Tests the value of the specified element. @@ -233,7 +247,7 @@ where #[must_use = "method returns a new bool and does not mutate the original value"] pub unsafe fn test_unchecked(&self, index: usize) -> bool { // Safety: the caller must confirm this invariant - unsafe { self.0.test_unchecked(index) } + unsafe { T::eq(*self.0.as_array().get_unchecked(index), T::TRUE) } } /// Tests the value of the specified element. @@ -244,9 +258,7 @@ where #[must_use = "method returns a new bool and does not mutate the original value"] #[track_caller] pub fn test(&self, index: usize) -> bool { - assert!(index < N, "element index out of range"); - // Safety: the element index has been checked - unsafe { self.test_unchecked(index) } + T::eq(self.0[index], T::TRUE) } /// Sets the value of the specified element. @@ -257,7 +269,7 @@ where pub unsafe fn set_unchecked(&mut self, index: usize, value: bool) { // Safety: the caller must confirm this invariant unsafe { - self.0.set_unchecked(index, value); + *self.0.as_mut_array().get_unchecked_mut(index) = if value { T::TRUE } else { T::FALSE } } } @@ -268,35 +280,67 @@ where #[inline] #[track_caller] pub fn set(&mut self, index: usize, value: bool) { - assert!(index < N, "element index out of range"); - // Safety: the element index has been checked - unsafe { - self.set_unchecked(index, value); - } + self.0[index] = if value { T::TRUE } else { T::FALSE } } /// Returns true if any element is set, or false otherwise. #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] pub fn any(self) -> bool { - self.0.any() + // Safety: `self` is a mask vector + unsafe { core::intrinsics::simd::simd_reduce_any(self.0) } } /// Returns true if all elements are set, or false otherwise. #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] pub fn all(self) -> bool { - self.0.all() + // Safety: `self` is a mask vector + unsafe { core::intrinsics::simd::simd_reduce_all(self.0) } } /// Creates a bitmask from a mask. /// /// Each bit is set if the corresponding element in the mask is `true`. - /// If the mask contains more than 64 elements, the bitmask is truncated to the first 64. #[inline] #[must_use = "method returns a new integer and does not mutate the original value"] pub fn to_bitmask(self) -> u64 { - self.0.to_bitmask_integer() + const { + assert!(N <= 64, "number of elements can't be greater than 64"); + } + + #[inline] + unsafe fn to_bitmask_impl( + mask: Mask, + ) -> U + where + T: MaskElement, + LaneCount: SupportedLaneCount, + LaneCount: SupportedLaneCount, + { + let resized = mask.resize::(false); + + // Safety: `resized` is an integer vector with length M, which must match T + let bitmask: U = unsafe { core::intrinsics::simd::simd_bitmask(resized.0) }; + + // LLVM assumes bit order should match endianness + bitmask.fix_endianness() + } + + // TODO modify simd_bitmask to zero-extend output, making this unnecessary + if N <= 8 { + // Safety: bitmask matches length + unsafe { to_bitmask_impl::(self) as u64 } + } else if N <= 16 { + // Safety: bitmask matches length + unsafe { to_bitmask_impl::(self) as u64 } + } else if N <= 32 { + // Safety: bitmask matches length + unsafe { to_bitmask_impl::(self) as u64 } + } else { + // Safety: bitmask matches length + unsafe { to_bitmask_impl::(self) } + } } /// Creates a mask from a bitmask. @@ -306,7 +350,7 @@ where #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] pub fn from_bitmask(bitmask: u64) -> Self { - Self(mask_impl::Mask::from_bitmask_integer(bitmask)) + Self(bitmask.select(Simd::splat(T::TRUE), Simd::splat(T::FALSE))) } /// Finds the index of the first set element. @@ -450,7 +494,8 @@ where type Output = Self; #[inline] fn bitand(self, rhs: Self) -> Self { - Self(self.0 & rhs.0) + // Safety: `self` is an integer vector + unsafe { Self(core::intrinsics::simd::simd_and(self.0, rhs.0)) } } } @@ -486,7 +531,8 @@ where type Output = Self; #[inline] fn bitor(self, rhs: Self) -> Self { - Self(self.0 | rhs.0) + // Safety: `self` is an integer vector + unsafe { Self(core::intrinsics::simd::simd_or(self.0, rhs.0)) } } } @@ -522,7 +568,8 @@ where type Output = Self; #[inline] fn bitxor(self, rhs: Self) -> Self::Output { - Self(self.0 ^ rhs.0) + // Safety: `self` is an integer vector + unsafe { Self(core::intrinsics::simd::simd_xor(self.0, rhs.0)) } } } @@ -558,7 +605,7 @@ where type Output = Mask; #[inline] fn not(self) -> Self::Output { - Self(!self.0) + Self::splat(true) ^ self } } @@ -569,7 +616,7 @@ where { #[inline] fn bitand_assign(&mut self, rhs: Self) { - self.0 = self.0 & rhs.0; + *self = *self & rhs; } } @@ -591,7 +638,7 @@ where { #[inline] fn bitor_assign(&mut self, rhs: Self) { - self.0 = self.0 | rhs.0; + *self = *self | rhs; } } @@ -613,7 +660,7 @@ where { #[inline] fn bitxor_assign(&mut self, rhs: Self) { - self.0 = self.0 ^ rhs.0; + *self = *self ^ rhs; } } diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs deleted file mode 100644 index 83ee88c372ab..000000000000 --- a/crates/core_simd/src/masks/bitmask.rs +++ /dev/null @@ -1,231 +0,0 @@ -#![allow(unused_imports)] -use super::MaskElement; -use crate::simd::{LaneCount, Simd, SupportedLaneCount}; -use core::marker::PhantomData; - -/// A mask where each lane is represented by a single bit. -#[repr(transparent)] -pub(crate) struct Mask( - as SupportedLaneCount>::BitMask, - PhantomData, -) -where - T: MaskElement, - LaneCount: SupportedLaneCount; - -impl Copy for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ -} - -impl Clone for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - #[inline] - fn clone(&self) -> Self { - *self - } -} - -impl PartialEq for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - #[inline] - fn eq(&self, other: &Self) -> bool { - self.0.as_ref() == other.0.as_ref() - } -} - -impl PartialOrd for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - self.0.as_ref().partial_cmp(other.0.as_ref()) - } -} - -impl Eq for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ -} - -impl Ord for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - #[inline] - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.0.as_ref().cmp(other.0.as_ref()) - } -} - -impl Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] - pub(crate) const fn splat(value: bool) -> Self { - Self( - if value { - as SupportedLaneCount>::FULL_BIT_MASK - } else { - as SupportedLaneCount>::EMPTY_BIT_MASK - }, - PhantomData, - ) - } - - #[inline] - #[must_use = "method returns a new bool and does not mutate the original value"] - pub(crate) unsafe fn test_unchecked(&self, lane: usize) -> bool { - (self.0.as_ref()[lane / 8] >> (lane % 8)) & 0x1 > 0 - } - - #[inline] - pub(crate) unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { - unsafe { - self.0.as_mut()[lane / 8] ^= ((value ^ self.test_unchecked(lane)) as u8) << (lane % 8) - } - } - - #[inline] - #[must_use = "method returns a new vector and does not mutate the original value"] - pub(crate) fn to_simd(self) -> Simd { - unsafe { - core::intrinsics::simd::simd_select_bitmask( - self.0, - Simd::splat(T::TRUE), - Simd::splat(T::FALSE), - ) - } - } - - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) unsafe fn from_simd_unchecked(value: Simd) -> Self { - unsafe { Self(core::intrinsics::simd::simd_bitmask(value), PhantomData) } - } - - #[inline] - pub(crate) fn to_bitmask_integer(self) -> u64 { - let mut bitmask = [0u8; 8]; - bitmask[..self.0.as_ref().len()].copy_from_slice(self.0.as_ref()); - u64::from_ne_bytes(bitmask) - } - - #[inline] - pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self { - let mut bytes = as SupportedLaneCount>::EMPTY_BIT_MASK; - let len = bytes.as_mut().len(); - bytes - .as_mut() - .copy_from_slice(&bitmask.to_ne_bytes()[..len]); - Self(bytes, PhantomData) - } - - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) fn convert(self) -> Mask - where - U: MaskElement, - { - // Safety: bitmask layout does not depend on the element width - unsafe { core::mem::transmute_copy(&self) } - } - - #[inline] - #[must_use = "method returns a new bool and does not mutate the original value"] - pub(crate) fn any(self) -> bool { - self != Self::splat(false) - } - - #[inline] - #[must_use = "method returns a new bool and does not mutate the original value"] - pub(crate) fn all(self) -> bool { - self == Self::splat(true) - } -} - -impl core::ops::BitAnd for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, - as SupportedLaneCount>::BitMask: AsRef<[u8]> + AsMut<[u8]>, -{ - type Output = Self; - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - fn bitand(mut self, rhs: Self) -> Self { - for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { - *l &= r; - } - self - } -} - -impl core::ops::BitOr for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, - as SupportedLaneCount>::BitMask: AsRef<[u8]> + AsMut<[u8]>, -{ - type Output = Self; - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - fn bitor(mut self, rhs: Self) -> Self { - for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { - *l |= r; - } - self - } -} - -impl core::ops::BitXor for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - type Output = Self; - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - fn bitxor(mut self, rhs: Self) -> Self::Output { - for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { - *l ^= r; - } - self - } -} - -impl core::ops::Not for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - type Output = Self; - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - fn not(mut self) -> Self::Output { - for x in self.0.as_mut() { - *x = !*x; - } - if N % 8 > 0 { - *self.0.as_mut().last_mut().unwrap() &= u8::MAX >> (8 - N % 8); - } - self - } -} diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs deleted file mode 100644 index 5ad2c1d1eaf6..000000000000 --- a/crates/core_simd/src/masks/full_masks.rs +++ /dev/null @@ -1,297 +0,0 @@ -//! Masks that take up full SIMD vector registers. - -use crate::simd::{LaneCount, MaskElement, Simd, SupportedLaneCount}; - -#[repr(transparent)] -pub(crate) struct Mask(Simd) -where - T: MaskElement, - LaneCount: SupportedLaneCount; - -impl Copy for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ -} - -impl Clone for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - #[inline] - fn clone(&self) -> Self { - *self - } -} - -impl PartialEq for Mask -where - T: MaskElement + PartialEq, - LaneCount: SupportedLaneCount, -{ - #[inline] - fn eq(&self, other: &Self) -> bool { - self.0.eq(&other.0) - } -} - -impl PartialOrd for Mask -where - T: MaskElement + PartialOrd, - LaneCount: SupportedLaneCount, -{ - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - self.0.partial_cmp(&other.0) - } -} - -impl Eq for Mask -where - T: MaskElement + Eq, - LaneCount: SupportedLaneCount, -{ -} - -impl Ord for Mask -where - T: MaskElement + Ord, - LaneCount: SupportedLaneCount, -{ - #[inline] - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.0.cmp(&other.0) - } -} - -// Used for bitmask bit order workaround -pub(crate) trait ReverseBits { - // Reverse the least significant `n` bits of `self`. - // (Remaining bits must be 0.) - fn reverse_bits(self, n: usize) -> Self; -} - -macro_rules! impl_reverse_bits { - { $($int:ty),* } => { - $( - impl ReverseBits for $int { - #[inline(always)] - fn reverse_bits(self, n: usize) -> Self { - let rev = <$int>::reverse_bits(self); - let bitsize = size_of::<$int>() * 8; - if n < bitsize { - // Shift things back to the right - rev >> (bitsize - n) - } else { - rev - } - } - } - )* - } -} - -impl_reverse_bits! { u8, u16, u32, u64 } - -impl Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] - pub(crate) const fn splat(value: bool) -> Self { - Self(Simd::splat(if value { T::TRUE } else { T::FALSE })) - } - - #[inline] - #[must_use = "method returns a new bool and does not mutate the original value"] - pub(crate) unsafe fn test_unchecked(&self, lane: usize) -> bool { - T::eq(self.0[lane], T::TRUE) - } - - #[inline] - pub(crate) unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { - self.0[lane] = if value { T::TRUE } else { T::FALSE } - } - - #[inline] - #[must_use = "method returns a new vector and does not mutate the original value"] - pub(crate) fn to_simd(self) -> Simd { - self.0 - } - - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) unsafe fn from_simd_unchecked(value: Simd) -> Self { - Self(value) - } - - #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) fn convert(self) -> Mask - where - U: MaskElement, - { - // Safety: masks are simply integer vectors of 0 and -1, and we can cast the element type. - unsafe { Mask(core::intrinsics::simd::simd_cast(self.0)) } - } - - #[inline] - unsafe fn to_bitmask_impl(self) -> U - where - LaneCount: SupportedLaneCount, - { - let resized = self.to_simd().resize::(T::FALSE); - - // Safety: `resized` is an integer vector with length M, which must match T - let bitmask: U = unsafe { core::intrinsics::simd::simd_bitmask(resized) }; - - // LLVM assumes bit order should match endianness - if cfg!(target_endian = "big") { - bitmask.reverse_bits(M) - } else { - bitmask - } - } - - #[inline] - unsafe fn from_bitmask_impl(bitmask: U) -> Self - where - LaneCount: SupportedLaneCount, - { - // LLVM assumes bit order should match endianness - let bitmask = if cfg!(target_endian = "big") { - bitmask.reverse_bits(M) - } else { - bitmask - }; - - // SAFETY: `mask` is the correct bitmask type for a u64 bitmask - let mask: Simd = unsafe { - core::intrinsics::simd::simd_select_bitmask( - bitmask, - Simd::::splat(T::TRUE), - Simd::::splat(T::FALSE), - ) - }; - - // SAFETY: `mask` only contains `T::TRUE` or `T::FALSE` - unsafe { Self::from_simd_unchecked(mask.resize::(T::FALSE)) } - } - - #[inline] - pub(crate) fn to_bitmask_integer(self) -> u64 { - // TODO modify simd_bitmask to zero-extend output, making this unnecessary - if N <= 8 { - // Safety: bitmask matches length - unsafe { self.to_bitmask_impl::() as u64 } - } else if N <= 16 { - // Safety: bitmask matches length - unsafe { self.to_bitmask_impl::() as u64 } - } else if N <= 32 { - // Safety: bitmask matches length - unsafe { self.to_bitmask_impl::() as u64 } - } else { - // Safety: bitmask matches length - unsafe { self.to_bitmask_impl::() } - } - } - - #[inline] - pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self { - // TODO modify simd_bitmask_select to truncate input, making this unnecessary - if N <= 8 { - // Safety: bitmask matches length - unsafe { Self::from_bitmask_impl::(bitmask as u8) } - } else if N <= 16 { - // Safety: bitmask matches length - unsafe { Self::from_bitmask_impl::(bitmask as u16) } - } else if N <= 32 { - // Safety: bitmask matches length - unsafe { Self::from_bitmask_impl::(bitmask as u32) } - } else { - // Safety: bitmask matches length - unsafe { Self::from_bitmask_impl::(bitmask) } - } - } - - #[inline] - #[must_use = "method returns a new bool and does not mutate the original value"] - pub(crate) fn any(self) -> bool { - // Safety: use `self` as an integer vector - unsafe { core::intrinsics::simd::simd_reduce_any(self.to_simd()) } - } - - #[inline] - #[must_use = "method returns a new bool and does not mutate the original value"] - pub(crate) fn all(self) -> bool { - // Safety: use `self` as an integer vector - unsafe { core::intrinsics::simd::simd_reduce_all(self.to_simd()) } - } -} - -impl From> for Simd -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - #[inline] - fn from(value: Mask) -> Self { - value.0 - } -} - -impl core::ops::BitAnd for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - type Output = Self; - #[inline] - fn bitand(self, rhs: Self) -> Self { - // Safety: `self` is an integer vector - unsafe { Self(core::intrinsics::simd::simd_and(self.0, rhs.0)) } - } -} - -impl core::ops::BitOr for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - type Output = Self; - #[inline] - fn bitor(self, rhs: Self) -> Self { - // Safety: `self` is an integer vector - unsafe { Self(core::intrinsics::simd::simd_or(self.0, rhs.0)) } - } -} - -impl core::ops::BitXor for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - type Output = Self; - #[inline] - fn bitxor(self, rhs: Self) -> Self { - // Safety: `self` is an integer vector - unsafe { Self(core::intrinsics::simd::simd_xor(self.0, rhs.0)) } - } -} - -impl core::ops::Not for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - type Output = Self; - #[inline] - fn not(self) -> Self::Output { - Self::splat(true) ^ self - } -} diff --git a/crates/core_simd/src/mod.rs b/crates/core_simd/src/mod.rs index 45b1a0f97514..14fe70df4ed1 100644 --- a/crates/core_simd/src/mod.rs +++ b/crates/core_simd/src/mod.rs @@ -29,6 +29,7 @@ pub mod simd { pub use crate::core_simd::cast::*; pub use crate::core_simd::lane_count::{LaneCount, SupportedLaneCount}; pub use crate::core_simd::masks::*; + pub use crate::core_simd::select::*; pub use crate::core_simd::swizzle::*; pub use crate::core_simd::to_bytes::ToBytes; pub use crate::core_simd::vector::*; diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index f36e8d01a73b..f36e360fadf9 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -1,4 +1,4 @@ -use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount, cmp::SimdPartialEq}; +use crate::simd::{LaneCount, Select, Simd, SimdElement, SupportedLaneCount, cmp::SimdPartialEq}; use core::ops::{Add, Mul}; use core::ops::{BitAnd, BitOr, BitXor}; use core::ops::{Div, Rem, Sub}; diff --git a/crates/core_simd/src/select.rs b/crates/core_simd/src/select.rs index a2db455a5268..5240b9b0c716 100644 --- a/crates/core_simd/src/select.rs +++ b/crates/core_simd/src/select.rs @@ -1,54 +1,163 @@ -use crate::simd::{LaneCount, Mask, MaskElement, Simd, SimdElement, SupportedLaneCount}; +use crate::simd::{ + FixEndianness, LaneCount, Mask, MaskElement, Simd, SimdElement, SupportedLaneCount, +}; -impl Mask +/// Choose elements from two vectors using a mask. +/// +/// For each element in the mask, choose the corresponding element from `true_values` if +/// that element mask is true, and `false_values` if that element mask is false. +/// +/// If the mask is `u64`, it's treated as a bitmask with the least significant bit +/// corresponding to the first element. +/// +/// # Examples +/// +/// ## Selecting values from `Simd` +/// ``` +/// # #![feature(portable_simd)] +/// # #[cfg(feature = "as_crate")] use core_simd::simd; +/// # #[cfg(not(feature = "as_crate"))] use core::simd; +/// # use simd::{Simd, Mask, Select}; +/// let a = Simd::from_array([0, 1, 2, 3]); +/// let b = Simd::from_array([4, 5, 6, 7]); +/// let mask = Mask::::from_array([true, false, false, true]); +/// let c = mask.select(a, b); +/// assert_eq!(c.to_array(), [0, 5, 6, 3]); +/// ``` +/// +/// ## Selecting values from `Mask` +/// ``` +/// # #![feature(portable_simd)] +/// # #[cfg(feature = "as_crate")] use core_simd::simd; +/// # #[cfg(not(feature = "as_crate"))] use core::simd; +/// # use simd::{Mask, Select}; +/// let a = Mask::::from_array([true, true, false, false]); +/// let b = Mask::::from_array([false, false, true, true]); +/// let mask = Mask::::from_array([true, false, false, true]); +/// let c = mask.select(a, b); +/// assert_eq!(c.to_array(), [true, false, true, false]); +/// ``` +/// +/// ## Selecting with a bitmask +/// ``` +/// # #![feature(portable_simd)] +/// # #[cfg(feature = "as_crate")] use core_simd::simd; +/// # #[cfg(not(feature = "as_crate"))] use core::simd; +/// # use simd::{Mask, Select}; +/// let a = Mask::::from_array([true, true, false, false]); +/// let b = Mask::::from_array([false, false, true, true]); +/// let mask = 0b1001; +/// let c = mask.select(a, b); +/// assert_eq!(c.to_array(), [true, false, true, false]); +/// ``` +pub trait Select { + /// Choose elements + fn select(self, true_values: T, false_values: T) -> T; +} + +impl Select> for Mask +where + T: SimdElement, + U: MaskElement, + LaneCount: SupportedLaneCount, +{ + #[inline] + fn select(self, true_values: Simd, false_values: Simd) -> Simd { + // Safety: + // simd_as between masks is always safe (they're vectors of ints). + // simd_select uses a mask that matches the width and number of elements + unsafe { + let mask: Simd = core::intrinsics::simd::simd_as(self.to_simd()); + core::intrinsics::simd::simd_select(mask, true_values, false_values) + } + } +} + +impl Select> for u64 +where + T: SimdElement, + LaneCount: SupportedLaneCount, +{ + #[inline] + fn select(self, true_values: Simd, false_values: Simd) -> Simd { + const { + assert!(N <= 64, "number of elements can't be greater than 64"); + } + + #[inline] + unsafe fn select_impl( + bitmask: U, + true_values: Simd, + false_values: Simd, + ) -> Simd + where + T: SimdElement, + LaneCount: SupportedLaneCount, + LaneCount: SupportedLaneCount, + { + let default = true_values[0]; + let true_values = true_values.resize::(default); + let false_values = false_values.resize::(default); + + // LLVM assumes bit order should match endianness + let bitmask = bitmask.fix_endianness(); + + // Safety: the caller guarantees that the size of U matches M + let selected = unsafe { + core::intrinsics::simd::simd_select_bitmask(bitmask, true_values, false_values) + }; + + selected.resize::(default) + } + + // TODO modify simd_bitmask_select to truncate input, making this unnecessary + if N <= 8 { + let bitmask = self as u8; + // Safety: bitmask matches length + unsafe { select_impl::(bitmask, true_values, false_values) } + } else if N <= 16 { + let bitmask = self as u16; + // Safety: bitmask matches length + unsafe { select_impl::(bitmask, true_values, false_values) } + } else if N <= 32 { + let bitmask = self as u32; + // Safety: bitmask matches length + unsafe { select_impl::(bitmask, true_values, false_values) } + } else { + let bitmask = self; + // Safety: bitmask matches length + unsafe { select_impl::(bitmask, true_values, false_values) } + } + } +} + +impl Select> for Mask +where + T: MaskElement, + U: MaskElement, + LaneCount: SupportedLaneCount, +{ + #[inline] + fn select(self, true_values: Mask, false_values: Mask) -> Mask { + let selected: Simd = + Select::select(self, true_values.to_simd(), false_values.to_simd()); + + // Safety: all values come from masks + unsafe { Mask::from_simd_unchecked(selected) } + } +} + +impl Select> for u64 where T: MaskElement, LaneCount: SupportedLaneCount, { - /// Choose elements from two vectors. - /// - /// For each element in the mask, choose the corresponding element from `true_values` if - /// that element mask is true, and `false_values` if that element mask is false. - /// - /// # Examples - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::{Simd, Mask}; - /// let a = Simd::from_array([0, 1, 2, 3]); - /// let b = Simd::from_array([4, 5, 6, 7]); - /// let mask = Mask::from_array([true, false, false, true]); - /// let c = mask.select(a, b); - /// assert_eq!(c.to_array(), [0, 5, 6, 3]); - /// ``` #[inline] - #[must_use = "method returns a new vector and does not mutate the original inputs"] - pub fn select(self, true_values: Simd, false_values: Simd) -> Simd - where - U: SimdElement, - { - // Safety: The mask has been cast to a vector of integers, - // and the operands to select between are vectors of the same type and length. - unsafe { core::intrinsics::simd::simd_select(self.to_simd(), true_values, false_values) } - } + fn select(self, true_values: Mask, false_values: Mask) -> Mask { + let selected: Simd = + Select::select(self, true_values.to_simd(), false_values.to_simd()); - /// Choose elements from two masks. - /// - /// For each element in the mask, choose the corresponding element from `true_values` if - /// that element mask is true, and `false_values` if that element mask is false. - /// - /// # Examples - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Mask; - /// let a = Mask::::from_array([true, true, false, false]); - /// let b = Mask::::from_array([false, false, true, true]); - /// let mask = Mask::::from_array([true, false, false, true]); - /// let c = mask.select_mask(a, b); - /// assert_eq!(c.to_array(), [true, false, true, false]); - /// ``` - #[inline] - #[must_use = "method returns a new mask and does not mutate the original inputs"] - pub fn select_mask(self, true_values: Self, false_values: Self) -> Self { - self & true_values | !self & false_values + // Safety: all values come from masks + unsafe { Mask::from_simd_unchecked(selected) } } } diff --git a/crates/core_simd/src/simd/cmp/ord.rs b/crates/core_simd/src/simd/cmp/ord.rs index 4b2d0b55feba..1b1c689ad458 100644 --- a/crates/core_simd/src/simd/cmp/ord.rs +++ b/crates/core_simd/src/simd/cmp/ord.rs @@ -1,5 +1,5 @@ use crate::simd::{ - LaneCount, Mask, Simd, SupportedLaneCount, + LaneCount, Mask, Select, Simd, SupportedLaneCount, cmp::SimdPartialEq, ptr::{SimdConstPtr, SimdMutPtr}, }; @@ -194,12 +194,12 @@ macro_rules! impl_mask { { #[inline] fn simd_max(self, other: Self) -> Self { - self.simd_gt(other).select_mask(other, self) + self.simd_gt(other).select(other, self) } #[inline] fn simd_min(self, other: Self) -> Self { - self.simd_lt(other).select_mask(other, self) + self.simd_lt(other).select(other, self) } #[inline] diff --git a/crates/core_simd/src/simd/num/float.rs b/crates/core_simd/src/simd/num/float.rs index b5972c47373b..76ab5748c638 100644 --- a/crates/core_simd/src/simd/num/float.rs +++ b/crates/core_simd/src/simd/num/float.rs @@ -1,6 +1,6 @@ use super::sealed::Sealed; use crate::simd::{ - LaneCount, Mask, Simd, SimdCast, SimdElement, SupportedLaneCount, + LaneCount, Mask, Select, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::{SimdPartialEq, SimdPartialOrd}, }; diff --git a/crates/core_simd/src/simd/num/int.rs b/crates/core_simd/src/simd/num/int.rs index d25050c3e4b4..5a292407d050 100644 --- a/crates/core_simd/src/simd/num/int.rs +++ b/crates/core_simd/src/simd/num/int.rs @@ -1,6 +1,6 @@ use super::sealed::Sealed; use crate::simd::{ - LaneCount, Mask, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd, + LaneCount, Mask, Select, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd, cmp::SimdPartialOrd, num::SimdUint, }; diff --git a/crates/core_simd/src/swizzle_dyn.rs b/crates/core_simd/src/swizzle_dyn.rs index 773bd028bae0..73b18595d0a1 100644 --- a/crates/core_simd/src/swizzle_dyn.rs +++ b/crates/core_simd/src/swizzle_dyn.rs @@ -139,7 +139,7 @@ unsafe fn armv7_neon_swizzle_u8x16(bytes: Simd, idxs: Simd) -> S #[inline] #[allow(clippy::let_and_return)] unsafe fn avx2_pshufb(bytes: Simd, idxs: Simd) -> Simd { - use crate::simd::cmp::SimdPartialOrd; + use crate::simd::{Select, cmp::SimdPartialOrd}; #[cfg(target_arch = "x86")] use core::arch::x86; #[cfg(target_arch = "x86_64")] @@ -200,7 +200,7 @@ fn zeroing_idxs(idxs: Simd) -> Simd where LaneCount: SupportedLaneCount, { - use crate::simd::cmp::SimdPartialOrd; + use crate::simd::{Select, cmp::SimdPartialOrd}; idxs.simd_lt(Simd::splat(N as u8)) .select(idxs, Simd::splat(u8::MAX)) } From 316a79f4320bbdfd7fd1eead13ea45f71bc66d5b Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Wed, 17 Sep 2025 10:54:02 +0000 Subject: [PATCH 0035/3801] Stabilize 29 RISC-V target features (`riscv_ratified_v2`) This commit stabilizes RISC-V target features with following constraints: * Describes a ratified extension. * Implemented on Rust 1.88.0 or before. Waiting for four+ version cycles seems sufficient. * Does not disrupt current rustc's target feature + ABI handling. It excludes "E" and all floating point-arithmetic extensions. "Zfinx" family does not involve floating point registers but not stabilizing for now to avoid possible confusion between the "F" extension family. * Not vector-related (floating point and integer). While integer vector subsets should not cause any ABI issues (as they don't use ABI-dependent floating point registers), we need to discuss before stabilizing them. * Supported by the lowest LLVM version supported by rustc (LLVM 20). List of target features to be stabilized: 1. "b" 2. "za64rs" (no-RT) 3. "za128rs" (no-RT) 4. "zaamo" 5. "zabha" 6. "zacas" 7. "zalrsc" 8. "zama16b" (no-RT) 9. "zawrs" 10. "zca" 11. "zcb" 12. "zcmop" 13. "zic64b" (no-RT) 14. "zicbom" 15. "zicbop" (no-RT) 16. "zicboz" 17. "ziccamoa" (no-RT) 18. "ziccif" (no-RT) 19. "zicclsm" (no-RT) 20. "ziccrse" (no-RT) 21. "zicntr" 22. "zicond" 23. "zicsr" 24. "zifencei" 25. "zihintntl" 26. "zihintpause" 27. "zihpm" 28. "zimop" 29. "ztso" Of which, 20 of them (29 minus 9 "no-RT" target features) support runtime detection through `std::arch::is_riscv_feature_detected!()`. --- .../rustc_codegen_ssa/src/back/metadata.rs | 6 +- compiler/rustc_target/src/target_features.rs | 58 +++++++++---------- library/std_detect/src/detect/arch/riscv.rs | 40 ++++++------- 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 10aaadd5688a..41b692c466c9 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -330,14 +330,12 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { let mut e_flags: u32 = 0x0; // Check if compression is enabled - // `unstable_target_features` is used here because "zca" is gated behind riscv_target_feature. - if sess.unstable_target_features.contains(&sym::zca) { + if sess.target_features.contains(&sym::zca) { e_flags |= elf::EF_RISCV_RVC; } // Check if RVTSO is enabled - // `unstable_target_features` is used here because "ztso" is gated behind riscv_target_feature. - if sess.unstable_target_features.contains(&sym::ztso) { + if sess.target_features.contains(&sym::ztso) { e_flags |= elf::EF_RISCV_TSO; } diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index dc70089c385f..f2f0802f12b2 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -589,7 +589,7 @@ const NVPTX_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start ("a", Stable, &["zaamo", "zalrsc"]), - ("b", Unstable(sym::riscv_target_feature), &["zba", "zbb", "zbs"]), + ("b", Stable, &["zba", "zbb", "zbs"]), ("c", Stable, &["zca"]), ("d", Unstable(sym::riscv_target_feature), &["f"]), ("e", Unstable(sym::riscv_target_feature), &[]), @@ -647,14 +647,14 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]), ("unaligned-vector-mem", Unstable(sym::riscv_target_feature), &[]), ("v", Unstable(sym::riscv_target_feature), &["zvl128b", "zve64d"]), - ("za64rs", Unstable(sym::riscv_target_feature), &["za128rs"]), // Za64rs ⊃ Za128rs - ("za128rs", Unstable(sym::riscv_target_feature), &[]), - ("zaamo", Unstable(sym::riscv_target_feature), &[]), - ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]), - ("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]), - ("zalrsc", Unstable(sym::riscv_target_feature), &[]), - ("zama16b", Unstable(sym::riscv_target_feature), &[]), - ("zawrs", Unstable(sym::riscv_target_feature), &[]), + ("za64rs", Stable, &["za128rs"]), // Za64rs ⊃ Za128rs + ("za128rs", Stable, &[]), + ("zaamo", Stable, &[]), + ("zabha", Stable, &["zaamo"]), + ("zacas", Stable, &["zaamo"]), + ("zalrsc", Stable, &[]), + ("zama16b", Stable, &[]), + ("zawrs", Stable, &[]), ("zba", Stable, &[]), ("zbb", Stable, &[]), ("zbc", Stable, &["zbkc"]), // Zbc ⊃ Zbkc @@ -662,9 +662,9 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zbkc", Stable, &[]), ("zbkx", Stable, &[]), ("zbs", Stable, &[]), - ("zca", Unstable(sym::riscv_target_feature), &[]), - ("zcb", Unstable(sym::riscv_target_feature), &["zca"]), - ("zcmop", Unstable(sym::riscv_target_feature), &["zca"]), + ("zca", Stable, &[]), + ("zcb", Stable, &["zca"]), + ("zcmop", Stable, &["zca"]), ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]), ("zfa", Unstable(sym::riscv_target_feature), &["f"]), ("zfbfmin", Unstable(sym::riscv_target_feature), &["f"]), // and a subset of Zfhmin @@ -673,22 +673,22 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]), ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]), ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]), - ("zic64b", Unstable(sym::riscv_target_feature), &[]), - ("zicbom", Unstable(sym::riscv_target_feature), &[]), - ("zicbop", Unstable(sym::riscv_target_feature), &[]), - ("zicboz", Unstable(sym::riscv_target_feature), &[]), - ("ziccamoa", Unstable(sym::riscv_target_feature), &[]), - ("ziccif", Unstable(sym::riscv_target_feature), &[]), - ("zicclsm", Unstable(sym::riscv_target_feature), &[]), - ("ziccrse", Unstable(sym::riscv_target_feature), &[]), - ("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]), - ("zicond", Unstable(sym::riscv_target_feature), &[]), - ("zicsr", Unstable(sym::riscv_target_feature), &[]), - ("zifencei", Unstable(sym::riscv_target_feature), &[]), - ("zihintntl", Unstable(sym::riscv_target_feature), &[]), - ("zihintpause", Unstable(sym::riscv_target_feature), &[]), - ("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]), - ("zimop", Unstable(sym::riscv_target_feature), &[]), + ("zic64b", Stable, &[]), + ("zicbom", Stable, &[]), + ("zicbop", Stable, &[]), + ("zicboz", Stable, &[]), + ("ziccamoa", Stable, &[]), + ("ziccif", Stable, &[]), + ("zicclsm", Stable, &[]), + ("ziccrse", Stable, &[]), + ("zicntr", Stable, &["zicsr"]), + ("zicond", Stable, &[]), + ("zicsr", Stable, &[]), + ("zifencei", Stable, &[]), + ("zihintntl", Stable, &[]), + ("zihintpause", Stable, &[]), + ("zihpm", Stable, &["zicsr"]), + ("zimop", Stable, &[]), ("zk", Stable, &["zkn", "zkr", "zkt"]), ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]), ("zknd", Stable, &[]), @@ -699,7 +699,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zksed", Stable, &[]), ("zksh", Stable, &[]), ("zkt", Stable, &[]), - ("ztso", Unstable(sym::riscv_target_feature), &[]), + ("ztso", Stable, &[]), ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]), // Zvbb ⊃ Zvkb ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]), ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]), diff --git a/library/std_detect/src/detect/arch/riscv.rs b/library/std_detect/src/detect/arch/riscv.rs index 1e57d09edb14..f6d708dd2ee0 100644 --- a/library/std_detect/src/detect/arch/riscv.rs +++ b/library/std_detect/src/detect/arch/riscv.rs @@ -194,26 +194,26 @@ features! { @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] unaligned_vector_mem: "unaligned-vector-mem"; /// Has reasonably performant unaligned vector - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicsr: "zicsr"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zicsr: "zicsr"; /// "Zicsr" Extension for Control and Status Register (CSR) Instructions - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicntr: "zicntr"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zicntr: "zicntr"; /// "Zicntr" Extension for Base Counters and Timers - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zihpm: "zihpm"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zihpm: "zihpm"; /// "Zihpm" Extension for Hardware Performance Counters - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zifencei: "zifencei"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zifencei: "zifencei"; /// "Zifencei" Extension for Instruction-Fetch Fence - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zihintntl: "zihintntl"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zihintntl: "zihintntl"; /// "Zihintntl" Extension for Non-Temporal Locality Hints - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zihintpause: "zihintpause"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zihintpause: "zihintpause"; /// "Zihintpause" Extension for Pause Hint - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zimop: "zimop"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zimop: "zimop"; /// "Zimop" Extension for May-Be-Operations - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicbom: "zicbom"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zicbom: "zicbom"; /// "Zicbom" Extension for Cache-Block Management Instructions - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicboz: "zicboz"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zicboz: "zicboz"; /// "Zicboz" Extension for Cache-Block Zero Instruction - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicond: "zicond"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zicond: "zicond"; /// "Zicond" Extension for Integer Conditional Operations @FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] m: "m"; @@ -221,20 +221,20 @@ features! { @FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] a: "a"; /// "A" Extension for Atomic Instructions - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zalrsc: "zalrsc"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zalrsc: "zalrsc"; /// "Zalrsc" Extension for Load-Reserved/Store-Conditional Instructions - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zaamo: "zaamo"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zaamo: "zaamo"; /// "Zaamo" Extension for Atomic Memory Operations - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zawrs: "zawrs"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zawrs: "zawrs"; /// "Zawrs" Extension for Wait-on-Reservation-Set Instructions - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zabha: "zabha"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zabha: "zabha"; /// "Zabha" Extension for Byte and Halfword Atomic Memory Operations - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zacas: "zacas"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zacas: "zacas"; /// "Zacas" Extension for Atomic Compare-and-Swap (CAS) Instructions @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zam: "zam"; without cfg check: true; /// "Zam" Extension for Misaligned Atomics - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] ztso: "ztso"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] ztso: "ztso"; /// "Ztso" Extension for Total Store Ordering @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] f: "f"; @@ -264,7 +264,7 @@ features! { @FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] c: "c"; /// "C" Extension for Compressed Instructions - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zca: "zca"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zca: "zca"; /// "Zca" Compressed Instructions excluding Floating-Point Loads/Stores @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcf: "zcf"; without cfg check: true; @@ -272,12 +272,12 @@ features! { @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcd: "zcd"; without cfg check: true; /// "Zcd" Compressed Instructions for Double-Precision Floating-Point Loads/Stores - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcb: "zcb"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zcb: "zcb"; /// "Zcb" Simple Code-size Saving Compressed Instructions - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcmop: "zcmop"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] zcmop: "zcmop"; /// "Zcmop" Extension for Compressed May-Be-Operations - @FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] b: "b"; + @FEATURE: #[stable(feature = "riscv_ratified_v2", since = "CURRENT_RUSTC_VERSION")] b: "b"; /// "B" Extension for Bit Manipulation @FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zba: "zba"; /// "Zba" Extension for Address Generation From 2b228ce31075811028c9447d2387ca037e4ac9ee Mon Sep 17 00:00:00 2001 From: bluurryy <164359728+bluurryy@users.noreply.github.com> Date: Sun, 21 Sep 2025 01:42:06 +0200 Subject: [PATCH 0036/3801] Implement `Allocator` for `&mut A` where `A: Allocator + ?Sized` --- library/core/src/alloc/mod.rs | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 9d608d5e83c4..680b1ec105a2 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -421,3 +421,58 @@ where unsafe { (**self).shrink(ptr, old_layout, new_layout) } } } + +#[unstable(feature = "allocator_api", issue = "32838")] +unsafe impl Allocator for &mut A +where + A: Allocator + ?Sized, +{ + #[inline] + fn allocate(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate(layout) + } + + #[inline] + fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { + (**self).allocate_zeroed(layout) + } + + #[inline] + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).deallocate(ptr, layout) } + } + + #[inline] + unsafe fn grow( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn grow_zeroed( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).grow_zeroed(ptr, old_layout, new_layout) } + } + + #[inline] + unsafe fn shrink( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: the safety contract must be upheld by the caller + unsafe { (**self).shrink(ptr, old_layout, new_layout) } + } +} From 1974d1176b06f999fd706b0ffce14c1af8262b39 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 27 Sep 2025 11:40:02 +0800 Subject: [PATCH 0037/3801] Fix loses label for convert_for_to_while_let Fixes: - loses label for `convert_while_to_loop` and `convert_for_to_while_let` - loses attributes for `convert_while_to_loop` and `convert_for_to_while_let` - bad indent for `convert_while_to_loop` Examples --- ```rust fn main() { #[allow(unused)] #[deny(unsafe_code)] 'a: while$0 let Some(x) = cond { foo(); break 'a; } } ``` **Before this PR**: ```rust fn main() { loop { if let Some(x) = cond { foo(); break 'a; } else { break; } } } ``` **After this PR**: ```rust fn main() { #[allow(unused)] #[deny(unsafe_code)] 'a: loop { if let Some(x) = cond { foo(); break 'a; } else { break; } } } ``` --- ```rust fn main() { let mut x = vec![1, 2, 3]; #[allow(unused)] #[deny(unsafe_code)] 'a: for $0v in x { v *= 2; break 'a; }; } ``` **Before this PR**: ```rust fn main() { let mut x = vec![1, 2, 3]; let mut tmp = x.into_iter(); while let Some(v) = tmp.next() { v *= 2; break 'a; }; } ``` **After this PR**: ```rust fn main() { let mut x = vec![1, 2, 3]; let mut tmp = x.into_iter(); #[allow(unused)] #[deny(unsafe_code)] 'a: while let Some(v) = tmp.next() { v *= 2; break 'a; }; } ``` --- .../src/handlers/convert_for_to_while_let.rs | 69 +++++- .../src/handlers/convert_while_to_loop.rs | 224 ++++++++++++++++-- .../crates/ide-assists/src/utils.rs | 24 +- .../crates/syntax/src/ast/make.rs | 2 +- 4 files changed, 292 insertions(+), 27 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs index 2d6a59a7c365..b281d5a02e53 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs @@ -1,11 +1,8 @@ -use hir::{ - Name, - sym::{self}, -}; +use hir::{Name, sym}; use ide_db::{famous_defs::FamousDefs, syntax_helpers::suggest_name}; use syntax::{ AstNode, - ast::{self, HasLoopBody, edit::IndentLevel, make, syntax_factory::SyntaxFactory}, + ast::{self, HasAttrs, HasLoopBody, edit::IndentLevel, make, syntax_factory::SyntaxFactory}, syntax_editor::Position, }; @@ -82,6 +79,18 @@ pub(crate) fn convert_for_loop_to_while_let( Some(iterable), ); let indent = IndentLevel::from_node(for_loop.syntax()); + + if let Some(label) = for_loop.label() { + let label = label.syntax().clone_for_update(); + editor.insert(Position::before(for_loop.syntax()), make.whitespace(" ")); + editor.insert(Position::before(for_loop.syntax()), label); + } + crate::utils::insert_attributes( + for_loop.syntax(), + &mut editor, + for_loop.attrs().map(|it| it.clone_for_update()), + ); + editor.insert( Position::before(for_loop.syntax()), make::tokens::whitespace(format!("\n{indent}").as_str()), @@ -186,6 +195,56 @@ fn main() { ) } + #[test] + fn each_to_for_with_label() { + check_assist( + convert_for_loop_to_while_let, + r" +fn main() { + let mut x = vec![1, 2, 3]; + 'a: for $0v in x { + v *= 2; + break 'a; + }; +}", + r" +fn main() { + let mut x = vec![1, 2, 3]; + let mut tmp = x.into_iter(); + 'a: while let Some(v) = tmp.next() { + v *= 2; + break 'a; + }; +}", + ) + } + + #[test] + fn each_to_for_with_attributes() { + check_assist( + convert_for_loop_to_while_let, + r" +fn main() { + let mut x = vec![1, 2, 3]; + #[allow(unused)] + #[deny(unsafe_code)] + for $0v in x { + v *= 2; + }; +}", + r" +fn main() { + let mut x = vec![1, 2, 3]; + let mut tmp = x.into_iter(); + #[allow(unused)] + #[deny(unsafe_code)] + while let Some(v) = tmp.next() { + v *= 2; + }; +}", + ) + } + #[test] fn each_to_for_for_in_range() { check_assist( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs index dbe3ee0ed603..9fd8b4b3159e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs @@ -1,6 +1,5 @@ use std::iter; -use either::Either; use ide_db::syntax_helpers::node_ext::is_pattern_cond; use syntax::{ AstNode, T, @@ -9,6 +8,7 @@ use syntax::{ edit::{AstNodeEdit, IndentLevel}, make, }, + syntax_editor::{Element, Position}, }; use crate::{ @@ -44,43 +44,53 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) let while_expr = while_kw.parent().and_then(ast::WhileExpr::cast)?; let while_body = while_expr.loop_body()?; let while_cond = while_expr.condition()?; + let l_curly = while_body.stmt_list()?.l_curly_token()?; let target = while_expr.syntax().text_range(); acc.add( AssistId::refactor_rewrite("convert_while_to_loop"), "Convert while to loop", target, - |edit| { + |builder| { + let mut edit = builder.make_editor(while_expr.syntax()); let while_indent_level = IndentLevel::from_node(while_expr.syntax()); let break_block = make::block_expr( iter::once(make::expr_stmt(make::expr_break(None, None)).into()), None, ) - .indent(while_indent_level); - let block_expr = if is_pattern_cond(while_cond.clone()) { - let if_expr = make::expr_if(while_cond, while_body, Some(break_block.into())); + .indent(IndentLevel(1)); + + edit.replace_all( + while_kw.syntax_element()..=while_cond.syntax().syntax_element(), + vec![make::token(T![loop]).syntax_element()], + ); + + if is_pattern_cond(while_cond.clone()) { + let then_branch = while_body.reset_indent().indent(IndentLevel(1)); + let if_expr = make::expr_if(while_cond, then_branch, Some(break_block.into())); let stmts = iter::once(make::expr_stmt(if_expr.into()).into()); - make::block_expr(stmts, None) + let block_expr = make::block_expr(stmts, None); + edit.replace(while_body.syntax(), block_expr.indent(while_indent_level).syntax()); } else { let if_cond = invert_boolean_expression_legacy(while_cond); - let if_expr = make::expr_if(if_cond, break_block, None).syntax().clone().into(); - let elements = while_body.stmt_list().map_or_else( - || Either::Left(iter::empty()), - |stmts| { - Either::Right(stmts.syntax().children_with_tokens().filter(|node_or_tok| { - // Filter out the trailing expr - !node_or_tok - .as_node() - .is_some_and(|node| ast::Expr::can_cast(node.kind())) - })) - }, + let if_expr = make::expr_if(if_cond, break_block, None).indent(while_indent_level); + if !while_body.syntax().text().contains_char('\n') { + edit.insert( + Position::after(&l_curly), + make::tokens::whitespace(&format!("\n{while_indent_level}")), + ); + } + edit.insert_all( + Position::after(&l_curly), + vec![ + make::tokens::whitespace(&format!("\n{}", while_indent_level + 1)).into(), + if_expr.syntax().syntax_element(), + ], ); - make::hacky_block_expr(iter::once(if_expr).chain(elements), while_body.tail_expr()) }; - let replacement = make::expr_loop(block_expr.indent(while_indent_level)); - edit.replace(target, replacement.syntax().text()) + builder.add_file_edits(ctx.vfs_file_id(), edit); }, ) } @@ -115,6 +125,110 @@ fn main() { ); } + #[test] + fn convert_with_label() { + check_assist( + convert_while_to_loop, + r#" +fn main() { + 'x: while$0 cond { + foo(); + break 'x + } +} +"#, + r#" +fn main() { + 'x: loop { + if !cond { + break; + } + foo(); + break 'x + } +} +"#, + ); + + check_assist( + convert_while_to_loop, + r#" +fn main() { + 'x: while$0 let Some(x) = cond { + foo(); + break 'x + } +} +"#, + r#" +fn main() { + 'x: loop { + if let Some(x) = cond { + foo(); + break 'x + } else { + break; + } + } +} +"#, + ); + } + + #[test] + fn convert_with_attributes() { + check_assist( + convert_while_to_loop, + r#" +fn main() { + #[allow(unused)] + while$0 cond { + foo(); + break 'x + } +} +"#, + r#" +fn main() { + #[allow(unused)] + loop { + if !cond { + break; + } + foo(); + break 'x + } +} +"#, + ); + + check_assist( + convert_while_to_loop, + r#" +fn main() { + #[allow(unused)] + #[deny(unsafe_code)] + while$0 let Some(x) = cond { + foo(); + } +} +"#, + r#" +fn main() { + #[allow(unused)] + #[deny(unsafe_code)] + loop { + if let Some(x) = cond { + foo(); + } else { + break; + } + } +} +"#, + ); + } + #[test] fn convert_busy_wait() { check_assist( @@ -185,6 +299,76 @@ fn main() { ); } + #[test] + fn indentation() { + check_assist( + convert_while_to_loop, + r#" +fn main() { + { + { + while$0 cond { + foo( + "xxx", + ); + } + } + } +} +"#, + r#" +fn main() { + { + { + loop { + if !cond { + break; + } + foo( + "xxx", + ); + } + } + } +} +"#, + ); + + check_assist( + convert_while_to_loop, + r#" +fn main() { + { + { + while$0 let Some(_) = foo() { + bar( + "xxx", + ); + } + } + } +} +"#, + r#" +fn main() { + { + { + loop { + if let Some(_) = foo() { + bar( + "xxx", + ); + } else { + break; + } + } + } + } +} +"#, + ); + } + #[test] fn ignore_cursor_in_body() { check_assist_not_applicable( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 20e0302b57d7..7bca451c5e31 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -27,7 +27,7 @@ use syntax::{ make, syntax_factory::SyntaxFactory, }, - syntax_editor::{Removable, SyntaxEditor}, + syntax_editor::{Element, Removable, SyntaxEditor}, }; use crate::{ @@ -385,6 +385,28 @@ fn invert_special_case_legacy(expr: &ast::Expr) -> Option { } } +pub(crate) fn insert_attributes( + before: impl Element, + edit: &mut SyntaxEditor, + attrs: impl IntoIterator, +) { + let mut attrs = attrs.into_iter().peekable(); + if attrs.peek().is_none() { + return; + } + let elem = before.syntax_element(); + let indent = IndentLevel::from_element(&elem); + let whitespace = format!("\n{indent}"); + edit.insert_all( + syntax::syntax_editor::Position::before(elem), + attrs + .flat_map(|attr| { + [attr.syntax().clone().into(), make::tokens::whitespace(&whitespace).into()] + }) + .collect(), + ); +} + pub(crate) fn next_prev() -> impl Iterator { [Direction::Next, Direction::Prev].into_iter() } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index 051c5835571b..dba39204e32e 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -1355,7 +1355,7 @@ pub mod tokens { pub(super) static SOURCE_FILE: LazyLock> = LazyLock::new(|| { SourceFile::parse( - "use crate::foo; const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, async { let _ @ [] })\n;\n\nunsafe impl A for B where: {}", + "use crate::foo; const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, async { let _ @ [] }, while loop {} {})\n;\n\nunsafe impl A for B where: {}", Edition::CURRENT, ) }); From 321cd2aa25318eb2f565b06d26ced5111e1fd15f Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 22 Sep 2025 22:55:22 +0200 Subject: [PATCH 0038/3801] remove duplicated columns from `rustc_error_code::error_codes!` --- .../src/error_codes/E0773.md | 2 +- compiler/rustc_error_codes/src/lib.rs | 1040 ++++++++--------- compiler/rustc_errors/src/codes.rs | 8 +- compiler/rustc_errors/src/lib.rs | 1 + src/tools/tidy/src/error_codes.rs | 46 +- 5 files changed, 535 insertions(+), 562 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0773.md b/compiler/rustc_error_codes/src/error_codes/E0773.md index 5ebb43c6683e..91cf005d5471 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0773.md +++ b/compiler/rustc_error_codes/src/error_codes/E0773.md @@ -1,4 +1,4 @@ -#### this error code is no longer emitted by the compiler. +#### Note: this error code is no longer emitted by the compiler. This was triggered when multiple macro definitions used the same `#[rustc_builtin_macro(..)]`. This is no longer an error. diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 0aff1c06e0a8..a7bcab444788 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -21,533 +21,531 @@ // Also, the contents of this macro is checked by tidy (in `check_error_codes_docs`). If you change // the macro syntax you will need to change tidy as well. // -// Both columns are necessary because it's not possible in Rust to create a new identifier such as -// `E0123` from an integer literal such as `0123`, unfortunately. -// -// Do *not* remove entries from this list. Instead, just add a note th the corresponding markdown +// Do *not* remove entries from this list. Instead, just add a note to the corresponding markdown // file saying that this error is not emitted by the compiler any more (see E0001.md for an // example), and remove all code examples that do not build any more. #[macro_export] +#[rustfmt::skip] macro_rules! error_codes { ($macro:path) => ( $macro!( -E0001: 0001, -E0002: 0002, -E0004: 0004, -E0005: 0005, -E0007: 0007, -E0009: 0009, -E0010: 0010, -E0013: 0013, -E0014: 0014, -E0015: 0015, -E0023: 0023, -E0025: 0025, -E0026: 0026, -E0027: 0027, -E0029: 0029, -E0030: 0030, -E0033: 0033, -E0034: 0034, -E0038: 0038, -E0040: 0040, -E0044: 0044, -E0045: 0045, -E0046: 0046, -E0049: 0049, -E0050: 0050, -E0053: 0053, -E0054: 0054, -E0055: 0055, -E0057: 0057, -E0059: 0059, -E0060: 0060, -E0061: 0061, -E0062: 0062, -E0063: 0063, -E0067: 0067, -E0069: 0069, -E0070: 0070, -E0071: 0071, -E0072: 0072, -E0073: 0073, -E0074: 0074, -E0075: 0075, -E0076: 0076, -E0077: 0077, -E0080: 0080, -E0081: 0081, -E0084: 0084, -E0087: 0087, -E0088: 0088, -E0089: 0089, -E0090: 0090, -E0091: 0091, -E0092: 0092, -E0093: 0093, -E0094: 0094, -E0106: 0106, -E0107: 0107, -E0109: 0109, -E0110: 0110, -E0116: 0116, -E0117: 0117, -E0118: 0118, -E0119: 0119, -E0120: 0120, -E0121: 0121, -E0124: 0124, -E0128: 0128, -E0130: 0130, -E0131: 0131, -E0132: 0132, -E0133: 0133, -E0136: 0136, -E0137: 0137, -E0138: 0138, -E0139: 0139, -E0152: 0152, -E0154: 0154, -E0158: 0158, -E0161: 0161, -E0162: 0162, -E0164: 0164, -E0165: 0165, -E0170: 0170, -E0178: 0178, -E0183: 0183, -E0184: 0184, -E0185: 0185, -E0186: 0186, -E0191: 0191, -E0192: 0192, -E0193: 0193, -E0195: 0195, -E0197: 0197, -E0198: 0198, -E0199: 0199, -E0200: 0200, -E0201: 0201, -E0203: 0203, -E0204: 0204, -E0205: 0205, -E0206: 0206, -E0207: 0207, -E0208: 0208, -E0210: 0210, -E0211: 0211, -E0212: 0212, -E0214: 0214, -E0220: 0220, -E0221: 0221, -E0222: 0222, -E0223: 0223, -E0224: 0224, -E0225: 0225, -E0226: 0226, -E0227: 0227, -E0228: 0228, -E0229: 0229, -E0230: 0230, -E0231: 0231, -E0232: 0232, -E0243: 0243, -E0244: 0244, -E0251: 0251, -E0252: 0252, -E0253: 0253, -E0254: 0254, -E0255: 0255, -E0256: 0256, -E0259: 0259, -E0260: 0260, -E0261: 0261, -E0262: 0262, -E0263: 0263, -E0264: 0264, -E0267: 0267, -E0268: 0268, -E0271: 0271, -E0275: 0275, -E0276: 0276, -E0277: 0277, -E0281: 0281, -E0282: 0282, -E0283: 0283, -E0284: 0284, -E0297: 0297, -E0301: 0301, -E0302: 0302, -E0303: 0303, -E0307: 0307, -E0308: 0308, -E0309: 0309, -E0310: 0310, -E0311: 0311, -E0312: 0312, -E0316: 0316, -E0317: 0317, -E0320: 0320, -E0321: 0321, -E0322: 0322, -E0323: 0323, -E0324: 0324, -E0325: 0325, -E0326: 0326, -E0328: 0328, -E0329: 0329, -E0364: 0364, -E0365: 0365, -E0366: 0366, -E0367: 0367, -E0368: 0368, -E0369: 0369, -E0370: 0370, -E0371: 0371, -E0373: 0373, -E0374: 0374, -E0375: 0375, -E0376: 0376, -E0377: 0377, -E0378: 0378, -E0379: 0379, -E0380: 0380, -E0381: 0381, -E0382: 0382, -E0383: 0383, -E0384: 0384, -E0386: 0386, -E0387: 0387, -E0388: 0388, -E0389: 0389, -E0390: 0390, -E0391: 0391, -E0392: 0392, -E0393: 0393, -E0398: 0398, -E0399: 0399, -E0401: 0401, -E0403: 0403, -E0404: 0404, -E0405: 0405, -E0407: 0407, -E0408: 0408, -E0409: 0409, -E0411: 0411, -E0412: 0412, -E0415: 0415, -E0416: 0416, -E0422: 0422, -E0423: 0423, -E0424: 0424, -E0425: 0425, -E0426: 0426, -E0428: 0428, -E0429: 0429, -E0430: 0430, -E0431: 0431, -E0432: 0432, -E0433: 0433, -E0434: 0434, -E0435: 0435, -E0436: 0436, -E0437: 0437, -E0438: 0438, -E0439: 0439, -E0445: 0445, -E0446: 0446, -E0447: 0447, -E0448: 0448, -E0449: 0449, -E0451: 0451, -E0452: 0452, -E0453: 0453, -E0454: 0454, -E0455: 0455, -E0457: 0457, -E0458: 0458, -E0459: 0459, -E0460: 0460, -E0461: 0461, -E0462: 0462, -E0463: 0463, -E0464: 0464, -E0466: 0466, -E0468: 0468, -E0469: 0469, -E0472: 0472, -E0476: 0476, -E0477: 0477, -E0478: 0478, -E0482: 0482, -E0491: 0491, -E0492: 0492, -E0493: 0493, -E0495: 0495, -E0496: 0496, -E0497: 0497, -E0498: 0498, -E0499: 0499, -E0500: 0500, -E0501: 0501, -E0502: 0502, -E0503: 0503, -E0504: 0504, -E0505: 0505, -E0506: 0506, -E0507: 0507, -E0508: 0508, -E0509: 0509, -E0510: 0510, -E0511: 0511, -E0512: 0512, -E0514: 0514, -E0515: 0515, -E0516: 0516, -E0517: 0517, -E0518: 0518, -E0519: 0519, -E0520: 0520, -E0521: 0521, -E0522: 0522, -E0523: 0523, -E0524: 0524, -E0525: 0525, -E0527: 0527, -E0528: 0528, -E0529: 0529, -E0530: 0530, -E0531: 0531, -E0532: 0532, -E0533: 0533, -E0534: 0534, -E0535: 0535, -E0536: 0536, -E0537: 0537, -E0538: 0538, -E0539: 0539, -E0541: 0541, -E0542: 0542, -E0543: 0543, -E0544: 0544, -E0545: 0545, -E0546: 0546, -E0547: 0547, -E0549: 0549, -E0550: 0550, -E0551: 0551, -E0552: 0552, -E0554: 0554, -E0556: 0556, -E0557: 0557, -E0559: 0559, -E0560: 0560, -E0561: 0561, -E0562: 0562, -E0565: 0565, -E0566: 0566, -E0567: 0567, -E0568: 0568, -E0569: 0569, -E0570: 0570, -E0571: 0571, -E0572: 0572, -E0573: 0573, -E0574: 0574, -E0575: 0575, -E0576: 0576, -E0577: 0577, -E0578: 0578, -E0579: 0579, -E0580: 0580, -E0581: 0581, -E0582: 0582, -E0583: 0583, -E0584: 0584, -E0585: 0585, -E0586: 0586, -E0587: 0587, -E0588: 0588, -E0589: 0589, -E0590: 0590, -E0591: 0591, -E0592: 0592, -E0593: 0593, -E0594: 0594, -E0595: 0595, -E0596: 0596, -E0597: 0597, -E0599: 0599, -E0600: 0600, -E0601: 0601, -E0602: 0602, -E0603: 0603, -E0604: 0604, -E0605: 0605, -E0606: 0606, -E0607: 0607, -E0608: 0608, -E0609: 0609, -E0610: 0610, -E0614: 0614, -E0615: 0615, -E0616: 0616, -E0617: 0617, -E0618: 0618, -E0619: 0619, -E0620: 0620, -E0621: 0621, -E0622: 0622, // REMOVED: rustc-intrinsic ABI was removed -E0623: 0623, -E0624: 0624, -E0625: 0625, -E0626: 0626, -E0627: 0627, -E0628: 0628, -E0631: 0631, -E0632: 0632, -E0633: 0633, -E0634: 0634, -E0635: 0635, -E0636: 0636, -E0637: 0637, -E0638: 0638, -E0639: 0639, -E0640: 0640, -E0641: 0641, -E0642: 0642, -E0643: 0643, -E0644: 0644, -E0646: 0646, -E0647: 0647, -E0648: 0648, -E0657: 0657, -E0658: 0658, -E0659: 0659, -E0660: 0660, -E0661: 0661, -E0662: 0662, -E0663: 0663, -E0664: 0664, -E0665: 0665, -E0666: 0666, -E0667: 0667, -E0668: 0668, -E0669: 0669, -E0670: 0670, -E0671: 0671, -E0687: 0687, -E0688: 0688, -E0689: 0689, -E0690: 0690, -E0691: 0691, -E0692: 0692, -E0693: 0693, -E0695: 0695, -E0696: 0696, -E0697: 0697, -E0698: 0698, -E0699: 0699, // REMOVED: merged into generic inference var error -E0700: 0700, -E0701: 0701, -E0703: 0703, -E0704: 0704, -E0705: 0705, -E0706: 0706, -E0708: 0708, -E0710: 0710, -E0712: 0712, -E0713: 0713, -E0714: 0714, -E0715: 0715, -E0716: 0716, -E0711: 0711, -E0717: 0717, -E0718: 0718, -E0719: 0719, -E0720: 0720, -E0722: 0722, -E0724: 0724, -E0725: 0725, -E0726: 0726, -E0727: 0727, -E0728: 0728, -E0729: 0729, -E0730: 0730, -E0731: 0731, -E0732: 0732, -E0733: 0733, -E0734: 0734, -E0735: 0735, -E0736: 0736, -E0737: 0737, -E0739: 0739, -E0740: 0740, -E0741: 0741, -E0742: 0742, -E0743: 0743, -E0744: 0744, -E0745: 0745, -E0746: 0746, -E0747: 0747, -E0748: 0748, -E0749: 0749, -E0750: 0750, -E0751: 0751, -E0752: 0752, -E0753: 0753, -E0754: 0754, -E0755: 0755, -E0756: 0756, -E0757: 0757, -E0758: 0758, -E0759: 0759, -E0760: 0760, -E0761: 0761, -E0762: 0762, -E0763: 0763, -E0764: 0764, -E0765: 0765, -E0766: 0766, -E0767: 0767, -E0768: 0768, -E0769: 0769, -E0770: 0770, -E0771: 0771, -E0772: 0772, -E0773: 0773, -E0774: 0774, -E0775: 0775, -E0776: 0776, -E0777: 0777, -E0778: 0778, -E0779: 0779, -E0780: 0780, -E0781: 0781, -E0782: 0782, -E0783: 0783, -E0784: 0784, -E0785: 0785, -E0786: 0786, -E0787: 0787, -E0788: 0788, -E0789: 0789, -E0790: 0790, -E0791: 0791, -E0792: 0792, -E0793: 0793, -E0794: 0794, -E0795: 0795, -E0796: 0796, -E0797: 0797, -E0798: 0798, -E0799: 0799, -E0800: 0800, -E0801: 0801, -E0802: 0802, -E0803: 0803, -E0804: 0804, -E0805: 0805, +0001, +0002, +0004, +0005, +0007, +0009, +0010, +0013, +0014, +0015, +0023, +0025, +0026, +0027, +0029, +0030, +0033, +0034, +0038, +0040, +0044, +0045, +0046, +0049, +0050, +0053, +0054, +0055, +0057, +0059, +0060, +0061, +0062, +0063, +0067, +0069, +0070, +0071, +0072, +0073, +0074, +0075, +0076, +0077, +0080, +0081, +0084, +0087, +0088, +0089, +0090, +0091, +0092, +0093, +0094, +0106, +0107, +0109, +0110, +0116, +0117, +0118, +0119, +0120, +0121, +0124, +0128, +0130, +0131, +0132, +0133, +0136, +0137, +0138, +0139, +0152, +0154, +0158, +0161, +0162, +0164, +0165, +0170, +0178, +0183, +0184, +0185, +0186, +0191, +0192, +0193, +0195, +0197, +0198, +0199, +0200, +0201, +0203, +0204, +0205, +0206, +0207, +0208, +0210, +0211, +0212, +0214, +0220, +0221, +0222, +0223, +0224, +0225, +0226, +0227, +0228, +0229, +0230, +0231, +0232, +0243, +0244, +0251, +0252, +0253, +0254, +0255, +0256, +0259, +0260, +0261, +0262, +0263, +0264, +0267, +0268, +0271, +0275, +0276, +0277, +0281, +0282, +0283, +0284, +0297, +0301, +0302, +0303, +0307, +0308, +0309, +0310, +0311, +0312, +0316, +0317, +0320, +0321, +0322, +0323, +0324, +0325, +0326, +0328, +0329, +0364, +0365, +0366, +0367, +0368, +0369, +0370, +0371, +0373, +0374, +0375, +0376, +0377, +0378, +0379, +0380, +0381, +0382, +0383, +0384, +0386, +0387, +0388, +0389, +0390, +0391, +0392, +0393, +0398, +0399, +0401, +0403, +0404, +0405, +0407, +0408, +0409, +0411, +0412, +0415, +0416, +0422, +0423, +0424, +0425, +0426, +0428, +0429, +0430, +0431, +0432, +0433, +0434, +0435, +0436, +0437, +0438, +0439, +0445, +0446, +0447, +0448, +0449, +0451, +0452, +0453, +0454, +0455, +0457, +0458, +0459, +0460, +0461, +0462, +0463, +0464, +0466, +0468, +0469, +0472, +0476, +0477, +0478, +0482, +0491, +0492, +0493, +0495, +0496, +0497, +0498, +0499, +0500, +0501, +0502, +0503, +0504, +0505, +0506, +0507, +0508, +0509, +0510, +0511, +0512, +0514, +0515, +0516, +0517, +0518, +0519, +0520, +0521, +0522, +0523, +0524, +0525, +0527, +0528, +0529, +0530, +0531, +0532, +0533, +0534, +0535, +0536, +0537, +0538, +0539, +0541, +0542, +0543, +0544, +0545, +0546, +0547, +0549, +0550, +0551, +0552, +0554, +0556, +0557, +0559, +0560, +0561, +0562, +0565, +0566, +0567, +0568, +0569, +0570, +0571, +0572, +0573, +0574, +0575, +0576, +0577, +0578, +0579, +0580, +0581, +0582, +0583, +0584, +0585, +0586, +0587, +0588, +0589, +0590, +0591, +0592, +0593, +0594, +0595, +0596, +0597, +0599, +0600, +0601, +0602, +0603, +0604, +0605, +0606, +0607, +0608, +0609, +0610, +0614, +0615, +0616, +0617, +0618, +0619, +0620, +0621, +0622, // REMOVED: rustc-intrinsic ABI was removed +0623, +0624, +0625, +0626, +0627, +0628, +0631, +0632, +0633, +0634, +0635, +0636, +0637, +0638, +0639, +0640, +0641, +0642, +0643, +0644, +0646, +0647, +0648, +0657, +0658, +0659, +0660, +0661, +0662, +0663, +0664, +0665, +0666, +0667, +0668, +0669, +0670, +0671, +0687, +0688, +0689, +0690, +0691, +0692, +0693, +0695, +0696, +0697, +0698, +0699, // REMOVED: merged into generic inference var error +0700, +0701, +0703, +0704, +0705, +0706, +0708, +0710, +0712, +0713, +0714, +0715, +0716, +0711, +0717, +0718, +0719, +0720, +0722, +0724, +0725, +0726, +0727, +0728, +0729, +0730, +0731, +0732, +0733, +0734, +0735, +0736, +0737, +0739, +0740, +0741, +0742, +0743, +0744, +0745, +0746, +0747, +0748, +0749, +0750, +0751, +0752, +0753, +0754, +0755, +0756, +0757, +0758, +0759, +0760, +0761, +0762, +0763, +0764, +0765, +0766, +0767, +0768, +0769, +0770, +0771, +0772, +0773, // REMOVED: no longer an error +0774, +0775, +0776, +0777, +0778, +0779, +0780, +0781, +0782, +0783, +0784, +0785, +0786, +0787, +0788, +0789, +0790, +0791, +0792, +0793, +0794, +0795, +0796, +0797, +0798, +0799, +0800, +0801, +0802, +0803, +0804, +0805, ); ) } diff --git a/compiler/rustc_errors/src/codes.rs b/compiler/rustc_errors/src/codes.rs index 787a8af99b1f..924924f285eb 100644 --- a/compiler/rustc_errors/src/codes.rs +++ b/compiler/rustc_errors/src/codes.rs @@ -23,15 +23,15 @@ impl fmt::Display for ErrCode { rustc_error_messages::into_diag_arg_using_display!(ErrCode); macro_rules! define_error_code_constants_and_diagnostics_table { - ($($name:ident: $num:literal,)*) => ( + ($($num:literal,)*) => ( $( - pub const $name: $crate::ErrCode = $crate::ErrCode::from_u32($num); + pub const ${concat(E, $num)}: $crate::ErrCode = $crate::ErrCode::from_u32($num); )* pub static DIAGNOSTICS: &[($crate::ErrCode, &str)] = &[ $( ( - $name, + ${concat(E, $num)}, include_str!( - concat!("../../rustc_error_codes/src/error_codes/", stringify!($name), ".md") + concat!("../../rustc_error_codes/src/error_codes/E", stringify!($num), ".md") ) ), )* ]; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8869799ce90d..ad2b3c74270a 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -15,6 +15,7 @@ #![feature(box_patterns)] #![feature(default_field_values)] #![feature(error_reporter)] +#![feature(macro_metavar_expr_concat)] #![feature(negative_impls)] #![feature(never_type)] #![feature(rustc_attrs)] diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 83fbefa43d97..240ac839e3e3 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -91,20 +91,16 @@ fn extract_error_codes(root_path: &Path, check: &mut RunningCheck) -> Vec(); + if chars.next() != Some(',') { check.error(format!( - "{path}:{line_index}: Expected a line with the format `Eabcd: abcd, \ - but got \"{line}\" without a `:` delimiter", + "{path}:{line_index}: Expected a line with the format `abcd,` \ + but got \"{line}\" without a `,` delimiter", )); continue; - }; - - let err_code = split_line.0.to_owned(); + } // If this is a duplicate of another error code, emit a fatal error. if error_codes.contains(&err_code) { @@ -114,35 +110,13 @@ fn extract_error_codes(root_path: &Path, check: &mut RunningCheck) -> Vec Date: Tue, 7 Oct 2025 05:52:37 -0400 Subject: [PATCH 0039/3801] slice/ascii: Optimize `eq_ignore_ascii_case` with auto-vectorization Refactor the current functionality into a helper function Use `as_chunks` to encourage auto-vectorization in the optimized chunk processing function Add a codegen test Add benches for `eq_ignore_ascii_case` The optimized function is initially only enabled for x86_64 which has `sse2` as part of its baseline, but none of the code is platform specific. Other platforms with SIMD instructions may also benefit from this implementation. Performance improvements only manifest for slices of 16 bytes or longer, so the optimized path is gated behind a length check for greater than or equal to 16. --- library/core/src/slice/ascii.rs | 43 ++++++++++++++ library/coretests/benches/ascii.rs | 1 + .../benches/ascii/eq_ignore_ascii_case.rs | 56 +++++++++++++++++++ .../lib-optimizations/eq_ignore_ascii_case.rs | 14 +++++ 4 files changed, 114 insertions(+) create mode 100644 library/coretests/benches/ascii/eq_ignore_ascii_case.rs create mode 100644 tests/codegen-llvm/lib-optimizations/eq_ignore_ascii_case.rs diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index e17a2e03d2dc..1f9ca4bc6698 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -60,6 +60,18 @@ impl [u8] { return false; } + #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] + if self.len() >= 16 { + return self.eq_ignore_ascii_case_chunks(other); + } + + self.eq_ignore_ascii_case_simple(other) + } + + /// ASCII case-insensitive equality check without chunk-at-a-time + /// optimization. + #[inline] + const fn eq_ignore_ascii_case_simple(&self, other: &[u8]) -> bool { // FIXME(const-hack): This implementation can be reverted when // `core::iter::zip` is allowed in const. The original implementation: // self.len() == other.len() && iter::zip(self, other).all(|(a, b)| a.eq_ignore_ascii_case(b)) @@ -78,6 +90,37 @@ impl [u8] { true } + /// Optimized version of `eq_ignore_ascii_case` which processes chunks at a + /// time. + /// + /// Platforms that have SIMD instructions may benefit from this + /// implementation over `eq_ignore_ascii_case_simple`. + #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] + #[inline] + const fn eq_ignore_ascii_case_chunks(&self, other: &[u8]) -> bool { + const N: usize = 16; + let (a, a_rem) = self.as_chunks::(); + let (b, b_rem) = other.as_chunks::(); + + let mut i = 0; + while i < a.len() && i < b.len() { + let mut equal_ascii = true; + let mut j = 0; + while j < N { + equal_ascii &= a[i][j].eq_ignore_ascii_case(&b[i][j]); + j += 1; + } + + if !equal_ascii { + return false; + } + + i += 1; + } + + a_rem.eq_ignore_ascii_case_simple(b_rem) + } + /// Converts this slice to its ASCII upper case equivalent in-place. /// /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', diff --git a/library/coretests/benches/ascii.rs b/library/coretests/benches/ascii.rs index 64bdc7fed118..17a520922bfa 100644 --- a/library/coretests/benches/ascii.rs +++ b/library/coretests/benches/ascii.rs @@ -1,3 +1,4 @@ +mod eq_ignore_ascii_case; mod is_ascii; // Lower-case ASCII 'a' is the first byte that has its highest bit set diff --git a/library/coretests/benches/ascii/eq_ignore_ascii_case.rs b/library/coretests/benches/ascii/eq_ignore_ascii_case.rs new file mode 100644 index 000000000000..a51acb1e8463 --- /dev/null +++ b/library/coretests/benches/ascii/eq_ignore_ascii_case.rs @@ -0,0 +1,56 @@ +use test::Bencher; + +#[bench] +fn bench_str_under_8_bytes_eq(b: &mut Bencher) { + let s = "foo"; + let other = "FOo"; + b.iter(|| { + assert!(s.eq_ignore_ascii_case(other)); + }) +} + +#[bench] +fn bench_str_of_8_bytes_eq(b: &mut Bencher) { + let s = "foobar78"; + let other = "FOObAr78"; + b.iter(|| { + assert!(s.eq_ignore_ascii_case(other)); + }) +} + +#[bench] +fn bench_str_17_bytes_eq(b: &mut Bencher) { + let s = "performance-criti"; + let other = "performANce-cRIti"; + b.iter(|| { + assert!(s.eq_ignore_ascii_case(other)); + }) +} + +#[bench] +fn bench_str_31_bytes_eq(b: &mut Bencher) { + let s = "foobarbazquux02foobarbazquux025"; + let other = "fooBARbazQuuX02fooBARbazQuuX025"; + b.iter(|| { + assert!(s.eq_ignore_ascii_case(other)); + }) +} + +#[bench] +fn bench_long_str_eq(b: &mut Bencher) { + let s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \ + incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \ + exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \ + irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \ + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \ + officia deserunt mollit anim id est laborum."; + let other = "Lorem ipsum dolor sit amet, CONSECTETUR adipisicing elit, sed do eiusmod tempor \ + incididunt ut labore et dolore MAGNA aliqua. Ut enim ad MINIM veniam, quis nostrud \ + exercitation ullamco LABORIS nisi ut aliquip ex ea commodo consequat. Duis aute \ + irure dolor in reprehenderit in voluptate velit esse cillum DOLORE eu fugiat nulla \ + pariatur. Excepteur sint occaecat CUPIDATAT non proident, sunt in culpa qui \ + officia deserunt mollit anim id est laborum."; + b.iter(|| { + assert!(s.eq_ignore_ascii_case(other)); + }) +} diff --git a/tests/codegen-llvm/lib-optimizations/eq_ignore_ascii_case.rs b/tests/codegen-llvm/lib-optimizations/eq_ignore_ascii_case.rs new file mode 100644 index 000000000000..b733f1812c92 --- /dev/null +++ b/tests/codegen-llvm/lib-optimizations/eq_ignore_ascii_case.rs @@ -0,0 +1,14 @@ +//@ compile-flags: -Copt-level=3 +//@ only-x86_64 +#![crate_type = "lib"] + +// Ensure that the optimized variant of the function gets auto-vectorized. +// CHECK-LABEL: @eq_ignore_ascii_case_autovectorized +#[no_mangle] +pub fn eq_ignore_ascii_case_autovectorized(s: &str, other: &str) -> bool { + // CHECK: load <16 x i8> + // CHECK: load <16 x i8> + // CHECK: bitcast <16 x i1> + // CHECK-NOT: panic + s.eq_ignore_ascii_case(other) +} From 8ce88bcb509e1f7d7b6b76724a6fcb827d9a78ac Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Tue, 7 Oct 2025 10:16:49 -0400 Subject: [PATCH 0040/3801] Remove LaneCount in favor of #[rustc_simd_monomorphize_lane_limit] attribute (#485) * Remove LaneCount in favor of #[rustc_simd_monomorphize_lane_limit] attribute * Document allowed vector lengths --- crates/core_simd/src/fmt.rs | 3 +- crates/core_simd/src/iter.rs | 10 +---- crates/core_simd/src/lane_count.rs | 52 ---------------------- crates/core_simd/src/lib.rs | 3 +- crates/core_simd/src/masks.rs | 46 +++---------------- crates/core_simd/src/mod.rs | 2 - crates/core_simd/src/ops.rs | 5 +-- crates/core_simd/src/ops/assign.rs | 1 - crates/core_simd/src/ops/deref.rs | 3 -- crates/core_simd/src/ops/shift_scalar.rs | 10 +---- crates/core_simd/src/ops/unary.rs | 4 +- crates/core_simd/src/select.rs | 10 +---- crates/core_simd/src/simd/cmp/eq.rs | 16 ++----- crates/core_simd/src/simd/cmp/ord.rs | 32 +++---------- crates/core_simd/src/simd/num/float.rs | 10 +---- crates/core_simd/src/simd/num/int.rs | 14 ++---- crates/core_simd/src/simd/num/uint.rs | 10 +---- crates/core_simd/src/simd/ptr/const_ptr.rs | 9 ++-- crates/core_simd/src/simd/ptr/mut_ptr.rs | 9 ++-- crates/core_simd/src/swizzle.rs | 32 +++---------- crates/core_simd/src/swizzle_dyn.rs | 17 ++----- crates/core_simd/src/to_bytes.rs | 4 +- crates/core_simd/src/vector.rs | 43 +++--------------- crates/std_float/src/lib.rs | 10 ++--- crates/test_helpers/src/lib.rs | 4 -- rust-toolchain.toml | 2 +- 26 files changed, 57 insertions(+), 304 deletions(-) delete mode 100644 crates/core_simd/src/lane_count.rs diff --git a/crates/core_simd/src/fmt.rs b/crates/core_simd/src/fmt.rs index 3a540f5a0490..90c520e75bb3 100644 --- a/crates/core_simd/src/fmt.rs +++ b/crates/core_simd/src/fmt.rs @@ -1,9 +1,8 @@ -use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount}; +use crate::simd::{Simd, SimdElement}; use core::fmt; impl fmt::Debug for Simd where - LaneCount: SupportedLaneCount, T: SimdElement + fmt::Debug, { /// A `Simd` has a debug format like the one for `[T]`: diff --git a/crates/core_simd/src/iter.rs b/crates/core_simd/src/iter.rs index b3732fd74d5f..fdc458efeda4 100644 --- a/crates/core_simd/src/iter.rs +++ b/crates/core_simd/src/iter.rs @@ -1,4 +1,4 @@ -use crate::simd::{LaneCount, Simd, SupportedLaneCount}; +use crate::simd::Simd; use core::{ iter::{Product, Sum}, ops::{Add, Mul}, @@ -7,8 +7,6 @@ use core::{ macro_rules! impl_traits { { $type:ty } => { impl Sum for Simd<$type, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn sum>(iter: I) -> Self { @@ -17,8 +15,6 @@ macro_rules! impl_traits { } impl Product for Simd<$type, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn product>(iter: I) -> Self { @@ -27,8 +23,6 @@ macro_rules! impl_traits { } impl<'a, const N: usize> Sum<&'a Self> for Simd<$type, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn sum>(iter: I) -> Self { @@ -37,8 +31,6 @@ macro_rules! impl_traits { } impl<'a, const N: usize> Product<&'a Self> for Simd<$type, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn product>(iter: I) -> Self { diff --git a/crates/core_simd/src/lane_count.rs b/crates/core_simd/src/lane_count.rs deleted file mode 100644 index 839195c38eda..000000000000 --- a/crates/core_simd/src/lane_count.rs +++ /dev/null @@ -1,52 +0,0 @@ -mod sealed { - pub trait Sealed {} -} -use sealed::Sealed; - -/// Specifies the number of lanes in a SIMD vector as a type. -pub struct LaneCount; - -impl LaneCount { - /// The number of bytes in a bitmask with this many lanes. - pub const BITMASK_LEN: usize = N.div_ceil(8); -} - -/// Statically guarantees that a lane count is marked as supported. -/// -/// This trait is *sealed*: the list of implementors below is total. -/// Users do not have the ability to mark additional `LaneCount` values as supported. -/// Only SIMD vectors with supported lane counts are constructable. -pub trait SupportedLaneCount: Sealed { - #[doc(hidden)] - type BitMask: Copy + AsRef<[u8]> + AsMut<[u8]>; - #[doc(hidden)] - const EMPTY_BIT_MASK: Self::BitMask; - #[doc(hidden)] - const FULL_BIT_MASK: Self::BitMask; -} - -impl Sealed for LaneCount {} - -macro_rules! supported_lane_count { - ($($lanes:literal),+) => { - $( - impl SupportedLaneCount for LaneCount<$lanes> { - type BitMask = [u8; Self::BITMASK_LEN]; - const EMPTY_BIT_MASK: Self::BitMask = [0; Self::BITMASK_LEN]; - const FULL_BIT_MASK: Self::BitMask = { - let mut array = [!0u8; Self::BITMASK_LEN]; - if $lanes % 8 > 0 { - array[Self::BITMASK_LEN - 1] = (!0) >> (8 - $lanes % 8); - } - array - }; - } - )+ - }; -} - -supported_lane_count!( - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 -); diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index 9d7dfd2ab351..3e5ebe19e4db 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -9,7 +9,8 @@ simd_ffi, staged_api, prelude_import, - ptr_metadata + ptr_metadata, + rustc_attrs )] #![cfg_attr( all( diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index 7baa96475910..3e2209556b66 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -2,7 +2,7 @@ //! Types representing #![allow(non_camel_case_types)] -use crate::simd::{LaneCount, Select, Simd, SimdCast, SimdElement, SupportedLaneCount}; +use crate::simd::{Select, Simd, SimdCast, SimdElement}; use core::cmp::Ordering; use core::{fmt, mem}; @@ -41,7 +41,6 @@ mod sealed { pub trait Sealed { fn valid(values: Simd) -> bool where - LaneCount: SupportedLaneCount, Self: SimdElement; fn eq(self, other: Self) -> bool; @@ -69,8 +68,6 @@ macro_rules! impl_element { impl Sealed for $ty { #[inline] fn valid(value: Simd) -> bool - where - LaneCount: SupportedLaneCount, { // We can't use `Simd` directly, because `Simd`'s functions call this function and // we will end up with an infinite loop. @@ -121,23 +118,19 @@ impl_element! { isize, usize } /// The layout of this type is unspecified, and may change between platforms /// and/or Rust versions, and code should not assume that it is equivalent to /// `[T; N]`. +/// +/// `N` cannot be 0 and may be at most 64. This limit may be increased in +/// the future. #[repr(transparent)] pub struct Mask(Simd) where - T: MaskElement, - LaneCount: SupportedLaneCount; + T: MaskElement; -impl Copy for Mask -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ -} +impl Copy for Mask where T: MaskElement {} impl Clone for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn clone(&self) -> Self { @@ -148,7 +141,6 @@ where impl Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { /// Constructs a mask by setting all elements to the given value. #[inline] @@ -315,8 +307,6 @@ where ) -> U where T: MaskElement, - LaneCount: SupportedLaneCount, - LaneCount: SupportedLaneCount, { let resized = mask.resize::(false); @@ -421,7 +411,6 @@ where impl From<[bool; N]> for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn from(array: [bool; N]) -> Self { @@ -432,7 +421,6 @@ where impl From> for [bool; N] where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn from(vector: Mask) -> Self { @@ -443,7 +431,6 @@ where impl Default for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn default() -> Self { @@ -454,7 +441,6 @@ where impl PartialEq for Mask where T: MaskElement + PartialEq, - LaneCount: SupportedLaneCount, { #[inline] fn eq(&self, other: &Self) -> bool { @@ -465,7 +451,6 @@ where impl PartialOrd for Mask where T: MaskElement + PartialOrd, - LaneCount: SupportedLaneCount, { #[inline] fn partial_cmp(&self, other: &Self) -> Option { @@ -476,7 +461,6 @@ where impl fmt::Debug for Mask where T: MaskElement + fmt::Debug, - LaneCount: SupportedLaneCount, { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -489,7 +473,6 @@ where impl core::ops::BitAnd for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Self; #[inline] @@ -502,7 +485,6 @@ where impl core::ops::BitAnd for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Self; #[inline] @@ -514,7 +496,6 @@ where impl core::ops::BitAnd> for bool where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Mask; #[inline] @@ -526,7 +507,6 @@ where impl core::ops::BitOr for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Self; #[inline] @@ -539,7 +519,6 @@ where impl core::ops::BitOr for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Self; #[inline] @@ -551,7 +530,6 @@ where impl core::ops::BitOr> for bool where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Mask; #[inline] @@ -563,7 +541,6 @@ where impl core::ops::BitXor for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Self; #[inline] @@ -576,7 +553,6 @@ where impl core::ops::BitXor for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Self; #[inline] @@ -588,7 +564,6 @@ where impl core::ops::BitXor> for bool where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Mask; #[inline] @@ -600,7 +575,6 @@ where impl core::ops::Not for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { type Output = Mask; #[inline] @@ -612,7 +586,6 @@ where impl core::ops::BitAndAssign for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn bitand_assign(&mut self, rhs: Self) { @@ -623,7 +596,6 @@ where impl core::ops::BitAndAssign for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn bitand_assign(&mut self, rhs: bool) { @@ -634,7 +606,6 @@ where impl core::ops::BitOrAssign for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn bitor_assign(&mut self, rhs: Self) { @@ -645,7 +616,6 @@ where impl core::ops::BitOrAssign for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn bitor_assign(&mut self, rhs: bool) { @@ -656,7 +626,6 @@ where impl core::ops::BitXorAssign for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn bitxor_assign(&mut self, rhs: Self) { @@ -667,7 +636,6 @@ where impl core::ops::BitXorAssign for Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn bitxor_assign(&mut self, rhs: bool) { @@ -679,8 +647,6 @@ macro_rules! impl_from { { $from:ty => $($to:ty),* } => { $( impl From> for Mask<$to, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn from(value: Mask<$from, N>) -> Self { diff --git a/crates/core_simd/src/mod.rs b/crates/core_simd/src/mod.rs index 14fe70df4ed1..5f635d80a178 100644 --- a/crates/core_simd/src/mod.rs +++ b/crates/core_simd/src/mod.rs @@ -5,7 +5,6 @@ mod alias; mod cast; mod fmt; mod iter; -mod lane_count; mod masks; mod ops; mod select; @@ -27,7 +26,6 @@ pub mod simd { pub use crate::core_simd::alias::*; pub use crate::core_simd::cast::*; - pub use crate::core_simd::lane_count::{LaneCount, SupportedLaneCount}; pub use crate::core_simd::masks::*; pub use crate::core_simd::select::*; pub use crate::core_simd::swizzle::*; diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index f36e360fadf9..eb6601f73483 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -1,4 +1,4 @@ -use crate::simd::{LaneCount, Select, Simd, SimdElement, SupportedLaneCount, cmp::SimdPartialEq}; +use crate::simd::{Select, Simd, SimdElement, cmp::SimdPartialEq}; use core::ops::{Add, Mul}; use core::ops::{BitAnd, BitOr, BitXor}; use core::ops::{Div, Rem, Sub}; @@ -12,7 +12,6 @@ mod unary; impl core::ops::Index for Simd where T: SimdElement, - LaneCount: SupportedLaneCount, I: core::slice::SliceIndex<[T]>, { type Output = I::Output; @@ -25,7 +24,6 @@ where impl core::ops::IndexMut for Simd where T: SimdElement, - LaneCount: SupportedLaneCount, I: core::slice::SliceIndex<[T]>, { #[inline] @@ -130,7 +128,6 @@ macro_rules! for_base_types { impl $op for Simd<$scalar, N> where $scalar: SimdElement, - LaneCount: SupportedLaneCount, { type Output = $out; diff --git a/crates/core_simd/src/ops/assign.rs b/crates/core_simd/src/ops/assign.rs index d21d867de26d..c1830c35df77 100644 --- a/crates/core_simd/src/ops/assign.rs +++ b/crates/core_simd/src/ops/assign.rs @@ -21,7 +21,6 @@ macro_rules! assign_ops { where Self: $trait, T: SimdElement, - LaneCount: SupportedLaneCount, { #[inline] fn $assign_call(&mut self, rhs: U) { diff --git a/crates/core_simd/src/ops/deref.rs b/crates/core_simd/src/ops/deref.rs index 913cbbe977c4..360b83c40346 100644 --- a/crates/core_simd/src/ops/deref.rs +++ b/crates/core_simd/src/ops/deref.rs @@ -13,7 +13,6 @@ macro_rules! deref_lhs { where T: SimdElement, $simd: $trait<$simd, Output = $simd>, - LaneCount: SupportedLaneCount, { type Output = Simd; @@ -33,7 +32,6 @@ macro_rules! deref_rhs { where T: SimdElement, $simd: $trait<$simd, Output = $simd>, - LaneCount: SupportedLaneCount, { type Output = Simd; @@ -64,7 +62,6 @@ macro_rules! deref_ops { where T: SimdElement, $simd: $trait<$simd, Output = $simd>, - LaneCount: SupportedLaneCount, { type Output = $simd; diff --git a/crates/core_simd/src/ops/shift_scalar.rs b/crates/core_simd/src/ops/shift_scalar.rs index f5115a5a5e93..7ca83dc40f61 100644 --- a/crates/core_simd/src/ops/shift_scalar.rs +++ b/crates/core_simd/src/ops/shift_scalar.rs @@ -1,13 +1,11 @@ // Shift operations uniquely typically only have a scalar on the right-hand side. // Here, we implement shifts for scalar RHS arguments. -use crate::simd::{LaneCount, Simd, SupportedLaneCount}; +use crate::simd::Simd; macro_rules! impl_splatted_shifts { { impl $trait:ident :: $trait_fn:ident for $ty:ty } => { impl core::ops::$trait<$ty> for Simd<$ty, N> - where - LaneCount: SupportedLaneCount, { type Output = Self; #[inline] @@ -17,8 +15,6 @@ macro_rules! impl_splatted_shifts { } impl core::ops::$trait<&$ty> for Simd<$ty, N> - where - LaneCount: SupportedLaneCount, { type Output = Self; #[inline] @@ -28,8 +24,6 @@ macro_rules! impl_splatted_shifts { } impl<'lhs, const N: usize> core::ops::$trait<$ty> for &'lhs Simd<$ty, N> - where - LaneCount: SupportedLaneCount, { type Output = Simd<$ty, N>; #[inline] @@ -39,8 +33,6 @@ macro_rules! impl_splatted_shifts { } impl<'lhs, const N: usize> core::ops::$trait<&$ty> for &'lhs Simd<$ty, N> - where - LaneCount: SupportedLaneCount, { type Output = Simd<$ty, N>; #[inline] diff --git a/crates/core_simd/src/ops/unary.rs b/crates/core_simd/src/ops/unary.rs index 412a5b801171..e1c06167f979 100644 --- a/crates/core_simd/src/ops/unary.rs +++ b/crates/core_simd/src/ops/unary.rs @@ -1,4 +1,4 @@ -use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount}; +use crate::simd::{Simd, SimdElement}; use core::ops::{Neg, Not}; // unary ops macro_rules! neg { @@ -6,7 +6,6 @@ macro_rules! neg { $(impl Neg for Simd<$scalar, N> where $scalar: SimdElement, - LaneCount: SupportedLaneCount, { type Output = Self; @@ -40,7 +39,6 @@ macro_rules! not { $(impl Not for Simd<$scalar, N> where $scalar: SimdElement, - LaneCount: SupportedLaneCount, { type Output = Self; diff --git a/crates/core_simd/src/select.rs b/crates/core_simd/src/select.rs index 5240b9b0c716..404f54d8f382 100644 --- a/crates/core_simd/src/select.rs +++ b/crates/core_simd/src/select.rs @@ -1,6 +1,4 @@ -use crate::simd::{ - FixEndianness, LaneCount, Mask, MaskElement, Simd, SimdElement, SupportedLaneCount, -}; +use crate::simd::{FixEndianness, Mask, MaskElement, Simd, SimdElement}; /// Choose elements from two vectors using a mask. /// @@ -59,7 +57,6 @@ impl Select> for Mask where T: SimdElement, U: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn select(self, true_values: Simd, false_values: Simd) -> Simd { @@ -76,7 +73,6 @@ where impl Select> for u64 where T: SimdElement, - LaneCount: SupportedLaneCount, { #[inline] fn select(self, true_values: Simd, false_values: Simd) -> Simd { @@ -92,8 +88,6 @@ where ) -> Simd where T: SimdElement, - LaneCount: SupportedLaneCount, - LaneCount: SupportedLaneCount, { let default = true_values[0]; let true_values = true_values.resize::(default); @@ -135,7 +129,6 @@ impl Select> for Mask where T: MaskElement, U: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn select(self, true_values: Mask, false_values: Mask) -> Mask { @@ -150,7 +143,6 @@ where impl Select> for u64 where T: MaskElement, - LaneCount: SupportedLaneCount, { #[inline] fn select(self, true_values: Mask, false_values: Mask) -> Mask { diff --git a/crates/core_simd/src/simd/cmp/eq.rs b/crates/core_simd/src/simd/cmp/eq.rs index 789fc0bb9424..d553d6c040c9 100644 --- a/crates/core_simd/src/simd/cmp/eq.rs +++ b/crates/core_simd/src/simd/cmp/eq.rs @@ -1,5 +1,5 @@ use crate::simd::{ - LaneCount, Mask, Simd, SimdElement, SupportedLaneCount, + Mask, Simd, SimdElement, ptr::{SimdConstPtr, SimdMutPtr}, }; @@ -21,8 +21,6 @@ macro_rules! impl_number { { $($number:ty),* } => { $( impl SimdPartialEq for Simd<$number, N> - where - LaneCount: SupportedLaneCount, { type Mask = Mask<<$number as SimdElement>::Mask, N>; @@ -50,8 +48,6 @@ macro_rules! impl_mask { { $($integer:ty),* } => { $( impl SimdPartialEq for Mask<$integer, N> - where - LaneCount: SupportedLaneCount, { type Mask = Self; @@ -75,10 +71,7 @@ macro_rules! impl_mask { impl_mask! { i8, i16, i32, i64, isize } -impl SimdPartialEq for Simd<*const T, N> -where - LaneCount: SupportedLaneCount, -{ +impl SimdPartialEq for Simd<*const T, N> { type Mask = Mask; #[inline] @@ -92,10 +85,7 @@ where } } -impl SimdPartialEq for Simd<*mut T, N> -where - LaneCount: SupportedLaneCount, -{ +impl SimdPartialEq for Simd<*mut T, N> { type Mask = Mask; #[inline] diff --git a/crates/core_simd/src/simd/cmp/ord.rs b/crates/core_simd/src/simd/cmp/ord.rs index 1b1c689ad458..5672fbbf54ca 100644 --- a/crates/core_simd/src/simd/cmp/ord.rs +++ b/crates/core_simd/src/simd/cmp/ord.rs @@ -1,5 +1,5 @@ use crate::simd::{ - LaneCount, Mask, Select, Simd, SupportedLaneCount, + Mask, Select, Simd, cmp::SimdPartialEq, ptr::{SimdConstPtr, SimdMutPtr}, }; @@ -49,8 +49,6 @@ macro_rules! impl_integer { { $($integer:ty),* } => { $( impl SimdPartialOrd for Simd<$integer, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn simd_lt(self, other: Self) -> Self::Mask { @@ -82,8 +80,6 @@ macro_rules! impl_integer { } impl SimdOrd for Simd<$integer, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn simd_max(self, other: Self) -> Self { @@ -115,8 +111,6 @@ macro_rules! impl_float { { $($float:ty),* } => { $( impl SimdPartialOrd for Simd<$float, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn simd_lt(self, other: Self) -> Self::Mask { @@ -156,8 +150,6 @@ macro_rules! impl_mask { { $($integer:ty),* } => { $( impl SimdPartialOrd for Mask<$integer, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn simd_lt(self, other: Self) -> Self::Mask { @@ -189,8 +181,6 @@ macro_rules! impl_mask { } impl SimdOrd for Mask<$integer, N> - where - LaneCount: SupportedLaneCount, { #[inline] fn simd_max(self, other: Self) -> Self { @@ -218,10 +208,7 @@ macro_rules! impl_mask { impl_mask! { i8, i16, i32, i64, isize } -impl SimdPartialOrd for Simd<*const T, N> -where - LaneCount: SupportedLaneCount, -{ +impl SimdPartialOrd for Simd<*const T, N> { #[inline] fn simd_lt(self, other: Self) -> Self::Mask { self.addr().simd_lt(other.addr()) @@ -243,10 +230,7 @@ where } } -impl SimdOrd for Simd<*const T, N> -where - LaneCount: SupportedLaneCount, -{ +impl SimdOrd for Simd<*const T, N> { #[inline] fn simd_max(self, other: Self) -> Self { self.simd_lt(other).select(other, self) @@ -268,10 +252,7 @@ where } } -impl SimdPartialOrd for Simd<*mut T, N> -where - LaneCount: SupportedLaneCount, -{ +impl SimdPartialOrd for Simd<*mut T, N> { #[inline] fn simd_lt(self, other: Self) -> Self::Mask { self.addr().simd_lt(other.addr()) @@ -293,10 +274,7 @@ where } } -impl SimdOrd for Simd<*mut T, N> -where - LaneCount: SupportedLaneCount, -{ +impl SimdOrd for Simd<*mut T, N> { #[inline] fn simd_max(self, other: Self) -> Self { self.simd_lt(other).select(other, self) diff --git a/crates/core_simd/src/simd/num/float.rs b/crates/core_simd/src/simd/num/float.rs index 76ab5748c638..efd7c2469512 100644 --- a/crates/core_simd/src/simd/num/float.rs +++ b/crates/core_simd/src/simd/num/float.rs @@ -1,6 +1,6 @@ use super::sealed::Sealed; use crate::simd::{ - LaneCount, Mask, Select, Simd, SimdCast, SimdElement, SupportedLaneCount, + Mask, Select, Simd, SimdCast, SimdElement, cmp::{SimdPartialEq, SimdPartialOrd}, }; @@ -240,15 +240,9 @@ pub trait SimdFloat: Copy + Sealed { macro_rules! impl_trait { { $($ty:ty { bits: $bits_ty:ty, mask: $mask_ty:ty }),* } => { $( - impl Sealed for Simd<$ty, N> - where - LaneCount: SupportedLaneCount, - { - } + impl Sealed for Simd<$ty, N> {} impl SimdFloat for Simd<$ty, N> - where - LaneCount: SupportedLaneCount, { type Mask = Mask<<$mask_ty as SimdElement>::Mask, N>; type Scalar = $ty; diff --git a/crates/core_simd/src/simd/num/int.rs b/crates/core_simd/src/simd/num/int.rs index 5a292407d050..6ebf0ba397c6 100644 --- a/crates/core_simd/src/simd/num/int.rs +++ b/crates/core_simd/src/simd/num/int.rs @@ -1,7 +1,6 @@ use super::sealed::Sealed; use crate::simd::{ - LaneCount, Mask, Select, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd, - cmp::SimdPartialOrd, num::SimdUint, + Mask, Select, Simd, SimdCast, SimdElement, cmp::SimdOrd, cmp::SimdPartialOrd, num::SimdUint, }; /// Operations on SIMD vectors of signed integers. @@ -241,16 +240,9 @@ pub trait SimdInt: Copy + Sealed { macro_rules! impl_trait { { $($ty:ident ($unsigned:ident)),* } => { $( - impl Sealed for Simd<$ty, N> - where - LaneCount: SupportedLaneCount, - { - } + impl Sealed for Simd<$ty, N> {} - impl SimdInt for Simd<$ty, N> - where - LaneCount: SupportedLaneCount, - { + impl SimdInt for Simd<$ty, N> { type Mask = Mask<<$ty as SimdElement>::Mask, N>; type Scalar = $ty; type Unsigned = Simd<$unsigned, N>; diff --git a/crates/core_simd/src/simd/num/uint.rs b/crates/core_simd/src/simd/num/uint.rs index 45d978068b66..f8a40f8ec565 100644 --- a/crates/core_simd/src/simd/num/uint.rs +++ b/crates/core_simd/src/simd/num/uint.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd}; +use crate::simd::{Simd, SimdCast, SimdElement, cmp::SimdOrd}; /// Operations on SIMD vectors of unsigned integers. pub trait SimdUint: Copy + Sealed { @@ -123,15 +123,9 @@ pub trait SimdUint: Copy + Sealed { macro_rules! impl_trait { { $($ty:ident ($signed:ident)),* } => { $( - impl Sealed for Simd<$ty, N> - where - LaneCount: SupportedLaneCount, - { - } + impl Sealed for Simd<$ty, N> {} impl SimdUint for Simd<$ty, N> - where - LaneCount: SupportedLaneCount, { type Scalar = $ty; type Cast = Simd; diff --git a/crates/core_simd/src/simd/ptr/const_ptr.rs b/crates/core_simd/src/simd/ptr/const_ptr.rs index 36452e7ae920..7ef9dc21373e 100644 --- a/crates/core_simd/src/simd/ptr/const_ptr.rs +++ b/crates/core_simd/src/simd/ptr/const_ptr.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, num::SimdUint}; +use crate::simd::{Mask, Simd, cmp::SimdPartialEq, num::SimdUint}; /// Operations on SIMD vectors of constant pointers. pub trait SimdConstPtr: Copy + Sealed { @@ -88,12 +88,9 @@ pub trait SimdConstPtr: Copy + Sealed { fn wrapping_sub(self, count: Self::Usize) -> Self; } -impl Sealed for Simd<*const T, N> where LaneCount: SupportedLaneCount {} +impl Sealed for Simd<*const T, N> {} -impl SimdConstPtr for Simd<*const T, N> -where - LaneCount: SupportedLaneCount, -{ +impl SimdConstPtr for Simd<*const T, N> { type Usize = Simd; type Isize = Simd; type CastPtr = Simd<*const U, N>; diff --git a/crates/core_simd/src/simd/ptr/mut_ptr.rs b/crates/core_simd/src/simd/ptr/mut_ptr.rs index c644f390c20a..3b9b75ddf566 100644 --- a/crates/core_simd/src/simd/ptr/mut_ptr.rs +++ b/crates/core_simd/src/simd/ptr/mut_ptr.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, num::SimdUint}; +use crate::simd::{Mask, Simd, cmp::SimdPartialEq, num::SimdUint}; /// Operations on SIMD vectors of mutable pointers. pub trait SimdMutPtr: Copy + Sealed { @@ -85,12 +85,9 @@ pub trait SimdMutPtr: Copy + Sealed { fn wrapping_sub(self, count: Self::Usize) -> Self; } -impl Sealed for Simd<*mut T, N> where LaneCount: SupportedLaneCount {} +impl Sealed for Simd<*mut T, N> {} -impl SimdMutPtr for Simd<*mut T, N> -where - LaneCount: SupportedLaneCount, -{ +impl SimdMutPtr for Simd<*mut T, N> { type Usize = Simd; type Isize = Simd; type CastPtr = Simd<*mut U, N>; diff --git a/crates/core_simd/src/swizzle.rs b/crates/core_simd/src/swizzle.rs index 81085a9ee4a3..02dcd71356dd 100644 --- a/crates/core_simd/src/swizzle.rs +++ b/crates/core_simd/src/swizzle.rs @@ -1,4 +1,4 @@ -use crate::simd::{LaneCount, Mask, MaskElement, Simd, SimdElement, SupportedLaneCount}; +use crate::simd::{Mask, MaskElement, Simd, SimdElement}; /// Constructs a new SIMD vector by copying elements from selected elements in other vectors. /// @@ -82,8 +82,6 @@ pub trait Swizzle { fn swizzle(vector: Simd) -> Simd where T: SimdElement, - LaneCount: SupportedLaneCount, - LaneCount: SupportedLaneCount, { // Safety: `vector` is a vector, and the index is a const vector of u32. unsafe { @@ -122,8 +120,6 @@ pub trait Swizzle { fn concat_swizzle(first: Simd, second: Simd) -> Simd where T: SimdElement, - LaneCount: SupportedLaneCount, - LaneCount: SupportedLaneCount, { // Safety: `first` and `second` are vectors, and the index is a const vector of u32. unsafe { @@ -161,8 +157,6 @@ pub trait Swizzle { fn swizzle_mask(mask: Mask) -> Mask where T: MaskElement, - LaneCount: SupportedLaneCount, - LaneCount: SupportedLaneCount, { // SAFETY: all elements of this mask come from another mask unsafe { Mask::from_simd_unchecked(Self::swizzle(mask.to_simd())) } @@ -177,8 +171,6 @@ pub trait Swizzle { fn concat_swizzle_mask(first: Mask, second: Mask) -> Mask where T: MaskElement, - LaneCount: SupportedLaneCount, - LaneCount: SupportedLaneCount, { // SAFETY: all elements of this mask come from another mask unsafe { @@ -190,7 +182,6 @@ pub trait Swizzle { impl Simd where T: SimdElement, - LaneCount: SupportedLaneCount, { /// Reverse the order of the elements in the vector. #[inline] @@ -464,10 +455,7 @@ where /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] - pub fn resize(self, value: T) -> Simd - where - LaneCount: SupportedLaneCount, - { + pub fn resize(self, value: T) -> Simd { struct Resize; impl Swizzle for Resize { const INDEX: [usize; M] = const { @@ -495,10 +483,7 @@ where /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] - pub fn extract(self) -> Simd - where - LaneCount: SupportedLaneCount, - { + pub fn extract(self) -> Simd { struct Extract; impl Swizzle for Extract { const INDEX: [usize; LEN] = const { @@ -519,7 +504,6 @@ where impl Mask where T: MaskElement, - LaneCount: SupportedLaneCount, { /// Reverse the order of the elements in the mask. #[inline] @@ -655,10 +639,7 @@ where /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] - pub fn resize(self, value: bool) -> Mask - where - LaneCount: SupportedLaneCount, - { + pub fn resize(self, value: bool) -> Mask { // Safety: swizzles are safe for masks unsafe { Mask::::from_simd_unchecked(self.to_simd().resize::(if value { @@ -681,10 +662,7 @@ where /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] - pub fn extract(self) -> Mask - where - LaneCount: SupportedLaneCount, - { + pub fn extract(self) -> Mask { // Safety: swizzles are safe for masks unsafe { Mask::::from_simd_unchecked(self.to_simd().extract::()) } } diff --git a/crates/core_simd/src/swizzle_dyn.rs b/crates/core_simd/src/swizzle_dyn.rs index 73b18595d0a1..ae0b174973da 100644 --- a/crates/core_simd/src/swizzle_dyn.rs +++ b/crates/core_simd/src/swizzle_dyn.rs @@ -1,10 +1,7 @@ -use crate::simd::{LaneCount, Simd, SupportedLaneCount}; +use crate::simd::Simd; use core::mem; -impl Simd -where - LaneCount: SupportedLaneCount, -{ +impl Simd { /// Swizzle a vector of bytes according to the index vector. /// Indices within range select the appropriate byte. /// Indices "out of bounds" instead select 0. @@ -184,10 +181,7 @@ unsafe fn transize( f: unsafe fn(T, T) -> T, a: Simd, b: Simd, -) -> Simd -where - LaneCount: SupportedLaneCount, -{ +) -> Simd { // SAFETY: Same obligation to use this function as to use mem::transmute_copy. unsafe { mem::transmute_copy(&f(mem::transmute_copy(&a), mem::transmute_copy(&b))) } } @@ -196,10 +190,7 @@ where #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[allow(unused)] #[inline(always)] -fn zeroing_idxs(idxs: Simd) -> Simd -where - LaneCount: SupportedLaneCount, -{ +fn zeroing_idxs(idxs: Simd) -> Simd { use crate::simd::{Select, cmp::SimdPartialOrd}; idxs.simd_lt(Simd::splat(N as u8)) .select(idxs, Simd::splat(u8::MAX)) diff --git a/crates/core_simd/src/to_bytes.rs b/crates/core_simd/src/to_bytes.rs index fee2cc06c5b0..1fd285e457db 100644 --- a/crates/core_simd/src/to_bytes.rs +++ b/crates/core_simd/src/to_bytes.rs @@ -1,12 +1,12 @@ use crate::simd::{ - LaneCount, Simd, SimdElement, SupportedLaneCount, + Simd, SimdElement, num::{SimdFloat, SimdInt, SimdUint}, }; mod sealed { use super::*; pub trait Sealed {} - impl Sealed for Simd where LaneCount: SupportedLaneCount {} + impl Sealed for Simd {} } use sealed::Sealed; diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index c00cfcdd41ff..2dba5c83e112 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -1,5 +1,5 @@ use crate::simd::{ - LaneCount, Mask, MaskElement, SupportedLaneCount, Swizzle, + Mask, MaskElement, Swizzle, cmp::SimdPartialOrd, num::SimdUint, ptr::{SimdConstPtr, SimdMutPtr}, @@ -51,6 +51,8 @@ use crate::simd::{ /// Thus it is sound to [`transmute`] `Simd` to `[T; N]` and should optimize to "zero cost", /// but the reverse transmutation may require a copy the compiler cannot simply elide. /// +/// `N` cannot be 0 and may be at most 64. This limit may be increased in the future. +/// /// # ABI "Features" /// Due to Rust's safety guarantees, `Simd` is currently passed and returned via memory, /// not SIMD registers, except as an optimization. Using `#[inline]` on functions that accept @@ -100,14 +102,13 @@ use crate::simd::{ // avoided, as it will likely become illegal on `#[repr(simd)]` structs in the future. It also // causes rustc to emit illegal LLVM IR in some cases. #[repr(simd, packed)] +#[rustc_simd_monomorphize_lane_limit = "64"] pub struct Simd([T; N]) where - LaneCount: SupportedLaneCount, T: SimdElement; impl Simd where - LaneCount: SupportedLaneCount, T: SimdElement, { /// Number of elements in this vector. @@ -149,7 +150,6 @@ where const fn splat_const(value: T) -> Simd where T: SimdElement, - LaneCount: SupportedLaneCount, { Simd::from_array([value; N]) } @@ -157,7 +157,6 @@ where fn splat_rt(value: T) -> Simd where T: SimdElement, - LaneCount: SupportedLaneCount, { // This is preferred over `[value; N]`, since it's explicitly a splat: // https://github.com/rust-lang/rust/issues/97804 @@ -886,16 +885,10 @@ where } } -impl Copy for Simd -where - LaneCount: SupportedLaneCount, - T: SimdElement, -{ -} +impl Copy for Simd where T: SimdElement {} impl Clone for Simd where - LaneCount: SupportedLaneCount, T: SimdElement, { #[inline] @@ -906,7 +899,6 @@ where impl Default for Simd where - LaneCount: SupportedLaneCount, T: SimdElement + Default, { #[inline] @@ -917,7 +909,6 @@ where impl PartialEq for Simd where - LaneCount: SupportedLaneCount, T: SimdElement + PartialEq, { #[inline] @@ -951,7 +942,6 @@ where /// Lexicographic order. For the SIMD elementwise minimum and maximum, use simd_min and simd_max instead. impl PartialOrd for Simd where - LaneCount: SupportedLaneCount, T: SimdElement + PartialOrd, { #[inline] @@ -961,17 +951,11 @@ where } } -impl Eq for Simd -where - LaneCount: SupportedLaneCount, - T: SimdElement + Eq, -{ -} +impl Eq for Simd where T: SimdElement + Eq {} /// Lexicographic order. For the SIMD elementwise minimum and maximum, use simd_min and simd_max instead. impl Ord for Simd where - LaneCount: SupportedLaneCount, T: SimdElement + Ord, { #[inline] @@ -983,7 +967,6 @@ where impl core::hash::Hash for Simd where - LaneCount: SupportedLaneCount, T: SimdElement + core::hash::Hash, { #[inline] @@ -998,7 +981,6 @@ where // array references impl AsRef<[T; N]> for Simd where - LaneCount: SupportedLaneCount, T: SimdElement, { #[inline] @@ -1009,7 +991,6 @@ where impl AsMut<[T; N]> for Simd where - LaneCount: SupportedLaneCount, T: SimdElement, { #[inline] @@ -1021,7 +1002,6 @@ where // slice references impl AsRef<[T]> for Simd where - LaneCount: SupportedLaneCount, T: SimdElement, { #[inline] @@ -1032,7 +1012,6 @@ where impl AsMut<[T]> for Simd where - LaneCount: SupportedLaneCount, T: SimdElement, { #[inline] @@ -1044,7 +1023,6 @@ where // vector/array conversion impl From<[T; N]> for Simd where - LaneCount: SupportedLaneCount, T: SimdElement, { #[inline] @@ -1055,7 +1033,6 @@ where impl From> for [T; N] where - LaneCount: SupportedLaneCount, T: SimdElement, { #[inline] @@ -1066,7 +1043,6 @@ where impl TryFrom<&[T]> for Simd where - LaneCount: SupportedLaneCount, T: SimdElement, { type Error = core::array::TryFromSliceError; @@ -1079,7 +1055,6 @@ where impl TryFrom<&mut [T]> for Simd where - LaneCount: SupportedLaneCount, T: SimdElement, { type Error = core::array::TryFromSliceError; @@ -1217,10 +1192,7 @@ where } #[inline] -fn lane_indices() -> Simd -where - LaneCount: SupportedLaneCount, -{ +fn lane_indices() -> Simd { #![allow(clippy::needless_range_loop)] let mut index = [0; N]; for i in 0..N { @@ -1232,7 +1204,6 @@ where #[inline] fn mask_up_to(len: usize) -> Mask where - LaneCount: SupportedLaneCount, M: MaskElement, { let index = lane_indices::(); diff --git a/crates/std_float/src/lib.rs b/crates/std_float/src/lib.rs index 148aa5f9f177..c3c9b76e50b8 100644 --- a/crates/std_float/src/lib.rs +++ b/crates/std_float/src/lib.rs @@ -11,7 +11,7 @@ use core_simd::simd; use core::intrinsics::simd as intrinsics; -use simd::{LaneCount, Simd, SupportedLaneCount}; +use simd::Simd; #[cfg(feature = "as_crate")] mod experimental { @@ -140,16 +140,14 @@ pub trait StdFloat: Sealed + Sized { fn fract(self) -> Self; } -impl Sealed for Simd where LaneCount: SupportedLaneCount {} -impl Sealed for Simd where LaneCount: SupportedLaneCount {} +impl Sealed for Simd {} +impl Sealed for Simd {} macro_rules! impl_float { { $($fn:ident: $intrinsic:ident,)* } => { impl StdFloat for Simd - where - LaneCount: SupportedLaneCount, { #[inline] fn fract(self) -> Self { @@ -165,8 +163,6 @@ macro_rules! impl_float { } impl StdFloat for Simd - where - LaneCount: SupportedLaneCount, { #[inline] fn fract(self) -> Self { diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 35401a9ddb40..eb3d3f68bc2e 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -604,8 +604,6 @@ macro_rules! test_lanes { use super::*; fn implementation() - where - core_simd::simd::LaneCount<$lanes>: core_simd::simd::SupportedLaneCount, $body #[cfg(target_arch = "wasm32")] @@ -704,8 +702,6 @@ macro_rules! test_lanes_panic { use super::*; fn implementation() - where - core_simd::simd::LaneCount<$lanes>: core_simd::simd::SupportedLaneCount, $body // test some odd and even non-power-of-2 lengths on miri diff --git a/rust-toolchain.toml b/rust-toolchain.toml index df4bd75ecfe2..ed4d7e8a801e 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-08-17" +channel = "nightly-2025-09-30" components = ["rustfmt", "clippy", "miri", "rust-src"] From 7b88f48b530f6610581a0d023199c9563e635730 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:35:02 -0400 Subject: [PATCH 0041/3801] Avoid scalar fallback in chunk remainder check Refactor the eq check into an inner function for reuse in tail checking Rather than fall back to the simple implementation for tail handling, load the last 16 bytes to take advantage of vectorization. This doesn't seem to negatively impact check time even when the remainder count is low. --- library/core/src/slice/ascii.rs | 35 +++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 1f9ca4bc6698..3f3f5a8c441d 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -90,8 +90,8 @@ impl [u8] { true } - /// Optimized version of `eq_ignore_ascii_case` which processes chunks at a - /// time. + /// Optimized version of `eq_ignore_ascii_case` for byte lengths of at least + /// 16 bytes, which processes chunks at a time. /// /// Platforms that have SIMD instructions may benefit from this /// implementation over `eq_ignore_ascii_case_simple`. @@ -99,26 +99,41 @@ impl [u8] { #[inline] const fn eq_ignore_ascii_case_chunks(&self, other: &[u8]) -> bool { const N: usize = 16; - let (a, a_rem) = self.as_chunks::(); - let (b, b_rem) = other.as_chunks::(); + let (self_chunks, self_rem) = self.as_chunks::(); + let (other_chunks, _) = other.as_chunks::(); - let mut i = 0; - while i < a.len() && i < b.len() { + // Branchless check to encourage auto-vectorization + const fn eq_ignore_ascii_inner(lhs: &[u8; N], rhs: &[u8; N]) -> bool { let mut equal_ascii = true; let mut j = 0; while j < N { - equal_ascii &= a[i][j].eq_ignore_ascii_case(&b[i][j]); + equal_ascii &= lhs[j].eq_ignore_ascii_case(&rhs[j]); j += 1; } - if !equal_ascii { + equal_ascii + } + + // Process the chunks, returning early if an inequality is found + let mut i = 0; + while i < self_chunks.len() && i < other_chunks.len() { + if !eq_ignore_ascii_inner(&self_chunks[i], &other_chunks[i]) { return false; } - i += 1; } - a_rem.eq_ignore_ascii_case_simple(b_rem) + // If there are remaining tails, load the last N bytes in the slices to + // avoid falling back to per-byte checking. + if !self_rem.is_empty() { + if let (Some(a_rem), Some(b_rem)) = (self.last_chunk::(), other.last_chunk::()) { + if !eq_ignore_ascii_inner(a_rem, b_rem) { + return false; + } + } + } + + true } /// Converts this slice to its ASCII upper case equivalent in-place. From a5ba24843d6e4ceda580e49344bef73baec14204 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Tue, 7 Oct 2025 19:04:32 -0400 Subject: [PATCH 0042/3801] Relocate bench and use str corpora for data Add #[inline(always)] to inner function and check not for filecheck test --- library/core/src/slice/ascii.rs | 1 + library/coretests/benches/ascii.rs | 1 - .../benches/ascii/eq_ignore_ascii_case.rs | 56 ------------------- library/coretests/benches/str.rs | 1 + .../benches/str/eq_ignore_ascii_case.rs | 45 +++++++++++++++ .../lib-optimizations/eq_ignore_ascii_case.rs | 4 +- 6 files changed, 50 insertions(+), 58 deletions(-) delete mode 100644 library/coretests/benches/ascii/eq_ignore_ascii_case.rs create mode 100644 library/coretests/benches/str/eq_ignore_ascii_case.rs diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 3f3f5a8c441d..8b713947cd9c 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -103,6 +103,7 @@ impl [u8] { let (other_chunks, _) = other.as_chunks::(); // Branchless check to encourage auto-vectorization + #[inline(always)] const fn eq_ignore_ascii_inner(lhs: &[u8; N], rhs: &[u8; N]) -> bool { let mut equal_ascii = true; let mut j = 0; diff --git a/library/coretests/benches/ascii.rs b/library/coretests/benches/ascii.rs index 17a520922bfa..64bdc7fed118 100644 --- a/library/coretests/benches/ascii.rs +++ b/library/coretests/benches/ascii.rs @@ -1,4 +1,3 @@ -mod eq_ignore_ascii_case; mod is_ascii; // Lower-case ASCII 'a' is the first byte that has its highest bit set diff --git a/library/coretests/benches/ascii/eq_ignore_ascii_case.rs b/library/coretests/benches/ascii/eq_ignore_ascii_case.rs deleted file mode 100644 index a51acb1e8463..000000000000 --- a/library/coretests/benches/ascii/eq_ignore_ascii_case.rs +++ /dev/null @@ -1,56 +0,0 @@ -use test::Bencher; - -#[bench] -fn bench_str_under_8_bytes_eq(b: &mut Bencher) { - let s = "foo"; - let other = "FOo"; - b.iter(|| { - assert!(s.eq_ignore_ascii_case(other)); - }) -} - -#[bench] -fn bench_str_of_8_bytes_eq(b: &mut Bencher) { - let s = "foobar78"; - let other = "FOObAr78"; - b.iter(|| { - assert!(s.eq_ignore_ascii_case(other)); - }) -} - -#[bench] -fn bench_str_17_bytes_eq(b: &mut Bencher) { - let s = "performance-criti"; - let other = "performANce-cRIti"; - b.iter(|| { - assert!(s.eq_ignore_ascii_case(other)); - }) -} - -#[bench] -fn bench_str_31_bytes_eq(b: &mut Bencher) { - let s = "foobarbazquux02foobarbazquux025"; - let other = "fooBARbazQuuX02fooBARbazQuuX025"; - b.iter(|| { - assert!(s.eq_ignore_ascii_case(other)); - }) -} - -#[bench] -fn bench_long_str_eq(b: &mut Bencher) { - let s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \ - incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \ - exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \ - irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \ - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \ - officia deserunt mollit anim id est laborum."; - let other = "Lorem ipsum dolor sit amet, CONSECTETUR adipisicing elit, sed do eiusmod tempor \ - incididunt ut labore et dolore MAGNA aliqua. Ut enim ad MINIM veniam, quis nostrud \ - exercitation ullamco LABORIS nisi ut aliquip ex ea commodo consequat. Duis aute \ - irure dolor in reprehenderit in voluptate velit esse cillum DOLORE eu fugiat nulla \ - pariatur. Excepteur sint occaecat CUPIDATAT non proident, sunt in culpa qui \ - officia deserunt mollit anim id est laborum."; - b.iter(|| { - assert!(s.eq_ignore_ascii_case(other)); - }) -} diff --git a/library/coretests/benches/str.rs b/library/coretests/benches/str.rs index 2f7d9d56a70b..bf45a8f0a79b 100644 --- a/library/coretests/benches/str.rs +++ b/library/coretests/benches/str.rs @@ -5,6 +5,7 @@ use test::{Bencher, black_box}; mod char_count; mod corpora; mod debug; +mod eq_ignore_ascii_case; mod iter; #[bench] diff --git a/library/coretests/benches/str/eq_ignore_ascii_case.rs b/library/coretests/benches/str/eq_ignore_ascii_case.rs new file mode 100644 index 000000000000..29129b933bc4 --- /dev/null +++ b/library/coretests/benches/str/eq_ignore_ascii_case.rs @@ -0,0 +1,45 @@ +use test::{Bencher, black_box}; + +use super::corpora::*; + +#[bench] +fn bench_str_under_8_bytes_eq(b: &mut Bencher) { + let s = black_box("foo"); + let other = black_box("foo"); + b.iter(|| assert!(s.eq_ignore_ascii_case(other))) +} + +#[bench] +fn bench_str_of_8_bytes_eq(b: &mut Bencher) { + let s = black_box(en::TINY); + let other = black_box(en::TINY); + b.iter(|| assert!(s.eq_ignore_ascii_case(other))) +} + +#[bench] +fn bench_str_17_bytes_eq(b: &mut Bencher) { + let s = black_box(&en::SMALL[..17]); + let other = black_box(&en::SMALL[..17]); + b.iter(|| assert!(s.eq_ignore_ascii_case(other))) +} + +#[bench] +fn bench_str_31_bytes_eq(b: &mut Bencher) { + let s = black_box(&en::SMALL[..31]); + let other = black_box(&en::SMALL[..31]); + b.iter(|| assert!(s.eq_ignore_ascii_case(other))) +} + +#[bench] +fn bench_medium_str_eq(b: &mut Bencher) { + let s = black_box(en::MEDIUM); + let other = black_box(en::MEDIUM); + b.iter(|| assert!(s.eq_ignore_ascii_case(other))) +} + +#[bench] +fn bench_large_str_eq(b: &mut Bencher) { + let s = black_box(en::LARGE); + let other = black_box(en::LARGE); + b.iter(|| assert!(s.eq_ignore_ascii_case(other))) +} diff --git a/tests/codegen-llvm/lib-optimizations/eq_ignore_ascii_case.rs b/tests/codegen-llvm/lib-optimizations/eq_ignore_ascii_case.rs index b733f1812c92..d4ac5d64585d 100644 --- a/tests/codegen-llvm/lib-optimizations/eq_ignore_ascii_case.rs +++ b/tests/codegen-llvm/lib-optimizations/eq_ignore_ascii_case.rs @@ -2,13 +2,15 @@ //@ only-x86_64 #![crate_type = "lib"] -// Ensure that the optimized variant of the function gets auto-vectorized. +// Ensure that the optimized variant of the function gets auto-vectorized and +// that the inner helper function is inlined. // CHECK-LABEL: @eq_ignore_ascii_case_autovectorized #[no_mangle] pub fn eq_ignore_ascii_case_autovectorized(s: &str, other: &str) -> bool { // CHECK: load <16 x i8> // CHECK: load <16 x i8> // CHECK: bitcast <16 x i1> + // CHECK-NOT: call {{.*}}eq_ignore_ascii_inner // CHECK-NOT: panic s.eq_ignore_ascii_case(other) } From 6a709e7195b819c2baef9cba2c889d5408346b48 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 11 Oct 2025 18:52:58 +0800 Subject: [PATCH 0043/3801] Suppress the error for private fields with non_exhaustive attribute --- compiler/rustc_hir_typeck/src/expr.rs | 6 ++++- .../auxiliary/non_exhaustive_with_private.rs | 13 +++++++++++ ...n-exhaustive-with-private-fields-147513.rs | 17 ++++++++++++++ ...haustive-with-private-fields-147513.stderr | 23 +++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs create mode 100644 tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs create mode 100644 tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 1aaf02646c79..9aaf34a0fd1c 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2331,7 +2331,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys); - } else if adt_kind != AdtKind::Union && !remaining_fields.is_empty() { + } else if adt_kind != AdtKind::Union + && !remaining_fields.is_empty() + //~ non_exhaustive already reported, which will only happen for extern modules + && !variant.field_list_has_applicable_non_exhaustive() + { debug!(?remaining_fields); let private_fields: Vec<&ty::FieldDef> = variant .fields diff --git a/tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs b/tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs new file mode 100644 index 000000000000..18e63db0cdd1 --- /dev/null +++ b/tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs @@ -0,0 +1,13 @@ +// Auxiliary crate for testing non-exhaustive struct with private fields + +#[non_exhaustive] +pub struct Foo { + pub my_field: u32, + private_field: i32, +} + +#[non_exhaustive] +pub struct Bar { + pub my_field: u32, + pub missing_field: i32, +} diff --git a/tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs new file mode 100644 index 000000000000..0553ff6c781e --- /dev/null +++ b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs @@ -0,0 +1,17 @@ +//@ aux-build:non_exhaustive_with_private.rs + +extern crate non_exhaustive_with_private; + +use non_exhaustive_with_private::{Bar, Foo}; + +fn main() { + let foo = Foo { + //~^ ERROR cannot create non-exhaustive struct using struct expression + my_field: 10, + }; + + let bar = Bar { + //~^ ERROR cannot create non-exhaustive struct using struct expression + my_field: 10, + }; +} diff --git a/tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr new file mode 100644 index 000000000000..85bf7e4847d7 --- /dev/null +++ b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr @@ -0,0 +1,23 @@ +error[E0639]: cannot create non-exhaustive struct using struct expression + --> $DIR/non-exhaustive-with-private-fields-147513.rs:8:15 + | +LL | let foo = Foo { + | _______________^ +LL | | +LL | | my_field: 10, +LL | | }; + | |_____^ + +error[E0639]: cannot create non-exhaustive struct using struct expression + --> $DIR/non-exhaustive-with-private-fields-147513.rs:13:15 + | +LL | let bar = Bar { + | _______________^ +LL | | +LL | | my_field: 10, +LL | | }; + | |_____^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0639`. From e4194c7075ae35d45bdec1b779a2b57c400af60b Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 12 Oct 2025 16:51:28 +0900 Subject: [PATCH 0044/3801] Deduplicate higher-ranked lifetime capture errors in impl Trait Previously, when an `impl Trait` captured multiple higher-ranked lifetimes from an outer `impl Trait`, the compiler would emit a separate error for each captured lifetime. This resulted in verbose and confusing diagnostics, especially in edition 2024 where implicit captures caused duplicate errors. This commit introduces error accumulation that collects all capture spans and lifetime declaration spans, then emits a single consolidated diagnostic using MultiSpan. The new error shows all captured lifetimes with visual indicators and lists all declarations in a single note. --- .../src/collect/resolve_bound_vars.rs | 69 ++++++++++++++++--- compiler/rustc_hir_analysis/src/errors.rs | 4 +- tests/ui/error-codes/E0657.stderr | 8 +-- ...e-capture-deduplication.edition2015.stderr | 17 +++++ ...e-capture-deduplication.edition2024.stderr | 17 +++++ ...r-ranked-lifetime-capture-deduplication.rs | 26 +++++++ .../ui/impl-trait/impl-fn-hrtb-bounds.stderr | 18 +++-- .../impl-fn-parsing-ambiguities.stderr | 6 +- .../issues/issue-54895.edition2015.stderr | 6 +- .../issues/issue-54895.edition2024.stderr | 18 ++--- tests/ui/impl-trait/issues/issue-54895.rs | 1 - tests/ui/impl-trait/issues/issue-67830.stderr | 6 +- .../ui/impl-trait/issues/issue-88236-2.stderr | 18 +++-- tests/ui/impl-trait/issues/issue-88236.stderr | 6 +- tests/ui/impl-trait/nested-rpit-hrtb.stderr | 20 +++--- .../bound-lifetime-through-dyn-trait.stderr | 4 +- .../escaping-bound-var.rs | 1 - .../escaping-bound-var.stderr | 16 +---- 18 files changed, 185 insertions(+), 76 deletions(-) create mode 100644 tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2015.stderr create mode 100644 tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2024.stderr create mode 100644 tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.rs 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 8133f9f68234..6f7ce916c7ac 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -66,6 +66,13 @@ struct BoundVarContext<'a, 'tcx> { rbv: &'a mut ResolveBoundVars, disambiguator: &'a mut DisambiguatorState, scope: ScopeRef<'a>, + opaque_capture_errors: RefCell>, +} + +struct OpaqueHigherRankedLifetimeCaptureErrors { + bad_place: &'static str, + capture_spans: Vec, + decl_spans: Vec, } #[derive(Debug)] @@ -253,6 +260,7 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None }, disambiguator: &mut DisambiguatorState::new(), + opaque_capture_errors: RefCell::new(None), }; match tcx.hir_owner_node(local_def_id) { hir::OwnerNode::Item(item) => visitor.visit_item(item), @@ -597,6 +605,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { }) }); + self.emit_opaque_capture_errors(); + let captures = captures.into_inner().into_iter().collect(); debug!(?captures); self.rbv.opaque_captured_lifetimes.insert(opaque.def_id, captures); @@ -1089,12 +1099,20 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>), { let BoundVarContext { tcx, rbv, disambiguator, .. } = self; - let mut this = BoundVarContext { tcx: *tcx, rbv, disambiguator, scope: &wrap_scope }; + let nested_errors = RefCell::new(self.opaque_capture_errors.borrow_mut().take()); + let mut this = BoundVarContext { + tcx: *tcx, + rbv, + disambiguator, + scope: &wrap_scope, + opaque_capture_errors: nested_errors, + }; let span = debug_span!("scope", scope = ?this.scope.debug_truncated()); { let _enter = span.enter(); f(&mut this); } + *self.opaque_capture_errors.borrow_mut() = this.opaque_capture_errors.into_inner(); } fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec) { @@ -1424,21 +1442,52 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { }; let decl_span = self.tcx.def_span(lifetime_def_id); - let (span, label) = if capture_span != decl_span { - (capture_span, None) - } else { - let opaque_span = self.tcx.def_span(opaque_def_id); - (opaque_span, Some(opaque_span)) - }; + let opaque_span = self.tcx.def_span(opaque_def_id); + + let mut errors = self.opaque_capture_errors.borrow_mut(); + let error_info = errors.get_or_insert_with(|| OpaqueHigherRankedLifetimeCaptureErrors { + bad_place, + capture_spans: Vec::new(), + decl_spans: Vec::new(), + }); + + if error_info.capture_spans.is_empty() { + error_info.capture_spans.push(opaque_span); + } + + if capture_span != decl_span && capture_span != opaque_span { + error_info.capture_spans.push(capture_span); + } + + if !error_info.decl_spans.contains(&decl_span) { + error_info.decl_spans.push(decl_span); + } + + // Errors should be emitted by `emit_opaque_capture_errors`. + Err(self.tcx.dcx().span_delayed_bug(capture_span, "opaque capture error not emitted")) + } + + fn emit_opaque_capture_errors(&self) -> Option { + let errors = self.opaque_capture_errors.borrow_mut().take()?; + if errors.capture_spans.is_empty() { + return None; + } + + let mut span = rustc_errors::MultiSpan::from_span(errors.capture_spans[0]); + for &capture_span in &errors.capture_spans[1..] { + span.push_span_label(capture_span, ""); + } + let decl_span = rustc_errors::MultiSpan::from_spans(errors.decl_spans); // Ensure that the parent of the def is an item, not HRTB let guar = self.tcx.dcx().emit_err(errors::OpaqueCapturesHigherRankedLifetime { span, - label, + label: Some(errors.capture_spans[0]), decl_span, - bad_place, + bad_place: errors.bad_place, }); - Err(guar) + + Some(guar) } #[instrument(level = "trace", skip(self, opaque_capture_scopes), ret)] diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 49c510642288..c0cb6f732799 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1562,11 +1562,11 @@ pub(crate) struct UnconstrainedGenericParameter { #[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)] pub(crate) struct OpaqueCapturesHigherRankedLifetime { #[primary_span] - pub span: Span, + pub span: MultiSpan, #[label] pub label: Option, #[note] - pub decl_span: Span, + pub decl_span: MultiSpan, pub bad_place: &'static str, } diff --git a/tests/ui/error-codes/E0657.stderr b/tests/ui/error-codes/E0657.stderr index c9dfc9eb9069..1d69af5d9654 100644 --- a/tests/ui/error-codes/E0657.stderr +++ b/tests/ui/error-codes/E0657.stderr @@ -1,8 +1,8 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/E0657.rs:10:35 + --> $DIR/E0657.rs:10:27 | LL | -> Box Id>> - | ^^ + | ^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/E0657.rs:10:20 @@ -11,10 +11,10 @@ LL | -> Box Id>> | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/E0657.rs:19:39 + --> $DIR/E0657.rs:19:31 | LL | -> Box Id>> - | ^^ + | ^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/E0657.rs:19:24 diff --git a/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2015.stderr b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2015.stderr new file mode 100644 index 000000000000..8954a802ab95 --- /dev/null +++ b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2015.stderr @@ -0,0 +1,17 @@ +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` + --> $DIR/higher-ranked-lifetime-capture-deduplication.rs:19:44 + | +LL | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + | ^^^^^^^^^^^^^--^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope + | +note: lifetime declared here + --> $DIR/higher-ranked-lifetime-capture-deduplication.rs:19:20 + | +LL | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + | ^^ ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2024.stderr b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2024.stderr new file mode 100644 index 000000000000..8954a802ab95 --- /dev/null +++ b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2024.stderr @@ -0,0 +1,17 @@ +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` + --> $DIR/higher-ranked-lifetime-capture-deduplication.rs:19:44 + | +LL | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + | ^^^^^^^^^^^^^--^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope + | +note: lifetime declared here + --> $DIR/higher-ranked-lifetime-capture-deduplication.rs:19:20 + | +LL | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + | ^^ ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.rs b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.rs new file mode 100644 index 000000000000..d8da93e5560d --- /dev/null +++ b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.rs @@ -0,0 +1,26 @@ +//@revisions: edition2015 edition2024 +//@[edition2015] edition:2015 +//@[edition2024] edition:2024 + +trait Trait<'a> { + type Out; + fn call(&'a self) -> Self::Out; +} + +struct X(()); + +impl<'a> Trait<'a> for X { + type Out = (); + fn call(&'a self) -> Self::Out { + () + } +} + +fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` + X(()) +} + +fn main() { + let _ = f(); +} diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr index 40cb6b647d1e..36f52e8103a3 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr @@ -12,10 +12,12 @@ LL + fn d() -> impl Fn() -> (impl Debug + 'static) { | error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-hrtb-bounds.rs:4:41 + --> $DIR/impl-fn-hrtb-bounds.rs:4:28 | LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/impl-fn-hrtb-bounds.rs:4:19 @@ -24,10 +26,12 @@ LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) { | ^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-hrtb-bounds.rs:9:52 + --> $DIR/impl-fn-hrtb-bounds.rs:9:39 | LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/impl-fn-hrtb-bounds.rs:9:20 @@ -36,10 +40,12 @@ LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-hrtb-bounds.rs:14:52 + --> $DIR/impl-fn-hrtb-bounds.rs:14:39 | LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/impl-fn-hrtb-bounds.rs:14:20 diff --git a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr index 94b6ffdd9123..5ba9567e14e3 100644 --- a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr +++ b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr @@ -21,10 +21,12 @@ LL | fn b() -> impl Fn() -> (impl Debug + Send) { | + + error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-parsing-ambiguities.rs:4:40 + --> $DIR/impl-fn-parsing-ambiguities.rs:4:27 | LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/impl-fn-parsing-ambiguities.rs:4:19 diff --git a/tests/ui/impl-trait/issues/issue-54895.edition2015.stderr b/tests/ui/impl-trait/issues/issue-54895.edition2015.stderr index 27a3c6c8b7ce..8348a1d5e87b 100644 --- a/tests/ui/impl-trait/issues/issue-54895.edition2015.stderr +++ b/tests/ui/impl-trait/issues/issue-54895.edition2015.stderr @@ -1,8 +1,10 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-54895.rs:18:53 + --> $DIR/issue-54895.rs:18:40 | LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-54895.rs:18:20 diff --git a/tests/ui/impl-trait/issues/issue-54895.edition2024.stderr b/tests/ui/impl-trait/issues/issue-54895.edition2024.stderr index 54aa29e62d88..8348a1d5e87b 100644 --- a/tests/ui/impl-trait/issues/issue-54895.edition2024.stderr +++ b/tests/ui/impl-trait/issues/issue-54895.edition2024.stderr @@ -2,7 +2,9 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `imp --> $DIR/issue-54895.rs:18:40 | LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { - | ^^^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-54895.rs:18:20 @@ -10,18 +12,6 @@ note: lifetime declared here LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { | ^^ -error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-54895.rs:18:53 - | -LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { - | ^^ - | -note: lifetime declared here - --> $DIR/issue-54895.rs:18:20 - | -LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { - | ^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/issues/issue-54895.rs b/tests/ui/impl-trait/issues/issue-54895.rs index bc1841209e17..ccdb0ce20f9a 100644 --- a/tests/ui/impl-trait/issues/issue-54895.rs +++ b/tests/ui/impl-trait/issues/issue-54895.rs @@ -17,7 +17,6 @@ impl<'a> Trait<'a> for X { fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - //[edition2024]~^^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` X(()) } diff --git a/tests/ui/impl-trait/issues/issue-67830.stderr b/tests/ui/impl-trait/issues/issue-67830.stderr index a7633c7f20b6..7254955ed0bd 100644 --- a/tests/ui/impl-trait/issues/issue-67830.stderr +++ b/tests/ui/impl-trait/issues/issue-67830.stderr @@ -1,8 +1,10 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-67830.rs:20:64 + --> $DIR/issue-67830.rs:20:48 | LL | fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> { - | ^^ + | ^^^^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-67830.rs:20:23 diff --git a/tests/ui/impl-trait/issues/issue-88236-2.stderr b/tests/ui/impl-trait/issues/issue-88236-2.stderr index 4ded9ed386fa..3943c4121845 100644 --- a/tests/ui/impl-trait/issues/issue-88236-2.stderr +++ b/tests/ui/impl-trait/issues/issue-88236-2.stderr @@ -1,8 +1,10 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236-2.rs:15:61 + --> $DIR/issue-88236-2.rs:15:49 | LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} - | ^^ + | ^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-88236-2.rs:15:28 @@ -11,10 +13,12 @@ LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236-2.rs:18:80 + --> $DIR/issue-88236-2.rs:18:68 | LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - | ^^ + | ^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-88236-2.rs:18:47 @@ -23,10 +27,12 @@ LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Sen | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236-2.rs:23:78 + --> $DIR/issue-88236-2.rs:23:66 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - | ^^ + | ^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-88236-2.rs:23:45 diff --git a/tests/ui/impl-trait/issues/issue-88236.stderr b/tests/ui/impl-trait/issues/issue-88236.stderr index 5dee5f88c89f..6303379288b7 100644 --- a/tests/ui/impl-trait/issues/issue-88236.stderr +++ b/tests/ui/impl-trait/issues/issue-88236.stderr @@ -1,8 +1,10 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236.rs:15:61 + --> $DIR/issue-88236.rs:15:49 | LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} - | ^^ + | ^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-88236.rs:15:28 diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index 93cd7bd788f4..130723035b1a 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -30,10 +30,12 @@ LL | fn two_htrb_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl for<'b | ++++ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:25:69 + --> $DIR/nested-rpit-hrtb.rs:25:56 | LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {} - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/nested-rpit-hrtb.rs:25:36 @@ -42,10 +44,10 @@ LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {} | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:29:68 + --> $DIR/nested-rpit-hrtb.rs:29:59 | LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} - | ^^ + | ^^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/nested-rpit-hrtb.rs:29:39 @@ -54,10 +56,12 @@ LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:32:74 + --> $DIR/nested-rpit-hrtb.rs:32:61 | LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/nested-rpit-hrtb.rs:32:41 @@ -66,10 +70,10 @@ LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:35:73 + --> $DIR/nested-rpit-hrtb.rs:35:64 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} - | ^^ + | ^^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/nested-rpit-hrtb.rs:35:44 diff --git a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr index 7219fda4772a..6f0c6bb22060 100644 --- a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr +++ b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr @@ -1,8 +1,8 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/bound-lifetime-through-dyn-trait.rs:6:71 + --> $DIR/bound-lifetime-through-dyn-trait.rs:6:57 | LL | fn dyn_hoops() -> dyn for<'a> Iterator> { - | ^^ + | ^^^^^^^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/bound-lifetime-through-dyn-trait.rs:6:37 diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs index 31bdd0815ec3..4b17448080ed 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -8,7 +8,6 @@ trait Test<'a> {} pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` -//~| ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` impl Trait<'_> for () { type Assoc = (); diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr index c9f0618639af..cdbcfa6f3dc9 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr @@ -2,7 +2,7 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `imp --> $DIR/escaping-bound-var.rs:9:47 | LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; - | ^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope + | ^^^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/escaping-bound-var.rs:9:25 @@ -10,18 +10,6 @@ note: lifetime declared here LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; | ^^ -error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/escaping-bound-var.rs:9:57 - | -LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; - | ^^ - | -note: lifetime declared here - --> $DIR/escaping-bound-var.rs:9:25 - | -LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; - | ^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0657`. From 1566879798185efdcfba62d2944a2e60dc10d814 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Mon, 13 Oct 2025 19:53:57 +0200 Subject: [PATCH 0045/3801] clean-up - update file name to match lint name - use `Symbol`s instead of `&str`s - get rid of needless lifetimes --- ...alls.rs => collapsible_span_lint_calls.rs} | 47 +++++++++---------- clippy_lints_internal/src/lib.rs | 6 +-- clippy_utils/src/sym.rs | 4 ++ 3 files changed, 29 insertions(+), 28 deletions(-) rename clippy_lints_internal/src/{collapsible_calls.rs => collapsible_span_lint_calls.rs} (88%) diff --git a/clippy_lints_internal/src/collapsible_calls.rs b/clippy_lints_internal/src/collapsible_span_lint_calls.rs similarity index 88% rename from clippy_lints_internal/src/collapsible_calls.rs rename to clippy_lints_internal/src/collapsible_span_lint_calls.rs index 7c9e7286925e..e83508f6ff4a 100644 --- a/clippy_lints_internal/src/collapsible_calls.rs +++ b/clippy_lints_internal/src/collapsible_span_lint_calls.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; -use clippy_utils::{SpanlessEq, is_lint_allowed, peel_blocks_with_stmt}; +use clippy_utils::{SpanlessEq, is_lint_allowed, peel_blocks_with_stmt, sym}; use rustc_errors::Applicability; use rustc_hir::{Closure, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -91,8 +91,8 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls { let and_then_snippets = get_and_then_snippets(cx, call_cx.span, call_lint.span, call_sp.span, call_msg.span); let mut sle = SpanlessEq::new(cx).deny_side_effects(); - match ps.ident.as_str() { - "span_suggestion" if sle.eq_expr(call_sp, &span_call_args[0]) => { + match ps.ident.name { + sym::span_suggestion if sle.eq_expr(call_sp, &span_call_args[0]) => { suggest_suggestion( cx, expr, @@ -100,19 +100,19 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls { &span_suggestion_snippets(cx, span_call_args), ); }, - "span_help" if sle.eq_expr(call_sp, &span_call_args[0]) => { + sym::span_help if sle.eq_expr(call_sp, &span_call_args[0]) => { let help_snippet = snippet(cx, span_call_args[1].span, r#""...""#); suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), true); }, - "span_note" if sle.eq_expr(call_sp, &span_call_args[0]) => { + sym::span_note if sle.eq_expr(call_sp, &span_call_args[0]) => { let note_snippet = snippet(cx, span_call_args[1].span, r#""...""#); suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), true); }, - "help" => { + sym::help => { let help_snippet = snippet(cx, span_call_args[0].span, r#""...""#); suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), false); }, - "note" => { + sym::note => { let note_snippet = snippet(cx, span_call_args[0].span, r#""...""#); suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), false); }, @@ -122,11 +122,11 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls { } } -struct AndThenSnippets<'a> { - cx: Cow<'a, str>, - lint: Cow<'a, str>, - span: Cow<'a, str>, - msg: Cow<'a, str>, +struct AndThenSnippets { + cx: Cow<'static, str>, + lint: Cow<'static, str>, + span: Cow<'static, str>, + msg: Cow<'static, str>, } fn get_and_then_snippets( @@ -135,7 +135,7 @@ fn get_and_then_snippets( lint_span: Span, span_span: Span, msg_span: Span, -) -> AndThenSnippets<'static> { +) -> AndThenSnippets { let cx_snippet = snippet(cx, cx_span, "cx"); let lint_snippet = snippet(cx, lint_span, ".."); let span_snippet = snippet(cx, span_span, "span"); @@ -149,16 +149,13 @@ fn get_and_then_snippets( } } -struct SpanSuggestionSnippets<'a> { - help: Cow<'a, str>, - sugg: Cow<'a, str>, - applicability: Cow<'a, str>, +struct SpanSuggestionSnippets { + help: Cow<'static, str>, + sugg: Cow<'static, str>, + applicability: Cow<'static, str>, } -fn span_suggestion_snippets<'a, 'hir>( - cx: &LateContext<'_>, - span_call_args: &'hir [Expr<'hir>], -) -> SpanSuggestionSnippets<'a> { +fn span_suggestion_snippets<'hir>(cx: &LateContext<'_>, span_call_args: &'hir [Expr<'hir>]) -> SpanSuggestionSnippets { let help_snippet = snippet(cx, span_call_args[1].span, r#""...""#); let sugg_snippet = snippet(cx, span_call_args[2].span, ".."); let applicability_snippet = snippet(cx, span_call_args[3].span, "Applicability::MachineApplicable"); @@ -173,8 +170,8 @@ fn span_suggestion_snippets<'a, 'hir>( fn suggest_suggestion( cx: &LateContext<'_>, expr: &Expr<'_>, - and_then_snippets: &AndThenSnippets<'_>, - span_suggestion_snippets: &SpanSuggestionSnippets<'_>, + and_then_snippets: &AndThenSnippets, + span_suggestion_snippets: &SpanSuggestionSnippets, ) { span_lint_and_sugg( cx, @@ -199,7 +196,7 @@ fn suggest_suggestion( fn suggest_help( cx: &LateContext<'_>, expr: &Expr<'_>, - and_then_snippets: &AndThenSnippets<'_>, + and_then_snippets: &AndThenSnippets, help: &str, with_span: bool, ) { @@ -226,7 +223,7 @@ fn suggest_help( fn suggest_note( cx: &LateContext<'_>, expr: &Expr<'_>, - and_then_snippets: &AndThenSnippets<'_>, + and_then_snippets: &AndThenSnippets, note: &str, with_span: bool, ) { diff --git a/clippy_lints_internal/src/lib.rs b/clippy_lints_internal/src/lib.rs index 43cde86504f5..2fc172f64725 100644 --- a/clippy_lints_internal/src/lib.rs +++ b/clippy_lints_internal/src/lib.rs @@ -31,7 +31,7 @@ extern crate rustc_session; extern crate rustc_span; mod almost_standard_lint_formulation; -mod collapsible_calls; +mod collapsible_span_lint_calls; mod derive_deserialize_allowing_unknown; mod internal_paths; mod lint_without_lint_pass; @@ -46,7 +46,7 @@ use rustc_lint::{Lint, LintStore}; static LINTS: &[&Lint] = &[ almost_standard_lint_formulation::ALMOST_STANDARD_LINT_FORMULATION, - collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS, + collapsible_span_lint_calls::COLLAPSIBLE_SPAN_LINT_CALLS, derive_deserialize_allowing_unknown::DERIVE_DESERIALIZE_ALLOWING_UNKNOWN, lint_without_lint_pass::DEFAULT_LINT, lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE, @@ -66,7 +66,7 @@ pub fn register_lints(store: &mut LintStore) { store.register_early_pass(|| Box::new(unsorted_clippy_utils_paths::UnsortedClippyUtilsPaths)); store.register_early_pass(|| Box::new(produce_ice::ProduceIce)); - store.register_late_pass(|_| Box::new(collapsible_calls::CollapsibleCalls)); + store.register_late_pass(|_| Box::new(collapsible_span_lint_calls::CollapsibleCalls)); store.register_late_pass(|_| Box::new(derive_deserialize_allowing_unknown::DeriveDeserializeAllowingUnknown)); store.register_late_pass(|_| Box::::default()); store.register_late_pass(|_| Box::::default()); diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 2b22f344e8c0..e3d733cada71 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -173,6 +173,7 @@ generate! { get_unchecked, get_unchecked_mut, has_significant_drop, + help, hidden_glob_reexports, hygiene, insert, @@ -310,7 +311,10 @@ generate! { sort, sort_by, sort_unstable_by, + span_help, span_lint_and_then, + span_note, + span_suggestion, split, split_at, split_at_checked, From 4d795229058b568570cf68a1320cd5bd95eab377 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Mon, 13 Oct 2025 19:32:34 +0200 Subject: [PATCH 0046/3801] fix: use `snippet_with_context` for spans that are likely to contain macro expns --- .../src/collapsible_span_lint_calls.rs | 69 ++++++++++++------- .../collapsible_span_lint_calls.fixed | 9 +++ .../collapsible_span_lint_calls.rs | 29 ++++++++ .../collapsible_span_lint_calls.stderr | 50 +++++++++++++- 4 files changed, 131 insertions(+), 26 deletions(-) diff --git a/clippy_lints_internal/src/collapsible_span_lint_calls.rs b/clippy_lints_internal/src/collapsible_span_lint_calls.rs index e83508f6ff4a..f7adb782929c 100644 --- a/clippy_lints_internal/src/collapsible_span_lint_calls.rs +++ b/clippy_lints_internal/src/collapsible_span_lint_calls.rs @@ -1,11 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet; +use clippy_utils::source::{snippet, snippet_with_context}; use clippy_utils::{SpanlessEq, is_lint_allowed, peel_blocks_with_stmt, sym}; use rustc_errors::Applicability; use rustc_hir::{Closure, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::Span; +use rustc_span::{Span, SyntaxContext}; use std::borrow::{Borrow, Cow}; @@ -88,33 +88,42 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls { && let ExprKind::MethodCall(ps, recv, span_call_args, _) = &only_expr.kind && let ExprKind::Path(..) = recv.kind { - let and_then_snippets = - get_and_then_snippets(cx, call_cx.span, call_lint.span, call_sp.span, call_msg.span); + let mut app = Applicability::MachineApplicable; + let expr_ctxt = expr.span.ctxt(); + let and_then_snippets = get_and_then_snippets( + cx, + expr_ctxt, + call_cx.span, + call_lint.span, + call_sp.span, + call_msg.span, + &mut app, + ); let mut sle = SpanlessEq::new(cx).deny_side_effects(); match ps.ident.name { sym::span_suggestion if sle.eq_expr(call_sp, &span_call_args[0]) => { - suggest_suggestion( - cx, - expr, - &and_then_snippets, - &span_suggestion_snippets(cx, span_call_args), - ); + let snippets = span_suggestion_snippets(cx, expr_ctxt, span_call_args, &mut app); + suggest_suggestion(cx, expr, &and_then_snippets, &snippets, app); }, sym::span_help if sle.eq_expr(call_sp, &span_call_args[0]) => { - let help_snippet = snippet(cx, span_call_args[1].span, r#""...""#); - suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), true); + let help_snippet = + snippet_with_context(cx, span_call_args[1].span, expr_ctxt, r#""...""#, &mut app).0; + suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), true, app); }, sym::span_note if sle.eq_expr(call_sp, &span_call_args[0]) => { - let note_snippet = snippet(cx, span_call_args[1].span, r#""...""#); - suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), true); + let note_snippet = + snippet_with_context(cx, span_call_args[1].span, expr_ctxt, r#""...""#, &mut app).0; + suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), true, app); }, sym::help => { - let help_snippet = snippet(cx, span_call_args[0].span, r#""...""#); - suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), false); + let help_snippet = + snippet_with_context(cx, span_call_args[0].span, expr_ctxt, r#""...""#, &mut app).0; + suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), false, app); }, sym::note => { - let note_snippet = snippet(cx, span_call_args[0].span, r#""...""#); - suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), false); + let note_snippet = + snippet_with_context(cx, span_call_args[0].span, expr_ctxt, r#""...""#, &mut app).0; + suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), false, app); }, _ => (), } @@ -131,15 +140,17 @@ struct AndThenSnippets { fn get_and_then_snippets( cx: &LateContext<'_>, + expr_ctxt: SyntaxContext, cx_span: Span, lint_span: Span, span_span: Span, msg_span: Span, + app: &mut Applicability, ) -> AndThenSnippets { let cx_snippet = snippet(cx, cx_span, "cx"); let lint_snippet = snippet(cx, lint_span, ".."); let span_snippet = snippet(cx, span_span, "span"); - let msg_snippet = snippet(cx, msg_span, r#""...""#); + let msg_snippet = snippet_with_context(cx, msg_span, expr_ctxt, r#""...""#, app).0; AndThenSnippets { cx: cx_snippet, @@ -155,9 +166,14 @@ struct SpanSuggestionSnippets { applicability: Cow<'static, str>, } -fn span_suggestion_snippets<'hir>(cx: &LateContext<'_>, span_call_args: &'hir [Expr<'hir>]) -> SpanSuggestionSnippets { - let help_snippet = snippet(cx, span_call_args[1].span, r#""...""#); - let sugg_snippet = snippet(cx, span_call_args[2].span, ".."); +fn span_suggestion_snippets<'hir>( + cx: &LateContext<'_>, + expr_ctxt: SyntaxContext, + span_call_args: &'hir [Expr<'hir>], + app: &mut Applicability, +) -> SpanSuggestionSnippets { + let help_snippet = snippet_with_context(cx, span_call_args[1].span, expr_ctxt, r#""...""#, app).0; + let sugg_snippet = snippet_with_context(cx, span_call_args[2].span, expr_ctxt, "..", app).0; let applicability_snippet = snippet(cx, span_call_args[3].span, "Applicability::MachineApplicable"); SpanSuggestionSnippets { @@ -172,6 +188,7 @@ fn suggest_suggestion( expr: &Expr<'_>, and_then_snippets: &AndThenSnippets, span_suggestion_snippets: &SpanSuggestionSnippets, + app: Applicability, ) { span_lint_and_sugg( cx, @@ -189,7 +206,7 @@ fn suggest_suggestion( span_suggestion_snippets.sugg, span_suggestion_snippets.applicability ), - Applicability::MachineApplicable, + app, ); } @@ -199,6 +216,7 @@ fn suggest_help( and_then_snippets: &AndThenSnippets, help: &str, with_span: bool, + app: Applicability, ) { let option_span = if with_span { format!("Some({})", and_then_snippets.span) @@ -216,7 +234,7 @@ fn suggest_help( "span_lint_and_help({}, {}, {}, {}, {}, {help})", and_then_snippets.cx, and_then_snippets.lint, and_then_snippets.span, and_then_snippets.msg, &option_span, ), - Applicability::MachineApplicable, + app, ); } @@ -226,6 +244,7 @@ fn suggest_note( and_then_snippets: &AndThenSnippets, note: &str, with_span: bool, + app: Applicability, ) { let note_span = if with_span { format!("Some({})", and_then_snippets.span) @@ -243,6 +262,6 @@ fn suggest_note( "span_lint_and_note({}, {}, {}, {}, {note_span}, {note})", and_then_snippets.cx, and_then_snippets.lint, and_then_snippets.span, and_then_snippets.msg, ), - Applicability::MachineApplicable, + app, ); } diff --git a/tests/ui-internal/collapsible_span_lint_calls.fixed b/tests/ui-internal/collapsible_span_lint_calls.fixed index 76f68686ee2a..2b646a38b534 100644 --- a/tests/ui-internal/collapsible_span_lint_calls.fixed +++ b/tests/ui-internal/collapsible_span_lint_calls.fixed @@ -50,6 +50,15 @@ impl EarlyLintPass for Pass { span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { db.help(help_msg).help(help_msg); }); + + // Issue #15880 + #[expect(clippy::disallowed_names)] + let foo = "foo"; + span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, format!("try using {foo}"), format!("{foo}.use"), Applicability::MachineApplicable); + span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), format!("try using {foo}")); + span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, format!("try using {foo}")); + span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), format!("required because of {foo}")); + span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, format!("required because of {foo}")); } } diff --git a/tests/ui-internal/collapsible_span_lint_calls.rs b/tests/ui-internal/collapsible_span_lint_calls.rs index 214c8783a669..500552370053 100644 --- a/tests/ui-internal/collapsible_span_lint_calls.rs +++ b/tests/ui-internal/collapsible_span_lint_calls.rs @@ -65,6 +65,35 @@ impl EarlyLintPass for Pass { span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { db.help(help_msg).help(help_msg); }); + + // Issue #15880 + #[expect(clippy::disallowed_names)] + let foo = "foo"; + span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { + //~^ collapsible_span_lint_calls + db.span_suggestion( + expr.span, + format!("try using {foo}"), + format!("{foo}.use"), + Applicability::MachineApplicable, + ); + }); + span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { + //~^ collapsible_span_lint_calls + db.span_help(expr.span, format!("try using {foo}")); + }); + span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { + //~^ collapsible_span_lint_calls + db.help(format!("try using {foo}")); + }); + span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { + //~^ collapsible_span_lint_calls + db.span_note(expr.span, format!("required because of {foo}")); + }); + span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { + //~^ collapsible_span_lint_calls + db.note(format!("required because of {foo}")); + }); } } diff --git a/tests/ui-internal/collapsible_span_lint_calls.stderr b/tests/ui-internal/collapsible_span_lint_calls.stderr index 9c83538947ca..76b453019270 100644 --- a/tests/ui-internal/collapsible_span_lint_calls.stderr +++ b/tests/ui-internal/collapsible_span_lint_calls.stderr @@ -49,5 +49,53 @@ LL | | db.note(note_msg); LL | | }); | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, note_msg)` -error: aborting due to 5 previous errors +error: this call is collapsible + --> tests/ui-internal/collapsible_span_lint_calls.rs:72:9 + | +LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { +LL | | +LL | | db.span_suggestion( +LL | | expr.span, +... | +LL | | ); +LL | | }); + | |__________^ help: collapse into: `span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, format!("try using {foo}"), format!("{foo}.use"), Applicability::MachineApplicable)` + +error: this call is collapsible + --> tests/ui-internal/collapsible_span_lint_calls.rs:81:9 + | +LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { +LL | | +LL | | db.span_help(expr.span, format!("try using {foo}")); +LL | | }); + | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), format!("try using {foo}"))` + +error: this call is collapsible + --> tests/ui-internal/collapsible_span_lint_calls.rs:85:9 + | +LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { +LL | | +LL | | db.help(format!("try using {foo}")); +LL | | }); + | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, format!("try using {foo}"))` + +error: this call is collapsible + --> tests/ui-internal/collapsible_span_lint_calls.rs:89:9 + | +LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { +LL | | +LL | | db.span_note(expr.span, format!("required because of {foo}")); +LL | | }); + | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), format!("required because of {foo}"))` + +error: this call is collapsible + --> tests/ui-internal/collapsible_span_lint_calls.rs:93:9 + | +LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| { +LL | | +LL | | db.note(format!("required because of {foo}")); +LL | | }); + | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, format!("required because of {foo}"))` + +error: aborting due to 10 previous errors From b270954300ec06f3478e3758d0c8d3e9f38efebf Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Mon, 13 Oct 2025 19:50:47 +0200 Subject: [PATCH 0047/3801] s/snippet/snippet_with_applicability while we're at it --- .../src/collapsible_span_lint_calls.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clippy_lints_internal/src/collapsible_span_lint_calls.rs b/clippy_lints_internal/src/collapsible_span_lint_calls.rs index f7adb782929c..b048a1004b0d 100644 --- a/clippy_lints_internal/src/collapsible_span_lint_calls.rs +++ b/clippy_lints_internal/src/collapsible_span_lint_calls.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::{snippet, snippet_with_context}; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::{SpanlessEq, is_lint_allowed, peel_blocks_with_stmt, sym}; use rustc_errors::Applicability; use rustc_hir::{Closure, Expr, ExprKind}; @@ -147,9 +147,9 @@ fn get_and_then_snippets( msg_span: Span, app: &mut Applicability, ) -> AndThenSnippets { - let cx_snippet = snippet(cx, cx_span, "cx"); - let lint_snippet = snippet(cx, lint_span, ".."); - let span_snippet = snippet(cx, span_span, "span"); + let cx_snippet = snippet_with_applicability(cx, cx_span, "cx", app); + let lint_snippet = snippet_with_applicability(cx, lint_span, "..", app); + let span_snippet = snippet_with_applicability(cx, span_span, "span", app); let msg_snippet = snippet_with_context(cx, msg_span, expr_ctxt, r#""...""#, app).0; AndThenSnippets { @@ -174,7 +174,8 @@ fn span_suggestion_snippets<'hir>( ) -> SpanSuggestionSnippets { let help_snippet = snippet_with_context(cx, span_call_args[1].span, expr_ctxt, r#""...""#, app).0; let sugg_snippet = snippet_with_context(cx, span_call_args[2].span, expr_ctxt, "..", app).0; - let applicability_snippet = snippet(cx, span_call_args[3].span, "Applicability::MachineApplicable"); + let applicability_snippet = + snippet_with_applicability(cx, span_call_args[3].span, "Applicability::MachineApplicable", app); SpanSuggestionSnippets { help: help_snippet, From 31bf836c74e5b53e654bed70158cabfdfdca8acf Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Tue, 14 Oct 2025 02:23:44 -0400 Subject: [PATCH 0048/3801] Use a const generic parameter for the function chunk size Add comments for the optimized function invariants to the caller Add const-hack fixme for using while-loops Document the invariant for the `_chunks` function Add a debug assert for the tail handling invariant --- library/core/src/slice/ascii.rs | 35 +++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 8b713947cd9c..0f3cf243f164 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -61,8 +61,15 @@ impl [u8] { } #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] - if self.len() >= 16 { - return self.eq_ignore_ascii_case_chunks(other); + { + const CHUNK_SIZE: usize = 16; + // The following function has two invariants: + // 1. The slice lengths must be equal, which we checked above. + // 2. The slice lengths must greater than or equal to N, which this + // if-statement is checking. + if self.len() >= CHUNK_SIZE { + return self.eq_ignore_ascii_case_chunks::(other); + } } self.eq_ignore_ascii_case_simple(other) @@ -90,24 +97,30 @@ impl [u8] { true } - /// Optimized version of `eq_ignore_ascii_case` for byte lengths of at least - /// 16 bytes, which processes chunks at a time. + /// Optimized version of `eq_ignore_ascii_case` to process chunks at a time. /// /// Platforms that have SIMD instructions may benefit from this /// implementation over `eq_ignore_ascii_case_simple`. + /// + /// # Invariants + /// + /// The caller must guarantee that the slices are equal in length, and the + /// slice lengths are greater than or equal to `N` bytes. #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] #[inline] - const fn eq_ignore_ascii_case_chunks(&self, other: &[u8]) -> bool { - const N: usize = 16; + const fn eq_ignore_ascii_case_chunks(&self, other: &[u8]) -> bool { + // FIXME(const-hack): The while-loops that follow should be replaced by + // for-loops when available in const. + let (self_chunks, self_rem) = self.as_chunks::(); let (other_chunks, _) = other.as_chunks::(); // Branchless check to encourage auto-vectorization #[inline(always)] - const fn eq_ignore_ascii_inner(lhs: &[u8; N], rhs: &[u8; N]) -> bool { + const fn eq_ignore_ascii_inner(lhs: &[u8; L], rhs: &[u8; L]) -> bool { let mut equal_ascii = true; let mut j = 0; - while j < N { + while j < L { equal_ascii &= lhs[j].eq_ignore_ascii_case(&rhs[j]); j += 1; } @@ -124,6 +137,12 @@ impl [u8] { i += 1; } + // Check the length invariant which is necessary for the tail-handling + // logic to be correct. This should have been upheld by the caller, + // otherwise lengths less than N will compare as true without any + // checking. + debug_assert!(self.len() >= N); + // If there are remaining tails, load the last N bytes in the slices to // avoid falling back to per-byte checking. if !self_rem.is_empty() { From 3fadbd50b099b873b8631bc39158ce83d0845768 Mon Sep 17 00:00:00 2001 From: Dan54 Date: Thu, 16 Oct 2025 01:33:22 +0100 Subject: [PATCH 0049/3801] Add bounds to clamp error message --- library/core/src/cmp.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 7f369d19c3d1..e50984bb781d 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1997,6 +1997,19 @@ mod impls { fn cmp(&self, other: &Self) -> Ordering { crate::intrinsics::three_way_compare(*self, *other) } + + #[inline] + fn clamp(self, min: Self, max: Self) -> Self + { + assert!(min <= max, "min > max. min = {min}, max = {max}"); + if self < min { + min + } else if self > max { + max + } else { + self + } + } } )*) } From f7d7a35daf9cb25b0b5ed0c76d176df66eb2a4e4 Mon Sep 17 00:00:00 2001 From: Dan54 Date: Thu, 16 Oct 2025 02:03:39 +0100 Subject: [PATCH 0050/3801] track_caller for clamp --- library/core/src/cmp.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index e50984bb781d..3bc4c28a9d81 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1999,6 +1999,7 @@ mod impls { } #[inline] + #[track_caller] fn clamp(self, min: Self, max: Self) -> Self { assert!(min <= max, "min > max. min = {min}, max = {max}"); From 6dbea1f0a257862d1fcc1582f80fbd701dc5f18e Mon Sep 17 00:00:00 2001 From: Dan54 Date: Thu, 16 Oct 2025 03:04:51 +0100 Subject: [PATCH 0051/3801] use const_assert! --- library/core/src/cmp.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 3bc4c28a9d81..feb9c4319604 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1855,6 +1855,7 @@ mod impls { use crate::hint::unreachable_unchecked; use crate::marker::PointeeSized; use crate::ops::ControlFlow::{self, Break, Continue}; + use crate::panic::const_assert; macro_rules! partial_eq_impl { ($($t:ty)*) => ($( @@ -2002,7 +2003,13 @@ mod impls { #[track_caller] fn clamp(self, min: Self, max: Self) -> Self { - assert!(min <= max, "min > max. min = {min}, max = {max}"); + const_assert!( + min <= max, + "min > max", + "min > max. min = {min:?}, max = {max:?}", + min: $t, + max: $t, + ); if self < min { min } else if self > max { From d056f59704cdd283733fa8a896e45f1731725cbb Mon Sep 17 00:00:00 2001 From: matwatson Date: Sun, 21 Sep 2025 14:14:29 -0700 Subject: [PATCH 0052/3801] corrected Cell module level doc replaced `&mut T` with `&T` to finally state "a &T to the inner value can never be obtained" --- library/core/src/cell.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 9b53b75ebee8..1b3126700ff3 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -27,10 +27,9 @@ //! //! ## `Cell` //! -//! [`Cell`] implements interior mutability by moving values in and out of the cell. That is, an -//! `&mut T` to the inner value can never be obtained, and the value itself cannot be directly -//! obtained without replacing it with something else. Both of these rules ensure that there is -//! never more than one reference pointing to the inner value. This type provides the following +//! [`Cell`] implements interior mutability by moving values in and out of the cell. That is, a +//! `&T` to the inner value can never be obtained, and the value itself cannot be directly +//! obtained without replacing it with something else. This type provides the following //! methods: //! //! - For types that implement [`Copy`], the [`get`](Cell::get) method retrieves the current From ce4265663ded513b905f2371ba85cc119bae07e5 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 10 Oct 2025 00:21:33 +0200 Subject: [PATCH 0053/3801] make the suggestions verbose they are much readable this way imo --- .../src/matches/match_like_matches.rs | 46 +++--- tests/ui/match_like_matches_macro.stderr | 135 ++++++++++++++++-- 2 files changed, 150 insertions(+), 31 deletions(-) diff --git a/clippy_lints/src/matches/match_like_matches.rs b/clippy_lints/src/matches/match_like_matches.rs index b5f631e8fea3..63bef58409ea 100644 --- a/clippy_lints/src/matches/match_like_matches.rs +++ b/clippy_lints/src/matches/match_like_matches.rs @@ -1,7 +1,7 @@ //! Lint a `match` or `if let .. { .. } else { .. }` expr that could be replaced by `matches!` use super::REDUNDANT_PATTERN_MATCHING; -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment}; use rustc_ast::LitKind; @@ -43,18 +43,23 @@ pub(crate) fn check_if_let<'tcx>( { ex_new = ex_inner; } - span_lint_and_sugg( + span_lint_and_then( cx, MATCH_LIKE_MATCHES_MACRO, expr.span, - "if let .. else expression looks like `matches!` macro", - "try", - format!( - "{}matches!({}, {pat})", - if b0 { "" } else { "!" }, - snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), - ), - applicability, + "`if let .. else` expression looks like `matches!` macro", + |diag| { + diag.span_suggestion_verbose( + expr.span, + "use `matches!` directly", + format!( + "{}matches!({}, {pat})", + if b0 { "" } else { "!" }, + snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), + ), + applicability, + ); + }, ); } } @@ -169,18 +174,23 @@ pub(super) fn check_match<'tcx>( { ex_new = ex_inner; } - span_lint_and_sugg( + span_lint_and_then( cx, MATCH_LIKE_MATCHES_MACRO, e.span, "match expression looks like `matches!` macro", - "try", - format!( - "{}matches!({}, {pat_and_guard})", - if b0 { "" } else { "!" }, - snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), - ), - applicability, + |diag| { + diag.span_suggestion_verbose( + e.span, + "use `matches!` directly", + format!( + "{}matches!({}, {pat_and_guard})", + if b0 { "" } else { "!" }, + snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), + ), + applicability, + ); + }, ); true } else { diff --git a/tests/ui/match_like_matches_macro.stderr b/tests/ui/match_like_matches_macro.stderr index ae277ce4dca6..8ea13e04422e 100644 --- a/tests/ui/match_like_matches_macro.stderr +++ b/tests/ui/match_like_matches_macro.stderr @@ -6,10 +6,18 @@ LL | let _y = match x { LL | | Some(0) => true, LL | | _ => false, LL | | }; - | |_____^ help: try: `matches!(x, Some(0))` + | |_____^ | = note: `-D clippy::match-like-matches-macro` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::match_like_matches_macro)]` +help: use `matches!` directly + | +LL - let _y = match x { +LL - Some(0) => true, +LL - _ => false, +LL - }; +LL + let _y = matches!(x, Some(0)); + | error: redundant pattern matching, consider using `is_some()` --> tests/ui/match_like_matches_macro.rs:20:14 @@ -42,13 +50,28 @@ LL | let _zz = match x { LL | | Some(r) if r == 0 => false, LL | | _ => true, LL | | }; - | |_____^ help: try: `!matches!(x, Some(r) if r == 0)` + | |_____^ + | +help: use `matches!` directly + | +LL - let _zz = match x { +LL - Some(r) if r == 0 => false, +LL - _ => true, +LL - }; +LL + let _zz = !matches!(x, Some(r) if r == 0); + | -error: if let .. else expression looks like `matches!` macro +error: `if let .. else` expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:41:16 | LL | let _zzz = if let Some(5) = x { true } else { false }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(x, Some(5))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `matches!` directly + | +LL - let _zzz = if let Some(5) = x { true } else { false }; +LL + let _zzz = matches!(x, Some(5)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:66:20 @@ -59,7 +82,17 @@ LL | | E::A(_) => true, LL | | E::B(_) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(x, E::A(_) | E::B(_))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _ans = match x { +LL - E::A(_) => true, +LL - E::B(_) => true, +LL - _ => false, +LL - }; +LL + let _ans = matches!(x, E::A(_) | E::B(_)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:77:20 @@ -71,7 +104,19 @@ LL | | true ... | LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(x, E::A(_) | E::B(_))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _ans = match x { +LL - E::A(_) => { +LL - true +LL - } +LL - E::B(_) => true, +LL - _ => false, +LL - }; +LL + let _ans = matches!(x, E::A(_) | E::B(_)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:88:20 @@ -82,7 +127,17 @@ LL | | E::B(_) => false, LL | | E::C => false, LL | | _ => true, LL | | }; - | |_________^ help: try: `!matches!(x, E::B(_) | E::C)` + | |_________^ + | +help: use `matches!` directly + | +LL - let _ans = match x { +LL - E::B(_) => false, +LL - E::C => false, +LL - _ => true, +LL - }; +LL + let _ans = !matches!(x, E::B(_) | E::C); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:149:18 @@ -92,7 +147,16 @@ LL | let _z = match &z { LL | | Some(3) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(z, Some(3))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _z = match &z { +LL - Some(3) => true, +LL - _ => false, +LL - }; +LL + let _z = matches!(z, Some(3)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:159:18 @@ -102,7 +166,16 @@ LL | let _z = match &z { LL | | Some(3) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(&z, Some(3))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _z = match &z { +LL - Some(3) => true, +LL - _ => false, +LL - }; +LL + let _z = matches!(&z, Some(3)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:177:21 @@ -112,7 +185,16 @@ LL | let _ = match &z { LL | | AnEnum::X => true, LL | | _ => false, LL | | }; - | |_____________^ help: try: `matches!(&z, AnEnum::X)` + | |_____________^ + | +help: use `matches!` directly + | +LL - let _ = match &z { +LL - AnEnum::X => true, +LL - _ => false, +LL - }; +LL + let _ = matches!(&z, AnEnum::X); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:192:20 @@ -122,7 +204,16 @@ LL | let _res = match &val { LL | | &Some(ref _a) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(&val, &Some(ref _a))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _res = match &val { +LL - &Some(ref _a) => true, +LL - _ => false, +LL - }; +LL + let _res = matches!(&val, &Some(ref _a)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:205:20 @@ -132,7 +223,16 @@ LL | let _res = match &val { LL | | &Some(ref _a) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(&val, &Some(ref _a))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _res = match &val { +LL - &Some(ref _a) => true, +LL - _ => false, +LL - }; +LL + let _res = matches!(&val, &Some(ref _a)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:264:14 @@ -142,7 +242,16 @@ LL | let _y = match Some(5) { LL | | Some(0) => true, LL | | _ => false, LL | | }; - | |_____^ help: try: `matches!(Some(5), Some(0))` + | |_____^ + | +help: use `matches!` directly + | +LL - let _y = match Some(5) { +LL - Some(0) => true, +LL - _ => false, +LL - }; +LL + let _y = matches!(Some(5), Some(0)); + | error: aborting due to 14 previous errors From 7b83f421075bb9b8e68fb26570d18554a926526e Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 10 Oct 2025 00:01:51 +0200 Subject: [PATCH 0054/3801] fix(match_like_matches_macro): don't create `matches!` with if-let guards --- .../src/matches/match_like_matches.rs | 6 ++- tests/ui/match_like_matches_macro.fixed | 7 +++ tests/ui/match_like_matches_macro.rs | 10 ++++ tests/ui/match_like_matches_macro.stderr | 21 +++++++- .../match_like_matches_macro_if_let_guard.rs | 51 +++++++++++++++++++ 5 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 tests/ui/match_like_matches_macro_if_let_guard.rs diff --git a/clippy_lints/src/matches/match_like_matches.rs b/clippy_lints/src/matches/match_like_matches.rs index 63bef58409ea..89411115f730 100644 --- a/clippy_lints/src/matches/match_like_matches.rs +++ b/clippy_lints/src/matches/match_like_matches.rs @@ -2,6 +2,7 @@ use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::higher::has_let_expr; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment}; use rustc_ast::LitKind; @@ -92,7 +93,10 @@ pub(super) fn check_match<'tcx>( // ```rs // matches!(e, Either::Left $(if $guard)|+) // ``` - middle_arms.is_empty() + // + // But if the guard _is_ present, it may not be an `if-let` guard, as `matches!` doesn't + // support these (currently?) + (middle_arms.is_empty() && first_arm.guard.is_none_or(|g| !has_let_expr(g))) // - (added in #6216) There are middle arms // diff --git a/tests/ui/match_like_matches_macro.fixed b/tests/ui/match_like_matches_macro.fixed index a1c95e8a94f1..dad59c1ce6e4 100644 --- a/tests/ui/match_like_matches_macro.fixed +++ b/tests/ui/match_like_matches_macro.fixed @@ -223,3 +223,10 @@ fn msrv_1_42() { let _y = matches!(Some(5), Some(0)); //~^^^^ match_like_matches_macro } + +#[expect(clippy::option_option)] +fn issue15841(opt: Option>>, value: i32) { + // Lint: no if-let _in the guard_ + let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() })); + //~^^^^ match_like_matches_macro +} diff --git a/tests/ui/match_like_matches_macro.rs b/tests/ui/match_like_matches_macro.rs index eb419ba5bf8d..94bc6433e5cb 100644 --- a/tests/ui/match_like_matches_macro.rs +++ b/tests/ui/match_like_matches_macro.rs @@ -267,3 +267,13 @@ fn msrv_1_42() { }; //~^^^^ match_like_matches_macro } + +#[expect(clippy::option_option)] +fn issue15841(opt: Option>>, value: i32) { + // Lint: no if-let _in the guard_ + let _ = match opt { + Some(first) if (if let Some(second) = first { true } else { todo!() }) => true, + _ => false, + }; + //~^^^^ match_like_matches_macro +} diff --git a/tests/ui/match_like_matches_macro.stderr b/tests/ui/match_like_matches_macro.stderr index 8ea13e04422e..a8e352461dbb 100644 --- a/tests/ui/match_like_matches_macro.stderr +++ b/tests/ui/match_like_matches_macro.stderr @@ -253,5 +253,24 @@ LL - }; LL + let _y = matches!(Some(5), Some(0)); | -error: aborting due to 14 previous errors +error: match expression looks like `matches!` macro + --> tests/ui/match_like_matches_macro.rs:274:13 + | +LL | let _ = match opt { + | _____________^ +LL | | Some(first) if (if let Some(second) = first { true } else { todo!() }) => true, +LL | | _ => false, +LL | | }; + | |_____^ + | +help: use `matches!` directly + | +LL - let _ = match opt { +LL - Some(first) if (if let Some(second) = first { true } else { todo!() }) => true, +LL - _ => false, +LL - }; +LL + let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() })); + | + +error: aborting due to 15 previous errors diff --git a/tests/ui/match_like_matches_macro_if_let_guard.rs b/tests/ui/match_like_matches_macro_if_let_guard.rs new file mode 100644 index 000000000000..b596d36072e5 --- /dev/null +++ b/tests/ui/match_like_matches_macro_if_let_guard.rs @@ -0,0 +1,51 @@ +//@check-pass +#![warn(clippy::match_like_matches_macro)] +#![feature(if_let_guard)] + +#[expect(clippy::option_option)] +fn issue15841(opt: Option>>, value: i32) { + let _ = match opt { + Some(first) + if let Some(second) = first + && let Some(third) = second + && third == value => + { + true + }, + _ => false, + }; + + // if-let is the second if + let _ = match opt { + Some(first) + if first.is_some() + && let Some(second) = first => + { + true + }, + _ => false, + }; + + // if-let is the third if + let _ = match opt { + Some(first) + if first.is_some() + && first.is_none() + && let Some(second) = first => + { + true + }, + _ => false, + }; + + // don't get confused by `or`s + let _ = match opt { + Some(first) + if (first.is_some() || first.is_none()) + && let Some(second) = first => + { + true + }, + _ => false, + }; +} From 3833ac3be02c3e9853570660224d14dced9250f2 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Wed, 8 Oct 2025 16:38:57 +0200 Subject: [PATCH 0055/3801] misc: use `Symbol`s instead of `&str`s --- .../methods/manual_saturating_arithmetic.rs | 67 ++++++++++++++----- clippy_lints/src/methods/mod.rs | 9 +-- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs index 2196ce92b0ab..21526c83c318 100644 --- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -8,6 +8,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_lint::LateContext; use rustc_middle::ty::layout::LayoutOf; +use rustc_span::Symbol; pub fn check( cx: &LateContext<'_>, @@ -15,7 +16,7 @@ pub fn check( arith_lhs: &hir::Expr<'_>, arith_rhs: &hir::Expr<'_>, unwrap_arg: &hir::Expr<'_>, - arith: &str, + arith: Symbol, ) { let ty = cx.typeck_results().expr_ty(arith_lhs); if !ty.is_integral() { @@ -26,35 +27,43 @@ pub fn check( return; }; - if ty.is_signed() { + let Some(checked_arith) = CheckedArith::new(arith) else { + return; + }; + + { use self::MinMax::{Max, Min}; use self::Sign::{Neg, Pos}; + use CheckedArith::{Add, Mul, Sub}; - let Some(sign) = lit_sign(arith_rhs) else { - return; - }; + if ty.is_signed() { + let Some(sign) = lit_sign(arith_rhs) else { + return; + }; - match (arith, sign, mm) { - ("add", Pos, Max) | ("add", Neg, Min) | ("sub", Neg, Max) | ("sub", Pos, Min) => (), - // "mul" is omitted because lhs can be negative. - _ => return, - } - } else { - match (mm, arith) { - (MinMax::Max, "add" | "mul") | (MinMax::Min, "sub") => (), - _ => return, + match (&checked_arith, sign, mm) { + (Add, Pos, Max) | (Add, Neg, Min) | (Sub, Neg, Max) | (Sub, Pos, Min) => (), + // "mul" is omitted because lhs can be negative. + _ => return, + } + } else { + match (mm, &checked_arith) { + (Max, Add | Mul) | (Min, Sub) => (), + _ => return, + } } } let mut applicability = Applicability::MachineApplicable; + let saturating_arith = checked_arith.as_saturating(); span_lint_and_sugg( cx, super::MANUAL_SATURATING_ARITHMETIC, expr.span, "manual saturating arithmetic", - format!("consider using `saturating_{arith}`"), + format!("consider using `{saturating_arith}`"), format!( - "{}.saturating_{arith}({})", + "{}.{saturating_arith}({})", snippet_with_applicability(cx, arith_lhs.span, "..", &mut applicability), snippet_with_applicability(cx, arith_rhs.span, "..", &mut applicability), ), @@ -62,6 +71,32 @@ pub fn check( ); } +enum CheckedArith { + Add, + Sub, + Mul, +} + +impl CheckedArith { + fn new(sym: Symbol) -> Option { + let res = match sym { + sym::checked_add => Self::Add, + sym::checked_sub => Self::Sub, + sym::checked_mul => Self::Mul, + _ => return None, + }; + Some(res) + } + + fn as_saturating(&self) -> &'static str { + match self { + Self::Add => "saturating_add", + Self::Sub => "saturating_sub", + Self::Mul => "saturating_mul", + } + } +} + #[derive(PartialEq, Eq)] enum MinMax { Min, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index c9066be51c44..5702d08aa6d3 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -5507,14 +5507,7 @@ impl Methods { (sym::unwrap_or, [u_arg]) => { match method_call(recv) { Some((arith @ (sym::checked_add | sym::checked_sub | sym::checked_mul), lhs, [rhs], _, _)) => { - manual_saturating_arithmetic::check( - cx, - expr, - lhs, - rhs, - u_arg, - &arith.as_str()[const { "checked_".len() }..], - ); + manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, arith); }, Some((sym::map, m_recv, [m_arg], span, _)) => { option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv); From 95834c9f6008a2f6fda31db7e990bd816cc297b3 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Wed, 8 Oct 2025 17:15:13 +0200 Subject: [PATCH 0056/3801] recognize `x.checked_sub(y).unwrap_or_default()` as well --- .../methods/manual_saturating_arithmetic.rs | 90 +++++++++++++------ clippy_lints/src/methods/mod.rs | 5 +- tests/ui/manual_saturating_arithmetic.fixed | 10 +++ tests/ui/manual_saturating_arithmetic.rs | 10 +++ tests/ui/manual_saturating_arithmetic.stderr | 8 +- 5 files changed, 93 insertions(+), 30 deletions(-) diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs index 21526c83c318..a3dd967bd77a 100644 --- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -4,18 +4,19 @@ use clippy_utils::source::snippet_with_applicability; use clippy_utils::sym; use rustc_ast::ast; use rustc_errors::Applicability; -use rustc_hir as hir; use rustc_hir::def::Res; +use rustc_hir::{self as hir, Expr}; use rustc_lint::LateContext; +use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; use rustc_span::Symbol; -pub fn check( +pub fn check_unwrap_or( cx: &LateContext<'_>, - expr: &hir::Expr<'_>, - arith_lhs: &hir::Expr<'_>, - arith_rhs: &hir::Expr<'_>, - unwrap_arg: &hir::Expr<'_>, + expr: &Expr<'_>, + arith_lhs: &Expr<'_>, + arith_rhs: &Expr<'_>, + unwrap_arg: &Expr<'_>, arith: Symbol, ) { let ty = cx.typeck_results().expr_ty(arith_lhs); @@ -31,26 +32,58 @@ pub fn check( return; }; - { - use self::MinMax::{Max, Min}; - use self::Sign::{Neg, Pos}; - use CheckedArith::{Add, Mul, Sub}; + check(cx, expr, arith_lhs, arith_rhs, ty, mm, checked_arith); +} - if ty.is_signed() { - let Some(sign) = lit_sign(arith_rhs) else { - return; - }; +pub(super) fn check_sub_unwrap_or_default( + cx: &LateContext<'_>, + expr: &Expr<'_>, + arith_lhs: &Expr<'_>, + arith_rhs: &Expr<'_>, +) { + let ty = cx.typeck_results().expr_ty(arith_lhs); + if !ty.is_integral() { + return; + } - match (&checked_arith, sign, mm) { - (Add, Pos, Max) | (Add, Neg, Min) | (Sub, Neg, Max) | (Sub, Pos, Min) => (), - // "mul" is omitted because lhs can be negative. - _ => return, - } - } else { - match (mm, &checked_arith) { - (Max, Add | Mul) | (Min, Sub) => (), - _ => return, - } + let mm = if ty.is_signed() { + return; // iN::default() is 0, which is neither MIN nor MAX + } else { + MinMax::Min // uN::default() is 0, which is also the MIN + }; + + let checked_arith = CheckedArith::Sub; + + check(cx, expr, arith_lhs, arith_rhs, ty, mm, checked_arith); +} + +fn check( + cx: &LateContext<'_>, + expr: &Expr<'_>, + arith_lhs: &Expr<'_>, + arith_rhs: &Expr<'_>, + ty: Ty<'_>, + mm: MinMax, + checked_arith: CheckedArith, +) { + use self::MinMax::{Max, Min}; + use self::Sign::{Neg, Pos}; + use CheckedArith::{Add, Mul, Sub}; + + if ty.is_signed() { + let Some(sign) = lit_sign(arith_rhs) else { + return; + }; + + match (checked_arith, sign, mm) { + (Add, Pos, Max) | (Add, Neg, Min) | (Sub, Neg, Max) | (Sub, Pos, Min) => (), + // "mul" is omitted because lhs can be negative. + _ => return, + } + } else { + match (mm, checked_arith) { + (Max, Add | Mul) | (Min, Sub) => (), + _ => return, } } @@ -71,6 +104,7 @@ pub fn check( ); } +#[derive(Clone, Copy)] enum CheckedArith { Add, Sub, @@ -88,7 +122,7 @@ impl CheckedArith { Some(res) } - fn as_saturating(&self) -> &'static str { + fn as_saturating(self) -> &'static str { match self { Self::Add => "saturating_add", Self::Sub => "saturating_sub", @@ -103,7 +137,7 @@ enum MinMax { Max, } -fn is_min_or_max(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option { +fn is_min_or_max(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { // `T::max_value()` `T::min_value()` inherent methods if let hir::ExprKind::Call(func, []) = &expr.kind && let hir::ExprKind::Path(hir::QPath::TypeRelative(_, segment)) = &func.kind @@ -141,7 +175,7 @@ fn is_min_or_max(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option { (0, if bits == 128 { !0 } else { (1 << bits) - 1 }) }; - let check_lit = |expr: &hir::Expr<'_>, check_min: bool| { + let check_lit = |expr: &Expr<'_>, check_min: bool| { if let hir::ExprKind::Lit(lit) = &expr.kind && let ast::LitKind::Int(value, _) = lit.node { @@ -176,7 +210,7 @@ enum Sign { Neg, } -fn lit_sign(expr: &hir::Expr<'_>) -> Option { +fn lit_sign(expr: &Expr<'_>) -> Option { if let hir::ExprKind::Unary(hir::UnOp::Neg, inner) = &expr.kind { if let hir::ExprKind::Lit(..) = &inner.kind { return Some(Sign::Neg); diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 5702d08aa6d3..d8181dcf19f0 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -5507,7 +5507,7 @@ impl Methods { (sym::unwrap_or, [u_arg]) => { match method_call(recv) { Some((arith @ (sym::checked_add | sym::checked_sub | sym::checked_mul), lhs, [rhs], _, _)) => { - manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, arith); + manual_saturating_arithmetic::check_unwrap_or(cx, expr, lhs, rhs, u_arg, arith); }, Some((sym::map, m_recv, [m_arg], span, _)) => { option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv); @@ -5528,6 +5528,9 @@ impl Methods { }, (sym::unwrap_or_default, []) => { match method_call(recv) { + Some((sym::checked_sub, lhs, [rhs], _, _)) => { + manual_saturating_arithmetic::check_sub_unwrap_or_default(cx, expr, lhs, rhs); + }, Some((sym::map, m_recv, [arg], span, _)) => { manual_is_variant_and::check(cx, expr, m_recv, arg, span, self.msrv); }, diff --git a/tests/ui/manual_saturating_arithmetic.fixed b/tests/ui/manual_saturating_arithmetic.fixed index 304be05f6c4c..8dd142b2c79a 100644 --- a/tests/ui/manual_saturating_arithmetic.fixed +++ b/tests/ui/manual_saturating_arithmetic.fixed @@ -58,3 +58,13 @@ fn main() { let _ = 1i8.checked_sub(1).unwrap_or(127); // ok let _ = 1i8.checked_sub(-1).unwrap_or(-128); // ok } + +fn issue15655() { + let _ = 5u32.saturating_sub(1u32); //~ manual_saturating_arithmetic + let _ = 5u32.checked_add(1u32).unwrap_or_default(); // ok + let _ = 5u32.checked_mul(1u32).unwrap_or_default(); // ok + + let _ = 5i32.checked_sub(1i32).unwrap_or_default(); // ok + let _ = 5i32.checked_add(1i32).unwrap_or_default(); // ok + let _ = 5i32.checked_mul(1i32).unwrap_or_default(); // ok +} diff --git a/tests/ui/manual_saturating_arithmetic.rs b/tests/ui/manual_saturating_arithmetic.rs index c2b570e974ac..9cc8bc42410d 100644 --- a/tests/ui/manual_saturating_arithmetic.rs +++ b/tests/ui/manual_saturating_arithmetic.rs @@ -73,3 +73,13 @@ fn main() { let _ = 1i8.checked_sub(1).unwrap_or(127); // ok let _ = 1i8.checked_sub(-1).unwrap_or(-128); // ok } + +fn issue15655() { + let _ = 5u32.checked_sub(1u32).unwrap_or_default(); //~ manual_saturating_arithmetic + let _ = 5u32.checked_add(1u32).unwrap_or_default(); // ok + let _ = 5u32.checked_mul(1u32).unwrap_or_default(); // ok + + let _ = 5i32.checked_sub(1i32).unwrap_or_default(); // ok + let _ = 5i32.checked_add(1i32).unwrap_or_default(); // ok + let _ = 5i32.checked_mul(1i32).unwrap_or_default(); // ok +} diff --git a/tests/ui/manual_saturating_arithmetic.stderr b/tests/ui/manual_saturating_arithmetic.stderr index 2f006a3ae170..aec0f0a16419 100644 --- a/tests/ui/manual_saturating_arithmetic.stderr +++ b/tests/ui/manual_saturating_arithmetic.stderr @@ -165,5 +165,11 @@ LL | | .checked_sub(-1) LL | | .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727); | |_______________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(-1)` -error: aborting due to 24 previous errors +error: manual saturating arithmetic + --> tests/ui/manual_saturating_arithmetic.rs:78:13 + | +LL | let _ = 5u32.checked_sub(1u32).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `5u32.saturating_sub(1u32)` + +error: aborting due to 25 previous errors From e548d77721254a12519b2d04a00c6b5afd0758d6 Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas) Chirananthavat" Date: Tue, 21 Oct 2025 17:51:38 +0700 Subject: [PATCH 0057/3801] Remove an attempted error annotation This file previously contained an error annotation with incorrect syntax. Remove this annotation, as per the dev guide, since this is marked as known-bug. https://rustc-dev-guide.rust-lang.org/tests/ui.html#known-bugs --- .../const-traits/const_closure-const_trait_impl-ice-113381.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs index 30002038f689..e355ee724d1b 100644 --- a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs +++ b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs @@ -13,6 +13,4 @@ impl Foo for () { fn main() { (const || (()).foo())(); - // ^ ERROR: cannot call non-const method `<() as Foo>::foo` in constant functions - // FIXME(const_trait_impl) this should probably say constant closures } From a2d1d14f682c7976a089c26546ab55c7c2e66744 Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas) Chirananthavat" Date: Tue, 21 Oct 2025 14:10:07 +0700 Subject: [PATCH 0058/3801] Make `const BorrowMut` require `const Borrow` --- library/core/src/borrow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs index 78ba69fec142..eb4562bda4ce 100644 --- a/library/core/src/borrow.rs +++ b/library/core/src/borrow.rs @@ -187,7 +187,7 @@ pub const trait Borrow { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "BorrowMut"] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] -pub const trait BorrowMut: Borrow { +pub const trait BorrowMut: [const] Borrow { /// Mutably borrows from an owned value. /// /// # Examples From 28819e0f4b860f62d2e1748fdc19a1628cc5933c Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas) Chirananthavat" Date: Tue, 21 Oct 2025 14:11:33 +0700 Subject: [PATCH 0059/3801] Make `const Fn` require `const FnMut` --- library/core/src/ops/function.rs | 2 +- tests/ui/traits/const-traits/call.rs | 1 + tests/ui/traits/const-traits/call.stderr | 11 ++++++++++- .../const_closure-const_trait_impl-ice-113381.stderr | 11 ++++++++++- .../non-const-op-const-closure-non-const-outer.rs | 1 + .../non-const-op-const-closure-non-const-outer.stderr | 11 ++++++++++- 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index 479368ba8f80..efe5c0871fb8 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -73,7 +73,7 @@ use crate::marker::Tuple; #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] #[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")] -pub const trait Fn: FnMut { +pub const trait Fn: [const] FnMut { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] extern "rust-call" fn call(&self, args: Args) -> Self::Output; diff --git a/tests/ui/traits/const-traits/call.rs b/tests/ui/traits/const-traits/call.rs index b1080fe78bb5..65b75cfe5cb2 100644 --- a/tests/ui/traits/const-traits/call.rs +++ b/tests/ui/traits/const-traits/call.rs @@ -6,6 +6,7 @@ pub const _: () = { assert!((const || true)()); //~^ ERROR }: [const] Fn()` is not satisfied + //~| ERROR }: [const] FnMut()` is not satisfied }; fn main() {} diff --git a/tests/ui/traits/const-traits/call.stderr b/tests/ui/traits/const-traits/call.stderr index 8e32cab6dfcf..b688746e2506 100644 --- a/tests/ui/traits/const-traits/call.stderr +++ b/tests/ui/traits/const-traits/call.stderr @@ -4,6 +4,15 @@ error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] Fn()` LL | assert!((const || true)()); | ^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] FnMut()` is not satisfied + --> $DIR/call.rs:7:13 + | +LL | assert!((const || true)()); + | ^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `call` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr index dab3f14161fa..90e87c724f54 100644 --- a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr +++ b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr @@ -4,6 +4,15 @@ error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice- LL | (const || (()).foo())(); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice-113381.rs:15:6: 15:14}: [const] FnMut()` is not satisfied + --> $DIR/const_closure-const_trait_impl-ice-113381.rs:15:5 + | +LL | (const || (()).foo())(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `call` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs index d0470fa34584..ee4ff02f4c7c 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs @@ -12,4 +12,5 @@ impl Foo for () { fn main() { (const || { (()).foo() })(); //~^ ERROR: }: [const] Fn()` is not satisfied + //~| ERROR: }: [const] FnMut()` is not satisfied } diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr index dcf65ab69408..69d289537da1 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr @@ -4,6 +4,15 @@ error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-cons LL | (const || { (()).foo() })(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:13:6: 13:14}: [const] FnMut()` is not satisfied + --> $DIR/non-const-op-const-closure-non-const-outer.rs:13:5 + | +LL | (const || { (()).foo() })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `call` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. From 033711ce8d011d7eed296917eb274232c3b45c34 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 23 Oct 2025 17:04:03 -0400 Subject: [PATCH 0060/3801] Stabilize `const_mul_add` Newly stable API: impl {f32, f64} { pub const fn mul_add(self, a: Self, b: Self) -> Self; } This includes making the intrinsics `fmaf{16,32,64,128}` const stable for indirect use, matching similar intrinsics. Closes: https://github.com/rust-lang/rust/issues/146724 --- library/core/src/intrinsics/mod.rs | 4 ++++ 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 - library/coretests/tests/lib.rs | 1 - library/std/src/lib.rs | 1 - library/std/src/num/f32.rs | 2 +- library/std/src/num/f64.rs | 2 +- 9 files changed, 6 insertions(+), 8 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index c397e762d558..eef147b9b506 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1310,6 +1310,7 @@ pub fn log2f128(x: f128) -> f128; /// /// The stabilized version of this intrinsic is /// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] pub const fn fmaf16(a: f16, b: f16, c: f16) -> f16; @@ -1317,6 +1318,7 @@ pub const fn fmaf16(a: f16, b: f16, c: f16) -> f16; /// /// The stabilized version of this intrinsic is /// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add) +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] pub const fn fmaf32(a: f32, b: f32, c: f32) -> f32; @@ -1324,6 +1326,7 @@ pub const fn fmaf32(a: f32, b: f32, c: f32) -> f32; /// /// The stabilized version of this intrinsic is /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] pub const fn fmaf64(a: f64, b: f64, c: f64) -> f64; @@ -1331,6 +1334,7 @@ pub const fn fmaf64(a: f64, b: f64, c: f64) -> f64; /// /// The stabilized version of this intrinsic is /// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] pub const fn fmaf128(a: f128, b: f128, c: f128) -> f128; diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index e7101537b298..09b89b2f7e8c 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1660,7 +1660,6 @@ impl f128 { #[doc(alias = "fmaf128", alias = "fusedMultiplyAdd")] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] pub const fn mul_add(self, a: f128, b: f128) -> f128 { intrinsics::fmaf128(self, a, b) } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index aa8342a22ad5..38165ce46692 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1635,7 +1635,6 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[doc(alias = "fmaf16", alias = "fusedMultiplyAdd")] #[must_use = "method returns a new number and does not mutate the original value"] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] pub const fn mul_add(self, a: f16, b: f16) -> f16 { intrinsics::fmaf16(self, a, b) } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 3070e1dedbe4..f4255ae75d3b 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1799,7 +1799,6 @@ pub mod math { #[doc(alias = "fmaf", alias = "fusedMultiplyAdd")] #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "core_float_math", issue = "137578")] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] pub const fn mul_add(x: f32, y: f32, z: f32) -> f32 { intrinsics::fmaf32(x, y, z) } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index dc8ccc551b2d..5a09ecd326ba 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1797,7 +1797,6 @@ pub mod math { #[doc(alias = "fma", alias = "fusedMultiplyAdd")] #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] pub const fn mul_add(x: f64, a: f64, b: f64) -> f64 { intrinsics::fmaf64(x, a, b) } diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 5c2522acb136..dee21a1fec91 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -22,7 +22,6 @@ #![feature(const_destruct)] #![feature(const_drop_in_place)] #![feature(const_eval_select)] -#![feature(const_mul_add)] #![feature(const_ops)] #![feature(const_option_ops)] #![feature(const_ref_cell)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 60c8f53a0cc4..eec5fc91cdfe 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -328,7 +328,6 @@ #![feature(char_internals)] #![feature(clone_to_uninit)] #![feature(const_convert)] -#![feature(const_mul_add)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] #![feature(drop_guard)] diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index c9e192201aff..ef288f967f71 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -217,7 +217,7 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + #[rustc_const_stable(feature = "const_mul_add", since = "CURRENT_RUSTC_VERSION")] pub const fn mul_add(self, a: f32, b: f32) -> f32 { core::f32::math::mul_add(self, a, b) } diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index 11874f9280f0..a62ec289591b 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -217,7 +217,7 @@ impl f64 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[rustc_const_unstable(feature = "const_mul_add", issue = "146724")] + #[rustc_const_stable(feature = "const_mul_add", since = "CURRENT_RUSTC_VERSION")] pub const fn mul_add(self, a: f64, b: f64) -> f64 { core::f64::math::mul_add(self, a, b) } From 482feee3118977db3731f1de171da7dfd043a864 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sat, 3 May 2025 22:58:27 -0600 Subject: [PATCH 0061/3801] refactor ub_checks and contract_checks to share logic --- src/base.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/base.rs b/src/base.rs index 7d50548b4026..6a1217a6a49b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -841,17 +841,8 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: fields.iter(), ) .bytes(), - NullOp::UbChecks => { - let val = fx.tcx.sess.ub_checks(); - let val = CValue::by_val( - fx.bcx.ins().iconst(types::I8, i64::from(val)), - fx.layout_of(fx.tcx.types.bool), - ); - lval.write_cvalue(fx, val); - return; - } - NullOp::ContractChecks => { - let val = fx.tcx.sess.contract_checks(); + NullOp::RuntimeChecks(kind) => { + let val = kind.value(fx.tcx.sess); let val = CValue::by_val( fx.bcx.ins().iconst(types::I8, i64::from(val)), fx.layout_of(fx.tcx.types.bool), From 562b485585a8da7fd0aee010d684a0c4663fafaa Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 7 Jul 2025 22:05:33 +0300 Subject: [PATCH 0062/3801] Provide a setting to disable showing rename conflicts --- .../crates/ide-assists/src/assist_config.rs | 6 +++ .../src/handlers/remove_underscore.rs | 4 +- .../crates/ide-assists/src/tests.rs | 4 ++ .../rust-analyzer/crates/ide-db/src/rename.rs | 53 ++++++++++++------- .../src/handlers/incorrect_case.rs | 7 ++- .../crates/ide-diagnostics/src/lib.rs | 7 +++ src/tools/rust-analyzer/crates/ide/src/lib.rs | 3 +- .../rust-analyzer/crates/ide/src/rename.rs | 21 ++++++-- .../rust-analyzer/src/cli/analysis_stats.rs | 1 + .../crates/rust-analyzer/src/config.rs | 6 +++ .../rust-analyzer/src/handlers/request.rs | 6 ++- .../src/integrated_benchmarks.rs | 1 + .../docs/book/src/configuration_generated.md | 7 +++ .../rust-analyzer/editors/code/package.json | 10 ++++ 14 files changed, 108 insertions(+), 28 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs index 7d5070ace619..636acf3f0088 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs @@ -9,6 +9,7 @@ use ide_db::{ SnippetCap, assists::ExprFillDefaultMode, imports::{import_assets::ImportPathConfig, insert_use::InsertUseConfig}, + rename::RenameConfig, }; use crate::AssistKind; @@ -27,6 +28,7 @@ pub struct AssistConfig { pub code_action_grouping: bool, pub expr_fill_default: ExprFillDefaultMode, pub prefer_self_ty: bool, + pub show_rename_conflicts: bool, } impl AssistConfig { @@ -46,4 +48,8 @@ impl AssistConfig { allow_unstable, } } + + pub fn rename_config(&self) -> RenameConfig { + RenameConfig { show_conflicts: self.show_rename_conflicts } + } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs index a8e27416d5ce..1de1c15cf720 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs @@ -62,7 +62,9 @@ pub(crate) fn remove_underscore(acc: &mut Assists, ctx: &AssistContext<'_>) -> O "Remove underscore from a used variable", text_range, |builder| { - let changes = def.rename(&ctx.sema, new_name, RenameDefinition::Yes).unwrap(); + let changes = def + .rename(&ctx.sema, new_name, RenameDefinition::Yes, &ctx.config.rename_config()) + .unwrap(); builder.source_change = changes; }, ) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs index ade60691b57b..112619119269 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs @@ -38,6 +38,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig { code_action_grouping: true, expr_fill_default: ExprFillDefaultMode::Todo, prefer_self_ty: false, + show_rename_conflicts: true, }; pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig { @@ -59,6 +60,7 @@ pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig { code_action_grouping: false, expr_fill_default: ExprFillDefaultMode::Todo, prefer_self_ty: false, + show_rename_conflicts: true, }; pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig { @@ -80,6 +82,7 @@ pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig { code_action_grouping: true, expr_fill_default: ExprFillDefaultMode::Todo, prefer_self_ty: false, + show_rename_conflicts: true, }; pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig { @@ -101,6 +104,7 @@ pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig { code_action_grouping: true, expr_fill_default: ExprFillDefaultMode::Todo, prefer_self_ty: false, + show_rename_conflicts: true, }; fn assists( diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index a8800c142a22..aeb7c06582bc 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -45,6 +45,11 @@ use crate::{ traits::convert_to_def_in_trait, }; +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct RenameConfig { + pub show_conflicts: bool, +} + pub type Result = std::result::Result; #[derive(Debug)] @@ -81,6 +86,7 @@ impl Definition { sema: &Semantics<'_, RootDatabase>, new_name: &str, rename_definition: RenameDefinition, + config: &RenameConfig, ) -> Result { // self.krate() returns None if // self is a built-in attr, built-in type or tool module. @@ -109,10 +115,15 @@ impl Definition { bail!("Cannot rename a builtin attr.") } Definition::SelfType(_) => bail!("Cannot rename `Self`"), - Definition::Macro(mac) => { - rename_reference(sema, Definition::Macro(mac), new_name, rename_definition, edition) - } - def => rename_reference(sema, def, new_name, rename_definition, edition), + Definition::Macro(mac) => rename_reference( + sema, + Definition::Macro(mac), + new_name, + rename_definition, + edition, + config, + ), + def => rename_reference(sema, def, new_name, rename_definition, edition, config), } } @@ -338,6 +349,7 @@ fn rename_reference( new_name: &str, rename_definition: RenameDefinition, edition: Edition, + config: &RenameConfig, ) -> Result { let (mut new_name, ident_kind) = IdentifierKind::classify(edition, new_name)?; @@ -396,7 +408,8 @@ fn rename_reference( if rename_definition == RenameDefinition::Yes { // This needs to come after the references edits, because we change the annotation of existing edits // if a conflict is detected. - let (file_id, edit) = source_edit_from_def(sema, def, &new_name, &mut source_change)?; + let (file_id, edit) = + source_edit_from_def(sema, config, def, &new_name, &mut source_change)?; source_change.insert_source_edit(file_id, edit); } Ok(source_change) @@ -554,6 +567,7 @@ fn source_edit_from_name_ref( fn source_edit_from_def( sema: &Semantics<'_, RootDatabase>, + config: &RenameConfig, def: Definition, new_name: &Name, source_change: &mut SourceChange, @@ -562,21 +576,22 @@ fn source_edit_from_def( if let Definition::Local(local) = def { let mut file_id = None; - let conflict_annotation = if !sema.rename_conflicts(&local, new_name).is_empty() { - Some( - source_change.insert_annotation(ChangeAnnotation { - label: "This rename will change the program's meaning".to_owned(), - needs_confirmation: true, - description: Some( - "Some variable(s) will shadow the renamed variable \ + let conflict_annotation = + if config.show_conflicts && !sema.rename_conflicts(&local, new_name).is_empty() { + Some( + source_change.insert_annotation(ChangeAnnotation { + label: "This rename will change the program's meaning".to_owned(), + needs_confirmation: true, + description: Some( + "Some variable(s) will shadow the renamed variable \ or be shadowed by it if the rename is performed" - .to_owned(), - ), - }), - ) - } else { - None - }; + .to_owned(), + ), + }), + ) + } else { + None + }; for source in local.sources(sema.db) { let source = match source.source.clone().original_ast_node_rooted(sema.db) { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs index 519ff192799d..f52e575133fb 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs @@ -44,7 +44,12 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Option RenameConfig { + RenameConfig { show_conflicts: self.show_rename_conflicts } + } } struct DiagnosticsContext<'a> { diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index ece5bac6df4b..0cb0d33259df 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -846,8 +846,9 @@ impl Analysis { &self, file_id: FileId, new_name_stem: &str, + config: &RenameConfig, ) -> Cancellable> { - self.with_db(|db| rename::will_rename_file(db, file_id, new_name_stem)) + self.with_db(|db| rename::will_rename_file(db, file_id, new_name_stem, config)) } pub fn structural_search_replace( diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index ce5963919d9a..59343f494a02 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -31,6 +31,7 @@ pub struct RenameConfig { pub prefer_no_std: bool, pub prefer_prelude: bool, pub prefer_absolute: bool, + pub show_conflicts: bool, } impl RenameConfig { @@ -42,6 +43,10 @@ impl RenameConfig { allow_unstable: true, } } + + fn ide_db_config(&self) -> ide_db::rename::RenameConfig { + ide_db::rename::RenameConfig { show_conflicts: self.show_conflicts } + } } /// This is similar to `collect::, _>>`, but unlike it, it succeeds if there is *any* `Ok` item. @@ -190,7 +195,7 @@ pub(crate) fn rename( return rename_to_self(&sema, local); } } - def.rename(&sema, new_name.as_str(), rename_def) + def.rename(&sema, new_name.as_str(), rename_def, &config.ide_db_config()) })), }; @@ -205,11 +210,13 @@ pub(crate) fn will_rename_file( db: &RootDatabase, file_id: FileId, new_name_stem: &str, + config: &RenameConfig, ) -> Option { let sema = Semantics::new(db); let module = sema.file_to_module_def(file_id)?; let def = Definition::Module(module); - let mut change = def.rename(&sema, new_name_stem, RenameDefinition::Yes).ok()?; + let mut change = + def.rename(&sema, new_name_stem, RenameDefinition::Yes, &config.ide_db_config()).ok()?; change.file_system_edits.clear(); Some(change) } @@ -803,8 +810,12 @@ mod tests { use super::{RangeInfo, RenameConfig, RenameError}; - const TEST_CONFIG: RenameConfig = - RenameConfig { prefer_no_std: false, prefer_prelude: true, prefer_absolute: false }; + const TEST_CONFIG: RenameConfig = RenameConfig { + prefer_no_std: false, + prefer_prelude: true, + prefer_absolute: false, + show_conflicts: true, + }; #[track_caller] fn check( @@ -893,7 +904,7 @@ mod tests { ) { let (analysis, position) = fixture::position(ra_fixture); let source_change = analysis - .will_rename_file(position.file_id, new_name) + .will_rename_file(position.file_id, new_name, &TEST_CONFIG) .unwrap() .expect("Expect returned a RenameError"); expect.assert_eq(&filter_expect(source_change)) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index de24bc09ff0f..9d3756e64103 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -1153,6 +1153,7 @@ impl flags::AnalysisStats { style_lints: false, term_search_fuel: 400, term_search_borrowck: true, + show_rename_conflicts: true, }, ide::AssistResolveStrategy::All, analysis.editioned_file_id_to_vfs(file_id), diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 6d2907ee56aa..295e45352728 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -707,6 +707,9 @@ config_data! { /// /// E.g. `use ::std::io::Read;`. imports_prefixExternPrelude: bool = false, + + /// Whether to warn when a rename will cause conflicts (change the meaning of the code). + rename_showConflicts: bool = true, } } @@ -1702,6 +1705,7 @@ impl Config { ExprFillDefaultDef::Underscore => ExprFillDefaultMode::Underscore, }, prefer_self_ty: *self.assist_preferSelf(source_root), + show_rename_conflicts: *self.rename_showConflicts(source_root), } } @@ -1710,6 +1714,7 @@ impl Config { prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(), + show_conflicts: *self.rename_showConflicts(source_root), } } @@ -1809,6 +1814,7 @@ impl Config { style_lints: self.diagnostics_styleLints_enable(source_root).to_owned(), term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64, term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(), + show_rename_conflicts: *self.rename_showConflicts(source_root), } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 2976441d762a..773729be78b3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -787,7 +787,11 @@ pub(crate) fn handle_will_rename_files( } }) .filter_map(|(file_id, new_name)| { - snap.analysis.will_rename_file(file_id?, &new_name).ok()? + let file_id = file_id?; + let source_root = snap.analysis.source_root_id(file_id).ok(); + snap.analysis + .will_rename_file(file_id, &new_name, &snap.config.rename(source_root)) + .ok()? }) .collect(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs index 38ee9cbe7fc8..c61825b99fec 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs @@ -363,6 +363,7 @@ fn integrated_diagnostics_benchmark() { prefer_absolute: false, term_search_fuel: 400, term_search_borrowck: true, + show_rename_conflicts: true, }; host.analysis() .full_diagnostics(&diagnostics_config, ide::AssistResolveStrategy::None, file_id) diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index d768993f501f..227282f192bd 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1303,6 +1303,13 @@ Default: `false` Exclude tests from find-all-references and call-hierarchy. +## rust-analyzer.rename.showConflicts {#rename.showConflicts} + +Default: `true` + +Whether to warn when a rename will cause conflicts (change the meaning of the code). + + ## rust-analyzer.runnables.command {#runnables.command} Default: `null` diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index d659421a0299..f0414c962295 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -2769,6 +2769,16 @@ } } }, + { + "title": "Rename", + "properties": { + "rust-analyzer.rename.showConflicts": { + "markdownDescription": "Whether to warn when a rename will cause conflicts (change the meaning of the code).", + "default": true, + "type": "boolean" + } + } + }, { "title": "Runnables", "properties": { From 664875e01d69ead828d9bcc7389af6297060a0e1 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Tue, 21 Oct 2025 20:22:48 +0000 Subject: [PATCH 0063/3801] fix: `if_not_else` wrong unmangled macros --- clippy_lints/src/if_not_else.rs | 37 ++++++++++++++++----------- tests/ui/if_not_else.fixed | 17 +++++++++++++ tests/ui/if_not_else.rs | 17 +++++++++++++ tests/ui/if_not_else.stderr | 44 ++++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/if_not_else.rs b/clippy_lints/src/if_not_else.rs index 54e9538fcb99..ff22ba4fcd0d 100644 --- a/clippy_lints/src/if_not_else.rs +++ b/clippy_lints/src/if_not_else.rs @@ -1,7 +1,7 @@ use clippy_utils::consts::is_zero_integer_const; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::is_else_clause; -use clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet}; +use clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet_with_context}; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; @@ -78,6 +78,7 @@ impl LateLintPass<'_> for IfNotElse { // } // ``` if !e.span.from_expansion() && !is_else_clause(cx.tcx, e) { + let mut applicability = Applicability::MachineApplicable; match cond.kind { ExprKind::Unary(UnOp::Not, _) | ExprKind::Binary(_, _, _) => span_lint_and_sugg( cx, @@ -85,8 +86,16 @@ impl LateLintPass<'_> for IfNotElse { e.span, msg, "try", - make_sugg(cx, &cond.kind, cond_inner.span, els.span, "..", Some(e.span)), - Applicability::MachineApplicable, + make_sugg( + cx, + e.span, + &cond.kind, + cond_inner.span, + els.span, + "..", + &mut applicability, + ), + applicability, ), _ => span_lint_and_help(cx, IF_NOT_ELSE, e.span, msg, None, help), } @@ -97,28 +106,26 @@ impl LateLintPass<'_> for IfNotElse { fn make_sugg<'a>( sess: &impl HasSession, + expr_span: Span, cond_kind: &'a ExprKind<'a>, cond_inner: Span, els_span: Span, default: &'a str, - indent_relative_to: Option, + applicability: &mut Applicability, ) -> String { - let cond_inner_snip = snippet(sess, cond_inner, default); - let els_snip = snippet(sess, els_span, default); - let indent = indent_relative_to.and_then(|s| indent_of(sess, s)); + let (cond_inner_snip, _) = snippet_with_context(sess, cond_inner, expr_span.ctxt(), default, applicability); + let (els_snip, _) = snippet_with_context(sess, els_span, expr_span.ctxt(), default, applicability); + let indent = indent_of(sess, expr_span); let suggestion = match cond_kind { ExprKind::Unary(UnOp::Not, cond_rest) => { - format!( - "if {} {} else {}", - snippet(sess, cond_rest.span, default), - els_snip, - cond_inner_snip - ) + let (cond_rest_snip, _) = + snippet_with_context(sess, cond_rest.span, expr_span.ctxt(), default, applicability); + format!("if {cond_rest_snip} {els_snip} else {cond_inner_snip}") }, ExprKind::Binary(_, lhs, rhs) => { - let lhs_snip = snippet(sess, lhs.span, default); - let rhs_snip = snippet(sess, rhs.span, default); + let (lhs_snip, _) = snippet_with_context(sess, lhs.span, expr_span.ctxt(), default, applicability); + let (rhs_snip, _) = snippet_with_context(sess, rhs.span, expr_span.ctxt(), default, applicability); format!("if {lhs_snip} == {rhs_snip} {els_snip} else {cond_inner_snip}") }, diff --git a/tests/ui/if_not_else.fixed b/tests/ui/if_not_else.fixed index 4e6f43e5671e..a29847f0cf97 100644 --- a/tests/ui/if_not_else.fixed +++ b/tests/ui/if_not_else.fixed @@ -76,3 +76,20 @@ fn with_annotations() { println!("foo is false"); } } + +fn issue15924() { + let x = 0; + if matches!(x, 0..10) { + println!(":("); + } else { + //~^ if_not_else + println!(":)"); + } + + if dbg!(x) == 1 { + println!(":("); + } else { + //~^ if_not_else + println!(":)"); + } +} diff --git a/tests/ui/if_not_else.rs b/tests/ui/if_not_else.rs index 6cd2e3bd63fe..4ae11d6ad90e 100644 --- a/tests/ui/if_not_else.rs +++ b/tests/ui/if_not_else.rs @@ -76,3 +76,20 @@ fn with_annotations() { println!("foo"); /* foo */ } } + +fn issue15924() { + let x = 0; + if !matches!(x, 0..10) { + //~^ if_not_else + println!(":)"); + } else { + println!(":("); + } + + if dbg!(x) != 1 { + //~^ if_not_else + println!(":)"); + } else { + println!(":("); + } +} diff --git a/tests/ui/if_not_else.stderr b/tests/ui/if_not_else.stderr index 824837bd52bb..0682bf80da55 100644 --- a/tests/ui/if_not_else.stderr +++ b/tests/ui/if_not_else.stderr @@ -147,5 +147,47 @@ LL + println!("foo is false"); LL + } | -error: aborting due to 6 previous errors +error: unnecessary boolean `not` operation + --> tests/ui/if_not_else.rs:82:5 + | +LL | / if !matches!(x, 0..10) { +LL | | +LL | | println!(":)"); +LL | | } else { +LL | | println!(":("); +LL | | } + | |_____^ + | +help: try + | +LL ~ if matches!(x, 0..10) { +LL + println!(":("); +LL + } else { +LL + +LL + println!(":)"); +LL + } + | + +error: unnecessary `!=` operation + --> tests/ui/if_not_else.rs:89:5 + | +LL | / if dbg!(x) != 1 { +LL | | +LL | | println!(":)"); +LL | | } else { +LL | | println!(":("); +LL | | } + | |_____^ + | +help: try + | +LL ~ if dbg!(x) == 1 { +LL + println!(":("); +LL + } else { +LL + +LL + println!(":)"); +LL + } + | + +error: aborting due to 8 previous errors From 96ac0996a0d41e80536343bc861b2cda6d54d8d5 Mon Sep 17 00:00:00 2001 From: yanglsh Date: Tue, 2 Sep 2025 00:40:54 +0800 Subject: [PATCH 0064/3801] fix: `nonstandard_macro_braces` FN on macros with empty args --- clippy_lints/src/nonstandard_macro_braces.rs | 38 +++++++++------- .../conf_nonstandard_macro_braces.fixed | 14 ++++++ .../conf_nonstandard_macro_braces.rs | 14 ++++++ .../conf_nonstandard_macro_braces.stderr | 44 ++++++++++++++----- 4 files changed, 84 insertions(+), 26 deletions(-) diff --git a/clippy_lints/src/nonstandard_macro_braces.rs b/clippy_lints/src/nonstandard_macro_braces.rs index 3a8a4dd0c713..8970970f4b47 100644 --- a/clippy_lints/src/nonstandard_macro_braces.rs +++ b/clippy_lints/src/nonstandard_macro_braces.rs @@ -115,35 +115,41 @@ impl EarlyLintPass for MacroBraces { } fn is_offending_macro(cx: &EarlyContext<'_>, span: Span, mac_braces: &MacroBraces) -> Option { - let unnested_or_local = || { - !span.ctxt().outer_expn_data().call_site.from_expansion() + let unnested_or_local = |span: Span| { + !span.from_expansion() || span .macro_backtrace() .last() .is_some_and(|e| e.macro_def_id.is_some_and(DefId::is_local)) }; - let callsite_span = span.ctxt().outer_expn_data().call_site; - if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span.ctxt().outer_expn_data().kind + + let mut ctxt = span.ctxt(); + while !ctxt.is_root() { + let expn_data = ctxt.outer_expn_data(); + if let ExpnKind::Macro(MacroKind::Bang, mac_name) = expn_data.kind && let name = mac_name.as_str() && let Some(&braces) = mac_braces.macro_braces.get(name) - && let Some(snip) = callsite_span.get_source_text(cx) + && let Some(snip) = expn_data.call_site.get_source_text(cx) // we must check only invocation sites // https://github.com/rust-lang/rust-clippy/issues/7422 && let Some(macro_args_str) = snip.strip_prefix(name).and_then(|snip| snip.strip_prefix('!')) && let Some(old_open_brace @ ('{' | '(' | '[')) = macro_args_str.trim_start().chars().next() && old_open_brace != braces.0 - && unnested_or_local() - && !mac_braces.done.contains(&callsite_span) - { - Some(MacroInfo { - callsite_span, - callsite_snippet: snip, - old_open_brace, - braces, - }) - } else { - None + && unnested_or_local(expn_data.call_site) + && !mac_braces.done.contains(&expn_data.call_site) + { + return Some(MacroInfo { + callsite_span: expn_data.call_site, + callsite_snippet: snip, + old_open_brace, + braces, + }); + } + + ctxt = expn_data.call_site.ctxt(); } + + None } fn emit_help(cx: &EarlyContext<'_>, snip: &str, (open, close): (char, char), span: Span, add_semi: bool) { diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed index 419e62f92f46..3683e826aa92 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed @@ -1,6 +1,7 @@ //@aux-build:proc_macro_derive.rs #![warn(clippy::nonstandard_macro_braces)] +#![allow(clippy::println_empty_string)] extern crate proc_macro_derive; extern crate quote; @@ -75,3 +76,16 @@ fn issue9913() { [0]; // separate statement, not indexing into the result of println. //~^^ nonstandard_macro_braces } + +fn issue15594() { + println!(); + println!(""); + println!(); + //~^ nonstandard_macro_braces + println!(""); + //~^ nonstandard_macro_braces + println!(); + //~^ nonstandard_macro_braces + println!(""); + //~^ nonstandard_macro_braces +} diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs index b0bbced4ea3c..c1779dceff17 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs @@ -1,6 +1,7 @@ //@aux-build:proc_macro_derive.rs #![warn(clippy::nonstandard_macro_braces)] +#![allow(clippy::println_empty_string)] extern crate proc_macro_derive; extern crate quote; @@ -75,3 +76,16 @@ fn issue9913() { [0]; // separate statement, not indexing into the result of println. //~^^ nonstandard_macro_braces } + +fn issue15594() { + println!(); + println!(""); + println![]; + //~^ nonstandard_macro_braces + println![""]; + //~^ nonstandard_macro_braces + println! {}; + //~^ nonstandard_macro_braces + println! {""}; + //~^ nonstandard_macro_braces +} diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr index 87325f05c9bc..2488f7fa01e5 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr @@ -1,5 +1,5 @@ error: use of irregular braces for `vec!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:44:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:45:13 | LL | let _ = vec! {1, 2, 3}; | ^^^^^^^^^^^^^^ help: consider writing: `vec![1, 2, 3]` @@ -8,31 +8,31 @@ LL | let _ = vec! {1, 2, 3}; = help: to override `-D warnings` add `#[allow(clippy::nonstandard_macro_braces)]` error: use of irregular braces for `format!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:46:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:47:13 | LL | let _ = format!["ugh {} stop being such a good compiler", "hello"]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `format!("ugh {} stop being such a good compiler", "hello")` error: use of irregular braces for `matches!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:48:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:49:13 | LL | let _ = matches!{{}, ()}; | ^^^^^^^^^^^^^^^^ help: consider writing: `matches!({}, ())` error: use of irregular braces for `quote!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:50:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:51:13 | LL | let _ = quote!(let x = 1;); | ^^^^^^^^^^^^^^^^^^ help: consider writing: `quote!{let x = 1;}` error: use of irregular braces for `quote::quote!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:52:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:53:13 | LL | let _ = quote::quote!(match match match); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `quote::quote!{match match match}` error: use of irregular braces for `vec!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:18:9 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:19:9 | LL | vec!{0, 0, 0} | ^^^^^^^^^^^^^ help: consider writing: `vec![0, 0, 0]` @@ -43,22 +43,46 @@ LL | let _ = test!(); // trigger when macro def is inside our own crate = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error: use of irregular braces for `type_pos!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:62:12 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:63:12 | LL | let _: type_pos!(usize) = vec![]; | ^^^^^^^^^^^^^^^^ help: consider writing: `type_pos![usize]` error: use of irregular braces for `eprint!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:65:5 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:66:5 | LL | eprint!("test if user config overrides defaults"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `eprint!["test if user config overrides defaults"]` error: use of irregular braces for `println!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:74:5 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:75:5 | LL | println! {"hello world"} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `println!("hello world");` -error: aborting due to 9 previous errors +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:83:5 + | +LL | println![]; + | ^^^^^^^^^^ help: consider writing: `println!()` + +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:85:5 + | +LL | println![""]; + | ^^^^^^^^^^^^ help: consider writing: `println!("")` + +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:87:5 + | +LL | println! {}; + | ^^^^^^^^^^^ help: consider writing: `println!()` + +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:89:5 + | +LL | println! {""}; + | ^^^^^^^^^^^^^ help: consider writing: `println!("")` + +error: aborting due to 13 previous errors From 061617bdbcaa49bb5c4456c0c5264d0849afe4b1 Mon Sep 17 00:00:00 2001 From: sayantn Date: Wed, 8 Oct 2025 08:12:09 +0530 Subject: [PATCH 0065/3801] Add alignment parameter to `simd_masked_{load,store}` --- crates/core_simd/src/vector.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index d76a6cd52bfc..f40031f8c4da 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -474,7 +474,14 @@ where or: Self, ) -> Self { // SAFETY: The safety of reading elements through `ptr` is ensured by the caller. - unsafe { core::intrinsics::simd::simd_masked_load(enable.to_int(), ptr, or) } + unsafe { + core::intrinsics::simd::simd_masked_load::< + _, + _, + _, + { core::intrinsics::simd::SimdAlign::Element }, + >(enable.to_int(), ptr, or) + } } /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector. @@ -723,7 +730,14 @@ where #[inline] pub unsafe fn store_select_ptr(self, ptr: *mut T, enable: Mask<::Mask, N>) { // SAFETY: The safety of writing elements through `ptr` is ensured by the caller. - unsafe { core::intrinsics::simd::simd_masked_store(enable.to_int(), ptr, self) } + unsafe { + core::intrinsics::simd::simd_masked_store::< + _, + _, + _, + { core::intrinsics::simd::SimdAlign::Element }, + >(enable.to_int(), ptr, self) + } } /// Writes the values in a SIMD vector to potentially discontiguous indices in `slice`. From dc3ab70b58ecc619dbebef3433f4af6d07e219fa Mon Sep 17 00:00:00 2001 From: Jeremy Smart Date: Tue, 4 Nov 2025 11:38:45 -0500 Subject: [PATCH 0066/3801] add Option::into_flat_iter --- library/core/src/option.rs | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index e3c4758bc6af..8fe3c0c4d351 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2007,6 +2007,30 @@ impl Option { } } +impl Option { + /// Transforms an optional iterator into an iterator. + /// + /// If `self` is `None`, the resulting iterator is empty. + /// Otherwise, an iterator is made from the `Some` value and returned. + /// # Examples + /// ``` + /// #![feature(option_into_flat_iter)] + /// + /// let o1 = Some([1, 2]); + /// let o2 = None::<&[usize]>; + /// + /// assert_eq!(o1.into_flat_iter().collect::>(), [1, 2]); + /// assert_eq!(o2.into_flat_iter().collect::>(), Vec::<&usize>::new()); + /// ``` + #[unstable(feature = "option_into_flat_iter", issue = "148441")] + pub fn into_flat_iter(self) -> OptionFlatten + where + T: IntoIterator, + { + OptionFlatten { iter: self.map(IntoIterator::into_iter) } + } +} + impl Option<(T, U)> { /// Unzips an option containing a tuple of two options. /// @@ -2569,6 +2593,42 @@ impl FusedIterator for IntoIter {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for IntoIter {} +/// The iterator produced by [`Option::into_flat_iter`]. See its documentation for more. +#[derive(Clone, Debug)] +#[unstable(feature = "option_into_flat_iter", issue = "148441")] +pub struct OptionFlatten { + iter: Option, +} + +#[unstable(feature = "option_into_flat_iter", issue = "148441")] +impl Iterator for OptionFlatten { + type Item = A::Item; + + fn next(&mut self) -> Option { + self.iter.as_mut()?.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.as_ref().map(|i| i.size_hint()).unwrap_or((0, Some(0))) + } +} + +#[unstable(feature = "option_into_flat_iter", issue = "148441")] +impl DoubleEndedIterator for OptionFlatten { + fn next_back(&mut self) -> Option { + self.iter.as_mut()?.next_back() + } +} + +#[unstable(feature = "option_into_flat_iter", issue = "148441")] +impl ExactSizeIterator for OptionFlatten {} + +#[unstable(feature = "option_into_flat_iter", issue = "148441")] +impl FusedIterator for OptionFlatten {} + +#[unstable(feature = "option_into_flat_iter", issue = "148441")] +unsafe impl TrustedLen for OptionFlatten {} + ///////////////////////////////////////////////////////////////////////////// // FromIterator ///////////////////////////////////////////////////////////////////////////// From d160cb7313fb07d85ad57b99a98106211684c270 Mon Sep 17 00:00:00 2001 From: "Ian D. Bollinger" Date: Tue, 4 Nov 2025 13:00:02 -0500 Subject: [PATCH 0067/3801] `double_comparison`: add missing cases Add checks for expressions such as `x != y && x >= y` and `x != y && x <= y`. --- .../src/operators/double_comparison.rs | 12 +++++++++ tests/ui/double_comparison.fixed | 16 ++++++++++++ tests/ui/double_comparison.rs | 16 ++++++++++++ tests/ui/double_comparison.stderr | 26 ++++++++++++++++++- 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/operators/double_comparison.rs b/clippy_lints/src/operators/double_comparison.rs index 71982023779e..a40a724d2da5 100644 --- a/clippy_lints/src/operators/double_comparison.rs +++ b/clippy_lints/src/operators/double_comparison.rs @@ -39,6 +39,18 @@ pub(super) fn check(cx: &LateContext<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &E | (BinOpKind::And, BinOpKind::Ge, BinOpKind::Le) => { "==" }, + // x != y && x >= y => x > y + (BinOpKind::And, BinOpKind::Ne, BinOpKind::Ge) + // x >= y && x != y => x > y + | (BinOpKind::And, BinOpKind::Ge, BinOpKind::Ne) => { + ">" + }, + // x != y && x <= y => x < y + (BinOpKind::And, BinOpKind::Ne, BinOpKind::Le) + // x <= y && x != y => x < y + | (BinOpKind::And, BinOpKind::Le, BinOpKind::Ne) => { + "<" + }, _ => return, }; diff --git a/tests/ui/double_comparison.fixed b/tests/ui/double_comparison.fixed index 0680eb35ef97..29047b8a31cb 100644 --- a/tests/ui/double_comparison.fixed +++ b/tests/ui/double_comparison.fixed @@ -35,4 +35,20 @@ fn main() { //~^ double_comparisons // do something } + if x < y { + //~^ double_comparisons + // do something + } + if x < y { + //~^ double_comparisons + // do something + } + if x > y { + //~^ double_comparisons + // do something + } + if x > y { + //~^ double_comparisons + // do something + } } diff --git a/tests/ui/double_comparison.rs b/tests/ui/double_comparison.rs index 18ab7d2c4254..13edb2a996a1 100644 --- a/tests/ui/double_comparison.rs +++ b/tests/ui/double_comparison.rs @@ -35,4 +35,20 @@ fn main() { //~^ double_comparisons // do something } + if x != y && x <= y { + //~^ double_comparisons + // do something + } + if x <= y && x != y { + //~^ double_comparisons + // do something + } + if x != y && x >= y { + //~^ double_comparisons + // do something + } + if x >= y && x != y { + //~^ double_comparisons + // do something + } } diff --git a/tests/ui/double_comparison.stderr b/tests/ui/double_comparison.stderr index 984614c203eb..be7eba611cb0 100644 --- a/tests/ui/double_comparison.stderr +++ b/tests/ui/double_comparison.stderr @@ -49,5 +49,29 @@ error: this binary expression can be simplified LL | if x >= y && x <= y { | ^^^^^^^^^^^^^^^^ help: try: `x == y` -error: aborting due to 8 previous errors +error: this binary expression can be simplified + --> tests/ui/double_comparison.rs:38:8 + | +LL | if x != y && x <= y { + | ^^^^^^^^^^^^^^^^ help: try: `x < y` + +error: this binary expression can be simplified + --> tests/ui/double_comparison.rs:42:8 + | +LL | if x <= y && x != y { + | ^^^^^^^^^^^^^^^^ help: try: `x < y` + +error: this binary expression can be simplified + --> tests/ui/double_comparison.rs:46:8 + | +LL | if x != y && x >= y { + | ^^^^^^^^^^^^^^^^ help: try: `x > y` + +error: this binary expression can be simplified + --> tests/ui/double_comparison.rs:50:8 + | +LL | if x >= y && x != y { + | ^^^^^^^^^^^^^^^^ help: try: `x > y` + +error: aborting due to 12 previous errors From 1a5576dcd25224035336ff80780f9fc426f32cb1 Mon Sep 17 00:00:00 2001 From: alexey semenyuk Date: Thu, 6 Nov 2025 00:13:26 +0500 Subject: [PATCH 0068/3801] Upgrade Node.js setup action and version --- .github/workflows/remark.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/remark.yml b/.github/workflows/remark.yml index c2cc48ab9511..980379a6c6ad 100644 --- a/.github/workflows/remark.yml +++ b/.github/workflows/remark.yml @@ -17,9 +17,9 @@ jobs: persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: - node-version: '20.x' + node-version: '24.x' - name: Install remark run: npm install remark-cli remark-lint remark-lint-maximum-line-length@^3.1.3 remark-preset-lint-recommended remark-gfm From 8785dd6689f6d662d025563560628d20827ce38c Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 8 Nov 2025 21:15:45 +0800 Subject: [PATCH 0069/3801] Add ide-assist: add_explicit_method_call_deref Insert explicit method call reference and dereferences. Example --- ```rust struct Foo; impl Foo { fn foo(&self) {} } fn test() { Foo$0.$0foo(); } ``` -> ```rust struct Foo; impl Foo { fn foo(&self) {} } fn test() { (&Foo).foo(); } ``` --- .../src/handlers/add_explicit_dot_deref.rs | 214 ++++++++++++++++++ .../crates/ide-assists/src/lib.rs | 2 + .../crates/ide-assists/src/tests/generated.rs | 21 ++ .../crates/syntax/src/ast/make.rs | 7 + .../src/ast/syntax_factory/constructors.rs | 16 ++ 5 files changed, 260 insertions(+) create mode 100644 src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_dot_deref.rs diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_dot_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_dot_deref.rs new file mode 100644 index 000000000000..d27a6b4ce770 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_dot_deref.rs @@ -0,0 +1,214 @@ +use hir::{Adjust, Mutability}; +use ide_db::assists::AssistId; +use itertools::Itertools; +use syntax::{ + AstNode, T, + ast::{self, syntax_factory::SyntaxFactory}, +}; + +use crate::{AssistContext, Assists}; + +// Assist: add_explicit_method_call_deref +// +// Insert explicit method call reference and dereferences. +// +// ``` +// struct Foo; +// impl Foo { fn foo(&self) {} } +// fn test() { +// Foo$0.$0foo(); +// } +// ``` +// -> +// ``` +// struct Foo; +// impl Foo { fn foo(&self) {} } +// fn test() { +// (&Foo).foo(); +// } +// ``` +pub(crate) fn add_explicit_method_call_deref( + acc: &mut Assists, + ctx: &AssistContext<'_>, +) -> Option<()> { + if ctx.has_empty_selection() { + return None; + } + let dot_token = ctx.find_token_syntax_at_offset(T![.])?; + if ctx.selection_trimmed() != dot_token.text_range() { + return None; + } + let method_call_expr = dot_token.parent().and_then(ast::MethodCallExpr::cast)?; + let receiver = method_call_expr.receiver()?; + + let adjustments = ctx.sema.expr_adjustments(&receiver)?; + let adjustments = + adjustments.into_iter().filter_map(|adjust| simple_adjust_kind(adjust.kind)).collect_vec(); + if adjustments.is_empty() { + return None; + } + + acc.add( + AssistId::refactor_rewrite("add_explicit_method_call_deref"), + "Insert explicit method call derefs", + dot_token.text_range(), + |builder| { + let mut edit = builder.make_editor(method_call_expr.syntax()); + let make = SyntaxFactory::without_mappings(); + let mut expr = receiver.clone(); + + for adjust_kind in adjustments { + expr = adjust_kind.wrap_expr(expr, &make); + } + + expr = make.expr_paren(expr).into(); + edit.replace(receiver.syntax(), expr.syntax()); + + builder.add_file_edits(ctx.vfs_file_id(), edit); + }, + ) +} + +fn simple_adjust_kind(adjust: Adjust) -> Option { + match adjust { + Adjust::NeverToAny | Adjust::Pointer(_) => None, + Adjust::Deref(_) => Some(AdjustKind::Deref), + Adjust::Borrow(hir::AutoBorrow::Ref(mutability)) => Some(AdjustKind::Ref(mutability)), + Adjust::Borrow(hir::AutoBorrow::RawPtr(mutability)) => Some(AdjustKind::RefRaw(mutability)), + } +} + +enum AdjustKind { + Deref, + Ref(Mutability), + RefRaw(Mutability), +} + +impl AdjustKind { + fn wrap_expr(self, expr: ast::Expr, make: &SyntaxFactory) -> ast::Expr { + match self { + AdjustKind::Deref => make.expr_prefix(T![*], expr).into(), + AdjustKind::Ref(mutability) => make.expr_ref(expr, mutability.is_mut()), + AdjustKind::RefRaw(mutability) => make.expr_raw_ref(expr, mutability.is_mut()), + } + } +} + +#[cfg(test)] +mod tests { + use crate::tests::check_assist; + + use super::*; + + #[test] + fn works_ref() { + check_assist( + add_explicit_method_call_deref, + r#" + struct Foo; + impl Foo { fn foo(&self) {} } + fn test() { + Foo$0.$0foo(); + }"#, + r#" + struct Foo; + impl Foo { fn foo(&self) {} } + fn test() { + (&Foo).foo(); + }"#, + ); + } + + #[test] + fn works_ref_mut() { + check_assist( + add_explicit_method_call_deref, + r#" + struct Foo; + impl Foo { fn foo(&mut self) {} } + fn test() { + Foo$0.$0foo(); + }"#, + r#" + struct Foo; + impl Foo { fn foo(&mut self) {} } + fn test() { + (&mut Foo).foo(); + }"#, + ); + } + + #[test] + fn works_deref() { + check_assist( + add_explicit_method_call_deref, + r#" + struct Foo; + impl Foo { fn foo(self) {} } + fn test() { + let foo = &Foo; + foo$0.$0foo(); + }"#, + r#" + struct Foo; + impl Foo { fn foo(self) {} } + fn test() { + let foo = &Foo; + (*foo).foo(); + }"#, + ); + } + + #[test] + fn works_reborrow() { + check_assist( + add_explicit_method_call_deref, + r#" + struct Foo; + impl Foo { fn foo(&self) {} } + fn test() { + let foo = &mut Foo; + foo$0.$0foo(); + }"#, + r#" + struct Foo; + impl Foo { fn foo(&self) {} } + fn test() { + let foo = &mut Foo; + (&*foo).foo(); + }"#, + ); + } + + #[test] + fn works_deref_reborrow() { + check_assist( + add_explicit_method_call_deref, + r#" + //- minicore: deref + struct Foo; + struct Bar; + impl core::ops::Deref for Foo { + type Target = Bar; + fn deref(&self) -> &Self::Target {} + } + impl Bar { fn bar(&self) {} } + fn test() { + let foo = &mut Foo; + foo$0.$0bar(); + }"#, + r#" + struct Foo; + struct Bar; + impl core::ops::Deref for Foo { + type Target = Bar; + fn deref(&self) -> &Self::Target {} + } + impl Bar { fn bar(&self) {} } + fn test() { + let foo = &mut Foo; + (&**foo).bar(); + }"#, + ); + } +} diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index 4b4aa9427955..df9fc4f740c9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -105,6 +105,7 @@ mod handlers { pub(crate) type Handler = fn(&mut Assists, &AssistContext<'_>) -> Option<()>; mod add_braces; + mod add_explicit_dot_deref; mod add_explicit_enum_discriminant; mod add_explicit_type; mod add_label_to_loop; @@ -241,6 +242,7 @@ mod handlers { &[ // These are alphabetic for the foolish consistency add_braces::add_braces, + add_explicit_dot_deref::add_explicit_method_call_deref, add_explicit_enum_discriminant::add_explicit_enum_discriminant, add_explicit_type::add_explicit_type, add_label_to_loop::add_label_to_loop, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 7f0836abdf3c..17c74e20516d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs @@ -69,6 +69,27 @@ enum TheEnum { ) } +#[test] +fn doctest_add_explicit_method_call_deref() { + check_doc_test( + "add_explicit_method_call_deref", + r#####" +struct Foo; +impl Foo { fn foo(&self) {} } +fn test() { + Foo$0.$0foo(); +} +"#####, + r#####" +struct Foo; +impl Foo { fn foo(&self) {} } +fn test() { + (&Foo).foo(); +} +"#####, + ) +} + #[test] fn doctest_add_explicit_type() { check_doc_test( diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index dba39204e32e..7fbf9eeba459 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -690,6 +690,13 @@ pub fn expr_macro(path: ast::Path, tt: ast::TokenTree) -> ast::MacroExpr { pub fn expr_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr { expr_from_text(&if exclusive { format!("&mut {expr}") } else { format!("&{expr}") }) } +pub fn expr_raw_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr { + expr_from_text(&if exclusive { + format!("&raw mut {expr}") + } else { + format!("&raw const {expr}") + }) +} pub fn expr_reborrow(expr: ast::Expr) -> ast::Expr { expr_from_text(&format!("&mut *{expr}")) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 969552392180..32fc1e6fedd4 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -566,6 +566,22 @@ impl SyntaxFactory { ast.into() } + pub fn expr_raw_ref(&self, expr: ast::Expr, exclusive: bool) -> ast::Expr { + let ast::Expr::RefExpr(ast) = + make::expr_raw_ref(expr.clone(), exclusive).clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast.into() + } + pub fn expr_closure( &self, pats: impl IntoIterator, From c90a9d836ba72cd3ae6bb0d6ba09883025835d8b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 8 Nov 2025 14:18:53 +0000 Subject: [PATCH 0070/3801] Merge commit 'a0b865dc8782500efe9623859017dd5e16f85407' into sync_cg_clif-2025-11-08 --- .cirrus.yml | 44 +-- .github/workflows/abi-cafe.yml | 2 +- .github/workflows/main.yml | 6 +- .vscode/settings.json | 6 +- Cargo.lock | 290 +++++++++++------- Cargo.toml | 31 +- Readme.md | 19 +- build_system/abi_cafe.rs | 2 + build_system/bench.rs | 2 +- build_system/build_backend.rs | 7 +- build_system/build_sysroot.rs | 73 ++--- build_system/main.rs | 7 + build_system/rustc_info.rs | 30 +- build_system/tests.rs | 42 ++- build_system/usage.txt | 4 + build_system/utils.rs | 4 +- config.txt | 1 - example/example.rs | 16 +- example/mini_core.rs | 22 +- example/mini_core_hello_world.rs | 91 +++--- example/neon.rs | 52 ++-- example/raw-dylib.rs | 2 +- example/std_example.rs | 144 +++++---- ...oot_tests-Disable-long-running-tests.patch | 47 +-- rust-toolchain | 2 +- scripts/cargo-clif.rs | 6 +- scripts/rustc-clif.rs | 6 +- scripts/rustdoc-clif.rs | 6 +- scripts/rustup.sh | 2 +- scripts/setup_rust_fork.sh | 29 +- scripts/test_rustc_tests.sh | 29 +- src/abi/mod.rs | 208 ++++++++++--- src/abi/pass_mode.rs | 7 +- src/base.rs | 99 ++++-- src/codegen_f16_f128.rs | 11 +- src/common.rs | 36 +-- src/compiler_builtins.rs | 51 ++- src/config.rs | 2 +- src/constant.rs | 76 +++-- src/debuginfo/emit.rs | 6 +- src/debuginfo/gcc_except_table.rs | 271 ++++++++++++++++ src/debuginfo/line_info.rs | 48 +-- src/debuginfo/mod.rs | 51 ++- src/debuginfo/types.rs | 4 +- src/debuginfo/unwind.rs | 191 +++++++++++- src/driver/aot.rs | 61 ++-- src/driver/jit.rs | 43 ++- src/driver/mod.rs | 16 +- src/global_asm.rs | 5 +- src/inline_asm.rs | 56 ++-- src/intrinsics/mod.rs | 76 ++++- src/intrinsics/simd.rs | 18 +- src/lib.rs | 96 ++---- src/main_shim.rs | 6 +- src/pretty_clif.rs | 9 +- src/unsize.rs | 2 +- src/value_and_place.rs | 21 +- src/vtable.rs | 2 +- 58 files changed, 1664 insertions(+), 832 deletions(-) create mode 100644 src/debuginfo/gcc_except_table.rs diff --git a/.cirrus.yml b/.cirrus.yml index ee5de8b42f46..3ed89beceb7f 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,21 +1,23 @@ -# FIXME re-enable once https://github.com/rust-lang/rust/issues/134863 is fixed. -# task: -# name: freebsd -# freebsd_instance: -# image: freebsd-13-2-release-amd64 -# setup_rust_script: -# - pkg install -y git-tiny binutils -# - curl https://sh.rustup.rs -sSf --output rustup.sh -# - sh rustup.sh --default-toolchain none -y --profile=minimal -# target_cache: -# folder: build/cg_clif -# prepare_script: -# - . $HOME/.cargo/env -# - ./y.sh prepare -# test_script: -# - . $HOME/.cargo/env -# # Disabling incr comp reduces cache size and incr comp doesn't save as much -# # on CI anyway. -# - export CARGO_BUILD_INCREMENTAL=false -# # Skip rand as it fails on FreeBSD due to rust-random/rand#1355 -# - ./y.sh test --skip-test test.rust-random/rand +task: + name: freebsd + freebsd_instance: + image_family: freebsd-14-2 + setup_rust_script: + - pkg install -y git-tiny binutils + - curl https://sh.rustup.rs -sSf --output rustup.sh + - sh rustup.sh --default-toolchain none -y --profile=minimal + target_cache: + folder: build/cg_clif + prepare_script: + - . $HOME/.cargo/env + - ./y.sh prepare + test_script: + - . $HOME/.cargo/env + # Disabling incr comp reduces cache size and incr comp doesn't save as much + # on CI anyway. + - export CARGO_BUILD_INCREMENTAL=false + # FIXME(rust-lang/rust#134863) necessary to avoid error when dlopening proc + # macros during compilation of cg_clif. + - export LD_STATIC_TLS_EXTRA=4096 + # Skip rand as it fails on FreeBSD due to rust-random/rand#1355 + - ./y.sh test --skip-test test.rust-random/rand diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index 6ad041a796c9..170c7126c296 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -28,7 +28,7 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - - os: macos-13 + - os: macos-15-intel env: TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d92e0fdce99a..0930b924d177 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -56,7 +56,7 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - - os: macos-13 + - os: macos-15-intel env: TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest @@ -187,7 +187,7 @@ jobs: - os: ubuntu-24.04-arm env: TARGET_TRIPLE: aarch64-unknown-linux-gnu - - os: macos-13 + - os: macos-15-intel env: TARGET_TRIPLE: x86_64-apple-darwin - os: macos-latest @@ -231,7 +231,7 @@ jobs: release: runs-on: ubuntu-latest timeout-minutes: 10 - if: ${{ github.ref == 'refs/heads/master' }} + if: ${{ github.ref == 'refs/heads/main' }} needs: [rustfmt, test, bench, dist] permissions: diff --git a/.vscode/settings.json b/.vscode/settings.json index 68bd93aea890..2a3ec5e1c905 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,13 +20,13 @@ "crates": [ { "root_module": "./example/mini_core.rs", - "edition": "2015", + "edition": "2024", "deps": [], "cfg": [], }, { "root_module": "./example/mini_core_hello_world.rs", - "edition": "2015", + "edition": "2024", "deps": [ { "crate": 0, @@ -37,7 +37,7 @@ }, { "root_module": "./example/std_example.rs", - "edition": "2015", + "edition": "2024", "deps": [], "cfg": [], }, diff --git a/Cargo.lock b/Cargo.lock index b893a2be9a2c..09b6c6b87c30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "arbitrary" @@ -28,57 +28,57 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" dependencies = [ "allocator-api2", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cranelift-assembler-x64" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f53499803b1607b6ee0ba0de4ba036e6da700c2e489fe8f9d0f683d0b84d31" +checksum = "f502c60b6af2025c312b37788c089943ef03156a2910da1aa046bb39eb8f61c7" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aadaa5bc8430d0e7bb999459369bedd0e5816ad4a82a0e20748341c4e333eda" +checksum = "2b7e21a74bcf08443a4ef800a4a257063e5c51ee4d7a3bd58da5262d10340830" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2005fda2fc52a2dbce58229b4fb4483b70cbc806ba8ecc11b3f050c1a2d26cac" +checksum = "f337d268865c292ad5df0669a9bbf6223ca41460292a20ad5b0a57b8e9f27f93" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56935e02452ca1249d39ad5c45a96304d0b4300a158a391fd113451e0cd4483d" +checksum = "c0e60319a8242c8d1c7b5a2444d140c416f903f75e0d84da3256fceb822bab85" [[package]] name = "cranelift-codegen" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62612786bf00e10999f50217d6f455d02b31591155881a45a903d1a95d1a4043" +checksum = "78dee669e447a1c68760bf7acee33835e99d564f0137b067f74d4718dfc9970d" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -97,49 +97,50 @@ dependencies = [ "serde", "smallvec", "target-lexicon", - "wasmtime-math", + "wasmtime-internal-math", ] [[package]] name = "cranelift-codegen-meta" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bae789df91ef236079733af9df11d852256c64af196f0bc6471ea0f5f301be" +checksum = "601f629d172b7230f41dd0e78ee797efaf7ec1a5e113c8f395f4027dff6a92ca" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", "cranelift-srcgen", + "heck", ] [[package]] name = "cranelift-codegen-shared" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be319616d36527782558a8312508757815f64deb19b094c7b8f4337229a9bc6" +checksum = "15755c2660902c7d59d96f6551a66ef629650dc3fd405f9dad841e8c58c1a4a2" [[package]] name = "cranelift-control" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8810ee1ab5e9bd5cff4c0c8d240e2009cb5c2b79888fde1d5256d605712314b7" +checksum = "727bfca18705101a294ab9077ad214a8b762ea2bc9844389d0db233d7c61ec3b" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086452c97cfbe116bf17dbe622dc5fdf2ea97299c7d4ce42460f284387c9928a" +checksum = "15564c6f0c72750ca4374f40b044857cbc8087571e46d4c7ccdbdcc29b1dec8b" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c27947010ab759330f252610c17a8cd64d123358be4f33164233d04fcd77b80" +checksum = "16c681f2731f1cf68eed9f3b6811571823a5ac498f59c52b73736b68599defb3" dependencies = [ "cranelift-codegen", "log", @@ -149,15 +150,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec67bfb8bd55b1e9760eb9f5186dca8d81bd4d86110f8d5af01154a044c91802" +checksum = "40cedc02f08307da019a3e06d3f20f772f829ff813aec975accb012f8930b688" [[package]] name = "cranelift-jit" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d67cdfc447f2abdb46bb30a6582cce189539c3c051c1d5330692376e1400edff" +checksum = "c2864461448c72d15ae3311ea63df9c7e35f22f04683785f6715a0cf17e6577d" dependencies = [ "anyhow", "cranelift-codegen", @@ -169,15 +170,15 @@ dependencies = [ "log", "region", "target-lexicon", - "wasmtime-jit-icache-coherence", - "windows-sys 0.59.0", + "wasmtime-internal-jit-icache-coherence", + "windows-sys 0.60.2", ] [[package]] name = "cranelift-module" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4597eaa52bca1ed111986c7a7f70cdbe192f83d271d627201365078e37b7e84" +checksum = "2b31d249bbbccc4c1ae54701087d4d49d05951897691eef44f4a60e70252743b" dependencies = [ "anyhow", "cranelift-codegen", @@ -186,9 +187,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a9b63edea46e013fce459c46e500462cb03a0490fdd9c18fe42b1dd7b93aa1" +checksum = "db03ab51c60710eb83d0217725b77db4062aca83b35359f5e6aa99ed1c275977" dependencies = [ "cranelift-codegen", "libc", @@ -197,9 +198,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce706f0166d5b7f31693dff521e87cb9858e12adf22ffcde93c4a2826f8f04a9" +checksum = "7131e0eb45ee10b0bd6082d0c0114c2e9a670b034d46774b39d0fc5c0ed7cedf" dependencies = [ "anyhow", "cranelift-codegen", @@ -212,24 +213,24 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.121.0" +version = "0.125.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5870e266df8237b56cc98b04f5739c228565c92dd629ec6c66efa87271a158" +checksum = "3d7a06c330b7994a891ad5b622ebc9aefcd17beae832dd25f577cf60c13426bf" [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "fallible-iterator" @@ -239,15 +240,15 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe" dependencies = [ "fallible-iterator", "indexmap", @@ -256,18 +257,24 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ "foldhash", ] [[package]] -name = "indexmap" -version = "2.7.0" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown", @@ -275,18 +282,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.169" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets", + "windows-targets 0.53.3", ] [[package]] @@ -297,30 +304,30 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "mach2" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" dependencies = [ "libc", ] [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "crc32fast", "hashbrown", @@ -330,27 +337,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] name = "regalloc2" -version = "0.12.2" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5216b1837de2149f8bc8e6d5f88a9326b63b8c836ed58ce4a0a29ec736a59734" +checksum = "efd8138ce7c3d7c13be4f61893154b5d711bd798d2d7be3ecb8dcc7e7a06ca98" dependencies = [ "allocator-api2", "bumpalo", @@ -374,9 +381,9 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_codegen_cranelift" @@ -398,18 +405,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -418,9 +425,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" @@ -430,9 +437,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" -version = "2.0.95" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -441,53 +448,59 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc12939a1c9b9d391e0b7135f72fd30508b73450753e28341fed159317582a77" +checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "wasmtime-jit-icache-coherence" -version = "34.0.0" +name = "wasmtime-internal-jit-icache-coherence" +version = "38.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eedc0324e37cf39b049f4dca0c30997eaab49f09006d5f4c1994e64e7b7dba8" +checksum = "8d0a76f1a6e887cc1b551b02dfd6e2ce5f6738e8cacd9ad7284f6ac1aac4698f" dependencies = [ "anyhow", "cfg-if", "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] -name = "wasmtime-math" -version = "34.0.0" +name = "wasmtime-internal-math" +version = "38.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd35fae4cf51d2b4a9bd2ef04b0eb309fa1849cab6a6ab5ac27cbd054ea284d" +checksum = "b900df4252ad86547e7f2b2c00201b006db4e864893bedfb3aca32b23d81868a" dependencies = [ "libm", ] +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets", + "windows-targets 0.53.3", ] [[package]] @@ -496,14 +509,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -512,44 +542,92 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" diff --git a/Cargo.toml b/Cargo.toml index 9066e4dbbb52..f2001123e579 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,22 @@ [package] name = "rustc_codegen_cranelift" version = "0.1.0" -edition = "2021" +edition = "2024" [lib] crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.121.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.121.0" } -cranelift-module = { version = "0.121.0" } -cranelift-native = { version = "0.121.0" } -cranelift-jit = { version = "0.121.0", optional = true } -cranelift-object = { version = "0.121.0" } +cranelift-codegen = { version = "0.125.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.125.0" } +cranelift-module = { version = "0.125.0" } +cranelift-native = { version = "0.125.0" } +cranelift-jit = { version = "0.125.0", optional = true } +cranelift-object = { version = "0.125.0" } target-lexicon = "0.13" -gimli = { version = "0.31", default-features = false, features = ["write"] } -object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } +gimli = { version = "0.32", default-features = false, features = ["write"] } +object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" libloading = { version = "0.8.0", optional = true } @@ -24,12 +24,12 @@ smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } @@ -46,6 +46,7 @@ smallvec = "1.8.1" unstable-features = ["jit", "inline_asm_sym"] jit = ["cranelift-jit", "libloading"] inline_asm_sym = [] +unwinding = [] # Not yet included in unstable-features for performance reasons [package.metadata.rust-analyzer] rustc_private = true diff --git a/Readme.md b/Readme.md index 4d1e4d843ffe..c5436cf67c80 100644 --- a/Readme.md +++ b/Readme.md @@ -11,7 +11,7 @@ The Cranelift codegen backend is distributed in nightly builds on Linux, macOS a install it using Rustup, you can do that by running: ```bash -$ rustup component add rustc-codegen-cranelift-preview --toolchain nightly +rustup component add rustc-codegen-cranelift-preview --toolchain nightly ``` Once it is installed, you can enable it with one of the following approaches: @@ -47,16 +47,16 @@ If you want to use `cargo clif build` instead of having to specify the full path If you want to build the backend manually, you can download it from GitHub and build it yourself: ```bash -$ git clone https://github.com/rust-lang/rustc_codegen_cranelift -$ cd rustc_codegen_cranelift -$ ./y.sh build +git clone https://github.com/rust-lang/rustc_codegen_cranelift +cd rustc_codegen_cranelift +./y.sh build ``` To run the test suite replace the last command with: ```bash -$ ./y.sh prepare # only needs to be run the first time -$ ./test.sh +./y.sh prepare # only needs to be run the first time +./test.sh ``` For more docs on how to build and test see [build_system/usage.txt](build_system/usage.txt) or the help message of `./y.sh`. @@ -66,7 +66,7 @@ For more docs on how to build and test see [build_system/usage.txt](build_system |OS \ architecture|x86\_64|AArch64|Riscv64|s390x (System-Z)| |---|---|---|---|---| |Linux|✅|✅|✅[^no-rustup]|✅[^no-rustup]| -|FreeBSD|✅[^no-rustup]|❓|❓|❓| +|FreeBSD|✅[^no-rustup][^tls]|❓|❓|❓| |AIX|❌[^xcoff]|N/A|N/A|❌[^xcoff]| |Other unixes|❓|❓|❓|❓| |macOS|✅|✅|N/A|N/A| @@ -80,6 +80,7 @@ Not all targets are available as rustup component for nightly. See notes in the [^xcoff]: XCOFF object file format is not supported. [^no-rustup]: Not available as [rustup component for nightly](https://rust-lang.github.io/rustup-components-history/). You can build it yourself. +[^tls]: FreeBSD requires setting `LD_STATIC_TLS_EXTRA=4096` to build cg_clif. In addition you need at least FreeBSD 14. ## Usage @@ -90,7 +91,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo In the directory with your project (where you can do the usual `cargo build`), run: ```bash -$ $cg_clif_dir/dist/cargo-clif build +$cg_clif_dir/dist/cargo-clif build ``` This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend. @@ -104,7 +105,7 @@ See [rustc_testing.md](docs/rustc_testing.md). ## Not yet supported * SIMD ([tracked here](https://github.com/rust-lang/rustc_codegen_cranelift/issues/171), `std::simd` fully works, `std::arch` is partially supported) -* Unwinding on panics ([no cranelift support](https://github.com/bytecodealliance/wasmtime/issues/1677), `-Cpanic=abort` is enabled by default) +* Unwinding on panics ([experimental and not supported on Windows and macOS](https://github.com/rust-lang/rustc_codegen_cranelift/issues/1567), `-Cpanic=abort` is enabled by default) ## License diff --git a/build_system/abi_cafe.rs b/build_system/abi_cafe.rs index 43025137bc6b..5a393a217c27 100644 --- a/build_system/abi_cafe.rs +++ b/build_system/abi_cafe.rs @@ -19,6 +19,7 @@ pub(crate) fn run( cg_clif_dylib: &CodegenBackend, rustup_toolchain_name: Option<&str>, bootstrap_host_compiler: &Compiler, + panic_unwind_support: bool, ) { std::fs::create_dir_all(&dirs.download_dir).unwrap(); ABI_CAFE_REPO.fetch(dirs); @@ -32,6 +33,7 @@ pub(crate) fn run( bootstrap_host_compiler, rustup_toolchain_name, bootstrap_host_compiler.triple.clone(), + panic_unwind_support, ); eprintln!("Running abi-cafe"); diff --git a/build_system/bench.rs b/build_system/bench.rs index 8359b7b52790..192cb499536f 100644 --- a/build_system/bench.rs +++ b/build_system/bench.rs @@ -144,7 +144,7 @@ fn hyperfine_command( } for &(name, cmd) in cmds { - if name != "" { + if !name.is_empty() { bench.arg("-n").arg(name); } bench.arg(cmd); diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs index bf7cf1c0a346..b9fa0ff2d94c 100644 --- a/build_system/build_backend.rs +++ b/build_system/build_backend.rs @@ -12,10 +12,11 @@ pub(crate) fn build_backend( dirs: &Dirs, bootstrap_host_compiler: &Compiler, use_unstable_features: bool, + panic_unwind_support: bool, ) -> PathBuf { let _group = LogGroup::guard("Build backend"); - let mut cmd = CG_CLIF.build(&bootstrap_host_compiler, dirs); + let mut cmd = CG_CLIF.build(bootstrap_host_compiler, dirs); let mut rustflags = rustflags_from_env("RUSTFLAGS"); rustflags.push("-Zallow-features=rustc_private,f16,f128".to_owned()); @@ -31,6 +32,10 @@ pub(crate) fn build_backend( cmd.arg("--features").arg("unstable-features"); } + if panic_unwind_support { + cmd.arg("--features").arg("unwinding"); + } + cmd.arg("--release"); eprintln!("[BUILD] rustc_codegen_cranelift"); diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 00955998e703..72140c651a9a 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -17,6 +17,7 @@ pub(crate) fn build_sysroot( bootstrap_host_compiler: &Compiler, rustup_toolchain_name: Option<&str>, target_triple: String, + panic_unwind_support: bool, ) -> Compiler { let _guard = LogGroup::guard("Build sysroot"); @@ -48,10 +49,13 @@ pub(crate) fn build_sysroot( let mut build_cargo_wrapper_cmd = Command::new(&bootstrap_host_compiler.rustc); let wrapper_path = dist_dir.join(&wrapper_name); build_cargo_wrapper_cmd - .arg(dirs.source_dir.join("scripts").join(&format!("{wrapper}.rs"))) + .arg(dirs.source_dir.join("scripts").join(format!("{wrapper}.rs"))) .arg("-o") .arg(&wrapper_path) .arg("-Cstrip=debuginfo"); + if panic_unwind_support { + build_cargo_wrapper_cmd.arg("--cfg").arg("support_panic_unwind"); + } if let Some(rustup_toolchain_name) = &rustup_toolchain_name { build_cargo_wrapper_cmd .env("TOOLCHAIN_NAME", rustup_toolchain_name) @@ -77,6 +81,7 @@ pub(crate) fn build_sysroot( bootstrap_host_compiler.clone(), &cg_clif_dylib_path, sysroot_kind, + panic_unwind_support, ); host.install_into_sysroot(dist_dir); @@ -91,6 +96,7 @@ pub(crate) fn build_sysroot( }, &cg_clif_dylib_path, sysroot_kind, + panic_unwind_support, ) .install_into_sysroot(dist_dir); } @@ -134,19 +140,20 @@ impl SysrootTarget { static STDLIB_SRC: RelPath = RelPath::build("stdlib"); static STANDARD_LIBRARY: CargoProject = CargoProject::new(&RelPath::build("stdlib/library/sysroot"), "stdlib_target"); -static RTSTARTUP_SYSROOT: RelPath = RelPath::build("rtstartup"); fn build_sysroot_for_triple( dirs: &Dirs, compiler: Compiler, cg_clif_dylib_path: &CodegenBackend, sysroot_kind: SysrootKind, + panic_unwind_support: bool, ) -> SysrootTarget { match sysroot_kind { - SysrootKind::None => build_rtstartup(dirs, &compiler) - .unwrap_or(SysrootTarget { triple: compiler.triple, libs: vec![] }), + SysrootKind::None => SysrootTarget { triple: compiler.triple, libs: vec![] }, SysrootKind::Llvm => build_llvm_sysroot_for_triple(compiler), - SysrootKind::Clif => build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path), + SysrootKind::Clif => { + build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path, panic_unwind_support) + } } } @@ -188,25 +195,28 @@ fn build_clif_sysroot_for_triple( dirs: &Dirs, mut compiler: Compiler, cg_clif_dylib_path: &CodegenBackend, + panic_unwind_support: bool, ) -> SysrootTarget { let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] }; - if let Some(rtstartup_target_libs) = build_rtstartup(dirs, &compiler) { - rtstartup_target_libs.install_into_sysroot(&RTSTARTUP_SYSROOT.to_path(dirs)); - - target_libs.libs.extend(rtstartup_target_libs.libs); - } - let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(&compiler.triple).join("release"); if !config::get_bool("keep_sysroot") { + let sysroot_src_orig = get_default_sysroot(&compiler.rustc).join("lib/rustlib/src/rust"); + assert!(sysroot_src_orig.exists()); + + apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs)); + // Cleanup the deps dir, but keep build scripts and the incremental cache for faster // recompilation as they are not affected by changes in cg_clif. ensure_empty_dir(&build_dir.join("deps")); } // Build sysroot - let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned(), "-Cpanic=abort".to_owned()]; + let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned()]; + if !panic_unwind_support { + rustflags.push("-Cpanic=abort".to_owned()); + } match cg_clif_dylib_path { CodegenBackend::Local(path) => { rustflags.push(format!("-Zcodegen-backend={}", path.to_str().unwrap())); @@ -215,9 +225,7 @@ fn build_clif_sysroot_for_triple( rustflags.push(format!("-Zcodegen-backend={name}")); } }; - // Necessary for MinGW to find rsbegin.o and rsend.o - rustflags.push("--sysroot".to_owned()); - rustflags.push(RTSTARTUP_SYSROOT.to_path(dirs).to_str().unwrap().to_owned()); + rustflags.push("--sysroot=/dev/null".to_owned()); // Incremental compilation by default disables mir inlining. This leads to both a decent // compile perf and a significant runtime perf regression. As such forcefully enable mir @@ -258,38 +266,3 @@ fn build_clif_sysroot_for_triple( target_libs } - -fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option { - if !config::get_bool("keep_sysroot") { - let sysroot_src_orig = get_default_sysroot(&compiler.rustc).join("lib/rustlib/src/rust"); - assert!(sysroot_src_orig.exists()); - - apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs)); - } - - if !compiler.triple.ends_with("windows-gnu") { - return None; - } - - let rtstartup_sysroot = RTSTARTUP_SYSROOT.to_path(dirs); - ensure_empty_dir(&rtstartup_sysroot); - - let rtstartup_src = STDLIB_SRC.to_path(dirs).join("library").join("rtstartup"); - let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] }; - - for file in ["rsbegin", "rsend"] { - let obj = rtstartup_sysroot.join(format!("{file}.o")); - let mut build_rtstartup_cmd = Command::new(&compiler.rustc); - build_rtstartup_cmd - .arg("--target") - .arg(&compiler.triple) - .arg("--emit=obj") - .arg("-o") - .arg(&obj) - .arg(rtstartup_src.join(format!("{file}.rs"))); - spawn_and_wait(build_rtstartup_cmd); - target_libs.libs.push(obj.clone()); - } - - Some(target_libs) -} diff --git a/build_system/main.rs b/build_system/main.rs index 3ff9751a3ef2..fc0093128300 100644 --- a/build_system/main.rs +++ b/build_system/main.rs @@ -83,6 +83,7 @@ fn main() { let mut download_dir = None; let mut sysroot_kind = SysrootKind::Clif; let mut use_unstable_features = true; + let mut panic_unwind_support = false; let mut frozen = false; let mut skip_tests = vec![]; let mut use_backend = None; @@ -108,6 +109,7 @@ fn main() { } } "--no-unstable-features" => use_unstable_features = false, + "--panic-unwind-support" => panic_unwind_support = true, "--frozen" => frozen = true, "--skip-test" => { // FIXME check that all passed in tests actually exist @@ -201,6 +203,7 @@ fn main() { &dirs, &bootstrap_host_compiler, use_unstable_features, + panic_unwind_support, )) }; match command { @@ -212,6 +215,7 @@ fn main() { &dirs, sysroot_kind, use_unstable_features, + panic_unwind_support, &skip_tests.iter().map(|test| &**test).collect::>(), &cg_clif_dylib, &bootstrap_host_compiler, @@ -230,6 +234,7 @@ fn main() { &cg_clif_dylib, rustup_toolchain_name.as_deref(), &bootstrap_host_compiler, + panic_unwind_support, ); } Command::Build => { @@ -240,6 +245,7 @@ fn main() { &bootstrap_host_compiler, rustup_toolchain_name.as_deref(), target_triple, + panic_unwind_support, ); } Command::Bench => { @@ -250,6 +256,7 @@ fn main() { &bootstrap_host_compiler, rustup_toolchain_name.as_deref(), target_triple, + panic_unwind_support, ); bench::benchmark(&dirs, &compiler); } diff --git a/build_system/rustc_info.rs b/build_system/rustc_info.rs index 5b71504e90a4..2fa827498de9 100644 --- a/build_system/rustc_info.rs +++ b/build_system/rustc_info.rs @@ -2,25 +2,19 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; pub(crate) fn get_host_triple(rustc: &Path) -> String { - let version_info = - Command::new(rustc).stderr(Stdio::inherit()).args(&["-vV"]).output().unwrap().stdout; - String::from_utf8(version_info) + let version_info = Command::new(rustc) + .stderr(Stdio::inherit()) + .args(["--print", "host-tuple"]) + .output() .unwrap() - .lines() - .to_owned() - .find(|line| line.starts_with("host")) - .unwrap() - .split(":") - .nth(1) - .unwrap() - .trim() - .to_owned() + .stdout; + String::from_utf8(version_info).unwrap().trim().to_owned() } pub(crate) fn get_toolchain_name() -> String { let active_toolchain = Command::new("rustup") .stderr(Stdio::inherit()) - .args(&["show", "active-toolchain"]) + .args(["show", "active-toolchain"]) .output() .unwrap() .stdout; @@ -33,7 +27,7 @@ pub(crate) fn get_cargo_path() -> PathBuf { } let cargo_path = Command::new("rustup") .stderr(Stdio::inherit()) - .args(&["which", "cargo"]) + .args(["which", "cargo"]) .output() .unwrap() .stdout; @@ -46,7 +40,7 @@ pub(crate) fn get_rustc_path() -> PathBuf { } let rustc_path = Command::new("rustup") .stderr(Stdio::inherit()) - .args(&["which", "rustc"]) + .args(["which", "rustc"]) .output() .unwrap() .stdout; @@ -59,7 +53,7 @@ pub(crate) fn get_rustdoc_path() -> PathBuf { } let rustc_path = Command::new("rustup") .stderr(Stdio::inherit()) - .args(&["which", "rustdoc"]) + .args(["which", "rustdoc"]) .output() .unwrap() .stdout; @@ -69,7 +63,7 @@ pub(crate) fn get_rustdoc_path() -> PathBuf { pub(crate) fn get_default_sysroot(rustc: &Path) -> PathBuf { let default_sysroot = Command::new(rustc) .stderr(Stdio::inherit()) - .args(&["--print", "sysroot"]) + .args(["--print", "sysroot"]) .output() .unwrap() .stdout; @@ -80,7 +74,7 @@ pub(crate) fn get_default_sysroot(rustc: &Path) -> PathBuf { pub(crate) fn get_file_name(rustc: &Path, crate_name: &str, crate_type: &str) -> String { let file_name = Command::new(rustc) .stderr(Stdio::inherit()) - .args(&[ + .args([ "--crate-name", crate_name, "--crate-type", diff --git a/build_system/tests.rs b/build_system/tests.rs index eec89c026b26..dd8cf929bc2f 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -89,15 +89,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[ TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]), TestCase::build_bin("aot.issue-59326", "example/issue-59326.rs"), TestCase::build_bin_and_run("aot.neon", "example/neon.rs", &[]), - TestCase::custom("aot.gen_block_iterate", &|runner| { - runner.run_rustc([ - "example/gen_block_iterate.rs", - "--edition", - "2024", - "-Zunstable-options", - ]); - runner.run_out_command("gen_block_iterate", &[]); - }), + TestCase::build_bin_and_run("aot.gen_block_iterate", "example/gen_block_iterate.rs", &[]), TestCase::build_bin_and_run("aot.raw-dylib", "example/raw-dylib.rs", &[]), TestCase::custom("test.sysroot", &|runner| { apply_patches( @@ -217,13 +209,15 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ PORTABLE_SIMD.clean(&runner.dirs); - let mut build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs); - build_cmd.arg("--all-targets"); + let build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs); + // FIXME uncomment once examples work: https://github.com/rust-lang/portable-simd/issues/470 + //build_cmd.arg("--all-targets"); spawn_and_wait(build_cmd); if runner.is_native { let mut test_cmd = PORTABLE_SIMD.test(&runner.target_compiler, &runner.dirs); - test_cmd.arg("-q"); + // FIXME remove --tests once examples work: https://github.com/rust-lang/portable-simd/issues/470 + test_cmd.arg("-q").arg("--tests"); spawn_and_wait(test_cmd); } }), @@ -233,6 +227,7 @@ pub(crate) fn run_tests( dirs: &Dirs, sysroot_kind: SysrootKind, use_unstable_features: bool, + panic_unwind_support: bool, skip_tests: &[&str], cg_clif_dylib: &CodegenBackend, bootstrap_host_compiler: &Compiler, @@ -251,12 +246,14 @@ pub(crate) fn run_tests( bootstrap_host_compiler, rustup_toolchain_name, target_triple.clone(), + panic_unwind_support, ); let runner = TestRunner::new( dirs.clone(), target_compiler, use_unstable_features, + panic_unwind_support, skip_tests, bootstrap_host_compiler.triple == target_triple, stdlib_source.clone(), @@ -283,12 +280,14 @@ pub(crate) fn run_tests( bootstrap_host_compiler, rustup_toolchain_name, target_triple.clone(), + panic_unwind_support, ); let mut runner = TestRunner::new( dirs.clone(), target_compiler, use_unstable_features, + panic_unwind_support, skip_tests, bootstrap_host_compiler.triple == target_triple, stdlib_source, @@ -314,6 +313,7 @@ pub(crate) fn run_tests( struct TestRunner<'a> { is_native: bool, jit_supported: bool, + panic_unwind_support: bool, skip_tests: &'a [&'a str], dirs: Dirs, target_compiler: Compiler, @@ -325,6 +325,7 @@ impl<'a> TestRunner<'a> { dirs: Dirs, mut target_compiler: Compiler, use_unstable_features: bool, + panic_unwind_support: bool, skip_tests: &'a [&'a str], is_native: bool, stdlib_source: PathBuf, @@ -335,7 +336,15 @@ impl<'a> TestRunner<'a> { let jit_supported = use_unstable_features && is_native && !target_compiler.triple.contains("windows"); - Self { is_native, jit_supported, skip_tests, dirs, target_compiler, stdlib_source } + Self { + is_native, + jit_supported, + panic_unwind_support, + skip_tests, + dirs, + target_compiler, + stdlib_source, + } } fn run_testsuite(&self, tests: &[TestCase]) { @@ -346,7 +355,7 @@ impl<'a> TestRunner<'a> { let _guard = if !config::get_bool(config) || (is_jit_test && !self.jit_supported) - || self.skip_tests.contains(&config) + || self.skip_tests.contains(config) { eprintln!("[{tag}] {testname} (skipped)"); continue; @@ -404,8 +413,11 @@ impl<'a> TestRunner<'a> { cmd.arg("-Cdebuginfo=2"); cmd.arg("--target"); cmd.arg(&self.target_compiler.triple); - cmd.arg("-Cpanic=abort"); + if !self.panic_unwind_support { + cmd.arg("-Cpanic=abort"); + } cmd.arg("--check-cfg=cfg(jit)"); + cmd.arg("--edition=2024"); cmd.args(args); cmd } diff --git a/build_system/usage.txt b/build_system/usage.txt index 5c333fe2db59..6c98087e5239 100644 --- a/build_system/usage.txt +++ b/build_system/usage.txt @@ -25,6 +25,10 @@ OPTIONS: Some features are not yet ready for production usage. This option will disable these features. This includes the JIT mode and inline assembly support. + --panic-unwind-support + Enable support for unwinding when -Cpanic=unwind is used. This currently regresses build + performance. + --frozen Require Cargo.lock and cache are up to date diff --git a/build_system/utils.rs b/build_system/utils.rs index d9807155a3d5..3266aa0ce8b6 100644 --- a/build_system/utils.rs +++ b/build_system/utils.rs @@ -162,7 +162,7 @@ impl CargoProject { pub(crate) fn try_hard_link(src: impl AsRef, dst: impl AsRef) { let src = src.as_ref(); let dst = dst.as_ref(); - if let Err(_) = fs::hard_link(src, dst) { + if fs::hard_link(src, dst).is_err() { fs::copy(src, dst).unwrap(); // Fallback to copying if hardlinking failed } } @@ -179,7 +179,7 @@ pub(crate) fn spawn_and_wait(mut cmd: Command) { /// Create the specified directory if it doesn't exist yet and delete all contents. pub(crate) fn ensure_empty_dir(path: &Path) { fs::create_dir_all(path).unwrap(); - let read_dir = match fs::read_dir(&path) { + let read_dir = match fs::read_dir(path) { Ok(read_dir) => read_dir, Err(err) if err.kind() == io::ErrorKind::NotFound => { return; diff --git a/config.txt b/config.txt index 6ae4767adfdf..85748a4f8a78 100644 --- a/config.txt +++ b/config.txt @@ -20,7 +20,6 @@ aot.mini_core_hello_world testsuite.base_sysroot aot.arbitrary_self_types_pointers_and_wrappers -aot.issue_91827_extern_types jit.std_example aot.std_example aot.dst_field_align diff --git a/example/example.rs b/example/example.rs index 769d262b9ebb..2e15f06f8fc7 100644 --- a/example/example.rs +++ b/example/example.rs @@ -77,12 +77,16 @@ pub fn use_size_of() -> usize { } pub unsafe fn use_copy_intrinsic(src: *const u8, dst: *mut u8) { - intrinsics::copy::(src, dst, 1); + unsafe { + intrinsics::copy::(src, dst, 1); + } } pub unsafe fn use_copy_intrinsic_ref(src: *const u8, dst: *mut u8) { - let copy2 = &intrinsics::copy::; - copy2(src, dst, 1); + unsafe { + let copy2 = &intrinsics::copy::; + copy2(src, dst, 1); + } } pub const ABC: u8 = 6 * 7; @@ -126,11 +130,11 @@ pub fn eq_char(a: char, b: char) -> bool { } pub unsafe fn transmute(c: char) -> u32 { - intrinsics::transmute(c) + unsafe { intrinsics::transmute(c) } } pub unsafe fn deref_str_ptr(s: *const str) -> &'static str { - &*s + unsafe { &*s } } pub fn use_array(arr: [u8; 3]) -> u8 { @@ -146,7 +150,7 @@ pub fn array_as_slice(arr: &[u8; 3]) -> &[u8] { } pub unsafe fn use_ctlz_nonzero(a: u16) -> u32 { - intrinsics::ctlz_nonzero(a) + unsafe { intrinsics::ctlz_nonzero(a) } } pub fn ptr_as_usize(ptr: *const u8) -> usize { diff --git a/example/mini_core.rs b/example/mini_core.rs index 304d0d648561..b522ea193716 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -546,7 +546,7 @@ fn panic_in_cleanup() -> ! { #[cfg(all(unix, not(target_vendor = "apple")))] #[link(name = "gcc_s")] -extern "C" { +unsafe extern "C" { fn _Unwind_Resume(exc: *mut ()) -> !; } @@ -555,7 +555,9 @@ extern "C" { pub unsafe fn drop_in_place(to_drop: *mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. - drop_in_place(to_drop); + unsafe { + drop_in_place(to_drop); + } } #[lang = "unpin"] @@ -622,7 +624,7 @@ impl Deref for Box { #[lang = "exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { - libc::malloc(size) + unsafe { libc::malloc(size) } } #[lang = "drop"] @@ -649,11 +651,11 @@ pub mod intrinsics { #[rustc_intrinsic] pub const fn size_of() -> usize; #[rustc_intrinsic] - pub unsafe fn size_of_val(val: *const T) -> usize; + pub unsafe fn size_of_val(val: *const T) -> usize; #[rustc_intrinsic] pub const fn align_of() -> usize; #[rustc_intrinsic] - pub unsafe fn align_of_val(val: *const T) -> usize; + pub unsafe fn align_of_val(val: *const T) -> usize; #[rustc_intrinsic] pub unsafe fn copy(src: *const T, dst: *mut T, count: usize); #[rustc_intrinsic] @@ -661,7 +663,7 @@ pub mod intrinsics { #[rustc_intrinsic] pub unsafe fn ctlz_nonzero(x: T) -> u32; #[rustc_intrinsic] - pub const fn needs_drop() -> bool; + pub const fn needs_drop() -> bool; #[rustc_intrinsic] pub fn bitreverse(x: T) -> T; #[rustc_intrinsic] @@ -678,13 +680,13 @@ pub mod libc { // symbols to link against. #[cfg_attr(unix, link(name = "c"))] #[cfg_attr(target_env = "msvc", link(name = "legacy_stdio_definitions"))] - extern "C" { + unsafe extern "C" { pub fn printf(format: *const i8, ...) -> i32; } #[cfg_attr(unix, link(name = "c"))] #[cfg_attr(target_env = "msvc", link(name = "msvcrt"))] - extern "C" { + unsafe extern "C" { pub fn puts(s: *const i8) -> i32; pub fn malloc(size: usize) -> *mut u8; pub fn free(ptr: *mut u8); @@ -733,7 +735,7 @@ trait SizedTypeProperties: Sized { } impl SizedTypeProperties for T {} -extern "C" { +unsafe extern "C" { type VaListImpl; } @@ -792,7 +794,7 @@ struct PanicLocation { column: u32, } -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(not(all(windows, target_env = "gnu")))] pub fn get_tls() -> u8 { #[thread_local] diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index a9388814a7f5..10549cd2a41e 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -124,9 +124,11 @@ static mut NUM: u8 = 6 * 7; static NUM_REF: &'static u8 = unsafe { &*&raw const NUM }; unsafe fn zeroed() -> T { - let mut uninit = MaybeUninit { uninit: () }; - intrinsics::write_bytes(&mut uninit.value.value as *mut T, 0, 1); - uninit.value.value + unsafe { + let mut uninit = MaybeUninit { uninit: () }; + intrinsics::write_bytes(&mut uninit.value.value as *mut T, 0, 1); + uninit.value.value + } } fn take_f32(_f: f32) {} @@ -237,7 +239,7 @@ fn main() { } unsafe fn uninitialized() -> T { - MaybeUninit { uninit: () }.value.value + unsafe { MaybeUninit { uninit: () }.value.value } } zeroed::<(u8, u8)>(); @@ -270,20 +272,20 @@ fn main() { let x = &[0u32, 42u32] as &[u32]; match x { [] => assert_eq!(0u32, 1), - [_, ref y @ ..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize), + [_, y @ ..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize), } assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42); #[cfg(not(any(jit, target_vendor = "apple", windows)))] { - extern "C" { + unsafe extern "C" { #[linkage = "extern_weak"] static ABC: *const u8; } { - extern "C" { + unsafe extern "C" { #[linkage = "extern_weak"] static ABC: *const u8; } @@ -310,7 +312,7 @@ fn main() { check_niche_behavior(); - extern "C" { + unsafe extern "C" { type ExternType; } @@ -364,7 +366,7 @@ fn stack_val_align() { } #[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))] -extern "C" { +unsafe extern "C" { fn global_asm_test(); } @@ -412,7 +414,7 @@ struct pthread_attr_t { #[link(name = "pthread")] #[cfg(unix)] -extern "C" { +unsafe extern "C" { fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int; fn pthread_create( @@ -433,7 +435,7 @@ type HANDLE = *mut c_void; #[link(name = "msvcrt")] #[cfg(windows)] -extern "C" { +unsafe extern "C" { fn WaitForSingleObject(hHandle: LPVOID, dwMilliseconds: DWORD) -> DWORD; fn CreateThread( @@ -455,46 +457,51 @@ struct Thread { impl Thread { unsafe fn create(f: extern "C" fn(_: *mut c_void) -> *mut c_void) -> Self { - #[cfg(unix)] - { - let mut attr: pthread_attr_t = zeroed(); - let mut thread: pthread_t = 0; + unsafe { + #[cfg(unix)] + { + let mut attr: pthread_attr_t = zeroed(); + let mut thread: pthread_t = 0; - if pthread_attr_init(&mut attr) != 0 { - assert!(false); + if pthread_attr_init(&mut attr) != 0 { + assert!(false); + } + + if pthread_create(&mut thread, &attr, f, 0 as *mut c_void) != 0 { + assert!(false); + } + + Thread { handle: thread } } - if pthread_create(&mut thread, &attr, f, 0 as *mut c_void) != 0 { - assert!(false); + #[cfg(windows)] + { + let handle = + CreateThread(0 as *mut c_void, 0, f, 0 as *mut c_void, 0, 0 as *mut u32); + + if (handle as u64) == 0 { + assert!(false); + } + + Thread { handle } } - - Thread { handle: thread } - } - - #[cfg(windows)] - { - let handle = CreateThread(0 as *mut c_void, 0, f, 0 as *mut c_void, 0, 0 as *mut u32); - - if (handle as u64) == 0 { - assert!(false); - } - - Thread { handle } } } unsafe fn join(self) { - #[cfg(unix)] - { - let mut res = 0 as *mut c_void; - pthread_join(self.handle, &mut res); - } + unsafe { + #[cfg(unix)] + { + let mut res = 0 as *mut c_void; + pthread_join(self.handle, &mut res); + } - #[cfg(windows)] - { - // The INFINITE macro is used to signal operations that do not timeout. - let infinite = 0xffffffff; - assert!(WaitForSingleObject(self.handle, infinite) == 0); + #[cfg(windows)] + { + // The INFINITE macro is used to signal operations that do not timeout. + let infinite = 0xffffffff; + assert!(WaitForSingleObject(self.handle, infinite) == 0); + } } } } diff --git a/example/neon.rs b/example/neon.rs index 704f866e2c4f..fb3e10a41c02 100644 --- a/example/neon.rs +++ b/example/neon.rs @@ -14,7 +14,7 @@ unsafe fn test_vpmin_s8() { let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]); let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); let e = i8x8::from([-2, -4, 5, 7, 0, 2, 4, 6]); - let r: i8x8 = transmute(vpmin_s8(transmute(a), transmute(b))); + let r: i8x8 = unsafe { transmute(vpmin_s8(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -23,7 +23,7 @@ unsafe fn test_vpmin_s16() { let a = i16x4::from([1, 2, 3, -4]); let b = i16x4::from([0, 3, 2, 5]); let e = i16x4::from([1, -4, 0, 2]); - let r: i16x4 = transmute(vpmin_s16(transmute(a), transmute(b))); + let r: i16x4 = unsafe { transmute(vpmin_s16(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -32,7 +32,7 @@ unsafe fn test_vpmin_s32() { let a = i32x2::from([1, -2]); let b = i32x2::from([0, 3]); let e = i32x2::from([-2, 0]); - let r: i32x2 = transmute(vpmin_s32(transmute(a), transmute(b))); + let r: i32x2 = unsafe { transmute(vpmin_s32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -41,7 +41,7 @@ unsafe fn test_vpmin_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); let e = u8x8::from([1, 3, 5, 7, 0, 2, 4, 6]); - let r: u8x8 = transmute(vpmin_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vpmin_u8(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -50,7 +50,7 @@ unsafe fn test_vpmin_u16() { let a = u16x4::from([1, 2, 3, 4]); let b = u16x4::from([0, 3, 2, 5]); let e = u16x4::from([1, 3, 0, 2]); - let r: u16x4 = transmute(vpmin_u16(transmute(a), transmute(b))); + let r: u16x4 = unsafe { transmute(vpmin_u16(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -59,7 +59,7 @@ unsafe fn test_vpmin_u32() { let a = u32x2::from([1, 2]); let b = u32x2::from([0, 3]); let e = u32x2::from([1, 0]); - let r: u32x2 = transmute(vpmin_u32(transmute(a), transmute(b))); + let r: u32x2 = unsafe { transmute(vpmin_u32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -68,7 +68,7 @@ unsafe fn test_vpmin_f32() { let a = f32x2::from([1., -2.]); let b = f32x2::from([0., 3.]); let e = f32x2::from([-2., 0.]); - let r: f32x2 = transmute(vpmin_f32(transmute(a), transmute(b))); + let r: f32x2 = unsafe { transmute(vpmin_f32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -77,7 +77,7 @@ unsafe fn test_vpmax_s8() { let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]); let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); let e = i8x8::from([1, 3, 6, 8, 3, 5, 7, 9]); - let r: i8x8 = transmute(vpmax_s8(transmute(a), transmute(b))); + let r: i8x8 = unsafe { transmute(vpmax_s8(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -86,7 +86,7 @@ unsafe fn test_vpmax_s16() { let a = i16x4::from([1, 2, 3, -4]); let b = i16x4::from([0, 3, 2, 5]); let e = i16x4::from([2, 3, 3, 5]); - let r: i16x4 = transmute(vpmax_s16(transmute(a), transmute(b))); + let r: i16x4 = unsafe { transmute(vpmax_s16(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -95,7 +95,7 @@ unsafe fn test_vpmax_s32() { let a = i32x2::from([1, -2]); let b = i32x2::from([0, 3]); let e = i32x2::from([1, 3]); - let r: i32x2 = transmute(vpmax_s32(transmute(a), transmute(b))); + let r: i32x2 = unsafe { transmute(vpmax_s32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -104,7 +104,7 @@ unsafe fn test_vpmax_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]); let e = u8x8::from([2, 4, 6, 8, 3, 5, 7, 9]); - let r: u8x8 = transmute(vpmax_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vpmax_u8(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -113,7 +113,7 @@ unsafe fn test_vpmax_u16() { let a = u16x4::from([1, 2, 3, 4]); let b = u16x4::from([0, 3, 2, 5]); let e = u16x4::from([2, 4, 3, 5]); - let r: u16x4 = transmute(vpmax_u16(transmute(a), transmute(b))); + let r: u16x4 = unsafe { transmute(vpmax_u16(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -122,7 +122,7 @@ unsafe fn test_vpmax_u32() { let a = u32x2::from([1, 2]); let b = u32x2::from([0, 3]); let e = u32x2::from([2, 3]); - let r: u32x2 = transmute(vpmax_u32(transmute(a), transmute(b))); + let r: u32x2 = unsafe { transmute(vpmax_u32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -131,7 +131,7 @@ unsafe fn test_vpmax_f32() { let a = f32x2::from([1., -2.]); let b = f32x2::from([0., 3.]); let e = f32x2::from([1., 3.]); - let r: f32x2 = transmute(vpmax_f32(transmute(a), transmute(b))); + let r: f32x2 = unsafe { transmute(vpmax_f32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -139,7 +139,7 @@ unsafe fn test_vpmax_f32() { unsafe fn test_vpadd_s16() { let a = i16x4::from([1, 2, 3, 4]); let b = i16x4::from([0, -1, -2, -3]); - let r: i16x4 = transmute(vpadd_s16(transmute(a), transmute(b))); + let r: i16x4 = unsafe { transmute(vpadd_s16(transmute(a), transmute(b))) }; let e = i16x4::from([3, 7, -1, -5]); assert_eq!(r, e); } @@ -147,7 +147,7 @@ unsafe fn test_vpadd_s16() { unsafe fn test_vpadd_s32() { let a = i32x2::from([1, 2]); let b = i32x2::from([0, -1]); - let r: i32x2 = transmute(vpadd_s32(transmute(a), transmute(b))); + let r: i32x2 = unsafe { transmute(vpadd_s32(transmute(a), transmute(b))) }; let e = i32x2::from([3, -1]); assert_eq!(r, e); } @@ -155,7 +155,7 @@ unsafe fn test_vpadd_s32() { unsafe fn test_vpadd_s8() { let a = i8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); let b = i8x8::from([0, -1, -2, -3, -4, -5, -6, -7]); - let r: i8x8 = transmute(vpadd_s8(transmute(a), transmute(b))); + let r: i8x8 = unsafe { transmute(vpadd_s8(transmute(a), transmute(b))) }; let e = i8x8::from([3, 7, 11, 15, -1, -5, -9, -13]); assert_eq!(r, e); } @@ -163,7 +163,7 @@ unsafe fn test_vpadd_s8() { unsafe fn test_vpadd_u16() { let a = u16x4::from([1, 2, 3, 4]); let b = u16x4::from([30, 31, 32, 33]); - let r: u16x4 = transmute(vpadd_u16(transmute(a), transmute(b))); + let r: u16x4 = unsafe { transmute(vpadd_u16(transmute(a), transmute(b))) }; let e = u16x4::from([3, 7, 61, 65]); assert_eq!(r, e); } @@ -171,7 +171,7 @@ unsafe fn test_vpadd_u16() { unsafe fn test_vpadd_u32() { let a = u32x2::from([1, 2]); let b = u32x2::from([30, 31]); - let r: u32x2 = transmute(vpadd_u32(transmute(a), transmute(b))); + let r: u32x2 = unsafe { transmute(vpadd_u32(transmute(a), transmute(b))) }; let e = u32x2::from([3, 61]); assert_eq!(r, e); } @@ -179,7 +179,7 @@ unsafe fn test_vpadd_u32() { unsafe fn test_vpadd_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]); let b = u8x8::from([30, 31, 32, 33, 34, 35, 36, 37]); - let r: u8x8 = transmute(vpadd_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vpadd_u8(transmute(a), transmute(b))) }; let e = u8x8::from([3, 7, 11, 15, 61, 65, 69, 73]); assert_eq!(r, e); } @@ -188,7 +188,7 @@ unsafe fn test_vpadd_u8() { unsafe fn test_vqsub_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]); let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]); - let r: u8x8 = transmute(vqsub_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vqsub_u8(transmute(a), transmute(b))) }; let e = u8x8::from([0, 1, 2, 3, 0, 0, 0, 218]); assert_eq!(r, e); } @@ -197,7 +197,7 @@ unsafe fn test_vqsub_u8() { unsafe fn test_vqadd_u8() { let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]); let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]); - let r: u8x8 = transmute(vqadd_u8(transmute(a), transmute(b))); + let r: u8x8 = unsafe { transmute(vqadd_u8(transmute(a), transmute(b))) }; let e = u8x8::from([31, 3, 4, 5, 39, 0xff, 43, 0xff]); assert_eq!(r, e); } @@ -208,7 +208,7 @@ unsafe fn test_vmaxq_f32() { let a = f32x4::from([0., -1., 2., -3.]); let b = f32x4::from([-4., 5., -6., 7.]); let e = f32x4::from([0., 5., 2., 7.]); - let r: f32x4 = transmute(vmaxq_f32(transmute(a), transmute(b))); + let r: f32x4 = unsafe { transmute(vmaxq_f32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -218,7 +218,7 @@ unsafe fn test_vminq_f32() { let a = f32x4::from([0., -1., 2., -3.]); let b = f32x4::from([-4., 5., -6., 7.]); let e = f32x4::from([-4., -1., -6., -3.]); - let r: f32x4 = transmute(vminq_f32(transmute(a), transmute(b))); + let r: f32x4 = unsafe { transmute(vminq_f32(transmute(a), transmute(b))) }; assert_eq!(r, e); } @@ -227,7 +227,7 @@ unsafe fn test_vaddvq_f32() { // AArch64 llvm intrinsic: llvm.aarch64.neon.faddv.f32.v4f32 let a = f32x4::from([0., 1., 2., 3.]); let e = 6f32; - let r = vaddvq_f32(transmute(a)); + let r = unsafe { vaddvq_f32(transmute(a)) }; assert_eq!(r, e); } @@ -236,7 +236,7 @@ unsafe fn test_vrndnq_f32() { // llvm intrinsic: llvm.roundeven.v4f32 let a = f32x4::from([0.1, -1.9, 4.5, 5.5]); let e = f32x4::from([0., -2., 4., 6.]); - let r: f32x4 = transmute(vrndnq_f32(transmute(a))); + let r: f32x4 = unsafe { transmute(vrndnq_f32(transmute(a))) }; assert_eq!(r, e); } diff --git a/example/raw-dylib.rs b/example/raw-dylib.rs index 4711884f76af..5f5bde7d4dc5 100644 --- a/example/raw-dylib.rs +++ b/example/raw-dylib.rs @@ -5,7 +5,7 @@ fn main() { #[cfg(windows)] { #[link(name = "kernel32", kind = "raw-dylib")] - extern "C" { + unsafe extern "C" { fn GetModuleFileNameA( module: *mut std::ffi::c_void, filename: *mut u8, diff --git a/example/std_example.rs b/example/std_example.rs index 5d83066cffb8..c569ef0ef829 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -230,51 +230,53 @@ unsafe fn test_crc32() { #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] unsafe fn test_simd() { - assert!(is_x86_feature_detected!("sse2")); + unsafe { + assert!(is_x86_feature_detected!("sse2")); - let x = _mm_setzero_si128(); - let y = _mm_set1_epi16(7); - let or = _mm_or_si128(x, y); - let cmp_eq = _mm_cmpeq_epi8(y, y); - let cmp_lt = _mm_cmplt_epi8(y, y); + let x = _mm_setzero_si128(); + let y = _mm_set1_epi16(7); + let or = _mm_or_si128(x, y); + let cmp_eq = _mm_cmpeq_epi8(y, y); + let cmp_lt = _mm_cmplt_epi8(y, y); - let (zero0, zero1) = std::mem::transmute::<_, (u64, u64)>(x); - assert_eq!((zero0, zero1), (0, 0)); - assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]); - assert_eq!( - std::mem::transmute::<_, [u16; 8]>(cmp_eq), - [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff] - ); - assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]); + let (zero0, zero1) = std::mem::transmute::<_, (u64, u64)>(x); + assert_eq!((zero0, zero1), (0, 0)); + assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]); + assert_eq!( + std::mem::transmute::<_, [u16; 8]>(cmp_eq), + [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff] + ); + assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]); - test_mm_slli_si128(); - test_mm_movemask_epi8(); - test_mm256_movemask_epi8(); - test_mm_add_epi8(); - test_mm_add_pd(); - test_mm_cvtepi8_epi16(); - #[cfg(not(jit))] - test_mm_cvtps_epi32(); - test_mm_cvttps_epi32(); - test_mm_cvtsi128_si64(); + test_mm_slli_si128(); + test_mm_movemask_epi8(); + test_mm256_movemask_epi8(); + test_mm_add_epi8(); + test_mm_add_pd(); + test_mm_cvtepi8_epi16(); + #[cfg(not(jit))] + test_mm_cvtps_epi32(); + test_mm_cvttps_epi32(); + test_mm_cvtsi128_si64(); - test_mm_extract_epi8(); - test_mm_insert_epi16(); - test_mm_shuffle_epi8(); + test_mm_extract_epi8(); + test_mm_insert_epi16(); + test_mm_shuffle_epi8(); - #[cfg(not(jit))] - test_mm_cmpestri(); + #[cfg(not(jit))] + test_mm_cmpestri(); - test_mm256_shuffle_epi8(); - test_mm256_permute2x128_si256(); - test_mm256_permutevar8x32_epi32(); + test_mm256_shuffle_epi8(); + test_mm256_permute2x128_si256(); + test_mm256_permutevar8x32_epi32(); - #[rustfmt::skip] + #[rustfmt::skip] let mask1 = _mm_movemask_epi8(dbg!(_mm_setr_epi8(255u8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); - assert_eq!(mask1, 1); + assert_eq!(mask1, 1); - #[cfg(not(jit))] - test_crc32(); + #[cfg(not(jit))] + test_crc32(); + } } #[cfg(target_arch = "x86_64")] @@ -361,7 +363,7 @@ fn assert_eq_m128i(x: std::arch::x86_64::__m128i, y: std::arch::x86_64::__m128i) #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] -pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) { +pub fn assert_eq_m128d(a: __m128d, b: __m128d) { if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 { panic!("{:?} != {:?}", a, b); } @@ -369,15 +371,19 @@ pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) { #[cfg(target_arch = "x86_64")] #[target_feature(enable = "avx")] -pub unsafe fn assert_eq_m256i(a: __m256i, b: __m256i) { - assert_eq!(std::mem::transmute::<_, [u64; 4]>(a), std::mem::transmute::<_, [u64; 4]>(b)) +pub fn assert_eq_m256i(a: __m256i, b: __m256i) { + unsafe { + assert_eq!(std::mem::transmute::<_, [u64; 4]>(a), std::mem::transmute::<_, [u64; 4]>(b)) + } } #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] unsafe fn test_mm_cvtsi128_si64() { - let r = _mm_cvtsi128_si64(std::mem::transmute::<[i64; 2], _>([5, 0])); - assert_eq!(r, 5); + unsafe { + let r = _mm_cvtsi128_si64(std::mem::transmute::<[i64; 2], _>([5, 0])); + assert_eq!(r, 5); + } } #[cfg(target_arch = "x86_64")] @@ -445,20 +451,24 @@ unsafe fn test_mm_shuffle_epi8() { #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse4.2")] unsafe fn str_to_m128i(s: &[u8]) -> __m128i { - assert!(s.len() <= 16); - let slice = &mut [0u8; 16]; - std::ptr::copy_nonoverlapping(s.as_ptr(), slice.as_mut_ptr(), s.len()); - _mm_loadu_si128(slice.as_ptr() as *const _) + unsafe { + assert!(s.len() <= 16); + let slice = &mut [0u8; 16]; + std::ptr::copy_nonoverlapping(s.as_ptr(), slice.as_mut_ptr(), s.len()); + _mm_loadu_si128(slice.as_ptr() as *const _) + } } #[cfg(not(jit))] #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse4.2")] unsafe fn test_mm_cmpestri() { - let a = str_to_m128i(b"bar - garbage"); - let b = str_to_m128i(b"foobar"); - let i = _mm_cmpestri::<_SIDD_CMP_EQUAL_ORDERED>(a, 3, b, 6); - assert_eq!(3, i); + unsafe { + let a = str_to_m128i(b"bar - garbage"); + let b = str_to_m128i(b"foobar"); + let i = _mm_cmpestri::<_SIDD_CMP_EQUAL_ORDERED>(a, 3, b, 6); + assert_eq!(3, i); + } } #[cfg(target_arch = "x86_64")] @@ -513,35 +523,39 @@ unsafe fn test_mm256_permutevar8x32_epi32() { #[target_feature(enable = "avx2")] #[cfg(not(jit))] unsafe fn test_mm_cvtps_epi32() { - let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN]; + unsafe { + let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN]; - let float_vec = _mm_loadu_ps(floats.as_ptr()); - let int_vec = _mm_cvtps_epi32(float_vec); + let float_vec = _mm_loadu_ps(floats.as_ptr()); + let int_vec = _mm_cvtps_epi32(float_vec); - let mut ints: [i32; 4] = [0; 4]; - _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec); + let mut ints: [i32; 4] = [0; 4]; + _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec); - // this is very different from `floats.map(|f| f as i32)`! - let expected_ints: [i32; 4] = [2, -2, i32::MIN, i32::MIN]; + // this is very different from `floats.map(|f| f as i32)`! + let expected_ints: [i32; 4] = [2, -2, i32::MIN, i32::MIN]; - assert_eq!(ints, expected_ints); + assert_eq!(ints, expected_ints); + } } #[cfg(target_arch = "x86_64")] #[target_feature(enable = "avx2")] unsafe fn test_mm_cvttps_epi32() { - let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN]; + unsafe { + let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN]; - let float_vec = _mm_loadu_ps(floats.as_ptr()); - let int_vec = _mm_cvttps_epi32(float_vec); + let float_vec = _mm_loadu_ps(floats.as_ptr()); + let int_vec = _mm_cvttps_epi32(float_vec); - let mut ints: [i32; 4] = [0; 4]; - _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec); + let mut ints: [i32; 4] = [0; 4]; + _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec); - // this is very different from `floats.map(|f| f as i32)`! - let expected_ints: [i32; 4] = [1, -2, i32::MIN, i32::MIN]; + // this is very different from `floats.map(|f| f as i32)`! + let expected_ints: [i32; 4] = [1, -2, i32::MIN, i32::MIN]; - assert_eq!(ints, expected_ints); + assert_eq!(ints, expected_ints); + } } fn test_checked_mul() { diff --git a/patches/0028-sysroot_tests-Disable-long-running-tests.patch b/patches/0028-sysroot_tests-Disable-long-running-tests.patch index 357b8d306cf6..853acab2773b 100644 --- a/patches/0028-sysroot_tests-Disable-long-running-tests.patch +++ b/patches/0028-sysroot_tests-Disable-long-running-tests.patch @@ -11,38 +11,41 @@ diff --git a/coretests/tests/slice.rs b/coretests/tests/slice.rs index 8402833..84592e0 100644 --- a/coretests/tests/slice.rs +++ b/coretests/tests/slice.rs -@@ -1809,6 +1809,7 @@ fn sort_unstable() { - } - } +@@ -1619,7 +1619,7 @@ fn brute_force_rotate_test_1() { -+/* #[test] #[cfg(not(target_arch = "wasm32"))] - #[cfg_attr(miri, ignore)] // Miri is too slow -@@ -1914,6 +1915,7 @@ fn select_nth_unstable() { - v.select_nth_unstable(0); - assert!(v == [0xDEADBEEF]); - } -+*/ +-#[cfg_attr(miri, ignore)] // Miri is too slow ++#[ignore] // Miri is too slow + fn select_nth_unstable() { + use core::cmp::Ordering::{Equal, Greater, Less}; - #[test] - #[should_panic(expected = "index 0 greater than length of slice")] -@@ -2462,6 +2462,7 @@ take_tests! { - #[cfg(not(miri))] // unused in Miri +@@ -2303,14 +2303,14 @@ split_off_tests! { const EMPTY_MAX: &'static [()] = &[(); usize::MAX]; -+/* // can't be a constant due to const mutability rules - #[cfg(not(miri))] // unused in Miri +-#[cfg(not(miri))] // unused in Miri ++#[cfg(any())] // unused in Miri macro_rules! empty_max_mut { -@@ -2485,6 +2486,7 @@ take_tests! { - (split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()), - (split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()), + () => { + &mut [(); usize::MAX] as _ + }; } -+*/ - #[test] - fn test_slice_from_ptr_range() { +-#[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations) ++#[cfg(any())] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations) + split_off_tests! { + slice: &[(); usize::MAX], method: split_off, + (split_off_in_bounds_max_range_to, (..usize::MAX), Some(EMPTY_MAX), &[(); 0]), +@@ -2318,7 +2318,7 @@ split_off_tests! { + (split_off_in_bounds_max_range_from, (usize::MAX..), Some(&[] as _), EMPTY_MAX), + } + +-#[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations) ++#[cfg(any())] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations) + split_off_tests! { + slice: &mut [(); usize::MAX], method: split_off_mut, + (split_off_mut_in_bounds_max_range_to, (..usize::MAX), Some(empty_max_mut!()), &mut [(); 0]), diff --git a/alloctests/tests/sort/tests.rs b/alloctests/tests/sort/tests.rs index d321f8d..8b2040a 100644 --- a/alloctests/tests/sort/tests.rs diff --git a/rust-toolchain b/rust-toolchain index 150bb562f74a..17c2cc5ac660 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-06-24" +channel = "nightly-2025-11-08" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" diff --git a/scripts/cargo-clif.rs b/scripts/cargo-clif.rs index e6c63bf5e650..e391cc7f75a9 100644 --- a/scripts/cargo-clif.rs +++ b/scripts/cargo-clif.rs @@ -12,7 +12,11 @@ fn main() { sysroot = sysroot.parent().unwrap(); } - let mut rustflags = vec!["-Cpanic=abort".to_owned(), "-Zpanic-abort-tests".to_owned()]; + let mut rustflags = vec![]; + if !cfg!(support_panic_unwind) { + rustflags.push("-Cpanic=abort".to_owned()); + rustflags.push("-Zpanic-abort-tests".to_owned()); + } if let Some(name) = option_env!("BUILTIN_BACKEND") { rustflags.push(format!("-Zcodegen-backend={name}")); } else { diff --git a/scripts/rustc-clif.rs b/scripts/rustc-clif.rs index 528031af82a8..15d929d0f5a5 100644 --- a/scripts/rustc-clif.rs +++ b/scripts/rustc-clif.rs @@ -17,8 +17,10 @@ fn main() { let passed_args = std::env::args_os().skip(1).collect::>(); let mut args = vec![]; - args.push(OsString::from("-Cpanic=abort")); - args.push(OsString::from("-Zpanic-abort-tests")); + if !cfg!(support_panic_unwind) { + args.push(OsString::from("-Cpanic=abort")); + args.push(OsString::from("-Zpanic-abort-tests")); + } if let Some(name) = option_env!("BUILTIN_BACKEND") { args.push(OsString::from(format!("-Zcodegen-backend={name}"))) } else { diff --git a/scripts/rustdoc-clif.rs b/scripts/rustdoc-clif.rs index 6ebe060d8bbd..dc5bef18cda8 100644 --- a/scripts/rustdoc-clif.rs +++ b/scripts/rustdoc-clif.rs @@ -17,8 +17,10 @@ fn main() { let passed_args = std::env::args_os().skip(1).collect::>(); let mut args = vec![]; - args.push(OsString::from("-Cpanic=abort")); - args.push(OsString::from("-Zpanic-abort-tests")); + if !cfg!(support_panic_unwind) { + args.push(OsString::from("-Cpanic=abort")); + args.push(OsString::from("-Zpanic-abort-tests")); + } if let Some(name) = option_env!("BUILTIN_BACKEND") { args.push(OsString::from(format!("-Zcodegen-backend={name}"))) } else { diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 152c243aa6ad..fdfd03029b16 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -46,7 +46,7 @@ case $1 in git pull origin master branch=sync_cg_clif-$(date +%Y-%m-%d) git checkout -b "$branch" - "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git master + "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git main git push -u my "$branch" # immediately merge the merge commit into cg_clif to prevent merge conflicts when syncing diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh index 492f4dc44527..c16cb4e538fe 100644 --- a/scripts/setup_rust_fork.sh +++ b/scripts/setup_rust_fork.sh @@ -50,23 +50,24 @@ EOF cat <( + ); } + +- #[cfg(not(test))] +- if b && dwn_ctx.is_running_on_ci && CiEnv::is_rust_lang_managed_ci_job() { +- // On rust-lang CI, we must always rebuild LLVM if there were any modifications to it +- panic!( +- "\`llvm.download-ci-llvm\` cannot be set to \`true\` on CI. Use \`if-unchanged\` instead." +- ); +- } +- + // If download-ci-llvm=true we also want to check that CI llvm is available + b && llvm::is_ci_llvm_available_for_target(&dwn_ctx.host_target, asserts) + } EOF popd diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 62f1cc6a8933..b5af585a732e 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -10,7 +10,7 @@ pushd rust command -v rg >/dev/null 2>&1 || cargo install ripgrep -rm -r tests/ui/{unsized-locals/,lto/,linkage*} || true +rm -r tests/ui/{lto/,linkage*} || true for test in $(rg --files-with-matches "lto" tests/{codegen-units,ui,incremental}); do rm $test done @@ -34,6 +34,7 @@ git checkout -- tests/ui/entry-point/auxiliary/bad_main_functions.rs # vendor intrinsics rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic rm tests/ui/simd/dont-invalid-bitcast-x86_64.rs # unimplemented llvm.x86.sse41.round.ps +rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # unimplemented simd_funnel_{shl,shr} # exotic linkages rm tests/incremental/hashes/function_interfaces.rs @@ -42,8 +43,14 @@ rm -r tests/run-make/naked-symbol-visibility # variadic arguments rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs +rm tests/ui/c-variadic/naked.rs # same rm tests/ui/abi/variadic-ffi.rs # requires callee side vararg support rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg support +rm tests/ui/c-variadic/valid.rs # same +rm tests/ui/c-variadic/trait-method.rs # same +rm tests/ui/c-variadic/inherent-method.rs # same +rm tests/ui/sanitizer/kcfi-c-variadic.rs # same +rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported rm tests/ui/delegation/fn-header.rs # misc unimplemented things @@ -56,8 +63,13 @@ rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't rm tests/ui/asm/global-asm-mono-sym-fn.rs # same rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported +rm tests/ui/asm/label-operand.rs # same rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes -rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo +rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet +rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same +rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported +rm -r tests/ui/explicit-tail-calls # tail calls +rm -r tests/run-make/pointer-auth-link-with-c # pointer auth # requires LTO rm -r tests/run-make/cdylib @@ -69,15 +81,13 @@ rm -r tests/run-make/reachable-extern-fn-available-lto # coverage instrumentation rm tests/ui/consts/precise-drop-with-coverage.rs -rm tests/ui/issues/issue-85461.rs rm -r tests/ui/instrument-coverage/ # optimization tests # ================== rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations rm tests/ui/codegen/init-large-type.rs # same -rm -r tests/run-make/fmt-write-bloat/ # tests an optimization -rm tests/ui/statics/const_generics.rs # same +rm tests/ui/statics/const_generics.rs # tests an optimization rm tests/ui/linking/executable-no-mangle-strip.rs # requires --gc-sections to work for statics # backend specific tests @@ -92,7 +102,7 @@ rm -r tests/run-make/llvm-location-discriminator-limit-dummy-span # same rm tests/ui/abi/stack-protector.rs # requires stack protector support rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific -rm -r tests/ui/optimization-remark.rs # same +rm -r tests/ui/codegen/remark-flag-functionality.rs # same rm -r tests/run-make/print-to-output # requires --print relocation-models # requires asm, llvm-ir and/or llvm-bc emit support @@ -123,6 +133,8 @@ rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump rm -r tests/run-make/strip # same rm -r tests/run-make-cargo/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source rm -r tests/run-make/translation # same +rm -r tests/run-make-cargo/panic-immediate-abort-works # same +rm -r tests/run-make-cargo/panic-immediate-abort-codegen # same rm -r tests/run-make/missing-unstable-trait-bound # This disables support for unstable features, but running cg_clif needs some unstable features rm -r tests/run-make/const-trait-stable-toolchain # same rm -r tests/run-make/print-request-help-stable-unstable # same @@ -130,6 +142,7 @@ rm -r tests/run-make/incr-add-rust-src-component rm tests/ui/errors/remap-path-prefix-sysroot.rs # different sysroot source path rm -r tests/run-make/export/extern-opt # something about rustc version mismatches rm -r tests/run-make/export # same +rm -r tests/ui/compiletest-self-test/compile-flags-incremental.rs # needs compiletest compiled with panic=unwind # genuine bugs # ============ @@ -143,9 +156,9 @@ rm tests/ui/backtrace/synchronized-panic-handler.rs # missing needs-unwind annot rm tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs # same rm tests/ui/async-await/async-drop/async-drop-initial.rs # same (rust-lang/rust#140493) rm -r tests/ui/codegen/equal-pointers-unequal # make incorrect assumptions about the location of stack variables +rm -r tests/run-make-cargo/rustdoc-scrape-examples-paths # FIXME(rust-lang/rust#145580) incr comp bug -rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd -rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # same +rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # really slow with unoptimized libstd rm tests/ui/process/process-panic-after-fork.rs # same cp ../dist/bin/rustdoc-clif ../dist/bin/rustdoc # some tests expect bin/rustdoc to exist diff --git a/src/abi/mod.rs b/src/abi/mod.rs index d7f17795815d..9ac282df5b5e 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -7,7 +7,9 @@ mod returning; use std::borrow::Cow; use std::mem; -use cranelift_codegen::ir::{ArgumentPurpose, SigRef}; +use cranelift_codegen::ir::{ + ArgumentPurpose, BlockArg, ExceptionTableData, ExceptionTableItem, ExceptionTag, SigRef, +}; use cranelift_codegen::isa::CallConv; use cranelift_module::ModuleError; use rustc_abi::{CanonAbi, ExternAbi, X86Call}; @@ -21,10 +23,12 @@ use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_target::callconv::{FnAbi, PassMode}; use rustc_target::spec::Arch; -use smallvec::SmallVec; +use smallvec::{SmallVec, smallvec}; use self::pass_mode::*; pub(crate) use self::returning::codegen_return; +use crate::base::codegen_unwind_terminate; +use crate::debuginfo::EXCEPTION_HANDLER_CLEANUP; use crate::prelude::*; fn clif_sig_from_fn_abi<'tcx>( @@ -82,7 +86,7 @@ pub(crate) fn get_function_sig<'tcx>( clif_sig_from_fn_abi( tcx, default_call_conv, - &FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()), + FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()), ) } @@ -111,7 +115,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { /// Instance must be monomorphized pub(crate) fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef { let func_id = import_function(self.tcx, self.module, inst); - let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func); + let func_ref = self.module.declare_func_in_func(func_id, self.bcx.func); if self.clif_comments.enabled() { self.add_comment(func_ref, format!("{:?}", inst)); @@ -182,7 +186,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { ) -> &[Value] { let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv }; let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap(); - let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func); + let func_ref = self.module.declare_func_in_func(func_id, self.bcx.func); let call_inst = self.bcx.ins().call(func_ref, args); if self.clif_comments.enabled() { self.add_comment(func_ref, format!("{:?}", name)); @@ -267,7 +271,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ // individual function arguments. let tupled_arg_tys = match arg_ty.kind() { - ty::Tuple(ref tys) => tys, + ty::Tuple(tys) => tys, _ => bug!("spread argument isn't a tuple?! but {:?}", arg_ty), }; @@ -297,7 +301,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ Some(cvalue_for_param(fx, None, None, arg_abi, &mut block_params_iter).unwrap()); } - assert!(arg_abis_iter.next().is_none(), "ArgAbi left behind"); + assert_eq!(arg_abis_iter.next(), None, "ArgAbi left behind for {:?}", fx.fn_abi); assert!(block_params_iter.next().is_none(), "arg_value left behind"); self::comments::add_locals_header_comment(fx); @@ -381,7 +385,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( args: &[Spanned>], destination: Place<'tcx>, target: Option, - _unwind: UnwindAction, + unwind: UnwindAction, ) { let func = codegen_operand(fx, func); let fn_sig = func.layout().ty.fn_sig(fx.tcx); @@ -416,7 +420,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( if fx.tcx.symbol_name(instance).name.starts_with("llvm.") { crate::intrinsics::codegen_llvm_intrinsic_call( fx, - &fx.tcx.symbol_name(instance).name, + fx.tcx.symbol_name(instance).name, args, ret_place, target, @@ -490,7 +494,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( }; let tupled_arguments = match pack_arg.value.layout().ty.kind() { - ty::Tuple(ref tupled_arguments) => tupled_arguments, + ty::Tuple(tupled_arguments) => tupled_arguments, _ => bug!("argument to function with \"rust-call\" ABI is not a tuple"), }; @@ -516,12 +520,6 @@ pub(crate) fn codegen_terminator_call<'tcx>( let args = args; assert_eq!(fn_abi.args.len(), args.len()); - #[derive(Copy, Clone)] - enum CallTarget { - Direct(FuncRef), - Indirect(SigRef, Value), - } - let (func_ref, first_arg_override) = match instance { // Trait object call Some(Instance { def: InstanceKind::Virtual(_, idx), .. }) => { @@ -537,7 +535,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } let (ptr, method) = crate::vtable::get_ptr_and_method_ref(fx, args[0].value, idx); - let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); + let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, fn_abi); let sig = fx.bcx.import_signature(sig); (CallTarget::Indirect(sig, method), Some(ptr.get_addr(fx))) @@ -557,7 +555,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } let func = func.load_scalar(fx); - let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); + let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, fn_abi); let sig = fx.bcx.import_signature(sig); (CallTarget::Indirect(sig, func), None) @@ -567,7 +565,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( self::returning::codegen_with_call_return_arg(fx, &fn_abi.ret, ret_place, |fx, return_ptr| { let mut call_args = return_ptr .into_iter() - .chain(first_arg_override.into_iter()) + .chain(first_arg_override) .chain( args.into_iter() .enumerate() @@ -580,21 +578,15 @@ pub(crate) fn codegen_terminator_call<'tcx>( // FIXME: Find a cleaner way to support varargs. if fn_abi.c_variadic { - adjust_call_for_c_variadic(fx, &fn_abi, source_info, func_ref, &mut call_args); + adjust_call_for_c_variadic(fx, fn_abi, source_info, func_ref, &mut call_args); } - let call_inst = match func_ref { - CallTarget::Direct(func_ref) => fx.bcx.ins().call(func_ref, &call_args), - CallTarget::Indirect(sig, func_ptr) => { - fx.bcx.ins().call_indirect(sig, func_ptr, &call_args) - } - }; - if fx.clif_comments.enabled() { - with_no_trimmed_paths!(fx.add_comment(call_inst, format!("abi: {:?}", fn_abi))); + let nop_inst = fx.bcx.ins().nop(); + with_no_trimmed_paths!(fx.add_post_comment(nop_inst, format!("abi: {:?}", fn_abi))); } - fx.bcx.func.dfg.inst_results(call_inst).iter().copied().collect::>() + codegen_call_with_unwind_action(fx, source_info.span, func_ref, unwind, &call_args, None) }); if let Some(dest) = target { @@ -704,7 +696,7 @@ pub(crate) fn codegen_drop<'tcx>( source_info: mir::SourceInfo, drop_place: CPlace<'tcx>, target: BasicBlock, - _unwind: UnwindAction, + unwind: UnwindAction, ) { let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty); @@ -748,11 +740,16 @@ pub(crate) fn codegen_drop<'tcx>( let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx) .fn_abi_of_instance(virtual_drop, ty::List::empty()); - let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi); + let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, fn_abi); let sig = fx.bcx.import_signature(sig); - // FIXME implement cleanup on exceptions - fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]); - fx.bcx.ins().jump(ret_block, &[]); + codegen_call_with_unwind_action( + fx, + source_info.span, + CallTarget::Indirect(sig, drop_fn), + unwind, + &[ptr], + Some(ret_block), + ); } _ => { assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _))); @@ -771,15 +768,146 @@ pub(crate) fn codegen_drop<'tcx>( if drop_instance.def.requires_caller_location(fx.tcx) { // Pass the caller location for `#[track_caller]`. let caller_location = fx.get_caller_location(source_info); - call_args.extend( - adjust_arg_for_abi(fx, caller_location, &fn_abi.args[1], false).into_iter(), - ); + call_args.extend(adjust_arg_for_abi( + fx, + caller_location, + &fn_abi.args[1], + false, + )); } let func_ref = fx.get_function_ref(drop_instance); - fx.bcx.ins().call(func_ref, &call_args); - // FIXME implement cleanup on exceptions - fx.bcx.ins().jump(ret_block, &[]); + codegen_call_with_unwind_action( + fx, + source_info.span, + CallTarget::Direct(func_ref), + unwind, + &call_args, + Some(ret_block), + ); + } + } + } +} + +#[derive(Copy, Clone)] +pub(crate) enum CallTarget { + Direct(FuncRef), + Indirect(SigRef, Value), +} + +pub(crate) fn codegen_call_with_unwind_action( + fx: &mut FunctionCx<'_, '_, '_>, + span: Span, + func_ref: CallTarget, + mut unwind: UnwindAction, + call_args: &[Value], + target_block: Option, +) -> SmallVec<[Value; 2]> { + let sig_ref = match func_ref { + CallTarget::Direct(func_ref) => fx.bcx.func.dfg.ext_funcs[func_ref].signature, + CallTarget::Indirect(sig_ref, _func_ptr) => sig_ref, + }; + + if target_block.is_some() { + assert!(fx.bcx.func.dfg.signatures[sig_ref].returns.is_empty()); + } + + if cfg!(not(feature = "unwinding")) { + unwind = UnwindAction::Unreachable; + } + + match unwind { + UnwindAction::Continue | UnwindAction::Unreachable => { + let call_inst = match func_ref { + CallTarget::Direct(func_ref) => fx.bcx.ins().call(func_ref, call_args), + CallTarget::Indirect(sig, func_ptr) => { + fx.bcx.ins().call_indirect(sig, func_ptr, call_args) + } + }; + + if let Some(target_block) = target_block { + fx.bcx.ins().jump(target_block, &[]); + smallvec![] + } else { + fx.bcx + .func + .dfg + .inst_results(call_inst) + .iter() + .copied() + .collect::>() + } + } + UnwindAction::Cleanup(_) | UnwindAction::Terminate(_) => { + let returns_types = fx.bcx.func.dfg.signatures[sig_ref] + .returns + .iter() + .map(|return_param| return_param.value_type) + .collect::>(); + + let fallthrough_block = fx.bcx.create_block(); + let fallthrough_block_call_args = returns_types + .iter() + .enumerate() + .map(|(i, _)| BlockArg::TryCallRet(i.try_into().unwrap())) + .collect::>(); + let fallthrough_block_call = fx.bcx.func.dfg.block_call( + target_block.unwrap_or(fallthrough_block), + &fallthrough_block_call_args, + ); + let pre_cleanup_block = fx.bcx.create_block(); + let pre_cleanup_block_call = + fx.bcx.func.dfg.block_call(pre_cleanup_block, &[BlockArg::TryCallExn(0)]); + let exception_table = fx.bcx.func.dfg.exception_tables.push(ExceptionTableData::new( + sig_ref, + fallthrough_block_call, + [ExceptionTableItem::Tag( + ExceptionTag::with_number(EXCEPTION_HANDLER_CLEANUP).unwrap(), + pre_cleanup_block_call, + )], + )); + + match func_ref { + CallTarget::Direct(func_ref) => { + fx.bcx.ins().try_call(func_ref, call_args, exception_table); + } + CallTarget::Indirect(_sig, func_ptr) => { + fx.bcx.ins().try_call_indirect(func_ptr, call_args, exception_table); + } + } + + fx.bcx.seal_block(pre_cleanup_block); + fx.bcx.switch_to_block(pre_cleanup_block); + fx.bcx.set_cold_block(pre_cleanup_block); + match unwind { + UnwindAction::Continue | UnwindAction::Unreachable => unreachable!(), + UnwindAction::Cleanup(cleanup) => { + let exception_ptr = + fx.bcx.append_block_param(pre_cleanup_block, fx.pointer_type); + fx.bcx.def_var(fx.exception_slot, exception_ptr); + let cleanup_block = fx.get_block(cleanup); + fx.bcx.ins().jump(cleanup_block, &[]); + } + UnwindAction::Terminate(reason) => { + // FIXME dedup terminate blocks + fx.bcx.append_block_param(pre_cleanup_block, fx.pointer_type); + + codegen_unwind_terminate(fx, span, reason); + } + } + + if target_block.is_none() { + fx.bcx.seal_block(fallthrough_block); + fx.bcx.switch_to_block(fallthrough_block); + let returns = returns_types + .into_iter() + .map(|ty| fx.bcx.append_block_param(fallthrough_block, ty)) + .collect(); + fx.bcx.ins().nop(); + returns + } else { + smallvec![] } } } diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index 7a909a740b05..44b63aa95f83 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -209,12 +209,7 @@ pub(super) fn to_casted_value<'tcx>( cast_target_to_abi_params(cast) .into_iter() .map(|(offset, param)| { - let val = ptr.offset_i64(fx, offset.bytes() as i64).load( - fx, - param.value_type, - MemFlags::new(), - ); - val + ptr.offset_i64(fx, offset.bytes() as i64).load(fx, param.value_type, MemFlags::new()) }) .collect() } diff --git a/src/base.rs b/src/base.rs index 7d50548b4026..0d3b38d52c8d 100644 --- a/src/base.rs +++ b/src/base.rs @@ -12,6 +12,8 @@ use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv}; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_session::config::OutputFilenames; +use rustc_span::Symbol; use crate::constant::ConstantCx; use crate::debuginfo::{FunctionDebugContext, TypeDebugContext}; @@ -25,11 +27,13 @@ pub(crate) struct CodegenedFunction { func: Function, clif_comments: CommentWriter, func_debug_cx: Option, + inline_asm: String, } pub(crate) fn codegen_fn<'tcx>( tcx: TyCtxt<'tcx>, - cx: &mut crate::CodegenCx, + cgu_name: Symbol, + mut debug_context: Option<&mut DebugContext>, type_dbg: &mut TypeDebugContext<'tcx>, cached_func: Function, module: &mut dyn Module, @@ -60,7 +64,9 @@ pub(crate) fn codegen_fn<'tcx>( func.clear(); func.name = UserFuncName::user(0, func_id.as_u32()); func.signature = sig; - func.collect_debug_info(); + if debug_context.is_some() { + func.collect_debug_info(); + } let mut bcx = FunctionBuilder::new(&mut func, &mut func_ctx); @@ -74,23 +80,27 @@ pub(crate) fn codegen_fn<'tcx>( // Make FunctionCx let target_config = module.target_config(); let pointer_type = target_config.pointer_type(); + assert_eq!(pointer_ty(tcx), pointer_type); let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance, fn_abi); - let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context { + let func_debug_cx = if let Some(debug_context) = debug_context.as_deref_mut() { Some(debug_context.define_function(tcx, type_dbg, instance, fn_abi, &symbol_name, mir.span)) } else { None }; + let exception_slot = bcx.declare_var(pointer_type); + let mut fx = FunctionCx { - cx, module, + debug_context, tcx, target_config, pointer_type, constants_cx: ConstantCx::new(), func_debug_cx, + cgu_name, instance, symbol_name, mir, @@ -100,9 +110,11 @@ pub(crate) fn codegen_fn<'tcx>( block_map, local_map: IndexVec::with_capacity(mir.local_decls.len()), caller_location: None, // set by `codegen_fn_prelude` + exception_slot, clif_comments, - next_ssa_var: 0, + inline_asm: String::new(), + inline_asm_index: 0, }; tcx.prof.generic_activity("codegen clif ir").run(|| codegen_fn_body(&mut fx, start_block)); @@ -113,10 +125,11 @@ pub(crate) fn codegen_fn<'tcx>( let symbol_name = fx.symbol_name; let clif_comments = fx.clif_comments; let func_debug_cx = fx.func_debug_cx; + let inline_asm = fx.inline_asm; fx.constants_cx.finalize(fx.tcx, &mut *fx.module); - if cx.should_write_ir { + if crate::pretty_clif::should_write_ir(tcx.sess) { crate::pretty_clif::write_clif_file( tcx.output_filenames(()), &symbol_name, @@ -130,20 +143,24 @@ pub(crate) fn codegen_fn<'tcx>( // Verify function verify_func(tcx, &clif_comments, &func); - CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx } + CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx, inline_asm } } pub(crate) fn compile_fn( - cx: &mut crate::CodegenCx, profiler: &SelfProfilerRef, + output_filenames: &OutputFilenames, + should_write_ir: bool, cached_context: &mut Context, module: &mut dyn Module, + debug_context: Option<&mut DebugContext>, + global_asm: &mut String, codegened_func: CodegenedFunction, ) { let _timer = profiler.generic_activity_with_arg("compile function", &*codegened_func.symbol_name); let clif_comments = codegened_func.clif_comments; + global_asm.push_str(&codegened_func.inline_asm); // Store function in context let context = cached_context; @@ -180,7 +197,7 @@ pub(crate) fn compile_fn( // Define function profiler.generic_activity("define function").run(|| { - context.want_disasm = cx.should_write_ir; + context.want_disasm = should_write_ir; match module.define_function(codegened_func.func_id, context) { Ok(()) => {} Err(ModuleError::Compilation(CodegenError::ImplLimitExceeded)) => { @@ -210,10 +227,10 @@ pub(crate) fn compile_fn( } }); - if cx.should_write_ir { + if should_write_ir { // Write optimized function to file for debugging crate::pretty_clif::write_clif_file( - &cx.output_filenames, + output_filenames, &codegened_func.symbol_name, "opt", module.isa(), @@ -223,7 +240,7 @@ pub(crate) fn compile_fn( if let Some(disasm) = &context.compiled_code().unwrap().vcode { crate::pretty_clif::write_ir_file( - &cx.output_filenames, + output_filenames, &format!("{}.vcode", codegened_func.symbol_name), |file| file.write_all(disasm.as_bytes()), ) @@ -231,7 +248,6 @@ pub(crate) fn compile_fn( } // Define debuginfo for function - let debug_context = &mut cx.debug_context; profiler.generic_activity("generate debug info").run(|| { if let Some(debug_context) = debug_context { codegened_func.func_debug_cx.unwrap().finalize( @@ -250,12 +266,12 @@ fn verify_func(tcx: TyCtxt<'_>, writer: &crate::pretty_clif::CommentWriter, func tcx.prof.generic_activity("verify clif ir").run(|| { let flags = cranelift_codegen::settings::Flags::new(cranelift_codegen::settings::builder()); - match cranelift_codegen::verify_function(&func, &flags) { + match cranelift_codegen::verify_function(func, &flags) { Ok(_) => {} Err(err) => { tcx.dcx().err(format!("{:?}", err)); let pretty_error = cranelift_codegen::print_errors::pretty_verifier_error( - &func, + func, Some(Box::new(writer)), err, ); @@ -295,11 +311,11 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } if bb_data.is_cleanup { - // Unwinding after panicking is not supported - continue; + if cfg!(not(feature = "unwinding")) { + continue; + } - // FIXME Once unwinding is supported and Cranelift supports marking blocks as cold, do - // so for cleanup blocks. + fx.bcx.set_cold_block(block); } fx.bcx.ins().nop(); @@ -369,7 +385,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { fx.bcx.ins().nop(); match &**msg { - AssertKind::BoundsCheck { ref len, ref index } => { + AssertKind::BoundsCheck { len, index } => { let len = codegen_operand(fx, len).load_scalar(fx); let index = codegen_operand(fx, index).load_scalar(fx); let location = fx.get_caller_location(source_info).load_scalar(fx); @@ -382,7 +398,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { source_info.span, ); } - AssertKind::MisalignedPointerDereference { ref required, ref found } => { + AssertKind::MisalignedPointerDereference { required, found } => { let required = codegen_operand(fx, required).load_scalar(fx); let found = codegen_operand(fx, found).load_scalar(fx); let location = fx.get_caller_location(source_info).load_scalar(fx); @@ -538,14 +554,22 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { template, operands, *options, - targets.get(0).copied(), + targets.first().copied(), ); } TerminatorKind::UnwindTerminate(reason) => { codegen_unwind_terminate(fx, source_info.span, *reason); } TerminatorKind::UnwindResume => { - // FIXME implement unwinding + if cfg!(feature = "unwinding") { + let exception_ptr = fx.bcx.use_var(fx.exception_slot); + fx.lib_call( + "_Unwind_Resume", + vec![AbiParam::new(fx.pointer_type)], + vec![], + &[exception_ptr], + ); + } fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); } TerminatorKind::Unreachable => { @@ -929,7 +953,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: | StatementKind::AscribeUserType(..) => {} StatementKind::Coverage { .. } => unreachable!(), - StatementKind::Intrinsic(ref intrinsic) => match &**intrinsic { + StatementKind::Intrinsic(intrinsic) => match &**intrinsic { // We ignore `assume` intrinsics, they are only useful for optimizations NonDivergingIntrinsic::Assume(_) => {} NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping { @@ -1060,7 +1084,7 @@ pub(crate) fn codegen_panic_nounwind<'tcx>( msg_str: &str, span: Span, ) { - let msg_ptr = fx.anonymous_str(msg_str); + let msg_ptr = crate::constant::pointer_for_anonymous_str(fx, msg_str); let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); let args = [msg_ptr, msg_len]; @@ -1085,7 +1109,7 @@ fn codegen_panic_inner<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, lang_item: rustc_hir::LangItem, args: &[Value], - _unwind: UnwindAction, + unwind: UnwindAction, span: Span, ) { fx.bcx.set_cold_block(fx.bcx.current_block().unwrap()); @@ -1101,14 +1125,23 @@ fn codegen_panic_inner<'tcx>( let symbol_name = fx.tcx.symbol_name(instance).name; - // FIXME implement cleanup on exceptions + let sig = Signature { + params: args.iter().map(|&arg| AbiParam::new(fx.bcx.func.dfg.value_type(arg))).collect(), + returns: vec![], + call_conv: fx.target_config.default_call_conv, + }; + let func_id = fx.module.declare_function(symbol_name, Linkage::Import, &sig).unwrap(); + let func_ref = fx.module.declare_func_in_func(func_id, fx.bcx.func); + if fx.clif_comments.enabled() { + fx.add_comment(func_ref, format!("{:?}", symbol_name)); + } - fx.lib_call( - symbol_name, - args.iter().map(|&arg| AbiParam::new(fx.bcx.func.dfg.value_type(arg))).collect(), - vec![], - args, - ); + let nop_inst = fx.bcx.ins().nop(); + if fx.clif_comments.enabled() { + fx.add_comment(nop_inst, format!("panic {}", symbol_name)); + } + + codegen_call_with_unwind_action(fx, span, CallTarget::Direct(func_ref), unwind, args, None); fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); } diff --git a/src/codegen_f16_f128.rs b/src/codegen_f16_f128.rs index c0f6d9d853db..91f7220667ff 100644 --- a/src/codegen_f16_f128.rs +++ b/src/codegen_f16_f128.rs @@ -1,5 +1,6 @@ use rustc_target::spec::Arch; +use crate::compiler_builtins::CMP_RESULT_TY; use crate::prelude::*; pub(crate) fn f16_to_f32(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { @@ -74,15 +75,11 @@ pub(crate) fn fcmp(fx: &mut FunctionCx<'_, '_, '_>, cc: FloatCC, lhs: Value, rhs let res = fx.lib_call( name, vec![AbiParam::new(types::F128), AbiParam::new(types::F128)], - // FIXME(rust-lang/compiler-builtins#919): This should be `I64` on non-AArch64 - // architectures, but switching it before compiler-builtins is fixed causes test - // failures. - vec![AbiParam::new(types::I32)], + vec![AbiParam::new(CMP_RESULT_TY)], &[lhs, rhs], )[0]; - let zero = fx.bcx.ins().iconst(types::I32, 0); - let res = fx.bcx.ins().icmp(int_cc, res, zero); - res + let zero = fx.bcx.ins().iconst(CMP_RESULT_TY, 0); + fx.bcx.ins().icmp(int_cc, res, zero) } _ => unreachable!("{ty:?}"), } diff --git a/src/common.rs b/src/common.rs index de3d2f31af10..38676eaac3d5 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,11 +1,12 @@ use cranelift_codegen::isa::TargetFrontendConfig; -use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; use rustc_abi::{Float, Integer, Primitive}; use rustc_index::IndexVec; use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, }; +use rustc_span::Symbol; use rustc_span::source_map::Spanned; use rustc_target::callconv::FnAbi; use rustc_target::spec::{Arch, HasTargetSpec, Target}; @@ -256,7 +257,7 @@ pub(crate) fn create_wrapper_function( .map(|param| func.dfg.append_block_param(block, param.value_type)) .collect::>(); - let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func); + let callee_func_ref = module.declare_func_in_func(callee_func_id, bcx.func); let call_inst = bcx.ins().call(callee_func_ref, &args); let results = bcx.inst_results(call_inst).to_vec(); // Clone to prevent borrow error @@ -268,14 +269,15 @@ pub(crate) fn create_wrapper_function( } pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { - pub(crate) cx: &'clif mut crate::CodegenCx, pub(crate) module: &'m mut dyn Module, + pub(crate) debug_context: Option<&'clif mut DebugContext>, pub(crate) tcx: TyCtxt<'tcx>, pub(crate) target_config: TargetFrontendConfig, // Cached from module pub(crate) pointer_type: Type, // Cached from module pub(crate) constants_cx: ConstantCx, pub(crate) func_debug_cx: Option, + pub(crate) cgu_name: Symbol, pub(crate) instance: Instance<'tcx>, pub(crate) symbol_name: String, pub(crate) mir: &'tcx Body<'tcx>, @@ -288,10 +290,13 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { /// When `#[track_caller]` is used, the implicit caller location is stored in this variable. pub(crate) caller_location: Option>, + /// During cleanup the exception pointer will be stored in this variable. + pub(crate) exception_slot: Variable, + pub(crate) clif_comments: crate::pretty_clif::CommentWriter, - /// This should only be accessed by `CPlace::new_var`. - pub(crate) next_ssa_var: u32, + pub(crate) inline_asm: String, + pub(crate) inline_asm_index: u32, } impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> { @@ -369,7 +374,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) fn create_stack_slot(&mut self, size: u32, align: u32) -> Pointer { assert!( - size % align == 0, + size.is_multiple_of(align), "size must be a multiple of alignment (size={size}, align={align})" ); @@ -379,7 +384,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { kind: StackSlotKind::ExplicitSlot, // FIXME Don't force the size to a multiple of bytes once Cranelift gets // a way to specify stack slot alignment. - size: (size + abi_align - 1) / abi_align * abi_align, + size: size.div_ceil(abi_align) * abi_align, align_shift: 4, }); Pointer::stack_slot(stack_slot) @@ -401,7 +406,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { } pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) { - if let Some(debug_context) = &mut self.cx.debug_context { + if let Some(debug_context) = &mut self.debug_context { let (file_id, line, column) = debug_context.get_span_loc(self.tcx, self.mir.span, source_info.span); @@ -417,21 +422,6 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { crate::constant::codegen_const_value(self, const_loc, self.tcx.caller_location_ty()) }) } - - pub(crate) fn anonymous_str(&mut self, msg: &str) -> Value { - let mut data = DataDescription::new(); - data.define(msg.as_bytes().to_vec().into_boxed_slice()); - let msg_id = self.module.declare_anonymous_data(false, false).unwrap(); - - // Ignore DuplicateDefinition error, as the data will be the same - let _ = self.module.define_data(msg_id, &data); - - let local_msg_id = self.module.declare_data_in_func(msg_id, self.bcx.func); - if self.clif_comments.enabled() { - self.add_comment(local_msg_id, msg); - } - self.bcx.ins().global_value(self.pointer_type, local_msg_id) - } } pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>); diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs index 6eea19211fa1..ca9157daae58 100644 --- a/src/compiler_builtins.rs +++ b/src/compiler_builtins.rs @@ -3,11 +3,34 @@ use std::ffi::c_int; #[cfg(feature = "jit")] use std::ffi::c_void; +use cranelift_codegen::ir::{Type, types}; + // FIXME replace with core::ffi::c_size_t once stabilized #[allow(non_camel_case_types)] #[cfg(feature = "jit")] type size_t = usize; +// Needs to stay in sync with compiler-builtins + +// Aarch64 uses `int` rather than a pointer-sized value. +#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] +#[cfg(feature = "jit")] +type CmpResult = i32; +#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] +pub(crate) const CMP_RESULT_TY: Type = types::I32; + +// In compiler-rt, LLP64 ABIs use `long long` and everything else uses `long`. In effect, +// this means the return value is always pointer-sized. +#[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))] +#[cfg(feature = "jit")] +type CmpResult = isize; +#[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))] +#[cfg(target_pointer_width = "32")] +pub(crate) const CMP_RESULT_TY: Type = types::I32; +#[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))] +#[cfg(target_pointer_width = "64")] +pub(crate) const CMP_RESULT_TY: Type = types::I64; + macro_rules! builtin_functions { ( $register:ident; @@ -18,7 +41,7 @@ macro_rules! builtin_functions { ) => { #[cfg(feature = "jit")] #[allow(improper_ctypes)] - extern "C" { + unsafe extern "C" { $( $(#[$attr])? fn $name($($arg_name: $arg_ty),*) -> $ret_ty; @@ -85,15 +108,18 @@ builtin_functions! { fn __divtf3(a: f128, b: f128) -> f128; fn fmodf(a: f32, b: f32) -> f32; fn fmod(a: f64, b: f64) -> f64; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fmodf128(a: f128, b: f128) -> f128; // float comparison - fn __eqtf2(a: f128, b: f128) -> i32; - fn __netf2(a: f128, b: f128) -> i32; - fn __lttf2(a: f128, b: f128) -> i32; - fn __letf2(a: f128, b: f128) -> i32; - fn __gttf2(a: f128, b: f128) -> i32; - fn __getf2(a: f128, b: f128) -> i32; + fn __eqtf2(a: f128, b: f128) -> CmpResult; + fn __netf2(a: f128, b: f128) -> CmpResult; + fn __lttf2(a: f128, b: f128) -> CmpResult; + fn __letf2(a: f128, b: f128) -> CmpResult; + fn __gttf2(a: f128, b: f128) -> CmpResult; + fn __getf2(a: f128, b: f128) -> CmpResult; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fminimumf128(a: f128, b: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fmaximumf128(a: f128, b: f128) -> f128; // Cranelift float libcalls fn fmaf(a: f32, b: f32, c: f32) -> f32; @@ -127,16 +153,27 @@ builtin_functions! { fn sin(f: f64) -> f64; fn cosf(f: f32) -> f32; fn cos(f: f64) -> f64; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn fmaf128(a: f128, b: f128, c: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn floorf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn floorf128(f: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn ceilf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn ceilf128(f: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn truncf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn truncf128(f: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn rintf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn rintf128(f: f128) -> f128; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn sqrtf16(f: f16) -> f16; + #[cfg(not(all(target_os = "windows", target_env = "gnu")))] fn sqrtf128(f: f128) -> f128; // FIXME(f16_f128): Add other float intrinsics as compiler-builtins gains support (meaning they // are available on all targets). diff --git a/src/config.rs b/src/config.rs index d328b33a704f..31bc0374460f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,5 @@ /// Configuration of cg_clif as passed in through `-Cllvm-args` and various env vars. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct BackendConfig { /// Should the crate be AOT compiled or JIT executed. /// diff --git a/src/constant.rs b/src/constant.rs index 3243e12e6999..2b65b8290681 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -3,6 +3,7 @@ use std::cmp::Ordering; use cranelift_module::*; +use rustc_const_eval::interpret::CTFE_ALLOC_SALT; use rustc_data_structures::fx::FxHashSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{ @@ -64,7 +65,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( // For a declaration the stated mutability doesn't matter. false, ); - let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("tls {:?}", def_id)); } @@ -110,7 +111,7 @@ pub(crate) fn codegen_const_value<'tcx>( ConstValue::Scalar(x) => match x { Scalar::Int(int) => { if fx.clif_type(layout.ty).is_some() { - return CValue::const_val(fx, layout, int); + CValue::const_val(fx, layout, int) } else { let raw_val = int.size().truncate(int.to_bits(int.size())); let val = match int.size().bytes() { @@ -140,11 +141,7 @@ pub(crate) fn codegen_const_value<'tcx>( let base_addr = match fx.tcx.global_alloc(alloc_id) { GlobalAlloc::Memory(alloc) => { if alloc.inner().len() == 0 { - let val = alloc.inner().align.bytes().wrapping_add(offset.bytes()); - fx.bcx.ins().iconst( - fx.pointer_type, - fx.tcx.truncate_to_target_usize(val) as i64, - ) + fx.bcx.ins().iconst(fx.pointer_type, alloc.inner().align.bytes() as i64) } else { let data_id = data_id_for_alloc_id( &mut fx.constants_cx, @@ -153,17 +150,16 @@ pub(crate) fn codegen_const_value<'tcx>( alloc.inner().mutability, ); let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", alloc_id)); } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } } GlobalAlloc::Function { instance, .. } => { let func_id = crate::abi::import_function(fx.tcx, fx.module, instance); - let local_func_id = - fx.module.declare_func_in_func(func_id, &mut fx.bcx.func); + let local_func_id = fx.module.declare_func_in_func(func_id, fx.bcx.func); fx.bcx.ins().func_addr(fx.pointer_type, local_func_id) } GlobalAlloc::VTable(ty, dyn_ty) => { @@ -176,9 +172,8 @@ pub(crate) fn codegen_const_value<'tcx>( fx.tcx.instantiate_bound_regions_with_erased(principal) }), ); - let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } GlobalAlloc::TypeId { .. } => { return CValue::const_val( @@ -194,16 +189,26 @@ pub(crate) fn codegen_const_value<'tcx>( // For a declaration the stated mutability doesn't matter. false, ); - let local_data_id = - fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", def_id)); } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + if fx + .tcx + .codegen_fn_attrs(def_id) + .flags + .contains(CodegenFnAttrFlags::THREAD_LOCAL) + { + fx.bcx.ins().tls_value(fx.pointer_type, local_data_id) + } else { + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) + } } }; let val = if offset.bytes() != 0 { - fx.bcx.ins().iadd_imm(base_addr, i64::try_from(offset.bytes()).unwrap()) + fx.bcx + .ins() + .iadd_imm(base_addr, fx.tcx.truncate_to_target_usize(offset.bytes()) as i64) } else { base_addr }; @@ -211,32 +216,28 @@ pub(crate) fn codegen_const_value<'tcx>( } }, ConstValue::Indirect { alloc_id, offset } => CValue::by_ref( - pointer_for_allocation(fx, alloc_id) + Pointer::new(pointer_for_allocation(fx, alloc_id)) .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()), layout, ), ConstValue::Slice { alloc_id, meta } => { - let ptr = pointer_for_allocation(fx, alloc_id).get_addr(fx); + let ptr = pointer_for_allocation(fx, alloc_id); let len = fx.bcx.ins().iconst(fx.pointer_type, meta as i64); CValue::by_val_pair(ptr, len, layout) } } } -fn pointer_for_allocation<'tcx>( - fx: &mut FunctionCx<'_, '_, 'tcx>, - alloc_id: AllocId, -) -> crate::pointer::Pointer { +fn pointer_for_allocation<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, alloc_id: AllocId) -> Value { let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); let data_id = data_id_for_alloc_id(&mut fx.constants_cx, fx.module, alloc_id, alloc.inner().mutability); - let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("{:?}", alloc_id)); } - let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id); - crate::pointer::Pointer::new(global_ptr) + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } fn data_id_for_alloc_id( @@ -262,6 +263,11 @@ pub(crate) fn data_id_for_vtable<'tcx>( data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) } +pub(crate) fn pointer_for_anonymous_str(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) -> Value { + let alloc_id = fx.tcx.allocate_bytes_dedup(msg.as_bytes(), CTFE_ALLOC_SALT); + pointer_for_allocation(fx, alloc_id) +} + fn data_id_for_static( tcx: TyCtxt<'_>, module: &mut dyn Module, @@ -345,7 +351,7 @@ fn data_id_for_static( Linkage::Import }; - let data_id = match module.declare_data( + match module.declare_data( symbol_name, linkage, definition_writable, @@ -356,9 +362,7 @@ fn data_id_for_static( "attempt to declare `{symbol_name}` as static, but it was already declared as function" )), Err(err) => Err::<_, _>(err).unwrap(), - }; - - data_id + } } fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) { @@ -368,6 +372,8 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant continue; } + let mut data = DataDescription::new(); + let (data_id, alloc, section_name) = match todo_item { TodoItem::Alloc(alloc_id) => { let alloc = match tcx.global_alloc(alloc_id) { @@ -386,7 +392,10 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant (data_id, alloc, None) } TodoItem::Static(def_id) => { - let section_name = tcx.codegen_fn_attrs(def_id).link_section; + let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id); + let section_name = codegen_fn_attrs.link_section; + + data.set_used(codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)); let alloc = tcx.eval_static_initializer(def_id).unwrap(); @@ -401,7 +410,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } }; - let mut data = DataDescription::new(); let alloc = alloc.inner(); data.set_align(alloc.align.bytes()); @@ -594,7 +602,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( { return None; } - StatementKind::Intrinsic(ref intrinsic) => match **intrinsic { + StatementKind::Intrinsic(intrinsic) => match **intrinsic { NonDivergingIntrinsic::CopyNonOverlapping(..) => return None, NonDivergingIntrinsic::Assume(..) => {} }, diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index 0f4696b9337e..8016c5a3005a 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -96,7 +96,7 @@ impl WriterRelocate { if jit_module.declarations().get_function_decl(func_id).name.as_deref() == Some("rust_eh_personality") { - extern "C" { + unsafe extern "C" { fn rust_eh_personality() -> !; } rust_eh_personality as *const u8 @@ -222,12 +222,12 @@ impl Writer for WriterRelocate { gimli::DW_EH_PE_absptr => { self.relocs.push(DebugReloc { offset: self.len() as u32, - size: size.into(), + size, name: DebugRelocName::Symbol(symbol), addend, kind: object::RelocationKind::Absolute, }); - self.write_udata(0, size.into()) + self.write_udata(0, size) } _ => Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)), }, diff --git a/src/debuginfo/gcc_except_table.rs b/src/debuginfo/gcc_except_table.rs new file mode 100644 index 000000000000..ff1c6aacd2f9 --- /dev/null +++ b/src/debuginfo/gcc_except_table.rs @@ -0,0 +1,271 @@ +use gimli::write::{Address, Writer}; +use gimli::{DW_EH_PE_omit, DW_EH_PE_uleb128, Encoding, LittleEndian}; + +pub(super) struct GccExceptTable { + pub call_sites: CallSiteTable, + pub actions: ActionTable, + pub type_info: TypeInfoTable, +} + +impl GccExceptTable { + pub(super) fn write( + &self, + w: &mut W, + encoding: Encoding, + ) -> gimli::write::Result<()> { + // lpStartEncoding + w.write_u8(DW_EH_PE_omit.0)?; + // lpStart (omitted) + let type_info_padding = if self.type_info.type_info.is_empty() { + // ttypeEncoding + w.write_u8(DW_EH_PE_omit.0)?; + None + } else { + // ttypeEncoding + w.write_u8(self.type_info.ttype_encoding.0)?; + + // classInfoOffset + let class_info_offset_field_offset = w.len() as u64; + + // Note: The offset in classInfoOffset is relative to position right after classInfoOffset + // itself. + let class_info_offset_no_padding = self.call_sites.encoded_size() + + self.actions.encoded_size() + + self.type_info.encoded_size(encoding); + + let type_info_is_aligned = |type_info_padding: u64| { + (class_info_offset_field_offset + + gimli::leb128::write::uleb128_size( + class_info_offset_no_padding + type_info_padding, + ) as u64 + + self.call_sites.encoded_size() + + self.actions.encoded_size() + + type_info_padding) + .is_multiple_of(4) + }; + + let mut type_info_padding = 0; + while !type_info_is_aligned(type_info_padding) { + type_info_padding += 1; + } + + w.write_uleb128(class_info_offset_no_padding + type_info_padding)?; + + Some(type_info_padding) + }; + + // call site table + self.call_sites.write(w)?; + + // action table + self.actions.write(w)?; + + // align to 4 bytes + if let Some(type_info_padding) = type_info_padding { + for _ in 0..type_info_padding { + w.write_u8(0)?; + } + // In this case we calculated the expected padding amount and used it to write the + // classInfoOffset field. Assert that the expected value matched the actual value to catch + // any inconsistency. + assert!(w.len().is_multiple_of(4), "type_info must be aligned to 4 bytes"); + } else { + while !w.len().is_multiple_of(4) { + w.write_u8(0)?; + } + } + + // type_info + self.type_info.write(w, encoding)?; + + // exception specs (unused for rust) + + // align to 4 bytes + while !w.len().is_multiple_of(4) { + w.write_u8(0)?; + } + + Ok(()) + } +} + +pub(super) struct CallSiteTable(pub Vec); + +impl CallSiteTable { + fn encoded_size(&self) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W) -> gimli::write::Result<()> { + let callsite_table_length = self.0.iter().map(|call_site| call_site.encoded_size()).sum(); + + // callsiteEncoding + w.write_u8(DW_EH_PE_uleb128.0)?; + // callsiteTableLength + w.write_uleb128(callsite_table_length)?; + + for call_site in &self.0 { + call_site.write(w)?; + } + + Ok(()) + } +} + +pub(super) struct CallSite { + pub start: u64, + pub length: u64, + pub landing_pad: u64, + pub action_entry: Option, +} + +impl CallSite { + fn encoded_size(&self) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W) -> gimli::write::Result<()> { + w.write_uleb128(self.start)?; + w.write_uleb128(self.length)?; + w.write_uleb128(self.landing_pad)?; + w.write_uleb128(match self.action_entry { + Some(action_offset) => action_offset.0 + 1, + None => 0, + })?; + Ok(()) + } +} + +pub(super) struct ActionTable { + actions: Vec, + encoded_length: u64, +} + +impl ActionTable { + pub(super) fn new() -> ActionTable { + ActionTable { actions: vec![], encoded_length: 0 } + } + + pub(super) fn add(&mut self, action: Action) -> ActionOffset { + let id = ActionOffset(self.encoded_length); + self.encoded_length += action.encoded_size(self.encoded_length); + self.actions.push(action); + id + } + + fn encoded_size(&self) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W) -> gimli::write::Result<()> { + let action_table_start = w.len() as u64; + for action in &self.actions { + action.write(w, w.len() as u64 - action_table_start)?; + } + + Ok(()) + } +} + +#[derive(Copy, Clone)] +pub(super) struct ActionOffset(u64); + +pub(super) struct Action { + pub(super) kind: ActionKind, + pub(super) next_action: Option, +} + +impl Action { + fn encoded_size(&self, action_table_offset: u64) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len, action_table_offset).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W, action_table_offset: u64) -> gimli::write::Result<()> { + // ttypeIndex + let ttype_index = match self.kind { + ActionKind::Catch(type_info_id) => type_info_id.0 as i64 + 1, + }; + w.write_sleb128(ttype_index)?; + // actionOffset + let action_offset_field_offset = + action_table_offset + gimli::leb128::write::sleb128_size(ttype_index) as u64; + w.write_sleb128(match self.next_action { + Some(next_action_offset) => { + next_action_offset.0 as i64 - action_offset_field_offset as i64 + } + None => 0, + })?; + Ok(()) + } +} + +#[derive(Copy, Clone)] +pub(super) enum ActionKind { + Catch(TypeInfoId), +} + +pub(super) struct TypeInfoTable { + ttype_encoding: gimli::DwEhPe, + type_info: Vec
, +} + +impl TypeInfoTable { + pub(super) fn new(ttype_encoding: gimli::DwEhPe) -> TypeInfoTable { + TypeInfoTable { ttype_encoding, type_info: vec![] } + } + + pub(super) fn add(&mut self, type_info: Address) -> TypeInfoId { + let id = TypeInfoId(self.type_info.len() as u64); + self.type_info.push(type_info); + id + } + + fn encoded_size(&self, encoding: Encoding) -> u64 { + let mut len = LenWriter(0); + self.write(&mut len, encoding).unwrap(); + len.0 as u64 + } + + fn write(&self, w: &mut W, encoding: Encoding) -> gimli::write::Result<()> { + for &type_info in self.type_info.iter().rev() { + w.write_eh_pointer(type_info, self.ttype_encoding, encoding.address_size)?; + } + + Ok(()) + } +} + +#[derive(Copy, Clone)] +pub(super) struct TypeInfoId(u64); + +struct LenWriter(usize); + +impl Writer for LenWriter { + type Endian = LittleEndian; + + fn endian(&self) -> LittleEndian { + LittleEndian + } + + fn len(&self) -> usize { + self.0 + } + + fn write(&mut self, bytes: &[u8]) -> gimli::write::Result<()> { + self.0 += bytes.len(); + Ok(()) + } + + fn write_at(&mut self, offset: usize, bytes: &[u8]) -> gimli::write::Result<()> { + assert!(offset + bytes.len() < self.0); + Ok(()) + } +} diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index fa7b39c836f6..6fe22f5c6dd9 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -6,9 +6,7 @@ use std::path::{Component, Path}; use cranelift_codegen::MachSrcLoc; use cranelift_codegen::binemit::CodeOffset; use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable}; -use rustc_span::{ - FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, hygiene, -}; +use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene}; use crate::debuginfo::FunctionDebugContext; use crate::debuginfo::emit::address_for_func; @@ -44,21 +42,27 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] { } } -const MD5_LEN: usize = 16; +fn make_file_info(source_file: &SourceFile, embed_source: bool) -> Option { + let has_md5 = source_file.src_hash.kind == SourceFileHashAlgorithm::Md5; + let has_source = embed_source && source_file.src.is_some(); -fn make_file_info(hash: SourceFileHash) -> Option { - if hash.kind == SourceFileHashAlgorithm::Md5 { - let mut buf = [0u8; MD5_LEN]; - buf.copy_from_slice(hash.hash_bytes()); - Some(FileInfo { - timestamp: 0, - size: 0, - md5: buf, - source: None, // FIXME implement -Zembed-source - }) - } else { - None + if !has_md5 && !has_source { + return None; } + + let mut info = FileInfo::default(); + + if has_md5 { + info.md5.copy_from_slice(source_file.src_hash.hash_bytes()); + } + + if embed_source { + if let Some(src) = &source_file.src { + info.source = Some(LineString::String(src.as_bytes().to_vec())); + } + } + + Some(info) } impl DebugContext { @@ -105,15 +109,19 @@ impl DebugContext { let file_name = LineString::new(file_name, line_program.encoding(), line_strings); - let info = make_file_info(source_file.src_hash); + let info = make_file_info(source_file, self.embed_source); - line_program.file_has_md5 &= info.is_some(); + let has_md5 = source_file.src_hash.kind == SourceFileHashAlgorithm::Md5; + line_program.file_has_md5 &= has_md5; line_program.add_file(file_name, dir_id, info) } filename => { - let dir_id = line_program.default_directory(); + // For anonymous sources, create an empty directory instead of using the default + let empty_dir = LineString::new(b"", line_program.encoding(), line_strings); + let dir_id = line_program.add_directory(empty_dir); + let dummy_file_name = LineString::new( - filename.display(self.filename_display_preference).to_string().into_bytes(), + filename.prefer_remapped_unconditionally().to_string().into_bytes(), line_program.encoding(), line_strings, ); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 4c438742f3d2..494002f525c8 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -1,6 +1,7 @@ //! Handling of everything related to debuginfo. mod emit; +mod gcc_except_table; mod line_info; mod object; mod types; @@ -19,12 +20,13 @@ use rustc_codegen_ssa::debuginfo::type_names; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; +use rustc_session::config::DebugInfo; use rustc_span::{FileNameDisplayPreference, SourceFileHash, StableSourceFileId}; use rustc_target::callconv::FnAbi; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; pub(crate) use self::types::TypeDebugContext; -pub(crate) use self::unwind::UnwindContext; +pub(crate) use self::unwind::{EXCEPTION_HANDLER_CATCH, EXCEPTION_HANDLER_CLEANUP, UnwindContext}; use crate::debuginfo::emit::{address_for_data, address_for_func}; use crate::prelude::*; @@ -43,6 +45,7 @@ pub(crate) struct DebugContext { array_size_type: UnitEntryId, filename_display_preference: FileNameDisplayPreference, + embed_source: bool, } pub(crate) struct FunctionDebugContext { @@ -52,22 +55,37 @@ pub(crate) struct FunctionDebugContext { } impl DebugContext { - pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, cgu_name: &str) -> Self { + pub(crate) fn new( + tcx: TyCtxt<'_>, + isa: &dyn TargetIsa, + force_disable_debuginfo: bool, + cgu_name: &str, + ) -> Option { + if tcx.sess.opts.debuginfo == DebugInfo::None + || force_disable_debuginfo + || tcx.sess.target.options.is_like_windows + { + return None; + } + + let mut requested_dwarf_version = tcx.sess.dwarf_version(); + if tcx.sess.target.is_like_darwin && requested_dwarf_version > 4 { + // Apple’s shipped debuggers still expect DWARF <= 4 by default. + // Stay on v4 unless the user explicitly opts into a feature that + // only works with v5 (e.g. -Zembed-source). + if !tcx.sess.opts.unstable_opts.embed_source { + requested_dwarf_version = 4; + } + } + let encoding = Encoding { format: Format::Dwarf32, - // FIXME this should be configurable - // macOS doesn't seem to support DWARF > 3 - // 5 version is required for md5 file hash - version: if tcx.sess.target.is_like_darwin { - 3 - } else { - // FIXME change to version 5 once the gdb and lldb shipping with the latest debian - // support it. - 4 - }, + version: requested_dwarf_version as u16, address_size: isa.frontend_config().pointer_bytes(), }; + let embed_source = tcx.sess.opts.unstable_opts.embed_source && encoding.version >= 5; + let endian = match isa.endianness() { Endianness::Little => RunTimeEndian::Little, Endianness::Big => RunTimeEndian::Big, @@ -106,10 +124,14 @@ impl DebugContext { encoding, LineEncoding::default(), LineString::new(comp_dir.as_bytes(), encoding, &mut dwarf.line_strings), + None, LineString::new(name.as_bytes(), encoding, &mut dwarf.line_strings), file_info, ); line_program.file_has_md5 = file_has_md5; + if embed_source { + line_program.file_has_source = true; + } dwarf.unit.line_program = line_program; @@ -145,7 +167,7 @@ impl DebugContext { AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), ); - DebugContext { + Some(DebugContext { endian, dwarf, unit_range_list: RangeList(Vec::new()), @@ -154,7 +176,8 @@ impl DebugContext { namespace_map: DefIdMap::default(), array_size_type, filename_display_preference, - } + embed_source, + }) } fn item_namespace(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> UnitEntryId { diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs index 0d49f32373ca..a292429cdfad 100644 --- a/src/debuginfo/types.rs +++ b/src/debuginfo/types.rs @@ -56,7 +56,7 @@ impl DebugContext { // ty::FnDef(..) | ty::FnPtr(..) // ty::Closure(..) // ty::Adt(def, ..) - ty::Tuple(components) => self.tuple_type(tcx, type_dbg, ty, *components), + ty::Tuple(components) => self.tuple_type(tcx, type_dbg, ty, components), // ty::Param(_) // FIXME implement remaining types and add unreachable!() to the fallback branch _ => self.placeholder_for_type(tcx, type_dbg, ty), @@ -152,7 +152,7 @@ impl DebugContext { components: &'tcx [Ty<'tcx>], ) -> UnitEntryId { let components = components - .into_iter() + .iter() .map(|&ty| (ty, self.debug_type(tcx, type_dbg, ty))) .collect::>(); diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index 74b82a7139ab..ecaf88a26259 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -1,15 +1,23 @@ //! Unwind info generation (`.eh_frame`) +use cranelift_codegen::FinalizedMachExceptionHandler; use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::unwind::UnwindInfo; +use cranelift_module::DataId; use cranelift_object::ObjectProduct; -use gimli::RunTimeEndian; -use gimli::write::{CieId, EhFrame, FrameTable, Section}; +use gimli::write::{Address, CieId, EhFrame, FrameTable, Section}; +use gimli::{Encoding, Format, RunTimeEndian}; -use super::emit::address_for_func; +use super::emit::{DebugRelocName, address_for_data, address_for_func}; +use super::gcc_except_table::{ + Action, ActionKind, ActionTable, CallSite, CallSiteTable, GccExceptTable, TypeInfoTable, +}; use super::object::WriteDebugInfo; use crate::prelude::*; +pub(crate) const EXCEPTION_HANDLER_CLEANUP: u32 = 0; +pub(crate) const EXCEPTION_HANDLER_CATCH: u32 = 1; + pub(crate) struct UnwindContext { endian: RunTimeEndian, frame_table: FrameTable, @@ -25,10 +33,79 @@ impl UnwindContext { let mut frame_table = FrameTable::default(); let cie_id = if let Some(mut cie) = module.isa().create_systemv_cie() { - if pic_eh_frame { - cie.fde_address_encoding = - gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0); + let ptr_encoding = if pic_eh_frame { + gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0) + } else { + gimli::DW_EH_PE_absptr + }; + + cie.fde_address_encoding = ptr_encoding; + + // FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204 + if cfg!(feature = "unwinding") { + let code_ptr_encoding = if pic_eh_frame { + if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 { + gimli::DwEhPe( + gimli::DW_EH_PE_indirect.0 + | gimli::DW_EH_PE_pcrel.0 + | gimli::DW_EH_PE_sdata4.0, + ) + } else if let target_lexicon::Architecture::Aarch64(_) = + module.isa().triple().architecture + { + gimli::DwEhPe( + gimli::DW_EH_PE_indirect.0 + | gimli::DW_EH_PE_pcrel.0 + | gimli::DW_EH_PE_sdata8.0, + ) + } else { + todo!() + } + } else { + gimli::DwEhPe(gimli::DW_EH_PE_indirect.0 | gimli::DW_EH_PE_absptr.0) + }; + + cie.lsda_encoding = Some(ptr_encoding); + + // FIXME use eh_personality lang item instead + let personality = module + .declare_function( + "rust_eh_personality", + Linkage::Import, + &Signature { + params: vec![ + AbiParam::new(types::I32), + AbiParam::new(types::I32), + AbiParam::new(types::I64), + AbiParam::new(module.target_config().pointer_type()), + AbiParam::new(module.target_config().pointer_type()), + ], + returns: vec![AbiParam::new(types::I32)], + call_conv: module.target_config().default_call_conv, + }, + ) + .unwrap(); + + // Use indirection here to support PIC the case where rust_eh_personality is defined in + // another DSO. + let personality_ref = module + .declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false) + .unwrap(); + + let mut personality_ref_data = DataDescription::new(); + // Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss + // section. + let pointer_bytes = usize::from(module.target_config().pointer_bytes()); + personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice()); + let personality_func_ref = + module.declare_func_in_data(personality, &mut personality_ref_data); + personality_ref_data.write_function_addr(0, personality_func_ref); + + module.define_data(personality_ref, &personality_ref_data).unwrap(); + + cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref))); } + Some(frame_table.add_cie(cie)) } else { None @@ -63,8 +140,100 @@ impl UnwindContext { match unwind_info { UnwindInfo::SystemV(unwind_info) => { - self.frame_table - .add_fde(self.cie_id.unwrap(), unwind_info.to_fde(address_for_func(func_id))); + let mut fde = unwind_info.to_fde(address_for_func(func_id)); + + // FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204 + if cfg!(feature = "unwinding") { + // FIXME use unique symbol name derived from function name + let lsda = module.declare_anonymous_data(false, false).unwrap(); + + let encoding = Encoding { + format: Format::Dwarf32, + version: 1, + address_size: module.isa().frontend_config().pointer_bytes(), + }; + + let mut gcc_except_table_data = GccExceptTable { + call_sites: CallSiteTable(vec![]), + actions: ActionTable::new(), + type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4), + }; + + let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0)); + let catch_action = gcc_except_table_data + .actions + .add(Action { kind: ActionKind::Catch(catch_type), next_action: None }); + + for call_site in context.compiled_code().unwrap().buffer.call_sites() { + if call_site.exception_handlers.is_empty() { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: 0, + action_entry: None, + }); + } + for &handler in call_site.exception_handlers { + match handler { + FinalizedMachExceptionHandler::Tag(tag, landingpad) => { + match tag.as_u32() { + EXCEPTION_HANDLER_CLEANUP => { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: u64::from(landingpad), + action_entry: None, + }) + } + EXCEPTION_HANDLER_CATCH => { + gcc_except_table_data.call_sites.0.push(CallSite { + start: u64::from(call_site.ret_addr - 1), + length: 1, + landing_pad: u64::from(landingpad), + action_entry: Some(catch_action), + }) + } + _ => unreachable!(), + } + } + _ => unreachable!(), + } + } + } + + let mut gcc_except_table = super::emit::WriterRelocate::new(self.endian); + + gcc_except_table_data.write(&mut gcc_except_table, encoding).unwrap(); + + let mut data = DataDescription::new(); + data.define(gcc_except_table.writer.into_vec().into_boxed_slice()); + data.set_segment_section("", ".gcc_except_table"); + + for reloc in &gcc_except_table.relocs { + match reloc.name { + DebugRelocName::Section(_id) => unreachable!(), + DebugRelocName::Symbol(id) => { + let id = id.try_into().unwrap(); + if id & 1 << 31 == 0 { + let func_ref = module + .declare_func_in_data(FuncId::from_u32(id), &mut data); + data.write_function_addr(reloc.offset, func_ref); + } else { + let gv = module.declare_data_in_data( + DataId::from_u32(id & !(1 << 31)), + &mut data, + ); + data.write_data_addr(reloc.offset, gv, 0); + } + } + }; + } + + module.define_data(lsda, &data).unwrap(); + fde.lsda = Some(address_for_data(lsda)); + } + + self.frame_table.add_fde(self.cie_id.unwrap(), fde); } UnwindInfo::WindowsX64(_) | UnwindInfo::WindowsArm64(_) => { // Windows does not have debug info for its unwind info. @@ -116,7 +285,7 @@ impl UnwindContext { // Everything after this line up to the end of the file is loosely based on // https://github.com/bytecodealliance/wasmtime/blob/4471a82b0c540ff48960eca6757ccce5b1b5c3e4/crates/jit/src/unwind/systemv.rs #[cfg(target_os = "macos")] - { + unsafe { // On macOS, `__register_frame` takes a pointer to a single FDE let start = eh_frame.as_ptr(); let end = start.add(eh_frame.len()); @@ -138,12 +307,12 @@ impl UnwindContext { #[cfg(not(target_os = "macos"))] { // On other platforms, `__register_frame` will walk the FDEs until an entry of length 0 - __register_frame(eh_frame.as_ptr()); + unsafe { __register_frame(eh_frame.as_ptr()) }; } } } -extern "C" { +unsafe extern "C" { // libunwind import fn __register_frame(fde: *const u8); } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 7bf1efc10653..760e23f2171b 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -24,9 +24,8 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{CodegenUnit, MonoItem, MonoItemData, Visibility}; use rustc_session::Session; -use rustc_session::config::{DebugInfo, OutFileName, OutputFilenames, OutputType}; +use rustc_session::config::{OutFileName, OutputFilenames, OutputType}; -use crate::CodegenCx; use crate::base::CodegenedFunction; use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken}; use crate::debuginfo::TypeDebugContext; @@ -98,8 +97,8 @@ impl OngoingCodegen { sess, &module_regular.name, &[ - ("o", &module_regular.object.as_ref().unwrap()), - ("asm.o", &module_global_asm.object.as_ref().unwrap()), + ("o", module_regular.object.as_ref().unwrap()), + ("asm.o", module_global_asm.object.as_ref().unwrap()), ], &[], ) @@ -107,7 +106,7 @@ impl OngoingCodegen { rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( sess, &module_regular.name, - &[("o", &module_regular.object.as_ref().unwrap())], + &[("o", module_regular.object.as_ref().unwrap())], &[], ) }; @@ -309,7 +308,7 @@ fn produce_final_output_artifacts( module.for_each_output(|path, ty| { if sess.opts.output_types.contains_key(&ty) { let descr = ty.shorthand(); - sess.dcx().emit_artifact_notification(&path, descr); + sess.dcx().emit_artifact_notification(path, descr); } }); } @@ -451,8 +450,8 @@ fn reuse_workproduct_for_cgu( tcx.sess.invocation_temp.as_deref(), ); let source_file_regular = rustc_incremental::in_incr_comp_dir_sess( - &tcx.sess, - &work_product.saved_files.get("o").expect("no saved object file in work product"), + tcx.sess, + work_product.saved_files.get("o").expect("no saved object file in work product"), ); if let Err(err) = rustc_fs_util::link_or_copy(&source_file_regular, &obj_out_regular) { @@ -467,7 +466,7 @@ fn reuse_workproduct_for_cgu( let obj_out_global_asm = crate::global_asm::add_file_stem_postfix(obj_out_regular.clone(), ".asm"); let source_file_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") { - let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, asm_o); + let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(tcx.sess, asm_o); if let Err(err) = rustc_fs_util::link_or_copy(&source_file_global_asm, &obj_out_global_asm) { return Err(format!( @@ -511,18 +510,14 @@ fn codegen_cgu_content( tcx: TyCtxt<'_>, module: &mut dyn Module, cgu_name: rustc_span::Symbol, -) -> (CodegenCx, Vec) { +) -> (Option, Vec, String) { let _timer = tcx.prof.generic_activity_with_arg("codegen cgu", cgu_name.as_str()); let cgu = tcx.codegen_unit(cgu_name); let mono_items = cgu.items_in_deterministic_order(tcx); - let mut cx = crate::CodegenCx::new( - tcx, - module.isa(), - tcx.sess.opts.debuginfo != DebugInfo::None, - cgu_name, - ); + let mut debug_context = DebugContext::new(tcx, module.isa(), false, cgu_name.as_str()); + let mut global_asm = String::new(); let mut type_dbg = TypeDebugContext::default(); super::predefine_mono_items(tcx, module, &mono_items); let mut codegened_functions = vec![]; @@ -532,7 +527,7 @@ fn codegen_cgu_content( let flags = tcx.codegen_instance_attrs(instance.def).flags; if flags.contains(CodegenFnAttrFlags::NAKED) { rustc_codegen_ssa::mir::naked_asm::codegen_naked_asm( - &mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm }, + &mut GlobalAsmContext { tcx, global_asm: &mut global_asm }, instance, MonoItemData { linkage: RLinkage::External, @@ -548,7 +543,8 @@ fn codegen_cgu_content( } let codegened_function = crate::base::codegen_fn( tcx, - &mut cx, + cgu_name, + debug_context.as_mut(), &mut type_dbg, Function::new(), module, @@ -558,13 +554,13 @@ fn codegen_cgu_content( } MonoItem::Static(def_id) => { let data_id = crate::constant::codegen_static(tcx, module, def_id); - if let Some(debug_context) = &mut cx.debug_context { + if let Some(debug_context) = debug_context.as_mut() { debug_context.define_static(tcx, &mut type_dbg, def_id, data_id); } } MonoItem::GlobalAsm(item_id) => { rustc_codegen_ssa::base::codegen_global_asm( - &mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm }, + &mut GlobalAsmContext { tcx, global_asm: &mut global_asm }, item_id, ); } @@ -572,7 +568,7 @@ fn codegen_cgu_content( } crate::main_shim::maybe_create_entry_wrapper(tcx, module, false, cgu.is_primary()); - (cx, codegened_functions) + (debug_context, codegened_functions, global_asm) } fn module_codegen( @@ -585,13 +581,17 @@ fn module_codegen( ) -> OngoingModuleCodegen { let mut module = make_module(tcx.sess, cgu_name.as_str().to_string()); - let (mut cx, codegened_functions) = codegen_cgu_content(tcx, &mut module, cgu_name); + let (mut debug_context, codegened_functions, mut global_asm) = + codegen_cgu_content(tcx, &mut module, cgu_name); let cgu_name = cgu_name.as_str().to_owned(); let producer = crate::debuginfo::producer(tcx.sess); let profiler = tcx.prof.clone(); + let invocation_temp = tcx.sess.invocation_temp.clone(); + let output_filenames = tcx.output_filenames(()).clone(); + let should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess); OngoingModuleCodegen::Async(std::thread::spawn(move || { profiler.clone().generic_activity_with_arg("compile functions", &*cgu_name).run(|| { @@ -602,10 +602,13 @@ fn module_codegen( let mut cached_context = Context::new(); for codegened_func in codegened_functions { crate::base::compile_fn( - &mut cx, &profiler, + &output_filenames, + should_write_ir, &mut cached_context, &mut module, + debug_context.as_mut(), + &mut global_asm, codegened_func, ); } @@ -616,8 +619,8 @@ fn module_codegen( crate::global_asm::compile_global_asm( &global_asm_config, &cgu_name, - &cx.global_asm, - cx.invocation_temp.as_deref(), + global_asm, + invocation_temp.as_deref(), ) })?; @@ -625,11 +628,11 @@ fn module_codegen( profiler.generic_activity_with_arg("write object file", &*cgu_name).run(|| { emit_cgu( &global_asm_config.output_filenames, - cx.invocation_temp.as_deref(), + invocation_temp.as_deref(), &profiler, cgu_name, module, - cx.debug_context, + debug_context, global_asm_object_file, &producer, ) @@ -681,7 +684,7 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { // Calculate the CGU reuse let cgu_reuse = tcx.sess.time("find_cgu_reuse", || { - cgus.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::>() + cgus.iter().map(|cgu| determine_cgu_reuse(tcx, cgu)).collect::>() }); rustc_codegen_ssa::assert_module_sources::assert_module_sources(tcx, &|cgu_reuse_tracker| { @@ -695,7 +698,7 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { let disable_incr_cache = disable_incr_cache(); let (todo_cgus, done_cgus) = - cgus.into_iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] { + cgus.iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] { _ if disable_incr_cache => true, CguReuse::No => true, CguReuse::PreLto | CguReuse::PostLto => false, diff --git a/src/driver/jit.rs b/src/driver/jit.rs index fec46bf26975..9dba46363936 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -9,14 +9,14 @@ use rustc_codegen_ssa::CrateInfo; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::MonoItem; use rustc_session::Session; +use rustc_session::config::OutputFilenames; use rustc_span::sym; -use crate::CodegenCx; use crate::debuginfo::TypeDebugContext; use crate::prelude::*; use crate::unwind_module::UnwindModule; -fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, CodegenCx) { +fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, Option) { let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string()); let isa = crate::build_isa(tcx.sess, true); @@ -25,7 +25,7 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, CodegenCx) { jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info)); let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false); - let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, sym::dummy_cgu_name); + let cx = DebugContext::new(tcx, jit_module.isa(), false, "dummy_cgu_name"); crate::allocator::codegen(tcx, &mut jit_module); @@ -33,13 +33,13 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, CodegenCx) { } pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { - // FIXME error on check mode or crate types other than bin in CodegenBackend::init() - if !tcx.crate_types().contains(&rustc_session::config::CrateType::Executable) { tcx.dcx().fatal("can't jit non-executable crate"); } - let (mut jit_module, mut cx) = create_jit_module(tcx); + let output_filenames = tcx.output_filenames(()); + let should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess); + let (mut jit_module, mut debug_context) = create_jit_module(tcx); let mut cached_context = Context::new(); let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; @@ -58,7 +58,9 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { MonoItem::Fn(inst) => { codegen_and_compile_fn( tcx, - &mut cx, + &output_filenames, + should_write_ir, + debug_context.as_mut(), &mut cached_context, &mut jit_module, inst, @@ -75,10 +77,6 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { } }); - if !cx.global_asm.is_empty() { - tcx.dcx().fatal("Inline asm is not supported in JIT mode"); - } - crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, true, true); tcx.dcx().abort_if_errors(); @@ -120,7 +118,9 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! { fn codegen_and_compile_fn<'tcx>( tcx: TyCtxt<'tcx>, - cx: &mut crate::CodegenCx, + output_filenames: &OutputFilenames, + should_write_ir: bool, + mut debug_context: Option<&mut DebugContext>, cached_context: &mut Context, module: &mut dyn Module, instance: Instance<'tcx>, @@ -141,13 +141,28 @@ fn codegen_and_compile_fn<'tcx>( let cached_func = std::mem::replace(&mut cached_context.func, Function::new()); let codegened_func = crate::base::codegen_fn( tcx, - cx, + sym::dummy_cgu_name, + debug_context.as_deref_mut(), &mut TypeDebugContext::default(), cached_func, module, instance, ); - crate::base::compile_fn(cx, &tcx.prof, cached_context, module, codegened_func); + + let mut global_asm = String::new(); + crate::base::compile_fn( + &tcx.prof, + output_filenames, + should_write_ir, + cached_context, + module, + debug_context.as_deref_mut(), + &mut global_asm, + codegened_func, + ); + if !global_asm.is_empty() { + tcx.dcx().fatal("Inline asm is not supported in JIT mode"); + } }); } diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 8f83c30b598d..9f2b7b4b09f2 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -38,16 +38,12 @@ fn predefine_mono_items<'tcx>( .codegen_instance_attrs(instance.def) .flags .contains(CodegenFnAttrFlags::NAKED); - module - .declare_function( - name, - // Naked functions are defined in a separate object - // file from the codegen unit rustc expects them to - // be defined in. - if is_naked { Linkage::Import } else { linkage }, - &sig, - ) - .unwrap(); + if is_naked { + // Naked functions are defined in a separate object + // file, so they can be declared on the fly. + continue; + } + module.declare_function(name, linkage, &sig).unwrap(); } MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {} } diff --git a/src/global_asm.rs b/src/global_asm.rs index 1306c6aa5179..8d8cdb14dbc6 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -171,7 +171,7 @@ impl GlobalAsmConfig { pub(crate) fn compile_global_asm( config: &GlobalAsmConfig, cgu_name: &str, - global_asm: &str, + global_asm: String, invocation_temp: Option<&str>, ) -> Result, String> { if global_asm.is_empty() { @@ -205,6 +205,9 @@ pub(crate) fn compile_global_asm( return Err(format!("Failed to assemble `{}`", global_asm)); } } else { + // Escape { and } + let global_asm = global_asm.replace('{', "{{").replace('}', "}}"); + let mut child = Command::new(std::env::current_exe().unwrap()) // Avoid a warning about the jobserver fd not being passed .env_remove("CARGO_MAKEFLAGS") diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 120d6ff9e38e..08cabe9d695c 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -7,6 +7,7 @@ use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::LangItem; use rustc_span::sym; use rustc_target::asm::*; +use rustc_target::spec::Arch; use target_lexicon::BinaryFormat; use crate::prelude::*; @@ -51,6 +52,26 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( return; } + if fx.tcx.sess.target.arch == Arch::S390x + && template.len() == 3 + && template[0] == InlineAsmTemplatePiece::String("stfle 0(".into()) + && let InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: None, span: _ } = + template[1] + && template[2] == InlineAsmTemplatePiece::String(")".into()) + { + // FIXME no inline asm support for s390x yet, but stdarch needs it for feature detection + match destination { + Some(destination) => { + let destination_block = fx.get_block(destination); + fx.bcx.ins().jump(destination_block, &[]); + } + None => { + fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); + } + } + return; + } + let operands = operands .iter() .map(|operand| match *operand { @@ -103,11 +124,12 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( // be exported from the main codegen unit and may thus be unreachable from the // object file created by an external assembler. let wrapper_name = format!( - "__inline_asm_{}_wrapper_n{}", - fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), - fx.cx.inline_asm_index + "{}__inline_asm_{}_wrapper_n{}", + fx.symbol_name, + fx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + fx.inline_asm_index, ); - fx.cx.inline_asm_index += 1; + fx.inline_asm_index += 1; let sig = get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance); create_wrapper_function(fx.module, sig, &wrapper_name, symbol.name); @@ -166,14 +188,15 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( asm_gen.allocate_stack_slots(); let asm_name = format!( - "__inline_asm_{}_n{}", - fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), - fx.cx.inline_asm_index + "{}__inline_asm_{}_n{}", + fx.symbol_name, + fx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + fx.inline_asm_index, ); - fx.cx.inline_asm_index += 1; + fx.inline_asm_index += 1; let generated_asm = asm_gen.generate_asm_wrapper(&asm_name); - fx.cx.global_asm.push_str(&generated_asm); + fx.inline_asm.push_str(&generated_asm); let mut inputs = Vec::new(); let mut outputs = Vec::new(); @@ -546,20 +569,6 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { .emit(&mut generated_asm, InlineAsmArch::X86_64, *modifier) .unwrap(), }, - InlineAsmArch::AArch64 => match reg { - InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => { - // rustc emits v0 rather than q0 - reg.emit( - &mut generated_asm, - InlineAsmArch::AArch64, - Some(modifier.unwrap_or('q')), - ) - .unwrap() - } - _ => reg - .emit(&mut generated_asm, InlineAsmArch::AArch64, *modifier) - .unwrap(), - }, _ => reg.emit(&mut generated_asm, self.arch, *modifier).unwrap(), } } @@ -827,6 +836,7 @@ fn call_inline_asm<'tcx>( } let stack_slot_addr = stack_slot.get_addr(fx); + // FIXME use try_call once unwinding inline assembly is supported fx.bcx.ins().call(inline_asm_func, &[stack_slot_addr]); for (offset, place) in outputs { diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index ed40901ac9b8..a78c6e0a4e7a 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -3,7 +3,7 @@ macro_rules! intrinsic_args { ($fx:expr, $args:expr => ($($arg:tt),*); $intrinsic:expr) => { - #[allow(unused_parens)] + #[allow(unused_parens, clippy::unused_unit)] let ($($arg),*) = if let [$($arg),*] = $args { ($(codegen_operand($fx, &($arg).node)),*) } else { @@ -17,17 +17,21 @@ mod llvm_aarch64; mod llvm_x86; mod simd; -use cranelift_codegen::ir::AtomicRmwOp; +use cranelift_codegen::ir::{ + AtomicRmwOp, BlockArg, ExceptionTableData, ExceptionTableItem, ExceptionTag, +}; use rustc_middle::ty; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_span::source_map::Spanned; use rustc_span::{Symbol, sym}; +use rustc_target::spec::PanicStrategy; pub(crate) use self::llvm::codegen_llvm_intrinsic_call; use crate::cast::clif_intcast; use crate::codegen_f16_f128; +use crate::debuginfo::EXCEPTION_HANDLER_CATCH; use crate::prelude::*; fn bug_on_incorrect_arg_count(intrinsic: impl std::fmt::Display) -> ! { @@ -479,7 +483,7 @@ fn codegen_float_intrinsic_call<'tcx>( }; let input_tys: Vec<_> = vec![AbiParam::new(clif_ty), lib_call_arg_param(fx.tcx, types::I32, true)]; - let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0]; + let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], args)[0]; let ret_val = if intrinsic == sym::powif16 { codegen_f16_f128::f32_to_f16(fx, ret_val) } else { @@ -501,7 +505,7 @@ fn codegen_float_intrinsic_call<'tcx>( } _ => { let input_tys: Vec<_> = args.iter().map(|_| AbiParam::new(clif_ty)).collect(); - let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0]; + let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], args)[0]; CValue::by_val(ret_val, fx.layout_of(ty)) } }; @@ -1337,23 +1341,75 @@ fn codegen_regular_intrinsic_call<'tcx>( } sym::catch_unwind => { + let ret_block = fx.get_block(destination.unwrap()); + intrinsic_args!(fx, args => (f, data, catch_fn); intrinsic); let f = f.load_scalar(fx); let data = data.load_scalar(fx); - let _catch_fn = catch_fn.load_scalar(fx); + let catch_fn = catch_fn.load_scalar(fx); - // FIXME once unwinding is supported, change this to actually catch panics let f_sig = fx.bcx.func.import_signature(Signature { call_conv: fx.target_config.default_call_conv, params: vec![AbiParam::new(pointer_ty(fx.tcx))], returns: vec![], }); - fx.bcx.ins().call_indirect(f_sig, f, &[data]); + if cfg!(not(feature = "unwinding")) + || fx.tcx.sess.panic_strategy() == PanicStrategy::Abort + { + fx.bcx.ins().call_indirect(f_sig, f, &[data]); - let layout = fx.layout_of(fx.tcx.types.i32); - let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout); - ret.write_cvalue(fx, ret_val); + let layout = fx.layout_of(fx.tcx.types.i32); + let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout); + ret.write_cvalue(fx, ret_val); + + fx.bcx.ins().jump(ret_block, &[]); + } else { + let catch_fn_sig = fx.bcx.func.import_signature(Signature { + call_conv: fx.target_config.default_call_conv, + params: vec![ + AbiParam::new(pointer_ty(fx.tcx)), + AbiParam::new(pointer_ty(fx.tcx)), + ], + returns: vec![], + }); + + let fallthrough_block = fx.bcx.create_block(); + let fallthrough_block_call = fx.bcx.func.dfg.block_call(fallthrough_block, &[]); + let catch_block = fx.bcx.create_block(); + let catch_block_call = + fx.bcx.func.dfg.block_call(catch_block, &[BlockArg::TryCallExn(0)]); + let exception_table = + fx.bcx.func.dfg.exception_tables.push(ExceptionTableData::new( + f_sig, + fallthrough_block_call, + [ExceptionTableItem::Tag( + ExceptionTag::with_number(EXCEPTION_HANDLER_CATCH).unwrap(), + catch_block_call, + )], + )); + + fx.bcx.ins().try_call_indirect(f, &[data], exception_table); + + fx.bcx.seal_block(fallthrough_block); + fx.bcx.switch_to_block(fallthrough_block); + let layout = fx.layout_of(fx.tcx.types.i32); + let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout); + ret.write_cvalue(fx, ret_val); + fx.bcx.ins().jump(ret_block, &[]); + + fx.bcx.seal_block(catch_block); + fx.bcx.switch_to_block(catch_block); + fx.bcx.set_cold_block(catch_block); + let exception = fx.bcx.append_block_param(catch_block, pointer_ty(fx.tcx)); + fx.bcx.ins().call_indirect(catch_fn_sig, catch_fn, &[data, exception]); + let layout = fx.layout_of(fx.tcx.types.i32); + let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 1), layout); + ret.write_cvalue(fx, ret_val); + fx.bcx.ins().jump(ret_block, &[]); + } + + return Ok(()); } sym::fadd_fast diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index ca41381f0abc..0bce31beb8b8 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -813,7 +813,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( Endian::Big => lane_count - 1 - lane, Endian::Little => lane, }; - let m_lane = fx.bcx.ins().ushr_imm(m, u64::from(mask_lane) as i64); + let m_lane = fx.bcx.ins().ushr_imm(m, mask_lane.cast_signed()); let m_lane = fx.bcx.ins().band_imm(m_lane, 1); let a_lane = a.value_lane(fx, lane).load_scalar(fx); let b_lane = b.value_lane(fx, lane).load_scalar(fx); @@ -1059,6 +1059,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let ret_lane_layout = fx.layout_of(ret_lane_ty); let ptr_val = ptr.load_scalar(fx); + let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(); + + let memflags = match alignment { + SimdAlign::Unaligned => MemFlags::new().with_notrap(), + _ => MemFlags::trusted(), + }; + for lane_idx in 0..ret_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let mask_lane = mask.value_lane(fx, lane_idx).load_scalar(fx); @@ -1074,12 +1083,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.switch_to_block(if_enabled); let offset = lane_idx as i32 * lane_clif_ty.bytes() as i32; - let res = fx.bcx.ins().load( - lane_clif_ty, - MemFlags::trusted(), - ptr_val, - Offset32::new(offset), - ); + let res = fx.bcx.ins().load(lane_clif_ty, memflags, ptr_val, Offset32::new(offset)); fx.bcx.ins().jump(next, &[res.into()]); fx.bcx.switch_to_block(if_disabled); diff --git a/src/lib.rs b/src/lib.rs index b63773053d3f..4745243a6eab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,7 @@ extern crate rustc_middle; extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_codegen_ssa; +extern crate rustc_const_eval; extern crate rustc_data_structures; extern crate rustc_errors; extern crate rustc_fs_util; @@ -35,6 +36,7 @@ extern crate rustc_target; extern crate rustc_driver; use std::any::Any; +use std::cell::OnceCell; use std::env; use std::sync::Arc; @@ -120,41 +122,8 @@ impl String> Drop for PrintOnPanic { } } -/// The codegen context holds any information shared between the codegen of individual functions -/// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module). -struct CodegenCx { - output_filenames: Arc, - invocation_temp: Option, - should_write_ir: bool, - global_asm: String, - inline_asm_index: usize, - debug_context: Option, - cgu_name: Symbol, -} - -impl CodegenCx { - fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, debug_info: bool, cgu_name: Symbol) -> Self { - assert_eq!(pointer_ty(tcx), isa.pointer_type()); - - let debug_context = if debug_info && !tcx.sess.target.options.is_like_windows { - Some(DebugContext::new(tcx, isa, cgu_name.as_str())) - } else { - None - }; - CodegenCx { - output_filenames: tcx.output_filenames(()).clone(), - invocation_temp: tcx.sess.invocation_temp.clone(), - should_write_ir: crate::pretty_clif::should_write_ir(tcx), - global_asm: String::new(), - inline_asm_index: 0, - debug_context, - cgu_name, - } - } -} - pub struct CraneliftCodegenBackend { - pub config: Option, + pub config: OnceCell, } impl CodegenBackend for CraneliftCodegenBackend { @@ -180,6 +149,15 @@ impl CodegenBackend for CraneliftCodegenBackend { sess.dcx() .fatal("`-Cinstrument-coverage` is LLVM specific and not supported by Cranelift"); } + + let config = self.config.get_or_init(|| { + BackendConfig::from_opts(&sess.opts.cg.llvm_args) + .unwrap_or_else(|err| sess.dcx().fatal(err)) + }); + + if config.jit_mode && !sess.opts.output_types.should_codegen() { + sess.dcx().fatal("JIT mode doesn't work with `cargo check`"); + } } fn target_config(&self, sess: &Session) -> TargetConfig { @@ -202,36 +180,23 @@ impl CodegenBackend for CraneliftCodegenBackend { // FIXME do `unstable_target_features` properly let unstable_target_features = target_features.clone(); - // FIXME(f16_f128): LLVM 20 (currently used by `rustc`) passes `f128` in XMM registers on - // Windows, whereas LLVM 21+ and Cranelift pass it indirectly. This means that `f128` won't - // work when linking against a LLVM-built sysroot. - let has_reliable_f128 = !sess.target.is_like_windows; - let has_reliable_f16 = match sess.target.arch { - // FIXME(f16_f128): LLVM 20 does not support `f16` on s390x, meaning the required - // builtins are not available in `compiler-builtins`. - Arch::S390x => false, - // FIXME(f16_f128): `rustc_codegen_llvm` currently disables support on Windows GNU - // targets due to GCC using a different ABI than LLVM. Therefore `f16` won't be - // available when using a LLVM-built sysroot. - Arch::X86_64 - if sess.target.os == "windows" - && sess.target.env == "gnu" - && sess.target.abi != "llvm" => - { - false - } - _ => true, - }; + // FIXME(f16_f128): `rustc_codegen_llvm` currently disables support on Windows GNU + // targets due to GCC using a different ABI than LLVM. Therefore `f16` and `f128` + // won't be available when using a LLVM-built sysroot. + let has_reliable_f16_f128 = !(sess.target.arch == Arch::X86_64 + && sess.target.os == "windows" + && sess.target.env == "gnu" + && sess.target.abi != "llvm"); TargetConfig { target_features, unstable_target_features, // `rustc_codegen_cranelift` polyfills functionality not yet // available in Cranelift. - has_reliable_f16, - has_reliable_f16_math: has_reliable_f16, - has_reliable_f128, - has_reliable_f128_math: has_reliable_f128, + has_reliable_f16: has_reliable_f16_f128, + has_reliable_f16_math: has_reliable_f16_f128, + has_reliable_f128: has_reliable_f16_f128, + has_reliable_f128_math: has_reliable_f16_f128, } } @@ -241,13 +206,10 @@ impl CodegenBackend for CraneliftCodegenBackend { fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE)); - let config = self.config.clone().unwrap_or_else(|| { - BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args) - .unwrap_or_else(|err| tcx.sess.dcx().fatal(err)) - }); + let config = self.config.get().unwrap(); if config.jit_mode { #[cfg(feature = "jit")] - driver::jit::run_jit(tcx, config.jit_args); + driver::jit::run_jit(tcx, config.jit_args.clone()); #[cfg(not(feature = "jit"))] tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift"); @@ -294,8 +256,8 @@ fn build_isa(sess: &Session, jit: bool) -> Arc { flags_builder.set("enable_verifier", enable_verifier).unwrap(); flags_builder.set("regalloc_checker", enable_verifier).unwrap(); - let mut frame_ptr = sess.target.options.frame_pointer.clone(); - frame_ptr.ratchet(sess.opts.cg.force_frame_pointers); + let frame_ptr = + { sess.target.options.frame_pointer }.ratchet(sess.opts.cg.force_frame_pointers); let preserve_frame_pointer = frame_ptr != rustc_target::spec::FramePointer::MayOmit; flags_builder .set("preserve_frame_pointers", if preserve_frame_pointer { "true" } else { "false" }) @@ -391,7 +353,7 @@ fn build_isa(sess: &Session, jit: bool) -> Arc { } /// This is the entrypoint for a hot plugged rustc_codegen_cranelift -#[no_mangle] +#[unsafe(no_mangle)] pub fn __rustc_codegen_backend() -> Box { - Box::new(CraneliftCodegenBackend { config: None }) + Box::new(CraneliftCodegenBackend { config: OnceCell::new() }) } diff --git a/src/main_shim.rs b/src/main_shim.rs index bf756860b649..c3e4bf1f0c27 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -93,7 +93,7 @@ pub(crate) fn maybe_create_entry_wrapper( let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type()); let arg_sigpipe = bcx.ins().iconst(types::I8, sigpipe as i64); - let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func); + let main_func_ref = m.declare_func_in_func(main_func_id, bcx.func); let result = if ignore_lang_start_wrapper { // ignoring #[lang = "start"] as we are running in the jit @@ -123,7 +123,7 @@ pub(crate) fn maybe_create_entry_wrapper( let report_sig = get_function_sig(tcx, m.target_config().default_call_conv, report); let report_func_id = m.declare_function(report_name, Linkage::Import, &report_sig).unwrap(); - let report_func_ref = m.declare_func_in_func(report_func_id, &mut bcx.func); + let report_func_ref = m.declare_func_in_func(report_func_id, bcx.func); // FIXME do proper abi handling instead of expecting the pass mode to be identical // for returns and arguments. @@ -148,7 +148,7 @@ pub(crate) fn maybe_create_entry_wrapper( let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref); - let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func); + let func_ref = m.declare_func_in_func(start_func_id, bcx.func); let call_inst = bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv, arg_sigpipe]); bcx.inst_results(call_inst)[0] diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 9400ae9fcff0..2878fa7aa298 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -64,6 +64,7 @@ use cranelift_codegen::ir::Fact; use cranelift_codegen::ir::entities::AnyEntity; use cranelift_codegen::write::{FuncWriter, PlainWriter}; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_session::Session; use rustc_session::config::{OutputFilenames, OutputType}; use rustc_target::callconv::FnAbi; @@ -83,7 +84,7 @@ impl CommentWriter { instance: Instance<'tcx>, fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>, ) -> Self { - let enabled = should_write_ir(tcx); + let enabled = should_write_ir(tcx.sess); let global_comments = if enabled { with_no_trimmed_paths!({ vec![ @@ -247,8 +248,8 @@ impl FunctionCx<'_, '_, '_> { } } -pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool { - tcx.sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) +pub(crate) fn should_write_ir(sess: &Session) -> bool { + sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) } pub(crate) fn write_ir_file( @@ -311,7 +312,7 @@ impl fmt::Debug for FunctionCx<'_, '_, '_> { ::cranelift_codegen::write::decorate_function( &mut &self.clif_comments, &mut clif, - &self.bcx.func, + self.bcx.func, ) .unwrap(); writeln!(f, "\n{}", clif) diff --git a/src/unsize.rs b/src/unsize.rs index c97eb3874b02..3dbb689cccd2 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -134,7 +134,7 @@ pub(crate) fn coerce_unsized_into<'tcx>( (ty::Pat(a, _), ty::Pat(b, _)) => { let src = src.cast_pat_ty_to_base(fx.layout_of(*a)); let dst = dst.place_transmute_type(fx, *b); - return coerce_unsized_into(fx, src, dst); + coerce_unsized_into(fx, src, dst) } (&ty::Ref(..), &ty::Ref(..)) | (&ty::Ref(..), &ty::RawPtr(..)) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 9dcd4a33d44f..5b76a4cb9779 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -310,13 +310,13 @@ impl<'tcx> CValue<'tcx> { fx.bcx.ins().iconst(clif_ty, raw_val as i64) } ty::Float(FloatTy::F16) => { - fx.bcx.ins().f16const(Ieee16::with_bits(u16::try_from(const_val).unwrap())) + fx.bcx.ins().f16const(Ieee16::with_bits(u16::from(const_val))) } ty::Float(FloatTy::F32) => { - fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap())) + fx.bcx.ins().f32const(Ieee32::with_bits(u32::from(const_val))) } ty::Float(FloatTy::F64) => { - fx.bcx.ins().f64const(Ieee64::with_bits(u64::try_from(const_val).unwrap())) + fx.bcx.ins().f64const(Ieee64::with_bits(u64::from(const_val))) } ty::Float(FloatTy::F128) => { let value = fx @@ -324,7 +324,7 @@ impl<'tcx> CValue<'tcx> { .func .dfg .constants - .insert(Ieee128::with_bits(u128::try_from(const_val).unwrap()).into()); + .insert(Ieee128::with_bits(u128::from(const_val)).into()); fx.bcx.ins().f128const(value) } _ => panic!( @@ -401,9 +401,7 @@ impl<'tcx> CPlace<'tcx> { local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - let var = Variable::from_u32(fx.next_ssa_var); - fx.next_ssa_var += 1; - fx.bcx.declare_var(var, fx.clif_type(layout.ty).unwrap()); + let var = fx.bcx.declare_var(fx.clif_type(layout.ty).unwrap()); CPlace { inner: CPlaceInner::Var(local, var), layout } } @@ -412,14 +410,9 @@ impl<'tcx> CPlace<'tcx> { local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - let var1 = Variable::from_u32(fx.next_ssa_var); - fx.next_ssa_var += 1; - let var2 = Variable::from_u32(fx.next_ssa_var); - fx.next_ssa_var += 1; - let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap(); - fx.bcx.declare_var(var1, ty1); - fx.bcx.declare_var(var2, ty2); + let var1 = fx.bcx.declare_var(ty1); + let var2 = fx.bcx.declare_var(ty2); CPlace { inner: CPlaceInner::VarPair(local, var1, var2), layout } } diff --git a/src/vtable.rs b/src/vtable.rs index 423cc8d225be..b5d241d8f39f 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -84,5 +84,5 @@ pub(crate) fn get_vtable<'tcx>( if fx.clif_comments.enabled() { fx.add_comment(local_data_id, "vtable"); } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } From 9d292ca475cf182d404f5c1f4b6eaf07ac8bfb21 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 8 Nov 2025 15:03:47 +0000 Subject: [PATCH 0071/3801] Add missing --check-cfg --- build_system/build_sysroot.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 72140c651a9a..70504ee8007d 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -52,7 +52,8 @@ pub(crate) fn build_sysroot( .arg(dirs.source_dir.join("scripts").join(format!("{wrapper}.rs"))) .arg("-o") .arg(&wrapper_path) - .arg("-Cstrip=debuginfo"); + .arg("-Cstrip=debuginfo") + .arg("--check-cfg=cfg(support_panic_unwind)"); if panic_unwind_support { build_cargo_wrapper_cmd.arg("--cfg").arg("support_panic_unwind"); } From a44af2ba0a111c7495cb01027fba44cf9855de92 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 8 Nov 2025 15:04:45 +0000 Subject: [PATCH 0072/3801] Add missing --check-cfg --- build_system/build_sysroot.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 72140c651a9a..70504ee8007d 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -52,7 +52,8 @@ pub(crate) fn build_sysroot( .arg(dirs.source_dir.join("scripts").join(format!("{wrapper}.rs"))) .arg("-o") .arg(&wrapper_path) - .arg("-Cstrip=debuginfo"); + .arg("-Cstrip=debuginfo") + .arg("--check-cfg=cfg(support_panic_unwind)"); if panic_unwind_support { build_cargo_wrapper_cmd.arg("--cfg").arg("support_panic_unwind"); } From 35a99c1d41a5d1b0751aec83242c86d66526155c Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sun, 9 Nov 2025 12:39:18 -0500 Subject: [PATCH 0073/3801] rustc_target: hide TargetOptions::vendor --- src/abi/mod.rs | 4 ++-- src/codegen_f16_f128.rs | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 9ac282df5b5e..09d71f5dd557 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -916,8 +916,8 @@ pub(crate) fn codegen_call_with_unwind_action( pub(crate) fn lib_call_arg_param(tcx: TyCtxt<'_>, ty: Type, is_signed: bool) -> AbiParam { let param = AbiParam::new(ty); if ty.is_int() && u64::from(ty.bits()) < tcx.data_layout.pointer_size().bits() { - match (&tcx.sess.target.arch, tcx.sess.target.vendor.as_ref()) { - (Arch::X86_64, _) | (Arch::AArch64, "apple") => match (ty, is_signed) { + match (&tcx.sess.target.arch, tcx.sess.target.is_like_darwin) { + (Arch::X86_64, _) | (Arch::AArch64, true) => match (ty, is_signed) { (types::I8 | types::I16, true) => param.sext(), (types::I8 | types::I16, false) => param.uext(), _ => param, diff --git a/src/codegen_f16_f128.rs b/src/codegen_f16_f128.rs index 91f7220667ff..86bff32dc623 100644 --- a/src/codegen_f16_f128.rs +++ b/src/codegen_f16_f128.rs @@ -5,7 +5,7 @@ use crate::prelude::*; pub(crate) fn f16_to_f32(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { let (value, arg_ty) = - if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 { + if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == Arch::X86_64 { ( fx.bcx.ins().bitcast(types::I16, MemFlags::new(), value), lib_call_arg_param(fx.tcx, types::I16, false), @@ -22,8 +22,7 @@ fn f16_to_f64(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { } pub(crate) fn f32_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { - let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 - { + let ret_ty = if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == Arch::X86_64 { types::I16 } else { types::F16 @@ -38,8 +37,7 @@ pub(crate) fn f32_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value } fn f64_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { - let ret_ty = if fx.tcx.sess.target.vendor == "apple" && fx.tcx.sess.target.arch == Arch::X86_64 - { + let ret_ty = if fx.tcx.sess.target.is_like_darwin && fx.tcx.sess.target.arch == Arch::X86_64 { types::I16 } else { types::F16 From a197ebdb07e0908a6bbfc6faf6874ecb709c1e88 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Wed, 27 Aug 2025 16:15:08 +0300 Subject: [PATCH 0074/3801] {CStr,OsStr,Path}::as_$1 --- library/core/src/ffi/c_str.rs | 11 +++++++++++ library/std/src/ffi/os_str.rs | 11 +++++++++++ library/std/src/path.rs | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 09d9b160700c..02e43b870cb7 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -648,6 +648,17 @@ impl CStr { pub fn display(&self) -> impl fmt::Display { crate::bstr::ByteStr::from_bytes(self.to_bytes()) } + + /// Returns the same string as a string slice `&CStr`. + /// + /// This method is redundant when used directly on `&CStr`, but + /// it helps dereferencing other string-like types to string slices, + /// for example references to `Box` or `Arc`. + #[inline] + #[unstable(feature = "str_as_str", issue = "130366")] + pub const fn as_c_str(&self) -> &CStr { + self + } } #[stable(feature = "c_string_eq_c_str", since = "1.90.0")] diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 09bd911aa769..5fdf745bc18d 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -1278,6 +1278,17 @@ impl OsStr { pub fn display(&self) -> Display<'_> { Display { os_str: self } } + + /// Returns the same string as a string slice `&OsStr`. + /// + /// This method is redundant when used directly on `&OsStr`, but + /// it helps dereferencing other string-like types to string slices, + /// for example references to `Box` or `Arc`. + #[inline] + #[unstable(feature = "str_as_str", issue = "130366")] + pub const fn as_os_str(&self) -> &OsStr { + self + } } #[stable(feature = "box_from_os_str", since = "1.17.0")] diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 114fcc796c52..b6b899a67d5d 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -3208,6 +3208,17 @@ impl Path { Display { inner: self.inner.display() } } + /// Returns the same path as `&Path`. + /// + /// This method is redundant when used directly on `&Path`, but + /// it helps dereferencing other `PathBuf`-like types to `Path`s, + /// for example references to `Box` or `Arc`. + #[inline] + #[unstable(feature = "str_as_str", issue = "130366")] + pub const fn as_path(&self) -> &Path { + self + } + /// Queries the file system to get information about a file, directory, etc. /// /// This function will traverse symbolic links to query information about the From 4e5ce74da2f36ebc760e24245bb02a9563a30c38 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Wed, 27 Aug 2025 17:27:05 +0300 Subject: [PATCH 0075/3801] `[T]::as_[mut_]slice` --- library/core/src/slice/mod.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f03f2045444d..7b482c751036 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4906,6 +4906,28 @@ impl [T] { if start <= self.len() && end <= self.len() { Some(start..end) } else { None } } + + /// Returns the same slice `&[T]`. + /// + /// This method is redundant when used directly on `&[T]`, but + /// it helps dereferencing other "container" types to slices, + /// for example `Box<[T]>` or `Arc<[T]>`. + #[inline] + #[unstable(feature = "str_as_str", issue = "130366")] + pub const fn as_slice(&self) -> &[T] { + self + } + + /// Returns the same slice `&mut [T]`. + /// + /// This method is redundant when used directly on `&mut [T]`, but + /// it helps dereferencing other "container" types to slices, + /// for example `Box<[T]>` or `MutexGuard<[T]>`. + #[inline] + #[unstable(feature = "str_as_str", issue = "130366")] + pub const fn as_mut_slice(&mut self) -> &mut [T] { + self + } } impl [MaybeUninit] { From 48f7f312f12340591ab25d0679376f9d3b874d36 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Wed, 27 Aug 2025 17:27:05 +0300 Subject: [PATCH 0076/3801] `ByteStr::as_[mut_]byte_str` --- library/core/src/bstr/mod.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/library/core/src/bstr/mod.rs b/library/core/src/bstr/mod.rs index e13dc5cd44d5..34e1ea66c99a 100644 --- a/library/core/src/bstr/mod.rs +++ b/library/core/src/bstr/mod.rs @@ -68,6 +68,30 @@ impl ByteStr { ByteStr::from_bytes(bytes.as_ref()) } + /// Returns the same string as `&ByteStr`. + /// + /// This method is redundant when used directly on `&ByteStr`, but + /// it helps dereferencing other "container" types, + /// for example `Box` or `Arc`. + #[inline] + // #[unstable(feature = "str_as_str", issue = "130366")] + #[unstable(feature = "bstr", issue = "134915")] + pub const fn as_byte_str(&self) -> &ByteStr { + self + } + + /// Returns the same string as `&mut ByteStr`. + /// + /// This method is redundant when used directly on `&mut ByteStr`, but + /// it helps dereferencing other "container" types, + /// for example `Box` or `MutexGuard`. + #[inline] + // #[unstable(feature = "str_as_str", issue = "130366")] + #[unstable(feature = "bstr", issue = "134915")] + pub const fn as_mut_byte_str(&mut self) -> &mut ByteStr { + self + } + #[doc(hidden)] #[unstable(feature = "bstr_internals", issue = "none")] #[inline] From 242b4b5dc96472858438338642635091dfd3ec99 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 11 Nov 2025 13:25:22 -0800 Subject: [PATCH 0077/3801] Remove more #[must_use] from portable-simd warning: `#[must_use]` attribute cannot be used on trait methods in impl blocks --> crates/core_simd/src/masks/bitmask.rs:173:5 | 173 | #[must_use = "method returns a new mask and does not mutate the original value"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, traits, and unions = note: `#[warn(unused_attributes)]` (part of `#[warn(unused)]`) on by default warning: `#[must_use]` attribute cannot be used on trait methods in impl blocks --> crates/core_simd/src/masks/bitmask.rs:190:5 | 190 | #[must_use = "method returns a new mask and does not mutate the original value"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, traits, and unions warning: `#[must_use]` attribute cannot be used on trait methods in impl blocks --> crates/core_simd/src/masks/bitmask.rs:206:5 | 206 | #[must_use = "method returns a new mask and does not mutate the original value"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, traits, and unions warning: `#[must_use]` attribute cannot be used on trait methods in impl blocks --> crates/core_simd/src/masks/bitmask.rs:222:5 | 222 | #[must_use = "method returns a new mask and does not mutate the original value"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, traits, and unions --- crates/core_simd/src/masks/bitmask.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index 8221d8f17e90..32d37b553392 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -170,7 +170,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(mut self, rhs: Self) -> Self { for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { *l &= r; @@ -187,7 +186,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(mut self, rhs: Self) -> Self { for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { *l |= r; @@ -203,7 +201,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(mut self, rhs: Self) -> Self::Output { for (l, r) in self.0.as_mut().iter_mut().zip(rhs.0.as_ref().iter()) { *l ^= r; @@ -219,7 +216,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(mut self) -> Self::Output { for x in self.0.as_mut() { *x = !*x; From 032ba980b1717457201515ab5476b82dba4f7f1e Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 5 Nov 2025 12:37:09 -0500 Subject: [PATCH 0078/3801] rustc_target: introduce Abi Improve type safety by using an enum rather than strings. --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4745243a6eab..19058dac832f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,7 +49,7 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; -use rustc_target::spec::Arch; +use rustc_target::spec::{Abi, Arch}; pub use crate::config::*; use crate::prelude::*; @@ -186,7 +186,7 @@ impl CodegenBackend for CraneliftCodegenBackend { let has_reliable_f16_f128 = !(sess.target.arch == Arch::X86_64 && sess.target.os == "windows" && sess.target.env == "gnu" - && sess.target.abi != "llvm"); + && sess.target.abi != Abi::Llvm); TargetConfig { target_features, From 46f27590af7a87efa24904166b1123a0bdea49b0 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 5 Nov 2025 12:37:09 -0500 Subject: [PATCH 0079/3801] rustc_target: introduce Env Improve type safety by using an enum rather than strings. --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 19058dac832f..2175869085a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,7 +49,7 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; -use rustc_target::spec::{Abi, Arch}; +use rustc_target::spec::{Abi, Arch, Env}; pub use crate::config::*; use crate::prelude::*; @@ -185,7 +185,7 @@ impl CodegenBackend for CraneliftCodegenBackend { // won't be available when using a LLVM-built sysroot. let has_reliable_f16_f128 = !(sess.target.arch == Arch::X86_64 && sess.target.os == "windows" - && sess.target.env == "gnu" + && sess.target.env == Env::Gnu && sess.target.abi != Abi::Llvm); TargetConfig { From d1c33c3e84cf76e30e5b9b851da865fa8c948baa Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 5 Nov 2025 16:32:20 -0500 Subject: [PATCH 0080/3801] rustc_target: introduce Os Improve type safety by using an enum rather than strings. --- src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2175869085a3..5fdecd014ac0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,7 +49,7 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; -use rustc_target::spec::{Abi, Arch, Env}; +use rustc_target::spec::{Abi, Arch, Env, Os}; pub use crate::config::*; use crate::prelude::*; @@ -163,15 +163,15 @@ impl CodegenBackend for CraneliftCodegenBackend { fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] let target_features = match sess.target.arch { - Arch::X86_64 if sess.target.os != "none" => { + Arch::X86_64 if sess.target.os != Os::None => { // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled vec![sym::fxsr, sym::sse, sym::sse2, Symbol::intern("x87")] } - Arch::AArch64 => match &*sess.target.os { - "none" => vec![], + Arch::AArch64 => match &sess.target.os { + Os::None => vec![], // On macOS the aes, sha2 and sha3 features are enabled by default and ring // fails to compile on macOS when they are not present. - "macos" => vec![sym::neon, sym::aes, sym::sha2, sym::sha3], + Os::MacOs => vec![sym::neon, sym::aes, sym::sha2, sym::sha3], // AArch64 mandates Neon support _ => vec![sym::neon], }, @@ -184,7 +184,7 @@ impl CodegenBackend for CraneliftCodegenBackend { // targets due to GCC using a different ABI than LLVM. Therefore `f16` and `f128` // won't be available when using a LLVM-built sysroot. let has_reliable_f16_f128 = !(sess.target.arch == Arch::X86_64 - && sess.target.os == "windows" + && sess.target.os == Os::Windows && sess.target.env == Env::Gnu && sess.target.abi != Abi::Llvm); From 519785671b6d56dea6b11c4ab41aacaebe4d252e Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 11 Nov 2025 14:57:22 -0500 Subject: [PATCH 0081/3801] Set -Cpanic=abort in windows-msvc stack protector tests --- ...otector-heuristics-effect-windows-32bit.rs | 74 +++++++++++------- ...otector-heuristics-effect-windows-64bit.rs | 78 +++++++++++-------- .../stack-protector-target-support.rs | 2 +- 3 files changed, 93 insertions(+), 61 deletions(-) diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs index 3287e018b404..5759c387e3b1 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs @@ -7,7 +7,7 @@ //@ [strong] compile-flags: -Z stack-protector=strong //@ [basic] compile-flags: -Z stack-protector=basic //@ [none] compile-flags: -Z stack-protector=none -//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled +//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort #![crate_type = "lib"] #![allow(internal_features)] @@ -26,6 +26,7 @@ pub fn emptyfn() { // CHECK-LABEL: array_char #[no_mangle] pub fn array_char(f: fn(*const char)) { + // CHECK-DAG: .cv_fpo_endprologue let a = ['c'; 1]; let b = ['d'; 3]; let c = ['e'; 15]; @@ -39,11 +40,14 @@ pub fn array_char(f: fn(*const char)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } // CHECK-LABEL: array_u8_1 #[no_mangle] pub fn array_u8_1(f: fn(*const u8)) { + // CHECK-DAG: .cv_fpo_endprologue let a = [0u8; 1]; f(&a as *const _); @@ -55,11 +59,14 @@ pub fn array_u8_1(f: fn(*const u8)) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } // CHECK-LABEL: array_u8_small: #[no_mangle] pub fn array_u8_small(f: fn(*const u8)) { + // CHECK-DAG: .cv_fpo_endprologue let a = [0u8; 2]; let b = [0u8; 7]; f(&a as *const _); @@ -72,11 +79,14 @@ pub fn array_u8_small(f: fn(*const u8)) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } // CHECK-LABEL: array_u8_large: #[no_mangle] pub fn array_u8_large(f: fn(*const u8)) { + // CHECK-DAG: .cv_fpo_endprologue let a = [0u8; 9]; f(&a as *const _); @@ -88,6 +98,8 @@ pub fn array_u8_large(f: fn(*const u8)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } #[derive(Copy, Clone)] @@ -96,6 +108,7 @@ pub struct ByteSizedNewtype(u8); // CHECK-LABEL: array_bytesizednewtype_9: #[no_mangle] pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { + // CHECK-DAG: .cv_fpo_endprologue let a = [ByteSizedNewtype(0); 9]; f(&a as *const _); @@ -107,11 +120,14 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } // CHECK-LABEL: local_var_addr_used_indirectly #[no_mangle] pub fn local_var_addr_used_indirectly(f: fn(bool)) { + // CHECK-DAG: .cv_fpo_endprologue let a = 5; let a_addr = &a as *const _ as usize; f(a_addr & 0x10 == 0); @@ -134,37 +150,27 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } // CHECK-LABEL: local_string_addr_taken #[no_mangle] pub fn local_string_addr_taken(f: fn(&String)) { + // CHECK-DAG: .cv_fpo_endprologue let x = String::new(); f(&x); // Taking the address of the local variable `x` leads to stack smash - // protection with the `strong` heuristic, but not with the `basic` - // heuristic. It does not matter that the reference is not mut. - // - // An interesting note is that a similar function in C++ *would* be - // protected by the `basic` heuristic, because `std::string` has a char - // array internally as a small object optimization: - // ``` - // cat < - // void f(void (*g)(const std::string&)) { - // std::string x; - // g(x); - // } - // EOF - // ``` - // + // protection. It does not matter that the reference is not mut. // all: __security_check_cookie - // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie + // strong: __security_check_cookie + // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } pub trait SelfByRef { @@ -180,6 +186,7 @@ impl SelfByRef for i32 { // CHECK-LABEL: local_var_addr_taken_used_locally_only #[no_mangle] pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32)) { + // CHECK-DAG: .cv_fpo_endprologue let x = factory(); let g = x.f(); sink(g); @@ -194,6 +201,8 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } pub struct Gigastruct { @@ -207,6 +216,7 @@ pub struct Gigastruct { // CHECK-LABEL: local_large_var_moved #[no_mangle] pub fn local_large_var_moved(f: fn(Gigastruct)) { + // CHECK-DAG: .cv_fpo_endprologue let x = Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 }; f(x); @@ -231,11 +241,14 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } // CHECK-LABEL: local_large_var_cloned #[no_mangle] pub fn local_large_var_cloned(f: fn(Gigastruct)) { + // CHECK-DAG: .cv_fpo_endprologue f(Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 }); // A new instance of `Gigastruct` is passed to `f()`, without any apparent @@ -260,6 +273,8 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } extern "C" { @@ -293,6 +308,7 @@ extern "C" { // CHECK-LABEL: alloca_small_compile_time_constant_arg #[no_mangle] pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { + // CHECK-DAG: .cv_fpo_endprologue f(unsafe { alloca(8) }); // all: __security_check_cookie @@ -300,11 +316,14 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } // CHECK-LABEL: alloca_large_compile_time_constant_arg #[no_mangle] pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { + // CHECK-DAG: .cv_fpo_endprologue f(unsafe { alloca(9) }); // all: __security_check_cookie @@ -312,11 +331,14 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } // CHECK-LABEL: alloca_dynamic_arg #[no_mangle] pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { + // CHECK-DAG: .cv_fpo_endprologue f(unsafe { alloca(n) }); // all: __security_check_cookie @@ -324,18 +346,19 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } // The question then is: in what ways can Rust code generate array-`alloca` // LLVM instructions? This appears to only be generated by // rustc_codegen_ssa::traits::Builder::array_alloca() through -// rustc_codegen_ssa::mir::operand::OperandValue::store_unsized(). FWICT -// this is support for the "unsized locals" unstable feature: -// https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html. +// rustc_codegen_ssa::mir::operand::OperandValue::store_unsized(). // CHECK-LABEL: unsized_fn_param #[no_mangle] pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { + // CHECK-DAG: .cv_fpo_endprologue let n = if l { 1 } else { 2 }; f(*Box::<[u8]>::from(&s[0..n])); // slice-copy with Box::from @@ -346,14 +369,11 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // alloca, and is therefore not protected by the `strong` or `basic` // heuristics. - // We should have a __security_check_cookie call in `all` and `strong` modes but - // LLVM does not support generating stack protectors in functions with funclet - // based EH personalities. - // https://github.com/llvm/llvm-project/blob/37fd3c96b917096d8a550038f6e61cdf0fc4174f/llvm/lib/CodeGen/StackProtector.cpp#L103C1-L109C4 // all-NOT: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .cv_fpo_endproc } diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs index 9a3dabc74dde..56a6f08da587 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs @@ -7,7 +7,7 @@ //@ [strong] compile-flags: -Z stack-protector=strong //@ [basic] compile-flags: -Z stack-protector=basic //@ [none] compile-flags: -Z stack-protector=none -//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled +//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort #![crate_type = "lib"] #![feature(unsized_fn_params)] @@ -25,6 +25,7 @@ pub fn emptyfn() { // CHECK-LABEL: array_char #[no_mangle] pub fn array_char(f: fn(*const char)) { + // CHECK-DAG: .seh_endprologue let a = ['c'; 1]; let b = ['d'; 3]; let c = ['e'; 15]; @@ -38,11 +39,14 @@ pub fn array_char(f: fn(*const char)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } // CHECK-LABEL: array_u8_1 #[no_mangle] pub fn array_u8_1(f: fn(*const u8)) { + // CHECK-DAG: .seh_endprologue let a = [0u8; 1]; f(&a as *const _); @@ -54,11 +58,14 @@ pub fn array_u8_1(f: fn(*const u8)) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } // CHECK-LABEL: array_u8_small: #[no_mangle] pub fn array_u8_small(f: fn(*const u8)) { + // CHECK-DAG: .seh_endprologue let a = [0u8; 2]; let b = [0u8; 7]; f(&a as *const _); @@ -71,11 +78,14 @@ pub fn array_u8_small(f: fn(*const u8)) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } // CHECK-LABEL: array_u8_large: #[no_mangle] pub fn array_u8_large(f: fn(*const u8)) { + // CHECK-DAG: .seh_endprologue let a = [0u8; 9]; f(&a as *const _); @@ -87,6 +97,8 @@ pub fn array_u8_large(f: fn(*const u8)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } #[derive(Copy, Clone)] @@ -95,6 +107,7 @@ pub struct ByteSizedNewtype(u8); // CHECK-LABEL: array_bytesizednewtype_9: #[no_mangle] pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { + // CHECK-DAG: .seh_endprologue let a = [ByteSizedNewtype(0); 9]; f(&a as *const _); @@ -106,11 +119,14 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } // CHECK-LABEL: local_var_addr_used_indirectly #[no_mangle] pub fn local_var_addr_used_indirectly(f: fn(bool)) { + // CHECK-DAG: .seh_endprologue let a = 5; let a_addr = &a as *const _ as usize; f(a_addr & 0x10 == 0); @@ -133,6 +149,8 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } // CHECK-LABEL: local_string_addr_taken @@ -143,31 +161,11 @@ pub fn local_string_addr_taken(f: fn(&String)) { f(&x); // Taking the address of the local variable `x` leads to stack smash - // protection with the `strong` heuristic, but not with the `basic` - // heuristic. It does not matter that the reference is not mut. - // - // An interesting note is that a similar function in C++ *would* be - // protected by the `basic` heuristic, because `std::string` has a char - // array internally as a small object optimization: - // ``` - // cat < - // void f(void (*g)(const std::string&)) { - // std::string x; - // g(x); - // } - // EOF - // ``` - // + // protection. It does not matter that the reference is not mut. - // We should have a __security_check_cookie call in `all` and `strong` modes but - // LLVM does not support generating stack protectors in functions with funclet - // based EH personalities. - // https://github.com/llvm/llvm-project/blob/37fd3c96b917096d8a550038f6e61cdf0fc4174f/llvm/lib/CodeGen/StackProtector.cpp#L103C1-L109C4 - // all-NOT: __security_check_cookie - // strong-NOT: __security_check_cookie - - // basic-NOT: __security_check_cookie + // all: __security_check_cookie + // strong: __security_check_cookie + // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -187,6 +185,7 @@ impl SelfByRef for i32 { // CHECK-LABEL: local_var_addr_taken_used_locally_only #[no_mangle] pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32)) { + // CHECK-DAG: .seh_endprologue let x = factory(); let g = x.f(); sink(g); @@ -201,6 +200,8 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } pub struct Gigastruct { @@ -214,6 +215,7 @@ pub struct Gigastruct { // CHECK-LABEL: local_large_var_moved #[no_mangle] pub fn local_large_var_moved(f: fn(Gigastruct)) { + // CHECK-DAG: .seh_endprologue let x = Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 }; f(x); @@ -238,11 +240,14 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } // CHECK-LABEL: local_large_var_cloned #[no_mangle] pub fn local_large_var_cloned(f: fn(Gigastruct)) { + // CHECK-DAG: .seh_endprologue f(Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 }); // A new instance of `Gigastruct` is passed to `f()`, without any apparent @@ -267,6 +272,8 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } extern "C" { @@ -300,6 +307,7 @@ extern "C" { // CHECK-LABEL: alloca_small_compile_time_constant_arg #[no_mangle] pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { + // CHECK-DAG: .seh_endprologue f(unsafe { alloca(8) }); // all: __security_check_cookie @@ -307,11 +315,14 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } // CHECK-LABEL: alloca_large_compile_time_constant_arg #[no_mangle] pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { + // CHECK-DAG: .seh_endprologue f(unsafe { alloca(9) }); // all: __security_check_cookie @@ -319,11 +330,14 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } // CHECK-LABEL: alloca_dynamic_arg #[no_mangle] pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { + // CHECK-DAG: .seh_endprologue f(unsafe { alloca(n) }); // all: __security_check_cookie @@ -331,18 +345,19 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } // The question then is: in what ways can Rust code generate array-`alloca` // LLVM instructions? This appears to only be generated by // rustc_codegen_ssa::traits::Builder::array_alloca() through -// rustc_codegen_ssa::mir::operand::OperandValue::store_unsized(). FWICT -// this is support for the "unsized locals" unstable feature: -// https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html. +// rustc_codegen_ssa::mir::operand::OperandValue::store_unsized(). // CHECK-LABEL: unsized_fn_param #[no_mangle] pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { + // CHECK-DAG: .seh_endprologue let n = if l { 1 } else { 2 }; f(*Box::<[u8]>::from(&s[0..n])); // slice-copy with Box::from @@ -353,14 +368,11 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // alloca, and is therefore not protected by the `strong` or `basic` // heuristics. - // We should have a __security_check_cookie call in `all` and `strong` modes but - // LLVM does not support generating stack protectors in functions with funclet - // based EH personalities. - // https://github.com/llvm/llvm-project/blob/37fd3c96b917096d8a550038f6e61cdf0fc4174f/llvm/lib/CodeGen/StackProtector.cpp#L103C1-L109C4 // all-NOT: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc } diff --git a/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs b/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs index 0218fe0a52f8..9f182985d157 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs @@ -173,7 +173,7 @@ //@ [r84] needs-llvm-components: x86 //@ [r85] compile-flags: --target x86_64-unknown-redox //@ [r85] needs-llvm-components: x86 -//@ compile-flags: -Z stack-protector=all +//@ compile-flags: -Z stack-protector=all -Cpanic=abort //@ compile-flags: -C opt-level=2 #![crate_type = "lib"] From a5f677b665961956f25e81818b1983687449135d Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 12 Nov 2025 23:40:47 -0500 Subject: [PATCH 0082/3801] Try to fix i686 --- ...-protector-heuristics-effect-windows-32bit.rs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs index 5759c387e3b1..d1b51068fce5 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs @@ -7,7 +7,7 @@ //@ [strong] compile-flags: -Z stack-protector=strong //@ [basic] compile-flags: -Z stack-protector=basic //@ [none] compile-flags: -Z stack-protector=none -//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort +//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort -Cdebuginfo=1 #![crate_type = "lib"] #![allow(internal_features)] @@ -26,7 +26,6 @@ pub fn emptyfn() { // CHECK-LABEL: array_char #[no_mangle] pub fn array_char(f: fn(*const char)) { - // CHECK-DAG: .cv_fpo_endprologue let a = ['c'; 1]; let b = ['d'; 3]; let c = ['e'; 15]; @@ -47,7 +46,6 @@ pub fn array_char(f: fn(*const char)) { // CHECK-LABEL: array_u8_1 #[no_mangle] pub fn array_u8_1(f: fn(*const u8)) { - // CHECK-DAG: .cv_fpo_endprologue let a = [0u8; 1]; f(&a as *const _); @@ -66,7 +64,6 @@ pub fn array_u8_1(f: fn(*const u8)) { // CHECK-LABEL: array_u8_small: #[no_mangle] pub fn array_u8_small(f: fn(*const u8)) { - // CHECK-DAG: .cv_fpo_endprologue let a = [0u8; 2]; let b = [0u8; 7]; f(&a as *const _); @@ -86,7 +83,6 @@ pub fn array_u8_small(f: fn(*const u8)) { // CHECK-LABEL: array_u8_large: #[no_mangle] pub fn array_u8_large(f: fn(*const u8)) { - // CHECK-DAG: .cv_fpo_endprologue let a = [0u8; 9]; f(&a as *const _); @@ -108,7 +104,6 @@ pub struct ByteSizedNewtype(u8); // CHECK-LABEL: array_bytesizednewtype_9: #[no_mangle] pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { - // CHECK-DAG: .cv_fpo_endprologue let a = [ByteSizedNewtype(0); 9]; f(&a as *const _); @@ -127,7 +122,6 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // CHECK-LABEL: local_var_addr_used_indirectly #[no_mangle] pub fn local_var_addr_used_indirectly(f: fn(bool)) { - // CHECK-DAG: .cv_fpo_endprologue let a = 5; let a_addr = &a as *const _ as usize; f(a_addr & 0x10 == 0); @@ -157,7 +151,6 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // CHECK-LABEL: local_string_addr_taken #[no_mangle] pub fn local_string_addr_taken(f: fn(&String)) { - // CHECK-DAG: .cv_fpo_endprologue let x = String::new(); f(&x); @@ -186,7 +179,6 @@ impl SelfByRef for i32 { // CHECK-LABEL: local_var_addr_taken_used_locally_only #[no_mangle] pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32)) { - // CHECK-DAG: .cv_fpo_endprologue let x = factory(); let g = x.f(); sink(g); @@ -216,7 +208,6 @@ pub struct Gigastruct { // CHECK-LABEL: local_large_var_moved #[no_mangle] pub fn local_large_var_moved(f: fn(Gigastruct)) { - // CHECK-DAG: .cv_fpo_endprologue let x = Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 }; f(x); @@ -248,7 +239,6 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // CHECK-LABEL: local_large_var_cloned #[no_mangle] pub fn local_large_var_cloned(f: fn(Gigastruct)) { - // CHECK-DAG: .cv_fpo_endprologue f(Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 }); // A new instance of `Gigastruct` is passed to `f()`, without any apparent @@ -308,7 +298,6 @@ extern "C" { // CHECK-LABEL: alloca_small_compile_time_constant_arg #[no_mangle] pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { - // CHECK-DAG: .cv_fpo_endprologue f(unsafe { alloca(8) }); // all: __security_check_cookie @@ -323,7 +312,6 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // CHECK-LABEL: alloca_large_compile_time_constant_arg #[no_mangle] pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { - // CHECK-DAG: .cv_fpo_endprologue f(unsafe { alloca(9) }); // all: __security_check_cookie @@ -338,7 +326,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // CHECK-LABEL: alloca_dynamic_arg #[no_mangle] pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { - // CHECK-DAG: .cv_fpo_endprologue f(unsafe { alloca(n) }); // all: __security_check_cookie @@ -358,7 +345,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // CHECK-LABEL: unsized_fn_param #[no_mangle] pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { - // CHECK-DAG: .cv_fpo_endprologue let n = if l { 1 } else { 2 }; f(*Box::<[u8]>::from(&s[0..n])); // slice-copy with Box::from From cf7efc3624e9060ac88cbd3381cdc189eb16c2f2 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Thu, 13 Nov 2025 19:08:35 +0800 Subject: [PATCH 0083/3801] Fix complete unit return semicolon in arg-list Example --- ```rust fn foo() {} fn baz(_: impl FnOnce()) {} fn bar() { baz(fo$0); } ``` **Before this PR** ```rust fn foo() {} fn baz(_: impl FnOnce()) {} fn bar() { baz(foo();$0); } ``` **After this PR** ```rust fn foo() {} fn baz(_: impl FnOnce()) {} fn bar() { baz(foo()$0); } ``` --- .../crates/ide-completion/src/context.rs | 59 +++++-------------- .../ide-completion/src/render/function.rs | 21 +++++++ 2 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index 2f166b718451..8051f6d20775 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -4,7 +4,7 @@ mod analysis; #[cfg(test)] mod tests; -use std::{iter, ops::ControlFlow}; +use std::iter; use base_db::RootQueryDb as _; use hir::{ @@ -21,7 +21,6 @@ use syntax::{ SyntaxKind::{self, *}, SyntaxToken, T, TextRange, TextSize, ast::{self, AttrKind, NameOrNameRef}, - match_ast, }; use crate::{ @@ -818,48 +817,20 @@ impl<'db> CompletionContext<'db> { .extend(exclude_traits.iter().map(|&t| (t.into(), AutoImportExclusionType::Always))); // FIXME: This should be part of `CompletionAnalysis` / `expand_and_analyze` - let complete_semicolon = if config.add_semicolon_to_unit { - let inside_closure_ret = token.parent_ancestors().try_for_each(|ancestor| { - match_ast! { - match ancestor { - ast::BlockExpr(_) => ControlFlow::Break(false), - ast::ClosureExpr(_) => ControlFlow::Break(true), - _ => ControlFlow::Continue(()) - } - } - }); - - if inside_closure_ret == ControlFlow::Break(true) { - CompleteSemicolon::DoNotComplete - } else { - let next_non_trivia_token = - std::iter::successors(token.next_token(), |it| it.next_token()) - .find(|it| !it.kind().is_trivia()); - let in_match_arm = token.parent_ancestors().try_for_each(|ancestor| { - if ast::MatchArm::can_cast(ancestor.kind()) { - ControlFlow::Break(true) - } else if matches!( - ancestor.kind(), - SyntaxKind::EXPR_STMT | SyntaxKind::BLOCK_EXPR - ) { - ControlFlow::Break(false) - } else { - ControlFlow::Continue(()) - } - }); - // FIXME: This will assume expr macros are not inside match, we need to somehow go to the "parent" of the root node. - let in_match_arm = match in_match_arm { - ControlFlow::Continue(()) => false, - ControlFlow::Break(it) => it, - }; - let complete_token = if in_match_arm { T![,] } else { T![;] }; - if next_non_trivia_token.map(|it| it.kind()) == Some(complete_token) { - CompleteSemicolon::DoNotComplete - } else if in_match_arm { - CompleteSemicolon::CompleteComma - } else { - CompleteSemicolon::CompleteSemi - } + let complete_semicolon = if !config.add_semicolon_to_unit { + CompleteSemicolon::DoNotComplete + } else if let Some(term_node) = + sema.token_ancestors_with_macros(token.clone()).find(|node| { + matches!(node.kind(), BLOCK_EXPR | MATCH_ARM | CLOSURE_EXPR | ARG_LIST | PAREN_EXPR) + }) + { + let next_token = iter::successors(token.next_token(), |it| it.next_token()) + .map(|it| it.kind()) + .find(|kind| !kind.is_trivia()); + match term_node.kind() { + MATCH_ARM if next_token != Some(T![,]) => CompleteSemicolon::CompleteComma, + BLOCK_EXPR if next_token != Some(T![;]) => CompleteSemicolon::CompleteSemi, + _ => CompleteSemicolon::DoNotComplete, } } else { CompleteSemicolon::DoNotComplete diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs index 3235323b3a59..4713b1f1afa7 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs @@ -884,6 +884,27 @@ fn baz(_: impl FnOnce()) {} fn bar() { baz(|| foo()$0); } +"#, + ); + } + + #[test] + fn no_semicolon_in_arg_list() { + check_edit( + r#"foo"#, + r#" +fn foo() {} +fn baz(_: impl FnOnce()) {} +fn bar() { + baz(fo$0); +} +"#, + r#" +fn foo() {} +fn baz(_: impl FnOnce()) {} +fn bar() { + baz(foo()$0); +} "#, ); } From a842469f0d7ac75d92464ecd1b5b7cef289e0bed Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 15 Nov 2025 16:08:59 +0000 Subject: [PATCH 0084/3801] Adjust for rust-lang/rust default branch rename --- scripts/rustup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/rustup.sh b/scripts/rustup.sh index fdfd03029b16..1a82193303e2 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -43,7 +43,7 @@ case $1 in cg_clif=$(pwd) pushd ../rust - git pull origin master + git pull origin main branch=sync_cg_clif-$(date +%Y-%m-%d) git checkout -b "$branch" "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git main @@ -63,7 +63,7 @@ case $1 in cg_clif=$(pwd) pushd ../rust - git fetch origin master + git fetch origin main git -c advice.detachedHead=false checkout "$RUST_VERS" "$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust popd From 614349ab2cf3a7a9afee52dc6ed50ab0914a5fbd Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 15 Nov 2025 16:18:36 +0000 Subject: [PATCH 0085/3801] Rustup to rustc 1.93.0-nightly (b6d7ff3aa 2025-11-14) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 17c2cc5ac660..3aeb07e469a3 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-11-08" +channel = "nightly-2025-11-15" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 95b5bbac7ca87573d35d1cde09f938f577dd3a4a Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Thu, 13 Nov 2025 23:00:13 -0800 Subject: [PATCH 0086/3801] Fix division syntax in doc comments `mod` is a keyword in Rust, and since we're talking about remainders we should be using division syntax here. --- library/core/src/num/f128.rs | 3 ++- library/core/src/num/f16.rs | 3 ++- library/core/src/num/int_macros.rs | 3 ++- library/core/src/num/uint_macros.rs | 3 ++- library/std/src/num/f32.rs | 3 ++- library/std/src/num/f64.rs | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index e7101537b298..50b8cd56e914 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1704,7 +1704,8 @@ impl f128 { q } - /// Calculates the least nonnegative remainder of `self (mod rhs)`. + /// Calculates the least nonnegative remainder of `self` when + /// divided by `rhs`. /// /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in /// most cases. However, due to a floating point round-off error it can diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index aa8342a22ad5..80342c27802f 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1679,7 +1679,8 @@ impl f16 { q } - /// Calculates the least nonnegative remainder of `self (mod rhs)`. + /// Calculates the least nonnegative remainder of `self` when + /// divided by `rhs`. /// /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in /// most cases. However, due to a floating point round-off error it can diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 70e764de9069..ab75074ca66b 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -3124,7 +3124,8 @@ macro_rules! int_impl { } - /// Calculates the least nonnegative remainder of `self (mod rhs)`. + /// Calculates the least nonnegative remainder of `self` when + /// divided by `rhs`. /// /// This is done as if by the Euclidean division algorithm -- given /// `r = self.rem_euclid(rhs)`, the result satisfies diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index d38d3a1a5ad4..5720df816093 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3399,7 +3399,8 @@ macro_rules! uint_impl { } - /// Calculates the least remainder of `self (mod rhs)`. + /// Calculates the least remainder of `self` when divided by + /// `rhs`. /// /// Since, for the positive integers, all common /// definitions of division are equal, this diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index c9e192201aff..0d209b051f4a 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -252,7 +252,8 @@ impl f32 { core::f32::math::div_euclid(self, rhs) } - /// Calculates the least nonnegative remainder of `self (mod rhs)`. + /// Calculates the least nonnegative remainder of `self` when divided by + /// `rhs`. /// /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in /// most cases. However, due to a floating point round-off error it can diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index 11874f9280f0..43de685ad8ba 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -252,7 +252,8 @@ impl f64 { core::f64::math::div_euclid(self, rhs) } - /// Calculates the least nonnegative remainder of `self (mod rhs)`. + /// Calculates the least nonnegative remainder of `self` when divided by + /// `rhs`. /// /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in /// most cases. However, due to a floating point round-off error it can From 8e3fc73e97982ebe2ba7011eff61cee4016ee9d9 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 16 Nov 2025 17:23:32 +0800 Subject: [PATCH 0087/3801] Fix make::unnamed_param result a untyped_param - Add `make::untyped_param` - Add some basic make tests Example --- ```rust make::unnamed_param(make::ty("Vec")), ``` **Before this PR** ```text PARAM@0..4 IDENT_PAT@0..4 NAME@0..4 IDENT@0..4 "Vec" ``` **After this PR** ```text PARAM@0..6 PATH_TYPE@0..6 PATH@0..6 PATH_SEGMENT@0..6 NAME_REF@0..3 IDENT@0..3 "Vec" GENERIC_ARG_LIST@3..6 L_ANGLE@3..4 "<" TYPE_ARG@4..5 PATH_TYPE@4..5 PATH@4..5 PATH_SEGMENT@4..5 NAME_REF@4..5 IDENT@4..5 "T" R_ANGLE@5..6 ">" ``` --- Assist: `Generate a type alias for function with unnamed params` ```rust fn foo$0(x: Vec) {} ``` **Before this PR** ```rust type FooFn = fn(Vec); fn foo(x: Vec) {} ``` **After this PR** ```rust type FooFn = fn(Vec); fn foo(x: Vec) {} ``` --- .../crates/syntax/src/ast/make.rs | 97 ++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index dba39204e32e..4a7afed61ee2 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -1016,7 +1016,19 @@ pub fn item_static( } pub fn unnamed_param(ty: ast::Type) -> ast::Param { - ast_from_text(&format!("fn f({ty}) {{ }}")) + quote! { + Param { + #ty + } + } +} + +pub fn untyped_param(pat: ast::Pat) -> ast::Param { + quote! { + Param { + #pat + } + } } pub fn param(pat: ast::Pat, ty: ast::Type) -> ast::Param { @@ -1456,3 +1468,86 @@ pub mod tokens { } } } + +#[cfg(test)] +mod tests { + use expect_test::expect; + + use super::*; + + #[track_caller] + fn check(node: impl AstNode, expect: expect_test::Expect) { + let node_debug = format!("{:#?}", node.syntax()); + expect.assert_eq(&node_debug); + } + + #[test] + fn test_unnamed_param() { + check( + unnamed_param(ty("Vec")), + expect![[r#" + PARAM@0..3 + PATH_TYPE@0..3 + PATH@0..3 + PATH_SEGMENT@0..3 + NAME_REF@0..3 + IDENT@0..3 "Vec" + "#]], + ); + + check( + unnamed_param(ty("Vec")), + expect![[r#" + PARAM@0..6 + PATH_TYPE@0..6 + PATH@0..6 + PATH_SEGMENT@0..6 + NAME_REF@0..3 + IDENT@0..3 "Vec" + GENERIC_ARG_LIST@3..6 + L_ANGLE@3..4 "<" + TYPE_ARG@4..5 + PATH_TYPE@4..5 + PATH@4..5 + PATH_SEGMENT@4..5 + NAME_REF@4..5 + IDENT@4..5 "T" + R_ANGLE@5..6 ">" + "#]], + ); + } + + #[test] + fn test_untyped_param() { + check( + untyped_param(path_pat(ext::ident_path("name"))), + expect![[r#" + PARAM@0..4 + IDENT_PAT@0..4 + NAME@0..4 + IDENT@0..4 "name" + "#]], + ); + + check( + untyped_param( + range_pat( + Some(path_pat(ext::ident_path("start"))), + Some(path_pat(ext::ident_path("end"))), + ) + .into(), + ), + expect![[r#" + PARAM@0..10 + RANGE_PAT@0..10 + IDENT_PAT@0..5 + NAME@0..5 + IDENT@0..5 "start" + DOT2@5..7 ".." + IDENT_PAT@7..10 + NAME@7..10 + IDENT@7..10 "end" + "#]], + ); + } +} From f4496bf9b653faff16f271c09105ed620792b920 Mon Sep 17 00:00:00 2001 From: Sergio Giro Date: Sun, 16 Nov 2025 17:49:10 +0000 Subject: [PATCH 0088/3801] Fix suggestions in while_let_on_iterator for non-sized traits --- .../src/loops/while_let_on_iterator.rs | 29 +++++++++++++---- tests/ui/while_let_on_iterator.fixed | 31 +++++++++++++++++++ tests/ui/while_let_on_iterator.rs | 31 +++++++++++++++++++ tests/ui/while_let_on_iterator.stderr | 16 ++++++++-- 4 files changed, 99 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs index 2545f81f1afa..c063e9263ba0 100644 --- a/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/clippy_lints/src/loops/while_let_on_iterator.rs @@ -12,6 +12,7 @@ use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_hir::{Closure, Expr, ExprKind, HirId, LetStmt, Mutability, UnOp}; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter::OnlyBodies; +use rustc_middle::ty; use rustc_middle::ty::adjustment::Adjust; use rustc_span::Symbol; use rustc_span::symbol::sym; @@ -43,26 +44,26 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { }; // If the iterator is a field or the iterator is accessed after the loop is complete it needs to be - // borrowed mutably. TODO: If the struct can be partially moved from and the struct isn't used + // passed by reference. TODO: If the struct can be partially moved from and the struct isn't used // afterwards a mutable borrow of a field isn't necessary. - let by_ref = if cx.typeck_results().expr_ty(iter_expr).ref_mutability() == Some(Mutability::Mut) + let iterator = snippet_with_applicability(cx, iter_expr.span, "_", &mut applicability); + let iterator_by_ref = if cx.typeck_results().expr_ty(iter_expr).ref_mutability() == Some(Mutability::Mut) || !iter_expr_struct.can_move || !iter_expr_struct.fields.is_empty() || needs_mutable_borrow(cx, &iter_expr_struct, expr) { - ".by_ref()" + make_iterator_snippet(cx, iter_expr, iterator) } else { - "" + iterator.to_string() }; - let iterator = snippet_with_applicability(cx, iter_expr.span, "_", &mut applicability); span_lint_and_sugg( cx, WHILE_LET_ON_ITERATOR, expr.span.with_hi(let_expr.span.hi()), "this loop could be written as a `for` loop", "try", - format!("{loop_label}for {loop_var} in {iterator}{by_ref}"), + format!("{loop_label}for {loop_var} in {iterator_by_ref}"), applicability, ); } @@ -355,3 +356,19 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: & .is_break() } } + +/// Constructs the transformed iterator expression for the suggestion. +/// Returns `iterator.by_ref()` unless the iterator type is a reference to an unsized type, +/// in which case it returns `&mut *iterator`. +fn make_iterator_snippet<'tcx>(cx: &LateContext<'tcx>, iter_expr: &Expr<'tcx>, iterator: impl Into) -> String { + let iterator = iterator.into(); + let ty = cx.typeck_results().expr_ty(iter_expr); + + if let ty::Ref(_, inner_ty, _) = ty.kind() + && !inner_ty.is_sized(cx.tcx, cx.typing_env()) + { + return format!("&mut *{iterator}"); + } + + format!("{iterator}.by_ref()") +} diff --git a/tests/ui/while_let_on_iterator.fixed b/tests/ui/while_let_on_iterator.fixed index f9ccefab5898..4e03e954108e 100644 --- a/tests/ui/while_let_on_iterator.fixed +++ b/tests/ui/while_let_on_iterator.fixed @@ -492,6 +492,37 @@ fn issue13123() { } } +fn issue16089() { + trait CertainTrait: Iterator { + fn iter_over_self(&mut self) { + let mut a = 0; + for r in &mut *self { + //~^ while_let_on_iterator + a = r; + } + self.use_after_iter() + } + + fn use_after_iter(&mut self) {} + } +} + +fn issue16089_sized_trait_not_reborrowed() { + trait CertainTrait: Iterator + Sized { + fn iter_over_self(&mut self) { + let mut a = 0; + // Check that the suggestion is just "self", since the trait is sized. + for r in self.by_ref() { + //~^ while_let_on_iterator + a = r; + } + self.use_after_iter() + } + + fn use_after_iter(&mut self) {} + } +} + fn main() { let mut it = 0..20; for _ in it { diff --git a/tests/ui/while_let_on_iterator.rs b/tests/ui/while_let_on_iterator.rs index f957f2e5a523..cc65fda6d18f 100644 --- a/tests/ui/while_let_on_iterator.rs +++ b/tests/ui/while_let_on_iterator.rs @@ -492,6 +492,37 @@ fn issue13123() { } } +fn issue16089() { + trait CertainTrait: Iterator { + fn iter_over_self(&mut self) { + let mut a = 0; + while let Some(r) = self.next() { + //~^ while_let_on_iterator + a = r; + } + self.use_after_iter() + } + + fn use_after_iter(&mut self) {} + } +} + +fn issue16089_sized_trait_not_reborrowed() { + trait CertainTrait: Iterator + Sized { + fn iter_over_self(&mut self) { + let mut a = 0; + // Check that the suggestion is just "self", since the trait is sized. + while let Some(r) = self.next() { + //~^ while_let_on_iterator + a = r; + } + self.use_after_iter() + } + + fn use_after_iter(&mut self) {} + } +} + fn main() { let mut it = 0..20; while let Some(..) = it.next() { diff --git a/tests/ui/while_let_on_iterator.stderr b/tests/ui/while_let_on_iterator.stderr index 50f20227b90f..21ebc22f699d 100644 --- a/tests/ui/while_let_on_iterator.stderr +++ b/tests/ui/while_let_on_iterator.stderr @@ -164,10 +164,22 @@ LL | 'label: while let Some(n) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'label: for n in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:497:5 + --> tests/ui/while_let_on_iterator.rs:499:13 + | +LL | while let Some(r) = self.next() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for r in &mut *self` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:515:13 + | +LL | while let Some(r) = self.next() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for r in self.by_ref()` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:528:5 | LL | while let Some(..) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it` -error: aborting due to 28 previous errors +error: aborting due to 30 previous errors From 726b7360cf771cabbdbe44feac96b59aafd1fa32 Mon Sep 17 00:00:00 2001 From: srosefield-riverside Date: Mon, 17 Nov 2025 09:31:02 -0500 Subject: [PATCH 0089/3801] Only allocate the minimal alignment requested for a type when possible. (#1604) * Only allocate the minimal alignment requested for a type when possible. * Code review: make an assertion a debug assert. Adjust an out-of-date comment. --- src/common.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/common.rs b/src/common.rs index 38676eaac3d5..758d89c92b75 100644 --- a/src/common.rs +++ b/src/common.rs @@ -377,26 +377,26 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { size.is_multiple_of(align), "size must be a multiple of alignment (size={size}, align={align})" ); + debug_assert!(align.is_power_of_two(), "alignment must be a power of two (align={align})"); let abi_align = if self.tcx.sess.target.arch == Arch::S390x { 8 } else { 16 }; + // Cranelift can only guarantee alignment up to the ABI alignment provided by the target. + // If the requested alignment is less than the abi_align it can be used directly. if align <= abi_align { let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, - // FIXME Don't force the size to a multiple of bytes once Cranelift gets - // a way to specify stack slot alignment. - size: size.div_ceil(abi_align) * abi_align, - align_shift: 4, + size, + // The maximum value of ilog2 is 31 which will always fit in a u8. + align_shift: align.ilog2().try_into().unwrap(), }); Pointer::stack_slot(stack_slot) } else { - // Alignment is too big to handle using the above hack. Dynamically realign a stack slot + // Alignment is larger than the ABI alignment guaranteed. Dynamically realign a stack slot // instead. This wastes some space for the realignment. let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, - // FIXME Don't force the size to a multiple of bytes once Cranelift gets - // a way to specify stack slot alignment. - size: (size + align) / abi_align * abi_align, - align_shift: 4, + size: size + align, + align_shift: abi_align.ilog2().try_into().unwrap(), }); let base_ptr = self.bcx.ins().stack_addr(self.pointer_type, stack_slot, 0); let misalign_offset = self.bcx.ins().band_imm(base_ptr, i64::from(align - 1)); From 201734496e4d76a77ef6ba8ae28017c232096550 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 17 Nov 2025 19:00:14 +0000 Subject: [PATCH 0090/3801] Remove usage of function const promotion in the build system --- build_system/abi_cafe.rs | 2 +- build_system/build_backend.rs | 2 +- build_system/build_sysroot.rs | 2 +- build_system/tests.rs | 8 ++++---- build_system/utils.rs | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build_system/abi_cafe.rs b/build_system/abi_cafe.rs index 5a393a217c27..762b2be8f440 100644 --- a/build_system/abi_cafe.rs +++ b/build_system/abi_cafe.rs @@ -11,7 +11,7 @@ static ABI_CAFE_REPO: GitRepo = GitRepo::github( "abi-cafe", ); -static ABI_CAFE: CargoProject = CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe_target"); +static ABI_CAFE: CargoProject = CargoProject::new(ABI_CAFE_REPO.source_dir(), "abi_cafe_target"); pub(crate) fn run( sysroot_kind: SysrootKind, diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs index b9fa0ff2d94c..ad6743a6d659 100644 --- a/build_system/build_backend.rs +++ b/build_system/build_backend.rs @@ -6,7 +6,7 @@ use crate::rustc_info::get_file_name; use crate::shared_utils::{rustflags_from_env, rustflags_to_cmd_env}; use crate::utils::{CargoProject, Compiler, LogGroup}; -static CG_CLIF: CargoProject = CargoProject::new(&RelPath::source("."), "cg_clif"); +static CG_CLIF: CargoProject = CargoProject::new(RelPath::source("."), "cg_clif"); pub(crate) fn build_backend( dirs: &Dirs, diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 70504ee8007d..804d50e25d0d 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -140,7 +140,7 @@ impl SysrootTarget { static STDLIB_SRC: RelPath = RelPath::build("stdlib"); static STANDARD_LIBRARY: CargoProject = - CargoProject::new(&RelPath::build("stdlib/library/sysroot"), "stdlib_target"); + CargoProject::new(RelPath::build("stdlib/library/sysroot"), "stdlib_target"); fn build_sysroot_for_triple( dirs: &Dirs, diff --git a/build_system/tests.rs b/build_system/tests.rs index dd8cf929bc2f..3b6a2e7a055c 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -129,7 +129,7 @@ pub(crate) static RAND_REPO: GitRepo = GitRepo::github( "rand", ); -static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand_target"); +static RAND: CargoProject = CargoProject::new(RAND_REPO.source_dir(), "rand_target"); pub(crate) static REGEX_REPO: GitRepo = GitRepo::github( "rust-lang", @@ -139,15 +139,15 @@ pub(crate) static REGEX_REPO: GitRepo = GitRepo::github( "regex", ); -static REGEX: CargoProject = CargoProject::new(®EX_REPO.source_dir(), "regex_target"); +static REGEX: CargoProject = CargoProject::new(REGEX_REPO.source_dir(), "regex_target"); static PORTABLE_SIMD_SRC: RelPath = RelPath::build("portable-simd"); -static PORTABLE_SIMD: CargoProject = CargoProject::new(&PORTABLE_SIMD_SRC, "portable-simd_target"); +static PORTABLE_SIMD: CargoProject = CargoProject::new(PORTABLE_SIMD_SRC, "portable-simd_target"); static SYSROOT_TESTS_SRC: RelPath = RelPath::build("sysroot_tests"); -static SYSROOT_TESTS: CargoProject = CargoProject::new(&SYSROOT_TESTS_SRC, "sysroot_tests_target"); +static SYSROOT_TESTS: CargoProject = CargoProject::new(SYSROOT_TESTS_SRC, "sysroot_tests_target"); const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ TestCase::custom("test.rust-random/rand", &|runner| { diff --git a/build_system/utils.rs b/build_system/utils.rs index 3266aa0ce8b6..5c7cefa120a7 100644 --- a/build_system/utils.rs +++ b/build_system/utils.rs @@ -75,12 +75,12 @@ impl Compiler { } pub(crate) struct CargoProject { - source: &'static RelPath, + source: RelPath, target: &'static str, } impl CargoProject { - pub(crate) const fn new(path: &'static RelPath, target: &'static str) -> CargoProject { + pub(crate) const fn new(path: RelPath, target: &'static str) -> CargoProject { CargoProject { source: path, target } } From 94ff1de61ea096eab6f7937c8850deb59201d3cd Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 25 Oct 2025 04:15:43 +0000 Subject: [PATCH 0091/3801] Replace OffsetOf by an actual sum. --- src/base.rs | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/base.rs b/src/base.rs index 3bd2e4ea7343..e445f9457477 100644 --- a/src/base.rs +++ b/src/base.rs @@ -853,31 +853,14 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: fx.bcx.ins().nop(); } } - Rvalue::NullaryOp(ref null_op, ty) => { + Rvalue::NullaryOp(ref null_op) => { assert!(lval.layout().ty.is_sized(fx.tcx, fx.typing_env())); - let layout = fx.layout_of(fx.monomorphize(ty)); let val = match null_op { - NullOp::OffsetOf(fields) => fx - .tcx - .offset_of_subfield( - ty::TypingEnv::fully_monomorphized(), - layout, - fields.iter(), - ) - .bytes(), - NullOp::RuntimeChecks(kind) => { - let val = kind.value(fx.tcx.sess); - let val = CValue::by_val( - fx.bcx.ins().iconst(types::I8, i64::from(val)), - fx.layout_of(fx.tcx.types.bool), - ); - lval.write_cvalue(fx, val); - return; - } + NullOp::RuntimeChecks(kind) => kind.value(fx.tcx.sess), }; let val = CValue::by_val( - fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(val).unwrap()), - fx.layout_of(fx.tcx.types.usize), + fx.bcx.ins().iconst(types::I8, i64::from(val)), + fx.layout_of(fx.tcx.types.bool), ); lval.write_cvalue(fx, val); } From 63ca8047bc8717763db6188b3621b72383616519 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Tue, 18 Nov 2025 03:04:20 -0600 Subject: [PATCH 0092/3801] add debuginfo subsection --- src/doc/rustc-dev-guide/src/SUMMARY.md | 13 +- .../src/debuginfo/CodeView.pdf | Bin 0 -> 214354 bytes .../src/debuginfo/debugger-internals.md | 14 + .../src/debuginfo/debugger-visualizers.md | 62 ++ .../src/debuginfo/gdb-internals.md | 4 + .../src/debuginfo/gdb-visualizers.md | 9 + .../rustc-dev-guide/src/debuginfo/intro.md | 114 +++ .../src/debuginfo/lldb-internals.md | 205 ++++++ .../src/debuginfo/lldb-visualizers.md | 662 ++++++++++++++++++ .../src/debuginfo/llvm-codegen.md | 12 + .../src/debuginfo/natvis-visualizers.md | 3 + .../src/debuginfo/rust-codegen.md | 183 +++++ .../rustc-dev-guide/src/debuginfo/testing.md | 8 + 13 files changed, 1288 insertions(+), 1 deletion(-) create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/CodeView.pdf create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/intro.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/testing.md diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 249140956c09..bec587f0eec9 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -228,11 +228,22 @@ - [Debugging LLVM](./backend/debugging.md) - [Backend Agnostic Codegen](./backend/backend-agnostic.md) - [Implicit caller location](./backend/implicit-caller-location.md) +- [Debug Info](./debuginfo/intro.md) + - [Rust Codegen](./debuginfo/rust-codegen.md) + - [LLVM Codegen](./debuginfo/llvm-codegen.md) + - [Debugger Interanls](./debuginfo/debugger-internals.md) + - [LLDB Internals](./debuginfo/lldb-internals.md) + - [GDB Internals](./debuginfo/gdb-internals.md) + - [Debugger Visualizers](./debuginfo/debugger-visualizers.md) + - [LLDB - Python Providers](./debuginfo/lldb-visualizers.md) + - [GDB - Python Providers](./debuginfo/gdb-visualizers.md) + - [CDB - Natvis](./debuginfo/natvis-visualizers.md) + - [Testing](./debuginfo/testing.md) + - [(Lecture Notes) Debugging support in the Rust compiler](./debugging-support-in-rustc.md) - [Libraries and metadata](./backend/libs-and-metadata.md) - [Profile-guided optimization](./profile-guided-optimization.md) - [LLVM source-based code coverage](./llvm-coverage-instrumentation.md) - [Sanitizers support](./sanitizers.md) -- [Debugging support in the Rust compiler](./debugging-support-in-rustc.md) --- diff --git a/src/doc/rustc-dev-guide/src/debuginfo/CodeView.pdf b/src/doc/rustc-dev-guide/src/debuginfo/CodeView.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f899d25178458c24bf49cb9ab086761fbdc86f08 GIT binary patch literal 214354 zcmY!laBiE*l$OE`6WWy!4U`1w$iqUM_vN%$$Q;3rC#J9|$=pa>95+2*=5%PmKaR*s}`w%|bl%pFO=~dcoMhAdth8&9i07=c3FX zX=>t6#h)*qs=*TeOzr7&4V7n0HCjT%mS|NxTl!S|soJ!ZXU{X+Qa%>#WXfgZFko2u zPVOErS884g%q6LLDPT_+qxdGEC_gzkwL~FWKfuLJK|dt5qC_DUH?3CGhX_m*kOfR2hC*!nA#ZM@mj`*go zyl>7@y$epa%U0}OwkAu1Eo$8xKHE3K+jYOaO!@3n`)Q*JpWKPli>58$_2M+zK0`CY z(1dB1Ro|@kr59XX6aM-yedD{e?7J=J*}w_65|-t=rWRlLzU%dIJ&R4z%i5iyg%&Uxaz%N&N%&7?R@OqBaVD;j;*MO5;?nbfreL_@R)D(tkfoxkQT%Wv-o z?=8NcIQxIm|CspJ8CP~ZWB%wY)8gUPYFYS;Bljz7uie@Jtyg!&PwRAsXUx*O{)|n{ zWv_$i&**HECgl$oTN1p!T;03!{p77xo{Ohv?PdJYa;|D(~`awUN* zEyu z!*APvudLj@KF)Q&&Az#d%wH;^Y_KhyVTF{v3e>zCW^o;r7?m35(ZiHpV4w7Z*Q^i*Vx3bi)P<_wnGUMT;L zODP~?F1IcU_#HhrqmV3#Hb6O@5kiu_8hK^^&co+h#caW1lDEt>q^jZGJ~>#oLD$zIN4Y z(tEb6`?h=Fer@^ouDLrt&z!aT*rZ-b_Lm2ag8OJRki!#w&?P$2R4))oz}&4wg08j?U2mO4v}dOboAR+ zbc;opXcx)*mR^{_8L@BWqdl847RpcRb~a8)bWSsQH~AxSfSd6$ZeuIC!9UC!6M z;;-iCo0XE~1#{-r%H4b@c))n=BcZedCVG?Ae{Wf$udfj$tEZi3<0G`;Ueop#w$j~N zll=dyM|iov4*qs?TeSC4mC54HOY0Td&g8Sp>K4rRDLKKUP<>+3rW+#NTsALqcE>DJ z-IAx#XBnaT`H)Im?~l%a-wN;ke3WQ)_>}l9dRE8_Kl3&6kGARx7%&tTe(T$MJjL~` z@kYMjJ9f+8pMF|4_u18FMqT$9E*h7v_cpmK`-+*z=6q;z;iJB*O#s@cjFfO^oSFd4)=0DyZA3W;=vkTGKiZ#4hlKp@ig5== zyOD*@hK9sje8Q{5H6HyISaI9^#G=rc)cwm%TeUA}Wu(k`eD=#D)52Nbx*awIvvf#K zc-PIsw$Hp!w0xr8^5++rZQV;|e5v@77kWk}WNzi|9HztZ^S2z?s#XMH)2}e!F#H!Ddcpbp>!f*$epgIer?+K!7qjhFX;s_Ld+NGAr*_?|^PIf)<2?QYHx33z z{Q4x4?9{C&+h)5veQ{;-;-~9+)zV)4)YM+Bdu7)#KlhJ3%dQ-k__XoaEQ5dFYrpa; z%4IxrGyWcO-GTq7k?n~cl4%#_8p@msm}@ur*6eU)wOL$!Go{Qg*4%J0uBsAV>*izf zROWKQ5tqw~!e?I`wXG;^>0HLFw##+boG@XTi&-x^I?HmNn_N7|D6DI(W39I9s(g~# zOq=oyw;O8?6mGc|!5$gwh`{wfX zZ@64?!Y@9ocQM;3`&GxjzAZUj!dbTKc*zOB%Z%2wfp@pMmt63>%v^Ts;oK{J?-OM* zm%sFWW3u@E4ZrKZCpwqSvddq7H+24Gzw74ych5#^KHi#r@5_l7D}5eY+I(NsGd*+r zS^-DD@FQ#iYnlqDY?iU03qsakJ|`{gbWs z%cAd>`_0WSRHmG;EeW6UddIB=FQ1#76pIv^?X<@D{d1l9;`KRqE}oJ*%e1DYD7ZO) z{e;3iy%keAiaBl4%w;NP{``8Iqpoq`x(EA8CKrZ4#nDVF$6U# z5zPi7S}yQrs=gcHMvT6jrGlXuq;Ugkvy#xPHN@JkH8L_YAg)1kWqNe+?H!VB?`m-QcJG$-Ci@>LUB3Apt7;=(bmx@`A)DW=f6p#p<0VA10j&+^}np!VA%B|E-q3Fm3;z z=p@1Q?AP;y*H3p}bhbHv$)=afq&E8OB~`A;tX%i5an*V(GKp?=oul^n!Tc)!`|n;R zpE@(`S)-7AwcVsCNsp#SA5uG%V|20q%9}60I}*kF)z`VZJq@#L;=OS8^X02&<1aqm z)e-)&{?yxlf`3>~*!ZaIk!ZO$tNhZZx%>M+G@hT)Wt)9W_+9^ue|t5|C*IHxJj48S zLvOPRqe#@^6W=QL_MDJ+5%^@}<{xPl-tD{WLb~WmAJyVizOJG(EW%+sEScW#J*9r{ z|8}?klNgtVGx}+n3P=6R=D+NUU>80v=Qhh@~OL5LVS&6yUi_Ro{cIjNre6dtkr&6{fZ*p+oSxvt8i&{=k z^t&l@ca?@;(p=|^RdJ?jRg!E`2^8Y-{=Jz-r?Kio;>DE zZoheK%9k~g{w&wq{oL+dSSY-HuEIG#WyNJ5W_46~h!={iUbAYqj9q#_`R${pvbEL+ zZjY@@UHwTYxN`m_3r(HLM?_wIjZ}F1XUpmIsd(C6dZG=q^G|R&9A(}xJ9Wl$E&JcquOGeLX}-Pr`HO1pO=tHoJP#A9y7BZ~ z=AT>hOn2vmJvNxlowHx{!r%HSvxN_vt6P-_y?8h2tXJyUfTCrb>TSa7qBZt@(<%JM zsM*Fmsr*8X!{&XD>L#Cgoy|O5+xF%B2^$z!@gyu=>1&d?Xv14$omh^N^MzqKhf;gn zn+n);6Mw13Xct`U`z(8Q^0nyQdmcQmy{xHd9D7K9y}Z4UwBMcQ%WdA=H9h-rcd3o! z#J_tz?Jx2@+T*lDY@*edm{$iF76;yp=i3#&gJIumgZ}5T{s*|5Te9X@I_J--kD)wA9)ma9*0TWt1 z_wjIVUC}1yZk7JfyzHP>Ve{XvSD9}TH|sq5`ib}MG3}{O0xl=!<#gcn;*Kw zXzCeJ3w2Zf@YfZb+eP-QUAwg1`Igwn=XZmO-Q$Yg_gdV|5I%N6FF@+;;sS%3*|Nrq zt0LBP`*&VH1+T8uTJ5p1JMB>^V`O)HgSNmU4nfI6H&> zqDOoGglzF;PT70GUTJAc=ii`Bl?!CxLtX-%D=RvO3<9 zB<5V}ZhqR}{OWn$8{GF!{<`|wtk?}+w?FKCd974d{OR4N_W$;ldUsqAixrK(6c%x7 z=jWIYQbuVf*Bp>NeJ<;?-mPhK1^wNhfBVz8?^wd4{7WkOPA_=&uf4A2eEp?bWJ7)W zpA9EY&2JVnd~&|mQG8kG=3@(H=a=d&4?Dl>)!*_J|7X;(epS42U(9_SyWlPMMOP_XW%Me%w}mwnAx!*#?n+xAGGd-3_L1ZJcU-UAd?C@0vrZyZDMjw=LM5>+r~d zIqQ7Wp&!?8OQ_vqvOONT@nxdOjpzF;^pg4erW#%;Y%yFbKk2B!gyz`mwrOr(FGTP< zzjKf{Ts6Jn^SMJzSwg==)=km0JO8j~v6lpAq({GSBX3)9;*GoIvzA7SN3M@eam@_b z9Km?xuiDIPox1{0%|pKY|7iTp-Qj^0({`mB@snE%=L&cSENl{qRn7d!%2oGaTUY?s zv&?NP&fQnlvpw|l`@DTOt215+9!t8{=E~uhV;US8y1j!x?9rFf)y&V#mYzQG`h4kM zm)(I&d!KD-P?=dCaQ60sMlbhyrwYFvh_wB?{Ti?1db119ZmG2C&vD*vc_gEiFWmgC zjs40!4EvKey$W+J6q?Di?xtNLE+ z_Qn2QT>CwF(JjxiZOp4|3>H|G8l1{A(EHW&(Xgv1^u@i`|19^0cb92h+<#{`M^+h2 zkgU&xqzgy14Yy_O4wdUql<9Ds>%UUw?(&;jIz=Y2t1D%We!j%(n%VYGOuhR{c3iH~ zTeX-izoj>ZpKCQRzti#2OE+b=6Km$KmV5k}Qmw^HqrEqA7)wOQxgBhOdHTklXL=1v zt#M!D4V%gj4SqCTWw=oVY0dEJyca^Wp&>2m&M*aKMHgOTrWR;%Bng;!sWsKJ&z_Ot4$Q+3hrAr`!sh` z*oWr*z8X=v5BY=-T`0-3pZ{;i9*(@pmGg2pr#7nT&yL*Y7P!md^7P{pcbA;jx$ojS zY3bsZ^>3FXnra?(nKF5owwH*Sf##l#7ksVqp8XW-xH#hz!(nYfqaVjFtDT!{`Af+C z{^PeV>@V++kCRxla-090x*{RXul7gne@X{d{gMz^V6mdHI{4h`!V@y>yBExf;1M-C zQ@XRvL2>Ss2X+eQ+XRa2ohGMDJ;q(~Rp4n}qSG1C@VLFo=F3mX&$h4c+1sf4eAyzI z>c-@*nF))cQaJADN#>qV{uzlr<5ezx7Rq3}e#ttqk~o^_+{idgUY?I+l-_{%nwehdDs*eyNT{`Z8plXbnj?OmEb zOW$}gdvR~cg`>}|e$8{w>QCA4UMY0;+Q$mn<*Oet`gYl@oaNScFzlzaf*eDn+{1IT zpNguUlCw~4oi}4TyWe`Ax-|c_AG}!j-+ihO)ECbFSzfuxv+GH9&oce~kJs#{Coiph zA=o(KQZVOR9oa)GA1z?qx8y0$wU2WO${jsBd^=PGBTfXB%ZhG4VDOi}y;0M~M^Y#z z{im8%z&4ltM{isF=hM(-Q2NQ&U?J)7XQH7%?}esLuACU(-0u=wBOkMFXmh)6a^_No z*c*4oTF-5*ck_}jZk?5D_@=+V(0|&uK(rf7YuqJdbEgtT54@edptm$FIci?$s%5Ie681iu-4!bGD028F~|c z2%Ng~u>E&S+zUbV|GI4lNe7m8;s3LA9w|p$us_w9U>dS$S<$DylGl0> zAv>$8CyRZ|;?JEC8vZ5Zu5#TYPIdmsxR7N|zCU)Yd&KLSu=3Tr&8rsQSTs>;t<)7+ z)Ax#cW&4Wj%{K5qWz_aK#a|zj7svw{>rL zY1+!HO3sOUE@+l`ZldqpBhSj8>`pO$BD?8lTKA@NzL^G7OElJA3p82(>C2_Eskw63 zKYq^swZFW!t=BBA-0|?WCZ~<16^Xs!e_wFi->&uYT(j4Fucw#a{#nU)s%&b`?~HZr zEgKbmj5}Jgh1M=w{Y2JqVt?eezQrZ&?um*=5By1f-fe4jTakN$S3sp}=OGuRG>&T* z9P(DNnFL7W6iv-}yYfr%uPvRQS9okHc`l+*{>#eCUv=4*a-KJ}M;(oLjF%?ecCtM9 zu1UzEvaLfi^ZuNBRwj8bSDHJvg44~7V}-pum1eJ+Yp=do|MQQc=A+7wQ=B^lZpZi{1{bQE!@?4u6H&m7|AGUV+Y}CKd_Sk0@tD~zkUeA^D zacXVOZsz~s)c^eHwvQ>D<>g<``_DhGotIdDr{<7v979I21Do>A11EOfoO8h}`lbP! zuWy~+qmpcGqo}l<+WEWIoc)ul!0%zjZGJUiMrHlOw0#Bl(_E*ezvei|tLVPU%(Ut6 zq*ZT^_Z*vaP?1&7^Q!zW&)k+3zH0WS*%3Zx59xNN9ejKCF3VPdV^byyyKMNMeI`R^ z#nrP+w=S0iWLSAzE?IGR+2L=#+BY(>t^9pu(eD0lX1k`eN0=N4y}e3N z;t1Ppp@Rn;%r@urE-HDrtEOb`)7dKuD$8b{`J6Lbm)qk&#lH}j&81r+X1tKf{NQHB$!AVR zZ_fG7y;Rt3YY}$nuI<@tC;#-ku#3@VS+{M=&SS6c-QM?hzRo_@%RH~TbvOJpnsq!Q z$YE{gr`EIUUYD#F4nKiq#iF?fh504FL8vXkE)9N=CuYDDG zEG@&>Yev1rp-e&^qLjSE|@&-!Q1&{1~90BZ}z2sGV=XfhBn z07cVLCnK!WXclHf&Zb_Oemn27fkeZ5?XR*mGZl{h5ID{!BtD1DnMYCTAnQ{l-#J24 z)Iwu!eEare$}-vL<(|7wSY;Lmo&RU||6gsz+_UND&nGoFhMi59a8zNqWWP=&XhzY2 z$1F))o6gp>9f-PKzyCnO+AqQ`9Sv&?-fuqrQ)kDD?tQ_rTba9GpIw#haBrHz?t5MZ z_rhZLpDZuE-gYzpa{8;^PYhJIc}E`zF+as{{Ky}}Shmv)v5Gz~j99$h?)wvITDoxd z_OnX@jx@cjKX>n3`oxEV)1JFCy#LuUvEq%@vKcLcqK;Dk&e&xs^ou8YBnd@(96q7* zSV7F%&^+l>7N^Dz0pW|gV$Uky3+e8^G9$S9>Xp}JJd(Z{Mv~iaH>EM=&r)?y>*SA$ zugMZG`n%+8-*V;qvtvu1&Uf=OKEFfMdHLrz7Ac21YgdKW-n$;;YntZAYp;^FGPwGF z$?83lLT7azYI-eyXx1gDZ}wnroZ}~FJP#D#Z*YZX?F+7rXle zH|H$Byrv*YJpNvUB46oM%^!dMU%Gkp-nr&^eNivP-FNOgvHkMhRsCn*-B|T=;>wL+e91wsoCr=~4mU&X$C3yW%nR@VQS zGh;TJ2Sgw6cz<6r!SL$txx2qOwdm$QsnzGTYUgR<-}#HR?B}Y9-&U>ORrg%pdu7+Y zd$YLLb16Ih_}e3KH%`4LX;tUf>vtH7XILdf9|%b{JfP7!C+a~)Pxt-#x*H>J99%!K zLUP6H-rBmKLD~9;#S>eO{$0TTf5yW!X4_r4>YEzYpV~CtOP24k(TT68ZB+^lvbVbzG)@unAYIZtRL$OLgE@lH76a9+yKLI3&YS2GVrywBz| z-hV7=e?7+HM&g}iI?Pu2PopE<&ub?I;(|Nmq z5bq?XiA=M%9RK}w<*QX{E4$O1w=#B$+`L zzwVI56i1y)8WXidRv&)bt6#R^fxNeB8QZ%h@7a?=AG}}v{I>M_;>az%ncL<@?320X ztNN)*IZWSO*Y4WwWwuXZZ(iAa^?gOg1HPxi#uIg)D2c9I|AE`T`pc9#XQy@H33opSn{A;v?ea_g>v+l5|<*ujBQ(H!^~^JdKjR_;#zp<25_k=Uz|UD||Mr z=b_&=w{m9oE5)|*w`eP6br;m)U{F`iowJpP}@+v#MtPexgRbxkN^#FC>=(iy*r z`rdt-y4L*B&Ntsub$2~?EBU#L$@$@)3zyqBz5ddccTN9GuilMrt@Y)#`yTI3zAbWV z#xm90VfS|*S!^1cY@2^=|LaAMo%xE34t=B0(nvh32n^rvo54n4Tbc=*$l?MrKy zUi!N3w)3p6Wp^ba_H8O#apv~4wJ%>xD%(8$sm{kUN5niXA6j-&`_n3?;=Kb5% z8CGt+=P*N|^jv04_T6O-TA~~Kx7@!{#=PzDI_EOWXZiQm)K%|T9KfgM$A9*^?|s1= zH$B3c8mcO1oh$JOH3^xUXSihH^v~b7UAfBEzoE{!LhZnDpBuiRYNE#`2U*H5G+=D_ zYCEw`Ankh4ydxsN^Z2jEUX%VC%5!4B#m#rD>l{x_`l8Yup|2O9x5WPAr;nU2B8x(2 zKC7RXQai_bM`Zfph$jB5S8IyS-MV|y>iaFp(>ts-ot*kD^t4N+*z&{HeL}M8z5=;A zODtzBzq-6F^ySu9#ruNavNjxe`G}EUP@J(zLBFB-_o*Om1Bqh`v|igYyxyU>@8cb% zlUL1}o|q>n?)?(2nl8F_|Eopm#~P!x;`ay{uWFhmHznkYWs1?415KMsTN(cx)0ltl zK)?s#I02SbkyYn1PlhCw@4EI@d!66iE$7vq-4@>A^6}!~^Y86z|7=jv*1f9a`1owV zKjp(4*e~CSdfoqbmlpT;ipASgW263;#G2IJb*wO3XRw^-2iF3p>33ZZRPH!_OKjPn z^=5O3VcAJt9&d}Z~=<_-3mNqc0slsZh|)#|7gVZS)_QJB`8gf6~KcPbhr5@e2) zm)`rD8&{b4*>AZ3*Meq++n-n6xtj5^e1~Tx!`GTik5)u;H}8^Yd2oNrY6-D~z0+A$ zZVIRggfUopmpr)~_1-}L+pd*!536qoY?jqwWYN!vJhlANlnzcefj05NENO9@!;)qF zmH%eR_lb6N883Pn9dRS`*8ZAFKi)a3* z&`i+}@JM)`abnJ+4UaWU+0LY0wR~l@ewTPOcj)B&4M%T3iM6YUFrVQbIA8rb>vuk- zgz)+ntCfdz6sO<2yZp}dw$2{$!UuC^PdYH&ple5OS?n7Br6z7lMSVIl0vnokY~=_( z`9}O#_m4FUw%LI!ViyIQ9gSKh{N4X;&g!Geg)c4yJ5Ae}C}k^bQA=lG4y=LJ{VtJQc}sc0r|-RI`VCy{vO(&vSiGL2`V*i6kXi6`@~ zjHtTixa&$w=Bb50K7QW&^=Egs$j4_Fa(iVaO4RR>QquMDy%|VBE zM!kel-7U6Za#^@YOGc^cwBVfsau*dRaV4q79IFo^|Q%y48(2{@loVGkwjmc?&{X z`wSBOC)6G>ntEbKozcU>BWoJJ?aWXpXTK0~=updii_3aaD_B&L6$3AEZuWZm=+w+= zJ?(ckcYa@Ac;ag7S*Z(ZUe*rp=FFH-pynuWAa+~24)14PmQAj+`zt@T&pq97k9k?S z=qXmO$@(v}qEEPLHHkEEG+2K)B3QV!X|9ljQqNxhvwWL^JD1)|ER|HR@-q|BIh_$- zy>!9pL%ok3^qh8o+*JHNCLA$3U*_Sv_V~t+ zclQSQG1ks{`ltA)$&+*UXT81l;++py^2~)N;$B+RK3y{5&1AoM7c*D!S`@LD>mtP(Z*Nv?|8O@Jv3(8;T+3@y^{JUo@QZj7r zlh|gyUiVOW(!b2rHC(ZUjT0m|emMo&NIB)yvp&AN@oGht-^cnL%`-%|opLCNomzqB{HF&2u>XNdgi_uutZz=hXt-Hldyt%9Gq)=pbz@c+y+J?>q{ zelC&RlzlQWgJ*?jYQpnB-1<-NfBz|b-FdC=bCs(LCajT;YWZ(-cGBi5$&+aCSIq9!-yS)mMCD`dYp@RTIkziKtBie5DPylO=!(@&$U zN6HzoyjyvMFCqrImd5ic=YU4|s$cdT;sDG@Da%6R$n% z?nu4Kng0)JY!ghaT=IPVmV+Vrb9ldPJEHWzO?d8u2SEuJ1Jadev`-6cuvmYs=Zd4P z>_oX#gB-p99?9pc*``RQuPd7^9;IWwK_TCq?a|&}JN_6o3#?9IblADv(?Q4oR(Xz5 z9jjU1yt79+W}Y;WTRp?6G&Lf4BhRG+FB_M?dAwWHMqu~t**cR8HIgJGodsJb`Y17$ z&SJY@bLU>p#`IZxrh0OG`61>psrvQbS2h}oC5?_c3mhi@@VUJ=K4F8?`zc@8v;WC3 zO!x4Pz}^@}T{l5QhnmC{9fpPqMxbd2($}aOW1k){F(Yz~>YVW0;>X8$|Gks^-#)iS zbLvEiefw*C^vaIEJ-T=0)F;k&Pp&yJ^@!Zj(49|y&WVp_*j+RA=;x9=zqm;^SU)gS zH2lr1uKs+u_CUXI_4%@!Rw*VAube%pJPPvQS{_35%AHaGho zZ_I6bzg>U3`89plFmKiGywz2xQjEdAHQ`CO4}xBYjVJMrSn+lg=3 za+3e$)n9ww_ABPL=gSxMk+&BoXzOp#`nWZ5=?^6@weLQupJGDT!!*9#-M7{#n{)aWrOlOF`gO%~(d@oGiIVGY_#JpY>xkAusfo9H)|#zLx4jg+zIrQT_?NQ1 z&$eFRt_W>ZSX;jS*l#noZn~pN=xpG#Y=b3h?V6vv7RMMzX3Nja zs<><5YWR|e$tGSh>#WyG2gMgmnnim*YZn@$4ELZd2qMo>GA7V8PzNH5y*ELE@ zko*{UVG=pBKb3$^}IwBgzxB8fB3RyZFZn34^zR4pPe6V z*0%;_be1vlFjjkPYtCTUbU4ZWS6{UD%>(Pi5=`e!PMUmLLrbei^pNqAiL+msTsrME zGyE7=wEdy=@0-#upPziAOps|})Ew61DN}PlA9_7!YiRHkTI-Yu`Kk!&;G-riKRb$O;(`PTU*fmKs_I}fXvbU7v+32U~$WmhMpBmVqZhDK6U zbjODy64CZbb`!ro=9&;G7`0>Nt5+K}{f^FeiT%avHcf0nVOE8IRAWBR`J?M>WnA`} zUC?~XDrRZyY3sX9`M=Y#U)S~tq^|oi%k1K*CkyK){N5|nJMrfAPggu=E0;YA2nmg6 zJ$Ao-Y+sd85yt&Wz)o zq52?E{!rgF&5rCWK>pU}&TB_J4_~yK|E=-M&pd(m zTPn%~-0yiGn7T6NLFO}lO=?&nr;QTkIGIBk|D@AGWcyhV~ld7Kpw+@u=# z_t*aVc=&!KcS(TB`X_u%8$QZf7X=@=^;x*Qui@V6zD>FpdDQ$|o4*_q{T+No=ur9_ zjmpxDpN8?iEr8+HzM~lC<7&(2AGi-3;n0(+@M9BPy z8E;?7`q=7eOZeGz&i$qHCC1ugW->eH?F;$3dHLV&@Ap>Nx_E;yN9^tXXF`Gxg!E(? znGDh;8Sita-EU@@oc*vNpX*DUMVX8=y2IMJff>pi=|*0lDZcWLW0BrYB9m+RbBI(>(Da-(MD z>!O?>19RJ+7i+U`>{5UIvopNPVUEDXSth>G(wDMI58B^zeHq($;(Dr?x)yitp)RK2 z|BY>XL{44!Fk?QqX@$X;lGqaq?S8&>+V*QBOWCZv`{l;9Vm>?%{%7PEeOR&aUhHk1 z#rN}9sa)>Ro6qrY-_hp*yeCWb?vPGrhghx|8tO$M8c4md>djcEq)d`*kzxj#vJb+duzcu;7 zH2FZj)x(>066KnCLef4OswzSkl~o_!U|(Cvn|x&7ii|tUzWC?Jr%%&1DO{0SeQb`| z$;f@LzMT0jc|(A6ei);w<&`a(rXP9x-tnJI;Y;g2+^MlHZT`ClnujZ8C+un$Z(6L~ z-0<_3@MczXxem4(S-lC#r#qapm3;n**afnOWr7v=?fUZ-TRh@B{S$l=@O_CQNg z?`A?z$%p=#>mM-s?J{_@%VYhsT_=A3xZo{&yFXoctE>5>a>3*qv6~g9mPT-;MyM=L z*jL{WZ9MDPwfwKHOZ;tb_^t>%@H+E$+Wl1r0^9VaKk78UDVXhWzGFq!8KxPhT#rf{ zdin3Vtz(vTzcE7h=`z8H6K7kMOY)=|SMS`J!Yui6=}Ou1NYNu^E!BFA-;R3kt@CX7 zW5UE;rx%&1vQGP=heYFQ51kb+RMxHfv8-X8{d#Tt`+l~ubz8iGj4t@*Twng`@S!4` z;)SdsZ?39+t$n@GwsY5s8}0}9JFL36woKzx_oB8+(Z14y`sEr~v5WaKyl#ABJ^x>J zy{huNqg)lNZp&tcaLL(+e{y~4^L%x$bkrK7X;YfszYJ>eiCJT|F!bU1A3Lrd3cR;uS85RxN7`y>ih}GIU$dtKfG=i zyL0;m=k`mFxb>qqPdRL!8fUutL{;Peq9nPV-?waXIV+-=R5)CZ+THvA@yBcZ^8YnI z4$RYip8d$;+~+Qt3k7_95_U<)rW|+_dAW$$mtEC%LhrXDEgD8@GrCulG3!`fX?lFL zyXT_ z9U66JT6M2sFgwTC)M+%=a0hdS^rVxUQcX2@ML4VlTB!4Zgl-^jazX^O~*W>Kl`f znLS=2?Eg=e;cfHx!?kzr<}u&)oV#WBy;tx4ykS4MX0G~#RKF{oymRZd7v7Uga9H=< zM)=K2#*j*04*Tfa?aQBEy>Q_Mqo3y+0gpL)b&MOqTY8{?Le0#`{ml7_ZhhN?tY84C2CCa)DDR)QN-F}eK!hPrC6tY3@y!x zTxi@Aemn2Bn*eCI_69riQm$-oz4w*HHJW#h6$%JyGOgCo$WqN!oT%k_vvA)&FCdy&x_0x_5NH{xBs$}BT~lY&gaN&miEOr zh4lVdeY~-$QT^Snrc~B{^Y+e}Z^^%E#p-2ITXH__ni-lsZF=#vy?Ls;^~FQ?o{SEi zy7*0gh}N2*`OBTOmj+MzWReyrRBWy~H#tOj(k%7kj~V5AgYAm~a+r&rubOc7#rZep zB2s%FcB(r~l2V+Hu>|9g5z0{ zAz$|->T8Ftd621?9VxcycWm#mjlqxXeWc$Ul{wPYc;~{Y*7%c4%2aP2b^Z4B^4pfJ zKXY_%rd{8XbKS!zM~6ZEp?c1nLj9w!-2xI=RVQxzU>U#KQhRmLpV(`n*%vLBK78EM zdu(38yH&Gt%QtV;if}eC`N4GH+{03quzuGE7hJ6l=Kl1RU)}oe{@-VZ%Q+3zej-@QwJoT&F*0pnrKb=fXKKS>@>za*)MSG9@FbeE=eZqULZ`{61 z3zya$xO`>hQ>mb}F`Kp}t==7Xq?ga+3gZOb6@M%-@RKuPk~F`zII=|gTw_#j_Oxz zCl%hzZ4b<_ahaWU^Te;nbCOs14hyjGWvA@!|FLaa@y-C%nzVVn>9t#=*3FfOKKgs# zjW6{@>uzwYTO+D+Z^lZ1P@MwZiGF z!-~(Hr?P|3mS_JAzI-)Od3r`k`tz*o5zZmbv&2@h^#pubTK8Czxog#&_(?lk>Vjt` zOs#pa^4q7!8)sfC)cPoS>UTPO+lrXaffJ{vUUgbEEtjuB?{n_riPP5H$xYkTHs$&M z?l|WPiA$?ryf9U%`Z~9}`{ecZ@BQ*>OKvI^Uw)h+apr{Bw4`Q>2Zvs3goSq&*W8~m z^WTgO%?3{#vzAug@_7)bvNo9?lkZy~&nQn%nX8_S!SqP66RdAH1_W$*ryY zbt{ibWx!$iV-=J1{ z|7jx6+NZif<-zAeayCz8UB)i9j8*b{vE^;umseDc?HKI2f}c*l9es9$H`jCcOD1I<-)4Fxc%i4mvkM%hwHwbRp1Aw0WVR@yNytR08^`vZ zZrStiiNK9@oz-d{Zvz)hv?*F+*uB1^Ld5l>+&;g1vjR-sztFya#KA!+$^4#om-_SM zeG}g^^edF;e#+n4RbZfOYkB=@8k>rzC_j@;##fJ9=PRup%I=8s--&qc+q`ShmEyd- z`^`qqFZT8xuDi)Ac(-H{qiezv)BKAoZ(S{!v3J|7tbTP~4tqmg70a^u0=xR7rd94< ztr@HNU2J{H$H;5ENo$|ZVRPD{=InROuF;R{n_Pdyq0el_(>xV?)*sH)dZ@(tSorXi z&_7$uePuWN`I~g&jlSsR18=_GI%hhgZ3q7a`LAEC!I6jhNeD{wq7E)<_k;X*NF9^CKvw}Y^=-MzwX(m z?n(MR94Vah{bYY{JimWprQ3-TmkU1?9m?nIkiAnKm-YQ&|8hl(Gb}wHxGv?YrJjt- z+Ojw0R`m783(0}6*?%j0EoAno*<{DtRGMILdCM||s`J*@?vz_S(Cf*yx*F=(l4Q)b zy>->mnJ)faZ6@q`^JkS^GpCzS#t#5D5T6-&8 zpmjo{qQOSn)m+QO9vMl7%<>kAK?^l@qL3z2KL7Rc-TvoOA7A_T?SPS#yGPB23B2EpLXySx_nwvbH0v+#liIw-BSvRisBnLusr+m<(FBrcuwbk4YpVYOx#Xf@pE!t^wBhr1?R*s8`!)nGy7}Jpl_j&hP|ai z@&q#3EfqUEUM>=LK^bG6OExq$CUQk>OZe%$+ZG~s*-zLPOl*xgvc_ZYZtq7+PWapw zNnY5jG?z8^q8Ychk&4yI=dYiCQjOeXT*}Zo>BMh~?|0hsKA-OX&abGX5g!{TApcwQ z)5G&?F7c#udL5FO%<%N-)7JiL8~#6@v!Il_{Kj|9Q`28n{;R5dSSxmVS>EfZE}xxu zuGroY%6f|5x=(I(=-nwkUAtyIv7hSqsw8N!z`M*PSB}o?*WCDOO2PYAS^xfietUVj z<*biWR~(r*%uO;k@JkgtR_S7ju^QZf!9^3L~uAxR5+r%qUTOMRw zzjCzhBsVKx`e|ORhjphXmc>?{by<3}oiB24*p!RhXQdanw^{HuF)aEm#-g=sg)Q%d zKH~r-&&5w(R9uoZKX^6D{7viYzn2vb8J_ej=Ls;e}kEAi7wS{`$Zp}klVHTbn6NR69#5JVWHss>mA~1mGVuQ^E(QXPTvZ9 z*=hXh?7Mu&i8n1vw*{W)nbEhm=|SqT%{7NFdYPcy6 zwy=$xKDC;!?W(iw+%xsF-GM?6|7IyG&e(a{oR5F8vZc>Tu1dUln!8wA?edM)SB}o| zOp-bN(eR;BaAg%op-c0Z4Cc22OY#+8Z2D37^h$$vv%#E}pt6Ni)_+x))b_&UaO0|~ zO8>}O#7Yf-&8!j;Nubh#B73n zRene3qtB8bF0WaA=uXAoTN(~ptqKL71-HLXY-6-zI$Hp76J~>$MBcO_K{fx|VHK!RJHVlVxV= z#l@EO6y?M$-LpGCKL6c6muk&zPI3;@4srV2H2vdx<@Yt$SoPkMw|$5jljwdqx;t60+|D0U6HS5WR!X3MsB%jo+GyQIv&BnFu#;0#FkFUwf zZY(`)DR(yX--4-?<^KHt?XCW%d1U?UGrh1oVPnYqsMntN-DDTOVH174-8wsbpQ3os z?CM=-mDb!WH@)tDKWjbTr`e0u?3QZ!?%i*peIakX z4LxJEo1W>sA*Uo%H%gy7;HZ#wk}qIyz|Q+#8=DPJ@M-gLwDL_^QT0(+ZimQ*$cVGp?emm-QU7?=JjvpJ-q%c+;f}P%1LXTWzV+JIs12J|T~0h>hq>bqC1h+kXz zUS4SS8Ag#GXU?&4H9Py0X1 z3+q0U+h^JNYl4c0!i1@hG#mn(5)benY>*J*Wb@&A`r}j5*K>6xw_+DqSlwb>d+F`2 zv&RK4njAE7a%>9Kn%3O){j8Zu)8BK;{(W@2^Md;T%Y{c=dvX?ZZWHd?*#`0dkaS-w`*XYB%%G&ZYp@_HUE ztN%N%m?2<_%dK3aWJjg~z56?BcihzxfB&9I?Z&bQy_VB=TXuekU;pRA^SBd_6doN) zpIx=H;HI43pAQN*_BH3FqgT@`WdNzUh@32*jk zhD4{=uAFuC8Gp#D$fa({hbB!~ZrB~$D8GdF3A@Vw^5c(JZxu*Jk<1Y^_`Vw?|c4V+Eq%@2>)YLO{{Me}ezUi?-Qf2w`{tK5Zz7KE+BY?_H*0@t?#x{6 zlUg_5{B~z(`m%Ys(7pvNd%tzPyinuc_R}UM`-d=hz|X>+9XsWZiSg%8ZJYPm@9+k( zJ752_99+)-|Aon{EdT7at4k$ZRtB5xtchFOY``@~X3m2-{Yn}dJc&;dc{DQ=u1G7D z@9VdIK2cOIQPizT{m`BN%h_4nK8W(B&1dm>TW!Pn_Akq+XHm_TjzY`)D)Nr}4c{a4 zEj{PM9SQTeo%!F=-!G4N`>bxthbOn3iknn?=5r1m*@XXOgZx_@%!^X23r@ucUL?$5A5`wpz>p<7FOM}F`Pa#?D!n{!~bF) z?X7$;EuvqbSlB{|O{hxcnBRi{{{-W!=h7?AxH7ODS}OVC&ywT1J_)vk`7>(ng&yCN z^Ub8}tc9Le+cS-a!@_g&#zdqIP-wK`<3iNfZXlX;hn^(Jha z9NPQp=DUe5ykGK{zjBTgR8QY}Dz!DUS-L&!ZS<1~y0xkdzt`M79k)K4qvWQ?y8Q>^ z?VXyfi?`$$++J#y`8jXS+znhz$wAuRQ?H+%reM%__rmmK_1mR-+!rQpmit_J_Z&27pLc3*7RE-({_C7sd$m4rppvO^c6DHlGH*PeEc1F z_#4CIR^_li3*OPospiliZhPd|3ZA1k0xBoYJ3l|CtMF&f&xlx+6;|8+J{IMA?4mkb z^SkH9w_>;COmCRZ)PCk$`Tr-Qio>z53EwtOeP4R-l$g)O)Sw5C)7Jd`!uOX!qgL~& zaB%y+HK+G$+)mfJ(c32T)ot#}Df6~$kwQ-w_}sx`q1mQ`9f1dkFIz# zn5_>LBL~{2rWtO>S8{3@DDOfE$ti^ix87EI_bZO3~HMJWX zcOU+u^6`UG;m4WJ<81C0aNNpqXg>c+ICsyRe#^aH)>r0Q?X8rJdMU2QqrffkZrd-F z$pQPbdKmU4_lvyWEVV(BrEG6c)h17q=tH*@F8|^$SpU*{PvNvQPpdD-+72-=IDI-T z_USUm+I|6RPF5Dy!V_^{5&|R7@d>T_qJKlNbox0_MgF@2>bxSc?SH?1X!7$_ue5oP z(CiiVJ!-=H13Ifhv*+j(?uu3KZG9FV+0a_>)iHcqnB#bv-Pq}@*sQk^!gcYrQPMJRf7wx>! zn(ZuZWy&d2Uw<-8vF7fMC=xiSv6I>7#^zmy_h%$pl==BSpJ!gM zuQ{iXWx`_j)hBjU%z9?R!Jm=Gx0h{G!W2ETnEke=o@EJ0ylDT%Z=|4Y{Xxu0b^hjE zIVX4@Gu_>@vno5rBw|O`wah+1fQB zKaRxhS87bRm)<;UjaknEnPvX3V_Xk>K1)t46lamuret=V8HA|Z4 zpTx!GfDJCiXC)duh=1Dbvm1x?}eed;)0Dae%wgacR=X_yk%6%g& ztg+FMCwRizLd~AgH zt%xY8?(>qHYu)Bt-~KR_?eMz#m1lmRK2RC@TlvGfhl*LOTfGI{qJ1^}jniXOv?oq5 z`XM2DTPz}3xAb&dlB*Sy$ttT;im#8IS{tY?*PU=_LQ~J3xbBxdUHN9T_eY=&C#*LVG!8J+Ji9dpCH_2YzIAQ5*t&0I0_U}8C!F~RG zZPPZ^nqb3a8XZ60A3XnB`>A5*r!^&AtyyH0+pjZllM60Uh{ zm?=CtjPaqhX@$k*gIcOecRJh^l$wH+^)6X-Mg%s`5bqG4%%R~NT)I5zUeQ`R#{2c6 zf4H3+W(#iJxb{c<@_zo+NB346U-C)Pyqr_-QO1*7_Hdg+Ye)U(_z#WCt(CM2H#9cQ zY+1;3j7j4BT>U=>zB056Evm?wEuwn*V!wg^p|5?R3J2pCG&o7W2YJF z8nPHBZqYcr#pa`mz;NU;kDqj( zes^Q`Jx3+BtD^gPiWLqXvZ=CEUC0}LZHj8)bYnmFauIQrjrUS7elLG9AziS$-?F;B zPVMPw>nTrH)L1UNfB(dVNs_WV${gaPZD@J5R?3krATgOVw;}5@n`RWIsLJroRbZs*Bc=Y;k#ZSpO9QS2U z2gn`zBKovfxV^`vy<6b)%Lh9TPTu~+s4VB{HcylEr-uH4XSy`}`H~LsKB+l2*>m1I zqYrlM<=pah7Z0xAEY>-FyHj=j>nn@2v#_-+yI}tjv6t&=5F*xiLb=l}S7 z>5a-)j%RFp=Jz&lJYdkd@=m(o4PCy|8@La8N6RlU`Vk{%q7nLRcTVlY6#tGTvvxam ztX|IPZeXyYpfu+Fq!lw&nI)pco%4kwD*J;E9^SOoiqY~#fTG)r0zJ3c-A4>^cb|M( z?@%zkPgA|3;QN+85z}46ne1Zq=S-JfXSinD`tSXh`%C?GQV+F%pWV6T@t4a=J07!_ zYP5agO#3tY`J8PXk3H9_oGy6qSKN3D_w_ex_`e=33-G;LFDI9NHFDA6*J;0mmPNPS z&=-?!UHXloj5A#~xNaYB*yAqir&U#cpFVN;PWZg`iGEQDhvL#>zdp1{OpAIw)kCQD z|@HaN{7^}6TG_Dbs`OXjXvb#uw_vY~nyCiJ$x#aSziWR2MGheN==jB;p zuUISF{A;O}pVRDBZykM6x%u76nda<5mXj^)f42+055C-fZ_XC6-D*emB9huQm>&7N z)a~1sdDo%v_JarKijNyloV@JeuA>LN&mEHZ>0sXyd7!mCOk8cQ<@1O_`yhDI zv76@?-8{Xf>guHuQR^F-Woxrke=mAjm9M%vH0RMfudw`lN431|3x4v(L_4G>O0`$U zEYSDb@L~TQ4hi#yxqP`l<2jjhqD@UwB33O^l;xPQVN2rGMG5m?ukMwwiT)|VVrJ!k zFzLFDDd(@&McbAJF=tN8lG+q>_1y}a&3hhfRnVF?r;eXNwM%9l_Sy|}(ivj>g8H=^ z`6DZ+V?MCT&CHnimACn~%>@3*Dg1Age`)sUh4s5_ht~Ittd08N`e??&n=$|Ezy1BgbAS5hWqGet+vVzW=Djuzy2^C6 zZjacDby3&Ox|OEJ`li*tc8;vqP`BLNK5My-`c9WjHP1P-jg@P8%#YU`?J+RwEYkb% zzEm{#RcqAl&9_d@-+ceToXxDyB9nAFdknH}HY+CbJXDwYFMZswcGiN-y_LGxS$D;* zp89wi8`GuPDVBmi6O1-0D)bZ!x2>=E7PKwn5KCUJ#Fxi=?&WL?wG591%4#; zHi#L-iaeVozA9LJ+NC#h<+GVtq8k&S|!Qm z+=s{Um;Jx;AK}7dPs?A&H^t1OJo(6;{{aB)wJUQf0 zriPl*Wp?8$BG1!Lm$w(`cJgFQ*gRv2<%!@)LCgPdX7FOMEp3`C&7551wrR}nwWLB^p z&!+`-?|v(I6iGZ~Osth~EYRYxpP1cjbD%LeI1Zxyt90^nW`3nA`948O+p`O&w_Bv# zd0gNmcjbF=<(!4{&n9yy`h927wLe-oq224B?|}=Y4-S2r$Ea##o2Q-FvY9dY0H5Kd zn+|?YJI_6P{a@!mnI3n8f5mbZ!2^jR7r)QjFyCn7-;XR#6)uPW>Pm24-@j&GPrvao z=Z03pBNytMbY@P-|8em)$Ipi+-T%I*o^jQ`UpnNOWuc1PF8>Mh-|2t!l&_Xn+zm@6V5|7-L|E9XI=^*Ff9WTOKr6neJAM3fl zqE`3W(@*Y^Yx|x>G+hwidhbv{{MEV4(~dGND>q*Kdh?kT=XT7Cf5@?C&Gpy6c5mCN zcbjkJGKTrL7X1v<(JQa0-%_4Ep>9#$iR;-sJ_jcS)r6NCOi3>kdw;Bec|m)_7ls3T z3~x9N@(cXoP~;Ohk3=&mW6EnlNia+N@K`Pd=93W1ivsi$kyYw6GCxn{wN7 zvwLRKExYG=zcB4)by=hvH9ukgmkFXfMXq&796Hre&wFU~xrcfI8?&drjo@y+IDgkV zDgWL**cG<$2Tti^LwI(lMdr%CGR78SKPcO&6#OF zt@6YfZc#POwD|B^)3dLtdP|PyOv{Q}aNIAH`>IaVmzMPMet+Q|d9$3tlsV42mFiY) zdB0$1ZRyL~{}-qZApEknJgRP20%h$GCi zL6Z~@rdVUIN-a_LP*cAuC4ar3DQX`UT9+Cbm=ifAKP5c3c*zdIfA6&Zv)5k9(bW-J zKiU80>6_*IZpEz2(fXb^*DF!LSfyc^z~X4lAb=~SRmb&H(i1M-xsZ$yKYMyb$lWuzx3?e-uAKu|4$1$S~L2udmcFD*{9m7 zU3(AKum9A?9rx|U%e9pcO;6ooTAI(^CUYBbeRK`+CaT{Th$uiaNZvU1~9W zrkxzWaeJYY7stQ3sdt~nzs%om{*t{l&a-n8+mCx0>I=yEMxbjulD2eOMiM!WjIJQ_npYZhm*|ImbOJ4Md9NnK5TX@Q< zjZgOcOo2Vl=Pf?QO_p%{pvY>=;%(f8BNzRojok~O^;i>{+a5qNB3XM_X(H& z-Z{{4%6!E=QPw%{B!dipEKaUeZ7|h(ozt$>$nrYy{KBYJLSGk5`}{26>Kf*t(zE_f zd;k3TeVO^!ZKnkVmTuF+1Kis$)|IcBSs>{3{ejCb%Z4RuA{H((ow{k8*2{+nw>s$O z3r*j$`i}K~3x&D~CyRV5g_B<0?u-?>@YXVaQDr@I^7QmWIUmox60c8uyY9aAfrV@0 z7+1Wo?sQPDpM2UXyWBm}KA2ZR{GEu*t_cnL;?k_AHjBx=(rIrF7nzze{pznjp>Gq) z4g^f~KBzxqg;f}jW72u+7m7YlV!s|@Ic3Jz`9a~`_sITll1ru=I`4J3 zdaScR`@i%SYi8~)_PBsQ?#K79oF(+ZhdJif@zhtT8x3Wz1 z&NZ`~&q`%fyn3=ayp~-zG2rP^Cc(Z53zzMD)&1v&@&vvcA)eV4?40W__&A+pDf=!U zBCXuH!g1N#T^YE2=-~LO+%NZKo0IJvtqqHkHm9rUEX@&CbK3Ug>Du&V!949(CGt17 zWokIf$%`m4KIOYP#92@3z@U;i*Vd$T?GV8o-n z5+xr>pDla(_sJ^PS)V7EZ=J;YfJZV^|5nppzSHycr+;+V#df01z=b~`aPrgY2Yt_u z`>xp1@sHPz=Ub%I=T}klTbqnq>*_A0%YXfI<7COT{0>vmIp^{$j2EY-Z%hi=z1Tr* zR(!XT`K?*&wU^H3_;H!H_4MRFjr?r?HYnCf9PV#o>AlhHr!T#U|Nl9uf8lGi1>b4O zef@BGzx?~U$_lUdatj~T=pU+o`|uW9wtm;g85J7G6b^1`cw#nz=fl?H);oL-rArW_6F>rfJ*(rvvK08T2=|gAz)@eFFPyIWvYN^Hqq=!kuxyjp6~;U+hR!d=tYz4vt}DlDAJ&LHFd zd7F@mc>6#0Bgw&COQ&Tw)NxLZ~s>`DP@Wry0Q07 zw40-2M3BU-OID|U?4EeZjHm1Bwe524N0!a}p>_4N)Tu+0j@_6Q7I^7|$Q9Av1BW)= z`WIF?<6GJ{_J^(;+*wl-920Z=R!h`6?LU0^MntONsqlyyZ01*{Y`>CJyL-hnlQy=k zeL_i+zpk53=`EFOuIX*hD{?lQbo#P!){7FIj2>StIm0uKQmoQX)^OJP%S0{QckOZ5 zU-dHPi0r29NAn->eSbNxfn}-c93#u03jF`RaJlif+J${@+j24dluNAU*|~vnarSrJ zk2$1_w(!ibDCD|NuIs)z#FN*R%!E(JahJHzw7c|E`Q1U;<($`*Ybm^b_ zm^bFYS?RgoLicS?Kb#*~8}hjGg(c5isd?p%Y9=w?7OZTKiufXXx=JF%IAY!osS=hm zwwe+5!*|>EFtYZDWbG4VpBBC$a7AYE7sqXvKAjgkZ|QNG$0{Y(zQD?T?c75G%Y04? zvc~V4yG%yH;Y-IU|6{*eKNi+W>qZ62-90_i&w0X*RDop~t2NIn8B|XHID4k)#j}<@ z>7lC+8fj0yHQyzdcX`8ydH!kY&%~{dx~oVy`|E_iR}$9Keo}O1%l6PDqx7U1i|1)4 zq-|op&Z{3`%O*Up&vbX#{p4-7XTy8L@2|`jo~57FQp_i-y*j*O+a0SXr$aVPW$(VT z`~2+nvc1LkexJMj`0B^7RE}#eZtzXb@QZkpw=&BtYvKxTwl4`@An4fuTlNv z5M+CQ|NA%6TPKx;r7z%2cxiI}%(>g=>^_%O)_%P%FMQ}kQE~0j3?FW%hxLDbmnc2c zJULk>tx2c+diaz(&4>KC-QKbP&|WrW@>8#W`)YRW>#EBPt2Hl~JyB;~dHLOGA#Z2t z%$LvpwC`@o-*r;6*Ui=augw4STfjR1mi?7d(=AVWNfj^a>)z+`MS5vS&CH3j*U27R zCEHuo_9LhFiH@JwTjPqES^CMdQcqnzfAP~oNssvTyXt%&+^$=3J>`wZc6s^l%8@e< zvxy!&n={XSN#6I}yTTQD3>7z9KEC+->=Mh_pH+-ry{f+Y%HRF{*EjK}=cjIarjxex z%d5Lnc7I%$$N9(EZRYxAvDfb(*zbFn|I#jzhT!C@TYRh6*K~%eDV(u+oTB&0B)!vU z#xd65k9B<(^UoTGxz$YTHmWjB);ayqxzaHG5-;QbO!H+)b$#1PtL^O^T3lzjb=Tkj z^Q&-U&F4bR!wZ#u&HhqgCa&YX_pWT}wG3UY^$BH!R6OnQ=a@YO)&h+KYr3RJGn>Y8`DI8$eKXhiE!<9>zZk?<9S=Kxo}*|OeaSD%iiV}ZaF-*IPteI<=t0LoBUbL z6Sg02-q6hQ{nEKjr#W)`ZWwQ{kl9(!6T`A6^v!(39Ticj+d88IHIHc1PkUm8D4H!I!Vb!$hu$GJ6I z_~Z7x@ThW%W?rZ!^~>?&)1S&8zCM#)!yNSWPe93I&z(}q?~YAAaP0H#fbXA8XXIq> zb={lu)pOySm2ua)$BpMDO=aJEtGrE zzVZJ0W3~GG-$(EKy=U60O?AzDJaJ!jPWPKl&{<|v7&gI)Bf{}ngSC!4gW%DdY)XD+ z0uzndq)+6(Px$FE>5iU!)x!madf8=(4=PS+W6dpC7?g| z0gLW+whN($UmX7Ypz@rlQ}hR=B2$q<`5u|C3oke>`qes{Wq!;=`^EgxM{f$J3*Ktt zKNu|5bMTa*yu}`mg%WFIuKUlCD0&!a%HtIML6IfqtI`GTu)d!P6+8OE`d)Ew@4J`k zv195Nr7oLgs&$K9CVDcyTRd^G_%o#g_aa|R3Tnxy;z-OnkgHjHx=s1{zSiUO9=xj8 zcer28>+xA4@#QgA`2+W&Y)<`2TGqq+meo%3f{jStj7`rNSt33tE}Pw5r78H(Vhyhj zpZmMs!}sch-5<@iztelTc}AZ8tECTK74j)azE+PZ&MjY9@yV2lC7wYYLBSlZ#wWO6-Z#Abx4!s{$r(e{(^FmgcDTG# zdMe^7`244c>E(2ZPcxZ*#`J{RPjZd@y1IS(M?XgM*>XZF@3!Sfx=r(+bXiya)xx${ zYj)M~#%x*dxwUrHJa*AT%U-r$e8(krdCL-}TQl5JuCM)m`c57at;LF2T&EGcs$(l1E{_MZSle;XK@BHPHT9$QPZSIFB+zRi_=9*>vaGh6o zB4ztcp06D8tCXLGy*0_6X?URP$PWFv6Ysq|v}*mbQfrR=_e%qQ=l)$A85(W0#%hOO zz^_0(eYNn%&Zd)&w?B7u+ID_PRZYtW_RD5mF}r6bOB%c1ew%KadU(#Bx2sGu%dXbe zzTmMCcqjhFefK0TtF^tJ%l>h{yA?G}xa`cvmB$tbyJr4&nYQpB8}HgK7S_5fg*l67 z%&9ZcT{`Q)w9vZi?z7&lShg=c;VVmv@n_rJsK< zH#h&U@O$G;v&WlXb>5W=x>csUbG7H*Y`4lOj`^#<)$vOz_t$P;)xPlc*CmZ7rx}*k zeo{Ics=Q>A`5f5^7ngJh{m_wo)0D<(bNl~{x3*cY)6E?d1XXjIx{tn{U4QS7EYrCN zMPZfMLjNWO1t;X*x%sz(&p)lR*hbmia^959HU~aBF}OZtQuir(cAxiZTKX5)#&>nc zn#3n+K5PD6FyVLYi5{$VgU%QLKi;G1H*G@6PMy1$Ry+2lTz@wwSx??(Uni0z5bQE`R8q^eJGT?9Ts( zVpx32&AKO>Z28?PaExusUB-tqxo371zxPY=EBLx!e8Ky@Y!06lch4_8$i88_Sbvc4 z9d3?H=juj(HWU75&$4UpyO}6XVSOK#ny>dtbwb)sV^+aiY+}b%+#hY&9{)O>vBBs8 zqffc`*T4Ydm&_d7Gd~z_(0KFr`mcL?&nZn|)jt$xf9Ld_V)U+z5KfC z-2dFm>7JG+``qJ5OwfVDY11TxI8;JYLf+|4H&Z!r;bPxXjh_i-iw^{yE|P2BeVlcx zcP?A{9j4u_T6^!7tzNGmofWw%&ZTDM-kW93ckU-F-ss)uw`%j_Edp&i_m#gm?rrnQ z<}aDB{-poycYIkNGha!6{@tGU^xvAp_Uo3u3|stx{f$JJWK_z^D*yDN*!(MpE^Xa) z>VTx`+j*y7L@dfl-NajZYR5Zii_TN`|ET-v37x6kseqi*fD3vhTlWXA ztMWNryu&Yj_IZ|u&wCkeD_68E)pOuD$RD>Tx8s>Z`OIr=(?8c#&t|as%CyXBv7F!D zGS0@U7iAic76|-)UE-<7=_)t<*TKMe6BEs(bAEDj&R^X0dfSs)>uZ0PMXfBnw{CTv z?SaYLYxe&zn(deqIn(9I@pbn@mG_kWQj8CMb#vPJ-}1h@-_2wD{p9JlLfuC;t!o0T z|6XNQpY-I5sdw_c;@@2EONCZ%^m(^_J=f9Ymt~e&dAbOtuS)o-IQxpDsNo({_7DTj z|FbtvG}QRhxHi`~xMIZ&#~4YrHHQ>?g_w6_Gk9ga|Bk&IfVwye9&p7w};$2(U_ zFA*|h=v4{0&MndO_l=HRciR;SK|86q`p3MPDj(A3Kb^yn7Br>uZ26v?&AKO7-`#iP z)2>3!owEYj6nFd-tV`TCIelqOfZ)^VJbRek?bcUp+x4sZypC?eG4M?w!JhBT*0+_|8B<@uh+fJYHj#`BR!S*i@A&1@+-cP zMm!>~9Xi)Dt+n#I#dYryBlqcbH`Z0LaXHVbxZMzZZ2rX?tP9>OIhL>^dDF6$pOmt9 zRbU{`+Y3EUacbjyCH>YnM~azQ4lOu$y8CN)^6m|1E}XnE^SPVm4Po;| zS%1%4Irv{#$#bfY@z|R)zD|4XT8b4nRVK6q_FI%jS~NP|&Xo`fU6NaCq>^~%+>yd% z*N*R#W-;UMF?e?H&;?($3X?K!HnC%qWh8c&)*3xf=)3!4M(Sh5Y>AH_{#I-d_bXrg z-hHx-^zPivb4v|=+m=lZQC`6G@?_h#>Jt(dI+*(}&l4(>x?TM$;qQ5?g!3Bg6@|-n z6J;0<&1k;&@tfA;%|0h3xLUWaeq*C@*y!;AU%yvxY%^?LC6?_KRc&Tg{IcBEplxek zW9=5ctCqX^N=`XWDSVZ%ZLR3ymvf5cuEnk_idZdiCttJiFU=O)pu|{-A2vj022M8$E8tE#LY4Nb(6GT{%_DNZL?fk>q3gq}wQdgv=T7^tqWme&o#x*tZ_mZtX{K-obIli(4=@xh$?5{cV zt$NfQ1QUN;@;MqMW@}rE(wXqzOYQ;THft856-?7r_#=UW{Nvk>D6q& zTA0ek$EV@jcZ|ai z0M{84TFQ8CMZ2WGlef@F8MbkNPRi|{gEzH}Xdy5LuNLZWUGpN*eCi~Yf*wd#is{+eHUpf8-S%yG5C4c50IQ$I#7OW|ofRHb&K z(xWZak0VMn(dmNUf{>=NOU%g;uMNt)Wmml~l?`)TeR>1eEzTaVb$(SY%w}uVo40aZ z{aGuj{(Skz3#oG|cy66YHBmJr{r8sV3j&wg=&YLbB=lyQYv-v_mzn%uZUs~}p0Jskt`*Y!YX7ab56x$8 zsMM_S{un=hk@)&r!DShr_TI=lDU@XQ=}$bzIqnQSkTMzjus> z_2Xn7iK(8R`Dj5@%&*h>-TUR%J!e_Ebs^uBnzbw|I$z8QVb#&$d!P_u%z40P^CR62 zm)kE0s(kf&Xm+=5zpl@r;BO5*-!{Hl_UOQ#h10p;^qNjPQsXfBQQdLHlU$kt-n+JG zm>(~Z_Yu}Vxv6xqO{(Vq-o&Cc7a_o->RZjW>6);C9_uWXr68kVD&qg-cX@wF#u zSK6|&KNt5DE38+)<*fLV`RN~?9}(jA4Lr9y7OrTEt5o{U({{^oeGl(Cfr9g=r`Fu9 zDzmgsH+=P2#L{Y4nn8N3^J=DD*S{{i%~*Z*^D~`UZ0qW6_SMdl*s{ZCan2_9Gcwxg z9u{UM9CxH8Bg<3uUNo%zvhm=@E5)n6-iWXYK3XfTaf^|wV%0Y#wia>6_wVyQlr%+% zn0>F04J`iZJLBWSci$52jAu*MpIR*{(rl}c`U3Gv|2MJXH$a0w=Pyc|M@?rr7!(cdOPF? zL;9Q_4YF6B23+5@u53oZ+^3JWoW7O(FR_PL=Cja=D7nRj&xvW-tz8>63ct@a%!{g zJ|+L7>FQ42)AM~7$m(#Oo6&lTso_)4(RLR;na+gYKMa->#JKda^G* z^CZ3ekc%1hVoz87x_3hM&nvYs_x17zPQINf?KbyLoq&w&#m?8R_dZm7T>5%Z)93eL zUt~)x)IW=z+v_uDSNxo#Z~vSYZ9CYeDBZE>xZaB$3_3+ z9jZl>8XEOXWKJ5N`N_iMw1MIGodrMZ8MyU*xv{t0P}g1!rk0x-_6>IiW`;z!-16?Y z3Dt@(sDI&p>cf{!`Z<#-Z~YLfxL(GTJtsj?S4^bc_|dzL5RbmpzkkENwifGVO=2)= z4~<>EdRN5rFSCC>J$m0RL+wUQWu;=0T)Ix%|GSgDM5c3kZ++;r@#o>Eu4lqFJeZz+ zFwFMPqe7jVdyahny!>?ci{jX_-1~a$Wq+|67XJCa z(h8mhmlO}>&-`GMs@A_#gpZG53u{N-;veoZ$IG{ezj?bpzwYmmeP2V(qeD*bS}D`k zpWTt-^d+QVZvRE$?X`L>+cfXEeEz*FJvMaP-KK+=m$iRzJ}o1py)I3u^TS)Qngc9~ zwq>T1t)$**e^2P%m~-0qeckTd+s8N6R;;-mdi<{ckJUY_`+j}@BOh^g<^!eUXZK2H zzuq1q=6jj%&AKH1x8)4$rEkb2t-JO%c4OLJ?LPr`)@ql1&+*N#|Nr*+_Wvof7sg#b zY`ncSXhPAsv@UhcWqcNz4!5%IxCGs*Js3aNb^V=X3Emq+B=dX^*5_phI6l0-W_6nB z9cMMA(~DpKzmc$G;b~HO7n5b{HXrBHc*yRP8q>AFqPBlW)BYn3ou@XMJ6%ia zXY@`uaNhOvnSEiacge3>XW#!r=!ei_+08>s_J|b$g_rH2@~Jn3uV(vKjfMw z^u^v_ch$LVbys2Oj5~qela6m(Dlu7gBEzAB-<$R(rS8sTd%(N$ipbA1ew+KR9k82U z|L@cK_3!HoyIUV+vNiwva3#-1`)mrAhg_(Xa$|OQ_6g4KQ`Fb-=csu5SCY|`2rx%#!?|Cn$NU!f$-_^J$RRaEMGYz!m`gb1wKhm{oUW?fx0(~-KP&dWm9ggv;Scv3yWUG*Ki*%N)NyVJ11LVC zuFstOWXH~$?4Xa$%!2k`)_ts$`S|k29F>Oh1q?Ocf3ZB7s3dWFG7|?Mi^Gfif)5Pp zG8~Ndl`nYYKl{8eOVx9|U3)EeSk}pfM%xCMcfWF1c(H#G&$cr!eVA%ouB$v+J2nV5>9Z4=Wc_Gp!o88#DY@7_8ZME6n`GYS*jNV{5}V{{Ge} z8g9H$c^i*3!~RVX>sKGm&OWB%*qLEbcxOiSzqmE#SF^vz=-=J1z;$@`y_ZveY&hq? ztHQU|m{8Go$C$*D?zKL*y4-!;QZ2@v z-@g9+bNjmfhv1bKQR})x`8Ne{2!B2NS&C)Wxkn~ZBF=>>hd<0SaZKNG^O9ulHls7M zGbP>DmFKw4+{?rLaADZ532W50w_9m1y!bIovi}9!t&a+Of;i*OuK4ODxku{Kv!2z0 zvNNv8oZ1lcc)8oU^KZ{iH(Orud1*KEch+^nMSr=UZ8UuI-TSpl=9Oy?k5pZH<9BYR z=Ufv;Q10Bfxu)i1soNGlRsk7~h6~Z>c$QR`>{?i<(eS{5q2*oCGZoui%{_0OnJU=1 z4ty7nT(r>{EVU=W&i{l*?r)BnhyC|_?)by}t10EhwwlJ2kCS8hB01Lfi8$|gH?3|C z*Wyht)EW7W&MiLfTYr9^cT2YfSX9NMD7Pd_we&XU~aTiWHDw`kq=7{-X`ItZ)R?0lvb$_k z!>P}^?yi4YI)!(`Z5#i^?{oKlSm?LuT?NC(vb7tsCp)~Hc6MTo;}qWNU8_O)J(5|z z`Q-`?p>LhPd-;zpe0u6{)|sZyFW*^s`2FH-3Rt&$mCPKamuVli>vB(MT(h$4T}k|b zqOXrWrAGA5O}PHzu<62yeobv`m-aO(I3zL8ILV;=Msls|^+_*u^f%l)$aLUeG4t+- z4ZEMeoxbaK!Jn21_cCAfE4<>{QhcU(=FEcK7FRzWQhj8*Vc~}BamoIsJf9DQ-$;0O zD$rbejtYP4^_K^1{LF5*>ueWa$FnO)XS>IiGX9Qn%q@b=lirJGOk6v)=cwAvtUQuL7x+{)|UlXDw0mt~cEg8YRDM)%QOY z7P^XS7EkTSDXpBCY7^*TT=6wzmUMuyq5t;BR`))hvXJ?Ijk_bce8v0e?u~9!ID<9K zPab4d_$6x>dq()k=^eBG^E2e1s5ipe@G(POC^x7YKE^1^3w=`a(n~TFjLgl5pSjMz zeM0bG-huy#_CY&4j^BN%cd{;Pl6O>majpP&xQJ)r0#&axeQdJ5 z|Fo{^Zn1lZG?G%b9=jjTe?9!5{?lD6Z&%%(czgNb*uCnNTNPI?Pj<{(m3vp_)4DaQ zkG`^h5gaw&s3%hEWKc_t%7@$jw>AW{?Pn?3_@t-!hcxRG(a7t|S4ID+{`&drRU@v; zQzohMTK>7NeatOTdAiQ&lnWxeYi~;J{XW51RdwgSBpa?urzPhmxAF8EUJ|(;emh)W z;IhD<-$!jy4t24zRkL|Kj{LlGhUt8@#4~RIm45+&}SS$&Tol z*optb&is(k3;A$!mtuVL@1k=5S82?QIj5Js-KX~;DJ(WFEOl$}!`jo|mmgv~k|R1p zk8zLj!cYA{e>%FNep$=c@Gd&8(Z#hP%lOeTryllH4&AFhI zUZ=V1ca`(K@Yv5Kes1aWPqt`2nB;M>UDNb=tKh%3J=>Z7e~`QuAjssueA|r)>(pj1 ziZy>4yO1l%CiPmd4AbqSj|G0JNLs20A3iDbXhyubDxxR%!TR;*8(Ax4Vg%wdIzobM)eb&AduGi_z3n>_&(CBC z>SQ!~87S}fd#~dB>r2*L`+b>BdeXilSyEfiv^c-qrt@v~H`B@;`q#fR`)kHuT#}hK zZTd15u`c^b2i$yl+E^|dU7bAdYLejN6OE=)Kbe!bD|bYs+3en$4QhGa zcNwdgzAQCA`)l8uuF~=>g;3X+$=hUt4d0d5T$z?B;uu}`yR$~`o58ty?JdpIzXr}b zY4G^6os{uayL~U*vg`t@b*`z_DE)R`ecSV%2+OX}z2^*P@46J5da~j|+0S3)e>*x? zw=bOi@xhHNualTF+keScFXXU`c(MCvkd%s?$lu%i_Is|G20d>~vslFQmM>;|t7ZDG z)6WC0*Z6N+p4GdX&+?fs-(K$KsEiw>z;iginFU;2qqlt^tk%rRe$1y-N_BF=bU?LaN_PS$)isXKAW(L^>X_G z85s_>#W!W#iqd&}E`jKNJNf4ej#cY36&EO2c&8;xoSbV|Fs(Of#?;+kE9)a1<5O-J z@8#I=z$GPFnos`bjVAAP$0keujeB=7eDTvWky45_>6&f&rgu(iY9E<&_L;?`-THrB z9nM=b?KtoDK#J+Pz%jPx$}P>eEe>a1JD;2U_dRRIyGsn5S3hl>-FL8a!=1R_N zTHms9;o}dVXKxp3+rOnw$TvT)KR_&|V_yB9K&8WHo+sx1`1IoGJR6<%neP>sZQt(x z;{8L1FEUShCv6s4zAMtjsO#|g;(azc{WERS7_53F#XcRMF>{}FvxI#8e*S#1wv&IB zuX3;O5A|2Mr%|o9yW_*hmah*_FP{E8#Y8>KmJcReB#bFtB!SH zWz#lHcd_7@|2|D^walSAQ+0c8vn>0y>IWOY>baYt;j2m?zVqCxg)jne*t&cnG z?9;RCmsUj@y;g4h`f+hoW8JCUf2y~+&r<#2Uisp?Ys`T+bseh}YZmt2sy5Gv&F%Tn z`{B1(|M6W1`FG~NVm^6t;k`NESm!BvPJ*R?zENfudDj}F8|4uslPW>H*qtE%hcb0``X$d>s@lY^{Q1mr@D?O z)f(AP4RHO++9;oSW`6E!Ci(WXz7U=fH=vC#;N3i9EKXdg9WUgy&!Qs@>knehc6;?x?>pn|Vc><>Q6Z zn;G9LWq)~mWcLXvZa@$N&*2xKm z^Uo%#e1Fj$$mev1@jwIffyMt;SSU-JoGbXjqu18>*WNpe*Ng2@Y_|BOT*4LHa>6aN z;D^MMcM?xprA~00PIxTUabn}KQ-z{29Wy?GGGaQ9VQ+e|#7WyC{I;?+A!zM`Ni%(K5v-vqW{vSPp&Qf zAJ_2b%Z0sD-qPK$eRcZkrzxV7MVQYR?Rjy&+}64={)X9C1NlGBjhyRJQe%0m)lQnv zUY2oty6(=Z-7eK-kLqWBkM8})d}sNs1#yOY7X7AWtN}MRnH_!n;Ct%7E&HMp)-Hk;j5j&7KJ{wiC-sZoocW$SzhOw_)CjV?4EW< zuDf)n?)9Bo3h!F~x6FCf9+n?&U+3YIQ*djs&a39jjkQk;Yo<9%xfxBmoWFI|!_9X> zVlU==E_KY?z30}Gv&&TDo3EaId%e|Y@ifa#%-We67J{5P6I9r)&-yp{A(yMN$PN+Z zD>qFm;v}Z6ntfP!Pvy5K-m;I@yIxKbUC{ge;-7qm1J4bQVsEyaptOyt-)u+hVnsQ& zTi?ylSiuZ5%}x5vGG|NY`A;3YQuwf3wd zo{mC4jQ3ZZN}e_;CdKe+%EsOMyiPFd{HSq1>CEn5ILTmB#LDm8^4G&JuK&6!cURiw z$-9@|-E?zO)_%3_<;^Pl- zw5w?O3XL_(W?x@_e}be%!j95k+sig*sopfVeaTl8nxCbxrB*3>=dGp$-(7NM*-IUZ z!oS<@S(UbPu|fH=^D}oGxYQHH{$`)%=H|VxO?pGOs(X8eoqZRuc1q{d$$j$-4@Kw* z1@gS$Tt9bq%kH1g-|n7WKOs3j|MkDlE5G+CS}C5Ip`L0LG3(dTGdiJVay|KKCRKOm zT((%=)Za0+s`g6w>9sxjOADf&70&vdQ(fkk<5leO^7i8*Zo|4tv*ne7;w!Je-zmB< zr_NLAb%^Qfq|XfVZMy4TT7Ry16JvK~qsHuN?S)?ahNnS0kgiri&iV zS@YdYbLl_387p3dYu#GjGdFVgho?oC)Xr?X_uqY6+W)JcD}NfkE0CMM=0r?b#qu+e zopt}e3R{}2T_0H7eteRRrkD5fn;Dxw1+MEm_R^QPGKv5F*^RkR_ic|Wdt&#CFFv7d z$%JLk99F-`T^+Y=g7_~-LzDd_3D25OoM}H^nWvmF@jSDB+syLs&)>?wPn_(_*HFBD z?VmXF=wd#@&JoN;N=8Os!VQLDHE z7ecnL7fd!jcDm!N%c;fT+a@^321+w1KKtD4}QH?COZDW#gptj zEe8bp4sjf;FzYyUqiwpfoq?S!v%dRv{^SX2g@yah%OzU02wb@AQ&doNrhSrcaY0du z?fxSN6$AKUmb?mbJ})euG->hljL%6SEG8 z@V7fu^7JV@TDqQTy1)z0&1L~|aecB2x*NV%ty(IQy~ub~f5o)b`nKt}%pO;Mo_jpR zVTYeFi@EWE_fl`7T$%RHf4gP%SE*YM&-Jq3YutHt$)N+>Rc7CQZhN*qa=-D5|II%S zX_(YrVST(zzPrRY_Wkuwg$dv7HWlBgPrZHT{J&YXi~Yaniu=r#GyA3Vo&WFlp9`nX z{v}uyvh~Z87QZr#X5PJaaK_5HfxBliHrjAMahfFB zn6e`E`!T<1Cg(Cbd8egisyFV9dFeb)_=m-8y}L5$=lP4T_RS1pKd%$Y+E+Z|)Q)w< z&5ujuRr@)8S$by2&l1gf5gWhN_R6vCCf3#y7yruq8nkYg$a3?qnHkRee}t8P6!t>8^D!pZocq}~_ls8*`-6ki| zt2>!PHNs8Vi`oy@W(a-DJ|eNiR9o3l*s|t{E8G0fbHoKXGB|~v^({GN&-eeF*U9S{ ztFv_vT%P3Crfc(rwVQAI1EV{kA6zEC_)xe%OfjJ8{*%R3bJHr9m`$pX&AJ(-*U#To zvf4oMhspohA0ItF^!<*`+;=C}%Dg=pxyqVrkNSM37k$--nx-xeW(?Ntj6EM}dQc$B zSzzMJqdWNh`hHF@bQX#|&*sQ+vUQbk+1>}B!hj)SQFZARX8q$j*n zXAhpd`1PkMA75k91Dlyo9z4AvvT)rEPQJLlbT_zuV&9+RdkqnRCWG`11Amn zPbobUUVifQ#jmL`KRA{}DjefWe0Gq*X~|E8uE(czE@k$`^@-l=W(fb?T4rjJzw41* z;|8k=I|r6`;_D_0?T>GJ9nWR(y`Awx(G(qKh8+S-H(uEvywtN*T)?aSBh&uG3l=w| zkE{__YP%=l+R!F&=q}@q={k*E);s6>u^&rT;Qv(cz2j-%k*Aeg*g1|Ww`}-+pk;bP zz)IWRgp#J?o^sC;-wVwSReC1OF*QuFWiPkd9+o4la$)SJ9;@(w-the-OTRGF!-wyf z?|8S)c=oU)!G`UV0)P4P8DAs0E-Usi@H)2a6;<1#cTdM{V$oY*)qKOT3WPii2;Mw&3(5{ew^Ss^OmLTnhUZWop1lPbe%0pJ`zxJ z^KJYn#t{@tYR0wocg`iV`w+HRbond~9^wU-2o? zsc)V5udJ<#e#e-XxM%P>vTX1<#VJ2W=JUc6A?N(pY%eOQwe#2%aQLNQoAZiH(aSO* zo!yzBWvJ;8*nF)dbgQDW)`cHCH)6#Qn5h4&*F?eG<~%nrOU zLa&R`j!p>pnIUDNs1WVM5#P6^`{24>sDUl-m>K8R|Dm~xnCFp1ekU- zwfyGj;I`@In{(7tE-kTZR0E(+X;ZH@ev&xRY?ISj{M)eXV)xawo+InFJ@~itQyFKXtpm5hxd$rWU&pfr z)V}opue>j-N~*o_g>2^k!!m~(b1pCOt#T7lT*#WMWs#%$L~Zi53AZNZYW(>v+kct= z!m1=yl_fHhGVJEXzd2cbxuxsynxE}1vg$VXi^_cC7V$+yxqZvsd*SWNHy4-p|9)em zHqmNf%6jMXdjx!)N`4m9{{H=JPD+befL%;m`wsv6rS`A6EBJzL9gen~-KKSStwG!d zxy)CK-D~|_3ba|er%sMyjMd$D%4*)V7WBE^Wz8cYlNR|j{n;xdrr*j#6h?8yGSo0^f^*z}e zvi07L2OsPFKF@oyrQ@?;@9KF^4}7pWyNO@EndePn%pO}U&r^*#Qi(qwFVXlDpEzZ5 zWb2t~o_Q;O*4^XfThukf`PND4T(HuVM};){%tq0I{pd&4f;a_HqDWY`@G@CHqTv|n+pS0 zvvQ?xTySLJnKm`nNt@Qz?@!Nr;xTLC|>L+NIzJwz{44p|MUCn_UZb2>aX42C%r4n z<@)j6zSkEl(!Ka=NBRrr=+eKjhSy?uNBuupnzUxhGR8iSz8a|`ntd03trd~sJQ#P< ztX(!Kcjb*q!RrbR9T%z(4P}-Nyu0XZVG8rAU+?&OxAX8OU+iD8`iT7ReYZD#x?pTl z_NjYap8J=A(?7zu`)F`a>}Pf|)+wnl_P1RyPxR?T_*`Mt<;!}S&G7|MCl9$Gw4D}MO?_oF^eP21a751*(?c=bBzvVqxY)B~HYeSC{Gw+bJu&?@?(QuKS>^T=I2A%W9urQ1}`25;CAp>vckr~LRW_1=J& z`=-6ve~jz>`#Je7zkVNkB)BwcyK40o5w7K5b8dg_K4{O`n8UX|tLyHDl&0^MLCPEQ zb-tR+gwMcYnNg|NEL%@`)S;VR7EUvM+BbRy`52%zv0K^f^;HSSG+U_xZCwk6QZ``5xT!P&b`HCgiwoiEM*jMo5$l*2x z$Iar*Chmrdn6_-c+tFrw`&uaP;q{h_Cgn;iOsRR)_jMZoNv0sN$`|Xj`FXho9!avO zo(b#BntG!2;MVSky2}>-`Lpr%t~=Mw>Kj)w|L`q8-=x2Kxssf!K;Ip~k1R_2_StTU zpD+JRW6_`Ml`{@^%t(xzcp^CMbN?%8!J>bRi_`^_4!Q5MzpyVYIxyt+x)dY9H-cry z8WxDR?-DT){j~GlvlWZk9ta$s%=gexe%swRU9SuKEV~M3pF6L*F?W|^5*JJ5t$Wwr z^6eFVojq?tz=;i){LQL)LZ_{+Q%QOH+|VSErCBHHXyS{BqHT@r`->(W_D@t0ap#Et zq_l8K`LUA)dp}BDEP4>r6#V|z{nzz>zP%Lp5Zoajl>cASYvWU6-9Djwez8ygmfyHt zpVa@s^xS8k^`7$SnRair6_!qXzW&dV-?L4g$lmdixXMwNR48$A4x7Q;!wN#z1PlH> z?S6IDa&B-9=gCu_ z?YAem)bQwj@GoJn7iyWz|G|CU4nc*3Z4JKS6K>=-J8r+_kg-Jg>4W|rms>9$ZM#+( zq3~HHX2NBi1>BMbFUsC#o|6>+p}uRb{b9E+k19ABm~V4FvtOjRmm-otSoKvWK_-X61-Fq(Vc1~?(ySQ|!(85iL&M$Z$Y!jMs_-Iasq@TUW z-IwjRlqT7?HP&S=b@AXdJFaQ{Cx|6D2;DyqB6TUp0Nl=Y@jrYJ8**=BBze z&CpZcAn5=7TH&vWGfOjHC-xSU|J))vC#=Y2*NgUP4?j6yj;(ufcF`Y(D^K$#b3AS5 zUC6%sw%6Y1c`iGiZM*jHi}S^~$v-_0@MoV^Hc?w7mYgV4-*W7aW_D1~- zlsK&a_0q12l%whWIxjXIX=abRd+7JYGUe&37NO!xdg7kjQ_31T(i=BTJRp&cSvTx+R_BCLV(3%b(K9A+R#&`3a)s8Qo zUBBq|&*I8f?|&9No4C2tSv)ou^ZTGSX=_ zG*P|rqEpX|y*^1~aj)L>=2c5I7I1UKd7HU-^;YeBqcLkzs&x9Uy@~T!d~CVfo^&sN z$K-Uf;i{3cPBEjL&dRS0AyPj7o-?J~_jZ`XvNGGqLwXIz-R*hy#+5O;ic5Gh+pEni zlowXTe>!|-|B4x$iYhk*g5O)MeR6l_8&I$&FS7n~;qUrS8yP0NjCc_Tir|=?QEjKY zJKue9@@IJJnlsyxOY!ao#S-RSYp)nT@N8MVe+%Do`C0F>=BqRQQTh4Kw#~5P+SI33 zjVzx+9`yK2*3JEp-Q1OZ_;$Ts6#g|m- z+cY0J8Rbq~mgo;HwSFdWcm8=(CuFdH7d)@R^ z+KDGCsx$U4TBK8L#&ch$s&ZZx^Xok2bP!{u?IF3Yb+4{8&s~bWtpR&%i#`w6)|=x`KCWs?R6h{ zv+ZNo{{QjEZ^K-3sfAO_r4~jQYw1=vb~DbKTJ!(g^ZVM((pr%k>$6zJQ}$M{)0DFM`fx2;turG)1)gvB`-~>0h0|(q|kQz!Ka+Y($MY7uj3c5%AWO(aY}BV)6F}}HduDmv7g>* zwIyleY13!wMk{T!?(peaPMu^Qvg~ZJHLKvsN&kaYFBpjYY%v!O*0}U`&bfE}?~e@KRXS$8&DVZj>HU+W;WlBf zF5lrP3=3rqwh2wNc6{=BtIkR$tyN{S?v};aux~k9@gnrh_4R(6!c86sm|weh;s46r zSycipi7(<`3JS%x-4(xQ`myICx42T4&y<;oNq@fQ1sCw_EPs9N`nSEuA6Fh@>=HQG zk+_`g>s$xHy~l&jWd6?NlT|!ftYl~*R+Da~(YAbFVfLvR?u84Or`LbgQ15zXWAWwe z57%|^3U*mZjd%EW*){nl#?7x(sb96IX#2UF2UeDZ%wGDr)g!{{{FDQ(o31?zvyIaD zvufk7+uWBXn{C){vbAoT?8%dS@@^S^)i(C)wI*(SvAHY2@#qex=(X!N6jnb;sg~(- zzj|fr%4m(rZ zKQ1PI@1IaXKhSK^ISp-&=Jy|_Uzx<^Ta>CX9W+^#^n_97U*++W&dmN(3?0R^zyCkF z{q^cM_E%r+$p1Eb+8x{X@4iQGT5~<+W6g#qv3qaIm!IBt>-y%S>DyO$ba!n~vf=hU zJ!i(Gz=MB_ZXWNkH9YsJ-}qD2?)X~8^0%LE2<62U3O|-;sp*2Qb(~aUP zPRVaNntXMF+J#)cvd~ikY}p^ZiQ>DbjMvRyGywH|KZXkGcA6&ZkM4n<}JVtgJI_4A1W0y((_ohC_di zBZXExc(rkr{E55EXaC>VyE-VI(@(W#;?9OOy&nWcbxU8IZ};IaeQfo7=5LKswX{1Q zF4Yz!KVY74v)h5&!%&gi{am}xlN6qc?Tq4sm1RF_ zE4P%sp2sy)Ht&_`pOvidD_0ub&Nu7Lee9epUv^Nno#AVd_~~Ni!zVpmADHXc>bvsw za4bGGS@=oD`t@e|=iZ((`o7?to`k9D4PH~5U;lL&j&=C26?kiRU`Ff(C-wTspiG07 zeuFN9CN0~8iZ>1U+%7Ge^Qph=O1$;)7x`0er*a%}mvH6?3^JbRobGPH!Fkvc#Q4j4 zb<_2Br^Jpc?TSj`cD7TTHzmsyX`Bh+oh1A9`a2JA%L7TyZGwVD5{@2W0hSw+t*j3@ z8flzy;kB}Uc7EsNX;YjX*;#}YmKZPvJbhwPUe?q2Y;Weg4U7LZJ^L9VZpCu1)ye-| z+qu3%jZY`)s039g=YJG`2iDSN7q8lzX$EaazBMzwl|xV#b=d zr+k9H4BAe7zNf?U)%9sw(ed&!A3HrJE7r?-8OqFl#l}-KWCW87ZaVj@P`OcQw{TMJ z|M{#eqC5;oU$8J}^e|3pdl)J8-nx^+kcm4+{i2nNEYClM%qpgbD|!^HWSt|qP9Eay zR!-v4>7Q3?(!Zp2qjb%V@@kIjeTFWVjOL{39lkfyp+zD?PW^XMpuS&in&w5r}Ag{hh!K&0b(#pkdrh8Z8(~Fz?pG_1o`nGt% z(SXI)Ew7JDC~=CMGs=A8%CgKplNV%YOq?E5+~MAjPuI)D37<$}K5kOneEfm+A6D}? z^@d$vtU)>S)w0&f+o8v5mx(TkSG2x!<+ZUG_s^(bAyu^h?)rTf zB%W_c>iKea((kj&Ha^$=k>@#m8y9QU`-4w5*texTzV$7UJ$FlXk;S|4vcF$5P8RL8 zyS416B3~Y(oLI-gx(VlE9sa+qar#oVbMxU$1GVGF96#Kc`}1Lj`Bh#h+yyfJubLP1#YeZQ8 zJUjHk=Zr&7Ea!8GUMiM{32!9Y=UgmW#5`B_ ztN6RKMrZkB;@NnFm3l64I2qaQ^akbqO*KXQC1qFkzj)s$!`>p|#&9aY@M7z^KEnXZ zv+BD*8T``zkaEct8+Y@auh!%dEO6IQTefp^vP@UfF1C|>zoze%(zqhC?a+t4bN$Z+ zq`QZO8_WnczH&3L{_1MEJ9(!*YrYpyY&3LPc;_u!sBn6^uk!bP&d>7QcfW>~tH#!p%~P{_Hbwh|)$6?N zx9;a{w$Aqao#B}rp1XBD=bxOn!CRy9JU8Ex*SQ(?b^5Bh1%`3QQ{y|YBk)iHn4otzi@@3^nQcPTTeHtp8onPWA?Ll>od*|j@iAbOE?!Y z%eeoab>)$w+sh9Z2E5zTki6}B+S$mg&wmQG%zkxp-AVoO{Cj(wkMQ`-J*Ps%Fuw-*{2{l2gzL- zBG>aKy%S`)HgguJKko^TmJdjTz@^X zS*FY$p^^6cZpVf14;)YAS{_O4Q8t}XYg=H)Ta@7Wt|;Q9dar^ByF8PP0)OF#!ZmCW zo}UERrQOdTzTR*7J~3_q5h#vEqv4qbu9(Z^sv$|F7w= zdOh0`PPsOwXNjw4TO7V~CWv8S@e8hkT(|0kE!PcBJo05w^sEqAT(&6G%jL(mT)v)m z;qRX|{91kfu)R)01CQO274tKu3JE?-EKabQvtxSu)r7;%jY|&*PHN{*G!YlyI``vrGyJ+Tyixs%L<54%E!7oOjH(#2ili{-C%<;!$Xn z?Y^!9Th9GsJC)q^d+8gk2WP(>GCy1PJH)>5!kw*VT>q~Hzgv3MLSyyEdflg18JhnW z^-T3!bNATisD*2%S_ukos%81lwr^wj)GrT0LOP~Au(<6O8u{f~aMS;vUw%H0etc5s z%>8fs`|j^zj`_4t_-S_KzIS}>@7(K+=Ps7MIi>sC9rv#*qjfA#UwYA|H|@jHJ1)_M z>pX%d|GM)o)U@Ad?u62LyOzmnIqpg}Zus7__2{jAlV*mv%<;c8XRQSHlWY}hX0=7u z{JznaE0-O+>%K_p+#=Rs_M%LqODXd{hIH-{cGuV};4**binVL^g)?pXkRy6xQNXi` z_hKnsmfH)mRWF<_mb$Amt@4QJ347Dz{adAL@9n8uajX4dVWp4(kNxUNCl(iFEN{Hp zylUV5Pd8WD7j0GiXcKqw<5{ENuiKgr?wI;_UAHaIm4Gd&il^qiS@ibp-8{y-3tqOl zKd~*@AW>CRzUrIr-8bAl6*S-n@u}rD=y@GBk|mSM^Ig3_uC7X zwleKwc3t%3;nQxL>F@IAo;*6&SZ?_%?@7L|W>~DSX`AM|LY=GprX1TXzWD5ECuL84 zQ@`q3v(iPs@{)z*>Yus?7+R&?Vc$b-K0s>{N$pl*U5036Li`<4x%sy(guvHq+z->s z((??=|NVBBTKUb}dELDitraX~Qaa1Fq$#=JO|>cH=qz z-LF^Ae{ZoUW8w`azf|&^(3B4nmj!gUT@Pnj%lQ90d)GDDn!_yyTQr{B z7q?%xzDYmyqFLlFCAv?L}F@5sVI5|J<#WTzG*O~6_>q^o;yFlMp)2!pz{tGu|^w^rLdDxOPFH=sS za*guwkfP=n^36w!uPzJ|@r_pcvE{u>=P$OazVU1C1^m|u(46-BYt)txs_*R=tvi2v z->T~x^Uq#hFx_4xCw6a#l&FA0R@iF4FIs}Xcda+eFiW>#xbVilJ3jT%Gm*TJ_oCR<88iThhIh1svLXx3B4g*rO~6n)h{Tb!^p zZ0YIwWTE)|Rq&1@&boqg=7qg(xUlt!lS1dq8%^$GO-<0+cu^X2)*f7Oh;{%1K%dGPt06@vnc_<=Hi`_oTA2P?|9 z?su;KJfSZ$?aiNieF6ywTP3Vkn0v962VcFz;&l7NM~RbjZF0n~{j!b|)|2`mj;rT{AW6rUk z8V{6(p7S0l3(T+C8Dl|yN; zw$tC+ekBztWg8BM$Z2rao&WvH^@WNP(<`>Ox0VUSmTyq^n$0OKCA-65DyI}%{HjH{ zVZIyRUpRZ+Kfb^i@Cm-Dkp$|qL8vskf8@#O88 zUq3W*wf1+hTPkPYI)CPqq5Lk>et(tHJ5+Z6YsN}0 zuc>^mq*J4o*&8ff`n#<&TckHnF5rg6LK!aEWfxuu%{Eif-~V(~(PA&Rd1_PM`!-!k zv^!f;H^2C8&ea^Vv;4vF58jAB?R@RVT(?Oj?Nne_WKNXumE~ORiA)bqoN4*+ehH6U z^X^4%{{<>FZ{4)%x~x($L?}~jPZrmThaYyNTQlU<{?a7sM5*1HAarm@n zhdxt6hi}z{qTB~SfSOy%cp7s4aAbo4jwx7_tyt8$%rE> zA0NyUxYZ=gcsqW|kMolb7MY*Ccw(=6sbIotR)!Lp&wKP;Oa|>#IG>1WvW}9tod%FJ{In<6oSX@iuHNn;y8x z@ZA+(x^j0n$NQO5@^x}y@2odNng zr5;dCpV8L5ui8$k!|dU_e#JiZ3cezLkxkbpa*8$ISuMYM;nJ^nKVMXs!uq}D%G;ym z({#F*Sw`)Aze10xEvxg1{_`)^Qx3B@-D(Icb+FJfN}Tt7%1481_38&g=CD;fTip0U z;m+s66%zcxmUj=GjERs|6Uq<$Rg}2e@AdBIiybw%-~E(`eU$k6ozkK5W!KuLw@>}u z_eRO#ocsBJB{5f1wnn?eV|*;ruqA%d#jv}%!mM3RV$%aZ->3?= z7lrXFmN(D3{(sf0O+PQbY^dMoedcDHj2^cnU-9d%WGp;;5J9)9ZT_3psK z?W(Hf!ZqHPrcAsV^=IF&qDsNPYoq%Qo8+W#`tz;8`i;ls{1dNkCwt%fb~~{q<5}Jd z@zwu3TxUj3StvWYS zg%`)8eC z`jlxGKYc!KzWV$AHUGG(g^lCFFK)Q&_f{wAdZfwLa{gTXeHT}C#q}Rnm=}3;@%5&e zQ6HqTS|{}#h>tq`_q0*OtRKi&Pd`*~Snr|OAYk+VchZ$t(Ky#2qJ!NN)^ z%JFt8!~D6bp?QCbSG;F(KEV;^64`yb@p;0V2)?Omoj=3hsr`846XX3ho;k5kF@;6G zX=-E;>$i)yCdx$2WdDBPR^b0bH<|q=fBLBx-O}^GIb{piyTx0TEmHz=+G}}k1lDtz z-?$buE9Cs@t4bldKLu2|iw(+j+9$PJN?5;|Z!NRn{&V%+IRdX_Y&iJL)wu6eWxE$W z(2423*7s}oRu0KDjY9<%t_SR%m&yBEOSgx+8Mr4Om%1L=@OEy)YG1ZZul#2z_gyf2 z@VMc_m-HVCQWx0o{%6k>@Hd?ClaXcadNBsg9}LT?AL*RlY`rvjh0X`Q-gnMVFRi)x za&M`Cz`^znvLa_E9lSfmRNP^OgarTbcTW>{ZTR#&l7oTKhT*pJMH%A{PaWr}u^l_K zu{v^w-J0yKx%cAO6}wKg8`O%N7y9;zhhLWYY2k+7l`rDf_&@#X#MVg_)Bd+}O+GqkfI&)aCL`%>pVl9G5vh>iFv0bszXOClajp_KnB`Q?K|>Npf1e zV3F(7QpH_=H(oFh{;@GcQ}~pmj_UEBFXV-sjUmjIY9?vd z^KY$JQ(Ss_R%D%EVy`2|EEi2FbHlx7J|EfP=W}Yo^Ug+_(|%g<0!FdmBlGNCQB`c-P>+vz2CrK+J4YyqfzL}53yi2D>Ki%;)ZGQ_bX0~`cM(w#8=G&1m3}Nig2Ft*HzO+O=fq_n1P|xyU(q}KZP|wXNwbXwU+mzpbKSjdf3s0X=G;peKYt$n znlHcZK4bll#;4Ehj`uWQRbh*djB{P@+NhUQvGc=iAC%|r6acwv^V(0wMEFi`6u&W=}9LUzOp0o zTt|yEyyDx$7zJxMj=A1_XlYUQf6B4XD!c^+Z#wEHemHD7XIc8$eLI`3-kH)_|F!w< zeyf;#iD;&O*ZO`;KlkpZ8XJ4#84=0z&FT+s{GBYx!aKJi+5OMz#ljx1F7vEj?EFEY z;psvl+iaOP|72c8`P4JkXMaEMlBt!ZRV=(J*!8i(5#JArr$Wy3XZSyMm3{K!#$Vmn zItR*pBR|LGX53QhyI^QhE->#L&-GnrnC9O6`aiJY)gG=1ms^tdMm~MuI^$gDXOS-T zJ;GLPrPXa85kPKUF-W`ARF=XaCJ{HkD_vg z;IjTlk=J%s-DeZHqbai|e6dZ5{x+L{hJ}q~K_;gjHZU|0yVkeC;BLfyz72^C zrIt1fm%TsAy!I;H#Nc$)AyUHnnA7*prk+ZY1;L#J3T~ z*4#UyWHmPlO9lqq%v<>Q;-{TG7dDqW9CADTZXNsI1rywj9!0p+v_~z?3bcOAKCQH9 z%d3@dzw^Jn;gPDQGJBf66PsGgpV}GGsx?!RuJ|qJE|cDrSG6;$i!*fT!hM#PI80K_ z_o-a2tM#AN8KWN``&avj$PwSX#bH{jCh4bVyy98%igoYmh}!$}wEQ)D_T^7359&PH zpS=6+zC$ayu3vUtd+F??sP5RGAt%Mlr-?qAtE{DI_ab&eC#SzyA+J~N%G4DWDgnC+ z-cNgb*ZDTL?61>1_Pu{rX8ZnlSx`~mE7KVh_ar5W8U_CZ@>j$6`i$Hid3s@hq)ZYt3hF3KG4z^;x^8XgD;>DBo~U?aE@_ zI?MI)oi+ah`kQvtWH>zju zX)`U3#NT!PBl0$dm1*}Z(TkrxU;WL0{r!VKk91P6Y*{Q3RlZW+|4d}uYN6>1*N2xi zrL5udn{lhpZ${75Me2`*(>N5KA3wl#D=x`c&wJIKAL5p8G}|T!?&BF1dp1OUwsl70l`QNR+U%Sn>t(f$x za%n`16+3^^^E}&XwT*lDinf%!xip{k#y;ie>FbqjOvHE=CSSPYSWzWCbrJ9T+;#u^ znL^$NH8ANZT)P{>7k6ag_XHd5-7__ujs{dd_{)2j^X`5o8y=>o55LH(cu$+o$q&z8 zwmzRv_~);8)sT~Gx!gQKhjr1pbBcVG4{G@yC;po8OprlC>Y!fBQ;rU;Gr`9p8K~Uo z>HDj5*%Xy4O4IAseaqFi?mqCV1(JcJEx3Q!-PKHMF!~)_`uuA3gzEh5Pj4D@Sj<&RVx(rrK1=lt(LEB_99&#woW; z?%AulcT4Pc{8eM-?=Sv-;jj1_gI4*L6?2~}Us(RvVDjy0Tl~-Ft*^OVx>@}5Uz?K) zWBI;J__*)?V)=bv?yq&tcJH3_-`p@tiZx1(MPq%>zmnFYSq+P;xuuHln7y8+^H9L- z?2efye798X-V@m%wAht5iAUtRGjsK>5GMcpH4}3Fzxj3cgX`)`^Y2fw`oG5Ol+3!g zSD*Hrw5VTa^;1yK@X*w0LK;)KckbR3@KEGX1 zR2xm}thCm4m9`DrdC~nsLzB91(CoAS*%;=oznX=$DQ`jR^+<+>3Pzy2DoNk7Zh?Ib zk})Z3kRH1U)yg0Ef1&@1&yn13tw;rzXMIg9{P;|MKC9-5q}q?m7Fe$3Z2kXjW!|S{N>epHH%&hJ z?h&u*_J;pOp%ZS)?Rz@KXj8yF(ow=KE5{=}n?aTDi% zfBkMlcDwKP`MUoWUr(v?O%rc<@AK;EskUcpHk>}lbV(@NQ!YNLa@$vS zy3E^do3nS>BIUFH_Wp2P zZ>#@l(M2BnsC83y)BL<2e!4XCjKuk{tevgTr~bUeA8=x6<(IOpw|Sb4x9|NaeD#n3yg$~!^9+KdwM+-o^UgIw#k*LMscry75xx@bvm|T?XCNK<(n-R^M*V= zzh3^n{ypc$CR38#RYh z=RQSM)dxP!+0*1agTvFswb<_HrP~{29#mWlmf0iw^|>Xt%qgq&$0e;=Iwv?898|Mp zv7W>%TrbwN{9;!tNU~T@VqEUC`d`cb&5Qs2`r-!K#XawkgyQTK zT%D$SWKS=&32y%6!+UB6+oZnVDhfL7EKVXIbCfMRoP3Hn%C79UIjpEqz?W*eGW(X@ z$&0rQZ(4D4oQix}`q;Q3dy$N{a^D8S6lLWj5p%chT~Sb4_vn9ALts3+Kxv%fuQx>= zN_(mv**MC-EK$wjna;lILWSxYChL0Mc@7ROB1#$>vzA^vktwIgc1n4ZdZmSE*}qL^ zPCw@oQB-i^5-brpJ1MyQxu3$LV~$&;o<7|2<4E$FVD*-#hHe$QM>kJ-er`c`<7bPT zmu*h%;G5LDTg@p$j??8ru!(o?jAsv%7T73NPinvXgi}tC>G4BV!Sk0^f3jp*RguR# z=lIEaVp}#h@Tcw5;mT3a=AN8zbjv$?*`I&9e_Wop?iBaIgq7*l~@5j_dCZoJG)hUtiSmxT-@WuaX;MRE>B@KP8@4tx?hvS2&EeCkbo#&U;yTJ1Z&CqnbOdba!)-PqWWs64ad+oDg6 z4u^A>fO4;bvB!a;*Jn3-Zno9f^q%d~{nby?_A)x%cHb0qT2~@$iTtg^%_a(4Z}Tw! zxpGd+Kk?o4x^qXww_QlTrt;vMufFu#*!&Eg+qOFcQ*OR}cYA5vqh}XG&g(HZX#$#qrF5JtxdNWNdKyF9Sd^6*%uXjy*cHz?fKJ(}mAGL4IFn?Bikp0_N16h-- z$Jf8;ZwY%GrLsN#!DR89=biKS%T=e!o4sS7pjY~X``eis>9o&AufMp5W=vZ4U&jWosdr!UKb>`#z51ST=$`ej9CiDr9jN-;B=>O5N!MnM zc@6J2RDXGULHFt_j^iJ)GWZX#p2fP)b&`~ygJQwi=*Ft|q5j*_KECz|E{tN(yxX3_ zlegIWyU)T^Z*DG&V7%o2`f=S#+j%8NJvDkXGG|_xwfH}quFC zvC~#?MO}!=^>#(i`AuQ_GW3e?7w?|9RIcl)HfzzgxBt$qPfzRSx|>_D@l#CL zu2&b#3wT4fiSAGDIs2^C(Rg9&-bQ=YrO#$Bxb#QkZ20mWyZ&1Isb1E0fAiX%m5gzh zFUi`hFkipw%|GcB-h8cMx7kX&|8I$ZsdYtX_y6ft5+$MB8MDX` z*)*Hk|1YO~Vu!ix#iU&uy&c!Jj>)g@V z`sLrAHnk%HYED9o>zDiZJ$djpf=_j`N?^U1sA8)4udc#>4M~f&D#0b71m`JEzJq;F z4kTP#C@j+?`&E1=kIa%Ytp`Bb0~?q4e{tH7Y#EZC6)<@??rOC4V zsY-i-d(i`fXTF7?(#{fG+BNwWe<;&oKe*ho!uplIGGDSu^(&u82dI$g8z zxPTtpbU~%U;{_`k=IlsL`hT72jcgL5%&9&`A1=)UFWC-6Fg@~F8pAW2weIwS(t_r7dolEd8m&Y`wEJd}i=Z+t!V6i@Q_`c4&ngc)DmEQdHQ1m<0mm1k7 z{e_3=a_)Y%Q-^OGM%r=zSfDO4qc6+p;r?2!FR`q56vKCH65HKvK0)=zjgOuO?yz1K zJd^Zc+sgk8d(Lp#nsjPazdpWx&$Z3sX3aMzdcI`rKKStDuCKeot3F)%9I`&IJdMYA z^A-Q92U2qHujZV~zLxSjxBB+^XF(>Q3N_0n^Wf6>kDbvMZhedn*uO_Kc>4pE193$^ zxDNVVo;+jj;x+awjI1(ma(KF2ong&)_F;_-j`e@%oZ|o6+~gK} zWN+LKrG{k&Yy}q@SAG_{Ia#t`?^fa65;rgZo8-29p;WA?y77+wGfg)od7^DMsfUZt zc{a)a$NV=P^@5@6*9ekg+CSkVA z*0E7fy!TA%r?q$2eK_)eE5qX5d=oOhG8kwsVTdy=oObo5*G&mM?vR-ut*#jQ-uxWmJ>5<{--wq!=P+4Jp?6B5` z=Zx+dCH<8xPbWIC@Vah(vdFG@UkuL__YMF1e`MXvm1b+&zsdb&LO6eP*g4mrB^UiANwIGe&%8fkNmt(2^j)+%^lQf4 zy_^QIf7`o7EFJF3W`5wV{)&-6^5{iE~c zqu};+dF%7`#nrp;wzjmk*X8drH_ZR#B-h1B9NrmeUdDN^m zSN|Lz$zi~^THRN)gYTsQYnpxTd)3NQAu&EHomZe>$>Uo!uw-%*2l`uh!kosekTe7#3AKhqZE+z>~`geuXXD-Yl{en$-!t`n;N;=DcmX<|ag zt0&^Icl};`?EAR>-HZS+C3*Iiw1^iU{A|8Z;{|!SY?t4%}O`i|LM`1?O=~^V!`0Gd14LoM5!!cGa943_i}WZ={a3ZcC`UYm#yN zg7aCqNXeKZfvit_vecVC#yoiu`Q%sLgUVf?{p`%r?$e)HM#Sh$OL8x(K7T76vY*}l zJXfe#{Zk>exNbdXo4~cxO%Lsty|GVvPNDr}ZR^9UXFVz_S@p+gwcw5NwoBGO3m=Ep zZvUt}OYNTZo{xr{#rf7U66@E#y712RLWN@3q6IFI&bp=FznXkp_4E6;>7{S)RxlaM z{K|YR?6lI^DC8fHn{)Y$SJN~X-Znq&a<5|37jwI%3%7~3PZz2-`*4$iO}sg4dg}q{ z^{M<>GuR|_=d{tAy|;hN6!*MPEPKUCWdFtz`;Fhqc76Wc z82VNCi+%djttQteu9IEFt~c?r*grKx9!C+-X7()q+Mids=Q{}U4D6Lj19#7B+i<~5HJohK}qEUs+gZn%(X z%l5l1$L76#y{c{Jb(z4E-*^SQ>~fY@oqwLpsM&2(a(`-j8!N|0o+hERRW4iIpR9Xu z>*yV^=D@mtSKj8n%bvae&;iCj>#7qDUO!tb*e}H4p4VByBzXUx>@E8^InZYI>C;xv z4rdAHn`F5|Kw0vzay;LP^*7_DoZY8AlgG5WsntN~#kP%Y@4H-GKNdWb`?KW6?;RhL z^B>ti*}lNx&$?a9UM8fT*k5)$b@#kaeA;QwO7EF-6#hl~T7Q(xO*wT$elo|2lk9eU zw}M1ZR`91P=(hhMyeGop}(Hd`g(pIUrv54oPciglo zpWIsd=Ce!ky1u%TS>>o5I)Kf3c56;7$JJu=B(#>4mjOj}=@ zKb6bMjqccH+UdK`f1vaEPw)JS`iX5d4Yzp~OC9u|^Es+1Rp5XfN3%zSy8`?A_|W`o zC4L`SGnP%BaNS~g`_4!8nhflMWtlTxDjaZ8cNEM1=V8(%$|%&+(ZY7)>C?`g z9u$8#U&384)UuiXgZsQ2f(i#)8t$Ib&sxpPz3U>Ilk!{*?)ohrOFH%ZD(AAZ&s2Zd zG$)O*G$p~&Jlntc+=~bEU#8V5%vmIUT#tdnfI-9JMc4hNye$ovas=(w?;e_exM0(< zdPlRP@f&Y$o&O^3?abZ3#7emTZ~En9yUQVBmqpW839Fij3%zD8Dx6B~{M@@*?Rhs% z=8tqxvTpjF;IyQ3Grw5LXO)Yet)3W|o-drBHl6uqUx3l1oJNB;Eh@Z|Zfq2u_D7%f z#7uogLB6EhVH3B=OHWW-1I=bick7}c5@1_5)I4C_S;r-cT{f8v#PO9^8da#ur`NgR$ztHY~ z$JNFDcF(@dZcC_Gd~ox+yl%F*DFuF&xrOJ!``{N!ykeTCwfuVLEki-hqE|N@C*|FD zbWp#swONK?XW|>FG%LgX(N9)8e^M_nxOGo8s7Y|*$c!m;OyL%jnXWI5uz)m*&9zt-FgG*Qiy_AelO1m*xV+f6_4mw^*(X{j7%h?gb~B;3J!r$>v4>L}9Sx~b6s#{+{__}F{pOcnF z@3|oCP$@V&ZGw}Bxev$PhBEE1JQZSzul3g+e$~G0_O0iU4E7=Wesdm{aJhY|V6y{L zrIvz}LF$jQhw}Nf&hfARAH>6RuH)_d7`H_(OBnk&UPQ@iFWeElC;QlilH(Und<(w2 zmE)iJo0a#(d8NL`g0{lfUwNCmV9B{@KfUz&`RDA~T#|dbeOrtq({-_ZTOJ>CE=XGH z`Hw01$lNVkT)X0CJ^DKT=4C693toQ?Ojh$aYIyYj>?FmHKE>go%GGAvT7Kb7J-_lM ztkO>Gw2|xHBy+=}uK2~%m#=!?eETPTN@3EA?9PA1IukT)_t&03+Yl{np?5~$iI0M0V?uy*&nfK$8Y zIb7FvTgqy^MdyIJ>izxypI(3c_NsksR)O5wD+0S`vEKOo_V|1I+9I!WCwP|e%~Zc( zuyNYN74enX z%AX8Qok^bfO!8~p7FJ>NPYdf%Pn=}9E3DHRn;kVzoK4dLsm71CCuzAY;9ErHJ$bXB(`Z_+; z9i6$#p(C^GnT+{@2_GA~6eDXQ_f{>lFSDC}B4bT{^b6L=s@0y6o6@u{Tv;glcsFyx zhnd15Hbt`i9?zWEj>KOPnE!S4gP&4obstaNvT4oxS7k|uqfMtezI>-K#q8R*)|qiU z+c%W2cGfPdE131f;(60gCG#b=EniYj{?~jfQ1>tDfZ~^Tk*v4bwU0iU7Q1Nxqy1~c_wqFv2;B3nX_qeC zu<(o4m002Q9==Tr8Vm!oySnq=2Qn^v@T_k7mh$g^W!L}Y@9|Lko%H{F=0XlF{xvyz zKh}yew+Pr5T+Do3;2^K?RqiB+n7f^AcrtJc)sEV?2u6jysScUAd~JFg!v z*(|f-?w$j3Hqw%us$rMxdfIM2c#ykw-=SqpUXHt4e$2eL`AUka%DpmSb>mI(H485^ zZ#CQgCDJKpp|9SJTZf#aZ^XZo+&RxJ`%v3`O`ek*SdTux+v!lU@5ILN&oqa5od)-XxUKg$gE2a6icy0ZP0XAs|7wy-D`*_|cf`%n8u{+(>R zzxJ$j(!Vv0*t-^}Yx?PS95RVp4=g~FQ29w&yj(Umyj=RwZicaug(Y#_j6LDE^Q0|> zYRw8qon3eu*XerNQ{#d7WYv?p)Vw*T?UJ9actWlfdxj?cl0xAtzI zCAw+rBgeedr(#n~-9F`-)xTjgir9HLPIq_dayBD7Eu$G*%d$I~N@~~hJ-L_Bus`QY z@b;J-v-2qt@4jU{mEmEX`7|c&Lu|-{$eaCrx%LvxH|0Oy|FZ7sngm_llYjP3RbRfF zbC+A`jk3Qh6;X4!)Qi*1?6*rk zFFJN=R_ZVJ=vVTh*dfc3Xb!MyTCFIjBCvQEGXSaXv zzc26PC-luJJhtiYesT7z{l9{hH~kIW-xTkCPAzQH*|OJP7r1>-4B(H>4r*?$+gN(L zn04z(5BCSw#;p+_r9=dyJe2z;H}BdLvES;b=_Ki(1D3k0#6GNAF=O-pNTw-*-fJHe zJXUD?yhwBJ-VE-*M4rcrr&d%bo^E05PnOaOG|4@6@8OEtmArFnRZFKU@;p{N_F#|h zDi=y*_-*=bP5HJx+}GPL&Y9RWbyvn*rm!nle|8*_JjX69 z?3UuibnexWDRXZ9*E#6t=sjVJhk%1q&x3RcxzyC0$vm$QuR8EtWfy-QUsSb3W@^*I zr7jYQeG9dAF8J1RRPr3V*m0KrV-M38o@TRtf0xsFx$?0On|Z<`xo=x@wta0pR(Rxb z;f~6Tx2|u(3R4=|C6vz?hb)~JVRAG69!%?^ZsnrQGYm>(4BO^s?Km}Q-vq<=%)O60 zjz2D#EO`ESOXJhS{$??$!F#6|K8K25zWCKW_zGv+yM7L3AM=oeR?$4Ep6ut zuUU6BT#vcCvTc>w9qa$#zng98>7#8tr|-s1^u1pH_E-C%eJSd*ik?Tm@A>yKTp+DA zr~c}Czat-**vezLb3A_E&)B$bdC;cbSMtY>3v-qpRQWEoDce~w*8kmnchd=XZ>`H0 zGnU`gcqhN?^!nD%#W5Evf90LLTV=cAvPjMLC4AAhcz>mwNZD_FBjN6?SBc!2A=;bl z-%QK;`gXyIq^(vf5`QT2RxzfD7p$ubIM6!yv%I`Yw}bi>?nfBe^qAR(>s=_{QIFCo;+{ z>e*z-?-X)aus?gnig}qk{tCLknK>`x+`bma`hSx+cs>Xu7lf&QFKlu*Ex6|M&9L+M zTg8huM-+ZmE>q|EAdq^%yJcCD#iK&rsaNtBw$vUFtS*)<`1V1;vYt~`@`2*1jI*}9 z*9(q3mWnF&_P)U`voXIbsKsWEy_Y)6+_vJThSgOwU;N~h3srdVa_Xr^Ebec9s&rqv zb1I;XPw`mBrKtu7A4|>3R8=WFa_^2@t^4KA)~{L?T3a2OP_WhasKLR-QcE%>8~S|M zu{UM1L<*DH+ZwLJeDdd;PyF2}cv5TjgO3M4Dk+{>7bHJ-qjjBxpT*&y6Os;foN?DU zVfBscgSOAx`e_Nz=c^ugywY~<*8>Jpi+Jq!f3SFHmON=@LWF!6yPfjIxdp}-ZcQ)n zb&)*g+#{GKu`0-4b6U^g-v=IXSO~SxZ@wnCZ@b3fiVmYcGKWK%7W*B4ShJw8LZ4qprHd6+J_Zqr(>iEkX=Gxr{T93hh@x2xtulXp+zXTijl&bCz|m+r-DF51T+qpRkjE|lUfzz zzpg~)9=n+Pfr%D>a(He|SZ*pTVJG{X$9_S<)H=6)Ck{O8j|bUzqoQ)+2eG)$_4Wok z6ej$X;>)yHEba90^uJ~DYE=xccH0_kn=bya)9U{sUF~#^<2zeCGAiCqd$x5pp*;GN z+pFk#;QRKBh!5Ip?*9$lZ#D4%x5V{yt~_I-)2Xpr?G>N)|IELijmWFUoT>(M*miGP zky4hsW6A52e?PBa+Y}wGm=^l|;d(xa@3ZfI$}XvW{N0*y_t&Zb{bi1~-a<3#g}Dr0 zH?)SV5{+CF#%?MzwYU553ww(|`x)|S;w9_qcX;vq{=e}2)&8nm@_t7g)6FhuFRxC& z6k((lBlY>O6z%|nKO7Ha+`%k(2Ezj-V+pw+}{dZT{&UKkL&DXN9^-o#7TxPv? ztzGtZgMUj4q|c^X=Cu6`yf*X6o2hqoZm7O`6@Os=z%kE_Bf>MpsF(;x@UY~uG*dVtwbn@5kwVPJQo;`eY{`F@yZt`q=?(%F34)Xhd z99D2Oxc=`57oRy_lEwAwA?f_vzkm9Z_)y}Q^OTDQwU&oXD`YM+TyEc{S>3+)+a`_H z?dw;a(5r0wD3JU?=#N?whsC1C!?Me~jtCT7iF>7f+K~S_lkCCe52rk+5(pJ2aA`~k zvcD_zjnDn9_TPfT${Z{vO}l)qIUX=%Er^kMt=k1;r5GcdO_`VcI6m%04aE{=bf>#ly; z!RdT(|0CsMQ zJTvp;{Y?&n+#MH9=jsSZp)?0Gg@9E1BbCNwKV_3C(vZ~UJS3a|( z^klF7TEzEwf1a$^p{0i{R?Jpakl5Qg&XnJKJTLak+oP+c7(a5Y+q-@FY~7mZ z_j^OWsXi24`O7Lir!T@!>AYLPi)AX0&RD-#wf=F$FFx&+qBqS2?jADe3VT%;V&2dx zQhWUMB`s6acSk3uUOye>>U?+t+vhG{O>M>V4#tyR-tT-6Hr?KPrBdpSAlHR$Z`b-} zC|tf?ki~i;xu@#)*=dy<*>wHS-pHRDbKmU5{8PWSTIWe~9{wQxOl zx4l>R^}v<)A!q(f=o7zFqR+CfQ@kN=n#;oP9J;4=O|vmiJ*Pb{-OJRZujY9vqn=kIymzo?SWurSKd(dq z+?R4QQUFaa1%U)j6bwPy!E7@HL(u9%Fxy$(Rp)nb-l;dseBN{1kMy`C;hO0n z5qkS!y38I{ofGrZUp!M?Z^pW-R(l%zOt#w9;YY` z{MuQIaxd~YyxkWu?X{4{iTv*JuZovXpI=q+y2kdRYE4K;m)*8t!xgLJloK3pPIUd| zXsRT*Oz_<~neqbW&RwUjJd+78P>y#mex6%>^ zW4TAy_h=S(tgy|0m=hSH^ke?AqJM`>+U^EAv?v`~aOm~wukD|A^qdi0(Z9LDMe~TV zP~hf&?u-V%O0w96!#R&V>QPx3E8isNV%KuYpsOQzrCJ@I*}KORW+>IZ7T(U8T&R|M zW{v;Cgon;6c#=89iYNJe+1OugvB6@_8%O!?>-y)&adEfqJ@MGlEO9Zt<8p=5{JUT6xi0)#&6w!Z_URUL!y$o451Q^}jDDLpTmol)|bz}}{+NF$5cSebT|iOY_p%r$FY&!uh`)p|A2I5?-GO14F2m0`=(Kzr{OPg|{g`0{0s|EQ34>ppu| z!j7vY_(*`mny#v!o^yHBvbR{)h+2HS$hAgjHrJzv#y1^LC>;|ByW#w){GeCHS%RTLqO3u0*9KnJ|M^Y!&y`n4Te#Swzvh2&YJR`v?XBy* zpVS}NPYIta-krPm55Hk$l~(a&PqP+hUNiZtKi^pYZ@tTVmA$uY`}DjQ^-B(v1m&9e zaT+K&sj)q^Pc*1-`oM92UeuQUgbNpT-OGFZ{;hg$FpG@cgW7#7*BvQwn0e@dE=O9i z9J}Vfz3+N{o)*9DBz-qMW&&>`?}T3;E6wr>6uC_!^IqNEcSnr(mPqKuC$cw=+4Jw- z8)u)!e>F=jJh=bnA8hPNk3dse+KQN2HHwwG`2 z{t(>Z<5BC>soa1E4k`el*J4^Nay+nRzegD|PDi(n|lizkJdUf3#SWa_tKb!b+l{02$$wR&yS54(Bu+;J5O zW<1QV+pAo*E=*Eqoucz%=_`vudD|B_>sy}L_O|I&RJLh%Bx8Ei-iOu|tP}Fs^eYPQ zc$?eXxBZBm`!M07jdOqMW!X=CasPg)s%&rn?zwTh-@kG* zZ=Q9pXhU_#ihEp2JiY2X%O@Xv|H?RliM#TkFwgNYU%4~x4ELYTDfnS6{8xRC?keB! zOq=~Od*uIB{F!w3|D3jG!Nfw*V@!7ulV*7$Ds&GeRg%b)Kax;?UQX23ZHy&xbU!hb@PPv+mtzy zQ})Qr`7!0<$MyEdY+q~6xm!1_X`yDRK+&{g0=JI*u#|Zmtd^d%cg8x#cb7M^2~I4y z@Ko99Ub|q+M#DHhznW9eeAdjL=X&r?Bug8!^(%!EUgwr=7ICS@d`HiJl#mx+*WD0j z{dD)w6}+#HUhFrpd|+Ab((|Ht!lW7gFE;P~=gt^aZ>rF9G9b>>Ay|Sr;_H`i$@n)@ zPA-i6A$sd}`w?B^)WgNuf>wtm7KI1sd$XknpS{E4^!&rs#K-%r)^NT4+EmSGb&zAh z^#FZ$K4Vq2*IO)WLT~I?&$aq++OiuTzC^W1q7_hT@75m9*tk>ruzO=cmjqWwXrR9R z%E<>)dd=F`Gf96BO_+KkM1X((NwLH(3FipKFPpbS)d)VkY`MFAJD>3PQ#V`>Jb!a! z9-oez%Tkw%D$}y+vkc$t{=U-F@L$;Ou$tw(kM`wFXPJF`hW#k1rPU$gMk1-TQ~pM912er3L!PtY>AkXV&hl3GHCGVJHynKJR} zSFzf)yB0-0Kh0!YQn~fi?9lFch2OqDtTbzWEU}bnv3}|1)4RoN-*l($)SJHZR`8^s z>LKy<`MKMZFI&!=VA0Z?6SX}0&zV+>*9M~M7D+1--9!T_1Gntl=Owg~`GeTOrJ96V+BiNvzLc})r!rRYi`N$S+ViE@x511yf1HC|6^lDRHVA9Fbf5nIx${;3uM5w;Y&u&`cV3zKS+UUH zrcrixy}u;x&%70T_4?VmZGYx(@|^3N#dFB|?3A5*j%cdhiYc1=z}@HLtEx7;Q@3}$ zPUYs0zVLavi%R|36<4RZ+Z0%_dRAt}FkG6cHdp8UE56dU%yRwkugj*rb8i2&dzE{r zcHq{#W~*0C&%R=HxwcuW!nh~sY~!-XnSmzhnQ9#Fr^}zGSI(LoH2c@20ISoM-amSt z?DTlilXU7Tzh>d5q;JPRJ^#Gf(y@4w(U0Zf+KcY2yLakuZoT>J%T66BAHP0+`n!L6 z_=7)lHub2UO}l(jF3!bK_&8TwW|+$VH;R8goMH9-cGXWRc>090rYx5F&U1z5BqH1_ zp0+AE9^CnP^V#m?os-U(o;a=P_gUzP$egXO>qQuLDh7+KiP7dbnHiOmS37TMNzOr~ zEo};mG=j{YE}eYb;((v#vYLWVH+~82tCU|5;VS2x!K=t}_NK$}8*S6wEiTNN?c#d< zv!jx8(OtDSzj~JGbX|~g;&AKoTmPN0>~Y}~+e1GDoH(XU z>WupINrL@g>C9u-qbo~l=Ox9n+i)9h;aIEK^58+LU7$Bex2E?;7rDJQyXGyQd0tuk zvFvNXW9b2wVLr3ch4~NJyR`1j zZ+~4clJILi;{h?TjeNNlEQ0ImkNs`o>s+p!SSlg+QBJnEV+nht33>q8^HSE1b zAssJ!tYr=L**+~0U&lTBt0ebaW;sSFCyx8Bi*+P*uBE?YStRkHqx{tj`E|n4_758R zn5RfHHoRV3*w>)3?C%zuA zcWC~3WhK=)O`5ff{l&h%l{?1KTw~^IGhdZWLOt=`3YfA9Lc+E;8FuC8*P-hF*~e*OF+xo1nxL~Hk$8sDDt;f~SeU=0cL zceU{|&U)FJ*3O@(ZM*F3`{e`l|8s5+Mi=!47nPycUyt1<_WZh}&o1XS>R#|>$ywq#v+kGuGej(`6 zyw_5-tE+=0Z_Sz|^PeTyDO1czzMSV>QkHfn&%2Z~>w359?Xz84WRrKT|LAnz-o*Ow zn^|3VZvT4wWLe6bWj5B|CP~Ha?YtGZ;DG_-3&q-5HSk)<)mA*|BT>SF^UTcv@s}L_H}XM za;D{~cg_}1{A48aE$~Wc%m)i2*F@#!Gy#_INmid$>D8*1*_y1G`cJLAlz(CPUgv!N z*~}JV3V$MJUR->R-Cs-nmRE-Q&fW(`8!glf4J?{N)YF1rxv%!Ow_f_|XvVev3!Dq{ zc)b7YnLqQzeUBBb`wtvAJNaIY`24!s;*Z=_FJ9-~wO?4p-`?`8Zg+0pfemjj)s}9a zT6JD)X3dnsx6p;#kf(bLw{Mo#FW{PqtMv z`xsnKuHAWiW?S;2b%!p_Jbr4iG5_(1-j0tm)43L?&*J0`TPND`BqZN-v)yS$cEgry z0xlgvx_!k3pCsB3SxH96^E3-g3NB^b{@S}>#&LltXAZ~Kyic>bOp;l@f8BX@ z!v`t`x|S{11e|Vos+~G`T3P0ef^hu%Cl|k7xLC6_{leknizm6xh~iRw@W}dQGpIb1 zFn-xQ+5LJtvwQ;2DYw8fj>+u|ht4^I&0UZ-V`bErPcMEY>M}Wtxmw5{XhTga7IDw5P7@jYGj_`=F7krM0v2R6LhFE*jGlvIndH(4zDi%T4&eXIi=uL+lD9mr5?3$ z+aAsN8gqH3q1x8fwv9Vu*B?62uxU11hv7@TAHrtrEaGgvv(DZ(j*}=&n`e<|Wqw1| z;o#e?HGk~1)27Y~+IN1twyhYXa7bJg>^)cW)h170t%tIDd=uQO#Y-!nxLqx6k~cj1 zsjBVX?1%a$2jo6Vg?4RaP*?n8!L25B;R@HfUab&dTy)U_`D zV%(v(Z(q4`de?;aBP7Mji_~=n%cEE~aRP z=l;7=?mt__c&=J%<%k+2TFj^@Rl5|beR1E*KyX{3?M=@7EypacxcZfBO;2^3yX%l^ zt!{X9#GW?a$gf|$v?uM}_5Pu-O7$XziOL4EotK5EeL1}9*6eoaOnZ~vzq6KpnR$M* zO{G)_tLD{dRnMJQpL+f1^7?$eI!FH6y=#A~U*D&)%QPov>6fc#uf4PM*l{!a*TM_m zt>PSx%D&yI&&evZ^OtwmoR>jOo7%LB3tzuZ>tAr=V)_fYv)j)Z*otsHE)Yq$FYtyh zZI1lY^&W+MmexxVX zAI4?H>(22PS}gp)z^b;H@zskdm2yg4>XUYD;0%3wez)r<&uw$Nm^?S8fBw(NP_RV_ z$0#o9vid>Q3PwFX3c3`>$i&EyxK{9<@aW>($3*L{_xw9-*VMT)?hUVloKBT*B zGrashC!`t)Y?u(x%)ri&x^n-%bbW^P+?RZVPdf`)q@T~-U;MkUvi9q@w#5Rv-LF?q zNDxwHs{bY~%oE(Gq*r+2LQ!e0>jh<*9~(F>CbRp`5a^mVvu^*Ns#?(+tjG&kXbYpdYtWFP0(Tpql= zS030Y=(h+K**nY6)>(TY_I8REyJg13<+=G!tT!)J4{K(cl`yY|Ye_F3UuuTZ7t07c zO_RkoFLD~9rkdv7TNopnx;7y7%6)d%NX;u>1=jQQMDaf>kyv=sX30Tbi@$kh(;GWK z?0&z$zPZbH?#mBlE9$+fr))cQtYJZA$Ke)^Eq{Jj1nxYg_29%@zANS$uB+AVH$+wR zUs?60T4DL!K$kTSWz9Zv7zzh=JmWbmZZ0J;?PNiu$T}~!8nnygubviH#rY^9R2UKMVYQ_f@dq)}VspPw{2Vlzh}Sf;!23~$vpNtMG7TPjX&oFkyGso zE1!4pD%bupH%Ya{Wr`)Xx6>I;wS3i43%<5_#=8i8l|KFnhi@*aI9GmDc+Lsus*dFS zzl@(4YAf~1dz*c*NSTmyy5P~C{x_RWO*$x2$WqhJv%c>5gWw0BPEAsrv~SPHlkyTa zpW2TU@oiB4HNhh8XWv2f`>E45&zDoLt5I`cZuWQFBd*Yx`NmUjepBPY#R(_$UTO)X zU7Bnc$J%#r`GKd?RZn;Fe9)ATu;Ds4p+07wgp7r`XuoIfEIFB$yjANy7rvNc#94Z{ z$2H}bTI0*a7qcHYs=N%mzvc3z+|p(K!aCoMH*DO=#uc?JO>i5lyaDIwkZZQDE~P&e zJ*IPC>+L=XxjbI$l|}E|^o{vNvy~-gPQI{fp*;VofMAiiMtkR~DL?)ZbRuJa>F!?# zeZ;CxclW!u%lbB(M~4a| zjY>WW=XR?oA71&{ZqwnZs?MF$?lj9l0(3#@$qR>X2wFVKWMyu4KggiBzDdy54#L)7 zu3*L1(A*!sFZsjC@*hQ?`qdu^DncYBKfPR~UuyesV&~d*zYMzbR@=>WO?3Er=x~$3 zzLXg+@@F|H{>h8}&H4SU&u-PS6*EG@&-mHCYLaq282>fu=Kgh4-)UY*in_YJZAJL9 zMZV!&Yo%8lUFG`BcIqTn(>-=tJ7sRE-gxKDtABG@+kBtg4xUJcmOi87Yn1MN4qWqG zQC~8R(JE{C@xyKRN|N?hisa4avX^`pskZp5NVoGxgWgX^>g9xVKU%X-Z@l^9&dNmn znP28jjD7Dv!CA-s`IlRTHw+U(=In?P>t4A!b>p4Aw|;0?%;}c>t1gr`$>x#YtIW?= z)E-DE99vjF`Qs$nJYC6cHj>p1FR#9rsNs?+(w%wiM}d^YgqM@;4Jw}SUnu1(;5XQN zNw(R4m-9MRXWy@im$mJ0mfq)%^=6Zi(`!;TtL0*2o6p1^=RNI6v+evZjR%$g@GeOFb6mT~p|y%XP=oJp0D(l>EO%E?P zt#QrD7I-E7+o@mv#p}sgz8~Iv+9}T|Frn75EUMDW`pbfl-Yx6SN-49fU}>6{aLKAX z=6q)KGJesBiAxjC_gyIr<(=pKHT0>*+t?*rWP<~(Ha^*GH;V{RP*j zhq4yBnXM?$-rl~hp-#Dq^Q(SD?y7w;;arYYU+zj*GrO)_6*K#P{#7&a`z_ksRt~Yh z)?CnfyDw&j$##S9cDGJmw=(7Wacxn^n*EVKeXlOD6=~kN_l|u+vqeWkH0v_0sfQOf z#&4HP2%Fc#F7o%wrY=*Lhx^SI6c{=#Pb%6e`~2(sJI$L@?rzzZ7JX+~<-Jwwq~-jV zKR;?Nvg_Mgxo~ll0J{?X!+)PgZrdyq7q)lW0WO7;S5J3(EzMkeYL?mmYhjPeE_oN1 zx&P&u@Q?FU#kDK7QP<`w-#nGR*i=L%So-eFP1b?#<$F>WuB`ZX)dTK=WRFK!GD6g z@#y!uHoK6s%sy%5$}Qq*Q@^CtBs{rT^Ug$|vs1#*Bj! z9+=3K_TeHYyVMRJ;q!TGH*LD`Iq7Rx(bQ0f6Qyn6QBu)r}f{QSKk|v(j7Nr>kiQ`sFM* z+izi5?X@O+t0K=f<)+WP9v5V{>0Ub1vHtUxv(^)K?TKx$xUnLI>D?U(Ve2gtd(5x; z9e)|_vF=%R`rYbk;hnD&Hdu1qIC?^F+dIkU?bnZe|MB6%8cpM#_lca`7axBOl}SE0 zp~IlLby}g0Ws|Aat##Qc?b_GE_dR{|@m|n&c{w-9WlS4A-Z%X=;QY7pmfvs5B%`R$ z^BEaDI^`c@A7({eP(7F$n1%+RbqAQ^tOh2Qyj=Qjgx3bV3HL6(?IyHuwb%bdKFfx6 z1xEUN`Zmez-r^aiHMvkLH8;2M$%G?qED}5t(f_{Q{>RS^vwI z?`L2C{Cbr?pLJ2jzI~vh=6M8vq=!fLeHK}&ba2YzpZ|V!E#Q5ze|F%Ozz=Pli5dH@ z)X%TqwXdsAbGq-^SEb!){=Z%KI=gOl`n;yy|Yi<7df73Yyd}&)IyUDuCn7qTBrZ=G*NT{&tRjcUu42Y5QmO%#Y6* zStM`VsBLs+#o49Zc2zwm(v>(W=PYPn7I*6E#)&WX#+-Hw^M1+X$K?8HT4bN=y-2^D zSOd?b;Mx5bYofK5q$mSl{UR@_Gi0Y{^RWA7wfj>KUL|RvR2qJxGU37;hMQs)~o>WuYryo z!m@6;a&Na~+;zIO|Mmx~@Qlci48@1LWwhtc@yv~0p?f26Q^vIDkoE094}IVK@>amJ z^*#(X#f%oe)rxx*icT%6zHzTcYwDkU-&bGQWcMy?@9SN+Y;U@VzstNk{pvB%0&Ql| zZQd`|IC^Y5{4{=3rPJ@K(v}RLnt zZ|9`z5n(lozt$Bu{hRA_qA^=nyUopO|F2)`%ANT3I2~xr*L%*ucc`-X*E>$D0xm`N zb$eqv9~i4P{^PX#z{SYE@8BHfw$H`v`&^s&<~W@=xZ}sxg^E+!6vX_Nyi=IzTmQnZI^1 z-H}e6pY6{UQz*T2&1}&q^RM?bbe=3*qt$z)?0D-dxBIo`zyD6Z{@p(Mg}LPGwa#y9 z9gX@PTDsIkZoU(${qyGYq;jRh)zeB@udXX`b_o9xdF#su%gwgx^O+>{x~;oT_@7W` z{q%ELMtA$J6SDSfE95MW37k)wf+Qh$+W;f~` z=VZrxIVxDdXnolK!}(7S>dqz4`6O6qrSVp^X-1lb{7rkkcT&w6YYiNqn7kI%d&A!u zn;cmnOwA#ZXnh*ZnT*KP$DR<{wf>n^6(zW?X34gVhEPol1J5R8D zs_9?Zwj{2^Cy5&TU3aH%d}JWf4-Ue2w<8Lr9_xhsoxr?apx}YM|8s?qf8ap--}58Y z!ENTrM1%KVURK@Y`M1?b+_2pKcc`av)SH8@uY(Sy9^;wAd?s#ZQ}*1wtL8j7%Nio- zAl75})xC1V<~zOxEzhL(CG66j7iF-^epOiftbHezu|15gl@ESvU2NIhc-PuOGDnZK znEC51{^Li#9~Q9*YSNzFTh40vHf7;0KC!Q+`aw^{Iiuwk$HwN$shb5j%*zXJP3X(K z@j|Wonl%Pnewcmi^upDV|aPzmC2HN{lT+T=eP!Zt-YvaVtoQM zb1dK-D{1#3I&$qR|5JQ#RZ+1JRsoWazi;WbO2)x|rv<;9FHociMPZmUaK z(GoxJB`1xT&E`~@t#IBlLA-WC@1;2rtDs| za*NQWNxz$Osy>-kR7Cv$b$a>L>qj5OzqY@Bzm{pb#L5$YW2aq=n4sdHIc>6si%I7R zqa}fER+aVJtIO-Zcf3=V`!3mUI$0$-B;xzQhc_&I4y!mWujjTC@NU%beig81(xZwg zuI{Vau7rNRpA_s}l(Btzl$IAq#nI;F^JI2^i{8q5{=xoDtNU)5y55pys1W&b{*vB> z>X>cTkJCJ+^=yi{{4=AYvrtXsSp3A;>Lw8e&b6-}KAgVazOM4uW3JDiK5Y2)_4)Dr zb&-u9&t~#J@$S)4;kwwSTRU6Nu{f`(MSJp=mh>slB^EDzCZs4n*Pc!CjB5|4O8w;2 z+qu2W+aJq4d%Qz>sz8n`&xr-sT;_4N#+2vAZoj`e&EIF{U&hGdS)3O(h?w|AwlsQa zChxp>MKa$(cbC6c zU-Y)DHGA#uw>Wzmv(s}TH+&mrPU!g=RoZmes_h|H zX|1JF>~oXPhfS;flJDjoUTw$ySXanXrsiO5RZ4DLb?4y^n-2F^8TefKTD;VQGkBf) zZLtTww`ZT@c`RqOmv1@)|JTI^@f$W(Rs{WHg_`Sa{|LI-tmTJ~>DrtKJ*RhBVy1$sFB~IJ5K2hmS zxL$?Ki|*KpfA;PT<#J1oL<>+2f+^q(f}CUd?k@;Yo)BWlU+$aFcl^ zoFt)`v@E&z$>nRCOYEG}cc%Z}(WPu))_j4_MDXCmiY4otGc3KJECfyJfELwf>OT z-xPY}g*y^WDkAwVzf?OkJrH81>KnBOg=^#6dVbDp;|yy#(R!|FpL{RPm9y5?RQf;A-7$65n^nDcCiS+kFRXse_iTFDWWFYbdw%l` zetqyPJ6w{qK%UX-O5n7s>zImby;B11X1lMdyC8M>!)}@Jeh)F$C((iPRWi#}YB(RtdvVk}KPYu?PXr`>sVdy;JASTv#^ysa3@>agUvefm2d%=dMok7mH!pAYOl51cP5pU!2S|LfP)f~ft@YC79}taeVGo8wi| zwBq{VWoxhAn8s9l_FL~pPiJ55IpBwxWa$spGHo^FX^4^_4~vB z8fVU4_(sq3RRu$E$wA@fg>xq1eZQW zDwzK&NPlhSw`F^E||)SNyXvQQ;nK$CRJPw zdMH@V=KGHyn}#F^ru zZkC5{U;6opY3-6$=YLlk_QeJ|J^bRjS@(<0FR3;2!{Wss2zwV5yfzkFprjq#nA&K% z`1H&90z4~XA7AjFA6(7ZlpZW~c&kxKZ4Cdi^-5j$Vx~ouG%kJ@cQl!$u4%V|^6%ff zbuMqeWU-X#-7=*`ocA7H{=C;jW}%VPG36_>cRx+7U=jb-suWZ^xAfyi^KJDf{4(t& zdD+eWOEdiJJo%QFD>W|#wt*!zF9qD7Tv$dL*)2< z-#>g`GyE_4ga+Pu#>=wormI1K)$N=2a&mO4W~?YV;B&s_wUeYF?o zdoI)Nr!HU1B(UITNz(!*UxuH{_ZsOQHEM7yVO`nqZn-c=oW*}j*9S|V?HA!NToC!$ zzIL`>TDQ{bQ@hUeEBxJAuUDQ>e1qxN=c$bkCQQFtSFCgDuMNW6m)duf|LUKE zhmO2vqK{=Bx0mn!wANxzjS%0QGfGDdOr2-!&3~hm`2D=(AI6{kyQ`ZxX14yj-+hDk z&jIgu{}$~x{rIW*MAn{?^Cs_JrpmZ{VY$pd*KFF>P{(ZET=mYs776-)6!w0y*>ZVH z`of+}reJBEr6;re!aK`Pv+gZV6lE>EvRO9aON01YvF$M?OCLMQTo z5i;}ik=e()pK>S`CGJqplIgg{E>zupS|+X`*Y{E6p{%gl^xI;#rR~*gR;c~@Kg;E$ z^iDhi3eUJIswL5yPzpmVN>2tB|eEA)-yzgw4(0TRI zY1?l9U%&TkZGC6GP5;Z1_7_#28@}C44(Eys`oRT={YX5nhtWb8?F5Ic-2h3xTMR{kGmXJ zzWm{N;CG+>enX>EuVe=Z2l5U+l5uC}gO>i1>fRb@yMv;Dak-|Lt&J^0~u4 zbOJeEOz`=qMl;2@6MvMWY+}@ zF{eXJL^IkJt!gM>FZs96;pl-qU;Wj8w&(4BtC1HmStDtlW;>s7tFQAxsQ_Nr>*r=( zigv%gX4UK%1=e}Bzf=z}{1;wtkE75cdGdhp#zN5cK7H4U68GSe#FA9V)%MxI3_HitNr z7$^L?>OUpe!-8W5zai_zLK~+Ck(M=g6F$VOGVc&z3|zF|{r%&K<F72^67CLRd+Qs`-f%o;Sjxx11`X89$B$vRpNcwAFu(9*s!_NN| z+P+QJJgoC!+UNap&u{;JeYM8!r|~ae$F;YoIB0G7m^XLt(w^W6bH7C@c`tBcSiXI+ z&L);6Gi}~@PguUdWZ^WmYhK5rPN?Wl(bZE~5x1nsTISRDH(zQ}o${|8HW0AMIDGVZ z0jtxAmeVCWzTe(``|G1!ePWsRGD`P;Oo4wa-#q*M>aS-T46n_&V360oz;V{@I)*iy?Or_+a_;u=3@_(DecOIl7tiZm z`LDA+#@1F{DRQ_gn&mN9%jW2gX8BXs-b&xeJbwIUmGD||-=`CIKYZ2tMcBN(G0j7e z!6C3f$K>eYH*B?AcyG-K%K6ZEK&=0Fs8?rld6o9kzPWKZT_L3=%V$I_xZI@qK5}RB z*XpqQ8`*5LA4IsG*OJM;vAIor^~_^ZC!}LHMt|Sd^YUE4B(_fdVzpYo@R;L1vYX$` zzWKBxM7}6=30vmXzc%V;6_mb;1if!r{gQ!0a6*E0(=KLrx$;d6n^$RVx*M%}Fh>6M zxt7A?QHML7P8^yQ-1_|XzoT~B{_dV=pDHMSpvA!dEa%_l#~XiMFLtsw+3aNheult_AwG&$jNs_=E2qz z+B09gT&KRuEM=-q**7c6b7@yOt#W(z{H{6i`J&~=!-uauUU;JJ*wi;>3YN2ZTJL;s z%{H?$HF#sY=Ph64C6jxR8&{s)U%aFAozlHP)*rv>yG&ok2CkJT7rD%{X@ya>yydA^ zs`sZ)U-Bq+WxxyDW6R$ZbgaEy-?3z4WZ>SF|K27sOI)iyZPO8u&vNbE+P;9mb?@@K zgH^jt!g}|tyz*D$+S-3lT)WR+cF}G68}Rk(oiA~mIkP%#hnyQpX9?`dBPF0?(Hcz_}Q>Rr*-zctt-CHh+$<}k@Qcrh;K`L*i3AWz4x zbG_~_)vL?5YA{ZX((URre&zk7%cXNC>t%*tcPw@HxJOR0isrd!xvZX@L3Y-fOzcG; zcpo&P*cnvqHACzJiRK2xHrT>r`)|7m)x;Tj{DnCct-IU5 zK0GjWg(-8Vh(^}jzu&Kab}e!(JN+$|=}6b^Wy`BpRY!a-E3N(dOD%2A+HKdvZMYWq zxPDmwck0u`bu+pyPw?J$D?Z-!jo^p+-H+dVKw{hIW3`90&W)yEc|5IQ=|$Va6A=Bv5Bb7md+ z-WZ{?vt!ePb%8SY*?9eO-59O%RY{K3JU5i7_2Z(e{!#+g z2XgOjJ^O6Sx>xSsLbl#rdE@K?;r4$OS>8<3`Vz02r^xYrunS1r$YD42_@-Jd*;ikA zpTAo$P3y_V6E}lej2>@G*=%MZbNcc!OY89VzF(U?@3`gvNSfJg5wTT0VQ1>y>6ZkP zuTH%BH25ad&*bncv7seT+iY#5&+NJ>zbf|Tqazg>RcRX*Zh7-+*{c0hadZ^`-B=cE{5#vt|Ux zzFBp=>XPBdNX9<#92MjJ7n$;AINz2zwQaS-H`XntF=saXH?|h}Q2zSzx&q;SBB$ck z?aD8GH2qIAp9vo?t0Y(Lna9#GchcFwM%jZ+8>v?&`D73u#A(7 z%^429TA7CmN&?0UukE(jWw)(8<=XPd8FS|c^&3d033^>J{b6y;QMH8Eu5X>c{?!M9 z8N5O^!Ac+VrW86|yK#JD+HQ^)zim0Ee&Ml*>A2i>Oi+)#CW7tA86QU(J@uMp$6oIj zPe?z;WVGXSkPM^DGlAOki%YvaBDQk0oK38JP~1AVWxn+8IM;vfW_i_VMSj-5eFWs}et{ty6niWs)NI z@~2I)*J1IuP0v5eyS@&eW^^+3L)u0k=DK%cAuG<^IaD4YoA0^ia+3Z_-Na+A)Ansx z|GoKUV}6NLX1|Z%uf*vlipV{2;7g#GdXzn^BSNi2qN^|YbdX3xR$LjjU-kyHv{n$*q?6}+hck@m? zfBd9&V*AW(8|*DgX67sB{yT3J-T%k=u<)0qA*L0-ZFMrTR-2j3Q(d^WY92@P`CrTX zHoh{DNx1s(*KhvHfJ6~_w-uOz?Nv7pA9)qt<*#=?H?L)&+M-8tj4hAorP8ATTJc;6|9 zHSA71ez+puxyIkU-9Y^OgPAX`H*l&3GV#pV9~Bz@Qt*rCPnl_~ zb?OPvAEe(~*M4mFzGT}&DKlJu%sd+T?9exv#toJitZHOdA3nQxweoSsZ9SR`=0{Cg zd_`O;a{2kj(2K_>YW;a~`|Ag*8F%J`G&+BI+`j2eenU4$&aOXl5wf*1((}3*eixkz z+@DcxWR&~#uTptja*A$|YUl@TiM6jd;skWwZL89{>3sEIf6;c!eUg*M8DVjrFPxW#gjhrj&7y{rMZ7HjVLCgzaYzr5g9G{aKc zz>bwup6}fE+931dhSZMMyYC`y@Y#Oz5HZ}7l(@0!=5x0vzZHz4(hka}8isbKr!lUZ z#w?KaP;*WcpTi2*B^$CV85W9#cC0qxO@6=ioZXsz0x}OP7j?{I>zX0$wLV+$#79z7qrqiaFHO#d12Qt zCIKv}Qge92^G>u(e*J#=@uF4Y6#}lYoqP^2TbF&Piey+SKJU=WRK_WBE{e5F1=YVQ z2{8M!7%pm5(Aaz6wBzQV`tfhrd}qB5WX?*W-W3_q_Yk<}w z%{^UW4l6sB7idK>EL95ZSZ%`X>bJ^6!Ny zQ+-wpOJ!yq(oScbQdGgUd=6{CDZ$nqUcztRX*}gKD^UB7JdJ95VO*V**PEmJa>mM`fQc6!9Qrq9gpgvXQw?~ujcZ_Mdn zIS}Z=IFE@-L4<{Su5YYwS>67!^X)I^&Qd+xR=nw^g`)JV11HlSx8zhXY0vHz-Xy4c zL+G)A>RKMg0+GOm~iHDxBXIrlWr9FnMtdsI15|c%$YNR*FPb3 zbD@*jB9>?+{?C=|4;eh|7@i3U6c)Rg`OOtPb%61L>>b5h7Ns3O_{19CC-~nywldhQ zynvyk-MjGaO|3JnnK_@8jRW4k{Q1O8sC%i$*|}4e2CyxV%p>#XRt-Rqjd z?wjfU4iC+rwf^1jPrul@l2^a|I<@DpM*o8N8?R(j%p#l58}*5=wl~!)-J#QSN#pB= zx^+#V%=g#b-lcszccb3T*zhZ}7u}V)`8=Vt`g>*Kr5TLL{S#EVg)L%4y-p_GurmFn zc~M-xH(*1mk<&zXl?U0{LTXd<9O~UxF8y(SlkKbEhUvNB{oxNch3E5fVH+_u1dRyL zvIS0^1C9(0QBT%|4p11GSr9p`zb5>4-|Z8Eweku77RsA;ub5u@@T@;~`r`xKDZ(jR zPB!o5m+74K&`F84bCYfT{JbzzPtP@vB&4N3r2hJ{QfuDjt5@HLe=oPM+u+oB_1ix` zSEExdPwEcu_sLn(=b9zFvM1v0`}ay8-7{(JXP`&C~z zTAJPtv)T7<{;atguX-c)%6Wa)SK zzRr;?G;UlxPU#Xm3i&-WtWY5#s2I0KmF*vb7!Ez$+rT9UXCmVT$e;vC@@K|N^%7VF!nUX zC`PQDIP;On69Gkkp^M8MmF|^Kckqj0(z+PSxAK!4PgK^GPZ#9ApIufH5w-gAQR~aH z7i&JAf4po}_go9vQ>9yL*S>mQ5aPd0;zdi2Ss2@kJ)()e}7NMnuwSN3eLr)I}zURika(A?R&|6EOOs1(j`$lk#5fJIre zDS_bu%VNy{1BQYo!`3fTwYD8B>QMA&GW2S8@VVcwFtaz+#^i>D$qm0fM@+BhR_eU| zdZe;@vf`a3H4G1)C~G!>sKuHAb_@ld3|kYHZroB+o(l7##m}B^_nL*5TVH%s@W|zM zhwnwPr1*F9m+>tybw1+B%6LH2BZvh|1utk~cp#F(bg=A9~&+ank9)@ZJ5aOf#}6~O~9-Gf;EG8}m69=xEA;lY<=P{Dq` zQzq%ey*1N82FWRrlKMpjXsy8X(@0$$`)yoAg z_Inxi=ZHD{72O>ndw%JPZF;Y))w3&Ff9*}qcQO3W;mYuwcal;CGs7J746ZM13>NtY ztqDsPo1Z%p;H}%vvwZsR7ne_euG{eL@QzLkS*a4PPqmqIWLL#jK4zb-_N!WVVoa3M zp5j%LcW@XRxy{M8&%Auhfgzb^7E^B{!!ZdSRtaXt9>X0@8-kv)hn$jlQgouAYG=RQ zUYq0|lc~p2r4qv;y;E9>seM-^?*A(E7PHS;Td3A?Kr-%D3$m&!)CBoa0w< z{ori#{Zz8X1^$nBwEMMLv}O12&-?2D54i{Jb3Qfu?JA#K9hCBOhvT0s`{Yh#Pwefv zo1OINhxM8juY7;{nnYi;`5U+{`VFh}cY{5Fciigo5=GbM3+x9bWXB#QJ;2y*$%Iors?Mo9-aOuLbUXE*j>SQOYF9V23LQ)J^hmEro6t{ z`#XFqHD3FM+LzZ%^bT5e=l$36(?1`WRg~;7t~%U1cTw#3#N{3g1%8T}O~DKYEL)d3 zEN5sa<_hKryY-M^!Pz61Cp$w+6o%^>t~cD&kF{^8lM1_@e}4HP^UCGVSJvE{ZvL;( zxZ|txm#@W6I!Bdr1me5y{tWx;!GF_l6+eSt?IfiYAZixVRd$BucEKL;nI+Y|3UA9^K_49A3l@`-(znXnJRQ$K}`5QX&az4TH92p)<&SJ7{W;kZd!&d^ltLT z7oAV%i*P(}QP*sG!SKLkxn@8KL%|~B)`X>LHedZa&nY;~Q(5HS?6N1Y#9Tu4jOoW+ z^;u=%n|^ORQm&pM>i1^9S$p_>Ew>k{O&x5E&F!;YuJ7JF->7PU^7Z75eCQdBu(W^VeCq+RK?G z1#fA+G5z=QPZdw+#_Y;=?%(q{`t7s84Ls`vr&)r_-LGkhO1-&@lV@(;#>kK^JxS>X z8^fI346ZG_3>LQyTE9%qx@X3dbYe2Nddc71dvftdkF5Nh&HA^erzz*P1+CtkQgV91 z{R`Gf25dJtKDPAc9lCo%t?Ngm7~`B=kFEr1hJtMiH7}SkJjgi=D#CrayErBv`;&2) zaaVt9!_0oyltvCKjygY>J1k*4 zaHK9v(q2|)d6?R?9~LP!ECGxkUVmlW)U#qfmjHuH!_22MUwf#Ys+W7~x5=nLwsG~r zwb!@zZ>sup?4a<5D%&Y}b$6%S|MO&b-m7gZvg+%sggSL<`MjU(+%dI*^ZZet8wE=i zv70|%ow0CIxmM%iHyjG9enjn*+?97^`l}oBy64`Q_qz1;tb?8w9zPb!zw^E9`n**ef@2Wmrq8fhj%4yww%_t_w}{pLrp!Bb*V59hq(n4%uA;_v*G`85?& z-(8-STI)SEt*LL7!PK4aW+i;@U$a{=$4u^o^V`+SZg%$9Mcoj49b~iZor~!4vz|3^ zYwYam>I#Zhs%+=}xbSt1`o|l+Qdf6;Fth3OAnV^LWerrwjkr znq7-4wJ+E2D>Ul)VeJ_j zw|;Ez^Zd&rz0aS?^Urddc{Ovr+-gA!6<+_Xn#_y6*^RmwfQW%_!gGH5Zd7V(8yTQ1 z?}fIt4b4r6oD6&u?wx)lirWc%L6{gwTw<(_|FFsvd-cDQXMpA91V#NvLV-M&5o$@qs-lh=M zg&jANsw)rPlzmXYOYF_M)_le1lXR#3df)y0boYblSv#|DrQO~5`u*+OX@|S2j*8uv z_bLlrKl|>s7ps=d)BShJO8AOoYoV6N?8onqs%x8XEIQbA=fpoLop;`5leH=`R_)R* ze^z{bM*QkU+GpBxckXqa6!vxj!|iEzYd0r-KN@_}YQmO0v)Rvfu6jSibWLg~?}FUT zzvYa~W^+r%oSn2_-rt=+B7d8UFFaA1^LF#SeIlE+Za-aDbwO_1n#jdMy0=^&uDoG0 z?cMwR|Gqu#HhyPY&0fWwp!Mp#nAj}=U6wYElINL9TX{3ZmY-wm@GlT{{iCpe<5{hS zs1x(K{4^gG`;HU|Nnslv8HqDo+wO?uo}Rb*-Mp*3)vLxapg5&;9Z>4{?2|5W&%Zfuid6mk;`sI&R* zqImky3Gr6jxdlZ+4<4O4Y*8fUAf$G@afzUYa~kuJ6Vazk&a^z&ZU6I}=}mN`!=x6? zud}YT1-5XDzFl6u){{k&^NOR}p^KjG%NgW-w~IGrd{^3d^HlO&{$2OayK|S`&%P9( zF_XW_H)rE~hFzM|o^D%XeLZ=>+FAR;xAxRWA3k3=d-8_~3Q2m-s+*tOu@nDZ>o@1_ z^S)VkqQ98Uez}p!oHdryLtR_3t*CXOM|cx|!lyfn8DF|F+`KyB{^hFyP0Lqb4BX)9 zbNj`MC6gyJh^I@uT)BSrPXP_*XCSvbX|DSCGr^SS=Xur}+cz=zhdWE##GZYQ?(pTM zTP1eQx~Cd{`Rb(0yKdb!HTn6f?OFU4p}EOXC$Br4x*79PLTdKSik0Wo1o9r6g-0H1 zX8$eeWyU@4OuBN?h0jyEzG)xxn5!^%jWFxo1J-|Q8G>2mcsfke>N}w&&wTb5{$|WGc}~s4mHj5i%<|QcCPv{(eKmp30s-@ zrz{dU*Q)H2BA#j_u58+KX(O-gT(7O34)fnS*-uaZ^aJ8a4_D92(_VH-eVWg`K{T0h z-pOXO3bp?8{?_4pIJ6Jnats%h`=wxD9s>(BA`Ste`` zw|CEzZQMmO;%rk=2oQs}!M^vuX7_?K?{hxyzF`K=7+r!|;W zY-5=}|J~MQ0wpSI_^gEb{H&~4EpoL^PI+BZaWy1p`Q7FBjq>VWER$-Lnf32Ae`sly z`d|0!tAf5oh2|Ho_0s#I=@{O-^l~V(;JKvus}&5})H1+{gsGa#vX;GQK-4SGQ#HpJ!rss~uujSBtO6o_fYLrp;5j z+G=Xn}9`!Y%^ZF|Bg=~!K+1+25v(w+Rm#%&Hcfq>Q{;9QJeH2fe zagkjjZ#&m(kLQ8R>c)l&r`mt@YyW*;fA!(fS#3K_`ZMiPmYrUCCb#1E(zn?H2PJ2) z$nc%k=}h^s^JZ@My436ZPd7z{pLUY(O-uf@cvbk>;_T~F`R50hs0UrBta#sl`_>ez z0&DKdL+$Gu__t-u;@y4eU~Kc}H@liIZ@IB{OLF(>*RyZ_vr8#gQ00Eyaa8k7q>t;m z<4b<;ddMuYqKAD&^PPH0CC*m1r$S2;g}xgeV)?iC&Q>cfr6+q$>-iZH9JhF4ue*&5 zQL0DU*4_Fch6;v8p#3(`Wjmy->M_DTg>69WUYIlCfyIxv3D$k@`Ohr3ayEyeL&K6! zGd$N7&o!ytaLaDa?*p4P%5Dzx}%R z@AuWOpONtT?ccd4D&sca`Ew|EA-A6C>X4JJ2e1A9y?c(Wbo+iAj&C+I@@>wmM%&-~ zzkdI{`>FM>=k@))knjKI;rGAG>yFPl+_tv9KJ#Y#;cfQsW(QxF7kho*r)TSjZoQ?C zqQp$2#bUypHh%Tjo7XwZR?L;}!}rt^6W6Z_nk6E8MrDB_V!xBvEk_WIk`4=KV)YNpq8ra7g*$-K_P{QK5iyUot$ z_mv#KoV~gGM5E-B!3NvXykEkz$M zg0qldRO@xgvTU)&vP0_|%am?hbb8KUzw4m}i;=9W=AAGPbCtU#CgJ3@e$@T&fN3!Q9LU)t8nv_n3KEyTcNfo|{q7`>|945X6~CD#f95UvzstH*f4A7|rQ$5b zhA!==HMJJ{y$-*n%-1Y3f60Z7{dudW?OJs@=Q6MUgf{7Q1y{F(?GgDA`lalPR+jUk zuU$L3L=ME7B(dg~GhW#E>Tl=9SISF{uiC9z!FRClX~Mcf->U*|X8iZM@%riC)lBR= z7&seDQs?frxa%INb%RaiaK`a%nPLL|UI$%W1({nv7*3H;6j~lA89XZ~v32ABwG0-y z3<@0wpF0RJhpP9~3Nacg@c(gHH1~r#-yiMGFLY^v?`?ZPrE9=v&f`|X8!I$K$}KDLy_Rlcmv{oDHTPsfEjKKuGS>y0kN ze!lYVc60Q*pu+i_S2x@(e=jHgKRfDcTMI# zj*U)h1m0SHEPMEuQ|gN#ht!c`i`$ni4|pj4S#0~3U+4MXLa8r|lT21P&7LgT^X4Sa zl9|sJE%>uo_T&09jB=q1mN}a$Eok9f6!2Kj=eoqr$(ABslWZk!3f7yxakQMQ-mS__laxgc9iOmTP{~j<#kcD*_y1_dg4c`=Cj{p+ zE4r_+a_pPH(ZN{xU^3&|mi<2;_@5AzZ=9g)GA%A=0*7gqg`NBct3!YLORogmJ`!Bm z$EkEL-o(3m!TG$7#;byFJ!BKv9+bMUM7i&2%9vKjbw+7}v=}%7-Y}hIS~s~}OaJYh zpY^8?FXdHKJn~O!VuYH@qKT=qpIy1L$UWXIdu>p*uKU)xcIAg%%(7C;e$Ekpu|vn} z=-JsU$GaxXo#nsV%wc)v^|%9lm+iK{JZ+kLsnaYn^_HyAOqRgEOKpAN`U{>?Sb1O^Z#$qRXZf^op?rBbzj6O zCF?IAB)!Vx=a{u0f41Qx|AY7Q+TVT1DdYUd|6W01dGT)JLuH3UIo_*^OT{1ZZZ(}= zc5H{8Waj&*nL*#gSKVtl(e|x!(cPz~Y8U9deXHRey?eV6(*Ldw)9s5J*uvbmBukrd@9J)f3lso_n(V z&?(T{@Rq+a;g)fK(45&Rp~o$a*X%M{vulDDbJ|w_|DwC)^jgmz(3$)$zI^$+qXFs% zXDOFH6_R+y`DJnHg{7xT)f69n_1UHKd1~9*YVTExrhUt0lTE(Y*Jl{G+q1dfkn4fY z5w3fD@)9en>YGApS(-vV$~4KIW@Hn2`2Ot-`+{ZPk9%Ha_n5S*$xK<&#d=a>{an>Q zdu6|_-?7e3bj8b#Zyf=LSQ6vYR&IU~Uv^Puv8;90=7x$}cW0`$Ft&a$JXO`=aYy4a zpVzXuANRQ$e3=*&d20At3>Lg%Npw(BV0+SdUu%o-ziSQliaa$eP7(rNmu@M)Fe~rLHOa5fY~r>ppWqiG zE~-&6bxxl)-1w0muP5dW<=yxjBxK@ zX?KBr!AI+7JU;a__I!4{-7c9Rzll#8Cdv5laYsG$ed(CVs`vl*7aP;02Ch;Nd`voad8Gw7uo`Tn9ZNHEh9VV^s0m=&~2DgY#9DMmv)nL`>}e# zl*vE${`&vt_fywzuM76y?z{bT-km=Y_jALS+}1hq=XkRJzMN^d@9w(IfBS6CKmHpt zjGu4TxIJldj7aKPm6`R|t{q4#(`GS!u=-T&C`pKhv&jRhX#4mI=L|4xe1Ne^11|YR<G0l7C zTwav5bRJZs5MVq{!mL z<6mnz&%U^>#M%%q$gqBicCks5gIsSz_%3nbUvYget`{tB=2>z?P_32I>BI)EVEINH zspbhbkA95-|MAocIl0E?4_C1CU)p%nljWGmIrdrYlapNvgg$uspYBn7Y_$5!RH3D-+U8A9 zbjdx_vC8ehZE8dTF+K-;fdU5{ohRTLtv;XUh?XHtK+vgH` zcIGL+*4Zx;F39$^-ClKN#f@9fW{2u0q%ml&tlN5l@#v|Gj7yh1GFUd3`@&=QL(NmU zb4)LHPrd5DChnS3&DTqhx#L)k=R7d9vYhqAvtjjS3!lXo6OCI9%u=L%woKeSMc38M z;PFF`|1k}A+T0#Iv(4I$Y?yiK^4x2hEODHVnb)^WUfem4Y0o>usT=wZt^X_^+-bM0 z&7#rhrRljTdnW8zdGE}Wt`yneqJ&eD7p5h8e|>qjNAl^Zua~pzZI~?8Dhw+mw|*8} zdcx~&Jns|>$61qVu0EeIy)-!WSL5YA=5r!z8D#gIUnBF@_~N0$4KDMSGVJOWl3Noa z?O=KNmAb{{sE*=gd5kt}>c^7|UPn3IKV?{ZxjJmWn1zFM2g939?eiALKE1%PSH^nT zWQO|Sh>Ke^ulXyk>D|REF!44=kyyQbZ+pQ1n1-FXY!eb{rJb9;23Jb?`78DC3bWTK zU-Y^mo&F{9;%b#X25!R^`yvys`qzF+8-z>kHrOy#{yE^s6!*QVb5qdwUu#z{kPZ2N z+v&%wtIlp=`~~UqBE}DQ_a1&DbzT1D*Z=!7Z&*CID02C0l61Yw;qM<`6uQjcA+>AC z7X2A>JfjW;tDk)=TKh)9pzODQ(>uJx1_Ysj7p2*E|ijWrN7Z40v5m97kcgbEnVb?tdA>qzm zMZ<|pKA8x63MJ;uuqa4#&`z|z|3Y0&C|l8RqROHzpWTEMo0}g0X?XhZ*Zt=gecXk* z3o3mC9RDk!lmZqE;8LJT%w^FRodTi8(ixu{pFVsV!915`Po7hYqUXmm(dtLGpKIG` zbg;McYqr`EEhEK4F56ywyK8y)Me>8yy+2Pi-}!dGt#}BdHH2lYJb(1;8v_aX<#$B3EV}wd>D>0)qCXdL?QS`8^6b9bI=k*Vsha*T zDz?6y_Ql0V?m*YObDP4>s<%FV^6SEU69>~(hxt~B+m^*B-Mi8?-z7F=>H3L#_tbye z9T?gudd2|Y&DfFCpp{SK&jCB^q$lQd;6;E@*qw{Yc6RI8F8}SKoL_kxe{u8keqFfGMzD@g zc>f8HD3&^ptA!bNc7JR-uE4QqHtWv3ZM&yU>`v5}KV{*ShkMPY2iof`vHV~@Q7v5B zZHfC2N3TOm9}4kKZks%*c|q=P_J4kJgnxNXY)O&)>FJid>DS9YI$tk4Mf`r&`Y_3p z`&DbV#pioEhin@E|Bv`vQ@4%huZD)urX_VO^({)j1U1jD_OFkt`C0Vw{!t^I&nK$S zM{Sc;OzKV*S+eu{zLoM<`&|X9bYH(a*1JWfQL;qSz^wS>TJ7yVKmG{jO`p_u;QtnZ zjU7rKnpo=QEOu6uyz%qqud~ILUelOTo+LJ;T-Nv!yz0w-afa&-&;0_55)Y{H|FyaJ zEAvsizJCBm;=!&H#rCt3S3cE~|8(g5bBm0f-uoB)m^Yzk* z5Los|^ZX0#ox%3af6TW}`2F*;DYeFD)}^!*A9IMmxMPNZ8( z>^$5q;dMoZUAg?#WzF^*{z2kSMH>`1@o;tQRyz`D^*gHP&etdYOg>i^*2QJ;ub977 z|8$r1!kh!g8539Ld~n=6^OV`u|8Wg#VuTp@HHxpAy=)d;sNFwX{mQfiJE2o;Uk=CK zoij1us`sn(0FNYdCY>7s%l=vH%oN!BX`$}g&{l^O|4m#g1_&DRlTALEx%kK~CiuE53b-DBJ zrB#{G!&QR6c+{Jl@5C|rG1+xk&JMc1Vpfn&kmtmtrB@bbX&v8r*rUSceVSeGVW-~u zc{4W6UYFLtBwjcyOxpDHBD2?S@tM-{)4b%B1rM&i=A5$3?`re&GYcnYG3>A*!A}8@4L78=MNLz$~#5o8%jT)$ZA^ktl<9@ zwaG03uZ)Z5f4pcWeAuk`=CnD+|8}{mHI}#4<;JhmpSmUacJvDW%O=*hq8H3hcHryw zo^|lirZbCV>_06yz%SKeSSQA~&gk@nV`+;y|4e`Fv*^v%H8GF1rUb5k_5Ci#{mBy7 zW|bbkB~`zmb-VO0S?OcyKMeJR-q+S%EnwdBe74Ya*;!52T8h(5yp1Yz4>51Neqx{8 z^3S#LC+F76KmG9RZf!lE!meLuINjdOusO1C(U*mi5q<_78xmYql7dQq7fiTa+i*zu zOrgaI*88%C6S9}X%&MD(cNRxkyXbS~M5o$y&KI3{{`wk_afb6-g?BptU!la9#n!m~W>ZJv zZSM4%87JOu7F#p>rH`236TZJJ>9%JX_1^yMGjdd5msaZjbK}N_v)zi{O1Jm3@7!BD zhh@gQsmUL=1yA%=;1F}6X!5?o*KJ$p8j zZPU6Pf}rGkS9R{hfY^YK4GYh8PO!=0xO?Em(xGN^Y_{Av>RjryQl9%ZU(1FB z=NW#_z6e!|_C6E5yr-btTb%zcuW0|7XG@(tNTG#QTgg83!Az_K6TgqN~>yK6edJR-DM=s^5W-qU7kEH2EyK4fW^ z-;8;)sc35K-&VGurSpH9v^|%Yv30uFi>u4+_1EjITkmNv@S|?;uTNi#zJ5LJ9{*CB zecCCeHpNpbHwt@OhwguWEI3_F==bZo>eFnO)^ldxoK~u=?(2SxS2;AgsBhhe!W-d_ z>k{k~SNk6B+`zwK)!pko-OWwP@q2bjMwtHdcsD!o&h)qaOWtG!OxS;Izv_0?^q5oI za_)RF4R@RU?p?xEu@~A=Z{Od%@GX_ss?>7Yf|h-U{cCiNFRS`?`s;-a>%zWO`v1z) z>w7lkajASv=W$7)Wug*BOeZkhpZ()SMTY%-d{_%?fi4%6L9 z9u0eTB?q^y**Njp&EkCrN_A%U$=^)W>$4UxE0>+&6t~>d%fjwXr(^OOt)Dw0+}1@i zXxf)BfQSB+~AdI%hU;r~Xq^@Z;IXKtM{{{`@w?)>;b^ZV`C({5#(8@zU< zF~8O-vv@N5xb_aEo+v@J_7mMg$~m5vD#v!coVD@g?v$>c! z>#^|%FaJ5des`L4ar~n2N1d;4as2=FcgOAiC*M4$1#&oDcIwp4om%uMr};R;zY|_3 zAKu-jdwAB$w=w_z-9GwMKgHfGmpQ-sjiSR1)w*9lo_>BWU%%CWE)Wz{=Grgl|4 z&nOC6GOMf5bM+}2$^yC`L?j=e<9j$6DNrd%< zE4!u|@ST!b@YG{hozS+GmM3Pd?NN>UQ+spE)7{j3 zuQyh<>=y9rNadGmR{Qy?PhjPoozG_%9sgH&>BYJ2_sXX(uvYR{>Pcc;)0W0A`Z|=C zNv-=`-kmc)o9@ca2xn;*I8?qS>zaSX?>#?fpS&aW_3CEN`SqdolVo-m{k~NY!&yJw zdIjrQC`e&Zd3d3dIAJh5v&bYqB zaVJMc^(D_AZrq`E{NGMAiQQYaC;bukF)n+{U;XhZ-zH6(y+w(o`{t7TuH|a+iYgX= zlFlnKy%Ag{d+*NS$42Mx+>1CIW4ZKnr(II3mHnRr4da~K2YAZ4GuNqE82*!R-@C?IX`tj39sHoldPGviNm3&vkjoAOw0A+x0H*XyD8w?8R1 z-;@{|#`BKjj^@Qi>HM!hf2A?1WJDd2`>E1&;^fv7K{bzm*cBA~;@$>Ee{(^mVrvp_Q{?FImkek0^!nxC_i3`)Y-h|A0Ey-LRdQ7b< zO>IG3gXN<6i499mIq^%Fa)f5ovR-j8GBdhn%v84EjAN~8gvLxq89}z3RZV{~SEMtP z^D>xTlM}_>Xg4N##+Afdn90Az&d?b3hCS$FDI-%uA{R@o36IUcZ6Q|6KjFVaLj041 z5zav>s&9i0=cZhAT^_vU-8<)95f*)Osvh2GTT(LX@7L;|n#Z0k6;4QRxOL9<`@Le% zR~^rAj+q}Ha29eWl$k^4~p`^<^I4Ew#j zEF;%^xi4NH7bmhmKkRSajrH!Ie!hHIwqN!1UD-$*S*uTZ+wXnnKV7)_{#mjA7j1XG zKbhZX}3hy(R`xeEQfuR6_{-nH}3b*2RIh;_}~vzb;} z=u5x+EUKF=lBlI3=o@Ng$!FJBn2~ZaRqy`Mi#4g@C!csnay2UYw2CxwTg;j{m#eUa zS^TFdN1=&*9JA-?XBEqt51pIfv_;Flxj$LvmX&>T|Kgu-cS_nY&0W}J|16E8u*F$5 zvaC(O{qyP!wu7gl5;=kuJ2O5%w>)CVms>N>xX@((#rHz?%u?H!W!hPLT%5lL`wA=V zcUJ84ycX#Y;Co}$HDiOwUhpsmCb50CM`;k!UHuLeH>r87tMKv^uU;k*?DR4ls z^TVmm^EW$!!YW(VCRRRp)w8Z8IDWSN)tAQ7iVK{$1g{9EuKYSNt^CUM1J61howVG; zwA+$lj^hi=qRzS~#l^xu%_UyZL zzXdBMyiJps{PuN7_3H{X=}&VUVw*l^`g4fL%g(uz=XQHr$;@Eq>C)z3zNuYy(a*k~ zAC_`k_j-y&$?CJeGB@v5Km2TeRY=iqld|S{W>K%jw=8qNrfIy`n(IC9^`8shUz;s| zSN7t{UGF!~Td{ts&y+i}g0A1%d0Xnv+pB*3J7pGLIIXiTW2?2T-5U3_@}0`EB7VDL zZ+gw!yjwTF=VIup5B3a_J7cxJd=)C+9WKA`58u2n&6j7_{rs2KqRe%F=D&S){OQ7V z0q2$rKi`|Tn0x-mUEkKJq^w=9{UY|%(TlsMOmO4)xI2U|AIA9*dZOHw*S<* z2R3U?i))p#Prk_G>2ms$OpVOr3t@uoJ~C&;zioJAT)|@HtQs-RxkFh->&Eg6!``Hb2R8vuF={mcHTpBAB9oqlAG*51rl8j? z{7~kGv;LOLIT%GR=}nqH^Kj)|ou>5X-~`HdyC(4UEe)sn=S2>^);PDRmD_Ks`-Tqo zbyr`=_;ni>`*5W6Em*4I-Fw2mc^{jZyNLg}hhHV^!v&cv!yWw#r(JtH&oSlsj7Kjm z=cuJWn;~#Q#!)D6n&Z^-N(M(i+itL2R1tOI98=u0vR2V^;ydmNn?Li(Gq0TXFttzH zX!|jiJ!i^l8O?9!_ddNGx$o=hXsPh3E0d>hZIiowb9U32XHA|_Iwi+>4Sp>AJxeHs zd*0G5da8Nvvt+k#pO#f*p5C^NrK_LMFVB2&?(hF*TaEIw9;>?9=7!FkKF!|c&&>6? z2d*EISpDwZM*Fnp9k;mFF?-D`-umRh>Sc3uZNw&Zr=PoK^ZnqBq8rPa4zllv{4rq< zQ}$`qr5_Ua>MogAar@-;x<6lz-(G!xU(K#rXJ-n9eq8oH&u{a|)I}}3uAbD~rx|wo z?KO+os4sUfe7(QhT0^t+&RN{VrgTr^_O94GgZMMtr zW3y^M^S=FhqPhFjirFVC>?d`2`U*~Kx)c<4(=vv)giqf6*@v#4_wEi0ehYFcnYCLi z?~rSJIrn|zxrdKu%$du&=gjRQ#VxO@r5Da&EcyOr&hFa0?`{Ti_ov@J&iAXo|1aO0 zi*G0Y%q~z^U%K!Z>z*^;_pz=p+q?SjyXx)I=D+7Y7uof{=26{?&Bx4H=bqI*m+^67 z^tUIvKcgD?iCb^!Th&c{ zDy~&KcjmS3`ANx@%=fsWE^pg$ZLW9pndCj1j|}(rpJv>(+#)M$)}n{6EXo9rpPIE! zTxhQP19R8Z6$Z}NjVk?a_N(5BX!}%U*^}nY{AJmMi+7e6#&+!vI<@7=QT6xilX+k7 zcxZ5M?zPXWZ|=Cd=UBs3=52Xl(VsFcUukcHH~U?|tLX`S!f6k@;cX#ow;~p7%#s z&e!7AwtxE9w^lc41zwug=6>Scuj^hNi`98UTp5e2Y8=FV|DCqyc5m$dxOG;aDr4Tg zoA&oEgL~n}cblzE!xe0M?l@0%JH59gpQnO(X1JT}Nrm2kcV{05x(9u$>8uFO{>prP z>648We;2=I-^;aTN#oi7Yz&Le9m9SDv!OBSB0M6N3(~RiYKF3u5!QIMBzC3$8qgTC zn;2+}+2Fvw07uJ*F%~M{6DOW_%k5I(%`*EvL4;MeH;GLsbHWta_v`N)n|Do0%UFJc zO;mOM`#F}^^ZDYZP8UBvT}Ch@Pfy>YX|jy!hx0YbnukqXCB#p2C{rhzHi`u=fZtc6v^Ws%v`Q5z0t7`&(7HD6*op!lwch-vAX@PaY z?OfFvJ{;#HlQq&T&T_av-LJ22=iZ{1G)quwZ~gC&Tx(aoE&G`MbG4PG+6)oTR|P(g zJ-%$tNeN%iv#KU-kMb>RhmSLsy;M5)S>;#kw@tezXE)dEQ#n#ODe+KdVTr?h@RlchPfQ7K_f1{?PvST~yhMy9yUpl@(2h?O(g@z00X0qgw`^y>TITujk(7 z@0ZQ|d%1Jn?5%&+^|9Xl>u1IsBz9pz%G{W(cW+fX#$H{iY58ZFrk;^X#==wUUfVu1 z_$8!zf3k|^KAj8IE0d$&&7Qh^!SdKAYYwfS(i=ASyt&ZKa{>Gz3+Ha!yK!6K-Nmce zZKmGK8fS5+b5-}jkm&T-`DY&m*(>X_Zf$t z+-Pxb(Yu6Z2cD)eZ$L<;2aV-ME(({bx*gR=IQD7I`8Yp+=`sSRkm3^BP zoT5J{N}M#D`!R6}driWH)k>@^QK=leYAv00&SAp812&>S{FH8y#suE}S9 zK6s)SR=8)m`}I#sfyL!+If*S>Cq5HyX^#%Rdo3|G^Fy6%68X%oEG_EGuFhJ`*BY^J|5t=I$RRWS7ZKV-*rSoL#Zl=MLjzM^`OY0kMK zoNCW??36+zLD5Z*r)uSmzBAVj-{d%III;S1K~2_UfgKj#i(FP% z)NmYcKl$Qt=VUQ~l1~cXt$wchlJjQH>o8U(@n^OSmw2rn*U5g?c~mx;ZF0-z&AziD zx722KX(pe1*s7++s;{)wEc|tT^^e1ef44q4JtJwJfu(fij5(4=BhB2;88bNVeJH#p zMw&x^pPT#%C42jWN?Ta&EAk%Bbc~Q@ zuu-rvX61kOSfKn+$bWanv^1Ur(=*!*>?#D?=kXt%`SG|>Vy=Y!p<>Z9Epw%%-MhL4 z4jp^w==00&fhw!u++I+~Jbbdy;?A2J7B%|o#1bEWP~=-H{pphL`NbUp>AQ@Z3L`2v ze3WBd@%#PHNe8ZWoa%k9CE{YrqTe#hzf^S9Y2O#8b*nDk<>lXA6j&E*)?zv_@zBDm z&V5{qg&0=kUHfF6WuCEP;)`{+-l@*9f3w?d-NmoX|6b=_U-zWyzGu$aUcIB&7I^VA z>t4CL;ffU~li5FSW?Ifx^X}}b+_qJDubydNYP)ma{CAq^mE6xMNkme@jV&5Q2erPrqJ zfA#9N`u6}E%k`7}b6?y~)!%Ksv+eQy!*ZSLR447Ol1SK~@b&-H*xz3cul3x$(eCXZ z{_5De6UQRj-IVJ zx}VA!Y`dhtZZ8VWf91(GW#@9$hKDwqmzJv?SoA-ib3yy&H@{CPTW(O_o4ub&KF5D? z;*6z|Gx^)9GfxLyJNc1wSyP2qLQUwK%VpDg+GdBHJyf5UqWs<=C^Bq%^v>p!uHXJx z9ChhnlH6UV6NJflO2M*1J*lrad*fy$;jG=Lx*xduQ}jbXlbBDp#Kh z7Tbh9GV8ZFR&t(YP0HfiaO`39)~J*F>`Tr)I{zvB>iOf7k7cC&-F-Q1_3PUUnd4^M zTM~U*yUOz7-s<|`^?3}YC2y)aw*u?jtgW>trFu&9 zI4_@6*G!AkW6F++_8bV=y+=x~uCN!?|I6L!a*TJwv)oI~+4Gg9 zcb-&hvsl3K;iSu#vg9>K&cyv&e&(so;>?F1-vrFJz4A<5G`ZQ&XyGc~MUM4R^AjH@ ze7G<9a7FT*^IEY6aR%0VXTDfG>t&YD-*UCT;rum=-yEr*>h%1-lHcOE+8Y)*SvR)? z1e*&7$=vzk8ndEdVce<2^4zs|f8_5fGtab-<&$33du(ov5O2BRiH-FnA(b8gw~Lz7mk-LqIEdBv||zKG0n>8uuU_oII{F48#UUv~1mVC<1a z3szPwb5&I8Tle~4>a;%d-Fed=n;D)BjQjiP(_`rjeXocm3PC%0OoxI5$Z`3qh>tgNqLYRI?@E?YmGR8(Ji`Mkx18jgj! z6@sp8i>)6wPj0W#C=yNyu%EB;Fvd^VwcIcMiG}^yOC1-)_HYEAIc9Lm*)HW|4$oqn z75?gm2mYR}1Fn`xn(Sk*3yEG4fNGfV;Pu#(2 zal#<@uRN;+n_+{&;TBtiKZ#$SOB{=skvwAoKl{%6?57nH{|3IhT8e!I@h z-b5w-7nePGig}V>KS-4@7FLv3E85R5pd4=ZEUUn0b6}a(bgqy451o!>ca-2dyu0)L z1;Oc2Io_|iCv4b}P?D&)=-3etr{tPi|NJRo7dhMP-|qbSx1-mUpRoqC`@Ums zdR#K&%VyO-;R11n)yLx->wXBo|M_t9n^Pw`fBuk75IpASo^yp|M)Qe1QAX#>{11O~ zs9^M;@>J!<#A{ZwtCPN+0g0VSiTA9WL@W*>*Tv_{j0R46ZhU= zN}6`;kY-5qq|y&;$M|IP``6W5?ueRxh}BzFOy<~osO;YbnMArtElP;>I$xT`>J!3?;a@#GJGKt&VJ<|SpLCHKzwPcfgJ*V}W zyjXV?8>234rG8g~N*jz#ur6&ev@|y7CF)ATHQ~AWx6K6p$tnDAlz*BO_EXL4)^gR? zMkOcA78siGWE!3@o13v=sYB4TulL{oQ1jmAq3Up3p|kkB?E4e#-(}W^PZximZ=sa2 zb@v_xi(`_9KHUE^?P=k>MN_(G7;LeMiA(sx@MHdaj;f4@!99kqt9yU_e)aT|(yy&| zOiH8QTa|qOx?$b-6)U!7eEsUVsQ>D^JU-X(Ygd!L_D4+?*qtFI>{q-crEro^Uzog4 z!Xjq(=$m=7KCN6W{aXE4-i~sQp2MQIuAVuEEjY9a;?M7GF({>=nGDG=r~k@#?qRCgyg}d$sA+g>5WaE|Da9*p^W}bXy?u9M-Z1CG zuKpdqoU4ppo^X3wFd=qfxcl+NQmRdFs;;bge*Sf7r;KO0ysDMzD*l#>2mPXUTgV+b zacBNY-fxQzXhtb9337T@eDU12>1TLe@8#dpuktuduQS_Sc8Tp%@qBzGuJ7NUH>E#h z9{x8t_WC^cm&fm~@4x>@m}`EVx%i}~8yDHP^n5WhD`F0D>v!$G78Lg3rV6`HzDeiT zy|=H9NQC=Ct8ZTq9-0pP-g>_BWoB}!@SYNDFIcRZCs3mz_bMT7CpOU`6 zyRuHloA=dQk>g6&%U(Di`@fb!s8}d!;dbW+P3zFUYxYkK1?yN`X1F}b^qK6y=l;8d zuku;fmmlfPz82eqlQ;b1tg*kll+o$`3^FzJ=?_-eBeb+nK)1-PmB# zd47Eh>kE-(3~e75YB3sa4mN8$d8m5zpWg|2yy!6vq+W(!u`kh{1=q@Yq=<>_5m&b0OoO$WQ(=)qPHr6q$;C?UbZV^*`W9~kwsm&~(S_xL@OFeyx2@?iF9p0knq#>$;Hn~ubY=k9b2 z_YJO@dwFKaRz=kCz9*Q@>KulpCJ!+PB2m!tQm znPw~0ojj!1+^rVRJap)m0Mm=vVi5;#MFvREv7aZkOZSk=42OVOGgWLYzm)m&O?g?~ zd;k8;z5iIA{EuLsUvb2;LpO=(P=wWulbx26I}@hvy;~l#xnZ7eiJPnwhjjDf1y&l> z9wO0NirPF?djLi+#HCa?w26J3>Grn9_dcJ0ASi;@%v&|gyoHpIC zQQA43{i}qQ_Fn~!DO_hxah{y?aJ8zWXBUg-PTgxo|981_3nu-^Xk7pN+P=W9ZByG# z_qbn(bIrMUdU4K@QzHAAH>{ePGUY1s6aF907pIoCc9s6U^Rj5mbWQeo{ZUid@+B{1 zPyZdbTjSvypWQb;>K0d*{=NJ*X=Vy%Ki}7HG3z)!*r|kHdzZ`CvMg~Y7vq<+{A&{4 zW(KTVQ?IwjUs5`e%W>f;oe9qQ-=8?FoVV=HzjN=tE>D}hrCv?#$|=Q?7EKoBHYWAG z>L&|!9J}|uu&w zL9@1#htGT7_p>-B`Cn&tz$#@Y+mmVneFSQj_34xHmsG>pLXE9 z&M#lFFk7GH*W_Hx|M7Dj*L|19;ckIwos}IdEhkwPU+kT> zQ0%VlN#C8?=5CXw%=jA_7VUB8NPYd}TfGT3$1LBKAIj2v{3qq`CJF8peDgbkwyb(> z`zxY!(@jz7&Ud>O-4Z*y&2|3btH*br=azMQEnL;0F*7M(Qqw*~K5uSYsb%hb4;i_p z`LL}Jmh0Kxk+yOdV~)w98HYRmP4Hb^)_7#c`Dgzb8K!C;NX6b1F)>6LS)_hbgn}u1 z6RcDAh8D&|uB@FBemn1unLw@igZc-H%^D;oF3QU%B{Z)uSJzn-=%@5!_5DXG%WM>9 zdT4fg{w$~xnrL0{<7wB#-MW9=7I#c8()_>wPg#}Fp8RRG+uvSe-dR<(Qiy@uy{h>%v>^S2}g~EQ$293_i_j?)b&FYth%UO*J=i&5oJ6 ze%i`7sj189Ik%*m*5L(v^0%@4d%NvxSIzGA(MET!r>y?`=Jo$F-}rn_SGJjX@%p># zT=UACoz|{esC0Ur?5nZ~hEXS4SEaC|X3m;uu*~xqi{|~6aVNg+*wo%5X5-Ikll)^b z!@;LN?d9#_OGYuQ(}=0s$}+s#Kr&6wRb ze`$BC5>RuSV%gETm&N+DP4&xP`$ZOf_hRmnIj7mzAhS$hTWH1HvhB|VBh=qWMX1aC zE?Ky_VZN9CU6qv+=Gvrm2kbNQ&6?F5p<=m0+T&*U+p=KZudga|rf_`S@G<%9^eK+p zQ-A2snjsd$@@yf8*FKF&Rn>n#zIpq8N#69kd_R`6cSW`6aPw7UeJuYuJI7R4NKb*$ z)p0kdh$Tg%YW|Uyt7Ih{BD?T@arjCb0P8oPhi)M2_m|kXD&T1^6%$)@$qk- zu}S}I^-t?6SKQVuU^KWHc|Y9${9-RgU4fHJ3XEOSzuvwuF?4V2x3jstlinU&x4Y=t z+9$hawIp%f5uPmYL&tmPqZvNioZ9{i73|ZfV5~W^xQBhc$#k!{QXMRmCm-olFwgYxGC9ICd){eDsl!ipZP`|}qCZpjoa4VL zljeELfW^Qo~Ss!B$&hH&?@@Ss&T2^iNJ<&^o}GmM(+Vj)%gh z!VhP-7j*>xx9cmra{umem02eYO3RD56cd)$d{%k8Ps-ieOmA~TVN!7AD_ij;{E0~^ zha7!2Fx{B>eD#L||Cch@ewCUaZenHkk&mfphEq>*_qCHVAByoG@)dc`wnn(@+t&Sm zem>^4RC-|8xnXm6Iw!~fdAB7pWUGId$fo`Cl@;u@<%m4ak~AmY#Jlsu^~B_aQj2dV zt#sHk{O-*G!zhs_MSdn68D2|N|j#5vg}`D)-Y z)s~5}?Z31Z`xJ!dzwqDopm_JH-)Dm_-+Oufc;4E5zhzcFSt2+~W0T}3;j_oO&K?ST zbVesPUQhxE?Y4x>?zB#z(YIdPdR`3tw-?L=OvNb%MaK7xN-gUGiwjG zmsU50LxhVje4f)=eTZMhklpjoMyYp8qxR=$=1?d`3D8YvTs0w>C7Jo(_E z6hD8u{P|Py;tLz1)h?V%Jaoxs$J%XQ!`O?q=!+Y&9L~2)cF(uev+$kyeA;KmD}NtH z9=s9C5b|59KIZo4&uStMyaXe*B&hFMM!u?MIn4vZo#I$H@J^ zbDw!_PVavA-?KPoeET}rwRrtP%f7NVE6y?Jq?nlXD{=}pYha7!;L~h*tvVBh6 zK~O&O?_sMbS$y)~Vrkn_sk<*+cXU1~ZY@1@uJ_yb7jD7_7faVhX5F=Do?v*v>f5)M zR%hPKuqwEl@%ljNV)fI7RcV4ZPHxEtMeECEbMA_H_Z|gmJ--~c+s)~v_nXRJkJcWU zv`+o)yNBD}E!`6EUCv{+co-!y;O$s6-S)C*(3 zdp$Oi>b?2Lp5aeddmh2GgNI6^ZY-W0!^SR@n{=Av~dWJ#J zx^w3vJPyxk`4GSNDXXs0q@$Xtf|};f(-n8J|E<4gRAhfZU#e}+6w^BW`RC3z>HFR- zcit{_^6lxgi)%fv>UsYBq;X<-+10PJvvPKoh5d7wf9J=OQ;L6{aqjZ&o=~KAm$lsS zhfJH!uGtgsAMyIKXf5l`m#%knfRxaj-=keLiRtd_ zYbPnBe2pr98)3S3qRHDg=RX;5vP_>Mn&@;YUNGWnS;9K?*?Bu-xi4)I>aP&{TDC?k z+mUlky3Gy)DWT0~eS#*3&uy)`oT#SUd{G$F00pc_!{^5R_}kmxQXFWg9iVci#F*K?0M?@PIjeiYC4^N{kluq z?8`PMd%9-(wN35XdPBFaqw0@BBJT&bsqVM3nC<0uy{+;TbCP0uZqj{Vw)alG^j#v| zZ~yL=z7#&Ge!*7NU&)*kW7k}FNnIv&d|zaayT=;S^)}7!TC%Pt$%QV@1X&+!ESY>s zDe(96>H|M}9G|j(;OJKAczAH}gS|>A=Q0J4Stj*7n9n=w<Z+NK60Kz)OOu{?v)ZeXKSN-Z^vaUDwa~3A=|rCNvdXWwZA8x@Jl~< zYVYg2Iw~9e*DzU#xZ5m#*vS*I^LRCj>ijt;8m3lX-~DE(WN*LVu0Ot62OgPNHXb}t zE7A4Hgx&33qC_1c8=z8IycrqjIM>XTAo1Iddi|&WjhaN1O&C-~`(v$YG z(E4L`hIHkV44)E{3Cv>k?#0*tuW7oa?ZucE{ZR38A6vqVOB-yDORJ|>xzD>$(D>{3 ztbWeR+pqjeSydRt>hrqA=~t9p<+rRkD`)%Hr+;>vxbvpRq{nk#XCz1nOKtmK5xB^$ z&Pe)Ln?9eron-sV#H`v`hf`0jXB1O2_2K`tSf@y8?wJ`IAND4z&+l{oZWtZ{ zrf@_3Iok1SO7a86-#;z#$hft%BCMFDhdu2?qxE{3Nw?mnHGV!(cEE7)`=cLj99&{v zc4@jyyv4nh-}Rptsjb?+;9lR6(#7mj%0bRNS9j!IDekR#zi8j#_3L)7KQiluB~z*A z_1O*uRTm3pMZGy%y-~{1v39~6n~qL}@5^i~f7IMK+oR>-Db^Rno@i*H{B}dJQoe!k z!>jj?9Wq(@MEtsK?#+5A z^*;W-UERN`k59XJ^k=(nSL@iu-W_o)fmdzS>h=3yE%aI%nCY?k>F>P{Uaym7(jg4S#PR7Uw(M}7LQ6`(e#~+CkqPY^Vn53D|;Ira`EnI z_2S!p>fO0(8)|D}%#%(n^g9u3d}xDJ;_^cWza5bI@s54HZf~XXfk#2t7*1_pygQXA z`=ev$$rHE0MbyOE?=E|=Ic$qd+SL9w>*^KWlD4nhFL$%PQ$BrgUSjOC)vF?#Z!&Jx zIk$bQaO#4!X8CJ>uV0Ym5t!;zV*28QZAhZ9XVAxq41s=J?}w>V2$$ zo%7_*_i0bKwn-V3KaSA5_$l$ewauF?l^F>JFQh(e$=+u^x#r&KWsBHK`(_#(xiqiH zt1uwv(4m`iL>rey?zYuoSn^bOO$C^Eez1t?$m1VT-t)sy*i`9)hhdDa; zvuLwe?^uzdd*+!9k3+~R;gG*?t^^k?y{};QQheRU%vovYwuQWvy=O69qv`bhd_BGY zt_y_M&i?2sJGG#;?d`KQr_O5GgcOQC`@3<~|FHDbDF>b~s+#Sc{y_Jc+LM!Zt2GY@ z3q*uiPI-Gp<1enq@vw$5UsO z#)hk!@n6^ugdbV=CF*BDXjT6dt~DV)c&@7c+r9SM4p+Xs*k2;InUBoT;@!i(H>8E7i`qGmot%QXI#Kg+0)-?`G}XR=z#4*$J0w2H7%D{CS4OZ?A;@E>ChCm zcIl6rJYnw+9*BIGV4?VZE&HU3#B1q-z5MN7s}*&9vP3p2-J0wf=b~<$`E;Ml-cRd&c6zn0}4to%`j!U;DqNX^r{X0F{n&s~IJhndI!PczmQQ;bLa* znS&44dg=@BdiLd)&a$6@PUTVwi9v^#-08m*ayMJ*UQd?%KZ~+YFI)Dm`mphid?A&2e!RvXJXon__qtKRFh z?n*p8Jtl9D#qv3klagw0xKtcqv7EE2QtIP_U9S(Gamc%xyCck5?%uP14a%FUrLO$^ ze7bbm&7KEmw4J<{@7wNPSaYDt@36=^2kUEJ7e0`ZE?@C&Zi#! z_WKXt<&I1+*^=?koZ-WvyQgt9M`=A}M#(spCCV5YbakGgu?dmQQP4QmZ8w2h@dfoW z+)puVuYUS;qvvCV++cCTiFP+!9X+S)S?jV&CG~p!{m6HdlvF4B$=pyfo?e_*mS*}{ zZ|3>B9a9e|+&q)sBP7LmwEml?hU1Q=0JauRk8htPTXm&s_M~rE`=K}Blw#z}|Ne2$ zjNfmLo9Y^xleMG%u70=dlAltOt~;~M|KuC^?sAm)PoH5C4nU#r+e0}lJ+WiMMR{j6_UH<-mCU=wT5;=Q6 zD6coDe-I$Hdd;c>Mk#YR{=D32wfx%y$(Y%pOx*Lm&)?J%nlWR|%6cn7_Im+eTb+V* z_MK=bGSJCNl-an(==hbnk3Wg>MP?c;`mDQzd%h-rnPiyiyzrIV{huA+`#L#w+r`w- z+wNQJr%kOp_vW=??BC@1UA=#EF1<7nT)D|n)jXCtq&;V;`Lc!yEvo~L#dK;NYEpRf z)c4kn(tXz?jzu~a3$5HxpP(1K;mn5=PKQfRD&{Y;oTd_F^5$CR+*wX>qU?tsxnB1_ zD)>4nJUuly=g6}N!C>Bf3ThX1ovtX@RLHyz+<2ho)QrvlmOp5!lF7SM`EAkTIR+;m zpZ*Yb)NuXzCT@=lm$z1#zx$#&aos=Oqlx0S75ne~Yc*$-bCThDpC?!)|Ka+c)iY)% zZ*=;cR9Gu_afA0p{lF(PRU-e%fB2WYfbsvP8+XLD_&N?4D;XK_Sfo|h-M%yDbnlV; zDOQ%tBW`OP7YaZ3uUhoOs-$2Jzk3!t)XY^c-(qKcSmd+#V?n5L*T$Xd7F#|U@>P_# z2S;W-UHt9NoxkVe+*D+)X4u4BejxO|my>U9O$+mMnca)FhOa0M#RR( z5;o~`;Fyg_TEJk%DAM^dL;60 z%&UhhmuC8F8^t@Ruf2CQU#fnF$Q`)?PZq(lwRN|$_a)`eu=u#?&5b|y425r2*kG?N zOi@=Z4611jQzLBEg^`h&0dcD;ri4f4-}Vp!E#|(!|Ji{xaJhb5{^XoT2X@~(n4oed z!7!31qjS^Fi5|M1mf!Zzf7Pt(^(ya{rOwQ+S8s;K%G>L%UvGDZ!{uU8ajh$-nxxW) z@cPq5bCzp}axRn6Ex#VlV$1OFb zv#aY~x6{*WJM&)qUVhiLFYDFKPxY77rE7}j7{3j!y=*sG=cr1!-SbPl;dx4Ztk>A; zwZnaPzk5&|ye)OF*7c0bX1j$Kesbw8{BS%eH7aFB;9R~4v0I-F!Rz_NKQ1_ZMt?bL!hl zm%IBSrgEHWGHd^LVcLR?dh<{7Y2TL-o~V{_u5eCJ$H&iKLz_4+U;HO&Xm&bTZtv{B zkXVPd@4|uby{v-7&>k`c$LwFT;a3E2ru>MHVO}Nu4=(s@Cv` z&Wz@%)nAWVv`cV5bbcWt!@+l0thnC1XwqYy3)*4tvbT92xbVI}Gxetc<57bd&v|7X zB&0K~oGj9~o|y2Sxf1bzErYGG)P!R{id1wMoC+9yje$}2*gW$zq z7yhkaU=)k#Sor#HpqGn9|G_r>{)u;H9yhR5>px<;J7-Qiv!Tg4`%{T!%LMoBld1Xf zN#f+)TyxGJOHQya-KRSH#o~r)CChiOUEXK!J>j?A}wo3(bYTP1(N-(L6s=hxGZR$sB7^_08&SHSmF?e7&E>$F7HHcYh@+IL+$_<>DZ zst)%t#p4GP*EGLwaD210J83s->V_TK*F!IAn~VNn7fOE7^d)xsdD|+jZC9hJ52@)# z&$N_jy!l@1@Z-90?>{}O9~5#vO6E+OmwM4@Bi~`iYh86QMxsYAD|meIW;XoZ@5*nl za3k!a7Du$W;l$l;Du>9buL1mCk6(PS+;8)|Ug@dD({1x#aQ;J@8A ze)iO#>t6lRRN}bIxme5MLg?Mak`r$HIdSP(NYL8G)#cq&g5_@LDmFyPGV+J{-L3K4 zXt-GZLH04HhV?&_El%Ave6d&X!g)8>51+O=%CFn&y{WjxLs+k4r{3Pco+sxtES4VB z>UknpYqqY*_=xh6>8%Md`*u`X2OY@#WiDyVoHXUmp_wLjHQN3$DSy3MzW3(;|zUErAWy!x?8j9QC< zSIjV z_F&HEX)ol3x)TmxZ@+6RusO{*K;s8X*~PDln@SFyZBgyZYM&Q;T*q(aY;(>-nJPOQ zzTDgYMz=foN^)%3>TSEG-*FL=tJuO^wMqY0QaIDc%L|xt`M!E>TGeQ0^r8IJ90oS2 z{<9{{51mYBt$M>*op>P5Zu;y;8{X=6&r~w#+;p^a0<(&*mQ(Ui?x&KH7sWLu?O34y z#UtLXekUWF@$Ahe-HYd&dd@eVG-*Z6z3r1K_*Eq?iu;8eu3R6f{5@{-oPaq;8new< z0(|8@Bs@9QFnyoI-=4!ee+isw;y&o1GZyC3npwOsn_vA`KI@83!v>!RSB!(z*u)Q&?J@Vid08cb zGx_k5hjX>^RnJ_JsQo#s{NzhrCLIew=lj1G`y|!wXAwvWDR`gr^Yewx#b+KjP3aM^ z>i14F-m=cz%i1=WBR^eA{+^9nQTbzEra1TLC!H!Am+E$=@@_b(X3?D};q5GVD&12e z;pIWAX1nCJ0>0~U7MzK7lyd&@mZC9^A^qm(gFqFP9LpJLKv_3GtY7IJm2JjQum zznwIUlIunEPIr6BE|y=K`(w5%vqTgqN}N$X`B(j=?%a-v-}q|VoEwT8+v;4RKVRCd+pS)4_iy0W{!gJ{`yPEOst+-JGx4|h z*GJqlcxxCNqiPw#{SP+XGkB7;llS$fjjwvP#mwn%h`Uv{H6TnD>Y5p=S~-n z&fM&=Qy`svQsN|rj}~$rmb+6g=UmLaJN@mlh^ZMDo!`0ces^JeM&<4wX2EG!gk1O& zR3|e_F5lohk>UERxyz2bsVax4ZT~1(dM#(UYEtB?8wsx-cO-mG3qzt0rj5?OeL}R3f5Lx*{tyAf;>T~-ddiCHZR$?a-NO1P z$x8j?DV6*%jf4=DrIb}{NMLLWID&; z`E^N>-kEJ&^Om0XD!i7VIoP7HCGte+Gr&z2bb@@PH3uYTDgSwR`rtn7lt_p-FbC=^UQ|i)BK98Kq^CA9! zSo6X=Ht&DG+qk~`*VCQ%{@E$yN^1wj2=KLQDVt2!JXqqjW_S8rpW<%IUe#ke{mzLz zpZU=zveM+zjUR!wo>CS!x)Y05i0VHUiBfqSpC8_yYkP=OCw?MlyGx$yZwtG~eYN`k zGIkv<5W2T%m&L7(m*Y=q&5L;ZNm6B}igw^$4aSvKF2)wGTN!oZ-3t=U^d|?_Nr=x= zUw?q{W6=9qVrQl=y_pkG>|)+*FD+Ni$oKu&oL!;(KT@0R=SA#zJ5O;lpKX-c1VPgj zUY7Oi!xsm#xg8L$cymlL&YV}kKgs^|Tt9D%)=bR_?mC%I*?*P&etq}6dHnz0dD15eH9dZA6*2q$kmG1K z=e?DcH$$3!ro>sBy>&e9(SFP=ZDBQszgp`n-?aW|UR_%fR1MD_m}#%MZpJ*v1Hbyu zo9p|%53^n5lQ~nA@3F}CAocK~GPQX*7tgjm(_FTO$3!~+@ij@c`E7e6OdBlJ?pH2T zoE%c{CC_Ls+p9Q^68*5QLzm8Q?)>IjR&iYX_VVDTj6R2zmS^zwY|51So!YDU`(@5K z%f~0#Eq*nv&Of!;$n$c@IlWn$UTwvlDJJ?4V_&x4n{#r7!H;sWXYWsjU6F2Jwu`*3 z{6x&aC~{$uR+tXs%@!H^%z4SaOC>dV%vBF8+A($C`VD&ot|vGpQL29^|AphfAa>7>=@z>Bi&6x=n)n?bE=jWU`O?5E@<`@$;v)8+D<3oK z28+39aK^c~ExM`kGEmz1x|{!|SoSIF#O1jCUdVBKJxf^~elV0_dU;z1n=}7h=b4V> zR@a<6a=IS&oXHS8yQov{!nq7l+l8HSkJ4{+>Mx#NX{R`aMPDhsP+rG2g*l}93cEM| zr|0YVT~AeVEUf*YU~w+Np#AfNa;N})- z(Q*2v(#s_r{?mp3$+NC_naCjHrOvN>fKA`2{Qr#k1@k1kmACNZx)&U3QC_It@$meM z)b}L<3J2Q_gcXuhTMLf;-C*QYXHl|VKCMflE`#l8+aYxBX-5tr<)CoRUfH0 zrz*~y9_FT@FT2ZJC{0hY?wJ1S{J#2Js$)TD1ykB+a>YFVRf9rM9cB@l-o}#YT4W7HFbEgWOd-HVK zIgK3d%Tq_x9WM+3WY;`TP0x*_?SFSNVk9T_~GgJa2mHC-Iecc6Plo zZJ4^stvS1CA^UX}&*K|S71;v39b68(9KZK*?fMzhGDIpsv&+W+u`}uQO(T^oOUeAHm{nUzu!9GA@=p)LiQis+IAKl6ZmI|oN*6( zRw&A!|UcrTkrg`k#BatpsvYVC#K znb$3(xU~;Q2(4KYpp)}7;~!J?wCwHxp_&fO&&^?{?)3dmOl|oy;{~IA&exW|GXxUt zb3V1L-SV|qRPdDVYULO0OWT9qYdNfEZ)tf}x$Yf1&$f!1J3>3|34PJ9j^#+`e<+ew zDb+Ib*uR<^x~}Whtk3LWG+jIE_U$x@VC5vEq`a0B0R|Q<+N-WC`f{aa_N~@A?|gUX zJ=ybpt>|U1i(C9Rg!DYuZoQ?pM6V|4+*ebjO~n_xmQR`Ee)&y|<(ruJ1AVvMa<1pc zY|ogu^iPG&v2xAS#Yz z<`q_d|0?~)S7ouv&8}~SHIwv3eZSpZpwn=@DYenI>yQxFqGs9q7n)_~8%6YbE_r;M zVbxrB6Nz0y0(Tbk*o)|&bmmY!*uCOP4gc+gmx|J>f~+N<=+9NCNMk+r=}`8Mho2uE zvIZ3pO)IY|WgK?lzj}B~@Jzu*mhr`r?fwzGdjI>G zN{(hTe0hDkX&ysD6Mw>M(>JOL>s(HqxDeJ-?PS2W?3tpFk*_gVABgUSRLh4yrOx>f1n^2cUP&jR_>KQ=jUrR`@dZ=Uw9@`pe$ zBiq_JRR=;{R_t5TH$k57ZoFMMWB%>rr${ zzE_dd8~bM7+^Jvw?@D^UTzgx^#$Q)Atq65ueDOBicFL;LpDx|4dwXpAi(R_An%{1@ ze?`0T!1c1&?;Cd8sdVrD-7dMNN@aaTQ{L{naOW5Azb9SInH9QLY2(YPFZvr6RsSnK zx*@`#-AX26){NOq!rE7!UbwbxV<%_T<6A7QbLFmNN~yIav_6=&)X7SJI_r)Sqt=k+ zpo8Nc$fWjpyk+xPrSqj>V|zgBw4}i1;}SD=HSUy+C}Xs)-teKZttcWZ(D20k19cL2 zOc}oJ$oh_>rH{IrYjCynQIDa9PVE_)niIJL4s^xlV>cnt6`L=VO(P87hhyMZl#`d2I0JX)pTI_vn9$w$Ba(NW}Y`2U<&m0x+!QO`psk~IJAtFW{0UU&QH zh5o-)O6K~vf7dy`%5xRd_vhXD=Gxy4YnN|(pVnQ^J@?Fu6fea+n|)TCUagWAvXYr~ zWr)CC*OS{@RFB^6i7~&Nyk9B&twm;}Ws<#a#GJxO={A1anj5<^Rax)3^_`3vI3h zhn?WK5TbIZM$PE!%op>Is4u&Bg1>prb}Q{Y1tk?~x)(A9XKc~?U(J{`NsGZQvyl6W z%+)`Qo~u<^)O6E86<~sz=BfS5mH%Y*Y5lvfBvi<0ve@Q>3#)StCW}1ZUedC^Kugmk zb1Q$NXZOtq7xtRX@a*~=ZFOk)9A_S4hfb$|MnoA8Gvl2j};sES(dP^v%Wj^OY;Xn>Ps`k8r;k_sOwiYGFNpKuf4c z7u%Fe>mMt;7i?4rUU^Dfq4&h8r2Y?`9E@6lIZ^?K?tC(}?O}~+c@Y&BDVP}}6Tan~ zq?!}MszZVYgLEP?bWD^MJP~;?dCw7zqkc1EBxj~CTFuwD_^;@vUvf=+K8hBddy~F| ze`0TL|J>r!&wJDC_U|->*Rk70?w^l1z46+attuB^$b_*guMhcj#e;d6_&@ttN%1x#Szp3Uk`)u-pA6XLD&m zz2vNoFV!xU&ldmm=SIn)2g}oD#C7yqGbZ28llpZv?`9eQlk;UW%D%SUx!L+8PprD9 z{L!b-TP#5x28GGNo9|qC%u#jwsdD7EyCK`}t~hk9+0EnDmDAU+C(dxbDq`|9VEM+y zJZaZ9??~F;HQ`)@)YZ+FXO({L$X#~4PE}t1b>P2y<`33ZM10@vH!{VtZ9~~uFk8+AyO*}cRz=y#j^2^e8sR^4}H1GPA39AIu%D4$m31vQcYg??c zva;^I#+6^AR=&C(wzMi@``NUma;`n!%iee!Pdpf8$8&bq#JNVRuI=3Q4iHE{E%;3*k&hS_-o_) zV=LRP{rJlHtFcBX(>`O>V#8%yK6af>s@b}y`_F8q*b~1Ng)VV#s<={rv$waZ{gAl* z>a-XqakEcL)wGXatIB`9D)Rd7vo2CpR+S{3Vtvhh;LcFT`+lb({#aLsr|cG_#8Mj z<5^|mu?b#BD+I2(eEU)tWXSs4;L6?lkl%-WCw4x26zM4Ixn1ze(dVaM%kQuIDeARa zCsU>JnM_WP-Kkk^;u)S#cWyejb8&?hKkJviOC?|W9<7X-_|aO6WkPw7L-R6k#uu_n ze|C#J>QP+6qQ6M%h+gCEgcmb-Ls!mm`RT3BG0$3SV)?XZ=Y@OLyqln0#Mdf(V&c-| zTg8^jOn+weeJWP3iY(nTHL7LG1LuNc&5|2Rj;ds4@AsZvNp?@bf-*fb4n( z);atV4znIGzxgftd6Sl(tJmp(um{GBz0L0`kMir5gy@3{QNQO(VO{rpntqxX8QAN{ zemq>V|0^@AggMjR?i(5c4|60WXNXVht4RD6|1rHXM$UA)qX%c)k$ry+w9m3wbRO7s z`h~+^jk`H4X)Ih7w;fNd{3AF!Cgpnnfxx3zSA9CV?nGI<^!=Jrv0tx3UZ1i)=NGX2 z+Bfsepq}sZ){0q+o^`T$CA=*#dg(n;$Liq2qUp9~>hofP6Hor(T=7u(V&3Wv zCg`LI|4Zd(e9~^c!11zh&h`nj_dL^2d?KHHfkX3PdxEE4m(GOnGpBd936<|4rHlo%Kr=8T>osyQKfz5xq4(`}u{Or@e7cITvZbJgqO| z`5boRgqIri&(ahQGiou)IXu0#@ws+f>*MT~5sT-r%!t#~ewdYTnO|{B&!Pf>d6f)b zj#OXG;ssSXT76sr%L*HPSyG$%6Mu<*4=za&>S>v{@XdjACNa*-pS$jFSANf^aA3E~ z>OS5ZGv=S#F|n~~oh|zP)9T(o zdlCD8Vy=C-7GFN|r(<8|rxp6G{=RlvWx`+el#e%7)J}eODI%hPe=|>anempp%^Q4K z9d_=0XZ|SkRPkZOrmt3VTEVU{D?dBgO(~kTRCR^TjSu;YOU%-f4$ix5^jv4xi}qaJ z$Q^-lIRxCEHWnO%bN{(Otq7afg=ZV1l#k=CZ{B4UV3pQT! zI@LK(!FY95MDG*5sF-_q&MuMI=|7o$LeMGMg&mgank&L4FS$`(`DlSd>azuWR$ogy zA|g97&vJj~y7cl-xbX?E#f3?0f8J-9*^+hyNAnkT^%(V=zf?L5!VGn%D6A=LU~ER* zvIS66__mt>s40BInJ*+D_uJ9yx}L$}dXvODri!=*iHNw~%u&6h@YLep_qnxMx^IKZ z&igV1KdJeA>*meB&)z=z^X6)+gNW|6=jl@tf)tqkf7PE?bS7v@H&1Y%*zM28P3s&V zKG*JA=UxF?wy@&q_oIJ*Mt)kjw!QAnb?cI^8)Cmnhm>k>so0TwA$9w^_S~)6zw@^J zh_*_-rg>TJ;oPM=&IE=Domo++-m4xj{AsR1Q0?4>^Xz|ek77<)Tve*w z%z5V|OIp2N-Nc*cHJ2^zc{w*aX=#&S)EyJYWPw}DUafn->NQ*McHg_}ZcD9R`d~(f zjdL+uX1dSq64pPHHr%uk-Z|mC$@7^tT=S-LR$GSLwYO4QIon9_@uLstZ!S1??05J6 zd$Dyt{yclU{N@}{)-^Lj=6<$WeDd|SXw&--TZ^adX{*_Ka()7P&=sX0-rk`C)0zui zHfSu7Zv!{UKLzNi7PA%=xfO&p*&LQM{dJ!8K-_|0xtg2$rW`Ebq{TvBd9d{?u&F4wXj#mAN3^I1uCoeSDx3|>h%fDJICa%7>$t_C8w>6@v-q)0xLotd<-^zc+!timGgfx>OW$HtXc0K@ zE!)Q1VNQf*va`FOz3`&f2~}~gow;S-it{^uRyb6eXX15pcFLxC*W7gY{pHRaF57=P znQ6i0j&FG;Zk;pMwQUtVeP}ZK<_&+>f4$5j?tXTwdqb6RtUe!!^1uA691dzDWhVf4}DKX34v<{(DQ# z5x47>^Q3cU+OfRNd2*{QQBPea>)8yAZQSpsoSSSrGecB&)`!U%r?{V$U+Vp&c)y{% z_Rq^lulo58VoT3g1OD(;FE&h=6l6Ag>H9Ai4{WG8 zbl^i=VY=tRy%!T}ZoN@RNMClxQap|QMB~9L2YI>nnkyVhV>V~biSeoPGrx^!d&yHBqYI9(*`PPZ<`B@X6S$M1G zz0z#h)uC=9vC~N4={vXm4XIY&5(G{;aUAqeo4VN0qEdy;t*A1=?}c<_NW5wDMgC3k z-2q~U{@mCuxGSlao3S#FOZ4*jzfNsWe2StM*V`mSYz(p&I-Fw}$*A66(LQa)nuf{l zUxW8EWy&nz7GRk2&yMfTsi$9lSyiqH^ka%ypSI&k@R?e!#2k)?icHTLPec}Unab7t zea`g7D$7B!K+amQgh#RE_4SN-o0LyJ@rsbP>iaQMAe!^`=P3IlmERfM4llV;l4Eo1 zO~}!;y%}QFl@{H1^ur7G-B2!(I&Qr7?cIzio2-|wPRu>>>BEzQHaY*ZYd=hubw9bc zh(++}%6En72RvQY>|fKLA@{WNnx{PtZ!gR(*2i zRR@D)B}3=NKbiYhJaqWi!02fA&G}G{pKFtwD0|52TZ*QkJ2(;(dE9cO!%;s>E z2>+uZ)jHXIQ9?{$H)pMK|4Z)8K3@Az6cn0l7xIT=>eg z^@5p?%Eeg8Xztywx70BnzQMvIr`V!fW#hH`y`OTD=~la>%8E|~C;gb_xv@wJ7Gq34JCMJ-s(AaRn#{{3*LO>A$(w!FOa8mSo@LCh+!r37 z>r|9nom*VIOux#Y{N~$PiLnQ_mTzs2UN*`6(e;$V%CDtt-?h(r?I_d#l^Ffjt)%q! zmAAXDiZ4{s*w4KE_4~6+f4@>PpLuZJnP82%o@X!c>m5-%E6`tX5=&AQY;1VB^xcCE6+pB1 zP-&2o)V!4Zq%2-8Lo?JZudo)5shJ6JEu1ysk@=4;gh12!2i$iGW_xt)x>q%6p3WwZ z_e{x)zbi)aq|Ej+xsd2lvi$S=s>z9 zH6PJ-FAd$ZcVo-Rd&kC zUn`cZ5SCb1XZ%CD>erpFXFEiXx82wIxBuVvo|lt;s7(D<%Xode>$Pp>FCrW{@&oQF z#L0T!TQT9+azj(brE^cKeAIjy!&hQ5-}Vo)anF457v=LrUzlZE?wVX>Cw9WXw|3e* z79l^KfTtgxtc_2#(D)qE@noUxhg?3zi|c!T_lE47cxvioyGe`-?;VztWcw=R^yk#< zm@Uiy?71p=``Uy9-vXS~6tpiX%bxhEo++w$ZPh*B2`tkWOt|-Hkpp|hBkMjRi|Yy- z998wrKP2z`5?7iPt0L+ z4rf~S;)=ghwLMpD)w+WP8l015JRh+a$3^Wr%{HU%{UwEG_WGj>0|w})BS zc@IZQTkSf`CUuNiI_<@|-<^J2cJZH*C@$3C43=R`++6wM1)nsNk$iLCyFK^Cgo>)RPV~TvGKCW2nRF1P?+o;;(+hUT8M{oB-~Fs!x(_V6jXAyyKdx%_}DUwC_@te<_=uM+0ilpUc0O#;`~NeEtjByrj@x%{Y0 z{(`FW68f_@`b)6--kr4QyVv`Lw+^c5WvRTM;p?TJ@b})1ZRsJYsxq6oaucTB@6cKQ z!%s6P+mu(qIBefRvER$|93%3!o9qrLpQqcKx_IlJ`+a&9f|aV_iq1H zt~GoOQxvxVC?>@QY@A%~+G1oBCqUm&SOhPd6^v9dIdIv*{-bXX@2=^BcVds@^^q zSoKiDD9fGIn0ukwR)NyUYYS3)mbFQqUZs0o-(+2oJLft#PrJi;mswK^A{Z*d>oVCb zbUqoT+VUx@blLuBl$&NR=*c)uu;k)%xg5(c1kvEb3FCDw@yLRd(Zj%Z-Zy_ zB}jQby77CT<$*N}$CH{KI?k&;vF!S~2DeYr&tp#W+}$~i^}^ghi_O!{8m?HH?bf_d zo6&DW+PmXCURRGURPiZVl6A4*cEU?N=}RuwFZaynX)@Tzbx?gG%eT4?^)SWLASEp+ z*V_BuZBksa*{-DId2QKA_R|l)C?0sYhF|t>qI1LINO`MWpX-c1G#-psZ=Ymvk}>Yw zEs%)`_HS}$EVO=q+@PM#u4Vbvdxa75=PV?`wAWv5>wC9>QEgUCMfyAGU7!DLkYBE~ z^l`y8A#PEDVm~u6wa<1@yRr*nQ(mO0f4-a`#dYi9i)RK#32$Fosy#ElpgD8qd2q&f zzCNwvV5B+o41=Qy%a`Bwey~G8Q`tHC;k*myEM{=7d4E{L`t@x_cGbx;cUelKG%cU~ z-Cz_`$Ma%x-3`q*-;xhJ{IGcTB0p`_<9p=8+D`W~)?VVb?)+LS=6%zTZ-T+eMD>-o zPZ?at?~~pp?;rn_zn}MBu0D2cP4UvpJ58o9dCnkY#USu{cG}DN7nNr^pZyc? z_6NU8mdbmH4ND5e-K8EV9I&oTJ?HFj`QWCntFN`Wi)G&FTD6Ad9FKsw`&YM=O4c12 z_phj~IH7AZyLhAXETIE3dOM%3T`Irx)2SVXn|=m7pUR-29yrIyVc*}32Gc`Q4$HX> z`%M0a_ZIKY&X~;2TWmiiiu>%bQ!C_|+5^8mVN^+VJhJD%jQ4?g(F|K}%57!eclP`H z%CC!<7@eZ@o*iB!eAx6`vRJyGTjKU?3zdl2txl!qc0b@Nt3IpNpdC;OVNFBcDG z7nylte{qV>+|JhvEw(KWjH&+>(3&6{GMgpqxcJr0-1Aocnl;&>mgCI>qr)$59=10) z{H3x{?v2Kev^jgHD(;>9ZSD(u>0UQx&i2I@&n(=kGu=_C_+DA?@{0Dy+DoDiyqGb^ zfxmjnOo_SiQqv#0L~Zcr5cxX$jk0RXc5|y&rOYcWt|$nd$~snTd@SnAG;!7`^?_IN zHJTs4m-!*)eahzOn%i0pMrtoD3~L#tx7pkkD^Tj(Xu7&A!!hW6x0$z`x{vnPFB`>9 zd9znMuwJLL=HSI=Q#994`Jd&MIXiV`;{2r5yH7-4;HX>4H1%v^(8dU%EM2L{&9bao z*$cLwia9Z*X`8REOYAgL4&5JdI<9+jK1~ld3|J>pt+qUJYb#%FS=uCi;XALS*w-w` zj+PZ-ZHQ3X&J%nq9ZE z-*>L_@dqOFpM17Vc(X)aNZx(I(SM%>W?WkTnyHKX*n7ESOi_)+yM2zmxEXD~W}dj$ znfwi90$-SdgzQ^*b-pp*P;o3h@}x=VyS9K_LF1`{1Erge^*Fl-^Y%STET0wmr`LRK z57WoO^t18I4B?kfDB@`Gf|{G)1}3-xI=EWAsJm)mEnX9IBFFUhgh%J!wt}^I8%jO8 zcJ1A2>nj$yr7~mBUDjDgowhv<;f^*+QO*4KSMpxUt!EebHr$YVaN}G}@z1uy56?Wm z`Sq&&_9g?P=-7Besmo0PKm6;xFR47!Jn1U7x#f)6_3$Y+jfd{bNmSlCxPC^EUmEw% z?>Aq64gIn<^2^NxXyUugh|D3x$%6FMfx=7uL z_or_1ru0l~JMdregOPgVLc0tdE=eZ!+S=N!zY27wPg=>;Tf|p5-HXrj+OPMl8zMGL zXblq`NglQ>QZ{x=l5Voqyu+F4!kL24c1-^*eLeEP4eM?T-y9a5bDJ+e>rn3LwJ8>u_ixVXmPdbY zUai-6_#V&8V88tBRfZ4_yN0*(EW91&oSd?8;o<|W&hZY1%AQz}-XNtzHfwl$j%&DA-0)lT)m1N7nIrXJ_lCJ5 z{YJiD-v~HxsPpZKUTouIZf4^rXQF*g#c%hFmy0uMHU(c&aL;B=HaI27woUx8sHxJ0 zE~#imxutK9r3*$Z-)t8k7uILGX>-H*to{U^NR@<)@aazPg|j9$FzyXt-Zk$$e|eKl zTGR9edg(t`9x>|uTlIUs{QUoae!YCySYq24U;ZpTN2f>8ruFM2(FN%X{r;l9&&|H!47_-60hZ}Rs;%-WNCZe2~;xUOvX zj0rdO-}cJ6h-eySuI5!(J?%{PrL*m;GGD7ke!a^UV`BZ-&}HIOqp(bYZL{85W=)Jb zDRuPJ1&fZ#+oo>=zO#gx$u|6XeN^&V_4LgFb3KceeZ2qbtV~T`R?0n|l&e=>D}1a~ zJA0_?MbB|fg`Umx1siP*PP&x*-?Q>}n&Y+7txCId_hy9U`~F^H#OPM`Rp4B=-OQ-` zmP2{-@9F4FujN%=6S6k2_C<18th~7FrpcyzXSSWQIubga!R6ZANwH?T-|mXKGJBV7 z%~b1<&!xGNjLYhq^RGIH#cFd`q~{&K*P*}k{1`>IQcl|&dk(xis#m;e*feZ z{&v!z71z!mFMqJaUTSmY%Wv+NYtuHl&AFVNHTU+ls)~tnDSQhWuc)=m+G7?Fv-Y<+ zhqtl!BcrEHKEgLrX9S%2ED9EETZ}naON*dQ*&CDAWHwuD{E3 z&YFM!|D){l-^*{(jGo#E`f<-tn{wHMmFs@wG#8_)+#hLX=N>s3{G70G^R9`DH}4V% z*%$m{jU3a8K${1k{eAQ29Cyw7>MghVa^ii3DXj8M#-=|P8uk>au$?pV6}ozUj>?ZG ztui}%>f8)B2HA@~&+<61H`?-X;#NPIBqRRuBt{APw<(itC4BWMkuR9gluy?JeWctc_b<^vH4F+Zv?-Xog8`BG4 z-p%S|5C6ZHq4u%qf|hUXj3FFy4SUyHcz1H7pSpD+@PRGk>E^wkqvW3zC>peEdf+-^ zwseP4xU`4B!rTQmYh)fL=Iy`sJvT_%De{Bjo3}?7Px)?q=J2fp6+J~Q?Qa<@`UM+5 z8;BbSEPcuNT=2%LMSboDY0 z2)>l+{p$LzTB$nU?X`Qe>JI-}am@K~?PB3V2U*!XVaBNkk7-WH{+xD3)Zp2@Z@#?A z&)*jBo=~GVJ6AaFh`=}2&AF_e$SHEaIu=i4o;xYFaM`f{r&eJM36`cnF+ zQZHWMPbnAUmB+%MK|ltp^-_P8oS%m#A8daR@>V;8XR%CYqp`El<@7wEnj$^X-hB>7 zch)WIKf3aj&W>{J<9n8`d~=zxR@wb)v3j*rX*$b7&L0A)JNTB`R5&fIcA95o%`KrF z%PZIzso!E?X7o_OX1k{M6ZX20sYeR`FU=V z>%3kwrv~m?F1aIG{p5wpLF_epyXrF8+1_*i*)JXG zQjy}gXR$E1_KvxN{_4|2)Wm#CuTAvNW&cuTGO%D;}5MC*hytLaV=$c-_ ziwU=aE7Bt>EwUYCa_sZ(+^ygF^Lh%`)nkkLdwbmYrO)Xce3HvkVz2DJTYibfxz7&Y zxfw%PSwZ9Y4d;a1?8RT`BL&yf8ElODWY8)7>#O8(dB%=9gw zV!a{CQ}~aH?`@}KnWr}#=d$)}J(T?F{_i+-JvsiU0!%@@RKIG!JvsBwIjb@zdDmwz3o zh_I}RNoSnCH@PQm)2dwY^CjI^&l-K0=dx(@VwjWFNsSh=A6{mp+1vtC#2ob3N}Pn&D$U7nPmcg)`kSH7Li zX!n(ym33*n+SjE4+g%P^JMHGzSt*znyS>dlbH(q_tt(C*4%m8n6}x!<#W(LB7BWR^ zp7s))czfObki&g8Ij>zeXNgU%;Xk?R^-252!tc8-pFbhLeW#~y(2+{6cK^HTKMe&R z{g^4tzT-xVSZB%p$CH-7UcG3-R_1DsDQzAJ0fDyq_rv*116pnV+rC=C#CLh}2bX*E zRJNaARs78URh@d}rWt(~|CloDI+T!#qh*S^xN%UmOwA3kZm}{mu;3-?>VYTW(fN0F z34%7sA8@xk@ybKR)$_R~$D=KpkCvp&nHredxm?CcVU!QYnxTW?fmb#E0)%EK#j(Pw1xc%#VJ^e5fUDvqDq4SJ> z_-me?u_N%`kALsYubbzu|6jCqQPb6vvn8|G?z2AkG(MkPUO(sQdmZ7E8*cl))oE-} ztu4;j+MR82VonLmzq40YavnP%c`_)@bN`f{w@;70yBfT6${LXqCo`vYNj)(U-FdNI zlR<0#aZn*4FzNCZtu=K=gR0&gRG88#(3GZ>I#Fk?OlMtckjVISVT1Jb7qy=8aLMgLHw6;%5$p zJ6{|Zrz}_#w~AxYCp|v9hZ}6(uw4E%XXziEQ^HI-EP`cx4+FW@Eq7o!xTosTX1=qB z&lvrQtK@hRw==NG?d7tYN=&mwuCY&RSLf$%ay=03y7IG3^6~=R#1PS~6Fy(sblGcj zuR0ExLbJ|3gmZo8)wpv)La0*1soBSS>1EI7>VJuxKKQayJ4Kby0U3ytNEn_c~Kga3F%WeCUIDT^+jU;Xd+w*OZ4YxecNUHAK9 zUT4VEK#%8D^%XI^C3iJfc$~fz%d*%1#?j?1N1un~tLfjX?^@%Px`qA!od??MuWb6J zx`XTGE!)`ED{3WMPgN#eQ)F_VeECW7{>-%uWuaZwaS-Il!#iz>*luI_eib>sb*JQuiU7LxX>t}p0Pi?sKU**4zS@rw86~=*j z`^rBz|C==Hm9y$1`}dQ+uHWxv5EA{@aoyTi%xk__ZThOc{i$EBah}{7Vc}zU?!1q_ zTG#tmn8n22WHX<$tHQ?%%Py?m{O*?Dw-2AEdGBc35c4T$$I?kJQ;jx-+*@}yYUV+$ z%f!Fr%ha3<9#ae)T0`0wtyV1M+Z*|9$RkavRMA6VsGmS zzRqJ0PA11_FM9u^W8W=--nx`_6EP)g6}iKna*rbg|JuxJjuXt~+gh_au;q+mL&BBq zf{z0BwN99G`*hoj;`c^vPn?Vl7W0R^nsa-OK!Re&iod^W?gg$n_sH-XH}7VS0^8Gx zn~r?jAaUqML+bk$jx($e(o-{LZ;`9{JDsUS)>L6r`%DR?>IfD8&F!v&w?OHdH$pY% zefHlIa%nm)-!?={sp9We+EgJI*7r2=SN!X44hKmNhM4b*482_bJd2W!5cBIxNmOq* zxrpPeLi2^p7J;up-*-rE=s57}^e>0cE5vW53x3%1wlzJg_E-JgxPR@hnY2T!Z=Txh z{@RI^<=e8k@@;QFhp{Z^EwZtR6)dVa^+@~BhxKK5_|J+NZM-P|`|KUwzb$XMPED!5 zF?*T%**d8=Rs#1J-UvE}9C9n2bKrf=R-uy$|2JwcEaKk(&3S*7$O4@c*-X!Mrnj!k zFW;SadF$UbPRXn-%dWAgX?}k0f8G50Yx}yo<^LBYe+^>@FW${#!{Z)d{XTlpqDkf! zFX}I;b598_{O0arzxa;&uSG12_B z9MZynCUMKD{oHcq(yWL5J0~vg-#O*7&8Hd18M5xU+E`dhIC$>6C|>%jM6H^^K!EAW zl{SgK2P*vT0mYtwlz#d3y$~-DUQ-viWX@xb4FXO95}aEOB!75vP$ENceWSYjm%ma4 zf(lx#@vQ<)sgWjZ{&GEysU}r?^JFfj-?MaRIePPRozn}MbAqi((HZs|odPv&j!m|? zqu0%Fdt<@HO4-Ff3|lq^PLWeG5apUUZDH!kst;e|xh}-6XH*sWx<*~c>8OCqjD5XN zB8^j(+ZMzv_>tqFomdtBnt7Gg=_^W8S_KY$)0123a^(D-TL(TB6shpv{vS1e`tvK- z6~S`)a;m34wSL}Uw!vnO%*n&&7$zT&ERWpi$CSO#qh{Iv>4FjYk@6XAVSQWADLttC zGS5g){Y-M)icHo>r9EvE>#ek+I8q93%k!hXOdSiKczoON_2=3r>FYGtMe1cm=-F+(%p(`l z_WnTZ{gcI2_cl#DJX=$|yZQ0Cg>M&Km%FlPL#f=A)Qi`b%#E9zDc3*yr^TuF$@<&- zuCsKM-&XCIOf>=3la{zmpjmTG#G2Llk1B_Dzs|A)^o8p?kc*^mlFHatx-o{bzUDm_6`{E@Dr`rsNLR`wOM#-~Z3*7gO`{}Cq zEi!ZFls8Y){?52__v?&0A;I+%H!e(exXrn`;icGG*_2sq3%)cnRA2wd;Vm1@vrxO` zX}~R}wqlLFTr8CtFRv1M) zttgv^Uc8fd?k}|Rk`IIanRzz%PF6{Ld*W=r{qee+ zTb`8V{mM1YQ!kpn#{SN|SWV+sSJmPVdM*96m_^RPVu#o(R}KH;vnw?UA}dy?FaNT` zWlPZIiBnf<%oBQj|5o9o(1xc6TtB~OWax|k&BcrLk}mT>yi&p31Z(Tqh}gB5Yr=0A zJ>DT$TR!zaWB-@1BdQJ`zHPHM4!gEevReCDmHf4pBC3sM!9p)5Y_Yw!-k&)mV2P_k z(WIHHCYsd#YRh{hQ+Mk8`MQ`QC(pQf^DiFY4-z^M|5vxiX}+tjVrYt$+Ie`TFPS_qJ!kadel$B&aL86@HwLufd>~fc{uOy`n9k= z#%AlHHT$}GC$3wf>B;}Hw&$SFVxMx({gEsuJ?E&@HRe~+)8UOp4R-9j{eK?_=p}0&<_M&~OvgH{A1%*R0O{^Q`t#--W zOwUeme6+kz&aJGwUQJ)(OTUsh1JfDCM;Rqu?ZqjE=E*bG7v#^EzZ`gAgJ!1=i}r## zA^CMpvI~=4B2AoR@{*^lj9PQs;^Th}hg@llzUQk*f?c_Scb;iWot4*TIc@pPpJlpU+@y)hIS=O3U>N?d2JPkv&r*3Gx z-8ea@_WUdD&nEZwt}=hLd*`W%^Eo!1a4UJeEh_Zu;Tv2rQ~Nipzgotvv*?oMvP8u* z$5S3!dH=t2?a9W9iCdhW$j-n2@6+e?)4T5aZd()_Id9>Dvfs-ldA(DAvg_qhyFc?z zeDl>%n{v)KvTRZKF2=gO%hzjiPu`SU#uc7pw)Tb9ROR-~-$f3&1hV)xBy_*c{&;Po zz3Xk6P?bP|K2cALKo#u(mDAgV7Ob;7{b2b^{&{Z6e;e1H@9blW3ck2?n?qRN(?8;O zmKV-ZFbw|rR@QiVU{dn4r}x+Et>0hsuZnw>isxhItZUb0o;OaOaxrf&+tRz9r}P?j zJ&}=Q+uc3oqWx6%6nBrHd5#LtBeNxLKKGo;=X>t=<&TPIZeE?*@b6CIG+o0_B zjy@*8#mRCX{!7dD&k*d)C|a2tb_7$G*Y=5=|YolP!$8S~e1x zX+ARfv$etng9JY&*WF)lO)67w+{N%JtSCj|jUJQhf0N1l8$}g4OV|`8v*eTKJ@_X0 z?9H9@nWyVFME_CV`S=CDm951N-ESNn2HhTs?lHD+-hMV+QgCja+_$oB`_G#fwsYi^ zF|f>FJh1NY<)rlqDf8DV@Jx+zt(W^9XcL=OvEoVh9gBlkWW2IA&E9!4MKW&VQI>|7 zgwOU#a`Q~8Tv~PrSh0B^O3_y)W_o;TyTNFVe;SD&P2bxLrt4>yS)R#j6(q zhqrjJ^mNa$F*|2JtvmW5w8ZaM1Sp!-kobEa0`(T@>F3)gyn zTT?e{(q*jl$G-Az^5*E)TM=zfIxn$!s_x1giw6(S9)WIfJ!J?&8wN{z0z4mO0meoJkMT+x6np0J`9c#7O zx=6V6eb&UZO+k^H*M)1Yy&Uyh>s9-|LPpP1udFrvl{YPao^|zvN$B>Ad))3dxa~Wf z965{ma(d;ggk_(qyxU%E?Bcs`@uYHU)0Y`#Y)?LJQ6`9R17247@1C~}DO=B*8Q*vqIwC!ErZk#W0 zi`sI$kSXi#iIShiN|(idGfy)53odhKKMis{|0lzwqR%mKWxI}-?cL{%7Rwj>jVb9X z)1Di=s-=7Gxmbo;?OVnR=H6y$6|=r|U-6t_lk=SDY>7A1q$aGA{g<)*m-frve}V!X zu5*%GB3|)N&%`Z04^+E>+3?(@O( zFD~p6SpRoV=C&tZRnv|}O}M>pg}LkQmnZg4kH32_o`Lz21+!3$+1qt5tczBk*b*hK zRep2JlX8u=3+N(&2%%{c@s1f<<#nA_6m#No10;MQ~hi6!dd@$ z7-XiMXT{M{8^km0=2&OgjV*~B#*CTdpFhVy;OKjgns!Sk)n)(MbJqpV&e9IGO)zcG z<7au((REbYN9gJ8>k?bMl=ay5&oqB;erKl5?;8Dvrou`$P9a_uyWgJXH#7pAl%6K& zRk}UUe6@e8$ULVSXD5jnb-(lCKCk&<_^q4&-r5WMV&(p_+_h<_+#O|c_MHCoJlVf7 zv-ZzcU)sLXNh^X`^mtSt6 zDN$X;#Ap`7Up<#d!^jt#7DW|>-C2Hv@z(0M?&jY(8C@hk7@TXa=Y1;wx%Tw3zML3^ z%oDnIHTuoJ*VBrWJ^v9JcyYQT&)*8dwt>ClH01S zf=T+lrtMLR&lMgq1Ua|{Y&@ZP{?78`_w8Cz*WZUY-47{$rYyHibd%H$r^xsA0Wu-) zn*VL`z7Y|ivVG=1P6LKtpXOb`k@QF&LN`$`1f5MA1RBORQ!oS#bA#FD3WlH#2bfL4 z8fFWS;rXED%r>Cq&af371|~!vSTJY$?Y!G=0&VYEU&wx&q^HzY{pjH)-`Uq(Coyfj z6Qknl=so3Zm{RPdRg<^BFDRe3DCO)WEv6$=($c=qpL_G?5&3DKZ@%8%Rk-cWnRFYj z#Zz2AoVWATbzT^`=+Ol4ZFkP53+`@jn4fR4JO5#@glm&-_}}lRm;cnMh+j8r*IIMg z-9NYOUcFss{k5E*Z#O1fzq%~1tTO!C)vKS@*9AW`J1QGIEiG}{29-yD=htmN-^jII zY|d+y9~ zoS(aI_W3%4&SNf%VqVmpw|Khnh>POZ8_U>ss;liifAG`7gxOWQ*UmrnYF=)y*few2 z+uM)Mnkt&@du#2<-OYQVzkLa4u#GSMU2|IN%%l4?yV;{d9j;t;TCrgD+xxo@Efd?w z%3mp#x$V!zj?UyM7wp7V7X^#Gp5VwKesFpFq9j?4&DEQC8Cq{XzAR2Oms|e-x>w7^ zVm|df6n5!<^T|d%EpJ|5Qr~M)68_=c+xhZ& z_y2$S_^UT_Uh8KY%Ox6xqQ%R~a%Q-d9pLfh%?}_&Ma-Q4!V>$oJS04l2CQ8N5IKTMJjfm{$U9YsZp4%-G zz21~<;|tbg*43pSuYQqP(O}mV!?kViq6KUEOm`G_P0?O+TKL=UW|3d+8n-|0PZ8GyFoo?456ZKW^jhq^XC$)?Dk?iM=yb_I7w~<$d`puN3naoSLx5)SOs3!x3tvtLV}5WTMCo}}}8 z=@yT}7RK6Xis6^mY3$JD@X68*iRah+eembvleMkAcf*DA_Jn0#kbjqvQEdEjYsc@6 zxz9{=6x$MObKdJ7KRl;S1ywptuelT*F^Os)U+rz>2?vtbvhf9gZ zulL7X4D6r$VB|L6|L0pFXUqdh{;19GH6^A5#2GA@yQjm;!(O6>?~a=1yN0rttjxzQ zCmdkSFqi=HJ;VAL>T+*W_RRdHcaNEEdkZ^Hit0zciCQopKVgxmk=wym^P0K2Y0{4a z1tJiSK44_d`p|H2vU=0O*M?$V<*KDZ>s}koV`}bRe&9hMy5~L^8F>O@W~Gr{TjI)Zc{2N6&GJQ-M#pSw`|V-NOpexfaZ4bc{UTpJ*N0V=kJirZGrxTQXf?yb zX&)Gx)~MW54O+T+a_g*;g1v_}b2|L6Dd^Ss$mHa*QCz_N<8-SVb({I*92T(gE7(*j zDeRF;URV+yr2cRh-(yXO9Ti*xa;@tgFGKYTW7G0Wj7cUNx1WD*%*v&yS3mc`tjjY3 z9$)XA-psUnHbW~%7bv+0q^IX?$(m|77rfTt|;)X2yhG&$`@T(v>~{4R*6KF>P&~$^UT*f zwup<`1jU8O9F2dK@cXP)ML?sJ&593CI#+x^$}GzR9zN0xsSx3lHGk16{P*ka zoTsK`&d6B7{mM_)i8*=>MH)FKpS%ux z^zZTODz32!IuVeemgw>NVNH_uqwk9{f7?7fTN?2BK12VsD?Zp;I2NE53Zg+Vs1^xW z7-Jg-H8is%a``H#u_J9R(Dt79hit`8Erqt{Pvg`)VwQLWs!W^Ry+cF9+bHD5t&mBx zpS^X~Yya}fVDltlg$+jkWll(*OW!*)CT`CzBcDwtAANG-(z6kMnE&gf`JR=LxiZsd z`O4|*v+U;o6~A6}_x%?C7>=WA$1yw+ur;-{`mU0M&EE_v!5Sx z&)r)u_V!oduGnp>FFu(+BlzhYEmfZRQ+r>=DDRl08S9a-o8@Y*>c8&~FTd@`H2t^h z&ZgDvWxHAv_$(VrW=Wr%le;5x*96|_Zp$Z}D!G?@bnEmSot=F3H=g94n(Y$5ia)%* zzUuq0=CH*Z*KS>V?ek0LA0Mti*?zja{NXp1=uIEizgc(crj<)#le9du*0y=^aXNK3 zx4WO-AuPIE=#J^ZcRMCOs9)!>Z1Ez=1NT@h(!%fDe)B&2oq?nHgANBz4Z)QQZcOBw z5>j}MqkhBUf3t2sw-#%3!a ze9Y?_B;3A>xIZ(zk?MOU`TqYH$64D|IA*&@#0X|tEYlEfo)_#nBg^TczQ}y9H)@}* zH11b;bMgOyxLdtp5o&n>jituV51hNOSw8>Tf(O3GIW;fZYVR)Wa-JAgesA*b-#htk zhqtn%o<3C8K6PJ*cJ0nx^7Yx%SL^=H|MkJ-x$~Y4_tN81ymmNnrk`8d!t4KwL-mj3 zl!9gMogW^~6neS$=7r=g{si~?i?_BtV^*E;azX~%2I)!s5BfhdGCinq(AFqh!c>vj zVt*s>f8NjZ`X+u$mV@kDCV!Z6L91If`^tg^XS(DbFfVP8aGO-qQP#z8{qH%~r9G;Q z2iaFNK432Nd%(Q%g?N|0YMF55s{`_noxdIb;ShrCt;sb9SeJi1=(Ybad%E8fW}VOC z9}iY+Ki_Wk;b3?1&xAvh+3YIrIb_Cbsk+aZF%FNZaIxT77VSNXO}rJmVHT- zTAdLPz%h3?9Wxu}HnDCb~;E4c>#s$Aavz=D! zl&uMDZZgs?Vi1|al=PyF#dS;Yf*T+0!zVn`<>Ux(;APS1C}z^|aNQqJqqTANiD34B z5*nNA*|-)RGAeB5S~J^{y{v8CTozV63tkboU9tf!yp>WK39I*Wh}@dZ(Z z`~=0R>G|i9+xXVcPH59UQ}EH^_l1Dn7dU=0n@%aaJNJnH?;97wCf#7L{^he()Wl4q z(TCm5xFL4J4TgFdX#s}gY*CIIl|>IQtNc0G_p99J#6K3ZA`T|$4E2Yt3q!@MudQ%& zoF{sjC!smWfhTtIjgB%dX;|<#@~&t+z*gvYfDJkL54(LkzQHkMhI(EEELBauae#Gs zqHqQzAFs*g5M$jS=FvE$yq?av6@q# zckQMd8^d_HPHnlt*b%_hvCx!rV#acXO^@r>Dfq?+2?#VwadZegX93Age05;C(C$u~ z(g*$yD(wmiPFEtI zi)HH6nd@p+zR6eVL#@!d>5x^;4n&dzWDH=Oj}m?u)Z(k|{#>DPZ}-5K5lS`k10$K-j`j`%Xx^&mPz%X(j$fAg6v+a)}8OD=~(=8*6q8J+y~z- zbe(WS^_NOilwQ;yPf(paFQqS;|J4eG?_E#V`SPjczdD?DKy*Xf#nwg3ffIiKVH866YHlbTMI=Fd(1CauH9HA zVZT-!R4MQJQ+}-f;~}f?Plw)oe01)!)9MXBc7J_*x#-(llcb3MRq_Ily_cTJh&jE@ zsPJF^-fLRU8z0|YKfmtxkAM7YZR}EV4{hu@)@zu%wPKE)PT1wM-k{TxE%+9)=7IUuB ziH|$F-%Tyw{aoRY&5hTr%Cmzmt~F4YW9=#5$g{M;v`0np@=?tbZ=Ujt9?9!rVlsNr z*ub;Vzkz3^M(-or?zt|nJWm`~nEc7`M8n}98{!32xVV~a84e!aC^^}7k)$EBXG4gE zkR7jm*e=^YGR^!ky6g5#vGp~N-ZpRZZV%3FzrKGg+vfS<N=%md zCI83wQZLD`>_2qgWR|&9&;K~jpveF5xze9I0Y9#$as25KlvTJ;$W&M| zr=)OYXQ2~k${qVC#p9{=GR(IXW91{|rDJ+MIGQ?blR{uJ+@EPpNuvHS@T zcinTH^~~%yOmodsTNxi-@!a)RPMy)-i!pn}vVbpF0!p_F+*_OaFTnB5F%5+W>~b7G z1b?&qnAmkm?VIW+M@<_F_L zCCk4kAN0RHO}qO*{qOxZR-gHAnC9AnJafmhZTl=I#ib3Ve;VJ3*qYYFd}UM$)%e`bm1OS5 z*y!}ZVZnqO>I)`>OmX`-@2H>BSCuEp8a_WIxDG1z9lDgj&-Jk&=U7UAhT9njAqCOC z7Jui3pZd3Nvlro-YPcs;K;)b)*V3Zq2noB?Df#S)50xS&Y}o1)^7X{~J*Vu2IA*^) z^h2oS6+_FW-M&$)L(~?EvT*JWKfm=yPNRiY^sXH_9XFjgQ*5}mIQ5;b3u3$ASa&-~ zrG>SM}|vty7E+*Wk-OvF)L+y!?VgasL7wU$_aBEN@w8F!ROaCw)%k ztETkD`fG$FioT8dqO(Bzv)=`a9Ok#`6JPI7P^=LWW&55`t|N16qeaFRSwm)p16nei z^N%^*yz#E|*Te{otq7Bm$>fvwsWqa@Hgz+zr(>W?l7Cr0W$x}# zSs=oA@`q1nVa+m*>wg{3h&Tzbv&Dg8d`iQF{`;(njDPeXQC?#%{8PaF^I=#0r^4k2 zx3Cn7yTm@Rc*JD4e>3-&&%4)va_q{N{}ebpG#^Q=)n#c{t%>+*$aqbEGy5@T^0zM$npeLa&cg)t{% zOal`)#p&OCnq__a%<^*M^D|$*s@t`*KF$2Y z=H<@YUHgmw!kcIR85x8=H@o9#ZJ9-(09v8 zEJ<}qP0mkAg`5UcTvC*pn9IxM(HS%Gbk<=50oU(r{}1cDZCYLxIcfVsU(bcw-DMX` z9$FNwnsmd_tmRMbQ}%_t_f9;@cy?y))Xv4nw=!@o>s0odkfHE!w*RgJPK`oBn(W10 z%1rGC_D>PvtNj6*Rjb-#KHb9WUd-Fw`?A?I)-R7OZ&`J>dFMRcoLkF2FV8B7ojq&* zM)jrM!L1=1n2h>%E@C=!IYdvy_t(MQ-!^>sWbc<|AkiUNw|>v+GWXfCxz!T;66<;{ zXScG>J~oT*bBL4j;>!W^J?EwQsOg+tF>Q|OYtOCipK`LV@2I-eX24LhqwId{uP>+f z^!a5KK4S88%nRClVH$Vg^K}zFl>YDdENL2hBI`2WHS^Hig)&ZgQ}2J@;Cp7-on^r@ zpKs8zdgg!7am7-@=M%J_$hZhhU@~gzYTRCU#YSg$)QSrh|D8E&7l%EwlUpXbNoI%B z%=6y-i;6gJ{;E6Eq_orWFP8zsdX~1k*b|c_>dX`oiHXKjWtO1%HjETxXiEIGz0vu% z%|swuOm;Rz#;IlA*y{YKb-lQ+F@AFBYsPH?uiJ}3jMP3n)O`qrS}&4mlo>WdK4Ia_UxniU*$jFwB~48#B?^@ zEAeFD9JPq09tDlbjni1TTeEEEKh1x(S-SbDMe4Z?wME;KR~mS)eY=#i@AiWpX%QLE zogI0(A}dZ^Ouzf$SK#}$xIKG&nO83HiDI@ny2o4fMStuk1JjqaM$^_9xrm*%aPt1G z>7jKo)@9fHC(M?mEZ4IJ~aopt}L|(@ps+n?)!1RA-iUWt zTVTth2;ZL%o+`>uF=;W{xNkE1_2YV;WwsZD_?6bQ8L~XCxzrvf_n}eJ%X9g)?nd_H zqSMQS4Zn00@O1h925Xb}VW7yrZu*6D&!f0HcRTG8Dppiqy<$51n&OE*?-KO+*M&E~ z@$5YMmGh$Vnl{501)<3%XV{xK&Zz%bFuncO-%yA17My-NzBfElsq@rKbXl%Ek@*P6 z>PDFit20@LzuI#Zta-{{C?i%V!D!c`Wb?Y^aZA;-8mWgR7WRkEh@Ejc9+PJ)lJM!$ zX*ouzV*<9HS@xQAytMspmp(0Rc_eYd{qcvGXV*?ktbWZWrQmQ_V$t$R3#Qx7 z-rL1t*t%V?D_KEay(yg0{M#z0%!~tlZ?`&nrTw_Xf8!KiL*A+4>wNYL)Ms!>d_DOi z;&=MWvpxL523Gz%+`K}0-d*AD)es&!+j)XnsUxyBP_sH$uY^OZ?nczJVes_usq@yFN6cr-uy z{PZf5F>{Y6gN4D4pK-mn-(TJFJFeGi&BrVe#=GsePa7waGWj z4(*$}Aa`ch+DRF_LSKxtcKv%P{cch1jfment|ebQerlDxufSV_{W-H<6=a!a&Fi22 zsvy*2-_o$E`YWl`3p1-PdMN!065YK~Z&%T|@0WeAi9|1%Hap#5pY7GHdfU&hFWHg5 zx!-E_#NZ2COgCK0IK1(N8HaNC+O*8YYd3GQym8j3(z!BLRxspLa^PI4FAHy63k`mn zJ6&t@)Z=S%tJ0*ec*@u8@18dC-n_Vg;IMZA?v8pt)b?DS{@Yur%jeU&r0;i59&1@6 z+-0cvzU7ry#X93Gf6-!-8NDvG>{9*iQBi)IgKTvD+>Ubk&9wdSrg_t3%R9jmZ~d+9 zEDr5+%RZr7#eZ|%=bY6SSGBgJe_iKTe(~4eS9y$X8FRWg?(VwlGHuD{q}f~B>!6IA zpK;tRPaR8t@sx%j39rXJyJiXKO+GSnZdqm1&z%Uzw1mID{^)& zV3{n?@w3!Fu|=6Ph-F4m!0x9_2d+J^&(+Au{@liyxM0$^-BnR~7fR=aq{gQ4=ERkK zf69EsmFrdN`iHAdoXQe6uZ&!CWqsM%1@XZNV!woJ8dDvV1H@w=9uRXg`)wOy^=_5w z)4cx+=I07B$sILO`ZwW-wVAB`;TP6Q=Udj;Xlc66IaqsdP2Gy~r(3NG9bYvy&fqi> z=Q-&!VYfo+L!XcxD`v1n=Uv&f#o+!Si(MDDuB&@p5~NyTt&@IunJ&-g34T#8O^SHe zez!XLnBDC93Ff`)N}1-a-6Qby?fs8y1Kgiw$Edrl`Fxt+-2KOiiCfIqZmGN|GjWRV zO@oqu#_Num{IR^Nt0=Vaw$0TEGv-)ieo^_DAW`M)kb%i#=d?o2!X>xDr5#X?iR*QM{o7DvqZTya72 z8r%Lw&y;7KO)7r(;9TqU{^-Bolay!fEOfo+VCbE#vdKBkz44&I@_QPVmJ>fec6`)v zQ!-zEm!Q7WnGExX?P-GBQ=KQWuDBZ{QP6g+tnd1UOm>fH>SfECXTB?#EuQ%^V!+e60hQkF@kiltk3M&C4& zKWpoD`*f!h-?FfdTE2Zp<}@3yoGJOvG40G9<+c1`^v}n_ED$K znfx)24#@v{x^7keu2r|=0({u~>RBWhtZI(pYK@`}RuYjzX`L-mSCT>dGlqsnL>@jl zXL@e_BR7HL_mw}&ep_mJGWvaU`P*uC8JQ4UzC`t_D_3eAmw3hX=7ibFrStdwe)4qY z<5?aP6|MLGJpb;@n+kz)>-{~N4hnIl)+d_d7;HYSp5NiG@Qrafj}p_P-0hDWw;KGA zQQWZZsQQaai6blj*wwu*o1Q5fn5;66vS>~rrFOL5A zSiYmwE1_d+@K=!*gC`BFGF1ydz4S77+4=MEN5wW^%|R z|Mk?1`Y?;wZCGDm(jf6tfTdS!mhj$`%y~H?3(Pj%n7Y@2M^k`LkyqE_w9)SmYOKfV z&+a>R|JmYs-c0@0_saeMe2I~1yHlxgY5!y`&)I8E{XaWx!Nf!J=PU~G_qWx($E??+ z@ufzf{!&iLUWM07?K`U0$yY2aYn;-3;idicr)k$y7KE`c==|8ec=M%Qyy{Z5|BPlG zbz0ZHF)i^Z*Bp)L{LPC3AAM6OU+;0tzHV-vkduM(tr;GZ+UFcMijVuGm;3BiN6``+ zrOYKZ=Qb^2(oc=+kY)1aj61JTef;yrg$l=1Sf#yQ^yE8EdFe7+XlK+6p=_(0Yd7C! z>JW9<(AiwjqS7YCQ_fK~|1+D2`C&sIVK&Dz(*^G5wKcA(J0fAHBewYFhuH?oxyJ&P zQzl%g3wSFWfIDis-X2884~acT>L9K`P38>e}sL zr+yrm_Q>J(rsm|GIaM*9FE&hi{y#UKk`;M2Nu*Immd zW$_?yuTJxwrSjCvII;Cd& zgpbX(tSM<_0z`=V`9XW*hYDlGTgVx}oYO}v=Y*B+(YQLFM}&Ft84 zm4LM>!s182Z&=4=e7yB+;ZOBbVfKn^Y|ZX`i>_gR9dV=A=vYz+*X=-0(f3M|bszi> zF*sJ1w(!E@eQR&G_As3I_4sYd!aZMBSQxwaNgQYO(BHb&b#}$RQ<5nGZ`Sk)U5sG; zBje4t?$NZiuf82?H++;en0rLm$z|1~8%lnYf2>ldsxZ~R#d76ip!EHxEPIr_X4+J} zuGZsPxk~WEKLd(-wz%;4HZ&j*p+R+NBPRom~ z9j#XwlS@}$b>Q8!+9ve#);+HeyszA-bN`iD;!aOfA%}OxYAh>m2K68GZ@F}N$`be2 z3vRL<|9%l!{GeQ|fCcmu{ z<$bftv1XSe%W83fLyEWKQ+>QE&#a1a>t2v<`q!M{Pl4?U91R`RQ5YhMQIZ-upyPQ- zIKkJ*0DG6-z|@ks#tmpe$YV3;f)Gt{gVTp6h*V#{d##kKMEc0BXGy^#QPJO4d8~2x zrnEahzH9l3O{&_i4F}AY_43JnZU>Rn+b>&$e1crg%>O+lYmI1-g5gt* z>REmqw`M-Cj}F{oJtKdHK-;F$&(+_I=Bm_BdA-XjerS}{TRt7Ru&b~UT%2JMzh5gPkB-=^)> z{^TC~_UH3Y8QZRJys z{LO4Cx;9=71<~diQ9aYHWUgopKOXESdugTh>o&*2O^=~?C3R$;F@-5UBJ22oo0M8 z0!OwLh8UYj?wYXR7!PB)$)-fF{u!z2nsP^ZzWtA!zApJad#uyVHx)Y9rapVGJ?~{x z!7MH$X$o+ z##}RA8uuT#`Tr|NNOy+SFI%Q9Ak@@vb57aewsOZd_YX4?`x$ck8EoBuH!OG|xZthe z5rY?9?hV`A8&1nTJS9~MR=>kWjO}Rb2aXHhI4(REJoY+Q0bl}0n zx}{g{fz32Luv(7smK`tK{AuS+)J=E{E00`|dya`m8~2(wnre2AgNZ8yoMuut~r%cc7zhwbwNd7UJ({ldX z55=A3Yokuh`?jrG_4d9UYqd_X9a-re=5Y1f?d$x)%!-_j+G`mq>pp+)Nw=w+%gH7nZv78it_x;cDf(d^% z$K{-k-Fav7&GpaMKQ%YHZ!_`Fb#KQ!v(rVtZSJo>eOBZDeM`})!Gboo-aB19BQV!c ztD+!XR^z<_qv5|@_a@&i+WhH=Y*I;g*}9$Wl76XTi8d>EcddQ&f6|}RZ-4JDU%WBt zlFFOqu}W^q6Fawj+7Z3p?C9ke#s9Y7el{a`o~3Vo(?{nG(-;m#chCCz{p`ltf5!_i z%=v43>$FbkH<`V&pRAjaf6{yBy*J&uH>WRg>|I>R*2OT{i(gP&;rSw)w5Az8hV6oZ zr zlVAD*DVObQr?q}!$qVm_+wkm0q>Nfnf>NmO?N3sfp-!x7A)R&`f-_~0uA8y&)RA9P zj^BOaZ1~@8%NK{&4`ywep6L}Vx>4ZtyyKhp?>rqG{VnR3gyG`9+e(`Fn(Ll_f5W5j zKv7^xcdNPt50B6)i8;o6O78+$PuKi@5a_zM$U3A|tRX4qD9ePGY^L4Zsy!O2Q`bLO zk$EZlQs#m;l3X4hjqFP@^SG|N;>`gJcJO?9zFTR2@VH&?9NxVXGwg30P< zLiY_P6eX`*y*5`ayo4vg%1?Gl>*Enx3X!_G`!oB!m z;C%jlUcZA%%a4^=#*3tE+rIwV&u^LTa+Ck0eY242wY)yl=fn~F#PXDHK|0q?e?4TM z-dTHNlK<^qlgM`~I^s&d8nh z*+w!qZiX=iwlN8CPRjB;)+3c@ZYQG?>v1L)jzZB4Wt3^a8-`eW*A^B;E=^i8J=XuWfk@kX?XUJf zj9gcx%hw;dc{d>?HA#5UMKjK2E2oH*F7mxvCiUm{Pvx@xk3?qd$PE0m=eddhqsNyQ z-L9No>=J1BvP|Qki{hgHchsjo)N$3EKEo*F%r4m`xi4Smw~5%U`C{(Fu^=huU;Ll9 zWs~$Tf7}!mI@wgp?) z_u`^i=dM2$TB}_m5IEGgA^y2xOg&Kd`l@G5tpBtb|25vLGkMD|tWTUIynK56=KSzE6WKisI?ZN_r1RJ$Ckyq?xWZwXH0g=8+QqQR zix_j&Zr*D4+;Vmab6vM*jMkiuX_G}NCws=c*(02+rnxCs=nC)EnSztg%~t-%UQLflFa9C%wQ3mET!n~6O?jXCBsxx>O$J2wYD=@a@Ax%MEfK;C7zh&yXeC< z*@+wHevk1{?KO|9m_8$)bCLAvG|{hS8#{b;r`RMoRLqaq?5{iJVA~ZH0*sO_5Uo?C2D}#kcwH|0ro1NR4AAR&d(YaMOA8o9u>J4YG z&fmN2+_`mn^#*?n3Tm_0h8?p1RQl$|(RX)!_V+BE61D!&rrPyUhLsNjPOgn;oV=gO z_=Cg=qtvsj4BOMT7Ji8>Q}~?q=#JGXXUDU0vJYF?7Ul)K`KWfhQ1jdzy>HF4|L?qY zuXe=%j3&Kw zunycE`TttalHHdyeN-m?+w>qjDCF0a!bGcCJ;zj~)_v_v-m)it;q4_mB<_9Fc@`sI zw8C;{fQjp@r5h5e?j7z?T*rN(*=_y{N=}M@ug93{>Ll` z;$hl2_qg{ir~Ok;PyMN@p|)^YJrfT@WxMBd9OcR2>S%)ZZDPzFTbdKOt#{7!{Cp`( zfn%V-x<5jGhtkjAh|7;(RvumTYOBYZTVB&wElTNJA!Nqnm%Fd_?brFdSF&em1+kp? z{Q1o0^XG1af35hEuF9eQHO=NxkCE?;pT+Y7lvq8v7HYT$-S2nrxihOF+}kgY|Cw|u zkH_9^`>)?Ww)o`!+h6zDZkeqdX?L$a^Zkjea_3ja+uQcs%f0pY@2efT<(Gf0zAJKQ z*@H5Z`;M13DXdBn*>U?^j>0ZpHLo-Ka{8a7R{t-!Uh{qdyMGY#%i^QfaR*mwDD%f2 z(kq?(rGE0S&!>;h?)UOZXG*b5ye~Pq#;RE;oW)bs$xHs7KB~{e zzfp`yO(%r( zWK~{tm}P4!@MF`TZ7e4lnR`f3nZz=IS|{ z{Do$Gz9GoP$YD4~^Sx)qO>`yfmC}EM=)@ z0$Y`T*sRJaZpqgT4ZJ>Iez2?M<(AGF3zLJx=2WiHDr$R{5jMB7!0)_d)(Xo?ANG=8 zH!68OY&Ih=nj^5w5fLfsUe zmld~a-}-P)dwg%FQIuY-(#d6#_fO3`R=kB<>)7>G#~t~~9gk?Oxbb+?V`J4MM{je} z-Tb@WoO8F5>u=hkb|glWH+^%Ic}k_p_v2UpJ#$#6{`K|KuUD2F2-Q?u@=9+q`=*+V zYq!sq-Hp}h+?h0q|Mp$q-){xd${xDwW<{NFn#uBJZtqU(r>0zmc9V{tw0hpc77+`!0?YrypZdx-_!&W$J{2D$}g2%29+I0rhv zU|~t@zVNWz{>5ej|Kv3PC)&*l{+O8j=Tl+v$++!VOM@NvPA>c1sOsmmwNb?5`?veo z*_<0rzkBI7QRq=+^|P6Y$5yB8tf)WT;IJuL&!d5vv+-w%e^8>TgF&As$H~H-90~bf z?2oa0+xoM;xxs1D&CgFNcRJKRi448=bY0_*r#~X>9HVj+D=jm3XqTmy`pn*=v*(Gt z^yF`bu?G~R9NzTzwpp~$<^AuV6r(CP<&y+)Z@Yb zQW{<+-@7uQ$}W-PmEQYj6U+)cvMa6}a}l3<+9|)DG5gIGt+`XLioKeA?o;f#Z0*ng z{OUHh{9+Lnb(ye6w_^eq`=WBze*M}D4?W^7n*Lu}zWEq~TkE1DN50fF*Q~iH_oVcD zwce-t^L{He=N8S9-L>2~DtG?nQ;pvDN_jRGzP+qv{iOHYtm4#9*7N;RufEWo7jAu| ztL(~l|JbvZ4`-~JR(aowFZ%fRW&c>J_i;(?(w6$mV)R4nXZ3I02WcYf-xcf)OuT0n zni7=~^3cxb!B3+e39VC3-{-L%;M0A(Tjh~pTFQrug$+yo&oFo1d`<85`-6u1V(%|a zv*>AQcFwb5c3*H`Kj*&kuY)p1rnWrS!%c3!>Pkzg0X*k5|5;qO_SyYL7C$eZ4Vq@3V$U_Z|(aEm@&cU_ov(g-9JUsulLS<6B$lYz)d)ju~4v*aKb|$I)eC0;n`R#@} zGNEar>{@OPk^)Q?NOI?k$6vfkCrWGu`XAdK>c=CchI-6TbSPVbbm& z2c_>afBS2ykmdg8shGlx0&Whss7rp+!ryZRcdZba;U>U!X7SCh41ZIlj%;!$Fj(+2 zzJZZJ?Y-1P90iQ&pz2~7qAnJN7BJ?-Hi@Q$dizTo3hZ+~RsZ3lW7q4Cx7|4!mo=%K zo%M~uc1dD$kYm%PK<@whwtasYq8XySw#>f%^SqC9cGkT=-0IM9XVraXuN970?4OEH zpJULuC4j}E$p5dLD}USrBjzswKkS_}o%19MzVE(&`1G`{k>tg=;$-K zo!6hs_?oSL`z~{1e7-sJcVmgvt$|@tU;g_Dt)94Pib2P-f^T#5uXnqfM2S=ea;{Ro z*VLr3u8||UQo3gMQ5iPp+$F~*Hy+%4u>8B`9Nxx;r9wMD*X2t%1)A0xgv?+SJo@qI z)t9MZT{|ZCdBv@i@lSjEa>Ln<1C}l5Sm5O->3ElM@=6A|qEoe>`$W@HnBH)0#eL&8kG>^p z`;1%V4OA!i_oZb_|6aX%a@O`R9p^tuS&@fK))<%1&^q^M+Ot_2H=nHXvHbUH{Y3#? zfm=VmxHm8|2o-GlgCnP-j$RCOQ^LpqrQm_(bYmh{5S2^=uOMoBul&^h$E1+1=lQc& zYb{MawZtnh@vf_NXwQV6mAs-GLjQg@eWpA^;%VCv|C)1^XD!#~KYIGe`ve2q$Hbin zIFwi?{M+Jxs(l~JB+d@aj`-=^EPb>7izODU`C{H7z*uP;{&L$75aQ+m{z=#80-;_gnoVUwHBtL(MOq(wA+v8n#Xn_^I}67pJrD40nGA zrts|fM(@|H=-yP}Y0@RYG~4L!*UR&S|A8m-pmwC!orKx!*vRqc(nQ*o3 zO1blN-yeBytL0ubyk>r|PyadJ?sA2^E#fC$$IJbev7D*H{&&}#TEBU@eVQI05*%`# zEKLg$zBq$DtVu}Udt3tjKe&hw=7S#O0NJpX5l{yp}~ljpt+TqYY*tzqPMb>H86 z!l`SFAKa4>bz$n1lh*qB$VvLgwF|(?dqaSTnB)ks}u^VZQmd90c|%f0Tcg zp|tU1-THnP-OO3boIYwzz4gVRbKyE68Oc=||M$J#deE42>QUB;{PcT!=H9)@Z7(y%Dt^Z)Ieb+UzRHP2(AKbI?}98%NSamF&I?4h`KFk{`-Kkws@Eq<~r z=IYgTQSTM&Yk!5>9xD3H@bBx+hShI(t(rgW_oiEZf99*Lv{0FE>ku4P_L`5$*B^z^6nT$6jQk8L*j9G+Eq#PWgCqiqM@Uy|eRaN$tzcr{TncCnz- zb%_>^rid1gs8*X5CADkkrJWIQGU9sDuP({z-l5Xr(4o}f(xKMj)S=kn)=~R@ufx12 zOSBqoPG*MkDQ;QCqqszCrcz6Ys-=@hsL)qezg3e~=oeL2?N|ABWa8Buli$Ri-{<1@ zx;xLJ!1sIfExFytr0tHz>PJtHIlL=o!q>?DC*9wx7i|c4+36H__uPu2=Df8B=FC{K zwg0%#zL4cHheWln#C}+5BUf>7$>WcE@o`EkJN(s4JQ4W9YZmIu`S=3QZ!J%@2I z`;8|t62=GA(vRL?+@_jie&F4&i*jmn-m=Tg@_ZrlON-}hn$^|UPggb6$g{oJRCnWG z?W6UdexFP^wew^M(`O6c@(K3htBYdSJxXacNPZZ-vvx(?uE+|z?RR}9_eJLV3S2Bt zFVde{W&K;^;YPox&5LB+^@HFx!F$bSFypm=`RB>+cUB;e7M5jg(EMccA^Ko zB1WBLfmXz(hD08J(lYgI*KGq4x9^R64#(bNzUC3Wsbs6{ttleAx-!HkNABp9jZrJx z5ZhMy`;@)u#RCd^CZ7GcyqmA4s_6FF$9|0r;ko8b#(oF>8m~WLlzl+sYzs^I-8_pJ zoBwYW9$flue$2ATy7&Iw+hvpgtniP$z5Oaf`}f!HzlnA|<9YWt?9jfIx86nZl-^$Q z?);ABaoQbIH~Ht(8Oy5uc;;`qvOKcseB!&rL#{mHjD3bO%rVCbBp+zCt!6l% zTp{1bZFwHbk=G7vbyBb5gB99)> zI=Ut)VQNyC;RY|bvRgAkB_p;Pt`1sb+vqcCMs|`W+waaNbsBB^|4JFDOQaRPI+1A@ zzC@`lDeuJZcV5OU85ynV`onZFh6n7Vw|D*s^VruVKtLd~ClTRZ==e0kbRx0Mpx z@BCUjEwMJMXo^?uih!h;;=l6ItMv=lu76PbSbcq0FlYP0>xCERR$Hj$)mtnJJ`-Ng z+_CW*>y-zaJDv&^9bUrnl>Gvi(K()9&NuQ_wLj&G(AZyC=dKyGQvLhK1rvA<%PdK> ziud!OH2(L+@jW=wIBGwRh%`=kWh}{+6zXU{G+`T>8WA~K)f4Vr zeA`T5U$)!-#QqR>CysqLXU5IBF?UO+vFz%XitiYO96NbkSFuRm{=aWGgGXS`lq#F# zMwN!Y-)?_DTV+>WEY8qgYB#@d`cBRrKhneMUKs1QSae8yPpqABKIX>5#&~&)HzIb1 z*S{w0UHbj?@}FmZM&!(nx?0K2uix$)+qA+cV!w>)p7o!0S$1q&vHIvQd7)Qdoz@;< znKWgo;Ss&%@{_(D?Yx*Xk&oqms&l7(r`d;AD+s${% z*4~&BlzDLb3d44$XPZ?L7xD+nY-(|Sz^=oU@N|N~eIdhJHGZ_o609WwszRIAzFnRoVc!Sc=b#JQ$i z5qDI(x=qt8$Z_}d1dUd|lRUSio+LJR`{eDqyKY5Uz#NO?rg;mDiykn4S~MjmtGD}A z+sB=|{w-Ly{3`F9a+T7Y)a-@ftK{0!SGgZsDbc^9Y>objCX-onGgCPyT-|0T(;9T5 z+o7FP=Ejt--?Xn-rYsU&Ve#(P)gO_cH$+tKb541|>g;uu-tfdoW{7!rB(Eh;;9@#w=%eA92(+-jK1JR$Tx2PtNym zeUA<04`11OWOrUdncl-p{lIUZjTh#-&k2=nb6#xR#@hBSXxdld)??u)fl=o=aLxsanwl%P3CVB4NUl_Y%{lyK8`$|H}ZLaxh8<*X*kC`6re{J; z@7-D0y(~P!IO^}6%ZmMciE4iWLgFvlWCRp?)qZ&R_wW1Dj^8H~mUGUKe!4&Qqwka_ zUGwwoojlWLcP{A``1`+cg*of`3(9j|31-GxEJOzZd?rBfSUh@Scx{4}YD`%BM_pOcG> z9RDrWHW1u<_4WQPt=02I3Z6N|PSp>#6ZZAZ;#1aF|GaOl@z0$T{LOZsPFvv3=r*zY z-Q6p9^ZfZAe$rB1yvb-$@RK8(6NQg0ImpU#dh$Y#4bQ&bNuO&d=A)d-DOyyK^J;C# zD)Cjqer}pG?cN#oNOjZc)Po`lth>JWtlqcMXmUtTZGZP%{#SCz zT5np5Co|6Vmw&JJ^2T4i$XT=ACfsDdV>fBVwCi2sldeitNW9&4>}8e@kKV$BNxEw{ zzPKFMr9qw8UKRzEU55O`?9QmzuT%^+1rFxwnU+g8Rkd*zR6c>rQK8X+3=vW=n#{+qp7WFfMT3ut0?1s2C*x#yX~Lfpb2(sYtW6?we0lTG(YI6H>%k|oK<-RNbA8L2`V!Gew6#^-zGmi;< z__W#5{Oa?(C;XK=c%J@KIk{O!`{v8_^^GeeS91QDdDNs?U}m4mB2T|4C zpZSREX4YcubD2RIHe!#zzc=;BI5Vd`;)2FO-v>Re!g8+nG(X!sTC^ci=h?%DrxVvn zSu88k+R@u^QD<&&W0ZyZiq_M@TYv1CecyT7Q>|@V1hgt@1s`@j*{ofZq3v0xH09E3 zQ_1GOpz{w8u^ud3JojMpC%2|&Iy(B#jtXs;Qk@gaa`d3?9R4eZTsxy`u037kaH@5x zW_lNg>gBMPM|%DC*Z%vM{OMbykE>#m#R0qO#2oq8%a_UM%~g5oaIAk#xTB=@9{(9X zpOom>Pv1L-YrfbW?=-(mhU=^PDm;E{>Ckka_s>J~RjNp;t(RNy@0>`RP}%0YFHdja z&XY7tTCSb6d}lVF-|PF1z2Bbin%utd?Y(!~BTrpAyZ!OT>CBn^OEz&>mc5<%#?dS& zEL8pXyqf!W{-=NEkAH8`uCUNp;^^_o>f)U51WWjr4%j#P_~sjg0wvqSw%e&7C>x^LC#4;44R zD_DG~TlBi5e!r;FS+iPun=MzLs@Mzt2t3RAt3Cd8ZFt$%H}Nah96G< zeB*j(@x{~E#Z0>Pc<@c{IBDL{HFp#?aS^)Hr|`UZC9;X<@e22^8A3i+=>z|)A=jn$#VIQoQ@GoSD&@?--y{2-Uqt1iD~%+zdWqHbHB~RU54ogUL+jb+44;0)y-*_&nzq0yeqC>Sxr77 zwo=8cK701UHM8gK*-~nJ!tdv-ogchs*KOdm*==FK)o<}@fv`cb?zg>czqUs4H?rH# z6V&RGntOq*+FFbIZcu<9_+~G?1(tOiXb3P@o^F&z4uW0QS+8VL)_Tq>QFId%zA!NUY82@ZT*dgW4Y<;JYFZYTHn8SdxifF;EhX6}+_m;FBNd%S+n zn`!}>TjqwzEG0D)(`N6Jm%H_meviF*HOnD*YR#@QDr*9y_0IA4 zNq6$dg-m?dy-Jnqb5dnoZ;<}3g+YDMFuw)|37U8kTY6TRX+4VTXs-&p>{W+TJ8ow6SV z{_eT()YirRRqB#7+fyf2mwSI<*MXMXEie3yZ{HPr(f&(Z>k8wYg6t0peKxvihJn3-+&<>`sycZ~kDAM=>!vhJzHQuDVTbgYBSk8iV{ z?)84AP7|wlHG}yaX&a61j%!i^uRt|U>XXnDJ9RX2_C1q4>&!1xz-Gy08&1EoI?DD=1=D{Ix%=mSe{(stOexDk?bkQs(j>#M4Qszg?6a*g6f^X7nNwl9 zZbM#W;+<)8TVD8oSn^N(dS|jZ+a3?i<$4yg2_}e&j|) zmVaHLg<+XLf8TQtUbtQ6i0*@G)wxmMjtRTZtGmDA{kw-t_SI#bdU$E({a13ADkeTv zSl$2R#yr2btJj?P=eyf->sjG7v;Ll5X>($84%^g~Ouw>!@5o#9dGF-qli$Rwj)-+o z{BT2WVOq|OqN}aXIpZ|7kNI4ky2I_pooi+@{xjd7$#r`2&!skvdmkMa5LhX&Rm{qzIPpR9P1C0@ zzbt#VOo#uxUH7T~*|s+Q*ULKN4>R!?Z>&@K)xIadU*+W0&vUo^5OMOpI$y`Xa?j62 z(hmM|@lO`oU1Pt?(AjCm5v&HsM& zsb3u1+im!kF530#;k-Bd?CSRKH&gn=vi!-a;_jXzKcRxTuY{(@b_YC(Z1jE@>C1Ie z*R^onaWxIwl`}#np532vU0Y0|H^$_@Jj0)YB|mU9Zb=@EBs@|>QHvJT62@3!WMoS8 z7UuBi{M!~{b^H_lA8@Y}D0U6Hk}BWrm%e*OnOMih-xtm`>zwQ?lhvH?WZBF0_YcqZ zxouTqr5SMAPX7GVCHvmrefI5HzP!+(6KUnuhm)k9tF+ZW^Yn1ssS-IUNbSV4m*3RX z_%}S*UhO95_QUP*jLE)B>+bKlbI)b|t*jTv>&z$qzP>znzj|u;4fo$bnY*HvgO z-}XLi_WxB2?y!n(d7!qU?i6=aipp7IDRHZ3QLTbjXQpc`Zd!M()nn1`!(};IPbcij zXRmnGe*NnF+4WlYHG>2m2U+`n-l_0mZpQtK&o(MPzL@!T&ZOf-D#8-wf9vk=-*T7P zaOy`;ved}z3pvjXeYtbnKhF4S&z)eBSj;l<@*ATQJdE<)0`rVaRkrZWI~Kz7>cgAU znQ^RV=60t!ar)@X6I@pS|r~Hv7Tp&_#McARu|fs9VzQ?}!cu7zuN&04x(B~Kq*Lxc?bozG4Jks05g-CeXkvC6Pz zMrEJ)Dd)G_4j+?~agw>rWNEg}MyD(L!d0E*Q;`K67D;`A4mWfHT{1W#SDm_^{%Fx( zqw}`Yr?);VyBwX(zcv2QX*BBR`}A#zbi!0+INr`&JN zSDkmd^-#d>w`(`D-{zlS@u$mu@s4XTXMNOhq)Ej^s5Bld}Qd5+@L(=^}IFzBO5ZOFtSuUl6`WblYd?7`}MdoqwMYXW!K{4 zZoLe&pR#YyC85rq%LOZz9lkJO+v?j~OO!a)Zv1;OL-3~Tylo2>Z`s!!dOc#HQ1$!y zk=jnb?{4Y|e!e4j$`oz&)lXN176hF%=ltbceMTdAY1ZD8Kf4;&bWajx-u+KQrRIgp zwK-frLYFE($oD(mc{PiB`w9CVrkKw<;?JhXUv1qK#Vwc~$a?=^n2PI``(NkJen0uA zqIlt!+tc|McP@D^QXC|-BAssz)EWT6g&+f!3wHWbhD-fqW!CACG8 zQEr-mjo(!<_u>z4x-CCMoSuK+*Ui2)`cn?B^Kab4F7RPv#|amU_Qkc9?LJkOEN@Tz zy22YJ``u};Mj%T?gcHZZ-#dC9-V`quC^&gYRXD=__QbEOb8hTp^PJ4$zCvo6fa{L_ zd9{}9kG%N1v~4y1$SpC<3zL3%XU++m3L%@{pE66nvo1ICIP1jmn)#l!(E$aauYM_w z)+gitZ)PZdF5xh5fqwby!$L{>j4xPST`RzD{jg?+&4+5v*Dbrt&-@C}o8#GSASWjH z?%sjTEc5hSB^3AAeAvyo_V7L1ZG18br#bG(Wb`?uJhK&cSaNUM!Q_O{9k-9KnXY;E z{P(%e68zm9<<$=&#XgQ*c?Oxu39}DZ1$~+UNs~8-eQtdq>a?|~(?@w*C7zW&Jt*<;K0U7mN{@=ei6|I@eS)V3~qyKLENM~=6@ z8V?9Q{a&pBIubLH*~Ax!Frj-~M)Xr+92;L7T#Jgx23H$qx!-kscDRL@}eJ)*AJ&&;>{&H0m_n}pXowv=uAe%Zz& z_^MPM!-Tpf4a@QvF8d!@=9Uw;d!~f0uKF_Nbw;ad%cjSBEriRTJl)uO*wW5Cbhq(> zo0C`rd7Dl`}J!>`0izS`|b-~dgt-;&z^kktFv|+r*G)L>bTST{o@<|GJM`T z@CI8jW;6QCRJDp)X0ldv!<_Y#bXa$u4z}x#W8=zo{8F_0*y_}|OE|l4`Pc4^I_3lITcy%W-$xrK{`Ce^OP- z61;U-sOh-R-v1Y5(yX=OOt15=*~7x2%K zjh=73o;|b9^GsUH#8_?)#m5P}n`MRTjBJkI>|6K!`Ha-*A@y!EEOiuw4mPQK-E^)_ z-ImP$Oe?`|v(?px13Zdr_)pp#IkZLxMmpBt|l-Zp%x_P5gMl*WN6g`6Mw6ec~cVUKZ5cz*imfmJi! z-uSqat75jnW1C=kuNgmi9_Ma)@o$6eC4;kb8l3N$_b&6E6~ffYa&6hmM9!A-IU@Y5 zq6-)fnB10HIDOiosykeFwueUioFkB?ooV7(6>U1-hV4a(XS#`mjo~KNxxv||zAu)n z`efR*f8CU&+51da*{qrO;>E=(^^f0W|ExUfY;1Pe{P+S>{`O~6gf$z#mD$$xCC6`l zdgThYmugj}4=g4U6^#R^QsCB;Hv3y_eS>bor@pWzththPvC|Zx`_k zJ?}en|6l2isCBRF0(Tuhmz2p6ucO>+X)QQ4>&>d(C2O)*)Tp$rkV{oNoq6!{7yXw$ z%v(GeReOZLzH4*T;4RvvyU*pS*rnu3v05|XHrt)Gb4%9SxcU3m6}arMv-+iYJ^z>r z`|)3Q8YaDT)OgIr$zroeXV@ zBGbzDOi$vU8Z7Z#u(WLZ95dH~TG6haWkKafh4=o?YYV)}Y5srC+5hYe(%t&lkB%@h zCV8Hb?4enGH$y`OBhZ{;5ET$x-`*j(*Z=Atb{W;_M^zm@Waqyw z-P0*ty*D-V+k>x-lU7I`lPU5El03iP-<-iori(X7Gdxo2EAy|?@6L-qrd3yezHEKc z;RVfX z%KhEAF70RkqNNk~zdj6kCYPKbn6Cf2cf#tNzoozB4&N^5UtX8-($l%0eI?)DjVJpn zFF#=qGjHD$xbK`y)VGk5@2mwo&+8X07E*H3cVgdHdaznNC_{XIeZ_IP*KS9bTx*GA zvXs{0)LreO?sY3ES%J@&56=B*rIUju6&xE)_~CVump z)Su25O9kG(i?r0}ekJYl_xh{H(l^%WzFW1%+Vp4qYsa{o7VZ;LBUT6Rsa@*K5yG)L zIdyyCN^> zI&JRuS38UNr{wMUHP2^*nUkRHKB?OmHw7-(99!YI=8clc>-DTXn^a{uZX|IjD(rT2 za97;%LCMeEaD)HkIjlEqT;n9Z@a$j@+V8>Axxr6{Ls-3Y#+A?|4+NJ8o>*)Z)ZhN= z%sQL*Yd8)YOlZEVzQy5oFW1z&p`HO1hvrUQQuD=f*3%U-J6|~{uiV@c-3kCP`i#u&zB6!)V^CJ_-We(0gS2*MDyq)6nMz3XNR4aVbz*r&upGAj{0&qAxO8gf8M%4 z@232122$VG9i3&lIcAaM+5UCxx$;Ndv)Bao6~9uc{ql9rV-9ugf^$85F7FSwUeL)r zk|Nt2G543jp%?LH)6busClh{1!_7RLLoL)+i6?h;gx*xfovc9@&%7|Y@GUT9Nr=Oj ziN$MFYrmwL7 zqmgB$xOKYgCHMF}mVFNnmY?f_IlLu1?1`e={)#XWL#v&2VNbS+>WH6exW%+EBdtU* zeeP|GNLr`p?fywfolWJ|8*# z?WsMfk<8_ecQ-Cy_F~tbBv;mJi&9IAPe^a84!f~w#lDA^zPgko@4x@gFaNSvU7KFayBQofZOz)*ezKc=_cJb;_&9yPZ^ljc zw!KAKO`+AdwiX0*?+U74rEq2YqE}geg*P47w_^G;EtLK1%_lbe||!Qs36g0|bVgpU(zMel!#@9^_KC zP?Po8V)e*2&YO1jvz8ikeY&#d4o}si_wx5L8yb$!pU}K_?XC|_!C!AW?%>gC@ato} z;OOrb|6$J&KEZqLtKNogyRJv9r+x&ynZ0XmzpV9> z-IwpmR%Cs8um0lsGNDxua?_v5dDz|C6)`FK;+DCmT)DXq1f)D|*e=uYR;NM#`D&)F z{r3tsR)w3tG0g8P{X8M`x6GY%T@7x(TUC?SS^eQpWnBHLy?u|>lXhdnxwC#*SVZaD zZvVx;;Ht9Tkrki*PAL8TdwTS~5Ub65e#-<*GJbk|!>vc_PVEwY_GzQ$19pv%$Ia`0 zMdkKMwI@vZ|9j2VqwBp_Xld0;Fsns=WIBBQ)LZ}e3tTt76}-B14|8{j%Eidmw79=N zo*n1ktYoD9V5(F?vyAMdtIy}X{VDWZ)9g5d+_r;HgdexozWVg3@B-(8<8BYX+%@5T zVDU|ozrfV7inHZb5|`qSg8r4=$0sN(+ECW@MCZUW&qv8e3?ER&z6F{wf1SG@mEE^rcAZ0R;eoa@=k^|s;jc0Hzxt0vS_*H*Zwn(Yb*6cf ztNtx7ar$LoI_J5><;#0-Ho8EIIyG$xPnj}To!>h}`}XgwvU$IV=fkzxb#*fYJa>C; z+P3=?14sQYhwqF*cE3c<7ENjXXB){Tl~`*b(5Bj1AbY(d`HOddw$7Q{vZsZ-Z!boN zdiTF>xOud2tzOBZnHNnJ-abCzG51K#vw3Q@UrgsbeZjAH$aC%mj@O494Rkz@q_8&M zn7mv-QY$05QpBO- z<-E(+8$MkOFPyemtIJ!{1Qb}HnrE%ZRW?@z!(Y?Ae%^WWa+#8INpWjPkm-z$17;mh zgCr+JD~O)$(PPe(cX#t*eIf@bx{pQnUHUwC^CD)Dm(2K>9?oKHaQKrHwr9_OX2Tm5 zN;a4Bgx0)WC)Cix^j*U3=Znk6r!OAQh*ezxE3d=jzbE&^$u64NcTV`u|6hIYZYyv9 z^Ui*ARMGeBw32_Gzb%Y{lx5svzV~?ieDT`+wBffM)ox3`x*sbD^!1&)%&>U>qQ$=z zckSG@`16%-%}0YIC!so3?{2cv)5ZFab&enCzMHJnyTML|?tgt}t^;Cm0_k{uv zt(TizYWI9(bNqi`oax?NCdV)9-%Ru{O%soJAmutuY3td8Vbvd5A1`$(@?~);{a5>4 zc*S1h)$=A9=o@c-ztOl~C2fVbvp_K~OX6-8!3%e$`v%9YxP06C?|P4{fB6#LJB2;% zEWV2Od${h@daKCL6V2%(BfL`M3g1DOrYsAlX4_9YT>c6+&B#{ZxUJgpp=*laRg<&9 zrB$kvrajLtmwL5Oc=43w3rwQ^)djdotr6O&QgG)}-lG{tLXLsAS*{hVVXgKFmGY64 zFud*{u+3ZG;eNYYJ1^-3E@yv!=i%qrl`h(0JG@imY&oW04z1+pOt^C@;n9qMoq8>t ztXB(E+N#cc;rG#yc$k&IaapzJL%ia;)})xF*QY&ND(zzY_3-n(+5yHJoy_!Pwu{WR zP-}8AxFXtMD&u%iu5!-ebqtPYOa)rr3b|+qZnK`*A`{gwv-6+Bl1n^BkNM5CcYpi) zv+VMsobo$r4-CDRexGvs<iYJ{c_e}Sg+!EG9#bp{c+uw6nuMb_v8yBkE z{qoYc^ItXQnPr}v^kQwUyWzxrs_H*4sGmQ~F=ggOTZUu0zt#F)I#0f^t|`lc&DmBh zG$UM*WAb9H3!2d{9hWhEPrvf>`v1T43(q!mDyz);RmbP7UZTS;D8Rmr68wIq8?IgMQB{&fHZIa%ySZrzx(x>wd)gE8pDTy)1k8vU$7ydEKg0 zu;2Z9=l|sJzh&V!8r6E8gH~pzsm+qCIc{?L9b3Gly3NDY2h-D^EPSv3d+ZL;X9kj0gb3y*9F$~W5C z`{UExY)b3f~qNt2;}N>S*@9t>1q&UPO1}EF-2P z+g`1V58b=!)vMcIzh2#K?I{r%emz`gp{JYBkLPv5UIFVov`kZ**2u44FZ78a{zvW6 z6VCkg7gZjn>@}Rfe*U`kV)I}7UjLT6RekmJ$6Yv zr=^MFeSc5C{rtJ}@T{VVh8{r$SDeES+IRm~PnkAx)`9;z%PYMuwak>~oH{e{@e=Lz z>sQ75y*;*R%YuXFgjW@3vm4&|exEBLWYd8OPeqEll^%3xvZOyYKDYQmPC=4U*TmXe zCnFC`Sl*%~X!GEC3A_qO~jtGy@dGqXw6$~W^+PI*nVN$Br|@A9T837=%D zYv#(?Eq*C1H2z)wzo`EYxexzbwYle$j6Ua`cTYZj>sVmr-Po%^P2UDxJy#GG`_S=P)-(LLh+v&CRVM9!zv(kzw z)1LTma*i;18F4^2HBv0c;(Pq%`wx9C|Jj;;obyqP@^NP;wz=s$*jD^CG1}tCz^H5& zrY_-rq2QW(VqfP~&OQkXC64#1T{A)gyjMMp*5VYOvt;M~at+(bj+-w&6joeRHa{i3 z|KtMQKp(aqEnXGWBKl8v>ZIGV=kg~%{B+Rn)7z$l?`#f-I=o#zap6>^tMh!% z&so5DOfY25*T4%Z{b5`nUvwz)u^7f`o@!Y;`Ocq;Sk2XW&HSQ2CO*m6oO);7YAZ>$ zBTtta6}@W;DxCMwXu-G3CoTjrDhb{fHSAM(Jg5JI^YL<589|FAj_0a<9d8)4uB-hD zTsi0de@`o`3MHE>?}XpHG2|4AmNeuv=$kMvQvTsjsrbVMpm^dbROmPn6E10f@wQr* zf5}wu;(xQ%cX_o>+x_F6d}ZmuyYFqCKlk7ES3aEO^7N33c9610`}O>L?tYhF^hr4K z$OyK47jkt`+jVJY=f6*#>oy&^u%~j7w(Xhb)8461?yxR>WOFzb?DM5e9V)xj7Rfjs zvy@-B(51w;M}f(m=i#0sf|r+03TE4gQ`JPZqrIa%IKc=XY-=pK>_7 z{Nh&5ryP;9KMP7sdT~p{k)=-}se{?kXM6wcn3+Zw7Z>OK{d9T7k)nBRYDMyMIgefz z{OckVuzUK!o5@avxmlWOBF6+LS-f6s)E(!eA!AtJB5==Jq%qdx!gsBWb4!e#hy6~9 z&%ZNgvQhkw{U0sawR^hmo>+0$`@tK-i4w~rYqAemI5DNyKACcKI~!QHvkXU4)j7lB z=2JSx7u)k5xi5V8YT2J1x2K&~5Yc(a{n@-weop5U6?iDPyG*Lgt2^Ry2xLypl*+UO z!HG&7=LKDVSfoW7**f|B=)6_CY>w@;(>^nsm3F#VI?dT^r}cSRhg+u-TOSA5ui|@R zt(K-8bNzkcXF&PWwEJcH%kxENc3r$E%($p*eo}gW=Y*nFi^?rd2@09KRyNi@F@wV* z=|P9Wp6MEgIzGJ9Q!j817cSDsoTnX>rpE8q_wrtsW_t)^eHXH<_Hl7gx%gZ5DF^4guZD}0c0~P{+0;>KA!}Uy zeA(H_cNf1orjf}0`TEiAuEATkyT;$sX?>J)5mc(3f5*m|D?WGkio4Hm+)UQ;FfBG; zAfxEN+3wWNm9maMj9L26`y@V}v~iBxONnFm>$MN09%M|KSz_mtUZi(U@%m;C9pOgi z(?=4HGtFh)G4aS@4yEw6pDF6}WSe$dr^?$IoYFa7s(T}!Iq8PA{}#O?SGv3S zJ@==(Ilfaay*FRS*|+%hnwdNHHo9g_pS7Xda?#P>%M|Oy&ocVm*;>6xcXd^Gp66cW z-}0&}Z!OE5|LQJt=BqmYu5~RBer@_Ktq^*9;;RHVMawTw*O$r7Iy=R4@^h1B*{kRL zPA8Y|Isf+C1qWvDx$50dB(+ZNoHs*%gUqwdKbu;ArB4;o+UoIa!t409^azVDuOIGP zY0mKUkmFB5E2bOj4HG)INE9B?@ju7y->fRawmHG_k=>(v<^{q#f}Jg1wNzfswR;=( zl-a>ZzTK|9Wle`bcGt0AEBC$cT4y$MqEB}BIX}OW{($EZ9-elcjYn=IYUwPSail_a zN7_u+yYp50`mg-`CB0&T(erC+lOBG0So~4gX~N3l{BAa$3;IVFd-}bbs;z$X$E~UR zxAs3f(_$TC%J+OjGuPdFI$O7QJuyx0P`YAvL~-iXkPRO#h0FSW*;QTah`AXg^eE)t zMK4xoz|8)QLddeNB_@_gNKUO-rm-@{L;QRtCE6+EQ+`5?piA;__|+v2ETzs zsh;?gb#LXmYyHFQPy5DRoqecJ`10}kYrAuQUupN8^vhGpXqJ}5%9AT5i{EdZqJCOv z^7;Z39d9f9JkKW&e`#&LJ>BbVu)w>r+~;*wb55S*n0m7{*J19NtJhyPdYRu|>9Nvo zpWfEuNB2{&&$f{CWy}9(&tP2gXdjM-9O`oI!L*Xx1oa>gpVYkck_-hSGczLh^iB!C znfLgZP_6lc`V5xJ1#Du6-#x3kFLd7LfsQb<+OtQ8&M|9lP4UwRdXNBfCCfTAHg?Tt@2c9bm(%4Fr{t|$zu|e6;im`lYr2HZI|H7y>n+o`8yjDl!ToE$ zUBZ^!hqGT-vMkm9SN*H1_UWIu#BNZ zA7{86S20qkQD@{ASDWX(f#bQ2<-OVMo!_@OgYbo}Qe~$6H75zs$cL{*s+j zMPmLvIT=F_b#3nu=PPVmYwtA`$8~MxT&%Q1$@`I8p}<1b(q@j|N>>@`COxey;fOq9 zSa#x2ztfMNf(JDb2~sW}+!-Q;t}{!n7j6CTvvx&M!2T)mE|Fs1UC#G4|7jFe@CZFx zBX>hgZt)B&{=1B;_NjEvxA>r)Z}y|D_WVyK(P*4>`y@uG$=DsSs|cT1KVyt!P54z@5g?o>IIma<#6S)%7o)4}8a-f&9oylN*i_kqcwf|9n$QV)OV&GR#{SNSZl z^^Vzwb6PWIO71LNB$yzs_WNYOmTV7sN1+}Qzvo8NAD^(Be*b3u`lcDXy%azBY1>|6 z;F&B{m3Qm2&xxI09`ao6rDnIa71P&m;@8-d{8s8gqSs*`e{HWv?wekxnH&l{xK{Yq ztoB(4toVzf-cDpYpX_wlCqUcl)kEV-4f$&}Zl6xtToDQTrr2V=?wbd*jZfB#$Sils zUwIDCO5kD}VH2-{AKFW&sw>M>Sg)ALe;iUgBS*;2ErUxHkHGXnVtE zUY`%L`&}kncwM})s;<2@wAg9d_qoqf#IKl4V^q!G#dF7f+V|VK&-dtV54v*Y0E1Q4 zZFAlOI{YivJ$T%Hd%eBFg!MOB5bN#~>K7Z5dsb6~Zz~S8&9=yzJ z-cmYgYz=DxbU(D8@j zf+_M+fB02T%wl_|yya%0QB7T21oP}yi8Hw8$!D{2oR1DaEVWQ9&6|f=hiCER$>B#M zHg}w$t6$I781suxLI4m zKGU@J&Z$==OdWO&!EBa=?;fa#ExfGv&#%5YL}b-t;|bqy3-6Gr%)6k;q4sE*-sxXk z|Ms8g+hNH1X~UBifjtGUFZhOp%F8;53G&I*H!h6&;NJG-PQ&rVcRu~KseiIGTBo_i z<(yr#{G!KWAAcuYVHuo1riMw)>Y7UsI_= zho`VL?(s-Cp72DBN99vmcEXdeYNJ(-0zL{?z>=zh@l)1<@^Is%pHdP#&(7=1W~lzJ z`F7!BEuX9do@ei>>&-v9;_0^6MPUc;M4Y*PdnIdSiE6IYsrLCjCTh!=KDgM=n8}s= z`+ewy?QvQzH@^D4Yq=&Mp=R1voqgJPVb!(>(-RykYRw|F7rxtf>Tvnv$v#`#&Lle} zmz3**a@ovm`E52mcP6#(`+v!fLp>mi_hF(}a!I|ehGys8hI82-Q0aM$m+W}_G*?^{ zkW({l)6Q^Sx%@yR?`_`8hHEM_cD`kr8@i)sNsyAqI<=MiA}>4>bJm-_S~Pw)%Y4Z& z!_BR+$5y8}>^l>)t@B>`Yt!Xw8?L@>I8Y$eylK;oFs2E2E}OGzU$2R7Z=GSPKWF}- zNqb(h?%S6d{JSn}?ZtKZ)+{xxZ@KoK{d;=WuS092-X~5sJiNcfC_S{wzqU3lX>w}U z{<6r+v0*M-zr=dy%U_PPPL%U&j)zm?2Za;NPS=bwkS-}SxUq3NRE{YswUxc?&260r-6 ztHcVvR-O)$Quh|QBeJ{F8WFjt9_>!4uG{8b-z{mD4EcGI2~HL>$eP9M3Xc@)`#-_^K!bXR`IEBa(@4Nk51V1 ztt+B3x7hnWbUVv+HazQ{<(y?2if0z_b?LrpkWioJQ>O1IHj4%p3G9LVMet|HtnC78@vb_u-2ChpMGlc64rgzS%`)R%T4*qr==?Ka{zX zbRI3dnWB2T(=T2pdHExG=i|+vJOX2ns`4$Y|9Sey3%52cxyIC(W5UjH+ujW*%b3g{awirv3W=#>9_<*N%s*zz9Dytqzk_OE||%E#A0ft{L z99(m9Rw;M5?%wJE^Vh;__$6`=c1PT7>NuY+@6?{e+us&?Ogi)EpHPDg*|o~=y$oJ?kaFZ26beTW31Y}>Urk<*uJ(t-caJeM?mn)1YGvCo8?@4l%i zW=DKDJ!N7kd%lUM#Z27~zu&z4ruHjB_tvuPFx#2?-aI=yZOYe4XX4~UE92MCDhvM> z8hrokzazfJyED(IZPAeER6T2KrntFY>TrQo(#`J6gaY76OR+}durpk;r5%V4BJ9SW}P`#8~Uf$ ze0cJ_c0%j(!>*MHe_NJ0FHf1Y?0Doi6N8!QCM=UfVqTc}*Ii>j7!(!rLe*a`;{A8V zii%08{)dkgtO_ic)n%~A<)Gegi&N*BpRGF75ZT!m!7t%6D>$IdbPcbtPlcXD{GsB5 z@&6Zdv3++_^nal!uQ*(>5Iwv z<~GhpbK08YZg{uxSveUMy(4vyVB3$%d2Gfy<2F8s&nE^|L-{hQaXqdHR)+~!@ zg&yfer&Q)QG&;)(|6MiJbF)(a@1NVECM;idKg5)=Y*TQlKj+NcRebyMwx_J~;EX>0 znM?dd>F=u5yZqiyeIetRa#-xz{JO;*Rbkz=@#nU8HEf;4v2Jb8{KUonzUw{qYgPxX zZCJS1qTlN5%{{(1SbPtw1>V#ucp-1_p!{r5u6)AIRi2#tW^LUdnz17G>h~GWz?z^9a?y`gy4?-=@$TIf{~h_SKp+U!9%s z*Wj#L=yBKI(OY?+iI^(*S8E&!meiW{w%c`c^_p!HOy0Do-Jd+sxm>yZT`xOx`@e}b zS*w26Hr54v-F5#+|Jta~^ACjeWTUT1J>=8A!@zoPr``VG9eM|zlxid%dv;x;(oaG> z{=LWbuk*L6?vRzKEMcyM|VRLRYc`np3`{8Zh&8U2T^ zJ?KrtX`?I3KiA5`aZ(5~j$PnX@pPnbs9w8ac6Om=Lv99l3 z<9?}X-lTpBZdTtSwY^mw=?ast9r#i|zrLC|Wp8F@9ZQMib~%AOZ;ct>UhAD(EcJiF zO3n?+bGYt0r)ke~{+7VfU!8h5?##QRD_gE@vn&iernK}xNnes^!YQ4m#0xevmrO4R zbk@IgV!pd=UB;L2*&asuzj*t&I=F33oF8kv3=rIOIIpMhi$r|d_Z{Z!Ou65_l^y&W z&amQKs8~})?R0n9KbPYL(wA|*Vf%Gc?RDafyEP5PNf)=A?tAl1mSK~Aw1y0i-3i_n z#m7Ir>mN*79b=OJ?dztT_!p)ZJQBDo^Q>arA2TTPCM>%bu#Zbz^Fgl7azAbB%>_5Y zzQ(V*+HbMNS7=t$&13Hq4)F>Yss`K-`Rz38=ll;76PkR*Z+n$lsm{oo%cGcK<+(F= z(+%lz`@bfC&mTA6UpM1bL(=jJo&~`R`ky~(xN2y9_^!zhj!410$LtwTTdUrb-VhT!H{*S6j{E$BE!O|vpkk-uirsU2x*6 z{8LrDk?*DF3UA+NyYImD>$kIFokPMm>L|=T@JDyr-oyH)5oK-r_|G&|9@pG__vNY% z#-z*(L4HRQz2`srXAt~bN|;mexA8Tm8=u57j0Dd*p0@eg`}c0dMEk;zvQ^Rlr-?~j zTdo{qTrN|Udf~$nXTehsFZ`AIG39eE%W>rcp4U6qOsMQDmMCkRc+DZ@*Go>dZIwmA zKMwAB6>MO3_f_dk&o^PV;oKP?^Da8XE8I9``k~P)cltiz2?zISZNGXyt8%M+#iUMVbEW?SCCygPx<#^a)* za=^OJrWD-6$Ub$j@5<*%c6IFdN;@MZ)`Y5v&WR<8LufCl?CShK12|^+=&jxU=|Poe@WZ18lT?;JaIy${ zAT(R!%|QkJiUX-!pZ{E{(&k@xeua;|i-AUql7MH|Wz!cRNrg#0en*ym4U>zBKk)Ur z6HBv`LDL$CeF8@&o%qx}*Y1RKz|K_$3rv^ml*<`#^?cxwahAHqCQ@_7!dP(0m9IR0 zEcJi;wIq&6x9V_qZe?EnNO1K+4(@kcl2;7Ode|RU3Y=*?y1TofNb=GK$2nOQ9lRAM z6AkxAc&96i99Q5!@-RTYFZlw;v4;=M9;hl!-h5i>n43nQqg=<~M0=Uz3k3U;S>jK4 zxBp))rI-V)!K}hX@12=2jY*vA!=;|g0_G!Ko%NqD$~>NM*=dTi2tNzSB!0 z(`H<1)m^l`;P(s8n6i?o-;_6zzMp>{rm`ob6|Yw}$WP-0Ab8-HAUS zGU2lID}9~mvrW%V+q1s<>beHr$(iwwdf7X^T+jGc_vo7a#L*OS+&s@4g`Rp}zKDhV}!^9;K$RrGIL_meq^b ztUbL>^zAZt{rByqyWL%b7he56aq;uC%Vq70*56Ls_^ZFCb0g=hHVZY&s7nT(g*{>Q z8OJ+|WZt}PtIsl*K3KhZLhQQkHqni7AGd$zD$#l6*TS*3Y-<4jiX7>{?zjbI&A(*b zFWG1LwVS@bu>;=FST)26-;=C5N4FhRMt+{SffQ>QMCE z_pjWXe||eKTQ1`7w)^uRKZvPnw`lyP6L7Kc%17IdZ_SJMg?3-Bi8lAWo6~;a)@|ji zTmRZRKkchxn7`rezSY;&XEN;mav^N_-v>W^UUSa)Jpbs!9nbq$>?<+3bW=y(rdTmn z()`8!)#v}mWExG%y%>FP(R{(aMedPO;&JYmwEpUSz3U+NyF10v>7eM3UDr;W6)n5$ ztoE&1rR=S=mFz^{lbN~|E4OG)iRSsLzxvpvfRj54&TL6Ob72?T=4qTMkDsp8zqWw; zgSJ3gJ>!v|;RV0;G_KvxZzWE+79cKEi09kZ&pZ?f2`Z{fgeEkzUgr zuIcfgtyKE-(OR{@>6iB;yug zK0)#FhhD?0W^v4#Uz#pB$U8*pfAU-%P#EY`d-Bz!nOXj^m9<&cAt9m1TPJAqAN{Cd z|GN12#R*5hUlrHpT(**Pt+sMYLt%s13=KW2PZP`8XGTkgZ??GgI9O+z#D~So0aspy z$oc)=*VdfenfJ=pVEXd^GXG2;xb6%VhbkyO~_QfPwigO3-&#Azx~4f#+8L{ z&lDPdRhcbYaQSwGcvE!dj<*%ck|meJW{WnTyYSaS#j#XAGUu~wMhJhDWo+d0eSL*> zcbD+i9PjQb=lUm^r___h@;|xs?U72EG|sL=7QwX=Gw$5am0S1r(x#9F2mKaJczTNO z`n0(Jfed`fIm!Yu?O)7JFfhtb7Vw(MYrK=+OZdH=+qcYFn;RT8wRTFeS@_&sE8=%V z;7D_Vv0Yuf@0T_arRIjrl=kiiKVO~bJ121Hxsu@&V;e5>KsmqNC+BRdo;-V{$Gs=J z7De2A7P0Kr;ptN5hmL(vywTJD^2(7!zrZ;wj$U4Ac>Q{ARD>0m>Bhw6cQe+#y|;y- z#iDQN-3{7ZQ*)-Natpum?Upt?@>D1%ir@rm^ z7U|ZlcW1X)aIJj&EGeFXv3A`K_$o;dKoO|F^#DNm@EH)$`De>b1WG zjB52>?REQaYCGF*xw|dn)&G~=uKzb(oc|#6W9?U0GxGq>=bNtnWnAu4 zd?B6p$x%aBZwcujw<)ocmUsQhb`bNo48h%Zsia)%~&ARrz_~pN6<$=;eMmyu*hL^I%zE^2C z=R9wb@aEiSha#a#cZ%g|7((C7<2bfX#^%lkooUK|>qwZiigFzrCrOZI$4IdkenxRka>)yLN=e3<&pwN9dyOX`4 z$bi+uxU|q(GGcePzM7iC93$Qx!8Q)!=G5Q;;SbA5|vxZK$H_?~*nv=i%FJ}#`>Q9V1D^YZR5RkQAf{cQ-4 zTPEQAy>OGtjgm_KB%K|*5AXbzXgwqDe1u0{q*Ti%gU$`MC(as$uJ?;;`S$Qm`_|px z5`WFO>8_Km#_se!naS{rqPq9Z%s-{6wL88U-jMyhVXx16{}X3h4H%|0Yc}Mn71HQX$> z>{-ONtBF5)zCKyA?Ae3!mlJs>8=cv*cwxkXO}SMwru*04&6zl>=eO9*oe?c+ha3ts zlROq`q?~X|YMUzKR^NH0qmL^~xyej*eLYW#S!{KK=RUCvo1Fhl%C;5pXO8T5d$XNQ zG&X#XcUF;UO&$w-S{s*p_P({V-GW#;s!j{o9{I8AzQ?bmzl^h7*lqb=$*bSozqMo1 z(_Qb_SGoW6O1YQ&EB2yvXy~rq6 zz151XW@zD&=T*W9}L7x|WQD!a^bOqN`3aN%RC2v?t}%AW(>ZZDK39C?*?xs3g9ANMMg z-2Q*Jx8$Ey)^d1VxBT{@kVi{u*INror^_J#F{+kvzgNE$N2xCBJ(E&`EIVMyBBGDO>kilooRG%cic+LsneNPsERuK zUYx%xslTgsZ|;(6-2ka)F0op#yqBfLOIUDjGw;&;c3mM>hm-q6Qm3(-=Z7U+t_!9s z>%aDmeYL3ZljDB|$6Mwbf9(6Er0UzdMC4en%_;rvKhiwR;g`}Ak1W`<_;uXgtlPF# z)3$EVd{9^Qa^aIMKEAu#6TbfWl)LawO`EmwV%>_9hgue?Of?SYS@`wI%z5wMXSAGp z5>nz8d-vdUp@}|w)i0W)oLn%`vZKCziHB&yC%GGc>KRG`mx*F;Oq-%Ec^zDhX%lRx zu^X8i8xh->j_$v`O{gwD;Xkwd)`PPIS61JjRXnL#Bs1W^F-wQdwG&jU!k15b;#FjJ zJN~}pq)8dGr<6;VQB#S zAAcX_IH~Q^?wDGyh(>VJlcR$3LX!ut?6TQ8@Qul$PU$TGQ)biSv zFNQ&aKTaFXQdRMjsQY2!BgoL6ap&Hfdvi|*ZkpsZdCqT>b4z55)}7lQ+IVq-?p=eE z2OE6PWlHrvU-;zDX=ydy4GC8}j89G5Gv{d;52wY>Cx>;)=RChMzlMWJYPaZt2G_>l zg1*M)OwM_(2mZ30%6s`orF@Qmrje_`DUB;@gPCX~FGZh>Cy&xw53VxYwEVXJ1&`^<3v)GO^4iMW zoQyYE$-7K{W1Q*1ZPwfAJXho4+%;WEj?Om=ej1*Xt?RK_bME-G9$%?TO`*w80?kiF z6n|aBcB|l*;i=fV485@D59b|Nsi=FyL`|=BkxOr?y_>Y2z1q&h{S*7IRz6_i_DcJa zcva%(m0lr}bw3v7TKtuGs%LMao^79WJ6h4`?}iMYDKA_sH+~A`6@T1YzT?k~Cwfl1 zSAB3?XVzm`CM~x5B?AXjMf^Ln&*v1=zg#v|UC48tHU8Y^d)Jfqippk|hfnW+xbl_% zG=3+$_XXt>ztu`kWpGkBD^-=SNHXD~CEtcu9>re^?L*jOT2@J2pFi!%Pr@Dw;qf8S+>0W`81ZAt*t@Qf9)OkGft>? z{FeN*Y5%49yL9_E8JhXO2)*7fo=}=l@%3^s>#N>Bse8WIEGyosZGC$>WB+{j4^NK8 zIjo+V9`4kk(0=K|v%4`C=MyT=Y~EFUvE=sDE>#D?Q{N{ruQ>TkCM{l4?-n1AJVVc$ zcZntqN0;c&e&u}pq0L_dHYUTiWToYcth~*c^VrJfU0z%1uPS}uKcB3s$Q98ut)5b< z%kQpu_ueqzK+uE_QBQjHqFKUB1HPBqh2%CX=H6=jb92l2vwPn>eCRoKy>6k#@j9vB z%SCD#Z8+xc6aD>driqgwchG_UJ#4-|Bf1<*ez>fFbL%K1ZYa?h7prw_YD z-YoukOip`S{O71WlMMg2rtoB{o&Dl=aMn~#v-@nkGh&#G%%^YqEyZE=^7ZFz6Gw3Y z8;&BrIeYH!S2)Hz!F}rE!}0D9iW5Ev)k)9eDbcRjt)|0sqU-X60aT(z`QNPe{ZOyi%XsSTdD_x0pz@iSc7E&BMLxX*6B1iP(8_ItJZ ze7{~7Wcau7=hHoRYEE6c&~l79KYzyI?QbO4&!74&#^c8{W}Ah}y~4$&X?-o@pW0oc zBzWRfh*{kv$Hyk83T}602&fvnvl-dnx2fCS)ueIc`~>!i;`_AgnAIAWcNq7-R?n2G z&~o~pQoVR?zFeQt>I?nB{`0vm9rzy7;c(zlfYq8mp<#A;%chz%{M3kyh}?Q-=cYw6 z9hdiR($hTATJo^X^IdefE4YA5p7B{Pe}+j-+I5d$DV<8o({Cj%`Q$Bp_j&T2I=f_x zd9OYv*6b{ikV-hX>|k?>V6)=(qz8^^2@z9npKlLdWXS*W>7m4o1UVh4#{Dwx&Ur@# z47R;!RxF?Myp7+pX>}jC>@(UtPv2VW#2Jg5VY{_?i$fD%-JI~K`@p7czP>N7T`*fv zn#Rkm?@)Z`%!6mFpZ`RQhR95HlDT~3C=XY2X!4ur?ej0p{8yy1g}3$aS>AIVFYbju zclJK&BXz0CH~Cepx|ak`hKNqK3LBrf{f<8pzvJin*GMyG@@5`fX83iza4JLd(M|G; zd8f-yzVq<-3C3IfXVxybvq2-}`mXdx4XdTr{gZlMP&F|&bN*^Bc{6oqwIg@^6SKZ_ z{yLV_#(QovPh?u~{5RdNyF(8f{&+PteeL%ht2B@DH#N_f`Ss+_mtBSB`=WczxwqeL z%e75DJ<)$%y2Zzpm2a+Y(#Ief~kDo8-JMZRGCEKOF&}5s+&ZlBOH(uAgcsnDOw>iq~ z{N$zKTCaC$2Rfhi@4WE*yz{icimjVAPFZ{O*wnk07M+LIIWa5Pz1KU_cBS1VhV9BV z-x$|tNzE=le60mO#+rQRkelTAPb_wI_#v0~=58r_({DWZFh_8!6qj(f@U@c@=KV`jfTOw&EZE{EuHA z^6CEx%H6$ZwM)HN4|m)ZwZlDaH&cRKIkx$Torz9kzdF%8!gz!JvU?5n9(NCIx@Gq0 ziQgu>yz7ei6?sVez7FNBm)mnC|OoM9MGfw#%thEbue;lq+{&T1J*~cHYSd}D& z{}p(;r=RJX#U+l}d&K_QR@SZRQV(iUYiPQ3g}3=cT#Eb`7OMp+Pd7GS6^nl9|6|MH zmK5gu^Bg9+tak|A`^_QtT0hq#mid1CHO*!L9_}WuzAlXXd+>Fu!INN%eJw8ffN7X)3$*TO*7JLOn6&GpBCJe?5QN#N>X{4K3}dQkVE8&Q@#ixf--}hcend39!l8dRFn%sy)Ix z9HuS&GwIYzYa7k%RspT`x!<1@8+YVQXP&yYeUIknb#D}tW}koEZr#D&ZG7UcdSpmI z4SQh7?o}rYQzkk6XE(U@JnrbDzsp^|Go6{?X|lN^Z?OW;`D!(ri;JaZO=k)EsO%%x zV{`A`lA^R;A*lnGxHkvMJnETrCU`=A#!`_-R@rlXjg~*;tWa>@(UP=v{+AWs<16$R z%fp)qyWY30dO78dBU`S2)Ta71uNw2G%=8Ir`P8hV!Q4M*g^TBYRpuJrtGk}E zJPPSnWnC+~-t5nYALn1mM{HH)&6Hf4@>Oi&#h#T`UG8z_w}UU+ddNSDIg_>7vOw{~ zIw9*#wq-(Fc1+CDeJ|HGmvc?;tm21Dr|H~%#U43n(UsN<(`K+mJZ83?6Fg^4W6+Wwp0BNX}SQv-t$mLal`i8!fIiY^%Nf%|GDT*ORl)Twb^G;NHbM zBcz^qv;Vr3G(G7JyNFMnLP_$KogNu66%%@jg3tK`?Qa%d$*lZI-ICAuHjnzJk_@85B3m*t7I3UcB~5fGnHi z0%nV*Oov-?EwBIG$X#{#r#@qyDZa1dZ)N3)lpovOc*?ZiS*m}Z z74yl!wMyZ)+ytw`K3W;=S@OFYpY=Xd>{2a_+@LgNb;Kq2xFtK6^>cJS@i}(FwJZ0+ z%cD6fF4%k7>*yp!RC=>5>EvNK7xZEEk59!1ZZxIpcqq&^I^;g>$cG6Gj1FBINhJz_ z8Oj-)X-rGcJXSi;_S%2eQ^&nwx0!3)JXZbqxmhIGf#H7n0{!|4j`t4Axq3Q3u%9X& z<9R+Py8krUjim6)BRYdLnX0VDA6DTpN~O*vS#4C+l-^;jNV$ z&z~~*tm(lX%%vJEP|MMCr+tA>f%*K6*NfKIN-f)VEK@`*+|)?w(%~s=&B8}x_`=>D zJTNKAj9vTtt?7PzkwVL+hi;Qv#Vagj=zFLl?b@0<&5Fx1BhL6tnp*v~_<`!}cB3=v z1+#dswrlp@`D!SrTyE=gviqi8)Xww!I_B6tE1aQX$NMtTOWAXw<;MBKlT7BV-8}X8 zv_G4f+lS;iB|J%c}+m+{^aW0;* z?fg2+S6Ek<83vUi(goDgj+?k zir}A>=3KlkU8jtnoV+UM*M9EiRT++t2P%KtUAFr)L5-*Brf|-pE%g)GKYsKrE1Au+ zRk=HDWo)8vk_WTwsUJR-Tih?~XH58H_gjgDkD>ZSEn9=tVRrk6u3ZOW7h1o&UeLm> z@me@eW%fDUu04(W_DEbg`04ZM)gPSn8;^ zOppG0soa_M$Ca&WZAYhWIjCYU(Q8sCw|&62-Hd?z}9`@i}Mu^ULl1^}pWUtqv-cF8Y7`_U@~)b(W^5 z7P@`txAEY3^6|p;8fK1GlbvBVLY$X&uX-GR&E%>E4~KM4IPa5{_S>W{eKqKw@cZFP zL7B97`{%5&d|%S@%|&kYFaLdw@~>ZUNJTtbx^{DwykGyFwGypwW4CV*{GGL;Tt=$t zt|Iq~leW)4J)Y-nHR*kUky3Po@NYS*OC=w;$~4wo`&&5SY@lF-)U@X}i^Y^$uHOAP zC2Flga($#$+R3=S{`&aspV*Ib*u3nt$))Meu)K!)ke-?e|5RA z){#Ga_Jp!Ir(a83@rCVn6DW+~j@7U&a+-G7Y{k3p7Zx*CeW{4q?wjkLRsG_7+8TRL zLA`F#KMPK2GtQJWU+iSOta|x&0atbgmhc3r39{?W4n#egc>U}*70y>@7Ds$IY3r_U zATiw{qw+h$>41H!3%i&F`mV(Y^}B_g>o68G|HS@MaNeI$hU9aM$QFDLWUtzsjlQqw9{Jy+yW%(1Qk4ffI#uKdL=QH0F zN(_Fn?oUtDf-TOjPd?bE9ekgmvcEKV5ySMIRo37l|Lez+jDl>b*SA)RB~M9fdvqe; zM`cAm$9jd#U_QrxkJ{^ga(FOqv$$sM>eW2Q?+lyzYagRR1p-?q4!%)xPQ( zYKjRH@`7dk!fo%H$w(B`gdKLgUt`<#FvgdGvzx~(ck{}cH|*;kScSYemR6Rc@JRQ< ztrdzEmMq&Rn5xfqyK{UkUjj<0ud4Jv@9Qfj`CFiwUi*l{vWN%&G!8h%% zBU{LxgUxIr6+53F*k-WsY{8V~%6lgIVm`|KQzqW2PMKr7-YW6JETfXWRbJ6Q)r6Z!G#yM9OP>Ao`K45tSjelI1FamD&*bz|CzKaVUAX1Q+9o3@wUS3prqkl%S7>y9xV2nf z`1?|E4UOynIHK15@j0>Z+{%sTy>9%q<+^lmiqlCE7kMV-?}{3e1tgM=#hu>!P4nI5 zTXwyN9<6e7bFP|kDZ$fhcJtI~gAGe&oIQAI@3*Csou{?DOr5&6E$eWLo6lr}c{5G5 zzbABLN{JayPI(&l+a{%K(j{^W__oq3&dLiS-g-yPym-NG(VdGk61I7m9yy(}?(cW4 z6-=6~a}EVwSYr z2fJomFc5jgryFR>KT`Ay0Pz`5!Kslzfo=9zUOfQ-HTryx)8_L&i%JfT*zM{^oB#t3*MO* zV;fpq7Fs2|XlLm(3GeMyjfs?OwKjFkR(QN9_1(G8o^H=lb*3EAN!Hxtk}MiB;d%JN zq@?rqEGd#|;S8%qq7N{ipWWWPQp+qM+~UC6)QoRpA2%o7n|I`w9pCfEl^g~BNA|m3 z*|9fiO^m7DtIKTZA!?0|G3$GOMz-rOom#f7FQdA=x%ll@OS`_`jFyjgE_bMy;Syi+ zc2|6Xq*`{Nlc>LJn03P*gBiCz{e8F3RxLe0@l@5fYyR_}9Md@OyD~O2yR1#6EhRAL z*l`!V2j!El>|xB!U6O{QQ-ZqYdr);s%ur7gfptoZjEU})+%LXuCRF#m=Rdnm&`u6D zj|n30bu(X^l!tE@UcI+{$K^&9kFF1;Z{HoU zFFr2*?wz7TCyJ_Tk2*=|d2sxnx!a;MbIOFCm*;?kAm|j{0<899`4Y& z{^R$jpTD$ztc)<EXiJlU)*HmZ4H|NOpE}T!K>Ql`64<+boRR@Q!WvJPFfBOF&`?{P@P43uz!RHpE z!n>INAK%5x+uw;S63tBi>>4n;{Q0}o2a}(2)Ce@4y=QB2nUD41=X#+)rdNAiZf(m8 zKkU)*JEdEt`1cdB!=D28O^Q6yf8pUh#>3UCZSI*B#hOd^8Z*xM&@RJx<{8ht^8p#t zL{ty(cQ@_c#rn`IlzHwV(}`{AihNvK9{-ts_*7BeLan0z$Mxse{d;$rfBWHt{5<9B za!Qw_A6R-VNb#IhI4gCTp^W!OMUHqUv9)q(?wuRiS4yFQ?K&7;swUvUQ|8!77_en=W5Mh=a!5Y*|7}|jQ9-%_T;_Zv}Qiz`nssSvsPb? zyZ?InvsFL5^Qt;_t>V-4mbG7$c|_akLgJO%YbWV0SZyklz_jZ3%5`SDw)KC>5PPIj zVeZY$`ak*MQLC_8<16R?U3)A)pWC!$+OAV6+}v+>YTgP9%kLC(Eh2B@qBy4u9c_sGi z?tJ#EP00)Hrkp$G;li2bqP$Ve+%1G-vbEn2&p&%vWM(ZqA9&VB@z$G?n~9$`9k}w7 zNp%0kNba@9mfQT|-&+cuQx4aT(q()*O+SXaF`!lH{3e}`tG0`z{(L2NUnoO4HPDms z>LreZ@XkwY_q{pJF4F{ zd5(Gsqq^o(?phw^d9PQ$oqf49W@h%{JX@~JS+7f{-Tc1)YD3^TD}J71>#yW9Rrky~ z5a>JkhP=B-dda~*gCeFDsS_dtX|L#&w@N+0xp3Is0RsWznrAn)701 zDpH{CvTgM~Q6@cXu9M$$DJ&)z`??->m0k6zH+pzcv=QYBkTg z<&JkJdxMHLXS=@bbpa2HM^cH$cjvJhy`C&}h~59m%IxEP=er+&S31SBZ>gH;m*^5Z zH60zV^+#8?E-5QpuAD5KWb)P%l((3wh>x@Zxf=NF#?gp5Ao4RPD z@x@0ruNW6)gyB_p%# z;q9u!`XLxIVh=?5`ypk!{w#T@OA#;@H(;wD{taIfjWBf6myjL1V92 z@YKmiI4;V@q&dl63;4RVxBm}s&iPjwzEvCCPJCP!U3=!&k`_&OCNDr_ZxHxU_1*5wm);d-@7i1UP1G-{ zy%1meO7|fDwYuD^X<{wI{g0Xr2ipex0$wGIWN7F{a1Cumfs83 z9DQ~|-I6hxt&odv(50b*@~Q5X)6kN{#!ktn0u`K)q*E%cE5z?Ii1<%BiO6FDjZpv*q!?A}i_SJIcl7&-MisHBEN;q8nuR1$Q zD{K3^31{Cv>#%EUn8O|Y`S`EDRvybjd3X75Z~e&oIeW>>3+CLPH!iz;L^fq(uFC0M zdMA&sntC>Djq1+)h0$GUi%&Rj_*3!UpgD|(*;xl8{46_cN&IeUrqY__DEUpM}^>io50bJfpB)4%fwZn?F$#?ffbRE=i) z&mmzugggxTJp00qPuDlv!v078JIh=4A8ng^7F~7wyYJV(Pp+R<-u!a+!dthJ|0OZy z>>=Buw^Uhqepz_8^zTNw+3WU3{|&$Ex!ii?PJw-wonnu#<_TW3-g}?g&HkPXXRlkE z@H}3=|K6>`HVzd*iX3TE6M1B~4-2L*xn#3nWp#U+L-`V)V^y^iex3ZM(0|tA)Y`f@ zd&x7+F7>&)*19+_%>9*j|GN8^zmD5h?DO`VxWMsU|EAF6PxyCMns_-XCYTpVJovs$ zcK7c6;q_YKOIap+O{_AveCHjscw2Vx`gyU%6C@UjZZNRV*;Te?c9}!hjg5A5XO;Dr z)t0*)Smv`v==0Ld?Ysd7@yE{9yldERk`uPRr@QFwq9wI9>r(9#-aeBF=9BZ*+%YBC z_q(^#`=G$Ui5J3WSMN0Uy2QhMs3C20RDvN9me*XP=?SAKLf>#uN%zq*B zcuB)zjl*j~qBLGTJuSXFe0q_pr)kEt%RHaCp70bWo&T@HP}F)PZ$r`A1M16n=q&rZ z=!jCs1*sa2S%NWc7H2*&u+MT_({-a#n}1&VG0$f;VTs3_1Qs7+Kl!jCtTlP&;hQ!> zrz7RKuKFIBqidQ~YvgiNsQk>ERQ5SS$r6_LQ9euX7+}4&xL_HJcs=KD#4x z3>~dA-3lij7j$cXD0uGF1odTWHa}nJG=2IqD}kkl*k?A&J+XX#*Vjd3*=1QpZ<(F; zDdvp%CG%BPu57mm^bB<=XoF3yBeGJ&VN^_qjdFKlhakZ z-!8O``*d=e&$+uN=l$7w`z@PgoPk!s%+S`uC#w9vKD=4NqPxMZZRV?Y;^xlRQZAfS zQ#G#%n2}e$@8TJ!lj5h1RqOXF#mIXtWDU5jBt9*2`(I(*9IkV2tXEX!vXDD_W3gemX6nfV zH>baAN~@nQys2KcBt&>gP+?Vt)SYTJ(}u5?PAr?aMy|nc?^exqrrnzarfY7zq<-+o zx~ai@A;ke-FC;h3vI^w=Ipg6XtrhC;{XYD&OqSU*<-J{<$>h)|sW?q*exLNyUnd-$ zx!^L#(G0=L%@@P?X797?jkV8cpI^KB`5LDcaR)P2wpIAsN1w3$yXFFuo9UVB>*g^x z{7m1~Sm5tGTOq1l+^O~C-3hW@e%%{nH`};;R!jIM68`tLwYASW4y9+_i#T%A1r}DF zygGYsvCadLFTrV29p@G`eU3@Lc$`nD^Wcl8-b+r0-|*Bh@9)WNvD{-*DKc%gfOMq^ z_kxMxO7mD3Myvh5m$LGCUj)zLj-P!RPMdj@{urjbdbZ~Z^Rtk-zV9zj?YQyD$G9UW zEbwaXeaAHdHSJP?s_$plN!TXt=~Lp-N>7vf-||$=#Z9g^Y1wQaldgr)YW(*TW`<9d za!?NJQFtS3E^xr8>4WRULu)i2q#b-N_xhXhWrjHcPnH&3sqW!9y>r-9$w1wYFMwxmhA9C;7Hv zZ5%95F)Z4*Ma5}f$Ud%UtIFSIN>939_D#@Ft2}XKHp5q`9lxJEl|I<1<}vfs%BTNQ z+x|YyQ#452QdGvhTW{Si!DCxrs5R)9-@c-?`;NoOpJk>h|LR%v)J`xefB9A5@Oxji zjqbO}vE>#e_pe?ni@TU+<(VSD+Ph(!Wq91{w${A+HIv^)eok7uB`?l?q4#xx^5?~C zLhKwhH?5l)Za(eikxx4=ifulB{>$Un`_|8Q5_Eaty!-X9WLvY??pLMXEf)Q{bk)v0 z@0HkE)gQk$-c{Q0y)fg}->Fwc_q4=V%<)Ox$JJC?*>$2d@WZFnf|ZLG8b}4$DlE9L zCHg1xKY8npa$||_7tgq)I_?O|W2k;Fe?2)q-)%>NuKCx;3Zctl-l|U%JR)82RbjiC z$%jdthl-{I*{uGz_nwVH<%C}f7Ev#EmziDSxxg$C&Ml_e<$JuWdB(ERH!~ z8fAOb=flc{2lu(|xR5QbeU)8MHGF<$nCPp?&sses{_ssZy!>5SfPIS+_rDVl@4Fi8 zQ`zmjSN?%V+=eB;%QpC1{d^et^>l2!ysC}yi>16z?x%m=n&5hAkL{Ji3H1US6iRmA zRdD|iv{CEknuCIV{;E~)6%1Y$zQ3?{LbVlVOIU81!Q!)b-=#CUd|h>dH*B5gk0&8p zC9CI6TlIuZAgWnB(BWoBq~%Fx8LqC%Gi{!7Hs=ezHb)lj z5p4hDCgWw!XZg`U=dQ&Mfhh)empIF$RW>lUDmJ_2%y@e6^Roq88DGR1Z{bL8<_}CM zlvb*ER!84MHIZRg%1S2YcyEkTI`oKX z)kl@IFRQW)gOZ|H&l_uGMgAybQ|+F++2MsvEJMPkv#vjCVr-^|%7o5?v*2)@e zW)(cfC+~EpC!^AM(V^aq9X0H4HSShC+1Z}@^4Q__f>YTIs;aH~?Ai>hoXXC8YLE@? z+*W2VhaIHrQB0Dvj-qznjl@!xw=L=N*5#`0lY?`J3zyTuRxtG5zjzEz>J247JaE zUiZg2ar*Bidv4u3AgukP@_j;o|KW}l<`;4{Dbsd5eKu3kqRvxRiZ`c%kJr1B`L<|8 zf8Fotd!L#wsoQ1Xv^TS$&ML1@>N`hF;9QYk3$LWknW{BE#BIgw8L_`va=L9EZdf_h zX8FnLy={Ci{;8Os<-22V7Q6cJU-=DNe%sA3eK-C4p-Bxe$j`SYWI|SMn{Iqcv*?v<)UJ+04_wYZ2t8x>sO{1IRC^75fjMV${+Tl*&(=@G z(W0jHY79&GUFj5E$YX|mWrn$lA#ttiHQ|x@cPxbJ%pd$e!1_rc{c_C2E0PKFNzWb9 zCUhF!y>al+O!lp_va}aZlbUqv_`hGeal2Hvi@#>b^wg;gXG&2*)8Z8K@0qP~i{2c$SR1nN*Sy6`PHcK)c=mh7bTv->%DBbM z{Y5{57RuUxs!Lt{$jp z`g`E3^`b_hsS~9h35klU=BQ@R>%9=OVN0`E)|QZ8#!O2rHaKrr_TRcNa*KSl)UGQp zPgF@&&%UOib^1l+r8M#Czi%?wyW2N@G&)sge*gW}p2R0zwu+VSYXx>GaPbH|Q`RpqX#BvmcBOaWiCOwLpC0}7=~2|Y z-hyX2CeblIHKk@7d`(0r{>tW&e!$&pcaU%96^nAI*}Ad4zA`+POLp1q2oV2qqkd^~ zns>Ntu1wCoqRdmhaZ@~wRz?+WFuk_X+SH_P(4e=%KW8eO%Md)6J(TWmL+ zq!nY|ZMo%U` zUaoR-MQQt;$ZuD>0F?5_Fv>EP@aGEJGQ>2|Nz z;ca5_n#rb;39F12Fzfh;E_{7FLiVA_^(h}hzO+rb@U4Sa?cNIBcfDGZBu&mmE)zH^ zGHJ=rh&@%;)v{LEgdRPz#UOT8+_#;{RukBBZWn!#j}tSnfB7i1_b2!Exi(d{YDc3j zO4e)6EG#^g-kGx{S+-P~S$O6Q;oOO_D+`%_m+k2~{e>e`&hyp@LDq=*zC9s}8Q+*H zPvE>%u`lHE+v;2mo=pPMi7OtI?RUB#`TpkBE~EL8?;n0!)F&SCUejhm!z%qV*Z8-w z8}ZrfI5Ih2qS)zc!oCXuIqI*#AH zv9Lk8edf)-8+dAe|Jjsd{?&+kgK-4E1fST2h3`wmFD#sy8!JBV%k_nhQJZ3Q^l$LR zMqMwn+A`Owds}e&#j;mla?0Ib|4X{3vE_OSzOw{-WBLKEd`8;>@mlUZe2))aP<$-waf~VZ$S0<3 z8IH1k(|ZT1j=!!lzqfzSojGNeDJN4kYy+~}nO>!r{lBwmomiG++zj(zz9n@#n3^Xt zMkV<*pIDwfEwba}i-6b3rt2NO&tx|Ix$MTAQ>uRM?Ch=j{Xk2_(ggzR_=ZGe$S()%sq*L`zALB#Gc@*&eX}- z^-8>b-Ndk5d7t71ujl53TH6+#>`&M!VHB`LI;Uk_rOaHdyknC%mR;YoLVelMzVN`% zrN3qNNSVF+`EtY4R8>=EwHmG9bq@WJBHb1$rus)e9hs5L7&E8rLDX&SCG5BRtOFz6 z&U-h$DV?)SJZ$Z{(=q40PQ5q~y8q@elaR}2cYJ^Ertf}no7N^_9;1tS?DN&1Eh(^3 zyZiFpt*;%`%gV}~tdFQaHf(vIvvgUdeZN)nMlahuSH6dS@tr@lnm3wiJ^wpTp~#wL z=EKJQDSg*xCEu73)^YmmMYG50FHIjGZCbam&Hcs)t{TgYdzkjI{M55C{o20j5%c>i zq2cmJ6(>)1Z)sjx@Mpst_1OXc9&?3;?tS+AK1(~>;ny3cWIF8V(8y#sY__keKI7YC zhcgqttzbEu)#4<-t7OU^YwnW)i*}rNt#P)|IkK(GW!~e&rvhIM&n?)nKt?1);-HU2 z#0UG$Qzt$OJ$TZ+W9gsP#VhJu4Fi^EK6Sh7 zpZH1sR_23tVJ_W>s7)MCruL98-0ED`}z45tM{m`_E?hpQ1<@3Z~1vwXMdAeZSLrwRcqt9 z=!E`pjep#6_g0!0p7nG#&#$gLuJU1PuKE96e+xcqTV2hZcJ2I&2rpO+M!D<;3 zo&~TMt#G-(qWQSSu!KY9r@#s|>lb4F%U<7JreX9YltJafodu=5ce+l+w$??=UjJG? ze1i6)*1lFd@u!MSmp9vevhZE-fm6uyYrR8A*YQ(d826R2N9EmbO$%Qh?A~a3?n3Tz z_4c!_4}S-J5H8ut@>XB}pEWnPZE!McaB;zY#t7ktTc6pgo^^cNz&J^ZyWp_oI<6br z-1AHqv-KNp2;_USfzetgZP|wpjbZl^4=htSF~6;ft>8KX!*3zaBpl6kTCY=}QghuL z>zV~aQ%fS(EKCW%op;+ppq76^{e#6aS9ClBw;wml?b6vMe&o&(`S%WWxG{1r@!#qF z=!ESx zvzKVU$`btFYIpS9as$4Fx;7=x-Fvv!-L)*|t4_KjTFzaxIO?j+sxyAy(-q$Lu*^Ai zB7tp6(BhIZGmZvD*Q+a+d3jyh-nEb8ROw1_o^LV9=MNP##@#LpcU`$|wU6yyA*Jai zU)Uz^Q=C*ZKiepO?vM0~lUgVE-CiF(RjGW}%xj_3MW(*=7W3AV{Tn5g>;7tvN@{2S zyX8u`cgyM{|NEddb>L%R%_L5mI5wzO{LIHj0T>IPdHyHVLfnn zQvI(bI-i)FF0T+u`Lv>Oq2X(HZTH39`aEjqk0@wMJy@2vO|5MXn_d42p~FX?ZeXyS z^m47TnD~Pm*0wRU7r0XFU$R@d zz-WPzjf_Iey&c7$Sq}(*zSml?(tg2r%id+oPVYsk1b;2R&}|^G@cZAxan~m=-;h{t zl7IVa%_}zL7ynu$PdaNon>kUS%)>se?P;0`&+Y`8PaXvxSgpeu=UTMpU7L}*0h5nO9;5ixJFIB&{cX8W5RCLH=tcDrk}1oIY~nO)tx z^m*Cx|L-T8wj9%*eQ8y<%$Zf)tIVS;ySfiFznghr&K34MVKYw36)!Vrtj~)-%r@Cf zR`$*wk(tV(QTqFDCq0V4dc|8~ika)wlH{uB-FNvo<&CP|w#goQ73yg>Q{{_#my!58 zhiJ{du*`0w%q}C2)bJ$%ef!pFG#5SCk=Iguy7!pt%@qoV!>)hHyl%ch@9UH$vQvyx zKW;Zl_r6`L^|~~u?)7z+$yMxE7sa>fF{JP3No$Px%UTzEf9JbruZ$8u8lJEbxWCUV z=I@WP&tE@1dpy-{k5A?i&BL=Yq_Si7N6u?rn!H+4xiVf-Bj4lFqRaPDD>Ukxq|1wQC##fqzh!>4?$l|ew^0J!dk-8>wA8Wi4K?qY zB$&~#(uB)%e~Z=nhFzH|XAVCyZaDGFk7H}vi`|DBC+AN-;JCXgKr^TBN)A)XTmKzP zU&U|xQ(Z0k<{T^M!?eTGwk|4PYGbv22EWTD&(K##N@FLz=K5ALZ%Nkyww0TfoQzta zwlD6k?iR`5+|J~j1`5Z%JxFQQxx6hb(nw`z+=Z|E-+!2}>xke~Gq$9Y&+E<| z?|<_3&!0Dsj;Z#Xx&A!;%(60%oF6OH-xa>9P${TAWij*px$`-j7@PUadvdfY7H@ky zp;D=SzWn*~YwllOqO&R~cJl7ycQ>8zn6v)GpF;f;$7^Dz?B3zmU1Rj$ovn1%f;nz| zTwVT&E{hv}Bs#q1NcKyW5I-Ej_*LVl>AG!8`liox_#Ya0?N_PlswF<(jl7l~{?T@8 z#^Xd8`<(1%gL$jkHeCo7J-fZ>PMot^=&qBGe+6(|5{)c%y|(GZ7VSwYu5rgR<0k5+ zR9}1=(I~cZJJaROC#M98o!qdWXUpbQulOT3_87l-7JX^o-@=G}p;N=Z#_~QCnlSm* zhBYotOD|s*d;QNU_o~hkzRSW#kKH?F-MI3V-@WJnnSJNeE^PdL(*OQ-fBmi%(sREE z?_M!`>UEH zUoH|Dt6^ut`BS$-T&!{b)8xM^_4t18)p)=5>E9NgWjY&dUuSW->c`*w|F5Xnex}Wt z`pb_u+8#gtQRDN~jWMO)Rx4W-D2Lx%-}l0ywkl8NR8If*J1X9p$7-_O_T7^!^A4Pp z#5?tP>YOW!asry({z^Nic3c1HlLaj56V`omoz=Yajrcbc-POB3YdPDL-#X1(E4S%; z!&=FW`qn+$5(6La@D)_r)D_+${NiBvmAU(`NzI-AKkaXyxAI)$NRQ8&XWlW&#LRlL zeqEZ1%mlA!hcxwx1>7Qcmi&pHT(jP0<)d<~lZwqo2QRV~THAY=`{+7cedOHs^W3a6 z?Z1-B*$yynIwP|8_VgbGs?84{&o)0+c9-$V|9Nv2)^P4;xZQrxuJ+WaMdwmHN#&ov}uid2Of7ku2Jw12#oVK?`-$gU^3idvhikF*oev#Tvr-~>>=jkuSH!8i} zbi?$go_r&>-RY_N2Q6n>t=p;{*1jg-JVVrp z5vF9mrCOVP-;7=JUPo_lW$rKB;M7}cVYgV(`1-}k{L6nXa=NW~ zLu|1cvm5jOO6?x0+zEobvC9J=SJ`d2WKmOjq|xryn=cD4IZrz8{Q5bMpQiQ1>mS|~ z!NYpxrjJ41pl1?60_neGy`=4#1D57}SmIRZcLGikcq zXp^lld#;?c!-Q)|?a{L)RC?IGDpPRv>9YK7Q8YI$pG_@gn)U>ZpBjA*t&$SUXHL-c zGJY(+ImKwwq~d%IcZBPjl*M-bjrNvz_Y<+Ww)IxoebM$k>jb>~Ubr*|IB|H`?!0>< zal5;}X}!c>iz#2&ZXRl$5s+9NyVUuw+3Bk%rq+mvnz>22wrYAAZxr8rL|?W1hk(`@ zsoWkx-nmNylO;s=?Kx+7BjV2sNv%V&2Atn_d|em)vU~0l@p}o2+;x6i9G!gpRm7Cl zT|!3roQ(CCW?Y<6uu_-bo6YBor`P;hUK_=ho)ETRdc~c1IL`mvQmyjU{uvqTa%OFL zurK<6=tIxAT79eDZ+4ky7VeB*_d(~@=cJ>jnaq7_1#8=~#9Zz!Vf$dD6kZVa$uPuQ z^teO2l>RXdsY3m9NiTD+cdpDU)nV%#g0w(6DD zscW{p{njnDEY8HxXK%*SWkK;F5>MC-nmAiJls);w{2t_KT|aaql|%dhpNPN7SEUwd z^?QelcFYYcSZ-UY;i)RBew%Ysf06uwx+c#@&K(@3&Ymf}&4p(ZJ~Lf=aeR;1Q!77~ zovR<$h%#F{vVHC^|8$Fmxi_Z!&I8`HO6AoPm%KLVe7)s>ZqJ{o&$M?e)V#H82j`cq z)7niwB-CwNq<2*O`<+t5!`;&HuNg0X{kp>MEZ3qwffLXE=p5Nt!T5B}4w;14r#`aC zGQ61=rg8r3+-oNV=5K31tjBQp@s7Xde=jcIVecAw(n@mc?VNw|3{uhxPjJ-UsH>`I zu;R;9!N?pm2^Pf5WoO6BrSDo%;vQU*Sdyw>W5dg(?;dQZfFuo4lA4#2pOnSRWn_+Z zQp(WClIVLiz4ITN34oV;1?nZZ)x6m1z_ON&7#{-X9iqF4(e0*m6mv7JBISRR5`tz;r=av3W{`zN{ei=d&J=&&lP72#@ZfDu> zFJIb?Pj*k>{pTuoAAbMx_uH}Gi*Ic8z5c}ZW=)8`uji&J|4aShu5z#UWUgMLKdWl$ zzizXi36rIpKb&JW5m&Q&>NETEzIWf(zOuSxn(P1T&C-yR*Qp;q&M0*+s^`z%wpzdJ z_yxhE8}b!a`1nXXs7R1muJh#9Pj!7;txb=D-uJtGtW4VR!ed+1<^#&@+bXMdUomGE z1(~%cO`p0XxZUe&E&D%H-92v&uH@}ja`nB}fApP42%G)fbEjWf{*|4)Ep3YGi<9e< zxuU184!dgYdawH*M|bsyQ+aji+g-yi7;aV9mtVrLcskcwEye5qH9r`<5AiQ;J1}p7 zmN;9VX0*+wX*2KOxS@prsSV)^PgNgj=iQytJB+ ze%fj3Ce1B%&3pN=oSzjg&KmPmB+~E-_4%&OcuHMWMy63`9Oh6`w9Q< zonp%nUh=m6ndBt#rw&0X`Ln$~U+A_HDb3}$Hf5@#UWLp&!Da2M%2p=oF|gI0?%wvA z-SgsVu1vqn>(w@kG=0+JxGeBQ#D;OcO3E^wyq%716ZMimj)-xNhq4t3FVp0t6_4BQ8aKdVmN%k`)g19Le0xNW(b_l4tsGf z`TxBwzx#wH^_^K@A9*Jt!{b$QdP5yp!E9YHF`G+APtFmtO`)`MTR#Do+eG%?X-85fxkf21mRA$Npb?&PVY=#y)L{qW2WJoFU;R_ zc|Ke`>&*IEPkfd$r?5<4+>yRUuJ#??(jF$QyLP1ch$pRaEx4X>{wwo=u*JnQvd>rW z>TSF5IdM~u^TECBwi8QJKCdcs<#V2F_o_noZ}64s87Fv>@7lVQ-4Z=pxow)ai{6Z@iWWG30|)q5+( zZ7X@}@U7;r$s0p9uh{Tre}2!VE#7*QKcvkozjt%CL4{4hf`nTJ3s^eY9-WIaJZK=e zV28`8178vy9z3zz^F+jN@@_>%&KX&i=F<&2?(NFjGC4Q>#QML}|27t_I2d!DH^n*o z_`W&T)<>RIH=g2MW#DUbS={Pq2;=n`0sJ;@$9CD>G%!z&4&!~Y`E_L9R~FZlO?x^X z%Puu~Dkx)<(Ddg{NbK!UIW|6S`MUwPPm9#gy573R%;@rpmPvfM^Zsz;O<0jI=f35V zKlAxGqnFOAdbs)Y1ihUBFBEvTxE*xRNa3+~tYP_vV-?FWHJ)4Tx`%z2PVBJPT9?0S z@6P@<)jDaPg(9zwV*V6u{dBMAvXQQ9(dRGP2N<3;=I+6sAS_7k(3>b2f?_QQ)TuU8 zFa+rbv&|I@LB|A=QS)1X^nn`z;6_47WkITfzDHtCT1kFhDlZqD36=mYQGv<%CFZ6o zXt<=NC6?xtXo4J6lv-GtnwMOu0A48Wn3tZDs$c?2O~D2EC2pm8$t9Wjc?$YL`K5U& zkR}SO{Q+v0pt}Lydg0~L4|Y^YOUx+-xyL^M&h!XT(1+TOYMhY;>S#njQGRl8YKcO$ zet?Ucg1%>NVtT5RLM*B#LnG9X0Q*lr1mtC~-}T+{^GZN&DNQN?2NFmWGzk!tTAW{6 zl$=_u0I?SwA^CYFPEPq13eg~!7+ES98^nTwC_k^nH?gEBvqB--K+nL)7@PtO6p+|p zWtm0ACC(X%MG8iSX1rYbK8Yw?*SzHXl+3(z1tSYkn-XLnNHNHlAUA*l6C@U%nNpHb ztPpK%jP6y4K8yf|8q3S2?~<98mRgjW2l7<3k)fHsdx{07As~wohJch9S%7Xsf~G=P z$EhtD_2OXs3}CSE^5+bSu5k9t1GhBxJlWf$=RZzm3hWFw}1@+7x&!%-+1)+!N14v zs&=})Ix6d{G9p z|I_@am!A)AoI0O@nc+-dVI$V84vHs42!K+K0@m~dN^OvY=LR}L6Dg)a4RlbfIwcmT zf>NS_zDH_KS!zjUa-yzNehylO0+$jbS_m4c!)swkW^QUR*fP(O#GK4zNJPP+8C)2V zXeB6d6Jcdger{qOnr*0=m8cK}r8h+I1y|-K<>#Q83QE2t`T^8KBEk=tab$#gO9D|| zFa#wKB5cDJL1w7=l{ouA1sq=c;HeNbBq2Rf5`)qZR9WD)%{jlcC^NMP%`OX2=0LX# zW)6CBreL6-UX)mts-Ku#T9T@toLQ7ynwyrBTA^Q(nUj*LpPQIml%J=cRFqnls-Kcy zl9-&FnpdKql9^hRTAW$T%cWnGnU}7goSKrElar{QQJR;YSX7#ulUQ1!pP!zemzu4g zoCq=@CBGymwYWG_!Prv2ur$9UwKx-8C0d$69Kg$^U}$8npH!NYlUjmCA=D=&7N_c` z<>VJ-=0QwJNy-6>rRL;h78GX|>!&29r-On7%1BAdff-hiT2zveUs{})m!cmGaa4L~ zW)9dLIjLzS`u?skr4U!}a-s4eHiDIcT~w5ro>2l3Oi9W?h^HjwK%^kX=%?nTBo=4z za_Oh$f*3GEONtUxQgaiFvh|D6Tm#Xap9)h6F^88+KN1%1`o#r_$*Bs4W+wW{rA45+ zsZznv%uGM2C_g(jFDbD|!O+YC9!vVk`303wLyJ<kYI&et3`#1NM*5DBgzE^lQQr|M={iEvt|L6O9Kngy(N*6W>HyGq z5JbBxM7t}Jc2~GQPly^%h#F5MHJ&gvAd^Zm^!*@K`a?AMLp1m!Y4C?Cfa%lEEzK#( zEXb+k<r&PgoJ&<}-Z4uxnAMbaD!*A)qo49UnZ%F|CzEy_*IOG(NB<-d#h5ff0rq6M}I$Sb6q4e~6= zI(S5yKm!Rm`I&(HLb}-?-=dlg4JBl=O+kJk*=+DF2q1IPi0Lg4n*rJ;a3OSO^2A?5-5+-J#uthW543xh}HyauP2zQ%-!WP|Z zvckj+BTT@1qR`DID@?#^WKhBcynqwUY;(e40-H(GN90R$j4%POdO zQ*!8L6AlwBW`hTrP{IT}^owRT)`39OIvAVT7-0e)dqX!Hl*90+L2PD2a|$92VjEtv z0EHaMW?MpY3X<8NutjsXC8&%c-E3%1L6~g`N^j_9gF=pUvq7l~B`z&NVT*1yDC9^t z8yW&g?goV|n%Ra1pr9k!a6d38Eg1pww?{KHJ=TMXg^~&ADUQ@-H$DNunr3n zk$zyUW+d~$?Q!(*0k^lw2!B}98QFYLR>d$Ml+Fm44{tpq8w%!eixr0_Ap7Ct7RbVi2x;C4Bh z`$0jC9{%8VH#z1*6AP02VU2o}@Bz2I$uS=q7|7;>k|KutLE%V_`Ov^XHXjt!=;njl z;AEH&Zl|M$Kdga|5&3;2mP^Kdzd@Mof4mEtRHT?}OLE(tsd?RoZ9%L3${;3VQc>z5z+p~>VC}j zzY(_fzY!7bf9&Ri@+BzF5#fWa{cl7>`yadc(8PjBKSqY2phnAIM&Pk^GSUxb``-v# z``-vWz)p_&pmc{CKH#ndy8FTX1ai!W1_o02fV&bH=7YkKfcfyYJ|h1b!5aI>=0lS# zO8O_F{cnWTe9Z6x56YvvA3W$zj{7mg2Rt&5VLqAR18eLfg^w||@B#M|$Z$Wbv5#av zxGRC~esDj59P=^CegYzIFe&NG%%3e4+?5@^TGWDGR%iH_L0m7cO@{)2h|hg zn2%Y$fx8kI=7YkK9P^=pf$V-zP-B=63P%Fw!`u2u`4`sMM=~GWl|VP2i1xn`R`W5# z2V48!h=}$-cJndA2V48!2;8M6J*`P(N&iSQzB?^Y1Goztv4zLx6;8GJ?Y$4nODWw&_M7)c@6A}1b1WsZ>3g)1&3{n7h z*n$+m{i+}ZaQ7!j0o+RoQUG@*f)v1Q{vZW#(>zE4GJ;NmlOW@X_}yd(Xl-vr2rclp7Ng40O>h{XmClY0O^SaDHuW{8Pc;O!EumgGy%s!(+s5B6{KKf04}B!jG)mB>23rm zK)MAW8j>g>&FmlrNOKrOgB?wLHh{DN@jK4Q2wdhX7(vpEf)O;DjlfAFNWlo)mIBdG zM?*8O5j6K2L9?$BB>$4&IB*sx;5cY$U<64s3XqB|NC8p-1t}OobFmRLnvEd&7~u%e za$$TW7p`$)M9Bq-3UCn@qyR2gK$#yRY6uM@=vaaRBryajK*Am5Opy6OpjG$!kfPKA zAR-w=6oH6*5Rn8T5h)@6#E+8TkL==MvumqT!1LA^-R1gbn3Rs6Rh^q%8 z3_ye-hyY8ZfmmRR5Q@V=Vqo*~K&%uH0aj8DVijwmdcLA4HI0|cK*7k;fS1bv4iwBx zO^ri*pkWPUF#`i*aP5UEW@>^S&W4s2 z=Aa=XGWMFQIo+gb9%*;U}cF5`sEiH{fy>w(T10zF2P_2S0W@HX3J(0x>EiEzg zhmny5Xb2Wroq>^w8I~|L1x@v$sWS&PI#9*TEJ34J$YO?;mS*UFGcYnY08Jert1~dN zv;+;OB8wSXTAHKh4+CQZLr|@Vtj@sL$OKfRBa4AcVgt1FY;0r(s%((e85o-q6wvBhMIuyk>IRBb_Y&D&0~14IPzwNA%*epN08{}Z ziy4?0nquU06BAR=$TPA!BLf3N(5w@(n1P9j8K#(pA$tBWGBC3MjYuHtH8L2KIj0_CSFzOF819OZ#ZDwMK#a?rCF#|IbBaE`x z%*+Ba>mE>XU}TP#hRiI@Ks_fkH(P?5z{p|-W|kJ{b&r9$kuj(RdgsXMj0_BoK@DAGF#~f;OZ58Ez{1EJ zJzp9b7@A|pxA3+YJrhgEzHf(!`aZ%)D*K$F*E}W zFQJ-ej*+(vEDa1mE0d7b85tOwqqnaNEDgZ@Ib?MPmPX*74YHV#fuRMcV}UGYU}j0`|NL5)iTOH*U?^4Y-B+!DPFVq{=sfS#TWEG-N{t8$RtVrXE9QO6q@ zm>Yt6Sjg&(42%rX%VI+VLu1hF2C_Os17nQ#u91O}5qdpiXkcs#npH&AYifet_AxRr z!YEG-4NOfzLv5&fEwGe1MkeTO0YgwiHA4+kLjy~5&}ayMGd9G?zeb?0 zDte#9*bpN<8ybTG71h5+2FAvq>2)+aEYZs=Lt_&I^g785tOxq1W+-#umn)X(D8GhQ^qE93ul`bM$(_(AdHf zBkh_Pm}1s%#un)Hf}x24X8Yd6&;+v_H?~Bt7Yt1d%`nO#6C(@EurfD6PX|T@CI;yB zf}x3#C3<_@(8RhF(V*nwXoT_s@+COia+r977Xx3(#h7RDW1lpqJT31}3H$b%2Ql zMq9wp#L@yi4H+4jVDvQ%O)M=j`YEOc7U*@Ok%5UhdYjtN)W8zm4ntEzbM$yKGBB~g zr~^z5Ez#>4a8ZobCowWGu|!WphNebl=wlg%rY1({@nK|Oj!_4Iic^ew!PLYAqntD~ zH$ZQrgKBe(yk%+*Ub2M}Z>E;!=xsA215@zuE}A+^(4aYrn3=H|dYx=!U}}t>?hVb1 z&C%O%hGu5q74^vG85x+GpttJ`&CD?ROonEb2Iyg61S&Sr>i{!LL-er>Lvurnu_Yq| zQ#17X+|V44yk%iviP_FJwZNzY zEDR0MQ=*aWj*i`nlsGBCBos241ZO)=Ua7G_51{xvc%Gr*`9EX+(W%1H}LBhV^2 z)G#mu&wn6`8CqDHV3diV5n;6PH6sHv@G%f5dMyo&K+En>#f&k^Vna(aOY|`wBLg#I zjJm?o7(9@VYMzN1`WT9l0T%ySnwX>a2MsMv!Sg(*=9wC!w@W}Rd5pYoX=;Iyw=7LD z#tscFO)W9%H%oH^^m53^z`_8tezPz{?z5K^C1&P;PJaNO-V~f!l?oZZ)(^_hFHwNZ z1b`MbdFG|%D}X~@0nBw#h_yPfIpVF-x{cO)^b1NHR+{HBGf6 gtO7doP+XE&R00`4H!`p=wlL)7QdM>JcjM&(01oS1PXGV_ literal 0 HcmV?d00001 diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md new file mode 100644 index 000000000000..114ce8a998c5 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md @@ -0,0 +1,14 @@ +# Debugger Internals + +It is the debugger's job to convert the debug info into an in-memory representation. Both the +interpretation of the debug info and the in-memory representation are arbitrary; anything will do +so long as meaningful information can be reconstructed while the program is running. The pipeline +from raw debug info to usable types can be quite complicated. + +Once the information is in a workable format, the debugger front-end then must provide a way to +interpret and display the data, a way for users to interact with it, and an API for extensibility. + +Debuggers are vast systems and cannot be covered completely here. This section will provide a brief +overview of the subsystems directly relevant to the Rust debugging experience. + +Microsoft's debugging engine is closed source, so it will not be covered here. \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md new file mode 100644 index 000000000000..07e3861a500b --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md @@ -0,0 +1,62 @@ +# Debugger Visualizers + +These are typically the last step before the debugger displays the information, but the results may +be piped through a debug adapter such as an IDE's debugger API. + +The term "Visualizer" is a bit of a misnomer. The real goal isn't just to prettify the output, but +to provide an interface for the user to interact with that is as useful as possible. In many cases +this means reconstructing the original type as closely as possible to its Rust representation, but +not always. + +The visualizer interface allows generating "synthetic children" - fields that don't exist in the +debug info, but can be derived from invariants about the language and the type itself. A simple +example is allowing one to interact with the elements of a `Vec` instead of just it's `*mut u8` +heap pointer, length, and capacity. + +## Performance + +Before tackling the visualizers themselves, it's important to note that these are part of a +performance-sensitive system. Please excuse the break in formality, but: if I have to spend +significant time debugging, I'm annoyed. If I have to *wait on my debugger*, I'm pissed. + +Every millisecond spent in these visualizers is a millisecond longer for the user to see output. +This can be especially painful for large stackframes that contain many/large container types. +Debugger GUI's such as VSCode will request the whole stack frame at once, and this can result in +delays of tens of seconds (or even minutes) before being able to interact with any variables in the +frame. + +There is a tendancy to balk at the idea of optimizing Python code, but it really can have a +substantial impact. Remember, there is no compiler to help keep the code fast. Even simple +transformations are not done for you. It can be difficult to find Python performance tips through +all the noise of people suggesting you don't bother optimizing Python, so here are some things to +keep in mind that are relevant to these scripts: + +* Everything allocates, even `int` +* Use tuples when possible. `list` is effectively `Vec>`, whereas tuples are equivalent +to `Box<[Any]>`. They have one less layer of indirection, don't carry extra capacity and can't +grow/shrink which can be advantageous in many cases. An additional benefit is that Python caches and +recycles the underlying allocations of all tuples up to size 20. +* Regexes are slow and should be avoided when simple string manipulation will do +* Strings are immutable, thus many string operations implictly copy the contents. +* When concatenating large lists of strings, `"".join(iterable_of_strings)` is typically the fastest +way to do it. +* f-strings are generally the fastest way to do small, simple string transformations such as +surrounding a string with parentheses. +* The act of calling a function is somewhat slow (even if the function is completely empty). If the +code section is very hot, consider inlining the function manually. +* Local variable access is significantly faster than global and built-in function access +* Member/method access via the `.` operator is also slow, consider reassigning deeply nested values +to local variables to avoid this cost (e.g. `h = a.b.c.d.e.f.g.h`). +* Accessing inherited methods and fields is about 2x slower than base-class methods and fields. +Avoid inheritance whenever possible. +* Use [`__slots__`](https://wiki.python.org/moin/UsingSlots) wherever possible. `__slots__` is a way +to indicate to Python that your class's fields won't change and speeds up field access by a +noticable amount. This does require you to name your fields in advance and initialize them in +`__init__`, but it's a small price to pay for the benefits. +* Match statements/if..elif..else are not optimized in any way. The conditions are checked in order, +1 by 1. If possible, use an alternative such as dictionary dispatch or a table of values +* Compute lazily when possible +* List comprehensions are typically faster than loops, generator comprehensions are a bit slower +than list comprehensions, but use less memory. You can think of comprehensions as equivalent to +Rust's `iter.map()`. List comprehensions effectively call `collect::>` at the end, whereas +generator comprehensions do not. \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md new file mode 100644 index 000000000000..95f543c8e94a --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md @@ -0,0 +1,4 @@ +# (WIP) GDB Internals + +GDB's Rust support lives at `gdb/rust-lang.h` and `gdb/rust-lang.c`. The expression parsing support +can be found in `gdb/rust-exp.h` and `gdb/rust-parse.c` \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md new file mode 100644 index 000000000000..4027ef897f28 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md @@ -0,0 +1,9 @@ +# (WIP) GDB - Python Providers + +Below are links to relevant parts of the GDB documentation + +* [Overview on writing a pretty printer](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Writing-a-Pretty_002dPrinter.html#Writing-a-Pretty_002dPrinter) +* [Pretty Printer API](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Pretty-Printing-API.html#Pretty-Printing-API) (equivalent to LLDB's `SyntheticProvider`) +* [Value API](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Values-From-Inferior.html#Values-From-Inferior) (equivalent to LLDB's `SBValue`) +* [Type API](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Types-In-Python.html#Types-In-Python) (equivalent to LLDB's `SBType`) +* [Type Printing API](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Type-Printing-API.html#Type-Printing-API) (equivalent to LLDB's `SyntheticProvider.get_type_name`) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/intro.md b/src/doc/rustc-dev-guide/src/debuginfo/intro.md new file mode 100644 index 000000000000..0f1e59fa65e2 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/intro.md @@ -0,0 +1,114 @@ +# Debug Info + +Debug info is a collection of information generated by the compiler that allows debuggers to +correctly interpret the state of a program while it is running. That includes things like mapping +instruction addresses to lines of code in the source file, and type layout information so that +bytes in memory can be read and displayed in a meaningful way. + +Debug info can be a slightly overloaded term, covering all the layers between Rust MIR, and the +end-user seeing the output of their debugger onscreen. In brief, the stack from beginning to end is +as follows: + +1. Rustc inspects the MIR and communicates the relevant source, symbol, and type information to LLVM +2. LLVM translates this information into a target-specific debug info format during compilation +3. A debugger reads and interprets the debug info, mapping source-lines and allowing the debugee's +variables in memory to be located and read with the correct layout +4. Built-in debugger formatting and styling is applied to variables +5. User-defined scripts are run, formatting and styling the variables further +6. The debugger frontend displays the variable to the user, possibly through the means of additional +API layers (e.g. VSCode extension by way of the +[Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/)) + + +> NOTE: This subsection of the dev guide is perhaps more detailed than necessary. It aims to collect +> a large amount of scattered information into one place and equip the reader with as firm a grasp of +> the entire debug stack as possible. +> +> If you are only interested in working on the visualizer +> scripts, the information in the [debugger-visualizers](./debugger-visualizers.md) and +> [testing](./testing.md) will suffice. If you need to make changes to Rust's debug node generation, +> please see [rust-codegen](./rust-codegen.md). All other sections are supplementary, but can be +> vital to understanding some of the compromises the visualizers or codegen need to make. It can +> also be valuable to know when a problem might be better solved in LLVM or the debugger itself. + +# DWARF + +The is the primary debug info format for `*-gnu` targets. It is typically bundled in with the +binary, but it [can be generated as a separate file](https://gcc.gnu.org/wiki/DebugFission). The +DWARF standard is available [here](https://dwarfstd.org/). + +> NOTE: To inspect DWARF debug info, [gimli](https://crates.io/crates/gimli) can be used +> programatically. If you prefer a GUI, the author recommends [DWEX](https://github.com/sevaa/dwex) + +# PDB/CodeView + +The primary debug info format for `*-msvc` targets. PDB is a proprietary container format created by +Microsoft that, unfortunately, +[has multiple meanings](https://docs.rs/ms-pdb/0.1.10/ms_pdb/taster/enum.Flavor.html). +We are concerned with ordinary PDB files, as Portable PDB is used mainly for .Net applications. PDB +files are separate from the compiled binary and use the `.pdb` extension. + +PDB files contain CodeView objects, equivalent to DWARF's tags. CodeView, the debugger that +consumed CodeView objects, was originally released in 1985. Its original intent was for C debugging, +and was later extended to support Visual C++. There are still minor alterations to the format to +support modern architectures and languages, but many of these changes are undocumented and/or +sparsely used. + +It is important to keep this context in mind when working with CodeView objects. Due to its origins, +the "feature-set" of these objects is very limited, and focused around the core features of C. It +does not have many of the convenience or features of modern DWARF standards. A fair number of +workarounds exist within the debug info stack to compensate for CodeView's shortcomings. + +Due to its proprietary nature, it is very difficult to find information about PDB and CodeView. Many +of the sources were made at vastly different times and contain incomplete or somewhat contradictory +information. As such this page will aim to collect as many sources as possible. + +* [CodeView 1.0 specification](./CodeView.pdf) +* LLVM + * [CodeView Overview](https://llvm.org/docs/SourceLevelDebugging.html#codeview-debug-info-format) + * [PDB Overview and technical details](https://llvm.org/docs/PDB/index.html) +* Microsoft + * [microsoft-pdb](https://github.com/microsoft/microsoft-pdb) - A C/C++ implementation of a PDB + reader. The implementation does not contain the full PDB or CodeView specification, but does + contain enough information for other PDB consumers to be written. At time of writing (Nov 2025), + this repo has been archived for several years. + * [pdb-rs](https://github.com/microsoft/pdb-rs/) - A Rust-based PDB reader and writer based on + other publicly-available information. Does not guarantee stability or spec compliance. Also + contains `pdbtool`, which can dump PDB files (`cargo install pdbtool`) + * [Debug Interface Access SDK](https://learn.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/getting-started-debug-interface-access-sdk). + While it does not document the PDB format directly, details can be gleaned from the interface + itself. + +# Debuggers + +Rust supports 3 major debuggers: GDB, LLDB, and CDB. Each has its own set of requirements, +limitations, and quirks. This unfortunately creates a large surface area to account for. + +> NOTE: CDB is a proprietary debugger created by Microsoft. The underlying engine also powers +>WinDbg, KD, the Microsoft C/C++ extension for VSCode, and part of the Visual Studio Debugger. In +>these docs, it will be referred to as CDB for consistency + +While GDB and LLDB do offer facilities to natively support Rust's value layout, this isn't +completely necessary. Rust currently outputs debug info very similar to that of C++, allowing +debuggers without Rust support to work with a slightly degraded experience. More detail will be +included in later sections, but here is a quick reference for the capabilities of each debugger: + +| Debugger | Debug Info Format | Native Rust support | Expression Style | Visualizer Scripts | +| --- | --- | --- | --- | --- | +| GDB | DWARF | Full | Rust | Python | +| LLDB | DWARF and PDB | Partial | C/C++ | Python | +| CDB | PDB | None | C/C++ | Natvis | + +> IMPORTANT: CDB can be assumed to run only on Windows. No assumptions can be made about the OS +>running GDB or LLDB. + +## Unsupported + +Below, are several unsupported debuggers that are of particular note due to their potential impact +in the future. + +* [Bugstalker](https://github.com/godzie44/BugStalker) is an x86-64 Linux debugger written in Rust, +specifically to debug Rust programs. While promising, it is still in early development. +* [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) is a Windows-only GUI debugger. It has +a custom debug info format that PDB is translated into. The project also includes a linker that can +generate their new debug info format during the linking phase. \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md new file mode 100644 index 000000000000..301dda9778d5 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md @@ -0,0 +1,205 @@ +# LLDB Internals + +LLDB's debug info processing relies on a set of extensible interfaces largely defined in +[lldb/src/Plugins][lldb_plugins]. These are meant to allow third-party compiler developers to add +language support that is loaded at run-time by LLDB, but at time of writing (Nov 2025) the public +API has not been settled on, so plugins exist either in LLDB itself or in standalone forks of LLDB. + +[lldb_plugins]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins + +Typically, language support will be written as a pipeline of these plugins: `*ASTParser` -> +`TypeSystem` -> `ExpressionParser`/`Language`. + +Here are some existing implementations of LLDB's plugin API: + +* [Apple's fork with support for Swift](https://github.com/swiftlang/llvm-project) +* [CodeLLDB's former fork with support for Rust](https://archive.softwareheritage.org/browse/origin/directory/?branch=refs/heads/codelldb/16.x&origin_url=https://github.com/vadimcn/llvm-project&path=lldb/source/Plugins/TypeSystem/Rust×tamp=2023-09-11T04:55:10Z) +* [A work in progress reimplementation of Rust support](https://github.com/Walnut356/llvm-project/tree/lldbrust/19.x) + +## Rust Support and TypeSystemClang + +As mentioned in the debug info overview, LLDB has partial Rust support. To further clarify, Rust +uses the plugin-pipeline that was built for C/C++ (though it contains some helpers for Rust enum +types), which relies directly on the `clang` compiler's representation of types. This imposes heavy +restrictions on how much we can change when LLDB's output doesn't match what we want. Some +workarounds can help, but at the end of the day Rust's needs are secondary compared to making sure +C and C++ compilation and debugging work correctly. + +LLDB is receptive to adding a `TypeSystemRust`, but it is a massive undertaking. This section serves +to not only document how we currently interact with [`TypeSystemClang`][ts_clang], but also as light +guidance on implementing a `TypeSystemRust` in the future. + +[ts_clang]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/TypeSystem/Clang + +It is worth noting that a `TypeSystem` directly interacting with the target language's compiler is +the intention, but it is not a requirement. One can create all the necessary supporting types within +their plugin implementation. + +> Note: LLDB's documentation, including comments in the source code, is pretty sparse. Trying to +> understand how language support works by reading `TypeSystemClang`'s implementation is somewhat +> difficult due to the added requirement of understanding the `clang` compiler's internals. It is +> recommended to look at the 2 `TypeSystemRust` implementations listed above, as they are written +> "from scratch" without leveraging a compiler's type representation. They are relatively close to +> the minimum necessary to implement language support. + +## DWARF vs PDB + +LLDB is unique in being able to handle both DWARF and PDB debug information. This does come with +some added complexity. To complicate matters further, PDB support is split between `dia`, which +relies on the `msdia140.dll` library distributed with Visual Studio, and `native`, which is written +from scratch using publicly available information about the PDB format. + +> Note: `dia` was the default up to LLDB version 21. `native` is the new default as of +> LLDB 22's release. There are plans to deprecate and completely remove the `dia`-based plugins. As +> such, only `native` parsing will be discussed below. For progress, please see +> [this discourse thread][dia_discourse] and the relevant [tracking issue][dia_tracking]. +> +> `native` can be toggled via the `plugin.symbol-file.pdb.reader` setting added in LLDB 22 or using +> the environment variable `LLDB_USE_NATIVE_PDB_READER=0/1` + +[dia_discourse]: https://discourse.llvm.org/t/rfc-removing-the-dia-pdb-plugin-from-lldb/87827 +[dia_tracking]: https://github.com/llvm/llvm-project/issues/114906 + +## Debug Node Parsing + +The first step is to process the raw debug nodes into something usable. This primarily occurs in +the [`DWARFASTParser`][dwarf_ast] and [`PdbAstBuilder`][pdb_ast] classes. These classes are fed a +deserialized form of the debug info generated from [`SymbolFileDWARF`][sf_dwarf] and +[`SymbolFileNativePDB`][sf_pdb] respectively. The `SymbolFile` implementers make almost no +transformations to the underlying debug info before passing it to the parsers. For both PDB and +DWARF, the debug info is read using LLVM's debug info handlers. + +[dwarf_ast]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/SymbolFile/DWARF +[pdb_ast]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/SymbolFile/NativePDB +[sf_dwarf]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +[sf_pdb]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h + +The parsers translate the nodes into more convenient formats for LLDB's purposes. For `clang`, these +formats are `clang::QualType`, `clang::Decl`, and `clang::DeclContext`, which are the types `clang` +uses internally when compiling C and C++. Again, using the compiler's representation of types is not a +requirement, but the plugin system was built with it as a possibility. + +> Note: The above types will be referred to language-agnostically as `LangType`, `Decl`, and +`DeclContext` when the specific implementation details of `TypeSystemClang` are not relevant. + +`LangType` represents a type. This includes information such as the name of the type, the size and +alignment, its classification (e.g. struct, primitive, pointer), its qualifiers (e.g. +`const`, `volatile`), template arguments, function argument and return types, etc. [Here][rust_type] +is an example of what a `RustType` might look like. + +[rust_type]: https://github.com/Walnut356/llvm-project/blob/13bcfd502452606d69faeea76aec3a06db554af9/lldb/source/Plugins/TypeSystem/Rust/TypeSystemRust.h#L618 + +`Decl` represents any kind of declaration. It could be a type, a variable, a static field of a +struct, the value that a static or const is initialized with, etc. + +`DeclContext` more or less represents a scope. `DeclContext`s typically contain `Decl`s and other +`DeclContexts`, though the relationship isn't that straight forward. For example, a function can be +both a `Decl` (because function signatures are types), **and** a `DeclContext` (because functions +contain variable declarations, nested functions declarations, etc.). + +The translation process can be quite verbose, but is usually straightforward. Much of the work here +is dependant on the exact information needed to fill out `LangType`, `Decl`, and `DeclContext`. + +Once a node is translated, a pointer to it is type-erased (`void*`) and wrapped in `CompilerType`, +`CompilerDecl`, or `CompilerDeclContext`. These wrappers associate the them with the `TypeSystem` +that owns them. Methods on these objects delegates to the `TypeSystem`, which casts the `void*` back +to the appropriate `LangType*`/`Decl*`/`DeclContext*` and operates on the internals. In Rust terms, +the relationship looks something like this: + +```Rust +struct CompilerType { + inner_type: *mut c_void, + type_system: Arc, +} + +impl CompilerType { + pub fn get_byte_size(&self) -> usize { + self.type_system.get_byte_size(self.lang_type) + } + +} + +... + +impl TypeSystem for TypeSystemLang { + pub fn get_byte_size(lang_type: *mut c_void) -> usize { + let lang_type = lang_type as *mut LangType; + + // Operate on the internals of the LangType to + // determine its size + ... + } +} +``` + +## Type Systems + +The [`TypeSystem` interface][ts_interface] has 3 major purposes: + +[ts_interface]: https://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Symbol/TypeSystem.h#L69 + +1. Act as the "sole authority" of a language's types. This allows the type system to be added to +LLDB's "pool" of type systems. When an executable is loaded, the target language is determined, and +the pool is queried to find a `TypeSystem` that claims it can handle the language. One can also use +the `TypeSystem` to retrieve the backing `SymbolFile`, search for types, and synthesize basic types +that might not exist in the debug info (e.g. primitives, arrays-of-`T`, pointers-to-`T`). +2. Manage the lifetimes of the `LangType`, `Decl`, and `DeclContext` objects +3. Customize the "defaults" of how those types appear and how they can be interacted with. + +The first two functions are pretty straightforward so we will focus on the third. + +Many of the functions in the `TypeSystem` interface will look familiar if you have worked with the +visualizer scripts. These functions underpin `SBType` the `SBValue` functions with matching names. +For example, `TypeSystem::GetFormat` returns the default format for the type if no custom formatter +has been applied to it. + +Of particular note are `GetIndexOfChildWithName` and `GetNumChildren`. The `TypeSystem` versions of +these functions operate on a *type*, not a value like the `SBValue` versions. The values returned +from the `TypeSystem` functions dictate what parts of the struct can be interacted with *at all* by +the rest of LLDB. If a field is ommitted, that field effectively no longer exists to LLDB. + +Additionally, since they do not work with objects, there is no underlying memory to inspect or +interpret. Essentially, this means these functions do not have the same purpose as their equivalent +`SyntheticProvider` functions. There is no way to determine how many elements a `Vec` has or what +address those elements live at. It is also not possible to determine the value of the discriminant +of a sum-type. + +Ideally, the `TypeSystem` should expose types as they appear in the debug info with as few +alterations as possible. LLDB's synthetics and frontend can handle making the type pretty. If some +piece of information is useless, the Rust compiler should be altered to not output that debug info +in the first place. + +## Expression Parsing + +The `TypeSystem` is typically written to have a counterpart that can handle expression parsing. It +requires implementing a few extra functions in the `TypeSystem` interface. The bulk of the +expression parsing code should live in [lldb/source/Plugins/ExpressionParser][expr]. + +[expr]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/ExpressionParser + +There isn't too much of note about the parser. It requires implementing a simple interpreter that +can handle (possibly simplified) Rust syntax. They operate on `lldb::ValueObject`s, which are the +objects that underpin `SBValue`. + +## Language + +The [`Language` plugins][lang_plugin] are the C++ equivalent to the Python visualizer scripts. They +operate on `SBValue` objects for the same purpose: creating synthetic children and pretty-printing. +The [CPlusPlusLanguage's implementations][cpp_lang] for the LibCxx types are great resources to +learn how visualizers should be written. + +[lang_plugin]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/Language +[cpp_lang]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/Language/CPlusPlus + +These plugins can access LLDB's private internals (including the underlying `TypeSystem`), so +synthetic/summary providers written as a `Language` plugin can provide higher quality output than +their python equivalent. + +While debug node parsing, type systems, and expression parsing are all closely tied to eachother, +the `Language` plugin is encapsulated more and thus can be written "standalone" for any language +that an existing type system supports. Due to the lower barrier of entry, a `RustLanguage` plugin +may be a good stepping stone towards full language support in LLDB. + +## Visualizers + +WIP \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md new file mode 100644 index 000000000000..c7bcc25029ef --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md @@ -0,0 +1,662 @@ +# LLDB - Python Providers + +> NOTE: LLDB's C++<->Python FFI expects a version of python designated at the time LLDB was +>compiled. LLDB is careful to correspond this version to the minimum in typical Linux and MacOs +>distributions, but on Windows there is no easy solution. If you recieve an import error regarding +>`_lldb` not existing, a mismatched Python version is likely the cause. +> +> LLDB is considering solutions this issue. For updates, see +>[this discussion][minimal_python_install] and [this github issue][issue_167001] + +[minimal_python_install]: https://discourse.llvm.org/t/a-minimal-python-install-for-lldb/88658 +[issue_167001]: https://github.com/llvm/llvm-project/issues/167001 + +> NOTE: Currently (Nov 2025), LLDB's minimum supported Python version is 3.8 with plans to update it to +>3.9 or 3.10 depending on several outside factors. Scripts should ideally be written with only the +>features available in the minimum supported Python version. Please see [this discussion][mrpv] for +>more info. + +[mrpv]: https://discourse.llvm.org/t/rfc-upgrading-llvm-s-minimum-required-python-version/88605/ + +> NOTE: The path to LLDB's python package can be located via the CLI command `lldb -P` + +LLDB provides 3 mechanisms for customizing output: + +* Formats +* Synthetic providers +* Summary providers + +## Formats + +The official documentation is [here](https://lldb.llvm.org/use/variable.html#type-format). In short, +formats allow one to set the default print format for primitive types (e.g. print `25u8` as decimal +`25`, hex `0x19`, or binary `00011001`). + +Rust will almost always need to override `unsigned char`, `signed char`, `char`, `u8`, and `i8`, to +(unsigned) decimal format. + +## Synthetic Providers + +The official documentation is [here](https://lldb.llvm.org/use/variable.html#synthetic-children), +but some information is vague, outdated, or entirely missing. + +Nearly all interaction the user has with variables will be through LLDB's +[`SBValue` objects][sbvalue] which are used both in the Python API, and internally via LLDB's +plugins and CLI. + +[sbvalue]: https://lldb.llvm.org/python_api/lldb.SBValue.html + +A Synthetic Provider is a Python class, written with a specific interface, that is associated with +one or more Rust types. The Synthetic Provider wraps `SBValue` objects and LLDB will call our +class's functions when inspecting the variable. + +The wrapped value is still an `SBValue`, but when calling e.g. `SBValue.GetChildAtIndex`, it will +internally call `SyntheticProvider.get_child_at_index`. You can check if a value has a synthetic +provider via `SBValue.IsSynthetic()`, and which synthetic it is via `SBValue.GetTypeSynthetic()`. If +you want to interact with the underlying non-synthetic value, you can call +`SBValue.GetNonSyntheticValue()`. + + +The expected interface is as follows: + +```python +class SyntheticProvider: + def __init__(self, valobj: SBValue, _lldb_internal): ... + + # optional + def update(self) -> bool: ... + + # optional + def has_children(self) -> bool: ... + + # optional + def num_children(self, max_children: int) -> int: ... + + def get_child_index(self, name: str) -> int: ... + + def get_child_at_index(self, index: int) -> SBValue: ... + + # optional + def get_type_name(self) -> str: ... + + # optional + def get_value(self) -> SBValue: ... +``` + +Below are explanations of the methods, their quirks, and how they should generally be used. If a +method overrides an `SBValue` method, that method will be listed. + +### `__init__` + +This function is called once per object, and must store the `valobj` in the python class so that it +is accessible elsewhere. Very little else should be done here. + +### (optional) `update` + +This function is called prior to LLDB interacting with a variable, but after `__init__`. LLDB tracks +whether `update` has already been called. If it has been, and if it is not possible for the variable +to have changed (e.g. inspecting the same variable a second time without stepping), it will omit the +call to `update`. + +This function has 2 purposes: + +* Store/update any information that may have changed since the last time `update` was run +* Inform LLDB if there were changes to the children such that it should flush the child cache. + +Typical operations include storing the heap pointer, length, capacity, and element type of a `Vec`, +determining an enum variable's variant, or checking which slots of a `HashMap` are occupied. + +The bool returned from this function is somewhat complicated, see: +[`update` caching](#update-caching) below for more info. When in doubt, return `False`/`None`. +Currently (Nov 2025), none of the visualizers return `True`, but that may change as the debug info +test suite is improved. + +#### `update` caching + +LLDB attempts to cache values when possible, including child values. This cache is effectively the +number of child objects, and the addresses of the underlying debugee memory that the child object +represents. By returning `True`, you indicate to LLDB that the number of children and the addresses +of those children have not changed since the last time `update` was run, meaning it can reuse the +cached children. + +**Returning `True` in the wrong circumstances will result in the debugger outputting incorrect +information**. + +Returning `False` indicates that there have been changes, the cache will be flushed, and the +children will be fetched from scratch. It is the safer option if you are unsure. + +The only relationship that matters is parent-to-child. Grandchildren depend on the `update` function +of their direct parent, not that of the grandparent. + +It is important to view the child cache as pointers-to-memory. For example, if a slice's `data_ptr` +value and `length` have not changed, returning `True` is appropriate. Even if the slice is mutable +and elements of it are overwritten (e.g. `slice[0] = 15`), because the child cache consists of +*pointers*, they will reflect the new data at that memory location. + +Conversely, if `data_ptr` has changed, that means it is pointing to a new location in memory, the +child pointers are invalid, and the cache must be flushed. If the `length` has changed, we need to +flush the cache to reflect the new number of children. If `length` has changed but `data_ptr` has +not, it is possible to store the old children in the `SyntheticProvider` itself (e.g. +`list[SBValue]`) and dole those out rather than generating them from scratch, only creating new +children if they do not already exist in the `SyntheticProvider`'s list. + +For further clarification, see [this discussion](https://discourse.llvm.org/t/when-is-it-safe-to-cache-syntheticprovider-update/88608) + +> NOTE: when testing the caching behavior, do not rely on LLDB's heuristic to persist variables when +> stepping. Instead, store the variable in a python object (e.g. `v = lldb.frame.var("var_name")`), +> step forward, and then inspect the stored variable. + +### (optional) `has_children` + +> Overrides `SBValue.MightHaveChildren` + +This is a shortcut used by LLDB to check if the value has children *at all*, without doing +potentially expensive computations to determine how many children there are (e.g. linked list). +Often, this will be a one-liner of `return True`/`return False` or +`return self.valobj.MightHaveChildren()`. + +### (optional) `num_children` + +> Overrides `SBValue.GetNumChildren` + +Returns the total number of children that LLDB should try to access when printing the type. This +number **does not** need to match to total number of synthetic children. + +The `max_children` argument can be returned if calculating the number of children can be expensive +(e.g. linked list). If this is not a consideration, `max_children` can be omitted from the function +signature. + +Additionally, fields can be intentionally "hidden" from LLDB while still being accessible to the +user. For example, one might want a `vec![1, 2, 3]` to display only its elements, but still have the +`len` and `capacity` values accessible on request. By returning `3` from `num_children`, one can +restrict LLDB to only displaying `[1, 2, 3]`, while users can still directly access `v.len` and +`v.capacity`. See: [Example Provider: Vec\](#example-provider-vect) to see an implementation of +this. + +### `get_child_index` + +> Overrides `SBValue.GetIndexOfChildWithName` +> +> Affects `SBValue.GetChildMemberWithName` + +Given a name, returns the index that the child should be accessed at. It is expected that the return +value of this function is passed directly to `get_child_at_index`. As with `num_children`, the +values returned here *can* be arbitrary, so long as they are properly coordinated with +`get_child_at_index`. + +One special value is `$$dereference$$`. Accounting for this pseudo-field will allow LLDB to use the +`SBValue` returned from `get_child_at_index` as the result of a dereference via LLDB's expression +parser (e.g. `*val` and `val->field`) + +### `get_child_at_index` + +> Overrides `SBValue.GetChildAtIndex` + +Given an index, returns a child `SBValue`. Often these are generated via +`SBValue.CreateValueFromAddress`, but less commonly `SBValue.CreateChildAtOffset`, +`SBValue.CreateValueFromExpression`, and `SBValue.CreateValueFromData`. These functions can be a +little finicky, so you may need to fiddle with them to get the output you want. + +In some cases, `SBValue.Clone` is appropriate. It creates a new child that is an exact copy of an +existing child, but with a new name. This is useful for cases like tuples, which have field names of +the style `__0`, `__1`, ... when we would prefer they were named `0`, `1`, ... + +Small alterations can be made to the resulting child before it is returned. This is useful for +`&str`/`String`, where we would prefer if the children were displayed as +`lldb.eFormatBytesWithASCII` rather than just as a decimal value. + +### (optional) `get_type_name` + +> Overrides `SBValue.GetDisplayTypeName` + +Overrides the displayed name of a type. For a synthetic `SBValue` whose type name is overridden, the +original type name can still be retrieved via `SBValue.GetTypeName()` and +`SBValue.GetType().GetName()` + +This can be helpful in shortening the name of common standard library types (e.g. +`std::collections::hash::map::HashMap` -> `HashMap`), or +in normalizing MSVC type names (e.g. `ref$` -> `&str`). + +The string manipulation can be a little tricky, especially on MSVC where we cannot conveniently +access the generic parameters of the type. + +### (optional) `get_value` + +> Overrides `SBValue.GetValue()`, `SBValue.GetValueAsUnsigned()`, `SBValue.GetValueAsSigned()`, +>`SBValue.GetValueAsAddress()`, + +The `SBValue` returned is expected to be a primitive type or pointer, and is treated as the value of +the variable in expressions. + +> IMPORTANT: The `SBValue` returned **must be stored in the `SyntheticProvider`**. There is +>currently (Nov 2025) a bug where if the `SBValue` is acquired within `get_value` and not stored +>anywhere, Python will segfault when LLDB attempts to access the value. + +## Summary Providers + +Summary providers are python functions of the following form: + +```python +def SummaryProvider(valobj: SBValue, _lldb_internal) -> str: ... +``` + +Where the returned string is passed verbatim to the user. If the returned value isn't a string, it +is naively convered to a string (e.g. `return None` prints `"None"`, not an empty string). + +If the `SBValue` passed in is of a type that has a Synthetic Provider, `valobj.IsSynthetic()` will +return `True`, and the synthetic's corresponding functions will be used. If this is undesirable, the +original value can be retrieved via `valobj.GetNonSyntheticValue()`. This can be helpful in cases +like `String`, where individually calling `GetChildAtIndex` in a loop is much slower than accessing +the heap pointer, reading the whole byte array directly from the debugee's memory, and using +Python's `bytes.decode()`. + +### Instance Summaries + +Regular `SummaryProvider` functions take an opaque `SBValue`. That `SBValue` will reflect the type's +`SyntheticProvider` if one exists, but we cannot access the `SyntheticProvider` instance itself, or +any of its internal implementation details. This is deterimental in cases where we need some of +those internal details to help complete the summary. Currently (Nov 2025), in the synthetic we just +run the non-synthetic value through the synthetic provider +(`synth = SyntheticProvider(valobj.GetNonSyntheticValue(), _dict)`), but this is obviously +suboptimal and there are plans to use the method outlined below. + +Instead, we can leverage the Python module's state to allow for instance summaries. Prior art for +this technique exists in the [old CodeLLDB Rust visualizer scripts](https://github.com/vadimcn/codelldb/blob/cf9574977b80e29c6de2c44d12f1071a53a54caf/formatters/rust.py#L110). + +In short: every Synthetic Provider's `__init__` function stores a unique ID and a weak reference to +`self` in a global dictionary. The Synthetic Provider class also implements a `get_summary` +function. The type's `SummaryProvider` is a function that looks up the unique ID in this dictionary, +then calls a `get_summary` on the instance it retrieves. + +```python +import weakref + +SYNTH_BY_ID = weakref.WeakValueDictionary() + +class SyntheticProvider: + valobj: SBValue + + # slots requires opting-in to __weakref__ + __slots__ = ("valobj", "__weakref__") + + def __init__(valobj: SBValue, _dict): + SYNTH_BY_ID[valobj.GetID()] = self + self.valobj = valobj + + def get_summary(self) -> str: + ... + +def InstanceSummaryProvider(valobj: SBValue, _dict) -> str: + # GetNonSyntheticValue should never fail as InstanceSummaryProvider implies an instance of a + # `SyntheticProvider`. No non-synthetic types should ever have this summary assigned to them + # We use GetNonSyntheticValue because the synthetic vaobj has its own unique ID + return SYNTH_BY_ID[valobj.GetNonSyntheticValue().GetID()].get_summary() +``` + +For example, one might use this for the Enum synthetic provider. The summary would like to access +the variant name, but there isn't a convenient way to reflect this via the type name or child-values +of the synthetic. By implementing an instance summary, we can retrieve the variant name via +`self.variant.GetTypeName()` and some string manipulation. + +# Writing Visualizer Scripts + +> IMPORTANT: Unlike GDB and CDB, LLDB can debug executables with either DWARF or PDB debug info. +>Visualizers must be written to account for both formats whenever possible. See: +>[rust-codegen](./rust-codegen.md#dwarf-vs-pdb) for an overview of the differences + +Scripts are injected into LLDB via the CLI command `command script import .py`. Once +injected, classes and functions can be added to the synthetic/summary pool with `type synthetic add` +and `type summary add` respectively. The summaries and synthetics can be associated with a +"category", which is typically named after the language the providers are intended for. The category +we use will be called `Rust`. + +> TIP: all LLDB commands can be prefixed with `help` (e.g. `help type synthetic add`) for a brief +description, list of arguments, and examples. + +Currently (Nov 2025) we use `command source ...`, which executes a series of CLI commands from the +file [`lldb_commands`](https://github.com/rust-lang/rust/blob/main/src/etc/lldb_commands) to add +providers. This file is somewhat unwieldy, and will soon be supplanted by the Python API equivalent +outlined below. + +## `__lldb_init_module` + +This is an optional function of the form: + +```python +def __lldb_init_module(debugger: SBDebugger, _lldb_internal) -> None: ... +``` + +This function is called at the end of `command script import ...`, but before control returns back +to the CLI. It allows the script to initialize its own state. + +Crucially, it is passed a reference to the debugger itself. This allows us to create the `Rust` +category and add providers to it. It can also allow us to conditionally change which providers we +use depending on what version of LLDB the script detects. This is vital for backwards compatibility +once we begin using recognizer functions, as recognizers were added in lldb 19.0. + +## Visualizer Resolution + +The order that visualizers resolve in is listed [here][formatters_101]. In short: + +[formatters_101]: https://lldb.llvm.org/use/variable.html#finding-formatters-101 + +* If there is an exact match (non-regex name, recognizer function, or type already matched to +provider), use that +* If the object is a pointer/reference, try to use the dereferenced type's formatter +* If the object is a typedef, check the underlying type for a formatter +* If none of the above work, iterate through the regex type matchers + +Within each of those steps, **iteration is done backwards** to allow new commands to "override" old +commands. This is important for cases like `Box` vs `Box`, were we want a specialized +synthetic for the former, but a more generalized synthetic for the latter. + +## Minutiae + +LLDB's API is very powerful, but there are some "gotchas" and unintuitive behavior, some of which +will be outlined below. The python implementation can be viewed at the path returned by the CLI +command `lldb -P` in `lldb\__init__.py`. In addition to the +[examples in the lldb repo][synth_examples], there are also [C++ visualizers][plugin_cpp] that can +be used as a reference (e.g. [LibCxxVector, the equivalent to `Vec`][cxx_vector]). While C++'s +visualizers are written in C++ and have access to LLDB's internals, the API and general practices +are very similar. + +[synth_examples]:https://github.com/llvm/llvm-project/tree/main/lldb/examples/synthetic +[plugin_cpp]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/Language/CPlusPlus +[cxx_vector]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp + +### `SBValue` + +* Pointer/reference `SBValue`s will effectively "auto-deref" in some cases, acting as if the +children of the pointed-to-object are its own children. +* The non-function fields are typically [`property()`][property] fields that point directly to the +function anyway (e.g. `SBValue.type = property(GetType, None)`). Accessing through these shorthands +is a bit slower to access than just calling the function directly, so they should be avoided. Some +of the properties return special objects with special properties (e.g. `SBValue.member` returns an +object that acts like `dict[str, SBValue]` to access children). Internally, many of these special +objects just allocate a new class instance and call the function on the `SBValue` anyway, resulting +in additional performance loss (e.g. `SBValue.member` internally just implements `__getitem__` which +is the one-liner `return self.valobj.GetChildMemberWithName(name)`) +* `SBValue.GetID` returns a unique `int` for each value for the duration of the debug session. +Synthetic `SBValue`'s have a different ID than their underlying `SBValue`. The underlying ID can be +retrieved via `SBValue.GetNonSyntheticValue().GetID()`. +* When manually calculating an address, `SBValue.GetValueAsAddress` should be preferred over +`SBValue.GetValueAsUnsigned` due to [target-specific behavior][get_address] +* Getting a string representation of an `SBValue` can be tricky because `GetSummary` requires a +summary provider and `GetValue` requires the type be representable by a primitive. In almost all +cases where neither of those conditions are met, the type is a user defined struct that can be +passed through `StructSummaryProvider`. + +[property]: https://docs.python.org/3/library/functions.html#property +[get_address]: https://lldb.llvm.org/python_api/lldb.SBValue.html#lldb.SBValue.GetValueAsAddress + +### `SBType` + +* "Aggregate type" means a non-primitive struct/class/union +* "Template" is equivalent to "Generic" +* Types can be looked up by their name via `SBTarget.FindFirstType(type_name)`. `SBTarget` can be +acquired via `SBValue.GetTarget` +* `SBType.template_args` returns `None` instead of an empty list if the type has no generics +* It is sometimes necessary to transform a type into the type you want via functions like +`SBType.GetArrayType` and `SBType.GetPointerType`. These functions cannot fail. They ask the +underlying LLDB `TypeSystem` plugin for the type, bypassing the debug info completely. Even if the +type does not exist in the debug info at all, these functions can create the appropriate type. +* `SBType.GetCanonicalType` is effectively `SBType.GetTypedefedType` + `SBType.GetUnqualifiedType`. +Unlike `SBType.GetTypedefedType`, it will always return a valid `SBType` regardless of whether or +not the original `SBType` is a typedef. +* `SBType.GetStaticFieldWithName` was added in LLDB 18. Unfortunately, backwards compatibility isn't +always possible since the static fields are otherwise completely inaccessible. + + +# Example Provider: `Vec` + +## SyntheticProvider + +We start with the typical prelude, using `__slots__` since we have known fields. In addition to the +object itself, we also need to store the type of the elements because `Vec`'s heap pointer is a +`*mut u8`, not a `*mut T`. Rust is a statically typed language, so the type of `T` will never +change. That means we can store it during initialization. The heap pointer, length, and capacity +*can* change though, and thus are default initialized here. + +```python +import lldb + +class VecSyntheticProvider: + valobj: SBValue + data_ptr: SBValue + len: int + cap: int + element_type: SBType + + __slots__ = ( + "valobj", + "data_ptr", + "len", + "cap", + "element_type", + "__weakref__", + ) + + def __init__(valobj: SBValue, _dict) -> None: + self.valobj = valobj + # invalid type is a better default than `None` + self.element_type = SBType() + + # special handling to account for DWARF/PDB differences + if (arg := valobj.GetType().GetTemplateArgumentType(0)): + self.element_type = arg + else: + arg_name = next(get_template_args(valobj.GetTypeName())) + self.element_type = resolve_msvc_template_arg(arg_name, valobj.GetTarget()) +``` + +For the implementation of `get_template_args` and `resolve_msvc_template_arg`, please see: +[`lldb_providers.py`](https://github.com/rust-lang/rust/blob/main/src/etc/lldb_providers.py#L136). + +Next, the update function. We check if the pointer or length have changed. We can ommit checking the +capacity, as the number of children will remain the same unless `len` changes. If changing the +capacity resulted in a reallocation, `data_ptr`'s address would be different. + +If `data_ptr` and `length` haven't changed, we can take advantage of LLDB's caching and return +early. If they have changed, we store the new values and tell LLDB to flush the cache. + +```python +def update(self): + ptr = self.valobj.GetChildMemberWithName("data_ptr") + len = self.valobj.GetChildMemberWithName("length").GetValueAsUnsigned() + + if ( + self.data_ptr.GetValueAsAddress() == ptr.GetValueAsAddress() + and self.len == len + ): + # Our child address offsets and child count are still valid + # so we can reuse cached children + return True + + self.data_ptr = ptr + self.len = len + + return False +``` + +`has_children` and `num_children` are both straightforward: + +```python +def has_children(self) -> bool: + return True + +def num_children(self) -> int: + return self.len +``` + +When accessing elements, we expect values of the format `[0]`, `[1]`, etc. to mimic indexing. +Additionally, we still want the user to be able to quickly access the length and capacity, as they +can be very useful when debugging. We assign these values `u32::MAX - 1` and `u32::MAX - 2` +respectively, as we can almost surely guarantee that they will not overlap with element values. Note +that we can account for both the full and shorthand `capacity` name. + +```python + def get_child_index(self, name: str) -> int: + index = name.lstrip("[").rstrip("]") + if index.isdigit(): + return int(index) + if name == "len": + return lldb.UINT32_MAX - 1 + if name == "cap" or name == "capacity": + return lldb.UINT32_MAX - 2 + + return -1 +``` + +We now have to properly coordinate `get_child_at_index` so that the elements, length, and capacity +are all accessible. + +```python +def get_child_at_index(self, index: int) -> SBValue: + if index == UINT32_MAX - 1: + return self.valobj.GetChildMemberWithName("len") + if index == UINT32_MAX - 2: + return ( + self.valobj.GetChildMemberWithName("buf") + .GetChildMemberWithName("inner") + .GetChildMemberWithName("cap") + .GetChildAtIndex(0) + .Clone("capacity") + ) + addr = self.data_ptr.GetValueAsAddress() + addr += index * self.element_type.GetByteSize() + return self.valobj.CreateValueFromAddress(f"[{index}]", addr, self.element_type) +``` + +For the type's display name, we can strip the path qualifier. User defined types named +`Vec` will end up fully qualified, so there shouldn't be any ambiguity. We can also remove the +allocator generic, as it's very very rarely useful. We use `get_template_args` instead of +`self.element_type.GetName()` for 3 reasons: + +1. If we fail to resolve the element type for any reason, `self.valobj`'s type name can still let +the user know what the real type of the element is +2. Type names are not subject to the limitations of DWARF and PDB nodes, so the template type in +the name will reflect things like `*const`/`*mut` and `&`/`&mut`. +3. We do not currently (Nov 2025) normalize MSVC type names, but once we do, we will need to work with the +string-names of types anyway. It's also much easier to cache a string-to-string conversion compared +to an `SBType`-to-string conversion. + +```python +def get_type_name(self) -> str: + return f"Vec<{next(get_template_args(self.valobj))}>" +``` + +There isn't an appropriate primitive value with which to represent a `Vec`, so we simply ommit +the `get_value` function. + +## SummaryProvider + +The summary provider is very simple thanks to our synthetic provider. The only real hiccup is that +`GetSummary` only returns a value if the object's type has a `SummaryProvider`. If it doesn't, it +will return an empty string which is not ideal. In a full set of visualizer scripts, we can ensure +that every type that doesn't have a `GetSummary()` or a `GetValue()` is a struct, and then delegate +to a generic `StructSummaryProvider`. For this demonstration, I will gloss over that detail. + +```python +def VecSummaryProvider(valobj: SBValue, _lldb_internal) -> str: + children = [] + for i in range(valobj.GetNumChildren()): + child = valobj.GetChildAtIndex(i) + summary = child.GetSummary() + if summary is None: + summary = child.GetValue() + if summary is None: + summary = "{...}" + + children.append(summary) + + return f"vec![{", ".join(children)}]" +``` + +## Enabling the providers + +Assume this synthetic is imported into `lldb_lookup.py` + +With CLI commands: + +```txt +type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust +``` + +With `__lldb_init_module`: + +```python +def __lldb_init_module(debugger: SBDebugger, _dict: LLDBOpaque): + # Ensure the category exists and is enabled + rust_cat = debugger.GetCategory("Rust") + + if not rust_cat.IsValid(): + rust_cat = debugger.CreateCategory("Rust") + + rust_cat.SetEnabled(True) + + # Register Vec providers + vec_regex = r"^(alloc::([a-z_]+::)+)Vec<.+>$" + sb_name = lldb.SBTypeNameSpecifier(vec_regex, is_regex=True) + + sb_synth = lldb.SBTypeSynthetic.CreateWithClassName("lldb_lookup.VecSyntheticProvider") + sb_synth.SetOptions(lldb.eTypeOptionCascade) + + sb_summary = lldb.SBTypeSummary.CreateWithFunctionName("lldb_lookup.VecSummaryProvider") + sb_summary.SetOptions(lldb.eTypeOptionCascade) + + rust_cat.AddTypeSynthetic(sb_name, sb_synth) + rust_cat.AddSummary(sb_name, sb_summary) +``` + +## Output + +Without providers: + +```text +(lldb) v vec_v +(alloc::vec::Vec) vec_v = { + buf = { + inner = { + ptr = { + pointer = (pointer = "\n") + _marker = {} + } + cap = (__0 = 5) + alloc = {} + } + _marker = {} + } + len = 5 +} +(lldb) v vec_v[0] +error: :1:6: subscripted value is not an array or pointer + 1 | vec_v[0] + | ^ +``` + +With providers (`v ` prints the summary and then a list of all children): + +```text +(lldb) v vec_v +(Vec) vec_v = vec![10, 20, 30, 40, 50] { + [0] = 10 + [1] = 20 + [2] = 30 + [3] = 40 + [4] = 50 +} +(lldb) v vec_v[0] +(int) vec_v[0] = 10 +``` + +We can also confirm that the "hidden" length and capacity are still accessible: + +```text +(lldb) v vec_v.len +(unsigned long long) vec_v.len = 5 +(lldb) v vec_v.capacity +(unsigned long long) vec_v.capacity = 5 +(lldb) v vec_v.cap +(unsigned long long) vec_v.cap = 5 +``` \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md new file mode 100644 index 000000000000..cc052b6b965f --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md @@ -0,0 +1,12 @@ +# (WIP) LLVM Codegen + +When Rust calls an LLVM `DIBuilder` function, LLVM translates the given information to a +["debug record"][dbg_record] that is format-agnostic. These records can be inspected in the LLVM-IR. + +[dbg_record]: https://llvm.org/docs/SourceLevelDebugging.html#debug-records + +It is important to note that tags within the debug records are **always stored as DWARF tags**. If +the target calls for PDB debug info, during codegen the debug records will then be passed through +[a module that translates the DWARF tags to their CodeView counterparts][cv]. + +[cv]:https://github.com/llvm/llvm-project/blob/main/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md new file mode 100644 index 000000000000..653e7d5d6555 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md @@ -0,0 +1,3 @@ +# (WIP) CDB - Natvis + +Official documentation for Natvis can be found [here](https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects) and [here](https://code.visualstudio.com/docs/cpp/natvis) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md new file mode 100644 index 000000000000..6d5dfe08cb15 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -0,0 +1,183 @@ +# Rust Codegen + +The first phase in debug info generation requires Rust to inspect the MIR of the program and +communicate it to LLVM. This is primarily done in [`rustc_codegen_llvm/debuginfo`][llvm_di], though +some type-name processing exists in [`rustc_codegen_ssa/debuginfo`][ssa_di]. Rust communicates to +LLVM via the `DIBuilder` API - a thin wrapper around LLVM's internals that exists in +[rustc_llvm][rustc_llvm]. + +[llvm_di]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_llvm/src/debuginfo +[ssa_di]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_ssa/src/debuginfo +[rustc_llvm]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_llvm + +# Type Information + +Type information typically consists of the type name, size, alignment, as well as things like +fields, generic parameters, and storage modifiers if they are relevant. Much of this work happens in +[rustc_codegen_llvm/src/debuginfo/metadata][di_metadata]. + +[di_metadata]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs + +It is important to keep in mind that the goal is not necessarily "represent types exactly how they +appear in Rust", rather it is to represent them in a way that allows debuggers to most accurately +reconstruct the data during debugging. This distinction is vital to understanding the core work that +occurs on this layer; many changes made here will be for the purpose of working around debugger +limitations when no other option will work. + +## Quirks + +Rust's generated DI nodes "pretend" to be C/C++ for both CDB and LLDB's sake. This can result in +some unintuitive and non-idiomatic debug info. + +### Pointers and Reference + +Wide pointers/references/`Box` are treated as a struct with 2 fields: `data_ptr` and `length`. + +All non-wide pointers, references, and `Box` pointers are output as pointer nodes, and no +distinction is made between `mut` and non-`mut`. Several attempts have been made to rectify this, +but unfortunately there is not a straightforward solution. Using the `reference` DI nodes of the +respective formats has pitfalls. There is a semantic difference between C++ references and Rust +references that is unreconcilable. + +>From [cppreference](https://en.cppreference.com/w/cpp/language/reference.html): +> +>References are not objects; **they do not necessarily occupy storage**, although the compiler may +>allocate storage if it is necessary to implement the desired semantics (e.g. a non-static data +>member of reference type usually increases the size of the class by the amount necessary to store +>a memory address). +> +>Because references are not objects, **there are no arrays of references, no pointers to references, and no references to references** + +The current proposed solution is to simply [typedef the pointer nodes][issue_144394]. + +[issue_144394]: https://github.com/rust-lang/rust/pull/144394 + +Using the `const` qualifier to denote non-`mut` poses potential issues due to LLDB's internal +optimizations. In short, LLDB attempts to cache the child-values of variables (e.g. struct fields, +array elements) when stepping through code. A heuristic is used to determine which values are safely +cache-able, and `const` is part of that heuristic. Research has not been done into how this would +interact with things like Rust's interrior mutability constructs. + +### DWARF vs PDB + +While most of the type information is fairly straight forward, one notable issue is the debug info +format of the target. Each format has different semantics and limitations, as such they require +slightly different debug info in some cases. This is gated by calls to +[`cpp_like_debuginfo`][cpp_like]. + +[cpp_like]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs#L813 + +### Naming + +Rust attempts to communicate type names as accurately as possible, but debuggers and debug info +formats do not always respect that. + +Due to limitations in MSVC's expression parser, the following name transformations are made for PDB +debug info: + +| Rust name | MSVC name | +| --- | --- | +| `&str`/`&mut str` | `ref$`/`ref_mut$` | +| `&[T]`/`&mut [T]` | `ref$ >`/`ref_mut$ >`* | +| `[T; N]` | `array$` | +| `RustEnum` | `enum2$` | +| `(T1, T2)` | `tuple$`| +| `*const T` | `ptr_const$` | +| `*mut T` | `ptr_mut$` | +| `usize` | `size_t`** | +| `isize` | `ptrdiff_t`** | +| `uN` | `unsigned __intN`** | +| `iN` | `__intN`** | +| `f32` | `float`** | +| `f64` | `double`** | +| `f128` | `fp128`** | + +> \* MSVC's expression parser will treat `>>` as a right shift. It is necessary to separate +>consecutive `>`'s with a space (`> >`) in type names. +> +> ** While these type names are generated as part of the debug info node (which is then wrapped in +>a typedef node with the Rust name), once the LLVM-IR node is converted to a CodeView node, the type +>name information is lost. This is because CodeView has special shorthand nodes for primitive types, +>and those shorthand nodes to not have a "name" field. + +### Generics + +Rust outputs generic *type* information (`T` in `ArrayVec`), but not generic *value* +information (`N` in `ArrayVec`). + +CodeView does not have a leaf node for generics/C++ templates, so all generic information is lost +when generating PDB debug info. There are workarounds that allow the debugger to retrieve the +generic arguments via the type name, but it is fragile solution at best. Efforts are being made to +contact Microsoft to correct this deficiency, and/or to use one of the unused CodeView node types as +a suitable equivalent. + +### Type aliases + +Rust outputs typedef nodes in several cases to help account for debugger limitiations, but it does +not currently output nodes for [type aliases in the source code][type_aliases]. + +[type_aliases]: https://doc.rust-lang.org/reference/items/type-aliases.html + +### Enums + +Enum DI nodes are generated in [rustc_codegen_llvm/src/debuginfo/metadata/enums][di_metadata_enums] + +[di_metadata_enums]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums + +#### DWARF + +DWARF has a dedicated node for discriminated unions: `DW_TAG_variant`. It is a container that +references `DW_TAG_variant_part` nodes that may or may not contain a discriminant value. The +hierarchy looks as follows: + +```txt +DW_TAG_structure_type (top-level type for the coroutine) + DW_TAG_variant_part (variant part) + DW_AT_discr (reference to discriminant DW_TAG_member) + DW_TAG_member (discriminant member) + DW_TAG_variant (variant 1) + DW_TAG_variant (variant 2) + DW_TAG_variant (variant 3) + DW_TAG_structure_type (type of variant 1) + DW_TAG_structure_type (type of variant 2) + DW_TAG_structure_type (type of variant 3) +``` + +#### PDB +PDB does not have a dedicated node, so it generates the C equivalent of a discriminated union: + +```c +union enum2$ { + enum VariantNames { + First, + Second + }; + struct Variant0 { + struct First { + // fields + }; + static const enum2$::VariantNames NAME; + static const unsigned long DISCR_EXACT; + enum2$::Variant0::First value; + }; + struct Variant1 { + struct Second { + // fields + }; + static enum2$::VariantNames NAME; + static unsigned long DISCR_EXACT; + enum2$::Variant1::Second value; + }; + enum2$::Variant0 variant0; + enum2$::Variant1 variant1; + unsigned long tag; +} +``` + +An important note is that due to limitations in LLDB, the `DISCR_*` value generated is always a +`u64` even if the value is not `#[repr(u64)]`. This is largely a non-issue for LLDB because the +`DISCR_*` value and the `tag` are read into `uint64_t` values regardless of their type. + +# Source Information + +TODO \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/testing.md b/src/doc/rustc-dev-guide/src/debuginfo/testing.md new file mode 100644 index 000000000000..f58050875e1a --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/testing.md @@ -0,0 +1,8 @@ +# (WIP) Testing + +The debug info test suite is undergoing a substantial rewrite. This section will be filled out as +the rewrite makes progress. + +Please see [this tracking issue][148483] for more information. + +[148483]: https://github.com/rust-lang/rust/issues/148483 \ No newline at end of file From d707ec1e03b2424507fed49f308b97ac59ba0e19 Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Tue, 18 Nov 2025 14:05:03 -0500 Subject: [PATCH 0093/3801] Allow multiline suggestions in `map-unwrap-or` --- clippy_lints/src/methods/map_unwrap_or.rs | 12 +++------- tests/ui/map_unwrap_or.stderr | 29 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs index 62bdc4a3e411..8eb26fb50747 100644 --- a/clippy_lints/src/methods/map_unwrap_or.rs +++ b/clippy_lints/src/methods/map_unwrap_or.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeDef; use clippy_utils::source::snippet; @@ -51,11 +51,8 @@ pub(super) fn check<'tcx>( // get snippets for args to map() and unwrap_or_else() let map_snippet = snippet(cx, map_arg.span, ".."); let unwrap_snippet = snippet(cx, unwrap_arg.span, ".."); - // lint, with note if neither arg is > 1 line and both map() and - // unwrap_or_else() have the same span - let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1; - let same_span = map_arg.span.eq_ctxt(unwrap_arg.span); - if same_span && !multiline { + // lint, with note if both map() and unwrap_or_else() have the same span + if map_arg.span.eq_ctxt(unwrap_arg.span) { let var_snippet = snippet(cx, recv.span, ".."); span_lint_and_sugg( cx, @@ -67,9 +64,6 @@ pub(super) fn check<'tcx>( Applicability::MachineApplicable, ); return true; - } else if same_span && multiline { - span_lint(cx, MAP_UNWRAP_OR, expr.span, msg); - return true; } } diff --git a/tests/ui/map_unwrap_or.stderr b/tests/ui/map_unwrap_or.stderr index 0b6c9b7fcf19..99fcf3d77a3b 100644 --- a/tests/ui/map_unwrap_or.stderr +++ b/tests/ui/map_unwrap_or.stderr @@ -123,6 +123,14 @@ LL | | x + 1 LL | | } LL | | ).unwrap_or_else(|| 0); | |__________________________^ + | +help: try + | +LL ~ let _ = opt.map_or_else(|| 0, |x| { +LL + +LL + x + 1 +LL ~ }); + | error: called `map().unwrap_or_else()` on an `Option` value --> tests/ui/map_unwrap_or.rs:63:13 @@ -134,6 +142,12 @@ LL | | .unwrap_or_else(|| LL | | 0 LL | | ); | |_________^ + | +help: try + | +LL ~ let _ = opt.map_or_else(|| +LL ~ 0, |x| x + 1); + | error: called `map().unwrap_or(false)` on an `Option` value --> tests/ui/map_unwrap_or.rs:70:13 @@ -157,6 +171,14 @@ LL | | x + 1 LL | | } LL | | ).unwrap_or_else(|_e| 0); | |____________________________^ + | +help: try + | +LL ~ let _ = res.map_or_else(|_e| 0, |x| { +LL + +LL + x + 1 +LL ~ }); + | error: called `map().unwrap_or_else()` on a `Result` value --> tests/ui/map_unwrap_or.rs:86:13 @@ -168,6 +190,13 @@ LL | | .unwrap_or_else(|_e| { LL | | 0 LL | | }); | |__________^ + | +help: try + | +LL ~ let _ = res.map_or_else(|_e| { +LL + 0 +LL ~ }, |x| x + 1); + | error: called `map().unwrap_or_else()` on a `Result` value --> tests/ui/map_unwrap_or.rs:111:13 From 0087253015d1191b97b5e312c2409e008db87ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 18 Nov 2025 14:31:06 +0100 Subject: [PATCH 0094/3801] early return on duplicate span lowerings --- compiler/rustc_ast_lowering/src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 9cb17ea67a37..4172d079abac 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -220,6 +220,13 @@ struct SpanLowerer { impl SpanLowerer { fn lower(&self, span: Span) -> Span { if self.is_incremental { + // early return: span lowering takes some time since it accesses the query dependency graph + // to make sure we rerun the right code paths when spans change. When we've already lowered a span, + // or don't have to, bail out ASAP. + if span.is_dummy() || span.parent().is_some_and(|i| i == self.def_id) { + return span; + } + span.with_parent(Some(self.def_id)) } else { // Do not make spans relative when not using incremental compilation. From 98bf9c48574c9863f236939157c7006013175bb2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 19 Nov 2025 14:49:43 +0000 Subject: [PATCH 0095/3801] Rustup to rustc 1.93.0-nightly (3d461af2a 2025-11-18) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 3aeb07e469a3..5eba4411d78b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-11-15" +channel = "nightly-2025-11-19" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 8ad6e38384241d3766b7a09dc898be00dff6d051 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 19 Nov 2025 15:02:42 +0000 Subject: [PATCH 0096/3801] Remove no longer necessary portable-simd patch --- ...-simd-Disable-broken-reduce_sum-test.patch | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch diff --git a/patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch b/patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch deleted file mode 100644 index b1fd6224632b..000000000000 --- a/patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5489384bc265e9e6fc2efaa63d93a4d51ebec2f5 Mon Sep 17 00:00:00 2001 -From: bjorn3 <17426603+bjorn3@users.noreply.github.com> -Date: Thu, 22 Aug 2024 19:22:58 +0000 -Subject: [PATCH] Disable broken reduce_sum test - -It was broken by an upstream change to the .sum() implementation on -float iterators. ---- - crates/core_simd/tests/ops_macros.rs | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs -index aa565a1..5e6ac41 100644 ---- a/crates/core_simd/tests/ops_macros.rs -+++ b/crates/core_simd/tests/ops_macros.rs -@@ -646,6 +646,7 @@ macro_rules! impl_float_tests { - } - - fn reduce_sum() { -+ return; - test_helpers::test_1(&|x| { - test_helpers::prop_assert_biteq! ( - Vector::::from_array(x).reduce_sum(), --- -2.34.1 - From 0670b60de378951a518fbd67dd24849629534585 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 19 Nov 2025 15:16:18 +0000 Subject: [PATCH 0097/3801] Use the rust-std manifest file in build_llvm_sysroot_for_triple This is far more accurate than filtering based on filename and as such allows building the sysroot a bit quicker. In addition the code is a bit simpler. --- build_system/build_sysroot.rs | 37 ++++++++++------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 804d50e25d0d..b3bf7f725db7 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -161,35 +161,18 @@ fn build_sysroot_for_triple( fn build_llvm_sysroot_for_triple(compiler: Compiler) -> SysrootTarget { let default_sysroot = crate::rustc_info::get_default_sysroot(&compiler.rustc); - let mut target_libs = SysrootTarget { triple: compiler.triple, libs: vec![] }; + let std_manifest_path = default_sysroot + .join("lib") + .join("rustlib") + .join(format!("manifest-rust-std-{}", compiler.triple)); - for entry in fs::read_dir( - default_sysroot.join("lib").join("rustlib").join(&target_libs.triple).join("lib"), - ) - .unwrap() - { - let entry = entry.unwrap(); - if entry.file_type().unwrap().is_dir() { - continue; - } - let file = entry.path(); - let file_name_str = file.file_name().unwrap().to_str().unwrap(); - if (file_name_str.contains("rustc_") - && !file_name_str.contains("rustc_std_workspace_") - && !file_name_str.contains("rustc_demangle") - && !file_name_str.contains("rustc_literal_escaper")) - || file_name_str.contains("chalk") - || file_name_str.contains("tracing") - || file_name_str.contains("regex") - { - // These are large crates that are part of the rustc-dev component and are not - // necessary to run regular programs. - continue; - } - target_libs.libs.push(file); - } + let libs = fs::read_to_string(std_manifest_path) + .unwrap() + .lines() + .map(|entry| default_sysroot.join(entry.strip_prefix("file:").unwrap())) + .collect(); - target_libs + SysrootTarget { triple: compiler.triple, libs } } fn build_clif_sysroot_for_triple( From 055cd2717fe298a567c130204743cc0cc06a08e0 Mon Sep 17 00:00:00 2001 From: Voxell Paladynee Date: Wed, 19 Nov 2025 21:17:40 +0100 Subject: [PATCH 0098/3801] ptr_cast_slice: add new methods to raw pointers --- library/core/src/ptr/const_ptr.rs | 37 +++++++++++++++++++++++++ library/core/src/ptr/mut_ptr.rs | 45 +++++++++++++++++++++++++++++++ library/core/src/ptr/non_null.rs | 29 ++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 84a6982d5680..e4d2f7436f13 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1386,6 +1386,43 @@ impl *const T { pub const fn cast_uninit(self) -> *const MaybeUninit { self as _ } + + /// Forms a raw slice from a pointer and a length. + /// + /// The `len` argument is the number of **elements**, not the number of bytes. + /// + /// This function is safe, but actually using the return value is unsafe. + /// See the documentation of [`slice::from_raw_parts`] for slice safety requirements. + /// + /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts + /// + /// # Examples + /// + /// ```rust + /// #![feature(ptr_cast_slice)] + /// // create a slice pointer when starting out with a pointer to the first element + /// let x = [5, 6, 7]; + /// let raw_pointer = x.as_ptr(); + /// let slice = raw_pointer.cast_slice(3); + /// assert_eq!(unsafe { &*slice }[2], 7); + /// ``` + /// + /// You must ensure that the pointer is valid and not null before dereferencing + /// the raw slice. A slice reference must never have a null pointer, even if it's empty. + /// + /// ```rust,should_panic + /// #![feature(ptr_cast_slice)] + /// use std::ptr; + /// let danger: *const [u8] = ptr::null::().cast_slice(0); + /// unsafe { + /// danger.as_ref().expect("references must not be null"); + /// } + /// ``` + #[inline] + #[unstable(feature = "ptr_cast_slice", issue = "149103")] + pub const fn cast_slice(self, len: usize) -> *const [T] { + slice_from_raw_parts(self, len) + } } impl *const MaybeUninit { /// Casts from a maybe-uninitialized type to its initialized version. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 85d54b4d3b9b..edcd0cd2d932 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1655,6 +1655,51 @@ impl *mut T { pub const fn cast_uninit(self) -> *mut MaybeUninit { self as _ } + + /// Forms a raw mutable slice from a pointer and a length. + /// + /// The `len` argument is the number of **elements**, not the number of bytes. + /// + /// Performs the same functionality as [`cast_slice`] on a `*const T`, except that a + /// raw mutable slice is returned, as opposed to a raw immutable slice. + /// + /// This function is safe, but actually using the return value is unsafe. + /// See the documentation of [`slice::from_raw_parts_mut`] for slice safety requirements. + /// + /// [`slice::from_raw_parts_mut`]: crate::slice::from_raw_parts_mut + /// [`cast_slice`]: pointer::cast_slice + /// + /// # Examples + /// + /// ```rust + /// #![feature(ptr_cast_slice)] + /// + /// let x = &mut [5, 6, 7]; + /// let slice = x.as_mut_ptr().cast_slice(3); + /// + /// unsafe { + /// (*slice)[2] = 99; // assign a value at an index in the slice + /// }; + /// + /// assert_eq!(unsafe { &*slice }[2], 99); + /// ``` + /// + /// You must ensure that the pointer is valid and not null before dereferencing + /// the raw slice. A slice reference must never have a null pointer, even if it's empty. + /// + /// ```rust,should_panic + /// #![feature(ptr_cast_slice)] + /// use std::ptr; + /// let danger: *mut [u8] = ptr::null_mut::().cast_slice(0); + /// unsafe { + /// danger.as_mut().expect("references must not be null"); + /// } + /// ``` + #[inline] + #[unstable(feature = "ptr_cast_slice", issue = "149103")] + pub const fn cast_slice(self, len: usize) -> *mut [T] { + slice_from_raw_parts_mut(self, len) + } } impl *mut MaybeUninit { /// Casts from a maybe-uninitialized type to its initialized version. diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index aa3af2f18528..2cefc41017f4 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1377,6 +1377,35 @@ impl NonNull { pub const fn cast_uninit(self) -> NonNull> { self.cast() } + + /// Creates a non-null raw slice from a thin pointer and a length. + /// + /// The `len` argument is the number of **elements**, not the number of bytes. + /// + /// This function is safe, but dereferencing the return value is unsafe. + /// See the documentation of [`slice::from_raw_parts`] for slice safety requirements. + /// + /// # Examples + /// + /// ```rust + /// #![feature(ptr_cast_slice)] + /// use std::ptr::NonNull; + /// + /// // create a slice pointer when starting out with a pointer to the first element + /// let mut x = [5, 6, 7]; + /// let nonnull_pointer = NonNull::new(x.as_mut_ptr()).unwrap(); + /// let slice = nonnull_pointer.cast_slice(3); + /// assert_eq!(unsafe { slice.as_ref()[2] }, 7); + /// ``` + /// + /// (Note that this example artificially demonstrates a use of this method, + /// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.) + #[inline] + #[must_use] + #[unstable(feature = "ptr_cast_slice", issue = "149103")] + pub const fn cast_slice(self, len: usize) -> NonNull<[T]> { + NonNull::slice_from_raw_parts(self, len) + } } impl NonNull> { /// Casts from a maybe-uninitialized type to its initialized version. From 53f8a7bd0b9be3bddeaed2fef4994805fc4d5da5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 20 Nov 2025 12:01:48 +0100 Subject: [PATCH 0099/3801] Make it clearer what exactly is being benchmarked --- build_system/bench.rs | 42 +++++++++++++++++++++-------------- build_system/build_backend.rs | 5 +++++ build_system/build_sysroot.rs | 4 ++++ build_system/main.rs | 7 +----- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/build_system/bench.rs b/build_system/bench.rs index 192cb499536f..80c7826d4e73 100644 --- a/build_system/bench.rs +++ b/build_system/bench.rs @@ -39,7 +39,26 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { let rustc_clif = &compiler.rustc; let rustflags = &compiler.rustflags.join("\x1f"); let manifest_path = SIMPLE_RAYTRACER_REPO.source_dir().to_path(dirs).join("Cargo.toml"); - let target_dir = dirs.build_dir.join("simple_raytracer"); + let target_dir = dirs.build_dir.join("simple-raytracer_target"); + + let raytracer_cg_llvm = dirs + .build_dir + .join(get_file_name(&compiler.rustc, "raytracer_cg_llvm", "bin")) + .to_str() + .unwrap() + .to_owned(); + let raytracer_cg_clif = dirs + .build_dir + .join(get_file_name(&compiler.rustc, "raytracer_cg_clif", "bin")) + .to_str() + .unwrap() + .to_owned(); + let raytracer_cg_clif_opt = dirs + .build_dir + .join(get_file_name(&compiler.rustc, "raytracer_cg_clif_opt", "bin")) + .to_str() + .unwrap() + .to_owned(); let clean_cmd = format!( "RUSTC=rustc cargo clean --manifest-path {manifest_path} --target-dir {target_dir}", @@ -47,19 +66,19 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { target_dir = target_dir.display(), ); let llvm_build_cmd = format!( - "RUSTC=rustc cargo build --manifest-path {manifest_path} --target-dir {target_dir} && (rm build/raytracer_cg_llvm || true) && ln build/simple_raytracer/debug/main build/raytracer_cg_llvm", + "RUSTC=rustc cargo build --manifest-path {manifest_path} --target-dir {target_dir} && (rm {raytracer_cg_llvm} || true) && ln {target_dir}/debug/main {raytracer_cg_llvm}", manifest_path = manifest_path.display(), target_dir = target_dir.display(), ); let clif_build_cmd = format!( - "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} && (rm build/raytracer_cg_clif || true) && ln build/simple_raytracer/debug/main build/raytracer_cg_clif", + "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} && (rm {raytracer_cg_clif} || true) && ln {target_dir}/debug/main {raytracer_cg_clif}", cargo_clif = cargo_clif.display(), rustc_clif = rustc_clif.display(), manifest_path = manifest_path.display(), target_dir = target_dir.display(), ); let clif_build_opt_cmd = format!( - "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} --release && (rm build/raytracer_cg_clif_opt || true) && ln build/simple_raytracer/release/main build/raytracer_cg_clif_opt", + "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" CARGO_BUILD_INCREMENTAL=true {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} --release && (rm {raytracer_cg_clif_opt} || true) && ln {target_dir}/release/main {raytracer_cg_clif_opt}", cargo_clif = cargo_clif.display(), rustc_clif = rustc_clif.display(), manifest_path = manifest_path.display(), @@ -92,24 +111,13 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { let bench_run_markdown = dirs.build_dir.join("bench_run.md"); - let raytracer_cg_llvm = - Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_llvm", "bin")); - let raytracer_cg_clif = - Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_clif", "bin")); - let raytracer_cg_clif_opt = - Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_clif_opt", "bin")); - let mut bench_run = hyperfine_command( + let bench_run = hyperfine_command( 0, bench_runs, None, - &[ - ("", raytracer_cg_llvm.to_str().unwrap()), - ("", raytracer_cg_clif.to_str().unwrap()), - ("", raytracer_cg_clif_opt.to_str().unwrap()), - ], + &[("", &raytracer_cg_llvm), ("", &raytracer_cg_clif), ("", &raytracer_cg_clif_opt)], &bench_run_markdown, ); - bench_run.current_dir(&dirs.build_dir); spawn_and_wait(bench_run); if let Some(gha_step_summary) = gha_step_summary.as_mut() { diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs index ad6743a6d659..c0a8cc95614f 100644 --- a/build_system/build_backend.rs +++ b/build_system/build_backend.rs @@ -22,6 +22,11 @@ pub(crate) fn build_backend( rustflags.push("-Zallow-features=rustc_private,f16,f128".to_owned()); rustflags_to_cmd_env(&mut cmd, "RUSTFLAGS", &rustflags); + // Use incr comp despite release mode unless incremental builds are explicitly disabled + if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() { + cmd.env("CARGO_BUILD_INCREMENTAL", "true"); + } + if env::var("CG_CLIF_EXPENSIVE_CHECKS").is_ok() { // Enabling debug assertions implicitly enables the clif ir verifier cmd.env("CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS", "true"); diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index b3bf7f725db7..e7363e37a45d 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -234,6 +234,10 @@ fn build_clif_sysroot_for_triple( if compiler.triple.contains("apple") { build_cmd.env("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO", "packed"); } + // Use incr comp despite release mode unless incremental builds are explicitly disabled + if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() { + build_cmd.env("CARGO_BUILD_INCREMENTAL", "true"); + } spawn_and_wait(build_cmd); for entry in fs::read_dir(build_dir.join("deps")).unwrap() { diff --git a/build_system/main.rs b/build_system/main.rs index fc0093128300..6251687babc6 100644 --- a/build_system/main.rs +++ b/build_system/main.rs @@ -59,11 +59,6 @@ fn main() { } env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1"); - // Force incr comp even in release mode unless in CI or incremental builds are explicitly disabled - if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() { - env::set_var("CARGO_BUILD_INCREMENTAL", "true"); - } - let mut args = env::args().skip(1); let command = match args.next().as_deref() { Some("prepare") => Command::Prepare, @@ -79,7 +74,7 @@ fn main() { } }; - let mut out_dir = PathBuf::from("."); + let mut out_dir = std::env::current_dir().unwrap(); let mut download_dir = None; let mut sysroot_kind = SysrootKind::Clif; let mut use_unstable_features = true; From 06962948eb7bf5abbfce4169215c1b5602e8cea9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 20 Nov 2025 11:20:25 +0000 Subject: [PATCH 0100/3801] Update to Cranelift 0.126 --- Cargo.lock | 109 +++++++++++++++++++++++++++----------------------- Cargo.toml | 24 +++++------ src/common.rs | 2 + 3 files changed, 73 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09b6c6b87c30..dc27d9c6b542 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,15 +10,15 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "bitflags" @@ -43,42 +43,42 @@ checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cranelift-assembler-x64" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f502c60b6af2025c312b37788c089943ef03156a2910da1aa046bb39eb8f61c7" +checksum = "bf7631e609c97f063f9777aae405e8492abf9bf92336d7aa3f875403dd4ffd7d" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b7e21a74bcf08443a4ef800a4a257063e5c51ee4d7a3bd58da5262d10340830" +checksum = "9c030edccdc4a5bbf28fbfe7701b5cd1f9854b4445184dd34af2a7e8f8db6f45" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f337d268865c292ad5df0669a9bbf6223ca41460292a20ad5b0a57b8e9f27f93" +checksum = "bb544c1242d0ca98baf01873ebba96c79d5df155d5108d9bb699aefc741f5e6d" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0e60319a8242c8d1c7b5a2444d140c416f903f75e0d84da3256fceb822bab85" +checksum = "f0325aecbafec053d3d3f082edfdca7937e2945e7f09c5ff9672e05198312282" [[package]] name = "cranelift-codegen" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78dee669e447a1c68760bf7acee33835e99d564f0137b067f74d4718dfc9970d" +checksum = "abb3236fd319ae897ba00c8a25105081de5c1348576def0e96c062ad259f87a7" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601f629d172b7230f41dd0e78ee797efaf7ec1a5e113c8f395f4027dff6a92ca" +checksum = "7b8791c911a361c539130ace34fb726b16aca4216470ec75d75264b1495c8a3a" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -114,33 +114,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15755c2660902c7d59d96f6551a66ef629650dc3fd405f9dad841e8c58c1a4a2" +checksum = "12ead718c2a10990870c19b2497b5a04b8aae6024485e33da25b5d02e35819e0" [[package]] name = "cranelift-control" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727bfca18705101a294ab9077ad214a8b762ea2bc9844389d0db233d7c61ec3b" +checksum = "c0a57fc972b5651047efddccb99440d103d9d8c13393ccebde15ddd5b6a1181b" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15564c6f0c72750ca4374f40b044857cbc8087571e46d4c7ccdbdcc29b1dec8b" +checksum = "5aae980b4a1678b601eab2f52e372ed0b3c9565a31c17f380008cb97b3a699c5" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c681f2731f1cf68eed9f3b6811571823a5ac498f59c52b73736b68599defb3" +checksum = "a78877016b607982ca1708c0dd4ce23bde04581a39854c9b43a1dca43625b54c" dependencies = [ "cranelift-codegen", "log", @@ -150,15 +150,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40cedc02f08307da019a3e06d3f20f772f829ff813aec975accb012f8930b688" +checksum = "5dc46a68b46d4f53f9f2f02ab8d3a34b00f03a21c124a7a965b8cbf5fdb6773b" [[package]] name = "cranelift-jit" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2864461448c72d15ae3311ea63df9c7e35f22f04683785f6715a0cf17e6577d" +checksum = "7df920009af919ad9df52eb7b47b1895145822e0c29da9b715a876fc8ecc6d82" dependencies = [ "anyhow", "cranelift-codegen", @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b31d249bbbccc4c1ae54701087d4d49d05951897691eef44f4a60e70252743b" +checksum = "ddcf313629071ce74de8e59f02092f5453d1a01047607fc4ad36886b8bd1486c" dependencies = [ "anyhow", "cranelift-codegen", @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db03ab51c60710eb83d0217725b77db4062aca83b35359f5e6aa99ed1c275977" +checksum = "03faa07ec8cf373250a8252eb773d098ff88259fa1c19ee1ecde8012839f4097" dependencies = [ "cranelift-codegen", "libc", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7131e0eb45ee10b0bd6082d0c0114c2e9a670b034d46774b39d0fc5c0ed7cedf" +checksum = "7cca62c14f3c2e4f438192562bbf82d1a98a59543cc66ba04fb658ba99f515a6" dependencies = [ "anyhow", "cranelift-codegen", @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7a06c330b7994a891ad5b622ebc9aefcd17beae832dd25f577cf60c13426bf" +checksum = "0484cb32c527a742e1bba09ef174acac0afb1dcf623ef1adda42849200edcd2e" [[package]] name = "crc32fast" @@ -246,9 +246,9 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "gimli" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" dependencies = [ "fallible-iterator", "indexmap", @@ -282,9 +282,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libloading" @@ -304,9 +304,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "mach2" @@ -405,18 +405,27 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +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.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -460,9 +469,9 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "38.0.1" +version = "39.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d0a76f1a6e887cc1b551b02dfd6e2ce5f6738e8cacd9ad7284f6ac1aac4698f" +checksum = "3f67986f5c499274ae5b2ba5b173bba0b95d1381f5ca70d8eec657f2392117d8" dependencies = [ "anyhow", "cfg-if", @@ -472,9 +481,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-math" -version = "38.0.1" +version = "39.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b900df4252ad86547e7f2b2c00201b006db4e864893bedfb3aca32b23d81868a" +checksum = "a681733e9b5d5d8804ee6cacd59f92c0d87ba2274f42ee1d4e5a943828d0075d" dependencies = [ "libm", ] diff --git a/Cargo.toml b/Cargo.toml index f2001123e579..02d0d2ab3c58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,12 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.125.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.125.0" } -cranelift-module = { version = "0.125.0" } -cranelift-native = { version = "0.125.0" } -cranelift-jit = { version = "0.125.0", optional = true } -cranelift-object = { version = "0.125.0" } +cranelift-codegen = { version = "0.126.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.126.0" } +cranelift-module = { version = "0.126.0" } +cranelift-native = { version = "0.126.0" } +cranelift-jit = { version = "0.126.0", optional = true } +cranelift-object = { version = "0.126.0" } target-lexicon = "0.13" gimli = { version = "0.32", default-features = false, features = ["write"] } object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } @@ -24,12 +24,12 @@ smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } diff --git a/src/common.rs b/src/common.rs index 758d89c92b75..b11f42408f58 100644 --- a/src/common.rs +++ b/src/common.rs @@ -388,6 +388,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { size, // The maximum value of ilog2 is 31 which will always fit in a u8. align_shift: align.ilog2().try_into().unwrap(), + key: None, }); Pointer::stack_slot(stack_slot) } else { @@ -397,6 +398,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { kind: StackSlotKind::ExplicitSlot, size: size + align, align_shift: abi_align.ilog2().try_into().unwrap(), + key: None, }); let base_ptr = self.bcx.ins().stack_addr(self.pointer_type, stack_slot, 0); let misalign_offset = self.bcx.ins().band_imm(base_ptr, i64::from(align - 1)); From fb32ac4a635dada245f892d5b56caad2182e56a3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Nov 2025 10:31:02 +0000 Subject: [PATCH 0101/3801] Minor benchmarking improvements --- build_system/bench.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/build_system/bench.rs b/build_system/bench.rs index 80c7826d4e73..91353ba8a874 100644 --- a/build_system/bench.rs +++ b/build_system/bench.rs @@ -111,13 +111,18 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { let bench_run_markdown = dirs.build_dir.join("bench_run.md"); - let bench_run = hyperfine_command( + let mut bench_run = hyperfine_command( 0, bench_runs, None, - &[("", &raytracer_cg_llvm), ("", &raytracer_cg_clif), ("", &raytracer_cg_clif_opt)], + &[ + ("build/raytracer_cg_llvm", &raytracer_cg_llvm), + ("build/raytracer_cg_clif", &raytracer_cg_clif), + ("build/raytracer_cg_clif_opt", &raytracer_cg_clif_opt), + ], &bench_run_markdown, ); + bench_run.current_dir(&dirs.build_dir); spawn_and_wait(bench_run); if let Some(gha_step_summary) = gha_step_summary.as_mut() { From f5a5f0ff03be6c3feb25440c675ce6bcb787ec23 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 21 Nov 2025 20:34:35 +0800 Subject: [PATCH 0102/3801] use verbose for associated functions suggestion --- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- tests/ui/issues/issue-4265.stderr | 10 ++-- tests/ui/methods/issue-3707.stderr | 10 ++-- tests/ui/suggestions/issue-102354.stderr | 10 ++-- tests/ui/suggestions/issue-103646.stderr | 10 ++-- .../suggest-assoc-fn-call-deref.stderr | 10 ++-- ...uggest-assoc-fn-call-for-impl-trait.stderr | 30 ++++++----- ...-fn-call-with-turbofish-placeholder.stderr | 10 ++-- ...n-call-with-turbofish-through-deref.stderr | 10 ++-- ...uggest-assoc-fn-call-with-turbofish.stderr | 50 +++++++++++-------- ...gest-assoc-fn-call-without-receiver.stderr | 40 +++++++++------ 11 files changed, 115 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a0d9e9a72386..37661f93f021 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2339,7 +2339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { applicability = Applicability::HasPlaceholders; "(...)".to_owned() }; - err.span_suggestion( + err.span_suggestion_verbose( sugg_span, "use associated function syntax instead", format!("{ty_str}::{item_name}{args}"), diff --git a/tests/ui/issues/issue-4265.stderr b/tests/ui/issues/issue-4265.stderr index 23d00aaa44b5..d4a44c129a89 100644 --- a/tests/ui/issues/issue-4265.stderr +++ b/tests/ui/issues/issue-4265.stderr @@ -14,10 +14,7 @@ LL | struct Foo { | ---------- method `bar` not found for this struct ... LL | Foo { baz: 0 }.bar(); - | ---------------^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `Foo::bar()` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `Foo` @@ -25,6 +22,11 @@ note: the candidate is defined in an impl for the type `Foo` | LL | fn bar() { | ^^^^^^^^ +help: use associated function syntax instead + | +LL - Foo { baz: 0 }.bar(); +LL + Foo::bar(); + | error: aborting due to 2 previous errors diff --git a/tests/ui/methods/issue-3707.stderr b/tests/ui/methods/issue-3707.stderr index b3d4dfe5aaa8..c163ccc81899 100644 --- a/tests/ui/methods/issue-3707.stderr +++ b/tests/ui/methods/issue-3707.stderr @@ -2,10 +2,7 @@ error[E0599]: no method named `boom` found for reference `&Obj` in the current s --> $DIR/issue-3707.rs:10:14 | LL | self.boom(); - | -----^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `Obj::boom()` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `Obj` @@ -13,6 +10,11 @@ note: the candidate is defined in an impl for the type `Obj` | LL | pub fn boom() -> bool { | ^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - self.boom(); +LL + Obj::boom(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-102354.stderr b/tests/ui/suggestions/issue-102354.stderr index 8340d9340f9b..9354ce3efe57 100644 --- a/tests/ui/suggestions/issue-102354.stderr +++ b/tests/ui/suggestions/issue-102354.stderr @@ -2,10 +2,7 @@ error[E0599]: no method named `func` found for type `i32` in the current scope --> $DIR/issue-102354.rs:9:7 | LL | x.func(); - | --^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `i32::func()` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `Trait` @@ -13,6 +10,11 @@ note: the candidate is defined in the trait `Trait` | LL | fn func() {} | ^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.func(); +LL + i32::func(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-103646.stderr b/tests/ui/suggestions/issue-103646.stderr index 8d0e8652392d..42505e13e7e6 100644 --- a/tests/ui/suggestions/issue-103646.stderr +++ b/tests/ui/suggestions/issue-103646.stderr @@ -4,10 +4,7 @@ error[E0599]: no method named `nya` found for type parameter `T` in the current LL | fn uwu(c: T) { | - method `nya` not found for this type parameter LL | c.nya(); - | --^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `T::nya()` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `Cat` @@ -15,6 +12,11 @@ note: the candidate is defined in the trait `Cat` | LL | fn nya() {} | ^^^^^^^^ +help: use associated function syntax instead + | +LL - c.nya(); +LL + T::nya(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-deref.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-deref.stderr index a30b78692146..2314ff378f64 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-deref.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-deref.stderr @@ -2,10 +2,7 @@ error[E0599]: no method named `test` found for struct `Box>` in the cur --> $DIR/suggest-assoc-fn-call-deref.rs:13:7 | LL | x.test(); - | --^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `Foo::::test()` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `Foo` @@ -13,6 +10,11 @@ note: the candidate is defined in an impl for the type `Foo` | LL | fn test() -> i32 { 1 } | ^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.test(); +LL + Foo::::test(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr index 0df2b08d3be8..4ff4c50f1790 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr @@ -5,10 +5,7 @@ LL | struct A { | -------- method `foo` not found for this struct ... LL | _a.foo(); - | ---^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::foo(_a)` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `M` @@ -16,6 +13,11 @@ note: the candidate is defined in the trait `M` | LL | fn foo(_a: Self); | ^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _a.foo(); +LL + A::foo(_a); + | error[E0599]: no method named `baz` found for struct `A` in the current scope --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:23:8 @@ -24,10 +26,7 @@ LL | struct A { | -------- method `baz` not found for this struct ... LL | _a.baz(0); - | ---^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::baz(0)` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `M` @@ -35,6 +34,11 @@ note: the candidate is defined in the trait `M` | LL | fn baz(_a: i32); | ^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _a.baz(0); +LL + A::baz(0); + | error[E0599]: no method named `bar` found for struct `A` in the current scope --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:27:8 @@ -43,10 +47,7 @@ LL | struct A { | -------- method `bar` not found for this struct ... LL | _b.bar(); - | ---^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::bar(_b)` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `M` @@ -54,6 +55,11 @@ note: the candidate is defined in the trait `M` | LL | fn bar(_a: Self); | ^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _b.bar(); +LL + A::bar(_b); + | error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr index 6e4c77deac50..df8d80c4babf 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr @@ -5,10 +5,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct ... LL | x.default_hello(); - | --^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello()` + | ^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -16,6 +13,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.default_hello(); +LL + GenericAssocMethod::<_>::default_hello(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr index 1bc259294469..99d206764a17 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr @@ -2,10 +2,7 @@ error[E0599]: no method named `hello` found for struct `RefMut<'_, HasAssocMetho --> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:11:11 | LL | state.hello(); - | ------^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `HasAssocMethod::hello()` + | ^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `HasAssocMethod` @@ -13,6 +10,11 @@ note: the candidate is defined in an impl for the type `HasAssocMethod` | LL | fn hello() {} | ^^^^^^^^^^ +help: use associated function syntax instead + | +LL - state.hello(); +LL + HasAssocMethod::hello(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index 92b03fc77142..56d6b9fcd143 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -5,10 +5,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct ... LL | x.self_ty_ref_hello(); - | --^^^^^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_ref_hello(&x)` + | ^^^^^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -16,6 +13,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn self_ty_ref_hello(_: &Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.self_ty_ref_hello(); +LL + GenericAssocMethod::<_>::self_ty_ref_hello(&x); + | error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:16:7 @@ -24,10 +26,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct ... LL | x.self_ty_hello(); - | --^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_hello(x)` + | ^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -35,6 +34,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn self_ty_hello(_: Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.self_ty_hello(); +LL + GenericAssocMethod::<_>::self_ty_hello(x); + | error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:20:7 @@ -43,10 +47,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct ... LL | y.default_hello(); - | --^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::default_hello()` + | ^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -54,6 +55,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - y.default_hello(); +LL + GenericAssocMethod::::default_hello(); + | error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:22:7 @@ -62,10 +68,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct ... LL | y.self_ty_ref_hello(); - | --^^^^^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_ref_hello(&y)` + | ^^^^^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -73,6 +76,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn self_ty_ref_hello(_: &Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - y.self_ty_ref_hello(); +LL + GenericAssocMethod::::self_ty_ref_hello(&y); + | error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:24:7 @@ -81,10 +89,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct ... LL | y.self_ty_hello(); - | --^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_hello(y)` + | ^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -92,6 +97,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn self_ty_hello(_: Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - y.self_ty_hello(); +LL + GenericAssocMethod::::self_ty_hello(y); + | error: aborting due to 5 previous errors diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr index 793595784d93..a09cf41488df 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr @@ -5,10 +5,7 @@ LL | struct A {} | -------- method `hello` not found for this struct ... LL | _a.hello(1); - | ---^^^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::hello(1)` + | ^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `A` @@ -16,6 +13,11 @@ note: the candidate is defined in an impl for the type `A` | LL | fn hello(_a: i32) {} | ^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _a.hello(1); +LL + A::hello(1); + | error[E0599]: no method named `test` found for struct `A` in the current scope --> $DIR/suggest-assoc-fn-call-without-receiver.rs:22:8 @@ -24,10 +26,7 @@ LL | struct A {} | -------- method `test` not found for this struct ... LL | _a.test(1); - | ---^^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::test(_a, 1)` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `A` @@ -35,6 +34,11 @@ note: the candidate is defined in an impl for the type `A` | LL | fn test(_a: Self, _b: i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _a.test(1); +LL + A::test(_a, 1); + | error[E0599]: no method named `hello` found for struct `B<&str>` in the current scope --> $DIR/suggest-assoc-fn-call-without-receiver.rs:26:8 @@ -43,10 +47,7 @@ LL | struct B { | ----------- method `hello` not found for this struct ... LL | _b.hello(1); - | ---^^^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `B::<&str>::hello(1)` + | ^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `B` @@ -54,6 +55,11 @@ note: the candidate is defined in an impl for the type `B` | LL | fn hello(_a: i32) {} | ^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _b.hello(1); +LL + B::<&str>::hello(1); + | error[E0599]: no method named `test` found for struct `B<&str>` in the current scope --> $DIR/suggest-assoc-fn-call-without-receiver.rs:28:8 @@ -62,10 +68,7 @@ LL | struct B { | ----------- method `test` not found for this struct ... LL | _b.test(1); - | ---^^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `B::<&str>::test(_b, 1)` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `B` @@ -73,6 +76,11 @@ note: the candidate is defined in an impl for the type `B` | LL | fn test(_a: Self, _b: i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _b.test(1); +LL + B::<&str>::test(_b, 1); + | error: aborting due to 4 previous errors From e802180f416b1e30b70e605e4d950ea5e5564745 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 21 Nov 2025 21:04:13 +0800 Subject: [PATCH 0103/3801] add suggestion for associated function --- compiler/rustc_hir_typeck/src/expr.rs | 34 +++++++++++++++ tests/ui/methods/assc-func-issue-149038.rs | 10 +++++ .../ui/methods/assc-func-issue-149038.stderr | 43 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 tests/ui/methods/assc-func-issue-149038.rs create mode 100644 tests/ui/methods/assc-func-issue-149038.stderr diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 658f9857e5e1..29eb1183953a 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3369,6 +3369,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(within_macro_span, "due to this macro variable"); } + // Check if there is an associated function with the same name. + if let Some(def_id) = base_ty.peel_refs().ty_adt_def().map(|d| d.did()) { + for impl_def_id in self.tcx.inherent_impls(def_id) { + for item in self.tcx.associated_items(impl_def_id).in_definition_order() { + if let ExprKind::Field(base_expr, _) = expr.kind + && item.name() == field.name + && matches!(item.kind, ty::AssocKind::Fn { has_self: false, .. }) + { + err.span_label(field.span, "this is an associated function, not a method"); + err.note("found the following associated function; to be used as method, it must have a `self` parameter"); + let impl_ty = self.tcx.type_of(impl_def_id).instantiate_identity(); + err.span_note( + self.tcx.def_span(item.def_id), + format!("the candidate is defined in an impl for the type `{impl_ty}`"), + ); + + let ty_str = match base_ty.peel_refs().kind() { + ty::Adt(def, args) => self.tcx.def_path_str_with_args(def.did(), args), + _ => base_ty.peel_refs().to_string(), + }; + err.multipart_suggestion( + "use associated function syntax instead", + vec![ + (base_expr.span, ty_str), + (base_expr.span.between(field.span), "::".to_string()), + ], + Applicability::MaybeIncorrect, + ); + return err; + } + } + } + } + // try to add a suggestion in case the field is a nested field of a field of the Adt let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id(); let (ty, unwrap) = if let ty::Adt(def, args) = base_ty.kind() diff --git a/tests/ui/methods/assc-func-issue-149038.rs b/tests/ui/methods/assc-func-issue-149038.rs new file mode 100644 index 000000000000..4fb4bd72fcc3 --- /dev/null +++ b/tests/ui/methods/assc-func-issue-149038.rs @@ -0,0 +1,10 @@ +struct S; +impl S { + fn foo() {} + fn bar(&self) { + self.foo(); //~ ERROR no method named `foo` found for reference `&S` in the current scope + let f: fn() = self.foo; //~ ERROR no field `foo` on type `&S` + } +} + +fn main() {} diff --git a/tests/ui/methods/assc-func-issue-149038.stderr b/tests/ui/methods/assc-func-issue-149038.stderr new file mode 100644 index 000000000000..55b762bc0ee0 --- /dev/null +++ b/tests/ui/methods/assc-func-issue-149038.stderr @@ -0,0 +1,43 @@ +error[E0599]: no method named `foo` found for reference `&S` in the current scope + --> $DIR/assc-func-issue-149038.rs:5:14 + | +LL | self.foo(); + | ^^^ this is an associated function, not a method + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `S` + --> $DIR/assc-func-issue-149038.rs:3:5 + | +LL | fn foo() {} + | ^^^^^^^^ +help: use associated function syntax instead + | +LL - self.foo(); +LL + S::foo(); + | + +error[E0609]: no field `foo` on type `&S` + --> $DIR/assc-func-issue-149038.rs:6:28 + | +LL | let f: fn() = self.foo; + | ^^^ + | | + | this is an associated function, not a method + | unknown field + | + = note: found the following associated function; to be used as method, it must have a `self` parameter +note: the candidate is defined in an impl for the type `S` + --> $DIR/assc-func-issue-149038.rs:3:5 + | +LL | fn foo() {} + | ^^^^^^^^ +help: use associated function syntax instead + | +LL - let f: fn() = self.foo; +LL + let f: fn() = S::foo; + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0599, E0609. +For more information about an error, try `rustc --explain E0599`. From adae6aa8520feb6abfcb7c0080a1d2845f701295 Mon Sep 17 00:00:00 2001 From: Greg Morenz Date: Fri, 21 Nov 2025 14:10:35 -0500 Subject: [PATCH 0104/3801] Add test for nfc-normalization of idents --- tests/ui/lexer/ident_normalization.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/ui/lexer/ident_normalization.rs diff --git a/tests/ui/lexer/ident_normalization.rs b/tests/ui/lexer/ident_normalization.rs new file mode 100644 index 000000000000..a16c52171106 --- /dev/null +++ b/tests/ui/lexer/ident_normalization.rs @@ -0,0 +1,20 @@ +//@check-pass +//@edition:2021 + +#![allow(non_snake_case)] + +// Tests that identifiers are NFC-normalized as per +// https://rust-lang.github.io/rfcs/2457-non-ascii-idents.html + +// Note that in the first argument of each function `K` is LATIN CAPITAL LETTER K +// and in the second it is K (KELVIN SIGN). + +fn ident_nfc(_p1: K, _p2: K) {} + +fn raw_ident_nfc(_p1: r#K, _p2: r#K) {} + +fn lifetime_nfc<'K>(_p1: &'K str, _p2: &'K str) {} + +fn raw_lifetime_nfc<'K>(_p1: &'r#K str, _p2: &'r#K str) {} + +fn main() {} From b1cde92016d139521ce6a437797574d413b4b6ce Mon Sep 17 00:00:00 2001 From: Greg Morenz Date: Fri, 21 Nov 2025 14:11:06 -0500 Subject: [PATCH 0105/3801] nfc normalize lifetime idents --- compiler/rustc_parse/src/lexer/mod.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 51019db7c00e..84596de12ae9 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -316,7 +316,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { // Include the leading `'` in the real identifier, for macro // expansion purposes. See #12512 for the gory details of why // this is necessary. - let lifetime_name = self.str_from(start); + let lifetime_name = nfc_normalize(self.str_from(start)); self.last_lifetime = Some(self.mk_sp(start, start + BytePos(1))); if starts_with_number { let span = self.mk_sp(start, self.pos); @@ -325,8 +325,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { .with_span(span) .stash(span, StashKey::LifetimeIsChar); } - let ident = Symbol::intern(lifetime_name); - token::Lifetime(ident, IdentIsRaw::No) + token::Lifetime(lifetime_name, IdentIsRaw::No) } rustc_lexer::TokenKind::RawLifetime => { self.last_lifetime = Some(self.mk_sp(start, start + BytePos(1))); @@ -373,7 +372,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { String::with_capacity(lifetime_name_without_tick.as_str().len() + 1); lifetime_name.push('\''); lifetime_name += lifetime_name_without_tick.as_str(); - let sym = Symbol::intern(&lifetime_name); + let sym = nfc_normalize(&lifetime_name); // Make sure we mark this as a raw identifier. self.psess.raw_identifier_spans.push(span); @@ -393,9 +392,8 @@ impl<'psess, 'src> Lexer<'psess, 'src> { self.pos = lt_start; self.cursor = Cursor::new(&str_before[2 as usize..], FrontmatterAllowed::No); - let lifetime_name = self.str_from(start); - let ident = Symbol::intern(lifetime_name); - token::Lifetime(ident, IdentIsRaw::No) + let lifetime_name = nfc_normalize(self.str_from(start)); + token::Lifetime(lifetime_name, IdentIsRaw::No) } } rustc_lexer::TokenKind::Semi => token::Semi, From 0e5484549243aae0e783080b02872018a6f09d41 Mon Sep 17 00:00:00 2001 From: Coca Date: Sat, 22 Nov 2025 17:30:48 +0000 Subject: [PATCH 0106/3801] Add `flatten_{ref/mut}` for `Option<&Option>`/`Option<&mut Option>` --- library/core/src/option.rs | 89 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 57098b95f641..91da3e22667b 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2737,6 +2737,95 @@ impl Option> { } } +impl<'a, T> Option<&'a Option> { + /// Converts from `Option<&Option>` to `Option<&T>`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(option_reference_flattening)] + /// + /// let x: Option<&Option> = Some(&Some(6)); + /// assert_eq!(Some(&6), x.flatten_ref()); + /// + /// let x: Option<&Option> = Some(&None); + /// assert_eq!(None, x.flatten_ref()); + /// + /// let x: Option<&Option> = None; + /// assert_eq!(None, x.flatten_ref()); + /// ``` + #[inline] + #[unstable(feature = "option_reference_flattening", issue = "149221")] + pub const fn flatten_ref(self) -> Option<&'a T> { + match self { + Some(inner) => inner.as_ref(), + None => None, + } + } +} + +impl<'a, T> Option<&'a mut Option> { + /// Converts from `Option<&mut Option>` to `&Option`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(option_reference_flattening)] + /// + /// let y = &mut Some(6); + /// let x: Option<&mut Option> = Some(y); + /// assert_eq!(Some(&6), x.flatten_ref()); + /// + /// let y: &mut Option = &mut None; + /// let x: Option<&mut Option> = Some(y); + /// assert_eq!(None, x.flatten_ref()); + /// + /// let x: Option<&mut Option> = None; + /// assert_eq!(None, x.flatten_ref()); + /// ``` + #[inline] + #[unstable(feature = "option_reference_flattening", issue = "149221")] + pub const fn flatten_ref(self) -> Option<&'a T> { + match self { + Some(inner) => inner.as_ref(), + None => None, + } + } + + /// Converts from `Option<&mut Option>` to `Option<&mut T>`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(option_reference_flattening)] + /// + /// let y: &mut Option = &mut Some(6); + /// let x: Option<&mut Option> = Some(y); + /// assert_eq!(Some(&mut 6), x.flatten_mut()); + /// + /// let y: &mut Option = &mut None; + /// let x: Option<&mut Option> = Some(y); + /// assert_eq!(None, x.flatten_mut()); + /// + /// let x: Option<&mut Option> = None; + /// assert_eq!(None, x.flatten_mut()); + /// ``` + #[inline] + #[unstable(feature = "option_reference_flattening", issue = "149221")] + pub const fn flatten_mut(self) -> Option<&'a mut T> { + match self { + Some(inner) => inner.as_mut(), + None => None, + } + } +} + impl [Option; N] { /// Transposes a `[Option; N]` into a `Option<[T; N]>`. /// From aca2dc0c064e0d7c8f83f3f4df8e3238724165f1 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Sun, 23 Nov 2025 01:52:14 -0600 Subject: [PATCH 0107/3801] fix typos and footnotes --- src/doc/rustc-dev-guide/src/SUMMARY.md | 2 +- .../src/debuginfo/lldb-visualizers.md | 2 +- .../src/debuginfo/rust-codegen.md | 30 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index bec587f0eec9..c85e37e134dd 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -231,7 +231,7 @@ - [Debug Info](./debuginfo/intro.md) - [Rust Codegen](./debuginfo/rust-codegen.md) - [LLVM Codegen](./debuginfo/llvm-codegen.md) - - [Debugger Interanls](./debuginfo/debugger-internals.md) + - [Debugger Internals](./debuginfo/debugger-internals.md) - [LLDB Internals](./debuginfo/lldb-internals.md) - [GDB Internals](./debuginfo/gdb-internals.md) - [Debugger Visualizers](./debuginfo/debugger-visualizers.md) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md index c7bcc25029ef..bb27c0e97369 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md @@ -1,7 +1,7 @@ # LLDB - Python Providers > NOTE: LLDB's C++<->Python FFI expects a version of python designated at the time LLDB was ->compiled. LLDB is careful to correspond this version to the minimum in typical Linux and MacOs +>compiled. LLDB is careful to correspond this version to the minimum in typical Linux and macOS >distributions, but on Windows there is no easy solution. If you recieve an import error regarding >`_lldb` not existing, a mismatched Python version is likely the cause. > diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md index 6d5dfe08cb15..00a03e3657f1 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -78,27 +78,27 @@ debug info: | Rust name | MSVC name | | --- | --- | | `&str`/`&mut str` | `ref$`/`ref_mut$` | -| `&[T]`/`&mut [T]` | `ref$ >`/`ref_mut$ >`* | +| `&[T]`/`&mut [T]` | `ref$ >`/`ref_mut$ >`[^1] | | `[T; N]` | `array$` | | `RustEnum` | `enum2$` | | `(T1, T2)` | `tuple$`| | `*const T` | `ptr_const$` | | `*mut T` | `ptr_mut$` | -| `usize` | `size_t`** | -| `isize` | `ptrdiff_t`** | -| `uN` | `unsigned __intN`** | -| `iN` | `__intN`** | -| `f32` | `float`** | -| `f64` | `double`** | -| `f128` | `fp128`** | +| `usize` | `size_t`[^2] | +| `isize` | `ptrdiff_t`[^2] | +| `uN` | `unsigned __intN`[^2] | +| `iN` | `__intN`[^2] | +| `f32` | `float`[^2] | +| `f64` | `double`[^2] | +| `f128` | `fp128`[^2] | -> \* MSVC's expression parser will treat `>>` as a right shift. It is necessary to separate ->consecutive `>`'s with a space (`> >`) in type names. -> -> ** While these type names are generated as part of the debug info node (which is then wrapped in ->a typedef node with the Rust name), once the LLVM-IR node is converted to a CodeView node, the type ->name information is lost. This is because CodeView has special shorthand nodes for primitive types, ->and those shorthand nodes to not have a "name" field. +[^1]: MSVC's expression parser will treat `>>` as a right shift. It is necessary to separate +consecutive `>`'s with a space (`> >`) in type names. + +[^2]: While these type names are generated as part of the debug info node (which is then wrapped in +a typedef node with the Rust name), once the LLVM-IR node is converted to a CodeView node, the type +name information is lost. This is because CodeView has special shorthand nodes for primitive types, +and those shorthand nodes to not have a "name" field. ### Generics From 5d997ffc644fce728756e17af8c3f8e9989bb0da Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Sun, 23 Nov 2025 01:54:38 -0600 Subject: [PATCH 0108/3801] Add section for `#![debugger_visualizer]` --- .../src/debuginfo/debugger-visualizers.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md index 07e3861a500b..831acbd2f8f8 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md @@ -13,6 +13,55 @@ debug info, but can be derived from invariants about the language and the type i example is allowing one to interact with the elements of a `Vec` instead of just it's `*mut u8` heap pointer, length, and capacity. +## `rust-lldb`, `rust-gdb`, and `rust-windbg.cmd` + +These support scripts are distributed with Rust toolchains. They locate the appropriate debugger and +the toolchain's visualizer scripts, then launch the debugger with the appropriate arguments to load +the visualizer scripts before a debugee is launched/attached to. + +## `#![debugger_visualizer]` + +[This attribute][dbg_vis_attr] allows Rust library authors to include pretty printers for their +types within the library itself. These pretty printers are of the same format as typical +visualizers, but are embedded directly into the compiled binary. These scripts are loaded +automatically by the debugger, allowing a seamless experience for users. This attribute currently +works for GDB and natvis scripts. + +[dbg_vis_attr]: https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute + +GDB python scripts are embedded in the `.debug_gdb_scripts` section of the binary. More information +can be found [here](https://sourceware.org/gdb/current/onlinedocs/gdb.html/dotdebug_005fgdb_005fscripts-section.html). Rustc accomplishes this in [`rustc_codegen_llvm/src/debuginfo/gdb.rs`][gdb_rs] + +[gdb_rs]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs + +Natvis files can be embedded in the PDB debug info using the [`/NATVIS` linker option][linker_opt], +and have the [highest priority][priority] when a type is resolving which visualizer to use. The +files specified by the attribute are collected into +[`CrateInfo::natvis_debugger_visualizers`][natvis] which are then added as linker arguments in +[`rustc_codegen_ssa/src/back/linker.rs`][linker_rs] + +[linker_opt]: https://learn.microsoft.com/en-us/cpp/build/reference/natvis-add-natvis-to-pdb?view=msvc-170 +[priority]: https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=visualstudio#BKMK_natvis_location +[natvis]: https://github.com/rust-lang/rust/blob/e0e204f3e97ad5f79524b9c259dc38df606ed82c/compiler/rustc_codegen_ssa/src/lib.rs#L212 +[linker_rs]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_ssa/src/back/linker.rs#L1106 + +LLDB is not currently supported, but there are a few methods that could potentially allow support in +the future. Officially, the intended method is via a [formatter bytecode][bytecode]. This was +created to offer a comparable experience to GDB's, but without the safety concerns associated with +embedding an entire python script. The opcodes are limited, but it works with `SBValue` and `SBType` +in roughly the same way as python visualizer scripts. Implementing this would require writing some +sort of DSL/mini compiler. + +[bytecode]: https://lldb.llvm.org/resources/formatterbytecode.html + +Alternatively, it might be possible to copy GDB's strategy entirely: create a bespoke section in the +binary and embed a python script in it. LLDB will not load it automatically, but the python API does +allow one to access the [raw sections of the debug info][SBSection]. With this, it may be possible +to extract the python script from our bespoke section and then load it in during the startup of +Rust's visualizer scripts. + +[SBSection]: https://lldb.llvm.org/python_api/lldb.SBSection.html#sbsection + ## Performance Before tackling the visualizers themselves, it's important to note that these are part of a From 12f41b519435e3952f2bf8e2c829e19c982ace04 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 17 Oct 2025 12:52:31 +0000 Subject: [PATCH 0109/3801] More explicit handling of the allocator shim around LTO --- compiler/rustc_codegen_ssa/src/back/write.rs | 56 +++++++++----------- compiler/rustc_codegen_ssa/src/base.rs | 11 +--- 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 3e36bd8552b1..885af95b1f2c 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -334,7 +334,6 @@ pub struct CodegenContext { pub output_filenames: Arc, pub invocation_temp: Option, pub module_config: Arc, - pub allocator_config: Arc, pub tm_factory: TargetMachineFactoryFn, pub msvc_imps_needed: bool, pub is_pe_coff: bool, @@ -799,19 +798,12 @@ pub(crate) fn compute_per_cgu_lto_type( sess_lto: &Lto, opts: &config::Options, sess_crate_types: &[CrateType], - module_kind: ModuleKind, ) -> ComputedLtoType { // If the linker does LTO, we don't have to do it. Note that we // keep doing full LTO, if it is requested, as not to break the // assumption that the output will be a single module. let linker_does_lto = opts.cg.linker_plugin_lto.enabled(); - // When we're automatically doing ThinLTO for multi-codegen-unit - // builds we don't actually want to LTO the allocator module if - // it shows up. This is due to various linker shenanigans that - // we'll encounter later. - let is_allocator = module_kind == ModuleKind::Allocator; - // We ignore a request for full crate graph LTO if the crate type // is only an rlib, as there is no full crate graph to process, // that'll happen later. @@ -823,7 +815,7 @@ pub(crate) fn compute_per_cgu_lto_type( let is_rlib = matches!(sess_crate_types, [CrateType::Rlib]); match sess_lto { - Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin, + Lto::ThinLocal if !linker_does_lto => ComputedLtoType::Thin, Lto::Thin if !linker_does_lto && !is_rlib => ComputedLtoType::Thin, Lto::Fat if !is_rlib => ComputedLtoType::Fat, _ => ComputedLtoType::No, @@ -839,23 +831,18 @@ fn execute_optimize_work_item( let dcx = cgcx.create_dcx(); let dcx = dcx.handle(); - let module_config = match module.kind { - ModuleKind::Regular => &cgcx.module_config, - ModuleKind::Allocator => &cgcx.allocator_config, - }; - - B::optimize(cgcx, dcx, &mut module, module_config); + B::optimize(cgcx, dcx, &mut module, &cgcx.module_config); // After we've done the initial round of optimizations we need to // decide whether to synchronously codegen this module or ship it // back to the coordinator thread for further LTO processing (which // has to wait for all the initial modules to be optimized). - let lto_type = compute_per_cgu_lto_type(&cgcx.lto, &cgcx.opts, &cgcx.crate_types, module.kind); + let lto_type = compute_per_cgu_lto_type(&cgcx.lto, &cgcx.opts, &cgcx.crate_types); // If we're doing some form of incremental LTO then we need to be sure to // save our module to disk first. - let bitcode = if module_config.emit_pre_lto_bc { + let bitcode = if cgcx.module_config.emit_pre_lto_bc { let filename = pre_lto_bitcode_filename(&module.name); cgcx.incr_comp_session_dir.as_ref().map(|path| path.join(&filename)) } else { @@ -864,7 +851,7 @@ fn execute_optimize_work_item( match lto_type { ComputedLtoType::No => { - let module = B::codegen(cgcx, module, module_config); + let module = B::codegen(cgcx, module, &cgcx.module_config); WorkItemResult::Finished(module) } ComputedLtoType::Thin => { @@ -1245,7 +1232,7 @@ fn start_executing_work( coordinator_receive: Receiver>, regular_config: Arc, allocator_config: Arc, - allocator_module: Option>, + mut allocator_module: Option>, coordinator_send: Sender>, ) -> thread::JoinHandle> { let sess = tcx.sess; @@ -1303,7 +1290,6 @@ fn start_executing_work( diag_emitter: shared_emitter.clone(), output_filenames: Arc::clone(tcx.output_filenames(())), module_config: regular_config, - allocator_config, tm_factory: backend.target_machine_factory(tcx.sess, ol, backend_features), msvc_imps_needed: msvc_imps_needed(tcx), is_pe_coff: tcx.sess.target.is_like_windows, @@ -1497,16 +1483,12 @@ fn start_executing_work( let mut llvm_start_time: Option> = None; - let compiled_allocator_module = allocator_module.and_then(|allocator_module| { - match execute_optimize_work_item(&cgcx, allocator_module) { - WorkItemResult::Finished(compiled_module) => return Some(compiled_module), - WorkItemResult::NeedsFatLto(fat_lto_input) => needs_fat_lto.push(fat_lto_input), - WorkItemResult::NeedsThinLto(name, thin_buffer) => { - needs_thin_lto.push((name, thin_buffer)) - } - } - None - }); + if let Some(allocator_module) = &mut allocator_module { + let dcx = cgcx.create_dcx(); + let dcx = dcx.handle(); + + B::optimize(&cgcx, dcx, allocator_module, &allocator_config); + } // Run the message loop while there's still anything that needs message // processing. Note that as soon as codegen is aborted we simply want to @@ -1733,6 +1715,10 @@ fn start_executing_work( assert!(compiled_modules.is_empty()); assert!(needs_thin_lto.is_empty()); + if let Some(allocator_module) = allocator_module.take() { + needs_fat_lto.push(FatLtoInput::InMemory(allocator_module)); + } + // This uses the implicit token let module = do_fat_lto( &cgcx, @@ -1746,6 +1732,13 @@ fn start_executing_work( assert!(compiled_modules.is_empty()); assert!(needs_fat_lto.is_empty()); + if cgcx.lto != Lto::ThinLocal { + if let Some(allocator_module) = allocator_module.take() { + let (name, thin_buffer) = B::prepare_thin(allocator_module); + needs_thin_lto.push((name, thin_buffer)); + } + } + compiled_modules.extend(do_thin_lto( &cgcx, exported_symbols_for_lto, @@ -1762,7 +1755,8 @@ fn start_executing_work( Ok(CompiledModules { modules: compiled_modules, - allocator_module: compiled_allocator_module, + allocator_module: allocator_module + .map(|allocator_module| B::codegen(&cgcx, allocator_module, &allocator_config)), }) }) .expect("failed to spawn coordinator thread"); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 414e9ce1c821..815a3ee706f8 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -49,9 +49,7 @@ use crate::meth::load_vtable; use crate::mir::operand::OperandValue; use crate::mir::place::PlaceRef; use crate::traits::*; -use crate::{ - CachedModuleCodegen, CodegenLintLevels, CrateInfo, ModuleCodegen, ModuleKind, errors, meth, mir, -}; +use crate::{CachedModuleCodegen, CodegenLintLevels, CrateInfo, ModuleCodegen, errors, meth, mir}; pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate { match (op, signed) { @@ -1132,12 +1130,7 @@ pub fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> // We can re-use either the pre- or the post-thinlto state. If no LTO is // being performed then we can use post-LTO artifacts, otherwise we must // reuse pre-LTO artifacts - match compute_per_cgu_lto_type( - &tcx.sess.lto(), - &tcx.sess.opts, - tcx.crate_types(), - ModuleKind::Regular, - ) { + match compute_per_cgu_lto_type(&tcx.sess.lto(), &tcx.sess.opts, tcx.crate_types()) { ComputedLtoType::No => CguReuse::PostLto, _ => CguReuse::PreLto, } From b93b4b003eb1b1dea681d65a5ac9c222b854046d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Oct 2025 09:39:13 +0000 Subject: [PATCH 0110/3801] Remove opts field from CodegenContext --- compiler/rustc_codegen_gcc/src/back/lto.rs | 2 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- compiler/rustc_codegen_llvm/src/back/write.rs | 6 +++--- compiler/rustc_codegen_ssa/src/back/lto.rs | 6 +++--- compiler/rustc_codegen_ssa/src/back/write.rs | 14 +++++++++----- compiler/rustc_codegen_ssa/src/base.rs | 6 +++++- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs index 404064fb7a06..08c36d2b7318 100644 --- a/compiler/rustc_codegen_gcc/src/back/lto.rs +++ b/compiler/rustc_codegen_gcc/src/back/lto.rs @@ -290,7 +290,7 @@ pub(crate) fn run_thin( let dcx = cgcx.create_dcx(); let dcx = dcx.handle(); let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx); - if cgcx.opts.cg.linker_plugin_lto.enabled() { + if cgcx.use_linker_plugin_lto { unreachable!( "We should never reach this case if the LTO step \ is deferred to the linker" diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index b820b992105f..3137ed288fa8 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -179,7 +179,7 @@ pub(crate) fn run_thin( prepare_lto(cgcx, exported_symbols_for_lto, each_linked_rlib_for_lto, dcx); let symbols_below_threshold = symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>(); - if cgcx.opts.cg.linker_plugin_lto.enabled() { + if cgcx.use_linker_plugin_lto { unreachable!( "We should never reach this case if the LTO step \ is deferred to the linker" diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 95539059653b..a49d4c010d67 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -398,7 +398,7 @@ impl<'a> DiagnosticHandlers<'a> { }) .and_then(|dir| dir.to_str().and_then(|p| CString::new(p).ok())); - let pgo_available = cgcx.opts.cg.profile_use.is_some(); + let pgo_available = cgcx.module_config.pgo_use.is_some(); let data = Box::into_raw(Box::new((cgcx, dcx))); unsafe { let old_handler = llvm::LLVMRustContextGetDiagnosticHandler(llcx); @@ -738,7 +738,7 @@ pub(crate) unsafe fn llvm_optimize( &*module.module_llvm.tm.raw(), to_pass_builder_opt_level(opt_level), opt_stage, - cgcx.opts.cg.linker_plugin_lto.enabled(), + cgcx.use_linker_plugin_lto, config.no_prepopulate_passes, config.verify_llvm_ir, config.lint_llvm_ir, @@ -801,7 +801,7 @@ pub(crate) fn optimize( let opt_stage = match cgcx.lto { Lto::Fat => llvm::OptStage::PreLinkFatLTO, Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO, - _ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO, + _ if cgcx.use_linker_plugin_lto => llvm::OptStage::PreLinkThinLTO, _ => llvm::OptStage::PreLinkNoLTO, }; diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index e6df6a2469f3..e3dc985bf782 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -137,15 +137,15 @@ pub(super) fn check_lto_allowed(cgcx: &CodegenContext if !crate_type_allows_lto(*crate_type) { dcx.handle().emit_fatal(LtoDisallowed); } else if *crate_type == CrateType::Dylib { - if !cgcx.opts.unstable_opts.dylib_lto { + if !cgcx.dylib_lto { dcx.handle().emit_fatal(LtoDylib); } - } else if *crate_type == CrateType::ProcMacro && !cgcx.opts.unstable_opts.dylib_lto { + } else if *crate_type == CrateType::ProcMacro && !cgcx.dylib_lto { dcx.handle().emit_fatal(LtoProcMacro); } } - if cgcx.opts.cg.prefer_dynamic && !cgcx.opts.unstable_opts.dylib_lto { + if cgcx.prefer_dynamic && !cgcx.dylib_lto { dcx.handle().emit_fatal(DynamicLinkingWithLTO); } } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 885af95b1f2c..bc7c32931613 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -326,10 +326,12 @@ pub struct CodegenContext { // Resources needed when running LTO pub prof: SelfProfilerRef, pub lto: Lto, + pub use_linker_plugin_lto: bool, + pub dylib_lto: bool, + pub prefer_dynamic: bool, pub save_temps: bool, pub fewer_names: bool, pub time_trace: bool, - pub opts: Arc, pub crate_types: Vec, pub output_filenames: Arc, pub invocation_temp: Option, @@ -796,13 +798,12 @@ pub(crate) enum ComputedLtoType { pub(crate) fn compute_per_cgu_lto_type( sess_lto: &Lto, - opts: &config::Options, + linker_does_lto: bool, sess_crate_types: &[CrateType], ) -> ComputedLtoType { // If the linker does LTO, we don't have to do it. Note that we // keep doing full LTO, if it is requested, as not to break the // assumption that the output will be a single module. - let linker_does_lto = opts.cg.linker_plugin_lto.enabled(); // We ignore a request for full crate graph LTO if the crate type // is only an rlib, as there is no full crate graph to process, @@ -838,7 +839,8 @@ fn execute_optimize_work_item( // back to the coordinator thread for further LTO processing (which // has to wait for all the initial modules to be optimized). - let lto_type = compute_per_cgu_lto_type(&cgcx.lto, &cgcx.opts, &cgcx.crate_types); + let lto_type = + compute_per_cgu_lto_type(&cgcx.lto, cgcx.use_linker_plugin_lto, &cgcx.crate_types); // If we're doing some form of incremental LTO then we need to be sure to // save our module to disk first. @@ -1279,10 +1281,12 @@ fn start_executing_work( let cgcx = CodegenContext:: { crate_types: tcx.crate_types().to_vec(), lto: sess.lto(), + use_linker_plugin_lto: sess.opts.cg.linker_plugin_lto.enabled(), + dylib_lto: sess.opts.unstable_opts.dylib_lto, + prefer_dynamic: sess.opts.cg.prefer_dynamic, fewer_names: sess.fewer_names(), save_temps: sess.opts.cg.save_temps, time_trace: sess.opts.unstable_opts.llvm_time_trace, - opts: Arc::new(sess.opts.clone()), prof: sess.prof.clone(), remark: sess.opts.cg.remark.clone(), remark_dir, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 815a3ee706f8..2943df8f02aa 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -1130,7 +1130,11 @@ pub fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> // We can re-use either the pre- or the post-thinlto state. If no LTO is // being performed then we can use post-LTO artifacts, otherwise we must // reuse pre-LTO artifacts - match compute_per_cgu_lto_type(&tcx.sess.lto(), &tcx.sess.opts, tcx.crate_types()) { + match compute_per_cgu_lto_type( + &tcx.sess.lto(), + tcx.sess.opts.cg.linker_plugin_lto.enabled(), + tcx.crate_types(), + ) { ComputedLtoType::No => CguReuse::PostLto, _ => CguReuse::PreLto, } From 2d7c571391e558a55767dc9aaeca6989a63c77c4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Nov 2025 15:08:09 +0000 Subject: [PATCH 0111/3801] Remove SharedEmitter from CodegenContext --- compiler/rustc_codegen_gcc/src/back/lto.rs | 12 +- compiler/rustc_codegen_gcc/src/back/write.rs | 8 +- compiler/rustc_codegen_gcc/src/lib.rs | 14 ++- compiler/rustc_codegen_llvm/src/back/lto.rs | 27 +++-- compiler/rustc_codegen_llvm/src/back/write.rs | 43 ++++--- compiler/rustc_codegen_llvm/src/lib.rs | 29 +++-- compiler/rustc_codegen_ssa/src/back/lto.rs | 8 +- compiler/rustc_codegen_ssa/src/back/write.rs | 112 +++++++++++------- .../rustc_codegen_ssa/src/traits/write.rs | 8 +- 9 files changed, 165 insertions(+), 96 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs index 08c36d2b7318..24be3ee4c34d 100644 --- a/compiler/rustc_codegen_gcc/src/back/lto.rs +++ b/compiler/rustc_codegen_gcc/src/back/lto.rs @@ -26,11 +26,11 @@ use std::sync::atomic::Ordering; use gccjit::{Context, OutputKind}; use object::read::archive::ArchiveFile; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared}; -use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; +use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, SharedEmitter}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file}; use rustc_data_structures::memmap::Mmap; -use rustc_errors::DiagCtxtHandle; +use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_log::tracing::info; use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; @@ -112,10 +112,11 @@ fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> { /// for further optimization. pub(crate) fn run_fat( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx); /*let symbols_below_threshold = @@ -283,12 +284,11 @@ impl ModuleBufferMethods for ModuleBuffer { /// can simply be copied over from the incr. comp. cache. pub(crate) fn run_thin( cgcx: &CodegenContext, + dcx: DiagCtxtHandle<'_>, each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> (Vec>, Vec) { - let dcx = cgcx.create_dcx(); - let dcx = dcx.handle(); let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx); if cgcx.use_linker_plugin_lto { unreachable!( @@ -522,8 +522,6 @@ pub fn optimize_thin_module( thin_module: ThinModule, _cgcx: &CodegenContext, ) -> ModuleCodegen { - //let dcx = cgcx.create_dcx(); - //let module_name = &thin_module.shared.module_names[thin_module.idx]; /*let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap()); let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&dcx, e))?;*/ diff --git a/compiler/rustc_codegen_gcc/src/back/write.rs b/compiler/rustc_codegen_gcc/src/back/write.rs index eae0f2aa00f6..b6223c5be370 100644 --- a/compiler/rustc_codegen_gcc/src/back/write.rs +++ b/compiler/rustc_codegen_gcc/src/back/write.rs @@ -2,8 +2,11 @@ use std::{env, fs}; use gccjit::{Context, OutputKind}; use rustc_codegen_ssa::back::link::ensure_removed; -use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; +use rustc_codegen_ssa::back::write::{ + BitcodeSection, CodegenContext, EmitObj, ModuleConfig, SharedEmitter, +}; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; +use rustc_errors::DiagCtxt; use rustc_fs_util::link_or_copy; use rustc_log::tracing::debug; use rustc_session::config::OutputType; @@ -15,10 +18,11 @@ use crate::{GccCodegenBackend, GccContext, LtoMode}; pub(crate) fn codegen( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); let _timer = cgcx.prof.generic_activity_with_arg("GCC_module_codegen", &*module.name); diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 409b7886740a..5a2ec0a2fc68 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -82,7 +82,7 @@ use gccjit::{TargetInfo, Version}; use rustc_ast::expand::allocator::AllocatorMethod; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ - CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn, + CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn, }; use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::target_features::cfg_target_feature; @@ -371,23 +371,25 @@ impl WriteBackendMethods for GccCodegenBackend { fn run_and_optimize_fat_lto( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, // FIXME(bjorn3): Limit LTO exports to these symbols _exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - back::lto::run_fat(cgcx, each_linked_rlib_for_lto, modules) + back::lto::run_fat(cgcx, shared_emitter, each_linked_rlib_for_lto, modules) } fn run_thin_lto( cgcx: &CodegenContext, + dcx: DiagCtxtHandle<'_>, // FIXME(bjorn3): Limit LTO exports to these symbols _exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, Self::ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> (Vec>, Vec) { - back::lto::run_thin(cgcx, each_linked_rlib_for_lto, modules, cached_modules) + back::lto::run_thin(cgcx, dcx, each_linked_rlib_for_lto, modules, cached_modules) } fn print_pass_timings(&self) { @@ -400,7 +402,7 @@ impl WriteBackendMethods for GccCodegenBackend { fn optimize( _cgcx: &CodegenContext, - _dcx: DiagCtxtHandle<'_>, + _shared_emitter: &SharedEmitter, module: &mut ModuleCodegen, config: &ModuleConfig, ) { @@ -409,6 +411,7 @@ impl WriteBackendMethods for GccCodegenBackend { fn optimize_thin( cgcx: &CodegenContext, + _shared_emitter: &SharedEmitter, thin: ThinModule, ) -> ModuleCodegen { back::lto::optimize_thin_module(thin, cgcx) @@ -416,10 +419,11 @@ impl WriteBackendMethods for GccCodegenBackend { fn codegen( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - back::write::codegen(cgcx, module, config) + back::write::codegen(cgcx, shared_emitter, module, config) } fn prepare_thin(module: ModuleCodegen) -> (String, Self::ThinBuffer) { diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 3137ed288fa8..3210afc063a9 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -9,12 +9,12 @@ use std::{io, iter, slice}; use object::read::archive::ArchiveFile; use object::{Object, ObjectSection}; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared}; -use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; +use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, SharedEmitter}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::memmap::Mmap; -use rustc_errors::DiagCtxtHandle; +use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_hir::attrs::SanitizerSet; use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; @@ -150,17 +150,18 @@ fn get_bitcode_slice_from_object_data<'a>( /// for further optimization. pub(crate) fn run_fat( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, exported_symbols_for_lto, each_linked_rlib_for_lto, dcx); let symbols_below_threshold = symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>(); - fat_lto(cgcx, dcx, modules, upstream_modules, &symbols_below_threshold) + fat_lto(cgcx, dcx, shared_emitter, modules, upstream_modules, &symbols_below_threshold) } /// Performs thin LTO by performing necessary global analysis and returning two @@ -168,13 +169,12 @@ pub(crate) fn run_fat( /// can simply be copied over from the incr. comp. cache. pub(crate) fn run_thin( cgcx: &CodegenContext, + dcx: DiagCtxtHandle<'_>, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> (Vec>, Vec) { - let dcx = cgcx.create_dcx(); - let dcx = dcx.handle(); let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, exported_symbols_for_lto, each_linked_rlib_for_lto, dcx); let symbols_below_threshold = @@ -197,6 +197,7 @@ pub(crate) fn prepare_thin(module: ModuleCodegen) -> (String, ThinBu fn fat_lto( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, + shared_emitter: &SharedEmitter, modules: Vec>, mut serialized_modules: Vec<(SerializedModule, CString)>, symbols_below_threshold: &[*const libc::c_char], @@ -265,8 +266,13 @@ fn fat_lto( // The linking steps below may produce errors and diagnostics within LLVM // which we'd like to handle and print, so set up our diagnostic handlers // (which get unregistered when they go out of scope below). - let _handler = - DiagnosticHandlers::new(cgcx, dcx, llcx, &module, CodegenDiagnosticsStage::LTO); + let _handler = DiagnosticHandlers::new( + cgcx, + shared_emitter, + llcx, + &module, + CodegenDiagnosticsStage::LTO, + ); // For all other modules we codegened we'll need to link them into our own // bitcode. All modules were codegened in their own LLVM context, however, @@ -730,10 +736,11 @@ impl Drop for ThinBuffer { } pub(crate) fn optimize_thin_module( - thin_module: ThinModule, cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, + thin_module: ThinModule, ) -> ModuleCodegen { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); let module_name = &thin_module.shared.module_names[thin_module.idx]; diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a49d4c010d67..a5b6ea08a66d 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -9,7 +9,7 @@ use libc::{c_char, c_int, c_void, size_t}; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::back::write::{ - BitcodeSection, CodegenContext, EmitObj, InlineAsmError, ModuleConfig, + BitcodeSection, CodegenContext, EmitObj, InlineAsmError, ModuleConfig, SharedEmitter, TargetMachineFactoryConfig, TargetMachineFactoryFn, }; use rustc_codegen_ssa::base::wants_wasm_eh; @@ -17,7 +17,7 @@ use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_errors::{DiagCtxtHandle, Level}; +use rustc_errors::{DiagCtxt, DiagCtxtHandle, Level}; use rustc_fs_util::{link_or_copy, path_to_c_string}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -356,7 +356,7 @@ pub(crate) enum CodegenDiagnosticsStage { } pub(crate) struct DiagnosticHandlers<'a> { - data: *mut (&'a CodegenContext, DiagCtxtHandle<'a>), + data: *mut (&'a CodegenContext, &'a SharedEmitter), llcx: &'a llvm::Context, old_handler: Option<&'a llvm::DiagnosticHandler>, } @@ -364,7 +364,7 @@ pub(crate) struct DiagnosticHandlers<'a> { impl<'a> DiagnosticHandlers<'a> { pub(crate) fn new( cgcx: &'a CodegenContext, - dcx: DiagCtxtHandle<'a>, + shared_emitter: &'a SharedEmitter, llcx: &'a llvm::Context, module: &ModuleCodegen, stage: CodegenDiagnosticsStage, @@ -399,7 +399,7 @@ impl<'a> DiagnosticHandlers<'a> { .and_then(|dir| dir.to_str().and_then(|p| CString::new(p).ok())); let pgo_available = cgcx.module_config.pgo_use.is_some(); - let data = Box::into_raw(Box::new((cgcx, dcx))); + let data = Box::into_raw(Box::new((cgcx, shared_emitter))); unsafe { let old_handler = llvm::LLVMRustContextGetDiagnosticHandler(llcx); llvm::LLVMRustContextConfigureDiagnosticHandler( @@ -461,12 +461,16 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void if user.is_null() { return; } - let (cgcx, dcx) = - unsafe { *(user as *const (&CodegenContext, DiagCtxtHandle<'_>)) }; + let (cgcx, shared_emitter) = + unsafe { *(user as *const (&CodegenContext, &SharedEmitter)) }; + + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); + let dcx = dcx.handle(); match unsafe { llvm::diagnostic::Diagnostic::unpack(info) } { llvm::diagnostic::InlineAsm(inline) => { - cgcx.diag_emitter.inline_asm_error(report_inline_asm( + // FIXME use dcx + shared_emitter.inline_asm_error(report_inline_asm( cgcx, inline.message, inline.level, @@ -777,14 +781,18 @@ pub(crate) unsafe fn llvm_optimize( // Unsafe due to LLVM calls. pub(crate) fn optimize( cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, + shared_emitter: &SharedEmitter, module: &mut ModuleCodegen, config: &ModuleConfig, ) { let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &*module.name); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); + let dcx = dcx.handle(); + let llcx = &*module.module_llvm.llcx; - let _handlers = DiagnosticHandlers::new(cgcx, dcx, llcx, module, CodegenDiagnosticsStage::Opt); + let _handlers = + DiagnosticHandlers::new(cgcx, shared_emitter, llcx, module, CodegenDiagnosticsStage::Opt); if config.emit_no_opt_bc { let out = cgcx.output_filenames.temp_path_ext_for_cgu( @@ -865,19 +873,26 @@ pub(crate) fn optimize( pub(crate) fn codegen( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - let dcx = cgcx.create_dcx(); + let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_codegen", &*module.name); + + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); - let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_codegen", &*module.name); { let llmod = module.module_llvm.llmod(); let llcx = &*module.module_llvm.llcx; let tm = &*module.module_llvm.tm; - let _handlers = - DiagnosticHandlers::new(cgcx, dcx, llcx, &module, CodegenDiagnosticsStage::Codegen); + let _handlers = DiagnosticHandlers::new( + cgcx, + shared_emitter, + llcx, + &module, + CodegenDiagnosticsStage::Codegen, + ); if cgcx.msvc_imps_needed { create_msvc_imps(cgcx, llcx, llmod); diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 1b65a133d58c..3901662442e9 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -30,12 +30,13 @@ use llvm_util::target_config; use rustc_ast::expand::allocator::AllocatorMethod; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ - CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn, + CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryConfig, + TargetMachineFactoryFn, }; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::DiagCtxtHandle; +use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; @@ -166,14 +167,20 @@ impl WriteBackendMethods for LlvmCodegenBackend { } fn run_and_optimize_fat_lto( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - let mut module = - back::lto::run_fat(cgcx, exported_symbols_for_lto, each_linked_rlib_for_lto, modules); + let mut module = back::lto::run_fat( + cgcx, + shared_emitter, + exported_symbols_for_lto, + each_linked_rlib_for_lto, + modules, + ); - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); back::lto::run_pass_manager(cgcx, dcx, &mut module, false); @@ -181,6 +188,7 @@ impl WriteBackendMethods for LlvmCodegenBackend { } fn run_thin_lto( cgcx: &CodegenContext, + dcx: DiagCtxtHandle<'_>, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, Self::ThinBuffer)>, @@ -188,6 +196,7 @@ impl WriteBackendMethods for LlvmCodegenBackend { ) -> (Vec>, Vec) { back::lto::run_thin( cgcx, + dcx, exported_symbols_for_lto, each_linked_rlib_for_lto, modules, @@ -196,24 +205,26 @@ impl WriteBackendMethods for LlvmCodegenBackend { } fn optimize( cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, + shared_emitter: &SharedEmitter, module: &mut ModuleCodegen, config: &ModuleConfig, ) { - back::write::optimize(cgcx, dcx, module, config) + back::write::optimize(cgcx, shared_emitter, module, config) } fn optimize_thin( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, thin: ThinModule, ) -> ModuleCodegen { - back::lto::optimize_thin_module(thin, cgcx) + back::lto::optimize_thin_module(cgcx, shared_emitter, thin) } fn codegen( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - back::write::codegen(cgcx, module, config) + back::write::codegen(cgcx, shared_emitter, module, config) } fn prepare_thin(module: ModuleCodegen) -> (String, Self::ThinBuffer) { back::lto::prepare_thin(module) diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index e3dc985bf782..ef4c193c4c2a 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -2,6 +2,7 @@ use std::ffi::CString; use std::sync::Arc; use rustc_data_structures::memmap::Mmap; +use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportLevel}; use rustc_middle::ty::TyCtxt; @@ -124,14 +125,15 @@ pub(super) fn exported_symbols_for_lto( symbols_below_threshold } -pub(super) fn check_lto_allowed(cgcx: &CodegenContext) { +pub(super) fn check_lto_allowed( + cgcx: &CodegenContext, + dcx: DiagCtxtHandle<'_>, +) { if cgcx.lto == Lto::ThinLocal { // Crate local LTO is always allowed return; } - let dcx = cgcx.create_dcx(); - // Make sure we actually can run LTO for crate_type in cgcx.crate_types.iter() { if !crate_type_allows_lto(*crate_type) { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index bc7c32931613..76f76c84dbdc 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -15,8 +15,8 @@ use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard}; use rustc_errors::emitter::Emitter; use rustc_errors::translation::Translator; use rustc_errors::{ - Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, FatalErrorMarker, Level, - MultiSpan, Style, Suggestions, + Diag, DiagArgMap, DiagCtxt, DiagCtxtHandle, DiagMessage, ErrCode, FatalError, FatalErrorMarker, + Level, MultiSpan, Style, Suggestions, }; use rustc_fs_util::link_or_copy; use rustc_incremental::{ @@ -348,8 +348,6 @@ pub struct CodegenContext { pub split_dwarf_kind: rustc_session::config::SplitDwarfKind, pub pointer_size: Size, - /// Emitter to use for diagnostics produced during codegen. - pub diag_emitter: SharedEmitter, /// LLVM optimizations for which we want to print remarks. pub remark: Passes, /// Directory into which should the LLVM optimization remarks be written. @@ -364,14 +362,9 @@ pub struct CodegenContext { pub parallel: bool, } -impl CodegenContext { - pub fn create_dcx(&self) -> DiagCtxt { - DiagCtxt::new(Box::new(self.diag_emitter.clone())) - } -} - fn generate_thin_lto_work( cgcx: &CodegenContext, + dcx: DiagCtxtHandle<'_>, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], needs_thin_lto: Vec<(String, B::ThinBuffer)>, @@ -381,6 +374,7 @@ fn generate_thin_lto_work( let (lto_modules, copy_jobs) = B::run_thin_lto( cgcx, + dcx, exported_symbols_for_lto, each_linked_rlib_for_lto, needs_thin_lto, @@ -825,14 +819,12 @@ pub(crate) fn compute_per_cgu_lto_type( fn execute_optimize_work_item( cgcx: &CodegenContext, + shared_emitter: SharedEmitter, mut module: ModuleCodegen, ) -> WorkItemResult { let _timer = cgcx.prof.generic_activity_with_arg("codegen_module_optimize", &*module.name); - let dcx = cgcx.create_dcx(); - let dcx = dcx.handle(); - - B::optimize(cgcx, dcx, &mut module, &cgcx.module_config); + B::optimize(cgcx, &shared_emitter, &mut module, &cgcx.module_config); // After we've done the initial round of optimizations we need to // decide whether to synchronously codegen this module or ship it @@ -853,7 +845,7 @@ fn execute_optimize_work_item( match lto_type { ComputedLtoType::No => { - let module = B::codegen(cgcx, module, &cgcx.module_config); + let module = B::codegen(cgcx, &shared_emitter, module, &cgcx.module_config); WorkItemResult::Finished(module) } ComputedLtoType::Thin => { @@ -883,12 +875,16 @@ fn execute_optimize_work_item( fn execute_copy_from_cache_work_item( cgcx: &CodegenContext, + shared_emitter: SharedEmitter, module: CachedModuleCodegen, ) -> CompiledModule { let _timer = cgcx .prof .generic_activity_with_arg("codegen_copy_artifacts_from_incr_cache", &*module.name); + let dcx = DiagCtxt::new(Box::new(shared_emitter)); + let dcx = dcx.handle(); + let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap(); let mut links_from_incr_cache = Vec::new(); @@ -907,11 +903,7 @@ fn execute_copy_from_cache_work_item( Some(output_path) } Err(error) => { - cgcx.create_dcx().handle().emit_err(errors::CopyPathBuf { - source_file, - output_path, - error, - }); + dcx.emit_err(errors::CopyPathBuf { source_file, output_path, error }); None } } @@ -954,7 +946,7 @@ fn execute_copy_from_cache_work_item( let bytecode = load_from_incr_cache(module_config.emit_bc, OutputType::Bitcode); let object = load_from_incr_cache(should_emit_obj, OutputType::Object); if should_emit_obj && object.is_none() { - cgcx.create_dcx().handle().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name }) + dcx.emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name }) } CompiledModule { @@ -971,6 +963,7 @@ fn execute_copy_from_cache_work_item( fn do_fat_lto( cgcx: &CodegenContext, + shared_emitter: SharedEmitter, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], mut needs_fat_lto: Vec>, @@ -978,7 +971,10 @@ fn do_fat_lto( ) -> CompiledModule { let _timer = cgcx.prof.verbose_generic_activity("LLVM_fatlto"); - check_lto_allowed(&cgcx); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); + let dcx = dcx.handle(); + + check_lto_allowed(&cgcx, dcx); for (module, wp) in import_only_modules { needs_fat_lto.push(FatLtoInput::Serialized { name: wp.cgu_name, buffer: module }) @@ -986,15 +982,17 @@ fn do_fat_lto( let module = B::run_and_optimize_fat_lto( cgcx, + &shared_emitter, exported_symbols_for_lto, each_linked_rlib_for_lto, needs_fat_lto, ); - B::codegen(cgcx, module, &cgcx.module_config) + B::codegen(cgcx, &shared_emitter, module, &cgcx.module_config) } fn do_thin_lto<'a, B: ExtraBackendMethods>( cgcx: &'a CodegenContext, + shared_emitter: SharedEmitter, exported_symbols_for_lto: Arc>, each_linked_rlib_for_lto: Vec, needs_thin_lto: Vec<(String, ::ThinBuffer)>, @@ -1005,7 +1003,10 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( ) -> Vec { let _timer = cgcx.prof.verbose_generic_activity("LLVM_thinlto"); - check_lto_allowed(&cgcx); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); + let dcx = dcx.handle(); + + check_lto_allowed(&cgcx, dcx); let (coordinator_send, coordinator_receive) = channel(); @@ -1030,6 +1031,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( // we don't worry about tokens. for (work, cost) in generate_thin_lto_work( cgcx, + dcx, &exported_symbols_for_lto, &each_linked_rlib_for_lto, needs_thin_lto, @@ -1071,7 +1073,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( while used_token_count < tokens.len() + 1 && let Some((item, _)) = work_items.pop() { - spawn_thin_lto_work(&cgcx, coordinator_send.clone(), item); + spawn_thin_lto_work(&cgcx, shared_emitter.clone(), coordinator_send.clone(), item); used_token_count += 1; } } else { @@ -1095,7 +1097,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( } Err(e) => { let msg = &format!("failed to acquire jobserver token: {e}"); - cgcx.diag_emitter.fatal(msg); + shared_emitter.fatal(msg); codegen_aborted = Some(FatalError); } }, @@ -1133,12 +1135,13 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( fn execute_thin_lto_work_item( cgcx: &CodegenContext, + shared_emitter: SharedEmitter, module: lto::ThinModule, ) -> CompiledModule { let _timer = cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", module.name()); - let module = B::optimize_thin(cgcx, module); - B::codegen(cgcx, module, &cgcx.module_config) + let module = B::optimize_thin(cgcx, &shared_emitter, module); + B::codegen(cgcx, &shared_emitter, module, &cgcx.module_config) } /// Messages sent to the coordinator. @@ -1291,7 +1294,6 @@ fn start_executing_work( remark: sess.opts.cg.remark.clone(), remark_dir, incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()), - diag_emitter: shared_emitter.clone(), output_filenames: Arc::clone(tcx.output_filenames(())), module_config: regular_config, tm_factory: backend.target_machine_factory(tcx.sess, ol, backend_features), @@ -1488,10 +1490,7 @@ fn start_executing_work( let mut llvm_start_time: Option> = None; if let Some(allocator_module) = &mut allocator_module { - let dcx = cgcx.create_dcx(); - let dcx = dcx.handle(); - - B::optimize(&cgcx, dcx, allocator_module, &allocator_config); + B::optimize(&cgcx, &shared_emitter, allocator_module, &allocator_config); } // Run the message loop while there's still anything that needs message @@ -1529,7 +1528,13 @@ fn start_executing_work( let (item, _) = work_items.pop().expect("queue empty - queue_full_enough() broken?"); main_thread_state = MainThreadState::Lending; - spawn_work(&cgcx, coordinator_send.clone(), &mut llvm_start_time, item); + spawn_work( + &cgcx, + shared_emitter.clone(), + coordinator_send.clone(), + &mut llvm_start_time, + item, + ); } } } else if codegen_state == Completed { @@ -1547,7 +1552,13 @@ fn start_executing_work( MainThreadState::Idle => { if let Some((item, _)) = work_items.pop() { main_thread_state = MainThreadState::Lending; - spawn_work(&cgcx, coordinator_send.clone(), &mut llvm_start_time, item); + spawn_work( + &cgcx, + shared_emitter.clone(), + coordinator_send.clone(), + &mut llvm_start_time, + item, + ); } else { // There is no unstarted work, so let the main thread // take over for a running worker. Otherwise the @@ -1583,7 +1594,13 @@ fn start_executing_work( while running_with_own_token < tokens.len() && let Some((item, _)) = work_items.pop() { - spawn_work(&cgcx, coordinator_send.clone(), &mut llvm_start_time, item); + spawn_work( + &cgcx, + shared_emitter.clone(), + coordinator_send.clone(), + &mut llvm_start_time, + item, + ); running_with_own_token += 1; } } @@ -1726,6 +1743,7 @@ fn start_executing_work( // This uses the implicit token let module = do_fat_lto( &cgcx, + shared_emitter.clone(), &exported_symbols_for_lto, &each_linked_rlib_file_for_lto, needs_fat_lto, @@ -1745,6 +1763,7 @@ fn start_executing_work( compiled_modules.extend(do_thin_lto( &cgcx, + shared_emitter.clone(), exported_symbols_for_lto, each_linked_rlib_file_for_lto, needs_thin_lto, @@ -1759,8 +1778,9 @@ fn start_executing_work( Ok(CompiledModules { modules: compiled_modules, - allocator_module: allocator_module - .map(|allocator_module| B::codegen(&cgcx, allocator_module, &allocator_config)), + allocator_module: allocator_module.map(|allocator_module| { + B::codegen(&cgcx, &shared_emitter, allocator_module, &allocator_config) + }), }) }) .expect("failed to spawn coordinator thread"); @@ -1829,6 +1849,7 @@ pub(crate) struct WorkerFatalError; fn spawn_work<'a, B: ExtraBackendMethods>( cgcx: &'a CodegenContext, + shared_emitter: SharedEmitter, coordinator_send: Sender>, llvm_start_time: &mut Option>, work: WorkItem, @@ -1841,10 +1862,10 @@ fn spawn_work<'a, B: ExtraBackendMethods>( B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || { let result = std::panic::catch_unwind(AssertUnwindSafe(|| match work { - WorkItem::Optimize(m) => execute_optimize_work_item(&cgcx, m), - WorkItem::CopyPostLtoArtifacts(m) => { - WorkItemResult::Finished(execute_copy_from_cache_work_item(&cgcx, m)) - } + WorkItem::Optimize(m) => execute_optimize_work_item(&cgcx, shared_emitter, m), + WorkItem::CopyPostLtoArtifacts(m) => WorkItemResult::Finished( + execute_copy_from_cache_work_item(&cgcx, shared_emitter, m), + ), })); let msg = match result { @@ -1866,6 +1887,7 @@ fn spawn_work<'a, B: ExtraBackendMethods>( fn spawn_thin_lto_work<'a, B: ExtraBackendMethods>( cgcx: &'a CodegenContext, + shared_emitter: SharedEmitter, coordinator_send: Sender, work: ThinLtoWorkItem, ) { @@ -1873,8 +1895,10 @@ fn spawn_thin_lto_work<'a, B: ExtraBackendMethods>( B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || { let result = std::panic::catch_unwind(AssertUnwindSafe(|| match work { - ThinLtoWorkItem::CopyPostLtoArtifacts(m) => execute_copy_from_cache_work_item(&cgcx, m), - ThinLtoWorkItem::ThinLto(m) => execute_thin_lto_work_item(&cgcx, m), + ThinLtoWorkItem::CopyPostLtoArtifacts(m) => { + execute_copy_from_cache_work_item(&cgcx, shared_emitter, m) + } + ThinLtoWorkItem::ThinLto(m) => execute_thin_lto_work_item(&cgcx, shared_emitter, m), })); let msg = match result { diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index 1ac1d7ef2e2e..e1d23841118c 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -4,7 +4,7 @@ use rustc_errors::DiagCtxtHandle; use rustc_middle::dep_graph::WorkProduct; use crate::back::lto::{SerializedModule, ThinModule}; -use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig}; +use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter}; use crate::{CompiledModule, ModuleCodegen}; pub trait WriteBackendMethods: Clone + 'static { @@ -19,6 +19,7 @@ pub trait WriteBackendMethods: Clone + 'static { /// if necessary and running any further optimizations fn run_and_optimize_fat_lto( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, @@ -28,6 +29,7 @@ pub trait WriteBackendMethods: Clone + 'static { /// can simply be copied over from the incr. comp. cache. fn run_thin_lto( cgcx: &CodegenContext, + dcx: DiagCtxtHandle<'_>, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, Self::ThinBuffer)>, @@ -37,16 +39,18 @@ pub trait WriteBackendMethods: Clone + 'static { fn print_statistics(&self); fn optimize( cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, + shared_emitter: &SharedEmitter, module: &mut ModuleCodegen, config: &ModuleConfig, ); fn optimize_thin( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, thin: ThinModule, ) -> ModuleCodegen; fn codegen( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule; From 67c61cefaf87cb842b2248935dcc481faad21b14 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Oct 2025 09:39:13 +0000 Subject: [PATCH 0112/3801] Remove opts field from CodegenContext --- src/back/lto.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index 404064fb7a06..08c36d2b7318 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -290,7 +290,7 @@ pub(crate) fn run_thin( let dcx = cgcx.create_dcx(); let dcx = dcx.handle(); let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx); - if cgcx.opts.cg.linker_plugin_lto.enabled() { + if cgcx.use_linker_plugin_lto { unreachable!( "We should never reach this case if the LTO step \ is deferred to the linker" From b13bb4b2da208c2c26d000354816400243df1b4a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Nov 2025 15:26:47 +0000 Subject: [PATCH 0113/3801] Move LTO to OngoingCodegen::join --- compiler/rustc_codegen_ssa/src/back/write.rs | 140 +++++++++++++++---- compiler/rustc_driver_impl/src/lib.rs | 20 +-- compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_span/src/fatal_error.rs | 17 +++ 4 files changed, 131 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 76f76c84dbdc..ddcd8decf303 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -16,7 +16,7 @@ use rustc_errors::emitter::Emitter; use rustc_errors::translation::Translator; use rustc_errors::{ Diag, DiagArgMap, DiagCtxt, DiagCtxtHandle, DiagMessage, ErrCode, FatalError, FatalErrorMarker, - Level, MultiSpan, Style, Suggestions, + Level, MultiSpan, Style, Suggestions, catch_fatal_errors, }; use rustc_fs_util::link_or_copy; use rustc_incremental::{ @@ -403,6 +403,29 @@ struct CompiledModules { allocator_module: Option, } +enum MaybeLtoModules { + NoLto { + modules: Vec, + allocator_module: Option, + }, + FatLto { + cgcx: CodegenContext, + exported_symbols_for_lto: Arc>, + each_linked_rlib_file_for_lto: Vec, + needs_fat_lto: Vec>, + lto_import_only_modules: + Vec<(SerializedModule<::ModuleBuffer>, WorkProduct)>, + }, + ThinLto { + cgcx: CodegenContext, + exported_symbols_for_lto: Arc>, + each_linked_rlib_file_for_lto: Vec, + needs_thin_lto: Vec<(String, ::ThinBuffer)>, + lto_import_only_modules: + Vec<(SerializedModule<::ModuleBuffer>, WorkProduct)>, + }, +} + fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool { let sess = tcx.sess; sess.opts.cg.embed_bitcode @@ -1239,7 +1262,7 @@ fn start_executing_work( allocator_config: Arc, mut allocator_module: Option>, coordinator_send: Sender>, -) -> thread::JoinHandle> { +) -> thread::JoinHandle, ()>> { let sess = tcx.sess; let mut each_linked_rlib_for_lto = Vec::new(); @@ -1740,43 +1763,43 @@ fn start_executing_work( needs_fat_lto.push(FatLtoInput::InMemory(allocator_module)); } - // This uses the implicit token - let module = do_fat_lto( - &cgcx, - shared_emitter.clone(), - &exported_symbols_for_lto, - &each_linked_rlib_file_for_lto, + return Ok(MaybeLtoModules::FatLto { + cgcx, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, needs_fat_lto, lto_import_only_modules, - ); - compiled_modules.push(module); + }); } else if !needs_thin_lto.is_empty() || !lto_import_only_modules.is_empty() { assert!(compiled_modules.is_empty()); assert!(needs_fat_lto.is_empty()); - if cgcx.lto != Lto::ThinLocal { + if cgcx.lto == Lto::ThinLocal { + compiled_modules.extend(do_thin_lto( + &cgcx, + shared_emitter.clone(), + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_thin_lto, + lto_import_only_modules, + )); + } else { if let Some(allocator_module) = allocator_module.take() { let (name, thin_buffer) = B::prepare_thin(allocator_module); needs_thin_lto.push((name, thin_buffer)); } - } - compiled_modules.extend(do_thin_lto( - &cgcx, - shared_emitter.clone(), - exported_symbols_for_lto, - each_linked_rlib_file_for_lto, - needs_thin_lto, - lto_import_only_modules, - )); + return Ok(MaybeLtoModules::ThinLto { + cgcx, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_thin_lto, + lto_import_only_modules, + }); + } } - // Regardless of what order these modules completed in, report them to - // the backend in the same order every time to ensure that we're handing - // out deterministic results. - compiled_modules.sort_by(|a, b| a.name.cmp(&b.name)); - - Ok(CompiledModules { + Ok(MaybeLtoModules::NoLto { modules: compiled_modules, allocator_module: allocator_module.map(|allocator_module| { B::codegen(&cgcx, &shared_emitter, allocator_module, &allocator_config) @@ -2074,13 +2097,13 @@ impl SharedEmitterMain { pub struct Coordinator { sender: Sender>, - future: Option>>, + future: Option, ()>>>, // Only used for the Message type. phantom: PhantomData, } impl Coordinator { - fn join(mut self) -> std::thread::Result> { + fn join(mut self) -> std::thread::Result, ()>> { self.future.take().unwrap().join() } } @@ -2111,8 +2134,9 @@ pub struct OngoingCodegen { impl OngoingCodegen { pub fn join(self, sess: &Session) -> (CodegenResults, FxIndexMap) { self.shared_emitter_main.check(sess, true); - let compiled_modules = sess.time("join_worker_thread", || match self.coordinator.join() { - Ok(Ok(compiled_modules)) => compiled_modules, + + let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() { + Ok(Ok(maybe_lto_modules)) => maybe_lto_modules, Ok(Err(())) => { sess.dcx().abort_if_errors(); panic!("expected abort due to worker thread errors") @@ -2124,6 +2148,62 @@ impl OngoingCodegen { sess.dcx().abort_if_errors(); + let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); + + // Catch fatal errors to ensure shared_emitter_main.check() can emit the actual diagnostics + let compiled_modules = catch_fatal_errors(|| match maybe_lto_modules { + MaybeLtoModules::NoLto { modules, allocator_module } => { + drop(shared_emitter); + CompiledModules { modules, allocator_module } + } + MaybeLtoModules::FatLto { + cgcx, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_fat_lto, + lto_import_only_modules, + } => CompiledModules { + modules: vec![do_fat_lto( + &cgcx, + shared_emitter, + &exported_symbols_for_lto, + &each_linked_rlib_file_for_lto, + needs_fat_lto, + lto_import_only_modules, + )], + allocator_module: None, + }, + MaybeLtoModules::ThinLto { + cgcx, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_thin_lto, + lto_import_only_modules, + } => CompiledModules { + modules: do_thin_lto( + &cgcx, + shared_emitter, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_thin_lto, + lto_import_only_modules, + ), + allocator_module: None, + }, + }); + + shared_emitter_main.check(sess, true); + + sess.dcx().abort_if_errors(); + + let mut compiled_modules = + compiled_modules.expect("fatal error emitted but not sent to SharedEmitter"); + + // Regardless of what order these modules completed in, report them to + // the backend in the same order every time to ensure that we're handing + // out deterministic results. + compiled_modules.modules.sort_by(|a, b| a.name.cmp(&b.name)); + let work_products = copy_all_cgu_workproducts_to_incr_comp_cache_dir(sess, &compiled_modules); produce_final_output_artifacts(sess, &compiled_modules, &self.output_filenames); diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 9a3d7cc506cf..cf5a5fdd234c 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -19,7 +19,7 @@ use std::ffi::OsString; use std::fmt::Write as _; use std::fs::{self, File}; use std::io::{self, IsTerminal, Read, Write}; -use std::panic::{self, PanicHookInfo, catch_unwind}; +use std::panic::{self, PanicHookInfo}; use std::path::{Path, PathBuf}; use std::process::{self, Command, Stdio}; use std::sync::OnceLock; @@ -33,10 +33,11 @@ use rustc_codegen_ssa::{CodegenErrors, CodegenResults}; use rustc_data_structures::profiling::{ TimePassesFormat, get_resident_set_size, print_time_passes_entry, }; +pub use rustc_errors::catch_fatal_errors; use rustc_errors::emitter::stderr_destination; use rustc_errors::registry::Registry; use rustc_errors::translation::Translator; -use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, FatalError, PResult, markdown}; +use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, PResult, markdown}; use rustc_feature::find_gated_cfg; // This avoids a false positive with `-Wunused_crate_dependencies`. // `rust_index` isn't used in this crate's code, but it must be named in the @@ -1306,21 +1307,6 @@ fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> { parser.parse_inner_attributes() } -/// Runs a closure and catches unwinds triggered by fatal errors. -/// -/// The compiler currently unwinds with a special sentinel value to abort -/// compilation on fatal errors. This function catches that sentinel and turns -/// the panic into a `Result` instead. -pub fn catch_fatal_errors R, R>(f: F) -> Result { - catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| { - if value.is::() { - FatalError - } else { - panic::resume_unwind(value); - } - }) -} - /// Variant of `catch_fatal_errors` for the `interface::Result` return type /// that also computes the exit code. pub fn catch_with_exit_code(f: impl FnOnce()) -> i32 { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index bbdda155496f..ada32bf0c283 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -68,7 +68,7 @@ pub use rustc_lint_defs::{Applicability, listify, pluralize}; use rustc_lint_defs::{Lint, LintExpectationId}; use rustc_macros::{Decodable, Encodable}; pub use rustc_span::ErrorGuaranteed; -pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker}; +pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors}; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, DUMMY_SP, Loc, Span}; pub use snippet::Style; diff --git a/compiler/rustc_span/src/fatal_error.rs b/compiler/rustc_span/src/fatal_error.rs index 26c5711099c6..5e2d82681a11 100644 --- a/compiler/rustc_span/src/fatal_error.rs +++ b/compiler/rustc_span/src/fatal_error.rs @@ -3,6 +3,8 @@ #[must_use] pub struct FatalError; +use std::panic; + pub use rustc_data_structures::FatalErrorMarker; // Don't implement Send on FatalError. This makes it impossible to `panic_any!(FatalError)`. @@ -22,3 +24,18 @@ impl std::fmt::Display for FatalError { } impl std::error::Error for FatalError {} + +/// Runs a closure and catches unwinds triggered by fatal errors. +/// +/// The compiler currently unwinds with a special sentinel value to abort +/// compilation on fatal errors. This function catches that sentinel and turns +/// the panic into a `Result` instead. +pub fn catch_fatal_errors R, R>(f: F) -> Result { + panic::catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| { + if value.is::() { + FatalError + } else { + panic::resume_unwind(value); + } + }) +} From 385590e9dc85761402f278c61fd081c24c184cb6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Nov 2025 15:08:09 +0000 Subject: [PATCH 0114/3801] Remove SharedEmitter from CodegenContext --- src/back/lto.rs | 12 +++++------- src/back/write.rs | 8 ++++++-- src/lib.rs | 14 +++++++++----- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index 08c36d2b7318..24be3ee4c34d 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -26,11 +26,11 @@ use std::sync::atomic::Ordering; use gccjit::{Context, OutputKind}; use object::read::archive::ArchiveFile; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared}; -use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; +use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, SharedEmitter}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file}; use rustc_data_structures::memmap::Mmap; -use rustc_errors::DiagCtxtHandle; +use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_log::tracing::info; use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; @@ -112,10 +112,11 @@ fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> { /// for further optimization. pub(crate) fn run_fat( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx); /*let symbols_below_threshold = @@ -283,12 +284,11 @@ impl ModuleBufferMethods for ModuleBuffer { /// can simply be copied over from the incr. comp. cache. pub(crate) fn run_thin( cgcx: &CodegenContext, + dcx: DiagCtxtHandle<'_>, each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> (Vec>, Vec) { - let dcx = cgcx.create_dcx(); - let dcx = dcx.handle(); let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx); if cgcx.use_linker_plugin_lto { unreachable!( @@ -522,8 +522,6 @@ pub fn optimize_thin_module( thin_module: ThinModule, _cgcx: &CodegenContext, ) -> ModuleCodegen { - //let dcx = cgcx.create_dcx(); - //let module_name = &thin_module.shared.module_names[thin_module.idx]; /*let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap()); let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&dcx, e))?;*/ diff --git a/src/back/write.rs b/src/back/write.rs index eae0f2aa00f6..b6223c5be370 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -2,8 +2,11 @@ use std::{env, fs}; use gccjit::{Context, OutputKind}; use rustc_codegen_ssa::back::link::ensure_removed; -use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; +use rustc_codegen_ssa::back::write::{ + BitcodeSection, CodegenContext, EmitObj, ModuleConfig, SharedEmitter, +}; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; +use rustc_errors::DiagCtxt; use rustc_fs_util::link_or_copy; use rustc_log::tracing::debug; use rustc_session::config::OutputType; @@ -15,10 +18,11 @@ use crate::{GccCodegenBackend, GccContext, LtoMode}; pub(crate) fn codegen( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); let _timer = cgcx.prof.generic_activity_with_arg("GCC_module_codegen", &*module.name); diff --git a/src/lib.rs b/src/lib.rs index 409b7886740a..5a2ec0a2fc68 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,7 +82,7 @@ use gccjit::{TargetInfo, Version}; use rustc_ast::expand::allocator::AllocatorMethod; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ - CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn, + CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn, }; use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::target_features::cfg_target_feature; @@ -371,23 +371,25 @@ impl WriteBackendMethods for GccCodegenBackend { fn run_and_optimize_fat_lto( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, // FIXME(bjorn3): Limit LTO exports to these symbols _exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - back::lto::run_fat(cgcx, each_linked_rlib_for_lto, modules) + back::lto::run_fat(cgcx, shared_emitter, each_linked_rlib_for_lto, modules) } fn run_thin_lto( cgcx: &CodegenContext, + dcx: DiagCtxtHandle<'_>, // FIXME(bjorn3): Limit LTO exports to these symbols _exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, Self::ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> (Vec>, Vec) { - back::lto::run_thin(cgcx, each_linked_rlib_for_lto, modules, cached_modules) + back::lto::run_thin(cgcx, dcx, each_linked_rlib_for_lto, modules, cached_modules) } fn print_pass_timings(&self) { @@ -400,7 +402,7 @@ impl WriteBackendMethods for GccCodegenBackend { fn optimize( _cgcx: &CodegenContext, - _dcx: DiagCtxtHandle<'_>, + _shared_emitter: &SharedEmitter, module: &mut ModuleCodegen, config: &ModuleConfig, ) { @@ -409,6 +411,7 @@ impl WriteBackendMethods for GccCodegenBackend { fn optimize_thin( cgcx: &CodegenContext, + _shared_emitter: &SharedEmitter, thin: ThinModule, ) -> ModuleCodegen { back::lto::optimize_thin_module(thin, cgcx) @@ -416,10 +419,11 @@ impl WriteBackendMethods for GccCodegenBackend { fn codegen( cgcx: &CodegenContext, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - back::write::codegen(cgcx, module, config) + back::write::codegen(cgcx, shared_emitter, module, config) } fn prepare_thin(module: ModuleCodegen) -> (String, Self::ThinBuffer) { From c15b8f6c33db4594f783a4f0e55766c19aa85af2 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Sun, 23 Nov 2025 20:33:40 -0600 Subject: [PATCH 0115/3801] Add additional LLDB plugin example --- src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md | 3 +++ src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md index 301dda9778d5..e104f1d24532 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md @@ -15,6 +15,9 @@ Here are some existing implementations of LLDB's plugin API: * [Apple's fork with support for Swift](https://github.com/swiftlang/llvm-project) * [CodeLLDB's former fork with support for Rust](https://archive.softwareheritage.org/browse/origin/directory/?branch=refs/heads/codelldb/16.x&origin_url=https://github.com/vadimcn/llvm-project&path=lldb/source/Plugins/TypeSystem/Rust×tamp=2023-09-11T04:55:10Z) * [A work in progress reimplementation of Rust support](https://github.com/Walnut356/llvm-project/tree/lldbrust/19.x) +* [A Rust expression parser plugin](https://github.com/tromey/lldb/tree/a0fc10ce0dacb3038b7302fff9f6cb8cb34b37c6/source/Plugins/ExpressionParser/Rust). +This was written before the `TypeSystem` API was created. Due to the freeform nature of expression parsing, the +underlyng lexing, parsing, function calling, etc. should still offer valuable insights. ## Rust Support and TypeSystemClang diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md index 00a03e3657f1..73fa68d36076 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -56,7 +56,7 @@ Using the `const` qualifier to denote non-`mut` poses potential issues due to LL optimizations. In short, LLDB attempts to cache the child-values of variables (e.g. struct fields, array elements) when stepping through code. A heuristic is used to determine which values are safely cache-able, and `const` is part of that heuristic. Research has not been done into how this would -interact with things like Rust's interrior mutability constructs. +interact with things like Rust's interior mutability constructs. ### DWARF vs PDB From d60e7cf94b514897c4185ebab08438af281a464b Mon Sep 17 00:00:00 2001 From: chenx97 Date: Thu, 30 Oct 2025 20:47:36 +0800 Subject: [PATCH 0116/3801] callconv: adapt mips padding logic to mips64 MIPS64 needs to put a padding argument before an aggregate argument when this argument is in an odd-number position, starting from 0, and has an alignment of 16 bytes or higher, e.g. `void foo(int a, max_align_t b);` is the same as `void foo(int a, long _padding, max_align_t b);` This fix uses an i32 padding, but it should work just fine because i32 is aligned like i64 for arguments. --- compiler/rustc_target/src/callconv/mips64.rs | 115 ++++++++++--------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_target/src/callconv/mips64.rs b/compiler/rustc_target/src/callconv/mips64.rs index a4e94ce81605..4fafa7b3a5e2 100644 --- a/compiler/rustc_target/src/callconv/mips64.rs +++ b/compiler/rustc_target/src/callconv/mips64.rs @@ -34,7 +34,7 @@ where } } -fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>) +fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, offset: &mut Size) where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, @@ -70,77 +70,82 @@ where ret.cast_to(Uniform::new(Reg::i64(), size)); } else { ret.make_indirect(); + *offset += cx.data_layout().pointer_size(); } } -fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) +fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, offset: &mut Size) where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { - if !arg.layout.is_aggregate() { - extend_integer_width_mips(arg, 64); - return; - } - if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { - arg.make_indirect(); - return; - } - let dl = cx.data_layout(); let size = arg.layout.size; let mut prefix = [None; 8]; let mut prefix_index = 0; - match arg.layout.fields { - FieldsShape::Primitive => unreachable!(), - FieldsShape::Array { .. } => { - // Arrays are passed indirectly - arg.make_indirect(); - return; - } - FieldsShape::Union(_) => { - // Unions and are always treated as a series of 64-bit integer chunks - } - FieldsShape::Arbitrary { .. } => { - // Structures are split up into a series of 64-bit integer chunks, but any aligned - // doubles not part of another aggregate are passed as floats. - let mut last_offset = Size::ZERO; + // Detect need for padding + let align = Ord::clamp(arg.layout.align.abi, dl.i64_align, dl.i128_align); + let pad_i32 = !offset.is_aligned(align); - for i in 0..arg.layout.fields.count() { - let field = arg.layout.field(cx, i); - let offset = arg.layout.fields.offset(i); + if !arg.layout.is_aggregate() { + extend_integer_width_mips(arg, 64); + } else if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { + arg.make_indirect(); + } else { + match arg.layout.fields { + FieldsShape::Primitive => unreachable!(), + FieldsShape::Array { .. } => { + // Arrays are passed indirectly + arg.make_indirect(); + } + FieldsShape::Union(_) => { + // Unions and are always treated as a series of 64-bit integer chunks + } + FieldsShape::Arbitrary { .. } => { + // Structures are split up into a series of 64-bit integer chunks, but any aligned + // doubles not part of another aggregate are passed as floats. + let mut last_offset = Size::ZERO; - // We only care about aligned doubles - if let BackendRepr::Scalar(scalar) = field.backend_repr { - if scalar.primitive() == Primitive::Float(Float::F64) { - if offset.is_aligned(dl.f64_align) { - // Insert enough integers to cover [last_offset, offset) - assert!(last_offset.is_aligned(dl.f64_align)); - for _ in 0..((offset - last_offset).bits() / 64) - .min((prefix.len() - prefix_index) as u64) - { - prefix[prefix_index] = Some(Reg::i64()); + for i in 0..arg.layout.fields.count() { + let field = arg.layout.field(cx, i); + let offset = arg.layout.fields.offset(i); + + // We only care about aligned doubles + if let BackendRepr::Scalar(scalar) = field.backend_repr { + if scalar.primitive() == Primitive::Float(Float::F64) { + if offset.is_aligned(dl.f64_align) { + // Insert enough integers to cover [last_offset, offset) + assert!(last_offset.is_aligned(dl.f64_align)); + for _ in 0..((offset - last_offset).bits() / 64) + .min((prefix.len() - prefix_index) as u64) + { + prefix[prefix_index] = Some(Reg::i64()); + prefix_index += 1; + } + + if prefix_index == prefix.len() { + break; + } + + prefix[prefix_index] = Some(Reg::f64()); prefix_index += 1; + last_offset = offset + Reg::f64().size; } - - if prefix_index == prefix.len() { - break; - } - - prefix[prefix_index] = Some(Reg::f64()); - prefix_index += 1; - last_offset = offset + Reg::f64().size; } } } } - } - }; + }; - // Extract first 8 chunks as the prefix - let rest_size = size - Size::from_bytes(8) * prefix_index as u64; - arg.cast_to(CastTarget::prefixed(prefix, Uniform::new(Reg::i64(), rest_size))); + // Extract first 8 chunks as the prefix + let rest_size = size - Size::from_bytes(8) * prefix_index as u64; + arg.cast_to_and_pad_i32( + CastTarget::prefixed(prefix, Uniform::new(Reg::i64(), rest_size)), + pad_i32, + ); + } + *offset = offset.align_to(align) + size.align_to(align); } pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) @@ -148,14 +153,18 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + // mips64 argument passing is also affected by the alignment of aggregates. + // see mips.rs for how the offset is used + let mut offset = Size::ZERO; + if !fn_abi.ret.is_ignore() && fn_abi.ret.layout.is_sized() { - classify_ret(cx, &mut fn_abi.ret); + classify_ret(cx, &mut fn_abi.ret, &mut offset); } for arg in fn_abi.args.iter_mut() { if arg.is_ignore() || !arg.layout.is_sized() { continue; } - classify_arg(cx, arg); + classify_arg(cx, arg, &mut offset); } } From 5f623260818ba453bd969bf3f259e1e1e506dd45 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 24 Nov 2025 04:18:20 +0000 Subject: [PATCH 0117/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to d3e1ccdf40ae7b7a6dc81edc073d80dad7b66f75. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 8c841aac8eb6..08324790e311 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -cc328c12382f05d8ddf6ffc8139deb7985270ad8 +d3e1ccdf40ae7b7a6dc81edc073d80dad7b66f75 From 6a11d0be8996ac56aa6b3d6905bbc99a1a0ecca5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 24 Nov 2025 14:54:22 +0000 Subject: [PATCH 0118/3801] Don't leak sysroot crates through dependencies Previously if a dependency of the current crate depended on a sysroot crate, then extern crate would in the current crate would pick the first loaded version of said sysroot crate even in case of an ambiguity. This is surprising and brittle. For -Ldependency= we already blocked this, but the fix didn't account for sysroot crates. --- compiler/rustc_metadata/src/creader.rs | 29 ++++---------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 4e2e1e21ec6d..85fa8cda2229 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -519,7 +519,6 @@ impl CStore { externs: &Externs, name: Symbol, hash: Option, - kind: PathKind, ) -> Option { for (cnum, data) in self.iter_crate_data() { if data.name() != name { @@ -561,27 +560,9 @@ impl CStore { continue; } - // Alright, so we've gotten this far which means that `data` has the - // right name, we don't have a hash, and we don't have a --extern - // pointing for ourselves. We're still not quite yet done because we - // have to make sure that this crate was found in the crate lookup - // path (this is a top-level dependency) as we don't want to - // implicitly load anything inside the dependency lookup path. - let prev_kind = source - .dylib - .as_ref() - .or(source.rlib.as_ref()) - .or(source.rmeta.as_ref()) - .expect("No sources for crate") - .1; - if kind.matches(prev_kind) { - return Some(cnum); - } else { - debug!( - "failed to load existing crate {}; kind {:?} did not match prev_kind {:?}", - name, kind, prev_kind - ); - } + // While the crate name matched, no --extern crate_name=path matched. It is possible + // that we have already loaded the target crate, but if that happens CStore::load will + // indicate so and we gracefully handle this, just potentially wasting a bit of time. } None @@ -818,9 +799,7 @@ impl CStore { let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate }; let private_dep = origin.private_dep(); - let result = if let Some(cnum) = - self.existing_match(&tcx.sess.opts.externs, name, hash, path_kind) - { + let result = if let Some(cnum) = self.existing_match(&tcx.sess.opts.externs, name, hash) { (LoadResult::Previous(cnum), None) } else { info!("falling back to a load"); From d7860a51079e6b4cee826ade1f9fd0ccb6ba31ad Mon Sep 17 00:00:00 2001 From: reucru01 Date: Fri, 24 Oct 2025 10:15:01 +0100 Subject: [PATCH 0119/3801] Fixes generator, neon intrinics now build in debug This fixes build issues associated with failing LLVM const param assertions --- .../src/arm_shared/neon/generated.rs | 1144 ++++++----------- .../spec/neon/arm_shared.spec.yml | 333 ++--- .../crates/stdarch-gen-arm/src/expression.rs | 17 + .../crates/stdarch-gen-arm/src/intrinsic.rs | 3 +- 4 files changed, 572 insertions(+), 925 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index b5ba792b18ae..c1bd70175c4c 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -15137,268 +15137,104 @@ pub unsafe fn vld1q_f16_x4(a: *const f16) -> float16x8x4_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))] pub unsafe fn vld1_f32(ptr: *const f32) -> float32x2_t { - transmute(vld1_v2f32( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))] -pub unsafe fn vld1_f32(ptr: *const f32) -> float32x2_t { - let ret_val: float32x2_t = transmute(vld1_v2f32( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1_v2f32::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))] pub unsafe fn vld1q_f32(ptr: *const f32) -> float32x4_t { - transmute(vld1q_v4f32( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))] -pub unsafe fn vld1q_f32(ptr: *const f32) -> float32x4_t { - let ret_val: float32x4_t = transmute(vld1q_v4f32( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [3, 2, 1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1q_v4f32::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] pub unsafe fn vld1_u8(ptr: *const u8) -> uint8x8_t { - transmute(vld1_v8i8( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] -pub unsafe fn vld1_u8(ptr: *const u8) -> uint8x8_t { - let ret_val: uint8x8_t = transmute(vld1_v8i8( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [7, 6, 5, 4, 3, 2, 1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1_v8i8::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] pub unsafe fn vld1q_u8(ptr: *const u8) -> uint8x16_t { - transmute(vld1q_v16i8( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] -pub unsafe fn vld1q_u8(ptr: *const u8) -> uint8x16_t { - let ret_val: uint8x16_t = transmute(vld1q_v16i8( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!( - ret_val, - ret_val, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1q_v16i8::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] pub unsafe fn vld1_u16(ptr: *const u16) -> uint16x4_t { - transmute(vld1_v4i16( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] -pub unsafe fn vld1_u16(ptr: *const u16) -> uint16x4_t { - let ret_val: uint16x4_t = transmute(vld1_v4i16( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [3, 2, 1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1_v4i16::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] pub unsafe fn vld1q_u16(ptr: *const u16) -> uint16x8_t { - transmute(vld1q_v8i16( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] -pub unsafe fn vld1q_u16(ptr: *const u16) -> uint16x8_t { - let ret_val: uint16x8_t = transmute(vld1q_v8i16( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [7, 6, 5, 4, 3, 2, 1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1q_v8i16::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))] pub unsafe fn vld1_u32(ptr: *const u32) -> uint32x2_t { - transmute(vld1_v2i32( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))] -pub unsafe fn vld1_u32(ptr: *const u32) -> uint32x2_t { - let ret_val: uint32x2_t = transmute(vld1_v2i32( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1_v2i32::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))] pub unsafe fn vld1q_u32(ptr: *const u32) -> uint32x4_t { - transmute(vld1q_v4i32( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))] -pub unsafe fn vld1q_u32(ptr: *const u32) -> uint32x4_t { - let ret_val: uint32x4_t = transmute(vld1q_v4i32( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [3, 2, 1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1q_v4i32::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64)"] @@ -15410,212 +15246,86 @@ pub unsafe fn vld1q_u32(ptr: *const u32) -> uint32x4_t { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))] pub unsafe fn vld1_u64(ptr: *const u64) -> uint64x1_t { - transmute(vld1_v1i64( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1_v1i64::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.64"))] pub unsafe fn vld1q_u64(ptr: *const u64) -> uint64x2_t { - transmute(vld1q_v2i64( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.64"))] -pub unsafe fn vld1q_u64(ptr: *const u64) -> uint64x2_t { - let ret_val: uint64x2_t = transmute(vld1q_v2i64( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1q_v2i64::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] pub unsafe fn vld1_p8(ptr: *const p8) -> poly8x8_t { - transmute(vld1_v8i8( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] -pub unsafe fn vld1_p8(ptr: *const p8) -> poly8x8_t { - let ret_val: poly8x8_t = transmute(vld1_v8i8( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [7, 6, 5, 4, 3, 2, 1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1_v8i8::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] pub unsafe fn vld1q_p8(ptr: *const p8) -> poly8x16_t { - transmute(vld1q_v16i8( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] -pub unsafe fn vld1q_p8(ptr: *const p8) -> poly8x16_t { - let ret_val: poly8x16_t = transmute(vld1q_v16i8( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!( - ret_val, - ret_val, - [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1q_v16i8::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] pub unsafe fn vld1_p16(ptr: *const p16) -> poly16x4_t { - transmute(vld1_v4i16( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] -pub unsafe fn vld1_p16(ptr: *const p16) -> poly16x4_t { - let ret_val: poly16x4_t = transmute(vld1_v4i16( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [3, 2, 1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1_v4i16::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] pub unsafe fn vld1q_p16(ptr: *const p16) -> poly16x8_t { - transmute(vld1q_v8i16( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,v7")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] -pub unsafe fn vld1q_p16(ptr: *const p16) -> poly16x8_t { - let ret_val: poly16x8_t = transmute(vld1q_v8i16( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [7, 6, 5, 4, 3, 2, 1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1q_v8i16::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64)"] #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] -#[cfg(target_endian = "little")] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,aes")] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.64"))] pub unsafe fn vld1q_p64(ptr: *const p64) -> poly64x2_t { - transmute(vld1q_v2i64( - ptr as *const i8, - crate::mem::align_of::() as i32, - )) -} -#[doc = "Load multiple single-element structures to one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] -#[inline] -#[cfg(target_endian = "big")] -#[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,aes")] -#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.64"))] -pub unsafe fn vld1q_p64(ptr: *const p64) -> poly64x2_t { - let ret_val: poly64x2_t = transmute(vld1q_v2i64( - ptr as *const i8, - crate::mem::align_of::() as i32, - )); - simd_shuffle!(ret_val, ret_val, [1, 0]) + const ALIGN: i32 = crate::mem::align_of::() as i32; + transmute(vld1q_v2i64::(ptr as *const i8)) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32_x2)"] @@ -16694,7 +16404,8 @@ pub unsafe fn vld1q_p64_x4(a: *const p64) -> poly64x2x4_t { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] pub unsafe fn vld1_s8(ptr: *const i8) -> int8x8_t { - vld1_v8i8(ptr as *const i8, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vld1_v8i8::(ptr as *const i8) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s8)"] @@ -16706,7 +16417,8 @@ pub unsafe fn vld1_s8(ptr: *const i8) -> int8x8_t { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))] pub unsafe fn vld1q_s8(ptr: *const i8) -> int8x16_t { - vld1q_v16i8(ptr as *const i8, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vld1q_v16i8::(ptr as *const i8) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s16)"] @@ -16718,7 +16430,8 @@ pub unsafe fn vld1q_s8(ptr: *const i8) -> int8x16_t { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] pub unsafe fn vld1_s16(ptr: *const i16) -> int16x4_t { - vld1_v4i16(ptr as *const i8, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vld1_v4i16::(ptr as *const i8) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s16)"] @@ -16730,7 +16443,8 @@ pub unsafe fn vld1_s16(ptr: *const i16) -> int16x4_t { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))] pub unsafe fn vld1q_s16(ptr: *const i16) -> int16x8_t { - vld1q_v8i16(ptr as *const i8, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vld1q_v8i16::(ptr as *const i8) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s32)"] @@ -16742,7 +16456,8 @@ pub unsafe fn vld1q_s16(ptr: *const i16) -> int16x8_t { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))] pub unsafe fn vld1_s32(ptr: *const i32) -> int32x2_t { - vld1_v2i32(ptr as *const i8, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vld1_v2i32::(ptr as *const i8) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s32)"] @@ -16754,7 +16469,8 @@ pub unsafe fn vld1_s32(ptr: *const i32) -> int32x2_t { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))] pub unsafe fn vld1q_s32(ptr: *const i32) -> int32x4_t { - vld1q_v4i32(ptr as *const i8, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vld1q_v4i32::(ptr as *const i8) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s64)"] @@ -16766,7 +16482,8 @@ pub unsafe fn vld1q_s32(ptr: *const i32) -> int32x4_t { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))] pub unsafe fn vld1_s64(ptr: *const i64) -> int64x1_t { - vld1_v1i64(ptr as *const i8, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vld1_v1i64::(ptr as *const i8) } #[doc = "Load multiple single-element structures to one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s64)"] @@ -16778,7 +16495,8 @@ pub unsafe fn vld1_s64(ptr: *const i64) -> int64x1_t { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.64"))] pub unsafe fn vld1q_s64(ptr: *const i64) -> int64x2_t { - vld1q_v2i64(ptr as *const i8, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vld1q_v2i64::(ptr as *const i8) } #[doc = "Load multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8_x2)"] @@ -19417,160 +19135,136 @@ pub unsafe fn vld1q_p16_x4(a: *const p16) -> poly16x8x4_t { ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [7, 6, 5, 4, 3, 2, 1, 0]) }; ret_val } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_v1i64)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1_v1i64(a: *const i8, b: i32) -> int64x1_t { +unsafe fn vld1_v1i64(a: *const i8) -> int64x1_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v1i64")] fn _vld1_v1i64(a: *const i8, b: i32) -> int64x1_t; } - _vld1_v1i64(a, b) + _vld1_v1i64(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_v2f32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1_v2f32(a: *const i8, b: i32) -> float32x2_t { +unsafe fn vld1_v2f32(a: *const i8) -> float32x2_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v2f32")] fn _vld1_v2f32(a: *const i8, b: i32) -> float32x2_t; } - _vld1_v2f32(a, b) + _vld1_v2f32(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_v2i32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1_v2i32(a: *const i8, b: i32) -> int32x2_t { +unsafe fn vld1_v2i32(a: *const i8) -> int32x2_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v2i32")] fn _vld1_v2i32(a: *const i8, b: i32) -> int32x2_t; } - _vld1_v2i32(a, b) + _vld1_v2i32(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_v4i16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1_v4i16(a: *const i8, b: i32) -> int16x4_t { +unsafe fn vld1_v4i16(a: *const i8) -> int16x4_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v4i16")] fn _vld1_v4i16(a: *const i8, b: i32) -> int16x4_t; } - _vld1_v4i16(a, b) + _vld1_v4i16(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_v8i8)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1_v8i8(a: *const i8, b: i32) -> int8x8_t { +unsafe fn vld1_v8i8(a: *const i8) -> int8x8_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v8i8")] fn _vld1_v8i8(a: *const i8, b: i32) -> int8x8_t; } - _vld1_v8i8(a, b) + _vld1_v8i8(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_v16i8)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1q_v16i8(a: *const i8, b: i32) -> int8x16_t { +unsafe fn vld1q_v16i8(a: *const i8) -> int8x16_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v16i8")] fn _vld1q_v16i8(a: *const i8, b: i32) -> int8x16_t; } - _vld1q_v16i8(a, b) + _vld1q_v16i8(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_v2i64)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1q_v2i64(a: *const i8, b: i32) -> int64x2_t { +unsafe fn vld1q_v2i64(a: *const i8) -> int64x2_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v2i64")] fn _vld1q_v2i64(a: *const i8, b: i32) -> int64x2_t; } - _vld1q_v2i64(a, b) + _vld1q_v2i64(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_v4f32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1q_v4f32(a: *const i8, b: i32) -> float32x4_t { +unsafe fn vld1q_v4f32(a: *const i8) -> float32x4_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v4f32")] fn _vld1q_v4f32(a: *const i8, b: i32) -> float32x4_t; } - _vld1q_v4f32(a, b) + _vld1q_v4f32(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_v4i32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1q_v4i32(a: *const i8, b: i32) -> int32x4_t { +unsafe fn vld1q_v4i32(a: *const i8) -> int32x4_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v4i32")] fn _vld1q_v4i32(a: *const i8, b: i32) -> int32x4_t; } - _vld1q_v4i32(a, b) + _vld1q_v4i32(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_v8i16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] +#[rustc_legacy_const_generics(1)] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8", ALIGN = 0))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -unsafe fn vld1q_v8i16(a: *const i8, b: i32) -> int16x8_t { +unsafe fn vld1q_v8i16(a: *const i8) -> int16x8_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v8i16")] fn _vld1q_v8i16(a: *const i8, b: i32) -> int16x8_t; } - _vld1q_v8i16(a, b) + _vld1q_v8i16(a, ALIGN) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_v4f16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] @@ -19585,10 +19279,6 @@ unsafe fn vld1_v4f16(a: *const i8, b: i32) -> float16x4_t { } _vld1_v4f16(a, b) } -#[doc = "Load multiple single-element structures to one, two, three, or four registers"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_v8f16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[cfg(target_arch = "arm")] #[target_feature(enable = "neon,v7")] @@ -61060,117 +60750,229 @@ pub fn vsha256su1q_u32(tw0_3: uint32x4_t, w8_11: uint32x4_t, w12_15: uint32x4_t) } unsafe { _vsha256su1q_u32(tw0_3, w8_11, w12_15) } } -#[doc = "Shift Right and Insert (immediate)"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftins_v16i8)"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -fn vshiftins_v16i8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t { +#[rustc_legacy_const_generics(2)] +fn vshiftlins_v16i8(a: int8x16_t, b: int8x16_t) -> int8x16_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v16i8")] - fn _vshiftins_v16i8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t; + fn _vshiftlins_v16i8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t; } - unsafe { _vshiftins_v16i8(a, b, c) } + unsafe { _vshiftlins_v16i8(a, b, const { int8x16_t([N as i8; 16]) }) } } -#[doc = "Shift Right and Insert (immediate)"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftins_v1i64)"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -fn vshiftins_v1i64(a: int64x1_t, b: int64x1_t, c: int64x1_t) -> int64x1_t { +#[rustc_legacy_const_generics(2)] +fn vshiftlins_v1i64(a: int64x1_t, b: int64x1_t) -> int64x1_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v1i64")] - fn _vshiftins_v1i64(a: int64x1_t, b: int64x1_t, c: int64x1_t) -> int64x1_t; + fn _vshiftlins_v1i64(a: int64x1_t, b: int64x1_t, c: int64x1_t) -> int64x1_t; } - unsafe { _vshiftins_v1i64(a, b, c) } + unsafe { _vshiftlins_v1i64(a, b, const { int64x1_t([N as i64; 1]) }) } } -#[doc = "Shift Right and Insert (immediate)"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftins_v2i32)"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -fn vshiftins_v2i32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t { +#[rustc_legacy_const_generics(2)] +fn vshiftlins_v2i32(a: int32x2_t, b: int32x2_t) -> int32x2_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v2i32")] - fn _vshiftins_v2i32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t; + fn _vshiftlins_v2i32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t; } - unsafe { _vshiftins_v2i32(a, b, c) } + unsafe { _vshiftlins_v2i32(a, b, const { int32x2_t([N; 2]) }) } } -#[doc = "Shift Right and Insert (immediate)"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftins_v2i64)"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -fn vshiftins_v2i64(a: int64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t { +#[rustc_legacy_const_generics(2)] +fn vshiftlins_v2i64(a: int64x2_t, b: int64x2_t) -> int64x2_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v2i64")] - fn _vshiftins_v2i64(a: int64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t; + fn _vshiftlins_v2i64(a: int64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t; } - unsafe { _vshiftins_v2i64(a, b, c) } + unsafe { _vshiftlins_v2i64(a, b, const { int64x2_t([N as i64; 2]) }) } } -#[doc = "Shift Right and Insert (immediate)"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftins_v4i16)"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -fn vshiftins_v4i16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t { +#[rustc_legacy_const_generics(2)] +fn vshiftlins_v4i16(a: int16x4_t, b: int16x4_t) -> int16x4_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v4i16")] - fn _vshiftins_v4i16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t; + fn _vshiftlins_v4i16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t; } - unsafe { _vshiftins_v4i16(a, b, c) } + unsafe { _vshiftlins_v4i16(a, b, const { int16x4_t([N as i16; 4]) }) } } -#[doc = "Shift Right and Insert (immediate)"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftins_v4i32)"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -fn vshiftins_v4i32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t { +#[rustc_legacy_const_generics(2)] +fn vshiftlins_v4i32(a: int32x4_t, b: int32x4_t) -> int32x4_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v4i32")] - fn _vshiftins_v4i32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t; + fn _vshiftlins_v4i32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t; } - unsafe { _vshiftins_v4i32(a, b, c) } + unsafe { _vshiftlins_v4i32(a, b, const { int32x4_t([N; 4]) }) } } -#[doc = "Shift Right and Insert (immediate)"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftins_v8i16)"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -fn vshiftins_v8i16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t { +#[rustc_legacy_const_generics(2)] +fn vshiftlins_v8i16(a: int16x8_t, b: int16x8_t) -> int16x8_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v8i16")] - fn _vshiftins_v8i16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t; + fn _vshiftlins_v8i16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t; } - unsafe { _vshiftins_v8i16(a, b, c) } + unsafe { _vshiftlins_v8i16(a, b, const { int16x8_t([N as i16; 8]) }) } } -#[doc = "Shift Right and Insert (immediate)"] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftins_v8i8)"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -fn vshiftins_v8i8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t { +#[rustc_legacy_const_generics(2)] +fn vshiftlins_v8i8(a: int8x8_t, b: int8x8_t) -> int8x8_t { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v8i8")] - fn _vshiftins_v8i8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t; + fn _vshiftlins_v8i8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t; } - unsafe { _vshiftins_v8i8(a, b, c) } + unsafe { _vshiftlins_v8i8(a, b, const { int8x8_t([N as i8; 8]) }) } +} +#[doc = "Shift Right and Insert (immediate)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v16i8)"] +#[inline] +#[target_feature(enable = "neon")] +#[cfg(target_arch = "arm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] +#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] +#[rustc_legacy_const_generics(2)] +fn vshiftrins_v16i8(a: int8x16_t, b: int8x16_t) -> int8x16_t { + unsafe extern "unadjusted" { + #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v16i8")] + fn _vshiftrins_v16i8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t; + } + unsafe { _vshiftrins_v16i8(a, b, const { int8x16_t([-N as i8; 16]) }) } +} +#[doc = "Shift Right and Insert (immediate)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v1i64)"] +#[inline] +#[target_feature(enable = "neon")] +#[cfg(target_arch = "arm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] +#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] +#[rustc_legacy_const_generics(2)] +fn vshiftrins_v1i64(a: int64x1_t, b: int64x1_t) -> int64x1_t { + unsafe extern "unadjusted" { + #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v1i64")] + fn _vshiftrins_v1i64(a: int64x1_t, b: int64x1_t, c: int64x1_t) -> int64x1_t; + } + unsafe { _vshiftrins_v1i64(a, b, const { int64x1_t([-N as i64; 1]) }) } +} +#[doc = "Shift Right and Insert (immediate)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v2i32)"] +#[inline] +#[target_feature(enable = "neon")] +#[cfg(target_arch = "arm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] +#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] +#[rustc_legacy_const_generics(2)] +fn vshiftrins_v2i32(a: int32x2_t, b: int32x2_t) -> int32x2_t { + unsafe extern "unadjusted" { + #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v2i32")] + fn _vshiftrins_v2i32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t; + } + unsafe { _vshiftrins_v2i32(a, b, const { int32x2_t([-N; 2]) }) } +} +#[doc = "Shift Right and Insert (immediate)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v2i64)"] +#[inline] +#[target_feature(enable = "neon")] +#[cfg(target_arch = "arm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] +#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] +#[rustc_legacy_const_generics(2)] +fn vshiftrins_v2i64(a: int64x2_t, b: int64x2_t) -> int64x2_t { + unsafe extern "unadjusted" { + #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v2i64")] + fn _vshiftrins_v2i64(a: int64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t; + } + unsafe { _vshiftrins_v2i64(a, b, const { int64x2_t([-N as i64; 2]) }) } +} +#[doc = "Shift Right and Insert (immediate)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v4i16)"] +#[inline] +#[target_feature(enable = "neon")] +#[cfg(target_arch = "arm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] +#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] +#[rustc_legacy_const_generics(2)] +fn vshiftrins_v4i16(a: int16x4_t, b: int16x4_t) -> int16x4_t { + unsafe extern "unadjusted" { + #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v4i16")] + fn _vshiftrins_v4i16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t; + } + unsafe { _vshiftrins_v4i16(a, b, const { int16x4_t([-N as i16; 4]) }) } +} +#[doc = "Shift Right and Insert (immediate)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v4i32)"] +#[inline] +#[target_feature(enable = "neon")] +#[cfg(target_arch = "arm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] +#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] +#[rustc_legacy_const_generics(2)] +fn vshiftrins_v4i32(a: int32x4_t, b: int32x4_t) -> int32x4_t { + unsafe extern "unadjusted" { + #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v4i32")] + fn _vshiftrins_v4i32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t; + } + unsafe { _vshiftrins_v4i32(a, b, const { int32x4_t([-N; 4]) }) } +} +#[doc = "Shift Right and Insert (immediate)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v8i16)"] +#[inline] +#[target_feature(enable = "neon")] +#[cfg(target_arch = "arm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] +#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] +#[rustc_legacy_const_generics(2)] +fn vshiftrins_v8i16(a: int16x8_t, b: int16x8_t) -> int16x8_t { + unsafe extern "unadjusted" { + #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v8i16")] + fn _vshiftrins_v8i16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t; + } + unsafe { _vshiftrins_v8i16(a, b, const { int16x8_t([-N as i16; 8]) }) } +} +#[doc = "Shift Right and Insert (immediate)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v8i8)"] +#[inline] +#[target_feature(enable = "neon")] +#[cfg(target_arch = "arm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] +#[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] +#[rustc_legacy_const_generics(2)] +fn vshiftrins_v8i8(a: int8x8_t, b: int8x8_t) -> int8x8_t { + unsafe extern "unadjusted" { + #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vshiftins.v8i8")] + fn _vshiftrins_v8i8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t; + } + unsafe { _vshiftrins_v8i8(a, b, const { int8x8_t([-N as i8; 8]) }) } } #[doc = "Shift left"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_s8)"] @@ -62706,7 +62508,7 @@ pub fn vshrn_n_u64(a: uint64x2_t) -> uint32x2_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t { static_assert_uimm_bits!(N, 3); - vshiftins_v8i8(a, b, int8x8_t::splat(N as i8)) + vshiftlins_v8i8::(a, b) } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s8)"] @@ -62718,7 +62520,7 @@ pub fn vsli_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t { static_assert_uimm_bits!(N, 3); - vshiftins_v16i8(a, b, int8x16_t::splat(N as i8)) + vshiftlins_v16i8::(a, b) } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s16)"] @@ -62730,7 +62532,7 @@ pub fn vsliq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t { static_assert_uimm_bits!(N, 4); - vshiftins_v4i16(a, b, int16x4_t::splat(N as i16)) + vshiftlins_v4i16::(a, b) } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s16)"] @@ -62742,7 +62544,7 @@ pub fn vsli_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { static_assert_uimm_bits!(N, 4); - vshiftins_v8i16(a, b, int16x8_t::splat(N as i16)) + vshiftlins_v8i16::(a, b) } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s32)"] @@ -62754,7 +62556,7 @@ pub fn vsliq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t { static_assert!(N >= 0 && N <= 31); - vshiftins_v2i32(a, b, int32x2_t::splat(N)) + vshiftlins_v2i32::(a, b) } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s32)"] @@ -62766,7 +62568,7 @@ pub fn vsli_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { static_assert!(N >= 0 && N <= 31); - vshiftins_v4i32(a, b, int32x4_t::splat(N)) + vshiftlins_v4i32::(a, b) } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s64)"] @@ -62778,7 +62580,7 @@ pub fn vsliq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t { static_assert!(N >= 0 && N <= 63); - vshiftins_v1i64(a, b, int64x1_t::splat(N as i64)) + vshiftlins_v1i64::(a, b) } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s64)"] @@ -62790,7 +62592,7 @@ pub fn vsli_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { static_assert!(N >= 0 && N <= 63); - vshiftins_v2i64(a, b, int64x2_t::splat(N as i64)) + vshiftlins_v2i64::(a, b) } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u8)"] @@ -62802,13 +62604,7 @@ pub fn vsliq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - transmute(vshiftins_v8i8( - transmute(a), - transmute(b), - int8x8_t::splat(N as i8), - )) - } + unsafe { transmute(vshiftlins_v8i8::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u8)"] @@ -62820,13 +62616,7 @@ pub fn vsli_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t { static_assert_uimm_bits!(N, 3); - unsafe { - transmute(vshiftins_v16i8( - transmute(a), - transmute(b), - int8x16_t::splat(N as i8), - )) - } + unsafe { transmute(vshiftlins_v16i8::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u16)"] @@ -62838,13 +62628,7 @@ pub fn vsliq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t { static_assert_uimm_bits!(N, 4); - unsafe { - transmute(vshiftins_v4i16( - transmute(a), - transmute(b), - int16x4_t::splat(N as i16), - )) - } + unsafe { transmute(vshiftlins_v4i16::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u16)"] @@ -62856,13 +62640,7 @@ pub fn vsli_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t { static_assert_uimm_bits!(N, 4); - unsafe { - transmute(vshiftins_v8i16( - transmute(a), - transmute(b), - int16x8_t::splat(N as i16), - )) - } + unsafe { transmute(vshiftlins_v8i16::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u32)"] @@ -62874,13 +62652,7 @@ pub fn vsliq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t { static_assert!(N >= 0 && N <= 31); - unsafe { - transmute(vshiftins_v2i32( - transmute(a), - transmute(b), - int32x2_t::splat(N), - )) - } + unsafe { transmute(vshiftlins_v2i32::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u32)"] @@ -62892,13 +62664,7 @@ pub fn vsli_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { static_assert!(N >= 0 && N <= 31); - unsafe { - transmute(vshiftins_v4i32( - transmute(a), - transmute(b), - int32x4_t::splat(N), - )) - } + unsafe { transmute(vshiftlins_v4i32::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u64)"] @@ -62910,13 +62676,7 @@ pub fn vsliq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t { static_assert!(N >= 0 && N <= 63); - unsafe { - transmute(vshiftins_v1i64( - transmute(a), - transmute(b), - int64x1_t::splat(N as i64), - )) - } + unsafe { transmute(vshiftlins_v1i64::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u64)"] @@ -62928,13 +62688,7 @@ pub fn vsli_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t { static_assert!(N >= 0 && N <= 63); - unsafe { - transmute(vshiftins_v2i64( - transmute(a), - transmute(b), - int64x2_t::splat(N as i64), - )) - } + unsafe { transmute(vshiftlins_v2i64::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_p8)"] @@ -62946,13 +62700,7 @@ pub fn vsliq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - transmute(vshiftins_v8i8( - transmute(a), - transmute(b), - int8x8_t::splat(N as i8), - )) - } + unsafe { transmute(vshiftlins_v8i8::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_p8)"] @@ -62964,13 +62712,7 @@ pub fn vsli_n_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t { static_assert_uimm_bits!(N, 3); - unsafe { - transmute(vshiftins_v16i8( - transmute(a), - transmute(b), - int8x16_t::splat(N as i8), - )) - } + unsafe { transmute(vshiftlins_v16i8::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_p16)"] @@ -62982,13 +62724,7 @@ pub fn vsliq_n_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t { #[rustc_legacy_const_generics(2)] pub fn vsli_n_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t { static_assert_uimm_bits!(N, 4); - unsafe { - transmute(vshiftins_v4i16( - transmute(a), - transmute(b), - int16x4_t::splat(N as i16), - )) - } + unsafe { transmute(vshiftlins_v4i16::(transmute(a), transmute(b))) } } #[doc = "Shift Left and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_p16)"] @@ -63000,13 +62736,7 @@ pub fn vsli_n_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t { #[rustc_legacy_const_generics(2)] pub fn vsliq_n_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t { static_assert_uimm_bits!(N, 4); - unsafe { - transmute(vshiftins_v8i16( - transmute(a), - transmute(b), - int16x8_t::splat(N as i16), - )) - } + unsafe { transmute(vshiftlins_v8i16::(transmute(a), transmute(b))) } } #[doc = "Signed shift right and accumulate"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_s8)"] @@ -63386,7 +63116,7 @@ pub fn vsraq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t { static_assert!(1 <= N && N <= 8); - vshiftins_v8i8(a, b, int8x8_t::splat(-N as i8)) + vshiftrins_v8i8::(a, b) } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s8)"] @@ -63398,7 +63128,7 @@ pub fn vsri_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t { static_assert!(1 <= N && N <= 8); - vshiftins_v16i8(a, b, int8x16_t::splat(-N as i8)) + vshiftrins_v16i8::(a, b) } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s16)"] @@ -63410,7 +63140,7 @@ pub fn vsriq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t { static_assert!(1 <= N && N <= 16); - vshiftins_v4i16(a, b, int16x4_t::splat(-N as i16)) + vshiftrins_v4i16::(a, b) } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s16)"] @@ -63422,7 +63152,7 @@ pub fn vsri_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { static_assert!(1 <= N && N <= 16); - vshiftins_v8i16(a, b, int16x8_t::splat(-N as i16)) + vshiftrins_v8i16::(a, b) } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s32)"] @@ -63434,7 +63164,7 @@ pub fn vsriq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t { static_assert!(1 <= N && N <= 32); - vshiftins_v2i32(a, b, int32x2_t::splat(-N)) + vshiftrins_v2i32::(a, b) } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s32)"] @@ -63446,7 +63176,7 @@ pub fn vsri_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { static_assert!(1 <= N && N <= 32); - vshiftins_v4i32(a, b, int32x4_t::splat(-N)) + vshiftrins_v4i32::(a, b) } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s64)"] @@ -63458,7 +63188,7 @@ pub fn vsriq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t { static_assert!(1 <= N && N <= 64); - vshiftins_v1i64(a, b, int64x1_t::splat(-N as i64)) + vshiftrins_v1i64::(a, b) } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s64)"] @@ -63470,7 +63200,7 @@ pub fn vsri_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { static_assert!(1 <= N && N <= 64); - vshiftins_v2i64(a, b, int64x2_t::splat(-N as i64)) + vshiftrins_v2i64::(a, b) } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u8)"] @@ -63482,13 +63212,7 @@ pub fn vsriq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t { static_assert!(1 <= N && N <= 8); - unsafe { - transmute(vshiftins_v8i8( - transmute(a), - transmute(b), - int8x8_t::splat(-N as i8), - )) - } + unsafe { transmute(vshiftrins_v8i8::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u8)"] @@ -63500,13 +63224,7 @@ pub fn vsri_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t { static_assert!(1 <= N && N <= 8); - unsafe { - transmute(vshiftins_v16i8( - transmute(a), - transmute(b), - int8x16_t::splat(-N as i8), - )) - } + unsafe { transmute(vshiftrins_v16i8::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u16)"] @@ -63518,13 +63236,7 @@ pub fn vsriq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t { static_assert!(1 <= N && N <= 16); - unsafe { - transmute(vshiftins_v4i16( - transmute(a), - transmute(b), - int16x4_t::splat(-N as i16), - )) - } + unsafe { transmute(vshiftrins_v4i16::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u16)"] @@ -63536,13 +63248,7 @@ pub fn vsri_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t { static_assert!(1 <= N && N <= 16); - unsafe { - transmute(vshiftins_v8i16( - transmute(a), - transmute(b), - int16x8_t::splat(-N as i16), - )) - } + unsafe { transmute(vshiftrins_v8i16::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u32)"] @@ -63554,13 +63260,7 @@ pub fn vsriq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t { static_assert!(1 <= N && N <= 32); - unsafe { - transmute(vshiftins_v2i32( - transmute(a), - transmute(b), - int32x2_t::splat(-N), - )) - } + unsafe { transmute(vshiftrins_v2i32::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u32)"] @@ -63572,13 +63272,7 @@ pub fn vsri_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { static_assert!(1 <= N && N <= 32); - unsafe { - transmute(vshiftins_v4i32( - transmute(a), - transmute(b), - int32x4_t::splat(-N), - )) - } + unsafe { transmute(vshiftrins_v4i32::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u64)"] @@ -63590,13 +63284,7 @@ pub fn vsriq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t { static_assert!(1 <= N && N <= 64); - unsafe { - transmute(vshiftins_v1i64( - transmute(a), - transmute(b), - int64x1_t::splat(-N as i64), - )) - } + unsafe { transmute(vshiftrins_v1i64::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u64)"] @@ -63608,13 +63296,7 @@ pub fn vsri_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t { static_assert!(1 <= N && N <= 64); - unsafe { - transmute(vshiftins_v2i64( - transmute(a), - transmute(b), - int64x2_t::splat(-N as i64), - )) - } + unsafe { transmute(vshiftrins_v2i64::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_p8)"] @@ -63626,13 +63308,7 @@ pub fn vsriq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t { static_assert!(1 <= N && N <= 8); - unsafe { - transmute(vshiftins_v8i8( - transmute(a), - transmute(b), - int8x8_t::splat(-N as i8), - )) - } + unsafe { transmute(vshiftrins_v8i8::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_p8)"] @@ -63644,13 +63320,7 @@ pub fn vsri_n_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t { static_assert!(1 <= N && N <= 8); - unsafe { - transmute(vshiftins_v16i8( - transmute(a), - transmute(b), - int8x16_t::splat(-N as i8), - )) - } + unsafe { transmute(vshiftrins_v16i8::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_p16)"] @@ -63662,13 +63332,7 @@ pub fn vsriq_n_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t { #[rustc_legacy_const_generics(2)] pub fn vsri_n_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t { static_assert!(1 <= N && N <= 16); - unsafe { - transmute(vshiftins_v4i16( - transmute(a), - transmute(b), - int16x4_t::splat(-N as i16), - )) - } + unsafe { transmute(vshiftrins_v4i16::(transmute(a), transmute(b))) } } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_p16)"] @@ -63680,13 +63344,7 @@ pub fn vsri_n_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t { #[rustc_legacy_const_generics(2)] pub fn vsriq_n_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t { static_assert!(1 <= N && N <= 16); - unsafe { - transmute(vshiftins_v8i16( - transmute(a), - transmute(b), - int16x8_t::splat(-N as i16), - )) - } + unsafe { transmute(vshiftrins_v8i16::(transmute(a), transmute(b))) } } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f16)"] @@ -63987,11 +63645,8 @@ pub unsafe fn vst1q_f16_x4(a: *mut f16, b: float16x8x4_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] pub unsafe fn vst1_f32(ptr: *mut f32, a: float32x2_t) { - vst1_v2f32( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v2f32::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32)"] @@ -64004,11 +63659,8 @@ pub unsafe fn vst1_f32(ptr: *mut f32, a: float32x2_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] pub unsafe fn vst1q_f32(ptr: *mut f32, a: float32x4_t) { - vst1q_v4f32( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v4f32::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8)"] @@ -64021,7 +63673,8 @@ pub unsafe fn vst1q_f32(ptr: *mut f32, a: float32x4_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8"))] pub unsafe fn vst1_s8(ptr: *mut i8, a: int8x8_t) { - vst1_v8i8(ptr as *const i8, a, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v8i8::(ptr as *const i8, a) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8)"] @@ -64034,7 +63687,8 @@ pub unsafe fn vst1_s8(ptr: *mut i8, a: int8x8_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8"))] pub unsafe fn vst1q_s8(ptr: *mut i8, a: int8x16_t) { - vst1q_v16i8(ptr as *const i8, a, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v16i8::(ptr as *const i8, a) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16)"] @@ -64047,7 +63701,8 @@ pub unsafe fn vst1q_s8(ptr: *mut i8, a: int8x16_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16"))] pub unsafe fn vst1_s16(ptr: *mut i16, a: int16x4_t) { - vst1_v4i16(ptr as *const i8, a, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v4i16::(ptr as *const i8, a) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16)"] @@ -64060,7 +63715,8 @@ pub unsafe fn vst1_s16(ptr: *mut i16, a: int16x4_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16"))] pub unsafe fn vst1q_s16(ptr: *mut i16, a: int16x8_t) { - vst1q_v8i16(ptr as *const i8, a, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v8i16::(ptr as *const i8, a) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32)"] @@ -64073,7 +63729,8 @@ pub unsafe fn vst1q_s16(ptr: *mut i16, a: int16x8_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] pub unsafe fn vst1_s32(ptr: *mut i32, a: int32x2_t) { - vst1_v2i32(ptr as *const i8, a, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v2i32::(ptr as *const i8, a) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32)"] @@ -64086,7 +63743,8 @@ pub unsafe fn vst1_s32(ptr: *mut i32, a: int32x2_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] pub unsafe fn vst1q_s32(ptr: *mut i32, a: int32x4_t) { - vst1q_v4i32(ptr as *const i8, a, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v4i32::(ptr as *const i8, a) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64)"] @@ -64099,7 +63757,8 @@ pub unsafe fn vst1q_s32(ptr: *mut i32, a: int32x4_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64"))] pub unsafe fn vst1_s64(ptr: *mut i64, a: int64x1_t) { - vst1_v1i64(ptr as *const i8, a, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v1i64::(ptr as *const i8, a) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64)"] @@ -64112,7 +63771,8 @@ pub unsafe fn vst1_s64(ptr: *mut i64, a: int64x1_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64"))] pub unsafe fn vst1q_s64(ptr: *mut i64, a: int64x2_t) { - vst1q_v2i64(ptr as *const i8, a, crate::mem::align_of::() as i32) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v2i64::(ptr as *const i8, a) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u8)"] @@ -64125,11 +63785,8 @@ pub unsafe fn vst1q_s64(ptr: *mut i64, a: int64x2_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8"))] pub unsafe fn vst1_u8(ptr: *mut u8, a: uint8x8_t) { - vst1_v8i8( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v8i8::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u8)"] @@ -64142,11 +63799,8 @@ pub unsafe fn vst1_u8(ptr: *mut u8, a: uint8x8_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8"))] pub unsafe fn vst1q_u8(ptr: *mut u8, a: uint8x16_t) { - vst1q_v16i8( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v16i8::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u16)"] @@ -64159,11 +63813,8 @@ pub unsafe fn vst1q_u8(ptr: *mut u8, a: uint8x16_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16"))] pub unsafe fn vst1_u16(ptr: *mut u16, a: uint16x4_t) { - vst1_v4i16( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v4i16::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u16)"] @@ -64176,11 +63827,8 @@ pub unsafe fn vst1_u16(ptr: *mut u16, a: uint16x4_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16"))] pub unsafe fn vst1q_u16(ptr: *mut u16, a: uint16x8_t) { - vst1q_v8i16( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v8i16::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u32)"] @@ -64193,11 +63841,8 @@ pub unsafe fn vst1q_u16(ptr: *mut u16, a: uint16x8_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] pub unsafe fn vst1_u32(ptr: *mut u32, a: uint32x2_t) { - vst1_v2i32( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v2i32::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u32)"] @@ -64210,11 +63855,8 @@ pub unsafe fn vst1_u32(ptr: *mut u32, a: uint32x2_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] pub unsafe fn vst1q_u32(ptr: *mut u32, a: uint32x4_t) { - vst1q_v4i32( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v4i32::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u64)"] @@ -64227,11 +63869,8 @@ pub unsafe fn vst1q_u32(ptr: *mut u32, a: uint32x4_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64"))] pub unsafe fn vst1_u64(ptr: *mut u64, a: uint64x1_t) { - vst1_v1i64( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v1i64::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u64)"] @@ -64244,11 +63883,8 @@ pub unsafe fn vst1_u64(ptr: *mut u64, a: uint64x1_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64"))] pub unsafe fn vst1q_u64(ptr: *mut u64, a: uint64x2_t) { - vst1q_v2i64( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v2i64::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p8)"] @@ -64261,11 +63897,8 @@ pub unsafe fn vst1q_u64(ptr: *mut u64, a: uint64x2_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8"))] pub unsafe fn vst1_p8(ptr: *mut p8, a: poly8x8_t) { - vst1_v8i8( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v8i8::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p8)"] @@ -64278,11 +63911,8 @@ pub unsafe fn vst1_p8(ptr: *mut p8, a: poly8x8_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8"))] pub unsafe fn vst1q_p8(ptr: *mut p8, a: poly8x16_t) { - vst1q_v16i8( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v16i8::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p16)"] @@ -64295,11 +63925,8 @@ pub unsafe fn vst1q_p8(ptr: *mut p8, a: poly8x16_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16"))] pub unsafe fn vst1_p16(ptr: *mut p16, a: poly16x4_t) { - vst1_v4i16( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v4i16::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p16)"] @@ -64312,11 +63939,8 @@ pub unsafe fn vst1_p16(ptr: *mut p16, a: poly16x4_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16"))] pub unsafe fn vst1q_p16(ptr: *mut p16, a: poly16x8_t) { - vst1q_v8i16( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v8i16::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64)"] @@ -64329,11 +63953,8 @@ pub unsafe fn vst1q_p16(ptr: *mut p16, a: poly16x8_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64"))] pub unsafe fn vst1_p64(ptr: *mut p64, a: poly64x1_t) { - vst1_v1i64( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1_v1i64::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64)"] @@ -64346,11 +63967,8 @@ pub unsafe fn vst1_p64(ptr: *mut p64, a: poly64x1_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64"))] pub unsafe fn vst1q_p64(ptr: *mut p64, a: poly64x2_t) { - vst1q_v2i64( - ptr as *const i8, - transmute(a), - crate::mem::align_of::() as i32, - ) + const ALIGN: i32 = crate::mem::align_of::() as i32; + vst1q_v2i64::(ptr as *const i8, transmute(a)) } #[doc = "Store multiple single-element structures to one, two, three, or four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x2)"] @@ -66973,175 +66591,145 @@ pub unsafe fn vst1q_p16_x3(a: *mut p16, b: poly16x8x3_t) { pub unsafe fn vst1q_p16_x4(a: *mut p16, b: poly16x8x4_t) { vst1q_s16_x4(transmute(a), transmute(b)) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_v1i64)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64"))] -unsafe fn vst1_v1i64(addr: *const i8, val: int64x1_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1_v1i64(addr: *const i8, val: int64x1_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v1i64.p0")] fn _vst1_v1i64(addr: *const i8, val: int64x1_t, align: i32); } - _vst1_v1i64(addr, val, align) + _vst1_v1i64(addr, val, ALIGN) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_v2f32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] -unsafe fn vst1_v2f32(addr: *const i8, val: float32x2_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1_v2f32(addr: *const i8, val: float32x2_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v2f32.p0")] fn _vst1_v2f32(addr: *const i8, val: float32x2_t, align: i32); } - _vst1_v2f32(addr, val, align) + _vst1_v2f32(addr, val, ALIGN) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_v2i32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] -unsafe fn vst1_v2i32(addr: *const i8, val: int32x2_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1_v2i32(addr: *const i8, val: int32x2_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v2i32.p0")] fn _vst1_v2i32(addr: *const i8, val: int32x2_t, align: i32); } - _vst1_v2i32(addr, val, align) + _vst1_v2i32(addr, val, ALIGN) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_v4i16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16"))] -unsafe fn vst1_v4i16(addr: *const i8, val: int16x4_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1_v4i16(addr: *const i8, val: int16x4_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v4i16.p0")] fn _vst1_v4i16(addr: *const i8, val: int16x4_t, align: i32); } - _vst1_v4i16(addr, val, align) + _vst1_v4i16(addr, val, ALIGN) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_v8i8)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8"))] -unsafe fn vst1_v8i8(addr: *const i8, val: int8x8_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1_v8i8(addr: *const i8, val: int8x8_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v8i8.p0")] fn _vst1_v8i8(addr: *const i8, val: int8x8_t, align: i32); } - _vst1_v8i8(addr, val, align) + _vst1_v8i8(addr, val, ALIGN) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_v16i8)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8"))] -unsafe fn vst1q_v16i8(addr: *const i8, val: int8x16_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.8", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1q_v16i8(addr: *const i8, val: int8x16_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v16i8.p0")] fn _vst1q_v16i8(addr: *const i8, val: int8x16_t, align: i32); } - _vst1q_v16i8(addr, val, align) + _vst1q_v16i8(addr, val, ALIGN) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_v2i64)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64"))] -unsafe fn vst1q_v2i64(addr: *const i8, val: int64x2_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.64", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1q_v2i64(addr: *const i8, val: int64x2_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v2i64.p0")] fn _vst1q_v2i64(addr: *const i8, val: int64x2_t, align: i32); } - _vst1q_v2i64(addr, val, align) + _vst1q_v2i64(addr, val, ALIGN) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_v4f32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] -unsafe fn vst1q_v4f32(addr: *const i8, val: float32x4_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1q_v4f32(addr: *const i8, val: float32x4_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v4f32.p0")] fn _vst1q_v4f32(addr: *const i8, val: float32x4_t, align: i32); } - _vst1q_v4f32(addr, val, align) + _vst1q_v4f32(addr, val, ALIGN) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_v4i32)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32"))] -unsafe fn vst1q_v4i32(addr: *const i8, val: int32x4_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.32", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1q_v4i32(addr: *const i8, val: int32x4_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v4i32.p0")] fn _vst1q_v4i32(addr: *const i8, val: int32x4_t, align: i32); } - _vst1q_v4i32(addr, val, align) + _vst1q_v4i32(addr, val, ALIGN) } -#[doc = "Store multiple single-element structures from one, two, three, or four registers."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_v8i16)"] -#[doc = "## Safety"] -#[doc = " * Neon instrinsic unsafe"] #[inline] #[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] -#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16"))] -unsafe fn vst1q_v8i16(addr: *const i8, val: int16x8_t, align: i32) { +#[cfg_attr(all(test, target_arch = "arm"), assert_instr("vst1.16", ALIGN = 0))] +#[rustc_legacy_const_generics(2)] +unsafe fn vst1q_v8i16(addr: *const i8, val: int16x8_t) { unsafe extern "unadjusted" { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst1.v8i16.p0")] fn _vst1q_v8i16(addr: *const i8, val: int16x8_t, align: i32); } - _vst1q_v8i16(addr, val, align) + _vst1q_v8i16(addr, val, ALIGN) } #[doc = "Store multiple single-element structures from one, two, three, or four registers."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_v4f16)"] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 43dd3b903150..4816d17bd654 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -11787,39 +11787,39 @@ intrinsics: - name: "vld1{type[0]}" visibility: private - doc: "Load multiple single-element structures to one, two, three, or four registers" - arguments: ["a: {type[1]}", "b: {type[2]}"] - return_type: "{neon_type[3]}" + arguments: ["a: {type[1]}"] + static_defs: ["const ALIGN: i32"] + return_type: "{neon_type[2]}" attr: + - FnCall: [rustc_legacy_const_generics, ['1']] - *target-is-arm - *enable-v7 - # - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld1]]}]] + - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vld1.8"', "ALIGN = 0"]]}]] - *neon-arm-unstable safety: unsafe: [neon] types: - - ["_v8i8", "*const i8", "i32", "int8x8_t"] - - ["q_v16i8", "*const i8", "i32", "int8x16_t"] - - ["_v4i16", "*const i8", "i32", "int16x4_t"] - - ["q_v8i16", "*const i8", "i32", "int16x8_t"] - - ["_v2i32", "*const i8", "i32", "int32x2_t"] - - ["q_v4i32", "*const i8", "i32", "int32x4_t"] - - ["_v1i64", "*const i8", "i32", "int64x1_t"] - - ["q_v2i64", "*const i8", "i32", "int64x2_t"] - - ["_v2f32", "*const i8", "i32", "float32x2_t"] - - ["q_v4f32", "*const i8", "i32", "float32x4_t"] + - ["_v8i8", "*const i8", "int8x8_t" ] + - ["q_v16i8", "*const i8", "int8x16_t" ] + - ["_v4i16", "*const i8", "int16x4_t" ] + - ["q_v8i16", "*const i8", "int16x8_t" ] + - ["_v2i32", "*const i8", "int32x2_t" ] + - ["q_v4i32", "*const i8", "int32x4_t" ] + - ["_v1i64", "*const i8", "int64x1_t" ] + - ["q_v2i64", "*const i8", "int64x2_t" ] + - ["_v2f32", "*const i8", "float32x2_t"] + - ["q_v4f32", "*const i8", "float32x4_t"] compose: - LLVMLink: name: "vld1.{type[0]}" + arguments: ["a: {type[1]}", "b: i32"] links: - - link: "llvm.arm.neon.vld1.{neon_type[3]}" + - link: "llvm.arm.neon.vld1.{neon_type[2]}" arch: arm - - FnCall: ["_vld1{type[0]}", [a, b]] - + - FnCall: ["_vld1{type[0]}", [a, ALIGN]] - name: "vld1{type[0]}" visibility: private - doc: "Load multiple single-element structures to one, two, three, or four registers" arguments: ["a: {type[1]}", "b: {type[2]}"] return_type: "{neon_type[3]}" attr: @@ -11855,19 +11855,23 @@ intrinsics: - *neon-arm-unstable - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['{type[2]}']]}]] types: - - ['*const i8', int8x8_t, '"vld1.8"', 'crate::mem::align_of::() as i32', '_v8i8'] - - ['*const i8', int8x16_t, '"vld1.8"', 'crate::mem::align_of::() as i32', 'q_v16i8'] - - ['*const i16', int16x4_t, '"vld1.16"', 'crate::mem::align_of::() as i32', '_v4i16'] - - ['*const i16', int16x8_t, '"vld1.16"', 'crate::mem::align_of::() as i32', 'q_v8i16'] - - ['*const i32', int32x2_t, 'vldr', 'crate::mem::align_of::() as i32', '_v2i32'] - - ['*const i32', int32x4_t, '"vld1.32"', 'crate::mem::align_of::() as i32', 'q_v4i32'] - - ['*const i64', int64x1_t, 'vldr', 'crate::mem::align_of::() as i32', '_v1i64'] - - ['*const i64', int64x2_t, '"vld1.64"', 'crate::mem::align_of::() as i32', 'q_v2i64'] + - ['*const i8', int8x8_t, '"vld1.8"', 'crate::mem::align_of::()', '_v8i8' ] + - ['*const i8', int8x16_t, '"vld1.8"', 'crate::mem::align_of::()', 'q_v16i8'] + - ['*const i16', int16x4_t, '"vld1.16"', 'crate::mem::align_of::()', '_v4i16' ] + - ['*const i16', int16x8_t, '"vld1.16"', 'crate::mem::align_of::()', 'q_v8i16'] + - ['*const i32', int32x2_t, 'vldr', 'crate::mem::align_of::()', '_v2i32' ] + - ['*const i32', int32x4_t, '"vld1.32"', 'crate::mem::align_of::()', 'q_v4i32'] + - ['*const i64', int64x1_t, 'vldr', 'crate::mem::align_of::()', '_v1i64' ] + - ['*const i64', int64x2_t, '"vld1.64"', 'crate::mem::align_of::()', 'q_v2i64'] compose: + - Const: + - ALIGN + - "i32" + - "{type[3]} as i32" - FnCall: - "vld1{type[4]}" - - - 'ptr as *const i8' - - '{type[3]}' + - ['ptr as *const i8'] + - ['ALIGN'] - name: "vld1{neon_type[1].no}" doc: "Load multiple single-element structures to one, two, three, or four registers." @@ -11881,28 +11885,32 @@ intrinsics: - *neon-arm-unstable - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['{type[2]}']]}]] types: - - ['*const u8', uint8x8_t, '"vld1.8"', 'neon,v7', 'crate::mem::align_of::() as i32', '_v8i8'] - - ['*const u8', uint8x16_t, '"vld1.8"', 'neon,v7', 'crate::mem::align_of::() as i32', 'q_v16i8'] - - ['*const u16', uint16x4_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::() as i32', '_v4i16'] - - ['*const u16', uint16x8_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::() as i32', 'q_v8i16'] - - ['*const u32', uint32x2_t, 'vldr', 'neon,v7', 'crate::mem::align_of::() as i32', '_v2i32'] - - ['*const u32', uint32x4_t, '"vld1.32"', 'neon,v7', 'crate::mem::align_of::() as i32', 'q_v4i32'] - - ['*const u64', uint64x1_t, 'vldr', 'neon,v7', 'crate::mem::align_of::() as i32', '_v1i64'] - - ['*const u64', uint64x2_t, '"vld1.64"', 'neon,v7', 'crate::mem::align_of::() as i32', 'q_v2i64'] - - ['*const p8', poly8x8_t, '"vld1.8"', 'neon,v7', 'crate::mem::align_of::() as i32', '_v8i8'] - - ['*const p8', poly8x16_t, '"vld1.8"', 'neon,v7', 'crate::mem::align_of::() as i32', 'q_v16i8'] - - ['*const p16', poly16x4_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::() as i32', '_v4i16'] - - ['*const p16', poly16x8_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::() as i32', 'q_v8i16'] - - ['*const p64', poly64x2_t, '"vld1.64"', 'neon,aes', 'crate::mem::align_of::() as i32', 'q_v2i64'] - - ['*const f32', float32x2_t, 'vldr', 'neon,v7', 'crate::mem::align_of::() as i32', '_v2f32'] - - ['*const f32', float32x4_t, '"vld1.32"', 'neon,v7', 'crate::mem::align_of::() as i32', 'q_v4f32'] + - ['*const u8', uint8x8_t, '"vld1.8"', 'neon,v7', 'crate::mem::align_of::()', '_v8i8' ] + - ['*const u8', uint8x16_t, '"vld1.8"', 'neon,v7', 'crate::mem::align_of::()', 'q_v16i8'] + - ['*const u16', uint16x4_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::()', '_v4i16' ] + - ['*const u16', uint16x8_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::()', 'q_v8i16'] + - ['*const u32', uint32x2_t, 'vldr', 'neon,v7', 'crate::mem::align_of::()', '_v2i32' ] + - ['*const u32', uint32x4_t, '"vld1.32"', 'neon,v7', 'crate::mem::align_of::()', 'q_v4i32'] + - ['*const u64', uint64x1_t, 'vldr', 'neon,v7', 'crate::mem::align_of::()', '_v1i64' ] + - ['*const u64', uint64x2_t, '"vld1.64"', 'neon,v7', 'crate::mem::align_of::()', 'q_v2i64'] + - ['*const p8', poly8x8_t, '"vld1.8"', 'neon,v7', 'crate::mem::align_of::()', '_v8i8' ] + - ['*const p8', poly8x16_t, '"vld1.8"', 'neon,v7', 'crate::mem::align_of::()', 'q_v16i8'] + - ['*const p16', poly16x4_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::()', '_v4i16' ] + - ['*const p16', poly16x8_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::()', 'q_v8i16'] + - ['*const p64', poly64x2_t, '"vld1.64"', 'neon,aes', 'crate::mem::align_of::()', 'q_v2i64'] + - ['*const f32', float32x2_t, 'vldr', 'neon,v7', 'crate::mem::align_of::()', '_v2f32' ] + - ['*const f32', float32x4_t, '"vld1.32"', 'neon,v7', 'crate::mem::align_of::()', 'q_v4f32'] compose: + - Const: + - ALIGN + - "i32" + - "{type[4]} as i32" - FnCall: - transmute - - FnCall: - "vld1{type[5]}" - - - 'ptr as *const i8' - - '{type[4]}' + - ['ptr as *const i8'] + - ['ALIGN'] - name: "vld1{neon_type[1].no}" doc: "Load multiple single-element structures to one, two, three, or four registers." @@ -13724,32 +13732,35 @@ intrinsics: - name: "vst1{type[0]}" visibility: private - doc: "Store multiple single-element structures from one, two, three, or four registers." - arguments: ["addr: {type[1]}", "val: {neon_type[2]}", "align: {type[3]}"] + arguments: ["addr: {type[1]}", "val: {neon_type[2]}"] + static_defs: ["const ALIGN: i32"] safety: unsafe: [neon] attr: - *target-is-arm - *neon-v7 - *neon-arm-unstable - - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vst1.{type[4]}"']]}]] + - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vst1.{type[3]}"', "ALIGN = 0"]]}]] + - FnCall: ["rustc_legacy_const_generics", ['2']] types: - - ['_v8i8', '* const i8', int8x8_t, i32, '8'] - - ['q_v16i8', '* const i8', int8x16_t, i32, '8'] - - ['_v4i16', '* const i8', int16x4_t, i32, '16'] - - ['q_v8i16', '* const i8', int16x8_t, i32, '16'] - - ['_v2i32', '* const i8', int32x2_t, i32, '32'] - - ['q_v4i32', '* const i8', int32x4_t, i32, '32'] - - ['_v1i64', '* const i8', int64x1_t, i32, '64'] - - ['q_v2i64', '* const i8', int64x2_t, i32, '64'] - - ['_v2f32', '* const i8', float32x2_t, i32, '32'] - - ['q_v4f32', '* const i8', float32x4_t, i32, '32'] + - ['_v8i8', '* const i8', int8x8_t, '8' ] + - ['q_v16i8', '* const i8', int8x16_t, '8' ] + - ['_v4i16', '* const i8', int16x4_t, '16'] + - ['q_v8i16', '* const i8', int16x8_t, '16'] + - ['_v2i32', '* const i8', int32x2_t, '32'] + - ['q_v4i32', '* const i8', int32x4_t, '32'] + - ['_v1i64', '* const i8', int64x1_t, '64'] + - ['q_v2i64', '* const i8', int64x2_t, '64'] + - ['_v2f32', '* const i8', float32x2_t, '32'] + - ['q_v4f32', '* const i8', float32x4_t, '32'] compose: - LLVMLink: name: "_vst1{type[0]}" + arguments: ["addr: {type[1]}", "val: {neon_type[2]}", "align: i32"] links: - link: "llvm.arm.neon.vst1.{neon_type[2]}.p0" arch: arm + - FnCall: ["_vst1{type[0]}",[addr, val, ALIGN]] - name: "vst1{type[0]}" visibility: private @@ -13785,37 +13796,39 @@ intrinsics: - *neon-arm-unstable - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vst1.{type[2]}"']]}]] types: - - ['*mut i8', int8x8_t, '8', 'a', 'crate::mem::align_of::() as i32', '_v8i8'] - - ['*mut i8', int8x16_t, '8', 'a', 'crate::mem::align_of::() as i32', 'q_v16i8'] - - ['*mut i16', int16x4_t, '16', 'a', 'crate::mem::align_of::() as i32', '_v4i16'] - - ['*mut i16', int16x8_t, '16', 'a', 'crate::mem::align_of::() as i32', 'q_v8i16'] - - ['*mut i32', int32x2_t, '32', 'a', 'crate::mem::align_of::() as i32', '_v2i32'] - - ['*mut i32', int32x4_t, '32', 'a', 'crate::mem::align_of::() as i32', 'q_v4i32'] - - ['*mut i64', int64x1_t, '64', 'a', 'crate::mem::align_of::() as i32', '_v1i64'] - - ['*mut i64', int64x2_t, '64', 'a', 'crate::mem::align_of::() as i32', 'q_v2i64'] - - ['*mut u8', uint8x8_t, '8', 'transmute(a)', 'crate::mem::align_of::() as i32', '_v8i8'] - - ['*mut u8', uint8x16_t, '8', 'transmute(a)', 'crate::mem::align_of::() as i32', 'q_v16i8'] - - ['*mut u16', uint16x4_t, '16', 'transmute(a)', 'crate::mem::align_of::() as i32', '_v4i16'] - - ['*mut u16', uint16x8_t, '16', 'transmute(a)', 'crate::mem::align_of::() as i32', 'q_v8i16'] - - ['*mut u32', uint32x2_t, '32', 'transmute(a)', 'crate::mem::align_of::() as i32', '_v2i32'] - - ['*mut u32', uint32x4_t, '32', 'transmute(a)', 'crate::mem::align_of::() as i32', 'q_v4i32'] - - ['*mut u64', uint64x1_t, '64', 'transmute(a)', 'crate::mem::align_of::() as i32', '_v1i64'] - - ['*mut u64', uint64x2_t, '64', 'transmute(a)', 'crate::mem::align_of::() as i32', 'q_v2i64'] - - ['*mut p8', poly8x8_t, '8', 'transmute(a)', 'crate::mem::align_of::() as i32', '_v8i8'] - - ['*mut p8', poly8x16_t, '8', 'transmute(a)', 'crate::mem::align_of::() as i32', 'q_v16i8'] - - ['*mut p16', poly16x4_t, '16', 'transmute(a)', 'crate::mem::align_of::() as i32', '_v4i16'] - - ['*mut p16', poly16x8_t, '16', 'transmute(a)', 'crate::mem::align_of::() as i32', 'q_v8i16'] - - ['*mut p64', poly64x1_t, '64', 'transmute(a)', 'crate::mem::align_of::() as i32', '_v1i64'] - - ['*mut p64', poly64x2_t, '64', 'transmute(a)', 'crate::mem::align_of::() as i32', 'q_v2i64'] - - ['*mut f32', float32x2_t, '32', 'transmute(a)', 'crate::mem::align_of::() as i32', '_v2f32'] - - ['*mut f32', float32x4_t, '32', 'transmute(a)', 'crate::mem::align_of::() as i32', 'q_v4f32'] + - ['*mut i8', int8x8_t, '8', 'a', 'crate::mem::align_of::()', '_v8i8' ] + - ['*mut i8', int8x16_t, '8', 'a', 'crate::mem::align_of::()', 'q_v16i8'] + - ['*mut i16', int16x4_t, '16', 'a', 'crate::mem::align_of::()', '_v4i16' ] + - ['*mut i16', int16x8_t, '16', 'a', 'crate::mem::align_of::()', 'q_v8i16'] + - ['*mut i32', int32x2_t, '32', 'a', 'crate::mem::align_of::()', '_v2i32' ] + - ['*mut i32', int32x4_t, '32', 'a', 'crate::mem::align_of::()', 'q_v4i32'] + - ['*mut i64', int64x1_t, '64', 'a', 'crate::mem::align_of::()', '_v1i64' ] + - ['*mut i64', int64x2_t, '64', 'a', 'crate::mem::align_of::()', 'q_v2i64'] + - ['*mut u8', uint8x8_t, '8', 'transmute(a)', 'crate::mem::align_of::()', '_v8i8' ] + - ['*mut u8', uint8x16_t, '8', 'transmute(a)', 'crate::mem::align_of::()', 'q_v16i8'] + - ['*mut u16', uint16x4_t, '16', 'transmute(a)', 'crate::mem::align_of::()', '_v4i16' ] + - ['*mut u16', uint16x8_t, '16', 'transmute(a)', 'crate::mem::align_of::()', 'q_v8i16'] + - ['*mut u32', uint32x2_t, '32', 'transmute(a)', 'crate::mem::align_of::()', '_v2i32' ] + - ['*mut u32', uint32x4_t, '32', 'transmute(a)', 'crate::mem::align_of::()', 'q_v4i32'] + - ['*mut u64', uint64x1_t, '64', 'transmute(a)', 'crate::mem::align_of::()', '_v1i64' ] + - ['*mut u64', uint64x2_t, '64', 'transmute(a)', 'crate::mem::align_of::()', 'q_v2i64'] + - ['*mut p8', poly8x8_t, '8', 'transmute(a)', 'crate::mem::align_of::()', '_v8i8' ] + - ['*mut p8', poly8x16_t, '8', 'transmute(a)', 'crate::mem::align_of::()', 'q_v16i8'] + - ['*mut p16', poly16x4_t, '16', 'transmute(a)', 'crate::mem::align_of::()', '_v4i16' ] + - ['*mut p16', poly16x8_t, '16', 'transmute(a)', 'crate::mem::align_of::()', 'q_v8i16'] + - ['*mut p64', poly64x1_t, '64', 'transmute(a)', 'crate::mem::align_of::()', '_v1i64' ] + - ['*mut p64', poly64x2_t, '64', 'transmute(a)', 'crate::mem::align_of::()', 'q_v2i64'] + - ['*mut f32', float32x2_t, '32', 'transmute(a)', 'crate::mem::align_of::()', '_v2f32' ] + - ['*mut f32', float32x4_t, '32', 'transmute(a)', 'crate::mem::align_of::()', 'q_v4f32'] compose: + - Const: + - ALIGN + - "i32" + - "{type[4]} as i32" - FnCall: - "vst1{type[5]}" - - - 'ptr as *const i8' - - '{type[3]}' - - '{type[4]}' - + - ['ptr as *const i8','{type[3]}'] + - ['ALIGN'] - name: "vst1{neon_type[1].no}" doc: "Store multiple single-element structures from one, two, three, or four registers." @@ -13839,32 +13852,64 @@ intrinsics: - '{type[3]}' - '{type[4]}' - - - name: "vshiftins{type[0]}" + - name: "vshiftlins{type[0]}" visibility: private - doc: "Shift Right and Insert (immediate)" - arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}", "c: {neon_type[1]}"] + arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"] return_type: "{neon_type[1]}" safety: safe attr: - *target-is-arm - *neon-v7 - *neon-arm-unstable + - FnCall: [rustc_legacy_const_generics, ['2']] + static_defs: ['const N: i32'] types: - - ['_v8i8', "int8x8_t", '8'] - - ['_v16i8', 'int8x16_t', '8'] - - ['_v4i16', 'int16x4_t', '16'] - - ['_v8i16', 'int16x8_t', '16'] - - ['_v2i32', 'int32x2_t', '32'] - - ['_v4i32', 'int32x4_t', '32'] - - ['_v1i64', 'int64x1_t', '64'] - - ['_v2i64', 'int64x2_t', '64'] + - ['_v8i8', 'int8x8_t', '8', 'int8x8_t([N as i8; 8 ])' ] + - ['_v16i8', 'int8x16_t', '8', 'int8x16_t([N as i8; 16])'] + - ['_v4i16', 'int16x4_t', '16', 'int16x4_t([N as i16; 4])'] + - ['_v8i16', 'int16x8_t', '16', 'int16x8_t([N as i16; 8])'] + - ['_v2i32', 'int32x2_t', '32', 'int32x2_t([N; 2])' ] + - ['_v4i32', 'int32x4_t', '32', 'int32x4_t([N; 4])' ] + - ['_v1i64', 'int64x1_t', '64', 'int64x1_t([N as i64; 1])'] + - ['_v2i64', 'int64x2_t', '64', 'int64x2_t([N as i64; 2])'] compose: - LLVMLink: name: "_vshiftins{type[0]}" + arguments: ["a: {type[1]}", "b: {type[1]}", "c: {type[1]}"] links: - link: "llvm.arm.neon.vshiftins.{neon_type[1]}" arch: arm + - FnCall: ["_vshiftlins{type[0]}", [a,b, "const {{ {type[3]} }}"], [], true] + + - name: "vshiftrins{type[0]}" + doc: "Shift Right and Insert (immediate)" + visibility: private + arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"] + return_type: "{neon_type[1]}" + safety: safe + attr: + - *target-is-arm + - *neon-v7 + - *neon-arm-unstable + - FnCall: [rustc_legacy_const_generics, ['2']] + static_defs: ['const N: i32'] + types: + - ['_v8i8', 'int8x8_t', '8', 'int8x8_t([-N as i8; 8 ])' ] + - ['_v16i8', 'int8x16_t', '8', 'int8x16_t([-N as i8; 16])'] + - ['_v4i16', 'int16x4_t', '16', 'int16x4_t([-N as i16; 4])'] + - ['_v8i16', 'int16x8_t', '16', 'int16x8_t([-N as i16; 8])'] + - ['_v2i32', 'int32x2_t', '32', 'int32x2_t([-N; 2])' ] + - ['_v4i32', 'int32x4_t', '32', 'int32x4_t([-N; 4])' ] + - ['_v1i64', 'int64x1_t', '64', 'int64x1_t([-N as i64; 1])'] + - ['_v2i64', 'int64x2_t', '64', 'int64x2_t([-N as i64; 2])'] + compose: + - LLVMLink: + name: "_vshiftins{type[0]}" + arguments: ["a: {type[1]}", "b: {type[1]}", "c: {type[1]}"] + links: + - link: "llvm.arm.neon.vshiftins.{neon_type[1]}" + arch: arm + - FnCall: ["_vshiftrins{type[0]}", [a,b, "const {{ {type[3]} }}"], [], true] - name: "vsri{neon_type[0].N}" doc: "Shift Right and Insert (immediate)" @@ -13879,18 +13924,18 @@ intrinsics: - FnCall: [rustc_legacy_const_generics, ['2']] static_defs: ['const N: i32'] types: - - [uint8x8_t, "neon,v7", '8', '1 <= N && N <= 8', 'v8i8', 'int8x8_t::splat', '-N as i8'] - - [uint8x16_t, "neon,v7", '8', '1 <= N && N <= 8', 'v16i8', 'int8x16_t::splat', '-N as i8'] - - [uint16x4_t, "neon,v7", '16', '1 <= N && N <= 16', 'v4i16', 'int16x4_t::splat', '-N as i16'] - - [uint16x8_t, "neon,v7", '16', '1 <= N && N <= 16', 'v8i16', 'int16x8_t::splat', '-N as i16'] - - [uint32x2_t, "neon,v7", '32', '1 <= N && N <= 32', 'v2i32', 'int32x2_t::splat', '-N'] - - [uint32x4_t, "neon,v7", '32', '1 <= N && N <= 32', 'v4i32', 'int32x4_t::splat', '-N'] - - [uint64x1_t, "neon,v7", '64', '1 <= N && N <= 64', 'v1i64', 'int64x1_t::splat', '-N as i64'] - - [uint64x2_t, "neon,v7", '64', '1 <= N && N <= 64', 'v2i64', 'int64x2_t::splat', '-N as i64'] - - [poly8x8_t, "neon,v7", '8', '1 <= N && N <= 8', 'v8i8', 'int8x8_t::splat', '-N as i8'] - - [poly8x16_t, "neon,v7", '8', '1 <= N && N <= 8', 'v16i8', 'int8x16_t::splat', '-N as i8'] - - [poly16x4_t, "neon,v7", '16', '1 <= N && N <= 16', 'v4i16', 'int16x4_t::splat', '-N as i16'] - - [poly16x8_t, "neon,v7", '16', '1 <= N && N <= 16', 'v8i16', 'int16x8_t::splat', '-N as i16'] + - [uint8x8_t, "neon,v7", '8', '1 <= N && N <= 8', 'v8i8' ] + - [uint8x16_t, "neon,v7", '8', '1 <= N && N <= 8', 'v16i8'] + - [uint16x4_t, "neon,v7", '16', '1 <= N && N <= 16', 'v4i16'] + - [uint16x8_t, "neon,v7", '16', '1 <= N && N <= 16', 'v8i16'] + - [uint32x2_t, "neon,v7", '32', '1 <= N && N <= 32', 'v2i32'] + - [uint32x4_t, "neon,v7", '32', '1 <= N && N <= 32', 'v4i32'] + - [uint64x1_t, "neon,v7", '64', '1 <= N && N <= 64', 'v1i64'] + - [uint64x2_t, "neon,v7", '64', '1 <= N && N <= 64', 'v2i64'] + - [poly8x8_t, "neon,v7", '8', '1 <= N && N <= 8', 'v8i8' ] + - [poly8x16_t, "neon,v7", '8', '1 <= N && N <= 8', 'v16i8'] + - [poly16x4_t, "neon,v7", '16', '1 <= N && N <= 16', 'v4i16'] + - [poly16x8_t, "neon,v7", '16', '1 <= N && N <= 16', 'v8i16'] ## These live in ./crates/core_arch/src/arm/neon.rs #- [poly64x1_t, "neon,v7,aes", '64', '1 <= N && N <= 64', 'v1i64', 'int64x1_t::splat', '-N as i64'] #- [poly64x2_t, "neon,v7,aes", '64', '1 <= N && N <= 64', 'v2i64', 'int64x2_t::splat', '-N as i64'] @@ -13899,10 +13944,9 @@ intrinsics: - FnCall: - 'transmute' - - FnCall: - - "vshiftins_{type[4]}" + - "vshiftrins_{type[4]}::" - - FnCall: [transmute, [a]] - FnCall: [transmute, [b]] - - FnCall: ["{type[5]}", ["{type[6]}"]] - name: "vsri{neon_type[0].N}" doc: "Shift Right and Insert (immediate)" @@ -13917,21 +13961,20 @@ intrinsics: - FnCall: [rustc_legacy_const_generics, ['2']] safety: safe types: - - [int8x8_t, '8', '1 <= N && N <= 8', 'v8i8', 'int8x8_t::splat', '-N as i8'] - - [int8x16_t, '8', '1 <= N && N <= 8', 'v16i8', 'int8x16_t::splat', '-N as i8'] - - [int16x4_t, '16', '1 <= N && N <= 16', 'v4i16', 'int16x4_t::splat', '-N as i16'] - - [int16x8_t, '16', '1 <= N && N <= 16', 'v8i16', 'int16x8_t::splat', '-N as i16'] - - [int32x2_t, '32', '1 <= N && N <= 32', 'v2i32', 'int32x2_t::splat', '-N'] - - [int32x4_t, '32', '1 <= N && N <= 32', 'v4i32', 'int32x4_t::splat', '-N'] - - [int64x1_t, '64', '1 <= N && N <= 64', 'v1i64', 'int64x1_t::splat', '-N as i64'] - - [int64x2_t, '64', '1 <= N && N <= 64', 'v2i64', 'int64x2_t::splat', '-N as i64'] + - [int8x8_t, '8', '1 <= N && N <= 8', 'v8i8' ] + - [int8x16_t, '8', '1 <= N && N <= 8', 'v16i8'] + - [int16x4_t, '16', '1 <= N && N <= 16', 'v4i16'] + - [int16x8_t, '16', '1 <= N && N <= 16', 'v8i16'] + - [int32x2_t, '32', '1 <= N && N <= 32', 'v2i32'] + - [int32x4_t, '32', '1 <= N && N <= 32', 'v4i32'] + - [int64x1_t, '64', '1 <= N && N <= 64', 'v1i64'] + - [int64x2_t, '64', '1 <= N && N <= 64', 'v2i64'] compose: - FnCall: ["static_assert!", ['{type[2]}']] - FnCall: - - "vshiftins_{type[3]}" + - "vshiftrins_{type[3]}::" - - a - b - - FnCall: ["{type[4]}", ["{type[5]}"]] - name: "vsli{neon_type[0].N}" doc: "Shift Left and Insert (immediate)" @@ -13946,18 +13989,18 @@ intrinsics: - FnCall: [rustc_legacy_const_generics, ['2']] static_defs: ['const N: i32'] types: - - [uint8x8_t, "neon,v7", '8', 'static_assert_uimm_bits!', 'N, 3', 'v8i8', 'int8x8_t::splat', 'N as i8'] - - [uint8x16_t, "neon,v7", '8', 'static_assert_uimm_bits!', 'N, 3', 'v16i8', 'int8x16_t::splat', 'N as i8'] - - [uint16x4_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4', 'v4i16', 'int16x4_t::splat', 'N as i16'] - - [uint16x8_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4', 'v8i16', 'int16x8_t::splat', 'N as i16'] - - [uint32x2_t, "neon,v7", '32', 'static_assert!', 'N >= 0 && N <= 31', 'v2i32', 'int32x2_t::splat', 'N'] - - [uint32x4_t, "neon,v7", '32', 'static_assert!', 'N >= 0 && N <= 31', 'v4i32', 'int32x4_t::splat', 'N'] - - [uint64x1_t, "neon,v7", '64', 'static_assert!', 'N >= 0 && N <= 63', 'v1i64', 'int64x1_t::splat', 'N as i64'] - - [uint64x2_t, "neon,v7", '64', 'static_assert!', 'N >= 0 && N <= 63', 'v2i64', 'int64x2_t::splat', 'N as i64'] - - [poly8x8_t, "neon,v7", '8', 'static_assert_uimm_bits!', 'N, 3', 'v8i8', 'int8x8_t::splat', 'N as i8'] - - [poly8x16_t, "neon,v7", '8', 'static_assert_uimm_bits!', 'N, 3', 'v16i8', 'int8x16_t::splat', 'N as i8'] - - [poly16x4_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4', 'v4i16', 'int16x4_t::splat', 'N as i16'] - - [poly16x8_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4', 'v8i16', 'int16x8_t::splat', 'N as i16'] + - [uint8x8_t, "neon,v7", '8', 'static_assert_uimm_bits!', 'N, 3', 'v8i8'] + - [uint8x16_t, "neon,v7", '8', 'static_assert_uimm_bits!', 'N, 3', 'v16i8'] + - [uint16x4_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4', 'v4i16'] + - [uint16x8_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4', 'v8i16'] + - [uint32x2_t, "neon,v7", '32', 'static_assert!', 'N >= 0 && N <= 31', 'v2i32'] + - [uint32x4_t, "neon,v7", '32', 'static_assert!', 'N >= 0 && N <= 31', 'v4i32'] + - [uint64x1_t, "neon,v7", '64', 'static_assert!', 'N >= 0 && N <= 63', 'v1i64'] + - [uint64x2_t, "neon,v7", '64', 'static_assert!', 'N >= 0 && N <= 63', 'v2i64'] + - [poly8x8_t, "neon,v7", '8', 'static_assert_uimm_bits!', 'N, 3', 'v8i8'] + - [poly8x16_t, "neon,v7", '8', 'static_assert_uimm_bits!', 'N, 3', 'v16i8'] + - [poly16x4_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4', 'v4i16'] + - [poly16x8_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4', 'v8i16'] ## These live in ./crates/core_arch/src/arm/neon.rs #- [poly64x1_t, "neon,v7,aes", '"vsli.64"', 'static_assert!', '0 <= N && N <= 63', 'v1i64', 'int64x1_t::splat', 'N as i64'] #- [poly64x2_t, "neon,v7,aes", '"vsli.64"', 'static_assert!', '0 <= N && N <= 63', 'v2i64', 'int64x2_t::splat', 'N as i64'] @@ -13966,10 +14009,9 @@ intrinsics: - FnCall: - 'transmute' - - FnCall: - - "vshiftins_{type[5]}" + - "vshiftlins_{type[5]}::" - - FnCall: [transmute, [a]] - FnCall: [transmute, [b]] - - FnCall: ["{type[6]}", ["{type[7]}"]] - name: "vsli{neon_type[0].N}" doc: "Shift Left and Insert (immediate)" @@ -13984,21 +14026,20 @@ intrinsics: - FnCall: [rustc_legacy_const_generics, ['2']] static_defs: ['const N: i32'] types: - - [int8x8_t, '8', 'static_assert_uimm_bits!', 'N, 3', 'v8i8', 'int8x8_t::splat', 'N as i8'] - - [int8x16_t, '8', 'static_assert_uimm_bits!', 'N, 3', 'v16i8', 'int8x16_t::splat', 'N as i8'] - - [int16x4_t, '16', 'static_assert_uimm_bits!', 'N, 4', 'v4i16', 'int16x4_t::splat', 'N as i16'] - - [int16x8_t, '16', 'static_assert_uimm_bits!', 'N, 4', 'v8i16', 'int16x8_t::splat', 'N as i16'] - - [int32x2_t, '32', 'static_assert!', 'N >= 0 && N <= 31', 'v2i32', 'int32x2_t::splat', 'N'] - - [int32x4_t, '32', 'static_assert!', 'N >= 0 && N <= 31', 'v4i32', 'int32x4_t::splat', 'N'] - - [int64x1_t, '64', 'static_assert!', 'N >= 0 && N <= 63', 'v1i64', 'int64x1_t::splat', 'N as i64'] - - [int64x2_t, '64', 'static_assert!', 'N >= 0 && N <= 63', 'v2i64', 'int64x2_t::splat', 'N as i64'] + - [int8x8_t, '8', 'static_assert_uimm_bits!', 'N, 3', 'v8i8' ] + - [int8x16_t, '8', 'static_assert_uimm_bits!', 'N, 3', 'v16i8'] + - [int16x4_t, '16', 'static_assert_uimm_bits!', 'N, 4', 'v4i16'] + - [int16x8_t, '16', 'static_assert_uimm_bits!', 'N, 4', 'v8i16'] + - [int32x2_t, '32', 'static_assert!', 'N >= 0 && N <= 31', 'v2i32'] + - [int32x4_t, '32', 'static_assert!', 'N >= 0 && N <= 31', 'v4i32'] + - [int64x1_t, '64', 'static_assert!', 'N >= 0 && N <= 63', 'v1i64'] + - [int64x2_t, '64', 'static_assert!', 'N >= 0 && N <= 63', 'v2i64'] compose: - FnCall: ["{type[2]}", ['{type[3]}']] - FnCall: - - "vshiftins_{type[4]}" + - "vshiftlins_{type[4]}::" - - a - b - - FnCall: ["{type[5]}", ["{type[6]}"]] - name: "vcombine{neon_type[0].no}" doc: Join two smaller vectors into a single larger vector diff --git a/library/stdarch/crates/stdarch-gen-arm/src/expression.rs b/library/stdarch/crates/stdarch-gen-arm/src/expression.rs index d5644ef27d4b..bf48f0dab749 100644 --- a/library/stdarch/crates/stdarch-gen-arm/src/expression.rs +++ b/library/stdarch/crates/stdarch-gen-arm/src/expression.rs @@ -108,6 +108,8 @@ impl ToTokens for FnCall { pub enum Expression { /// (Re)Defines a variable Let(LetVariant), + /// Defines a const + Const(WildString, TypeKind, Box), /// Performs a variable assignment operation Assign(String, Box), /// Performs a macro call @@ -169,6 +171,7 @@ impl Expression { | LetVariant::WithType(_, _, ex) | LetVariant::MutWithType(_, _, ex), ) => ex.pre_build(ctx), + Self::Const(_, _, ex) => ex.pre_build(ctx), Self::CastAs(ex, _) => ex.pre_build(ctx), Self::Multiply(lhs, rhs) | Self::Xor(lhs, rhs) => { lhs.pre_build(ctx)?; @@ -245,6 +248,15 @@ impl Expression { ); ex.build(intrinsic, ctx) } + Self::Const(var_name, ty, ex) => { + var_name.build_acle(ctx.local)?; + ctx.local.variables.insert( + var_name.to_string(), + (ty.to_owned(), VariableType::Internal), + ); + ex.build(intrinsic, ctx) + } + Self::CastAs(ex, _) => ex.build(intrinsic, ctx), Self::Multiply(lhs, rhs) | Self::Xor(lhs, rhs) => { lhs.build(intrinsic, ctx)?; @@ -303,6 +315,7 @@ impl Expression { | LetVariant::WithType(_, _, exp) | LetVariant::MutWithType(_, _, exp), ) => exp.requires_unsafe_wrapper(ctx_fn), + Self::Const(_, _, exp) => exp.requires_unsafe_wrapper(ctx_fn), Self::Array(exps) => exps.iter().any(|exp| exp.requires_unsafe_wrapper(ctx_fn)), Self::Multiply(lhs, rhs) | Self::Xor(lhs, rhs) => { lhs.requires_unsafe_wrapper(ctx_fn) || rhs.requires_unsafe_wrapper(ctx_fn) @@ -462,6 +475,10 @@ impl ToTokens for Expression { let var_ident = format_ident!("{}", var_name.to_string()); tokens.append_all(quote! { let mut #var_ident: #ty = #exp }) } + Self::Const(var_name, ty, exp) => { + let var_ident = format_ident!("{}", var_name.to_string()); + tokens.append_all(quote! { const #var_ident: #ty = #exp }) + } Self::Assign(var_name, exp) => { /* If we are dereferencing a variable to assign a value \ * the 'format_ident!' macro does not like the asterix */ diff --git a/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs b/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs index efaa9e141889..0cdff6ff6c39 100644 --- a/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs +++ b/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs @@ -1730,7 +1730,8 @@ fn create_tokens(intrinsic: &Intrinsic, endianness: Endianness, tokens: &mut Tok "{fn_name} needs to be private, or to have documentation." ); assert!( - !safety.has_doc_comments(), + !safety.has_doc_comments() + || matches!(intrinsic.visibility, FunctionVisibility::Private), "{fn_name} needs a documentation section for its safety comments." ); } From 7593f9d70612de27d8db97260ad247a8fa675a82 Mon Sep 17 00:00:00 2001 From: Redddy Date: Tue, 25 Nov 2025 01:18:01 +0900 Subject: [PATCH 0120/3801] Fix link to README in ui test documentation Updated link from SUMMARY.md to README.md in ui.md --- src/doc/rustc-dev-guide/src/tests/ui.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index 497e6109446e..759029e67132 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -12,7 +12,7 @@ the resulting program](#controlling-passfail-expectations) to verify its behavior. For a survey of each subdirectory's purpose under `tests/ui`, consult the -[SUMMARY.md](https://github.com/rust-lang/rust/tree/HEAD/tests/ui/SUMMARY.md). +[README.md](https://github.com/rust-lang/rust/tree/HEAD/tests/ui/README.md). This is useful if you write a new test, and are looking for a category to place it in. From b3f67c73d0830ac071228de41820529c2c113dbf Mon Sep 17 00:00:00 2001 From: valadaptive Date: Mon, 24 Nov 2025 14:08:15 -0500 Subject: [PATCH 0121/3801] Correct the docs for WASM relaxed_simd's min/max --- .../core_arch/src/wasm32/relaxed_simd.rs | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/wasm32/relaxed_simd.rs b/library/stdarch/crates/core_arch/src/wasm32/relaxed_simd.rs index a9b7e9c04d11..8a9d46984dbb 100644 --- a/library/stdarch/crates/core_arch/src/wasm32/relaxed_simd.rs +++ b/library/stdarch/crates/core_arch/src/wasm32/relaxed_simd.rs @@ -248,8 +248,10 @@ pub fn i64x2_relaxed_laneselect(a: v128, b: v128, m: v128) -> v128 { #[stable(feature = "stdarch_wasm_relaxed_simd", since = "1.82.0")] pub use i64x2_relaxed_laneselect as u64x2_relaxed_laneselect; -/// A relaxed version of `f32x4_min` which is either `f32x4_min` or -/// `f32x4_pmin`. +/// A relaxed version of `f32x4_min` which has implementation-specific behavior +/// when its operands are NaN or signed zeroes. For more information, see [the +/// WebAssembly +/// specification](https://webassembly.github.io/spec/core/exec/numerics.html#op-frelaxed-min). #[inline] #[cfg_attr(test, assert_instr(f32x4.relaxed_min))] #[target_feature(enable = "relaxed-simd")] @@ -259,8 +261,10 @@ pub fn f32x4_relaxed_min(a: v128, b: v128) -> v128 { unsafe { llvm_f32x4_relaxed_min(a.as_f32x4(), b.as_f32x4()).v128() } } -/// A relaxed version of `f32x4_max` which is either `f32x4_max` or -/// `f32x4_pmax`. +/// A relaxed version of `f32x4_max` which has implementation-specific behavior +/// when its operands are NaN or signed zeroes. For more information, see [the +/// WebAssembly +/// specification](https://webassembly.github.io/spec/core/exec/numerics.html#op-frelaxed-max). #[inline] #[cfg_attr(test, assert_instr(f32x4.relaxed_max))] #[target_feature(enable = "relaxed-simd")] @@ -270,8 +274,10 @@ pub fn f32x4_relaxed_max(a: v128, b: v128) -> v128 { unsafe { llvm_f32x4_relaxed_max(a.as_f32x4(), b.as_f32x4()).v128() } } -/// A relaxed version of `f64x2_min` which is either `f64x2_min` or -/// `f64x2_pmin`. +/// A relaxed version of `f64x2_min` which has implementation-specific behavior +/// when its operands are NaN or signed zeroes. For more information, see [the +/// WebAssembly +/// specification](https://webassembly.github.io/spec/core/exec/numerics.html#op-frelaxed-min). #[inline] #[cfg_attr(test, assert_instr(f64x2.relaxed_min))] #[target_feature(enable = "relaxed-simd")] @@ -281,8 +287,10 @@ pub fn f64x2_relaxed_min(a: v128, b: v128) -> v128 { unsafe { llvm_f64x2_relaxed_min(a.as_f64x2(), b.as_f64x2()).v128() } } -/// A relaxed version of `f64x2_max` which is either `f64x2_max` or -/// `f64x2_pmax`. +/// A relaxed version of `f64x2_max` which has implementation-specific behavior +/// when its operands are NaN or signed zeroes. For more information, see [the +/// WebAssembly +/// specification](https://webassembly.github.io/spec/core/exec/numerics.html#op-frelaxed-max). #[inline] #[cfg_attr(test, assert_instr(f64x2.relaxed_max))] #[target_feature(enable = "relaxed-simd")] From 09f774da8eccc725f54b38715c88cf7d52315361 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sun, 23 Nov 2025 01:56:15 -0500 Subject: [PATCH 0122/3801] Mark all arms as being from a desugaring when lowering `?` and for loops. --- compiler/rustc_ast_lowering/src/expr.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 524f8b054cb4..0ab3191f23be 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -941,14 +941,14 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr)); this.arena.alloc(this.expr(gen_future_span, expr_break)) }); - self.arm(ready_pat, break_x) + self.arm(ready_pat, break_x, span) }; // `::std::task::Poll::Pending => {}` let pending_arm = { let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]); let empty_block = self.expr_block_empty(span); - self.arm(pending_pat, empty_block) + self.arm(pending_pat, empty_block, span) }; let inner_match_stmt = { @@ -1002,7 +1002,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }); // mut __awaitee => loop { ... } - let awaitee_arm = self.arm(awaitee_pat, loop_expr); + let awaitee_arm = self.arm(awaitee_pat, loop_expr, span); // `match ::std::future::IntoFuture::into_future() { ... }` let into_future_expr = match await_kind { @@ -1788,7 +1788,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let break_expr = self.with_loop_scope(loop_hir_id, |this| this.expr_break_alloc(for_span)); let pat = self.pat_none(for_span); - self.arm(pat, break_expr) + self.arm(pat, break_expr, for_span) }; // Some() => , @@ -1797,7 +1797,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let body_block = self.with_loop_scope(loop_hir_id, |this| this.lower_block(body, false)); let body_expr = self.arena.alloc(self.expr_block(body_block)); - self.arm(some_pat, body_expr) + self.arm(some_pat, body_expr, for_span) }; // `mut iter` @@ -1856,7 +1856,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let loop_expr = self.arena.alloc(hir::Expr { hir_id: loop_hir_id, kind, span: for_span }); // `mut iter => { ... }` - let iter_arm = self.arm(iter_pat, loop_expr); + let iter_arm = self.arm(iter_pat, loop_expr, for_span); let match_expr = match loop_kind { ForLoopKind::For => { @@ -1901,7 +1901,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::LangItem::IntoAsyncIterIntoIter, arena_vec![self; head], ); - let iter_arm = self.arm(async_iter_pat, inner_match_expr); + let iter_arm = self.arm(async_iter_pat, inner_match_expr, for_span); self.arena.alloc(self.expr_match( for_span, iter, @@ -1968,7 +1968,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let val_expr = self.expr_ident(span, val_ident, val_pat_nid); self.lower_attrs(val_expr.hir_id, &attrs, span, Target::Expression); let continue_pat = self.pat_cf_continue(unstable_span, val_pat); - self.arm(continue_pat, val_expr) + self.arm(continue_pat, val_expr, try_span) }; // `ControlFlow::Break(residual) => @@ -2004,7 +2004,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_attrs(ret_expr.hir_id, &attrs, span, Target::Expression); let break_pat = self.pat_cf_break(try_span, residual_local); - self.arm(break_pat, ret_expr) + self.arm(break_pat, ret_expr, try_span) }; hir::ExprKind::Match( @@ -2329,12 +2329,13 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, pat: &'hir hir::Pat<'hir>, expr: &'hir hir::Expr<'hir>, + span: Span, ) -> hir::Arm<'hir> { hir::Arm { hir_id: self.next_id(), pat, guard: None, - span: self.lower_span(expr.span), + span: self.lower_span(span), body: expr, } } From 4aa5ee99c848e1da81ddac872d9c82dc3faa6943 Mon Sep 17 00:00:00 2001 From: Redddy Date: Tue, 25 Nov 2025 13:42:45 +0900 Subject: [PATCH 0123/3801] Update contributing.md with Rust Book reference Added a reference to The Rust Book for more information on Rust's release channels. --- src/doc/rustc-dev-guide/src/contributing.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 8c764c31dbfa..4476ed842dae 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -52,6 +52,7 @@ the CI to build and test their PR (e.g. when developing on a slow machine). Rust has strong backwards-compatibility guarantees. Thus, new features can't just be implemented directly in stable Rust. Instead, we have 3 release channels: stable, beta, and nightly. +See [The Rust Book] for more details on Rust’s train release model. - **Stable**: this is the latest stable release for general usage. - **Beta**: this is the next release (will be stable within 6 weeks). @@ -62,6 +63,8 @@ Instead, we have 3 release channels: stable, beta, and nightly. See [this chapter on implementing new features](./implementing_new_features.md) for more information. +[The Rust Book]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html + ### Breaking changes Breaking changes have a [dedicated section][Breaking Changes] in the dev-guide. From 0fc34524d4688f9e34f5e661ca9504eb2d4a7b28 Mon Sep 17 00:00:00 2001 From: Young-Flash Date: Tue, 25 Nov 2025 22:37:48 +0800 Subject: [PATCH 0124/3801] internal: add missing method for SyntaxFactory --- .../crates/syntax/src/ast/make.rs | 2 +- .../src/ast/syntax_factory/constructors.rs | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index dba39204e32e..19019ad08d81 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -658,7 +658,7 @@ pub fn expr_if( }; expr_from_text(&format!("if {condition} {then_branch} {else_branch}")) } -pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::Expr { +pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::ForExpr { expr_from_text(&format!("for {pat} in {expr} {block}")) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 969552392180..e0fac97f67ab 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -671,6 +671,26 @@ impl SyntaxFactory { ast } + pub fn expr_for_loop( + &self, + pat: ast::Pat, + iterable: ast::Expr, + body: ast::BlockExpr, + ) -> ast::ForExpr { + let ast = + make::expr_for_loop(pat.clone(), iterable.clone(), body.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.map_node(iterable.syntax().clone(), ast.iterable().unwrap().syntax().clone()); + builder.map_node(body.syntax().clone(), ast.loop_body().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn expr_let(&self, pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr { let ast = make::expr_let(pattern.clone(), expr.clone()).clone_for_update(); From cbc3860a72bd0675691a7f0ea7678296447b2740 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Nov 2025 10:15:19 +0000 Subject: [PATCH 0125/3801] Use rust rather than LLVM target features in the target spec This works better with non-LLVM codegen backends. --- src/gcc_util.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gcc_util.rs b/src/gcc_util.rs index e4e2dfdd5643..330b5ff6828d 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -33,11 +33,7 @@ pub(crate) fn global_gcc_features(sess: &Session) -> Vec { // should be taken in cases like these. let mut features = vec![]; - // Features implied by an implicit or explicit `--target`. - features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from)); - - // -Ctarget-features - target_features::flag_to_backend_features(sess, |feature, enable| { + let mut extend_backend_features = |feature: &str, enable: bool| { // We run through `to_gcc_features` when // passing requests down to GCC. This means that all in-language // features also work on the command line instead of having two @@ -48,7 +44,13 @@ pub(crate) fn global_gcc_features(sess: &Session) -> Vec { .flat_map(|feat| to_gcc_features(sess, feat).into_iter()) .map(|feature| if !enable { format!("-{}", feature) } else { feature.to_string() }), ); - }); + }; + + // Features implied by an implicit or explicit `--target`. + target_features::target_spec_to_backend_features(sess, &mut extend_backend_features); + + // -Ctarget-features + target_features::flag_to_backend_features(sess, extend_backend_features); gcc_features_by_flags(sess, &mut features); @@ -66,6 +68,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> (&Arch::X86 | &Arch::X86_64, "rdrand") => smallvec!["rdrnd"], (&Arch::X86 | &Arch::X86_64, "bmi1") => smallvec!["bmi"], (&Arch::X86 | &Arch::X86_64, "cmpxchg16b") => smallvec!["cx16"], + (&Arch::X86 | &Arch::X86_64, "lahfsahf") => smallvec!["sahf"], (&Arch::X86 | &Arch::X86_64, "avx512vaes") => smallvec!["vaes"], (&Arch::X86 | &Arch::X86_64, "avx512gfni") => smallvec!["gfni"], (&Arch::X86 | &Arch::X86_64, "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], From b881bd29fdcd5c906396977358ef9b308f982aee Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 25 Nov 2025 15:43:23 -0500 Subject: [PATCH 0126/3801] add a high-level design description --- src/doc/rustc-dev-guide/src/offload/internals.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/offload/internals.md b/src/doc/rustc-dev-guide/src/offload/internals.md index 28857a6e78bf..77a4cadbcb98 100644 --- a/src/doc/rustc-dev-guide/src/offload/internals.md +++ b/src/doc/rustc-dev-guide/src/offload/internals.md @@ -7,3 +7,10 @@ also offer more advanced, possibly unsafe, interfaces which allow a higher degre The implementation is based on LLVM's "offload" project, which is already used by OpenMP to run Fortran or C++ code on GPUs. While the project is under development, users will need to call other compilers like clang to finish the compilation process. + +## High-level design: +We use a single-source, two-pass compilation approach. + +First we compile all functions that should be offloaded for the device (e.g nvptx64, amdgcn-amd-amdhsa, intel in the future). Currently we require cumbersome `#cfg(target_os="")` annotations, but we intend to recognize those in the future based on our offload intrinsic. + +We then compile the code for the host (e.g. x86-64), where most of the offloading logic happens. On the host side, we generate calls to the openmp offload runtime, to inform it about the layout of the types (a simplified version of the autodiff TypeTrees). We also use the type system to figure out whether kernel arguments have to be moved only to the device (e.g. `&[f32;1024]`), from the device, or both (e.g. `&mut [f64]`). We then launched the kernel, after which we inform the runtime to end this environment and move data back (as far as needed). From e4777322534026b246592d8b80d915085df07cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Tue, 9 Sep 2025 18:45:23 +0200 Subject: [PATCH 0127/3801] =?UTF-8?q?Don't=20strip=20shebang=20in=20expr-c?= =?UTF-8?q?txt=20`include!(=E2=80=A6)`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rustc_builtin_macros/src/source_util.rs | 4 +-- .../include-macros/auxiliary/shebang-expr.rs | 3 ++ .../include-macros/auxiliary/shebang-items.rs | 3 ++ .../ui/include-macros/shebang-in-expr-ctxt.rs | 16 +++++++++ .../shebang-in-expr-ctxt.stderr | 33 +++++++++++++++++++ .../ui/include-macros/shebang-in-item-ctxt.rs | 4 +++ 6 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 tests/ui/include-macros/auxiliary/shebang-expr.rs create mode 100644 tests/ui/include-macros/auxiliary/shebang-items.rs create mode 100644 tests/ui/include-macros/shebang-in-expr-ctxt.rs create mode 100644 tests/ui/include-macros/shebang-in-expr-ctxt.stderr create mode 100644 tests/ui/include-macros/shebang-in-item-ctxt.rs diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 16adaab15c52..b063413bce36 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -147,9 +147,7 @@ pub(crate) fn expand_include<'cx>( let mut p = unwrap_or_emit_fatal(new_parser_from_file( self.psess, &self.path, - // Don't strip frontmatter for backward compatibility, `---` may be the start of a - // manifold negation. FIXME: Ideally, we wouldn't strip shebangs here either. - StripTokens::Shebang, + StripTokens::Nothing, Some(self.span), )); let expr = parse_expr(&mut p).ok()?; diff --git a/tests/ui/include-macros/auxiliary/shebang-expr.rs b/tests/ui/include-macros/auxiliary/shebang-expr.rs new file mode 100644 index 000000000000..73e92b5a889e --- /dev/null +++ b/tests/ui/include-macros/auxiliary/shebang-expr.rs @@ -0,0 +1,3 @@ +#!/usr/bin/env my-rust-expr-evaluator + +2 * (1 + 3) diff --git a/tests/ui/include-macros/auxiliary/shebang-items.rs b/tests/ui/include-macros/auxiliary/shebang-items.rs new file mode 100644 index 000000000000..b9011b62cc91 --- /dev/null +++ b/tests/ui/include-macros/auxiliary/shebang-items.rs @@ -0,0 +1,3 @@ +#!/usr/bin/env my-rust-script-runner + +fn main() {} diff --git a/tests/ui/include-macros/shebang-in-expr-ctxt.rs b/tests/ui/include-macros/shebang-in-expr-ctxt.rs new file mode 100644 index 000000000000..b6d3fa9e076f --- /dev/null +++ b/tests/ui/include-macros/shebang-in-expr-ctxt.rs @@ -0,0 +1,16 @@ +// Check that we *don't* strip shebang in files that were `include`d in an expression or +// expression statement context. +// We do that to be consistent with frontmatter (see test `frontmatter/include-in-expr-ctxt.rs`). +// While there could be niche use cases for such shebang, it seems more confusing than beneficial. + +fn main() { + // expr ctxt + _ = include!("auxiliary/shebang-expr.rs"); + //~^ ERROR non-expression macro in expression position + //~? ERROR expected `[`, found `/` + + // stmt ctxt (reuses expr expander) + include!("auxiliary/shebang-expr.rs"); + //~^ ERROR non-statement macro in statement position + //~? ERROR expected `[`, found `/` +} diff --git a/tests/ui/include-macros/shebang-in-expr-ctxt.stderr b/tests/ui/include-macros/shebang-in-expr-ctxt.stderr new file mode 100644 index 000000000000..9e95b02a78dc --- /dev/null +++ b/tests/ui/include-macros/shebang-in-expr-ctxt.stderr @@ -0,0 +1,33 @@ +error: expected `[`, found `/` + --> $DIR/auxiliary/shebang-expr.rs:1:3 + | +LL | #!/usr/bin/env my-rust-expr-evaluator + | ^ expected `[` + | + = note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not + = help: if you meant this to be a shebang interpreter directive, move it to the very start of the file + +error: non-expression macro in expression position: include + --> $DIR/shebang-in-expr-ctxt.rs:8:9 + | +LL | _ = include!("auxiliary/shebang-expr.rs"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected `[`, found `/` + --> $DIR/auxiliary/shebang-expr.rs:1:3 + | +LL | #!/usr/bin/env my-rust-expr-evaluator + | ^ expected `[` + | + = note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not + = help: if you meant this to be a shebang interpreter directive, move it to the very start of the file + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: non-statement macro in statement position: include + --> $DIR/shebang-in-expr-ctxt.rs:13:5 + | +LL | include!("auxiliary/shebang-expr.rs"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/include-macros/shebang-in-item-ctxt.rs b/tests/ui/include-macros/shebang-in-item-ctxt.rs new file mode 100644 index 000000000000..3e0718e287f0 --- /dev/null +++ b/tests/ui/include-macros/shebang-in-item-ctxt.rs @@ -0,0 +1,4 @@ +// Ensure that we strip shebang in files `include`d in item contexts. +//@ check-pass + +include!("auxiliary/shebang-items.rs"); From 2af849a6e5c5706528efdf7ca3507525b64a074b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Nov 2025 19:41:43 +0100 Subject: [PATCH 0128/3801] Merge commit '55171cfa8b53970e06dcd2f5f2e2b8d82eeb0885' into subtree-update_cg_gcc_2025-11-26 --- .github/workflows/failures.yml | 2 - .github/workflows/gcc12.yml | 6 -- .github/workflows/release.yml | 3 + .github/workflows/stdarch.yml | 9 +- Cargo.lock | 8 +- Cargo.toml | 6 +- build_system/src/build.rs | 24 +++-- build_system/src/config.rs | 13 --- build_system/src/test.rs | 14 +-- doc/tips.md | 8 ++ libgccjit.version | 2 +- rust-toolchain | 2 +- src/attributes.rs | 2 +- src/back/lto.rs | 1 + src/builder.rs | 3 +- src/consts.rs | 3 +- src/context.rs | 4 +- src/declare.rs | 2 +- src/intrinsic/archs.rs | 20 +--- src/intrinsic/llvm.rs | 13 ++- src/intrinsic/simd.rs | 190 ++++++++++++++++++++++++++++++++- src/lib.rs | 59 +++++++--- src/mono_item.rs | 3 +- src/type_.rs | 2 +- tests/failing-lto-tests.txt | 7 ++ tests/failing-ui-tests.txt | 13 ++- tests/lang_tests_common.rs | 26 +---- tools/generate_intrinsics.py | 3 +- 28 files changed, 315 insertions(+), 133 deletions(-) create mode 100644 tests/failing-lto-tests.txt diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index 67b7fbe4478b..aa4b4dc22c3e 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -54,8 +54,6 @@ jobs: if: matrix.libgccjit_version.gcc == 'libgccjit12.so' run: | echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml - echo "LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV - name: Download artifact if: matrix.libgccjit_version.gcc != 'libgccjit12.so' diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index da9a1506855c..55b090894b4a 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -51,12 +51,6 @@ jobs: - name: Setup path to libgccjit run: echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml - - name: Set env - run: | - echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - echo "LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV - #- name: Cache rust repository ## We only clone the rust repository for rustc tests #if: ${{ contains(matrix.commands, 'rustc') }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 52f94dc2970a..895d66f9a4ac 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,6 +72,9 @@ jobs: git config --global user.name "User" ./y.sh prepare + - name: Add more failing tests (some panic and debuginfo tests fail) + run: cat tests/failing-lto-tests.txt >> tests/failing-ui-tests.txt + - name: Run tests run: | # FIXME(antoyo): we cannot enable LTO for stdarch tests currently because of some failing LTO tests using proc-macros. diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index 184f122cc1c1..c0a0e3344cc2 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -59,9 +59,8 @@ jobs: sudo ln -s /usr/share/intel-sde/sde /usr/bin/sde sudo ln -s /usr/share/intel-sde/sde64 /usr/bin/sde64 - - name: Set env + - name: Set config run: | - echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV echo 'download-gccjit = true' > config.toml - name: Build @@ -69,12 +68,6 @@ jobs: ./y.sh prepare --only-libcore ./y.sh build --sysroot --release --release-sysroot - - name: Set env (part 2) - run: | - # Set the `LD_LIBRARY_PATH` and `LIBRARY_PATH` env variables... - echo "LD_LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV - echo "LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV - - name: Clean if: ${{ !matrix.cargo_runner }} run: | diff --git a/Cargo.lock b/Cargo.lock index 181d3aa89bc8..00bdacaca676 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,18 +56,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "2.10.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60362e038e71e4bdc1a5b23fb45e1aba587b5947fe0db58f4871d95608f89eca" +checksum = "ff80f4d6d0749eab3a69122210b3a1fdd52edb6162781aadd7c4842e26983683" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.9.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd542c8414e122217551c6af6b7d33acf51a227aee85276f218c087525e01bb" +checksum = "263da4f60b7bb5d6a5b21efda961741051ebdbf0e380a09118b03cce66a8c77e" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index d3ff2757857b..18847f50d46a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,11 +24,11 @@ default = ["master"] [dependencies] object = { version = "0.37.0", default-features = false, features = ["std", "read"] } tempfile = "3.20" -gccjit = "2.10" -#gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } +gccjit = { version = "3.1.1", features = ["dlopen"] } +#gccjit = { git = "https://github.com/rust-lang/gccjit.rs", branch = "error-dlopen", features = ["dlopen"] } # Local copy. -#gccjit = { path = "../gccjit.rs" } +#gccjit = { path = "../gccjit.rs", features = ["dlopen"] } [dev-dependencies] boml = "0.3.1" diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 6aa5faec4c81..56503b239a3b 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -1,7 +1,8 @@ use std::collections::HashMap; use std::ffi::OsStr; use std::fs; -use std::path::Path; +use std::os::unix::fs::symlink; +use std::path::{Path, PathBuf}; use crate::config::{Channel, ConfigInfo}; use crate::utils::{ @@ -100,6 +101,18 @@ fn cleanup_sysroot_previous_build(library_dir: &Path) { pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Result<(), String> { let start_dir = get_sysroot_dir(); + // Symlink libgccjit.so to sysroot. + let lib_path = start_dir.join("sysroot").join("lib"); + let libgccjit_path = + PathBuf::from(config.gcc_path.as_ref().expect("libgccjit should be set by this point")) + .join("libgccjit.so"); + let libgccjit_in_sysroot_path = lib_path.join("libgccjit.so"); + // First remove the file to be able to create the symlink even when the file already exists. + let _ = fs::remove_file(&libgccjit_in_sysroot_path); + create_dir(&lib_path)?; + symlink(libgccjit_path, libgccjit_in_sysroot_path) + .map_err(|error| format!("Cannot create symlink for libgccjit.so: {}", error))?; + let library_dir = start_dir.join("sysroot_src").join("library"); cleanup_sysroot_previous_build(&library_dir); @@ -148,7 +161,7 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu run_command_with_output_and_env(&args, Some(&sysroot_dir), Some(&env))?; // Copy files to sysroot - let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple)); + let sysroot_path = lib_path.join(format!("rustlib/{}/lib/", config.target_triple)); // To avoid errors like "multiple candidates for `rmeta` dependency `core` found", we clean the // sysroot directory before copying the sysroot build artifacts. let _ = fs::remove_dir_all(&sysroot_path); @@ -175,13 +188,6 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu fn build_codegen(args: &mut BuildArg) -> Result<(), String> { let mut env = HashMap::new(); - let gcc_path = - args.config_info.gcc_path.clone().expect( - "The config module should have emitted an error if the GCC path wasn't provided", - ); - env.insert("LD_LIBRARY_PATH".to_string(), gcc_path.clone()); - env.insert("LIBRARY_PATH".to_string(), gcc_path); - if args.config_info.no_default_features { env.insert("RUSTFLAGS".to_string(), "-Csymbol-mangling-version=v0".to_string()); } diff --git a/build_system/src/config.rs b/build_system/src/config.rs index a5f802e293a9..19255e1ba2b2 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -429,19 +429,6 @@ impl ConfigInfo { // display metadata load errors env.insert("RUSTC_LOG".to_string(), "warn".to_string()); - let sysroot = current_dir - .join(get_sysroot_dir()) - .join(format!("sysroot/lib/rustlib/{}/lib", self.target_triple)); - let ld_library_path = format!( - "{target}:{sysroot}:{gcc_path}", - target = self.cargo_target_dir, - sysroot = sysroot.display(), - gcc_path = gcc_path, - ); - env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone()); - env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone()); - env.insert("DYLD_LIBRARY_PATH".to_string(), ld_library_path); - // NOTE: To avoid the -fno-inline errors, use /opt/gcc/bin/gcc instead of cc. // To do so, add a symlink for cc to /opt/gcc/bin/gcc in our PATH. // Another option would be to add the following Rust flag: -Clinker=/opt/gcc/bin/gcc diff --git a/build_system/src/test.rs b/build_system/src/test.rs index dbdaf2a63ef2..8aabfa894ce0 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -214,14 +214,6 @@ fn cargo_tests(test_env: &Env, test_args: &TestArg) -> Result<(), String> { // We don't want to pass things like `RUSTFLAGS`, since they contain the -Zcodegen-backend flag. // That would force `cg_gcc` to *rebuild itself* and only then run tests, which is undesirable. let mut env = HashMap::new(); - env.insert( - "LD_LIBRARY_PATH".into(), - test_env.get("LD_LIBRARY_PATH").expect("LD_LIBRARY_PATH missing!").to_string(), - ); - env.insert( - "LIBRARY_PATH".into(), - test_env.get("LIBRARY_PATH").expect("LIBRARY_PATH missing!").to_string(), - ); env.insert( "CG_RUSTFLAGS".into(), test_env.get("CG_RUSTFLAGS").map(|s| s.as_str()).unwrap_or("").to_string(), @@ -1065,6 +1057,7 @@ where &test_dir, &"--compiletest-rustc-args", &rustc_args, + &"--bypass-ignore-backends", ]; if run_ignored_tests { @@ -1275,11 +1268,6 @@ pub fn run() -> Result<(), String> { if !args.use_system_gcc { args.config_info.setup_gcc_path()?; - let gcc_path = args.config_info.gcc_path.clone().expect( - "The config module should have emitted an error if the GCC path wasn't provided", - ); - env.insert("LIBRARY_PATH".to_string(), gcc_path.clone()); - env.insert("LD_LIBRARY_PATH".to_string(), gcc_path); } build_if_no_backend(&env, &args)?; diff --git a/doc/tips.md b/doc/tips.md index e62c3402a292..38bc98c02d92 100644 --- a/doc/tips.md +++ b/doc/tips.md @@ -9,6 +9,14 @@ be useful. CG_RUSTFLAGS="-Clink-args=-save-temps -v" ../y.sh cargo build ``` +### How to send arguments to GCC + +The `-Cllvm-args` `rustc` flag is repurposed by `rustc_codegen_gcc` to pass arguments directly to the GCC backend. You can use it via the `CG_RUSTFLAGS` environment variable. For example, to pass a `-f` flag to GCC: + +``` +CG_RUSTFLAGS="-Cllvm-args=-fflag-name" ../y.sh cargo build +``` + ### How to see the personality functions in the asm dump ``` diff --git a/libgccjit.version b/libgccjit.version index b8d4166542bc..bab62f642365 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -28b84db392ac0a572f1a2a2a1317aa5f2bc742cb +0081ca6631abdfa02bf42bc85aaf507b8a0e6beb diff --git a/rust-toolchain b/rust-toolchain index 9813bbea00c4..f9645451e964 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-11-04" +channel = "nightly-2025-11-24" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/attributes.rs b/src/attributes.rs index 5df1dc41b01d..cd8c1206c821 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -86,7 +86,7 @@ fn inline_attr<'gcc, 'tcx>( /// attributes. pub fn from_fn_attrs<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, - #[cfg_attr(not(feature = "master"), allow(unused_variables))] func: Function<'gcc>, + #[cfg_attr(not(feature = "master"), expect(unused_variables))] func: Function<'gcc>, instance: ty::Instance<'tcx>, ) { let codegen_fn_attrs = cx.tcx.codegen_instance_attrs(instance.def); diff --git a/src/back/lto.rs b/src/back/lto.rs index 404064fb7a06..840f51c0685d 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -633,6 +633,7 @@ pub fn optimize_thin_module( save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); } }*/ + // FIXME: switch to #[expect] when the clippy bug is fixed. #[allow(clippy::let_and_return)] module } diff --git a/src/builder.rs b/src/builder.rs index 132c43ef3cda..c0519f7a68e2 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1481,7 +1481,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { variable.to_rvalue() } - #[allow(dead_code)] fn va_arg(&mut self, _list: RValue<'gcc>, _ty: Type<'gcc>) -> RValue<'gcc> { unimplemented!(); } @@ -2517,7 +2516,7 @@ impl ToGccComp for RealPredicate { } #[repr(C)] -#[allow(non_camel_case_types)] +#[expect(non_camel_case_types)] enum MemOrdering { __ATOMIC_RELAXED, __ATOMIC_CONSUME, diff --git a/src/consts.rs b/src/consts.rs index ec7d4b285a3f..6fb96f8832b9 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -58,7 +58,6 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { global_value } - #[cfg_attr(not(feature = "master"), allow(unused_mut))] fn codegen_static(&mut self, def_id: DefId) { let attrs = self.tcx.codegen_fn_attrs(def_id); @@ -162,7 +161,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { // TODO(antoyo) } - #[cfg_attr(not(feature = "master"), allow(unused_variables))] + #[cfg_attr(not(feature = "master"), expect(unused_variables))] pub fn add_used_function(&self, function: Function<'gcc>) { #[cfg(feature = "master")] function.add_attribute(FnAttribute::Used); diff --git a/src/context.rs b/src/context.rs index c9ae96777de4..dbb89a4ff7db 100644 --- a/src/context.rs +++ b/src/context.rs @@ -28,7 +28,7 @@ use crate::abi::conv_to_fn_attribute; use crate::callee::get_fn; use crate::common::SignType; -#[cfg_attr(not(feature = "master"), allow(dead_code))] +#[cfg_attr(not(feature = "master"), expect(dead_code))] pub struct CodegenCx<'gcc, 'tcx> { /// A cache of converted ConstAllocs pub const_cache: RefCell>>, @@ -132,7 +132,7 @@ pub struct CodegenCx<'gcc, 'tcx> { } impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] pub fn new( context: &'gcc Context<'gcc>, codegen_unit: &'tcx CodegenUnit<'tcx>, diff --git a/src/declare.rs b/src/declare.rs index 691fd8729e39..42d6fb17a88b 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -156,7 +156,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. -#[allow(clippy::let_and_return)] +#[expect(clippy::let_and_return)] fn declare_raw_fn<'gcc>( cx: &CodegenCx<'gcc, '_>, name: &str, diff --git a/src/intrinsic/archs.rs b/src/intrinsic/archs.rs index c51bcbcedd67..bb8bcbf66f38 100644 --- a/src/intrinsic/archs.rs +++ b/src/intrinsic/archs.rs @@ -10,7 +10,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { }; match arch { "AMDGPU" => { - #[allow(non_snake_case)] + #[expect(non_snake_case)] fn AMDGPU(name: &str, full_name: &str) -> &'static str { match name { // AMDGPU @@ -48,7 +48,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { AMDGPU(name, full_name) } "aarch64" => { - #[allow(non_snake_case)] fn aarch64(name: &str, full_name: &str) -> &'static str { match name { // aarch64 @@ -81,7 +80,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { aarch64(name, full_name) } "amdgcn" => { - #[allow(non_snake_case)] fn amdgcn(name: &str, full_name: &str) -> &'static str { match name { // amdgcn @@ -524,7 +522,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { amdgcn(name, full_name) } "arm" => { - #[allow(non_snake_case)] fn arm(name: &str, full_name: &str) -> &'static str { match name { // arm @@ -633,7 +630,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { arm(name, full_name) } "bpf" => { - #[allow(non_snake_case)] fn bpf(name: &str, full_name: &str) -> &'static str { match name { // bpf @@ -655,7 +651,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { bpf(name, full_name) } "cuda" => { - #[allow(non_snake_case)] fn cuda(name: &str, full_name: &str) -> &'static str { match name { // cuda @@ -666,7 +661,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { cuda(name, full_name) } "hexagon" => { - #[allow(non_snake_case)] fn hexagon(name: &str, full_name: &str) -> &'static str { match name { // hexagon @@ -2653,7 +2647,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { hexagon(name, full_name) } "loongarch" => { - #[allow(non_snake_case)] fn loongarch(name: &str, full_name: &str) -> &'static str { match name { // loongarch @@ -4162,7 +4155,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { loongarch(name, full_name) } "mips" => { - #[allow(non_snake_case)] fn mips(name: &str, full_name: &str) -> &'static str { match name { // mips @@ -4843,7 +4835,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { mips(name, full_name) } "nvvm" => { - #[allow(non_snake_case)] fn nvvm(name: &str, full_name: &str) -> &'static str { match name { // nvvm @@ -5652,7 +5643,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { nvvm(name, full_name) } "ppc" => { - #[allow(non_snake_case)] fn ppc(name: &str, full_name: &str) -> &'static str { match name { // ppc @@ -6245,7 +6235,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { ppc(name, full_name) } "ptx" => { - #[allow(non_snake_case)] fn ptx(name: &str, full_name: &str) -> &'static str { match name { // ptx @@ -6273,7 +6262,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { ptx(name, full_name) } "r600" => { - #[allow(non_snake_case)] fn r600(name: &str, full_name: &str) -> &'static str { match name { // r600 @@ -6298,7 +6286,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { r600(name, full_name) } "riscv" => { - #[allow(non_snake_case)] fn riscv(name: &str, full_name: &str) -> &'static str { match name { // riscv @@ -6332,7 +6319,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { riscv(name, full_name) } "s390" => { - #[allow(non_snake_case)] fn s390(name: &str, full_name: &str) -> &'static str { match name { // s390 @@ -6526,7 +6512,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { s390(name, full_name) } "spv" => { - #[allow(non_snake_case)] fn spv(name: &str, full_name: &str) -> &'static str { match name { // spv @@ -6543,7 +6528,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { spv(name, full_name) } "ve" => { - #[allow(non_snake_case)] fn ve(name: &str, full_name: &str) -> &'static str { match name { // ve @@ -7816,7 +7800,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { ve(name, full_name) } "x86" => { - #[allow(non_snake_case)] fn x86(name: &str, full_name: &str) -> &'static str { match name { // x86 @@ -10384,7 +10367,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { x86(name, full_name) } "xcore" => { - #[allow(non_snake_case)] fn xcore(name: &str, full_name: &str) -> &'static str { match name { // xcore diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 39dba28b24c9..e3d189c95ced 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -85,7 +85,7 @@ fn wide_aes_output_type<'a, 'gcc, 'tcx>( (aes_output_type.as_type(), field1, field2) } -#[cfg_attr(not(feature = "master"), allow(unused_variables))] +#[cfg_attr(not(feature = "master"), expect(unused_variables))] pub fn adjust_function<'gcc>( context: &'gcc Context<'gcc>, func_name: &str, @@ -1573,14 +1573,25 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.x86.tileloadd64" => "__builtin_trap", "llvm.x86.tilerelease" => "__builtin_trap", "llvm.x86.tilestored64" => "__builtin_trap", + "llvm.x86.tileloaddrs64" => "__builtin_trap", "llvm.x86.tileloaddt164" => "__builtin_trap", + "llvm.x86.tileloaddrst164" => "__builtin_trap", "llvm.x86.tilezero" => "__builtin_trap", + "llvm.x86.tilemovrow" => "__builtin_trap", + "llvm.x86.tdpbhf8ps" => "__builtin_trap", + "llvm.x86.tdphbf8ps" => "__builtin_trap", + "llvm.x86.tdpbf8ps" => "__builtin_trap", + "llvm.x86.tdphf8ps" => "__builtin_trap", "llvm.x86.tdpbf16ps" => "__builtin_trap", "llvm.x86.tdpbssd" => "__builtin_trap", "llvm.x86.tdpbsud" => "__builtin_trap", "llvm.x86.tdpbusd" => "__builtin_trap", "llvm.x86.tdpbuud" => "__builtin_trap", "llvm.x86.tdpfp16ps" => "__builtin_trap", + "llvm.x86.tmmultf32ps" => "__builtin_trap", + "llvm.x86.tcvtrowps2phh" => "__builtin_trap", + "llvm.x86.tcvtrowps2phl" => "__builtin_trap", + "llvm.x86.tcvtrowd2ps" => "__builtin_trap", "llvm.x86.tcmmimfp16ps" => "__builtin_trap", "llvm.x86.tcmmrlfp16ps" => "__builtin_trap", diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 41363d6313d6..c7ed887b30d0 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -53,6 +53,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( }; } + // TODO(antoyo): refactor with the above require_simd macro that was changed in cg_llvm. + #[cfg(feature = "master")] + macro_rules! require_simd2 { + ($ty: expr, $variant:ident) => {{ + require!($ty.is_simd(), InvalidMonomorphization::$variant { span, name, ty: $ty }); + $ty.simd_size_and_type(bx.tcx()) + }}; + } + if name == sym::simd_select_bitmask { require_simd!( args[1].layout.ty, @@ -464,9 +473,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( m_len == v_len, InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len } ); - // TODO: also support unsigned integers. match *m_elem_ty.kind() { - ty::Int(_) => {} + ty::Int(_) | ty::Uint(_) => {} _ => return_error!(InvalidMonomorphization::MaskWrongElementType { span, name, @@ -1454,6 +1462,184 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( bitwise_red!(simd_reduce_all: BinaryOp::BitwiseAnd, true); bitwise_red!(simd_reduce_any: BinaryOp::BitwiseOr, true); + #[cfg(feature = "master")] + if name == sym::simd_masked_load { + // simd_masked_load<_, _, _, const ALIGN: SimdAlign>(mask: , pointer: *_ T, values: ) -> + // * N: number of elements in the input vectors + // * T: type of the element to load + // * M: any integer width is supported, will be truncated to i1 + // Loads contiguous elements from memory behind `pointer`, but only for + // those lanes whose `mask` bit is enabled. + // The memory addresses corresponding to the “off” lanes are not accessed. + + // TODO: handle the alignment. + + // The element type of the "mask" argument must be a signed integer type of any width + let mask_ty = in_ty; + let mask_len = in_len; + + // The second argument must be a pointer matching the element type + let pointer_ty = args[1].layout.ty; + + // The last argument is a passthrough vector providing values for disabled lanes + let values_ty = args[2].layout.ty; + let (values_len, values_elem) = require_simd2!(values_ty, SimdThird); + + require_simd2!(ret_ty, SimdReturn); + + // Of the same length: + require!( + values_len == mask_len, + InvalidMonomorphization::ThirdArgumentLength { + span, + name, + in_len: mask_len, + in_ty: mask_ty, + arg_ty: values_ty, + out_len: values_len + } + ); + + // The return type must match the last argument type + require!( + ret_ty == values_ty, + InvalidMonomorphization::ExpectedReturnType { span, name, in_ty: values_ty, ret_ty } + ); + + require!( + matches!( + *pointer_ty.kind(), + ty::RawPtr(p_ty, _) if p_ty == values_elem && p_ty.kind() == values_elem.kind() + ), + InvalidMonomorphization::ExpectedElementType { + span, + name, + expected_element: values_elem, + second_arg: pointer_ty, + in_elem: values_elem, + in_ty: values_ty, + mutability: ExpectedPointerMutability::Not, + } + ); + + let mask = args[0].immediate(); + + let pointer = args[1].immediate(); + let default = args[2].immediate(); + let default_type = default.get_type(); + let vector_type = default_type.unqualified().dyncast_vector().expect("vector type"); + let value_type = vector_type.get_element_type(); + let new_pointer_type = value_type.make_pointer(); + + let pointer = bx.context.new_cast(None, pointer, new_pointer_type); + + let mask_vector_type = mask.get_type().unqualified().dyncast_vector().expect("vector type"); + let elem_type = mask_vector_type.get_element_type(); + let zero = bx.context.new_rvalue_zero(elem_type); + let mut elements = vec![]; + for i in 0..mask_len { + let i = bx.context.new_rvalue_from_int(bx.int_type, i as i32); + let mask = bx.context.new_vector_access(None, mask, i).to_rvalue(); + let mask = bx.context.new_comparison(None, ComparisonOp::NotEquals, mask, zero); + let then_val = bx.context.new_array_access(None, pointer, i).to_rvalue(); + let else_val = bx.context.new_vector_access(None, default, i).to_rvalue(); + let element = bx.select(mask, then_val, else_val); + elements.push(element); + } + let result = bx.context.new_rvalue_from_vector(None, default_type, &elements); + return Ok(result); + } + + #[cfg(feature = "master")] + if name == sym::simd_masked_store { + // simd_masked_store<_, _, _, const ALIGN: SimdAlign>(mask: , pointer: *mut T, values: ) -> () + // * N: number of elements in the input vectors + // * T: type of the element to load + // * M: any integer width is supported, will be truncated to i1 + // Stores contiguous elements to memory behind `pointer`, but only for + // those lanes whose `mask` bit is enabled. + // The memory addresses corresponding to the “off” lanes are not accessed. + + // TODO: handle the alignment. + + // The element type of the "mask" argument must be a signed integer type of any width + let mask_ty = in_ty; + let mask_len = in_len; + + // The second argument must be a pointer matching the element type + let pointer_ty = args[1].layout.ty; + + // The last argument specifies the values to store to memory + let values_ty = args[2].layout.ty; + let (values_len, values_elem) = require_simd2!(values_ty, SimdThird); + + // Of the same length: + require!( + values_len == mask_len, + InvalidMonomorphization::ThirdArgumentLength { + span, + name, + in_len: mask_len, + in_ty: mask_ty, + arg_ty: values_ty, + out_len: values_len + } + ); + + // The second argument must be a mutable pointer type matching the element type + require!( + matches!( + *pointer_ty.kind(), + ty::RawPtr(p_ty, p_mutbl) + if p_ty == values_elem && p_ty.kind() == values_elem.kind() && p_mutbl.is_mut() + ), + InvalidMonomorphization::ExpectedElementType { + span, + name, + expected_element: values_elem, + second_arg: pointer_ty, + in_elem: values_elem, + in_ty: values_ty, + mutability: ExpectedPointerMutability::Mut, + } + ); + + let mask = args[0].immediate(); + let pointer = args[1].immediate(); + let values = args[2].immediate(); + let values_type = values.get_type(); + let vector_type = values_type.unqualified().dyncast_vector().expect("vector type"); + let value_type = vector_type.get_element_type(); + let new_pointer_type = value_type.make_pointer(); + + let pointer = bx.context.new_cast(None, pointer, new_pointer_type); + + let vector_type = mask.get_type().unqualified().dyncast_vector().expect("vector type"); + let elem_type = vector_type.get_element_type(); + let zero = bx.context.new_rvalue_zero(elem_type); + for i in 0..mask_len { + let i = bx.context.new_rvalue_from_int(bx.int_type, i as i32); + let mask = bx.context.new_vector_access(None, mask, i).to_rvalue(); + let mask = bx.context.new_comparison(None, ComparisonOp::NotEquals, mask, zero); + + let after_block = bx.current_func().new_block("after"); + let then_block = bx.current_func().new_block("then"); + bx.llbb().end_with_conditional(None, mask, then_block, after_block); + + bx.switch_to_block(then_block); + let lvalue = bx.context.new_array_access(None, pointer, i); + let value = bx.context.new_vector_access(None, values, i).to_rvalue(); + bx.llbb().add_assignment(None, lvalue, value); + bx.llbb().end_with_jump(None, after_block); + + bx.switch_to_block(after_block); + } + + let dummy_value = bx.context.new_rvalue_zero(bx.int_type); + + return Ok(dummy_value); + } + unimplemented!("simd {}", name); } diff --git a/src/lib.rs b/src/lib.rs index 409b7886740a..662e303f94f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![deny(clippy::pattern_type_mismatch)] -#![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)] +#![expect(clippy::uninlined_format_args)] // The rustc crates we need extern crate rustc_abi; @@ -43,7 +43,7 @@ extern crate rustc_target; extern crate rustc_type_ir; // This prevents duplicating functions and statics that are already part of the host rustc process. -#[allow(unused_extern_crates)] +#[expect(unused_extern_crates)] extern crate rustc_driver; mod abi; @@ -69,9 +69,10 @@ mod type_; mod type_of; use std::any::Any; +use std::ffi::CString; use std::fmt::Debug; use std::ops::Deref; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; @@ -142,7 +143,7 @@ impl TargetInfo { #[derive(Clone)] pub struct LockedTargetInfo { - info: Arc>>, + info: Arc>>>, } impl Debug for LockedTargetInfo { @@ -153,11 +154,21 @@ impl Debug for LockedTargetInfo { impl LockedTargetInfo { fn cpu_supports(&self, feature: &str) -> bool { - self.info.lock().expect("lock").cpu_supports(feature) + self.info + .lock() + .expect("lock") + .as_ref() + .expect("target info not initialized") + .cpu_supports(feature) } fn supports_target_dependent_type(&self, typ: CType) -> bool { - self.info.lock().expect("lock").supports_target_dependent_type(typ) + self.info + .lock() + .expect("lock") + .as_ref() + .expect("target info not initialized") + .supports_target_dependent_type(typ) } } @@ -169,6 +180,23 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); +fn load_libgccjit_if_needed(sysroot_path: &Path) { + if gccjit::is_loaded() { + // Do not load a libgccjit second time. + return; + } + + let sysroot_lib_dir = sysroot_path.join("lib"); + let libgccjit_target_lib_file = sysroot_lib_dir.join("libgccjit.so"); + let path = libgccjit_target_lib_file.to_str().expect("libgccjit path"); + + let string = CString::new(path).expect("string to libgccjit path"); + + if let Err(error) = gccjit::load(&string) { + panic!("Cannot load libgccjit.so: {}", error); + } +} + impl CodegenBackend for GccCodegenBackend { fn locale_resource(&self) -> &'static str { crate::DEFAULT_LOCALE_RESOURCE @@ -178,10 +206,12 @@ impl CodegenBackend for GccCodegenBackend { "gcc" } - fn init(&self, _sess: &Session) { + fn init(&self, sess: &Session) { + load_libgccjit_if_needed(sess.opts.sysroot.path()); + #[cfg(feature = "master")] { - let target_cpu = target_cpu(_sess); + let target_cpu = target_cpu(sess); // Get the second TargetInfo with the correct CPU features by setting the arch. let context = Context::default(); @@ -189,7 +219,8 @@ impl CodegenBackend for GccCodegenBackend { context.add_command_line_option(format!("-march={}", target_cpu)); } - **self.target_info.info.lock().expect("lock") = context.get_target_info(); + *self.target_info.info.lock().expect("lock") = + IntoDynSyncSend(Some(context.get_target_info())); } #[cfg(feature = "master")] @@ -217,6 +248,9 @@ impl CodegenBackend for GccCodegenBackend { .info .lock() .expect("lock") + .0 + .as_ref() + .expect("target info not initialized") .supports_128bit_integers .store(check_context.get_last_error() == Ok(None), Ordering::SeqCst); } @@ -438,13 +472,12 @@ pub fn __rustc_codegen_backend() -> Box { let info = { // Check whether the target supports 128-bit integers, and sized floating point types (like // Float16). - let context = Context::default(); - Arc::new(Mutex::new(IntoDynSyncSend(context.get_target_info()))) + Arc::new(Mutex::new(IntoDynSyncSend(None))) }; #[cfg(not(feature = "master"))] - let info = Arc::new(Mutex::new(IntoDynSyncSend(TargetInfo { + let info = Arc::new(Mutex::new(IntoDynSyncSend(Some(TargetInfo { supports_128bit_integers: AtomicBool::new(false), - }))); + })))); Box::new(GccCodegenBackend { lto_supported: Arc::new(AtomicBool::new(false)), diff --git a/src/mono_item.rs b/src/mono_item.rs index 35d44d21bcbf..31c03eddaca5 100644 --- a/src/mono_item.rs +++ b/src/mono_item.rs @@ -15,7 +15,7 @@ use crate::type_of::LayoutGccExt; use crate::{attributes, base}; impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - #[cfg_attr(not(feature = "master"), allow(unused_variables))] + #[cfg_attr(not(feature = "master"), expect(unused_variables))] fn predefine_static( &mut self, def_id: DefId, @@ -41,7 +41,6 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.instances.borrow_mut().insert(instance, global); } - #[cfg_attr(not(feature = "master"), allow(unused_variables))] fn predefine_fn( &mut self, instance: Instance<'tcx>, diff --git a/src/type_.rs b/src/type_.rs index 15a0206607e1..d356b6af260a 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -299,7 +299,7 @@ impl<'gcc, 'tcx> BaseTypeCodegenMethods for CodegenCx<'gcc, 'tcx> { value.get_type() } - #[cfg_attr(feature = "master", allow(unused_mut))] + #[cfg_attr(feature = "master", expect(unused_mut))] fn type_array(&self, ty: Type<'gcc>, mut len: u64) -> Type<'gcc> { #[cfg(not(feature = "master"))] if let Some(struct_type) = ty.is_struct() diff --git a/tests/failing-lto-tests.txt b/tests/failing-lto-tests.txt new file mode 100644 index 000000000000..c45fc0776588 --- /dev/null +++ b/tests/failing-lto-tests.txt @@ -0,0 +1,7 @@ +tests/ui/lto/all-crates.rs +tests/ui/lto/debuginfo-lto-alloc.rs +tests/ui/panic-runtime/lto-unwind.rs +tests/ui/uninhabited/uninhabited-transparent-return-abi.rs +tests/ui/coroutine/panic-drops-resume.rs +tests/ui/coroutine/panic-drops.rs +tests/ui/coroutine/panic-safe.rs diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index cc00432ceb54..2380bd0fc137 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -8,7 +8,6 @@ tests/ui/iterators/iter-sum-overflow-overflow-checks.rs tests/ui/mir/mir_drop_order.rs tests/ui/mir/mir_let_chains_drop_order.rs tests/ui/mir/mir_match_guard_let_chains_drop_order.rs -tests/ui/panics/oom-panic-unwind.rs tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs tests/ui/panic-runtime/abort.rs tests/ui/panic-runtime/link-to-abort.rs @@ -77,3 +76,15 @@ tests/ui/explicit-tail-calls/recursion-etc.rs tests/ui/explicit-tail-calls/indexer.rs tests/ui/explicit-tail-calls/drop-order.rs tests/ui/c-variadic/valid.rs +tests/ui/c-variadic/inherent-method.rs +tests/ui/c-variadic/trait-method.rs +tests/ui/explicit-tail-calls/become-cast-return.rs +tests/ui/explicit-tail-calls/become-indirect-return.rs +tests/ui/panics/panic-abort-backtrace-without-debuginfo.rs +tests/ui/sanitizer/kcfi-c-variadic.rs +tests/ui/sanitizer/kcfi/fn-trait-objects.rs +tests/ui/statics/const_generics.rs +tests/ui/test-attrs/test-panic-while-printing.rs +tests/ui/thir-print/offset_of.rs +tests/ui/iterators/rangefrom-overflow-debug.rs +tests/ui/iterators/rangefrom-overflow-overflow-checks.rs diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index 9abe97b10876..311f256b7600 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -2,11 +2,10 @@ #![allow(clippy::uninlined_format_args)] -use std::env::{self, current_dir}; +use std::env::current_dir; use std::path::{Path, PathBuf}; use std::process::Command; -use boml::Toml; use lang_tester::LangTester; use tempfile::TempDir; @@ -23,29 +22,6 @@ pub fn main_inner(profile: Profile) { let current_dir = current_dir().expect("current dir"); let current_dir = current_dir.to_str().expect("current dir").to_string(); - let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); - - let gcc_path = std::fs::read_to_string(manifest_dir.join("config.toml")) - .ok() - .and_then(|v| { - let toml = Toml::parse(&v).expect("Failed to parse `config.toml`"); - toml.get_string("gcc-path").map(PathBuf::from).ok() - }) - .unwrap_or_else(|| { - // then we try to retrieve it from the `target` folder. - let commit = include_str!("../libgccjit.version").trim(); - Path::new("build/libgccjit").join(commit) - }); - - let gcc_path = Path::new(&gcc_path) - .canonicalize() - .expect("failed to get absolute path of `gcc-path`") - .display() - .to_string(); - unsafe { - env::set_var("LD_LIBRARY_PATH", gcc_path); - } - fn rust_filter(path: &Path) -> bool { path.is_file() && path.extension().expect("extension").to_str().expect("to_str") == "rs" } diff --git a/tools/generate_intrinsics.py b/tools/generate_intrinsics.py index 88927f39b93e..767082c23cce 100644 --- a/tools/generate_intrinsics.py +++ b/tools/generate_intrinsics.py @@ -183,7 +183,8 @@ def update_intrinsics(llvm_path, llvmint, llvmint2): for arch in archs: if len(intrinsics[arch]) == 0: continue - out.write("\"{}\" => {{ #[allow(non_snake_case)] fn {}(name: &str,full_name:&str) -> &'static str {{ match name {{".format(arch,arch)) + attribute = "#[expect(non_snake_case)]" if arch[0].isupper() else "" + out.write("\"{}\" => {{ {} fn {}(name: &str,full_name:&str) -> &'static str {{ match name {{".format(arch, attribute, arch)) intrinsics[arch].sort(key=lambda x: (x[0], x[2])) out.write(' // {}\n'.format(arch)) for entry in intrinsics[arch]: From a7ea98bf2c8d4688aae2d238d856c14282fbbab6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Nov 2025 11:42:42 +0100 Subject: [PATCH 0129/3801] Update GCC commit --- libgccjit.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgccjit.version b/libgccjit.version index bab62f642365..b8d4166542bc 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -0081ca6631abdfa02bf42bc85aaf507b8a0e6beb +28b84db392ac0a572f1a2a2a1317aa5f2bc742cb From 8059907cef079081bd51d2adddc8769dddd16728 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Nov 2025 20:11:18 +0100 Subject: [PATCH 0130/3801] Update GCC submodule --- libgccjit.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgccjit.version b/libgccjit.version index b8d4166542bc..bab62f642365 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -28b84db392ac0a572f1a2a2a1317aa5f2bc742cb +0081ca6631abdfa02bf42bc85aaf507b8a0e6beb From 72076c6b54478159b848552237b1e09e2c39bbce Mon Sep 17 00:00:00 2001 From: Skgland Date: Wed, 26 Nov 2025 21:38:51 +0100 Subject: [PATCH 0131/3801] move and rename proc_macro::tracked_{env::var,path::path} --- compiler/rustc_fluent_macro/src/fluent.rs | 3 +++ compiler/rustc_fluent_macro/src/lib.rs | 3 ++- compiler/rustc_macros/src/current_version.rs | 4 ++++ compiler/rustc_macros/src/symbols.rs | 8 ++++++- library/proc_macro/src/lib.rs | 22 ++++++++++---------- tests/ui/proc-macro/auxiliary/env.rs | 6 +++--- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index e383d085bb3d..46d11d0469a4 100644 --- a/compiler/rustc_fluent_macro/src/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -8,6 +8,9 @@ use fluent_syntax::ast::{ Attribute, Entry, Expression, Identifier, InlineExpression, Message, Pattern, PatternElement, }; use fluent_syntax::parser::ParserError; +#[cfg(not(bootstrap))] +use proc_macro::tracked::path; +#[cfg(bootstrap)] use proc_macro::tracked_path::path; use proc_macro::{Diagnostic, Level, Span}; use proc_macro2::TokenStream; diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index c2f49de31c23..e9ddeb3b971e 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -1,7 +1,8 @@ // tidy-alphabetical-start #![allow(rustc::default_hash_types)] +#![cfg_attr(bootstrap, feature(track_path))] +#![cfg_attr(not(bootstrap), feature(proc_macro_tracked_path))] #![feature(proc_macro_diagnostic)] -#![feature(track_path)] // tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_macros/src/current_version.rs b/compiler/rustc_macros/src/current_version.rs index 42ca60a6d8ab..6912d68421cb 100644 --- a/compiler/rustc_macros/src/current_version.rs +++ b/compiler/rustc_macros/src/current_version.rs @@ -22,7 +22,11 @@ struct RustcVersion { impl RustcVersion { fn parse_cfg_release(env_var: &str) -> Result> { + #[cfg(not(bootstrap))] + let value = proc_macro::tracked::env_var(env_var)?; + #[cfg(bootstrap)] let value = proc_macro::tracked_env::var(env_var)?; + Self::parse_str(&value) .ok_or_else(|| format!("failed to parse rustc version: {:?}", value).into()) } diff --git a/compiler/rustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs index 78a4d47ca334..7437dddf58c5 100644 --- a/compiler/rustc_macros/src/symbols.rs +++ b/compiler/rustc_macros/src/symbols.rs @@ -259,7 +259,13 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec) { break; } - let value = match proc_macro::tracked_env::var(env_var.value()) { + #[cfg(bootstrap)] + let tracked_env = proc_macro::tracked_env::var(env_var.value()); + + #[cfg(not(bootstrap))] + let tracked_env = proc_macro::tracked::env_var(env_var.value()); + + let value = match tracked_env { Ok(value) => value, Err(err) => { errors.list.push(syn::Error::new_spanned(expr, err)); diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 4efdfcad924b..ee224ceb6045 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -1594,9 +1594,14 @@ impl fmt::Debug for Literal { } } -/// Tracked access to environment variables. -#[unstable(feature = "proc_macro_tracked_env", issue = "99515")] -pub mod tracked_env { +#[unstable( + feature = "proc_macro_tracked_path", + issue = "99515", + implied_by = "proc_macro_tracked_env" +)] +/// Functionality for adding environment state to the build dependency info. +pub mod tracked { + use std::env::{self, VarError}; use std::ffi::OsStr; @@ -1606,23 +1611,18 @@ pub mod tracked_env { /// Besides the dependency tracking this function should be equivalent to `env::var` from the /// standard library, except that the argument must be UTF-8. #[unstable(feature = "proc_macro_tracked_env", issue = "99515")] - pub fn var + AsRef>(key: K) -> Result { + pub fn env_var + AsRef>(key: K) -> Result { let key: &str = key.as_ref(); let value = crate::bridge::client::FreeFunctions::injected_env_var(key) .map_or_else(|| env::var(key), Ok); crate::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok()); value } -} -/// Tracked access to additional files. -#[unstable(feature = "track_path", issue = "99515")] -pub mod tracked_path { - - /// Track a file explicitly. + /// Track a file or directory explicitly. /// /// Commonly used for tracking asset preprocessing. - #[unstable(feature = "track_path", issue = "99515")] + #[unstable(feature = "proc_macro_tracked_path", issue = "99515")] pub fn path>(path: P) { let path: &str = path.as_ref(); crate::bridge::client::FreeFunctions::track_path(path); diff --git a/tests/ui/proc-macro/auxiliary/env.rs b/tests/ui/proc-macro/auxiliary/env.rs index d01e3b42d4ce..f0f0328e131e 100644 --- a/tests/ui/proc-macro/auxiliary/env.rs +++ b/tests/ui/proc-macro/auxiliary/env.rs @@ -3,11 +3,11 @@ extern crate proc_macro; use proc_macro::TokenStream; -use proc_macro::tracked_env::var; +use proc_macro::tracked::env_var; #[proc_macro] pub fn generate_const(input: TokenStream) -> TokenStream { - let the_const = match var("THE_CONST") { + let the_const = match env_var("THE_CONST") { Ok(x) if x == "12" => { "const THE_CONST: u32 = 12;" } @@ -15,7 +15,7 @@ pub fn generate_const(input: TokenStream) -> TokenStream { "const THE_CONST: u32 = 0;" } }; - let another = if var("ANOTHER").is_ok() { + let another = if env_var("ANOTHER").is_ok() { "const ANOTHER: u32 = 1;" } else { "const ANOTHER: u32 = 2;" From 8d8d7021c6006481728775ac4db170af05cf161d Mon Sep 17 00:00:00 2001 From: Skgland Date: Wed, 26 Nov 2025 21:43:44 +0100 Subject: [PATCH 0132/3801] change proc_macro::tracked::path to take an AsRef instead of an AsRef --- library/proc_macro/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index ee224ceb6045..cb9e53780b04 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -1604,6 +1604,7 @@ pub mod tracked { use std::env::{self, VarError}; use std::ffi::OsStr; + use std::path::Path; /// Retrieve an environment variable and add it to build dependency info. /// The build system executing the compiler will know that the variable was accessed during @@ -1623,8 +1624,8 @@ pub mod tracked { /// /// Commonly used for tracking asset preprocessing. #[unstable(feature = "proc_macro_tracked_path", issue = "99515")] - pub fn path>(path: P) { - let path: &str = path.as_ref(); + pub fn path>(path: P) { + let path: &str = path.as_ref().to_str().unwrap(); crate::bridge::client::FreeFunctions::track_path(path); } } From f83c72f00c7cefecb2bb5d07cfb0de67a0697c7f Mon Sep 17 00:00:00 2001 From: yanglsh Date: Thu, 21 Aug 2025 10:56:14 +0800 Subject: [PATCH 0133/3801] fix: `branches-sharing-code` suggests wrongly on `const` and `static` --- clippy_lints/src/ifs/branches_sharing_code.rs | 75 +++++-- clippy_utils/src/hir_utils.rs | 209 +++++++++++++++++- .../branches_sharing_code/shared_at_bottom.rs | 62 ++++++ .../shared_at_bottom.stderr | 70 +++++- 4 files changed, 388 insertions(+), 28 deletions(-) diff --git a/clippy_lints/src/ifs/branches_sharing_code.rs b/clippy_lints/src/ifs/branches_sharing_code.rs index b3f597cc8736..b6e8d047c5cd 100644 --- a/clippy_lints/src/ifs/branches_sharing_code.rs +++ b/clippy_lints/src/ifs/branches_sharing_code.rs @@ -9,7 +9,7 @@ use clippy_utils::{ use core::iter; use core::ops::ControlFlow; use rustc_errors::Applicability; -use rustc_hir::{Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Node, Stmt, StmtKind, intravisit}; +use rustc_hir::{Block, Expr, ExprKind, HirId, HirIdSet, ItemKind, LetStmt, Node, Stmt, StmtKind, UseKind, intravisit}; use rustc_lint::LateContext; use rustc_span::hygiene::walk_chain; use rustc_span::source_map::SourceMap; @@ -108,6 +108,7 @@ struct BlockEq { /// The name and id of every local which can be moved at the beginning and the end. moved_locals: Vec<(HirId, Symbol)>, } + impl BlockEq { fn start_span(&self, b: &Block<'_>, sm: &SourceMap) -> Option { match &b.stmts[..self.start_end_eq] { @@ -129,20 +130,33 @@ impl BlockEq { } /// If the statement is a local, checks if the bound names match the expected list of names. -fn eq_binding_names(s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool { - if let StmtKind::Let(l) = s.kind { - let mut i = 0usize; - let mut res = true; - l.pat.each_binding_or_first(&mut |_, _, _, name| { - if names.get(i).is_some_and(|&(_, n)| n == name.name) { - i += 1; - } else { - res = false; - } - }); - res && i == names.len() - } else { - false +fn eq_binding_names(cx: &LateContext<'_>, s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool { + match s.kind { + StmtKind::Let(l) => { + let mut i = 0usize; + let mut res = true; + l.pat.each_binding_or_first(&mut |_, _, _, name| { + if names.get(i).is_some_and(|&(_, n)| n == name.name) { + i += 1; + } else { + res = false; + } + }); + res && i == names.len() + }, + StmtKind::Item(item_id) + if let [(_, name)] = names + && let item = cx.tcx.hir_item(item_id) + && let ItemKind::Static(_, ident, ..) + | ItemKind::Const(ident, ..) + | ItemKind::Fn { ident, .. } + | ItemKind::TyAlias(ident, ..) + | ItemKind::Use(_, UseKind::Single(ident)) + | ItemKind::Mod(ident, _) = item.kind => + { + *name == ident.name + }, + _ => false, } } @@ -164,6 +178,7 @@ fn modifies_any_local<'tcx>(cx: &LateContext<'tcx>, s: &'tcx Stmt<'_>, locals: & /// Checks if the given statement should be considered equal to the statement in the same /// position for each block. fn eq_stmts( + cx: &LateContext<'_>, stmt: &Stmt<'_>, blocks: &[&Block<'_>], get_stmt: impl for<'a> Fn(&'a Block<'a>) -> Option<&'a Stmt<'a>>, @@ -178,7 +193,7 @@ fn eq_stmts( let new_bindings = &moved_bindings[old_count..]; blocks .iter() - .all(|b| get_stmt(b).is_some_and(|s| eq_binding_names(s, new_bindings))) + .all(|b| get_stmt(b).is_some_and(|s| eq_binding_names(cx, s, new_bindings))) } else { true }) && blocks.iter().all(|b| get_stmt(b).is_some_and(|s| eq.eq_stmt(s, stmt))) @@ -218,7 +233,7 @@ fn scan_block_for_eq<'tcx>( return true; } modifies_any_local(cx, stmt, &cond_locals) - || !eq_stmts(stmt, blocks, |b| b.stmts.get(i), &mut eq, &mut moved_locals) + || !eq_stmts(cx, stmt, blocks, |b| b.stmts.get(i), &mut eq, &mut moved_locals) }) .map_or(block.stmts.len(), |(i, stmt)| { adjust_by_closest_callsite(i, stmt, block.stmts[..i].iter().enumerate().rev()) @@ -279,6 +294,7 @@ fn scan_block_for_eq<'tcx>( })) .fold(end_search_start, |init, (stmt, offset)| { if eq_stmts( + cx, stmt, blocks, |b| b.stmts.get(b.stmts.len() - offset), @@ -290,11 +306,26 @@ fn scan_block_for_eq<'tcx>( // Clear out all locals seen at the end so far. None of them can be moved. let stmts = &blocks[0].stmts; for stmt in &stmts[stmts.len() - init..=stmts.len() - offset] { - if let StmtKind::Let(l) = stmt.kind { - l.pat.each_binding_or_first(&mut |_, id, _, _| { - // FIXME(rust/#120456) - is `swap_remove` correct? - eq.locals.swap_remove(&id); - }); + match stmt.kind { + StmtKind::Let(l) => { + l.pat.each_binding_or_first(&mut |_, id, _, _| { + // FIXME(rust/#120456) - is `swap_remove` correct? + eq.locals.swap_remove(&id); + }); + }, + StmtKind::Item(item_id) => { + let item = cx.tcx.hir_item(item_id); + if let ItemKind::Static(..) + | ItemKind::Const(..) + | ItemKind::Fn { .. } + | ItemKind::TyAlias(..) + | ItemKind::Use(..) + | ItemKind::Mod(..) = item.kind + { + eq.local_items.swap_remove(&item.owner_id.to_def_id()); + } + }, + _ => {}, } } moved_locals.truncate(moved_locals_at_start); diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index b286701fbed1..5b55ad2a3f5b 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -4,14 +4,17 @@ use crate::source::{SpanRange, SpanRangeExt, walk_span_to_context}; use crate::tokenize_with_text; use rustc_ast::ast; use rustc_ast::ast::InlineAsmTemplatePiece; -use rustc_data_structures::fx::FxHasher; +use rustc_data_structures::fx::{FxHasher, FxIndexMap}; use rustc_hir::MatchSource::TryDesugar; use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id::DefId; use rustc_hir::{ - AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, ByRef, Closure, ConstArg, ConstArgKind, Expr, - ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, - LifetimeKind, Node, Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, - StructTailExpr, TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind, + AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, ByRef, Closure, ConstArg, ConstArgKind, ConstItemRhs, + Expr, ExprField, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericArgs, GenericBound, GenericBounds, + GenericParam, GenericParamKind, GenericParamSource, Generics, HirId, HirIdMap, InlineAsmOperand, ItemId, ItemKind, + LetExpr, Lifetime, LifetimeKind, LifetimeParamKind, Node, ParamName, Pat, PatExpr, PatExprKind, PatField, PatKind, + Path, PathSegment, PreciseCapturingArgKind, PrimTy, QPath, Stmt, StmtKind, StructTailExpr, TraitBoundModifiers, Ty, + TyKind, TyPat, TyPatKind, UseKind, WherePredicate, WherePredicateKind, }; use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::LateContext; @@ -106,6 +109,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { left_ctxt: SyntaxContext::root(), right_ctxt: SyntaxContext::root(), locals: HirIdMap::default(), + local_items: FxIndexMap::default(), } } @@ -144,6 +148,7 @@ pub struct HirEqInterExpr<'a, 'b, 'tcx> { // right. For example, when comparing `{ let x = 1; x + 2 }` and `{ let y = 1; y + 2 }`, // these blocks are considered equal since `x` is mapped to `y`. pub locals: HirIdMap, + pub local_items: FxIndexMap, } impl HirEqInterExpr<'_, '_, '_> { @@ -168,6 +173,189 @@ impl HirEqInterExpr<'_, '_, '_> { && self.eq_pat(l.pat, r.pat) }, (StmtKind::Expr(l), StmtKind::Expr(r)) | (StmtKind::Semi(l), StmtKind::Semi(r)) => self.eq_expr(l, r), + (StmtKind::Item(l), StmtKind::Item(r)) => self.eq_item(*l, *r), + _ => false, + } + } + + pub fn eq_item(&mut self, l: ItemId, r: ItemId) -> bool { + let left = self.inner.cx.tcx.hir_item(l); + let right = self.inner.cx.tcx.hir_item(r); + let eq = match (left.kind, right.kind) { + ( + ItemKind::Const(l_ident, l_generics, l_ty, ConstItemRhs::Body(l_body)), + ItemKind::Const(r_ident, r_generics, r_ty, ConstItemRhs::Body(r_body)), + ) => { + l_ident.name == r_ident.name + && self.eq_generics(l_generics, r_generics) + && self.eq_ty(l_ty, r_ty) + && self.eq_body(l_body, r_body) + }, + (ItemKind::Static(l_mut, l_ident, l_ty, l_body), ItemKind::Static(r_mut, r_ident, r_ty, r_body)) => { + l_mut == r_mut && l_ident.name == r_ident.name && self.eq_ty(l_ty, r_ty) && self.eq_body(l_body, r_body) + }, + ( + ItemKind::Fn { + sig: l_sig, + ident: l_ident, + generics: l_generics, + body: l_body, + has_body: l_has_body, + }, + ItemKind::Fn { + sig: r_sig, + ident: r_ident, + generics: r_generics, + body: r_body, + has_body: r_has_body, + }, + ) => { + l_ident.name == r_ident.name + && (l_has_body == r_has_body) + && self.eq_fn_sig(&l_sig, &r_sig) + && self.eq_generics(l_generics, r_generics) + && self.eq_body(l_body, r_body) + }, + (ItemKind::TyAlias(l_ident, l_generics, l_ty), ItemKind::TyAlias(r_ident, r_generics, r_ty)) => { + l_ident.name == r_ident.name && self.eq_generics(l_generics, r_generics) && self.eq_ty(l_ty, r_ty) + }, + (ItemKind::Use(l_path, l_kind), ItemKind::Use(r_path, r_kind)) => { + self.eq_path_segments(l_path.segments, r_path.segments) + && match (l_kind, r_kind) { + (UseKind::Single(l_ident), UseKind::Single(r_ident)) => l_ident.name == r_ident.name, + (UseKind::Glob, UseKind::Glob) | (UseKind::ListStem, UseKind::ListStem) => true, + _ => false, + } + }, + (ItemKind::Mod(l_ident, l_mod), ItemKind::Mod(r_ident, r_mod)) => { + l_ident.name == r_ident.name && over(l_mod.item_ids, r_mod.item_ids, |l, r| self.eq_item(*l, *r)) + }, + _ => false, + }; + if eq { + self.local_items.insert(l.owner_id.to_def_id(), r.owner_id.to_def_id()); + } + eq + } + + fn eq_fn_sig(&mut self, left: &FnSig<'_>, right: &FnSig<'_>) -> bool { + left.header.safety == right.header.safety + && left.header.constness == right.header.constness + && left.header.asyncness == right.header.asyncness + && left.header.abi == right.header.abi + && self.eq_fn_decl(left.decl, right.decl) + } + + fn eq_fn_decl(&mut self, left: &FnDecl<'_>, right: &FnDecl<'_>) -> bool { + over(left.inputs, right.inputs, |l, r| self.eq_ty(l, r)) + && (match (left.output, right.output) { + (FnRetTy::DefaultReturn(_), FnRetTy::DefaultReturn(_)) => true, + (FnRetTy::Return(l_ty), FnRetTy::Return(r_ty)) => self.eq_ty(l_ty, r_ty), + _ => false, + }) + && left.c_variadic == right.c_variadic + && left.implicit_self == right.implicit_self + && left.lifetime_elision_allowed == right.lifetime_elision_allowed + } + + fn eq_generics(&mut self, left: &Generics<'_>, right: &Generics<'_>) -> bool { + self.eq_generics_param(left.params, right.params) + && self.eq_generics_predicate(left.predicates, right.predicates) + } + + fn eq_generics_predicate(&mut self, left: &[WherePredicate<'_>], right: &[WherePredicate<'_>]) -> bool { + over(left, right, |l, r| match (l.kind, r.kind) { + (WherePredicateKind::BoundPredicate(l_bound), WherePredicateKind::BoundPredicate(r_bound)) => { + l_bound.origin == r_bound.origin + && self.eq_ty(l_bound.bounded_ty, r_bound.bounded_ty) + && self.eq_generics_param(l_bound.bound_generic_params, r_bound.bound_generic_params) + && self.eq_generics_bound(l_bound.bounds, r_bound.bounds) + }, + (WherePredicateKind::RegionPredicate(l_region), WherePredicateKind::RegionPredicate(r_region)) => { + Self::eq_lifetime(l_region.lifetime, r_region.lifetime) + && self.eq_generics_bound(l_region.bounds, r_region.bounds) + }, + (WherePredicateKind::EqPredicate(l_eq), WherePredicateKind::EqPredicate(r_eq)) => { + self.eq_ty(l_eq.lhs_ty, r_eq.lhs_ty) + }, + _ => false, + }) + } + + fn eq_generics_bound(&mut self, left: GenericBounds<'_>, right: GenericBounds<'_>) -> bool { + over(left, right, |l, r| match (l, r) { + (GenericBound::Trait(l_trait), GenericBound::Trait(r_trait)) => { + l_trait.modifiers == r_trait.modifiers + && self.eq_path(l_trait.trait_ref.path, r_trait.trait_ref.path) + && self.eq_generics_param(l_trait.bound_generic_params, r_trait.bound_generic_params) + }, + (GenericBound::Outlives(l_lifetime), GenericBound::Outlives(r_lifetime)) => { + Self::eq_lifetime(l_lifetime, r_lifetime) + }, + (GenericBound::Use(l_capture, _), GenericBound::Use(r_capture, _)) => { + over(l_capture, r_capture, |l, r| match (l, r) { + (PreciseCapturingArgKind::Lifetime(l_lifetime), PreciseCapturingArgKind::Lifetime(r_lifetime)) => { + Self::eq_lifetime(l_lifetime, r_lifetime) + }, + (PreciseCapturingArgKind::Param(l_param), PreciseCapturingArgKind::Param(r_param)) => { + l_param.ident == r_param.ident && l_param.res == r_param.res + }, + _ => false, + }) + }, + _ => false, + }) + } + + fn eq_generics_param(&mut self, left: &[GenericParam<'_>], right: &[GenericParam<'_>]) -> bool { + over(left, right, |l, r| { + (match (l.name, r.name) { + (ParamName::Plain(l_ident), ParamName::Plain(r_ident)) + | (ParamName::Error(l_ident), ParamName::Error(r_ident)) => l_ident.name == r_ident.name, + (ParamName::Fresh, ParamName::Fresh) => true, + _ => false, + }) && l.pure_wrt_drop == r.pure_wrt_drop + && self.eq_generics_param_kind(&l.kind, &r.kind) + && (matches!( + (l.source, r.source), + (GenericParamSource::Generics, GenericParamSource::Generics) + | (GenericParamSource::Binder, GenericParamSource::Binder) + )) + }) + } + + fn eq_generics_param_kind(&mut self, left: &GenericParamKind<'_>, right: &GenericParamKind<'_>) -> bool { + match (left, right) { + (GenericParamKind::Lifetime { kind: l_kind }, GenericParamKind::Lifetime { kind: r_kind }) => { + match (l_kind, r_kind) { + (LifetimeParamKind::Explicit, LifetimeParamKind::Explicit) + | (LifetimeParamKind::Error, LifetimeParamKind::Error) => true, + (LifetimeParamKind::Elided(l_lifetime_kind), LifetimeParamKind::Elided(r_lifetime_kind)) => { + l_lifetime_kind == r_lifetime_kind + }, + _ => false, + } + }, + ( + GenericParamKind::Type { + default: l_default, + synthetic: l_synthetic, + }, + GenericParamKind::Type { + default: r_default, + synthetic: r_synthetic, + }, + ) => both(*l_default, *r_default, |l, r| self.eq_ty(l, r)) && l_synthetic == r_synthetic, + ( + GenericParamKind::Const { + ty: l_ty, + default: l_default, + }, + GenericParamKind::Const { + ty: r_ty, + default: r_default, + }, + ) => self.eq_ty(l_ty, r_ty) && both(*l_default, *r_default, |l, r| self.eq_const_arg(l, r)), _ => false, } } @@ -563,6 +751,17 @@ impl HirEqInterExpr<'_, '_, '_> { match (left.res, right.res) { (Res::Local(l), Res::Local(r)) => l == r || self.locals.get(&l) == Some(&r), (Res::Local(_), _) | (_, Res::Local(_)) => false, + (Res::Def(l_kind, l), Res::Def(r_kind, r)) + if l_kind == r_kind + && let DefKind::Const + | DefKind::Static { .. } + | DefKind::Fn + | DefKind::TyAlias + | DefKind::Use + | DefKind::Mod = l_kind => + { + (l == r || self.local_items.get(&l) == Some(&r)) && self.eq_path_segments(left.segments, right.segments) + }, _ => self.eq_path_segments(left.segments, right.segments), } } diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.rs b/tests/ui/branches_sharing_code/shared_at_bottom.rs index fa322dc28a78..a7f950b44caf 100644 --- a/tests/ui/branches_sharing_code/shared_at_bottom.rs +++ b/tests/ui/branches_sharing_code/shared_at_bottom.rs @@ -300,3 +300,65 @@ fn issue15004() { //~^ branches_sharing_code }; } + +pub fn issue15347() -> isize { + if false { + static A: isize = 4; + return A; + } else { + static A: isize = 5; + return A; + } + + if false { + //~^ branches_sharing_code + type ISize = isize; + return ISize::MAX; + } else { + type ISize = isize; + return ISize::MAX; + } + + if false { + //~^ branches_sharing_code + fn foo() -> isize { + 4 + } + return foo(); + } else { + fn foo() -> isize { + 4 + } + return foo(); + } + + if false { + //~^ branches_sharing_code + use std::num::NonZeroIsize; + return NonZeroIsize::new(4).unwrap().get(); + } else { + use std::num::NonZeroIsize; + return NonZeroIsize::new(4).unwrap().get(); + } + + if false { + //~^ branches_sharing_code + const B: isize = 5; + return B; + } else { + const B: isize = 5; + return B; + } + + // Should not lint! + const A: isize = 1; + if false { + const B: isize = A; + return B; + } else { + const C: isize = A; + return C; + } + + todo!() +} diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/tests/ui/branches_sharing_code/shared_at_bottom.stderr index 1c470fb0da5e..4ff3990232a5 100644 --- a/tests/ui/branches_sharing_code/shared_at_bottom.stderr +++ b/tests/ui/branches_sharing_code/shared_at_bottom.stderr @@ -202,5 +202,73 @@ LL ~ } LL ~ 1; | -error: aborting due to 12 previous errors +error: all if blocks contain the same code at the start + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:313:5 + | +LL | / if false { +LL | | +LL | | type ISize = isize; +LL | | return ISize::MAX; + | |__________________________^ + | +help: consider moving these statements before the if + | +LL ~ type ISize = isize; +LL + return ISize::MAX; +LL + if false { + | + +error: all if blocks contain the same code at the start + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:322:5 + | +LL | / if false { +LL | | +LL | | fn foo() -> isize { +LL | | 4 +LL | | } +LL | | return foo(); + | |_____________________^ + | +help: consider moving these statements before the if + | +LL ~ fn foo() -> isize { +LL + 4 +LL + } +LL + return foo(); +LL + if false { + | + +error: all if blocks contain the same code at the start + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:335:5 + | +LL | / if false { +LL | | +LL | | use std::num::NonZeroIsize; +LL | | return NonZeroIsize::new(4).unwrap().get(); + | |___________________________________________________^ + | +help: consider moving these statements before the if + | +LL ~ use std::num::NonZeroIsize; +LL + return NonZeroIsize::new(4).unwrap().get(); +LL + if false { + | + +error: all if blocks contain the same code at the start + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:344:5 + | +LL | / if false { +LL | | +LL | | const B: isize = 5; +LL | | return B; + | |_________________^ + | +help: consider moving these statements before the if + | +LL ~ const B: isize = 5; +LL + return B; +LL + if false { + | + +error: aborting due to 16 previous errors From 2aa9360c359fb9fcf2e9ecf3acb66d5c936ace01 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Thu, 27 Nov 2025 06:41:59 +0100 Subject: [PATCH 0134/3801] Give an overview of our stability guarantees --- src/doc/rustc-dev-guide/src/SUMMARY.md | 1 + .../src/stability-guarantees.md | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/doc/rustc-dev-guide/src/stability-guarantees.md diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 249140956c09..37ab3ff56979 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -52,6 +52,7 @@ - [Mastering @rustbot](./rustbot.md) - [Walkthrough: a typical contribution](./walkthrough.md) - [Implementing new language features](./implementing_new_features.md) +- [Stability guarantees](./stability-guarantees.md) - [Stability attributes](./stability.md) - [Stabilizing language features](./stabilization_guide.md) - [Stabilization report template](./stabilization_report_template.md) diff --git a/src/doc/rustc-dev-guide/src/stability-guarantees.md b/src/doc/rustc-dev-guide/src/stability-guarantees.md new file mode 100644 index 000000000000..21c4f3594d84 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/stability-guarantees.md @@ -0,0 +1,26 @@ +# Stability guarantees + +This page gives an overview of our stability guarantees. + +## RFCs + +* [RFC 1105 api evolution](https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md) +* [RFC 1122 language semver](https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md) + +## Blog posts + +* [Stability as a Deliverable](https://blog.rust-lang.org/2014/10/30/Stability/) + +## rustc-dev-guide links + +* [Stabilizing library features](./stability.md) +* [Stabilizing language features](./stabilization_guide.md) +* [What qualifies as a bug fix?](./bug-fix-procedure.md#what-qualifies-as-a-bug-fix) + +## Exemptions + +Even if some of our infrastructure can be used by others, it is still considered +internal and comes without stability guarantees. This is a non-exhaustive list +of components without stability guarantees: + +* The CLIs and environment variables used by `remote-test-client` / `remote-test-server` From 430ec291a0ba420c187a5ca22ac05811551efedd Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 27 Nov 2025 06:58:36 +0000 Subject: [PATCH 0135/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 1be6b13be73dc12e98e51b403add4c41a0b77759. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 08324790e311..bddb68a06b02 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -d3e1ccdf40ae7b7a6dc81edc073d80dad7b66f75 +1be6b13be73dc12e98e51b403add4c41a0b77759 From 1c2a0aaa313a42af4233108a9a007eae07691cb4 Mon Sep 17 00:00:00 2001 From: reucru01 Date: Thu, 6 Nov 2025 10:01:41 +0000 Subject: [PATCH 0136/3801] Fixes differences found between clang & rust The intrinsics test was flagging differences in aarch64_be between rust in debug and clang in O2. It was found that rust was correct in debug, but incorrect in release, and in both cases were being compared against clang in O2 which was also incorrect. The vdot intrinsics were fixed and are now correct in rust for both release and debug. However the vcmla ones could not be as the issue lies with LLVM. Both the vdot and vcmla intrinsics were added to the skiplist as clang is still incorrect for both. LLVM issue: https://github.com/llvm/llvm-project/issues/166190 --- library/stdarch/ci/intrinsic-test.sh | 2 +- .../core_arch/src/aarch64/neon/generated.rs | 24 ++-- .../src/arm_shared/neon/generated.rs | 32 +++--- .../intrinsic-test/missing_aarch64_be.txt | 105 ++++++++++++++++++ .../spec/neon/aarch64.spec.yml | 30 ++--- .../spec/neon/arm_shared.spec.yml | 36 +++--- 6 files changed, 171 insertions(+), 58 deletions(-) create mode 100644 library/stdarch/crates/intrinsic-test/missing_aarch64_be.txt diff --git a/library/stdarch/ci/intrinsic-test.sh b/library/stdarch/ci/intrinsic-test.sh index be63f0c0c617..a8f96897bc23 100755 --- a/library/stdarch/ci/intrinsic-test.sh +++ b/library/stdarch/ci/intrinsic-test.sh @@ -56,7 +56,7 @@ case ${TARGET} in aarch64_be-unknown-linux-gnu*) TEST_CPPFLAGS="-fuse-ld=lld" - TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_aarch64.txt + TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_aarch64_be.txt TEST_CXX_COMPILER="clang++" TEST_RUNNER="${CARGO_TARGET_AARCH64_BE_UNKNOWN_LINUX_GNU_RUNNER}" : "${TEST_SAMPLE_INTRINSICS_PERCENTAGE:=100}" diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index 09cf3818040d..ce864cc7d907 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -9500,10 +9500,10 @@ pub fn vdivh_f16(a: f16, b: f16) -> f16 { #[unstable(feature = "stdarch_neon_dotprod", issue = "117224")] pub fn vdot_laneq_s32(a: int32x2_t, b: int8x8_t, c: int8x16_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 2); + let c: int32x4_t = vreinterpretq_s32_s8(c); unsafe { - let c: int32x4_t = transmute(c); let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vdot_s32(a, b, transmute(c)) + vdot_s32(a, b, vreinterpret_s8_s32(c)) } } #[doc = "Dot product arithmetic (indexed)"] @@ -9515,11 +9515,11 @@ pub fn vdot_laneq_s32(a: int32x2_t, b: int8x8_t, c: int8x16_t) #[unstable(feature = "stdarch_neon_dotprod", issue = "117224")] pub fn vdotq_laneq_s32(a: int32x4_t, b: int8x16_t, c: int8x16_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); + let c: int32x4_t = vreinterpretq_s32_s8(c); unsafe { - let c: int32x4_t = transmute(c); let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vdotq_s32(a, b, transmute(c)) + vdotq_s32(a, b, vreinterpretq_s8_s32(c)) } } #[doc = "Dot product arithmetic (indexed)"] @@ -9531,10 +9531,10 @@ pub fn vdotq_laneq_s32(a: int32x4_t, b: int8x16_t, c: int8x16_t #[unstable(feature = "stdarch_neon_dotprod", issue = "117224")] pub fn vdot_laneq_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x16_t) -> uint32x2_t { static_assert_uimm_bits!(LANE, 2); + let c: uint32x4_t = vreinterpretq_u32_u8(c); unsafe { - let c: uint32x4_t = transmute(c); let c: uint32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vdot_u32(a, b, transmute(c)) + vdot_u32(a, b, vreinterpret_u8_u32(c)) } } #[doc = "Dot product arithmetic (indexed)"] @@ -9546,11 +9546,11 @@ pub fn vdot_laneq_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x16_ #[unstable(feature = "stdarch_neon_dotprod", issue = "117224")] pub fn vdotq_laneq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x16_t) -> uint32x4_t { static_assert_uimm_bits!(LANE, 2); + let c: uint32x4_t = vreinterpretq_u32_u8(c); unsafe { - let c: uint32x4_t = transmute(c); let c: uint32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vdotq_u32(a, b, transmute(c)) + vdotq_u32(a, b, vreinterpretq_u8_u32(c)) } } #[doc = "Set all vector lanes to the same value"] @@ -28283,10 +28283,10 @@ pub fn vuqadds_s32(a: i32, b: u32) -> i32 { #[unstable(feature = "stdarch_neon_i8mm", issue = "117223")] pub fn vusdot_laneq_s32(a: int32x2_t, b: uint8x8_t, c: int8x16_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 2); + let c: int32x4_t = vreinterpretq_s32_s8(c); unsafe { - let c: int32x4_t = transmute(c); let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vusdot_s32(a, b, transmute(c)) + vusdot_s32(a, b, vreinterpret_s8_s32(c)) } } #[doc = "Dot product index form with unsigned and signed integers"] @@ -28298,11 +28298,11 @@ pub fn vusdot_laneq_s32(a: int32x2_t, b: uint8x8_t, c: int8x16_ #[unstable(feature = "stdarch_neon_i8mm", issue = "117223")] pub fn vusdotq_laneq_s32(a: int32x4_t, b: uint8x16_t, c: int8x16_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); + let c: int32x4_t = vreinterpretq_s32_s8(c); unsafe { - let c: int32x4_t = transmute(c); let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vusdotq_s32(a, b, transmute(c)) + vusdotq_s32(a, b, vreinterpretq_s8_s32(c)) } } #[doc = "Unzip vectors"] diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index c1bd70175c4c..7229f33f6142 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -9201,10 +9201,10 @@ pub fn vcvtq_u32_f32(a: float32x4_t) -> uint32x4_t { )] pub fn vdot_lane_s32(a: int32x2_t, b: int8x8_t, c: int8x8_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); + let c: int32x2_t = vreinterpret_s32_s8(c); unsafe { - let c: int32x2_t = transmute(c); let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vdot_s32(a, b, transmute(c)) + vdot_s32(a, b, vreinterpret_s8_s32(c)) } } #[doc = "Dot product arithmetic (indexed)"] @@ -9228,11 +9228,11 @@ pub fn vdot_lane_s32(a: int32x2_t, b: int8x8_t, c: int8x8_t) -> )] pub fn vdotq_lane_s32(a: int32x4_t, b: int8x16_t, c: int8x8_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); + let c: int32x2_t = vreinterpret_s32_s8(c); unsafe { - let c: int32x2_t = transmute(c); let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vdotq_s32(a, b, transmute(c)) + vdotq_s32(a, b, vreinterpretq_s8_s32(c)) } } #[doc = "Dot product arithmetic (indexed)"] @@ -9256,10 +9256,10 @@ pub fn vdotq_lane_s32(a: int32x4_t, b: int8x16_t, c: int8x8_t) )] pub fn vdot_lane_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x8_t) -> uint32x2_t { static_assert_uimm_bits!(LANE, 1); + let c: uint32x2_t = vreinterpret_u32_u8(c); unsafe { - let c: uint32x2_t = transmute(c); let c: uint32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vdot_u32(a, b, transmute(c)) + vdot_u32(a, b, vreinterpret_u8_u32(c)) } } #[doc = "Dot product arithmetic (indexed)"] @@ -9283,11 +9283,11 @@ pub fn vdot_lane_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x8_t) )] pub fn vdotq_lane_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x8_t) -> uint32x4_t { static_assert_uimm_bits!(LANE, 1); + let c: uint32x2_t = vreinterpret_u32_u8(c); unsafe { - let c: uint32x2_t = transmute(c); let c: uint32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vdotq_u32(a, b, transmute(c)) + vdotq_u32(a, b, vreinterpretq_u8_u32(c)) } } #[doc = "Dot product arithmetic (vector)"] @@ -71710,10 +71710,10 @@ pub fn vsubw_u32(a: uint64x2_t, b: uint32x2_t) -> uint64x2_t { )] pub fn vsudot_lane_s32(a: int32x2_t, b: int8x8_t, c: uint8x8_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); + let c: uint32x2_t = vreinterpret_u32_u8(c); unsafe { - let c: uint32x2_t = transmute(c); let c: uint32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vusdot_s32(a, transmute(c), b) + vusdot_s32(a, vreinterpret_u8_u32(c), b) } } #[doc = "Dot product index form with signed and unsigned integers"] @@ -71737,11 +71737,11 @@ pub fn vsudot_lane_s32(a: int32x2_t, b: int8x8_t, c: uint8x8_t) )] pub fn vsudotq_lane_s32(a: int32x4_t, b: int8x16_t, c: uint8x8_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); + let c: uint32x2_t = vreinterpret_u32_u8(c); unsafe { - let c: uint32x2_t = transmute(c); let c: uint32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vusdotq_s32(a, transmute(c), b) + vusdotq_s32(a, vreinterpretq_u8_u32(c), b) } } #[doc = "Table look-up"] @@ -73630,10 +73630,10 @@ pub fn vtstq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { )] pub fn vusdot_lane_s32(a: int32x2_t, b: uint8x8_t, c: int8x8_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); + let c: int32x2_t = vreinterpret_s32_s8(c); unsafe { - let c: int32x2_t = transmute(c); let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vusdot_s32(a, b, transmute(c)) + vusdot_s32(a, b, vreinterpret_s8_s32(c)) } } #[doc = "Dot product index form with unsigned and signed integers"] @@ -73657,11 +73657,11 @@ pub fn vusdot_lane_s32(a: int32x2_t, b: uint8x8_t, c: int8x8_t) )] pub fn vusdotq_lane_s32(a: int32x4_t, b: uint8x16_t, c: int8x8_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); + let c: int32x2_t = vreinterpret_s32_s8(c); unsafe { - let c: int32x2_t = transmute(c); let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vusdotq_s32(a, b, transmute(c)) + vusdotq_s32(a, b, vreinterpretq_s8_s32(c)) } } #[doc = "Dot product vector form with unsigned and signed integers"] diff --git a/library/stdarch/crates/intrinsic-test/missing_aarch64_be.txt b/library/stdarch/crates/intrinsic-test/missing_aarch64_be.txt new file mode 100644 index 000000000000..28e1d9203ee5 --- /dev/null +++ b/library/stdarch/crates/intrinsic-test/missing_aarch64_be.txt @@ -0,0 +1,105 @@ +# Bad LLVM codegen for BE in O2 in clang, and release in rust (https://github.com/llvm/llvm-project/issues/166190) +vcmla_lane_f16 +vcmla_laneq_f16 +vcmla_rot180_lane_f16 +vcmla_rot180_laneq_f16 +vcmla_rot270_lane_f16 +vcmla_rot270_laneq_f16 +vcmla_rot90_lane_f16 +vcmla_rot90_laneq_f16 +vcmlaq_lane_f16 +vcmlaq_laneq_f16 +vcmlaq_laneq_f32 +vcmlaq_rot180_lane_f16 +vcmlaq_rot180_laneq_f16 +vcmlaq_rot180_laneq_f32 +vcmlaq_rot270_lane_f16 +vcmlaq_rot270_laneq_f16 +vcmlaq_rot270_laneq_f32 +vcmlaq_rot90_lane_f16 +vcmlaq_rot90_laneq_f16 +vcmlaq_rot90_laneq_f32 +# Bad codegen for BE in O2 in clang, correct in rust. Same cause as above issue. +vdot_lane_s32 +vdot_lane_u32 +vdot_laneq_s32 +vdot_laneq_u32 +vdotq_lane_s32 +vdotq_lane_u32 +vdotq_laneq_s32 +vdotq_laneq_u32 +vsudot_lane_s32 +vsudot_laneq_s32 +vsudotq_lane_s32 +vsudotq_laneq_s32 +vusdot_lane_s32 +vusdot_laneq_s32 +vusdotq_lane_s32 +vusdotq_laneq_s32 + +# Below are in common to missing_aarch64.txt + +# Not implemented in stdarch yet +vbfdot_f32 +vbfdot_lane_f32 +vbfdot_laneq_f32 +vbfdotq_f32 +vbfdotq_lane_f32 +vbfdotq_laneq_f32 +vbfmlalbq_f32 +vbfmlalbq_lane_f32 +vbfmlalbq_laneq_f32 +vbfmlaltq_f32 +vbfmlaltq_lane_f32 +vbfmlaltq_laneq_f32 +vbfmmlaq_f32 + + +# Implemented in stdarch, but missing in Clang. +vrnd32xq_f64 +vrnd32zq_f64 +vrnd64xq_f64 +vrnd64zq_f64 +vamin_f32 +vaminq_f32 +vaminq_f64 +vamax_f32 +vamaxq_f32 +vamaxq_f64 +# LLVM select error, and missing in Clang. +vrnd32x_f64 +vrnd32z_f64 +vrnd64x_f64 +vrnd64z_f64 +vluti2_lane_p16 +vluti2_lane_p8 +vluti2_lane_s16 +vluti2_lane_s8 +vluti2_lane_u16 +vluti2_lane_u8 +vluti2q_lane_p16 +vluti2q_lane_p8 +vluti2q_lane_s16 +vluti2q_lane_s8 +vluti2q_lane_u16 +vluti2q_lane_u8 +vluti4q_lane_f16_x2 +vluti4q_lane_p16_x2 +vluti4q_lane_p8 +vluti4q_lane_s16_x2 +vluti4q_lane_s8 +vluti4q_lane_u16_x2 +vluti4q_lane_u8 +vluti4q_laneq_f16_x2 +vluti4q_laneq_p16_x2 +vluti4q_laneq_p8 +vluti4q_laneq_s16_x2 +vluti4q_laneq_s8 +vluti4q_laneq_u16_x2 +vluti4q_laneq_u8 + +# Broken in Clang +vcvth_s16_f16 +# FIXME: Broken output due to missing f16 printing support in Rust +vmulh_lane_f16 +vmulh_laneq_f16 diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index fe64f9d7869e..48c12779a8c1 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -5091,13 +5091,13 @@ intrinsics: static_defs: ["const LANE: i32"] safety: safe types: - - [int32x2_t, uint8x8_t, int8x16_t, '[LANE as u32, LANE as u32]'] - - [int32x4_t, uint8x16_t, int8x16_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [int32x2_t, uint8x8_t, int8x16_t, '[LANE as u32, LANE as u32]',''] + - [int32x4_t, uint8x16_t, int8x16_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '2']] - - Let: [c, int32x4_t, {FnCall: [transmute, [c]]}] + - Let: [c, int32x4_t, {FnCall: ['vreinterpretq_s32_s8', [c]]}] - Let: [c, "{neon_type[0]}", {FnCall: [simd_shuffle!, [c, c, "{type[3]}"]]}] - - FnCall: ["vusdot{neon_type[0].no}", [a, b, {FnCall: [transmute, [c]]}]] + - FnCall: ["vusdot{neon_type[0].no}", [a, b, {FnCall: ['vreinterpret{type[4]}_s8_s32', [c]]}]] - name: "vsudot{neon_type[0].laneq_nox}" doc: "Dot product index form with signed and unsigned integers" @@ -5123,7 +5123,11 @@ intrinsics: - c - "{type[4]}" - FnCall: [simd_shuffle!, [c, c, "{type[3]}"]] - - FnCall: ["vusdot{neon_type[0].no}", [a, {FnCall: [transmute, [c]]}, b]] + - FnCall: + - "vusdot{neon_type[0].no}" + - - a + - FnCall: [transmute, [c]] + - b - name: "vmul{neon_type.no}" doc: Multiply @@ -6580,14 +6584,14 @@ intrinsics: - FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']] safety: safe types: - - [int32x2_t, int8x8_t, int8x16_t, int32x4_t, '[LANE as u32, LANE as u32]'] - - [int32x4_t, int8x16_t, int8x16_t, int32x4_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [int32x2_t, int8x8_t, int8x16_t, int32x4_t, '[LANE as u32, LANE as u32]', ''] + - [int32x4_t, int8x16_t, int8x16_t, int32x4_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '2']] - Let: - c - "{neon_type[3]}" - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpretq_{neon_type[0]}_{neon_type[1]}', [c]] - Let: - c - "{neon_type[0]}" @@ -6596,7 +6600,7 @@ intrinsics: - "vdot{neon_type[0].no}" - - a - b - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]] - name: "vdot{neon_type[0].laneq_nox}" doc: Dot product arithmetic (indexed) @@ -6610,14 +6614,14 @@ intrinsics: - FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']] safety: safe types: - - [uint32x2_t, uint8x8_t, uint8x16_t, uint32x4_t, '[LANE as u32, LANE as u32]'] - - [uint32x4_t, uint8x16_t, uint8x16_t, uint32x4_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [uint32x2_t, uint8x8_t, uint8x16_t, uint32x4_t, '[LANE as u32, LANE as u32]',''] + - [uint32x4_t, uint8x16_t, uint8x16_t, uint32x4_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '2']] - Let: - c - "{neon_type[3]}" - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpretq_{neon_type[0]}_{neon_type[1]}', [c]] - Let: - c - "{neon_type[0]}" @@ -6626,7 +6630,7 @@ intrinsics: - "vdot{neon_type[0].no}" - - a - b - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]] - name: "vmax{neon_type.no}" doc: Maximum (vector) diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 4816d17bd654..bb44aab66b40 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -6261,19 +6261,19 @@ intrinsics: static_defs: ["const LANE: i32"] safety: safe types: - - ['_lane_s32', int32x2_t, uint8x8_t, '[LANE as u32, LANE as u32]'] - - ['q_lane_s32', int32x4_t, uint8x16_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - ['_lane_s32', int32x2_t, uint8x8_t, '[LANE as u32, LANE as u32]',''] + - ['q_lane_s32', int32x4_t, uint8x16_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '1']] - Let: - c - int32x2_t - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpret_s32_s8', [c]] - Let: - c - "{type[1]}" - FnCall: [simd_shuffle!, [c, c, "{type[3]}"]] - - FnCall: ["vusdot{neon_type[1].no}", [a, b, {FnCall: [transmute, [c]]}]] + - FnCall: ["vusdot{neon_type[1].no}", [a, b, {FnCall: ['vreinterpret{type[4]}_s8_s32', [c]]}]] - name: "vsudot{neon_type[0].lane_nox}" doc: "Dot product index form with signed and unsigned integers" @@ -6290,19 +6290,23 @@ intrinsics: static_defs: ["const LANE: i32"] safety: safe types: - - [int32x2_t, int8x8_t, uint8x8_t, '[LANE as u32, LANE as u32]', uint32x2_t] - - [int32x4_t, int8x16_t, uint8x8_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]', uint32x4_t] + - [int32x2_t, int8x8_t, uint8x8_t, '[LANE as u32, LANE as u32]', uint32x2_t,''] + - [int32x4_t, int8x16_t, uint8x8_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]', uint32x4_t,'q'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '1']] - Let: - c - uint32x2_t - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpret_u32_u8', [c]] - Let: - c - "{type[4]}" - FnCall: [simd_shuffle!, [c, c, "{type[3]}"]] - - FnCall: ["vusdot{neon_type[0].no}", [a, {FnCall: [transmute, [c]]}, b]] + - FnCall: + - "vusdot{neon_type[0].no}" + - - a + - FnCall: ['vreinterpret{type[5]}_u8_u32', [c]] + - b - name: "vmul{neon_type[1].no}" doc: Multiply @@ -7113,14 +7117,14 @@ intrinsics: - *neon-cfg-arm-unstable safety: safe types: - - [int32x2_t, int8x8_t, int8x8_t, int32x2_t, '[LANE as u32, LANE as u32]'] - - [int32x4_t, int8x16_t, int8x8_t, int32x2_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [int32x2_t, int8x8_t, int8x8_t, int32x2_t, '[LANE as u32, LANE as u32]',''] + - [int32x4_t, int8x16_t, int8x8_t, int32x2_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '1']] - Let: - c - "{neon_type[3]}" - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpret_{neon_type[0]}_{neon_type[1]}', [c]] - Let: - c - "{neon_type[0]}" @@ -7129,7 +7133,7 @@ intrinsics: - "vdot{neon_type[0].no}" - - a - b - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]] - name: "vdot{neon_type[0].lane_nox}" doc: Dot product arithmetic (indexed) @@ -7146,14 +7150,14 @@ intrinsics: - *neon-cfg-arm-unstable safety: safe types: - - [uint32x2_t, uint8x8_t, uint8x8_t, uint32x2_t, '[LANE as u32, LANE as u32]'] - - [uint32x4_t, uint8x16_t, uint8x8_t, uint32x2_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [uint32x2_t, uint8x8_t, uint8x8_t, uint32x2_t, '[LANE as u32, LANE as u32]',''] + - [uint32x4_t, uint8x16_t, uint8x8_t, uint32x2_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '1']] - Let: - c - "{neon_type[3]}" - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpret_{neon_type[0]}_{neon_type[1]}', [c]] - Let: - c - "{neon_type[0]}" @@ -7162,7 +7166,7 @@ intrinsics: - "vdot{neon_type[0].no}" - - a - b - - FnCall: [transmute, [c]] + - FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]] - name: "vmax{neon_type.no}" doc: Maximum (vector) From 73ad94ab862c2bbb17857c3376d5628fb21dd99b Mon Sep 17 00:00:00 2001 From: reucru01 Date: Mon, 24 Nov 2025 14:34:03 +0000 Subject: [PATCH 0137/3801] Provides work-around for vreinterpret inline fail --- .../src/arm_shared/neon/generated.rs | 304 +++++++++++++++++- .../spec/neon/arm_shared.spec.yml | 20 +- 2 files changed, 300 insertions(+), 24 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index 7229f33f6142..d45454c696c7 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -9183,6 +9183,7 @@ pub fn vcvtq_u32_f32(a: float32x4_t) -> uint32x4_t { #[doc = "Dot product arithmetic (indexed)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_s32)"] #[inline] +#[cfg(target_endian = "little")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[target_feature(enable = "neon,dotprod")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsdot, LANE = 0))] @@ -9201,15 +9202,48 @@ pub fn vcvtq_u32_f32(a: float32x4_t) -> uint32x4_t { )] pub fn vdot_lane_s32(a: int32x2_t, b: int8x8_t, c: int8x8_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); - let c: int32x2_t = vreinterpret_s32_s8(c); unsafe { + let c: int32x2_t = transmute(c); let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vdot_s32(a, b, vreinterpret_s8_s32(c)) + vdot_s32(a, b, transmute(c)) + } +} +#[doc = "Dot product arithmetic (indexed)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_s32)"] +#[inline] +#[cfg(target_endian = "big")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +#[target_feature(enable = "neon,dotprod")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsdot, LANE = 0))] +#[cfg_attr( + all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), + assert_instr(sdot, LANE = 0) +)] +#[rustc_legacy_const_generics(3)] +#[cfg_attr( + not(target_arch = "arm"), + unstable(feature = "stdarch_neon_dotprod", issue = "117224") +)] +#[cfg_attr( + target_arch = "arm", + unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") +)] +pub fn vdot_lane_s32(a: int32x2_t, b: int8x8_t, c: int8x8_t) -> int32x2_t { + static_assert_uimm_bits!(LANE, 1); + let a: int32x2_t = unsafe { simd_shuffle!(a, a, [1, 0]) }; + let b: int8x8_t = unsafe { simd_shuffle!(b, b, [7, 6, 5, 4, 3, 2, 1, 0]) }; + let c: int8x8_t = unsafe { simd_shuffle!(c, c, [7, 6, 5, 4, 3, 2, 1, 0]) }; + unsafe { + let c: int32x2_t = transmute(c); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let ret_val: int32x2_t = vdot_s32(a, b, transmute(c)); + simd_shuffle!(ret_val, ret_val, [1, 0]) } } #[doc = "Dot product arithmetic (indexed)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_s32)"] #[inline] +#[cfg(target_endian = "little")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[target_feature(enable = "neon,dotprod")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsdot, LANE = 0))] @@ -9228,16 +9262,51 @@ pub fn vdot_lane_s32(a: int32x2_t, b: int8x8_t, c: int8x8_t) -> )] pub fn vdotq_lane_s32(a: int32x4_t, b: int8x16_t, c: int8x8_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); - let c: int32x2_t = vreinterpret_s32_s8(c); unsafe { + let c: int32x2_t = transmute(c); let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vdotq_s32(a, b, vreinterpretq_s8_s32(c)) + vdotq_s32(a, b, transmute(c)) + } +} +#[doc = "Dot product arithmetic (indexed)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_s32)"] +#[inline] +#[cfg(target_endian = "big")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +#[target_feature(enable = "neon,dotprod")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsdot, LANE = 0))] +#[cfg_attr( + all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), + assert_instr(sdot, LANE = 0) +)] +#[rustc_legacy_const_generics(3)] +#[cfg_attr( + not(target_arch = "arm"), + unstable(feature = "stdarch_neon_dotprod", issue = "117224") +)] +#[cfg_attr( + target_arch = "arm", + unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") +)] +pub fn vdotq_lane_s32(a: int32x4_t, b: int8x16_t, c: int8x8_t) -> int32x4_t { + static_assert_uimm_bits!(LANE, 1); + let a: int32x4_t = unsafe { simd_shuffle!(a, a, [3, 2, 1, 0]) }; + let b: int8x16_t = + unsafe { simd_shuffle!(b, b, [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) }; + let c: int8x8_t = unsafe { simd_shuffle!(c, c, [7, 6, 5, 4, 3, 2, 1, 0]) }; + unsafe { + let c: int32x2_t = transmute(c); + let c: int32x4_t = + simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let ret_val: int32x4_t = vdotq_s32(a, b, transmute(c)); + simd_shuffle!(ret_val, ret_val, [3, 2, 1, 0]) } } #[doc = "Dot product arithmetic (indexed)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_u32)"] #[inline] +#[cfg(target_endian = "little")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[target_feature(enable = "neon,dotprod")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vudot, LANE = 0))] @@ -9256,15 +9325,48 @@ pub fn vdotq_lane_s32(a: int32x4_t, b: int8x16_t, c: int8x8_t) )] pub fn vdot_lane_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x8_t) -> uint32x2_t { static_assert_uimm_bits!(LANE, 1); - let c: uint32x2_t = vreinterpret_u32_u8(c); unsafe { + let c: uint32x2_t = transmute(c); let c: uint32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vdot_u32(a, b, vreinterpret_u8_u32(c)) + vdot_u32(a, b, transmute(c)) + } +} +#[doc = "Dot product arithmetic (indexed)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_u32)"] +#[inline] +#[cfg(target_endian = "big")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +#[target_feature(enable = "neon,dotprod")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vudot, LANE = 0))] +#[cfg_attr( + all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), + assert_instr(udot, LANE = 0) +)] +#[rustc_legacy_const_generics(3)] +#[cfg_attr( + not(target_arch = "arm"), + unstable(feature = "stdarch_neon_dotprod", issue = "117224") +)] +#[cfg_attr( + target_arch = "arm", + unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") +)] +pub fn vdot_lane_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x8_t) -> uint32x2_t { + static_assert_uimm_bits!(LANE, 1); + let a: uint32x2_t = unsafe { simd_shuffle!(a, a, [1, 0]) }; + let b: uint8x8_t = unsafe { simd_shuffle!(b, b, [7, 6, 5, 4, 3, 2, 1, 0]) }; + let c: uint8x8_t = unsafe { simd_shuffle!(c, c, [7, 6, 5, 4, 3, 2, 1, 0]) }; + unsafe { + let c: uint32x2_t = transmute(c); + let c: uint32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let ret_val: uint32x2_t = vdot_u32(a, b, transmute(c)); + simd_shuffle!(ret_val, ret_val, [1, 0]) } } #[doc = "Dot product arithmetic (indexed)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_u32)"] #[inline] +#[cfg(target_endian = "little")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[target_feature(enable = "neon,dotprod")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vudot, LANE = 0))] @@ -9283,11 +9385,45 @@ pub fn vdot_lane_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x8_t) )] pub fn vdotq_lane_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x8_t) -> uint32x4_t { static_assert_uimm_bits!(LANE, 1); - let c: uint32x2_t = vreinterpret_u32_u8(c); unsafe { + let c: uint32x2_t = transmute(c); let c: uint32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vdotq_u32(a, b, vreinterpretq_u8_u32(c)) + vdotq_u32(a, b, transmute(c)) + } +} +#[doc = "Dot product arithmetic (indexed)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_u32)"] +#[inline] +#[cfg(target_endian = "big")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +#[target_feature(enable = "neon,dotprod")] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vudot, LANE = 0))] +#[cfg_attr( + all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), + assert_instr(udot, LANE = 0) +)] +#[rustc_legacy_const_generics(3)] +#[cfg_attr( + not(target_arch = "arm"), + unstable(feature = "stdarch_neon_dotprod", issue = "117224") +)] +#[cfg_attr( + target_arch = "arm", + unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") +)] +pub fn vdotq_lane_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x8_t) -> uint32x4_t { + static_assert_uimm_bits!(LANE, 1); + let a: uint32x4_t = unsafe { simd_shuffle!(a, a, [3, 2, 1, 0]) }; + let b: uint8x16_t = + unsafe { simd_shuffle!(b, b, [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) }; + let c: uint8x8_t = unsafe { simd_shuffle!(c, c, [7, 6, 5, 4, 3, 2, 1, 0]) }; + unsafe { + let c: uint32x2_t = transmute(c); + let c: uint32x4_t = + simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let ret_val: uint32x4_t = vdotq_u32(a, b, transmute(c)); + simd_shuffle!(ret_val, ret_val, [3, 2, 1, 0]) } } #[doc = "Dot product arithmetic (vector)"] @@ -71692,6 +71828,7 @@ pub fn vsubw_u32(a: uint64x2_t, b: uint32x2_t) -> uint64x2_t { #[doc = "Dot product index form with signed and unsigned integers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudot_lane_s32)"] #[inline] +#[cfg(target_endian = "little")] #[target_feature(enable = "neon,i8mm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsudot, LANE = 0))] @@ -71710,15 +71847,48 @@ pub fn vsubw_u32(a: uint64x2_t, b: uint32x2_t) -> uint64x2_t { )] pub fn vsudot_lane_s32(a: int32x2_t, b: int8x8_t, c: uint8x8_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); - let c: uint32x2_t = vreinterpret_u32_u8(c); unsafe { + let c: uint32x2_t = transmute(c); let c: uint32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vusdot_s32(a, vreinterpret_u8_u32(c), b) + vusdot_s32(a, transmute(c), b) + } +} +#[doc = "Dot product index form with signed and unsigned integers"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudot_lane_s32)"] +#[inline] +#[cfg(target_endian = "big")] +#[target_feature(enable = "neon,i8mm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsudot, LANE = 0))] +#[cfg_attr( + all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), + assert_instr(sudot, LANE = 0) +)] +#[rustc_legacy_const_generics(3)] +#[cfg_attr( + not(target_arch = "arm"), + unstable(feature = "stdarch_neon_i8mm", issue = "117223") +)] +#[cfg_attr( + target_arch = "arm", + unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") +)] +pub fn vsudot_lane_s32(a: int32x2_t, b: int8x8_t, c: uint8x8_t) -> int32x2_t { + static_assert_uimm_bits!(LANE, 1); + let a: int32x2_t = unsafe { simd_shuffle!(a, a, [1, 0]) }; + let b: int8x8_t = unsafe { simd_shuffle!(b, b, [7, 6, 5, 4, 3, 2, 1, 0]) }; + let c: uint8x8_t = unsafe { simd_shuffle!(c, c, [7, 6, 5, 4, 3, 2, 1, 0]) }; + unsafe { + let c: uint32x2_t = transmute(c); + let c: uint32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let ret_val: int32x2_t = vusdot_s32(a, transmute(c), b); + simd_shuffle!(ret_val, ret_val, [1, 0]) } } #[doc = "Dot product index form with signed and unsigned integers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudotq_lane_s32)"] #[inline] +#[cfg(target_endian = "little")] #[target_feature(enable = "neon,i8mm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsudot, LANE = 0))] @@ -71737,11 +71907,45 @@ pub fn vsudot_lane_s32(a: int32x2_t, b: int8x8_t, c: uint8x8_t) )] pub fn vsudotq_lane_s32(a: int32x4_t, b: int8x16_t, c: uint8x8_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); - let c: uint32x2_t = vreinterpret_u32_u8(c); unsafe { + let c: uint32x2_t = transmute(c); let c: uint32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vusdotq_s32(a, vreinterpretq_u8_u32(c), b) + vusdotq_s32(a, transmute(c), b) + } +} +#[doc = "Dot product index form with signed and unsigned integers"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudotq_lane_s32)"] +#[inline] +#[cfg(target_endian = "big")] +#[target_feature(enable = "neon,i8mm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsudot, LANE = 0))] +#[cfg_attr( + all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), + assert_instr(sudot, LANE = 0) +)] +#[rustc_legacy_const_generics(3)] +#[cfg_attr( + not(target_arch = "arm"), + unstable(feature = "stdarch_neon_i8mm", issue = "117223") +)] +#[cfg_attr( + target_arch = "arm", + unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") +)] +pub fn vsudotq_lane_s32(a: int32x4_t, b: int8x16_t, c: uint8x8_t) -> int32x4_t { + static_assert_uimm_bits!(LANE, 1); + let a: int32x4_t = unsafe { simd_shuffle!(a, a, [3, 2, 1, 0]) }; + let b: int8x16_t = + unsafe { simd_shuffle!(b, b, [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) }; + let c: uint8x8_t = unsafe { simd_shuffle!(c, c, [7, 6, 5, 4, 3, 2, 1, 0]) }; + unsafe { + let c: uint32x2_t = transmute(c); + let c: uint32x4_t = + simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let ret_val: int32x4_t = vusdotq_s32(a, transmute(c), b); + simd_shuffle!(ret_val, ret_val, [3, 2, 1, 0]) } } #[doc = "Table look-up"] @@ -73612,6 +73816,7 @@ pub fn vtstq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { #[doc = "Dot product index form with unsigned and signed integers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdot_lane_s32)"] #[inline] +#[cfg(target_endian = "little")] #[target_feature(enable = "neon,i8mm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vusdot, LANE = 0))] @@ -73630,15 +73835,48 @@ pub fn vtstq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { )] pub fn vusdot_lane_s32(a: int32x2_t, b: uint8x8_t, c: int8x8_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); - let c: int32x2_t = vreinterpret_s32_s8(c); unsafe { + let c: int32x2_t = transmute(c); let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); - vusdot_s32(a, b, vreinterpret_s8_s32(c)) + vusdot_s32(a, b, transmute(c)) + } +} +#[doc = "Dot product index form with unsigned and signed integers"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdot_lane_s32)"] +#[inline] +#[cfg(target_endian = "big")] +#[target_feature(enable = "neon,i8mm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vusdot, LANE = 0))] +#[cfg_attr( + all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), + assert_instr(usdot, LANE = 0) +)] +#[rustc_legacy_const_generics(3)] +#[cfg_attr( + not(target_arch = "arm"), + unstable(feature = "stdarch_neon_i8mm", issue = "117223") +)] +#[cfg_attr( + target_arch = "arm", + unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") +)] +pub fn vusdot_lane_s32(a: int32x2_t, b: uint8x8_t, c: int8x8_t) -> int32x2_t { + static_assert_uimm_bits!(LANE, 1); + let a: int32x2_t = unsafe { simd_shuffle!(a, a, [1, 0]) }; + let b: uint8x8_t = unsafe { simd_shuffle!(b, b, [7, 6, 5, 4, 3, 2, 1, 0]) }; + let c: int8x8_t = unsafe { simd_shuffle!(c, c, [7, 6, 5, 4, 3, 2, 1, 0]) }; + unsafe { + let c: int32x2_t = transmute(c); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let ret_val: int32x2_t = vusdot_s32(a, b, transmute(c)); + simd_shuffle!(ret_val, ret_val, [1, 0]) } } #[doc = "Dot product index form with unsigned and signed integers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdotq_lane_s32)"] #[inline] +#[cfg(target_endian = "little")] #[target_feature(enable = "neon,i8mm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vusdot, LANE = 0))] @@ -73657,11 +73895,45 @@ pub fn vusdot_lane_s32(a: int32x2_t, b: uint8x8_t, c: int8x8_t) )] pub fn vusdotq_lane_s32(a: int32x4_t, b: uint8x16_t, c: int8x8_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); - let c: int32x2_t = vreinterpret_s32_s8(c); unsafe { + let c: int32x2_t = transmute(c); let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); - vusdotq_s32(a, b, vreinterpretq_s8_s32(c)) + vusdotq_s32(a, b, transmute(c)) + } +} +#[doc = "Dot product index form with unsigned and signed integers"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdotq_lane_s32)"] +#[inline] +#[cfg(target_endian = "big")] +#[target_feature(enable = "neon,i8mm")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vusdot, LANE = 0))] +#[cfg_attr( + all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), + assert_instr(usdot, LANE = 0) +)] +#[rustc_legacy_const_generics(3)] +#[cfg_attr( + not(target_arch = "arm"), + unstable(feature = "stdarch_neon_i8mm", issue = "117223") +)] +#[cfg_attr( + target_arch = "arm", + unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800") +)] +pub fn vusdotq_lane_s32(a: int32x4_t, b: uint8x16_t, c: int8x8_t) -> int32x4_t { + static_assert_uimm_bits!(LANE, 1); + let a: int32x4_t = unsafe { simd_shuffle!(a, a, [3, 2, 1, 0]) }; + let b: uint8x16_t = + unsafe { simd_shuffle!(b, b, [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) }; + let c: int8x8_t = unsafe { simd_shuffle!(c, c, [7, 6, 5, 4, 3, 2, 1, 0]) }; + unsafe { + let c: int32x2_t = transmute(c); + let c: int32x4_t = + simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let ret_val: int32x4_t = vusdotq_s32(a, b, transmute(c)); + simd_shuffle!(ret_val, ret_val, [3, 2, 1, 0]) } } #[doc = "Dot product vector form with unsigned and signed integers"] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index bb44aab66b40..9ebdc4334c25 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -6259,6 +6259,7 @@ intrinsics: - *neon-unstable-i8mm - *neon-cfg-arm-unstable static_defs: ["const LANE: i32"] + big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure. safety: safe types: - ['_lane_s32', int32x2_t, uint8x8_t, '[LANE as u32, LANE as u32]',''] @@ -6268,12 +6269,12 @@ intrinsics: - Let: - c - int32x2_t - - FnCall: ['vreinterpret_s32_s8', [c]] + - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret_s32_s8', [c]] - Let: - c - "{type[1]}" - FnCall: [simd_shuffle!, [c, c, "{type[3]}"]] - - FnCall: ["vusdot{neon_type[1].no}", [a, b, {FnCall: ['vreinterpret{type[4]}_s8_s32', [c]]}]] + - FnCall: ["vusdot{neon_type[1].no}", [a, b, {FnCall: [transmute, [c]]}]] #'vreinterpret{type[4]}_s8_s32' - name: "vsudot{neon_type[0].lane_nox}" doc: "Dot product index form with signed and unsigned integers" @@ -6288,6 +6289,7 @@ intrinsics: - *neon-unstable-i8mm - *neon-cfg-arm-unstable static_defs: ["const LANE: i32"] + big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure. safety: safe types: - [int32x2_t, int8x8_t, uint8x8_t, '[LANE as u32, LANE as u32]', uint32x2_t,''] @@ -6297,7 +6299,7 @@ intrinsics: - Let: - c - uint32x2_t - - FnCall: ['vreinterpret_u32_u8', [c]] + - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret_u32_u8', [c]] - Let: - c - "{type[4]}" @@ -6305,7 +6307,7 @@ intrinsics: - FnCall: - "vusdot{neon_type[0].no}" - - a - - FnCall: ['vreinterpret{type[5]}_u8_u32', [c]] + - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret{type[5]}_u8_u32', [c]] - b - name: "vmul{neon_type[1].no}" @@ -7115,6 +7117,7 @@ intrinsics: - FnCall: [rustc_legacy_const_generics, ['3']] - FnCall: [cfg_attr, [{FnCall: [not, ['target_arch = "arm"']]}, {FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']]}]] - *neon-cfg-arm-unstable + big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure. safety: safe types: - [int32x2_t, int8x8_t, int8x8_t, int32x2_t, '[LANE as u32, LANE as u32]',''] @@ -7124,7 +7127,7 @@ intrinsics: - Let: - c - "{neon_type[3]}" - - FnCall: ['vreinterpret_{neon_type[0]}_{neon_type[1]}', [c]] + - FnCall: [transmute, [c]] - Let: - c - "{neon_type[0]}" @@ -7133,7 +7136,7 @@ intrinsics: - "vdot{neon_type[0].no}" - - a - b - - FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]] + - FnCall: [transmute, [c]] - name: "vdot{neon_type[0].lane_nox}" doc: Dot product arithmetic (indexed) @@ -7149,6 +7152,7 @@ intrinsics: - FnCall: [cfg_attr, [{FnCall: [not, ['target_arch = "arm"']]}, {FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']]}]] - *neon-cfg-arm-unstable safety: safe + big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure. types: - [uint32x2_t, uint8x8_t, uint8x8_t, uint32x2_t, '[LANE as u32, LANE as u32]',''] - [uint32x4_t, uint8x16_t, uint8x8_t, uint32x2_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q'] @@ -7157,7 +7161,7 @@ intrinsics: - Let: - c - "{neon_type[3]}" - - FnCall: ['vreinterpret_{neon_type[0]}_{neon_type[1]}', [c]] + - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret_{neon_type[0]}_{neon_type[1]}', [c]] - Let: - c - "{neon_type[0]}" @@ -7166,7 +7170,7 @@ intrinsics: - "vdot{neon_type[0].no}" - - a - b - - FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]] + - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]] - name: "vmax{neon_type.no}" doc: Maximum (vector) From 00ec159c71740764de2c4d39744e99cdb8c9572c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 24 Nov 2025 15:07:32 +0000 Subject: [PATCH 0138/3801] Remove PathKind from CrateSource It is never used anywhere anymore now that existing_matches doesn't use it anymore. And there is no good reason for any other code to use it in the future either. --- compiler/rustc_codegen_ssa/src/back/link.rs | 18 +++----- compiler/rustc_interface/src/passes.rs | 6 +-- compiler/rustc_metadata/src/creader.rs | 16 +++---- compiler/rustc_metadata/src/locator.rs | 50 ++++++++++----------- compiler/rustc_session/src/cstore.rs | 12 +++-- compiler/rustc_session/src/search_paths.rs | 1 - 6 files changed, 47 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 820f7ba4a6f2..dd497667a4d9 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -278,7 +278,7 @@ pub fn each_linked_rlib( } let crate_name = info.crate_name[&cnum]; let used_crate_source = &info.used_crate_source[&cnum]; - if let Some((path, _)) = &used_crate_source.rlib { + if let Some(path) = &used_crate_source.rlib { f(cnum, path); } else if used_crate_source.rmeta.is_some() { return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name }); @@ -542,7 +542,7 @@ fn link_staticlib( }; let crate_name = codegen_results.crate_info.crate_name[&cnum]; let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum]; - if let Some((path, _)) = &used_crate_source.dylib { + if let Some(path) = &used_crate_source.dylib { all_rust_dylibs.push(&**path); } else if used_crate_source.rmeta.is_some() { sess.dcx().emit_fatal(errors::LinkRlibError::OnlyRmetaFound { crate_name }); @@ -620,7 +620,6 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out .used_crate_source .items() .filter_map(|(_, csource)| csource.rlib.as_ref()) - .map(|(path, _)| path) .into_sorted_stable_ord(); for input_rlib in input_rlibs { @@ -2178,12 +2177,7 @@ fn add_rpath_args( .crate_info .used_crates .iter() - .filter_map(|cnum| { - codegen_results.crate_info.used_crate_source[cnum] - .dylib - .as_ref() - .map(|(path, _)| &**path) - }) + .filter_map(|cnum| codegen_results.crate_info.used_crate_source[cnum].dylib.as_deref()) .collect::>(); let rpath_config = RPathConfig { libs: &*libs, @@ -2661,7 +2655,7 @@ fn add_native_libs_from_crate( if link_static && cnum != LOCAL_CRATE && !bundled_libs.is_empty() { // If rlib contains native libs as archives, unpack them to tmpdir. - let rlib = &codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap().0; + let rlib = codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap(); archive_builder_builder .extract_bundled_libs(rlib, tmpdir, bundled_libs) .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); @@ -2832,7 +2826,7 @@ fn add_upstream_rust_crates( } Linkage::Dynamic => { let src = &codegen_results.crate_info.used_crate_source[&cnum]; - add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0); + add_dynamic_crate(cmd, sess, src.dylib.as_ref().unwrap()); } } @@ -2960,7 +2954,7 @@ fn add_static_crate( bundled_lib_file_names: &FxIndexSet, ) { let src = &codegen_results.crate_info.used_crate_source[&cnum]; - let cratepath = &src.rlib.as_ref().unwrap().0; + let cratepath = src.rlib.as_ref().unwrap(); let mut link_upstream = |path: &Path| cmd.link_staticlib_by_path(&rehome_lib_path(sess, path), false); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ddfec9f886a6..b7273dd69561 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -684,19 +684,19 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P for &cnum in tcx.crates(()) { let source = tcx.used_crate_source(cnum); - if let Some((path, _)) = &source.dylib { + if let Some(path) = &source.dylib { files.extend(hash_iter_files( iter::once(escape_dep_filename(&path.display().to_string())), checksum_hash_algo, )); } - if let Some((path, _)) = &source.rlib { + if let Some(path) = &source.rlib { files.extend(hash_iter_files( iter::once(escape_dep_filename(&path.display().to_string())), checksum_hash_algo, )); } - if let Some((path, _)) = &source.rmeta { + if let Some(path) = &source.rmeta { files.extend(hash_iter_files( iter::once(escape_dep_filename(&path.display().to_string())), checksum_hash_algo, diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 85fa8cda2229..250aa0769024 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -135,16 +135,16 @@ impl<'a> std::fmt::Debug for CrateDump<'a> { writeln!(fmt, " priv: {:?}", data.is_private_dep())?; let CrateSource { dylib, rlib, rmeta, sdylib_interface } = data.source(); if let Some(dylib) = dylib { - writeln!(fmt, " dylib: {}", dylib.0.display())?; + writeln!(fmt, " dylib: {}", dylib.display())?; } if let Some(rlib) = rlib { - writeln!(fmt, " rlib: {}", rlib.0.display())?; + writeln!(fmt, " rlib: {}", rlib.display())?; } if let Some(rmeta) = rmeta { - writeln!(fmt, " rmeta: {}", rmeta.0.display())?; + writeln!(fmt, " rmeta: {}", rmeta.display())?; } if let Some(sdylib_interface) = sdylib_interface { - writeln!(fmt, " sdylib interface: {}", sdylib_interface.0.display())?; + writeln!(fmt, " sdylib interface: {}", sdylib_interface.display())?; } } Ok(()) @@ -550,9 +550,9 @@ impl CStore { if let Some(mut files) = entry.files() { if files.any(|l| { let l = l.canonicalized(); - source.dylib.as_ref().map(|(p, _)| p) == Some(l) - || source.rlib.as_ref().map(|(p, _)| p) == Some(l) - || source.rmeta.as_ref().map(|(p, _)| p) == Some(l) + source.dylib.as_ref() == Some(l) + || source.rlib.as_ref() == Some(l) + || source.rmeta.as_ref() == Some(l) }) { return Some(cnum); } @@ -658,7 +658,7 @@ impl CStore { None => (&source, &crate_root), }; let dlsym_dylib = dlsym_source.dylib.as_ref().expect("no dylib for a proc-macro crate"); - Some(self.dlsym_proc_macros(tcx.sess, &dlsym_dylib.0, dlsym_root.stable_crate_id())?) + Some(self.dlsym_proc_macros(tcx.sess, dlsym_dylib, dlsym_root.stable_crate_id())?) } else { None }; diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 9fef22f9558d..c4083a27e72b 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -218,7 +218,7 @@ use std::ops::Deref; use std::path::{Path, PathBuf}; use std::{cmp, fmt}; -use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned}; use rustc_data_structures::svh::Svh; @@ -401,7 +401,7 @@ impl<'a> CrateLocator<'a> { let mut candidates: FxIndexMap< _, - (FxIndexMap<_, _>, FxIndexMap<_, _>, FxIndexMap<_, _>, FxIndexMap<_, _>), + (FxIndexSet<_>, FxIndexSet<_>, FxIndexSet<_>, FxIndexSet<_>), > = Default::default(); // First, find all possible candidate rlibs and dylibs purely based on @@ -460,10 +460,10 @@ impl<'a> CrateLocator<'a> { // filesystem code should not care, but this is nicer for diagnostics. let path = spf.path.to_path_buf(); match kind { - CrateFlavor::Rlib => rlibs.insert(path, search_path.kind), - CrateFlavor::Rmeta => rmetas.insert(path, search_path.kind), - CrateFlavor::Dylib => dylibs.insert(path, search_path.kind), - CrateFlavor::SDylib => interfaces.insert(path, search_path.kind), + CrateFlavor::Rlib => rlibs.insert(path), + CrateFlavor::Rmeta => rmetas.insert(path), + CrateFlavor::Dylib => dylibs.insert(path), + CrateFlavor::SDylib => interfaces.insert(path), }; } } @@ -524,10 +524,10 @@ impl<'a> CrateLocator<'a> { fn extract_lib( &self, crate_rejections: &mut CrateRejections, - rlibs: FxIndexMap, - rmetas: FxIndexMap, - dylibs: FxIndexMap, - interfaces: FxIndexMap, + rlibs: FxIndexSet, + rmetas: FxIndexSet, + dylibs: FxIndexSet, + interfaces: FxIndexSet, ) -> Result, CrateError> { let mut slot = None; // Order here matters, rmeta should come first. @@ -575,10 +575,10 @@ impl<'a> CrateLocator<'a> { fn extract_one( &self, crate_rejections: &mut CrateRejections, - m: FxIndexMap, + m: FxIndexSet, flavor: CrateFlavor, slot: &mut Option<(Svh, MetadataBlob, PathBuf, CrateFlavor)>, - ) -> Result, CrateError> { + ) -> Result, CrateError> { // If we are producing an rlib, and we've already loaded metadata, then // we should not attempt to discover further crate sources (unless we're // locating a proc macro; exact logic is in needs_crate_flavor). This means @@ -594,9 +594,9 @@ impl<'a> CrateLocator<'a> { } } - let mut ret: Option<(PathBuf, PathKind)> = None; + let mut ret: Option = None; let mut err_data: Option> = None; - for (lib, kind) in m { + for lib in m { info!("{} reading metadata from: {}", flavor, lib.display()); if flavor == CrateFlavor::Rmeta && lib.metadata().is_ok_and(|m| m.len() == 0) { // Empty files will cause get_metadata_section to fail. Rmeta @@ -640,7 +640,7 @@ impl<'a> CrateLocator<'a> { info!("no metadata found: {}", err); // Metadata was loaded from interface file earlier. if let Some((.., CrateFlavor::SDylib)) = slot { - ret = Some((lib, kind)); + ret = Some(lib); continue; } // The file was present and created by the same compiler version, but we @@ -689,7 +689,7 @@ impl<'a> CrateLocator<'a> { // As a result, we favor the sysroot crate here. Note that the // candidates are all canonicalized, so we canonicalize the sysroot // as well. - if let Some((prev, _)) = &ret { + if let Some(prev) = &ret { let sysroot = self.sysroot; let sysroot = try_canonicalize(sysroot).unwrap_or_else(|_| sysroot.to_path_buf()); if prev.starts_with(&sysroot) { @@ -714,7 +714,7 @@ impl<'a> CrateLocator<'a> { } else { *slot = Some((hash, metadata, lib.clone(), flavor)); } - ret = Some((lib, kind)); + ret = Some(lib); } if let Some(candidates) = err_data { @@ -774,10 +774,10 @@ impl<'a> CrateLocator<'a> { // First, filter out all libraries that look suspicious. We only accept // files which actually exist that have the correct naming scheme for // rlibs/dylibs. - let mut rlibs = FxIndexMap::default(); - let mut rmetas = FxIndexMap::default(); - let mut dylibs = FxIndexMap::default(); - let mut sdylib_interfaces = FxIndexMap::default(); + let mut rlibs = FxIndexSet::default(); + let mut rmetas = FxIndexSet::default(); + let mut dylibs = FxIndexSet::default(); + let mut sdylib_interfaces = FxIndexSet::default(); for loc in &self.exact_paths { let loc_canon = loc.canonicalized(); let loc_orig = loc.original(); @@ -798,21 +798,21 @@ impl<'a> CrateLocator<'a> { }; if file.starts_with("lib") { if file.ends_with(".rlib") { - rlibs.insert(loc_canon.clone(), PathKind::ExternFlag); + rlibs.insert(loc_canon.clone()); continue; } if file.ends_with(".rmeta") { - rmetas.insert(loc_canon.clone(), PathKind::ExternFlag); + rmetas.insert(loc_canon.clone()); continue; } if file.ends_with(".rs") { - sdylib_interfaces.insert(loc_canon.clone(), PathKind::ExternFlag); + sdylib_interfaces.insert(loc_canon.clone()); } } let dll_prefix = self.target.dll_prefix.as_ref(); let dll_suffix = self.target.dll_suffix.as_ref(); if file.starts_with(dll_prefix) && file.ends_with(dll_suffix) { - dylibs.insert(loc_canon.clone(), PathKind::ExternFlag); + dylibs.insert(loc_canon.clone()); continue; } crate_rejections diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 30f6256a75ef..378c32d22ae2 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -15,24 +15,22 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::{Span, Symbol}; -use crate::search_paths::PathKind; - // lonely orphan structs and enums looking for a better home /// Where a crate came from on the local filesystem. One of these three options /// must be non-None. #[derive(PartialEq, Clone, Debug, HashStable_Generic, Encodable, Decodable)] pub struct CrateSource { - pub dylib: Option<(PathBuf, PathKind)>, - pub rlib: Option<(PathBuf, PathKind)>, - pub rmeta: Option<(PathBuf, PathKind)>, - pub sdylib_interface: Option<(PathBuf, PathKind)>, + pub dylib: Option, + pub rlib: Option, + pub rmeta: Option, + pub sdylib_interface: Option, } impl CrateSource { #[inline] pub fn paths(&self) -> impl Iterator { - self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).map(|p| &p.0) + self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()) } } diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index 00e12b45bafb..2ca390b50dd0 100644 --- a/compiler/rustc_session/src/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs @@ -71,7 +71,6 @@ pub enum PathKind { Crate, Dependency, Framework, - ExternFlag, All, } From d10216a3a8eec34104f6f897689245245e406a8a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:22:37 +0000 Subject: [PATCH 0139/3801] Fix rustc_hash ambiguity in miri There are two rustc_hash crates in the sysroot when building miri and there is no way to disambiguate between the two. Instead use the re-exports of it in the rustc_data_structures crate. --- compiler/rustc_data_structures/src/fx.rs | 2 +- src/tools/miri/src/diagnostics.rs | 4 ++-- src/tools/miri/src/helpers.rs | 4 ++-- src/tools/miri/src/lib.rs | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_data_structures/src/fx.rs b/compiler/rustc_data_structures/src/fx.rs index f0db9623b674..c1a5c8ebc764 100644 --- a/compiler/rustc_data_structures/src/fx.rs +++ b/compiler/rustc_data_structures/src/fx.rs @@ -1,6 +1,6 @@ use std::hash::BuildHasherDefault; -pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +pub use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet, FxHasher}; pub type StdEntry<'a, K, V> = std::collections::hash_map::Entry<'a, K, V>; diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index bb8ba196983c..bf037e3e804f 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -3,8 +3,8 @@ use std::num::NonZero; use std::sync::Mutex; use rustc_abi::{Align, Size}; +use rustc_data_structures::fx::{FxBuildHasher, FxHashSet}; use rustc_errors::{Diag, DiagMessage, Level}; -use rustc_hash::FxHashSet; use rustc_span::{DUMMY_SP, Span, SpanData, Symbol}; use crate::borrow_tracker::stacked_borrows::diagnostics::TagHistory; @@ -878,6 +878,6 @@ pub struct SpanDedupDiagnostic(Mutex>); impl SpanDedupDiagnostic { pub const fn new() -> Self { - Self(Mutex::new(FxHashSet::with_hasher(rustc_hash::FxBuildHasher))) + Self(Mutex::new(FxHashSet::with_hasher(FxBuildHasher))) } } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 383a4e2ea4b0..2ceb12a25062 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -6,7 +6,7 @@ use std::{cmp, iter}; use rand::RngCore; use rustc_abi::{Align, ExternAbi, FieldIdx, FieldsShape, Size, Variants}; use rustc_apfloat::Float; -use rustc_hash::FxHashSet; +use rustc_data_structures::fx::{FxBuildHasher, FxHashSet}; use rustc_hir::Safety; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefId, LOCAL_CRATE}; @@ -647,7 +647,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { RejectOpWith::WarningWithoutBacktrace => { // Deduplicate these warnings *by shim* (not by span) static DEDUP: Mutex> = - Mutex::new(FxHashSet::with_hasher(rustc_hash::FxBuildHasher)); + Mutex::new(FxHashSet::with_hasher(FxBuildHasher)); let mut emitted_warnings = DEDUP.lock().unwrap(); if !emitted_warnings.contains(op_name) { // First time we are seeing this. diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 5ec2e8edd857..d6d54c5ce056 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -57,7 +57,6 @@ extern crate rustc_codegen_ssa; extern crate rustc_const_eval; extern crate rustc_data_structures; extern crate rustc_errors; -extern crate rustc_hash; extern crate rustc_hir; extern crate rustc_index; extern crate rustc_log; From 9289323fe2f081ca3caa43c9f384288fde9b2e42 Mon Sep 17 00:00:00 2001 From: Mattias Petersson Date: Thu, 27 Nov 2025 20:22:51 +0100 Subject: [PATCH 0140/3801] Specify toolchain part in building and running There was an issue raised that the toolchain explanation for building and running the compiler needed some refinement. This patch aims to remedy that by specifying what "first" and "second" refer to, and what the toolchain does. Small change to the language to specify that the stage2 toolchain is not built, and how one would build it. --- .../src/building/how-to-build-and-run.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index c924216b8cd3..b15d77111e19 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -277,18 +277,20 @@ default). Once you have successfully built `rustc`, you will have created a bunch of files in your `build` directory. In order to actually run the resulting `rustc`, we recommend creating rustup toolchains. The first -one will run the stage1 compiler (which we built above). The second -will execute the stage2 compiler (which we did not build, but which -you will likely need to build at some point; for example, if you want -to run the entire test suite). +command listed below runs the stage1 compiler, which was built in the +steps above, with the name `stage1`. The second command runs the stage2 +compiler using the stage1 compiler. This will be needed in the future +if running the entire test suite, but will not be built in this page. +Building stage2 is done with the same `./x build` command as for stage1, +specifying that the stage is 2 instead. ```bash rustup toolchain link stage1 build/host/stage1 rustup toolchain link stage2 build/host/stage2 ``` -Now you can run the `rustc` you built with. If you run with `-vV`, you -should see a version number ending in `-dev`, indicating a build from +Now you can run the `rustc` you built with via the toolchain. If you run with +`-vV`, you should see a version number ending in `-dev`, indicating a build from your local environment: ```bash From f4296bce97007d68ab4236f5293f50bf06a3664e Mon Sep 17 00:00:00 2001 From: Skgland Date: Thu, 27 Nov 2025 22:02:47 +0100 Subject: [PATCH 0141/3801] fix tests --- tests/run-make/env-dep-info/macro_def.rs | 4 ++-- tests/run-make/track-path-dep-info/macro_def.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/run-make/env-dep-info/macro_def.rs b/tests/run-make/env-dep-info/macro_def.rs index e328eae48326..17d27ebfba3c 100644 --- a/tests/run-make/env-dep-info/macro_def.rs +++ b/tests/run-make/env-dep-info/macro_def.rs @@ -6,7 +6,7 @@ use proc_macro::*; #[proc_macro] pub fn access_env_vars(_: TokenStream) -> TokenStream { - let _ = tracked_env::var("EXISTING_PROC_MACRO_ENV"); - let _ = tracked_env::var("NONEXISTENT_PROC_MACEO_ENV"); + let _ = tracked::env_var("EXISTING_PROC_MACRO_ENV"); + let _ = tracked::env_var("NONEXISTENT_PROC_MACEO_ENV"); TokenStream::new() } diff --git a/tests/run-make/track-path-dep-info/macro_def.rs b/tests/run-make/track-path-dep-info/macro_def.rs index 8777ce21f8b8..032594d905d0 100644 --- a/tests/run-make/track-path-dep-info/macro_def.rs +++ b/tests/run-make/track-path-dep-info/macro_def.rs @@ -1,4 +1,4 @@ -#![feature(track_path)] +#![feature(proc_macro_track_path)] #![crate_type = "proc-macro"] extern crate proc_macro; @@ -6,6 +6,6 @@ use proc_macro::*; #[proc_macro] pub fn access_tracked_paths(_: TokenStream) -> TokenStream { - tracked_path::path("emojis.txt"); + tracked::path("emojis.txt"); TokenStream::new() } From 6a14a523d286adb2d1d7265f20b6a8e2bd042466 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 20 Nov 2025 12:56:12 +0100 Subject: [PATCH 0142/3801] clean-up: pass things by value to avoid copying --- clippy_lints/src/missing_asserts_for_indexing.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index 808adb7e71ce..9e9aa5ffc544 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -67,14 +67,14 @@ declare_clippy_lint! { } declare_lint_pass!(MissingAssertsForIndexing => [MISSING_ASSERTS_FOR_INDEXING]); -fn report_lint(cx: &LateContext<'_>, full_span: Span, msg: &'static str, indexes: &[Span], f: F) +fn report_lint(cx: &LateContext<'_>, full_span: Span, msg: &'static str, indexes: Vec, f: F) where F: FnOnce(&mut Diag<'_, ()>), { span_lint_and_then(cx, MISSING_ASSERTS_FOR_INDEXING, full_span, msg, |diag| { f(diag); for span in indexes { - diag.span_note(*span, "slice indexed here"); + diag.span_note(span, "slice indexed here"); } diag.note("asserting the length before indexing will elide bounds checks"); }); @@ -354,8 +354,8 @@ fn check_assert<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Un /// Inspects indexes and reports lints. /// /// Called at the end of this lint after all indexing and `assert!` expressions have been collected. -fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap>>) { - for bucket in map.values() { +fn report_indexes(cx: &LateContext<'_>, map: UnindexMap>>) { + for bucket in map.into_values() { for entry in bucket { let Some(full_span) = entry .index_spans() @@ -365,12 +365,12 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap continue; }; - match *entry { + match entry { IndexEntry::AssertWithIndex { highest_index, is_first_highest, asserted_len, - ref indexes, + indexes, comparison, assert_span, slice, @@ -433,7 +433,7 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap } }, IndexEntry::IndexWithoutAssert { - ref indexes, + indexes, highest_index, is_first_highest, slice, @@ -469,6 +469,6 @@ impl LateLintPass<'_> for MissingAssertsForIndexing { ControlFlow::::Continue(()) }); - report_indexes(cx, &map); + report_indexes(cx, map); } } From 9ced0f5892eaff77f7b707fbd41be92d38b42028 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 20 Nov 2025 12:58:16 +0100 Subject: [PATCH 0143/3801] use `note_once` This is a general advice, and so shouldn't be repeated --- clippy_lints/src/missing_asserts_for_indexing.rs | 2 +- tests/ui/missing_asserts_for_indexing.stderr | 14 -------------- .../missing_asserts_for_indexing_unfixable.stderr | 9 --------- 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index 9e9aa5ffc544..ea65aa274dc4 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -76,7 +76,7 @@ where for span in indexes { diag.span_note(span, "slice indexed here"); } - diag.note("asserting the length before indexing will elide bounds checks"); + diag.note_once("asserting the length before indexing will elide bounds checks"); }); } diff --git a/tests/ui/missing_asserts_for_indexing.stderr b/tests/ui/missing_asserts_for_indexing.stderr index b686eda7530a..d6eef15c0448 100644 --- a/tests/ui/missing_asserts_for_indexing.stderr +++ b/tests/ui/missing_asserts_for_indexing.stderr @@ -68,7 +68,6 @@ note: slice indexed here | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:42:5 @@ -103,7 +102,6 @@ note: slice indexed here | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:48:5 @@ -138,7 +136,6 @@ note: slice indexed here | LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:66:13 @@ -161,7 +158,6 @@ note: slice indexed here | LL | let _ = v[1..4]; | ^^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:81:13 @@ -184,7 +180,6 @@ note: slice indexed here | LL | let _ = v[1..=4]; | ^^^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:97:13 @@ -205,7 +200,6 @@ note: slice indexed here | LL | let _ = v1[0] + v1[12]; | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:100:13 @@ -226,7 +220,6 @@ note: slice indexed here | LL | let _ = v2[5] + v2[15]; | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:106:13 @@ -247,7 +240,6 @@ note: slice indexed here | LL | let _ = v1[0] + v1[12]; | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:131:13 @@ -273,7 +265,6 @@ note: slice indexed here | LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:136:13 @@ -299,7 +290,6 @@ note: slice indexed here | LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:158:13 @@ -325,7 +315,6 @@ note: slice indexed here | LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:163:13 @@ -351,7 +340,6 @@ note: slice indexed here | LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:172:17 @@ -376,7 +364,6 @@ note: slice indexed here | LL | let _ = v[0] + v[1] + v[2]; | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:178:17 @@ -401,7 +388,6 @@ note: slice indexed here | LL | let _ = v[0] + v[1] + v[2]; | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: aborting due to 15 previous errors diff --git a/tests/ui/missing_asserts_for_indexing_unfixable.stderr b/tests/ui/missing_asserts_for_indexing_unfixable.stderr index a17ad0232138..aec64857a699 100644 --- a/tests/ui/missing_asserts_for_indexing_unfixable.stderr +++ b/tests/ui/missing_asserts_for_indexing_unfixable.stderr @@ -54,7 +54,6 @@ note: slice indexed here | LL | let _ = v[1..4]; | ^^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:17:13 @@ -83,7 +82,6 @@ note: slice indexed here | LL | let c = v[2]; | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:13 @@ -102,7 +100,6 @@ note: slice indexed here | LL | let _ = v1[0] + v1[12]; | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:13 @@ -121,7 +118,6 @@ note: slice indexed here | LL | let _ = v2[5] + v2[15]; | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:13 @@ -140,7 +136,6 @@ note: slice indexed here | LL | let _ = v2[5] + v2[15]; | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:13 @@ -159,7 +154,6 @@ note: slice indexed here | LL | let _ = f.v[0] + f.v[1]; | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:13 @@ -178,7 +172,6 @@ note: slice indexed here | LL | let _ = x[0] + x[1]; | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:77:13 @@ -197,7 +190,6 @@ note: slice indexed here | LL | let _ = v1[1] + v1[2]; | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:13 @@ -221,7 +213,6 @@ note: slice indexed here | LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: aborting due to 10 previous errors From 4b021f6b62c5210b4c0e37ae3eb3873081e92128 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 20 Nov 2025 13:30:54 +0100 Subject: [PATCH 0144/3801] point the suggestion at each individual span This makes the labels redundant. --- .../src/missing_asserts_for_indexing.rs | 30 +- tests/ui/missing_asserts_for_indexing.stderr | 292 ++---------------- ...sing_asserts_for_indexing_unfixable.stderr | 153 +-------- 3 files changed, 37 insertions(+), 438 deletions(-) diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index ea65aa274dc4..a89a460cdfb3 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -67,15 +67,12 @@ declare_clippy_lint! { } declare_lint_pass!(MissingAssertsForIndexing => [MISSING_ASSERTS_FOR_INDEXING]); -fn report_lint(cx: &LateContext<'_>, full_span: Span, msg: &'static str, indexes: Vec, f: F) +fn report_lint(cx: &LateContext<'_>, index_spans: Vec, msg: &'static str, f: F) where F: FnOnce(&mut Diag<'_, ()>), { - span_lint_and_then(cx, MISSING_ASSERTS_FOR_INDEXING, full_span, msg, |diag| { + span_lint_and_then(cx, MISSING_ASSERTS_FOR_INDEXING, index_spans, msg, |diag| { f(diag); - for span in indexes { - diag.span_note(span, "slice indexed here"); - } diag.note_once("asserting the length before indexing will elide bounds checks"); }); } @@ -213,15 +210,6 @@ impl<'hir> IndexEntry<'hir> { | IndexEntry::IndexWithoutAssert { slice, .. } => slice, } } - - pub fn index_spans(&self) -> Option<&[Span]> { - match self { - IndexEntry::StrayAssert { .. } => None, - IndexEntry::AssertWithIndex { indexes, .. } | IndexEntry::IndexWithoutAssert { indexes, .. } => { - Some(indexes) - }, - } - } } /// Extracts the upper index of a slice indexing expression. @@ -357,14 +345,6 @@ fn check_assert<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Un fn report_indexes(cx: &LateContext<'_>, map: UnindexMap>>) { for bucket in map.into_values() { for entry in bucket { - let Some(full_span) = entry - .index_spans() - .and_then(|spans| spans.first().zip(spans.last())) - .map(|(low, &high)| low.to(high)) - else { - continue; - }; - match entry { IndexEntry::AssertWithIndex { highest_index, @@ -418,9 +398,8 @@ fn report_indexes(cx: &LateContext<'_>, map: UnindexMap> if let Some(sugg) = sugg { report_lint( cx, - full_span, - "indexing into a slice multiple times with an `assert` that does not cover the highest index", indexes, + "indexing into a slice multiple times with an `assert` that does not cover the highest index", |diag| { diag.span_suggestion( assert_span, @@ -442,9 +421,8 @@ fn report_indexes(cx: &LateContext<'_>, map: UnindexMap> // adding an `assert!` that covers the highest index report_lint( cx, - full_span, - "indexing into a slice multiple times without an `assert`", indexes, + "indexing into a slice multiple times without an `assert`", |diag| { diag.help(format!( "consider asserting the length before indexing: `assert!({}.len() > {highest_index});`", diff --git a/tests/ui/missing_asserts_for_indexing.stderr b/tests/ui/missing_asserts_for_indexing.stderr index d6eef15c0448..30a35a21e5d3 100644 --- a/tests/ui/missing_asserts_for_indexing.stderr +++ b/tests/ui/missing_asserts_for_indexing.stderr @@ -4,33 +4,8 @@ error: indexing into a slice multiple times with an `assert` that does not cover LL | assert!(v.len() < 5); | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:5 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:12 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ = note: asserting the length before indexing will elide bounds checks = note: `-D clippy::missing-asserts-for-indexing` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]` @@ -41,33 +16,7 @@ error: indexing into a slice multiple times with an `assert` that does not cover LL | assert!(v.len() <= 5); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:5 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:12 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:42:5 @@ -75,33 +24,7 @@ error: indexing into a slice multiple times with an `assert` that does not cover LL | assert!(v.len() > 3); | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:5 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:12 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:48:5 @@ -109,75 +32,27 @@ error: indexing into a slice multiple times with an `assert` that does not cover LL | assert!(v.len() >= 4); | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:5 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:12 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:66:13 | -LL | assert!(v.len() >= 3); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 3)` -LL | let _ = v[0]; - | _____________^ -... | -LL | | let _ = v[1..4]; - | |___________________^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:66:13 - | +LL | assert!(v.len() >= 3); + | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 3)` LL | let _ = v[0]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:69:13 - | +... LL | let _ = v[1..4]; | ^^^^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:81:13 | -LL | assert!(v.len() >= 4); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` -LL | let _ = v[0]; - | _____________^ -... | -LL | | let _ = v[1..=4]; - | |____________________^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:81:13 - | +LL | assert!(v.len() >= 4); + | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | let _ = v[0]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:84:13 - | +... LL | let _ = v[1..=4]; | ^^^^^^^^ @@ -188,18 +63,7 @@ LL | assert!(v1.len() >= 12); | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` LL | assert!(v2.len() >= 15); LL | let _ = v1[0] + v1[12]; - | ^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:97:13 - | -LL | let _ = v1[0] + v1[12]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:97:21 - | -LL | let _ = v1[0] + v1[12]; - | ^^^^^^ + | ^^^^^ ^^^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:100:13 @@ -208,18 +72,7 @@ LL | assert!(v2.len() >= 15); | ----------------------- help: provide the highest index that is indexed with: `assert!(v2.len() > 15)` ... LL | let _ = v2[5] + v2[15]; - | ^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:100:13 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:100:21 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^^ + | ^^^^^ ^^^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:106:13 @@ -228,18 +81,7 @@ LL | assert!(v1.len() >= 12); | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` LL | assert!(v2.len() > 15); LL | let _ = v1[0] + v1[12]; - | ^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:106:13 - | -LL | let _ = v1[0] + v1[12]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:106:21 - | -LL | let _ = v1[0] + v1[12]; - | ^^^^^^ + | ^^^^^ ^^^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:131:13 @@ -248,23 +90,7 @@ LL | assert!(v1.len() == 2); | ---------------------- help: provide the highest index that is indexed with: `assert!(v1.len() == 3)` ... LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:131:13 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:131:21 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:131:29 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ + | ^^^^^ ^^^^^ ^^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:136:13 @@ -273,23 +99,7 @@ LL | assert!(2 == v3.len()); | ---------------------- help: provide the highest index that is indexed with: `assert!(v3.len() == 3)` ... LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:136:13 - | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:136:21 - | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:136:29 - | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ + | ^^^^^ ^^^^^ ^^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:158:13 @@ -298,23 +108,7 @@ LL | assert_eq!(v1.len(), 2); | ----------------------- help: provide the highest index that is indexed with: `assert_eq!(v1.len(), 3)` ... LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:158:13 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:158:21 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:158:29 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ + | ^^^^^ ^^^^^ ^^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:163:13 @@ -323,23 +117,7 @@ LL | assert_eq!(2, v3.len()); | ----------------------- help: provide the highest index that is indexed with: `assert_eq!(v3.len(), 3)` ... LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:163:13 - | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:163:21 - | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:163:29 - | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ + | ^^^^^ ^^^^^ ^^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:172:17 @@ -347,23 +125,7 @@ error: indexing into a slice multiple times with an `assert` that does not cover LL | assert_eq!(v.len(), 2); | ---------------------- help: provide the highest index that is indexed with: `assert_eq!(v.len(), 3)` LL | let _ = v[0] + v[1] + v[2]; - | ^^^^^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:172:17 - | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:172:24 - | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:172:31 - | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ + | ^^^^ ^^^^ ^^^^ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:178:17 @@ -371,23 +133,7 @@ error: indexing into a slice multiple times with an `assert` that does not cover LL | debug_assert_eq!(v.len(), 2); | ---------------------------- help: provide the highest index that is indexed with: `debug_assert_eq!(v.len(), 3)` LL | let _ = v[0] + v[1] + v[2]; - | ^^^^^^^^^^^^^^^^^^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:178:17 - | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:178:24 - | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:178:31 - | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ + | ^^^^ ^^^^ ^^^^ error: aborting due to 15 previous errors diff --git a/tests/ui/missing_asserts_for_indexing_unfixable.stderr b/tests/ui/missing_asserts_for_indexing_unfixable.stderr index aec64857a699..2929646494a4 100644 --- a/tests/ui/missing_asserts_for_indexing_unfixable.stderr +++ b/tests/ui/missing_asserts_for_indexing_unfixable.stderr @@ -2,34 +2,9 @@ error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:5 | LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ | = help: consider asserting the length before indexing: `assert!(v.len() > 4);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:5 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:12 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ = note: asserting the length before indexing will elide bounds checks = note: `-D clippy::missing-asserts-for-indexing` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]` @@ -37,182 +12,82 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:10:13 | -LL | let _ = v[0]; - | _____________^ -... | -LL | | let _ = v[1..4]; - | |___________________^ - | - = help: consider asserting the length before indexing: `assert!(v.len() > 3);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:10:13 - | LL | let _ = v[0]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:13:13 - | +... LL | let _ = v[1..4]; | ^^^^^^^ + | + = help: consider asserting the length before indexing: `assert!(v.len() > 3);` error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:17:13 | -LL | let a = v[0]; - | _____________^ -LL | | -LL | | -LL | | let b = v[1]; -LL | | let c = v[2]; - | |________________^ - | - = help: consider asserting the length before indexing: `assert!(v.len() > 2);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:17:13 - | LL | let a = v[0]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:20:13 - | +... LL | let b = v[1]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:21:13 - | LL | let c = v[2]; | ^^^^ + | + = help: consider asserting the length before indexing: `assert!(v.len() > 2);` error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:13 | LL | let _ = v1[0] + v1[12]; - | ^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^^ | = help: consider asserting the length before indexing: `assert!(v1.len() > 12);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:13 - | -LL | let _ = v1[0] + v1[12]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:21 - | -LL | let _ = v1[0] + v1[12]; - | ^^^^^^ error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:13 | LL | let _ = v2[5] + v2[15]; - | ^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^^ | = help: consider asserting the length before indexing: `assert!(v2.len() > 15);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:13 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:21 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^^ error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:13 | LL | let _ = v2[5] + v2[15]; - | ^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^^ | = help: consider asserting the length before indexing: `assert!(v2.len() > 15);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:13 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:21 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^^ error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:13 | LL | let _ = f.v[0] + f.v[1]; - | ^^^^^^^^^^^^^^^ + | ^^^^^^ ^^^^^^ | = help: consider asserting the length before indexing: `assert!(f.v.len() > 1);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:13 - | -LL | let _ = f.v[0] + f.v[1]; - | ^^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:22 - | -LL | let _ = f.v[0] + f.v[1]; - | ^^^^^^ error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:13 | LL | let _ = x[0] + x[1]; - | ^^^^^^^^^^^ + | ^^^^ ^^^^ | = help: consider asserting the length before indexing: `assert!(x.len() > 1);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:13 - | -LL | let _ = x[0] + x[1]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:20 - | -LL | let _ = x[0] + x[1]; - | ^^^^ error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:77:13 | LL | let _ = v1[1] + v1[2]; - | ^^^^^^^^^^^^^ + | ^^^^^ ^^^^^ | = help: consider asserting the length before indexing: `assert!(v1.len() > 2);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:77:13 - | -LL | let _ = v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:77:21 - | -LL | let _ = v1[1] + v1[2]; - | ^^^^^ error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:13 | LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^ ^^^^^ | = help: consider asserting the length before indexing: `assert!(v1.len() > 2);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:13 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:21 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:29 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ error: aborting due to 10 previous errors From f3b905d4a84b4d7ef58bcda3e2dcff08df979d2c Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 20 Nov 2025 13:46:55 +0100 Subject: [PATCH 0145/3801] use `span_suggestion_verbose` --- .../src/missing_asserts_for_indexing.rs | 2 +- tests/ui/missing_asserts_for_indexing.stderr | 126 +++++++++++++----- 2 files changed, 90 insertions(+), 38 deletions(-) diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index a89a460cdfb3..72bfe830da81 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -401,7 +401,7 @@ fn report_indexes(cx: &LateContext<'_>, map: UnindexMap> indexes, "indexing into a slice multiple times with an `assert` that does not cover the highest index", |diag| { - diag.span_suggestion( + diag.span_suggestion_verbose( assert_span, "provide the highest index that is indexed with", sugg, diff --git a/tests/ui/missing_asserts_for_indexing.stderr b/tests/ui/missing_asserts_for_indexing.stderr index 30a35a21e5d3..d5b5455343e4 100644 --- a/tests/ui/missing_asserts_for_indexing.stderr +++ b/tests/ui/missing_asserts_for_indexing.stderr @@ -1,139 +1,191 @@ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:30:5 | -LL | assert!(v.len() < 5); - | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ | = note: asserting the length before indexing will elide bounds checks = note: `-D clippy::missing-asserts-for-indexing` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]` +help: provide the highest index that is indexed with + | +LL - assert!(v.len() < 5); +LL + assert!(v.len() > 4); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:36:5 | -LL | assert!(v.len() <= 5); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(v.len() <= 5); +LL + assert!(v.len() > 4); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:42:5 | -LL | assert!(v.len() > 3); - | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(v.len() > 3); +LL + assert!(v.len() > 4); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:48:5 | -LL | assert!(v.len() >= 4); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(v.len() >= 4); +LL + assert!(v.len() > 4); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:66:13 | -LL | assert!(v.len() >= 3); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 3)` LL | let _ = v[0]; | ^^^^ ... LL | let _ = v[1..4]; | ^^^^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(v.len() >= 3); +LL + assert!(v.len() > 3); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:81:13 | -LL | assert!(v.len() >= 4); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | let _ = v[0]; | ^^^^ ... LL | let _ = v[1..=4]; | ^^^^^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(v.len() >= 4); +LL + assert!(v.len() > 4); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:97:13 | -LL | assert!(v1.len() >= 12); - | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` -LL | assert!(v2.len() >= 15); LL | let _ = v1[0] + v1[12]; | ^^^^^ ^^^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(v1.len() >= 12); +LL + assert!(v1.len() > 12); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:100:13 | -LL | assert!(v2.len() >= 15); - | ----------------------- help: provide the highest index that is indexed with: `assert!(v2.len() > 15)` -... LL | let _ = v2[5] + v2[15]; | ^^^^^ ^^^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(v2.len() >= 15); +LL + assert!(v2.len() > 15); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:106:13 | -LL | assert!(v1.len() >= 12); - | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` -LL | assert!(v2.len() > 15); LL | let _ = v1[0] + v1[12]; | ^^^^^ ^^^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(v1.len() >= 12); +LL + assert!(v1.len() > 12); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:131:13 | -LL | assert!(v1.len() == 2); - | ---------------------- help: provide the highest index that is indexed with: `assert!(v1.len() == 3)` -... LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ ^^^^^ ^^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(v1.len() == 2); +LL + assert!(v1.len() == 3); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:136:13 | -LL | assert!(2 == v3.len()); - | ---------------------- help: provide the highest index that is indexed with: `assert!(v3.len() == 3)` -... LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ ^^^^^ ^^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert!(2 == v3.len()); +LL + assert!(v3.len() == 3); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:158:13 | -LL | assert_eq!(v1.len(), 2); - | ----------------------- help: provide the highest index that is indexed with: `assert_eq!(v1.len(), 3)` -... LL | let _ = v1[0] + v1[1] + v1[2]; | ^^^^^ ^^^^^ ^^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert_eq!(v1.len(), 2); +LL + assert_eq!(v1.len(), 3); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:163:13 | -LL | assert_eq!(2, v3.len()); - | ----------------------- help: provide the highest index that is indexed with: `assert_eq!(v3.len(), 3)` -... LL | let _ = v3[0] + v3[1] + v3[2]; | ^^^^^ ^^^^^ ^^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert_eq!(2, v3.len()); +LL + assert_eq!(v3.len(), 3); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:172:17 | -LL | assert_eq!(v.len(), 2); - | ---------------------- help: provide the highest index that is indexed with: `assert_eq!(v.len(), 3)` LL | let _ = v[0] + v[1] + v[2]; | ^^^^ ^^^^ ^^^^ + | +help: provide the highest index that is indexed with + | +LL - assert_eq!(v.len(), 2); +LL + assert_eq!(v.len(), 3); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:178:17 | -LL | debug_assert_eq!(v.len(), 2); - | ---------------------------- help: provide the highest index that is indexed with: `debug_assert_eq!(v.len(), 3)` LL | let _ = v[0] + v[1] + v[2]; | ^^^^ ^^^^ ^^^^ + | +help: provide the highest index that is indexed with + | +LL - debug_assert_eq!(v.len(), 2); +LL + debug_assert_eq!(v.len(), 3); + | error: aborting due to 15 previous errors From 129a39d6be3e18ea1ad3daae992901e1a27f7851 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 20 Nov 2025 14:53:19 +0100 Subject: [PATCH 0146/3801] fix: adjust the applicability for the suggestion --- .../src/missing_asserts_for_indexing.rs | 48 ++++++++----------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index 72bfe830da81..87ee164a1760 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -5,7 +5,7 @@ use clippy_utils::comparisons::{Rel, normalize_comparison}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::{If, Range}; use clippy_utils::macros::{find_assert_eq_args, first_node_macro_backtrace, root_macro_call}; -use clippy_utils::source::snippet; +use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{eq_expr_value, hash_expr}; use rustc_ast::{BinOpKind, LitKind, RangeLimits}; @@ -356,41 +356,33 @@ fn report_indexes(cx: &LateContext<'_>, map: UnindexMap> slice, macro_call, } if indexes.len() > 1 && !is_first_highest => { + let mut app = Applicability::MachineApplicable; + let slice_str = snippet_with_applicability(cx, slice.span, "_", &mut app); // if we have found an `assert!`, let's also check that it's actually right // and if it covers the highest index and if not, suggest the correct length let sugg = match comparison { // `v.len() < 5` and `v.len() <= 5` does nothing in terms of bounds checks. // The user probably meant `v.len() > 5` - LengthComparison::LengthLessThanInt | LengthComparison::LengthLessThanOrEqualInt => Some( - format!("assert!({}.len() > {highest_index})", snippet(cx, slice.span, "..")), - ), + LengthComparison::LengthLessThanInt | LengthComparison::LengthLessThanOrEqualInt => { + Some(format!("assert!({slice_str}.len() > {highest_index})",)) + }, // `5 < v.len()` == `v.len() > 5` - LengthComparison::IntLessThanLength if asserted_len < highest_index => Some(format!( - "assert!({}.len() > {highest_index})", - snippet(cx, slice.span, "..") - )), + LengthComparison::IntLessThanLength if asserted_len < highest_index => { + Some(format!("assert!({slice_str}.len() > {highest_index})",)) + }, // `5 <= v.len() == `v.len() >= 5` - LengthComparison::IntLessThanOrEqualLength if asserted_len <= highest_index => Some(format!( - "assert!({}.len() > {highest_index})", - snippet(cx, slice.span, "..") - )), + LengthComparison::IntLessThanOrEqualLength if asserted_len <= highest_index => { + Some(format!("assert!({slice_str}.len() > {highest_index})",)) + }, // `highest_index` here is rather a length, so we need to add 1 to it LengthComparison::LengthEqualInt if asserted_len < highest_index + 1 => match macro_call { - sym::assert_eq_macro => Some(format!( - "assert_eq!({}.len(), {})", - snippet(cx, slice.span, ".."), - highest_index + 1 - )), - sym::debug_assert_eq_macro => Some(format!( - "debug_assert_eq!({}.len(), {})", - snippet(cx, slice.span, ".."), - highest_index + 1 - )), - _ => Some(format!( - "assert!({}.len() == {})", - snippet(cx, slice.span, ".."), - highest_index + 1 - )), + sym::assert_eq_macro => { + Some(format!("assert_eq!({slice_str}.len(), {})", highest_index + 1)) + }, + sym::debug_assert_eq_macro => { + Some(format!("debug_assert_eq!({slice_str}.len(), {})", highest_index + 1)) + }, + _ => Some(format!("assert!({slice_str}.len() == {})", highest_index + 1)), }, _ => None, }; @@ -405,7 +397,7 @@ fn report_indexes(cx: &LateContext<'_>, map: UnindexMap> assert_span, "provide the highest index that is indexed with", sugg, - Applicability::MachineApplicable, + app, ); }, ); From daa2cd340aa39099914b0459b5d3843eb9d072a4 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 27 Nov 2025 22:36:54 +0100 Subject: [PATCH 0147/3801] s390x: use `simd_shuffle!` macro --- .../crates/core_arch/src/s390x/vector.rs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/s390x/vector.rs b/library/stdarch/crates/core_arch/src/s390x/vector.rs index 7208105fb872..1366b5c78273 100644 --- a/library/stdarch/crates/core_arch/src/s390x/vector.rs +++ b/library/stdarch/crates/core_arch/src/s390x/vector.rs @@ -896,7 +896,7 @@ mod sealed { #[cfg_attr(test, assert_instr(vrepb, IMM2 = 1))] unsafe fn vrepb(a: vector_signed_char) -> vector_signed_char { static_assert_uimm_bits!(IMM2, 4); - simd_shuffle(a, a, const { u32x16::from_array([IMM2; 16]) }) + simd_shuffle!(a, a, [IMM2; 16]) } #[inline] @@ -904,7 +904,7 @@ mod sealed { #[cfg_attr(test, assert_instr(vreph, IMM2 = 1))] unsafe fn vreph(a: vector_signed_short) -> vector_signed_short { static_assert_uimm_bits!(IMM2, 3); - simd_shuffle(a, a, const { u32x8::from_array([IMM2; 8]) }) + simd_shuffle!(a, a, [IMM2; 8]) } #[inline] @@ -912,7 +912,7 @@ mod sealed { #[cfg_attr(test, assert_instr(vrepf, IMM2 = 1))] unsafe fn vrepf(a: vector_signed_int) -> vector_signed_int { static_assert_uimm_bits!(IMM2, 2); - simd_shuffle(a, a, const { u32x4::from_array([IMM2; 4]) }) + simd_shuffle!(a, a, [IMM2; 4]) } #[inline] @@ -920,7 +920,7 @@ mod sealed { #[cfg_attr(test, assert_instr(vrepg, IMM2 = 1))] unsafe fn vrepg(a: vector_signed_long_long) -> vector_signed_long_long { static_assert_uimm_bits!(IMM2, 1); - simd_shuffle(a, a, const { u32x2::from_array([IMM2; 2]) }) + simd_shuffle!(a, a, [IMM2; 2]) } macro_rules! impl_vec_splat { @@ -5307,11 +5307,13 @@ pub unsafe fn vec_search_string_until_zero_cc( #[inline] #[target_feature(enable = "vector-enhancements-1")] #[unstable(feature = "stdarch_s390x", issue = "135681")] -// FIXME: this emits `vflls` where `vldeb` is expected -// #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vldeb))] +// NOTE: `vflls` and `vldeb` are equivalent; our disassmbler prefers vflls. +#[cfg_attr( + all(test, target_feature = "vector-enhancements-1"), + assert_instr(vflls) +)] pub unsafe fn vec_doublee(a: vector_float) -> vector_double { - let even = simd_shuffle::<_, _, f32x2>(a, a, const { u32x2::from_array([0, 2]) }); - simd_as(even) + simd_as::(simd_shuffle!(a, a, [0, 2])) } /// Vector Convert from double to float (even elements) @@ -5322,11 +5324,7 @@ pub unsafe fn vec_doublee(a: vector_float) -> vector_double { // #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vledb))] pub unsafe fn vec_floate(a: vector_double) -> vector_float { let truncated: f32x2 = simd_as(a); - simd_shuffle( - truncated, - truncated, - const { u32x4::from_array([0, 0, 1, 1]) }, - ) + simd_shuffle!(truncated, truncated, [0, 0, 1, 1]) } /// Vector Convert from int to float From 4c49a7a22f791fad7e3e60f2d8f3c080db3aabd4 Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 27 Nov 2025 07:04:37 +0530 Subject: [PATCH 0148/3801] Refactor max/min intrinsics using a helper function --- library/stdarch/crates/core_arch/src/simd.rs | 12 +++ .../stdarch/crates/core_arch/src/x86/avx2.rs | 72 +++----------- .../crates/core_arch/src/x86/avx512bw.rs | 50 ++-------- .../crates/core_arch/src/x86/avx512f.rs | 96 ++++--------------- .../stdarch/crates/core_arch/src/x86/sse2.rs | 24 +---- .../stdarch/crates/core_arch/src/x86/sse41.rs | 48 ++-------- 6 files changed, 61 insertions(+), 241 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/simd.rs b/library/stdarch/crates/core_arch/src/simd.rs index 25834943f009..9fa8e2502265 100644 --- a/library/stdarch/crates/core_arch/src/simd.rs +++ b/library/stdarch/crates/core_arch/src/simd.rs @@ -2,6 +2,18 @@ #![allow(non_camel_case_types)] +#[inline(always)] +pub(crate) unsafe fn simd_imax(a: T, b: T) -> T { + let mask: T = crate::intrinsics::simd::simd_gt(a, b); + crate::intrinsics::simd::simd_select(mask, a, b) +} + +#[inline(always)] +pub(crate) unsafe fn simd_imin(a: T, b: T) -> T { + let mask: T = crate::intrinsics::simd::simd_lt(a, b); + crate::intrinsics::simd::simd_select(mask, a, b) +} + macro_rules! simd_ty { ($id:ident [$elem_type:ty ; $len:literal]: $($param_name:ident),*) => { #[repr(simd)] diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 8be302cabc77..3734915b709f 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -1897,11 +1897,7 @@ pub unsafe fn _mm256_maskstore_epi64(mem_addr: *mut i64, mask: __m256i, a: __m25 #[cfg_attr(test, assert_instr(vpmaxsw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_max_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_i16x16(); - let b = b.as_i16x16(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i16x16(), b.as_i16x16()).as_m256i() } } /// Compares packed 32-bit integers in `a` and `b`, and returns the packed @@ -1913,11 +1909,7 @@ pub fn _mm256_max_epi16(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpmaxsd))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_max_epi32(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_i32x8(); - let b = b.as_i32x8(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i32x8(), b.as_i32x8()).as_m256i() } } /// Compares packed 8-bit integers in `a` and `b`, and returns the packed @@ -1929,11 +1921,7 @@ pub fn _mm256_max_epi32(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpmaxsb))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_max_epi8(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_i8x32(); - let b = b.as_i8x32(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i8x32(), b.as_i8x32()).as_m256i() } } /// Compares packed unsigned 16-bit integers in `a` and `b`, and returns @@ -1945,11 +1933,7 @@ pub fn _mm256_max_epi8(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpmaxuw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_max_epu16(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_u16x16(); - let b = b.as_u16x16(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u16x16(), b.as_u16x16()).as_m256i() } } /// Compares packed unsigned 32-bit integers in `a` and `b`, and returns @@ -1961,11 +1945,7 @@ pub fn _mm256_max_epu16(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpmaxud))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_max_epu32(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_u32x8(); - let b = b.as_u32x8(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u32x8(), b.as_u32x8()).as_m256i() } } /// Compares packed unsigned 8-bit integers in `a` and `b`, and returns @@ -1977,11 +1957,7 @@ pub fn _mm256_max_epu32(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpmaxub))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_max_epu8(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_u8x32(); - let b = b.as_u8x32(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u8x32(), b.as_u8x32()).as_m256i() } } /// Compares packed 16-bit integers in `a` and `b`, and returns the packed @@ -1993,11 +1969,7 @@ pub fn _mm256_max_epu8(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpminsw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_min_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_i16x16(); - let b = b.as_i16x16(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i16x16(), b.as_i16x16()).as_m256i() } } /// Compares packed 32-bit integers in `a` and `b`, and returns the packed @@ -2009,11 +1981,7 @@ pub fn _mm256_min_epi16(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpminsd))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_min_epi32(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_i32x8(); - let b = b.as_i32x8(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i32x8(), b.as_i32x8()).as_m256i() } } /// Compares packed 8-bit integers in `a` and `b`, and returns the packed @@ -2025,11 +1993,7 @@ pub fn _mm256_min_epi32(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpminsb))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_min_epi8(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_i8x32(); - let b = b.as_i8x32(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i8x32(), b.as_i8x32()).as_m256i() } } /// Compares packed unsigned 16-bit integers in `a` and `b`, and returns @@ -2041,11 +2005,7 @@ pub fn _mm256_min_epi8(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpminuw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_min_epu16(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_u16x16(); - let b = b.as_u16x16(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u16x16(), b.as_u16x16()).as_m256i() } } /// Compares packed unsigned 32-bit integers in `a` and `b`, and returns @@ -2057,11 +2017,7 @@ pub fn _mm256_min_epu16(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpminud))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_min_epu32(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_u32x8(); - let b = b.as_u32x8(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u32x8(), b.as_u32x8()).as_m256i() } } /// Compares packed unsigned 8-bit integers in `a` and `b`, and returns @@ -2073,11 +2029,7 @@ pub fn _mm256_min_epu32(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpminub))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_min_epu8(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_u8x32(); - let b = b.as_u8x32(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u8x32(), b.as_u8x32()).as_m256i() } } /// Creates mask from the most significant bit of each 8-bit element in `a`, diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 0e2dd3ad4068..4310c3d0ac1b 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -1743,11 +1743,7 @@ pub fn _mm_maskz_mullo_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuw))] pub fn _mm512_max_epu16(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_u16x32(); - let b = b.as_u16x32(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u16x32(), b.as_u16x32()).as_m512i() } } /// Compare packed unsigned 16-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -1842,11 +1838,7 @@ pub fn _mm_maskz_max_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxub))] pub fn _mm512_max_epu8(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_u8x64(); - let b = b.as_u8x64(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u8x64(), b.as_u8x64()).as_m512i() } } /// Compare packed unsigned 8-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -1941,11 +1933,7 @@ pub fn _mm_maskz_max_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsw))] pub fn _mm512_max_epi16(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_i16x32(); - let b = b.as_i16x32(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i16x32(), b.as_i16x32()).as_m512i() } } /// Compare packed signed 16-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2040,11 +2028,7 @@ pub fn _mm_maskz_max_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsb))] pub fn _mm512_max_epi8(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_i8x64(); - let b = b.as_i8x64(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i8x64(), b.as_i8x64()).as_m512i() } } /// Compare packed signed 8-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2139,11 +2123,7 @@ pub fn _mm_maskz_max_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuw))] pub fn _mm512_min_epu16(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_u16x32(); - let b = b.as_u16x32(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u16x32(), b.as_u16x32()).as_m512i() } } /// Compare packed unsigned 16-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2238,11 +2218,7 @@ pub fn _mm_maskz_min_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminub))] pub fn _mm512_min_epu8(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_u8x64(); - let b = b.as_u8x64(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u8x64(), b.as_u8x64()).as_m512i() } } /// Compare packed unsigned 8-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2337,11 +2313,7 @@ pub fn _mm_maskz_min_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsw))] pub fn _mm512_min_epi16(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_i16x32(); - let b = b.as_i16x32(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i16x32(), b.as_i16x32()).as_m512i() } } /// Compare packed signed 16-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2436,11 +2408,7 @@ pub fn _mm_maskz_min_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsb))] pub fn _mm512_min_epi8(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_i8x64(); - let b = b.as_i8x64(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i8x64(), b.as_i8x64()).as_m512i() } } /// Compare packed signed 8-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -21172,7 +21140,7 @@ mod tests { let e = _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, - u8::MAX as i8, u8::MAX as i8, u8::MAX as i8, u8::MAX as i8, + u8::MAX as i8, u8::MAX as i8, u8::MAX as i8, u8::MAX as i8, u8::MAX as i8, u8::MAX as i8, u8::MAX as i8, u8::MAX as i8, ); assert_eq_m128i(r, e); diff --git a/library/stdarch/crates/core_arch/src/x86/avx512f.rs b/library/stdarch/crates/core_arch/src/x86/avx512f.rs index f7bf9178dbb9..8c57fc201161 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512f.rs @@ -2091,11 +2091,7 @@ pub fn _mm_maskz_div_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsd))] pub fn _mm512_max_epi32(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_i32x16(); - let b = b.as_i32x16(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i32x16(), b.as_i32x16()).as_m512i() } } /// Compare packed signed 32-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2190,11 +2186,7 @@ pub fn _mm_maskz_max_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] pub fn _mm512_max_epi64(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_i64x8(); - let b = b.as_i64x8(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i64x8(), b.as_i64x8()).as_m512i() } } /// Compare packed signed 64-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2233,11 +2225,7 @@ pub fn _mm512_maskz_max_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] pub fn _mm256_max_epi64(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_i64x4(); - let b = b.as_i64x4(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i64x4(), b.as_i64x4()).as_m256i() } } /// Compare packed signed 64-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2276,11 +2264,7 @@ pub fn _mm256_maskz_max_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] pub fn _mm_max_epi64(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_i64x2(); - let b = b.as_i64x2(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i64x2(), b.as_i64x2()).as_m128i() } } /// Compare packed signed 64-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2515,11 +2499,7 @@ pub fn _mm_maskz_max_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxud))] pub fn _mm512_max_epu32(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_u32x16(); - let b = b.as_u32x16(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u32x16(), b.as_u32x16()).as_m512i() } } /// Compare packed unsigned 32-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2614,11 +2594,7 @@ pub fn _mm_maskz_max_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] pub fn _mm512_max_epu64(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_u64x8(); - let b = b.as_u64x8(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u64x8(), b.as_u64x8()).as_m512i() } } /// Compare packed unsigned 64-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2657,11 +2633,7 @@ pub fn _mm512_maskz_max_epu64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] pub fn _mm256_max_epu64(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_u64x4(); - let b = b.as_u64x4(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u64x4(), b.as_u64x4()).as_m256i() } } /// Compare packed unsigned 64-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2700,11 +2672,7 @@ pub fn _mm256_maskz_max_epu64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] pub fn _mm_max_epu64(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_u64x2(); - let b = b.as_u64x2(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u64x2(), b.as_u64x2()).as_m128i() } } /// Compare packed unsigned 64-bit integers in a and b, and store packed maximum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2743,11 +2711,7 @@ pub fn _mm_maskz_max_epu64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsd))] pub fn _mm512_min_epi32(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_i32x16(); - let b = b.as_i32x16(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i32x16(), b.as_i32x16()).as_m512i() } } /// Compare packed signed 32-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2842,11 +2806,7 @@ pub fn _mm_maskz_min_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] pub fn _mm512_min_epi64(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_i64x8(); - let b = b.as_i64x8(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i64x8(), b.as_i64x8()).as_m512i() } } /// Compare packed signed 64-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2885,11 +2845,7 @@ pub fn _mm512_maskz_min_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] pub fn _mm256_min_epi64(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_i64x4(); - let b = b.as_i64x4(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i64x4(), b.as_i64x4()).as_m256i() } } /// Compare packed signed 64-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -2928,11 +2884,7 @@ pub fn _mm256_maskz_min_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] pub fn _mm_min_epi64(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_i64x2(); - let b = b.as_i64x2(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i64x2(), b.as_i64x2()).as_m128i() } } /// Compare packed signed 64-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -3167,11 +3119,7 @@ pub fn _mm_maskz_min_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminud))] pub fn _mm512_min_epu32(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_u32x16(); - let b = b.as_u32x16(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u32x16(), b.as_u32x16()).as_m512i() } } /// Compare packed unsigned 32-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -3266,11 +3214,7 @@ pub fn _mm_maskz_min_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] pub fn _mm512_min_epu64(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let a = a.as_u64x8(); - let b = b.as_u64x8(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u64x8(), b.as_u64x8()).as_m512i() } } /// Compare packed unsigned 64-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -3309,11 +3253,7 @@ pub fn _mm512_maskz_min_epu64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] pub fn _mm256_min_epu64(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let a = a.as_u64x4(); - let b = b.as_u64x4(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u64x4(), b.as_u64x4()).as_m256i() } } /// Compare packed unsigned 64-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -3352,11 +3292,7 @@ pub fn _mm256_maskz_min_epu64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] pub fn _mm_min_epu64(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_u64x2(); - let b = b.as_u64x2(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u64x2(), b.as_u64x2()).as_m128i() } } /// Compare packed unsigned 64-bit integers in a and b, and store packed minimum values in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index 11335856fb22..93fe7a7ae3f4 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -218,11 +218,7 @@ pub fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pmaxsw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_max_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_i16x8(); - let b = b.as_i16x8(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i16x8(), b.as_i16x8()).as_m128i() } } /// Compares packed unsigned 8-bit integers in `a` and `b`, and returns the @@ -234,11 +230,7 @@ pub fn _mm_max_epi16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pmaxub))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_max_epu8(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_u8x16(); - let b = b.as_u8x16(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u8x16(), b.as_u8x16()).as_m128i() } } /// Compares packed 16-bit integers in `a` and `b`, and returns the packed @@ -250,11 +242,7 @@ pub fn _mm_max_epu8(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pminsw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_min_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_i16x8(); - let b = b.as_i16x8(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i16x8(), b.as_i16x8()).as_m128i() } } /// Compares packed unsigned 8-bit integers in `a` and `b`, and returns the @@ -266,11 +254,7 @@ pub fn _mm_min_epi16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pminub))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_min_epu8(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_u8x16(); - let b = b.as_u8x16(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u8x16(), b.as_u8x16()).as_m128i() } } /// Multiplies the packed 16-bit integers in `a` and `b`. diff --git a/library/stdarch/crates/core_arch/src/x86/sse41.rs b/library/stdarch/crates/core_arch/src/x86/sse41.rs index f457c74aa9c1..6c16ee760065 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse41.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse41.rs @@ -312,11 +312,7 @@ pub fn _mm_insert_epi32(a: __m128i, i: i32) -> __m128i { #[cfg_attr(test, assert_instr(pmaxsb))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_max_epi8(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_i8x16(); - let b = b.as_i8x16(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i8x16(), b.as_i8x16()).as_m128i() } } /// Compares packed unsigned 16-bit integers in `a` and `b`, and returns packed @@ -328,11 +324,7 @@ pub fn _mm_max_epi8(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pmaxuw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_max_epu16(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_u16x8(); - let b = b.as_u16x8(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u16x8(), b.as_u16x8()).as_m128i() } } /// Compares packed 32-bit integers in `a` and `b`, and returns packed maximum @@ -344,11 +336,7 @@ pub fn _mm_max_epu16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pmaxsd))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_max_epi32(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_i32x4(); - let b = b.as_i32x4(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_i32x4(), b.as_i32x4()).as_m128i() } } /// Compares packed unsigned 32-bit integers in `a` and `b`, and returns packed @@ -360,11 +348,7 @@ pub fn _mm_max_epi32(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pmaxud))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_max_epu32(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_u32x4(); - let b = b.as_u32x4(); - transmute(simd_select::(simd_gt(a, b), a, b)) - } + unsafe { simd_imax(a.as_u32x4(), b.as_u32x4()).as_m128i() } } /// Compares packed 8-bit integers in `a` and `b` and returns packed minimum @@ -376,11 +360,7 @@ pub fn _mm_max_epu32(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pminsb))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_min_epi8(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_i8x16(); - let b = b.as_i8x16(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i8x16(), b.as_i8x16()).as_m128i() } } /// Compares packed unsigned 16-bit integers in `a` and `b`, and returns packed @@ -392,11 +372,7 @@ pub fn _mm_min_epi8(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pminuw))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_min_epu16(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_u16x8(); - let b = b.as_u16x8(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u16x8(), b.as_u16x8()).as_m128i() } } /// Compares packed 32-bit integers in `a` and `b`, and returns packed minimum @@ -408,11 +384,7 @@ pub fn _mm_min_epu16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pminsd))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_min_epi32(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_i32x4(); - let b = b.as_i32x4(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_i32x4(), b.as_i32x4()).as_m128i() } } /// Compares packed unsigned 32-bit integers in `a` and `b`, and returns packed @@ -424,11 +396,7 @@ pub fn _mm_min_epi32(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pminud))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_min_epu32(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let a = a.as_u32x4(); - let b = b.as_u32x4(); - transmute(simd_select::(simd_lt(a, b), a, b)) - } + unsafe { simd_imin(a.as_u32x4(), b.as_u32x4()).as_m128i() } } /// Converts packed 32-bit integers from `a` and `b` to packed 16-bit integers From 98a95454b06bf3f263209bebf7bc983cd9741f45 Mon Sep 17 00:00:00 2001 From: sayantn Date: Fri, 28 Nov 2025 03:31:23 +0530 Subject: [PATCH 0149/3801] Use generic SIMD intrinsics for AVX512BW cvtepi --- .../crates/core_arch/src/x86/avx512bw.rs | 83 ++++++++++--------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 4310c3d0ac1b..c7f271d22ef5 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -10735,11 +10735,11 @@ pub fn _mm_maskz_cvtepi16_epi8(k: __mmask8, a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(vpmovswb))] pub fn _mm512_cvtsepi16_epi8(a: __m512i) -> __m256i { unsafe { - transmute(vpmovswb( - a.as_i16x32(), - i8x32::ZERO, - 0b11111111_11111111_11111111_11111111, + simd_cast::<_, i8x32>(simd_imax( + simd_imin(a.as_i16x32(), i16x32::splat(i8::MAX as _)), + i16x32::splat(i8::MIN as _), )) + .as_m256i() } } @@ -10751,7 +10751,9 @@ pub fn _mm512_cvtsepi16_epi8(a: __m512i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] pub fn _mm512_mask_cvtsepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m256i { - unsafe { transmute(vpmovswb(a.as_i16x32(), src.as_i8x32(), k)) } + unsafe { + simd_select_bitmask(k, _mm512_cvtsepi16_epi8(a).as_i8x32(), src.as_i8x32()).as_m256i() + } } /// Convert packed signed 16-bit integers in a to packed 8-bit integers with signed saturation, and store the results in dst using zeromask k (elements are zeroed out when the corresponding mask bit is not set). @@ -10762,7 +10764,7 @@ pub fn _mm512_mask_cvtsepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] pub fn _mm512_maskz_cvtsepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { - unsafe { transmute(vpmovswb(a.as_i16x32(), i8x32::ZERO, k)) } + unsafe { simd_select_bitmask(k, _mm512_cvtsepi16_epi8(a).as_i8x32(), i8x32::ZERO).as_m256i() } } /// Convert packed signed 16-bit integers in a to packed 8-bit integers with signed saturation, and store the results in dst. @@ -10773,7 +10775,13 @@ pub fn _mm512_maskz_cvtsepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] pub fn _mm256_cvtsepi16_epi8(a: __m256i) -> __m128i { - unsafe { transmute(vpmovswb256(a.as_i16x16(), i8x16::ZERO, 0b11111111_11111111)) } + unsafe { + simd_cast::<_, i8x16>(simd_imax( + simd_imin(a.as_i16x16(), i16x16::splat(i8::MAX as _)), + i16x16::splat(i8::MIN as _), + )) + .as_m128i() + } } /// Convert packed signed 16-bit integers in a to packed 8-bit integers with signed saturation, and store the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -10784,7 +10792,9 @@ pub fn _mm256_cvtsepi16_epi8(a: __m256i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] pub fn _mm256_mask_cvtsepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m128i { - unsafe { transmute(vpmovswb256(a.as_i16x16(), src.as_i8x16(), k)) } + unsafe { + simd_select_bitmask(k, _mm256_cvtsepi16_epi8(a).as_i8x16(), src.as_i8x16()).as_m128i() + } } /// Convert packed signed 16-bit integers in a to packed 8-bit integers with signed saturation, and store the results in dst using zeromask k (elements are zeroed out when the corresponding mask bit is not set). @@ -10795,7 +10805,7 @@ pub fn _mm256_mask_cvtsepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] pub fn _mm256_maskz_cvtsepi16_epi8(k: __mmask16, a: __m256i) -> __m128i { - unsafe { transmute(vpmovswb256(a.as_i16x16(), i8x16::ZERO, k)) } + unsafe { simd_select_bitmask(k, _mm256_cvtsepi16_epi8(a).as_i8x16(), i8x16::ZERO).as_m128i() } } /// Convert packed signed 16-bit integers in a to packed 8-bit integers with signed saturation, and store the results in dst. @@ -10840,11 +10850,7 @@ pub fn _mm_maskz_cvtsepi16_epi8(k: __mmask8, a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(vpmovuswb))] pub fn _mm512_cvtusepi16_epi8(a: __m512i) -> __m256i { unsafe { - transmute(vpmovuswb( - a.as_u16x32(), - u8x32::ZERO, - 0b11111111_11111111_11111111_11111111, - )) + simd_cast::<_, u8x32>(simd_imin(a.as_u16x32(), u16x32::splat(u8::MAX as _))).as_m256i() } } @@ -10856,7 +10862,9 @@ pub fn _mm512_cvtusepi16_epi8(a: __m512i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] pub fn _mm512_mask_cvtusepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m256i { - unsafe { transmute(vpmovuswb(a.as_u16x32(), src.as_u8x32(), k)) } + unsafe { + simd_select_bitmask(k, _mm512_cvtusepi16_epi8(a).as_u8x32(), src.as_u8x32()).as_m256i() + } } /// Convert packed unsigned 16-bit integers in a to packed unsigned 8-bit integers with unsigned saturation, and store the results in dst using zeromask k (elements are zeroed out when the corresponding mask bit is not set). @@ -10867,7 +10875,7 @@ pub fn _mm512_mask_cvtusepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] pub fn _mm512_maskz_cvtusepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { - unsafe { transmute(vpmovuswb(a.as_u16x32(), u8x32::ZERO, k)) } + unsafe { simd_select_bitmask(k, _mm512_cvtusepi16_epi8(a).as_u8x32(), u8x32::ZERO).as_m256i() } } /// Convert packed unsigned 16-bit integers in a to packed unsigned 8-bit integers with unsigned saturation, and store the results in dst. @@ -10879,11 +10887,7 @@ pub fn _mm512_maskz_cvtusepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { #[cfg_attr(test, assert_instr(vpmovuswb))] pub fn _mm256_cvtusepi16_epi8(a: __m256i) -> __m128i { unsafe { - transmute(vpmovuswb256( - a.as_u16x16(), - u8x16::ZERO, - 0b11111111_11111111, - )) + simd_cast::<_, u8x16>(simd_imin(a.as_u16x16(), u16x16::splat(u8::MAX as _))).as_m128i() } } @@ -10895,7 +10899,9 @@ pub fn _mm256_cvtusepi16_epi8(a: __m256i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] pub fn _mm256_mask_cvtusepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m128i { - unsafe { transmute(vpmovuswb256(a.as_u16x16(), src.as_u8x16(), k)) } + unsafe { + simd_select_bitmask(k, _mm256_cvtusepi16_epi8(a).as_u8x16(), src.as_u8x16()).as_m128i() + } } /// Convert packed unsigned 16-bit integers in a to packed unsigned 8-bit integers with unsigned saturation, and store the results in dst using zeromask k (elements are zeroed out when the corresponding mask bit is not set). @@ -10906,7 +10912,7 @@ pub fn _mm256_mask_cvtusepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] pub fn _mm256_maskz_cvtusepi16_epi8(k: __mmask16, a: __m256i) -> __m128i { - unsafe { transmute(vpmovuswb256(a.as_u16x16(), u8x16::ZERO, k)) } + unsafe { simd_select_bitmask(k, _mm256_cvtusepi16_epi8(a).as_u8x16(), u8x16::ZERO).as_m128i() } } /// Convert packed unsigned 16-bit integers in a to packed unsigned 8-bit integers with unsigned saturation, and store the results in dst. @@ -11592,7 +11598,9 @@ pub unsafe fn _mm_mask_cvtsepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask8, a: #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] pub unsafe fn _mm512_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask32, a: __m512i) { - vpmovwbmem(mem_addr, a.as_i16x32(), k); + let result = _mm512_cvtepi16_epi8(a).as_i8x32(); + let mask = simd_select_bitmask(k, i8x32::splat(!0), i8x32::ZERO); + simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, result); } /// Convert packed 16-bit integers in a to packed 8-bit integers with truncation, and store the active results (those with their respective bit set in writemask k) to unaligned memory at base_addr. @@ -11603,7 +11611,9 @@ pub unsafe fn _mm512_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask32, #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] pub unsafe fn _mm256_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask16, a: __m256i) { - vpmovwbmem256(mem_addr, a.as_i16x16(), k); + let result = _mm256_cvtepi16_epi8(a).as_i8x16(); + let mask = simd_select_bitmask(k, i8x16::splat(!0), i8x16::ZERO); + simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, result); } /// Convert packed 16-bit integers in a to packed 8-bit integers with truncation, and store the active results (those with their respective bit set in writemask k) to unaligned memory at base_addr. @@ -11614,7 +11624,13 @@ pub unsafe fn _mm256_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask16, #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] pub unsafe fn _mm_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask8, a: __m128i) { - vpmovwbmem128(mem_addr, a.as_i16x8(), k); + let result: i8x8 = simd_shuffle!( + _mm_cvtepi16_epi8(a).as_i8x16(), + i8x16::ZERO, + [0, 1, 2, 3, 4, 5, 6, 7] + ); + let mask = simd_select_bitmask(k, i8x8::splat(!0), i8x8::ZERO); + simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, result); } /// Convert packed unsigned 16-bit integers in a to packed unsigned 8-bit integers with unsigned saturation, and store the active results (those with their respective bit set in writemask k) to unaligned memory at base_addr. @@ -11703,17 +11719,9 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.dbpsadbw.128"] fn vdbpsadbw128(a: u8x16, b: u8x16, imm8: i32) -> u16x8; - #[link_name = "llvm.x86.avx512.mask.pmovs.wb.512"] - fn vpmovswb(a: i16x32, src: i8x32, mask: u32) -> i8x32; - #[link_name = "llvm.x86.avx512.mask.pmovs.wb.256"] - fn vpmovswb256(a: i16x16, src: i8x16, mask: u16) -> i8x16; #[link_name = "llvm.x86.avx512.mask.pmovs.wb.128"] fn vpmovswb128(a: i16x8, src: i8x16, mask: u8) -> i8x16; - #[link_name = "llvm.x86.avx512.mask.pmovus.wb.512"] - fn vpmovuswb(a: u16x32, src: u8x32, mask: u32) -> u8x32; - #[link_name = "llvm.x86.avx512.mask.pmovus.wb.256"] - fn vpmovuswb256(a: u16x16, src: u8x16, mask: u16) -> u8x16; #[link_name = "llvm.x86.avx512.mask.pmovus.wb.128"] fn vpmovuswb128(a: u16x8, src: u8x16, mask: u8) -> u8x16; @@ -11724,13 +11732,6 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.mask.pmovs.wb.mem.128"] fn vpmovswbmem128(mem_addr: *mut i8, a: i16x8, mask: u8); - #[link_name = "llvm.x86.avx512.mask.pmov.wb.mem.512"] - fn vpmovwbmem(mem_addr: *mut i8, a: i16x32, mask: u32); - #[link_name = "llvm.x86.avx512.mask.pmov.wb.mem.256"] - fn vpmovwbmem256(mem_addr: *mut i8, a: i16x16, mask: u16); - #[link_name = "llvm.x86.avx512.mask.pmov.wb.mem.128"] - fn vpmovwbmem128(mem_addr: *mut i8, a: i16x8, mask: u8); - #[link_name = "llvm.x86.avx512.mask.pmovus.wb.mem.512"] fn vpmovuswbmem(mem_addr: *mut i8, a: i16x32, mask: u32); #[link_name = "llvm.x86.avx512.mask.pmovus.wb.mem.256"] From 845da883816d60b6a3c8b161ecf5d3c306867afa Mon Sep 17 00:00:00 2001 From: Aatif Syed Date: Fri, 28 Nov 2025 00:52:38 +0000 Subject: [PATCH 0150/3801] refactor: remove Ord bound from BinaryHeap::new etc --- library/alloc/src/collections/binary_heap/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 63828b482b9a..a221c66d31d5 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -466,7 +466,7 @@ impl Clone for BinaryHeap { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for BinaryHeap { +impl Default for BinaryHeap { /// Creates an empty `BinaryHeap`. #[inline] fn default() -> BinaryHeap { @@ -496,7 +496,7 @@ impl Drop for RebuildOnDrop<'_, T, A> { } } -impl BinaryHeap { +impl BinaryHeap { /// Creates an empty `BinaryHeap` as a max-heap. /// /// # Examples @@ -537,7 +537,7 @@ impl BinaryHeap { } } -impl BinaryHeap { +impl BinaryHeap { /// Creates an empty `BinaryHeap` as a max-heap, using `A` as allocator. /// /// # Examples @@ -615,7 +615,9 @@ impl BinaryHeap { pub fn peek_mut(&mut self) -> Option> { if self.is_empty() { None } else { Some(PeekMut { heap: self, original_len: None }) } } +} +impl BinaryHeap { /// Removes the greatest item from the binary heap and returns it, or `None` if it /// is empty. /// From fcf24266b4feb4f788ad1d51d8f056cce039cf00 Mon Sep 17 00:00:00 2001 From: Aatif Syed Date: Fri, 28 Nov 2025 01:19:07 +0000 Subject: [PATCH 0151/3801] fix: BinaryHeap::peek_mut --- library/alloc/src/collections/binary_heap/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index a221c66d31d5..5710b2a3a91d 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -581,7 +581,9 @@ impl BinaryHeap { pub fn with_capacity_in(capacity: usize, alloc: A) -> BinaryHeap { BinaryHeap { data: Vec::with_capacity_in(capacity, alloc) } } +} +impl BinaryHeap { /// Returns a mutable reference to the greatest item in the binary heap, or /// `None` if it is empty. /// @@ -615,9 +617,7 @@ impl BinaryHeap { pub fn peek_mut(&mut self) -> Option> { if self.is_empty() { None } else { Some(PeekMut { heap: self, original_len: None }) } } -} -impl BinaryHeap { /// Removes the greatest item from the binary heap and returns it, or `None` if it /// is empty. /// From 16a47d97267748f98fbc084afcff67a6ff962530 Mon Sep 17 00:00:00 2001 From: Mattias Petersson <61464624+Mattias-Petersson@users.noreply.github.com> Date: Fri, 28 Nov 2025 07:44:24 +0100 Subject: [PATCH 0152/3801] Update src/building/how-to-build-and-run.md Co-authored-by: Tshepang Mbambo --- .../rustc-dev-guide/src/building/how-to-build-and-run.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index b15d77111e19..d0a38b12c550 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -277,9 +277,9 @@ default). Once you have successfully built `rustc`, you will have created a bunch of files in your `build` directory. In order to actually run the resulting `rustc`, we recommend creating rustup toolchains. The first -command listed below runs the stage1 compiler, which was built in the -steps above, with the name `stage1`. The second command runs the stage2 -compiler using the stage1 compiler. This will be needed in the future +command listed below creates the stage1 toolchain, which was built in the +steps above, with the name `stage1`. The second command creates the stage2 +toolchain using the stage1 compiler. This will be needed in the future if running the entire test suite, but will not be built in this page. Building stage2 is done with the same `./x build` command as for stage1, specifying that the stage is 2 instead. From e6ad406d48956b2b3f159d116af2d05cda5da79a Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Sat, 11 Oct 2025 13:13:48 +0200 Subject: [PATCH 0153/3801] feat(manual_ilog2): new lint --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + clippy_lints/src/manual_ilog2.rs | 115 +++++++++++++++++++++++++++++ clippy_utils/src/msrvs.rs | 1 + clippy_utils/src/sym.rs | 2 + tests/ui/manual_ilog2.fixed | 32 ++++++++ tests/ui/manual_ilog2.rs | 32 ++++++++ tests/ui/manual_ilog2.stderr | 23 ++++++ 9 files changed, 209 insertions(+) create mode 100644 clippy_lints/src/manual_ilog2.rs create mode 100644 tests/ui/manual_ilog2.fixed create mode 100644 tests/ui/manual_ilog2.rs create mode 100644 tests/ui/manual_ilog2.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 78b81b5b74d6..76de222960e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6541,6 +6541,7 @@ Released 2018-09-13 [`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten [`manual_hash_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one [`manual_ignore_case_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ignore_case_cmp +[`manual_ilog2`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ilog2 [`manual_inspect`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_inspect [`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed [`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 4a350dca2993..edaea69d01a5 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -300,6 +300,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::manual_float_methods::MANUAL_IS_INFINITE_INFO, crate::manual_hash_one::MANUAL_HASH_ONE_INFO, crate::manual_ignore_case_cmp::MANUAL_IGNORE_CASE_CMP_INFO, + crate::manual_ilog2::MANUAL_ILOG2_INFO, crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO, crate::manual_is_power_of_two::MANUAL_IS_POWER_OF_TWO_INFO, crate::manual_let_else::MANUAL_LET_ELSE_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 230d83dacc95..cad36b7f197a 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -201,6 +201,7 @@ mod manual_clamp; mod manual_float_methods; mod manual_hash_one; mod manual_ignore_case_cmp; +mod manual_ilog2; mod manual_is_ascii_check; mod manual_is_power_of_two; mod manual_let_else; @@ -848,6 +849,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(|_| Box::new(toplevel_ref_arg::ToplevelRefArg)), Box::new(|_| Box::new(volatile_composites::VolatileComposites)), Box::new(|_| Box::::default()), + Box::new(move |_| Box::new(manual_ilog2::ManualIlog2::new(conf))), // add late passes here, used by `cargo dev new_lint` ]; store.late_passes.extend(late_lints); diff --git a/clippy_lints/src/manual_ilog2.rs b/clippy_lints/src/manual_ilog2.rs new file mode 100644 index 000000000000..1c61db530606 --- /dev/null +++ b/clippy_lints/src/manual_ilog2.rs @@ -0,0 +1,115 @@ +use clippy_config::Conf; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::{is_from_proc_macro, sym}; +use rustc_ast::LitKind; +use rustc_data_structures::packed::Pu128; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::ty; +use rustc_session::impl_lint_pass; + +declare_clippy_lint! { + /// ### What it does + /// Checks for expressions like `N - x.leading_zeros()` (where `N` is one less than bit width + /// of `x`) or `x.ilog(2)`, which are manual reimplementations of `x.ilog2()` + /// + /// ### Why is this bad? + /// Manual reimplementations of `ilog2` increase code complexity for little benefit. + /// + /// ### Example + /// ```no_run + /// let x: u32 = 5; + /// let log = 31 - x.leading_zeros(); + /// let log = x.ilog(2); + /// ``` + /// Use instead: + /// ```no_run + /// let x: u32 = 5; + /// let log = x.ilog2(); + /// let log = x.ilog2(); + /// ``` + #[clippy::version = "1.93.0"] + pub MANUAL_ILOG2, + pedantic, + "manually reimplementing `ilog2`" +} + +pub struct ManualIlog2 { + msrv: Msrv, +} + +impl ManualIlog2 { + pub fn new(conf: &Conf) -> Self { + Self { msrv: conf.msrv } + } +} + +impl_lint_pass!(ManualIlog2 => [MANUAL_ILOG2]); + +impl LateLintPass<'_> for ManualIlog2 { + fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + if expr.span.in_external_macro(cx.sess().source_map()) { + return; + } + + match expr.kind { + // `BIT_WIDTH - 1 - n.leading_zeros()` + ExprKind::Binary(op, left, right) + if left.span.eq_ctxt(right.span) + && op.node == BinOpKind::Sub + && let ExprKind::Lit(lit) = left.kind + && let LitKind::Int(Pu128(val), _) = lit.node + && let ExprKind::MethodCall(leading_zeros, recv, [], _) = right.kind + && leading_zeros.ident.name == sym::leading_zeros + && let ty = cx.typeck_results().expr_ty(recv) + && let Some(bit_width) = match ty.kind() { + ty::Uint(uint_ty) => uint_ty.bit_width(), + ty::Int(_) => { + // On non-positive integers, `ilog2` would panic, which might be a sign that the author does + // in fact want to calculate something different, so stay on the safer side and don't + // suggest anything. + return; + }, + _ => return, + } + && val == u128::from(bit_width) - 1 + && self.msrv.meets(cx, msrvs::ILOG2) + && !is_from_proc_macro(cx, expr) => + { + emit(cx, recv, expr); + }, + + // `n.ilog(2)` + ExprKind::MethodCall(ilog, recv, [two], _) + if expr.span.eq_ctxt(two.span) + && ilog.ident.name == sym::ilog + && let ExprKind::Lit(lit) = two.kind + && let LitKind::Int(Pu128(2), _) = lit.node + && cx.typeck_results().expr_ty_adjusted(recv).is_integral() + /* no need to check MSRV here, as `ilog` and `ilog2` were introduced simultaneously */ + && !is_from_proc_macro(cx, expr) => + { + emit(cx, recv, expr); + }, + + _ => {}, + } + } +} + +fn emit(cx: &LateContext<'_>, recv: &Expr<'_>, full_expr: &Expr<'_>) { + let mut app = Applicability::MachineApplicable; + let recv = snippet_with_applicability(cx, recv.span, "_", &mut app); + span_lint_and_sugg( + cx, + MANUAL_ILOG2, + full_expr.span, + "manually reimplementing `ilog2`", + "try", + format!("{recv}.ilog2()"), + app, + ); +} diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 86d17a8231d5..4a7fa3472cae 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -40,6 +40,7 @@ msrv_aliases! { 1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE } 1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN } 1,68,0 { PATH_MAIN_SEPARATOR_STR } + 1,67,0 { ILOG2 } 1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS } 1,63,0 { CLONE_INTO, CONST_SLICE_FROM_REF } 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_C_FN } diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 1d1537dd0e91..00f4a9c7e586 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -180,6 +180,7 @@ generate! { has_significant_drop, hidden_glob_reexports, hygiene, + ilog, insert, insert_str, inspect, @@ -207,6 +208,7 @@ generate! { join, kw, lazy_static, + leading_zeros, lint_vec, ln, lock, diff --git a/tests/ui/manual_ilog2.fixed b/tests/ui/manual_ilog2.fixed new file mode 100644 index 000000000000..a0f6d9392c30 --- /dev/null +++ b/tests/ui/manual_ilog2.fixed @@ -0,0 +1,32 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::manual_ilog2)] +#![allow(clippy::unnecessary_operation)] + +use proc_macros::{external, with_span}; + +fn foo(a: u32, b: u64) { + a.ilog2(); //~ manual_ilog2 + a.ilog2(); //~ manual_ilog2 + + b.ilog2(); //~ manual_ilog2 + 64 - b.leading_zeros(); // No lint because manual ilog2 is `BIT_WIDTH - 1 - x.leading_zeros()` + + // don't lint when macros are involved + macro_rules! two { + () => { + 2 + }; + }; + + macro_rules! thirty_one { + () => { + 31 + }; + }; + + a.ilog(two!()); + thirty_one!() - a.leading_zeros(); + + external!($a.ilog(2)); + with_span!(span; a.ilog(2)); +} diff --git a/tests/ui/manual_ilog2.rs b/tests/ui/manual_ilog2.rs new file mode 100644 index 000000000000..bd4b5d9d3c0d --- /dev/null +++ b/tests/ui/manual_ilog2.rs @@ -0,0 +1,32 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::manual_ilog2)] +#![allow(clippy::unnecessary_operation)] + +use proc_macros::{external, with_span}; + +fn foo(a: u32, b: u64) { + 31 - a.leading_zeros(); //~ manual_ilog2 + a.ilog(2); //~ manual_ilog2 + + 63 - b.leading_zeros(); //~ manual_ilog2 + 64 - b.leading_zeros(); // No lint because manual ilog2 is `BIT_WIDTH - 1 - x.leading_zeros()` + + // don't lint when macros are involved + macro_rules! two { + () => { + 2 + }; + }; + + macro_rules! thirty_one { + () => { + 31 + }; + }; + + a.ilog(two!()); + thirty_one!() - a.leading_zeros(); + + external!($a.ilog(2)); + with_span!(span; a.ilog(2)); +} diff --git a/tests/ui/manual_ilog2.stderr b/tests/ui/manual_ilog2.stderr new file mode 100644 index 000000000000..7c9694f35330 --- /dev/null +++ b/tests/ui/manual_ilog2.stderr @@ -0,0 +1,23 @@ +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:8:5 + | +LL | 31 - a.leading_zeros(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.ilog2()` + | + = note: `-D clippy::manual-ilog2` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_ilog2)]` + +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:9:5 + | +LL | a.ilog(2); + | ^^^^^^^^^ help: try: `a.ilog2()` + +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:11:5 + | +LL | 63 - b.leading_zeros(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `b.ilog2()` + +error: aborting due to 3 previous errors + From 7cd6922f6be880c4ee330bfa0d7fd6d9a93149f1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 28 Nov 2025 10:51:35 +0000 Subject: [PATCH 0154/3801] Rustup to rustc 1.93.0-nightly (c86564c41 2025-11-27) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 5eba4411d78b..4bbbc12cdd0b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-11-19" +channel = "nightly-2025-11-28" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 110649f0a8dfb21e65ee8114c05eacf5260307b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Nov 2025 13:09:08 +0100 Subject: [PATCH 0155/3801] Fix display of dropdown menu "buttons" --- util/gh-pages/style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/gh-pages/style.css b/util/gh-pages/style.css index 242e2227ed94..ce478a3e18d0 100644 --- a/util/gh-pages/style.css +++ b/util/gh-pages/style.css @@ -637,14 +637,14 @@ pre, hr { display: flex; } -ul.dropdown-menu li.checkbox > button { +#menu-filters ul.dropdown-menu li.checkbox > button { border: 0; width: 100%; background: var(--theme-popup-bg); color: var(--fg); } -ul.dropdown-menu li.checkbox > button:hover { +#menu-filters ul.dropdown-menu li.checkbox > button:hover { background: var(--theme-hover); box-shadow: none; } From e163707c70dd5490b13b68f1ed111bdea2785f98 Mon Sep 17 00:00:00 2001 From: nxsaken Date: Sun, 9 Nov 2025 21:07:54 +0400 Subject: [PATCH 0156/3801] Constify `DropGuard` methods --- library/core/src/mem/drop_guard.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/library/core/src/mem/drop_guard.rs b/library/core/src/mem/drop_guard.rs index 1301dedf1241..013134727b7f 100644 --- a/library/core/src/mem/drop_guard.rs +++ b/library/core/src/mem/drop_guard.rs @@ -1,4 +1,5 @@ use crate::fmt::{self, Debug}; +use crate::marker::Destruct; use crate::mem::ManuallyDrop; use crate::ops::{Deref, DerefMut}; @@ -81,8 +82,12 @@ where /// assert_eq!(guard.dismiss(), "Nori likes chicken"); /// ``` #[unstable(feature = "drop_guard", issue = "144426")] + #[rustc_const_unstable(feature = "const_drop_guard", issue = "none")] #[inline] - pub fn dismiss(self) -> T { + pub const fn dismiss(self) -> T + where + F: [const] Destruct, + { // First we ensure that dropping the guard will not trigger // its destructor let mut this = ManuallyDrop::new(self); @@ -103,7 +108,8 @@ where } #[unstable(feature = "drop_guard", issue = "144426")] -impl Deref for DropGuard +#[rustc_const_unstable(feature = "const_convert", issue = "143773")] +impl const Deref for DropGuard where F: FnOnce(T), { @@ -115,7 +121,8 @@ where } #[unstable(feature = "drop_guard", issue = "144426")] -impl DerefMut for DropGuard +#[rustc_const_unstable(feature = "const_convert", issue = "143773")] +impl const DerefMut for DropGuard where F: FnOnce(T), { @@ -125,9 +132,10 @@ where } #[unstable(feature = "drop_guard", issue = "144426")] -impl Drop for DropGuard +#[rustc_const_unstable(feature = "const_drop_guard", issue = "none")] +impl const Drop for DropGuard where - F: FnOnce(T), + F: [const] FnOnce(T), { fn drop(&mut self) { // SAFETY: `DropGuard` is in the process of being dropped. From bd211952823c79c382bf0f6a8ace3fddee860c1e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 22 Nov 2025 13:29:55 -0800 Subject: [PATCH 0157/3801] Update to mdbook 0.5 Changelog: https://github.com/rust-lang/mdBook/blob/master/CHANGELOG.md#mdbook-051 --- src/doc/rustc-dev-guide/.github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index 76e1d0a8f7cf..fe92bc876cf7 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -14,9 +14,9 @@ jobs: if: github.repository == 'rust-lang/rustc-dev-guide' runs-on: ubuntu-latest env: - MDBOOK_VERSION: 0.4.52 - MDBOOK_LINKCHECK2_VERSION: 0.9.1 - MDBOOK_MERMAID_VERSION: 0.12.6 + MDBOOK_VERSION: 0.5.1 + MDBOOK_LINKCHECK2_VERSION: 0.11.0 + MDBOOK_MERMAID_VERSION: 0.17.0 MDBOOK_OUTPUT__LINKCHECK__FOLLOW_WEB_LINKS: ${{ github.event_name != 'pull_request' }} DEPLOY_DIR: book/html BASE_SHA: ${{ github.event.pull_request.base.sha }} From 099308af902a1d2bc6104192c276b7e946eb5aae Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 28 Nov 2025 20:25:22 +0100 Subject: [PATCH 0158/3801] Merge commit '92b4b68683249c781c3acad742fc6e57c4140ad9' into clippy-subtree-update --- .github/workflows/clippy_mq.yml | 10 +- .github/workflows/deploy.yml | 4 +- .github/workflows/lintcheck.yml | 6 +- .github/workflows/remark.yml | 7 +- CHANGELOG.md | 2 + .../continuous_integration/github_actions.md | 2 +- book/src/lint_configuration.md | 11 + clippy_config/src/conf.rs | 4 + clippy_lints/src/byte_char_slices.rs | 51 +- clippy_lints/src/declared_lints.rs | 3 +- clippy_lints/src/dereference.rs | 460 ++++--- .../doc/doc_paragraphs_missing_punctuation.rs | 126 ++ clippy_lints/src/doc/mod.rs | 38 + clippy_lints/src/equatable_if_let.rs | 80 +- clippy_lints/src/functions/mod.rs | 30 +- clippy_lints/src/functions/result.rs | 30 +- clippy_lints/src/implicit_hasher.rs | 40 +- clippy_lints/src/lib.rs | 4 +- .../src/methods/sliced_string_as_bytes.rs | 10 +- clippy_lints/src/methods/useless_asref.rs | 28 +- clippy_lints/src/missing_doc.rs | 443 ++++--- .../src/multiple_unsafe_ops_per_block.rs | 115 +- clippy_lints/src/ptr/ptr_arg.rs | 6 +- clippy_lints/src/time_subtraction.rs | 68 +- .../src/transmute/transmute_ptr_to_ptr.rs | 66 +- .../src/transmute/transmute_ref_to_ref.rs | 42 +- clippy_lints/src/unwrap.rs | 229 +++- clippy_lints/src/{vec.rs => useless_vec.rs} | 35 +- clippy_utils/README.md | 2 +- clippy_utils/src/ast_utils/mod.rs | 4 +- clippy_utils/src/check_proc_macro.rs | 9 +- clippy_utils/src/lib.rs | 3 + clippy_utils/src/sugg.rs | 11 +- rust-toolchain.toml | 2 +- src/driver.rs | 7 +- .../missing_docs_allow_unused.rs | 26 - .../missing_docs_allow_unused.stderr | 38 - .../allow_unused}/clippy.toml | 0 .../crate_root}/clippy.toml | 0 .../default/clippy.toml | 0 ..._docs_in_private_items.allow_unused.stderr | 644 +++++++++ ...ng_docs_in_private_items.crate_root.stderr | 500 +++++++ ...ssing_docs_in_private_items.default.stderr | 704 ++++++++++ .../missing_docs_in_private_items.rs | 1167 +++++++++++++++++ .../pub_crate_missing_doc.rs | 67 - .../pub_crate_missing_doc.stderr | 53 - tests/ui-toml/result_large_err/clippy.toml | 1 + .../result_large_err/result_large_err.rs | 20 + .../result_large_err/result_large_err.stderr | 2 +- .../toml_unknown_key/conf_unknown_key.stderr | 3 + tests/ui/blanket_clippy_restriction_lints.rs | 2 +- tests/ui/byte_char_slices.fixed | 1 - tests/ui/byte_char_slices.rs | 1 - tests/ui/byte_char_slices.stderr | 10 +- tests/ui/cast.rs | 10 + tests/ui/cast.stderr | 8 +- .../ui/checked_unwrap/complex_conditionals.rs | 28 +- .../complex_conditionals.stderr | 56 +- .../complex_conditionals_nested.rs | 11 +- .../complex_conditionals_nested.stderr | 19 +- tests/ui/checked_unwrap/if_let_chains.rs | 2 +- tests/ui/checked_unwrap/if_let_chains.stderr | 7 +- .../ui/checked_unwrap/simple_conditionals.rs | 225 +++- .../checked_unwrap/simple_conditionals.stderr | 390 ++++-- .../doc_paragraphs_missing_punctuation.fixed | 172 +++ .../doc/doc_paragraphs_missing_punctuation.rs | 172 +++ .../doc_paragraphs_missing_punctuation.stderr | 113 ++ ...aragraphs_missing_punctuation_unfixable.rs | 13 + ...raphs_missing_punctuation_unfixable.stderr | 20 + tests/ui/equatable_if_let.fixed | 107 +- tests/ui/equatable_if_let.rs | 107 +- tests/ui/equatable_if_let.stderr | 52 +- tests/ui/equatable_if_let_const_cmp.fixed | 24 + tests/ui/equatable_if_let_const_cmp.rs | 24 + tests/ui/equatable_if_let_const_cmp.stderr | 17 + tests/ui/explicit_deref_methods.fixed | 113 ++ tests/ui/explicit_deref_methods.rs | 113 ++ tests/ui/implicit_hasher.fixed | 24 + tests/ui/implicit_hasher.rs | 24 + tests/ui/implicit_hasher.stderr | 30 +- tests/ui/missing_doc.rs | 148 --- tests/ui/missing_doc.stderr | 102 -- tests/ui/missing_doc_crate.rs | 7 - tests/ui/missing_doc_crate_missing.rs | 4 - tests/ui/missing_doc_crate_missing.stderr | 13 - tests/ui/missing_doc_impl.rs | 114 -- tests/ui/missing_doc_impl.stderr | 57 - tests/ui/multiple_unsafe_ops_per_block.rs | 103 ++ tests/ui/multiple_unsafe_ops_per_block.stderr | 148 ++- .../redundant_pattern_matching_option.fixed | 29 + tests/ui/redundant_pattern_matching_option.rs | 29 + .../redundant_pattern_matching_option.stderr | 14 +- tests/ui/sliced_string_as_bytes.fixed | 6 + tests/ui/sliced_string_as_bytes.rs | 6 + tests/ui/transmute.rs | 13 + tests/ui/transmute.stderr | 8 +- tests/ui/transmute_ref_to_ref.rs | 20 + tests/ui/transmute_ref_to_ref.stderr | 20 +- tests/ui/unchecked_time_subtraction.stderr | 16 +- ...nchecked_time_subtraction_unfixable.stderr | 8 +- tests/ui/useless_asref.fixed | 35 + tests/ui/useless_asref.rs | 35 + tests/ui/useless_asref.stderr | 32 +- tests/ui/{vec.fixed => useless_vec.fixed} | 38 +- tests/ui/useless_vec.rs | 258 +++- tests/ui/useless_vec.stderr | 132 +- tests/ui/useless_vec_unfixable.rs | 14 + tests/ui/useless_vec_unfixable.stderr | 21 + tests/ui/vec.rs | 253 ---- tests/ui/vec.stderr | 137 -- triagebot.toml | 3 +- util/gh-pages/index_template.html | 216 ++- util/gh-pages/style.css | 79 +- 113 files changed, 6904 insertions(+), 2322 deletions(-) create mode 100644 clippy_lints/src/doc/doc_paragraphs_missing_punctuation.rs rename clippy_lints/src/{vec.rs => useless_vec.rs} (90%) delete mode 100644 tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs delete mode 100644 tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.stderr rename tests/ui-toml/{missing_docs_allow_unused => missing_docs_in_private_items/allow_unused}/clippy.toml (100%) rename tests/ui-toml/{pub_crate_missing_docs => missing_docs_in_private_items/crate_root}/clippy.toml (100%) create mode 100644 tests/ui-toml/missing_docs_in_private_items/default/clippy.toml create mode 100644 tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.allow_unused.stderr create mode 100644 tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.crate_root.stderr create mode 100644 tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.default.stderr create mode 100644 tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs delete mode 100644 tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs delete mode 100644 tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr create mode 100644 tests/ui/doc/doc_paragraphs_missing_punctuation.fixed create mode 100644 tests/ui/doc/doc_paragraphs_missing_punctuation.rs create mode 100644 tests/ui/doc/doc_paragraphs_missing_punctuation.stderr create mode 100644 tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.rs create mode 100644 tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.stderr create mode 100644 tests/ui/equatable_if_let_const_cmp.fixed create mode 100644 tests/ui/equatable_if_let_const_cmp.rs create mode 100644 tests/ui/equatable_if_let_const_cmp.stderr delete mode 100644 tests/ui/missing_doc.rs delete mode 100644 tests/ui/missing_doc.stderr delete mode 100644 tests/ui/missing_doc_crate.rs delete mode 100644 tests/ui/missing_doc_crate_missing.rs delete mode 100644 tests/ui/missing_doc_crate_missing.stderr delete mode 100644 tests/ui/missing_doc_impl.rs delete mode 100644 tests/ui/missing_doc_impl.stderr rename tests/ui/{vec.fixed => useless_vec.fixed} (90%) create mode 100644 tests/ui/useless_vec_unfixable.rs create mode 100644 tests/ui/useless_vec_unfixable.stderr delete mode 100644 tests/ui/vec.rs delete mode 100644 tests/ui/vec.stderr diff --git a/.github/workflows/clippy_mq.yml b/.github/workflows/clippy_mq.yml index ce15a861bb07..c49241bdff1b 100644 --- a/.github/workflows/clippy_mq.yml +++ b/.github/workflows/clippy_mq.yml @@ -34,7 +34,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false @@ -94,7 +94,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false @@ -112,7 +112,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false @@ -168,7 +168,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false @@ -179,7 +179,7 @@ jobs: # Download - name: Download target dir - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: name: binaries path: target/debug diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 48c5bd36dbcd..872931160c35 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -25,13 +25,13 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: # Unsetting this would make so that any malicious package could get our Github Token persist-credentials: false - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: ref: ${{ env.TARGET_BRANCH }} path: 'out' diff --git a/.github/workflows/lintcheck.yml b/.github/workflows/lintcheck.yml index 45fd10ae7614..9ce0b7f5fc46 100644 --- a/.github/workflows/lintcheck.yml +++ b/.github/workflows/lintcheck.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: fetch-depth: 2 # Unsetting this would make so that any malicious package could get our Github Token @@ -80,7 +80,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: # Unsetting this would make so that any malicious package could get our Github Token persist-credentials: false @@ -113,7 +113,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: # Unsetting this would make so that any malicious package could get our Github Token persist-credentials: false diff --git a/.github/workflows/remark.yml b/.github/workflows/remark.yml index c2cc48ab9511..03641a9aa62f 100644 --- a/.github/workflows/remark.yml +++ b/.github/workflows/remark.yml @@ -4,6 +4,9 @@ on: merge_group: pull_request: +env: + MDBOOK_VERSION: 0.5.1 + jobs: remark: runs-on: ubuntu-latest @@ -11,7 +14,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: # Unsetting this would make so that any malicious package could get our Github Token persist-credentials: false @@ -27,7 +30,7 @@ jobs: - name: Install mdbook run: | mkdir mdbook - curl -Lf https://github.com/rust-lang/mdBook/releases/download/v0.4.43/mdbook-v0.4.43-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook + curl -Lf https://github.com/rust-lang/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook echo `pwd`/mdbook >> $GITHUB_PATH # Run diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cb2755be0ee..78b81b5b74d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6314,6 +6314,7 @@ Released 2018-09-13 [`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown [`doc_nested_refdefs`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_nested_refdefs [`doc_overindented_list_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_overindented_list_items +[`doc_paragraphs_missing_punctuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_paragraphs_missing_punctuation [`doc_suspicious_footnotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_suspicious_footnotes [`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons [`double_ended_iterator_last`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_ended_iterator_last @@ -7121,6 +7122,7 @@ Released 2018-09-13 [`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold [`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability [`inherent-impl-lint-scope`]: https://doc.rust-lang.org/clippy/lint_configuration.html#inherent-impl-lint-scope +[`large-error-ignored`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-ignored [`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold [`lint-commented-code`]: https://doc.rust-lang.org/clippy/lint_configuration.html#lint-commented-code [`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold diff --git a/book/src/continuous_integration/github_actions.md b/book/src/continuous_integration/github_actions.md index 62d32446d920..bed0f66bab33 100644 --- a/book/src/continuous_integration/github_actions.md +++ b/book/src/continuous_integration/github_actions.md @@ -15,7 +15,7 @@ jobs: clippy_check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Run Clippy run: cargo clippy --all-targets --all-features ``` diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 6569bdabf115..2e185fb3a086 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -681,6 +681,17 @@ Sets the scope ("crate", "file", or "module") in which duplicate inherent `impl` * [`multiple_inherent_impl`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl) +## `large-error-ignored` +A list of paths to types that should be ignored as overly large `Err`-variants in a +`Result` returned from a function + +**Default Value:** `[]` + +--- +**Affected lints:** +* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err) + + ## `large-error-threshold` The maximum size of the `Err`-variant in a `Result` returned from a function diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 8cdd99ac44a8..2e9cf8e91f7d 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -666,6 +666,10 @@ define_Conf! { /// Sets the scope ("crate", "file", or "module") in which duplicate inherent `impl` blocks for the same type are linted. #[lints(multiple_inherent_impl)] inherent_impl_lint_scope: InherentImplLintScope = InherentImplLintScope::Crate, + /// A list of paths to types that should be ignored as overly large `Err`-variants in a + /// `Result` returned from a function + #[lints(result_large_err)] + large_error_ignored: Vec = Vec::default(), /// The maximum size of the `Err`-variant in a `Result` returned from a function #[lints(result_large_err)] large_error_threshold: u64 = 128, diff --git a/clippy_lints/src/byte_char_slices.rs b/clippy_lints/src/byte_char_slices.rs index d88c0711b397..fc9931439e93 100644 --- a/clippy_lints/src/byte_char_slices.rs +++ b/clippy_lints/src/byte_char_slices.rs @@ -31,8 +31,8 @@ declare_lint_pass!(ByteCharSlice => [BYTE_CHAR_SLICES]); impl EarlyLintPass for ByteCharSlice { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { - if let Some(slice) = is_byte_char_slices(expr) - && !expr.span.from_expansion() + if !expr.span.from_expansion() + && let Some(slice) = is_byte_char_slices(expr) { span_lint_and_sugg( cx, @@ -47,33 +47,28 @@ impl EarlyLintPass for ByteCharSlice { } } +/// Checks whether the slice is that of byte chars, and if so, builds a byte-string out of it fn is_byte_char_slices(expr: &Expr) -> Option { - if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, expr) = &expr.kind { - match &expr.kind { - ExprKind::Array(members) => { - if members.is_empty() { - return None; - } - - members - .iter() - .map(|member| match &member.kind { - ExprKind::Lit(Lit { - kind: LitKind::Byte, - symbol, - .. - }) => Some(symbol.as_str()), - _ => None, - }) - .map(|maybe_quote| match maybe_quote { - Some("\"") => Some("\\\""), - Some("\\'") => Some("'"), - other => other, - }) - .collect::>() - }, - _ => None, - } + if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, expr) = &expr.kind + && let ExprKind::Array(members) = &expr.kind + && !members.is_empty() + { + members + .iter() + .map(|member| match &member.kind { + ExprKind::Lit(Lit { + kind: LitKind::Byte, + symbol, + .. + }) => Some(symbol.as_str()), + _ => None, + }) + .map(|maybe_quote| match maybe_quote { + Some("\"") => Some("\\\""), + Some("\\'") => Some("'"), + other => other, + }) + .collect::>() } else { None } diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index a754eea31165..4a350dca2993 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -118,6 +118,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::doc::DOC_MARKDOWN_INFO, crate::doc::DOC_NESTED_REFDEFS_INFO, crate::doc::DOC_OVERINDENTED_LIST_ITEMS_INFO, + crate::doc::DOC_PARAGRAPHS_MISSING_PUNCTUATION_INFO, crate::doc::DOC_SUSPICIOUS_FOOTNOTES_INFO, crate::doc::EMPTY_DOCS_INFO, crate::doc::MISSING_ERRORS_DOC_INFO, @@ -777,7 +778,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::use_self::USE_SELF_INFO, crate::useless_concat::USELESS_CONCAT_INFO, crate::useless_conversion::USELESS_CONVERSION_INFO, - crate::vec::USELESS_VEC_INFO, + crate::useless_vec::USELESS_VEC_INFO, crate::vec_init_then_push::VEC_INIT_THEN_PUSH_INFO, crate::visibility::NEEDLESS_PUB_SELF_INFO, crate::visibility::PUB_WITHOUT_SHORTHAND_INFO, diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 548f03c9f205..32fd4afb122e 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -12,8 +12,8 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty}; use rustc_hir::{ - self as hir, AmbigArg, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, - Pat, PatKind, Path, QPath, TyKind, UnOp, + self as hir, AmbigArg, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, Item, MatchSource, Mutability, + Node, OwnerId, Pat, PatKind, Path, QPath, TyKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; @@ -27,6 +27,8 @@ declare_clippy_lint! { /// ### What it does /// Checks for explicit `deref()` or `deref_mut()` method calls. /// + /// Doesn't lint inside the implementation of the `Deref` or `DerefMut` traits. + /// /// ### Why is this bad? /// Dereferencing by `&*x` or `&mut *x` is clearer and more concise, /// when not part of a method chain. @@ -169,6 +171,10 @@ pub struct Dereferencing<'tcx> { /// /// e.g. `m!(x) | Foo::Bar(ref x)` ref_locals: FxIndexMap>, + + /// The outermost `impl Deref` we're currently in. While we're in one, + /// `explicit_deref_methods` is deactivated + outermost_deref_impl: Option, } #[derive(Debug)] @@ -246,7 +252,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { // Stop processing sub expressions when a macro call is seen if expr.span.from_expansion() { if let Some((state, data)) = self.state.take() { - report(cx, expr, state, data, cx.typeck_results()); + self.report(cx, expr, state, data, cx.typeck_results()); } return; } @@ -255,7 +261,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { let Some((kind, sub_expr, skip_expr)) = try_parse_ref_op(cx.tcx, typeck, expr) else { // The whole chain of reference operations has been seen if let Some((state, data)) = self.state.take() { - report(cx, expr, state, data, typeck); + self.report(cx, expr, state, data, typeck); } return; }; @@ -263,7 +269,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { if is_from_proc_macro(cx, expr) { if let Some((state, data)) = self.state.take() { - report(cx, expr, state, data, cx.typeck_results()); + self.report(cx, expr, state, data, cx.typeck_results()); } return; } @@ -515,7 +521,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { (Some((State::DerefedBorrow(state), data)), RefOp::AddrOf(mutability)) => { let adjusted_ty = data.adjusted_ty; let stability = state.stability; - report(cx, expr, State::DerefedBorrow(state), data, typeck); + self.report(cx, expr, State::DerefedBorrow(state), data, typeck); if stability.is_deref_stable() { self.state = Some(( State::Borrow { mutability }, @@ -530,7 +536,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { let adjusted_ty = data.adjusted_ty; let stability = state.stability; let for_field_access = state.for_field_access; - report(cx, expr, State::DerefedBorrow(state), data, typeck); + self.report(cx, expr, State::DerefedBorrow(state), data, typeck); if let Some(name) = for_field_access && let sub_expr_ty = typeck.expr_ty(sub_expr) && !ty_contains_field(sub_expr_ty, name) @@ -602,7 +608,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { )); }, - (Some((state, data)), _) => report(cx, expr, state, data, typeck), + (Some((state, data)), _) => self.report(cx, expr, state, data, typeck), } } @@ -673,6 +679,31 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { self.current_body = None; } } + + fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { + // Only check for `impl Deref(Mut)`s if we're not already in one + if !self.in_deref_impl() && is_deref_or_derefmut_impl(cx, item) { + self.outermost_deref_impl = Some(item.owner_id); + } + } + + fn check_item_post(&mut self, _cx: &LateContext<'_>, item: &Item<'_>) { + // Only clear `self.outermost_deref_impl` if we're escaping the _outermost_ `impl Deref(Mut)` + if self.outermost_deref_impl == Some(item.owner_id) { + self.outermost_deref_impl = None; + } + } +} + +fn is_deref_or_derefmut_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool { + if let hir::ItemKind::Impl(impl_) = item.kind + && let Some(of_trait) = impl_.of_trait + && let Some(trait_id) = of_trait.trait_ref.trait_def_id() + { + cx.tcx.lang_items().deref_trait() == Some(trait_id) || cx.tcx.lang_items().deref_mut_trait() == Some(trait_id) + } else { + false + } } fn try_parse_ref_op<'tcx>( @@ -930,209 +961,11 @@ fn ty_contains_field(ty: Ty<'_>, name: Symbol) -> bool { } } -#[expect(clippy::needless_pass_by_value, clippy::too_many_lines)] -fn report<'tcx>( - cx: &LateContext<'tcx>, - expr: &'tcx Expr<'_>, - state: State, - data: StateData<'tcx>, - typeck: &'tcx TypeckResults<'tcx>, -) { - match state { - State::DerefMethod { - ty_changed_count, - is_ufcs, - mutbl, - } => { - let mut app = Applicability::MachineApplicable; - let (expr_str, expr_is_macro_call) = - snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app); - let ty = typeck.expr_ty(expr); - let (_, ref_count, _) = peel_and_count_ty_refs(ty); - let deref_str = if ty_changed_count >= ref_count && ref_count != 0 { - // a deref call changing &T -> &U requires two deref operators the first time - // this occurs. One to remove the reference, a second to call the deref impl. - "*".repeat(ty_changed_count + 1) - } else { - "*".repeat(ty_changed_count) - }; - let addr_of_str = if ty_changed_count < ref_count { - // Check if a reborrow from &mut T -> &T is required. - if mutbl == Mutability::Not && matches!(ty.kind(), ty::Ref(_, _, Mutability::Mut)) { - "&*" - } else { - "" - } - } else if mutbl == Mutability::Mut { - "&mut " - } else { - "&" - }; - - let expr_str = if !expr_is_macro_call && is_ufcs && cx.precedence(expr) < ExprPrecedence::Prefix { - Cow::Owned(format!("({expr_str})")) - } else { - expr_str - }; - - span_lint_and_sugg( - cx, - EXPLICIT_DEREF_METHODS, - data.first_expr.span, - match mutbl { - Mutability::Not => "explicit `deref` method call", - Mutability::Mut => "explicit `deref_mut` method call", - }, - "try", - format!("{addr_of_str}{deref_str}{expr_str}"), - app, - ); - }, - State::DerefedBorrow(state) => { - // Do not suggest removing a non-mandatory `&` in `&*rawptr` in an `unsafe` context, - // as this may make rustc trigger its `dangerous_implicit_autorefs` lint. - if let ExprKind::AddrOf(BorrowKind::Ref, _, subexpr) = data.first_expr.kind - && let ExprKind::Unary(UnOp::Deref, subsubexpr) = subexpr.kind - && cx.typeck_results().expr_ty_adjusted(subsubexpr).is_raw_ptr() - { - return; - } - - let mut app = Applicability::MachineApplicable; - let (snip, snip_is_macro) = - snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app); - span_lint_hir_and_then( - cx, - NEEDLESS_BORROW, - data.first_expr.hir_id, - data.first_expr.span, - state.msg, - |diag| { - let needs_paren = match cx.tcx.parent_hir_node(data.first_expr.hir_id) { - Node::Expr(e) => match e.kind { - ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false, - ExprKind::Call(..) => { - cx.precedence(expr) < ExprPrecedence::Unambiguous - || matches!(expr.kind, ExprKind::Field(..)) - }, - _ => cx.precedence(expr) < cx.precedence(e), - }, - _ => false, - }; - let is_in_tuple = matches!( - get_parent_expr(cx, data.first_expr), - Some(Expr { - kind: ExprKind::Tup(..), - .. - }) - ); - - let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) && !is_in_tuple { - format!("({snip})") - } else { - snip.into() - }; - diag.span_suggestion(data.first_expr.span, "change this to", sugg, app); - }, - ); - }, - State::ExplicitDeref { mutability } => { - if is_block_like(expr) - && let ty::Ref(_, ty, _) = data.adjusted_ty.kind() - && ty.is_sized(cx.tcx, cx.typing_env()) - { - // Rustc bug: auto deref doesn't work on block expression when targeting sized types. - return; - } - - let ty = typeck.expr_ty(expr); - - // `&&[T; N]`, or `&&..&[T; N]` (src) cannot coerce to `&[T]` (dst). - if let ty::Ref(_, dst, _) = data.adjusted_ty.kind() - && dst.is_slice() - { - let (src, n_src_refs, _) = peel_and_count_ty_refs(ty); - if n_src_refs >= 2 && src.is_array() { - return; - } - } - - let (prefix, needs_paren) = match mutability { - Some(mutability) if !ty.is_ref() => { - let prefix = match mutability { - Mutability::Not => "&", - Mutability::Mut => "&mut ", - }; - (prefix, cx.precedence(expr) < ExprPrecedence::Prefix) - }, - None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", false), - _ => ("", false), - }; - span_lint_hir_and_then( - cx, - EXPLICIT_AUTO_DEREF, - data.first_expr.hir_id, - data.first_expr.span, - "deref which would be done by auto-deref", - |diag| { - let mut app = Applicability::MachineApplicable; - let (snip, snip_is_macro) = - snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app); - let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) { - format!("{prefix}({snip})") - } else { - format!("{prefix}{snip}") - }; - diag.span_suggestion(data.first_expr.span, "try", sugg, app); - }, - ); - }, - State::ExplicitDerefField { - derefs_manually_drop, .. - } => { - let (snip_span, needs_parens) = if matches!(expr.kind, ExprKind::Field(..)) - && (derefs_manually_drop - || adjust_derefs_manually_drop( - typeck.expr_adjustments(data.first_expr), - typeck.expr_ty(data.first_expr), - )) { - // `DerefMut` will not be automatically applied to `ManuallyDrop<_>` - // field expressions when the base type is a union and the parent - // expression is also a field access. - // - // e.g. `&mut x.y.z` where `x` is a union, and accessing `z` requires a - // deref through `ManuallyDrop<_>` will not compile. - let parent_id = cx.tcx.parent_hir_id(expr.hir_id); - if parent_id == data.first_expr.hir_id { - return; - } - (cx.tcx.hir_node(parent_id).expect_expr().span, true) - } else { - (expr.span, false) - }; - span_lint_hir_and_then( - cx, - EXPLICIT_AUTO_DEREF, - data.first_expr.hir_id, - data.first_expr.span, - "deref which would be done by auto-deref", - |diag| { - let mut app = Applicability::MachineApplicable; - let snip = snippet_with_context(cx, snip_span, data.first_expr.span.ctxt(), "..", &mut app).0; - let sugg = if needs_parens { - format!("({snip})") - } else { - snip.into_owned() - }; - diag.span_suggestion(data.first_expr.span, "try", sugg, app); - }, - ); - }, - State::Borrow { .. } | State::Reborrow { .. } => (), - } -} - impl<'tcx> Dereferencing<'tcx> { + fn in_deref_impl(&self) -> bool { + self.outermost_deref_impl.is_some() + } + fn check_local_usage(&mut self, cx: &LateContext<'tcx>, e: &Expr<'tcx>, local: HirId) { if let Some(outer_pat) = self.ref_locals.get_mut(&local) && let Some(pat) = outer_pat @@ -1191,4 +1024,211 @@ impl<'tcx> Dereferencing<'tcx> { } } } + + #[expect(clippy::needless_pass_by_value, clippy::too_many_lines)] + fn report( + &self, + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + state: State, + data: StateData<'tcx>, + typeck: &'tcx TypeckResults<'tcx>, + ) { + match state { + State::DerefMethod { + ty_changed_count, + is_ufcs, + mutbl, + } => { + if self.in_deref_impl() { + // `deref(_mut)` is fine in an `impl Deref(Mut)` + return; + } + let mut app = Applicability::MachineApplicable; + let (expr_str, expr_is_macro_call) = + snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app); + let ty = typeck.expr_ty(expr); + let (_, ref_count, _) = peel_and_count_ty_refs(ty); + let deref_str = if ty_changed_count >= ref_count && ref_count != 0 { + // a deref call changing &T -> &U requires two deref operators the first time + // this occurs. One to remove the reference, a second to call the deref impl. + "*".repeat(ty_changed_count + 1) + } else { + "*".repeat(ty_changed_count) + }; + let addr_of_str = if ty_changed_count < ref_count { + // Check if a reborrow from &mut T -> &T is required. + if mutbl == Mutability::Not && matches!(ty.kind(), ty::Ref(_, _, Mutability::Mut)) { + "&*" + } else { + "" + } + } else if mutbl == Mutability::Mut { + "&mut " + } else { + "&" + }; + + let expr_str = if !expr_is_macro_call && is_ufcs && cx.precedence(expr) < ExprPrecedence::Prefix { + Cow::Owned(format!("({expr_str})")) + } else { + expr_str + }; + + span_lint_and_sugg( + cx, + EXPLICIT_DEREF_METHODS, + data.first_expr.span, + match mutbl { + Mutability::Not => "explicit `deref` method call", + Mutability::Mut => "explicit `deref_mut` method call", + }, + "try", + format!("{addr_of_str}{deref_str}{expr_str}"), + app, + ); + }, + State::DerefedBorrow(state) => { + // Do not suggest removing a non-mandatory `&` in `&*rawptr` in an `unsafe` context, + // as this may make rustc trigger its `dangerous_implicit_autorefs` lint. + if let ExprKind::AddrOf(BorrowKind::Ref, _, subexpr) = data.first_expr.kind + && let ExprKind::Unary(UnOp::Deref, subsubexpr) = subexpr.kind + && cx.typeck_results().expr_ty_adjusted(subsubexpr).is_raw_ptr() + { + return; + } + + let mut app = Applicability::MachineApplicable; + let (snip, snip_is_macro) = + snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app); + span_lint_hir_and_then( + cx, + NEEDLESS_BORROW, + data.first_expr.hir_id, + data.first_expr.span, + state.msg, + |diag| { + let needs_paren = match cx.tcx.parent_hir_node(data.first_expr.hir_id) { + Node::Expr(e) => match e.kind { + ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false, + ExprKind::Call(..) => { + cx.precedence(expr) < ExprPrecedence::Unambiguous + || matches!(expr.kind, ExprKind::Field(..)) + }, + _ => cx.precedence(expr) < cx.precedence(e), + }, + _ => false, + }; + let is_in_tuple = matches!( + get_parent_expr(cx, data.first_expr), + Some(Expr { + kind: ExprKind::Tup(..), + .. + }) + ); + + let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) && !is_in_tuple { + format!("({snip})") + } else { + snip.into() + }; + diag.span_suggestion(data.first_expr.span, "change this to", sugg, app); + }, + ); + }, + State::ExplicitDeref { mutability } => { + if is_block_like(expr) + && let ty::Ref(_, ty, _) = data.adjusted_ty.kind() + && ty.is_sized(cx.tcx, cx.typing_env()) + { + // Rustc bug: auto deref doesn't work on block expression when targeting sized types. + return; + } + + let ty = typeck.expr_ty(expr); + + // `&&[T; N]`, or `&&..&[T; N]` (src) cannot coerce to `&[T]` (dst). + if let ty::Ref(_, dst, _) = data.adjusted_ty.kind() + && dst.is_slice() + { + let (src, n_src_refs, _) = peel_and_count_ty_refs(ty); + if n_src_refs >= 2 && src.is_array() { + return; + } + } + + let (prefix, needs_paren) = match mutability { + Some(mutability) if !ty.is_ref() => { + let prefix = match mutability { + Mutability::Not => "&", + Mutability::Mut => "&mut ", + }; + (prefix, cx.precedence(expr) < ExprPrecedence::Prefix) + }, + None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", false), + _ => ("", false), + }; + span_lint_hir_and_then( + cx, + EXPLICIT_AUTO_DEREF, + data.first_expr.hir_id, + data.first_expr.span, + "deref which would be done by auto-deref", + |diag| { + let mut app = Applicability::MachineApplicable; + let (snip, snip_is_macro) = + snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app); + let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) { + format!("{prefix}({snip})") + } else { + format!("{prefix}{snip}") + }; + diag.span_suggestion(data.first_expr.span, "try", sugg, app); + }, + ); + }, + State::ExplicitDerefField { + derefs_manually_drop, .. + } => { + let (snip_span, needs_parens) = if matches!(expr.kind, ExprKind::Field(..)) + && (derefs_manually_drop + || adjust_derefs_manually_drop( + typeck.expr_adjustments(data.first_expr), + typeck.expr_ty(data.first_expr), + )) { + // `DerefMut` will not be automatically applied to `ManuallyDrop<_>` + // field expressions when the base type is a union and the parent + // expression is also a field access. + // + // e.g. `&mut x.y.z` where `x` is a union, and accessing `z` requires a + // deref through `ManuallyDrop<_>` will not compile. + let parent_id = cx.tcx.parent_hir_id(expr.hir_id); + if parent_id == data.first_expr.hir_id { + return; + } + (cx.tcx.hir_node(parent_id).expect_expr().span, true) + } else { + (expr.span, false) + }; + span_lint_hir_and_then( + cx, + EXPLICIT_AUTO_DEREF, + data.first_expr.hir_id, + data.first_expr.span, + "deref which would be done by auto-deref", + |diag| { + let mut app = Applicability::MachineApplicable; + let snip = snippet_with_context(cx, snip_span, data.first_expr.span.ctxt(), "..", &mut app).0; + let sugg = if needs_parens { + format!("({snip})") + } else { + snip.into_owned() + }; + diag.span_suggestion(data.first_expr.span, "try", sugg, app); + }, + ); + }, + State::Borrow { .. } | State::Reborrow { .. } => (), + } + } } diff --git a/clippy_lints/src/doc/doc_paragraphs_missing_punctuation.rs b/clippy_lints/src/doc/doc_paragraphs_missing_punctuation.rs new file mode 100644 index 000000000000..a8f734637672 --- /dev/null +++ b/clippy_lints/src/doc/doc_paragraphs_missing_punctuation.rs @@ -0,0 +1,126 @@ +use rustc_errors::Applicability; +use rustc_lint::LateContext; +use rustc_resolve::rustdoc::main_body_opts; + +use rustc_resolve::rustdoc::pulldown_cmark::{Event, Options, Parser, Tag, TagEnd}; + +use super::{DOC_PARAGRAPHS_MISSING_PUNCTUATION, Fragments}; + +const MSG: &str = "doc paragraphs should end with a terminal punctuation mark"; +const PUNCTUATION_SUGGESTION: char = '.'; + +pub fn check(cx: &LateContext<'_>, doc: &str, fragments: Fragments<'_>) { + for missing_punctuation in is_missing_punctuation(doc) { + match missing_punctuation { + MissingPunctuation::Fixable(offset) => { + // This ignores `#[doc]` attributes, which we do not handle. + if let Some(span) = fragments.span(cx, offset..offset) { + clippy_utils::diagnostics::span_lint_and_sugg( + cx, + DOC_PARAGRAPHS_MISSING_PUNCTUATION, + span, + MSG, + "end the paragraph with some punctuation", + PUNCTUATION_SUGGESTION.to_string(), + Applicability::MaybeIncorrect, + ); + } + }, + MissingPunctuation::Unfixable(offset) => { + // This ignores `#[doc]` attributes, which we do not handle. + if let Some(span) = fragments.span(cx, offset..offset) { + clippy_utils::diagnostics::span_lint_and_help( + cx, + DOC_PARAGRAPHS_MISSING_PUNCTUATION, + span, + MSG, + None, + "end the paragraph with some punctuation", + ); + } + }, + } + } +} + +#[must_use] +/// If punctuation is missing, returns the offset where new punctuation should be inserted. +fn is_missing_punctuation(doc_string: &str) -> Vec { + // The colon is not exactly a terminal punctuation mark, but this is required for paragraphs that + // introduce a table or a list for example. + const TERMINAL_PUNCTUATION_MARKS: &[char] = &['.', '?', '!', '…', ':']; + + let mut no_report_depth = 0; + let mut missing_punctuation = Vec::new(); + let mut current_paragraph = None; + + for (event, offset) in + Parser::new_ext(doc_string, main_body_opts() - Options::ENABLE_SMART_PUNCTUATION).into_offset_iter() + { + match event { + Event::Start( + Tag::CodeBlock(..) + | Tag::FootnoteDefinition(_) + | Tag::Heading { .. } + | Tag::HtmlBlock + | Tag::List(..) + | Tag::Table(_), + ) => { + no_report_depth += 1; + }, + Event::End(TagEnd::FootnoteDefinition) => { + no_report_depth -= 1; + }, + Event::End( + TagEnd::CodeBlock | TagEnd::Heading(_) | TagEnd::HtmlBlock | TagEnd::List(_) | TagEnd::Table, + ) => { + no_report_depth -= 1; + current_paragraph = None; + }, + Event::InlineHtml(_) | Event::Start(Tag::Image { .. }) | Event::End(TagEnd::Image) => { + current_paragraph = None; + }, + Event::End(TagEnd::Paragraph) => { + if let Some(mp) = current_paragraph { + missing_punctuation.push(mp); + } + }, + Event::Code(..) | Event::Start(Tag::Link { .. }) | Event::End(TagEnd::Link) + if no_report_depth == 0 && !offset.is_empty() => + { + if doc_string[..offset.end] + .trim_end() + .ends_with(TERMINAL_PUNCTUATION_MARKS) + { + current_paragraph = None; + } else { + current_paragraph = Some(MissingPunctuation::Fixable(offset.end)); + } + }, + Event::Text(..) if no_report_depth == 0 && !offset.is_empty() => { + let trimmed = doc_string[..offset.end].trim_end(); + if trimmed.ends_with(TERMINAL_PUNCTUATION_MARKS) { + current_paragraph = None; + } else if let Some(t) = trimmed.strip_suffix(|c| c == ')' || c == '"') { + if t.ends_with(TERMINAL_PUNCTUATION_MARKS) { + // Avoid false positives. + current_paragraph = None; + } else { + current_paragraph = Some(MissingPunctuation::Unfixable(offset.end)); + } + } else { + current_paragraph = Some(MissingPunctuation::Fixable(offset.end)); + } + }, + _ => {}, + } + } + + missing_punctuation +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +enum MissingPunctuation { + Fixable(usize), + Unfixable(usize), +} diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 1e1d6e69cc91..120da92da944 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -27,6 +27,7 @@ use url::Url; mod broken_link; mod doc_comment_double_space_linebreaks; +mod doc_paragraphs_missing_punctuation; mod doc_suspicious_footnotes; mod include_in_doc_without_cfg; mod lazy_continuation; @@ -670,6 +671,33 @@ declare_clippy_lint! { "looks like a link or footnote ref, but with no definition" } +declare_clippy_lint! { + /// ### What it does + /// Checks for doc comments whose paragraphs do not end with a period or another punctuation mark. + /// Various Markdowns constructs are taken into account to avoid false positives. + /// + /// ### Why is this bad? + /// A project may wish to enforce consistent doc comments by making sure paragraphs end with a + /// punctuation mark. + /// + /// ### Example + /// ```no_run + /// /// Returns a random number + /// /// + /// /// It was chosen by a fair dice roll + /// ``` + /// Use instead: + /// ```no_run + /// /// Returns a random number. + /// /// + /// /// It was chosen by a fair dice roll. + /// ``` + #[clippy::version = "1.93.0"] + pub DOC_PARAGRAPHS_MISSING_PUNCTUATION, + restriction, + "missing terminal punctuation in doc comments" +} + pub struct Documentation { valid_idents: FxHashSet, check_private_items: bool, @@ -704,6 +732,7 @@ impl_lint_pass!(Documentation => [ DOC_INCLUDE_WITHOUT_CFG, DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS, DOC_SUSPICIOUS_FOOTNOTES, + DOC_PARAGRAPHS_MISSING_PUNCTUATION, ]); impl EarlyLintPass for Documentation { @@ -875,6 +904,15 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ }, ); + doc_paragraphs_missing_punctuation::check( + cx, + &doc, + Fragments { + doc: &doc, + fragments: &fragments, + }, + ); + // NOTE: check_doc uses it own cb function, // to avoid causing duplicated diagnostics for the broken link checker. let mut full_fake_broken_link_callback = |bl: BrokenLink<'_>| -> Option<(CowStr<'_>, CowStr<'_>)> { diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs index 9b5cd7e1731f..a92bfd45df0c 100644 --- a/clippy_lints/src/equatable_if_let.rs +++ b/clippy_lints/src/equatable_if_let.rs @@ -1,4 +1,5 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::is_in_const_context; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::implements_trait; use rustc_errors::Applicability; @@ -40,9 +41,9 @@ declare_clippy_lint! { declare_lint_pass!(PatternEquality => [EQUATABLE_IF_LET]); /// detects if pattern matches just one thing -fn unary_pattern(pat: &Pat<'_>) -> bool { +fn is_unary_pattern(pat: &Pat<'_>) -> bool { fn array_rec(pats: &[Pat<'_>]) -> bool { - pats.iter().all(unary_pattern) + pats.iter().all(is_unary_pattern) } match &pat.kind { PatKind::Missing => unreachable!(), @@ -53,9 +54,9 @@ fn unary_pattern(pat: &Pat<'_>) -> bool { | PatKind::Never | PatKind::Or(_) | PatKind::Err(_) => false, - PatKind::Struct(_, a, etc) => etc.is_none() && a.iter().all(|x| unary_pattern(x.pat)), + PatKind::Struct(_, a, etc) => etc.is_none() && a.iter().all(|x| is_unary_pattern(x.pat)), PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a), - PatKind::Ref(x, _, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => unary_pattern(x), + PatKind::Ref(x, _, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => is_unary_pattern(x), PatKind::Expr(_) => true, } } @@ -103,48 +104,63 @@ fn contains_type_mismatch(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { impl<'tcx> LateLintPass<'tcx> for PatternEquality { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if let ExprKind::Let(let_expr) = expr.kind - && unary_pattern(let_expr.pat) + && is_unary_pattern(let_expr.pat) && !expr.span.in_external_macro(cx.sess().source_map()) + && !let_expr.pat.span.from_expansion() + && !let_expr.init.span.from_expansion() { let exp_ty = cx.typeck_results().expr_ty(let_expr.init); let pat_ty = cx.typeck_results().pat_ty(let_expr.pat); - let mut applicability = Applicability::MachineApplicable; - if is_structural_partial_eq(cx, exp_ty, pat_ty) && !contains_type_mismatch(cx, let_expr.pat) { - let pat_str = match let_expr.pat.kind { - PatKind::Struct(..) => format!( - "({})", - snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0, - ), - _ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability) - .0 - .to_string(), - }; - span_lint_and_sugg( + let mut app = Applicability::MachineApplicable; + let ctxt = expr.span.ctxt(); + + if is_structural_partial_eq(cx, exp_ty, pat_ty) + && !contains_type_mismatch(cx, let_expr.pat) + // Calls to trait methods (`PartialEq::eq` in this case) aren't stable yet. We could _technically_ + // try looking at whether: + // 1) features `const_trait_impl` and `const_cmp` are enabled + // 2) implementation of `PartialEq for ExpTy` has `fn eq` that is `const` + // + // but that didn't quite work out (see #15482), so we just reject outright in this case + && !is_in_const_context(cx) + { + span_lint_and_then( cx, EQUATABLE_IF_LET, expr.span, "this pattern matching can be expressed using equality", - "try", - format!( - "{} == {pat_str}", - snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0, - ), - applicability, + |diag| { + let pat_str = { + let str = snippet_with_context(cx, let_expr.pat.span, ctxt, "..", &mut app).0; + if let PatKind::Struct(..) = let_expr.pat.kind { + format!("({str})").into() + } else { + str + } + }; + + let sugg = format!( + "{} == {pat_str}", + snippet_with_context(cx, let_expr.init.span, ctxt, "..", &mut app).0, + ); + diag.span_suggestion(expr.span, "try", sugg, app); + }, ); } else { - span_lint_and_sugg( + span_lint_and_then( cx, EQUATABLE_IF_LET, expr.span, "this pattern matching can be expressed using `matches!`", - "try", - format!( - "matches!({}, {})", - snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0, - snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0, - ), - applicability, + |diag| { + let sugg = format!( + "matches!({}, {})", + snippet_with_context(cx, let_expr.init.span, ctxt, "..", &mut app).0, + snippet_with_context(cx, let_expr.pat.span, ctxt, "..", &mut app).0, + ); + diag.span_suggestion(expr.span, "try", sugg, app); + }, ); } } diff --git a/clippy_lints/src/functions/mod.rs b/clippy_lints/src/functions/mod.rs index 5a40af421942..bdc366f6878a 100644 --- a/clippy_lints/src/functions/mod.rs +++ b/clippy_lints/src/functions/mod.rs @@ -485,6 +485,7 @@ pub struct Functions { too_many_arguments_threshold: u64, too_many_lines_threshold: u64, large_error_threshold: u64, + large_error_ignored: DefIdSet, avoid_breaking_exported_api: bool, /// A set of resolved `def_id` of traits that are configured to allow /// function params renaming. @@ -498,6 +499,11 @@ impl Functions { too_many_arguments_threshold: conf.too_many_arguments_threshold, too_many_lines_threshold: conf.too_many_lines_threshold, large_error_threshold: conf.large_error_threshold, + large_error_ignored: conf + .large_error_ignored + .iter() + .flat_map(|ignored_ty| lookup_path_str(tcx, PathNS::Type, ignored_ty)) + .collect(), avoid_breaking_exported_api: conf.avoid_breaking_exported_api, trait_ids: conf .allow_renamed_params_for @@ -554,12 +560,24 @@ impl<'tcx> LateLintPass<'tcx> for Functions { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { must_use::check_item(cx, item); - result::check_item(cx, item, self.large_error_threshold, self.msrv); + result::check_item( + cx, + item, + self.large_error_threshold, + &self.large_error_ignored, + self.msrv, + ); } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { must_use::check_impl_item(cx, item); - result::check_impl_item(cx, item, self.large_error_threshold, self.msrv); + result::check_impl_item( + cx, + item, + self.large_error_threshold, + &self.large_error_ignored, + self.msrv, + ); impl_trait_in_params::check_impl_item(cx, item); renamed_function_params::check_impl_item(cx, item, &self.trait_ids); } @@ -568,7 +586,13 @@ impl<'tcx> LateLintPass<'tcx> for Functions { too_many_arguments::check_trait_item(cx, item, self.too_many_arguments_threshold); not_unsafe_ptr_arg_deref::check_trait_item(cx, item); must_use::check_trait_item(cx, item); - result::check_trait_item(cx, item, self.large_error_threshold, self.msrv); + result::check_trait_item( + cx, + item, + self.large_error_threshold, + &self.large_error_ignored, + self.msrv, + ); impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api); ref_option::check_trait_item(cx, item, self.avoid_breaking_exported_api); } diff --git a/clippy_lints/src/functions/result.rs b/clippy_lints/src/functions/result.rs index fb80cc1a63a3..04e15a1d8a0e 100644 --- a/clippy_lints/src/functions/result.rs +++ b/clippy_lints/src/functions/result.rs @@ -4,6 +4,7 @@ use rustc_errors::Diag; use rustc_hir as hir; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty::{self, Ty}; +use rustc_span::def_id::DefIdSet; use rustc_span::{Span, sym}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; @@ -35,7 +36,13 @@ fn result_err_ty<'tcx>( } } -pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64, msrv: Msrv) { +pub(super) fn check_item<'tcx>( + cx: &LateContext<'tcx>, + item: &hir::Item<'tcx>, + large_err_threshold: u64, + large_err_ignored: &DefIdSet, + msrv: Msrv, +) { if let hir::ItemKind::Fn { ref sig, .. } = item.kind && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span) { @@ -43,7 +50,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, l let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); check_result_unit_err(cx, err_ty, fn_header_span, msrv); } - check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold); + check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored); } } @@ -51,6 +58,7 @@ pub(super) fn check_impl_item<'tcx>( cx: &LateContext<'tcx>, item: &hir::ImplItem<'tcx>, large_err_threshold: u64, + large_err_ignored: &DefIdSet, msrv: Msrv, ) { // Don't lint if method is a trait's implementation, we can't do anything about those @@ -62,7 +70,7 @@ pub(super) fn check_impl_item<'tcx>( let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); check_result_unit_err(cx, err_ty, fn_header_span, msrv); } - check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold); + check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored); } } @@ -70,6 +78,7 @@ pub(super) fn check_trait_item<'tcx>( cx: &LateContext<'tcx>, item: &hir::TraitItem<'tcx>, large_err_threshold: u64, + large_err_ignored: &DefIdSet, msrv: Msrv, ) { if let hir::TraitItemKind::Fn(ref sig, _) = item.kind { @@ -78,7 +87,7 @@ pub(super) fn check_trait_item<'tcx>( if cx.effective_visibilities.is_exported(item.owner_id.def_id) { check_result_unit_err(cx, err_ty, fn_header_span, msrv); } - check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold); + check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored); } } } @@ -96,7 +105,18 @@ fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: S } } -fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty_span: Span, large_err_threshold: u64) { +fn check_result_large_err<'tcx>( + cx: &LateContext<'tcx>, + err_ty: Ty<'tcx>, + hir_ty_span: Span, + large_err_threshold: u64, + large_err_ignored: &DefIdSet, +) { + if let ty::Adt(adt, _) = err_ty.kind() + && large_err_ignored.contains(&adt.did()) + { + return; + } if let ty::Adt(adt, subst) = err_ty.kind() && let Some(local_def_id) = adt.did().as_local() && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_def_id) diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index d2bc0b6d9935..638a08b096db 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -13,7 +13,7 @@ use rustc_session::declare_lint_pass; use rustc_span::Span; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::source::{IntoSpan, SpanRangeExt, snippet}; +use clippy_utils::source::{IntoSpan, SpanRangeExt, snippet, snippet_with_context}; use clippy_utils::sym; declare_clippy_lint! { @@ -335,29 +335,29 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> { return; } - match (self.cx.tcx.get_diagnostic_name(ty_did), method.ident.name) { - (Some(sym::HashMap), sym::new) => { - self.suggestions.insert(e.span, "HashMap::default()".to_string()); + let container_name = match self.cx.tcx.get_diagnostic_name(ty_did) { + Some(sym::HashMap) => "HashMap", + Some(sym::HashSet) => "HashSet", + _ => return, + }; + + match method.ident.name { + sym::new => { + self.suggestions.insert(e.span, format!("{container_name}::default()")); }, - (Some(sym::HashMap), sym::with_capacity) => { - self.suggestions.insert( - e.span, - format!( - "HashMap::with_capacity_and_hasher({}, Default::default())", - snippet(self.cx, args[0].span, "capacity"), - ), + sym::with_capacity => { + let (arg_snippet, _) = snippet_with_context( + self.cx, + args[0].span, + e.span.ctxt(), + "..", + // We can throw-away the applicability here since the whole suggestion is + // marked as `MaybeIncorrect` later. + &mut Applicability::MaybeIncorrect, ); - }, - (Some(sym::HashSet), sym::new) => { - self.suggestions.insert(e.span, "HashSet::default()".to_string()); - }, - (Some(sym::HashSet), sym::with_capacity) => { self.suggestions.insert( e.span, - format!( - "HashSet::with_capacity_and_hasher({}, Default::default())", - snippet(self.cx, args[0].span, "capacity"), - ), + format!("{container_name}::with_capacity_and_hasher({arg_snippet}, Default::default())",), ); }, _ => {}, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 4542105d3277..230d83dacc95 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -386,7 +386,7 @@ mod upper_case_acronyms; mod use_self; mod useless_concat; mod useless_conversion; -mod vec; +mod useless_vec; mod vec_init_then_push; mod visibility; mod volatile_composites; @@ -592,7 +592,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(move |_| Box::new(transmute::Transmute::new(conf))), Box::new(move |_| Box::new(cognitive_complexity::CognitiveComplexity::new(conf))), Box::new(move |_| Box::new(escape::BoxedLocal::new(conf))), - Box::new(move |_| Box::new(vec::UselessVec::new(conf))), + Box::new(move |_| Box::new(useless_vec::UselessVec::new(conf))), Box::new(move |_| Box::new(panic_unimplemented::PanicUnimplemented::new(conf))), Box::new(|_| Box::new(strings::StringLitAsBytes)), Box::new(|_| Box::new(derive::Derive)), diff --git a/clippy_lints/src/methods/sliced_string_as_bytes.rs b/clippy_lints/src/methods/sliced_string_as_bytes.rs index 4aff194923a6..fb124f3605b9 100644 --- a/clippy_lints/src/methods/sliced_string_as_bytes.rs +++ b/clippy_lints/src/methods/sliced_string_as_bytes.rs @@ -1,15 +1,21 @@ use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::higher; use clippy_utils::res::MaybeDef; use clippy_utils::source::snippet_with_applicability; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, LangItem, is_range_literal}; +use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_lint::LateContext; use super::SLICED_STRING_AS_BYTES; +/// Checks if `index` is any type of range except `RangeFull` (i.e. `..`) +fn is_bounded_range_literal(cx: &LateContext<'_>, index: &Expr<'_>) -> bool { + higher::Range::hir(cx, index).is_some_and(|range| Option::or(range.start, range.end).is_some()) +} + pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>) { if let ExprKind::Index(indexed, index, _) = recv.kind - && is_range_literal(index) + && is_bounded_range_literal(cx, index) && let ty = cx.typeck_results().expr_ty(indexed).peel_refs() && (ty.is_str() || ty.is_lang_item(cx, LangItem::String)) { diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs index 972304d79e75..f852080d0f2a 100644 --- a/clippy_lints/src/methods/useless_asref.rs +++ b/clippy_lints/src/methods/useless_asref.rs @@ -4,7 +4,8 @@ use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::{implements_trait, peel_and_count_ty_refs, should_call_clone_as_function}; use clippy_utils::{get_parent_expr, peel_blocks, strip_pat_refs}; use rustc_errors::Applicability; -use rustc_hir::{self as hir, LangItem}; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{self as hir, LangItem, Node}; use rustc_lint::LateContext; use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::{Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; @@ -69,14 +70,37 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: Symbo } } + // Add `*` derefs if the expr is used in a ctor, because automatic derefs don't apply in that case. + let deref = if rcv_depth > res_depth { + let parent = cx.tcx.parent_hir_node(expr.hir_id); + match parent { + Node::ExprField(_) => "*".repeat(rcv_depth - res_depth), + Node::Expr(parent) + if let hir::ExprKind::Call(func, _) = parent.kind + && let (_, Some(path)) = func.opt_res_path() + && matches!(path.res, Res::Def(DefKind::Ctor(_, _), _) | Res::SelfCtor(_)) => + { + "*".repeat(rcv_depth - res_depth) + }, + _ => String::new(), + } + } else { + String::new() + }; + let mut applicability = Applicability::MachineApplicable; + let suggestion = format!( + "{deref}{}", + snippet_with_applicability(cx, recvr.span, "..", &mut applicability) + ); + span_lint_and_sugg( cx, USELESS_ASREF, expr.span, format!("this call to `{call_name}` does nothing"), "try", - snippet_with_applicability(cx, recvr.span, "..", &mut applicability).to_string(), + suggestion, applicability, ); } diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 1c62caa1c827..ac221743cfd6 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -1,26 +1,18 @@ -// Note: More specifically this lint is largely inspired (aka copied) from -// *rustc*'s -// [`missing_doc`]. -// -// [`missing_doc`]: https://github.com/rust-lang/rust/blob/cf9cf7c923eb01146971429044f216a3ca905e06/compiler/rustc_lint/src/builtin.rs#L415 -// - use clippy_config::Conf; -use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::span_lint; -use clippy_utils::is_from_proc_macro; -use clippy_utils::source::SpanRangeExt; -use rustc_ast::ast::MetaItemInner; -use rustc_hir as hir; -use rustc_hir::Attribute; -use rustc_hir::def::DefKind; +use clippy_utils::{is_doc_hidden, is_from_proc_macro}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::LocalDefId; -use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty::{AssocContainer, Visibility}; +use rustc_hir::{ + AttrArgs, Attribute, Body, BodyId, FieldDef, HirId, ImplItem, Item, ItemKind, Node, TraitItem, Variant, +}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::middle::privacy::Level; +use rustc_middle::ty::Visibility; use rustc_session::impl_lint_pass; use rustc_span::def_id::CRATE_DEF_ID; +use rustc_span::sym; use rustc_span::symbol::kw; -use rustc_span::{Span, sym}; declare_clippy_lint! { /// ### What it does @@ -37,24 +29,27 @@ declare_clippy_lint! { "detects missing documentation for private members" } -macro_rules! note_prev_span_then_ret { - ($prev_span:expr, $span:expr) => {{ - $prev_span = Some($span); - return; - }}; -} - pub struct MissingDoc { /// Whether to **only** check for missing documentation in items visible within the current /// crate. For example, `pub(crate)` items. crate_items_only: bool, /// Whether to allow fields starting with an underscore to skip documentation requirements allow_unused: bool, - /// Stack of whether #[doc(hidden)] is set - /// at each level which has lint attributes. - doc_hidden_stack: Vec, - /// Used to keep tracking of the previous item, field or variants etc, to get the search span. - prev_span: Option, + /// The current number of modules since the crate root. + module_depth: u32, + macro_module_depth: u32, + /// The current level of the attribute stack. + attr_depth: u32, + /// What `attr_depth` level the first `doc(hidden)` attribute was seen. This is zero if the + /// attribute hasn't been seen. + doc_hidden_depth: u32, + /// What `attr_depth` level the first `automatically_derived` attribute was seen. This is zero + /// if the attribute hasn't been seen. + automatically_derived_depth: u32, + /// The id of the first body we've seen. + in_body: Option, + /// The module/crate id an item must be visible at to be linted. + require_visibility_at: Option, } impl MissingDoc { @@ -62,113 +57,45 @@ impl MissingDoc { Self { crate_items_only: conf.missing_docs_in_crate_items, allow_unused: conf.missing_docs_allow_unused, - doc_hidden_stack: vec![false], - prev_span: None, + module_depth: 0, + macro_module_depth: 0, + attr_depth: 0, + doc_hidden_depth: 0, + automatically_derived_depth: 0, + in_body: None, + require_visibility_at: None, } } - fn doc_hidden(&self) -> bool { - *self.doc_hidden_stack.last().expect("empty doc_hidden_stack") - } - - fn has_include(meta: Option<&[MetaItemInner]>) -> bool { - if let Some(list) = meta - && let Some(meta) = list.first() - && let Some(name) = meta.ident() - { - name.name == sym::include - } else { - false - } - } - - fn check_missing_docs_attrs( - &self, - cx: &LateContext<'_>, - def_id: LocalDefId, - attrs: &[Attribute], - sp: Span, - article: &'static str, - desc: &'static str, - ) { - // If we're building a test harness, then warning about - // documentation is probably not really relevant right now. - if cx.sess().opts.test { - return; + fn is_missing_docs(&self, cx: &LateContext<'_>, def_id: LocalDefId, hir_id: HirId) -> bool { + if cx.tcx.sess.opts.test { + return false; } - // `#[doc(hidden)]` disables missing_docs check. - if self.doc_hidden() { - return; + match cx.effective_visibilities.effective_vis(def_id) { + None if self.require_visibility_at.is_some() => return false, + None if self.crate_items_only && self.module_depth != 0 => return false, + // `missing_docs` lint uses `Reexported` because rustdoc doesn't render documentation + // for items without a reachable path. + Some(vis) if vis.is_public_at_level(Level::Reexported) => return false, + Some(vis) => { + if self.crate_items_only { + // Use the `Reachable` level since rustdoc will be able to render the documentation + // when building private docs. + let vis = vis.at_level(Level::Reachable); + if !(vis.is_public() || matches!(vis, Visibility::Restricted(id) if id.is_top_level_module())) { + return false; + } + } else if let Some(id) = self.require_visibility_at + && !vis.at_level(Level::Reexported).is_accessible_from(id, cx.tcx) + { + return false; + } + }, + None => {}, } - if sp.from_expansion() { - return; - } - - if self.crate_items_only && def_id != CRATE_DEF_ID { - let vis = cx.tcx.visibility(def_id); - if vis == Visibility::Public || vis != Visibility::Restricted(CRATE_DEF_ID.into()) { - return; - } - } else if def_id != CRATE_DEF_ID && cx.effective_visibilities.is_exported(def_id) { - return; - } - - if let Some(parent_def_id) = cx.tcx.opt_parent(def_id.to_def_id()) - && let DefKind::AnonConst - | DefKind::AssocConst - | DefKind::AssocFn - | DefKind::Closure - | DefKind::Const - | DefKind::Fn - | DefKind::InlineConst - | DefKind::Static { .. } - | DefKind::SyntheticCoroutineBody = cx.tcx.def_kind(parent_def_id) - { - // Nested item has no generated documentation, so it doesn't need to be documented. - return; - } - - let has_doc = attrs - .iter() - .any(|a| a.doc_str().is_some() || Self::has_include(a.meta_item_list().as_deref())) - || matches!(self.search_span(sp), Some(span) if span_to_snippet_contains_docs(cx, span)); - - if !has_doc { - span_lint( - cx, - MISSING_DOCS_IN_PRIVATE_ITEMS, - sp, - format!("missing documentation for {article} {desc}"), - ); - } - } - - /// Return a span to search for doc comments manually. - /// - /// # Example - /// ```ignore - /// fn foo() { ... } - /// ^^^^^^^^^^^^^^^^ prev_span - /// ↑ - /// | search_span | - /// ↓ - /// fn bar() { ... } - /// ^^^^^^^^^^^^^^^^ cur_span - /// ``` - fn search_span(&self, cur_span: Span) -> Option { - let prev_span = self.prev_span?; - let start_pos = if prev_span.contains(cur_span) { - // In case when the prev_span is an entire struct, or enum, - // and the current span is a field, or variant, we need to search from - // the starting pos of the previous span. - prev_span.lo() - } else { - prev_span.hi() - }; - let search_span = cur_span.with_lo(start_pos).with_hi(cur_span.lo()); - Some(search_span) + !cx.tcx.hir_attrs(hir_id).iter().any(is_doc_attr) } } @@ -176,111 +103,195 @@ impl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]); impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { - let doc_hidden = self.doc_hidden() || is_doc_hidden(attrs); - self.doc_hidden_stack.push(doc_hidden); + self.attr_depth += 1; + if self.doc_hidden_depth == 0 && is_doc_hidden(attrs) { + self.doc_hidden_depth = self.attr_depth; + } } fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [Attribute]) { - self.doc_hidden_stack.pop().expect("empty doc_hidden_stack"); + self.attr_depth -= 1; + if self.attr_depth < self.doc_hidden_depth { + self.doc_hidden_depth = 0; + } + if self.attr_depth < self.automatically_derived_depth { + self.automatically_derived_depth = 0; + } } - fn check_crate(&mut self, cx: &LateContext<'tcx>) { - let attrs = cx.tcx.hir_attrs(hir::CRATE_HIR_ID); - self.check_missing_docs_attrs(cx, CRATE_DEF_ID, attrs, cx.tcx.def_span(CRATE_DEF_ID), "the", "crate"); - } + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { + if self.doc_hidden_depth != 0 || self.automatically_derived_depth != 0 || self.in_body.is_some() { + return; + } - fn check_crate_post(&mut self, _: &LateContext<'tcx>) { - self.prev_span = None; - } - - fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) { - match it.kind { - hir::ItemKind::Fn { ident, .. } => { - // ignore main() - if ident.name == sym::main { - let at_root = cx.tcx.local_parent(it.owner_id.def_id) == CRATE_DEF_ID; - if at_root { - note_prev_span_then_ret!(self.prev_span, it.span); - } + let span = match item.kind { + // ignore main() + ItemKind::Fn { ident, .. } + if ident.name == sym::main && cx.tcx.local_parent(item.owner_id.def_id) == CRATE_DEF_ID => + { + return; + }, + ItemKind::Const(ident, ..) if ident.name == kw::Underscore => return, + ItemKind::Impl { .. } => { + if cx.tcx.is_automatically_derived(item.owner_id.def_id.to_def_id()) { + self.automatically_derived_depth = self.attr_depth; } + return; }, - hir::ItemKind::Const(ident, ..) => { - if ident.name == kw::Underscore { - note_prev_span_then_ret!(self.prev_span, it.span); + ItemKind::ExternCrate(..) + | ItemKind::ForeignMod { .. } + | ItemKind::GlobalAsm { .. } + | ItemKind::Use(..) => return, + + ItemKind::Mod(ident, ..) => { + if item.span.from_expansion() && item.span.eq_ctxt(ident.span) { + self.module_depth += 1; + self.require_visibility_at = cx.tcx.opt_local_parent(item.owner_id.def_id); + self.macro_module_depth = self.module_depth; + return; } + ident.span }, - hir::ItemKind::Enum(..) - | hir::ItemKind::Macro(..) - | hir::ItemKind::Mod(..) - | hir::ItemKind::Static(..) - | hir::ItemKind::Struct(..) - | hir::ItemKind::Trait(..) - | hir::ItemKind::TraitAlias(..) - | hir::ItemKind::TyAlias(..) - | hir::ItemKind::Union(..) => {}, - hir::ItemKind::ExternCrate(..) - | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::GlobalAsm { .. } - | hir::ItemKind::Impl { .. } - | hir::ItemKind::Use(..) => note_prev_span_then_ret!(self.prev_span, it.span), - } - let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id()); + ItemKind::Const(ident, ..) + | ItemKind::Enum(ident, ..) + | ItemKind::Fn { ident, .. } + | ItemKind::Macro(ident, ..) + | ItemKind::Static(_, ident, ..) + | ItemKind::Struct(ident, ..) + | ItemKind::Trait(_, _, _, ident, ..) + | ItemKind::TraitAlias(_, ident, ..) + | ItemKind::TyAlias(ident, ..) + | ItemKind::Union(ident, ..) => ident.span, + }; - let attrs = cx.tcx.hir_attrs(it.hir_id()); - if !is_from_proc_macro(cx, it) { - self.check_missing_docs_attrs(cx, it.owner_id.def_id, attrs, it.span, article, desc); - } - self.prev_span = Some(it.span); - } - - fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) { - let (article, desc) = cx.tcx.article_and_description(trait_item.owner_id.to_def_id()); - - let attrs = cx.tcx.hir_attrs(trait_item.hir_id()); - if !is_from_proc_macro(cx, trait_item) { - self.check_missing_docs_attrs(cx, trait_item.owner_id.def_id, attrs, trait_item.span, article, desc); - } - self.prev_span = Some(trait_item.span); - } - - fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { - // If the method is an impl for a trait, don't doc. - match cx.tcx.associated_item(impl_item.owner_id).container { - AssocContainer::Trait | AssocContainer::TraitImpl(_) => { - note_prev_span_then_ret!(self.prev_span, impl_item.span); - }, - AssocContainer::InherentImpl => {}, - } - - let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id()); - let attrs = cx.tcx.hir_attrs(impl_item.hir_id()); - if !is_from_proc_macro(cx, impl_item) { - self.check_missing_docs_attrs(cx, impl_item.owner_id.def_id, attrs, impl_item.span, article, desc); - } - self.prev_span = Some(impl_item.span); - } - - fn check_field_def(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::FieldDef<'_>) { - if !(sf.is_positional() - || is_from_proc_macro(cx, sf) - || self.allow_unused && sf.ident.as_str().starts_with('_')) + if !item.span.from_expansion() + && self.is_missing_docs(cx, item.owner_id.def_id, item.hir_id()) + && !is_from_proc_macro(cx, item) { - let attrs = cx.tcx.hir_attrs(sf.hir_id); - self.check_missing_docs_attrs(cx, sf.def_id, attrs, sf.span, "a", "struct field"); + let (article, desc) = cx.tcx.article_and_description(item.owner_id.to_def_id()); + span_lint( + cx, + MISSING_DOCS_IN_PRIVATE_ITEMS, + span, + format!("missing documentation for {article} {desc}"), + ); + } + if matches!(item.kind, ItemKind::Mod(..)) { + self.module_depth += 1; } - self.prev_span = Some(sf.span); } - fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) { - let attrs = cx.tcx.hir_attrs(v.hir_id); - if !is_from_proc_macro(cx, v) { - self.check_missing_docs_attrs(cx, v.def_id, attrs, v.span, "a", "variant"); + fn check_item_post(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { + if matches!(item.kind, ItemKind::Mod(..)) + && self.doc_hidden_depth == 0 + && self.automatically_derived_depth == 0 + && self.in_body.is_none() + { + self.module_depth -= 1; + if self.module_depth < self.macro_module_depth { + self.require_visibility_at = None; + } + } + } + + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { + if self.doc_hidden_depth == 0 + && self.automatically_derived_depth == 0 + && self.in_body.is_none() + && !item.span.from_expansion() + && self.is_missing_docs(cx, item.owner_id.def_id, item.hir_id()) + && !is_from_proc_macro(cx, item) + { + let (article, desc) = cx.tcx.article_and_description(item.owner_id.to_def_id()); + span_lint( + cx, + MISSING_DOCS_IN_PRIVATE_ITEMS, + item.ident.span, + format!("missing documentation for {article} {desc}"), + ); + } + } + + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { + if self.doc_hidden_depth == 0 + && self.automatically_derived_depth == 0 + && self.in_body.is_none() + && let Node::Item(parent) = cx.tcx.parent_hir_node(item.hir_id()) + && let ItemKind::Impl(impl_) = parent.kind + && impl_.of_trait.is_none() + && !item.span.from_expansion() + && self.is_missing_docs(cx, item.owner_id.def_id, item.hir_id()) + && !is_from_proc_macro(cx, item) + { + let (article, desc) = cx.tcx.article_and_description(item.owner_id.to_def_id()); + span_lint( + cx, + MISSING_DOCS_IN_PRIVATE_ITEMS, + item.ident.span, + format!("missing documentation for {article} {desc}"), + ); + } + } + + fn check_body(&mut self, _: &LateContext<'tcx>, body: &Body<'tcx>) { + if self.doc_hidden_depth == 0 && self.automatically_derived_depth == 0 && self.in_body.is_none() { + self.in_body = Some(body.id()); + } + } + + fn check_body_post(&mut self, _: &LateContext<'tcx>, body: &Body<'tcx>) { + if self.in_body == Some(body.id()) { + self.in_body = None; + } + } + + fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &'tcx FieldDef<'_>) { + if self.doc_hidden_depth == 0 + && self.automatically_derived_depth == 0 + && self.in_body.is_none() + && !field.is_positional() + && !field.span.from_expansion() + && !(self.allow_unused && field.ident.name.as_str().starts_with('_')) + && self.is_missing_docs(cx, field.def_id, field.hir_id) + && !is_from_proc_macro(cx, field) + { + span_lint( + cx, + MISSING_DOCS_IN_PRIVATE_ITEMS, + field.ident.span, + "missing documentation for a field", + ); + } + } + + fn check_variant(&mut self, cx: &LateContext<'tcx>, variant: &'tcx Variant<'_>) { + if self.doc_hidden_depth == 0 + && self.automatically_derived_depth == 0 + && self.in_body.is_none() + && !variant.span.from_expansion() + && self.is_missing_docs(cx, variant.def_id, variant.hir_id) + && !is_from_proc_macro(cx, variant) + { + span_lint( + cx, + MISSING_DOCS_IN_PRIVATE_ITEMS, + variant.ident.span, + "missing documentation for a variant", + ); } - self.prev_span = Some(v.span); } } -fn span_to_snippet_contains_docs(cx: &LateContext<'_>, search_span: Span) -> bool { - search_span.check_source_text(cx, |src| src.lines().rev().any(|line| line.trim().starts_with("///"))) +fn is_doc_attr(attr: &Attribute) -> bool { + match attr { + Attribute::Parsed(AttributeKind::DocComment { .. }) => true, + Attribute::Unparsed(attr) + if let [ident] = &*attr.path.segments + && ident.name == sym::doc => + { + matches!(attr.args, AttrArgs::Eq { .. }) + }, + _ => false, + } } diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index bc5e72270f4e..80cf081992cc 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -1,13 +1,13 @@ use clippy_utils::desugar_await; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::visitors::{Descend, Visitable, for_each_expr}; -use core::ops::ControlFlow::Continue; use hir::def::{DefKind, Res}; use hir::{BlockCheckMode, ExprKind, QPath, UnOp}; -use rustc_ast::Mutability; +use rustc_ast::{BorrowKind, Mutability}; use rustc_hir as hir; +use rustc_hir::intravisit::{Visitor, walk_body, walk_expr}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; +use rustc_middle::hir::nested_filter; +use rustc_middle::ty::{self, TyCtxt, TypeckResults}; use rustc_session::declare_lint_pass; use rustc_span::{DesugaringKind, Span}; @@ -55,6 +55,13 @@ declare_clippy_lint! { /// unsafe { char::from_u32_unchecked(int_value) } /// } /// ``` + /// + /// ### Note + /// + /// Taking a raw pointer to a union field is always safe and will + /// not be considered unsafe by this lint, even when linting code written + /// with a specified Rust version of 1.91 or earlier (which required + /// using an `unsafe` block). #[clippy::version = "1.69.0"] pub MULTIPLE_UNSAFE_OPS_PER_BLOCK, restriction, @@ -70,8 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock { { return; } - let mut unsafe_ops = vec![]; - collect_unsafe_exprs(cx, block, &mut unsafe_ops); + let unsafe_ops = UnsafeExprCollector::collect_unsafe_exprs(cx, block); if unsafe_ops.len() > 1 { span_lint_and_then( cx, @@ -91,25 +97,49 @@ impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock { } } -fn collect_unsafe_exprs<'tcx>( - cx: &LateContext<'tcx>, - node: impl Visitable<'tcx>, - unsafe_ops: &mut Vec<(&'static str, Span)>, -) { - for_each_expr(cx, node, |expr| { +struct UnsafeExprCollector<'tcx> { + tcx: TyCtxt<'tcx>, + typeck_results: &'tcx TypeckResults<'tcx>, + unsafe_ops: Vec<(&'static str, Span)>, +} + +impl<'tcx> UnsafeExprCollector<'tcx> { + fn collect_unsafe_exprs(cx: &LateContext<'tcx>, block: &'tcx hir::Block<'tcx>) -> Vec<(&'static str, Span)> { + let mut collector = Self { + tcx: cx.tcx, + typeck_results: cx.typeck_results(), + unsafe_ops: vec![], + }; + collector.visit_block(block); + collector.unsafe_ops + } +} + +impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { + type NestedFilter = nested_filter::OnlyBodies; + + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { match expr.kind { // The `await` itself will desugar to two unsafe calls, but we should ignore those. // Instead, check the expression that is `await`ed _ if let Some(e) = desugar_await(expr) => { - collect_unsafe_exprs(cx, e, unsafe_ops); - return Continue(Descend::No); + return self.visit_expr(e); }, - ExprKind::InlineAsm(_) => unsafe_ops.push(("inline assembly used here", expr.span)), + ExprKind::InlineAsm(_) => self.unsafe_ops.push(("inline assembly used here", expr.span)), + + ExprKind::AddrOf(BorrowKind::Raw, _, mut inner) => { + while let ExprKind::Field(prefix, _) = inner.kind + && self.typeck_results.expr_adjustments(prefix).is_empty() + { + inner = prefix; + } + return self.visit_expr(inner); + }, ExprKind::Field(e, _) => { - if cx.typeck_results().expr_ty(e).is_union() { - unsafe_ops.push(("union field access occurs here", expr.span)); + if self.typeck_results.expr_ty(e).is_union() { + self.unsafe_ops.push(("union field access occurs here", expr.span)); } }, @@ -127,32 +157,32 @@ fn collect_unsafe_exprs<'tcx>( .. }, )) => { - unsafe_ops.push(("access of a mutable static occurs here", expr.span)); + self.unsafe_ops + .push(("access of a mutable static occurs here", expr.span)); }, - ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty_adjusted(e).is_raw_ptr() => { - unsafe_ops.push(("raw pointer dereference occurs here", expr.span)); + ExprKind::Unary(UnOp::Deref, e) if self.typeck_results.expr_ty(e).is_raw_ptr() => { + self.unsafe_ops.push(("raw pointer dereference occurs here", expr.span)); }, ExprKind::Call(path_expr, _) => { - let sig = match *cx.typeck_results().expr_ty(path_expr).kind() { - ty::FnDef(id, _) => cx.tcx.fn_sig(id).skip_binder(), - ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr), - _ => return Continue(Descend::Yes), + let opt_sig = match *self.typeck_results.expr_ty_adjusted(path_expr).kind() { + ty::FnDef(id, _) => Some(self.tcx.fn_sig(id).skip_binder()), + ty::FnPtr(sig_tys, hdr) => Some(sig_tys.with(hdr)), + _ => None, }; - if sig.safety().is_unsafe() { - unsafe_ops.push(("unsafe function call occurs here", expr.span)); + if opt_sig.is_some_and(|sig| sig.safety().is_unsafe()) { + self.unsafe_ops.push(("unsafe function call occurs here", expr.span)); } }, ExprKind::MethodCall(..) => { - if let Some(sig) = cx - .typeck_results() + let opt_sig = self + .typeck_results .type_dependent_def_id(expr.hir_id) - .map(|def_id| cx.tcx.fn_sig(def_id)) - && sig.skip_binder().safety().is_unsafe() - { - unsafe_ops.push(("unsafe method call occurs here", expr.span)); + .map(|def_id| self.tcx.fn_sig(def_id)); + if opt_sig.is_some_and(|sig| sig.skip_binder().safety().is_unsafe()) { + self.unsafe_ops.push(("unsafe method call occurs here", expr.span)); } }, @@ -173,15 +203,26 @@ fn collect_unsafe_exprs<'tcx>( } )) ) { - unsafe_ops.push(("modification of a mutable static occurs here", expr.span)); - collect_unsafe_exprs(cx, rhs, unsafe_ops); - return Continue(Descend::No); + self.unsafe_ops + .push(("modification of a mutable static occurs here", expr.span)); + return self.visit_expr(rhs); } }, _ => {}, } - Continue::<(), _>(Descend::Yes) - }); + walk_expr(self, expr); + } + + fn visit_body(&mut self, body: &hir::Body<'tcx>) { + let saved_typeck_results = self.typeck_results; + self.typeck_results = self.tcx.typeck_body(body.id()); + walk_body(self, body); + self.typeck_results = saved_typeck_results; + } + + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.tcx + } } diff --git a/clippy_lints/src/ptr/ptr_arg.rs b/clippy_lints/src/ptr/ptr_arg.rs index fd9230f00a8b..4bfff64b1bd4 100644 --- a/clippy_lints/src/ptr/ptr_arg.rs +++ b/clippy_lints/src/ptr/ptr_arg.rs @@ -2,7 +2,7 @@ use super::PTR_ARG; use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::res::MaybeResPath; use clippy_utils::source::SpanRangeExt; -use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, sym}; +use clippy_utils::{VEC_METHODS_SHADOWING_SLICE_METHODS, get_expr_use_or_unification_node, is_lint_allowed, sym}; use hir::LifetimeKind; use rustc_abi::ExternAbi; use rustc_errors::Applicability; @@ -23,8 +23,6 @@ use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use std::{fmt, iter}; -use crate::vec::is_allowed_vec_method; - pub(super) fn check_body<'tcx>( cx: &LateContext<'tcx>, body: &Body<'tcx>, @@ -383,7 +381,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[ // Some methods exist on both `[T]` and `Vec`, such as `len`, where the receiver type // doesn't coerce to a slice and our adjusted type check below isn't enough, // but it would still be valid to call with a slice - if is_allowed_vec_method(use_expr) { + if VEC_METHODS_SHADOWING_SLICE_METHODS.contains(&name) { return; } } diff --git a/clippy_lints/src/time_subtraction.rs b/clippy_lints/src/time_subtraction.rs index dbd4ec77fd5f..e0fdca97dbee 100644 --- a/clippy_lints/src/time_subtraction.rs +++ b/clippy_lints/src/time_subtraction.rs @@ -1,5 +1,5 @@ use clippy_config::Conf; -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; use clippy_utils::sugg::Sugg; @@ -109,36 +109,16 @@ impl LateLintPass<'_> for UncheckedTimeSubtraction { && !expr.span.from_expansion() && self.msrv.meets(cx, msrvs::TRY_FROM) { - // For chained subtraction like (instant - dur1) - dur2, avoid suggestions - if is_chained_time_subtraction(cx, lhs) { - span_lint( - cx, - UNCHECKED_TIME_SUBTRACTION, - expr.span, - "unchecked subtraction of a 'Duration' from an 'Instant'", - ); - } else { - // instant - duration - print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); - } + print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); } - } else if lhs_ty.is_diag_item(cx, sym::Duration) + } + // duration - duration + else if lhs_ty.is_diag_item(cx, sym::Duration) && rhs_ty.is_diag_item(cx, sym::Duration) && !expr.span.from_expansion() && self.msrv.meets(cx, msrvs::TRY_FROM) { - // For chained subtraction like (dur1 - dur2) - dur3, avoid suggestions - if is_chained_time_subtraction(cx, lhs) { - span_lint( - cx, - UNCHECKED_TIME_SUBTRACTION, - expr.span, - "unchecked subtraction between 'Duration' values", - ); - } else { - // duration - duration - print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); - } + print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); } } } @@ -191,26 +171,26 @@ fn print_unchecked_duration_subtraction_sugg( right_expr: &Expr<'_>, expr: &Expr<'_>, ) { - let typeck = cx.typeck_results(); - let left_ty = typeck.expr_ty(left_expr); - - let lint_msg = if left_ty.is_diag_item(cx, sym::Instant) { - "unchecked subtraction of a 'Duration' from an 'Instant'" - } else { - "unchecked subtraction between 'Duration' values" - }; - - let mut applicability = Applicability::MachineApplicable; - let left_sugg = Sugg::hir_with_applicability(cx, left_expr, "", &mut applicability); - let right_sugg = Sugg::hir_with_applicability(cx, right_expr, "", &mut applicability); - - span_lint_and_sugg( + span_lint_and_then( cx, UNCHECKED_TIME_SUBTRACTION, expr.span, - lint_msg, - "try", - format!("{}.checked_sub({}).unwrap()", left_sugg.maybe_paren(), right_sugg), - applicability, + "unchecked subtraction of a `Duration`", + |diag| { + // For chained subtraction, like `(dur1 - dur2) - dur3` or `(instant - dur1) - dur2`, + // avoid suggestions + if !is_chained_time_subtraction(cx, left_expr) { + let mut applicability = Applicability::MachineApplicable; + let left_sugg = Sugg::hir_with_applicability(cx, left_expr, "", &mut applicability); + let right_sugg = Sugg::hir_with_applicability(cx, right_expr, "", &mut applicability); + + diag.span_suggestion( + expr.span, + "try", + format!("{}.checked_sub({}).unwrap()", left_sugg.maybe_paren(), right_sugg), + applicability, + ); + } + }, ); } diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs index 933e25fe98c6..91fce5d5bd68 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs @@ -17,6 +17,8 @@ pub(super) fn check<'tcx>( arg: &'tcx Expr<'_>, msrv: Msrv, ) -> bool { + let mut applicability = Applicability::MachineApplicable; + let arg_sugg = sugg::Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut applicability); match (from_ty.kind(), to_ty.kind()) { (ty::RawPtr(from_pointee_ty, from_mutbl), ty::RawPtr(to_pointee_ty, to_mutbl)) => { span_lint_and_then( @@ -25,40 +27,38 @@ pub(super) fn check<'tcx>( e.span, "transmute from a pointer to a pointer", |diag| { - if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) { - if from_mutbl == to_mutbl - && to_pointee_ty.is_sized(cx.tcx, cx.typing_env()) - && msrv.meets(cx, msrvs::POINTER_CAST) - { - diag.span_suggestion_verbose( - e.span, - "use `pointer::cast` instead", - format!("{}.cast::<{to_pointee_ty}>()", arg.maybe_paren()), - Applicability::MaybeIncorrect, - ); - } else if from_pointee_ty == to_pointee_ty - && let Some(method) = match (from_mutbl, to_mutbl) { - (ty::Mutability::Not, ty::Mutability::Mut) => Some("cast_mut"), - (ty::Mutability::Mut, ty::Mutability::Not) => Some("cast_const"), - _ => None, - } - && !from_pointee_ty.has_erased_regions() - && msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS) - { - diag.span_suggestion_verbose( - e.span, - format!("use `pointer::{method}` instead"), - format!("{}.{method}()", arg.maybe_paren()), - Applicability::MaybeIncorrect, - ); - } else { - diag.span_suggestion_verbose( - e.span, - "use an `as` cast instead", - arg.as_ty(to_ty), - Applicability::MaybeIncorrect, - ); + if from_mutbl == to_mutbl + && to_pointee_ty.is_sized(cx.tcx, cx.typing_env()) + && msrv.meets(cx, msrvs::POINTER_CAST) + { + diag.span_suggestion_verbose( + e.span, + "use `pointer::cast` instead", + format!("{}.cast::<{to_pointee_ty}>()", arg_sugg.maybe_paren()), + Applicability::MaybeIncorrect, + ); + } else if from_pointee_ty == to_pointee_ty + && let Some(method) = match (from_mutbl, to_mutbl) { + (ty::Mutability::Not, ty::Mutability::Mut) => Some("cast_mut"), + (ty::Mutability::Mut, ty::Mutability::Not) => Some("cast_const"), + _ => None, } + && !from_pointee_ty.has_erased_regions() + && msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS) + { + diag.span_suggestion_verbose( + e.span, + format!("use `pointer::{method}` instead"), + format!("{}.{method}()", arg_sugg.maybe_paren()), + Applicability::MaybeIncorrect, + ); + } else { + diag.span_suggestion_verbose( + e.span, + "use an `as` cast instead", + arg_sugg.as_ty(to_ty), + Applicability::MaybeIncorrect, + ); } }, ); diff --git a/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/clippy_lints/src/transmute/transmute_ref_to_ref.rs index 70c2a73ce6ef..39b1ccdc9426 100644 --- a/clippy_lints/src/transmute/transmute_ref_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ref_to_ref.rs @@ -1,6 +1,5 @@ use super::{TRANSMUTE_BYTES_TO_STR, TRANSMUTE_PTR_TO_PTR}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::source::snippet; use clippy_utils::{std_or_core, sugg}; use rustc_errors::Applicability; use rustc_hir::{Expr, Mutability}; @@ -17,8 +16,7 @@ pub(super) fn check<'tcx>( arg: &'tcx Expr<'_>, const_context: bool, ) -> bool { - let mut triggered = false; - + let arg_sugg = || sugg::Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut Applicability::Unspecified); if let (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) = (*from_ty.kind(), *to_ty.kind()) { if let ty::Slice(slice_ty) = *ty_from.kind() && ty_to.is_str() @@ -29,8 +27,6 @@ pub(super) fn check<'tcx>( let postfix = if from_mutbl == Mutability::Mut { "_mut" } else { "" }; - let snippet = snippet(cx, arg.span, ".."); - span_lint_and_sugg( cx, TRANSMUTE_BYTES_TO_STR, @@ -38,15 +34,17 @@ pub(super) fn check<'tcx>( format!("transmute from a `{from_ty}` to a `{to_ty}`"), "consider using", if const_context { - format!("{top_crate}::str::from_utf8_unchecked{postfix}({snippet})") + format!("{top_crate}::str::from_utf8_unchecked{postfix}({})", arg_sugg()) } else { - format!("{top_crate}::str::from_utf8{postfix}({snippet}).unwrap()") + format!("{top_crate}::str::from_utf8{postfix}({}).unwrap()", arg_sugg()) }, Applicability::MaybeIncorrect, ); - triggered = true; - } else if (cx.tcx.erase_and_anonymize_regions(from_ty) != cx.tcx.erase_and_anonymize_regions(to_ty)) - && !const_context + + return true; + } + + if (cx.tcx.erase_and_anonymize_regions(from_ty) != cx.tcx.erase_and_anonymize_regions(to_ty)) && !const_context { span_lint_and_then( cx, @@ -54,23 +52,21 @@ pub(super) fn check<'tcx>( e.span, "transmute from a reference to a reference", |diag| { - if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) { - let sugg_paren = arg - .as_ty(Ty::new_ptr(cx.tcx, ty_from, from_mutbl)) - .as_ty(Ty::new_ptr(cx.tcx, ty_to, to_mutbl)); - let sugg = if to_mutbl == Mutability::Mut { - sugg_paren.mut_addr_deref() - } else { - sugg_paren.addr_deref() - }; - diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified); - } + let sugg_paren = arg_sugg() + .as_ty(Ty::new_ptr(cx.tcx, ty_from, from_mutbl)) + .as_ty(Ty::new_ptr(cx.tcx, ty_to, to_mutbl)); + let sugg = if to_mutbl == Mutability::Mut { + sugg_paren.mut_addr_deref() + } else { + sugg_paren.addr_deref() + }; + diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified); }, ); - triggered = true; + return true; } } - triggered + false } diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index 99201a1ca215..8ed3df8731b3 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -1,15 +1,21 @@ +use std::borrow::Cow; +use std::iter; + use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::msrvs::Msrv; use clippy_utils::res::{MaybeDef, MaybeResPath}; +use clippy_utils::source::snippet; use clippy_utils::usage::is_potentially_local_place; use clippy_utils::{can_use_if_let_chains, higher, sym}; +use rustc_abi::FieldIdx; use rustc_errors::Applicability; use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn}; use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, UnOp}; -use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceWithHirId}; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, Place, PlaceWithHirId}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::nested_filter; +use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::impl_lint_pass; @@ -114,11 +120,91 @@ impl UnwrappableKind { } } +#[derive(Clone, Debug, Eq)] +enum Local { + /// `x.field1.field2.field3` + WithFieldAccess { + local_id: HirId, + /// The indices of the field accessed. + /// + /// Stored last-to-first, e.g. for the example above: `[field3, field2, field1]` + field_indices: Vec, + /// The span of the whole expression + span: Span, + }, + /// `x` + Pure { local_id: HirId }, +} + +/// Identical to derived impl, but ignores `span` on [`Local::WithFieldAccess`] +impl PartialEq for Local { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + ( + Self::WithFieldAccess { + local_id: self_local_id, + field_indices: self_field_indices, + .. + }, + Self::WithFieldAccess { + local_id: other_local_id, + field_indices: other_field_indices, + .. + }, + ) => self_local_id == other_local_id && self_field_indices == other_field_indices, + ( + Self::Pure { + local_id: self_local_id, + }, + Self::Pure { + local_id: other_local_id, + }, + ) => self_local_id == other_local_id, + _ => false, + } + } +} + +impl Local { + fn snippet(&self, cx: &LateContext<'_>) -> Cow<'static, str> { + match *self { + Self::WithFieldAccess { span, .. } => snippet(cx.sess(), span, "_"), + Self::Pure { local_id } => cx.tcx.hir_name(local_id).to_string().into(), + } + } + + fn is_potentially_local_place(&self, place: &Place<'_>) -> bool { + match self { + Self::WithFieldAccess { + local_id, + field_indices, + .. + } => { + is_potentially_local_place(*local_id, place) + // If there were projections other than field projections, err on the side of caution and say that they + // _might_ be mutating something. + // + // The reason we use `<=` and not `==` is that a mutation of `struct` or `struct.field1` should count as + // mutation of the child fields such as `struct.field1.field2` + && place.projections.len() <= field_indices.len() + && iter::zip(&place.projections, field_indices.iter().copied().rev()).all(|(proj, field_idx)| { + match proj.kind { + ProjectionKind::Field(f_idx, _) => f_idx == field_idx, + // If this is a projection we don't expect, it _might_ be mutating something + _ => false, + } + }) + }, + Self::Pure { local_id } => is_potentially_local_place(*local_id, place), + } + } +} + /// Contains information about whether a variable can be unwrapped. -#[derive(Copy, Clone, Debug)] +#[derive(Clone, Debug)] struct UnwrapInfo<'tcx> { /// The variable that is checked - local_id: HirId, + local: Local, /// The if itself if_expr: &'tcx Expr<'tcx>, /// The check, like `x.is_ok()` @@ -156,38 +242,77 @@ fn collect_unwrap_info<'tcx>( } } - match expr.kind { - ExprKind::Binary(op, left, right) - if matches!( - (invert, op.node), - (false, BinOpKind::And | BinOpKind::BitAnd) | (true, BinOpKind::Or | BinOpKind::BitOr) - ) => - { - let mut unwrap_info = collect_unwrap_info(cx, if_expr, left, branch, invert, false); - unwrap_info.extend(collect_unwrap_info(cx, if_expr, right, branch, invert, false)); - unwrap_info - }, - ExprKind::Unary(UnOp::Not, expr) => collect_unwrap_info(cx, if_expr, expr, branch, !invert, false), - ExprKind::MethodCall(method_name, receiver, [], _) - if let Some(local_id) = receiver.res_local_id() - && let ty = cx.typeck_results().expr_ty(receiver) - && let name = method_name.ident.name - && let Some((kind, unwrappable)) = option_or_result_call(cx, ty, name) => - { - let safe_to_unwrap = unwrappable != invert; + fn inner<'tcx>( + cx: &LateContext<'tcx>, + if_expr: &'tcx Expr<'_>, + expr: &'tcx Expr<'_>, + branch: &'tcx Expr<'_>, + invert: bool, + is_entire_condition: bool, + out: &mut Vec>, + ) { + match expr.kind { + ExprKind::Binary(op, left, right) + if matches!( + (invert, op.node), + (false, BinOpKind::And | BinOpKind::BitAnd) | (true, BinOpKind::Or | BinOpKind::BitOr) + ) => + { + inner(cx, if_expr, left, branch, invert, false, out); + inner(cx, if_expr, right, branch, invert, false, out); + }, + ExprKind::Unary(UnOp::Not, expr) => inner(cx, if_expr, expr, branch, !invert, false, out), + ExprKind::MethodCall(method_name, receiver, [], _) + if let Some(local) = extract_local(cx, receiver) + && let ty = cx.typeck_results().expr_ty(receiver) + && let name = method_name.ident.name + && let Some((kind, unwrappable)) = option_or_result_call(cx, ty, name) => + { + let safe_to_unwrap = unwrappable != invert; - vec![UnwrapInfo { + out.push(UnwrapInfo { + local, + if_expr, + check: expr, + check_name: name, + branch, + safe_to_unwrap, + kind, + is_entire_condition, + }); + }, + _ => {}, + } + } + + let mut out = vec![]; + inner(cx, if_expr, expr, branch, invert, is_entire_condition, &mut out); + out +} + +/// Extracts either a local used by itself ([`Local::Pure`]), or (one or more levels of) field +/// access to a local ([`Local::WithFieldAccess`]) +fn extract_local(cx: &LateContext<'_>, mut expr: &Expr<'_>) -> Option { + let span = expr.span; + let mut field_indices = vec![]; + while let ExprKind::Field(recv, _) = expr.kind + && let Some(field_idx) = cx.typeck_results().opt_field_index(expr.hir_id) + { + field_indices.push(field_idx); + expr = recv; + } + if let Some(local_id) = expr.res_local_id() { + if field_indices.is_empty() { + Some(Local::Pure { local_id }) + } else { + Some(Local::WithFieldAccess { local_id, - if_expr, - check: expr, - check_name: name, - branch, - safe_to_unwrap, - kind, - is_entire_condition, - }] - }, - _ => vec![], + field_indices, + span, + }) + } + } else { + None } } @@ -198,9 +323,9 @@ fn collect_unwrap_info<'tcx>( /// `is_some` + `unwrap` is equivalent to `if let Some(..) = ..`, which it would not be if /// the option is changed to None between `is_some` and `unwrap`, ditto for `Result`. /// (And also `.as_mut()` is a somewhat common method that is still worth linting on.) -struct MutationVisitor<'tcx> { +struct MutationVisitor<'tcx, 'lcl> { is_mutated: bool, - local_id: HirId, + local: &'lcl Local, tcx: TyCtxt<'tcx>, } @@ -221,10 +346,10 @@ fn is_as_mut_use(tcx: TyCtxt<'_>, expr_id: HirId) -> bool { } } -impl<'tcx> Delegate<'tcx> for MutationVisitor<'tcx> { +impl<'tcx> Delegate<'tcx> for MutationVisitor<'tcx, '_> { fn borrow(&mut self, cat: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) { if let ty::BorrowKind::Mutable = bk - && is_potentially_local_place(self.local_id, &cat.place) + && self.local.is_potentially_local_place(&cat.place) && !is_as_mut_use(self.tcx, diag_expr_id) { self.is_mutated = true; @@ -232,7 +357,7 @@ impl<'tcx> Delegate<'tcx> for MutationVisitor<'tcx> { } fn mutate(&mut self, cat: &PlaceWithHirId<'tcx>, _: HirId) { - if is_potentially_local_place(self.local_id, &cat.place) { + if self.local.is_potentially_local_place(&cat.place) { self.is_mutated = true; } } @@ -256,7 +381,7 @@ impl<'tcx> UnwrappableVariablesVisitor<'_, 'tcx> { for unwrap_info in collect_unwrap_info(self.cx, if_expr, cond, branch, else_branch, true) { let mut delegate = MutationVisitor { is_mutated: false, - local_id: unwrap_info.local_id, + local: &unwrap_info.local, tcx: self.cx.tcx, }; @@ -318,24 +443,17 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> { // find `unwrap[_err]()` or `expect("...")` calls: if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind && let (self_arg, as_ref_kind) = consume_option_as_ref(self_arg) - && let Some(id) = self_arg.res_local_id() + && let Some(local) = extract_local(self.cx, self_arg) && matches!(method_name.ident.name, sym::unwrap | sym::expect | sym::unwrap_err) && let call_to_unwrap = matches!(method_name.ident.name, sym::unwrap | sym::expect) - && let Some(unwrappable) = self.unwrappables.iter() - .find(|u| u.local_id == id) + && let Some(unwrappable) = self.unwrappables.iter().find(|u| u.local == local) // Span contexts should not differ with the conditional branch && let span_ctxt = expr.span.ctxt() && unwrappable.branch.span.ctxt() == span_ctxt && unwrappable.check.span.ctxt() == span_ctxt { if call_to_unwrap == unwrappable.safe_to_unwrap { - let is_entire_condition = unwrappable.is_entire_condition; - let unwrappable_variable_name = self.cx.tcx.hir_name(unwrappable.local_id); - let suggested_pattern = if call_to_unwrap { - unwrappable.kind.success_variant_pattern() - } else { - unwrappable.kind.error_variant_pattern() - }; + let unwrappable_variable_str = unwrappable.local.snippet(self.cx); span_lint_hir_and_then( self.cx, @@ -343,16 +461,21 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> { expr.hir_id, expr.span, format!( - "called `{}` on `{unwrappable_variable_name}` after checking its variant with `{}`", + "called `{}` on `{unwrappable_variable_str}` after checking its variant with `{}`", method_name.ident.name, unwrappable.check_name, ), |diag| { - if is_entire_condition { + if unwrappable.is_entire_condition { diag.span_suggestion( unwrappable.check.span.with_lo(unwrappable.if_expr.span.lo()), "try", format!( - "if let {suggested_pattern} = {borrow_prefix}{unwrappable_variable_name}", + "if let {suggested_pattern} = {borrow_prefix}{unwrappable_variable_str}", + suggested_pattern = if call_to_unwrap { + unwrappable.kind.success_variant_pattern() + } else { + unwrappable.kind.error_variant_pattern() + }, borrow_prefix = match as_ref_kind { Some(AsRefKind::AsRef) => "&", Some(AsRefKind::AsMut) => "&mut ", diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/useless_vec.rs similarity index 90% rename from clippy_lints/src/vec.rs rename to clippy_lints/src/useless_vec.rs index b87db836869d..28c339ce2b7d 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/useless_vec.rs @@ -10,7 +10,7 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_local_use_after_expr; -use clippy_utils::{get_parent_expr, higher, is_in_test, span_contains_comment, sym}; +use clippy_utils::{VEC_METHODS_SHADOWING_SLICE_METHODS, get_parent_expr, higher, is_in_test, span_contains_comment}; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -123,8 +123,16 @@ impl UselessVec { // allow indexing into a vec and some set of allowed method calls that exist on slices, too if let Some(parent) = get_parent_expr(cx, expr) && (adjusts_to_slice(cx, expr) - || matches!(parent.kind, ExprKind::Index(..)) - || is_allowed_vec_method(parent)) + || match parent.kind { + ExprKind::Index(..) => true, + ExprKind::MethodCall(path, _, [], _) => { + // If the given expression is a method call to a `Vec` method that also exists on + // slices, it means that this expression does not actually require a `Vec` and could + // just work with an array. + VEC_METHODS_SHADOWING_SLICE_METHODS.contains(&path.ident.name) + }, + _ => false, + }) { ControlFlow::Continue(()) } else { @@ -144,8 +152,9 @@ impl UselessVec { VecToArray::Impossible }, // search for `for _ in vec![...]` - Node::Expr(Expr { span, .. }) - if span.is_desugaring(DesugaringKind::ForLoop) && self.msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) => + Node::Expr(expr) + if expr.span.is_desugaring(DesugaringKind::ForLoop) + && self.msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) => { VecToArray::Possible }, @@ -276,9 +285,8 @@ impl SuggestedType { assert!(args_span.is_none_or(|s| !s.from_expansion())); assert!(len_span.is_none_or(|s| !s.from_expansion())); - let maybe_args = args_span - .map(|sp| sp.get_source_text(cx).expect("spans are always crate-local")) - .map_or(String::new(), |x| x.to_owned()); + let maybe_args = args_span.map(|sp| sp.get_source_text(cx).expect("spans are always crate-local")); + let maybe_args = maybe_args.as_deref().unwrap_or_default(); let maybe_len = len_span .map(|sp| sp.get_source_text(cx).expect("spans are always crate-local")) .map(|st| format!("; {st}")) @@ -301,17 +309,6 @@ fn adjusts_to_slice(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { matches!(cx.typeck_results().expr_ty_adjusted(e).kind(), ty::Ref(_, ty, _) if ty.is_slice()) } -/// Checks if the given expression is a method call to a `Vec` method -/// that also exists on slices. If this returns true, it means that -/// this expression does not actually require a `Vec` and could just work with an array. -pub fn is_allowed_vec_method(e: &Expr<'_>) -> bool { - if let ExprKind::MethodCall(path, _, [], _) = e.kind { - matches!(path.ident.name, sym::as_ptr | sym::is_empty | sym::len) - } else { - false - } -} - fn suggest_type(expr: &Expr<'_>) -> SuggestedType { if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind { // `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.) diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 6f976094fc2d..4b1a10a3d9cf 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-11-14 +nightly-2025-11-28 ``` diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index 4bdbfc885366..27b5a57c737d 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -43,7 +43,7 @@ pub fn eq_pat(l: &Pat, r: &Pat) -> bool { (Range(lf, lt, le), Range(rf, rt, re)) => { eq_expr_opt(lf.as_deref(), rf.as_deref()) && eq_expr_opt(lt.as_deref(), rt.as_deref()) - && eq_range_end(&le.node, &re.node) + && eq_range_end(le.node, re.node) }, (Box(l), Box(r)) => eq_pat(l, r), (Ref(l, l_pin, l_mut), Ref(r, r_pin, r_mut)) => l_pin == r_pin && l_mut == r_mut && eq_pat(l, r), @@ -64,7 +64,7 @@ pub fn eq_pat(l: &Pat, r: &Pat) -> bool { } } -pub fn eq_range_end(l: &RangeEnd, r: &RangeEnd) -> bool { +pub fn eq_range_end(l: RangeEnd, r: RangeEnd) -> bool { match (l, r) { (RangeEnd::Excluded, RangeEnd::Excluded) => true, (RangeEnd::Included(l), RangeEnd::Included(r)) => { diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 50d9136b8b4d..d9254fca9453 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -265,7 +265,14 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) { ItemKind::Trait(_, IsAuto::Yes, ..) => (Pat::Str("auto"), Pat::Str("}")), ItemKind::Trait(..) => (Pat::Str("trait"), Pat::Str("}")), ItemKind::Impl(_) => (Pat::Str("impl"), Pat::Str("}")), - _ => return (Pat::Str(""), Pat::Str("")), + ItemKind::Mod(..) => (Pat::Str("mod"), Pat::Str("")), + ItemKind::Macro(_, def, _) => ( + Pat::Str(if def.macro_rules { "macro_rules" } else { "macro" }), + Pat::Str(""), + ), + ItemKind::TraitAlias(..) => (Pat::Str("trait"), Pat::Str(";")), + ItemKind::GlobalAsm { .. } => return (Pat::Str("global_asm"), Pat::Str("")), + ItemKind::Use(..) => return (Pat::Str(""), Pat::Str("")), }; if item.vis_span.is_empty() { (start_pat, end_pat) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index c9302b17eb7e..ed164fcf371b 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -136,6 +136,9 @@ use crate::res::{MaybeDef, MaybeQPath, MaybeResPath}; use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type}; use crate::visitors::for_each_expr_without_closures; +/// Methods on `Vec` that also exists on slices. +pub const VEC_METHODS_SHADOWING_SLICE_METHODS: [Symbol; 3] = [sym::as_ptr, sym::is_empty, sym::len]; + #[macro_export] macro_rules! extract_msrv_attr { () => { diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 2593df103527..2ef2afb45071 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -8,7 +8,7 @@ use rustc_ast::util::parser::AssocOp; use rustc_ast::{UnOp, ast}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir::{self as hir, Closure, ExprKind, HirId, MutTy, Node, TyKind}; +use rustc_hir::{self as hir, Closure, ExprKind, HirId, MatchSource, MutTy, Node, TyKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_lint::{EarlyContext, LateContext, LintContext}; use rustc_middle::hir::place::ProjectionKind; @@ -146,7 +146,9 @@ impl<'a> Sugg<'a> { | ExprKind::Let(..) | ExprKind::Closure { .. } | ExprKind::Unary(..) - | ExprKind::Match(..) => Sugg::MaybeParen(get_snippet(expr.span)), + | ExprKind::Match(_, _, + MatchSource::Normal | MatchSource::Postfix | MatchSource::ForLoopDesugar + ) => Sugg::MaybeParen(get_snippet(expr.span)), ExprKind::Continue(..) | ExprKind::Yield(..) | ExprKind::Array(..) @@ -169,7 +171,10 @@ impl<'a> Sugg<'a> { | ExprKind::Tup(..) | ExprKind::Use(..) | ExprKind::Err(_) - | ExprKind::UnsafeBinderCast(..) => Sugg::NonParen(get_snippet(expr.span)), + | ExprKind::UnsafeBinderCast(..) + | ExprKind::Match(_, _, + MatchSource::AwaitDesugar | MatchSource::TryDesugar(_) | MatchSource::FormatArgs + ) => Sugg::NonParen(get_snippet(expr.span)), ExprKind::DropTemps(inner) => Self::hir_from_snippet(cx, inner, get_snippet), ExprKind::Assign(lhs, rhs, _) => { Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span)) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index f6809da98f2b..5157b79832a3 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-11-14" +channel = "nightly-2025-11-28" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" diff --git a/src/driver.rs b/src/driver.rs index 2fc4abe48fe4..8693973ef78c 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -13,12 +13,12 @@ extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; -/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs -/// and https://github.com/rust-lang/rust/pull/146627 for why we need this. +/// See docs in +/// and for why we need this. /// /// FIXME(madsmtm): This is loaded from the sysroot that was built with the other `rustc` crates /// above, instead of via Cargo as you'd normally do. This is currently needed for LTO due to -/// https://github.com/rust-lang/cc-rs/issues/1613. +/// . #[cfg(feature = "jemalloc")] extern crate tikv_jemalloc_sys as _; @@ -191,7 +191,6 @@ fn display_help() { const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml"; -#[expect(clippy::too_many_lines)] pub fn main() { let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); diff --git a/tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs b/tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs deleted file mode 100644 index 155f680c7b13..000000000000 --- a/tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! Test file for missing_docs_in_private_items lint with allow_unused configuration -#![warn(clippy::missing_docs_in_private_items)] -#![allow(dead_code)] - -/// A struct with some documented and undocumented fields -struct Test { - /// This field is documented - field1: i32, - _unused: i32, // This should not trigger a warning because it starts with an underscore - field3: i32, //~ missing_docs_in_private_items -} - -struct Test2 { - //~^ missing_docs_in_private_items - _field1: i32, // This should not trigger a warning - _field2: i32, // This should not trigger a warning -} - -struct Test3 { - //~^ missing_docs_in_private_items - /// This field is documented although this is not mandatory - _unused: i32, // This should not trigger a warning because it starts with an underscore - field2: i32, //~ missing_docs_in_private_items -} - -fn main() {} diff --git a/tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.stderr b/tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.stderr deleted file mode 100644 index 8f511883e900..000000000000 --- a/tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error: missing documentation for a struct field - --> tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs:10:5 - | -LL | field3: i32, - | ^^^^^^^^^^^ - | - = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` - -error: missing documentation for a struct - --> tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs:13:1 - | -LL | / struct Test2 { -LL | | -LL | | _field1: i32, // This should not trigger a warning -LL | | _field2: i32, // This should not trigger a warning -LL | | } - | |_^ - -error: missing documentation for a struct - --> tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs:19:1 - | -LL | / struct Test3 { -LL | | -LL | | /// This field is documented although this is not mandatory -LL | | _unused: i32, // This should not trigger a warning because it starts with an underscore -LL | | field2: i32, -LL | | } - | |_^ - -error: missing documentation for a struct field - --> tests/ui-toml/missing_docs_allow_unused/missing_docs_allow_unused.rs:23:5 - | -LL | field2: i32, - | ^^^^^^^^^^^ - -error: aborting due to 4 previous errors - diff --git a/tests/ui-toml/missing_docs_allow_unused/clippy.toml b/tests/ui-toml/missing_docs_in_private_items/allow_unused/clippy.toml similarity index 100% rename from tests/ui-toml/missing_docs_allow_unused/clippy.toml rename to tests/ui-toml/missing_docs_in_private_items/allow_unused/clippy.toml diff --git a/tests/ui-toml/pub_crate_missing_docs/clippy.toml b/tests/ui-toml/missing_docs_in_private_items/crate_root/clippy.toml similarity index 100% rename from tests/ui-toml/pub_crate_missing_docs/clippy.toml rename to tests/ui-toml/missing_docs_in_private_items/crate_root/clippy.toml diff --git a/tests/ui-toml/missing_docs_in_private_items/default/clippy.toml b/tests/ui-toml/missing_docs_in_private_items/default/clippy.toml new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.allow_unused.stderr b/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.allow_unused.stderr new file mode 100644 index 000000000000..b686288c7d27 --- /dev/null +++ b/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.allow_unused.stderr @@ -0,0 +1,644 @@ +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:26:5 + | +LL | f3: u32, + | ^^ + | +note: the lint level is defined here + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:8:9 + | +LL | #![deny(clippy::missing_docs_in_private_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:60:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:77:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:78:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:117:4 + | +LL | fn fn_crate() {} + | ^^^^^^^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:118:7 + | +LL | const CONST_CRATE: u32 = 0; + | ^^^^^^^^^^^ + +error: missing documentation for a static + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:119:8 + | +LL | static STATIC_CRATE: u32 = 0; + | ^^^^^^^^^^^^ + +error: missing documentation for a type alias + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:120:6 + | +LL | type TyAliasCrate = u32; + | ^^^^^^^^^^^^ + +error: missing documentation for a trait alias + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:121:7 + | +LL | trait TraitAliasCrate = Iterator; + | ^^^^^^^^^^^^^^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:122:8 + | +LL | struct StructCrate; + | ^^^^^^^^^^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:124:8 + | +LL | struct StructFieldCrate { + | ^^^^^^^^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:125:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:128:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:138:8 + | +LL | struct StructTupleCrate(u32, pub u32); + | ^^^^^^^^^^^^^^^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:140:6 + | +LL | enum EnumCrate { + | ^^^^^^^^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:141:5 + | +LL | V1, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:142:5 + | +LL | V2(u32), + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:144:5 + | +LL | V3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:145:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:155:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a union + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:161:7 + | +LL | union UnionCrate { + | ^^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:162:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:165:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:176:12 + | +LL | pub fn f1() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:177:15 + | +LL | pub const C1: u32 = 0; + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:182:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:183:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a trait + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:190:7 + | +LL | trait TraitCrate { + | ^^^^^^^^^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:191:8 + | +LL | fn f1(); + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:192:8 + | +LL | fn f2() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:193:11 + | +LL | const C1: u32; + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:194:11 + | +LL | const C2: u32 = 0; + | ^^ + +error: missing documentation for an associated type + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:195:10 + | +LL | type T1; + | ^^ + +error: missing documentation for a macro + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:216:14 + | +LL | macro_rules! mac_rules_crate { + | ^^^^^^^^^^^^^^^ + +error: missing documentation for a macro + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:220:7 + | +LL | macro mac_crate { + | ^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:238:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:241:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:255:5 + | +LL | V1, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:256:5 + | +LL | V2(u32), + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:258:5 + | +LL | V3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:259:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:269:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:276:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:279:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:290:12 + | +LL | pub fn f1() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:291:15 + | +LL | pub const C1: u32 = 0; + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:296:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:297:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:305:8 + | +LL | fn f1(); + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:306:8 + | +LL | fn f2() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:307:11 + | +LL | const C1: u32; + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:308:11 + | +LL | const C2: u32 = 0; + | ^^ + +error: missing documentation for an associated type + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:309:10 + | +LL | type T1; + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:541:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:567:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:588:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:591:12 + | +LL | struct S3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:592:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:595:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:600:10 + | +LL | enum E3 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:602:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:603:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:609:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:614:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:620:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:623:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:630:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:631:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:637:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a module + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:647:5 + | +LL | mod mod_crate { + | ^^^^^^^^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:648:12 + | +LL | pub fn f1() {} + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:651:16 + | +LL | pub struct S1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:652:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:655:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:660:14 + | +LL | pub enum E1 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:662:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:663:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:669:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:674:15 + | +LL | pub const C1: u32 = 0; + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:680:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:683:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:690:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:691:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:697:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:705:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:708:12 + | +LL | struct S3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:709:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:712:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:717:10 + | +LL | enum E3 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:719:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:720:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:726:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:731:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:737:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:740:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:747:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:748:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:754:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1061:9 + | +LL | f2: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1062:20 + | +LL | pub(crate) f3: u32, + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1069:23 + | +LL | pub(crate) fn f2() {} + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1072:18 + | +LL | pub enum E1 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1074:13 + | +LL | V2, + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1077:20 + | +LL | pub struct S2; + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1096:18 + | +LL | $(pub fn f2() {}) + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1165:20 + | +LL | pub struct VisFromOutside; + | ^^^^^^^^^^^^^^ + +error: aborting due to 106 previous errors + diff --git a/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.crate_root.stderr b/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.crate_root.stderr new file mode 100644 index 000000000000..e95ce5615cce --- /dev/null +++ b/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.crate_root.stderr @@ -0,0 +1,500 @@ +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:26:5 + | +LL | f3: u32, + | ^^ + | +note: the lint level is defined here + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:8:9 + | +LL | #![deny(clippy::missing_docs_in_private_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:32:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:60:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:66:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:77:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:78:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:117:4 + | +LL | fn fn_crate() {} + | ^^^^^^^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:118:7 + | +LL | const CONST_CRATE: u32 = 0; + | ^^^^^^^^^^^ + +error: missing documentation for a static + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:119:8 + | +LL | static STATIC_CRATE: u32 = 0; + | ^^^^^^^^^^^^ + +error: missing documentation for a type alias + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:120:6 + | +LL | type TyAliasCrate = u32; + | ^^^^^^^^^^^^ + +error: missing documentation for a trait alias + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:121:7 + | +LL | trait TraitAliasCrate = Iterator; + | ^^^^^^^^^^^^^^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:122:8 + | +LL | struct StructCrate; + | ^^^^^^^^^^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:124:8 + | +LL | struct StructFieldCrate { + | ^^^^^^^^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:125:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:128:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:131:9 + | +LL | pub _f5: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:134:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:138:8 + | +LL | struct StructTupleCrate(u32, pub u32); + | ^^^^^^^^^^^^^^^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:140:6 + | +LL | enum EnumCrate { + | ^^^^^^^^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:141:5 + | +LL | V1, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:142:5 + | +LL | V2(u32), + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:144:5 + | +LL | V3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:145:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:155:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a union + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:161:7 + | +LL | union UnionCrate { + | ^^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:162:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:165:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:168:9 + | +LL | pub _f5: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:171:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:176:12 + | +LL | pub fn f1() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:177:15 + | +LL | pub const C1: u32 = 0; + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:182:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:183:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a trait + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:190:7 + | +LL | trait TraitCrate { + | ^^^^^^^^^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:191:8 + | +LL | fn f1(); + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:192:8 + | +LL | fn f2() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:193:11 + | +LL | const C1: u32; + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:194:11 + | +LL | const C2: u32 = 0; + | ^^ + +error: missing documentation for an associated type + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:195:10 + | +LL | type T1; + | ^^ + +error: missing documentation for a macro + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:216:14 + | +LL | macro_rules! mac_rules_crate { + | ^^^^^^^^^^^^^^^ + +error: missing documentation for a macro + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:220:7 + | +LL | macro mac_crate { + | ^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:238:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:241:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:244:9 + | +LL | pub _f5: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:247:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:255:5 + | +LL | V1, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:256:5 + | +LL | V2(u32), + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:258:5 + | +LL | V3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:259:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:269:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:276:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:279:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:282:9 + | +LL | pub _f5: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:285:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:290:12 + | +LL | pub fn f1() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:291:15 + | +LL | pub const C1: u32 = 0; + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:296:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:297:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:305:8 + | +LL | fn f1(); + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:306:8 + | +LL | fn f2() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:307:11 + | +LL | const C1: u32; + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:308:11 + | +LL | const C2: u32 = 0; + | ^^ + +error: missing documentation for an associated type + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:309:10 + | +LL | type T1; + | ^^ + +error: missing documentation for a module + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:647:5 + | +LL | mod mod_crate { + | ^^^^^^^^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:648:12 + | +LL | pub fn f1() {} + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:651:16 + | +LL | pub struct S1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:652:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:660:14 + | +LL | pub enum E1 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:662:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:663:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:669:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:674:15 + | +LL | pub const C1: u32 = 0; + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:680:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:690:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:691:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:697:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1062:20 + | +LL | pub(crate) f3: u32, + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1072:18 + | +LL | pub enum E1 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1074:13 + | +LL | V2, + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1077:20 + | +LL | pub struct S2; + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1096:18 + | +LL | $(pub fn f2() {}) + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1165:20 + | +LL | pub struct VisFromOutside; + | ^^^^^^^^^^^^^^ + +error: aborting due to 82 previous errors + diff --git a/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.default.stderr b/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.default.stderr new file mode 100644 index 000000000000..44a3d29580ad --- /dev/null +++ b/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.default.stderr @@ -0,0 +1,704 @@ +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:26:5 + | +LL | f3: u32, + | ^^ + | +note: the lint level is defined here + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:8:9 + | +LL | #![deny(clippy::missing_docs_in_private_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:32:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:60:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:66:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:77:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:78:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:117:4 + | +LL | fn fn_crate() {} + | ^^^^^^^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:118:7 + | +LL | const CONST_CRATE: u32 = 0; + | ^^^^^^^^^^^ + +error: missing documentation for a static + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:119:8 + | +LL | static STATIC_CRATE: u32 = 0; + | ^^^^^^^^^^^^ + +error: missing documentation for a type alias + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:120:6 + | +LL | type TyAliasCrate = u32; + | ^^^^^^^^^^^^ + +error: missing documentation for a trait alias + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:121:7 + | +LL | trait TraitAliasCrate = Iterator; + | ^^^^^^^^^^^^^^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:122:8 + | +LL | struct StructCrate; + | ^^^^^^^^^^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:124:8 + | +LL | struct StructFieldCrate { + | ^^^^^^^^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:125:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:128:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:131:9 + | +LL | pub _f5: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:134:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:138:8 + | +LL | struct StructTupleCrate(u32, pub u32); + | ^^^^^^^^^^^^^^^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:140:6 + | +LL | enum EnumCrate { + | ^^^^^^^^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:141:5 + | +LL | V1, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:142:5 + | +LL | V2(u32), + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:144:5 + | +LL | V3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:145:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:155:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a union + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:161:7 + | +LL | union UnionCrate { + | ^^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:162:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:165:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:168:9 + | +LL | pub _f5: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:171:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:176:12 + | +LL | pub fn f1() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:177:15 + | +LL | pub const C1: u32 = 0; + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:182:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:183:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a trait + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:190:7 + | +LL | trait TraitCrate { + | ^^^^^^^^^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:191:8 + | +LL | fn f1(); + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:192:8 + | +LL | fn f2() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:193:11 + | +LL | const C1: u32; + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:194:11 + | +LL | const C2: u32 = 0; + | ^^ + +error: missing documentation for an associated type + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:195:10 + | +LL | type T1; + | ^^ + +error: missing documentation for a macro + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:216:14 + | +LL | macro_rules! mac_rules_crate { + | ^^^^^^^^^^^^^^^ + +error: missing documentation for a macro + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:220:7 + | +LL | macro mac_crate { + | ^^^^^^^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:238:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:241:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:244:9 + | +LL | pub _f5: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:247:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:255:5 + | +LL | V1, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:256:5 + | +LL | V2(u32), + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:258:5 + | +LL | V3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:259:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:269:9 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:276:9 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:279:5 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:282:9 + | +LL | pub _f5: u32, + | ^^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:285:5 + | +LL | _f7: u32, + | ^^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:290:12 + | +LL | pub fn f1() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:291:15 + | +LL | pub const C1: u32 = 0; + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:296:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:297:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:305:8 + | +LL | fn f1(); + | ^^ + +error: missing documentation for an associated function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:306:8 + | +LL | fn f2() {} + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:307:11 + | +LL | const C1: u32; + | ^^ + +error: missing documentation for an associated constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:308:11 + | +LL | const C2: u32 = 0; + | ^^ + +error: missing documentation for an associated type + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:309:10 + | +LL | type T1; + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:541:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:567:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:588:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:591:12 + | +LL | struct S3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:592:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:595:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:600:10 + | +LL | enum E3 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:602:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:603:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:609:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:614:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:620:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:623:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:630:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:631:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:637:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a module + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:647:5 + | +LL | mod mod_crate { + | ^^^^^^^^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:648:12 + | +LL | pub fn f1() {} + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:651:16 + | +LL | pub struct S1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:652:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:655:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:660:14 + | +LL | pub enum E1 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:662:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:663:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:669:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:674:15 + | +LL | pub const C1: u32 = 0; + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:680:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:683:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:690:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:691:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:697:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:705:8 + | +LL | fn f3() {} + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:708:12 + | +LL | struct S3 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:709:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:712:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:717:10 + | +LL | enum E3 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:719:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:720:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:726:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a constant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:731:11 + | +LL | const C3: u32 = 0; + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:737:13 + | +LL | pub f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:740:9 + | +LL | f3: u32, + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:747:9 + | +LL | V1 { + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:748:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:754:13 + | +LL | f1: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1061:9 + | +LL | f2: u32, + | ^^ + +error: missing documentation for a field + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1062:20 + | +LL | pub(crate) f3: u32, + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1069:23 + | +LL | pub(crate) fn f2() {} + | ^^ + +error: missing documentation for an enum + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1072:18 + | +LL | pub enum E1 { + | ^^ + +error: missing documentation for a variant + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1074:13 + | +LL | V2, + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1077:20 + | +LL | pub struct S2; + | ^^ + +error: missing documentation for a function + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1096:18 + | +LL | $(pub fn f2() {}) + | ^^ + +error: missing documentation for a struct + --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1165:20 + | +LL | pub struct VisFromOutside; + | ^^^^^^^^^^^^^^ + +error: aborting due to 116 previous errors + diff --git a/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs b/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs new file mode 100644 index 000000000000..0a7730a4ee7f --- /dev/null +++ b/tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs @@ -0,0 +1,1167 @@ +//@aux-build:../../ui/auxiliary/proc_macros.rs +//@revisions: default crate_root allow_unused +//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/missing_docs_in_private_items/default +//@[crate_root] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/missing_docs_in_private_items/crate_root +//@[allow_unused] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/missing_docs_in_private_items/allow_unused + +#![feature(decl_macro, trait_alias)] +#![deny(clippy::missing_docs_in_private_items)] +#![allow(non_local_definitions)] + +extern crate proc_macros; +use proc_macros::{external, with_span}; + +fn main() {} + +pub fn fn_pub() {} +pub const CONST_PUB: u32 = 0; +pub static STATIC_PUB: u32 = 0; +pub type TyAliasPub = u32; +pub trait TraitAliasPub = Iterator; +pub struct StructPub; +pub struct StructFieldPub { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, //~ missing_docs_in_private_items + /// docs + f4: u32, + pub _f5: u32, + /// docs + pub _f6: u32, + _f7: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + _f8: u32, +} +pub struct StructTuplePub(u32, pub u32); +pub enum EnumPub { + V1, + V2(u32), + V3 { + f1: u32, + /// docs + f2: u32, + }, + /// docs + V4, + /// docs + V5(u32), + /// docs + V6 { + f1: u32, + /// docs + f2: u32, + }, +} +pub union UnionPub { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, //~ missing_docs_in_private_items + /// docs + f4: u32, + pub _f5: u32, + /// docs + pub _f6: u32, + _f7: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + _f8: u32, +} +impl StructFieldPub { + pub fn f1() {} + pub const C1: u32 = 0; + /// docs + pub fn f2() {} + /// docs + pub const C2: u32 = 0; + fn f3() {} //~ missing_docs_in_private_items + const C3: u32 = 0; //~ missing_docs_in_private_items + /// docs + fn f4() {} + /// docs + const C4: u32 = 0; +} +pub trait TraitPub { + fn f1(); + fn f2() {} + const C1: u32; + const C2: u32 = 0; + type T1; + /// docs + fn f3(); + /// docs + fn f4() {} + /// docs + const C3: u32; + /// docs + const C4: u32 = 0; + /// docs + type T2; +} +impl TraitPub for StructPub { + fn f1() {} + const C1: u32 = 0; + type T1 = u32; + fn f3() {} + const C3: u32 = 0; + type T2 = u32; +} +#[macro_export] +macro_rules! mac_rules_pub { + () => {}; +} +pub macro mac_pub { + () => {}, +} + +fn fn_crate() {} //~ missing_docs_in_private_items +const CONST_CRATE: u32 = 0; //~ missing_docs_in_private_items +static STATIC_CRATE: u32 = 0; //~ missing_docs_in_private_items +type TyAliasCrate = u32; //~ missing_docs_in_private_items +trait TraitAliasCrate = Iterator; //~ missing_docs_in_private_items +struct StructCrate; //~ missing_docs_in_private_items +//~v missing_docs_in_private_items +struct StructFieldCrate { + pub f1: u32, //~ missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~ missing_docs_in_private_items + /// docs + f4: u32, + pub _f5: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + pub _f6: u32, + _f7: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + _f8: u32, +} +struct StructTupleCrate(u32, pub u32); //~ missing_docs_in_private_items +//~v missing_docs_in_private_items +enum EnumCrate { + V1, //~ missing_docs_in_private_items + V2(u32), //~ missing_docs_in_private_items + //~v missing_docs_in_private_items + V3 { + f1: u32, //~ missing_docs_in_private_items + /// docs + f2: u32, + }, + /// docs + V4, + /// docs + V5(u32), + /// docs + V6 { + f1: u32, //~ missing_docs_in_private_items + /// docs + f2: u32, + }, +} +//~v missing_docs_in_private_items +union UnionCrate { + pub f1: u32, //~ missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~ missing_docs_in_private_items + /// docs + f4: u32, + pub _f5: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + pub _f6: u32, + _f7: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + _f8: u32, +} +impl StructFieldCrate { + pub fn f1() {} //~ missing_docs_in_private_items + pub const C1: u32 = 0; //~ missing_docs_in_private_items + /// docs + pub fn f2() {} + /// docs + pub const C2: u32 = 0; + fn f3() {} //~ missing_docs_in_private_items + const C3: u32 = 0; //~ missing_docs_in_private_items + /// docs + fn f4() {} + /// docs + const C4: u32 = 0; +} +//~v missing_docs_in_private_items +trait TraitCrate { + fn f1(); //~ missing_docs_in_private_items + fn f2() {} //~ missing_docs_in_private_items + const C1: u32; //~ missing_docs_in_private_items + const C2: u32 = 0; //~ missing_docs_in_private_items + type T1; //~ missing_docs_in_private_items + /// docs + fn f3(); + /// docs + fn f4() {} + /// docs + const C3: u32; + /// docs + const C4: u32 = 0; + /// docs + type T2; +} +impl TraitCrate for StructCrate { + fn f1() {} + const C1: u32 = 0; + type T1 = u32; + fn f3() {} + const C3: u32 = 0; + type T2 = u32; +} +//~v missing_docs_in_private_items +macro_rules! mac_rules_crate { + () => {}; +} +//~v missing_docs_in_private_items +macro mac_crate { + () => {}, +} + +/// docs +fn fn_crate_doc() {} +/// docs +const CONST_CRATE_DOC: u32 = 0; +/// docs +static STATIC_CRATE_DOC: u32 = 0; +/// docs +type TyAliasCrateDoc = u32; +/// docs +trait TraitAliasCrateDoc = Iterator; +/// docs +struct StructCrateDoc; +/// docs +struct StructFieldCrateDoc { + pub f1: u32, //~ missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~ missing_docs_in_private_items + /// docs + f4: u32, + pub _f5: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + pub _f6: u32, + _f7: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + _f8: u32, +} +/// docs +struct StructTupleCrateDoc(u32, pub u32); +/// docs +enum EnumCrateDoc { + V1, //~ missing_docs_in_private_items + V2(u32), //~ missing_docs_in_private_items + //~v missing_docs_in_private_items + V3 { + f1: u32, //~ missing_docs_in_private_items + /// docs + f2: u32, + }, + /// docs + V4, + /// docs + V5(u32), + /// docs + V6 { + f1: u32, //~ missing_docs_in_private_items + /// docs + f2: u32, + }, +} +/// docs +union UnionCrateDoc { + pub f1: u32, //~ missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~ missing_docs_in_private_items + /// docs + f4: u32, + pub _f5: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + pub _f6: u32, + _f7: u32, //~[default,crate_root] missing_docs_in_private_items + /// docs + _f8: u32, +} +impl StructFieldCrateDoc { + pub fn f1() {} //~ missing_docs_in_private_items + pub const C1: u32 = 0; //~ missing_docs_in_private_items + /// docs + pub fn f2() {} + /// docs + pub const C2: u32 = 0; + fn f3() {} //~ missing_docs_in_private_items + const C3: u32 = 0; //~ missing_docs_in_private_items + /// docs + fn f4() {} + /// docs + const C4: u32 = 0; +} +/// docs +trait TraitCrateDoc { + fn f1(); //~ missing_docs_in_private_items + fn f2() {} //~ missing_docs_in_private_items + const C1: u32; //~ missing_docs_in_private_items + const C2: u32 = 0; //~ missing_docs_in_private_items + type T1; //~ missing_docs_in_private_items + /// docs + fn f3(); + /// docs + fn f4() {} + /// docs + const C3: u32; + /// docs + const C4: u32 = 0; + /// docs + type T2; +} +impl TraitCrate for StructCrateDoc { + fn f1() {} + const C1: u32 = 0; + type T1 = u32; + fn f3() {} + const C3: u32 = 0; + type T2 = u32; +} +/// docs +macro_rules! mac_rules_crate_doc { + () => {}; +} +/// docs +macro mac_crate_doc { + () => {}, +} + +#[doc(hidden)] +fn fn_crate_hidden() {} +#[doc(hidden)] +const CONST_CRATE_HIDDEN: u32 = 0; +#[doc(hidden)] +static STATIC_CRATE_HIDDEN: u32 = 0; +#[doc(hidden)] +type TyAliasCrateHidden = u32; +#[doc(hidden)] +trait TraitAliasCrateHidden = Iterator; +#[doc(hidden)] +struct StructCrateHidden; +#[doc(hidden)] +struct StructFieldCrateHidden { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, + /// docs + f4: u32, + pub _f5: u32, + /// docs + pub _f6: u32, + _f7: u32, + /// docs + _f8: u32, +} +#[doc(hidden)] +struct StructTupleCrateHidden(u32, pub u32); +#[doc(hidden)] +enum EnumCrateHidden { + V1, + V2(u32), + V3 { + f1: u32, + /// docs + f2: u32, + }, + V4, + V5(u32), + /// docs + V6 { + f1: u32, + /// docs + f2: u32, + }, +} +#[doc(hidden)] +union UnionCrateHidden { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, + /// docs + f4: u32, + pub _f5: u32, + /// docs + pub _f6: u32, + _f7: u32, + /// docs + _f8: u32, +} +#[doc(hidden)] +impl StructFieldCrateHidden { + pub fn f1() {} + pub const C1: u32 = 0; + /// docs + pub fn f2() {} + /// docs + pub const C2: u32 = 0; + fn f3() {} + const C3: u32 = 0; + /// docs + fn f4() {} + /// docs + const C4: u32 = 0; +} +#[doc(hidden)] +trait TraitCrateHidden { + fn f1(); + fn f2() {} + const C1: u32; + const C2: u32 = 0; + type T1; + /// docs + fn f3(); + /// docs + fn f4() {} + /// docs + const C3: u32; + /// docs + const C4: u32 = 0; + /// docs + type T2; +} +#[doc(hidden)] +macro_rules! mac_rules_crate_hidden { + () => {}; +} +#[doc(hidden)] +macro mac_crate_hidden { + () => {}, +} + +#[expect(clippy::missing_docs_in_private_items)] +fn fn_crate_expect() {} +#[expect(clippy::missing_docs_in_private_items)] +const CONST_CRATE_EXPECT: u32 = 0; +#[expect(clippy::missing_docs_in_private_items)] +static STATIC_CRATE_EXPECT: u32 = 0; +#[expect(clippy::missing_docs_in_private_items)] +type TyAliasCrateExpect = u32; +#[expect(clippy::missing_docs_in_private_items)] +trait TraitAliasCrateExpect = Iterator; +#[expect(clippy::missing_docs_in_private_items)] +struct StructCrateExpect; +#[expect(clippy::missing_docs_in_private_items)] +struct StructFieldCrateExpect { + #[expect(clippy::missing_docs_in_private_items)] + pub f1: u32, + /// docs + pub f2: u32, + #[expect(clippy::missing_docs_in_private_items)] + f3: u32, + /// docs + f4: u32, +} +#[expect(clippy::missing_docs_in_private_items)] +struct StructTupleCrateExpect(u32, pub u32); +#[expect(clippy::missing_docs_in_private_items)] +enum EnumCrateExpect { + #[expect(clippy::missing_docs_in_private_items)] + V1, + #[expect(clippy::missing_docs_in_private_items)] + V2(u32), + #[expect(clippy::missing_docs_in_private_items)] + V3 { + #[expect(clippy::missing_docs_in_private_items)] + f1: u32, + /// docs + f2: u32, + }, + /// docs + V4, + /// docs + V5(u32), + /// docs + V6 { + #[expect(clippy::missing_docs_in_private_items)] + f1: u32, + /// docs + f2: u32, + }, +} +#[expect(clippy::missing_docs_in_private_items)] +union UnionCrateExpect { + #[expect(clippy::missing_docs_in_private_items)] + pub f1: u32, + /// docs + pub f2: u32, + #[expect(clippy::missing_docs_in_private_items)] + f3: u32, + /// docs + f4: u32, +} +impl StructFieldCrateExpect { + #[expect(clippy::missing_docs_in_private_items)] + pub fn f1() {} + #[expect(clippy::missing_docs_in_private_items)] + pub const C1: u32 = 0; + #[expect(clippy::missing_docs_in_private_items)] + fn f2() {} + #[expect(clippy::missing_docs_in_private_items)] + const C2: u32 = 0; +} +#[expect(clippy::missing_docs_in_private_items)] +trait TraitCrateExpect { + #[expect(clippy::missing_docs_in_private_items)] + fn f1(); + #[expect(clippy::missing_docs_in_private_items)] + fn f2() {} + #[expect(clippy::missing_docs_in_private_items)] + const C1: u32; + #[expect(clippy::missing_docs_in_private_items)] + const C2: u32 = 0; + #[expect(clippy::missing_docs_in_private_items)] + type T1; +} +#[expect(clippy::missing_docs_in_private_items)] +macro_rules! mac_rules_crate_expect { + () => {}; +} +#[expect(clippy::missing_docs_in_private_items)] +macro mac_crate_expect { + () => {}, +} + +pub mod mod_pub { + pub fn f1() {} + pub struct S1 { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f4: u32, + } + pub enum E1 { + V1 { + f1: u32, + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, + /// docs + f2: u32, + }, + } + pub const C1: u32 = 0; + + /// docs + pub fn f2() {} + /// docs + pub struct S2 { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f4: u32, + } + /// docs + pub enum E2 { + V1 { + f1: u32, + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, + /// docs + f2: u32, + }, + } + /// docs + pub const C2: u32 = 0; + + fn f3() {} //~[default,allow_unused] missing_docs_in_private_items + // + //~[default,allow_unused]v missing_docs_in_private_items + struct S3 { + pub f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f4: u32, + } + //~[default,allow_unused]v missing_docs_in_private_items + enum E3 { + //~[default,allow_unused]v missing_docs_in_private_items + V1 { + f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f2: u32, + }, + } + const C3: u32 = 0; //~[default,allow_unused] missing_docs_in_private_items + + /// docs + fn f4() {} + /// docs + struct S4 { + pub f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f4: u32, + } + /// docs + enum E4 { + //~[default,allow_unused]v missing_docs_in_private_items + V1 { + f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f2: u32, + }, + } + /// docs + const C4: u32 = 0; +} + +//~v missing_docs_in_private_items +mod mod_crate { + pub fn f1() {} //~ missing_docs_in_private_items + // + //~v missing_docs_in_private_items + pub struct S1 { + pub f1: u32, //~ missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f4: u32, + } + //~v missing_docs_in_private_items + pub enum E1 { + //~v missing_docs_in_private_items + V1 { + f1: u32, //~ missing_docs_in_private_items + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, //~ missing_docs_in_private_items + /// docs + f2: u32, + }, + } + pub const C1: u32 = 0; //~ missing_docs_in_private_items + + /// docs + pub fn f2() {} + /// docs + pub struct S2 { + pub f1: u32, //~ missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f4: u32, + } + /// docs + pub enum E2 { + //~v missing_docs_in_private_items + V1 { + f1: u32, //~ missing_docs_in_private_items + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, //~ missing_docs_in_private_items + /// docs + f2: u32, + }, + } + /// docs + pub const C2: u32 = 0; + + fn f3() {} //~[default,allow_unused] missing_docs_in_private_items + // + //~[default,allow_unused]v missing_docs_in_private_items + struct S3 { + pub f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f4: u32, + } + //~[default,allow_unused]v missing_docs_in_private_items + enum E3 { + //~[default,allow_unused]v missing_docs_in_private_items + V1 { + f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f2: u32, + }, + } + const C3: u32 = 0; //~[default,allow_unused] missing_docs_in_private_items + + /// docs + fn f4() {} + /// docs + struct S4 { + pub f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + pub f2: u32, + f3: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f4: u32, + } + /// docs + enum E4 { + //~[default,allow_unused]v missing_docs_in_private_items + V1 { + f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, //~[default,allow_unused] missing_docs_in_private_items + /// docs + f2: u32, + }, + } + /// docs + const C4: u32 = 0; +} + +/// docs +mod mod_crate_doc {} + +#[doc(hidden)] +mod mod_crate_hidden { + pub fn f1() {} + pub struct S1 { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, + /// docs + f4: u32, + } + pub enum E1 { + V1 { + f1: u32, + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, + /// docs + f2: u32, + }, + } + pub const C1: u32 = 0; + + /// docs + pub fn f2() {} + /// docs + pub struct S2 { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, + /// docs + f4: u32, + } + /// docs + pub enum E2 { + V1 { + f1: u32, + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, + /// docs + f2: u32, + }, + } + /// docs + pub const C2: u32 = 0; + + fn f3() {} + struct S3 { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, + /// docs + f4: u32, + } + enum E3 { + V1 { + f1: u32, + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, + /// docs + f2: u32, + }, + } + const C3: u32 = 0; + + /// docs + fn f4() {} + /// docs + struct S4 { + pub f1: u32, + /// docs + pub f2: u32, + f3: u32, + /// docs + f4: u32, + } + /// docs + enum E4 { + V1 { + f1: u32, + /// docs + f2: u32, + }, + /// docs + V2 { + f1: u32, + /// docs + f2: u32, + }, + } + /// docs + const C4: u32 = 0; +} + +#[expect(clippy::missing_docs_in_private_items)] +mod mod_crate_expect {} + +#[doc = "docs"] +mod explicit_doc_attr {} + +with_span! { + sp + fn fn_pm() {} + const CONST_PM: u32 = 0; + static STATIC_PM: u32 = 0; + type TyAliasPm = u32; + trait TraitAliasPm = Iterator; + struct StructPm; + struct StructFieldPm { + pub f1: u32, + f2: u32, + pub _f3: u32, + _f4: u32, + } + struct StructTuplePm(u32, pub u32); + enum EnumPm { + V1, + V2(u32), + V3 { f1: u32, }, + } + union UnionPm { + pub f1: u32, + f2: u32, + pub _f3: u32, + _f4: u32, + } + impl StructFieldPm { + pub fn f1() {} + pub const C1: u32 = 0; + fn f2() {} + const C2: u32 = 0; + } + trait TraitPm { + fn f1(); + fn f2() {} + const C1: u32; + const C2: u32 = 0; + type T1; + } + impl TraitPm for StructPm { + fn f1() {} + const C1: u32 = 0; + type T1 = u32; + } + macro_rules! mac_rules_pm { + () => {}; + } + macro mac_pm { + () => {}, + } + mod mod_pm {} +} + +external! { + fn fn_external() {} + const CONST_EXTERNAL: u32 = 0; + static STATIC_EXTERNAL: u32 = 0; + type TyAliasExternal = u32; + trait TraitAliasExternal = Iterator; + struct StructExternal; + struct StructFieldExternal { + pub f1: u32, + f2: u32, + pub _f3: u32, + _f4: u32, + } + struct StructTupleExternal(u32, pub u32); + enum EnumExternal { + V1, + V2(u32), + V3 { f1: u32, }, + } + union UnionExternal { + pub f1: u32, + f2: u32, + pub _f3: u32, + _f4: u32, + } + impl StructFieldExternal { + pub fn f1() {} + pub const C1: u32 = 0; + fn f2() {} + const C2: u32 = 0; + } + trait TraitExternal { + fn f1(); + fn f2() {} + const C1: u32; + const C2: u32 = 0; + type T1; + } + impl TraitExternal for StructExternal { + fn f1() {} + const C1: u32 = 0; + type T1 = u32; + } + macro_rules! mac_rules_external { + () => {}; + } + macro mac_external { + () => {}, + } + mod mod_external {} +} + +pub const _: () = {}; +const _: () = {}; + +/// docs +fn fn_with_items() { + fn f() {} + type T = u32; + struct S { + f1: u32, + f2: u32, + } + enum E { + V { f: u32 }, + } + impl S { + fn f() {} + const C: u32 = 0; + } + const C: u32 = 0; + static ST: u32 = 0; + trait Tr { + fn f(); + type T; + const C: u32; + } + trait Tr2 = Tr; + mod m {} + macro_rules! m2 { + () => {}; + } + macro m3 { () => {}, } + union U { + f: u32, + } +} +/// docs +const CONST_WITH_ITEMS: () = { + fn f() {} +}; +/// docs +static STATIC_WITH_ITEMS: () = { + fn f() {} +}; +/// docs +trait TraitWithItems { + /// docs + fn f() { + fn f() {} + } + /// docs + const C: () = { + fn f() {} + }; +} +/// docs +struct StructWithItems; +impl StructWithItems { + /// docs + fn f() { + fn f() {} + } + /// docs + const C: () = { + fn f() {} + }; +} +/// docs +type TypeAliasWithItems = [u32; { + fn f() {} + 1 +}]; + +/// docs +mod with_reexports { + pub fn f1_reexport() {} + pub struct S1Reexport { + pub f1: u32, + f2: u32, //~[default,allow_unused] missing_docs_in_private_items + pub(crate) f3: u32, //~ missing_docs_in_private_items + /// docs + f4: u32, + } + + /// docs + mod m1 { + pub(crate) fn f2() {} //~[default,allow_unused] missing_docs_in_private_items + + //~v missing_docs_in_private_items + pub enum E1 { + V1Reexport, + V2, //~ missing_docs_in_private_items + } + + pub struct S2; //~ missing_docs_in_private_items + pub fn f3_reexport() -> S2 { + S2 + } + } + pub use m1::E1::{V1Reexport, V2}; + use m1::f2; + pub use m1::f3_reexport; +} +pub use with_reexports::{S1Reexport, V1Reexport, f1_reexport, f3_reexport}; + +external! { + mod mod_generated { + $(type T = u32;) + struct S { + $(f1: u32,) + f2: u32, + } + pub fn f() {} + $(pub fn f2() {}) //~ missing_docs_in_private_items + #[doc(hidden)] + $(pub fn f3() {}) + } +} + +/// docs +mod mod_with_hidden { + #[doc(hidden)] + pub mod m { + pub struct S { + #[doc(hidden)] + pub f: u32, + } + #[automatically_derived] + impl S { + #[doc(hidden)] + pub fn f() {} + pub const C: () = { + #[automatically_derived] + impl S { + #[doc(hidden)] + pub fn f2() { + mod m { + pub(crate) union U { + pub f: u32, + } + } + } + } + }; + } + } + #[doc(hidden)] + pub(crate) fn f() {} +} + +/// docs +struct WithProject { + /// docs + a: u32, + /// docs + b: u32, +} +with_span! { + span + const _: () = { + // Similar output to pin_project + struct Project<'a> { + $(a: &'a u32), + $(b: &'a u32), + } + impl $(WithProject) { + fn project(&self) -> Project<'_> { + Project { + a: &self.a, + b: &self.b, + } + } + } + }; +} + +external! { + mod mod_mac_with_pub {$( + struct DerivedFromInput; + impl DerivedFromInput { + pub fn foo() {} + } + pub struct VisFromOutside; //~ missing_docs_in_private_items + )} +} diff --git a/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs b/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs deleted file mode 100644 index 6a1d2b51abc8..000000000000 --- a/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! this is crate -#![allow(missing_docs)] -#![allow(clippy::struct_field_names)] -#![warn(clippy::missing_docs_in_private_items)] - -/// this is mod -mod my_mod { - /// some docs - fn priv_with_docs() {} - fn priv_no_docs() {} - /// some docs - pub(crate) fn crate_with_docs() {} - pub(crate) fn crate_no_docs() {} - //~^ missing_docs_in_private_items - /// some docs - pub(super) fn super_with_docs() {} - pub(super) fn super_no_docs() {} - //~^ missing_docs_in_private_items - - mod my_sub { - /// some docs - fn sub_priv_with_docs() {} - fn sub_priv_no_docs() {} - /// some docs - pub(crate) fn sub_crate_with_docs() {} - pub(crate) fn sub_crate_no_docs() {} - //~^ missing_docs_in_private_items - /// some docs - pub(super) fn sub_super_with_docs() {} - pub(super) fn sub_super_no_docs() {} - } - - /// some docs - pub(crate) struct CrateStructWithDocs { - /// some docs - pub(crate) crate_field_with_docs: (), - pub(crate) crate_field_no_docs: (), - //~^ missing_docs_in_private_items - /// some docs - priv_field_with_docs: (), - priv_field_no_docs: (), - } - - pub(crate) struct CrateStructNoDocs { - //~^ missing_docs_in_private_items - /// some docs - pub(crate) crate_field_with_docs: (), - pub(crate) crate_field_no_docs: (), - //~^ missing_docs_in_private_items - /// some docs - priv_field_with_docs: (), - priv_field_no_docs: (), - } -} - -/// some docs -type CrateTypedefWithDocs = String; -type CrateTypedefNoDocs = String; -//~^ missing_docs_in_private_items -/// some docs -pub type PubTypedefWithDocs = String; -pub type PubTypedefNoDocs = String; - -fn main() { - my_mod::crate_with_docs(); - my_mod::crate_no_docs(); -} diff --git a/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr b/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr deleted file mode 100644 index 0d70276de42d..000000000000 --- a/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr +++ /dev/null @@ -1,53 +0,0 @@ -error: missing documentation for a function - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:13:5 - | -LL | pub(crate) fn crate_no_docs() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` - -error: missing documentation for a function - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:17:5 - | -LL | pub(super) fn super_no_docs() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a function - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:26:9 - | -LL | pub(crate) fn sub_crate_no_docs() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a struct field - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:37:9 - | -LL | pub(crate) crate_field_no_docs: (), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a struct - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:44:5 - | -LL | / pub(crate) struct CrateStructNoDocs { -LL | | -LL | | /// some docs -LL | | pub(crate) crate_field_with_docs: (), -... | -LL | | priv_field_no_docs: (), -LL | | } - | |_____^ - -error: missing documentation for a struct field - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:48:9 - | -LL | pub(crate) crate_field_no_docs: (), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a type alias - --> tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.rs:58:1 - | -LL | type CrateTypedefNoDocs = String; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 7 previous errors - diff --git a/tests/ui-toml/result_large_err/clippy.toml b/tests/ui-toml/result_large_err/clippy.toml index df505ed9672a..80eeac0f9870 100644 --- a/tests/ui-toml/result_large_err/clippy.toml +++ b/tests/ui-toml/result_large_err/clippy.toml @@ -1 +1,2 @@ large-error-threshold = 512 +large-error-ignored = ["result_large_err::IgnoredError", "result_large_err::IgnoredErrorEnum"] diff --git a/tests/ui-toml/result_large_err/result_large_err.rs b/tests/ui-toml/result_large_err/result_large_err.rs index dea4d61a96bf..170f37db7593 100644 --- a/tests/ui-toml/result_large_err/result_large_err.rs +++ b/tests/ui-toml/result_large_err/result_large_err.rs @@ -1,4 +1,6 @@ +//@compile-flags: --crate-name result_large_err #![warn(clippy::result_large_err)] +#![allow(clippy::large_enum_variant)] fn f() -> Result<(), [u8; 511]> { todo!() @@ -7,4 +9,22 @@ fn f2() -> Result<(), [u8; 512]> { //~^ ERROR: the `Err`-variant returned from this function is very large todo!() } + +struct IgnoredError { + inner: [u8; 512], +} + +fn f3() -> Result<(), IgnoredError> { + todo!() +} + +enum IgnoredErrorEnum { + V1, + V2 { inner: [u8; 512] }, +} + +fn f4() -> Result<(), IgnoredErrorEnum> { + todo!() +} + fn main() {} diff --git a/tests/ui-toml/result_large_err/result_large_err.stderr b/tests/ui-toml/result_large_err/result_large_err.stderr index 656ce7ab7f2f..7e5954f885b8 100644 --- a/tests/ui-toml/result_large_err/result_large_err.stderr +++ b/tests/ui-toml/result_large_err/result_large_err.stderr @@ -1,5 +1,5 @@ error: the `Err`-variant returned from this function is very large - --> tests/ui-toml/result_large_err/result_large_err.rs:6:12 + --> tests/ui-toml/result_large_err/result_large_err.rs:8:12 | LL | fn f2() -> Result<(), [u8; 512]> { | ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 2d9503c5ac53..d5040f4a39bf 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -50,6 +50,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect future-size-threshold ignore-interior-mutability inherent-impl-lint-scope + large-error-ignored large-error-threshold lint-commented-code literal-representation-threshold @@ -147,6 +148,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect future-size-threshold ignore-interior-mutability inherent-impl-lint-scope + large-error-ignored large-error-threshold lint-commented-code literal-representation-threshold @@ -244,6 +246,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni future-size-threshold ignore-interior-mutability inherent-impl-lint-scope + large-error-ignored large-error-threshold lint-commented-code literal-representation-threshold diff --git a/tests/ui/blanket_clippy_restriction_lints.rs b/tests/ui/blanket_clippy_restriction_lints.rs index de699309b16d..1cd45685609f 100644 --- a/tests/ui/blanket_clippy_restriction_lints.rs +++ b/tests/ui/blanket_clippy_restriction_lints.rs @@ -3,7 +3,7 @@ #![warn(clippy::blanket_clippy_restriction_lints)] -//! Test that the whole restriction group is not enabled +//! Test that the whole restriction group is not enabled. #![warn(clippy::restriction)] //~^ blanket_clippy_restriction_lints #![deny(clippy::restriction)] diff --git a/tests/ui/byte_char_slices.fixed b/tests/ui/byte_char_slices.fixed index b0c1b1f034b4..87934d6362f7 100644 --- a/tests/ui/byte_char_slices.fixed +++ b/tests/ui/byte_char_slices.fixed @@ -1,4 +1,3 @@ -#![allow(unused)] #![warn(clippy::byte_char_slices)] fn main() { diff --git a/tests/ui/byte_char_slices.rs b/tests/ui/byte_char_slices.rs index 0d6953dda97e..0de7cf66fda8 100644 --- a/tests/ui/byte_char_slices.rs +++ b/tests/ui/byte_char_slices.rs @@ -1,4 +1,3 @@ -#![allow(unused)] #![warn(clippy::byte_char_slices)] fn main() { diff --git a/tests/ui/byte_char_slices.stderr b/tests/ui/byte_char_slices.stderr index 2556aa9c0f76..c1b7e4ca2f17 100644 --- a/tests/ui/byte_char_slices.stderr +++ b/tests/ui/byte_char_slices.stderr @@ -1,5 +1,5 @@ error: can be more succinctly written as a byte str - --> tests/ui/byte_char_slices.rs:5:15 + --> tests/ui/byte_char_slices.rs:4:15 | LL | let bad = &[b'a', b'b', b'c']; | ^^^^^^^^^^^^^^^^^^^ help: try: `b"abc"` @@ -8,25 +8,25 @@ LL | let bad = &[b'a', b'b', b'c']; = help: to override `-D warnings` add `#[allow(clippy::byte_char_slices)]` error: can be more succinctly written as a byte str - --> tests/ui/byte_char_slices.rs:7:18 + --> tests/ui/byte_char_slices.rs:6:18 | LL | let quotes = &[b'"', b'H', b'i']; | ^^^^^^^^^^^^^^^^^^^ help: try: `b"\"Hi"` error: can be more succinctly written as a byte str - --> tests/ui/byte_char_slices.rs:9:18 + --> tests/ui/byte_char_slices.rs:8:18 | LL | let quotes = &[b'\'', b'S', b'u', b'p']; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b"'Sup"` error: can be more succinctly written as a byte str - --> tests/ui/byte_char_slices.rs:11:19 + --> tests/ui/byte_char_slices.rs:10:19 | LL | let escapes = &[b'\x42', b'E', b's', b'c']; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b"\x42Esc"` error: useless use of `vec!` - --> tests/ui/byte_char_slices.rs:15:16 + --> tests/ui/byte_char_slices.rs:14:16 | LL | let good = vec![b'a', b'a']; | ^^^^^^^^^^^^^^^^ help: you can use an array directly: `[b'a', b'a']` diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index fab02bf7b24e..ff2791c45730 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -582,3 +582,13 @@ mod issue14150 { //~^ cast_possible_wrap } } + +fn issue16045() { + fn f() -> Result<(), ()> { + let val = Ok::<_, ()>(0u8); + _ = val? as i8; + //~^ cast_possible_wrap + + Ok(()) + } +} diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 8c48855123f9..0ff1dc11c3ac 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -764,5 +764,11 @@ error: casting `u8` to `i8` may wrap around the value LL | _ = 1u8 as i8; | ^^^^^^^^^ -error: aborting due to 94 previous errors +error: casting `u8` to `i8` may wrap around the value + --> tests/ui/cast.rs:589:13 + | +LL | _ = val? as i8; + | ^^^^^^^^^^ help: if this is intentional, use `cast_signed()` instead: `val?.cast_signed()` + +error: aborting due to 95 previous errors diff --git a/tests/ui/checked_unwrap/complex_conditionals.rs b/tests/ui/checked_unwrap/complex_conditionals.rs index 7d0bcc547a42..d1db2e67e269 100644 --- a/tests/ui/checked_unwrap/complex_conditionals.rs +++ b/tests/ui/checked_unwrap/complex_conditionals.rs @@ -1,27 +1,19 @@ -#![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] -#![allow( - clippy::if_same_then_else, - clippy::branches_sharing_code, - clippy::unnecessary_literal_unwrap -)] +#![warn(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] +#![expect(clippy::branches_sharing_code, clippy::unnecessary_literal_unwrap)] fn test_complex_conditions() { let x: Result<(), ()> = Ok(()); let y: Result<(), ()> = Ok(()); if x.is_ok() && y.is_err() { - // unnecessary x.unwrap(); //~^ unnecessary_unwrap - // will panic x.unwrap_err(); //~^ panicking_unwrap - // will panic y.unwrap(); //~^ panicking_unwrap - // unnecessary y.unwrap_err(); //~^ unnecessary_unwrap } else { @@ -37,45 +29,35 @@ fn test_complex_conditions() { x.unwrap(); y.unwrap(); } else { - // will panic x.unwrap(); //~^ panicking_unwrap - // unnecessary x.unwrap_err(); //~^ unnecessary_unwrap - // will panic y.unwrap(); //~^ panicking_unwrap - // unnecessary y.unwrap_err(); //~^ unnecessary_unwrap } let z: Result<(), ()> = Ok(()); if x.is_ok() && !(y.is_ok() || z.is_err()) { - // unnecessary x.unwrap(); //~^ unnecessary_unwrap - // will panic x.unwrap_err(); //~^ panicking_unwrap - // will panic y.unwrap(); //~^ panicking_unwrap - // unnecessary y.unwrap_err(); //~^ unnecessary_unwrap - // unnecessary z.unwrap(); //~^ unnecessary_unwrap - // will panic z.unwrap_err(); //~^ panicking_unwrap } @@ -85,27 +67,21 @@ fn test_complex_conditions() { y.unwrap(); z.unwrap(); } else { - // will panic x.unwrap(); //~^ panicking_unwrap - // unnecessary x.unwrap_err(); //~^ unnecessary_unwrap - // unnecessary y.unwrap(); //~^ unnecessary_unwrap - // will panic y.unwrap_err(); //~^ panicking_unwrap - // will panic z.unwrap(); //~^ panicking_unwrap - // unnecessary z.unwrap_err(); //~^ unnecessary_unwrap } diff --git a/tests/ui/checked_unwrap/complex_conditionals.stderr b/tests/ui/checked_unwrap/complex_conditionals.stderr index d3905850c970..e154e3c35dc9 100644 --- a/tests/ui/checked_unwrap/complex_conditionals.stderr +++ b/tests/ui/checked_unwrap/complex_conditionals.stderr @@ -1,21 +1,17 @@ error: called `unwrap` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:13:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:8:9 | LL | if x.is_ok() && y.is_err() { | --------- the check is happening here -LL | // unnecessary LL | x.unwrap(); | ^^^^^^^^^^ | = help: try using `if let` or `match` -note: the lint level is defined here - --> tests/ui/checked_unwrap/complex_conditionals.rs:1:35 - | -LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::unnecessary-unwrap` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_unwrap)]` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:17:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:11:9 | LL | if x.is_ok() && y.is_err() { | --------- because of this check @@ -23,14 +19,11 @@ LL | if x.is_ok() && y.is_err() { LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> tests/ui/checked_unwrap/complex_conditionals.rs:1:9 - | -LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::panicking-unwrap` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::panicking_unwrap)]` error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:21:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:14:9 | LL | if x.is_ok() && y.is_err() { | ---------- because of this check @@ -39,7 +32,7 @@ LL | y.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/complex_conditionals.rs:25:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:17:9 | LL | if x.is_ok() && y.is_err() { | ---------- the check is happening here @@ -50,7 +43,7 @@ LL | y.unwrap_err(); = help: try using `if let` or `match` error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:41:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:32:9 | LL | if x.is_ok() || y.is_ok() { | --------- because of this check @@ -59,7 +52,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:45:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:35:9 | LL | if x.is_ok() || y.is_ok() { | --------- the check is happening here @@ -70,7 +63,7 @@ LL | x.unwrap_err(); = help: try using `if let` or `match` error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:49:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:38:9 | LL | if x.is_ok() || y.is_ok() { | --------- because of this check @@ -79,7 +72,7 @@ LL | y.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:53:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:41:9 | LL | if x.is_ok() || y.is_ok() { | --------- the check is happening here @@ -90,18 +83,17 @@ LL | y.unwrap_err(); = help: try using `if let` or `match` error: called `unwrap` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:59:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:46:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- the check is happening here -LL | // unnecessary LL | x.unwrap(); | ^^^^^^^^^^ | = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:63:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:49:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- because of this check @@ -110,7 +102,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:67:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:52:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- because of this check @@ -119,7 +111,7 @@ LL | y.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `y` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:71:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:55:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | --------- the check is happening here @@ -130,7 +122,7 @@ LL | y.unwrap_err(); = help: try using `if let` or `match` error: called `unwrap` on `z` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/complex_conditionals.rs:75:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:58:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | ---------- the check is happening here @@ -141,7 +133,7 @@ LL | z.unwrap(); = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:79:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:61:9 | LL | if x.is_ok() && !(y.is_ok() || z.is_err()) { | ---------- because of this check @@ -150,7 +142,7 @@ LL | z.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:89:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:70:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- because of this check @@ -159,7 +151,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:93:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:73:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- the check is happening here @@ -170,7 +162,7 @@ LL | x.unwrap_err(); = help: try using `if let` or `match` error: called `unwrap` on `y` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/complex_conditionals.rs:97:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:76:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- the check is happening here @@ -181,7 +173,7 @@ LL | y.unwrap(); = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:101:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:79:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | --------- because of this check @@ -190,7 +182,7 @@ LL | y.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals.rs:105:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:82:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | ---------- because of this check @@ -199,7 +191,7 @@ LL | z.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `z` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/complex_conditionals.rs:109:9 + --> tests/ui/checked_unwrap/complex_conditionals.rs:85:9 | LL | if x.is_ok() || !(y.is_ok() && z.is_err()) { | ---------- the check is happening here diff --git a/tests/ui/checked_unwrap/complex_conditionals_nested.rs b/tests/ui/checked_unwrap/complex_conditionals_nested.rs index 7635f848cb34..6789e7c262b3 100644 --- a/tests/ui/checked_unwrap/complex_conditionals_nested.rs +++ b/tests/ui/checked_unwrap/complex_conditionals_nested.rs @@ -1,19 +1,14 @@ -#![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] -#![allow( - clippy::if_same_then_else, - clippy::branches_sharing_code, - clippy::unnecessary_literal_unwrap -)] //@no-rustfix: has placeholders +#![warn(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] +#![expect(clippy::branches_sharing_code, clippy::unnecessary_literal_unwrap)] + fn test_nested() { fn nested() { let x = Some(()); if x.is_some() { - // unnecessary x.unwrap(); //~^ unnecessary_unwrap } else { - // will panic x.unwrap(); //~^ panicking_unwrap } diff --git a/tests/ui/checked_unwrap/complex_conditionals_nested.stderr b/tests/ui/checked_unwrap/complex_conditionals_nested.stderr index 329be4d36621..7e4ef049f4a5 100644 --- a/tests/ui/checked_unwrap/complex_conditionals_nested.stderr +++ b/tests/ui/checked_unwrap/complex_conditionals_nested.stderr @@ -1,20 +1,16 @@ error: called `unwrap` on `x` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:13:13 + --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:9:13 | LL | if x.is_some() { | -------------- help: try: `if let Some() = x` -LL | // unnecessary LL | x.unwrap(); | ^^^^^^^^^^ | -note: the lint level is defined here - --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:1:35 - | -LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::unnecessary-unwrap` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_unwrap)]` error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:17:13 + --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:12:13 | LL | if x.is_some() { | ----------- because of this check @@ -22,11 +18,8 @@ LL | if x.is_some() { LL | x.unwrap(); | ^^^^^^^^^^ | -note: the lint level is defined here - --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:1:9 - | -LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::panicking-unwrap` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::panicking_unwrap)]` error: aborting due to 2 previous errors diff --git a/tests/ui/checked_unwrap/if_let_chains.rs b/tests/ui/checked_unwrap/if_let_chains.rs index cfa7715965cd..5c20ebb80024 100644 --- a/tests/ui/checked_unwrap/if_let_chains.rs +++ b/tests/ui/checked_unwrap/if_let_chains.rs @@ -1,5 +1,5 @@ //@require-annotations-for-level: ERROR -#![deny(clippy::unnecessary_unwrap)] +#![warn(clippy::unnecessary_unwrap)] #[clippy::msrv = "1.85"] fn if_let_chains_unsupported(a: Option, b: Option) { diff --git a/tests/ui/checked_unwrap/if_let_chains.stderr b/tests/ui/checked_unwrap/if_let_chains.stderr index 8a4137de37a3..801b074fc277 100644 --- a/tests/ui/checked_unwrap/if_let_chains.stderr +++ b/tests/ui/checked_unwrap/if_let_chains.stderr @@ -8,11 +8,8 @@ LL | println!("the value of a is {}", a.unwrap()); | ^^^^^^^^^^ | = help: try using `match` -note: the lint level is defined here - --> tests/ui/checked_unwrap/if_let_chains.rs:2:9 - | -LL | #![deny(clippy::unnecessary_unwrap)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::unnecessary-unwrap` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_unwrap)]` error: called `unwrap` on `a` after checking its variant with `is_none` --> tests/ui/checked_unwrap/if_let_chains.rs:20:42 diff --git a/tests/ui/checked_unwrap/simple_conditionals.rs b/tests/ui/checked_unwrap/simple_conditionals.rs index bba264080b40..c6476a7507a1 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.rs +++ b/tests/ui/checked_unwrap/simple_conditionals.rs @@ -1,15 +1,15 @@ //@no-rustfix: has placeholders -#![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] -#![allow( +#![warn(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] +#![expect( clippy::if_same_then_else, clippy::branches_sharing_code, - clippy::unnecessary_literal_unwrap + clippy::unnecessary_literal_unwrap, + clippy::self_assignment )] macro_rules! m { ($a:expr) => { if $a.is_some() { - // unnecessary $a.unwrap(); //~^ unnecessary_unwrap } @@ -43,90 +43,71 @@ macro_rules! checks_some { fn main() { let x = Some(()); if x.is_some() { - // unnecessary x.unwrap(); //~^ unnecessary_unwrap - // unnecessary x.expect("an error message"); //~^ unnecessary_unwrap } else { - // will panic x.unwrap(); //~^ panicking_unwrap - // will panic x.expect("an error message"); //~^ panicking_unwrap } if x.is_none() { - // will panic x.unwrap(); //~^ panicking_unwrap } else { - // unnecessary x.unwrap(); //~^ unnecessary_unwrap } m!(x); - // ok checks_in_param!(x.is_some(), x.unwrap()); - // ok checks_unwrap!(x, x.unwrap()); - // ok checks_some!(x.is_some(), x); let mut x: Result<(), ()> = Ok(()); if x.is_ok() { - // unnecessary x.unwrap(); //~^ unnecessary_unwrap - // unnecessary x.expect("an error message"); //~^ unnecessary_unwrap - // will panic x.unwrap_err(); //~^ panicking_unwrap } else { - // will panic x.unwrap(); //~^ panicking_unwrap - // will panic x.expect("an error message"); //~^ panicking_unwrap - // unnecessary x.unwrap_err(); //~^ unnecessary_unwrap } if x.is_err() { - // will panic x.unwrap(); //~^ panicking_unwrap - // unnecessary x.unwrap_err(); //~^ unnecessary_unwrap } else { - // unnecessary x.unwrap(); //~^ unnecessary_unwrap - // will panic x.unwrap_err(); //~^ panicking_unwrap } if x.is_ok() { x = Err(()); - // not unnecessary because of mutation of x + // not unnecessary because of mutation of `x` // it will always panic but the lint is not smart enough to see this (it only // checks if conditions). x.unwrap(); } else { x = Ok(()); - // not unnecessary because of mutation of x + // not unnecessary because of mutation of `x` // it will always panic but the lint is not smart enough to see this (it // only checks if conditions). x.unwrap_err(); @@ -175,13 +156,11 @@ fn issue11371() { //~^ panicking_unwrap } - // This should not lint. Statics are, at the time of writing, not linted on anyway, - // but if at some point they are supported by this lint, it should correctly see that - // `X` is being mutated and not suggest `if let Some(..) = X {}` + // This should not lint and suggest `if let Some(..) = X {}`, as `X` is being mutated static mut X: Option = Some(123); unsafe { + #[expect(static_mut_refs)] if X.is_some() { - //~^ ERROR: creating a shared reference X = None; X.unwrap(); } @@ -299,17 +278,197 @@ fn check_expect() { let x = Some(()); if x.is_some() { #[expect(clippy::unnecessary_unwrap)] - // unnecessary x.unwrap(); #[expect(clippy::unnecessary_unwrap)] - // unnecessary x.expect("an error message"); } else { #[expect(clippy::panicking_unwrap)] - // will panic x.unwrap(); #[expect(clippy::panicking_unwrap)] - // will panic x.expect("an error message"); } } + +fn partial_moves() { + fn borrow_option(_: &Option<()>) {} + + let x = Some(()); + // Using `if let Some(o) = x` won't work here, as `borrow_option` will try to borrow a moved value + if x.is_some() { + borrow_option(&x); + x.unwrap(); + //~^ unnecessary_unwrap + } + // This is fine though, as `if let Some(o) = &x` won't move `x` + if x.is_some() { + borrow_option(&x); + x.as_ref().unwrap(); + //~^ unnecessary_unwrap + } +} + +fn issue15321() { + struct Soption { + option: Option, + other: bool, + } + let mut sopt = Soption { + option: Some(true), + other: true, + }; + // Lint: nothing was mutated + let _res = if sopt.option.is_some() { + sopt.option.unwrap() + //~^ unnecessary_unwrap + } else { + sopt.option.unwrap() + //~^ panicking_unwrap + }; + // Lint: an unrelated field was mutated + let _res = if sopt.option.is_some() { + sopt.other = false; + sopt.option.unwrap() + //~^ unnecessary_unwrap + } else { + sopt.other = false; + sopt.option.unwrap() + //~^ panicking_unwrap + }; + // No lint: the whole local was mutated + let _res = if sopt.option.is_some() { + sopt = sopt; + sopt.option.unwrap() + } else { + sopt.option = None; + sopt.option.unwrap() + }; + // No lint: the field we're looking at was mutated + let _res = if sopt.option.is_some() { + sopt = sopt; + sopt.option.unwrap() + } else { + sopt.option = None; + sopt.option.unwrap() + }; + + struct Toption(Option, bool); + let mut topt = Toption(Some(true), true); + // Lint: nothing was mutated + let _res = if topt.0.is_some() { + topt.0.unwrap() + //~^ unnecessary_unwrap + } else { + topt.0.unwrap() + //~^ panicking_unwrap + }; + // Lint: an unrelated field was mutated + let _res = if topt.0.is_some() { + topt.1 = false; + topt.0.unwrap() + //~^ unnecessary_unwrap + } else { + topt.1 = false; + topt.0.unwrap() + //~^ panicking_unwrap + }; + // No lint: the whole local was mutated + let _res = if topt.0.is_some() { + topt = topt; + topt.0.unwrap() + } else { + topt = topt; + topt.0.unwrap() + }; + // No lint: the field we're looking at was mutated + let _res = if topt.0.is_some() { + topt.0 = None; + topt.0.unwrap() + } else { + topt.0 = None; + topt.0.unwrap() + }; + + // Nested field accesses get linted as well + struct Soption2 { + other: bool, + option: Soption, + } + let mut sopt2 = Soption2 { + other: true, + option: Soption { + option: Some(true), + other: true, + }, + }; + // Lint: no fields were mutated + let _res = if sopt2.option.option.is_some() { + sopt2.option.option.unwrap() + //~^ unnecessary_unwrap + } else { + sopt2.option.option.unwrap() + //~^ panicking_unwrap + }; + // Lint: an unrelated outer field was mutated -- don't get confused by `Soption2.other` having the + // same `FieldIdx` of 1 as `Soption.option` + let _res = if sopt2.option.option.is_some() { + sopt2.other = false; + sopt2.option.option.unwrap() + //~^ unnecessary_unwrap + } else { + sopt2.other = false; + sopt2.option.option.unwrap() + //~^ panicking_unwrap + }; + // Lint: an unrelated inner field was mutated + let _res = if sopt2.option.option.is_some() { + sopt2.option.other = false; + sopt2.option.option.unwrap() + //~^ unnecessary_unwrap + } else { + sopt2.option.other = false; + sopt2.option.option.unwrap() + //~^ panicking_unwrap + }; + // Don't lint: the whole local was mutated + let _res = if sopt2.option.option.is_some() { + sopt2 = sopt2; + sopt2.option.option.unwrap() + } else { + sopt2 = sopt2; + sopt2.option.option.unwrap() + }; + // Don't lint: a parent field of the field we're looking at was mutated, and with that the + // field we're looking at + let _res = if sopt2.option.option.is_some() { + sopt2.option = sopt; + sopt2.option.option.unwrap() + } else { + sopt2.option = sopt; + sopt2.option.option.unwrap() + }; + // Don't lint: the field we're looking at was mutated directly + let _res = if sopt2.option.option.is_some() { + sopt2.option.option = None; + sopt2.option.option.unwrap() + } else { + sopt2.option.option = None; + sopt2.option.option.unwrap() + }; + + // Partial moves + fn borrow_toption(_: &Toption) {} + + // Using `if let Some(o) = topt.0` won't work here, as `borrow_toption` will try to borrow a + // partially moved value + if topt.0.is_some() { + borrow_toption(&topt); + topt.0.unwrap(); + //~^ unnecessary_unwrap + } + // This is fine though, as `if let Some(o) = &topt.0` won't (partially) move `topt` + if topt.0.is_some() { + borrow_toption(&topt); + topt.0.as_ref().unwrap(); + //~^ unnecessary_unwrap + } +} diff --git a/tests/ui/checked_unwrap/simple_conditionals.stderr b/tests/ui/checked_unwrap/simple_conditionals.stderr index 2007a8595413..be979baa9fe4 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.stderr +++ b/tests/ui/checked_unwrap/simple_conditionals.stderr @@ -1,20 +1,16 @@ error: called `unwrap` on `x` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:47:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:46:9 | LL | if x.is_some() { | -------------- help: try: `if let Some() = x` -LL | // unnecessary LL | x.unwrap(); | ^^^^^^^^^^ | -note: the lint level is defined here - --> tests/ui/checked_unwrap/simple_conditionals.rs:2:35 - | -LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::unnecessary-unwrap` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_unwrap)]` error: called `expect` on `x` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:51:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:49:9 | LL | if x.is_some() { | -------------- help: try: `if let Some() = x` @@ -23,40 +19,36 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:52:9 + | +LL | if x.is_some() { + | ----------- because of this check +... +LL | x.unwrap(); + | ^^^^^^^^^^ + | + = note: `-D clippy::panicking-unwrap` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::panicking_unwrap)]` + +error: this call to `expect()` will always panic --> tests/ui/checked_unwrap/simple_conditionals.rs:55:9 | LL | if x.is_some() { | ----------- because of this check ... -LL | x.unwrap(); - | ^^^^^^^^^^ - | -note: the lint level is defined here - --> tests/ui/checked_unwrap/simple_conditionals.rs:2:9 - | -LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: this call to `expect()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:59:9 - | -LL | if x.is_some() { - | ----------- because of this check -... LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:64:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:59:9 | LL | if x.is_none() { | ----------- because of this check -LL | // will panic LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_none` - --> tests/ui/checked_unwrap/simple_conditionals.rs:68:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:62:9 | LL | if x.is_none() { | -------------- help: try: `if let Some() = x` @@ -69,7 +61,6 @@ error: called `unwrap` on `x` after checking its variant with `is_some` | LL | if $a.is_some() { | --------------- help: try: `if let Some() = x` -LL | // unnecessary LL | $a.unwrap(); | ^^^^^^^^^^^ ... @@ -79,16 +70,15 @@ LL | m!(x); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: called `unwrap` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:81:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:71:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok() = x` -LL | // unnecessary LL | x.unwrap(); | ^^^^^^^^^^ error: called `expect` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:85:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:74:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok() = x` @@ -97,7 +87,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:89:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:77:9 | LL | if x.is_ok() { | --------- because of this check @@ -106,7 +96,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:93:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:80:9 | LL | if x.is_ok() { | --------- because of this check @@ -115,7 +105,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: this call to `expect()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:97:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:83:9 | LL | if x.is_ok() { | --------- because of this check @@ -124,7 +114,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:101:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:86:9 | LL | if x.is_ok() { | ------------ help: try: `if let Err() = x` @@ -133,16 +123,15 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:106:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:90:9 | LL | if x.is_err() { | ---------- because of this check -LL | // will panic LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/simple_conditionals.rs:110:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:93:9 | LL | if x.is_err() { | ------------- help: try: `if let Err() = x` @@ -151,7 +140,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/simple_conditionals.rs:114:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:96:9 | LL | if x.is_err() { | ------------- help: try: `if let Ok() = x` @@ -160,7 +149,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:118:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:99:9 | LL | if x.is_err() { | ---------- because of this check @@ -169,58 +158,58 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:143:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:124:9 | LL | if option.is_some() { | ------------------- help: try: `if let Some() = &option` LL | option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:127:9 + | +LL | if option.is_some() { + | ---------------- because of this check +... +LL | option.as_ref().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: called `unwrap` on `result` after checking its variant with `is_ok` + --> tests/ui/checked_unwrap/simple_conditionals.rs:134:9 + | +LL | if result.is_ok() { + | ----------------- help: try: `if let Ok() = &result` +LL | result.as_ref().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:137:9 + | +LL | if result.is_ok() { + | -------------- because of this check +... +LL | result.as_ref().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: called `unwrap` on `option` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:143:9 + | +LL | if option.is_some() { + | ------------------- help: try: `if let Some() = &mut option` +LL | option.as_mut().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + error: this call to `unwrap()` will always panic --> tests/ui/checked_unwrap/simple_conditionals.rs:146:9 | LL | if option.is_some() { | ---------------- because of this check ... -LL | option.as_ref().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:153:9 - | -LL | if result.is_ok() { - | ----------------- help: try: `if let Ok() = &result` -LL | result.as_ref().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:156:9 - | -LL | if result.is_ok() { - | -------------- because of this check -... -LL | result.as_ref().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:162:9 - | -LL | if option.is_some() { - | ------------------- help: try: `if let Some() = &mut option` -LL | option.as_mut().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:165:9 - | -LL | if option.is_some() { - | ---------------- because of this check -... LL | option.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:171:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:152:9 | LL | if result.is_ok() { | ----------------- help: try: `if let Ok() = &mut result` @@ -228,7 +217,7 @@ LL | result.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:174:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:155:9 | LL | if result.is_ok() { | -------------- because of this check @@ -237,7 +226,7 @@ LL | result.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:205:17 + --> tests/ui/checked_unwrap/simple_conditionals.rs:184:17 | LL | if option.is_some() { | ------------------- help: try: `if let Some() = &option` @@ -245,7 +234,7 @@ LL | let _ = option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:208:17 + --> tests/ui/checked_unwrap/simple_conditionals.rs:187:17 | LL | if option.is_some() { | ---------------- because of this check @@ -254,7 +243,7 @@ LL | let _ = option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:216:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:195:9 | LL | if result.is_ok() { | ----------------- help: try: `if let Ok() = &result` @@ -263,7 +252,7 @@ LL | result.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:220:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:199:9 | LL | if result.is_ok() { | -------------- because of this check @@ -271,6 +260,40 @@ LL | if result.is_ok() { LL | result.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ +error: called `unwrap` on `x` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:225:17 + | +LL | if x.is_some() { + | -------------- help: try: `if let Some() = x` +LL | _ = x.unwrap(); + | ^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:228:17 + | +LL | if x.is_some() { + | ----------- because of this check +... +LL | _ = x.unwrap(); + | ^^^^^^^^^^ + +error: called `unwrap` on `r` after checking its variant with `is_ok` + --> tests/ui/checked_unwrap/simple_conditionals.rs:234:17 + | +LL | if r.is_ok() { + | ------------ help: try: `if let Ok() = &r` +LL | _ = r.as_ref().unwrap(); + | ^^^^^^^^^^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:237:17 + | +LL | if r.is_ok() { + | --------- because of this check +... +LL | _ = r.as_ref().unwrap(); + | ^^^^^^^^^^^^^^^^^^^ + error: called `unwrap` on `x` after checking its variant with `is_some` --> tests/ui/checked_unwrap/simple_conditionals.rs:246:17 | @@ -288,42 +311,8 @@ LL | if x.is_some() { LL | _ = x.unwrap(); | ^^^^^^^^^^ -error: called `unwrap` on `r` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:255:17 - | -LL | if r.is_ok() { - | ------------ help: try: `if let Ok() = &r` -LL | _ = r.as_ref().unwrap(); - | ^^^^^^^^^^^^^^^^^^^ - -error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:258:17 - | -LL | if r.is_ok() { - | --------- because of this check -... -LL | _ = r.as_ref().unwrap(); - | ^^^^^^^^^^^^^^^^^^^ - -error: called `unwrap` on `x` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:267:17 - | -LL | if x.is_some() { - | -------------- help: try: `if let Some() = x` -LL | _ = x.unwrap(); - | ^^^^^^^^^^ - -error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:270:17 - | -LL | if x.is_some() { - | ----------- because of this check -... -LL | _ = x.unwrap(); - | ^^^^^^^^^^ - error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:280:26 + --> tests/ui/checked_unwrap/simple_conditionals.rs:259:26 | LL | if option.is_some() { | ------------------- help: try: `if let Some() = option` @@ -331,7 +320,7 @@ LL | println!("{:?}", option.unwrap()); | ^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:283:26 + --> tests/ui/checked_unwrap/simple_conditionals.rs:262:26 | LL | if option.is_some() { | ---------------- because of this check @@ -340,7 +329,7 @@ LL | println!("{:?}", option.unwrap()); | ^^^^^^^^^^^^^^^ error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:290:26 + --> tests/ui/checked_unwrap/simple_conditionals.rs:269:26 | LL | if result.is_ok() { | ----------------- help: try: `if let Ok() = result` @@ -348,7 +337,7 @@ LL | println!("{:?}", result.unwrap()); | ^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:293:26 + --> tests/ui/checked_unwrap/simple_conditionals.rs:272:26 | LL | if result.is_ok() { | -------------- because of this check @@ -356,15 +345,164 @@ LL | if result.is_ok() { LL | println!("{:?}", result.unwrap()); | ^^^^^^^^^^^^^^^ -error: creating a shared reference to mutable static - --> tests/ui/checked_unwrap/simple_conditionals.rs:183:12 +error: called `unwrap` on `x` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:299:9 | -LL | if X.is_some() { - | ^^^^^^^^^^^ shared reference to mutable static +LL | if x.is_some() { + | -------------- help: try: `if let Some() = x` +LL | borrow_option(&x); +LL | x.unwrap(); + | ^^^^^^^^^^ + +error: called `unwrap` on `x` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:305:9 | - = note: for more information, see - = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives - = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default +LL | if x.is_some() { + | -------------- help: try: `if let Some() = &x` +LL | borrow_option(&x); +LL | x.as_ref().unwrap(); + | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 40 previous errors +error: called `unwrap` on `sopt.option` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:321:9 + | +LL | let _res = if sopt.option.is_some() { + | ------------------------ help: try: `if let Some() = sopt.option` +LL | sopt.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:324:9 + | +LL | let _res = if sopt.option.is_some() { + | --------------------- because of this check +... +LL | sopt.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^ + +error: called `unwrap` on `sopt.option` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:330:9 + | +LL | let _res = if sopt.option.is_some() { + | ------------------------ help: try: `if let Some() = sopt.option` +LL | sopt.other = false; +LL | sopt.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:334:9 + | +LL | let _res = if sopt.option.is_some() { + | --------------------- because of this check +... +LL | sopt.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^ + +error: called `unwrap` on `topt.0` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:358:9 + | +LL | let _res = if topt.0.is_some() { + | ------------------- help: try: `if let Some() = topt.0` +LL | topt.0.unwrap() + | ^^^^^^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:361:9 + | +LL | let _res = if topt.0.is_some() { + | ---------------- because of this check +... +LL | topt.0.unwrap() + | ^^^^^^^^^^^^^^^ + +error: called `unwrap` on `topt.0` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:367:9 + | +LL | let _res = if topt.0.is_some() { + | ------------------- help: try: `if let Some() = topt.0` +LL | topt.1 = false; +LL | topt.0.unwrap() + | ^^^^^^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:371:9 + | +LL | let _res = if topt.0.is_some() { + | ---------------- because of this check +... +LL | topt.0.unwrap() + | ^^^^^^^^^^^^^^^ + +error: called `unwrap` on `sopt2.option.option` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:405:9 + | +LL | let _res = if sopt2.option.option.is_some() { + | -------------------------------- help: try: `if let Some() = sopt2.option.option` +LL | sopt2.option.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:408:9 + | +LL | let _res = if sopt2.option.option.is_some() { + | ----------------------------- because of this check +... +LL | sopt2.option.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: called `unwrap` on `sopt2.option.option` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:415:9 + | +LL | let _res = if sopt2.option.option.is_some() { + | -------------------------------- help: try: `if let Some() = sopt2.option.option` +LL | sopt2.other = false; +LL | sopt2.option.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:419:9 + | +LL | let _res = if sopt2.option.option.is_some() { + | ----------------------------- because of this check +... +LL | sopt2.option.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: called `unwrap` on `sopt2.option.option` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:425:9 + | +LL | let _res = if sopt2.option.option.is_some() { + | -------------------------------- help: try: `if let Some() = sopt2.option.option` +LL | sopt2.option.other = false; +LL | sopt2.option.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this call to `unwrap()` will always panic + --> tests/ui/checked_unwrap/simple_conditionals.rs:429:9 + | +LL | let _res = if sopt2.option.option.is_some() { + | ----------------------------- because of this check +... +LL | sopt2.option.option.unwrap() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: called `unwrap` on `topt.0` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:465:9 + | +LL | if topt.0.is_some() { + | ------------------- help: try: `if let Some() = topt.0` +LL | borrow_toption(&topt); +LL | topt.0.unwrap(); + | ^^^^^^^^^^^^^^^ + +error: called `unwrap` on `topt.0` after checking its variant with `is_some` + --> tests/ui/checked_unwrap/simple_conditionals.rs:471:9 + | +LL | if topt.0.is_some() { + | ------------------- help: try: `if let Some() = &topt.0` +LL | borrow_toption(&topt); +LL | topt.0.as_ref().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 57 previous errors diff --git a/tests/ui/doc/doc_paragraphs_missing_punctuation.fixed b/tests/ui/doc/doc_paragraphs_missing_punctuation.fixed new file mode 100644 index 000000000000..95d65039440b --- /dev/null +++ b/tests/ui/doc/doc_paragraphs_missing_punctuation.fixed @@ -0,0 +1,172 @@ +#![feature(custom_inner_attributes)] +#![rustfmt::skip] +#![warn(clippy::doc_paragraphs_missing_punctuation)] + +/// Returns the Answer to the Ultimate Question of Life, the Universe, and Everything. +//~^ doc_paragraphs_missing_punctuation +fn answer() -> i32 { + 42 +} + +/// The `Option` type. +//~^ doc_paragraphs_missing_punctuation +// Triggers even in the presence of another attribute. +#[derive(Debug)] +enum MyOption { + /// No value. + //~^ doc_paragraphs_missing_punctuation + None, + /// Some value of type `T`. + Some(T), +} + +// Triggers correctly even when interleaved with other attributes. +/// A multiline +#[derive(Debug)] +/// doc comment: +/// only the last line triggers the lint. +//~^ doc_paragraphs_missing_punctuation +enum Exceptions { + /// Question marks are fine? + QuestionMark, + /// Exclamation marks are fine! + ExclamationMark, + /// Ellipses are ok too… + Ellipsis, + /// HTML content is however not checked: + /// Raw HTML is allowed as well + RawHtml, + /// The raw HTML exception actually does the right thing to autolinks: + /// . + //~^ doc_paragraphs_missing_punctuation + MarkdownAutolink, + /// This table introduction ends with a colon: + /// + /// | Exception | Note | + /// | -------------- | ----- | + /// | Markdown table | A-ok | + MarkdownTable, + /// Here is a snippet. + //~^ doc_paragraphs_missing_punctuation + /// + /// ``` + /// // Code blocks are no issues. + /// ``` + CodeBlock, +} + +// Check the lint can be expected on a whole enum at once. +#[expect(clippy::doc_paragraphs_missing_punctuation)] +enum Char { + /// U+0000 + Null, + /// U+0001 + StartOfHeading, +} + +// Check the lint can be expected on a single variant without affecting others. +enum Char2 { + #[expect(clippy::doc_paragraphs_missing_punctuation)] + /// U+0000 + Null, + /// U+0001. + //~^ doc_paragraphs_missing_punctuation + StartOfHeading, +} + +mod module { + //! Works on + //! inner attributes too. + //~^ doc_paragraphs_missing_punctuation +} + +enum Trailers { + /// Sometimes the last sentence ends with parentheses (and that's ok). + ParensPassing, + /// (Sometimes the last sentence is in parentheses.) + SentenceInParensPassing, + /// **Sometimes the last sentence is in bold, and that's ok.** + DoubleStarPassing, + /// **But sometimes it is missing a period.** + //~^ doc_paragraphs_missing_punctuation + DoubleStarFailing, + /// _Sometimes the last sentence is in italics, and that's ok._ + UnderscorePassing, + /// _But sometimes it is missing a period._ + //~^ doc_paragraphs_missing_punctuation + UnderscoreFailing, + /// This comment ends with "a quote." + AmericanStyleQuotePassing, + /// This comment ends with "a quote". + BritishStyleQuotePassing, +} + +/// Doc comments can end with an [inline link](#anchor). +//~^ doc_paragraphs_missing_punctuation +struct InlineLink; + +/// Some doc comments contain [link reference definitions][spec]. +//~^ doc_paragraphs_missing_punctuation +/// +/// [spec]: https://spec.commonmark.org/0.31.2/#link-reference-definitions +struct LinkRefDefinition; + +// List items do not always need to end with a period. +enum UnorderedLists { + /// This list has an introductory sentence: + /// + /// - A list item + Dash, + /// + A list item + Plus, + /// * A list item + Star, +} + +enum OrderedLists { + /// 1. A list item + Dot, + /// 42) A list item + Paren, +} + +/// Doc comments with trailing blank lines are supported. +//~^ doc_paragraphs_missing_punctuation +/// +struct TrailingBlankLine; + +/// This doc comment has multiple paragraph. +/// This first paragraph is missing punctuation. +//~^ doc_paragraphs_missing_punctuation +/// +/// The second one as well +/// And it has multiple sentences. +//~^ doc_paragraphs_missing_punctuation +/// +/// Same for this third and last one. +//~^ doc_paragraphs_missing_punctuation +struct MultiParagraphDocComment; + +/// ``` +struct IncompleteBlockCode; + +/// This ends with a code `span`. +//~^ doc_paragraphs_missing_punctuation +struct CodeSpan; + +#[expect(clippy::empty_docs)] +/// +struct EmptyDocComment; + +/** + * Block doc comments work. + * + */ +//~^^^ doc_paragraphs_missing_punctuation +struct BlockDocComment; + +/// Sometimes a doc attribute is used for concatenation +/// ``` +#[doc = ""] +/// ``` +struct DocAttribute; diff --git a/tests/ui/doc/doc_paragraphs_missing_punctuation.rs b/tests/ui/doc/doc_paragraphs_missing_punctuation.rs new file mode 100644 index 000000000000..35b74d7d13b9 --- /dev/null +++ b/tests/ui/doc/doc_paragraphs_missing_punctuation.rs @@ -0,0 +1,172 @@ +#![feature(custom_inner_attributes)] +#![rustfmt::skip] +#![warn(clippy::doc_paragraphs_missing_punctuation)] + +/// Returns the Answer to the Ultimate Question of Life, the Universe, and Everything +//~^ doc_paragraphs_missing_punctuation +fn answer() -> i32 { + 42 +} + +/// The `Option` type +//~^ doc_paragraphs_missing_punctuation +// Triggers even in the presence of another attribute. +#[derive(Debug)] +enum MyOption { + /// No value + //~^ doc_paragraphs_missing_punctuation + None, + /// Some value of type `T`. + Some(T), +} + +// Triggers correctly even when interleaved with other attributes. +/// A multiline +#[derive(Debug)] +/// doc comment: +/// only the last line triggers the lint +//~^ doc_paragraphs_missing_punctuation +enum Exceptions { + /// Question marks are fine? + QuestionMark, + /// Exclamation marks are fine! + ExclamationMark, + /// Ellipses are ok too… + Ellipsis, + /// HTML content is however not checked: + /// Raw HTML is allowed as well + RawHtml, + /// The raw HTML exception actually does the right thing to autolinks: + /// + //~^ doc_paragraphs_missing_punctuation + MarkdownAutolink, + /// This table introduction ends with a colon: + /// + /// | Exception | Note | + /// | -------------- | ----- | + /// | Markdown table | A-ok | + MarkdownTable, + /// Here is a snippet + //~^ doc_paragraphs_missing_punctuation + /// + /// ``` + /// // Code blocks are no issues. + /// ``` + CodeBlock, +} + +// Check the lint can be expected on a whole enum at once. +#[expect(clippy::doc_paragraphs_missing_punctuation)] +enum Char { + /// U+0000 + Null, + /// U+0001 + StartOfHeading, +} + +// Check the lint can be expected on a single variant without affecting others. +enum Char2 { + #[expect(clippy::doc_paragraphs_missing_punctuation)] + /// U+0000 + Null, + /// U+0001 + //~^ doc_paragraphs_missing_punctuation + StartOfHeading, +} + +mod module { + //! Works on + //! inner attributes too + //~^ doc_paragraphs_missing_punctuation +} + +enum Trailers { + /// Sometimes the last sentence ends with parentheses (and that's ok). + ParensPassing, + /// (Sometimes the last sentence is in parentheses.) + SentenceInParensPassing, + /// **Sometimes the last sentence is in bold, and that's ok.** + DoubleStarPassing, + /// **But sometimes it is missing a period** + //~^ doc_paragraphs_missing_punctuation + DoubleStarFailing, + /// _Sometimes the last sentence is in italics, and that's ok._ + UnderscorePassing, + /// _But sometimes it is missing a period_ + //~^ doc_paragraphs_missing_punctuation + UnderscoreFailing, + /// This comment ends with "a quote." + AmericanStyleQuotePassing, + /// This comment ends with "a quote". + BritishStyleQuotePassing, +} + +/// Doc comments can end with an [inline link](#anchor) +//~^ doc_paragraphs_missing_punctuation +struct InlineLink; + +/// Some doc comments contain [link reference definitions][spec] +//~^ doc_paragraphs_missing_punctuation +/// +/// [spec]: https://spec.commonmark.org/0.31.2/#link-reference-definitions +struct LinkRefDefinition; + +// List items do not always need to end with a period. +enum UnorderedLists { + /// This list has an introductory sentence: + /// + /// - A list item + Dash, + /// + A list item + Plus, + /// * A list item + Star, +} + +enum OrderedLists { + /// 1. A list item + Dot, + /// 42) A list item + Paren, +} + +/// Doc comments with trailing blank lines are supported +//~^ doc_paragraphs_missing_punctuation +/// +struct TrailingBlankLine; + +/// This doc comment has multiple paragraph. +/// This first paragraph is missing punctuation +//~^ doc_paragraphs_missing_punctuation +/// +/// The second one as well +/// And it has multiple sentences +//~^ doc_paragraphs_missing_punctuation +/// +/// Same for this third and last one +//~^ doc_paragraphs_missing_punctuation +struct MultiParagraphDocComment; + +/// ``` +struct IncompleteBlockCode; + +/// This ends with a code `span` +//~^ doc_paragraphs_missing_punctuation +struct CodeSpan; + +#[expect(clippy::empty_docs)] +/// +struct EmptyDocComment; + +/** + * Block doc comments work + * + */ +//~^^^ doc_paragraphs_missing_punctuation +struct BlockDocComment; + +/// Sometimes a doc attribute is used for concatenation +/// ``` +#[doc = ""] +/// ``` +struct DocAttribute; diff --git a/tests/ui/doc/doc_paragraphs_missing_punctuation.stderr b/tests/ui/doc/doc_paragraphs_missing_punctuation.stderr new file mode 100644 index 000000000000..49aa4e8aeb88 --- /dev/null +++ b/tests/ui/doc/doc_paragraphs_missing_punctuation.stderr @@ -0,0 +1,113 @@ +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:5:86 + | +LL | /// Returns the Answer to the Ultimate Question of Life, the Universe, and Everything + | ^ help: end the paragraph with some punctuation: `.` + | + = note: `-D clippy::doc-paragraphs-missing-punctuation` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_paragraphs_missing_punctuation)]` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:11:22 + | +LL | /// The `Option` type + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:16:17 + | +LL | /// No value + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:27:41 + | +LL | /// only the last line triggers the lint + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:40:56 + | +LL | /// + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:49:26 + | +LL | /// Here is a snippet + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:72:15 + | +LL | /// U+0001 + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:79:29 + | +LL | //! inner attributes too + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:90:47 + | +LL | /// **But sometimes it is missing a period** + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:95:46 + | +LL | /// _But sometimes it is missing a period_ + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:104:56 + | +LL | /// Doc comments can end with an [inline link](#anchor) + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:108:65 + | +LL | /// Some doc comments contain [link reference definitions][spec] + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:133:57 + | +LL | /// Doc comments with trailing blank lines are supported + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:139:48 + | +LL | /// This first paragraph is missing punctuation + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:143:34 + | +LL | /// And it has multiple sentences + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:146:37 + | +LL | /// Same for this third and last one + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:153:33 + | +LL | /// This ends with a code `span` + | ^ help: end the paragraph with some punctuation: `.` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:162:27 + | +LL | * Block doc comments work + | ^ help: end the paragraph with some punctuation: `.` + +error: aborting due to 18 previous errors + diff --git a/tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.rs b/tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.rs new file mode 100644 index 000000000000..3873f1d1edcf --- /dev/null +++ b/tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.rs @@ -0,0 +1,13 @@ +#![feature(custom_inner_attributes)] +#![rustfmt::skip] +#![warn(clippy::doc_paragraphs_missing_punctuation)] +//@no-rustfix + +enum UnfixableTrailers { + /// Sometimes the doc comment ends with parentheses (like this) + //~^ doc_paragraphs_missing_punctuation + EndsWithParens, + /// This comment ends with "a quote" + //~^ doc_paragraphs_missing_punctuation + QuoteFailing, +} diff --git a/tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.stderr b/tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.stderr new file mode 100644 index 000000000000..e8587eace2d6 --- /dev/null +++ b/tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.stderr @@ -0,0 +1,20 @@ +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.rs:7:68 + | +LL | /// Sometimes the doc comment ends with parentheses (like this) + | ^ + | + = help: end the paragraph with some punctuation + = note: `-D clippy::doc-paragraphs-missing-punctuation` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_paragraphs_missing_punctuation)]` + +error: doc paragraphs should end with a terminal punctuation mark + --> tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.rs:10:41 + | +LL | /// This comment ends with "a quote" + | ^ + | + = help: end the paragraph with some punctuation + +error: aborting due to 2 previous errors + diff --git a/tests/ui/equatable_if_let.fixed b/tests/ui/equatable_if_let.fixed index 58fbad64a78d..2cf69cf7b2fd 100644 --- a/tests/ui/equatable_if_let.fixed +++ b/tests/ui/equatable_if_let.fixed @@ -1,14 +1,6 @@ //@aux-build:proc_macros.rs - -#![allow( - unused_variables, - dead_code, - clippy::derive_partial_eq_without_eq, - clippy::needless_ifs -)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::needless_ifs)] #![warn(clippy::equatable_if_let)] - -extern crate proc_macros; use proc_macros::{external, inline_macros}; use std::cmp::Ordering; @@ -48,7 +40,6 @@ impl PartialEq for NotStructuralEq { } } -#[inline_macros] fn main() { let a = 2; let b = 3; @@ -95,13 +86,6 @@ fn main() { //~^ equatable_if_let if matches!(h, NoPartialEqStruct { a: 2, b: false }) {} //~^ equatable_if_let - - if "abc" == inline!("abc") { - //~^ equatable_if_let - println!("OK"); - } - - external!({ if let 2 = $a {} }); } mod issue8710 { @@ -139,3 +123,92 @@ mod issue8710 { } } } + +#[inline_macros] +fn issue14548() { + if let inline!("abc") = "abc" { + println!("OK"); + } + + let a = 2; + external!({ if let 2 = $a {} }); + + // Don't lint: `==`/`matches!` might be correct for a particular `$($font)|*`, but not in general + macro_rules! m1 { + ($($font:pat_param)|*) => { + if let $($font)|* = "from_expansion" {} + } + } + m1!("foo"); + m1!("Sans" | "Serif" | "Sans Mono"); + m1!(inline!("foo")); + + // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in + // general + macro_rules! m2 { + ($from_root_ctxt:pat) => { + if let $from_root_ctxt = "from_expansion" {} + }; + } + m2!("foo"); + m2!("Sans" | "Serif" | "Sans Mono"); + m2!(inline!("foo")); + + // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in + // general + macro_rules! m3 { + ($from_root_ctxt:expr) => { + if let "from_expansion" = $from_root_ctxt {} + }; + } + m3!("foo"); + m3!("foo"); + m3!(inline!("foo")); + + // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in + // general. Don't get confused by the scrutinee coming from macro invocation + macro_rules! m4 { + ($from_root_ctxt:pat) => { + if let $from_root_ctxt = inline!("from_expansion") {} + }; + } + m4!("foo"); + m4!("Sans" | "Serif" | "Sans Mono"); + m4!(inline!("foo")); + + // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in + // general. Don't get confused by the scrutinee coming from macro invocation + macro_rules! m5 { + ($from_root_ctxt:expr) => { + if let inline!("from_expansion") = $from_root_ctxt {} + }; + } + m5!("foo"); + m5!("foo"); + m5!(inline!("foo")); + + // Would be nice to lint: both sides are macro _invocations_, so the suggestion is correct in + // general + if let inline!("foo") = inline!("bar") {} +} + +// PartialEq is not stable in consts yet +fn issue15376() { + enum NonConstEq { + A, + B, + } + impl PartialEq for NonConstEq { + fn eq(&self, _other: &Self) -> bool { + true + } + } + + const N: NonConstEq = NonConstEq::A; + + // `impl PartialEq` is not const, suggest `matches!` + const _: u32 = if matches!(N, NonConstEq::A) { 0 } else { 1 }; + //~^ ERROR: this pattern matching can be expressed using `matches!` + const _: u32 = if matches!(Some(N), Some(NonConstEq::A)) { 0 } else { 1 }; + //~^ ERROR: this pattern matching can be expressed using `matches!` +} diff --git a/tests/ui/equatable_if_let.rs b/tests/ui/equatable_if_let.rs index cca97c76b509..94302b3dfa65 100644 --- a/tests/ui/equatable_if_let.rs +++ b/tests/ui/equatable_if_let.rs @@ -1,14 +1,6 @@ //@aux-build:proc_macros.rs - -#![allow( - unused_variables, - dead_code, - clippy::derive_partial_eq_without_eq, - clippy::needless_ifs -)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::needless_ifs)] #![warn(clippy::equatable_if_let)] - -extern crate proc_macros; use proc_macros::{external, inline_macros}; use std::cmp::Ordering; @@ -48,7 +40,6 @@ impl PartialEq for NotStructuralEq { } } -#[inline_macros] fn main() { let a = 2; let b = 3; @@ -95,13 +86,6 @@ fn main() { //~^ equatable_if_let if let NoPartialEqStruct { a: 2, b: false } = h {} //~^ equatable_if_let - - if let inline!("abc") = "abc" { - //~^ equatable_if_let - println!("OK"); - } - - external!({ if let 2 = $a {} }); } mod issue8710 { @@ -139,3 +123,92 @@ mod issue8710 { } } } + +#[inline_macros] +fn issue14548() { + if let inline!("abc") = "abc" { + println!("OK"); + } + + let a = 2; + external!({ if let 2 = $a {} }); + + // Don't lint: `==`/`matches!` might be correct for a particular `$($font)|*`, but not in general + macro_rules! m1 { + ($($font:pat_param)|*) => { + if let $($font)|* = "from_expansion" {} + } + } + m1!("foo"); + m1!("Sans" | "Serif" | "Sans Mono"); + m1!(inline!("foo")); + + // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in + // general + macro_rules! m2 { + ($from_root_ctxt:pat) => { + if let $from_root_ctxt = "from_expansion" {} + }; + } + m2!("foo"); + m2!("Sans" | "Serif" | "Sans Mono"); + m2!(inline!("foo")); + + // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in + // general + macro_rules! m3 { + ($from_root_ctxt:expr) => { + if let "from_expansion" = $from_root_ctxt {} + }; + } + m3!("foo"); + m3!("foo"); + m3!(inline!("foo")); + + // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in + // general. Don't get confused by the scrutinee coming from macro invocation + macro_rules! m4 { + ($from_root_ctxt:pat) => { + if let $from_root_ctxt = inline!("from_expansion") {} + }; + } + m4!("foo"); + m4!("Sans" | "Serif" | "Sans Mono"); + m4!(inline!("foo")); + + // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in + // general. Don't get confused by the scrutinee coming from macro invocation + macro_rules! m5 { + ($from_root_ctxt:expr) => { + if let inline!("from_expansion") = $from_root_ctxt {} + }; + } + m5!("foo"); + m5!("foo"); + m5!(inline!("foo")); + + // Would be nice to lint: both sides are macro _invocations_, so the suggestion is correct in + // general + if let inline!("foo") = inline!("bar") {} +} + +// PartialEq is not stable in consts yet +fn issue15376() { + enum NonConstEq { + A, + B, + } + impl PartialEq for NonConstEq { + fn eq(&self, _other: &Self) -> bool { + true + } + } + + const N: NonConstEq = NonConstEq::A; + + // `impl PartialEq` is not const, suggest `matches!` + const _: u32 = if let NonConstEq::A = N { 0 } else { 1 }; + //~^ ERROR: this pattern matching can be expressed using `matches!` + const _: u32 = if let Some(NonConstEq::A) = Some(N) { 0 } else { 1 }; + //~^ ERROR: this pattern matching can be expressed using `matches!` +} diff --git a/tests/ui/equatable_if_let.stderr b/tests/ui/equatable_if_let.stderr index dd1832ad68b2..8cc78daa2535 100644 --- a/tests/ui/equatable_if_let.stderr +++ b/tests/ui/equatable_if_let.stderr @@ -1,5 +1,5 @@ error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:64:8 + --> tests/ui/equatable_if_let.rs:55:8 | LL | if let 2 = a {} | ^^^^^^^^^ help: try: `a == 2` @@ -8,100 +8,106 @@ LL | if let 2 = a {} = help: to override `-D warnings` add `#[allow(clippy::equatable_if_let)]` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:66:8 + --> tests/ui/equatable_if_let.rs:57:8 | LL | if let Ordering::Greater = a.cmp(&b) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:68:8 + --> tests/ui/equatable_if_let.rs:59:8 | LL | if let Some(2) = c {} | ^^^^^^^^^^^^^^^ help: try: `c == Some(2)` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:70:8 + --> tests/ui/equatable_if_let.rs:61:8 | LL | if let Struct { a: 2, b: false } = d {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:72:8 + --> tests/ui/equatable_if_let.rs:63:8 | LL | if let Enum::TupleVariant(32, 64) = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:74:8 + --> tests/ui/equatable_if_let.rs:65:8 | LL | if let Enum::RecordVariant { a: 64, b: 32 } = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:76:8 + --> tests/ui/equatable_if_let.rs:67:8 | LL | if let Enum::UnitVariant = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:78:8 + --> tests/ui/equatable_if_let.rs:69:8 | LL | if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })` error: this pattern matching can be expressed using `matches!` - --> tests/ui/equatable_if_let.rs:88:8 + --> tests/ui/equatable_if_let.rs:79:8 | LL | if let NotPartialEq::A = f {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:90:8 + --> tests/ui/equatable_if_let.rs:81:8 | LL | if let NotStructuralEq::A = g {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A` error: this pattern matching can be expressed using `matches!` - --> tests/ui/equatable_if_let.rs:92:8 + --> tests/ui/equatable_if_let.rs:83:8 | LL | if let Some(NotPartialEq::A) = Some(f) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))` error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:94:8 + --> tests/ui/equatable_if_let.rs:85:8 | LL | if let Some(NotStructuralEq::A) = Some(g) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)` error: this pattern matching can be expressed using `matches!` - --> tests/ui/equatable_if_let.rs:96:8 + --> tests/ui/equatable_if_let.rs:87:8 | LL | if let NoPartialEqStruct { a: 2, b: false } = h {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })` -error: this pattern matching can be expressed using equality - --> tests/ui/equatable_if_let.rs:99:8 - | -LL | if let inline!("abc") = "abc" { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"abc" == inline!("abc")` - error: this pattern matching can be expressed using `matches!` - --> tests/ui/equatable_if_let.rs:109:12 + --> tests/ui/equatable_if_let.rs:93:12 | LL | if let Some('i') = cs.iter().next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(cs.iter().next(), Some('i'))` error: this pattern matching can be expressed using `matches!` - --> tests/ui/equatable_if_let.rs:117:12 + --> tests/ui/equatable_if_let.rs:101:12 | LL | if let Some(1) = cs.iter().next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(cs.iter().next(), Some(1))` error: this pattern matching can be expressed using `matches!` - --> tests/ui/equatable_if_let.rs:135:12 + --> tests/ui/equatable_if_let.rs:119:12 | LL | if let Some(MyEnum::B) = get_enum() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(get_enum(), Some(MyEnum::B))` -error: aborting due to 17 previous errors +error: this pattern matching can be expressed using `matches!` + --> tests/ui/equatable_if_let.rs:210:23 + | +LL | const _: u32 = if let NonConstEq::A = N { 0 } else { 1 }; + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(N, NonConstEq::A)` + +error: this pattern matching can be expressed using `matches!` + --> tests/ui/equatable_if_let.rs:212:23 + | +LL | const _: u32 = if let Some(NonConstEq::A) = Some(N) { 0 } else { 1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(N), Some(NonConstEq::A))` + +error: aborting due to 18 previous errors diff --git a/tests/ui/equatable_if_let_const_cmp.fixed b/tests/ui/equatable_if_let_const_cmp.fixed new file mode 100644 index 000000000000..51dab25ed6d8 --- /dev/null +++ b/tests/ui/equatable_if_let_const_cmp.fixed @@ -0,0 +1,24 @@ +#![warn(clippy::equatable_if_let)] +#![allow(clippy::eq_op)] +#![feature(const_trait_impl, const_cmp)] + +fn issue15376() { + enum ConstEq { + A, + B, + } + impl const PartialEq for ConstEq { + fn eq(&self, _other: &Self) -> bool { + true + } + } + + const C: ConstEq = ConstEq::A; + + // `impl PartialEq` is const... but we still suggest `matches!` for now + // TODO: detect this and suggest `=` + const _: u32 = if matches!(C, ConstEq::A) { 0 } else { 1 }; + //~^ ERROR: this pattern matching can be expressed using `matches!` + const _: u32 = if matches!(Some(C), Some(ConstEq::A)) { 0 } else { 1 }; + //~^ ERROR: this pattern matching can be expressed using `matches!` +} diff --git a/tests/ui/equatable_if_let_const_cmp.rs b/tests/ui/equatable_if_let_const_cmp.rs new file mode 100644 index 000000000000..b402e05c53de --- /dev/null +++ b/tests/ui/equatable_if_let_const_cmp.rs @@ -0,0 +1,24 @@ +#![warn(clippy::equatable_if_let)] +#![allow(clippy::eq_op)] +#![feature(const_trait_impl, const_cmp)] + +fn issue15376() { + enum ConstEq { + A, + B, + } + impl const PartialEq for ConstEq { + fn eq(&self, _other: &Self) -> bool { + true + } + } + + const C: ConstEq = ConstEq::A; + + // `impl PartialEq` is const... but we still suggest `matches!` for now + // TODO: detect this and suggest `=` + const _: u32 = if let ConstEq::A = C { 0 } else { 1 }; + //~^ ERROR: this pattern matching can be expressed using `matches!` + const _: u32 = if let Some(ConstEq::A) = Some(C) { 0 } else { 1 }; + //~^ ERROR: this pattern matching can be expressed using `matches!` +} diff --git a/tests/ui/equatable_if_let_const_cmp.stderr b/tests/ui/equatable_if_let_const_cmp.stderr new file mode 100644 index 000000000000..ec72e42d6430 --- /dev/null +++ b/tests/ui/equatable_if_let_const_cmp.stderr @@ -0,0 +1,17 @@ +error: this pattern matching can be expressed using `matches!` + --> tests/ui/equatable_if_let_const_cmp.rs:20:23 + | +LL | const _: u32 = if let ConstEq::A = C { 0 } else { 1 }; + | ^^^^^^^^^^^^^^^^^^ help: try: `matches!(C, ConstEq::A)` + | + = note: `-D clippy::equatable-if-let` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::equatable_if_let)]` + +error: this pattern matching can be expressed using `matches!` + --> tests/ui/equatable_if_let_const_cmp.rs:22:23 + | +LL | const _: u32 = if let Some(ConstEq::A) = Some(C) { 0 } else { 1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(C), Some(ConstEq::A))` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/explicit_deref_methods.fixed b/tests/ui/explicit_deref_methods.fixed index 97e8e0bafe4f..6c29630dc3a5 100644 --- a/tests/ui/explicit_deref_methods.fixed +++ b/tests/ui/explicit_deref_methods.fixed @@ -156,3 +156,116 @@ fn main() { let _ = &&mut **&mut x; //~ explicit_deref_methods let _ = &&mut ***(&mut &mut x); //~ explicit_deref_methods } + +mod issue_15392 { + use std::ops::{Deref, DerefMut}; + + struct Wrapper(String); + + impl Deref for Wrapper { + type Target = str; + fn deref(&self) -> &Self::Target { + // forwarding is ok + let res = Deref::deref(&self.0); + // we let `deref_mut` pass as well + let _ = DerefMut::deref_mut(&mut String::new()); + res + } + } + + impl DerefMut for Wrapper { + fn deref_mut(&mut self) -> &mut Self::Target { + // forwarding is ok + let res = DerefMut::deref_mut(&mut self.0); + // we let `deref` pass as well + let _ = Deref::deref(&String::new()); + res + } + } + + struct A(String); + struct AA(String); + struct AB(String); + + impl Deref for A { + type Target = str; + + fn deref(&self) -> &Self::Target { + // in a top-level `Deref` impl, ok + let _ = self.0.deref(); + // in a top-level `Deref` impl, acceptable + let _ = String::new().deref_mut(); + + #[allow(non_local_definitions)] + impl Deref for AA { + type Target = str; + fn deref(&self) -> &Self::Target { + // in a nested `Deref` impl, acceptable + let _ = String::new().deref_mut(); + // in a nested `Deref` impl, ok + self.0.deref() + } + } + + // still in a top-level `Deref` impl, ok + let _ = self.0.deref(); + // still in a top-level `Deref` impl, acceptable + let _ = String::new().deref_mut(); + + #[allow(non_local_definitions)] + impl DerefMut for AA { + fn deref_mut(&mut self) -> &mut Self::Target { + // in a top-level `DerefMut` impl, acceptable + let _ = self.0.deref(); + // in a top-level `DerefMut` impl, ok + self.0.deref_mut() + } + } + + // still in a top-level `Deref` impl, acceptable + let _ = String::new().deref_mut(); + // still in a top-level `Deref` impl, ok + self.0.deref() + } + } + + impl DerefMut for A { + fn deref_mut(&mut self) -> &mut Self::Target { + // in a top-level `DerefMut` impl, acceptable + let _ = self.0.deref(); + // in a top-level `DerefMut` impl, ok + let _ = self.0.deref_mut(); + + #[allow(non_local_definitions)] + impl Deref for AB { + type Target = str; + fn deref(&self) -> &Self::Target { + // in a nested `Deref` impl, acceptable + let _ = String::new().deref_mut(); + // in a nested `Deref` impl, ok + Deref::deref(&self.0) + } + } + + // still in a top-level `DerefMut` impl, acceptable + let _ = self.0.deref(); + // still in a top-level `DerefMut` impl, ok + let _ = self.0.deref_mut(); + + #[allow(non_local_definitions)] + impl DerefMut for AB { + fn deref_mut(&mut self) -> &mut Self::Target { + // in a nested `DerefMut` impl, acceptable + self.0.deref(); + // in a nested `DerefMut` impl, ok + self.0.deref_mut() + } + } + + // still in a top-level `DerefMut` impl, acceptable + let _ = self.0.deref(); + // still in a top-level `DerefMut` impl, ok + self.0.deref_mut() + } + } +} diff --git a/tests/ui/explicit_deref_methods.rs b/tests/ui/explicit_deref_methods.rs index b689649d49dd..f6309cd404b8 100644 --- a/tests/ui/explicit_deref_methods.rs +++ b/tests/ui/explicit_deref_methods.rs @@ -156,3 +156,116 @@ fn main() { let _ = &DerefMut::deref_mut(&mut x); //~ explicit_deref_methods let _ = &DerefMut::deref_mut((&mut &mut x).deref_mut()); //~ explicit_deref_methods } + +mod issue_15392 { + use std::ops::{Deref, DerefMut}; + + struct Wrapper(String); + + impl Deref for Wrapper { + type Target = str; + fn deref(&self) -> &Self::Target { + // forwarding is ok + let res = Deref::deref(&self.0); + // we let `deref_mut` pass as well + let _ = DerefMut::deref_mut(&mut String::new()); + res + } + } + + impl DerefMut for Wrapper { + fn deref_mut(&mut self) -> &mut Self::Target { + // forwarding is ok + let res = DerefMut::deref_mut(&mut self.0); + // we let `deref` pass as well + let _ = Deref::deref(&String::new()); + res + } + } + + struct A(String); + struct AA(String); + struct AB(String); + + impl Deref for A { + type Target = str; + + fn deref(&self) -> &Self::Target { + // in a top-level `Deref` impl, ok + let _ = self.0.deref(); + // in a top-level `Deref` impl, acceptable + let _ = String::new().deref_mut(); + + #[allow(non_local_definitions)] + impl Deref for AA { + type Target = str; + fn deref(&self) -> &Self::Target { + // in a nested `Deref` impl, acceptable + let _ = String::new().deref_mut(); + // in a nested `Deref` impl, ok + self.0.deref() + } + } + + // still in a top-level `Deref` impl, ok + let _ = self.0.deref(); + // still in a top-level `Deref` impl, acceptable + let _ = String::new().deref_mut(); + + #[allow(non_local_definitions)] + impl DerefMut for AA { + fn deref_mut(&mut self) -> &mut Self::Target { + // in a top-level `DerefMut` impl, acceptable + let _ = self.0.deref(); + // in a top-level `DerefMut` impl, ok + self.0.deref_mut() + } + } + + // still in a top-level `Deref` impl, acceptable + let _ = String::new().deref_mut(); + // still in a top-level `Deref` impl, ok + self.0.deref() + } + } + + impl DerefMut for A { + fn deref_mut(&mut self) -> &mut Self::Target { + // in a top-level `DerefMut` impl, acceptable + let _ = self.0.deref(); + // in a top-level `DerefMut` impl, ok + let _ = self.0.deref_mut(); + + #[allow(non_local_definitions)] + impl Deref for AB { + type Target = str; + fn deref(&self) -> &Self::Target { + // in a nested `Deref` impl, acceptable + let _ = String::new().deref_mut(); + // in a nested `Deref` impl, ok + Deref::deref(&self.0) + } + } + + // still in a top-level `DerefMut` impl, acceptable + let _ = self.0.deref(); + // still in a top-level `DerefMut` impl, ok + let _ = self.0.deref_mut(); + + #[allow(non_local_definitions)] + impl DerefMut for AB { + fn deref_mut(&mut self) -> &mut Self::Target { + // in a nested `DerefMut` impl, acceptable + self.0.deref(); + // in a nested `DerefMut` impl, ok + self.0.deref_mut() + } + } + + // still in a top-level `DerefMut` impl, acceptable + let _ = self.0.deref(); + // still in a top-level `DerefMut` impl, ok + self.0.deref_mut() + } + } +} diff --git a/tests/ui/implicit_hasher.fixed b/tests/ui/implicit_hasher.fixed index bea5b9afc43a..882a545963b4 100644 --- a/tests/ui/implicit_hasher.fixed +++ b/tests/ui/implicit_hasher.fixed @@ -109,3 +109,27 @@ pub async fn election_vote(_data: HashMap { + $num * 10 + }; + } + + impl Foo for HashMap { + //~^ implicit_hasher + fn make() -> (Self, Self) { + (HashMap::default(), HashMap::with_capacity_and_hasher(times_ten!(5), Default::default())) + } + } + + impl Foo for HashSet { + //~^ implicit_hasher + fn make() -> (Self, Self) { + (HashSet::default(), HashSet::with_capacity_and_hasher(times_ten!(5), Default::default())) + } + } +} diff --git a/tests/ui/implicit_hasher.rs b/tests/ui/implicit_hasher.rs index afdf4da61650..186f9e9978e5 100644 --- a/tests/ui/implicit_hasher.rs +++ b/tests/ui/implicit_hasher.rs @@ -109,3 +109,27 @@ pub async fn election_vote(_data: HashMap) {} //~^ implicit_hasher fn main() {} + +mod issue16128 { + use super::*; + + macro_rules! times_ten { + ($num:expr) => { + $num * 10 + }; + } + + impl Foo for HashMap { + //~^ implicit_hasher + fn make() -> (Self, Self) { + (HashMap::new(), HashMap::with_capacity(times_ten!(5))) + } + } + + impl Foo for HashSet { + //~^ implicit_hasher + fn make() -> (Self, Self) { + (HashSet::new(), HashSet::with_capacity(times_ten!(5))) + } + } +} diff --git a/tests/ui/implicit_hasher.stderr b/tests/ui/implicit_hasher.stderr index 6735998ed654..326115c8e9a3 100644 --- a/tests/ui/implicit_hasher.stderr +++ b/tests/ui/implicit_hasher.stderr @@ -122,5 +122,33 @@ help: add a type parameter for `BuildHasher` LL | pub async fn election_vote(_data: HashMap) {} | +++++++++++++++++++++++++++++ +++ -error: aborting due to 9 previous errors +error: impl for `HashMap` should be generalized over different hashers + --> tests/ui/implicit_hasher.rs:122:40 + | +LL | impl Foo for HashMap { + | ^^^^^^^^^^^^^ + | +help: add a type parameter for `BuildHasher` + | +LL ~ impl Foo for HashMap { +LL | +LL | fn make() -> (Self, Self) { +LL ~ (HashMap::default(), HashMap::with_capacity_and_hasher(times_ten!(5), Default::default())) + | + +error: impl for `HashSet` should be generalized over different hashers + --> tests/ui/implicit_hasher.rs:129:37 + | +LL | impl Foo for HashSet { + | ^^^^^^^^^^ + | +help: add a type parameter for `BuildHasher` + | +LL ~ impl Foo for HashSet { +LL | +LL | fn make() -> (Self, Self) { +LL ~ (HashSet::default(), HashSet::with_capacity_and_hasher(times_ten!(5), Default::default())) + | + +error: aborting due to 11 previous errors diff --git a/tests/ui/missing_doc.rs b/tests/ui/missing_doc.rs deleted file mode 100644 index 705de959cb7d..000000000000 --- a/tests/ui/missing_doc.rs +++ /dev/null @@ -1,148 +0,0 @@ -//@needs-asm-support -//@aux-build: proc_macros.rs -//@aux-build: proc_macro_attr.rs - -#![warn(clippy::missing_docs_in_private_items)] -// When denying at the crate level, be sure to not get random warnings from the -// injected intrinsics by the compiler. -#![allow(dead_code)] -//! Some garbage docs for the crate here -#![doc = "More garbage"] - -#[macro_use] -extern crate proc_macro_attr; -extern crate proc_macros; - -use proc_macros::with_span; -use std::arch::global_asm; - -type Typedef = String; -//~^ missing_docs_in_private_items -pub type PubTypedef = String; - -mod module_no_dox {} -//~^ missing_docs_in_private_items -pub mod pub_module_no_dox {} - -/// dox -pub fn foo() {} -pub fn foo2() {} -fn foo3() {} -//~^ missing_docs_in_private_items -#[allow(clippy::missing_docs_in_private_items)] -pub fn foo4() {} - -// It sure is nice if doc(hidden) implies allow(missing_docs), and that it -// applies recursively -#[doc(hidden)] -mod a { - pub fn baz() {} - pub mod b { - pub fn baz() {} - } -} - -enum Baz { - //~^ missing_docs_in_private_items - BazA { a: isize, b: isize }, - //~^ missing_docs_in_private_items - //~| missing_docs_in_private_items - //~| missing_docs_in_private_items - BarB, - //~^ missing_docs_in_private_items -} - -pub enum PubBaz { - PubBazA { a: isize }, -} - -/// dox -pub enum PubBaz2 { - /// dox - PubBaz2A { - /// dox - a: isize, - }, -} - -#[allow(clippy::missing_docs_in_private_items)] -pub enum PubBaz3 { - PubBaz3A { b: isize }, -} - -#[doc(hidden)] -pub fn baz() {} - -const FOO: u32 = 0; -//~^ missing_docs_in_private_items -/// dox -pub const FOO1: u32 = 0; -#[allow(clippy::missing_docs_in_private_items)] -pub const FOO2: u32 = 0; -#[doc(hidden)] -pub const FOO3: u32 = 0; -pub const FOO4: u32 = 0; - -static BAR: u32 = 0; -//~^ missing_docs_in_private_items -/// dox -pub static BAR1: u32 = 0; -#[allow(clippy::missing_docs_in_private_items)] -pub static BAR2: u32 = 0; -#[doc(hidden)] -pub static BAR3: u32 = 0; -pub static BAR4: u32 = 0; - -mod internal_impl { - //~^ missing_docs_in_private_items - /// dox - pub fn documented() {} - pub fn undocumented1() {} - pub fn undocumented2() {} - fn undocumented3() {} - //~^ missing_docs_in_private_items - /// dox - pub mod globbed { - /// dox - pub fn also_documented() {} - pub fn also_undocumented1() {} - fn also_undocumented2() {} - //~^ missing_docs_in_private_items - } -} -/// dox -pub mod public_interface { - pub use crate::internal_impl::globbed::*; - pub use crate::internal_impl::{documented as foo, documented, undocumented1 as bar, undocumented2}; -} - -fn main() {} - -// Ensure global asm doesn't require documentation. -global_asm! { "" } - -// Don't lint proc macro output with an unexpected span. -with_span!(span pub struct FooPm { pub field: u32}); -with_span!(span pub struct FooPm2;); -with_span!(span pub enum FooPm3 { A, B(u32), C { field: u32 }}); -with_span!(span pub fn foo_pm() {}); -with_span!(span pub static FOO_PM: u32 = 0;); -with_span!(span pub const FOO2_PM: u32 = 0;); - -// Don't lint unnamed constants -const _: () = (); - -fn issue13298() { - //~^ missing_docs_in_private_items - // Rustdoc doesn't generate documentation for items within other items like fns or consts - const MSG: &str = "Hello, world!"; -} - -// issue #12197 -// Undocumented field originated inside of spanned proc-macro attribute -/// Some dox for struct. -#[rewrite_struct] -pub struct Test { - /// Dox - a: u8, -} diff --git a/tests/ui/missing_doc.stderr b/tests/ui/missing_doc.stderr deleted file mode 100644 index 63e440b82d14..000000000000 --- a/tests/ui/missing_doc.stderr +++ /dev/null @@ -1,102 +0,0 @@ -error: missing documentation for a type alias - --> tests/ui/missing_doc.rs:19:1 - | -LL | type Typedef = String; - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` - -error: missing documentation for a module - --> tests/ui/missing_doc.rs:23:1 - | -LL | mod module_no_dox {} - | ^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a function - --> tests/ui/missing_doc.rs:30:1 - | -LL | fn foo3() {} - | ^^^^^^^^^^^^ - -error: missing documentation for an enum - --> tests/ui/missing_doc.rs:45:1 - | -LL | / enum Baz { -LL | | -LL | | BazA { a: isize, b: isize }, -... | -LL | | } - | |_^ - -error: missing documentation for a variant - --> tests/ui/missing_doc.rs:47:5 - | -LL | BazA { a: isize, b: isize }, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a struct field - --> tests/ui/missing_doc.rs:47:12 - | -LL | BazA { a: isize, b: isize }, - | ^^^^^^^^ - -error: missing documentation for a struct field - --> tests/ui/missing_doc.rs:47:22 - | -LL | BazA { a: isize, b: isize }, - | ^^^^^^^^ - -error: missing documentation for a variant - --> tests/ui/missing_doc.rs:51:5 - | -LL | BarB, - | ^^^^ - -error: missing documentation for a constant - --> tests/ui/missing_doc.rs:76:1 - | -LL | const FOO: u32 = 0; - | ^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a static - --> tests/ui/missing_doc.rs:86:1 - | -LL | static BAR: u32 = 0; - | ^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a module - --> tests/ui/missing_doc.rs:96:1 - | -LL | / mod internal_impl { -LL | | -LL | | /// dox -LL | | pub fn documented() {} -... | -LL | | } - | |_^ - -error: missing documentation for a function - --> tests/ui/missing_doc.rs:102:5 - | -LL | fn undocumented3() {} - | ^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a function - --> tests/ui/missing_doc.rs:109:9 - | -LL | fn also_undocumented2() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a function - --> tests/ui/missing_doc.rs:135:1 - | -LL | / fn issue13298() { -LL | | -LL | | // Rustdoc doesn't generate documentation for items within other items like fns or consts -LL | | const MSG: &str = "Hello, world!"; -LL | | } - | |_^ - -error: aborting due to 14 previous errors - diff --git a/tests/ui/missing_doc_crate.rs b/tests/ui/missing_doc_crate.rs deleted file mode 100644 index e6e783a2bb40..000000000000 --- a/tests/ui/missing_doc_crate.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ check-pass - -#![warn(clippy::missing_docs_in_private_items)] -#![allow(clippy::doc_include_without_cfg)] -#![doc = include_str!("../../README.md")] - -fn main() {} diff --git a/tests/ui/missing_doc_crate_missing.rs b/tests/ui/missing_doc_crate_missing.rs deleted file mode 100644 index f55d8b67cb84..000000000000 --- a/tests/ui/missing_doc_crate_missing.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![warn(clippy::missing_docs_in_private_items)] -//~^ missing_docs_in_private_items - -fn main() {} diff --git a/tests/ui/missing_doc_crate_missing.stderr b/tests/ui/missing_doc_crate_missing.stderr deleted file mode 100644 index d6a4342c5031..000000000000 --- a/tests/ui/missing_doc_crate_missing.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: missing documentation for the crate - --> tests/ui/missing_doc_crate_missing.rs:1:1 - | -LL | / #![warn(clippy::missing_docs_in_private_items)] -... | -LL | | fn main() {} - | |____________^ - | - = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` - -error: aborting due to 1 previous error - diff --git a/tests/ui/missing_doc_impl.rs b/tests/ui/missing_doc_impl.rs deleted file mode 100644 index 034ce31dfe76..000000000000 --- a/tests/ui/missing_doc_impl.rs +++ /dev/null @@ -1,114 +0,0 @@ -//@aux-build: proc_macros.rs - -#![warn(clippy::missing_docs_in_private_items)] -#![allow(dead_code)] -#![feature(associated_type_defaults)] - -//! Some garbage docs for the crate here -#![doc = "More garbage"] - -extern crate proc_macros; -use proc_macros::with_span; - -struct Foo { - //~^ missing_docs_in_private_items - a: isize, - //~^ missing_docs_in_private_items - b: isize, - //~^ missing_docs_in_private_items -} - -pub struct PubFoo { - pub a: isize, - b: isize, - //~^ missing_docs_in_private_items -} - -#[allow(clippy::missing_docs_in_private_items)] -pub struct PubFoo2 { - pub a: isize, - pub c: isize, -} - -/// dox -pub trait A { - /// dox - fn foo(&self); - /// dox - fn foo_with_impl(&self) {} -} - -#[allow(clippy::missing_docs_in_private_items)] -trait B { - fn foo(&self); - fn foo_with_impl(&self) {} -} - -pub trait C { - fn foo(&self); - fn foo_with_impl(&self) {} -} - -#[allow(clippy::missing_docs_in_private_items)] -pub trait D { - fn dummy(&self) {} -} - -/// dox -pub trait E: Sized { - type AssociatedType; - type AssociatedTypeDef = Self; - - /// dox - type DocumentedType; - /// dox - type DocumentedTypeDef = Self; - /// dox - fn dummy(&self) {} -} - -impl Foo { - pub fn new() -> Self { - //~^ missing_docs_in_private_items - Foo { a: 0, b: 0 } - } - fn bar() {} - //~^ missing_docs_in_private_items -} - -impl PubFoo { - pub fn foo() {} - /// dox - pub fn foo1() {} - #[must_use = "yep"] - fn foo2() -> u32 { - //~^ missing_docs_in_private_items - 1 - } - #[allow(clippy::missing_docs_in_private_items)] - pub fn foo3() {} -} - -#[allow(clippy::missing_docs_in_private_items)] -trait F { - fn a(); - fn b(&self); -} - -// should need to redefine documentation for implementations of traits -impl F for Foo { - fn a() {} - fn b(&self) {} -} - -fn main() {} - -// don't lint proc macro output -with_span!(span - pub struct FooPm; - impl FooPm { - pub fn foo() {} - pub const fn bar() {} - pub const X: u32 = 0; - } -); diff --git a/tests/ui/missing_doc_impl.stderr b/tests/ui/missing_doc_impl.stderr deleted file mode 100644 index 999ff06f593e..000000000000 --- a/tests/ui/missing_doc_impl.stderr +++ /dev/null @@ -1,57 +0,0 @@ -error: missing documentation for a struct - --> tests/ui/missing_doc_impl.rs:13:1 - | -LL | / struct Foo { -LL | | -LL | | a: isize, -... | -LL | | } - | |_^ - | - = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]` - -error: missing documentation for a struct field - --> tests/ui/missing_doc_impl.rs:15:5 - | -LL | a: isize, - | ^^^^^^^^ - -error: missing documentation for a struct field - --> tests/ui/missing_doc_impl.rs:17:5 - | -LL | b: isize, - | ^^^^^^^^ - -error: missing documentation for a struct field - --> tests/ui/missing_doc_impl.rs:23:5 - | -LL | b: isize, - | ^^^^^^^^ - -error: missing documentation for an associated function - --> tests/ui/missing_doc_impl.rs:71:5 - | -LL | / pub fn new() -> Self { -LL | | -LL | | Foo { a: 0, b: 0 } -LL | | } - | |_____^ - -error: missing documentation for an associated function - --> tests/ui/missing_doc_impl.rs:75:5 - | -LL | fn bar() {} - | ^^^^^^^^^^^ - -error: missing documentation for an associated function - --> tests/ui/missing_doc_impl.rs:84:5 - | -LL | / fn foo2() -> u32 { -LL | | -LL | | 1 -LL | | } - | |_____^ - -error: aborting due to 7 previous errors - diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index 132673d5164a..c1512ba3e269 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -105,6 +105,14 @@ fn correct3() { } } +fn with_adjustment(f: &unsafe fn()) { + unsafe { + //~^ multiple_unsafe_ops_per_block + f(); + f(); + } +} + fn issue10064() { unsafe fn read_char_bad(ptr: *const u8) -> char { unsafe { char::from_u32_unchecked(*ptr.cast::()) } @@ -209,4 +217,99 @@ async fn issue13879() { } } +fn issue16076() { + #[derive(Clone, Copy)] + union U { + i: u32, + f: f32, + } + + let u = U { i: 0 }; + + // Taking a raw pointer to a place is safe since Rust 1.92 + unsafe { + _ = &raw const u.i; + _ = &raw const u.i; + } + + // Taking a reference to a union field is not safe + unsafe { + //~^ multiple_unsafe_ops_per_block + _ = &u.i; + _ = &u.i; + } + + // Check that we still check and lint the prefix of the raw pointer to a field access + #[expect(clippy::deref_addrof)] + unsafe { + //~^ multiple_unsafe_ops_per_block + _ = &raw const (*&raw const u).i; + _ = &raw const (*&raw const u).i; + } + + union V { + u: U, + } + + // Taking a raw pointer to a union field of an union field (etc.) is safe + let v = V { u }; + unsafe { + _ = &raw const v.u.i; + _ = &raw const v.u.i; + } + + // Check that unions in structs work properly as well + struct T { + u: U, + } + let t = T { u }; + unsafe { + _ = &raw const t.u.i; + _ = &raw const t.u.i; + } + + // As well as structs in unions + #[derive(Clone, Copy)] + struct X { + i: i32, + } + union Z { + x: X, + } + let z = Z { x: X { i: 0 } }; + unsafe { + _ = &raw const z.x.i; + _ = &raw const z.x.i; + } + + // If a field needs to be adjusted then it is accessed + struct S { + i: i32, + } + union W<'a> { + s: &'a S, + } + let s = S { i: 0 }; + let w = W { s: &s }; + unsafe { + //~^ multiple_unsafe_ops_per_block + _ = &raw const w.s.i; + _ = &raw const w.s.i; + } +} + +fn check_closures() { + unsafe fn apply(f: impl Fn()) { + todo!() + } + unsafe fn f(_x: i32) { + todo!() + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + apply(|| f(0)); + } +} + fn main() {} diff --git a/tests/ui/multiple_unsafe_ops_per_block.stderr b/tests/ui/multiple_unsafe_ops_per_block.stderr index 922a464c6b6e..63f7742b734b 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.stderr +++ b/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -113,24 +113,45 @@ LL | asm!("nop"); | ^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:110:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:109:5 + | +LL | / unsafe { +LL | | +LL | | f(); +LL | | f(); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:111:9 + | +LL | f(); + | ^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:112:9 + | +LL | f(); + | ^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:118:9 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:110:18 + --> tests/ui/multiple_unsafe_ops_per_block.rs:118:18 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:110:43 + --> tests/ui/multiple_unsafe_ops_per_block.rs:118:43 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:131:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:139:9 | LL | / unsafe { LL | | @@ -140,18 +161,18 @@ LL | | } | |_________^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:133:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:141:13 | LL | x(); | ^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:134:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:142:13 | LL | x(); | ^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:143:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:151:13 | LL | / unsafe { LL | | @@ -161,18 +182,18 @@ LL | | } | |_____________^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:145:17 + --> tests/ui/multiple_unsafe_ops_per_block.rs:153:17 | LL | T::X(); | ^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:146:17 + --> tests/ui/multiple_unsafe_ops_per_block.rs:154:17 | LL | T::X(); | ^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:154:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:162:9 | LL | / unsafe { LL | | @@ -182,18 +203,18 @@ LL | | } | |_________^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:156:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:164:13 | LL | x.0(); | ^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:157:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:165:13 | LL | x.0(); | ^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:184:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:192:5 | LL | / unsafe { LL | | @@ -204,18 +225,18 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:186:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:194:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ note: modification of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:187:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:195:9 | LL | STATIC += 1; | ^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:199:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:207:5 | LL | / unsafe { LL | | @@ -225,18 +246,18 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:201:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:209:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:202:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:210:9 | LL | foo_unchecked().await; | ^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:206:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:214:5 | LL | / unsafe { LL | | @@ -245,15 +266,98 @@ LL | | } | |_____^ | note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:208:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:216:9 | LL | Some(foo_unchecked()).unwrap_unchecked().await; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:208:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:216:14 | LL | Some(foo_unchecked()).unwrap_unchecked().await; | ^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:236:5 + | +LL | / unsafe { +LL | | +LL | | _ = &u.i; +LL | | _ = &u.i; +LL | | } + | |_____^ + | +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:238:14 + | +LL | _ = &u.i; + | ^^^ +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:239:14 + | +LL | _ = &u.i; + | ^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:244:5 + | +LL | / unsafe { +LL | | +LL | | _ = &raw const (*&raw const u).i; +LL | | _ = &raw const (*&raw const u).i; +LL | | } + | |_____^ + | +note: raw pointer dereference occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:246:24 + | +LL | _ = &raw const (*&raw const u).i; + | ^^^^^^^^^^^^^^^ +note: raw pointer dereference occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:247:24 + | +LL | _ = &raw const (*&raw const u).i; + | ^^^^^^^^^^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:294:5 + | +LL | / unsafe { +LL | | +LL | | _ = &raw const w.s.i; +LL | | _ = &raw const w.s.i; +LL | | } + | |_____^ + | +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:296:24 + | +LL | _ = &raw const w.s.i; + | ^^^ +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:297:24 + | +LL | _ = &raw const w.s.i; + | ^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:309:5 + | +LL | / unsafe { +LL | | +LL | | apply(|| f(0)); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:311:9 + | +LL | apply(|| f(0)); + | ^^^^^^^^^^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:311:18 + | +LL | apply(|| f(0)); + | ^^^^ + +error: aborting due to 16 previous errors diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed index a54a4ce13d53..08903ef7fdda 100644 --- a/tests/ui/redundant_pattern_matching_option.fixed +++ b/tests/ui/redundant_pattern_matching_option.fixed @@ -166,3 +166,32 @@ fn issue13902() { //~^ redundant_pattern_matching } } + +fn issue16045() { + fn f() -> Result<(), ()> { + let x = Ok::<_, ()>(Some(123)); + if x?.is_some() { + //~^ redundant_pattern_matching + } + + Ok(()) + } + + async fn g() { + struct F { + x: Option, + } + + impl Future for F { + type Output = Option; + + fn poll(self: std::pin::Pin<&mut Self>, _: &mut std::task::Context<'_>) -> std::task::Poll { + std::task::Poll::Ready(self.x) + } + } + let x = F { x: Some(123) }; + if x.await.is_some() { + //~^ redundant_pattern_matching + } + } +} diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs index 7252fce8cce6..95eff3f9ebf9 100644 --- a/tests/ui/redundant_pattern_matching_option.rs +++ b/tests/ui/redundant_pattern_matching_option.rs @@ -202,3 +202,32 @@ fn issue13902() { //~^ redundant_pattern_matching } } + +fn issue16045() { + fn f() -> Result<(), ()> { + let x = Ok::<_, ()>(Some(123)); + if let Some(_) = x? { + //~^ redundant_pattern_matching + } + + Ok(()) + } + + async fn g() { + struct F { + x: Option, + } + + impl Future for F { + type Output = Option; + + fn poll(self: std::pin::Pin<&mut Self>, _: &mut std::task::Context<'_>) -> std::task::Poll { + std::task::Poll::Ready(self.x) + } + } + let x = F { x: Some(123) }; + if let Some(_) = x.await { + //~^ redundant_pattern_matching + } + } +} diff --git a/tests/ui/redundant_pattern_matching_option.stderr b/tests/ui/redundant_pattern_matching_option.stderr index e5a6598898aa..6fd0c5a6f859 100644 --- a/tests/ui/redundant_pattern_matching_option.stderr +++ b/tests/ui/redundant_pattern_matching_option.stderr @@ -224,5 +224,17 @@ error: redundant pattern matching, consider using `is_none()` LL | let _ = matches!(*p, None); | ^^^^^^^^^^^^^^^^^^ help: try: `(*p).is_none()` -error: aborting due to 31 previous errors +error: redundant pattern matching, consider using `is_some()` + --> tests/ui/redundant_pattern_matching_option.rs:209:16 + | +LL | if let Some(_) = x? { + | -------^^^^^^^----- help: try: `if x?.is_some()` + +error: redundant pattern matching, consider using `is_some()` + --> tests/ui/redundant_pattern_matching_option.rs:229:16 + | +LL | if let Some(_) = x.await { + | -------^^^^^^^---------- help: try: `if x.await.is_some()` + +error: aborting due to 33 previous errors diff --git a/tests/ui/sliced_string_as_bytes.fixed b/tests/ui/sliced_string_as_bytes.fixed index 16c0daff78fd..b5576188b83f 100644 --- a/tests/ui/sliced_string_as_bytes.fixed +++ b/tests/ui/sliced_string_as_bytes.fixed @@ -32,6 +32,12 @@ fn main() { let bytes = &"consectetur adipiscing".as_bytes()[..=5]; //~^ sliced_string_as_bytes + // this lint is a perf lint meant to catch utf-8 alignment checks. + // while the slicing here *is* redundant, it's more like a needless borrow, and shouldn't affect + // perf + let bytes = s[..].as_bytes(); + let bytes = string[..].as_bytes(); + let f = Foo; let bytes = f[0..4].as_bytes(); } diff --git a/tests/ui/sliced_string_as_bytes.rs b/tests/ui/sliced_string_as_bytes.rs index 67985ae5b984..58b8d9290294 100644 --- a/tests/ui/sliced_string_as_bytes.rs +++ b/tests/ui/sliced_string_as_bytes.rs @@ -32,6 +32,12 @@ fn main() { let bytes = "consectetur adipiscing"[..=5].as_bytes(); //~^ sliced_string_as_bytes + // this lint is a perf lint meant to catch utf-8 alignment checks. + // while the slicing here *is* redundant, it's more like a needless borrow, and shouldn't affect + // perf + let bytes = s[..].as_bytes(); + let bytes = string[..].as_bytes(); + let f = Foo; let bytes = f[0..4].as_bytes(); } diff --git a/tests/ui/transmute.rs b/tests/ui/transmute.rs index e7099104f942..afb79deac20f 100644 --- a/tests/ui/transmute.rs +++ b/tests/ui/transmute.rs @@ -128,4 +128,17 @@ fn bytes_to_str(mb: &mut [u8]) { //~^ transmute_bytes_to_str } +fn issue16104() { + let b = vec![1_u8, 2_u8]; + macro_rules! take_ref { + ($x:expr) => { + $x.as_slice() + }; + } + unsafe { + let _: &str = std::mem::transmute(take_ref!(b)); + //~^ transmute_bytes_to_str + } +} + fn main() {} diff --git a/tests/ui/transmute.stderr b/tests/ui/transmute.stderr index 9478db09481a..6f9a0b717fc9 100644 --- a/tests/ui/transmute.stderr +++ b/tests/ui/transmute.stderr @@ -106,5 +106,11 @@ error: transmute from a `&[u8]` to a `&str` LL | const _: &str = unsafe { std::mem::transmute(B) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)` -error: aborting due to 16 previous errors +error: transmute from a `&[u8]` to a `&str` + --> tests/ui/transmute.rs:139:23 + | +LL | let _: &str = std::mem::transmute(take_ref!(b)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(take_ref!(b)).unwrap()` + +error: aborting due to 17 previous errors diff --git a/tests/ui/transmute_ref_to_ref.rs b/tests/ui/transmute_ref_to_ref.rs index 8bdf07b4a428..ed8fb8083291 100644 --- a/tests/ui/transmute_ref_to_ref.rs +++ b/tests/ui/transmute_ref_to_ref.rs @@ -18,3 +18,23 @@ fn main() { //~^ transmute_ptr_to_ptr } } + +fn issue16104(make_ptr: fn() -> *const u32) { + macro_rules! call { + ($x:expr) => { + $x() + }; + } + macro_rules! take_ref { + ($x:expr) => { + &$x + }; + } + + unsafe { + let _: *const f32 = std::mem::transmute(call!(make_ptr)); + //~^ transmute_ptr_to_ptr + let _: &f32 = std::mem::transmute(take_ref!(1u32)); + //~^ transmute_ptr_to_ptr + } +} diff --git a/tests/ui/transmute_ref_to_ref.stderr b/tests/ui/transmute_ref_to_ref.stderr index e8d659f9c5d8..1b845ef859d8 100644 --- a/tests/ui/transmute_ref_to_ref.stderr +++ b/tests/ui/transmute_ref_to_ref.stderr @@ -22,5 +22,23 @@ error: transmute from a reference to a reference LL | let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])` -error: aborting due to 3 previous errors +error: transmute from a pointer to a pointer + --> tests/ui/transmute_ref_to_ref.rs:35:29 + | +LL | let _: *const f32 = std::mem::transmute(call!(make_ptr)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `pointer::cast` instead + | +LL - let _: *const f32 = std::mem::transmute(call!(make_ptr)); +LL + let _: *const f32 = call!(make_ptr).cast::(); + | + +error: transmute from a reference to a reference + --> tests/ui/transmute_ref_to_ref.rs:37:23 + | +LL | let _: &f32 = std::mem::transmute(take_ref!(1u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(take_ref!(1u32) as *const u32 as *const f32)` + +error: aborting due to 5 previous errors diff --git a/tests/ui/unchecked_time_subtraction.stderr b/tests/ui/unchecked_time_subtraction.stderr index 7a39712269cf..c129497447fc 100644 --- a/tests/ui/unchecked_time_subtraction.stderr +++ b/tests/ui/unchecked_time_subtraction.stderr @@ -1,4 +1,4 @@ -error: unchecked subtraction of a 'Duration' from an 'Instant' +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction.rs:9:13 | LL | let _ = _first - second; @@ -7,43 +7,43 @@ LL | let _ = _first - second; = note: `-D clippy::unchecked-time-subtraction` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unchecked_time_subtraction)]` -error: unchecked subtraction of a 'Duration' from an 'Instant' +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction.rs:12:13 | LL | let _ = Instant::now() - Duration::from_secs(5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(Duration::from_secs(5)).unwrap()` -error: unchecked subtraction of a 'Duration' from an 'Instant' +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction.rs:15:13 | LL | let _ = _first - Duration::from_secs(5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `_first.checked_sub(Duration::from_secs(5)).unwrap()` -error: unchecked subtraction of a 'Duration' from an 'Instant' +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction.rs:18:13 | LL | let _ = Instant::now() - second; | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(second).unwrap()` -error: unchecked subtraction between 'Duration' values +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction.rs:25:13 | LL | let _ = dur1 - dur2; | ^^^^^^^^^^^ help: try: `dur1.checked_sub(dur2).unwrap()` -error: unchecked subtraction between 'Duration' values +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction.rs:28:13 | LL | let _ = Duration::from_secs(10) - Duration::from_secs(5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::from_secs(10).checked_sub(Duration::from_secs(5)).unwrap()` -error: unchecked subtraction between 'Duration' values +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction.rs:31:13 | LL | let _ = second - dur1; | ^^^^^^^^^^^^^ help: try: `second.checked_sub(dur1).unwrap()` -error: unchecked subtraction between 'Duration' values +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction.rs:35:13 | LL | let _ = 2 * dur1 - dur2; diff --git a/tests/ui/unchecked_time_subtraction_unfixable.stderr b/tests/ui/unchecked_time_subtraction_unfixable.stderr index c25c112b06ce..017e5b1c7c11 100644 --- a/tests/ui/unchecked_time_subtraction_unfixable.stderr +++ b/tests/ui/unchecked_time_subtraction_unfixable.stderr @@ -1,4 +1,4 @@ -error: unchecked subtraction between 'Duration' values +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction_unfixable.rs:12:13 | LL | let _ = dur1 - dur2 - dur3; @@ -7,19 +7,19 @@ LL | let _ = dur1 - dur2 - dur3; = note: `-D clippy::unchecked-time-subtraction` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unchecked_time_subtraction)]` -error: unchecked subtraction between 'Duration' values +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction_unfixable.rs:12:13 | LL | let _ = dur1 - dur2 - dur3; | ^^^^^^^^^^^ help: try: `dur1.checked_sub(dur2).unwrap()` -error: unchecked subtraction of a 'Duration' from an 'Instant' +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction_unfixable.rs:19:13 | LL | let _ = instant1 - dur2 - dur3; | ^^^^^^^^^^^^^^^^^^^^^^ -error: unchecked subtraction of a 'Duration' from an 'Instant' +error: unchecked subtraction of a `Duration` --> tests/ui/unchecked_time_subtraction_unfixable.rs:19:13 | LL | let _ = instant1 - dur2 - dur3; diff --git a/tests/ui/useless_asref.fixed b/tests/ui/useless_asref.fixed index 3c3ea5a736d4..54a7c0a8c080 100644 --- a/tests/ui/useless_asref.fixed +++ b/tests/ui/useless_asref.fixed @@ -258,6 +258,41 @@ fn issue_14828() { ().as_ref(); } +fn issue16098(exts: Vec<&str>) { + use std::borrow::Cow; + + let v: Vec> = exts.iter().map(|s| Cow::Borrowed(*s)).collect(); + //~^ useless_asref + + trait Identity { + fn id(self) -> Self + where + Self: Sized, + { + self + } + } + impl Identity for &str {} + + let v: Vec> = exts.iter().map(|s| Cow::Borrowed(s.id())).collect(); + //~^ useless_asref + + let v: Vec> = exts + .iter() + .map(|s| Cow::Borrowed(*std::convert::identity(s))) + //~^ useless_asref + .collect(); + + struct Wrapper<'a>(&'a str); + let exts_field: Vec = exts.iter().map(|s| Wrapper(s)).collect(); + let v: Vec> = exts_field.iter().map(|w| Cow::Borrowed(w.0)).collect(); + //~^ useless_asref + + let exts_index: Vec<&[&str]> = exts.iter().map(|s| std::slice::from_ref(s)).collect(); + let v: Vec> = exts_index.iter().map(|arr| Cow::Borrowed(arr[0])).collect(); + //~^ useless_asref +} + fn main() { not_ok(); ok(); diff --git a/tests/ui/useless_asref.rs b/tests/ui/useless_asref.rs index c173dd677152..1b9ce1d46233 100644 --- a/tests/ui/useless_asref.rs +++ b/tests/ui/useless_asref.rs @@ -258,6 +258,41 @@ fn issue_14828() { ().as_ref(); } +fn issue16098(exts: Vec<&str>) { + use std::borrow::Cow; + + let v: Vec> = exts.iter().map(|s| Cow::Borrowed(s.as_ref())).collect(); + //~^ useless_asref + + trait Identity { + fn id(self) -> Self + where + Self: Sized, + { + self + } + } + impl Identity for &str {} + + let v: Vec> = exts.iter().map(|s| Cow::Borrowed(s.id().as_ref())).collect(); + //~^ useless_asref + + let v: Vec> = exts + .iter() + .map(|s| Cow::Borrowed(std::convert::identity(s).as_ref())) + //~^ useless_asref + .collect(); + + struct Wrapper<'a>(&'a str); + let exts_field: Vec = exts.iter().map(|s| Wrapper(s)).collect(); + let v: Vec> = exts_field.iter().map(|w| Cow::Borrowed(w.0.as_ref())).collect(); + //~^ useless_asref + + let exts_index: Vec<&[&str]> = exts.iter().map(|s| std::slice::from_ref(s)).collect(); + let v: Vec> = exts_index.iter().map(|arr| Cow::Borrowed(arr[0].as_ref())).collect(); + //~^ useless_asref +} + fn main() { not_ok(); ok(); diff --git a/tests/ui/useless_asref.stderr b/tests/ui/useless_asref.stderr index 8255f5d9d2ab..861472b4419e 100644 --- a/tests/ui/useless_asref.stderr +++ b/tests/ui/useless_asref.stderr @@ -112,5 +112,35 @@ error: this call to `as_ref.map(...)` does nothing LL | Some(1).as_ref().map(|&x| x.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(1).clone()` -error: aborting due to 18 previous errors +error: this call to `as_ref` does nothing + --> tests/ui/useless_asref.rs:264:66 + | +LL | let v: Vec> = exts.iter().map(|s| Cow::Borrowed(s.as_ref())).collect(); + | ^^^^^^^^^^ help: try: `*s` + +error: this call to `as_ref` does nothing + --> tests/ui/useless_asref.rs:277:66 + | +LL | let v: Vec> = exts.iter().map(|s| Cow::Borrowed(s.id().as_ref())).collect(); + | ^^^^^^^^^^^^^^^ help: try: `s.id()` + +error: this call to `as_ref` does nothing + --> tests/ui/useless_asref.rs:282:32 + | +LL | .map(|s| Cow::Borrowed(std::convert::identity(s).as_ref())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `*std::convert::identity(s)` + +error: this call to `as_ref` does nothing + --> tests/ui/useless_asref.rs:288:72 + | +LL | let v: Vec> = exts_field.iter().map(|w| Cow::Borrowed(w.0.as_ref())).collect(); + | ^^^^^^^^^^^^ help: try: `w.0` + +error: this call to `as_ref` does nothing + --> tests/ui/useless_asref.rs:292:74 + | +LL | let v: Vec> = exts_index.iter().map(|arr| Cow::Borrowed(arr[0].as_ref())).collect(); + | ^^^^^^^^^^^^^^^ help: try: `arr[0]` + +error: aborting due to 23 previous errors diff --git a/tests/ui/vec.fixed b/tests/ui/useless_vec.fixed similarity index 90% rename from tests/ui/vec.fixed rename to tests/ui/useless_vec.fixed index 55742459c92c..3cea4862611d 100644 --- a/tests/ui/vec.fixed +++ b/tests/ui/useless_vec.fixed @@ -1,5 +1,4 @@ #![warn(clippy::useless_vec)] -#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)] use std::rc::Rc; @@ -39,17 +38,14 @@ fn main() { on_mut_slice(&mut [1, 2]); //~^ useless_vec - on_slice(&[1, 2]); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut [1, 2]); - //~^ useless_vec #[rustfmt::skip] - on_slice(&[1, 2]); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut [1, 2]); - //~^ useless_vec + #[allow(clippy::nonstandard_macro_braces)] // not an `expect` as it will only lint _before_ the fix + { + on_slice(&[1, 2]); + //~^ useless_vec + on_mut_slice(&mut [1, 2]); + //~^ useless_vec + }; on_slice(&[1; 2]); //~^ useless_vec @@ -75,22 +71,24 @@ fn main() { on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` - // Ok + // Ok, size of `vec` higher than `too_large_for_stack` for a in vec![1; 201] { - println!("{:?}", a); + println!("{a:?}"); } // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 let _x: i32 = [1, 2, 3].iter().sum(); //~^ useless_vec - // Do lint - let mut x = [1, 2, 3]; - //~^ useless_vec - x.fill(123); - dbg!(x[0]); - dbg!(x.len()); - dbg!(x.iter().sum::()); + // Do lint, only used as slice + { + let mut x = [1, 2, 3]; + //~^ useless_vec + x.fill(123); + dbg!(x[0]); + dbg!(x.len()); + dbg!(x.iter().sum::()); + } let _x: &[i32] = &[1, 2, 3]; //~^ useless_vec diff --git a/tests/ui/useless_vec.rs b/tests/ui/useless_vec.rs index 880809f81d7a..2b5d71ae7fa4 100644 --- a/tests/ui/useless_vec.rs +++ b/tests/ui/useless_vec.rs @@ -1,15 +1,251 @@ -//@no-rustfix: no suggestions - #![warn(clippy::useless_vec)] -// Regression test for . -fn foo() { - // There should be no suggestion in this case. - let _some_variable = vec![ - //~^ useless_vec - 1, 2, // i'm here to stay - 3, 4, // but this one going away ;-; - ]; // that is life anyways +use std::rc::Rc; + +struct StructWithVec { + _x: Vec, } -fn main() {} +fn on_slice(_: &[u8]) {} + +fn on_mut_slice(_: &mut [u8]) {} + +#[allow(clippy::ptr_arg)] +fn on_vec(_: &Vec) {} + +fn on_mut_vec(_: &mut Vec) {} + +struct Line { + length: usize, +} + +impl Line { + fn length(&self) -> usize { + self.length + } +} + +fn main() { + on_slice(&vec![]); + //~^ useless_vec + on_slice(&[]); + on_mut_slice(&mut vec![]); + //~^ useless_vec + + on_slice(&vec![1, 2]); + //~^ useless_vec + on_slice(&[1, 2]); + on_mut_slice(&mut vec![1, 2]); + //~^ useless_vec + + #[rustfmt::skip] + #[allow(clippy::nonstandard_macro_braces)] // not an `expect` as it will only lint _before_ the fix + { + on_slice(&vec!(1, 2)); + //~^ useless_vec + on_mut_slice(&mut vec!(1, 2)); + //~^ useless_vec + }; + + on_slice(&vec![1; 2]); + //~^ useless_vec + on_slice(&[1; 2]); + on_mut_slice(&mut vec![1; 2]); + //~^ useless_vec + + on_vec(&vec![]); + on_vec(&vec![1, 2]); + on_vec(&vec![1; 2]); + on_mut_vec(&mut vec![]); + on_mut_vec(&mut vec![1, 2]); + on_mut_vec(&mut vec![1; 2]); + + // Now with non-constant expressions + let line = Line { length: 2 }; + + on_slice(&vec![2; line.length]); + on_slice(&vec![2; line.length()]); + on_mut_slice(&mut vec![2; line.length]); + on_mut_slice(&mut vec![2; line.length()]); + + on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` + on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` + + // Ok, size of `vec` higher than `too_large_for_stack` + for a in vec![1; 201] { + println!("{a:?}"); + } + + // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 + let _x: i32 = vec![1, 2, 3].iter().sum(); + //~^ useless_vec + + // Do lint, only used as slice + { + let mut x = vec![1, 2, 3]; + //~^ useless_vec + x.fill(123); + dbg!(x[0]); + dbg!(x.len()); + dbg!(x.iter().sum::()); + } + + let _x: &[i32] = &vec![1, 2, 3]; + //~^ useless_vec + + for _ in vec![1, 2, 3] {} + //~^ useless_vec + + // Don't lint + let x = vec![1, 2, 3]; + let _v: Vec = x; + + let x = vec![1, 2, 3]; + let _s = StructWithVec { _x: x }; + + // Explicit type annotation would make the change to [1, 2, 3] + // a compile error. + let _x: Vec = vec![1, 2, 3]; + + // Calling a Vec method through a mutable reference + let mut x = vec![1, 2, 3]; + let re = &mut x; + re.push(4); + + // Comparing arrays whose length is not equal is a compile error + let x = vec![1, 2, 3]; + let y = vec![1, 2, 3, 4]; + dbg!(x == y); + + // Non-copy types + let _x = vec![String::new(); 10]; + #[allow(clippy::rc_clone_in_vec_init)] + let _x = vec![Rc::new(1); 10]; + + // Too large + let _x = vec![1; 201]; +} + +fn issue11075() { + macro_rules! repro { + ($e:expr) => { + stringify!($e) + }; + } + #[allow(clippy::never_loop)] + for _string in vec![repro!(true), repro!(null)] { + //~^ useless_vec + unimplemented!(); + } + + macro_rules! in_macro { + ($e:expr, $vec:expr, $vec2:expr) => {{ + vec![1; 2].fill(3); + vec![1, 2].fill(3); + for _ in vec![1, 2] {} + for _ in vec![1; 2] {} + for _ in vec![$e, $e] {} + for _ in vec![$e; 2] {} + for _ in $vec {} + for _ in $vec2 {} + }}; + } + + in_macro!(1, vec![1, 2], vec![1; 2]); + //~^ useless_vec + //~| useless_vec + + macro_rules! from_macro { + () => { + vec![1, 2, 3] + }; + } + macro_rules! from_macro_repeat { + () => { + vec![1; 3] + }; + } + + for _ in from_macro!() {} + for _ in from_macro_repeat!() {} +} + +#[clippy::msrv = "1.53"] +fn above() { + for a in vec![1, 2, 3] { + //~^ useless_vec + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + //~^ useless_vec + let _: String = a; + } +} + +#[clippy::msrv = "1.52"] +fn below() { + for a in vec![1, 2, 3] { + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + let _: String = a; + } +} + +fn func_needing_vec(_bar: usize, _baz: Vec) {} +fn func_not_needing_vec(_bar: usize, _baz: usize) {} + +fn issue11861() { + macro_rules! this_macro_needs_vec { + ($x:expr) => {{ + func_needing_vec($x.iter().sum(), $x); + for _ in $x {} + }}; + } + macro_rules! this_macro_doesnt_need_vec { + ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }}; + } + + // Do not lint the next line + this_macro_needs_vec!(vec![1]); + this_macro_doesnt_need_vec!(vec![1]); + //~^ useless_vec + + macro_rules! m { + ($x:expr) => { + fn f2() { + let _x: Vec = $x; + } + fn f() { + let _x = $x; + $x.starts_with(&[]); + } + }; + } + + // should not lint + m!(vec![1]); +} + +fn issue_11958() { + fn f(_s: &[String]) {} + + // should not lint, `String` is not `Copy` + f(&vec!["test".to_owned(); 2]); +} + +fn issue_12101() { + for a in &(vec![1, 2]) {} + //~^ useless_vec +} + +fn issue_14531() { + // The lint used to suggest using an array rather than a reference to a slice. + + fn requires_ref_slice(v: &[()]) {} + let v = &vec![]; + //~^ useless_vec + requires_ref_slice(v); +} diff --git a/tests/ui/useless_vec.stderr b/tests/ui/useless_vec.stderr index e47364fb06d3..65120d8b338f 100644 --- a/tests/ui/useless_vec.stderr +++ b/tests/ui/useless_vec.stderr @@ -1,21 +1,125 @@ error: useless use of `vec!` - --> tests/ui/useless_vec.rs:8:26 + --> tests/ui/useless_vec.rs:29:14 | -LL | let _some_variable = vec![ - | __________________________^ -LL | | -LL | | 1, 2, // i'm here to stay -LL | | 3, 4, // but this one going away ;-; -LL | | ]; // that is life anyways - | |_____^ +LL | on_slice(&vec![]); + | ^^^^^^^ help: you can use a slice directly: `&[]` | = note: `-D clippy::useless-vec` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]` -help: you can use an array directly - | -LL ~ let _some_variable = [1, 2, // i'm here to stay -LL ~ 3, 4]; // that is life anyways - | -error: aborting due to 1 previous error +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:32:18 + | +LL | on_mut_slice(&mut vec![]); + | ^^^^^^^^^^^ help: you can use a slice directly: `&mut []` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:35:14 + | +LL | on_slice(&vec![1, 2]); + | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:38:18 + | +LL | on_mut_slice(&mut vec![1, 2]); + | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:44:18 + | +LL | on_slice(&vec!(1, 2)); + | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:46:22 + | +LL | on_mut_slice(&mut vec!(1, 2)); + | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:50:14 + | +LL | on_slice(&vec![1; 2]); + | ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:53:18 + | +LL | on_mut_slice(&mut vec![1; 2]); + | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:80:19 + | +LL | let _x: i32 = vec![1, 2, 3].iter().sum(); + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:85:21 + | +LL | let mut x = vec![1, 2, 3]; + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:93:22 + | +LL | let _x: &[i32] = &vec![1, 2, 3]; + | ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:96:14 + | +LL | for _ in vec![1, 2, 3] {} + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:136:20 + | +LL | for _string in vec![repro!(true), repro!(null)] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:154:18 + | +LL | in_macro!(1, vec![1, 2], vec![1; 2]); + | ^^^^^^^^^^ help: you can use an array directly: `[1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:154:30 + | +LL | in_macro!(1, vec![1, 2], vec![1; 2]); + | ^^^^^^^^^^ help: you can use an array directly: `[1; 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:175:14 + | +LL | for a in vec![1, 2, 3] { + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:180:14 + | +LL | for a in vec![String::new(), String::new()] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:213:33 + | +LL | this_macro_doesnt_need_vec!(vec![1]); + | ^^^^^^^ help: you can use an array directly: `[1]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:240:14 + | +LL | for a in &(vec![1, 2]) {} + | ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:248:13 + | +LL | let v = &vec![]; + | ^^^^^^^ help: you can use a slice directly: `&[]` + +error: aborting due to 20 previous errors diff --git a/tests/ui/useless_vec_unfixable.rs b/tests/ui/useless_vec_unfixable.rs new file mode 100644 index 000000000000..7f45f4df5ee6 --- /dev/null +++ b/tests/ui/useless_vec_unfixable.rs @@ -0,0 +1,14 @@ +//@no-rustfix: no suggestions +#![warn(clippy::useless_vec)] + +// Regression test for . +fn foo() { + // There should be no suggestion in this case. + let _some_variable = vec![ + //~^ useless_vec + 1, 2, // i'm here to stay + 3, 4, // but this one going away ;-; + ]; // that is life anyways +} + +fn main() {} diff --git a/tests/ui/useless_vec_unfixable.stderr b/tests/ui/useless_vec_unfixable.stderr new file mode 100644 index 000000000000..980194ac7191 --- /dev/null +++ b/tests/ui/useless_vec_unfixable.stderr @@ -0,0 +1,21 @@ +error: useless use of `vec!` + --> tests/ui/useless_vec_unfixable.rs:7:26 + | +LL | let _some_variable = vec![ + | __________________________^ +LL | | +LL | | 1, 2, // i'm here to stay +LL | | 3, 4, // but this one going away ;-; +LL | | ]; // that is life anyways + | |_____^ + | + = note: `-D clippy::useless-vec` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]` +help: you can use an array directly + | +LL ~ let _some_variable = [1, 2, // i'm here to stay +LL ~ 3, 4]; // that is life anyways + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/vec.rs b/tests/ui/vec.rs deleted file mode 100644 index fbf7131323c3..000000000000 --- a/tests/ui/vec.rs +++ /dev/null @@ -1,253 +0,0 @@ -#![warn(clippy::useless_vec)] -#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)] - -use std::rc::Rc; - -struct StructWithVec { - _x: Vec, -} - -fn on_slice(_: &[u8]) {} - -fn on_mut_slice(_: &mut [u8]) {} - -#[allow(clippy::ptr_arg)] -fn on_vec(_: &Vec) {} - -fn on_mut_vec(_: &mut Vec) {} - -struct Line { - length: usize, -} - -impl Line { - fn length(&self) -> usize { - self.length - } -} - -fn main() { - on_slice(&vec![]); - //~^ useless_vec - on_slice(&[]); - on_mut_slice(&mut vec![]); - //~^ useless_vec - - on_slice(&vec![1, 2]); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut vec![1, 2]); - //~^ useless_vec - - on_slice(&vec![1, 2]); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut vec![1, 2]); - //~^ useless_vec - #[rustfmt::skip] - on_slice(&vec!(1, 2)); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut vec![1, 2]); - //~^ useless_vec - - on_slice(&vec![1; 2]); - //~^ useless_vec - on_slice(&[1; 2]); - on_mut_slice(&mut vec![1; 2]); - //~^ useless_vec - - on_vec(&vec![]); - on_vec(&vec![1, 2]); - on_vec(&vec![1; 2]); - on_mut_vec(&mut vec![]); - on_mut_vec(&mut vec![1, 2]); - on_mut_vec(&mut vec![1; 2]); - - // Now with non-constant expressions - let line = Line { length: 2 }; - - on_slice(&vec![2; line.length]); - on_slice(&vec![2; line.length()]); - on_mut_slice(&mut vec![2; line.length]); - on_mut_slice(&mut vec![2; line.length()]); - - on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` - on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` - - // Ok - for a in vec![1; 201] { - println!("{:?}", a); - } - - // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 - let _x: i32 = vec![1, 2, 3].iter().sum(); - //~^ useless_vec - - // Do lint - let mut x = vec![1, 2, 3]; - //~^ useless_vec - x.fill(123); - dbg!(x[0]); - dbg!(x.len()); - dbg!(x.iter().sum::()); - - let _x: &[i32] = &vec![1, 2, 3]; - //~^ useless_vec - - for _ in vec![1, 2, 3] {} - //~^ useless_vec - - // Don't lint - let x = vec![1, 2, 3]; - let _v: Vec = x; - - let x = vec![1, 2, 3]; - let _s = StructWithVec { _x: x }; - - // Explicit type annotation would make the change to [1, 2, 3] - // a compile error. - let _x: Vec = vec![1, 2, 3]; - - // Calling a Vec method through a mutable reference - let mut x = vec![1, 2, 3]; - let re = &mut x; - re.push(4); - - // Comparing arrays whose length is not equal is a compile error - let x = vec![1, 2, 3]; - let y = vec![1, 2, 3, 4]; - dbg!(x == y); - - // Non-copy types - let _x = vec![String::new(); 10]; - #[allow(clippy::rc_clone_in_vec_init)] - let _x = vec![Rc::new(1); 10]; - - // Too large - let _x = vec![1; 201]; -} - -fn issue11075() { - macro_rules! repro { - ($e:expr) => { - stringify!($e) - }; - } - #[allow(clippy::never_loop)] - for _string in vec![repro!(true), repro!(null)] { - //~^ useless_vec - unimplemented!(); - } - - macro_rules! in_macro { - ($e:expr, $vec:expr, $vec2:expr) => {{ - vec![1; 2].fill(3); - vec![1, 2].fill(3); - for _ in vec![1, 2] {} - for _ in vec![1; 2] {} - for _ in vec![$e, $e] {} - for _ in vec![$e; 2] {} - for _ in $vec {} - for _ in $vec2 {} - }}; - } - - in_macro!(1, vec![1, 2], vec![1; 2]); - //~^ useless_vec - //~| useless_vec - - macro_rules! from_macro { - () => { - vec![1, 2, 3] - }; - } - macro_rules! from_macro_repeat { - () => { - vec![1; 3] - }; - } - - for _ in from_macro!() {} - for _ in from_macro_repeat!() {} -} - -#[clippy::msrv = "1.53"] -fn above() { - for a in vec![1, 2, 3] { - //~^ useless_vec - let _: usize = a; - } - - for a in vec![String::new(), String::new()] { - //~^ useless_vec - let _: String = a; - } -} - -#[clippy::msrv = "1.52"] -fn below() { - for a in vec![1, 2, 3] { - let _: usize = a; - } - - for a in vec![String::new(), String::new()] { - let _: String = a; - } -} - -fn func_needing_vec(_bar: usize, _baz: Vec) {} -fn func_not_needing_vec(_bar: usize, _baz: usize) {} - -fn issue11861() { - macro_rules! this_macro_needs_vec { - ($x:expr) => {{ - func_needing_vec($x.iter().sum(), $x); - for _ in $x {} - }}; - } - macro_rules! this_macro_doesnt_need_vec { - ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }}; - } - - // Do not lint the next line - this_macro_needs_vec!(vec![1]); - this_macro_doesnt_need_vec!(vec![1]); - //~^ useless_vec - - macro_rules! m { - ($x:expr) => { - fn f2() { - let _x: Vec = $x; - } - fn f() { - let _x = $x; - $x.starts_with(&[]); - } - }; - } - - // should not lint - m!(vec![1]); -} - -fn issue_11958() { - fn f(_s: &[String]) {} - - // should not lint, `String` is not `Copy` - f(&vec!["test".to_owned(); 2]); -} - -fn issue_12101() { - for a in &(vec![1, 2]) {} - //~^ useless_vec -} - -fn issue_14531() { - // The lint used to suggest using an array rather than a reference to a slice. - - fn requires_ref_slice(v: &[()]) {} - let v = &vec![]; - //~^ useless_vec - requires_ref_slice(v); -} diff --git a/tests/ui/vec.stderr b/tests/ui/vec.stderr deleted file mode 100644 index d16c8a8944a2..000000000000 --- a/tests/ui/vec.stderr +++ /dev/null @@ -1,137 +0,0 @@ -error: useless use of `vec!` - --> tests/ui/vec.rs:30:14 - | -LL | on_slice(&vec![]); - | ^^^^^^^ help: you can use a slice directly: `&[]` - | - = note: `-D clippy::useless-vec` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:33:18 - | -LL | on_mut_slice(&mut vec![]); - | ^^^^^^^^^^^ help: you can use a slice directly: `&mut []` - -error: useless use of `vec!` - --> tests/ui/vec.rs:36:14 - | -LL | on_slice(&vec![1, 2]); - | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:39:18 - | -LL | on_mut_slice(&mut vec![1, 2]); - | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:42:14 - | -LL | on_slice(&vec![1, 2]); - | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:45:18 - | -LL | on_mut_slice(&mut vec![1, 2]); - | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:48:14 - | -LL | on_slice(&vec!(1, 2)); - | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:51:18 - | -LL | on_mut_slice(&mut vec![1, 2]); - | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:54:14 - | -LL | on_slice(&vec![1; 2]); - | ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:57:18 - | -LL | on_mut_slice(&mut vec![1; 2]); - | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:84:19 - | -LL | let _x: i32 = vec![1, 2, 3].iter().sum(); - | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:88:17 - | -LL | let mut x = vec![1, 2, 3]; - | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:95:22 - | -LL | let _x: &[i32] = &vec![1, 2, 3]; - | ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:98:14 - | -LL | for _ in vec![1, 2, 3] {} - | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:138:20 - | -LL | for _string in vec![repro!(true), repro!(null)] { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:156:18 - | -LL | in_macro!(1, vec![1, 2], vec![1; 2]); - | ^^^^^^^^^^ help: you can use an array directly: `[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:156:30 - | -LL | in_macro!(1, vec![1, 2], vec![1; 2]); - | ^^^^^^^^^^ help: you can use an array directly: `[1; 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:177:14 - | -LL | for a in vec![1, 2, 3] { - | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:182:14 - | -LL | for a in vec![String::new(), String::new()] { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:215:33 - | -LL | this_macro_doesnt_need_vec!(vec![1]); - | ^^^^^^^ help: you can use an array directly: `[1]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:242:14 - | -LL | for a in &(vec![1, 2]) {} - | ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:250:13 - | -LL | let v = &vec![]; - | ^^^^^^^ help: you can use a slice directly: `&[]` - -error: aborting due to 22 previous errors - diff --git a/triagebot.toml b/triagebot.toml index db951b95ef50..3bf62b6b3bba 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -63,7 +63,8 @@ contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIB users_on_vacation = [ "matthiaskrgr", "Manishearth", - "blyxyas", + "Alexendoo", + "y21", ] [assign.owners] diff --git a/util/gh-pages/index_template.html b/util/gh-pages/index_template.html index e443baff0808..91a5c1263195 100644 --- a/util/gh-pages/index_template.html +++ b/util/gh-pages/index_template.html @@ -57,118 +57,114 @@ Otherwise, have a great day =^.^= {# #} {% for lint in lints %} diff --git a/util/gh-pages/style.css b/util/gh-pages/style.css index 18bb95cf67b6..242e2227ed94 100644 --- a/util/gh-pages/style.css +++ b/util/gh-pages/style.css @@ -113,29 +113,26 @@ label { background: var(--bg); border: 1px solid var(--theme-popup-border); box-shadow: 0 1px 1px rgba(0,0,0,.05); + display: block; } -div.panel-body { - padding: 15px; +#menu-filters { + padding: 15px 0; + display: flex; + flex-direction: column; } -div.panel-body::before, div.panel-body::after { - display: table; - content: " "; -} -div.panel-body::after { - clear: both; -} -div.panel-body button { + +#menu-filters button { background: var(--searchbar-bg); border-color: var(--theme-popup-border); color: var(--searchbar-fg); } -div.panel-body button:hover { +#menu-filters button:hover { box-shadow: 0 0 3px var(--searchbar-shadow-color); } -div.panel-body button.open { +#menu-filters button.open { filter: brightness(90%); } @@ -242,33 +239,10 @@ article:hover .panel-title-name .anchor { display: inline;} min-height: 1px; padding-right: 15px; padding-left: 15px; -} - -.input-group { - position: relative; display: flex; } -.input-group > :last-child { - border-left: 0; -} -.input-group > :first-child, .btn-group > :first-child { - border-right: 0; - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} -.input-group > :last-child, .btn-group > :last-child { - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} -.input-group .form-control:not(:first-child):not(:last-child) { - border-radius: 0; -} -.form-control:focus { - border-color: #66afe9; - outline: 0; - box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6); -} -.input-group-addon { + +#filter-label { padding: 6px 12px; font-size: 14px; font-weight: 400; @@ -280,6 +254,29 @@ article:hover .panel-title-name .anchor { display: inline;} display: flex; align-items: center; justify-content: center; + border-right: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.search-control > :last-child { + border-left: 0; +} +.btn-group > :first-child { + border-right: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.search-control > :last-child, .btn-group > :last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.search-control .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6); } .glyphicon.glyphicon-collapse-up::before, .glyphicon.glyphicon-collapse-down::before { @@ -343,6 +340,7 @@ article:hover .panel-title-name .anchor { display: inline;} @media (min-width: 992px) { .search-control { margin-top: 0; + align-self: flex-start; } .container { width: 970px; @@ -357,6 +355,10 @@ article:hover .panel-title-name .anchor { display: inline;} margin-top: 0; padding: 0px 15px; width: 16.66666667%; + align-self: flex-start; + } + #menu-filters { + flex-direction: row; } } @@ -376,7 +378,7 @@ article:hover .panel-title-name .anchor { display: inline;} @media (max-width: 412px) { #upper-filters, - .panel-body .search-control { + #menu-filters .search-control { padding-right: 8px; padding-left: 8px; } @@ -617,6 +619,7 @@ L4.75,12h2.5l0.5393066-2.1572876 c0.2276001-0.1062012,0.4459839-0.2269287,0.649 color: var(--fg); background: var(--theme-hover); border: 1px solid var(--theme-popup-border); + padding: 8px; } .page-header { border: 0; From 8f55c15bfe539a012f111bd00687241ad5a4a947 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 15 Oct 2025 09:55:38 +0000 Subject: [PATCH 0159/3801] Remove -Zoom=panic There are major questions remaining about the reentrancy that this allows. It doesn't have any users on github outside of a single project that uses it in a panic=abort project to show backtraces. It can still be emulated through #[alloc_error_handler] or set_alloc_error_hook depending on if you use the standard library or not. And finally it makes it harder to do various improvements to the allocator shim. --- .../rustc_codegen_cranelift/src/allocator.rs | 39 +--------------- compiler/rustc_codegen_gcc/src/allocator.rs | 39 +--------------- compiler/rustc_codegen_llvm/src/allocator.rs | 44 +------------------ .../src/back/symbol_export.rs | 3 +- compiler/rustc_interface/src/tests.rs | 9 ++-- compiler/rustc_session/src/config.rs | 26 +---------- compiler/rustc_session/src/options.rs | 12 ----- library/alloc/src/alloc.rs | 19 ++------ library/std/src/alloc.rs | 11 ----- src/tools/miri/src/shims/foreign_items.rs | 9 +--- .../tests/panic/alloc_error_handler_panic.rs | 18 -------- .../panic/alloc_error_handler_panic.stderr | 6 --- ...c-unwind.rs => alloc_error_hook-unwind.rs} | 8 ++-- 13 files changed, 22 insertions(+), 221 deletions(-) delete mode 100644 src/tools/miri/tests/panic/alloc_error_handler_panic.rs delete mode 100644 src/tools/miri/tests/panic/alloc_error_handler_panic.stderr rename tests/ui/panics/{oom-panic-unwind.rs => alloc_error_hook-unwind.rs} (84%) diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 67b89114356b..4a9b0c0952ff 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -6,7 +6,6 @@ use rustc_ast::expand::allocator::{ AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_codegen_ssa::base::{allocator_kind_for_codegen, allocator_shim_contents}; -use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; use crate::prelude::*; @@ -15,16 +14,11 @@ use crate::prelude::*; pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; let methods = allocator_shim_contents(tcx, kind); - codegen_inner(tcx, module, &methods, tcx.sess.opts.unstable_opts.oom); + codegen_inner(tcx, module, &methods); true } -fn codegen_inner( - tcx: TyCtxt<'_>, - module: &mut dyn Module, - methods: &[AllocatorMethod], - oom_strategy: OomStrategy, -) { +fn codegen_inner(tcx: TyCtxt<'_>, module: &mut dyn Module, methods: &[AllocatorMethod]) { let usize_ty = module.target_config().pointer_type(); for method in methods { @@ -65,35 +59,6 @@ fn codegen_inner( ); } - { - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![], - returns: vec![AbiParam::new(types::I8)], - }; - let func_id = module - .declare_function( - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - Linkage::Export, - &sig, - ) - .unwrap(); - let mut ctx = Context::new(); - ctx.func.signature = sig; - { - let mut func_ctx = FunctionBuilderContext::new(); - let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); - - let block = bcx.create_block(); - bcx.switch_to_block(block); - let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64); - bcx.ins().return_(&[value]); - bcx.seal_all_blocks(); - bcx.finalize(); - } - module.define_function(func_id, &mut ctx).unwrap(); - } - { let sig = Signature { call_conv: module.target_config().default_call_conv, diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 647569694b04..1f464d7e1226 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -1,12 +1,11 @@ #[cfg(feature = "master")] use gccjit::FnAttribute; -use gccjit::{Context, FunctionType, RValue, ToRValue, Type}; +use gccjit::{Context, FunctionType, ToRValue, Type}; use rustc_ast::expand::allocator::{ AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; -use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; use crate::GccContext; @@ -59,14 +58,6 @@ pub(crate) unsafe fn codegen( create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output); } - create_const_value_function( - tcx, - context, - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - i8, - context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32), - ); - create_wrapper_function( tcx, context, @@ -77,34 +68,6 @@ pub(crate) unsafe fn codegen( ); } -fn create_const_value_function( - tcx: TyCtxt<'_>, - context: &Context<'_>, - name: &str, - output: Type<'_>, - value: RValue<'_>, -) { - let func = context.new_function(None, FunctionType::Exported, output, &[], name, false); - - #[cfg(feature = "master")] - { - func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc( - tcx.sess.default_visibility(), - ))); - - // FIXME(antoyo): cg_llvm sets AlwaysInline, but AlwaysInline is different in GCC and using - // it here will causes linking errors when using LTO. - func.add_attribute(FnAttribute::Inline); - } - - if tcx.sess.must_emit_unwind_tables() { - // TODO(antoyo): emit unwind tables. - } - - let block = func.new_block("entry"); - block.end_with_return(None, value); -} - fn create_wrapper_function( tcx: TyCtxt<'_>, context: &Context<'_>, diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index de0b85ebb63b..24b2bd37aa46 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -7,13 +7,13 @@ use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::ty::TyCtxt; -use rustc_session::config::{DebugInfo, OomStrategy}; +use rustc_session::config::DebugInfo; use rustc_symbol_mangling::mangle_internal_symbol; use crate::attributes::llfn_attrs_from_instance; use crate::builder::SBuilder; use crate::declare::declare_simple_fn; -use crate::llvm::{self, FALSE, FromGeneric, TRUE, Type, Value}; +use crate::llvm::{self, FromGeneric, TRUE, Type}; use crate::{SimpleCx, attributes, debuginfo}; pub(crate) unsafe fn codegen( @@ -28,7 +28,6 @@ pub(crate) unsafe fn codegen( 64 => cx.type_i64(), tws => bug!("Unsupported target word size for int: {}", tws), }; - let i8 = cx.type_i8(); let i8p = cx.type_ptr(); for method in methods { @@ -87,17 +86,6 @@ pub(crate) unsafe fn codegen( ); } - // __rust_alloc_error_handler_should_panic_v2 - create_const_value_function( - tcx, - &cx, - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - &i8, - unsafe { - llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, FALSE) - }, - ); - // __rust_no_alloc_shim_is_unstable_v2 create_wrapper_function( tcx, @@ -117,34 +105,6 @@ pub(crate) unsafe fn codegen( } } -fn create_const_value_function( - tcx: TyCtxt<'_>, - cx: &SimpleCx<'_>, - name: &str, - output: &Type, - value: &Value, -) { - let ty = cx.type_func(&[], output); - let llfn = declare_simple_fn( - &cx, - name, - llvm::CallConv::CCallConv, - llvm::UnnamedAddr::Global, - llvm::Visibility::from_generic(tcx.sess.default_visibility()), - ty, - ); - - attributes::apply_to_llfn( - llfn, - llvm::AttributePlace::Function, - &[llvm::AttributeKind::AlwaysInline.create_attr(cx.llcx)], - ); - - let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) }; - let mut bx = SBuilder::build(&cx, llbb); - bx.ret(value); -} - fn create_wrapper_function( tcx: TyCtxt<'_>, cx: &SimpleCx<'_>, diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index a80976fad02a..9d06de2b35c2 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -15,7 +15,7 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt}; use rustc_middle::util::Providers; -use rustc_session::config::{CrateType, OomStrategy}; +use rustc_session::config::CrateType; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{Arch, Os, TlsModel}; use tracing::debug; @@ -493,7 +493,6 @@ pub(crate) fn allocator_shim_symbols( .map(move |method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str())) .chain([ mangle_internal_symbol(tcx, global_fn_name(ALLOC_ERROR_HANDLER).as_str()), - mangle_internal_symbol(tcx, OomStrategy::SYMBOL), mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), ]) .map(move |symbol_name| { diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8bf9f8420c05..24de3620ca3c 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -14,10 +14,10 @@ use rustc_session::config::{ CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, - NextSolverConfig, Offload, OomStrategy, Options, OutFileName, OutputType, OutputTypes, - PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, - SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration, - build_session_options, rustc_optgroups, + NextSolverConfig, Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, + Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, + SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options, + rustc_optgroups, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -839,7 +839,6 @@ fn test_unstable_options_tracking_hash() { tracked!(no_unique_section_names, true); tracked!(offload, vec![Offload::Enable]); tracked!(on_broken_pipe, OnBrokenPipe::Kill); - tracked!(oom, OomStrategy::Panic); tracked!(osx_rpath_install_name, true); tracked!(packed_bundled_libs, true); tracked!(panic_abort_tests, true); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f97a29e064b6..c5f253a00e32 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3127,8 +3127,8 @@ pub(crate) mod dep_tracking { AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, - LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OomStrategy, - OptLevel, OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, + LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, + OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; @@ -3227,7 +3227,6 @@ pub(crate) mod dep_tracking { LocationDetail, FmtDebug, BranchProtection, - OomStrategy, LanguageIdentifier, NextSolverConfig, PatchableFunctionEntry, @@ -3340,27 +3339,6 @@ pub(crate) mod dep_tracking { } } -/// Default behavior to use in out-of-memory situations. -#[derive(Clone, Copy, PartialEq, Hash, Debug, Encodable, Decodable, HashStable_Generic)] -pub enum OomStrategy { - /// Generate a panic that can be caught by `catch_unwind`. - Panic, - - /// Abort the process immediately. - Abort, -} - -impl OomStrategy { - pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic_v2"; - - pub fn should_panic(self) -> u8 { - match self { - OomStrategy::Panic => 1, - OomStrategy::Abort => 0, - } - } -} - /// How to run proc-macro code when building this crate #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum ProcMacroExecutionStrategy { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 7c7e9118d590..f30612fa77b5 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -806,7 +806,6 @@ mod desc { pub(crate) const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`"; pub(crate) const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)"; pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy; - pub(crate) const parse_oom_strategy: &str = "either `panic` or `abort`"; pub(crate) const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread`, or 'realtime'"; pub(crate) const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2"; @@ -1242,15 +1241,6 @@ pub mod parse { false } - pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool { - match v { - Some("panic") => *slot = OomStrategy::Panic, - Some("abort") => *slot = OomStrategy::Abort, - _ => return false, - } - true - } - pub(crate) fn parse_relro_level(slot: &mut Option, v: Option<&str>) -> bool { match v { Some(s) => match s.parse::() { @@ -2529,8 +2519,6 @@ options! { Currently the only option available"), on_broken_pipe: OnBrokenPipe = (OnBrokenPipe::Default, parse_on_broken_pipe, [TRACKED], "behavior of std::io::ErrorKind::BrokenPipe (SIGPIPE)"), - oom: OomStrategy = (OomStrategy::Abort, parse_oom_strategy, [TRACKED], - "panic strategy for out-of-memory handling"), osx_rpath_install_name: bool = (false, parse_bool, [TRACKED], "pass `-install_name @rpath/...` to the macOS linker (default: no)"), packed_bundled_libs: bool = (false, parse_bool, [TRACKED], diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 39450f69ce30..c5f16f3708d7 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -426,20 +426,9 @@ pub mod __alloc_error_handler { // `#[alloc_error_handler]`. #[rustc_std_internal_symbol] pub unsafe fn __rdl_alloc_error_handler(size: usize, _align: usize) -> ! { - unsafe extern "Rust" { - // This symbol is emitted by rustc next to __rust_alloc_error_handler. - // Its value depends on the -Zoom={panic,abort} compiler option. - #[rustc_std_internal_symbol] - fn __rust_alloc_error_handler_should_panic_v2() -> u8; - } - - if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } { - panic!("memory allocation of {size} bytes failed") - } else { - core::panicking::panic_nounwind_fmt( - format_args!("memory allocation of {size} bytes failed"), - /* force_no_backtrace */ false, - ) - } + core::panicking::panic_nounwind_fmt( + format_args!("memory allocation of {size} bytes failed"), + /* force_no_backtrace */ false, + ) } } diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 701b3be6894d..35eb77315a22 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -350,17 +350,6 @@ fn default_alloc_error_hook(layout: Layout) { return; } - unsafe extern "Rust" { - // This symbol is emitted by rustc next to __rust_alloc_error_handler. - // Its value depends on the -Zoom={panic,abort} compiler option. - #[rustc_std_internal_symbol] - fn __rust_alloc_error_handler_should_panic_v2() -> u8; - } - - if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } { - panic!("memory allocation of {} bytes failed", layout.size()); - } - // This is the default path taken on OOM, and the only path taken on stable with std. // Crucially, it does *not* call any user-defined code, and therefore users do not have to // worry about allocation failure causing reentrancy issues. That makes it different from diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 440388673e7d..8a959d06bf9c 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -12,7 +12,6 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::AllocInit; use rustc_middle::ty::{Instance, Ty}; use rustc_middle::{mir, ty}; -use rustc_session::config::OomStrategy; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; use rustc_target::spec::{Arch, Os}; @@ -305,18 +304,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Here we dispatch all the shims for foreign functions. If you have a platform specific // shim, add it to the corresponding submodule. match link_name.as_str() { - // Magic functions Rust emits (and not as part of the allocator shim). + // Magic function Rust emits (and not as part of the allocator shim). name if name == this.mangle_internal_symbol(NO_ALLOC_SHIM_IS_UNSTABLE) => { // This is a no-op shim that only exists to prevent making the allocator shims // instantly stable. let [] = this.check_shim_sig_lenient(abi, CanonAbi::Rust, link_name, args)?; } - name if name == this.mangle_internal_symbol(OomStrategy::SYMBOL) => { - // Gets the value of the `oom` option. - let [] = this.check_shim_sig_lenient(abi, CanonAbi::Rust, link_name, args)?; - let val = this.tcx.sess.opts.unstable_opts.oom.should_panic(); - this.write_int(val, dest)?; - } // Miri-specific extern functions "miri_alloc" => { diff --git a/src/tools/miri/tests/panic/alloc_error_handler_panic.rs b/src/tools/miri/tests/panic/alloc_error_handler_panic.rs deleted file mode 100644 index c434e8d3227a..000000000000 --- a/src/tools/miri/tests/panic/alloc_error_handler_panic.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@compile-flags: -Zoom=panic -#![feature(allocator_api)] - -use std::alloc::*; - -struct Bomb; -impl Drop for Bomb { - fn drop(&mut self) { - eprintln!("yes we are unwinding!"); - } -} - -#[allow(unreachable_code, unused_variables)] -fn main() { - let bomb = Bomb; - handle_alloc_error(Layout::for_value(&0)); - std::mem::forget(bomb); // defuse unwinding bomb -} diff --git a/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr b/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr deleted file mode 100644 index 7c2d089f952e..000000000000 --- a/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr +++ /dev/null @@ -1,6 +0,0 @@ - -thread 'main' ($TID) panicked at RUSTLIB/std/src/alloc.rs:LL:CC: -memory allocation of 4 bytes failed -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect -yes we are unwinding! diff --git a/tests/ui/panics/oom-panic-unwind.rs b/tests/ui/panics/alloc_error_hook-unwind.rs similarity index 84% rename from tests/ui/panics/oom-panic-unwind.rs rename to tests/ui/panics/alloc_error_hook-unwind.rs index 4f7939ce60b2..8a107bc390d4 100644 --- a/tests/ui/panics/oom-panic-unwind.rs +++ b/tests/ui/panics/alloc_error_hook-unwind.rs @@ -1,17 +1,19 @@ -//! Test that out-of-memory conditions trigger catchable panics with `-Z oom=panic`. +//! Test that out-of-memory conditions trigger catchable panics with `set_alloc_error_hook`. -//@ compile-flags: -Z oom=panic //@ run-pass -//@ no-prefer-dynamic //@ needs-unwind //@ only-linux //@ ignore-backends: gcc +#![feature(alloc_error_hook)] + use std::hint::black_box; use std::mem::forget; use std::panic::catch_unwind; fn main() { + std::alloc::set_alloc_error_hook(|_| panic!()); + let panic = catch_unwind(|| { // This is guaranteed to exceed even the size of the address space for _ in 0..16 { From 4054d07d38c7c8cdbdc2604cf6268fa52dde0165 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 15 Oct 2025 09:55:38 +0000 Subject: [PATCH 0160/3801] Remove -Zoom=panic There are major questions remaining about the reentrancy that this allows. It doesn't have any users on github outside of a single project that uses it in a panic=abort project to show backtraces. It can still be emulated through #[alloc_error_handler] or set_alloc_error_hook depending on if you use the standard library or not. And finally it makes it harder to do various improvements to the allocator shim. --- src/allocator.rs | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 647569694b04..1f464d7e1226 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -1,12 +1,11 @@ #[cfg(feature = "master")] use gccjit::FnAttribute; -use gccjit::{Context, FunctionType, RValue, ToRValue, Type}; +use gccjit::{Context, FunctionType, ToRValue, Type}; use rustc_ast::expand::allocator::{ AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; -use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; use crate::GccContext; @@ -59,14 +58,6 @@ pub(crate) unsafe fn codegen( create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output); } - create_const_value_function( - tcx, - context, - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - i8, - context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32), - ); - create_wrapper_function( tcx, context, @@ -77,34 +68,6 @@ pub(crate) unsafe fn codegen( ); } -fn create_const_value_function( - tcx: TyCtxt<'_>, - context: &Context<'_>, - name: &str, - output: Type<'_>, - value: RValue<'_>, -) { - let func = context.new_function(None, FunctionType::Exported, output, &[], name, false); - - #[cfg(feature = "master")] - { - func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc( - tcx.sess.default_visibility(), - ))); - - // FIXME(antoyo): cg_llvm sets AlwaysInline, but AlwaysInline is different in GCC and using - // it here will causes linking errors when using LTO. - func.add_attribute(FnAttribute::Inline); - } - - if tcx.sess.must_emit_unwind_tables() { - // TODO(antoyo): emit unwind tables. - } - - let block = func.new_block("entry"); - block.end_with_return(None, value); -} - fn create_wrapper_function( tcx: TyCtxt<'_>, context: &Context<'_>, From 4c29d61ec622f9081ee4f6bbe38ee5735d4cfb22 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 15 Oct 2025 09:55:38 +0000 Subject: [PATCH 0161/3801] Remove -Zoom=panic There are major questions remaining about the reentrancy that this allows. It doesn't have any users on github outside of a single project that uses it in a panic=abort project to show backtraces. It can still be emulated through #[alloc_error_handler] or set_alloc_error_hook depending on if you use the standard library or not. And finally it makes it harder to do various improvements to the allocator shim. --- src/allocator.rs | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 67b89114356b..4a9b0c0952ff 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -6,7 +6,6 @@ use rustc_ast::expand::allocator::{ AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_codegen_ssa::base::{allocator_kind_for_codegen, allocator_shim_contents}; -use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; use crate::prelude::*; @@ -15,16 +14,11 @@ use crate::prelude::*; pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; let methods = allocator_shim_contents(tcx, kind); - codegen_inner(tcx, module, &methods, tcx.sess.opts.unstable_opts.oom); + codegen_inner(tcx, module, &methods); true } -fn codegen_inner( - tcx: TyCtxt<'_>, - module: &mut dyn Module, - methods: &[AllocatorMethod], - oom_strategy: OomStrategy, -) { +fn codegen_inner(tcx: TyCtxt<'_>, module: &mut dyn Module, methods: &[AllocatorMethod]) { let usize_ty = module.target_config().pointer_type(); for method in methods { @@ -65,35 +59,6 @@ fn codegen_inner( ); } - { - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![], - returns: vec![AbiParam::new(types::I8)], - }; - let func_id = module - .declare_function( - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - Linkage::Export, - &sig, - ) - .unwrap(); - let mut ctx = Context::new(); - ctx.func.signature = sig; - { - let mut func_ctx = FunctionBuilderContext::new(); - let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); - - let block = bcx.create_block(); - bcx.switch_to_block(block); - let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64); - bcx.ins().return_(&[value]); - bcx.seal_all_blocks(); - bcx.finalize(); - } - module.define_function(func_id, &mut ctx).unwrap(); - } - { let sig = Signature { call_conv: module.target_config().default_call_conv, From 3f67246af50fe6f67d5c56b02efaeb01a0d48f0e Mon Sep 17 00:00:00 2001 From: Skgland Date: Fri, 28 Nov 2025 20:47:03 +0100 Subject: [PATCH 0162/3801] fix tests/run-make/track-path-dep-info attempt 2 --- tests/run-make/track-path-dep-info/macro_def.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-make/track-path-dep-info/macro_def.rs b/tests/run-make/track-path-dep-info/macro_def.rs index 032594d905d0..b7271cac2344 100644 --- a/tests/run-make/track-path-dep-info/macro_def.rs +++ b/tests/run-make/track-path-dep-info/macro_def.rs @@ -1,4 +1,4 @@ -#![feature(proc_macro_track_path)] +#![feature(proc_macro_tracked_path)] #![crate_type = "proc-macro"] extern crate proc_macro; From 5d8e7ae8057f8278784420f3925ebe4e99b79a2e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 28 Nov 2025 11:47:54 -0800 Subject: [PATCH 0163/3801] Fix some broken links `P` was removed in https://github.com/rust-lang/rust/pull/145146 (replaced with plain Box). `CrateLoader` was inlined to `CStore` in https://github.com/rust-lang/rust/pull/144059. `elaborate_drops.rs` was moved in https://github.com/rust-lang/rust/pull/137008. --- src/doc/rustc-dev-guide/src/appendix/bibliography.md | 2 +- src/doc/rustc-dev-guide/src/appendix/code-index.md | 1 - src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md | 7 +++---- src/doc/rustc-dev-guide/src/contributing.md | 4 ++-- .../rustc-dev-guide/src/llvm-coverage-instrumentation.md | 4 ++-- src/doc/rustc-dev-guide/src/mir/drop-elaboration.md | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index 93426b645a61..3729194f5fa1 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/src/appendix/bibliography.md @@ -32,7 +32,7 @@ Rust, as well as publications about Rust. * [Scheduling techniques for concurrent systems](https://www.stanford.edu/~ouster/cgi-bin/papers/coscheduling.pdf) * [Singularity: rethinking the software stack](https://research.microsoft.com/pubs/69431/osr2007_rethinkingsoftwarestack.pdf) * [The data locality of work stealing](http://www.aladdin.cs.cmu.edu/papers/pdfs/y2000/locality_spaa00.pdf) -* [Thread scheduling for multiprogramming multiprocessors](https://www.eecis.udel.edu/%7Ecavazos/cisc879-spring2008/papers/arora98thread.pdf) +* [Thread scheduling for multiprogramming multiprocessors](https://dl.acm.org/doi/10.1145/277651.277678) * [Three layer cake for shared-memory programming](https://dl.acm.org/doi/10.1145/1953611.1953616) * [Work-first and help-first scheduling policies for async-finish task parallelism](https://dl.acm.org/doi/10.1109/IPDPS.2009.5161079) - More general than fully-strict work stealing diff --git a/src/doc/rustc-dev-guide/src/appendix/code-index.md b/src/doc/rustc-dev-guide/src/appendix/code-index.md index 0795d83b2e9a..22b3396ed1ff 100644 --- a/src/doc/rustc-dev-guide/src/appendix/code-index.md +++ b/src/doc/rustc-dev-guide/src/appendix/code-index.md @@ -16,7 +16,6 @@ Item | Kind | Short description | Chapter | `HirId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir_id/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.HirId.html) `Lexer` | struct | This is the lexer used during parsing. It consumes characters from the raw source code being compiled and produces a series of tokens for use by the rest of the parser | [The parser] | [compiler/rustc_parse/src/lexer/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html) `NodeId` | struct | One of four types of HIR node identifiers. Being phased out | [Identifiers in the HIR] | [compiler/rustc_ast/src/ast.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/node_id/struct.NodeId.html) -`P` | struct | An owned immutable smart pointer. By contrast, `&T` is not owned, and `Box` is not immutable. | None | [compiler/rustc_ast/src/ptr.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ptr/struct.P.html) `ParamEnv` | struct | Information about generic parameters or `Self`, useful for working with associated or generic items | [Parameter Environment] | [compiler/rustc_middle/src/ty/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html) `ParseSess` | struct | This struct contains information about a parsing session | [The parser] | [compiler/rustc_session/src/parse/parse.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html) `Rib` | struct | Represents a single scope of names | [Name resolution] | [compiler/rustc_resolve/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.Rib.html) diff --git a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md index aa1d644703a0..44b647d28a1e 100644 --- a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md +++ b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md @@ -133,12 +133,12 @@ crate name, so they need to be disambiguated). Crate loading can have quite a few subtle complexities. During [name resolution], when an external crate is referenced (via an `extern crate` or -path), the resolver uses the [`CrateLoader`] which is responsible for finding +path), the resolver uses the [`CStore`] which is responsible for finding the crate libraries and loading the [metadata] for them. After the dependency -is loaded, the `CrateLoader` will provide the information the resolver needs +is loaded, the `CStore` will provide the information the resolver needs to perform its job (such as expanding macros, resolving paths, etc.). -To load each external crate, the `CrateLoader` uses a [`CrateLocator`] to +To load each external crate, the `CStore` uses a [`CrateLocator`] to actually find the correct files for one specific crate. There is some great documentation in the [`locator`] module that goes into detail on how loading works, and I strongly suggest reading it to get the full picture. @@ -157,7 +157,6 @@ wrapped in the [`CrateMetadata`] struct. After resolution and expansion, the compilation. [name resolution]: ../name-resolution.md -[`CrateLoader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/creader/struct.CrateLoader.html [`CrateLocator`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/locator/struct.CrateLocator.html [`locator`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/locator/index.html [`CStore`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/creader/struct.CStore.html diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 4476ed842dae..40ad58e025c1 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -468,7 +468,7 @@ Just a few things to keep in mind: #### ⚠️ Note: Where to contribute `rustc-dev-guide` changes For detailed information about where to contribute rustc-dev-guide changes and the benefits of doing so, -see [the rustc-dev-guide working group documentation]. +see [the rustc-dev-guide team documentation]. ## Issue triage @@ -485,7 +485,7 @@ Please see . [regression-]: https://github.com/rust-lang/rust/labels?q=regression [relnotes]: https://github.com/rust-lang/rust/labels/relnotes [S-tracking-]: https://github.com/rust-lang/rust/labels?q=s-tracking -[the rustc-dev-guide working group documentation]: https://forge.rust-lang.org/wg-rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes +[the rustc-dev-guide team documentation]: https://forge.rust-lang.org/rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes ### rfcbot labels diff --git a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md index 30a1c5ebc7ef..d71e51d5f61b 100644 --- a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md +++ b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md @@ -84,11 +84,11 @@ Note that when building `rustc`, `profiler_builtins` is only included when `build.profiler = true` is set in `bootstrap.toml`. When compiling with `-C instrument-coverage`, -[`CrateLoader::postprocess()`][crate-loader-postprocess] dynamically loads +[`CStore::postprocess()`][crate-loader-postprocess] dynamically loads `profiler_builtins` by calling `inject_profiler_runtime()`. [compiler-rt-profile]: https://github.com/llvm/llvm-project/tree/main/compiler-rt/lib/profile -[crate-loader-postprocess]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/creader/struct.CrateLoader.html#method.postprocess +[crate-loader-postprocess]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/creader/struct.CStore.html#method.postprocess ## Testing coverage instrumentation diff --git a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md index 93e21e2b227f..7ef60f4cca00 100644 --- a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md +++ b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md @@ -188,6 +188,6 @@ known to be uninitialized) to run these checks. [RFC 320]: https://rust-lang.github.io/rfcs/0320-nonzeroing-dynamic-drop.html [reference-drop]: https://doc.rust-lang.org/reference/destructors.html -[drops]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +[drops]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_mir_transform/src/elaborate_drops.rs [drops-shim]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_mir_transform/src/shim.rs [drops-transform]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_mir_transform/src/elaborate_drops.rs From 05b8b5ae92f32e551b8fe189140cc0a9d43c2455 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 29 Nov 2025 02:05:46 +0200 Subject: [PATCH 0164/3801] sembr backend/libs-and-metadata.md --- .../src/backend/libs-and-metadata.md | 146 +++++++++--------- 1 file changed, 77 insertions(+), 69 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md index 44b647d28a1e..4cf0dfa6a6da 100644 --- a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md +++ b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md @@ -1,36 +1,41 @@ # Libraries and metadata When the compiler sees a reference to an external crate, it needs to load some -information about that crate. This chapter gives an overview of that process, +information about that crate. +This chapter gives an overview of that process, and the supported file formats for crate libraries. ## Libraries -A crate dependency can be loaded from an `rlib`, `dylib`, or `rmeta` file. A -key point of these file formats is that they contain `rustc`-specific -[*metadata*](#metadata). This metadata allows the compiler to discover enough +A crate dependency can be loaded from an `rlib`, `dylib`, or `rmeta` file. +A key point of these file formats is that they contain `rustc`-specific +[*metadata*](#metadata). +This metadata allows the compiler to discover enough information about the external crate to understand the items it contains, which macros it exports, and *much* more. ### rlib -An `rlib` is an [archive file], which is similar to a tar file. This file -format is specific to `rustc`, and may change over time. This file contains: +An `rlib` is an [archive file], which is similar to a tar file. +This file format is specific to `rustc`, and may change over time. +This file contains: -* Object code, which is the result of code generation. This is used during - regular linking. There is a separate `.o` file for each [codegen unit]. The - codegen step can be skipped with the [`-C +* Object code, which is the result of code generation. + This is used during regular linking. + There is a separate `.o` file for each [codegen unit]. + The codegen step can be skipped with the [`-C linker-plugin-lto`][linker-plugin-lto] CLI option, which means each `.o` file will only contain LLVM bitcode. * [LLVM bitcode], which is a binary representation of LLVM's intermediate - representation, which is embedded as a section in the `.o` files. This can - be used for [Link Time Optimization] (LTO). This can be removed with the + representation, which is embedded as a section in the `.o` files. + This can be used for [Link Time Optimization] (LTO). + This can be removed with the [`-C embed-bitcode=no`][embed-bitcode] CLI option to improve compile times and reduce disk space if LTO is not needed. * `rustc` [metadata], in a file named `lib.rmeta`. * A symbol table, which is essentially a list of symbols with offsets to the - object files that contain that symbol. This is pretty standard for archive - files. + object files that contain that symbol. + This is pretty standard for archive files. [archive file]: https://en.wikipedia.org/wiki/Ar_(Unix) [LLVM bitcode]: https://llvm.org/docs/BitCodeFormat.html @@ -41,46 +46,46 @@ format is specific to `rustc`, and may change over time. This file contains: ### dylib -A `dylib` is a platform-specific shared library. It includes the `rustc` -[metadata] in a special link section called `.rustc`. +A `dylib` is a platform-specific shared library. +It includes the `rustc` [metadata] in a special link section called `.rustc`. ### rmeta -An `rmeta` file is a custom binary format that contains the [metadata] for the -crate. This file can be used for fast "checks" of a project by skipping all code +An `rmeta` file is a custom binary format that contains the [metadata] for the crate. +This file can be used for fast "checks" of a project by skipping all code generation (as is done with `cargo check`), collecting enough information for documentation (as is done with `cargo doc`), or for [pipelining](#pipelining). This file is created if the [`--emit=metadata`][emit] CLI option is used. -`rmeta` files do not support linking, since they do not contain compiled -object files. +`rmeta` files do not support linking, since they do not contain compiled object files. [emit]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-emit ## Metadata -The metadata contains a wide swath of different elements. This guide will not go -into detail about every field it contains. You are encouraged to browse the +The metadata contains a wide swath of different elements. +This guide will not go into detail about every field it contains. +You are encouraged to browse the [`CrateRoot`] definition to get a sense of the different elements it contains. -Everything about metadata encoding and decoding is in the [`rustc_metadata`] -package. +Everything about metadata encoding and decoding is in the [`rustc_metadata`] package. Here are a few highlights of things it contains: -* The version of the `rustc` compiler. The compiler will refuse to load files - from any other version. -* The [Strict Version Hash](#strict-version-hash) (SVH). This helps ensure the - correct dependency is loaded. -* The [Stable Crate Id](#stable-crate-id). This is a hash used - to identify crates. -* Information about all the source files in the library. This can be used for - a variety of things, such as diagnostics pointing to sources in a +* The version of the `rustc` compiler. + The compiler will refuse to load files from any other version. +* The [Strict Version Hash](#strict-version-hash) (SVH). + This helps ensure the correct dependency is loaded. +* The [Stable Crate Id](#stable-crate-id). + This is a hash used to identify crates. +* Information about all the source files in the library. + This can be used for a variety of things, such as diagnostics pointing to sources in a dependency. -* Information about exported macros, traits, types, and items. Generally, - anything that's needed to be known when a path references something inside a - crate dependency. -* Encoded [MIR]. This is optional, and only encoded if needed for code - generation. `cargo check` skips this for performance reasons. +* Information about exported macros, traits, types, and items. + Generally, + anything that's needed to be known when a path references something inside a crate dependency. +* Encoded [MIR]. + This is optional, and only encoded if needed for code generation. + `cargo check` skips this for performance reasons. [`CrateRoot`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/struct.CrateRoot.html [`rustc_metadata`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/index.html @@ -89,10 +94,10 @@ Here are a few highlights of things it contains: ### Strict Version Hash The Strict Version Hash ([SVH], also known as the "crate hash") is a 64-bit -hash that is used to ensure that the correct crate dependencies are loaded. It -is possible for a directory to contain multiple copies of the same dependency -built with different settings, or built from different sources. The crate -loader will skip any crates that have the wrong SVH. +hash that is used to ensure that the correct crate dependencies are loaded. +It is possible for a directory to contain multiple copies of the same dependency +built with different settings, or built from different sources. +The crate loader will skip any crates that have the wrong SVH. The SVH is also used for the [incremental compilation] session filename, though that usage is mostly historic. @@ -114,14 +119,15 @@ See [`compute_hir_hash`] for where the hash is actually computed. ### Stable Crate Id The [`StableCrateId`] is a 64-bit hash used to identify different crates with -potentially the same name. It is a hash of the crate name and all the -[`-C metadata`] CLI options computed in [`StableCrateId::new`]. It is -used in a variety of places, such as symbol name mangling, crate loading, and +potentially the same name. +It is a hash of the crate name and all the +[`-C metadata`] CLI options computed in [`StableCrateId::new`]. +It is used in a variety of places, such as symbol name mangling, crate loading, and much more. By default, all Rust symbols are mangled and incorporate the stable crate id. -This allows multiple versions of the same crate to be included together. Cargo -automatically generates `-C metadata` hashes based on a variety of factors, like +This allows multiple versions of the same crate to be included together. +Cargo automatically generates `-C metadata` hashes based on a variety of factors, like the package version, source, and target kind (a lib and test can have the same crate name, so they need to be disambiguated). @@ -131,30 +137,31 @@ crate name, so they need to be disambiguated). ## Crate loading -Crate loading can have quite a few subtle complexities. During [name -resolution], when an external crate is referenced (via an `extern crate` or +Crate loading can have quite a few subtle complexities. +During [name resolution], when an external crate is referenced (via an `extern crate` or path), the resolver uses the [`CStore`] which is responsible for finding -the crate libraries and loading the [metadata] for them. After the dependency -is loaded, the `CStore` will provide the information the resolver needs +the crate libraries and loading the [metadata] for them. +After the dependency is loaded, the `CStore` will provide the information the resolver needs to perform its job (such as expanding macros, resolving paths, etc.). To load each external crate, the `CStore` uses a [`CrateLocator`] to -actually find the correct files for one specific crate. There is some great -documentation in the [`locator`] module that goes into detail on how loading +actually find the correct files for one specific crate. +There is some great documentation in the [`locator`] module that goes into detail on how loading works, and I strongly suggest reading it to get the full picture. -The location of a dependency can come from several different places. Direct -dependencies are usually passed with `--extern` flags, and the loader can look -at those directly. Direct dependencies often have references to their own -dependencies, which need to be loaded, too. These are usually found by +The location of a dependency can come from several different places. +Direct dependencies are usually passed with `--extern` flags, and the loader can look +at those directly. +Direct dependencies often have references to their own dependencies, which need to be loaded, too. +These are usually found by scanning the directories passed with the `-L` flag for any file whose metadata -contains a matching crate name and [SVH](#strict-version-hash). The loader -will also look at the [sysroot] to find dependencies. +contains a matching crate name and [SVH](#strict-version-hash). +The loader will also look at the [sysroot] to find dependencies. As crates are loaded, they are kept in the [`CStore`] with the crate metadata -wrapped in the [`CrateMetadata`] struct. After resolution and expansion, the -`CStore` will make its way into the [`GlobalCtxt`] for the rest of the -compilation. +wrapped in the [`CrateMetadata`] struct. +After resolution and expansion, the +`CStore` will make its way into the [`GlobalCtxt`] for the rest of the compilation. [name resolution]: ../name-resolution.md [`CrateLocator`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/locator/struct.CrateLocator.html @@ -167,20 +174,21 @@ compilation. ## Pipelining One trick to improve compile times is to start building a crate as soon as the -metadata for its dependencies is available. For a library, there is no need to -wait for the code generation of dependencies to finish. Cargo implements this -technique by telling `rustc` to emit an [`rmeta`](#rmeta) file for each -dependency as well as an [`rlib`](#rlib). As early as it can, `rustc` will -save the `rmeta` file to disk before it continues to the code generation -phase. The compiler sends a JSON message to let the build tool know that it +metadata for its dependencies is available. +For a library, there is no need to wait for the code generation of dependencies to finish. +Cargo implements this technique by telling `rustc` to emit an [`rmeta`](#rmeta) file for each +dependency as well as an [`rlib`](#rlib). +As early as it can, `rustc` will +save the `rmeta` file to disk before it continues to the code generation phase. +The compiler sends a JSON message to let the build tool know that it can start building the next crate if possible. The [crate loading](#crate-loading) system is smart enough to know when it -sees an `rmeta` file to use that if the `rlib` is not there (or has only been -partially written). +sees an `rmeta` file to use that if the `rlib` is not there (or has only been partially written). This pipelining isn't possible for binaries, because the linking phase will -require the code generation of all its dependencies. In the future, it may be +require the code generation of all its dependencies. +In the future, it may be possible to further improve this scenario by splitting linking into a separate command (see [#64191]). From 9e61149e8e40538b2de23db5979ad54d034403b0 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 29 Nov 2025 02:24:02 +0200 Subject: [PATCH 0165/3801] link text spanning separate lines is awkward --- src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md index 4cf0dfa6a6da..4a0b75c69431 100644 --- a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md +++ b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md @@ -23,9 +23,8 @@ This file contains: * Object code, which is the result of code generation. This is used during regular linking. There is a separate `.o` file for each [codegen unit]. - The codegen step can be skipped with the [`-C - linker-plugin-lto`][linker-plugin-lto] CLI option, which means each `.o` - file will only contain LLVM bitcode. + The codegen step can be skipped with the [`-C linker-plugin-lto`][linker-plugin-lto] CLI option, + which means each `.o` file will only contain LLVM bitcode. * [LLVM bitcode], which is a binary representation of LLVM's intermediate representation, which is embedded as a section in the `.o` files. This can be used for [Link Time Optimization] (LTO). From 4046385d609f73d32069ec0680a92b6d04d96761 Mon Sep 17 00:00:00 2001 From: EFanZh Date: Sat, 29 Nov 2025 09:52:19 +0800 Subject: [PATCH 0166/3801] Add `ilog10` result range hints --- library/core/src/num/int_log10.rs | 111 +++++---- library/core/src/num/int_macros.rs | 6 +- library/core/src/num/nonzero.rs | 2 +- .../lib-optimizations/ilog10-range.rs | 213 ++++++++++++++++++ 4 files changed, 282 insertions(+), 50 deletions(-) create mode 100644 tests/codegen-llvm/lib-optimizations/ilog10-range.rs diff --git a/library/core/src/num/int_log10.rs b/library/core/src/num/int_log10.rs index 649a736b6e7b..af8e1f90968d 100644 --- a/library/core/src/num/int_log10.rs +++ b/library/core/src/num/int_log10.rs @@ -1,9 +1,11 @@ //! These functions compute the integer logarithm of their type, assuming //! that someone has already checked that the value is strictly positive. +use crate::num::NonZero; + // 0 < val <= u8::MAX #[inline] -pub(super) const fn u8(val: u8) -> u32 { +const fn u8_impl(val: u8) -> u32 { let val = val as u32; // For better performance, avoid branches by assembling the solution @@ -45,13 +47,13 @@ const fn less_than_5(val: u32) -> u32 { // 0 < val <= u16::MAX #[inline] -pub(super) const fn u16(val: u16) -> u32 { +const fn u16_impl(val: u16) -> u32 { less_than_5(val as u32) } // 0 < val <= u32::MAX #[inline] -pub(super) const fn u32(mut val: u32) -> u32 { +const fn u32_impl(mut val: u32) -> u32 { let mut log = 0; if val >= 100_000 { val /= 100_000; @@ -62,7 +64,7 @@ pub(super) const fn u32(mut val: u32) -> u32 { // 0 < val <= u64::MAX #[inline] -pub(super) const fn u64(mut val: u64) -> u32 { +const fn u64_impl(mut val: u64) -> u32 { let mut log = 0; if val >= 10_000_000_000 { val /= 10_000_000_000; @@ -77,66 +79,87 @@ pub(super) const fn u64(mut val: u64) -> u32 { // 0 < val <= u128::MAX #[inline] -pub(super) const fn u128(mut val: u128) -> u32 { +const fn u128_impl(mut val: u128) -> u32 { let mut log = 0; if val >= 100_000_000_000_000_000_000_000_000_000_000 { val /= 100_000_000_000_000_000_000_000_000_000_000; log += 32; - return log + u32(val as u32); + return log + u32_impl(val as u32); } if val >= 10_000_000_000_000_000 { val /= 10_000_000_000_000_000; log += 16; } - log + u64(val as u64) + log + u64_impl(val as u64) } -#[cfg(target_pointer_width = "16")] -#[inline] -pub(super) const fn usize(val: usize) -> u32 { - u16(val as _) +macro_rules! define_unsigned_ilog10 { + ($($ty:ident => $impl_fn:ident,)*) => {$( + #[inline] + pub(super) const fn $ty(val: NonZero<$ty>) -> u32 { + let result = $impl_fn(val.get()); + + // SAFETY: Integer logarithm is monotonic non-decreasing, so the computed `result` cannot + // exceed the value produced for the maximum input. + unsafe { crate::hint::assert_unchecked(result <= const { $impl_fn($ty::MAX) }) }; + + result + } + )*}; } -#[cfg(target_pointer_width = "32")] -#[inline] -pub(super) const fn usize(val: usize) -> u32 { - u32(val as _) +define_unsigned_ilog10! { + u8 => u8_impl, + u16 => u16_impl, + u32 => u32_impl, + u64 => u64_impl, + u128 => u128_impl, } -#[cfg(target_pointer_width = "64")] #[inline] -pub(super) const fn usize(val: usize) -> u32 { - u64(val as _) +pub(super) const fn usize(val: NonZero) -> u32 { + #[cfg(target_pointer_width = "16")] + let impl_fn = u16; + + #[cfg(target_pointer_width = "32")] + let impl_fn = u32; + + #[cfg(target_pointer_width = "64")] + let impl_fn = u64; + + // SAFETY: We have selected the correct `impl_fn`, so the converting `val` to the argument is + // safe. + impl_fn(unsafe { NonZero::new_unchecked(val.get() as _) }) } -// 0 < val <= i8::MAX -#[inline] -pub(super) const fn i8(val: i8) -> u32 { - u8(val as u8) +macro_rules! define_signed_ilog10 { + ($($ty:ident => $impl_fn:ident,)*) => {$( + // 0 < val <= $ty::MAX + #[inline] + pub(super) const fn $ty(val: $ty) -> Option { + if val > 0 { + let result = $impl_fn(val.cast_unsigned()); + + // SAFETY: Integer logarithm is monotonic non-decreasing, so the computed `result` + // cannot exceed the value produced for the maximum input. + unsafe { + crate::hint::assert_unchecked(result <= const { $impl_fn($ty::MAX.cast_unsigned()) }); + } + + Some(result) + } else { + None + } + } + )*}; } -// 0 < val <= i16::MAX -#[inline] -pub(super) const fn i16(val: i16) -> u32 { - u16(val as u16) -} - -// 0 < val <= i32::MAX -#[inline] -pub(super) const fn i32(val: i32) -> u32 { - u32(val as u32) -} - -// 0 < val <= i64::MAX -#[inline] -pub(super) const fn i64(val: i64) -> u32 { - u64(val as u64) -} - -// 0 < val <= i128::MAX -#[inline] -pub(super) const fn i128(val: i128) -> u32 { - u128(val as u128) +define_signed_ilog10! { + i8 => u8_impl, + i16 => u16_impl, + i32 => u32_impl, + i64 => u64_impl, + i128 => u128_impl, } /// Instantiate this panic logic once, rather than for all the ilog methods diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 62f83a3a14d9..3e1749855d73 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -3527,11 +3527,7 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn checked_ilog10(self) -> Option { - if self > 0 { - Some(int_log10::$ActualT(self as $ActualT)) - } else { - None - } + int_log10::$ActualT(self as $ActualT) } /// Computes the absolute value of `self`. diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index ee375dbaaab2..2b5279efb7f7 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1657,7 +1657,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods { without modifying the original"] #[inline] pub const fn ilog10(self) -> u32 { - super::int_log10::$Int(self.get()) + super::int_log10::$Int(self) } /// Calculates the midpoint (average) between `self` and `rhs`. diff --git a/tests/codegen-llvm/lib-optimizations/ilog10-range.rs b/tests/codegen-llvm/lib-optimizations/ilog10-range.rs new file mode 100644 index 000000000000..b466855389fb --- /dev/null +++ b/tests/codegen-llvm/lib-optimizations/ilog10-range.rs @@ -0,0 +1,213 @@ +//! Make sure the compiler knows the result range of `ilog10`. + +//@ compile-flags: -O -Z merge-functions=disabled + +#![crate_type = "lib"] + +use std::num::NonZero; + +// Signed integers. + +#[no_mangle] +fn i8_ilog10_range(value: i8) { + const MAX_RESULT: u32 = i8::MAX.ilog10(); + + // CHECK-LABEL: @i8_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value <= 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn i16_ilog10_range(value: i16) { + const MAX_RESULT: u32 = i16::MAX.ilog10(); + + // CHECK-LABEL: @i16_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value <= 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn i32_ilog10_range(value: i32) { + const MAX_RESULT: u32 = i32::MAX.ilog10(); + + // CHECK-LABEL: @i32_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value <= 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn i64_ilog10_range(value: i64) { + const MAX_RESULT: u32 = i64::MAX.ilog10(); + + // CHECK-LABEL: @i64_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value <= 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn i128_ilog10_range(value: i128) { + const MAX_RESULT: u32 = i128::MAX.ilog10(); + + // CHECK-LABEL: @i128_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value <= 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn isize_ilog10_range(value: isize) { + const MAX_RESULT: u32 = isize::MAX.ilog10(); + + // CHECK-LABEL: @isize_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value <= 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +// Unsigned integer types. + +#[no_mangle] +fn u8_ilog10_range(value: u8) { + const MAX_RESULT: u32 = u8::MAX.ilog10(); + + // CHECK-LABEL: @u8_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value == 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn u16_ilog10_range(value: u16) { + const MAX_RESULT: u32 = u16::MAX.ilog10(); + + // CHECK-LABEL: @u16_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value == 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn u32_ilog10_range(value: u32) { + const MAX_RESULT: u32 = u32::MAX.ilog10(); + + // CHECK-LABEL: @u32_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value == 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn u64_ilog10_range(value: u64) { + const MAX_RESULT: u32 = u64::MAX.ilog10(); + + // CHECK-LABEL: @u64_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value == 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn u128_ilog10_range(value: u128) { + const MAX_RESULT: u32 = u128::MAX.ilog10(); + + // CHECK-LABEL: @u128_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value == 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +#[no_mangle] +fn usize_ilog10_range(value: usize) { + const MAX_RESULT: u32 = usize::MAX.ilog10(); + + // CHECK-LABEL: @usize_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value == 0 || value.ilog10() <= MAX_RESULT); + assert!(value.checked_ilog10().is_none_or(|result| result <= MAX_RESULT)); +} + +// Signed non-zero integers do not have `ilog10` methods. + +// Unsigned non-zero integers. + +#[no_mangle] +fn non_zero_u8_ilog10_range(value: NonZero) { + // CHECK-LABEL: @non_zero_u8_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value.ilog10() <= const { u8::MAX.ilog10() }); +} + +#[no_mangle] +fn non_zero_u16_ilog10_range(value: NonZero) { + // CHECK-LABEL: @non_zero_u16_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value.ilog10() <= const { u16::MAX.ilog10() }); +} + +#[no_mangle] +fn non_zero_u32_ilog10_range(value: NonZero) { + // CHECK-LABEL: @non_zero_u32_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value.ilog10() <= const { u32::MAX.ilog10() }); +} + +#[no_mangle] +fn non_zero_u64_ilog10_range(value: NonZero) { + // CHECK-LABEL: @non_zero_u64_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value.ilog10() <= const { u64::MAX.ilog10() }); +} + +#[no_mangle] +fn non_zero_u128_ilog10_range(value: NonZero) { + // CHECK-LABEL: @non_zero_u128_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value.ilog10() <= const { u128::MAX.ilog10() }); +} + +#[no_mangle] +fn non_zero_usize_ilog10_range(value: NonZero) { + // CHECK-LABEL: @non_zero_usize_ilog10_range( + // CHECK-NOT: panic + // CHECK: ret void + // CHECK-NEXT: } + assert!(value.ilog10() <= const { usize::MAX.ilog10() }); +} From 1af6474cdfd46fb4c8cc2f5442428000bd83b9af Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 29 Nov 2025 16:32:41 +0800 Subject: [PATCH 0167/3801] Support undotted-self for `this` param closure Using `this` instead of `self` in a closure is a common pattern Example --- ```rust struct Foo { field: i32 } impl Foo { fn foo(&mut self) { let f: fn(&mut Self) = |this| { $0 }; f(self) } } ``` **Before this PR** ```text fd self.field i32 me self.foo() fn(&mut self) lc self &mut Foo lc this &mut Foo md core sp Self Foo st Foo Foo tt Fn tt FnMut tt FnOnce bt u32 u32 ``` **After this PR** ```text fd this.field i32 me this.foo() fn(&mut self) lc self &mut Foo lc this &mut Foo md core sp Self Foo st Foo Foo tt Fn tt FnMut tt FnOnce bt u32 u32 ``` --- .../ide-completion/src/completions/dot.rs | 108 +++++++++++++++++- .../crates/ide-completion/src/context.rs | 2 +- .../ide-completion/src/context/analysis.rs | 25 +++- .../crates/ide-completion/src/render.rs | 42 +++++++ 4 files changed, 165 insertions(+), 12 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs index 9c2e0dcf1c62..18cfa53f8e96 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs @@ -4,6 +4,7 @@ use std::ops::ControlFlow; use hir::{Complete, Function, HasContainer, ItemContainer, MethodCandidateCallback}; use ide_db::FxHashSet; +use itertools::Either; use syntax::SmolStr; use crate::{ @@ -146,11 +147,14 @@ pub(crate) fn complete_undotted_self( _ => return, }; - let ty = self_param.ty(ctx.db); + let (param_name, ty) = match self_param { + Either::Left(self_param) => ("self", &self_param.ty(ctx.db)), + Either::Right(this_param) => ("this", this_param.ty()), + }; complete_fields( acc, ctx, - &ty, + ty, |acc, field, ty| { acc.add_field( ctx, @@ -163,15 +167,17 @@ pub(crate) fn complete_undotted_self( in_breakable: expr_ctx.in_breakable, }, }, - Some(SmolStr::new_static("self")), + Some(SmolStr::new_static(param_name)), field, &ty, ) }, - |acc, field, ty| acc.add_tuple_field(ctx, Some(SmolStr::new_static("self")), field, &ty), + |acc, field, ty| { + acc.add_tuple_field(ctx, Some(SmolStr::new_static(param_name)), field, &ty) + }, false, ); - complete_methods(ctx, &ty, &ctx.traits_in_scope(), |func| { + complete_methods(ctx, ty, &ctx.traits_in_scope(), |func| { acc.add_method( ctx, &DotAccess { @@ -184,7 +190,7 @@ pub(crate) fn complete_undotted_self( }, }, func, - Some(SmolStr::new_static("self")), + Some(SmolStr::new_static(param_name)), None, ) }); @@ -1073,6 +1079,96 @@ impl Foo { fn foo(&mut self) { $0 } }"#, ); } + #[test] + fn completes_bare_fields_and_methods_in_this_closure() { + check_no_kw( + r#" +//- minicore: fn +struct Foo { field: i32 } + +impl Foo { fn foo(&mut self) { let _: fn(&mut Self) = |this| { $0 } } }"#, + expect![[r#" + fd this.field i32 + me this.foo() fn(&mut self) + lc self &mut Foo + lc this &mut Foo + md core + sp Self Foo + st Foo Foo + tt Fn + tt FnMut + tt FnOnce + bt u32 u32 + "#]], + ); + } + + #[test] + fn completes_bare_fields_and_methods_in_other_closure() { + check_no_kw( + r#" +//- minicore: fn +struct Foo { field: i32 } + +impl Foo { fn foo(&self) { let _: fn(&Self) = |foo| { $0 } } }"#, + expect![[r#" + fd self.field i32 + me self.foo() fn(&self) + lc foo &Foo + lc self &Foo + md core + sp Self Foo + st Foo Foo + tt Fn + tt FnMut + tt FnOnce + bt u32 u32 + "#]], + ); + + check_no_kw( + r#" +//- minicore: fn +struct Foo { field: i32 } + +impl Foo { fn foo(&self) { let _: fn(&Self) = || { $0 } } }"#, + expect![[r#" + fd self.field i32 + me self.foo() fn(&self) + lc self &Foo + md core + sp Self Foo + st Foo Foo + tt Fn + tt FnMut + tt FnOnce + bt u32 u32 + "#]], + ); + + check_no_kw( + r#" +//- minicore: fn +struct Foo { field: i32 } + +impl Foo { fn foo(&self) { let _: fn(&Self, &Self) = |foo, other| { $0 } } }"#, + expect![[r#" + fd self.field i32 + me self.foo() fn(&self) + lc foo &Foo + lc other &Foo + lc self &Foo + md core + sp Self Foo + st Foo Foo + tt Fn + tt FnMut + tt FnOnce + bt u32 u32 + "#]], + ); + } + #[test] fn macro_completion_after_dot() { check_no_kw( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index 23318e1d1991..7502026c6fc2 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -157,7 +157,7 @@ pub(crate) struct PathExprCtx<'db> { pub(crate) after_amp: bool, /// The surrounding RecordExpression we are completing a functional update pub(crate) is_func_update: Option, - pub(crate) self_param: Option, + pub(crate) self_param: Option>>, pub(crate) innermost_ret_ty: Option>, pub(crate) innermost_breakable_ty: Option>, pub(crate) impl_: Option, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index e761da7152c6..71c64a8366a5 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -1286,10 +1286,26 @@ fn classify_name_ref<'db>( ) } }; - let find_fn_self_param = |it| match it { - ast::Item::Fn(fn_) => Some(sema.to_def(&fn_).and_then(|it| it.self_param(sema.db))), - ast::Item::MacroCall(_) => None, - _ => Some(None), + let fn_self_param = + |fn_: ast::Fn| sema.to_def(&fn_).and_then(|it| it.self_param(sema.db)); + let closure_this_param = |closure: ast::ClosureExpr| { + if closure.param_list()?.params().next()?.pat()?.syntax().text() != "this" { + return None; + } + sema.type_of_expr(&closure.into()) + .and_then(|it| it.original.as_callable(sema.db)) + .and_then(|it| it.params().into_iter().next()) + }; + let find_fn_self_param = |it: SyntaxNode| { + match_ast! { + match it { + ast::Fn(fn_) => Some(fn_self_param(fn_).map(Either::Left)), + ast::ClosureExpr(f) => closure_this_param(f).map(Either::Right).map(Some), + ast::MacroCall(_) => None, + ast::Item(_) => Some(None), + _ => None, + } + } }; match find_node_in_file_compensated(sema, original_file, &expr) { @@ -1302,7 +1318,6 @@ fn classify_name_ref<'db>( let self_param = sema .ancestors_with_macros(it.syntax().clone()) - .filter_map(ast::Item::cast) .find_map(find_fn_self_param) .flatten(); (innermost_ret_ty, self_param) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index c0f09e1d950d..aa9b05ecffec 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -3239,6 +3239,48 @@ impl S { ) } + #[test] + fn field_access_includes_closure_this_param() { + check_edit( + "length", + r#" +//- minicore: fn +struct S { + length: i32 +} + +impl S { + fn pack(&mut self, f: impl FnOnce(&mut Self, i32)) { + self.length += 1; + f(self, 3); + self.length -= 1; + } + + fn some_fn(&mut self) { + self.pack(|this, n| len$0); + } +} +"#, + r#" +struct S { + length: i32 +} + +impl S { + fn pack(&mut self, f: impl FnOnce(&mut Self, i32)) { + self.length += 1; + f(self, 3); + self.length -= 1; + } + + fn some_fn(&mut self) { + self.pack(|this, n| this.length); + } +} +"#, + ) + } + #[test] fn notable_traits_method_relevance() { check_kinds( From 5a7ea1d3bffd3e3f268d3b3875d779cee8b93294 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 19 Nov 2025 14:34:00 +0100 Subject: [PATCH 0168/3801] Count unsafe operations only towards the innermost unsafe block Also, macro calls are counted as at most one unsafe operation. --- .../src/multiple_unsafe_ops_per_block.rs | 70 +++-- tests/ui/multiple_unsafe_ops_per_block.rs | 133 +++++++++ tests/ui/multiple_unsafe_ops_per_block.stderr | 257 ++++++++++++++---- 3 files changed, 392 insertions(+), 68 deletions(-) diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 80cf081992cc..42dc9f2f1fa8 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -3,13 +3,14 @@ use clippy_utils::diagnostics::span_lint_and_then; use hir::def::{DefKind, Res}; use hir::{BlockCheckMode, ExprKind, QPath, UnOp}; use rustc_ast::{BorrowKind, Mutability}; +use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::intravisit::{Visitor, walk_body, walk_expr}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt, TypeckResults}; use rustc_session::declare_lint_pass; -use rustc_span::{DesugaringKind, Span}; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does @@ -56,12 +57,16 @@ declare_clippy_lint! { /// } /// ``` /// - /// ### Note + /// ### Notes /// - /// Taking a raw pointer to a union field is always safe and will - /// not be considered unsafe by this lint, even when linting code written - /// with a specified Rust version of 1.91 or earlier (which required - /// using an `unsafe` block). + /// - Unsafe operations only count towards the total for the innermost + /// enclosing `unsafe` block. + /// - Each call to a macro expanding to unsafe operations count for one + /// unsafe operation. + /// - Taking a raw pointer to a union field is always safe and will + /// not be considered unsafe by this lint, even when linting code written + /// with a specified Rust version of 1.91 or earlier (which required + /// using an `unsafe` block). #[clippy::version = "1.69.0"] pub MULTIPLE_UNSAFE_OPS_PER_BLOCK, restriction, @@ -71,10 +76,7 @@ declare_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK]) impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock { fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) { - if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) - || block.span.in_external_macro(cx.tcx.sess.source_map()) - || block.span.is_desugaring(DesugaringKind::Await) - { + if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) || block.span.from_expansion() { return; } let unsafe_ops = UnsafeExprCollector::collect_unsafe_exprs(cx, block); @@ -100,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock { struct UnsafeExprCollector<'tcx> { tcx: TyCtxt<'tcx>, typeck_results: &'tcx TypeckResults<'tcx>, - unsafe_ops: Vec<(&'static str, Span)>, + unsafe_ops: FxHashMap, } impl<'tcx> UnsafeExprCollector<'tcx> { @@ -108,10 +110,33 @@ impl<'tcx> UnsafeExprCollector<'tcx> { let mut collector = Self { tcx: cx.tcx, typeck_results: cx.typeck_results(), - unsafe_ops: vec![], + unsafe_ops: FxHashMap::default(), }; collector.visit_block(block); - collector.unsafe_ops + #[allow( + rustc::potential_query_instability, + reason = "span ordering only needed inside the one expression being walked" + )] + let mut unsafe_ops = collector + .unsafe_ops + .into_iter() + .map(|(span, msg)| (msg, span)) + .collect::>(); + unsafe_ops.sort_unstable(); + unsafe_ops + } +} + +impl UnsafeExprCollector<'_> { + fn insert_span(&mut self, span: Span, message: &'static str) { + if span.from_expansion() { + self.unsafe_ops.insert( + span.source_callsite(), + "this macro call expands into one or more unsafe operations", + ); + } else { + self.unsafe_ops.insert(span, message); + } } } @@ -126,7 +151,10 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { return self.visit_expr(e); }, - ExprKind::InlineAsm(_) => self.unsafe_ops.push(("inline assembly used here", expr.span)), + // Do not recurse inside an inner `unsafe` block, it will be checked on its own + ExprKind::Block(block, _) if matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) => return, + + ExprKind::InlineAsm(_) => self.insert_span(expr.span, "inline assembly used here"), ExprKind::AddrOf(BorrowKind::Raw, _, mut inner) => { while let ExprKind::Field(prefix, _) = inner.kind @@ -139,7 +167,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { ExprKind::Field(e, _) => { if self.typeck_results.expr_ty(e).is_union() { - self.unsafe_ops.push(("union field access occurs here", expr.span)); + self.insert_span(expr.span, "union field access occurs here"); } }, @@ -157,12 +185,11 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { .. }, )) => { - self.unsafe_ops - .push(("access of a mutable static occurs here", expr.span)); + self.insert_span(expr.span, "access of a mutable static occurs here"); }, ExprKind::Unary(UnOp::Deref, e) if self.typeck_results.expr_ty(e).is_raw_ptr() => { - self.unsafe_ops.push(("raw pointer dereference occurs here", expr.span)); + self.insert_span(expr.span, "raw pointer dereference occurs here"); }, ExprKind::Call(path_expr, _) => { @@ -172,7 +199,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { _ => None, }; if opt_sig.is_some_and(|sig| sig.safety().is_unsafe()) { - self.unsafe_ops.push(("unsafe function call occurs here", expr.span)); + self.insert_span(expr.span, "unsafe function call occurs here"); } }, @@ -182,7 +209,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { .type_dependent_def_id(expr.hir_id) .map(|def_id| self.tcx.fn_sig(def_id)); if opt_sig.is_some_and(|sig| sig.skip_binder().safety().is_unsafe()) { - self.unsafe_ops.push(("unsafe method call occurs here", expr.span)); + self.insert_span(expr.span, "unsafe method call occurs here"); } }, @@ -203,8 +230,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { } )) ) { - self.unsafe_ops - .push(("modification of a mutable static occurs here", expr.span)); + self.insert_span(expr.span, "modification of a mutable static occurs here"); return self.visit_expr(rhs); } }, diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index c1512ba3e269..0ff881472cbb 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -312,4 +312,137 @@ fn check_closures() { } } +fn issue16116() { + unsafe fn foo() -> u32 { + 0 + } + + // Do not lint even though `format!` expansion + // contains unsafe calls. + unsafe { + let _ = format!("{}", foo()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + let _ = format!("{}", foo()); + let _ = format!("{}", foo()); + } + + // Do not lint: only one `assert!()` argument is unsafe + unsafe { + assert_eq!(foo(), 0, "{}", 1 + 2); + } + + // Each argument of a macro call may count as an unsafe operation. + unsafe { + //~^ multiple_unsafe_ops_per_block + assert_eq!(foo(), 0, "{}", foo()); // One unsafe operation + } + + macro_rules! twice { + ($e:expr) => {{ + $e; + $e; + }}; + } + + // Do not lint, a repeated argument used twice by a macro counts + // as at most one unsafe operation. + unsafe { + twice!(foo()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + twice!(foo()); + twice!(foo()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + assert_eq!(foo(), 0, "{}", 1 + 2); + assert_eq!(foo(), 0, "{}", 1 + 2); + } + + macro_rules! unsafe_twice { + ($e:expr) => { + unsafe { + $e; + $e; + } + }; + }; + + // A macro whose expansion contains unsafe blocks will not + // check inside the blocks. + unsafe { + unsafe_twice!(foo()); + } + + macro_rules! double_non_arg_unsafe { + () => {{ + _ = str::from_utf8_unchecked(&[]); + _ = str::from_utf8_unchecked(&[]); + }}; + } + + // Do not lint: each unsafe expression contained in the + // macro expansion will count towards the macro call. + unsafe { + double_non_arg_unsafe!(); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + double_non_arg_unsafe!(); + double_non_arg_unsafe!(); + } + + // Do not lint: the inner macro call counts as one unsafe op. + unsafe { + assert_eq!(double_non_arg_unsafe!(), ()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + assert_eq!(double_non_arg_unsafe!(), ()); + assert_eq!(double_non_arg_unsafe!(), ()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ())); + } + + macro_rules! unsafe_with_arg { + ($e:expr) => {{ + _ = str::from_utf8_unchecked(&[]); + $e; + }}; + } + + // A confusing situation: the macro call counts towards two unsafe calls, + // one coming from inside the macro itself, and one coming from its argument. + // The error message may seem a bit strange as both the macro call and its + // argument will be marked as counting as unsafe ops, but a short investigation + // in those rare situations should sort it out easily. + unsafe { + //~^ multiple_unsafe_ops_per_block + unsafe_with_arg!(foo()); + } + + macro_rules! ignore { + ($e: expr) => {}; + } + + // Another surprising case is when the macro argument is not + // used in the expansion, but in this case we won't see the + // unsafe operation at all. + unsafe { + ignore!(foo()); + ignore!(foo()); + } +} + fn main() {} diff --git a/tests/ui/multiple_unsafe_ops_per_block.stderr b/tests/ui/multiple_unsafe_ops_per_block.stderr index 63f7742b734b..185225bd28c8 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.stderr +++ b/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -31,16 +31,16 @@ LL | | *raw_ptr(); LL | | } | |_____^ | -note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:50:14 - | -LL | drop(u.u); - | ^^^ note: raw pointer dereference occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:51:9 | LL | *raw_ptr(); | ^^^^^^^^^^ +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:50:14 + | +LL | drop(u.u); + | ^^^ error: this `unsafe` block contains 3 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:56:5 @@ -58,16 +58,16 @@ note: inline assembly used here | LL | asm!("nop"); | ^^^^^^^^^^^ -note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:59:9 - | -LL | sample.not_very_safe(); - | ^^^^^^^^^^^^^^^^^^^^^^ note: modification of a mutable static occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:60:9 | LL | STATIC = 0; | ^^^^^^^^^^ +note: unsafe method call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:59:9 + | +LL | sample.not_very_safe(); + | ^^^^^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 6 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:66:5 @@ -81,36 +81,36 @@ LL | | asm!("nop"); LL | | } | |_____^ | -note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:68:14 - | -LL | drop(u.u); - | ^^^ note: access of a mutable static occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:69:14 | LL | drop(STATIC); | ^^^^^^ -note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:70:9 - | -LL | sample.not_very_safe(); - | ^^^^^^^^^^^^^^^^^^^^^^ -note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:71:9 - | -LL | not_very_safe(); - | ^^^^^^^^^^^^^^^ -note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:72:9 - | -LL | *raw_ptr(); - | ^^^^^^^^^^ note: inline assembly used here --> tests/ui/multiple_unsafe_ops_per_block.rs:73:9 | LL | asm!("nop"); | ^^^^^^^^^^^ +note: raw pointer dereference occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:72:9 + | +LL | *raw_ptr(); + | ^^^^^^^^^^ +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:68:14 + | +LL | drop(u.u); + | ^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:71:9 + | +LL | not_very_safe(); + | ^^^^^^^^^^^^^^^ +note: unsafe method call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:70:9 + | +LL | sample.not_very_safe(); + | ^^^^^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:109:5 @@ -139,16 +139,16 @@ error: this `unsafe` block contains 2 unsafe operations, expected only one LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:118:18 - | -LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:118:43 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:118:18 + | +LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:139:9 @@ -224,16 +224,16 @@ LL | | foo().await; LL | | } | |_____^ | -note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:194:9 - | -LL | not_very_safe(); - | ^^^^^^^^^^^^^^^ note: modification of a mutable static occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:195:9 | LL | STATIC += 1; | ^^^^^^^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:194:9 + | +LL | not_very_safe(); + | ^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:207:5 @@ -265,16 +265,16 @@ LL | | Some(foo_unchecked()).unwrap_unchecked().await; LL | | } | |_____^ | -note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:216:9 - | -LL | Some(foo_unchecked()).unwrap_unchecked().await; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: unsafe function call occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:216:14 | LL | Some(foo_unchecked()).unwrap_unchecked().await; | ^^^^^^^^^^^^^^^ +note: unsafe method call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:216:9 + | +LL | Some(foo_unchecked()).unwrap_unchecked().await; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:236:5 @@ -359,5 +359,170 @@ note: unsafe function call occurs here LL | apply(|| f(0)); | ^^^^ -error: aborting due to 16 previous errors +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:326:5 + | +LL | / unsafe { +LL | | +LL | | let _ = format!("{}", foo()); +LL | | let _ = format!("{}", foo()); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:328:31 + | +LL | let _ = format!("{}", foo()); + | ^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:329:31 + | +LL | let _ = format!("{}", foo()); + | ^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:338:5 + | +LL | / unsafe { +LL | | +LL | | assert_eq!(foo(), 0, "{}", foo()); // One unsafe operation +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:340:20 + | +LL | assert_eq!(foo(), 0, "{}", foo()); // One unsafe operation + | ^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:340:36 + | +LL | assert_eq!(foo(), 0, "{}", foo()); // One unsafe operation + | ^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:356:5 + | +LL | / unsafe { +LL | | +LL | | twice!(foo()); +LL | | twice!(foo()); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:358:16 + | +LL | twice!(foo()); + | ^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:359:16 + | +LL | twice!(foo()); + | ^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:362:5 + | +LL | / unsafe { +LL | | +LL | | assert_eq!(foo(), 0, "{}", 1 + 2); +LL | | assert_eq!(foo(), 0, "{}", 1 + 2); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:364:20 + | +LL | assert_eq!(foo(), 0, "{}", 1 + 2); + | ^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:365:20 + | +LL | assert_eq!(foo(), 0, "{}", 1 + 2); + | ^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:396:5 + | +LL | / unsafe { +LL | | +LL | | double_non_arg_unsafe!(); +LL | | double_non_arg_unsafe!(); +LL | | } + | |_____^ + | +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:398:9 + | +LL | double_non_arg_unsafe!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:399:9 + | +LL | double_non_arg_unsafe!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:407:5 + | +LL | / unsafe { +LL | | +LL | | assert_eq!(double_non_arg_unsafe!(), ()); +LL | | assert_eq!(double_non_arg_unsafe!(), ()); +LL | | } + | |_____^ + | +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:409:20 + | +LL | assert_eq!(double_non_arg_unsafe!(), ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:410:20 + | +LL | assert_eq!(double_non_arg_unsafe!(), ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:413:5 + | +LL | / unsafe { +LL | | +LL | | assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ())); +LL | | } + | |_____^ + | +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:415:21 + | +LL | assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ())); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:415:47 + | +LL | assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ())); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:430:5 + | +LL | / unsafe { +LL | | +LL | | unsafe_with_arg!(foo()); +LL | | } + | |_____^ + | +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:432:9 + | +LL | unsafe_with_arg!(foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:432:26 + | +LL | unsafe_with_arg!(foo()); + | ^^^^^ + +error: aborting due to 24 previous errors From 1c89fe9d6d8e72c12ad78413465beb8470eca972 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Sat, 29 Nov 2025 10:19:56 +0100 Subject: [PATCH 0169/3801] Remove an unnecessary `unwrap` in `rustc_codegen_gcc` --- src/builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index c0519f7a68e2..1787415b72e6 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -503,9 +503,9 @@ fn set_rvalue_location<'a, 'gcc, 'tcx>( bx: &mut Builder<'a, 'gcc, 'tcx>, rvalue: RValue<'gcc>, ) -> RValue<'gcc> { - if bx.location.is_some() { + if let Some(location) = bx.location { #[cfg(feature = "master")] - rvalue.set_location(bx.location.unwrap()); + rvalue.set_location(location); } rvalue } From 74da3a26c60ddf6fbdf12bedba409a12c51789da Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Sat, 29 Nov 2025 14:29:58 +0000 Subject: [PATCH 0170/3801] add coercions chapter and split out non hir typeck stuff --- src/doc/rustc-dev-guide/src/SUMMARY.md | 17 +- .../src/appendix/code-index.md | 2 +- .../rustc-dev-guide/src/appendix/glossary.md | 2 +- .../src/hir-typeck/coercions.md | 284 ++++++++++++++++++ .../src/{ => hir-typeck}/method-lookup.md | 0 .../summary.md} | 8 +- src/doc/rustc-dev-guide/src/overview.md | 2 +- src/doc/rustc-dev-guide/src/thir.md | 2 +- .../src/traits/canonical-queries.md | 2 +- 9 files changed, 302 insertions(+), 17 deletions(-) create mode 100644 src/doc/rustc-dev-guide/src/hir-typeck/coercions.md rename src/doc/rustc-dev-guide/src/{ => hir-typeck}/method-lookup.md (100%) rename src/doc/rustc-dev-guide/src/{type-checking.md => hir-typeck/summary.md} (94%) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 37ab3ff56979..c136d37160c5 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -186,14 +186,15 @@ - [Opaque types](./solve/opaque-types.md) - [Significant changes and quirks](./solve/significant-changes.md) - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md) -- [Type checking](./type-checking.md) - - [Method lookup](./method-lookup.md) - - [Variance](./variance.md) - - [Coherence checking](./coherence.md) - - [Opaque types](./opaque-types-type-alias-impl-trait.md) - - [Inference details](./opaque-types-impl-trait-inference.md) - - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md) - - [Region inference restrictions][opaque-infer] +- [Variance](./variance.md) +- [Coherence checking](./coherence.md) +- [HIR Type checking](./hir-typeck/summary.md) + - [Coercions](./hir-typeck/coercions.md) + - [Method lookup](./hir-typeck/method-lookup.md) +- [Opaque types](./opaque-types-type-alias-impl-trait.md) + - [Inference details](./opaque-types-impl-trait-inference.md) + - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md) + - [Region inference restrictions][opaque-infer] - [Const condition checking](./effects.md) - [Pattern and exhaustiveness checking](./pat-exhaustive-checking.md) - [Unsafety checking](./unsafety-checking.md) diff --git a/src/doc/rustc-dev-guide/src/appendix/code-index.md b/src/doc/rustc-dev-guide/src/appendix/code-index.md index 22b3396ed1ff..bf9d3bd46564 100644 --- a/src/doc/rustc-dev-guide/src/appendix/code-index.md +++ b/src/doc/rustc-dev-guide/src/appendix/code-index.md @@ -33,7 +33,7 @@ Item | Kind | Short description | Chapter | [Identifiers in the HIR]: ../hir.html#hir-id [The parser]: ../the-parser.html [The Rustc Driver and Interface]: ../rustc-driver/intro.html -[Type checking]: ../type-checking.html +[Type checking]: ../hir-typeck/summary.html [The `ty` modules]: ../ty.html [Rustdoc]: ../rustdoc.html [Emitting Diagnostics]: ../diagnostics.html diff --git a/src/doc/rustc-dev-guide/src/appendix/glossary.md b/src/doc/rustc-dev-guide/src/appendix/glossary.md index 21162f8ee7d0..901fb68c0513 100644 --- a/src/doc/rustc-dev-guide/src/appendix/glossary.md +++ b/src/doc/rustc-dev-guide/src/appendix/glossary.md @@ -88,7 +88,7 @@ Term | Meaning trans | Short for _translation_, the code to translate MIR into LLVM IR. Renamed to [codegen](#codegen). `Ty` | The internal representation of a type. ([see more](../ty.md)) `TyCtxt` | The data structure often referred to as [`tcx`](#tcx) in code which provides access to session data and the query system. -UFCS | Short for _universal function call syntax_, this is an unambiguous syntax for calling a method. **Term no longer in use!** Prefer _fully-qualified path/syntax_. ([see more](../type-checking.md), [see the reference](https://doc.rust-lang.org/reference/expressions/call-expr.html#disambiguating-function-calls)) +UFCS | Short for _universal function call syntax_, this is an unambiguous syntax for calling a method. **Term no longer in use!** Prefer _fully-qualified path/syntax_. ([see more](../hir-typeck/summary.md), [see the reference](https://doc.rust-lang.org/reference/expressions/call-expr.html#disambiguating-function-calls)) uninhabited type | A type which has _no_ values. This is not the same as a ZST, which has exactly 1 value. An example of an uninhabited type is `enum Foo {}`, which has no variants, and so, can never be created. The compiler can treat code that deals with uninhabited types as dead code, since there is no such value to be manipulated. `!` (the never type) is an uninhabited type. Uninhabited types are also called _empty types_. upvar | A variable captured by a closure from outside the closure. variance | Determines how changes to a generic parameter affect subtyping; for example, if `T` is a subtype of `U`, then `Vec` is a subtype `Vec` because `Vec` is _covariant_ in its generic parameter. See [the background chapter](./background.md#variance) for a more general explanation. See the [variance chapter](../variance.md) for an explanation of how type checking handles variance. diff --git a/src/doc/rustc-dev-guide/src/hir-typeck/coercions.md b/src/doc/rustc-dev-guide/src/hir-typeck/coercions.md new file mode 100644 index 000000000000..384ea9bcf030 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/hir-typeck/coercions.md @@ -0,0 +1,284 @@ +# Coercions + +Coercions are implicit operations which transform a value into a different type. A coercion *site* is a position where a coercion is able to be implicitly performed. There are two kinds of coercion sites: +- one-to-one +- LUB (Least-Uppper-Bound) + +```rust +let one_to_one_coercion: &u32 = &mut 8; + +let lub_coercion = match my_bool { + true => &mut 10, + false => &12, +}; +``` + +See the Reference page on coercions for descriptions of what coercions exist and what expressions are coercion sites: + +## one-to-one coercions + +With a one-to-one coercion we coerce from one singular type to a known target type. In the above example this would be the coercion from `&mut u32` to `&u32`. + +A one-to-one coercion can be performed by calling [`FnCtxt::coerce`][fnctxt_coerce]. + +## LUB coercions + +With a LUB coercion we coerce a set of source types to some unknown target type. Unlike one-to-one coercions, a LUB coercion *produces* the target type that all of the source types coerce to. + +In the above example this would be the LUB coercion of both `&mut i32` and `&i32`, where we produce the target type `&i32`. + +The name "LUB coercion" (Least-Upper-Bound coercion) comes from how this coercion takes a set of types and computes the least coerced/subtyped type that both source types are coercable/subtypeable into. + +The general process for performing a LUB coercion is as follows: + +```rust ignore +// * 1 +let mut coerce = CoerceMany::new(intial_lub_ty); +for expr in exprs { + // * 2 + let expr_ty = fcx.check_expr_with_expectation(expr, expectation); + coerce.coerce(fcx, &cause, expr, expr_ty); +} +// * 3 +let final_ty = coerce.complete(fcx); +``` + +There are a few key steps here: +1. Creating the [`CoerceMany`][coerce_many] value and picking an initial lub +2. Typechecking each expression and registering its type as part of the LUB coercion +3. Completing the LUB coercion to get the resulting lubbed type + +### Step 1 + +First we create a [`CoerceMany`][coerce_many] value, this stores all of the state required for the LUB coercion. Unlike one-to-one coercions, a LUB coercion isn't a single function call as we want to intermix typechecking with advancing the LUB coercion. + +Creating a `CoerceMany` takes some `initial_lub` type. This is different from the *target* of the coercion which is an output of a LUB coercion rather than an input (unlike a one-to-one coercion). + +The initial lub ty should be derived from the [`Expectation`][expectation] for whatever expression this LUB coercion is for. It allows for inference constraints from computing the LUB coercion to propagate into the `Expectation`s used for type checking later expressions participating in the LUB coercion. + +See the ["unnecessary inference constraints"][unnecessary_inference_constraints] header for some more information about the effects this has. + +If there's no `Expectation` to use then some new infer var should be made for the initial lub ty. + +### Step 2 + +Next, for each expression participating in the LUB coercion, we typecheck it then invoke [`CoerceMany::coerce`][coerce_many_coerce] with its type. + +In some cases the expression participating in the LUB coercion doesn't actually exist in the HIR. For example when handling an operand-less `break` or `return` expression we need `()` to participate in the LUB coercion. + +In these cases the [`CoerceMany::coerce_forced_unit`][coerce_many_coerce_forced_unit] method can be used. + +The `CoerceMany::coerce` and `coerce_forced_unit` methods will both emit errors if the new type causes the LUB coercion to be unsatisfiable. In this case the final type of the LUB coercion will be an error type. + +### Step 3 + +Finally once all expressions have been coerced the final type of the LUB coercion can be obtained by calling [`CoerceMany::complete`][coerce_many_complete]. + +The resulting type of the LUB coercion is meaningfully different from the initial lub type passed in when constructing the [`CoerceMany`][coerce_many]. You should always take the resulting type of the LUB coercion and perform any necessary checks on it. + +## Implementation nuances + +### Adjustments + +When a coerce operation succeeds we record what kind of coercion it was, for example an unsize coercion or an autoderef etc. This is handled as part of the coerce operation by writing a list of *adjustments* into the in-progress [`TypeckResults`][typeck_results]. + +When building THIR we take the adjustments stored in the `TypeckResults` and make all of the coercion steps explicit. After this point in the compiler there isn't really a notion of coercions, only explicit casts and subtyping in the MIR. + +TODO: write and link to an adjustments chapter here + +### How does `CoerceMany` work + +[`CoerceMany`][coerce_many] works by repeatedly taking the current lub ty and some new source type, and computing a new lub ty which both types can coerce to. The core logic of taking a pair of types and computing some new third type can be found in [`try_find_coercion_lub`][try_find_coercion_lub]. + +```rust +fn foo() {} +fn bar() {} + +let a = match my_bool { + true => foo, + true if other_bool => foo, + false => bar, +} +``` + +In this example when type checking the `match` expression a LUB coercion is performed. This LUB coercion starts out with an initial lub ty of some inference variable `?x` due to the let statement having no known type. + +There are three expressions that participate in this LUB coercion. The first expression of a LUB coercion is special, instead of computing a new type with the existing initial lub ty, we coerce directly from the first expression to the initial lub ty. + +1. After type checking `true => foo,` we wind up with the type `FnDef(Foo)`. We then call [`CoerceMany::coerce`][coerce_many_coerce] which will perform a one-to-one coercion of `FnDef(Foo)` to `?x`. This infers `?x=FnDef(Foo)` giving us a new lub ty for the LUB coercion. +2. After type checking `true if other_bool => foo,` we once again wind up with the type `FnDef(Foo)`. We'll then call `CoerceMany::coerce` which will attempt to compute a new lub ty from our previous lub ty (`FnDef(Foo)`) and the type of this expression (`FnDef(Foo)`). This gives us a lub ty of `FnDef(Foo)`. +3. After type checking `false => bar,` we'll wind up with the type `FnDef(Bar)`. We'll then call `CoerceMany::coerce` which will attempt to compute a new lub ty from our previous lub ty (`FnDef(Foo)`) and the type of this expression (`FnDef(Bar)`). In this case we get the type `fn() -> ()` as we choose to coerce both function item types to a function pointer. + +This gives us a final type for the LUB coercion of `fn() -> ()`. + +### Transitive coercions + +[`CoerceMany`][coerce_many]'s algorithm of repeatedly attempting to coerce the currrent target type to the new type currently results in "Transitive Coercions". It's possible for a step in a LUB coercion to coerce an expression, and then a later step to coerce that expression further. + +```rust +struct Foo; + +use std::ops::Deref; + +impl Deref for Foo { + type Target = [u8; 2]; + + fn deref(&self) -> &[u8; 2] { + &[1; _] + } +} + +fn main() { + match () { + _ if true => &Foo, + _ if true => &[1_u8; 2], + _ => &[1_u8; 2] as &[u8], + }; +} +``` + +Here we have a LUB coercion with an initial lub ty of `?x`. In the first step we do a one-to-one coercion of `&Foo` to `?x` (reminder the first step is special). + +In the second step we compute a new lub ty from the current lub ty of `&Foo` and the new type of `&[u8; 2]`. This new lub ty would be `&[u8; 2]` by performing a deref coercion of `&Foo` to `&[u8; 2]` on the first expression. + +In the third step we compute a new lub ty from the current lub ty of `&[u8; 2]` and the new type of `&[u8]`. This new lub ty would be `&[u8]` by performing an unsizing coercion of `&[u8; 2]` to `&[u8]` on the first two expressions. + +Note how the first expression is coerced twice. Once a deref coercion from `&Foo` to `&[u8; 2]`, and then an unsizing coercion from `&[u8; 2]` to `&[u8]`. + +The current implementation of transitive coercions is broken, the previous example actually ICEs on stable. While the logic for performing a LUB coercion can produce transitive coercions just fine, the rest of the compiler is not set up to handle them. + +One-to-one coercions are also not capable of producing a lot of the kinds of transitive coercions that LUB coercions can. For example if we take the previous example and turn it into a one-to-one coercion we get a compile error: +```rust +struct Foo; + +use std::ops::Deref; + +impl Deref for Foo { + type Target = [u8; 2]; + + fn deref(&self) -> &[u8; 2] { + &[1; _] + } +} + +fn main() { + let a: &[u8] = &Foo; +} +``` + +Here we try to perform a one-to-one coercion from `&Foo` to `&[u8]` which fails as we can only perform a deref coercion *or* an unsizing coercion, we can't compose the two. + +### How does `try_find_coercion_lub` work + +There are three ways that we can compute a new lub ty for a LUB coercion: +1. Coerce both the current lub ty and the new type to a function pointer +2. Coerce the current lub ty to the new type (or vice versa) +3. Compute a mutual supertype of the current lub ty and the new type + +Unfortunately the actual implementation obsfucates this a fair amount. + +Computing a mutual supertype happens implicitly due to reusing the logic for one-to-one coercions which already handles subtyping if coercing fails. + +Additionally when trying to coerce both the current lub ty and the new type to function pointers we eagerly try to compute a mutual supertype to avoid unnecessary coercions. + +There is likely room for improving the structure of this function to make it more closely align with the conceptual model. + +### `use_lub` field in one-to-one coercions + +The implementation of one-to-one coercions is reused as part of LUB coercions. + +It would be wrong for LUB coercions to use one way subtyping when relating signatures or falling back to subtyping in the case of no coercions being possible. Instead we want to compute a mutual supertype of the two types. + +The `use_lub` field on [`Coerce`][coerce_ty] exists to toggle whether to perform normal subtyping (in the case of a one-to-one coercion), or whether to compute a mutual supertype (in the case of a LUB coercion). + +### Lubbing + +In theory computing a mutual supertype should be as simple as creating some new infer var `?mutual_sup` and then requiring `lub_ty <: ?mutual_sup` and `new_ty <: ?mutual_sup`. In reality LUB coercions use a special [`TypeRelation`][type_relation], [`LatticeOp`][lattice_op]. + +This is primarily to work around subtyping/generalization for higher ranked types being fairly broken. Unlike normal subtyping, when encountering higher ranked types the lub type relation will switch to invariance. + +This enforces that the binders of the higher ranked types are equivalent which avoids the need to pick a "most general" binder, which would be quite difficult to do. + +It also avoids the process of computing a mutual supertype being *order dependent*. Given the types `a` and `b`, it may be nice if computing the mutual supertype of `a` and `b` would yield the same result as computing the mutual supertype of `b` and `a`. + +The current issues with higher ranked types and subtyping would cause this property to not hold if we were to use the naive method of computing a mutual supertype. + +Coercions being turned into explicit MIR operations during MIR building means that the process of computing the final type of a LUB coercion only occurs during HIR typeck. This also means the behaviour of computing a mutual supertype only matters for type inference, and is not soundness relevant. + +## Cautionary notes + +### Probes + +Care should be taken when coercing from inside of a probe as both one-to-one coercions and LUB coercions have side effects that can't be rolled back by a probe. + +LUB coercions will emit error when a coercion step fails, this makes it entirely suitable for use inside of probes. + +1-to-1 and LUB coercions will both apply *adjustments* to the coerced expressions on success. This means that if inside of a probe and an attempt to coerce succeeds, then the probe must not rollback anything. + +It's therefore correct to wrap a [`FnCtxt::coerce`][fnctxt_coerce] call inside of a [`commit_if_ok`][commit_if_ok], but would be wrong to do so if returning `Err` after the coerce call. It would also be wrong to call `FnCtxt::coerce` from within a [`probe`][probe]. + +[`CoerceMany`][coerce_many] should never be used from within a `probe` or `commit_if_ok`. + +### Never-to-Any coercions + +Coercing from the never type (`!`) to an inference variable will result in a [`NeverToAny`][never_to_any] coercion with a target type of the inference variable. This is subtly different from *unifying* the inference variable with the never type. + +Unifying some infer var `?x` with `!` requires that `?x` actually be *equal* to `!`. However, a `NeverToAny` coercion allows for `?x` to be inferred to any possible type. + +This distinction means that in cases where the initial lub ty of a coercion is an inference variable (e.g. there's no [`Expectation`][expectation] to use for the initial lub ty), it's still important to use a coercion instead of subtyping. + +See PR [#147834](https://github.com/rust-lang/rust/pull/147834) which fixes a bug where we were incorrectly inferring things to the never type instead of going through a coercion. + +### Fallback to subtyping + +Even though subtyping is not a coercion, both [`FnCtxt::coerce`][fnctxt_coerce] and [`CoerceMany::coerce`][coerce_many_coerce]/[`coerce_forced_unit`][coerce_many_coerce_forced_unit] are able to succeed due to subtyping. + +For one-to-one coercions we will try to enforce the source type is a subtype of the target type. For LUB coercions we will try to compute a type that is a supertype of all the existing types. + +For example performing a one-to-one coercion of `?x` to `u32` will fallback to subtyping, inferring `?x eq u32`. This means that when a coercion fails there's no need to attempt subtyping afterwards. + +### Unnecessary inference constraints + +Using types from [`Expectation`][expectation]s as the initial lub ty can cause infer vars to be constrained by the types of the expressions participating in the LUB coercion. This is not always desirable as these infer vars actually only need to be constrained by the final type of the LUB coercion. + +```rust +fn foo(_: T) {} + +fn a() {} +fn b() {} + +foo::(match my_bool { + true => a, + false => b, +}) +``` + +Here we have a LUB coercion with the first expression being of type `FnDef(a)` and the second expression being of type `FnDef(b)`. If we use `?x` as the initial lub ty of the LUB coercion then we would get the following behaviour: +- expression 1: infer `?x=FnDef(a)` +- expression 2: find a coercion lub between `FnDef(a), FnDef(b)` resulting in `fn() -> ()` +- the final type of the LUB coercion is `fn() -> ()`. equate `?x eq fn() -> ()`, where `?x` actually already has been inferred to `FnDef(a)`, so this is actually equating `FnDef(a) eq fn() -> ()` which does not hold + +To avoid some (but not all) of these undesirable inference constraints, if the `Expectation` for the LUB coercion is an inference variable then we won't use it as the initial lub ty. Instead we create a new infer var, for example in the above code snippet we would actually make some new infer var `?y` for the initial lub ty instead of using `?x`. +- expression 1: infer `?y=FnDef(a)` +- expression 2: find a coercion lub between `FnDef(a), FnDef(b)` resulting in `fn() -> ()` +- the final type of the LUB coercion is `fn() -> ()`, infer `?x=fn() -> ()` + +See [#140283](https://github.com/rust-lang/rust/pull/140283) for a case where we had undesirable inference constraints caused by not creating a new infer var. + +This doesn't avoid unnecessary constraints in *all* cases, only the most common case of having an infer var as our `Expectation`. In theory it would be desirable to avoid these constraints in all cases but it would be quite involved to do so. + +[coerce_many]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/coercion/struct.CoerceMany.html +[coerce_many_coerce]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/coercion/struct.CoerceMany.html#method.coerce +[coerce_many_coerce_forced_unit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/coercion/struct.CoerceMany.html#method.coerce_forced_unit +[coerce_many_complete]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/coercion/struct.CoerceMany.html#method.complete +[try_find_coercion_lub]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#method.try_find_coercion_lub +[expectation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/expectation/enum.Expectation.html +[unnecessary_inference_constraints]: #unnecessary-inference-constraints +[typeck_results]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html +[type_relation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/canonical/ir/relate/trait.TypeRelation.html +[lattice_op]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/relate/lattice/struct.LatticeOp.html +[fnctxt_coerce]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#method.coerce +[coerce_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/coercion/struct.Coerce.html +[commit_if_ok]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.commit_if_ok +[probe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.probe +[never_to_any]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/adjustment/enum.Adjust.html#variant.NeverToAny diff --git a/src/doc/rustc-dev-guide/src/method-lookup.md b/src/doc/rustc-dev-guide/src/hir-typeck/method-lookup.md similarity index 100% rename from src/doc/rustc-dev-guide/src/method-lookup.md rename to src/doc/rustc-dev-guide/src/hir-typeck/method-lookup.md diff --git a/src/doc/rustc-dev-guide/src/type-checking.md b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md similarity index 94% rename from src/doc/rustc-dev-guide/src/type-checking.md rename to src/doc/rustc-dev-guide/src/hir-typeck/summary.md index 4e8b30b19fc7..23df97a9cf83 100644 --- a/src/doc/rustc-dev-guide/src/type-checking.md +++ b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md @@ -1,4 +1,4 @@ -# Type checking +# HIR Type checking The [`hir_analysis`] crate contains the source for "type collection" as well as a bunch of related functionality. @@ -7,8 +7,8 @@ These crates draw heavily on the [type inference] and [trait solving]. [`hir_analysis`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/index.html [`hir_typeck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/index.html -[type inference]: ./type-inference.md -[trait solving]: ./traits/resolution.md +[type inference]: ./../type-inference.md +[trait solving]: ./../traits/resolution.md ## Type collection @@ -40,7 +40,7 @@ type *checking*). For more details, see the [`collect`][collect] module. -[queries]: ./query.md +[queries]: ../query.md [collect]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/collect/index.html **TODO**: actually talk about type checking... [#1161](https://github.com/rust-lang/rustc-dev-guide/issues/1161) diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md index f83b5b2e181c..23cc94d41846 100644 --- a/src/doc/rustc-dev-guide/src/overview.md +++ b/src/doc/rustc-dev-guide/src/overview.md @@ -130,7 +130,7 @@ with additional low-level types and annotations added (e.g. an ELF object or the final binary. [*trait solving*]: traits/resolution.md -[*type checking*]: type-checking.md +[*type checking*]: hir-typeck/summary.md [*type inference*]: type-inference.md [`bump`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.bump [`check`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.check diff --git a/src/doc/rustc-dev-guide/src/thir.md b/src/doc/rustc-dev-guide/src/thir.md index 3d3dafaef49b..d5f7d8b5fcb7 100644 --- a/src/doc/rustc-dev-guide/src/thir.md +++ b/src/doc/rustc-dev-guide/src/thir.md @@ -5,7 +5,7 @@ The THIR ("Typed High-Level Intermediate Representation"), previously called HAI [type checking]. It is (as of January 2024) used for [MIR construction], [exhaustiveness checking], and [unsafety checking]. -[type checking]: ./type-checking.md +[type checking]: ./hir-typeck/summary.md [MIR construction]: ./mir/construction.md [exhaustiveness checking]: ./pat-exhaustive-checking.md [unsafety checking]: ./unsafety-checking.md diff --git a/src/doc/rustc-dev-guide/src/traits/canonical-queries.md b/src/doc/rustc-dev-guide/src/traits/canonical-queries.md index 792858bd2af8..389f380e4b8d 100644 --- a/src/doc/rustc-dev-guide/src/traits/canonical-queries.md +++ b/src/doc/rustc-dev-guide/src/traits/canonical-queries.md @@ -214,7 +214,7 @@ As a result of this assignment, the type of `u` is forced to be `Option>`, where `?V` represents the element type of the vector. This in turn implies that `?U` is [unified] to `Vec`. -[unified]: ../type-checking.html +[unified]: ../hir-typeck/summary.md Let's suppose that the type checker decides to revisit the "as-yet-unproven" trait obligation we saw before, `Vec: From ee84ff9fe5f28de39792f1af195e17be34ca774c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Nov 2025 09:58:03 +0100 Subject: [PATCH 0171/3801] miri genmc: fix exit() handling --- .../rustc_const_eval/src/interpret/step.rs | 7 +- src/tools/miri/src/shims/foreign_items.rs | 2 +- src/tools/miri/tests/genmc/fail/shims/exit.rs | 9 ++ .../miri/tests/genmc/fail/shims/exit.stderr | 126 ++++++++++++++++++ 4 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 src/tools/miri/tests/genmc/fail/shims/exit.rs create mode 100644 src/tools/miri/tests/genmc/fail/shims/exit.stderr diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 88a116094758..9a4b9786eb15 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -561,8 +561,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if fn_abi.can_unwind { unwind } else { mir::UnwindAction::Unreachable }, )?; // Sanity-check that `eval_fn_call` either pushed a new frame or - // did a jump to another block. - if self.frame_idx() == old_stack && self.frame().loc == old_loc { + // did a jump to another block. We disable the sanity check for functions that + // can't return, since Miri sometimes does have to keep the location the same + // for those (which is fine since execution will continue on a different thread). + if target.is_some() && self.frame_idx() == old_stack && self.frame().loc == old_loc + { span_bug!(terminator.source_info.span, "evaluating this call made no progress"); } } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 440388673e7d..39b691bb97d7 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -538,7 +538,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { code, crate::concurrency::ExitType::ExitCalled, )?; - todo!(); // FIXME(genmc): Add a way to return here that is allowed to not do progress (can't use existing EmulateItemResult variants). + return interp_ok(EmulateItemResult::AlreadyJumped); } throw_machine_stop!(TerminationInfo::Exit { code, leak_check: false }); } diff --git a/src/tools/miri/tests/genmc/fail/shims/exit.rs b/src/tools/miri/tests/genmc/fail/shims/exit.rs new file mode 100644 index 000000000000..4138f4e785bb --- /dev/null +++ b/src/tools/miri/tests/genmc/fail/shims/exit.rs @@ -0,0 +1,9 @@ +//@ compile-flags: -Zmiri-genmc -Zmiri-disable-stacked-borrows + +fn main() { + std::thread::spawn(|| { + unsafe { std::hint::unreachable_unchecked() }; //~ERROR: entering unreachable code + }); + // If we exit immediately, we might entirely miss the UB in the other thread. + std::process::exit(0); +} diff --git a/src/tools/miri/tests/genmc/fail/shims/exit.stderr b/src/tools/miri/tests/genmc/fail/shims/exit.stderr new file mode 100644 index 000000000000..dead5faaa514 --- /dev/null +++ b/src/tools/miri/tests/genmc/fail/shims/exit.stderr @@ -0,0 +1,126 @@ +Running GenMC Verification... +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/thread/mod.rs:LL:CC + | +LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside `std::thread::ThreadId::new` at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC + = note: inside `std::thread::current::id::get_or_init` at RUSTLIB/std/src/thread/current.rs:LL:CC + = note: inside `std::thread::current_id` at RUSTLIB/std/src/thread/current.rs:LL:CC + = note: inside `std::rt::init` at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC + = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC + +warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. + --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC + | +LL | || self + | ________________^ +LL | | .state +LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) + | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC + = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC + = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC + = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC + = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> tests/genmc/fail/shims/exit.rs:LL:CC + | +LL | / std::thread::spawn(|| { +LL | | unsafe { std::hint::unreachable_unchecked() }; +LL | | }); + | |______^ + +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC + | +LL | || self + | ________________^ +LL | | .state +LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) + | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC + = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC + = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC + = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC + = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> tests/genmc/fail/shims/exit.rs:LL:CC + | +LL | / std::thread::spawn(|| { +LL | | unsafe { std::hint::unreachable_unchecked() }; +LL | | }); + | |______^ + +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> RUSTLIB/std/src/rt.rs:LL:CC + | +LL | / CLEANUP.call_once(|| unsafe { +LL | | // Flush stdout and disable buffering. +LL | | crate::io::cleanup(); +... | +LL | | }); + | |______^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside `std::rt::cleanup` at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside `std::process::exit` at RUSTLIB/std/src/process.rs:LL:CC +note: inside `main` + --> tests/genmc/fail/shims/exit.rs:LL:CC + | +LL | std::process::exit(0); + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. + --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC + | +LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + | + = note: BACKTRACE: + = note: inside `std::sys::exit_guard::unique_thread_exit` at RUSTLIB/std/src/sys/exit_guard.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::os::exit` at RUSTLIB/std/src/sys/pal/PLATFORM/os.rs:LL:CC + = note: inside `std::process::exit` at RUSTLIB/std/src/process.rs:LL:CC +note: inside `main` + --> tests/genmc/fail/shims/exit.rs:LL:CC + | +LL | std::process::exit(0); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: Undefined Behavior: entering unreachable code + --> tests/genmc/fail/shims/exit.rs:LL:CC + | +LL | unsafe { std::hint::unreachable_unchecked() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report + +error: aborting due to 1 previous error; 5 warnings emitted + From 783780c25312d0eb78511e33fa572a5c3feb8dfd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Nov 2025 09:57:33 +0100 Subject: [PATCH 0172/3801] miri tests can always rely on CARGO_BIN_EXE_miri --- src/bootstrap/src/core/build_steps/test.rs | 1 - src/tools/miri/tests/ui.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index d888e63275cd..fbdf0adc76ac 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -679,7 +679,6 @@ impl Step for Miri { // miri tests need to know about the stage sysroot cargo.env("MIRI_SYSROOT", &miri_sysroot); cargo.env("MIRI_HOST_SYSROOT", &host_sysroot); - cargo.env("MIRI", &miri.tool_path); // Set the target. cargo.env("MIRI_TEST_TARGET", target.rustc_target_arg()); diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index 1f8d98a4d339..b7f428ff01e0 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -27,7 +27,7 @@ enum Mode { } fn miri_path() -> PathBuf { - PathBuf::from(env::var("MIRI").unwrap_or_else(|_| env!("CARGO_BIN_EXE_miri").into())) + env!("CARGO_BIN_EXE_miri").into() } // Build the shared object file for testing native function calls. From c3c14018cf98d2944b206716b8184e2caa9a59ac Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 29 Nov 2025 19:41:44 +0200 Subject: [PATCH 0173/3801] do not mess with a &[u8; 2] --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index b74dbbe56bfe..7ace34aed984 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -27,7 +27,7 @@ static REGEX_IGNORE_END: LazyLock = static REGEX_IGNORE_LINK_TARGETS: LazyLock = LazyLock::new(|| Regex::new(r"^\[.+\]: ").unwrap()); static REGEX_SPLIT: LazyLock = - LazyLock::new(|| Regex::new(r"([^\.\d\-\*]\.|[^r]\?|;|!)\s").unwrap()); + LazyLock::new(|| Regex::new(r"([^\.\d\-\*]\.|[^r]\?|!)\s").unwrap()); // list elements, numbered (1.) or not (- and *) static REGEX_LIST_ENTRY: LazyLock = LazyLock::new(|| Regex::new(r"^\s*(\d\.|\-|\*)\s+").unwrap()); @@ -196,7 +196,7 @@ fn lengthen_lines(content: &str, limit: usize) -> String { fn test_sembr() { let original = " # some. heading -must! be; split? +must! be. split? 1. ignore a dot after number. but no further ignore | tables ignore e.g. and @@ -214,7 +214,7 @@ git log main.. compiler let expected = " # some. heading must! -be; +be. split? 1. ignore a dot after number. but no further From e26128a3c71a553e2c00e58253a48ab95dbb4dc8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 29 Nov 2025 19:42:53 +0200 Subject: [PATCH 0174/3801] sembr tests/crater.md --- src/doc/rustc-dev-guide/src/tests/crater.md | 41 +++++++++++---------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/crater.md b/src/doc/rustc-dev-guide/src/tests/crater.md index 96bb5a4f2ae6..df7e8ef0b7ed 100644 --- a/src/doc/rustc-dev-guide/src/tests/crater.md +++ b/src/doc/rustc-dev-guide/src/tests/crater.md @@ -1,43 +1,46 @@ # Crater [Crater](https://github.com/rust-lang/crater) is a tool for compiling and -running tests for _every_ crate on [crates.io](https://crates.io) (and a few on -GitHub). It is mainly used for checking the extent of breakage when implementing +running tests for _every_ crate on [crates.io](https://crates.io) (and a few on GitHub). +It is mainly used for checking the extent of breakage when implementing potentially breaking changes and ensuring lack of breakage by running beta vs stable compiler versions. ## When to run Crater You should request a Crater run if your PR makes large changes to the compiler -or could cause breakage. If you are unsure, feel free to ask your PR's reviewer. +or could cause breakage. +If you are unsure, feel free to ask your PR's reviewer. ## Requesting Crater Runs The Rust team maintains a few machines that can be used for Crater runs -on the changes introduced by a PR. If your PR needs a Crater run, leave a -comment for the triage team in the PR thread. Please inform the team whether you -require a "check-only" Crater run, a "build only" Crater run, or a -"build-and-test" Crater run. The difference is primarily in time; -if you're not sure, go for the build-and-test run. If +on the changes introduced by a PR. +If your PR needs a Crater run, leave a comment for the triage team in the PR thread. +Please inform the team whether you +require a "check-only" Crater run, a "build only" Crater run, or a "build-and-test" Crater run. +The difference is primarily in time; +if you're not sure, go for the build-and-test run. +If making changes that will only have an effect at compile-time (e.g., implementing a new trait), then you only need a check run. -Your PR will be enqueued by the triage team and the results will be posted when -they are ready. Check runs will take around ~3-4 days, and the other two taking -5-6 days on average. +Your PR will be enqueued by the triage team and the results will be posted when they are ready. +Check runs will take around ~3-4 days, and the other two taking 5-6 days on average. -While Crater is really useful, it is also important to be aware of a few -caveats: +While Crater is really useful, it is also important to be aware of a few caveats: -- Not all code is on crates.io! There is a lot of code in repos on GitHub and - elsewhere. Also, companies may not wish to publish their code. Thus, a - successful Crater run does not mean there will be no +- Not all code is on crates.io! + There is a lot of code in repos on GitHub and elsewhere. + Also, companies may not wish to publish their code. + Thus, a successful Crater run does not mean there will be no breakage; you still need to be careful. -- Crater only runs Linux builds on x86_64. Thus, other architectures and - platforms are not tested. Critically, this includes Windows. +- Crater only runs Linux builds on x86_64. Thus, other architectures and platforms are not tested. + Critically, this includes Windows. -- Many crates are not tested. This could be for a lot of reasons, including that +- Many crates are not tested. + This could be for a lot of reasons, including that the crate doesn't compile any more (e.g. used old nightly features), has broken or flaky tests, requires network access, or other reasons. From c58288a411123f898a61b1b1e7d90b6fa040bbaa Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 29 Nov 2025 20:00:25 +0200 Subject: [PATCH 0175/3801] manual formatting improvement --- src/doc/rustc-dev-guide/src/tests/crater.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/crater.md b/src/doc/rustc-dev-guide/src/tests/crater.md index df7e8ef0b7ed..beea10aab770 100644 --- a/src/doc/rustc-dev-guide/src/tests/crater.md +++ b/src/doc/rustc-dev-guide/src/tests/crater.md @@ -21,9 +21,8 @@ Please inform the team whether you require a "check-only" Crater run, a "build only" Crater run, or a "build-and-test" Crater run. The difference is primarily in time; if you're not sure, go for the build-and-test run. -If -making changes that will only have an effect at compile-time (e.g., implementing -a new trait), then you only need a check run. +If making changes that will only have an effect at compile-time +(e.g., implementing a new trait), then you only need a check run. Your PR will be enqueued by the triage team and the results will be posted when they are ready. Check runs will take around ~3-4 days, and the other two taking 5-6 days on average. From bbadb72919e510c3a98cbe303cac2f58e0c5d065 Mon Sep 17 00:00:00 2001 From: Sergio Giro Date: Sat, 29 Nov 2025 18:40:32 +0000 Subject: [PATCH 0176/3801] while_let_on_iterator: consider all deref adjustments for by_ref --- .../src/loops/while_let_on_iterator.rs | 30 ++++---- tests/ui/while_let_on_iterator.fixed | 73 +++++++++++++++++++ tests/ui/while_let_on_iterator.rs | 73 +++++++++++++++++++ tests/ui/while_let_on_iterator.stderr | 22 +++++- 4 files changed, 182 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs index c063e9263ba0..6c95c7b54c50 100644 --- a/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/clippy_lints/src/loops/while_let_on_iterator.rs @@ -12,7 +12,6 @@ use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_hir::{Closure, Expr, ExprKind, HirId, LetStmt, Mutability, UnOp}; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter::OnlyBodies; -use rustc_middle::ty; use rustc_middle::ty::adjustment::Adjust; use rustc_span::Symbol; use rustc_span::symbol::sym; @@ -52,9 +51,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { || !iter_expr_struct.fields.is_empty() || needs_mutable_borrow(cx, &iter_expr_struct, expr) { - make_iterator_snippet(cx, iter_expr, iterator) + make_iterator_snippet(cx, iter_expr, &iterator) } else { - iterator.to_string() + iterator.into_owned() }; span_lint_and_sugg( @@ -358,17 +357,20 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: & } /// Constructs the transformed iterator expression for the suggestion. -/// Returns `iterator.by_ref()` unless the iterator type is a reference to an unsized type, -/// in which case it returns `&mut *iterator`. -fn make_iterator_snippet<'tcx>(cx: &LateContext<'tcx>, iter_expr: &Expr<'tcx>, iterator: impl Into) -> String { - let iterator = iterator.into(); - let ty = cx.typeck_results().expr_ty(iter_expr); - - if let ty::Ref(_, inner_ty, _) = ty.kind() - && !inner_ty.is_sized(cx.tcx, cx.typing_env()) +/// Returns `iterator.by_ref()` unless the last deref adjustment targets an unsized type, +/// in which case it applies all derefs (e.g., `&mut **iterator` or `&mut ***iterator`). +fn make_iterator_snippet<'tcx>(cx: &LateContext<'tcx>, iter_expr: &Expr<'tcx>, iterator: &str) -> String { + if let Some((n, adjust)) = cx + .typeck_results() + .expr_adjustments(iter_expr) + .iter() + .take_while(|x| matches!(x.kind, Adjust::Deref(_))) + .enumerate() + .last() + && !adjust.target.is_sized(cx.tcx, cx.typing_env()) { - return format!("&mut *{iterator}"); + format!("&mut {:*(T); + impl core::ops::Deref for S { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for S { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + fn f(mut x: S>>) { + for _ in &mut ***x {} + //~^ while_let_on_iterator + } +} + +fn issue16089_nested_derefs_last_not_sized() { + struct WithSize(T); + impl core::ops::Deref for WithSize { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for WithSize { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + // The suggestion must use `&mut **x`. Using `x.by_ref()` doesn't work in this + // case, since the last type adjustment for `x` in the expression `x.next()` is + // to dereference a `?Sized` trait. + fn f(mut x: WithSize<&mut dyn Iterator>) { + for _ in &mut **x {} + //~^ while_let_on_iterator + } +} + +fn issue16089_nested_derefs_last_sized() { + struct NoSize(T); + impl core::ops::Deref for NoSize { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for NoSize { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + struct SizedIter {} + + impl Iterator for SizedIter { + type Item = u32; + fn next(&mut self) -> Option { + Some(0) + } + } + + // We want the suggestion to be `x.by_ref()`. It works in this case since the last type + // adjustment for `x` in the expression `x.next()` is to dereference a Sized type. + fn f(mut x: NoSize>) { + for _ in x.by_ref() {} + //~^ while_let_on_iterator + } +} + fn main() { let mut it = 0..20; for _ in it { diff --git a/tests/ui/while_let_on_iterator.rs b/tests/ui/while_let_on_iterator.rs index cc65fda6d18f..e1d9e9081e45 100644 --- a/tests/ui/while_let_on_iterator.rs +++ b/tests/ui/while_let_on_iterator.rs @@ -523,6 +523,79 @@ fn issue16089_sized_trait_not_reborrowed() { } } +fn issue16089_nested_derefs() { + struct S(T); + impl core::ops::Deref for S { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for S { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + fn f(mut x: S>>) { + while let Some(_) = x.next() {} + //~^ while_let_on_iterator + } +} + +fn issue16089_nested_derefs_last_not_sized() { + struct WithSize(T); + impl core::ops::Deref for WithSize { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for WithSize { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + // The suggestion must use `&mut **x`. Using `x.by_ref()` doesn't work in this + // case, since the last type adjustment for `x` in the expression `x.next()` is + // to dereference a `?Sized` trait. + fn f(mut x: WithSize<&mut dyn Iterator>) { + while let Some(_) = x.next() {} + //~^ while_let_on_iterator + } +} + +fn issue16089_nested_derefs_last_sized() { + struct NoSize(T); + impl core::ops::Deref for NoSize { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for NoSize { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + struct SizedIter {} + + impl Iterator for SizedIter { + type Item = u32; + fn next(&mut self) -> Option { + Some(0) + } + } + + // We want the suggestion to be `x.by_ref()`. It works in this case since the last type + // adjustment for `x` in the expression `x.next()` is to dereference a Sized type. + fn f(mut x: NoSize>) { + while let Some(_) = x.next() {} + //~^ while_let_on_iterator + } +} + fn main() { let mut it = 0..20; while let Some(..) = it.next() { diff --git a/tests/ui/while_let_on_iterator.stderr b/tests/ui/while_let_on_iterator.stderr index 21ebc22f699d..cd43d3c17800 100644 --- a/tests/ui/while_let_on_iterator.stderr +++ b/tests/ui/while_let_on_iterator.stderr @@ -176,10 +176,28 @@ LL | while let Some(r) = self.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for r in self.by_ref()` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:528:5 + --> tests/ui/while_let_on_iterator.rs:541:9 + | +LL | while let Some(_) = x.next() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in &mut ***x` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:563:9 + | +LL | while let Some(_) = x.next() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in &mut **x` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:594:9 + | +LL | while let Some(_) = x.next() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in x.by_ref()` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:601:5 | LL | while let Some(..) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it` -error: aborting due to 30 previous errors +error: aborting due to 33 previous errors From 9cb6306a48f02d96ee839398e85b17e181fa3844 Mon Sep 17 00:00:00 2001 From: Artur Sulej Date: Sun, 23 Nov 2025 22:51:03 +0100 Subject: [PATCH 0177/3801] New lint: decimal_bitwise_operands --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + .../src/operators/decimal_bitwise_operands.rs | 76 +++++++ clippy_lints/src/operators/mod.rs | 28 +++ tests/ui/decimal_bitwise_operands.rs | 133 ++++++++++++ tests/ui/decimal_bitwise_operands.stderr | 204 ++++++++++++++++++ 6 files changed, 443 insertions(+) create mode 100644 clippy_lints/src/operators/decimal_bitwise_operands.rs create mode 100644 tests/ui/decimal_bitwise_operands.rs create mode 100644 tests/ui/decimal_bitwise_operands.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 78b81b5b74d6..dc93753a2130 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6280,6 +6280,7 @@ Released 2018-09-13 [`cyclomatic_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#cyclomatic_complexity [`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro [`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call +[`decimal_bitwise_operands`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_bitwise_operands [`decimal_literal_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation [`declare_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const [`default_constructed_unit_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 4a350dca2993..de7d01ce0d1b 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -578,6 +578,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::operators::ASSIGN_OP_PATTERN_INFO, crate::operators::BAD_BIT_MASK_INFO, crate::operators::CMP_OWNED_INFO, + crate::operators::DECIMAL_BITWISE_OPERANDS_INFO, crate::operators::DOUBLE_COMPARISONS_INFO, crate::operators::DURATION_SUBSEC_INFO, crate::operators::EQ_OP_INFO, diff --git a/clippy_lints/src/operators/decimal_bitwise_operands.rs b/clippy_lints/src/operators/decimal_bitwise_operands.rs new file mode 100644 index 000000000000..8511f2151342 --- /dev/null +++ b/clippy_lints/src/operators/decimal_bitwise_operands.rs @@ -0,0 +1,76 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::numeric_literal; +use clippy_utils::numeric_literal::NumericLiteral; +use clippy_utils::source::SpanRangeExt; +use rustc_ast::LitKind; +use rustc_data_structures::packed::Pu128; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_span::Span; + +use super::DECIMAL_BITWISE_OPERANDS; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, op: BinOpKind, left: &'tcx Expr<'_>, right: &'tcx Expr<'_>) { + if !matches!(op, BinOpKind::BitAnd | BinOpKind::BitOr | BinOpKind::BitXor) { + return; + } + + for expr in [left, right] { + check_expr(cx, expr); + } +} + +fn check_expr(cx: &LateContext<'_>, expr: &Expr<'_>) { + match &expr.kind { + ExprKind::Block(block, _) => { + if let Some(block_expr) = block.expr { + check_expr(cx, block_expr); + } + }, + ExprKind::Cast(cast_expr, _) => { + check_expr(cx, cast_expr); + }, + ExprKind::Unary(_, unary_expr) => { + check_expr(cx, unary_expr); + }, + ExprKind::AddrOf(_, _, addr_of_expr) => { + check_expr(cx, addr_of_expr); + }, + ExprKind::Lit(lit) => { + if let LitKind::Int(Pu128(val), _) = lit.node + && !is_single_digit(val) + && !is_power_of_twoish(val) + && let Some(src) = lit.span.get_source_text(cx) + && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node) + && num_lit.is_decimal() + { + emit_lint(cx, lit.span, num_lit.suffix, val); + } + }, + _ => (), + } +} + +fn is_power_of_twoish(val: u128) -> bool { + val.is_power_of_two() || val.wrapping_add(1).is_power_of_two() +} + +fn is_single_digit(val: u128) -> bool { + val <= 9 +} + +fn emit_lint(cx: &LateContext<'_>, span: Span, suffix: Option<&str>, val: u128) { + span_lint_and_help( + cx, + DECIMAL_BITWISE_OPERANDS, + span, + "using decimal literal for bitwise operation", + None, + format!( + "use binary ({}), hex ({}), or octal ({}) notation for better readability", + numeric_literal::format(&format!("{val:#b}"), suffix, false), + numeric_literal::format(&format!("{val:#x}"), suffix, false), + numeric_literal::format(&format!("{val:#o}"), suffix, false), + ), + ); +} diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 8db2cc1d3f57..53b8e9e5d5ae 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -3,6 +3,7 @@ mod assign_op_pattern; mod bit_mask; mod cmp_owned; mod const_comparisons; +mod decimal_bitwise_operands; mod double_comparison; mod duration_subsec; mod eq_op; @@ -935,6 +936,28 @@ declare_clippy_lint! { "use of disallowed default division and remainder operations" } +declare_clippy_lint! { + /// ### What it does + /// Checks for decimal literals used as bit masks in bitwise operations. + /// + /// ### Why is this bad? + /// Using decimal literals for bit masks can make the code less readable and obscure the intended bit pattern. + /// Binary, hexadecimal, or octal literals make the bit pattern more explicit and easier to understand at a glance. + /// + /// ### Example + /// ```rust,no_run + /// let a = 14 & 6; // Bit pattern is not immediately clear + /// ``` + /// Use instead: + /// ```rust,no_run + /// let a = 0b1110 & 0b0110; + /// ``` + #[clippy::version = "1.93.0"] + pub DECIMAL_BITWISE_OPERANDS, + pedantic, + "use binary, hex, or octal literals for bitwise operations" +} + pub struct Operators { arithmetic_context: numeric_arithmetic::Context, verbose_bit_mask_threshold: u64, @@ -984,6 +1007,7 @@ impl_lint_pass!(Operators => [ MANUAL_IS_MULTIPLE_OF, MANUAL_DIV_CEIL, INVALID_UPCAST_COMPARISONS, + DECIMAL_BITWISE_OPERANDS ]); impl<'tcx> LateLintPass<'tcx> for Operators { @@ -1003,6 +1027,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators { needless_bitwise_bool::check(cx, e, op.node, lhs, rhs); manual_midpoint::check(cx, e, op.node, lhs, rhs, self.msrv); manual_is_multiple_of::check(cx, e, op.node, lhs, rhs, self.msrv); + decimal_bitwise_operands::check(cx, op.node, lhs, rhs); } self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs); bit_mask::check(cx, e, op.node, lhs, rhs); @@ -1028,6 +1053,9 @@ impl<'tcx> LateLintPass<'tcx> for Operators { }, ExprKind::AssignOp(op, lhs, rhs) => { let bin_op = op.node.into(); + if !e.span.from_expansion() { + decimal_bitwise_operands::check(cx, bin_op, lhs, rhs); + } self.arithmetic_context.check_binary(cx, e, bin_op, lhs, rhs); misrefactored_assign_op::check(cx, e, bin_op, lhs, rhs); modulo_arithmetic::check(cx, e, bin_op, lhs, rhs, false); diff --git a/tests/ui/decimal_bitwise_operands.rs b/tests/ui/decimal_bitwise_operands.rs new file mode 100644 index 000000000000..f1c053bb4358 --- /dev/null +++ b/tests/ui/decimal_bitwise_operands.rs @@ -0,0 +1,133 @@ +#![allow( + clippy::erasing_op, + clippy::no_effect, + clippy::unnecessary_operation, + clippy::unnecessary_cast, + clippy::op_ref +)] +#![warn(clippy::decimal_bitwise_operands)] + +macro_rules! bitwise_op { + ($x:expr, $y:expr) => { + $x & $y; + }; +} + +pub const SOME_CONST: i32 = 12345; + +fn main() { + let mut x = 0; + // BAD: Bitwise operation, decimal literal, one literal + x & 9_8765_4321; //~ decimal_bitwise_operands + x & 100_i32; //~ decimal_bitwise_operands + x | (/* comment */99); //~ decimal_bitwise_operands + x ^ (99); //~ decimal_bitwise_operands + x &= 99; //~ decimal_bitwise_operands + x |= { 99 }; //~ decimal_bitwise_operands + x |= { { 99 } }; //~ decimal_bitwise_operands + x |= { + 0b1000; + 99 //~ decimal_bitwise_operands + }; + x ^= (99); //~ decimal_bitwise_operands + + // BAD: Bitwise operation, decimal literal, two literals + 0b1010 & 99; //~ decimal_bitwise_operands + 0b1010 | (99); //~ decimal_bitwise_operands + 0b1010 ^ (/* comment */99); //~ decimal_bitwise_operands + 99 & 0b1010; //~ decimal_bitwise_operands + (99) | 0b1010; //~ decimal_bitwise_operands + (/* comment */99) ^ 0b1010; //~ decimal_bitwise_operands + 0xD | { 99 }; //~ decimal_bitwise_operands + 88 & 99; + //~^ decimal_bitwise_operands + //~| decimal_bitwise_operands + 37 & 38 & 39; + //~^ decimal_bitwise_operands + //~| decimal_bitwise_operands + //~| decimal_bitwise_operands + + // GOOD: Bitwise operation, binary/hex/octal literal, one literal + x & 0b1010; + x | 0b1010; + x ^ 0b1010; + x &= 0b1010; + x |= 0b1010; + x ^= 0b1010; + x & 0xD; + x & 0o77; + x | 0o123; + x ^ 0o377; + x &= 0o777; + x |= 0o7; + x ^= 0o70; + + // GOOD: Bitwise operation, binary/hex/octal literal, two literals + 0b1010 & 0b1101; + 0xD ^ 0xF; + 0o377 ^ 0o77; + 0b1101 ^ 0xFF; + + // GOOD: Numeric operation, any literal + x += 99; + x -= 0b1010; + x *= 0xD; + 99 + 99; + 0b1010 - 0b1101; + 0xD * 0xD; + + // BAD: Unary, cast and reference, decimal literal + x & !100; //~ decimal_bitwise_operands + x & -100; //~ decimal_bitwise_operands + x & (100 as i32); //~ decimal_bitwise_operands + x & &100; //~ decimal_bitwise_operands + + // GOOD: Unary, cast and reference, non-decimal literal + x & !0b1101; + x & -0xD; + x & (0o333 as i32); + x & &0b1010; + + // GOOD: Bitwise operation, variables only + let y = 0; + x & y; + x &= y; + x + y; + x += y; + + // GOOD: Macro expansion (should be ignored) + bitwise_op!(x, 123); + bitwise_op!(0b1010, 123); + + // GOOD: Using const (should be ignored) + x & SOME_CONST; + x |= SOME_CONST; + + // GOOD: Parenthesized binary/hex literal (should not trigger lint) + x & (0b1111); + x |= (0b1010); + x ^ (/* comment */0b1100); + (0xFF) & x; + + // GOOD: Power of two and power of two minus one + x & 16; // 2^4 + x | (31); // 2^5 - 1 + x ^ 0x40; // 2^6 (hex) + x ^= 7; // 2^3 - 1 + + // GOOD: Bitwise operation, single digit decimal literal + 5 & 9; + x ^ 6; + x ^= 7; + + // GOOD: More complex expressions + (x + 1) & 0xFF; + (x * 2) | (y & 0xF); + (x ^ y) & 0b11110000; + x | (1 << 9); + + // GOOD: Special cases + x & 0; // All bits off + x | !0; // All bits on + x ^ 1; // Toggle LSB +} diff --git a/tests/ui/decimal_bitwise_operands.stderr b/tests/ui/decimal_bitwise_operands.stderr new file mode 100644 index 000000000000..1b2b7bb71b69 --- /dev/null +++ b/tests/ui/decimal_bitwise_operands.stderr @@ -0,0 +1,204 @@ +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:21:9 + | +LL | x & 9_8765_4321; + | ^^^^^^^^^^^ + | + = help: use binary (0b11_1010_1101_1110_0110_1000_1011_0001), hex (0x3ade_68b1), or octal (0o7_267_464_261) notation for better readability + = note: `-D clippy::decimal-bitwise-operands` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::decimal_bitwise_operands)]` + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:22:9 + | +LL | x & 100_i32; + | ^^^^^^^ + | + = help: use binary (0b110_0100_i32), hex (0x0064_i32), or octal (0o144_i32) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:23:23 + | +LL | x | (/* comment */99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:24:10 + | +LL | x ^ (99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:25:10 + | +LL | x &= 99; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:26:12 + | +LL | x |= { 99 }; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:27:14 + | +LL | x |= { { 99 } }; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:30:9 + | +LL | 99 + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:32:11 + | +LL | x ^= (99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:35:14 + | +LL | 0b1010 & 99; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:36:15 + | +LL | 0b1010 | (99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:37:28 + | +LL | 0b1010 ^ (/* comment */99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:38:5 + | +LL | 99 & 0b1010; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:39:6 + | +LL | (99) | 0b1010; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:40:19 + | +LL | (/* comment */99) ^ 0b1010; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:41:13 + | +LL | 0xD | { 99 }; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:42:5 + | +LL | 88 & 99; + | ^^ + | + = help: use binary (0b101_1000), hex (0x0058), or octal (0o130) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:42:10 + | +LL | 88 & 99; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:45:15 + | +LL | 37 & 38 & 39; + | ^^ + | + = help: use binary (0b10_0111), hex (0x0027), or octal (0o47) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:45:5 + | +LL | 37 & 38 & 39; + | ^^ + | + = help: use binary (0b10_0101), hex (0x0025), or octal (0o45) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:45:10 + | +LL | 37 & 38 & 39; + | ^^ + | + = help: use binary (0b10_0110), hex (0x0026), or octal (0o46) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:80:10 + | +LL | x & !100; + | ^^^ + | + = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:81:10 + | +LL | x & -100; + | ^^^ + | + = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:82:10 + | +LL | x & (100 as i32); + | ^^^ + | + = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:83:10 + | +LL | x & &100; + | ^^^ + | + = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability + +error: aborting due to 25 previous errors + From 00ee70d216dcc15e527d1d2384c8a0b4e2f1b0b8 Mon Sep 17 00:00:00 2001 From: sayantn Date: Sat, 29 Nov 2025 09:20:03 +0530 Subject: [PATCH 0178/3801] systematically exclude svml, mmx and mpx rather than having an ad-hoc list --- .../crates/intrinsic-test/missing_x86.txt | 873 +----------------- .../src/common/intrinsic_helpers.rs | 2 +- .../crates/intrinsic-test/src/x86/compile.rs | 12 + .../crates/intrinsic-test/src/x86/config.rs | 6 - .../crates/intrinsic-test/src/x86/types.rs | 6 - .../intrinsic-test/src/x86/xml_parser.rs | 14 +- 6 files changed, 49 insertions(+), 864 deletions(-) diff --git a/library/stdarch/crates/intrinsic-test/missing_x86.txt b/library/stdarch/crates/intrinsic-test/missing_x86.txt index 58e37b92a1db..11c3eeba9063 100644 --- a/library/stdarch/crates/intrinsic-test/missing_x86.txt +++ b/library/stdarch/crates/intrinsic-test/missing_x86.txt @@ -3,17 +3,9 @@ #__bswap_64 _bswap64 -# Provides pointer to allocated memory, which is difficult to test -_mm_malloc - -# requires target feature 'waitpkg', but would be inlined into function that is compiled without support for 'waitpkg' -_tpause -_umwait - -# `use of undeclared identifier` error in Clang +# not present in Clang and Rust _bit_scan_forward _bit_scan_reverse -_bswap _castf32_u32 _castf64_u64 _castu32_f32 @@ -22,569 +14,6 @@ _lrotl _lrotr _may_i_use_cpu_feature _may_i_use_cpu_feature_ext -_mm256_acos_pd -_mm256_acos_ph -_mm256_acos_ps -_mm256_acosh_pd -_mm256_acosh_ph -_mm256_acosh_ps -_mm256_asin_pd -_mm256_asin_ph -_mm256_asin_ps -_mm256_asinh_pd -_mm256_asinh_ph -_mm256_asinh_ps -_mm256_atan_pd -_mm256_atan_ps -_mm256_atan_ph -_mm256_atan2_pd -_mm256_atan2_ph -_mm256_atan2_ps -_mm256_atanh_pd -_mm256_atanh_ph -_mm256_atanh_ps -_mm256_cbrt_pd -_mm256_cbrt_ph -_mm256_cbrt_ps -_mm256_cdfnorm_pd -_mm256_cdfnorm_ph -_mm256_cdfnorm_ps -_mm256_cdfnorminv_pd -_mm256_cdfnorminv_ph -_mm256_cdfnorminv_ps -_mm256_cexp_ps -_mm256_cos_pd -_mm256_cos_ph -_mm256_cos_ps -_mm256_cosd_pd -_mm256_cosd_ph -_mm256_cosd_ps -_mm256_cosh_pd -_mm256_cosh_ph -_mm256_cosh_ps -_mm256_csqrt_ps -_mm256_div_epi16 -_mm256_div_epi32 -_mm256_div_epi64 -_mm256_div_epi8 -_mm256_div_epu16 -_mm256_div_epu32 -_mm256_div_epu64 -_mm256_div_epu8 -_mm256_dpbssd_epi32 -_mm256_dpbssds_epi32 -_mm256_dpbsud_epi32 -_mm256_dpbsuds_epi32 -_mm256_dpbuud_epi32 -_mm256_dpbuuds_epi32 -_mm256_dpwsud_epi32 -_mm256_dpwsuds_epi32 -_mm256_dpwusd_epi32 -_mm256_dpwusds_epi32 -_mm256_dpwuud_epi32 -_mm256_dpwuuds_epi32 -_mm256_erf_pd -_mm256_erf_ps -_mm256_erfc_pd -_mm256_erfc_ph -_mm256_erfc_ps -_mm256_erfcinv_pd -_mm256_erfcinv_ph -_mm256_erfcinv_ps -_mm256_erfinv_pd -_mm256_erfinv_ph -_mm256_erfinv_ps -_mm256_exp10_pd -_mm256_exp10_ph -_mm256_exp10_ps -_mm256_exp2_pd -_mm256_exp2_ph -_mm256_exp2_ps -_mm256_exp_pd -_mm256_exp_ph -_mm256_exp_ps -_mm256_expm1_pd -_mm256_expm1_ph -_mm256_expm1_ps -_mm256_hypot_pd -_mm256_hypot_ph -_mm256_hypot_ps -_mm256_idiv_epi32 -_mm256_invcbrt_pd -_mm256_invcbrt_ph -_mm256_invcbrt_ps -_mm256_invsqrt_pd -_mm256_invsqrt_ph -_mm256_invsqrt_ps -_mm256_irem_epi32 -_mm256_log10_pd -_mm256_log10_ph -_mm256_log10_ps -_mm256_log1p_pd -_mm256_log1p_ph -_mm256_log1p_ps -_mm256_log2_pd -_mm256_log2_ph -_mm256_log2_ps -_mm256_log_pd -_mm256_log_ph -_mm256_log_ps -_mm256_logb_pd -_mm256_logb_ph -_mm256_logb_ps -_mm256_clog_ps -_mm256_madd52hi_avx_epu64 -_mm256_madd52lo_avx_epu64 -_mm256_erf_ph -_mm256_mask_reduce_add_epi16 -_mm256_mask_reduce_add_epi8 -_mm256_mask_reduce_and_epi16 -_mm256_mask_reduce_and_epi8 -_mm256_mask_reduce_max_epi16 -_mm256_mask_reduce_max_epi8 -_mm256_mask_reduce_max_epu16 -_mm256_mask_reduce_max_epu8 -_mm256_mask_reduce_min_epi16 -_mm256_mask_reduce_min_epi8 -_mm256_mask_reduce_min_epu16 -_mm256_mask_reduce_min_epu8 -_mm256_mask_reduce_mul_epi16 -_mm256_mask_reduce_mul_epi8 -_mm256_mask_reduce_or_epi16 -_mm256_mask_reduce_or_epi8 -_mm512_cosd_ph -_mm512_cosd_ps -_mm512_cosh_pd -_mm512_cosh_ph -_mm512_cosh_ps -_mm512_div_epi16 -_mm512_div_epi32 -_mm512_div_epi64 -_mm512_div_epi8 -_mm512_div_epu16 -_mm512_div_epu32 -_mm512_div_epu64 -_mm512_div_epu8 -_mm512_erf_pd -_mm512_erf_ph -_mm512_erf_ps -_mm512_erfc_pd -_mm512_erfc_ph -_mm512_erfc_ps -_mm512_erfcinv_pd -_mm512_erfcinv_ph -_mm512_erfcinv_ps -_mm512_erfinv_pd -_mm512_erfinv_ph -_mm512_erfinv_ps -_mm512_exp10_pd -_mm512_exp10_ph -_mm512_exp10_ps -_mm512_exp2_pd -_mm512_exp2_ph -_mm512_exp2_ps -_mm512_exp_pd -_mm512_exp_ph -_mm512_exp_ps -_mm512_expm1_pd -_mm512_expm1_ph -_mm512_expm1_ps -_mm512_floor_ph -_mm512_hypot_pd -_mm512_hypot_ph -_mm512_hypot_ps -_mm512_invsqrt_pd -_mm512_invsqrt_ph -_mm512_invsqrt_ps -_mm512_log10_pd -_mm512_log10_ph -_mm512_log10_ps -_mm512_log1p_pd -_mm512_log1p_ph -_mm512_log1p_ps -_mm512_log2_pd -_mm512_log2_ph -_mm512_log2_ps -_mm512_log_pd -_mm512_log_ph -_mm512_log_ps -_mm512_logb_pd -_mm512_logb_ph -_mm512_logb_ps -_mm512_mask_acos_pd -_mm512_mask_acos_ph -_mm512_mask_acos_ps -_mm512_mask_acosh_pd -_mm512_mask_acosh_ph -_mm512_mask_acosh_ps -_mm512_mask_asin_pd -_mm512_mask_asin_ph -_mm512_mask_asin_ps -_mm512_mask_asinh_pd -_mm512_mask_asinh_ph -_mm512_mask_asinh_ps -_mm512_mask_atan2_pd -_mm512_mask_atan2_ps -_mm512_mask_atan_pd -_mm512_mask_atan_ph -_mm512_mask_atan_ph -_mm512_mask_atanh_pd -_mm512_mask_atanh_ph -_mm512_mask_atanh_ps -_mm512_mask_cbrt_pd -_mm512_mask_cbrt_ph -_mm512_mask_cbrt_ps -_mm512_mask_cdfnorm_pd -_mm512_mask_cdfnorm_ph -_mm512_mask_cdfnorm_ps -_mm512_mask_cdfnorminv_pd -_mm512_mask_cdfnorminv_ph -_mm512_mask_cdfnorminv_ps -_mm512_mask_ceil_ph -_mm512_mask_cos_pd -_mm512_mask_cos_ph -_mm512_mask_cos_ps -_mm512_mask_cosd_pd -_mm512_mask_cosd_ph -_mm512_mask_cosd_ps -_mm512_mask_cosh_pd -_mm512_mask_cosh_ph -_mm512_mask_cosh_ps -_mm512_mask_atan_ps -_mm512_cosd_pd -_mm512_cos_ps -_mm512_cos_ph -_mm512_cos_pd -_mm512_mask_div_epi32 -_mm512_mask_div_epu32 -_mm512_mask_erf_pd -_mm512_mask_erf_ph -_mm512_mask_erf_ps -_mm512_mask_erfc_pd -_mm512_mask_erfc_ph -_mm512_mask_erfc_ps -_mm512_mask_erfcinv_pd -_mm512_mask_erfcinv_ph -_mm512_mask_erfcinv_ps -_mm512_mask_erfinv_pd -_mm512_mask_erfinv_ph -_mm512_mask_erfinv_ps -_mm512_mask_exp10_pd -_mm512_mask_exp10_ph -_mm512_mask_exp10_ps -_mm512_mask_exp2_pd -_mm512_mask_exp2_ph -_mm512_mask_exp2_ps -_mm512_mask_exp_pd -_mm512_mask_exp_ph -_mm512_mask_exp_ps -_mm512_mask_expm1_pd -_mm512_mask_expm1_ph -_mm512_mask_expm1_ps -_mm512_mask_floor_ph -_mm512_mask_hypot_pd -_mm512_mask_hypot_ps -_mm512_mask_invsqrt_pd -_mm512_mask_invsqrt_ph -_mm512_mask_invsqrt_ps -_mm512_mask_log10_pd -_mm512_mask_log10_ph -_mm512_mask_log10_ps -_mm512_mask_log1p_pd -_mm512_mask_log1p_ph -_mm512_mask_log1p_ps -_mm512_mask_log2_pd -_mm512_mask_log2_ph -_mm512_mask_log2_ps -_mm512_mask_log_pd -_mm512_mask_log_ph -_mm512_mask_log_ps -_mm512_mask_logb_pd -_mm512_mask_logb_ph -_mm512_mask_logb_ps -_mm512_mask_nearbyint_pd -_mm512_mask_nearbyint_ph -_mm512_mask_nearbyint_ps -_mm512_mask_pow_pd -_mm512_mask_pow_ps -_mm512_mask_recip_pd -_mm512_mask_recip_ph -_mm512_mask_recip_ps -_mm512_mask_rem_epi32 -_mm512_mask_rem_epu32 -_mm512_mask_rint_pd -_mm512_mask_rint_ph -_mm512_mask_rint_ps -_mm512_mask_sin_pd -_mm512_mask_sin_ph -_mm512_mask_sin_ps -_mm512_mask_sind_pd -_mm512_mask_sind_ph -_mm512_mask_sind_ps -_mm512_mask_sinh_pd -_mm512_mask_sinh_ph -_mm512_mask_sinh_ps -_mm512_mask_svml_round_pd -_mm512_mask_svml_round_ph -_mm512_mask_tan_pd -_mm512_mask_tan_ph -_mm512_mask_tan_ps -_mm512_mask_tand_pd -_mm512_mask_tand_ph -_mm512_mask_tand_ps -_mm512_mask_tanh_pd -_mm512_mask_tanh_ph -_mm512_mask_tanh_ps -_mm512_mask_trunc_pd -_mm512_mask_trunc_ph -_mm512_mask_trunc_ps -_mm512_nearbyint_pd -_mm512_nearbyint_ph -_mm512_nearbyint_ps -_mm512_pow_pd -_mm512_pow_ph -_mm512_pow_ps -_mm512_recip_pd -_mm512_recip_ph -_mm512_recip_ps -_mm512_rem_epi16 -_mm512_rem_epi32 -_mm512_rem_epi64 -_mm512_rem_epi8 -_mm512_rem_epu16 -_mm512_rem_epu32 -_mm512_rem_epu64 -_mm512_rem_epu8 -_mm512_rint_pd -_mm512_rint_ph -_mm512_rint_ps -_mm512_sin_pd -_mm512_sin_ph -_mm512_sin_ps -_mm512_sind_pd -_mm512_sind_ph -_mm512_sind_ps -_mm512_sinh_pd -_mm512_sinh_ph -_mm512_sinh_ps -_mm512_svml_round_pd -_mm512_svml_round_ph -_mm512_tan_pd -_mm512_tan_ph -_mm512_tan_ps -_mm512_tand_pd -_mm512_tand_ph -_mm512_tand_ps -_mm512_tanh_pd -_mm512_tanh_ph -_mm512_tanh_ps -_mm512_trunc_pd -_mm512_trunc_ph -_mm512_trunc_ps -_mm_acos_pd -_mm_acos_ph -_mm_acos_ps -_mm_acosh_pd -_mm_acosh_ph -_mm_acosh_ps -_mm_asin_pd -_mm_asin_ph -_mm_asin_ps -_mm_asinh_pd -_mm_asinh_ph -_mm_asinh_ps -_mm_atan2_pd -_mm_atan2_ph -_mm_atan2_ps -_mm_atan_pd -_mm_atan_ph -_mm_atan_ps -_mm_atanh_pd -_mm_atanh_ph -_mm_atanh_ps -_mm_cbrt_pd -_mm_cbrt_ph -_mm_cbrt_ps -_mm_cdfnorm_pd -_mm_cdfnorm_ph -_mm_cdfnorm_ps -_mm_cdfnorminv_pd -_mm_cdfnorminv_ph -_mm_cdfnorminv_ps -_mm_cexp_ps -_mm_clog_ps -_mm_cos_pd -_mm_cos_ph -_mm_cos_ps -_mm_cosd_pd -_mm_cosd_ph -_mm_cosd_ps -_mm_cosh_pd -_mm_cosh_ph -_mm_cosh_ps -_mm_csqrt_ps -_mm_cvtsd_si64x -_mm_cvtsi128_si64x -_mm_cvtsi64x_sd -_mm_cvtsi64x_si128 -_mm_cvttsd_si64x -_mm_div_epi16 -_mm_div_epi32 -_mm_div_epi64 -_mm_div_epi8 -_mm_div_epu16 -_mm_div_epu32 -_mm_div_epu64 -_mm_div_epu8 -_mm_dpbssd_epi32 -_mm_dpbssds_epi32 -_mm_dpbsud_epi32 -_mm_dpbsuds_epi32 -_mm_dpbuud_epi32 -_mm_dpbuuds_epi32 -_mm_dpwsud_epi32 -_mm_dpwsuds_epi32 -_mm_dpwusd_epi32 -_mm_dpwusds_epi32 -_mm_dpwuud_epi32 -_mm_dpwuuds_epi32 -_mm_erf_pd -_mm_erf_ph -_mm_erf_ps -_mm_erfc_pd -_mm_erfc_ph -_mm_erfc_ps -_mm_erfcinv_pd -_mm_erfcinv_ph -_mm_erfcinv_ps -_mm_erfinv_pd -_mm_erfinv_ph -_mm_erfinv_ps -_mm_exp10_pd -_mm_exp10_ph -_mm_exp10_ps -_mm_exp2_pd -_mm_exp2_ph -_mm_exp2_ps -_mm_exp_pd -_mm_exp_ph -_mm_exp_ps -_mm_expm1_pd -_mm_expm1_ph -_mm_expm1_ps -_mm_hypot_pd -_mm_hypot_ph -_mm_hypot_ps -_mm_idiv_epi32 -_mm_invcbrt_pd -_mm_invcbrt_ph -_mm_invcbrt_ps -_mm_invsqrt_pd -_mm_invsqrt_ph -_mm_invsqrt_ps -_mm_irem_epi32 -_mm_log10_pd -_mm_log10_ph -_mm_log10_ps -_mm_log1p_pd -_mm_log1p_ph -_mm_log1p_ps -_mm_log2_pd -_mm_log2_ph -_mm_log2_ps -_mm_log_pd -_mm_log_ph -_mm_log_ps -_mm_logb_pd -_mm_logb_ph -_mm_logb_ps -_mm_madd52hi_avx_epu64 -_mm_madd52lo_avx_epu64 -_mm_mask_reduce_add_epi16 -_mm_mask_reduce_add_epi8 -_mm_mask_reduce_and_epi16 -_mm_mask_reduce_and_epi8 -_mm_mask_reduce_max_epi16 -_mm_mask_reduce_max_epi8 -_mm_mask_reduce_max_epu16 -_mm_mask_reduce_max_epu8 -_mm_mask_reduce_min_epi16 -_mm_mask_reduce_min_epi8 -_mm_mask_reduce_min_epu16 -_mm_mask_reduce_min_epu8 -_mm_mask_reduce_mul_epi16 -_mm_mask_reduce_mul_epi8 -_mm_mask_reduce_or_epi16 -_mm_mask_reduce_or_epi8 -_mm_pow_pd -_mm_pow_ph -_mm_pow_ps -_mm_reduce_add_epi16 -_mm_reduce_add_epi8 -_mm_reduce_and_epi16 -_mm_reduce_and_epi8 -_mm_reduce_max_epi16 -_mm_reduce_max_epi8 -_mm_reduce_max_epu16 -_mm_reduce_max_epu8 -_mm_reduce_min_epi16 -_mm_reduce_min_epi8 -_mm_reduce_min_epu16 -_mm_reduce_min_epu8 -_mm_reduce_mul_epi16 -_mm_reduce_mul_epi8 -_mm_reduce_or_epi16 -_mm_reduce_or_epi8 -_mm_rem_epi16 -_mm_rem_epi32 -_mm_rem_epi64 -_mm_rem_epi8 -_mm_rem_epu16 -_mm_rem_epu32 -_mm_rem_epu64 -_mm_rem_epu8 -_mm_sin_pd -_mm_sin_ph -_mm_sin_ps -_mm_sind_pd -_mm_sind_ph -_mm_sind_ps -_mm_sinh_pd -_mm_sinh_ph -_mm_sinh_ps -_mm_sm3msg1_epi32 -_mm_sm3msg2_epi32 -_mm_sm3rnds2_epi32 -_mm_sm4key4_epi32 -_mm_sm4rnds4_epi32 -_mm_svml_ceil_pd -_mm_svml_ceil_ph -_mm_svml_ceil_ps -_mm_svml_floor_pd -_mm_svml_floor_ph -_mm_svml_floor_ps -_mm_svml_round_pd -_mm_svml_round_ph -_mm_svml_round_ps -_mm_svml_sqrt_pd -_mm_svml_sqrt_ph -_mm_svml_sqrt_ps -_mm_tan_pd -_mm_tan_ph -_mm_tan_ps -_mm_tand_pd -_mm_tand_ph -_mm_tand_ps -_mm_tanh_pd -_mm_tanh_ph -_mm_tanh_ps -_mm_trunc_pd -_mm_trunc_ph -_mm_trunc_ps -_mm_udiv_epi32 -_mm_urem_epi32 -_popcnt32 -_popcnt64 _rdpmc _rotl _rotl64 @@ -594,284 +23,30 @@ _rotwl _rotwr _urdmsr -# Cannot find value in this scope (in Rust testfiles) -_mm512_set1_pch -_mm_abs_pi16 -_mm_abs_pi32 -_mm_abs_pi8 -_mm_add_pi16 -_mm_add_pi32 -_mm_add_pi8 -_mm_add_si64 -_mm_adds_pi16 -_mm_adds_pi8 -_mm_adds_pu16 -_mm_adds_pu8 -_mm_alignr_pi8 -_mm_and_si64 -_mm_andnot_si64 -_mm_avg_pu16 -_mm_avg_pu8 -_mm_cmpeq_pi16 -_mm_cmpeq_pi32 -_mm_cmpeq_pi8 -_mm_cmpgt_pi16 -_mm_cmpgt_pi32 -_mm_cmpgt_pi8 -_mm_cvt_pi2ps -_mm_cvt_ps2pi -_mm_cvtm64_si64 -_mm_cvtpd_pi32 -_mm_cvtpi16_ps -_mm_cvtpi32_pd -_mm_cvtpi32_ps -_mm_cvtpi32x2_ps -_mm_cvtpi8_ps -_mm_cvtps_pi16 -_mm_cvtps_pi32 -_mm_cvtps_pi8 -_mm_cvtpu16_ps -_mm_cvtpu8_ps -_mm_cvtsi32_si64 -_mm_cvtsi64_m64 -_mm_cvtsi64_si32 -_mm_cvtt_ps2pi -_mm_cvttpd_pi32 -_mm512_cbrt_pd -_mm512_cbrt_ph -_mm512_cbrt_ps -_mm512_cdfnorm_pd -_mm512_cdfnorm_ph -_mm512_cdfnorm_ps -_mm512_cdfnorminv_pd -_mm512_cdfnorminv_ph -_mm512_cdfnorminv_ps -_mm512_ceil_pd -_mm512_ceil_ph -_mm512_ceil_ps -_mm512_floor_pd -_mm512_floor_ps -_mm512_mask_ceil_pd -_mm512_mask_ceil_ps -_mm_max_pi16 -_mm_max_pu8 -_mm_min_pi16 -_mm_min_pu8 -_mm_movemask_pi8 -_mm_movepi64_pi64 -_mm_movpi64_epi64 -_mm_mul_su32 -_mm_mulhi_pi16 -_mm_mulhi_pu16 -_mm_mulhrs_pi16 -_mm_mullo_pi16 -_mm_or_si64 -_mm_packs_pi16 -_mm_packs_pi32 -_mm_packs_pu16 -_mm_popcnt_u32 -_mm_popcnt_u64 -_mm_sad_pu8 -_mm_set1_epi64 -_mm_set1_pch -_mm_set1_pi16 -_mm_set1_pi32 -_mm_set1_pi8 -_mm_set_epi64 -_mm_set_pi16 -_mm_set_pi32 -_mm_set_pi8 -_mm_setr_epi64 -_mm_setr_pi16 -_mm_setr_pi32 -_mm_setr_pi8 -_mm_shuffle_pi16 -_mm_shuffle_pi8 -_mm_sign_pi16 -_mm_sign_pi32 -_mm_sign_pi8 -_mm_sll_pi16 -_mm_sll_pi32 -_mm_sll_si64 -_mm_slli_pi16 -_mm_slli_pi32 -_mm_slli_si64 -_mm_sra_pi16 -_mm_sra_pi32 -_mm_srai_pi16 -_mm_srai_pi32 -_mm_srl_pi16 -_mm_srl_pi32 -_mm_srl_si64 -_mm_srli_pi16 -_mm_srli_pi32 -_mm_srli_si64 -_mm_sub_pi16 -_mm_sub_pi32 -_mm_sub_pi8 -_mm_sub_si64 -_mm_subs_pi16 -_mm_subs_pi8 -_mm_subs_pu16 -_mm_subs_pu8 -_mm_unpackhi_pi16 -_mm_unpackhi_pi32 -_mm_unpackhi_pi8 -_mm_unpacklo_pi16 -_mm_unpacklo_pi32 -_mm_unpacklo_pi8 -_mm_xor_si64 -_mm256_pow_pd -_mm256_pow_ph -_mm256_pow_ps -_mm256_rem_epi16 -_mm256_rem_epi32 -_mm256_rem_epi64 -_mm256_rem_epi8 -_mm256_rem_epu16 -_mm256_rem_epu32 -_mm256_rem_epu64 -_mm256_rem_epu8 -_mm256_set1_pch -_mm256_sin_pd -_mm256_sin_ph -_mm256_sin_ps -_mm256_sind_pd -_mm256_sind_ph -_mm256_sind_ps -_mm256_sinh_pd -_mm256_sinh_ph -_mm256_sinh_ps -_mm256_svml_ceil_pd -_mm256_svml_ceil_ph -_mm256_svml_ceil_ps -_mm256_svml_floor_pd -_mm256_svml_floor_ph -_mm256_svml_floor_ps -_mm256_svml_round_pd -_mm256_svml_round_ph -_mm256_svml_round_ps -_mm256_svml_sqrt_pd -_mm256_svml_sqrt_ph -_mm256_svml_sqrt_ps -_mm256_tan_pd -_mm256_tan_ph -_mm256_tan_ps -_mm256_tand_pd -_mm256_tand_ph -_mm256_tand_ps -_mm256_tanh_pd -_mm256_tanh_ph -_mm256_tanh_ps -_mm256_trunc_pd -_mm256_trunc_ph -_mm256_trunc_ps -_mm256_udiv_epi32 -_mm256_urem_epi32 -_mm512_acos_pd -_mm512_acos_ph -_mm512_acos_ps -_mm512_acosh_pd -_mm512_acosh_ph -_mm512_acosh_ps -_mm_cvttps_pi32 -_mm_extract_pi16 -_mm_hadd_pi16 -_mm_hadd_pi32 -_mm_hadds_pi16 -_mm_hsub_pi16 -_mm_hsub_pi32 -_mm_hsubs_pi16 -_mm_insert_pi16 -_mm_madd_pi16 -_mm_maddubs_pi16 -_mm512_asin_pd -_mm512_asin_ph -_mm512_asin_ps -_mm512_asinh_pd -_mm512_asinh_ph -_mm512_asinh_ps -_mm512_atan2_pd -_mm512_atan2_ph -_mm512_atan2_ps -_mm512_atan_pd -_mm512_atan_ph -_mm512_atan_ps -_mm512_atanh_pd -_mm512_atanh_ph -_mm512_atanh_ps +# not present in Clang +_bswap +_mm_cvtsd_si64x +_mm_cvtsi128_si64x +_mm_cvtsi64x_sd +_mm_cvtsi64x_si128 +_mm_cvttsd_si64x +_popcnt32 +_popcnt64 + +# not present in Rust _cvtsh_ss _cvtss_sh -_m_from_int -_m_from_int64 -_m_packssdw -_m_packsswb -_m_packuswb -_m_paddb -_m_paddd -_m_paddsb -_m_paddsw -_m_paddusb -_m_paddusw -_m_paddw -_m_pand -_m_pandn -_m_pavgb -_m_pavgw -_m_pcmpeqb -_m_pcmpeqd -_m_pcmpeqw -_m_pcmpgtb -_m_pcmpgtd -_m_pcmpgtw -_m_pextrw -_m_pinsrw -_m_pmaddwd -_m_pmaxsw -_m_pmaxub -_m_pminsw -_m_pminub -_m_pmovmskb -_m_pmulhuw -_m_pmulhw -_m_pmullw -_m_por -_m_psadbw -_m_pshufw -_m_pslld -_m_pslldi -_m_psllq -_m_psllqi -_m_psllw -_m_psllwi -_m_psrad -_m_psradi -_m_psraw -_m_psrawi -_m_psrld -_m_psrldi -_m_psrlq -_m_psrlqi -_m_psrlw -_m_psrlwi -_m_psubb -_m_psubd -_m_psubsb -_m_psubsw -_m_psubusb -_m_psubusw -_m_psubw -_m_punpckhbw -_m_punpckhdq -_m_punpckhwd -_m_punpcklbw -_m_punpckldq -_m_punpcklwd -_m_pxor -_m_to_int -_m_to_int64 -_mm512_mask_floor_pd -_mm512_mask_floor_ps +_mm256_set1_pch +_mm512_set1_pch +_mm_malloc +_mm_popcnt_u32 +_mm_popcnt_u64 +_mm_set1_pch +_tpause +_umwait + +# IMM8 must be an even number in the range `0..=62` +_mm_sm3rnds2_epi32 # SDE ERROR: Cannot execute XGETBV with ECX != 0 _xgetbv @@ -901,4 +76,4 @@ _mm_extract_epi8 _mm_mask_cvtepi16_epi8 _mm_mask_cvtpd_epi32 _mm_mask_cvtpd_ps -_mm_ucomineq_sh \ No newline at end of file +_mm_ucomineq_sh diff --git a/library/stdarch/crates/intrinsic-test/src/common/intrinsic_helpers.rs b/library/stdarch/crates/intrinsic-test/src/common/intrinsic_helpers.rs index c2d66868ceb4..bd943c211e46 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/intrinsic_helpers.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/intrinsic_helpers.rs @@ -42,7 +42,7 @@ impl FromStr for TypeKind { "uint" | "unsigned" | "UI8" | "UI16" | "UI32" | "UI64" => Ok(Self::Int(Sign::Unsigned)), "void" => Ok(Self::Void), "MASK" => Ok(Self::Mask), - "M64" | "M128" | "M256" | "M512" => Ok(Self::Vector), + "M128" | "M256" | "M512" => Ok(Self::Vector), _ => Err(format!("Impossible to parse argument kind {s}")), } } diff --git a/library/stdarch/crates/intrinsic-test/src/x86/compile.rs b/library/stdarch/crates/intrinsic-test/src/x86/compile.rs index 60997a1278a4..65cd291b1b37 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/compile.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/compile.rs @@ -25,14 +25,26 @@ pub fn build_cpp_compilation(config: &ProcessedCli) -> Option { "-mavx512cd", "-mavx512fp16", "-msha512", + "-msm3", "-msm4", "-mavxvnni", + "-mavxvnniint8", + "-mavxneconvert", + "-mavxifma", + "-mavxvnniint16", + "-mavx512bf16", "-mavx512bitalg", "-mavx512ifma", "-mavx512vbmi", "-mavx512vbmi2", "-mavx512vnni", "-mavx512vpopcntdq", + "-mavx512vp2intersect", + "-mbmi", + "-mbmi2", + "-mgfni", + "-mvaes", + "-mvpclmulqdq", "-ferror-limit=1000", "-std=c++23", ]); diff --git a/library/stdarch/crates/intrinsic-test/src/x86/config.rs b/library/stdarch/crates/intrinsic-test/src/x86/config.rs index 7c349e448206..40607d8491d1 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/config.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/config.rs @@ -280,12 +280,6 @@ pub const PLATFORM_C_FORWARD_DECLARATIONS: &str = r#" #define _mm512_extract_intrinsic_test_epi64(m, lane) \ _mm_extract_epi64(_mm512_extracti64x2_epi64((m), (lane) / 2), (lane) % 2) - - #define _mm64_extract_intrinsic_test_epi8(m, lane) \ - ((_mm_extract_pi16((m), (lane) / 2) >> (((lane) % 2) * 8)) & 0xFF) - - #define _mm64_extract_intrinsic_test_epi32(m, lane) \ - _mm_cvtsi64_si32(_mm_srli_si64(m, (lane) * 32)) // Load f16 (__m128h) and cast to integer (__m128i) #define _mm_loadu_ph_to___m128i(mem_addr) _mm_castph_si128(_mm_loadu_ph(mem_addr)) diff --git a/library/stdarch/crates/intrinsic-test/src/x86/types.rs b/library/stdarch/crates/intrinsic-test/src/x86/types.rs index 87932fcb3ec7..d6cb938096a1 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/types.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/types.rs @@ -115,9 +115,6 @@ impl IntrinsicTypeDefinition for X86IntrinsicType { // if "type" starts with __m{h/i/}, // then use either _mm_set1_epi64, // _mm256_set1_epi64 or _mm512_set1_epi64 - if type_value.contains("__m64") { - return String::from("*(__m64*)"); - } let type_val_filtered = type_value .chars() @@ -262,9 +259,6 @@ impl IntrinsicTypeDefinition for X86IntrinsicType { (Some(16), Some(512)) => String::from("(uint16_t)_mm512_extract_intrinsic_test_epi16"), (Some(32), Some(512)) => String::from("(uint32_t)_mm512_extract_intrinsic_test_epi32"), (Some(64), Some(512)) => String::from("(uint64_t)_mm512_extract_intrinsic_test_epi64"), - (Some(8), Some(64)) => String::from("(uint8_t)_mm64_extract_intrinsic_test_epi8"), - (Some(16), Some(64)) => String::from("(uint16_t)_mm_extract_pi16"), - (Some(32), Some(64)) => String::from("(uint32_t)_mm64_extract_intrinsic_test_epi32"), _ => unreachable!( "invalid length for vector argument: {:?}, {:?}", self.bit_len, self.simd_len diff --git a/library/stdarch/crates/intrinsic-test/src/x86/xml_parser.rs b/library/stdarch/crates/intrinsic-test/src/x86/xml_parser.rs index af85118b8aac..681b1a3c5274 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/xml_parser.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/xml_parser.rs @@ -30,8 +30,8 @@ struct XMLIntrinsic { pub return_data: Parameter, #[serde(rename = "@name")] pub name: String, - // #[serde(rename = "@tech")] - // tech: String, + #[serde(rename = "@tech")] + tech: String, #[serde(rename = "CPUID", default)] cpuid: Vec, #[serde(rename = "parameter", default)] @@ -65,6 +65,16 @@ pub fn get_xml_intrinsics( let parsed_intrinsics: Vec> = data .intrinsics .into_iter() + .filter(|intrinsic| { + intrinsic.tech != "SVML" + && intrinsic.tech != "MMX" + && !intrinsic.cpuid.contains(&"MPX".to_string()) + && intrinsic.return_data.type_data != "__m64" + && !intrinsic + .parameters + .iter() + .any(|param| param.type_data.contains("__m64")) + }) .filter_map(|intr| { // Some(xml_to_intrinsic(intr, target).expect("Couldn't parse XML properly!")) xml_to_intrinsic(intr).ok() From 0c0de0742a168294b3b0d3d93ab86ce1c9417cef Mon Sep 17 00:00:00 2001 From: sayantn Date: Sat, 29 Nov 2025 10:30:15 +0530 Subject: [PATCH 0179/3801] Format `f16` values normally, rather than use the bit patterns --- .../crates/intrinsic-test/src/arm/config.rs | 93 +------------------ .../src/common/intrinsic_helpers.rs | 13 +-- .../crates/intrinsic-test/src/x86/config.rs | 73 +-------------- .../crates/intrinsic-test/src/x86/types.rs | 44 +++------ 4 files changed, 20 insertions(+), 203 deletions(-) diff --git a/library/stdarch/crates/intrinsic-test/src/arm/config.rs b/library/stdarch/crates/intrinsic-test/src/arm/config.rs index a63464596915..85cb21c2d6c4 100644 --- a/library/stdarch/crates/intrinsic-test/src/arm/config.rs +++ b/library/stdarch/crates/intrinsic-test/src/arm/config.rs @@ -38,11 +38,7 @@ std::ostream& operator<<(std::ostream& os, poly128_t value) { #endif std::ostream& operator<<(std::ostream& os, float16_t value) { - uint16_t temp = 0; - memcpy(&temp, &value, sizeof(float16_t)); - std::stringstream ss; - ss << "0x" << std::setfill('0') << std::setw(4) << std::hex << temp; - os << ss.str(); + os << static_cast(value); return os; } @@ -52,92 +48,7 @@ std::ostream& operator<<(std::ostream& os, uint8_t value) { } "#; -// Format f16 values (and vectors containing them) in a way that is consistent with C. -pub const PLATFORM_RUST_DEFINITIONS: &str = r#" -/// Used to continue `Debug`ging SIMD types as `MySimd(1, 2, 3, 4)`, as they -/// were before moving to array-based simd. -#[inline] -fn debug_simd_finish( - formatter: &mut core::fmt::Formatter<'_>, - type_name: &str, - array: &[T; N], -) -> core::fmt::Result { - core::fmt::Formatter::debug_tuple_fields_finish( - formatter, - type_name, - &core::array::from_fn::<&dyn core::fmt::Debug, N, _>(|i| &array[i]), - ) -} - -#[repr(transparent)] -struct Hex(T); - -impl core::fmt::Debug for Hex { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - ::fmt(&self.0, f) - } -} - -fn debug_f16(x: T) -> impl core::fmt::Debug { - Hex(x) -} - -trait DebugHexF16 { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result; -} - -impl DebugHexF16 for f16 { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "{:#06x?}", self.to_bits()) - } -} - -impl DebugHexF16 for float16x4_t { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let array = unsafe { core::mem::transmute::<_, [Hex; 4]>(*self) }; - debug_simd_finish(f, "float16x4_t", &array) - } -} - -impl DebugHexF16 for float16x8_t { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let array = unsafe { core::mem::transmute::<_, [Hex; 8]>(*self) }; - debug_simd_finish(f, "float16x8_t", &array) - } -} - -impl DebugHexF16 for float16x4x2_t { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - debug_simd_finish(f, "float16x4x2_t", &[Hex(self.0), Hex(self.1)]) - } -} -impl DebugHexF16 for float16x4x3_t { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - debug_simd_finish(f, "float16x4x3_t", &[Hex(self.0), Hex(self.1), Hex(self.2)]) - } -} -impl DebugHexF16 for float16x4x4_t { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - debug_simd_finish(f, "float16x4x4_t", &[Hex(self.0), Hex(self.1), Hex(self.2), Hex(self.3)]) - } -} - -impl DebugHexF16 for float16x8x2_t { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - debug_simd_finish(f, "float16x8x2_t", &[Hex(self.0), Hex(self.1)]) - } -} -impl DebugHexF16 for float16x8x3_t { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - debug_simd_finish(f, "float16x8x3_t", &[Hex(self.0), Hex(self.1), Hex(self.2)]) - } -} -impl DebugHexF16 for float16x8x4_t { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - debug_simd_finish(f, "float16x8x4_t", &[Hex(self.0), Hex(self.1), Hex(self.2), Hex(self.3)]) - } -} - "#; +pub const PLATFORM_RUST_DEFINITIONS: &str = ""; pub const PLATFORM_RUST_CFGS: &str = r#" #![cfg_attr(target_arch = "arm", feature(stdarch_arm_neon_intrinsics))] diff --git a/library/stdarch/crates/intrinsic-test/src/common/intrinsic_helpers.rs b/library/stdarch/crates/intrinsic-test/src/common/intrinsic_helpers.rs index bd943c211e46..a14d7ef05f53 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/intrinsic_helpers.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/intrinsic_helpers.rs @@ -368,19 +368,8 @@ pub trait IntrinsicTypeDefinition: Deref { /// Generates a std::cout for the intrinsics results that will match the /// rust debug output format for the return type. The generated line assumes /// there is an int i in scope which is the current pass number. - /// - /// The `intrinsic-test` crate compares the output of C and Rust intrinsics. Currently, It uses - /// a string representation of the output value to compare. In C, f16 values are currently printed - /// as hexadecimal integers. Since https://github.com/rust-lang/rust/pull/127013, rust does print - /// them as decimal floating point values. To keep the intrinsics tests working, for now, format - /// vectors containing f16 values like C prints them. fn print_result_rust(&self) -> String { - let return_value = match self.kind() { - TypeKind::Float if self.inner_size() == 16 => "debug_f16(__return_value)", - _ => "format_args!(\"{__return_value:.150?}\")", - }; - - String::from(return_value) + String::from("format_args!(\"{__return_value:.150?}\")") } /// To enable architecture-specific logic diff --git a/library/stdarch/crates/intrinsic-test/src/x86/config.rs b/library/stdarch/crates/intrinsic-test/src/x86/config.rs index 40607d8491d1..bf943b795cd1 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/config.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/config.rs @@ -142,71 +142,6 @@ fn debug_simd_finish( ) } -#[repr(transparent)] -struct Hex(T); - -impl core::fmt::Debug for Hex { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - ::fmt(&self.0, f) - } -} - -fn debug_f16(x: T) -> impl core::fmt::Debug { - Hex(x) -} - -trait DebugHexF16 { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result; -} - -impl DebugHexF16 for f16 { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "{:#06x?}", self.to_bits()) - } -} - -impl DebugHexF16 for __m128h { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let array = unsafe { core::mem::transmute::<_, [Hex; 8]>(*self) }; - debug_simd_finish(f, "__m128h", &array) - } -} - -impl DebugHexF16 for __m128i { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let array = unsafe { core::mem::transmute::<_, [Hex; 8]>(*self) }; - debug_simd_finish(f, "__m128i", &array) - } -} - -impl DebugHexF16 for __m256h { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let array = unsafe { core::mem::transmute::<_, [Hex; 16]>(*self) }; - debug_simd_finish(f, "__m256h", &array) - } -} - -impl DebugHexF16 for __m256i { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let array = unsafe { core::mem::transmute::<_, [Hex; 16]>(*self) }; - debug_simd_finish(f, "__m256i", &array) - } -} - -impl DebugHexF16 for __m512h { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let array = unsafe { core::mem::transmute::<_, [Hex; 32]>(*self) }; - debug_simd_finish(f, "__m512h", &array) - } -} - -impl DebugHexF16 for __m512i { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let array = unsafe { core::mem::transmute::<_, [Hex; 32]>(*self) }; - debug_simd_finish(f, "__m512i", &array) - } -} - trait DebugAs { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result; } @@ -232,7 +167,7 @@ macro_rules! impl_debug_as { }; } -impl_debug_as!(__m128i, "__m128i", 128, [u8, i8, u16, i16, u32, i32, u64, i64]); +impl_debug_as!(__m128i, "__m128i", 128, [u8, i8, u16, i16, u32, i32, u64, i64, f16]); impl_debug_as!(__m256i, "__m256i", 256, [u8, i8, u16, i16, u32, i32, u64, i64]); impl_debug_as!(__m512i, "__m512i", 512, [u8, i8, u16, i16, u32, i32, u64, i64]); impl_debug_as!(__m128h, "__m128h", 128, [f32]); @@ -336,11 +271,7 @@ pub const PLATFORM_C_FORWARD_DECLARATIONS: &str = r#" pub const PLATFORM_C_DEFINITIONS: &str = r#" std::ostream& operator<<(std::ostream& os, _Float16 value) { - uint16_t temp = 0; - memcpy(&temp, &value, sizeof(_Float16)); - std::stringstream ss; - ss << "0x" << std::setfill('0') << std::setw(4) << std::hex << temp; - os << ss.str(); + os << static_cast(value); return os; } diff --git a/library/stdarch/crates/intrinsic-test/src/x86/types.rs b/library/stdarch/crates/intrinsic-test/src/x86/types.rs index d6cb938096a1..2391ee9c2df4 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/types.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/types.rs @@ -172,29 +172,7 @@ impl IntrinsicTypeDefinition for X86IntrinsicType { /// rust debug output format for the return type. The generated line assumes /// there is an int i in scope which is the current pass number. fn print_result_c(&self, indentation: Indentation, additional: &str) -> String { - let lanes = if self.num_vectors() > 1 { - (0..self.num_vectors()) - .map(|vector| { - format!( - r#""{ty}(" << {lanes} << ")""#, - ty = self.c_single_vector_type(), - lanes = (0..self.num_lanes()) - .map(move |idx| -> std::string::String { - format!( - "{cast}{lane_fn}(__return_value.val[{vector}], {lane})", - cast = self.generate_final_type_cast(), - lane_fn = self.get_lane_function(), - lane = idx, - vector = vector, - ) - }) - .collect::>() - .join(r#" << ", " << "#) - ) - }) - .collect::>() - .join(r#" << ", " << "#) - } else if self.num_lanes() > 1 { + let lanes = if self.num_lanes() > 1 { (0..self.num_lanes()) .map(|idx| -> std::string::String { let cast_type = self.c_promotion(); @@ -283,12 +261,9 @@ impl IntrinsicTypeDefinition for X86IntrinsicType { fn print_result_rust(&self) -> String { let return_value = match self.kind() { - TypeKind::Float if self.inner_size() == 16 => "debug_f16(__return_value)".to_string(), - TypeKind::Float - if self.inner_size() == 32 - && ["__m512h"].contains(&self.param.type_data.as_str()) => - { - "debug_as::<_, f32>(__return_value)".to_string() + // `_mm{256}_cvtps_ph` has return type __m128i but contains f16 values + TypeKind::Float if self.param.type_data == "__m128i" => { + "format_args!(\"{:.150?}\", debug_as::<_, f16>(__return_value))".to_string() } TypeKind::Int(_) if ["__m128i", "__m256i", "__m512i"].contains(&self.param.type_data.as_str()) => @@ -463,6 +438,17 @@ impl X86IntrinsicType { } } + // a few intrinsics have wrong `etype` field in the XML + // - _mm512_reduce_add_ph + // - _mm512_reduce_mul_ph + // - _mm512_reduce_min_ph + // - _mm512_reduce_max_ph + // - _mm512_conj_pch + if param.type_data == "__m512h" && param.etype == "FP32" { + data.bit_len = Some(16); + data.simd_len = Some(32); + } + let mut result = X86IntrinsicType { data, param: param.clone(), From 8b35ef74a51fa972c045d09d97f9b71185989802 Mon Sep 17 00:00:00 2001 From: sayantn Date: Sat, 29 Nov 2025 12:02:48 +0530 Subject: [PATCH 0180/3801] correct behavior of some intrinsics --- .../stdarch/crates/core_arch/src/x86/avx512bw.rs | 16 ++++++++-------- .../stdarch/crates/core_arch/src/x86/avx512f.rs | 14 ++++++-------- .../crates/core_arch/src/x86/avx512fp16.rs | 4 ++-- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index c7f271d22ef5..0073bdeb4acd 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -10705,9 +10705,13 @@ pub fn _mm_cvtepi16_epi8(a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(vpmovwb))] pub fn _mm_mask_cvtepi16_epi8(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { - let convert = _mm_cvtepi16_epi8(a).as_i8x16(); - let k: __mmask16 = 0b11111111_11111111 & k as __mmask16; - transmute(simd_select_bitmask(k, convert, src.as_i8x16())) + let a = _mm_cvtepi16_epi8(a).as_i8x16(); + let src = simd_shuffle!( + src.as_i8x16(), + i8x16::ZERO, + [0, 1, 2, 3, 4, 5, 6, 7, 16, 16, 16, 16, 16, 16, 16, 16] + ); + simd_select_bitmask(k as u16, a, src).as_m128i() } } @@ -10719,11 +10723,7 @@ pub fn _mm_mask_cvtepi16_epi8(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] pub fn _mm_maskz_cvtepi16_epi8(k: __mmask8, a: __m128i) -> __m128i { - unsafe { - let convert = _mm_cvtepi16_epi8(a).as_i8x16(); - let k: __mmask16 = 0b11111111_11111111 & k as __mmask16; - transmute(simd_select_bitmask(k, convert, i8x16::ZERO)) - } + _mm_mask_cvtepi16_epi8(_mm_setzero_si128(), k, a) } /// Convert packed signed 16-bit integers in a to packed 8-bit integers with signed saturation, and store the results in dst. diff --git a/library/stdarch/crates/core_arch/src/x86/avx512f.rs b/library/stdarch/crates/core_arch/src/x86/avx512f.rs index 8c57fc201161..8d3ddbd964bb 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512f.rs @@ -11149,10 +11149,7 @@ pub fn _mm256_maskz_cvtpd_ps(k: __mmask8, a: __m256d) -> __m128 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtpd2ps))] pub fn _mm_mask_cvtpd_ps(src: __m128, k: __mmask8, a: __m128d) -> __m128 { - unsafe { - let convert = _mm_cvtpd_ps(a); - transmute(simd_select_bitmask(k, convert.as_f32x4(), src.as_f32x4())) - } + unsafe { vcvtpd2ps128(a.as_f64x2(), src.as_f32x4(), k).as_m128() } } /// Convert packed double-precision (64-bit) floating-point elements in a to packed single-precision (32-bit) floating-point elements, and store the results in dst using zeromask k (elements are zeroed out when the corresponding mask bit is not set). @@ -11259,10 +11256,7 @@ pub fn _mm256_maskz_cvtpd_epi32(k: __mmask8, a: __m256d) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtpd2dq))] pub fn _mm_mask_cvtpd_epi32(src: __m128i, k: __mmask8, a: __m128d) -> __m128i { - unsafe { - let convert = _mm_cvtpd_epi32(a); - transmute(simd_select_bitmask(k, convert.as_i32x4(), src.as_i32x4())) - } + unsafe { vcvtpd2dq128(a.as_f64x2(), src.as_i32x4(), k).as_m128i() } } /// Convert packed double-precision (64-bit) floating-point elements in a to packed 32-bit integers, and store the results in dst using zeromask k (elements are zeroed out when the corresponding mask bit is not set). @@ -42483,9 +42477,13 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.mask.cvtps2pd.512"] fn vcvtps2pd(a: f32x8, src: f64x8, mask: u8, sae: i32) -> f64x8; + #[link_name = "llvm.x86.avx512.mask.cvtpd2ps"] + fn vcvtpd2ps128(a: f64x2, src: f32x4, mask: u8) -> f32x4; #[link_name = "llvm.x86.avx512.mask.cvtpd2ps.512"] fn vcvtpd2ps(a: f64x8, src: f32x8, mask: u8, rounding: i32) -> f32x8; + #[link_name = "llvm.x86.avx512.mask.cvtpd2dq.128"] + fn vcvtpd2dq128(a: f64x2, src: i32x4, k: u8) -> i32x4; #[link_name = "llvm.x86.avx512.mask.cvtpd2dq.512"] fn vcvtpd2dq(a: f64x8, src: i32x8, mask: u8, rounding: i32) -> i32x8; diff --git a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs index 13cae45d0f81..01b1be364fe5 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs @@ -1007,7 +1007,7 @@ pub fn _mm_comilt_sh(a: __m128h, b: __m128h) -> i32 { #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] pub fn _mm_comineq_sh(a: __m128h, b: __m128h) -> i32 { - _mm_comi_sh::<_CMP_NEQ_OS>(a, b) + _mm_comi_sh::<_CMP_NEQ_US>(a, b) } /// Compare the lower half-precision (16-bit) floating-point elements in a and b for equality, and @@ -1073,7 +1073,7 @@ pub fn _mm_ucomilt_sh(a: __m128h, b: __m128h) -> i32 { #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] pub fn _mm_ucomineq_sh(a: __m128h, b: __m128h) -> i32 { - _mm_comi_sh::<_CMP_NEQ_OQ>(a, b) + _mm_comi_sh::<_CMP_NEQ_UQ>(a, b) } /// Load 128-bits (composed of 8 packed half-precision (16-bit) floating-point elements) from memory into From ae78a301e0332d01c11d89ce531686d9aa7fc92a Mon Sep 17 00:00:00 2001 From: sayantn Date: Sat, 29 Nov 2025 11:53:23 +0530 Subject: [PATCH 0181/3801] fix intrinsic-test to use `core_arch::arch` rather than `std::arch` --- .../crates/intrinsic-test/missing_x86.txt | 22 +++++-------------- .../crates/intrinsic-test/src/x86/config.rs | 2 +- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/library/stdarch/crates/intrinsic-test/missing_x86.txt b/library/stdarch/crates/intrinsic-test/missing_x86.txt index 11c3eeba9063..f88a125bfdff 100644 --- a/library/stdarch/crates/intrinsic-test/missing_x86.txt +++ b/library/stdarch/crates/intrinsic-test/missing_x86.txt @@ -51,29 +51,17 @@ _mm_sm3rnds2_epi32 # SDE ERROR: Cannot execute XGETBV with ECX != 0 _xgetbv -# Miscellaneous issues that can be fixed first -_kshiftli_mask16 -_kshiftli_mask32 -_kshiftli_mask64 -_kshiftli_mask8 -_kshiftri_mask16 -_kshiftri_mask32 -_kshiftri_mask64 -_kshiftri_mask8 +# top bits are undefined, unclear how to test these _mm256_castsi128_si256 -_mm256_extract_epi16 -_mm256_extract_epi8 _mm512_castsi128_si512 _mm512_castsi256_si512 -# _mm512_conj_pch + +# Clang bug +_mm256_extract_epi16 +_mm256_extract_epi8 _mm512_mask_reduce_max_pd _mm512_mask_reduce_max_ps _mm512_mask_reduce_min_pd _mm512_mask_reduce_min_ps -_mm_comineq_sh _mm_extract_epi16 _mm_extract_epi8 -_mm_mask_cvtepi16_epi8 -_mm_mask_cvtpd_epi32 -_mm_mask_cvtpd_ps -_mm_ucomineq_sh diff --git a/library/stdarch/crates/intrinsic-test/src/x86/config.rs b/library/stdarch/crates/intrinsic-test/src/x86/config.rs index bf943b795cd1..491dbb5147bb 100644 --- a/library/stdarch/crates/intrinsic-test/src/x86/config.rs +++ b/library/stdarch/crates/intrinsic-test/src/x86/config.rs @@ -5,7 +5,7 @@ pub const NOTICE: &str = "\ // Format f16 values (and vectors containing them) in a way that is consistent with C. pub const PLATFORM_RUST_DEFINITIONS: &str = r#" -use std::arch::x86_64::*; +use core_arch::arch::x86_64::*; #[inline] unsafe fn _mm_loadu_ph_to___m128i(mem_addr: *const f16) -> __m128i { From 3e8185f155a0294b201667f2736d9554f5e00e9a Mon Sep 17 00:00:00 2001 From: sayantn Date: Sun, 5 Oct 2025 05:29:09 +0530 Subject: [PATCH 0182/3801] Make `cpuid` safe and update docs --- .../stdarch/crates/core_arch/src/x86/cpuid.rs | 40 +++++++++++-------- .../stdarch/crates/core_arch/src/x86/xsave.rs | 2 +- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/cpuid.rs b/library/stdarch/crates/core_arch/src/x86/cpuid.rs index 0634f10a99fd..84dcf75492b3 100644 --- a/library/stdarch/crates/core_arch/src/x86/cpuid.rs +++ b/library/stdarch/crates/core_arch/src/x86/cpuid.rs @@ -28,12 +28,21 @@ pub struct CpuidResult { /// Returns the result of the `cpuid` instruction for a given `leaf` (`EAX`) /// and `sub_leaf` (`ECX`). /// -/// The highest-supported leaf value is returned by the first tuple argument of -/// [`__get_cpuid_max(0)`](fn.__get_cpuid_max.html). For leaves containing -/// sub-leaves, the second tuple argument returns the highest-supported -/// sub-leaf value. +/// There are two types of information leaves - basic leaves (with `leaf < 0x8000000`) +/// and extended leaves (with `leaf >= 0x80000000`). The highest supported basic and +/// extended leaves can be obtained by calling CPUID with `0` and `0x80000000`, +/// respectively, and reading the value in the `EAX` register. If the leaf supports +/// more than one sub-leaf, then the procedure of obtaining the highest supported +/// sub-leaf, as well as the behavior if a invalid sub-leaf value is passed, depends +/// on the specific leaf. /// -/// The [CPUID Wikipedia page][wiki_cpuid] contains how to query which +/// If the `leaf` value is higher than the maximum supported basic or extended leaf +/// for the processor, this returns the information for the highest supported basic +/// information leaf (with the passed `sub_leaf` value). If the `leaf` value is less +/// than or equal to the highest basic or extended leaf value, but the leaf is not +/// supported on the processor, all zeros are returned. +/// +/// The [CPUID Wikipedia page][wiki_cpuid] contains information on how to query which /// information using the `EAX` and `ECX` registers, and the interpretation of /// the results returned in `EAX`, `EBX`, `ECX`, and `EDX`. /// @@ -49,7 +58,7 @@ pub struct CpuidResult { #[inline] #[cfg_attr(test, assert_instr(cpuid))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult { +pub fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult { let eax; let ebx; let ecx; @@ -58,7 +67,7 @@ pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult { // LLVM sometimes reserves `ebx` for its internal use, we so we need to use // a scratch register for it instead. #[cfg(target_arch = "x86")] - { + unsafe { asm!( "mov {0}, ebx", "cpuid", @@ -71,7 +80,7 @@ pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult { ); } #[cfg(target_arch = "x86_64")] - { + unsafe { asm!( "mov {0:r}, rbx", "cpuid", @@ -86,27 +95,26 @@ pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult { CpuidResult { eax, ebx, ecx, edx } } +/// Calls CPUID with the provided `leaf` value, with `sub_leaf` set to 0. /// See [`__cpuid_count`](fn.__cpuid_count.html). #[inline] #[cfg_attr(test, assert_instr(cpuid))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn __cpuid(leaf: u32) -> CpuidResult { +pub fn __cpuid(leaf: u32) -> CpuidResult { __cpuid_count(leaf, 0) } -/// Returns the highest-supported `leaf` (`EAX`) and sub-leaf (`ECX`) `cpuid` -/// values. +/// Returns the EAX and EBX register after calling CPUID with the provided `leaf`, +/// with `sub_leaf` set to 0. /// -/// If `cpuid` is supported, and `leaf` is zero, then the first tuple argument -/// contains the highest `leaf` value that `cpuid` supports. For `leaf`s -/// containing sub-leafs, the second tuple argument contains the -/// highest-supported sub-leaf value. +/// If `leaf` if 0 or `0x80000000`, the first tuple argument contains the maximum +/// supported basic or extended leaf, respectively. /// /// See also [`__cpuid`](fn.__cpuid.html) and /// [`__cpuid_count`](fn.__cpuid_count.html). #[inline] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn __get_cpuid_max(leaf: u32) -> (u32, u32) { +pub fn __get_cpuid_max(leaf: u32) -> (u32, u32) { let CpuidResult { eax, ebx, .. } = __cpuid(leaf); (eax, ebx) } diff --git a/library/stdarch/crates/core_arch/src/x86/xsave.rs b/library/stdarch/crates/core_arch/src/x86/xsave.rs index 190cef929e47..653eb28c4268 100644 --- a/library/stdarch/crates/core_arch/src/x86/xsave.rs +++ b/library/stdarch/crates/core_arch/src/x86/xsave.rs @@ -184,7 +184,7 @@ mod tests { // `CPUID.(EAX=0DH,ECX=0):ECX` contains the size required to hold all supported xsave // components. `EBX` contains the size required to hold all xsave components currently // enabled in `XCR0`. We are using `ECX` to ensure enough space in all scenarios - let CpuidResult { ecx, .. } = unsafe { __cpuid(0x0d) }; + let CpuidResult { ecx, .. } = __cpuid(0x0d); XsaveArea { data: vec![AlignedArray([0; 64]); ecx.div_ceil(64) as usize].into_boxed_slice(), From ae310e230a14205b26f2c2796d80e9d90a6b5333 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Wed, 12 Nov 2025 19:26:31 +0000 Subject: [PATCH 0183/3801] fix: `redundant_pattern_matching` misses `)` in suggestion span --- .../src/matches/redundant_pattern_match.rs | 14 ++++---------- tests/ui/redundant_pattern_matching_option.fixed | 13 +++++++++++++ tests/ui/redundant_pattern_matching_option.rs | 13 +++++++++++++ tests/ui/redundant_pattern_matching_option.stderr | 14 +++++++++++++- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index bc3783750e5c..897e7da5a967 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -1,7 +1,6 @@ use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; -use clippy_utils::source::walk_span_to_context; use clippy_utils::sugg::{Sugg, make_unop}; use clippy_utils::ty::needs_ordered_drop; use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr_without_closures}; @@ -25,7 +24,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { .. }) = higher::WhileLet::hir(expr) { - find_method_sugg_for_if_let(cx, expr, let_pat, let_expr, "while", false); + find_method_sugg_for_if_let(cx, expr, let_pat, let_expr, "while", false, let_span); find_if_let_true(cx, let_pat, let_expr, let_span); } } @@ -39,7 +38,7 @@ pub(super) fn check_if_let<'tcx>( let_span: Span, ) { find_if_let_true(cx, pat, scrutinee, let_span); - find_method_sugg_for_if_let(cx, expr, pat, scrutinee, "if", has_else); + find_method_sugg_for_if_let(cx, expr, pat, scrutinee, "if", has_else, let_span); } /// Looks for: @@ -182,6 +181,7 @@ fn find_method_sugg_for_if_let<'tcx>( let_expr: &'tcx Expr<'_>, keyword: &'static str, has_else: bool, + let_span: Span, ) { // also look inside refs // if we have &None for example, peel it so we can detect "if let None = x" @@ -239,15 +239,9 @@ fn find_method_sugg_for_if_let<'tcx>( let expr_span = expr.span; let ctxt = expr.span.ctxt(); - // if/while let ... = ... { ... } - // ^^^ - let Some(res_span) = walk_span_to_context(result_expr.span.source_callsite(), ctxt) else { - return; - }; - // if/while let ... = ... { ... } // ^^^^^^^^^^^^^^^^^^^^^^ - let span = expr_span.until(res_span.shrink_to_hi()); + let span = expr_span.until(let_span.shrink_to_hi()); let mut app = if needs_drop { Applicability::MaybeIncorrect diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed index 08903ef7fdda..b44009446640 100644 --- a/tests/ui/redundant_pattern_matching_option.fixed +++ b/tests/ui/redundant_pattern_matching_option.fixed @@ -195,3 +195,16 @@ fn issue16045() { } } } + +fn issue14989() { + macro_rules! x { + () => { + None:: + }; + } + + if x! {}.is_some() {}; + //~^ redundant_pattern_matching + while x! {}.is_some() {} + //~^ redundant_pattern_matching +} diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs index 95eff3f9ebf9..c13cf993e786 100644 --- a/tests/ui/redundant_pattern_matching_option.rs +++ b/tests/ui/redundant_pattern_matching_option.rs @@ -231,3 +231,16 @@ fn issue16045() { } } } + +fn issue14989() { + macro_rules! x { + () => { + None:: + }; + } + + if let Some(_) = (x! {}) {}; + //~^ redundant_pattern_matching + while let Some(_) = (x! {}) {} + //~^ redundant_pattern_matching +} diff --git a/tests/ui/redundant_pattern_matching_option.stderr b/tests/ui/redundant_pattern_matching_option.stderr index 6fd0c5a6f859..5c9edfd4c50a 100644 --- a/tests/ui/redundant_pattern_matching_option.stderr +++ b/tests/ui/redundant_pattern_matching_option.stderr @@ -236,5 +236,17 @@ error: redundant pattern matching, consider using `is_some()` LL | if let Some(_) = x.await { | -------^^^^^^^---------- help: try: `if x.await.is_some()` -error: aborting due to 33 previous errors +error: redundant pattern matching, consider using `is_some()` + --> tests/ui/redundant_pattern_matching_option.rs:242:12 + | +LL | if let Some(_) = (x! {}) {}; + | -------^^^^^^^---------- help: try: `if x! {}.is_some()` + +error: redundant pattern matching, consider using `is_some()` + --> tests/ui/redundant_pattern_matching_option.rs:244:15 + | +LL | while let Some(_) = (x! {}) {} + | ----------^^^^^^^---------- help: try: `while x! {}.is_some()` + +error: aborting due to 35 previous errors From f242c46a0a423e3b088c6826636394fd21f788a1 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sun, 2 Nov 2025 19:17:30 +0000 Subject: [PATCH 0184/3801] fix: `set-contains-or-insert` FP when set is mutated before `insert` --- clippy_lints/src/set_contains_or_insert.rs | 21 ++++++++++++++++++--- tests/ui/set_contains_or_insert.rs | 21 +++++++++++++++++++++ tests/ui/set_contains_or_insert.stderr | 11 ++++++++++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/set_contains_or_insert.rs b/clippy_lints/src/set_contains_or_insert.rs index 688da33a1777..7482bac4c7b4 100644 --- a/clippy_lints/src/set_contains_or_insert.rs +++ b/clippy_lints/src/set_contains_or_insert.rs @@ -112,6 +112,16 @@ fn try_parse_op_call<'tcx>( None } +fn is_set_mutated<'tcx>(cx: &LateContext<'tcx>, contains_expr: &OpExpr<'tcx>, expr: &'tcx Expr<'_>) -> bool { + // Guard on type to avoid useless potentially expansive `SpanlessEq` checks + cx.typeck_results().expr_ty_adjusted(expr).is_mutable_ptr() + && matches!( + cx.typeck_results().expr_ty(expr).peel_refs().opt_diag_name(cx), + Some(sym::HashSet | sym::BTreeSet) + ) + && SpanlessEq::new(cx).eq_expr(contains_expr.receiver, expr.peel_borrows()) +} + fn find_insert_calls<'tcx>( cx: &LateContext<'tcx>, contains_expr: &OpExpr<'tcx>, @@ -122,9 +132,14 @@ fn find_insert_calls<'tcx>( && SpanlessEq::new(cx).eq_expr(contains_expr.receiver, insert_expr.receiver) && SpanlessEq::new(cx).eq_expr(contains_expr.value, insert_expr.value) { - ControlFlow::Break(insert_expr) - } else { - ControlFlow::Continue(()) + return ControlFlow::Break(Some(insert_expr)); } + + if is_set_mutated(cx, contains_expr, e) { + return ControlFlow::Break(None); + } + + ControlFlow::Continue(()) }) + .flatten() } diff --git a/tests/ui/set_contains_or_insert.rs b/tests/ui/set_contains_or_insert.rs index 575cfda139a4..ac1d74f8afa4 100644 --- a/tests/ui/set_contains_or_insert.rs +++ b/tests/ui/set_contains_or_insert.rs @@ -164,3 +164,24 @@ fn main() { should_not_warn_hashset(); should_not_warn_btreeset(); } + +fn issue15990(s: &mut HashSet, v: usize) { + if !s.contains(&v) { + s.clear(); + s.insert(v); + } + + fn borrow_as_mut(v: usize, s: &mut HashSet) { + s.clear(); + } + if !s.contains(&v) { + borrow_as_mut(v, s); + s.insert(v); + } + + if !s.contains(&v) { + //~^ set_contains_or_insert + let _readonly_access = s.contains(&v); + s.insert(v); + } +} diff --git a/tests/ui/set_contains_or_insert.stderr b/tests/ui/set_contains_or_insert.stderr index 3152b1136458..3b06b63182ab 100644 --- a/tests/ui/set_contains_or_insert.stderr +++ b/tests/ui/set_contains_or_insert.stderr @@ -127,5 +127,14 @@ LL | LL | borrow_set.insert(value); | ^^^^^^^^^^^^^ -error: aborting due to 14 previous errors +error: usage of `HashSet::insert` after `HashSet::contains` + --> tests/ui/set_contains_or_insert.rs:182:11 + | +LL | if !s.contains(&v) { + | ^^^^^^^^^^^^ +... +LL | s.insert(v); + | ^^^^^^^^^ + +error: aborting due to 15 previous errors From 0e336684fd92ec8343d76085646dffe576b9b015 Mon Sep 17 00:00:00 2001 From: tison Date: Sun, 30 Nov 2025 10:42:41 +0800 Subject: [PATCH 0185/3801] Leverage &mut in OnceLock when possible Signed-off-by: tison --- library/std/src/sync/once_lock.rs | 45 ++++++++++++++++++------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index d1bbe0ff843c..dc7df5baf863 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -1,3 +1,4 @@ +use super::once::OnceExclusiveState; use crate::cell::UnsafeCell; use crate::fmt; use crate::marker::PhantomData; @@ -152,8 +153,8 @@ impl OnceLock { #[stable(feature = "once_cell", since = "1.70.0")] #[rustc_should_not_be_called_on_const_items] pub fn get(&self) -> Option<&T> { - if self.is_initialized() { - // Safe b/c checked is_initialized + if self.initialized() { + // Safe b/c checked initialized Some(unsafe { self.get_unchecked() }) } else { None @@ -170,8 +171,8 @@ impl OnceLock { #[inline] #[stable(feature = "once_cell", since = "1.70.0")] pub fn get_mut(&mut self) -> Option<&mut T> { - if self.is_initialized() { - // Safe b/c checked is_initialized and we have a unique access + if self.initialized_mut() { + // Safe b/c checked initialized and we have a unique access Some(unsafe { self.get_unchecked_mut() }) } else { None @@ -402,14 +403,12 @@ impl OnceLock { // NOTE: We need to perform an acquire on the state in this method // in order to correctly synchronize `LazyLock::force`. This is // currently done by calling `self.get()`, which in turn calls - // `self.is_initialized()`, which in turn performs the acquire. + // `self.initialized()`, which in turn performs the acquire. if let Some(value) = self.get() { return Ok(value); } self.initialize(f)?; - debug_assert!(self.is_initialized()); - // SAFETY: The inner value has been initialized Ok(unsafe { self.get_unchecked() }) } @@ -451,10 +450,10 @@ impl OnceLock { where F: FnOnce() -> Result, { - if self.get().is_none() { + if self.get_mut().is_none() { self.initialize(f)?; } - debug_assert!(self.is_initialized()); + // SAFETY: The inner value has been initialized Ok(unsafe { self.get_unchecked_mut() }) } @@ -503,22 +502,32 @@ impl OnceLock { #[inline] #[stable(feature = "once_cell", since = "1.70.0")] pub fn take(&mut self) -> Option { - if self.is_initialized() { + if self.initialized_mut() { self.once = Once::new(); // SAFETY: `self.value` is initialized and contains a valid `T`. - // `self.once` is reset, so `is_initialized()` will be false again + // `self.once` is reset, so `initialized()` will be false again // which prevents the value from being read twice. - unsafe { Some((&mut *self.value.get()).assume_init_read()) } + unsafe { Some(self.value.get_mut().assume_init_read()) } } else { None } } #[inline] - fn is_initialized(&self) -> bool { + fn initialized(&self) -> bool { self.once.is_completed() } + #[inline] + fn initialized_mut(&mut self) -> bool { + // `state()` does not perform an atomic load, so prefer it over `is_complete()`. + let state = self.once.state(); + match state { + OnceExclusiveState::Complete => true, + _ => false, + } + } + #[cold] #[optimize(size)] fn initialize(&self, f: F) -> Result<(), E> @@ -552,7 +561,7 @@ impl OnceLock { /// The cell must be initialized #[inline] unsafe fn get_unchecked(&self) -> &T { - debug_assert!(self.is_initialized()); + debug_assert!(self.initialized()); unsafe { (&*self.value.get()).assume_init_ref() } } @@ -561,8 +570,8 @@ impl OnceLock { /// The cell must be initialized #[inline] unsafe fn get_unchecked_mut(&mut self) -> &mut T { - debug_assert!(self.is_initialized()); - unsafe { (&mut *self.value.get()).assume_init_mut() } + debug_assert!(self.initialized_mut()); + unsafe { self.value.get_mut().assume_init_mut() } } } @@ -689,11 +698,11 @@ impl Eq for OnceLock {} unsafe impl<#[may_dangle] T> Drop for OnceLock { #[inline] fn drop(&mut self) { - if self.is_initialized() { + if self.initialized_mut() { // SAFETY: The cell is initialized and being dropped, so it can't // be accessed again. We also don't touch the `T` other than // dropping it, which validates our usage of #[may_dangle]. - unsafe { (&mut *self.value.get()).assume_init_drop() }; + unsafe { self.value.get_mut().assume_init_drop() }; } } } From 8b27170cb4a29262a60daa6c735b65a1d3b42765 Mon Sep 17 00:00:00 2001 From: Young-Flash Date: Sun, 30 Nov 2025 11:32:56 +0800 Subject: [PATCH 0186/3801] internal: migrate `convert_iter_for_each_to_for` to SyntaxEditor api --- .../handlers/convert_iter_for_each_to_for.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs index c8a244b2136d..d564555b91ea 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs @@ -3,7 +3,7 @@ use ide_db::famous_defs::FamousDefs; use stdx::format_to; use syntax::{ AstNode, - ast::{self, HasArgList, HasLoopBody, edit_in_place::Indent, make}, + ast::{self, HasArgList, HasLoopBody, edit_in_place::Indent, syntax_factory::SyntaxFactory}, }; use crate::{AssistContext, AssistId, Assists}; @@ -57,18 +57,22 @@ pub(crate) fn convert_iter_for_each_to_for( "Replace this `Iterator::for_each` with a for loop", range, |builder| { + let make = SyntaxFactory::with_mappings(); let indent = stmt.as_ref().map_or_else(|| method.indent_level(), ast::ExprStmt::indent_level); let block = match body { - ast::Expr::BlockExpr(block) => block, - _ => make::block_expr(Vec::new(), Some(body)), - } - .clone_for_update(); + ast::Expr::BlockExpr(block) => block.clone_for_update(), + _ => make.block_expr(Vec::new(), Some(body)), + }; block.reindent_to(indent); - let expr_for_loop = make::expr_for_loop(param, receiver, block); - builder.replace(range, expr_for_loop.to_string()) + let expr_for_loop = make.expr_for_loop(param, receiver, block); + + let target_node = stmt.as_ref().map_or(method.syntax(), AstNode::syntax); + let mut editor = builder.make_editor(target_node); + editor.replace(target_node, expr_for_loop.syntax()); + builder.add_file_edits(ctx.vfs_file_id(), editor); }, ) } From daf592985ef14a4a053ac1165fd5efb921154344 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sun, 30 Nov 2025 04:57:57 +0000 Subject: [PATCH 0187/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 3ff30e7eafc1da7104c3960187d17939172428ed. --- 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 1efb31457bab..5c4de1da0312 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -1eb0657f78777f0b4d6bcc49c126d5d35212cae5 +3ff30e7eafc1da7104c3960187d17939172428ed From 34f2848ef46254e144f3056de9c1594998c312fd Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 30 Nov 2025 13:42:13 +0800 Subject: [PATCH 0188/3801] Fix indent for toggle_ignore Example --- ```rust mod indent { #[test$0] fn test() {} } ``` **Before this PR** ```rust mod indent { #[test] #[ignore] fn test() {} } ``` And re-enable ```rust mod indent { #[test] fn test() {} } ``` **After this PR** ```rust mod indent { #[test] #[ignore] fn test() {} } ``` --- .../ide-assists/src/handlers/toggle_ignore.rs | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_ignore.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_ignore.rs index 386625b86b27..a088fb178d25 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_ignore.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_ignore.rs @@ -1,6 +1,6 @@ use syntax::{ AstNode, AstToken, - ast::{self, HasAttrs}, + ast::{self, HasAttrs, edit::AstNodeEdit}, }; use crate::{AssistContext, AssistId, Assists, utils::test_related_attribute_syn}; @@ -27,13 +27,16 @@ pub(crate) fn toggle_ignore(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio let attr: ast::Attr = ctx.find_node_at_offset()?; let func = attr.syntax().parent().and_then(ast::Fn::cast)?; let attr = test_related_attribute_syn(&func)?; + let indent = attr.indent_level(); match has_ignore_attribute(&func) { None => acc.add( AssistId::refactor("toggle_ignore"), "Ignore this test", attr.syntax().text_range(), - |builder| builder.insert(attr.syntax().text_range().end(), "\n#[ignore]"), + |builder| { + builder.insert(attr.syntax().text_range().end(), format!("\n{indent}#[ignore]")) + }, ), Some(ignore_attr) => acc.add( AssistId::refactor("toggle_ignore"), @@ -69,13 +72,17 @@ mod tests { check_assist( toggle_ignore, r#" - #[test$0] - fn test() {} + mod indent { + #[test$0] + fn test() {} + } "#, r#" - #[test] - #[ignore] - fn test() {} + mod indent { + #[test] + #[ignore] + fn test() {} + } "#, ) } @@ -85,13 +92,17 @@ mod tests { check_assist( toggle_ignore, r#" - #[test$0] - #[ignore] - fn test() {} + mod indent { + #[test$0] + #[ignore] + fn test() {} + } "#, r#" - #[test] - fn test() {} + mod indent { + #[test] + fn test() {} + } "#, ) } From ad7ba50e528c512f3714348ed46c4b41d4f17c9c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 30 Nov 2025 10:12:38 +0100 Subject: [PATCH 0189/3801] bless genmc tests --- .../tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr | 4 ++-- src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr | 6 +++--- src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr | 6 +++--- src/tools/miri/tests/genmc/pass/std/empty_main.stderr | 2 +- .../miri/tests/genmc/pass/std/spawn_std_threads.stderr | 6 +++--- src/tools/miri/tests/genmc/pass/std/thread_locals.stderr | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr index e74b76ea415e..e2148bedd318 100644 --- a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr +++ b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr @@ -18,7 +18,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside `miri_start` --> tests/genmc/fail/shims/mutex_diff_thread_unlock.rs:LL:CC | @@ -48,7 +48,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside `miri_start` --> tests/genmc/fail/shims/mutex_diff_thread_unlock.rs:LL:CC | diff --git a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr index 695aa3f5aeaf..fdbb9eff2faa 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr @@ -1,6 +1,6 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/mod.rs:LL:CC + --> RUSTLIB/std/src/thread/id.rs:LL:CC | LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code @@ -46,7 +46,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | @@ -67,7 +67,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | diff --git a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr index 8609c2c5c864..a5423f9a398b 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr @@ -1,6 +1,6 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/mod.rs:LL:CC + --> RUSTLIB/std/src/thread/id.rs:LL:CC | LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code @@ -46,7 +46,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | @@ -67,7 +67,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/arc.rs:LL:CC | diff --git a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr index b1413ee6d574..de07943b0d8d 100644 --- a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr +++ b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr @@ -1,6 +1,6 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/mod.rs:LL:CC + --> RUSTLIB/std/src/thread/id.rs:LL:CC | LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code diff --git a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr index 87d3c60ef02e..701934a7cd7f 100644 --- a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr +++ b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr @@ -1,6 +1,6 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/mod.rs:LL:CC + --> RUSTLIB/std/src/thread/id.rs:LL:CC | LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code @@ -20,7 +20,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside closure --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC | @@ -52,7 +52,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside closure --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC | diff --git a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr index 91d2f5daa146..fd6538fd70fa 100644 --- a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr +++ b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr @@ -1,6 +1,6 @@ Running GenMC Verification... warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/mod.rs:LL:CC + --> RUSTLIB/std/src/thread/id.rs:LL:CC | LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code @@ -20,7 +20,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/thread_locals.rs:LL:CC | @@ -42,7 +42,7 @@ LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquir | = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC note: inside `main` --> tests/genmc/pass/std/thread_locals.rs:LL:CC | From 8eb411b0981c0a4b8c21c16b5e1fad94a2dcec5f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 30 Nov 2025 10:39:56 +0100 Subject: [PATCH 0190/3801] use fully deterministic concurrency for while-queued tests --- .../concurrency/libc_pthread_mutex_read_while_queued.rs | 2 +- .../concurrency/libc_pthread_mutex_write_while_queued.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs index 555d765d24ba..418259ca4e8e 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs @@ -1,5 +1,5 @@ //@ignore-target: windows # No pthreads on Windows -//@compile-flags: -Zmiri-fixed-schedule +//@compile-flags: -Zmiri-deterministic-concurrency use std::cell::UnsafeCell; use std::sync::atomic::*; diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs index 00274f7080f3..0778f06ff6fe 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs @@ -1,5 +1,5 @@ //@ignore-target: windows # No pthreads on Windows -//@compile-flags: -Zmiri-fixed-schedule +//@compile-flags: -Zmiri-deterministic-concurrency use std::cell::UnsafeCell; use std::sync::atomic::*; From a6162c3dd9e8b620c277f6b90df1ed3f669864f8 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 3 Sep 2025 15:53:13 +0200 Subject: [PATCH 0191/3801] add `ptr_offset_by_literal` lint --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/methods/mod.rs | 37 +++++ .../src/methods/ptr_offset_by_literal.rs | 138 +++++++++++++++++ tests/ui/borrow_as_ptr.fixed | 2 +- tests/ui/borrow_as_ptr.rs | 2 +- tests/ui/crashes/ice-4579.rs | 2 +- tests/ui/ptr_offset_by_literal.fixed | 50 +++++++ tests/ui/ptr_offset_by_literal.rs | 50 +++++++ tests/ui/ptr_offset_by_literal.stderr | 141 ++++++++++++++++++ tests/ui/zero_offset.rs | 2 +- 11 files changed, 422 insertions(+), 4 deletions(-) create mode 100644 clippy_lints/src/methods/ptr_offset_by_literal.rs create mode 100644 tests/ui/ptr_offset_by_literal.fixed create mode 100644 tests/ui/ptr_offset_by_literal.rs create mode 100644 tests/ui/ptr_offset_by_literal.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cb2755be0ee..434cfff20510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6764,6 +6764,7 @@ Released 2018-09-13 [`ptr_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr [`ptr_cast_constness`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_cast_constness [`ptr_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq +[`ptr_offset_by_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_by_literal [`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast [`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names [`pub_underscore_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index a754eea31165..1414e6076364 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -443,6 +443,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::methods::OR_THEN_UNWRAP_INFO, crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO, crate::methods::PATH_ENDS_WITH_EXT_INFO, + crate::methods::PTR_OFFSET_BY_LITERAL_INFO, crate::methods::PTR_OFFSET_WITH_CAST_INFO, crate::methods::RANGE_ZIP_WITH_LEN_INFO, crate::methods::READONLY_WRITE_LOCK_INFO, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index c22b0a548e3d..e6b9589233c9 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -94,6 +94,7 @@ mod or_fun_call; mod or_then_unwrap; mod path_buf_push_overwrite; mod path_ends_with_ext; +mod ptr_offset_by_literal; mod ptr_offset_with_cast; mod range_zip_with_len; mod read_line_without_trim; @@ -1728,6 +1729,40 @@ declare_clippy_lint! { "Check for offset calculations on raw pointers to zero-sized types" } +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of the `offset` pointer method with an integer + /// literal. + /// + /// ### Why is this bad? + /// The `add` and `sub` methods more accurately express the intent. + /// + /// ### Example + /// ```no_run + /// let vec = vec![b'a', b'b', b'c']; + /// let ptr = vec.as_ptr(); + /// + /// unsafe { + /// ptr.offset(-8); + /// } + /// ``` + /// + /// Could be written: + /// + /// ```no_run + /// let vec = vec![b'a', b'b', b'c']; + /// let ptr = vec.as_ptr(); + /// + /// unsafe { + /// ptr.sub(8); + /// } + /// ``` + #[clippy::version = "1.92.0"] + pub PTR_OFFSET_BY_LITERAL, + pedantic, + "unneeded pointer offset" +} + declare_clippy_lint! { /// ### What it does /// Checks for usage of the `offset` pointer method with a `usize` casted to an @@ -4803,6 +4838,7 @@ impl_lint_pass!(Methods => [ UNINIT_ASSUMED_INIT, MANUAL_SATURATING_ARITHMETIC, ZST_OFFSET, + PTR_OFFSET_BY_LITERAL, PTR_OFFSET_WITH_CAST, FILETYPE_IS_FILE, OPTION_AS_REF_DEREF, @@ -5426,6 +5462,7 @@ impl Methods { zst_offset::check(cx, expr, recv); ptr_offset_with_cast::check(cx, name, expr, recv, arg, self.msrv); + ptr_offset_by_literal::check(cx, expr, self.msrv); }, (sym::ok_or_else, [arg]) => { unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"); diff --git a/clippy_lints/src/methods/ptr_offset_by_literal.rs b/clippy_lints/src/methods/ptr_offset_by_literal.rs new file mode 100644 index 000000000000..b5d2add65cf1 --- /dev/null +++ b/clippy_lints/src/methods/ptr_offset_by_literal.rs @@ -0,0 +1,138 @@ +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::source::SpanRangeExt; +use clippy_utils::sym; +use rustc_ast::LitKind; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, Lit, UnOp}; +use rustc_lint::LateContext; +use std::cmp::Ordering; +use std::fmt; + +use super::PTR_OFFSET_BY_LITERAL; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Msrv) { + // `pointer::add` and `pointer::wrapping_add` are only stable since 1.26.0. These functions + // became const-stable in 1.61.0, the same version that `pointer::offset` became const-stable. + if !msrv.meets(cx, msrvs::POINTER_ADD_SUB_METHODS) { + return; + } + + let ExprKind::MethodCall(method_name, recv, [arg_expr], _) = expr.kind else { + return; + }; + + let method = match method_name.ident.name { + sym::offset => Method::Offset, + sym::wrapping_offset => Method::WrappingOffset, + _ => return, + }; + + if !cx.typeck_results().expr_ty_adjusted(recv).is_raw_ptr() { + return; + } + + // Check if the argument to the method call is a (negated) literal. + let Some((literal, literal_text)) = expr_as_literal(cx, arg_expr) else { + return; + }; + + match method.suggestion(literal) { + None => { + let msg = format!("use of `{method}` with zero"); + span_lint_and_then(cx, PTR_OFFSET_BY_LITERAL, expr.span, msg, |diag| { + diag.span_suggestion( + expr.span.with_lo(recv.span.hi()), + format!("remove the call to `{method}`"), + String::new(), + Applicability::MachineApplicable, + ); + }); + }, + Some(method_suggestion) => { + let msg = format!("use of `{method}` with a literal"); + span_lint_and_then(cx, PTR_OFFSET_BY_LITERAL, expr.span, msg, |diag| { + diag.multipart_suggestion( + format!("use `{method_suggestion}` instead"), + vec![ + (method_name.ident.span, method_suggestion.to_string()), + (arg_expr.span, literal_text), + ], + Applicability::MachineApplicable, + ); + }); + }, + } +} + +fn get_literal_bits<'tcx>(expr: &'tcx Expr<'tcx>) -> Option { + match expr.kind { + ExprKind::Lit(Lit { + node: LitKind::Int(packed_u128, _), + .. + }) => Some(packed_u128.get()), + _ => None, + } +} + +// If the given expression is a (negated) literal, return its value. +fn expr_as_literal<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<(i128, String)> { + if let Some(literal_bits) = get_literal_bits(expr) { + // The value must fit in a isize, so we can't have overflow here. + return Some((literal_bits.cast_signed(), format_isize_literal(cx, expr)?)); + } + + if let ExprKind::Unary(UnOp::Neg, inner) = expr.kind + && let Some(literal_bits) = get_literal_bits(inner) + { + return Some((-(literal_bits.cast_signed()), format_isize_literal(cx, inner)?)); + } + + None +} + +fn format_isize_literal<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option { + let text = expr.span.get_source_text(cx)?; + let text = peel_parens_str(&text); + Some(text.trim_end_matches("isize").trim_end_matches('_').to_string()) +} + +fn peel_parens_str(snippet: &str) -> &str { + let mut s = snippet.trim(); + while let Some(next) = s.strip_prefix("(").and_then(|suf| suf.strip_suffix(")")) { + s = next.trim(); + } + s +} + +#[derive(Copy, Clone)] +enum Method { + Offset, + WrappingOffset, +} + +impl Method { + fn suggestion(self, literal: i128) -> Option<&'static str> { + match Ord::cmp(&literal, &0) { + Ordering::Greater => match self { + Method::Offset => Some("add"), + Method::WrappingOffset => Some("wrapping_add"), + }, + // `ptr.offset(0)` is equivalent to `ptr`, so no adjustment is needed + Ordering::Equal => None, + Ordering::Less => match self { + Method::Offset => Some("sub"), + Method::WrappingOffset => Some("wrapping_sub"), + }, + } + } +} + +impl fmt::Display for Method { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Offset => write!(f, "offset"), + Self::WrappingOffset => write!(f, "wrapping_offset"), + } + } +} diff --git a/tests/ui/borrow_as_ptr.fixed b/tests/ui/borrow_as_ptr.fixed index bfe826508f36..a4689a7840ce 100644 --- a/tests/ui/borrow_as_ptr.fixed +++ b/tests/ui/borrow_as_ptr.fixed @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs #![warn(clippy::borrow_as_ptr)] -#![allow(clippy::useless_vec)] +#![allow(clippy::useless_vec, clippy::ptr_offset_by_literal)] extern crate proc_macros; diff --git a/tests/ui/borrow_as_ptr.rs b/tests/ui/borrow_as_ptr.rs index ce248f157c6e..d7468f37a3a4 100644 --- a/tests/ui/borrow_as_ptr.rs +++ b/tests/ui/borrow_as_ptr.rs @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs #![warn(clippy::borrow_as_ptr)] -#![allow(clippy::useless_vec)] +#![allow(clippy::useless_vec, clippy::ptr_offset_by_literal)] extern crate proc_macros; diff --git a/tests/ui/crashes/ice-4579.rs b/tests/ui/crashes/ice-4579.rs index 14c8113e315b..a2592e74c66d 100644 --- a/tests/ui/crashes/ice-4579.rs +++ b/tests/ui/crashes/ice-4579.rs @@ -1,6 +1,6 @@ //@ check-pass -#![allow(clippy::single_match)] +#![allow(clippy::single_match, clippy::ptr_offset_by_literal)] use std::ptr; diff --git a/tests/ui/ptr_offset_by_literal.fixed b/tests/ui/ptr_offset_by_literal.fixed new file mode 100644 index 000000000000..bd9e41def938 --- /dev/null +++ b/tests/ui/ptr_offset_by_literal.fixed @@ -0,0 +1,50 @@ +#![warn(clippy::ptr_offset_by_literal)] +#![allow(clippy::inconsistent_digit_grouping)] + +fn main() { + let arr = [b'a', b'b', b'c']; + let ptr = arr.as_ptr(); + + let var = 32; + const CONST: isize = 42; + + unsafe { + let _ = ptr; + //~^ ptr_offset_by_literal + let _ = ptr; + //~^ ptr_offset_by_literal + + let _ = ptr.add(5); + //~^ ptr_offset_by_literal + let _ = ptr.sub(5); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(var); + let _ = ptr.offset(CONST); + + let _ = ptr.wrapping_add(5); + //~^ ptr_offset_by_literal + let _ = ptr.wrapping_sub(5); + //~^ ptr_offset_by_literal + + let _ = ptr.sub(5); + //~^ ptr_offset_by_literal + let _ = ptr.wrapping_sub(5); + //~^ ptr_offset_by_literal + + // isize::MAX and isize::MIN on 32-bit systems. + let _ = ptr.add(2_147_483_647); + //~^ ptr_offset_by_literal + let _ = ptr.sub(2_147_483_648); + //~^ ptr_offset_by_literal + + let _ = ptr.add(5_0); + //~^ ptr_offset_by_literal + let _ = ptr.sub(5_0); + //~^ ptr_offset_by_literal + + macro_rules! offs { { $e:expr, $offs:expr } => { $e.offset($offs) }; } + offs!(ptr, 6); + offs!(ptr, var); + } +} diff --git a/tests/ui/ptr_offset_by_literal.rs b/tests/ui/ptr_offset_by_literal.rs new file mode 100644 index 000000000000..b8e3f9b26c68 --- /dev/null +++ b/tests/ui/ptr_offset_by_literal.rs @@ -0,0 +1,50 @@ +#![warn(clippy::ptr_offset_by_literal)] +#![allow(clippy::inconsistent_digit_grouping)] + +fn main() { + let arr = [b'a', b'b', b'c']; + let ptr = arr.as_ptr(); + + let var = 32; + const CONST: isize = 42; + + unsafe { + let _ = ptr.offset(0); + //~^ ptr_offset_by_literal + let _ = ptr.offset(-0); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(5); + //~^ ptr_offset_by_literal + let _ = ptr.offset(-5); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(var); + let _ = ptr.offset(CONST); + + let _ = ptr.wrapping_offset(5isize); + //~^ ptr_offset_by_literal + let _ = ptr.wrapping_offset(-5isize); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(-(5)); + //~^ ptr_offset_by_literal + let _ = ptr.wrapping_offset(-(5)); + //~^ ptr_offset_by_literal + + // isize::MAX and isize::MIN on 32-bit systems. + let _ = ptr.offset(2_147_483_647isize); + //~^ ptr_offset_by_literal + let _ = ptr.offset(-2_147_483_648isize); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(5_0__isize); + //~^ ptr_offset_by_literal + let _ = ptr.offset(-5_0__isize); + //~^ ptr_offset_by_literal + + macro_rules! offs { { $e:expr, $offs:expr } => { $e.offset($offs) }; } + offs!(ptr, 6); + offs!(ptr, var); + } +} diff --git a/tests/ui/ptr_offset_by_literal.stderr b/tests/ui/ptr_offset_by_literal.stderr new file mode 100644 index 000000000000..f85fef87d55f --- /dev/null +++ b/tests/ui/ptr_offset_by_literal.stderr @@ -0,0 +1,141 @@ +error: use of `offset` with zero + --> tests/ui/ptr_offset_by_literal.rs:12:17 + | +LL | let _ = ptr.offset(0); + | ^^^---------- + | | + | help: remove the call to `offset` + | + = note: `-D clippy::ptr-offset-by-literal` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::ptr_offset_by_literal)]` + +error: use of `offset` with zero + --> tests/ui/ptr_offset_by_literal.rs:14:17 + | +LL | let _ = ptr.offset(-0); + | ^^^----------- + | | + | help: remove the call to `offset` + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:17:17 + | +LL | let _ = ptr.offset(5); + | ^^^^^^^^^^^^^ + | +help: use `add` instead + | +LL - let _ = ptr.offset(5); +LL + let _ = ptr.add(5); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:19:17 + | +LL | let _ = ptr.offset(-5); + | ^^^^^^^^^^^^^^ + | +help: use `sub` instead + | +LL - let _ = ptr.offset(-5); +LL + let _ = ptr.sub(5); + | + +error: use of `wrapping_offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:25:17 + | +LL | let _ = ptr.wrapping_offset(5isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `wrapping_add` instead + | +LL - let _ = ptr.wrapping_offset(5isize); +LL + let _ = ptr.wrapping_add(5); + | + +error: use of `wrapping_offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:27:17 + | +LL | let _ = ptr.wrapping_offset(-5isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `wrapping_sub` instead + | +LL - let _ = ptr.wrapping_offset(-5isize); +LL + let _ = ptr.wrapping_sub(5); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:30:17 + | +LL | let _ = ptr.offset(-(5)); + | ^^^^^^^^^^^^^^^^ + | +help: use `sub` instead + | +LL - let _ = ptr.offset(-(5)); +LL + let _ = ptr.sub(5); + | + +error: use of `wrapping_offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:32:17 + | +LL | let _ = ptr.wrapping_offset(-(5)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `wrapping_sub` instead + | +LL - let _ = ptr.wrapping_offset(-(5)); +LL + let _ = ptr.wrapping_sub(5); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:36:17 + | +LL | let _ = ptr.offset(2_147_483_647isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `add` instead + | +LL - let _ = ptr.offset(2_147_483_647isize); +LL + let _ = ptr.add(2_147_483_647); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:38:17 + | +LL | let _ = ptr.offset(-2_147_483_648isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `sub` instead + | +LL - let _ = ptr.offset(-2_147_483_648isize); +LL + let _ = ptr.sub(2_147_483_648); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:41:17 + | +LL | let _ = ptr.offset(5_0__isize); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `add` instead + | +LL - let _ = ptr.offset(5_0__isize); +LL + let _ = ptr.add(5_0); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:43:17 + | +LL | let _ = ptr.offset(-5_0__isize); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `sub` instead + | +LL - let _ = ptr.offset(-5_0__isize); +LL + let _ = ptr.sub(5_0); + | + +error: aborting due to 12 previous errors + diff --git a/tests/ui/zero_offset.rs b/tests/ui/zero_offset.rs index bedb09536c53..5a9c3ac9248f 100644 --- a/tests/ui/zero_offset.rs +++ b/tests/ui/zero_offset.rs @@ -1,4 +1,4 @@ -#[allow(clippy::borrow_as_ptr)] +#[allow(clippy::borrow_as_ptr, clippy::ptr_offset_by_literal)] fn main() { unsafe { let m = &mut () as *mut (); From 1deb487076519970fdba20742cc10c380962d2c3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 30 Nov 2025 14:21:08 +0100 Subject: [PATCH 0192/3801] thread::scope: document how join interacts with TLS destructors --- library/std/src/thread/join_handle.rs | 2 ++ library/std/src/thread/scoped.rs | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/library/std/src/thread/join_handle.rs b/library/std/src/thread/join_handle.rs index 8714ceeb4f46..bb3759cd3a07 100644 --- a/library/std/src/thread/join_handle.rs +++ b/library/std/src/thread/join_handle.rs @@ -102,6 +102,8 @@ impl JoinHandle { /// Waits for the associated thread to finish. /// /// This function will return immediately if the associated thread has already finished. + /// Otherwise, it fully waits for the thread to finish, including all destructors + /// for thread-local variables that might be running after the main function of the thread. /// /// In terms of [atomic memory orderings], the completion of the associated /// thread synchronizes with this function returning. In other words, all diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index 301f5e949cac..368fb819962b 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -80,6 +80,9 @@ impl ScopeData { /// /// All threads spawned within the scope that haven't been manually joined /// will be automatically joined before this function returns. +/// However, note that joining will only wait for the main function of these threads to finish; even +/// when this function returns, destructors of thread-local variables in these threads might still +/// be running. /// /// # Panics /// @@ -292,6 +295,8 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// Waits for the associated thread to finish. /// /// This function will return immediately if the associated thread has already finished. + /// Otherwise, it fully waits for the thread to finish, including all destructors + /// for thread-local variables that might be running after the main function of the thread. /// /// In terms of [atomic memory orderings], the completion of the associated /// thread synchronizes with this function returning. From d706368b7006146cd43eb1774b79d481cddb0d30 Mon Sep 17 00:00:00 2001 From: Aliaksei Semianiuk Date: Sun, 30 Nov 2025 15:56:32 +0500 Subject: [PATCH 0193/3801] Changelog for Clippy 1.92 --- CHANGELOG.md | 83 ++++++++++++++++++++++++++++++++- clippy_lints/src/methods/mod.rs | 4 +- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78b81b5b74d6..cf619d254cec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,88 @@ document. ## Unreleased / Beta / In Rust Nightly -[e9b7045...master](https://github.com/rust-lang/rust-clippy/compare/e9b7045...master) +[d9fb15c...master](https://github.com/rust-lang/rust-clippy/compare/d9fb15c...master) + +## Rust 1.92 + +Current stable, released 2025-12-11 + +[View all 124 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-09-05T18%3A24%3A03Z..2025-10-16T14%3A13%3A43Z+base%3Amaster) + +### New Lints + +* Added [`unnecessary_option_map_or_else`] to `suspicious` + [#14662](https://github.com/rust-lang/rust-clippy/pull/14662) +* Added [`replace_box`] to `perf` + [#14953](https://github.com/rust-lang/rust-clippy/pull/14953) +* Added [`volatile_composites`] to `nursery` + [#15686](https://github.com/rust-lang/rust-clippy/pull/15686) +* Added [`self_only_used_in_recursion`] to `pedantic` + [#14787](https://github.com/rust-lang/rust-clippy/pull/14787) +* Added [`redundant_iter_cloned`] to `perf` + [#15277](https://github.com/rust-lang/rust-clippy/pull/15277) + +### Moves and Deprecations + +* Renamed [`unchecked_duration_subtraction`] to [`unchecked_time_subtraction`] + [#13800](https://github.com/rust-lang/rust-clippy/pull/13800) + +### Enhancements + +* [`mutex_atomic`] and [`mutex_integer`] overhauled to only lint definitions, not uses; added suggestions + and better help messages + [#15632](https://github.com/rust-lang/rust-clippy/pull/15632) +* [`manual_rotate`] now recognizes non-const rotation amounts + [#15402](https://github.com/rust-lang/rust-clippy/pull/15402) +* [`multiple_inherent_impl`] added `inherent-impl-lint-scope` config option (`module`, `file`, + or `crate`) + [#15843](https://github.com/rust-lang/rust-clippy/pull/15843) +* [`use_self`] now checks structs and enums + [#15566](https://github.com/rust-lang/rust-clippy/pull/15566) +* [`while_let_loop`] extended to lint on `loop { let else }` + [#15701](https://github.com/rust-lang/rust-clippy/pull/15701) +* [`mut_mut`] overhauled with structured suggestions and improved documentation + [#15417](https://github.com/rust-lang/rust-clippy/pull/15417) +* [`nonstandard_macro_braces`] now suggests trailing semicolon when needed + [#15593](https://github.com/rust-lang/rust-clippy/pull/15593) +* [`ptr_offset_with_cast`] now respects MSRV when suggesting fix, and lints more cases + [#15613](https://github.com/rust-lang/rust-clippy/pull/15613) +* [`cast_sign_loss`] and [`cast_possible_wrap`] added suggestions using `cast_{un,}signed()` methods + (MSRV 1.87+) + [#15384](https://github.com/rust-lang/rust-clippy/pull/15384) +* [`unchecked_time_subtraction`] extended to include `Duration - Duration` operations + [#13800](https://github.com/rust-lang/rust-clippy/pull/13800) +* [`filter_next`] now suggests replacing `filter().next_back()` with `rfind()` for + `DoubleEndedIterator` + [#15748](https://github.com/rust-lang/rust-clippy/pull/15748) + +### False Positive Fixes + +* [`unnecessary_safety_comment`] fixed FPs with comments above attributes + [#15678](https://github.com/rust-lang/rust-clippy/pull/15678) +* [`manual_unwrap_or`] fixed FP edge case + [#15812](https://github.com/rust-lang/rust-clippy/pull/15812) +* [`needless_continue`] fixed FP when match type is not unit or never + [#15547](https://github.com/rust-lang/rust-clippy/pull/15547) +* [`if_then_some_else_none`] fixed FP when return exists in block expr + [#15783](https://github.com/rust-lang/rust-clippy/pull/15783) +* [`new_without_default`] fixed to copy `#[cfg]` onto `impl Default` and fixed FP on private type + with trait impl + [#15720](https://github.com/rust-lang/rust-clippy/pull/15720) + [#15782](https://github.com/rust-lang/rust-clippy/pull/15782) +* [`question_mark`] fixed FP on variables used after + [#15644](https://github.com/rust-lang/rust-clippy/pull/15644) +* [`needless_return`] fixed FP with `cfg`d code after `return` + [#15669](https://github.com/rust-lang/rust-clippy/pull/15669) +* [`useless_attribute`] fixed FP on `deprecated_in_future` + [#15645](https://github.com/rust-lang/rust-clippy/pull/15645) +* [`double_parens`] fixed FP when macros are involved + [#15420](https://github.com/rust-lang/rust-clippy/pull/15420) + +### ICE Fixes + +* [`len_zero`] fixed ICE when fn len has a return type without generic type params + [#15660](https://github.com/rust-lang/rust-clippy/pull/15660) ## Rust 1.91 diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index c22b0a548e3d..089e32d1e430 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -4635,7 +4635,7 @@ declare_clippy_lint! { /// let x = vec![String::new()]; /// let _ = x.iter().map(|x| x.len()); /// ``` - #[clippy::version = "1.90.0"] + #[clippy::version = "1.92.0"] pub REDUNDANT_ITER_CLONED, perf, "detects redundant calls to `Iterator::cloned`" @@ -4659,7 +4659,7 @@ declare_clippy_lint! { /// let x: Option = Some(4); /// let y = x.unwrap_or_else(|| 2 * k); /// ``` - #[clippy::version = "1.88.0"] + #[clippy::version = "1.92.0"] pub UNNECESSARY_OPTION_MAP_OR_ELSE, suspicious, "making no use of the \"map closure\" when calling `.map_or_else(|| 2 * k, |n| n)`" From bd0a5e4ef372d542b73c30e5fb5404f89aa18946 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sun, 30 Nov 2025 20:52:32 +0000 Subject: [PATCH 0194/3801] fix: `empty_enum_variants_with_brackets` misses removing brackets in patterns --- clippy_lints/src/empty_with_brackets.rs | 84 +++++++++++++------ .../empty_enum_variants_with_brackets.fixed | 13 +++ tests/ui/empty_enum_variants_with_brackets.rs | 13 +++ .../empty_enum_variants_with_brackets.stderr | 36 ++++++-- 4 files changed, 112 insertions(+), 34 deletions(-) diff --git a/clippy_lints/src/empty_with_brackets.rs b/clippy_lints/src/empty_with_brackets.rs index e7230ebf8cba..5dc1bb96266a 100644 --- a/clippy_lints/src/empty_with_brackets.rs +++ b/clippy_lints/src/empty_with_brackets.rs @@ -2,13 +2,13 @@ use clippy_utils::attrs::span_contains_cfg; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; -use rustc_hir::def::CtorOf; use rustc_hir::def::DefKind::Ctor; use rustc_hir::def::Res::Def; +use rustc_hir::def::{CtorOf, DefKind}; use rustc_hir::def_id::LocalDefId; -use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node, Path, QPath, Variant, VariantData}; +use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node, Pat, PatKind, Path, QPath, Variant, VariantData}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{self, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::Span; @@ -177,28 +177,7 @@ impl LateLintPass<'_> for EmptyWithBrackets { if expr.span.from_expansion() { return; } - match self.empty_tuple_enum_variants.get_mut(&def_id) { - Some( - &mut (Usage::Unused { - ref mut redundant_use_sites, - } - | Usage::NoDefinition { - ref mut redundant_use_sites, - }), - ) => { - redundant_use_sites.push(parentheses_span); - }, - None => { - // The variant isn't in the IndexMap which means its definition wasn't encountered yet. - self.empty_tuple_enum_variants.insert( - def_id, - Usage::NoDefinition { - redundant_use_sites: vec![parentheses_span], - }, - ); - }, - _ => {}, - } + self.update_enum_variant_usage(def_id, parentheses_span); } else { // The parentheses are not redundant. self.empty_tuple_enum_variants.insert(def_id, Usage::Used); @@ -206,6 +185,16 @@ impl LateLintPass<'_> for EmptyWithBrackets { } } + fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) { + if let Some((def_id, parentheses_span)) = check_pat_for_enum_as_function(cx, pat) { + if pat.span.from_expansion() { + return; + } + + self.update_enum_variant_usage(def_id, parentheses_span); + } + } + fn check_crate_post(&mut self, cx: &LateContext<'_>) { for (local_def_id, usage) in &self.empty_tuple_enum_variants { // Ignore all variants with Usage::Used or Usage::NoDefinition @@ -252,6 +241,33 @@ impl LateLintPass<'_> for EmptyWithBrackets { } } +impl EmptyWithBrackets { + fn update_enum_variant_usage(&mut self, def_id: LocalDefId, parentheses_span: Span) { + match self.empty_tuple_enum_variants.get_mut(&def_id) { + Some( + &mut (Usage::Unused { + ref mut redundant_use_sites, + } + | Usage::NoDefinition { + ref mut redundant_use_sites, + }), + ) => { + redundant_use_sites.push(parentheses_span); + }, + None => { + // The variant isn't in the IndexMap which means its definition wasn't encountered yet. + self.empty_tuple_enum_variants.insert( + def_id, + Usage::NoDefinition { + redundant_use_sites: vec![parentheses_span], + }, + ); + }, + _ => {}, + } + } +} + fn has_brackets(var_data: &VariantData<'_>) -> bool { !matches!(var_data, VariantData::Unit(..)) } @@ -291,3 +307,21 @@ fn check_expr_for_enum_as_function(expr: &Expr<'_>) -> Option { None } } + +fn check_pat_for_enum_as_function(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(LocalDefId, Span)> { + match pat.kind { + PatKind::TupleStruct(qpath, ..) + if let Def(Ctor(CtorOf::Variant, _), def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) => + { + def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi()))) + }, + PatKind::Struct(qpath, ..) + if let Def(DefKind::Variant, def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) + && let ty = cx.tcx.type_of(def_id).instantiate_identity() + && let ty::FnDef(def_id, _) = ty.kind() => + { + def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi()))) + }, + _ => None, + } +} diff --git a/tests/ui/empty_enum_variants_with_brackets.fixed b/tests/ui/empty_enum_variants_with_brackets.fixed index abdf6ca5cb61..515d5a975944 100644 --- a/tests/ui/empty_enum_variants_with_brackets.fixed +++ b/tests/ui/empty_enum_variants_with_brackets.fixed @@ -1,5 +1,6 @@ #![warn(clippy::empty_enum_variants_with_brackets)] #![allow(dead_code)] +#![feature(more_qualified_paths)] pub enum PublicTestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error @@ -102,4 +103,16 @@ pub enum PubFoo { Variant3(), } +fn issue16157() { + enum E { + V, + //~^ empty_enum_variants_with_brackets + } + + let E::V = E::V; + + ::V = E::V; + ::V = E::V; +} + fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.rs b/tests/ui/empty_enum_variants_with_brackets.rs index 63a5a8e9143e..2c29fc505d3b 100644 --- a/tests/ui/empty_enum_variants_with_brackets.rs +++ b/tests/ui/empty_enum_variants_with_brackets.rs @@ -1,5 +1,6 @@ #![warn(clippy::empty_enum_variants_with_brackets)] #![allow(dead_code)] +#![feature(more_qualified_paths)] pub enum PublicTestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error @@ -102,4 +103,16 @@ pub enum PubFoo { Variant3(), } +fn issue16157() { + enum E { + V(), + //~^ empty_enum_variants_with_brackets + } + + let E::V() = E::V(); + + ::V() = E::V(); + ::V {} = E::V(); +} + fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.stderr b/tests/ui/empty_enum_variants_with_brackets.stderr index 7fe85e829a35..c487cebd21ac 100644 --- a/tests/ui/empty_enum_variants_with_brackets.stderr +++ b/tests/ui/empty_enum_variants_with_brackets.stderr @@ -1,5 +1,5 @@ error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:7:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:8:16 | LL | EmptyBraces {}, | ^^^ @@ -9,7 +9,7 @@ LL | EmptyBraces {}, = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:15:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:16:16 | LL | EmptyBraces {}, | ^^^ @@ -17,7 +17,7 @@ LL | EmptyBraces {}, = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:17:21 + --> tests/ui/empty_enum_variants_with_brackets.rs:18:21 | LL | EmptyParentheses(), | ^^ @@ -25,7 +25,7 @@ LL | EmptyParentheses(), = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:28:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:29:16 | LL | Unknown(), | ^^ @@ -33,7 +33,7 @@ LL | Unknown(), = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:47:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:48:16 | LL | Unknown(), | ^^ @@ -41,7 +41,7 @@ LL | Unknown(), = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:53:20 + --> tests/ui/empty_enum_variants_with_brackets.rs:54:20 | LL | Parentheses(), | ^^ @@ -56,7 +56,7 @@ LL ~ RedundantParenthesesFunctionCall::Parentheses; | error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:76:20 + --> tests/ui/empty_enum_variants_with_brackets.rs:77:20 | LL | Parentheses(), | ^^ @@ -71,12 +71,30 @@ LL ~ Parentheses, | error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:95:13 + --> tests/ui/empty_enum_variants_with_brackets.rs:96:13 | LL | Variant3(), | ^^ | = help: remove the brackets -error: aborting due to 8 previous errors +error: enum variant has empty brackets + --> tests/ui/empty_enum_variants_with_brackets.rs:108:10 + | +LL | V(), + | ^^ + | +help: remove the brackets + | +LL ~ V, +LL | +LL | } +LL | +LL ~ let E::V = E::V; +LL | +LL ~ ::V = E::V; +LL ~ ::V = E::V; + | + +error: aborting due to 9 previous errors From 2cf9b7f5e5713dfe318832f316d38c91687a0843 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Thu, 27 Nov 2025 19:50:38 +0000 Subject: [PATCH 0195/3801] Fix `name()` functions for local defs in rustc_public The `name()` function specifies that it returns absolute path of items, however it wasn't including the crate name for local items. This change fixes that. This was reported here: https://github.com/rust-lang/project-stable-mir/issues/109 --- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- .../rustc_public_bridge/src/context/impls.rs | 7 ++-- tests/ui-fulldeps/rustc_public/check_abi.rs | 10 ++--- .../rustc_public/check_allocation.rs | 10 ++--- .../rustc_public/check_assoc_items.rs | 2 +- .../rustc_public/check_attribute.rs | 11 ++--- .../rustc_public/check_coroutine_body.rs | 19 +++------ .../rustc_public/check_crate_defs.rs | 19 +++++---- .../ui-fulldeps/rustc_public/check_def_ty.rs | 12 +++--- tests/ui-fulldeps/rustc_public/check_defs.rs | 32 +++++++------- .../ui-fulldeps/rustc_public/check_foreign.rs | 4 +- .../rustc_public/check_item_kind.rs | 2 +- .../rustc_public/check_trait_queries.rs | 19 +++++---- .../rustc_public/check_transform.rs | 2 +- .../ui-fulldeps/rustc_public/check_variant.rs | 2 +- .../rustc_public/closure-generic-body.rs | 2 +- .../ui-fulldeps/rustc_public/closure_body.rs | 2 +- tests/ui-fulldeps/rustc_public/crate-info.rs | 42 +++++++++---------- tests/ui-fulldeps/rustc_public/projections.rs | 4 +- 19 files changed, 99 insertions(+), 104 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 06744ae6e242..6a4122ad6717 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -105,7 +105,7 @@ define_helper!( /// /// Overrides `with_crate_prefix`. - // This function is not currently used in-tree, but it's used by a downstream rustc-driver in + // This function is used by `rustc_public` and downstream rustc-driver in // Ferrocene. Please check with them before removing it. fn with_resolve_crate_name(CrateNamePrefixGuard, SHOULD_PREFIX_WITH_CRATE_NAME); /// Adds the `crate::` prefix to paths where appropriate. diff --git a/compiler/rustc_public_bridge/src/context/impls.rs b/compiler/rustc_public_bridge/src/context/impls.rs index cbb00d64e096..1047bbbef69e 100644 --- a/compiler/rustc_public_bridge/src/context/impls.rs +++ b/compiler/rustc_public_bridge/src/context/impls.rs @@ -10,7 +10,7 @@ use rustc_hir::{Attribute, LangItem}; use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; -use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; +use rustc_middle::ty::print::{with_forced_trimmed_paths, with_resolve_crate_name}; use rustc_middle::ty::util::Discr; use rustc_middle::ty::{ AdtDef, AdtKind, AssocItem, Binder, ClosureKind, CoroutineArgsExt, EarlyBinder, @@ -264,7 +264,8 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { if trimmed { with_forced_trimmed_paths!(self.tcx.def_path_str(def_id)) } else { - with_no_trimmed_paths!(self.tcx.def_path_str(def_id)) + // For local definitions, we need to prepend with crate name. + with_resolve_crate_name!(self.tcx.def_path_str(def_id)) } } @@ -724,7 +725,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { self.tcx.def_path_str_with_args(instance.def_id(), instance.args) ) } else { - with_no_trimmed_paths!( + with_resolve_crate_name!( self.tcx.def_path_str_with_args(instance.def_id(), instance.args) ) } diff --git a/tests/ui-fulldeps/rustc_public/check_abi.rs b/tests/ui-fulldeps/rustc_public/check_abi.rs index 57c8377ea367..b3519a2c60ed 100644 --- a/tests/ui-fulldeps/rustc_public/check_abi.rs +++ b/tests/ui-fulldeps/rustc_public/check_abi.rs @@ -9,10 +9,10 @@ #![feature(assert_matches)] #![feature(ascii_char, ascii_char_variants)] -extern crate rustc_hir; -extern crate rustc_middle; extern crate rustc_driver; +extern crate rustc_hir; extern crate rustc_interface; +extern crate rustc_middle; #[macro_use] extern crate rustc_public; @@ -39,7 +39,7 @@ fn test_stable_mir() -> ControlFlow<()> { let items = rustc_public::all_local_items(); // Test fn_abi - let target_fn = *get_item(&items, (ItemKind::Fn, "fn_abi")).unwrap(); + let target_fn = *get_item(&items, (ItemKind::Fn, "input::fn_abi")).unwrap(); let instance = Instance::try_from(target_fn).unwrap(); let fn_abi = instance.fn_abi().unwrap(); assert_eq!(fn_abi.conv, CallConvention::Rust); @@ -51,11 +51,11 @@ fn test_stable_mir() -> ControlFlow<()> { check_result(&fn_abi.ret); // Test variadic function. - let variadic_fn = *get_item(&items, (ItemKind::Fn, "variadic_fn")).unwrap(); + let variadic_fn = *get_item(&items, (ItemKind::Fn, "input::variadic_fn")).unwrap(); check_variadic(variadic_fn); // Extract function pointers. - let fn_ptr_holder = *get_item(&items, (ItemKind::Fn, "fn_ptr_holder")).unwrap(); + let fn_ptr_holder = *get_item(&items, (ItemKind::Fn, "input::fn_ptr_holder")).unwrap(); let fn_ptr_holder_instance = Instance::try_from(fn_ptr_holder).unwrap(); let body = fn_ptr_holder_instance.body().unwrap(); let args = body.arg_locals(); diff --git a/tests/ui-fulldeps/rustc_public/check_allocation.rs b/tests/ui-fulldeps/rustc_public/check_allocation.rs index 70e4ee3fe347..3a0a2382be72 100644 --- a/tests/ui-fulldeps/rustc_public/check_allocation.rs +++ b/tests/ui-fulldeps/rustc_public/check_allocation.rs @@ -40,11 +40,11 @@ const CRATE_NAME: &str = "input"; fn test_stable_mir() -> ControlFlow<()> { // Find items in the local crate. let items = rustc_public::all_local_items(); - check_foo(*get_item(&items, (ItemKind::Static, "FOO")).unwrap()); - check_bar(*get_item(&items, (ItemKind::Static, "BAR")).unwrap()); - check_len(*get_item(&items, (ItemKind::Static, "LEN")).unwrap()); - check_cstr(*get_item(&items, (ItemKind::Static, "C_STR")).unwrap()); - check_other_consts(*get_item(&items, (ItemKind::Fn, "other_consts")).unwrap()); + check_foo(*get_item(&items, (ItemKind::Static, "input::FOO")).unwrap()); + check_bar(*get_item(&items, (ItemKind::Static, "input::BAR")).unwrap()); + check_len(*get_item(&items, (ItemKind::Static, "input::LEN")).unwrap()); + check_cstr(*get_item(&items, (ItemKind::Static, "input::C_STR")).unwrap()); + check_other_consts(*get_item(&items, (ItemKind::Fn, "input::other_consts")).unwrap()); ControlFlow::Continue(()) } diff --git a/tests/ui-fulldeps/rustc_public/check_assoc_items.rs b/tests/ui-fulldeps/rustc_public/check_assoc_items.rs index 1557991f8cab..194d6be88a76 100644 --- a/tests/ui-fulldeps/rustc_public/check_assoc_items.rs +++ b/tests/ui-fulldeps/rustc_public/check_assoc_items.rs @@ -77,7 +77,7 @@ fn test_assoc_items() -> ControlFlow<()> { /// Note that order doesn't matter. fn check_items(items: &[T], expected: &[&str]) { let expected: HashSet<_> = expected.iter().map(|s| s.to_string()).collect(); - let item_names: HashSet<_> = items.iter().map(|item| item.name()).collect(); + let item_names: HashSet<_> = items.iter().map(|item| item.trimmed_name()).collect(); assert_eq!(item_names, expected); } diff --git a/tests/ui-fulldeps/rustc_public/check_attribute.rs b/tests/ui-fulldeps/rustc_public/check_attribute.rs index 0c34ac4dfe95..393ff4c63c5a 100644 --- a/tests/ui-fulldeps/rustc_public/check_attribute.rs +++ b/tests/ui-fulldeps/rustc_public/check_attribute.rs @@ -38,16 +38,13 @@ fn test_tool(items: &CrateItems) { assert_eq!(rustfmt_attrs[0].as_str(), "#[rustfmt::skip]\n"); let clippy_fn = *get_item(&items, "complex_fn").unwrap(); - let clippy_attrs = clippy_fn.tool_attrs(&["clippy".to_string(), - "cyclomatic_complexity".to_string()]); + let clippy_attrs = + clippy_fn.tool_attrs(&["clippy".to_string(), "cyclomatic_complexity".to_string()]); assert_eq!(clippy_attrs[0].as_str(), "#[clippy::cyclomatic_complexity = \"100\"]\n"); } -fn get_item<'a>( - items: &'a CrateItems, - name: &str, -) -> Option<&'a rustc_public::CrateItem> { - items.iter().find(|crate_item| crate_item.name() == name) +fn get_item<'a>(items: &'a CrateItems, name: &str) -> Option<&'a rustc_public::CrateItem> { + items.iter().find(|crate_item| crate_item.trimmed_name() == name) } /// This test will generate and analyze a dummy crate using the stable mir. diff --git a/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs b/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs index 725b538b0fe5..75f4f1f5bf4c 100644 --- a/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs +++ b/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs @@ -29,11 +29,7 @@ fn test_coroutine_body() -> ControlFlow<()> { if let Some(body) = crate_items.iter().find_map(|item| { let item_ty = item.ty(); if let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &item_ty.kind() { - if def.0.name() == "gbc::{closure#0}".to_string() { - def.body() - } else { - None - } + if def.0.trimmed_name() == "gbc::{closure#0}".to_string() { def.body() } else { None } } else { None } @@ -51,26 +47,23 @@ fn check_coroutine_body(body: Body) { let local_3 = &body.locals()[3].ty; let local_4 = &body.locals()[4].ty; - let TyKind::RigidTy(RigidTy::Adt(def, ..)) = &ret_ty.kind() - else { + let TyKind::RigidTy(RigidTy::Adt(def, ..)) = &ret_ty.kind() else { panic!("Expected RigidTy::Adt, got: {:#?}", ret_ty); }; assert_eq!("std::task::Poll", def.0.name()); - let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &local_3.kind() - else { + let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &local_3.kind() else { panic!("Expected RigidTy::Coroutine, got: {:#?}", local_3); }; - assert_eq!("gbc::{closure#0}::{closure#0}", def.0.name()); + assert_eq!("crate_coroutine_body::gbc::{closure#0}::{closure#0}", def.0.name()); - let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &local_4.kind() - else { + let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &local_4.kind() else { panic!("Expected RigidTy::Coroutine, got: {:#?}", local_4); }; - assert_eq!("gbc::{closure#0}::{closure#0}", def.0.name()); + assert_eq!("crate_coroutine_body::gbc::{closure#0}::{closure#0}", def.0.name()); } fn main() { diff --git a/tests/ui-fulldeps/rustc_public/check_crate_defs.rs b/tests/ui-fulldeps/rustc_public/check_crate_defs.rs index 3ca8b66e58dc..7d949eae3910 100644 --- a/tests/ui-fulldeps/rustc_public/check_crate_defs.rs +++ b/tests/ui-fulldeps/rustc_public/check_crate_defs.rs @@ -27,17 +27,20 @@ const CRATE_NAME: &str = "crate_defs"; fn test_stable_mir() -> ControlFlow<()> { // Find items in the local crate. let local = rustc_public::local_crate(); - check_items(&local.statics(), &["PRIVATE_STATIC", "dummy::PUBLIC_STATIC"]); + check_items( + &local.statics(), + &["crate_defs::PRIVATE_STATIC", "crate_defs::dummy::PUBLIC_STATIC"], + ); check_items( &local.fn_defs(), &[ - "top_level", - "dummy::public_fn", - "dummy::private_fn", - "dummy::PrivateStruct::new", - "::drop", - "DummyTrait::method", - "::method", + "crate_defs::top_level", + "crate_defs::dummy::public_fn", + "crate_defs::dummy::private_fn", + "crate_defs::dummy::PrivateStruct::new", + "::drop", + "crate_defs::DummyTrait::method", + "::method", ], ); diff --git a/tests/ui-fulldeps/rustc_public/check_def_ty.rs b/tests/ui-fulldeps/rustc_public/check_def_ty.rs index 4a45bb6daa5f..242b06dcd229 100644 --- a/tests/ui-fulldeps/rustc_public/check_def_ty.rs +++ b/tests/ui-fulldeps/rustc_public/check_def_ty.rs @@ -16,7 +16,7 @@ extern crate rustc_driver; extern crate rustc_interface; extern crate rustc_public; -use rustc_public::ty::{Ty, ForeignItemKind}; +use rustc_public::ty::{ForeignItemKind, Ty}; use rustc_public::*; use std::io::Write; use std::ops::ControlFlow; @@ -29,11 +29,11 @@ fn test_def_tys() -> ControlFlow<()> { for item in &items { // Type from crate items. let ty = item.ty(); - match item.name().as_str() { + match item.trimmed_name().as_str() { "STATIC_STR" => assert!(ty.kind().is_ref()), "CONST_U32" => assert!(ty.kind().is_integral()), - "main" => { check_fn_def(ty) } - _ => unreachable!("Unexpected item: `{item:?}`") + "main" => check_fn_def(ty), + _ => unreachable!("Unexpected item: `{item:?}`"), } } @@ -42,7 +42,7 @@ fn test_def_tys() -> ControlFlow<()> { // Type from foreign items. let ty = item.ty(); let item_kind = item.kind(); - let name = item.name(); + let name = item.trimmed_name(); match item_kind { ForeignItemKind::Fn(fn_def) => { assert_eq!(&name, "extern_fn"); @@ -54,7 +54,7 @@ fn test_def_tys() -> ControlFlow<()> { assert_eq!(ty, def.ty()); assert!(ty.kind().is_integral()) } - _ => unreachable!("Unexpected kind: {item_kind:?}") + _ => unreachable!("Unexpected kind: {item_kind:?}"), }; } diff --git a/tests/ui-fulldeps/rustc_public/check_defs.rs b/tests/ui-fulldeps/rustc_public/check_defs.rs index 0c45859a132a..e6f9fb9972b0 100644 --- a/tests/ui-fulldeps/rustc_public/check_defs.rs +++ b/tests/ui-fulldeps/rustc_public/check_defs.rs @@ -15,11 +15,11 @@ extern crate rustc_driver; extern crate rustc_interface; extern crate rustc_public; -use std::assert_matches::assert_matches; -use mir::{mono::Instance, TerminatorKind::*}; +use mir::{TerminatorKind::*, mono::Instance}; use rustc_public::mir::mono::InstanceKind; -use rustc_public::ty::{RigidTy, TyKind, Ty, UintTy}; +use rustc_public::ty::{RigidTy, Ty, TyKind, UintTy}; use rustc_public::*; +use std::assert_matches::assert_matches; use std::io::Write; use std::ops::ControlFlow; @@ -29,7 +29,7 @@ const CRATE_NAME: &str = "input"; fn test_stable_mir() -> ControlFlow<()> { let entry = rustc_public::entry_fn().unwrap(); let main_fn = Instance::try_from(entry).unwrap(); - assert_eq!(main_fn.name(), "main"); + assert_eq!(main_fn.name(), "input::main"); assert_eq!(main_fn.trimmed_name(), "main"); let instances = get_instances(main_fn.body().unwrap()); @@ -65,10 +65,8 @@ fn test_fn(instance: Instance, expected_trimmed: &str, expected_qualified: &str, fn extract_elem_ty(ty: Ty) -> Ty { match ty.kind() { - TyKind::RigidTy(RigidTy::Adt(_, args)) => { - *args.0[0].expect_ty() - } - _ => unreachable!("Expected Vec ADT, but found: {ty:?}") + TyKind::RigidTy(RigidTy::Adt(_, args)) => *args.0[0].expect_ty(), + _ => unreachable!("Expected Vec ADT, but found: {ty:?}"), } } @@ -89,19 +87,19 @@ fn test_vec_new(instance: mir::mono::Instance) { /// Inspect the instance body fn get_instances(body: mir::Body) -> Vec { - body.blocks.iter().filter_map(|bb| { - match &bb.terminator.kind { + body.blocks + .iter() + .filter_map(|bb| match &bb.terminator.kind { Call { func, .. } => { - let TyKind::RigidTy(ty) = func.ty(body.locals()).unwrap().kind() else { unreachable! - () }; + let TyKind::RigidTy(ty) = func.ty(body.locals()).unwrap().kind() else { + unreachable!() + }; let RigidTy::FnDef(def, args) = ty else { unreachable!() }; Instance::resolve(def, &args).ok() } - _ => { - None - } - } - }).collect::>() + _ => None, + }) + .collect::>() } /// This test will generate and analyze a dummy crate using the stable mir. diff --git a/tests/ui-fulldeps/rustc_public/check_foreign.rs b/tests/ui-fulldeps/rustc_public/check_foreign.rs index 78b62594c618..bd34fb5cf8a8 100644 --- a/tests/ui-fulldeps/rustc_public/check_foreign.rs +++ b/tests/ui-fulldeps/rustc_public/check_foreign.rs @@ -13,8 +13,8 @@ extern crate rustc_middle; extern crate rustc_driver; extern crate rustc_interface; -extern crate rustc_span; extern crate rustc_public; +extern crate rustc_span; use rustc_public::{ ty::{Abi, ForeignItemKind}, @@ -40,7 +40,7 @@ fn test_foreign() -> ControlFlow<()> { assert_eq!(c_items.len(), 3); for item in c_items { let kind = item.kind(); - match item.name().as_str() { + match item.trimmed_name().as_str() { "foo" => assert_matches!(kind, ForeignItemKind::Fn(..)), "bar" => assert_matches!(kind, ForeignItemKind::Static(..)), "Baz" => assert_matches!(kind, ForeignItemKind::Type(..)), diff --git a/tests/ui-fulldeps/rustc_public/check_item_kind.rs b/tests/ui-fulldeps/rustc_public/check_item_kind.rs index b759628f1a42..c687b3af1c63 100644 --- a/tests/ui-fulldeps/rustc_public/check_item_kind.rs +++ b/tests/ui-fulldeps/rustc_public/check_item_kind.rs @@ -27,7 +27,7 @@ fn test_item_kind() -> ControlFlow<()> { assert_eq!(items.len(), 4); // Constructor item. for item in items { - let expected_kind = match item.name().as_str() { + let expected_kind = match item.trimmed_name().as_str() { "Dummy" => ItemKind::Ctor(CtorKind::Fn), "dummy" => ItemKind::Fn, "unit" => ItemKind::Fn, diff --git a/tests/ui-fulldeps/rustc_public/check_trait_queries.rs b/tests/ui-fulldeps/rustc_public/check_trait_queries.rs index 0dd13044fcce..5603add82f59 100644 --- a/tests/ui-fulldeps/rustc_public/check_trait_queries.rs +++ b/tests/ui-fulldeps/rustc_public/check_trait_queries.rs @@ -28,19 +28,20 @@ fn test_traits() -> ControlFlow<()> { let local_crate = rustc_public::local_crate(); let local_traits = local_crate.trait_decls(); assert_eq!(local_traits.len(), 1, "Expected `Max` trait, but found {:?}", local_traits); - assert_eq!(&local_traits[0].name(), "Max"); + assert_eq!(&local_traits[0].trimmed_name(), "Max"); let local_impls = local_crate.trait_impls(); - let impl_names = local_impls.iter().map(|trait_impl| trait_impl.name()).collect::>(); + let impl_names = + local_impls.iter().map(|trait_impl| trait_impl.trimmed_name()).collect::>(); assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ">"); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ">"); assert_impl(&impl_names, ""); - assert_impl(&impl_names, " for u64>"); + assert_impl(&impl_names, " for u64>"); let all_traits = rustc_public::all_trait_decls(); assert!(all_traits.len() > local_traits.len()); diff --git a/tests/ui-fulldeps/rustc_public/check_transform.rs b/tests/ui-fulldeps/rustc_public/check_transform.rs index b30d98c3b26f..900bb4014d54 100644 --- a/tests/ui-fulldeps/rustc_public/check_transform.rs +++ b/tests/ui-fulldeps/rustc_public/check_transform.rs @@ -34,7 +34,7 @@ fn test_transform() -> ControlFlow<()> { let items = rustc_public::all_local_items(); // Test fn_abi - let target_fn = *get_item(&items, (ItemKind::Fn, "dummy")).unwrap(); + let target_fn = *get_item(&items, (ItemKind::Fn, "input::dummy")).unwrap(); let instance = Instance::try_from(target_fn).unwrap(); let body = instance.body().unwrap(); check_msg(&body, "oops"); diff --git a/tests/ui-fulldeps/rustc_public/check_variant.rs b/tests/ui-fulldeps/rustc_public/check_variant.rs index 9ed16f2357c0..9bdd0c9d80ba 100644 --- a/tests/ui-fulldeps/rustc_public/check_variant.rs +++ b/tests/ui-fulldeps/rustc_public/check_variant.rs @@ -97,7 +97,7 @@ fn check_adt_poly2() { } fn get_fn(name: &str) -> CrateItem { - rustc_public::all_local_items().into_iter().find(|it| it.name().eq(name)).unwrap() + rustc_public::all_local_items().into_iter().find(|it| it.trimmed_name().eq(name)).unwrap() } fn check_statement_is_aggregate_assign( diff --git a/tests/ui-fulldeps/rustc_public/closure-generic-body.rs b/tests/ui-fulldeps/rustc_public/closure-generic-body.rs index e5f910fbda11..46aeca76ba65 100644 --- a/tests/ui-fulldeps/rustc_public/closure-generic-body.rs +++ b/tests/ui-fulldeps/rustc_public/closure-generic-body.rs @@ -52,7 +52,7 @@ fn check_incr_closure_body(body: Body) { panic!("expected FnDef"); }; - assert_eq!(def_id.name(), "id"); + assert_eq!(def_id.trimmed_name(), "id"); } fn main() { diff --git a/tests/ui-fulldeps/rustc_public/closure_body.rs b/tests/ui-fulldeps/rustc_public/closure_body.rs index f5f9f23ad126..43cbca8baab8 100644 --- a/tests/ui-fulldeps/rustc_public/closure_body.rs +++ b/tests/ui-fulldeps/rustc_public/closure_body.rs @@ -52,7 +52,7 @@ fn check_incr_closure_body(body: Body) { panic!("expected FnDef"); }; - assert_eq!(def_id.name(), "incr"); + assert_eq!(def_id.name(), "crate_closure_body::incr"); } fn main() { diff --git a/tests/ui-fulldeps/rustc_public/crate-info.rs b/tests/ui-fulldeps/rustc_public/crate-info.rs index 19082d7394ab..06cbbfcd69ec 100644 --- a/tests/ui-fulldeps/rustc_public/crate-info.rs +++ b/tests/ui-fulldeps/rustc_public/crate-info.rs @@ -38,12 +38,12 @@ fn test_stable_mir() -> ControlFlow<()> { // Find items in the local crate. let items = rustc_public::all_local_items(); - assert!(get_item(&items, (DefKind::Fn, "foo::bar")).is_some()); + assert!(get_item(&items, (DefKind::Fn, "input::foo::bar")).is_some()); // Find the `std` crate and assert that there is only one of it. assert!(rustc_public::find_crates("std").len() == 1); - let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap(); + let bar = get_item(&items, (DefKind::Fn, "input::bar")).unwrap(); let body = bar.expect_body(); assert_eq!(body.locals().len(), 2); assert_eq!(body.blocks.len(), 1); @@ -58,7 +58,7 @@ fn test_stable_mir() -> ControlFlow<()> { other => panic!("{other:?}"), } - let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap(); + let foo_bar = get_item(&items, (DefKind::Fn, "input::foo_bar")).unwrap(); let body = foo_bar.expect_body(); assert_eq!(body.locals().len(), 5); assert_eq!(body.blocks.len(), 4); @@ -68,7 +68,7 @@ fn test_stable_mir() -> ControlFlow<()> { other => panic!("{other:?}"), } - let types = get_item(&items, (DefKind::Fn, "types")).unwrap(); + let types = get_item(&items, (DefKind::Fn, "input::types")).unwrap(); let body = types.expect_body(); assert_eq!(body.locals().len(), 6); assert_matches!( @@ -85,15 +85,15 @@ fn test_stable_mir() -> ControlFlow<()> { ); assert_matches!( body.locals()[3].ty.kind(), - rustc_public::ty::TyKind::RigidTy( - rustc_public::ty::RigidTy::Int(rustc_public::ty::IntTy::I32) - ) + rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::Int( + rustc_public::ty::IntTy::I32 + )) ); assert_matches!( body.locals()[4].ty.kind(), - rustc_public::ty::TyKind::RigidTy( - rustc_public::ty::RigidTy::Uint(rustc_public::ty::UintTy::U64) - ) + rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::Uint( + rustc_public::ty::UintTy::U64 + )) ); assert_matches!( body.locals()[5].ty.kind(), @@ -102,7 +102,7 @@ fn test_stable_mir() -> ControlFlow<()> { )) ); - let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap(); + let drop = get_item(&items, (DefKind::Fn, "input::drop")).unwrap(); let body = drop.expect_body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; @@ -111,7 +111,7 @@ fn test_stable_mir() -> ControlFlow<()> { other => panic!("{other:?}"), } - let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap(); + let assert = get_item(&items, (DefKind::Fn, "input::assert")).unwrap(); let body = assert.expect_body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; @@ -120,7 +120,7 @@ fn test_stable_mir() -> ControlFlow<()> { other => panic!("{other:?}"), } - let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap(); + let monomorphic = get_item(&items, (DefKind::Fn, "input::monomorphic")).unwrap(); let instance = Instance::try_from(monomorphic.clone()).unwrap(); for block in instance.body().unwrap().blocks { match &block.terminator.kind { @@ -140,11 +140,11 @@ fn test_stable_mir() -> ControlFlow<()> { } } - let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap(); + let foo_const = get_item(&items, (DefKind::Const, "input::FOO")).unwrap(); // Ensure we don't panic trying to get the body of a constant. foo_const.expect_body(); - let locals_fn = get_item(&items, (DefKind::Fn, "locals")).unwrap(); + let locals_fn = get_item(&items, (DefKind::Fn, "input::locals")).unwrap(); let body = locals_fn.expect_body(); assert_eq!(body.locals().len(), 4); assert_matches!( @@ -154,15 +154,15 @@ fn test_stable_mir() -> ControlFlow<()> { assert_eq!(body.arg_locals().len(), 2); assert_matches!( body.arg_locals()[0].ty.kind(), - rustc_public::ty::TyKind::RigidTy( - rustc_public::ty::RigidTy::Int(rustc_public::ty::IntTy::I32) - ) + rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::Int( + rustc_public::ty::IntTy::I32 + )) ); assert_matches!( body.arg_locals()[1].ty.kind(), - rustc_public::ty::TyKind::RigidTy( - rustc_public::ty::RigidTy::Uint(rustc_public::ty::UintTy::U64) - ) + rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::Uint( + rustc_public::ty::UintTy::U64 + )) ); assert_eq!(body.inner_locals().len(), 1); // If conditions have an extra inner local to hold their results diff --git a/tests/ui-fulldeps/rustc_public/projections.rs b/tests/ui-fulldeps/rustc_public/projections.rs index e0213b4253c7..c1cdb5374d46 100644 --- a/tests/ui-fulldeps/rustc_public/projections.rs +++ b/tests/ui-fulldeps/rustc_public/projections.rs @@ -136,7 +136,9 @@ fn get_item<'a>( items: &'a rustc_public::CrateItems, item: (ItemKind, &str), ) -> Option<&'a rustc_public::CrateItem> { - items.iter().find(|crate_item| crate_item.kind() == item.0 && crate_item.name() == item.1) + items + .iter() + .find(|crate_item| crate_item.kind() == item.0 && crate_item.trimmed_name() == item.1) } /// This test will generate and analyze a dummy crate using the stable mir. From 7b2284ce11d917ed797edbde985324e90be07718 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 1 Dec 2025 02:31:30 +0200 Subject: [PATCH 0196/3801] Register `define_opaque` builtin attribute macro So that we'll correctly treat it as an attribute. I don't like that we have to register every builtin macro even if we don't need it, but that's what we got. --- .../hir-expand/src/builtin/attr_macro.rs | 5 +- .../ide-completion/src/tests/attribute.rs | 52 +++++++++++++++++++ .../crates/intern/src/symbol/symbols.rs | 1 + 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs index 25dd933f2677..06b9b5418e37 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs @@ -7,7 +7,7 @@ use crate::{ExpandResult, MacroCallId, MacroCallKind, db::ExpandDatabase, name, use super::quote; macro_rules! register_builtin { - ($(($name:ident, $variant:ident) => $expand:ident),* ) => { + ($(($name:ident, $variant:ident) => $expand:ident),* $(,)? ) => { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinAttrExpander { $($variant),* @@ -65,7 +65,8 @@ register_builtin! { (derive_const, DeriveConst) => derive_expand, (global_allocator, GlobalAllocator) => dummy_attr_expand, (test, Test) => dummy_gate_test_expand, - (test_case, TestCase) => dummy_gate_test_expand + (test_case, TestCase) => dummy_gate_test_expand, + (define_opaque, DefineOpaque) => dummy_attr_expand, } pub fn find_builtin_attr(ident: &name::Name) -> Option { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs index 9ff490f9049a..3701416dfc84 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs @@ -1508,3 +1508,55 @@ extern crate dep; ) } } + +#[test] +fn builtin_macro_completed_only_as_its_kind() { + check( + r#" +#[rustc_builtin_macro] +pub macro define_opaque($($tt:tt)*) { + /* compiler built-in */ +} + +fn foo() { + def$0 +} + "#, + expect![[r#" + fn foo() fn() + bt u32 u32 + kw async + kw const + kw crate:: + kw enum + kw extern + kw false + kw fn + kw for + kw if + kw if let + kw impl + kw impl for + kw let + kw letm + kw loop + kw match + kw mod + kw return + kw self:: + kw static + kw struct + kw trait + kw true + kw type + kw union + kw unsafe + kw use + kw while + kw while let + sn macro_rules + sn pd + sn ppd + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 37eb3d4101c6..462f1c69fa69 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -524,4 +524,5 @@ define_symbols! { arbitrary_self_types, arbitrary_self_types_pointers, supertrait_item_shadowing, + define_opaque, } From bb2bfc3f3fd3fdda775dc5e2e20e85d0b18b3b24 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Fri, 28 Nov 2025 19:29:14 +0000 Subject: [PATCH 0197/3801] Fix name and pretty print now uses trimmed_name --- compiler/rustc_public/src/lib.rs | 2 +- compiler/rustc_public/src/mir/pretty.rs | 2 +- compiler/rustc_public/src/ty.rs | 3 ++ .../rustc_public_bridge/src/context/impls.rs | 10 ++++--- .../rustc_public/check_def_parent.rs | 30 +++++++++++-------- .../ui-fulldeps/rustc_public/check_def_ty.rs | 14 ++++++++- .../async-closure.stdout | 4 +-- .../ui/rustc_public-ir-print/operands.stdout | 16 +++++----- 8 files changed, 51 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index f470eebc8b38..5da79196dd4e 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -178,7 +178,7 @@ impl CrateItem { pub fn emit_mir(&self, w: &mut W) -> io::Result<()> { self.body() .ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))? - .dump(w, &self.name()) + .dump(w, &self.trimmed_name()) } } diff --git a/compiler/rustc_public/src/mir/pretty.rs b/compiler/rustc_public/src/mir/pretty.rs index d80e227f5a9c..08e4e0c7e0f9 100644 --- a/compiler/rustc_public/src/mir/pretty.rs +++ b/compiler/rustc_public/src/mir/pretty.rs @@ -412,7 +412,7 @@ fn pretty_aggregate( } AggregateKind::Adt(def, var, _, _, _) => { if def.kind() == AdtKind::Enum { - write!(writer, "{}::{}", def.name(), def.variant(*var).unwrap().name())?; + write!(writer, "{}::{}", def.trimmed_name(), def.variant(*var).unwrap().name())?; } else { write!(writer, "{}", def.variant(*var).unwrap().name())?; } diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index f24d98f7e552..14656a2e594a 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -876,6 +876,9 @@ pub struct VariantDef { } impl VariantDef { + /// The name of the variant, struct or union. + /// + /// This will not include the name of the enum or qualified path. pub fn name(&self) -> Symbol { with(|cx| cx.variant_name(*self)) } diff --git a/compiler/rustc_public_bridge/src/context/impls.rs b/compiler/rustc_public_bridge/src/context/impls.rs index 1047bbbef69e..26728a34b84a 100644 --- a/compiler/rustc_public_bridge/src/context/impls.rs +++ b/compiler/rustc_public_bridge/src/context/impls.rs @@ -10,7 +10,9 @@ use rustc_hir::{Attribute, LangItem}; use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; -use rustc_middle::ty::print::{with_forced_trimmed_paths, with_resolve_crate_name}; +use rustc_middle::ty::print::{ + with_forced_trimmed_paths, with_no_trimmed_paths, with_resolve_crate_name, +}; use rustc_middle::ty::util::Discr; use rustc_middle::ty::{ AdtDef, AdtKind, AssocItem, Binder, ClosureKind, CoroutineArgsExt, EarlyBinder, @@ -265,7 +267,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { with_forced_trimmed_paths!(self.tcx.def_path_str(def_id)) } else { // For local definitions, we need to prepend with crate name. - with_resolve_crate_name!(self.tcx.def_path_str(def_id)) + with_resolve_crate_name!(with_no_trimmed_paths!(self.tcx.def_path_str(def_id))) } } @@ -725,9 +727,9 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { self.tcx.def_path_str_with_args(instance.def_id(), instance.args) ) } else { - with_resolve_crate_name!( + with_resolve_crate_name!(with_no_trimmed_paths!( self.tcx.def_path_str_with_args(instance.def_id(), instance.args) - ) + )) } } diff --git a/tests/ui-fulldeps/rustc_public/check_def_parent.rs b/tests/ui-fulldeps/rustc_public/check_def_parent.rs index 192ad471de33..7f633a627b19 100644 --- a/tests/ui-fulldeps/rustc_public/check_def_parent.rs +++ b/tests/ui-fulldeps/rustc_public/check_def_parent.rs @@ -47,44 +47,47 @@ fn test_stable_mir() -> ControlFlow<()> { let krate = rustc_public::local_crate(); for it in rustc_public::all_local_items() { match &*it.0.name() { - "wrapper_mod::CONST_ITEM" => { + "input::wrapper_mod::CONST_ITEM" => { set_once(&mut const_item, it.0); } - "wrapper_mod::STATIC_ITEM" => { + "input::wrapper_mod::STATIC_ITEM" => { set_once(&mut static_item, it.0); } - "::trait_method" => { + "::trait_method" => { set_once(&mut trait_method, it.0); } - "::trait_method::trait_method_helper" => { + "::trait_method::trait_method_helper" => + { set_once(&mut trait_method_helper, it.0); } - "wrapper_mod::MyStruct::inherent_method" => { + "input::wrapper_mod::MyStruct::inherent_method" => { set_once(&mut inherent_method, it.0); } - "wrapper_mod::MyStruct::inherent_method::inherent_method_helper" => { + "input::wrapper_mod::MyStruct::inherent_method::inherent_method_helper" => { set_once(&mut inherent_method_helper, it.0); } - "main" => { + "input::main" => { set_once(&mut main, it.0); } - "wrapper_mod::MyStruct" => { + "input::wrapper_mod::MyStruct" => { set_once(&mut mystruct_ctor, it.0); mystruct_ctor_ty = Some(it.ty()); } - _ => (), + name => panic!("Unexpected item: `{name}`"), } } for it in krate.trait_decls() { match &*it.0.name() { - "wrapper_mod::MyTrait" => set_once(&mut trait_decl, it.0), + "input::wrapper_mod::MyTrait" => set_once(&mut trait_decl, it.0), _ => (), } } for it in krate.trait_impls() { match &*it.0.name() { - "" => set_once(&mut trait_impl, it.0), - _ => (), + "" => { + set_once(&mut trait_impl, it.0) + } + name => panic!("Unexpected trait impl: `{name}`"), } } @@ -106,9 +109,10 @@ fn test_stable_mir() -> ControlFlow<()> { let inherent_impl = inherent_method.parent().unwrap(); let wrapper_mod = const_item.parent().unwrap(); let crate_root = wrapper_mod.parent().unwrap(); - assert_eq!(&*wrapper_mod.name(), "wrapper_mod"); + assert_eq!(&*wrapper_mod.name(), "input::wrapper_mod"); // Check that each def-id has the correct parent + assert_eq!(crate_root.name(), "input"); assert_eq!(crate_root.parent(), None); assert_eq!(inherent_impl.parent(), Some(wrapper_mod)); assert_eq!(const_item.parent(), Some(wrapper_mod)); diff --git a/tests/ui-fulldeps/rustc_public/check_def_ty.rs b/tests/ui-fulldeps/rustc_public/check_def_ty.rs index 242b06dcd229..5984d6f8821a 100644 --- a/tests/ui-fulldeps/rustc_public/check_def_ty.rs +++ b/tests/ui-fulldeps/rustc_public/check_def_ty.rs @@ -15,9 +15,12 @@ extern crate rustc_middle; extern crate rustc_driver; extern crate rustc_interface; extern crate rustc_public; +extern crate rustc_public_bridge; -use rustc_public::ty::{ForeignItemKind, Ty}; +use rustc_public::ty::VariantIdx; +use rustc_public::ty::{ForeignItemKind, RigidTy, Ty}; use rustc_public::*; +use rustc_public_bridge::IndexedVal; use std::io::Write; use std::ops::ControlFlow; @@ -32,6 +35,14 @@ fn test_def_tys() -> ControlFlow<()> { match item.trimmed_name().as_str() { "STATIC_STR" => assert!(ty.kind().is_ref()), "CONST_U32" => assert!(ty.kind().is_integral()), + "NONE" => { + let RigidTy::Adt(adt, _) = *ty.kind().rigid().unwrap() else { panic!() }; + // Definition names include the entire path. + assert_eq!(adt.name(), "std::option::Option"); + // Variant name only includes the actual variant name. + // I know, probably not the best name schema. o.O + assert_eq!(adt.variant(VariantIdx::to_val(0)).unwrap().name(), "None"); + } "main" => check_fn_def(ty), _ => unreachable!("Unexpected item: `{item:?}`"), } @@ -92,6 +103,7 @@ fn generate_input(path: &str) -> std::io::Result<()> { r#" static STATIC_STR: &str = "foo"; const CONST_U32: u32 = 0u32; + static NONE: Option = Option::None; fn main() {{ let _c = core::char::from_u32(99); diff --git a/tests/ui/rustc_public-ir-print/async-closure.stdout b/tests/ui/rustc_public-ir-print/async-closure.stdout index 3ec816b657f4..8df31e2f680a 100644 --- a/tests/ui/rustc_public-ir-print/async-closure.stdout +++ b/tests/ui/rustc_public-ir-print/async-closure.stdout @@ -56,7 +56,7 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo _3 = (*_4); _5 = (); StorageDead(_3); - _0 = std::task::Poll::Ready(move _5); + _0 = Poll::Ready(move _5); discriminant((*_7)) = 1; return; } @@ -88,7 +88,7 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c _3 = (*_4); _5 = (); StorageDead(_3); - _0 = std::task::Poll::Ready(move _5); + _0 = Poll::Ready(move _5); discriminant((*_7)) = 1; return; } diff --git a/tests/ui/rustc_public-ir-print/operands.stdout b/tests/ui/rustc_public-ir-print/operands.stdout index b7775416af85..58f229be2e6e 100644 --- a/tests/ui/rustc_public-ir-print/operands.stdout +++ b/tests/ui/rustc_public-ir-print/operands.stdout @@ -206,7 +206,7 @@ fn operands(_1: u8) -> () { StorageDead(_19); StorageDead(_18); StorageLive(_21); - _21 = core::panicking::AssertKind::Eq; + _21 = AssertKind::Eq; StorageLive(_22); StorageLive(_23); _23 = move _21; @@ -219,7 +219,7 @@ fn operands(_1: u8) -> () { _27 = &(*_16); _26 = &(*_27); StorageLive(_28); - _28 = std::option::Option::None; + _28 = Option::None; _22 = core::panicking::assert_failed::(move _23, move _24, move _26, move _28) -> unwind unreachable; } bb6: { @@ -268,7 +268,7 @@ fn operands(_1: u8) -> () { StorageDead(_39); StorageDead(_38); StorageLive(_41); - _41 = core::panicking::AssertKind::Eq; + _41 = AssertKind::Eq; StorageLive(_42); StorageLive(_43); _43 = move _41; @@ -281,7 +281,7 @@ fn operands(_1: u8) -> () { _47 = &(*_36); _46 = &(*_47); StorageLive(_48); - _48 = std::option::Option::None; + _48 = Option::None; _42 = core::panicking::assert_failed::(move _43, move _44, move _46, move _48) -> unwind unreachable; } bb8: { @@ -305,7 +305,7 @@ fn operands(_1: u8) -> () { StorageDead(_62); StorageDead(_61); StorageLive(_64); - _64 = core::panicking::AssertKind::Eq; + _64 = AssertKind::Eq; StorageLive(_65); StorageLive(_66); _66 = move _64; @@ -318,7 +318,7 @@ fn operands(_1: u8) -> () { _70 = &(*_59); _69 = &(*_70); StorageLive(_71); - _71 = std::option::Option::None; + _71 = Option::None; _65 = core::panicking::assert_failed::(move _66, move _67, move _69, move _71) -> unwind unreachable; } bb10: { @@ -380,7 +380,7 @@ fn operands(_1: u8) -> () { StorageDead(_86); StorageDead(_85); StorageLive(_88); - _88 = core::panicking::AssertKind::Eq; + _88 = AssertKind::Eq; StorageLive(_89); StorageLive(_90); _90 = move _88; @@ -393,7 +393,7 @@ fn operands(_1: u8) -> () { _94 = &(*_83); _93 = &(*_94); StorageLive(_95); - _95 = std::option::Option::None; + _95 = Option::None; _89 = core::panicking::assert_failed::(move _90, move _91, move _93, move _95) -> unwind unreachable; } } From c5e928d5ac9a65e237aa8158a30c0cca35d30356 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 1 Dec 2025 04:28:14 +0000 Subject: [PATCH 0198/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to dfe1b8c97bcde283102f706d5dcdc3649e5e12e3. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index bddb68a06b02..7a84872f266d 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -1be6b13be73dc12e98e51b403add4c41a0b77759 +dfe1b8c97bcde283102f706d5dcdc3649e5e12e3 From 18d0c379048a59966c22af0b602c924498d517bb Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Mon, 1 Dec 2025 18:55:14 +0900 Subject: [PATCH 0199/3801] moved tests --- tests/ui/{issues/issue-3290.rs => box/self-assignment.rs} | 0 .../break-continue-in-loop-while-condition-1.rs} | 0 .../break-continue-in-loop-while-condition-1.stderr} | 0 .../break-continue-in-loop-while-condition-2.rs} | 0 .../break-continue-in-loop-while-condition-2.stderr} | 0 .../issue-3680.rs => match/match-option-result-mismatch.rs} | 0 .../match-option-result-mismatch.stderr} | 0 tests/ui/{issues/issue-3091.rs => numeric/ref-int.rs} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-3290.rs => box/self-assignment.rs} (100%) rename tests/ui/{issues/issue-37576.rs => for-loop-while/break-continue-in-loop-while-condition-1.rs} (100%) rename tests/ui/{issues/issue-37576.stderr => for-loop-while/break-continue-in-loop-while-condition-1.stderr} (100%) rename tests/ui/{issues/issue-50802.rs => for-loop-while/break-continue-in-loop-while-condition-2.rs} (100%) rename tests/ui/{issues/issue-50802.stderr => for-loop-while/break-continue-in-loop-while-condition-2.stderr} (100%) rename tests/ui/{issues/issue-3680.rs => match/match-option-result-mismatch.rs} (100%) rename tests/ui/{issues/issue-3680.stderr => match/match-option-result-mismatch.stderr} (100%) rename tests/ui/{issues/issue-3091.rs => numeric/ref-int.rs} (100%) diff --git a/tests/ui/issues/issue-3290.rs b/tests/ui/box/self-assignment.rs similarity index 100% rename from tests/ui/issues/issue-3290.rs rename to tests/ui/box/self-assignment.rs diff --git a/tests/ui/issues/issue-37576.rs b/tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.rs similarity index 100% rename from tests/ui/issues/issue-37576.rs rename to tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.rs diff --git a/tests/ui/issues/issue-37576.stderr b/tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.stderr similarity index 100% rename from tests/ui/issues/issue-37576.stderr rename to tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.stderr diff --git a/tests/ui/issues/issue-50802.rs b/tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.rs similarity index 100% rename from tests/ui/issues/issue-50802.rs rename to tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.rs diff --git a/tests/ui/issues/issue-50802.stderr b/tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.stderr similarity index 100% rename from tests/ui/issues/issue-50802.stderr rename to tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.stderr diff --git a/tests/ui/issues/issue-3680.rs b/tests/ui/match/match-option-result-mismatch.rs similarity index 100% rename from tests/ui/issues/issue-3680.rs rename to tests/ui/match/match-option-result-mismatch.rs diff --git a/tests/ui/issues/issue-3680.stderr b/tests/ui/match/match-option-result-mismatch.stderr similarity index 100% rename from tests/ui/issues/issue-3680.stderr rename to tests/ui/match/match-option-result-mismatch.stderr diff --git a/tests/ui/issues/issue-3091.rs b/tests/ui/numeric/ref-int.rs similarity index 100% rename from tests/ui/issues/issue-3091.rs rename to tests/ui/numeric/ref-int.rs From 4e1e17e80038a57354fef4dd2a72a1030606e8e0 Mon Sep 17 00:00:00 2001 From: Nicolas Guichard Date: Mon, 22 Sep 2025 20:07:48 +0200 Subject: [PATCH 0200/3801] Include operator overload occurrences in SCIP index Operators were explicitly filtered out, both when filtering tokens to search definitions for and when searching for actual definitions. --- .../crates/ide/src/static_index.rs | 22 +++++++----------- .../crates/rust-analyzer/src/cli/scip.rs | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 0cf2e15bc6f0..625cc888c84c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -10,7 +10,7 @@ use ide_db::{ documentation::Documentation, famous_defs::FamousDefs, }; -use syntax::{AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, T, TextRange}; +use syntax::{AstNode, SyntaxNode, SyntaxToken, TextRange}; use crate::navigation_target::UpmappingResult; use crate::{ @@ -136,12 +136,12 @@ fn documentation_for_definition( } // FIXME: This is a weird function -fn get_definitions( - sema: &Semantics<'_, RootDatabase>, +fn get_definitions<'db>( + sema: &Semantics<'db, RootDatabase>, token: SyntaxToken, -) -> Option> { +) -> Option>), 2>> { for token in sema.descend_into_macros_exact(token) { - let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops); + let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions); if let Some(defs) = def && !defs.is_empty() { @@ -225,12 +225,6 @@ impl StaticIndex<'_> { show_drop_glue: true, minicore: MiniCore::default(), }; - let tokens = tokens.filter(|token| { - matches!( - token.kind(), - IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | T![Self] - ) - }); let mut result = StaticIndexedFile { file_id, inlay_hints, folds, tokens: vec![] }; let mut add_token = |def: Definition, range: TextRange, scope_node: &SyntaxNode| { @@ -290,9 +284,9 @@ impl StaticIndex<'_> { let range = token.text_range(); let node = token.parent().unwrap(); match hir::attach_db(self.db, || get_definitions(&sema, token.clone())) { - Some(it) => { - for i in it { - add_token(i, range, &node); + Some(defs) => { + for (def, _) in defs { + add_token(def, range, &node); } } None => continue, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs index fbf3082e1b89..271d2507bcfe 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs @@ -603,6 +603,29 @@ pub mod example_mod { ); } + #[test] + fn operator_overload() { + check_symbol( + r#" +//- minicore: add +//- /workspace/lib.rs crate:main +use core::ops::AddAssign; + +struct S; + +impl AddAssign for S { + fn add_assign(&mut self, _rhs: Self) {} +} + +fn main() { + let mut s = S; + s +=$0 S; +} +"#, + "rust-analyzer cargo main . impl#[S][`AddAssign`]add_assign().", + ); + } + #[test] fn symbol_for_trait() { check_symbol( From 0f5b29a4d46ca2a89f1979242f7abfa104b28c50 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 1 Dec 2025 13:29:33 +0100 Subject: [PATCH 0201/3801] add invariant --- src/doc/rustc-dev-guide/src/solve/invariants.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/solve/invariants.md b/src/doc/rustc-dev-guide/src/solve/invariants.md index 8ec15f339e51..bdf974099f2f 100644 --- a/src/doc/rustc-dev-guide/src/solve/invariants.md +++ b/src/doc/rustc-dev-guide/src/solve/invariants.md @@ -116,6 +116,12 @@ We do however break this invariant in a few cases, some of which are due to bugs - the builtin trait object trait implementation can overlap with a user-defined impl: [#57893](https://github.com/rust-lang/rust/issues/57893) +### Goals with can be proven in a non-empty environment also hold during monomorphization ✅ + +If a goal can be proven in a generic environment, the goal should still hold after instantiating +it with fully concrete types and no where-clauses in scope. + +This is assumed by codegen whicih ICEs when encountering non-overflow ambiguity. This invariant is currently broken by specialization ([#147507](https://github.com/rust-lang/rust/issues/147507)) and by marker traits ([#149502](https://github.com/rust-lang/rust/issues/149502)). #### The type system is complete during the implicit negative overlap check in coherence ✅ From 7fa80495eadbcde54a59fb8a894b04aaa321db5a Mon Sep 17 00:00:00 2001 From: Young-Flash Date: Mon, 1 Dec 2025 22:05:24 +0800 Subject: [PATCH 0202/3801] internal: add missing method for `SyntaxFactory` --- .../src/ast/syntax_factory/constructors.rs | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 969552392180..9847d639d613 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -71,6 +71,189 @@ impl SyntaxFactory { ast } + + pub fn path_from_text(&self, text: &str) -> ast::Path { + make::path_from_text(text).clone_for_update() + } + + pub fn expr_field(&self, receiver: ast::Expr, field: &str) -> ast::FieldExpr { + let ast::Expr::FieldExpr(ast) = + make::expr_field(receiver.clone(), field).clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(receiver.syntax().clone(), ast.expr().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn impl_trait( + &self, + attrs: impl IntoIterator, + is_unsafe: bool, + trait_gen_params: Option, + trait_gen_args: Option, + type_gen_params: Option, + type_gen_args: Option, + is_negative: bool, + path_type: ast::Type, + ty: ast::Type, + trait_where_clause: Option, + ty_where_clause: Option, + body: Option, + ) -> ast::Impl { + let (attrs, attrs_input) = iterator_input(attrs); + let ast = make::impl_trait( + attrs, + is_unsafe, + trait_gen_params.clone(), + trait_gen_args.clone(), + type_gen_params.clone(), + type_gen_args.clone(), + is_negative, + path_type.clone(), + ty.clone(), + trait_where_clause.clone(), + ty_where_clause.clone(), + body.clone(), + ) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(attrs_input, ast.attrs().map(|attr| attr.syntax().clone())); + if let Some(trait_gen_params) = trait_gen_params { + builder.map_node( + trait_gen_params.syntax().clone(), + ast.generic_param_list().unwrap().syntax().clone(), + ); + } + builder.map_node(path_type.syntax().clone(), ast.trait_().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.self_ty().unwrap().syntax().clone()); + if let Some(ty_where_clause) = ty_where_clause { + builder.map_node( + ty_where_clause.syntax().clone(), + ast.where_clause().unwrap().syntax().clone(), + ); + } + if let Some(body) = body { + builder.map_node( + body.syntax().clone(), + ast.assoc_item_list().unwrap().syntax().clone(), + ); + } + builder.finish(&mut mapping); + } + + ast + } + + pub fn ty_alias( + &self, + attrs: impl IntoIterator, + ident: &str, + generic_param_list: Option, + type_param_bounds: Option, + where_clause: Option, + assignment: Option<(ast::Type, Option)>, + ) -> ast::TypeAlias { + let (attrs, attrs_input) = iterator_input(attrs); + let ast = make::ty_alias( + attrs, + ident, + generic_param_list.clone(), + type_param_bounds.clone(), + where_clause.clone(), + assignment.clone(), + ) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(attrs_input, ast.attrs().map(|attr| attr.syntax().clone())); + if let Some(generic_param_list) = generic_param_list { + builder.map_node( + generic_param_list.syntax().clone(), + ast.generic_param_list().unwrap().syntax().clone(), + ); + } + if let Some(type_param_bounds) = type_param_bounds { + builder.map_node( + type_param_bounds.syntax().clone(), + ast.type_bound_list().unwrap().syntax().clone(), + ); + } + if let Some(where_clause) = where_clause { + builder.map_node( + where_clause.syntax().clone(), + ast.where_clause().unwrap().syntax().clone(), + ); + } + if let Some((ty, _)) = assignment { + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast + } + + pub fn param_list( + &self, + self_param: Option, + params: impl IntoIterator, + ) -> ast::ParamList { + let (params, input) = iterator_input(params); + let ast = make::param_list(self_param.clone(), params).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(self_param) = self_param { + if let Some(new_self_param) = ast.self_param() { + builder.map_node(self_param.syntax().clone(), new_self_param.syntax().clone()); + } + } + builder.map_children(input, ast.params().map(|p| p.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + + pub fn const_param(&self, name: ast::Name, ty: ast::Type) -> ast::ConstParam { + let ast = make::const_param(name.clone(), ty.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn generic_param_list( + &self, + params: impl IntoIterator, + ) -> ast::GenericParamList { + let (params, input) = iterator_input(params); + let ast = make::generic_param_list(params).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input, ast.generic_params().map(|p| p.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + pub fn path_segment(&self, name_ref: ast::NameRef) -> ast::PathSegment { let ast = make::path_segment(name_ref.clone()).clone_for_update(); From b55796facaf80bc5f7ba2855672280ca22c1766d Mon Sep 17 00:00:00 2001 From: Boxy Date: Mon, 1 Dec 2025 16:22:27 +0000 Subject: [PATCH 0203/3801] Uppper typo Co-authored-by: Santiago Pastorino --- src/doc/rustc-dev-guide/src/hir-typeck/coercions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/hir-typeck/coercions.md b/src/doc/rustc-dev-guide/src/hir-typeck/coercions.md index 384ea9bcf030..158ac0885d32 100644 --- a/src/doc/rustc-dev-guide/src/hir-typeck/coercions.md +++ b/src/doc/rustc-dev-guide/src/hir-typeck/coercions.md @@ -2,7 +2,7 @@ Coercions are implicit operations which transform a value into a different type. A coercion *site* is a position where a coercion is able to be implicitly performed. There are two kinds of coercion sites: - one-to-one -- LUB (Least-Uppper-Bound) +- LUB (Least-Upper-Bound) ```rust let one_to_one_coercion: &u32 = &mut 8; From 919e46f4d41003ce7b927df83be284101d27b8d3 Mon Sep 17 00:00:00 2001 From: bendn Date: Tue, 11 Nov 2025 13:46:52 +0700 Subject: [PATCH 0204/3801] stabilize [T]::array_windows --- compiler/rustc_ast/src/lib.rs | 2 +- compiler/rustc_data_structures/src/lib.rs | 2 +- compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_expand/src/lib.rs | 2 +- compiler/rustc_lint/src/lib.rs | 2 +- compiler/rustc_middle/src/lib.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 2 +- compiler/rustc_monomorphize/src/lib.rs | 2 +- compiler/rustc_span/src/lib.rs | 2 +- library/alloc/src/lib.rs | 1 - library/alloc/src/slice.rs | 2 +- library/core/src/slice/iter.rs | 10 ++++------ library/core/src/slice/mod.rs | 5 ++--- library/coretests/tests/lib.rs | 1 - src/tools/clippy/clippy_lints/src/lib.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- 16 files changed, 18 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index e19dccbce02a..cbdc89f9deed 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -5,8 +5,8 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(array_windows))] #![doc(test(attr(deny(warnings), allow(internal_features))))] -#![feature(array_windows)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index b4031973fbc2..41f6292e740b 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -10,9 +10,9 @@ #![allow(internal_features)] #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] +#![cfg_attr(bootstrap, feature(array_windows))] #![deny(unsafe_op_in_unsafe_fn)] #![feature(allocator_api)] -#![feature(array_windows)] #![feature(ascii_char)] #![feature(ascii_char_variants)] #![feature(assert_matches)] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b8dda9ed5743..52e532014ca3 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -7,7 +7,7 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index e76fca92c586..5eefa4bcdf6b 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -1,7 +1,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![feature(associated_type_defaults)] #![feature(if_let_guard)] #![feature(macro_metavar_expr)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 78b76e083d41..1aac65dbaa77 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -21,7 +21,7 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index ef8326fd038e..5f62d44df6b6 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -29,8 +29,8 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(bootstrap, feature(array_windows))] #![feature(allocator_api)] -#![feature(array_windows)] #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_as_ptr)] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 18b798c01faa..1f6cc2700592 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,5 +1,5 @@ // tidy-alphabetical-start -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(const_type_name)] diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 05683940cba4..8b48cf5a6501 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -1,5 +1,5 @@ // tidy-alphabetical-start -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 2e03ccb1aa1a..31f82860b73d 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -17,8 +17,8 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(bootstrap, feature(array_windows))] #![cfg_attr(target_arch = "loongarch64", feature(stdarch_loongarch))] -#![feature(array_windows)] #![feature(cfg_select)] #![feature(core_io_borrowed_buf)] #![feature(if_let_guard)] diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 3f391fe2c1de..bfb6eeb8dad1 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -89,7 +89,6 @@ #![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_into_iter_constructors)] -#![feature(array_windows)] #![feature(ascii_char)] #![feature(assert_matches)] #![feature(async_fn_traits)] diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index a83b51ccb60c..e7d0fc3454ee 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -18,7 +18,7 @@ use core::cmp::Ordering::{self, Less}; use core::mem::MaybeUninit; #[cfg(not(no_global_oom_handling))] use core::ptr; -#[unstable(feature = "array_windows", issue = "75027")] +#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")] pub use core::slice::ArrayWindows; #[stable(feature = "inherent_ascii_escape", since = "1.60.0")] pub use core::slice::EscapeAscii; diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index a2fbf6ead646..0e70be783625 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -2187,8 +2187,6 @@ unsafe impl Sync for ChunksExactMut<'_, T> where T: Sync {} /// # Example /// /// ``` -/// #![feature(array_windows)] -/// /// let slice = [0, 1, 2, 3]; /// let mut iter = slice.array_windows::<2>(); /// assert_eq!(iter.next(), Some(&[0, 1])); @@ -2200,7 +2198,7 @@ unsafe impl Sync for ChunksExactMut<'_, T> where T: Sync {} /// [`array_windows`]: slice::array_windows /// [slices]: slice #[derive(Debug, Clone, Copy)] -#[unstable(feature = "array_windows", issue = "75027")] +#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")] #[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ArrayWindows<'a, T: 'a, const N: usize> { v: &'a [T], @@ -2213,7 +2211,7 @@ impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> { } } -#[unstable(feature = "array_windows", issue = "75027")] +#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")] impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> { type Item = &'a [T; N]; @@ -2250,7 +2248,7 @@ impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> { } } -#[unstable(feature = "array_windows", issue = "75027")] +#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")] impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> { #[inline] fn next_back(&mut self) -> Option<&'a [T; N]> { @@ -2269,7 +2267,7 @@ impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> { } } -#[unstable(feature = "array_windows", issue = "75027")] +#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")] impl ExactSizeIterator for ArrayWindows<'_, T, N> { fn is_empty(&self) -> bool { self.v.len() < N diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f03f2045444d..8b32f00bc861 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -51,7 +51,7 @@ pub use ascii::is_ascii_simple; pub use index::SliceIndex; #[unstable(feature = "slice_range", issue = "76393")] pub use index::{range, try_range}; -#[unstable(feature = "array_windows", issue = "75027")] +#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")] pub use iter::ArrayWindows; #[stable(feature = "slice_group_by", since = "1.77.0")] pub use iter::{ChunkBy, ChunkByMut}; @@ -1626,7 +1626,6 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(array_windows)] /// let slice = [0, 1, 2, 3]; /// let mut iter = slice.array_windows(); /// assert_eq!(iter.next().unwrap(), &[0, 1]); @@ -1636,7 +1635,7 @@ impl [T] { /// ``` /// /// [`windows`]: slice::windows - #[unstable(feature = "array_windows", issue = "75027")] + #[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")] #[inline] #[track_caller] diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 436856635c1c..1c22ef23a7b0 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -5,7 +5,6 @@ #![feature(array_ptr_get)] #![feature(array_try_from_fn)] #![feature(array_try_map)] -#![feature(array_windows)] #![feature(ascii_char)] #![feature(ascii_char_variants)] #![feature(async_iter_from_iter)] diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 230d83dacc95..bc62d9b8450c 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![feature(box_patterns)] #![feature(macro_metavar_expr_concat)] #![feature(f128)] diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index ed164fcf371b..409f13013489 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -5,7 +5,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] #![feature(unwrap_infallible)] -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![recursion_limit = "512"] #![allow( clippy::missing_errors_doc, From 3e88c6a639ea28ada59ef63f4b11814d6de5c489 Mon Sep 17 00:00:00 2001 From: bendn Date: Tue, 11 Nov 2025 13:46:52 +0700 Subject: [PATCH 0205/3801] stabilize [T]::array_windows --- clippy_lints/src/lib.rs | 2 +- clippy_utils/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 230d83dacc95..bc62d9b8450c 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![feature(box_patterns)] #![feature(macro_metavar_expr_concat)] #![feature(f128)] diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index ed164fcf371b..409f13013489 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -5,7 +5,7 @@ #![feature(rustc_private)] #![feature(assert_matches)] #![feature(unwrap_infallible)] -#![feature(array_windows)] +#![cfg_attr(bootstrap, feature(array_windows))] #![recursion_limit = "512"] #![allow( clippy::missing_errors_doc, From 37c9b16b1dbe9e06ae5f269104f398887ff08021 Mon Sep 17 00:00:00 2001 From: bendn Date: Tue, 11 Nov 2025 14:02:18 +0700 Subject: [PATCH 0206/3801] document --- library/core/src/slice/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 8b32f00bc861..dc34d2a21ee9 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -1620,8 +1620,11 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is zero. This check will most probably get changed to a compile time - /// error before this method gets stabilized. + /// Panics if `N` is zero. + /// + /// Note that this check is against a const generic parameter, not a runtime + /// value, and thus a particular monomorphization will either always panic + /// or it will never panic. /// /// # Examples /// From 1b76a346e826930d0b1e4901781da6a3038bac99 Mon Sep 17 00:00:00 2001 From: yanglsh Date: Sun, 22 Jun 2025 15:43:06 +0800 Subject: [PATCH 0207/3801] fix: `large_stack_frames` FP on compiler generated targets --- CHANGELOG.md | 1 + book/src/lint_configuration.md | 10 ++ clippy_config/src/conf.rs | 3 + clippy_lints/src/large_stack_frames.rs | 152 ++++++++++++------ .../large_stack_frames_for_macros/clippy.toml | 1 + .../large_stack_frames.rs | 42 +++++ .../large_stack_frames.stderr | 89 ++++++++++ .../clippy.toml | 2 + .../large_stack_frames.rs | 13 ++ .../toml_unknown_key/conf_unknown_key.stderr | 3 + 10 files changed, 269 insertions(+), 47 deletions(-) create mode 100644 tests/ui-toml/large_stack_frames_for_macros/clippy.toml create mode 100644 tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs create mode 100644 tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.stderr create mode 100644 tests/ui-toml/large_stack_frames_for_special_targets/clippy.toml create mode 100644 tests/ui-toml/large_stack_frames_for_special_targets/large_stack_frames.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7db95c081aa3..d7f663ee9f1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7081,6 +7081,7 @@ Released 2018-09-13 [`allow-expect-in-consts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-consts [`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests [`allow-indexing-slicing-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-indexing-slicing-in-tests +[`allow-large-stack-frames-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-large-stack-frames-in-tests [`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args [`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings [`allow-panic-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-panic-in-tests diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 6569bdabf115..c2e7e19042c7 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -111,6 +111,16 @@ Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]` * [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing) +## `allow-large-stack-frames-in-tests` +Whether functions inside `#[cfg(test)]` modules or test functions should be checked. + +**Default Value:** `true` + +--- +**Affected lints:** +* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames) + + ## `allow-mixed-uninlined-format-args` Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)` diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 2a042e6c3d85..2cec8a1a2821 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -373,6 +373,9 @@ define_Conf! { /// Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]` #[lints(indexing_slicing)] allow_indexing_slicing_in_tests: bool = false, + /// Whether functions inside `#[cfg(test)]` modules or test functions should be checked. + #[lints(large_stack_frames)] + allow_large_stack_frames_in_tests: bool = true, /// Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)` #[lints(uninlined_format_args)] allow_mixed_uninlined_format_args: bool = true, diff --git a/clippy_lints/src/large_stack_frames.rs b/clippy_lints/src/large_stack_frames.rs index 5ed948c02bbc..6b0080d04c44 100644 --- a/clippy_lints/src/large_stack_frames.rs +++ b/clippy_lints/src/large_stack_frames.rs @@ -2,15 +2,16 @@ use std::{fmt, ops}; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::fn_has_unsatisfiable_preds; -use clippy_utils::source::SpanRangeExt; +use clippy_utils::source::{HasSession, SpanRangeExt}; +use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_in_test}; +use rustc_errors::Diag; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::FnKind; use rustc_hir::{Body, FnDecl}; use rustc_lexer::is_ident; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::Span; +use rustc_span::{Span, SyntaxContext}; declare_clippy_lint! { /// ### What it does @@ -83,12 +84,14 @@ declare_clippy_lint! { pub struct LargeStackFrames { maximum_allowed_size: u64, + allow_large_stack_frames_in_tests: bool, } impl LargeStackFrames { pub fn new(conf: &'static Conf) -> Self { Self { maximum_allowed_size: conf.stack_size_threshold, + allow_large_stack_frames_in_tests: conf.allow_large_stack_frames_in_tests, } } } @@ -152,67 +155,122 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackFrames { let mir = cx.tcx.optimized_mir(def_id); let typing_env = mir.typing_env(cx.tcx); - let sizes_of_locals = || { - mir.local_decls.iter().filter_map(|local| { + let sizes_of_locals = mir + .local_decls + .iter() + .filter_map(|local| { let layout = cx.tcx.layout_of(typing_env.as_query_input(local.ty)).ok()?; Some((local, layout.size.bytes())) }) - }; + .collect::>(); - let frame_size = sizes_of_locals().fold(Space::Used(0), |sum, (_, size)| sum + size); + let frame_size = sizes_of_locals + .iter() + .fold(Space::Used(0), |sum, (_, size)| sum + *size); let limit = self.maximum_allowed_size; if frame_size.exceeds_limit(limit) { // Point at just the function name if possible, because lints that span // the entire body and don't have to are less legible. - let fn_span = match fn_kind { - FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span, - FnKind::Closure => entire_fn_span, + let (fn_span, fn_name) = match fn_kind { + FnKind::ItemFn(ident, _, _) => (ident.span, format!("function `{}`", ident.name)), + FnKind::Method(ident, _) => (ident.span, format!("method `{}`", ident.name)), + FnKind::Closure => (entire_fn_span, "closure".to_string()), }; + // Don't lint inside tests if configured to not do so. + if self.allow_large_stack_frames_in_tests && is_in_test(cx.tcx, cx.tcx.local_def_id_to_hir_id(local_def_id)) + { + return; + } + + let explain_lint = |diag: &mut Diag<'_, ()>, ctxt: SyntaxContext| { + // Point out the largest individual contribution to this size, because + // it is the most likely to be unintentionally large. + if let Some((local, size)) = sizes_of_locals.iter().max_by_key(|&(_, size)| size) + && let local_span = local.source_info.span + && local_span.ctxt() == ctxt + { + let size = Space::Used(*size); // pluralizes for us + let ty = local.ty; + + // TODO: Is there a cleaner, robust way to ask this question? + // The obvious `LocalDecl::is_user_variable()` panics on "unwrapping cross-crate data", + // and that doesn't get us the true name in scope rather than the span text either. + if let Some(name) = local_span.get_source_text(cx) + && is_ident(&name) + { + // If the local is an ordinary named variable, + // print its name rather than relying solely on the span. + diag.span_label( + local_span, + format!("`{name}` is the largest part, at {size} for type `{ty}`"), + ); + } else { + diag.span_label( + local_span, + format!("this is the largest part, at {size} for type `{ty}`"), + ); + } + } + + // Explain why we are linting this and not other functions. + diag.note(format!( + "{frame_size} is larger than Clippy's configured `stack-size-threshold` of {limit}" + )); + + // Explain why the user should care, briefly. + diag.note_once( + "allocating large amounts of stack space can overflow the stack \ + and cause the program to abort", + ); + }; + + if fn_span.from_expansion() { + // Don't lint on the main function generated by `--test` target + if cx.sess().is_test_crate() && is_entrypoint_fn(cx, local_def_id.to_def_id()) { + return; + } + + let is_from_external_macro = fn_span.in_external_macro(cx.sess().source_map()); + span_lint_and_then( + cx, + LARGE_STACK_FRAMES, + fn_span.source_callsite(), + format!( + "{} generated by this macro may allocate a lot of stack space", + if is_from_external_macro { + cx.tcx.def_descr(local_def_id.into()) + } else { + fn_name.as_str() + } + ), + |diag| { + if is_from_external_macro { + return; + } + + diag.span_label( + fn_span, + format!( + "this {} has a stack frame size of {frame_size}", + cx.tcx.def_descr(local_def_id.into()) + ), + ); + + explain_lint(diag, fn_span.ctxt()); + }, + ); + return; + } + span_lint_and_then( cx, LARGE_STACK_FRAMES, fn_span, format!("this function may allocate {frame_size} on the stack"), |diag| { - // Point out the largest individual contribution to this size, because - // it is the most likely to be unintentionally large. - if let Some((local, size)) = sizes_of_locals().max_by_key(|&(_, size)| size) { - let local_span: Span = local.source_info.span; - let size = Space::Used(size); // pluralizes for us - let ty = local.ty; - - // TODO: Is there a cleaner, robust way to ask this question? - // The obvious `LocalDecl::is_user_variable()` panics on "unwrapping cross-crate data", - // and that doesn't get us the true name in scope rather than the span text either. - if let Some(name) = local_span.get_source_text(cx) - && is_ident(&name) - { - // If the local is an ordinary named variable, - // print its name rather than relying solely on the span. - diag.span_label( - local_span, - format!("`{name}` is the largest part, at {size} for type `{ty}`"), - ); - } else { - diag.span_label( - local_span, - format!("this is the largest part, at {size} for type `{ty}`"), - ); - } - } - - // Explain why we are linting this and not other functions. - diag.note(format!( - "{frame_size} is larger than Clippy's configured `stack-size-threshold` of {limit}" - )); - - // Explain why the user should care, briefly. - diag.note_once( - "allocating large amounts of stack space can overflow the stack \ - and cause the program to abort", - ); + explain_lint(diag, SyntaxContext::root()); }, ); } diff --git a/tests/ui-toml/large_stack_frames_for_macros/clippy.toml b/tests/ui-toml/large_stack_frames_for_macros/clippy.toml new file mode 100644 index 000000000000..b6fd0e8a0483 --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_macros/clippy.toml @@ -0,0 +1 @@ +stack-size-threshold = 0 diff --git a/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs b/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs new file mode 100644 index 000000000000..1f6265590f93 --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs @@ -0,0 +1,42 @@ +//@ignore-target: i686 +//@normalize-stderr-test: "\b10000(08|16|32)\b" -> "100$$PTR" +//@normalize-stderr-test: "\b2500(060|120)\b" -> "250$$PTR" + +#![warn(clippy::large_stack_frames)] + +extern crate serde; +use serde::{Deserialize, Serialize}; + +struct ArrayDefault([u8; N]); + +macro_rules! mac { + ($name:ident) => { + fn foo() { + let $name = 1; + println!("macro_name called"); + } + + fn bar() { + let $name = ArrayDefault([0; 1000]); + } + }; +} + +mac!(something); +//~^ large_stack_frames +//~| large_stack_frames + +#[derive(Deserialize, Serialize)] +//~^ large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +struct S { + a: [u128; 31], +} + +fn main() {} diff --git a/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.stderr b/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.stderr new file mode 100644 index 000000000000..bc222f6b1039 --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.stderr @@ -0,0 +1,89 @@ +error: function `foo` generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:25:1 + | +LL | fn foo() { + | --- this function has a stack frame size of 20 bytes +... +LL | mac!(something); + | ^^^^^^^^^^^^^^^ + | + = note: 20 bytes is larger than Clippy's configured `stack-size-threshold` of 0 + = note: allocating large amounts of stack space can overflow the stack and cause the program to abort + = note: `-D clippy::large-stack-frames` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]` + +error: function `bar` generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:25:1 + | +LL | fn bar() { + | --- this function has a stack frame size of 2000 bytes +LL | let $name = ArrayDefault([0; 1000]); + | --------- this is the largest part, at 1000 bytes for type `[u8; 1000]` +... +LL | mac!(something); + | ^^^^^^^^^^^^^^^ + | + = note: 2000 bytes is larger than Clippy's configured `stack-size-threshold` of 0 + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:23 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^ + +error: aborting due to 10 previous errors + diff --git a/tests/ui-toml/large_stack_frames_for_special_targets/clippy.toml b/tests/ui-toml/large_stack_frames_for_special_targets/clippy.toml new file mode 100644 index 000000000000..02f3bc02dc4b --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_special_targets/clippy.toml @@ -0,0 +1,2 @@ +stack-size-threshold = 0 +allow-large-stack-frames-in-tests = false diff --git a/tests/ui-toml/large_stack_frames_for_special_targets/large_stack_frames.rs b/tests/ui-toml/large_stack_frames_for_special_targets/large_stack_frames.rs new file mode 100644 index 000000000000..cc01232ca408 --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_special_targets/large_stack_frames.rs @@ -0,0 +1,13 @@ +// This test checks if `clippy::large_stack_frames` is working correctly when encountering functions +// generated by special compiling targets like `--test`. +//@compile-flags: --test +//@check-pass + +#![warn(clippy::large_stack_frames)] + +#[cfg(test)] +#[expect(clippy::large_stack_frames)] +mod test { + #[test] + fn main_test() {} +} diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 2d9503c5ac53..ac449bc82b9d 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -9,6 +9,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect allow-expect-in-consts allow-expect-in-tests allow-indexing-slicing-in-tests + allow-large-stack-frames-in-tests allow-mixed-uninlined-format-args allow-one-hash-in-raw-strings allow-panic-in-tests @@ -106,6 +107,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect allow-expect-in-consts allow-expect-in-tests allow-indexing-slicing-in-tests + allow-large-stack-frames-in-tests allow-mixed-uninlined-format-args allow-one-hash-in-raw-strings allow-panic-in-tests @@ -203,6 +205,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni allow-expect-in-consts allow-expect-in-tests allow-indexing-slicing-in-tests + allow-large-stack-frames-in-tests allow-mixed-uninlined-format-args allow-one-hash-in-raw-strings allow-panic-in-tests From 5ac265676a6a62946382a67a32661b94338c15cd Mon Sep 17 00:00:00 2001 From: ceptontech <> Date: Fri, 24 Oct 2025 14:26:04 -0700 Subject: [PATCH 0208/3801] feat(transmute_ptr_to_ref): Handle a pointer wrapped in a struct Now the program checks for transmutting from a struct containing a single raw pointer to a reference. ```Rust struct Foo(*const i32); fn foo(foo: Foo) -> &i32 { unsafe { transmute(foo) } } ``` changelog: [`transmute_ptr_to_ref`]: now checks for a pointer wrapped in a struct --- clippy_lints/src/transmute/mod.rs | 34 +++++- .../src/transmute/transmute_ptr_to_ref.rs | 3 +- tests/ui/transmute_ptr_to_ref.fixed | 56 ++++++++- tests/ui/transmute_ptr_to_ref.rs | 56 ++++++++- tests/ui/transmute_ptr_to_ref.stderr | 110 ++++++++++++++---- 5 files changed, 230 insertions(+), 29 deletions(-) diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index d643f7aea497..839491b082f2 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -18,8 +18,11 @@ mod wrong_transmute; use clippy_config::Conf; use clippy_utils::is_in_const_context; use clippy_utils::msrvs::Msrv; +use clippy_utils::sugg::Sugg; +use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use rustc_span::symbol::sym; @@ -490,6 +493,32 @@ impl Transmute { pub fn new(conf: &'static Conf) -> Self { Self { msrv: conf.msrv } } + + /// When transmuting, a struct containing a single field works like the field. + /// This function extracts the field type and the expression to get the field. + fn extract_struct_field<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + outer_type: Ty<'tcx>, + outer: &'tcx Expr<'tcx>, + ) -> (Ty<'tcx>, Sugg<'tcx>) { + let mut applicability = Applicability::MachineApplicable; + let outer_sugg = Sugg::hir_with_context(cx, outer, e.span.ctxt(), "..", &mut applicability); + if let ty::Adt(struct_def, struct_args) = *outer_type.kind() + && struct_def.is_struct() + && let mut fields = struct_def.all_fields() + && let Some(first) = fields.next() + && fields.next().is_none() + && first.vis.is_accessible_from(cx.tcx.parent_module(outer.hir_id), cx.tcx) + { + ( + first.ty(cx.tcx, struct_args), + Sugg::NonParen(format!("{}.{}", outer_sugg.maybe_paren(), first.name).into()), + ) + } else { + (outer_type, outer_sugg) + } + } } impl<'tcx> LateLintPass<'tcx> for Transmute { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { @@ -516,11 +545,14 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { return; } + // A struct having a single pointer can be treated like a pointer. + let (from_field_ty, from_field_expr) = Self::extract_struct_field(cx, e, from_ty, arg); + let linted = wrong_transmute::check(cx, e, from_ty, to_ty) | crosspointer_transmute::check(cx, e, from_ty, to_ty) | transmuting_null::check(cx, e, arg, to_ty) | transmute_null_to_fn::check(cx, e, arg, to_ty) - | transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, self.msrv) + | transmute_ptr_to_ref::check(cx, e, from_field_ty, to_ty, from_field_expr.clone(), path, self.msrv) | missing_transmute_annotations::check(cx, path, arg, from_ty, to_ty, e.hir_id) | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context) | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, self.msrv) diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index e67ab6a73d26..ba107eed6b14 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -15,7 +15,7 @@ pub(super) fn check<'tcx>( e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>, - arg: &'tcx Expr<'_>, + arg: sugg::Sugg<'_>, path: &'tcx Path<'_>, msrv: Msrv, ) -> bool { @@ -27,7 +27,6 @@ pub(super) fn check<'tcx>( e.span, format!("transmute from a pointer type (`{from_ty}`) to a reference type (`{to_ty}`)"), |diag| { - let arg = sugg::Sugg::hir(cx, arg, ".."); let (deref, cast) = match mutbl { Mutability::Mut => ("&mut *", "*mut"), Mutability::Not => ("&*", "*const"), diff --git a/tests/ui/transmute_ptr_to_ref.fixed b/tests/ui/transmute_ptr_to_ref.fixed index c130575df960..8de47031a400 100644 --- a/tests/ui/transmute_ptr_to_ref.fixed +++ b/tests/ui/transmute_ptr_to_ref.fixed @@ -55,6 +55,52 @@ fn issue1231() { //~^ transmute_ptr_to_ref } +#[derive(Clone, Copy)] +struct PtrRefNamed<'a> { + ptr: *const &'a u32, +} +#[derive(Clone, Copy)] +struct PtrRef<'a>(*const &'a u32); +#[derive(Clone, Copy)] +struct PtrSliceRef<'a>(*const [&'a str]); +#[derive(Clone, Copy)] +struct PtrSlice(*const [i32]); +#[derive(Clone, Copy)] +struct Ptr(*const u32); +impl std::ops::Add for Ptr { + type Output = Self; + fn add(self, _: Self) -> Self { + self + } +} +mod ptr_mod { + #[derive(Clone, Copy)] + pub struct Ptr(*const u32); +} +fn issue1966(u: PtrSlice, v: PtrSliceRef, w: Ptr, x: PtrRefNamed, y: PtrRef, z: ptr_mod::Ptr) { + unsafe { + let _: &i32 = &*(w.0 as *const i32); + //~^ transmute_ptr_to_ref + let _: &u32 = &*w.0; + //~^ transmute_ptr_to_ref + let _: &&u32 = &*x.ptr.cast::<&u32>(); + //~^ transmute_ptr_to_ref + // The field is not accessible. The program should not generate code + // that accesses the field. + let _: &u32 = std::mem::transmute(z); + let _ = &*w.0.cast::(); + //~^ transmute_ptr_to_ref + let _: &[&str] = &*(v.0 as *const [&str]); + //~^ transmute_ptr_to_ref + let _ = &*(u.0 as *const [i32]); + //~^ transmute_ptr_to_ref + let _: &&u32 = &*y.0.cast::<&u32>(); + //~^ transmute_ptr_to_ref + let _: &u32 = &*(w + w).0; + //~^ transmute_ptr_to_ref + } +} + fn issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 { unsafe { match 0 { @@ -89,7 +135,7 @@ fn meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { } #[clippy::msrv = "1.37"] -fn under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { +fn under_msrv<'a, 'b, 'c>(x: *const &'a u32, y: PtrRef) -> &'c &'b u32 { unsafe { let a = 0u32; let a = &a as *const u32; @@ -97,10 +143,16 @@ fn under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { //~^ transmute_ptr_to_ref let _: &u32 = &*(a as *const u32); //~^ transmute_ptr_to_ref + let _ = &*(Ptr(a).0 as *const u32); + //~^ transmute_ptr_to_ref match 0 { 0 => &*(x as *const () as *const &u32), //~^ transmute_ptr_to_ref - _ => &*(x as *const () as *const &'b u32), + 1 => &*(x as *const () as *const &'b u32), + //~^ transmute_ptr_to_ref + 2 => &*(y.0 as *const () as *const &u32), + //~^ transmute_ptr_to_ref + _ => &*(y.0 as *const () as *const &'b u32), //~^ transmute_ptr_to_ref } } diff --git a/tests/ui/transmute_ptr_to_ref.rs b/tests/ui/transmute_ptr_to_ref.rs index f79d54234a2c..52fe669de935 100644 --- a/tests/ui/transmute_ptr_to_ref.rs +++ b/tests/ui/transmute_ptr_to_ref.rs @@ -55,6 +55,52 @@ fn issue1231() { //~^ transmute_ptr_to_ref } +#[derive(Clone, Copy)] +struct PtrRefNamed<'a> { + ptr: *const &'a u32, +} +#[derive(Clone, Copy)] +struct PtrRef<'a>(*const &'a u32); +#[derive(Clone, Copy)] +struct PtrSliceRef<'a>(*const [&'a str]); +#[derive(Clone, Copy)] +struct PtrSlice(*const [i32]); +#[derive(Clone, Copy)] +struct Ptr(*const u32); +impl std::ops::Add for Ptr { + type Output = Self; + fn add(self, _: Self) -> Self { + self + } +} +mod ptr_mod { + #[derive(Clone, Copy)] + pub struct Ptr(*const u32); +} +fn issue1966(u: PtrSlice, v: PtrSliceRef, w: Ptr, x: PtrRefNamed, y: PtrRef, z: ptr_mod::Ptr) { + unsafe { + let _: &i32 = std::mem::transmute(w); + //~^ transmute_ptr_to_ref + let _: &u32 = std::mem::transmute(w); + //~^ transmute_ptr_to_ref + let _: &&u32 = core::mem::transmute(x); + //~^ transmute_ptr_to_ref + // The field is not accessible. The program should not generate code + // that accesses the field. + let _: &u32 = std::mem::transmute(z); + let _ = std::mem::transmute::<_, &u32>(w); + //~^ transmute_ptr_to_ref + let _: &[&str] = core::mem::transmute(v); + //~^ transmute_ptr_to_ref + let _ = std::mem::transmute::<_, &[i32]>(u); + //~^ transmute_ptr_to_ref + let _: &&u32 = std::mem::transmute(y); + //~^ transmute_ptr_to_ref + let _: &u32 = std::mem::transmute(w + w); + //~^ transmute_ptr_to_ref + } +} + fn issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 { unsafe { match 0 { @@ -89,7 +135,7 @@ fn meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { } #[clippy::msrv = "1.37"] -fn under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { +fn under_msrv<'a, 'b, 'c>(x: *const &'a u32, y: PtrRef) -> &'c &'b u32 { unsafe { let a = 0u32; let a = &a as *const u32; @@ -97,10 +143,16 @@ fn under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { //~^ transmute_ptr_to_ref let _: &u32 = std::mem::transmute::<_, &u32>(a); //~^ transmute_ptr_to_ref + let _ = std::mem::transmute::<_, &u32>(Ptr(a)); + //~^ transmute_ptr_to_ref match 0 { 0 => std::mem::transmute(x), //~^ transmute_ptr_to_ref - _ => std::mem::transmute::<_, &&'b u32>(x), + 1 => std::mem::transmute::<_, &&'b u32>(x), + //~^ transmute_ptr_to_ref + 2 => std::mem::transmute(y), + //~^ transmute_ptr_to_ref + _ => std::mem::transmute::<_, &&'b u32>(y), //~^ transmute_ptr_to_ref } } diff --git a/tests/ui/transmute_ptr_to_ref.stderr b/tests/ui/transmute_ptr_to_ref.stderr index 3f404d295fef..c0f0ca916761 100644 --- a/tests/ui/transmute_ptr_to_ref.stderr +++ b/tests/ui/transmute_ptr_to_ref.stderr @@ -61,125 +61,191 @@ error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`) LL | unsafe { std::mem::transmute::<_, Bar>(raw) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const u8)` +error: transmute from a pointer type (`*const u32`) to a reference type (`&i32`) + --> tests/ui/transmute_ptr_to_ref.rs:82:23 + | +LL | let _: &i32 = std::mem::transmute(w); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(w.0 as *const i32)` + +error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:84:23 + | +LL | let _: &u32 = std::mem::transmute(w); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*w.0` + error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:61:18 + --> tests/ui/transmute_ptr_to_ref.rs:86:24 + | +LL | let _: &&u32 = core::mem::transmute(x); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.ptr.cast::<&u32>()` + +error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:91:17 + | +LL | let _ = std::mem::transmute::<_, &u32>(w); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*w.0.cast::()` + +error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&str]`) + --> tests/ui/transmute_ptr_to_ref.rs:93:26 + | +LL | let _: &[&str] = core::mem::transmute(v); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(v.0 as *const [&str])` + +error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[i32]`) + --> tests/ui/transmute_ptr_to_ref.rs:95:17 + | +LL | let _ = std::mem::transmute::<_, &[i32]>(u); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(u.0 as *const [i32])` + +error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:97:24 + | +LL | let _: &&u32 = std::mem::transmute(y); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.0.cast::<&u32>()` + +error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:99:23 + | +LL | let _: &u32 = std::mem::transmute(w + w); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(w + w).0` + +error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:107:18 | LL | 0 => std::mem::transmute(x), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:63:18 + --> tests/ui/transmute_ptr_to_ref.rs:109:18 | LL | 1 => std::mem::transmute(y), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:65:18 + --> tests/ui/transmute_ptr_to_ref.rs:111:18 | LL | 2 => std::mem::transmute::<_, &&'b u32>(x), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:67:18 + --> tests/ui/transmute_ptr_to_ref.rs:113:18 | LL | _ => std::mem::transmute::<_, &&'b u32>(y), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&'b u32>()` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:78:23 + --> tests/ui/transmute_ptr_to_ref.rs:124:23 | LL | let _: &u32 = std::mem::transmute(a); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:80:23 + --> tests/ui/transmute_ptr_to_ref.rs:126:23 | LL | let _: &u32 = std::mem::transmute::<_, &u32>(a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a.cast::()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:83:18 + --> tests/ui/transmute_ptr_to_ref.rs:129:18 | LL | 0 => std::mem::transmute(x), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:85:18 + --> tests/ui/transmute_ptr_to_ref.rs:131:18 | LL | _ => std::mem::transmute::<_, &&'b u32>(x), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:96:23 + --> tests/ui/transmute_ptr_to_ref.rs:142:23 | LL | let _: &u32 = std::mem::transmute(a); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:98:23 + --> tests/ui/transmute_ptr_to_ref.rs:144:23 | LL | let _: &u32 = std::mem::transmute::<_, &u32>(a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const u32)` +error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:146:17 + | +LL | let _ = std::mem::transmute::<_, &u32>(Ptr(a)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(Ptr(a).0 as *const u32)` + error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:101:18 + --> tests/ui/transmute_ptr_to_ref.rs:149:18 | LL | 0 => std::mem::transmute(x), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &u32)` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:103:18 + --> tests/ui/transmute_ptr_to_ref.rs:151:18 | -LL | _ => std::mem::transmute::<_, &&'b u32>(x), +LL | 1 => std::mem::transmute::<_, &&'b u32>(x), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &'b u32)` +error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:153:18 + | +LL | 2 => std::mem::transmute(y), + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(y.0 as *const () as *const &u32)` + +error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:155:18 + | +LL | _ => std::mem::transmute::<_, &&'b u32>(y), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(y.0 as *const () as *const &'b u32)` + error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[u32]`) - --> tests/ui/transmute_ptr_to_ref.rs:113:17 + --> tests/ui/transmute_ptr_to_ref.rs:165:17 | LL | let _ = core::mem::transmute::<_, &[u32]>(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(ptr as *const [u32])` error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[u32]`) - --> tests/ui/transmute_ptr_to_ref.rs:115:25 + --> tests/ui/transmute_ptr_to_ref.rs:167:25 | LL | let _: &[u32] = core::mem::transmute(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(ptr as *const [u32])` error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&[u8]]`) - --> tests/ui/transmute_ptr_to_ref.rs:119:17 + --> tests/ui/transmute_ptr_to_ref.rs:171:17 | LL | let _ = core::mem::transmute::<_, &[&[u8]]>(a_s_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&[u8]])` error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&[u8]]`) - --> tests/ui/transmute_ptr_to_ref.rs:121:27 + --> tests/ui/transmute_ptr_to_ref.rs:173:27 | LL | let _: &[&[u8]] = core::mem::transmute(a_s_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&[u8]])` error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[i32]`) - --> tests/ui/transmute_ptr_to_ref.rs:125:17 + --> tests/ui/transmute_ptr_to_ref.rs:177:17 | LL | let _ = core::mem::transmute::<_, &[i32]>(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(ptr as *const [i32])` error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[i32]`) - --> tests/ui/transmute_ptr_to_ref.rs:127:25 + --> tests/ui/transmute_ptr_to_ref.rs:179:25 | LL | let _: &[i32] = core::mem::transmute(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*ptr` error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&str]`) - --> tests/ui/transmute_ptr_to_ref.rs:131:17 + --> tests/ui/transmute_ptr_to_ref.rs:183:17 | LL | let _ = core::mem::transmute::<_, &[&str]>(a_s_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&str])` error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&str]`) - --> tests/ui/transmute_ptr_to_ref.rs:133:26 + --> tests/ui/transmute_ptr_to_ref.rs:185:26 | LL | let _: &[&str] = core::mem::transmute(a_s_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&str])` -error: aborting due to 30 previous errors +error: aborting due to 41 previous errors From e9ceae44b7a659f81144ddb175d6bfa4e9b19504 Mon Sep 17 00:00:00 2001 From: ceptontech <> Date: Mon, 1 Dec 2025 09:00:29 -0800 Subject: [PATCH 0209/3801] feat(transmute_ptr_to_ptr): Handle a pointer wrapped in a struct Now the program checks for transmutting from a struct containing a single raw pointer to a raw pointer. changelog: [`transmute_ptr_to_ptr`]: now checks for a pointer wrapped in a struct --- clippy_lints/src/transmute/mod.rs | 2 +- .../src/transmute/transmute_ptr_to_ptr.rs | 10 +-- tests/ui/transmute_ptr_to_ptr.fixed | 23 ++++++ tests/ui/transmute_ptr_to_ptr.rs | 23 ++++++ tests/ui/transmute_ptr_to_ptr.stderr | 82 +++++++++++++++---- 5 files changed, 116 insertions(+), 24 deletions(-) diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 839491b082f2..435cd7bcba4e 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -555,7 +555,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { | transmute_ptr_to_ref::check(cx, e, from_field_ty, to_ty, from_field_expr.clone(), path, self.msrv) | missing_transmute_annotations::check(cx, path, arg, from_ty, to_ty, e.hir_id) | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context) - | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, self.msrv) + | transmute_ptr_to_ptr::check(cx, e, from_field_ty, to_ty, from_field_expr, self.msrv) | transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg) | transmute_int_to_non_zero::check(cx, e, from_ty, to_ty, arg) | (unsound_collection_transmute::check(cx, e, from_ty, to_ty) diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs index 91fce5d5bd68..036b16e3dc3d 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs @@ -14,11 +14,9 @@ pub(super) fn check<'tcx>( e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>, - arg: &'tcx Expr<'_>, + arg: sugg::Sugg<'_>, msrv: Msrv, ) -> bool { - let mut applicability = Applicability::MachineApplicable; - let arg_sugg = sugg::Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut applicability); match (from_ty.kind(), to_ty.kind()) { (ty::RawPtr(from_pointee_ty, from_mutbl), ty::RawPtr(to_pointee_ty, to_mutbl)) => { span_lint_and_then( @@ -34,7 +32,7 @@ pub(super) fn check<'tcx>( diag.span_suggestion_verbose( e.span, "use `pointer::cast` instead", - format!("{}.cast::<{to_pointee_ty}>()", arg_sugg.maybe_paren()), + format!("{}.cast::<{to_pointee_ty}>()", arg.maybe_paren()), Applicability::MaybeIncorrect, ); } else if from_pointee_ty == to_pointee_ty @@ -49,14 +47,14 @@ pub(super) fn check<'tcx>( diag.span_suggestion_verbose( e.span, format!("use `pointer::{method}` instead"), - format!("{}.{method}()", arg_sugg.maybe_paren()), + format!("{}.{method}()", arg.maybe_paren()), Applicability::MaybeIncorrect, ); } else { diag.span_suggestion_verbose( e.span, "use an `as` cast instead", - arg_sugg.as_ty(to_ty), + arg.as_ty(to_ty), Applicability::MaybeIncorrect, ); } diff --git a/tests/ui/transmute_ptr_to_ptr.fixed b/tests/ui/transmute_ptr_to_ptr.fixed index 476e7e35a1f6..caba277db754 100644 --- a/tests/ui/transmute_ptr_to_ptr.fixed +++ b/tests/ui/transmute_ptr_to_ptr.fixed @@ -24,6 +24,13 @@ struct GenericParam { t: T, } +#[derive(Clone, Copy)] +struct PtrNamed { + ptr: *const u32, +} +#[derive(Clone, Copy)] +struct Ptr(*const u32); + fn transmute_ptr_to_ptr() { let ptr = &1u32 as *const u32; let mut_ptr = &mut 1u32 as *mut u32; @@ -68,6 +75,18 @@ fn transmute_ptr_to_ptr() { let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) }; } +fn issue1966() { + let ptr = &1u32 as *const u32; + unsafe { + let _: *const f32 = Ptr(ptr).0.cast::(); + //~^ transmute_ptr_to_ptr + let _: *const f32 = PtrNamed { ptr }.ptr.cast::(); + //~^ transmute_ptr_to_ptr + let _: *mut u32 = Ptr(ptr).0.cast_mut(); + //~^ transmute_ptr_to_ptr + } +} + fn lifetime_to_static(v: *mut &()) -> *const &'static () { unsafe { v as *const &() } //~^ transmute_ptr_to_ptr @@ -81,11 +100,15 @@ const _: &() = { unsafe { transmute::<&'static Zst, &'static ()>(zst) } }; +#[derive(Clone, Copy)] +struct Ptr8(*const u8); #[clippy::msrv = "1.37"] fn msrv_1_37(ptr: *const u8) { unsafe { let _: *const i8 = ptr as *const i8; //~^ transmute_ptr_to_ptr + let _: *const i8 = Ptr8(ptr).0 as *const i8; + //~^ transmute_ptr_to_ptr } } diff --git a/tests/ui/transmute_ptr_to_ptr.rs b/tests/ui/transmute_ptr_to_ptr.rs index 7356668bcab5..b3c2baf29c36 100644 --- a/tests/ui/transmute_ptr_to_ptr.rs +++ b/tests/ui/transmute_ptr_to_ptr.rs @@ -24,6 +24,13 @@ struct GenericParam { t: T, } +#[derive(Clone, Copy)] +struct PtrNamed { + ptr: *const u32, +} +#[derive(Clone, Copy)] +struct Ptr(*const u32); + fn transmute_ptr_to_ptr() { let ptr = &1u32 as *const u32; let mut_ptr = &mut 1u32 as *mut u32; @@ -68,6 +75,18 @@ fn transmute_ptr_to_ptr() { let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) }; } +fn issue1966() { + let ptr = &1u32 as *const u32; + unsafe { + let _: *const f32 = transmute(Ptr(ptr)); + //~^ transmute_ptr_to_ptr + let _: *const f32 = transmute(PtrNamed { ptr }); + //~^ transmute_ptr_to_ptr + let _: *mut u32 = transmute(Ptr(ptr)); + //~^ transmute_ptr_to_ptr + } +} + fn lifetime_to_static(v: *mut &()) -> *const &'static () { unsafe { transmute(v) } //~^ transmute_ptr_to_ptr @@ -81,11 +100,15 @@ const _: &() = { unsafe { transmute::<&'static Zst, &'static ()>(zst) } }; +#[derive(Clone, Copy)] +struct Ptr8(*const u8); #[clippy::msrv = "1.37"] fn msrv_1_37(ptr: *const u8) { unsafe { let _: *const i8 = transmute(ptr); //~^ transmute_ptr_to_ptr + let _: *const i8 = transmute(Ptr8(ptr)); + //~^ transmute_ptr_to_ptr } } diff --git a/tests/ui/transmute_ptr_to_ptr.stderr b/tests/ui/transmute_ptr_to_ptr.stderr index c8db4fe214fd..ba9e6df6c2d7 100644 --- a/tests/ui/transmute_ptr_to_ptr.stderr +++ b/tests/ui/transmute_ptr_to_ptr.stderr @@ -1,5 +1,5 @@ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:32:29 + --> tests/ui/transmute_ptr_to_ptr.rs:39:29 | LL | let _: *const f32 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let _: *const f32 = ptr.cast::(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:35:27 + --> tests/ui/transmute_ptr_to_ptr.rs:42:27 | LL | let _: *mut f32 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -25,37 +25,37 @@ LL + let _: *mut f32 = mut_ptr.cast::(); | error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:39:23 + --> tests/ui/transmute_ptr_to_ptr.rs:46:23 | LL | let _: &f32 = transmute(&1u32); | ^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:42:23 + --> tests/ui/transmute_ptr_to_ptr.rs:49:23 | LL | let _: &f32 = transmute(&1f64); | ^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:47:27 + --> tests/ui/transmute_ptr_to_ptr.rs:54:27 | LL | let _: &mut f32 = transmute(&mut 1u32); | ^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:50:37 + --> tests/ui/transmute_ptr_to_ptr.rs:57:37 | LL | let _: &GenericParam = transmute(&GenericParam { t: 1u32 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam as *const GenericParam)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:54:27 + --> tests/ui/transmute_ptr_to_ptr.rs:61:27 | LL | let u8_ref: &u8 = transmute(u64_ref); | ^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)` error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:57:29 + --> tests/ui/transmute_ptr_to_ptr.rs:64:29 | LL | let _: *const u32 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL + let _: *const u32 = mut_ptr.cast_const(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:60:27 + --> tests/ui/transmute_ptr_to_ptr.rs:67:27 | LL | let _: *mut u32 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -79,7 +79,43 @@ LL + let _: *mut u32 = ptr.cast_mut(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:72:14 + --> tests/ui/transmute_ptr_to_ptr.rs:81:29 + | +LL | let _: *const f32 = transmute(Ptr(ptr)); + | ^^^^^^^^^^^^^^^^^^^ + | +help: use `pointer::cast` instead + | +LL - let _: *const f32 = transmute(Ptr(ptr)); +LL + let _: *const f32 = Ptr(ptr).0.cast::(); + | + +error: transmute from a pointer to a pointer + --> tests/ui/transmute_ptr_to_ptr.rs:83:29 + | +LL | let _: *const f32 = transmute(PtrNamed { ptr }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `pointer::cast` instead + | +LL - let _: *const f32 = transmute(PtrNamed { ptr }); +LL + let _: *const f32 = PtrNamed { ptr }.ptr.cast::(); + | + +error: transmute from a pointer to a pointer + --> tests/ui/transmute_ptr_to_ptr.rs:85:27 + | +LL | let _: *mut u32 = transmute(Ptr(ptr)); + | ^^^^^^^^^^^^^^^^^^^ + | +help: use `pointer::cast_mut` instead + | +LL - let _: *mut u32 = transmute(Ptr(ptr)); +LL + let _: *mut u32 = Ptr(ptr).0.cast_mut(); + | + +error: transmute from a pointer to a pointer + --> tests/ui/transmute_ptr_to_ptr.rs:91:14 | LL | unsafe { transmute(v) } | ^^^^^^^^^^^^ @@ -91,7 +127,7 @@ LL + unsafe { v as *const &() } | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:87:28 + --> tests/ui/transmute_ptr_to_ptr.rs:108:28 | LL | let _: *const i8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -103,7 +139,19 @@ LL + let _: *const i8 = ptr as *const i8; | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:95:28 + --> tests/ui/transmute_ptr_to_ptr.rs:110:28 + | +LL | let _: *const i8 = transmute(Ptr8(ptr)); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: use an `as` cast instead + | +LL - let _: *const i8 = transmute(Ptr8(ptr)); +LL + let _: *const i8 = Ptr8(ptr).0 as *const i8; + | + +error: transmute from a pointer to a pointer + --> tests/ui/transmute_ptr_to_ptr.rs:118:28 | LL | let _: *const i8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -115,7 +163,7 @@ LL + let _: *const i8 = ptr.cast::(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:103:26 + --> tests/ui/transmute_ptr_to_ptr.rs:126:26 | LL | let _: *mut u8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -127,7 +175,7 @@ LL + let _: *mut u8 = ptr as *mut u8; | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:105:28 + --> tests/ui/transmute_ptr_to_ptr.rs:128:28 | LL | let _: *const u8 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -139,7 +187,7 @@ LL + let _: *const u8 = mut_ptr as *const u8; | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:113:26 + --> tests/ui/transmute_ptr_to_ptr.rs:136:26 | LL | let _: *mut u8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -151,7 +199,7 @@ LL + let _: *mut u8 = ptr.cast_mut(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:115:28 + --> tests/ui/transmute_ptr_to_ptr.rs:138:28 | LL | let _: *const u8 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -162,5 +210,5 @@ LL - let _: *const u8 = transmute(mut_ptr); LL + let _: *const u8 = mut_ptr.cast_const(); | -error: aborting due to 16 previous errors +error: aborting due to 20 previous errors From 9f1724d3ac8c3cf07658f973379fe2ccc425c1b3 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 2 Dec 2025 00:22:05 +0530 Subject: [PATCH 0210/3801] use `wrapping_add` for `_kadd` intrinsics --- library/stdarch/crates/core_arch/src/x86/avx512bw.rs | 4 ++-- library/stdarch/crates/core_arch/src/x86/avx512dq.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 0073bdeb4acd..5d17d42532f1 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -10254,7 +10254,7 @@ pub fn _cvtu32_mask32(a: u32) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _kadd_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { - a + b + a.wrapping_add(b) } /// Add 64-bit masks in a and b, and store the result in k. @@ -10264,7 +10264,7 @@ pub fn _kadd_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _kadd_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { - a + b + a.wrapping_add(b) } /// Compute the bitwise AND of 32-bit masks a and b, and store the result in k. diff --git a/library/stdarch/crates/core_arch/src/x86/avx512dq.rs b/library/stdarch/crates/core_arch/src/x86/avx512dq.rs index afeb548a553c..a69168750283 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512dq.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512dq.rs @@ -4486,7 +4486,7 @@ pub fn _cvtu32_mask8(a: u32) -> __mmask8 { #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _kadd_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { - a + b + a.wrapping_add(b) } /// Add 8-bit masks a and b, and store the result in dst. @@ -4496,7 +4496,7 @@ pub fn _kadd_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _kadd_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { - a + b + a.wrapping_add(b) } /// Bitwise AND of 8-bit masks a and b, and store the result in dst. From b3381908ba29b10fc84b52ab31d32acaed36bb71 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 1 Dec 2025 21:38:23 +0100 Subject: [PATCH 0211/3801] Update src/solve/invariants.md Co-authored-by: Tshepang Mbambo --- src/doc/rustc-dev-guide/src/solve/invariants.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/solve/invariants.md b/src/doc/rustc-dev-guide/src/solve/invariants.md index bdf974099f2f..d6e360cbc682 100644 --- a/src/doc/rustc-dev-guide/src/solve/invariants.md +++ b/src/doc/rustc-dev-guide/src/solve/invariants.md @@ -121,7 +121,7 @@ We do however break this invariant in a few cases, some of which are due to bugs If a goal can be proven in a generic environment, the goal should still hold after instantiating it with fully concrete types and no where-clauses in scope. -This is assumed by codegen whicih ICEs when encountering non-overflow ambiguity. This invariant is currently broken by specialization ([#147507](https://github.com/rust-lang/rust/issues/147507)) and by marker traits ([#149502](https://github.com/rust-lang/rust/issues/149502)). +This is assumed by codegen which ICEs when encountering non-overflow ambiguity. This invariant is currently broken by specialization ([#147507](https://github.com/rust-lang/rust/issues/147507)) and by marker traits ([#149502](https://github.com/rust-lang/rust/issues/149502)). #### The type system is complete during the implicit negative overlap check in coherence ✅ From f0f0b8b2225ab6694e1cc08ce2d17867d7afe50c Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Tue, 4 Nov 2025 19:54:11 +0530 Subject: [PATCH 0212/3801] feat: configure test-files to run all intrinsics in the same process --- .../crates/intrinsic-test/src/common/gen_c.rs | 16 ++++------------ .../crates/intrinsic-test/src/common/gen_rust.rs | 12 +++--------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs index 04741e4f8075..30f359a27ef1 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs @@ -147,22 +147,14 @@ pub fn write_main_cpp<'a>( } writeln!(w, "int main(int argc, char **argv) {{")?; - writeln!(w, " std::string intrinsic_name = argv[1];")?; - - writeln!(w, " if (false) {{")?; for intrinsic in intrinsics { - writeln!(w, " }} else if (intrinsic_name == \"{intrinsic}\") {{")?; - writeln!(w, " return run_{intrinsic}();")?; + writeln!(w, " std::cout << \"############\" << std::endl;")?; + writeln!(w, " std::cout << \"{intrinsic}\" << std::endl;")?; + writeln!(w, " run_{intrinsic}();\n")?; } - writeln!(w, " }} else {{")?; - writeln!( - w, - " std::cerr << \"Unknown command: \" << intrinsic_name << \"\\n\";" - )?; - writeln!(w, " return -1;")?; - writeln!(w, " }}")?; + writeln!(w, " return 0;")?; writeln!(w, "}}")?; diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs index c8d815e46eae..afc6ca45561a 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs @@ -86,18 +86,12 @@ pub fn write_main_rs<'a>( writeln!(w, "fn main() {{")?; - writeln!(w, " match std::env::args().nth(1).unwrap().as_str() {{")?; - for binary in intrinsics { - writeln!(w, " \"{binary}\" => run_{binary}(),")?; + writeln!(w, " println!(\"############\");")?; + writeln!(w, " println!(\"{binary}\");")?; + writeln!(w, " run_{binary}();\n")?; } - writeln!( - w, - " other => panic!(\"unknown intrinsic `{{}}`\", other)," - )?; - - writeln!(w, " }}")?; writeln!(w, "}}")?; Ok(()) From 344acad879d8cc84581329fd3c64cfacc9b80888 Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Tue, 4 Nov 2025 21:54:56 +0530 Subject: [PATCH 0213/3801] feat: modified the compare function to check one huge output stream instead of len(intrinsic) output streams --- .../intrinsic-test/src/common/compare.rs | 149 +++++++++--------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/library/stdarch/crates/intrinsic-test/src/common/compare.rs b/library/stdarch/crates/intrinsic-test/src/common/compare.rs index c0459b743a7f..96a0bb94aab4 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/compare.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/compare.rs @@ -1,6 +1,7 @@ use super::cli::FailureReason; +use itertools::Itertools; use rayon::prelude::*; -use std::process::Command; +use std::{collections::HashMap, process::Command}; fn runner_command(runner: &str) -> Command { let mut it = runner.split_whitespace(); @@ -11,85 +12,83 @@ fn runner_command(runner: &str) -> Command { } pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: &str) -> bool { - let intrinsics = intrinsic_name_list + let c = runner_command(runner) + .arg("./intrinsic-test-programs") + .current_dir("c_programs") + .output(); + + let rust = runner_command(runner) + .arg(format!("./target/{target}/release/intrinsic-test-programs")) + .current_dir("rust_programs") + .output(); + + let (c, rust) = match (c, rust) { + (Ok(c), Ok(rust)) => (c, rust), + a => panic!("{a:#?}"), + }; + + if !c.status.success() { + error!( + "Failed to run C program.\nstdout: {stdout}\nstderr: {stderr}", + stdout = std::str::from_utf8(&c.stdout).unwrap_or(""), + stderr = std::str::from_utf8(&c.stderr).unwrap_or(""), + ); + } + + if !rust.status.success() { + error!( + "Failed to run Rust program.\nstdout: {stdout}\nstderr: {stderr}", + stdout = std::str::from_utf8(&rust.stdout).unwrap_or(""), + stderr = std::str::from_utf8(&rust.stderr).unwrap_or(""), + ); + } + + let c = std::str::from_utf8(&c.stdout) + .unwrap() + .to_lowercase() + .replace("-nan", "nan"); + let rust = std::str::from_utf8(&rust.stdout) + .unwrap() + .to_lowercase() + .replace("-nan", "nan"); + + let c_output_map = c.split("############") + .filter_map(|output| output.trim().split_once("\n")) + .collect::>(); + let rust_output_map = rust.split("############") + .filter_map(|output| output.trim().split_once("\n")) + .collect::>(); + + let intrinsics = c_output_map.keys().chain(rust_output_map.keys()).unique().collect_vec(); + let intrinsics_diff_count = intrinsics .par_iter() - .filter_map(|intrinsic_name| { - let c = runner_command(runner) - .arg("./intrinsic-test-programs") - .arg(intrinsic_name) - .current_dir("c_programs") - .output(); - - let rust = runner_command(runner) - .arg(format!("./target/{target}/release/intrinsic-test-programs")) - .arg(intrinsic_name) - .current_dir("rust_programs") - .output(); - - let (c, rust) = match (c, rust) { - (Ok(c), Ok(rust)) => (c, rust), - a => panic!("{a:#?}"), - }; - - if !c.status.success() { - error!( - "Failed to run C program for intrinsic `{intrinsic_name}`\nstdout: {stdout}\nstderr: {stderr}", - stdout = std::str::from_utf8(&c.stdout).unwrap_or(""), - stderr = std::str::from_utf8(&c.stderr).unwrap_or(""), - ); - return Some(FailureReason::RunC(intrinsic_name.clone())); - } - - if !rust.status.success() { - error!( - "Failed to run Rust program for intrinsic `{intrinsic_name}`\nstdout: {stdout}\nstderr: {stderr}", - stdout = std::str::from_utf8(&rust.stdout).unwrap_or(""), - stderr = std::str::from_utf8(&rust.stderr).unwrap_or(""), - ); - return Some(FailureReason::RunRust(intrinsic_name.clone())); - } - - info!("Comparing intrinsic: {intrinsic_name}"); - - let c = std::str::from_utf8(&c.stdout) - .unwrap() - .to_lowercase() - .replace("-nan", "nan"); - let rust = std::str::from_utf8(&rust.stdout) - .unwrap() - .to_lowercase() - .replace("-nan", "nan"); - - if c == rust { - None - } else { - Some(FailureReason::Difference(intrinsic_name.clone(), c, rust)) - } - }) - .collect::>(); - - intrinsics.iter().for_each(|reason| match reason { - FailureReason::Difference(intrinsic, c, rust) => { + .filter_map(|&&intrinsic| { println!("Difference for intrinsic: {intrinsic}"); - let diff = diff::lines(c, rust); - diff.iter().for_each(|diff| match diff { - diff::Result::Left(c) => println!("C: {c}"), - diff::Result::Right(rust) => println!("Rust: {rust}"), - diff::Result::Both(_, _) => (), - }); + let c_output = c_output_map.get(intrinsic).unwrap(); + let rust_output = rust_output_map.get(intrinsic).unwrap(); + let diff = diff::lines(c_output, rust_output); + let diff_count = diff.into_iter().filter_map(|diff| match diff { + diff::Result::Left(c) => { + println!("C: {c}"); + Some(c) + } + diff::Result::Right(rust) => { + println!("Rust: {rust}"); + Some(rust) + } + diff::Result::Both(_, _) => None, + }).count(); println!("****************************************************************"); - } - FailureReason::RunC(intrinsic) => { - println!("Failed to run C program for intrinsic {intrinsic}") - } - FailureReason::RunRust(intrinsic) => { - println!("Failed to run rust program for intrinsic {intrinsic}") - } - }); + if diff_count > 0 { + Some(intrinsic) + } else { None } + }).count(); + println!( "{} differences found (tested {} intrinsics)", - intrinsics.len(), + intrinsics_diff_count, intrinsic_name_list.len() ); - intrinsics.is_empty() + + intrinsics_diff_count == 0 } From a472b5dcd904c5dd25b3b84cfe862ccaf134acb0 Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Tue, 4 Nov 2025 22:02:20 +0530 Subject: [PATCH 0214/3801] chore: formatting checks --- .../crates/intrinsic-test/src/common/cli.rs | 6 --- .../intrinsic-test/src/common/compare.rs | 53 +++++++++++-------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/library/stdarch/crates/intrinsic-test/src/common/cli.rs b/library/stdarch/crates/intrinsic-test/src/common/cli.rs index 461ab542ea89..ff34ef3d2d3d 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/cli.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/cli.rs @@ -7,12 +7,6 @@ pub enum Language { C, } -pub enum FailureReason { - RunC(String), - RunRust(String), - Difference(String, String, String), -} - /// Intrinsic test tool #[derive(clap::Parser)] #[command( diff --git a/library/stdarch/crates/intrinsic-test/src/common/compare.rs b/library/stdarch/crates/intrinsic-test/src/common/compare.rs index 96a0bb94aab4..4ab2a3365737 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/compare.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/compare.rs @@ -1,4 +1,3 @@ -use super::cli::FailureReason; use itertools::Itertools; use rayon::prelude::*; use std::{collections::HashMap, process::Command}; @@ -21,12 +20,12 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: .arg(format!("./target/{target}/release/intrinsic-test-programs")) .current_dir("rust_programs") .output(); - + let (c, rust) = match (c, rust) { (Ok(c), Ok(rust)) => (c, rust), a => panic!("{a:#?}"), }; - + if !c.status.success() { error!( "Failed to run C program.\nstdout: {stdout}\nstderr: {stderr}", @@ -34,7 +33,7 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: stderr = std::str::from_utf8(&c.stderr).unwrap_or(""), ); } - + if !rust.status.success() { error!( "Failed to run Rust program.\nstdout: {stdout}\nstderr: {stderr}", @@ -51,15 +50,21 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: .unwrap() .to_lowercase() .replace("-nan", "nan"); - - let c_output_map = c.split("############") + + let c_output_map = c + .split("############") .filter_map(|output| output.trim().split_once("\n")) .collect::>(); - let rust_output_map = rust.split("############") + let rust_output_map = rust + .split("############") .filter_map(|output| output.trim().split_once("\n")) .collect::>(); - let intrinsics = c_output_map.keys().chain(rust_output_map.keys()).unique().collect_vec(); + let intrinsics = c_output_map + .keys() + .chain(rust_output_map.keys()) + .unique() + .collect_vec(); let intrinsics_diff_count = intrinsics .par_iter() .filter_map(|&&intrinsic| { @@ -67,22 +72,28 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: let c_output = c_output_map.get(intrinsic).unwrap(); let rust_output = rust_output_map.get(intrinsic).unwrap(); let diff = diff::lines(c_output, rust_output); - let diff_count = diff.into_iter().filter_map(|diff| match diff { - diff::Result::Left(c) => { - println!("C: {c}"); - Some(c) - } - diff::Result::Right(rust) => { - println!("Rust: {rust}"); - Some(rust) - } - diff::Result::Both(_, _) => None, - }).count(); + let diff_count = diff + .into_iter() + .filter_map(|diff| match diff { + diff::Result::Left(c) => { + println!("C: {c}"); + Some(c) + } + diff::Result::Right(rust) => { + println!("Rust: {rust}"); + Some(rust) + } + diff::Result::Both(_, _) => None, + }) + .count(); println!("****************************************************************"); if diff_count > 0 { Some(intrinsic) - } else { None } - }).count(); + } else { + None + } + }) + .count(); println!( "{} differences found (tested {} intrinsics)", From 09a67dfab090818158baf8a55ecff88a42531312 Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Tue, 4 Nov 2025 22:09:13 +0530 Subject: [PATCH 0215/3801] feat: increase TEST_SAMPLE_INTRINSICS_PERCENTAGE of x86_64 to 30% --- library/stdarch/ci/intrinsic-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/stdarch/ci/intrinsic-test.sh b/library/stdarch/ci/intrinsic-test.sh index a8f96897bc23..2b40044462aa 100755 --- a/library/stdarch/ci/intrinsic-test.sh +++ b/library/stdarch/ci/intrinsic-test.sh @@ -75,7 +75,7 @@ case ${TARGET} in TEST_CXX_COMPILER="clang++" TEST_RUNNER="${CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER}" TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_x86.txt - : "${TEST_SAMPLE_INTRINSICS_PERCENTAGE:=5}" + : "${TEST_SAMPLE_INTRINSICS_PERCENTAGE:=30}" ;; *) ;; From 99fbd39a7d7a84afd3f161df3368480bba9c60dc Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Tue, 4 Nov 2025 22:52:33 +0530 Subject: [PATCH 0216/3801] fix: update the comparison algorithm for cleaner comparisons --- .../intrinsic-test/src/common/compare.rs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/library/stdarch/crates/intrinsic-test/src/common/compare.rs b/library/stdarch/crates/intrinsic-test/src/common/compare.rs index 4ab2a3365737..38fa8dc0ec99 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/compare.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/compare.rs @@ -68,31 +68,31 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: let intrinsics_diff_count = intrinsics .par_iter() .filter_map(|&&intrinsic| { - println!("Difference for intrinsic: {intrinsic}"); let c_output = c_output_map.get(intrinsic).unwrap(); let rust_output = rust_output_map.get(intrinsic).unwrap(); let diff = diff::lines(c_output, rust_output); - let diff_count = diff + let diffs = diff .into_iter() .filter_map(|diff| match diff { - diff::Result::Left(c) => { - println!("C: {c}"); - Some(c) - } - diff::Result::Right(rust) => { - println!("Rust: {rust}"); - Some(rust) - } + diff::Result::Left(_) | diff::Result::Right(_) => Some(diff), diff::Result::Both(_, _) => None, }) - .count(); - println!("****************************************************************"); - if diff_count > 0 { - Some(intrinsic) + .collect_vec(); + if diffs.len() > 0 { + Some((intrinsic, diffs)) } else { None } }) + .inspect(|(intrinsic, diffs)| { + println!("Difference for intrinsic: {intrinsic}"); + diffs.into_iter().for_each(|diff| match diff { + diff::Result::Left(c) => println!("C: {c}"), + diff::Result::Right(rust) => println!("Rust: {rust}"), + _ => (), + }); + println!("****************************************************************"); + }) .count(); println!( From 998aff3dc57b4c951291d7ca5316ee74b0e09373 Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Tue, 4 Nov 2025 23:34:33 +0530 Subject: [PATCH 0217/3801] feat: add equality checks to reduce computation spent on equal outputs --- .../intrinsic-test/src/common/compare.rs | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/library/stdarch/crates/intrinsic-test/src/common/compare.rs b/library/stdarch/crates/intrinsic-test/src/common/compare.rs index 38fa8dc0ec99..b89059f9ebfc 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/compare.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/compare.rs @@ -11,16 +11,20 @@ fn runner_command(runner: &str) -> Command { } pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: &str) -> bool { - let c = runner_command(runner) - .arg("./intrinsic-test-programs") - .current_dir("c_programs") - .output(); - - let rust = runner_command(runner) - .arg(format!("./target/{target}/release/intrinsic-test-programs")) - .current_dir("rust_programs") - .output(); - + let (c, rust) = rayon::join( + || { + runner_command(runner) + .arg("./intrinsic-test-programs") + .current_dir("c_programs") + .output() + }, + || { + runner_command(runner) + .arg(format!("./target/{target}/release/intrinsic-test-programs")) + .current_dir("rust_programs") + .output() + }, + ); let (c, rust) = match (c, rust) { (Ok(c), Ok(rust)) => (c, rust), a => panic!("{a:#?}"), @@ -70,18 +74,22 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: .filter_map(|&&intrinsic| { let c_output = c_output_map.get(intrinsic).unwrap(); let rust_output = rust_output_map.get(intrinsic).unwrap(); - let diff = diff::lines(c_output, rust_output); - let diffs = diff - .into_iter() - .filter_map(|diff| match diff { - diff::Result::Left(_) | diff::Result::Right(_) => Some(diff), - diff::Result::Both(_, _) => None, - }) - .collect_vec(); - if diffs.len() > 0 { - Some((intrinsic, diffs)) - } else { + if rust_output.to_string() == c_output.to_string() { None + } else { + let diff = diff::lines(c_output, rust_output); + let diffs = diff + .into_iter() + .filter_map(|diff| match diff { + diff::Result::Left(_) | diff::Result::Right(_) => Some(diff), + diff::Result::Both(_, _) => None, + }) + .collect_vec(); + if diffs.len() > 0 { + Some((intrinsic, diffs)) + } else { + None + } } }) .inspect(|(intrinsic, diffs)| { From 7215e078f575aec225aeca06a13999b6cf16f532 Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Wed, 5 Nov 2025 11:20:12 +0530 Subject: [PATCH 0218/3801] feat: extract the delimiter to a const value for uniformity --- .../stdarch/crates/intrinsic-test/src/common/compare.rs | 9 +++++---- .../stdarch/crates/intrinsic-test/src/common/gen_c.rs | 6 +++++- .../stdarch/crates/intrinsic-test/src/common/gen_rust.rs | 8 ++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/library/stdarch/crates/intrinsic-test/src/common/compare.rs b/library/stdarch/crates/intrinsic-test/src/common/compare.rs index b89059f9ebfc..7c5d87b51fe3 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/compare.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/compare.rs @@ -2,6 +2,7 @@ use itertools::Itertools; use rayon::prelude::*; use std::{collections::HashMap, process::Command}; +pub const INTRINSIC_DELIMITER: &str = "############"; fn runner_command(runner: &str) -> Command { let mut it = runner.split_whitespace(); let mut cmd = Command::new(it.next().unwrap()); @@ -27,7 +28,7 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: ); let (c, rust) = match (c, rust) { (Ok(c), Ok(rust)) => (c, rust), - a => panic!("{a:#?}"), + failure => panic!("Failed to run: {failure:#?}"), }; if !c.status.success() { @@ -56,11 +57,11 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: .replace("-nan", "nan"); let c_output_map = c - .split("############") + .split(INTRINSIC_DELIMITER) .filter_map(|output| output.trim().split_once("\n")) .collect::>(); let rust_output_map = rust - .split("############") + .split(INTRINSIC_DELIMITER) .filter_map(|output| output.trim().split_once("\n")) .collect::>(); @@ -74,7 +75,7 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: .filter_map(|&&intrinsic| { let c_output = c_output_map.get(intrinsic).unwrap(); let rust_output = rust_output_map.get(intrinsic).unwrap(); - if rust_output.to_string() == c_output.to_string() { + if rust_output.eq(c_output) { None } else { let diff = diff::lines(c_output, rust_output); diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs index 30f359a27ef1..a95b4c36b7bf 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs @@ -1,6 +1,7 @@ use crate::common::intrinsic::Intrinsic; use super::argument::Argument; +use super::compare::INTRINSIC_DELIMITER; use super::indentation::Indentation; use super::intrinsic_helpers::IntrinsicTypeDefinition; @@ -149,7 +150,10 @@ pub fn write_main_cpp<'a>( writeln!(w, "int main(int argc, char **argv) {{")?; for intrinsic in intrinsics { - writeln!(w, " std::cout << \"############\" << std::endl;")?; + writeln!( + w, + " std::cout << \"{INTRINSIC_DELIMITER}\" << std::endl;" + )?; writeln!(w, " std::cout << \"{intrinsic}\" << std::endl;")?; writeln!(w, " run_{intrinsic}();\n")?; } diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs index afc6ca45561a..fb047e2612de 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs @@ -1,11 +1,11 @@ use itertools::Itertools; use std::process::Command; -use crate::common::argument::ArgumentList; -use crate::common::intrinsic::Intrinsic; - +use super::compare::INTRINSIC_DELIMITER; use super::indentation::Indentation; use super::intrinsic_helpers::IntrinsicTypeDefinition; +use crate::common::argument::ArgumentList; +use crate::common::intrinsic::Intrinsic; // The number of times each intrinsic will be called. pub(crate) const PASSES: u32 = 20; @@ -87,7 +87,7 @@ pub fn write_main_rs<'a>( writeln!(w, "fn main() {{")?; for binary in intrinsics { - writeln!(w, " println!(\"############\");")?; + writeln!(w, " println!(\"{INTRINSIC_DELIMITER}\");")?; writeln!(w, " println!(\"{binary}\");")?; writeln!(w, " run_{binary}();\n")?; } From 060b4d347c9e63a4388336c61c2963384224214e Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Wed, 5 Nov 2025 11:57:59 +0530 Subject: [PATCH 0219/3801] feat: reduce the intrinsics coverage for x86_64 intrinsics --- library/stdarch/ci/intrinsic-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/stdarch/ci/intrinsic-test.sh b/library/stdarch/ci/intrinsic-test.sh index 2b40044462aa..ff76a0c76996 100755 --- a/library/stdarch/ci/intrinsic-test.sh +++ b/library/stdarch/ci/intrinsic-test.sh @@ -75,7 +75,7 @@ case ${TARGET} in TEST_CXX_COMPILER="clang++" TEST_RUNNER="${CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER}" TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_x86.txt - : "${TEST_SAMPLE_INTRINSICS_PERCENTAGE:=30}" + : "${TEST_SAMPLE_INTRINSICS_PERCENTAGE:=20}" ;; *) ;; From d5c259097287375ea8a3f11381d8832d4f4b3eef Mon Sep 17 00:00:00 2001 From: Madhav Madhusoodanan Date: Wed, 5 Nov 2025 12:41:58 +0530 Subject: [PATCH 0220/3801] chore: logging to trace the time taken by binaries to complete a run --- library/stdarch/crates/intrinsic-test/src/common/compare.rs | 3 +++ library/stdarch/crates/intrinsic-test/src/main.rs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/library/stdarch/crates/intrinsic-test/src/common/compare.rs b/library/stdarch/crates/intrinsic-test/src/common/compare.rs index 7c5d87b51fe3..c4c2a1e3e482 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/compare.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/compare.rs @@ -47,6 +47,7 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: ); } + info!("Completed running C++ and Rust test binaries"); let c = std::str::from_utf8(&c.stdout) .unwrap() .to_lowercase() @@ -70,6 +71,8 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: .chain(rust_output_map.keys()) .unique() .collect_vec(); + + info!("Comparing outputs"); let intrinsics_diff_count = intrinsics .par_iter() .filter_map(|&&intrinsic| { diff --git a/library/stdarch/crates/intrinsic-test/src/main.rs b/library/stdarch/crates/intrinsic-test/src/main.rs index 3580d80bd112..e5c846877ce6 100644 --- a/library/stdarch/crates/intrinsic-test/src/main.rs +++ b/library/stdarch/crates/intrinsic-test/src/main.rs @@ -34,7 +34,7 @@ fn run(test_environment: impl SupportedArchitectureTest) { if !test_environment.build_rust_file() { std::process::exit(3); } - info!("comparing outputs"); + info!("Running binaries"); if !test_environment.compare_outputs() { std::process::exit(1); } From b963d298528db5881c1c594bb4aed8ffb1f57cbb Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 11 Nov 2025 03:43:37 +0530 Subject: [PATCH 0221/3801] Use ordered reduction intrinsics for integer reductions only ordered intrinsics have implementation in rustc-const-eval --- .../crates/core_arch/src/x86/avx512bw.rs | 32 +++++++++---------- .../crates/core_arch/src/x86/avx512f.rs | 30 ++++++++--------- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 5d17d42532f1..c76ec3cb290e 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -4778,7 +4778,7 @@ pub fn _mm_mask_cmp_epi8_mask(k1: __mmask16, a: __m128i, b: __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm256_reduce_add_epi16(a: __m256i) -> i16 { - unsafe { simd_reduce_add_unordered(a.as_i16x16()) } + unsafe { simd_reduce_add_ordered(a.as_i16x16(), 0) } } /// Reduce the packed 16-bit integers in a by addition using mask k. Returns the sum of all active elements in a. @@ -4788,7 +4788,7 @@ pub fn _mm256_reduce_add_epi16(a: __m256i) -> i16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm256_mask_reduce_add_epi16(k: __mmask16, a: __m256i) -> i16 { - unsafe { simd_reduce_add_unordered(simd_select_bitmask(k, a.as_i16x16(), i16x16::ZERO)) } + unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i16x16(), i16x16::ZERO), 0) } } /// Reduce the packed 16-bit integers in a by addition. Returns the sum of all elements in a. @@ -4798,7 +4798,7 @@ pub fn _mm256_mask_reduce_add_epi16(k: __mmask16, a: __m256i) -> i16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm_reduce_add_epi16(a: __m128i) -> i16 { - unsafe { simd_reduce_add_unordered(a.as_i16x8()) } + unsafe { simd_reduce_add_ordered(a.as_i16x8(), 0) } } /// Reduce the packed 16-bit integers in a by addition using mask k. Returns the sum of all active elements in a. @@ -4808,7 +4808,7 @@ pub fn _mm_reduce_add_epi16(a: __m128i) -> i16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm_mask_reduce_add_epi16(k: __mmask8, a: __m128i) -> i16 { - unsafe { simd_reduce_add_unordered(simd_select_bitmask(k, a.as_i16x8(), i16x8::ZERO)) } + unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i16x8(), i16x8::ZERO), 0) } } /// Reduce the packed 8-bit integers in a by addition. Returns the sum of all elements in a. @@ -4818,7 +4818,7 @@ pub fn _mm_mask_reduce_add_epi16(k: __mmask8, a: __m128i) -> i16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm256_reduce_add_epi8(a: __m256i) -> i8 { - unsafe { simd_reduce_add_unordered(a.as_i8x32()) } + unsafe { simd_reduce_add_ordered(a.as_i8x32(), 0) } } /// Reduce the packed 8-bit integers in a by addition using mask k. Returns the sum of all active elements in a. @@ -4828,7 +4828,7 @@ pub fn _mm256_reduce_add_epi8(a: __m256i) -> i8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm256_mask_reduce_add_epi8(k: __mmask32, a: __m256i) -> i8 { - unsafe { simd_reduce_add_unordered(simd_select_bitmask(k, a.as_i8x32(), i8x32::ZERO)) } + unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i8x32(), i8x32::ZERO), 0) } } /// Reduce the packed 8-bit integers in a by addition. Returns the sum of all elements in a. @@ -4838,7 +4838,7 @@ pub fn _mm256_mask_reduce_add_epi8(k: __mmask32, a: __m256i) -> i8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm_reduce_add_epi8(a: __m128i) -> i8 { - unsafe { simd_reduce_add_unordered(a.as_i8x16()) } + unsafe { simd_reduce_add_ordered(a.as_i8x16(), 0) } } /// Reduce the packed 8-bit integers in a by addition using mask k. Returns the sum of all active elements in a. @@ -4848,7 +4848,7 @@ pub fn _mm_reduce_add_epi8(a: __m128i) -> i8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm_mask_reduce_add_epi8(k: __mmask16, a: __m128i) -> i8 { - unsafe { simd_reduce_add_unordered(simd_select_bitmask(k, a.as_i8x16(), i8x16::ZERO)) } + unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i8x16(), i8x16::ZERO), 0) } } /// Reduce the packed 16-bit integers in a by bitwise AND. Returns the bitwise AND of all elements in a. @@ -5282,7 +5282,7 @@ pub fn _mm_mask_reduce_min_epu8(k: __mmask16, a: __m128i) -> u8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm256_reduce_mul_epi16(a: __m256i) -> i16 { - unsafe { simd_reduce_mul_unordered(a.as_i16x16()) } + unsafe { simd_reduce_mul_ordered(a.as_i16x16(), 1) } } /// Reduce the packed 16-bit integers in a by multiplication using mask k. Returns the product of all active elements in a. @@ -5292,7 +5292,7 @@ pub fn _mm256_reduce_mul_epi16(a: __m256i) -> i16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm256_mask_reduce_mul_epi16(k: __mmask16, a: __m256i) -> i16 { - unsafe { simd_reduce_mul_unordered(simd_select_bitmask(k, a.as_i16x16(), i16x16::splat(1))) } + unsafe { simd_reduce_mul_ordered(simd_select_bitmask(k, a.as_i16x16(), i16x16::splat(1)), 1) } } /// Reduce the packed 16-bit integers in a by multiplication. Returns the product of all elements in a. @@ -5302,7 +5302,7 @@ pub fn _mm256_mask_reduce_mul_epi16(k: __mmask16, a: __m256i) -> i16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm_reduce_mul_epi16(a: __m128i) -> i16 { - unsafe { simd_reduce_mul_unordered(a.as_i16x8()) } + unsafe { simd_reduce_mul_ordered(a.as_i16x8(), 1) } } /// Reduce the packed 16-bit integers in a by multiplication using mask k. Returns the product of all active elements in a. @@ -5312,7 +5312,7 @@ pub fn _mm_reduce_mul_epi16(a: __m128i) -> i16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm_mask_reduce_mul_epi16(k: __mmask8, a: __m128i) -> i16 { - unsafe { simd_reduce_mul_unordered(simd_select_bitmask(k, a.as_i16x8(), i16x8::splat(1))) } + unsafe { simd_reduce_mul_ordered(simd_select_bitmask(k, a.as_i16x8(), i16x8::splat(1)), 1) } } /// Reduce the packed 8-bit integers in a by multiplication. Returns the product of all elements in a. @@ -5322,7 +5322,7 @@ pub fn _mm_mask_reduce_mul_epi16(k: __mmask8, a: __m128i) -> i16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm256_reduce_mul_epi8(a: __m256i) -> i8 { - unsafe { simd_reduce_mul_unordered(a.as_i8x32()) } + unsafe { simd_reduce_mul_ordered(a.as_i8x32(), 1) } } /// Reduce the packed 8-bit integers in a by multiplication using mask k. Returns the product of all active elements in a. @@ -5332,7 +5332,7 @@ pub fn _mm256_reduce_mul_epi8(a: __m256i) -> i8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm256_mask_reduce_mul_epi8(k: __mmask32, a: __m256i) -> i8 { - unsafe { simd_reduce_mul_unordered(simd_select_bitmask(k, a.as_i8x32(), i8x32::splat(1))) } + unsafe { simd_reduce_mul_ordered(simd_select_bitmask(k, a.as_i8x32(), i8x32::splat(1)), 1) } } /// Reduce the packed 8-bit integers in a by multiplication. Returns the product of all elements in a. @@ -5342,7 +5342,7 @@ pub fn _mm256_mask_reduce_mul_epi8(k: __mmask32, a: __m256i) -> i8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm_reduce_mul_epi8(a: __m128i) -> i8 { - unsafe { simd_reduce_mul_unordered(a.as_i8x16()) } + unsafe { simd_reduce_mul_ordered(a.as_i8x16(), 1) } } /// Reduce the packed 8-bit integers in a by multiplication using mask k. Returns the product of all active elements in a. @@ -5352,7 +5352,7 @@ pub fn _mm_reduce_mul_epi8(a: __m128i) -> i8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm_mask_reduce_mul_epi8(k: __mmask16, a: __m128i) -> i8 { - unsafe { simd_reduce_mul_unordered(simd_select_bitmask(k, a.as_i8x16(), i8x16::splat(1))) } + unsafe { simd_reduce_mul_ordered(simd_select_bitmask(k, a.as_i8x16(), i8x16::splat(1)), 1) } } /// Reduce the packed 16-bit integers in a by bitwise OR. Returns the bitwise OR of all elements in a. diff --git a/library/stdarch/crates/core_arch/src/x86/avx512f.rs b/library/stdarch/crates/core_arch/src/x86/avx512f.rs index 8d3ddbd964bb..d6b30d2d7d86 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512f.rs @@ -33101,7 +33101,7 @@ pub fn _mm_mask_cmp_epi64_mask( #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm512_reduce_add_epi32(a: __m512i) -> i32 { - unsafe { simd_reduce_add_unordered(a.as_i32x16()) } + unsafe { simd_reduce_add_ordered(a.as_i32x16(), 0) } } /// Reduce the packed 32-bit integers in a by addition using mask k. Returns the sum of all active elements in a. @@ -33111,7 +33111,7 @@ pub fn _mm512_reduce_add_epi32(a: __m512i) -> i32 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm512_mask_reduce_add_epi32(k: __mmask16, a: __m512i) -> i32 { - unsafe { simd_reduce_add_unordered(simd_select_bitmask(k, a.as_i32x16(), i32x16::ZERO)) } + unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i32x16(), i32x16::ZERO), 0) } } /// Reduce the packed 64-bit integers in a by addition. Returns the sum of all elements in a. @@ -33121,7 +33121,7 @@ pub fn _mm512_mask_reduce_add_epi32(k: __mmask16, a: __m512i) -> i32 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm512_reduce_add_epi64(a: __m512i) -> i64 { - unsafe { simd_reduce_add_unordered(a.as_i64x8()) } + unsafe { simd_reduce_add_ordered(a.as_i64x8(), 0) } } /// Reduce the packed 64-bit integers in a by addition using mask k. Returns the sum of all active elements in a. @@ -33131,7 +33131,7 @@ pub fn _mm512_reduce_add_epi64(a: __m512i) -> i64 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm512_mask_reduce_add_epi64(k: __mmask8, a: __m512i) -> i64 { - unsafe { simd_reduce_add_unordered(simd_select_bitmask(k, a.as_i64x8(), i64x8::ZERO)) } + unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i64x8(), i64x8::ZERO), 0) } } /// Reduce the packed single-precision (32-bit) floating-point elements in a by addition. Returns the sum of all elements in a. @@ -33197,7 +33197,7 @@ pub fn _mm512_mask_reduce_add_pd(k: __mmask8, a: __m512d) -> f64 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm512_reduce_mul_epi32(a: __m512i) -> i32 { - unsafe { simd_reduce_mul_unordered(a.as_i32x16()) } + unsafe { simd_reduce_mul_ordered(a.as_i32x16(), 1) } } /// Reduce the packed 32-bit integers in a by multiplication using mask k. Returns the product of all active elements in a. @@ -33208,11 +33208,10 @@ pub fn _mm512_reduce_mul_epi32(a: __m512i) -> i32 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm512_mask_reduce_mul_epi32(k: __mmask16, a: __m512i) -> i32 { unsafe { - simd_reduce_mul_unordered(simd_select_bitmask( - k, - a.as_i32x16(), - _mm512_set1_epi32(1).as_i32x16(), - )) + simd_reduce_mul_ordered( + simd_select_bitmask(k, a.as_i32x16(), _mm512_set1_epi32(1).as_i32x16()), + 1, + ) } } @@ -33223,7 +33222,7 @@ pub fn _mm512_mask_reduce_mul_epi32(k: __mmask16, a: __m512i) -> i32 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm512_reduce_mul_epi64(a: __m512i) -> i64 { - unsafe { simd_reduce_mul_unordered(a.as_i64x8()) } + unsafe { simd_reduce_mul_ordered(a.as_i64x8(), 1) } } /// Reduce the packed 64-bit integers in a by multiplication using mask k. Returns the product of all active elements in a. @@ -33234,11 +33233,10 @@ pub fn _mm512_reduce_mul_epi64(a: __m512i) -> i64 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] pub fn _mm512_mask_reduce_mul_epi64(k: __mmask8, a: __m512i) -> i64 { unsafe { - simd_reduce_mul_unordered(simd_select_bitmask( - k, - a.as_i64x8(), - _mm512_set1_epi64(1).as_i64x8(), - )) + simd_reduce_mul_ordered( + simd_select_bitmask(k, a.as_i64x8(), _mm512_set1_epi64(1).as_i64x8()), + 1, + ) } } From 453377b0ffac4c0f4b70340ee17045faf55f23da Mon Sep 17 00:00:00 2001 From: sayantn Date: Mon, 15 Sep 2025 04:50:49 +0530 Subject: [PATCH 0222/3801] Make some helpers `const` --- library/stdarch/crates/core_arch/src/lib.rs | 5 +- library/stdarch/crates/core_arch/src/mod.rs | 5 + library/stdarch/crates/core_arch/src/simd.rs | 24 +- library/stdarch/crates/core_arch/src/test.rs | 25 ++ .../crates/core_arch/src/x86/avx512fp16.rs | 9 +- .../stdarch/crates/core_arch/src/x86/mod.rs | 4 +- .../stdarch/crates/core_arch/src/x86/test.rs | 295 +++++++++++------- 7 files changed, 247 insertions(+), 120 deletions(-) create mode 100644 library/stdarch/crates/core_arch/src/test.rs diff --git a/library/stdarch/crates/core_arch/src/lib.rs b/library/stdarch/crates/core_arch/src/lib.rs index a059a9c22570..5bedefe42d6e 100644 --- a/library/stdarch/crates/core_arch/src/lib.rs +++ b/library/stdarch/crates/core_arch/src/lib.rs @@ -34,7 +34,10 @@ aarch64_unstable_target_feature, bigint_helper_methods, funnel_shifts, - avx10_target_feature + avx10_target_feature, + const_trait_impl, + const_cmp, + const_eval_select )] #![cfg_attr(test, feature(test, abi_vectorcall, stdarch_internal))] #![deny(clippy::missing_inline_in_public_items)] diff --git a/library/stdarch/crates/core_arch/src/mod.rs b/library/stdarch/crates/core_arch/src/mod.rs index 2105cca1b438..7fc0ed0fca11 100644 --- a/library/stdarch/crates/core_arch/src/mod.rs +++ b/library/stdarch/crates/core_arch/src/mod.rs @@ -5,6 +5,11 @@ #[macro_use] mod macros; +#[cfg(test)] +mod test; +#[cfg(test)] +use test::assert_eq_const; + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64", doc))] mod riscv_shared; diff --git a/library/stdarch/crates/core_arch/src/simd.rs b/library/stdarch/crates/core_arch/src/simd.rs index 9fa8e2502265..b9dbde75971d 100644 --- a/library/stdarch/crates/core_arch/src/simd.rs +++ b/library/stdarch/crates/core_arch/src/simd.rs @@ -3,13 +3,15 @@ #![allow(non_camel_case_types)] #[inline(always)] -pub(crate) unsafe fn simd_imax(a: T, b: T) -> T { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub(crate) const unsafe fn simd_imax(a: T, b: T) -> T { let mask: T = crate::intrinsics::simd::simd_gt(a, b); crate::intrinsics::simd::simd_select(mask, a, b) } #[inline(always)] -pub(crate) unsafe fn simd_imin(a: T, b: T) -> T { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub(crate) const unsafe fn simd_imin(a: T, b: T) -> T { let mask: T = crate::intrinsics::simd::simd_lt(a, b); crate::intrinsics::simd::simd_select(mask, a, b) } @@ -35,7 +37,8 @@ macro_rules! simd_ty { } // FIXME: Workaround rust@60637 #[inline(always)] - pub(crate) fn splat(value: $elem_type) -> Self { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + pub(crate) const fn splat(value: $elem_type) -> Self { #[derive(Copy, Clone)] #[repr(simd)] struct JustOne([$elem_type; 1]); @@ -50,12 +53,12 @@ macro_rules! simd_ty { /// Use for testing only. // FIXME: Workaround rust@60637 #[inline(always)] - pub(crate) fn extract(&self, index: usize) -> $elem_type { + pub(crate) const fn extract(&self, index: usize) -> $elem_type { self.as_array()[index] } #[inline] - pub(crate) fn as_array(&self) -> &[$elem_type; $len] { + pub(crate) const fn as_array(&self) -> &[$elem_type; $len] { let simd_ptr: *const Self = self; let array_ptr: *const [$elem_type; $len] = simd_ptr.cast(); // SAFETY: We can always read the prefix of a simd type as an array. @@ -65,7 +68,8 @@ macro_rules! simd_ty { } } - impl core::cmp::PartialEq for $id { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + const impl core::cmp::PartialEq for $id { #[inline] fn eq(&self, other: &Self) -> bool { self.as_array() == other.as_array() @@ -101,7 +105,8 @@ macro_rules! simd_m_ty { // FIXME: Workaround rust@60637 #[inline(always)] - pub(crate) fn splat(value: bool) -> Self { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + pub(crate) const fn splat(value: bool) -> Self { #[derive(Copy, Clone)] #[repr(simd)] struct JustOne([$elem_type; 1]); @@ -112,7 +117,7 @@ macro_rules! simd_m_ty { } #[inline] - pub(crate) fn as_array(&self) -> &[$elem_type; $len] { + pub(crate) const fn as_array(&self) -> &[$elem_type; $len] { let simd_ptr: *const Self = self; let array_ptr: *const [$elem_type; $len] = simd_ptr.cast(); // SAFETY: We can always read the prefix of a simd type as an array. @@ -122,7 +127,8 @@ macro_rules! simd_m_ty { } } - impl core::cmp::PartialEq for $id { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + const impl core::cmp::PartialEq for $id { #[inline] fn eq(&self, other: &Self) -> bool { self.as_array() == other.as_array() diff --git a/library/stdarch/crates/core_arch/src/test.rs b/library/stdarch/crates/core_arch/src/test.rs new file mode 100644 index 000000000000..976d4ac1b023 --- /dev/null +++ b/library/stdarch/crates/core_arch/src/test.rs @@ -0,0 +1,25 @@ +use crate::fmt::Debug; + +#[track_caller] +#[allow(unused)] +pub(crate) fn assert_eq_rt(a: &T, b: &T) { + std::assert_eq!(a, b) +} + +#[allow(unused)] +macro_rules! assert_eq_const { + ($a:expr, $b:expr $(,)?) => {{ + #[inline(always)] + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + const fn assert_eq_ct(a: &T, b: &T) { + assert!(a == b, concat!("`", stringify!($a), "` != `", stringify!($b), "`")); + } + + $crate::intrinsics::const_eval_select((&$a, &$b), assert_eq_ct, $crate::core_arch::test::assert_eq_rt); + }}; + ($a:expr, $b:expr, $($t:tt)+) => { + ::std::assert_eq!($a, $b, $($t)+) + }; +} + +pub(crate) use assert_eq_const; diff --git a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs index 01b1be364fe5..7185531606d2 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs @@ -16714,19 +16714,22 @@ mod tests { use stdarch_test::simd_test; #[target_feature(enable = "avx512fp16")] - unsafe fn _mm_set1_pch(re: f16, im: f16) -> __m128h { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + const fn _mm_set1_pch(re: f16, im: f16) -> __m128h { _mm_setr_ph(re, im, re, im, re, im, re, im) } #[target_feature(enable = "avx512fp16")] - unsafe fn _mm256_set1_pch(re: f16, im: f16) -> __m256h { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + const fn _mm256_set1_pch(re: f16, im: f16) -> __m256h { _mm256_setr_ph( re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, ) } #[target_feature(enable = "avx512fp16")] - unsafe fn _mm512_set1_pch(re: f16, im: f16) -> __m512h { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + const fn _mm512_set1_pch(re: f16, im: f16) -> __m512h { _mm512_setr_ph( re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, re, im, diff --git a/library/stdarch/crates/core_arch/src/x86/mod.rs b/library/stdarch/crates/core_arch/src/x86/mod.rs index 79a593e647f1..7612cffd078a 100644 --- a/library/stdarch/crates/core_arch/src/x86/mod.rs +++ b/library/stdarch/crates/core_arch/src/x86/mod.rs @@ -520,14 +520,14 @@ macro_rules! as_transmute { ($from:ty => $as_from:ident, $($as_to:ident -> $to:ident),* $(,)?) => { impl $from {$( #[inline] - pub(crate) fn $as_to(self) -> crate::core_arch::simd::$to { + pub(crate) const fn $as_to(self) -> crate::core_arch::simd::$to { unsafe { transmute(self) } } )*} $( impl crate::core_arch::simd::$to { #[inline] - pub(crate) fn $as_from(self) -> $from { + pub(crate) const fn $as_from(self) -> $from { unsafe { transmute(self) } } } diff --git a/library/stdarch/crates/core_arch/src/x86/test.rs b/library/stdarch/crates/core_arch/src/x86/test.rs index fec25ce2bc7c..9fa88fc98d60 100644 --- a/library/stdarch/crates/core_arch/src/x86/test.rs +++ b/library/stdarch/crates/core_arch/src/x86/test.rs @@ -1,115 +1,228 @@ //! Utilities used in testing the x86 intrinsics +use crate::core_arch::assert_eq_const as assert_eq; use crate::core_arch::x86::*; use std::mem::transmute; #[track_caller] #[target_feature(enable = "sse2")] -pub unsafe fn assert_eq_m128i(a: __m128i, b: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub(crate) const unsafe fn assert_eq_m128i(a: __m128i, b: __m128i) { assert_eq!(transmute::<_, [u64; 2]>(a), transmute::<_, [u64; 2]>(b)) } -#[track_caller] -#[target_feature(enable = "sse2")] -pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) { - if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 { - panic!("{:?} != {:?}", a, b); - } -} - -#[target_feature(enable = "sse2")] -pub unsafe fn get_m128d(a: __m128d, idx: usize) -> f64 { - transmute::<_, [f64; 2]>(a)[idx] -} - -#[track_caller] -#[target_feature(enable = "sse")] -pub unsafe fn assert_eq_m128(a: __m128, b: __m128) { - let r = _mm_cmpeq_ps(a, b); - if _mm_movemask_ps(r) != 0b1111 { - panic!("{:?} != {:?}", a, b); - } -} - -#[target_feature(enable = "sse")] -pub unsafe fn get_m128(a: __m128, idx: usize) -> f32 { - transmute::<_, [f32; 4]>(a)[idx] -} - -#[track_caller] -#[target_feature(enable = "avx512fp16,avx512vl")] -pub unsafe fn assert_eq_m128h(a: __m128h, b: __m128h) { - let r = _mm_cmp_ph_mask::<_CMP_EQ_OQ>(a, b); - if r != 0b1111_1111 { - panic!("{:?} != {:?}", a, b); - } -} - -// not actually an intrinsic but useful in various tests as we proted from -// `i64x2::new` which is backwards from `_mm_set_epi64x` -#[target_feature(enable = "sse2")] -pub unsafe fn _mm_setr_epi64x(a: i64, b: i64) -> __m128i { - _mm_set_epi64x(b, a) -} - #[track_caller] #[target_feature(enable = "avx")] -pub unsafe fn assert_eq_m256i(a: __m256i, b: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub(crate) const unsafe fn assert_eq_m256i(a: __m256i, b: __m256i) { assert_eq!(transmute::<_, [u64; 4]>(a), transmute::<_, [u64; 4]>(b)) } #[track_caller] -#[target_feature(enable = "avx")] -pub unsafe fn assert_eq_m256d(a: __m256d, b: __m256d) { - let cmp = _mm256_cmp_pd::<_CMP_EQ_OQ>(a, b); - if _mm256_movemask_pd(cmp) != 0b1111 { - panic!("{:?} != {:?}", a, b); +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub(crate) const unsafe fn assert_eq_m512i(a: __m512i, b: __m512i) { + assert_eq!(transmute::<_, [i32; 16]>(a), transmute::<_, [i32; 16]>(b)) +} + +macro_rules! make_ct_rt { + ($( + $( #[$meta:meta] )* + $vis:vis unsafe fn $name:ident ($($param:ident : $type:ty),* $(,)?) { + ct: $ct:expr; + rt: $rt:expr; + } + )*) => {$( + $( #[$meta] )* + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + $vis const unsafe fn $name ($($param : $type),*) { + #[inline(always)] + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + const fn ct($($param : $type),*) { + $ct + } + #[inline(always)] + fn rt($($param : $type),*) { + $rt + } + + $crate::intrinsics::const_eval_select(($($param),*), ct, rt) + } + )*} +} + +make_ct_rt! { + // SAFETY: we can use simple float equality because when this should only be used in const + // context where Intel peculiarities don't appear + + #[track_caller] + #[target_feature(enable = "sse2")] + pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) { + ct: unsafe { + assert_eq!(transmute::<_, [f64; 2]>(a), transmute::<_, [f64; 2]>(b)) + }; + rt: unsafe { + if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 { + panic!("{:?} != {:?}", a, b); + } + }; + } + + #[track_caller] + #[target_feature(enable = "sse")] + pub unsafe fn assert_eq_m128(a: __m128, b: __m128) { + ct: unsafe { + assert_eq!(transmute::<_, [f32; 4]>(a), transmute::<_, [f32; 4]>(b)) + }; + rt: unsafe { + let r = _mm_cmpeq_ps(a, b); + if _mm_movemask_ps(r) != 0b1111 { + panic!("{:?} != {:?}", a, b); + } + }; + } + + #[track_caller] + #[target_feature(enable = "avx512fp16,avx512vl")] + pub unsafe fn assert_eq_m128h(a: __m128h, b: __m128h) { + ct: unsafe { + assert_eq!(transmute::<_, [f16; 8]>(a), transmute::<_, [f16; 8]>(b)) + }; + rt: unsafe { + let r = _mm_cmp_ph_mask::<_CMP_EQ_OQ>(a, b); + if r != 0b1111_1111 { + panic!("{:?} != {:?}", a, b); + } + }; + } + + #[track_caller] + #[target_feature(enable = "avx")] + pub unsafe fn assert_eq_m256d(a: __m256d, b: __m256d) { + ct: unsafe { + assert_eq!(transmute::<_, [f64; 4]>(a), transmute::<_, [f64; 4]>(b)) + }; + rt: unsafe { + let cmp = _mm256_cmp_pd::<_CMP_EQ_OQ>(a, b); + if _mm256_movemask_pd(cmp) != 0b1111 { + panic!("{:?} != {:?}", a, b); + } + }; + } + + #[track_caller] + #[target_feature(enable = "avx")] + pub unsafe fn assert_eq_m256(a: __m256, b: __m256) { + ct: unsafe { + assert_eq!(transmute::<_, [f32; 8]>(a), transmute::<_, [f32; 8]>(b)) + }; + rt: unsafe { + let cmp = _mm256_cmp_ps::<_CMP_EQ_OQ>(a, b); + if _mm256_movemask_ps(cmp) != 0b11111111 { + panic!("{:?} != {:?}", a, b); + } + }; + } + + #[track_caller] + #[target_feature(enable = "avx512fp16,avx512vl")] + pub unsafe fn assert_eq_m256h(a: __m256h, b: __m256h) { + ct: unsafe { + assert_eq!(transmute::<_, [f16; 16]>(a), transmute::<_, [f16; 16]>(b)) + }; + rt: unsafe { + let r = _mm256_cmp_ph_mask::<_CMP_EQ_OQ>(a, b); + if r != 0b11111111_11111111 { + panic!("{:?} != {:?}", a, b); + } + }; + } + + #[track_caller] + #[target_feature(enable = "avx512f")] + pub unsafe fn assert_eq_m512d(a: __m512d, b: __m512d) { + ct: unsafe { + assert_eq!(transmute::<_, [f64; 8]>(a), transmute::<_, [f64; 8]>(b)) + }; + rt: unsafe { + let cmp = _mm512_cmp_pd_mask::<_CMP_EQ_OQ>(a, b); + if cmp != 0b11111111 { + panic!("{:?} != {:?}", a, b); + } + }; + } + + #[track_caller] + #[target_feature(enable = "avx512f")] + pub unsafe fn assert_eq_m512(a: __m512, b: __m512) { + ct: unsafe { + assert_eq!(transmute::<_, [f32; 16]>(a), transmute::<_, [f32; 16]>(b)) + }; + rt: unsafe { + let cmp = _mm512_cmp_ps_mask::<_CMP_EQ_OQ>(a, b); + if cmp != 0b11111111_11111111 { + panic!("{:?} != {:?}", a, b); + } + }; + } + + #[track_caller] + #[target_feature(enable = "avx512fp16")] + pub unsafe fn assert_eq_m512h(a: __m512h, b: __m512h) { + ct: unsafe { + assert_eq!(transmute::<_, [f16; 32]>(a), transmute::<_, [f16; 32]>(b)) + }; + rt: unsafe { + let r = _mm512_cmp_ph_mask::<_CMP_EQ_OQ>(a, b); + if r != 0b11111111_11111111_11111111_11111111 { + panic!("{:?} != {:?}", a, b); + } + }; } } +#[target_feature(enable = "sse2")] +pub(crate) const unsafe fn get_m128d(a: __m128d, idx: usize) -> f64 { + transmute::<_, [f64; 2]>(a)[idx] +} + +#[target_feature(enable = "sse")] +pub(crate) const unsafe fn get_m128(a: __m128, idx: usize) -> f32 { + transmute::<_, [f32; 4]>(a)[idx] +} + #[target_feature(enable = "avx")] -pub unsafe fn get_m256d(a: __m256d, idx: usize) -> f64 { +pub(crate) const unsafe fn get_m256d(a: __m256d, idx: usize) -> f64 { transmute::<_, [f64; 4]>(a)[idx] } -#[track_caller] #[target_feature(enable = "avx")] -pub unsafe fn assert_eq_m256(a: __m256, b: __m256) { - let cmp = _mm256_cmp_ps::<_CMP_EQ_OQ>(a, b); - if _mm256_movemask_ps(cmp) != 0b11111111 { - panic!("{:?} != {:?}", a, b); - } -} - -#[target_feature(enable = "avx")] -pub unsafe fn get_m256(a: __m256, idx: usize) -> f32 { +pub(crate) const unsafe fn get_m256(a: __m256, idx: usize) -> f32 { transmute::<_, [f32; 8]>(a)[idx] } -#[track_caller] -#[target_feature(enable = "avx512fp16,avx512vl")] -pub unsafe fn assert_eq_m256h(a: __m256h, b: __m256h) { - let r = _mm256_cmp_ph_mask::<_CMP_EQ_OQ>(a, b); - if r != 0b11111111_11111111 { - panic!("{:?} != {:?}", a, b); - } -} - #[target_feature(enable = "avx512f")] -pub unsafe fn get_m512(a: __m512, idx: usize) -> f32 { +pub(crate) const unsafe fn get_m512(a: __m512, idx: usize) -> f32 { transmute::<_, [f32; 16]>(a)[idx] } #[target_feature(enable = "avx512f")] -pub unsafe fn get_m512d(a: __m512d, idx: usize) -> f64 { +pub(crate) const unsafe fn get_m512d(a: __m512d, idx: usize) -> f64 { transmute::<_, [f64; 8]>(a)[idx] } #[target_feature(enable = "avx512f")] -pub unsafe fn get_m512i(a: __m512i, idx: usize) -> i64 { +pub(crate) const unsafe fn get_m512i(a: __m512i, idx: usize) -> i64 { transmute::<_, [i64; 8]>(a)[idx] } +// not actually an intrinsic but useful in various tests as we ported from +// `i64x2::new` which is backwards from `_mm_set_epi64x` +#[target_feature(enable = "sse2")] +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const unsafe fn _mm_setr_epi64x(a: i64, b: i64) -> __m128i { + _mm_set_epi64x(b, a) +} + // These intrinsics doesn't exist on x86 b/c it requires a 64-bit register, // which doesn't exist on x86! #[cfg(target_arch = "x86")] @@ -118,14 +231,16 @@ mod x86_polyfill { use crate::intrinsics::simd::*; #[rustc_legacy_const_generics(2)] - pub unsafe fn _mm_insert_epi64(a: __m128i, val: i64) -> __m128i { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + pub const unsafe fn _mm_insert_epi64(a: __m128i, val: i64) -> __m128i { static_assert_uimm_bits!(INDEX, 1); transmute(simd_insert!(a.as_i64x2(), INDEX as u32, val)) } #[target_feature(enable = "avx2")] #[rustc_legacy_const_generics(2)] - pub unsafe fn _mm256_insert_epi64(a: __m256i, val: i64) -> __m256i { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + pub const unsafe fn _mm256_insert_epi64(a: __m256i, val: i64) -> __m256i { static_assert_uimm_bits!(INDEX, 2); transmute(simd_insert!(a.as_i64x4(), INDEX as u32, val)) } @@ -136,33 +251,3 @@ mod x86_polyfill { pub use crate::core_arch::x86_64::{_mm_insert_epi64, _mm256_insert_epi64}; } pub use self::x86_polyfill::*; - -#[track_caller] -pub unsafe fn assert_eq_m512i(a: __m512i, b: __m512i) { - assert_eq!(transmute::<_, [i32; 16]>(a), transmute::<_, [i32; 16]>(b)) -} - -#[track_caller] -pub unsafe fn assert_eq_m512(a: __m512, b: __m512) { - let cmp = _mm512_cmp_ps_mask::<_CMP_EQ_OQ>(a, b); - if cmp != 0b11111111_11111111 { - panic!("{:?} != {:?}", a, b); - } -} - -#[track_caller] -pub unsafe fn assert_eq_m512d(a: __m512d, b: __m512d) { - let cmp = _mm512_cmp_pd_mask::<_CMP_EQ_OQ>(a, b); - if cmp != 0b11111111 { - panic!("{:?} != {:?}", a, b); - } -} - -#[track_caller] -#[target_feature(enable = "avx512fp16")] -pub unsafe fn assert_eq_m512h(a: __m512h, b: __m512h) { - let r = _mm512_cmp_ph_mask::<_CMP_EQ_OQ>(a, b); - if r != 0b11111111_11111111_11111111_11111111 { - panic!("{:?} != {:?}", a, b); - } -} From 742e70fe8ff91ca6ac44f098faaed179019064e5 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 25 Nov 2025 09:45:33 +0530 Subject: [PATCH 0223/3801] Modify `#[simd_test]` to enable const-testing --- .../stdarch/crates/simd-test-macro/src/lib.rs | 70 +++++++++++-------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/library/stdarch/crates/simd-test-macro/src/lib.rs b/library/stdarch/crates/simd-test-macro/src/lib.rs index b18e2d6b63e5..b8bb874480a0 100644 --- a/library/stdarch/crates/simd-test-macro/src/lib.rs +++ b/library/stdarch/crates/simd-test-macro/src/lib.rs @@ -7,43 +7,41 @@ #[macro_use] extern crate quote; -use proc_macro2::{Ident, Literal, Span, TokenStream, TokenTree}; +use proc_macro2::{Ident, Span, TokenStream, TokenTree}; use quote::ToTokens; use std::env; -fn string(s: &str) -> TokenTree { - Literal::string(s).into() -} - #[proc_macro_attribute] pub fn simd_test( attr: proc_macro::TokenStream, item: proc_macro::TokenStream, ) -> proc_macro::TokenStream { let tokens = TokenStream::from(attr).into_iter().collect::>(); - if tokens.len() != 3 { - panic!("expected #[simd_test(enable = \"feature\")]"); - } - match &tokens[0] { - TokenTree::Ident(tt) if *tt == "enable" => {} - _ => panic!("expected #[simd_test(enable = \"feature\")]"), - } - match &tokens[1] { - TokenTree::Punct(tt) if tt.as_char() == '=' => {} - _ => panic!("expected #[simd_test(enable = \"feature\")]"), - } - let enable_feature = match &tokens[2] { - TokenTree::Literal(tt) => tt.to_string(), - _ => panic!("expected #[simd_test(enable = \"feature\")]"), - }; - let enable_feature = enable_feature.trim_start_matches('"').trim_end_matches('"'); - let target_features: Vec = enable_feature - .replace('+', "") - .split(',') - .map(String::from) - .collect(); + let (target_features, target_feature_attr) = match &tokens[..] { + [] => (Vec::new(), TokenStream::new()), + [ + TokenTree::Ident(enable), + TokenTree::Punct(equals), + TokenTree::Literal(literal), + ] if enable == "enable" && equals.as_char() == '=' => { + let enable_feature = literal.to_string(); + let enable_feature = enable_feature.trim_start_matches('"').trim_end_matches('"'); + let target_features: Vec<_> = enable_feature + .replace('+', "") + .split(',') + .map(String::from) + .collect(); + + ( + target_features, + quote! { + #[target_feature(enable = #enable_feature)] + }, + ) + } + _ => panic!("expected #[simd_test(enable = \"feature\")] or #[simd_test]"), + }; - let enable_feature = string(enable_feature); let mut item = syn::parse_macro_input!(item as syn::ItemFn); let item_attrs = std::mem::take(&mut item.attrs); let name = &item.sig.ident; @@ -102,6 +100,19 @@ pub fn simd_test( TokenStream::new() }; + let (const_test, const_stability) = if item.sig.constness.is_some() { + ( + quote! { + const _: () = unsafe { #name() }; + }, + quote! { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + }, + ) + } else { + (TokenStream::new(), TokenStream::new()) + }; + let ret: TokenStream = quote_spanned! { proc_macro2::Span::call_site() => #[allow(non_snake_case)] @@ -109,6 +120,8 @@ pub fn simd_test( #maybe_ignore #(#item_attrs)* fn #name() { + #const_test + let mut missing_features = ::std::vec::Vec::new(); #detect_missing_features if missing_features.is_empty() { @@ -118,7 +131,8 @@ pub fn simd_test( ::stdarch_test::assert_skip_test_ok(stringify!(#name), &missing_features); } - #[target_feature(enable = #enable_feature)] + #target_feature_attr + #const_stability #item } }; From 233574ace381e79c9bac17cc2d3dfc03346e257c Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:24:10 +0530 Subject: [PATCH 0224/3801] Make `abm`, `bmi1`, `bmi2`, `bswap` and `tbm` functions const --- .../stdarch/crates/core_arch/src/x86/abm.rs | 11 +++-- .../stdarch/crates/core_arch/src/x86/bmi1.rs | 34 ++++++++------ .../stdarch/crates/core_arch/src/x86/bmi2.rs | 6 ++- .../stdarch/crates/core_arch/src/x86/bswap.rs | 10 ++-- .../stdarch/crates/core_arch/src/x86/tbm.rs | 46 +++++++++++-------- .../crates/core_arch/src/x86_64/abm.rs | 11 +++-- .../crates/core_arch/src/x86_64/bmi.rs | 29 +++++++----- .../crates/core_arch/src/x86_64/bmi2.rs | 6 ++- .../crates/core_arch/src/x86_64/bswap.rs | 10 ++-- .../crates/core_arch/src/x86_64/tbm.rs | 46 +++++++++++-------- 10 files changed, 131 insertions(+), 78 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/abm.rs b/library/stdarch/crates/core_arch/src/x86/abm.rs index e6d551760043..59f3877b4ace 100644 --- a/library/stdarch/crates/core_arch/src/x86/abm.rs +++ b/library/stdarch/crates/core_arch/src/x86/abm.rs @@ -29,7 +29,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "lzcnt")] #[cfg_attr(test, assert_instr(lzcnt))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _lzcnt_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _lzcnt_u32(x: u32) -> u32 { x.leading_zeros() } @@ -40,23 +41,25 @@ pub fn _lzcnt_u32(x: u32) -> u32 { #[target_feature(enable = "popcnt")] #[cfg_attr(test, assert_instr(popcnt))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _popcnt32(x: i32) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _popcnt32(x: i32) -> i32 { x.count_ones() as i32 } #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; #[simd_test(enable = "lzcnt")] - unsafe fn test_lzcnt_u32() { + const unsafe fn test_lzcnt_u32() { assert_eq!(_lzcnt_u32(0b0101_1010), 25); } #[simd_test(enable = "popcnt")] - unsafe fn test_popcnt32() { + const unsafe fn test_popcnt32() { assert_eq!(_popcnt32(0b0101_1010), 4); } } diff --git a/library/stdarch/crates/core_arch/src/x86/bmi1.rs b/library/stdarch/crates/core_arch/src/x86/bmi1.rs index eb7242944abc..08444aaaeddd 100644 --- a/library/stdarch/crates/core_arch/src/x86/bmi1.rs +++ b/library/stdarch/crates/core_arch/src/x86/bmi1.rs @@ -46,7 +46,8 @@ pub fn _bextr2_u32(a: u32, control: u32) -> u32 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(andn))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _andn_u32(a: u32, b: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _andn_u32(a: u32, b: u32) -> u32 { !a & b } @@ -57,7 +58,8 @@ pub fn _andn_u32(a: u32, b: u32) -> u32 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(blsi))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsi_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsi_u32(x: u32) -> u32 { x & x.wrapping_neg() } @@ -68,7 +70,8 @@ pub fn _blsi_u32(x: u32) -> u32 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(blsmsk))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsmsk_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsmsk_u32(x: u32) -> u32 { x ^ (x.wrapping_sub(1_u32)) } @@ -81,7 +84,8 @@ pub fn _blsmsk_u32(x: u32) -> u32 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(blsr))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsr_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsr_u32(x: u32) -> u32 { x & (x.wrapping_sub(1)) } @@ -94,7 +98,8 @@ pub fn _blsr_u32(x: u32) -> u32 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(tzcnt))] #[stable(feature = "simd_x86_updates", since = "1.82.0")] -pub fn _tzcnt_u16(x: u16) -> u16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _tzcnt_u16(x: u16) -> u16 { x.trailing_zeros() as u16 } @@ -107,7 +112,8 @@ pub fn _tzcnt_u16(x: u16) -> u16 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(tzcnt))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _tzcnt_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _tzcnt_u32(x: u32) -> u32 { x.trailing_zeros() } @@ -120,7 +126,8 @@ pub fn _tzcnt_u32(x: u32) -> u32 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(tzcnt))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_tzcnt_32(x: u32) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_tzcnt_32(x: u32) -> i32 { x.trailing_zeros() as i32 } @@ -131,6 +138,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; @@ -142,7 +150,7 @@ mod tests { } #[simd_test(enable = "bmi1")] - unsafe fn test_andn_u32() { + const unsafe fn test_andn_u32() { assert_eq!(_andn_u32(0, 0), 0); assert_eq!(_andn_u32(0, 1), 1); assert_eq!(_andn_u32(1, 0), 0); @@ -165,32 +173,32 @@ mod tests { } #[simd_test(enable = "bmi1")] - unsafe fn test_blsi_u32() { + const unsafe fn test_blsi_u32() { assert_eq!(_blsi_u32(0b1101_0000u32), 0b0001_0000u32); } #[simd_test(enable = "bmi1")] - unsafe fn test_blsmsk_u32() { + const unsafe fn test_blsmsk_u32() { let r = _blsmsk_u32(0b0011_0000u32); assert_eq!(r, 0b0001_1111u32); } #[simd_test(enable = "bmi1")] - unsafe fn test_blsr_u32() { + const unsafe fn test_blsr_u32() { // TODO: test the behavior when the input is `0`. let r = _blsr_u32(0b0011_0000u32); assert_eq!(r, 0b0010_0000u32); } #[simd_test(enable = "bmi1")] - unsafe fn test_tzcnt_u16() { + const unsafe fn test_tzcnt_u16() { assert_eq!(_tzcnt_u16(0b0000_0001u16), 0u16); assert_eq!(_tzcnt_u16(0b0000_0000u16), 16u16); assert_eq!(_tzcnt_u16(0b1001_0000u16), 4u16); } #[simd_test(enable = "bmi1")] - unsafe fn test_tzcnt_u32() { + const unsafe fn test_tzcnt_u32() { assert_eq!(_tzcnt_u32(0b0000_0001u32), 0u32); assert_eq!(_tzcnt_u32(0b0000_0000u32), 32u32); assert_eq!(_tzcnt_u32(0b1001_0000u32), 4u32); diff --git a/library/stdarch/crates/core_arch/src/x86/bmi2.rs b/library/stdarch/crates/core_arch/src/x86/bmi2.rs index 83cf650923f7..b5b7d0f34073 100644 --- a/library/stdarch/crates/core_arch/src/x86/bmi2.rs +++ b/library/stdarch/crates/core_arch/src/x86/bmi2.rs @@ -25,7 +25,8 @@ use stdarch_test::assert_instr; #[cfg_attr(all(test, target_arch = "x86"), assert_instr(mul))] #[target_feature(enable = "bmi2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mulx_u32(a: u32, b: u32, hi: &mut u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mulx_u32(a: u32, b: u32, hi: &mut u32) -> u32 { let result: u64 = (a as u64) * (b as u64); *hi = (result >> 32) as u32; result as u32 @@ -77,6 +78,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; @@ -117,7 +119,7 @@ mod tests { } #[simd_test(enable = "bmi2")] - unsafe fn test_mulx_u32() { + const unsafe fn test_mulx_u32() { let a: u32 = 4_294_967_200; let b: u32 = 2; let mut hi = 0; diff --git a/library/stdarch/crates/core_arch/src/x86/bswap.rs b/library/stdarch/crates/core_arch/src/x86/bswap.rs index ea07a7d6229a..f8e177f7c278 100644 --- a/library/stdarch/crates/core_arch/src/x86/bswap.rs +++ b/library/stdarch/crates/core_arch/src/x86/bswap.rs @@ -10,16 +10,20 @@ use stdarch_test::assert_instr; #[inline] #[cfg_attr(test, assert_instr(bswap))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _bswap(x: i32) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _bswap(x: i32) -> i32 { x.swap_bytes() } #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; + use stdarch_test::simd_test; + use super::*; - #[test] - fn test_bswap() { + #[simd_test] + const fn test_bswap() { assert_eq!(_bswap(0x0EADBE0F), 0x0FBEAD0E); assert_eq!(_bswap(0x00000000), 0x00000000); } diff --git a/library/stdarch/crates/core_arch/src/x86/tbm.rs b/library/stdarch/crates/core_arch/src/x86/tbm.rs index 5a01752d8ac2..d7769b916d4f 100644 --- a/library/stdarch/crates/core_arch/src/x86/tbm.rs +++ b/library/stdarch/crates/core_arch/src/x86/tbm.rs @@ -42,7 +42,8 @@ pub fn _bextri_u32(a: u32) -> u32 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blcfill))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blcfill_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blcfill_u32(x: u32) -> u32 { x & (x.wrapping_add(1)) } @@ -53,7 +54,8 @@ pub fn _blcfill_u32(x: u32) -> u32 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blci))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blci_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blci_u32(x: u32) -> u32 { x | !x.wrapping_add(1) } @@ -64,7 +66,8 @@ pub fn _blci_u32(x: u32) -> u32 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blcic))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blcic_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blcic_u32(x: u32) -> u32 { !x & x.wrapping_add(1) } @@ -76,7 +79,8 @@ pub fn _blcic_u32(x: u32) -> u32 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blcmsk))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blcmsk_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blcmsk_u32(x: u32) -> u32 { x ^ x.wrapping_add(1) } @@ -87,7 +91,8 @@ pub fn _blcmsk_u32(x: u32) -> u32 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blcs))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blcs_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blcs_u32(x: u32) -> u32 { x | x.wrapping_add(1) } @@ -98,7 +103,8 @@ pub fn _blcs_u32(x: u32) -> u32 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blsfill))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsfill_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsfill_u32(x: u32) -> u32 { x | x.wrapping_sub(1) } @@ -109,7 +115,8 @@ pub fn _blsfill_u32(x: u32) -> u32 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blsic))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsic_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsic_u32(x: u32) -> u32 { !x | x.wrapping_sub(1) } @@ -121,7 +128,8 @@ pub fn _blsic_u32(x: u32) -> u32 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(t1mskc))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _t1mskc_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _t1mskc_u32(x: u32) -> u32 { !x | x.wrapping_add(1) } @@ -133,12 +141,14 @@ pub fn _t1mskc_u32(x: u32) -> u32 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(tzmsk))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _tzmsk_u32(x: u32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _tzmsk_u32(x: u32) -> u32 { !x & x.wrapping_sub(1) } #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; @@ -149,13 +159,13 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_blcfill_u32() { + const unsafe fn test_blcfill_u32() { assert_eq!(_blcfill_u32(0b0101_0111u32), 0b0101_0000u32); assert_eq!(_blcfill_u32(0b1111_1111u32), 0u32); } #[simd_test(enable = "tbm")] - unsafe fn test_blci_u32() { + const unsafe fn test_blci_u32() { assert_eq!( _blci_u32(0b0101_0000u32), 0b1111_1111_1111_1111_1111_1111_1111_1110u32 @@ -167,25 +177,25 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_blcic_u32() { + const unsafe fn test_blcic_u32() { assert_eq!(_blcic_u32(0b0101_0001u32), 0b0000_0010u32); assert_eq!(_blcic_u32(0b1111_1111u32), 0b1_0000_0000u32); } #[simd_test(enable = "tbm")] - unsafe fn test_blcmsk_u32() { + const unsafe fn test_blcmsk_u32() { assert_eq!(_blcmsk_u32(0b0101_0001u32), 0b0000_0011u32); assert_eq!(_blcmsk_u32(0b1111_1111u32), 0b1_1111_1111u32); } #[simd_test(enable = "tbm")] - unsafe fn test_blcs_u32() { + const unsafe fn test_blcs_u32() { assert_eq!(_blcs_u32(0b0101_0001u32), 0b0101_0011u32); assert_eq!(_blcs_u32(0b1111_1111u32), 0b1_1111_1111u32); } #[simd_test(enable = "tbm")] - unsafe fn test_blsfill_u32() { + const unsafe fn test_blsfill_u32() { assert_eq!(_blsfill_u32(0b0101_0100u32), 0b0101_0111u32); assert_eq!( _blsfill_u32(0u32), @@ -194,7 +204,7 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_blsic_u32() { + const unsafe fn test_blsic_u32() { assert_eq!( _blsic_u32(0b0101_0100u32), 0b1111_1111_1111_1111_1111_1111_1111_1011u32 @@ -206,7 +216,7 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_t1mskc_u32() { + const unsafe fn test_t1mskc_u32() { assert_eq!( _t1mskc_u32(0b0101_0111u32), 0b1111_1111_1111_1111_1111_1111_1111_1000u32 @@ -218,7 +228,7 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_tzmsk_u32() { + const unsafe fn test_tzmsk_u32() { assert_eq!(_tzmsk_u32(0b0101_1000u32), 0b0000_0111u32); assert_eq!(_tzmsk_u32(0b0101_1001u32), 0b0000_0000u32); } diff --git a/library/stdarch/crates/core_arch/src/x86_64/abm.rs b/library/stdarch/crates/core_arch/src/x86_64/abm.rs index bf59cc463218..63e422864d3b 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/abm.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/abm.rs @@ -29,7 +29,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "lzcnt")] #[cfg_attr(test, assert_instr(lzcnt))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _lzcnt_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _lzcnt_u64(x: u64) -> u64 { x.leading_zeros() as u64 } @@ -40,23 +41,25 @@ pub fn _lzcnt_u64(x: u64) -> u64 { #[target_feature(enable = "popcnt")] #[cfg_attr(test, assert_instr(popcnt))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _popcnt64(x: i64) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _popcnt64(x: i64) -> i32 { x.count_ones() as i32 } #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::arch::x86_64::*; #[simd_test(enable = "lzcnt")] - unsafe fn test_lzcnt_u64() { + const unsafe fn test_lzcnt_u64() { assert_eq!(_lzcnt_u64(0b0101_1010), 57); } #[simd_test(enable = "popcnt")] - unsafe fn test_popcnt64() { + const unsafe fn test_popcnt64() { assert_eq!(_popcnt64(0b0101_1010), 4); } } diff --git a/library/stdarch/crates/core_arch/src/x86_64/bmi.rs b/library/stdarch/crates/core_arch/src/x86_64/bmi.rs index 5d204d51ae6d..ee41d4137591 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/bmi.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/bmi.rs @@ -48,7 +48,8 @@ pub fn _bextr2_u64(a: u64, control: u64) -> u64 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(andn))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _andn_u64(a: u64, b: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _andn_u64(a: u64, b: u64) -> u64 { !a & b } @@ -60,7 +61,8 @@ pub fn _andn_u64(a: u64, b: u64) -> u64 { #[cfg_attr(test, assert_instr(blsi))] #[cfg(not(target_arch = "x86"))] // generates lots of instructions #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsi_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsi_u64(x: u64) -> u64 { x & x.wrapping_neg() } @@ -72,7 +74,8 @@ pub fn _blsi_u64(x: u64) -> u64 { #[cfg_attr(test, assert_instr(blsmsk))] #[cfg(not(target_arch = "x86"))] // generates lots of instructions #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsmsk_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsmsk_u64(x: u64) -> u64 { x ^ (x.wrapping_sub(1_u64)) } @@ -86,7 +89,8 @@ pub fn _blsmsk_u64(x: u64) -> u64 { #[cfg_attr(test, assert_instr(blsr))] #[cfg(not(target_arch = "x86"))] // generates lots of instructions #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsr_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsr_u64(x: u64) -> u64 { x & (x.wrapping_sub(1)) } @@ -99,7 +103,8 @@ pub fn _blsr_u64(x: u64) -> u64 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(tzcnt))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _tzcnt_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _tzcnt_u64(x: u64) -> u64 { x.trailing_zeros() as u64 } @@ -112,7 +117,8 @@ pub fn _tzcnt_u64(x: u64) -> u64 { #[target_feature(enable = "bmi1")] #[cfg_attr(test, assert_instr(tzcnt))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_tzcnt_64(x: u64) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_tzcnt_64(x: u64) -> i64 { x.trailing_zeros() as i64 } @@ -123,6 +129,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::{x86::*, x86_64::*}; @@ -134,7 +141,7 @@ mod tests { } #[simd_test(enable = "bmi1")] - unsafe fn test_andn_u64() { + const unsafe fn test_andn_u64() { assert_eq!(_andn_u64(0, 0), 0); assert_eq!(_andn_u64(0, 1), 1); assert_eq!(_andn_u64(1, 0), 0); @@ -157,25 +164,25 @@ mod tests { } #[simd_test(enable = "bmi1")] - unsafe fn test_blsi_u64() { + const unsafe fn test_blsi_u64() { assert_eq!(_blsi_u64(0b1101_0000u64), 0b0001_0000u64); } #[simd_test(enable = "bmi1")] - unsafe fn test_blsmsk_u64() { + const unsafe fn test_blsmsk_u64() { let r = _blsmsk_u64(0b0011_0000u64); assert_eq!(r, 0b0001_1111u64); } #[simd_test(enable = "bmi1")] - unsafe fn test_blsr_u64() { + const unsafe fn test_blsr_u64() { // TODO: test the behavior when the input is `0`. let r = _blsr_u64(0b0011_0000u64); assert_eq!(r, 0b0010_0000u64); } #[simd_test(enable = "bmi1")] - unsafe fn test_tzcnt_u64() { + const unsafe fn test_tzcnt_u64() { assert_eq!(_tzcnt_u64(0b0000_0001u64), 0u64); assert_eq!(_tzcnt_u64(0b0000_0000u64), 64u64); assert_eq!(_tzcnt_u64(0b1001_0000u64), 4u64); diff --git a/library/stdarch/crates/core_arch/src/x86_64/bmi2.rs b/library/stdarch/crates/core_arch/src/x86_64/bmi2.rs index ea9daf88574f..4eb53ed5ea4a 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/bmi2.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/bmi2.rs @@ -24,7 +24,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "bmi2")] #[cfg(not(target_arch = "x86"))] // calls an intrinsic #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mulx_u64(a: u64, b: u64, hi: &mut u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mulx_u64(a: u64, b: u64, hi: &mut u64) -> u64 { let result: u128 = (a as u128) * (b as u128); *hi = (result >> 64) as u64; result as u64 @@ -79,6 +80,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86_64::*; @@ -120,7 +122,7 @@ mod tests { #[simd_test(enable = "bmi2")] #[rustfmt::skip] - unsafe fn test_mulx_u64() { +const unsafe fn test_mulx_u64() { let a: u64 = 9_223_372_036_854_775_800; let b: u64 = 100; let mut hi = 0; diff --git a/library/stdarch/crates/core_arch/src/x86_64/bswap.rs b/library/stdarch/crates/core_arch/src/x86_64/bswap.rs index 4e2d8b96eade..1b1d739a62c8 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/bswap.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/bswap.rs @@ -11,16 +11,20 @@ use stdarch_test::assert_instr; #[inline] #[cfg_attr(test, assert_instr(bswap))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _bswap64(x: i64) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _bswap64(x: i64) -> i64 { x.swap_bytes() } #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; + use stdarch_test::simd_test; + use super::*; - #[test] - fn test_bswap64() { + #[simd_test] + const fn test_bswap64() { assert_eq!(_bswap64(0x0EADBEEFFADECA0E), 0x0ECADEFAEFBEAD0E); assert_eq!(_bswap64(0x0000000000000000), 0x0000000000000000); } diff --git a/library/stdarch/crates/core_arch/src/x86_64/tbm.rs b/library/stdarch/crates/core_arch/src/x86_64/tbm.rs index f4bba709f681..e7d4b8d3e4c9 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/tbm.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/tbm.rs @@ -42,7 +42,8 @@ pub fn _bextri_u64(a: u64) -> u64 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blcfill))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blcfill_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blcfill_u64(x: u64) -> u64 { x & x.wrapping_add(1) } @@ -53,7 +54,8 @@ pub fn _blcfill_u64(x: u64) -> u64 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blci))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blci_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blci_u64(x: u64) -> u64 { x | !x.wrapping_add(1) } @@ -64,7 +66,8 @@ pub fn _blci_u64(x: u64) -> u64 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blcic))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blcic_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blcic_u64(x: u64) -> u64 { !x & x.wrapping_add(1) } @@ -76,7 +79,8 @@ pub fn _blcic_u64(x: u64) -> u64 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blcmsk))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blcmsk_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blcmsk_u64(x: u64) -> u64 { x ^ x.wrapping_add(1) } @@ -87,7 +91,8 @@ pub fn _blcmsk_u64(x: u64) -> u64 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blcs))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blcs_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blcs_u64(x: u64) -> u64 { x | x.wrapping_add(1) } @@ -98,7 +103,8 @@ pub fn _blcs_u64(x: u64) -> u64 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blsfill))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsfill_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsfill_u64(x: u64) -> u64 { x | x.wrapping_sub(1) } @@ -109,7 +115,8 @@ pub fn _blsfill_u64(x: u64) -> u64 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(blsic))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _blsic_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _blsic_u64(x: u64) -> u64 { !x | x.wrapping_sub(1) } @@ -121,7 +128,8 @@ pub fn _blsic_u64(x: u64) -> u64 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(t1mskc))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _t1mskc_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _t1mskc_u64(x: u64) -> u64 { !x | x.wrapping_add(1) } @@ -133,12 +141,14 @@ pub fn _t1mskc_u64(x: u64) -> u64 { #[target_feature(enable = "tbm")] #[cfg_attr(test, assert_instr(tzmsk))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _tzmsk_u64(x: u64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _tzmsk_u64(x: u64) -> u64 { !x & x.wrapping_sub(1) } #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86_64::*; @@ -149,13 +159,13 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_blcfill_u64() { + const unsafe fn test_blcfill_u64() { assert_eq!(_blcfill_u64(0b0101_0111u64), 0b0101_0000u64); assert_eq!(_blcfill_u64(0b1111_1111u64), 0u64); } #[simd_test(enable = "tbm")] - unsafe fn test_blci_u64() { + const unsafe fn test_blci_u64() { assert_eq!( _blci_u64(0b0101_0000u64), 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1110u64 @@ -167,25 +177,25 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_blcic_u64() { + const unsafe fn test_blcic_u64() { assert_eq!(_blcic_u64(0b0101_0001u64), 0b0000_0010u64); assert_eq!(_blcic_u64(0b1111_1111u64), 0b1_0000_0000u64); } #[simd_test(enable = "tbm")] - unsafe fn test_blcmsk_u64() { + const unsafe fn test_blcmsk_u64() { assert_eq!(_blcmsk_u64(0b0101_0001u64), 0b0000_0011u64); assert_eq!(_blcmsk_u64(0b1111_1111u64), 0b1_1111_1111u64); } #[simd_test(enable = "tbm")] - unsafe fn test_blcs_u64() { + const unsafe fn test_blcs_u64() { assert_eq!(_blcs_u64(0b0101_0001u64), 0b0101_0011u64); assert_eq!(_blcs_u64(0b1111_1111u64), 0b1_1111_1111u64); } #[simd_test(enable = "tbm")] - unsafe fn test_blsfill_u64() { + const unsafe fn test_blsfill_u64() { assert_eq!(_blsfill_u64(0b0101_0100u64), 0b0101_0111u64); assert_eq!( _blsfill_u64(0u64), @@ -194,7 +204,7 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_blsic_u64() { + const unsafe fn test_blsic_u64() { assert_eq!( _blsic_u64(0b0101_0100u64), 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1011u64 @@ -206,7 +216,7 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_t1mskc_u64() { + const unsafe fn test_t1mskc_u64() { assert_eq!( _t1mskc_u64(0b0101_0111u64), 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1000u64 @@ -218,7 +228,7 @@ mod tests { } #[simd_test(enable = "tbm")] - unsafe fn test_tzmsk_u64() { + const unsafe fn test_tzmsk_u64() { assert_eq!(_tzmsk_u64(0b0101_1000u64), 0b0000_0111u64); assert_eq!(_tzmsk_u64(0b0101_1001u64), 0b0000_0000u64); } From 7d4bcdd3fddbcc04697889e3cde5a5f996cde070 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 19:11:09 +0530 Subject: [PATCH 0225/3801] Make `sse` functions const --- .../stdarch/crates/core_arch/src/x86/sse.rs | 361 +++++++++--------- .../crates/core_arch/src/x86_64/sse.rs | 44 ++- 2 files changed, 201 insertions(+), 204 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index 7dd96dd1c9d7..165c61104e1a 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -18,7 +18,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(addss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_add_ss(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_ss(a: __m128, b: __m128) -> __m128 { unsafe { simd_insert!(a, 0, _mm_cvtss_f32(a) + _mm_cvtss_f32(b)) } } @@ -30,7 +31,8 @@ pub fn _mm_add_ss(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(addps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_add_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_ps(a: __m128, b: __m128) -> __m128 { unsafe { simd_add(a, b) } } @@ -42,7 +44,8 @@ pub fn _mm_add_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(subss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sub_ss(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_ss(a: __m128, b: __m128) -> __m128 { unsafe { simd_insert!(a, 0, _mm_cvtss_f32(a) - _mm_cvtss_f32(b)) } } @@ -54,7 +57,8 @@ pub fn _mm_sub_ss(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(subps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sub_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_ps(a: __m128, b: __m128) -> __m128 { unsafe { simd_sub(a, b) } } @@ -66,7 +70,8 @@ pub fn _mm_sub_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(mulss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mul_ss(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mul_ss(a: __m128, b: __m128) -> __m128 { unsafe { simd_insert!(a, 0, _mm_cvtss_f32(a) * _mm_cvtss_f32(b)) } } @@ -78,7 +83,8 @@ pub fn _mm_mul_ss(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(mulps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mul_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mul_ps(a: __m128, b: __m128) -> __m128 { unsafe { simd_mul(a, b) } } @@ -90,7 +96,8 @@ pub fn _mm_mul_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(divss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_div_ss(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_div_ss(a: __m128, b: __m128) -> __m128 { unsafe { simd_insert!(a, 0, _mm_cvtss_f32(a) / _mm_cvtss_f32(b)) } } @@ -102,7 +109,8 @@ pub fn _mm_div_ss(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(divps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_div_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_div_ps(a: __m128, b: __m128) -> __m128 { unsafe { simd_div(a, b) } } @@ -241,7 +249,8 @@ pub fn _mm_max_ps(a: __m128, b: __m128) -> __m128 { assert_instr(andps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_and_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_and_ps(a: __m128, b: __m128) -> __m128 { unsafe { let a: __m128i = mem::transmute(a); let b: __m128i = mem::transmute(b); @@ -264,7 +273,8 @@ pub fn _mm_and_ps(a: __m128, b: __m128) -> __m128 { assert_instr(andnps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_andnot_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_andnot_ps(a: __m128, b: __m128) -> __m128 { unsafe { let a: __m128i = mem::transmute(a); let b: __m128i = mem::transmute(b); @@ -284,7 +294,8 @@ pub fn _mm_andnot_ps(a: __m128, b: __m128) -> __m128 { assert_instr(orps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_or_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_or_ps(a: __m128, b: __m128) -> __m128 { unsafe { let a: __m128i = mem::transmute(a); let b: __m128i = mem::transmute(b); @@ -304,7 +315,8 @@ pub fn _mm_or_ps(a: __m128, b: __m128) -> __m128 { assert_instr(xorps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_xor_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_xor_ps(a: __m128, b: __m128) -> __m128 { unsafe { let a: __m128i = mem::transmute(a); let b: __m128i = mem::transmute(b); @@ -866,7 +878,8 @@ pub fn _mm_cvtt_ss2si(a: __m128) -> i32 { // No point in using assert_instrs. In Unix x86_64 calling convention this is a // no-op, and on msvc it's just a `mov`. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtss_f32(a: __m128) -> f32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtss_f32(a: __m128) -> f32 { unsafe { simd_extract!(a, 0) } } @@ -881,7 +894,8 @@ pub fn _mm_cvtss_f32(a: __m128) -> f32 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(cvtsi2ss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi32_ss(a: __m128, b: i32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi32_ss(a: __m128, b: i32) -> __m128 { unsafe { simd_insert!(a, 0, b as f32) } } @@ -904,7 +918,8 @@ pub fn _mm_cvt_si2ss(a: __m128, b: i32) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_ss(a: f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_ss(a: f32) -> __m128 { __m128([a, 0.0, 0.0, 0.0]) } @@ -915,7 +930,8 @@ pub fn _mm_set_ss(a: f32) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(shufps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set1_ps(a: f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set1_ps(a: f32) -> __m128 { __m128([a, a, a, a]) } @@ -926,7 +942,8 @@ pub fn _mm_set1_ps(a: f32) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(shufps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_ps1(a: f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_ps1(a: f32) -> __m128 { _mm_set1_ps(a) } @@ -953,7 +970,8 @@ pub fn _mm_set_ps1(a: f32) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(unpcklps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_ps(a: f32, b: f32, c: f32, d: f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_ps(a: f32, b: f32, c: f32, d: f32) -> __m128 { __m128([d, c, b, a]) } @@ -979,7 +997,8 @@ pub fn _mm_set_ps(a: f32, b: f32, c: f32, d: f32) -> __m128 { assert_instr(movaps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_setr_ps(a: f32, b: f32, c: f32, d: f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setr_ps(a: f32, b: f32, c: f32, d: f32) -> __m128 { __m128([a, b, c, d]) } @@ -990,7 +1009,8 @@ pub fn _mm_setr_ps(a: f32, b: f32, c: f32, d: f32) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(xorps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_setzero_ps() -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setzero_ps() -> __m128 { const { unsafe { mem::zeroed() } } } @@ -1021,7 +1041,8 @@ pub const fn _MM_SHUFFLE(z: u32, y: u32, x: u32, w: u32) -> i32 { #[cfg_attr(test, assert_instr(shufps, MASK = 3))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_shuffle_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shuffle_ps(a: __m128, b: __m128) -> __m128 { static_assert_uimm_bits!(MASK, 8); unsafe { simd_shuffle!( @@ -1045,7 +1066,8 @@ pub fn _mm_shuffle_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(unpckhps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpackhi_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpackhi_ps(a: __m128, b: __m128) -> __m128 { unsafe { simd_shuffle!(a, b, [2, 6, 3, 7]) } } @@ -1057,7 +1079,8 @@ pub fn _mm_unpackhi_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(unpcklps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpacklo_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpacklo_ps(a: __m128, b: __m128) -> __m128 { unsafe { simd_shuffle!(a, b, [0, 4, 1, 5]) } } @@ -1069,7 +1092,8 @@ pub fn _mm_unpacklo_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movhlps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_movehl_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movehl_ps(a: __m128, b: __m128) -> __m128 { // TODO; figure why this is a different instruction on msvc? unsafe { simd_shuffle!(a, b, [6, 7, 2, 3]) } } @@ -1082,7 +1106,8 @@ pub fn _mm_movehl_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movlhps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_movelh_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movelh_ps(a: __m128, b: __m128) -> __m128 { unsafe { simd_shuffle!(a, b, [0, 1, 4, 5]) } } @@ -1096,12 +1121,13 @@ pub fn _mm_movelh_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movmskps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_movemask_ps(a: __m128) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movemask_ps(a: __m128) -> i32 { // Propagate the highest bit to the rest, because simd_bitmask // requires all-1 or all-0. unsafe { let mask: i32x4 = simd_lt(transmute(a), i32x4::ZERO); - simd_bitmask::(mask).into() + simd_bitmask::(mask) as i32 } } @@ -1115,7 +1141,8 @@ pub fn _mm_movemask_ps(a: __m128) -> i32 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_load_ss(p: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_ss(p: *const f32) -> __m128 { __m128([*p, 0.0, 0.0, 0.0]) } @@ -1130,7 +1157,8 @@ pub unsafe fn _mm_load_ss(p: *const f32) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_load1_ps(p: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load1_ps(p: *const f32) -> __m128 { let a = *p; __m128([a, a, a, a]) } @@ -1142,7 +1170,8 @@ pub unsafe fn _mm_load1_ps(p: *const f32) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_load_ps1(p: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_ps1(p: *const f32) -> __m128 { _mm_load1_ps(p) } @@ -1166,7 +1195,8 @@ pub unsafe fn _mm_load_ps1(p: *const f32) -> __m128 { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm_load_ps(p: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_ps(p: *const f32) -> __m128 { *(p as *const __m128) } @@ -1183,7 +1213,8 @@ pub unsafe fn _mm_load_ps(p: *const f32) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movups))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_loadu_ps(p: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_ps(p: *const f32) -> __m128 { // Note: Using `*p` would require `f32` alignment, but `movups` has no // alignment restrictions. let mut dst = _mm_undefined_ps(); @@ -1223,7 +1254,8 @@ pub unsafe fn _mm_loadu_ps(p: *const f32) -> __m128 { assert_instr(movaps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_loadr_ps(p: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadr_ps(p: *const f32) -> __m128 { let a = _mm_load_ps(p); simd_shuffle!(a, a, [3, 2, 1, 0]) } @@ -1237,7 +1269,8 @@ pub unsafe fn _mm_loadr_ps(p: *const f32) -> __m128 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_store_ss(p: *mut f32, a: __m128) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_ss(p: *mut f32, a: __m128) { *p = simd_extract!(a, 0); } @@ -1267,7 +1300,8 @@ pub unsafe fn _mm_store_ss(p: *mut f32, a: __m128) { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm_store1_ps(p: *mut f32, a: __m128) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store1_ps(p: *mut f32, a: __m128) { let b: __m128 = simd_shuffle!(a, a, [0, 0, 0, 0]); *(p as *mut __m128) = b; } @@ -1282,7 +1316,8 @@ pub unsafe fn _mm_store1_ps(p: *mut f32, a: __m128) { assert_instr(movaps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_store_ps1(p: *mut f32, a: __m128) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_ps1(p: *mut f32, a: __m128) { _mm_store1_ps(p, a); } @@ -1305,7 +1340,8 @@ pub unsafe fn _mm_store_ps1(p: *mut f32, a: __m128) { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm_store_ps(p: *mut f32, a: __m128) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_ps(p: *mut f32, a: __m128) { *(p as *mut __m128) = a; } @@ -1320,7 +1356,8 @@ pub unsafe fn _mm_store_ps(p: *mut f32, a: __m128) { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movups))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_storeu_ps(p: *mut f32, a: __m128) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_ps(p: *mut f32, a: __m128) { ptr::copy_nonoverlapping( ptr::addr_of!(a) as *const u8, p as *mut u8, @@ -1352,7 +1389,8 @@ pub unsafe fn _mm_storeu_ps(p: *mut f32, a: __m128) { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm_storer_ps(p: *mut f32, a: __m128) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storer_ps(p: *mut f32, a: __m128) { let b: __m128 = simd_shuffle!(a, a, [3, 2, 1, 0]); *(p as *mut __m128) = b; } @@ -1370,7 +1408,8 @@ pub unsafe fn _mm_storer_ps(p: *mut f32, a: __m128) { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(movss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_move_ss(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_move_ss(a: __m128, b: __m128) -> __m128 { unsafe { simd_shuffle!(a, b, [4, 1, 2, 3]) } } @@ -1917,7 +1956,8 @@ pub fn _mm_prefetch(p: *const i8) { #[inline] #[target_feature(enable = "sse")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_undefined_ps() -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_undefined_ps() -> __m128 { const { unsafe { mem::zeroed() } } } @@ -1928,7 +1968,8 @@ pub fn _mm_undefined_ps() -> __m128 { #[allow(non_snake_case)] #[target_feature(enable = "sse")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _MM_TRANSPOSE4_PS( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _MM_TRANSPOSE4_PS( row0: &mut __m128, row1: &mut __m128, row2: &mut __m128, @@ -2037,6 +2078,7 @@ pub unsafe fn _mm_stream_ps(mem_addr: *mut f32, a: __m128) { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use crate::{hint::black_box, mem::transmute, ptr}; use std::boxed; use stdarch_test::simd_test; @@ -2046,7 +2088,7 @@ mod tests { const NAN: f32 = f32::NAN; #[simd_test(enable = "sse")] - unsafe fn test_mm_add_ps() { + const unsafe fn test_mm_add_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_add_ps(a, b); @@ -2054,7 +2096,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_add_ss() { + const unsafe fn test_mm_add_ss() { let a = _mm_set_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_set_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_add_ss(a, b); @@ -2062,7 +2104,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_sub_ps() { + const unsafe fn test_mm_sub_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_sub_ps(a, b); @@ -2070,7 +2112,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_sub_ss() { + const unsafe fn test_mm_sub_ss() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_sub_ss(a, b); @@ -2078,7 +2120,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_mul_ps() { + const unsafe fn test_mm_mul_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_mul_ps(a, b); @@ -2086,7 +2128,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_mul_ss() { + const unsafe fn test_mm_mul_ss() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_mul_ss(a, b); @@ -2094,7 +2136,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_div_ps() { + const unsafe fn test_mm_div_ps() { let a = _mm_setr_ps(-1.0, 5.0, 2.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.2, -5.0); let r = _mm_div_ps(a, b); @@ -2102,7 +2144,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_div_ss() { + const unsafe fn test_mm_div_ss() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_div_ss(a, b); @@ -2229,7 +2271,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_and_ps() { + const unsafe fn test_mm_and_ps() { let a = transmute(u32x4::splat(0b0011)); let b = transmute(u32x4::splat(0b0101)); let r = _mm_and_ps(*black_box(&a), *black_box(&b)); @@ -2238,7 +2280,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_andnot_ps() { + const unsafe fn test_mm_andnot_ps() { let a = transmute(u32x4::splat(0b0011)); let b = transmute(u32x4::splat(0b0101)); let r = _mm_andnot_ps(*black_box(&a), *black_box(&b)); @@ -2247,7 +2289,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_or_ps() { + const unsafe fn test_mm_or_ps() { let a = transmute(u32x4::splat(0b0011)); let b = transmute(u32x4::splat(0b0101)); let r = _mm_or_ps(*black_box(&a), *black_box(&b)); @@ -2256,7 +2298,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_xor_ps() { + const unsafe fn test_mm_xor_ps() { let a = transmute(u32x4::splat(0b0011)); let b = transmute(u32x4::splat(0b0101)); let r = _mm_xor_ps(*black_box(&a), *black_box(&b)); @@ -2979,36 +3021,40 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_cvtsi32_ss() { - let inputs = &[ - (4555i32, 4555.0f32), - (322223333, 322223330.0), - (-432, -432.0), - (-322223333, -322223330.0), - ]; + const unsafe fn test_mm_cvtsi32_ss() { + let a = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); - for &(x, f) in inputs.iter() { - let a = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); - let r = _mm_cvtsi32_ss(a, x); - let e = _mm_setr_ps(f, 6.0, 7.0, 8.0); - assert_eq_m128(e, r); - } + let r = _mm_cvtsi32_ss(a, 4555); + let e = _mm_setr_ps(4555.0, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); + + let r = _mm_cvtsi32_ss(a, 322223333); + let e = _mm_setr_ps(322223333.0, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); + + let r = _mm_cvtsi32_ss(a, -432); + let e = _mm_setr_ps(-432.0, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); + + let r = _mm_cvtsi32_ss(a, -322223333); + let e = _mm_setr_ps(-322223333.0, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cvtss_f32() { + const unsafe fn test_mm_cvtss_f32() { let a = _mm_setr_ps(312.0134, 5.0, 6.0, 7.0); assert_eq!(_mm_cvtss_f32(a), 312.0134); } #[simd_test(enable = "sse")] - unsafe fn test_mm_set_ss() { + const unsafe fn test_mm_set_ss() { let r = _mm_set_ss(black_box(4.25)); assert_eq_m128(r, _mm_setr_ps(4.25, 0.0, 0.0, 0.0)); } #[simd_test(enable = "sse")] - unsafe fn test_mm_set1_ps() { + const unsafe fn test_mm_set1_ps() { let r1 = _mm_set1_ps(black_box(4.25)); let r2 = _mm_set_ps1(black_box(4.25)); assert_eq!(get_m128(r1, 0), 4.25); @@ -3022,7 +3068,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_set_ps() { + const unsafe fn test_mm_set_ps() { let r = _mm_set_ps( black_box(1.0), black_box(2.0), @@ -3036,7 +3082,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_setr_ps() { + const unsafe fn test_mm_setr_ps() { let r = _mm_setr_ps( black_box(1.0), black_box(2.0), @@ -3047,21 +3093,21 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_setzero_ps() { + const unsafe fn test_mm_setzero_ps() { let r = *black_box(&_mm_setzero_ps()); assert_eq_m128(r, _mm_set1_ps(0.0)); } - #[test] + #[simd_test] #[allow(non_snake_case)] - fn test_MM_SHUFFLE() { + const fn test_MM_SHUFFLE() { assert_eq!(_MM_SHUFFLE(0, 1, 1, 3), 0b00_01_01_11); assert_eq!(_MM_SHUFFLE(3, 1, 1, 0), 0b11_01_01_00); assert_eq!(_MM_SHUFFLE(1, 2, 2, 1), 0b01_10_10_01); } #[simd_test(enable = "sse")] - unsafe fn test_mm_shuffle_ps() { + const unsafe fn test_mm_shuffle_ps() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); let r = _mm_shuffle_ps::<0b00_01_01_11>(a, b); @@ -3069,7 +3115,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_unpackhi_ps() { + const unsafe fn test_mm_unpackhi_ps() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); let r = _mm_unpackhi_ps(a, b); @@ -3077,7 +3123,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_unpacklo_ps() { + const unsafe fn test_mm_unpacklo_ps() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); let r = _mm_unpacklo_ps(a, b); @@ -3085,7 +3131,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_movehl_ps() { + const unsafe fn test_mm_movehl_ps() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); let r = _mm_movehl_ps(a, b); @@ -3093,7 +3139,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_movelh_ps() { + const unsafe fn test_mm_movelh_ps() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); let r = _mm_movelh_ps(a, b); @@ -3101,43 +3147,35 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_load_ss() { + const unsafe fn test_mm_load_ss() { let a = 42.0f32; let r = _mm_load_ss(ptr::addr_of!(a)); assert_eq_m128(r, _mm_setr_ps(42.0, 0.0, 0.0, 0.0)); } #[simd_test(enable = "sse")] - unsafe fn test_mm_load1_ps() { + const unsafe fn test_mm_load1_ps() { let a = 42.0f32; let r = _mm_load1_ps(ptr::addr_of!(a)); assert_eq_m128(r, _mm_setr_ps(42.0, 42.0, 42.0, 42.0)); } #[simd_test(enable = "sse")] - unsafe fn test_mm_load_ps() { - let vals = &[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; + const unsafe fn test_mm_load_ps() { + let vals = Memory { + data: [1.0f32, 2.0, 3.0, 4.0], + }; - let mut p = vals.as_ptr(); - let mut fixup = 0.0f32; - - // Make sure p is aligned, otherwise we might get a - // (signal: 11, SIGSEGV: invalid memory reference) - - let unalignment = (p as usize) & 0xf; - if unalignment != 0 { - let delta = (16 - unalignment) >> 2; - fixup = delta as f32; - p = p.add(delta); - } + // guaranteed to be aligned to 16 bytes + let p = vals.data.as_ptr(); let r = _mm_load_ps(p); - let e = _mm_add_ps(_mm_setr_ps(1.0, 2.0, 3.0, 4.0), _mm_set1_ps(fixup)); + let e = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); assert_eq_m128(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_loadu_ps() { + const unsafe fn test_mm_loadu_ps() { let vals = &[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let p = vals.as_ptr().add(3); let r = _mm_loadu_ps(black_box(p)); @@ -3145,29 +3183,21 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_loadr_ps() { - let vals = &[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; + const unsafe fn test_mm_loadr_ps() { + let vals = Memory { + data: [1.0f32, 2.0, 3.0, 4.0], + }; - let mut p = vals.as_ptr(); - let mut fixup = 0.0f32; - - // Make sure p is aligned, otherwise we might get a - // (signal: 11, SIGSEGV: invalid memory reference) - - let unalignment = (p as usize) & 0xf; - if unalignment != 0 { - let delta = (16 - unalignment) >> 2; - fixup = delta as f32; - p = p.add(delta); - } + // guaranteed to be aligned to 16 bytes + let p = vals.data.as_ptr(); let r = _mm_loadr_ps(p); - let e = _mm_add_ps(_mm_setr_ps(4.0, 3.0, 2.0, 1.0), _mm_set1_ps(fixup)); + let e = _mm_setr_ps(4.0, 3.0, 2.0, 1.0); assert_eq_m128(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_store_ss() { + const unsafe fn test_mm_store_ss() { let mut vals = [0.0f32; 8]; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); _mm_store_ss(vals.as_mut_ptr().add(1), a); @@ -3178,110 +3208,65 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_store1_ps() { - let mut vals = [0.0f32; 8]; + const unsafe fn test_mm_store1_ps() { + let mut vals = Memory { data: [0.0f32; 4] }; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); - let mut ofs = 0; - let mut p = vals.as_mut_ptr(); - - if (p as usize) & 0xf != 0 { - ofs = (16 - ((p as usize) & 0xf)) >> 2; - p = p.add(ofs); - } + // guaranteed to be aligned to 16 bytes + let p = vals.data.as_mut_ptr(); _mm_store1_ps(p, *black_box(&a)); - if ofs > 0 { - assert_eq!(vals[ofs - 1], 0.0); - } - assert_eq!(vals[ofs + 0], 1.0); - assert_eq!(vals[ofs + 1], 1.0); - assert_eq!(vals[ofs + 2], 1.0); - assert_eq!(vals[ofs + 3], 1.0); - assert_eq!(vals[ofs + 4], 0.0); + assert_eq!(vals.data, [1.0, 1.0, 1.0, 1.0]); } #[simd_test(enable = "sse")] - unsafe fn test_mm_store_ps() { - let mut vals = [0.0f32; 8]; + const unsafe fn test_mm_store_ps() { + let mut vals = Memory { data: [0.0f32; 4] }; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); - let mut ofs = 0; - let mut p = vals.as_mut_ptr(); - - // Align p to 16-byte boundary - if (p as usize) & 0xf != 0 { - ofs = (16 - ((p as usize) & 0xf)) >> 2; - p = p.add(ofs); - } + // guaranteed to be aligned to 16 bytes + let p = vals.data.as_mut_ptr(); _mm_store_ps(p, *black_box(&a)); - if ofs > 0 { - assert_eq!(vals[ofs - 1], 0.0); - } - assert_eq!(vals[ofs + 0], 1.0); - assert_eq!(vals[ofs + 1], 2.0); - assert_eq!(vals[ofs + 2], 3.0); - assert_eq!(vals[ofs + 3], 4.0); - assert_eq!(vals[ofs + 4], 0.0); + assert_eq!(vals.data, [1.0, 2.0, 3.0, 4.0]); } #[simd_test(enable = "sse")] - unsafe fn test_mm_storer_ps() { - let mut vals = [0.0f32; 8]; + const unsafe fn test_mm_storer_ps() { + let mut vals = Memory { data: [0.0f32; 4] }; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); - let mut ofs = 0; - let mut p = vals.as_mut_ptr(); - - // Align p to 16-byte boundary - if (p as usize) & 0xf != 0 { - ofs = (16 - ((p as usize) & 0xf)) >> 2; - p = p.add(ofs); - } + // guaranteed to be aligned to 16 bytes + let p = vals.data.as_mut_ptr(); _mm_storer_ps(p, *black_box(&a)); - if ofs > 0 { - assert_eq!(vals[ofs - 1], 0.0); - } - assert_eq!(vals[ofs + 0], 4.0); - assert_eq!(vals[ofs + 1], 3.0); - assert_eq!(vals[ofs + 2], 2.0); - assert_eq!(vals[ofs + 3], 1.0); - assert_eq!(vals[ofs + 4], 0.0); + assert_eq!(vals.data, [4.0, 3.0, 2.0, 1.0]); } #[simd_test(enable = "sse")] - unsafe fn test_mm_storeu_ps() { - let mut vals = [0.0f32; 8]; + const unsafe fn test_mm_storeu_ps() { + #[repr(align(16))] + struct Memory8 { + data: [f32; 8], + } + + // guaranteed to be aligned to 16 bytes + let mut vals = Memory8 { data: [0.0f32; 8] }; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); - let mut ofs = 0; - let mut p = vals.as_mut_ptr(); - - // Make sure p is **not** aligned to 16-byte boundary - if (p as usize) & 0xf == 0 { - ofs = 1; - p = p.add(1); - } + // guaranteed to be *not* aligned to 16 bytes + let p = vals.data.as_mut_ptr().offset(1); _mm_storeu_ps(p, *black_box(&a)); - if ofs > 0 { - assert_eq!(vals[ofs - 1], 0.0); - } - assert_eq!(vals[ofs + 0], 1.0); - assert_eq!(vals[ofs + 1], 2.0); - assert_eq!(vals[ofs + 2], 3.0); - assert_eq!(vals[ofs + 3], 4.0); - assert_eq!(vals[ofs + 4], 0.0); + assert_eq!(vals.data, [0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0]); } #[simd_test(enable = "sse")] - unsafe fn test_mm_move_ss() { + const unsafe fn test_mm_move_ss() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); @@ -3291,7 +3276,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_movemask_ps() { + const unsafe fn test_mm_movemask_ps() { let r = _mm_movemask_ps(_mm_setr_ps(-1.0, 5.0, -5.0, 0.0)); assert_eq!(r, 0b0101); @@ -3307,7 +3292,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_MM_TRANSPOSE4_PS() { + const unsafe fn test_MM_TRANSPOSE4_PS() { let mut a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let mut b = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); let mut c = _mm_setr_ps(9.0, 10.0, 11.0, 12.0); diff --git a/library/stdarch/crates/core_arch/src/x86_64/sse.rs b/library/stdarch/crates/core_arch/src/x86_64/sse.rs index 6bd7ec83ec99..e5c1f7915342 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/sse.rs @@ -62,13 +62,15 @@ pub fn _mm_cvttss_si64(a: __m128) -> i64 { #[target_feature(enable = "sse")] #[cfg_attr(test, assert_instr(cvtsi2ss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi64_ss(a: __m128, b: i64) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi64_ss(a: __m128, b: i64) -> __m128 { unsafe { simd_insert!(a, 0, b as f32) } } #[cfg(test)] mod tests { use crate::core_arch::arch::x86_64::*; + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; #[simd_test(enable = "sse")] @@ -123,21 +125,31 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_cvtsi64_ss() { - let inputs = &[ - (4555i64, 4555.0f32), - (322223333, 322223330.0), - (-432, -432.0), - (-322223333, -322223330.0), - (9223372036854775807, 9.223372e18), - (-9223372036854775808, -9.223372e18), - ]; + const unsafe fn test_mm_cvtsi64_ss() { + let a = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); - for &(x, f) in inputs { - let a = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); - let r = _mm_cvtsi64_ss(a, x); - let e = _mm_setr_ps(f, 6.0, 7.0, 8.0); - assert_eq_m128(e, r); - } + let r = _mm_cvtsi64_ss(a, 4555); + let e = _mm_setr_ps(4555.0, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); + + let r = _mm_cvtsi64_ss(a, 322223333); + let e = _mm_setr_ps(322223333.0, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); + + let r = _mm_cvtsi64_ss(a, -432); + let e = _mm_setr_ps(-432.0, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); + + let r = _mm_cvtsi64_ss(a, -322223333); + let e = _mm_setr_ps(-322223333.0, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); + + let r = _mm_cvtsi64_ss(a, 9223372036854775807); + let e = _mm_setr_ps(9.223372e18, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); + + let r = _mm_cvtsi64_ss(a, -9223372036854775808); + let e = _mm_setr_ps(-9.223372e18, 6.0, 7.0, 8.0); + assert_eq_m128(e, r); } } From cd28decba9593f01e87dff024e28c096df550d73 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 19:11:14 +0530 Subject: [PATCH 0226/3801] Make `sse2` functions const --- .../stdarch/crates/core_arch/src/x86/sse2.rs | 768 +++++++++++------- .../crates/core_arch/src/x86_64/sse2.rs | 25 +- 2 files changed, 468 insertions(+), 325 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index 93fe7a7ae3f4..098cd67c02d0 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -76,7 +76,8 @@ pub fn _mm_mfence() { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(paddb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_add_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_add(a.as_i8x16(), b.as_i8x16())) } } @@ -87,7 +88,8 @@ pub fn _mm_add_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(paddw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_add_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_add(a.as_i16x8(), b.as_i16x8())) } } @@ -98,7 +100,8 @@ pub fn _mm_add_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(paddd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_add_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_add(a.as_i32x4(), b.as_i32x4())) } } @@ -109,7 +112,8 @@ pub fn _mm_add_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(paddq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_add_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_add(a.as_i64x2(), b.as_i64x2())) } } @@ -120,7 +124,8 @@ pub fn _mm_add_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(paddsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_adds_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_adds_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_saturating_add(a.as_i8x16(), b.as_i8x16())) } } @@ -131,7 +136,8 @@ pub fn _mm_adds_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(paddsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_adds_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_adds_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_saturating_add(a.as_i16x8(), b.as_i16x8())) } } @@ -142,7 +148,8 @@ pub fn _mm_adds_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(paddusb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_adds_epu8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_adds_epu8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_saturating_add(a.as_u8x16(), b.as_u8x16())) } } @@ -153,7 +160,8 @@ pub fn _mm_adds_epu8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(paddusw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_adds_epu16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_adds_epu16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_saturating_add(a.as_u16x8(), b.as_u16x8())) } } @@ -164,7 +172,8 @@ pub fn _mm_adds_epu16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pavgb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_avg_epu8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_avg_epu8(a: __m128i, b: __m128i) -> __m128i { unsafe { let a = simd_cast::<_, u16x16>(a.as_u8x16()); let b = simd_cast::<_, u16x16>(b.as_u8x16()); @@ -180,7 +189,8 @@ pub fn _mm_avg_epu8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pavgw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_avg_epu16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_avg_epu16(a: __m128i, b: __m128i) -> __m128i { unsafe { let a = simd_cast::<_, u32x8>(a.as_u16x8()); let b = simd_cast::<_, u32x8>(b.as_u16x8()); @@ -200,7 +210,8 @@ pub fn _mm_avg_epu16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { let r: i32x8 = simd_mul(simd_cast(a.as_i16x8()), simd_cast(b.as_i16x8())); let even: i32x4 = simd_shuffle!(r, r, [0, 2, 4, 6]); @@ -217,7 +228,8 @@ pub fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmaxsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_max_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_max_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imax(a.as_i16x8(), b.as_i16x8()).as_m128i() } } @@ -229,7 +241,8 @@ pub fn _mm_max_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmaxub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_max_epu8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_max_epu8(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imax(a.as_u8x16(), b.as_u8x16()).as_m128i() } } @@ -241,7 +254,8 @@ pub fn _mm_max_epu8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pminsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_min_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_min_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_i16x8(), b.as_i16x8()).as_m128i() } } @@ -253,7 +267,8 @@ pub fn _mm_min_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pminub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_min_epu8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_min_epu8(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_u8x16(), b.as_u8x16()).as_m128i() } } @@ -267,7 +282,8 @@ pub fn _mm_min_epu8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmulhw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mulhi_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mulhi_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { let a = simd_cast::<_, i32x8>(a.as_i16x8()); let b = simd_cast::<_, i32x8>(b.as_i16x8()); @@ -286,7 +302,8 @@ pub fn _mm_mulhi_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmulhuw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mulhi_epu16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mulhi_epu16(a: __m128i, b: __m128i) -> __m128i { unsafe { let a = simd_cast::<_, u32x8>(a.as_u16x8()); let b = simd_cast::<_, u32x8>(b.as_u16x8()); @@ -305,7 +322,8 @@ pub fn _mm_mulhi_epu16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmullw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mullo_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mullo_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_mul(a.as_i16x8(), b.as_i16x8())) } } @@ -319,11 +337,12 @@ pub fn _mm_mullo_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmuludq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mul_epu32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mul_epu32(a: __m128i, b: __m128i) -> __m128i { unsafe { let a = a.as_u64x2(); let b = b.as_u64x2(); - let mask = u64x2::splat(u32::MAX.into()); + let mask = u64x2::splat(u32::MAX as u64); transmute(simd_mul(simd_and(a, mask), simd_and(b, mask))) } } @@ -351,7 +370,8 @@ pub fn _mm_sad_epu8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(psubb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sub_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_sub(a.as_i8x16(), b.as_i8x16())) } } @@ -362,7 +382,8 @@ pub fn _mm_sub_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(psubw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sub_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_sub(a.as_i16x8(), b.as_i16x8())) } } @@ -373,7 +394,8 @@ pub fn _mm_sub_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(psubd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sub_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_sub(a.as_i32x4(), b.as_i32x4())) } } @@ -384,7 +406,8 @@ pub fn _mm_sub_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(psubq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sub_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_sub(a.as_i64x2(), b.as_i64x2())) } } @@ -396,7 +419,8 @@ pub fn _mm_sub_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(psubsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_subs_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_subs_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_saturating_sub(a.as_i8x16(), b.as_i8x16())) } } @@ -408,7 +432,8 @@ pub fn _mm_subs_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(psubsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_subs_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_subs_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_saturating_sub(a.as_i16x8(), b.as_i16x8())) } } @@ -420,7 +445,8 @@ pub fn _mm_subs_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(psubusb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_subs_epu8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_subs_epu8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_saturating_sub(a.as_u8x16(), b.as_u8x16())) } } @@ -432,7 +458,8 @@ pub fn _mm_subs_epu8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(psubusw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_subs_epu16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_subs_epu16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_saturating_sub(a.as_u16x8(), b.as_u16x8())) } } @@ -444,7 +471,8 @@ pub fn _mm_subs_epu16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pslldq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_slli_si128(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_slli_si128(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { _mm_slli_si128_impl::(a) } } @@ -453,7 +481,8 @@ pub fn _mm_slli_si128(a: __m128i) -> __m128i { /// `_mm_slli_si128` intrinsic into a compile-time constant. #[inline] #[target_feature(enable = "sse2")] -unsafe fn _mm_slli_si128_impl(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +const unsafe fn _mm_slli_si128_impl(a: __m128i) -> __m128i { const fn mask(shift: i32, i: u32) -> u32 { let shift = shift as u32 & 0xff; if shift > 15 { i } else { 16 - shift + i } @@ -490,7 +519,8 @@ unsafe fn _mm_slli_si128_impl(a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pslldq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_bslli_si128(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_bslli_si128(a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); _mm_slli_si128_impl::(a) @@ -505,7 +535,8 @@ pub fn _mm_bslli_si128(a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(psrldq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_bsrli_si128(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_bsrli_si128(a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); _mm_srli_si128_impl::(a) @@ -520,7 +551,8 @@ pub fn _mm_bsrli_si128(a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(psllw, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_slli_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_slli_epi16(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 16 { @@ -551,7 +583,8 @@ pub fn _mm_sll_epi16(a: __m128i, count: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pslld, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_slli_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_slli_epi32(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 32 { @@ -582,7 +615,8 @@ pub fn _mm_sll_epi32(a: __m128i, count: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(psllq, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_slli_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_slli_epi64(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 64 { @@ -614,7 +648,8 @@ pub fn _mm_sll_epi64(a: __m128i, count: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(psraw, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_srai_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srai_epi16(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { transmute(simd_shr(a.as_i16x8(), i16x8::splat(IMM8.min(15) as i16))) } } @@ -640,7 +675,8 @@ pub fn _mm_sra_epi16(a: __m128i, count: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(psrad, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_srai_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srai_epi32(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { transmute(simd_shr(a.as_i32x4(), i32x4::splat(IMM8.min(31)))) } } @@ -665,7 +701,8 @@ pub fn _mm_sra_epi32(a: __m128i, count: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(psrldq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_srli_si128(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srli_si128(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { _mm_srli_si128_impl::(a) } } @@ -674,7 +711,8 @@ pub fn _mm_srli_si128(a: __m128i) -> __m128i { /// `_mm_srli_si128` intrinsic into a compile-time constant. #[inline] #[target_feature(enable = "sse2")] -unsafe fn _mm_srli_si128_impl(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +const unsafe fn _mm_srli_si128_impl(a: __m128i) -> __m128i { const fn mask(shift: i32, i: u32) -> u32 { if (shift as u32) > 15 { i + 16 @@ -716,7 +754,8 @@ unsafe fn _mm_srli_si128_impl(a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(psrlw, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_srli_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srli_epi16(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 16 { @@ -748,7 +787,8 @@ pub fn _mm_srl_epi16(a: __m128i, count: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(psrld, IMM8 = 8))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_srli_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srli_epi32(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 32 { @@ -780,7 +820,8 @@ pub fn _mm_srl_epi32(a: __m128i, count: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(psrlq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_srli_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srli_epi64(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 64 { @@ -811,7 +852,8 @@ pub fn _mm_srl_epi64(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(andps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_and_si128(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_and_si128(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_and(a, b) } } @@ -823,7 +865,8 @@ pub fn _mm_and_si128(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(andnps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_andnot_si128(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_andnot_si128(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_and(simd_xor(_mm_set1_epi8(-1), a), b) } } @@ -835,7 +878,8 @@ pub fn _mm_andnot_si128(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(orps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_or_si128(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_or_si128(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_or(a, b) } } @@ -847,7 +891,8 @@ pub fn _mm_or_si128(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(xorps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_xor_si128(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_xor_si128(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_xor(a, b) } } @@ -858,7 +903,8 @@ pub fn _mm_xor_si128(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pcmpeqb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmpeq_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_eq(a.as_i8x16(), b.as_i8x16())) } } @@ -869,7 +915,8 @@ pub fn _mm_cmpeq_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pcmpeqw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmpeq_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_eq(a.as_i16x8(), b.as_i16x8())) } } @@ -880,7 +927,8 @@ pub fn _mm_cmpeq_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pcmpeqd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmpeq_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_eq(a.as_i32x4(), b.as_i32x4())) } } @@ -891,7 +939,8 @@ pub fn _mm_cmpeq_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pcmpgtb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmpgt_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_gt(a.as_i8x16(), b.as_i8x16())) } } @@ -902,7 +951,8 @@ pub fn _mm_cmpgt_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pcmpgtw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmpgt_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_gt(a.as_i16x8(), b.as_i16x8())) } } @@ -913,7 +963,8 @@ pub fn _mm_cmpgt_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pcmpgtd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmpgt_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_gt(a.as_i32x4(), b.as_i32x4())) } } @@ -924,7 +975,8 @@ pub fn _mm_cmpgt_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pcmpgtb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmplt_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_lt(a.as_i8x16(), b.as_i8x16())) } } @@ -935,7 +987,8 @@ pub fn _mm_cmplt_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pcmpgtw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmplt_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_lt(a.as_i16x8(), b.as_i16x8())) } } @@ -946,7 +999,8 @@ pub fn _mm_cmplt_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pcmpgtd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmplt_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_lt(a.as_i32x4(), b.as_i32x4())) } } @@ -958,7 +1012,8 @@ pub fn _mm_cmplt_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(cvtdq2pd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepi32_pd(a: __m128i) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepi32_pd(a: __m128i) -> __m128d { unsafe { let a = a.as_i32x4(); simd_cast::(simd_shuffle!(a, a, [0, 1])) @@ -973,7 +1028,8 @@ pub fn _mm_cvtepi32_pd(a: __m128i) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(cvtsi2sd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi32_sd(a: __m128d, b: i32) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi32_sd(a: __m128d, b: i32) -> __m128d { unsafe { simd_insert!(a, 0, b as f64) } } @@ -985,7 +1041,8 @@ pub fn _mm_cvtsi32_sd(a: __m128d, b: i32) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(cvtdq2ps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepi32_ps(a: __m128i) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepi32_ps(a: __m128i) -> __m128 { unsafe { transmute(simd_cast::<_, f32x4>(a.as_i32x4())) } } @@ -1008,7 +1065,8 @@ pub fn _mm_cvtps_epi32(a: __m128) -> __m128i { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi32_si128(a: i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi32_si128(a: i32) -> __m128i { unsafe { transmute(i32x4::new(a, 0, 0, 0)) } } @@ -1018,7 +1076,8 @@ pub fn _mm_cvtsi32_si128(a: i32) -> __m128i { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi128_si32(a: __m128i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi128_si32(a: __m128i) -> i32 { unsafe { simd_extract!(a.as_i32x4(), 0) } } @@ -1030,7 +1089,8 @@ pub fn _mm_cvtsi128_si32(a: __m128i) -> i32 { #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_epi64x(e1: i64, e0: i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_epi64x(e1: i64, e0: i64) -> __m128i { unsafe { transmute(i64x2::new(e0, e1)) } } @@ -1041,7 +1101,8 @@ pub fn _mm_set_epi64x(e1: i64, e0: i64) -> __m128i { #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_epi32(e3: i32, e2: i32, e1: i32, e0: i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_epi32(e3: i32, e2: i32, e1: i32, e0: i32) -> __m128i { unsafe { transmute(i32x4::new(e0, e1, e2, e3)) } } @@ -1052,7 +1113,8 @@ pub fn _mm_set_epi32(e3: i32, e2: i32, e1: i32, e0: i32) -> __m128i { #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_epi16( e7: i16, e6: i16, e5: i16, @@ -1072,7 +1134,8 @@ pub fn _mm_set_epi16( #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_epi8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_epi8( e15: i8, e14: i8, e13: i8, @@ -1105,7 +1168,8 @@ pub fn _mm_set_epi8( #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set1_epi64x(a: i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set1_epi64x(a: i64) -> __m128i { _mm_set_epi64x(a, a) } @@ -1116,7 +1180,8 @@ pub fn _mm_set1_epi64x(a: i64) -> __m128i { #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set1_epi32(a: i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set1_epi32(a: i32) -> __m128i { _mm_set_epi32(a, a, a, a) } @@ -1127,7 +1192,8 @@ pub fn _mm_set1_epi32(a: i32) -> __m128i { #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set1_epi16(a: i16) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set1_epi16(a: i16) -> __m128i { _mm_set_epi16(a, a, a, a, a, a, a, a) } @@ -1138,7 +1204,8 @@ pub fn _mm_set1_epi16(a: i16) -> __m128i { #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set1_epi8(a: i8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set1_epi8(a: i8) -> __m128i { _mm_set_epi8(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a) } @@ -1149,7 +1216,8 @@ pub fn _mm_set1_epi8(a: i8) -> __m128i { #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_setr_epi32(e3: i32, e2: i32, e1: i32, e0: i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setr_epi32(e3: i32, e2: i32, e1: i32, e0: i32) -> __m128i { _mm_set_epi32(e0, e1, e2, e3) } @@ -1160,7 +1228,8 @@ pub fn _mm_setr_epi32(e3: i32, e2: i32, e1: i32, e0: i32) -> __m128i { #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_setr_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setr_epi16( e7: i16, e6: i16, e5: i16, @@ -1180,7 +1249,8 @@ pub fn _mm_setr_epi16( #[target_feature(enable = "sse2")] // no particular instruction to test #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_setr_epi8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setr_epi8( e15: i8, e14: i8, e13: i8, @@ -1211,7 +1281,8 @@ pub fn _mm_setr_epi8( #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(xorps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_setzero_si128() -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setzero_si128() -> __m128i { const { unsafe { mem::zeroed() } } } @@ -1221,7 +1292,8 @@ pub fn _mm_setzero_si128() -> __m128i { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_loadl_epi64(mem_addr: *const __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadl_epi64(mem_addr: *const __m128i) -> __m128i { _mm_set_epi64x(0, ptr::read_unaligned(mem_addr as *const i64)) } @@ -1237,7 +1309,8 @@ pub unsafe fn _mm_loadl_epi64(mem_addr: *const __m128i) -> __m128i { assert_instr(movaps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_load_si128(mem_addr: *const __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_si128(mem_addr: *const __m128i) -> __m128i { *mem_addr } @@ -1250,7 +1323,8 @@ pub unsafe fn _mm_load_si128(mem_addr: *const __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movups))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_loadu_si128(mem_addr: *const __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_si128(mem_addr: *const __m128i) -> __m128i { let mut dst: __m128i = _mm_undefined_si128(); ptr::copy_nonoverlapping( mem_addr as *const u8, @@ -1299,7 +1373,8 @@ pub unsafe fn _mm_maskmoveu_si128(a: __m128i, mask: __m128i, mem_addr: *mut i8) assert_instr(movaps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_store_si128(mem_addr: *mut __m128i, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_si128(mem_addr: *mut __m128i, a: __m128i) { *mem_addr = a; } @@ -1312,7 +1387,8 @@ pub unsafe fn _mm_store_si128(mem_addr: *mut __m128i, a: __m128i) { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movups))] // FIXME movdqu expected #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_storeu_si128(mem_addr: *mut __m128i, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_si128(mem_addr: *mut __m128i, a: __m128i) { mem_addr.write_unaligned(a); } @@ -1324,7 +1400,8 @@ pub unsafe fn _mm_storeu_si128(mem_addr: *mut __m128i, a: __m128i) { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_storel_epi64(mem_addr: *mut __m128i, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storel_epi64(mem_addr: *mut __m128i, a: __m128i) { ptr::copy_nonoverlapping(ptr::addr_of!(a) as *const u8, mem_addr as *mut u8, 8); } @@ -1393,7 +1470,8 @@ pub unsafe fn _mm_stream_si32(mem_addr: *mut i32, a: i32) { // FIXME movd on msvc, movd on i686 #[cfg_attr(all(test, target_arch = "x86_64"), assert_instr(movq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_move_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_move_epi64(a: __m128i) -> __m128i { unsafe { let r: i64x2 = simd_shuffle!(a.as_i64x2(), i64x2::ZERO, [0, 2]); transmute(r) @@ -1444,7 +1522,8 @@ pub fn _mm_packus_epi16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pextrw, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_extract_epi16(a: __m128i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_extract_epi16(a: __m128i) -> i32 { static_assert_uimm_bits!(IMM8, 3); unsafe { simd_extract!(a.as_u16x8(), IMM8 as u32, u16) as i32 } } @@ -1457,7 +1536,8 @@ pub fn _mm_extract_epi16(a: __m128i) -> i32 { #[cfg_attr(test, assert_instr(pinsrw, IMM8 = 7))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_insert_epi16(a: __m128i, i: i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_insert_epi16(a: __m128i, i: i32) -> __m128i { static_assert_uimm_bits!(IMM8, 3); unsafe { transmute(simd_insert!(a.as_i16x8(), IMM8 as u32, i as i16)) } } @@ -1469,7 +1549,8 @@ pub fn _mm_insert_epi16(a: __m128i, i: i32) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmovmskb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_movemask_epi8(a: __m128i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movemask_epi8(a: __m128i) -> i32 { unsafe { let z = i8x16::ZERO; let m: i8x16 = simd_lt(a.as_i8x16(), z); @@ -1485,7 +1566,8 @@ pub fn _mm_movemask_epi8(a: __m128i) -> i32 { #[cfg_attr(test, assert_instr(pshufd, IMM8 = 9))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_shuffle_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shuffle_epi32(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { let a = a.as_i32x4(); @@ -1515,7 +1597,8 @@ pub fn _mm_shuffle_epi32(a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pshufhw, IMM8 = 9))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_shufflehi_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shufflehi_epi16(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { let a = a.as_i16x8(); @@ -1549,7 +1632,8 @@ pub fn _mm_shufflehi_epi16(a: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pshuflw, IMM8 = 9))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_shufflelo_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shufflelo_epi16(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { let a = a.as_i16x8(); @@ -1578,7 +1662,8 @@ pub fn _mm_shufflelo_epi16(a: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(punpckhbw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpackhi_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpackhi_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_shuffle!( a.as_i8x16(), @@ -1595,7 +1680,8 @@ pub fn _mm_unpackhi_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(punpckhwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpackhi_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpackhi_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { let x = simd_shuffle!(a.as_i16x8(), b.as_i16x8(), [4, 12, 5, 13, 6, 14, 7, 15]); transmute::(x) @@ -1609,7 +1695,8 @@ pub fn _mm_unpackhi_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(unpckhps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpackhi_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpackhi_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_shuffle!(a.as_i32x4(), b.as_i32x4(), [2, 6, 3, 7])) } } @@ -1620,7 +1707,8 @@ pub fn _mm_unpackhi_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(unpckhpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpackhi_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpackhi_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_shuffle!(a.as_i64x2(), b.as_i64x2(), [1, 3])) } } @@ -1631,7 +1719,8 @@ pub fn _mm_unpackhi_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(punpcklbw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpacklo_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpacklo_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_shuffle!( a.as_i8x16(), @@ -1648,7 +1737,8 @@ pub fn _mm_unpacklo_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(punpcklwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpacklo_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpacklo_epi16(a: __m128i, b: __m128i) -> __m128i { unsafe { let x = simd_shuffle!(a.as_i16x8(), b.as_i16x8(), [0, 8, 1, 9, 2, 10, 3, 11]); transmute::(x) @@ -1662,7 +1752,8 @@ pub fn _mm_unpacklo_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(unpcklps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpacklo_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpacklo_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_shuffle!(a.as_i32x4(), b.as_i32x4(), [0, 4, 1, 5])) } } @@ -1673,7 +1764,8 @@ pub fn _mm_unpacklo_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movlhps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpacklo_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpacklo_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute::(simd_shuffle!(a.as_i64x2(), b.as_i64x2(), [0, 2])) } } @@ -1685,7 +1777,8 @@ pub fn _mm_unpacklo_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(addsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_add_sd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_sd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_insert!(a, 0, _mm_cvtsd_f64(a) + _mm_cvtsd_f64(b)) } } @@ -1697,7 +1790,8 @@ pub fn _mm_add_sd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(addpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_add_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_add(a, b) } } @@ -1709,7 +1803,8 @@ pub fn _mm_add_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(divsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_div_sd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_div_sd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_insert!(a, 0, _mm_cvtsd_f64(a) / _mm_cvtsd_f64(b)) } } @@ -1721,7 +1816,8 @@ pub fn _mm_div_sd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(divpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_div_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_div_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_div(a, b) } } @@ -1781,7 +1877,8 @@ pub fn _mm_min_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(mulsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mul_sd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mul_sd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_insert!(a, 0, _mm_cvtsd_f64(a) * _mm_cvtsd_f64(b)) } } @@ -1793,7 +1890,8 @@ pub fn _mm_mul_sd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(mulpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mul_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mul_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_mul(a, b) } } @@ -1828,7 +1926,8 @@ pub fn _mm_sqrt_pd(a: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(subsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sub_sd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_sd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_insert!(a, 0, _mm_cvtsd_f64(a) - _mm_cvtsd_f64(b)) } } @@ -1840,7 +1939,8 @@ pub fn _mm_sub_sd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(subpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sub_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_sub(a, b) } } @@ -1852,7 +1952,8 @@ pub fn _mm_sub_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(andps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_and_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_and_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { let a: __m128i = transmute(a); let b: __m128i = transmute(b); @@ -1867,7 +1968,8 @@ pub fn _mm_and_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(andnps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_andnot_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_andnot_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { let a: __m128i = transmute(a); let b: __m128i = transmute(b); @@ -1882,7 +1984,8 @@ pub fn _mm_andnot_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(orps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_or_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_or_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { let a: __m128i = transmute(a); let b: __m128i = transmute(b); @@ -1897,7 +2000,8 @@ pub fn _mm_or_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(xorps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_xor_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_xor_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { let a: __m128i = transmute(a); let b: __m128i = transmute(b); @@ -2325,7 +2429,8 @@ pub fn _mm_ucomineq_sd(a: __m128d, b: __m128d) -> i32 { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(cvtpd2ps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtpd_ps(a: __m128d) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtpd_ps(a: __m128d) -> __m128 { unsafe { let r = simd_cast::<_, f32x2>(a.as_f64x2()); let zero = f32x2::ZERO; @@ -2342,7 +2447,8 @@ pub fn _mm_cvtpd_ps(a: __m128d) -> __m128 { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(cvtps2pd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtps_pd(a: __m128) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtps_pd(a: __m128) -> __m128d { unsafe { let a = a.as_f32x4(); transmute(simd_cast::(simd_shuffle!(a, a, [0, 1]))) @@ -2393,7 +2499,8 @@ pub fn _mm_cvtsd_ss(a: __m128, b: __m128d) -> __m128 { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsd_f64(a: __m128d) -> f64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsd_f64(a: __m128d) -> f64 { unsafe { simd_extract!(a, 0) } } @@ -2407,7 +2514,8 @@ pub fn _mm_cvtsd_f64(a: __m128d) -> f64 { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(cvtss2sd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtss_sd(a: __m128d, b: __m128) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtss_sd(a: __m128d, b: __m128) -> __m128d { unsafe { let elt: f32 = simd_extract!(b, 0); simd_insert!(a, 0, elt as f64) @@ -2457,7 +2565,8 @@ pub fn _mm_cvttps_epi32(a: __m128) -> __m128i { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_sd(a: f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_sd(a: f64) -> __m128d { _mm_set_pd(0.0, a) } @@ -2468,7 +2577,8 @@ pub fn _mm_set_sd(a: f64) -> __m128d { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set1_pd(a: f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set1_pd(a: f64) -> __m128d { _mm_set_pd(a, a) } @@ -2479,7 +2589,8 @@ pub fn _mm_set1_pd(a: f64) -> __m128d { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_pd1(a: f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_pd1(a: f64) -> __m128d { _mm_set_pd(a, a) } @@ -2490,7 +2601,8 @@ pub fn _mm_set_pd1(a: f64) -> __m128d { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_set_pd(a: f64, b: f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_pd(a: f64, b: f64) -> __m128d { __m128d([b, a]) } @@ -2501,7 +2613,8 @@ pub fn _mm_set_pd(a: f64, b: f64) -> __m128d { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_setr_pd(a: f64, b: f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setr_pd(a: f64, b: f64) -> __m128d { _mm_set_pd(b, a) } @@ -2513,7 +2626,8 @@ pub fn _mm_setr_pd(a: f64, b: f64) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(xorp))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_setzero_pd() -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setzero_pd() -> __m128d { const { unsafe { mem::zeroed() } } } @@ -2527,12 +2641,13 @@ pub fn _mm_setzero_pd() -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movmskpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_movemask_pd(a: __m128d) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movemask_pd(a: __m128d) -> i32 { // Propagate the highest bit to the rest, because simd_bitmask // requires all-1 or all-0. unsafe { let mask: i64x2 = simd_lt(transmute(a), i64x2::ZERO); - simd_bitmask::(mask).into() + simd_bitmask::(mask) as i32 } } @@ -2550,7 +2665,8 @@ pub fn _mm_movemask_pd(a: __m128d) -> i32 { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm_load_pd(mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_pd(mem_addr: *const f64) -> __m128d { *(mem_addr as *const __m128d) } @@ -2562,7 +2678,8 @@ pub unsafe fn _mm_load_pd(mem_addr: *const f64) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_load_sd(mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_sd(mem_addr: *const f64) -> __m128d { _mm_setr_pd(*mem_addr, 0.) } @@ -2575,7 +2692,8 @@ pub unsafe fn _mm_load_sd(mem_addr: *const f64) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movhps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_loadh_pd(a: __m128d, mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadh_pd(a: __m128d, mem_addr: *const f64) -> __m128d { _mm_setr_pd(simd_extract!(a, 0), *mem_addr) } @@ -2588,7 +2706,8 @@ pub unsafe fn _mm_loadh_pd(a: __m128d, mem_addr: *const f64) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movlps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_loadl_pd(a: __m128d, mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadl_pd(a: __m128d, mem_addr: *const f64) -> __m128d { _mm_setr_pd(*mem_addr, simd_extract!(a, 1)) } @@ -2630,7 +2749,8 @@ pub unsafe fn _mm_stream_pd(mem_addr: *mut f64, a: __m128d) { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movlps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_store_sd(mem_addr: *mut f64, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_sd(mem_addr: *mut f64, a: __m128d) { *mem_addr = simd_extract!(a, 0) } @@ -2647,7 +2767,8 @@ pub unsafe fn _mm_store_sd(mem_addr: *mut f64, a: __m128d) { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm_store_pd(mem_addr: *mut f64, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_pd(mem_addr: *mut f64, a: __m128d) { *(mem_addr as *mut __m128d) = a; } @@ -2660,7 +2781,8 @@ pub unsafe fn _mm_store_pd(mem_addr: *mut f64, a: __m128d) { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movups))] // FIXME movupd expected #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_storeu_pd(mem_addr: *mut f64, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_pd(mem_addr: *mut f64, a: __m128d) { mem_addr.cast::<__m128d>().write_unaligned(a); } @@ -2672,7 +2794,8 @@ pub unsafe fn _mm_storeu_pd(mem_addr: *mut f64, a: __m128d) { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86_updates", since = "1.82.0")] -pub unsafe fn _mm_storeu_si16(mem_addr: *mut u8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_si16(mem_addr: *mut u8, a: __m128i) { ptr::write_unaligned(mem_addr as *mut i16, simd_extract(a.as_i16x8(), 0)) } @@ -2684,7 +2807,8 @@ pub unsafe fn _mm_storeu_si16(mem_addr: *mut u8, a: __m128i) { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86_updates", since = "1.82.0")] -pub unsafe fn _mm_storeu_si32(mem_addr: *mut u8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_si32(mem_addr: *mut u8, a: __m128i) { ptr::write_unaligned(mem_addr as *mut i32, simd_extract(a.as_i32x4(), 0)) } @@ -2696,7 +2820,8 @@ pub unsafe fn _mm_storeu_si32(mem_addr: *mut u8, a: __m128i) { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86_updates", since = "1.82.0")] -pub unsafe fn _mm_storeu_si64(mem_addr: *mut u8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_si64(mem_addr: *mut u8, a: __m128i) { ptr::write_unaligned(mem_addr as *mut i64, simd_extract(a.as_i64x2(), 0)) } @@ -2709,7 +2834,8 @@ pub unsafe fn _mm_storeu_si64(mem_addr: *mut u8, a: __m128i) { #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm_store1_pd(mem_addr: *mut f64, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store1_pd(mem_addr: *mut f64, a: __m128d) { let b: __m128d = simd_shuffle!(a, a, [0, 0]); *(mem_addr as *mut __m128d) = b; } @@ -2723,7 +2849,8 @@ pub unsafe fn _mm_store1_pd(mem_addr: *mut f64, a: __m128d) { #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm_store_pd1(mem_addr: *mut f64, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_pd1(mem_addr: *mut f64, a: __m128d) { let b: __m128d = simd_shuffle!(a, a, [0, 0]); *(mem_addr as *mut __m128d) = b; } @@ -2738,7 +2865,8 @@ pub unsafe fn _mm_store_pd1(mem_addr: *mut f64, a: __m128d) { #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm_storer_pd(mem_addr: *mut f64, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storer_pd(mem_addr: *mut f64, a: __m128d) { let b: __m128d = simd_shuffle!(a, a, [1, 0]); *(mem_addr as *mut __m128d) = b; } @@ -2751,7 +2879,8 @@ pub unsafe fn _mm_storer_pd(mem_addr: *mut f64, a: __m128d) { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movhps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_storeh_pd(mem_addr: *mut f64, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeh_pd(mem_addr: *mut f64, a: __m128d) { *mem_addr = simd_extract!(a, 1); } @@ -2763,7 +2892,8 @@ pub unsafe fn _mm_storeh_pd(mem_addr: *mut f64, a: __m128d) { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movlps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_storel_pd(mem_addr: *mut f64, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storel_pd(mem_addr: *mut f64, a: __m128d) { *mem_addr = simd_extract!(a, 0); } @@ -2775,7 +2905,8 @@ pub unsafe fn _mm_storel_pd(mem_addr: *mut f64, a: __m128d) { #[target_feature(enable = "sse2")] // #[cfg_attr(test, assert_instr(movapd))] // FIXME LLVM uses different codegen #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_load1_pd(mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load1_pd(mem_addr: *const f64) -> __m128d { let d = *mem_addr; _mm_setr_pd(d, d) } @@ -2788,7 +2919,8 @@ pub unsafe fn _mm_load1_pd(mem_addr: *const f64) -> __m128d { #[target_feature(enable = "sse2")] // #[cfg_attr(test, assert_instr(movapd))] // FIXME same as _mm_load1_pd #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_load_pd1(mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_pd1(mem_addr: *const f64) -> __m128d { _mm_load1_pd(mem_addr) } @@ -2804,7 +2936,8 @@ pub unsafe fn _mm_load_pd1(mem_addr: *const f64) -> __m128d { assert_instr(movaps) )] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_loadr_pd(mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadr_pd(mem_addr: *const f64) -> __m128d { let a = _mm_load_pd(mem_addr); simd_shuffle!(a, a, [1, 0]) } @@ -2818,7 +2951,8 @@ pub unsafe fn _mm_loadr_pd(mem_addr: *const f64) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movups))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_loadu_pd(mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_pd(mem_addr: *const f64) -> __m128d { let mut dst = _mm_undefined_pd(); ptr::copy_nonoverlapping( mem_addr as *const u8, @@ -2836,7 +2970,8 @@ pub unsafe fn _mm_loadu_pd(mem_addr: *const f64) -> __m128d { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86_updates", since = "1.82.0")] -pub unsafe fn _mm_loadu_si16(mem_addr: *const u8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_si16(mem_addr: *const u8) -> __m128i { transmute(i16x8::new( ptr::read_unaligned(mem_addr as *const i16), 0, @@ -2857,7 +2992,8 @@ pub unsafe fn _mm_loadu_si16(mem_addr: *const u8) -> __m128i { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86_updates", since = "1.82.0")] -pub unsafe fn _mm_loadu_si32(mem_addr: *const u8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_si32(mem_addr: *const u8) -> __m128i { transmute(i32x4::new( ptr::read_unaligned(mem_addr as *const i32), 0, @@ -2874,7 +3010,8 @@ pub unsafe fn _mm_loadu_si32(mem_addr: *const u8) -> __m128i { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86_mm_loadu_si64", since = "1.46.0")] -pub unsafe fn _mm_loadu_si64(mem_addr: *const u8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_si64(mem_addr: *const u8) -> __m128i { transmute(i64x2::new(ptr::read_unaligned(mem_addr as *const i64), 0)) } @@ -2888,7 +3025,8 @@ pub unsafe fn _mm_loadu_si64(mem_addr: *const u8) -> __m128i { #[cfg_attr(test, assert_instr(shufps, MASK = 2))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_shuffle_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shuffle_pd(a: __m128d, b: __m128d) -> __m128d { static_assert_uimm_bits!(MASK, 8); unsafe { simd_shuffle!(a, b, [MASK as u32 & 0b1, ((MASK as u32 >> 1) & 0b1) + 2]) } } @@ -2902,7 +3040,8 @@ pub fn _mm_shuffle_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_move_sd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_move_sd(a: __m128d, b: __m128d) -> __m128d { unsafe { _mm_setr_pd(simd_extract!(b, 0), simd_extract!(a, 1)) } } @@ -2913,7 +3052,8 @@ pub fn _mm_move_sd(a: __m128d, b: __m128d) -> __m128d { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_castpd_ps(a: __m128d) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castpd_ps(a: __m128d) -> __m128 { unsafe { transmute(a) } } @@ -2924,7 +3064,8 @@ pub fn _mm_castpd_ps(a: __m128d) -> __m128 { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_castpd_si128(a: __m128d) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castpd_si128(a: __m128d) -> __m128i { unsafe { transmute(a) } } @@ -2935,7 +3076,8 @@ pub fn _mm_castpd_si128(a: __m128d) -> __m128i { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_castps_pd(a: __m128) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castps_pd(a: __m128) -> __m128d { unsafe { transmute(a) } } @@ -2946,7 +3088,8 @@ pub fn _mm_castps_pd(a: __m128) -> __m128d { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_castps_si128(a: __m128) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castps_si128(a: __m128) -> __m128i { unsafe { transmute(a) } } @@ -2957,7 +3100,8 @@ pub fn _mm_castps_si128(a: __m128) -> __m128i { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_castsi128_pd(a: __m128i) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castsi128_pd(a: __m128i) -> __m128d { unsafe { transmute(a) } } @@ -2968,7 +3112,8 @@ pub fn _mm_castsi128_pd(a: __m128i) -> __m128d { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_castsi128_ps(a: __m128i) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castsi128_ps(a: __m128i) -> __m128 { unsafe { transmute(a) } } @@ -2981,7 +3126,8 @@ pub fn _mm_castsi128_ps(a: __m128i) -> __m128 { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_undefined_pd() -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_undefined_pd() -> __m128d { const { unsafe { mem::zeroed() } } } @@ -2994,7 +3140,8 @@ pub fn _mm_undefined_pd() -> __m128d { #[inline] #[target_feature(enable = "sse2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_undefined_si128() -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_undefined_si128() -> __m128i { const { unsafe { mem::zeroed() } } } @@ -3009,7 +3156,8 @@ pub fn _mm_undefined_si128() -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(unpckhpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpackhi_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpackhi_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_shuffle!(a, b, [1, 3]) } } @@ -3024,7 +3172,8 @@ pub fn _mm_unpackhi_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movlhps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_unpacklo_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_unpacklo_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { simd_shuffle!(a, b, [0, 2]) } } @@ -3118,6 +3267,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use crate::{ core_arch::{simd::*, x86::*}, hint::black_box, @@ -3157,7 +3307,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_add_epi8() { + const unsafe fn test_mm_add_epi8() { let a = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); #[rustfmt::skip] let b = _mm_setr_epi8( @@ -3180,7 +3330,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_add_epi16() { + const unsafe fn test_mm_add_epi16() { let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_add_epi16(a, b); @@ -3189,7 +3339,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_add_epi32() { + const unsafe fn test_mm_add_epi32() { let a = _mm_setr_epi32(0, 1, 2, 3); let b = _mm_setr_epi32(4, 5, 6, 7); let r = _mm_add_epi32(a, b); @@ -3198,7 +3348,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_add_epi64() { + const unsafe fn test_mm_add_epi64() { let a = _mm_setr_epi64x(0, 1); let b = _mm_setr_epi64x(2, 3); let r = _mm_add_epi64(a, b); @@ -3207,7 +3357,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_adds_epi8() { + const unsafe fn test_mm_adds_epi8() { let a = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); #[rustfmt::skip] let b = _mm_setr_epi8( @@ -3238,7 +3388,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_adds_epi16() { + const unsafe fn test_mm_adds_epi16() { let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_adds_epi16(a, b); @@ -3263,7 +3413,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_adds_epu8() { + const unsafe fn test_mm_adds_epu8() { let a = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); #[rustfmt::skip] let b = _mm_setr_epi8( @@ -3286,7 +3436,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_adds_epu16() { + const unsafe fn test_mm_adds_epu16() { let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_adds_epu16(a, b); @@ -3303,21 +3453,21 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_avg_epu8() { + const unsafe fn test_mm_avg_epu8() { let (a, b) = (_mm_set1_epi8(3), _mm_set1_epi8(9)); let r = _mm_avg_epu8(a, b); assert_eq_m128i(r, _mm_set1_epi8(6)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_avg_epu16() { + const unsafe fn test_mm_avg_epu16() { let (a, b) = (_mm_set1_epi16(3), _mm_set1_epi16(9)); let r = _mm_avg_epu16(a, b); assert_eq_m128i(r, _mm_set1_epi16(6)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_madd_epi16() { + const unsafe fn test_mm_madd_epi16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_setr_epi16(9, 10, 11, 12, 13, 14, 15, 16); let r = _mm_madd_epi16(a, b); @@ -3352,7 +3502,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_max_epi16() { + const unsafe fn test_mm_max_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(-1); let r = _mm_max_epi16(a, b); @@ -3360,7 +3510,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_max_epu8() { + const unsafe fn test_mm_max_epu8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(!0); let r = _mm_max_epu8(a, b); @@ -3368,7 +3518,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_min_epi16() { + const unsafe fn test_mm_min_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(-1); let r = _mm_min_epi16(a, b); @@ -3376,7 +3526,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_min_epu8() { + const unsafe fn test_mm_min_epu8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(!0); let r = _mm_min_epu8(a, b); @@ -3384,28 +3534,28 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_mulhi_epi16() { + const unsafe fn test_mm_mulhi_epi16() { let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(-1001)); let r = _mm_mulhi_epi16(a, b); assert_eq_m128i(r, _mm_set1_epi16(-16)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_mulhi_epu16() { + const unsafe fn test_mm_mulhi_epu16() { let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(1001)); let r = _mm_mulhi_epu16(a, b); assert_eq_m128i(r, _mm_set1_epi16(15)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_mullo_epi16() { + const unsafe fn test_mm_mullo_epi16() { let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(-1001)); let r = _mm_mullo_epi16(a, b); assert_eq_m128i(r, _mm_set1_epi16(-17960)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_mul_epu32() { + const unsafe fn test_mm_mul_epu32() { let a = _mm_setr_epi64x(1_000_000_000, 1 << 34); let b = _mm_setr_epi64x(1_000_000_000, 1 << 35); let r = _mm_mul_epu32(a, b); @@ -3429,35 +3579,35 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_sub_epi8() { + const unsafe fn test_mm_sub_epi8() { let (a, b) = (_mm_set1_epi8(5), _mm_set1_epi8(6)); let r = _mm_sub_epi8(a, b); assert_eq_m128i(r, _mm_set1_epi8(-1)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_sub_epi16() { + const unsafe fn test_mm_sub_epi16() { let (a, b) = (_mm_set1_epi16(5), _mm_set1_epi16(6)); let r = _mm_sub_epi16(a, b); assert_eq_m128i(r, _mm_set1_epi16(-1)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_sub_epi32() { + const unsafe fn test_mm_sub_epi32() { let (a, b) = (_mm_set1_epi32(5), _mm_set1_epi32(6)); let r = _mm_sub_epi32(a, b); assert_eq_m128i(r, _mm_set1_epi32(-1)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_sub_epi64() { + const unsafe fn test_mm_sub_epi64() { let (a, b) = (_mm_set1_epi64x(5), _mm_set1_epi64x(6)); let r = _mm_sub_epi64(a, b); assert_eq_m128i(r, _mm_set1_epi64x(-1)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_subs_epi8() { + const unsafe fn test_mm_subs_epi8() { let (a, b) = (_mm_set1_epi8(5), _mm_set1_epi8(2)); let r = _mm_subs_epi8(a, b); assert_eq_m128i(r, _mm_set1_epi8(3)); @@ -3480,7 +3630,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_subs_epi16() { + const unsafe fn test_mm_subs_epi16() { let (a, b) = (_mm_set1_epi16(5), _mm_set1_epi16(2)); let r = _mm_subs_epi16(a, b); assert_eq_m128i(r, _mm_set1_epi16(3)); @@ -3503,7 +3653,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_subs_epu8() { + const unsafe fn test_mm_subs_epu8() { let (a, b) = (_mm_set1_epi8(5), _mm_set1_epi8(2)); let r = _mm_subs_epu8(a, b); assert_eq_m128i(r, _mm_set1_epi8(3)); @@ -3518,7 +3668,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_subs_epu16() { + const unsafe fn test_mm_subs_epu16() { let (a, b) = (_mm_set1_epi16(5), _mm_set1_epi16(2)); let r = _mm_subs_epu16(a, b); assert_eq_m128i(r, _mm_set1_epi16(3)); @@ -3533,7 +3683,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_slli_si128() { + const unsafe fn test_mm_slli_si128() { #[rustfmt::skip] let a = _mm_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, @@ -3559,7 +3709,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_slli_epi16() { + const unsafe fn test_mm_slli_epi16() { let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF); let r = _mm_slli_epi16::<4>(a); assert_eq_m128i( @@ -3587,7 +3737,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_slli_epi32() { + const unsafe fn test_mm_slli_epi32() { let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF); let r = _mm_slli_epi32::<4>(a); assert_eq_m128i(r, _mm_setr_epi32(0xEEEE0, -0xEEEE0, 0xFFFF0, -0xFFFF0)); @@ -3609,7 +3759,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_slli_epi64() { + const unsafe fn test_mm_slli_epi64() { let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF); let r = _mm_slli_epi64::<4>(a); assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFFF0, -0xFFFFFFFF0)); @@ -3631,7 +3781,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_srai_epi16() { + const unsafe fn test_mm_srai_epi16() { let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF); let r = _mm_srai_epi16::<4>(a); assert_eq_m128i( @@ -3659,7 +3809,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_srai_epi32() { + const unsafe fn test_mm_srai_epi32() { let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF); let r = _mm_srai_epi32::<4>(a); assert_eq_m128i(r, _mm_setr_epi32(0xEEE, -0xEEF, 0xFFF, -0x1000)); @@ -3681,7 +3831,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_srli_si128() { + const unsafe fn test_mm_srli_si128() { #[rustfmt::skip] let a = _mm_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, @@ -3710,7 +3860,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_srli_epi16() { + const unsafe fn test_mm_srli_epi16() { let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF); let r = _mm_srli_epi16::<4>(a); assert_eq_m128i( @@ -3738,7 +3888,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_srli_epi32() { + const unsafe fn test_mm_srli_epi32() { let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF); let r = _mm_srli_epi32::<4>(a); assert_eq_m128i(r, _mm_setr_epi32(0xEEE, 0xFFFF111, 0xFFF, 0xFFFF000)); @@ -3760,7 +3910,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_srli_epi64() { + const unsafe fn test_mm_srli_epi64() { let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF); let r = _mm_srli_epi64::<4>(a); assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFF, 0xFFFFFFFF0000000)); @@ -3782,7 +3932,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_and_si128() { + const unsafe fn test_mm_and_si128() { let a = _mm_set1_epi8(5); let b = _mm_set1_epi8(3); let r = _mm_and_si128(a, b); @@ -3790,7 +3940,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_andnot_si128() { + const unsafe fn test_mm_andnot_si128() { let a = _mm_set1_epi8(5); let b = _mm_set1_epi8(3); let r = _mm_andnot_si128(a, b); @@ -3798,7 +3948,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_or_si128() { + const unsafe fn test_mm_or_si128() { let a = _mm_set1_epi8(5); let b = _mm_set1_epi8(3); let r = _mm_or_si128(a, b); @@ -3806,7 +3956,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_xor_si128() { + const unsafe fn test_mm_xor_si128() { let a = _mm_set1_epi8(5); let b = _mm_set1_epi8(3); let r = _mm_xor_si128(a, b); @@ -3814,7 +3964,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cmpeq_epi8() { + const unsafe fn test_mm_cmpeq_epi8() { let a = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm_setr_epi8(15, 14, 2, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_cmpeq_epi8(a, b); @@ -3828,7 +3978,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cmpeq_epi16() { + const unsafe fn test_mm_cmpeq_epi16() { let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_setr_epi16(7, 6, 2, 4, 3, 2, 1, 0); let r = _mm_cmpeq_epi16(a, b); @@ -3836,7 +3986,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cmpeq_epi32() { + const unsafe fn test_mm_cmpeq_epi32() { let a = _mm_setr_epi32(0, 1, 2, 3); let b = _mm_setr_epi32(3, 2, 2, 0); let r = _mm_cmpeq_epi32(a, b); @@ -3844,7 +3994,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cmpgt_epi8() { + const unsafe fn test_mm_cmpgt_epi8() { let a = _mm_set_epi8(5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); let b = _mm_set1_epi8(0); let r = _mm_cmpgt_epi8(a, b); @@ -3853,7 +4003,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cmpgt_epi16() { + const unsafe fn test_mm_cmpgt_epi16() { let a = _mm_set_epi16(5, 0, 0, 0, 0, 0, 0, 0); let b = _mm_set1_epi16(0); let r = _mm_cmpgt_epi16(a, b); @@ -3862,7 +4012,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cmpgt_epi32() { + const unsafe fn test_mm_cmpgt_epi32() { let a = _mm_set_epi32(5, 0, 0, 0); let b = _mm_set1_epi32(0); let r = _mm_cmpgt_epi32(a, b); @@ -3870,7 +4020,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cmplt_epi8() { + const unsafe fn test_mm_cmplt_epi8() { let a = _mm_set1_epi8(0); let b = _mm_set_epi8(5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); let r = _mm_cmplt_epi8(a, b); @@ -3879,7 +4029,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cmplt_epi16() { + const unsafe fn test_mm_cmplt_epi16() { let a = _mm_set1_epi16(0); let b = _mm_set_epi16(5, 0, 0, 0, 0, 0, 0, 0); let r = _mm_cmplt_epi16(a, b); @@ -3888,7 +4038,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cmplt_epi32() { + const unsafe fn test_mm_cmplt_epi32() { let a = _mm_set1_epi32(0); let b = _mm_set_epi32(5, 0, 0, 0); let r = _mm_cmplt_epi32(a, b); @@ -3896,21 +4046,21 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtepi32_pd() { + const unsafe fn test_mm_cvtepi32_pd() { let a = _mm_set_epi32(35, 25, 15, 5); let r = _mm_cvtepi32_pd(a); assert_eq_m128d(r, _mm_setr_pd(5.0, 15.0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtsi32_sd() { + const unsafe fn test_mm_cvtsi32_sd() { let a = _mm_set1_pd(3.5); let r = _mm_cvtsi32_sd(a, 5); assert_eq_m128d(r, _mm_setr_pd(5.0, 3.5)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtepi32_ps() { + const unsafe fn test_mm_cvtepi32_ps() { let a = _mm_setr_epi32(1, 2, 3, 4); let r = _mm_cvtepi32_ps(a); assert_eq_m128(r, _mm_setr_ps(1.0, 2.0, 3.0, 4.0)); @@ -3924,37 +4074,37 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtsi32_si128() { + const unsafe fn test_mm_cvtsi32_si128() { let r = _mm_cvtsi32_si128(5); assert_eq_m128i(r, _mm_setr_epi32(5, 0, 0, 0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtsi128_si32() { + const unsafe fn test_mm_cvtsi128_si32() { let r = _mm_cvtsi128_si32(_mm_setr_epi32(5, 0, 0, 0)); assert_eq!(r, 5); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set_epi64x() { + const unsafe fn test_mm_set_epi64x() { let r = _mm_set_epi64x(0, 1); assert_eq_m128i(r, _mm_setr_epi64x(1, 0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set_epi32() { + const unsafe fn test_mm_set_epi32() { let r = _mm_set_epi32(0, 1, 2, 3); assert_eq_m128i(r, _mm_setr_epi32(3, 2, 1, 0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set_epi16() { + const unsafe fn test_mm_set_epi16() { let r = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); assert_eq_m128i(r, _mm_setr_epi16(7, 6, 5, 4, 3, 2, 1, 0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set_epi8() { + const unsafe fn test_mm_set_epi8() { #[rustfmt::skip] let r = _mm_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -3968,43 +4118,43 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set1_epi64x() { + const unsafe fn test_mm_set1_epi64x() { let r = _mm_set1_epi64x(1); assert_eq_m128i(r, _mm_set1_epi64x(1)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set1_epi32() { + const unsafe fn test_mm_set1_epi32() { let r = _mm_set1_epi32(1); assert_eq_m128i(r, _mm_set1_epi32(1)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set1_epi16() { + const unsafe fn test_mm_set1_epi16() { let r = _mm_set1_epi16(1); assert_eq_m128i(r, _mm_set1_epi16(1)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set1_epi8() { + const unsafe fn test_mm_set1_epi8() { let r = _mm_set1_epi8(1); assert_eq_m128i(r, _mm_set1_epi8(1)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_setr_epi32() { + const unsafe fn test_mm_setr_epi32() { let r = _mm_setr_epi32(0, 1, 2, 3); assert_eq_m128i(r, _mm_setr_epi32(0, 1, 2, 3)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_setr_epi16() { + const unsafe fn test_mm_setr_epi16() { let r = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); assert_eq_m128i(r, _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_setr_epi8() { + const unsafe fn test_mm_setr_epi8() { #[rustfmt::skip] let r = _mm_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -4018,27 +4168,27 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_setzero_si128() { + const unsafe fn test_mm_setzero_si128() { let r = _mm_setzero_si128(); assert_eq_m128i(r, _mm_set1_epi64x(0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_loadl_epi64() { + const unsafe fn test_mm_loadl_epi64() { let a = _mm_setr_epi64x(6, 5); let r = _mm_loadl_epi64(ptr::addr_of!(a)); assert_eq_m128i(r, _mm_setr_epi64x(6, 0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_load_si128() { + const unsafe fn test_mm_load_si128() { let a = _mm_set_epi64x(5, 6); let r = _mm_load_si128(ptr::addr_of!(a) as *const _); assert_eq_m128i(a, r); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_loadu_si128() { + const unsafe fn test_mm_loadu_si128() { let a = _mm_set_epi64x(5, 6); let r = _mm_loadu_si128(ptr::addr_of!(a) as *const _); assert_eq_m128i(a, r); @@ -4063,7 +4213,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_store_si128() { + const unsafe fn test_mm_store_si128() { let a = _mm_set1_epi8(9); let mut r = _mm_set1_epi8(0); _mm_store_si128(&mut r, a); @@ -4071,7 +4221,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_storeu_si128() { + const unsafe fn test_mm_storeu_si128() { let a = _mm_set1_epi8(9); let mut r = _mm_set1_epi8(0); _mm_storeu_si128(&mut r, a); @@ -4079,7 +4229,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_storel_epi64() { + const unsafe fn test_mm_storel_epi64() { let a = _mm_setr_epi64x(2, 9); let mut r = _mm_set1_epi8(0); _mm_storel_epi64(&mut r, a); @@ -4111,7 +4261,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_move_epi64() { + const unsafe fn test_mm_move_epi64() { let a = _mm_setr_epi64x(5, 6); let r = _mm_move_epi64(a); assert_eq_m128i(r, _mm_setr_epi64x(5, 0)); @@ -4154,7 +4304,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_extract_epi16() { + const unsafe fn test_mm_extract_epi16() { let a = _mm_setr_epi16(-1, 1, 2, 3, 4, 5, 6, 7); let r1 = _mm_extract_epi16::<0>(a); let r2 = _mm_extract_epi16::<3>(a); @@ -4163,7 +4313,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_insert_epi16() { + const unsafe fn test_mm_insert_epi16() { let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm_insert_epi16::<0>(a, 9); let e = _mm_setr_epi16(9, 1, 2, 3, 4, 5, 6, 7); @@ -4171,7 +4321,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_movemask_epi8() { + const unsafe fn test_mm_movemask_epi8() { #[rustfmt::skip] let a = _mm_setr_epi8( 0b1000_0000u8 as i8, 0b0, 0b1000_0000u8 as i8, 0b01, @@ -4184,7 +4334,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_shuffle_epi32() { + const unsafe fn test_mm_shuffle_epi32() { let a = _mm_setr_epi32(5, 10, 15, 20); let r = _mm_shuffle_epi32::<0b00_01_01_11>(a); let e = _mm_setr_epi32(20, 10, 10, 5); @@ -4192,7 +4342,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_shufflehi_epi16() { + const unsafe fn test_mm_shufflehi_epi16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 10, 15, 20); let r = _mm_shufflehi_epi16::<0b00_01_01_11>(a); let e = _mm_setr_epi16(1, 2, 3, 4, 20, 10, 10, 5); @@ -4200,7 +4350,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_shufflelo_epi16() { + const unsafe fn test_mm_shufflelo_epi16() { let a = _mm_setr_epi16(5, 10, 15, 20, 1, 2, 3, 4); let r = _mm_shufflelo_epi16::<0b00_01_01_11>(a); let e = _mm_setr_epi16(20, 10, 10, 5, 1, 2, 3, 4); @@ -4208,7 +4358,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpackhi_epi8() { + const unsafe fn test_mm_unpackhi_epi8() { #[rustfmt::skip] let a = _mm_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4227,7 +4377,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpackhi_epi16() { + const unsafe fn test_mm_unpackhi_epi16() { let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_unpackhi_epi16(a, b); @@ -4236,7 +4386,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpackhi_epi32() { + const unsafe fn test_mm_unpackhi_epi32() { let a = _mm_setr_epi32(0, 1, 2, 3); let b = _mm_setr_epi32(4, 5, 6, 7); let r = _mm_unpackhi_epi32(a, b); @@ -4245,7 +4395,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpackhi_epi64() { + const unsafe fn test_mm_unpackhi_epi64() { let a = _mm_setr_epi64x(0, 1); let b = _mm_setr_epi64x(2, 3); let r = _mm_unpackhi_epi64(a, b); @@ -4254,7 +4404,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpacklo_epi8() { + const unsafe fn test_mm_unpacklo_epi8() { #[rustfmt::skip] let a = _mm_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4274,7 +4424,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpacklo_epi16() { + const unsafe fn test_mm_unpacklo_epi16() { let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_unpacklo_epi16(a, b); @@ -4283,7 +4433,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpacklo_epi32() { + const unsafe fn test_mm_unpacklo_epi32() { let a = _mm_setr_epi32(0, 1, 2, 3); let b = _mm_setr_epi32(4, 5, 6, 7); let r = _mm_unpacklo_epi32(a, b); @@ -4292,7 +4442,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpacklo_epi64() { + const unsafe fn test_mm_unpacklo_epi64() { let a = _mm_setr_epi64x(0, 1); let b = _mm_setr_epi64x(2, 3); let r = _mm_unpacklo_epi64(a, b); @@ -4301,7 +4451,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_add_sd() { + const unsafe fn test_mm_add_sd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(5.0, 10.0); let r = _mm_add_sd(a, b); @@ -4309,7 +4459,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_add_pd() { + const unsafe fn test_mm_add_pd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(5.0, 10.0); let r = _mm_add_pd(a, b); @@ -4317,7 +4467,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_div_sd() { + const unsafe fn test_mm_div_sd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(5.0, 10.0); let r = _mm_div_sd(a, b); @@ -4325,7 +4475,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_div_pd() { + const unsafe fn test_mm_div_pd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(5.0, 10.0); let r = _mm_div_pd(a, b); @@ -4387,7 +4537,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_mul_sd() { + const unsafe fn test_mm_mul_sd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(5.0, 10.0); let r = _mm_mul_sd(a, b); @@ -4395,7 +4545,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_mul_pd() { + const unsafe fn test_mm_mul_pd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(5.0, 10.0); let r = _mm_mul_pd(a, b); @@ -4417,7 +4567,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_sub_sd() { + const unsafe fn test_mm_sub_sd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(5.0, 10.0); let r = _mm_sub_sd(a, b); @@ -4425,7 +4575,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_sub_pd() { + const unsafe fn test_mm_sub_pd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(5.0, 10.0); let r = _mm_sub_pd(a, b); @@ -4433,7 +4583,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_and_pd() { + const unsafe fn test_mm_and_pd() { let a = transmute(u64x2::splat(5)); let b = transmute(u64x2::splat(3)); let r = _mm_and_pd(a, b); @@ -4442,7 +4592,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_andnot_pd() { + const unsafe fn test_mm_andnot_pd() { let a = transmute(u64x2::splat(5)); let b = transmute(u64x2::splat(3)); let r = _mm_andnot_pd(a, b); @@ -4451,7 +4601,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_or_pd() { + const unsafe fn test_mm_or_pd() { let a = transmute(u64x2::splat(5)); let b = transmute(u64x2::splat(3)); let r = _mm_or_pd(a, b); @@ -4460,7 +4610,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_xor_pd() { + const unsafe fn test_mm_xor_pd() { let a = transmute(u64x2::splat(5)); let b = transmute(u64x2::splat(3)); let r = _mm_xor_pd(a, b); @@ -4739,7 +4889,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_movemask_pd() { + const unsafe fn test_mm_movemask_pd() { let r = _mm_movemask_pd(_mm_setr_pd(-1.0, 5.0)); assert_eq!(r, 0b01); @@ -4753,7 +4903,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_load_pd() { + const unsafe fn test_mm_load_pd() { let mem = Memory { data: [1.0f64, 2.0, 3.0, 4.0], }; @@ -4765,7 +4915,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_load_sd() { + const unsafe fn test_mm_load_sd() { let a = 1.; let expected = _mm_setr_pd(a, 0.); let r = _mm_load_sd(&a); @@ -4773,7 +4923,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_loadh_pd() { + const unsafe fn test_mm_loadh_pd() { let a = _mm_setr_pd(1., 2.); let b = 3.; let expected = _mm_setr_pd(_mm_cvtsd_f64(a), 3.); @@ -4782,7 +4932,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_loadl_pd() { + const unsafe fn test_mm_loadl_pd() { let a = _mm_setr_pd(1., 2.); let b = 3.; let expected = _mm_setr_pd(3., get_m128d(a, 1)); @@ -4810,7 +4960,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_store_sd() { + const unsafe fn test_mm_store_sd() { let mut dest = 0.; let a = _mm_setr_pd(1., 2.); _mm_store_sd(&mut dest, a); @@ -4818,7 +4968,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_store_pd() { + const unsafe fn test_mm_store_pd() { let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); @@ -4830,31 +4980,21 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_storeu_pd() { + const unsafe fn test_mm_storeu_pd() { + // guaranteed to be aligned to 16 bytes let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); - let mut ofs = 0; - let mut p = vals.as_mut_ptr(); - - // Make sure p is **not** aligned to 16-byte boundary - if (p as usize) & 0xf == 0 { - ofs = 1; - p = p.add(1); - } - + // so p is *not* aligned to 16 bytes + let p = vals.as_mut_ptr().offset(1); _mm_storeu_pd(p, *black_box(&a)); - if ofs > 0 { - assert_eq!(vals[ofs - 1], 0.0); - } - assert_eq!(vals[ofs + 0], 1.0); - assert_eq!(vals[ofs + 1], 2.0); + assert_eq!(*vals, [0.0, 1.0, 2.0, 0.0]); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_storeu_si16() { + const unsafe fn test_mm_storeu_si16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let mut r = _mm_setr_epi16(9, 10, 11, 12, 13, 14, 15, 16); _mm_storeu_si16(ptr::addr_of_mut!(r).cast(), a); @@ -4863,7 +5003,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_storeu_si32() { + const unsafe fn test_mm_storeu_si32() { let a = _mm_setr_epi32(1, 2, 3, 4); let mut r = _mm_setr_epi32(5, 6, 7, 8); _mm_storeu_si32(ptr::addr_of_mut!(r).cast(), a); @@ -4872,7 +5012,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_storeu_si64() { + const unsafe fn test_mm_storeu_si64() { let a = _mm_setr_epi64x(1, 2); let mut r = _mm_setr_epi64x(3, 4); _mm_storeu_si64(ptr::addr_of_mut!(r).cast(), a); @@ -4881,7 +5021,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_store1_pd() { + const unsafe fn test_mm_store1_pd() { let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); @@ -4893,7 +5033,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_store_pd1() { + const unsafe fn test_mm_store_pd1() { let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); @@ -4905,7 +5045,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_storer_pd() { + const unsafe fn test_mm_storer_pd() { let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); @@ -4917,7 +5057,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_storeh_pd() { + const unsafe fn test_mm_storeh_pd() { let mut dest = 0.; let a = _mm_setr_pd(1., 2.); _mm_storeh_pd(&mut dest, a); @@ -4925,7 +5065,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_storel_pd() { + const unsafe fn test_mm_storel_pd() { let mut dest = 0.; let a = _mm_setr_pd(1., 2.); _mm_storel_pd(&mut dest, a); @@ -4933,7 +5073,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_loadr_pd() { + const unsafe fn test_mm_loadr_pd() { let mut mem = Memory { data: [1.0f64, 2.0, 3.0, 4.0], }; @@ -4945,48 +5085,44 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_loadu_pd() { + const unsafe fn test_mm_loadu_pd() { + // guaranteed to be aligned to 16 bytes let mut mem = Memory { data: [1.0f64, 2.0, 3.0, 4.0], }; let vals = &mut mem.data; - let mut d = vals.as_ptr(); - // make sure d is not aligned to 16-byte boundary - let mut offset = 0; - if (d as usize) & 0xf == 0 { - offset = 1; - d = d.add(offset); - } + // so this will *not* be aligned to 16 bytes + let d = vals.as_ptr().offset(1); let r = _mm_loadu_pd(d); - let e = _mm_add_pd(_mm_setr_pd(1.0, 2.0), _mm_set1_pd(offset as f64)); + let e = _mm_setr_pd(2.0, 3.0); assert_eq_m128d(r, e); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_loadu_si16() { + const unsafe fn test_mm_loadu_si16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm_loadu_si16(ptr::addr_of!(a) as *const _); assert_eq_m128i(r, _mm_setr_epi16(1, 0, 0, 0, 0, 0, 0, 0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_loadu_si32() { + const unsafe fn test_mm_loadu_si32() { let a = _mm_setr_epi32(1, 2, 3, 4); let r = _mm_loadu_si32(ptr::addr_of!(a) as *const _); assert_eq_m128i(r, _mm_setr_epi32(1, 0, 0, 0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_loadu_si64() { + const unsafe fn test_mm_loadu_si64() { let a = _mm_setr_epi64x(5, 6); let r = _mm_loadu_si64(ptr::addr_of!(a) as *const _); assert_eq_m128i(r, _mm_setr_epi64x(5, 0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtpd_ps() { + const unsafe fn test_mm_cvtpd_ps() { let r = _mm_cvtpd_ps(_mm_setr_pd(-1.0, 5.0)); assert_eq_m128(r, _mm_setr_ps(-1.0, 5.0, 0.0, 0.0)); @@ -5001,7 +5137,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtps_pd() { + const unsafe fn test_mm_cvtps_pd() { let r = _mm_cvtps_pd(_mm_setr_ps(-1.0, 2.0, -3.0, 5.0)); assert_eq_m128d(r, _mm_setr_pd(-1.0, 2.0)); @@ -5070,13 +5206,13 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtsd_f64() { + const unsafe fn test_mm_cvtsd_f64() { let r = _mm_cvtsd_f64(_mm_setr_pd(-1.1, 2.2)); assert_eq!(r, -1.1); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtss_sd() { + const unsafe fn test_mm_cvtss_sd() { let a = _mm_setr_pd(-1.1, 2.2); let b = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); @@ -5124,57 +5260,57 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set_sd() { + const unsafe fn test_mm_set_sd() { let r = _mm_set_sd(-1.0_f64); assert_eq_m128d(r, _mm_setr_pd(-1.0_f64, 0_f64)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set1_pd() { + const unsafe fn test_mm_set1_pd() { let r = _mm_set1_pd(-1.0_f64); assert_eq_m128d(r, _mm_setr_pd(-1.0_f64, -1.0_f64)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set_pd1() { + const unsafe fn test_mm_set_pd1() { let r = _mm_set_pd1(-2.0_f64); assert_eq_m128d(r, _mm_setr_pd(-2.0_f64, -2.0_f64)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_set_pd() { + const unsafe fn test_mm_set_pd() { let r = _mm_set_pd(1.0_f64, 5.0_f64); assert_eq_m128d(r, _mm_setr_pd(5.0_f64, 1.0_f64)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_setr_pd() { + const unsafe fn test_mm_setr_pd() { let r = _mm_setr_pd(1.0_f64, -5.0_f64); assert_eq_m128d(r, _mm_setr_pd(1.0_f64, -5.0_f64)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_setzero_pd() { + const unsafe fn test_mm_setzero_pd() { let r = _mm_setzero_pd(); assert_eq_m128d(r, _mm_setr_pd(0_f64, 0_f64)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_load1_pd() { + const unsafe fn test_mm_load1_pd() { let d = -5.0; let r = _mm_load1_pd(&d); assert_eq_m128d(r, _mm_setr_pd(d, d)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_load_pd1() { + const unsafe fn test_mm_load_pd1() { let d = -5.0; let r = _mm_load_pd1(&d); assert_eq_m128d(r, _mm_setr_pd(d, d)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpackhi_pd() { + const unsafe fn test_mm_unpackhi_pd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(3.0, 4.0); let r = _mm_unpackhi_pd(a, b); @@ -5182,7 +5318,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_unpacklo_pd() { + const unsafe fn test_mm_unpacklo_pd() { let a = _mm_setr_pd(1.0, 2.0); let b = _mm_setr_pd(3.0, 4.0); let r = _mm_unpacklo_pd(a, b); @@ -5190,7 +5326,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_shuffle_pd() { + const unsafe fn test_mm_shuffle_pd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(3., 4.); let expected = _mm_setr_pd(1., 3.); @@ -5199,7 +5335,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_move_sd() { + const unsafe fn test_mm_move_sd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(3., 4.); let expected = _mm_setr_pd(3., 2.); @@ -5208,7 +5344,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_castpd_ps() { + const unsafe fn test_mm_castpd_ps() { let a = _mm_set1_pd(0.); let expected = _mm_set1_ps(0.); let r = _mm_castpd_ps(a); @@ -5216,7 +5352,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_castpd_si128() { + const unsafe fn test_mm_castpd_si128() { let a = _mm_set1_pd(0.); let expected = _mm_set1_epi64x(0); let r = _mm_castpd_si128(a); @@ -5224,7 +5360,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_castps_pd() { + const unsafe fn test_mm_castps_pd() { let a = _mm_set1_ps(0.); let expected = _mm_set1_pd(0.); let r = _mm_castps_pd(a); @@ -5232,7 +5368,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_castps_si128() { + const unsafe fn test_mm_castps_si128() { let a = _mm_set1_ps(0.); let expected = _mm_set1_epi32(0); let r = _mm_castps_si128(a); @@ -5240,7 +5376,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_castsi128_pd() { + const unsafe fn test_mm_castsi128_pd() { let a = _mm_set1_epi64x(0); let expected = _mm_set1_pd(0.); let r = _mm_castsi128_pd(a); @@ -5248,7 +5384,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_castsi128_ps() { + const unsafe fn test_mm_castsi128_ps() { let a = _mm_set1_epi32(0); let expected = _mm_set1_ps(0.); let r = _mm_castsi128_ps(a); diff --git a/library/stdarch/crates/core_arch/src/x86_64/sse2.rs b/library/stdarch/crates/core_arch/src/x86_64/sse2.rs index 0894aa9810de..9f350f236840 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/sse2.rs @@ -95,7 +95,8 @@ pub unsafe fn _mm_stream_si64(mem_addr: *mut i64, a: i64) { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi64_si128(a: i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi64_si128(a: i64) -> __m128i { _mm_set_epi64x(0, a) } @@ -107,7 +108,8 @@ pub fn _mm_cvtsi64_si128(a: i64) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi64x_si128(a: i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi64x_si128(a: i64) -> __m128i { _mm_cvtsi64_si128(a) } @@ -118,7 +120,8 @@ pub fn _mm_cvtsi64x_si128(a: i64) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi128_si64(a: __m128i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi128_si64(a: __m128i) -> i64 { unsafe { simd_extract!(a.as_i64x2(), 0) } } @@ -129,7 +132,8 @@ pub fn _mm_cvtsi128_si64(a: __m128i) -> i64 { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(movq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi128_si64x(a: __m128i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi128_si64x(a: __m128i) -> i64 { _mm_cvtsi128_si64(a) } @@ -141,7 +145,8 @@ pub fn _mm_cvtsi128_si64x(a: __m128i) -> i64 { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(cvtsi2sd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi64_sd(a: __m128d, b: i64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi64_sd(a: __m128d, b: i64) -> __m128d { unsafe { simd_insert!(a, 0, b as f64) } } @@ -153,13 +158,15 @@ pub fn _mm_cvtsi64_sd(a: __m128d, b: i64) -> __m128d { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(cvtsi2sd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtsi64x_sd(a: __m128d, b: i64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi64x_sd(a: __m128d, b: i64) -> __m128d { _mm_cvtsi64_sd(a, b) } #[cfg(test)] mod tests { use crate::core_arch::arch::x86_64::*; + use crate::core_arch::assert_eq_const as assert_eq; use std::boxed; use std::ptr; use stdarch_test::simd_test; @@ -206,19 +213,19 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtsi64_si128() { + const unsafe fn test_mm_cvtsi64_si128() { let r = _mm_cvtsi64_si128(5); assert_eq_m128i(r, _mm_setr_epi64x(5, 0)); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtsi128_si64() { + const unsafe fn test_mm_cvtsi128_si64() { let r = _mm_cvtsi128_si64(_mm_setr_epi64x(5, 0)); assert_eq!(r, 5); } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtsi64_sd() { + const unsafe fn test_mm_cvtsi64_sd() { let a = _mm_set1_pd(3.5); let r = _mm_cvtsi64_sd(a, 5); assert_eq_m128d(r, _mm_setr_pd(5.0, 3.5)); From 7b71101c08d8c037b158e5e365a5401ff3fcfcdd Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:21:22 +0530 Subject: [PATCH 0227/3801] Make `sse3` functions const --- .../stdarch/crates/core_arch/src/x86/sse3.rs | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/sse3.rs b/library/stdarch/crates/core_arch/src/x86/sse3.rs index 79be7a7e9b2c..eebca864f43c 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse3.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse3.rs @@ -14,7 +14,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(addsubps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_addsub_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_addsub_ps(a: __m128, b: __m128) -> __m128 { unsafe { let a = a.as_f32x4(); let b = b.as_f32x4(); @@ -32,7 +33,8 @@ pub fn _mm_addsub_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(addsubpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_addsub_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_addsub_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { let a = a.as_f64x2(); let b = b.as_f64x2(); @@ -50,7 +52,8 @@ pub fn _mm_addsub_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(haddpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_hadd_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_hadd_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { let even = simd_shuffle!(a, b, [0, 2]); let odd = simd_shuffle!(a, b, [1, 3]); @@ -66,7 +69,8 @@ pub fn _mm_hadd_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(haddps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_hadd_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_hadd_ps(a: __m128, b: __m128) -> __m128 { unsafe { let even = simd_shuffle!(a, b, [0, 2, 4, 6]); let odd = simd_shuffle!(a, b, [1, 3, 5, 7]); @@ -82,7 +86,8 @@ pub fn _mm_hadd_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(hsubpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_hsub_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_hsub_pd(a: __m128d, b: __m128d) -> __m128d { unsafe { let even = simd_shuffle!(a, b, [0, 2]); let odd = simd_shuffle!(a, b, [1, 3]); @@ -98,7 +103,8 @@ pub fn _mm_hsub_pd(a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(hsubps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_hsub_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_hsub_ps(a: __m128, b: __m128) -> __m128 { unsafe { let even = simd_shuffle!(a, b, [0, 2, 4, 6]); let odd = simd_shuffle!(a, b, [1, 3, 5, 7]); @@ -127,7 +133,8 @@ pub unsafe fn _mm_lddqu_si128(mem_addr: *const __m128i) -> __m128i { #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(movddup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_movedup_pd(a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movedup_pd(a: __m128d) -> __m128d { unsafe { simd_shuffle!(a, a, [0, 0]) } } @@ -139,7 +146,8 @@ pub fn _mm_movedup_pd(a: __m128d) -> __m128d { #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(movddup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_loaddup_pd(mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loaddup_pd(mem_addr: *const f64) -> __m128d { _mm_load1_pd(mem_addr) } @@ -151,7 +159,8 @@ pub unsafe fn _mm_loaddup_pd(mem_addr: *const f64) -> __m128d { #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(movshdup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_movehdup_ps(a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movehdup_ps(a: __m128) -> __m128 { unsafe { simd_shuffle!(a, a, [1, 1, 3, 3]) } } @@ -163,7 +172,8 @@ pub fn _mm_movehdup_ps(a: __m128) -> __m128 { #[target_feature(enable = "sse3")] #[cfg_attr(test, assert_instr(movsldup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_moveldup_ps(a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_moveldup_ps(a: __m128) -> __m128 { unsafe { simd_shuffle!(a, a, [0, 0, 2, 2]) } } @@ -175,12 +185,13 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; #[simd_test(enable = "sse3")] - unsafe fn test_mm_addsub_ps() { + const unsafe fn test_mm_addsub_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_addsub_ps(a, b); @@ -188,7 +199,7 @@ mod tests { } #[simd_test(enable = "sse3")] - unsafe fn test_mm_addsub_pd() { + const unsafe fn test_mm_addsub_pd() { let a = _mm_setr_pd(-1.0, 5.0); let b = _mm_setr_pd(-100.0, 20.0); let r = _mm_addsub_pd(a, b); @@ -196,7 +207,7 @@ mod tests { } #[simd_test(enable = "sse3")] - unsafe fn test_mm_hadd_pd() { + const unsafe fn test_mm_hadd_pd() { let a = _mm_setr_pd(-1.0, 5.0); let b = _mm_setr_pd(-100.0, 20.0); let r = _mm_hadd_pd(a, b); @@ -204,7 +215,7 @@ mod tests { } #[simd_test(enable = "sse3")] - unsafe fn test_mm_hadd_ps() { + const unsafe fn test_mm_hadd_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_hadd_ps(a, b); @@ -212,7 +223,7 @@ mod tests { } #[simd_test(enable = "sse3")] - unsafe fn test_mm_hsub_pd() { + const unsafe fn test_mm_hsub_pd() { let a = _mm_setr_pd(-1.0, 5.0); let b = _mm_setr_pd(-100.0, 20.0); let r = _mm_hsub_pd(a, b); @@ -220,7 +231,7 @@ mod tests { } #[simd_test(enable = "sse3")] - unsafe fn test_mm_hsub_ps() { + const unsafe fn test_mm_hsub_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_hsub_ps(a, b); @@ -241,28 +252,28 @@ mod tests { } #[simd_test(enable = "sse3")] - unsafe fn test_mm_movedup_pd() { + const unsafe fn test_mm_movedup_pd() { let a = _mm_setr_pd(-1.0, 5.0); let r = _mm_movedup_pd(a); assert_eq_m128d(r, _mm_setr_pd(-1.0, -1.0)); } #[simd_test(enable = "sse3")] - unsafe fn test_mm_movehdup_ps() { + const unsafe fn test_mm_movehdup_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let r = _mm_movehdup_ps(a); assert_eq_m128(r, _mm_setr_ps(5.0, 5.0, -10.0, -10.0)); } #[simd_test(enable = "sse3")] - unsafe fn test_mm_moveldup_ps() { + const unsafe fn test_mm_moveldup_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let r = _mm_moveldup_ps(a); assert_eq_m128(r, _mm_setr_ps(-1.0, -1.0, 0.0, 0.0)); } #[simd_test(enable = "sse3")] - unsafe fn test_mm_loaddup_pd() { + const unsafe fn test_mm_loaddup_pd() { let d = -5.0; let r = _mm_loaddup_pd(&d); assert_eq_m128d(r, _mm_setr_pd(d, d)); From cfe6c04f732e0175af232b3751afcaa9254404fa Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:21:33 +0530 Subject: [PATCH 0228/3801] Make `ssse3` functions const --- .../stdarch/crates/core_arch/src/x86/ssse3.rs | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/ssse3.rs b/library/stdarch/crates/core_arch/src/x86/ssse3.rs index ac067bd4b5a7..c44da6eb97e4 100644 --- a/library/stdarch/crates/core_arch/src/x86/ssse3.rs +++ b/library/stdarch/crates/core_arch/src/x86/ssse3.rs @@ -16,7 +16,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "ssse3")] #[cfg_attr(test, assert_instr(pabsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_abs_epi8(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_abs_epi8(a: __m128i) -> __m128i { unsafe { let a = a.as_i8x16(); let zero = i8x16::ZERO; @@ -34,7 +35,8 @@ pub fn _mm_abs_epi8(a: __m128i) -> __m128i { #[target_feature(enable = "ssse3")] #[cfg_attr(test, assert_instr(pabsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_abs_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_abs_epi16(a: __m128i) -> __m128i { unsafe { let a = a.as_i16x8(); let zero = i16x8::ZERO; @@ -52,7 +54,8 @@ pub fn _mm_abs_epi16(a: __m128i) -> __m128i { #[target_feature(enable = "ssse3")] #[cfg_attr(test, assert_instr(pabsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_abs_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_abs_epi32(a: __m128i) -> __m128i { unsafe { let a = a.as_i32x4(); let zero = i32x4::ZERO; @@ -104,7 +107,8 @@ pub fn _mm_shuffle_epi8(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(palignr, IMM8 = 15))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_alignr_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_alignr_epi8(a: __m128i, b: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); // If palignr is shifting the pair of vectors more than the size of two // lanes, emit zero. @@ -163,7 +167,8 @@ pub fn _mm_alignr_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "ssse3")] #[cfg_attr(test, assert_instr(phaddw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_hadd_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_hadd_epi16(a: __m128i, b: __m128i) -> __m128i { let a = a.as_i16x8(); let b = b.as_i16x8(); unsafe { @@ -194,7 +199,8 @@ pub fn _mm_hadds_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "ssse3")] #[cfg_attr(test, assert_instr(phaddd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_hadd_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_hadd_epi32(a: __m128i, b: __m128i) -> __m128i { let a = a.as_i32x4(); let b = b.as_i32x4(); unsafe { @@ -212,7 +218,8 @@ pub fn _mm_hadd_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "ssse3")] #[cfg_attr(test, assert_instr(phsubw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_hsub_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_hsub_epi16(a: __m128i, b: __m128i) -> __m128i { let a = a.as_i16x8(); let b = b.as_i16x8(); unsafe { @@ -244,7 +251,8 @@ pub fn _mm_hsubs_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "ssse3")] #[cfg_attr(test, assert_instr(phsubd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_hsub_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_hsub_epi32(a: __m128i, b: __m128i) -> __m128i { let a = a.as_i32x4(); let b = b.as_i32x4(); unsafe { @@ -353,24 +361,25 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; #[simd_test(enable = "ssse3")] - unsafe fn test_mm_abs_epi8() { + const unsafe fn test_mm_abs_epi8() { let r = _mm_abs_epi8(_mm_set1_epi8(-5)); assert_eq_m128i(r, _mm_set1_epi8(5)); } #[simd_test(enable = "ssse3")] - unsafe fn test_mm_abs_epi16() { + const unsafe fn test_mm_abs_epi16() { let r = _mm_abs_epi16(_mm_set1_epi16(-5)); assert_eq_m128i(r, _mm_set1_epi16(5)); } #[simd_test(enable = "ssse3")] - unsafe fn test_mm_abs_epi32() { + const unsafe fn test_mm_abs_epi32() { let r = _mm_abs_epi32(_mm_set1_epi32(-5)); assert_eq_m128i(r, _mm_set1_epi32(5)); } @@ -400,7 +409,7 @@ mod tests { } #[simd_test(enable = "ssse3")] - unsafe fn test_mm_alignr_epi8() { + const unsafe fn test_mm_alignr_epi8() { #[rustfmt::skip] let a = _mm_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -440,7 +449,7 @@ mod tests { } #[simd_test(enable = "ssse3")] - unsafe fn test_mm_hadd_epi16() { + const unsafe fn test_mm_hadd_epi16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_setr_epi16(4, 128, 4, 3, 24, 12, 6, 19); let expected = _mm_setr_epi16(3, 7, 11, 15, 132, 7, 36, 25); @@ -490,7 +499,7 @@ mod tests { } #[simd_test(enable = "ssse3")] - unsafe fn test_mm_hadd_epi32() { + const unsafe fn test_mm_hadd_epi32() { let a = _mm_setr_epi32(1, 2, 3, 4); let b = _mm_setr_epi32(4, 128, 4, 3); let expected = _mm_setr_epi32(3, 7, 132, 7); @@ -506,7 +515,7 @@ mod tests { } #[simd_test(enable = "ssse3")] - unsafe fn test_mm_hsub_epi16() { + const unsafe fn test_mm_hsub_epi16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_setr_epi16(4, 128, 4, 3, 24, 12, 6, 19); let expected = _mm_setr_epi16(-1, -1, -1, -1, -124, 1, 12, -13); @@ -556,7 +565,7 @@ mod tests { } #[simd_test(enable = "ssse3")] - unsafe fn test_mm_hsub_epi32() { + const unsafe fn test_mm_hsub_epi32() { let a = _mm_setr_epi32(1, 2, 3, 4); let b = _mm_setr_epi32(4, 128, 4, 3); let expected = _mm_setr_epi32(-1, -1, -124, 1); From d8a0ca2e463654c6d7cb6f79fe3b490824fe16e5 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:21:41 +0530 Subject: [PATCH 0229/3801] Make `sse4.1` functions const --- .../stdarch/crates/core_arch/src/x86/sse41.rs | 211 +++++++++++------- .../crates/core_arch/src/x86_64/sse41.rs | 11 +- 2 files changed, 134 insertions(+), 88 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/sse41.rs b/library/stdarch/crates/core_arch/src/x86/sse41.rs index 6c16ee760065..a83f8cc747a8 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse41.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse41.rs @@ -59,7 +59,8 @@ pub const _MM_FROUND_NEARBYINT: i32 = _MM_FROUND_NO_EXC | _MM_FROUND_CUR_DIRECTI #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pblendvb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_blendv_epi8(a: __m128i, b: __m128i, mask: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_blendv_epi8(a: __m128i, b: __m128i, mask: __m128i) -> __m128i { unsafe { let mask: i8x16 = simd_lt(mask.as_i8x16(), i8x16::ZERO); transmute(simd_select(mask, b.as_i8x16(), a.as_i8x16())) @@ -78,7 +79,8 @@ pub fn _mm_blendv_epi8(a: __m128i, b: __m128i, mask: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pblendw, IMM8 = 0xB1))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_blend_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_blend_epi16(a: __m128i, b: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); unsafe { transmute::(simd_shuffle!( @@ -106,7 +108,8 @@ pub fn _mm_blend_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(blendvpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_blendv_pd(a: __m128d, b: __m128d, mask: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_blendv_pd(a: __m128d, b: __m128d, mask: __m128d) -> __m128d { unsafe { let mask: i64x2 = simd_lt(transmute::<_, i64x2>(mask), i64x2::ZERO); transmute(simd_select(mask, b.as_f64x2(), a.as_f64x2())) @@ -121,7 +124,8 @@ pub fn _mm_blendv_pd(a: __m128d, b: __m128d, mask: __m128d) -> __m128d { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(blendvps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_blendv_ps(a: __m128, b: __m128, mask: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_blendv_ps(a: __m128, b: __m128, mask: __m128) -> __m128 { unsafe { let mask: i32x4 = simd_lt(transmute::<_, i32x4>(mask), i32x4::ZERO); transmute(simd_select(mask, b.as_f32x4(), a.as_f32x4())) @@ -140,7 +144,8 @@ pub fn _mm_blendv_ps(a: __m128, b: __m128, mask: __m128) -> __m128 { #[cfg_attr(test, assert_instr(blendps, IMM2 = 0b10))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_blend_pd(a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_blend_pd(a: __m128d, b: __m128d) -> __m128d { static_assert_uimm_bits!(IMM2, 2); unsafe { transmute::(simd_shuffle!( @@ -160,7 +165,8 @@ pub fn _mm_blend_pd(a: __m128d, b: __m128d) -> __m128d { #[cfg_attr(test, assert_instr(blendps, IMM4 = 0b0101))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_blend_ps(a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_blend_ps(a: __m128, b: __m128) -> __m128 { static_assert_uimm_bits!(IMM4, 4); unsafe { transmute::(simd_shuffle!( @@ -207,7 +213,8 @@ pub fn _mm_blend_ps(a: __m128, b: __m128) -> __m128 { #[cfg_attr(test, assert_instr(extractps, IMM8 = 0))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_extract_ps(a: __m128) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_extract_ps(a: __m128) -> i32 { static_assert_uimm_bits!(IMM8, 2); unsafe { simd_extract!(a, IMM8 as u32, f32).to_bits() as i32 } } @@ -223,7 +230,8 @@ pub fn _mm_extract_ps(a: __m128) -> i32 { #[cfg_attr(test, assert_instr(pextrb, IMM8 = 0))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_extract_epi8(a: __m128i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_extract_epi8(a: __m128i) -> i32 { static_assert_uimm_bits!(IMM8, 4); unsafe { simd_extract!(a.as_u8x16(), IMM8 as u32, u8) as i32 } } @@ -236,7 +244,8 @@ pub fn _mm_extract_epi8(a: __m128i) -> i32 { #[cfg_attr(test, assert_instr(extractps, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_extract_epi32(a: __m128i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_extract_epi32(a: __m128i) -> i32 { static_assert_uimm_bits!(IMM8, 2); unsafe { simd_extract!(a.as_i32x4(), IMM8 as u32, i32) } } @@ -284,7 +293,8 @@ pub fn _mm_insert_ps(a: __m128, b: __m128) -> __m128 { #[cfg_attr(test, assert_instr(pinsrb, IMM8 = 0))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_insert_epi8(a: __m128i, i: i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_insert_epi8(a: __m128i, i: i32) -> __m128i { static_assert_uimm_bits!(IMM8, 4); unsafe { transmute(simd_insert!(a.as_i8x16(), IMM8 as u32, i as i8)) } } @@ -298,7 +308,8 @@ pub fn _mm_insert_epi8(a: __m128i, i: i32) -> __m128i { #[cfg_attr(test, assert_instr(pinsrd, IMM8 = 0))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_insert_epi32(a: __m128i, i: i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_insert_epi32(a: __m128i, i: i32) -> __m128i { static_assert_uimm_bits!(IMM8, 2); unsafe { transmute(simd_insert!(a.as_i32x4(), IMM8 as u32, i)) } } @@ -311,7 +322,8 @@ pub fn _mm_insert_epi32(a: __m128i, i: i32) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmaxsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_max_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_max_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imax(a.as_i8x16(), b.as_i8x16()).as_m128i() } } @@ -323,7 +335,8 @@ pub fn _mm_max_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmaxuw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_max_epu16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_max_epu16(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imax(a.as_u16x8(), b.as_u16x8()).as_m128i() } } @@ -335,7 +348,8 @@ pub fn _mm_max_epu16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmaxsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_max_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_max_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imax(a.as_i32x4(), b.as_i32x4()).as_m128i() } } @@ -347,7 +361,8 @@ pub fn _mm_max_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmaxud))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_max_epu32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_max_epu32(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imax(a.as_u32x4(), b.as_u32x4()).as_m128i() } } @@ -359,7 +374,8 @@ pub fn _mm_max_epu32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pminsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_min_epi8(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_min_epi8(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_i8x16(), b.as_i8x16()).as_m128i() } } @@ -371,7 +387,8 @@ pub fn _mm_min_epi8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pminuw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_min_epu16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_min_epu16(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_u16x8(), b.as_u16x8()).as_m128i() } } @@ -383,7 +400,8 @@ pub fn _mm_min_epu16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pminsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_min_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_min_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_i32x4(), b.as_i32x4()).as_m128i() } } @@ -395,7 +413,8 @@ pub fn _mm_min_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pminud))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_min_epu32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_min_epu32(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_u32x4(), b.as_u32x4()).as_m128i() } } @@ -418,7 +437,8 @@ pub fn _mm_packus_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pcmpeqq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmpeq_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_eq::<_, i64x2>(a.as_i64x2(), b.as_i64x2())) } } @@ -429,7 +449,8 @@ pub fn _mm_cmpeq_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovsxbw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepi8_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepi8_epi16(a: __m128i) -> __m128i { unsafe { let a = a.as_i8x16(); let a: i8x8 = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -444,7 +465,8 @@ pub fn _mm_cvtepi8_epi16(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovsxbd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepi8_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepi8_epi32(a: __m128i) -> __m128i { unsafe { let a = a.as_i8x16(); let a: i8x4 = simd_shuffle!(a, a, [0, 1, 2, 3]); @@ -460,7 +482,8 @@ pub fn _mm_cvtepi8_epi32(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovsxbq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepi8_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepi8_epi64(a: __m128i) -> __m128i { unsafe { let a = a.as_i8x16(); let a: i8x2 = simd_shuffle!(a, a, [0, 1]); @@ -475,7 +498,8 @@ pub fn _mm_cvtepi8_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovsxwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepi16_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepi16_epi32(a: __m128i) -> __m128i { unsafe { let a = a.as_i16x8(); let a: i16x4 = simd_shuffle!(a, a, [0, 1, 2, 3]); @@ -490,7 +514,8 @@ pub fn _mm_cvtepi16_epi32(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovsxwq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepi16_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepi16_epi64(a: __m128i) -> __m128i { unsafe { let a = a.as_i16x8(); let a: i16x2 = simd_shuffle!(a, a, [0, 1]); @@ -505,7 +530,8 @@ pub fn _mm_cvtepi16_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovsxdq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepi32_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepi32_epi64(a: __m128i) -> __m128i { unsafe { let a = a.as_i32x4(); let a: i32x2 = simd_shuffle!(a, a, [0, 1]); @@ -520,7 +546,8 @@ pub fn _mm_cvtepi32_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovzxbw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepu8_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepu8_epi16(a: __m128i) -> __m128i { unsafe { let a = a.as_u8x16(); let a: u8x8 = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -535,7 +562,8 @@ pub fn _mm_cvtepu8_epi16(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovzxbd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepu8_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepu8_epi32(a: __m128i) -> __m128i { unsafe { let a = a.as_u8x16(); let a: u8x4 = simd_shuffle!(a, a, [0, 1, 2, 3]); @@ -550,7 +578,8 @@ pub fn _mm_cvtepu8_epi32(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovzxbq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepu8_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepu8_epi64(a: __m128i) -> __m128i { unsafe { let a = a.as_u8x16(); let a: u8x2 = simd_shuffle!(a, a, [0, 1]); @@ -566,7 +595,8 @@ pub fn _mm_cvtepu8_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovzxwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepu16_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepu16_epi32(a: __m128i) -> __m128i { unsafe { let a = a.as_u16x8(); let a: u16x4 = simd_shuffle!(a, a, [0, 1, 2, 3]); @@ -582,7 +612,8 @@ pub fn _mm_cvtepu16_epi32(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovzxwq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepu16_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepu16_epi64(a: __m128i) -> __m128i { unsafe { let a = a.as_u16x8(); let a: u16x2 = simd_shuffle!(a, a, [0, 1]); @@ -598,7 +629,8 @@ pub fn _mm_cvtepu16_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmovzxdq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cvtepu32_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepu32_epi64(a: __m128i) -> __m128i { unsafe { let a = a.as_u32x4(); let a: u32x2 = simd_shuffle!(a, a, [0, 1]); @@ -655,7 +687,8 @@ pub fn _mm_dp_ps(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(roundpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_floor_pd(a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_floor_pd(a: __m128d) -> __m128d { unsafe { simd_floor(a) } } @@ -668,7 +701,8 @@ pub fn _mm_floor_pd(a: __m128d) -> __m128d { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(roundps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_floor_ps(a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_floor_ps(a: __m128) -> __m128 { unsafe { simd_floor(a) } } @@ -711,7 +745,8 @@ pub fn _mm_floor_ss(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(roundpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_ceil_pd(a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_ceil_pd(a: __m128d) -> __m128d { unsafe { simd_ceil(a) } } @@ -724,7 +759,8 @@ pub fn _mm_ceil_pd(a: __m128d) -> __m128d { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(roundps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_ceil_ps(a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_ceil_ps(a: __m128) -> __m128 { unsafe { simd_ceil(a) } } @@ -887,7 +923,8 @@ pub fn _mm_minpos_epu16(a: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmuldq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mul_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mul_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { let a = simd_cast::<_, i64x2>(simd_cast::<_, i32x2>(a.as_i64x2())); let b = simd_cast::<_, i64x2>(simd_cast::<_, i32x2>(b.as_i64x2())); @@ -907,7 +944,8 @@ pub fn _mm_mul_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(pmulld))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_mullo_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mullo_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_mul(a.as_i32x4(), b.as_i32x4())) } } @@ -973,7 +1011,8 @@ pub fn _mm_mpsadbw_epu8(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(ptest))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_testz_si128(a: __m128i, mask: __m128i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testz_si128(a: __m128i, mask: __m128i) -> i32 { unsafe { let r = simd_reduce_or(simd_and(a.as_i64x2(), mask.as_i64x2())); (0i64 == r) as i32 @@ -999,7 +1038,8 @@ pub fn _mm_testz_si128(a: __m128i, mask: __m128i) -> i32 { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(ptest))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_testc_si128(a: __m128i, mask: __m128i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testc_si128(a: __m128i, mask: __m128i) -> i32 { unsafe { let r = simd_reduce_or(simd_and( simd_xor(a.as_i64x2(), i64x2::splat(!0)), @@ -1051,7 +1091,8 @@ pub fn _mm_testnzc_si128(a: __m128i, mask: __m128i) -> i32 { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(ptest))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_test_all_zeros(a: __m128i, mask: __m128i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_test_all_zeros(a: __m128i, mask: __m128i) -> i32 { _mm_testz_si128(a, mask) } @@ -1073,7 +1114,8 @@ pub fn _mm_test_all_zeros(a: __m128i, mask: __m128i) -> i32 { #[cfg_attr(test, assert_instr(pcmpeqd))] #[cfg_attr(test, assert_instr(ptest))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_test_all_ones(a: __m128i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_test_all_ones(a: __m128i) -> i32 { _mm_testc_si128(a, _mm_cmpeq_epi32(a, a)) } @@ -1148,12 +1190,13 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use crate::core_arch::x86::*; use std::mem; use stdarch_test::simd_test; #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_blendv_epi8() { + const unsafe fn test_mm_blendv_epi8() { #[rustfmt::skip] let a = _mm_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -1176,7 +1219,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_blendv_pd() { + const unsafe fn test_mm_blendv_pd() { let a = _mm_set1_pd(0.0); let b = _mm_set1_pd(1.0); let mask = transmute(_mm_setr_epi64x(0, -1)); @@ -1186,7 +1229,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_blendv_ps() { + const unsafe fn test_mm_blendv_ps() { let a = _mm_set1_ps(0.0); let b = _mm_set1_ps(1.0); let mask = transmute(_mm_setr_epi32(0, -1, 0, -1)); @@ -1196,7 +1239,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_blend_pd() { + const unsafe fn test_mm_blend_pd() { let a = _mm_set1_pd(0.0); let b = _mm_set1_pd(1.0); let r = _mm_blend_pd::<0b10>(a, b); @@ -1205,7 +1248,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_blend_ps() { + const unsafe fn test_mm_blend_ps() { let a = _mm_set1_ps(0.0); let b = _mm_set1_ps(1.0); let r = _mm_blend_ps::<0b1010>(a, b); @@ -1214,7 +1257,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_blend_epi16() { + const unsafe fn test_mm_blend_epi16() { let a = _mm_set1_epi16(0); let b = _mm_set1_epi16(1); let r = _mm_blend_epi16::<0b1010_1100>(a, b); @@ -1223,7 +1266,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_extract_ps() { + const unsafe fn test_mm_extract_ps() { let a = _mm_setr_ps(0.0, 1.0, 2.0, 3.0); let r: f32 = f32::from_bits(_mm_extract_ps::<1>(a) as u32); assert_eq!(r, 1.0); @@ -1232,7 +1275,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_extract_epi8() { + const unsafe fn test_mm_extract_epi8() { #[rustfmt::skip] let a = _mm_setr_epi8( -1, 1, 2, 3, 4, 5, 6, 7, @@ -1245,7 +1288,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_extract_epi32() { + const unsafe fn test_mm_extract_epi32() { let a = _mm_setr_epi32(0, 1, 2, 3); let r = _mm_extract_epi32::<1>(a); assert_eq!(r, 1); @@ -1270,7 +1313,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_insert_epi8() { + const unsafe fn test_mm_insert_epi8() { let a = _mm_set1_epi8(0); let e = _mm_setr_epi8(0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); let r = _mm_insert_epi8::<1>(a, 32); @@ -1281,7 +1324,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_insert_epi32() { + const unsafe fn test_mm_insert_epi32() { let a = _mm_set1_epi32(0); let e = _mm_setr_epi32(0, 32, 0, 0); let r = _mm_insert_epi32::<1>(a, 32); @@ -1292,7 +1335,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_max_epi8() { + const unsafe fn test_mm_max_epi8() { #[rustfmt::skip] let a = _mm_setr_epi8( 1, 4, 5, 8, 9, 12, 13, 16, @@ -1313,7 +1356,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_max_epu16() { + const unsafe fn test_mm_max_epu16() { let a = _mm_setr_epi16(1, 4, 5, 8, 9, 12, 13, 16); let b = _mm_setr_epi16(2, 3, 6, 7, 10, 11, 14, 15); let r = _mm_max_epu16(a, b); @@ -1322,7 +1365,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_max_epi32() { + const unsafe fn test_mm_max_epi32() { let a = _mm_setr_epi32(1, 4, 5, 8); let b = _mm_setr_epi32(2, 3, 6, 7); let r = _mm_max_epi32(a, b); @@ -1331,7 +1374,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_max_epu32() { + const unsafe fn test_mm_max_epu32() { let a = _mm_setr_epi32(1, 4, 5, 8); let b = _mm_setr_epi32(2, 3, 6, 7); let r = _mm_max_epu32(a, b); @@ -1340,7 +1383,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_min_epi8() { + const unsafe fn test_mm_min_epi8() { #[rustfmt::skip] let a = _mm_setr_epi8( 1, 4, 5, 8, 9, 12, 13, 16, @@ -1379,7 +1422,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_min_epu16() { + const unsafe fn test_mm_min_epu16() { let a = _mm_setr_epi16(1, 4, 5, 8, 9, 12, 13, 16); let b = _mm_setr_epi16(2, 3, 6, 7, 10, 11, 14, 15); let r = _mm_min_epu16(a, b); @@ -1388,7 +1431,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_min_epi32() { + const unsafe fn test_mm_min_epi32() { let a = _mm_setr_epi32(1, 4, 5, 8); let b = _mm_setr_epi32(2, 3, 6, 7); let r = _mm_min_epi32(a, b); @@ -1403,7 +1446,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_min_epu32() { + const unsafe fn test_mm_min_epu32() { let a = _mm_setr_epi32(1, 4, 5, 8); let b = _mm_setr_epi32(2, 3, 6, 7); let r = _mm_min_epu32(a, b); @@ -1421,7 +1464,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cmpeq_epi64() { + const unsafe fn test_mm_cmpeq_epi64() { let a = _mm_setr_epi64x(0, 1); let b = _mm_setr_epi64x(0, 0); let r = _mm_cmpeq_epi64(a, b); @@ -1430,7 +1473,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepi8_epi16() { + const unsafe fn test_mm_cvtepi8_epi16() { let a = _mm_set1_epi8(10); let r = _mm_cvtepi8_epi16(a); let e = _mm_set1_epi16(10); @@ -1442,7 +1485,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepi8_epi32() { + const unsafe fn test_mm_cvtepi8_epi32() { let a = _mm_set1_epi8(10); let r = _mm_cvtepi8_epi32(a); let e = _mm_set1_epi32(10); @@ -1454,7 +1497,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepi8_epi64() { + const unsafe fn test_mm_cvtepi8_epi64() { let a = _mm_set1_epi8(10); let r = _mm_cvtepi8_epi64(a); let e = _mm_set1_epi64x(10); @@ -1466,7 +1509,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepi16_epi32() { + const unsafe fn test_mm_cvtepi16_epi32() { let a = _mm_set1_epi16(10); let r = _mm_cvtepi16_epi32(a); let e = _mm_set1_epi32(10); @@ -1478,7 +1521,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepi16_epi64() { + const unsafe fn test_mm_cvtepi16_epi64() { let a = _mm_set1_epi16(10); let r = _mm_cvtepi16_epi64(a); let e = _mm_set1_epi64x(10); @@ -1490,7 +1533,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepi32_epi64() { + const unsafe fn test_mm_cvtepi32_epi64() { let a = _mm_set1_epi32(10); let r = _mm_cvtepi32_epi64(a); let e = _mm_set1_epi64x(10); @@ -1502,7 +1545,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepu8_epi16() { + const unsafe fn test_mm_cvtepu8_epi16() { let a = _mm_set1_epi8(10); let r = _mm_cvtepu8_epi16(a); let e = _mm_set1_epi16(10); @@ -1510,7 +1553,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepu8_epi32() { + const unsafe fn test_mm_cvtepu8_epi32() { let a = _mm_set1_epi8(10); let r = _mm_cvtepu8_epi32(a); let e = _mm_set1_epi32(10); @@ -1518,7 +1561,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepu8_epi64() { + const unsafe fn test_mm_cvtepu8_epi64() { let a = _mm_set1_epi8(10); let r = _mm_cvtepu8_epi64(a); let e = _mm_set1_epi64x(10); @@ -1526,7 +1569,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepu16_epi32() { + const unsafe fn test_mm_cvtepu16_epi32() { let a = _mm_set1_epi16(10); let r = _mm_cvtepu16_epi32(a); let e = _mm_set1_epi32(10); @@ -1534,7 +1577,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepu16_epi64() { + const unsafe fn test_mm_cvtepu16_epi64() { let a = _mm_set1_epi16(10); let r = _mm_cvtepu16_epi64(a); let e = _mm_set1_epi64x(10); @@ -1542,7 +1585,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_cvtepu32_epi64() { + const unsafe fn test_mm_cvtepu32_epi64() { let a = _mm_set1_epi32(10); let r = _mm_cvtepu32_epi64(a); let e = _mm_set1_epi64x(10); @@ -1566,7 +1609,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_floor_pd() { + const unsafe fn test_mm_floor_pd() { let a = _mm_setr_pd(2.5, 4.5); let r = _mm_floor_pd(a); let e = _mm_setr_pd(2.0, 4.0); @@ -1574,7 +1617,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_floor_ps() { + const unsafe fn test_mm_floor_ps() { let a = _mm_setr_ps(2.5, 4.5, 8.5, 16.5); let r = _mm_floor_ps(a); let e = _mm_setr_ps(2.0, 4.0, 8.0, 16.0); @@ -1600,7 +1643,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_ceil_pd() { + const unsafe fn test_mm_ceil_pd() { let a = _mm_setr_pd(1.5, 3.5); let r = _mm_ceil_pd(a); let e = _mm_setr_pd(2.0, 4.0); @@ -1608,7 +1651,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_ceil_ps() { + const unsafe fn test_mm_ceil_ps() { let a = _mm_setr_ps(1.5, 3.5, 7.5, 15.5); let r = _mm_ceil_ps(a); let e = _mm_setr_ps(2.0, 4.0, 8.0, 16.0); @@ -1729,7 +1772,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_mul_epi32() { + const unsafe fn test_mm_mul_epi32() { { let a = _mm_setr_epi32(1, 1, 1, 1); let b = _mm_setr_epi32(1, 2, 3, 4); @@ -1750,7 +1793,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_mullo_epi32() { + const unsafe fn test_mm_mullo_epi32() { { let a = _mm_setr_epi32(1, 1, 1, 1); let b = _mm_setr_epi32(1, 2, 3, 4); @@ -1808,7 +1851,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_testz_si128() { + const unsafe fn test_mm_testz_si128() { let a = _mm_set1_epi8(1); let mask = _mm_set1_epi8(0); let r = _mm_testz_si128(a, mask); @@ -1824,7 +1867,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_testc_si128() { + const unsafe fn test_mm_testc_si128() { let a = _mm_set1_epi8(-1); let mask = _mm_set1_epi8(0); let r = _mm_testc_si128(a, mask); @@ -1860,7 +1903,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_test_all_zeros() { + const unsafe fn test_mm_test_all_zeros() { let a = _mm_set1_epi8(1); let mask = _mm_set1_epi8(0); let r = _mm_test_all_zeros(a, mask); @@ -1876,7 +1919,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_test_all_ones() { + const unsafe fn test_mm_test_all_ones() { let a = _mm_set1_epi8(-1); let r = _mm_test_all_ones(a); assert_eq!(r, 1); diff --git a/library/stdarch/crates/core_arch/src/x86_64/sse41.rs b/library/stdarch/crates/core_arch/src/x86_64/sse41.rs index 4b7d25f2144b..3b1c88ad8cb2 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/sse41.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/sse41.rs @@ -13,7 +13,8 @@ use stdarch_test::assert_instr; #[cfg_attr(test, assert_instr(pextrq, IMM1 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_extract_epi64(a: __m128i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_extract_epi64(a: __m128i) -> i64 { static_assert_uimm_bits!(IMM1, 1); unsafe { simd_extract!(a.as_i64x2(), IMM1 as u32) } } @@ -27,7 +28,8 @@ pub fn _mm_extract_epi64(a: __m128i) -> i64 { #[cfg_attr(test, assert_instr(pinsrq, IMM1 = 0))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_insert_epi64(a: __m128i, i: i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_insert_epi64(a: __m128i, i: i64) -> __m128i { static_assert_uimm_bits!(IMM1, 1); unsafe { transmute(simd_insert!(a.as_i64x2(), IMM1 as u32, i)) } } @@ -35,10 +37,11 @@ pub fn _mm_insert_epi64(a: __m128i, i: i64) -> __m128i { #[cfg(test)] mod tests { use crate::core_arch::arch::x86_64::*; + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_extract_epi64() { + const unsafe fn test_mm_extract_epi64() { let a = _mm_setr_epi64x(0, 1); let r = _mm_extract_epi64::<1>(a); assert_eq!(r, 1); @@ -47,7 +50,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_insert_epi64() { + const unsafe fn test_mm_insert_epi64() { let a = _mm_set1_epi64x(0); let e = _mm_setr_epi64x(0, 32); let r = _mm_insert_epi64::<1>(a, 32); From 96b8e391abd6fd6cc3a20c9c6f4867735c487365 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:21:58 +0530 Subject: [PATCH 0230/3801] Make `sse4.2` functions const --- library/stdarch/crates/core_arch/src/x86/sse42.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/sse42.rs b/library/stdarch/crates/core_arch/src/x86/sse42.rs index 83c51f2b70eb..4d3c481fe124 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse42.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse42.rs @@ -563,7 +563,8 @@ pub fn _mm_crc32_u32(crc: u32, v: u32) -> u32 { #[target_feature(enable = "sse4.2")] #[cfg_attr(test, assert_instr(pcmpgtq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_cmpgt_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_gt::<_, i64x2>(a.as_i64x2(), b.as_i64x2())) } } @@ -609,6 +610,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; @@ -789,7 +791,7 @@ mod tests { } #[simd_test(enable = "sse4.2")] - unsafe fn test_mm_cmpgt_epi64() { + const unsafe fn test_mm_cmpgt_epi64() { let a = _mm_setr_epi64x(0, 0x2a); let b = _mm_set1_epi64x(0x00); let i = _mm_cmpgt_epi64(a, b); From 0864ad202c54a662460ad11bad86c0797a07d0ce Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 19:11:22 +0530 Subject: [PATCH 0231/3801] Make `avx` functions const --- .../stdarch/crates/core_arch/src/x86/avx.rs | 752 +++++++++++------- .../crates/core_arch/src/x86_64/avx.rs | 11 +- 2 files changed, 466 insertions(+), 297 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx.rs b/library/stdarch/crates/core_arch/src/x86/avx.rs index c50c83fcaa8f..acba0a3db7c6 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx.rs @@ -30,7 +30,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vaddpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_add_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_add_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { simd_add(a, b) } } @@ -42,7 +43,8 @@ pub fn _mm256_add_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vaddps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_add_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_add_ps(a: __m256, b: __m256) -> __m256 { unsafe { simd_add(a, b) } } @@ -55,7 +57,8 @@ pub fn _mm256_add_ps(a: __m256, b: __m256) -> __m256 { // See https://github.com/rust-lang/stdarch/issues/71 #[cfg_attr(test, assert_instr(vandp))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_and_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_and_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { let a: u64x4 = transmute(a); let b: u64x4 = transmute(b); @@ -71,7 +74,8 @@ pub fn _mm256_and_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vandps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_and_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_and_ps(a: __m256, b: __m256) -> __m256 { unsafe { let a: u32x8 = transmute(a); let b: u32x8 = transmute(b); @@ -88,7 +92,8 @@ pub fn _mm256_and_ps(a: __m256, b: __m256) -> __m256 { // See . #[cfg_attr(test, assert_instr(vorp))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_or_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_or_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { let a: u64x4 = transmute(a); let b: u64x4 = transmute(b); @@ -104,7 +109,8 @@ pub fn _mm256_or_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vorps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_or_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_or_ps(a: __m256, b: __m256) -> __m256 { unsafe { let a: u32x8 = transmute(a); let b: u32x8 = transmute(b); @@ -121,7 +127,8 @@ pub fn _mm256_or_ps(a: __m256, b: __m256) -> __m256 { #[cfg_attr(test, assert_instr(vshufpd, MASK = 3))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_shuffle_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shuffle_pd(a: __m256d, b: __m256d) -> __m256d { static_assert_uimm_bits!(MASK, 8); unsafe { simd_shuffle!( @@ -146,7 +153,8 @@ pub fn _mm256_shuffle_pd(a: __m256d, b: __m256d) -> __m256d { #[cfg_attr(test, assert_instr(vshufps, MASK = 3))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_shuffle_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shuffle_ps(a: __m256, b: __m256) -> __m256 { static_assert_uimm_bits!(MASK, 8); unsafe { simd_shuffle!( @@ -174,7 +182,8 @@ pub fn _mm256_shuffle_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vandnp))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_andnot_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_andnot_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { let a: u64x4 = transmute(a); let b: u64x4 = transmute(b); @@ -191,7 +200,8 @@ pub fn _mm256_andnot_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vandnps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_andnot_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_andnot_ps(a: __m256, b: __m256) -> __m256 { unsafe { let a: u32x8 = transmute(a); let b: u32x8 = transmute(b); @@ -255,7 +265,8 @@ pub fn _mm256_min_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmulpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_mul_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mul_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { simd_mul(a, b) } } @@ -267,7 +278,8 @@ pub fn _mm256_mul_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmulps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_mul_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mul_ps(a: __m256, b: __m256) -> __m256 { unsafe { simd_mul(a, b) } } @@ -279,7 +291,8 @@ pub fn _mm256_mul_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vaddsubpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_addsub_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_addsub_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { let a = a.as_f64x4(); let b = b.as_f64x4(); @@ -297,7 +310,8 @@ pub fn _mm256_addsub_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vaddsubps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_addsub_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_addsub_ps(a: __m256, b: __m256) -> __m256 { unsafe { let a = a.as_f32x8(); let b = b.as_f32x8(); @@ -315,7 +329,8 @@ pub fn _mm256_addsub_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vsubpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_sub_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sub_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { simd_sub(a, b) } } @@ -327,7 +342,8 @@ pub fn _mm256_sub_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vsubps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_sub_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sub_ps(a: __m256, b: __m256) -> __m256 { unsafe { simd_sub(a, b) } } @@ -339,7 +355,8 @@ pub fn _mm256_sub_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vdivps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_div_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_div_ps(a: __m256, b: __m256) -> __m256 { unsafe { simd_div(a, b) } } @@ -351,7 +368,8 @@ pub fn _mm256_div_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vdivpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_div_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_div_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { simd_div(a, b) } } @@ -386,7 +404,8 @@ pub fn _mm256_round_pd(a: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vroundpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_ceil_pd(a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_ceil_pd(a: __m256d) -> __m256d { unsafe { simd_ceil(a) } } @@ -398,7 +417,8 @@ pub fn _mm256_ceil_pd(a: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vroundpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_floor_pd(a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_floor_pd(a: __m256d) -> __m256d { unsafe { simd_floor(a) } } @@ -433,7 +453,8 @@ pub fn _mm256_round_ps(a: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vroundps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_ceil_ps(a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_ceil_ps(a: __m256) -> __m256 { unsafe { simd_ceil(a) } } @@ -445,7 +466,8 @@ pub fn _mm256_ceil_ps(a: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vroundps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_floor_ps(a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_floor_ps(a: __m256) -> __m256 { unsafe { simd_floor(a) } } @@ -485,7 +507,8 @@ pub fn _mm256_sqrt_pd(a: __m256d) -> __m256d { #[cfg_attr(test, assert_instr(vblendps, IMM4 = 9))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_blend_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_blend_pd(a: __m256d, b: __m256d) -> __m256d { static_assert_uimm_bits!(IMM4, 4); unsafe { simd_shuffle!( @@ -510,7 +533,8 @@ pub fn _mm256_blend_pd(a: __m256d, b: __m256d) -> __m256d { #[cfg_attr(test, assert_instr(vblendps, IMM8 = 9))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_blend_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_blend_ps(a: __m256, b: __m256) -> __m256 { static_assert_uimm_bits!(IMM8, 8); unsafe { simd_shuffle!( @@ -538,7 +562,8 @@ pub fn _mm256_blend_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vblendvpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_blendv_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_blendv_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { let mask: i64x4 = simd_lt(transmute::<_, i64x4>(c), i64x4::ZERO); transmute(simd_select(mask, b.as_f64x4(), a.as_f64x4())) @@ -553,7 +578,8 @@ pub fn _mm256_blendv_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vblendvps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_blendv_ps(a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_blendv_ps(a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { let mask: i32x8 = simd_lt(transmute::<_, i32x8>(c), i32x8::ZERO); transmute(simd_select(mask, b.as_f32x8(), a.as_f32x8())) @@ -586,7 +612,8 @@ pub fn _mm256_dp_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vhaddpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_hadd_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_hadd_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { let even = simd_shuffle!(a, b, [0, 4, 2, 6]); let odd = simd_shuffle!(a, b, [1, 5, 3, 7]); @@ -605,7 +632,8 @@ pub fn _mm256_hadd_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vhaddps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_hadd_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_hadd_ps(a: __m256, b: __m256) -> __m256 { unsafe { let even = simd_shuffle!(a, b, [0, 2, 8, 10, 4, 6, 12, 14]); let odd = simd_shuffle!(a, b, [1, 3, 9, 11, 5, 7, 13, 15]); @@ -623,7 +651,8 @@ pub fn _mm256_hadd_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vhsubpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_hsub_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_hsub_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { let even = simd_shuffle!(a, b, [0, 4, 2, 6]); let odd = simd_shuffle!(a, b, [1, 5, 3, 7]); @@ -642,7 +671,8 @@ pub fn _mm256_hsub_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vhsubps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_hsub_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_hsub_ps(a: __m256, b: __m256) -> __m256 { unsafe { let even = simd_shuffle!(a, b, [0, 2, 8, 10, 4, 6, 12, 14]); let odd = simd_shuffle!(a, b, [1, 3, 9, 11, 5, 7, 13, 15]); @@ -658,7 +688,8 @@ pub fn _mm256_hsub_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vxorp))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_xor_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_xor_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { let a: u64x4 = transmute(a); let b: u64x4 = transmute(b); @@ -674,7 +705,8 @@ pub fn _mm256_xor_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_xor_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_xor_ps(a: __m256, b: __m256) -> __m256 { unsafe { let a: u32x8 = transmute(a); let b: u32x8 = transmute(b); @@ -881,7 +913,8 @@ pub fn _mm_cmp_ss(a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepi32_pd(a: __m128i) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi32_pd(a: __m128i) -> __m256d { unsafe { simd_cast(a.as_i32x4()) } } @@ -893,7 +926,8 @@ pub fn _mm256_cvtepi32_pd(a: __m128i) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vcvtdq2ps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepi32_ps(a: __m256i) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi32_ps(a: __m256i) -> __m256 { unsafe { simd_cast(a.as_i32x8()) } } @@ -905,7 +939,8 @@ pub fn _mm256_cvtepi32_ps(a: __m256i) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vcvtpd2ps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtpd_ps(a: __m256d) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtpd_ps(a: __m256d) -> __m128 { unsafe { simd_cast(a) } } @@ -929,7 +964,8 @@ pub fn _mm256_cvtps_epi32(a: __m256) -> __m256i { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vcvtps2pd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtps_pd(a: __m128) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtps_pd(a: __m128) -> __m256d { unsafe { simd_cast(a) } } @@ -940,7 +976,8 @@ pub fn _mm256_cvtps_pd(a: __m128) -> __m256d { #[target_feature(enable = "avx")] //#[cfg_attr(test, assert_instr(movsd))] FIXME #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtsd_f64(a: __m256d) -> f64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtsd_f64(a: __m256d) -> f64 { unsafe { simd_extract!(a, 0) } } @@ -989,7 +1026,8 @@ pub fn _mm256_cvttps_epi32(a: __m256) -> __m256i { #[cfg_attr(test, assert_instr(vextractf128, IMM1 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_extractf128_ps(a: __m256) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extractf128_ps(a: __m256) -> __m128 { static_assert_uimm_bits!(IMM1, 1); unsafe { simd_shuffle!( @@ -1009,7 +1047,8 @@ pub fn _mm256_extractf128_ps(a: __m256) -> __m128 { #[cfg_attr(test, assert_instr(vextractf128, IMM1 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_extractf128_pd(a: __m256d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extractf128_pd(a: __m256d) -> __m128d { static_assert_uimm_bits!(IMM1, 1); unsafe { simd_shuffle!(a, _mm256_undefined_pd(), [[0, 1], [2, 3]][IMM1 as usize]) } } @@ -1022,7 +1061,8 @@ pub fn _mm256_extractf128_pd(a: __m256d) -> __m128d { #[cfg_attr(test, assert_instr(vextractf128, IMM1 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_extractf128_si256(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extractf128_si256(a: __m256i) -> __m128i { static_assert_uimm_bits!(IMM1, 1); unsafe { let dst: i64x2 = simd_shuffle!(a.as_i64x4(), i64x4::ZERO, [[0, 1], [2, 3]][IMM1 as usize],); @@ -1038,7 +1078,8 @@ pub fn _mm256_extractf128_si256(a: __m256i) -> __m128i { // This intrinsic has no corresponding instruction. #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_extract_epi32(a: __m256i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extract_epi32(a: __m256i) -> i32 { static_assert_uimm_bits!(INDEX, 3); unsafe { simd_extract!(a.as_i32x8(), INDEX as u32) } } @@ -1049,7 +1090,8 @@ pub fn _mm256_extract_epi32(a: __m256i) -> i32 { #[inline] #[target_feature(enable = "avx")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtsi256_si32(a: __m256i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtsi256_si32(a: __m256i) -> i32 { unsafe { simd_extract!(a.as_i32x8(), 0) } } @@ -1109,7 +1151,8 @@ pub fn _mm_permutevar_ps(a: __m128, b: __m128i) -> __m128 { #[cfg_attr(test, assert_instr(vshufps, IMM8 = 9))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_permute_ps(a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permute_ps(a: __m256) -> __m256 { static_assert_uimm_bits!(IMM8, 8); unsafe { simd_shuffle!( @@ -1138,7 +1181,8 @@ pub fn _mm256_permute_ps(a: __m256) -> __m256 { #[cfg_attr(test, assert_instr(vshufps, IMM8 = 9))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_permute_ps(a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_permute_ps(a: __m128) -> __m128 { static_assert_uimm_bits!(IMM8, 8); unsafe { simd_shuffle!( @@ -1187,7 +1231,8 @@ pub fn _mm_permutevar_pd(a: __m128d, b: __m128i) -> __m128d { #[cfg_attr(test, assert_instr(vshufpd, IMM4 = 0x1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_permute_pd(a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permute_pd(a: __m256d) -> __m256d { static_assert_uimm_bits!(IMM4, 4); unsafe { simd_shuffle!( @@ -1212,7 +1257,8 @@ pub fn _mm256_permute_pd(a: __m256d) -> __m256d { #[cfg_attr(test, assert_instr(vshufpd, IMM2 = 0x1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_permute_pd(a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_permute_pd(a: __m128d) -> __m128d { static_assert_uimm_bits!(IMM2, 2); unsafe { simd_shuffle!( @@ -1232,7 +1278,8 @@ pub fn _mm_permute_pd(a: __m128d) -> __m128d { #[cfg_attr(test, assert_instr(vperm2f128, IMM8 = 0x5))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_permute2f128_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permute2f128_ps(a: __m256, b: __m256) -> __m256 { static_assert_uimm_bits!(IMM8, 8); _mm256_castsi256_ps(_mm256_permute2f128_si256::( _mm256_castps_si256(a), @@ -1249,7 +1296,8 @@ pub fn _mm256_permute2f128_ps(a: __m256, b: __m256) -> __m256 { #[cfg_attr(test, assert_instr(vperm2f128, IMM8 = 0x31))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_permute2f128_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permute2f128_pd(a: __m256d, b: __m256d) -> __m256d { static_assert_uimm_bits!(IMM8, 8); _mm256_castsi256_pd(_mm256_permute2f128_si256::( _mm256_castpd_si256(a), @@ -1266,7 +1314,8 @@ pub fn _mm256_permute2f128_pd(a: __m256d, b: __m256d) -> __m256 #[cfg_attr(test, assert_instr(vperm2f128, IMM8 = 0x31))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_permute2f128_si256(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permute2f128_si256(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); const fn idx(imm8: i32, pos: u32) -> u32 { let part = if pos < 2 { @@ -1308,7 +1357,8 @@ pub fn _mm256_permute2f128_si256(a: __m256i, b: __m256i) -> __m #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::trivially_copy_pass_by_ref)] -pub fn _mm256_broadcast_ss(f: &f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_ss(f: &f32) -> __m256 { _mm256_set1_ps(*f) } @@ -1321,7 +1371,8 @@ pub fn _mm256_broadcast_ss(f: &f32) -> __m256 { #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::trivially_copy_pass_by_ref)] -pub fn _mm_broadcast_ss(f: &f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcast_ss(f: &f32) -> __m128 { _mm_set1_ps(*f) } @@ -1334,7 +1385,8 @@ pub fn _mm_broadcast_ss(f: &f32) -> __m128 { #[cfg_attr(test, assert_instr(vbroadcastsd))] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::trivially_copy_pass_by_ref)] -pub fn _mm256_broadcast_sd(f: &f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_sd(f: &f64) -> __m256d { _mm256_set1_pd(*f) } @@ -1346,7 +1398,8 @@ pub fn _mm256_broadcast_sd(f: &f64) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vbroadcastf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_broadcast_ps(a: &__m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_ps(a: &__m128) -> __m256 { unsafe { simd_shuffle!(*a, _mm_setzero_ps(), [0, 1, 2, 3, 0, 1, 2, 3]) } } @@ -1358,7 +1411,8 @@ pub fn _mm256_broadcast_ps(a: &__m128) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vbroadcastf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_broadcast_pd(a: &__m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_pd(a: &__m128d) -> __m256d { unsafe { simd_shuffle!(*a, _mm_setzero_pd(), [0, 1, 0, 1]) } } @@ -1372,7 +1426,8 @@ pub fn _mm256_broadcast_pd(a: &__m128d) -> __m256d { #[cfg_attr(test, assert_instr(vinsertf128, IMM1 = 1))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_insertf128_ps(a: __m256, b: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_insertf128_ps(a: __m256, b: __m128) -> __m256 { static_assert_uimm_bits!(IMM1, 1); unsafe { simd_shuffle!( @@ -1393,7 +1448,8 @@ pub fn _mm256_insertf128_ps(a: __m256, b: __m128) -> __m256 { #[cfg_attr(test, assert_instr(vinsertf128, IMM1 = 1))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_insertf128_pd(a: __m256d, b: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_insertf128_pd(a: __m256d, b: __m128d) -> __m256d { static_assert_uimm_bits!(IMM1, 1); unsafe { simd_shuffle!( @@ -1413,7 +1469,8 @@ pub fn _mm256_insertf128_pd(a: __m256d, b: __m128d) -> __m256d #[cfg_attr(test, assert_instr(vinsertf128, IMM1 = 1))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_insertf128_si256(a: __m256i, b: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_insertf128_si256(a: __m256i, b: __m128i) -> __m256i { static_assert_uimm_bits!(IMM1, 1); unsafe { let dst: i64x4 = simd_shuffle!( @@ -1434,7 +1491,8 @@ pub fn _mm256_insertf128_si256(a: __m256i, b: __m128i) -> __m25 // This intrinsic has no corresponding instruction. #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_insert_epi8(a: __m256i, i: i8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_insert_epi8(a: __m256i, i: i8) -> __m256i { static_assert_uimm_bits!(INDEX, 5); unsafe { transmute(simd_insert!(a.as_i8x32(), INDEX as u32, i)) } } @@ -1448,7 +1506,8 @@ pub fn _mm256_insert_epi8(a: __m256i, i: i8) -> __m256i { // This intrinsic has no corresponding instruction. #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_insert_epi16(a: __m256i, i: i16) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_insert_epi16(a: __m256i, i: i16) -> __m256i { static_assert_uimm_bits!(INDEX, 4); unsafe { transmute(simd_insert!(a.as_i16x16(), INDEX as u32, i)) } } @@ -1462,7 +1521,8 @@ pub fn _mm256_insert_epi16(a: __m256i, i: i16) -> __m256i { // This intrinsic has no corresponding instruction. #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_insert_epi32(a: __m256i, i: i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_insert_epi32(a: __m256i, i: i32) -> __m256i { static_assert_uimm_bits!(INDEX, 3); unsafe { transmute(simd_insert!(a.as_i32x8(), INDEX as u32, i)) } } @@ -1481,7 +1541,8 @@ pub fn _mm256_insert_epi32(a: __m256i, i: i32) -> __m256i { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm256_load_pd(mem_addr: *const f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_load_pd(mem_addr: *const f64) -> __m256d { *(mem_addr as *const __m256d) } @@ -1499,7 +1560,8 @@ pub unsafe fn _mm256_load_pd(mem_addr: *const f64) -> __m256d { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm256_store_pd(mem_addr: *mut f64, a: __m256d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_store_pd(mem_addr: *mut f64, a: __m256d) { *(mem_addr as *mut __m256d) = a; } @@ -1517,7 +1579,8 @@ pub unsafe fn _mm256_store_pd(mem_addr: *mut f64, a: __m256d) { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm256_load_ps(mem_addr: *const f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_load_ps(mem_addr: *const f32) -> __m256 { *(mem_addr as *const __m256) } @@ -1535,7 +1598,8 @@ pub unsafe fn _mm256_load_ps(mem_addr: *const f32) -> __m256 { )] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::cast_ptr_alignment)] -pub unsafe fn _mm256_store_ps(mem_addr: *mut f32, a: __m256) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_store_ps(mem_addr: *mut f32, a: __m256) { *(mem_addr as *mut __m256) = a; } @@ -1548,7 +1612,8 @@ pub unsafe fn _mm256_store_ps(mem_addr: *mut f32, a: __m256) { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_loadu_pd(mem_addr: *const f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu_pd(mem_addr: *const f64) -> __m256d { let mut dst = _mm256_undefined_pd(); ptr::copy_nonoverlapping( mem_addr as *const u8, @@ -1567,7 +1632,8 @@ pub unsafe fn _mm256_loadu_pd(mem_addr: *const f64) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_storeu_pd(mem_addr: *mut f64, a: __m256d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu_pd(mem_addr: *mut f64, a: __m256d) { mem_addr.cast::<__m256d>().write_unaligned(a); } @@ -1580,7 +1646,8 @@ pub unsafe fn _mm256_storeu_pd(mem_addr: *mut f64, a: __m256d) { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_loadu_ps(mem_addr: *const f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu_ps(mem_addr: *const f32) -> __m256 { let mut dst = _mm256_undefined_ps(); ptr::copy_nonoverlapping( mem_addr as *const u8, @@ -1599,7 +1666,8 @@ pub unsafe fn _mm256_loadu_ps(mem_addr: *const f32) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_storeu_ps(mem_addr: *mut f32, a: __m256) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu_ps(mem_addr: *mut f32, a: __m256) { mem_addr.cast::<__m256>().write_unaligned(a); } @@ -1615,7 +1683,8 @@ pub unsafe fn _mm256_storeu_ps(mem_addr: *mut f32, a: __m256) { assert_instr(vmovaps) )] // FIXME vmovdqa expected #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_load_si256(mem_addr: *const __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_load_si256(mem_addr: *const __m256i) -> __m256i { *mem_addr } @@ -1631,7 +1700,8 @@ pub unsafe fn _mm256_load_si256(mem_addr: *const __m256i) -> __m256i { assert_instr(vmovaps) )] // FIXME vmovdqa expected #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_store_si256(mem_addr: *mut __m256i, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_store_si256(mem_addr: *mut __m256i, a: __m256i) { *mem_addr = a; } @@ -1643,7 +1713,8 @@ pub unsafe fn _mm256_store_si256(mem_addr: *mut __m256i, a: __m256i) { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovups))] // FIXME vmovdqu expected #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_loadu_si256(mem_addr: *const __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu_si256(mem_addr: *const __m256i) -> __m256i { let mut dst = _mm256_undefined_si256(); ptr::copy_nonoverlapping( mem_addr as *const u8, @@ -1661,7 +1732,8 @@ pub unsafe fn _mm256_loadu_si256(mem_addr: *const __m256i) -> __m256i { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovups))] // FIXME vmovdqu expected #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_storeu_si256(mem_addr: *mut __m256i, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu_si256(mem_addr: *mut __m256i, a: __m256i) { mem_addr.write_unaligned(a); } @@ -1674,7 +1746,8 @@ pub unsafe fn _mm256_storeu_si256(mem_addr: *mut __m256i, a: __m256i) { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmaskmovpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_maskload_pd(mem_addr: *const f64, mask: __m256i) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskload_pd(mem_addr: *const f64, mask: __m256i) -> __m256d { let mask = simd_shr(mask.as_i64x4(), i64x4::splat(63)); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, _mm256_setzero_pd()) } @@ -1687,7 +1760,8 @@ pub unsafe fn _mm256_maskload_pd(mem_addr: *const f64, mask: __m256i) -> __m256d #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmaskmovpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_maskstore_pd(mem_addr: *mut f64, mask: __m256i, a: __m256d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskstore_pd(mem_addr: *mut f64, mask: __m256i, a: __m256d) { let mask = simd_shr(mask.as_i64x4(), i64x4::splat(63)); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a) } @@ -1701,7 +1775,8 @@ pub unsafe fn _mm256_maskstore_pd(mem_addr: *mut f64, mask: __m256i, a: __m256d) #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmaskmovpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_maskload_pd(mem_addr: *const f64, mask: __m128i) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskload_pd(mem_addr: *const f64, mask: __m128i) -> __m128d { let mask = simd_shr(mask.as_i64x2(), i64x2::splat(63)); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, _mm_setzero_pd()) } @@ -1714,7 +1789,8 @@ pub unsafe fn _mm_maskload_pd(mem_addr: *const f64, mask: __m128i) -> __m128d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmaskmovpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_maskstore_pd(mem_addr: *mut f64, mask: __m128i, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskstore_pd(mem_addr: *mut f64, mask: __m128i, a: __m128d) { let mask = simd_shr(mask.as_i64x2(), i64x2::splat(63)); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a) } @@ -1728,7 +1804,8 @@ pub unsafe fn _mm_maskstore_pd(mem_addr: *mut f64, mask: __m128i, a: __m128d) { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmaskmovps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_maskload_ps(mem_addr: *const f32, mask: __m256i) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskload_ps(mem_addr: *const f32, mask: __m256i) -> __m256 { let mask = simd_shr(mask.as_i32x8(), i32x8::splat(31)); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, _mm256_setzero_ps()) } @@ -1741,7 +1818,8 @@ pub unsafe fn _mm256_maskload_ps(mem_addr: *const f32, mask: __m256i) -> __m256 #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmaskmovps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_maskstore_ps(mem_addr: *mut f32, mask: __m256i, a: __m256) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskstore_ps(mem_addr: *mut f32, mask: __m256i, a: __m256) { let mask = simd_shr(mask.as_i32x8(), i32x8::splat(31)); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a) } @@ -1755,7 +1833,8 @@ pub unsafe fn _mm256_maskstore_ps(mem_addr: *mut f32, mask: __m256i, a: __m256) #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmaskmovps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_maskload_ps(mem_addr: *const f32, mask: __m128i) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskload_ps(mem_addr: *const f32, mask: __m128i) -> __m128 { let mask = simd_shr(mask.as_i32x4(), i32x4::splat(31)); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, _mm_setzero_ps()) } @@ -1768,7 +1847,8 @@ pub unsafe fn _mm_maskload_ps(mem_addr: *const f32, mask: __m128i) -> __m128 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmaskmovps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_maskstore_ps(mem_addr: *mut f32, mask: __m128i, a: __m128) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskstore_ps(mem_addr: *mut f32, mask: __m128i, a: __m128) { let mask = simd_shr(mask.as_i32x4(), i32x4::splat(31)); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a) } @@ -1781,7 +1861,8 @@ pub unsafe fn _mm_maskstore_ps(mem_addr: *mut f32, mask: __m128i, a: __m128) { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovshdup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_movehdup_ps(a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movehdup_ps(a: __m256) -> __m256 { unsafe { simd_shuffle!(a, a, [1, 1, 3, 3, 5, 5, 7, 7]) } } @@ -1793,7 +1874,8 @@ pub fn _mm256_movehdup_ps(a: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovsldup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_moveldup_ps(a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_moveldup_ps(a: __m256) -> __m256 { unsafe { simd_shuffle!(a, a, [0, 0, 2, 2, 4, 4, 6, 6]) } } @@ -1805,7 +1887,8 @@ pub fn _mm256_moveldup_ps(a: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovddup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_movedup_pd(a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movedup_pd(a: __m256d) -> __m256d { unsafe { simd_shuffle!(a, a, [0, 0, 2, 2]) } } @@ -1943,7 +2026,8 @@ pub fn _mm256_rsqrt_ps(a: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vunpckhpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpackhi_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpackhi_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { simd_shuffle!(a, b, [1, 5, 3, 7]) } } @@ -1955,7 +2039,8 @@ pub fn _mm256_unpackhi_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vunpckhps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpackhi_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpackhi_ps(a: __m256, b: __m256) -> __m256 { unsafe { simd_shuffle!(a, b, [2, 10, 3, 11, 6, 14, 7, 15]) } } @@ -1967,7 +2052,8 @@ pub fn _mm256_unpackhi_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vunpcklpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpacklo_pd(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpacklo_pd(a: __m256d, b: __m256d) -> __m256d { unsafe { simd_shuffle!(a, b, [0, 4, 2, 6]) } } @@ -1979,7 +2065,8 @@ pub fn _mm256_unpacklo_pd(a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vunpcklps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpacklo_ps(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpacklo_ps(a: __m256, b: __m256) -> __m256 { unsafe { simd_shuffle!(a, b, [0, 8, 1, 9, 4, 12, 5, 13]) } } @@ -1993,7 +2080,8 @@ pub fn _mm256_unpacklo_ps(a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vptest))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_testz_si256(a: __m256i, b: __m256i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_testz_si256(a: __m256i, b: __m256i) -> i32 { unsafe { let r = simd_and(a.as_i64x4(), b.as_i64x4()); (0i64 == simd_reduce_or(r)) as i32 @@ -2010,7 +2098,8 @@ pub fn _mm256_testz_si256(a: __m256i, b: __m256i) -> i32 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vptest))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_testc_si256(a: __m256i, b: __m256i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_testc_si256(a: __m256i, b: __m256i) -> i32 { unsafe { let r = simd_and(simd_xor(a.as_i64x4(), i64x4::splat(!0)), b.as_i64x4()); (0i64 == simd_reduce_or(r)) as i32 @@ -2097,7 +2186,8 @@ pub fn _mm256_testnzc_pd(a: __m256d, b: __m256d) -> i32 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vtestpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_testz_pd(a: __m128d, b: __m128d) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testz_pd(a: __m128d, b: __m128d) -> i32 { unsafe { let r: i64x2 = simd_lt(transmute(_mm_and_pd(a, b)), i64x2::ZERO); (0i64 == simd_reduce_or(r)) as i32 @@ -2117,7 +2207,8 @@ pub fn _mm_testz_pd(a: __m128d, b: __m128d) -> i32 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vtestpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_testc_pd(a: __m128d, b: __m128d) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testc_pd(a: __m128d, b: __m128d) -> i32 { unsafe { let r: i64x2 = simd_lt(transmute(_mm_andnot_pd(a, b)), i64x2::ZERO); (0i64 == simd_reduce_or(r)) as i32 @@ -2207,7 +2298,8 @@ pub fn _mm256_testnzc_ps(a: __m256, b: __m256) -> i32 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vtestps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_testz_ps(a: __m128, b: __m128) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testz_ps(a: __m128, b: __m128) -> i32 { unsafe { let r: i32x4 = simd_lt(transmute(_mm_and_ps(a, b)), i32x4::ZERO); (0i32 == simd_reduce_or(r)) as i32 @@ -2227,7 +2319,8 @@ pub fn _mm_testz_ps(a: __m128, b: __m128) -> i32 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vtestps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_testc_ps(a: __m128, b: __m128) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testc_ps(a: __m128, b: __m128) -> i32 { unsafe { let r: i32x4 = simd_lt(transmute(_mm_andnot_ps(a, b)), i32x4::ZERO); (0i32 == simd_reduce_or(r)) as i32 @@ -2261,12 +2354,13 @@ pub fn _mm_testnzc_ps(a: __m128, b: __m128) -> i32 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovmskpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_movemask_pd(a: __m256d) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movemask_pd(a: __m256d) -> i32 { // Propagate the highest bit to the rest, because simd_bitmask // requires all-1 or all-0. unsafe { let mask: i64x4 = simd_lt(transmute(a), i64x4::ZERO); - simd_bitmask::(mask).into() + simd_bitmask::(mask) as i32 } } @@ -2279,12 +2373,13 @@ pub fn _mm256_movemask_pd(a: __m256d) -> i32 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vmovmskps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_movemask_ps(a: __m256) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movemask_ps(a: __m256) -> i32 { // Propagate the highest bit to the rest, because simd_bitmask // requires all-1 or all-0. unsafe { let mask: i32x8 = simd_lt(transmute(a), i32x8::ZERO); - simd_bitmask::(mask).into() + simd_bitmask::(mask) as i32 } } @@ -2295,7 +2390,8 @@ pub fn _mm256_movemask_ps(a: __m256) -> i32 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vxorp))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setzero_pd() -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setzero_pd() -> __m256d { const { unsafe { mem::zeroed() } } } @@ -2306,7 +2402,8 @@ pub fn _mm256_setzero_pd() -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setzero_ps() -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setzero_ps() -> __m256 { const { unsafe { mem::zeroed() } } } @@ -2317,7 +2414,8 @@ pub fn _mm256_setzero_ps() -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vxor))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setzero_si256() -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setzero_si256() -> __m256i { const { unsafe { mem::zeroed() } } } @@ -2330,7 +2428,8 @@ pub fn _mm256_setzero_si256() -> __m256i { // This intrinsic has no corresponding instruction. #[cfg_attr(test, assert_instr(vinsertf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set_pd(a: f64, b: f64, c: f64, d: f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_pd(a: f64, b: f64, c: f64, d: f64) -> __m256d { _mm256_setr_pd(d, c, b, a) } @@ -2342,7 +2441,17 @@ pub fn _mm256_set_pd(a: f64, b: f64, c: f64, d: f64) -> __m256d { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set_ps(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32, g: f32, h: f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_ps( + a: f32, + b: f32, + c: f32, + d: f32, + e: f32, + f: f32, + g: f32, + h: f32, +) -> __m256 { _mm256_setr_ps(h, g, f, e, d, c, b, a) } @@ -2353,7 +2462,8 @@ pub fn _mm256_set_ps(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32, g: f32, h: #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set_epi8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_epi8( e00: i8, e01: i8, e02: i8, @@ -2403,7 +2513,8 @@ pub fn _mm256_set_epi8( #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_epi16( e00: i16, e01: i16, e02: i16, @@ -2437,7 +2548,8 @@ pub fn _mm256_set_epi16( #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_epi32( e0: i32, e1: i32, e2: i32, @@ -2457,7 +2569,8 @@ pub fn _mm256_set_epi32( #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set_epi64x(a: i64, b: i64, c: i64, d: i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_epi64x(a: i64, b: i64, c: i64, d: i64) -> __m256i { _mm256_setr_epi64x(d, c, b, a) } @@ -2469,7 +2582,8 @@ pub fn _mm256_set_epi64x(a: i64, b: i64, c: i64, d: i64) -> __m256i { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setr_pd(a: f64, b: f64, c: f64, d: f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_pd(a: f64, b: f64, c: f64, d: f64) -> __m256d { __m256d([a, b, c, d]) } @@ -2481,7 +2595,17 @@ pub fn _mm256_setr_pd(a: f64, b: f64, c: f64, d: f64) -> __m256d { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setr_ps(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32, g: f32, h: f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_ps( + a: f32, + b: f32, + c: f32, + d: f32, + e: f32, + f: f32, + g: f32, + h: f32, +) -> __m256 { __m256([a, b, c, d, e, f, g, h]) } @@ -2493,7 +2617,8 @@ pub fn _mm256_setr_ps(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32, g: f32, h: #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setr_epi8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_epi8( e00: i8, e01: i8, e02: i8, @@ -2546,7 +2671,8 @@ pub fn _mm256_setr_epi8( #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setr_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_epi16( e00: i16, e01: i16, e02: i16, @@ -2583,7 +2709,8 @@ pub fn _mm256_setr_epi16( #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setr_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_epi32( e0: i32, e1: i32, e2: i32, @@ -2604,7 +2731,8 @@ pub fn _mm256_setr_epi32( #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setr_epi64x(a: i64, b: i64, c: i64, d: i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_epi64x(a: i64, b: i64, c: i64, d: i64) -> __m256i { unsafe { transmute(i64x4::new(a, b, c, d)) } } @@ -2616,7 +2744,8 @@ pub fn _mm256_setr_epi64x(a: i64, b: i64, c: i64, d: i64) -> __m256i { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set1_pd(a: f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set1_pd(a: f64) -> __m256d { _mm256_setr_pd(a, a, a, a) } @@ -2628,7 +2757,8 @@ pub fn _mm256_set1_pd(a: f64) -> __m256d { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set1_ps(a: f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set1_ps(a: f32) -> __m256 { _mm256_setr_ps(a, a, a, a, a, a, a, a) } @@ -2640,7 +2770,8 @@ pub fn _mm256_set1_ps(a: f32) -> __m256 { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set1_epi8(a: i8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set1_epi8(a: i8) -> __m256i { #[rustfmt::skip] _mm256_setr_epi8( a, a, a, a, a, a, a, a, @@ -2660,7 +2791,8 @@ pub fn _mm256_set1_epi8(a: i8) -> __m256i { #[cfg_attr(test, assert_instr(vinsertf128))] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set1_epi16(a: i16) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set1_epi16(a: i16) -> __m256i { _mm256_setr_epi16(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a) } @@ -2672,7 +2804,8 @@ pub fn _mm256_set1_epi16(a: i16) -> __m256i { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set1_epi32(a: i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set1_epi32(a: i32) -> __m256i { _mm256_setr_epi32(a, a, a, a, a, a, a, a) } @@ -2686,7 +2819,8 @@ pub fn _mm256_set1_epi32(a: i32) -> __m256i { #[cfg_attr(all(test, target_arch = "x86"), assert_instr(vbroadcastsd))] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set1_epi64x(a: i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set1_epi64x(a: i64) -> __m256i { _mm256_setr_epi64x(a, a, a, a) } @@ -2698,7 +2832,8 @@ pub fn _mm256_set1_epi64x(a: i64) -> __m256i { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castpd_ps(a: __m256d) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castpd_ps(a: __m256d) -> __m256 { unsafe { transmute(a) } } @@ -2710,7 +2845,8 @@ pub fn _mm256_castpd_ps(a: __m256d) -> __m256 { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castps_pd(a: __m256) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castps_pd(a: __m256) -> __m256d { unsafe { transmute(a) } } @@ -2722,7 +2858,8 @@ pub fn _mm256_castps_pd(a: __m256) -> __m256d { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castps_si256(a: __m256) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castps_si256(a: __m256) -> __m256i { unsafe { transmute(a) } } @@ -2734,7 +2871,8 @@ pub fn _mm256_castps_si256(a: __m256) -> __m256i { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castsi256_ps(a: __m256i) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castsi256_ps(a: __m256i) -> __m256 { unsafe { transmute(a) } } @@ -2746,7 +2884,8 @@ pub fn _mm256_castsi256_ps(a: __m256i) -> __m256 { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castpd_si256(a: __m256d) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castpd_si256(a: __m256d) -> __m256i { unsafe { transmute(a) } } @@ -2758,7 +2897,8 @@ pub fn _mm256_castpd_si256(a: __m256d) -> __m256i { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castsi256_pd(a: __m256i) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castsi256_pd(a: __m256i) -> __m256d { unsafe { transmute(a) } } @@ -2770,7 +2910,8 @@ pub fn _mm256_castsi256_pd(a: __m256i) -> __m256d { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castps256_ps128(a: __m256) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castps256_ps128(a: __m256) -> __m128 { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3]) } } @@ -2782,7 +2923,8 @@ pub fn _mm256_castps256_ps128(a: __m256) -> __m128 { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castpd256_pd128(a: __m256d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castpd256_pd128(a: __m256d) -> __m128d { unsafe { simd_shuffle!(a, a, [0, 1]) } } @@ -2794,7 +2936,8 @@ pub fn _mm256_castpd256_pd128(a: __m256d) -> __m128d { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castsi256_si128(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castsi256_si128(a: __m256i) -> __m128i { unsafe { let a = a.as_i64x4(); let dst: i64x2 = simd_shuffle!(a, a, [0, 1]); @@ -2811,7 +2954,8 @@ pub fn _mm256_castsi256_si128(a: __m256i) -> __m128i { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castps128_ps256(a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castps128_ps256(a: __m128) -> __m256 { unsafe { simd_shuffle!(a, _mm_undefined_ps(), [0, 1, 2, 3, 4, 4, 4, 4]) } } @@ -2824,7 +2968,8 @@ pub fn _mm256_castps128_ps256(a: __m128) -> __m256 { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castpd128_pd256(a: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castpd128_pd256(a: __m128d) -> __m256d { unsafe { simd_shuffle!(a, _mm_undefined_pd(), [0, 1, 2, 2]) } } @@ -2837,7 +2982,8 @@ pub fn _mm256_castpd128_pd256(a: __m128d) -> __m256d { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_castsi128_si256(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castsi128_si256(a: __m128i) -> __m256i { unsafe { let a = a.as_i64x2(); let undefined = i64x2::ZERO; @@ -2856,7 +3002,8 @@ pub fn _mm256_castsi128_si256(a: __m128i) -> __m256i { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_zextps128_ps256(a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_zextps128_ps256(a: __m128) -> __m256 { unsafe { simd_shuffle!(a, _mm_setzero_ps(), [0, 1, 2, 3, 4, 5, 6, 7]) } } @@ -2870,7 +3017,8 @@ pub fn _mm256_zextps128_ps256(a: __m128) -> __m256 { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_zextsi128_si256(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_zextsi128_si256(a: __m128i) -> __m256i { unsafe { let b = i64x2::ZERO; let dst: i64x4 = simd_shuffle!(a.as_i64x2(), b, [0, 1, 2, 3]); @@ -2889,7 +3037,8 @@ pub fn _mm256_zextsi128_si256(a: __m128i) -> __m256i { // This intrinsic is only used for compilation and does not generate any // instructions, thus it has zero latency. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_zextpd128_pd256(a: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_zextpd128_pd256(a: __m128d) -> __m256d { unsafe { simd_shuffle!(a, _mm_setzero_pd(), [0, 1, 2, 3]) } } @@ -2903,7 +3052,8 @@ pub fn _mm256_zextpd128_pd256(a: __m128d) -> __m256d { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_undefined_ps() -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_undefined_ps() -> __m256 { const { unsafe { mem::zeroed() } } } @@ -2917,7 +3067,8 @@ pub fn _mm256_undefined_ps() -> __m256 { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_undefined_pd() -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_undefined_pd() -> __m256d { const { unsafe { mem::zeroed() } } } @@ -2931,7 +3082,8 @@ pub fn _mm256_undefined_pd() -> __m256d { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_undefined_si256() -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_undefined_si256() -> __m256i { const { unsafe { mem::zeroed() } } } @@ -2942,7 +3094,8 @@ pub fn _mm256_undefined_si256() -> __m256i { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vinsertf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set_m128(hi: __m128, lo: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_m128(hi: __m128, lo: __m128) -> __m256 { unsafe { simd_shuffle!(lo, hi, [0, 1, 2, 3, 4, 5, 6, 7]) } } @@ -2953,7 +3106,8 @@ pub fn _mm256_set_m128(hi: __m128, lo: __m128) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vinsertf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set_m128d(hi: __m128d, lo: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_m128d(hi: __m128d, lo: __m128d) -> __m256d { unsafe { let hi: __m128 = transmute(hi); let lo: __m128 = transmute(lo); @@ -2968,7 +3122,8 @@ pub fn _mm256_set_m128d(hi: __m128d, lo: __m128d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vinsertf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_set_m128i(hi: __m128i, lo: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_m128i(hi: __m128i, lo: __m128i) -> __m256i { unsafe { let hi: __m128 = transmute(hi); let lo: __m128 = transmute(lo); @@ -2983,7 +3138,8 @@ pub fn _mm256_set_m128i(hi: __m128i, lo: __m128i) -> __m256i { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vinsertf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setr_m128(lo: __m128, hi: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_m128(lo: __m128, hi: __m128) -> __m256 { _mm256_set_m128(hi, lo) } @@ -2994,7 +3150,8 @@ pub fn _mm256_setr_m128(lo: __m128, hi: __m128) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vinsertf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setr_m128d(lo: __m128d, hi: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_m128d(lo: __m128d, hi: __m128d) -> __m256d { _mm256_set_m128d(hi, lo) } @@ -3005,7 +3162,8 @@ pub fn _mm256_setr_m128d(lo: __m128d, hi: __m128d) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vinsertf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_setr_m128i(lo: __m128i, hi: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_m128i(lo: __m128i, hi: __m128i) -> __m256i { _mm256_set_m128i(hi, lo) } @@ -3019,7 +3177,8 @@ pub fn _mm256_setr_m128i(lo: __m128i, hi: __m128i) -> __m256i { #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_loadu2_m128(hiaddr: *const f32, loaddr: *const f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu2_m128(hiaddr: *const f32, loaddr: *const f32) -> __m256 { let a = _mm256_castps128_ps256(_mm_loadu_ps(loaddr)); _mm256_insertf128_ps::<1>(a, _mm_loadu_ps(hiaddr)) } @@ -3034,7 +3193,8 @@ pub unsafe fn _mm256_loadu2_m128(hiaddr: *const f32, loaddr: *const f32) -> __m2 #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_loadu2_m128d(hiaddr: *const f64, loaddr: *const f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu2_m128d(hiaddr: *const f64, loaddr: *const f64) -> __m256d { let a = _mm256_castpd128_pd256(_mm_loadu_pd(loaddr)); _mm256_insertf128_pd::<1>(a, _mm_loadu_pd(hiaddr)) } @@ -3048,7 +3208,8 @@ pub unsafe fn _mm256_loadu2_m128d(hiaddr: *const f64, loaddr: *const f64) -> __m #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_loadu2_m128i(hiaddr: *const __m128i, loaddr: *const __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu2_m128i(hiaddr: *const __m128i, loaddr: *const __m128i) -> __m256i { let a = _mm256_castsi128_si256(_mm_loadu_si128(loaddr)); _mm256_insertf128_si256::<1>(a, _mm_loadu_si128(hiaddr)) } @@ -3063,7 +3224,8 @@ pub unsafe fn _mm256_loadu2_m128i(hiaddr: *const __m128i, loaddr: *const __m128i #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_storeu2_m128(hiaddr: *mut f32, loaddr: *mut f32, a: __m256) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu2_m128(hiaddr: *mut f32, loaddr: *mut f32, a: __m256) { let lo = _mm256_castps256_ps128(a); _mm_storeu_ps(loaddr, lo); let hi = _mm256_extractf128_ps::<1>(a); @@ -3080,7 +3242,8 @@ pub unsafe fn _mm256_storeu2_m128(hiaddr: *mut f32, loaddr: *mut f32, a: __m256) #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_storeu2_m128d(hiaddr: *mut f64, loaddr: *mut f64, a: __m256d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu2_m128d(hiaddr: *mut f64, loaddr: *mut f64, a: __m256d) { let lo = _mm256_castpd256_pd128(a); _mm_storeu_pd(loaddr, lo); let hi = _mm256_extractf128_pd::<1>(a); @@ -3096,7 +3259,8 @@ pub unsafe fn _mm256_storeu2_m128d(hiaddr: *mut f64, loaddr: *mut f64, a: __m256 #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_storeu2_m128i(hiaddr: *mut __m128i, loaddr: *mut __m128i, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu2_m128i(hiaddr: *mut __m128i, loaddr: *mut __m128i, a: __m256i) { let lo = _mm256_castsi256_si128(a); _mm_storeu_si128(loaddr, lo); let hi = _mm256_extractf128_si256::<1>(a); @@ -3110,7 +3274,8 @@ pub unsafe fn _mm256_storeu2_m128i(hiaddr: *mut __m128i, loaddr: *mut __m128i, a #[target_feature(enable = "avx")] //#[cfg_attr(test, assert_instr(movss))] FIXME #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtss_f32(a: __m256) -> f32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtss_f32(a: __m256) -> f32 { unsafe { simd_extract!(a, 0) } } @@ -3191,6 +3356,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use crate::hint::black_box; use crate::ptr; use stdarch_test::simd_test; @@ -3198,7 +3364,7 @@ mod tests { use crate::core_arch::x86::*; #[simd_test(enable = "avx")] - unsafe fn test_mm256_add_pd() { + const unsafe fn test_mm256_add_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 6., 7., 8.); let r = _mm256_add_pd(a, b); @@ -3207,7 +3373,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_add_ps() { + const unsafe fn test_mm256_add_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_setr_ps(9., 10., 11., 12., 13., 14., 15., 16.); let r = _mm256_add_ps(a, b); @@ -3216,7 +3382,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_and_pd() { + const unsafe fn test_mm256_and_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set1_pd(0.6); let r = _mm256_and_pd(a, b); @@ -3225,7 +3391,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_and_ps() { + const unsafe fn test_mm256_and_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set1_ps(0.6); let r = _mm256_and_ps(a, b); @@ -3234,7 +3400,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_or_pd() { + const unsafe fn test_mm256_or_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set1_pd(0.6); let r = _mm256_or_pd(a, b); @@ -3243,7 +3409,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_or_ps() { + const unsafe fn test_mm256_or_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set1_ps(0.6); let r = _mm256_or_ps(a, b); @@ -3252,7 +3418,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_shuffle_pd() { + const unsafe fn test_mm256_shuffle_pd() { let a = _mm256_setr_pd(1., 4., 5., 8.); let b = _mm256_setr_pd(2., 3., 6., 7.); let r = _mm256_shuffle_pd::<0b11_11_11_11>(a, b); @@ -3261,7 +3427,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_shuffle_ps() { + const unsafe fn test_mm256_shuffle_ps() { let a = _mm256_setr_ps(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm256_setr_ps(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm256_shuffle_ps::<0b00_00_11_11>(a, b); @@ -3270,7 +3436,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_andnot_pd() { + const unsafe fn test_mm256_andnot_pd() { let a = _mm256_set1_pd(0.); let b = _mm256_set1_pd(0.6); let r = _mm256_andnot_pd(a, b); @@ -3278,7 +3444,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_andnot_ps() { + const unsafe fn test_mm256_andnot_ps() { let a = _mm256_set1_ps(0.); let b = _mm256_set1_ps(0.6); let r = _mm256_andnot_ps(a, b); @@ -3390,7 +3556,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_mul_pd() { + const unsafe fn test_mm256_mul_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 6., 7., 8.); let r = _mm256_mul_pd(a, b); @@ -3399,7 +3565,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_mul_ps() { + const unsafe fn test_mm256_mul_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_setr_ps(9., 10., 11., 12., 13., 14., 15., 16.); let r = _mm256_mul_ps(a, b); @@ -3408,7 +3574,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_addsub_pd() { + const unsafe fn test_mm256_addsub_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 6., 7., 8.); let r = _mm256_addsub_pd(a, b); @@ -3417,7 +3583,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_addsub_ps() { + const unsafe fn test_mm256_addsub_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 1., 2., 3., 4.); let b = _mm256_setr_ps(5., 6., 7., 8., 5., 6., 7., 8.); let r = _mm256_addsub_ps(a, b); @@ -3426,7 +3592,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_sub_pd() { + const unsafe fn test_mm256_sub_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 6., 7., 8.); let r = _mm256_sub_pd(a, b); @@ -3435,7 +3601,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_sub_ps() { + const unsafe fn test_mm256_sub_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., -1., -2., -3., -4.); let b = _mm256_setr_ps(5., 6., 7., 8., 3., 2., 1., 0.); let r = _mm256_sub_ps(a, b); @@ -3458,7 +3624,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_floor_pd() { + const unsafe fn test_mm256_floor_pd() { let a = _mm256_setr_pd(1.55, 2.2, 3.99, -1.2); let result_down = _mm256_floor_pd(a); let expected_down = _mm256_setr_pd(1., 2., 3., -2.); @@ -3466,7 +3632,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_ceil_pd() { + const unsafe fn test_mm256_ceil_pd() { let a = _mm256_setr_pd(1.55, 2.2, 3.99, -1.2); let result_up = _mm256_ceil_pd(a); let expected_up = _mm256_setr_pd(2., 3., 4., -1.); @@ -3488,7 +3654,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_floor_ps() { + const unsafe fn test_mm256_floor_ps() { let a = _mm256_setr_ps(1.55, 2.2, 3.99, -1.2, 1.55, 2.2, 3.99, -1.2); let result_down = _mm256_floor_ps(a); let expected_down = _mm256_setr_ps(1., 2., 3., -2., 1., 2., 3., -2.); @@ -3496,7 +3662,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_ceil_ps() { + const unsafe fn test_mm256_ceil_ps() { let a = _mm256_setr_ps(1.55, 2.2, 3.99, -1.2, 1.55, 2.2, 3.99, -1.2); let result_up = _mm256_ceil_ps(a); let expected_up = _mm256_setr_ps(2., 3., 4., -1., 2., 3., 4., -1.); @@ -3520,7 +3686,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_div_ps() { + const unsafe fn test_mm256_div_ps() { let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.); let b = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let r = _mm256_div_ps(a, b); @@ -3529,7 +3695,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_div_pd() { + const unsafe fn test_mm256_div_pd() { let a = _mm256_setr_pd(4., 9., 16., 25.); let b = _mm256_setr_pd(4., 3., 2., 5.); let r = _mm256_div_pd(a, b); @@ -3538,7 +3704,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_blend_pd() { + const unsafe fn test_mm256_blend_pd() { let a = _mm256_setr_pd(4., 9., 16., 25.); let b = _mm256_setr_pd(4., 3., 2., 5.); let r = _mm256_blend_pd::<0x0>(a, b); @@ -3550,7 +3716,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_blend_ps() { + const unsafe fn test_mm256_blend_ps() { let a = _mm256_setr_ps(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm256_setr_ps(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm256_blend_ps::<0x0>(a, b); @@ -3562,7 +3728,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_blendv_pd() { + const unsafe fn test_mm256_blendv_pd() { let a = _mm256_setr_pd(4., 9., 16., 25.); let b = _mm256_setr_pd(4., 3., 2., 5.); let c = _mm256_setr_pd(0., 0., !0 as f64, !0 as f64); @@ -3572,7 +3738,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_blendv_ps() { + const unsafe fn test_mm256_blendv_ps() { let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.); let b = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); #[rustfmt::skip] @@ -3594,7 +3760,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_hadd_pd() { + const unsafe fn test_mm256_hadd_pd() { let a = _mm256_setr_pd(4., 9., 16., 25.); let b = _mm256_setr_pd(4., 3., 2., 5.); let r = _mm256_hadd_pd(a, b); @@ -3609,7 +3775,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_hadd_ps() { + const unsafe fn test_mm256_hadd_ps() { let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.); let b = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let r = _mm256_hadd_ps(a, b); @@ -3624,7 +3790,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_hsub_pd() { + const unsafe fn test_mm256_hsub_pd() { let a = _mm256_setr_pd(4., 9., 16., 25.); let b = _mm256_setr_pd(4., 3., 2., 5.); let r = _mm256_hsub_pd(a, b); @@ -3639,7 +3805,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_hsub_ps() { + const unsafe fn test_mm256_hsub_ps() { let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.); let b = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let r = _mm256_hsub_ps(a, b); @@ -3654,7 +3820,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_xor_pd() { + const unsafe fn test_mm256_xor_pd() { let a = _mm256_setr_pd(4., 9., 16., 25.); let b = _mm256_set1_pd(0.); let r = _mm256_xor_pd(a, b); @@ -3662,7 +3828,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_xor_ps() { + const unsafe fn test_mm256_xor_ps() { let a = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.); let b = _mm256_set1_ps(0.); let r = _mm256_xor_ps(a, b); @@ -3728,7 +3894,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_cvtepi32_pd() { + const unsafe fn test_mm256_cvtepi32_pd() { let a = _mm_setr_epi32(4, 9, 16, 25); let r = _mm256_cvtepi32_pd(a); let e = _mm256_setr_pd(4., 9., 16., 25.); @@ -3736,7 +3902,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_cvtepi32_ps() { + const unsafe fn test_mm256_cvtepi32_ps() { let a = _mm256_setr_epi32(4, 9, 16, 25, 4, 9, 16, 25); let r = _mm256_cvtepi32_ps(a); let e = _mm256_setr_ps(4., 9., 16., 25., 4., 9., 16., 25.); @@ -3744,7 +3910,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_cvtpd_ps() { + const unsafe fn test_mm256_cvtpd_ps() { let a = _mm256_setr_pd(4., 9., 16., 25.); let r = _mm256_cvtpd_ps(a); let e = _mm_setr_ps(4., 9., 16., 25.); @@ -3760,7 +3926,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_cvtps_pd() { + const unsafe fn test_mm256_cvtps_pd() { let a = _mm_setr_ps(4., 9., 16., 25.); let r = _mm256_cvtps_pd(a); let e = _mm256_setr_pd(4., 9., 16., 25.); @@ -3768,7 +3934,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_cvtsd_f64() { + const unsafe fn test_mm256_cvtsd_f64() { let a = _mm256_setr_pd(1., 2., 3., 4.); let r = _mm256_cvtsd_f64(a); assert_eq!(r, 1.); @@ -3799,7 +3965,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_extractf128_ps() { + const unsafe fn test_mm256_extractf128_ps() { let a = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let r = _mm256_extractf128_ps::<0>(a); let e = _mm_setr_ps(4., 3., 2., 5.); @@ -3807,7 +3973,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_extractf128_pd() { + const unsafe fn test_mm256_extractf128_pd() { let a = _mm256_setr_pd(4., 3., 2., 5.); let r = _mm256_extractf128_pd::<0>(a); let e = _mm_setr_pd(4., 3.); @@ -3815,7 +3981,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_extractf128_si256() { + const unsafe fn test_mm256_extractf128_si256() { let a = _mm256_setr_epi64x(4, 3, 2, 5); let r = _mm256_extractf128_si256::<0>(a); let e = _mm_setr_epi64x(4, 3); @@ -3823,7 +3989,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_extract_epi32() { + const unsafe fn test_mm256_extract_epi32() { let a = _mm256_setr_epi32(-1, 1, 2, 3, 4, 5, 6, 7); let r1 = _mm256_extract_epi32::<0>(a); let r2 = _mm256_extract_epi32::<3>(a); @@ -3832,7 +3998,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_cvtsi256_si32() { + const unsafe fn test_mm256_cvtsi256_si32() { let a = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_cvtsi256_si32(a); assert_eq!(r, 1); @@ -3869,7 +4035,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_permute_ps() { + const unsafe fn test_mm256_permute_ps() { let a = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let r = _mm256_permute_ps::<0x1b>(a); let e = _mm256_setr_ps(5., 2., 3., 4., 50., 64., 9., 8.); @@ -3877,7 +4043,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_permute_ps() { + const unsafe fn test_mm_permute_ps() { let a = _mm_setr_ps(4., 3., 2., 5.); let r = _mm_permute_ps::<0x1b>(a); let e = _mm_setr_ps(5., 2., 3., 4.); @@ -3903,7 +4069,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_permute_pd() { + const unsafe fn test_mm256_permute_pd() { let a = _mm256_setr_pd(4., 3., 2., 5.); let r = _mm256_permute_pd::<5>(a); let e = _mm256_setr_pd(3., 4., 5., 2.); @@ -3911,7 +4077,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_permute_pd() { + const unsafe fn test_mm_permute_pd() { let a = _mm_setr_pd(4., 3.); let r = _mm_permute_pd::<1>(a); let e = _mm_setr_pd(3., 4.); @@ -3919,7 +4085,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_permute2f128_ps() { + const unsafe fn test_mm256_permute2f128_ps() { let a = _mm256_setr_ps(11., 12., 13., 14., 15., 16., 17., 18.); let b = _mm256_setr_ps(21., 22., 23., 24., 25., 26., 27., 28.); let r = _mm256_permute2f128_ps::<0b0001_0011>(a, b); @@ -3933,7 +4099,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_permute2f128_pd() { + const unsafe fn test_mm256_permute2f128_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 6., 7., 8.); let r = _mm256_permute2f128_pd::<0b0011_0001>(a, b); @@ -3947,7 +4113,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_permute2f128_si256() { + const unsafe fn test_mm256_permute2f128_si256() { let a = _mm256_setr_epi32(11, 12, 13, 14, 15, 16, 17, 18); let b = _mm256_setr_epi32(21, 22, 23, 24, 25, 26, 27, 28); let r = _mm256_permute2f128_si256::<0b0010_0000>(a, b); @@ -3961,28 +4127,28 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_broadcast_ss() { + const unsafe fn test_mm256_broadcast_ss() { let r = _mm256_broadcast_ss(&3.); let e = _mm256_set1_ps(3.); assert_eq_m256(r, e); } #[simd_test(enable = "avx")] - unsafe fn test_mm_broadcast_ss() { + const unsafe fn test_mm_broadcast_ss() { let r = _mm_broadcast_ss(&3.); let e = _mm_set1_ps(3.); assert_eq_m128(r, e); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_broadcast_sd() { + const unsafe fn test_mm256_broadcast_sd() { let r = _mm256_broadcast_sd(&3.); let e = _mm256_set1_pd(3.); assert_eq_m256d(r, e); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_broadcast_ps() { + const unsafe fn test_mm256_broadcast_ps() { let a = _mm_setr_ps(4., 3., 2., 5.); let r = _mm256_broadcast_ps(&a); let e = _mm256_setr_ps(4., 3., 2., 5., 4., 3., 2., 5.); @@ -3990,7 +4156,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_broadcast_pd() { + const unsafe fn test_mm256_broadcast_pd() { let a = _mm_setr_pd(4., 3.); let r = _mm256_broadcast_pd(&a); let e = _mm256_setr_pd(4., 3., 4., 3.); @@ -3998,7 +4164,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_insertf128_ps() { + const unsafe fn test_mm256_insertf128_ps() { let a = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let b = _mm_setr_ps(4., 9., 16., 25.); let r = _mm256_insertf128_ps::<0>(a, b); @@ -4007,7 +4173,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_insertf128_pd() { + const unsafe fn test_mm256_insertf128_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm_setr_pd(5., 6.); let r = _mm256_insertf128_pd::<0>(a, b); @@ -4016,7 +4182,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_insertf128_si256() { + const unsafe fn test_mm256_insertf128_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let b = _mm_setr_epi64x(5, 6); let r = _mm256_insertf128_si256::<0>(a, b); @@ -4025,7 +4191,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_insert_epi8() { + const unsafe fn test_mm256_insert_epi8() { #[rustfmt::skip] let a = _mm256_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -4045,7 +4211,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_insert_epi16() { + const unsafe fn test_mm256_insert_epi16() { #[rustfmt::skip] let a = _mm256_setr_epi16( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4061,7 +4227,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_insert_epi32() { + const unsafe fn test_mm256_insert_epi32() { let a = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_insert_epi32::<7>(a, 0); let e = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0); @@ -4069,7 +4235,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_load_pd() { + const unsafe fn test_mm256_load_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let p = ptr::addr_of!(a) as *const f64; let r = _mm256_load_pd(p); @@ -4078,7 +4244,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_store_pd() { + const unsafe fn test_mm256_store_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let mut r = _mm256_undefined_pd(); _mm256_store_pd(ptr::addr_of_mut!(r) as *mut f64, a); @@ -4086,7 +4252,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_load_ps() { + const unsafe fn test_mm256_load_ps() { let a = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let p = ptr::addr_of!(a) as *const f32; let r = _mm256_load_ps(p); @@ -4095,7 +4261,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_store_ps() { + const unsafe fn test_mm256_store_ps() { let a = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let mut r = _mm256_undefined_ps(); _mm256_store_ps(ptr::addr_of_mut!(r) as *mut f32, a); @@ -4103,7 +4269,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_loadu_pd() { + const unsafe fn test_mm256_loadu_pd() { let a = &[1.0f64, 2., 3., 4.]; let p = a.as_ptr(); let r = _mm256_loadu_pd(black_box(p)); @@ -4112,7 +4278,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_storeu_pd() { + const unsafe fn test_mm256_storeu_pd() { let a = _mm256_set1_pd(9.); let mut r = _mm256_undefined_pd(); _mm256_storeu_pd(ptr::addr_of_mut!(r) as *mut f64, a); @@ -4120,7 +4286,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_loadu_ps() { + const unsafe fn test_mm256_loadu_ps() { let a = &[4., 3., 2., 5., 8., 9., 64., 50.]; let p = a.as_ptr(); let r = _mm256_loadu_ps(black_box(p)); @@ -4129,7 +4295,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_storeu_ps() { + const unsafe fn test_mm256_storeu_ps() { let a = _mm256_set1_ps(9.); let mut r = _mm256_undefined_ps(); _mm256_storeu_ps(ptr::addr_of_mut!(r) as *mut f32, a); @@ -4137,7 +4303,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_load_si256() { + const unsafe fn test_mm256_load_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let p = ptr::addr_of!(a); let r = _mm256_load_si256(p); @@ -4146,7 +4312,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_store_si256() { + const unsafe fn test_mm256_store_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let mut r = _mm256_undefined_si256(); _mm256_store_si256(ptr::addr_of_mut!(r), a); @@ -4154,7 +4320,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_loadu_si256() { + const unsafe fn test_mm256_loadu_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let p = ptr::addr_of!(a); let r = _mm256_loadu_si256(black_box(p)); @@ -4163,7 +4329,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_storeu_si256() { + const unsafe fn test_mm256_storeu_si256() { let a = _mm256_set1_epi8(9); let mut r = _mm256_undefined_si256(); _mm256_storeu_si256(ptr::addr_of_mut!(r), a); @@ -4171,7 +4337,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_maskload_pd() { + const unsafe fn test_mm256_maskload_pd() { let a = &[1.0f64, 2., 3., 4.]; let p = a.as_ptr(); let mask = _mm256_setr_epi64x(0, !0, 0, !0); @@ -4181,7 +4347,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_maskstore_pd() { + const unsafe fn test_mm256_maskstore_pd() { let mut r = _mm256_set1_pd(0.); let mask = _mm256_setr_epi64x(0, !0, 0, !0); let a = _mm256_setr_pd(1., 2., 3., 4.); @@ -4191,7 +4357,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_maskload_pd() { + const unsafe fn test_mm_maskload_pd() { let a = &[1.0f64, 2.]; let p = a.as_ptr(); let mask = _mm_setr_epi64x(0, !0); @@ -4201,7 +4367,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_maskstore_pd() { + const unsafe fn test_mm_maskstore_pd() { let mut r = _mm_set1_pd(0.); let mask = _mm_setr_epi64x(0, !0); let a = _mm_setr_pd(1., 2.); @@ -4211,7 +4377,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_maskload_ps() { + const unsafe fn test_mm256_maskload_ps() { let a = &[1.0f32, 2., 3., 4., 5., 6., 7., 8.]; let p = a.as_ptr(); let mask = _mm256_setr_epi32(0, !0, 0, !0, 0, !0, 0, !0); @@ -4221,7 +4387,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_maskstore_ps() { + const unsafe fn test_mm256_maskstore_ps() { let mut r = _mm256_set1_ps(0.); let mask = _mm256_setr_epi32(0, !0, 0, !0, 0, !0, 0, !0); let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); @@ -4231,7 +4397,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_maskload_ps() { + const unsafe fn test_mm_maskload_ps() { let a = &[1.0f32, 2., 3., 4.]; let p = a.as_ptr(); let mask = _mm_setr_epi32(0, !0, 0, !0); @@ -4241,7 +4407,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_maskstore_ps() { + const unsafe fn test_mm_maskstore_ps() { let mut r = _mm_set1_ps(0.); let mask = _mm_setr_epi32(0, !0, 0, !0); let a = _mm_setr_ps(1., 2., 3., 4.); @@ -4251,7 +4417,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_movehdup_ps() { + const unsafe fn test_mm256_movehdup_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_movehdup_ps(a); let e = _mm256_setr_ps(2., 2., 4., 4., 6., 6., 8., 8.); @@ -4259,7 +4425,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_moveldup_ps() { + const unsafe fn test_mm256_moveldup_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_moveldup_ps(a); let e = _mm256_setr_ps(1., 1., 3., 3., 5., 5., 7., 7.); @@ -4267,7 +4433,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_movedup_pd() { + const unsafe fn test_mm256_movedup_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let r = _mm256_movedup_pd(a); let e = _mm256_setr_pd(1., 1., 3., 3.); @@ -4370,7 +4536,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_unpackhi_pd() { + const unsafe fn test_mm256_unpackhi_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 6., 7., 8.); let r = _mm256_unpackhi_pd(a, b); @@ -4379,7 +4545,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_unpackhi_ps() { + const unsafe fn test_mm256_unpackhi_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_setr_ps(9., 10., 11., 12., 13., 14., 15., 16.); let r = _mm256_unpackhi_ps(a, b); @@ -4388,7 +4554,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_unpacklo_pd() { + const unsafe fn test_mm256_unpacklo_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 6., 7., 8.); let r = _mm256_unpacklo_pd(a, b); @@ -4397,7 +4563,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_unpacklo_ps() { + const unsafe fn test_mm256_unpacklo_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_setr_ps(9., 10., 11., 12., 13., 14., 15., 16.); let r = _mm256_unpacklo_ps(a, b); @@ -4406,7 +4572,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_testz_si256() { + const unsafe fn test_mm256_testz_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let b = _mm256_setr_epi64x(5, 6, 7, 8); let r = _mm256_testz_si256(a, b); @@ -4417,7 +4583,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_testc_si256() { + const unsafe fn test_mm256_testc_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let b = _mm256_setr_epi64x(5, 6, 7, 8); let r = _mm256_testc_si256(a, b); @@ -4475,7 +4641,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_testz_pd() { + const unsafe fn test_mm_testz_pd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 6.); let r = _mm_testz_pd(a, b); @@ -4486,7 +4652,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_testc_pd() { + const unsafe fn test_mm_testc_pd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 6.); let r = _mm_testc_pd(a, b); @@ -4541,7 +4707,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_testz_ps() { + const unsafe fn test_mm_testz_ps() { let a = _mm_set1_ps(1.); let r = _mm_testz_ps(a, a); assert_eq!(r, 1); @@ -4551,7 +4717,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm_testc_ps() { + const unsafe fn test_mm_testc_ps() { let a = _mm_set1_ps(1.); let r = _mm_testc_ps(a, a); assert_eq!(r, 1); @@ -4572,51 +4738,51 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_movemask_pd() { + const unsafe fn test_mm256_movemask_pd() { let a = _mm256_setr_pd(1., -2., 3., -4.); let r = _mm256_movemask_pd(a); assert_eq!(r, 0xA); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_movemask_ps() { + const unsafe fn test_mm256_movemask_ps() { let a = _mm256_setr_ps(1., -2., 3., -4., 1., -2., 3., -4.); let r = _mm256_movemask_ps(a); assert_eq!(r, 0xAA); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setzero_pd() { + const unsafe fn test_mm256_setzero_pd() { let r = _mm256_setzero_pd(); assert_eq_m256d(r, _mm256_set1_pd(0.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setzero_ps() { + const unsafe fn test_mm256_setzero_ps() { let r = _mm256_setzero_ps(); assert_eq_m256(r, _mm256_set1_ps(0.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setzero_si256() { + const unsafe fn test_mm256_setzero_si256() { let r = _mm256_setzero_si256(); assert_eq_m256i(r, _mm256_set1_epi8(0)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set_pd() { + const unsafe fn test_mm256_set_pd() { let r = _mm256_set_pd(1., 2., 3., 4.); assert_eq_m256d(r, _mm256_setr_pd(4., 3., 2., 1.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set_ps() { + const unsafe fn test_mm256_set_ps() { let r = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); assert_eq_m256(r, _mm256_setr_ps(8., 7., 6., 5., 4., 3., 2., 1.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set_epi8() { + const unsafe fn test_mm256_set_epi8() { #[rustfmt::skip] let r = _mm256_set_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -4635,7 +4801,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set_epi16() { + const unsafe fn test_mm256_set_epi16() { #[rustfmt::skip] let r = _mm256_set_epi16( 1, 2, 3, 4, 5, 6, 7, 8, @@ -4650,31 +4816,31 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set_epi32() { + const unsafe fn test_mm256_set_epi32() { let r = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); assert_eq_m256i(r, _mm256_setr_epi32(8, 7, 6, 5, 4, 3, 2, 1)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set_epi64x() { + const unsafe fn test_mm256_set_epi64x() { let r = _mm256_set_epi64x(1, 2, 3, 4); assert_eq_m256i(r, _mm256_setr_epi64x(4, 3, 2, 1)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setr_pd() { + const unsafe fn test_mm256_setr_pd() { let r = _mm256_setr_pd(1., 2., 3., 4.); assert_eq_m256d(r, _mm256_setr_pd(1., 2., 3., 4.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setr_ps() { + const unsafe fn test_mm256_setr_ps() { let r = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); assert_eq_m256(r, _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setr_epi8() { + const unsafe fn test_mm256_setr_epi8() { #[rustfmt::skip] let r = _mm256_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -4694,7 +4860,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setr_epi16() { + const unsafe fn test_mm256_setr_epi16() { #[rustfmt::skip] let r = _mm256_setr_epi16( 1, 2, 3, 4, 5, 6, 7, 8, @@ -4709,55 +4875,55 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setr_epi32() { + const unsafe fn test_mm256_setr_epi32() { let r = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); assert_eq_m256i(r, _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setr_epi64x() { + const unsafe fn test_mm256_setr_epi64x() { let r = _mm256_setr_epi64x(1, 2, 3, 4); assert_eq_m256i(r, _mm256_setr_epi64x(1, 2, 3, 4)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set1_pd() { + const unsafe fn test_mm256_set1_pd() { let r = _mm256_set1_pd(1.); assert_eq_m256d(r, _mm256_set1_pd(1.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set1_ps() { + const unsafe fn test_mm256_set1_ps() { let r = _mm256_set1_ps(1.); assert_eq_m256(r, _mm256_set1_ps(1.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set1_epi8() { + const unsafe fn test_mm256_set1_epi8() { let r = _mm256_set1_epi8(1); assert_eq_m256i(r, _mm256_set1_epi8(1)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set1_epi16() { + const unsafe fn test_mm256_set1_epi16() { let r = _mm256_set1_epi16(1); assert_eq_m256i(r, _mm256_set1_epi16(1)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set1_epi32() { + const unsafe fn test_mm256_set1_epi32() { let r = _mm256_set1_epi32(1); assert_eq_m256i(r, _mm256_set1_epi32(1)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set1_epi64x() { + const unsafe fn test_mm256_set1_epi64x() { let r = _mm256_set1_epi64x(1); assert_eq_m256i(r, _mm256_set1_epi64x(1)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castpd_ps() { + const unsafe fn test_mm256_castpd_ps() { let a = _mm256_setr_pd(1., 2., 3., 4.); let r = _mm256_castpd_ps(a); let e = _mm256_setr_ps(0., 1.875, 0., 2., 0., 2.125, 0., 2.25); @@ -4765,7 +4931,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castps_pd() { + const unsafe fn test_mm256_castps_pd() { let a = _mm256_setr_ps(0., 1.875, 0., 2., 0., 2.125, 0., 2.25); let r = _mm256_castps_pd(a); let e = _mm256_setr_pd(1., 2., 3., 4.); @@ -4773,7 +4939,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castps_si256() { + const unsafe fn test_mm256_castps_si256() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_castps_si256(a); #[rustfmt::skip] @@ -4787,7 +4953,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castsi256_ps() { + const unsafe fn test_mm256_castsi256_ps() { #[rustfmt::skip] let a = _mm256_setr_epi8( 0, 0, -128, 63, 0, 0, 0, 64, @@ -4801,63 +4967,63 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castpd_si256() { + const unsafe fn test_mm256_castpd_si256() { let a = _mm256_setr_pd(1., 2., 3., 4.); let r = _mm256_castpd_si256(a); assert_eq_m256d(transmute(r), a); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castsi256_pd() { + const unsafe fn test_mm256_castsi256_pd() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let r = _mm256_castsi256_pd(a); assert_eq_m256d(r, transmute(a)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castps256_ps128() { + const unsafe fn test_mm256_castps256_ps128() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_castps256_ps128(a); assert_eq_m128(r, _mm_setr_ps(1., 2., 3., 4.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castpd256_pd128() { + const unsafe fn test_mm256_castpd256_pd128() { let a = _mm256_setr_pd(1., 2., 3., 4.); let r = _mm256_castpd256_pd128(a); assert_eq_m128d(r, _mm_setr_pd(1., 2.)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castsi256_si128() { + const unsafe fn test_mm256_castsi256_si128() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let r = _mm256_castsi256_si128(a); assert_eq_m128i(r, _mm_setr_epi64x(1, 2)); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castps128_ps256() { + const unsafe fn test_mm256_castps128_ps256() { let a = _mm_setr_ps(1., 2., 3., 4.); let r = _mm256_castps128_ps256(a); assert_eq_m128(_mm256_castps256_ps128(r), a); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castpd128_pd256() { + const unsafe fn test_mm256_castpd128_pd256() { let a = _mm_setr_pd(1., 2.); let r = _mm256_castpd128_pd256(a); assert_eq_m128d(_mm256_castpd256_pd128(r), a); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_castsi128_si256() { + const unsafe fn test_mm256_castsi128_si256() { let a = _mm_setr_epi32(1, 2, 3, 4); let r = _mm256_castsi128_si256(a); assert_eq_m128i(_mm256_castsi256_si128(r), a); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_zextps128_ps256() { + const unsafe fn test_mm256_zextps128_ps256() { let a = _mm_setr_ps(1., 2., 3., 4.); let r = _mm256_zextps128_ps256(a); let e = _mm256_setr_ps(1., 2., 3., 4., 0., 0., 0., 0.); @@ -4865,7 +5031,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_zextsi128_si256() { + const unsafe fn test_mm256_zextsi128_si256() { let a = _mm_setr_epi64x(1, 2); let r = _mm256_zextsi128_si256(a); let e = _mm256_setr_epi64x(1, 2, 0, 0); @@ -4873,7 +5039,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_zextpd128_pd256() { + const unsafe fn test_mm256_zextpd128_pd256() { let a = _mm_setr_pd(1., 2.); let r = _mm256_zextpd128_pd256(a); let e = _mm256_setr_pd(1., 2., 0., 0.); @@ -4881,7 +5047,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set_m128() { + const unsafe fn test_mm256_set_m128() { let hi = _mm_setr_ps(5., 6., 7., 8.); let lo = _mm_setr_ps(1., 2., 3., 4.); let r = _mm256_set_m128(hi, lo); @@ -4890,7 +5056,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set_m128d() { + const unsafe fn test_mm256_set_m128d() { let hi = _mm_setr_pd(3., 4.); let lo = _mm_setr_pd(1., 2.); let r = _mm256_set_m128d(hi, lo); @@ -4899,7 +5065,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_set_m128i() { + const unsafe fn test_mm256_set_m128i() { #[rustfmt::skip] let hi = _mm_setr_epi8( 17, 18, 19, 20, @@ -4926,7 +5092,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setr_m128() { + const unsafe fn test_mm256_setr_m128() { let lo = _mm_setr_ps(1., 2., 3., 4.); let hi = _mm_setr_ps(5., 6., 7., 8.); let r = _mm256_setr_m128(lo, hi); @@ -4935,7 +5101,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setr_m128d() { + const unsafe fn test_mm256_setr_m128d() { let lo = _mm_setr_pd(1., 2.); let hi = _mm_setr_pd(3., 4.); let r = _mm256_setr_m128d(lo, hi); @@ -4944,7 +5110,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_setr_m128i() { + const unsafe fn test_mm256_setr_m128i() { #[rustfmt::skip] let lo = _mm_setr_epi8( 1, 2, 3, 4, @@ -4969,7 +5135,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_loadu2_m128() { + const unsafe fn test_mm256_loadu2_m128() { let hi = &[5., 6., 7., 8.]; let hiaddr = hi.as_ptr(); let lo = &[1., 2., 3., 4.]; @@ -4980,7 +5146,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_loadu2_m128d() { + const unsafe fn test_mm256_loadu2_m128d() { let hi = &[3., 4.]; let hiaddr = hi.as_ptr(); let lo = &[1., 2.]; @@ -4991,7 +5157,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_loadu2_m128i() { + const unsafe fn test_mm256_loadu2_m128i() { #[rustfmt::skip] let hi = _mm_setr_epi8( 17, 18, 19, 20, 21, 22, 23, 24, @@ -5014,7 +5180,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_storeu2_m128() { + const unsafe fn test_mm256_storeu2_m128() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let mut hi = _mm_undefined_ps(); let mut lo = _mm_undefined_ps(); @@ -5028,7 +5194,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_storeu2_m128d() { + const unsafe fn test_mm256_storeu2_m128d() { let a = _mm256_setr_pd(1., 2., 3., 4.); let mut hi = _mm_undefined_pd(); let mut lo = _mm_undefined_pd(); @@ -5042,7 +5208,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_storeu2_m128i() { + const unsafe fn test_mm256_storeu2_m128i() { #[rustfmt::skip] let a = _mm256_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -5069,7 +5235,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_cvtss_f32() { + const unsafe fn test_mm256_cvtss_f32() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_cvtss_f32(a); assert_eq!(r, 1.); diff --git a/library/stdarch/crates/core_arch/src/x86_64/avx.rs b/library/stdarch/crates/core_arch/src/x86_64/avx.rs index b494385e4a61..bb8d25620714 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/avx.rs @@ -24,7 +24,8 @@ use crate::{core_arch::x86::*, mem::transmute}; #[target_feature(enable = "avx")] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_insert_epi64(a: __m256i, i: i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_insert_epi64(a: __m256i, i: i64) -> __m256i { static_assert_uimm_bits!(INDEX, 2); unsafe { transmute(simd_insert!(a.as_i64x4(), INDEX as u32, i)) } } @@ -37,19 +38,21 @@ pub fn _mm256_insert_epi64(a: __m256i, i: i64) -> __m256i { #[rustc_legacy_const_generics(1)] // This intrinsic has no corresponding instruction. #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_extract_epi64(a: __m256i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extract_epi64(a: __m256i) -> i64 { static_assert_uimm_bits!(INDEX, 2); unsafe { simd_extract!(a.as_i64x4(), INDEX as u32) } } #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::arch::x86_64::*; #[simd_test(enable = "avx")] - unsafe fn test_mm256_insert_epi64() { + const unsafe fn test_mm256_insert_epi64() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let r = _mm256_insert_epi64::<3>(a, 0); let e = _mm256_setr_epi64x(1, 2, 3, 0); @@ -57,7 +60,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_extract_epi64() { + const unsafe fn test_mm256_extract_epi64() { let a = _mm256_setr_epi64x(0, 1, 2, 3); let r = _mm256_extract_epi64::<3>(a); assert_eq!(r, 3); From 2d768ea921132aca1dcb9eb13a1dcc449ece2b80 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 19:13:18 +0530 Subject: [PATCH 0232/3801] Make `avx2` functions const --- .../stdarch/crates/core_arch/src/x86/avx2.rs | 661 +++++++++++------- 1 file changed, 399 insertions(+), 262 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 3734915b709f..b3b2accd7338 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -31,7 +31,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpabsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_abs_epi32(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_abs_epi32(a: __m256i) -> __m256i { unsafe { let a = a.as_i32x8(); let r = simd_select::(simd_lt(a, i32x8::ZERO), simd_neg(a), a); @@ -46,7 +47,8 @@ pub fn _mm256_abs_epi32(a: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpabsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_abs_epi16(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_abs_epi16(a: __m256i) -> __m256i { unsafe { let a = a.as_i16x16(); let r = simd_select::(simd_lt(a, i16x16::ZERO), simd_neg(a), a); @@ -61,7 +63,8 @@ pub fn _mm256_abs_epi16(a: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpabsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_abs_epi8(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_abs_epi8(a: __m256i) -> __m256i { unsafe { let a = a.as_i8x32(); let r = simd_select::(simd_lt(a, i8x32::ZERO), simd_neg(a), a); @@ -76,7 +79,8 @@ pub fn _mm256_abs_epi8(a: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpaddq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_add_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_add_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_add(a.as_i64x4(), b.as_i64x4())) } } @@ -87,7 +91,8 @@ pub fn _mm256_add_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpaddd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_add_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_add_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_add(a.as_i32x8(), b.as_i32x8())) } } @@ -98,7 +103,8 @@ pub fn _mm256_add_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpaddw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_add_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_add_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_add(a.as_i16x16(), b.as_i16x16())) } } @@ -109,7 +115,8 @@ pub fn _mm256_add_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpaddb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_add_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_add_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_add(a.as_i8x32(), b.as_i8x32())) } } @@ -120,7 +127,8 @@ pub fn _mm256_add_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpaddsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_adds_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_adds_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_saturating_add(a.as_i8x32(), b.as_i8x32())) } } @@ -131,7 +139,8 @@ pub fn _mm256_adds_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpaddsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_adds_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_adds_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_saturating_add(a.as_i16x16(), b.as_i16x16())) } } @@ -142,7 +151,8 @@ pub fn _mm256_adds_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpaddusb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_adds_epu8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_adds_epu8(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_saturating_add(a.as_u8x32(), b.as_u8x32())) } } @@ -153,7 +163,8 @@ pub fn _mm256_adds_epu8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpaddusw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_adds_epu16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_adds_epu16(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_saturating_add(a.as_u16x16(), b.as_u16x16())) } } @@ -166,7 +177,8 @@ pub fn _mm256_adds_epu16(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 7))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_alignr_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_alignr_epi8(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); // If palignr is shifting the pair of vectors more than the size of two @@ -247,7 +259,8 @@ pub fn _mm256_alignr_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vandps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_and_si256(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_and_si256(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_and(a.as_i64x4(), b.as_i64x4())) } } @@ -259,7 +272,8 @@ pub fn _mm256_and_si256(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vandnps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_andnot_si256(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_andnot_si256(a: __m256i, b: __m256i) -> __m256i { unsafe { let all_ones = _mm256_set1_epi8(-1); transmute(simd_and( @@ -276,7 +290,8 @@ pub fn _mm256_andnot_si256(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpavgw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_avg_epu16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_avg_epu16(a: __m256i, b: __m256i) -> __m256i { unsafe { let a = simd_cast::<_, u32x16>(a.as_u16x16()); let b = simd_cast::<_, u32x16>(b.as_u16x16()); @@ -292,7 +307,8 @@ pub fn _mm256_avg_epu16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpavgb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_avg_epu8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_avg_epu8(a: __m256i, b: __m256i) -> __m256i { unsafe { let a = simd_cast::<_, u16x32>(a.as_u8x32()); let b = simd_cast::<_, u16x32>(b.as_u8x32()); @@ -309,7 +325,8 @@ pub fn _mm256_avg_epu8(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vblendps, IMM4 = 9))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_blend_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_blend_epi32(a: __m128i, b: __m128i) -> __m128i { static_assert_uimm_bits!(IMM4, 4); unsafe { let a = a.as_i32x4(); @@ -336,7 +353,8 @@ pub fn _mm_blend_epi32(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(vblendps, IMM8 = 9))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_blend_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_blend_epi32(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { let a = a.as_i32x8(); @@ -367,7 +385,8 @@ pub fn _mm256_blend_epi32(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpblendw, IMM8 = 9))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_blend_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_blend_epi16(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { let a = a.as_i16x16(); @@ -406,7 +425,8 @@ pub fn _mm256_blend_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpblendvb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_blendv_epi8(a: __m256i, b: __m256i, mask: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_blendv_epi8(a: __m256i, b: __m256i, mask: __m256i) -> __m256i { unsafe { let mask: i8x32 = simd_lt(mask.as_i8x32(), i8x32::ZERO); transmute(simd_select(mask, b.as_i8x32(), a.as_i8x32())) @@ -421,7 +441,8 @@ pub fn _mm256_blendv_epi8(a: __m256i, b: __m256i, mask: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpbroadcastb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_broadcastb_epi8(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcastb_epi8(a: __m128i) -> __m128i { unsafe { let ret = simd_shuffle!(a.as_i8x16(), i8x16::ZERO, [0_u32; 16]); transmute::(ret) @@ -436,7 +457,8 @@ pub fn _mm_broadcastb_epi8(a: __m128i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpbroadcastb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_broadcastb_epi8(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcastb_epi8(a: __m128i) -> __m256i { unsafe { let ret = simd_shuffle!(a.as_i8x16(), i8x16::ZERO, [0_u32; 32]); transmute::(ret) @@ -453,7 +475,8 @@ pub fn _mm256_broadcastb_epi8(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_broadcastd_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcastd_epi32(a: __m128i) -> __m128i { unsafe { let ret = simd_shuffle!(a.as_i32x4(), i32x4::ZERO, [0_u32; 4]); transmute::(ret) @@ -470,7 +493,8 @@ pub fn _mm_broadcastd_epi32(a: __m128i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_broadcastd_epi32(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcastd_epi32(a: __m128i) -> __m256i { unsafe { let ret = simd_shuffle!(a.as_i32x4(), i32x4::ZERO, [0_u32; 8]); transmute::(ret) @@ -487,7 +511,8 @@ pub fn _mm256_broadcastd_epi32(a: __m128i) -> __m256i { // See https://github.com/rust-lang/stdarch/issues/791 #[cfg_attr(test, assert_instr(vmovddup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_broadcastq_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcastq_epi64(a: __m128i) -> __m128i { unsafe { let ret = simd_shuffle!(a.as_i64x2(), a.as_i64x2(), [0_u32; 2]); transmute::(ret) @@ -502,7 +527,8 @@ pub fn _mm_broadcastq_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vbroadcastsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_broadcastq_epi64(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcastq_epi64(a: __m128i) -> __m256i { unsafe { let ret = simd_shuffle!(a.as_i64x2(), a.as_i64x2(), [0_u32; 4]); transmute::(ret) @@ -517,7 +543,8 @@ pub fn _mm256_broadcastq_epi64(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vmovddup))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_broadcastsd_pd(a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcastsd_pd(a: __m128d) -> __m128d { unsafe { simd_shuffle!(a, _mm_setzero_pd(), [0_u32; 2]) } } @@ -529,7 +556,8 @@ pub fn _mm_broadcastsd_pd(a: __m128d) -> __m128d { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vbroadcastsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_broadcastsd_pd(a: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcastsd_pd(a: __m128d) -> __m256d { unsafe { simd_shuffle!(a, _mm_setzero_pd(), [0_u32; 4]) } } @@ -540,7 +568,8 @@ pub fn _mm256_broadcastsd_pd(a: __m128d) -> __m256d { #[inline] #[target_feature(enable = "avx2")] #[stable(feature = "simd_x86_updates", since = "1.82.0")] -pub fn _mm_broadcastsi128_si256(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcastsi128_si256(a: __m128i) -> __m256i { unsafe { let ret = simd_shuffle!(a.as_i64x2(), i64x2::ZERO, [0, 1, 0, 1]); transmute::(ret) @@ -556,7 +585,8 @@ pub fn _mm_broadcastsi128_si256(a: __m128i) -> __m256i { #[inline] #[target_feature(enable = "avx2")] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_broadcastsi128_si256(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcastsi128_si256(a: __m128i) -> __m256i { unsafe { let ret = simd_shuffle!(a.as_i64x2(), i64x2::ZERO, [0, 1, 0, 1]); transmute::(ret) @@ -571,7 +601,8 @@ pub fn _mm256_broadcastsi128_si256(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_broadcastss_ps(a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcastss_ps(a: __m128) -> __m128 { unsafe { simd_shuffle!(a, _mm_setzero_ps(), [0_u32; 4]) } } @@ -583,7 +614,8 @@ pub fn _mm_broadcastss_ps(a: __m128) -> __m128 { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_broadcastss_ps(a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcastss_ps(a: __m128) -> __m256 { unsafe { simd_shuffle!(a, _mm_setzero_ps(), [0_u32; 8]) } } @@ -595,7 +627,8 @@ pub fn _mm256_broadcastss_ps(a: __m128) -> __m256 { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpbroadcastw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_broadcastw_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcastw_epi16(a: __m128i) -> __m128i { unsafe { let ret = simd_shuffle!(a.as_i16x8(), i16x8::ZERO, [0_u32; 8]); transmute::(ret) @@ -610,7 +643,8 @@ pub fn _mm_broadcastw_epi16(a: __m128i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpbroadcastw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_broadcastw_epi16(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcastw_epi16(a: __m128i) -> __m256i { unsafe { let ret = simd_shuffle!(a.as_i16x8(), i16x8::ZERO, [0_u32; 16]); transmute::(ret) @@ -624,7 +658,8 @@ pub fn _mm256_broadcastw_epi16(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpcmpeqq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cmpeq_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute::(simd_eq(a.as_i64x4(), b.as_i64x4())) } } @@ -635,7 +670,8 @@ pub fn _mm256_cmpeq_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpcmpeqd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cmpeq_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute::(simd_eq(a.as_i32x8(), b.as_i32x8())) } } @@ -646,7 +682,8 @@ pub fn _mm256_cmpeq_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpcmpeqw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cmpeq_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute::(simd_eq(a.as_i16x16(), b.as_i16x16())) } } @@ -657,7 +694,8 @@ pub fn _mm256_cmpeq_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpcmpeqb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cmpeq_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute::(simd_eq(a.as_i8x32(), b.as_i8x32())) } } @@ -668,7 +706,8 @@ pub fn _mm256_cmpeq_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpcmpgtq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cmpgt_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute::(simd_gt(a.as_i64x4(), b.as_i64x4())) } } @@ -679,7 +718,8 @@ pub fn _mm256_cmpgt_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpcmpgtd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cmpgt_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute::(simd_gt(a.as_i32x8(), b.as_i32x8())) } } @@ -690,7 +730,8 @@ pub fn _mm256_cmpgt_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpcmpgtw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cmpgt_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute::(simd_gt(a.as_i16x16(), b.as_i16x16())) } } @@ -701,7 +742,8 @@ pub fn _mm256_cmpgt_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpcmpgtb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cmpgt_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute::(simd_gt(a.as_i8x32(), b.as_i8x32())) } } @@ -712,7 +754,8 @@ pub fn _mm256_cmpgt_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovsxwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepi16_epi32(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi16_epi32(a: __m128i) -> __m256i { unsafe { transmute::(simd_cast(a.as_i16x8())) } } @@ -723,7 +766,8 @@ pub fn _mm256_cvtepi16_epi32(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovsxwq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepi16_epi64(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi16_epi64(a: __m128i) -> __m256i { unsafe { let a = a.as_i16x8(); let v64: i16x4 = simd_shuffle!(a, a, [0, 1, 2, 3]); @@ -738,7 +782,8 @@ pub fn _mm256_cvtepi16_epi64(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovsxdq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepi32_epi64(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi32_epi64(a: __m128i) -> __m256i { unsafe { transmute::(simd_cast(a.as_i32x4())) } } @@ -749,7 +794,8 @@ pub fn _mm256_cvtepi32_epi64(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovsxbw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepi8_epi16(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi8_epi16(a: __m128i) -> __m256i { unsafe { transmute::(simd_cast(a.as_i8x16())) } } @@ -760,7 +806,8 @@ pub fn _mm256_cvtepi8_epi16(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovsxbd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepi8_epi32(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi8_epi32(a: __m128i) -> __m256i { unsafe { let a = a.as_i8x16(); let v64: i8x8 = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -775,7 +822,8 @@ pub fn _mm256_cvtepi8_epi32(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovsxbq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepi8_epi64(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi8_epi64(a: __m128i) -> __m256i { unsafe { let a = a.as_i8x16(); let v32: i8x4 = simd_shuffle!(a, a, [0, 1, 2, 3]); @@ -791,7 +839,8 @@ pub fn _mm256_cvtepi8_epi64(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovzxwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepu16_epi32(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepu16_epi32(a: __m128i) -> __m256i { unsafe { transmute::(simd_cast(a.as_u16x8())) } } @@ -803,7 +852,8 @@ pub fn _mm256_cvtepu16_epi32(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovzxwq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepu16_epi64(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepu16_epi64(a: __m128i) -> __m256i { unsafe { let a = a.as_u16x8(); let v64: u16x4 = simd_shuffle!(a, a, [0, 1, 2, 3]); @@ -818,7 +868,8 @@ pub fn _mm256_cvtepu16_epi64(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovzxdq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepu32_epi64(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepu32_epi64(a: __m128i) -> __m256i { unsafe { transmute::(simd_cast(a.as_u32x4())) } } @@ -829,7 +880,8 @@ pub fn _mm256_cvtepu32_epi64(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovzxbw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepu8_epi16(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepu8_epi16(a: __m128i) -> __m256i { unsafe { transmute::(simd_cast(a.as_u8x16())) } } @@ -841,7 +893,8 @@ pub fn _mm256_cvtepu8_epi16(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovzxbd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepu8_epi32(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepu8_epi32(a: __m128i) -> __m256i { unsafe { let a = a.as_u8x16(); let v64: u8x8 = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -857,7 +910,8 @@ pub fn _mm256_cvtepu8_epi32(a: __m128i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovzxbq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_cvtepu8_epi64(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepu8_epi64(a: __m128i) -> __m256i { unsafe { let a = a.as_u8x16(); let v32: u8x4 = simd_shuffle!(a, a, [0, 1, 2, 3]); @@ -873,7 +927,8 @@ pub fn _mm256_cvtepu8_epi64(a: __m128i) -> __m256i { #[cfg_attr(test, assert_instr(vextractf128, IMM1 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_extracti128_si256(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extracti128_si256(a: __m256i) -> __m128i { static_assert_uimm_bits!(IMM1, 1); unsafe { let a = a.as_i64x4(); @@ -890,7 +945,8 @@ pub fn _mm256_extracti128_si256(a: __m256i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vphaddw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_hadd_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_hadd_epi16(a: __m256i, b: __m256i) -> __m256i { let a = a.as_i16x16(); let b = b.as_i16x16(); unsafe { @@ -915,7 +971,8 @@ pub fn _mm256_hadd_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vphaddd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_hadd_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_hadd_epi32(a: __m256i, b: __m256i) -> __m256i { let a = a.as_i32x8(); let b = b.as_i32x8(); unsafe { @@ -944,7 +1001,8 @@ pub fn _mm256_hadds_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vphsubw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_hsub_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_hsub_epi16(a: __m256i, b: __m256i) -> __m256i { let a = a.as_i16x16(); let b = b.as_i16x16(); unsafe { @@ -969,7 +1027,8 @@ pub fn _mm256_hsub_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vphsubd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_hsub_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_hsub_epi32(a: __m256i, b: __m256i) -> __m256i { let a = a.as_i32x8(); let b = b.as_i32x8(); unsafe { @@ -1734,7 +1793,8 @@ pub unsafe fn _mm256_mask_i64gather_pd( #[cfg_attr(test, assert_instr(vinsertf128, IMM1 = 1))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_inserti128_si256(a: __m256i, b: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_inserti128_si256(a: __m256i, b: __m128i) -> __m256i { static_assert_uimm_bits!(IMM1, 1); unsafe { let a = a.as_i64x4(); @@ -1753,7 +1813,8 @@ pub fn _mm256_inserti128_si256(a: __m256i, b: __m128i) -> __m25 #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { let r: i32x16 = simd_mul(simd_cast(a.as_i16x16()), simd_cast(b.as_i16x16())); let even: i32x8 = simd_shuffle!(r, r, [0, 2, 4, 6, 8, 10, 12, 14]); @@ -1785,7 +1846,8 @@ pub fn _mm256_maddubs_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaskmovd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_maskload_epi32(mem_addr: *const i32, mask: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskload_epi32(mem_addr: *const i32, mask: __m128i) -> __m128i { let mask = simd_shr(mask.as_i32x4(), i32x4::splat(31)); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, i32x4::ZERO).as_m128i() } @@ -1799,7 +1861,8 @@ pub unsafe fn _mm_maskload_epi32(mem_addr: *const i32, mask: __m128i) -> __m128i #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaskmovd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_maskload_epi32(mem_addr: *const i32, mask: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskload_epi32(mem_addr: *const i32, mask: __m256i) -> __m256i { let mask = simd_shr(mask.as_i32x8(), i32x8::splat(31)); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, i32x8::ZERO).as_m256i() } @@ -1813,7 +1876,8 @@ pub unsafe fn _mm256_maskload_epi32(mem_addr: *const i32, mask: __m256i) -> __m2 #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaskmovq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_maskload_epi64(mem_addr: *const i64, mask: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskload_epi64(mem_addr: *const i64, mask: __m128i) -> __m128i { let mask = simd_shr(mask.as_i64x2(), i64x2::splat(63)); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, i64x2::ZERO).as_m128i() } @@ -1827,7 +1891,8 @@ pub unsafe fn _mm_maskload_epi64(mem_addr: *const i64, mask: __m128i) -> __m128i #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaskmovq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_maskload_epi64(mem_addr: *const i64, mask: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskload_epi64(mem_addr: *const i64, mask: __m256i) -> __m256i { let mask = simd_shr(mask.as_i64x4(), i64x4::splat(63)); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, i64x4::ZERO).as_m256i() } @@ -1841,7 +1906,8 @@ pub unsafe fn _mm256_maskload_epi64(mem_addr: *const i64, mask: __m256i) -> __m2 #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaskmovd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_maskstore_epi32(mem_addr: *mut i32, mask: __m128i, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskstore_epi32(mem_addr: *mut i32, mask: __m128i, a: __m128i) { let mask = simd_shr(mask.as_i32x4(), i32x4::splat(31)); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i32x4()) } @@ -1855,7 +1921,8 @@ pub unsafe fn _mm_maskstore_epi32(mem_addr: *mut i32, mask: __m128i, a: __m128i) #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaskmovd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_maskstore_epi32(mem_addr: *mut i32, mask: __m256i, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskstore_epi32(mem_addr: *mut i32, mask: __m256i, a: __m256i) { let mask = simd_shr(mask.as_i32x8(), i32x8::splat(31)); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i32x8()) } @@ -1869,7 +1936,8 @@ pub unsafe fn _mm256_maskstore_epi32(mem_addr: *mut i32, mask: __m256i, a: __m25 #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaskmovq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm_maskstore_epi64(mem_addr: *mut i64, mask: __m128i, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskstore_epi64(mem_addr: *mut i64, mask: __m128i, a: __m128i) { let mask = simd_shr(mask.as_i64x2(), i64x2::splat(63)); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i64x2()) } @@ -1883,7 +1951,8 @@ pub unsafe fn _mm_maskstore_epi64(mem_addr: *mut i64, mask: __m128i, a: __m128i) #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaskmovq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_maskstore_epi64(mem_addr: *mut i64, mask: __m256i, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskstore_epi64(mem_addr: *mut i64, mask: __m256i, a: __m256i) { let mask = simd_shr(mask.as_i64x4(), i64x4::splat(63)); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i64x4()) } @@ -1896,7 +1965,8 @@ pub unsafe fn _mm256_maskstore_epi64(mem_addr: *mut i64, mask: __m256i, a: __m25 #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaxsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_max_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_max_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imax(a.as_i16x16(), b.as_i16x16()).as_m256i() } } @@ -1908,7 +1978,8 @@ pub fn _mm256_max_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaxsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_max_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_max_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imax(a.as_i32x8(), b.as_i32x8()).as_m256i() } } @@ -1920,7 +1991,8 @@ pub fn _mm256_max_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaxsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_max_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_max_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imax(a.as_i8x32(), b.as_i8x32()).as_m256i() } } @@ -1932,7 +2004,8 @@ pub fn _mm256_max_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaxuw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_max_epu16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_max_epu16(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imax(a.as_u16x16(), b.as_u16x16()).as_m256i() } } @@ -1944,7 +2017,8 @@ pub fn _mm256_max_epu16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaxud))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_max_epu32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_max_epu32(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imax(a.as_u32x8(), b.as_u32x8()).as_m256i() } } @@ -1956,7 +2030,8 @@ pub fn _mm256_max_epu32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaxub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_max_epu8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_max_epu8(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imax(a.as_u8x32(), b.as_u8x32()).as_m256i() } } @@ -1968,7 +2043,8 @@ pub fn _mm256_max_epu8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpminsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_min_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_min_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imin(a.as_i16x16(), b.as_i16x16()).as_m256i() } } @@ -1980,7 +2056,8 @@ pub fn _mm256_min_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpminsd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_min_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_min_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imin(a.as_i32x8(), b.as_i32x8()).as_m256i() } } @@ -1992,7 +2069,8 @@ pub fn _mm256_min_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpminsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_min_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_min_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imin(a.as_i8x32(), b.as_i8x32()).as_m256i() } } @@ -2004,7 +2082,8 @@ pub fn _mm256_min_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpminuw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_min_epu16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_min_epu16(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imin(a.as_u16x16(), b.as_u16x16()).as_m256i() } } @@ -2016,7 +2095,8 @@ pub fn _mm256_min_epu16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpminud))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_min_epu32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_min_epu32(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imin(a.as_u32x8(), b.as_u32x8()).as_m256i() } } @@ -2028,7 +2108,8 @@ pub fn _mm256_min_epu32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpminub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_min_epu8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_min_epu8(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imin(a.as_u8x32(), b.as_u8x32()).as_m256i() } } @@ -2040,7 +2121,8 @@ pub fn _mm256_min_epu8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmovmskb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_movemask_epi8(a: __m256i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movemask_epi8(a: __m256i) -> i32 { unsafe { let z = i8x32::ZERO; let m: i8x32 = simd_lt(a.as_i8x32(), z); @@ -2077,7 +2159,8 @@ pub fn _mm256_mpsadbw_epu8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmuldq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_mul_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mul_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { let a = simd_cast::<_, i64x4>(simd_cast::<_, i32x4>(a.as_i64x4())); let b = simd_cast::<_, i64x4>(simd_cast::<_, i32x4>(b.as_i64x4())); @@ -2095,11 +2178,12 @@ pub fn _mm256_mul_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmuludq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_mul_epu32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mul_epu32(a: __m256i, b: __m256i) -> __m256i { unsafe { let a = a.as_u64x4(); let b = b.as_u64x4(); - let mask = u64x4::splat(u32::MAX.into()); + let mask = u64x4::splat(u32::MAX as u64); transmute(simd_mul(simd_and(a, mask), simd_and(b, mask))) } } @@ -2113,7 +2197,8 @@ pub fn _mm256_mul_epu32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmulhw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_mulhi_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mulhi_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { let a = simd_cast::<_, i32x16>(a.as_i16x16()); let b = simd_cast::<_, i32x16>(b.as_i16x16()); @@ -2131,7 +2216,8 @@ pub fn _mm256_mulhi_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmulhuw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_mulhi_epu16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mulhi_epu16(a: __m256i, b: __m256i) -> __m256i { unsafe { let a = simd_cast::<_, u32x16>(a.as_u16x16()); let b = simd_cast::<_, u32x16>(b.as_u16x16()); @@ -2149,7 +2235,8 @@ pub fn _mm256_mulhi_epu16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmullw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_mullo_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mullo_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_mul(a.as_i16x16(), b.as_i16x16())) } } @@ -2162,7 +2249,8 @@ pub fn _mm256_mullo_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmulld))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_mullo_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mullo_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_mul(a.as_i32x8(), b.as_i32x8())) } } @@ -2188,7 +2276,8 @@ pub fn _mm256_mulhrs_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vorps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_or_si256(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_or_si256(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_or(a.as_i32x8(), b.as_i32x8())) } } @@ -2262,7 +2351,8 @@ pub fn _mm256_permutevar8x32_epi32(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpermpd, IMM8 = 9))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_permute4x64_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permute4x64_epi64(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { let zero = i64x4::ZERO; @@ -2288,7 +2378,8 @@ pub fn _mm256_permute4x64_epi64(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vperm2f128, IMM8 = 9))] #[rustc_legacy_const_generics(2)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_permute2x128_si256(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permute2x128_si256(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_permute2f128_si256::(a, b) } @@ -2302,7 +2393,8 @@ pub fn _mm256_permute2x128_si256(a: __m256i, b: __m256i) -> __m #[cfg_attr(test, assert_instr(vpermpd, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_permute4x64_pd(a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permute4x64_pd(a: __m256d) -> __m256d { static_assert_uimm_bits!(IMM8, 8); unsafe { simd_shuffle!( @@ -2417,7 +2509,8 @@ pub fn _mm256_shuffle_epi8(a: __m256i, b: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vshufps, MASK = 9))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_shuffle_epi32(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shuffle_epi32(a: __m256i) -> __m256i { static_assert_uimm_bits!(MASK, 8); unsafe { let r: i32x8 = simd_shuffle!( @@ -2448,7 +2541,8 @@ pub fn _mm256_shuffle_epi32(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpshufhw, IMM8 = 9))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_shufflehi_epi16(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shufflehi_epi16(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { let a = a.as_i16x16(); @@ -2488,7 +2582,8 @@ pub fn _mm256_shufflehi_epi16(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpshuflw, IMM8 = 9))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_shufflelo_epi16(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shufflelo_epi16(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { let a = a.as_i16x16(); @@ -2602,7 +2697,8 @@ pub fn _mm256_sll_epi64(a: __m256i, count: __m128i) -> __m256i { #[cfg_attr(test, assert_instr(vpsllw, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_slli_epi16(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_slli_epi16(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 16 { @@ -2622,7 +2718,8 @@ pub fn _mm256_slli_epi16(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpslld, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_slli_epi32(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_slli_epi32(a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 32 { @@ -2642,7 +2739,8 @@ pub fn _mm256_slli_epi32(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpsllq, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_slli_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_slli_epi64(a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 64 { @@ -2661,7 +2759,8 @@ pub fn _mm256_slli_epi64(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpslldq, IMM8 = 3))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_slli_si256(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_slli_si256(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_bslli_epi128::(a) } @@ -2674,7 +2773,8 @@ pub fn _mm256_slli_si256(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpslldq, IMM8 = 3))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_bslli_epi128(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_bslli_epi128(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); const fn mask(shift: i32, i: u32) -> u32 { let shift = shift as u32 & 0xff; @@ -2737,7 +2837,8 @@ pub fn _mm256_bslli_epi128(a: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsllvd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sllv_epi32(a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sllv_epi32(a: __m128i, count: __m128i) -> __m128i { unsafe { let count = count.as_u32x4(); let no_overflow: u32x4 = simd_lt(count, u32x4::splat(u32::BITS)); @@ -2755,7 +2856,8 @@ pub fn _mm_sllv_epi32(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsllvd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_sllv_epi32(a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sllv_epi32(a: __m256i, count: __m256i) -> __m256i { unsafe { let count = count.as_u32x8(); let no_overflow: u32x8 = simd_lt(count, u32x8::splat(u32::BITS)); @@ -2773,7 +2875,8 @@ pub fn _mm256_sllv_epi32(a: __m256i, count: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsllvq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_sllv_epi64(a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sllv_epi64(a: __m128i, count: __m128i) -> __m128i { unsafe { let count = count.as_u64x2(); let no_overflow: u64x2 = simd_lt(count, u64x2::splat(u64::BITS as u64)); @@ -2791,7 +2894,8 @@ pub fn _mm_sllv_epi64(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsllvq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_sllv_epi64(a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sllv_epi64(a: __m256i, count: __m256i) -> __m256i { unsafe { let count = count.as_u64x4(); let no_overflow: u64x4 = simd_lt(count, u64x4::splat(u64::BITS as u64)); @@ -2833,7 +2937,8 @@ pub fn _mm256_sra_epi32(a: __m256i, count: __m128i) -> __m256i { #[cfg_attr(test, assert_instr(vpsraw, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_srai_epi16(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srai_epi16(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { transmute(simd_shr(a.as_i16x16(), i16x16::splat(IMM8.min(15) as i16))) } } @@ -2847,7 +2952,8 @@ pub fn _mm256_srai_epi16(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpsrad, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_srai_epi32(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srai_epi32(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { transmute(simd_shr(a.as_i32x8(), i32x8::splat(IMM8.min(31)))) } } @@ -2860,7 +2966,8 @@ pub fn _mm256_srai_epi32(a: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsravd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_srav_epi32(a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srav_epi32(a: __m128i, count: __m128i) -> __m128i { unsafe { let count = count.as_u32x4(); let no_overflow: u32x4 = simd_lt(count, u32x4::splat(u32::BITS)); @@ -2877,7 +2984,8 @@ pub fn _mm_srav_epi32(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsravd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_srav_epi32(a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srav_epi32(a: __m256i, count: __m256i) -> __m256i { unsafe { let count = count.as_u32x8(); let no_overflow: u32x8 = simd_lt(count, u32x8::splat(u32::BITS)); @@ -2894,7 +3002,8 @@ pub fn _mm256_srav_epi32(a: __m256i, count: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpsrldq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_srli_si256(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srli_si256(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_bsrli_epi128::(a) } @@ -2907,7 +3016,8 @@ pub fn _mm256_srli_si256(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpsrldq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_bsrli_epi128(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_bsrli_epi128(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); const fn mask(shift: i32, i: u32) -> u32 { let shift = shift as u32 & 0xff; @@ -3006,7 +3116,8 @@ pub fn _mm256_srl_epi64(a: __m256i, count: __m128i) -> __m256i { #[cfg_attr(test, assert_instr(vpsrlw, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_srli_epi16(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srli_epi16(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 16 { @@ -3026,7 +3137,8 @@ pub fn _mm256_srli_epi16(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpsrld, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_srli_epi32(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srli_epi32(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 32 { @@ -3046,7 +3158,8 @@ pub fn _mm256_srli_epi32(a: __m256i) -> __m256i { #[cfg_attr(test, assert_instr(vpsrlq, IMM8 = 7))] #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_srli_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srli_epi64(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); unsafe { if IMM8 >= 64 { @@ -3065,7 +3178,8 @@ pub fn _mm256_srli_epi64(a: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsrlvd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_srlv_epi32(a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srlv_epi32(a: __m128i, count: __m128i) -> __m128i { unsafe { let count = count.as_u32x4(); let no_overflow: u32x4 = simd_lt(count, u32x4::splat(u32::BITS)); @@ -3082,7 +3196,8 @@ pub fn _mm_srlv_epi32(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsrlvd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_srlv_epi32(a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srlv_epi32(a: __m256i, count: __m256i) -> __m256i { unsafe { let count = count.as_u32x8(); let no_overflow: u32x8 = simd_lt(count, u32x8::splat(u32::BITS)); @@ -3099,7 +3214,8 @@ pub fn _mm256_srlv_epi32(a: __m256i, count: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsrlvq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_srlv_epi64(a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srlv_epi64(a: __m128i, count: __m128i) -> __m128i { unsafe { let count = count.as_u64x2(); let no_overflow: u64x2 = simd_lt(count, u64x2::splat(u64::BITS as u64)); @@ -3116,7 +3232,8 @@ pub fn _mm_srlv_epi64(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsrlvq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_srlv_epi64(a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srlv_epi64(a: __m256i, count: __m256i) -> __m256i { unsafe { let count = count.as_u64x4(); let no_overflow: u64x4 = simd_lt(count, u64x4::splat(u64::BITS as u64)); @@ -3152,7 +3269,8 @@ pub unsafe fn _mm256_stream_load_si256(mem_addr: *const __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsubw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_sub_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sub_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_sub(a.as_i16x16(), b.as_i16x16())) } } @@ -3163,7 +3281,8 @@ pub fn _mm256_sub_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsubd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_sub_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sub_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_sub(a.as_i32x8(), b.as_i32x8())) } } @@ -3174,7 +3293,8 @@ pub fn _mm256_sub_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsubq))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_sub_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sub_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_sub(a.as_i64x4(), b.as_i64x4())) } } @@ -3185,7 +3305,8 @@ pub fn _mm256_sub_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsubb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_sub_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sub_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_sub(a.as_i8x32(), b.as_i8x32())) } } @@ -3197,7 +3318,8 @@ pub fn _mm256_sub_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsubsw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_subs_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_subs_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_saturating_sub(a.as_i16x16(), b.as_i16x16())) } } @@ -3209,7 +3331,8 @@ pub fn _mm256_subs_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsubsb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_subs_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_subs_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_saturating_sub(a.as_i8x32(), b.as_i8x32())) } } @@ -3221,7 +3344,8 @@ pub fn _mm256_subs_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsubusw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_subs_epu16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_subs_epu16(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_saturating_sub(a.as_u16x16(), b.as_u16x16())) } } @@ -3233,7 +3357,8 @@ pub fn _mm256_subs_epu16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpsubusb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_subs_epu8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_subs_epu8(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_saturating_sub(a.as_u8x32(), b.as_u8x32())) } } @@ -3280,7 +3405,8 @@ pub fn _mm256_subs_epu8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpunpckhbw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpackhi_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpackhi_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { #[rustfmt::skip] let r: i8x32 = simd_shuffle!(a.as_i8x32(), b.as_i8x32(), [ @@ -3335,7 +3461,8 @@ pub fn _mm256_unpackhi_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpunpcklbw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpacklo_epi8(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpacklo_epi8(a: __m256i, b: __m256i) -> __m256i { unsafe { #[rustfmt::skip] let r: i8x32 = simd_shuffle!(a.as_i8x32(), b.as_i8x32(), [ @@ -3386,7 +3513,8 @@ pub fn _mm256_unpacklo_epi8(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpunpckhwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpackhi_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpackhi_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { let r: i16x16 = simd_shuffle!( a.as_i16x16(), @@ -3436,7 +3564,8 @@ pub fn _mm256_unpackhi_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpunpcklwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpacklo_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpacklo_epi16(a: __m256i, b: __m256i) -> __m256i { unsafe { let r: i16x16 = simd_shuffle!( a.as_i16x16(), @@ -3479,7 +3608,8 @@ pub fn _mm256_unpacklo_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vunpckhps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpackhi_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpackhi_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { let r: i32x8 = simd_shuffle!(a.as_i32x8(), b.as_i32x8(), [2, 10, 3, 11, 6, 14, 7, 15]); transmute(r) @@ -3518,7 +3648,8 @@ pub fn _mm256_unpackhi_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vunpcklps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpacklo_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpacklo_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { let r: i32x8 = simd_shuffle!(a.as_i32x8(), b.as_i32x8(), [0, 8, 1, 9, 4, 12, 5, 13]); transmute(r) @@ -3557,7 +3688,8 @@ pub fn _mm256_unpacklo_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vunpckhpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpackhi_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpackhi_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { let r: i64x4 = simd_shuffle!(a.as_i64x4(), b.as_i64x4(), [1, 5, 3, 7]); transmute(r) @@ -3596,7 +3728,8 @@ pub fn _mm256_unpackhi_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vunpcklpd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_unpacklo_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_unpacklo_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { let r: i64x4 = simd_shuffle!(a.as_i64x4(), b.as_i64x4(), [0, 4, 2, 6]); transmute(r) @@ -3611,7 +3744,8 @@ pub fn _mm256_unpacklo_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_xor_si256(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_xor_si256(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_xor(a.as_i64x4(), b.as_i64x4())) } } @@ -3626,7 +3760,8 @@ pub fn _mm256_xor_si256(a: __m256i, b: __m256i) -> __m256i { // This intrinsic has no corresponding instruction. #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_extract_epi8(a: __m256i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extract_epi8(a: __m256i) -> i32 { static_assert_uimm_bits!(INDEX, 5); unsafe { simd_extract!(a.as_u8x32(), INDEX as u32, u8) as i32 } } @@ -3642,7 +3777,8 @@ pub fn _mm256_extract_epi8(a: __m256i) -> i32 { // This intrinsic has no corresponding instruction. #[rustc_legacy_const_generics(1)] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_extract_epi16(a: __m256i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extract_epi16(a: __m256i) -> i32 { static_assert_uimm_bits!(INDEX, 4); unsafe { simd_extract!(a.as_u16x16(), INDEX as u32, u16) as i32 } } @@ -3771,13 +3907,14 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; #[simd_test(enable = "avx2")] - unsafe fn test_mm256_abs_epi32() { + const unsafe fn test_mm256_abs_epi32() { #[rustfmt::skip] let a = _mm256_setr_epi32( 0, 1, -1, i32::MAX, @@ -3793,7 +3930,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_abs_epi16() { + const unsafe fn test_mm256_abs_epi16() { #[rustfmt::skip] let a = _mm256_setr_epi16( 0, 1, -1, 2, -2, 3, -3, 4, @@ -3809,7 +3946,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_abs_epi8() { + const unsafe fn test_mm256_abs_epi8() { #[rustfmt::skip] let a = _mm256_setr_epi8( 0, 1, -1, 2, -2, 3, -3, 4, @@ -3829,7 +3966,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_add_epi64() { + const unsafe fn test_mm256_add_epi64() { let a = _mm256_setr_epi64x(-10, 0, 100, 1_000_000_000); let b = _mm256_setr_epi64x(-1, 0, 1, 2); let r = _mm256_add_epi64(a, b); @@ -3838,7 +3975,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_add_epi32() { + const unsafe fn test_mm256_add_epi32() { let a = _mm256_setr_epi32(-1, 0, 1, 2, 3, 4, 5, 6); let b = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_add_epi32(a, b); @@ -3847,7 +3984,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_add_epi16() { + const unsafe fn test_mm256_add_epi16() { #[rustfmt::skip] let a = _mm256_setr_epi16( 0, 1, 2, 3, 4, 5, 6, 7, @@ -3868,7 +4005,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_add_epi8() { + const unsafe fn test_mm256_add_epi8() { #[rustfmt::skip] let a = _mm256_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -3895,7 +4032,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_adds_epi8() { + const unsafe fn test_mm256_adds_epi8() { #[rustfmt::skip] let a = _mm256_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -3938,7 +4075,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_adds_epi16() { + const unsafe fn test_mm256_adds_epi16() { #[rustfmt::skip] let a = _mm256_setr_epi16( 0, 1, 2, 3, 4, 5, 6, 7, @@ -3976,7 +4113,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_adds_epu8() { + const unsafe fn test_mm256_adds_epu8() { #[rustfmt::skip] let a = _mm256_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4011,7 +4148,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_adds_epu16() { + const unsafe fn test_mm256_adds_epu16() { #[rustfmt::skip] let a = _mm256_setr_epi16( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4041,7 +4178,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_and_si256() { + const unsafe fn test_mm256_and_si256() { let a = _mm256_set1_epi8(5); let b = _mm256_set1_epi8(3); let got = _mm256_and_si256(a, b); @@ -4049,7 +4186,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_andnot_si256() { + const unsafe fn test_mm256_andnot_si256() { let a = _mm256_set1_epi8(5); let b = _mm256_set1_epi8(3); let got = _mm256_andnot_si256(a, b); @@ -4057,21 +4194,21 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_avg_epu8() { + const unsafe fn test_mm256_avg_epu8() { let (a, b) = (_mm256_set1_epi8(3), _mm256_set1_epi8(9)); let r = _mm256_avg_epu8(a, b); assert_eq_m256i(r, _mm256_set1_epi8(6)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_avg_epu16() { + const unsafe fn test_mm256_avg_epu16() { let (a, b) = (_mm256_set1_epi16(3), _mm256_set1_epi16(9)); let r = _mm256_avg_epu16(a, b); assert_eq_m256i(r, _mm256_set1_epi16(6)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_blend_epi32() { + const unsafe fn test_mm_blend_epi32() { let (a, b) = (_mm_set1_epi32(3), _mm_set1_epi32(9)); let e = _mm_setr_epi32(9, 3, 3, 3); let r = _mm_blend_epi32::<0x01>(a, b); @@ -4082,7 +4219,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_blend_epi32() { + const unsafe fn test_mm256_blend_epi32() { let (a, b) = (_mm256_set1_epi32(3), _mm256_set1_epi32(9)); let e = _mm256_setr_epi32(9, 3, 3, 3, 3, 3, 3, 3); let r = _mm256_blend_epi32::<0x01>(a, b); @@ -4098,7 +4235,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_blend_epi16() { + const unsafe fn test_mm256_blend_epi16() { let (a, b) = (_mm256_set1_epi16(3), _mm256_set1_epi16(9)); let e = _mm256_setr_epi16(9, 3, 3, 3, 3, 3, 3, 3, 9, 3, 3, 3, 3, 3, 3, 3); let r = _mm256_blend_epi16::<0x01>(a, b); @@ -4109,7 +4246,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_blendv_epi8() { + const unsafe fn test_mm256_blendv_epi8() { let (a, b) = (_mm256_set1_epi8(4), _mm256_set1_epi8(2)); let mask = _mm256_insert_epi8::<2>(_mm256_set1_epi8(0), -1); let e = _mm256_insert_epi8::<2>(_mm256_set1_epi8(4), 2); @@ -4118,63 +4255,63 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_broadcastb_epi8() { + const unsafe fn test_mm_broadcastb_epi8() { let a = _mm_insert_epi8::<0>(_mm_set1_epi8(0x00), 0x2a); let res = _mm_broadcastb_epi8(a); assert_eq_m128i(res, _mm_set1_epi8(0x2a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_broadcastb_epi8() { + const unsafe fn test_mm256_broadcastb_epi8() { let a = _mm_insert_epi8::<0>(_mm_set1_epi8(0x00), 0x2a); let res = _mm256_broadcastb_epi8(a); assert_eq_m256i(res, _mm256_set1_epi8(0x2a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_broadcastd_epi32() { + const unsafe fn test_mm_broadcastd_epi32() { let a = _mm_setr_epi32(0x2a, 0x8000000, 0, 0); let res = _mm_broadcastd_epi32(a); assert_eq_m128i(res, _mm_set1_epi32(0x2a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_broadcastd_epi32() { + const unsafe fn test_mm256_broadcastd_epi32() { let a = _mm_setr_epi32(0x2a, 0x8000000, 0, 0); let res = _mm256_broadcastd_epi32(a); assert_eq_m256i(res, _mm256_set1_epi32(0x2a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_broadcastq_epi64() { + const unsafe fn test_mm_broadcastq_epi64() { let a = _mm_setr_epi64x(0x1ffffffff, 0); let res = _mm_broadcastq_epi64(a); assert_eq_m128i(res, _mm_set1_epi64x(0x1ffffffff)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_broadcastq_epi64() { + const unsafe fn test_mm256_broadcastq_epi64() { let a = _mm_setr_epi64x(0x1ffffffff, 0); let res = _mm256_broadcastq_epi64(a); assert_eq_m256i(res, _mm256_set1_epi64x(0x1ffffffff)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_broadcastsd_pd() { + const unsafe fn test_mm_broadcastsd_pd() { let a = _mm_setr_pd(6.88, 3.44); let res = _mm_broadcastsd_pd(a); assert_eq_m128d(res, _mm_set1_pd(6.88)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_broadcastsd_pd() { + const unsafe fn test_mm256_broadcastsd_pd() { let a = _mm_setr_pd(6.88, 3.44); let res = _mm256_broadcastsd_pd(a); assert_eq_m256d(res, _mm256_set1_pd(6.88f64)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_broadcastsi128_si256() { + const unsafe fn test_mm_broadcastsi128_si256() { let a = _mm_setr_epi64x(0x0987654321012334, 0x5678909876543210); let res = _mm_broadcastsi128_si256(a); let retval = _mm256_setr_epi64x( @@ -4187,7 +4324,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_broadcastsi128_si256() { + const unsafe fn test_mm256_broadcastsi128_si256() { let a = _mm_setr_epi64x(0x0987654321012334, 0x5678909876543210); let res = _mm256_broadcastsi128_si256(a); let retval = _mm256_setr_epi64x( @@ -4200,35 +4337,35 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_broadcastss_ps() { + const unsafe fn test_mm_broadcastss_ps() { let a = _mm_setr_ps(6.88, 3.44, 0.0, 0.0); let res = _mm_broadcastss_ps(a); assert_eq_m128(res, _mm_set1_ps(6.88)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_broadcastss_ps() { + const unsafe fn test_mm256_broadcastss_ps() { let a = _mm_setr_ps(6.88, 3.44, 0.0, 0.0); let res = _mm256_broadcastss_ps(a); assert_eq_m256(res, _mm256_set1_ps(6.88)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_broadcastw_epi16() { + const unsafe fn test_mm_broadcastw_epi16() { let a = _mm_insert_epi16::<0>(_mm_set1_epi16(0x2a), 0x22b); let res = _mm_broadcastw_epi16(a); assert_eq_m128i(res, _mm_set1_epi16(0x22b)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_broadcastw_epi16() { + const unsafe fn test_mm256_broadcastw_epi16() { let a = _mm_insert_epi16::<0>(_mm_set1_epi16(0x2a), 0x22b); let res = _mm256_broadcastw_epi16(a); assert_eq_m256i(res, _mm256_set1_epi16(0x22b)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cmpeq_epi8() { + const unsafe fn test_mm256_cmpeq_epi8() { #[rustfmt::skip] let a = _mm256_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4248,7 +4385,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cmpeq_epi16() { + const unsafe fn test_mm256_cmpeq_epi16() { #[rustfmt::skip] let a = _mm256_setr_epi16( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4264,7 +4401,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cmpeq_epi32() { + const unsafe fn test_mm256_cmpeq_epi32() { let a = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm256_setr_epi32(7, 6, 2, 4, 3, 2, 1, 0); let r = _mm256_cmpeq_epi32(a, b); @@ -4274,7 +4411,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cmpeq_epi64() { + const unsafe fn test_mm256_cmpeq_epi64() { let a = _mm256_setr_epi64x(0, 1, 2, 3); let b = _mm256_setr_epi64x(3, 2, 2, 0); let r = _mm256_cmpeq_epi64(a, b); @@ -4282,7 +4419,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cmpgt_epi8() { + const unsafe fn test_mm256_cmpgt_epi8() { let a = _mm256_insert_epi8::<0>(_mm256_set1_epi8(0), 5); let b = _mm256_set1_epi8(0); let r = _mm256_cmpgt_epi8(a, b); @@ -4290,7 +4427,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cmpgt_epi16() { + const unsafe fn test_mm256_cmpgt_epi16() { let a = _mm256_insert_epi16::<0>(_mm256_set1_epi16(0), 5); let b = _mm256_set1_epi16(0); let r = _mm256_cmpgt_epi16(a, b); @@ -4298,7 +4435,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cmpgt_epi32() { + const unsafe fn test_mm256_cmpgt_epi32() { let a = _mm256_insert_epi32::<0>(_mm256_set1_epi32(0), 5); let b = _mm256_set1_epi32(0); let r = _mm256_cmpgt_epi32(a, b); @@ -4306,7 +4443,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cmpgt_epi64() { + const unsafe fn test_mm256_cmpgt_epi64() { let a = _mm256_insert_epi64::<0>(_mm256_set1_epi64x(0), 5); let b = _mm256_set1_epi64x(0); let r = _mm256_cmpgt_epi64(a, b); @@ -4314,7 +4451,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepi8_epi16() { + const unsafe fn test_mm256_cvtepi8_epi16() { #[rustfmt::skip] let a = _mm_setr_epi8( 0, 0, -1, 1, -2, 2, -3, 3, @@ -4329,7 +4466,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepi8_epi32() { + const unsafe fn test_mm256_cvtepi8_epi32() { #[rustfmt::skip] let a = _mm_setr_epi8( 0, 0, -1, 1, -2, 2, -3, 3, @@ -4340,7 +4477,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepi8_epi64() { + const unsafe fn test_mm256_cvtepi8_epi64() { #[rustfmt::skip] let a = _mm_setr_epi8( 0, 0, -1, 1, -2, 2, -3, 3, @@ -4351,49 +4488,49 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepi16_epi32() { + const unsafe fn test_mm256_cvtepi16_epi32() { let a = _mm_setr_epi16(0, 0, -1, 1, -2, 2, -3, 3); let r = _mm256_setr_epi32(0, 0, -1, 1, -2, 2, -3, 3); assert_eq_m256i(r, _mm256_cvtepi16_epi32(a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepi16_epi64() { + const unsafe fn test_mm256_cvtepi16_epi64() { let a = _mm_setr_epi16(0, 0, -1, 1, -2, 2, -3, 3); let r = _mm256_setr_epi64x(0, 0, -1, 1); assert_eq_m256i(r, _mm256_cvtepi16_epi64(a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepi32_epi64() { + const unsafe fn test_mm256_cvtepi32_epi64() { let a = _mm_setr_epi32(0, 0, -1, 1); let r = _mm256_setr_epi64x(0, 0, -1, 1); assert_eq_m256i(r, _mm256_cvtepi32_epi64(a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepu16_epi32() { + const unsafe fn test_mm256_cvtepu16_epi32() { let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7); assert_eq_m256i(r, _mm256_cvtepu16_epi32(a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepu16_epi64() { + const unsafe fn test_mm256_cvtepu16_epi64() { let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm256_setr_epi64x(0, 1, 2, 3); assert_eq_m256i(r, _mm256_cvtepu16_epi64(a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepu32_epi64() { + const unsafe fn test_mm256_cvtepu32_epi64() { let a = _mm_setr_epi32(0, 1, 2, 3); let r = _mm256_setr_epi64x(0, 1, 2, 3); assert_eq_m256i(r, _mm256_cvtepu32_epi64(a)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepu8_epi16() { + const unsafe fn test_mm256_cvtepu8_epi16() { #[rustfmt::skip] let a = _mm_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4408,7 +4545,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepu8_epi32() { + const unsafe fn test_mm256_cvtepu8_epi32() { #[rustfmt::skip] let a = _mm_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4419,7 +4556,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_cvtepu8_epi64() { + const unsafe fn test_mm256_cvtepu8_epi64() { #[rustfmt::skip] let a = _mm_setr_epi8( 0, 1, 2, 3, 4, 5, 6, 7, @@ -4430,7 +4567,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_extracti128_si256() { + const unsafe fn test_mm256_extracti128_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let r = _mm256_extracti128_si256::<1>(a); let e = _mm_setr_epi64x(3, 4); @@ -4438,7 +4575,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_hadd_epi16() { + const unsafe fn test_mm256_hadd_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_hadd_epi16(a, b); @@ -4447,7 +4584,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_hadd_epi32() { + const unsafe fn test_mm256_hadd_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_hadd_epi32(a, b); @@ -4471,7 +4608,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_hsub_epi16() { + const unsafe fn test_mm256_hsub_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_hsub_epi16(a, b); @@ -4480,7 +4617,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_hsub_epi32() { + const unsafe fn test_mm256_hsub_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_hsub_epi32(a, b); @@ -4500,7 +4637,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_madd_epi16() { + const unsafe fn test_mm256_madd_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_madd_epi16(a, b); @@ -4509,7 +4646,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_inserti128_si256() { + const unsafe fn test_mm256_inserti128_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let b = _mm_setr_epi64x(7, 8); let r = _mm256_inserti128_si256::<1>(a, b); @@ -4527,7 +4664,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_maskload_epi32() { + const unsafe fn test_mm_maskload_epi32() { let nums = [1, 2, 3, 4]; let a = &nums as *const i32; let mask = _mm_setr_epi32(-1, 0, 0, -1); @@ -4537,7 +4674,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_maskload_epi32() { + const unsafe fn test_mm256_maskload_epi32() { let nums = [1, 2, 3, 4, 5, 6, 7, 8]; let a = &nums as *const i32; let mask = _mm256_setr_epi32(-1, 0, 0, -1, 0, -1, -1, 0); @@ -4547,7 +4684,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_maskload_epi64() { + const unsafe fn test_mm_maskload_epi64() { let nums = [1_i64, 2_i64]; let a = &nums as *const i64; let mask = _mm_setr_epi64x(0, -1); @@ -4557,7 +4694,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_maskload_epi64() { + const unsafe fn test_mm256_maskload_epi64() { let nums = [1_i64, 2_i64, 3_i64, 4_i64]; let a = &nums as *const i64; let mask = _mm256_setr_epi64x(0, -1, -1, 0); @@ -4567,7 +4704,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_maskstore_epi32() { + const unsafe fn test_mm_maskstore_epi32() { let a = _mm_setr_epi32(1, 2, 3, 4); let mut arr = [-1, -1, -1, -1]; let mask = _mm_setr_epi32(-1, 0, 0, -1); @@ -4577,7 +4714,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_maskstore_epi32() { + const unsafe fn test_mm256_maskstore_epi32() { let a = _mm256_setr_epi32(1, 0x6d726f, 3, 42, 0x777161, 6, 7, 8); let mut arr = [-1, -1, -1, 0x776173, -1, 0x68657265, -1, -1]; let mask = _mm256_setr_epi32(-1, 0, 0, -1, 0, -1, -1, 0); @@ -4587,7 +4724,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_maskstore_epi64() { + const unsafe fn test_mm_maskstore_epi64() { let a = _mm_setr_epi64x(1_i64, 2_i64); let mut arr = [-1_i64, -1_i64]; let mask = _mm_setr_epi64x(0, -1); @@ -4597,7 +4734,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_maskstore_epi64() { + const unsafe fn test_mm256_maskstore_epi64() { let a = _mm256_setr_epi64x(1_i64, 2_i64, 3_i64, 4_i64); let mut arr = [-1_i64, -1_i64, -1_i64, -1_i64]; let mask = _mm256_setr_epi64x(0, -1, -1, 0); @@ -4607,7 +4744,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_max_epi16() { + const unsafe fn test_mm256_max_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_max_epi16(a, b); @@ -4615,7 +4752,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_max_epi32() { + const unsafe fn test_mm256_max_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_max_epi32(a, b); @@ -4623,7 +4760,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_max_epi8() { + const unsafe fn test_mm256_max_epi8() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(4); let r = _mm256_max_epi8(a, b); @@ -4631,7 +4768,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_max_epu16() { + const unsafe fn test_mm256_max_epu16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_max_epu16(a, b); @@ -4639,7 +4776,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_max_epu32() { + const unsafe fn test_mm256_max_epu32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_max_epu32(a, b); @@ -4647,7 +4784,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_max_epu8() { + const unsafe fn test_mm256_max_epu8() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(4); let r = _mm256_max_epu8(a, b); @@ -4655,7 +4792,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_min_epi16() { + const unsafe fn test_mm256_min_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_min_epi16(a, b); @@ -4663,7 +4800,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_min_epi32() { + const unsafe fn test_mm256_min_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_min_epi32(a, b); @@ -4671,7 +4808,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_min_epi8() { + const unsafe fn test_mm256_min_epi8() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(4); let r = _mm256_min_epi8(a, b); @@ -4679,7 +4816,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_min_epu16() { + const unsafe fn test_mm256_min_epu16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_min_epu16(a, b); @@ -4687,7 +4824,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_min_epu32() { + const unsafe fn test_mm256_min_epu32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_min_epu32(a, b); @@ -4695,7 +4832,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_min_epu8() { + const unsafe fn test_mm256_min_epu8() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(4); let r = _mm256_min_epu8(a, b); @@ -4703,7 +4840,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_movemask_epi8() { + const unsafe fn test_mm256_movemask_epi8() { let a = _mm256_set1_epi8(-1); let r = _mm256_movemask_epi8(a); let e = -1; @@ -4720,7 +4857,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mul_epi32() { + const unsafe fn test_mm256_mul_epi32() { let a = _mm256_setr_epi32(0, 0, 0, 0, 2, 2, 2, 2); let b = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_mul_epi32(a, b); @@ -4729,7 +4866,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mul_epu32() { + const unsafe fn test_mm256_mul_epu32() { let a = _mm256_setr_epi32(0, 0, 0, 0, 2, 2, 2, 2); let b = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_mul_epu32(a, b); @@ -4738,7 +4875,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mulhi_epi16() { + const unsafe fn test_mm256_mulhi_epi16() { let a = _mm256_set1_epi16(6535); let b = _mm256_set1_epi16(6535); let r = _mm256_mulhi_epi16(a, b); @@ -4747,7 +4884,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mulhi_epu16() { + const unsafe fn test_mm256_mulhi_epu16() { let a = _mm256_set1_epi16(6535); let b = _mm256_set1_epi16(6535); let r = _mm256_mulhi_epu16(a, b); @@ -4756,7 +4893,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mullo_epi16() { + const unsafe fn test_mm256_mullo_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_mullo_epi16(a, b); @@ -4765,7 +4902,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mullo_epi32() { + const unsafe fn test_mm256_mullo_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_mullo_epi32(a, b); @@ -4783,7 +4920,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_or_si256() { + const unsafe fn test_mm256_or_si256() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(0); let r = _mm256_or_si256(a, b); @@ -4852,7 +4989,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_shufflehi_epi16() { + const unsafe fn test_mm256_shufflehi_epi16() { #[rustfmt::skip] let a = _mm256_setr_epi16( 0, 1, 2, 3, 11, 22, 33, 44, @@ -4868,7 +5005,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_shufflelo_epi16() { + const unsafe fn test_mm256_shufflelo_epi16() { #[rustfmt::skip] let a = _mm256_setr_epi16( 11, 22, 33, 44, 0, 1, 2, 3, @@ -4935,7 +5072,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_slli_epi16() { + const unsafe fn test_mm256_slli_epi16() { assert_eq_m256i( _mm256_slli_epi16::<4>(_mm256_set1_epi16(0xFF)), _mm256_set1_epi16(0xFF0), @@ -4943,7 +5080,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_slli_epi32() { + const unsafe fn test_mm256_slli_epi32() { assert_eq_m256i( _mm256_slli_epi32::<4>(_mm256_set1_epi32(0xFFFF)), _mm256_set1_epi32(0xFFFF0), @@ -4951,7 +5088,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_slli_epi64() { + const unsafe fn test_mm256_slli_epi64() { assert_eq_m256i( _mm256_slli_epi64::<4>(_mm256_set1_epi64x(0xFFFFFFFF)), _mm256_set1_epi64x(0xFFFFFFFF0), @@ -4959,14 +5096,14 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_slli_si256() { + const unsafe fn test_mm256_slli_si256() { let a = _mm256_set1_epi64x(0xFFFFFFFF); let r = _mm256_slli_si256::<3>(a); assert_eq_m256i(r, _mm256_set1_epi64x(0xFFFFFFFF000000)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_sllv_epi32() { + const unsafe fn test_mm_sllv_epi32() { let a = _mm_set1_epi32(2); let b = _mm_set1_epi32(1); let r = _mm_sllv_epi32(a, b); @@ -4975,7 +5112,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_sllv_epi32() { + const unsafe fn test_mm256_sllv_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(1); let r = _mm256_sllv_epi32(a, b); @@ -4984,7 +5121,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_sllv_epi64() { + const unsafe fn test_mm_sllv_epi64() { let a = _mm_set1_epi64x(2); let b = _mm_set1_epi64x(1); let r = _mm_sllv_epi64(a, b); @@ -4993,7 +5130,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_sllv_epi64() { + const unsafe fn test_mm256_sllv_epi64() { let a = _mm256_set1_epi64x(2); let b = _mm256_set1_epi64x(1); let r = _mm256_sllv_epi64(a, b); @@ -5018,7 +5155,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_srai_epi16() { + const unsafe fn test_mm256_srai_epi16() { assert_eq_m256i( _mm256_srai_epi16::<1>(_mm256_set1_epi16(-1)), _mm256_set1_epi16(-1), @@ -5026,7 +5163,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_srai_epi32() { + const unsafe fn test_mm256_srai_epi32() { assert_eq_m256i( _mm256_srai_epi32::<1>(_mm256_set1_epi32(-1)), _mm256_set1_epi32(-1), @@ -5034,7 +5171,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_srav_epi32() { + const unsafe fn test_mm_srav_epi32() { let a = _mm_set1_epi32(4); let count = _mm_set1_epi32(1); let r = _mm_srav_epi32(a, count); @@ -5043,7 +5180,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_srav_epi32() { + const unsafe fn test_mm256_srav_epi32() { let a = _mm256_set1_epi32(4); let count = _mm256_set1_epi32(1); let r = _mm256_srav_epi32(a, count); @@ -5052,7 +5189,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_srli_si256() { + const unsafe fn test_mm256_srli_si256() { #[rustfmt::skip] let a = _mm256_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -5096,7 +5233,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_srli_epi16() { + const unsafe fn test_mm256_srli_epi16() { assert_eq_m256i( _mm256_srli_epi16::<4>(_mm256_set1_epi16(0xFF)), _mm256_set1_epi16(0xF), @@ -5104,7 +5241,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_srli_epi32() { + const unsafe fn test_mm256_srli_epi32() { assert_eq_m256i( _mm256_srli_epi32::<4>(_mm256_set1_epi32(0xFFFF)), _mm256_set1_epi32(0xFFF), @@ -5112,7 +5249,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_srli_epi64() { + const unsafe fn test_mm256_srli_epi64() { assert_eq_m256i( _mm256_srli_epi64::<4>(_mm256_set1_epi64x(0xFFFFFFFF)), _mm256_set1_epi64x(0xFFFFFFF), @@ -5120,7 +5257,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_srlv_epi32() { + const unsafe fn test_mm_srlv_epi32() { let a = _mm_set1_epi32(2); let count = _mm_set1_epi32(1); let r = _mm_srlv_epi32(a, count); @@ -5129,7 +5266,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_srlv_epi32() { + const unsafe fn test_mm256_srlv_epi32() { let a = _mm256_set1_epi32(2); let count = _mm256_set1_epi32(1); let r = _mm256_srlv_epi32(a, count); @@ -5138,7 +5275,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_srlv_epi64() { + const unsafe fn test_mm_srlv_epi64() { let a = _mm_set1_epi64x(2); let count = _mm_set1_epi64x(1); let r = _mm_srlv_epi64(a, count); @@ -5147,7 +5284,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_srlv_epi64() { + const unsafe fn test_mm256_srlv_epi64() { let a = _mm256_set1_epi64x(2); let count = _mm256_set1_epi64x(1); let r = _mm256_srlv_epi64(a, count); @@ -5163,7 +5300,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_sub_epi16() { + const unsafe fn test_mm256_sub_epi16() { let a = _mm256_set1_epi16(4); let b = _mm256_set1_epi16(2); let r = _mm256_sub_epi16(a, b); @@ -5171,7 +5308,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_sub_epi32() { + const unsafe fn test_mm256_sub_epi32() { let a = _mm256_set1_epi32(4); let b = _mm256_set1_epi32(2); let r = _mm256_sub_epi32(a, b); @@ -5179,7 +5316,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_sub_epi64() { + const unsafe fn test_mm256_sub_epi64() { let a = _mm256_set1_epi64x(4); let b = _mm256_set1_epi64x(2); let r = _mm256_sub_epi64(a, b); @@ -5187,7 +5324,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_sub_epi8() { + const unsafe fn test_mm256_sub_epi8() { let a = _mm256_set1_epi8(4); let b = _mm256_set1_epi8(2); let r = _mm256_sub_epi8(a, b); @@ -5195,7 +5332,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_subs_epi16() { + const unsafe fn test_mm256_subs_epi16() { let a = _mm256_set1_epi16(4); let b = _mm256_set1_epi16(2); let r = _mm256_subs_epi16(a, b); @@ -5203,7 +5340,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_subs_epi8() { + const unsafe fn test_mm256_subs_epi8() { let a = _mm256_set1_epi8(4); let b = _mm256_set1_epi8(2); let r = _mm256_subs_epi8(a, b); @@ -5211,7 +5348,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_subs_epu16() { + const unsafe fn test_mm256_subs_epu16() { let a = _mm256_set1_epi16(4); let b = _mm256_set1_epi16(2); let r = _mm256_subs_epu16(a, b); @@ -5219,7 +5356,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_subs_epu8() { + const unsafe fn test_mm256_subs_epu8() { let a = _mm256_set1_epi8(4); let b = _mm256_set1_epi8(2); let r = _mm256_subs_epu8(a, b); @@ -5227,7 +5364,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_xor_si256() { + const unsafe fn test_mm256_xor_si256() { let a = _mm256_set1_epi8(5); let b = _mm256_set1_epi8(3); let r = _mm256_xor_si256(a, b); @@ -5235,7 +5372,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_alignr_epi8() { + const unsafe fn test_mm256_alignr_epi8() { #[rustfmt::skip] let a = _mm256_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -5327,7 +5464,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_permute4x64_epi64() { + const unsafe fn test_mm256_permute4x64_epi64() { let a = _mm256_setr_epi64x(100, 200, 300, 400); let expected = _mm256_setr_epi64x(400, 100, 200, 100); let r = _mm256_permute4x64_epi64::<0b00010011>(a); @@ -5335,7 +5472,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_permute2x128_si256() { + const unsafe fn test_mm256_permute2x128_si256() { let a = _mm256_setr_epi64x(100, 200, 500, 600); let b = _mm256_setr_epi64x(300, 400, 700, 800); let r = _mm256_permute2x128_si256::<0b00_01_00_11>(a, b); @@ -5344,7 +5481,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_permute4x64_pd() { + const unsafe fn test_mm256_permute4x64_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let r = _mm256_permute4x64_pd::<0b00_01_00_11>(a); let e = _mm256_setr_pd(4., 1., 2., 1.); @@ -5702,7 +5839,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_extract_epi8() { + const unsafe fn test_mm256_extract_epi8() { #[rustfmt::skip] let a = _mm256_setr_epi8( -1, 1, 2, 3, 4, 5, 6, 7, @@ -5717,7 +5854,7 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_extract_epi16() { + const unsafe fn test_mm256_extract_epi16() { #[rustfmt::skip] let a = _mm256_setr_epi16( -1, 1, 2, 3, 4, 5, 6, 7, From 5b046698643bf47790e8a540b010f52a911b59c7 Mon Sep 17 00:00:00 2001 From: sayantn Date: Wed, 1 Oct 2025 11:31:19 +0530 Subject: [PATCH 0233/3801] Make `fma` functions const --- .../stdarch/crates/core_arch/src/x86/fma.rs | 161 +++++++++++------- 1 file changed, 97 insertions(+), 64 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/fma.rs b/library/stdarch/crates/core_arch/src/x86/fma.rs index d3988422b9a4..abf79f4904fe 100644 --- a/library/stdarch/crates/core_arch/src/x86/fma.rs +++ b/library/stdarch/crates/core_arch/src/x86/fma.rs @@ -33,7 +33,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmadd_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmadd_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_fma(a, b, c) } } @@ -45,7 +46,8 @@ pub fn _mm_fmadd_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fmadd_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmadd_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_fma(a, b, c) } } @@ -57,7 +59,8 @@ pub fn _mm256_fmadd_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmadd_ps(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmadd_ps(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_fma(a, b, c) } } @@ -69,7 +72,8 @@ pub fn _mm_fmadd_ps(a: __m128, b: __m128, c: __m128) -> __m128 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fmadd_ps(a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmadd_ps(a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_fma(a, b, c) } } @@ -83,7 +87,8 @@ pub fn _mm256_fmadd_ps(a: __m256, b: __m256, c: __m256) -> __m256 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmadd_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmadd_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_insert!( a, @@ -103,7 +108,8 @@ pub fn _mm_fmadd_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmadd_ss(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmadd_ss(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_insert!( a, @@ -122,7 +128,8 @@ pub fn _mm_fmadd_ss(a: __m128, b: __m128, c: __m128) -> __m128 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmaddsub_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmaddsub_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -139,7 +146,8 @@ pub fn _mm_fmaddsub_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fmaddsub_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmaddsub_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -156,7 +164,8 @@ pub fn _mm256_fmaddsub_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmaddsub_ps(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmaddsub_ps(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -173,7 +182,8 @@ pub fn _mm_fmaddsub_ps(a: __m128, b: __m128, c: __m128) -> __m128 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fmaddsub_ps(a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmaddsub_ps(a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -189,7 +199,8 @@ pub fn _mm256_fmaddsub_ps(a: __m256, b: __m256, c: __m256) -> __m256 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmsub_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmsub_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_fma(a, b, simd_neg(c)) } } @@ -201,7 +212,8 @@ pub fn _mm_fmsub_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fmsub_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmsub_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_fma(a, b, simd_neg(c)) } } @@ -213,7 +225,8 @@ pub fn _mm256_fmsub_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsub213ps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmsub_ps(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmsub_ps(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_fma(a, b, simd_neg(c)) } } @@ -225,7 +238,8 @@ pub fn _mm_fmsub_ps(a: __m128, b: __m128, c: __m128) -> __m128 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsub213ps))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fmsub_ps(a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmsub_ps(a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_fma(a, b, simd_neg(c)) } } @@ -239,7 +253,8 @@ pub fn _mm256_fmsub_ps(a: __m256, b: __m256, c: __m256) -> __m256 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmsub_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmsub_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_insert!( a, @@ -259,7 +274,8 @@ pub fn _mm_fmsub_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmsub_ss(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmsub_ss(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_insert!( a, @@ -278,7 +294,8 @@ pub fn _mm_fmsub_ss(a: __m128, b: __m128, c: __m128) -> __m128 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmsubadd_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmsubadd_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -295,7 +312,8 @@ pub fn _mm_fmsubadd_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fmsubadd_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmsubadd_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -312,7 +330,8 @@ pub fn _mm256_fmsubadd_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fmsubadd_ps(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmsubadd_ps(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -329,7 +348,8 @@ pub fn _mm_fmsubadd_ps(a: __m128, b: __m128, c: __m128) -> __m128 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fmsubadd_ps(a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmsubadd_ps(a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -345,7 +365,8 @@ pub fn _mm256_fmsubadd_ps(a: __m256, b: __m256, c: __m256) -> __m256 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fnmadd_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmadd_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_fma(simd_neg(a), b, c) } } @@ -357,7 +378,8 @@ pub fn _mm_fnmadd_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fnmadd_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fnmadd_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_fma(simd_neg(a), b, c) } } @@ -369,7 +391,8 @@ pub fn _mm256_fnmadd_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fnmadd_ps(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmadd_ps(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_fma(simd_neg(a), b, c) } } @@ -381,7 +404,8 @@ pub fn _mm_fnmadd_ps(a: __m128, b: __m128, c: __m128) -> __m128 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fnmadd_ps(a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fnmadd_ps(a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_fma(simd_neg(a), b, c) } } @@ -395,7 +419,8 @@ pub fn _mm256_fnmadd_ps(a: __m256, b: __m256, c: __m256) -> __m256 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fnmadd_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmadd_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_insert!( a, @@ -415,7 +440,8 @@ pub fn _mm_fnmadd_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmadd))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fnmadd_ss(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmadd_ss(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_insert!( a, @@ -434,7 +460,8 @@ pub fn _mm_fnmadd_ss(a: __m128, b: __m128, c: __m128) -> __m128 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fnmsub_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmsub_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } } @@ -447,7 +474,8 @@ pub fn _mm_fnmsub_pd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fnmsub_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fnmsub_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } } @@ -460,7 +488,8 @@ pub fn _mm256_fnmsub_pd(a: __m256d, b: __m256d, c: __m256d) -> __m256d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fnmsub_ps(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmsub_ps(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } } @@ -473,7 +502,8 @@ pub fn _mm_fnmsub_ps(a: __m128, b: __m128, c: __m128) -> __m128 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_fnmsub_ps(a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fnmsub_ps(a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } } @@ -488,7 +518,8 @@ pub fn _mm256_fnmsub_ps(a: __m256, b: __m256, c: __m256) -> __m256 { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fnmsub_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmsub_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_insert!( a, @@ -509,7 +540,8 @@ pub fn _mm_fnmsub_sd(a: __m128d, b: __m128d, c: __m128d) -> __m128d { #[target_feature(enable = "fma")] #[cfg_attr(test, assert_instr(vfnmsub))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_fnmsub_ss(a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmsub_ss(a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_insert!( a, @@ -521,13 +553,14 @@ pub fn _mm_fnmsub_ss(a: __m128, b: __m128, c: __m128) -> __m128 { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; #[simd_test(enable = "fma")] - unsafe fn test_mm_fmadd_pd() { + const unsafe fn test_mm_fmadd_pd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -536,7 +569,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fmadd_pd() { + const unsafe fn test_mm256_fmadd_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 3., 7., 2.); let c = _mm256_setr_pd(4., 9., 1., 7.); @@ -545,7 +578,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmadd_ps() { + const unsafe fn test_mm_fmadd_ps() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); @@ -554,7 +587,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fmadd_ps() { + const unsafe fn test_mm256_fmadd_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 0., 10., -1., -2.); let b = _mm256_setr_ps(5., 3., 7., 2., 4., -6., 0., 14.); let c = _mm256_setr_ps(4., 9., 1., 7., -5., 11., -2., -3.); @@ -563,7 +596,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmadd_sd() { + const unsafe fn test_mm_fmadd_sd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -572,7 +605,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmadd_ss() { + const unsafe fn test_mm_fmadd_ss() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); @@ -581,7 +614,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmaddsub_pd() { + const unsafe fn test_mm_fmaddsub_pd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -590,7 +623,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fmaddsub_pd() { + const unsafe fn test_mm256_fmaddsub_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 3., 7., 2.); let c = _mm256_setr_pd(4., 9., 1., 7.); @@ -599,7 +632,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmaddsub_ps() { + const unsafe fn test_mm_fmaddsub_ps() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); @@ -608,7 +641,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fmaddsub_ps() { + const unsafe fn test_mm256_fmaddsub_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 0., 10., -1., -2.); let b = _mm256_setr_ps(5., 3., 7., 2., 4., -6., 0., 14.); let c = _mm256_setr_ps(4., 9., 1., 7., -5., 11., -2., -3.); @@ -617,7 +650,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmsub_pd() { + const unsafe fn test_mm_fmsub_pd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -626,7 +659,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fmsub_pd() { + const unsafe fn test_mm256_fmsub_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 3., 7., 2.); let c = _mm256_setr_pd(4., 9., 1., 7.); @@ -635,7 +668,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmsub_ps() { + const unsafe fn test_mm_fmsub_ps() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); @@ -644,7 +677,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fmsub_ps() { + const unsafe fn test_mm256_fmsub_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 0., 10., -1., -2.); let b = _mm256_setr_ps(5., 3., 7., 2., 4., -6., 0., 14.); let c = _mm256_setr_ps(4., 9., 1., 7., -5., 11., -2., -3.); @@ -653,7 +686,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmsub_sd() { + const unsafe fn test_mm_fmsub_sd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -662,7 +695,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmsub_ss() { + const unsafe fn test_mm_fmsub_ss() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); @@ -671,7 +704,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmsubadd_pd() { + const unsafe fn test_mm_fmsubadd_pd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -680,7 +713,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fmsubadd_pd() { + const unsafe fn test_mm256_fmsubadd_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 3., 7., 2.); let c = _mm256_setr_pd(4., 9., 1., 7.); @@ -689,7 +722,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fmsubadd_ps() { + const unsafe fn test_mm_fmsubadd_ps() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); @@ -698,7 +731,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fmsubadd_ps() { + const unsafe fn test_mm256_fmsubadd_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 0., 10., -1., -2.); let b = _mm256_setr_ps(5., 3., 7., 2., 4., -6., 0., 14.); let c = _mm256_setr_ps(4., 9., 1., 7., -5., 11., -2., -3.); @@ -707,7 +740,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fnmadd_pd() { + const unsafe fn test_mm_fnmadd_pd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -716,7 +749,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fnmadd_pd() { + const unsafe fn test_mm256_fnmadd_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 3., 7., 2.); let c = _mm256_setr_pd(4., 9., 1., 7.); @@ -725,7 +758,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fnmadd_ps() { + const unsafe fn test_mm_fnmadd_ps() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); @@ -734,7 +767,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fnmadd_ps() { + const unsafe fn test_mm256_fnmadd_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 0., 10., -1., -2.); let b = _mm256_setr_ps(5., 3., 7., 2., 4., -6., 0., 14.); let c = _mm256_setr_ps(4., 9., 1., 7., -5., 11., -2., -3.); @@ -743,7 +776,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fnmadd_sd() { + const unsafe fn test_mm_fnmadd_sd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -752,7 +785,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fnmadd_ss() { + const unsafe fn test_mm_fnmadd_ss() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); @@ -761,7 +794,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fnmsub_pd() { + const unsafe fn test_mm_fnmsub_pd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -770,7 +803,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fnmsub_pd() { + const unsafe fn test_mm256_fnmsub_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let b = _mm256_setr_pd(5., 3., 7., 2.); let c = _mm256_setr_pd(4., 9., 1., 7.); @@ -779,7 +812,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fnmsub_ps() { + const unsafe fn test_mm_fnmsub_ps() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); @@ -788,7 +821,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm256_fnmsub_ps() { + const unsafe fn test_mm256_fnmsub_ps() { let a = _mm256_setr_ps(1., 2., 3., 4., 0., 10., -1., -2.); let b = _mm256_setr_ps(5., 3., 7., 2., 4., -6., 0., 14.); let c = _mm256_setr_ps(4., 9., 1., 7., -5., 11., -2., -3.); @@ -797,7 +830,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fnmsub_sd() { + const unsafe fn test_mm_fnmsub_sd() { let a = _mm_setr_pd(1., 2.); let b = _mm_setr_pd(5., 3.); let c = _mm_setr_pd(4., 9.); @@ -806,7 +839,7 @@ mod tests { } #[simd_test(enable = "fma")] - unsafe fn test_mm_fnmsub_ss() { + const unsafe fn test_mm_fnmsub_ss() { let a = _mm_setr_ps(1., 2., 3., 4.); let b = _mm_setr_ps(5., 3., 7., 2.); let c = _mm_setr_ps(4., 9., 1., 7.); From df6119fd3e92ed9fafdbe9f355804d09270aeedb Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 19:11:28 +0530 Subject: [PATCH 0234/3801] Make `avx512f` functions const --- .../crates/core_arch/src/x86/avx512f.rs | 6306 +++++++++++------ .../crates/core_arch/src/x86_64/avx512f.rs | 1305 ++-- 2 files changed, 4751 insertions(+), 2860 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512f.rs b/library/stdarch/crates/core_arch/src/x86/avx512f.rs index d6b30d2d7d86..f300bf48ef6d 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512f.rs @@ -17,7 +17,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsd))] -pub fn _mm512_abs_epi32(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_abs_epi32(a: __m512i) -> __m512i { unsafe { let a = a.as_i32x16(); let r = simd_select::(simd_lt(a, i32x16::ZERO), simd_neg(a), a); @@ -34,7 +35,8 @@ pub fn _mm512_abs_epi32(a: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsd))] -pub fn _mm512_mask_abs_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_abs_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { unsafe { let abs = _mm512_abs_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, abs, src.as_i32x16())) @@ -50,7 +52,8 @@ pub fn _mm512_mask_abs_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsd))] -pub fn _mm512_maskz_abs_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_abs_epi32(k: __mmask16, a: __m512i) -> __m512i { unsafe { let abs = _mm512_abs_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, abs, i32x16::ZERO)) @@ -64,7 +67,8 @@ pub fn _mm512_maskz_abs_epi32(k: __mmask16, a: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsd))] -pub fn _mm256_mask_abs_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_abs_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { unsafe { let abs = _mm256_abs_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, abs, src.as_i32x8())) @@ -78,7 +82,8 @@ pub fn _mm256_mask_abs_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsd))] -pub fn _mm256_maskz_abs_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_abs_epi32(k: __mmask8, a: __m256i) -> __m256i { unsafe { let abs = _mm256_abs_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, abs, i32x8::ZERO)) @@ -92,7 +97,8 @@ pub fn _mm256_maskz_abs_epi32(k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsd))] -pub fn _mm_mask_abs_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_abs_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let abs = _mm_abs_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, abs, src.as_i32x4())) @@ -106,7 +112,8 @@ pub fn _mm_mask_abs_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsd))] -pub fn _mm_maskz_abs_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_abs_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { let abs = _mm_abs_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, abs, i32x4::ZERO)) @@ -120,7 +127,8 @@ pub fn _mm_maskz_abs_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsq))] -pub fn _mm512_abs_epi64(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_abs_epi64(a: __m512i) -> __m512i { unsafe { let a = a.as_i64x8(); let r = simd_select::(simd_lt(a, i64x8::ZERO), simd_neg(a), a); @@ -135,7 +143,8 @@ pub fn _mm512_abs_epi64(a: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsq))] -pub fn _mm512_mask_abs_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_abs_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { unsafe { let abs = _mm512_abs_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, abs, src.as_i64x8())) @@ -149,7 +158,8 @@ pub fn _mm512_mask_abs_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsq))] -pub fn _mm512_maskz_abs_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_abs_epi64(k: __mmask8, a: __m512i) -> __m512i { unsafe { let abs = _mm512_abs_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, abs, i64x8::ZERO)) @@ -163,7 +173,8 @@ pub fn _mm512_maskz_abs_epi64(k: __mmask8, a: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsq))] -pub fn _mm256_abs_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_abs_epi64(a: __m256i) -> __m256i { unsafe { let a = a.as_i64x4(); let r = simd_select::(simd_lt(a, i64x4::ZERO), simd_neg(a), a); @@ -178,7 +189,8 @@ pub fn _mm256_abs_epi64(a: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsq))] -pub fn _mm256_mask_abs_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_abs_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { unsafe { let abs = _mm256_abs_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, abs, src.as_i64x4())) @@ -192,7 +204,8 @@ pub fn _mm256_mask_abs_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsq))] -pub fn _mm256_maskz_abs_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_abs_epi64(k: __mmask8, a: __m256i) -> __m256i { unsafe { let abs = _mm256_abs_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, abs, i64x4::ZERO)) @@ -206,7 +219,8 @@ pub fn _mm256_maskz_abs_epi64(k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsq))] -pub fn _mm_abs_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_abs_epi64(a: __m128i) -> __m128i { unsafe { let a = a.as_i64x2(); let r = simd_select::(simd_lt(a, i64x2::ZERO), simd_neg(a), a); @@ -221,7 +235,8 @@ pub fn _mm_abs_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsq))] -pub fn _mm_mask_abs_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_abs_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let abs = _mm_abs_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, abs, src.as_i64x2())) @@ -235,7 +250,8 @@ pub fn _mm_mask_abs_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsq))] -pub fn _mm_maskz_abs_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_abs_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let abs = _mm_abs_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, abs, i64x2::ZERO)) @@ -249,7 +265,8 @@ pub fn _mm_maskz_abs_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandd))] -pub fn _mm512_abs_ps(v2: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_abs_ps(v2: __m512) -> __m512 { unsafe { simd_fabs(v2) } } @@ -260,7 +277,8 @@ pub fn _mm512_abs_ps(v2: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandd))] -pub fn _mm512_mask_abs_ps(src: __m512, k: __mmask16, v2: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_abs_ps(src: __m512, k: __mmask16, v2: __m512) -> __m512 { unsafe { simd_select_bitmask(k, simd_fabs(v2), src) } } @@ -271,7 +289,8 @@ pub fn _mm512_mask_abs_ps(src: __m512, k: __mmask16, v2: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm512_abs_pd(v2: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_abs_pd(v2: __m512d) -> __m512d { unsafe { simd_fabs(v2) } } @@ -282,7 +301,8 @@ pub fn _mm512_abs_pd(v2: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm512_mask_abs_pd(src: __m512d, k: __mmask8, v2: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_abs_pd(src: __m512d, k: __mmask8, v2: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, simd_fabs(v2), src) } } @@ -293,7 +313,8 @@ pub fn _mm512_mask_abs_pd(src: __m512d, k: __mmask8, v2: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa32))] -pub fn _mm512_mask_mov_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mov_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { unsafe { let mov = a.as_i32x16(); transmute(simd_select_bitmask(k, mov, src.as_i32x16())) @@ -307,7 +328,8 @@ pub fn _mm512_mask_mov_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa32))] -pub fn _mm512_maskz_mov_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mov_epi32(k: __mmask16, a: __m512i) -> __m512i { unsafe { let mov = a.as_i32x16(); transmute(simd_select_bitmask(k, mov, i32x16::ZERO)) @@ -321,7 +343,8 @@ pub fn _mm512_maskz_mov_epi32(k: __mmask16, a: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa32))] -pub fn _mm256_mask_mov_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mov_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { unsafe { let mov = a.as_i32x8(); transmute(simd_select_bitmask(k, mov, src.as_i32x8())) @@ -335,7 +358,8 @@ pub fn _mm256_mask_mov_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa32))] -pub fn _mm256_maskz_mov_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mov_epi32(k: __mmask8, a: __m256i) -> __m256i { unsafe { let mov = a.as_i32x8(); transmute(simd_select_bitmask(k, mov, i32x8::ZERO)) @@ -349,7 +373,8 @@ pub fn _mm256_maskz_mov_epi32(k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa32))] -pub fn _mm_mask_mov_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mov_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let mov = a.as_i32x4(); transmute(simd_select_bitmask(k, mov, src.as_i32x4())) @@ -363,7 +388,8 @@ pub fn _mm_mask_mov_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa32))] -pub fn _mm_maskz_mov_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mov_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { let mov = a.as_i32x4(); transmute(simd_select_bitmask(k, mov, i32x4::ZERO)) @@ -377,7 +403,8 @@ pub fn _mm_maskz_mov_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa64))] -pub fn _mm512_mask_mov_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mov_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { unsafe { let mov = a.as_i64x8(); transmute(simd_select_bitmask(k, mov, src.as_i64x8())) @@ -391,7 +418,8 @@ pub fn _mm512_mask_mov_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa64))] -pub fn _mm512_maskz_mov_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mov_epi64(k: __mmask8, a: __m512i) -> __m512i { unsafe { let mov = a.as_i64x8(); transmute(simd_select_bitmask(k, mov, i64x8::ZERO)) @@ -405,7 +433,8 @@ pub fn _mm512_maskz_mov_epi64(k: __mmask8, a: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa64))] -pub fn _mm256_mask_mov_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mov_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { unsafe { let mov = a.as_i64x4(); transmute(simd_select_bitmask(k, mov, src.as_i64x4())) @@ -419,7 +448,8 @@ pub fn _mm256_mask_mov_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa64))] -pub fn _mm256_maskz_mov_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mov_epi64(k: __mmask8, a: __m256i) -> __m256i { unsafe { let mov = a.as_i64x4(); transmute(simd_select_bitmask(k, mov, i64x4::ZERO)) @@ -433,7 +463,8 @@ pub fn _mm256_maskz_mov_epi64(k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa64))] -pub fn _mm_mask_mov_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mov_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let mov = a.as_i64x2(); transmute(simd_select_bitmask(k, mov, src.as_i64x2())) @@ -447,7 +478,8 @@ pub fn _mm_mask_mov_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa64))] -pub fn _mm_maskz_mov_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mov_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let mov = a.as_i64x2(); transmute(simd_select_bitmask(k, mov, i64x2::ZERO)) @@ -461,7 +493,8 @@ pub fn _mm_maskz_mov_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovaps))] -pub fn _mm512_mask_mov_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mov_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { unsafe { let mov = a.as_f32x16(); transmute(simd_select_bitmask(k, mov, src.as_f32x16())) @@ -475,7 +508,8 @@ pub fn _mm512_mask_mov_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovaps))] -pub fn _mm512_maskz_mov_ps(k: __mmask16, a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mov_ps(k: __mmask16, a: __m512) -> __m512 { unsafe { let mov = a.as_f32x16(); transmute(simd_select_bitmask(k, mov, f32x16::ZERO)) @@ -489,7 +523,8 @@ pub fn _mm512_maskz_mov_ps(k: __mmask16, a: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovaps))] -pub fn _mm256_mask_mov_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mov_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { unsafe { let mov = a.as_f32x8(); transmute(simd_select_bitmask(k, mov, src.as_f32x8())) @@ -503,7 +538,8 @@ pub fn _mm256_mask_mov_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovaps))] -pub fn _mm256_maskz_mov_ps(k: __mmask8, a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mov_ps(k: __mmask8, a: __m256) -> __m256 { unsafe { let mov = a.as_f32x8(); transmute(simd_select_bitmask(k, mov, f32x8::ZERO)) @@ -517,7 +553,8 @@ pub fn _mm256_maskz_mov_ps(k: __mmask8, a: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovaps))] -pub fn _mm_mask_mov_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mov_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { unsafe { let mov = a.as_f32x4(); transmute(simd_select_bitmask(k, mov, src.as_f32x4())) @@ -531,7 +568,8 @@ pub fn _mm_mask_mov_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovaps))] -pub fn _mm_maskz_mov_ps(k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mov_ps(k: __mmask8, a: __m128) -> __m128 { unsafe { let mov = a.as_f32x4(); transmute(simd_select_bitmask(k, mov, f32x4::ZERO)) @@ -545,7 +583,8 @@ pub fn _mm_maskz_mov_ps(k: __mmask8, a: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovapd))] -pub fn _mm512_mask_mov_pd(src: __m512d, k: __mmask8, a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mov_pd(src: __m512d, k: __mmask8, a: __m512d) -> __m512d { unsafe { let mov = a.as_f64x8(); transmute(simd_select_bitmask(k, mov, src.as_f64x8())) @@ -559,7 +598,8 @@ pub fn _mm512_mask_mov_pd(src: __m512d, k: __mmask8, a: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovapd))] -pub fn _mm512_maskz_mov_pd(k: __mmask8, a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mov_pd(k: __mmask8, a: __m512d) -> __m512d { unsafe { let mov = a.as_f64x8(); transmute(simd_select_bitmask(k, mov, f64x8::ZERO)) @@ -573,7 +613,8 @@ pub fn _mm512_maskz_mov_pd(k: __mmask8, a: __m512d) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovapd))] -pub fn _mm256_mask_mov_pd(src: __m256d, k: __mmask8, a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mov_pd(src: __m256d, k: __mmask8, a: __m256d) -> __m256d { unsafe { let mov = a.as_f64x4(); transmute(simd_select_bitmask(k, mov, src.as_f64x4())) @@ -587,7 +628,8 @@ pub fn _mm256_mask_mov_pd(src: __m256d, k: __mmask8, a: __m256d) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovapd))] -pub fn _mm256_maskz_mov_pd(k: __mmask8, a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mov_pd(k: __mmask8, a: __m256d) -> __m256d { unsafe { let mov = a.as_f64x4(); transmute(simd_select_bitmask(k, mov, f64x4::ZERO)) @@ -601,7 +643,8 @@ pub fn _mm256_maskz_mov_pd(k: __mmask8, a: __m256d) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovapd))] -pub fn _mm_mask_mov_pd(src: __m128d, k: __mmask8, a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mov_pd(src: __m128d, k: __mmask8, a: __m128d) -> __m128d { unsafe { let mov = a.as_f64x2(); transmute(simd_select_bitmask(k, mov, src.as_f64x2())) @@ -615,7 +658,8 @@ pub fn _mm_mask_mov_pd(src: __m128d, k: __mmask8, a: __m128d) -> __m128d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovapd))] -pub fn _mm_maskz_mov_pd(k: __mmask8, a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mov_pd(k: __mmask8, a: __m128d) -> __m128d { unsafe { let mov = a.as_f64x2(); transmute(simd_select_bitmask(k, mov, f64x2::ZERO)) @@ -629,7 +673,8 @@ pub fn _mm_maskz_mov_pd(k: __mmask8, a: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddd))] -pub fn _mm512_add_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_add_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_add(a.as_i32x16(), b.as_i32x16())) } } @@ -640,7 +685,8 @@ pub fn _mm512_add_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddd))] -pub fn _mm512_mask_add_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_add_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_add_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, add, src.as_i32x16())) @@ -654,7 +700,8 @@ pub fn _mm512_mask_add_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddd))] -pub fn _mm512_maskz_add_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_add_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_add_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, add, i32x16::ZERO)) @@ -668,7 +715,8 @@ pub fn _mm512_maskz_add_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddd))] -pub fn _mm256_mask_add_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_add_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_add_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, add, src.as_i32x8())) @@ -682,7 +730,8 @@ pub fn _mm256_mask_add_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddd))] -pub fn _mm256_maskz_add_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_add_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_add_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, add, i32x8::ZERO)) @@ -696,7 +745,8 @@ pub fn _mm256_maskz_add_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddd))] -pub fn _mm_mask_add_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_add_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, add, src.as_i32x4())) @@ -710,7 +760,8 @@ pub fn _mm_mask_add_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddd))] -pub fn _mm_maskz_add_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_add_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, add, i32x4::ZERO)) @@ -724,7 +775,8 @@ pub fn _mm_maskz_add_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddq))] -pub fn _mm512_add_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_add_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_add(a.as_i64x8(), b.as_i64x8())) } } @@ -735,7 +787,8 @@ pub fn _mm512_add_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddq))] -pub fn _mm512_mask_add_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_add_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_add_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, add, src.as_i64x8())) @@ -749,7 +802,8 @@ pub fn _mm512_mask_add_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddq))] -pub fn _mm512_maskz_add_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_add_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_add_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, add, i64x8::ZERO)) @@ -763,7 +817,8 @@ pub fn _mm512_maskz_add_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddq))] -pub fn _mm256_mask_add_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_add_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_add_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, add, src.as_i64x4())) @@ -777,7 +832,8 @@ pub fn _mm256_mask_add_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddq))] -pub fn _mm256_maskz_add_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_add_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_add_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, add, i64x4::ZERO)) @@ -791,7 +847,8 @@ pub fn _mm256_maskz_add_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddq))] -pub fn _mm_mask_add_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_add_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, add, src.as_i64x2())) @@ -805,7 +862,8 @@ pub fn _mm_mask_add_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddq))] -pub fn _mm_maskz_add_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_add_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, add, i64x2::ZERO)) @@ -819,7 +877,8 @@ pub fn _mm_maskz_add_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddps))] -pub fn _mm512_add_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_add_ps(a: __m512, b: __m512) -> __m512 { unsafe { transmute(simd_add(a.as_f32x16(), b.as_f32x16())) } } @@ -830,7 +889,8 @@ pub fn _mm512_add_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddps))] -pub fn _mm512_mask_add_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_add_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let add = _mm512_add_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, add, src.as_f32x16())) @@ -844,7 +904,8 @@ pub fn _mm512_mask_add_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddps))] -pub fn _mm512_maskz_add_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_add_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let add = _mm512_add_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, add, f32x16::ZERO)) @@ -858,7 +919,8 @@ pub fn _mm512_maskz_add_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddps))] -pub fn _mm256_mask_add_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_add_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let add = _mm256_add_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, add, src.as_f32x8())) @@ -872,7 +934,8 @@ pub fn _mm256_mask_add_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddps))] -pub fn _mm256_maskz_add_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_add_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let add = _mm256_add_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, add, f32x8::ZERO)) @@ -886,7 +949,8 @@ pub fn _mm256_maskz_add_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddps))] -pub fn _mm_mask_add_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let add = _mm_add_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, add, src.as_f32x4())) @@ -900,7 +964,8 @@ pub fn _mm_mask_add_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddps))] -pub fn _mm_maskz_add_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let add = _mm_add_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, add, f32x4::ZERO)) @@ -914,7 +979,8 @@ pub fn _mm_maskz_add_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddpd))] -pub fn _mm512_add_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_add_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { transmute(simd_add(a.as_f64x8(), b.as_f64x8())) } } @@ -925,7 +991,8 @@ pub fn _mm512_add_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddpd))] -pub fn _mm512_mask_add_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_add_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let add = _mm512_add_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, add, src.as_f64x8())) @@ -939,7 +1006,8 @@ pub fn _mm512_mask_add_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddpd))] -pub fn _mm512_maskz_add_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_add_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let add = _mm512_add_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, add, f64x8::ZERO)) @@ -953,7 +1021,8 @@ pub fn _mm512_maskz_add_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddpd))] -pub fn _mm256_mask_add_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_add_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let add = _mm256_add_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, add, src.as_f64x4())) @@ -967,7 +1036,8 @@ pub fn _mm256_mask_add_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddpd))] -pub fn _mm256_maskz_add_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_add_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let add = _mm256_add_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, add, f64x4::ZERO)) @@ -981,7 +1051,8 @@ pub fn _mm256_maskz_add_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddpd))] -pub fn _mm_mask_add_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let add = _mm_add_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, add, src.as_f64x2())) @@ -995,7 +1066,8 @@ pub fn _mm_mask_add_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddpd))] -pub fn _mm_maskz_add_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let add = _mm_add_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, add, f64x2::ZERO)) @@ -1009,7 +1081,8 @@ pub fn _mm_maskz_add_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubd))] -pub fn _mm512_sub_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sub_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_sub(a.as_i32x16(), b.as_i32x16())) } } @@ -1020,7 +1093,8 @@ pub fn _mm512_sub_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubd))] -pub fn _mm512_mask_sub_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sub_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_sub_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, sub, src.as_i32x16())) @@ -1034,7 +1108,8 @@ pub fn _mm512_mask_sub_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubd))] -pub fn _mm512_maskz_sub_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sub_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_sub_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, sub, i32x16::ZERO)) @@ -1048,7 +1123,8 @@ pub fn _mm512_maskz_sub_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubd))] -pub fn _mm256_mask_sub_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sub_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_sub_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, sub, src.as_i32x8())) @@ -1062,7 +1138,8 @@ pub fn _mm256_mask_sub_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubd))] -pub fn _mm256_maskz_sub_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sub_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_sub_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, sub, i32x8::ZERO)) @@ -1076,7 +1153,8 @@ pub fn _mm256_maskz_sub_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubd))] -pub fn _mm_mask_sub_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_sub_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, sub, src.as_i32x4())) @@ -1090,7 +1168,8 @@ pub fn _mm_mask_sub_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubd))] -pub fn _mm_maskz_sub_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_sub_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, sub, i32x4::ZERO)) @@ -1104,7 +1183,8 @@ pub fn _mm_maskz_sub_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubq))] -pub fn _mm512_sub_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sub_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_sub(a.as_i64x8(), b.as_i64x8())) } } @@ -1115,7 +1195,8 @@ pub fn _mm512_sub_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubq))] -pub fn _mm512_mask_sub_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sub_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_sub_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, sub, src.as_i64x8())) @@ -1129,7 +1210,8 @@ pub fn _mm512_mask_sub_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubq))] -pub fn _mm512_maskz_sub_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sub_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_sub_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, sub, i64x8::ZERO)) @@ -1143,7 +1225,8 @@ pub fn _mm512_maskz_sub_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubq))] -pub fn _mm256_mask_sub_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sub_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_sub_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, sub, src.as_i64x4())) @@ -1157,7 +1240,8 @@ pub fn _mm256_mask_sub_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubq))] -pub fn _mm256_maskz_sub_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sub_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_sub_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, sub, i64x4::ZERO)) @@ -1171,7 +1255,8 @@ pub fn _mm256_maskz_sub_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubq))] -pub fn _mm_mask_sub_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_sub_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, sub, src.as_i64x2())) @@ -1185,7 +1270,8 @@ pub fn _mm_mask_sub_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubq))] -pub fn _mm_maskz_sub_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_sub_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, sub, i64x2::ZERO)) @@ -1199,7 +1285,8 @@ pub fn _mm_maskz_sub_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubps))] -pub fn _mm512_sub_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sub_ps(a: __m512, b: __m512) -> __m512 { unsafe { transmute(simd_sub(a.as_f32x16(), b.as_f32x16())) } } @@ -1210,7 +1297,8 @@ pub fn _mm512_sub_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubps))] -pub fn _mm512_mask_sub_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sub_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let sub = _mm512_sub_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, sub, src.as_f32x16())) @@ -1224,7 +1312,8 @@ pub fn _mm512_mask_sub_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubps))] -pub fn _mm512_maskz_sub_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sub_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let sub = _mm512_sub_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, sub, f32x16::ZERO)) @@ -1238,7 +1327,8 @@ pub fn _mm512_maskz_sub_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubps))] -pub fn _mm256_mask_sub_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sub_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let sub = _mm256_sub_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, sub, src.as_f32x8())) @@ -1252,7 +1342,8 @@ pub fn _mm256_mask_sub_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubps))] -pub fn _mm256_maskz_sub_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sub_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let sub = _mm256_sub_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, sub, f32x8::ZERO)) @@ -1266,7 +1357,8 @@ pub fn _mm256_maskz_sub_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubps))] -pub fn _mm_mask_sub_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let sub = _mm_sub_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, sub, src.as_f32x4())) @@ -1280,7 +1372,8 @@ pub fn _mm_mask_sub_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubps))] -pub fn _mm_maskz_sub_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let sub = _mm_sub_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, sub, f32x4::ZERO)) @@ -1294,7 +1387,8 @@ pub fn _mm_maskz_sub_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubpd))] -pub fn _mm512_sub_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sub_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { transmute(simd_sub(a.as_f64x8(), b.as_f64x8())) } } @@ -1305,7 +1399,8 @@ pub fn _mm512_sub_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubpd))] -pub fn _mm512_mask_sub_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sub_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let sub = _mm512_sub_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, sub, src.as_f64x8())) @@ -1319,7 +1414,8 @@ pub fn _mm512_mask_sub_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubpd))] -pub fn _mm512_maskz_sub_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sub_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let sub = _mm512_sub_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, sub, f64x8::ZERO)) @@ -1333,7 +1429,8 @@ pub fn _mm512_maskz_sub_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubpd))] -pub fn _mm256_mask_sub_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sub_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let sub = _mm256_sub_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, sub, src.as_f64x4())) @@ -1347,7 +1444,8 @@ pub fn _mm256_mask_sub_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubpd))] -pub fn _mm256_maskz_sub_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sub_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let sub = _mm256_sub_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, sub, f64x4::ZERO)) @@ -1361,7 +1459,8 @@ pub fn _mm256_maskz_sub_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubpd))] -pub fn _mm_mask_sub_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let sub = _mm_sub_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, sub, src.as_f64x2())) @@ -1375,7 +1474,8 @@ pub fn _mm_mask_sub_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubpd))] -pub fn _mm_maskz_sub_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let sub = _mm_sub_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, sub, f64x2::ZERO)) @@ -1389,7 +1489,8 @@ pub fn _mm_maskz_sub_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuldq))] -pub fn _mm512_mul_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mul_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = simd_cast::<_, i64x8>(simd_cast::<_, i32x8>(a.as_i64x8())); let b = simd_cast::<_, i64x8>(simd_cast::<_, i32x8>(b.as_i64x8())); @@ -1404,7 +1505,8 @@ pub fn _mm512_mul_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuldq))] -pub fn _mm512_mask_mul_epi32(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mul_epi32(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let mul = _mm512_mul_epi32(a, b).as_i64x8(); transmute(simd_select_bitmask(k, mul, src.as_i64x8())) @@ -1418,7 +1520,8 @@ pub fn _mm512_mask_mul_epi32(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuldq))] -pub fn _mm512_maskz_mul_epi32(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mul_epi32(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let mul = _mm512_mul_epi32(a, b).as_i64x8(); transmute(simd_select_bitmask(k, mul, i64x8::ZERO)) @@ -1432,7 +1535,8 @@ pub fn _mm512_maskz_mul_epi32(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuldq))] -pub fn _mm256_mask_mul_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mul_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let mul = _mm256_mul_epi32(a, b).as_i64x4(); transmute(simd_select_bitmask(k, mul, src.as_i64x4())) @@ -1446,7 +1550,8 @@ pub fn _mm256_mask_mul_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuldq))] -pub fn _mm256_maskz_mul_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mul_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let mul = _mm256_mul_epi32(a, b).as_i64x4(); transmute(simd_select_bitmask(k, mul, i64x4::ZERO)) @@ -1460,7 +1565,8 @@ pub fn _mm256_maskz_mul_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuldq))] -pub fn _mm_mask_mul_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mul_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mul_epi32(a, b).as_i64x2(); transmute(simd_select_bitmask(k, mul, src.as_i64x2())) @@ -1474,7 +1580,8 @@ pub fn _mm_mask_mul_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuldq))] -pub fn _mm_maskz_mul_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mul_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mul_epi32(a, b).as_i64x2(); transmute(simd_select_bitmask(k, mul, i64x2::ZERO)) @@ -1488,7 +1595,8 @@ pub fn _mm_maskz_mul_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulld))] -pub fn _mm512_mullo_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mullo_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_mul(a.as_i32x16(), b.as_i32x16())) } } @@ -1499,7 +1607,13 @@ pub fn _mm512_mullo_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulld))] -pub fn _mm512_mask_mullo_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mullo_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let mul = _mm512_mullo_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, mul, src.as_i32x16())) @@ -1513,7 +1627,8 @@ pub fn _mm512_mask_mullo_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulld))] -pub fn _mm512_maskz_mullo_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mullo_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let mul = _mm512_mullo_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, mul, i32x16::ZERO)) @@ -1527,7 +1642,8 @@ pub fn _mm512_maskz_mullo_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulld))] -pub fn _mm256_mask_mullo_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mullo_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let mul = _mm256_mullo_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, mul, src.as_i32x8())) @@ -1541,7 +1657,8 @@ pub fn _mm256_mask_mullo_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulld))] -pub fn _mm256_maskz_mullo_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mullo_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let mul = _mm256_mullo_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, mul, i32x8::ZERO)) @@ -1555,7 +1672,8 @@ pub fn _mm256_maskz_mullo_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulld))] -pub fn _mm_mask_mullo_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mullo_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mullo_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, mul, src.as_i32x4())) @@ -1569,7 +1687,8 @@ pub fn _mm_mask_mullo_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulld))] -pub fn _mm_maskz_mullo_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mullo_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mullo_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, mul, i32x4::ZERO)) @@ -1584,7 +1703,8 @@ pub fn _mm_maskz_mullo_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mullox_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mullox_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_mul(a.as_i64x8(), b.as_i64x8())) } } @@ -1596,7 +1716,13 @@ pub fn _mm512_mullox_epi64(a: __m512i, b: __m512i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_mullox_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mullox_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let mul = _mm512_mullox_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, mul, src.as_i64x8())) @@ -1610,11 +1736,12 @@ pub fn _mm512_mask_mullox_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuludq))] -pub fn _mm512_mul_epu32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mul_epu32(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = a.as_u64x8(); let b = b.as_u64x8(); - let mask = u64x8::splat(u32::MAX.into()); + let mask = u64x8::splat(u32::MAX as u64); transmute(simd_mul(simd_and(a, mask), simd_and(b, mask))) } } @@ -1626,7 +1753,8 @@ pub fn _mm512_mul_epu32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuludq))] -pub fn _mm512_mask_mul_epu32(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mul_epu32(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let mul = _mm512_mul_epu32(a, b).as_u64x8(); transmute(simd_select_bitmask(k, mul, src.as_u64x8())) @@ -1640,7 +1768,8 @@ pub fn _mm512_mask_mul_epu32(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuludq))] -pub fn _mm512_maskz_mul_epu32(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mul_epu32(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let mul = _mm512_mul_epu32(a, b).as_u64x8(); transmute(simd_select_bitmask(k, mul, u64x8::ZERO)) @@ -1654,7 +1783,8 @@ pub fn _mm512_maskz_mul_epu32(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuludq))] -pub fn _mm256_mask_mul_epu32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mul_epu32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let mul = _mm256_mul_epu32(a, b).as_u64x4(); transmute(simd_select_bitmask(k, mul, src.as_u64x4())) @@ -1668,7 +1798,8 @@ pub fn _mm256_mask_mul_epu32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuludq))] -pub fn _mm256_maskz_mul_epu32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mul_epu32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let mul = _mm256_mul_epu32(a, b).as_u64x4(); transmute(simd_select_bitmask(k, mul, u64x4::ZERO)) @@ -1682,7 +1813,8 @@ pub fn _mm256_maskz_mul_epu32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuludq))] -pub fn _mm_mask_mul_epu32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mul_epu32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mul_epu32(a, b).as_u64x2(); transmute(simd_select_bitmask(k, mul, src.as_u64x2())) @@ -1696,7 +1828,8 @@ pub fn _mm_mask_mul_epu32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmuludq))] -pub fn _mm_maskz_mul_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mul_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mul_epu32(a, b).as_u64x2(); transmute(simd_select_bitmask(k, mul, u64x2::ZERO)) @@ -1710,7 +1843,8 @@ pub fn _mm_maskz_mul_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulps))] -pub fn _mm512_mul_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mul_ps(a: __m512, b: __m512) -> __m512 { unsafe { transmute(simd_mul(a.as_f32x16(), b.as_f32x16())) } } @@ -1721,7 +1855,8 @@ pub fn _mm512_mul_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulps))] -pub fn _mm512_mask_mul_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mul_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let mul = _mm512_mul_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, mul, src.as_f32x16())) @@ -1735,7 +1870,8 @@ pub fn _mm512_mask_mul_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulps))] -pub fn _mm512_maskz_mul_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mul_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let mul = _mm512_mul_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, mul, f32x16::ZERO)) @@ -1749,7 +1885,8 @@ pub fn _mm512_maskz_mul_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulps))] -pub fn _mm256_mask_mul_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mul_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let mul = _mm256_mul_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, mul, src.as_f32x8())) @@ -1763,7 +1900,8 @@ pub fn _mm256_mask_mul_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulps))] -pub fn _mm256_maskz_mul_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mul_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let mul = _mm256_mul_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, mul, f32x8::ZERO)) @@ -1777,7 +1915,8 @@ pub fn _mm256_maskz_mul_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulps))] -pub fn _mm_mask_mul_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mul_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let mul = _mm_mul_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, mul, src.as_f32x4())) @@ -1791,7 +1930,8 @@ pub fn _mm_mask_mul_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulps))] -pub fn _mm_maskz_mul_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mul_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let mul = _mm_mul_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, mul, f32x4::ZERO)) @@ -1805,7 +1945,8 @@ pub fn _mm_maskz_mul_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulpd))] -pub fn _mm512_mul_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mul_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { transmute(simd_mul(a.as_f64x8(), b.as_f64x8())) } } @@ -1816,7 +1957,8 @@ pub fn _mm512_mul_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulpd))] -pub fn _mm512_mask_mul_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mul_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let mul = _mm512_mul_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, mul, src.as_f64x8())) @@ -1830,7 +1972,8 @@ pub fn _mm512_mask_mul_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulpd))] -pub fn _mm512_maskz_mul_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mul_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let mul = _mm512_mul_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, mul, f64x8::ZERO)) @@ -1844,7 +1987,8 @@ pub fn _mm512_maskz_mul_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulpd))] -pub fn _mm256_mask_mul_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mul_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let mul = _mm256_mul_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, mul, src.as_f64x4())) @@ -1858,7 +2002,8 @@ pub fn _mm256_mask_mul_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulpd))] -pub fn _mm256_maskz_mul_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mul_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let mul = _mm256_mul_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, mul, f64x4::ZERO)) @@ -1872,7 +2017,8 @@ pub fn _mm256_maskz_mul_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulpd))] -pub fn _mm_mask_mul_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mul_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let mul = _mm_mul_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, mul, src.as_f64x2())) @@ -1886,7 +2032,8 @@ pub fn _mm_mask_mul_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulpd))] -pub fn _mm_maskz_mul_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mul_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let mul = _mm_mul_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, mul, f64x2::ZERO)) @@ -1900,7 +2047,8 @@ pub fn _mm_maskz_mul_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivps))] -pub fn _mm512_div_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_div_ps(a: __m512, b: __m512) -> __m512 { unsafe { transmute(simd_div(a.as_f32x16(), b.as_f32x16())) } } @@ -1911,7 +2059,8 @@ pub fn _mm512_div_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivps))] -pub fn _mm512_mask_div_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_div_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let div = _mm512_div_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, div, src.as_f32x16())) @@ -1925,7 +2074,8 @@ pub fn _mm512_mask_div_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivps))] -pub fn _mm512_maskz_div_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_div_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let div = _mm512_div_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, div, f32x16::ZERO)) @@ -1939,7 +2089,8 @@ pub fn _mm512_maskz_div_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivps))] -pub fn _mm256_mask_div_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_div_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let div = _mm256_div_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, div, src.as_f32x8())) @@ -1953,7 +2104,8 @@ pub fn _mm256_mask_div_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivps))] -pub fn _mm256_maskz_div_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_div_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let div = _mm256_div_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, div, f32x8::ZERO)) @@ -1967,7 +2119,8 @@ pub fn _mm256_maskz_div_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivps))] -pub fn _mm_mask_div_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_div_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let div = _mm_div_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, div, src.as_f32x4())) @@ -1981,7 +2134,8 @@ pub fn _mm_mask_div_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivps))] -pub fn _mm_maskz_div_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_div_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let div = _mm_div_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, div, f32x4::ZERO)) @@ -1995,7 +2149,8 @@ pub fn _mm_maskz_div_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivpd))] -pub fn _mm512_div_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_div_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { transmute(simd_div(a.as_f64x8(), b.as_f64x8())) } } @@ -2006,7 +2161,8 @@ pub fn _mm512_div_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivpd))] -pub fn _mm512_mask_div_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_div_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let div = _mm512_div_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, div, src.as_f64x8())) @@ -2020,7 +2176,8 @@ pub fn _mm512_mask_div_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivpd))] -pub fn _mm512_maskz_div_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_div_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let div = _mm512_div_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, div, f64x8::ZERO)) @@ -2034,7 +2191,8 @@ pub fn _mm512_maskz_div_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivpd))] -pub fn _mm256_mask_div_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_div_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let div = _mm256_div_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, div, src.as_f64x4())) @@ -2048,7 +2206,8 @@ pub fn _mm256_mask_div_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivpd))] -pub fn _mm256_maskz_div_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_div_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let div = _mm256_div_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, div, f64x4::ZERO)) @@ -2062,7 +2221,8 @@ pub fn _mm256_maskz_div_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivpd))] -pub fn _mm_mask_div_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_div_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let div = _mm_div_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, div, src.as_f64x2())) @@ -2076,7 +2236,8 @@ pub fn _mm_mask_div_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivpd))] -pub fn _mm_maskz_div_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_div_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let div = _mm_div_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, div, f64x2::ZERO)) @@ -2090,7 +2251,8 @@ pub fn _mm_maskz_div_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsd))] -pub fn _mm512_max_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_max_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imax(a.as_i32x16(), b.as_i32x16()).as_m512i() } } @@ -2101,7 +2263,8 @@ pub fn _mm512_max_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsd))] -pub fn _mm512_mask_max_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_max_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, max, src.as_i32x16())) @@ -2115,7 +2278,8 @@ pub fn _mm512_mask_max_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsd))] -pub fn _mm512_maskz_max_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_max_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, max, i32x16::ZERO)) @@ -2129,7 +2293,8 @@ pub fn _mm512_maskz_max_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsd))] -pub fn _mm256_mask_max_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_max_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, max, src.as_i32x8())) @@ -2143,7 +2308,8 @@ pub fn _mm256_mask_max_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsd))] -pub fn _mm256_maskz_max_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_max_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, max, i32x8::ZERO)) @@ -2157,7 +2323,8 @@ pub fn _mm256_maskz_max_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsd))] -pub fn _mm_mask_max_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_max_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, max, src.as_i32x4())) @@ -2171,7 +2338,8 @@ pub fn _mm_mask_max_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsd))] -pub fn _mm_maskz_max_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_max_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, max, i32x4::ZERO)) @@ -2185,7 +2353,8 @@ pub fn _mm_maskz_max_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] -pub fn _mm512_max_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_max_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imax(a.as_i64x8(), b.as_i64x8()).as_m512i() } } @@ -2196,7 +2365,8 @@ pub fn _mm512_max_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] -pub fn _mm512_mask_max_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_max_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, max, src.as_i64x8())) @@ -2210,7 +2380,8 @@ pub fn _mm512_mask_max_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] -pub fn _mm512_maskz_max_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_max_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, max, i64x8::ZERO)) @@ -2224,7 +2395,8 @@ pub fn _mm512_maskz_max_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] -pub fn _mm256_max_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_max_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imax(a.as_i64x4(), b.as_i64x4()).as_m256i() } } @@ -2235,7 +2407,8 @@ pub fn _mm256_max_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] -pub fn _mm256_mask_max_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_max_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, max, src.as_i64x4())) @@ -2249,7 +2422,8 @@ pub fn _mm256_mask_max_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] -pub fn _mm256_maskz_max_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_max_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, max, i64x4::ZERO)) @@ -2263,7 +2437,8 @@ pub fn _mm256_maskz_max_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] -pub fn _mm_max_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_max_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imax(a.as_i64x2(), b.as_i64x2()).as_m128i() } } @@ -2274,7 +2449,8 @@ pub fn _mm_max_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] -pub fn _mm_mask_max_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_max_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, max, src.as_i64x2())) @@ -2288,7 +2464,8 @@ pub fn _mm_mask_max_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsq))] -pub fn _mm_maskz_max_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_max_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, max, i64x2::ZERO)) @@ -2498,7 +2675,8 @@ pub fn _mm_maskz_max_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxud))] -pub fn _mm512_max_epu32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_max_epu32(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imax(a.as_u32x16(), b.as_u32x16()).as_m512i() } } @@ -2509,7 +2687,8 @@ pub fn _mm512_max_epu32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxud))] -pub fn _mm512_mask_max_epu32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_max_epu32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epu32(a, b).as_u32x16(); transmute(simd_select_bitmask(k, max, src.as_u32x16())) @@ -2523,7 +2702,8 @@ pub fn _mm512_mask_max_epu32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxud))] -pub fn _mm512_maskz_max_epu32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_max_epu32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epu32(a, b).as_u32x16(); transmute(simd_select_bitmask(k, max, u32x16::ZERO)) @@ -2537,7 +2717,8 @@ pub fn _mm512_maskz_max_epu32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxud))] -pub fn _mm256_mask_max_epu32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_max_epu32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epu32(a, b).as_u32x8(); transmute(simd_select_bitmask(k, max, src.as_u32x8())) @@ -2551,7 +2732,8 @@ pub fn _mm256_mask_max_epu32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxud))] -pub fn _mm256_maskz_max_epu32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_max_epu32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epu32(a, b).as_u32x8(); transmute(simd_select_bitmask(k, max, u32x8::ZERO)) @@ -2565,7 +2747,8 @@ pub fn _mm256_maskz_max_epu32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxud))] -pub fn _mm_mask_max_epu32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_max_epu32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epu32(a, b).as_u32x4(); transmute(simd_select_bitmask(k, max, src.as_u32x4())) @@ -2579,7 +2762,8 @@ pub fn _mm_mask_max_epu32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxud))] -pub fn _mm_maskz_max_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_max_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epu32(a, b).as_u32x4(); transmute(simd_select_bitmask(k, max, u32x4::ZERO)) @@ -2593,7 +2777,8 @@ pub fn _mm_maskz_max_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] -pub fn _mm512_max_epu64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_max_epu64(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imax(a.as_u64x8(), b.as_u64x8()).as_m512i() } } @@ -2604,7 +2789,8 @@ pub fn _mm512_max_epu64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] -pub fn _mm512_mask_max_epu64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_max_epu64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epu64(a, b).as_u64x8(); transmute(simd_select_bitmask(k, max, src.as_u64x8())) @@ -2618,7 +2804,8 @@ pub fn _mm512_mask_max_epu64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] -pub fn _mm512_maskz_max_epu64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_max_epu64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epu64(a, b).as_u64x8(); transmute(simd_select_bitmask(k, max, u64x8::ZERO)) @@ -2632,7 +2819,8 @@ pub fn _mm512_maskz_max_epu64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] -pub fn _mm256_max_epu64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_max_epu64(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imax(a.as_u64x4(), b.as_u64x4()).as_m256i() } } @@ -2643,7 +2831,8 @@ pub fn _mm256_max_epu64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] -pub fn _mm256_mask_max_epu64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_max_epu64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epu64(a, b).as_u64x4(); transmute(simd_select_bitmask(k, max, src.as_u64x4())) @@ -2657,7 +2846,8 @@ pub fn _mm256_mask_max_epu64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] -pub fn _mm256_maskz_max_epu64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_max_epu64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epu64(a, b).as_u64x4(); transmute(simd_select_bitmask(k, max, u64x4::ZERO)) @@ -2671,7 +2861,8 @@ pub fn _mm256_maskz_max_epu64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] -pub fn _mm_max_epu64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_max_epu64(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imax(a.as_u64x2(), b.as_u64x2()).as_m128i() } } @@ -2682,7 +2873,8 @@ pub fn _mm_max_epu64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] -pub fn _mm_mask_max_epu64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_max_epu64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epu64(a, b).as_u64x2(); transmute(simd_select_bitmask(k, max, src.as_u64x2())) @@ -2696,7 +2888,8 @@ pub fn _mm_mask_max_epu64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuq))] -pub fn _mm_maskz_max_epu64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_max_epu64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epu64(a, b).as_u64x2(); transmute(simd_select_bitmask(k, max, u64x2::ZERO)) @@ -2710,7 +2903,8 @@ pub fn _mm_maskz_max_epu64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsd))] -pub fn _mm512_min_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_min_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imin(a.as_i32x16(), b.as_i32x16()).as_m512i() } } @@ -2721,7 +2915,8 @@ pub fn _mm512_min_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsd))] -pub fn _mm512_mask_min_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_min_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, min, src.as_i32x16())) @@ -2735,7 +2930,8 @@ pub fn _mm512_mask_min_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsd))] -pub fn _mm512_maskz_min_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_min_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, min, i32x16::ZERO)) @@ -2749,7 +2945,8 @@ pub fn _mm512_maskz_min_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsd))] -pub fn _mm256_mask_min_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_min_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, min, src.as_i32x8())) @@ -2763,7 +2960,8 @@ pub fn _mm256_mask_min_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsd))] -pub fn _mm256_maskz_min_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_min_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, min, i32x8::ZERO)) @@ -2777,7 +2975,8 @@ pub fn _mm256_maskz_min_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsd))] -pub fn _mm_mask_min_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_min_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, min, src.as_i32x4())) @@ -2791,7 +2990,8 @@ pub fn _mm_mask_min_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsd))] -pub fn _mm_maskz_min_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_min_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, min, i32x4::ZERO)) @@ -2805,7 +3005,8 @@ pub fn _mm_maskz_min_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] -pub fn _mm512_min_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_min_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imin(a.as_i64x8(), b.as_i64x8()).as_m512i() } } @@ -2816,7 +3017,8 @@ pub fn _mm512_min_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] -pub fn _mm512_mask_min_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_min_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, min, src.as_i64x8())) @@ -2830,7 +3032,8 @@ pub fn _mm512_mask_min_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] -pub fn _mm512_maskz_min_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_min_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, min, i64x8::ZERO)) @@ -2844,7 +3047,8 @@ pub fn _mm512_maskz_min_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] -pub fn _mm256_min_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_min_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imin(a.as_i64x4(), b.as_i64x4()).as_m256i() } } @@ -2855,7 +3059,8 @@ pub fn _mm256_min_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] -pub fn _mm256_mask_min_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_min_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, min, src.as_i64x4())) @@ -2869,7 +3074,8 @@ pub fn _mm256_mask_min_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] -pub fn _mm256_maskz_min_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_min_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, min, i64x4::ZERO)) @@ -2883,7 +3089,8 @@ pub fn _mm256_maskz_min_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] -pub fn _mm_min_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_min_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_i64x2(), b.as_i64x2()).as_m128i() } } @@ -2894,7 +3101,8 @@ pub fn _mm_min_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] -pub fn _mm_mask_min_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_min_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, min, src.as_i64x2())) @@ -2908,7 +3116,8 @@ pub fn _mm_mask_min_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsq))] -pub fn _mm_maskz_min_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_min_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, min, i64x2::ZERO)) @@ -3118,7 +3327,8 @@ pub fn _mm_maskz_min_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminud))] -pub fn _mm512_min_epu32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_min_epu32(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imin(a.as_u32x16(), b.as_u32x16()).as_m512i() } } @@ -3129,7 +3339,8 @@ pub fn _mm512_min_epu32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminud))] -pub fn _mm512_mask_min_epu32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_min_epu32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epu32(a, b).as_u32x16(); transmute(simd_select_bitmask(k, min, src.as_u32x16())) @@ -3143,7 +3354,8 @@ pub fn _mm512_mask_min_epu32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminud))] -pub fn _mm512_maskz_min_epu32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_min_epu32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epu32(a, b).as_u32x16(); transmute(simd_select_bitmask(k, min, u32x16::ZERO)) @@ -3157,7 +3369,8 @@ pub fn _mm512_maskz_min_epu32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminud))] -pub fn _mm256_mask_min_epu32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_min_epu32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epu32(a, b).as_u32x8(); transmute(simd_select_bitmask(k, min, src.as_u32x8())) @@ -3171,7 +3384,8 @@ pub fn _mm256_mask_min_epu32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminud))] -pub fn _mm256_maskz_min_epu32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_min_epu32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epu32(a, b).as_u32x8(); transmute(simd_select_bitmask(k, min, u32x8::ZERO)) @@ -3185,7 +3399,8 @@ pub fn _mm256_maskz_min_epu32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminud))] -pub fn _mm_mask_min_epu32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_min_epu32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epu32(a, b).as_u32x4(); transmute(simd_select_bitmask(k, min, src.as_u32x4())) @@ -3199,7 +3414,8 @@ pub fn _mm_mask_min_epu32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminud))] -pub fn _mm_maskz_min_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_min_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epu32(a, b).as_u32x4(); transmute(simd_select_bitmask(k, min, u32x4::ZERO)) @@ -3213,7 +3429,8 @@ pub fn _mm_maskz_min_epu32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] -pub fn _mm512_min_epu64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_min_epu64(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imin(a.as_u64x8(), b.as_u64x8()).as_m512i() } } @@ -3224,7 +3441,8 @@ pub fn _mm512_min_epu64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] -pub fn _mm512_mask_min_epu64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_min_epu64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epu64(a, b).as_u64x8(); transmute(simd_select_bitmask(k, min, src.as_u64x8())) @@ -3238,7 +3456,8 @@ pub fn _mm512_mask_min_epu64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] -pub fn _mm512_maskz_min_epu64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_min_epu64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epu64(a, b).as_u64x8(); transmute(simd_select_bitmask(k, min, u64x8::ZERO)) @@ -3252,7 +3471,8 @@ pub fn _mm512_maskz_min_epu64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] -pub fn _mm256_min_epu64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_min_epu64(a: __m256i, b: __m256i) -> __m256i { unsafe { simd_imin(a.as_u64x4(), b.as_u64x4()).as_m256i() } } @@ -3263,7 +3483,8 @@ pub fn _mm256_min_epu64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] -pub fn _mm256_mask_min_epu64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_min_epu64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epu64(a, b).as_u64x4(); transmute(simd_select_bitmask(k, min, src.as_u64x4())) @@ -3277,7 +3498,8 @@ pub fn _mm256_mask_min_epu64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] -pub fn _mm256_maskz_min_epu64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_min_epu64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epu64(a, b).as_u64x4(); transmute(simd_select_bitmask(k, min, u64x4::ZERO)) @@ -3291,7 +3513,8 @@ pub fn _mm256_maskz_min_epu64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] -pub fn _mm_min_epu64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_min_epu64(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_u64x2(), b.as_u64x2()).as_m128i() } } @@ -3302,7 +3525,8 @@ pub fn _mm_min_epu64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] -pub fn _mm_mask_min_epu64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_min_epu64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epu64(a, b).as_u64x2(); transmute(simd_select_bitmask(k, min, src.as_u64x2())) @@ -3316,7 +3540,8 @@ pub fn _mm_mask_min_epu64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuq))] -pub fn _mm_maskz_min_epu64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_min_epu64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epu64(a, b).as_u64x2(); transmute(simd_select_bitmask(k, min, u64x2::ZERO)) @@ -3484,7 +3709,8 @@ pub fn _mm_maskz_sqrt_pd(k: __mmask8, a: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm512_fmadd_ps(a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmadd_ps(a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_fma(a, b, c) } } @@ -3495,7 +3721,8 @@ pub fn _mm512_fmadd_ps(a: __m512, b: __m512, c: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm512_mask_fmadd_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmadd_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmadd_ps(a, b, c), a) } } @@ -3506,7 +3733,8 @@ pub fn _mm512_mask_fmadd_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm512_maskz_fmadd_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmadd_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmadd_ps(a, b, c), _mm512_setzero_ps()) } } @@ -3517,7 +3745,8 @@ pub fn _mm512_maskz_fmadd_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> _ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm512_mask3_fmadd_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmadd_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmadd_ps(a, b, c), c) } } @@ -3528,7 +3757,8 @@ pub fn _mm512_mask3_fmadd_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm256_mask_fmadd_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmadd_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmadd_ps(a, b, c), a) } } @@ -3539,7 +3769,8 @@ pub fn _mm256_mask_fmadd_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm256_maskz_fmadd_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmadd_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmadd_ps(a, b, c), _mm256_setzero_ps()) } } @@ -3550,7 +3781,8 @@ pub fn _mm256_maskz_fmadd_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm256_mask3_fmadd_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmadd_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmadd_ps(a, b, c), c) } } @@ -3561,7 +3793,8 @@ pub fn _mm256_mask3_fmadd_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm_mask_fmadd_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmadd_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmadd_ps(a, b, c), a) } } @@ -3572,7 +3805,8 @@ pub fn _mm_mask_fmadd_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm_maskz_fmadd_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmadd_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmadd_ps(a, b, c), _mm_setzero_ps()) } } @@ -3583,7 +3817,8 @@ pub fn _mm_maskz_fmadd_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m12 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132ps or vfmadd213ps or vfmadd231ps -pub fn _mm_mask3_fmadd_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmadd_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmadd_ps(a, b, c), c) } } @@ -3594,7 +3829,8 @@ pub fn _mm_mask3_fmadd_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm512_fmadd_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmadd_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_fma(a, b, c) } } @@ -3605,7 +3841,8 @@ pub fn _mm512_fmadd_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm512_mask_fmadd_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmadd_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmadd_pd(a, b, c), a) } } @@ -3616,7 +3853,8 @@ pub fn _mm512_mask_fmadd_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm512_maskz_fmadd_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmadd_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmadd_pd(a, b, c), _mm512_setzero_pd()) } } @@ -3627,7 +3865,8 @@ pub fn _mm512_maskz_fmadd_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm512_mask3_fmadd_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmadd_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmadd_pd(a, b, c), c) } } @@ -3638,7 +3877,8 @@ pub fn _mm512_mask3_fmadd_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm256_mask_fmadd_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmadd_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmadd_pd(a, b, c), a) } } @@ -3649,7 +3889,8 @@ pub fn _mm256_mask_fmadd_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm256_maskz_fmadd_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmadd_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmadd_pd(a, b, c), _mm256_setzero_pd()) } } @@ -3660,7 +3901,8 @@ pub fn _mm256_maskz_fmadd_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm256_mask3_fmadd_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmadd_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmadd_pd(a, b, c), c) } } @@ -3671,7 +3913,8 @@ pub fn _mm256_mask3_fmadd_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm_mask_fmadd_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmadd_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmadd_pd(a, b, c), a) } } @@ -3682,7 +3925,8 @@ pub fn _mm_mask_fmadd_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm_maskz_fmadd_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmadd_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmadd_pd(a, b, c), _mm_setzero_pd()) } } @@ -3693,7 +3937,8 @@ pub fn _mm_maskz_fmadd_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] //vfmadd132pd or vfmadd213pd or vfmadd231pd -pub fn _mm_mask3_fmadd_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmadd_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmadd_pd(a, b, c), c) } } @@ -3704,7 +3949,8 @@ pub fn _mm_mask3_fmadd_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm512_fmsub_ps(a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmsub_ps(a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_fma(a, b, simd_neg(c)) } } @@ -3715,7 +3961,8 @@ pub fn _mm512_fmsub_ps(a: __m512, b: __m512, c: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm512_mask_fmsub_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmsub_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmsub_ps(a, b, c), a) } } @@ -3726,7 +3973,8 @@ pub fn _mm512_mask_fmsub_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm512_maskz_fmsub_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmsub_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmsub_ps(a, b, c), _mm512_setzero_ps()) } } @@ -3737,7 +3985,8 @@ pub fn _mm512_maskz_fmsub_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> _ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm512_mask3_fmsub_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmsub_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmsub_ps(a, b, c), c) } } @@ -3748,7 +3997,8 @@ pub fn _mm512_mask3_fmsub_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm256_mask_fmsub_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmsub_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmsub_ps(a, b, c), a) } } @@ -3759,7 +4009,8 @@ pub fn _mm256_mask_fmsub_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm256_maskz_fmsub_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmsub_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmsub_ps(a, b, c), _mm256_setzero_ps()) } } @@ -3770,7 +4021,8 @@ pub fn _mm256_maskz_fmsub_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm256_mask3_fmsub_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmsub_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmsub_ps(a, b, c), c) } } @@ -3781,7 +4033,8 @@ pub fn _mm256_mask3_fmsub_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm_mask_fmsub_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmsub_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmsub_ps(a, b, c), a) } } @@ -3792,7 +4045,8 @@ pub fn _mm_mask_fmsub_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm_maskz_fmsub_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmsub_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmsub_ps(a, b, c), _mm_setzero_ps()) } } @@ -3803,7 +4057,8 @@ pub fn _mm_maskz_fmsub_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m12 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132ps or vfmsub213ps or vfmsub231ps, clang generate vfmadd, gcc generate vfmsub -pub fn _mm_mask3_fmsub_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmsub_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmsub_ps(a, b, c), c) } } @@ -3814,7 +4069,8 @@ pub fn _mm_mask3_fmsub_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm512_fmsub_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmsub_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_fma(a, b, simd_neg(c)) } } @@ -3825,7 +4081,8 @@ pub fn _mm512_fmsub_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm512_mask_fmsub_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmsub_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmsub_pd(a, b, c), a) } } @@ -3836,7 +4093,8 @@ pub fn _mm512_mask_fmsub_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm512_maskz_fmsub_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmsub_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmsub_pd(a, b, c), _mm512_setzero_pd()) } } @@ -3847,7 +4105,8 @@ pub fn _mm512_maskz_fmsub_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm512_mask3_fmsub_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmsub_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmsub_pd(a, b, c), c) } } @@ -3858,7 +4117,8 @@ pub fn _mm512_mask3_fmsub_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm256_mask_fmsub_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmsub_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmsub_pd(a, b, c), a) } } @@ -3869,7 +4129,8 @@ pub fn _mm256_mask_fmsub_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm256_maskz_fmsub_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmsub_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmsub_pd(a, b, c), _mm256_setzero_pd()) } } @@ -3880,7 +4141,8 @@ pub fn _mm256_maskz_fmsub_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm256_mask3_fmsub_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmsub_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmsub_pd(a, b, c), c) } } @@ -3891,7 +4153,8 @@ pub fn _mm256_mask3_fmsub_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm_mask_fmsub_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmsub_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmsub_pd(a, b, c), a) } } @@ -3902,7 +4165,8 @@ pub fn _mm_mask_fmsub_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm_maskz_fmsub_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmsub_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmsub_pd(a, b, c), _mm_setzero_pd()) } } @@ -3913,7 +4177,8 @@ pub fn _mm_maskz_fmsub_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] //vfmsub132pd or vfmsub213pd or vfmsub231pd. clang fmadd, gcc fmsub -pub fn _mm_mask3_fmsub_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmsub_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmsub_pd(a, b, c), c) } } @@ -3924,7 +4189,8 @@ pub fn _mm_mask3_fmsub_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm512_fmaddsub_ps(a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmaddsub_ps(a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -3943,7 +4209,8 @@ pub fn _mm512_fmaddsub_ps(a: __m512, b: __m512, c: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm512_mask_fmaddsub_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmaddsub_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_ps(a, b, c), a) } } @@ -3954,7 +4221,8 @@ pub fn _mm512_mask_fmaddsub_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm512_maskz_fmaddsub_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmaddsub_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_ps(a, b, c), _mm512_setzero_ps()) } } @@ -3965,7 +4233,8 @@ pub fn _mm512_maskz_fmaddsub_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) - #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm512_mask3_fmaddsub_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmaddsub_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_ps(a, b, c), c) } } @@ -3976,7 +4245,8 @@ pub fn _mm512_mask3_fmaddsub_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm256_mask_fmaddsub_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmaddsub_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_ps(a, b, c), a) } } @@ -3987,7 +4257,8 @@ pub fn _mm256_mask_fmaddsub_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm256_maskz_fmaddsub_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmaddsub_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_ps(a, b, c), _mm256_setzero_ps()) } } @@ -3998,7 +4269,8 @@ pub fn _mm256_maskz_fmaddsub_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm256_mask3_fmaddsub_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmaddsub_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_ps(a, b, c), c) } } @@ -4009,7 +4281,8 @@ pub fn _mm256_mask3_fmaddsub_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm_mask_fmaddsub_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmaddsub_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmaddsub_ps(a, b, c), a) } } @@ -4020,7 +4293,8 @@ pub fn _mm_mask_fmaddsub_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm_maskz_fmaddsub_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmaddsub_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmaddsub_ps(a, b, c), _mm_setzero_ps()) } } @@ -4031,7 +4305,8 @@ pub fn _mm_maskz_fmaddsub_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132ps or vfmaddsub213ps or vfmaddsub231ps -pub fn _mm_mask3_fmaddsub_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmaddsub_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmaddsub_ps(a, b, c), c) } } @@ -4042,7 +4317,8 @@ pub fn _mm_mask3_fmaddsub_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm512_fmaddsub_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmaddsub_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -4057,7 +4333,8 @@ pub fn _mm512_fmaddsub_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm512_mask_fmaddsub_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmaddsub_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_pd(a, b, c), a) } } @@ -4068,7 +4345,8 @@ pub fn _mm512_mask_fmaddsub_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm512_maskz_fmaddsub_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmaddsub_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_pd(a, b, c), _mm512_setzero_pd()) } } @@ -4079,7 +4357,8 @@ pub fn _mm512_maskz_fmaddsub_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm512_mask3_fmaddsub_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmaddsub_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_pd(a, b, c), c) } } @@ -4090,7 +4369,8 @@ pub fn _mm512_mask3_fmaddsub_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm256_mask_fmaddsub_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmaddsub_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_pd(a, b, c), a) } } @@ -4101,7 +4381,8 @@ pub fn _mm256_mask_fmaddsub_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm256_maskz_fmaddsub_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmaddsub_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_pd(a, b, c), _mm256_setzero_pd()) } } @@ -4112,7 +4393,8 @@ pub fn _mm256_maskz_fmaddsub_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm256_mask3_fmaddsub_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmaddsub_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_pd(a, b, c), c) } } @@ -4123,7 +4405,8 @@ pub fn _mm256_mask3_fmaddsub_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm_mask_fmaddsub_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmaddsub_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmaddsub_pd(a, b, c), a) } } @@ -4134,7 +4417,8 @@ pub fn _mm_mask_fmaddsub_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm_maskz_fmaddsub_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmaddsub_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmaddsub_pd(a, b, c), _mm_setzero_pd()) } } @@ -4145,7 +4429,8 @@ pub fn _mm_maskz_fmaddsub_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmaddsub))] //vfmaddsub132pd or vfmaddsub213pd or vfmaddsub231pd -pub fn _mm_mask3_fmaddsub_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmaddsub_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmaddsub_pd(a, b, c), c) } } @@ -4156,7 +4441,8 @@ pub fn _mm_mask3_fmaddsub_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm512_fmsubadd_ps(a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmsubadd_ps(a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -4175,7 +4461,8 @@ pub fn _mm512_fmsubadd_ps(a: __m512, b: __m512, c: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm512_mask_fmsubadd_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmsubadd_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_ps(a, b, c), a) } } @@ -4186,7 +4473,8 @@ pub fn _mm512_mask_fmsubadd_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm512_maskz_fmsubadd_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmsubadd_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_ps(a, b, c), _mm512_setzero_ps()) } } @@ -4197,7 +4485,8 @@ pub fn _mm512_maskz_fmsubadd_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) - #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm512_mask3_fmsubadd_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmsubadd_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_ps(a, b, c), c) } } @@ -4208,7 +4497,8 @@ pub fn _mm512_mask3_fmsubadd_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm256_mask_fmsubadd_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmsubadd_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_ps(a, b, c), a) } } @@ -4219,7 +4509,8 @@ pub fn _mm256_mask_fmsubadd_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm256_maskz_fmsubadd_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmsubadd_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_ps(a, b, c), _mm256_setzero_ps()) } } @@ -4230,7 +4521,8 @@ pub fn _mm256_maskz_fmsubadd_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm256_mask3_fmsubadd_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmsubadd_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_ps(a, b, c), c) } } @@ -4241,7 +4533,8 @@ pub fn _mm256_mask3_fmsubadd_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm_mask_fmsubadd_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmsubadd_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmsubadd_ps(a, b, c), a) } } @@ -4252,7 +4545,8 @@ pub fn _mm_mask_fmsubadd_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm_maskz_fmsubadd_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmsubadd_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmsubadd_ps(a, b, c), _mm_setzero_ps()) } } @@ -4263,7 +4557,8 @@ pub fn _mm_maskz_fmsubadd_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132ps or vfmsubadd213ps or vfmsubadd231ps -pub fn _mm_mask3_fmsubadd_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmsubadd_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fmsubadd_ps(a, b, c), c) } } @@ -4274,7 +4569,8 @@ pub fn _mm_mask3_fmsubadd_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm512_fmsubadd_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmsubadd_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -4289,7 +4585,8 @@ pub fn _mm512_fmsubadd_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm512_mask_fmsubadd_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmsubadd_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_pd(a, b, c), a) } } @@ -4300,7 +4597,8 @@ pub fn _mm512_mask_fmsubadd_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm512_maskz_fmsubadd_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmsubadd_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_pd(a, b, c), _mm512_setzero_pd()) } } @@ -4311,7 +4609,8 @@ pub fn _mm512_maskz_fmsubadd_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm512_mask3_fmsubadd_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmsubadd_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_pd(a, b, c), c) } } @@ -4322,7 +4621,8 @@ pub fn _mm512_mask3_fmsubadd_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm256_mask_fmsubadd_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmsubadd_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_pd(a, b, c), a) } } @@ -4333,7 +4633,8 @@ pub fn _mm256_mask_fmsubadd_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm256_maskz_fmsubadd_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmsubadd_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_pd(a, b, c), _mm256_setzero_pd()) } } @@ -4344,7 +4645,8 @@ pub fn _mm256_maskz_fmsubadd_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm256_mask3_fmsubadd_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmsubadd_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_pd(a, b, c), c) } } @@ -4355,7 +4657,8 @@ pub fn _mm256_mask3_fmsubadd_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm_mask_fmsubadd_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmsubadd_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmsubadd_pd(a, b, c), a) } } @@ -4366,7 +4669,8 @@ pub fn _mm_mask_fmsubadd_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm_maskz_fmsubadd_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmsubadd_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmsubadd_pd(a, b, c), _mm_setzero_pd()) } } @@ -4377,7 +4681,8 @@ pub fn _mm_maskz_fmsubadd_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsubadd))] //vfmsubadd132pd or vfmsubadd213pd or vfmsubadd231pd -pub fn _mm_mask3_fmsubadd_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmsubadd_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fmsubadd_pd(a, b, c), c) } } @@ -4388,7 +4693,8 @@ pub fn _mm_mask3_fmsubadd_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm512_fnmadd_ps(a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fnmadd_ps(a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_fma(simd_neg(a), b, c) } } @@ -4399,7 +4705,8 @@ pub fn _mm512_fnmadd_ps(a: __m512, b: __m512, c: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm512_mask_fnmadd_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fnmadd_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fnmadd_ps(a, b, c), a) } } @@ -4410,7 +4717,8 @@ pub fn _mm512_mask_fnmadd_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> _ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm512_maskz_fnmadd_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fnmadd_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fnmadd_ps(a, b, c), _mm512_setzero_ps()) } } @@ -4421,7 +4729,8 @@ pub fn _mm512_maskz_fnmadd_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm512_mask3_fnmadd_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fnmadd_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fnmadd_ps(a, b, c), c) } } @@ -4432,7 +4741,8 @@ pub fn _mm512_mask3_fnmadd_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm256_mask_fnmadd_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fnmadd_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fnmadd_ps(a, b, c), a) } } @@ -4443,7 +4753,8 @@ pub fn _mm256_mask_fnmadd_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm256_maskz_fnmadd_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fnmadd_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fnmadd_ps(a, b, c), _mm256_setzero_ps()) } } @@ -4454,7 +4765,8 @@ pub fn _mm256_maskz_fnmadd_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm256_mask3_fnmadd_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fnmadd_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fnmadd_ps(a, b, c), c) } } @@ -4465,7 +4777,8 @@ pub fn _mm256_mask3_fnmadd_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm_mask_fnmadd_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmadd_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fnmadd_ps(a, b, c), a) } } @@ -4476,7 +4789,8 @@ pub fn _mm_mask_fnmadd_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m12 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm_maskz_fnmadd_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmadd_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fnmadd_ps(a, b, c), _mm_setzero_ps()) } } @@ -4487,7 +4801,8 @@ pub fn _mm_maskz_fnmadd_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m1 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132ps or vfnmadd213ps or vfnmadd231ps -pub fn _mm_mask3_fnmadd_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmadd_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fnmadd_ps(a, b, c), c) } } @@ -4498,7 +4813,8 @@ pub fn _mm_mask3_fnmadd_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m1 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm512_fnmadd_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fnmadd_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_fma(simd_neg(a), b, c) } } @@ -4509,7 +4825,8 @@ pub fn _mm512_fnmadd_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm512_mask_fnmadd_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fnmadd_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fnmadd_pd(a, b, c), a) } } @@ -4520,7 +4837,8 @@ pub fn _mm512_mask_fnmadd_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm512_maskz_fnmadd_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fnmadd_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fnmadd_pd(a, b, c), _mm512_setzero_pd()) } } @@ -4531,7 +4849,8 @@ pub fn _mm512_maskz_fnmadd_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) - #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm512_mask3_fnmadd_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fnmadd_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fnmadd_pd(a, b, c), c) } } @@ -4542,7 +4861,8 @@ pub fn _mm512_mask3_fnmadd_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm256_mask_fnmadd_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fnmadd_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fnmadd_pd(a, b, c), a) } } @@ -4553,7 +4873,8 @@ pub fn _mm256_mask_fnmadd_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm256_maskz_fnmadd_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fnmadd_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fnmadd_pd(a, b, c), _mm256_setzero_pd()) } } @@ -4564,7 +4885,8 @@ pub fn _mm256_maskz_fnmadd_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm256_mask3_fnmadd_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fnmadd_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fnmadd_pd(a, b, c), c) } } @@ -4575,7 +4897,8 @@ pub fn _mm256_mask3_fnmadd_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm_mask_fnmadd_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmadd_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fnmadd_pd(a, b, c), a) } } @@ -4586,7 +4909,8 @@ pub fn _mm_mask_fnmadd_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm_maskz_fnmadd_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmadd_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fnmadd_pd(a, b, c), _mm_setzero_pd()) } } @@ -4597,7 +4921,8 @@ pub fn _mm_maskz_fnmadd_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] //vfnmadd132pd or vfnmadd213pd or vfnmadd231pd -pub fn _mm_mask3_fnmadd_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmadd_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fnmadd_pd(a, b, c), c) } } @@ -4608,7 +4933,8 @@ pub fn _mm_mask3_fnmadd_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> _ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm512_fnmsub_ps(a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fnmsub_ps(a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } } @@ -4619,7 +4945,8 @@ pub fn _mm512_fnmsub_ps(a: __m512, b: __m512, c: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm512_mask_fnmsub_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fnmsub_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fnmsub_ps(a, b, c), a) } } @@ -4630,7 +4957,8 @@ pub fn _mm512_mask_fnmsub_ps(a: __m512, k: __mmask16, b: __m512, c: __m512) -> _ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm512_maskz_fnmsub_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fnmsub_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fnmsub_ps(a, b, c), _mm512_setzero_ps()) } } @@ -4641,7 +4969,8 @@ pub fn _mm512_maskz_fnmsub_ps(k: __mmask16, a: __m512, b: __m512, c: __m512) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm512_mask3_fnmsub_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fnmsub_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> __m512 { unsafe { simd_select_bitmask(k, _mm512_fnmsub_ps(a, b, c), c) } } @@ -4652,7 +4981,8 @@ pub fn _mm512_mask3_fnmsub_ps(a: __m512, b: __m512, c: __m512, k: __mmask16) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm256_mask_fnmsub_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fnmsub_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fnmsub_ps(a, b, c), a) } } @@ -4663,7 +4993,8 @@ pub fn _mm256_mask_fnmsub_ps(a: __m256, k: __mmask8, b: __m256, c: __m256) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm256_maskz_fnmsub_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fnmsub_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fnmsub_ps(a, b, c), _mm256_setzero_ps()) } } @@ -4674,7 +5005,8 @@ pub fn _mm256_maskz_fnmsub_ps(k: __mmask8, a: __m256, b: __m256, c: __m256) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm256_mask3_fnmsub_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fnmsub_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> __m256 { unsafe { simd_select_bitmask(k, _mm256_fnmsub_ps(a, b, c), c) } } @@ -4685,7 +5017,8 @@ pub fn _mm256_mask3_fnmsub_ps(a: __m256, b: __m256, c: __m256, k: __mmask8) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm_mask_fnmsub_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmsub_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fnmsub_ps(a, b, c), a) } } @@ -4696,7 +5029,8 @@ pub fn _mm_mask_fnmsub_ps(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m12 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm_maskz_fnmsub_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmsub_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fnmsub_ps(a, b, c), _mm_setzero_ps()) } } @@ -4707,7 +5041,8 @@ pub fn _mm_maskz_fnmsub_ps(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m1 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132ps or vfnmsub213ps or vfnmsub231ps -pub fn _mm_mask3_fnmsub_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmsub_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { simd_select_bitmask(k, _mm_fnmsub_ps(a, b, c), c) } } @@ -4718,7 +5053,8 @@ pub fn _mm_mask3_fnmsub_ps(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m1 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm512_fnmsub_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fnmsub_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } } @@ -4729,7 +5065,8 @@ pub fn _mm512_fnmsub_pd(a: __m512d, b: __m512d, c: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm512_mask_fnmsub_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fnmsub_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fnmsub_pd(a, b, c), a) } } @@ -4740,7 +5077,8 @@ pub fn _mm512_mask_fnmsub_pd(a: __m512d, k: __mmask8, b: __m512d, c: __m512d) -> #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm512_maskz_fnmsub_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fnmsub_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fnmsub_pd(a, b, c), _mm512_setzero_pd()) } } @@ -4751,7 +5089,8 @@ pub fn _mm512_maskz_fnmsub_pd(k: __mmask8, a: __m512d, b: __m512d, c: __m512d) - #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm512_mask3_fnmsub_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fnmsub_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) -> __m512d { unsafe { simd_select_bitmask(k, _mm512_fnmsub_pd(a, b, c), c) } } @@ -4762,7 +5101,8 @@ pub fn _mm512_mask3_fnmsub_pd(a: __m512d, b: __m512d, c: __m512d, k: __mmask8) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm256_mask_fnmsub_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fnmsub_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fnmsub_pd(a, b, c), a) } } @@ -4773,7 +5113,8 @@ pub fn _mm256_mask_fnmsub_pd(a: __m256d, k: __mmask8, b: __m256d, c: __m256d) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm256_maskz_fnmsub_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fnmsub_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fnmsub_pd(a, b, c), _mm256_setzero_pd()) } } @@ -4784,7 +5125,8 @@ pub fn _mm256_maskz_fnmsub_pd(k: __mmask8, a: __m256d, b: __m256d, c: __m256d) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm256_mask3_fnmsub_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fnmsub_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) -> __m256d { unsafe { simd_select_bitmask(k, _mm256_fnmsub_pd(a, b, c), c) } } @@ -4795,7 +5137,8 @@ pub fn _mm256_mask3_fnmsub_pd(a: __m256d, b: __m256d, c: __m256d, k: __mmask8) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm_mask_fnmsub_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmsub_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fnmsub_pd(a, b, c), a) } } @@ -4806,7 +5149,8 @@ pub fn _mm_mask_fnmsub_pd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm_maskz_fnmsub_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmsub_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fnmsub_pd(a, b, c), _mm_setzero_pd()) } } @@ -4817,7 +5161,8 @@ pub fn _mm_maskz_fnmsub_pd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] //vfnmsub132pd or vfnmsub213pd or vfnmsub231pd -pub fn _mm_mask3_fnmsub_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmsub_pd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { simd_select_bitmask(k, _mm_fnmsub_pd(a, b, c), c) } } @@ -11446,7 +11791,8 @@ pub fn _mm512_mask_cvtpd_pslo(src: __m512, k: __mmask8, v2: __m512d) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbd))] -pub fn _mm512_cvtepi8_epi32(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi8_epi32(a: __m128i) -> __m512i { unsafe { let a = a.as_i8x16(); transmute::(simd_cast(a)) @@ -11460,7 +11806,8 @@ pub fn _mm512_cvtepi8_epi32(a: __m128i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbd))] -pub fn _mm512_mask_cvtepi8_epi32(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi8_epi32(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepi8_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, convert, src.as_i32x16())) @@ -11474,7 +11821,8 @@ pub fn _mm512_mask_cvtepi8_epi32(src: __m512i, k: __mmask16, a: __m128i) -> __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbd))] -pub fn _mm512_maskz_cvtepi8_epi32(k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi8_epi32(k: __mmask16, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepi8_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, convert, i32x16::ZERO)) @@ -11488,7 +11836,8 @@ pub fn _mm512_maskz_cvtepi8_epi32(k: __mmask16, a: __m128i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbd))] -pub fn _mm256_mask_cvtepi8_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi8_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi8_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, src.as_i32x8())) @@ -11502,7 +11851,8 @@ pub fn _mm256_mask_cvtepi8_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbd))] -pub fn _mm256_maskz_cvtepi8_epi32(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi8_epi32(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi8_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, i32x8::ZERO)) @@ -11516,7 +11866,8 @@ pub fn _mm256_maskz_cvtepi8_epi32(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbd))] -pub fn _mm_mask_cvtepi8_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepi8_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi8_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, src.as_i32x4())) @@ -11530,7 +11881,8 @@ pub fn _mm_mask_cvtepi8_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbd))] -pub fn _mm_maskz_cvtepi8_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepi8_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi8_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, i32x4::ZERO)) @@ -11544,7 +11896,8 @@ pub fn _mm_maskz_cvtepi8_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbq))] -pub fn _mm512_cvtepi8_epi64(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi8_epi64(a: __m128i) -> __m512i { unsafe { let a = a.as_i8x16(); let v64: i8x8 = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -11559,7 +11912,8 @@ pub fn _mm512_cvtepi8_epi64(a: __m128i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbq))] -pub fn _mm512_mask_cvtepi8_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi8_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepi8_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, src.as_i64x8())) @@ -11573,7 +11927,8 @@ pub fn _mm512_mask_cvtepi8_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m51 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbq))] -pub fn _mm512_maskz_cvtepi8_epi64(k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi8_epi64(k: __mmask8, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepi8_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, i64x8::ZERO)) @@ -11587,7 +11942,8 @@ pub fn _mm512_maskz_cvtepi8_epi64(k: __mmask8, a: __m128i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbq))] -pub fn _mm256_mask_cvtepi8_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi8_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi8_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, src.as_i64x4())) @@ -11601,7 +11957,8 @@ pub fn _mm256_mask_cvtepi8_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbq))] -pub fn _mm256_maskz_cvtepi8_epi64(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi8_epi64(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi8_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, i64x4::ZERO)) @@ -11615,7 +11972,8 @@ pub fn _mm256_maskz_cvtepi8_epi64(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbq))] -pub fn _mm_mask_cvtepi8_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepi8_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi8_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, src.as_i64x2())) @@ -11629,7 +11987,8 @@ pub fn _mm_mask_cvtepi8_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbq))] -pub fn _mm_maskz_cvtepi8_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepi8_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi8_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, i64x2::ZERO)) @@ -11643,7 +12002,8 @@ pub fn _mm_maskz_cvtepi8_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbd))] -pub fn _mm512_cvtepu8_epi32(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepu8_epi32(a: __m128i) -> __m512i { unsafe { let a = a.as_u8x16(); transmute::(simd_cast(a)) @@ -11657,7 +12017,8 @@ pub fn _mm512_cvtepu8_epi32(a: __m128i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbd))] -pub fn _mm512_mask_cvtepu8_epi32(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepu8_epi32(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepu8_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, convert, src.as_i32x16())) @@ -11671,7 +12032,8 @@ pub fn _mm512_mask_cvtepu8_epi32(src: __m512i, k: __mmask16, a: __m128i) -> __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbd))] -pub fn _mm512_maskz_cvtepu8_epi32(k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepu8_epi32(k: __mmask16, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepu8_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, convert, i32x16::ZERO)) @@ -11685,7 +12047,8 @@ pub fn _mm512_maskz_cvtepu8_epi32(k: __mmask16, a: __m128i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbd))] -pub fn _mm256_mask_cvtepu8_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepu8_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu8_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, src.as_i32x8())) @@ -11699,7 +12062,8 @@ pub fn _mm256_mask_cvtepu8_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbd))] -pub fn _mm256_maskz_cvtepu8_epi32(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepu8_epi32(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu8_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, i32x8::ZERO)) @@ -11713,7 +12077,8 @@ pub fn _mm256_maskz_cvtepu8_epi32(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbd))] -pub fn _mm_mask_cvtepu8_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepu8_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu8_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, src.as_i32x4())) @@ -11727,7 +12092,8 @@ pub fn _mm_mask_cvtepu8_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbd))] -pub fn _mm_maskz_cvtepu8_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepu8_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu8_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, i32x4::ZERO)) @@ -11741,7 +12107,8 @@ pub fn _mm_maskz_cvtepu8_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbq))] -pub fn _mm512_cvtepu8_epi64(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepu8_epi64(a: __m128i) -> __m512i { unsafe { let a = a.as_u8x16(); let v64: u8x8 = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -11756,7 +12123,8 @@ pub fn _mm512_cvtepu8_epi64(a: __m128i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbq))] -pub fn _mm512_mask_cvtepu8_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepu8_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepu8_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, src.as_i64x8())) @@ -11770,7 +12138,8 @@ pub fn _mm512_mask_cvtepu8_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m51 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbq))] -pub fn _mm512_maskz_cvtepu8_epi64(k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepu8_epi64(k: __mmask8, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepu8_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, i64x8::ZERO)) @@ -11784,7 +12153,8 @@ pub fn _mm512_maskz_cvtepu8_epi64(k: __mmask8, a: __m128i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbq))] -pub fn _mm256_mask_cvtepu8_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepu8_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu8_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, src.as_i64x4())) @@ -11798,7 +12168,8 @@ pub fn _mm256_mask_cvtepu8_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbq))] -pub fn _mm256_maskz_cvtepu8_epi64(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepu8_epi64(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu8_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, i64x4::ZERO)) @@ -11812,7 +12183,8 @@ pub fn _mm256_maskz_cvtepu8_epi64(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbq))] -pub fn _mm_mask_cvtepu8_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepu8_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu8_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, src.as_i64x2())) @@ -11826,7 +12198,8 @@ pub fn _mm_mask_cvtepu8_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbq))] -pub fn _mm_maskz_cvtepu8_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepu8_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu8_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, i64x2::ZERO)) @@ -11840,7 +12213,8 @@ pub fn _mm_maskz_cvtepu8_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwd))] -pub fn _mm512_cvtepi16_epi32(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi16_epi32(a: __m256i) -> __m512i { unsafe { let a = a.as_i16x16(); transmute::(simd_cast(a)) @@ -11854,7 +12228,8 @@ pub fn _mm512_cvtepi16_epi32(a: __m256i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwd))] -pub fn _mm512_mask_cvtepi16_epi32(src: __m512i, k: __mmask16, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi16_epi32(src: __m512i, k: __mmask16, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepi16_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, convert, src.as_i32x16())) @@ -11868,7 +12243,8 @@ pub fn _mm512_mask_cvtepi16_epi32(src: __m512i, k: __mmask16, a: __m256i) -> __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwd))] -pub fn _mm512_maskz_cvtepi16_epi32(k: __mmask16, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi16_epi32(k: __mmask16, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepi16_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, convert, i32x16::ZERO)) @@ -11882,7 +12258,8 @@ pub fn _mm512_maskz_cvtepi16_epi32(k: __mmask16, a: __m256i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwd))] -pub fn _mm256_mask_cvtepi16_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi16_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi16_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, src.as_i32x8())) @@ -11896,7 +12273,8 @@ pub fn _mm256_mask_cvtepi16_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwd))] -pub fn _mm256_maskz_cvtepi16_epi32(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi16_epi32(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi16_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, i32x8::ZERO)) @@ -11910,7 +12288,8 @@ pub fn _mm256_maskz_cvtepi16_epi32(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwd))] -pub fn _mm_mask_cvtepi16_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepi16_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi16_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, src.as_i32x4())) @@ -11924,7 +12303,8 @@ pub fn _mm_mask_cvtepi16_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwd))] -pub fn _mm_maskz_cvtepi16_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepi16_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi16_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, i32x4::ZERO)) @@ -11938,7 +12318,8 @@ pub fn _mm_maskz_cvtepi16_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwq))] -pub fn _mm512_cvtepi16_epi64(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi16_epi64(a: __m128i) -> __m512i { unsafe { let a = a.as_i16x8(); transmute::(simd_cast(a)) @@ -11952,7 +12333,8 @@ pub fn _mm512_cvtepi16_epi64(a: __m128i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwq))] -pub fn _mm512_mask_cvtepi16_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi16_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepi16_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, src.as_i64x8())) @@ -11966,7 +12348,8 @@ pub fn _mm512_mask_cvtepi16_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwq))] -pub fn _mm512_maskz_cvtepi16_epi64(k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi16_epi64(k: __mmask8, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepi16_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, i64x8::ZERO)) @@ -11980,7 +12363,8 @@ pub fn _mm512_maskz_cvtepi16_epi64(k: __mmask8, a: __m128i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwq))] -pub fn _mm256_mask_cvtepi16_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi16_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi16_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, src.as_i64x4())) @@ -11994,7 +12378,8 @@ pub fn _mm256_mask_cvtepi16_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwq))] -pub fn _mm256_maskz_cvtepi16_epi64(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi16_epi64(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi16_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, i64x4::ZERO)) @@ -12008,7 +12393,8 @@ pub fn _mm256_maskz_cvtepi16_epi64(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwq))] -pub fn _mm_mask_cvtepi16_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepi16_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi16_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, src.as_i64x2())) @@ -12022,7 +12408,8 @@ pub fn _mm_mask_cvtepi16_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxwq))] -pub fn _mm_maskz_cvtepi16_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepi16_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi16_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, i64x2::ZERO)) @@ -12036,7 +12423,8 @@ pub fn _mm_maskz_cvtepi16_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwd))] -pub fn _mm512_cvtepu16_epi32(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepu16_epi32(a: __m256i) -> __m512i { unsafe { let a = a.as_u16x16(); transmute::(simd_cast(a)) @@ -12050,7 +12438,8 @@ pub fn _mm512_cvtepu16_epi32(a: __m256i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwd))] -pub fn _mm512_mask_cvtepu16_epi32(src: __m512i, k: __mmask16, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepu16_epi32(src: __m512i, k: __mmask16, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepu16_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, convert, src.as_i32x16())) @@ -12064,7 +12453,8 @@ pub fn _mm512_mask_cvtepu16_epi32(src: __m512i, k: __mmask16, a: __m256i) -> __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwd))] -pub fn _mm512_maskz_cvtepu16_epi32(k: __mmask16, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepu16_epi32(k: __mmask16, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepu16_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, convert, i32x16::ZERO)) @@ -12078,7 +12468,8 @@ pub fn _mm512_maskz_cvtepu16_epi32(k: __mmask16, a: __m256i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwd))] -pub fn _mm256_mask_cvtepu16_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepu16_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu16_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, src.as_i32x8())) @@ -12092,7 +12483,8 @@ pub fn _mm256_mask_cvtepu16_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwd))] -pub fn _mm256_maskz_cvtepu16_epi32(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepu16_epi32(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu16_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, i32x8::ZERO)) @@ -12106,7 +12498,8 @@ pub fn _mm256_maskz_cvtepu16_epi32(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwd))] -pub fn _mm_mask_cvtepu16_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepu16_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu16_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, src.as_i32x4())) @@ -12120,7 +12513,8 @@ pub fn _mm_mask_cvtepu16_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwd))] -pub fn _mm_maskz_cvtepu16_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepu16_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu16_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, i32x4::ZERO)) @@ -12134,7 +12528,8 @@ pub fn _mm_maskz_cvtepu16_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwq))] -pub fn _mm512_cvtepu16_epi64(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepu16_epi64(a: __m128i) -> __m512i { unsafe { let a = a.as_u16x8(); transmute::(simd_cast(a)) @@ -12148,7 +12543,8 @@ pub fn _mm512_cvtepu16_epi64(a: __m128i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwq))] -pub fn _mm512_mask_cvtepu16_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepu16_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepu16_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, src.as_i64x8())) @@ -12162,7 +12558,8 @@ pub fn _mm512_mask_cvtepu16_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwq))] -pub fn _mm512_maskz_cvtepu16_epi64(k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepu16_epi64(k: __mmask8, a: __m128i) -> __m512i { unsafe { let convert = _mm512_cvtepu16_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, i64x8::ZERO)) @@ -12176,7 +12573,8 @@ pub fn _mm512_maskz_cvtepu16_epi64(k: __mmask8, a: __m128i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwq))] -pub fn _mm256_mask_cvtepu16_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepu16_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu16_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, src.as_i64x4())) @@ -12190,7 +12588,8 @@ pub fn _mm256_mask_cvtepu16_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwq))] -pub fn _mm256_maskz_cvtepu16_epi64(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepu16_epi64(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu16_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, i64x4::ZERO)) @@ -12204,7 +12603,8 @@ pub fn _mm256_maskz_cvtepu16_epi64(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwq))] -pub fn _mm_mask_cvtepu16_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepu16_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu16_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, src.as_i64x2())) @@ -12218,7 +12618,8 @@ pub fn _mm_mask_cvtepu16_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxwq))] -pub fn _mm_maskz_cvtepu16_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepu16_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu16_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, i64x2::ZERO)) @@ -12232,7 +12633,8 @@ pub fn _mm_maskz_cvtepu16_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxdq))] -pub fn _mm512_cvtepi32_epi64(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi32_epi64(a: __m256i) -> __m512i { unsafe { let a = a.as_i32x8(); transmute::(simd_cast(a)) @@ -12246,7 +12648,8 @@ pub fn _mm512_cvtepi32_epi64(a: __m256i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxdq))] -pub fn _mm512_mask_cvtepi32_epi64(src: __m512i, k: __mmask8, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi32_epi64(src: __m512i, k: __mmask8, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepi32_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, src.as_i64x8())) @@ -12260,7 +12663,8 @@ pub fn _mm512_mask_cvtepi32_epi64(src: __m512i, k: __mmask8, a: __m256i) -> __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxdq))] -pub fn _mm512_maskz_cvtepi32_epi64(k: __mmask8, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi32_epi64(k: __mmask8, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepi32_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, i64x8::ZERO)) @@ -12274,7 +12678,8 @@ pub fn _mm512_maskz_cvtepi32_epi64(k: __mmask8, a: __m256i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxdq))] -pub fn _mm256_mask_cvtepi32_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi32_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi32_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, src.as_i64x4())) @@ -12288,7 +12693,8 @@ pub fn _mm256_mask_cvtepi32_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxdq))] -pub fn _mm256_maskz_cvtepi32_epi64(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi32_epi64(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi32_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, i64x4::ZERO)) @@ -12302,7 +12708,8 @@ pub fn _mm256_maskz_cvtepi32_epi64(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxdq))] -pub fn _mm_mask_cvtepi32_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepi32_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi32_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, src.as_i64x2())) @@ -12316,7 +12723,8 @@ pub fn _mm_mask_cvtepi32_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxdq))] -pub fn _mm_maskz_cvtepi32_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepi32_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi32_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, i64x2::ZERO)) @@ -12330,7 +12738,8 @@ pub fn _mm_maskz_cvtepi32_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxdq))] -pub fn _mm512_cvtepu32_epi64(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepu32_epi64(a: __m256i) -> __m512i { unsafe { let a = a.as_u32x8(); transmute::(simd_cast(a)) @@ -12344,7 +12753,8 @@ pub fn _mm512_cvtepu32_epi64(a: __m256i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxdq))] -pub fn _mm512_mask_cvtepu32_epi64(src: __m512i, k: __mmask8, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepu32_epi64(src: __m512i, k: __mmask8, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepu32_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, src.as_i64x8())) @@ -12358,7 +12768,8 @@ pub fn _mm512_mask_cvtepu32_epi64(src: __m512i, k: __mmask8, a: __m256i) -> __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxdq))] -pub fn _mm512_maskz_cvtepu32_epi64(k: __mmask8, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepu32_epi64(k: __mmask8, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepu32_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, convert, i64x8::ZERO)) @@ -12372,7 +12783,8 @@ pub fn _mm512_maskz_cvtepu32_epi64(k: __mmask8, a: __m256i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxdq))] -pub fn _mm256_mask_cvtepu32_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepu32_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu32_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, src.as_i64x4())) @@ -12386,7 +12798,8 @@ pub fn _mm256_mask_cvtepu32_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxdq))] -pub fn _mm256_maskz_cvtepu32_epi64(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepu32_epi64(k: __mmask8, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu32_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, convert, i64x4::ZERO)) @@ -12400,7 +12813,8 @@ pub fn _mm256_maskz_cvtepu32_epi64(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxdq))] -pub fn _mm_mask_cvtepu32_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepu32_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu32_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, src.as_i64x2())) @@ -12414,7 +12828,8 @@ pub fn _mm_mask_cvtepu32_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxdq))] -pub fn _mm_maskz_cvtepu32_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepu32_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu32_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, convert, i64x2::ZERO)) @@ -12428,7 +12843,8 @@ pub fn _mm_maskz_cvtepu32_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2ps))] -pub fn _mm512_cvtepi32_ps(a: __m512i) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi32_ps(a: __m512i) -> __m512 { unsafe { let a = a.as_i32x16(); transmute::(simd_cast(a)) @@ -12442,7 +12858,8 @@ pub fn _mm512_cvtepi32_ps(a: __m512i) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2ps))] -pub fn _mm512_mask_cvtepi32_ps(src: __m512, k: __mmask16, a: __m512i) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi32_ps(src: __m512, k: __mmask16, a: __m512i) -> __m512 { unsafe { let convert = _mm512_cvtepi32_ps(a).as_f32x16(); transmute(simd_select_bitmask(k, convert, src.as_f32x16())) @@ -12456,7 +12873,8 @@ pub fn _mm512_mask_cvtepi32_ps(src: __m512, k: __mmask16, a: __m512i) -> __m512 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2ps))] -pub fn _mm512_maskz_cvtepi32_ps(k: __mmask16, a: __m512i) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi32_ps(k: __mmask16, a: __m512i) -> __m512 { unsafe { let convert = _mm512_cvtepi32_ps(a).as_f32x16(); transmute(simd_select_bitmask(k, convert, f32x16::ZERO)) @@ -12470,7 +12888,8 @@ pub fn _mm512_maskz_cvtepi32_ps(k: __mmask16, a: __m512i) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2ps))] -pub fn _mm256_mask_cvtepi32_ps(src: __m256, k: __mmask8, a: __m256i) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi32_ps(src: __m256, k: __mmask8, a: __m256i) -> __m256 { unsafe { let convert = _mm256_cvtepi32_ps(a).as_f32x8(); transmute(simd_select_bitmask(k, convert, src.as_f32x8())) @@ -12484,7 +12903,8 @@ pub fn _mm256_mask_cvtepi32_ps(src: __m256, k: __mmask8, a: __m256i) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2ps))] -pub fn _mm256_maskz_cvtepi32_ps(k: __mmask8, a: __m256i) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi32_ps(k: __mmask8, a: __m256i) -> __m256 { unsafe { let convert = _mm256_cvtepi32_ps(a).as_f32x8(); transmute(simd_select_bitmask(k, convert, f32x8::ZERO)) @@ -12498,7 +12918,8 @@ pub fn _mm256_maskz_cvtepi32_ps(k: __mmask8, a: __m256i) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2ps))] -pub fn _mm_mask_cvtepi32_ps(src: __m128, k: __mmask8, a: __m128i) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepi32_ps(src: __m128, k: __mmask8, a: __m128i) -> __m128 { unsafe { let convert = _mm_cvtepi32_ps(a).as_f32x4(); transmute(simd_select_bitmask(k, convert, src.as_f32x4())) @@ -12512,7 +12933,8 @@ pub fn _mm_mask_cvtepi32_ps(src: __m128, k: __mmask8, a: __m128i) -> __m128 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2ps))] -pub fn _mm_maskz_cvtepi32_ps(k: __mmask8, a: __m128i) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepi32_ps(k: __mmask8, a: __m128i) -> __m128 { unsafe { let convert = _mm_cvtepi32_ps(a).as_f32x4(); transmute(simd_select_bitmask(k, convert, f32x4::ZERO)) @@ -12526,7 +12948,8 @@ pub fn _mm_maskz_cvtepi32_ps(k: __mmask8, a: __m128i) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] -pub fn _mm512_cvtepi32_pd(a: __m256i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi32_pd(a: __m256i) -> __m512d { unsafe { let a = a.as_i32x8(); transmute::(simd_cast(a)) @@ -12540,7 +12963,8 @@ pub fn _mm512_cvtepi32_pd(a: __m256i) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] -pub fn _mm512_mask_cvtepi32_pd(src: __m512d, k: __mmask8, a: __m256i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi32_pd(src: __m512d, k: __mmask8, a: __m256i) -> __m512d { unsafe { let convert = _mm512_cvtepi32_pd(a).as_f64x8(); transmute(simd_select_bitmask(k, convert, src.as_f64x8())) @@ -12554,7 +12978,8 @@ pub fn _mm512_mask_cvtepi32_pd(src: __m512d, k: __mmask8, a: __m256i) -> __m512d #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] -pub fn _mm512_maskz_cvtepi32_pd(k: __mmask8, a: __m256i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi32_pd(k: __mmask8, a: __m256i) -> __m512d { unsafe { let convert = _mm512_cvtepi32_pd(a).as_f64x8(); transmute(simd_select_bitmask(k, convert, f64x8::ZERO)) @@ -12568,7 +12993,8 @@ pub fn _mm512_maskz_cvtepi32_pd(k: __mmask8, a: __m256i) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] -pub fn _mm256_mask_cvtepi32_pd(src: __m256d, k: __mmask8, a: __m128i) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi32_pd(src: __m256d, k: __mmask8, a: __m128i) -> __m256d { unsafe { let convert = _mm256_cvtepi32_pd(a).as_f64x4(); transmute(simd_select_bitmask(k, convert, src.as_f64x4())) @@ -12582,7 +13008,8 @@ pub fn _mm256_mask_cvtepi32_pd(src: __m256d, k: __mmask8, a: __m128i) -> __m256d #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] -pub fn _mm256_maskz_cvtepi32_pd(k: __mmask8, a: __m128i) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi32_pd(k: __mmask8, a: __m128i) -> __m256d { unsafe { let convert = _mm256_cvtepi32_pd(a).as_f64x4(); transmute(simd_select_bitmask(k, convert, f64x4::ZERO)) @@ -12596,7 +13023,8 @@ pub fn _mm256_maskz_cvtepi32_pd(k: __mmask8, a: __m128i) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] -pub fn _mm_mask_cvtepi32_pd(src: __m128d, k: __mmask8, a: __m128i) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepi32_pd(src: __m128d, k: __mmask8, a: __m128i) -> __m128d { unsafe { let convert = _mm_cvtepi32_pd(a).as_f64x2(); transmute(simd_select_bitmask(k, convert, src.as_f64x2())) @@ -12610,7 +13038,8 @@ pub fn _mm_mask_cvtepi32_pd(src: __m128d, k: __mmask8, a: __m128i) -> __m128d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] -pub fn _mm_maskz_cvtepi32_pd(k: __mmask8, a: __m128i) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepi32_pd(k: __mmask8, a: __m128i) -> __m128d { unsafe { let convert = _mm_cvtepi32_pd(a).as_f64x2(); transmute(simd_select_bitmask(k, convert, f64x2::ZERO)) @@ -12624,7 +13053,8 @@ pub fn _mm_maskz_cvtepi32_pd(k: __mmask8, a: __m128i) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2ps))] -pub fn _mm512_cvtepu32_ps(a: __m512i) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepu32_ps(a: __m512i) -> __m512 { unsafe { let a = a.as_u32x16(); transmute::(simd_cast(a)) @@ -12638,7 +13068,8 @@ pub fn _mm512_cvtepu32_ps(a: __m512i) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2ps))] -pub fn _mm512_mask_cvtepu32_ps(src: __m512, k: __mmask16, a: __m512i) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepu32_ps(src: __m512, k: __mmask16, a: __m512i) -> __m512 { unsafe { let convert = _mm512_cvtepu32_ps(a).as_f32x16(); transmute(simd_select_bitmask(k, convert, src.as_f32x16())) @@ -12652,7 +13083,8 @@ pub fn _mm512_mask_cvtepu32_ps(src: __m512, k: __mmask16, a: __m512i) -> __m512 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2ps))] -pub fn _mm512_maskz_cvtepu32_ps(k: __mmask16, a: __m512i) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepu32_ps(k: __mmask16, a: __m512i) -> __m512 { unsafe { let convert = _mm512_cvtepu32_ps(a).as_f32x16(); transmute(simd_select_bitmask(k, convert, f32x16::ZERO)) @@ -12666,7 +13098,8 @@ pub fn _mm512_maskz_cvtepu32_ps(k: __mmask16, a: __m512i) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm512_cvtepu32_pd(a: __m256i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepu32_pd(a: __m256i) -> __m512d { unsafe { let a = a.as_u32x8(); transmute::(simd_cast(a)) @@ -12680,7 +13113,8 @@ pub fn _mm512_cvtepu32_pd(a: __m256i) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm512_mask_cvtepu32_pd(src: __m512d, k: __mmask8, a: __m256i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepu32_pd(src: __m512d, k: __mmask8, a: __m256i) -> __m512d { unsafe { let convert = _mm512_cvtepu32_pd(a).as_f64x8(); transmute(simd_select_bitmask(k, convert, src.as_f64x8())) @@ -12694,7 +13128,8 @@ pub fn _mm512_mask_cvtepu32_pd(src: __m512d, k: __mmask8, a: __m256i) -> __m512d #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm512_maskz_cvtepu32_pd(k: __mmask8, a: __m256i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepu32_pd(k: __mmask8, a: __m256i) -> __m512d { unsafe { let convert = _mm512_cvtepu32_pd(a).as_f64x8(); transmute(simd_select_bitmask(k, convert, f64x8::ZERO)) @@ -12708,7 +13143,8 @@ pub fn _mm512_maskz_cvtepu32_pd(k: __mmask8, a: __m256i) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm256_cvtepu32_pd(a: __m128i) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepu32_pd(a: __m128i) -> __m256d { unsafe { let a = a.as_u32x4(); transmute::(simd_cast(a)) @@ -12722,7 +13158,8 @@ pub fn _mm256_cvtepu32_pd(a: __m128i) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm256_mask_cvtepu32_pd(src: __m256d, k: __mmask8, a: __m128i) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepu32_pd(src: __m256d, k: __mmask8, a: __m128i) -> __m256d { unsafe { let convert = _mm256_cvtepu32_pd(a).as_f64x4(); transmute(simd_select_bitmask(k, convert, src.as_f64x4())) @@ -12736,7 +13173,8 @@ pub fn _mm256_mask_cvtepu32_pd(src: __m256d, k: __mmask8, a: __m128i) -> __m256d #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm256_maskz_cvtepu32_pd(k: __mmask8, a: __m128i) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepu32_pd(k: __mmask8, a: __m128i) -> __m256d { unsafe { let convert = _mm256_cvtepu32_pd(a).as_f64x4(); transmute(simd_select_bitmask(k, convert, f64x4::ZERO)) @@ -12750,7 +13188,8 @@ pub fn _mm256_maskz_cvtepu32_pd(k: __mmask8, a: __m128i) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm_cvtepu32_pd(a: __m128i) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepu32_pd(a: __m128i) -> __m128d { unsafe { let a = a.as_u32x4(); let u64: u32x2 = simd_shuffle!(a, a, [0, 1]); @@ -12765,7 +13204,8 @@ pub fn _mm_cvtepu32_pd(a: __m128i) -> __m128d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm_mask_cvtepu32_pd(src: __m128d, k: __mmask8, a: __m128i) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepu32_pd(src: __m128d, k: __mmask8, a: __m128i) -> __m128d { unsafe { let convert = _mm_cvtepu32_pd(a).as_f64x2(); transmute(simd_select_bitmask(k, convert, src.as_f64x2())) @@ -12779,7 +13219,8 @@ pub fn _mm_mask_cvtepu32_pd(src: __m128d, k: __mmask8, a: __m128i) -> __m128d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm_maskz_cvtepu32_pd(k: __mmask8, a: __m128i) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepu32_pd(k: __mmask8, a: __m128i) -> __m128d { unsafe { let convert = _mm_cvtepu32_pd(a).as_f64x2(); transmute(simd_select_bitmask(k, convert, f64x2::ZERO)) @@ -12793,7 +13234,8 @@ pub fn _mm_maskz_cvtepu32_pd(k: __mmask8, a: __m128i) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] -pub fn _mm512_cvtepi32lo_pd(v2: __m512i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi32lo_pd(v2: __m512i) -> __m512d { unsafe { let v2 = v2.as_i32x16(); let v256: i32x8 = simd_shuffle!(v2, v2, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -12808,7 +13250,8 @@ pub fn _mm512_cvtepi32lo_pd(v2: __m512i) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtdq2pd))] -pub fn _mm512_mask_cvtepi32lo_pd(src: __m512d, k: __mmask8, v2: __m512i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi32lo_pd(src: __m512d, k: __mmask8, v2: __m512i) -> __m512d { unsafe { let convert = _mm512_cvtepi32lo_pd(v2).as_f64x8(); transmute(simd_select_bitmask(k, convert, src.as_f64x8())) @@ -12822,7 +13265,8 @@ pub fn _mm512_mask_cvtepi32lo_pd(src: __m512d, k: __mmask8, v2: __m512i) -> __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm512_cvtepu32lo_pd(v2: __m512i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepu32lo_pd(v2: __m512i) -> __m512d { unsafe { let v2 = v2.as_u32x16(); let v256: u32x8 = simd_shuffle!(v2, v2, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -12837,7 +13281,8 @@ pub fn _mm512_cvtepu32lo_pd(v2: __m512i) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtudq2pd))] -pub fn _mm512_mask_cvtepu32lo_pd(src: __m512d, k: __mmask8, v2: __m512i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepu32lo_pd(src: __m512d, k: __mmask8, v2: __m512i) -> __m512d { unsafe { let convert = _mm512_cvtepu32lo_pd(v2).as_f64x8(); transmute(simd_select_bitmask(k, convert, src.as_f64x8())) @@ -12851,7 +13296,8 @@ pub fn _mm512_mask_cvtepu32lo_pd(src: __m512d, k: __mmask8, v2: __m512i) -> __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovdw))] -pub fn _mm512_cvtepi32_epi16(a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi32_epi16(a: __m512i) -> __m256i { unsafe { let a = a.as_i32x16(); transmute::(simd_cast(a)) @@ -12865,7 +13311,8 @@ pub fn _mm512_cvtepi32_epi16(a: __m512i) -> __m256i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovdw))] -pub fn _mm512_mask_cvtepi32_epi16(src: __m256i, k: __mmask16, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi32_epi16(src: __m256i, k: __mmask16, a: __m512i) -> __m256i { unsafe { let convert = _mm512_cvtepi32_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, convert, src.as_i16x16())) @@ -12879,7 +13326,8 @@ pub fn _mm512_mask_cvtepi32_epi16(src: __m256i, k: __mmask16, a: __m512i) -> __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovdw))] -pub fn _mm512_maskz_cvtepi32_epi16(k: __mmask16, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi32_epi16(k: __mmask16, a: __m512i) -> __m256i { unsafe { let convert = _mm512_cvtepi32_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, convert, i16x16::ZERO)) @@ -12893,7 +13341,8 @@ pub fn _mm512_maskz_cvtepi32_epi16(k: __mmask16, a: __m512i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovdw))] -pub fn _mm256_cvtepi32_epi16(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi32_epi16(a: __m256i) -> __m128i { unsafe { let a = a.as_i32x8(); transmute::(simd_cast(a)) @@ -12907,7 +13356,8 @@ pub fn _mm256_cvtepi32_epi16(a: __m256i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovdw))] -pub fn _mm256_mask_cvtepi32_epi16(src: __m128i, k: __mmask8, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi32_epi16(src: __m128i, k: __mmask8, a: __m256i) -> __m128i { unsafe { let convert = _mm256_cvtepi32_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, convert, src.as_i16x8())) @@ -12921,7 +13371,8 @@ pub fn _mm256_mask_cvtepi32_epi16(src: __m128i, k: __mmask8, a: __m256i) -> __m1 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovdw))] -pub fn _mm256_maskz_cvtepi32_epi16(k: __mmask8, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi32_epi16(k: __mmask8, a: __m256i) -> __m128i { unsafe { let convert = _mm256_cvtepi32_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, convert, i16x8::ZERO)) @@ -12968,7 +13419,8 @@ pub fn _mm_maskz_cvtepi32_epi16(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovdb))] -pub fn _mm512_cvtepi32_epi8(a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi32_epi8(a: __m512i) -> __m128i { unsafe { let a = a.as_i32x16(); transmute::(simd_cast(a)) @@ -12982,7 +13434,8 @@ pub fn _mm512_cvtepi32_epi8(a: __m512i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovdb))] -pub fn _mm512_mask_cvtepi32_epi8(src: __m128i, k: __mmask16, a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi32_epi8(src: __m128i, k: __mmask16, a: __m512i) -> __m128i { unsafe { let convert = _mm512_cvtepi32_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, convert, src.as_i8x16())) @@ -12996,7 +13449,8 @@ pub fn _mm512_mask_cvtepi32_epi8(src: __m128i, k: __mmask16, a: __m512i) -> __m1 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovdb))] -pub fn _mm512_maskz_cvtepi32_epi8(k: __mmask16, a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi32_epi8(k: __mmask16, a: __m512i) -> __m128i { unsafe { let convert = _mm512_cvtepi32_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, convert, i8x16::ZERO)) @@ -13076,7 +13530,8 @@ pub fn _mm_maskz_cvtepi32_epi8(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovqd))] -pub fn _mm512_cvtepi64_epi32(a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi64_epi32(a: __m512i) -> __m256i { unsafe { let a = a.as_i64x8(); transmute::(simd_cast(a)) @@ -13090,7 +13545,8 @@ pub fn _mm512_cvtepi64_epi32(a: __m512i) -> __m256i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovqd))] -pub fn _mm512_mask_cvtepi64_epi32(src: __m256i, k: __mmask8, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi64_epi32(src: __m256i, k: __mmask8, a: __m512i) -> __m256i { unsafe { let convert = _mm512_cvtepi64_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, src.as_i32x8())) @@ -13104,7 +13560,8 @@ pub fn _mm512_mask_cvtepi64_epi32(src: __m256i, k: __mmask8, a: __m512i) -> __m2 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovqd))] -pub fn _mm512_maskz_cvtepi64_epi32(k: __mmask8, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi64_epi32(k: __mmask8, a: __m512i) -> __m256i { unsafe { let convert = _mm512_cvtepi64_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, convert, i32x8::ZERO)) @@ -13118,7 +13575,8 @@ pub fn _mm512_maskz_cvtepi64_epi32(k: __mmask8, a: __m512i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovqd))] -pub fn _mm256_cvtepi64_epi32(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi64_epi32(a: __m256i) -> __m128i { unsafe { let a = a.as_i64x4(); transmute::(simd_cast(a)) @@ -13132,7 +13590,8 @@ pub fn _mm256_cvtepi64_epi32(a: __m256i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovqd))] -pub fn _mm256_mask_cvtepi64_epi32(src: __m128i, k: __mmask8, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi64_epi32(src: __m128i, k: __mmask8, a: __m256i) -> __m128i { unsafe { let convert = _mm256_cvtepi64_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, src.as_i32x4())) @@ -13146,7 +13605,8 @@ pub fn _mm256_mask_cvtepi64_epi32(src: __m128i, k: __mmask8, a: __m256i) -> __m1 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovqd))] -pub fn _mm256_maskz_cvtepi64_epi32(k: __mmask8, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi64_epi32(k: __mmask8, a: __m256i) -> __m128i { unsafe { let convert = _mm256_cvtepi64_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, convert, i32x4::ZERO)) @@ -13193,7 +13653,8 @@ pub fn _mm_maskz_cvtepi64_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovqw))] -pub fn _mm512_cvtepi64_epi16(a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi64_epi16(a: __m512i) -> __m128i { unsafe { let a = a.as_i64x8(); transmute::(simd_cast(a)) @@ -13207,7 +13668,8 @@ pub fn _mm512_cvtepi64_epi16(a: __m512i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovqw))] -pub fn _mm512_mask_cvtepi64_epi16(src: __m128i, k: __mmask8, a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi64_epi16(src: __m128i, k: __mmask8, a: __m512i) -> __m128i { unsafe { let convert = _mm512_cvtepi64_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, convert, src.as_i16x8())) @@ -13221,7 +13683,8 @@ pub fn _mm512_mask_cvtepi64_epi16(src: __m128i, k: __mmask8, a: __m512i) -> __m1 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovqw))] -pub fn _mm512_maskz_cvtepi64_epi16(k: __mmask8, a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi64_epi16(k: __mmask8, a: __m512i) -> __m128i { unsafe { let convert = _mm512_cvtepi64_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, convert, i16x8::ZERO)) @@ -16178,7 +16641,8 @@ pub fn _mm_maskz_cvttpd_epu32(k: __mmask8, a: __m128d) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vxorps))] -pub fn _mm512_setzero_pd() -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setzero_pd() -> __m512d { // All-0 is a properly initialized __m512d unsafe { const { mem::zeroed() } } } @@ -16190,7 +16654,8 @@ pub fn _mm512_setzero_pd() -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vxorps))] -pub fn _mm512_setzero_ps() -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setzero_ps() -> __m512 { // All-0 is a properly initialized __m512 unsafe { const { mem::zeroed() } } } @@ -16202,7 +16667,8 @@ pub fn _mm512_setzero_ps() -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vxorps))] -pub fn _mm512_setzero() -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setzero() -> __m512 { // All-0 is a properly initialized __m512 unsafe { const { mem::zeroed() } } } @@ -16214,7 +16680,8 @@ pub fn _mm512_setzero() -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vxorps))] -pub fn _mm512_setzero_si512() -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setzero_si512() -> __m512i { // All-0 is a properly initialized __m512i unsafe { const { mem::zeroed() } } } @@ -16226,7 +16693,8 @@ pub fn _mm512_setzero_si512() -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vxorps))] -pub fn _mm512_setzero_epi32() -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setzero_epi32() -> __m512i { // All-0 is a properly initialized __m512i unsafe { const { mem::zeroed() } } } @@ -16238,7 +16706,8 @@ pub fn _mm512_setzero_epi32() -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_setr_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setr_epi32( e15: i32, e14: i32, e13: i32, @@ -16270,7 +16739,8 @@ pub fn _mm512_setr_epi32( #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set_epi8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set_epi8( e63: i8, e62: i8, e61: i8, @@ -16353,7 +16823,8 @@ pub fn _mm512_set_epi8( #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set_epi16( e31: i16, e30: i16, e29: i16, @@ -16402,7 +16873,8 @@ pub fn _mm512_set_epi16( #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set4_epi32(d: i32, c: i32, b: i32, a: i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set4_epi32(d: i32, c: i32, b: i32, a: i32) -> __m512i { _mm512_set_epi32(d, c, b, a, d, c, b, a, d, c, b, a, d, c, b, a) } @@ -16412,7 +16884,8 @@ pub fn _mm512_set4_epi32(d: i32, c: i32, b: i32, a: i32) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set4_ps(d: f32, c: f32, b: f32, a: f32) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set4_ps(d: f32, c: f32, b: f32, a: f32) -> __m512 { _mm512_set_ps(d, c, b, a, d, c, b, a, d, c, b, a, d, c, b, a) } @@ -16422,7 +16895,8 @@ pub fn _mm512_set4_ps(d: f32, c: f32, b: f32, a: f32) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set4_pd(d: f64, c: f64, b: f64, a: f64) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set4_pd(d: f64, c: f64, b: f64, a: f64) -> __m512d { _mm512_set_pd(d, c, b, a, d, c, b, a) } @@ -16432,7 +16906,8 @@ pub fn _mm512_set4_pd(d: f64, c: f64, b: f64, a: f64) -> __m512d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_setr4_epi32(d: i32, c: i32, b: i32, a: i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setr4_epi32(d: i32, c: i32, b: i32, a: i32) -> __m512i { _mm512_set_epi32(a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d) } @@ -16442,7 +16917,8 @@ pub fn _mm512_setr4_epi32(d: i32, c: i32, b: i32, a: i32) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_setr4_ps(d: f32, c: f32, b: f32, a: f32) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setr4_ps(d: f32, c: f32, b: f32, a: f32) -> __m512 { _mm512_set_ps(a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d) } @@ -16452,7 +16928,8 @@ pub fn _mm512_setr4_ps(d: f32, c: f32, b: f32, a: f32) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_setr4_pd(d: f64, c: f64, b: f64, a: f64) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setr4_pd(d: f64, c: f64, b: f64, a: f64) -> __m512d { _mm512_set_pd(a, b, c, d, a, b, c, d) } @@ -16462,7 +16939,8 @@ pub fn _mm512_setr4_pd(d: f64, c: f64, b: f64, a: f64) -> __m512d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set_epi64( e0: i64, e1: i64, e2: i64, @@ -16481,7 +16959,8 @@ pub fn _mm512_set_epi64( #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_setr_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setr_epi64( e0: i64, e1: i64, e2: i64, @@ -19006,7 +19485,8 @@ pub fn _mm_maskz_expand_pd(k: __mmask8, a: __m128d) -> __m128d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_rol_epi32(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_rol_epi32(a: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_rolv_epi32(a, _mm512_set1_epi32(IMM8)) } @@ -19019,7 +19499,12 @@ pub fn _mm512_rol_epi32(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_rol_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_rol_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, +) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_mask_rolv_epi32(src, k, a, _mm512_set1_epi32(IMM8)) } @@ -19032,7 +19517,8 @@ pub fn _mm512_mask_rol_epi32(src: __m512i, k: __mmask16, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_rol_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_rol_epi32(k: __mmask16, a: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_maskz_rolv_epi32(k, a, _mm512_set1_epi32(IMM8)) } @@ -19045,7 +19531,8 @@ pub fn _mm512_maskz_rol_epi32(k: __mmask16, a: __m512i) -> __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm256_rol_epi32(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_rol_epi32(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_rolv_epi32(a, _mm256_set1_epi32(IMM8)) } @@ -19058,7 +19545,12 @@ pub fn _mm256_rol_epi32(a: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_rol_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_rol_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_mask_rolv_epi32(src, k, a, _mm256_set1_epi32(IMM8)) } @@ -19071,7 +19563,8 @@ pub fn _mm256_mask_rol_epi32(src: __m256i, k: __mmask8, a: __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_rol_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_rol_epi32(k: __mmask8, a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_maskz_rolv_epi32(k, a, _mm256_set1_epi32(IMM8)) } @@ -19084,7 +19577,8 @@ pub fn _mm256_maskz_rol_epi32(k: __mmask8, a: __m256i) -> __m25 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm_rol_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_rol_epi32(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_rolv_epi32(a, _mm_set1_epi32(IMM8)) } @@ -19097,7 +19591,8 @@ pub fn _mm_rol_epi32(a: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_rol_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_rol_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_mask_rolv_epi32(src, k, a, _mm_set1_epi32(IMM8)) } @@ -19110,7 +19605,8 @@ pub fn _mm_mask_rol_epi32(src: __m128i, k: __mmask8, a: __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_rol_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_rol_epi32(k: __mmask8, a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_maskz_rolv_epi32(k, a, _mm_set1_epi32(IMM8)) } @@ -19123,7 +19619,8 @@ pub fn _mm_maskz_rol_epi32(k: __mmask8, a: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_ror_epi32(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_ror_epi32(a: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_rorv_epi32(a, _mm512_set1_epi32(IMM8)) } @@ -19136,7 +19633,12 @@ pub fn _mm512_ror_epi32(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 123))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_ror_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_ror_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, +) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_mask_rorv_epi32(src, k, a, _mm512_set1_epi32(IMM8)) } @@ -19149,7 +19651,8 @@ pub fn _mm512_mask_ror_epi32(src: __m512i, k: __mmask16, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 123))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_ror_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_ror_epi32(k: __mmask16, a: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_maskz_rorv_epi32(k, a, _mm512_set1_epi32(IMM8)) } @@ -19162,7 +19665,8 @@ pub fn _mm512_maskz_ror_epi32(k: __mmask16, a: __m512i) -> __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm256_ror_epi32(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_ror_epi32(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_rorv_epi32(a, _mm256_set1_epi32(IMM8)) } @@ -19175,7 +19679,12 @@ pub fn _mm256_ror_epi32(a: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 123))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_ror_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_ror_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_mask_rorv_epi32(src, k, a, _mm256_set1_epi32(IMM8)) } @@ -19188,7 +19697,8 @@ pub fn _mm256_mask_ror_epi32(src: __m256i, k: __mmask8, a: __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 123))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_ror_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_ror_epi32(k: __mmask8, a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_maskz_rorv_epi32(k, a, _mm256_set1_epi32(IMM8)) } @@ -19201,7 +19711,8 @@ pub fn _mm256_maskz_ror_epi32(k: __mmask8, a: __m256i) -> __m25 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm_ror_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_ror_epi32(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_rorv_epi32(a, _mm_set1_epi32(IMM8)) } @@ -19214,7 +19725,8 @@ pub fn _mm_ror_epi32(a: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 123))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_ror_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_ror_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_mask_rorv_epi32(src, k, a, _mm_set1_epi32(IMM8)) } @@ -19227,7 +19739,8 @@ pub fn _mm_mask_ror_epi32(src: __m128i, k: __mmask8, a: __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprold, IMM8 = 123))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_ror_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_ror_epi32(k: __mmask8, a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_maskz_rorv_epi32(k, a, _mm_set1_epi32(IMM8)) } @@ -19240,7 +19753,8 @@ pub fn _mm_maskz_ror_epi32(k: __mmask8, a: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_rol_epi64(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_rol_epi64(a: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_rolv_epi64(a, _mm512_set1_epi64(IMM8 as i64)) } @@ -19253,7 +19767,12 @@ pub fn _mm512_rol_epi64(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_rol_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_rol_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, +) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_mask_rolv_epi64(src, k, a, _mm512_set1_epi64(IMM8 as i64)) } @@ -19266,7 +19785,8 @@ pub fn _mm512_mask_rol_epi64(src: __m512i, k: __mmask8, a: __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_rol_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_rol_epi64(k: __mmask8, a: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_maskz_rolv_epi64(k, a, _mm512_set1_epi64(IMM8 as i64)) } @@ -19279,7 +19799,8 @@ pub fn _mm512_maskz_rol_epi64(k: __mmask8, a: __m512i) -> __m51 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm256_rol_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_rol_epi64(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_rolv_epi64(a, _mm256_set1_epi64x(IMM8 as i64)) } @@ -19292,7 +19813,12 @@ pub fn _mm256_rol_epi64(a: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_rol_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_rol_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_mask_rolv_epi64(src, k, a, _mm256_set1_epi64x(IMM8 as i64)) } @@ -19305,7 +19831,8 @@ pub fn _mm256_mask_rol_epi64(src: __m256i, k: __mmask8, a: __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_rol_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_rol_epi64(k: __mmask8, a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_maskz_rolv_epi64(k, a, _mm256_set1_epi64x(IMM8 as i64)) } @@ -19318,7 +19845,8 @@ pub fn _mm256_maskz_rol_epi64(k: __mmask8, a: __m256i) -> __m25 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm_rol_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_rol_epi64(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_rolv_epi64(a, _mm_set1_epi64x(IMM8 as i64)) } @@ -19331,7 +19859,8 @@ pub fn _mm_rol_epi64(a: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_rol_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_rol_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_mask_rolv_epi64(src, k, a, _mm_set1_epi64x(IMM8 as i64)) } @@ -19344,7 +19873,8 @@ pub fn _mm_mask_rol_epi64(src: __m128i, k: __mmask8, a: __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_rol_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_rol_epi64(k: __mmask8, a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_maskz_rolv_epi64(k, a, _mm_set1_epi64x(IMM8 as i64)) } @@ -19357,7 +19887,8 @@ pub fn _mm_maskz_rol_epi64(k: __mmask8, a: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 15))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_ror_epi64(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_ror_epi64(a: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_rorv_epi64(a, _mm512_set1_epi64(IMM8 as i64)) } @@ -19370,7 +19901,12 @@ pub fn _mm512_ror_epi64(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 15))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_ror_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_ror_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, +) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_mask_rorv_epi64(src, k, a, _mm512_set1_epi64(IMM8 as i64)) } @@ -19383,7 +19919,8 @@ pub fn _mm512_mask_ror_epi64(src: __m512i, k: __mmask8, a: __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 15))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_ror_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_ror_epi64(k: __mmask8, a: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_maskz_rorv_epi64(k, a, _mm512_set1_epi64(IMM8 as i64)) } @@ -19396,7 +19933,8 @@ pub fn _mm512_maskz_ror_epi64(k: __mmask8, a: __m512i) -> __m51 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 15))] #[rustc_legacy_const_generics(1)] -pub fn _mm256_ror_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_ror_epi64(a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_rorv_epi64(a, _mm256_set1_epi64x(IMM8 as i64)) } @@ -19409,7 +19947,12 @@ pub fn _mm256_ror_epi64(a: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 15))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_ror_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_ror_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_mask_rorv_epi64(src, k, a, _mm256_set1_epi64x(IMM8 as i64)) } @@ -19422,7 +19965,8 @@ pub fn _mm256_mask_ror_epi64(src: __m256i, k: __mmask8, a: __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 15))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_ror_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_ror_epi64(k: __mmask8, a: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_maskz_rorv_epi64(k, a, _mm256_set1_epi64x(IMM8 as i64)) } @@ -19435,7 +19979,8 @@ pub fn _mm256_maskz_ror_epi64(k: __mmask8, a: __m256i) -> __m25 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 15))] #[rustc_legacy_const_generics(1)] -pub fn _mm_ror_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_ror_epi64(a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_rorv_epi64(a, _mm_set1_epi64x(IMM8 as i64)) } @@ -19448,7 +19993,8 @@ pub fn _mm_ror_epi64(a: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 15))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_ror_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_ror_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_mask_rorv_epi64(src, k, a, _mm_set1_epi64x(IMM8 as i64)) } @@ -19461,7 +20007,8 @@ pub fn _mm_mask_ror_epi64(src: __m128i, k: __mmask8, a: __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolq, IMM8 = 15))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_ror_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_ror_epi64(k: __mmask8, a: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_maskz_rorv_epi64(k, a, _mm_set1_epi64x(IMM8 as i64)) } @@ -19474,7 +20021,8 @@ pub fn _mm_maskz_ror_epi64(k: __mmask8, a: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpslld, IMM8 = 5))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_slli_epi32(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_slli_epi32(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 32 { @@ -19493,7 +20041,12 @@ pub fn _mm512_slli_epi32(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpslld, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_slli_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_slli_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = if IMM8 >= 32 { @@ -19513,7 +20066,8 @@ pub fn _mm512_mask_slli_epi32(src: __m512i, k: __mmask16, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpslld, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_slli_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_slli_epi32(k: __mmask16, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 32 { @@ -19533,7 +20087,12 @@ pub fn _mm512_maskz_slli_epi32(k: __mmask16, a: __m512i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpslld, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_slli_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_slli_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = if IMM8 >= 32 { @@ -19553,7 +20112,8 @@ pub fn _mm256_mask_slli_epi32(src: __m256i, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpslld, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_slli_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_slli_epi32(k: __mmask8, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 32 { @@ -19573,7 +20133,12 @@ pub fn _mm256_maskz_slli_epi32(k: __mmask8, a: __m256i) -> __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpslld, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_slli_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_slli_epi32( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = if IMM8 >= 32 { @@ -19593,7 +20158,8 @@ pub fn _mm_mask_slli_epi32(src: __m128i, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpslld, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_slli_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_slli_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 32 { @@ -19613,7 +20179,8 @@ pub fn _mm_maskz_slli_epi32(k: __mmask8, a: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrld, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_srli_epi32(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srli_epi32(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 32 { @@ -19632,7 +20199,12 @@ pub fn _mm512_srli_epi32(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrld, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_srli_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srli_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = if IMM8 >= 32 { @@ -19652,7 +20224,8 @@ pub fn _mm512_mask_srli_epi32(src: __m512i, k: __mmask16, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrld, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_srli_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srli_epi32(k: __mmask16, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 32 { @@ -19672,7 +20245,12 @@ pub fn _mm512_maskz_srli_epi32(k: __mmask16, a: __m512i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrld, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_srli_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srli_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = if IMM8 >= 32 { @@ -19692,7 +20270,8 @@ pub fn _mm256_mask_srli_epi32(src: __m256i, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrld, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_srli_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srli_epi32(k: __mmask8, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 32 { @@ -19712,7 +20291,12 @@ pub fn _mm256_maskz_srli_epi32(k: __mmask8, a: __m256i) -> __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrld, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_srli_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srli_epi32( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = if IMM8 >= 32 { @@ -19732,7 +20316,8 @@ pub fn _mm_mask_srli_epi32(src: __m128i, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrld, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_srli_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srli_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 32 { @@ -19752,7 +20337,8 @@ pub fn _mm_maskz_srli_epi32(k: __mmask8, a: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllq, IMM8 = 5))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_slli_epi64(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_slli_epi64(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 64 { @@ -19771,7 +20357,12 @@ pub fn _mm512_slli_epi64(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllq, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_slli_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_slli_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = if IMM8 >= 64 { @@ -19791,7 +20382,8 @@ pub fn _mm512_mask_slli_epi64(src: __m512i, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllq, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_slli_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_slli_epi64(k: __mmask8, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 64 { @@ -19811,7 +20403,12 @@ pub fn _mm512_maskz_slli_epi64(k: __mmask8, a: __m512i) -> __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllq, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_slli_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_slli_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = if IMM8 >= 64 { @@ -19831,7 +20428,8 @@ pub fn _mm256_mask_slli_epi64(src: __m256i, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllq, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_slli_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_slli_epi64(k: __mmask8, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 64 { @@ -19851,7 +20449,12 @@ pub fn _mm256_maskz_slli_epi64(k: __mmask8, a: __m256i) -> __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllq, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_slli_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_slli_epi64( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = if IMM8 >= 64 { @@ -19871,7 +20474,8 @@ pub fn _mm_mask_slli_epi64(src: __m128i, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllq, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_slli_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_slli_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 64 { @@ -19891,7 +20495,8 @@ pub fn _mm_maskz_slli_epi64(k: __mmask8, a: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_srli_epi64(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srli_epi64(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 64 { @@ -19910,7 +20515,12 @@ pub fn _mm512_srli_epi64(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_srli_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srli_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = if IMM8 >= 64 { @@ -19930,7 +20540,8 @@ pub fn _mm512_mask_srli_epi64(src: __m512i, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_srli_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srli_epi64(k: __mmask8, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 64 { @@ -19950,7 +20561,12 @@ pub fn _mm512_maskz_srli_epi64(k: __mmask8, a: __m512i) -> __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_srli_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srli_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = if IMM8 >= 64 { @@ -19970,7 +20586,8 @@ pub fn _mm256_mask_srli_epi64(src: __m256i, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_srli_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srli_epi64(k: __mmask8, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 64 { @@ -19990,7 +20607,12 @@ pub fn _mm256_maskz_srli_epi64(k: __mmask8, a: __m256i) -> __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_srli_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srli_epi64( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = if IMM8 >= 64 { @@ -20010,7 +20632,8 @@ pub fn _mm_mask_srli_epi64(src: __m128i, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_srli_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srli_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 64 { @@ -20622,7 +21245,8 @@ pub fn _mm_maskz_sra_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrad, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_srai_epi32(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srai_epi32(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); transmute(simd_shr(a.as_i32x16(), i32x16::splat(IMM8.min(31) as i32))) @@ -20637,7 +21261,12 @@ pub fn _mm512_srai_epi32(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrad, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_srai_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srai_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = simd_shr(a.as_i32x16(), i32x16::splat(IMM8.min(31) as i32)); @@ -20653,7 +21282,8 @@ pub fn _mm512_mask_srai_epi32(src: __m512i, k: __mmask16, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrad, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_srai_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srai_epi32(k: __mmask16, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = simd_shr(a.as_i32x16(), i32x16::splat(IMM8.min(31) as i32)); @@ -20669,7 +21299,12 @@ pub fn _mm512_maskz_srai_epi32(k: __mmask16, a: __m512i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrad, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_srai_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srai_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { unsafe { let r = simd_shr(a.as_i32x8(), i32x8::splat(IMM8.min(31) as i32)); transmute(simd_select_bitmask(k, r, src.as_i32x8())) @@ -20684,7 +21319,8 @@ pub fn _mm256_mask_srai_epi32(src: __m256i, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrad, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_srai_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srai_epi32(k: __mmask8, a: __m256i) -> __m256i { unsafe { let r = simd_shr(a.as_i32x8(), i32x8::splat(IMM8.min(31) as i32)); transmute(simd_select_bitmask(k, r, i32x8::ZERO)) @@ -20699,7 +21335,12 @@ pub fn _mm256_maskz_srai_epi32(k: __mmask8, a: __m256i) -> __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrad, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_srai_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srai_epi32( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { let r = simd_shr(a.as_i32x4(), i32x4::splat(IMM8.min(31) as i32)); transmute(simd_select_bitmask(k, r, src.as_i32x4())) @@ -20714,7 +21355,8 @@ pub fn _mm_mask_srai_epi32(src: __m128i, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrad, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_srai_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srai_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { let r = simd_shr(a.as_i32x4(), i32x4::splat(IMM8.min(31) as i32)); transmute(simd_select_bitmask(k, r, i32x4::ZERO)) @@ -20729,7 +21371,8 @@ pub fn _mm_maskz_srai_epi32(k: __mmask8, a: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_srai_epi64(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srai_epi64(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); transmute(simd_shr(a.as_i64x8(), i64x8::splat(IMM8.min(63) as i64))) @@ -20744,7 +21387,12 @@ pub fn _mm512_srai_epi64(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_srai_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srai_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = simd_shr(a.as_i64x8(), i64x8::splat(IMM8.min(63) as i64)); @@ -20760,7 +21408,8 @@ pub fn _mm512_mask_srai_epi64(src: __m512i, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_srai_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srai_epi64(k: __mmask8, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = simd_shr(a.as_i64x8(), i64x8::splat(IMM8.min(63) as i64)); @@ -20776,7 +21425,8 @@ pub fn _mm512_maskz_srai_epi64(k: __mmask8, a: __m512i) -> __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm256_srai_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srai_epi64(a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); transmute(simd_shr(a.as_i64x4(), i64x4::splat(IMM8.min(63) as i64))) @@ -20791,7 +21441,12 @@ pub fn _mm256_srai_epi64(a: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_srai_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srai_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = simd_shr(a.as_i64x4(), i64x4::splat(IMM8.min(63) as i64)); @@ -20807,7 +21462,8 @@ pub fn _mm256_mask_srai_epi64(src: __m256i, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_srai_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srai_epi64(k: __mmask8, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = simd_shr(a.as_i64x4(), i64x4::splat(IMM8.min(63) as i64)); @@ -20823,7 +21479,8 @@ pub fn _mm256_maskz_srai_epi64(k: __mmask8, a: __m256i) -> __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraq, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm_srai_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srai_epi64(a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); transmute(simd_shr(a.as_i64x2(), i64x2::splat(IMM8.min(63) as i64))) @@ -20838,7 +21495,12 @@ pub fn _mm_srai_epi64(a: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_srai_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srai_epi64( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = simd_shr(a.as_i64x2(), i64x2::splat(IMM8.min(63) as i64)); @@ -20854,7 +21516,8 @@ pub fn _mm_mask_srai_epi64(src: __m128i, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_srai_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srai_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = simd_shr(a.as_i64x2(), i64x2::splat(IMM8.min(63) as i64)); @@ -20869,7 +21532,8 @@ pub fn _mm_maskz_srai_epi64(k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravd))] -pub fn _mm512_srav_epi32(a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srav_epi32(a: __m512i, count: __m512i) -> __m512i { unsafe { let count = count.as_u32x16(); let no_overflow: u32x16 = simd_lt(count, u32x16::splat(u32::BITS)); @@ -20885,7 +21549,13 @@ pub fn _mm512_srav_epi32(a: __m512i, count: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravd))] -pub fn _mm512_mask_srav_epi32(src: __m512i, k: __mmask16, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srav_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, + count: __m512i, +) -> __m512i { unsafe { let shf = _mm512_srav_epi32(a, count).as_i32x16(); transmute(simd_select_bitmask(k, shf, src.as_i32x16())) @@ -20899,7 +21569,8 @@ pub fn _mm512_mask_srav_epi32(src: __m512i, k: __mmask16, a: __m512i, count: __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravd))] -pub fn _mm512_maskz_srav_epi32(k: __mmask16, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srav_epi32(k: __mmask16, a: __m512i, count: __m512i) -> __m512i { unsafe { let shf = _mm512_srav_epi32(a, count).as_i32x16(); transmute(simd_select_bitmask(k, shf, i32x16::ZERO)) @@ -20913,7 +21584,13 @@ pub fn _mm512_maskz_srav_epi32(k: __mmask16, a: __m512i, count: __m512i) -> __m5 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravd))] -pub fn _mm256_mask_srav_epi32(src: __m256i, k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srav_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, + count: __m256i, +) -> __m256i { unsafe { let shf = _mm256_srav_epi32(a, count).as_i32x8(); transmute(simd_select_bitmask(k, shf, src.as_i32x8())) @@ -20927,7 +21604,8 @@ pub fn _mm256_mask_srav_epi32(src: __m256i, k: __mmask8, a: __m256i, count: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravd))] -pub fn _mm256_maskz_srav_epi32(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srav_epi32(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { unsafe { let shf = _mm256_srav_epi32(a, count).as_i32x8(); transmute(simd_select_bitmask(k, shf, i32x8::ZERO)) @@ -20941,7 +21619,8 @@ pub fn _mm256_maskz_srav_epi32(k: __mmask8, a: __m256i, count: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravd))] -pub fn _mm_mask_srav_epi32(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srav_epi32(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srav_epi32(a, count).as_i32x4(); transmute(simd_select_bitmask(k, shf, src.as_i32x4())) @@ -20955,7 +21634,8 @@ pub fn _mm_mask_srav_epi32(src: __m128i, k: __mmask8, a: __m128i, count: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravd))] -pub fn _mm_maskz_srav_epi32(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srav_epi32(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srav_epi32(a, count).as_i32x4(); transmute(simd_select_bitmask(k, shf, i32x4::ZERO)) @@ -20969,7 +21649,8 @@ pub fn _mm_maskz_srav_epi32(k: __mmask8, a: __m128i, count: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravq))] -pub fn _mm512_srav_epi64(a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srav_epi64(a: __m512i, count: __m512i) -> __m512i { unsafe { let count = count.as_u64x8(); let no_overflow: u64x8 = simd_lt(count, u64x8::splat(u64::BITS as u64)); @@ -20985,7 +21666,13 @@ pub fn _mm512_srav_epi64(a: __m512i, count: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravq))] -pub fn _mm512_mask_srav_epi64(src: __m512i, k: __mmask8, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srav_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, + count: __m512i, +) -> __m512i { unsafe { let shf = _mm512_srav_epi64(a, count).as_i64x8(); transmute(simd_select_bitmask(k, shf, src.as_i64x8())) @@ -20999,7 +21686,8 @@ pub fn _mm512_mask_srav_epi64(src: __m512i, k: __mmask8, a: __m512i, count: __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravq))] -pub fn _mm512_maskz_srav_epi64(k: __mmask8, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srav_epi64(k: __mmask8, a: __m512i, count: __m512i) -> __m512i { unsafe { let shf = _mm512_srav_epi64(a, count).as_i64x8(); transmute(simd_select_bitmask(k, shf, i64x8::ZERO)) @@ -21013,7 +21701,8 @@ pub fn _mm512_maskz_srav_epi64(k: __mmask8, a: __m512i, count: __m512i) -> __m51 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravq))] -pub fn _mm256_srav_epi64(a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srav_epi64(a: __m256i, count: __m256i) -> __m256i { unsafe { let count = count.as_u64x4(); let no_overflow: u64x4 = simd_lt(count, u64x4::splat(u64::BITS as u64)); @@ -21029,7 +21718,13 @@ pub fn _mm256_srav_epi64(a: __m256i, count: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravq))] -pub fn _mm256_mask_srav_epi64(src: __m256i, k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srav_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, + count: __m256i, +) -> __m256i { unsafe { let shf = _mm256_srav_epi64(a, count).as_i64x4(); transmute(simd_select_bitmask(k, shf, src.as_i64x4())) @@ -21043,7 +21738,8 @@ pub fn _mm256_mask_srav_epi64(src: __m256i, k: __mmask8, a: __m256i, count: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravq))] -pub fn _mm256_maskz_srav_epi64(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srav_epi64(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { unsafe { let shf = _mm256_srav_epi64(a, count).as_i64x4(); transmute(simd_select_bitmask(k, shf, i64x4::ZERO)) @@ -21057,7 +21753,8 @@ pub fn _mm256_maskz_srav_epi64(k: __mmask8, a: __m256i, count: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravq))] -pub fn _mm_srav_epi64(a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srav_epi64(a: __m128i, count: __m128i) -> __m128i { unsafe { let count = count.as_u64x2(); let no_overflow: u64x2 = simd_lt(count, u64x2::splat(u64::BITS as u64)); @@ -21073,7 +21770,8 @@ pub fn _mm_srav_epi64(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravq))] -pub fn _mm_mask_srav_epi64(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srav_epi64(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srav_epi64(a, count).as_i64x2(); transmute(simd_select_bitmask(k, shf, src.as_i64x2())) @@ -21087,7 +21785,8 @@ pub fn _mm_mask_srav_epi64(src: __m128i, k: __mmask8, a: __m128i, count: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravq))] -pub fn _mm_maskz_srav_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srav_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srav_epi64(a, count).as_i64x2(); transmute(simd_select_bitmask(k, shf, i64x2::ZERO)) @@ -21101,7 +21800,8 @@ pub fn _mm_maskz_srav_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvd))] -pub fn _mm512_rolv_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_rolv_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shl( a.as_u32x16(), @@ -21118,7 +21818,8 @@ pub fn _mm512_rolv_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvd))] -pub fn _mm512_mask_rolv_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_rolv_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let rol = _mm512_rolv_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, rol, src.as_i32x16())) @@ -21132,7 +21833,8 @@ pub fn _mm512_mask_rolv_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvd))] -pub fn _mm512_maskz_rolv_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_rolv_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let rol = _mm512_rolv_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, rol, i32x16::ZERO)) @@ -21146,7 +21848,8 @@ pub fn _mm512_maskz_rolv_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvd))] -pub fn _mm256_rolv_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_rolv_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shl( a.as_u32x8(), @@ -21163,7 +21866,8 @@ pub fn _mm256_rolv_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvd))] -pub fn _mm256_mask_rolv_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_rolv_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let rol = _mm256_rolv_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, rol, src.as_i32x8())) @@ -21177,7 +21881,8 @@ pub fn _mm256_mask_rolv_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvd))] -pub fn _mm256_maskz_rolv_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_rolv_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let rol = _mm256_rolv_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, rol, i32x8::ZERO)) @@ -21191,7 +21896,8 @@ pub fn _mm256_maskz_rolv_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvd))] -pub fn _mm_rolv_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_rolv_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shl( a.as_u32x4(), @@ -21208,7 +21914,8 @@ pub fn _mm_rolv_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvd))] -pub fn _mm_mask_rolv_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_rolv_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let rol = _mm_rolv_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, rol, src.as_i32x4())) @@ -21222,7 +21929,8 @@ pub fn _mm_mask_rolv_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvd))] -pub fn _mm_maskz_rolv_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_rolv_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let rol = _mm_rolv_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, rol, i32x4::ZERO)) @@ -21236,7 +21944,8 @@ pub fn _mm_maskz_rolv_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvd))] -pub fn _mm512_rorv_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_rorv_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shr( a.as_u32x16(), @@ -21253,7 +21962,8 @@ pub fn _mm512_rorv_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvd))] -pub fn _mm512_mask_rorv_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_rorv_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let ror = _mm512_rorv_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, ror, src.as_i32x16())) @@ -21267,7 +21977,8 @@ pub fn _mm512_mask_rorv_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvd))] -pub fn _mm512_maskz_rorv_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_rorv_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let ror = _mm512_rorv_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, ror, i32x16::ZERO)) @@ -21281,7 +21992,8 @@ pub fn _mm512_maskz_rorv_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvd))] -pub fn _mm256_rorv_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_rorv_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shr( a.as_u32x8(), @@ -21298,7 +22010,8 @@ pub fn _mm256_rorv_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvd))] -pub fn _mm256_mask_rorv_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_rorv_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let ror = _mm256_rorv_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, ror, src.as_i32x8())) @@ -21312,7 +22025,8 @@ pub fn _mm256_mask_rorv_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvd))] -pub fn _mm256_maskz_rorv_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_rorv_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let ror = _mm256_rorv_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, ror, i32x8::ZERO)) @@ -21326,7 +22040,8 @@ pub fn _mm256_maskz_rorv_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvd))] -pub fn _mm_rorv_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_rorv_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shr( a.as_u32x4(), @@ -21343,7 +22058,8 @@ pub fn _mm_rorv_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvd))] -pub fn _mm_mask_rorv_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_rorv_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let ror = _mm_rorv_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, ror, src.as_i32x4())) @@ -21357,7 +22073,8 @@ pub fn _mm_mask_rorv_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvd))] -pub fn _mm_maskz_rorv_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_rorv_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let ror = _mm_rorv_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, ror, i32x4::ZERO)) @@ -21371,7 +22088,8 @@ pub fn _mm_maskz_rorv_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvq))] -pub fn _mm512_rolv_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_rolv_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shl( a.as_u64x8(), @@ -21388,7 +22106,8 @@ pub fn _mm512_rolv_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvq))] -pub fn _mm512_mask_rolv_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_rolv_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let rol = _mm512_rolv_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, rol, src.as_i64x8())) @@ -21402,7 +22121,8 @@ pub fn _mm512_mask_rolv_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvq))] -pub fn _mm512_maskz_rolv_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_rolv_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let rol = _mm512_rolv_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, rol, i64x8::ZERO)) @@ -21416,7 +22136,8 @@ pub fn _mm512_maskz_rolv_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvq))] -pub fn _mm256_rolv_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_rolv_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shl( a.as_u64x4(), @@ -21433,7 +22154,8 @@ pub fn _mm256_rolv_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvq))] -pub fn _mm256_mask_rolv_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_rolv_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let rol = _mm256_rolv_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, rol, src.as_i64x4())) @@ -21447,7 +22169,8 @@ pub fn _mm256_mask_rolv_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvq))] -pub fn _mm256_maskz_rolv_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_rolv_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let rol = _mm256_rolv_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, rol, i64x4::ZERO)) @@ -21461,7 +22184,8 @@ pub fn _mm256_maskz_rolv_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvq))] -pub fn _mm_rolv_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_rolv_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shl( a.as_u64x2(), @@ -21478,7 +22202,8 @@ pub fn _mm_rolv_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvq))] -pub fn _mm_mask_rolv_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_rolv_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let rol = _mm_rolv_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, rol, src.as_i64x2())) @@ -21492,7 +22217,8 @@ pub fn _mm_mask_rolv_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprolvq))] -pub fn _mm_maskz_rolv_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_rolv_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let rol = _mm_rolv_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, rol, i64x2::ZERO)) @@ -21506,7 +22232,8 @@ pub fn _mm_maskz_rolv_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvq))] -pub fn _mm512_rorv_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_rorv_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shr( a.as_u64x8(), @@ -21523,7 +22250,8 @@ pub fn _mm512_rorv_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvq))] -pub fn _mm512_mask_rorv_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_rorv_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let ror = _mm512_rorv_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, ror, src.as_i64x8())) @@ -21537,7 +22265,8 @@ pub fn _mm512_mask_rorv_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvq))] -pub fn _mm512_maskz_rorv_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_rorv_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let ror = _mm512_rorv_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, ror, i64x8::ZERO)) @@ -21551,7 +22280,8 @@ pub fn _mm512_maskz_rorv_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvq))] -pub fn _mm256_rorv_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_rorv_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shr( a.as_u64x4(), @@ -21568,7 +22298,8 @@ pub fn _mm256_rorv_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvq))] -pub fn _mm256_mask_rorv_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_rorv_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let ror = _mm256_rorv_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, ror, src.as_i64x4())) @@ -21582,7 +22313,8 @@ pub fn _mm256_mask_rorv_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvq))] -pub fn _mm256_maskz_rorv_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_rorv_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let ror = _mm256_rorv_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, ror, i64x4::ZERO)) @@ -21596,7 +22328,8 @@ pub fn _mm256_maskz_rorv_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvq))] -pub fn _mm_rorv_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_rorv_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shr( a.as_u64x2(), @@ -21613,7 +22346,8 @@ pub fn _mm_rorv_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvq))] -pub fn _mm_mask_rorv_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_rorv_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let ror = _mm_rorv_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, ror, src.as_i64x2())) @@ -21627,7 +22361,8 @@ pub fn _mm_mask_rorv_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vprorvq))] -pub fn _mm_maskz_rorv_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_rorv_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let ror = _mm_rorv_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, ror, i64x2::ZERO)) @@ -21641,7 +22376,8 @@ pub fn _mm_maskz_rorv_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvd))] -pub fn _mm512_sllv_epi32(a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sllv_epi32(a: __m512i, count: __m512i) -> __m512i { unsafe { let count = count.as_u32x16(); let no_overflow: u32x16 = simd_lt(count, u32x16::splat(u32::BITS)); @@ -21657,7 +22393,13 @@ pub fn _mm512_sllv_epi32(a: __m512i, count: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvd))] -pub fn _mm512_mask_sllv_epi32(src: __m512i, k: __mmask16, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sllv_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, + count: __m512i, +) -> __m512i { unsafe { let shf = _mm512_sllv_epi32(a, count).as_i32x16(); transmute(simd_select_bitmask(k, shf, src.as_i32x16())) @@ -21671,7 +22413,8 @@ pub fn _mm512_mask_sllv_epi32(src: __m512i, k: __mmask16, a: __m512i, count: __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvd))] -pub fn _mm512_maskz_sllv_epi32(k: __mmask16, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sllv_epi32(k: __mmask16, a: __m512i, count: __m512i) -> __m512i { unsafe { let shf = _mm512_sllv_epi32(a, count).as_i32x16(); transmute(simd_select_bitmask(k, shf, i32x16::ZERO)) @@ -21685,7 +22428,13 @@ pub fn _mm512_maskz_sllv_epi32(k: __mmask16, a: __m512i, count: __m512i) -> __m5 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvd))] -pub fn _mm256_mask_sllv_epi32(src: __m256i, k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sllv_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, + count: __m256i, +) -> __m256i { unsafe { let shf = _mm256_sllv_epi32(a, count).as_i32x8(); transmute(simd_select_bitmask(k, shf, src.as_i32x8())) @@ -21699,7 +22448,8 @@ pub fn _mm256_mask_sllv_epi32(src: __m256i, k: __mmask8, a: __m256i, count: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvd))] -pub fn _mm256_maskz_sllv_epi32(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sllv_epi32(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { unsafe { let shf = _mm256_sllv_epi32(a, count).as_i32x8(); transmute(simd_select_bitmask(k, shf, i32x8::ZERO)) @@ -21713,7 +22463,8 @@ pub fn _mm256_maskz_sllv_epi32(k: __mmask8, a: __m256i, count: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvd))] -pub fn _mm_mask_sllv_epi32(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sllv_epi32(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_sllv_epi32(a, count).as_i32x4(); transmute(simd_select_bitmask(k, shf, src.as_i32x4())) @@ -21727,7 +22478,8 @@ pub fn _mm_mask_sllv_epi32(src: __m128i, k: __mmask8, a: __m128i, count: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvd))] -pub fn _mm_maskz_sllv_epi32(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sllv_epi32(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_sllv_epi32(a, count).as_i32x4(); transmute(simd_select_bitmask(k, shf, i32x4::ZERO)) @@ -21741,7 +22493,8 @@ pub fn _mm_maskz_sllv_epi32(k: __mmask8, a: __m128i, count: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvd))] -pub fn _mm512_srlv_epi32(a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srlv_epi32(a: __m512i, count: __m512i) -> __m512i { unsafe { let count = count.as_u32x16(); let no_overflow: u32x16 = simd_lt(count, u32x16::splat(u32::BITS)); @@ -21757,7 +22510,13 @@ pub fn _mm512_srlv_epi32(a: __m512i, count: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvd))] -pub fn _mm512_mask_srlv_epi32(src: __m512i, k: __mmask16, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srlv_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, + count: __m512i, +) -> __m512i { unsafe { let shf = _mm512_srlv_epi32(a, count).as_i32x16(); transmute(simd_select_bitmask(k, shf, src.as_i32x16())) @@ -21771,7 +22530,8 @@ pub fn _mm512_mask_srlv_epi32(src: __m512i, k: __mmask16, a: __m512i, count: __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvd))] -pub fn _mm512_maskz_srlv_epi32(k: __mmask16, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srlv_epi32(k: __mmask16, a: __m512i, count: __m512i) -> __m512i { unsafe { let shf = _mm512_srlv_epi32(a, count).as_i32x16(); transmute(simd_select_bitmask(k, shf, i32x16::ZERO)) @@ -21785,7 +22545,13 @@ pub fn _mm512_maskz_srlv_epi32(k: __mmask16, a: __m512i, count: __m512i) -> __m5 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvd))] -pub fn _mm256_mask_srlv_epi32(src: __m256i, k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srlv_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, + count: __m256i, +) -> __m256i { unsafe { let shf = _mm256_srlv_epi32(a, count).as_i32x8(); transmute(simd_select_bitmask(k, shf, src.as_i32x8())) @@ -21799,7 +22565,8 @@ pub fn _mm256_mask_srlv_epi32(src: __m256i, k: __mmask8, a: __m256i, count: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvd))] -pub fn _mm256_maskz_srlv_epi32(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srlv_epi32(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { unsafe { let shf = _mm256_srlv_epi32(a, count).as_i32x8(); transmute(simd_select_bitmask(k, shf, i32x8::ZERO)) @@ -21813,7 +22580,8 @@ pub fn _mm256_maskz_srlv_epi32(k: __mmask8, a: __m256i, count: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvd))] -pub fn _mm_mask_srlv_epi32(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srlv_epi32(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srlv_epi32(a, count).as_i32x4(); transmute(simd_select_bitmask(k, shf, src.as_i32x4())) @@ -21827,7 +22595,8 @@ pub fn _mm_mask_srlv_epi32(src: __m128i, k: __mmask8, a: __m128i, count: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvd))] -pub fn _mm_maskz_srlv_epi32(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srlv_epi32(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srlv_epi32(a, count).as_i32x4(); transmute(simd_select_bitmask(k, shf, i32x4::ZERO)) @@ -21841,7 +22610,8 @@ pub fn _mm_maskz_srlv_epi32(k: __mmask8, a: __m128i, count: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvq))] -pub fn _mm512_sllv_epi64(a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sllv_epi64(a: __m512i, count: __m512i) -> __m512i { unsafe { let count = count.as_u64x8(); let no_overflow: u64x8 = simd_lt(count, u64x8::splat(u64::BITS as u64)); @@ -21857,7 +22627,13 @@ pub fn _mm512_sllv_epi64(a: __m512i, count: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvq))] -pub fn _mm512_mask_sllv_epi64(src: __m512i, k: __mmask8, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sllv_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, + count: __m512i, +) -> __m512i { unsafe { let shf = _mm512_sllv_epi64(a, count).as_i64x8(); transmute(simd_select_bitmask(k, shf, src.as_i64x8())) @@ -21871,7 +22647,8 @@ pub fn _mm512_mask_sllv_epi64(src: __m512i, k: __mmask8, a: __m512i, count: __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvq))] -pub fn _mm512_maskz_sllv_epi64(k: __mmask8, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sllv_epi64(k: __mmask8, a: __m512i, count: __m512i) -> __m512i { unsafe { let shf = _mm512_sllv_epi64(a, count).as_i64x8(); transmute(simd_select_bitmask(k, shf, i64x8::ZERO)) @@ -21885,7 +22662,13 @@ pub fn _mm512_maskz_sllv_epi64(k: __mmask8, a: __m512i, count: __m512i) -> __m51 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvq))] -pub fn _mm256_mask_sllv_epi64(src: __m256i, k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sllv_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, + count: __m256i, +) -> __m256i { unsafe { let shf = _mm256_sllv_epi64(a, count).as_i64x4(); transmute(simd_select_bitmask(k, shf, src.as_i64x4())) @@ -21899,7 +22682,8 @@ pub fn _mm256_mask_sllv_epi64(src: __m256i, k: __mmask8, a: __m256i, count: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvq))] -pub fn _mm256_maskz_sllv_epi64(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sllv_epi64(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { unsafe { let shf = _mm256_sllv_epi64(a, count).as_i64x4(); transmute(simd_select_bitmask(k, shf, i64x4::ZERO)) @@ -21913,7 +22697,8 @@ pub fn _mm256_maskz_sllv_epi64(k: __mmask8, a: __m256i, count: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvq))] -pub fn _mm_mask_sllv_epi64(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sllv_epi64(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_sllv_epi64(a, count).as_i64x2(); transmute(simd_select_bitmask(k, shf, src.as_i64x2())) @@ -21927,7 +22712,8 @@ pub fn _mm_mask_sllv_epi64(src: __m128i, k: __mmask8, a: __m128i, count: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvq))] -pub fn _mm_maskz_sllv_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sllv_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_sllv_epi64(a, count).as_i64x2(); transmute(simd_select_bitmask(k, shf, i64x2::ZERO)) @@ -21941,7 +22727,8 @@ pub fn _mm_maskz_sllv_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvq))] -pub fn _mm512_srlv_epi64(a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srlv_epi64(a: __m512i, count: __m512i) -> __m512i { unsafe { let count = count.as_u64x8(); let no_overflow: u64x8 = simd_lt(count, u64x8::splat(u64::BITS as u64)); @@ -21957,7 +22744,13 @@ pub fn _mm512_srlv_epi64(a: __m512i, count: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvq))] -pub fn _mm512_mask_srlv_epi64(src: __m512i, k: __mmask8, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srlv_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, + count: __m512i, +) -> __m512i { unsafe { let shf = _mm512_srlv_epi64(a, count).as_i64x8(); transmute(simd_select_bitmask(k, shf, src.as_i64x8())) @@ -21971,7 +22764,8 @@ pub fn _mm512_mask_srlv_epi64(src: __m512i, k: __mmask8, a: __m512i, count: __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvq))] -pub fn _mm512_maskz_srlv_epi64(k: __mmask8, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srlv_epi64(k: __mmask8, a: __m512i, count: __m512i) -> __m512i { unsafe { let shf = _mm512_srlv_epi64(a, count).as_i64x8(); transmute(simd_select_bitmask(k, shf, i64x8::ZERO)) @@ -21985,7 +22779,13 @@ pub fn _mm512_maskz_srlv_epi64(k: __mmask8, a: __m512i, count: __m512i) -> __m51 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvq))] -pub fn _mm256_mask_srlv_epi64(src: __m256i, k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srlv_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, + count: __m256i, +) -> __m256i { unsafe { let shf = _mm256_srlv_epi64(a, count).as_i64x4(); transmute(simd_select_bitmask(k, shf, src.as_i64x4())) @@ -21999,7 +22799,8 @@ pub fn _mm256_mask_srlv_epi64(src: __m256i, k: __mmask8, a: __m256i, count: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvq))] -pub fn _mm256_maskz_srlv_epi64(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srlv_epi64(k: __mmask8, a: __m256i, count: __m256i) -> __m256i { unsafe { let shf = _mm256_srlv_epi64(a, count).as_i64x4(); transmute(simd_select_bitmask(k, shf, i64x4::ZERO)) @@ -22013,7 +22814,8 @@ pub fn _mm256_maskz_srlv_epi64(k: __mmask8, a: __m256i, count: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvq))] -pub fn _mm_mask_srlv_epi64(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srlv_epi64(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srlv_epi64(a, count).as_i64x2(); transmute(simd_select_bitmask(k, shf, src.as_i64x2())) @@ -22027,7 +22829,8 @@ pub fn _mm_mask_srlv_epi64(src: __m128i, k: __mmask8, a: __m128i, count: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvq))] -pub fn _mm_maskz_srlv_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srlv_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srlv_epi64(a, count).as_i64x2(); transmute(simd_select_bitmask(k, shf, i64x2::ZERO)) @@ -22042,7 +22845,8 @@ pub fn _mm_maskz_srlv_epi64(k: __mmask8, a: __m128i, count: __m128i) -> __m128i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 0b11_00_01_11))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_permute_ps(a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_permute_ps(a: __m512) -> __m512 { unsafe { static_assert_uimm_bits!(MASK, 8); simd_shuffle!( @@ -22078,7 +22882,12 @@ pub fn _mm512_permute_ps(a: __m512) -> __m512 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 0b11_00_01_11))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_permute_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_permute_ps( + src: __m512, + k: __mmask16, + a: __m512, +) -> __m512 { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_permute_ps::(a); @@ -22094,7 +22903,8 @@ pub fn _mm512_mask_permute_ps(src: __m512, k: __mmask16, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 0b11_00_01_11))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_permute_ps(k: __mmask16, a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_permute_ps(k: __mmask16, a: __m512) -> __m512 { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_permute_ps::(a); @@ -22110,7 +22920,12 @@ pub fn _mm512_maskz_permute_ps(k: __mmask16, a: __m512) -> __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 0b11_00_01_11))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_permute_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_permute_ps( + src: __m256, + k: __mmask8, + a: __m256, +) -> __m256 { unsafe { let r = _mm256_permute_ps::(a); transmute(simd_select_bitmask(k, r.as_f32x8(), src.as_f32x8())) @@ -22125,7 +22940,8 @@ pub fn _mm256_mask_permute_ps(src: __m256, k: __mmask8, a: __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 0b11_00_01_11))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_permute_ps(k: __mmask8, a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_permute_ps(k: __mmask8, a: __m256) -> __m256 { unsafe { let r = _mm256_permute_ps::(a); transmute(simd_select_bitmask(k, r.as_f32x8(), f32x8::ZERO)) @@ -22140,7 +22956,8 @@ pub fn _mm256_maskz_permute_ps(k: __mmask8, a: __m256) -> __m25 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 0b11_00_01_11))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_permute_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_permute_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { unsafe { let r = _mm_permute_ps::(a); transmute(simd_select_bitmask(k, r.as_f32x4(), src.as_f32x4())) @@ -22155,7 +22972,8 @@ pub fn _mm_mask_permute_ps(src: __m128, k: __mmask8, a: __m128) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 0b11_00_01_11))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_permute_ps(k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_permute_ps(k: __mmask8, a: __m128) -> __m128 { unsafe { let r = _mm_permute_ps::(a); transmute(simd_select_bitmask(k, r.as_f32x4(), f32x4::ZERO)) @@ -22170,7 +22988,8 @@ pub fn _mm_maskz_permute_ps(k: __mmask8, a: __m128) -> __m128 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 0b11_01_10_01))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_permute_pd(a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_permute_pd(a: __m512d) -> __m512d { unsafe { static_assert_uimm_bits!(MASK, 8); simd_shuffle!( @@ -22198,7 +23017,12 @@ pub fn _mm512_permute_pd(a: __m512d) -> __m512d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 0b11_01_10_01))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_permute_pd(src: __m512d, k: __mmask8, a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_permute_pd( + src: __m512d, + k: __mmask8, + a: __m512d, +) -> __m512d { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_permute_pd::(a); @@ -22214,7 +23038,8 @@ pub fn _mm512_mask_permute_pd(src: __m512d, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 0b11_01_10_01))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_permute_pd(k: __mmask8, a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_permute_pd(k: __mmask8, a: __m512d) -> __m512d { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_permute_pd::(a); @@ -22230,7 +23055,12 @@ pub fn _mm512_maskz_permute_pd(k: __mmask8, a: __m512d) -> __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 0b11_01))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_permute_pd(src: __m256d, k: __mmask8, a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_permute_pd( + src: __m256d, + k: __mmask8, + a: __m256d, +) -> __m256d { unsafe { static_assert_uimm_bits!(MASK, 4); let r = _mm256_permute_pd::(a); @@ -22246,7 +23076,8 @@ pub fn _mm256_mask_permute_pd(src: __m256d, k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 0b11_01))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_permute_pd(k: __mmask8, a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_permute_pd(k: __mmask8, a: __m256d) -> __m256d { unsafe { static_assert_uimm_bits!(MASK, 4); let r = _mm256_permute_pd::(a); @@ -22262,7 +23093,12 @@ pub fn _mm256_maskz_permute_pd(k: __mmask8, a: __m256d) -> __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, IMM2 = 0b01))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_permute_pd(src: __m128d, k: __mmask8, a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_permute_pd( + src: __m128d, + k: __mmask8, + a: __m128d, +) -> __m128d { unsafe { static_assert_uimm_bits!(IMM2, 2); let r = _mm_permute_pd::(a); @@ -22278,7 +23114,8 @@ pub fn _mm_mask_permute_pd(src: __m128d, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, IMM2 = 0b01))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_permute_pd(k: __mmask8, a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_permute_pd(k: __mmask8, a: __m128d) -> __m128d { unsafe { static_assert_uimm_bits!(IMM2, 2); let r = _mm_permute_pd::(a); @@ -22294,7 +23131,8 @@ pub fn _mm_maskz_permute_pd(k: __mmask8, a: __m128d) -> __m128d #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermq #[rustc_legacy_const_generics(1)] -pub fn _mm512_permutex_epi64(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_permutex_epi64(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(MASK, 8); simd_shuffle!( @@ -22322,7 +23160,8 @@ pub fn _mm512_permutex_epi64(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermq #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_permutex_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_permutex_epi64( src: __m512i, k: __mmask8, a: __m512i, @@ -22342,7 +23181,8 @@ pub fn _mm512_mask_permutex_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermq #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_permutex_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_permutex_epi64(k: __mmask8, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_permutex_epi64::(a); @@ -22358,7 +23198,8 @@ pub fn _mm512_maskz_permutex_epi64(k: __mmask8, a: __m512i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermq #[rustc_legacy_const_generics(1)] -pub fn _mm256_permutex_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permutex_epi64(a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(MASK, 8); simd_shuffle!( @@ -22382,7 +23223,8 @@ pub fn _mm256_permutex_epi64(a: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermq #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_permutex_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_permutex_epi64( src: __m256i, k: __mmask8, a: __m256i, @@ -22402,7 +23244,8 @@ pub fn _mm256_mask_permutex_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermq #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_permutex_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_permutex_epi64(k: __mmask8, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_permutex_epi64::(a); @@ -22418,7 +23261,8 @@ pub fn _mm256_maskz_permutex_epi64(k: __mmask8, a: __m256i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermpd #[rustc_legacy_const_generics(1)] -pub fn _mm512_permutex_pd(a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_permutex_pd(a: __m512d) -> __m512d { unsafe { static_assert_uimm_bits!(MASK, 8); simd_shuffle!( @@ -22446,7 +23290,12 @@ pub fn _mm512_permutex_pd(a: __m512d) -> __m512d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermpd #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_permutex_pd(src: __m512d, k: __mmask8, a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_permutex_pd( + src: __m512d, + k: __mmask8, + a: __m512d, +) -> __m512d { unsafe { let r = _mm512_permutex_pd::(a); transmute(simd_select_bitmask(k, r.as_f64x8(), src.as_f64x8())) @@ -22461,7 +23310,8 @@ pub fn _mm512_mask_permutex_pd(src: __m512d, k: __mmask8, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermpd #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_permutex_pd(k: __mmask8, a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_permutex_pd(k: __mmask8, a: __m512d) -> __m512d { unsafe { let r = _mm512_permutex_pd::(a); transmute(simd_select_bitmask(k, r.as_f64x8(), f64x8::ZERO)) @@ -22476,7 +23326,8 @@ pub fn _mm512_maskz_permutex_pd(k: __mmask8, a: __m512d) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermpd #[rustc_legacy_const_generics(1)] -pub fn _mm256_permutex_pd(a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_permutex_pd(a: __m256d) -> __m256d { unsafe { static_assert_uimm_bits!(MASK, 8); simd_shuffle!( @@ -22500,7 +23351,12 @@ pub fn _mm256_permutex_pd(a: __m256d) -> __m256d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermpd #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_permutex_pd(src: __m256d, k: __mmask8, a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_permutex_pd( + src: __m256d, + k: __mmask8, + a: __m256d, +) -> __m256d { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_permutex_pd::(a); @@ -22516,7 +23372,8 @@ pub fn _mm256_mask_permutex_pd(src: __m256d, k: __mmask8, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b10_01_10_11))] //should be vpermpd #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_permutex_pd(k: __mmask8, a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_permutex_pd(k: __mmask8, a: __m256d) -> __m256d { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_permutex_pd::(a); @@ -23786,7 +24643,8 @@ pub fn _mm_mask2_permutex2var_pd(a: __m128d, idx: __m128i, k: __mmask8, b: __m12 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 9))] //should be vpshufd #[rustc_legacy_const_generics(1)] -pub fn _mm512_shuffle_epi32(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shuffle_epi32(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(MASK, 8); let r: i32x16 = simd_shuffle!( @@ -23823,7 +24681,8 @@ pub fn _mm512_shuffle_epi32(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufd, MASK = 9))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_shuffle_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shuffle_epi32( src: __m512i, k: __mmask16, a: __m512i, @@ -23843,7 +24702,11 @@ pub fn _mm512_mask_shuffle_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufd, MASK = 9))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_shuffle_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shuffle_epi32( + k: __mmask16, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_shuffle_epi32::(a); @@ -23859,7 +24722,8 @@ pub fn _mm512_maskz_shuffle_epi32(k: __mmask16, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufd, MASK = 9))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_shuffle_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shuffle_epi32( src: __m256i, k: __mmask8, a: __m256i, @@ -23879,7 +24743,11 @@ pub fn _mm256_mask_shuffle_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufd, MASK = 9))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_shuffle_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shuffle_epi32( + k: __mmask8, + a: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_shuffle_epi32::(a); @@ -23895,7 +24763,8 @@ pub fn _mm256_maskz_shuffle_epi32(k: __mmask8, a: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufd, MASK = 9))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_shuffle_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shuffle_epi32( src: __m128i, k: __mmask8, a: __m128i, @@ -23915,7 +24784,11 @@ pub fn _mm_mask_shuffle_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufd, MASK = 9))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_shuffle_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shuffle_epi32( + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm_shuffle_epi32::(a); @@ -23931,7 +24804,8 @@ pub fn _mm_maskz_shuffle_epi32(k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 3))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_shuffle_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shuffle_ps(a: __m512, b: __m512) -> __m512 { unsafe { static_assert_uimm_bits!(MASK, 8); simd_shuffle!( @@ -23967,7 +24841,8 @@ pub fn _mm512_shuffle_ps(a: __m512, b: __m512) -> __m512 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 3))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shuffle_ps( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shuffle_ps( src: __m512, k: __mmask16, a: __m512, @@ -23988,7 +24863,12 @@ pub fn _mm512_mask_shuffle_ps( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 3))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shuffle_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shuffle_ps( + k: __mmask16, + a: __m512, + b: __m512, +) -> __m512 { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_shuffle_ps::(a, b); @@ -24004,7 +24884,8 @@ pub fn _mm512_maskz_shuffle_ps(k: __mmask16, a: __m512, b: __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 3))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shuffle_ps( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shuffle_ps( src: __m256, k: __mmask8, a: __m256, @@ -24025,7 +24906,8 @@ pub fn _mm256_mask_shuffle_ps( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 3))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shuffle_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shuffle_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_shuffle_ps::(a, b); @@ -24041,7 +24923,8 @@ pub fn _mm256_maskz_shuffle_ps(k: __mmask8, a: __m256, b: __m25 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 3))] #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_shuffle_ps( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shuffle_ps( src: __m128, k: __mmask8, a: __m128, @@ -24062,7 +24945,8 @@ pub fn _mm_mask_shuffle_ps( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufps, MASK = 3))] #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_shuffle_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shuffle_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm_shuffle_ps::(a, b); @@ -24078,7 +24962,8 @@ pub fn _mm_maskz_shuffle_ps(k: __mmask8, a: __m128, b: __m128) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 3))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_shuffle_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shuffle_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { static_assert_uimm_bits!(MASK, 8); simd_shuffle!( @@ -24106,7 +24991,8 @@ pub fn _mm512_shuffle_pd(a: __m512d, b: __m512d) -> __m512d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 3))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shuffle_pd( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shuffle_pd( src: __m512d, k: __mmask8, a: __m512d, @@ -24127,7 +25013,12 @@ pub fn _mm512_mask_shuffle_pd( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 3))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shuffle_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shuffle_pd( + k: __mmask8, + a: __m512d, + b: __m512d, +) -> __m512d { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_shuffle_pd::(a, b); @@ -24143,7 +25034,8 @@ pub fn _mm512_maskz_shuffle_pd(k: __mmask8, a: __m512d, b: __m5 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 3))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shuffle_pd( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shuffle_pd( src: __m256d, k: __mmask8, a: __m256d, @@ -24164,7 +25056,12 @@ pub fn _mm256_mask_shuffle_pd( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 3))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shuffle_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shuffle_pd( + k: __mmask8, + a: __m256d, + b: __m256d, +) -> __m256d { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_shuffle_pd::(a, b); @@ -24180,7 +25077,8 @@ pub fn _mm256_maskz_shuffle_pd(k: __mmask8, a: __m256d, b: __m2 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_shuffle_pd( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shuffle_pd( src: __m128d, k: __mmask8, a: __m128d, @@ -24201,7 +25099,8 @@ pub fn _mm_mask_shuffle_pd( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufpd, MASK = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_shuffle_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shuffle_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm_shuffle_pd::(a, b); @@ -24217,7 +25116,8 @@ pub fn _mm_maskz_shuffle_pd(k: __mmask8, a: __m128d, b: __m128d #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi64x2, MASK = 0b10_01_01_01))] //should be vshufi32x4 #[rustc_legacy_const_generics(2)] -pub fn _mm512_shuffle_i32x4(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shuffle_i32x4(a: __m512i, b: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(MASK, 8); let a = a.as_i32x16(); @@ -24256,7 +25156,8 @@ pub fn _mm512_shuffle_i32x4(a: __m512i, b: __m512i) -> __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi32x4, MASK = 0b10_11_01_01))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shuffle_i32x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shuffle_i32x4( src: __m512i, k: __mmask16, a: __m512i, @@ -24277,7 +25178,8 @@ pub fn _mm512_mask_shuffle_i32x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi32x4, MASK = 0b10_11_01_01))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shuffle_i32x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shuffle_i32x4( k: __mmask16, a: __m512i, b: __m512i, @@ -24297,7 +25199,8 @@ pub fn _mm512_maskz_shuffle_i32x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b11))] //should be vshufi32x4 #[rustc_legacy_const_generics(2)] -pub fn _mm256_shuffle_i32x4(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shuffle_i32x4(a: __m256i, b: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(MASK, 8); let a = a.as_i32x8(); @@ -24328,7 +25231,8 @@ pub fn _mm256_shuffle_i32x4(a: __m256i, b: __m256i) -> __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi32x4, MASK = 0b11))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shuffle_i32x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shuffle_i32x4( src: __m256i, k: __mmask8, a: __m256i, @@ -24349,7 +25253,12 @@ pub fn _mm256_mask_shuffle_i32x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi32x4, MASK = 0b11))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shuffle_i32x4(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shuffle_i32x4( + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_shuffle_i32x4::(a, b); @@ -24365,7 +25274,8 @@ pub fn _mm256_maskz_shuffle_i32x4(k: __mmask8, a: __m256i, b: _ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi64x2, MASK = 0b10_11_11_11))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_shuffle_i64x2(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shuffle_i64x2(a: __m512i, b: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(MASK, 8); let a = a.as_i64x8(); @@ -24396,7 +25306,8 @@ pub fn _mm512_shuffle_i64x2(a: __m512i, b: __m512i) -> __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi64x2, MASK = 0b10_11_11_11))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shuffle_i64x2( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shuffle_i64x2( src: __m512i, k: __mmask8, a: __m512i, @@ -24417,7 +25328,12 @@ pub fn _mm512_mask_shuffle_i64x2( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi64x2, MASK = 0b10_11_11_11))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shuffle_i64x2(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shuffle_i64x2( + k: __mmask8, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_shuffle_i64x2::(a, b); @@ -24433,7 +25349,8 @@ pub fn _mm512_maskz_shuffle_i64x2(k: __mmask8, a: __m512i, b: _ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b01))] //should be vshufi64x2 #[rustc_legacy_const_generics(2)] -pub fn _mm256_shuffle_i64x2(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shuffle_i64x2(a: __m256i, b: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(MASK, 8); let a = a.as_i64x4(); @@ -24460,7 +25377,8 @@ pub fn _mm256_shuffle_i64x2(a: __m256i, b: __m256i) -> __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi64x2, MASK = 0b11))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shuffle_i64x2( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shuffle_i64x2( src: __m256i, k: __mmask8, a: __m256i, @@ -24481,7 +25399,12 @@ pub fn _mm256_mask_shuffle_i64x2( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshufi64x2, MASK = 0b11))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shuffle_i64x2(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shuffle_i64x2( + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_shuffle_i64x2::(a, b); @@ -24497,7 +25420,8 @@ pub fn _mm256_maskz_shuffle_i64x2(k: __mmask8, a: __m256i, b: _ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff64x2, MASK = 0b1011))] //should be vshuff32x4, but generate vshuff64x2 #[rustc_legacy_const_generics(2)] -pub fn _mm512_shuffle_f32x4(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shuffle_f32x4(a: __m512, b: __m512) -> __m512 { unsafe { static_assert_uimm_bits!(MASK, 8); let a = a.as_f32x16(); @@ -24536,7 +25460,8 @@ pub fn _mm512_shuffle_f32x4(a: __m512, b: __m512) -> __m512 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff32x4, MASK = 0b1011))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shuffle_f32x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shuffle_f32x4( src: __m512, k: __mmask16, a: __m512, @@ -24557,7 +25482,12 @@ pub fn _mm512_mask_shuffle_f32x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff32x4, MASK = 0b1011))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shuffle_f32x4(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shuffle_f32x4( + k: __mmask16, + a: __m512, + b: __m512, +) -> __m512 { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_shuffle_f32x4::(a, b); @@ -24573,7 +25503,8 @@ pub fn _mm512_maskz_shuffle_f32x4(k: __mmask16, a: __m512, b: _ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b01))] //should be vshuff32x4 #[rustc_legacy_const_generics(2)] -pub fn _mm256_shuffle_f32x4(a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shuffle_f32x4(a: __m256, b: __m256) -> __m256 { unsafe { static_assert_uimm_bits!(MASK, 8); let a = a.as_f32x8(); @@ -24604,7 +25535,8 @@ pub fn _mm256_shuffle_f32x4(a: __m256, b: __m256) -> __m256 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff32x4, MASK = 0b11))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shuffle_f32x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shuffle_f32x4( src: __m256, k: __mmask8, a: __m256, @@ -24625,7 +25557,12 @@ pub fn _mm256_mask_shuffle_f32x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff32x4, MASK = 0b11))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shuffle_f32x4(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shuffle_f32x4( + k: __mmask8, + a: __m256, + b: __m256, +) -> __m256 { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_shuffle_f32x4::(a, b); @@ -24641,7 +25578,8 @@ pub fn _mm256_maskz_shuffle_f32x4(k: __mmask8, a: __m256, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff64x2, MASK = 0b10_11_11_11))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_shuffle_f64x2(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shuffle_f64x2(a: __m512d, b: __m512d) -> __m512d { unsafe { static_assert_uimm_bits!(MASK, 8); let a = a.as_f64x8(); @@ -24672,7 +25610,8 @@ pub fn _mm512_shuffle_f64x2(a: __m512d, b: __m512d) -> __m512d #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff64x2, MASK = 0b10_11_11_11))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shuffle_f64x2( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shuffle_f64x2( src: __m512d, k: __mmask8, a: __m512d, @@ -24693,7 +25632,12 @@ pub fn _mm512_mask_shuffle_f64x2( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff64x2, MASK = 0b10_11_11_11))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shuffle_f64x2(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shuffle_f64x2( + k: __mmask8, + a: __m512d, + b: __m512d, +) -> __m512d { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm512_shuffle_f64x2::(a, b); @@ -24709,7 +25653,8 @@ pub fn _mm512_maskz_shuffle_f64x2(k: __mmask8, a: __m512d, b: _ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vperm, MASK = 0b01))] //should be vshuff64x2 #[rustc_legacy_const_generics(2)] -pub fn _mm256_shuffle_f64x2(a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shuffle_f64x2(a: __m256d, b: __m256d) -> __m256d { unsafe { static_assert_uimm_bits!(MASK, 8); let a = a.as_f64x4(); @@ -24736,7 +25681,8 @@ pub fn _mm256_shuffle_f64x2(a: __m256d, b: __m256d) -> __m256d #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff64x2, MASK = 0b11))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shuffle_f64x2( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shuffle_f64x2( src: __m256d, k: __mmask8, a: __m256d, @@ -24757,7 +25703,12 @@ pub fn _mm256_mask_shuffle_f64x2( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vshuff64x2, MASK = 0b11))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shuffle_f64x2(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shuffle_f64x2( + k: __mmask8, + a: __m256d, + b: __m256d, +) -> __m256d { unsafe { static_assert_uimm_bits!(MASK, 8); let r = _mm256_shuffle_f64x2::(a, b); @@ -24773,7 +25724,8 @@ pub fn _mm256_maskz_shuffle_f64x2(k: __mmask8, a: __m256d, b: _ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextractf32x4, IMM8 = 3))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_extractf32x4_ps(a: __m512) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_extractf32x4_ps(a: __m512) -> __m128 { unsafe { static_assert_uimm_bits!(IMM8, 2); match IMM8 & 0x3 { @@ -24793,7 +25745,12 @@ pub fn _mm512_extractf32x4_ps(a: __m512) -> __m128 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextractf32x4, IMM8 = 3))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_extractf32x4_ps(src: __m128, k: __mmask8, a: __m512) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_extractf32x4_ps( + src: __m128, + k: __mmask8, + a: __m512, +) -> __m128 { unsafe { static_assert_uimm_bits!(IMM8, 2); let r = _mm512_extractf32x4_ps::(a); @@ -24809,7 +25766,8 @@ pub fn _mm512_mask_extractf32x4_ps(src: __m128, k: __mmask8, a: #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextractf32x4, IMM8 = 3))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_extractf32x4_ps(k: __mmask8, a: __m512) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_extractf32x4_ps(k: __mmask8, a: __m512) -> __m128 { unsafe { static_assert_uimm_bits!(IMM8, 2); let r = _mm512_extractf32x4_ps::(a); @@ -24828,7 +25786,8 @@ pub fn _mm512_maskz_extractf32x4_ps(k: __mmask8, a: __m512) -> assert_instr(vextract, IMM8 = 1) //should be vextractf32x4 )] #[rustc_legacy_const_generics(1)] -pub fn _mm256_extractf32x4_ps(a: __m256) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extractf32x4_ps(a: __m256) -> __m128 { unsafe { static_assert_uimm_bits!(IMM8, 1); match IMM8 & 0x1 { @@ -24846,7 +25805,12 @@ pub fn _mm256_extractf32x4_ps(a: __m256) -> __m128 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextractf32x4, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_extractf32x4_ps(src: __m128, k: __mmask8, a: __m256) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_extractf32x4_ps( + src: __m128, + k: __mmask8, + a: __m256, +) -> __m128 { unsafe { static_assert_uimm_bits!(IMM8, 1); let r = _mm256_extractf32x4_ps::(a); @@ -24862,7 +25826,8 @@ pub fn _mm256_mask_extractf32x4_ps(src: __m128, k: __mmask8, a: #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextractf32x4, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_extractf32x4_ps(k: __mmask8, a: __m256) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_extractf32x4_ps(k: __mmask8, a: __m256) -> __m128 { unsafe { static_assert_uimm_bits!(IMM8, 1); let r = _mm256_extractf32x4_ps::(a); @@ -24881,7 +25846,8 @@ pub fn _mm256_maskz_extractf32x4_ps(k: __mmask8, a: __m256) -> assert_instr(vextractf64x4, IMM1 = 1) //should be vextracti64x4 )] #[rustc_legacy_const_generics(1)] -pub fn _mm512_extracti64x4_epi64(a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_extracti64x4_epi64(a: __m512i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM1, 1); match IMM1 { @@ -24899,7 +25865,8 @@ pub fn _mm512_extracti64x4_epi64(a: __m512i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextracti64x4, IMM1 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_extracti64x4_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_extracti64x4_epi64( src: __m256i, k: __mmask8, a: __m512i, @@ -24919,7 +25886,8 @@ pub fn _mm512_mask_extracti64x4_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextracti64x4, IMM1 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_extracti64x4_epi64(k: __mmask8, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_extracti64x4_epi64(k: __mmask8, a: __m512i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM1, 1); let r = _mm512_extracti64x4_epi64::(a); @@ -24935,7 +25903,8 @@ pub fn _mm512_maskz_extracti64x4_epi64(k: __mmask8, a: __m512i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextractf64x4, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_extractf64x4_pd(a: __m512d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_extractf64x4_pd(a: __m512d) -> __m256d { unsafe { static_assert_uimm_bits!(IMM8, 1); match IMM8 & 0x1 { @@ -24953,7 +25922,8 @@ pub fn _mm512_extractf64x4_pd(a: __m512d) -> __m256d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextractf64x4, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_extractf64x4_pd( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_extractf64x4_pd( src: __m256d, k: __mmask8, a: __m512d, @@ -24973,7 +25943,8 @@ pub fn _mm512_mask_extractf64x4_pd( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextractf64x4, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_extractf64x4_pd(k: __mmask8, a: __m512d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_extractf64x4_pd(k: __mmask8, a: __m512d) -> __m256d { unsafe { static_assert_uimm_bits!(IMM8, 1); let r = _mm512_extractf64x4_pd::(a); @@ -24992,7 +25963,8 @@ pub fn _mm512_maskz_extractf64x4_pd(k: __mmask8, a: __m512d) -> assert_instr(vextractf32x4, IMM2 = 3) //should be vextracti32x4 )] #[rustc_legacy_const_generics(1)] -pub fn _mm512_extracti32x4_epi32(a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_extracti32x4_epi32(a: __m512i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM2, 2); let a = a.as_i32x16(); @@ -25015,7 +25987,8 @@ pub fn _mm512_extracti32x4_epi32(a: __m512i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextracti32x4, IMM2 = 3))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_extracti32x4_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_extracti32x4_epi32( src: __m128i, k: __mmask8, a: __m512i, @@ -25035,7 +26008,8 @@ pub fn _mm512_mask_extracti32x4_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextracti32x4, IMM2 = 3))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_extracti32x4_epi32(k: __mmask8, a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_extracti32x4_epi32(k: __mmask8, a: __m512i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM2, 2); let r = _mm512_extracti32x4_epi32::(a); @@ -25054,7 +26028,8 @@ pub fn _mm512_maskz_extracti32x4_epi32(k: __mmask8, a: __m512i) assert_instr(vextract, IMM1 = 1) //should be vextracti32x4 )] #[rustc_legacy_const_generics(1)] -pub fn _mm256_extracti32x4_epi32(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extracti32x4_epi32(a: __m256i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM1, 1); let a = a.as_i32x8(); @@ -25075,7 +26050,8 @@ pub fn _mm256_extracti32x4_epi32(a: __m256i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextracti32x4, IMM1 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_extracti32x4_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_extracti32x4_epi32( src: __m128i, k: __mmask8, a: __m256i, @@ -25095,7 +26071,8 @@ pub fn _mm256_mask_extracti32x4_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vextracti32x4, IMM1 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_extracti32x4_epi32(k: __mmask8, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_extracti32x4_epi32(k: __mmask8, a: __m256i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM1, 1); let r = _mm256_extracti32x4_epi32::(a); @@ -25110,7 +26087,8 @@ pub fn _mm256_maskz_extracti32x4_epi32(k: __mmask8, a: __m256i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovsldup))] -pub fn _mm512_moveldup_ps(a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_moveldup_ps(a: __m512) -> __m512 { unsafe { let r: f32x16 = simd_shuffle!(a, a, [0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14]); transmute(r) @@ -25124,7 +26102,8 @@ pub fn _mm512_moveldup_ps(a: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovsldup))] -pub fn _mm512_mask_moveldup_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_moveldup_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { unsafe { let mov: f32x16 = simd_shuffle!(a, a, [0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14]); @@ -25139,7 +26118,8 @@ pub fn _mm512_mask_moveldup_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovsldup))] -pub fn _mm512_maskz_moveldup_ps(k: __mmask16, a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_moveldup_ps(k: __mmask16, a: __m512) -> __m512 { unsafe { let mov: f32x16 = simd_shuffle!(a, a, [0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14]); @@ -25154,7 +26134,8 @@ pub fn _mm512_maskz_moveldup_ps(k: __mmask16, a: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovsldup))] -pub fn _mm256_mask_moveldup_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_moveldup_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { unsafe { let mov = _mm256_moveldup_ps(a); transmute(simd_select_bitmask(k, mov.as_f32x8(), src.as_f32x8())) @@ -25168,7 +26149,8 @@ pub fn _mm256_mask_moveldup_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovsldup))] -pub fn _mm256_maskz_moveldup_ps(k: __mmask8, a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_moveldup_ps(k: __mmask8, a: __m256) -> __m256 { unsafe { let mov = _mm256_moveldup_ps(a); transmute(simd_select_bitmask(k, mov.as_f32x8(), f32x8::ZERO)) @@ -25182,7 +26164,8 @@ pub fn _mm256_maskz_moveldup_ps(k: __mmask8, a: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovsldup))] -pub fn _mm_mask_moveldup_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_moveldup_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { unsafe { let mov = _mm_moveldup_ps(a); transmute(simd_select_bitmask(k, mov.as_f32x4(), src.as_f32x4())) @@ -25196,7 +26179,8 @@ pub fn _mm_mask_moveldup_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovsldup))] -pub fn _mm_maskz_moveldup_ps(k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_moveldup_ps(k: __mmask8, a: __m128) -> __m128 { unsafe { let mov = _mm_moveldup_ps(a); transmute(simd_select_bitmask(k, mov.as_f32x4(), f32x4::ZERO)) @@ -25210,7 +26194,8 @@ pub fn _mm_maskz_moveldup_ps(k: __mmask8, a: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovshdup))] -pub fn _mm512_movehdup_ps(a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movehdup_ps(a: __m512) -> __m512 { unsafe { let r: f32x16 = simd_shuffle!(a, a, [1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15]); transmute(r) @@ -25224,7 +26209,8 @@ pub fn _mm512_movehdup_ps(a: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovshdup))] -pub fn _mm512_mask_movehdup_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_movehdup_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { unsafe { let mov: f32x16 = simd_shuffle!(a, a, [1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15]); @@ -25239,7 +26225,8 @@ pub fn _mm512_mask_movehdup_ps(src: __m512, k: __mmask16, a: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovshdup))] -pub fn _mm512_maskz_movehdup_ps(k: __mmask16, a: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_movehdup_ps(k: __mmask16, a: __m512) -> __m512 { unsafe { let mov: f32x16 = simd_shuffle!(a, a, [1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15]); @@ -25254,7 +26241,8 @@ pub fn _mm512_maskz_movehdup_ps(k: __mmask16, a: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovshdup))] -pub fn _mm256_mask_movehdup_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_movehdup_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { unsafe { let mov = _mm256_movehdup_ps(a); transmute(simd_select_bitmask(k, mov.as_f32x8(), src.as_f32x8())) @@ -25268,7 +26256,8 @@ pub fn _mm256_mask_movehdup_ps(src: __m256, k: __mmask8, a: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovshdup))] -pub fn _mm256_maskz_movehdup_ps(k: __mmask8, a: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_movehdup_ps(k: __mmask8, a: __m256) -> __m256 { unsafe { let mov = _mm256_movehdup_ps(a); transmute(simd_select_bitmask(k, mov.as_f32x8(), f32x8::ZERO)) @@ -25282,7 +26271,8 @@ pub fn _mm256_maskz_movehdup_ps(k: __mmask8, a: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovshdup))] -pub fn _mm_mask_movehdup_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_movehdup_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { unsafe { let mov = _mm_movehdup_ps(a); transmute(simd_select_bitmask(k, mov.as_f32x4(), src.as_f32x4())) @@ -25296,7 +26286,8 @@ pub fn _mm_mask_movehdup_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovshdup))] -pub fn _mm_maskz_movehdup_ps(k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_movehdup_ps(k: __mmask8, a: __m128) -> __m128 { unsafe { let mov = _mm_movehdup_ps(a); transmute(simd_select_bitmask(k, mov.as_f32x4(), f32x4::ZERO)) @@ -25310,7 +26301,8 @@ pub fn _mm_maskz_movehdup_ps(k: __mmask8, a: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovddup))] -pub fn _mm512_movedup_pd(a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movedup_pd(a: __m512d) -> __m512d { unsafe { let r: f64x8 = simd_shuffle!(a, a, [0, 0, 2, 2, 4, 4, 6, 6]); transmute(r) @@ -25324,7 +26316,8 @@ pub fn _mm512_movedup_pd(a: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovddup))] -pub fn _mm512_mask_movedup_pd(src: __m512d, k: __mmask8, a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_movedup_pd(src: __m512d, k: __mmask8, a: __m512d) -> __m512d { unsafe { let mov: f64x8 = simd_shuffle!(a, a, [0, 0, 2, 2, 4, 4, 6, 6]); transmute(simd_select_bitmask(k, mov, src.as_f64x8())) @@ -25338,7 +26331,8 @@ pub fn _mm512_mask_movedup_pd(src: __m512d, k: __mmask8, a: __m512d) -> __m512d #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovddup))] -pub fn _mm512_maskz_movedup_pd(k: __mmask8, a: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_movedup_pd(k: __mmask8, a: __m512d) -> __m512d { unsafe { let mov: f64x8 = simd_shuffle!(a, a, [0, 0, 2, 2, 4, 4, 6, 6]); transmute(simd_select_bitmask(k, mov, f64x8::ZERO)) @@ -25352,7 +26346,8 @@ pub fn _mm512_maskz_movedup_pd(k: __mmask8, a: __m512d) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovddup))] -pub fn _mm256_mask_movedup_pd(src: __m256d, k: __mmask8, a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_movedup_pd(src: __m256d, k: __mmask8, a: __m256d) -> __m256d { unsafe { let mov = _mm256_movedup_pd(a); transmute(simd_select_bitmask(k, mov.as_f64x4(), src.as_f64x4())) @@ -25366,7 +26361,8 @@ pub fn _mm256_mask_movedup_pd(src: __m256d, k: __mmask8, a: __m256d) -> __m256d #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovddup))] -pub fn _mm256_maskz_movedup_pd(k: __mmask8, a: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_movedup_pd(k: __mmask8, a: __m256d) -> __m256d { unsafe { let mov = _mm256_movedup_pd(a); transmute(simd_select_bitmask(k, mov.as_f64x4(), f64x4::ZERO)) @@ -25380,7 +26376,8 @@ pub fn _mm256_maskz_movedup_pd(k: __mmask8, a: __m256d) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovddup))] -pub fn _mm_mask_movedup_pd(src: __m128d, k: __mmask8, a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_movedup_pd(src: __m128d, k: __mmask8, a: __m128d) -> __m128d { unsafe { let mov = _mm_movedup_pd(a); transmute(simd_select_bitmask(k, mov.as_f64x2(), src.as_f64x2())) @@ -25394,7 +26391,8 @@ pub fn _mm_mask_movedup_pd(src: __m128d, k: __mmask8, a: __m128d) -> __m128d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovddup))] -pub fn _mm_maskz_movedup_pd(k: __mmask8, a: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_movedup_pd(k: __mmask8, a: __m128d) -> __m128d { unsafe { let mov = _mm_movedup_pd(a); transmute(simd_select_bitmask(k, mov.as_f64x2(), f64x2::ZERO)) @@ -25409,7 +26407,8 @@ pub fn _mm_maskz_movedup_pd(k: __mmask8, a: __m128d) -> __m128d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf32x4, IMM8 = 2))] //should be vinserti32x4 #[rustc_legacy_const_generics(2)] -pub fn _mm512_inserti32x4(a: __m512i, b: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_inserti32x4(a: __m512i, b: __m128i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 2); let a = a.as_i32x16(); @@ -25452,7 +26451,8 @@ pub fn _mm512_inserti32x4(a: __m512i, b: __m128i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinserti32x4, IMM8 = 2))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_inserti32x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_inserti32x4( src: __m512i, k: __mmask16, a: __m512i, @@ -25473,7 +26473,12 @@ pub fn _mm512_mask_inserti32x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinserti32x4, IMM8 = 2))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_inserti32x4(k: __mmask16, a: __m512i, b: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_inserti32x4( + k: __mmask16, + a: __m512i, + b: __m128i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 2); let r = _mm512_inserti32x4::(a, b); @@ -25492,7 +26497,8 @@ pub fn _mm512_maskz_inserti32x4(k: __mmask16, a: __m512i, b: __ assert_instr(vinsert, IMM8 = 1) //should be vinserti32x4 )] #[rustc_legacy_const_generics(2)] -pub fn _mm256_inserti32x4(a: __m256i, b: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_inserti32x4(a: __m256i, b: __m128i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 1); let a = a.as_i32x8(); @@ -25513,7 +26519,8 @@ pub fn _mm256_inserti32x4(a: __m256i, b: __m128i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinserti32x4, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_inserti32x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_inserti32x4( src: __m256i, k: __mmask8, a: __m256i, @@ -25534,7 +26541,12 @@ pub fn _mm256_mask_inserti32x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinserti32x4, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_inserti32x4(k: __mmask8, a: __m256i, b: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_inserti32x4( + k: __mmask8, + a: __m256i, + b: __m128i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 1); let r = _mm256_inserti32x4::(a, b); @@ -25550,7 +26562,8 @@ pub fn _mm256_maskz_inserti32x4(k: __mmask8, a: __m256i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf64x4, IMM8 = 1))] //should be vinserti64x4 #[rustc_legacy_const_generics(2)] -pub fn _mm512_inserti64x4(a: __m512i, b: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_inserti64x4(a: __m512i, b: __m256i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm512_castsi256_si512(b); @@ -25569,7 +26582,8 @@ pub fn _mm512_inserti64x4(a: __m512i, b: __m256i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinserti64x4, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_inserti64x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_inserti64x4( src: __m512i, k: __mmask8, a: __m512i, @@ -25590,7 +26604,12 @@ pub fn _mm512_mask_inserti64x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinserti64x4, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_inserti64x4(k: __mmask8, a: __m512i, b: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_inserti64x4( + k: __mmask8, + a: __m512i, + b: __m256i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 1); let r = _mm512_inserti64x4::(a, b); @@ -25606,7 +26625,8 @@ pub fn _mm512_maskz_inserti64x4(k: __mmask8, a: __m512i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf32x4, IMM8 = 2))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_insertf32x4(a: __m512, b: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_insertf32x4(a: __m512, b: __m128) -> __m512 { unsafe { static_assert_uimm_bits!(IMM8, 2); let b = _mm512_castps128_ps512(b); @@ -25647,7 +26667,8 @@ pub fn _mm512_insertf32x4(a: __m512, b: __m128) -> __m512 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf32x4, IMM8 = 2))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_insertf32x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_insertf32x4( src: __m512, k: __mmask16, a: __m512, @@ -25668,7 +26689,12 @@ pub fn _mm512_mask_insertf32x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf32x4, IMM8 = 2))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_insertf32x4(k: __mmask16, a: __m512, b: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_insertf32x4( + k: __mmask16, + a: __m512, + b: __m128, +) -> __m512 { unsafe { static_assert_uimm_bits!(IMM8, 2); let r = _mm512_insertf32x4::(a, b); @@ -25687,7 +26713,8 @@ pub fn _mm512_maskz_insertf32x4(k: __mmask16, a: __m512, b: __m assert_instr(vinsert, IMM8 = 1) //should be vinsertf32x4 )] #[rustc_legacy_const_generics(2)] -pub fn _mm256_insertf32x4(a: __m256, b: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_insertf32x4(a: __m256, b: __m128) -> __m256 { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm256_castps128_ps256(b); @@ -25706,7 +26733,8 @@ pub fn _mm256_insertf32x4(a: __m256, b: __m128) -> __m256 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf32x4, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_insertf32x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_insertf32x4( src: __m256, k: __mmask8, a: __m256, @@ -25727,7 +26755,12 @@ pub fn _mm256_mask_insertf32x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf32x4, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_insertf32x4(k: __mmask8, a: __m256, b: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_insertf32x4( + k: __mmask8, + a: __m256, + b: __m128, +) -> __m256 { unsafe { static_assert_uimm_bits!(IMM8, 1); let r = _mm256_insertf32x4::(a, b); @@ -25743,7 +26776,8 @@ pub fn _mm256_maskz_insertf32x4(k: __mmask8, a: __m256, b: __m1 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf64x4, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_insertf64x4(a: __m512d, b: __m256d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_insertf64x4(a: __m512d, b: __m256d) -> __m512d { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm512_castpd256_pd512(b); @@ -25762,7 +26796,8 @@ pub fn _mm512_insertf64x4(a: __m512d, b: __m256d) -> __m512d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf64x4, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_insertf64x4( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_insertf64x4( src: __m512d, k: __mmask8, a: __m512d, @@ -25783,7 +26818,12 @@ pub fn _mm512_mask_insertf64x4( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vinsertf64x4, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_insertf64x4(k: __mmask8, a: __m512d, b: __m256d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_insertf64x4( + k: __mmask8, + a: __m512d, + b: __m256d, +) -> __m512d { unsafe { static_assert_uimm_bits!(IMM8, 1); let r = _mm512_insertf64x4::(a, b); @@ -25798,7 +26838,8 @@ pub fn _mm512_maskz_insertf64x4(k: __mmask8, a: __m512d, b: __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhps))] //should be vpunpckhdq -pub fn _mm512_unpackhi_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpackhi_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = a.as_i32x16(); let b = b.as_i32x16(); @@ -25821,7 +26862,13 @@ pub fn _mm512_unpackhi_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhdq))] -pub fn _mm512_mask_unpackhi_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpackhi_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let unpackhi = _mm512_unpackhi_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, unpackhi, src.as_i32x16())) @@ -25835,7 +26882,8 @@ pub fn _mm512_mask_unpackhi_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhdq))] -pub fn _mm512_maskz_unpackhi_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpackhi_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let unpackhi = _mm512_unpackhi_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, unpackhi, i32x16::ZERO)) @@ -25849,7 +26897,13 @@ pub fn _mm512_maskz_unpackhi_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m5 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhdq))] -pub fn _mm256_mask_unpackhi_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpackhi_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let unpackhi = _mm256_unpackhi_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, unpackhi, src.as_i32x8())) @@ -25863,7 +26917,8 @@ pub fn _mm256_mask_unpackhi_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhdq))] -pub fn _mm256_maskz_unpackhi_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpackhi_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let unpackhi = _mm256_unpackhi_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, unpackhi, i32x8::ZERO)) @@ -25877,7 +26932,8 @@ pub fn _mm256_maskz_unpackhi_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhdq))] -pub fn _mm_mask_unpackhi_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpackhi_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpackhi = _mm_unpackhi_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, unpackhi, src.as_i32x4())) @@ -25891,7 +26947,8 @@ pub fn _mm_mask_unpackhi_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhdq))] -pub fn _mm_maskz_unpackhi_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpackhi_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpackhi = _mm_unpackhi_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, unpackhi, i32x4::ZERO)) @@ -25905,7 +26962,8 @@ pub fn _mm_maskz_unpackhi_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhpd))] //should be vpunpckhqdq -pub fn _mm512_unpackhi_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpackhi_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_shuffle!(a, b, [1, 9, 1 + 2, 9 + 2, 1 + 4, 9 + 4, 1 + 6, 9 + 6]) } } @@ -25916,7 +26974,13 @@ pub fn _mm512_unpackhi_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhqdq))] -pub fn _mm512_mask_unpackhi_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpackhi_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let unpackhi = _mm512_unpackhi_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, unpackhi, src.as_i64x8())) @@ -25930,7 +26994,8 @@ pub fn _mm512_mask_unpackhi_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhqdq))] -pub fn _mm512_maskz_unpackhi_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpackhi_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let unpackhi = _mm512_unpackhi_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, unpackhi, i64x8::ZERO)) @@ -25944,7 +27009,13 @@ pub fn _mm512_maskz_unpackhi_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m51 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhqdq))] -pub fn _mm256_mask_unpackhi_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpackhi_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let unpackhi = _mm256_unpackhi_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, unpackhi, src.as_i64x4())) @@ -25958,7 +27029,8 @@ pub fn _mm256_mask_unpackhi_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhqdq))] -pub fn _mm256_maskz_unpackhi_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpackhi_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let unpackhi = _mm256_unpackhi_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, unpackhi, i64x4::ZERO)) @@ -25972,7 +27044,8 @@ pub fn _mm256_maskz_unpackhi_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhqdq))] -pub fn _mm_mask_unpackhi_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpackhi_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpackhi = _mm_unpackhi_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, unpackhi, src.as_i64x2())) @@ -25986,7 +27059,8 @@ pub fn _mm_mask_unpackhi_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhqdq))] -pub fn _mm_maskz_unpackhi_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpackhi_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpackhi = _mm_unpackhi_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, unpackhi, i64x2::ZERO)) @@ -26000,7 +27074,8 @@ pub fn _mm_maskz_unpackhi_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhps))] -pub fn _mm512_unpackhi_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpackhi_ps(a: __m512, b: __m512) -> __m512 { unsafe { #[rustfmt::skip] simd_shuffle!( @@ -26020,7 +27095,8 @@ pub fn _mm512_unpackhi_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhps))] -pub fn _mm512_mask_unpackhi_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpackhi_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let unpackhi = _mm512_unpackhi_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, unpackhi, src.as_f32x16())) @@ -26034,7 +27110,8 @@ pub fn _mm512_mask_unpackhi_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhps))] -pub fn _mm512_maskz_unpackhi_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpackhi_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let unpackhi = _mm512_unpackhi_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, unpackhi, f32x16::ZERO)) @@ -26048,7 +27125,8 @@ pub fn _mm512_maskz_unpackhi_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhps))] -pub fn _mm256_mask_unpackhi_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpackhi_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let unpackhi = _mm256_unpackhi_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, unpackhi, src.as_f32x8())) @@ -26062,7 +27140,8 @@ pub fn _mm256_mask_unpackhi_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhps))] -pub fn _mm256_maskz_unpackhi_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpackhi_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let unpackhi = _mm256_unpackhi_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, unpackhi, f32x8::ZERO)) @@ -26076,7 +27155,8 @@ pub fn _mm256_maskz_unpackhi_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhps))] -pub fn _mm_mask_unpackhi_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpackhi_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let unpackhi = _mm_unpackhi_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, unpackhi, src.as_f32x4())) @@ -26090,7 +27170,8 @@ pub fn _mm_mask_unpackhi_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhps))] -pub fn _mm_maskz_unpackhi_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpackhi_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let unpackhi = _mm_unpackhi_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, unpackhi, f32x4::ZERO)) @@ -26104,7 +27185,8 @@ pub fn _mm_maskz_unpackhi_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhpd))] -pub fn _mm512_unpackhi_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpackhi_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { simd_shuffle!(a, b, [1, 9, 1 + 2, 9 + 2, 1 + 4, 9 + 4, 1 + 6, 9 + 6]) } } @@ -26115,7 +27197,8 @@ pub fn _mm512_unpackhi_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhpd))] -pub fn _mm512_mask_unpackhi_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpackhi_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let unpackhi = _mm512_unpackhi_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, unpackhi, src.as_f64x8())) @@ -26129,7 +27212,8 @@ pub fn _mm512_mask_unpackhi_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhpd))] -pub fn _mm512_maskz_unpackhi_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpackhi_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let unpackhi = _mm512_unpackhi_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, unpackhi, f64x8::ZERO)) @@ -26143,7 +27227,8 @@ pub fn _mm512_maskz_unpackhi_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhpd))] -pub fn _mm256_mask_unpackhi_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpackhi_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let unpackhi = _mm256_unpackhi_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, unpackhi, src.as_f64x4())) @@ -26157,7 +27242,8 @@ pub fn _mm256_mask_unpackhi_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhpd))] -pub fn _mm256_maskz_unpackhi_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpackhi_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let unpackhi = _mm256_unpackhi_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, unpackhi, f64x4::ZERO)) @@ -26171,7 +27257,8 @@ pub fn _mm256_maskz_unpackhi_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhpd))] -pub fn _mm_mask_unpackhi_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpackhi_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let unpackhi = _mm_unpackhi_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, unpackhi, src.as_f64x2())) @@ -26185,7 +27272,8 @@ pub fn _mm_mask_unpackhi_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpckhpd))] -pub fn _mm_maskz_unpackhi_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpackhi_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let unpackhi = _mm_unpackhi_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, unpackhi, f64x2::ZERO)) @@ -26199,7 +27287,8 @@ pub fn _mm_maskz_unpackhi_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklps))] //should be vpunpckldq -pub fn _mm512_unpacklo_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpacklo_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = a.as_i32x16(); let b = b.as_i32x16(); @@ -26222,7 +27311,13 @@ pub fn _mm512_unpacklo_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckldq))] -pub fn _mm512_mask_unpacklo_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpacklo_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let unpacklo = _mm512_unpacklo_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, unpacklo, src.as_i32x16())) @@ -26236,7 +27331,8 @@ pub fn _mm512_mask_unpacklo_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckldq))] -pub fn _mm512_maskz_unpacklo_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpacklo_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let unpacklo = _mm512_unpacklo_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, unpacklo, i32x16::ZERO)) @@ -26250,7 +27346,13 @@ pub fn _mm512_maskz_unpacklo_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m5 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckldq))] -pub fn _mm256_mask_unpacklo_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpacklo_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let unpacklo = _mm256_unpacklo_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, unpacklo, src.as_i32x8())) @@ -26264,7 +27366,8 @@ pub fn _mm256_mask_unpacklo_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckldq))] -pub fn _mm256_maskz_unpacklo_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpacklo_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let unpacklo = _mm256_unpacklo_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, unpacklo, i32x8::ZERO)) @@ -26278,7 +27381,8 @@ pub fn _mm256_maskz_unpacklo_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckldq))] -pub fn _mm_mask_unpacklo_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpacklo_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpacklo = _mm_unpacklo_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, unpacklo, src.as_i32x4())) @@ -26292,7 +27396,8 @@ pub fn _mm_mask_unpacklo_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckldq))] -pub fn _mm_maskz_unpacklo_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpacklo_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpacklo = _mm_unpacklo_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, unpacklo, i32x4::ZERO)) @@ -26306,7 +27411,8 @@ pub fn _mm_maskz_unpacklo_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklpd))] //should be vpunpcklqdq -pub fn _mm512_unpacklo_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpacklo_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_shuffle!(a, b, [0, 8, 0 + 2, 8 + 2, 0 + 4, 8 + 4, 0 + 6, 8 + 6]) } } @@ -26317,7 +27423,13 @@ pub fn _mm512_unpacklo_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklqdq))] -pub fn _mm512_mask_unpacklo_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpacklo_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let unpacklo = _mm512_unpacklo_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, unpacklo, src.as_i64x8())) @@ -26331,7 +27443,8 @@ pub fn _mm512_mask_unpacklo_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklqdq))] -pub fn _mm512_maskz_unpacklo_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpacklo_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let unpacklo = _mm512_unpacklo_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, unpacklo, i64x8::ZERO)) @@ -26345,7 +27458,13 @@ pub fn _mm512_maskz_unpacklo_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m51 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklqdq))] -pub fn _mm256_mask_unpacklo_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpacklo_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let unpacklo = _mm256_unpacklo_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, unpacklo, src.as_i64x4())) @@ -26359,7 +27478,8 @@ pub fn _mm256_mask_unpacklo_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklqdq))] -pub fn _mm256_maskz_unpacklo_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpacklo_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let unpacklo = _mm256_unpacklo_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, unpacklo, i64x4::ZERO)) @@ -26373,7 +27493,8 @@ pub fn _mm256_maskz_unpacklo_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m25 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklqdq))] -pub fn _mm_mask_unpacklo_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpacklo_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpacklo = _mm_unpacklo_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, unpacklo, src.as_i64x2())) @@ -26387,7 +27508,8 @@ pub fn _mm_mask_unpacklo_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklqdq))] -pub fn _mm_maskz_unpacklo_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpacklo_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpacklo = _mm_unpacklo_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, unpacklo, i64x2::ZERO)) @@ -26401,7 +27523,8 @@ pub fn _mm_maskz_unpacklo_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklps))] -pub fn _mm512_unpacklo_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpacklo_ps(a: __m512, b: __m512) -> __m512 { unsafe { #[rustfmt::skip] simd_shuffle!(a, b, @@ -26420,7 +27543,8 @@ pub fn _mm512_unpacklo_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklps))] -pub fn _mm512_mask_unpacklo_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpacklo_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let unpacklo = _mm512_unpacklo_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, unpacklo, src.as_f32x16())) @@ -26434,7 +27558,8 @@ pub fn _mm512_mask_unpacklo_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklps))] -pub fn _mm512_maskz_unpacklo_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpacklo_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let unpacklo = _mm512_unpacklo_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, unpacklo, f32x16::ZERO)) @@ -26448,7 +27573,8 @@ pub fn _mm512_maskz_unpacklo_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklps))] -pub fn _mm256_mask_unpacklo_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpacklo_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let unpacklo = _mm256_unpacklo_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, unpacklo, src.as_f32x8())) @@ -26462,7 +27588,8 @@ pub fn _mm256_mask_unpacklo_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklps))] -pub fn _mm256_maskz_unpacklo_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpacklo_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let unpacklo = _mm256_unpacklo_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, unpacklo, f32x8::ZERO)) @@ -26476,7 +27603,8 @@ pub fn _mm256_maskz_unpacklo_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklps))] -pub fn _mm_mask_unpacklo_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpacklo_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let unpacklo = _mm_unpacklo_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, unpacklo, src.as_f32x4())) @@ -26490,7 +27618,8 @@ pub fn _mm_mask_unpacklo_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklps))] -pub fn _mm_maskz_unpacklo_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpacklo_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let unpacklo = _mm_unpacklo_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, unpacklo, f32x4::ZERO)) @@ -26504,7 +27633,8 @@ pub fn _mm_maskz_unpacklo_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklpd))] -pub fn _mm512_unpacklo_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpacklo_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { simd_shuffle!(a, b, [0, 8, 0 + 2, 8 + 2, 0 + 4, 8 + 4, 0 + 6, 8 + 6]) } } @@ -26515,7 +27645,8 @@ pub fn _mm512_unpacklo_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklpd))] -pub fn _mm512_mask_unpacklo_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpacklo_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let unpacklo = _mm512_unpacklo_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, unpacklo, src.as_f64x8())) @@ -26529,7 +27660,8 @@ pub fn _mm512_mask_unpacklo_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklpd))] -pub fn _mm512_maskz_unpacklo_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpacklo_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let unpacklo = _mm512_unpacklo_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, unpacklo, f64x8::ZERO)) @@ -26543,7 +27675,8 @@ pub fn _mm512_maskz_unpacklo_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklpd))] -pub fn _mm256_mask_unpacklo_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpacklo_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let unpacklo = _mm256_unpacklo_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, unpacklo, src.as_f64x4())) @@ -26557,7 +27690,8 @@ pub fn _mm256_mask_unpacklo_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklpd))] -pub fn _mm256_maskz_unpacklo_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpacklo_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let unpacklo = _mm256_unpacklo_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, unpacklo, f64x4::ZERO)) @@ -26571,7 +27705,8 @@ pub fn _mm256_maskz_unpacklo_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklpd))] -pub fn _mm_mask_unpacklo_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpacklo_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let unpacklo = _mm_unpacklo_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, unpacklo, src.as_f64x2())) @@ -26585,7 +27720,8 @@ pub fn _mm_mask_unpacklo_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vunpcklpd))] -pub fn _mm_maskz_unpacklo_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpacklo_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let unpacklo = _mm_unpacklo_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, unpacklo, f64x2::ZERO)) @@ -26598,7 +27734,8 @@ pub fn _mm_maskz_unpacklo_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castps128_ps512(a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castps128_ps512(a: __m128) -> __m512 { unsafe { simd_shuffle!( a, @@ -26614,7 +27751,8 @@ pub fn _mm512_castps128_ps512(a: __m128) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castps256_ps512(a: __m256) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castps256_ps512(a: __m256) -> __m512 { unsafe { simd_shuffle!( a, @@ -26630,7 +27768,8 @@ pub fn _mm512_castps256_ps512(a: __m256) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_zextps128_ps512(a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_zextps128_ps512(a: __m128) -> __m512 { unsafe { simd_shuffle!( a, @@ -26646,7 +27785,8 @@ pub fn _mm512_zextps128_ps512(a: __m128) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_zextps256_ps512(a: __m256) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_zextps256_ps512(a: __m256) -> __m512 { unsafe { simd_shuffle!( a, @@ -26662,7 +27802,8 @@ pub fn _mm512_zextps256_ps512(a: __m256) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castps512_ps128(a: __m512) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castps512_ps128(a: __m512) -> __m128 { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3]) } } @@ -26672,7 +27813,8 @@ pub fn _mm512_castps512_ps128(a: __m512) -> __m128 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castps512_ps256(a: __m512) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castps512_ps256(a: __m512) -> __m256 { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]) } } @@ -26682,7 +27824,8 @@ pub fn _mm512_castps512_ps256(a: __m512) -> __m256 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castps_pd(a: __m512) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castps_pd(a: __m512) -> __m512d { unsafe { transmute(a) } } @@ -26692,7 +27835,8 @@ pub fn _mm512_castps_pd(a: __m512) -> __m512d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castps_si512(a: __m512) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castps_si512(a: __m512) -> __m512i { unsafe { transmute(a) } } @@ -26702,7 +27846,8 @@ pub fn _mm512_castps_si512(a: __m512) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castpd128_pd512(a: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castpd128_pd512(a: __m128d) -> __m512d { unsafe { simd_shuffle!(a, _mm_undefined_pd(), [0, 1, 2, 2, 2, 2, 2, 2]) } } @@ -26712,7 +27857,8 @@ pub fn _mm512_castpd128_pd512(a: __m128d) -> __m512d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castpd256_pd512(a: __m256d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castpd256_pd512(a: __m256d) -> __m512d { unsafe { simd_shuffle!(a, _mm256_undefined_pd(), [0, 1, 2, 3, 4, 4, 4, 4]) } } @@ -26722,7 +27868,8 @@ pub fn _mm512_castpd256_pd512(a: __m256d) -> __m512d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_zextpd128_pd512(a: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_zextpd128_pd512(a: __m128d) -> __m512d { unsafe { simd_shuffle!(a, _mm_set1_pd(0.), [0, 1, 2, 2, 2, 2, 2, 2]) } } @@ -26732,7 +27879,8 @@ pub fn _mm512_zextpd128_pd512(a: __m128d) -> __m512d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_zextpd256_pd512(a: __m256d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_zextpd256_pd512(a: __m256d) -> __m512d { unsafe { simd_shuffle!(a, _mm256_set1_pd(0.), [0, 1, 2, 3, 4, 4, 4, 4]) } } @@ -26742,7 +27890,8 @@ pub fn _mm512_zextpd256_pd512(a: __m256d) -> __m512d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castpd512_pd128(a: __m512d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castpd512_pd128(a: __m512d) -> __m128d { unsafe { simd_shuffle!(a, a, [0, 1]) } } @@ -26752,7 +27901,8 @@ pub fn _mm512_castpd512_pd128(a: __m512d) -> __m128d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castpd512_pd256(a: __m512d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castpd512_pd256(a: __m512d) -> __m256d { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3]) } } @@ -26762,7 +27912,8 @@ pub fn _mm512_castpd512_pd256(a: __m512d) -> __m256d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castpd_ps(a: __m512d) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castpd_ps(a: __m512d) -> __m512 { unsafe { transmute(a) } } @@ -26772,7 +27923,8 @@ pub fn _mm512_castpd_ps(a: __m512d) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castpd_si512(a: __m512d) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castpd_si512(a: __m512d) -> __m512i { unsafe { transmute(a) } } @@ -26782,7 +27934,8 @@ pub fn _mm512_castpd_si512(a: __m512d) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castsi128_si512(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castsi128_si512(a: __m128i) -> __m512i { unsafe { simd_shuffle!(a, _mm_undefined_si128(), [0, 1, 2, 2, 2, 2, 2, 2]) } } @@ -26792,7 +27945,8 @@ pub fn _mm512_castsi128_si512(a: __m128i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castsi256_si512(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castsi256_si512(a: __m256i) -> __m512i { unsafe { simd_shuffle!(a, _mm256_undefined_si256(), [0, 1, 2, 3, 4, 4, 4, 4]) } } @@ -26802,7 +27956,8 @@ pub fn _mm512_castsi256_si512(a: __m256i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_zextsi128_si512(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_zextsi128_si512(a: __m128i) -> __m512i { unsafe { simd_shuffle!(a, _mm_setzero_si128(), [0, 1, 2, 2, 2, 2, 2, 2]) } } @@ -26812,7 +27967,8 @@ pub fn _mm512_zextsi128_si512(a: __m128i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_zextsi256_si512(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_zextsi256_si512(a: __m256i) -> __m512i { unsafe { simd_shuffle!(a, _mm256_setzero_si256(), [0, 1, 2, 3, 4, 4, 4, 4]) } } @@ -26822,7 +27978,8 @@ pub fn _mm512_zextsi256_si512(a: __m256i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castsi512_si128(a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castsi512_si128(a: __m512i) -> __m128i { unsafe { simd_shuffle!(a, a, [0, 1]) } } @@ -26832,7 +27989,8 @@ pub fn _mm512_castsi512_si128(a: __m512i) -> __m128i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castsi512_si256(a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castsi512_si256(a: __m512i) -> __m256i { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3]) } } @@ -26842,7 +28000,8 @@ pub fn _mm512_castsi512_si256(a: __m512i) -> __m256i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castsi512_ps(a: __m512i) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castsi512_ps(a: __m512i) -> __m512 { unsafe { transmute(a) } } @@ -26852,7 +28011,8 @@ pub fn _mm512_castsi512_ps(a: __m512i) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_castsi512_pd(a: __m512i) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castsi512_pd(a: __m512i) -> __m512d { unsafe { transmute(a) } } @@ -26863,7 +28023,8 @@ pub fn _mm512_castsi512_pd(a: __m512i) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovd))] -pub fn _mm512_cvtsi512_si32(a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtsi512_si32(a: __m512i) -> i32 { unsafe { simd_extract!(a.as_i32x16(), 0) } } @@ -26873,7 +28034,8 @@ pub fn _mm512_cvtsi512_si32(a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_cvtss_f32(a: __m512) -> f32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtss_f32(a: __m512) -> f32 { unsafe { simd_extract!(a, 0) } } @@ -26883,7 +28045,8 @@ pub fn _mm512_cvtss_f32(a: __m512) -> f32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_cvtsd_f64(a: __m512d) -> f64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtsd_f64(a: __m512d) -> f64 { unsafe { simd_extract!(a, 0) } } @@ -26894,7 +28057,8 @@ pub fn _mm512_cvtsd_f64(a: __m512d) -> f64 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcast))] //should be vpbroadcastd -pub fn _mm512_broadcastd_epi32(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcastd_epi32(a: __m128i) -> __m512i { unsafe { let a = _mm512_castsi128_si512(a).as_i32x16(); let ret: i32x16 = simd_shuffle!(a, a, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); @@ -26909,7 +28073,8 @@ pub fn _mm512_broadcastd_epi32(a: __m128i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastd -pub fn _mm512_mask_broadcastd_epi32(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcastd_epi32(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcastd_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, broadcast, src.as_i32x16())) @@ -26923,7 +28088,8 @@ pub fn _mm512_mask_broadcastd_epi32(src: __m512i, k: __mmask16, a: __m128i) -> _ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastd -pub fn _mm512_maskz_broadcastd_epi32(k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcastd_epi32(k: __mmask16, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcastd_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, broadcast, i32x16::ZERO)) @@ -26937,7 +28103,8 @@ pub fn _mm512_maskz_broadcastd_epi32(k: __mmask16, a: __m128i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastd -pub fn _mm256_mask_broadcastd_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcastd_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcastd_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, broadcast, src.as_i32x8())) @@ -26951,7 +28118,8 @@ pub fn _mm256_mask_broadcastd_epi32(src: __m256i, k: __mmask8, a: __m128i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastd -pub fn _mm256_maskz_broadcastd_epi32(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcastd_epi32(k: __mmask8, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcastd_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, broadcast, i32x8::ZERO)) @@ -26965,7 +28133,8 @@ pub fn _mm256_maskz_broadcastd_epi32(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastd -pub fn _mm_mask_broadcastd_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_broadcastd_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let broadcast = _mm_broadcastd_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, broadcast, src.as_i32x4())) @@ -26979,7 +28148,8 @@ pub fn _mm_mask_broadcastd_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m12 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastd -pub fn _mm_maskz_broadcastd_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_broadcastd_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { let broadcast = _mm_broadcastd_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, broadcast, i32x4::ZERO)) @@ -26993,7 +28163,8 @@ pub fn _mm_maskz_broadcastd_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcast))] //should be vpbroadcastq -pub fn _mm512_broadcastq_epi64(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcastq_epi64(a: __m128i) -> __m512i { unsafe { simd_shuffle!(a, a, [0, 0, 0, 0, 0, 0, 0, 0]) } } @@ -27004,7 +28175,8 @@ pub fn _mm512_broadcastq_epi64(a: __m128i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastq -pub fn _mm512_mask_broadcastq_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcastq_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcastq_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, broadcast, src.as_i64x8())) @@ -27018,7 +28190,8 @@ pub fn _mm512_mask_broadcastq_epi64(src: __m512i, k: __mmask8, a: __m128i) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastq -pub fn _mm512_maskz_broadcastq_epi64(k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcastq_epi64(k: __mmask8, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcastq_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, broadcast, i64x8::ZERO)) @@ -27032,7 +28205,8 @@ pub fn _mm512_maskz_broadcastq_epi64(k: __mmask8, a: __m128i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastq -pub fn _mm256_mask_broadcastq_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcastq_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcastq_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, broadcast, src.as_i64x4())) @@ -27046,7 +28220,8 @@ pub fn _mm256_mask_broadcastq_epi64(src: __m256i, k: __mmask8, a: __m128i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastq -pub fn _mm256_maskz_broadcastq_epi64(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcastq_epi64(k: __mmask8, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcastq_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, broadcast, i64x4::ZERO)) @@ -27060,7 +28235,8 @@ pub fn _mm256_maskz_broadcastq_epi64(k: __mmask8, a: __m128i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastq -pub fn _mm_mask_broadcastq_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_broadcastq_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let broadcast = _mm_broadcastq_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, broadcast, src.as_i64x2())) @@ -27074,7 +28250,8 @@ pub fn _mm_mask_broadcastq_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m12 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] //should be vpbroadcastq -pub fn _mm_maskz_broadcastq_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_broadcastq_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let broadcast = _mm_broadcastq_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, broadcast, i64x2::ZERO)) @@ -27088,7 +28265,8 @@ pub fn _mm_maskz_broadcastq_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastss))] -pub fn _mm512_broadcastss_ps(a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcastss_ps(a: __m128) -> __m512 { unsafe { simd_shuffle!(a, a, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) } } @@ -27099,7 +28277,8 @@ pub fn _mm512_broadcastss_ps(a: __m128) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastss))] -pub fn _mm512_mask_broadcastss_ps(src: __m512, k: __mmask16, a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcastss_ps(src: __m512, k: __mmask16, a: __m128) -> __m512 { unsafe { let broadcast = _mm512_broadcastss_ps(a).as_f32x16(); transmute(simd_select_bitmask(k, broadcast, src.as_f32x16())) @@ -27113,7 +28292,8 @@ pub fn _mm512_mask_broadcastss_ps(src: __m512, k: __mmask16, a: __m128) -> __m51 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastss))] -pub fn _mm512_maskz_broadcastss_ps(k: __mmask16, a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcastss_ps(k: __mmask16, a: __m128) -> __m512 { unsafe { let broadcast = _mm512_broadcastss_ps(a).as_f32x16(); transmute(simd_select_bitmask(k, broadcast, f32x16::ZERO)) @@ -27127,7 +28307,8 @@ pub fn _mm512_maskz_broadcastss_ps(k: __mmask16, a: __m128) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastss))] -pub fn _mm256_mask_broadcastss_ps(src: __m256, k: __mmask8, a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcastss_ps(src: __m256, k: __mmask8, a: __m128) -> __m256 { unsafe { let broadcast = _mm256_broadcastss_ps(a).as_f32x8(); transmute(simd_select_bitmask(k, broadcast, src.as_f32x8())) @@ -27141,7 +28322,8 @@ pub fn _mm256_mask_broadcastss_ps(src: __m256, k: __mmask8, a: __m128) -> __m256 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastss))] -pub fn _mm256_maskz_broadcastss_ps(k: __mmask8, a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcastss_ps(k: __mmask8, a: __m128) -> __m256 { unsafe { let broadcast = _mm256_broadcastss_ps(a).as_f32x8(); transmute(simd_select_bitmask(k, broadcast, f32x8::ZERO)) @@ -27155,7 +28337,8 @@ pub fn _mm256_maskz_broadcastss_ps(k: __mmask8, a: __m128) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastss))] -pub fn _mm_mask_broadcastss_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_broadcastss_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { unsafe { let broadcast = _mm_broadcastss_ps(a).as_f32x4(); transmute(simd_select_bitmask(k, broadcast, src.as_f32x4())) @@ -27169,7 +28352,8 @@ pub fn _mm_mask_broadcastss_ps(src: __m128, k: __mmask8, a: __m128) -> __m128 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastss))] -pub fn _mm_maskz_broadcastss_ps(k: __mmask8, a: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_broadcastss_ps(k: __mmask8, a: __m128) -> __m128 { unsafe { let broadcast = _mm_broadcastss_ps(a).as_f32x4(); transmute(simd_select_bitmask(k, broadcast, f32x4::ZERO)) @@ -27183,7 +28367,8 @@ pub fn _mm_maskz_broadcastss_ps(k: __mmask8, a: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastsd))] -pub fn _mm512_broadcastsd_pd(a: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcastsd_pd(a: __m128d) -> __m512d { unsafe { simd_shuffle!(a, a, [0, 0, 0, 0, 0, 0, 0, 0]) } } @@ -27194,7 +28379,8 @@ pub fn _mm512_broadcastsd_pd(a: __m128d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastsd))] -pub fn _mm512_mask_broadcastsd_pd(src: __m512d, k: __mmask8, a: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcastsd_pd(src: __m512d, k: __mmask8, a: __m128d) -> __m512d { unsafe { let broadcast = _mm512_broadcastsd_pd(a).as_f64x8(); transmute(simd_select_bitmask(k, broadcast, src.as_f64x8())) @@ -27208,7 +28394,8 @@ pub fn _mm512_mask_broadcastsd_pd(src: __m512d, k: __mmask8, a: __m128d) -> __m5 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastsd))] -pub fn _mm512_maskz_broadcastsd_pd(k: __mmask8, a: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcastsd_pd(k: __mmask8, a: __m128d) -> __m512d { unsafe { let broadcast = _mm512_broadcastsd_pd(a).as_f64x8(); transmute(simd_select_bitmask(k, broadcast, f64x8::ZERO)) @@ -27222,7 +28409,8 @@ pub fn _mm512_maskz_broadcastsd_pd(k: __mmask8, a: __m128d) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastsd))] -pub fn _mm256_mask_broadcastsd_pd(src: __m256d, k: __mmask8, a: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcastsd_pd(src: __m256d, k: __mmask8, a: __m128d) -> __m256d { unsafe { let broadcast = _mm256_broadcastsd_pd(a).as_f64x4(); transmute(simd_select_bitmask(k, broadcast, src.as_f64x4())) @@ -27236,7 +28424,8 @@ pub fn _mm256_mask_broadcastsd_pd(src: __m256d, k: __mmask8, a: __m128d) -> __m2 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vbroadcastsd))] -pub fn _mm256_maskz_broadcastsd_pd(k: __mmask8, a: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcastsd_pd(k: __mmask8, a: __m128d) -> __m256d { unsafe { let broadcast = _mm256_broadcastsd_pd(a).as_f64x4(); transmute(simd_select_bitmask(k, broadcast, f64x4::ZERO)) @@ -27249,7 +28438,8 @@ pub fn _mm256_maskz_broadcastsd_pd(k: __mmask8, a: __m128d) -> __m256d { #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcasti32x4, linux: vshuf #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_i32x4(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_i32x4(a: __m128i) -> __m512i { unsafe { let a = a.as_i32x4(); let ret: i32x16 = simd_shuffle!(a, a, [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]); @@ -27263,7 +28453,8 @@ pub fn _mm512_broadcast_i32x4(a: __m128i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcasti32x4, linux: vshuf #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_i32x4(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_i32x4(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcast_i32x4(a).as_i32x16(); transmute(simd_select_bitmask(k, broadcast, src.as_i32x16())) @@ -27276,7 +28467,8 @@ pub fn _mm512_mask_broadcast_i32x4(src: __m512i, k: __mmask16, a: __m128i) -> __ #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcasti32x4, linux: vshuf #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_i32x4(k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_i32x4(k: __mmask16, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcast_i32x4(a).as_i32x16(); transmute(simd_select_bitmask(k, broadcast, i32x16::ZERO)) @@ -27289,7 +28481,8 @@ pub fn _mm512_maskz_broadcast_i32x4(k: __mmask16, a: __m128i) -> __m512i { #[inline] #[target_feature(enable = "avx512f,avx512vl")] //msvc: vbroadcasti32x4, linux: vshuf #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_broadcast_i32x4(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_i32x4(a: __m128i) -> __m256i { unsafe { let a = a.as_i32x4(); let ret: i32x8 = simd_shuffle!(a, a, [0, 1, 2, 3, 0, 1, 2, 3]); @@ -27303,7 +28496,8 @@ pub fn _mm256_broadcast_i32x4(a: __m128i) -> __m256i { #[inline] #[target_feature(enable = "avx512f,avx512vl")] //msvc: vbroadcasti32x4, linux: vshuf #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_broadcast_i32x4(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcast_i32x4(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcast_i32x4(a).as_i32x8(); transmute(simd_select_bitmask(k, broadcast, src.as_i32x8())) @@ -27316,7 +28510,8 @@ pub fn _mm256_mask_broadcast_i32x4(src: __m256i, k: __mmask8, a: __m128i) -> __m #[inline] #[target_feature(enable = "avx512f,avx512vl")] //msvc: vbroadcasti32x4, linux: vshuf #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_broadcast_i32x4(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcast_i32x4(k: __mmask8, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcast_i32x4(a).as_i32x8(); transmute(simd_select_bitmask(k, broadcast, i32x8::ZERO)) @@ -27329,7 +28524,8 @@ pub fn _mm256_maskz_broadcast_i32x4(k: __mmask8, a: __m128i) -> __m256i { #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcasti64x4, linux: vperm #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_i64x4(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_i64x4(a: __m256i) -> __m512i { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 0, 1, 2, 3]) } } @@ -27339,7 +28535,8 @@ pub fn _mm512_broadcast_i64x4(a: __m256i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcasti64x4, linux: vperm #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_i64x4(src: __m512i, k: __mmask8, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_i64x4(src: __m512i, k: __mmask8, a: __m256i) -> __m512i { unsafe { let broadcast = _mm512_broadcast_i64x4(a).as_i64x8(); transmute(simd_select_bitmask(k, broadcast, src.as_i64x8())) @@ -27352,7 +28549,8 @@ pub fn _mm512_mask_broadcast_i64x4(src: __m512i, k: __mmask8, a: __m256i) -> __m #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcasti64x4, linux: vperm #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_i64x4(k: __mmask8, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_i64x4(k: __mmask8, a: __m256i) -> __m512i { unsafe { let broadcast = _mm512_broadcast_i64x4(a).as_i64x8(); transmute(simd_select_bitmask(k, broadcast, i64x8::ZERO)) @@ -27365,7 +28563,8 @@ pub fn _mm512_maskz_broadcast_i64x4(k: __mmask8, a: __m256i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcastf32x4, linux: vshuf #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_f32x4(a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_f32x4(a: __m128) -> __m512 { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]) } } @@ -27375,7 +28574,8 @@ pub fn _mm512_broadcast_f32x4(a: __m128) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcastf32x4, linux: vshu #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_f32x4(src: __m512, k: __mmask16, a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_f32x4(src: __m512, k: __mmask16, a: __m128) -> __m512 { unsafe { let broadcast = _mm512_broadcast_f32x4(a).as_f32x16(); transmute(simd_select_bitmask(k, broadcast, src.as_f32x16())) @@ -27388,7 +28588,8 @@ pub fn _mm512_mask_broadcast_f32x4(src: __m512, k: __mmask16, a: __m128) -> __m5 #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcastf32x4, linux: vshu #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_f32x4(k: __mmask16, a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_f32x4(k: __mmask16, a: __m128) -> __m512 { unsafe { let broadcast = _mm512_broadcast_f32x4(a).as_f32x16(); transmute(simd_select_bitmask(k, broadcast, f32x16::ZERO)) @@ -27401,7 +28602,8 @@ pub fn _mm512_maskz_broadcast_f32x4(k: __mmask16, a: __m128) -> __m512 { #[inline] #[target_feature(enable = "avx512f,avx512vl")] //msvc: vbroadcastf32x4, linux: vshuf #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_broadcast_f32x4(a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_f32x4(a: __m128) -> __m256 { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 0, 1, 2, 3]) } } @@ -27411,7 +28613,8 @@ pub fn _mm256_broadcast_f32x4(a: __m128) -> __m256 { #[inline] #[target_feature(enable = "avx512f,avx512vl")] //msvc: vbroadcastf32x4, linux: vshu #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_broadcast_f32x4(src: __m256, k: __mmask8, a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcast_f32x4(src: __m256, k: __mmask8, a: __m128) -> __m256 { unsafe { let broadcast = _mm256_broadcast_f32x4(a).as_f32x8(); transmute(simd_select_bitmask(k, broadcast, src.as_f32x8())) @@ -27424,7 +28627,8 @@ pub fn _mm256_mask_broadcast_f32x4(src: __m256, k: __mmask8, a: __m128) -> __m25 #[inline] #[target_feature(enable = "avx512f,avx512vl")] //msvc: vbroadcastf32x4, linux: vshu #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_broadcast_f32x4(k: __mmask8, a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcast_f32x4(k: __mmask8, a: __m128) -> __m256 { unsafe { let broadcast = _mm256_broadcast_f32x4(a).as_f32x8(); transmute(simd_select_bitmask(k, broadcast, f32x8::ZERO)) @@ -27437,7 +28641,8 @@ pub fn _mm256_maskz_broadcast_f32x4(k: __mmask8, a: __m128) -> __m256 { #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcastf64x4, linux: vperm #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_f64x4(a: __m256d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_f64x4(a: __m256d) -> __m512d { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 0, 1, 2, 3]) } } @@ -27447,7 +28652,8 @@ pub fn _mm512_broadcast_f64x4(a: __m256d) -> __m512d { #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcastf64x4, linux: vper #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_f64x4(src: __m512d, k: __mmask8, a: __m256d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_f64x4(src: __m512d, k: __mmask8, a: __m256d) -> __m512d { unsafe { let broadcast = _mm512_broadcast_f64x4(a).as_f64x8(); transmute(simd_select_bitmask(k, broadcast, src.as_f64x8())) @@ -27460,7 +28666,8 @@ pub fn _mm512_mask_broadcast_f64x4(src: __m512d, k: __mmask8, a: __m256d) -> __m #[inline] #[target_feature(enable = "avx512f")] //msvc: vbroadcastf64x4, linux: vper #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_f64x4(k: __mmask8, a: __m256d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_f64x4(k: __mmask8, a: __m256d) -> __m512d { unsafe { let broadcast = _mm512_broadcast_f64x4(a).as_f64x8(); transmute(simd_select_bitmask(k, broadcast, f64x8::ZERO)) @@ -27474,7 +28681,8 @@ pub fn _mm512_maskz_broadcast_f64x4(k: __mmask8, a: __m256d) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa32))] //should be vpblendmd -pub fn _mm512_mask_blend_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_blend_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask(k, b.as_i32x16(), a.as_i32x16())) } } @@ -27485,7 +28693,8 @@ pub fn _mm512_mask_blend_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa32))] //should be vpblendmd -pub fn _mm256_mask_blend_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_blend_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask(k, b.as_i32x8(), a.as_i32x8())) } } @@ -27496,7 +28705,8 @@ pub fn _mm256_mask_blend_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa32))] //should be vpblendmd -pub fn _mm_mask_blend_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_blend_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask(k, b.as_i32x4(), a.as_i32x4())) } } @@ -27507,7 +28717,8 @@ pub fn _mm_mask_blend_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa64))] //should be vpblendmq -pub fn _mm512_mask_blend_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_blend_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask(k, b.as_i64x8(), a.as_i64x8())) } } @@ -27518,7 +28729,8 @@ pub fn _mm512_mask_blend_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa64))] //should be vpblendmq -pub fn _mm256_mask_blend_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_blend_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask(k, b.as_i64x4(), a.as_i64x4())) } } @@ -27529,7 +28741,8 @@ pub fn _mm256_mask_blend_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqa64))] //should be vpblendmq -pub fn _mm_mask_blend_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_blend_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask(k, b.as_i64x2(), a.as_i64x2())) } } @@ -27540,7 +28753,8 @@ pub fn _mm_mask_blend_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovaps))] //should be vpblendmps -pub fn _mm512_mask_blend_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_blend_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { transmute(simd_select_bitmask(k, b.as_f32x16(), a.as_f32x16())) } } @@ -27551,7 +28765,8 @@ pub fn _mm512_mask_blend_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovaps))] //should be vpblendmps -pub fn _mm256_mask_blend_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_blend_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { transmute(simd_select_bitmask(k, b.as_f32x8(), a.as_f32x8())) } } @@ -27562,7 +28777,8 @@ pub fn _mm256_mask_blend_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovaps))] //should be vpblendmps -pub fn _mm_mask_blend_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_blend_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { transmute(simd_select_bitmask(k, b.as_f32x4(), a.as_f32x4())) } } @@ -27573,7 +28789,8 @@ pub fn _mm_mask_blend_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovapd))] //should be vpblendmpd -pub fn _mm512_mask_blend_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_blend_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { transmute(simd_select_bitmask(k, b.as_f64x8(), a.as_f64x8())) } } @@ -27584,7 +28801,8 @@ pub fn _mm512_mask_blend_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovapd))] //should be vpblendmpd -pub fn _mm256_mask_blend_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_blend_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { transmute(simd_select_bitmask(k, b.as_f64x4(), a.as_f64x4())) } } @@ -27595,7 +28813,8 @@ pub fn _mm256_mask_blend_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovapd))] //should be vpblendmpd -pub fn _mm_mask_blend_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_blend_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { transmute(simd_select_bitmask(k, b.as_f64x2(), a.as_f64x2())) } } @@ -27609,7 +28828,8 @@ pub fn _mm_mask_blend_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignd, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_alignr_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_alignr_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let a = a.as_i32x16(); @@ -27690,7 +28910,8 @@ pub fn _mm512_alignr_epi32(a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignd, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_alignr_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_alignr_epi32( src: __m512i, k: __mmask16, a: __m512i, @@ -27711,7 +28932,12 @@ pub fn _mm512_mask_alignr_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignd, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_alignr_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_alignr_epi32( + k: __mmask16, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm512_alignr_epi32::(a, b); @@ -27729,7 +28955,8 @@ pub fn _mm512_maskz_alignr_epi32(k: __mmask16, a: __m512i, b: _ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignd, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_alignr_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_alignr_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let a = a.as_i32x8(); @@ -27758,7 +28985,8 @@ pub fn _mm256_alignr_epi32(a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignd, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_alignr_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_alignr_epi32( src: __m256i, k: __mmask8, a: __m256i, @@ -27779,7 +29007,12 @@ pub fn _mm256_mask_alignr_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignd, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_alignr_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_alignr_epi32( + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm256_alignr_epi32::(a, b); @@ -27797,7 +29030,8 @@ pub fn _mm256_maskz_alignr_epi32(k: __mmask8, a: __m256i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 1))] //should be valignd #[rustc_legacy_const_generics(2)] -pub fn _mm_alignr_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_alignr_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let a = a.as_i32x4(); @@ -27822,7 +29056,8 @@ pub fn _mm_alignr_epi32(a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignd, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_alignr_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_alignr_epi32( src: __m128i, k: __mmask8, a: __m128i, @@ -27843,7 +29078,12 @@ pub fn _mm_mask_alignr_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignd, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_alignr_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_alignr_epi32( + k: __mmask8, + a: __m128i, + b: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm_alignr_epi32::(a, b); @@ -27861,7 +29101,8 @@ pub fn _mm_maskz_alignr_epi32(k: __mmask8, a: __m128i, b: __m12 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_alignr_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_alignr_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let imm8: i32 = IMM8 % 8; @@ -27888,7 +29129,8 @@ pub fn _mm512_alignr_epi64(a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignq, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_alignr_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_alignr_epi64( src: __m512i, k: __mmask8, a: __m512i, @@ -27909,7 +29151,12 @@ pub fn _mm512_mask_alignr_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_alignr_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_alignr_epi64( + k: __mmask8, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm512_alignr_epi64::(a, b); @@ -27927,7 +29174,8 @@ pub fn _mm512_maskz_alignr_epi64(k: __mmask8, a: __m512i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignq, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_alignr_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_alignr_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let imm8: i32 = IMM8 % 4; @@ -27950,7 +29198,8 @@ pub fn _mm256_alignr_epi64(a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignq, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_alignr_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_alignr_epi64( src: __m256i, k: __mmask8, a: __m256i, @@ -27971,7 +29220,12 @@ pub fn _mm256_mask_alignr_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_alignr_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_alignr_epi64( + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm256_alignr_epi64::(a, b); @@ -27989,7 +29243,8 @@ pub fn _mm256_maskz_alignr_epi64(k: __mmask8, a: __m256i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 1))] //should be valignq #[rustc_legacy_const_generics(2)] -pub fn _mm_alignr_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_alignr_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let imm8: i32 = IMM8 % 2; @@ -28010,7 +29265,8 @@ pub fn _mm_alignr_epi64(a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignq, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_alignr_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_alignr_epi64( src: __m128i, k: __mmask8, a: __m128i, @@ -28031,7 +29287,12 @@ pub fn _mm_mask_alignr_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(valignq, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_alignr_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_alignr_epi64( + k: __mmask8, + a: __m128i, + b: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm_alignr_epi64::(a, b); @@ -28046,7 +29307,8 @@ pub fn _mm_maskz_alignr_epi64(k: __mmask8, a: __m128i, b: __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] //should be vpandd, but generate vpandq -pub fn _mm512_and_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_and_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_and(a.as_i32x16(), b.as_i32x16())) } } @@ -28057,7 +29319,8 @@ pub fn _mm512_and_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandd))] -pub fn _mm512_mask_and_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_and_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let and = _mm512_and_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, and, src.as_i32x16())) @@ -28071,7 +29334,8 @@ pub fn _mm512_mask_and_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandd))] -pub fn _mm512_maskz_and_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_and_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let and = _mm512_and_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, and, i32x16::ZERO)) @@ -28085,7 +29349,8 @@ pub fn _mm512_maskz_and_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandd))] -pub fn _mm256_mask_and_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_and_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let and = simd_and(a.as_i32x8(), b.as_i32x8()); transmute(simd_select_bitmask(k, and, src.as_i32x8())) @@ -28099,7 +29364,8 @@ pub fn _mm256_mask_and_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandd))] -pub fn _mm256_maskz_and_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_and_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let and = simd_and(a.as_i32x8(), b.as_i32x8()); transmute(simd_select_bitmask(k, and, i32x8::ZERO)) @@ -28113,7 +29379,8 @@ pub fn _mm256_maskz_and_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandd))] -pub fn _mm_mask_and_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_and_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let and = simd_and(a.as_i32x4(), b.as_i32x4()); transmute(simd_select_bitmask(k, and, src.as_i32x4())) @@ -28127,7 +29394,8 @@ pub fn _mm_mask_and_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandd))] -pub fn _mm_maskz_and_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_and_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let and = simd_and(a.as_i32x4(), b.as_i32x4()); transmute(simd_select_bitmask(k, and, i32x4::ZERO)) @@ -28141,7 +29409,8 @@ pub fn _mm_maskz_and_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm512_and_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_and_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_and(a.as_i64x8(), b.as_i64x8())) } } @@ -28152,7 +29421,8 @@ pub fn _mm512_and_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm512_mask_and_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_and_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let and = _mm512_and_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, and, src.as_i64x8())) @@ -28166,7 +29436,8 @@ pub fn _mm512_mask_and_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm512_maskz_and_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_and_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let and = _mm512_and_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, and, i64x8::ZERO)) @@ -28180,7 +29451,8 @@ pub fn _mm512_maskz_and_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm256_mask_and_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_and_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let and = simd_and(a.as_i64x4(), b.as_i64x4()); transmute(simd_select_bitmask(k, and, src.as_i64x4())) @@ -28194,7 +29466,8 @@ pub fn _mm256_mask_and_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm256_maskz_and_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_and_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let and = simd_and(a.as_i64x4(), b.as_i64x4()); transmute(simd_select_bitmask(k, and, i64x4::ZERO)) @@ -28208,7 +29481,8 @@ pub fn _mm256_maskz_and_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm_mask_and_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_and_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let and = simd_and(a.as_i64x2(), b.as_i64x2()); transmute(simd_select_bitmask(k, and, src.as_i64x2())) @@ -28222,7 +29496,8 @@ pub fn _mm_mask_and_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm_maskz_and_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_and_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let and = simd_and(a.as_i64x2(), b.as_i64x2()); transmute(simd_select_bitmask(k, and, i64x2::ZERO)) @@ -28236,7 +29511,8 @@ pub fn _mm_maskz_and_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandq))] -pub fn _mm512_and_si512(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_and_si512(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_and(a.as_i32x16(), b.as_i32x16())) } } @@ -28247,7 +29523,8 @@ pub fn _mm512_and_si512(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vporq))] -pub fn _mm512_or_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_or_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_or(a.as_i32x16(), b.as_i32x16())) } } @@ -28258,7 +29535,8 @@ pub fn _mm512_or_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpord))] -pub fn _mm512_mask_or_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_or_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let or = _mm512_or_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, or, src.as_i32x16())) @@ -28272,7 +29550,8 @@ pub fn _mm512_mask_or_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpord))] -pub fn _mm512_maskz_or_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_or_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let or = _mm512_or_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, or, i32x16::ZERO)) @@ -28286,7 +29565,8 @@ pub fn _mm512_maskz_or_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vor))] //should be vpord -pub fn _mm256_or_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_or_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_or(a.as_i32x8(), b.as_i32x8())) } } @@ -28297,7 +29577,8 @@ pub fn _mm256_or_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpord))] -pub fn _mm256_mask_or_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_or_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let or = _mm256_or_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, or, src.as_i32x8())) @@ -28311,7 +29592,8 @@ pub fn _mm256_mask_or_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpord))] -pub fn _mm256_maskz_or_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_or_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let or = _mm256_or_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, or, i32x8::ZERO)) @@ -28325,7 +29607,8 @@ pub fn _mm256_maskz_or_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vor))] //should be vpord -pub fn _mm_or_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_or_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_or(a.as_i32x4(), b.as_i32x4())) } } @@ -28336,7 +29619,8 @@ pub fn _mm_or_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpord))] -pub fn _mm_mask_or_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_or_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let or = _mm_or_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, or, src.as_i32x4())) @@ -28350,7 +29634,8 @@ pub fn _mm_mask_or_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpord))] -pub fn _mm_maskz_or_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_or_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let or = _mm_or_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, or, i32x4::ZERO)) @@ -28364,7 +29649,8 @@ pub fn _mm_maskz_or_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vporq))] -pub fn _mm512_or_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_or_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_or(a.as_i64x8(), b.as_i64x8())) } } @@ -28375,7 +29661,8 @@ pub fn _mm512_or_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vporq))] -pub fn _mm512_mask_or_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_or_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let or = _mm512_or_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, or, src.as_i64x8())) @@ -28389,7 +29676,8 @@ pub fn _mm512_mask_or_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) - #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vporq))] -pub fn _mm512_maskz_or_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_or_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let or = _mm512_or_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, or, i64x8::ZERO)) @@ -28403,7 +29691,8 @@ pub fn _mm512_maskz_or_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vor))] //should be vporq -pub fn _mm256_or_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_or_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_or(a.as_i64x4(), b.as_i64x4())) } } @@ -28414,7 +29703,8 @@ pub fn _mm256_or_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vporq))] -pub fn _mm256_mask_or_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_or_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let or = _mm256_or_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, or, src.as_i64x4())) @@ -28428,7 +29718,8 @@ pub fn _mm256_mask_or_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) - #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vporq))] -pub fn _mm256_maskz_or_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_or_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let or = _mm256_or_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, or, i64x4::ZERO)) @@ -28442,7 +29733,8 @@ pub fn _mm256_maskz_or_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vor))] //should be vporq -pub fn _mm_or_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_or_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_or(a.as_i64x2(), b.as_i64x2())) } } @@ -28453,7 +29745,8 @@ pub fn _mm_or_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vporq))] -pub fn _mm_mask_or_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_or_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let or = _mm_or_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, or, src.as_i64x2())) @@ -28467,7 +29760,8 @@ pub fn _mm_mask_or_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vporq))] -pub fn _mm_maskz_or_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_or_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let or = _mm_or_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, or, i64x2::ZERO)) @@ -28481,7 +29775,8 @@ pub fn _mm_maskz_or_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vporq))] -pub fn _mm512_or_si512(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_or_si512(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_or(a.as_i32x16(), b.as_i32x16())) } } @@ -28492,7 +29787,8 @@ pub fn _mm512_or_si512(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxorq))] //should be vpxord -pub fn _mm512_xor_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_xor_epi32(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_xor(a.as_i32x16(), b.as_i32x16())) } } @@ -28503,7 +29799,8 @@ pub fn _mm512_xor_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxord))] -pub fn _mm512_mask_xor_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_xor_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let xor = _mm512_xor_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, xor, src.as_i32x16())) @@ -28517,7 +29814,8 @@ pub fn _mm512_mask_xor_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxord))] -pub fn _mm512_maskz_xor_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_xor_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let xor = _mm512_xor_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, xor, i32x16::ZERO)) @@ -28531,7 +29829,8 @@ pub fn _mm512_maskz_xor_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vxor))] //should be vpxord -pub fn _mm256_xor_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_xor_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_xor(a.as_i32x8(), b.as_i32x8())) } } @@ -28542,7 +29841,8 @@ pub fn _mm256_xor_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxord))] -pub fn _mm256_mask_xor_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_xor_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let xor = _mm256_xor_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, xor, src.as_i32x8())) @@ -28556,7 +29856,8 @@ pub fn _mm256_mask_xor_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxord))] -pub fn _mm256_maskz_xor_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_xor_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let xor = _mm256_xor_epi32(a, b).as_i32x8(); transmute(simd_select_bitmask(k, xor, i32x8::ZERO)) @@ -28570,7 +29871,8 @@ pub fn _mm256_maskz_xor_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vxor))] //should be vpxord -pub fn _mm_xor_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_xor_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_xor(a.as_i32x4(), b.as_i32x4())) } } @@ -28581,7 +29883,8 @@ pub fn _mm_xor_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxord))] -pub fn _mm_mask_xor_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_xor_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let xor = _mm_xor_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, xor, src.as_i32x4())) @@ -28595,7 +29898,8 @@ pub fn _mm_mask_xor_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxord))] -pub fn _mm_maskz_xor_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_xor_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let xor = _mm_xor_epi32(a, b).as_i32x4(); transmute(simd_select_bitmask(k, xor, i32x4::ZERO)) @@ -28609,7 +29913,8 @@ pub fn _mm_maskz_xor_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxorq))] -pub fn _mm512_xor_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_xor_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_xor(a.as_i64x8(), b.as_i64x8())) } } @@ -28620,7 +29925,8 @@ pub fn _mm512_xor_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxorq))] -pub fn _mm512_mask_xor_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_xor_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let xor = _mm512_xor_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, xor, src.as_i64x8())) @@ -28634,7 +29940,8 @@ pub fn _mm512_mask_xor_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxorq))] -pub fn _mm512_maskz_xor_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_xor_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let xor = _mm512_xor_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, xor, i64x8::ZERO)) @@ -28648,7 +29955,8 @@ pub fn _mm512_maskz_xor_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vxor))] //should be vpxorq -pub fn _mm256_xor_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_xor_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_xor(a.as_i64x4(), b.as_i64x4())) } } @@ -28659,7 +29967,8 @@ pub fn _mm256_xor_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxorq))] -pub fn _mm256_mask_xor_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_xor_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let xor = _mm256_xor_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, xor, src.as_i64x4())) @@ -28673,7 +29982,8 @@ pub fn _mm256_mask_xor_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxorq))] -pub fn _mm256_maskz_xor_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_xor_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let xor = _mm256_xor_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, xor, i64x4::ZERO)) @@ -28687,7 +29997,8 @@ pub fn _mm256_maskz_xor_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vxor))] //should be vpxorq -pub fn _mm_xor_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_xor_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_xor(a.as_i64x2(), b.as_i64x2())) } } @@ -28698,7 +30009,8 @@ pub fn _mm_xor_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxorq))] -pub fn _mm_mask_xor_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_xor_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let xor = _mm_xor_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, xor, src.as_i64x2())) @@ -28712,7 +30024,8 @@ pub fn _mm_mask_xor_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxorq))] -pub fn _mm_maskz_xor_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_xor_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let xor = _mm_xor_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, xor, i64x2::ZERO)) @@ -28726,7 +30039,8 @@ pub fn _mm_maskz_xor_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpxorq))] -pub fn _mm512_xor_si512(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_xor_si512(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_xor(a.as_i32x16(), b.as_i32x16())) } } @@ -28737,7 +30051,8 @@ pub fn _mm512_xor_si512(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnq))] //should be vpandnd -pub fn _mm512_andnot_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_andnot_epi32(a: __m512i, b: __m512i) -> __m512i { _mm512_and_epi32(_mm512_xor_epi32(a, _mm512_set1_epi32(u32::MAX as i32)), b) } @@ -28748,7 +30063,13 @@ pub fn _mm512_andnot_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnd))] -pub fn _mm512_mask_andnot_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_andnot_epi32( + src: __m512i, + k: __mmask16, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let andnot = _mm512_andnot_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, andnot, src.as_i32x16())) @@ -28762,7 +30083,8 @@ pub fn _mm512_mask_andnot_epi32(src: __m512i, k: __mmask16, a: __m512i, b: __m51 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnd))] -pub fn _mm512_maskz_andnot_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_andnot_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let andnot = _mm512_andnot_epi32(a, b).as_i32x16(); transmute(simd_select_bitmask(k, andnot, i32x16::ZERO)) @@ -28776,7 +30098,13 @@ pub fn _mm512_maskz_andnot_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnd))] -pub fn _mm256_mask_andnot_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_andnot_epi32( + src: __m256i, + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let not = _mm256_xor_epi32(a, _mm256_set1_epi32(u32::MAX as i32)); let andnot = simd_and(not.as_i32x8(), b.as_i32x8()); @@ -28791,7 +30119,8 @@ pub fn _mm256_mask_andnot_epi32(src: __m256i, k: __mmask8, a: __m256i, b: __m256 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnd))] -pub fn _mm256_maskz_andnot_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_andnot_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let not = _mm256_xor_epi32(a, _mm256_set1_epi32(u32::MAX as i32)); let andnot = simd_and(not.as_i32x8(), b.as_i32x8()); @@ -28806,7 +30135,8 @@ pub fn _mm256_maskz_andnot_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnd))] -pub fn _mm_mask_andnot_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_andnot_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let not = _mm_xor_epi32(a, _mm_set1_epi32(u32::MAX as i32)); let andnot = simd_and(not.as_i32x4(), b.as_i32x4()); @@ -28821,7 +30151,8 @@ pub fn _mm_mask_andnot_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnd))] -pub fn _mm_maskz_andnot_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_andnot_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let not = _mm_xor_epi32(a, _mm_set1_epi32(u32::MAX as i32)); let andnot = simd_and(not.as_i32x4(), b.as_i32x4()); @@ -28836,7 +30167,8 @@ pub fn _mm_maskz_andnot_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnq))] //should be vpandnd -pub fn _mm512_andnot_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_andnot_epi64(a: __m512i, b: __m512i) -> __m512i { _mm512_and_epi64(_mm512_xor_epi64(a, _mm512_set1_epi64(u64::MAX as i64)), b) } @@ -28847,7 +30179,13 @@ pub fn _mm512_andnot_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnq))] -pub fn _mm512_mask_andnot_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_andnot_epi64( + src: __m512i, + k: __mmask8, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let andnot = _mm512_andnot_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, andnot, src.as_i64x8())) @@ -28861,7 +30199,8 @@ pub fn _mm512_mask_andnot_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnq))] -pub fn _mm512_maskz_andnot_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_andnot_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let andnot = _mm512_andnot_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, andnot, i64x8::ZERO)) @@ -28875,7 +30214,13 @@ pub fn _mm512_maskz_andnot_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnq))] -pub fn _mm256_mask_andnot_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_andnot_epi64( + src: __m256i, + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let not = _mm256_xor_epi64(a, _mm256_set1_epi64x(u64::MAX as i64)); let andnot = simd_and(not.as_i64x4(), b.as_i64x4()); @@ -28890,7 +30235,8 @@ pub fn _mm256_mask_andnot_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256 #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnq))] -pub fn _mm256_maskz_andnot_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_andnot_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let not = _mm256_xor_epi64(a, _mm256_set1_epi64x(u64::MAX as i64)); let andnot = simd_and(not.as_i64x4(), b.as_i64x4()); @@ -28905,7 +30251,8 @@ pub fn _mm256_maskz_andnot_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnq))] -pub fn _mm_mask_andnot_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_andnot_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let not = _mm_xor_epi64(a, _mm_set1_epi64x(u64::MAX as i64)); let andnot = simd_and(not.as_i64x2(), b.as_i64x2()); @@ -28920,7 +30267,8 @@ pub fn _mm_mask_andnot_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnq))] -pub fn _mm_maskz_andnot_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_andnot_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let not = _mm_xor_epi64(a, _mm_set1_epi64x(u64::MAX as i64)); let andnot = simd_and(not.as_i64x2(), b.as_i64x2()); @@ -28935,7 +30283,8 @@ pub fn _mm_maskz_andnot_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpandnq))] -pub fn _mm512_andnot_si512(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_andnot_si512(a: __m512i, b: __m512i) -> __m512i { _mm512_and_epi64(_mm512_xor_epi64(a, _mm512_set1_epi64(u64::MAX as i64)), b) } @@ -28945,7 +30294,8 @@ pub fn _mm512_andnot_si512(a: __m512i, b: __m512i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _cvtmask16_u32(a: __mmask16) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _cvtmask16_u32(a: __mmask16) -> u32 { a as u32 } @@ -28955,7 +30305,8 @@ pub fn _cvtmask16_u32(a: __mmask16) -> u32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _cvtu32_mask16(a: u32) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _cvtu32_mask16(a: u32) -> __mmask16 { a as __mmask16 } @@ -28966,7 +30317,8 @@ pub fn _cvtu32_mask16(a: u32) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(and))] // generate normal and code instead of kandw -pub fn _kand_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kand_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { a & b } @@ -28977,7 +30329,8 @@ pub fn _kand_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(and))] // generate normal and code instead of kandw -pub fn _mm512_kand(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kand(a: __mmask16, b: __mmask16) -> __mmask16 { a & b } @@ -28988,7 +30341,8 @@ pub fn _mm512_kand(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(or))] // generate normal or code instead of korw -pub fn _kor_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kor_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { a | b } @@ -28999,7 +30353,8 @@ pub fn _kor_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(or))] // generate normal or code instead of korw -pub fn _mm512_kor(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kor(a: __mmask16, b: __mmask16) -> __mmask16 { a | b } @@ -29010,7 +30365,8 @@ pub fn _mm512_kor(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(xor))] // generate normal xor code instead of kxorw -pub fn _kxor_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kxor_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { a ^ b } @@ -29021,7 +30377,8 @@ pub fn _kxor_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(xor))] // generate normal xor code instead of kxorw -pub fn _mm512_kxor(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kxor(a: __mmask16, b: __mmask16) -> __mmask16 { a ^ b } @@ -29031,7 +30388,8 @@ pub fn _mm512_kxor(a: __mmask16, b: __mmask16) -> __mmask16 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _knot_mask16(a: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _knot_mask16(a: __mmask16) -> __mmask16 { a ^ 0b11111111_11111111 } @@ -29041,7 +30399,8 @@ pub fn _knot_mask16(a: __mmask16) -> __mmask16 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_knot(a: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_knot(a: __mmask16) -> __mmask16 { a ^ 0b11111111_11111111 } @@ -29052,7 +30411,8 @@ pub fn _mm512_knot(a: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(not))] // generate normal and, not code instead of kandnw -pub fn _kandn_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kandn_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { _mm512_kand(_mm512_knot(a), b) } @@ -29063,7 +30423,8 @@ pub fn _kandn_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(not))] // generate normal and code instead of kandw -pub fn _mm512_kandn(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kandn(a: __mmask16, b: __mmask16) -> __mmask16 { _mm512_kand(_mm512_knot(a), b) } @@ -29074,7 +30435,8 @@ pub fn _mm512_kandn(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(xor))] // generate normal xor, not code instead of kxnorw -pub fn _kxnor_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kxnor_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { _mm512_knot(_mm512_kxor(a, b)) } @@ -29085,7 +30447,8 @@ pub fn _kxnor_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(xor))] // generate normal and code instead of kandw -pub fn _mm512_kxnor(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kxnor(a: __mmask16, b: __mmask16) -> __mmask16 { _mm512_knot(_mm512_kxor(a, b)) } @@ -29096,7 +30459,8 @@ pub fn _mm512_kxnor(a: __mmask16, b: __mmask16) -> __mmask16 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _kortest_mask16_u8(a: __mmask16, b: __mmask16, all_ones: *mut u8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _kortest_mask16_u8(a: __mmask16, b: __mmask16, all_ones: *mut u8) -> u8 { let tmp = _kor_mask16(a, b); *all_ones = (tmp == 0xffff) as u8; (tmp == 0) as u8 @@ -29109,7 +30473,8 @@ pub unsafe fn _kortest_mask16_u8(a: __mmask16, b: __mmask16, all_ones: *mut u8) #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kortestc_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kortestc_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { (_kor_mask16(a, b) == 0xffff) as u8 } @@ -29120,7 +30485,8 @@ pub fn _kortestc_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kortestz_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kortestz_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { (_kor_mask16(a, b) == 0) as u8 } @@ -29131,7 +30497,8 @@ pub fn _kortestz_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { #[target_feature(enable = "avx512f")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kshiftli_mask16(a: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kshiftli_mask16(a: __mmask16) -> __mmask16 { a.unbounded_shl(COUNT) } @@ -29142,7 +30509,8 @@ pub fn _kshiftli_mask16(a: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kshiftri_mask16(a: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kshiftri_mask16(a: __mmask16) -> __mmask16 { a.unbounded_shr(COUNT) } @@ -29152,7 +30520,8 @@ pub fn _kshiftri_mask16(a: __mmask16) -> __mmask16 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _load_mask16(mem_addr: *const __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _load_mask16(mem_addr: *const __mmask16) -> __mmask16 { *mem_addr } @@ -29162,7 +30531,8 @@ pub unsafe fn _load_mask16(mem_addr: *const __mmask16) -> __mmask16 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _store_mask16(mem_addr: *mut __mmask16, a: __mmask16) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _store_mask16(mem_addr: *mut __mmask16, a: __mmask16) { *mem_addr = a; } @@ -29173,7 +30543,8 @@ pub unsafe fn _store_mask16(mem_addr: *mut __mmask16, a: __mmask16) { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(mov))] // generate normal and code instead of kmovw -pub fn _mm512_kmov(a: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kmov(a: __mmask16) -> __mmask16 { a } @@ -29183,7 +30554,8 @@ pub fn _mm512_kmov(a: __mmask16) -> __mmask16 { #[inline] #[target_feature(enable = "avx512f")] // generate normal and code instead of kmovw #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_int2mask(mask: i32) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_int2mask(mask: i32) -> __mmask16 { mask as u16 } @@ -29194,7 +30566,8 @@ pub fn _mm512_int2mask(mask: i32) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(mov))] // generate normal and code instead of kmovw -pub fn _mm512_mask2int(k1: __mmask16) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask2int(k1: __mmask16) -> i32 { k1 as i32 } @@ -29205,7 +30578,8 @@ pub fn _mm512_mask2int(k1: __mmask16) -> i32 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(mov))] // generate normal and code instead of kunpckbw -pub fn _mm512_kunpackb(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kunpackb(a: __mmask16, b: __mmask16) -> __mmask16 { ((a & 0xff) << 8) | (b & 0xff) } @@ -29216,7 +30590,8 @@ pub fn _mm512_kunpackb(a: __mmask16, b: __mmask16) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(cmp))] // generate normal and code instead of kortestw -pub fn _mm512_kortestc(a: __mmask16, b: __mmask16) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kortestc(a: __mmask16, b: __mmask16) -> i32 { let r = (a | b) == 0b11111111_11111111; r as i32 } @@ -29228,7 +30603,8 @@ pub fn _mm512_kortestc(a: __mmask16, b: __mmask16) -> i32 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(xor))] // generate normal and code instead of kortestw -pub fn _mm512_kortestz(a: __mmask16, b: __mmask16) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kortestz(a: __mmask16, b: __mmask16) -> i32 { let r = (a | b) == 0; r as i32 } @@ -29240,7 +30616,8 @@ pub fn _mm512_kortestz(a: __mmask16, b: __mmask16) -> i32 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmd))] -pub fn _mm512_test_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_test_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { let and = _mm512_and_epi32(a, b); let zero = _mm512_setzero_si512(); _mm512_cmpneq_epi32_mask(and, zero) @@ -29253,7 +30630,8 @@ pub fn _mm512_test_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmd))] -pub fn _mm512_mask_test_epi32_mask(k: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_test_epi32_mask(k: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { let and = _mm512_and_epi32(a, b); let zero = _mm512_setzero_si512(); _mm512_mask_cmpneq_epi32_mask(k, and, zero) @@ -29266,7 +30644,8 @@ pub fn _mm512_mask_test_epi32_mask(k: __mmask16, a: __m512i, b: __m512i) -> __mm #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmd))] -pub fn _mm256_test_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_test_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_cmpneq_epi32_mask(and, zero) @@ -29279,7 +30658,8 @@ pub fn _mm256_test_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmd))] -pub fn _mm256_mask_test_epi32_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_test_epi32_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_mask_cmpneq_epi32_mask(k, and, zero) @@ -29292,7 +30672,8 @@ pub fn _mm256_mask_test_epi32_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mma #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmd))] -pub fn _mm_test_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_test_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_cmpneq_epi32_mask(and, zero) @@ -29305,7 +30686,8 @@ pub fn _mm_test_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmd))] -pub fn _mm_mask_test_epi32_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_test_epi32_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_mask_cmpneq_epi32_mask(k, and, zero) @@ -29318,7 +30700,8 @@ pub fn _mm_mask_test_epi32_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmq))] -pub fn _mm512_test_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_test_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { let and = _mm512_and_epi64(a, b); let zero = _mm512_setzero_si512(); _mm512_cmpneq_epi64_mask(and, zero) @@ -29331,7 +30714,8 @@ pub fn _mm512_test_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmq))] -pub fn _mm512_mask_test_epi64_mask(k: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_test_epi64_mask(k: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { let and = _mm512_and_epi64(a, b); let zero = _mm512_setzero_si512(); _mm512_mask_cmpneq_epi64_mask(k, and, zero) @@ -29344,7 +30728,8 @@ pub fn _mm512_mask_test_epi64_mask(k: __mmask8, a: __m512i, b: __m512i) -> __mma #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmq))] -pub fn _mm256_test_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_test_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_cmpneq_epi64_mask(and, zero) @@ -29357,7 +30742,8 @@ pub fn _mm256_test_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmq))] -pub fn _mm256_mask_test_epi64_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_test_epi64_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_mask_cmpneq_epi64_mask(k, and, zero) @@ -29370,7 +30756,8 @@ pub fn _mm256_mask_test_epi64_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mma #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmq))] -pub fn _mm_test_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_test_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_cmpneq_epi64_mask(and, zero) @@ -29383,7 +30770,8 @@ pub fn _mm_test_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmq))] -pub fn _mm_mask_test_epi64_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_test_epi64_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_mask_cmpneq_epi64_mask(k, and, zero) @@ -29396,7 +30784,8 @@ pub fn _mm_mask_test_epi64_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmd))] -pub fn _mm512_testn_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_testn_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { let and = _mm512_and_epi32(a, b); let zero = _mm512_setzero_si512(); _mm512_cmpeq_epi32_mask(and, zero) @@ -29409,7 +30798,8 @@ pub fn _mm512_testn_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmd))] -pub fn _mm512_mask_testn_epi32_mask(k: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_testn_epi32_mask(k: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { let and = _mm512_and_epi32(a, b); let zero = _mm512_setzero_si512(); _mm512_mask_cmpeq_epi32_mask(k, and, zero) @@ -29422,7 +30812,8 @@ pub fn _mm512_mask_testn_epi32_mask(k: __mmask16, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmd))] -pub fn _mm256_testn_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_testn_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_cmpeq_epi32_mask(and, zero) @@ -29435,7 +30826,8 @@ pub fn _mm256_testn_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmd))] -pub fn _mm256_mask_testn_epi32_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_testn_epi32_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_mask_cmpeq_epi32_mask(k, and, zero) @@ -29448,7 +30840,8 @@ pub fn _mm256_mask_testn_epi32_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mm #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmd))] -pub fn _mm_testn_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testn_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_cmpeq_epi32_mask(and, zero) @@ -29461,7 +30854,8 @@ pub fn _mm_testn_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmd))] -pub fn _mm_mask_testn_epi32_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_testn_epi32_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_mask_cmpeq_epi32_mask(k, and, zero) @@ -29474,7 +30868,8 @@ pub fn _mm_mask_testn_epi32_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmq))] -pub fn _mm512_testn_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_testn_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { let and = _mm512_and_epi64(a, b); let zero = _mm512_setzero_si512(); _mm512_cmpeq_epi64_mask(and, zero) @@ -29487,7 +30882,8 @@ pub fn _mm512_testn_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmq))] -pub fn _mm512_mask_testn_epi64_mask(k: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_testn_epi64_mask(k: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { let and = _mm512_and_epi64(a, b); let zero = _mm512_setzero_si512(); _mm512_mask_cmpeq_epi64_mask(k, and, zero) @@ -29500,7 +30896,8 @@ pub fn _mm512_mask_testn_epi64_mask(k: __mmask8, a: __m512i, b: __m512i) -> __mm #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmq))] -pub fn _mm256_testn_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_testn_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_cmpeq_epi64_mask(and, zero) @@ -29513,7 +30910,8 @@ pub fn _mm256_testn_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmq))] -pub fn _mm256_mask_testn_epi64_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_testn_epi64_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_mask_cmpeq_epi64_mask(k, and, zero) @@ -29526,7 +30924,8 @@ pub fn _mm256_mask_testn_epi64_mask(k: __mmask8, a: __m256i, b: __m256i) -> __mm #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmq))] -pub fn _mm_testn_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testn_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_cmpeq_epi64_mask(and, zero) @@ -29539,7 +30938,8 @@ pub fn _mm_testn_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmq))] -pub fn _mm_mask_testn_epi64_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_testn_epi64_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_mask_cmpeq_epi64_mask(k, and, zero) @@ -29651,7 +31051,8 @@ pub unsafe fn _mm512_stream_load_si512(mem_addr: *const __m512i) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set_ps( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set_ps( e0: f32, e1: f32, e2: f32, @@ -29681,7 +31082,8 @@ pub fn _mm512_set_ps( #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_setr_ps( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setr_ps( e0: f32, e1: f32, e2: f32, @@ -29713,7 +31115,8 @@ pub fn _mm512_setr_ps( #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set1_pd(a: f64) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set1_pd(a: f64) -> __m512d { unsafe { transmute(f64x8::splat(a)) } } @@ -29723,7 +31126,8 @@ pub fn _mm512_set1_pd(a: f64) -> __m512d { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set1_ps(a: f32) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set1_ps(a: f32) -> __m512 { unsafe { transmute(f32x16::splat(a)) } } @@ -29733,7 +31137,8 @@ pub fn _mm512_set1_ps(a: f32) -> __m512 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set_epi32( e15: i32, e14: i32, e13: i32, @@ -29762,7 +31167,8 @@ pub fn _mm512_set_epi32( #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set1_epi8(a: i8) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set1_epi8(a: i8) -> __m512i { unsafe { transmute(i8x64::splat(a)) } } @@ -29772,7 +31178,8 @@ pub fn _mm512_set1_epi8(a: i8) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set1_epi16(a: i16) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set1_epi16(a: i16) -> __m512i { unsafe { transmute(i16x32::splat(a)) } } @@ -29782,7 +31189,8 @@ pub fn _mm512_set1_epi16(a: i16) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set1_epi32(a: i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set1_epi32(a: i32) -> __m512i { unsafe { transmute(i32x16::splat(a)) } } @@ -29793,7 +31201,8 @@ pub fn _mm512_set1_epi32(a: i32) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastd))] -pub fn _mm512_mask_set1_epi32(src: __m512i, k: __mmask16, a: i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_set1_epi32(src: __m512i, k: __mmask16, a: i32) -> __m512i { unsafe { let r = _mm512_set1_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, r, src.as_i32x16())) @@ -29807,7 +31216,8 @@ pub fn _mm512_mask_set1_epi32(src: __m512i, k: __mmask16, a: i32) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastd))] -pub fn _mm512_maskz_set1_epi32(k: __mmask16, a: i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_set1_epi32(k: __mmask16, a: i32) -> __m512i { unsafe { let r = _mm512_set1_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, r, i32x16::ZERO)) @@ -29821,7 +31231,8 @@ pub fn _mm512_maskz_set1_epi32(k: __mmask16, a: i32) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastd))] -pub fn _mm256_mask_set1_epi32(src: __m256i, k: __mmask8, a: i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_set1_epi32(src: __m256i, k: __mmask8, a: i32) -> __m256i { unsafe { let r = _mm256_set1_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, r, src.as_i32x8())) @@ -29835,7 +31246,8 @@ pub fn _mm256_mask_set1_epi32(src: __m256i, k: __mmask8, a: i32) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastd))] -pub fn _mm256_maskz_set1_epi32(k: __mmask8, a: i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_set1_epi32(k: __mmask8, a: i32) -> __m256i { unsafe { let r = _mm256_set1_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, r, i32x8::ZERO)) @@ -29849,7 +31261,8 @@ pub fn _mm256_maskz_set1_epi32(k: __mmask8, a: i32) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastd))] -pub fn _mm_mask_set1_epi32(src: __m128i, k: __mmask8, a: i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_set1_epi32(src: __m128i, k: __mmask8, a: i32) -> __m128i { unsafe { let r = _mm_set1_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, r, src.as_i32x4())) @@ -29863,7 +31276,8 @@ pub fn _mm_mask_set1_epi32(src: __m128i, k: __mmask8, a: i32) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastd))] -pub fn _mm_maskz_set1_epi32(k: __mmask8, a: i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_set1_epi32(k: __mmask8, a: i32) -> __m128i { unsafe { let r = _mm_set1_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, r, i32x4::ZERO)) @@ -29876,7 +31290,8 @@ pub fn _mm_maskz_set1_epi32(k: __mmask8, a: i32) -> __m128i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set1_epi64(a: i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set1_epi64(a: i64) -> __m512i { unsafe { transmute(i64x8::splat(a)) } } @@ -29887,7 +31302,8 @@ pub fn _mm512_set1_epi64(a: i64) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastq))] -pub fn _mm512_mask_set1_epi64(src: __m512i, k: __mmask8, a: i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_set1_epi64(src: __m512i, k: __mmask8, a: i64) -> __m512i { unsafe { let r = _mm512_set1_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, r, src.as_i64x8())) @@ -29901,7 +31317,8 @@ pub fn _mm512_mask_set1_epi64(src: __m512i, k: __mmask8, a: i64) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastq))] -pub fn _mm512_maskz_set1_epi64(k: __mmask8, a: i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_set1_epi64(k: __mmask8, a: i64) -> __m512i { unsafe { let r = _mm512_set1_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, r, i64x8::ZERO)) @@ -29915,7 +31332,8 @@ pub fn _mm512_maskz_set1_epi64(k: __mmask8, a: i64) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastq))] -pub fn _mm256_mask_set1_epi64(src: __m256i, k: __mmask8, a: i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_set1_epi64(src: __m256i, k: __mmask8, a: i64) -> __m256i { unsafe { let r = _mm256_set1_epi64x(a).as_i64x4(); transmute(simd_select_bitmask(k, r, src.as_i64x4())) @@ -29929,7 +31347,8 @@ pub fn _mm256_mask_set1_epi64(src: __m256i, k: __mmask8, a: i64) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastq))] -pub fn _mm256_maskz_set1_epi64(k: __mmask8, a: i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_set1_epi64(k: __mmask8, a: i64) -> __m256i { unsafe { let r = _mm256_set1_epi64x(a).as_i64x4(); transmute(simd_select_bitmask(k, r, i64x4::ZERO)) @@ -29943,7 +31362,8 @@ pub fn _mm256_maskz_set1_epi64(k: __mmask8, a: i64) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastq))] -pub fn _mm_mask_set1_epi64(src: __m128i, k: __mmask8, a: i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_set1_epi64(src: __m128i, k: __mmask8, a: i64) -> __m128i { unsafe { let r = _mm_set1_epi64x(a).as_i64x2(); transmute(simd_select_bitmask(k, r, src.as_i64x2())) @@ -29957,7 +31377,8 @@ pub fn _mm_mask_set1_epi64(src: __m128i, k: __mmask8, a: i64) -> __m128i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastq))] -pub fn _mm_maskz_set1_epi64(k: __mmask8, a: i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_set1_epi64(k: __mmask8, a: i64) -> __m128i { unsafe { let r = _mm_set1_epi64x(a).as_i64x2(); transmute(simd_select_bitmask(k, r, i64x2::ZERO)) @@ -29970,7 +31391,8 @@ pub fn _mm_maskz_set1_epi64(k: __mmask8, a: i64) -> __m128i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set4_epi64(d: i64, c: i64, b: i64, a: i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set4_epi64(d: i64, c: i64, b: i64, a: i64) -> __m512i { _mm512_set_epi64(d, c, b, a, d, c, b, a) } @@ -29980,7 +31402,8 @@ pub fn _mm512_set4_epi64(d: i64, c: i64, b: i64, a: i64) -> __m512i { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_setr4_epi64(d: i64, c: i64, b: i64, a: i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setr4_epi64(d: i64, c: i64, b: i64, a: i64) -> __m512i { _mm512_set_epi64(a, b, c, d, a, b, c, d) } @@ -30809,7 +32232,8 @@ pub fn _mm_mask_cmp_round_sd_mask( #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_cmplt_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmplt_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_lt(a.as_u32x16(), b.as_u32x16())) } } @@ -30820,7 +32244,8 @@ pub fn _mm512_cmplt_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_mask_cmplt_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmplt_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epu32_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -30831,7 +32256,8 @@ pub fn _mm512_mask_cmplt_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_cmplt_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmplt_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_lt(a.as_u32x8(), b.as_u32x8())) } } @@ -30842,7 +32268,8 @@ pub fn _mm256_cmplt_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_mask_cmplt_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmplt_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu32_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -30853,7 +32280,8 @@ pub fn _mm256_mask_cmplt_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_cmplt_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_lt(a.as_u32x4(), b.as_u32x4())) } } @@ -30864,7 +32292,8 @@ pub fn _mm_cmplt_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_mask_cmplt_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmplt_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu32_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -30875,7 +32304,8 @@ pub fn _mm_mask_cmplt_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_cmpgt_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpgt_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_gt(a.as_u32x16(), b.as_u32x16())) } } @@ -30886,7 +32316,8 @@ pub fn _mm512_cmpgt_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_mask_cmpgt_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpgt_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epu32_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -30897,7 +32328,8 @@ pub fn _mm512_mask_cmpgt_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_cmpgt_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_gt(a.as_u32x8(), b.as_u32x8())) } } @@ -30908,7 +32340,8 @@ pub fn _mm256_cmpgt_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_mask_cmpgt_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpgt_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu32_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -30919,7 +32352,8 @@ pub fn _mm256_mask_cmpgt_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_cmpgt_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_gt(a.as_u32x4(), b.as_u32x4())) } } @@ -30930,7 +32364,8 @@ pub fn _mm_cmpgt_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_mask_cmpgt_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpgt_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu32_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -30941,7 +32376,8 @@ pub fn _mm_mask_cmpgt_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_cmple_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmple_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_le(a.as_u32x16(), b.as_u32x16())) } } @@ -30952,7 +32388,8 @@ pub fn _mm512_cmple_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_mask_cmple_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmple_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epu32_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -30963,7 +32400,8 @@ pub fn _mm512_mask_cmple_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_cmple_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmple_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_le(a.as_u32x8(), b.as_u32x8())) } } @@ -30974,7 +32412,8 @@ pub fn _mm256_cmple_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_mask_cmple_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmple_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu32_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -30985,7 +32424,8 @@ pub fn _mm256_mask_cmple_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_cmple_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmple_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_le(a.as_u32x4(), b.as_u32x4())) } } @@ -30996,7 +32436,8 @@ pub fn _mm_cmple_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_mask_cmple_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmple_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu32_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -31007,7 +32448,8 @@ pub fn _mm_mask_cmple_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_cmpge_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpge_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_ge(a.as_u32x16(), b.as_u32x16())) } } @@ -31018,7 +32460,8 @@ pub fn _mm512_cmpge_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_mask_cmpge_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpge_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epu32_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -31029,7 +32472,8 @@ pub fn _mm512_mask_cmpge_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_cmpge_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpge_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_ge(a.as_u32x8(), b.as_u32x8())) } } @@ -31040,7 +32484,8 @@ pub fn _mm256_cmpge_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_mask_cmpge_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpge_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu32_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -31051,7 +32496,8 @@ pub fn _mm256_mask_cmpge_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_cmpge_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpge_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_ge(a.as_u32x4(), b.as_u32x4())) } } @@ -31062,7 +32508,8 @@ pub fn _mm_cmpge_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_mask_cmpge_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpge_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu32_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -31073,7 +32520,8 @@ pub fn _mm_mask_cmpge_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_cmpeq_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpeq_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_eq(a.as_u32x16(), b.as_u32x16())) } } @@ -31084,7 +32532,8 @@ pub fn _mm512_cmpeq_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_mask_cmpeq_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpeq_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epu32_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -31095,7 +32544,8 @@ pub fn _mm512_mask_cmpeq_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_cmpeq_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_eq(a.as_u32x8(), b.as_u32x8())) } } @@ -31106,7 +32556,8 @@ pub fn _mm256_cmpeq_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_mask_cmpeq_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpeq_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu32_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -31117,7 +32568,8 @@ pub fn _mm256_mask_cmpeq_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_cmpeq_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_eq(a.as_u32x4(), b.as_u32x4())) } } @@ -31128,7 +32580,8 @@ pub fn _mm_cmpeq_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_mask_cmpeq_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpeq_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu32_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -31139,7 +32592,8 @@ pub fn _mm_mask_cmpeq_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_cmpneq_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpneq_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_ne(a.as_u32x16(), b.as_u32x16())) } } @@ -31150,7 +32604,8 @@ pub fn _mm512_cmpneq_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm512_mask_cmpneq_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpneq_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epu32_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -31161,7 +32616,8 @@ pub fn _mm512_mask_cmpneq_epu32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_cmpneq_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpneq_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_ne(a.as_u32x8(), b.as_u32x8())) } } @@ -31172,7 +32628,8 @@ pub fn _mm256_cmpneq_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm256_mask_cmpneq_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpneq_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu32_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -31183,7 +32640,8 @@ pub fn _mm256_mask_cmpneq_epu32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_cmpneq_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpneq_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_ne(a.as_u32x4(), b.as_u32x4())) } } @@ -31194,7 +32652,8 @@ pub fn _mm_cmpneq_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpud -pub fn _mm_mask_cmpneq_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpneq_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu32_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -31206,7 +32665,11 @@ pub fn _mm_mask_cmpneq_epu32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mma #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm512_cmp_epu32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmp_epu32_mask( + a: __m512i, + b: __m512i, +) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_u32x16(); @@ -31233,7 +32696,8 @@ pub fn _mm512_cmp_epu32_mask(a: __m512i, b: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm512_mask_cmp_epu32_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmp_epu32_mask( k1: __mmask16, a: __m512i, b: __m512i, @@ -31265,7 +32729,11 @@ pub fn _mm512_mask_cmp_epu32_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm256_cmp_epu32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmp_epu32_mask( + a: __m256i, + b: __m256i, +) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_u32x8(); @@ -31292,7 +32760,8 @@ pub fn _mm256_cmp_epu32_mask(a: __m256i, b: __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm256_mask_cmp_epu32_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmp_epu32_mask( k1: __mmask8, a: __m256i, b: __m256i, @@ -31324,7 +32793,8 @@ pub fn _mm256_mask_cmp_epu32_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm_cmp_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmp_epu32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_u32x4(); @@ -31351,7 +32821,8 @@ pub fn _mm_cmp_epu32_mask(a: __m128i, b: __m128i) - #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm_mask_cmp_epu32_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmp_epu32_mask( k1: __mmask8, a: __m128i, b: __m128i, @@ -31382,7 +32853,8 @@ pub fn _mm_mask_cmp_epu32_mask( #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_cmplt_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmplt_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_lt(a.as_i32x16(), b.as_i32x16())) } } @@ -31393,7 +32865,8 @@ pub fn _mm512_cmplt_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_mask_cmplt_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmplt_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epi32_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -31404,7 +32877,8 @@ pub fn _mm512_mask_cmplt_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_cmplt_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmplt_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_lt(a.as_i32x8(), b.as_i32x8())) } } @@ -31415,7 +32889,8 @@ pub fn _mm256_cmplt_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_mask_cmplt_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmplt_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi32_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -31426,7 +32901,8 @@ pub fn _mm256_mask_cmplt_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_cmplt_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_lt(a.as_i32x4(), b.as_i32x4())) } } @@ -31437,7 +32913,8 @@ pub fn _mm_cmplt_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_mask_cmplt_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmplt_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi32_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -31448,7 +32925,8 @@ pub fn _mm_mask_cmplt_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_cmpgt_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpgt_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_gt(a.as_i32x16(), b.as_i32x16())) } } @@ -31459,7 +32937,8 @@ pub fn _mm512_cmpgt_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_mask_cmpgt_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpgt_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epi32_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -31470,7 +32949,8 @@ pub fn _mm512_mask_cmpgt_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_cmpgt_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_gt(a.as_i32x8(), b.as_i32x8())) } } @@ -31481,7 +32961,8 @@ pub fn _mm256_cmpgt_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_mask_cmpgt_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpgt_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi32_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -31492,7 +32973,8 @@ pub fn _mm256_mask_cmpgt_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_cmpgt_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_gt(a.as_i32x4(), b.as_i32x4())) } } @@ -31503,7 +32985,8 @@ pub fn _mm_cmpgt_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_mask_cmpgt_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpgt_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi32_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -31514,7 +32997,8 @@ pub fn _mm_mask_cmpgt_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_cmple_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmple_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_le(a.as_i32x16(), b.as_i32x16())) } } @@ -31525,7 +33009,8 @@ pub fn _mm512_cmple_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_mask_cmple_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmple_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epi32_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -31536,7 +33021,8 @@ pub fn _mm512_mask_cmple_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_cmple_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmple_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_le(a.as_i32x8(), b.as_i32x8())) } } @@ -31547,7 +33033,8 @@ pub fn _mm256_cmple_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_mask_cmple_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmple_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi32_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -31558,7 +33045,8 @@ pub fn _mm256_mask_cmple_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_cmple_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmple_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_le(a.as_i32x4(), b.as_i32x4())) } } @@ -31569,7 +33057,8 @@ pub fn _mm_cmple_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_mask_cmple_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmple_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi32_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -31580,7 +33069,8 @@ pub fn _mm_mask_cmple_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_cmpge_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpge_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_ge(a.as_i32x16(), b.as_i32x16())) } } @@ -31591,7 +33081,8 @@ pub fn _mm512_cmpge_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_mask_cmpge_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpge_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epi32_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -31602,7 +33093,8 @@ pub fn _mm512_mask_cmpge_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_cmpge_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpge_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_ge(a.as_i32x8(), b.as_i32x8())) } } @@ -31613,7 +33105,8 @@ pub fn _mm256_cmpge_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_mask_cmpge_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpge_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi32_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -31624,7 +33117,8 @@ pub fn _mm256_mask_cmpge_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_cmpge_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpge_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_ge(a.as_i32x4(), b.as_i32x4())) } } @@ -31635,7 +33129,8 @@ pub fn _mm_cmpge_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_mask_cmpge_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpge_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi32_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -31646,7 +33141,8 @@ pub fn _mm_mask_cmpge_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_cmpeq_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpeq_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_eq(a.as_i32x16(), b.as_i32x16())) } } @@ -31657,7 +33153,8 @@ pub fn _mm512_cmpeq_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_mask_cmpeq_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpeq_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epi32_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -31668,7 +33165,8 @@ pub fn _mm512_mask_cmpeq_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_cmpeq_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_eq(a.as_i32x8(), b.as_i32x8())) } } @@ -31679,7 +33177,8 @@ pub fn _mm256_cmpeq_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_mask_cmpeq_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpeq_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi32_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -31690,7 +33189,8 @@ pub fn _mm256_mask_cmpeq_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_cmpeq_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_eq(a.as_i32x4(), b.as_i32x4())) } } @@ -31701,7 +33201,8 @@ pub fn _mm_cmpeq_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_mask_cmpeq_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpeq_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi32_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -31712,7 +33213,8 @@ pub fn _mm_mask_cmpeq_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_cmpneq_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpneq_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { unsafe { simd_bitmask::(simd_ne(a.as_i32x16(), b.as_i32x16())) } } @@ -31723,7 +33225,8 @@ pub fn _mm512_cmpneq_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm512_mask_cmpneq_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpneq_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> __mmask16 { _mm512_mask_cmp_epi32_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -31734,7 +33237,8 @@ pub fn _mm512_mask_cmpneq_epi32_mask(k1: __mmask16, a: __m512i, b: __m512i) -> _ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_cmpneq_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpneq_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::(simd_ne(a.as_i32x8(), b.as_i32x8())) } } @@ -31745,7 +33249,8 @@ pub fn _mm256_cmpneq_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm256_mask_cmpneq_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpneq_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi32_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -31756,7 +33261,8 @@ pub fn _mm256_mask_cmpneq_epi32_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_cmpneq_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpneq_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_ne(a.as_i32x4(), b.as_i32x4())) } } @@ -31767,7 +33273,8 @@ pub fn _mm_cmpneq_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpd -pub fn _mm_mask_cmpneq_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpneq_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi32_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -31779,7 +33286,11 @@ pub fn _mm_mask_cmpneq_epi32_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mma #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm512_cmp_epi32_mask(a: __m512i, b: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmp_epi32_mask( + a: __m512i, + b: __m512i, +) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_i32x16(); @@ -31806,7 +33317,8 @@ pub fn _mm512_cmp_epi32_mask(a: __m512i, b: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm512_mask_cmp_epi32_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmp_epi32_mask( k1: __mmask16, a: __m512i, b: __m512i, @@ -31838,7 +33350,11 @@ pub fn _mm512_mask_cmp_epi32_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm256_cmp_epi32_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmp_epi32_mask( + a: __m256i, + b: __m256i, +) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_i32x8(); @@ -31865,7 +33381,8 @@ pub fn _mm256_cmp_epi32_mask(a: __m256i, b: __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm256_mask_cmp_epi32_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmp_epi32_mask( k1: __mmask8, a: __m256i, b: __m256i, @@ -31897,7 +33414,8 @@ pub fn _mm256_mask_cmp_epi32_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm_cmp_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmp_epi32_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_i32x4(); @@ -31924,7 +33442,8 @@ pub fn _mm_cmp_epi32_mask(a: __m128i, b: __m128i) - #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm_mask_cmp_epi32_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmp_epi32_mask( k1: __mmask8, a: __m128i, b: __m128i, @@ -31955,7 +33474,8 @@ pub fn _mm_mask_cmp_epi32_mask( #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_cmplt_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmplt_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_lt(a.as_u64x8(), b.as_u64x8())) } } @@ -31966,7 +33486,8 @@ pub fn _mm512_cmplt_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_mask_cmplt_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmplt_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epu64_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -31977,7 +33498,8 @@ pub fn _mm512_mask_cmplt_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_cmplt_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmplt_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_lt(a.as_u64x4(), b.as_u64x4())) } } @@ -31988,7 +33510,8 @@ pub fn _mm256_cmplt_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_mask_cmplt_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmplt_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu64_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -31999,7 +33522,8 @@ pub fn _mm256_mask_cmplt_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_cmplt_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_lt(a.as_u64x2(), b.as_u64x2())) } } @@ -32010,7 +33534,8 @@ pub fn _mm_cmplt_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_mask_cmplt_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmplt_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu64_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -32021,7 +33546,8 @@ pub fn _mm_mask_cmplt_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_cmpgt_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpgt_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_gt(a.as_u64x8(), b.as_u64x8())) } } @@ -32032,7 +33558,8 @@ pub fn _mm512_cmpgt_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_mask_cmpgt_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpgt_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epu64_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -32043,7 +33570,8 @@ pub fn _mm512_mask_cmpgt_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_cmpgt_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_gt(a.as_u64x4(), b.as_u64x4())) } } @@ -32054,7 +33582,8 @@ pub fn _mm256_cmpgt_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_mask_cmpgt_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpgt_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu64_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -32065,7 +33594,8 @@ pub fn _mm256_mask_cmpgt_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_cmpgt_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_gt(a.as_u64x2(), b.as_u64x2())) } } @@ -32076,7 +33606,8 @@ pub fn _mm_cmpgt_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_mask_cmpgt_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpgt_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu64_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -32087,7 +33618,8 @@ pub fn _mm_mask_cmpgt_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_cmple_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmple_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_le(a.as_u64x8(), b.as_u64x8())) } } @@ -32098,7 +33630,8 @@ pub fn _mm512_cmple_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_mask_cmple_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmple_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epu64_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -32109,7 +33642,8 @@ pub fn _mm512_mask_cmple_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_cmple_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmple_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_le(a.as_u64x4(), b.as_u64x4())) } } @@ -32120,7 +33654,8 @@ pub fn _mm256_cmple_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_mask_cmple_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmple_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu64_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -32131,7 +33666,8 @@ pub fn _mm256_mask_cmple_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_cmple_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmple_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_le(a.as_u64x2(), b.as_u64x2())) } } @@ -32142,7 +33678,8 @@ pub fn _mm_cmple_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_mask_cmple_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmple_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu64_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -32153,7 +33690,8 @@ pub fn _mm_mask_cmple_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_cmpge_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpge_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_ge(a.as_u64x8(), b.as_u64x8())) } } @@ -32164,7 +33702,8 @@ pub fn _mm512_cmpge_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_mask_cmpge_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpge_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epu64_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -32175,7 +33714,8 @@ pub fn _mm512_mask_cmpge_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_cmpge_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpge_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_ge(a.as_u64x4(), b.as_u64x4())) } } @@ -32186,7 +33726,8 @@ pub fn _mm256_cmpge_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_mask_cmpge_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpge_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu64_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -32197,7 +33738,8 @@ pub fn _mm256_mask_cmpge_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_cmpge_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpge_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_ge(a.as_u64x2(), b.as_u64x2())) } } @@ -32208,7 +33750,8 @@ pub fn _mm_cmpge_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_mask_cmpge_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpge_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu64_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -32219,7 +33762,8 @@ pub fn _mm_mask_cmpge_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_cmpeq_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpeq_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_eq(a.as_u64x8(), b.as_u64x8())) } } @@ -32230,7 +33774,8 @@ pub fn _mm512_cmpeq_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_mask_cmpeq_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpeq_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epu64_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -32241,7 +33786,8 @@ pub fn _mm512_mask_cmpeq_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_cmpeq_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_eq(a.as_u64x4(), b.as_u64x4())) } } @@ -32252,7 +33798,8 @@ pub fn _mm256_cmpeq_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_mask_cmpeq_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpeq_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu64_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -32263,7 +33810,8 @@ pub fn _mm256_mask_cmpeq_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_cmpeq_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_eq(a.as_u64x2(), b.as_u64x2())) } } @@ -32274,7 +33822,8 @@ pub fn _mm_cmpeq_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_mask_cmpeq_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpeq_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu64_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -32285,7 +33834,8 @@ pub fn _mm_mask_cmpeq_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_cmpneq_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpneq_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_ne(a.as_u64x8(), b.as_u64x8())) } } @@ -32296,7 +33846,8 @@ pub fn _mm512_cmpneq_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm512_mask_cmpneq_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpneq_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epu64_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -32307,7 +33858,8 @@ pub fn _mm512_mask_cmpneq_epu64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_cmpneq_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpneq_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_ne(a.as_u64x4(), b.as_u64x4())) } } @@ -32318,7 +33870,8 @@ pub fn _mm256_cmpneq_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm256_mask_cmpneq_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpneq_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epu64_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -32329,7 +33882,8 @@ pub fn _mm256_mask_cmpneq_epu64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_cmpneq_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpneq_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_ne(a.as_u64x2(), b.as_u64x2())) } } @@ -32340,7 +33894,8 @@ pub fn _mm_cmpneq_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpuq -pub fn _mm_mask_cmpneq_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpneq_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu64_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -32352,7 +33907,11 @@ pub fn _mm_mask_cmpneq_epu64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mma #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm512_cmp_epu64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmp_epu64_mask( + a: __m512i, + b: __m512i, +) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_u64x8(); @@ -32379,7 +33938,8 @@ pub fn _mm512_cmp_epu64_mask(a: __m512i, b: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm512_mask_cmp_epu64_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmp_epu64_mask( k1: __mmask8, a: __m512i, b: __m512i, @@ -32411,7 +33971,11 @@ pub fn _mm512_mask_cmp_epu64_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm256_cmp_epu64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmp_epu64_mask( + a: __m256i, + b: __m256i, +) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_u64x4(); @@ -32438,7 +34002,8 @@ pub fn _mm256_cmp_epu64_mask(a: __m256i, b: __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm256_mask_cmp_epu64_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmp_epu64_mask( k1: __mmask8, a: __m256i, b: __m256i, @@ -32470,7 +34035,8 @@ pub fn _mm256_mask_cmp_epu64_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm_cmp_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmp_epu64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_u64x2(); @@ -32497,7 +34063,8 @@ pub fn _mm_cmp_epu64_mask(a: __m128i, b: __m128i) - #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm_mask_cmp_epu64_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmp_epu64_mask( k1: __mmask8, a: __m128i, b: __m128i, @@ -32528,7 +34095,8 @@ pub fn _mm_mask_cmp_epu64_mask( #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_cmplt_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmplt_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_lt(a.as_i64x8(), b.as_i64x8())) } } @@ -32539,7 +34107,8 @@ pub fn _mm512_cmplt_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_mask_cmplt_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmplt_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epi64_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -32550,7 +34119,8 @@ pub fn _mm512_mask_cmplt_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_cmplt_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmplt_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_lt(a.as_i64x4(), b.as_i64x4())) } } @@ -32561,7 +34131,8 @@ pub fn _mm256_cmplt_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_mask_cmplt_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmplt_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi64_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -32572,7 +34143,8 @@ pub fn _mm256_mask_cmplt_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_cmplt_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_lt(a.as_i64x2(), b.as_i64x2())) } } @@ -32583,7 +34155,8 @@ pub fn _mm_cmplt_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_mask_cmplt_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmplt_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi64_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -32594,7 +34167,8 @@ pub fn _mm_mask_cmplt_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_cmpgt_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpgt_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_gt(a.as_i64x8(), b.as_i64x8())) } } @@ -32605,7 +34179,8 @@ pub fn _mm512_cmpgt_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_mask_cmpgt_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpgt_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epi64_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -32616,7 +34191,8 @@ pub fn _mm512_mask_cmpgt_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_cmpgt_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_gt(a.as_i64x4(), b.as_i64x4())) } } @@ -32627,7 +34203,8 @@ pub fn _mm256_cmpgt_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_mask_cmpgt_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpgt_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi64_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -32638,7 +34215,8 @@ pub fn _mm256_mask_cmpgt_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_cmpgt_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_gt(a.as_i64x2(), b.as_i64x2())) } } @@ -32649,7 +34227,8 @@ pub fn _mm_cmpgt_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_mask_cmpgt_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpgt_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi64_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -32660,7 +34239,8 @@ pub fn _mm_mask_cmpgt_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_cmple_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmple_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_le(a.as_i64x8(), b.as_i64x8())) } } @@ -32671,7 +34251,8 @@ pub fn _mm512_cmple_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_mask_cmple_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmple_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epi64_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -32682,7 +34263,8 @@ pub fn _mm512_mask_cmple_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_cmple_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmple_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_le(a.as_i64x4(), b.as_i64x4())) } } @@ -32693,7 +34275,8 @@ pub fn _mm256_cmple_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_mask_cmple_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmple_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi64_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -32704,7 +34287,8 @@ pub fn _mm256_mask_cmple_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_cmple_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmple_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_le(a.as_i64x2(), b.as_i64x2())) } } @@ -32715,7 +34299,8 @@ pub fn _mm_cmple_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_mask_cmple_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmple_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi64_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -32726,7 +34311,8 @@ pub fn _mm_mask_cmple_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_cmpge_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpge_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_ge(a.as_i64x8(), b.as_i64x8())) } } @@ -32737,7 +34323,8 @@ pub fn _mm512_cmpge_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_mask_cmpge_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpge_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epi64_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -32748,7 +34335,8 @@ pub fn _mm512_mask_cmpge_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_cmpge_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpge_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_ge(a.as_i64x4(), b.as_i64x4())) } } @@ -32759,7 +34347,8 @@ pub fn _mm256_cmpge_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_mask_cmpge_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpge_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi64_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -32770,7 +34359,8 @@ pub fn _mm256_mask_cmpge_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_cmpge_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpge_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_ge(a.as_i64x2(), b.as_i64x2())) } } @@ -32781,7 +34371,8 @@ pub fn _mm_cmpge_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_mask_cmpge_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpge_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi64_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -32792,7 +34383,8 @@ pub fn _mm_mask_cmpge_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_cmpeq_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpeq_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_eq(a.as_i64x8(), b.as_i64x8())) } } @@ -32803,7 +34395,8 @@ pub fn _mm512_cmpeq_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_mask_cmpeq_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpeq_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epi64_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -32814,7 +34407,8 @@ pub fn _mm512_mask_cmpeq_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_cmpeq_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_eq(a.as_i64x4(), b.as_i64x4())) } } @@ -32825,7 +34419,8 @@ pub fn _mm256_cmpeq_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_mask_cmpeq_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpeq_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi64_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -32836,7 +34431,8 @@ pub fn _mm256_mask_cmpeq_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_cmpeq_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_eq(a.as_i64x2(), b.as_i64x2())) } } @@ -32847,7 +34443,8 @@ pub fn _mm_cmpeq_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_mask_cmpeq_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpeq_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi64_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -32858,7 +34455,8 @@ pub fn _mm_mask_cmpeq_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_cmpneq_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpneq_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { unsafe { simd_bitmask::<__m512i, _>(simd_ne(a.as_i64x8(), b.as_i64x8())) } } @@ -32869,7 +34467,8 @@ pub fn _mm512_cmpneq_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm512_mask_cmpneq_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpneq_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __mmask8 { _mm512_mask_cmp_epi64_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -32880,7 +34479,8 @@ pub fn _mm512_mask_cmpneq_epi64_mask(k1: __mmask8, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_cmpneq_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpneq_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { unsafe { simd_bitmask::<__m256i, _>(simd_ne(a.as_i64x4(), b.as_i64x4())) } } @@ -32891,7 +34491,8 @@ pub fn _mm256_cmpneq_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm256_mask_cmpneq_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpneq_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __mmask8 { _mm256_mask_cmp_epi64_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -32902,7 +34503,8 @@ pub fn _mm256_mask_cmpneq_epi64_mask(k1: __mmask8, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_cmpneq_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpneq_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::<__m128i, _>(simd_ne(a.as_i64x2(), b.as_i64x2())) } } @@ -32913,7 +34515,8 @@ pub fn _mm_cmpneq_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] //should be vpcmpq -pub fn _mm_mask_cmpneq_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpneq_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi64_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -32925,7 +34528,11 @@ pub fn _mm_mask_cmpneq_epi64_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mma #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm512_cmp_epi64_mask(a: __m512i, b: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmp_epi64_mask( + a: __m512i, + b: __m512i, +) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_i64x8(); @@ -32952,7 +34559,8 @@ pub fn _mm512_cmp_epi64_mask(a: __m512i, b: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm512_mask_cmp_epi64_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmp_epi64_mask( k1: __mmask8, a: __m512i, b: __m512i, @@ -32984,7 +34592,11 @@ pub fn _mm512_mask_cmp_epi64_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm256_cmp_epi64_mask(a: __m256i, b: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmp_epi64_mask( + a: __m256i, + b: __m256i, +) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_i64x4(); @@ -33011,7 +34623,8 @@ pub fn _mm256_cmp_epi64_mask(a: __m256i, b: __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm256_mask_cmp_epi64_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmp_epi64_mask( k1: __mmask8, a: __m256i, b: __m256i, @@ -33043,7 +34656,8 @@ pub fn _mm256_mask_cmp_epi64_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm_cmp_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmp_epi64_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM3, 3); let a = a.as_i64x2(); @@ -33070,7 +34684,8 @@ pub fn _mm_cmp_epi64_mask(a: __m128i, b: __m128i) - #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM3 = 0))] -pub fn _mm_mask_cmp_epi64_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmp_epi64_mask( k1: __mmask8, a: __m128i, b: __m128i, @@ -33100,7 +34715,8 @@ pub fn _mm_mask_cmp_epi64_mask( #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_add_epi32(a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_add_epi32(a: __m512i) -> i32 { unsafe { simd_reduce_add_ordered(a.as_i32x16(), 0) } } @@ -33110,7 +34726,8 @@ pub fn _mm512_reduce_add_epi32(a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_add_epi32(k: __mmask16, a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_add_epi32(k: __mmask16, a: __m512i) -> i32 { unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i32x16(), i32x16::ZERO), 0) } } @@ -33120,7 +34737,8 @@ pub fn _mm512_mask_reduce_add_epi32(k: __mmask16, a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_add_epi64(a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_add_epi64(a: __m512i) -> i64 { unsafe { simd_reduce_add_ordered(a.as_i64x8(), 0) } } @@ -33130,7 +34748,8 @@ pub fn _mm512_reduce_add_epi64(a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_add_epi64(k: __mmask8, a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_add_epi64(k: __mmask8, a: __m512i) -> i64 { unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i64x8(), i64x8::ZERO), 0) } } @@ -33140,7 +34759,8 @@ pub fn _mm512_mask_reduce_add_epi64(k: __mmask8, a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_add_ps(a: __m512) -> f32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_add_ps(a: __m512) -> f32 { unsafe { // we have to use `simd_shuffle` here because `_mm512_extractf32x8_ps` is in AVX512DQ let a = _mm256_add_ps( @@ -33159,7 +34779,8 @@ pub fn _mm512_reduce_add_ps(a: __m512) -> f32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_add_ps(k: __mmask16, a: __m512) -> f32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_add_ps(k: __mmask16, a: __m512) -> f32 { unsafe { _mm512_reduce_add_ps(simd_select_bitmask(k, a, _mm512_setzero_ps())) } } @@ -33169,7 +34790,8 @@ pub fn _mm512_mask_reduce_add_ps(k: __mmask16, a: __m512) -> f32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_add_pd(a: __m512d) -> f64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_add_pd(a: __m512d) -> f64 { unsafe { let a = _mm256_add_pd( _mm512_extractf64x4_pd::<0>(a), @@ -33186,7 +34808,8 @@ pub fn _mm512_reduce_add_pd(a: __m512d) -> f64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_add_pd(k: __mmask8, a: __m512d) -> f64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_add_pd(k: __mmask8, a: __m512d) -> f64 { unsafe { _mm512_reduce_add_pd(simd_select_bitmask(k, a, _mm512_setzero_pd())) } } @@ -33196,7 +34819,8 @@ pub fn _mm512_mask_reduce_add_pd(k: __mmask8, a: __m512d) -> f64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_mul_epi32(a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_mul_epi32(a: __m512i) -> i32 { unsafe { simd_reduce_mul_ordered(a.as_i32x16(), 1) } } @@ -33206,7 +34830,8 @@ pub fn _mm512_reduce_mul_epi32(a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_mul_epi32(k: __mmask16, a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_mul_epi32(k: __mmask16, a: __m512i) -> i32 { unsafe { simd_reduce_mul_ordered( simd_select_bitmask(k, a.as_i32x16(), _mm512_set1_epi32(1).as_i32x16()), @@ -33221,7 +34846,8 @@ pub fn _mm512_mask_reduce_mul_epi32(k: __mmask16, a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_mul_epi64(a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_mul_epi64(a: __m512i) -> i64 { unsafe { simd_reduce_mul_ordered(a.as_i64x8(), 1) } } @@ -33231,7 +34857,8 @@ pub fn _mm512_reduce_mul_epi64(a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_mul_epi64(k: __mmask8, a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_mul_epi64(k: __mmask8, a: __m512i) -> i64 { unsafe { simd_reduce_mul_ordered( simd_select_bitmask(k, a.as_i64x8(), _mm512_set1_epi64(1).as_i64x8()), @@ -33246,7 +34873,8 @@ pub fn _mm512_mask_reduce_mul_epi64(k: __mmask8, a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_mul_ps(a: __m512) -> f32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_mul_ps(a: __m512) -> f32 { unsafe { // we have to use `simd_shuffle` here because `_mm512_extractf32x8_ps` is in AVX512DQ let a = _mm256_mul_ps( @@ -33265,7 +34893,8 @@ pub fn _mm512_reduce_mul_ps(a: __m512) -> f32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_mul_ps(k: __mmask16, a: __m512) -> f32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_mul_ps(k: __mmask16, a: __m512) -> f32 { unsafe { _mm512_reduce_mul_ps(simd_select_bitmask(k, a, _mm512_set1_ps(1.))) } } @@ -33275,7 +34904,8 @@ pub fn _mm512_mask_reduce_mul_ps(k: __mmask16, a: __m512) -> f32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_mul_pd(a: __m512d) -> f64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_mul_pd(a: __m512d) -> f64 { unsafe { let a = _mm256_mul_pd( _mm512_extractf64x4_pd::<0>(a), @@ -33292,7 +34922,8 @@ pub fn _mm512_reduce_mul_pd(a: __m512d) -> f64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_mul_pd(k: __mmask8, a: __m512d) -> f64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_mul_pd(k: __mmask8, a: __m512d) -> f64 { unsafe { _mm512_reduce_mul_pd(simd_select_bitmask(k, a, _mm512_set1_pd(1.))) } } @@ -33302,7 +34933,8 @@ pub fn _mm512_mask_reduce_mul_pd(k: __mmask8, a: __m512d) -> f64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_max_epi32(a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_max_epi32(a: __m512i) -> i32 { unsafe { simd_reduce_max(a.as_i32x16()) } } @@ -33312,7 +34944,8 @@ pub fn _mm512_reduce_max_epi32(a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_max_epi32(k: __mmask16, a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_max_epi32(k: __mmask16, a: __m512i) -> i32 { unsafe { simd_reduce_max(simd_select_bitmask( k, @@ -33328,7 +34961,8 @@ pub fn _mm512_mask_reduce_max_epi32(k: __mmask16, a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_max_epi64(a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_max_epi64(a: __m512i) -> i64 { unsafe { simd_reduce_max(a.as_i64x8()) } } @@ -33338,7 +34972,8 @@ pub fn _mm512_reduce_max_epi64(a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_max_epi64(k: __mmask8, a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_max_epi64(k: __mmask8, a: __m512i) -> i64 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_i64x8(), i64x8::splat(i64::MIN))) } } @@ -33348,7 +34983,8 @@ pub fn _mm512_mask_reduce_max_epi64(k: __mmask8, a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_max_epu32(a: __m512i) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_max_epu32(a: __m512i) -> u32 { unsafe { simd_reduce_max(a.as_u32x16()) } } @@ -33358,7 +34994,8 @@ pub fn _mm512_reduce_max_epu32(a: __m512i) -> u32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_max_epu32(k: __mmask16, a: __m512i) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_max_epu32(k: __mmask16, a: __m512i) -> u32 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_u32x16(), u32x16::ZERO)) } } @@ -33368,7 +35005,8 @@ pub fn _mm512_mask_reduce_max_epu32(k: __mmask16, a: __m512i) -> u32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_max_epu64(a: __m512i) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_max_epu64(a: __m512i) -> u64 { unsafe { simd_reduce_max(a.as_u64x8()) } } @@ -33378,7 +35016,8 @@ pub fn _mm512_reduce_max_epu64(a: __m512i) -> u64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_max_epu64(k: __mmask8, a: __m512i) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_max_epu64(k: __mmask8, a: __m512i) -> u64 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_u64x8(), u64x8::ZERO)) } } @@ -33443,7 +35082,8 @@ pub fn _mm512_mask_reduce_max_pd(k: __mmask8, a: __m512d) -> f64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_min_epi32(a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_min_epi32(a: __m512i) -> i32 { unsafe { simd_reduce_min(a.as_i32x16()) } } @@ -33453,7 +35093,8 @@ pub fn _mm512_reduce_min_epi32(a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_min_epi32(k: __mmask16, a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_min_epi32(k: __mmask16, a: __m512i) -> i32 { unsafe { simd_reduce_min(simd_select_bitmask( k, @@ -33469,7 +35110,8 @@ pub fn _mm512_mask_reduce_min_epi32(k: __mmask16, a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_min_epi64(a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_min_epi64(a: __m512i) -> i64 { unsafe { simd_reduce_min(a.as_i64x8()) } } @@ -33479,7 +35121,8 @@ pub fn _mm512_reduce_min_epi64(a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_min_epi64(k: __mmask8, a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_min_epi64(k: __mmask8, a: __m512i) -> i64 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_i64x8(), i64x8::splat(i64::MAX))) } } @@ -33489,7 +35132,8 @@ pub fn _mm512_mask_reduce_min_epi64(k: __mmask8, a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_min_epu32(a: __m512i) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_min_epu32(a: __m512i) -> u32 { unsafe { simd_reduce_min(a.as_u32x16()) } } @@ -33499,7 +35143,8 @@ pub fn _mm512_reduce_min_epu32(a: __m512i) -> u32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_min_epu32(k: __mmask16, a: __m512i) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_min_epu32(k: __mmask16, a: __m512i) -> u32 { unsafe { simd_reduce_min(simd_select_bitmask( k, @@ -33515,7 +35160,8 @@ pub fn _mm512_mask_reduce_min_epu32(k: __mmask16, a: __m512i) -> u32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_min_epu64(a: __m512i) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_min_epu64(a: __m512i) -> u64 { unsafe { simd_reduce_min(a.as_u64x8()) } } @@ -33525,7 +35171,8 @@ pub fn _mm512_reduce_min_epu64(a: __m512i) -> u64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_min_epu64(k: __mmask8, a: __m512i) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_min_epu64(k: __mmask8, a: __m512i) -> u64 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_u64x8(), u64x8::splat(u64::MAX))) } } @@ -33590,7 +35237,8 @@ pub fn _mm512_mask_reduce_min_pd(k: __mmask8, a: __m512d) -> f64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_and_epi32(a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_and_epi32(a: __m512i) -> i32 { unsafe { simd_reduce_and(a.as_i32x16()) } } @@ -33600,7 +35248,8 @@ pub fn _mm512_reduce_and_epi32(a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_and_epi32(k: __mmask16, a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_and_epi32(k: __mmask16, a: __m512i) -> i32 { unsafe { simd_reduce_and(simd_select_bitmask(k, a.as_i32x16(), i32x16::splat(-1))) } } @@ -33610,7 +35259,8 @@ pub fn _mm512_mask_reduce_and_epi32(k: __mmask16, a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_and_epi64(a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_and_epi64(a: __m512i) -> i64 { unsafe { simd_reduce_and(a.as_i64x8()) } } @@ -33620,7 +35270,8 @@ pub fn _mm512_reduce_and_epi64(a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_and_epi64(k: __mmask8, a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_and_epi64(k: __mmask8, a: __m512i) -> i64 { unsafe { simd_reduce_and(simd_select_bitmask(k, a.as_i64x8(), i64x8::splat(-1))) } } @@ -33630,7 +35281,8 @@ pub fn _mm512_mask_reduce_and_epi64(k: __mmask8, a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_or_epi32(a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_or_epi32(a: __m512i) -> i32 { unsafe { simd_reduce_or(a.as_i32x16()) } } @@ -33640,7 +35292,8 @@ pub fn _mm512_reduce_or_epi32(a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_or_epi32(k: __mmask16, a: __m512i) -> i32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_or_epi32(k: __mmask16, a: __m512i) -> i32 { unsafe { simd_reduce_or(simd_select_bitmask(k, a.as_i32x16(), i32x16::ZERO)) } } @@ -33650,7 +35303,8 @@ pub fn _mm512_mask_reduce_or_epi32(k: __mmask16, a: __m512i) -> i32 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_reduce_or_epi64(a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_or_epi64(a: __m512i) -> i64 { unsafe { simd_reduce_or(a.as_i64x8()) } } @@ -33660,7 +35314,8 @@ pub fn _mm512_reduce_or_epi64(a: __m512i) -> i64 { #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_reduce_or_epi64(k: __mmask8, a: __m512i) -> i64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_reduce_or_epi64(k: __mmask8, a: __m512i) -> i64 { unsafe { simd_reduce_or(simd_select_bitmask(k, a.as_i64x8(), i64x8::ZERO)) } } @@ -33674,7 +35329,8 @@ pub fn _mm512_mask_reduce_or_epi64(k: __mmask8, a: __m512i) -> i64 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] // This intrinsic has no corresponding instruction. -pub fn _mm512_undefined_pd() -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_undefined_pd() -> __m512d { unsafe { const { mem::zeroed() } } } @@ -33688,7 +35344,8 @@ pub fn _mm512_undefined_pd() -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] // This intrinsic has no corresponding instruction. -pub fn _mm512_undefined_ps() -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_undefined_ps() -> __m512 { unsafe { const { mem::zeroed() } } } @@ -33702,7 +35359,8 @@ pub fn _mm512_undefined_ps() -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] // This intrinsic has no corresponding instruction. -pub fn _mm512_undefined_epi32() -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_undefined_epi32() -> __m512i { unsafe { const { mem::zeroed() } } } @@ -33716,7 +35374,8 @@ pub fn _mm512_undefined_epi32() -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] // This intrinsic has no corresponding instruction. -pub fn _mm512_undefined() -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_undefined() -> __m512 { unsafe { const { mem::zeroed() } } } @@ -33727,7 +35386,8 @@ pub fn _mm512_undefined() -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu32 -pub unsafe fn _mm512_loadu_epi32(mem_addr: *const i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_loadu_epi32(mem_addr: *const i32) -> __m512i { ptr::read_unaligned(mem_addr as *const __m512i) } @@ -33738,7 +35398,8 @@ pub unsafe fn _mm512_loadu_epi32(mem_addr: *const i32) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu32 -pub unsafe fn _mm256_loadu_epi32(mem_addr: *const i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu_epi32(mem_addr: *const i32) -> __m256i { ptr::read_unaligned(mem_addr as *const __m256i) } @@ -33749,7 +35410,8 @@ pub unsafe fn _mm256_loadu_epi32(mem_addr: *const i32) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu32 -pub unsafe fn _mm_loadu_epi32(mem_addr: *const i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_epi32(mem_addr: *const i32) -> __m128i { ptr::read_unaligned(mem_addr as *const __m128i) } @@ -34255,7 +35917,8 @@ pub unsafe fn _mm_mask_cvtusepi64_storeu_epi32(mem_addr: *mut i32, k: __mmask8, #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu32 -pub unsafe fn _mm512_storeu_epi32(mem_addr: *mut i32, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_storeu_epi32(mem_addr: *mut i32, a: __m512i) { ptr::write_unaligned(mem_addr as *mut __m512i, a); } @@ -34266,7 +35929,8 @@ pub unsafe fn _mm512_storeu_epi32(mem_addr: *mut i32, a: __m512i) { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu32 -pub unsafe fn _mm256_storeu_epi32(mem_addr: *mut i32, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu_epi32(mem_addr: *mut i32, a: __m256i) { ptr::write_unaligned(mem_addr as *mut __m256i, a); } @@ -34277,7 +35941,8 @@ pub unsafe fn _mm256_storeu_epi32(mem_addr: *mut i32, a: __m256i) { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu32 -pub unsafe fn _mm_storeu_epi32(mem_addr: *mut i32, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_epi32(mem_addr: *mut i32, a: __m128i) { ptr::write_unaligned(mem_addr as *mut __m128i, a); } @@ -34288,7 +35953,8 @@ pub unsafe fn _mm_storeu_epi32(mem_addr: *mut i32, a: __m128i) { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu64 -pub unsafe fn _mm512_loadu_epi64(mem_addr: *const i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_loadu_epi64(mem_addr: *const i64) -> __m512i { ptr::read_unaligned(mem_addr as *const __m512i) } @@ -34299,7 +35965,8 @@ pub unsafe fn _mm512_loadu_epi64(mem_addr: *const i64) -> __m512i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu64 -pub unsafe fn _mm256_loadu_epi64(mem_addr: *const i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu_epi64(mem_addr: *const i64) -> __m256i { ptr::read_unaligned(mem_addr as *const __m256i) } @@ -34310,7 +35977,8 @@ pub unsafe fn _mm256_loadu_epi64(mem_addr: *const i64) -> __m256i { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu64 -pub unsafe fn _mm_loadu_epi64(mem_addr: *const i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_epi64(mem_addr: *const i64) -> __m128i { ptr::read_unaligned(mem_addr as *const __m128i) } @@ -34321,7 +35989,8 @@ pub unsafe fn _mm_loadu_epi64(mem_addr: *const i64) -> __m128i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu64 -pub unsafe fn _mm512_storeu_epi64(mem_addr: *mut i64, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_storeu_epi64(mem_addr: *mut i64, a: __m512i) { ptr::write_unaligned(mem_addr as *mut __m512i, a); } @@ -34332,7 +36001,8 @@ pub unsafe fn _mm512_storeu_epi64(mem_addr: *mut i64, a: __m512i) { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu64 -pub unsafe fn _mm256_storeu_epi64(mem_addr: *mut i64, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu_epi64(mem_addr: *mut i64, a: __m256i) { ptr::write_unaligned(mem_addr as *mut __m256i, a); } @@ -34343,7 +36013,8 @@ pub unsafe fn _mm256_storeu_epi64(mem_addr: *mut i64, a: __m256i) { #[target_feature(enable = "avx512f,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu64 -pub unsafe fn _mm_storeu_epi64(mem_addr: *mut i64, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_epi64(mem_addr: *mut i64, a: __m128i) { ptr::write_unaligned(mem_addr as *mut __m128i, a); } @@ -34354,7 +36025,8 @@ pub unsafe fn _mm_storeu_epi64(mem_addr: *mut i64, a: __m128i) { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu32 -pub unsafe fn _mm512_loadu_si512(mem_addr: *const __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_loadu_si512(mem_addr: *const __m512i) -> __m512i { ptr::read_unaligned(mem_addr) } @@ -34365,7 +36037,8 @@ pub unsafe fn _mm512_loadu_si512(mem_addr: *const __m512i) -> __m512i { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu32 -pub unsafe fn _mm512_storeu_si512(mem_addr: *mut __m512i, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_storeu_si512(mem_addr: *mut __m512i, a: __m512i) { ptr::write_unaligned(mem_addr, a); } @@ -34378,7 +36051,8 @@ pub unsafe fn _mm512_storeu_si512(mem_addr: *mut __m512i, a: __m512i) { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] -pub unsafe fn _mm512_loadu_pd(mem_addr: *const f64) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_loadu_pd(mem_addr: *const f64) -> __m512d { ptr::read_unaligned(mem_addr as *const __m512d) } @@ -34391,7 +36065,8 @@ pub unsafe fn _mm512_loadu_pd(mem_addr: *const f64) -> __m512d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] -pub unsafe fn _mm512_storeu_pd(mem_addr: *mut f64, a: __m512d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_storeu_pd(mem_addr: *mut f64, a: __m512d) { ptr::write_unaligned(mem_addr as *mut __m512d, a); } @@ -34404,7 +36079,8 @@ pub unsafe fn _mm512_storeu_pd(mem_addr: *mut f64, a: __m512d) { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] -pub unsafe fn _mm512_loadu_ps(mem_addr: *const f32) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_loadu_ps(mem_addr: *const f32) -> __m512 { ptr::read_unaligned(mem_addr as *const __m512) } @@ -34417,7 +36093,8 @@ pub unsafe fn _mm512_loadu_ps(mem_addr: *const f32) -> __m512 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] -pub unsafe fn _mm512_storeu_ps(mem_addr: *mut f32, a: __m512) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_storeu_ps(mem_addr: *mut f32, a: __m512) { ptr::write_unaligned(mem_addr as *mut __m512, a); } @@ -34431,7 +36108,8 @@ pub unsafe fn _mm512_storeu_ps(mem_addr: *mut f32, a: __m512) { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa32 -pub unsafe fn _mm512_load_si512(mem_addr: *const __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_load_si512(mem_addr: *const __m512i) -> __m512i { ptr::read(mem_addr) } @@ -34445,7 +36123,8 @@ pub unsafe fn _mm512_load_si512(mem_addr: *const __m512i) -> __m512i { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa32 -pub unsafe fn _mm512_store_si512(mem_addr: *mut __m512i, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_store_si512(mem_addr: *mut __m512i, a: __m512i) { ptr::write(mem_addr, a); } @@ -34459,7 +36138,8 @@ pub unsafe fn _mm512_store_si512(mem_addr: *mut __m512i, a: __m512i) { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa32 -pub unsafe fn _mm512_load_epi32(mem_addr: *const i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_load_epi32(mem_addr: *const i32) -> __m512i { ptr::read(mem_addr as *const __m512i) } @@ -34473,7 +36153,8 @@ pub unsafe fn _mm512_load_epi32(mem_addr: *const i32) -> __m512i { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa32 -pub unsafe fn _mm256_load_epi32(mem_addr: *const i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_load_epi32(mem_addr: *const i32) -> __m256i { ptr::read(mem_addr as *const __m256i) } @@ -34487,7 +36168,8 @@ pub unsafe fn _mm256_load_epi32(mem_addr: *const i32) -> __m256i { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa32 -pub unsafe fn _mm_load_epi32(mem_addr: *const i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_epi32(mem_addr: *const i32) -> __m128i { ptr::read(mem_addr as *const __m128i) } @@ -34501,7 +36183,8 @@ pub unsafe fn _mm_load_epi32(mem_addr: *const i32) -> __m128i { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa32 -pub unsafe fn _mm512_store_epi32(mem_addr: *mut i32, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_store_epi32(mem_addr: *mut i32, a: __m512i) { ptr::write(mem_addr as *mut __m512i, a); } @@ -34515,7 +36198,8 @@ pub unsafe fn _mm512_store_epi32(mem_addr: *mut i32, a: __m512i) { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa32 -pub unsafe fn _mm256_store_epi32(mem_addr: *mut i32, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_store_epi32(mem_addr: *mut i32, a: __m256i) { ptr::write(mem_addr as *mut __m256i, a); } @@ -34529,7 +36213,8 @@ pub unsafe fn _mm256_store_epi32(mem_addr: *mut i32, a: __m256i) { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa32 -pub unsafe fn _mm_store_epi32(mem_addr: *mut i32, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_epi32(mem_addr: *mut i32, a: __m128i) { ptr::write(mem_addr as *mut __m128i, a); } @@ -34543,7 +36228,8 @@ pub unsafe fn _mm_store_epi32(mem_addr: *mut i32, a: __m128i) { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa64 -pub unsafe fn _mm512_load_epi64(mem_addr: *const i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_load_epi64(mem_addr: *const i64) -> __m512i { ptr::read(mem_addr as *const __m512i) } @@ -34557,7 +36243,8 @@ pub unsafe fn _mm512_load_epi64(mem_addr: *const i64) -> __m512i { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa64 -pub unsafe fn _mm256_load_epi64(mem_addr: *const i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_load_epi64(mem_addr: *const i64) -> __m256i { ptr::read(mem_addr as *const __m256i) } @@ -34571,7 +36258,8 @@ pub unsafe fn _mm256_load_epi64(mem_addr: *const i64) -> __m256i { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa64 -pub unsafe fn _mm_load_epi64(mem_addr: *const i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_epi64(mem_addr: *const i64) -> __m128i { ptr::read(mem_addr as *const __m128i) } @@ -34585,7 +36273,8 @@ pub unsafe fn _mm_load_epi64(mem_addr: *const i64) -> __m128i { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa64 -pub unsafe fn _mm512_store_epi64(mem_addr: *mut i64, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_store_epi64(mem_addr: *mut i64, a: __m512i) { ptr::write(mem_addr as *mut __m512i, a); } @@ -34599,7 +36288,8 @@ pub unsafe fn _mm512_store_epi64(mem_addr: *mut i64, a: __m512i) { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa64 -pub unsafe fn _mm256_store_epi64(mem_addr: *mut i64, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_store_epi64(mem_addr: *mut i64, a: __m256i) { ptr::write(mem_addr as *mut __m256i, a); } @@ -34613,7 +36303,8 @@ pub unsafe fn _mm256_store_epi64(mem_addr: *mut i64, a: __m256i) { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovdqa64 -pub unsafe fn _mm_store_epi64(mem_addr: *mut i64, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_epi64(mem_addr: *mut i64, a: __m128i) { ptr::write(mem_addr as *mut __m128i, a); } @@ -34627,7 +36318,8 @@ pub unsafe fn _mm_store_epi64(mem_addr: *mut i64, a: __m128i) { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] -pub unsafe fn _mm512_load_ps(mem_addr: *const f32) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_load_ps(mem_addr: *const f32) -> __m512 { ptr::read(mem_addr as *const __m512) } @@ -34641,7 +36333,8 @@ pub unsafe fn _mm512_load_ps(mem_addr: *const f32) -> __m512 { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] -pub unsafe fn _mm512_store_ps(mem_addr: *mut f32, a: __m512) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_store_ps(mem_addr: *mut f32, a: __m512) { ptr::write(mem_addr as *mut __m512, a); } @@ -34655,7 +36348,8 @@ pub unsafe fn _mm512_store_ps(mem_addr: *mut f32, a: __m512) { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovapd -pub unsafe fn _mm512_load_pd(mem_addr: *const f64) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_load_pd(mem_addr: *const f64) -> __m512d { ptr::read(mem_addr as *const __m512d) } @@ -34669,7 +36363,8 @@ pub unsafe fn _mm512_load_pd(mem_addr: *const f64) -> __m512d { all(test, not(all(target_arch = "x86", target_env = "msvc"))), assert_instr(vmovaps) )] //should be vmovapd -pub unsafe fn _mm512_store_pd(mem_addr: *mut f64, a: __m512d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_store_pd(mem_addr: *mut f64, a: __m512d) { ptr::write(mem_addr as *mut __m512d, a); } @@ -34682,7 +36377,12 @@ pub unsafe fn _mm512_store_pd(mem_addr: *mut f64, a: __m512d) { #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqu32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_loadu_epi32(src: __m512i, k: __mmask16, mem_addr: *const i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_loadu_epi32( + src: __m512i, + k: __mmask16, + mem_addr: *const i32, +) -> __m512i { let mask = simd_select_bitmask(k, i32x16::splat(!0), i32x16::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i32x16()).as_m512i() } @@ -34696,7 +36396,8 @@ pub unsafe fn _mm512_mask_loadu_epi32(src: __m512i, k: __mmask16, mem_addr: *con #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqu32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_loadu_epi32(k: __mmask16, mem_addr: *const i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_loadu_epi32(k: __mmask16, mem_addr: *const i32) -> __m512i { _mm512_mask_loadu_epi32(_mm512_setzero_si512(), k, mem_addr) } @@ -34709,7 +36410,12 @@ pub unsafe fn _mm512_maskz_loadu_epi32(k: __mmask16, mem_addr: *const i32) -> __ #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqu64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_loadu_epi64(src: __m512i, k: __mmask8, mem_addr: *const i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_loadu_epi64( + src: __m512i, + k: __mmask8, + mem_addr: *const i64, +) -> __m512i { let mask = simd_select_bitmask(k, i64x8::splat(!0), i64x8::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i64x8()).as_m512i() } @@ -34723,7 +36429,8 @@ pub unsafe fn _mm512_mask_loadu_epi64(src: __m512i, k: __mmask8, mem_addr: *cons #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqu64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_loadu_epi64(k: __mmask8, mem_addr: *const i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_loadu_epi64(k: __mmask8, mem_addr: *const i64) -> __m512i { _mm512_mask_loadu_epi64(_mm512_setzero_si512(), k, mem_addr) } @@ -34736,7 +36443,12 @@ pub unsafe fn _mm512_maskz_loadu_epi64(k: __mmask8, mem_addr: *const i64) -> __m #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_loadu_ps(src: __m512, k: __mmask16, mem_addr: *const f32) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_loadu_ps( + src: __m512, + k: __mmask16, + mem_addr: *const f32, +) -> __m512 { let mask = simd_select_bitmask(k, i32x16::splat(!0), i32x16::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_f32x16()).as_m512() } @@ -34750,7 +36462,8 @@ pub unsafe fn _mm512_mask_loadu_ps(src: __m512, k: __mmask16, mem_addr: *const f #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_loadu_ps(k: __mmask16, mem_addr: *const f32) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_loadu_ps(k: __mmask16, mem_addr: *const f32) -> __m512 { _mm512_mask_loadu_ps(_mm512_setzero_ps(), k, mem_addr) } @@ -34763,7 +36476,12 @@ pub unsafe fn _mm512_maskz_loadu_ps(k: __mmask16, mem_addr: *const f32) -> __m51 #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovupd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_loadu_pd(src: __m512d, k: __mmask8, mem_addr: *const f64) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_loadu_pd( + src: __m512d, + k: __mmask8, + mem_addr: *const f64, +) -> __m512d { let mask = simd_select_bitmask(k, i64x8::splat(!0), i64x8::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_f64x8()).as_m512d() } @@ -34777,7 +36495,8 @@ pub unsafe fn _mm512_mask_loadu_pd(src: __m512d, k: __mmask8, mem_addr: *const f #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovupd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_loadu_pd(k: __mmask8, mem_addr: *const f64) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_loadu_pd(k: __mmask8, mem_addr: *const f64) -> __m512d { _mm512_mask_loadu_pd(_mm512_setzero_pd(), k, mem_addr) } @@ -34790,7 +36509,12 @@ pub unsafe fn _mm512_maskz_loadu_pd(k: __mmask8, mem_addr: *const f64) -> __m512 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_loadu_epi32(src: __m256i, k: __mmask8, mem_addr: *const i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_loadu_epi32( + src: __m256i, + k: __mmask8, + mem_addr: *const i32, +) -> __m256i { let mask = simd_select_bitmask(k, i32x8::splat(!0), i32x8::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i32x8()).as_m256i() } @@ -34804,7 +36528,8 @@ pub unsafe fn _mm256_mask_loadu_epi32(src: __m256i, k: __mmask8, mem_addr: *cons #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_loadu_epi32(k: __mmask8, mem_addr: *const i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_loadu_epi32(k: __mmask8, mem_addr: *const i32) -> __m256i { _mm256_mask_loadu_epi32(_mm256_setzero_si256(), k, mem_addr) } @@ -34817,7 +36542,12 @@ pub unsafe fn _mm256_maskz_loadu_epi32(k: __mmask8, mem_addr: *const i32) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_loadu_epi64(src: __m256i, k: __mmask8, mem_addr: *const i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_loadu_epi64( + src: __m256i, + k: __mmask8, + mem_addr: *const i64, +) -> __m256i { let mask = simd_select_bitmask(k, i64x4::splat(!0), i64x4::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i64x4()).as_m256i() } @@ -34831,7 +36561,8 @@ pub unsafe fn _mm256_mask_loadu_epi64(src: __m256i, k: __mmask8, mem_addr: *cons #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_loadu_epi64(k: __mmask8, mem_addr: *const i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_loadu_epi64(k: __mmask8, mem_addr: *const i64) -> __m256i { _mm256_mask_loadu_epi64(_mm256_setzero_si256(), k, mem_addr) } @@ -34844,7 +36575,8 @@ pub unsafe fn _mm256_maskz_loadu_epi64(k: __mmask8, mem_addr: *const i64) -> __m #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_loadu_ps(src: __m256, k: __mmask8, mem_addr: *const f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_loadu_ps(src: __m256, k: __mmask8, mem_addr: *const f32) -> __m256 { let mask = simd_select_bitmask(k, i32x8::splat(!0), i32x8::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_f32x8()).as_m256() } @@ -34858,7 +36590,8 @@ pub unsafe fn _mm256_mask_loadu_ps(src: __m256, k: __mmask8, mem_addr: *const f3 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_loadu_ps(k: __mmask8, mem_addr: *const f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_loadu_ps(k: __mmask8, mem_addr: *const f32) -> __m256 { _mm256_mask_loadu_ps(_mm256_setzero_ps(), k, mem_addr) } @@ -34871,7 +36604,12 @@ pub unsafe fn _mm256_maskz_loadu_ps(k: __mmask8, mem_addr: *const f32) -> __m256 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovupd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_loadu_pd(src: __m256d, k: __mmask8, mem_addr: *const f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_loadu_pd( + src: __m256d, + k: __mmask8, + mem_addr: *const f64, +) -> __m256d { let mask = simd_select_bitmask(k, i64x4::splat(!0), i64x4::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_f64x4()).as_m256d() } @@ -34885,7 +36623,8 @@ pub unsafe fn _mm256_mask_loadu_pd(src: __m256d, k: __mmask8, mem_addr: *const f #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovupd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_loadu_pd(k: __mmask8, mem_addr: *const f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_loadu_pd(k: __mmask8, mem_addr: *const f64) -> __m256d { _mm256_mask_loadu_pd(_mm256_setzero_pd(), k, mem_addr) } @@ -34898,7 +36637,12 @@ pub unsafe fn _mm256_maskz_loadu_pd(k: __mmask8, mem_addr: *const f64) -> __m256 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_loadu_epi32(src: __m128i, k: __mmask8, mem_addr: *const i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_loadu_epi32( + src: __m128i, + k: __mmask8, + mem_addr: *const i32, +) -> __m128i { let mask = simd_select_bitmask(k, i32x4::splat(!0), i32x4::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i32x4()).as_m128i() } @@ -34912,7 +36656,8 @@ pub unsafe fn _mm_mask_loadu_epi32(src: __m128i, k: __mmask8, mem_addr: *const i #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_loadu_epi32(k: __mmask8, mem_addr: *const i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_loadu_epi32(k: __mmask8, mem_addr: *const i32) -> __m128i { _mm_mask_loadu_epi32(_mm_setzero_si128(), k, mem_addr) } @@ -34925,7 +36670,12 @@ pub unsafe fn _mm_maskz_loadu_epi32(k: __mmask8, mem_addr: *const i32) -> __m128 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_loadu_epi64(src: __m128i, k: __mmask8, mem_addr: *const i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_loadu_epi64( + src: __m128i, + k: __mmask8, + mem_addr: *const i64, +) -> __m128i { let mask = simd_select_bitmask(k, i64x2::splat(!0), i64x2::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i64x2()).as_m128i() } @@ -34939,7 +36689,8 @@ pub unsafe fn _mm_mask_loadu_epi64(src: __m128i, k: __mmask8, mem_addr: *const i #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_loadu_epi64(k: __mmask8, mem_addr: *const i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_loadu_epi64(k: __mmask8, mem_addr: *const i64) -> __m128i { _mm_mask_loadu_epi64(_mm_setzero_si128(), k, mem_addr) } @@ -34952,7 +36703,8 @@ pub unsafe fn _mm_maskz_loadu_epi64(k: __mmask8, mem_addr: *const i64) -> __m128 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_loadu_ps(src: __m128, k: __mmask8, mem_addr: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_loadu_ps(src: __m128, k: __mmask8, mem_addr: *const f32) -> __m128 { let mask = simd_select_bitmask(k, i32x4::splat(!0), i32x4::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_f32x4()).as_m128() } @@ -34966,7 +36718,8 @@ pub unsafe fn _mm_mask_loadu_ps(src: __m128, k: __mmask8, mem_addr: *const f32) #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_loadu_ps(k: __mmask8, mem_addr: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_loadu_ps(k: __mmask8, mem_addr: *const f32) -> __m128 { _mm_mask_loadu_ps(_mm_setzero_ps(), k, mem_addr) } @@ -34979,7 +36732,8 @@ pub unsafe fn _mm_maskz_loadu_ps(k: __mmask8, mem_addr: *const f32) -> __m128 { #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovupd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_loadu_pd(src: __m128d, k: __mmask8, mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_loadu_pd(src: __m128d, k: __mmask8, mem_addr: *const f64) -> __m128d { let mask = simd_select_bitmask(k, i64x2::splat(!0), i64x2::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_f64x2()).as_m128d() } @@ -34993,7 +36747,8 @@ pub unsafe fn _mm_mask_loadu_pd(src: __m128d, k: __mmask8, mem_addr: *const f64) #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovupd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_loadu_pd(k: __mmask8, mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_loadu_pd(k: __mmask8, mem_addr: *const f64) -> __m128d { _mm_mask_loadu_pd(_mm_setzero_pd(), k, mem_addr) } @@ -35006,7 +36761,12 @@ pub unsafe fn _mm_maskz_loadu_pd(k: __mmask8, mem_addr: *const f64) -> __m128d { #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqa32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_load_epi32(src: __m512i, k: __mmask16, mem_addr: *const i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_load_epi32( + src: __m512i, + k: __mmask16, + mem_addr: *const i32, +) -> __m512i { let mask = simd_select_bitmask(k, i32x16::splat(!0), i32x16::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_i32x16()).as_m512i() } @@ -35020,7 +36780,8 @@ pub unsafe fn _mm512_mask_load_epi32(src: __m512i, k: __mmask16, mem_addr: *cons #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqa32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_load_epi32(k: __mmask16, mem_addr: *const i32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_load_epi32(k: __mmask16, mem_addr: *const i32) -> __m512i { _mm512_mask_load_epi32(_mm512_setzero_si512(), k, mem_addr) } @@ -35033,7 +36794,12 @@ pub unsafe fn _mm512_maskz_load_epi32(k: __mmask16, mem_addr: *const i32) -> __m #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqa64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_load_epi64(src: __m512i, k: __mmask8, mem_addr: *const i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_load_epi64( + src: __m512i, + k: __mmask8, + mem_addr: *const i64, +) -> __m512i { let mask = simd_select_bitmask(k, i64x8::splat(!0), i64x8::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_i64x8()).as_m512i() } @@ -35047,7 +36813,8 @@ pub unsafe fn _mm512_mask_load_epi64(src: __m512i, k: __mmask8, mem_addr: *const #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqa64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_load_epi64(k: __mmask8, mem_addr: *const i64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_load_epi64(k: __mmask8, mem_addr: *const i64) -> __m512i { _mm512_mask_load_epi64(_mm512_setzero_si512(), k, mem_addr) } @@ -35060,7 +36827,8 @@ pub unsafe fn _mm512_maskz_load_epi64(k: __mmask8, mem_addr: *const i64) -> __m5 #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovaps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_load_ps(src: __m512, k: __mmask16, mem_addr: *const f32) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_load_ps(src: __m512, k: __mmask16, mem_addr: *const f32) -> __m512 { let mask = simd_select_bitmask(k, i32x16::splat(!0), i32x16::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_f32x16()).as_m512() } @@ -35074,7 +36842,8 @@ pub unsafe fn _mm512_mask_load_ps(src: __m512, k: __mmask16, mem_addr: *const f3 #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovaps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_load_ps(k: __mmask16, mem_addr: *const f32) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_load_ps(k: __mmask16, mem_addr: *const f32) -> __m512 { _mm512_mask_load_ps(_mm512_setzero_ps(), k, mem_addr) } @@ -35087,7 +36856,12 @@ pub unsafe fn _mm512_maskz_load_ps(k: __mmask16, mem_addr: *const f32) -> __m512 #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovapd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_load_pd(src: __m512d, k: __mmask8, mem_addr: *const f64) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_load_pd( + src: __m512d, + k: __mmask8, + mem_addr: *const f64, +) -> __m512d { let mask = simd_select_bitmask(k, i64x8::splat(!0), i64x8::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_f64x8()).as_m512d() } @@ -35101,7 +36875,8 @@ pub unsafe fn _mm512_mask_load_pd(src: __m512d, k: __mmask8, mem_addr: *const f6 #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovapd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_load_pd(k: __mmask8, mem_addr: *const f64) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_load_pd(k: __mmask8, mem_addr: *const f64) -> __m512d { _mm512_mask_load_pd(_mm512_setzero_pd(), k, mem_addr) } @@ -35114,7 +36889,12 @@ pub unsafe fn _mm512_maskz_load_pd(k: __mmask8, mem_addr: *const f64) -> __m512d #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_load_epi32(src: __m256i, k: __mmask8, mem_addr: *const i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_load_epi32( + src: __m256i, + k: __mmask8, + mem_addr: *const i32, +) -> __m256i { let mask = simd_select_bitmask(k, i32x8::splat(!0), i32x8::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_i32x8()).as_m256i() } @@ -35128,7 +36908,8 @@ pub unsafe fn _mm256_mask_load_epi32(src: __m256i, k: __mmask8, mem_addr: *const #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_load_epi32(k: __mmask8, mem_addr: *const i32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_load_epi32(k: __mmask8, mem_addr: *const i32) -> __m256i { _mm256_mask_load_epi32(_mm256_setzero_si256(), k, mem_addr) } @@ -35141,7 +36922,12 @@ pub unsafe fn _mm256_maskz_load_epi32(k: __mmask8, mem_addr: *const i32) -> __m2 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_load_epi64(src: __m256i, k: __mmask8, mem_addr: *const i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_load_epi64( + src: __m256i, + k: __mmask8, + mem_addr: *const i64, +) -> __m256i { let mask = simd_select_bitmask(k, i64x4::splat(!0), i64x4::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_i64x4()).as_m256i() } @@ -35155,7 +36941,8 @@ pub unsafe fn _mm256_mask_load_epi64(src: __m256i, k: __mmask8, mem_addr: *const #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_load_epi64(k: __mmask8, mem_addr: *const i64) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_load_epi64(k: __mmask8, mem_addr: *const i64) -> __m256i { _mm256_mask_load_epi64(_mm256_setzero_si256(), k, mem_addr) } @@ -35168,7 +36955,8 @@ pub unsafe fn _mm256_maskz_load_epi64(k: __mmask8, mem_addr: *const i64) -> __m2 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovaps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_load_ps(src: __m256, k: __mmask8, mem_addr: *const f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_load_ps(src: __m256, k: __mmask8, mem_addr: *const f32) -> __m256 { let mask = simd_select_bitmask(k, i32x8::splat(!0), i32x8::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_f32x8()).as_m256() } @@ -35182,7 +36970,8 @@ pub unsafe fn _mm256_mask_load_ps(src: __m256, k: __mmask8, mem_addr: *const f32 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovaps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_load_ps(k: __mmask8, mem_addr: *const f32) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_load_ps(k: __mmask8, mem_addr: *const f32) -> __m256 { _mm256_mask_load_ps(_mm256_setzero_ps(), k, mem_addr) } @@ -35195,7 +36984,12 @@ pub unsafe fn _mm256_maskz_load_ps(k: __mmask8, mem_addr: *const f32) -> __m256 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovapd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_load_pd(src: __m256d, k: __mmask8, mem_addr: *const f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_load_pd( + src: __m256d, + k: __mmask8, + mem_addr: *const f64, +) -> __m256d { let mask = simd_select_bitmask(k, i64x4::splat(!0), i64x4::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_f64x4()).as_m256d() } @@ -35209,7 +37003,8 @@ pub unsafe fn _mm256_mask_load_pd(src: __m256d, k: __mmask8, mem_addr: *const f6 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovapd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_load_pd(k: __mmask8, mem_addr: *const f64) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_load_pd(k: __mmask8, mem_addr: *const f64) -> __m256d { _mm256_mask_load_pd(_mm256_setzero_pd(), k, mem_addr) } @@ -35222,7 +37017,12 @@ pub unsafe fn _mm256_maskz_load_pd(k: __mmask8, mem_addr: *const f64) -> __m256d #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_load_epi32(src: __m128i, k: __mmask8, mem_addr: *const i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_load_epi32( + src: __m128i, + k: __mmask8, + mem_addr: *const i32, +) -> __m128i { let mask = simd_select_bitmask(k, i32x4::splat(!0), i32x4::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_i32x4()).as_m128i() } @@ -35236,7 +37036,8 @@ pub unsafe fn _mm_mask_load_epi32(src: __m128i, k: __mmask8, mem_addr: *const i3 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_load_epi32(k: __mmask8, mem_addr: *const i32) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_load_epi32(k: __mmask8, mem_addr: *const i32) -> __m128i { _mm_mask_load_epi32(_mm_setzero_si128(), k, mem_addr) } @@ -35249,7 +37050,12 @@ pub unsafe fn _mm_maskz_load_epi32(k: __mmask8, mem_addr: *const i32) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_load_epi64(src: __m128i, k: __mmask8, mem_addr: *const i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_load_epi64( + src: __m128i, + k: __mmask8, + mem_addr: *const i64, +) -> __m128i { let mask = simd_select_bitmask(k, i64x2::splat(!0), i64x2::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_i64x2()).as_m128i() } @@ -35263,7 +37069,8 @@ pub unsafe fn _mm_mask_load_epi64(src: __m128i, k: __mmask8, mem_addr: *const i6 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_load_epi64(k: __mmask8, mem_addr: *const i64) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_load_epi64(k: __mmask8, mem_addr: *const i64) -> __m128i { _mm_mask_load_epi64(_mm_setzero_si128(), k, mem_addr) } @@ -35276,7 +37083,8 @@ pub unsafe fn _mm_maskz_load_epi64(k: __mmask8, mem_addr: *const i64) -> __m128i #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovaps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_load_ps(src: __m128, k: __mmask8, mem_addr: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_load_ps(src: __m128, k: __mmask8, mem_addr: *const f32) -> __m128 { let mask = simd_select_bitmask(k, i32x4::splat(!0), i32x4::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_f32x4()).as_m128() } @@ -35290,7 +37098,8 @@ pub unsafe fn _mm_mask_load_ps(src: __m128, k: __mmask8, mem_addr: *const f32) - #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovaps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_load_ps(k: __mmask8, mem_addr: *const f32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_load_ps(k: __mmask8, mem_addr: *const f32) -> __m128 { _mm_mask_load_ps(_mm_setzero_ps(), k, mem_addr) } @@ -35303,7 +37112,8 @@ pub unsafe fn _mm_maskz_load_ps(k: __mmask8, mem_addr: *const f32) -> __m128 { #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovapd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_load_pd(src: __m128d, k: __mmask8, mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_load_pd(src: __m128d, k: __mmask8, mem_addr: *const f64) -> __m128d { let mask = simd_select_bitmask(k, i64x2::splat(!0), i64x2::ZERO); simd_masked_load!(SimdAlign::Vector, mask, mem_addr, src.as_f64x2()).as_m128d() } @@ -35317,7 +37127,8 @@ pub unsafe fn _mm_mask_load_pd(src: __m128d, k: __mmask8, mem_addr: *const f64) #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovapd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_load_pd(k: __mmask8, mem_addr: *const f64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_load_pd(k: __mmask8, mem_addr: *const f64) -> __m128d { _mm_mask_load_pd(_mm_setzero_pd(), k, mem_addr) } @@ -35417,7 +37228,8 @@ pub unsafe fn _mm_maskz_load_sd(k: __mmask8, mem_addr: *const f64) -> __m128d { #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqu32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_storeu_epi32(mem_addr: *mut i32, mask: __mmask16, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_storeu_epi32(mem_addr: *mut i32, mask: __mmask16, a: __m512i) { let mask = simd_select_bitmask(mask, i32x16::splat(!0), i32x16::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i32x16()); } @@ -35430,7 +37242,8 @@ pub unsafe fn _mm512_mask_storeu_epi32(mem_addr: *mut i32, mask: __mmask16, a: _ #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqu64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_storeu_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_storeu_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m512i) { let mask = simd_select_bitmask(mask, i64x8::splat(!0), i64x8::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i64x8()); } @@ -35443,7 +37256,8 @@ pub unsafe fn _mm512_mask_storeu_epi64(mem_addr: *mut i64, mask: __mmask8, a: __ #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_storeu_ps(mem_addr: *mut f32, mask: __mmask16, a: __m512) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_storeu_ps(mem_addr: *mut f32, mask: __mmask16, a: __m512) { let mask = simd_select_bitmask(mask, i32x16::splat(!0), i32x16::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_f32x16()); } @@ -35456,7 +37270,8 @@ pub unsafe fn _mm512_mask_storeu_ps(mem_addr: *mut f32, mask: __mmask16, a: __m5 #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovupd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_storeu_pd(mem_addr: *mut f64, mask: __mmask8, a: __m512d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_storeu_pd(mem_addr: *mut f64, mask: __mmask8, a: __m512d) { let mask = simd_select_bitmask(mask, i64x8::splat(!0), i64x8::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_f64x8()); } @@ -35469,7 +37284,8 @@ pub unsafe fn _mm512_mask_storeu_pd(mem_addr: *mut f64, mask: __mmask8, a: __m51 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_storeu_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_storeu_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m256i) { let mask = simd_select_bitmask(mask, i32x8::splat(!0), i32x8::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i32x8()); } @@ -35482,7 +37298,8 @@ pub unsafe fn _mm256_mask_storeu_epi32(mem_addr: *mut i32, mask: __mmask8, a: __ #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_storeu_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_storeu_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m256i) { let mask = simd_select_bitmask(mask, i64x4::splat(!0), i64x4::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i64x4()); } @@ -35495,7 +37312,8 @@ pub unsafe fn _mm256_mask_storeu_epi64(mem_addr: *mut i64, mask: __mmask8, a: __ #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_storeu_ps(mem_addr: *mut f32, mask: __mmask8, a: __m256) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_storeu_ps(mem_addr: *mut f32, mask: __mmask8, a: __m256) { let mask = simd_select_bitmask(mask, i32x8::splat(!0), i32x8::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_f32x8()); } @@ -35508,7 +37326,8 @@ pub unsafe fn _mm256_mask_storeu_ps(mem_addr: *mut f32, mask: __mmask8, a: __m25 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovupd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_storeu_pd(mem_addr: *mut f64, mask: __mmask8, a: __m256d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_storeu_pd(mem_addr: *mut f64, mask: __mmask8, a: __m256d) { let mask = simd_select_bitmask(mask, i64x4::splat(!0), i64x4::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_f64x4()); } @@ -35521,7 +37340,8 @@ pub unsafe fn _mm256_mask_storeu_pd(mem_addr: *mut f64, mask: __mmask8, a: __m25 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_storeu_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_storeu_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m128i) { let mask = simd_select_bitmask(mask, i32x4::splat(!0), i32x4::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i32x4()); } @@ -35534,7 +37354,8 @@ pub unsafe fn _mm_mask_storeu_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m12 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_storeu_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_storeu_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m128i) { let mask = simd_select_bitmask(mask, i64x2::splat(!0), i64x2::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i64x2()); } @@ -35547,7 +37368,8 @@ pub unsafe fn _mm_mask_storeu_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m12 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovups))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_storeu_ps(mem_addr: *mut f32, mask: __mmask8, a: __m128) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_storeu_ps(mem_addr: *mut f32, mask: __mmask8, a: __m128) { let mask = simd_select_bitmask(mask, i32x4::splat(!0), i32x4::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_f32x4()); } @@ -35560,7 +37382,8 @@ pub unsafe fn _mm_mask_storeu_ps(mem_addr: *mut f32, mask: __mmask8, a: __m128) #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovupd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_storeu_pd(mem_addr: *mut f64, mask: __mmask8, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_storeu_pd(mem_addr: *mut f64, mask: __mmask8, a: __m128d) { let mask = simd_select_bitmask(mask, i64x2::splat(!0), i64x2::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_f64x2()); } @@ -35573,7 +37396,8 @@ pub unsafe fn _mm_mask_storeu_pd(mem_addr: *mut f64, mask: __mmask8, a: __m128d) #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqa32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_store_epi32(mem_addr: *mut i32, mask: __mmask16, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_store_epi32(mem_addr: *mut i32, mask: __mmask16, a: __m512i) { let mask = simd_select_bitmask(mask, i32x16::splat(!0), i32x16::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_i32x16()); } @@ -35586,7 +37410,8 @@ pub unsafe fn _mm512_mask_store_epi32(mem_addr: *mut i32, mask: __mmask16, a: __ #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovdqa64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_store_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_store_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m512i) { let mask = simd_select_bitmask(mask, i64x8::splat(!0), i64x8::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_i64x8()); } @@ -35599,7 +37424,8 @@ pub unsafe fn _mm512_mask_store_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovaps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_store_ps(mem_addr: *mut f32, mask: __mmask16, a: __m512) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_store_ps(mem_addr: *mut f32, mask: __mmask16, a: __m512) { let mask = simd_select_bitmask(mask, i32x16::splat(!0), i32x16::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_f32x16()); } @@ -35612,7 +37438,8 @@ pub unsafe fn _mm512_mask_store_ps(mem_addr: *mut f32, mask: __mmask16, a: __m51 #[target_feature(enable = "avx512f")] #[cfg_attr(test, assert_instr(vmovapd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_store_pd(mem_addr: *mut f64, mask: __mmask8, a: __m512d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_store_pd(mem_addr: *mut f64, mask: __mmask8, a: __m512d) { let mask = simd_select_bitmask(mask, i64x8::splat(!0), i64x8::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_f64x8()); } @@ -35625,7 +37452,8 @@ pub unsafe fn _mm512_mask_store_pd(mem_addr: *mut f64, mask: __mmask8, a: __m512 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_store_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_store_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m256i) { let mask = simd_select_bitmask(mask, i32x8::splat(!0), i32x8::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_i32x8()); } @@ -35638,7 +37466,8 @@ pub unsafe fn _mm256_mask_store_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_store_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_store_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m256i) { let mask = simd_select_bitmask(mask, i64x4::splat(!0), i64x4::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_i64x4()); } @@ -35651,7 +37480,8 @@ pub unsafe fn _mm256_mask_store_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovaps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_store_ps(mem_addr: *mut f32, mask: __mmask8, a: __m256) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_store_ps(mem_addr: *mut f32, mask: __mmask8, a: __m256) { let mask = simd_select_bitmask(mask, i32x8::splat(!0), i32x8::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_f32x8()); } @@ -35664,7 +37494,8 @@ pub unsafe fn _mm256_mask_store_ps(mem_addr: *mut f32, mask: __mmask8, a: __m256 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovapd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_store_pd(mem_addr: *mut f64, mask: __mmask8, a: __m256d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_store_pd(mem_addr: *mut f64, mask: __mmask8, a: __m256d) { let mask = simd_select_bitmask(mask, i64x4::splat(!0), i64x4::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_f64x4()); } @@ -35677,7 +37508,8 @@ pub unsafe fn _mm256_mask_store_pd(mem_addr: *mut f64, mask: __mmask8, a: __m256 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa32))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_store_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_store_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m128i) { let mask = simd_select_bitmask(mask, i32x4::splat(!0), i32x4::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_i32x4()); } @@ -35690,7 +37522,8 @@ pub unsafe fn _mm_mask_store_epi32(mem_addr: *mut i32, mask: __mmask8, a: __m128 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqa64))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_store_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_store_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m128i) { let mask = simd_select_bitmask(mask, i64x2::splat(!0), i64x2::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_i64x2()); } @@ -35703,7 +37536,8 @@ pub unsafe fn _mm_mask_store_epi64(mem_addr: *mut i64, mask: __mmask8, a: __m128 #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovaps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_store_ps(mem_addr: *mut f32, mask: __mmask8, a: __m128) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_store_ps(mem_addr: *mut f32, mask: __mmask8, a: __m128) { let mask = simd_select_bitmask(mask, i32x4::splat(!0), i32x4::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_f32x4()); } @@ -35716,7 +37550,8 @@ pub unsafe fn _mm_mask_store_ps(mem_addr: *mut f32, mask: __mmask8, a: __m128) { #[target_feature(enable = "avx512f,avx512vl")] #[cfg_attr(test, assert_instr(vmovapd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_store_pd(mem_addr: *mut f64, mask: __mmask8, a: __m128d) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_store_pd(mem_addr: *mut f64, mask: __mmask8, a: __m128d) { let mask = simd_select_bitmask(mask, i64x2::splat(!0), i64x2::ZERO); simd_masked_store!(SimdAlign::Vector, mask, mem_addr, a.as_f64x2()); } @@ -36063,7 +37898,8 @@ pub unsafe fn _mm_maskz_expandloadu_pd(k: __mmask8, mem_addr: *const f64) -> __m #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_setr_pd( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setr_pd( e0: f64, e1: f64, e2: f64, @@ -36085,7 +37921,8 @@ pub fn _mm512_setr_pd( #[inline] #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_set_pd( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set_pd( e0: f64, e1: f64, e2: f64, @@ -36105,7 +37942,8 @@ pub fn _mm512_set_pd( #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovss))] -pub fn _mm_mask_move_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_move_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let extractsrc: f32 = simd_extract!(src, 0); let mut mov: f32 = extractsrc; @@ -36123,7 +37961,8 @@ pub fn _mm_mask_move_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovss))] -pub fn _mm_maskz_move_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_move_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let mut mov: f32 = 0.; if (k & 0b00000001) != 0 { @@ -36140,7 +37979,8 @@ pub fn _mm_maskz_move_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovsd))] -pub fn _mm_mask_move_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_move_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let extractsrc: f64 = simd_extract!(src, 0); let mut mov: f64 = extractsrc; @@ -36158,7 +37998,8 @@ pub fn _mm_mask_move_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovsd))] -pub fn _mm_maskz_move_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_move_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let mut mov: f64 = 0.; if (k & 0b00000001) != 0 { @@ -36175,7 +38016,8 @@ pub fn _mm_maskz_move_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddss))] -pub fn _mm_mask_add_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let extractsrc: f32 = simd_extract!(src, 0); let mut add: f32 = extractsrc; @@ -36195,7 +38037,8 @@ pub fn _mm_mask_add_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddss))] -pub fn _mm_maskz_add_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let mut add: f32 = 0.; if (k & 0b00000001) != 0 { @@ -36214,7 +38057,8 @@ pub fn _mm_maskz_add_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddsd))] -pub fn _mm_mask_add_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let extractsrc: f64 = simd_extract!(src, 0); let mut add: f64 = extractsrc; @@ -36234,7 +38078,8 @@ pub fn _mm_mask_add_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vaddsd))] -pub fn _mm_maskz_add_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let mut add: f64 = 0.; if (k & 0b00000001) != 0 { @@ -36253,7 +38098,8 @@ pub fn _mm_maskz_add_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubss))] -pub fn _mm_mask_sub_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let extractsrc: f32 = simd_extract!(src, 0); let mut add: f32 = extractsrc; @@ -36273,7 +38119,8 @@ pub fn _mm_mask_sub_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubss))] -pub fn _mm_maskz_sub_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let mut add: f32 = 0.; if (k & 0b00000001) != 0 { @@ -36292,7 +38139,8 @@ pub fn _mm_maskz_sub_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubsd))] -pub fn _mm_mask_sub_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let extractsrc: f64 = simd_extract!(src, 0); let mut add: f64 = extractsrc; @@ -36312,7 +38160,8 @@ pub fn _mm_mask_sub_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vsubsd))] -pub fn _mm_maskz_sub_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let mut add: f64 = 0.; if (k & 0b00000001) != 0 { @@ -36331,7 +38180,8 @@ pub fn _mm_maskz_sub_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulss))] -pub fn _mm_mask_mul_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mul_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let extractsrc: f32 = simd_extract!(src, 0); let mut add: f32 = extractsrc; @@ -36351,7 +38201,8 @@ pub fn _mm_mask_mul_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulss))] -pub fn _mm_maskz_mul_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mul_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let mut add: f32 = 0.; if (k & 0b00000001) != 0 { @@ -36370,7 +38221,8 @@ pub fn _mm_maskz_mul_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulsd))] -pub fn _mm_mask_mul_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mul_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let extractsrc: f64 = simd_extract!(src, 0); let mut add: f64 = extractsrc; @@ -36390,7 +38242,8 @@ pub fn _mm_mask_mul_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmulsd))] -pub fn _mm_maskz_mul_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mul_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let mut add: f64 = 0.; if (k & 0b00000001) != 0 { @@ -36409,7 +38262,8 @@ pub fn _mm_maskz_mul_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivss))] -pub fn _mm_mask_div_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_div_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let extractsrc: f32 = simd_extract!(src, 0); let mut add: f32 = extractsrc; @@ -36429,7 +38283,8 @@ pub fn _mm_mask_div_ss(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivss))] -pub fn _mm_maskz_div_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_div_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let mut add: f32 = 0.; if (k & 0b00000001) != 0 { @@ -36448,7 +38303,8 @@ pub fn _mm_maskz_div_ss(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivsd))] -pub fn _mm_mask_div_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_div_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let extractsrc: f64 = simd_extract!(src, 0); let mut add: f64 = extractsrc; @@ -36468,7 +38324,8 @@ pub fn _mm_mask_div_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vdivsd))] -pub fn _mm_maskz_div_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_div_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let mut add: f64 = 0.; if (k & 0b00000001) != 0 { @@ -37452,7 +39309,8 @@ pub fn _mm_maskz_scalef_sd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] -pub fn _mm_mask_fmadd_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmadd_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { let mut fmadd: f32 = simd_extract!(a, 0); if (k & 0b00000001) != 0 { @@ -37471,7 +39329,8 @@ pub fn _mm_mask_fmadd_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] -pub fn _mm_maskz_fmadd_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmadd_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { let mut fmadd: f32 = 0.; if (k & 0b00000001) != 0 { @@ -37491,7 +39350,8 @@ pub fn _mm_maskz_fmadd_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] -pub fn _mm_mask3_fmadd_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmadd_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { let mut fmadd: f32 = simd_extract!(c, 0); if (k & 0b00000001) != 0 { @@ -37510,7 +39370,8 @@ pub fn _mm_mask3_fmadd_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] -pub fn _mm_mask_fmadd_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmadd_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { let mut fmadd: f64 = simd_extract!(a, 0); if (k & 0b00000001) != 0 { @@ -37529,7 +39390,8 @@ pub fn _mm_mask_fmadd_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] -pub fn _mm_maskz_fmadd_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmadd_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { let mut fmadd: f64 = 0.; if (k & 0b00000001) != 0 { @@ -37549,7 +39411,8 @@ pub fn _mm_maskz_fmadd_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmadd))] -pub fn _mm_mask3_fmadd_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmadd_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { let mut fmadd: f64 = simd_extract!(c, 0); if (k & 0b00000001) != 0 { @@ -37568,7 +39431,8 @@ pub fn _mm_mask3_fmadd_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] -pub fn _mm_mask_fmsub_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmsub_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { let mut fmsub: f32 = simd_extract!(a, 0); if (k & 0b00000001) != 0 { @@ -37588,7 +39452,8 @@ pub fn _mm_mask_fmsub_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] -pub fn _mm_maskz_fmsub_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmsub_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { let mut fmsub: f32 = 0.; if (k & 0b00000001) != 0 { @@ -37609,7 +39474,8 @@ pub fn _mm_maskz_fmsub_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] -pub fn _mm_mask3_fmsub_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmsub_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { let mut fmsub: f32 = simd_extract!(c, 0); if (k & 0b00000001) != 0 { @@ -37629,7 +39495,8 @@ pub fn _mm_mask3_fmsub_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] -pub fn _mm_mask_fmsub_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmsub_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { let mut fmsub: f64 = simd_extract!(a, 0); if (k & 0b00000001) != 0 { @@ -37649,7 +39516,8 @@ pub fn _mm_mask_fmsub_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] -pub fn _mm_maskz_fmsub_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmsub_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { let mut fmsub: f64 = 0.; if (k & 0b00000001) != 0 { @@ -37670,7 +39538,8 @@ pub fn _mm_maskz_fmsub_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfmsub))] -pub fn _mm_mask3_fmsub_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmsub_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { let mut fmsub: f64 = simd_extract!(c, 0); if (k & 0b00000001) != 0 { @@ -37690,7 +39559,8 @@ pub fn _mm_mask3_fmsub_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] -pub fn _mm_mask_fnmadd_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmadd_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { let mut fnmadd: f32 = simd_extract!(a, 0); if (k & 0b00000001) != 0 { @@ -37710,7 +39580,8 @@ pub fn _mm_mask_fnmadd_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] -pub fn _mm_maskz_fnmadd_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmadd_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { let mut fnmadd: f32 = 0.; if (k & 0b00000001) != 0 { @@ -37731,7 +39602,8 @@ pub fn _mm_maskz_fnmadd_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m1 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] -pub fn _mm_mask3_fnmadd_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmadd_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { let mut fnmadd: f32 = simd_extract!(c, 0); if (k & 0b00000001) != 0 { @@ -37751,7 +39623,8 @@ pub fn _mm_mask3_fnmadd_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m1 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] -pub fn _mm_mask_fnmadd_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmadd_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { let mut fnmadd: f64 = simd_extract!(a, 0); if (k & 0b00000001) != 0 { @@ -37771,7 +39644,8 @@ pub fn _mm_mask_fnmadd_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] -pub fn _mm_maskz_fnmadd_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmadd_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { let mut fnmadd: f64 = 0.; if (k & 0b00000001) != 0 { @@ -37792,7 +39666,8 @@ pub fn _mm_maskz_fnmadd_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> _ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmadd))] -pub fn _mm_mask3_fnmadd_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmadd_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { let mut fnmadd: f64 = simd_extract!(c, 0); if (k & 0b00000001) != 0 { @@ -37812,7 +39687,8 @@ pub fn _mm_mask3_fnmadd_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> _ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] -pub fn _mm_mask_fnmsub_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmsub_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m128 { unsafe { let mut fnmsub: f32 = simd_extract!(a, 0); if (k & 0b00000001) != 0 { @@ -37833,7 +39709,8 @@ pub fn _mm_mask_fnmsub_ss(a: __m128, k: __mmask8, b: __m128, c: __m128) -> __m12 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] -pub fn _mm_maskz_fnmsub_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmsub_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m128 { unsafe { let mut fnmsub: f32 = 0.; if (k & 0b00000001) != 0 { @@ -37855,7 +39732,8 @@ pub fn _mm_maskz_fnmsub_ss(k: __mmask8, a: __m128, b: __m128, c: __m128) -> __m1 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] -pub fn _mm_mask3_fnmsub_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmsub_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m128 { unsafe { let mut fnmsub: f32 = simd_extract!(c, 0); if (k & 0b00000001) != 0 { @@ -37876,7 +39754,8 @@ pub fn _mm_mask3_fnmsub_ss(a: __m128, b: __m128, c: __m128, k: __mmask8) -> __m1 #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] -pub fn _mm_mask_fnmsub_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmsub_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __m128d { unsafe { let mut fnmsub: f64 = simd_extract!(a, 0); if (k & 0b00000001) != 0 { @@ -37897,7 +39776,8 @@ pub fn _mm_mask_fnmsub_sd(a: __m128d, k: __mmask8, b: __m128d, c: __m128d) -> __ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] -pub fn _mm_maskz_fnmsub_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmsub_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> __m128d { unsafe { let mut fnmsub: f64 = 0.; if (k & 0b00000001) != 0 { @@ -37919,7 +39799,8 @@ pub fn _mm_maskz_fnmsub_sd(k: __mmask8, a: __m128d, b: __m128d, c: __m128d) -> _ #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vfnmsub))] -pub fn _mm_mask3_fnmsub_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmsub_sd(a: __m128d, b: __m128d, c: __m128d, k: __mmask8) -> __m128d { unsafe { let mut fnmsub: f64 = simd_extract!(c, 0); if (k & 0b00000001) != 0 { @@ -41499,7 +43380,8 @@ pub fn _mm_cvt_roundu32_ss(a: __m128, b: u32) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtsi2ss))] -pub fn _mm_cvti32_ss(a: __m128, b: i32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvti32_ss(a: __m128, b: i32) -> __m128 { unsafe { let b = b as f32; simd_insert!(a, 0, b) @@ -41513,7 +43395,8 @@ pub fn _mm_cvti32_ss(a: __m128, b: i32) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtsi2sd))] -pub fn _mm_cvti32_sd(a: __m128d, b: i32) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvti32_sd(a: __m128d, b: i32) -> __m128d { unsafe { let b = b as f64; simd_insert!(a, 0, b) @@ -41673,7 +43556,8 @@ pub fn _mm_cvttsd_u32(a: __m128d) -> u32 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtusi2ss))] -pub fn _mm_cvtu32_ss(a: __m128, b: u32) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtu32_ss(a: __m128, b: u32) -> __m128 { unsafe { let b = b as f32; simd_insert!(a, 0, b) @@ -41687,7 +43571,8 @@ pub fn _mm_cvtu32_ss(a: __m128, b: u32) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtusi2sd))] -pub fn _mm_cvtu32_sd(a: __m128d, b: u32) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtu32_sd(a: __m128d, b: u32) -> __m128d { unsafe { let b = b as f64; simd_insert!(a, 0, b) @@ -43139,6 +45024,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; @@ -43147,7 +45033,7 @@ mod tests { use crate::mem::{self}; #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_abs_epi32() { + const unsafe fn test_mm512_abs_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43167,7 +45053,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_abs_epi32() { + const unsafe fn test_mm512_mask_abs_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43189,7 +45075,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_abs_epi32() { + const unsafe fn test_mm512_maskz_abs_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43211,7 +45097,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_abs_epi32() { + const unsafe fn test_mm256_mask_abs_epi32() { #[rustfmt::skip] let a = _mm256_setr_epi32( 0, 1, -1, i32::MAX, @@ -43229,7 +45115,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_abs_epi32() { + const unsafe fn test_mm256_maskz_abs_epi32() { #[rustfmt::skip] let a = _mm256_setr_epi32( 0, 1, -1, i32::MAX, @@ -43247,7 +45133,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_abs_epi32() { + const unsafe fn test_mm_mask_abs_epi32() { let a = _mm_setr_epi32(i32::MIN, 100, -100, -32); let r = _mm_mask_abs_epi32(a, 0, a); assert_eq_m128i(r, a); @@ -43257,7 +45143,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_abs_epi32() { + const unsafe fn test_mm_maskz_abs_epi32() { let a = _mm_setr_epi32(i32::MIN, 100, -100, -32); let r = _mm_maskz_abs_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -43267,7 +45153,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_abs_ps() { + const unsafe fn test_mm512_abs_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -43287,7 +45173,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_abs_ps() { + const unsafe fn test_mm512_mask_abs_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -43309,7 +45195,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mov_epi32() { + const unsafe fn test_mm512_mask_mov_epi32() { let src = _mm512_set1_epi32(1); let a = _mm512_set1_epi32(2); let r = _mm512_mask_mov_epi32(src, 0, a); @@ -43319,7 +45205,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_mov_epi32() { + const unsafe fn test_mm512_maskz_mov_epi32() { let a = _mm512_set1_epi32(2); let r = _mm512_maskz_mov_epi32(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -43328,7 +45214,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_mov_epi32() { + const unsafe fn test_mm256_mask_mov_epi32() { let src = _mm256_set1_epi32(1); let a = _mm256_set1_epi32(2); let r = _mm256_mask_mov_epi32(src, 0, a); @@ -43338,7 +45224,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_mov_epi32() { + const unsafe fn test_mm256_maskz_mov_epi32() { let a = _mm256_set1_epi32(2); let r = _mm256_maskz_mov_epi32(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -43347,7 +45233,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_mov_epi32() { + const unsafe fn test_mm_mask_mov_epi32() { let src = _mm_set1_epi32(1); let a = _mm_set1_epi32(2); let r = _mm_mask_mov_epi32(src, 0, a); @@ -43357,7 +45243,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_mov_epi32() { + const unsafe fn test_mm_maskz_mov_epi32() { let a = _mm_set1_epi32(2); let r = _mm_maskz_mov_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -43366,7 +45252,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mov_ps() { + const unsafe fn test_mm512_mask_mov_ps() { let src = _mm512_set1_ps(1.); let a = _mm512_set1_ps(2.); let r = _mm512_mask_mov_ps(src, 0, a); @@ -43376,7 +45262,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_mov_ps() { + const unsafe fn test_mm512_maskz_mov_ps() { let a = _mm512_set1_ps(2.); let r = _mm512_maskz_mov_ps(0, a); assert_eq_m512(r, _mm512_setzero_ps()); @@ -43385,7 +45271,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_mov_ps() { + const unsafe fn test_mm256_mask_mov_ps() { let src = _mm256_set1_ps(1.); let a = _mm256_set1_ps(2.); let r = _mm256_mask_mov_ps(src, 0, a); @@ -43395,7 +45281,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_mov_ps() { + const unsafe fn test_mm256_maskz_mov_ps() { let a = _mm256_set1_ps(2.); let r = _mm256_maskz_mov_ps(0, a); assert_eq_m256(r, _mm256_setzero_ps()); @@ -43404,7 +45290,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_mov_ps() { + const unsafe fn test_mm_mask_mov_ps() { let src = _mm_set1_ps(1.); let a = _mm_set1_ps(2.); let r = _mm_mask_mov_ps(src, 0, a); @@ -43414,7 +45300,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_mov_ps() { + const unsafe fn test_mm_maskz_mov_ps() { let a = _mm_set1_ps(2.); let r = _mm_maskz_mov_ps(0, a); assert_eq_m128(r, _mm_setzero_ps()); @@ -43423,7 +45309,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_add_epi32() { + const unsafe fn test_mm512_add_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43444,7 +45330,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_add_epi32() { + const unsafe fn test_mm512_mask_add_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43467,7 +45353,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_add_epi32() { + const unsafe fn test_mm512_maskz_add_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43490,7 +45376,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_add_epi32() { + const unsafe fn test_mm256_mask_add_epi32() { let a = _mm256_set_epi32(0, 1, -1, i32::MAX, i32::MIN, 100, -100, -32); let b = _mm256_set1_epi32(1); let r = _mm256_mask_add_epi32(a, 0, a, b); @@ -43501,7 +45387,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_add_epi32() { + const unsafe fn test_mm256_maskz_add_epi32() { let a = _mm256_setr_epi32(0, 1, -1, i32::MAX, i32::MIN, 100, -100, -32); let b = _mm256_set1_epi32(1); let r = _mm256_maskz_add_epi32(0, a, b); @@ -43512,7 +45398,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_add_epi32() { + const unsafe fn test_mm_mask_add_epi32() { let a = _mm_set_epi32(1, -1, i32::MAX, i32::MIN); let b = _mm_set1_epi32(1); let r = _mm_mask_add_epi32(a, 0, a, b); @@ -43523,7 +45409,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_add_epi32() { + const unsafe fn test_mm_maskz_add_epi32() { let a = _mm_setr_epi32(1, -1, i32::MAX, i32::MIN); let b = _mm_set1_epi32(1); let r = _mm_maskz_add_epi32(0, a, b); @@ -43534,7 +45420,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_add_ps() { + const unsafe fn test_mm512_add_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -43555,7 +45441,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_add_ps() { + const unsafe fn test_mm512_mask_add_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -43578,7 +45464,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_add_ps() { + const unsafe fn test_mm512_maskz_add_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -43601,7 +45487,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_add_ps() { + const unsafe fn test_mm256_mask_add_ps() { let a = _mm256_set_ps(0., 1., -1., f32::MAX, f32::MIN, 100., -100., -32.); let b = _mm256_set1_ps(1.); let r = _mm256_mask_add_ps(a, 0, a, b); @@ -43612,7 +45498,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_add_ps() { + const unsafe fn test_mm256_maskz_add_ps() { let a = _mm256_set_ps(0., 1., -1., f32::MAX, f32::MIN, 100., -100., -32.); let b = _mm256_set1_ps(1.); let r = _mm256_maskz_add_ps(0, a, b); @@ -43623,7 +45509,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_add_ps() { + const unsafe fn test_mm_mask_add_ps() { let a = _mm_set_ps(1., -1., f32::MAX, f32::MIN); let b = _mm_set1_ps(1.); let r = _mm_mask_add_ps(a, 0, a, b); @@ -43634,7 +45520,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_add_ps() { + const unsafe fn test_mm_maskz_add_ps() { let a = _mm_set_ps(1., -1., f32::MAX, f32::MIN); let b = _mm_set1_ps(1.); let r = _mm_maskz_add_ps(0, a, b); @@ -43645,7 +45531,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_sub_epi32() { + const unsafe fn test_mm512_sub_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43666,7 +45552,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_sub_epi32() { + const unsafe fn test_mm512_mask_sub_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43689,7 +45575,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_sub_epi32() { + const unsafe fn test_mm512_maskz_sub_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43712,7 +45598,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_sub_epi32() { + const unsafe fn test_mm256_mask_sub_epi32() { let a = _mm256_set_epi32(0, 1, -1, i32::MAX, i32::MIN, 100, -100, -32); let b = _mm256_set1_epi32(1); let r = _mm256_mask_sub_epi32(a, 0, a, b); @@ -43723,7 +45609,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_sub_epi32() { + const unsafe fn test_mm256_maskz_sub_epi32() { let a = _mm256_set_epi32(0, 1, -1, i32::MAX, i32::MIN, 100, -100, -32); let b = _mm256_set1_epi32(1); let r = _mm256_maskz_sub_epi32(0, a, b); @@ -43734,7 +45620,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_sub_epi32() { + const unsafe fn test_mm_mask_sub_epi32() { let a = _mm_set_epi32(1, -1, i32::MAX, i32::MIN); let b = _mm_set1_epi32(1); let r = _mm_mask_sub_epi32(a, 0, a, b); @@ -43745,7 +45631,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_sub_epi32() { + const unsafe fn test_mm_maskz_sub_epi32() { let a = _mm_set_epi32(1, -1, i32::MAX, i32::MIN); let b = _mm_set1_epi32(1); let r = _mm_maskz_sub_epi32(0, a, b); @@ -43756,7 +45642,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_sub_ps() { + const unsafe fn test_mm512_sub_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -43777,7 +45663,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_sub_ps() { + const unsafe fn test_mm512_mask_sub_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -43800,7 +45686,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_sub_ps() { + const unsafe fn test_mm512_maskz_sub_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -43823,7 +45709,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_sub_ps() { + const unsafe fn test_mm256_mask_sub_ps() { let a = _mm256_set_ps(0., 1., -1., f32::MAX, f32::MIN, 100., -100., -32.); let b = _mm256_set1_ps(1.); let r = _mm256_mask_sub_ps(a, 0, a, b); @@ -43834,7 +45720,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_sub_ps() { + const unsafe fn test_mm256_maskz_sub_ps() { let a = _mm256_set_ps(0., 1., -1., f32::MAX, f32::MIN, 100., -100., -32.); let b = _mm256_set1_ps(1.); let r = _mm256_maskz_sub_ps(0, a, b); @@ -43845,7 +45731,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_sub_ps() { + const unsafe fn test_mm_mask_sub_ps() { let a = _mm_set_ps(1., -1., f32::MAX, f32::MIN); let b = _mm_set1_ps(1.); let r = _mm_mask_sub_ps(a, 0, a, b); @@ -43856,7 +45742,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_sub_ps() { + const unsafe fn test_mm_maskz_sub_ps() { let a = _mm_set_ps(1., -1., f32::MAX, f32::MIN); let b = _mm_set1_ps(1.); let r = _mm_maskz_sub_ps(0, a, b); @@ -43867,7 +45753,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mullo_epi32() { + const unsafe fn test_mm512_mullo_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43884,7 +45770,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mullo_epi32() { + const unsafe fn test_mm512_mask_mullo_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43907,7 +45793,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_mullo_epi32() { + const unsafe fn test_mm512_maskz_mullo_epi32() { #[rustfmt::skip] let a = _mm512_setr_epi32( 0, 1, -1, i32::MAX, @@ -43924,7 +45810,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_mullo_epi32() { + const unsafe fn test_mm256_mask_mullo_epi32() { let a = _mm256_set_epi32(0, 1, -1, i32::MAX, i32::MIN, 100, -100, -32); let b = _mm256_set1_epi32(2); let r = _mm256_mask_mullo_epi32(a, 0, a, b); @@ -43935,7 +45821,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_mullo_epi32() { + const unsafe fn test_mm256_maskz_mullo_epi32() { let a = _mm256_set_epi32(0, 1, -1, i32::MAX, i32::MIN, 100, -100, -32); let b = _mm256_set1_epi32(2); let r = _mm256_maskz_mullo_epi32(0, a, b); @@ -43946,7 +45832,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_mullo_epi32() { + const unsafe fn test_mm_mask_mullo_epi32() { let a = _mm_set_epi32(1, -1, i32::MAX, i32::MIN); let b = _mm_set1_epi32(2); let r = _mm_mask_mullo_epi32(a, 0, a, b); @@ -43957,7 +45843,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_mullo_epi32() { + const unsafe fn test_mm_maskz_mullo_epi32() { let a = _mm_set_epi32(1, -1, i32::MAX, i32::MIN); let b = _mm_set1_epi32(2); let r = _mm_maskz_mullo_epi32(0, a, b); @@ -43968,7 +45854,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mul_ps() { + const unsafe fn test_mm512_mul_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -43990,7 +45876,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mul_ps() { + const unsafe fn test_mm512_mask_mul_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -44013,7 +45899,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_mul_ps() { + const unsafe fn test_mm512_maskz_mul_ps() { #[rustfmt::skip] let a = _mm512_setr_ps( 0., 1., -1., f32::MAX, @@ -44036,7 +45922,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_mul_ps() { + const unsafe fn test_mm256_mask_mul_ps() { let a = _mm256_set_ps(0., 1., -1., f32::MAX, f32::MIN, 100., -100., -32.); let b = _mm256_set1_ps(2.); let r = _mm256_mask_mul_ps(a, 0, a, b); @@ -44051,7 +45937,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_mul_ps() { + const unsafe fn test_mm256_maskz_mul_ps() { let a = _mm256_set_ps(0., 1., -1., f32::MAX, f32::MIN, 100., -100., -32.); let b = _mm256_set1_ps(2.); let r = _mm256_maskz_mul_ps(0, a, b); @@ -44066,7 +45952,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_mul_ps() { + const unsafe fn test_mm_mask_mul_ps() { let a = _mm_set_ps(1., -1., f32::MAX, f32::MIN); let b = _mm_set1_ps(2.); let r = _mm_mask_mul_ps(a, 0, a, b); @@ -44077,7 +45963,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_mul_ps() { + const unsafe fn test_mm_maskz_mul_ps() { let a = _mm_set_ps(1., -1., f32::MAX, f32::MIN); let b = _mm_set1_ps(2.); let r = _mm_maskz_mul_ps(0, a, b); @@ -44088,7 +45974,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_div_ps() { + const unsafe fn test_mm512_div_ps() { let a = _mm512_setr_ps( 0., 1., -1., -2., 100., 100., -100., -32., 0., 1., -1., 1000., -131., 100., -100., -32., ); @@ -44107,7 +45993,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_div_ps() { + const unsafe fn test_mm512_mask_div_ps() { let a = _mm512_setr_ps( 0., 1., -1., -2., 100., 100., -100., -32., 0., 1., -1., 1000., -131., 100., -100., -32., ); @@ -44128,7 +46014,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_div_ps() { + const unsafe fn test_mm512_maskz_div_ps() { let a = _mm512_setr_ps( 0., 1., -1., -2., 100., 100., -100., -32., 0., 1., -1., 1000., -131., 100., -100., -32., ); @@ -44149,7 +46035,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_div_ps() { + const unsafe fn test_mm256_mask_div_ps() { let a = _mm256_set_ps(0., 1., -1., -2., 100., 100., -100., -32.); let b = _mm256_set_ps(2., 2., 2., 2., 2., 0., 2., 2.); let r = _mm256_mask_div_ps(a, 0, a, b); @@ -44160,7 +46046,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_div_ps() { + const unsafe fn test_mm256_maskz_div_ps() { let a = _mm256_set_ps(0., 1., -1., -2., 100., 100., -100., -32.); let b = _mm256_set_ps(2., 2., 2., 2., 2., 0., 2., 2.); let r = _mm256_maskz_div_ps(0, a, b); @@ -44171,7 +46057,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_div_ps() { + const unsafe fn test_mm_mask_div_ps() { let a = _mm_set_ps(100., 100., -100., -32.); let b = _mm_set_ps(2., 0., 2., 2.); let r = _mm_mask_div_ps(a, 0, a, b); @@ -44182,7 +46068,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_div_ps() { + const unsafe fn test_mm_maskz_div_ps() { let a = _mm_set_ps(100., 100., -100., -32.); let b = _mm_set_ps(2., 0., 2., 2.); let r = _mm_maskz_div_ps(0, a, b); @@ -44193,7 +46079,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_max_epi32() { + const unsafe fn test_mm512_max_epi32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_max_epi32(a, b); @@ -44202,7 +46088,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_max_epi32() { + const unsafe fn test_mm512_mask_max_epi32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_mask_max_epi32(a, 0, a, b); @@ -44213,7 +46099,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_max_epi32() { + const unsafe fn test_mm512_maskz_max_epi32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_maskz_max_epi32(0, a, b); @@ -44224,7 +46110,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_max_epi32() { + const unsafe fn test_mm256_mask_max_epi32() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_mask_max_epi32(a, 0, a, b); @@ -44235,7 +46121,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_max_epi32() { + const unsafe fn test_mm256_maskz_max_epi32() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_maskz_max_epi32(0, a, b); @@ -44246,7 +46132,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_max_epi32() { + const unsafe fn test_mm_mask_max_epi32() { let a = _mm_set_epi32(0, 1, 2, 3); let b = _mm_set_epi32(3, 2, 1, 0); let r = _mm_mask_max_epi32(a, 0, a, b); @@ -44257,7 +46143,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_max_epi32() { + const unsafe fn test_mm_maskz_max_epi32() { let a = _mm_set_epi32(0, 1, 2, 3); let b = _mm_set_epi32(3, 2, 1, 0); let r = _mm_maskz_max_epi32(0, a, b); @@ -44361,7 +46247,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_max_epu32() { + const unsafe fn test_mm512_max_epu32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_max_epu32(a, b); @@ -44370,7 +46256,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_max_epu32() { + const unsafe fn test_mm512_mask_max_epu32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_mask_max_epu32(a, 0, a, b); @@ -44381,7 +46267,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_max_epu32() { + const unsafe fn test_mm512_maskz_max_epu32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_maskz_max_epu32(0, a, b); @@ -44392,7 +46278,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_max_epu32() { + const unsafe fn test_mm256_mask_max_epu32() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_mask_max_epu32(a, 0, a, b); @@ -44403,7 +46289,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_max_epu32() { + const unsafe fn test_mm256_maskz_max_epu32() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_maskz_max_epu32(0, a, b); @@ -44414,7 +46300,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_max_epu32() { + const unsafe fn test_mm_mask_max_epu32() { let a = _mm_set_epi32(0, 1, 2, 3); let b = _mm_set_epi32(3, 2, 1, 0); let r = _mm_mask_max_epu32(a, 0, a, b); @@ -44425,7 +46311,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_max_epu32() { + const unsafe fn test_mm_maskz_max_epu32() { let a = _mm_set_epi32(0, 1, 2, 3); let b = _mm_set_epi32(3, 2, 1, 0); let r = _mm_maskz_max_epu32(0, a, b); @@ -44436,7 +46322,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_min_epi32() { + const unsafe fn test_mm512_min_epi32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_min_epi32(a, b); @@ -44445,7 +46331,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_min_epi32() { + const unsafe fn test_mm512_mask_min_epi32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_mask_min_epi32(a, 0, a, b); @@ -44456,7 +46342,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_min_epi32() { + const unsafe fn test_mm512_maskz_min_epi32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_maskz_min_epi32(0, a, b); @@ -44467,7 +46353,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_min_epi32() { + const unsafe fn test_mm256_mask_min_epi32() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_mask_min_epi32(a, 0, a, b); @@ -44478,7 +46364,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_min_epi32() { + const unsafe fn test_mm256_maskz_min_epi32() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_maskz_min_epi32(0, a, b); @@ -44489,7 +46375,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_min_epi32() { + const unsafe fn test_mm_mask_min_epi32() { let a = _mm_set_epi32(0, 1, 2, 3); let b = _mm_set_epi32(3, 2, 1, 0); let r = _mm_mask_min_epi32(a, 0, a, b); @@ -44500,7 +46386,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_min_epi32() { + const unsafe fn test_mm_maskz_min_epi32() { let a = _mm_set_epi32(0, 1, 2, 3); let b = _mm_set_epi32(3, 2, 1, 0); let r = _mm_maskz_min_epi32(0, a, b); @@ -44604,7 +46490,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_min_epu32() { + const unsafe fn test_mm512_min_epu32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_min_epu32(a, b); @@ -44613,7 +46499,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_min_epu32() { + const unsafe fn test_mm512_mask_min_epu32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_mask_min_epu32(a, 0, a, b); @@ -44624,7 +46510,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_min_epu32() { + const unsafe fn test_mm512_maskz_min_epu32() { let a = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm512_setr_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_maskz_min_epu32(0, a, b); @@ -44635,7 +46521,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_min_epu32() { + const unsafe fn test_mm256_mask_min_epu32() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_mask_min_epu32(a, 0, a, b); @@ -44646,7 +46532,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_min_epu32() { + const unsafe fn test_mm256_maskz_min_epu32() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_maskz_min_epu32(0, a, b); @@ -44657,7 +46543,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_min_epu32() { + const unsafe fn test_mm_mask_min_epu32() { let a = _mm_set_epi32(0, 1, 2, 3); let b = _mm_set_epi32(3, 2, 1, 0); let r = _mm_mask_min_epu32(a, 0, a, b); @@ -44668,7 +46554,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_min_epu32() { + const unsafe fn test_mm_maskz_min_epu32() { let a = _mm_set_epi32(0, 1, 2, 3); let b = _mm_set_epi32(3, 2, 1, 0); let r = _mm_maskz_min_epu32(0, a, b); @@ -44759,7 +46645,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fmadd_ps() { + const unsafe fn test_mm512_fmadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -44773,7 +46659,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fmadd_ps() { + const unsafe fn test_mm512_mask_fmadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -44789,7 +46675,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fmadd_ps() { + const unsafe fn test_mm512_maskz_fmadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -44805,7 +46691,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fmadd_ps() { + const unsafe fn test_mm512_mask3_fmadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -44821,7 +46707,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fmadd_ps() { + const unsafe fn test_mm256_mask_fmadd_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -44833,7 +46719,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fmadd_ps() { + const unsafe fn test_mm256_maskz_fmadd_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -44845,7 +46731,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fmadd_ps() { + const unsafe fn test_mm256_mask3_fmadd_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -44857,7 +46743,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fmadd_ps() { + const unsafe fn test_mm_mask_fmadd_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -44869,7 +46755,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fmadd_ps() { + const unsafe fn test_mm_maskz_fmadd_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -44881,7 +46767,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fmadd_ps() { + const unsafe fn test_mm_mask3_fmadd_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -44893,7 +46779,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fmsub_ps() { + const unsafe fn test_mm512_fmsub_ps() { let a = _mm512_setr_ps( 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., ); @@ -44911,7 +46797,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fmsub_ps() { + const unsafe fn test_mm512_mask_fmsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -44927,7 +46813,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fmsub_ps() { + const unsafe fn test_mm512_maskz_fmsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -44943,7 +46829,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fmsub_ps() { + const unsafe fn test_mm512_mask3_fmsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -44961,7 +46847,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fmsub_ps() { + const unsafe fn test_mm256_mask_fmsub_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -44973,7 +46859,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fmsub_ps() { + const unsafe fn test_mm256_maskz_fmsub_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -44985,7 +46871,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fmsub_ps() { + const unsafe fn test_mm256_mask3_fmsub_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -44997,7 +46883,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fmsub_ps() { + const unsafe fn test_mm_mask_fmsub_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45009,7 +46895,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fmsub_ps() { + const unsafe fn test_mm_maskz_fmsub_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45021,7 +46907,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fmsub_ps() { + const unsafe fn test_mm_mask3_fmsub_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45033,7 +46919,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fmaddsub_ps() { + const unsafe fn test_mm512_fmaddsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45047,7 +46933,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fmaddsub_ps() { + const unsafe fn test_mm512_mask_fmaddsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45063,7 +46949,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fmaddsub_ps() { + const unsafe fn test_mm512_maskz_fmaddsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45079,7 +46965,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fmaddsub_ps() { + const unsafe fn test_mm512_mask3_fmaddsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45097,7 +46983,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fmaddsub_ps() { + const unsafe fn test_mm256_mask_fmaddsub_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45109,7 +46995,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fmaddsub_ps() { + const unsafe fn test_mm256_maskz_fmaddsub_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45121,7 +47007,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fmaddsub_ps() { + const unsafe fn test_mm256_mask3_fmaddsub_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45133,7 +47019,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fmaddsub_ps() { + const unsafe fn test_mm_mask_fmaddsub_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45145,7 +47031,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fmaddsub_ps() { + const unsafe fn test_mm_maskz_fmaddsub_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45157,7 +47043,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fmaddsub_ps() { + const unsafe fn test_mm_mask3_fmaddsub_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45169,7 +47055,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fmsubadd_ps() { + const unsafe fn test_mm512_fmsubadd_ps() { let a = _mm512_setr_ps( 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., ); @@ -45187,7 +47073,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fmsubadd_ps() { + const unsafe fn test_mm512_mask_fmsubadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45203,7 +47089,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fmsubadd_ps() { + const unsafe fn test_mm512_maskz_fmsubadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45219,7 +47105,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fmsubadd_ps() { + const unsafe fn test_mm512_mask3_fmsubadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45237,7 +47123,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fmsubadd_ps() { + const unsafe fn test_mm256_mask_fmsubadd_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45249,7 +47135,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fmsubadd_ps() { + const unsafe fn test_mm256_maskz_fmsubadd_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45261,7 +47147,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fmsubadd_ps() { + const unsafe fn test_mm256_mask3_fmsubadd_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45273,7 +47159,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fmsubadd_ps() { + const unsafe fn test_mm_mask_fmsubadd_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45285,7 +47171,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fmsubadd_ps() { + const unsafe fn test_mm_maskz_fmsubadd_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45297,7 +47183,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fmsubadd_ps() { + const unsafe fn test_mm_mask3_fmsubadd_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45309,7 +47195,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fnmadd_ps() { + const unsafe fn test_mm512_fnmadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45323,7 +47209,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fnmadd_ps() { + const unsafe fn test_mm512_mask_fnmadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45339,7 +47225,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fnmadd_ps() { + const unsafe fn test_mm512_maskz_fnmadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45355,7 +47241,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fnmadd_ps() { + const unsafe fn test_mm512_mask3_fnmadd_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45373,7 +47259,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fnmadd_ps() { + const unsafe fn test_mm256_mask_fnmadd_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45385,7 +47271,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fnmadd_ps() { + const unsafe fn test_mm256_maskz_fnmadd_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45397,7 +47283,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fnmadd_ps() { + const unsafe fn test_mm256_mask3_fnmadd_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45409,7 +47295,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fnmadd_ps() { + const unsafe fn test_mm_mask_fnmadd_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45421,7 +47307,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fnmadd_ps() { + const unsafe fn test_mm_maskz_fnmadd_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45433,7 +47319,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fnmadd_ps() { + const unsafe fn test_mm_mask3_fnmadd_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45445,7 +47331,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fnmsub_ps() { + const unsafe fn test_mm512_fnmsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45459,7 +47345,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fnmsub_ps() { + const unsafe fn test_mm512_mask_fnmsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45475,7 +47361,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fnmsub_ps() { + const unsafe fn test_mm512_maskz_fnmsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45491,7 +47377,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fnmsub_ps() { + const unsafe fn test_mm512_mask3_fnmsub_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., @@ -45509,7 +47395,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fnmsub_ps() { + const unsafe fn test_mm256_mask_fnmsub_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45521,7 +47407,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fnmsub_ps() { + const unsafe fn test_mm256_maskz_fnmsub_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45533,7 +47419,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fnmsub_ps() { + const unsafe fn test_mm256_mask3_fnmsub_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm256_set1_ps(1.); @@ -45545,7 +47431,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fnmsub_ps() { + const unsafe fn test_mm_mask_fnmsub_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45557,7 +47443,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fnmsub_ps() { + const unsafe fn test_mm_maskz_fnmsub_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -45569,7 +47455,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fnmsub_ps() { + const unsafe fn test_mm_mask3_fnmsub_ps() { let a = _mm_set1_ps(1.); let b = _mm_set_ps(0., 1., 2., 3.); let c = _mm_set1_ps(1.); @@ -47731,7 +49617,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi8_epi32() { + const unsafe fn test_mm512_cvtepi8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi8_epi32(a); let e = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -47739,7 +49625,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi8_epi32() { + const unsafe fn test_mm512_mask_cvtepi8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi32(-1); let r = _mm512_mask_cvtepi8_epi32(src, 0, a); @@ -47750,7 +49636,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi8_epi32() { + const unsafe fn test_mm512_maskz_cvtepi8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi8_epi32(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -47760,7 +49646,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi8_epi32() { + const unsafe fn test_mm256_mask_cvtepi8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm256_set1_epi32(-1); let r = _mm256_mask_cvtepi8_epi32(src, 0, a); @@ -47771,7 +49657,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi8_epi32() { + const unsafe fn test_mm256_maskz_cvtepi8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_maskz_cvtepi8_epi32(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -47781,7 +49667,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi8_epi32() { + const unsafe fn test_mm_mask_cvtepi8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm_set1_epi32(-1); let r = _mm_mask_cvtepi8_epi32(src, 0, a); @@ -47792,7 +49678,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepi8_epi32() { + const unsafe fn test_mm_maskz_cvtepi8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_maskz_cvtepi8_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -47802,7 +49688,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepu8_epi32() { + const unsafe fn test_mm512_cvtepu8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepu8_epi32(a); let e = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -47810,7 +49696,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepu8_epi32() { + const unsafe fn test_mm512_mask_cvtepu8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi32(-1); let r = _mm512_mask_cvtepu8_epi32(src, 0, a); @@ -47821,7 +49707,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepu8_epi32() { + const unsafe fn test_mm512_maskz_cvtepu8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepu8_epi32(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -47831,7 +49717,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepu8_epi32() { + const unsafe fn test_mm256_mask_cvtepu8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm256_set1_epi32(-1); let r = _mm256_mask_cvtepu8_epi32(src, 0, a); @@ -47842,7 +49728,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepu8_epi32() { + const unsafe fn test_mm256_maskz_cvtepu8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_maskz_cvtepu8_epi32(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -47852,7 +49738,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepu8_epi32() { + const unsafe fn test_mm_mask_cvtepu8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm_set1_epi32(-1); let r = _mm_mask_cvtepu8_epi32(src, 0, a); @@ -47863,7 +49749,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepu8_epi32() { + const unsafe fn test_mm_maskz_cvtepu8_epi32() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_maskz_cvtepu8_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -47873,7 +49759,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi16_epi32() { + const unsafe fn test_mm512_cvtepi16_epi32() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi16_epi32(a); let e = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -47881,7 +49767,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi16_epi32() { + const unsafe fn test_mm512_mask_cvtepi16_epi32() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi32(-1); let r = _mm512_mask_cvtepi16_epi32(src, 0, a); @@ -47892,7 +49778,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi16_epi32() { + const unsafe fn test_mm512_maskz_cvtepi16_epi32() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi16_epi32(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -47902,7 +49788,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi16_epi32() { + const unsafe fn test_mm256_mask_cvtepi16_epi32() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let src = _mm256_set1_epi32(-1); let r = _mm256_mask_cvtepi16_epi32(src, 0, a); @@ -47913,7 +49799,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi16_epi32() { + const unsafe fn test_mm256_maskz_cvtepi16_epi32() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm256_maskz_cvtepi16_epi32(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -47923,7 +49809,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi16_epi32() { + const unsafe fn test_mm_mask_cvtepi16_epi32() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let src = _mm_set1_epi32(-1); let r = _mm_mask_cvtepi16_epi32(src, 0, a); @@ -47934,7 +49820,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepi16_epi32() { + const unsafe fn test_mm_maskz_cvtepi16_epi32() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm_maskz_cvtepi16_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -47944,7 +49830,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepu16_epi32() { + const unsafe fn test_mm512_cvtepu16_epi32() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepu16_epi32(a); let e = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -47952,7 +49838,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepu16_epi32() { + const unsafe fn test_mm512_mask_cvtepu16_epi32() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi32(-1); let r = _mm512_mask_cvtepu16_epi32(src, 0, a); @@ -47963,7 +49849,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepu16_epi32() { + const unsafe fn test_mm512_maskz_cvtepu16_epi32() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepu16_epi32(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -47973,7 +49859,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepu16_epi32() { + const unsafe fn test_mm256_mask_cvtepu16_epi32() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm256_set1_epi32(-1); let r = _mm256_mask_cvtepu16_epi32(src, 0, a); @@ -47984,7 +49870,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepu16_epi32() { + const unsafe fn test_mm256_maskz_cvtepu16_epi32() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_maskz_cvtepu16_epi32(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -47994,7 +49880,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepu16_epi32() { + const unsafe fn test_mm_mask_cvtepu16_epi32() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm_set1_epi32(-1); let r = _mm_mask_cvtepu16_epi32(src, 0, a); @@ -48005,7 +49891,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepu16_epi32() { + const unsafe fn test_mm_maskz_cvtepu16_epi32() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_maskz_cvtepu16_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -48015,7 +49901,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi32_ps() { + const unsafe fn test_mm512_cvtepi32_ps() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi32_ps(a); let e = _mm512_set_ps( @@ -48025,7 +49911,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi32_ps() { + const unsafe fn test_mm512_mask_cvtepi32_ps() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_ps(-1.); let r = _mm512_mask_cvtepi32_ps(src, 0, a); @@ -48038,7 +49924,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi32_ps() { + const unsafe fn test_mm512_maskz_cvtepi32_ps() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi32_ps(0, a); assert_eq_m512(r, _mm512_setzero_ps()); @@ -48050,7 +49936,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi32_ps() { + const unsafe fn test_mm256_mask_cvtepi32_ps() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let src = _mm256_set1_ps(-1.); let r = _mm256_mask_cvtepi32_ps(src, 0, a); @@ -48061,7 +49947,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi32_ps() { + const unsafe fn test_mm256_maskz_cvtepi32_ps() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_maskz_cvtepi32_ps(0, a); assert_eq_m256(r, _mm256_setzero_ps()); @@ -48071,7 +49957,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi32_ps() { + const unsafe fn test_mm_mask_cvtepi32_ps() { let a = _mm_set_epi32(1, 2, 3, 4); let src = _mm_set1_ps(-1.); let r = _mm_mask_cvtepi32_ps(src, 0, a); @@ -48082,7 +49968,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepi32_ps() { + const unsafe fn test_mm_maskz_cvtepi32_ps() { let a = _mm_set_epi32(1, 2, 3, 4); let r = _mm_maskz_cvtepi32_ps(0, a); assert_eq_m128(r, _mm_setzero_ps()); @@ -48092,7 +49978,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepu32_ps() { + const unsafe fn test_mm512_cvtepu32_ps() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepu32_ps(a); let e = _mm512_set_ps( @@ -48102,7 +49988,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepu32_ps() { + const unsafe fn test_mm512_mask_cvtepu32_ps() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_ps(-1.); let r = _mm512_mask_cvtepu32_ps(src, 0, a); @@ -48115,7 +50001,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepu32_ps() { + const unsafe fn test_mm512_maskz_cvtepu32_ps() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepu32_ps(0, a); assert_eq_m512(r, _mm512_setzero_ps()); @@ -48127,7 +50013,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi32_epi16() { + const unsafe fn test_mm512_cvtepi32_epi16() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi32_epi16(a); let e = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -48135,7 +50021,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi32_epi16() { + const unsafe fn test_mm512_mask_cvtepi32_epi16() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm256_set1_epi16(-1); let r = _mm512_mask_cvtepi32_epi16(src, 0, a); @@ -48146,7 +50032,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi32_epi16() { + const unsafe fn test_mm512_maskz_cvtepi32_epi16() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi32_epi16(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -48156,7 +50042,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cvtepi32_epi16() { + const unsafe fn test_mm256_cvtepi32_epi16() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm256_cvtepi32_epi16(a); let e = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); @@ -48164,7 +50050,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi32_epi16() { + const unsafe fn test_mm256_mask_cvtepi32_epi16() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let src = _mm_set1_epi16(-1); let r = _mm256_mask_cvtepi32_epi16(src, 0, a); @@ -48175,7 +50061,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi32_epi16() { + const unsafe fn test_mm256_maskz_cvtepi32_epi16() { let a = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm256_maskz_cvtepi32_epi16(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -48214,7 +50100,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi32_epi8() { + const unsafe fn test_mm512_cvtepi32_epi8() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi32_epi8(a); let e = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -48222,7 +50108,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi32_epi8() { + const unsafe fn test_mm512_mask_cvtepi32_epi8() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm_set1_epi8(-1); let r = _mm512_mask_cvtepi32_epi8(src, 0, a); @@ -48233,7 +50119,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi32_epi8() { + const unsafe fn test_mm512_maskz_cvtepi32_epi8() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi32_epi8(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -49982,7 +51868,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmplt_epu32_mask() { + const unsafe fn test_mm512_cmplt_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -49992,7 +51878,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmplt_epu32_mask() { + const unsafe fn test_mm512_mask_cmplt_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50003,7 +51889,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmplt_epu32_mask() { + const unsafe fn test_mm256_cmplt_epu32_mask() { let a = _mm256_set_epi32(0, 1, 2, u32::MAX as i32, i32::MAX, 101, 100, 99); let b = _mm256_set1_epi32(1); let r = _mm256_cmplt_epu32_mask(a, b); @@ -50011,7 +51897,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmplt_epu32_mask() { + const unsafe fn test_mm256_mask_cmplt_epu32_mask() { let a = _mm256_set_epi32(0, 1, 2, u32::MAX as i32, i32::MAX, 101, 100, 99); let b = _mm256_set1_epi32(1); let mask = 0b11111111; @@ -50020,7 +51906,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmplt_epu32_mask() { + const unsafe fn test_mm_cmplt_epu32_mask() { let a = _mm_set_epi32(0, 1, 2, u32::MAX as i32); let b = _mm_set1_epi32(1); let r = _mm_cmplt_epu32_mask(a, b); @@ -50028,7 +51914,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmplt_epu32_mask() { + const unsafe fn test_mm_mask_cmplt_epu32_mask() { let a = _mm_set_epi32(0, 1, 2, u32::MAX as i32); let b = _mm_set1_epi32(1); let mask = 0b11111111; @@ -50037,7 +51923,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpgt_epu32_mask() { + const unsafe fn test_mm512_cmpgt_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50047,7 +51933,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpgt_epu32_mask() { + const unsafe fn test_mm512_mask_cmpgt_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50058,7 +51944,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpgt_epu32_mask() { + const unsafe fn test_mm256_cmpgt_epu32_mask() { let a = _mm256_set_epi32(0, 1, 2, u32::MAX as i32, i32::MAX, 99, 100, 101); let b = _mm256_set1_epi32(1); let r = _mm256_cmpgt_epu32_mask(a, b); @@ -50066,7 +51952,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpgt_epu32_mask() { + const unsafe fn test_mm256_mask_cmpgt_epu32_mask() { let a = _mm256_set_epi32(0, 1, 2, u32::MAX as i32, i32::MAX, 99, 100, 101); let b = _mm256_set1_epi32(1); let mask = 0b11111111; @@ -50075,7 +51961,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpgt_epu32_mask() { + const unsafe fn test_mm_cmpgt_epu32_mask() { let a = _mm_set_epi32(0, 1, 2, u32::MAX as i32); let b = _mm_set1_epi32(1); let r = _mm_cmpgt_epu32_mask(a, b); @@ -50083,7 +51969,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpgt_epu32_mask() { + const unsafe fn test_mm_mask_cmpgt_epu32_mask() { let a = _mm_set_epi32(0, 1, 2, u32::MAX as i32); let b = _mm_set1_epi32(1); let mask = 0b11111111; @@ -50092,7 +51978,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmple_epu32_mask() { + const unsafe fn test_mm512_cmple_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50104,7 +51990,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmple_epu32_mask() { + const unsafe fn test_mm512_mask_cmple_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50117,7 +52003,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmple_epu32_mask() { + const unsafe fn test_mm256_cmple_epu32_mask() { let a = _mm256_set_epi32(0, 1, 2, u32::MAX as i32, i32::MAX, 200, 100, 101); let b = _mm256_set1_epi32(1); let r = _mm256_cmple_epu32_mask(a, b); @@ -50125,7 +52011,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmple_epu32_mask() { + const unsafe fn test_mm256_mask_cmple_epu32_mask() { let a = _mm256_set_epi32(0, 1, 2, u32::MAX as i32, i32::MAX, 200, 100, 101); let b = _mm256_set1_epi32(1); let mask = 0b11111111; @@ -50134,7 +52020,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmple_epu32_mask() { + const unsafe fn test_mm_cmple_epu32_mask() { let a = _mm_set_epi32(0, 1, 2, u32::MAX as i32); let b = _mm_set1_epi32(1); let r = _mm_cmple_epu32_mask(a, b); @@ -50142,7 +52028,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmple_epu32_mask() { + const unsafe fn test_mm_mask_cmple_epu32_mask() { let a = _mm_set_epi32(0, 1, 2, u32::MAX as i32); let b = _mm_set1_epi32(1); let mask = 0b11111111; @@ -50151,7 +52037,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpge_epu32_mask() { + const unsafe fn test_mm512_cmpge_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50163,7 +52049,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpge_epu32_mask() { + const unsafe fn test_mm512_mask_cmpge_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50173,7 +52059,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpge_epu32_mask() { + const unsafe fn test_mm256_cmpge_epu32_mask() { let a = _mm256_set_epi32(0, 1, 2, u32::MAX as i32, i32::MAX, 300, 100, 200); let b = _mm256_set1_epi32(1); let r = _mm256_cmpge_epu32_mask(a, b); @@ -50181,7 +52067,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpge_epu32_mask() { + const unsafe fn test_mm256_mask_cmpge_epu32_mask() { let a = _mm256_set_epi32(0, 1, 2, u32::MAX as i32, i32::MAX, 300, 100, 200); let b = _mm256_set1_epi32(1); let mask = 0b11111111; @@ -50190,7 +52076,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpge_epu32_mask() { + const unsafe fn test_mm_cmpge_epu32_mask() { let a = _mm_set_epi32(0, 1, 2, u32::MAX as i32); let b = _mm_set1_epi32(1); let r = _mm_cmpge_epu32_mask(a, b); @@ -50198,7 +52084,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpge_epu32_mask() { + const unsafe fn test_mm_mask_cmpge_epu32_mask() { let a = _mm_set_epi32(0, 1, 2, u32::MAX as i32); let b = _mm_set1_epi32(1); let mask = 0b11111111; @@ -50207,7 +52093,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpeq_epu32_mask() { + const unsafe fn test_mm512_cmpeq_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50219,7 +52105,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpeq_epu32_mask() { + const unsafe fn test_mm512_mask_cmpeq_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50232,7 +52118,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpeq_epu32_mask() { + const unsafe fn test_mm256_cmpeq_epu32_mask() { let a = _mm256_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set_epi32(0, 1, 13, 42, i32::MAX, i32::MIN, 100, -100); let m = _mm256_cmpeq_epu32_mask(b, a); @@ -50240,7 +52126,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpeq_epu32_mask() { + const unsafe fn test_mm256_mask_cmpeq_epu32_mask() { let a = _mm256_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set_epi32(0, 1, 13, 42, i32::MAX, i32::MIN, 100, -100); let mask = 0b01111010; @@ -50249,7 +52135,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpeq_epu32_mask() { + const unsafe fn test_mm_cmpeq_epu32_mask() { let a = _mm_set_epi32(0, 1, -1, u32::MAX as i32); let b = _mm_set_epi32(0, 1, 13, 42); let m = _mm_cmpeq_epu32_mask(b, a); @@ -50257,7 +52143,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpeq_epu32_mask() { + const unsafe fn test_mm_mask_cmpeq_epu32_mask() { let a = _mm_set_epi32(0, 1, -1, u32::MAX as i32); let b = _mm_set_epi32(0, 1, 13, 42); let mask = 0b11111111; @@ -50266,7 +52152,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpneq_epu32_mask() { + const unsafe fn test_mm512_cmpneq_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50278,7 +52164,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpneq_epu32_mask() { + const unsafe fn test_mm512_mask_cmpneq_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, -100, 100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, -100, 100); @@ -50291,7 +52177,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpneq_epu32_mask() { + const unsafe fn test_mm256_cmpneq_epu32_mask() { let a = _mm256_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, -100, 100); let b = _mm256_set_epi32(0, 1, 13, 42, i32::MAX, i32::MIN, -100, 100); let r = _mm256_cmpneq_epu32_mask(b, a); @@ -50299,7 +52185,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpneq_epu32_mask() { + const unsafe fn test_mm256_mask_cmpneq_epu32_mask() { let a = _mm256_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, -100, 100); let b = _mm256_set_epi32(0, 1, 13, 42, i32::MAX, i32::MIN, -100, 100); let mask = 0b11111111; @@ -50308,7 +52194,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpneq_epu32_mask() { + const unsafe fn test_mm_cmpneq_epu32_mask() { let a = _mm_set_epi32(0, 1, -1, u32::MAX as i32); let b = _mm_set_epi32(0, 1, 13, 42); let r = _mm_cmpneq_epu32_mask(b, a); @@ -50316,7 +52202,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpneq_epu32_mask() { + const unsafe fn test_mm_mask_cmpneq_epu32_mask() { let a = _mm_set_epi32(0, 1, -1, u32::MAX as i32); let b = _mm_set_epi32(0, 1, 13, 42); let mask = 0b11111111; @@ -50325,7 +52211,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmp_epu32_mask() { + const unsafe fn test_mm512_cmp_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50335,7 +52221,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmp_epu32_mask() { + const unsafe fn test_mm512_mask_cmp_epu32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50346,7 +52232,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmp_epu32_mask() { + const unsafe fn test_mm256_cmp_epu32_mask() { let a = _mm256_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let m = _mm256_cmp_epu32_mask::<_MM_CMPINT_LT>(a, b); @@ -50354,7 +52240,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmp_epu32_mask() { + const unsafe fn test_mm256_mask_cmp_epu32_mask() { let a = _mm256_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let mask = 0b11111111; @@ -50363,7 +52249,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmp_epu32_mask() { + const unsafe fn test_mm_cmp_epu32_mask() { let a = _mm_set_epi32(0, 1, -1, i32::MAX); let b = _mm_set1_epi32(1); let m = _mm_cmp_epu32_mask::<_MM_CMPINT_LT>(a, b); @@ -50371,7 +52257,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmp_epu32_mask() { + const unsafe fn test_mm_mask_cmp_epu32_mask() { let a = _mm_set_epi32(0, 1, -1, i32::MAX); let b = _mm_set1_epi32(1); let mask = 0b11111111; @@ -50380,7 +52266,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmplt_epi32_mask() { + const unsafe fn test_mm512_cmplt_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50390,7 +52276,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmplt_epi32_mask() { + const unsafe fn test_mm512_mask_cmplt_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50401,7 +52287,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmplt_epi32_mask() { + const unsafe fn test_mm256_cmplt_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 101, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let r = _mm256_cmplt_epi32_mask(a, b); @@ -50409,7 +52295,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmplt_epi32_mask() { + const unsafe fn test_mm256_mask_cmplt_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 101, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let mask = 0b11111111; @@ -50418,7 +52304,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmplt_epi32_mask() { + const unsafe fn test_mm_cmplt_epi32_mask() { let a = _mm_set_epi32(i32::MAX, i32::MIN, 100, -100); let b = _mm_set1_epi32(-1); let r = _mm_cmplt_epi32_mask(a, b); @@ -50426,7 +52312,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmplt_epi32_mask() { + const unsafe fn test_mm_mask_cmplt_epi32_mask() { let a = _mm_set_epi32(i32::MAX, i32::MIN, 100, -100); let b = _mm_set1_epi32(-1); let mask = 0b11111111; @@ -50435,7 +52321,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpgt_epi32_mask() { + const unsafe fn test_mm512_cmpgt_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); @@ -50445,7 +52331,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpgt_epi32_mask() { + const unsafe fn test_mm512_mask_cmpgt_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); @@ -50456,7 +52342,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpgt_epi32_mask() { + const unsafe fn test_mm256_cmpgt_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let r = _mm256_cmpgt_epi32_mask(a, b); @@ -50464,7 +52350,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpgt_epi32_mask() { + const unsafe fn test_mm256_mask_cmpgt_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let mask = 0b11111111; @@ -50473,7 +52359,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpgt_epi32_mask() { + const unsafe fn test_mm_cmpgt_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 13); let b = _mm_set1_epi32(-1); let r = _mm_cmpgt_epi32_mask(a, b); @@ -50481,7 +52367,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpgt_epi32_mask() { + const unsafe fn test_mm_mask_cmpgt_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 13); let b = _mm_set1_epi32(-1); let mask = 0b11111111; @@ -50490,7 +52376,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmple_epi32_mask() { + const unsafe fn test_mm512_cmple_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50502,7 +52388,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmple_epi32_mask() { + const unsafe fn test_mm512_mask_cmple_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50512,7 +52398,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmple_epi32_mask() { + const unsafe fn test_mm256_cmple_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 200, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let r = _mm256_cmple_epi32_mask(a, b); @@ -50520,7 +52406,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmple_epi32_mask() { + const unsafe fn test_mm256_mask_cmple_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 200, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let mask = 0b11111111; @@ -50529,7 +52415,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmple_epi32_mask() { + const unsafe fn test_mm_cmple_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 200); let b = _mm_set1_epi32(-1); let r = _mm_cmple_epi32_mask(a, b); @@ -50537,7 +52423,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmple_epi32_mask() { + const unsafe fn test_mm_mask_cmple_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 200); let b = _mm_set1_epi32(-1); let mask = 0b11111111; @@ -50546,7 +52432,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpge_epi32_mask() { + const unsafe fn test_mm512_cmpge_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50558,7 +52444,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpge_epi32_mask() { + const unsafe fn test_mm512_mask_cmpge_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); @@ -50571,7 +52457,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpge_epi32_mask() { + const unsafe fn test_mm256_cmpge_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let r = _mm256_cmpge_epi32_mask(a, b); @@ -50579,7 +52465,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpge_epi32_mask() { + const unsafe fn test_mm256_mask_cmpge_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, u32::MAX as i32, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let mask = 0b11111111; @@ -50588,7 +52474,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpge_epi32_mask() { + const unsafe fn test_mm_cmpge_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, u32::MAX as i32); let b = _mm_set1_epi32(-1); let r = _mm_cmpge_epi32_mask(a, b); @@ -50596,7 +52482,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpge_epi32_mask() { + const unsafe fn test_mm_mask_cmpge_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, u32::MAX as i32); let b = _mm_set1_epi32(-1); let mask = 0b11111111; @@ -50605,7 +52491,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpeq_epi32_mask() { + const unsafe fn test_mm512_cmpeq_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); @@ -50617,7 +52503,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpeq_epi32_mask() { + const unsafe fn test_mm512_mask_cmpeq_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); @@ -50630,7 +52516,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpeq_epi32_mask() { + const unsafe fn test_mm256_cmpeq_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set_epi32(0, 1, 13, 42, i32::MAX, i32::MIN, 100, -100); let m = _mm256_cmpeq_epi32_mask(b, a); @@ -50638,7 +52524,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpeq_epi32_mask() { + const unsafe fn test_mm256_mask_cmpeq_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set_epi32(0, 1, 13, 42, i32::MAX, i32::MIN, 100, -100); let mask = 0b01111010; @@ -50647,7 +52533,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpeq_epi32_mask() { + const unsafe fn test_mm_cmpeq_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 13); let b = _mm_set_epi32(0, 1, 13, 42); let m = _mm_cmpeq_epi32_mask(b, a); @@ -50655,7 +52541,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpeq_epi32_mask() { + const unsafe fn test_mm_mask_cmpeq_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 13); let b = _mm_set_epi32(0, 1, 13, 42); let mask = 0b11111111; @@ -50664,7 +52550,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpneq_epi32_mask() { + const unsafe fn test_mm512_cmpneq_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); @@ -50676,7 +52562,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpneq_epi32_mask() { + const unsafe fn test_mm512_mask_cmpneq_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, -100, 100, 0, 1, -1, 13, i32::MAX, i32::MIN, -100, 100); @@ -50689,7 +52575,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpneq_epi32_mask() { + const unsafe fn test_mm256_cmpneq_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set_epi32(0, 1, 13, 42, i32::MAX, i32::MIN, 100, -100); let m = _mm256_cmpneq_epi32_mask(b, a); @@ -50697,7 +52583,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpneq_epi32_mask() { + const unsafe fn test_mm256_mask_cmpneq_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, -100, 100); let b = _mm256_set_epi32(0, 1, 13, 42, i32::MAX, i32::MIN, 100, -100); let mask = 0b11111111; @@ -50706,7 +52592,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpneq_epi32_mask() { + const unsafe fn test_mm_cmpneq_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 13); let b = _mm_set_epi32(0, 1, 13, 42); let r = _mm_cmpneq_epi32_mask(b, a); @@ -50714,7 +52600,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpneq_epi32_mask() { + const unsafe fn test_mm_mask_cmpneq_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 13); let b = _mm_set_epi32(0, 1, 13, 42); let mask = 0b11111111; @@ -50723,7 +52609,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmp_epi32_mask() { + const unsafe fn test_mm512_cmp_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); @@ -50733,7 +52619,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmp_epi32_mask() { + const unsafe fn test_mm512_mask_cmp_epi32_mask() { #[rustfmt::skip] let a = _mm512_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100, 0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); @@ -50744,7 +52630,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmp_epi32_mask() { + const unsafe fn test_mm256_cmp_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let m = _mm256_cmp_epi32_mask::<_MM_CMPINT_LT>(a, b); @@ -50752,7 +52638,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmp_epi32_mask() { + const unsafe fn test_mm256_mask_cmp_epi32_mask() { let a = _mm256_set_epi32(0, 1, -1, 13, i32::MAX, i32::MIN, 100, -100); let b = _mm256_set1_epi32(-1); let mask = 0b01100110; @@ -50761,7 +52647,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmp_epi32_mask() { + const unsafe fn test_mm_cmp_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 13); let b = _mm_set1_epi32(1); let m = _mm_cmp_epi32_mask::<_MM_CMPINT_LT>(a, b); @@ -50769,7 +52655,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmp_epi32_mask() { + const unsafe fn test_mm_mask_cmp_epi32_mask() { let a = _mm_set_epi32(0, 1, -1, 13); let b = _mm_set1_epi32(1); let mask = 0b11111111; @@ -50778,7 +52664,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set_epi8() { + const unsafe fn test_mm512_set_epi8() { let r = _mm512_set1_epi8(2); assert_eq_m512i( r, @@ -50791,7 +52677,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set_epi16() { + const unsafe fn test_mm512_set_epi16() { let r = _mm512_set1_epi16(2); assert_eq_m512i( r, @@ -50803,7 +52689,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set_epi32() { + const unsafe fn test_mm512_set_epi32() { let r = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); assert_eq_m512i( r, @@ -50812,7 +52698,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setr_epi32() { + const unsafe fn test_mm512_setr_epi32() { let r = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); assert_eq_m512i( r, @@ -50821,7 +52707,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set1_epi8() { + const unsafe fn test_mm512_set1_epi8() { let r = _mm512_set_epi8( 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -50831,7 +52717,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set1_epi16() { + const unsafe fn test_mm512_set1_epi16() { let r = _mm512_set_epi16( 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -50840,23 +52726,23 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set1_epi32() { + const unsafe fn test_mm512_set1_epi32() { let r = _mm512_set_epi32(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); assert_eq_m512i(r, _mm512_set1_epi32(2)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setzero_si512() { + const unsafe fn test_mm512_setzero_si512() { assert_eq_m512i(_mm512_set1_epi32(0), _mm512_setzero_si512()); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setzero_epi32() { + const unsafe fn test_mm512_setzero_epi32() { assert_eq_m512i(_mm512_set1_epi32(0), _mm512_setzero_epi32()); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set_ps() { + const unsafe fn test_mm512_set_ps() { let r = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., ); @@ -50869,7 +52755,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setr_ps() { + const unsafe fn test_mm512_setr_ps() { let r = _mm512_set_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., ); @@ -50882,7 +52768,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set1_ps() { + const unsafe fn test_mm512_set1_ps() { #[rustfmt::skip] let expected = _mm512_set_ps(2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.); @@ -50890,13 +52776,13 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set4_epi32() { + const unsafe fn test_mm512_set4_epi32() { let r = _mm512_set_epi32(4, 3, 2, 1, 4, 3, 2, 1, 4, 3, 2, 1, 4, 3, 2, 1); assert_eq_m512i(r, _mm512_set4_epi32(4, 3, 2, 1)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set4_ps() { + const unsafe fn test_mm512_set4_ps() { let r = _mm512_set_ps( 4., 3., 2., 1., 4., 3., 2., 1., 4., 3., 2., 1., 4., 3., 2., 1., ); @@ -50904,13 +52790,13 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setr4_epi32() { + const unsafe fn test_mm512_setr4_epi32() { let r = _mm512_set_epi32(4, 3, 2, 1, 4, 3, 2, 1, 4, 3, 2, 1, 4, 3, 2, 1); assert_eq_m512i(r, _mm512_setr4_epi32(1, 2, 3, 4)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setr4_ps() { + const unsafe fn test_mm512_setr4_ps() { let r = _mm512_set_ps( 4., 3., 2., 1., 4., 3., 2., 1., 4., 3., 2., 1., 4., 3., 2., 1., ); @@ -50918,17 +52804,17 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setzero_ps() { + const unsafe fn test_mm512_setzero_ps() { assert_eq_m512(_mm512_setzero_ps(), _mm512_set1_ps(0.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setzero() { + const unsafe fn test_mm512_setzero() { assert_eq_m512(_mm512_setzero(), _mm512_set1_ps(0.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_loadu_pd() { + const unsafe fn test_mm512_loadu_pd() { let a = &[4., 3., 2., 5., 8., 9., 64., 50.]; let p = a.as_ptr(); let r = _mm512_loadu_pd(black_box(p)); @@ -50937,7 +52823,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_storeu_pd() { + const unsafe fn test_mm512_storeu_pd() { let a = _mm512_set1_pd(9.); let mut r = _mm512_undefined_pd(); _mm512_storeu_pd(&mut r as *mut _ as *mut f64, a); @@ -50945,7 +52831,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_loadu_ps() { + const unsafe fn test_mm512_loadu_ps() { let a = &[ 4., 3., 2., 5., 8., 9., 64., 50., -4., -3., -2., -5., -8., -9., -64., -50., ]; @@ -50958,7 +52844,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_storeu_ps() { + const unsafe fn test_mm512_storeu_ps() { let a = _mm512_set1_ps(9.); let mut r = _mm512_undefined_ps(); _mm512_storeu_ps(&mut r as *mut _ as *mut f32, a); @@ -50966,7 +52852,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_loadu_epi32() { + const unsafe fn test_mm512_mask_loadu_epi32() { let src = _mm512_set1_epi32(42); let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); @@ -50977,7 +52863,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_loadu_epi32() { + const unsafe fn test_mm512_maskz_loadu_epi32() { let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; @@ -50987,7 +52873,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_load_epi32() { + const unsafe fn test_mm512_mask_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 16], // 64 bytes @@ -51004,7 +52890,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_load_epi32() { + const unsafe fn test_mm512_maskz_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 16], // 64 bytes @@ -51020,7 +52906,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_storeu_epi32() { + const unsafe fn test_mm512_mask_storeu_epi32() { let mut r = [42_i32; 16]; let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let m = 0b11101000_11001010; @@ -51030,7 +52916,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_store_epi32() { + const unsafe fn test_mm512_mask_store_epi32() { #[repr(align(64))] struct Align { data: [i32; 16], @@ -51044,7 +52930,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_loadu_epi64() { + const unsafe fn test_mm512_mask_loadu_epi64() { let src = _mm512_set1_epi64(42); let a = &[1_i64, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); @@ -51055,7 +52941,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_loadu_epi64() { + const unsafe fn test_mm512_maskz_loadu_epi64() { let a = &[1_i64, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11001010; @@ -51065,7 +52951,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_load_epi64() { + const unsafe fn test_mm512_mask_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 8], // 64 bytes @@ -51082,7 +52968,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_load_epi64() { + const unsafe fn test_mm512_maskz_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 8], // 64 bytes @@ -51098,7 +52984,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_storeu_epi64() { + const unsafe fn test_mm512_mask_storeu_epi64() { let mut r = [42_i64; 8]; let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let m = 0b11001010; @@ -51108,7 +52994,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_store_epi64() { + const unsafe fn test_mm512_mask_store_epi64() { #[repr(align(64))] struct Align { data: [i64; 8], @@ -51123,7 +53009,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_loadu_ps() { + const unsafe fn test_mm512_mask_loadu_ps() { let src = _mm512_set1_ps(42.0); let a = &[ 1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, @@ -51140,7 +53026,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_loadu_ps() { + const unsafe fn test_mm512_maskz_loadu_ps() { let a = &[ 1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, @@ -51155,7 +53041,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_load_ps() { + const unsafe fn test_mm512_mask_load_ps() { #[repr(align(64))] struct Align { data: [f32; 16], // 64 bytes @@ -51178,7 +53064,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_load_ps() { + const unsafe fn test_mm512_maskz_load_ps() { #[repr(align(64))] struct Align { data: [f32; 16], // 64 bytes @@ -51199,7 +53085,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_storeu_ps() { + const unsafe fn test_mm512_mask_storeu_ps() { let mut r = [42_f32; 16]; let a = _mm512_setr_ps( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, @@ -51214,7 +53100,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_store_ps() { + const unsafe fn test_mm512_mask_store_ps() { #[repr(align(64))] struct Align { data: [f32; 16], @@ -51233,7 +53119,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_loadu_pd() { + const unsafe fn test_mm512_mask_loadu_pd() { let src = _mm512_set1_pd(42.0); let a = &[1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let p = a.as_ptr(); @@ -51244,7 +53130,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_loadu_pd() { + const unsafe fn test_mm512_maskz_loadu_pd() { let a = &[1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let p = a.as_ptr(); let m = 0b11001010; @@ -51254,7 +53140,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_load_pd() { + const unsafe fn test_mm512_mask_load_pd() { #[repr(align(64))] struct Align { data: [f64; 8], // 64 bytes @@ -51271,7 +53157,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_load_pd() { + const unsafe fn test_mm512_maskz_load_pd() { #[repr(align(64))] struct Align { data: [f64; 8], // 64 bytes @@ -51287,7 +53173,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_storeu_pd() { + const unsafe fn test_mm512_mask_storeu_pd() { let mut r = [42_f64; 8]; let a = _mm512_setr_pd(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let m = 0b11001010; @@ -51297,7 +53183,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_store_pd() { + const unsafe fn test_mm512_mask_store_pd() { #[repr(align(64))] struct Align { data: [f64; 8], @@ -51311,7 +53197,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_loadu_epi32() { + const unsafe fn test_mm256_mask_loadu_epi32() { let src = _mm256_set1_epi32(42); let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); @@ -51322,7 +53208,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_loadu_epi32() { + const unsafe fn test_mm256_maskz_loadu_epi32() { let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11001010; @@ -51332,7 +53218,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_load_epi32() { + const unsafe fn test_mm256_mask_load_epi32() { #[repr(align(32))] struct Align { data: [i32; 8], // 32 bytes @@ -51349,7 +53235,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_load_epi32() { + const unsafe fn test_mm256_maskz_load_epi32() { #[repr(align(32))] struct Align { data: [i32; 8], // 32 bytes @@ -51365,7 +53251,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_storeu_epi32() { + const unsafe fn test_mm256_mask_storeu_epi32() { let mut r = [42_i32; 8]; let a = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); let m = 0b11001010; @@ -51375,7 +53261,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_store_epi32() { + const unsafe fn test_mm256_mask_store_epi32() { #[repr(align(64))] struct Align { data: [i32; 8], @@ -51389,7 +53275,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_loadu_epi64() { + const unsafe fn test_mm256_mask_loadu_epi64() { let src = _mm256_set1_epi64x(42); let a = &[1_i64, 2, 3, 4]; let p = a.as_ptr(); @@ -51400,7 +53286,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_loadu_epi64() { + const unsafe fn test_mm256_maskz_loadu_epi64() { let a = &[1_i64, 2, 3, 4]; let p = a.as_ptr(); let m = 0b1010; @@ -51410,7 +53296,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_load_epi64() { + const unsafe fn test_mm256_mask_load_epi64() { #[repr(align(32))] struct Align { data: [i64; 4], // 32 bytes @@ -51427,7 +53313,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_load_epi64() { + const unsafe fn test_mm256_maskz_load_epi64() { #[repr(align(32))] struct Align { data: [i64; 4], // 32 bytes @@ -51443,7 +53329,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_storeu_epi64() { + const unsafe fn test_mm256_mask_storeu_epi64() { let mut r = [42_i64; 4]; let a = _mm256_setr_epi64x(1, 2, 3, 4); let m = 0b1010; @@ -51453,7 +53339,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_store_epi64() { + const unsafe fn test_mm256_mask_store_epi64() { #[repr(align(32))] struct Align { data: [i64; 4], @@ -51467,7 +53353,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_loadu_ps() { + const unsafe fn test_mm256_mask_loadu_ps() { let src = _mm256_set1_ps(42.0); let a = &[1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let p = a.as_ptr(); @@ -51478,7 +53364,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_loadu_ps() { + const unsafe fn test_mm256_maskz_loadu_ps() { let a = &[1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let p = a.as_ptr(); let m = 0b11001010; @@ -51488,7 +53374,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_load_ps() { + const unsafe fn test_mm256_mask_load_ps() { #[repr(align(32))] struct Align { data: [f32; 8], // 32 bytes @@ -51505,7 +53391,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_load_ps() { + const unsafe fn test_mm256_maskz_load_ps() { #[repr(align(32))] struct Align { data: [f32; 8], // 32 bytes @@ -51521,7 +53407,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_storeu_ps() { + const unsafe fn test_mm256_mask_storeu_ps() { let mut r = [42_f32; 8]; let a = _mm256_setr_ps(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let m = 0b11001010; @@ -51531,7 +53417,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_store_ps() { + const unsafe fn test_mm256_mask_store_ps() { #[repr(align(32))] struct Align { data: [f32; 8], @@ -51545,7 +53431,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_loadu_pd() { + const unsafe fn test_mm256_mask_loadu_pd() { let src = _mm256_set1_pd(42.0); let a = &[1.0_f64, 2.0, 3.0, 4.0]; let p = a.as_ptr(); @@ -51556,7 +53442,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_loadu_pd() { + const unsafe fn test_mm256_maskz_loadu_pd() { let a = &[1.0_f64, 2.0, 3.0, 4.0]; let p = a.as_ptr(); let m = 0b1010; @@ -51566,7 +53452,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_load_pd() { + const unsafe fn test_mm256_mask_load_pd() { #[repr(align(32))] struct Align { data: [f64; 4], // 32 bytes @@ -51583,7 +53469,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_load_pd() { + const unsafe fn test_mm256_maskz_load_pd() { #[repr(align(32))] struct Align { data: [f64; 4], // 32 bytes @@ -51599,7 +53485,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_storeu_pd() { + const unsafe fn test_mm256_mask_storeu_pd() { let mut r = [42_f64; 4]; let a = _mm256_setr_pd(1.0, 2.0, 3.0, 4.0); let m = 0b1010; @@ -51609,7 +53495,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_store_pd() { + const unsafe fn test_mm256_mask_store_pd() { #[repr(align(32))] struct Align { data: [f64; 4], @@ -51623,7 +53509,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_loadu_epi32() { + const unsafe fn test_mm_mask_loadu_epi32() { let src = _mm_set1_epi32(42); let a = &[1_i32, 2, 3, 4]; let p = a.as_ptr(); @@ -51634,7 +53520,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_loadu_epi32() { + const unsafe fn test_mm_maskz_loadu_epi32() { let a = &[1_i32, 2, 3, 4]; let p = a.as_ptr(); let m = 0b1010; @@ -51644,7 +53530,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_load_epi32() { + const unsafe fn test_mm_mask_load_epi32() { #[repr(align(16))] struct Align { data: [i32; 4], // 32 bytes @@ -51661,7 +53547,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_load_epi32() { + const unsafe fn test_mm_maskz_load_epi32() { #[repr(align(16))] struct Align { data: [i32; 4], // 16 bytes @@ -51677,7 +53563,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_storeu_epi32() { + const unsafe fn test_mm_mask_storeu_epi32() { let mut r = [42_i32; 4]; let a = _mm_setr_epi32(1, 2, 3, 4); let m = 0b1010; @@ -51687,7 +53573,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_store_epi32() { + const unsafe fn test_mm_mask_store_epi32() { #[repr(align(16))] struct Align { data: [i32; 4], // 16 bytes @@ -51701,7 +53587,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_loadu_epi64() { + const unsafe fn test_mm_mask_loadu_epi64() { let src = _mm_set1_epi64x(42); let a = &[1_i64, 2]; let p = a.as_ptr(); @@ -51712,7 +53598,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_loadu_epi64() { + const unsafe fn test_mm_maskz_loadu_epi64() { let a = &[1_i64, 2]; let p = a.as_ptr(); let m = 0b10; @@ -51722,7 +53608,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_load_epi64() { + const unsafe fn test_mm_mask_load_epi64() { #[repr(align(16))] struct Align { data: [i64; 2], // 16 bytes @@ -51737,7 +53623,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_load_epi64() { + const unsafe fn test_mm_maskz_load_epi64() { #[repr(align(16))] struct Align { data: [i64; 2], // 16 bytes @@ -51751,7 +53637,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_storeu_epi64() { + const unsafe fn test_mm_mask_storeu_epi64() { let mut r = [42_i64; 2]; let a = _mm_setr_epi64x(1, 2); let m = 0b10; @@ -51761,7 +53647,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_store_epi64() { + const unsafe fn test_mm_mask_store_epi64() { #[repr(align(16))] struct Align { data: [i64; 2], // 16 bytes @@ -51775,7 +53661,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_loadu_ps() { + const unsafe fn test_mm_mask_loadu_ps() { let src = _mm_set1_ps(42.0); let a = &[1.0_f32, 2.0, 3.0, 4.0]; let p = a.as_ptr(); @@ -51786,7 +53672,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_loadu_ps() { + const unsafe fn test_mm_maskz_loadu_ps() { let a = &[1.0_f32, 2.0, 3.0, 4.0]; let p = a.as_ptr(); let m = 0b1010; @@ -51796,7 +53682,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_load_ps() { + const unsafe fn test_mm_mask_load_ps() { #[repr(align(16))] struct Align { data: [f32; 4], // 16 bytes @@ -51813,7 +53699,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_load_ps() { + const unsafe fn test_mm_maskz_load_ps() { #[repr(align(16))] struct Align { data: [f32; 4], // 16 bytes @@ -51829,7 +53715,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_storeu_ps() { + const unsafe fn test_mm_mask_storeu_ps() { let mut r = [42_f32; 4]; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let m = 0b1010; @@ -51839,7 +53725,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_store_ps() { + const unsafe fn test_mm_mask_store_ps() { #[repr(align(16))] struct Align { data: [f32; 4], // 16 bytes @@ -51853,7 +53739,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_loadu_pd() { + const unsafe fn test_mm_mask_loadu_pd() { let src = _mm_set1_pd(42.0); let a = &[1.0_f64, 2.0]; let p = a.as_ptr(); @@ -51864,7 +53750,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_loadu_pd() { + const unsafe fn test_mm_maskz_loadu_pd() { let a = &[1.0_f64, 2.0]; let p = a.as_ptr(); let m = 0b10; @@ -51874,7 +53760,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_load_pd() { + const unsafe fn test_mm_mask_load_pd() { #[repr(align(16))] struct Align { data: [f64; 2], // 16 bytes @@ -51891,7 +53777,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_load_pd() { + const unsafe fn test_mm_maskz_load_pd() { #[repr(align(16))] struct Align { data: [f64; 2], // 16 bytes @@ -51961,7 +53847,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_storeu_pd() { + const unsafe fn test_mm_mask_storeu_pd() { let mut r = [42_f64; 2]; let a = _mm_setr_pd(1.0, 2.0); let m = 0b10; @@ -51971,7 +53857,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_store_pd() { + const unsafe fn test_mm_mask_store_pd() { #[repr(align(16))] struct Align { data: [f64; 2], // 16 bytes @@ -52013,19 +53899,19 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setr_pd() { + const unsafe fn test_mm512_setr_pd() { let r = _mm512_set_pd(0., 1., 2., 3., 4., 5., 6., 7.); assert_eq_m512d(r, _mm512_setr_pd(7., 6., 5., 4., 3., 2., 1., 0.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set_pd() { + const unsafe fn test_mm512_set_pd() { let r = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); assert_eq_m512d(r, _mm512_set_pd(7., 6., 5., 4., 3., 2., 1., 0.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_rol_epi32() { + const unsafe fn test_mm512_rol_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let r = _mm512_rol_epi32::<1>(a); let e = _mm512_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); @@ -52033,7 +53919,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_rol_epi32() { + const unsafe fn test_mm512_mask_rol_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let r = _mm512_mask_rol_epi32::<1>(a, 0, a); assert_eq_m512i(r, a); @@ -52043,7 +53929,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_rol_epi32() { + const unsafe fn test_mm512_maskz_rol_epi32() { let a = _mm512_set_epi32(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 << 31); let r = _mm512_maskz_rol_epi32::<1>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -52053,7 +53939,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_rol_epi32() { + const unsafe fn test_mm256_rol_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let r = _mm256_rol_epi32::<1>(a); let e = _mm256_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2); @@ -52061,7 +53947,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_rol_epi32() { + const unsafe fn test_mm256_mask_rol_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let r = _mm256_mask_rol_epi32::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -52071,7 +53957,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_rol_epi32() { + const unsafe fn test_mm256_maskz_rol_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let r = _mm256_maskz_rol_epi32::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -52081,7 +53967,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_rol_epi32() { + const unsafe fn test_mm_rol_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let r = _mm_rol_epi32::<1>(a); let e = _mm_set_epi32(1 << 0, 2, 2, 2); @@ -52089,7 +53975,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_rol_epi32() { + const unsafe fn test_mm_mask_rol_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let r = _mm_mask_rol_epi32::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -52099,7 +53985,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_rol_epi32() { + const unsafe fn test_mm_maskz_rol_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let r = _mm_maskz_rol_epi32::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -52109,7 +53995,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_ror_epi32() { + const unsafe fn test_mm512_ror_epi32() { let a = _mm512_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); let r = _mm512_ror_epi32::<1>(a); let e = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); @@ -52117,7 +54003,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_ror_epi32() { + const unsafe fn test_mm512_mask_ror_epi32() { let a = _mm512_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); let r = _mm512_mask_ror_epi32::<1>(a, 0, a); assert_eq_m512i(r, a); @@ -52127,7 +54013,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_ror_epi32() { + const unsafe fn test_mm512_maskz_ror_epi32() { let a = _mm512_set_epi32(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 << 0); let r = _mm512_maskz_ror_epi32::<1>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -52137,7 +54023,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_ror_epi32() { + const unsafe fn test_mm256_ror_epi32() { let a = _mm256_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2); let r = _mm256_ror_epi32::<1>(a); let e = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); @@ -52145,7 +54031,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_ror_epi32() { + const unsafe fn test_mm256_mask_ror_epi32() { let a = _mm256_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2); let r = _mm256_mask_ror_epi32::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -52155,7 +54041,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_ror_epi32() { + const unsafe fn test_mm256_maskz_ror_epi32() { let a = _mm256_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2); let r = _mm256_maskz_ror_epi32::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -52165,7 +54051,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_ror_epi32() { + const unsafe fn test_mm_ror_epi32() { let a = _mm_set_epi32(1 << 0, 2, 2, 2); let r = _mm_ror_epi32::<1>(a); let e = _mm_set_epi32(1 << 31, 1, 1, 1); @@ -52173,7 +54059,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_ror_epi32() { + const unsafe fn test_mm_mask_ror_epi32() { let a = _mm_set_epi32(1 << 0, 2, 2, 2); let r = _mm_mask_ror_epi32::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -52183,7 +54069,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_ror_epi32() { + const unsafe fn test_mm_maskz_ror_epi32() { let a = _mm_set_epi32(1 << 0, 2, 2, 2); let r = _mm_maskz_ror_epi32::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -52193,7 +54079,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_slli_epi32() { + const unsafe fn test_mm512_slli_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let r = _mm512_slli_epi32::<1>(a); let e = _mm512_set_epi32(0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); @@ -52201,7 +54087,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_slli_epi32() { + const unsafe fn test_mm512_mask_slli_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let r = _mm512_mask_slli_epi32::<1>(a, 0, a); assert_eq_m512i(r, a); @@ -52211,7 +54097,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_slli_epi32() { + const unsafe fn test_mm512_maskz_slli_epi32() { let a = _mm512_set_epi32(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 << 31); let r = _mm512_maskz_slli_epi32::<1>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -52221,7 +54107,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_slli_epi32() { + const unsafe fn test_mm256_mask_slli_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let r = _mm256_mask_slli_epi32::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -52231,7 +54117,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_slli_epi32() { + const unsafe fn test_mm256_maskz_slli_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let r = _mm256_maskz_slli_epi32::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -52241,7 +54127,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_slli_epi32() { + const unsafe fn test_mm_mask_slli_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let r = _mm_mask_slli_epi32::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -52251,7 +54137,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_slli_epi32() { + const unsafe fn test_mm_maskz_slli_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let r = _mm_maskz_slli_epi32::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -52261,7 +54147,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_srli_epi32() { + const unsafe fn test_mm512_srli_epi32() { let a = _mm512_set_epi32(0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); let r = _mm512_srli_epi32::<1>(a); let e = _mm512_set_epi32(0 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); @@ -52269,7 +54155,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_srli_epi32() { + const unsafe fn test_mm512_mask_srli_epi32() { let a = _mm512_set_epi32(0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); let r = _mm512_mask_srli_epi32::<1>(a, 0, a); assert_eq_m512i(r, a); @@ -52279,7 +54165,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_srli_epi32() { + const unsafe fn test_mm512_maskz_srli_epi32() { let a = _mm512_set_epi32(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0); let r = _mm512_maskz_srli_epi32::<1>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -52289,7 +54175,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_srli_epi32() { + const unsafe fn test_mm256_mask_srli_epi32() { let a = _mm256_set_epi32(1 << 5, 0, 0, 0, 0, 0, 0, 0); let r = _mm256_mask_srli_epi32::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -52299,7 +54185,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_srli_epi32() { + const unsafe fn test_mm256_maskz_srli_epi32() { let a = _mm256_set_epi32(1 << 5, 0, 0, 0, 0, 0, 0, 0); let r = _mm256_maskz_srli_epi32::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -52309,7 +54195,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_srli_epi32() { + const unsafe fn test_mm_mask_srli_epi32() { let a = _mm_set_epi32(1 << 5, 0, 0, 0); let r = _mm_mask_srli_epi32::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -52319,7 +54205,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_srli_epi32() { + const unsafe fn test_mm_maskz_srli_epi32() { let a = _mm_set_epi32(1 << 5, 0, 0, 0); let r = _mm_maskz_srli_epi32::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -52329,7 +54215,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_rolv_epi32() { + const unsafe fn test_mm512_rolv_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let b = _mm512_set1_epi32(1); let r = _mm512_rolv_epi32(a, b); @@ -52338,7 +54224,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_rolv_epi32() { + const unsafe fn test_mm512_mask_rolv_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let b = _mm512_set1_epi32(1); let r = _mm512_mask_rolv_epi32(a, 0, a, b); @@ -52349,7 +54235,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_rolv_epi32() { + const unsafe fn test_mm512_maskz_rolv_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 << 31); let b = _mm512_set1_epi32(1); let r = _mm512_maskz_rolv_epi32(0, a, b); @@ -52360,7 +54246,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_rolv_epi32() { + const unsafe fn test_mm256_rolv_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let b = _mm256_set1_epi32(1); let r = _mm256_rolv_epi32(a, b); @@ -52369,7 +54255,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_rolv_epi32() { + const unsafe fn test_mm256_mask_rolv_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let b = _mm256_set1_epi32(1); let r = _mm256_mask_rolv_epi32(a, 0, a, b); @@ -52380,7 +54266,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_rolv_epi32() { + const unsafe fn test_mm256_maskz_rolv_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let b = _mm256_set1_epi32(1); let r = _mm256_maskz_rolv_epi32(0, a, b); @@ -52391,7 +54277,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_rolv_epi32() { + const unsafe fn test_mm_rolv_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let b = _mm_set1_epi32(1); let r = _mm_rolv_epi32(a, b); @@ -52400,7 +54286,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_rolv_epi32() { + const unsafe fn test_mm_mask_rolv_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let b = _mm_set1_epi32(1); let r = _mm_mask_rolv_epi32(a, 0, a, b); @@ -52411,7 +54297,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_rolv_epi32() { + const unsafe fn test_mm_maskz_rolv_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let b = _mm_set1_epi32(1); let r = _mm_maskz_rolv_epi32(0, a, b); @@ -52422,7 +54308,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_rorv_epi32() { + const unsafe fn test_mm512_rorv_epi32() { let a = _mm512_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); let b = _mm512_set1_epi32(1); let r = _mm512_rorv_epi32(a, b); @@ -52431,7 +54317,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_rorv_epi32() { + const unsafe fn test_mm512_mask_rorv_epi32() { let a = _mm512_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); let b = _mm512_set1_epi32(1); let r = _mm512_mask_rorv_epi32(a, 0, a, b); @@ -52442,7 +54328,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_rorv_epi32() { + const unsafe fn test_mm512_maskz_rorv_epi32() { let a = _mm512_set_epi32(3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 << 0); let b = _mm512_set1_epi32(1); let r = _mm512_maskz_rorv_epi32(0, a, b); @@ -52453,7 +54339,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_rorv_epi32() { + const unsafe fn test_mm256_rorv_epi32() { let a = _mm256_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2); let b = _mm256_set1_epi32(1); let r = _mm256_rorv_epi32(a, b); @@ -52462,7 +54348,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_rorv_epi32() { + const unsafe fn test_mm256_mask_rorv_epi32() { let a = _mm256_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2); let b = _mm256_set1_epi32(1); let r = _mm256_mask_rorv_epi32(a, 0, a, b); @@ -52473,7 +54359,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_rorv_epi32() { + const unsafe fn test_mm256_maskz_rorv_epi32() { let a = _mm256_set_epi32(1 << 0, 2, 2, 2, 2, 2, 2, 2); let b = _mm256_set1_epi32(1); let r = _mm256_maskz_rorv_epi32(0, a, b); @@ -52484,7 +54370,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_rorv_epi32() { + const unsafe fn test_mm_rorv_epi32() { let a = _mm_set_epi32(1 << 0, 2, 2, 2); let b = _mm_set1_epi32(1); let r = _mm_rorv_epi32(a, b); @@ -52493,7 +54379,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_rorv_epi32() { + const unsafe fn test_mm_mask_rorv_epi32() { let a = _mm_set_epi32(1 << 0, 2, 2, 2); let b = _mm_set1_epi32(1); let r = _mm_mask_rorv_epi32(a, 0, a, b); @@ -52504,7 +54390,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_rorv_epi32() { + const unsafe fn test_mm_maskz_rorv_epi32() { let a = _mm_set_epi32(1 << 0, 2, 2, 2); let b = _mm_set1_epi32(1); let r = _mm_maskz_rorv_epi32(0, a, b); @@ -52515,7 +54401,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_sllv_epi32() { + const unsafe fn test_mm512_sllv_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let count = _mm512_set1_epi32(1); let r = _mm512_sllv_epi32(a, count); @@ -52524,7 +54410,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_sllv_epi32() { + const unsafe fn test_mm512_mask_sllv_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let count = _mm512_set1_epi32(1); let r = _mm512_mask_sllv_epi32(a, 0, a, count); @@ -52535,7 +54421,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_sllv_epi32() { + const unsafe fn test_mm512_maskz_sllv_epi32() { let a = _mm512_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 << 31); let count = _mm512_set_epi32(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let r = _mm512_maskz_sllv_epi32(0, a, count); @@ -52546,7 +54432,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_sllv_epi32() { + const unsafe fn test_mm256_mask_sllv_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let count = _mm256_set1_epi32(1); let r = _mm256_mask_sllv_epi32(a, 0, a, count); @@ -52557,7 +54443,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_sllv_epi32() { + const unsafe fn test_mm256_maskz_sllv_epi32() { let a = _mm256_set_epi32(1 << 31, 1, 1, 1, 1, 1, 1, 1); let count = _mm256_set1_epi32(1); let r = _mm256_maskz_sllv_epi32(0, a, count); @@ -52568,7 +54454,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_sllv_epi32() { + const unsafe fn test_mm_mask_sllv_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let count = _mm_set1_epi32(1); let r = _mm_mask_sllv_epi32(a, 0, a, count); @@ -52579,7 +54465,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_sllv_epi32() { + const unsafe fn test_mm_maskz_sllv_epi32() { let a = _mm_set_epi32(1 << 31, 1, 1, 1); let count = _mm_set1_epi32(1); let r = _mm_maskz_sllv_epi32(0, a, count); @@ -52590,7 +54476,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_srlv_epi32() { + const unsafe fn test_mm512_srlv_epi32() { let a = _mm512_set_epi32(0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); let count = _mm512_set1_epi32(1); let r = _mm512_srlv_epi32(a, count); @@ -52599,7 +54485,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_srlv_epi32() { + const unsafe fn test_mm512_mask_srlv_epi32() { let a = _mm512_set_epi32(0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); let count = _mm512_set1_epi32(1); let r = _mm512_mask_srlv_epi32(a, 0, a, count); @@ -52610,7 +54496,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_srlv_epi32() { + const unsafe fn test_mm512_maskz_srlv_epi32() { let a = _mm512_set_epi32(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0); let count = _mm512_set_epi32(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let r = _mm512_maskz_srlv_epi32(0, a, count); @@ -52621,7 +54507,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_srlv_epi32() { + const unsafe fn test_mm256_mask_srlv_epi32() { let a = _mm256_set_epi32(1 << 5, 0, 0, 0, 0, 0, 0, 0); let count = _mm256_set1_epi32(1); let r = _mm256_mask_srlv_epi32(a, 0, a, count); @@ -52632,7 +54518,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_srlv_epi32() { + const unsafe fn test_mm256_maskz_srlv_epi32() { let a = _mm256_set_epi32(1 << 5, 0, 0, 0, 0, 0, 0, 0); let count = _mm256_set1_epi32(1); let r = _mm256_maskz_srlv_epi32(0, a, count); @@ -52643,7 +54529,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_srlv_epi32() { + const unsafe fn test_mm_mask_srlv_epi32() { let a = _mm_set_epi32(1 << 5, 0, 0, 0); let count = _mm_set1_epi32(1); let r = _mm_mask_srlv_epi32(a, 0, a, count); @@ -52654,7 +54540,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_srlv_epi32() { + const unsafe fn test_mm_maskz_srlv_epi32() { let a = _mm_set_epi32(1 << 5, 0, 0, 0); let count = _mm_set1_epi32(1); let r = _mm_maskz_srlv_epi32(0, a, count); @@ -52938,7 +54824,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_srav_epi32() { + const unsafe fn test_mm512_srav_epi32() { let a = _mm512_set_epi32(8, -8, 16, -15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); let count = _mm512_set_epi32(2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); let r = _mm512_srav_epi32(a, count); @@ -52947,7 +54833,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_srav_epi32() { + const unsafe fn test_mm512_mask_srav_epi32() { let a = _mm512_set_epi32(8, -8, 16, -15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16); let count = _mm512_set_epi32(2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); let r = _mm512_mask_srav_epi32(a, 0, a, count); @@ -52958,7 +54844,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_srav_epi32() { + const unsafe fn test_mm512_maskz_srav_epi32() { let a = _mm512_set_epi32(8, -8, 16, -15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15, -14); let count = _mm512_set_epi32(2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2); let r = _mm512_maskz_srav_epi32(0, a, count); @@ -52969,7 +54855,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_srav_epi32() { + const unsafe fn test_mm256_mask_srav_epi32() { let a = _mm256_set_epi32(1 << 5, 0, 0, 0, 0, 0, 0, 0); let count = _mm256_set1_epi32(1); let r = _mm256_mask_srav_epi32(a, 0, a, count); @@ -52980,7 +54866,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_srav_epi32() { + const unsafe fn test_mm256_maskz_srav_epi32() { let a = _mm256_set_epi32(1 << 5, 0, 0, 0, 0, 0, 0, 0); let count = _mm256_set1_epi32(1); let r = _mm256_maskz_srav_epi32(0, a, count); @@ -52991,7 +54877,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_srav_epi32() { + const unsafe fn test_mm_mask_srav_epi32() { let a = _mm_set_epi32(1 << 5, 0, 0, 0); let count = _mm_set1_epi32(1); let r = _mm_mask_srav_epi32(a, 0, a, count); @@ -53002,7 +54888,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_srav_epi32() { + const unsafe fn test_mm_maskz_srav_epi32() { let a = _mm_set_epi32(1 << 5, 0, 0, 0); let count = _mm_set1_epi32(1); let r = _mm_maskz_srav_epi32(0, a, count); @@ -53013,7 +54899,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_srai_epi32() { + const unsafe fn test_mm512_srai_epi32() { let a = _mm512_set_epi32(8, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, -15); let r = _mm512_srai_epi32::<2>(a); let e = _mm512_set_epi32(2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, -4); @@ -53021,7 +54907,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_srai_epi32() { + const unsafe fn test_mm512_mask_srai_epi32() { let a = _mm512_set_epi32(8, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, -15); let r = _mm512_mask_srai_epi32::<2>(a, 0, a); assert_eq_m512i(r, a); @@ -53031,7 +54917,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_srai_epi32() { + const unsafe fn test_mm512_maskz_srai_epi32() { let a = _mm512_set_epi32(8, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, -15); let r = _mm512_maskz_srai_epi32::<2>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -53041,7 +54927,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_srai_epi32() { + const unsafe fn test_mm256_mask_srai_epi32() { let a = _mm256_set_epi32(1 << 5, 0, 0, 0, 0, 0, 0, 0); let r = _mm256_mask_srai_epi32::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -53051,7 +54937,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_srai_epi32() { + const unsafe fn test_mm256_maskz_srai_epi32() { let a = _mm256_set_epi32(1 << 5, 0, 0, 0, 0, 0, 0, 0); let r = _mm256_maskz_srai_epi32::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -53061,7 +54947,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_srai_epi32() { + const unsafe fn test_mm_mask_srai_epi32() { let a = _mm_set_epi32(1 << 5, 0, 0, 0); let r = _mm_mask_srai_epi32::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -53071,7 +54957,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_srai_epi32() { + const unsafe fn test_mm_maskz_srai_epi32() { let a = _mm_set_epi32(1 << 5, 0, 0, 0); let r = _mm_maskz_srai_epi32::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -53081,7 +54967,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_permute_ps() { + const unsafe fn test_mm512_permute_ps() { let a = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., ); @@ -53093,7 +54979,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_permute_ps() { + const unsafe fn test_mm512_mask_permute_ps() { let a = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., ); @@ -53107,7 +54993,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_permute_ps() { + const unsafe fn test_mm512_maskz_permute_ps() { let a = _mm512_setr_ps( 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., ); @@ -53121,7 +55007,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_permute_ps() { + const unsafe fn test_mm256_mask_permute_ps() { let a = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let r = _mm256_mask_permute_ps::<0b11_11_11_11>(a, 0, a); assert_eq_m256(r, a); @@ -53131,7 +55017,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_permute_ps() { + const unsafe fn test_mm256_maskz_permute_ps() { let a = _mm256_set_ps(0., 1., 2., 3., 4., 5., 6., 7.); let r = _mm256_maskz_permute_ps::<0b11_11_11_11>(0, a); assert_eq_m256(r, _mm256_setzero_ps()); @@ -53141,7 +55027,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_permute_ps() { + const unsafe fn test_mm_mask_permute_ps() { let a = _mm_set_ps(0., 1., 2., 3.); let r = _mm_mask_permute_ps::<0b11_11_11_11>(a, 0, a); assert_eq_m128(r, a); @@ -53151,7 +55037,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_permute_ps() { + const unsafe fn test_mm_maskz_permute_ps() { let a = _mm_set_ps(0., 1., 2., 3.); let r = _mm_maskz_permute_ps::<0b11_11_11_11>(0, a); assert_eq_m128(r, _mm_setzero_ps()); @@ -53750,7 +55636,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_shuffle_epi32() { + const unsafe fn test_mm512_shuffle_epi32() { let a = _mm512_setr_epi32(1, 4, 5, 8, 9, 12, 13, 16, 1, 4, 5, 8, 9, 12, 13, 16); let r = _mm512_shuffle_epi32::<_MM_PERM_AADD>(a); let e = _mm512_setr_epi32(8, 8, 1, 1, 16, 16, 9, 9, 8, 8, 1, 1, 16, 16, 9, 9); @@ -53758,7 +55644,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_shuffle_epi32() { + const unsafe fn test_mm512_mask_shuffle_epi32() { let a = _mm512_setr_epi32(1, 4, 5, 8, 9, 12, 13, 16, 1, 4, 5, 8, 9, 12, 13, 16); let r = _mm512_mask_shuffle_epi32::<_MM_PERM_AADD>(a, 0, a); assert_eq_m512i(r, a); @@ -53768,7 +55654,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_shuffle_epi32() { + const unsafe fn test_mm512_maskz_shuffle_epi32() { let a = _mm512_setr_epi32(1, 4, 5, 8, 9, 12, 13, 16, 1, 4, 5, 8, 9, 12, 13, 16); let r = _mm512_maskz_shuffle_epi32::<_MM_PERM_AADD>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -53778,7 +55664,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_shuffle_epi32() { + const unsafe fn test_mm256_mask_shuffle_epi32() { let a = _mm256_set_epi32(1, 4, 5, 8, 9, 12, 13, 16); let r = _mm256_mask_shuffle_epi32::<_MM_PERM_AADD>(a, 0, a); assert_eq_m256i(r, a); @@ -53788,7 +55674,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_shuffle_epi32() { + const unsafe fn test_mm256_maskz_shuffle_epi32() { let a = _mm256_set_epi32(1, 4, 5, 8, 9, 12, 13, 16); let r = _mm256_maskz_shuffle_epi32::<_MM_PERM_AADD>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -53798,7 +55684,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_shuffle_epi32() { + const unsafe fn test_mm_mask_shuffle_epi32() { let a = _mm_set_epi32(1, 4, 5, 8); let r = _mm_mask_shuffle_epi32::<_MM_PERM_AADD>(a, 0, a); assert_eq_m128i(r, a); @@ -53808,7 +55694,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_shuffle_epi32() { + const unsafe fn test_mm_maskz_shuffle_epi32() { let a = _mm_set_epi32(1, 4, 5, 8); let r = _mm_maskz_shuffle_epi32::<_MM_PERM_AADD>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -53818,7 +55704,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_shuffle_ps() { + const unsafe fn test_mm512_shuffle_ps() { let a = _mm512_setr_ps( 1., 4., 5., 8., 9., 12., 13., 16., 1., 4., 5., 8., 9., 12., 13., 16., ); @@ -53833,7 +55719,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_shuffle_ps() { + const unsafe fn test_mm512_mask_shuffle_ps() { let a = _mm512_setr_ps( 1., 4., 5., 8., 9., 12., 13., 16., 1., 4., 5., 8., 9., 12., 13., 16., ); @@ -53850,7 +55736,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_shuffle_ps() { + const unsafe fn test_mm512_maskz_shuffle_ps() { let a = _mm512_setr_ps( 1., 4., 5., 8., 9., 12., 13., 16., 1., 4., 5., 8., 9., 12., 13., 16., ); @@ -53867,7 +55753,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_shuffle_ps() { + const unsafe fn test_mm256_mask_shuffle_ps() { let a = _mm256_set_ps(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm256_set_ps(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm256_mask_shuffle_ps::<0b11_11_11_11>(a, 0, a, b); @@ -53878,7 +55764,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_shuffle_ps() { + const unsafe fn test_mm256_maskz_shuffle_ps() { let a = _mm256_set_ps(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm256_set_ps(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm256_maskz_shuffle_ps::<0b11_11_11_11>(0, a, b); @@ -53889,7 +55775,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_shuffle_ps() { + const unsafe fn test_mm_mask_shuffle_ps() { let a = _mm_set_ps(1., 4., 5., 8.); let b = _mm_set_ps(2., 3., 6., 7.); let r = _mm_mask_shuffle_ps::<0b11_11_11_11>(a, 0, a, b); @@ -53900,7 +55786,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_shuffle_ps() { + const unsafe fn test_mm_maskz_shuffle_ps() { let a = _mm_set_ps(1., 4., 5., 8.); let b = _mm_set_ps(2., 3., 6., 7.); let r = _mm_maskz_shuffle_ps::<0b11_11_11_11>(0, a, b); @@ -53911,7 +55797,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_shuffle_i32x4() { + const unsafe fn test_mm512_shuffle_i32x4() { let a = _mm512_setr_epi32(1, 4, 5, 8, 9, 12, 13, 16, 1, 4, 5, 8, 9, 12, 13, 16); let b = _mm512_setr_epi32(2, 3, 6, 7, 10, 11, 14, 15, 2, 3, 6, 7, 10, 11, 14, 15); let r = _mm512_shuffle_i32x4::<0b00_00_00_00>(a, b); @@ -53920,7 +55806,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_shuffle_i32x4() { + const unsafe fn test_mm512_mask_shuffle_i32x4() { let a = _mm512_setr_epi32(1, 4, 5, 8, 9, 12, 13, 16, 1, 4, 5, 8, 9, 12, 13, 16); let b = _mm512_setr_epi32(2, 3, 6, 7, 10, 11, 14, 15, 2, 3, 6, 7, 10, 11, 14, 15); let r = _mm512_mask_shuffle_i32x4::<0b00_00_00_00>(a, 0, a, b); @@ -53931,7 +55817,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_shuffle_i32x4() { + const unsafe fn test_mm512_maskz_shuffle_i32x4() { let a = _mm512_setr_epi32(1, 4, 5, 8, 9, 12, 13, 16, 1, 4, 5, 8, 9, 12, 13, 16); let b = _mm512_setr_epi32(2, 3, 6, 7, 10, 11, 14, 15, 2, 3, 6, 7, 10, 11, 14, 15); let r = _mm512_maskz_shuffle_i32x4::<0b00_00_00_00>(0, a, b); @@ -53942,7 +55828,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_shuffle_i32x4() { + const unsafe fn test_mm256_shuffle_i32x4() { let a = _mm256_set_epi32(1, 4, 5, 8, 9, 12, 13, 16); let b = _mm256_set_epi32(2, 3, 6, 7, 10, 11, 14, 15); let r = _mm256_shuffle_i32x4::<0b00>(a, b); @@ -53951,7 +55837,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_shuffle_i32x4() { + const unsafe fn test_mm256_mask_shuffle_i32x4() { let a = _mm256_set_epi32(1, 4, 5, 8, 9, 12, 13, 16); let b = _mm256_set_epi32(2, 3, 6, 7, 10, 11, 14, 15); let r = _mm256_mask_shuffle_i32x4::<0b00>(a, 0, a, b); @@ -53962,7 +55848,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_shuffle_i32x4() { + const unsafe fn test_mm256_maskz_shuffle_i32x4() { let a = _mm256_set_epi32(1, 4, 5, 8, 9, 12, 13, 16); let b = _mm256_set_epi32(2, 3, 6, 7, 10, 11, 14, 15); let r = _mm256_maskz_shuffle_i32x4::<0b00>(0, a, b); @@ -53973,7 +55859,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_shuffle_f32x4() { + const unsafe fn test_mm512_shuffle_f32x4() { let a = _mm512_setr_ps( 1., 4., 5., 8., 9., 12., 13., 16., 1., 4., 5., 8., 9., 12., 13., 16., ); @@ -53988,7 +55874,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_shuffle_f32x4() { + const unsafe fn test_mm512_mask_shuffle_f32x4() { let a = _mm512_setr_ps( 1., 4., 5., 8., 9., 12., 13., 16., 1., 4., 5., 8., 9., 12., 13., 16., ); @@ -54005,7 +55891,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_shuffle_f32x4() { + const unsafe fn test_mm512_maskz_shuffle_f32x4() { let a = _mm512_setr_ps( 1., 4., 5., 8., 9., 12., 13., 16., 1., 4., 5., 8., 9., 12., 13., 16., ); @@ -54022,7 +55908,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_shuffle_f32x4() { + const unsafe fn test_mm256_shuffle_f32x4() { let a = _mm256_set_ps(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm256_set_ps(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm256_shuffle_f32x4::<0b00>(a, b); @@ -54031,7 +55917,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_shuffle_f32x4() { + const unsafe fn test_mm256_mask_shuffle_f32x4() { let a = _mm256_set_ps(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm256_set_ps(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm256_mask_shuffle_f32x4::<0b00>(a, 0, a, b); @@ -54042,7 +55928,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_shuffle_f32x4() { + const unsafe fn test_mm256_maskz_shuffle_f32x4() { let a = _mm256_set_ps(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm256_set_ps(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm256_maskz_shuffle_f32x4::<0b00>(0, a, b); @@ -54053,7 +55939,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_extractf32x4_ps() { + const unsafe fn test_mm512_extractf32x4_ps() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54063,7 +55949,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_extractf32x4_ps() { + const unsafe fn test_mm512_mask_extractf32x4_ps() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54076,7 +55962,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_extractf32x4_ps() { + const unsafe fn test_mm512_maskz_extractf32x4_ps() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54088,7 +55974,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_extractf32x4_ps() { + const unsafe fn test_mm256_extractf32x4_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_extractf32x4_ps::<1>(a); let e = _mm_set_ps(1., 2., 3., 4.); @@ -54096,7 +55982,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_extractf32x4_ps() { + const unsafe fn test_mm256_mask_extractf32x4_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let src = _mm_set1_ps(100.); let r = _mm256_mask_extractf32x4_ps::<1>(src, 0, a); @@ -54107,7 +55993,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_extractf32x4_ps() { + const unsafe fn test_mm256_maskz_extractf32x4_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_maskz_extractf32x4_ps::<1>(0, a); assert_eq_m128(r, _mm_setzero_ps()); @@ -54117,7 +56003,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_extracti32x4_epi32() { + const unsafe fn test_mm512_extracti32x4_epi32() { let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_extracti32x4_epi32::<1>(a); let e = _mm_setr_epi32(5, 6, 7, 8); @@ -54125,7 +56011,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_extracti32x4_epi32() { + const unsafe fn test_mm512_mask_extracti32x4_epi32() { let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let src = _mm_set1_epi32(100); let r = _mm512_mask_extracti32x4_epi32::<1>(src, 0, a); @@ -54136,7 +56022,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm512_maskz_extracti32x4_epi32() { + const unsafe fn test_mm512_maskz_extracti32x4_epi32() { let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_maskz_extracti32x4_epi32::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -54146,7 +56032,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_extracti32x4_epi32() { + const unsafe fn test_mm256_extracti32x4_epi32() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_extracti32x4_epi32::<1>(a); let e = _mm_set_epi32(1, 2, 3, 4); @@ -54154,7 +56040,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_extracti32x4_epi32() { + const unsafe fn test_mm256_mask_extracti32x4_epi32() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let src = _mm_set1_epi32(100); let r = _mm256_mask_extracti32x4_epi32::<1>(src, 0, a); @@ -54165,7 +56051,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_extracti32x4_epi32() { + const unsafe fn test_mm256_maskz_extracti32x4_epi32() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_maskz_extracti32x4_epi32::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -54175,7 +56061,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_moveldup_ps() { + const unsafe fn test_mm512_moveldup_ps() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54187,7 +56073,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_moveldup_ps() { + const unsafe fn test_mm512_mask_moveldup_ps() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54201,7 +56087,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_moveldup_ps() { + const unsafe fn test_mm512_maskz_moveldup_ps() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54215,7 +56101,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_moveldup_ps() { + const unsafe fn test_mm256_mask_moveldup_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_mask_moveldup_ps(a, 0, a); assert_eq_m256(r, a); @@ -54225,7 +56111,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_moveldup_ps() { + const unsafe fn test_mm256_maskz_moveldup_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_maskz_moveldup_ps(0, a); assert_eq_m256(r, _mm256_setzero_ps()); @@ -54235,7 +56121,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_moveldup_ps() { + const unsafe fn test_mm_mask_moveldup_ps() { let a = _mm_set_ps(1., 2., 3., 4.); let r = _mm_mask_moveldup_ps(a, 0, a); assert_eq_m128(r, a); @@ -54245,7 +56131,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_moveldup_ps() { + const unsafe fn test_mm_maskz_moveldup_ps() { let a = _mm_set_ps(1., 2., 3., 4.); let r = _mm_maskz_moveldup_ps(0, a); assert_eq_m128(r, _mm_setzero_ps()); @@ -54255,7 +56141,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_movehdup_ps() { + const unsafe fn test_mm512_movehdup_ps() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54267,7 +56153,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_movehdup_ps() { + const unsafe fn test_mm512_mask_movehdup_ps() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54281,7 +56167,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_movehdup_ps() { + const unsafe fn test_mm512_maskz_movehdup_ps() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54295,7 +56181,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_movehdup_ps() { + const unsafe fn test_mm256_mask_movehdup_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_mask_movehdup_ps(a, 0, a); assert_eq_m256(r, a); @@ -54305,7 +56191,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_movehdup_ps() { + const unsafe fn test_mm256_maskz_movehdup_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_maskz_movehdup_ps(0, a); assert_eq_m256(r, _mm256_setzero_ps()); @@ -54315,7 +56201,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_movehdup_ps() { + const unsafe fn test_mm_mask_movehdup_ps() { let a = _mm_set_ps(1., 2., 3., 4.); let r = _mm_mask_movehdup_ps(a, 0, a); assert_eq_m128(r, a); @@ -54325,7 +56211,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_movehdup_ps() { + const unsafe fn test_mm_maskz_movehdup_ps() { let a = _mm_set_ps(1., 2., 3., 4.); let r = _mm_maskz_movehdup_ps(0, a); assert_eq_m128(r, _mm_setzero_ps()); @@ -54335,7 +56221,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_inserti32x4() { + const unsafe fn test_mm512_inserti32x4() { let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm_setr_epi32(17, 18, 19, 20); let r = _mm512_inserti32x4::<0>(a, b); @@ -54344,7 +56230,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_inserti32x4() { + const unsafe fn test_mm512_mask_inserti32x4() { let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm_setr_epi32(17, 18, 19, 20); let r = _mm512_mask_inserti32x4::<0>(a, 0, a, b); @@ -54355,7 +56241,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_inserti32x4() { + const unsafe fn test_mm512_maskz_inserti32x4() { let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm_setr_epi32(17, 18, 19, 20); let r = _mm512_maskz_inserti32x4::<0>(0, a, b); @@ -54366,7 +56252,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_inserti32x4() { + const unsafe fn test_mm256_inserti32x4() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi32(17, 18, 19, 20); let r = _mm256_inserti32x4::<1>(a, b); @@ -54375,7 +56261,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_inserti32x4() { + const unsafe fn test_mm256_mask_inserti32x4() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi32(17, 18, 19, 20); let r = _mm256_mask_inserti32x4::<0>(a, 0, a, b); @@ -54386,7 +56272,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_inserti32x4() { + const unsafe fn test_mm256_maskz_inserti32x4() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi32(17, 18, 19, 20); let r = _mm256_maskz_inserti32x4::<0>(0, a, b); @@ -54397,7 +56283,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_insertf32x4() { + const unsafe fn test_mm512_insertf32x4() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54410,7 +56296,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_insertf32x4() { + const unsafe fn test_mm512_mask_insertf32x4() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54425,7 +56311,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_insertf32x4() { + const unsafe fn test_mm512_maskz_insertf32x4() { let a = _mm512_setr_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54440,7 +56326,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_insertf32x4() { + const unsafe fn test_mm256_insertf32x4() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm_set_ps(17., 18., 19., 20.); let r = _mm256_insertf32x4::<1>(a, b); @@ -54449,7 +56335,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_insertf32x4() { + const unsafe fn test_mm256_mask_insertf32x4() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm_set_ps(17., 18., 19., 20.); let r = _mm256_mask_insertf32x4::<0>(a, 0, a, b); @@ -54460,7 +56346,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_insertf32x4() { + const unsafe fn test_mm256_maskz_insertf32x4() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm_set_ps(17., 18., 19., 20.); let r = _mm256_maskz_insertf32x4::<0>(0, a, b); @@ -54471,21 +56357,21 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castps128_ps512() { + const unsafe fn test_mm512_castps128_ps512() { let a = _mm_setr_ps(17., 18., 19., 20.); let r = _mm512_castps128_ps512(a); assert_eq_m128(_mm512_castps512_ps128(r), a); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castps256_ps512() { + const unsafe fn test_mm512_castps256_ps512() { let a = _mm256_setr_ps(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm512_castps256_ps512(a); assert_eq_m256(_mm512_castps512_ps256(r), a); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_zextps128_ps512() { + const unsafe fn test_mm512_zextps128_ps512() { let a = _mm_setr_ps(17., 18., 19., 20.); let r = _mm512_zextps128_ps512(a); let e = _mm512_setr_ps( @@ -54495,7 +56381,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_zextps256_ps512() { + const unsafe fn test_mm512_zextps256_ps512() { let a = _mm256_setr_ps(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm512_zextps256_ps512(a); let e = _mm512_setr_ps( @@ -54505,7 +56391,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castps512_ps128() { + const unsafe fn test_mm512_castps512_ps128() { let a = _mm512_setr_ps( 17., 18., 19., 20., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., -1., ); @@ -54515,7 +56401,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castps512_ps256() { + const unsafe fn test_mm512_castps512_ps256() { let a = _mm512_setr_ps( 17., 18., 19., 20., 21., 22., 23., 24., -1., -1., -1., -1., -1., -1., -1., -1., ); @@ -54525,7 +56411,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castps_pd() { + const unsafe fn test_mm512_castps_pd() { let a = _mm512_set1_ps(1.); let r = _mm512_castps_pd(a); let e = _mm512_set1_pd(0.007812501848093234); @@ -54533,7 +56419,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castps_si512() { + const unsafe fn test_mm512_castps_si512() { let a = _mm512_set1_ps(1.); let r = _mm512_castps_si512(a); let e = _mm512_set1_epi32(1065353216); @@ -54541,7 +56427,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_broadcastd_epi32() { + const unsafe fn test_mm512_broadcastd_epi32() { let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm512_broadcastd_epi32(a); let e = _mm512_set1_epi32(20); @@ -54549,7 +56435,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_broadcastd_epi32() { + const unsafe fn test_mm512_mask_broadcastd_epi32() { let src = _mm512_set1_epi32(20); let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm512_mask_broadcastd_epi32(src, 0, a); @@ -54560,7 +56446,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_broadcastd_epi32() { + const unsafe fn test_mm512_maskz_broadcastd_epi32() { let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm512_maskz_broadcastd_epi32(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -54570,7 +56456,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_broadcastd_epi32() { + const unsafe fn test_mm256_mask_broadcastd_epi32() { let src = _mm256_set1_epi32(20); let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm256_mask_broadcastd_epi32(src, 0, a); @@ -54581,7 +56467,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_broadcastd_epi32() { + const unsafe fn test_mm256_maskz_broadcastd_epi32() { let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm256_maskz_broadcastd_epi32(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -54591,7 +56477,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_broadcastd_epi32() { + const unsafe fn test_mm_mask_broadcastd_epi32() { let src = _mm_set1_epi32(20); let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm_mask_broadcastd_epi32(src, 0, a); @@ -54602,7 +56488,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_broadcastd_epi32() { + const unsafe fn test_mm_maskz_broadcastd_epi32() { let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm_maskz_broadcastd_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -54612,7 +56498,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_broadcastss_ps() { + const unsafe fn test_mm512_broadcastss_ps() { let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm512_broadcastss_ps(a); let e = _mm512_set1_ps(20.); @@ -54620,7 +56506,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_broadcastss_ps() { + const unsafe fn test_mm512_mask_broadcastss_ps() { let src = _mm512_set1_ps(20.); let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm512_mask_broadcastss_ps(src, 0, a); @@ -54631,7 +56517,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_broadcastss_ps() { + const unsafe fn test_mm512_maskz_broadcastss_ps() { let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm512_maskz_broadcastss_ps(0, a); assert_eq_m512(r, _mm512_setzero_ps()); @@ -54643,7 +56529,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_broadcastss_ps() { + const unsafe fn test_mm256_mask_broadcastss_ps() { let src = _mm256_set1_ps(20.); let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm256_mask_broadcastss_ps(src, 0, a); @@ -54654,7 +56540,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_broadcastss_ps() { + const unsafe fn test_mm256_maskz_broadcastss_ps() { let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm256_maskz_broadcastss_ps(0, a); assert_eq_m256(r, _mm256_setzero_ps()); @@ -54664,7 +56550,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_broadcastss_ps() { + const unsafe fn test_mm_mask_broadcastss_ps() { let src = _mm_set1_ps(20.); let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm_mask_broadcastss_ps(src, 0, a); @@ -54675,7 +56561,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_broadcastss_ps() { + const unsafe fn test_mm_maskz_broadcastss_ps() { let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm_maskz_broadcastss_ps(0, a); assert_eq_m128(r, _mm_setzero_ps()); @@ -54685,7 +56571,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_broadcast_i32x4() { + const unsafe fn test_mm512_broadcast_i32x4() { let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm512_broadcast_i32x4(a); let e = _mm512_set_epi32( @@ -54695,7 +56581,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_broadcast_i32x4() { + const unsafe fn test_mm512_mask_broadcast_i32x4() { let src = _mm512_set1_epi32(20); let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm512_mask_broadcast_i32x4(src, 0, a); @@ -54708,7 +56594,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_broadcast_i32x4() { + const unsafe fn test_mm512_maskz_broadcast_i32x4() { let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm512_maskz_broadcast_i32x4(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -54718,7 +56604,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_broadcast_i32x4() { + const unsafe fn test_mm256_broadcast_i32x4() { let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm256_broadcast_i32x4(a); let e = _mm256_set_epi32(17, 18, 19, 20, 17, 18, 19, 20); @@ -54726,7 +56612,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_broadcast_i32x4() { + const unsafe fn test_mm256_mask_broadcast_i32x4() { let src = _mm256_set1_epi32(20); let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm256_mask_broadcast_i32x4(src, 0, a); @@ -54737,7 +56623,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_broadcast_i32x4() { + const unsafe fn test_mm256_maskz_broadcast_i32x4() { let a = _mm_set_epi32(17, 18, 19, 20); let r = _mm256_maskz_broadcast_i32x4(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -54747,7 +56633,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_broadcast_f32x4() { + const unsafe fn test_mm512_broadcast_f32x4() { let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm512_broadcast_f32x4(a); let e = _mm512_set_ps( @@ -54757,7 +56643,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_broadcast_f32x4() { + const unsafe fn test_mm512_mask_broadcast_f32x4() { let src = _mm512_set1_ps(20.); let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm512_mask_broadcast_f32x4(src, 0, a); @@ -54770,7 +56656,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_broadcast_f32x4() { + const unsafe fn test_mm512_maskz_broadcast_f32x4() { let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm512_maskz_broadcast_f32x4(0, a); assert_eq_m512(r, _mm512_setzero_ps()); @@ -54782,7 +56668,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_broadcast_f32x4() { + const unsafe fn test_mm256_broadcast_f32x4() { let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm256_broadcast_f32x4(a); let e = _mm256_set_ps(17., 18., 19., 20., 17., 18., 19., 20.); @@ -54790,7 +56676,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_broadcast_f32x4() { + const unsafe fn test_mm256_mask_broadcast_f32x4() { let src = _mm256_set1_ps(20.); let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm256_mask_broadcast_f32x4(src, 0, a); @@ -54801,7 +56687,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_broadcast_f32x4() { + const unsafe fn test_mm256_maskz_broadcast_f32x4() { let a = _mm_set_ps(17., 18., 19., 20.); let r = _mm256_maskz_broadcast_f32x4(0, a); assert_eq_m256(r, _mm256_setzero_ps()); @@ -54811,7 +56697,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_blend_epi32() { + const unsafe fn test_mm512_mask_blend_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_set1_epi32(2); let r = _mm512_mask_blend_epi32(0b11111111_00000000, a, b); @@ -54820,7 +56706,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_blend_epi32() { + const unsafe fn test_mm256_mask_blend_epi32() { let a = _mm256_set1_epi32(1); let b = _mm256_set1_epi32(2); let r = _mm256_mask_blend_epi32(0b11111111, a, b); @@ -54829,7 +56715,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_blend_epi32() { + const unsafe fn test_mm_mask_blend_epi32() { let a = _mm_set1_epi32(1); let b = _mm_set1_epi32(2); let r = _mm_mask_blend_epi32(0b00001111, a, b); @@ -54838,7 +56724,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_blend_ps() { + const unsafe fn test_mm512_mask_blend_ps() { let a = _mm512_set1_ps(1.); let b = _mm512_set1_ps(2.); let r = _mm512_mask_blend_ps(0b11111111_00000000, a, b); @@ -54849,7 +56735,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_blend_ps() { + const unsafe fn test_mm256_mask_blend_ps() { let a = _mm256_set1_ps(1.); let b = _mm256_set1_ps(2.); let r = _mm256_mask_blend_ps(0b11111111, a, b); @@ -54858,7 +56744,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_blend_ps() { + const unsafe fn test_mm_mask_blend_ps() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let r = _mm_mask_blend_ps(0b00001111, a, b); @@ -54867,7 +56753,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_unpackhi_epi32() { + const unsafe fn test_mm512_unpackhi_epi32() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm512_set_epi32( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -54878,7 +56764,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_unpackhi_epi32() { + const unsafe fn test_mm512_mask_unpackhi_epi32() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm512_set_epi32( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -54891,7 +56777,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_unpackhi_epi32() { + const unsafe fn test_mm512_maskz_unpackhi_epi32() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm512_set_epi32( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -54904,7 +56790,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_unpackhi_epi32() { + const unsafe fn test_mm256_mask_unpackhi_epi32() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm256_set_epi32(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm256_mask_unpackhi_epi32(a, 0, a, b); @@ -54915,7 +56801,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_unpackhi_epi32() { + const unsafe fn test_mm256_maskz_unpackhi_epi32() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm256_set_epi32(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm256_maskz_unpackhi_epi32(0, a, b); @@ -54926,7 +56812,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_unpackhi_epi32() { + const unsafe fn test_mm_mask_unpackhi_epi32() { let a = _mm_set_epi32(1, 2, 3, 4); let b = _mm_set_epi32(17, 18, 19, 20); let r = _mm_mask_unpackhi_epi32(a, 0, a, b); @@ -54937,7 +56823,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_unpackhi_epi32() { + const unsafe fn test_mm_maskz_unpackhi_epi32() { let a = _mm_set_epi32(1, 2, 3, 4); let b = _mm_set_epi32(17, 18, 19, 20); let r = _mm_maskz_unpackhi_epi32(0, a, b); @@ -54948,7 +56834,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_unpackhi_ps() { + const unsafe fn test_mm512_unpackhi_ps() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54963,7 +56849,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_unpackhi_ps() { + const unsafe fn test_mm512_mask_unpackhi_ps() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54980,7 +56866,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_unpackhi_ps() { + const unsafe fn test_mm512_maskz_unpackhi_ps() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -54997,7 +56883,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_unpackhi_ps() { + const unsafe fn test_mm256_mask_unpackhi_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_set_ps(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm256_mask_unpackhi_ps(a, 0, a, b); @@ -55008,7 +56894,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_unpackhi_ps() { + const unsafe fn test_mm256_maskz_unpackhi_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_set_ps(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm256_maskz_unpackhi_ps(0, a, b); @@ -55019,7 +56905,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_unpackhi_ps() { + const unsafe fn test_mm_mask_unpackhi_ps() { let a = _mm_set_ps(1., 2., 3., 4.); let b = _mm_set_ps(17., 18., 19., 20.); let r = _mm_mask_unpackhi_ps(a, 0, a, b); @@ -55030,7 +56916,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_unpackhi_ps() { + const unsafe fn test_mm_maskz_unpackhi_ps() { let a = _mm_set_ps(1., 2., 3., 4.); let b = _mm_set_ps(17., 18., 19., 20.); let r = _mm_maskz_unpackhi_ps(0, a, b); @@ -55041,7 +56927,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_unpacklo_epi32() { + const unsafe fn test_mm512_unpacklo_epi32() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm512_set_epi32( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -55052,7 +56938,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_unpacklo_epi32() { + const unsafe fn test_mm512_mask_unpacklo_epi32() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm512_set_epi32( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -55065,7 +56951,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_unpacklo_epi32() { + const unsafe fn test_mm512_maskz_unpacklo_epi32() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm512_set_epi32( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -55078,7 +56964,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_unpacklo_epi32() { + const unsafe fn test_mm256_mask_unpacklo_epi32() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm256_set_epi32(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm256_mask_unpacklo_epi32(a, 0, a, b); @@ -55089,7 +56975,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_unpacklo_epi32() { + const unsafe fn test_mm256_maskz_unpacklo_epi32() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm256_set_epi32(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm256_maskz_unpacklo_epi32(0, a, b); @@ -55100,7 +56986,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_unpacklo_epi32() { + const unsafe fn test_mm_mask_unpacklo_epi32() { let a = _mm_set_epi32(1, 2, 3, 4); let b = _mm_set_epi32(17, 18, 19, 20); let r = _mm_mask_unpacklo_epi32(a, 0, a, b); @@ -55111,7 +56997,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_unpacklo_epi32() { + const unsafe fn test_mm_maskz_unpacklo_epi32() { let a = _mm_set_epi32(1, 2, 3, 4); let b = _mm_set_epi32(17, 18, 19, 20); let r = _mm_maskz_unpacklo_epi32(0, a, b); @@ -55122,7 +57008,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_unpacklo_ps() { + const unsafe fn test_mm512_unpacklo_ps() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -55137,7 +57023,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_unpacklo_ps() { + const unsafe fn test_mm512_mask_unpacklo_ps() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -55154,7 +57040,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_unpacklo_ps() { + const unsafe fn test_mm512_maskz_unpacklo_ps() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -55171,7 +57057,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_unpacklo_ps() { + const unsafe fn test_mm256_mask_unpacklo_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_set_ps(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm256_mask_unpacklo_ps(a, 0, a, b); @@ -55182,7 +57068,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_unpacklo_ps() { + const unsafe fn test_mm256_maskz_unpacklo_ps() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_set_ps(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm256_maskz_unpacklo_ps(0, a, b); @@ -55193,7 +57079,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_unpacklo_ps() { + const unsafe fn test_mm_mask_unpacklo_ps() { let a = _mm_set_ps(1., 2., 3., 4.); let b = _mm_set_ps(17., 18., 19., 20.); let r = _mm_mask_unpacklo_ps(a, 0, a, b); @@ -55204,7 +57090,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_unpacklo_ps() { + const unsafe fn test_mm_maskz_unpacklo_ps() { let a = _mm_set_ps(1., 2., 3., 4.); let b = _mm_set_ps(17., 18., 19., 20.); let r = _mm_maskz_unpacklo_ps(0, a, b); @@ -55215,7 +57101,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_alignr_epi32() { + const unsafe fn test_mm512_alignr_epi32() { let a = _mm512_set_epi32(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); let b = _mm512_set_epi32( 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, @@ -55232,7 +57118,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_alignr_epi32() { + const unsafe fn test_mm512_mask_alignr_epi32() { let a = _mm512_set_epi32(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); let b = _mm512_set_epi32( 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, @@ -55247,7 +57133,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_alignr_epi32() { + const unsafe fn test_mm512_maskz_alignr_epi32() { let a = _mm512_set_epi32(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); let b = _mm512_set_epi32( 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, @@ -55260,7 +57146,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_alignr_epi32() { + const unsafe fn test_mm256_alignr_epi32() { let a = _mm256_set_epi32(8, 7, 6, 5, 4, 3, 2, 1); let b = _mm256_set_epi32(16, 15, 14, 13, 12, 11, 10, 9); let r = _mm256_alignr_epi32::<0>(a, b); @@ -55271,7 +57157,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_alignr_epi32() { + const unsafe fn test_mm256_mask_alignr_epi32() { let a = _mm256_set_epi32(8, 7, 6, 5, 4, 3, 2, 1); let b = _mm256_set_epi32(16, 15, 14, 13, 12, 11, 10, 9); let r = _mm256_mask_alignr_epi32::<1>(a, 0, a, b); @@ -55282,7 +57168,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_alignr_epi32() { + const unsafe fn test_mm256_maskz_alignr_epi32() { let a = _mm256_set_epi32(8, 7, 6, 5, 4, 3, 2, 1); let b = _mm256_set_epi32(16, 15, 14, 13, 12, 11, 10, 9); let r = _mm256_maskz_alignr_epi32::<1>(0, a, b); @@ -55293,7 +57179,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_alignr_epi32() { + const unsafe fn test_mm_alignr_epi32() { let a = _mm_set_epi32(4, 3, 2, 1); let b = _mm_set_epi32(8, 7, 6, 5); let r = _mm_alignr_epi32::<0>(a, b); @@ -55304,7 +57190,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_alignr_epi32() { + const unsafe fn test_mm_mask_alignr_epi32() { let a = _mm_set_epi32(4, 3, 2, 1); let b = _mm_set_epi32(8, 7, 6, 5); let r = _mm_mask_alignr_epi32::<1>(a, 0, a, b); @@ -55315,7 +57201,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_alignr_epi32() { + const unsafe fn test_mm_maskz_alignr_epi32() { let a = _mm_set_epi32(4, 3, 2, 1); let b = _mm_set_epi32(8, 7, 6, 5); let r = _mm_maskz_alignr_epi32::<1>(0, a, b); @@ -55326,7 +57212,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_and_epi32() { + const unsafe fn test_mm512_and_epi32() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55347,7 +57233,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_and_epi32() { + const unsafe fn test_mm512_mask_and_epi32() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55376,7 +57262,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_and_epi32() { + const unsafe fn test_mm512_maskz_and_epi32() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55399,7 +57285,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_and_epi32() { + const unsafe fn test_mm256_mask_and_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_mask_and_epi32(a, 0, a, b); @@ -55410,7 +57296,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_and_epi32() { + const unsafe fn test_mm256_maskz_and_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_maskz_and_epi32(0, a, b); @@ -55421,7 +57307,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_and_epi32() { + const unsafe fn test_mm_mask_and_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 1); let r = _mm_mask_and_epi32(a, 0, a, b); @@ -55432,7 +57318,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_and_epi32() { + const unsafe fn test_mm_maskz_and_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 1); let r = _mm_maskz_and_epi32(0, a, b); @@ -55443,7 +57329,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_and_si512() { + const unsafe fn test_mm512_and_si512() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55464,7 +57350,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_or_epi32() { + const unsafe fn test_mm512_or_epi32() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55491,7 +57377,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_or_epi32() { + const unsafe fn test_mm512_mask_or_epi32() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55520,7 +57406,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_or_epi32() { + const unsafe fn test_mm512_maskz_or_epi32() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55549,7 +57435,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_or_epi32() { + const unsafe fn test_mm256_or_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_or_epi32(a, b); @@ -55558,7 +57444,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_or_epi32() { + const unsafe fn test_mm256_mask_or_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_mask_or_epi32(a, 0, a, b); @@ -55569,7 +57455,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_or_epi32() { + const unsafe fn test_mm256_maskz_or_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_maskz_or_epi32(0, a, b); @@ -55580,7 +57466,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_or_epi32() { + const unsafe fn test_mm_or_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 1); let r = _mm_or_epi32(a, b); @@ -55589,7 +57475,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_or_epi32() { + const unsafe fn test_mm_mask_or_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 1); let r = _mm_mask_or_epi32(a, 0, a, b); @@ -55600,7 +57486,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_or_epi32() { + const unsafe fn test_mm_maskz_or_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 1); let r = _mm_maskz_or_epi32(0, a, b); @@ -55611,7 +57497,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_or_si512() { + const unsafe fn test_mm512_or_si512() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55638,7 +57524,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_xor_epi32() { + const unsafe fn test_mm512_xor_epi32() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55665,7 +57551,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_xor_epi32() { + const unsafe fn test_mm512_mask_xor_epi32() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55694,7 +57580,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_xor_epi32() { + const unsafe fn test_mm512_maskz_xor_epi32() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55717,7 +57603,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_xor_epi32() { + const unsafe fn test_mm256_xor_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_xor_epi32(a, b); @@ -55726,7 +57612,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_xor_epi32() { + const unsafe fn test_mm256_mask_xor_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_mask_xor_epi32(a, 0, a, b); @@ -55737,7 +57623,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_xor_epi32() { + const unsafe fn test_mm256_maskz_xor_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_maskz_xor_epi32(0, a, b); @@ -55748,7 +57634,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_xor_epi32() { + const unsafe fn test_mm_xor_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 1); let r = _mm_xor_epi32(a, b); @@ -55757,7 +57643,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_xor_epi32() { + const unsafe fn test_mm_mask_xor_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 1); let r = _mm_mask_xor_epi32(a, 0, a, b); @@ -55768,7 +57654,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_xor_epi32() { + const unsafe fn test_mm_maskz_xor_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 1); let r = _mm_maskz_xor_epi32(0, a, b); @@ -55779,7 +57665,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_xor_si512() { + const unsafe fn test_mm512_xor_si512() { #[rustfmt::skip] let a = _mm512_set_epi32( 1 << 1 | 1 << 2, 0, 0, 0, @@ -55806,7 +57692,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_andnot_epi32() { + const unsafe fn test_mm512_andnot_epi32() { let a = _mm512_set1_epi32(0); let b = _mm512_set1_epi32(1 << 3 | 1 << 4); let r = _mm512_andnot_epi32(a, b); @@ -55815,7 +57701,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_andnot_epi32() { + const unsafe fn test_mm512_mask_andnot_epi32() { let a = _mm512_set1_epi32(1 << 1 | 1 << 2); let b = _mm512_set1_epi32(1 << 3 | 1 << 4); let r = _mm512_mask_andnot_epi32(a, 0, a, b); @@ -55826,7 +57712,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_andnot_epi32() { + const unsafe fn test_mm512_maskz_andnot_epi32() { let a = _mm512_set1_epi32(1 << 1 | 1 << 2); let b = _mm512_set1_epi32(1 << 3 | 1 << 4); let r = _mm512_maskz_andnot_epi32(0, a, b); @@ -55843,7 +57729,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_andnot_epi32() { + const unsafe fn test_mm256_mask_andnot_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 3 | 1 << 4); let r = _mm256_mask_andnot_epi32(a, 0, a, b); @@ -55854,7 +57740,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_andnot_epi32() { + const unsafe fn test_mm256_maskz_andnot_epi32() { let a = _mm256_set1_epi32(1 << 1 | 1 << 2); let b = _mm256_set1_epi32(1 << 3 | 1 << 4); let r = _mm256_maskz_andnot_epi32(0, a, b); @@ -55865,7 +57751,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_andnot_epi32() { + const unsafe fn test_mm_mask_andnot_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 3 | 1 << 4); let r = _mm_mask_andnot_epi32(a, 0, a, b); @@ -55876,7 +57762,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_andnot_epi32() { + const unsafe fn test_mm_maskz_andnot_epi32() { let a = _mm_set1_epi32(1 << 1 | 1 << 2); let b = _mm_set1_epi32(1 << 3 | 1 << 4); let r = _mm_maskz_andnot_epi32(0, a, b); @@ -55887,7 +57773,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_cvtmask16_u32() { + const unsafe fn test_cvtmask16_u32() { let a: __mmask16 = 0b11001100_00110011; let r = _cvtmask16_u32(a); let e: u32 = 0b11001100_00110011; @@ -55895,7 +57781,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_cvtu32_mask16() { + const unsafe fn test_cvtu32_mask16() { let a: u32 = 0b11001100_00110011; let r = _cvtu32_mask16(a); let e: __mmask16 = 0b11001100_00110011; @@ -55903,7 +57789,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_kand() { + const unsafe fn test_mm512_kand() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b11001100_00110011; let r = _mm512_kand(a, b); @@ -55912,7 +57798,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kand_mask16() { + const unsafe fn test_kand_mask16() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b11001100_00110011; let r = _kand_mask16(a, b); @@ -55921,7 +57807,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_kor() { + const unsafe fn test_mm512_kor() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _mm512_kor(a, b); @@ -55930,7 +57816,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kor_mask16() { + const unsafe fn test_kor_mask16() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _kor_mask16(a, b); @@ -55939,7 +57825,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_kxor() { + const unsafe fn test_mm512_kxor() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _mm512_kxor(a, b); @@ -55948,7 +57834,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kxor_mask16() { + const unsafe fn test_kxor_mask16() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _kxor_mask16(a, b); @@ -55957,7 +57843,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_knot() { + const unsafe fn test_mm512_knot() { let a: u16 = 0b11001100_00110011; let r = _mm512_knot(a); let e: u16 = 0b00110011_11001100; @@ -55965,7 +57851,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_knot_mask16() { + const unsafe fn test_knot_mask16() { let a: u16 = 0b11001100_00110011; let r = _knot_mask16(a); let e: u16 = 0b00110011_11001100; @@ -55973,7 +57859,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_kandn() { + const unsafe fn test_mm512_kandn() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _mm512_kandn(a, b); @@ -55982,7 +57868,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kandn_mask16() { + const unsafe fn test_kandn_mask16() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _kandn_mask16(a, b); @@ -55991,7 +57877,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_kxnor() { + const unsafe fn test_mm512_kxnor() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _mm512_kxnor(a, b); @@ -56000,7 +57886,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kxnor_mask16() { + const unsafe fn test_kxnor_mask16() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _kxnor_mask16(a, b); @@ -56009,7 +57895,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kortest_mask16_u8() { + const unsafe fn test_kortest_mask16_u8() { let a: __mmask16 = 0b0110100101101001; let b: __mmask16 = 0b1011011010110110; let mut all_ones: u8 = 0; @@ -56019,7 +57905,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kortestc_mask16_u8() { + const unsafe fn test_kortestc_mask16_u8() { let a: __mmask16 = 0b0110100101101001; let b: __mmask16 = 0b1011011010110110; let r = _kortestc_mask16_u8(a, b); @@ -56027,7 +57913,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kortestz_mask16_u8() { + const unsafe fn test_kortestz_mask16_u8() { let a: __mmask16 = 0b0110100101101001; let b: __mmask16 = 0b1011011010110110; let r = _kortestz_mask16_u8(a, b); @@ -56035,7 +57921,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kshiftli_mask16() { + const unsafe fn test_kshiftli_mask16() { let a: __mmask16 = 0b1001011011000011; let r = _kshiftli_mask16::<3>(a); let e: __mmask16 = 0b1011011000011000; @@ -56055,7 +57941,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_kshiftri_mask16() { + const unsafe fn test_kshiftri_mask16() { let a: __mmask16 = 0b1010100100111100; let r = _kshiftri_mask16::<3>(a); let e: __mmask16 = 0b0001010100100111; @@ -56075,7 +57961,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_load_mask16() { + const unsafe fn test_load_mask16() { let a: __mmask16 = 0b1001011011000011; let r = _load_mask16(&a); let e: __mmask16 = 0b1001011011000011; @@ -56083,7 +57969,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_store_mask16() { + const unsafe fn test_store_mask16() { let a: __mmask16 = 0b0110100100111100; let mut r = 0; _store_mask16(&mut r, a); @@ -56092,7 +57978,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_kmov() { + const unsafe fn test_mm512_kmov() { let a: u16 = 0b11001100_00110011; let r = _mm512_kmov(a); let e: u16 = 0b11001100_00110011; @@ -56100,7 +57986,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_int2mask() { + const unsafe fn test_mm512_int2mask() { let a: i32 = 0b11001100_00110011; let r = _mm512_int2mask(a); let e: u16 = 0b11001100_00110011; @@ -56108,7 +57994,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask2int() { + const unsafe fn test_mm512_mask2int() { let k1: __mmask16 = 0b11001100_00110011; let r = _mm512_mask2int(k1); let e: i32 = 0b11001100_00110011; @@ -56116,7 +58002,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_kunpackb() { + const unsafe fn test_mm512_kunpackb() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _mm512_kunpackb(a, b); @@ -56125,7 +58011,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_kortestc() { + const unsafe fn test_mm512_kortestc() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _mm512_kortestc(a, b); @@ -56136,7 +58022,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_kortestz() { + const unsafe fn test_mm512_kortestz() { let a: u16 = 0b11001100_00110011; let b: u16 = 0b00101110_00001011; let r = _mm512_kortestz(a, b); @@ -56146,7 +58032,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_test_epi32_mask() { + const unsafe fn test_mm512_test_epi32_mask() { let a = _mm512_set1_epi32(1 << 0); let b = _mm512_set1_epi32(1 << 0 | 1 << 1); let r = _mm512_test_epi32_mask(a, b); @@ -56155,7 +58041,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_test_epi32_mask() { + const unsafe fn test_mm512_mask_test_epi32_mask() { let a = _mm512_set1_epi32(1 << 0); let b = _mm512_set1_epi32(1 << 0 | 1 << 1); let r = _mm512_mask_test_epi32_mask(0, a, b); @@ -56166,7 +58052,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_test_epi32_mask() { + const unsafe fn test_mm256_test_epi32_mask() { let a = _mm256_set1_epi32(1 << 0); let b = _mm256_set1_epi32(1 << 0 | 1 << 1); let r = _mm256_test_epi32_mask(a, b); @@ -56175,7 +58061,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_test_epi32_mask() { + const unsafe fn test_mm256_mask_test_epi32_mask() { let a = _mm256_set1_epi32(1 << 0); let b = _mm256_set1_epi32(1 << 0 | 1 << 1); let r = _mm256_mask_test_epi32_mask(0, a, b); @@ -56186,7 +58072,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_test_epi32_mask() { + const unsafe fn test_mm_test_epi32_mask() { let a = _mm_set1_epi32(1 << 0); let b = _mm_set1_epi32(1 << 0 | 1 << 1); let r = _mm_test_epi32_mask(a, b); @@ -56195,7 +58081,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_test_epi32_mask() { + const unsafe fn test_mm_mask_test_epi32_mask() { let a = _mm_set1_epi32(1 << 0); let b = _mm_set1_epi32(1 << 0 | 1 << 1); let r = _mm_mask_test_epi32_mask(0, a, b); @@ -56206,7 +58092,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_testn_epi32_mask() { + const unsafe fn test_mm512_testn_epi32_mask() { let a = _mm512_set1_epi32(1 << 0); let b = _mm512_set1_epi32(1 << 0 | 1 << 1); let r = _mm512_testn_epi32_mask(a, b); @@ -56215,7 +58101,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_testn_epi32_mask() { + const unsafe fn test_mm512_mask_testn_epi32_mask() { let a = _mm512_set1_epi32(1 << 0); let b = _mm512_set1_epi32(1 << 1); let r = _mm512_mask_test_epi32_mask(0, a, b); @@ -56226,7 +58112,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_testn_epi32_mask() { + const unsafe fn test_mm256_testn_epi32_mask() { let a = _mm256_set1_epi32(1 << 0); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_testn_epi32_mask(a, b); @@ -56235,7 +58121,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_testn_epi32_mask() { + const unsafe fn test_mm256_mask_testn_epi32_mask() { let a = _mm256_set1_epi32(1 << 0); let b = _mm256_set1_epi32(1 << 1); let r = _mm256_mask_test_epi32_mask(0, a, b); @@ -56246,7 +58132,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_testn_epi32_mask() { + const unsafe fn test_mm_testn_epi32_mask() { let a = _mm_set1_epi32(1 << 0); let b = _mm_set1_epi32(1 << 1); let r = _mm_testn_epi32_mask(a, b); @@ -56255,7 +58141,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_testn_epi32_mask() { + const unsafe fn test_mm_mask_testn_epi32_mask() { let a = _mm_set1_epi32(1 << 0); let b = _mm_set1_epi32(1 << 1); let r = _mm_mask_test_epi32_mask(0, a, b); @@ -56324,84 +58210,84 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_add_epi32() { + const unsafe fn test_mm512_reduce_add_epi32() { let a = _mm512_set1_epi32(1); let e: i32 = _mm512_reduce_add_epi32(a); assert_eq!(16, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_add_epi32() { + const unsafe fn test_mm512_mask_reduce_add_epi32() { let a = _mm512_set1_epi32(1); let e: i32 = _mm512_mask_reduce_add_epi32(0b11111111_00000000, a); assert_eq!(8, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_add_ps() { + const unsafe fn test_mm512_reduce_add_ps() { let a = _mm512_set1_ps(1.); let e: f32 = _mm512_reduce_add_ps(a); assert_eq!(16., e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_add_ps() { + const unsafe fn test_mm512_mask_reduce_add_ps() { let a = _mm512_set1_ps(1.); let e: f32 = _mm512_mask_reduce_add_ps(0b11111111_00000000, a); assert_eq!(8., e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_mul_epi32() { + const unsafe fn test_mm512_reduce_mul_epi32() { let a = _mm512_set1_epi32(2); let e: i32 = _mm512_reduce_mul_epi32(a); assert_eq!(65536, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_mul_epi32() { + const unsafe fn test_mm512_mask_reduce_mul_epi32() { let a = _mm512_set1_epi32(2); let e: i32 = _mm512_mask_reduce_mul_epi32(0b11111111_00000000, a); assert_eq!(256, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_mul_ps() { + const unsafe fn test_mm512_reduce_mul_ps() { let a = _mm512_set1_ps(2.); let e: f32 = _mm512_reduce_mul_ps(a); assert_eq!(65536., e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_mul_ps() { + const unsafe fn test_mm512_mask_reduce_mul_ps() { let a = _mm512_set1_ps(2.); let e: f32 = _mm512_mask_reduce_mul_ps(0b11111111_00000000, a); assert_eq!(256., e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_max_epi32() { + const unsafe fn test_mm512_reduce_max_epi32() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i32 = _mm512_reduce_max_epi32(a); assert_eq!(15, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_max_epi32() { + const unsafe fn test_mm512_mask_reduce_max_epi32() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i32 = _mm512_mask_reduce_max_epi32(0b11111111_00000000, a); assert_eq!(7, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_max_epu32() { + const unsafe fn test_mm512_reduce_max_epu32() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u32 = _mm512_reduce_max_epu32(a); assert_eq!(15, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_max_epu32() { + const unsafe fn test_mm512_mask_reduce_max_epu32() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u32 = _mm512_mask_reduce_max_epu32(0b11111111_00000000, a); assert_eq!(7, e); @@ -56426,28 +58312,28 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_min_epi32() { + const unsafe fn test_mm512_reduce_min_epi32() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i32 = _mm512_reduce_min_epi32(a); assert_eq!(0, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_min_epi32() { + const unsafe fn test_mm512_mask_reduce_min_epi32() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i32 = _mm512_mask_reduce_min_epi32(0b11111111_00000000, a); assert_eq!(0, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_min_epu32() { + const unsafe fn test_mm512_reduce_min_epu32() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u32 = _mm512_reduce_min_epu32(a); assert_eq!(0, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_min_epu32() { + const unsafe fn test_mm512_mask_reduce_min_epu32() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u32 = _mm512_mask_reduce_min_epu32(0b11111111_00000000, a); assert_eq!(0, e); @@ -56472,28 +58358,28 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_and_epi32() { + const unsafe fn test_mm512_reduce_and_epi32() { let a = _mm512_set_epi32(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e: i32 = _mm512_reduce_and_epi32(a); assert_eq!(0, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_and_epi32() { + const unsafe fn test_mm512_mask_reduce_and_epi32() { let a = _mm512_set_epi32(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e: i32 = _mm512_mask_reduce_and_epi32(0b11111111_00000000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_or_epi32() { + const unsafe fn test_mm512_reduce_or_epi32() { let a = _mm512_set_epi32(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e: i32 = _mm512_reduce_or_epi32(a); assert_eq!(3, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_or_epi32() { + const unsafe fn test_mm512_mask_reduce_or_epi32() { let a = _mm512_set_epi32(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e: i32 = _mm512_mask_reduce_and_epi32(0b11111111_00000000, a); assert_eq!(1, e); @@ -56904,7 +58790,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_loadu_epi32() { + const unsafe fn test_mm512_loadu_epi32() { let a = &[4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50]; let p = a.as_ptr(); let r = _mm512_loadu_epi32(black_box(p)); @@ -56913,7 +58799,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_loadu_epi32() { + const unsafe fn test_mm256_loadu_epi32() { let a = &[4, 3, 2, 5, 8, 9, 64, 50]; let p = a.as_ptr(); let r = _mm256_loadu_epi32(black_box(p)); @@ -56922,7 +58808,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_loadu_epi32() { + const unsafe fn test_mm_loadu_epi32() { let a = &[4, 3, 2, 5]; let p = a.as_ptr(); let r = _mm_loadu_epi32(black_box(p)); @@ -57126,7 +59012,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_storeu_epi32() { + const unsafe fn test_mm512_storeu_epi32() { let a = _mm512_set1_epi32(9); let mut r = _mm512_undefined_epi32(); _mm512_storeu_epi32(&mut r as *mut _ as *mut i32, a); @@ -57134,7 +59020,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_storeu_epi32() { + const unsafe fn test_mm256_storeu_epi32() { let a = _mm256_set1_epi32(9); let mut r = _mm256_undefined_si256(); _mm256_storeu_epi32(&mut r as *mut _ as *mut i32, a); @@ -57142,7 +59028,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_storeu_epi32() { + const unsafe fn test_mm_storeu_epi32() { let a = _mm_set1_epi32(9); let mut r = _mm_undefined_si128(); _mm_storeu_epi32(&mut r as *mut _ as *mut i32, a); @@ -57150,7 +59036,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_loadu_si512() { + const unsafe fn test_mm512_loadu_si512() { let a = &[4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50]; let p = a.as_ptr().cast(); let r = _mm512_loadu_si512(black_box(p)); @@ -57159,7 +59045,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_storeu_si512() { + const unsafe fn test_mm512_storeu_si512() { let a = _mm512_set1_epi32(9); let mut r = _mm512_undefined_epi32(); _mm512_storeu_si512(&mut r as *mut _, a); @@ -57167,7 +59053,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_load_si512() { + const unsafe fn test_mm512_load_si512() { #[repr(align(64))] struct Align { data: [i32; 16], // 64 bytes @@ -57182,7 +59068,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_store_si512() { + const unsafe fn test_mm512_store_si512() { let a = _mm512_set1_epi32(9); let mut r = _mm512_undefined_epi32(); _mm512_store_si512(&mut r as *mut _, a); @@ -57190,7 +59076,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_load_epi32() { + const unsafe fn test_mm512_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 16], // 64 bytes @@ -57205,7 +59091,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_load_epi32() { + const unsafe fn test_mm256_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 8], @@ -57220,7 +59106,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_load_epi32() { + const unsafe fn test_mm_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 4], @@ -57233,7 +59119,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_store_epi32() { + const unsafe fn test_mm512_store_epi32() { let a = _mm512_set1_epi32(9); let mut r = _mm512_undefined_epi32(); _mm512_store_epi32(&mut r as *mut _ as *mut i32, a); @@ -57241,7 +59127,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_store_epi32() { + const unsafe fn test_mm256_store_epi32() { let a = _mm256_set1_epi32(9); let mut r = _mm256_undefined_si256(); _mm256_store_epi32(&mut r as *mut _ as *mut i32, a); @@ -57249,7 +59135,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_store_epi32() { + const unsafe fn test_mm_store_epi32() { let a = _mm_set1_epi32(9); let mut r = _mm_undefined_si128(); _mm_store_epi32(&mut r as *mut _ as *mut i32, a); @@ -57257,7 +59143,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_load_ps() { + const unsafe fn test_mm512_load_ps() { #[repr(align(64))] struct Align { data: [f32; 16], // 64 bytes @@ -57276,7 +59162,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_store_ps() { + const unsafe fn test_mm512_store_ps() { let a = _mm512_set1_ps(9.); let mut r = _mm512_undefined_ps(); _mm512_store_ps(&mut r as *mut _ as *mut f32, a); @@ -57284,7 +59170,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_set1_epi32() { + const unsafe fn test_mm512_mask_set1_epi32() { let src = _mm512_set1_epi32(2); let a: i32 = 11; let r = _mm512_mask_set1_epi32(src, 0, a); @@ -57295,7 +59181,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_set1_epi32() { + const unsafe fn test_mm512_maskz_set1_epi32() { let a: i32 = 11; let r = _mm512_maskz_set1_epi32(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -57305,7 +59191,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_set1_epi32() { + const unsafe fn test_mm256_mask_set1_epi32() { let src = _mm256_set1_epi32(2); let a: i32 = 11; let r = _mm256_mask_set1_epi32(src, 0, a); @@ -57316,7 +59202,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_set1_epi32() { + const unsafe fn test_mm256_maskz_set1_epi32() { let a: i32 = 11; let r = _mm256_maskz_set1_epi32(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -57326,7 +59212,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_set1_epi32() { + const unsafe fn test_mm_mask_set1_epi32() { let src = _mm_set1_epi32(2); let a: i32 = 11; let r = _mm_mask_set1_epi32(src, 0, a); @@ -57337,7 +59223,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_set1_epi32() { + const unsafe fn test_mm_maskz_set1_epi32() { let a: i32 = 11; let r = _mm_maskz_set1_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -57347,7 +59233,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_move_ss() { + const unsafe fn test_mm_mask_move_ss() { let src = _mm_set_ps(10., 11., 100., 110.); let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); @@ -57360,7 +59246,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_move_ss() { + const unsafe fn test_mm_maskz_move_ss() { let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); let r = _mm_maskz_move_ss(0, a, b); @@ -57372,7 +59258,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_move_sd() { + const unsafe fn test_mm_mask_move_sd() { let src = _mm_set_pd(10., 11.); let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); @@ -57385,7 +59271,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_move_sd() { + const unsafe fn test_mm_maskz_move_sd() { let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); let r = _mm_maskz_move_sd(0, a, b); @@ -57397,7 +59283,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_add_ss() { + const unsafe fn test_mm_mask_add_ss() { let src = _mm_set_ps(10., 11., 100., 110.); let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); @@ -57410,7 +59296,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_add_ss() { + const unsafe fn test_mm_maskz_add_ss() { let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); let r = _mm_maskz_add_ss(0, a, b); @@ -57422,7 +59308,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_add_sd() { + const unsafe fn test_mm_mask_add_sd() { let src = _mm_set_pd(10., 11.); let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); @@ -57435,7 +59321,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_add_sd() { + const unsafe fn test_mm_maskz_add_sd() { let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); let r = _mm_maskz_add_sd(0, a, b); @@ -57447,7 +59333,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_sub_ss() { + const unsafe fn test_mm_mask_sub_ss() { let src = _mm_set_ps(10., 11., 100., 110.); let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); @@ -57460,7 +59346,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_sub_ss() { + const unsafe fn test_mm_maskz_sub_ss() { let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); let r = _mm_maskz_sub_ss(0, a, b); @@ -57472,7 +59358,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_sub_sd() { + const unsafe fn test_mm_mask_sub_sd() { let src = _mm_set_pd(10., 11.); let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); @@ -57485,7 +59371,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_sub_sd() { + const unsafe fn test_mm_maskz_sub_sd() { let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); let r = _mm_maskz_sub_sd(0, a, b); @@ -57497,7 +59383,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_mul_ss() { + const unsafe fn test_mm_mask_mul_ss() { let src = _mm_set_ps(10., 11., 100., 110.); let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); @@ -57510,7 +59396,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_mul_ss() { + const unsafe fn test_mm_maskz_mul_ss() { let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); let r = _mm_maskz_mul_ss(0, a, b); @@ -57522,7 +59408,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_mul_sd() { + const unsafe fn test_mm_mask_mul_sd() { let src = _mm_set_pd(10., 11.); let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); @@ -57535,7 +59421,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_mul_sd() { + const unsafe fn test_mm_maskz_mul_sd() { let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); let r = _mm_maskz_mul_sd(0, a, b); @@ -57547,7 +59433,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_div_ss() { + const unsafe fn test_mm_mask_div_ss() { let src = _mm_set_ps(10., 11., 100., 110.); let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); @@ -57560,7 +59446,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_div_ss() { + const unsafe fn test_mm_maskz_div_ss() { let a = _mm_set_ps(1., 2., 10., 20.); let b = _mm_set_ps(3., 4., 30., 40.); let r = _mm_maskz_div_ss(0, a, b); @@ -57572,7 +59458,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_div_sd() { + const unsafe fn test_mm_mask_div_sd() { let src = _mm_set_pd(10., 11.); let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); @@ -57585,7 +59471,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_div_sd() { + const unsafe fn test_mm_maskz_div_sd() { let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(3., 4.); let r = _mm_maskz_div_sd(0, a, b); @@ -58143,7 +60029,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_fmadd_ss() { + const unsafe fn test_mm_mask_fmadd_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58155,7 +60041,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_fmadd_ss() { + const unsafe fn test_mm_maskz_fmadd_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58168,7 +60054,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask3_fmadd_ss() { + const unsafe fn test_mm_mask3_fmadd_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58180,7 +60066,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_fmadd_sd() { + const unsafe fn test_mm_mask_fmadd_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58192,7 +60078,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_fmadd_sd() { + const unsafe fn test_mm_maskz_fmadd_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58205,7 +60091,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask3_fmadd_sd() { + const unsafe fn test_mm_mask3_fmadd_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58217,7 +60103,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_fmsub_ss() { + const unsafe fn test_mm_mask_fmsub_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58229,7 +60115,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_fmsub_ss() { + const unsafe fn test_mm_maskz_fmsub_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58242,7 +60128,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask3_fmsub_ss() { + const unsafe fn test_mm_mask3_fmsub_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58254,7 +60140,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_fmsub_sd() { + const unsafe fn test_mm_mask_fmsub_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58266,7 +60152,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_fmsub_sd() { + const unsafe fn test_mm_maskz_fmsub_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58279,7 +60165,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask3_fmsub_sd() { + const unsafe fn test_mm_mask3_fmsub_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58291,7 +60177,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_fnmadd_ss() { + const unsafe fn test_mm_mask_fnmadd_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58303,7 +60189,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_fnmadd_ss() { + const unsafe fn test_mm_maskz_fnmadd_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58316,7 +60202,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask3_fnmadd_ss() { + const unsafe fn test_mm_mask3_fnmadd_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58328,7 +60214,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_fnmadd_sd() { + const unsafe fn test_mm_mask_fnmadd_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58340,7 +60226,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_fnmadd_sd() { + const unsafe fn test_mm_maskz_fnmadd_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58353,7 +60239,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask3_fnmadd_sd() { + const unsafe fn test_mm_mask3_fnmadd_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58365,7 +60251,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_fnmsub_ss() { + const unsafe fn test_mm_mask_fnmsub_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58377,7 +60263,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_fnmsub_ss() { + const unsafe fn test_mm_maskz_fnmsub_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58390,7 +60276,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask3_fnmsub_ss() { + const unsafe fn test_mm_mask3_fnmsub_ss() { let a = _mm_set1_ps(1.); let b = _mm_set1_ps(2.); let c = _mm_set1_ps(3.); @@ -58402,7 +60288,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_fnmsub_sd() { + const unsafe fn test_mm_mask_fnmsub_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58414,7 +60300,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_fnmsub_sd() { + const unsafe fn test_mm_maskz_fnmsub_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -58427,7 +60313,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask3_fnmsub_sd() { + const unsafe fn test_mm_mask3_fnmsub_sd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let c = _mm_set1_pd(3.); @@ -60082,7 +61968,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_cvti32_ss() { + const unsafe fn test_mm_cvti32_ss() { let a = _mm_set_ps(0., -0.5, 1., -1.5); let b: i32 = 9; let r = _mm_cvti32_ss(a, b); @@ -60091,7 +61977,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_cvti32_sd() { + const unsafe fn test_mm_cvti32_sd() { let a = _mm_set_pd(1., -1.5); let b: i32 = 9; let r = _mm_cvti32_sd(a, b); @@ -60180,7 +62066,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_cvtu32_ss() { + const unsafe fn test_mm_cvtu32_ss() { let a = _mm_set_ps(0., -0.5, 1., -1.5); let b: u32 = 9; let r = _mm_cvtu32_ss(a, b); @@ -60189,7 +62075,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_cvtu32_sd() { + const unsafe fn test_mm_cvtu32_sd() { let a = _mm_set_pd(1., -1.5); let b: u32 = 9; let r = _mm_cvtu32_sd(a, b); @@ -60216,7 +62102,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtsi512_si32() { + const unsafe fn test_mm512_cvtsi512_si32() { let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_cvtsi512_si32(a); let e: i32 = 1; @@ -60224,7 +62110,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtss_f32() { + const unsafe fn test_mm512_cvtss_f32() { let a = _mm512_setr_ps( 312.0134, 3., 2., 5., 8., 9., 64., 50., -4., -3., -2., -5., -8., -9., -64., -50., ); @@ -60232,13 +62118,13 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtsd_f64() { + const unsafe fn test_mm512_cvtsd_f64() { let r = _mm512_cvtsd_f64(_mm512_setr_pd(-1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8)); assert_eq!(r, -1.1); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_shuffle_pd() { + const unsafe fn test_mm512_shuffle_pd() { let a = _mm512_setr_pd(1., 4., 5., 8., 1., 4., 5., 8.); let b = _mm512_setr_pd(2., 3., 6., 7., 2., 3., 6., 7.); let r = _mm512_shuffle_pd::<0b11_11_11_11>(a, b); @@ -60247,7 +62133,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_shuffle_pd() { + const unsafe fn test_mm512_mask_shuffle_pd() { let a = _mm512_setr_pd(1., 4., 5., 8., 1., 4., 5., 8.); let b = _mm512_setr_pd(2., 3., 6., 7., 2., 3., 6., 7.); let r = _mm512_mask_shuffle_pd::<0b11_11_11_11>(a, 0, a, b); @@ -60258,7 +62144,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_shuffle_pd() { + const unsafe fn test_mm512_maskz_shuffle_pd() { let a = _mm512_setr_pd(1., 4., 5., 8., 1., 4., 5., 8.); let b = _mm512_setr_pd(2., 3., 6., 7., 2., 3., 6., 7.); let r = _mm512_maskz_shuffle_pd::<0b11_11_11_11>(0, a, b); diff --git a/library/stdarch/crates/core_arch/src/x86_64/avx512f.rs b/library/stdarch/crates/core_arch/src/x86_64/avx512f.rs index a2656c853563..c85a5580c864 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/avx512f.rs @@ -57,7 +57,8 @@ pub fn _mm_cvtsd_u64(a: __m128d) -> u64 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtsi2ss))] -pub fn _mm_cvti64_ss(a: __m128, b: i64) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvti64_ss(a: __m128, b: i64) -> __m128 { unsafe { let b = b as f32; simd_insert!(a, 0, b) @@ -71,7 +72,8 @@ pub fn _mm_cvti64_ss(a: __m128, b: i64) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtsi2sd))] -pub fn _mm_cvti64_sd(a: __m128d, b: i64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvti64_sd(a: __m128d, b: i64) -> __m128d { unsafe { let b = b as f64; simd_insert!(a, 0, b) @@ -85,7 +87,8 @@ pub fn _mm_cvti64_sd(a: __m128d, b: i64) -> __m128d { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtusi2ss))] -pub fn _mm_cvtu64_ss(a: __m128, b: u64) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtu64_ss(a: __m128, b: u64) -> __m128 { unsafe { let b = b as f32; simd_insert!(a, 0, b) @@ -99,7 +102,8 @@ pub fn _mm_cvtu64_ss(a: __m128, b: u64) -> __m128 { #[target_feature(enable = "avx512f")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vcvtusi2sd))] -pub fn _mm_cvtu64_sd(a: __m128d, b: u64) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtu64_sd(a: __m128d, b: u64) -> __m128d { unsafe { let b = b as f64; simd_insert!(a, 0, b) @@ -554,6 +558,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; @@ -562,7 +567,7 @@ mod tests { use crate::hint::black_box; #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_abs_epi64() { + const unsafe fn test_mm512_abs_epi64() { let a = _mm512_set_epi64(0, 1, -1, i64::MAX, i64::MIN, 100, -100, -32); let r = _mm512_abs_epi64(a); let e = _mm512_set_epi64(0, 1, 1, i64::MAX, i64::MAX.wrapping_add(1), 100, 100, 32); @@ -570,7 +575,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_abs_epi64() { + const unsafe fn test_mm512_mask_abs_epi64() { let a = _mm512_set_epi64(0, 1, -1, i64::MAX, i64::MIN, 100, -100, -32); let r = _mm512_mask_abs_epi64(a, 0, a); assert_eq_m512i(r, a); @@ -580,7 +585,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_abs_epi64() { + const unsafe fn test_mm512_maskz_abs_epi64() { let a = _mm512_set_epi64(0, 1, -1, i64::MAX, i64::MIN, 100, -100, -32); let r = _mm512_maskz_abs_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -590,7 +595,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_abs_epi64() { + const unsafe fn test_mm256_abs_epi64() { let a = _mm256_set_epi64x(i64::MAX, i64::MIN, 100, -100); let r = _mm256_abs_epi64(a); let e = _mm256_set_epi64x(i64::MAX, i64::MAX.wrapping_add(1), 100, 100); @@ -598,7 +603,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_abs_epi64() { + const unsafe fn test_mm256_mask_abs_epi64() { let a = _mm256_set_epi64x(i64::MAX, i64::MIN, 100, -100); let r = _mm256_mask_abs_epi64(a, 0, a); assert_eq_m256i(r, a); @@ -608,7 +613,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_abs_epi64() { + const unsafe fn test_mm256_maskz_abs_epi64() { let a = _mm256_set_epi64x(i64::MAX, i64::MIN, 100, -100); let r = _mm256_maskz_abs_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -618,7 +623,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_abs_epi64() { + const unsafe fn test_mm_abs_epi64() { let a = _mm_set_epi64x(i64::MAX, i64::MIN); let r = _mm_abs_epi64(a); let e = _mm_set_epi64x(i64::MAX, i64::MAX.wrapping_add(1)); @@ -630,7 +635,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_abs_epi64() { + const unsafe fn test_mm_mask_abs_epi64() { let a = _mm_set_epi64x(i64::MAX, i64::MIN); let r = _mm_mask_abs_epi64(a, 0, a); assert_eq_m128i(r, a); @@ -644,7 +649,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_abs_epi64() { + const unsafe fn test_mm_maskz_abs_epi64() { let a = _mm_set_epi64x(i64::MAX, i64::MIN); let r = _mm_maskz_abs_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -658,7 +663,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_abs_pd() { + const unsafe fn test_mm512_abs_pd() { let a = _mm512_setr_pd(0., 1., -1., f64::MAX, f64::MIN, 100., -100., -32.); let r = _mm512_abs_pd(a); let e = _mm512_setr_pd(0., 1., 1., f64::MAX, f64::MAX, 100., 100., 32.); @@ -666,7 +671,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_abs_pd() { + const unsafe fn test_mm512_mask_abs_pd() { let a = _mm512_setr_pd(0., 1., -1., f64::MAX, f64::MIN, 100., -100., -32.); let r = _mm512_mask_abs_pd(a, 0, a); assert_eq_m512d(r, a); @@ -676,7 +681,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mov_epi64() { + const unsafe fn test_mm512_mask_mov_epi64() { let src = _mm512_set1_epi64(1); let a = _mm512_set1_epi64(2); let r = _mm512_mask_mov_epi64(src, 0, a); @@ -686,7 +691,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_mov_epi64() { + const unsafe fn test_mm512_maskz_mov_epi64() { let a = _mm512_set1_epi64(2); let r = _mm512_maskz_mov_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -695,7 +700,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_mov_epi64() { + const unsafe fn test_mm256_mask_mov_epi64() { let src = _mm256_set1_epi64x(1); let a = _mm256_set1_epi64x(2); let r = _mm256_mask_mov_epi64(src, 0, a); @@ -705,7 +710,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_mov_epi64() { + const unsafe fn test_mm256_maskz_mov_epi64() { let a = _mm256_set1_epi64x(2); let r = _mm256_maskz_mov_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -714,7 +719,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_mov_epi64() { + const unsafe fn test_mm_mask_mov_epi64() { let src = _mm_set1_epi64x(1); let a = _mm_set1_epi64x(2); let r = _mm_mask_mov_epi64(src, 0, a); @@ -724,7 +729,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_mov_epi64() { + const unsafe fn test_mm_maskz_mov_epi64() { let a = _mm_set1_epi64x(2); let r = _mm_maskz_mov_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -733,7 +738,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mov_pd() { + const unsafe fn test_mm512_mask_mov_pd() { let src = _mm512_set1_pd(1.); let a = _mm512_set1_pd(2.); let r = _mm512_mask_mov_pd(src, 0, a); @@ -743,7 +748,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_mov_pd() { + const unsafe fn test_mm512_maskz_mov_pd() { let a = _mm512_set1_pd(2.); let r = _mm512_maskz_mov_pd(0, a); assert_eq_m512d(r, _mm512_setzero_pd()); @@ -752,7 +757,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_mov_pd() { + const unsafe fn test_mm256_mask_mov_pd() { let src = _mm256_set1_pd(1.); let a = _mm256_set1_pd(2.); let r = _mm256_mask_mov_pd(src, 0, a); @@ -762,7 +767,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_mov_pd() { + const unsafe fn test_mm256_maskz_mov_pd() { let a = _mm256_set1_pd(2.); let r = _mm256_maskz_mov_pd(0, a); assert_eq_m256d(r, _mm256_setzero_pd()); @@ -771,7 +776,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_mov_pd() { + const unsafe fn test_mm_mask_mov_pd() { let src = _mm_set1_pd(1.); let a = _mm_set1_pd(2.); let r = _mm_mask_mov_pd(src, 0, a); @@ -781,7 +786,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_mov_pd() { + const unsafe fn test_mm_maskz_mov_pd() { let a = _mm_set1_pd(2.); let r = _mm_maskz_mov_pd(0, a); assert_eq_m128d(r, _mm_setzero_pd()); @@ -790,7 +795,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_add_epi64() { + const unsafe fn test_mm512_add_epi64() { let a = _mm512_setr_epi64(0, 1, -1, i64::MAX, i64::MIN, 100, -100, -32); let b = _mm512_set1_epi64(1); let r = _mm512_add_epi64(a, b); @@ -799,7 +804,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_add_epi64() { + const unsafe fn test_mm512_mask_add_epi64() { let a = _mm512_setr_epi64(0, 1, -1, i64::MAX, i64::MIN, 100, -100, -32); let b = _mm512_set1_epi64(1); let r = _mm512_mask_add_epi64(a, 0, a, b); @@ -810,7 +815,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_add_epi64() { + const unsafe fn test_mm512_maskz_add_epi64() { let a = _mm512_setr_epi64(0, 1, -1, i64::MAX, i64::MIN, 100, -100, -32); let b = _mm512_set1_epi64(1); let r = _mm512_maskz_add_epi64(0, a, b); @@ -821,7 +826,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_add_epi64() { + const unsafe fn test_mm256_mask_add_epi64() { let a = _mm256_set_epi64x(1, -1, i64::MAX, i64::MIN); let b = _mm256_set1_epi64x(1); let r = _mm256_mask_add_epi64(a, 0, a, b); @@ -832,7 +837,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_add_epi64() { + const unsafe fn test_mm256_maskz_add_epi64() { let a = _mm256_set_epi64x(1, -1, i64::MAX, i64::MIN); let b = _mm256_set1_epi64x(1); let r = _mm256_maskz_add_epi64(0, a, b); @@ -843,7 +848,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_add_epi64() { + const unsafe fn test_mm_mask_add_epi64() { let a = _mm_set_epi64x(i64::MAX, i64::MIN); let b = _mm_set1_epi64x(1); let r = _mm_mask_add_epi64(a, 0, a, b); @@ -854,7 +859,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_add_epi64() { + const unsafe fn test_mm_maskz_add_epi64() { let a = _mm_set_epi64x(i64::MAX, i64::MIN); let b = _mm_set1_epi64x(1); let r = _mm_maskz_add_epi64(0, a, b); @@ -865,7 +870,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_add_pd() { + const unsafe fn test_mm512_add_pd() { let a = _mm512_setr_pd(0., 1., -1., f64::MAX, f64::MIN, 100., -100., -32.); let b = _mm512_set1_pd(1.); let r = _mm512_add_pd(a, b); @@ -874,7 +879,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_add_pd() { + const unsafe fn test_mm512_mask_add_pd() { let a = _mm512_setr_pd(0., 1., -1., f64::MAX, f64::MIN, 100., -100., -32.); let b = _mm512_set1_pd(1.); let r = _mm512_mask_add_pd(a, 0, a, b); @@ -885,7 +890,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_add_pd() { + const unsafe fn test_mm512_maskz_add_pd() { let a = _mm512_setr_pd(0., 1., -1., f64::MAX, f64::MIN, 100., -100., -32.); let b = _mm512_set1_pd(1.); let r = _mm512_maskz_add_pd(0, a, b); @@ -896,7 +901,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_add_pd() { + const unsafe fn test_mm256_mask_add_pd() { let a = _mm256_set_pd(1., -1., f64::MAX, f64::MIN); let b = _mm256_set1_pd(1.); let r = _mm256_mask_add_pd(a, 0, a, b); @@ -907,7 +912,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_add_pd() { + const unsafe fn test_mm256_maskz_add_pd() { let a = _mm256_set_pd(1., -1., f64::MAX, f64::MIN); let b = _mm256_set1_pd(1.); let r = _mm256_maskz_add_pd(0, a, b); @@ -918,7 +923,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_add_pd() { + const unsafe fn test_mm_mask_add_pd() { let a = _mm_set_pd(f64::MAX, f64::MIN); let b = _mm_set1_pd(1.); let r = _mm_mask_add_pd(a, 0, a, b); @@ -929,7 +934,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_add_pd() { + const unsafe fn test_mm_maskz_add_pd() { let a = _mm_set_pd(f64::MAX, f64::MIN); let b = _mm_set1_pd(1.); let r = _mm_maskz_add_pd(0, a, b); @@ -940,7 +945,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_sub_epi64() { + const unsafe fn test_mm512_sub_epi64() { let a = _mm512_setr_epi64(0, 1, -1, i64::MAX, i64::MIN, 100, -100, -32); let b = _mm512_set1_epi64(1); let r = _mm512_sub_epi64(a, b); @@ -949,7 +954,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_sub_epi64() { + const unsafe fn test_mm512_mask_sub_epi64() { let a = _mm512_setr_epi64(0, 1, -1, i64::MAX, i64::MIN, 100, -100, -32); let b = _mm512_set1_epi64(1); let r = _mm512_mask_sub_epi64(a, 0, a, b); @@ -960,7 +965,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_sub_epi64() { + const unsafe fn test_mm512_maskz_sub_epi64() { let a = _mm512_setr_epi64(0, 1, -1, i64::MAX, i64::MIN, 100, -100, -32); let b = _mm512_set1_epi64(1); let r = _mm512_maskz_sub_epi64(0, a, b); @@ -971,7 +976,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_sub_epi64() { + const unsafe fn test_mm256_mask_sub_epi64() { let a = _mm256_set_epi64x(1, -1, i64::MAX, i64::MIN); let b = _mm256_set1_epi64x(1); let r = _mm256_mask_sub_epi64(a, 0, a, b); @@ -982,7 +987,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_sub_epi64() { + const unsafe fn test_mm256_maskz_sub_epi64() { let a = _mm256_set_epi64x(1, -1, i64::MAX, i64::MIN); let b = _mm256_set1_epi64x(1); let r = _mm256_maskz_sub_epi64(0, a, b); @@ -993,7 +998,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_sub_epi64() { + const unsafe fn test_mm_mask_sub_epi64() { let a = _mm_set_epi64x(i64::MAX, i64::MIN); let b = _mm_set1_epi64x(1); let r = _mm_mask_sub_epi64(a, 0, a, b); @@ -1004,7 +1009,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_sub_epi64() { + const unsafe fn test_mm_maskz_sub_epi64() { let a = _mm_set_epi64x(i64::MAX, i64::MIN); let b = _mm_set1_epi64x(1); let r = _mm_maskz_sub_epi64(0, a, b); @@ -1015,7 +1020,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_sub_pd() { + const unsafe fn test_mm512_sub_pd() { let a = _mm512_setr_pd(0., 1., -1., f64::MAX, f64::MIN, 100., -100., -32.); let b = _mm512_set1_pd(1.); let r = _mm512_sub_pd(a, b); @@ -1024,7 +1029,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_sub_pd() { + const unsafe fn test_mm512_mask_sub_pd() { let a = _mm512_setr_pd(0., 1., -1., f64::MAX, f64::MIN, 100., -100., -32.); let b = _mm512_set1_pd(1.); let r = _mm512_mask_sub_pd(a, 0, a, b); @@ -1035,7 +1040,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_sub_pd() { + const unsafe fn test_mm512_maskz_sub_pd() { let a = _mm512_setr_pd(0., 1., -1., f64::MAX, f64::MIN, 100., -100., -32.); let b = _mm512_set1_pd(1.); let r = _mm512_maskz_sub_pd(0, a, b); @@ -1046,7 +1051,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_sub_pd() { + const unsafe fn test_mm256_mask_sub_pd() { let a = _mm256_set_pd(1., -1., f64::MAX, f64::MIN); let b = _mm256_set1_pd(1.); let r = _mm256_mask_sub_pd(a, 0, a, b); @@ -1057,7 +1062,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_sub_pd() { + const unsafe fn test_mm256_maskz_sub_pd() { let a = _mm256_set_pd(1., -1., f64::MAX, f64::MIN); let b = _mm256_set1_pd(1.); let r = _mm256_maskz_sub_pd(0, a, b); @@ -1068,7 +1073,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_sub_pd() { + const unsafe fn test_mm_mask_sub_pd() { let a = _mm_set_pd(f64::MAX, f64::MIN); let b = _mm_set1_pd(1.); let r = _mm_mask_sub_pd(a, 0, a, b); @@ -1079,7 +1084,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_sub_pd() { + const unsafe fn test_mm_maskz_sub_pd() { let a = _mm_set_pd(f64::MAX, f64::MIN); let b = _mm_set1_pd(1.); let r = _mm_maskz_sub_pd(0, a, b); @@ -1090,7 +1095,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mul_epi32() { + const unsafe fn test_mm512_mul_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_mul_epi32(a, b); @@ -1099,7 +1104,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mul_epi32() { + const unsafe fn test_mm512_mask_mul_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_mask_mul_epi32(a, 0, a, b); @@ -1114,7 +1119,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_mul_epi32() { + const unsafe fn test_mm512_maskz_mul_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_maskz_mul_epi32(0, a, b); @@ -1125,7 +1130,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_mul_epi32() { + const unsafe fn test_mm256_mask_mul_epi32() { let a = _mm256_set1_epi32(1); let b = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_mask_mul_epi32(a, 0, a, b); @@ -1136,7 +1141,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_mul_epi32() { + const unsafe fn test_mm256_maskz_mul_epi32() { let a = _mm256_set1_epi32(1); let b = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_maskz_mul_epi32(0, a, b); @@ -1147,7 +1152,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_mul_epi32() { + const unsafe fn test_mm_mask_mul_epi32() { let a = _mm_set1_epi32(1); let b = _mm_set_epi32(1, 2, 3, 4); let r = _mm_mask_mul_epi32(a, 0, a, b); @@ -1158,7 +1163,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_mul_epi32() { + const unsafe fn test_mm_maskz_mul_epi32() { let a = _mm_set1_epi32(1); let b = _mm_set_epi32(1, 2, 3, 4); let r = _mm_maskz_mul_epi32(0, a, b); @@ -1169,7 +1174,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mul_epu32() { + const unsafe fn test_mm512_mul_epu32() { let a = _mm512_set1_epi32(1); let b = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_mul_epu32(a, b); @@ -1178,7 +1183,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mul_epu32() { + const unsafe fn test_mm512_mask_mul_epu32() { let a = _mm512_set1_epi32(1); let b = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_mask_mul_epu32(a, 0, a, b); @@ -1193,7 +1198,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_mul_epu32() { + const unsafe fn test_mm512_maskz_mul_epu32() { let a = _mm512_set1_epi32(1); let b = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_maskz_mul_epu32(0, a, b); @@ -1204,7 +1209,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_mul_epu32() { + const unsafe fn test_mm256_mask_mul_epu32() { let a = _mm256_set1_epi32(1); let b = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_mask_mul_epu32(a, 0, a, b); @@ -1215,7 +1220,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_mul_epu32() { + const unsafe fn test_mm256_maskz_mul_epu32() { let a = _mm256_set1_epi32(1); let b = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm256_maskz_mul_epu32(0, a, b); @@ -1226,7 +1231,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_mul_epu32() { + const unsafe fn test_mm_mask_mul_epu32() { let a = _mm_set1_epi32(1); let b = _mm_set_epi32(1, 2, 3, 4); let r = _mm_mask_mul_epu32(a, 0, a, b); @@ -1237,7 +1242,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_mul_epu32() { + const unsafe fn test_mm_maskz_mul_epu32() { let a = _mm_set1_epi32(1); let b = _mm_set_epi32(1, 2, 3, 4); let r = _mm_maskz_mul_epu32(0, a, b); @@ -1248,7 +1253,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mullox_epi64() { + const unsafe fn test_mm512_mullox_epi64() { let a = _mm512_setr_epi64(0, 1, i64::MAX, i64::MIN, i64::MAX, 100, -100, -32); let b = _mm512_set1_epi64(2); let r = _mm512_mullox_epi64(a, b); @@ -1257,7 +1262,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mullox_epi64() { + const unsafe fn test_mm512_mask_mullox_epi64() { let a = _mm512_setr_epi64(0, 1, i64::MAX, i64::MIN, i64::MAX, 100, -100, -32); let b = _mm512_set1_epi64(2); let r = _mm512_mask_mullox_epi64(a, 0, a, b); @@ -1268,7 +1273,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mul_pd() { + const unsafe fn test_mm512_mul_pd() { let a = _mm512_setr_pd(0., 1., f64::MAX, f64::MIN, f64::MAX, f64::MIN, -100., -32.); let b = _mm512_set1_pd(2.); let r = _mm512_mul_pd(a, b); @@ -1281,7 +1286,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_mul_pd() { + const unsafe fn test_mm512_mask_mul_pd() { let a = _mm512_setr_pd(0., 1., f64::MAX, f64::MIN, f64::MAX, f64::MIN, -100., -32.); let b = _mm512_set1_pd(2.); let r = _mm512_mask_mul_pd(a, 0, a, b); @@ -1296,7 +1301,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_mul_pd() { + const unsafe fn test_mm512_maskz_mul_pd() { let a = _mm512_setr_pd(0., 1., f64::MAX, f64::MIN, f64::MAX, f64::MIN, -100., -32.); let b = _mm512_set1_pd(2.); let r = _mm512_maskz_mul_pd(0, a, b); @@ -1307,7 +1312,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_mul_pd() { + const unsafe fn test_mm256_mask_mul_pd() { let a = _mm256_set_pd(0., 1., f64::MAX, f64::MIN); let b = _mm256_set1_pd(2.); let r = _mm256_mask_mul_pd(a, 0, a, b); @@ -1318,7 +1323,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_mul_pd() { + const unsafe fn test_mm256_maskz_mul_pd() { let a = _mm256_set_pd(0., 1., f64::MAX, f64::MIN); let b = _mm256_set1_pd(2.); let r = _mm256_maskz_mul_pd(0, a, b); @@ -1329,7 +1334,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_mul_pd() { + const unsafe fn test_mm_mask_mul_pd() { let a = _mm_set_pd(f64::MAX, f64::MIN); let b = _mm_set1_pd(2.); let r = _mm_mask_mul_pd(a, 0, a, b); @@ -1340,7 +1345,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_mul_pd() { + const unsafe fn test_mm_maskz_mul_pd() { let a = _mm_set_pd(f64::MAX, f64::MIN); let b = _mm_set1_pd(2.); let r = _mm_maskz_mul_pd(0, a, b); @@ -1351,7 +1356,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_div_pd() { + const unsafe fn test_mm512_div_pd() { let a = _mm512_setr_pd(0., 1., f64::MAX, f64::MIN, f64::MAX, f64::MIN, -100., -32.); let b = _mm512_setr_pd(2., 2., 0., 0., 0., 0., 2., 2.); let r = _mm512_div_pd(a, b); @@ -1364,7 +1369,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_div_pd() { + const unsafe fn test_mm512_mask_div_pd() { let a = _mm512_setr_pd(0., 1., f64::MAX, f64::MIN, f64::MAX, f64::MIN, -100., -32.); let b = _mm512_setr_pd(2., 2., 0., 0., 0., 0., 2., 2.); let r = _mm512_mask_div_pd(a, 0, a, b); @@ -1379,7 +1384,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_div_pd() { + const unsafe fn test_mm512_maskz_div_pd() { let a = _mm512_setr_pd(0., 1., f64::MAX, f64::MIN, f64::MAX, f64::MIN, -100., -32.); let b = _mm512_setr_pd(2., 2., 0., 0., 0., 0., 2., 2.); let r = _mm512_maskz_div_pd(0, a, b); @@ -1390,7 +1395,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_div_pd() { + const unsafe fn test_mm256_mask_div_pd() { let a = _mm256_set_pd(0., 1., f64::MAX, f64::MIN); let b = _mm256_set_pd(2., 2., 0., 0.); let r = _mm256_mask_div_pd(a, 0, a, b); @@ -1401,7 +1406,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_div_pd() { + const unsafe fn test_mm256_maskz_div_pd() { let a = _mm256_set_pd(0., 1., f64::MAX, f64::MIN); let b = _mm256_set_pd(2., 2., 0., 0.); let r = _mm256_maskz_div_pd(0, a, b); @@ -1412,7 +1417,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_div_pd() { + const unsafe fn test_mm_mask_div_pd() { let a = _mm_set_pd(f64::MAX, f64::MIN); let b = _mm_set_pd(0., 0.); let r = _mm_mask_div_pd(a, 0, a, b); @@ -1423,7 +1428,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_div_pd() { + const unsafe fn test_mm_maskz_div_pd() { let a = _mm_set_pd(f64::MAX, f64::MIN); let b = _mm_set_pd(0., 0.); let r = _mm_maskz_div_pd(0, a, b); @@ -1434,7 +1439,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_max_epi64() { + const unsafe fn test_mm512_max_epi64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_max_epi64(a, b); @@ -1443,7 +1448,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_max_epi64() { + const unsafe fn test_mm512_mask_max_epi64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_mask_max_epi64(a, 0, a, b); @@ -1454,7 +1459,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_max_epi64() { + const unsafe fn test_mm512_maskz_max_epi64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_maskz_max_epi64(0, a, b); @@ -1465,7 +1470,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_max_epi64() { + const unsafe fn test_mm256_max_epi64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_max_epi64(a, b); @@ -1474,7 +1479,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_max_epi64() { + const unsafe fn test_mm256_mask_max_epi64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_mask_max_epi64(a, 0, a, b); @@ -1485,7 +1490,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_max_epi64() { + const unsafe fn test_mm256_maskz_max_epi64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_maskz_max_epi64(0, a, b); @@ -1496,7 +1501,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_max_epi64() { + const unsafe fn test_mm_max_epi64() { let a = _mm_set_epi64x(2, 3); let b = _mm_set_epi64x(3, 2); let r = _mm_max_epi64(a, b); @@ -1505,7 +1510,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_max_epi64() { + const unsafe fn test_mm_mask_max_epi64() { let a = _mm_set_epi64x(2, 3); let b = _mm_set_epi64x(3, 2); let r = _mm_mask_max_epi64(a, 0, a, b); @@ -1516,7 +1521,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_max_epi64() { + const unsafe fn test_mm_maskz_max_epi64() { let a = _mm_set_epi64x(2, 3); let b = _mm_set_epi64x(3, 2); let r = _mm_maskz_max_epi64(0, a, b); @@ -1602,7 +1607,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_max_epu64() { + const unsafe fn test_mm512_max_epu64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_max_epu64(a, b); @@ -1611,7 +1616,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_max_epu64() { + const unsafe fn test_mm512_mask_max_epu64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_mask_max_epu64(a, 0, a, b); @@ -1622,7 +1627,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_max_epu64() { + const unsafe fn test_mm512_maskz_max_epu64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_maskz_max_epu64(0, a, b); @@ -1633,7 +1638,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_max_epu64() { + const unsafe fn test_mm256_max_epu64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_max_epu64(a, b); @@ -1642,7 +1647,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_max_epu64() { + const unsafe fn test_mm256_mask_max_epu64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_mask_max_epu64(a, 0, a, b); @@ -1653,7 +1658,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_max_epu64() { + const unsafe fn test_mm256_maskz_max_epu64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_maskz_max_epu64(0, a, b); @@ -1664,7 +1669,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_max_epu64() { + const unsafe fn test_mm_max_epu64() { let a = _mm_set_epi64x(2, 3); let b = _mm_set_epi64x(3, 2); let r = _mm_max_epu64(a, b); @@ -1673,7 +1678,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_max_epu64() { + const unsafe fn test_mm_mask_max_epu64() { let a = _mm_set_epi64x(2, 3); let b = _mm_set_epi64x(3, 2); let r = _mm_mask_max_epu64(a, 0, a, b); @@ -1684,7 +1689,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_max_epu64() { + const unsafe fn test_mm_maskz_max_epu64() { let a = _mm_set_epi64x(2, 3); let b = _mm_set_epi64x(3, 2); let r = _mm_maskz_max_epu64(0, a, b); @@ -1695,7 +1700,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_min_epi64() { + const unsafe fn test_mm512_min_epi64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_min_epi64(a, b); @@ -1704,7 +1709,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_min_epi64() { + const unsafe fn test_mm512_mask_min_epi64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_mask_min_epi64(a, 0, a, b); @@ -1715,7 +1720,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_min_epi64() { + const unsafe fn test_mm512_maskz_min_epi64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_maskz_min_epi64(0, a, b); @@ -1726,7 +1731,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_min_epi64() { + const unsafe fn test_mm256_min_epi64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_min_epi64(a, b); @@ -1735,7 +1740,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_min_epi64() { + const unsafe fn test_mm256_mask_min_epi64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_mask_min_epi64(a, 0, a, b); @@ -1746,7 +1751,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_min_epi64() { + const unsafe fn test_mm256_maskz_min_epi64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_maskz_min_epi64(0, a, b); @@ -1757,7 +1762,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_min_epi64() { + const unsafe fn test_mm_min_epi64() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(3, 2); let r = _mm_min_epi64(a, b); @@ -1771,7 +1776,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_min_epi64() { + const unsafe fn test_mm_mask_min_epi64() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(3, 2); let r = _mm_mask_min_epi64(a, 0, a, b); @@ -1782,7 +1787,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_min_epi64() { + const unsafe fn test_mm_maskz_min_epi64() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(3, 2); let r = _mm_maskz_min_epi64(0, a, b); @@ -1868,7 +1873,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_min_epu64() { + const unsafe fn test_mm512_min_epu64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_min_epu64(a, b); @@ -1877,7 +1882,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_min_epu64() { + const unsafe fn test_mm512_mask_min_epu64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_mask_min_epu64(a, 0, a, b); @@ -1888,7 +1893,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_min_epu64() { + const unsafe fn test_mm512_maskz_min_epu64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm512_maskz_min_epu64(0, a, b); @@ -1899,7 +1904,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_min_epu64() { + const unsafe fn test_mm256_min_epu64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_min_epu64(a, b); @@ -1908,7 +1913,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_min_epu64() { + const unsafe fn test_mm256_mask_min_epu64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_mask_min_epu64(a, 0, a, b); @@ -1919,7 +1924,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_min_epu64() { + const unsafe fn test_mm256_maskz_min_epu64() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_maskz_min_epu64(0, a, b); @@ -1930,7 +1935,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_min_epu64() { + const unsafe fn test_mm_min_epu64() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(1, 0); let r = _mm_min_epu64(a, b); @@ -1939,7 +1944,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_min_epu64() { + const unsafe fn test_mm_mask_min_epu64() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(1, 0); let r = _mm_mask_min_epu64(a, 0, a, b); @@ -1950,7 +1955,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_min_epu64() { + const unsafe fn test_mm_maskz_min_epu64() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(1, 0); let r = _mm_maskz_min_epu64(0, a, b); @@ -2029,7 +2034,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fmadd_pd() { + const unsafe fn test_mm512_fmadd_pd() { let a = _mm512_setr_pd(1., 1., 1., 1., 1., 1., 1., 1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_setr_pd(1., 1., 1., 1., 1., 1., 1., 1.); @@ -2039,7 +2044,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fmadd_pd() { + const unsafe fn test_mm512_mask_fmadd_pd() { let a = _mm512_setr_pd(1., 1., 1., 1., 1., 1., 1., 1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_setr_pd(1., 1., 1., 1., 1., 1., 1., 1.); @@ -2051,7 +2056,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fmadd_pd() { + const unsafe fn test_mm512_maskz_fmadd_pd() { let a = _mm512_setr_pd(1., 1., 1., 1., 1., 1., 1., 1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_setr_pd(1., 1., 1., 1., 1., 1., 1., 1.); @@ -2063,7 +2068,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fmadd_pd() { + const unsafe fn test_mm512_mask3_fmadd_pd() { let a = _mm512_setr_pd(1., 1., 1., 1., 1., 1., 1., 1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_setr_pd(1., 1., 1., 1., 2., 2., 2., 2.); @@ -2075,7 +2080,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fmadd_pd() { + const unsafe fn test_mm256_mask_fmadd_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2087,7 +2092,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fmadd_pd() { + const unsafe fn test_mm256_maskz_fmadd_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2099,7 +2104,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fmadd_pd() { + const unsafe fn test_mm256_mask3_fmadd_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2111,7 +2116,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fmadd_pd() { + const unsafe fn test_mm_mask_fmadd_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2123,7 +2128,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fmadd_pd() { + const unsafe fn test_mm_maskz_fmadd_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2135,7 +2140,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fmadd_pd() { + const unsafe fn test_mm_mask3_fmadd_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2147,7 +2152,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fmsub_pd() { + const unsafe fn test_mm512_fmsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2157,7 +2162,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fmsub_pd() { + const unsafe fn test_mm512_mask_fmsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2169,7 +2174,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fmsub_pd() { + const unsafe fn test_mm512_maskz_fmsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2181,7 +2186,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fmsub_pd() { + const unsafe fn test_mm512_mask3_fmsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_setr_pd(1., 1., 1., 1., 2., 2., 2., 2.); @@ -2193,7 +2198,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fmsub_pd() { + const unsafe fn test_mm256_mask_fmsub_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2205,7 +2210,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fmsub_pd() { + const unsafe fn test_mm256_maskz_fmsub_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2217,7 +2222,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fmsub_pd() { + const unsafe fn test_mm256_mask3_fmsub_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2229,7 +2234,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fmsub_pd() { + const unsafe fn test_mm_mask_fmsub_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2241,7 +2246,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fmsub_pd() { + const unsafe fn test_mm_maskz_fmsub_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2253,7 +2258,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fmsub_pd() { + const unsafe fn test_mm_mask3_fmsub_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2265,7 +2270,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fmaddsub_pd() { + const unsafe fn test_mm512_fmaddsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2275,7 +2280,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fmaddsub_pd() { + const unsafe fn test_mm512_mask_fmaddsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2287,7 +2292,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fmaddsub_pd() { + const unsafe fn test_mm512_maskz_fmaddsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2299,7 +2304,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fmaddsub_pd() { + const unsafe fn test_mm512_mask3_fmaddsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_setr_pd(1., 1., 1., 1., 2., 2., 2., 2.); @@ -2311,7 +2316,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fmaddsub_pd() { + const unsafe fn test_mm256_mask_fmaddsub_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2323,7 +2328,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fmaddsub_pd() { + const unsafe fn test_mm256_maskz_fmaddsub_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2335,7 +2340,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fmaddsub_pd() { + const unsafe fn test_mm256_mask3_fmaddsub_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2347,7 +2352,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fmaddsub_pd() { + const unsafe fn test_mm_mask_fmaddsub_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2359,7 +2364,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fmaddsub_pd() { + const unsafe fn test_mm_maskz_fmaddsub_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2371,7 +2376,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fmaddsub_pd() { + const unsafe fn test_mm_mask3_fmaddsub_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2383,7 +2388,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fmsubadd_pd() { + const unsafe fn test_mm512_fmsubadd_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2393,7 +2398,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fmsubadd_pd() { + const unsafe fn test_mm512_mask_fmsubadd_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2405,7 +2410,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fmsubadd_pd() { + const unsafe fn test_mm512_maskz_fmsubadd_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2417,7 +2422,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fmsubadd_pd() { + const unsafe fn test_mm512_mask3_fmsubadd_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_setr_pd(1., 1., 1., 1., 2., 2., 2., 2.); @@ -2429,7 +2434,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fmsubadd_pd() { + const unsafe fn test_mm256_mask_fmsubadd_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2441,7 +2446,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fmsubadd_pd() { + const unsafe fn test_mm256_maskz_fmsubadd_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2453,7 +2458,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fmsubadd_pd() { + const unsafe fn test_mm256_mask3_fmsubadd_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2465,7 +2470,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fmsubadd_pd() { + const unsafe fn test_mm_mask_fmsubadd_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2477,7 +2482,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fmsubadd_pd() { + const unsafe fn test_mm_maskz_fmsubadd_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2489,7 +2494,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fmsubadd_pd() { + const unsafe fn test_mm_mask3_fmsubadd_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2501,7 +2506,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fnmadd_pd() { + const unsafe fn test_mm512_fnmadd_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2511,7 +2516,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fnmadd_pd() { + const unsafe fn test_mm512_mask_fnmadd_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2523,7 +2528,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fnmadd_pd() { + const unsafe fn test_mm512_maskz_fnmadd_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2535,7 +2540,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fnmadd_pd() { + const unsafe fn test_mm512_mask3_fnmadd_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_setr_pd(1., 1., 1., 1., 2., 2., 2., 2.); @@ -2547,7 +2552,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fnmadd_pd() { + const unsafe fn test_mm256_mask_fnmadd_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2559,7 +2564,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fnmadd_pd() { + const unsafe fn test_mm256_maskz_fnmadd_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2571,7 +2576,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fnmadd_pd() { + const unsafe fn test_mm256_mask3_fnmadd_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2583,7 +2588,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fnmadd_pd() { + const unsafe fn test_mm_mask_fnmadd_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2595,7 +2600,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fnmadd_pd() { + const unsafe fn test_mm_maskz_fnmadd_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2607,7 +2612,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fnmadd_pd() { + const unsafe fn test_mm_mask3_fnmadd_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2619,7 +2624,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_fnmsub_pd() { + const unsafe fn test_mm512_fnmsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2629,7 +2634,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_fnmsub_pd() { + const unsafe fn test_mm512_mask_fnmsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2641,7 +2646,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_fnmsub_pd() { + const unsafe fn test_mm512_maskz_fnmsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_set1_pd(1.); @@ -2653,7 +2658,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask3_fnmsub_pd() { + const unsafe fn test_mm512_mask3_fnmsub_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let c = _mm512_setr_pd(1., 1., 1., 1., 2., 2., 2., 2.); @@ -2665,7 +2670,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_fnmsub_pd() { + const unsafe fn test_mm256_mask_fnmsub_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2677,7 +2682,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_fnmsub_pd() { + const unsafe fn test_mm256_maskz_fnmsub_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2689,7 +2694,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask3_fnmsub_pd() { + const unsafe fn test_mm256_mask3_fnmsub_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set_pd(0., 1., 2., 3.); let c = _mm256_set1_pd(1.); @@ -2701,7 +2706,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_fnmsub_pd() { + const unsafe fn test_mm_mask_fnmsub_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2713,7 +2718,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_fnmsub_pd() { + const unsafe fn test_mm_maskz_fnmsub_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -2725,7 +2730,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask3_fnmsub_pd() { + const unsafe fn test_mm_mask3_fnmsub_pd() { let a = _mm_set1_pd(1.); let b = _mm_set_pd(0., 1.); let c = _mm_set1_pd(1.); @@ -3764,7 +3769,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi8_epi64() { + const unsafe fn test_mm512_cvtepi8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi8_epi64(a); let e = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); @@ -3772,7 +3777,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi8_epi64() { + const unsafe fn test_mm512_mask_cvtepi8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi64(-1); let r = _mm512_mask_cvtepi8_epi64(src, 0, a); @@ -3783,7 +3788,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi8_epi64() { + const unsafe fn test_mm512_maskz_cvtepi8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi8_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -3793,7 +3798,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi8_epi64() { + const unsafe fn test_mm256_mask_cvtepi8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm256_set1_epi64x(-1); let r = _mm256_mask_cvtepi8_epi64(src, 0, a); @@ -3804,7 +3809,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi8_epi64() { + const unsafe fn test_mm256_maskz_cvtepi8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_maskz_cvtepi8_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -3814,7 +3819,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi8_epi64() { + const unsafe fn test_mm_mask_cvtepi8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm_set1_epi64x(-1); let r = _mm_mask_cvtepi8_epi64(src, 0, a); @@ -3825,7 +3830,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepi8_epi64() { + const unsafe fn test_mm_maskz_cvtepi8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_maskz_cvtepi8_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -3835,7 +3840,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepu8_epi64() { + const unsafe fn test_mm512_cvtepu8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepu8_epi64(a); let e = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); @@ -3843,7 +3848,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepu8_epi64() { + const unsafe fn test_mm512_mask_cvtepu8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi64(-1); let r = _mm512_mask_cvtepu8_epi64(src, 0, a); @@ -3854,7 +3859,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepu8_epi64() { + const unsafe fn test_mm512_maskz_cvtepu8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepu8_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -3864,7 +3869,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepu8_epi64() { + const unsafe fn test_mm256_mask_cvtepu8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm256_set1_epi64x(-1); let r = _mm256_mask_cvtepu8_epi64(src, 0, a); @@ -3875,7 +3880,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepu8_epi64() { + const unsafe fn test_mm256_maskz_cvtepu8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_maskz_cvtepu8_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -3885,7 +3890,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepu8_epi64() { + const unsafe fn test_mm_mask_cvtepu8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm_set1_epi64x(-1); let r = _mm_mask_cvtepu8_epi64(src, 0, a); @@ -3896,7 +3901,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepu8_epi64() { + const unsafe fn test_mm_maskz_cvtepu8_epi64() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_maskz_cvtepu8_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -3906,7 +3911,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi16_epi64() { + const unsafe fn test_mm512_cvtepi16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi16_epi64(a); let e = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); @@ -3914,7 +3919,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi16_epi64() { + const unsafe fn test_mm512_mask_cvtepi16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi64(-1); let r = _mm512_mask_cvtepi16_epi64(src, 0, a); @@ -3925,7 +3930,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi16_epi64() { + const unsafe fn test_mm512_maskz_cvtepi16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi16_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -3935,7 +3940,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi16_epi64() { + const unsafe fn test_mm256_mask_cvtepi16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm256_set1_epi64x(-1); let r = _mm256_mask_cvtepi16_epi64(src, 0, a); @@ -3946,7 +3951,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi16_epi64() { + const unsafe fn test_mm256_maskz_cvtepi16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_maskz_cvtepi16_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -3956,7 +3961,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi16_epi64() { + const unsafe fn test_mm_mask_cvtepi16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm_set1_epi64x(-1); let r = _mm_mask_cvtepi16_epi64(src, 0, a); @@ -3967,7 +3972,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepi16_epi64() { + const unsafe fn test_mm_maskz_cvtepi16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_maskz_cvtepi16_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -3977,7 +3982,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepu16_epi64() { + const unsafe fn test_mm512_cvtepu16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepu16_epi64(a); let e = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); @@ -3985,7 +3990,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepu16_epi64() { + const unsafe fn test_mm512_mask_cvtepu16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi64(-1); let r = _mm512_mask_cvtepu16_epi64(src, 0, a); @@ -3996,7 +4001,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepu16_epi64() { + const unsafe fn test_mm512_maskz_cvtepu16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepu16_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -4006,7 +4011,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepu16_epi64() { + const unsafe fn test_mm256_mask_cvtepu16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm256_set1_epi64x(-1); let r = _mm256_mask_cvtepu16_epi64(src, 0, a); @@ -4017,7 +4022,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepu16_epi64() { + const unsafe fn test_mm256_maskz_cvtepu16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_maskz_cvtepu16_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -4027,7 +4032,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepu16_epi64() { + const unsafe fn test_mm_mask_cvtepu16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm_set1_epi64x(-1); let r = _mm_mask_cvtepu16_epi64(src, 0, a); @@ -4038,7 +4043,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepu16_epi64() { + const unsafe fn test_mm_maskz_cvtepu16_epi64() { let a = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm_maskz_cvtepu16_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -4048,7 +4053,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi32_epi64() { + const unsafe fn test_mm512_cvtepi32_epi64() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi32_epi64(a); let e = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); @@ -4056,7 +4061,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi32_epi64() { + const unsafe fn test_mm512_mask_cvtepi32_epi64() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi64(-1); let r = _mm512_mask_cvtepi32_epi64(src, 0, a); @@ -4067,7 +4072,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi32_epi64() { + const unsafe fn test_mm512_maskz_cvtepi32_epi64() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi32_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -4077,7 +4082,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi32_epi64() { + const unsafe fn test_mm256_mask_cvtepi32_epi64() { let a = _mm_set_epi32(8, 9, 10, 11); let src = _mm256_set1_epi64x(-1); let r = _mm256_mask_cvtepi32_epi64(src, 0, a); @@ -4088,7 +4093,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi32_epi64() { + const unsafe fn test_mm256_maskz_cvtepi32_epi64() { let a = _mm_set_epi32(8, 9, 10, 11); let r = _mm256_maskz_cvtepi32_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -4098,7 +4103,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi32_epi64() { + const unsafe fn test_mm_mask_cvtepi32_epi64() { let a = _mm_set_epi32(8, 9, 10, 11); let src = _mm_set1_epi64x(0); let r = _mm_mask_cvtepi32_epi64(src, 0, a); @@ -4109,7 +4114,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepi32_epi64() { + const unsafe fn test_mm_maskz_cvtepi32_epi64() { let a = _mm_set_epi32(8, 9, 10, 11); let r = _mm_maskz_cvtepi32_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -4119,7 +4124,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepu32_epi64() { + const unsafe fn test_mm512_cvtepu32_epi64() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepu32_epi64(a); let e = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); @@ -4127,7 +4132,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepu32_epi64() { + const unsafe fn test_mm512_mask_cvtepu32_epi64() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_epi64(-1); let r = _mm512_mask_cvtepu32_epi64(src, 0, a); @@ -4138,7 +4143,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepu32_epi64() { + const unsafe fn test_mm512_maskz_cvtepu32_epi64() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepu32_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -4148,7 +4153,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepu32_epi64() { + const unsafe fn test_mm256_mask_cvtepu32_epi64() { let a = _mm_set_epi32(12, 13, 14, 15); let src = _mm256_set1_epi64x(-1); let r = _mm256_mask_cvtepu32_epi64(src, 0, a); @@ -4159,7 +4164,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepu32_epi64() { + const unsafe fn test_mm256_maskz_cvtepu32_epi64() { let a = _mm_set_epi32(12, 13, 14, 15); let r = _mm256_maskz_cvtepu32_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -4169,7 +4174,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepu32_epi64() { + const unsafe fn test_mm_mask_cvtepu32_epi64() { let a = _mm_set_epi32(12, 13, 14, 15); let src = _mm_set1_epi64x(-1); let r = _mm_mask_cvtepu32_epi64(src, 0, a); @@ -4180,7 +4185,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepu32_epi64() { + const unsafe fn test_mm_maskz_cvtepu32_epi64() { let a = _mm_set_epi32(12, 13, 14, 15); let r = _mm_maskz_cvtepu32_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -4190,7 +4195,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi32_pd() { + const unsafe fn test_mm512_cvtepi32_pd() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi32_pd(a); let e = _mm512_set_pd(8., 9., 10., 11., 12., 13., 14., 15.); @@ -4198,7 +4203,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi32_pd() { + const unsafe fn test_mm512_mask_cvtepi32_pd() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_pd(-1.); let r = _mm512_mask_cvtepi32_pd(src, 0, a); @@ -4209,7 +4214,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi32_pd() { + const unsafe fn test_mm512_maskz_cvtepi32_pd() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi32_pd(0, a); assert_eq_m512d(r, _mm512_setzero_pd()); @@ -4219,7 +4224,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi32_pd() { + const unsafe fn test_mm256_mask_cvtepi32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let src = _mm256_set1_pd(-1.); let r = _mm256_mask_cvtepi32_pd(src, 0, a); @@ -4230,7 +4235,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi32_pd() { + const unsafe fn test_mm256_maskz_cvtepi32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let r = _mm256_maskz_cvtepi32_pd(0, a); assert_eq_m256d(r, _mm256_setzero_pd()); @@ -4240,7 +4245,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi32_pd() { + const unsafe fn test_mm_mask_cvtepi32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let src = _mm_set1_pd(-1.); let r = _mm_mask_cvtepi32_pd(src, 0, a); @@ -4251,7 +4256,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepi32_pd() { + const unsafe fn test_mm_maskz_cvtepi32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let r = _mm_maskz_cvtepi32_pd(0, a); assert_eq_m128d(r, _mm_setzero_pd()); @@ -4261,7 +4266,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepu32_pd() { + const unsafe fn test_mm512_cvtepu32_pd() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepu32_pd(a); let e = _mm512_set_pd(8., 9., 10., 11., 12., 13., 14., 15.); @@ -4269,7 +4274,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepu32_pd() { + const unsafe fn test_mm512_mask_cvtepu32_pd() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_pd(-1.); let r = _mm512_mask_cvtepu32_pd(src, 0, a); @@ -4280,7 +4285,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepu32_pd() { + const unsafe fn test_mm512_maskz_cvtepu32_pd() { let a = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepu32_pd(0, a); assert_eq_m512d(r, _mm512_setzero_pd()); @@ -4290,7 +4295,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cvtepu32_pd() { + const unsafe fn test_mm256_cvtepu32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let r = _mm256_cvtepu32_pd(a); let e = _mm256_set_pd(12., 13., 14., 15.); @@ -4298,7 +4303,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepu32_pd() { + const unsafe fn test_mm256_mask_cvtepu32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let src = _mm256_set1_pd(-1.); let r = _mm256_mask_cvtepu32_pd(src, 0, a); @@ -4309,7 +4314,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepu32_pd() { + const unsafe fn test_mm256_maskz_cvtepu32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let r = _mm256_maskz_cvtepu32_pd(0, a); assert_eq_m256d(r, _mm256_setzero_pd()); @@ -4319,7 +4324,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cvtepu32_pd() { + const unsafe fn test_mm_cvtepu32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let r = _mm_cvtepu32_pd(a); let e = _mm_set_pd(14., 15.); @@ -4327,7 +4332,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepu32_pd() { + const unsafe fn test_mm_mask_cvtepu32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let src = _mm_set1_pd(-1.); let r = _mm_mask_cvtepu32_pd(src, 0, a); @@ -4338,7 +4343,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_cvtepu32_pd() { + const unsafe fn test_mm_maskz_cvtepu32_pd() { let a = _mm_set_epi32(12, 13, 14, 15); let r = _mm_maskz_cvtepu32_pd(0, a); assert_eq_m128d(r, _mm_setzero_pd()); @@ -4348,7 +4353,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi32lo_pd() { + const unsafe fn test_mm512_cvtepi32lo_pd() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi32lo_pd(a); let e = _mm512_set_pd(8., 9., 10., 11., 12., 13., 14., 15.); @@ -4356,7 +4361,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi32lo_pd() { + const unsafe fn test_mm512_mask_cvtepi32lo_pd() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_pd(-1.); let r = _mm512_mask_cvtepi32lo_pd(src, 0, a); @@ -4367,7 +4372,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepu32lo_pd() { + const unsafe fn test_mm512_cvtepu32lo_pd() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepu32lo_pd(a); let e = _mm512_set_pd(8., 9., 10., 11., 12., 13., 14., 15.); @@ -4375,7 +4380,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepu32lo_pd() { + const unsafe fn test_mm512_mask_cvtepu32lo_pd() { let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let src = _mm512_set1_pd(-1.); let r = _mm512_mask_cvtepu32lo_pd(src, 0, a); @@ -4386,7 +4391,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi64_epi32() { + const unsafe fn test_mm512_cvtepi64_epi32() { let a = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi64_epi32(a); let e = _mm256_set_epi32(8, 9, 10, 11, 12, 13, 14, 15); @@ -4394,7 +4399,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi64_epi32() { + const unsafe fn test_mm512_mask_cvtepi64_epi32() { let a = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm256_set1_epi32(-1); let r = _mm512_mask_cvtepi64_epi32(src, 0, a); @@ -4405,7 +4410,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi64_epi32() { + const unsafe fn test_mm512_maskz_cvtepi64_epi32() { let a = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi64_epi32(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -4415,7 +4420,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cvtepi64_epi32() { + const unsafe fn test_mm256_cvtepi64_epi32() { let a = _mm256_set_epi64x(1, 2, 3, 4); let r = _mm256_cvtepi64_epi32(a); let e = _mm_set_epi32(1, 2, 3, 4); @@ -4423,7 +4428,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi64_epi32() { + const unsafe fn test_mm256_mask_cvtepi64_epi32() { let a = _mm256_set_epi64x(1, 2, 3, 4); let src = _mm_set1_epi32(0); let r = _mm256_mask_cvtepi64_epi32(src, 0, a); @@ -4434,7 +4439,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi64_epi32() { + const unsafe fn test_mm256_maskz_cvtepi64_epi32() { let a = _mm256_set_epi64x(1, 2, 3, 4); let r = _mm256_maskz_cvtepi64_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -4473,7 +4478,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cvtepi64_epi16() { + const unsafe fn test_mm512_cvtepi64_epi16() { let a = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_cvtepi64_epi16(a); let e = _mm_set_epi16(8, 9, 10, 11, 12, 13, 14, 15); @@ -4481,7 +4486,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi64_epi16() { + const unsafe fn test_mm512_mask_cvtepi64_epi16() { let a = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); let src = _mm_set1_epi16(-1); let r = _mm512_mask_cvtepi64_epi16(src, 0, a); @@ -4492,7 +4497,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_cvtepi64_epi16() { + const unsafe fn test_mm512_maskz_cvtepi64_epi16() { let a = _mm512_set_epi64(8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_maskz_cvtepi64_epi16(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -6449,42 +6454,42 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setzero_pd() { + const unsafe fn test_mm512_setzero_pd() { assert_eq_m512d(_mm512_setzero_pd(), _mm512_set1_pd(0.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set1_epi64() { + const unsafe fn test_mm512_set1_epi64() { let r = _mm512_set_epi64(2, 2, 2, 2, 2, 2, 2, 2); assert_eq_m512i(r, _mm512_set1_epi64(2)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set1_pd() { + const unsafe fn test_mm512_set1_pd() { let expected = _mm512_set_pd(2., 2., 2., 2., 2., 2., 2., 2.); assert_eq_m512d(expected, _mm512_set1_pd(2.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set4_epi64() { + const unsafe fn test_mm512_set4_epi64() { let r = _mm512_set_epi64(4, 3, 2, 1, 4, 3, 2, 1); assert_eq_m512i(r, _mm512_set4_epi64(4, 3, 2, 1)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set4_pd() { + const unsafe fn test_mm512_set4_pd() { let r = _mm512_set_pd(4., 3., 2., 1., 4., 3., 2., 1.); assert_eq_m512d(r, _mm512_set4_pd(4., 3., 2., 1.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setr4_epi64() { + const unsafe fn test_mm512_setr4_epi64() { let r = _mm512_set_epi64(4, 3, 2, 1, 4, 3, 2, 1); assert_eq_m512i(r, _mm512_setr4_epi64(1, 2, 3, 4)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setr4_pd() { + const unsafe fn test_mm512_setr4_pd() { let r = _mm512_set_pd(4., 3., 2., 1., 4., 3., 2., 1.); assert_eq_m512d(r, _mm512_setr4_pd(1., 2., 3., 4.)); } @@ -6709,7 +6714,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmplt_epu64_mask() { + const unsafe fn test_mm512_cmplt_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let m = _mm512_cmplt_epu64_mask(a, b); @@ -6717,7 +6722,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmplt_epu64_mask() { + const unsafe fn test_mm512_mask_cmplt_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b01111010; @@ -6726,7 +6731,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmplt_epu64_mask() { + const unsafe fn test_mm256_cmplt_epu64_mask() { let a = _mm256_set_epi64x(0, 1, 2, 100); let b = _mm256_set1_epi64x(2); let r = _mm256_cmplt_epu64_mask(a, b); @@ -6734,7 +6739,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmplt_epu64_mask() { + const unsafe fn test_mm256_mask_cmplt_epu64_mask() { let a = _mm256_set_epi64x(0, 1, 2, 100); let b = _mm256_set1_epi64x(2); let mask = 0b11111111; @@ -6743,7 +6748,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmplt_epu64_mask() { + const unsafe fn test_mm_cmplt_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(2); let r = _mm_cmplt_epu64_mask(a, b); @@ -6751,7 +6756,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmplt_epu64_mask() { + const unsafe fn test_mm_mask_cmplt_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(2); let mask = 0b11111111; @@ -6760,7 +6765,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpgt_epu64_mask() { + const unsafe fn test_mm512_cmpgt_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let m = _mm512_cmpgt_epu64_mask(b, a); @@ -6768,7 +6773,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpgt_epu64_mask() { + const unsafe fn test_mm512_mask_cmpgt_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b01111010; @@ -6777,7 +6782,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpgt_epu64_mask() { + const unsafe fn test_mm256_cmpgt_epu64_mask() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set1_epi64x(1); let r = _mm256_cmpgt_epu64_mask(a, b); @@ -6785,7 +6790,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpgt_epu64_mask() { + const unsafe fn test_mm256_mask_cmpgt_epu64_mask() { let a = _mm256_set_epi64x(0, 1, 2, 3); let b = _mm256_set1_epi64x(1); let mask = 0b11111111; @@ -6794,7 +6799,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpgt_epu64_mask() { + const unsafe fn test_mm_cmpgt_epu64_mask() { let a = _mm_set_epi64x(1, 2); let b = _mm_set1_epi64x(1); let r = _mm_cmpgt_epu64_mask(a, b); @@ -6802,7 +6807,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpgt_epu64_mask() { + const unsafe fn test_mm_mask_cmpgt_epu64_mask() { let a = _mm_set_epi64x(1, 2); let b = _mm_set1_epi64x(1); let mask = 0b11111111; @@ -6811,7 +6816,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmple_epu64_mask() { + const unsafe fn test_mm512_cmple_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); assert_eq!( @@ -6821,7 +6826,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmple_epu64_mask() { + const unsafe fn test_mm512_mask_cmple_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b01111010; @@ -6829,7 +6834,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmple_epu64_mask() { + const unsafe fn test_mm256_cmple_epu64_mask() { let a = _mm256_set_epi64x(0, 1, 2, 1); let b = _mm256_set1_epi64x(1); let r = _mm256_cmple_epu64_mask(a, b); @@ -6837,7 +6842,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmple_epu64_mask() { + const unsafe fn test_mm256_mask_cmple_epu64_mask() { let a = _mm256_set_epi64x(0, 1, 2, 1); let b = _mm256_set1_epi64x(1); let mask = 0b11111111; @@ -6846,7 +6851,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmple_epu64_mask() { + const unsafe fn test_mm_cmple_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let r = _mm_cmple_epu64_mask(a, b); @@ -6854,7 +6859,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmple_epu64_mask() { + const unsafe fn test_mm_mask_cmple_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let mask = 0b11111111; @@ -6863,7 +6868,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpge_epu64_mask() { + const unsafe fn test_mm512_cmpge_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); assert_eq!( @@ -6873,7 +6878,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpge_epu64_mask() { + const unsafe fn test_mm512_mask_cmpge_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b11111111; @@ -6882,7 +6887,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpge_epu64_mask() { + const unsafe fn test_mm256_cmpge_epu64_mask() { let a = _mm256_set_epi64x(0, 1, 2, u64::MAX as i64); let b = _mm256_set1_epi64x(1); let r = _mm256_cmpge_epu64_mask(a, b); @@ -6890,7 +6895,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpge_epu64_mask() { + const unsafe fn test_mm256_mask_cmpge_epu64_mask() { let a = _mm256_set_epi64x(0, 1, 2, u64::MAX as i64); let b = _mm256_set1_epi64x(1); let mask = 0b11111111; @@ -6899,7 +6904,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpge_epu64_mask() { + const unsafe fn test_mm_cmpge_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let r = _mm_cmpge_epu64_mask(a, b); @@ -6907,7 +6912,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpge_epu64_mask() { + const unsafe fn test_mm_mask_cmpge_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let mask = 0b11111111; @@ -6916,7 +6921,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpeq_epu64_mask() { + const unsafe fn test_mm512_cmpeq_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set_epi64(0, 1, 13, 42, i64::MAX, i64::MIN, 100, -100); let m = _mm512_cmpeq_epu64_mask(b, a); @@ -6924,7 +6929,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpeq_epu64_mask() { + const unsafe fn test_mm512_mask_cmpeq_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set_epi64(0, 1, 13, 42, i64::MAX, i64::MIN, 100, -100); let mask = 0b01111010; @@ -6933,7 +6938,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpeq_epu64_mask() { + const unsafe fn test_mm256_cmpeq_epu64_mask() { let a = _mm256_set_epi64x(0, 1, -1, u64::MAX as i64); let b = _mm256_set_epi64x(0, 1, 13, 42); let m = _mm256_cmpeq_epu64_mask(b, a); @@ -6941,7 +6946,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpeq_epu64_mask() { + const unsafe fn test_mm256_mask_cmpeq_epu64_mask() { let a = _mm256_set_epi64x(0, 1, -1, u64::MAX as i64); let b = _mm256_set_epi64x(0, 1, 13, 42); let mask = 0b11111111; @@ -6950,7 +6955,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpeq_epu64_mask() { + const unsafe fn test_mm_cmpeq_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(0, 1); let m = _mm_cmpeq_epu64_mask(b, a); @@ -6958,7 +6963,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpeq_epu64_mask() { + const unsafe fn test_mm_mask_cmpeq_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(0, 1); let mask = 0b11111111; @@ -6967,7 +6972,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpneq_epu64_mask() { + const unsafe fn test_mm512_cmpneq_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set_epi64(0, 1, 13, 42, i64::MAX, i64::MIN, 100, -100); let m = _mm512_cmpneq_epu64_mask(b, a); @@ -6975,7 +6980,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpneq_epu64_mask() { + const unsafe fn test_mm512_mask_cmpneq_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, -100, 100); let b = _mm512_set_epi64(0, 1, 13, 42, i64::MAX, i64::MIN, 100, -100); let mask = 0b01111010; @@ -6984,7 +6989,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpneq_epu64_mask() { + const unsafe fn test_mm256_cmpneq_epu64_mask() { let a = _mm256_set_epi64x(0, 1, -1, u64::MAX as i64); let b = _mm256_set_epi64x(0, 1, 13, 42); let r = _mm256_cmpneq_epu64_mask(b, a); @@ -6992,7 +6997,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpneq_epu64_mask() { + const unsafe fn test_mm256_mask_cmpneq_epu64_mask() { let a = _mm256_set_epi64x(0, 1, -1, u64::MAX as i64); let b = _mm256_set_epi64x(0, 1, 13, 42); let mask = 0b11111111; @@ -7001,7 +7006,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpneq_epu64_mask() { + const unsafe fn test_mm_cmpneq_epu64_mask() { let a = _mm_set_epi64x(-1, u64::MAX as i64); let b = _mm_set_epi64x(13, 42); let r = _mm_cmpneq_epu64_mask(b, a); @@ -7009,7 +7014,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpneq_epu64_mask() { + const unsafe fn test_mm_mask_cmpneq_epu64_mask() { let a = _mm_set_epi64x(-1, u64::MAX as i64); let b = _mm_set_epi64x(13, 42); let mask = 0b11111111; @@ -7018,7 +7023,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmp_epu64_mask() { + const unsafe fn test_mm512_cmp_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let m = _mm512_cmp_epu64_mask::<_MM_CMPINT_LT>(a, b); @@ -7026,7 +7031,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmp_epu64_mask() { + const unsafe fn test_mm512_mask_cmp_epu64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b01111010; @@ -7035,7 +7040,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmp_epu64_mask() { + const unsafe fn test_mm256_cmp_epu64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 100); let b = _mm256_set1_epi64x(1); let m = _mm256_cmp_epu64_mask::<_MM_CMPINT_LT>(a, b); @@ -7043,7 +7048,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmp_epu64_mask() { + const unsafe fn test_mm256_mask_cmp_epu64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 100); let b = _mm256_set1_epi64x(1); let mask = 0b11111111; @@ -7052,7 +7057,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmp_epu64_mask() { + const unsafe fn test_mm_cmp_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let m = _mm_cmp_epu64_mask::<_MM_CMPINT_LT>(a, b); @@ -7060,7 +7065,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmp_epu64_mask() { + const unsafe fn test_mm_mask_cmp_epu64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let mask = 0b11111111; @@ -7069,7 +7074,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmplt_epi64_mask() { + const unsafe fn test_mm512_cmplt_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let m = _mm512_cmplt_epi64_mask(a, b); @@ -7077,7 +7082,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmplt_epi64_mask() { + const unsafe fn test_mm512_mask_cmplt_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b01100110; @@ -7086,7 +7091,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmplt_epi64_mask() { + const unsafe fn test_mm256_cmplt_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, -13); let b = _mm256_set1_epi64x(-1); let r = _mm256_cmplt_epi64_mask(a, b); @@ -7094,7 +7099,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmplt_epi64_mask() { + const unsafe fn test_mm256_mask_cmplt_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, -13); let b = _mm256_set1_epi64x(-1); let mask = 0b11111111; @@ -7103,7 +7108,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmplt_epi64_mask() { + const unsafe fn test_mm_cmplt_epi64_mask() { let a = _mm_set_epi64x(-1, -13); let b = _mm_set1_epi64x(-1); let r = _mm_cmplt_epi64_mask(a, b); @@ -7111,7 +7116,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmplt_epi64_mask() { + const unsafe fn test_mm_mask_cmplt_epi64_mask() { let a = _mm_set_epi64x(-1, -13); let b = _mm_set1_epi64x(-1); let mask = 0b11111111; @@ -7120,7 +7125,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpgt_epi64_mask() { + const unsafe fn test_mm512_cmpgt_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let m = _mm512_cmpgt_epi64_mask(b, a); @@ -7128,7 +7133,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpgt_epi64_mask() { + const unsafe fn test_mm512_mask_cmpgt_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b01100110; @@ -7137,7 +7142,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpgt_epi64_mask() { + const unsafe fn test_mm256_cmpgt_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 13); let b = _mm256_set1_epi64x(-1); let r = _mm256_cmpgt_epi64_mask(a, b); @@ -7145,7 +7150,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpgt_epi64_mask() { + const unsafe fn test_mm256_mask_cmpgt_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 13); let b = _mm256_set1_epi64x(-1); let mask = 0b11111111; @@ -7154,7 +7159,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpgt_epi64_mask() { + const unsafe fn test_mm_cmpgt_epi64_mask() { let a = _mm_set_epi64x(0, -1); let b = _mm_set1_epi64x(-1); let r = _mm_cmpgt_epi64_mask(a, b); @@ -7162,7 +7167,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpgt_epi64_mask() { + const unsafe fn test_mm_mask_cmpgt_epi64_mask() { let a = _mm_set_epi64x(0, -1); let b = _mm_set1_epi64x(-1); let mask = 0b11111111; @@ -7171,7 +7176,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmple_epi64_mask() { + const unsafe fn test_mm512_cmple_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); assert_eq!( @@ -7181,7 +7186,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmple_epi64_mask() { + const unsafe fn test_mm512_mask_cmple_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b01111010; @@ -7189,7 +7194,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmple_epi64_mask() { + const unsafe fn test_mm256_cmple_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, i64::MAX); let b = _mm256_set1_epi64x(-1); let r = _mm256_cmple_epi64_mask(a, b); @@ -7197,7 +7202,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmple_epi64_mask() { + const unsafe fn test_mm256_mask_cmple_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, i64::MAX); let b = _mm256_set1_epi64x(-1); let mask = 0b11111111; @@ -7206,7 +7211,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmple_epi64_mask() { + const unsafe fn test_mm_cmple_epi64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let r = _mm_cmple_epi64_mask(a, b); @@ -7214,7 +7219,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmple_epi64_mask() { + const unsafe fn test_mm_mask_cmple_epi64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let mask = 0b11111111; @@ -7223,7 +7228,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpge_epi64_mask() { + const unsafe fn test_mm512_cmpge_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); assert_eq!( @@ -7233,7 +7238,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpge_epi64_mask() { + const unsafe fn test_mm512_mask_cmpge_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, u64::MAX as i64, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b11111111; @@ -7242,7 +7247,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpge_epi64_mask() { + const unsafe fn test_mm256_cmpge_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, i64::MAX); let b = _mm256_set1_epi64x(-1); let r = _mm256_cmpge_epi64_mask(a, b); @@ -7250,7 +7255,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpge_epi64_mask() { + const unsafe fn test_mm256_mask_cmpge_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, i64::MAX); let b = _mm256_set1_epi64x(-1); let mask = 0b11111111; @@ -7259,7 +7264,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpge_epi64_mask() { + const unsafe fn test_mm_cmpge_epi64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(-1); let r = _mm_cmpge_epi64_mask(a, b); @@ -7267,7 +7272,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpge_epi64_mask() { + const unsafe fn test_mm_mask_cmpge_epi64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(-1); let mask = 0b11111111; @@ -7276,7 +7281,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpeq_epi64_mask() { + const unsafe fn test_mm512_cmpeq_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set_epi64(0, 1, 13, 42, i64::MAX, i64::MIN, 100, -100); let m = _mm512_cmpeq_epi64_mask(b, a); @@ -7284,7 +7289,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpeq_epi64_mask() { + const unsafe fn test_mm512_mask_cmpeq_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set_epi64(0, 1, 13, 42, i64::MAX, i64::MIN, 100, -100); let mask = 0b01111010; @@ -7293,7 +7298,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpeq_epi64_mask() { + const unsafe fn test_mm256_cmpeq_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 13); let b = _mm256_set_epi64x(0, 1, 13, 42); let m = _mm256_cmpeq_epi64_mask(b, a); @@ -7301,7 +7306,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpeq_epi64_mask() { + const unsafe fn test_mm256_mask_cmpeq_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 13); let b = _mm256_set_epi64x(0, 1, 13, 42); let mask = 0b11111111; @@ -7310,7 +7315,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpeq_epi64_mask() { + const unsafe fn test_mm_cmpeq_epi64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(0, 1); let m = _mm_cmpeq_epi64_mask(b, a); @@ -7318,7 +7323,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpeq_epi64_mask() { + const unsafe fn test_mm_mask_cmpeq_epi64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set_epi64x(0, 1); let mask = 0b11111111; @@ -7327,19 +7332,19 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_set_epi64() { + const unsafe fn test_mm512_set_epi64() { let r = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); assert_eq_m512i(r, _mm512_set_epi64(7, 6, 5, 4, 3, 2, 1, 0)) } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_setr_epi64() { + const unsafe fn test_mm512_setr_epi64() { let r = _mm512_set_epi64(0, 1, 2, 3, 4, 5, 6, 7); assert_eq_m512i(r, _mm512_setr_epi64(7, 6, 5, 4, 3, 2, 1, 0)) } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmpneq_epi64_mask() { + const unsafe fn test_mm512_cmpneq_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set_epi64(0, 1, 13, 42, i64::MAX, i64::MIN, 100, -100); let m = _mm512_cmpneq_epi64_mask(b, a); @@ -7347,7 +7352,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmpneq_epi64_mask() { + const unsafe fn test_mm512_mask_cmpneq_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, -100, 100); let b = _mm512_set_epi64(0, 1, 13, 42, i64::MAX, i64::MIN, 100, -100); let mask = 0b01111010; @@ -7356,7 +7361,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmpneq_epi64_mask() { + const unsafe fn test_mm256_cmpneq_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 13); let b = _mm256_set_epi64x(0, 1, 13, 42); let r = _mm256_cmpneq_epi64_mask(b, a); @@ -7364,7 +7369,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmpneq_epi64_mask() { + const unsafe fn test_mm256_mask_cmpneq_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 13); let b = _mm256_set_epi64x(0, 1, 13, 42); let mask = 0b11111111; @@ -7373,7 +7378,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmpneq_epi64_mask() { + const unsafe fn test_mm_cmpneq_epi64_mask() { let a = _mm_set_epi64x(-1, 13); let b = _mm_set_epi64x(13, 42); let r = _mm_cmpneq_epi64_mask(b, a); @@ -7381,7 +7386,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmpneq_epi64_mask() { + const unsafe fn test_mm_mask_cmpneq_epi64_mask() { let a = _mm_set_epi64x(-1, 13); let b = _mm_set_epi64x(13, 42); let mask = 0b11111111; @@ -7390,7 +7395,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_cmp_epi64_mask() { + const unsafe fn test_mm512_cmp_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let m = _mm512_cmp_epi64_mask::<_MM_CMPINT_LT>(a, b); @@ -7398,7 +7403,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cmp_epi64_mask() { + const unsafe fn test_mm512_mask_cmp_epi64_mask() { let a = _mm512_set_epi64(0, 1, -1, 13, i64::MAX, i64::MIN, 100, -100); let b = _mm512_set1_epi64(-1); let mask = 0b01100110; @@ -7407,7 +7412,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_cmp_epi64_mask() { + const unsafe fn test_mm256_cmp_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 13); let b = _mm256_set1_epi64x(1); let m = _mm256_cmp_epi64_mask::<_MM_CMPINT_LT>(a, b); @@ -7415,7 +7420,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cmp_epi64_mask() { + const unsafe fn test_mm256_mask_cmp_epi64_mask() { let a = _mm256_set_epi64x(0, 1, -1, 13); let b = _mm256_set1_epi64x(1); let mask = 0b11111111; @@ -7424,7 +7429,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_cmp_epi64_mask() { + const unsafe fn test_mm_cmp_epi64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let m = _mm_cmp_epi64_mask::<_MM_CMPINT_LT>(a, b); @@ -7432,7 +7437,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cmp_epi64_mask() { + const unsafe fn test_mm_mask_cmp_epi64_mask() { let a = _mm_set_epi64x(0, 1); let b = _mm_set1_epi64x(1); let mask = 0b11111111; @@ -8313,7 +8318,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_rol_epi64() { + const unsafe fn test_mm512_rol_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 63, 1 << 32, 1 << 32, 1 << 32, @@ -8329,7 +8334,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_rol_epi64() { + const unsafe fn test_mm512_mask_rol_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 63, 1 << 32, 1 << 32, 1 << 32, @@ -8347,7 +8352,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_rol_epi64() { + const unsafe fn test_mm512_maskz_rol_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 32, 1 << 32, 1 << 32, @@ -8361,7 +8366,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_rol_epi64() { + const unsafe fn test_mm256_rol_epi64() { let a = _mm256_set_epi64x(1 << 63, 1 << 32, 1 << 32, 1 << 32); let r = _mm256_rol_epi64::<1>(a); let e = _mm256_set_epi64x(1 << 0, 1 << 33, 1 << 33, 1 << 33); @@ -8369,7 +8374,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_rol_epi64() { + const unsafe fn test_mm256_mask_rol_epi64() { let a = _mm256_set_epi64x(1 << 63, 1 << 32, 1 << 32, 1 << 32); let r = _mm256_mask_rol_epi64::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -8379,7 +8384,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_rol_epi64() { + const unsafe fn test_mm256_maskz_rol_epi64() { let a = _mm256_set_epi64x(1 << 63, 1 << 32, 1 << 32, 1 << 32); let r = _mm256_maskz_rol_epi64::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -8389,7 +8394,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_rol_epi64() { + const unsafe fn test_mm_rol_epi64() { let a = _mm_set_epi64x(1 << 63, 1 << 32); let r = _mm_rol_epi64::<1>(a); let e = _mm_set_epi64x(1 << 0, 1 << 33); @@ -8397,7 +8402,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_rol_epi64() { + const unsafe fn test_mm_mask_rol_epi64() { let a = _mm_set_epi64x(1 << 63, 1 << 32); let r = _mm_mask_rol_epi64::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -8407,7 +8412,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_rol_epi64() { + const unsafe fn test_mm_maskz_rol_epi64() { let a = _mm_set_epi64x(1 << 63, 1 << 32); let r = _mm_maskz_rol_epi64::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -8417,7 +8422,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_ror_epi64() { + const unsafe fn test_mm512_ror_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 0, 1 << 32, 1 << 32, 1 << 32, @@ -8433,7 +8438,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_ror_epi64() { + const unsafe fn test_mm512_mask_ror_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 0, 1 << 32, 1 << 32, 1 << 32, @@ -8451,7 +8456,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_ror_epi64() { + const unsafe fn test_mm512_maskz_ror_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 32, 1 << 32, 1 << 32, @@ -8465,7 +8470,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_ror_epi64() { + const unsafe fn test_mm256_ror_epi64() { let a = _mm256_set_epi64x(1 << 0, 1 << 32, 1 << 32, 1 << 32); let r = _mm256_ror_epi64::<1>(a); let e = _mm256_set_epi64x(1 << 63, 1 << 31, 1 << 31, 1 << 31); @@ -8473,7 +8478,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_ror_epi64() { + const unsafe fn test_mm256_mask_ror_epi64() { let a = _mm256_set_epi64x(1 << 0, 1 << 32, 1 << 32, 1 << 32); let r = _mm256_mask_ror_epi64::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -8483,7 +8488,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_ror_epi64() { + const unsafe fn test_mm256_maskz_ror_epi64() { let a = _mm256_set_epi64x(1 << 0, 1 << 32, 1 << 32, 1 << 32); let r = _mm256_maskz_ror_epi64::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -8493,7 +8498,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_ror_epi64() { + const unsafe fn test_mm_ror_epi64() { let a = _mm_set_epi64x(1 << 0, 1 << 32); let r = _mm_ror_epi64::<1>(a); let e = _mm_set_epi64x(1 << 63, 1 << 31); @@ -8501,7 +8506,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_ror_epi64() { + const unsafe fn test_mm_mask_ror_epi64() { let a = _mm_set_epi64x(1 << 0, 1 << 32); let r = _mm_mask_ror_epi64::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -8511,7 +8516,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_ror_epi64() { + const unsafe fn test_mm_maskz_ror_epi64() { let a = _mm_set_epi64x(1 << 0, 1 << 32); let r = _mm_maskz_ror_epi64::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -8521,7 +8526,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_slli_epi64() { + const unsafe fn test_mm512_slli_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 63, 1 << 32, 1 << 32, 1 << 32, @@ -8537,7 +8542,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_slli_epi64() { + const unsafe fn test_mm512_mask_slli_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 63, 1 << 32, 1 << 32, 1 << 32, @@ -8555,7 +8560,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_slli_epi64() { + const unsafe fn test_mm512_maskz_slli_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 32, 1 << 32, 1 << 32, @@ -8569,7 +8574,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_slli_epi64() { + const unsafe fn test_mm256_mask_slli_epi64() { let a = _mm256_set_epi64x(1 << 63, 1 << 32, 1 << 32, 1 << 32); let r = _mm256_mask_slli_epi64::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -8579,7 +8584,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_slli_epi64() { + const unsafe fn test_mm256_maskz_slli_epi64() { let a = _mm256_set_epi64x(1 << 63, 1 << 32, 1 << 32, 1 << 32); let r = _mm256_maskz_slli_epi64::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -8589,7 +8594,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_slli_epi64() { + const unsafe fn test_mm_mask_slli_epi64() { let a = _mm_set_epi64x(1 << 63, 1 << 32); let r = _mm_mask_slli_epi64::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -8599,7 +8604,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_slli_epi64() { + const unsafe fn test_mm_maskz_slli_epi64() { let a = _mm_set_epi64x(1 << 63, 1 << 32); let r = _mm_maskz_slli_epi64::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -8609,7 +8614,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_srli_epi64() { + const unsafe fn test_mm512_srli_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 0, 1 << 32, 1 << 32, 1 << 32, @@ -8625,7 +8630,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_srli_epi64() { + const unsafe fn test_mm512_mask_srli_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 0, 1 << 32, 1 << 32, 1 << 32, @@ -8643,7 +8648,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_srli_epi64() { + const unsafe fn test_mm512_maskz_srli_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 32, 1 << 32, 1 << 32, @@ -8657,7 +8662,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_srli_epi64() { + const unsafe fn test_mm256_mask_srli_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let r = _mm256_mask_srli_epi64::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -8667,7 +8672,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_srli_epi64() { + const unsafe fn test_mm256_maskz_srli_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let r = _mm256_maskz_srli_epi64::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -8677,7 +8682,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_srli_epi64() { + const unsafe fn test_mm_mask_srli_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let r = _mm_mask_srli_epi64::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -8687,7 +8692,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_srli_epi64() { + const unsafe fn test_mm_maskz_srli_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let r = _mm_maskz_srli_epi64::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -8697,7 +8702,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_rolv_epi64() { + const unsafe fn test_mm512_rolv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 63, 1 << 32, 1 << 32, @@ -8714,7 +8719,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_rolv_epi64() { + const unsafe fn test_mm512_mask_rolv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 63, 1 << 32, 1 << 32, @@ -8733,7 +8738,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_rolv_epi64() { + const unsafe fn test_mm512_maskz_rolv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 32, 1 << 32, 1 << 32, @@ -8748,7 +8753,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_rolv_epi64() { + const unsafe fn test_mm256_rolv_epi64() { let a = _mm256_set_epi64x(1 << 32, 1 << 63, 1 << 32, 1 << 32); let b = _mm256_set_epi64x(0, 1, 2, 3); let r = _mm256_rolv_epi64(a, b); @@ -8757,7 +8762,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_rolv_epi64() { + const unsafe fn test_mm256_mask_rolv_epi64() { let a = _mm256_set_epi64x(1 << 32, 1 << 63, 1 << 32, 1 << 32); let b = _mm256_set_epi64x(0, 1, 2, 3); let r = _mm256_mask_rolv_epi64(a, 0, a, b); @@ -8768,7 +8773,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_rolv_epi64() { + const unsafe fn test_mm256_maskz_rolv_epi64() { let a = _mm256_set_epi64x(1 << 32, 1 << 63, 1 << 32, 1 << 32); let b = _mm256_set_epi64x(0, 1, 2, 3); let r = _mm256_maskz_rolv_epi64(0, a, b); @@ -8779,7 +8784,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_rolv_epi64() { + const unsafe fn test_mm_rolv_epi64() { let a = _mm_set_epi64x(1 << 32, 1 << 63); let b = _mm_set_epi64x(0, 1); let r = _mm_rolv_epi64(a, b); @@ -8788,7 +8793,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_rolv_epi64() { + const unsafe fn test_mm_mask_rolv_epi64() { let a = _mm_set_epi64x(1 << 32, 1 << 63); let b = _mm_set_epi64x(0, 1); let r = _mm_mask_rolv_epi64(a, 0, a, b); @@ -8799,7 +8804,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_rolv_epi64() { + const unsafe fn test_mm_maskz_rolv_epi64() { let a = _mm_set_epi64x(1 << 32, 1 << 63); let b = _mm_set_epi64x(0, 1); let r = _mm_maskz_rolv_epi64(0, a, b); @@ -8810,7 +8815,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_rorv_epi64() { + const unsafe fn test_mm512_rorv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 0, 1 << 32, 1 << 32, @@ -8827,7 +8832,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_rorv_epi64() { + const unsafe fn test_mm512_mask_rorv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 0, 1 << 32, 1 << 32, @@ -8846,7 +8851,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_rorv_epi64() { + const unsafe fn test_mm512_maskz_rorv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 32, 1 << 32, 1 << 32, @@ -8861,7 +8866,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_rorv_epi64() { + const unsafe fn test_mm256_rorv_epi64() { let a = _mm256_set_epi64x(1 << 32, 1 << 0, 1 << 32, 1 << 32); let b = _mm256_set_epi64x(0, 1, 2, 3); let r = _mm256_rorv_epi64(a, b); @@ -8870,7 +8875,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_rorv_epi64() { + const unsafe fn test_mm256_mask_rorv_epi64() { let a = _mm256_set_epi64x(1 << 32, 1 << 0, 1 << 32, 1 << 32); let b = _mm256_set_epi64x(0, 1, 2, 3); let r = _mm256_mask_rorv_epi64(a, 0, a, b); @@ -8881,7 +8886,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_rorv_epi64() { + const unsafe fn test_mm256_maskz_rorv_epi64() { let a = _mm256_set_epi64x(1 << 32, 1 << 0, 1 << 32, 1 << 32); let b = _mm256_set_epi64x(0, 1, 2, 3); let r = _mm256_maskz_rorv_epi64(0, a, b); @@ -8892,7 +8897,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_rorv_epi64() { + const unsafe fn test_mm_rorv_epi64() { let a = _mm_set_epi64x(1 << 32, 1 << 0); let b = _mm_set_epi64x(0, 1); let r = _mm_rorv_epi64(a, b); @@ -8901,7 +8906,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_rorv_epi64() { + const unsafe fn test_mm_mask_rorv_epi64() { let a = _mm_set_epi64x(1 << 32, 1 << 0); let b = _mm_set_epi64x(0, 1); let r = _mm_mask_rorv_epi64(a, 0, a, b); @@ -8912,7 +8917,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_rorv_epi64() { + const unsafe fn test_mm_maskz_rorv_epi64() { let a = _mm_set_epi64x(1 << 32, 1 << 0); let b = _mm_set_epi64x(0, 1); let r = _mm_maskz_rorv_epi64(0, a, b); @@ -8923,7 +8928,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_sllv_epi64() { + const unsafe fn test_mm512_sllv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 63, 1 << 32, 1 << 32, @@ -8940,7 +8945,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_sllv_epi64() { + const unsafe fn test_mm512_mask_sllv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 32, 1 << 63, 1 << 32, @@ -8959,7 +8964,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_sllv_epi64() { + const unsafe fn test_mm512_maskz_sllv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 32, 1 << 32, 1 << 32, @@ -8974,7 +8979,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_sllv_epi64() { + const unsafe fn test_mm256_mask_sllv_epi64() { let a = _mm256_set_epi64x(1 << 32, 1 << 32, 1 << 63, 1 << 32); let count = _mm256_set_epi64x(0, 1, 2, 3); let r = _mm256_mask_sllv_epi64(a, 0, a, count); @@ -8985,7 +8990,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_sllv_epi64() { + const unsafe fn test_mm256_maskz_sllv_epi64() { let a = _mm256_set_epi64x(1 << 32, 1 << 32, 1 << 63, 1 << 32); let count = _mm256_set_epi64x(0, 1, 2, 3); let r = _mm256_maskz_sllv_epi64(0, a, count); @@ -8996,7 +9001,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_sllv_epi64() { + const unsafe fn test_mm_mask_sllv_epi64() { let a = _mm_set_epi64x(1 << 63, 1 << 32); let count = _mm_set_epi64x(2, 3); let r = _mm_mask_sllv_epi64(a, 0, a, count); @@ -9007,7 +9012,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_sllv_epi64() { + const unsafe fn test_mm_maskz_sllv_epi64() { let a = _mm_set_epi64x(1 << 63, 1 << 32); let count = _mm_set_epi64x(2, 3); let r = _mm_maskz_sllv_epi64(0, a, count); @@ -9018,7 +9023,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_srlv_epi64() { + const unsafe fn test_mm512_srlv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 0, 1 << 32, 1 << 32, @@ -9035,7 +9040,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_srlv_epi64() { + const unsafe fn test_mm512_mask_srlv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 0, 1 << 32, 1 << 32, @@ -9054,7 +9059,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_srlv_epi64() { + const unsafe fn test_mm512_maskz_srlv_epi64() { #[rustfmt::skip] let a = _mm512_set_epi64( 1 << 32, 1 << 32, 1 << 32, 1 << 32, @@ -9069,7 +9074,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_srlv_epi64() { + const unsafe fn test_mm256_mask_srlv_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let count = _mm256_set1_epi64x(1); let r = _mm256_mask_srlv_epi64(a, 0, a, count); @@ -9080,7 +9085,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_srlv_epi64() { + const unsafe fn test_mm256_maskz_srlv_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let count = _mm256_set1_epi64x(1); let r = _mm256_maskz_srlv_epi64(0, a, count); @@ -9091,7 +9096,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_srlv_epi64() { + const unsafe fn test_mm_mask_srlv_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let count = _mm_set1_epi64x(1); let r = _mm_mask_srlv_epi64(a, 0, a, count); @@ -9102,7 +9107,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_srlv_epi64() { + const unsafe fn test_mm_maskz_srlv_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let count = _mm_set1_epi64x(1); let r = _mm_maskz_srlv_epi64(0, a, count); @@ -9399,7 +9404,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_srav_epi64() { + const unsafe fn test_mm512_srav_epi64() { let a = _mm512_set_epi64(1, -8, 0, 0, 0, 0, 15, -16); let count = _mm512_set_epi64(2, 2, 0, 0, 0, 0, 2, 1); let r = _mm512_srav_epi64(a, count); @@ -9408,7 +9413,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_srav_epi64() { + const unsafe fn test_mm512_mask_srav_epi64() { let a = _mm512_set_epi64(1, -8, 0, 0, 0, 0, 15, -16); let count = _mm512_set_epi64(2, 2, 0, 0, 0, 0, 2, 1); let r = _mm512_mask_srav_epi64(a, 0, a, count); @@ -9419,7 +9424,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_srav_epi64() { + const unsafe fn test_mm512_maskz_srav_epi64() { let a = _mm512_set_epi64(1, -8, 0, 0, 0, 0, 15, -16); let count = _mm512_set_epi64(2, 2, 0, 0, 0, 0, 2, 1); let r = _mm512_maskz_srav_epi64(0, a, count); @@ -9430,7 +9435,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_srav_epi64() { + const unsafe fn test_mm256_srav_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let count = _mm256_set1_epi64x(1); let r = _mm256_srav_epi64(a, count); @@ -9439,7 +9444,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_srav_epi64() { + const unsafe fn test_mm256_mask_srav_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let count = _mm256_set1_epi64x(1); let r = _mm256_mask_srav_epi64(a, 0, a, count); @@ -9450,7 +9455,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_srav_epi64() { + const unsafe fn test_mm256_maskz_srav_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let count = _mm256_set1_epi64x(1); let r = _mm256_maskz_srav_epi64(0, a, count); @@ -9461,7 +9466,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_srav_epi64() { + const unsafe fn test_mm_srav_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let count = _mm_set1_epi64x(1); let r = _mm_srav_epi64(a, count); @@ -9470,7 +9475,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_srav_epi64() { + const unsafe fn test_mm_mask_srav_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let count = _mm_set1_epi64x(1); let r = _mm_mask_srav_epi64(a, 0, a, count); @@ -9481,7 +9486,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_srav_epi64() { + const unsafe fn test_mm_maskz_srav_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let count = _mm_set1_epi64x(1); let r = _mm_maskz_srav_epi64(0, a, count); @@ -9492,7 +9497,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_srai_epi64() { + const unsafe fn test_mm512_srai_epi64() { let a = _mm512_set_epi64(1, -4, 15, 0, 0, 0, 0, -16); let r = _mm512_srai_epi64::<2>(a); let e = _mm512_set_epi64(0, -1, 3, 0, 0, 0, 0, -4); @@ -9500,7 +9505,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_srai_epi64() { + const unsafe fn test_mm512_mask_srai_epi64() { let a = _mm512_set_epi64(1, -4, 15, 0, 0, 0, 0, -16); let r = _mm512_mask_srai_epi64::<2>(a, 0, a); assert_eq_m512i(r, a); @@ -9510,7 +9515,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_srai_epi64() { + const unsafe fn test_mm512_maskz_srai_epi64() { let a = _mm512_set_epi64(1, -4, 15, 0, 0, 0, 0, -16); let r = _mm512_maskz_srai_epi64::<2>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -9520,7 +9525,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_srai_epi64() { + const unsafe fn test_mm256_srai_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let r = _mm256_srai_epi64::<1>(a); let e = _mm256_set_epi64x(1 << 4, 0, 0, 0); @@ -9528,7 +9533,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_srai_epi64() { + const unsafe fn test_mm256_mask_srai_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let r = _mm256_mask_srai_epi64::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -9538,7 +9543,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_srai_epi64() { + const unsafe fn test_mm256_maskz_srai_epi64() { let a = _mm256_set_epi64x(1 << 5, 0, 0, 0); let r = _mm256_maskz_srai_epi64::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -9548,7 +9553,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_srai_epi64() { + const unsafe fn test_mm_srai_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let r = _mm_srai_epi64::<1>(a); let e = _mm_set_epi64x(1 << 4, 0); @@ -9556,7 +9561,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_srai_epi64() { + const unsafe fn test_mm_mask_srai_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let r = _mm_mask_srai_epi64::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -9566,7 +9571,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_srai_epi64() { + const unsafe fn test_mm_maskz_srai_epi64() { let a = _mm_set_epi64x(1 << 5, 0); let r = _mm_maskz_srai_epi64::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -9576,7 +9581,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_permute_pd() { + const unsafe fn test_mm512_permute_pd() { let a = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let r = _mm512_permute_pd::<0b11_11_11_11>(a); let e = _mm512_setr_pd(1., 1., 3., 3., 5., 5., 7., 7.); @@ -9584,7 +9589,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_permute_pd() { + const unsafe fn test_mm512_mask_permute_pd() { let a = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let r = _mm512_mask_permute_pd::<0b11_11_11_11>(a, 0, a); assert_eq_m512d(r, a); @@ -9594,7 +9599,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_permute_pd() { + const unsafe fn test_mm512_maskz_permute_pd() { let a = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let r = _mm512_maskz_permute_pd::<0b11_11_11_11>(0, a); assert_eq_m512d(r, _mm512_setzero_pd()); @@ -9604,7 +9609,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_permute_pd() { + const unsafe fn test_mm256_mask_permute_pd() { let a = _mm256_set_pd(3., 2., 1., 0.); let r = _mm256_mask_permute_pd::<0b11_11>(a, 0, a); assert_eq_m256d(r, a); @@ -9614,7 +9619,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_permute_pd() { + const unsafe fn test_mm256_maskz_permute_pd() { let a = _mm256_set_pd(3., 2., 1., 0.); let r = _mm256_maskz_permute_pd::<0b11_11>(0, a); assert_eq_m256d(r, _mm256_setzero_pd()); @@ -9624,7 +9629,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_permute_pd() { + const unsafe fn test_mm_mask_permute_pd() { let a = _mm_set_pd(1., 0.); let r = _mm_mask_permute_pd::<0b11>(a, 0, a); assert_eq_m128d(r, a); @@ -9634,7 +9639,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_permute_pd() { + const unsafe fn test_mm_maskz_permute_pd() { let a = _mm_set_pd(1., 0.); let r = _mm_maskz_permute_pd::<0b11>(0, a); assert_eq_m128d(r, _mm_setzero_pd()); @@ -9644,7 +9649,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_permutex_epi64() { + const unsafe fn test_mm512_permutex_epi64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm512_permutex_epi64::<0b11_11_11_11>(a); let e = _mm512_setr_epi64(3, 3, 3, 3, 7, 7, 7, 7); @@ -9652,7 +9657,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_permutex_epi64() { + const unsafe fn test_mm512_mask_permutex_epi64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm512_mask_permutex_epi64::<0b11_11_11_11>(a, 0, a); assert_eq_m512i(r, a); @@ -9662,7 +9667,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_permutex_epi64() { + const unsafe fn test_mm512_maskz_permutex_epi64() { let a = _mm512_setr_epi64(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm512_maskz_permutex_epi64::<0b11_11_11_11>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -9672,7 +9677,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_permutex_epi64() { + const unsafe fn test_mm256_permutex_epi64() { let a = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_permutex_epi64::<0b11_11_11_11>(a); let e = _mm256_set_epi64x(3, 3, 3, 3); @@ -9680,7 +9685,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_permutex_epi64() { + const unsafe fn test_mm256_mask_permutex_epi64() { let a = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_mask_permutex_epi64::<0b11_11_11_11>(a, 0, a); assert_eq_m256i(r, a); @@ -9690,7 +9695,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_permutex_epi64() { + const unsafe fn test_mm256_maskz_permutex_epi64() { let a = _mm256_set_epi64x(3, 2, 1, 0); let r = _mm256_maskz_permutex_epi64::<0b11_11_11_11>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -9700,7 +9705,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_permutex_pd() { + const unsafe fn test_mm512_permutex_pd() { let a = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let r = _mm512_permutex_pd::<0b11_11_11_11>(a); let e = _mm512_setr_pd(3., 3., 3., 3., 7., 7., 7., 7.); @@ -9708,7 +9713,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_permutex_pd() { + const unsafe fn test_mm512_mask_permutex_pd() { let a = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let r = _mm512_mask_permutex_pd::<0b11_11_11_11>(a, 0, a); assert_eq_m512d(r, a); @@ -9718,7 +9723,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_permutex_pd() { + const unsafe fn test_mm512_maskz_permutex_pd() { let a = _mm512_setr_pd(0., 1., 2., 3., 4., 5., 6., 7.); let r = _mm512_maskz_permutex_pd::<0b11_11_11_11>(0, a); assert_eq_m512d(r, _mm512_setzero_pd()); @@ -9728,7 +9733,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_permutex_pd() { + const unsafe fn test_mm256_permutex_pd() { let a = _mm256_set_pd(0., 1., 2., 3.); let r = _mm256_permutex_pd::<0b11_11_11_11>(a); let e = _mm256_set_pd(0., 0., 0., 0.); @@ -9736,7 +9741,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_permutex_pd() { + const unsafe fn test_mm256_mask_permutex_pd() { let a = _mm256_set_pd(0., 1., 2., 3.); let r = _mm256_mask_permutex_pd::<0b11_11_11_11>(a, 0, a); assert_eq_m256d(r, a); @@ -9746,7 +9751,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_permutex_pd() { + const unsafe fn test_mm256_maskz_permutex_pd() { let a = _mm256_set_pd(0., 1., 2., 3.); let r = _mm256_maskz_permutex_pd::<0b11_11_11_11>(0, a); assert_eq_m256d(r, _mm256_setzero_pd()); @@ -10231,7 +10236,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_shuffle_pd() { + const unsafe fn test_mm256_mask_shuffle_pd() { let a = _mm256_set_pd(1., 4., 5., 8.); let b = _mm256_set_pd(2., 3., 6., 7.); let r = _mm256_mask_shuffle_pd::<0b11_11_11_11>(a, 0, a, b); @@ -10242,7 +10247,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_shuffle_pd() { + const unsafe fn test_mm256_maskz_shuffle_pd() { let a = _mm256_set_pd(1., 4., 5., 8.); let b = _mm256_set_pd(2., 3., 6., 7.); let r = _mm256_maskz_shuffle_pd::<0b11_11_11_11>(0, a, b); @@ -10253,7 +10258,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_shuffle_pd() { + const unsafe fn test_mm_mask_shuffle_pd() { let a = _mm_set_pd(1., 4.); let b = _mm_set_pd(2., 3.); let r = _mm_mask_shuffle_pd::<0b11_11_11_11>(a, 0, a, b); @@ -10264,7 +10269,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_shuffle_pd() { + const unsafe fn test_mm_maskz_shuffle_pd() { let a = _mm_set_pd(1., 4.); let b = _mm_set_pd(2., 3.); let r = _mm_maskz_shuffle_pd::<0b11_11_11_11>(0, a, b); @@ -10275,7 +10280,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_shuffle_i64x2() { + const unsafe fn test_mm512_shuffle_i64x2() { let a = _mm512_setr_epi64(1, 4, 5, 8, 9, 12, 13, 16); let b = _mm512_setr_epi64(2, 3, 6, 7, 10, 11, 14, 15); let r = _mm512_shuffle_i64x2::<0b00_00_00_00>(a, b); @@ -10284,7 +10289,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_shuffle_i64x2() { + const unsafe fn test_mm512_mask_shuffle_i64x2() { let a = _mm512_setr_epi64(1, 4, 5, 8, 9, 12, 13, 16); let b = _mm512_setr_epi64(2, 3, 6, 7, 10, 11, 14, 15); let r = _mm512_mask_shuffle_i64x2::<0b00_00_00_00>(a, 0, a, b); @@ -10295,7 +10300,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_shuffle_i64x2() { + const unsafe fn test_mm512_maskz_shuffle_i64x2() { let a = _mm512_setr_epi64(1, 4, 5, 8, 9, 12, 13, 16); let b = _mm512_setr_epi64(2, 3, 6, 7, 10, 11, 14, 15); let r = _mm512_maskz_shuffle_i64x2::<0b00_00_00_00>(0, a, b); @@ -10306,7 +10311,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_shuffle_i64x2() { + const unsafe fn test_mm256_shuffle_i64x2() { let a = _mm256_set_epi64x(1, 4, 5, 8); let b = _mm256_set_epi64x(2, 3, 6, 7); let r = _mm256_shuffle_i64x2::<0b00>(a, b); @@ -10315,7 +10320,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_shuffle_i64x2() { + const unsafe fn test_mm256_mask_shuffle_i64x2() { let a = _mm256_set_epi64x(1, 4, 5, 8); let b = _mm256_set_epi64x(2, 3, 6, 7); let r = _mm256_mask_shuffle_i64x2::<0b00>(a, 0, a, b); @@ -10326,7 +10331,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_shuffle_i64x2() { + const unsafe fn test_mm256_maskz_shuffle_i64x2() { let a = _mm256_set_epi64x(1, 4, 5, 8); let b = _mm256_set_epi64x(2, 3, 6, 7); let r = _mm256_maskz_shuffle_i64x2::<0b00>(0, a, b); @@ -10337,7 +10342,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_shuffle_f64x2() { + const unsafe fn test_mm512_shuffle_f64x2() { let a = _mm512_setr_pd(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm512_setr_pd(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm512_shuffle_f64x2::<0b00_00_00_00>(a, b); @@ -10346,7 +10351,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_shuffle_f64x2() { + const unsafe fn test_mm512_mask_shuffle_f64x2() { let a = _mm512_setr_pd(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm512_setr_pd(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm512_mask_shuffle_f64x2::<0b00_00_00_00>(a, 0, a, b); @@ -10357,7 +10362,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_shuffle_f64x2() { + const unsafe fn test_mm512_maskz_shuffle_f64x2() { let a = _mm512_setr_pd(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm512_setr_pd(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm512_maskz_shuffle_f64x2::<0b00_00_00_00>(0, a, b); @@ -10368,7 +10373,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_shuffle_f64x2() { + const unsafe fn test_mm256_shuffle_f64x2() { let a = _mm256_set_pd(1., 4., 5., 8.); let b = _mm256_set_pd(2., 3., 6., 7.); let r = _mm256_shuffle_f64x2::<0b00>(a, b); @@ -10377,7 +10382,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_shuffle_f64x2() { + const unsafe fn test_mm256_mask_shuffle_f64x2() { let a = _mm256_set_pd(1., 4., 5., 8.); let b = _mm256_set_pd(2., 3., 6., 7.); let r = _mm256_mask_shuffle_f64x2::<0b00>(a, 0, a, b); @@ -10388,7 +10393,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_shuffle_f64x2() { + const unsafe fn test_mm256_maskz_shuffle_f64x2() { let a = _mm256_set_pd(1., 4., 5., 8.); let b = _mm256_set_pd(2., 3., 6., 7.); let r = _mm256_maskz_shuffle_f64x2::<0b00>(0, a, b); @@ -10399,7 +10404,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_movedup_pd() { + const unsafe fn test_mm512_movedup_pd() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_movedup_pd(a); let e = _mm512_setr_pd(1., 1., 3., 3., 5., 5., 7., 7.); @@ -10407,7 +10412,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_movedup_pd() { + const unsafe fn test_mm512_mask_movedup_pd() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_mask_movedup_pd(a, 0, a); assert_eq_m512d(r, a); @@ -10417,7 +10422,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_movedup_pd() { + const unsafe fn test_mm512_maskz_movedup_pd() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_maskz_movedup_pd(0, a); assert_eq_m512d(r, _mm512_setzero_pd()); @@ -10427,7 +10432,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_movedup_pd() { + const unsafe fn test_mm256_mask_movedup_pd() { let a = _mm256_set_pd(1., 2., 3., 4.); let r = _mm256_mask_movedup_pd(a, 0, a); assert_eq_m256d(r, a); @@ -10437,7 +10442,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_movedup_pd() { + const unsafe fn test_mm256_maskz_movedup_pd() { let a = _mm256_set_pd(1., 2., 3., 4.); let r = _mm256_maskz_movedup_pd(0, a); assert_eq_m256d(r, _mm256_setzero_pd()); @@ -10447,7 +10452,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_movedup_pd() { + const unsafe fn test_mm_mask_movedup_pd() { let a = _mm_set_pd(1., 2.); let r = _mm_mask_movedup_pd(a, 0, a); assert_eq_m128d(r, a); @@ -10457,7 +10462,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_movedup_pd() { + const unsafe fn test_mm_maskz_movedup_pd() { let a = _mm_set_pd(1., 2.); let r = _mm_maskz_movedup_pd(0, a); assert_eq_m128d(r, _mm_setzero_pd()); @@ -10467,7 +10472,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_inserti64x4() { + const unsafe fn test_mm512_inserti64x4() { let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm256_setr_epi64x(17, 18, 19, 20); let r = _mm512_inserti64x4::<1>(a, b); @@ -10476,7 +10481,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_inserti64x4() { + const unsafe fn test_mm512_mask_inserti64x4() { let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm256_setr_epi64x(17, 18, 19, 20); let r = _mm512_mask_inserti64x4::<1>(a, 0, a, b); @@ -10487,7 +10492,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_inserti64x4() { + const unsafe fn test_mm512_maskz_inserti64x4() { let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm256_setr_epi64x(17, 18, 19, 20); let r = _mm512_maskz_inserti64x4::<1>(0, a, b); @@ -10498,7 +10503,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_insertf64x4() { + const unsafe fn test_mm512_insertf64x4() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_setr_pd(17., 18., 19., 20.); let r = _mm512_insertf64x4::<1>(a, b); @@ -10507,7 +10512,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_insertf64x4() { + const unsafe fn test_mm512_mask_insertf64x4() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_setr_pd(17., 18., 19., 20.); let r = _mm512_mask_insertf64x4::<1>(a, 0, a, b); @@ -10518,7 +10523,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_insertf64x4() { + const unsafe fn test_mm512_maskz_insertf64x4() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm256_setr_pd(17., 18., 19., 20.); let r = _mm512_maskz_insertf64x4::<1>(0, a, b); @@ -10529,21 +10534,21 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castpd128_pd512() { + const unsafe fn test_mm512_castpd128_pd512() { let a = _mm_setr_pd(17., 18.); let r = _mm512_castpd128_pd512(a); assert_eq_m128d(_mm512_castpd512_pd128(r), a); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castpd256_pd512() { + const unsafe fn test_mm512_castpd256_pd512() { let a = _mm256_setr_pd(17., 18., 19., 20.); let r = _mm512_castpd256_pd512(a); assert_eq_m256d(_mm512_castpd512_pd256(r), a); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_zextpd128_pd512() { + const unsafe fn test_mm512_zextpd128_pd512() { let a = _mm_setr_pd(17., 18.); let r = _mm512_zextpd128_pd512(a); let e = _mm512_setr_pd(17., 18., 0., 0., 0., 0., 0., 0.); @@ -10551,7 +10556,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_zextpd256_pd512() { + const unsafe fn test_mm512_zextpd256_pd512() { let a = _mm256_setr_pd(17., 18., 19., 20.); let r = _mm512_zextpd256_pd512(a); let e = _mm512_setr_pd(17., 18., 19., 20., 0., 0., 0., 0.); @@ -10559,7 +10564,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castpd512_pd128() { + const unsafe fn test_mm512_castpd512_pd128() { let a = _mm512_setr_pd(17., 18., -1., -1., -1., -1., -1., -1.); let r = _mm512_castpd512_pd128(a); let e = _mm_setr_pd(17., 18.); @@ -10567,7 +10572,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castpd512_pd256() { + const unsafe fn test_mm512_castpd512_pd256() { let a = _mm512_setr_pd(17., 18., 19., 20., -1., -1., -1., -1.); let r = _mm512_castpd512_pd256(a); let e = _mm256_setr_pd(17., 18., 19., 20.); @@ -10575,7 +10580,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castpd_ps() { + const unsafe fn test_mm512_castpd_ps() { let a = _mm512_set1_pd(1.); let r = _mm512_castpd_ps(a); let e = _mm512_set_ps( @@ -10586,7 +10591,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castpd_si512() { + const unsafe fn test_mm512_castpd_si512() { let a = _mm512_set1_pd(1.); let r = _mm512_castpd_si512(a); let e = _mm512_set_epi32( @@ -10597,21 +10602,21 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castsi128_si512() { + const unsafe fn test_mm512_castsi128_si512() { let a = _mm_setr_epi64x(17, 18); let r = _mm512_castsi128_si512(a); assert_eq_m128i(_mm512_castsi512_si128(r), a); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castsi256_si512() { + const unsafe fn test_mm512_castsi256_si512() { let a = _mm256_setr_epi64x(17, 18, 19, 20); let r = _mm512_castsi256_si512(a); assert_eq_m256i(_mm512_castsi512_si256(r), a); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_zextsi128_si512() { + const unsafe fn test_mm512_zextsi128_si512() { let a = _mm_setr_epi64x(17, 18); let r = _mm512_zextsi128_si512(a); let e = _mm512_setr_epi64(17, 18, 0, 0, 0, 0, 0, 0); @@ -10619,7 +10624,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_zextsi256_si512() { + const unsafe fn test_mm512_zextsi256_si512() { let a = _mm256_setr_epi64x(17, 18, 19, 20); let r = _mm512_zextsi256_si512(a); let e = _mm512_setr_epi64(17, 18, 19, 20, 0, 0, 0, 0); @@ -10627,7 +10632,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castsi512_si128() { + const unsafe fn test_mm512_castsi512_si128() { let a = _mm512_setr_epi64(17, 18, -1, -1, -1, -1, -1, -1); let r = _mm512_castsi512_si128(a); let e = _mm_setr_epi64x(17, 18); @@ -10635,7 +10640,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castsi512_si256() { + const unsafe fn test_mm512_castsi512_si256() { let a = _mm512_setr_epi64(17, 18, 19, 20, -1, -1, -1, -1); let r = _mm512_castsi512_si256(a); let e = _mm256_setr_epi64x(17, 18, 19, 20); @@ -10643,7 +10648,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castsi512_ps() { + const unsafe fn test_mm512_castsi512_ps() { let a = _mm512_set1_epi64(1 << 62); let r = _mm512_castsi512_ps(a); let e = _mm512_set_ps( @@ -10653,7 +10658,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_castsi512_pd() { + const unsafe fn test_mm512_castsi512_pd() { let a = _mm512_set1_epi64(1 << 62); let r = _mm512_castsi512_pd(a); let e = _mm512_set_pd(2., 2., 2., 2., 2., 2., 2., 2.); @@ -10661,7 +10666,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_broadcastq_epi64() { + const unsafe fn test_mm512_broadcastq_epi64() { let a = _mm_setr_epi64x(17, 18); let r = _mm512_broadcastq_epi64(a); let e = _mm512_set1_epi64(17); @@ -10669,7 +10674,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_broadcastq_epi64() { + const unsafe fn test_mm512_mask_broadcastq_epi64() { let src = _mm512_set1_epi64(18); let a = _mm_setr_epi64x(17, 18); let r = _mm512_mask_broadcastq_epi64(src, 0, a); @@ -10680,7 +10685,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_broadcastq_epi64() { + const unsafe fn test_mm512_maskz_broadcastq_epi64() { let a = _mm_setr_epi64x(17, 18); let r = _mm512_maskz_broadcastq_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -10690,7 +10695,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_broadcastq_epi64() { + const unsafe fn test_mm256_mask_broadcastq_epi64() { let src = _mm256_set1_epi64x(18); let a = _mm_set_epi64x(17, 18); let r = _mm256_mask_broadcastq_epi64(src, 0, a); @@ -10701,7 +10706,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_broadcastq_epi64() { + const unsafe fn test_mm256_maskz_broadcastq_epi64() { let a = _mm_set_epi64x(17, 18); let r = _mm256_maskz_broadcastq_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -10711,7 +10716,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_broadcastq_epi64() { + const unsafe fn test_mm_mask_broadcastq_epi64() { let src = _mm_set1_epi64x(18); let a = _mm_set_epi64x(17, 18); let r = _mm_mask_broadcastq_epi64(src, 0, a); @@ -10722,7 +10727,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_broadcastq_epi64() { + const unsafe fn test_mm_maskz_broadcastq_epi64() { let a = _mm_set_epi64x(17, 18); let r = _mm_maskz_broadcastq_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -10732,7 +10737,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_broadcastsd_pd() { + const unsafe fn test_mm512_broadcastsd_pd() { let a = _mm_set_pd(17., 18.); let r = _mm512_broadcastsd_pd(a); let e = _mm512_set1_pd(18.); @@ -10740,7 +10745,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_broadcastsd_pd() { + const unsafe fn test_mm512_mask_broadcastsd_pd() { let src = _mm512_set1_pd(18.); let a = _mm_set_pd(17., 18.); let r = _mm512_mask_broadcastsd_pd(src, 0, a); @@ -10751,7 +10756,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_broadcastsd_pd() { + const unsafe fn test_mm512_maskz_broadcastsd_pd() { let a = _mm_set_pd(17., 18.); let r = _mm512_maskz_broadcastsd_pd(0, a); assert_eq_m512d(r, _mm512_setzero_pd()); @@ -10761,7 +10766,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_broadcastsd_pd() { + const unsafe fn test_mm256_mask_broadcastsd_pd() { let src = _mm256_set1_pd(18.); let a = _mm_set_pd(17., 18.); let r = _mm256_mask_broadcastsd_pd(src, 0, a); @@ -10772,7 +10777,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_broadcastsd_pd() { + const unsafe fn test_mm256_maskz_broadcastsd_pd() { let a = _mm_set_pd(17., 18.); let r = _mm256_maskz_broadcastsd_pd(0, a); assert_eq_m256d(r, _mm256_setzero_pd()); @@ -10782,7 +10787,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_broadcast_i64x4() { + const unsafe fn test_mm512_broadcast_i64x4() { let a = _mm256_set_epi64x(17, 18, 19, 20); let r = _mm512_broadcast_i64x4(a); let e = _mm512_set_epi64(17, 18, 19, 20, 17, 18, 19, 20); @@ -10790,7 +10795,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_broadcast_i64x4() { + const unsafe fn test_mm512_mask_broadcast_i64x4() { let src = _mm512_set1_epi64(18); let a = _mm256_set_epi64x(17, 18, 19, 20); let r = _mm512_mask_broadcast_i64x4(src, 0, a); @@ -10801,7 +10806,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_broadcast_i64x4() { + const unsafe fn test_mm512_maskz_broadcast_i64x4() { let a = _mm256_set_epi64x(17, 18, 19, 20); let r = _mm512_maskz_broadcast_i64x4(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -10811,7 +10816,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_broadcast_f64x4() { + const unsafe fn test_mm512_broadcast_f64x4() { let a = _mm256_set_pd(17., 18., 19., 20.); let r = _mm512_broadcast_f64x4(a); let e = _mm512_set_pd(17., 18., 19., 20., 17., 18., 19., 20.); @@ -10819,7 +10824,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_broadcast_f64x4() { + const unsafe fn test_mm512_mask_broadcast_f64x4() { let src = _mm512_set1_pd(18.); let a = _mm256_set_pd(17., 18., 19., 20.); let r = _mm512_mask_broadcast_f64x4(src, 0, a); @@ -10830,7 +10835,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_broadcast_f64x4() { + const unsafe fn test_mm512_maskz_broadcast_f64x4() { let a = _mm256_set_pd(17., 18., 19., 20.); let r = _mm512_maskz_broadcast_f64x4(0, a); assert_eq_m512d(r, _mm512_setzero_pd()); @@ -10840,7 +10845,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_blend_epi64() { + const unsafe fn test_mm512_mask_blend_epi64() { let a = _mm512_set1_epi64(1); let b = _mm512_set1_epi64(2); let r = _mm512_mask_blend_epi64(0b11110000, a, b); @@ -10849,7 +10854,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_blend_epi64() { + const unsafe fn test_mm256_mask_blend_epi64() { let a = _mm256_set1_epi64x(1); let b = _mm256_set1_epi64x(2); let r = _mm256_mask_blend_epi64(0b00001111, a, b); @@ -10858,7 +10863,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_blend_epi64() { + const unsafe fn test_mm_mask_blend_epi64() { let a = _mm_set1_epi64x(1); let b = _mm_set1_epi64x(2); let r = _mm_mask_blend_epi64(0b00000011, a, b); @@ -10867,7 +10872,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_blend_pd() { + const unsafe fn test_mm512_mask_blend_pd() { let a = _mm512_set1_pd(1.); let b = _mm512_set1_pd(2.); let r = _mm512_mask_blend_pd(0b11110000, a, b); @@ -10876,7 +10881,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_blend_pd() { + const unsafe fn test_mm256_mask_blend_pd() { let a = _mm256_set1_pd(1.); let b = _mm256_set1_pd(2.); let r = _mm256_mask_blend_pd(0b00001111, a, b); @@ -10885,7 +10890,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_blend_pd() { + const unsafe fn test_mm_mask_blend_pd() { let a = _mm_set1_pd(1.); let b = _mm_set1_pd(2.); let r = _mm_mask_blend_pd(0b00000011, a, b); @@ -10894,7 +10899,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_unpackhi_epi64() { + const unsafe fn test_mm512_unpackhi_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi64(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_unpackhi_epi64(a, b); @@ -10903,7 +10908,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_unpackhi_epi64() { + const unsafe fn test_mm512_mask_unpackhi_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi64(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_mask_unpackhi_epi64(a, 0, a, b); @@ -10914,7 +10919,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_unpackhi_epi64() { + const unsafe fn test_mm512_maskz_unpackhi_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi64(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_maskz_unpackhi_epi64(0, a, b); @@ -10925,7 +10930,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_unpackhi_epi64() { + const unsafe fn test_mm256_mask_unpackhi_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm256_set_epi64x(17, 18, 19, 20); let r = _mm256_mask_unpackhi_epi64(a, 0, a, b); @@ -10936,7 +10941,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_unpackhi_epi64() { + const unsafe fn test_mm256_maskz_unpackhi_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm256_set_epi64x(17, 18, 19, 20); let r = _mm256_maskz_unpackhi_epi64(0, a, b); @@ -10947,7 +10952,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_unpackhi_epi64() { + const unsafe fn test_mm_mask_unpackhi_epi64() { let a = _mm_set_epi64x(1, 2); let b = _mm_set_epi64x(17, 18); let r = _mm_mask_unpackhi_epi64(a, 0, a, b); @@ -10958,7 +10963,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_unpackhi_epi64() { + const unsafe fn test_mm_maskz_unpackhi_epi64() { let a = _mm_set_epi64x(1, 2); let b = _mm_set_epi64x(17, 18); let r = _mm_maskz_unpackhi_epi64(0, a, b); @@ -10969,7 +10974,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_unpackhi_pd() { + const unsafe fn test_mm512_unpackhi_pd() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm512_set_pd(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm512_unpackhi_pd(a, b); @@ -10978,7 +10983,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_unpackhi_pd() { + const unsafe fn test_mm512_mask_unpackhi_pd() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm512_set_pd(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm512_mask_unpackhi_pd(a, 0, a, b); @@ -10989,7 +10994,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_unpackhi_pd() { + const unsafe fn test_mm512_maskz_unpackhi_pd() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm512_set_pd(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm512_maskz_unpackhi_pd(0, a, b); @@ -11000,7 +11005,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_unpackhi_pd() { + const unsafe fn test_mm256_mask_unpackhi_pd() { let a = _mm256_set_pd(1., 2., 3., 4.); let b = _mm256_set_pd(17., 18., 19., 20.); let r = _mm256_mask_unpackhi_pd(a, 0, a, b); @@ -11011,7 +11016,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_unpackhi_pd() { + const unsafe fn test_mm256_maskz_unpackhi_pd() { let a = _mm256_set_pd(1., 2., 3., 4.); let b = _mm256_set_pd(17., 18., 19., 20.); let r = _mm256_maskz_unpackhi_pd(0, a, b); @@ -11022,7 +11027,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_unpackhi_pd() { + const unsafe fn test_mm_mask_unpackhi_pd() { let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(17., 18.); let r = _mm_mask_unpackhi_pd(a, 0, a, b); @@ -11033,7 +11038,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_unpackhi_pd() { + const unsafe fn test_mm_maskz_unpackhi_pd() { let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(17., 18.); let r = _mm_maskz_unpackhi_pd(0, a, b); @@ -11044,7 +11049,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_unpacklo_epi64() { + const unsafe fn test_mm512_unpacklo_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi64(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_unpacklo_epi64(a, b); @@ -11053,7 +11058,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_unpacklo_epi64() { + const unsafe fn test_mm512_mask_unpacklo_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi64(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_mask_unpacklo_epi64(a, 0, a, b); @@ -11064,7 +11069,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_unpacklo_epi64() { + const unsafe fn test_mm512_maskz_unpacklo_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi64(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_maskz_unpacklo_epi64(0, a, b); @@ -11075,7 +11080,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_unpacklo_epi64() { + const unsafe fn test_mm256_mask_unpacklo_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm256_set_epi64x(17, 18, 19, 20); let r = _mm256_mask_unpacklo_epi64(a, 0, a, b); @@ -11086,7 +11091,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_unpacklo_epi64() { + const unsafe fn test_mm256_maskz_unpacklo_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm256_set_epi64x(17, 18, 19, 20); let r = _mm256_maskz_unpacklo_epi64(0, a, b); @@ -11097,7 +11102,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_unpacklo_epi64() { + const unsafe fn test_mm_mask_unpacklo_epi64() { let a = _mm_set_epi64x(1, 2); let b = _mm_set_epi64x(17, 18); let r = _mm_mask_unpacklo_epi64(a, 0, a, b); @@ -11108,7 +11113,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_unpacklo_epi64() { + const unsafe fn test_mm_maskz_unpacklo_epi64() { let a = _mm_set_epi64x(1, 2); let b = _mm_set_epi64x(17, 18); let r = _mm_maskz_unpacklo_epi64(0, a, b); @@ -11119,7 +11124,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_unpacklo_pd() { + const unsafe fn test_mm512_unpacklo_pd() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm512_set_pd(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm512_unpacklo_pd(a, b); @@ -11128,7 +11133,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_unpacklo_pd() { + const unsafe fn test_mm512_mask_unpacklo_pd() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm512_set_pd(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm512_mask_unpacklo_pd(a, 0, a, b); @@ -11139,7 +11144,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_unpacklo_pd() { + const unsafe fn test_mm512_maskz_unpacklo_pd() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm512_set_pd(17., 18., 19., 20., 21., 22., 23., 24.); let r = _mm512_maskz_unpacklo_pd(0, a, b); @@ -11150,7 +11155,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_unpacklo_pd() { + const unsafe fn test_mm256_mask_unpacklo_pd() { let a = _mm256_set_pd(1., 2., 3., 4.); let b = _mm256_set_pd(17., 18., 19., 20.); let r = _mm256_mask_unpacklo_pd(a, 0, a, b); @@ -11161,7 +11166,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_unpacklo_pd() { + const unsafe fn test_mm256_maskz_unpacklo_pd() { let a = _mm256_set_pd(1., 2., 3., 4.); let b = _mm256_set_pd(17., 18., 19., 20.); let r = _mm256_maskz_unpacklo_pd(0, a, b); @@ -11172,7 +11177,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_unpacklo_pd() { + const unsafe fn test_mm_mask_unpacklo_pd() { let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(17., 18.); let r = _mm_mask_unpacklo_pd(a, 0, a, b); @@ -11183,7 +11188,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_unpacklo_pd() { + const unsafe fn test_mm_maskz_unpacklo_pd() { let a = _mm_set_pd(1., 2.); let b = _mm_set_pd(17., 18.); let r = _mm_maskz_unpacklo_pd(0, a, b); @@ -11194,7 +11199,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_alignr_epi64() { + const unsafe fn test_mm512_alignr_epi64() { let a = _mm512_set_epi64(8, 7, 6, 5, 4, 3, 2, 1); let b = _mm512_set_epi64(16, 15, 14, 13, 12, 11, 10, 9); let r = _mm512_alignr_epi64::<0>(a, b); @@ -11207,7 +11212,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_alignr_epi64() { + const unsafe fn test_mm512_mask_alignr_epi64() { let a = _mm512_set_epi64(8, 7, 6, 5, 4, 3, 2, 1); let b = _mm512_set_epi64(16, 15, 14, 13, 12, 11, 10, 9); let r = _mm512_mask_alignr_epi64::<1>(a, 0, a, b); @@ -11218,7 +11223,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_alignr_epi64() { + const unsafe fn test_mm512_maskz_alignr_epi64() { let a = _mm512_set_epi64(8, 7, 6, 5, 4, 3, 2, 1); let b = _mm512_set_epi64(16, 15, 14, 13, 12, 11, 10, 9); let r = _mm512_maskz_alignr_epi64::<1>(0, a, b); @@ -11229,7 +11234,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_alignr_epi64() { + const unsafe fn test_mm256_alignr_epi64() { let a = _mm256_set_epi64x(4, 3, 2, 1); let b = _mm256_set_epi64x(8, 7, 6, 5); let r = _mm256_alignr_epi64::<0>(a, b); @@ -11244,7 +11249,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_alignr_epi64() { + const unsafe fn test_mm256_mask_alignr_epi64() { let a = _mm256_set_epi64x(4, 3, 2, 1); let b = _mm256_set_epi64x(8, 7, 6, 5); let r = _mm256_mask_alignr_epi64::<1>(a, 0, a, b); @@ -11255,7 +11260,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_alignr_epi64() { + const unsafe fn test_mm256_maskz_alignr_epi64() { let a = _mm256_set_epi64x(4, 3, 2, 1); let b = _mm256_set_epi64x(8, 7, 6, 5); let r = _mm256_maskz_alignr_epi64::<1>(0, a, b); @@ -11266,7 +11271,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_alignr_epi64() { + const unsafe fn test_mm_alignr_epi64() { let a = _mm_set_epi64x(2, 1); let b = _mm_set_epi64x(4, 3); let r = _mm_alignr_epi64::<0>(a, b); @@ -11275,7 +11280,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_alignr_epi64() { + const unsafe fn test_mm_mask_alignr_epi64() { let a = _mm_set_epi64x(2, 1); let b = _mm_set_epi64x(4, 3); let r = _mm_mask_alignr_epi64::<1>(a, 0, a, b); @@ -11286,7 +11291,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_alignr_epi64() { + const unsafe fn test_mm_maskz_alignr_epi64() { let a = _mm_set_epi64x(2, 1); let b = _mm_set_epi64x(4, 3); let r = _mm_maskz_alignr_epi64::<1>(0, a, b); @@ -11297,7 +11302,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_and_epi64() { + const unsafe fn test_mm512_and_epi64() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_and_epi64(a, b); @@ -11306,7 +11311,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_and_epi64() { + const unsafe fn test_mm512_mask_and_epi64() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_mask_and_epi64(a, 0, a, b); @@ -11317,7 +11322,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_and_epi64() { + const unsafe fn test_mm512_maskz_and_epi64() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_maskz_and_epi64(0, a, b); @@ -11328,7 +11333,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_and_epi64() { + const unsafe fn test_mm256_mask_and_epi64() { let a = _mm256_set1_epi64x(1 << 0 | 1 << 15); let b = _mm256_set1_epi64x(1 << 0); let r = _mm256_mask_and_epi64(a, 0, a, b); @@ -11339,7 +11344,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_and_epi64() { + const unsafe fn test_mm256_maskz_and_epi64() { let a = _mm256_set1_epi64x(1 << 0 | 1 << 15); let b = _mm256_set1_epi64x(1 << 0); let r = _mm256_maskz_and_epi64(0, a, b); @@ -11350,7 +11355,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_and_epi64() { + const unsafe fn test_mm_mask_and_epi64() { let a = _mm_set1_epi64x(1 << 0 | 1 << 15); let b = _mm_set1_epi64x(1 << 0); let r = _mm_mask_and_epi64(a, 0, a, b); @@ -11361,7 +11366,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_and_epi64() { + const unsafe fn test_mm_maskz_and_epi64() { let a = _mm_set1_epi64x(1 << 0 | 1 << 15); let b = _mm_set1_epi64x(1 << 0); let r = _mm_maskz_and_epi64(0, a, b); @@ -11372,7 +11377,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_and_si512() { + const unsafe fn test_mm512_and_si512() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_and_epi64(a, b); @@ -11381,7 +11386,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_or_epi64() { + const unsafe fn test_mm512_or_epi64() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_or_epi64(a, b); @@ -11394,7 +11399,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_or_epi64() { + const unsafe fn test_mm512_mask_or_epi64() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_mask_or_epi64(a, 0, a, b); @@ -11409,7 +11414,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_or_epi64() { + const unsafe fn test_mm512_maskz_or_epi64() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_maskz_or_epi64(0, a, b); @@ -11420,7 +11425,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_or_epi64() { + const unsafe fn test_mm256_or_epi64() { let a = _mm256_set1_epi64x(1 << 0 | 1 << 15); let b = _mm256_set1_epi64x(1 << 13); let r = _mm256_or_epi64(a, b); @@ -11429,7 +11434,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_or_epi64() { + const unsafe fn test_mm256_mask_or_epi64() { let a = _mm256_set1_epi64x(1 << 0 | 1 << 15); let b = _mm256_set1_epi64x(1 << 13); let r = _mm256_mask_or_epi64(a, 0, a, b); @@ -11440,7 +11445,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_or_epi64() { + const unsafe fn test_mm256_maskz_or_epi64() { let a = _mm256_set1_epi64x(1 << 0 | 1 << 15); let b = _mm256_set1_epi64x(1 << 13); let r = _mm256_maskz_or_epi64(0, a, b); @@ -11451,7 +11456,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_or_epi64() { + const unsafe fn test_mm_or_epi64() { let a = _mm_set1_epi64x(1 << 0 | 1 << 15); let b = _mm_set1_epi64x(1 << 13); let r = _mm_or_epi64(a, b); @@ -11460,7 +11465,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_or_epi64() { + const unsafe fn test_mm_mask_or_epi64() { let a = _mm_set1_epi64x(1 << 0 | 1 << 15); let b = _mm_set1_epi64x(1 << 13); let r = _mm_mask_or_epi64(a, 0, a, b); @@ -11471,7 +11476,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_or_epi64() { + const unsafe fn test_mm_maskz_or_epi64() { let a = _mm_set1_epi64x(1 << 0 | 1 << 15); let b = _mm_set1_epi64x(1 << 13); let r = _mm_maskz_or_epi64(0, a, b); @@ -11482,7 +11487,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_or_si512() { + const unsafe fn test_mm512_or_si512() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_or_epi64(a, b); @@ -11495,7 +11500,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_xor_epi64() { + const unsafe fn test_mm512_xor_epi64() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_xor_epi64(a, b); @@ -11504,7 +11509,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_xor_epi64() { + const unsafe fn test_mm512_mask_xor_epi64() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_mask_xor_epi64(a, 0, a, b); @@ -11515,7 +11520,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_xor_epi64() { + const unsafe fn test_mm512_maskz_xor_epi64() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_maskz_xor_epi64(0, a, b); @@ -11526,7 +11531,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_xor_epi64() { + const unsafe fn test_mm256_xor_epi64() { let a = _mm256_set1_epi64x(1 << 0 | 1 << 15); let b = _mm256_set1_epi64x(1 << 13); let r = _mm256_xor_epi64(a, b); @@ -11535,7 +11540,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_xor_epi64() { + const unsafe fn test_mm256_mask_xor_epi64() { let a = _mm256_set1_epi64x(1 << 0 | 1 << 15); let b = _mm256_set1_epi64x(1 << 13); let r = _mm256_mask_xor_epi64(a, 0, a, b); @@ -11546,7 +11551,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_xor_epi64() { + const unsafe fn test_mm256_maskz_xor_epi64() { let a = _mm256_set1_epi64x(1 << 0 | 1 << 15); let b = _mm256_set1_epi64x(1 << 13); let r = _mm256_maskz_xor_epi64(0, a, b); @@ -11557,7 +11562,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_xor_epi64() { + const unsafe fn test_mm_xor_epi64() { let a = _mm_set1_epi64x(1 << 0 | 1 << 15); let b = _mm_set1_epi64x(1 << 13); let r = _mm_xor_epi64(a, b); @@ -11566,7 +11571,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_xor_epi64() { + const unsafe fn test_mm_mask_xor_epi64() { let a = _mm_set1_epi64x(1 << 0 | 1 << 15); let b = _mm_set1_epi64x(1 << 13); let r = _mm_mask_xor_epi64(a, 0, a, b); @@ -11577,7 +11582,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_xor_epi64() { + const unsafe fn test_mm_maskz_xor_epi64() { let a = _mm_set1_epi64x(1 << 0 | 1 << 15); let b = _mm_set1_epi64x(1 << 13); let r = _mm_maskz_xor_epi64(0, a, b); @@ -11588,7 +11593,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_xor_si512() { + const unsafe fn test_mm512_xor_si512() { let a = _mm512_set_epi64(1 << 0 | 1 << 15, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let b = _mm512_set_epi64(1 << 13, 0, 0, 0, 0, 0, 0, 1 << 1 | 1 << 2 | 1 << 3); let r = _mm512_xor_epi64(a, b); @@ -11597,7 +11602,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_andnot_epi64() { + const unsafe fn test_mm512_andnot_epi64() { let a = _mm512_set1_epi64(0); let b = _mm512_set1_epi64(1 << 3 | 1 << 4); let r = _mm512_andnot_epi64(a, b); @@ -11606,7 +11611,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_andnot_epi64() { + const unsafe fn test_mm512_mask_andnot_epi64() { let a = _mm512_set1_epi64(1 << 1 | 1 << 2); let b = _mm512_set1_epi64(1 << 3 | 1 << 4); let r = _mm512_mask_andnot_epi64(a, 0, a, b); @@ -11617,7 +11622,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_andnot_epi64() { + const unsafe fn test_mm512_maskz_andnot_epi64() { let a = _mm512_set1_epi64(1 << 1 | 1 << 2); let b = _mm512_set1_epi64(1 << 3 | 1 << 4); let r = _mm512_maskz_andnot_epi64(0, a, b); @@ -11632,7 +11637,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_andnot_epi64() { + const unsafe fn test_mm256_mask_andnot_epi64() { let a = _mm256_set1_epi64x(1 << 1 | 1 << 2); let b = _mm256_set1_epi64x(1 << 3 | 1 << 4); let r = _mm256_mask_andnot_epi64(a, 0, a, b); @@ -11643,7 +11648,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_andnot_epi64() { + const unsafe fn test_mm256_maskz_andnot_epi64() { let a = _mm256_set1_epi64x(1 << 1 | 1 << 2); let b = _mm256_set1_epi64x(1 << 3 | 1 << 4); let r = _mm256_maskz_andnot_epi64(0, a, b); @@ -11654,7 +11659,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_andnot_epi64() { + const unsafe fn test_mm_mask_andnot_epi64() { let a = _mm_set1_epi64x(1 << 1 | 1 << 2); let b = _mm_set1_epi64x(1 << 3 | 1 << 4); let r = _mm_mask_andnot_epi64(a, 0, a, b); @@ -11665,7 +11670,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_andnot_epi64() { + const unsafe fn test_mm_maskz_andnot_epi64() { let a = _mm_set1_epi64x(1 << 1 | 1 << 2); let b = _mm_set1_epi64x(1 << 3 | 1 << 4); let r = _mm_maskz_andnot_epi64(0, a, b); @@ -11676,7 +11681,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_andnot_si512() { + const unsafe fn test_mm512_andnot_si512() { let a = _mm512_set1_epi64(0); let b = _mm512_set1_epi64(1 << 3 | 1 << 4); let r = _mm512_andnot_si512(a, b); @@ -11685,84 +11690,84 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_add_epi64() { + const unsafe fn test_mm512_reduce_add_epi64() { let a = _mm512_set1_epi64(1); let e: i64 = _mm512_reduce_add_epi64(a); assert_eq!(8, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_add_epi64() { + const unsafe fn test_mm512_mask_reduce_add_epi64() { let a = _mm512_set1_epi64(1); let e: i64 = _mm512_mask_reduce_add_epi64(0b11110000, a); assert_eq!(4, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_add_pd() { + const unsafe fn test_mm512_reduce_add_pd() { let a = _mm512_set1_pd(1.); let e: f64 = _mm512_reduce_add_pd(a); assert_eq!(8., e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_add_pd() { + const unsafe fn test_mm512_mask_reduce_add_pd() { let a = _mm512_set1_pd(1.); let e: f64 = _mm512_mask_reduce_add_pd(0b11110000, a); assert_eq!(4., e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_mul_epi64() { + const unsafe fn test_mm512_reduce_mul_epi64() { let a = _mm512_set1_epi64(2); let e: i64 = _mm512_reduce_mul_epi64(a); assert_eq!(256, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_mul_epi64() { + const unsafe fn test_mm512_mask_reduce_mul_epi64() { let a = _mm512_set1_epi64(2); let e: i64 = _mm512_mask_reduce_mul_epi64(0b11110000, a); assert_eq!(16, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_mul_pd() { + const unsafe fn test_mm512_reduce_mul_pd() { let a = _mm512_set1_pd(2.); let e: f64 = _mm512_reduce_mul_pd(a); assert_eq!(256., e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_mul_pd() { + const unsafe fn test_mm512_mask_reduce_mul_pd() { let a = _mm512_set1_pd(2.); let e: f64 = _mm512_mask_reduce_mul_pd(0b11110000, a); assert_eq!(16., e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_max_epi64() { + const unsafe fn test_mm512_reduce_max_epi64() { let a = _mm512_set_epi64(0, 1, 2, 3, 4, 5, 6, 7); let e: i64 = _mm512_reduce_max_epi64(a); assert_eq!(7, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_max_epi64() { + const unsafe fn test_mm512_mask_reduce_max_epi64() { let a = _mm512_set_epi64(0, 1, 2, 3, 4, 5, 6, 7); let e: i64 = _mm512_mask_reduce_max_epi64(0b11110000, a); assert_eq!(3, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_max_epu64() { + const unsafe fn test_mm512_reduce_max_epu64() { let a = _mm512_set_epi64(0, 1, 2, 3, 4, 5, 6, 7); let e: u64 = _mm512_reduce_max_epu64(a); assert_eq!(7, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_max_epu64() { + const unsafe fn test_mm512_mask_reduce_max_epu64() { let a = _mm512_set_epi64(0, 1, 2, 3, 4, 5, 6, 7); let e: u64 = _mm512_mask_reduce_max_epu64(0b11110000, a); assert_eq!(3, e); @@ -11783,28 +11788,28 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_min_epi64() { + const unsafe fn test_mm512_reduce_min_epi64() { let a = _mm512_set_epi64(0, 1, 2, 3, 4, 5, 6, 7); let e: i64 = _mm512_reduce_min_epi64(a); assert_eq!(0, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_min_epi64() { + const unsafe fn test_mm512_mask_reduce_min_epi64() { let a = _mm512_set_epi64(0, 1, 2, 3, 4, 5, 6, 7); let e: i64 = _mm512_mask_reduce_min_epi64(0b11110000, a); assert_eq!(0, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_min_epu64() { + const unsafe fn test_mm512_reduce_min_epu64() { let a = _mm512_set_epi64(0, 1, 2, 3, 4, 5, 6, 7); let e: u64 = _mm512_reduce_min_epu64(a); assert_eq!(0, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_min_epu64() { + const unsafe fn test_mm512_mask_reduce_min_epu64() { let a = _mm512_set_epi64(0, 1, 2, 3, 4, 5, 6, 7); let e: u64 = _mm512_mask_reduce_min_epu64(0b11110000, a); assert_eq!(0, e); @@ -11825,35 +11830,35 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_and_epi64() { + const unsafe fn test_mm512_reduce_and_epi64() { let a = _mm512_set_epi64(1, 1, 1, 1, 2, 2, 2, 2); let e: i64 = _mm512_reduce_and_epi64(a); assert_eq!(0, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_and_epi64() { + const unsafe fn test_mm512_mask_reduce_and_epi64() { let a = _mm512_set_epi64(1, 1, 1, 1, 2, 2, 2, 2); let e: i64 = _mm512_mask_reduce_and_epi64(0b11110000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_reduce_or_epi64() { + const unsafe fn test_mm512_reduce_or_epi64() { let a = _mm512_set_epi64(1, 1, 1, 1, 2, 2, 2, 2); let e: i64 = _mm512_reduce_or_epi64(a); assert_eq!(3, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_reduce_or_epi64() { + const unsafe fn test_mm512_mask_reduce_or_epi64() { let a = _mm512_set_epi64(1, 1, 1, 1, 2, 2, 2, 2); let e: i64 = _mm512_mask_reduce_or_epi64(0b11110000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_extractf64x4_pd() { + const unsafe fn test_mm512_extractf64x4_pd() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_extractf64x4_pd::<1>(a); let e = _mm256_setr_pd(5., 6., 7., 8.); @@ -11861,7 +11866,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_extractf64x4_pd() { + const unsafe fn test_mm512_mask_extractf64x4_pd() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let src = _mm256_set1_pd(100.); let r = _mm512_mask_extractf64x4_pd::<1>(src, 0, a); @@ -11872,7 +11877,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_extractf64x4_pd() { + const unsafe fn test_mm512_maskz_extractf64x4_pd() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_maskz_extractf64x4_pd::<1>(0, a); assert_eq_m256d(r, _mm256_setzero_pd()); @@ -11882,7 +11887,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_extracti64x4_epi64() { + const unsafe fn test_mm512_extracti64x4_epi64() { let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm512_extracti64x4_epi64::<0x1>(a); let e = _mm256_setr_epi64x(5, 6, 7, 8); @@ -11890,7 +11895,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_extracti64x4_epi64() { + const unsafe fn test_mm512_mask_extracti64x4_epi64() { let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let src = _mm256_set1_epi64x(100); let r = _mm512_mask_extracti64x4_epi64::<0x1>(src, 0, a); @@ -11901,7 +11906,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_extracti64x4_epi64() { + const unsafe fn test_mm512_maskz_extracti64x4_epi64() { let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm512_maskz_extracti64x4_epi64::<0x1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -12163,7 +12168,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_loadu_epi64() { + const unsafe fn test_mm512_loadu_epi64() { let a = &[4, 3, 2, 5, -8, -9, -64, -50]; let p = a.as_ptr(); let r = _mm512_loadu_epi64(black_box(p)); @@ -12172,7 +12177,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_loadu_epi64() { + const unsafe fn test_mm256_loadu_epi64() { let a = &[4, 3, 2, 5]; let p = a.as_ptr(); let r = _mm256_loadu_epi64(black_box(p)); @@ -12181,7 +12186,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_loadu_epi64() { + const unsafe fn test_mm_loadu_epi64() { let a = &[4, 3]; let p = a.as_ptr(); let r = _mm_loadu_epi64(black_box(p)); @@ -12472,7 +12477,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_storeu_epi64() { + const unsafe fn test_mm512_storeu_epi64() { let a = _mm512_set1_epi64(9); let mut r = _mm512_set1_epi64(0); _mm512_storeu_epi64(&mut r as *mut _ as *mut i64, a); @@ -12480,7 +12485,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_storeu_epi64() { + const unsafe fn test_mm256_storeu_epi64() { let a = _mm256_set1_epi64x(9); let mut r = _mm256_set1_epi64x(0); _mm256_storeu_epi64(&mut r as *mut _ as *mut i64, a); @@ -12488,7 +12493,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_storeu_epi64() { + const unsafe fn test_mm_storeu_epi64() { let a = _mm_set1_epi64x(9); let mut r = _mm_set1_epi64x(0); _mm_storeu_epi64(&mut r as *mut _ as *mut i64, a); @@ -12496,7 +12501,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_load_epi64() { + const unsafe fn test_mm512_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 8], // 64 bytes @@ -12511,7 +12516,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_load_epi64() { + const unsafe fn test_mm256_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 4], @@ -12524,7 +12529,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_load_epi64() { + const unsafe fn test_mm_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 2], @@ -12537,7 +12542,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_store_epi64() { + const unsafe fn test_mm512_store_epi64() { let a = _mm512_set1_epi64(9); let mut r = _mm512_set1_epi64(0); _mm512_store_epi64(&mut r as *mut _ as *mut i64, a); @@ -12545,7 +12550,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_store_epi64() { + const unsafe fn test_mm256_store_epi64() { let a = _mm256_set1_epi64x(9); let mut r = _mm256_set1_epi64x(0); _mm256_store_epi64(&mut r as *mut _ as *mut i64, a); @@ -12553,7 +12558,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_store_epi64() { + const unsafe fn test_mm_store_epi64() { let a = _mm_set1_epi64x(9); let mut r = _mm_set1_epi64x(0); _mm_store_epi64(&mut r as *mut _ as *mut i64, a); @@ -12561,7 +12566,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_load_pd() { + const unsafe fn test_mm512_load_pd() { #[repr(align(64))] struct Align { data: [f64; 8], // 64 bytes @@ -12576,7 +12581,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_store_pd() { + const unsafe fn test_mm512_store_pd() { let a = _mm512_set1_pd(9.); let mut r = _mm512_undefined_pd(); _mm512_store_pd(&mut r as *mut _ as *mut f64, a); @@ -12584,7 +12589,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_test_epi64_mask() { + const unsafe fn test_mm512_test_epi64_mask() { let a = _mm512_set1_epi64(1 << 0); let b = _mm512_set1_epi64(1 << 0 | 1 << 1); let r = _mm512_test_epi64_mask(a, b); @@ -12593,7 +12598,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_test_epi64_mask() { + const unsafe fn test_mm512_mask_test_epi64_mask() { let a = _mm512_set1_epi64(1 << 0); let b = _mm512_set1_epi64(1 << 0 | 1 << 1); let r = _mm512_mask_test_epi64_mask(0, a, b); @@ -12604,7 +12609,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_test_epi64_mask() { + const unsafe fn test_mm256_test_epi64_mask() { let a = _mm256_set1_epi64x(1 << 0); let b = _mm256_set1_epi64x(1 << 0 | 1 << 1); let r = _mm256_test_epi64_mask(a, b); @@ -12613,7 +12618,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_test_epi64_mask() { + const unsafe fn test_mm256_mask_test_epi64_mask() { let a = _mm256_set1_epi64x(1 << 0); let b = _mm256_set1_epi64x(1 << 0 | 1 << 1); let r = _mm256_mask_test_epi64_mask(0, a, b); @@ -12624,7 +12629,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_test_epi64_mask() { + const unsafe fn test_mm_test_epi64_mask() { let a = _mm_set1_epi64x(1 << 0); let b = _mm_set1_epi64x(1 << 0 | 1 << 1); let r = _mm_test_epi64_mask(a, b); @@ -12633,7 +12638,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_test_epi64_mask() { + const unsafe fn test_mm_mask_test_epi64_mask() { let a = _mm_set1_epi64x(1 << 0); let b = _mm_set1_epi64x(1 << 0 | 1 << 1); let r = _mm_mask_test_epi64_mask(0, a, b); @@ -12644,7 +12649,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_testn_epi64_mask() { + const unsafe fn test_mm512_testn_epi64_mask() { let a = _mm512_set1_epi64(1 << 0); let b = _mm512_set1_epi64(1 << 0 | 1 << 1); let r = _mm512_testn_epi64_mask(a, b); @@ -12653,7 +12658,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_testn_epi64_mask() { + const unsafe fn test_mm512_mask_testn_epi64_mask() { let a = _mm512_set1_epi64(1 << 0); let b = _mm512_set1_epi64(1 << 1); let r = _mm512_mask_testn_epi64_mask(0, a, b); @@ -12664,7 +12669,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_testn_epi64_mask() { + const unsafe fn test_mm256_testn_epi64_mask() { let a = _mm256_set1_epi64x(1 << 0); let b = _mm256_set1_epi64x(1 << 1); let r = _mm256_testn_epi64_mask(a, b); @@ -12673,7 +12678,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_testn_epi64_mask() { + const unsafe fn test_mm256_mask_testn_epi64_mask() { let a = _mm256_set1_epi64x(1 << 0); let b = _mm256_set1_epi64x(1 << 1); let r = _mm256_mask_testn_epi64_mask(0, a, b); @@ -12684,7 +12689,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_testn_epi64_mask() { + const unsafe fn test_mm_testn_epi64_mask() { let a = _mm_set1_epi64x(1 << 0); let b = _mm_set1_epi64x(1 << 1); let r = _mm_testn_epi64_mask(a, b); @@ -12693,7 +12698,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_testn_epi64_mask() { + const unsafe fn test_mm_mask_testn_epi64_mask() { let a = _mm_set1_epi64x(1 << 0); let b = _mm_set1_epi64x(1 << 1); let r = _mm_mask_testn_epi64_mask(0, a, b); @@ -12704,7 +12709,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_set1_epi64() { + const unsafe fn test_mm512_mask_set1_epi64() { let src = _mm512_set1_epi64(2); let a: i64 = 11; let r = _mm512_mask_set1_epi64(src, 0, a); @@ -12715,7 +12720,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_set1_epi64() { + const unsafe fn test_mm512_maskz_set1_epi64() { let a: i64 = 11; let r = _mm512_maskz_set1_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -12725,7 +12730,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_set1_epi64() { + const unsafe fn test_mm256_mask_set1_epi64() { let src = _mm256_set1_epi64x(2); let a: i64 = 11; let r = _mm256_mask_set1_epi64(src, 0, a); @@ -12736,7 +12741,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_set1_epi64() { + const unsafe fn test_mm256_maskz_set1_epi64() { let a: i64 = 11; let r = _mm256_maskz_set1_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -12746,7 +12751,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_set1_epi64() { + const unsafe fn test_mm_mask_set1_epi64() { let src = _mm_set1_epi64x(2); let a: i64 = 11; let r = _mm_mask_set1_epi64(src, 0, a); @@ -12757,7 +12762,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_set1_epi64() { + const unsafe fn test_mm_maskz_set1_epi64() { let a: i64 = 11; let r = _mm_maskz_set1_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -12801,7 +12806,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_cvti64_ss() { + const unsafe fn test_mm_cvti64_ss() { let a = _mm_set_ps(0., -0.5, 1., -1.5); let b: i64 = 9; let r = _mm_cvti64_ss(a, b); @@ -12810,7 +12815,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_cvti64_sd() { + const unsafe fn test_mm_cvti64_sd() { let a = _mm_set_pd(1., -1.5); let b: i64 = 9; let r = _mm_cvti64_sd(a, b); @@ -12963,7 +12968,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_cvtu64_ss() { + const unsafe fn test_mm_cvtu64_ss() { let a = _mm_set_ps(0., -0.5, 1., -1.5); let b: u64 = 9; let r = _mm_cvtu64_ss(a, b); @@ -12972,7 +12977,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_cvtu64_sd() { + const unsafe fn test_mm_cvtu64_sd() { let a = _mm_set_pd(1., -1.5); let b: u64 = 9; let r = _mm_cvtu64_sd(a, b); From b2db9ab8b5d1b60603b843249398304638d4ac0b Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:23:10 +0530 Subject: [PATCH 0235/3801] Make `avx512bw` functions const --- .../crates/core_arch/src/x86/avx512bw.rs | 3738 ++++++++++------- .../crates/core_arch/src/x86_64/avx512bw.rs | 11 +- 2 files changed, 2332 insertions(+), 1417 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index c76ec3cb290e..b6e941908a76 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -14,7 +14,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsw))] -pub fn _mm512_abs_epi16(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_abs_epi16(a: __m512i) -> __m512i { unsafe { let a = a.as_i16x32(); let cmp: i16x32 = simd_gt(a, i16x32::ZERO); @@ -29,7 +30,8 @@ pub fn _mm512_abs_epi16(a: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsw))] -pub fn _mm512_mask_abs_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_abs_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i { unsafe { let abs = _mm512_abs_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, abs, src.as_i16x32())) @@ -43,7 +45,8 @@ pub fn _mm512_mask_abs_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsw))] -pub fn _mm512_maskz_abs_epi16(k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_abs_epi16(k: __mmask32, a: __m512i) -> __m512i { unsafe { let abs = _mm512_abs_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, abs, i16x32::ZERO)) @@ -57,7 +60,8 @@ pub fn _mm512_maskz_abs_epi16(k: __mmask32, a: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsw))] -pub fn _mm256_mask_abs_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_abs_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i { unsafe { let abs = _mm256_abs_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, abs, src.as_i16x16())) @@ -71,7 +75,8 @@ pub fn _mm256_mask_abs_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsw))] -pub fn _mm256_maskz_abs_epi16(k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_abs_epi16(k: __mmask16, a: __m256i) -> __m256i { unsafe { let abs = _mm256_abs_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, abs, i16x16::ZERO)) @@ -85,7 +90,8 @@ pub fn _mm256_maskz_abs_epi16(k: __mmask16, a: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsw))] -pub fn _mm_mask_abs_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_abs_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let abs = _mm_abs_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, abs, src.as_i16x8())) @@ -99,7 +105,8 @@ pub fn _mm_mask_abs_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsw))] -pub fn _mm_maskz_abs_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_abs_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { let abs = _mm_abs_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, abs, i16x8::ZERO)) @@ -113,7 +120,8 @@ pub fn _mm_maskz_abs_epi16(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsb))] -pub fn _mm512_abs_epi8(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_abs_epi8(a: __m512i) -> __m512i { unsafe { let a = a.as_i8x64(); let cmp: i8x64 = simd_gt(a, i8x64::ZERO); @@ -128,7 +136,8 @@ pub fn _mm512_abs_epi8(a: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsb))] -pub fn _mm512_mask_abs_epi8(src: __m512i, k: __mmask64, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_abs_epi8(src: __m512i, k: __mmask64, a: __m512i) -> __m512i { unsafe { let abs = _mm512_abs_epi8(a).as_i8x64(); transmute(simd_select_bitmask(k, abs, src.as_i8x64())) @@ -142,7 +151,8 @@ pub fn _mm512_mask_abs_epi8(src: __m512i, k: __mmask64, a: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsb))] -pub fn _mm512_maskz_abs_epi8(k: __mmask64, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_abs_epi8(k: __mmask64, a: __m512i) -> __m512i { unsafe { let abs = _mm512_abs_epi8(a).as_i8x64(); transmute(simd_select_bitmask(k, abs, i8x64::ZERO)) @@ -156,7 +166,8 @@ pub fn _mm512_maskz_abs_epi8(k: __mmask64, a: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsb))] -pub fn _mm256_mask_abs_epi8(src: __m256i, k: __mmask32, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_abs_epi8(src: __m256i, k: __mmask32, a: __m256i) -> __m256i { unsafe { let abs = _mm256_abs_epi8(a).as_i8x32(); transmute(simd_select_bitmask(k, abs, src.as_i8x32())) @@ -170,7 +181,8 @@ pub fn _mm256_mask_abs_epi8(src: __m256i, k: __mmask32, a: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsb))] -pub fn _mm256_maskz_abs_epi8(k: __mmask32, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_abs_epi8(k: __mmask32, a: __m256i) -> __m256i { unsafe { let abs = _mm256_abs_epi8(a).as_i8x32(); transmute(simd_select_bitmask(k, abs, i8x32::ZERO)) @@ -184,7 +196,8 @@ pub fn _mm256_maskz_abs_epi8(k: __mmask32, a: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsb))] -pub fn _mm_mask_abs_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_abs_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { unsafe { let abs = _mm_abs_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, abs, src.as_i8x16())) @@ -198,7 +211,8 @@ pub fn _mm_mask_abs_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpabsb))] -pub fn _mm_maskz_abs_epi8(k: __mmask16, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_abs_epi8(k: __mmask16, a: __m128i) -> __m128i { unsafe { let abs = _mm_abs_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, abs, i8x16::ZERO)) @@ -212,7 +226,8 @@ pub fn _mm_maskz_abs_epi8(k: __mmask16, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddw))] -pub fn _mm512_add_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_add_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_add(a.as_i16x32(), b.as_i16x32())) } } @@ -223,7 +238,8 @@ pub fn _mm512_add_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddw))] -pub fn _mm512_mask_add_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_add_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_add_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, add, src.as_i16x32())) @@ -237,7 +253,8 @@ pub fn _mm512_mask_add_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddw))] -pub fn _mm512_maskz_add_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_add_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_add_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, add, i16x32::ZERO)) @@ -251,7 +268,8 @@ pub fn _mm512_maskz_add_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddw))] -pub fn _mm256_mask_add_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_add_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_add_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, add, src.as_i16x16())) @@ -265,7 +283,8 @@ pub fn _mm256_mask_add_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddw))] -pub fn _mm256_maskz_add_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_add_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_add_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, add, i16x16::ZERO)) @@ -279,7 +298,8 @@ pub fn _mm256_maskz_add_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddw))] -pub fn _mm_mask_add_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_add_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, add, src.as_i16x8())) @@ -293,7 +313,8 @@ pub fn _mm_mask_add_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddw))] -pub fn _mm_maskz_add_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_add_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, add, i16x8::ZERO)) @@ -307,7 +328,8 @@ pub fn _mm_maskz_add_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddb))] -pub fn _mm512_add_epi8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_add_epi8(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_add(a.as_i8x64(), b.as_i8x64())) } } @@ -318,7 +340,8 @@ pub fn _mm512_add_epi8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddb))] -pub fn _mm512_mask_add_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_add_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_add_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, add, src.as_i8x64())) @@ -332,7 +355,8 @@ pub fn _mm512_mask_add_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddb))] -pub fn _mm512_maskz_add_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_add_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_add_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, add, i8x64::ZERO)) @@ -346,7 +370,8 @@ pub fn _mm512_maskz_add_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddb))] -pub fn _mm256_mask_add_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_add_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_add_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, add, src.as_i8x32())) @@ -360,7 +385,8 @@ pub fn _mm256_mask_add_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddb))] -pub fn _mm256_maskz_add_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_add_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_add_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, add, i8x32::ZERO)) @@ -374,7 +400,8 @@ pub fn _mm256_maskz_add_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddb))] -pub fn _mm_mask_add_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_add_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, add, src.as_i8x16())) @@ -388,7 +415,8 @@ pub fn _mm_mask_add_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddb))] -pub fn _mm_maskz_add_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_add_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, add, i8x16::ZERO)) @@ -402,7 +430,8 @@ pub fn _mm_maskz_add_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusw))] -pub fn _mm512_adds_epu16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_adds_epu16(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_saturating_add(a.as_u16x32(), b.as_u16x32())) } } @@ -413,7 +442,8 @@ pub fn _mm512_adds_epu16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusw))] -pub fn _mm512_mask_adds_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_adds_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_adds_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, add, src.as_u16x32())) @@ -427,7 +457,8 @@ pub fn _mm512_mask_adds_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusw))] -pub fn _mm512_maskz_adds_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_adds_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_adds_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, add, u16x32::ZERO)) @@ -441,7 +472,8 @@ pub fn _mm512_maskz_adds_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusw))] -pub fn _mm256_mask_adds_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_adds_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_adds_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, add, src.as_u16x16())) @@ -455,7 +487,8 @@ pub fn _mm256_mask_adds_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusw))] -pub fn _mm256_maskz_adds_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_adds_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_adds_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, add, u16x16::ZERO)) @@ -469,7 +502,8 @@ pub fn _mm256_maskz_adds_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusw))] -pub fn _mm_mask_adds_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_adds_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_adds_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, add, src.as_u16x8())) @@ -483,7 +517,8 @@ pub fn _mm_mask_adds_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusw))] -pub fn _mm_maskz_adds_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_adds_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_adds_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, add, u16x8::ZERO)) @@ -497,7 +532,8 @@ pub fn _mm_maskz_adds_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusb))] -pub fn _mm512_adds_epu8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_adds_epu8(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_saturating_add(a.as_u8x64(), b.as_u8x64())) } } @@ -508,7 +544,8 @@ pub fn _mm512_adds_epu8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusb))] -pub fn _mm512_mask_adds_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_adds_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_adds_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, add, src.as_u8x64())) @@ -522,7 +559,8 @@ pub fn _mm512_mask_adds_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusb))] -pub fn _mm512_maskz_adds_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_adds_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_adds_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, add, u8x64::ZERO)) @@ -536,7 +574,8 @@ pub fn _mm512_maskz_adds_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusb))] -pub fn _mm256_mask_adds_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_adds_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_adds_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, add, src.as_u8x32())) @@ -550,7 +589,8 @@ pub fn _mm256_mask_adds_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusb))] -pub fn _mm256_maskz_adds_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_adds_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_adds_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, add, u8x32::ZERO)) @@ -564,7 +604,8 @@ pub fn _mm256_maskz_adds_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusb))] -pub fn _mm_mask_adds_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_adds_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_adds_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, add, src.as_u8x16())) @@ -578,7 +619,8 @@ pub fn _mm_mask_adds_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddusb))] -pub fn _mm_maskz_adds_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_adds_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_adds_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, add, u8x16::ZERO)) @@ -592,7 +634,8 @@ pub fn _mm_maskz_adds_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsw))] -pub fn _mm512_adds_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_adds_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_saturating_add(a.as_i16x32(), b.as_i16x32())) } } @@ -603,7 +646,8 @@ pub fn _mm512_adds_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsw))] -pub fn _mm512_mask_adds_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_adds_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_adds_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, add, src.as_i16x32())) @@ -617,7 +661,8 @@ pub fn _mm512_mask_adds_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsw))] -pub fn _mm512_maskz_adds_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_adds_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_adds_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, add, i16x32::ZERO)) @@ -631,7 +676,8 @@ pub fn _mm512_maskz_adds_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsw))] -pub fn _mm256_mask_adds_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_adds_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_adds_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, add, src.as_i16x16())) @@ -645,7 +691,8 @@ pub fn _mm256_mask_adds_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsw))] -pub fn _mm256_maskz_adds_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_adds_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_adds_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, add, i16x16::ZERO)) @@ -659,7 +706,8 @@ pub fn _mm256_maskz_adds_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsw))] -pub fn _mm_mask_adds_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_adds_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_adds_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, add, src.as_i16x8())) @@ -673,7 +721,8 @@ pub fn _mm_mask_adds_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsw))] -pub fn _mm_maskz_adds_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_adds_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_adds_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, add, i16x8::ZERO)) @@ -687,7 +736,8 @@ pub fn _mm_maskz_adds_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsb))] -pub fn _mm512_adds_epi8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_adds_epi8(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_saturating_add(a.as_i8x64(), b.as_i8x64())) } } @@ -698,7 +748,8 @@ pub fn _mm512_adds_epi8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsb))] -pub fn _mm512_mask_adds_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_adds_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_adds_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, add, src.as_i8x64())) @@ -712,7 +763,8 @@ pub fn _mm512_mask_adds_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsb))] -pub fn _mm512_maskz_adds_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_adds_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let add = _mm512_adds_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, add, i8x64::ZERO)) @@ -726,7 +778,8 @@ pub fn _mm512_maskz_adds_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsb))] -pub fn _mm256_mask_adds_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_adds_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_adds_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, add, src.as_i8x32())) @@ -740,7 +793,8 @@ pub fn _mm256_mask_adds_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsb))] -pub fn _mm256_maskz_adds_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_adds_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let add = _mm256_adds_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, add, i8x32::ZERO)) @@ -754,7 +808,8 @@ pub fn _mm256_maskz_adds_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsb))] -pub fn _mm_mask_adds_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_adds_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_adds_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, add, src.as_i8x16())) @@ -768,7 +823,8 @@ pub fn _mm_mask_adds_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpaddsb))] -pub fn _mm_maskz_adds_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_adds_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let add = _mm_adds_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, add, i8x16::ZERO)) @@ -782,7 +838,8 @@ pub fn _mm_maskz_adds_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubw))] -pub fn _mm512_sub_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sub_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_sub(a.as_i16x32(), b.as_i16x32())) } } @@ -793,7 +850,8 @@ pub fn _mm512_sub_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubw))] -pub fn _mm512_mask_sub_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sub_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_sub_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, sub, src.as_i16x32())) @@ -807,7 +865,8 @@ pub fn _mm512_mask_sub_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubw))] -pub fn _mm512_maskz_sub_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sub_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_sub_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, sub, i16x32::ZERO)) @@ -821,7 +880,8 @@ pub fn _mm512_maskz_sub_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubw))] -pub fn _mm256_mask_sub_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sub_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_sub_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, sub, src.as_i16x16())) @@ -835,7 +895,8 @@ pub fn _mm256_mask_sub_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubw))] -pub fn _mm256_maskz_sub_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sub_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_sub_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, sub, i16x16::ZERO)) @@ -849,7 +910,8 @@ pub fn _mm256_maskz_sub_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubw))] -pub fn _mm_mask_sub_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_sub_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, sub, src.as_i16x8())) @@ -863,7 +925,8 @@ pub fn _mm_mask_sub_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubw))] -pub fn _mm_maskz_sub_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_sub_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, sub, i16x8::ZERO)) @@ -877,7 +940,8 @@ pub fn _mm_maskz_sub_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubb))] -pub fn _mm512_sub_epi8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sub_epi8(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_sub(a.as_i8x64(), b.as_i8x64())) } } @@ -888,7 +952,8 @@ pub fn _mm512_sub_epi8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubb))] -pub fn _mm512_mask_sub_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sub_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_sub_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, sub, src.as_i8x64())) @@ -902,7 +967,8 @@ pub fn _mm512_mask_sub_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubb))] -pub fn _mm512_maskz_sub_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sub_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_sub_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, sub, i8x64::ZERO)) @@ -916,7 +982,8 @@ pub fn _mm512_maskz_sub_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubb))] -pub fn _mm256_mask_sub_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sub_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_sub_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, sub, src.as_i8x32())) @@ -930,7 +997,8 @@ pub fn _mm256_mask_sub_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubb))] -pub fn _mm256_maskz_sub_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sub_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_sub_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, sub, i8x32::ZERO)) @@ -944,7 +1012,8 @@ pub fn _mm256_maskz_sub_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubb))] -pub fn _mm_mask_sub_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_sub_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, sub, src.as_i8x16())) @@ -958,7 +1027,8 @@ pub fn _mm_mask_sub_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubb))] -pub fn _mm_maskz_sub_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_sub_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, sub, i8x16::ZERO)) @@ -972,7 +1042,8 @@ pub fn _mm_maskz_sub_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusw))] -pub fn _mm512_subs_epu16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_subs_epu16(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_saturating_sub(a.as_u16x32(), b.as_u16x32())) } } @@ -983,7 +1054,8 @@ pub fn _mm512_subs_epu16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusw))] -pub fn _mm512_mask_subs_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_subs_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_subs_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, sub, src.as_u16x32())) @@ -997,7 +1069,8 @@ pub fn _mm512_mask_subs_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusw))] -pub fn _mm512_maskz_subs_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_subs_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_subs_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, sub, u16x32::ZERO)) @@ -1011,7 +1084,8 @@ pub fn _mm512_maskz_subs_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusw))] -pub fn _mm256_mask_subs_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_subs_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_subs_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, sub, src.as_u16x16())) @@ -1025,7 +1099,8 @@ pub fn _mm256_mask_subs_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusw))] -pub fn _mm256_maskz_subs_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_subs_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_subs_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, sub, u16x16::ZERO)) @@ -1039,7 +1114,8 @@ pub fn _mm256_maskz_subs_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusw))] -pub fn _mm_mask_subs_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_subs_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_subs_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, sub, src.as_u16x8())) @@ -1053,7 +1129,8 @@ pub fn _mm_mask_subs_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusw))] -pub fn _mm_maskz_subs_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_subs_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_subs_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, sub, u16x8::ZERO)) @@ -1067,7 +1144,8 @@ pub fn _mm_maskz_subs_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusb))] -pub fn _mm512_subs_epu8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_subs_epu8(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_saturating_sub(a.as_u8x64(), b.as_u8x64())) } } @@ -1078,7 +1156,8 @@ pub fn _mm512_subs_epu8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusb))] -pub fn _mm512_mask_subs_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_subs_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_subs_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, sub, src.as_u8x64())) @@ -1092,7 +1171,8 @@ pub fn _mm512_mask_subs_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusb))] -pub fn _mm512_maskz_subs_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_subs_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_subs_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, sub, u8x64::ZERO)) @@ -1106,7 +1186,8 @@ pub fn _mm512_maskz_subs_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusb))] -pub fn _mm256_mask_subs_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_subs_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_subs_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, sub, src.as_u8x32())) @@ -1120,7 +1201,8 @@ pub fn _mm256_mask_subs_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusb))] -pub fn _mm256_maskz_subs_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_subs_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_subs_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, sub, u8x32::ZERO)) @@ -1134,7 +1216,8 @@ pub fn _mm256_maskz_subs_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusb))] -pub fn _mm_mask_subs_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_subs_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_subs_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, sub, src.as_u8x16())) @@ -1148,7 +1231,8 @@ pub fn _mm_mask_subs_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubusb))] -pub fn _mm_maskz_subs_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_subs_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_subs_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, sub, u8x16::ZERO)) @@ -1162,7 +1246,8 @@ pub fn _mm_maskz_subs_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsw))] -pub fn _mm512_subs_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_subs_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_saturating_sub(a.as_i16x32(), b.as_i16x32())) } } @@ -1173,7 +1258,8 @@ pub fn _mm512_subs_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsw))] -pub fn _mm512_mask_subs_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_subs_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_subs_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, sub, src.as_i16x32())) @@ -1187,7 +1273,8 @@ pub fn _mm512_mask_subs_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsw))] -pub fn _mm512_maskz_subs_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_subs_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_subs_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, sub, i16x32::ZERO)) @@ -1201,7 +1288,8 @@ pub fn _mm512_maskz_subs_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsw))] -pub fn _mm256_mask_subs_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_subs_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_subs_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, sub, src.as_i16x16())) @@ -1215,7 +1303,8 @@ pub fn _mm256_mask_subs_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsw))] -pub fn _mm256_maskz_subs_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_subs_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_subs_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, sub, i16x16::ZERO)) @@ -1229,7 +1318,8 @@ pub fn _mm256_maskz_subs_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsw))] -pub fn _mm_mask_subs_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_subs_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_subs_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, sub, src.as_i16x8())) @@ -1243,7 +1333,8 @@ pub fn _mm_mask_subs_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsw))] -pub fn _mm_maskz_subs_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_subs_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_subs_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, sub, i16x8::ZERO)) @@ -1257,7 +1348,8 @@ pub fn _mm_maskz_subs_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsb))] -pub fn _mm512_subs_epi8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_subs_epi8(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_saturating_sub(a.as_i8x64(), b.as_i8x64())) } } @@ -1268,7 +1360,8 @@ pub fn _mm512_subs_epi8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsb))] -pub fn _mm512_mask_subs_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_subs_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_subs_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, sub, src.as_i8x64())) @@ -1282,7 +1375,8 @@ pub fn _mm512_mask_subs_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsb))] -pub fn _mm512_maskz_subs_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_subs_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let sub = _mm512_subs_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, sub, i8x64::ZERO)) @@ -1296,7 +1390,8 @@ pub fn _mm512_maskz_subs_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsb))] -pub fn _mm256_mask_subs_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_subs_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_subs_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, sub, src.as_i8x32())) @@ -1310,7 +1405,8 @@ pub fn _mm256_mask_subs_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsb))] -pub fn _mm256_maskz_subs_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_subs_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let sub = _mm256_subs_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, sub, i8x32::ZERO)) @@ -1324,7 +1420,8 @@ pub fn _mm256_maskz_subs_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsb))] -pub fn _mm_mask_subs_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_subs_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_subs_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, sub, src.as_i8x16())) @@ -1338,7 +1435,8 @@ pub fn _mm_mask_subs_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsubsb))] -pub fn _mm_maskz_subs_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_subs_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let sub = _mm_subs_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, sub, i8x16::ZERO)) @@ -1352,7 +1450,8 @@ pub fn _mm_maskz_subs_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhuw))] -pub fn _mm512_mulhi_epu16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mulhi_epu16(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = simd_cast::<_, u32x32>(a.as_u16x32()); let b = simd_cast::<_, u32x32>(b.as_u16x32()); @@ -1368,7 +1467,13 @@ pub fn _mm512_mulhi_epu16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhuw))] -pub fn _mm512_mask_mulhi_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mulhi_epu16( + src: __m512i, + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let mul = _mm512_mulhi_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, mul, src.as_u16x32())) @@ -1382,7 +1487,8 @@ pub fn _mm512_mask_mulhi_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhuw))] -pub fn _mm512_maskz_mulhi_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mulhi_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let mul = _mm512_mulhi_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, mul, u16x32::ZERO)) @@ -1396,7 +1502,13 @@ pub fn _mm512_maskz_mulhi_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhuw))] -pub fn _mm256_mask_mulhi_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mulhi_epu16( + src: __m256i, + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let mul = _mm256_mulhi_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, mul, src.as_u16x16())) @@ -1410,7 +1522,8 @@ pub fn _mm256_mask_mulhi_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhuw))] -pub fn _mm256_maskz_mulhi_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mulhi_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let mul = _mm256_mulhi_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, mul, u16x16::ZERO)) @@ -1424,7 +1537,8 @@ pub fn _mm256_maskz_mulhi_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhuw))] -pub fn _mm_mask_mulhi_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mulhi_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mulhi_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, mul, src.as_u16x8())) @@ -1438,7 +1552,8 @@ pub fn _mm_mask_mulhi_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) - #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhuw))] -pub fn _mm_maskz_mulhi_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mulhi_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mulhi_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, mul, u16x8::ZERO)) @@ -1452,7 +1567,8 @@ pub fn _mm_maskz_mulhi_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhw))] -pub fn _mm512_mulhi_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mulhi_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = simd_cast::<_, i32x32>(a.as_i16x32()); let b = simd_cast::<_, i32x32>(b.as_i16x32()); @@ -1468,7 +1584,13 @@ pub fn _mm512_mulhi_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhw))] -pub fn _mm512_mask_mulhi_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mulhi_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let mul = _mm512_mulhi_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, mul, src.as_i16x32())) @@ -1482,7 +1604,8 @@ pub fn _mm512_mask_mulhi_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhw))] -pub fn _mm512_maskz_mulhi_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mulhi_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let mul = _mm512_mulhi_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, mul, i16x32::ZERO)) @@ -1496,7 +1619,13 @@ pub fn _mm512_maskz_mulhi_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhw))] -pub fn _mm256_mask_mulhi_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mulhi_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let mul = _mm256_mulhi_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, mul, src.as_i16x16())) @@ -1510,7 +1639,8 @@ pub fn _mm256_mask_mulhi_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhw))] -pub fn _mm256_maskz_mulhi_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mulhi_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let mul = _mm256_mulhi_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, mul, i16x16::ZERO)) @@ -1524,7 +1654,8 @@ pub fn _mm256_maskz_mulhi_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhw))] -pub fn _mm_mask_mulhi_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mulhi_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mulhi_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, mul, src.as_i16x8())) @@ -1538,7 +1669,8 @@ pub fn _mm_mask_mulhi_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) - #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmulhw))] -pub fn _mm_maskz_mulhi_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mulhi_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mulhi_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, mul, i16x8::ZERO)) @@ -1647,7 +1779,8 @@ pub fn _mm_maskz_mulhrs_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmullw))] -pub fn _mm512_mullo_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mullo_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_mul(a.as_i16x32(), b.as_i16x32())) } } @@ -1658,7 +1791,13 @@ pub fn _mm512_mullo_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmullw))] -pub fn _mm512_mask_mullo_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mullo_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let mul = _mm512_mullo_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, mul, src.as_i16x32())) @@ -1672,7 +1811,8 @@ pub fn _mm512_mask_mullo_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmullw))] -pub fn _mm512_maskz_mullo_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mullo_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let mul = _mm512_mullo_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, mul, i16x32::ZERO)) @@ -1686,7 +1826,13 @@ pub fn _mm512_maskz_mullo_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmullw))] -pub fn _mm256_mask_mullo_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mullo_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let mul = _mm256_mullo_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, mul, src.as_i16x16())) @@ -1700,7 +1846,8 @@ pub fn _mm256_mask_mullo_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmullw))] -pub fn _mm256_maskz_mullo_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mullo_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let mul = _mm256_mullo_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, mul, i16x16::ZERO)) @@ -1714,7 +1861,8 @@ pub fn _mm256_maskz_mullo_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmullw))] -pub fn _mm_mask_mullo_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mullo_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mullo_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, mul, src.as_i16x8())) @@ -1728,7 +1876,8 @@ pub fn _mm_mask_mullo_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) - #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmullw))] -pub fn _mm_maskz_mullo_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mullo_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let mul = _mm_mullo_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, mul, i16x8::ZERO)) @@ -1742,7 +1891,8 @@ pub fn _mm_maskz_mullo_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuw))] -pub fn _mm512_max_epu16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_max_epu16(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imax(a.as_u16x32(), b.as_u16x32()).as_m512i() } } @@ -1753,7 +1903,8 @@ pub fn _mm512_max_epu16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuw))] -pub fn _mm512_mask_max_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_max_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, max, src.as_u16x32())) @@ -1767,7 +1918,8 @@ pub fn _mm512_mask_max_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuw))] -pub fn _mm512_maskz_max_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_max_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, max, u16x32::ZERO)) @@ -1781,7 +1933,8 @@ pub fn _mm512_maskz_max_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuw))] -pub fn _mm256_mask_max_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_max_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, max, src.as_u16x16())) @@ -1795,7 +1948,8 @@ pub fn _mm256_mask_max_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuw))] -pub fn _mm256_maskz_max_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_max_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, max, u16x16::ZERO)) @@ -1809,7 +1963,8 @@ pub fn _mm256_maskz_max_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuw))] -pub fn _mm_mask_max_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_max_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, max, src.as_u16x8())) @@ -1823,7 +1978,8 @@ pub fn _mm_mask_max_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxuw))] -pub fn _mm_maskz_max_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_max_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, max, u16x8::ZERO)) @@ -1837,7 +1993,8 @@ pub fn _mm_maskz_max_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxub))] -pub fn _mm512_max_epu8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_max_epu8(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imax(a.as_u8x64(), b.as_u8x64()).as_m512i() } } @@ -1848,7 +2005,8 @@ pub fn _mm512_max_epu8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxub))] -pub fn _mm512_mask_max_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_max_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, max, src.as_u8x64())) @@ -1862,7 +2020,8 @@ pub fn _mm512_mask_max_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxub))] -pub fn _mm512_maskz_max_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_max_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, max, u8x64::ZERO)) @@ -1876,7 +2035,8 @@ pub fn _mm512_maskz_max_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxub))] -pub fn _mm256_mask_max_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_max_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, max, src.as_u8x32())) @@ -1890,7 +2050,8 @@ pub fn _mm256_mask_max_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxub))] -pub fn _mm256_maskz_max_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_max_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, max, u8x32::ZERO)) @@ -1904,7 +2065,8 @@ pub fn _mm256_maskz_max_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxub))] -pub fn _mm_mask_max_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_max_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, max, src.as_u8x16())) @@ -1918,7 +2080,8 @@ pub fn _mm_mask_max_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxub))] -pub fn _mm_maskz_max_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_max_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, max, u8x16::ZERO)) @@ -1932,7 +2095,8 @@ pub fn _mm_maskz_max_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsw))] -pub fn _mm512_max_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_max_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imax(a.as_i16x32(), b.as_i16x32()).as_m512i() } } @@ -1943,7 +2107,8 @@ pub fn _mm512_max_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsw))] -pub fn _mm512_mask_max_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_max_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, max, src.as_i16x32())) @@ -1957,7 +2122,8 @@ pub fn _mm512_mask_max_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsw))] -pub fn _mm512_maskz_max_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_max_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, max, i16x32::ZERO)) @@ -1971,7 +2137,8 @@ pub fn _mm512_maskz_max_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsw))] -pub fn _mm256_mask_max_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_max_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, max, src.as_i16x16())) @@ -1985,7 +2152,8 @@ pub fn _mm256_mask_max_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsw))] -pub fn _mm256_maskz_max_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_max_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, max, i16x16::ZERO)) @@ -1999,7 +2167,8 @@ pub fn _mm256_maskz_max_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsw))] -pub fn _mm_mask_max_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_max_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, max, src.as_i16x8())) @@ -2013,7 +2182,8 @@ pub fn _mm_mask_max_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsw))] -pub fn _mm_maskz_max_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_max_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, max, i16x8::ZERO)) @@ -2027,7 +2197,8 @@ pub fn _mm_maskz_max_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsb))] -pub fn _mm512_max_epi8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_max_epi8(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imax(a.as_i8x64(), b.as_i8x64()).as_m512i() } } @@ -2038,7 +2209,8 @@ pub fn _mm512_max_epi8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsb))] -pub fn _mm512_mask_max_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_max_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, max, src.as_i8x64())) @@ -2052,7 +2224,8 @@ pub fn _mm512_mask_max_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsb))] -pub fn _mm512_maskz_max_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_max_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let max = _mm512_max_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, max, i8x64::ZERO)) @@ -2066,7 +2239,8 @@ pub fn _mm512_maskz_max_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsb))] -pub fn _mm256_mask_max_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_max_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, max, src.as_i8x32())) @@ -2080,7 +2254,8 @@ pub fn _mm256_mask_max_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsb))] -pub fn _mm256_maskz_max_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_max_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let max = _mm256_max_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, max, i8x32::ZERO)) @@ -2094,7 +2269,8 @@ pub fn _mm256_maskz_max_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsb))] -pub fn _mm_mask_max_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_max_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, max, src.as_i8x16())) @@ -2108,7 +2284,8 @@ pub fn _mm_mask_max_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaxsb))] -pub fn _mm_maskz_max_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_max_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let max = _mm_max_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, max, i8x16::ZERO)) @@ -2122,7 +2299,8 @@ pub fn _mm_maskz_max_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuw))] -pub fn _mm512_min_epu16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_min_epu16(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imin(a.as_u16x32(), b.as_u16x32()).as_m512i() } } @@ -2133,7 +2311,8 @@ pub fn _mm512_min_epu16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuw))] -pub fn _mm512_mask_min_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_min_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, min, src.as_u16x32())) @@ -2147,7 +2326,8 @@ pub fn _mm512_mask_min_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuw))] -pub fn _mm512_maskz_min_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_min_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, min, u16x32::ZERO)) @@ -2161,7 +2341,8 @@ pub fn _mm512_maskz_min_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuw))] -pub fn _mm256_mask_min_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_min_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, min, src.as_u16x16())) @@ -2175,7 +2356,8 @@ pub fn _mm256_mask_min_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuw))] -pub fn _mm256_maskz_min_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_min_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, min, u16x16::ZERO)) @@ -2189,7 +2371,8 @@ pub fn _mm256_maskz_min_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuw))] -pub fn _mm_mask_min_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_min_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, min, src.as_u16x8())) @@ -2203,7 +2386,8 @@ pub fn _mm_mask_min_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminuw))] -pub fn _mm_maskz_min_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_min_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, min, u16x8::ZERO)) @@ -2217,7 +2401,8 @@ pub fn _mm_maskz_min_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminub))] -pub fn _mm512_min_epu8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_min_epu8(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imin(a.as_u8x64(), b.as_u8x64()).as_m512i() } } @@ -2228,7 +2413,8 @@ pub fn _mm512_min_epu8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminub))] -pub fn _mm512_mask_min_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_min_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, min, src.as_u8x64())) @@ -2242,7 +2428,8 @@ pub fn _mm512_mask_min_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminub))] -pub fn _mm512_maskz_min_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_min_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, min, u8x64::ZERO)) @@ -2256,7 +2443,8 @@ pub fn _mm512_maskz_min_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminub))] -pub fn _mm256_mask_min_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_min_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, min, src.as_u8x32())) @@ -2270,7 +2458,8 @@ pub fn _mm256_mask_min_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminub))] -pub fn _mm256_maskz_min_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_min_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, min, u8x32::ZERO)) @@ -2284,7 +2473,8 @@ pub fn _mm256_maskz_min_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminub))] -pub fn _mm_mask_min_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_min_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, min, src.as_u8x16())) @@ -2298,7 +2488,8 @@ pub fn _mm_mask_min_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminub))] -pub fn _mm_maskz_min_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_min_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, min, u8x16::ZERO)) @@ -2312,7 +2503,8 @@ pub fn _mm_maskz_min_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsw))] -pub fn _mm512_min_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_min_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imin(a.as_i16x32(), b.as_i16x32()).as_m512i() } } @@ -2323,7 +2515,8 @@ pub fn _mm512_min_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsw))] -pub fn _mm512_mask_min_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_min_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, min, src.as_i16x32())) @@ -2337,7 +2530,8 @@ pub fn _mm512_mask_min_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsw))] -pub fn _mm512_maskz_min_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_min_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, min, i16x32::ZERO)) @@ -2351,7 +2545,8 @@ pub fn _mm512_maskz_min_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsw))] -pub fn _mm256_mask_min_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_min_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, min, src.as_i16x16())) @@ -2365,7 +2560,8 @@ pub fn _mm256_mask_min_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsw))] -pub fn _mm256_maskz_min_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_min_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, min, i16x16::ZERO)) @@ -2379,7 +2575,8 @@ pub fn _mm256_maskz_min_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsw))] -pub fn _mm_mask_min_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_min_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, min, src.as_i16x8())) @@ -2393,7 +2590,8 @@ pub fn _mm_mask_min_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsw))] -pub fn _mm_maskz_min_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_min_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, min, i16x8::ZERO)) @@ -2407,7 +2605,8 @@ pub fn _mm_maskz_min_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsb))] -pub fn _mm512_min_epi8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_min_epi8(a: __m512i, b: __m512i) -> __m512i { unsafe { simd_imin(a.as_i8x64(), b.as_i8x64()).as_m512i() } } @@ -2418,7 +2617,8 @@ pub fn _mm512_min_epi8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsb))] -pub fn _mm512_mask_min_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_min_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, min, src.as_i8x64())) @@ -2432,7 +2632,8 @@ pub fn _mm512_mask_min_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsb))] -pub fn _mm512_maskz_min_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_min_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let min = _mm512_min_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, min, i8x64::ZERO)) @@ -2446,7 +2647,8 @@ pub fn _mm512_maskz_min_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsb))] -pub fn _mm256_mask_min_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_min_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, min, src.as_i8x32())) @@ -2460,7 +2662,8 @@ pub fn _mm256_mask_min_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsb))] -pub fn _mm256_maskz_min_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_min_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let min = _mm256_min_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, min, i8x32::ZERO)) @@ -2474,7 +2677,8 @@ pub fn _mm256_maskz_min_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsb))] -pub fn _mm_mask_min_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_min_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, min, src.as_i8x16())) @@ -2488,7 +2692,8 @@ pub fn _mm_mask_min_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpminsb))] -pub fn _mm_maskz_min_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_min_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let min = _mm_min_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, min, i8x16::ZERO)) @@ -2502,7 +2707,8 @@ pub fn _mm_maskz_min_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmplt_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmplt_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_lt(a.as_u16x32(), b.as_u16x32())) } } @@ -2513,7 +2719,8 @@ pub fn _mm512_cmplt_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmplt_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmplt_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epu16_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2524,7 +2731,8 @@ pub fn _mm512_mask_cmplt_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmplt_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmplt_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_lt(a.as_u16x16(), b.as_u16x16())) } } @@ -2535,7 +2743,8 @@ pub fn _mm256_cmplt_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmplt_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmplt_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epu16_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2546,7 +2755,8 @@ pub fn _mm256_mask_cmplt_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmplt_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_lt(a.as_u16x8(), b.as_u16x8())) } } @@ -2557,7 +2767,8 @@ pub fn _mm_cmplt_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmplt_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmplt_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu16_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2568,7 +2779,8 @@ pub fn _mm_mask_cmplt_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmplt_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmplt_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_lt(a.as_u8x64(), b.as_u8x64())) } } @@ -2579,7 +2791,8 @@ pub fn _mm512_cmplt_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmplt_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmplt_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epu8_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2590,7 +2803,8 @@ pub fn _mm512_mask_cmplt_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmplt_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmplt_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_lt(a.as_u8x32(), b.as_u8x32())) } } @@ -2601,7 +2815,8 @@ pub fn _mm256_cmplt_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmplt_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmplt_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epu8_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2612,7 +2827,8 @@ pub fn _mm256_mask_cmplt_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmplt_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_lt(a.as_u8x16(), b.as_u8x16())) } } @@ -2623,7 +2839,8 @@ pub fn _mm_cmplt_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmplt_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmplt_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epu8_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2634,7 +2851,8 @@ pub fn _mm_mask_cmplt_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmplt_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmplt_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_lt(a.as_i16x32(), b.as_i16x32())) } } @@ -2645,7 +2863,8 @@ pub fn _mm512_cmplt_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmplt_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmplt_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epi16_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2656,7 +2875,8 @@ pub fn _mm512_mask_cmplt_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmplt_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmplt_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_lt(a.as_i16x16(), b.as_i16x16())) } } @@ -2667,7 +2887,8 @@ pub fn _mm256_cmplt_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmplt_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmplt_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epi16_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2678,7 +2899,8 @@ pub fn _mm256_mask_cmplt_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmplt_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_lt(a.as_i16x8(), b.as_i16x8())) } } @@ -2689,7 +2911,8 @@ pub fn _mm_cmplt_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmplt_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmplt_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi16_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2700,7 +2923,8 @@ pub fn _mm_mask_cmplt_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmplt_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmplt_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_lt(a.as_i8x64(), b.as_i8x64())) } } @@ -2711,7 +2935,8 @@ pub fn _mm512_cmplt_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmplt_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmplt_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epi8_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2722,7 +2947,8 @@ pub fn _mm512_mask_cmplt_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmplt_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmplt_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_lt(a.as_i8x32(), b.as_i8x32())) } } @@ -2733,7 +2959,8 @@ pub fn _mm256_cmplt_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmplt_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmplt_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epi8_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2744,7 +2971,8 @@ pub fn _mm256_mask_cmplt_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmplt_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmplt_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_lt(a.as_i8x16(), b.as_i8x16())) } } @@ -2755,7 +2983,8 @@ pub fn _mm_cmplt_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmplt_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmplt_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epi8_mask::<_MM_CMPINT_LT>(k1, a, b) } @@ -2766,7 +2995,8 @@ pub fn _mm_mask_cmplt_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpgt_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpgt_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_gt(a.as_u16x32(), b.as_u16x32())) } } @@ -2777,7 +3007,8 @@ pub fn _mm512_cmpgt_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpgt_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpgt_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epu16_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2788,7 +3019,8 @@ pub fn _mm512_mask_cmpgt_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpgt_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_gt(a.as_u16x16(), b.as_u16x16())) } } @@ -2799,7 +3031,8 @@ pub fn _mm256_cmpgt_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpgt_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpgt_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epu16_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2810,7 +3043,8 @@ pub fn _mm256_mask_cmpgt_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpgt_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_gt(a.as_u16x8(), b.as_u16x8())) } } @@ -2821,7 +3055,8 @@ pub fn _mm_cmpgt_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpgt_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpgt_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu16_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2832,7 +3067,8 @@ pub fn _mm_mask_cmpgt_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpgt_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpgt_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_gt(a.as_u8x64(), b.as_u8x64())) } } @@ -2843,7 +3079,8 @@ pub fn _mm512_cmpgt_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpgt_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpgt_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epu8_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2854,7 +3091,8 @@ pub fn _mm512_mask_cmpgt_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpgt_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_gt(a.as_u8x32(), b.as_u8x32())) } } @@ -2865,7 +3103,8 @@ pub fn _mm256_cmpgt_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpgt_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpgt_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epu8_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2876,7 +3115,8 @@ pub fn _mm256_mask_cmpgt_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpgt_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_gt(a.as_u8x16(), b.as_u8x16())) } } @@ -2887,7 +3127,8 @@ pub fn _mm_cmpgt_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpgt_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpgt_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epu8_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2898,7 +3139,8 @@ pub fn _mm_mask_cmpgt_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpgt_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpgt_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_gt(a.as_i16x32(), b.as_i16x32())) } } @@ -2909,7 +3151,8 @@ pub fn _mm512_cmpgt_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpgt_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpgt_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epi16_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2920,7 +3163,8 @@ pub fn _mm512_mask_cmpgt_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpgt_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_gt(a.as_i16x16(), b.as_i16x16())) } } @@ -2931,7 +3175,8 @@ pub fn _mm256_cmpgt_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpgt_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpgt_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epi16_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2942,7 +3187,8 @@ pub fn _mm256_mask_cmpgt_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpgt_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_gt(a.as_i16x8(), b.as_i16x8())) } } @@ -2953,7 +3199,8 @@ pub fn _mm_cmpgt_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpgt_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpgt_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi16_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2964,7 +3211,8 @@ pub fn _mm_mask_cmpgt_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpgt_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpgt_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_gt(a.as_i8x64(), b.as_i8x64())) } } @@ -2975,7 +3223,8 @@ pub fn _mm512_cmpgt_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpgt_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpgt_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epi8_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -2986,7 +3235,8 @@ pub fn _mm512_mask_cmpgt_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpgt_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpgt_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_gt(a.as_i8x32(), b.as_i8x32())) } } @@ -2997,7 +3247,8 @@ pub fn _mm256_cmpgt_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpgt_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpgt_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epi8_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -3008,7 +3259,8 @@ pub fn _mm256_mask_cmpgt_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpgt_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpgt_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_gt(a.as_i8x16(), b.as_i8x16())) } } @@ -3019,7 +3271,8 @@ pub fn _mm_cmpgt_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpgt_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpgt_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epi8_mask::<_MM_CMPINT_NLE>(k1, a, b) } @@ -3030,7 +3283,8 @@ pub fn _mm_mask_cmpgt_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmple_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmple_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_le(a.as_u16x32(), b.as_u16x32())) } } @@ -3041,7 +3295,8 @@ pub fn _mm512_cmple_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmple_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmple_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epu16_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3052,7 +3307,8 @@ pub fn _mm512_mask_cmple_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmple_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmple_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_le(a.as_u16x16(), b.as_u16x16())) } } @@ -3063,7 +3319,8 @@ pub fn _mm256_cmple_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmple_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmple_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epu16_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3074,7 +3331,8 @@ pub fn _mm256_mask_cmple_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmple_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmple_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_le(a.as_u16x8(), b.as_u16x8())) } } @@ -3085,7 +3343,8 @@ pub fn _mm_cmple_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmple_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmple_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu16_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3096,7 +3355,8 @@ pub fn _mm_mask_cmple_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmple_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmple_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_le(a.as_u8x64(), b.as_u8x64())) } } @@ -3107,7 +3367,8 @@ pub fn _mm512_cmple_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmple_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmple_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epu8_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3118,7 +3379,8 @@ pub fn _mm512_mask_cmple_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmple_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmple_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_le(a.as_u8x32(), b.as_u8x32())) } } @@ -3129,7 +3391,8 @@ pub fn _mm256_cmple_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmple_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmple_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epu8_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3140,7 +3403,8 @@ pub fn _mm256_mask_cmple_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmple_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmple_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_le(a.as_u8x16(), b.as_u8x16())) } } @@ -3151,7 +3415,8 @@ pub fn _mm_cmple_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmple_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmple_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epu8_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3162,7 +3427,8 @@ pub fn _mm_mask_cmple_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmple_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmple_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_le(a.as_i16x32(), b.as_i16x32())) } } @@ -3173,7 +3439,8 @@ pub fn _mm512_cmple_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmple_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmple_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epi16_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3184,7 +3451,8 @@ pub fn _mm512_mask_cmple_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmple_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmple_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_le(a.as_i16x16(), b.as_i16x16())) } } @@ -3195,7 +3463,8 @@ pub fn _mm256_cmple_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmple_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmple_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epi16_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3206,7 +3475,8 @@ pub fn _mm256_mask_cmple_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmple_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmple_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_le(a.as_i16x8(), b.as_i16x8())) } } @@ -3217,7 +3487,8 @@ pub fn _mm_cmple_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmple_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmple_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi16_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3228,7 +3499,8 @@ pub fn _mm_mask_cmple_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmple_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmple_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_le(a.as_i8x64(), b.as_i8x64())) } } @@ -3239,7 +3511,8 @@ pub fn _mm512_cmple_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmple_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmple_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epi8_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3250,7 +3523,8 @@ pub fn _mm512_mask_cmple_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmple_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmple_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_le(a.as_i8x32(), b.as_i8x32())) } } @@ -3261,7 +3535,8 @@ pub fn _mm256_cmple_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmple_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmple_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epi8_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3272,7 +3547,8 @@ pub fn _mm256_mask_cmple_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmple_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmple_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_le(a.as_i8x16(), b.as_i8x16())) } } @@ -3283,7 +3559,8 @@ pub fn _mm_cmple_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmple_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmple_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epi8_mask::<_MM_CMPINT_LE>(k1, a, b) } @@ -3294,7 +3571,8 @@ pub fn _mm_mask_cmple_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpge_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpge_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_ge(a.as_u16x32(), b.as_u16x32())) } } @@ -3305,7 +3583,8 @@ pub fn _mm512_cmpge_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpge_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpge_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epu16_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3316,7 +3595,8 @@ pub fn _mm512_mask_cmpge_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpge_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpge_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_ge(a.as_u16x16(), b.as_u16x16())) } } @@ -3327,7 +3607,8 @@ pub fn _mm256_cmpge_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpge_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpge_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epu16_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3338,7 +3619,8 @@ pub fn _mm256_mask_cmpge_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpge_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpge_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_ge(a.as_u16x8(), b.as_u16x8())) } } @@ -3349,7 +3631,8 @@ pub fn _mm_cmpge_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpge_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpge_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu16_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3360,7 +3643,8 @@ pub fn _mm_mask_cmpge_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpge_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpge_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_ge(a.as_u8x64(), b.as_u8x64())) } } @@ -3371,7 +3655,8 @@ pub fn _mm512_cmpge_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpge_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpge_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epu8_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3382,7 +3667,8 @@ pub fn _mm512_mask_cmpge_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpge_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpge_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_ge(a.as_u8x32(), b.as_u8x32())) } } @@ -3393,7 +3679,8 @@ pub fn _mm256_cmpge_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpge_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpge_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epu8_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3404,7 +3691,8 @@ pub fn _mm256_mask_cmpge_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpge_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpge_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_ge(a.as_u8x16(), b.as_u8x16())) } } @@ -3415,7 +3703,8 @@ pub fn _mm_cmpge_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpge_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpge_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epu8_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3426,7 +3715,8 @@ pub fn _mm_mask_cmpge_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpge_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpge_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_ge(a.as_i16x32(), b.as_i16x32())) } } @@ -3437,7 +3727,8 @@ pub fn _mm512_cmpge_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpge_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpge_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epi16_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3448,7 +3739,8 @@ pub fn _mm512_mask_cmpge_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpge_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpge_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_ge(a.as_i16x16(), b.as_i16x16())) } } @@ -3459,7 +3751,8 @@ pub fn _mm256_cmpge_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpge_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpge_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epi16_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3470,7 +3763,8 @@ pub fn _mm256_mask_cmpge_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpge_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpge_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_ge(a.as_i16x8(), b.as_i16x8())) } } @@ -3481,7 +3775,8 @@ pub fn _mm_cmpge_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpge_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpge_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi16_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3492,7 +3787,8 @@ pub fn _mm_mask_cmpge_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpge_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpge_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_ge(a.as_i8x64(), b.as_i8x64())) } } @@ -3503,7 +3799,8 @@ pub fn _mm512_cmpge_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpge_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpge_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epi8_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3514,7 +3811,8 @@ pub fn _mm512_mask_cmpge_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpge_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpge_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_ge(a.as_i8x32(), b.as_i8x32())) } } @@ -3525,7 +3823,8 @@ pub fn _mm256_cmpge_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpge_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpge_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epi8_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3536,7 +3835,8 @@ pub fn _mm256_mask_cmpge_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpge_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpge_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_ge(a.as_i8x16(), b.as_i8x16())) } } @@ -3547,7 +3847,8 @@ pub fn _mm_cmpge_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpge_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpge_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epi8_mask::<_MM_CMPINT_NLT>(k1, a, b) } @@ -3558,7 +3859,8 @@ pub fn _mm_mask_cmpge_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpeq_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpeq_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_eq(a.as_u16x32(), b.as_u16x32())) } } @@ -3569,7 +3871,8 @@ pub fn _mm512_cmpeq_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpeq_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpeq_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epu16_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3580,7 +3883,8 @@ pub fn _mm512_mask_cmpeq_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpeq_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_eq(a.as_u16x16(), b.as_u16x16())) } } @@ -3591,7 +3895,8 @@ pub fn _mm256_cmpeq_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpeq_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpeq_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epu16_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3602,7 +3907,8 @@ pub fn _mm256_mask_cmpeq_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpeq_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_eq(a.as_u16x8(), b.as_u16x8())) } } @@ -3613,7 +3919,8 @@ pub fn _mm_cmpeq_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpeq_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpeq_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu16_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3624,7 +3931,8 @@ pub fn _mm_mask_cmpeq_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpeq_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpeq_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_eq(a.as_u8x64(), b.as_u8x64())) } } @@ -3635,7 +3943,8 @@ pub fn _mm512_cmpeq_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpeq_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpeq_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epu8_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3646,7 +3955,8 @@ pub fn _mm512_mask_cmpeq_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpeq_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_eq(a.as_u8x32(), b.as_u8x32())) } } @@ -3657,7 +3967,8 @@ pub fn _mm256_cmpeq_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpeq_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpeq_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epu8_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3668,7 +3979,8 @@ pub fn _mm256_mask_cmpeq_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpeq_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_eq(a.as_u8x16(), b.as_u8x16())) } } @@ -3679,7 +3991,8 @@ pub fn _mm_cmpeq_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpeq_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpeq_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epu8_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3690,7 +4003,8 @@ pub fn _mm_mask_cmpeq_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpeq_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpeq_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_eq(a.as_i16x32(), b.as_i16x32())) } } @@ -3701,7 +4015,8 @@ pub fn _mm512_cmpeq_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpeq_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpeq_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epi16_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3712,7 +4027,8 @@ pub fn _mm512_mask_cmpeq_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpeq_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_eq(a.as_i16x16(), b.as_i16x16())) } } @@ -3723,7 +4039,8 @@ pub fn _mm256_cmpeq_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpeq_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpeq_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epi16_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3734,7 +4051,8 @@ pub fn _mm256_mask_cmpeq_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpeq_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_eq(a.as_i16x8(), b.as_i16x8())) } } @@ -3745,7 +4063,8 @@ pub fn _mm_cmpeq_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpeq_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpeq_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi16_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3756,7 +4075,8 @@ pub fn _mm_mask_cmpeq_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpeq_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpeq_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_eq(a.as_i8x64(), b.as_i8x64())) } } @@ -3767,7 +4087,8 @@ pub fn _mm512_cmpeq_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpeq_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpeq_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epi8_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3778,7 +4099,8 @@ pub fn _mm512_mask_cmpeq_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpeq_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpeq_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_eq(a.as_i8x32(), b.as_i8x32())) } } @@ -3789,7 +4111,8 @@ pub fn _mm256_cmpeq_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpeq_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpeq_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epi8_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3800,7 +4123,8 @@ pub fn _mm256_mask_cmpeq_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpeq_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpeq_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_eq(a.as_i8x16(), b.as_i8x16())) } } @@ -3811,7 +4135,8 @@ pub fn _mm_cmpeq_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpeq_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpeq_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epi8_mask::<_MM_CMPINT_EQ>(k1, a, b) } @@ -3822,7 +4147,8 @@ pub fn _mm_mask_cmpeq_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmas #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpneq_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpneq_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_ne(a.as_u16x32(), b.as_u16x32())) } } @@ -3833,7 +4159,8 @@ pub fn _mm512_cmpneq_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpneq_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpneq_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epu16_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -3844,7 +4171,8 @@ pub fn _mm512_mask_cmpneq_epu16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> _ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpneq_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpneq_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_ne(a.as_u16x16(), b.as_u16x16())) } } @@ -3855,7 +4183,8 @@ pub fn _mm256_cmpneq_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpneq_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpneq_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epu16_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -3866,7 +4195,8 @@ pub fn _mm256_mask_cmpneq_epu16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> _ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpneq_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpneq_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_ne(a.as_u16x8(), b.as_u16x8())) } } @@ -3877,7 +4207,8 @@ pub fn _mm_cmpneq_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpneq_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpneq_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epu16_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -3888,7 +4219,8 @@ pub fn _mm_mask_cmpneq_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mma #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpneq_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpneq_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_ne(a.as_u8x64(), b.as_u8x64())) } } @@ -3899,7 +4231,8 @@ pub fn _mm512_cmpneq_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpneq_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpneq_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epu8_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -3910,7 +4243,8 @@ pub fn _mm512_mask_cmpneq_epu8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpneq_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpneq_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_ne(a.as_u8x32(), b.as_u8x32())) } } @@ -3921,7 +4255,8 @@ pub fn _mm256_cmpneq_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpneq_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpneq_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epu8_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -3932,7 +4267,8 @@ pub fn _mm256_mask_cmpneq_epu8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpneq_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpneq_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_ne(a.as_u8x16(), b.as_u8x16())) } } @@ -3943,7 +4279,8 @@ pub fn _mm_cmpneq_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpneq_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpneq_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epu8_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -3954,7 +4291,8 @@ pub fn _mm_mask_cmpneq_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mma #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpneq_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpneq_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { simd_bitmask::(simd_ne(a.as_i16x32(), b.as_i16x32())) } } @@ -3965,7 +4303,8 @@ pub fn _mm512_cmpneq_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpneq_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpneq_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { _mm512_mask_cmp_epi16_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -3976,7 +4315,8 @@ pub fn _mm512_mask_cmpneq_epi16_mask(k1: __mmask32, a: __m512i, b: __m512i) -> _ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpneq_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpneq_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { simd_bitmask::(simd_ne(a.as_i16x16(), b.as_i16x16())) } } @@ -3987,7 +4327,8 @@ pub fn _mm256_cmpneq_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpneq_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpneq_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { _mm256_mask_cmp_epi16_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -3998,7 +4339,8 @@ pub fn _mm256_mask_cmpneq_epi16_mask(k1: __mmask16, a: __m256i, b: __m256i) -> _ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpneq_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpneq_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { simd_bitmask::(simd_ne(a.as_i16x8(), b.as_i16x8())) } } @@ -4009,7 +4351,8 @@ pub fn _mm_cmpneq_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpneq_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpneq_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { _mm_mask_cmp_epi16_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -4020,7 +4363,8 @@ pub fn _mm_mask_cmpneq_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mma #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_cmpneq_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmpneq_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { simd_bitmask::(simd_ne(a.as_i8x64(), b.as_i8x64())) } } @@ -4031,7 +4375,8 @@ pub fn _mm512_cmpneq_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm512_mask_cmpneq_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmpneq_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { _mm512_mask_cmp_epi8_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -4042,7 +4387,8 @@ pub fn _mm512_mask_cmpneq_epi8_mask(k1: __mmask64, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_cmpneq_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmpneq_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { simd_bitmask::(simd_ne(a.as_i8x32(), b.as_i8x32())) } } @@ -4053,7 +4399,8 @@ pub fn _mm256_cmpneq_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm256_mask_cmpneq_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmpneq_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { _mm256_mask_cmp_epi8_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -4064,7 +4411,8 @@ pub fn _mm256_mask_cmpneq_epi8_mask(k1: __mmask32, a: __m256i, b: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_cmpneq_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmpneq_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { simd_bitmask::(simd_ne(a.as_i8x16(), b.as_i8x16())) } } @@ -4075,7 +4423,8 @@ pub fn _mm_cmpneq_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpcmp))] -pub fn _mm_mask_cmpneq_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmpneq_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { _mm_mask_cmp_epi8_mask::<_MM_CMPINT_NE>(k1, a, b) } @@ -4087,7 +4436,8 @@ pub fn _mm_mask_cmpneq_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mma #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm512_cmp_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmp_epu16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_u16x32(); @@ -4114,7 +4464,8 @@ pub fn _mm512_cmp_epu16_mask(a: __m512i, b: __m512i) -> __mmask #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm512_mask_cmp_epu16_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmp_epu16_mask( k1: __mmask32, a: __m512i, b: __m512i, @@ -4146,7 +4497,8 @@ pub fn _mm512_mask_cmp_epu16_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm256_cmp_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmp_epu16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_u16x16(); @@ -4173,7 +4525,8 @@ pub fn _mm256_cmp_epu16_mask(a: __m256i, b: __m256i) -> __mmask #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm256_mask_cmp_epu16_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmp_epu16_mask( k1: __mmask16, a: __m256i, b: __m256i, @@ -4205,7 +4558,8 @@ pub fn _mm256_mask_cmp_epu16_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm_cmp_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmp_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_u16x8(); @@ -4232,7 +4586,12 @@ pub fn _mm_cmp_epu16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm_mask_cmp_epu16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmp_epu16_mask( + k1: __mmask8, + a: __m128i, + b: __m128i, +) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_u16x8(); @@ -4260,7 +4619,8 @@ pub fn _mm_mask_cmp_epu16_mask(k1: __mmask8, a: __m128i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm512_cmp_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmp_epu8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_u8x64(); @@ -4287,7 +4647,8 @@ pub fn _mm512_cmp_epu8_mask(a: __m512i, b: __m512i) -> __mmask6 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm512_mask_cmp_epu8_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmp_epu8_mask( k1: __mmask64, a: __m512i, b: __m512i, @@ -4319,7 +4680,8 @@ pub fn _mm512_mask_cmp_epu8_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm256_cmp_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmp_epu8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_u8x32(); @@ -4346,7 +4708,8 @@ pub fn _mm256_cmp_epu8_mask(a: __m256i, b: __m256i) -> __mmask3 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm256_mask_cmp_epu8_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmp_epu8_mask( k1: __mmask32, a: __m256i, b: __m256i, @@ -4378,7 +4741,8 @@ pub fn _mm256_mask_cmp_epu8_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm_cmp_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmp_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_u8x16(); @@ -4405,7 +4769,12 @@ pub fn _mm_cmp_epu8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm_mask_cmp_epu8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmp_epu8_mask( + k1: __mmask16, + a: __m128i, + b: __m128i, +) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_u8x16(); @@ -4433,7 +4802,8 @@ pub fn _mm_mask_cmp_epu8_mask(k1: __mmask16, a: __m128i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm512_cmp_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmp_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_i16x32(); @@ -4460,7 +4830,8 @@ pub fn _mm512_cmp_epi16_mask(a: __m512i, b: __m512i) -> __mmask #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm512_mask_cmp_epi16_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmp_epi16_mask( k1: __mmask32, a: __m512i, b: __m512i, @@ -4492,7 +4863,8 @@ pub fn _mm512_mask_cmp_epi16_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm256_cmp_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmp_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_i16x16(); @@ -4519,7 +4891,8 @@ pub fn _mm256_cmp_epi16_mask(a: __m256i, b: __m256i) -> __mmask #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm256_mask_cmp_epi16_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmp_epi16_mask( k1: __mmask16, a: __m256i, b: __m256i, @@ -4551,7 +4924,8 @@ pub fn _mm256_mask_cmp_epi16_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm_cmp_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmp_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_i16x8(); @@ -4578,7 +4952,12 @@ pub fn _mm_cmp_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm_mask_cmp_epi16_mask(k1: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmp_epi16_mask( + k1: __mmask8, + a: __m128i, + b: __m128i, +) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_i16x8(); @@ -4606,7 +4985,8 @@ pub fn _mm_mask_cmp_epi16_mask(k1: __mmask8, a: __m128i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm512_cmp_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cmp_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_i8x64(); @@ -4633,7 +5013,8 @@ pub fn _mm512_cmp_epi8_mask(a: __m512i, b: __m512i) -> __mmask6 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm512_mask_cmp_epi8_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cmp_epi8_mask( k1: __mmask64, a: __m512i, b: __m512i, @@ -4665,7 +5046,8 @@ pub fn _mm512_mask_cmp_epi8_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm256_cmp_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cmp_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_i8x32(); @@ -4692,7 +5074,8 @@ pub fn _mm256_cmp_epi8_mask(a: __m256i, b: __m256i) -> __mmask3 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm256_mask_cmp_epi8_mask( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cmp_epi8_mask( k1: __mmask32, a: __m256i, b: __m256i, @@ -4724,7 +5107,8 @@ pub fn _mm256_mask_cmp_epi8_mask( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm_cmp_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cmp_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_i8x16(); @@ -4751,7 +5135,12 @@ pub fn _mm_cmp_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpcmp, IMM8 = 0))] -pub fn _mm_mask_cmp_epi8_mask(k1: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cmp_epi8_mask( + k1: __mmask16, + a: __m128i, + b: __m128i, +) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM8, 3); let a = a.as_i8x16(); @@ -4777,7 +5166,8 @@ pub fn _mm_mask_cmp_epi8_mask(k1: __mmask16, a: __m128i, b: __m #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_add_epi16(a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_add_epi16(a: __m256i) -> i16 { unsafe { simd_reduce_add_ordered(a.as_i16x16(), 0) } } @@ -4787,7 +5177,8 @@ pub fn _mm256_reduce_add_epi16(a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_add_epi16(k: __mmask16, a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_add_epi16(k: __mmask16, a: __m256i) -> i16 { unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i16x16(), i16x16::ZERO), 0) } } @@ -4797,7 +5188,8 @@ pub fn _mm256_mask_reduce_add_epi16(k: __mmask16, a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_add_epi16(a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_add_epi16(a: __m128i) -> i16 { unsafe { simd_reduce_add_ordered(a.as_i16x8(), 0) } } @@ -4807,7 +5199,8 @@ pub fn _mm_reduce_add_epi16(a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_add_epi16(k: __mmask8, a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_add_epi16(k: __mmask8, a: __m128i) -> i16 { unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i16x8(), i16x8::ZERO), 0) } } @@ -4817,7 +5210,8 @@ pub fn _mm_mask_reduce_add_epi16(k: __mmask8, a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_add_epi8(a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_add_epi8(a: __m256i) -> i8 { unsafe { simd_reduce_add_ordered(a.as_i8x32(), 0) } } @@ -4827,7 +5221,8 @@ pub fn _mm256_reduce_add_epi8(a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_add_epi8(k: __mmask32, a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_add_epi8(k: __mmask32, a: __m256i) -> i8 { unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i8x32(), i8x32::ZERO), 0) } } @@ -4837,7 +5232,8 @@ pub fn _mm256_mask_reduce_add_epi8(k: __mmask32, a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_add_epi8(a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_add_epi8(a: __m128i) -> i8 { unsafe { simd_reduce_add_ordered(a.as_i8x16(), 0) } } @@ -4847,7 +5243,8 @@ pub fn _mm_reduce_add_epi8(a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_add_epi8(k: __mmask16, a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_add_epi8(k: __mmask16, a: __m128i) -> i8 { unsafe { simd_reduce_add_ordered(simd_select_bitmask(k, a.as_i8x16(), i8x16::ZERO), 0) } } @@ -4857,7 +5254,8 @@ pub fn _mm_mask_reduce_add_epi8(k: __mmask16, a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_and_epi16(a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_and_epi16(a: __m256i) -> i16 { unsafe { simd_reduce_and(a.as_i16x16()) } } @@ -4867,7 +5265,8 @@ pub fn _mm256_reduce_and_epi16(a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_and_epi16(k: __mmask16, a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_and_epi16(k: __mmask16, a: __m256i) -> i16 { unsafe { simd_reduce_and(simd_select_bitmask( k, @@ -4883,7 +5282,8 @@ pub fn _mm256_mask_reduce_and_epi16(k: __mmask16, a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_and_epi16(a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_and_epi16(a: __m128i) -> i16 { unsafe { simd_reduce_and(a.as_i16x8()) } } @@ -4893,7 +5293,8 @@ pub fn _mm_reduce_and_epi16(a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_and_epi16(k: __mmask8, a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_and_epi16(k: __mmask8, a: __m128i) -> i16 { unsafe { simd_reduce_and(simd_select_bitmask( k, @@ -4909,7 +5310,8 @@ pub fn _mm_mask_reduce_and_epi16(k: __mmask8, a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_and_epi8(a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_and_epi8(a: __m256i) -> i8 { unsafe { simd_reduce_and(a.as_i8x32()) } } @@ -4919,7 +5321,8 @@ pub fn _mm256_reduce_and_epi8(a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_and_epi8(k: __mmask32, a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_and_epi8(k: __mmask32, a: __m256i) -> i8 { unsafe { simd_reduce_and(simd_select_bitmask( k, @@ -4935,7 +5338,8 @@ pub fn _mm256_mask_reduce_and_epi8(k: __mmask32, a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_and_epi8(a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_and_epi8(a: __m128i) -> i8 { unsafe { simd_reduce_and(a.as_i8x16()) } } @@ -4945,7 +5349,8 @@ pub fn _mm_reduce_and_epi8(a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_and_epi8(k: __mmask16, a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_and_epi8(k: __mmask16, a: __m128i) -> i8 { unsafe { simd_reduce_and(simd_select_bitmask( k, @@ -4961,7 +5366,8 @@ pub fn _mm_mask_reduce_and_epi8(k: __mmask16, a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_max_epi16(a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_max_epi16(a: __m256i) -> i16 { unsafe { simd_reduce_max(a.as_i16x16()) } } @@ -4971,7 +5377,8 @@ pub fn _mm256_reduce_max_epi16(a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_max_epi16(k: __mmask16, a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_max_epi16(k: __mmask16, a: __m256i) -> i16 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_i16x16(), i16x16::splat(-32768))) } } @@ -4981,7 +5388,8 @@ pub fn _mm256_mask_reduce_max_epi16(k: __mmask16, a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_max_epi16(a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_max_epi16(a: __m128i) -> i16 { unsafe { simd_reduce_max(a.as_i16x8()) } } @@ -4991,7 +5399,8 @@ pub fn _mm_reduce_max_epi16(a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_max_epi16(k: __mmask8, a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_max_epi16(k: __mmask8, a: __m128i) -> i16 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_i16x8(), i16x8::splat(-32768))) } } @@ -5001,7 +5410,8 @@ pub fn _mm_mask_reduce_max_epi16(k: __mmask8, a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_max_epi8(a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_max_epi8(a: __m256i) -> i8 { unsafe { simd_reduce_max(a.as_i8x32()) } } @@ -5011,7 +5421,8 @@ pub fn _mm256_reduce_max_epi8(a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_max_epi8(k: __mmask32, a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_max_epi8(k: __mmask32, a: __m256i) -> i8 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_i8x32(), i8x32::splat(-128))) } } @@ -5021,7 +5432,8 @@ pub fn _mm256_mask_reduce_max_epi8(k: __mmask32, a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_max_epi8(a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_max_epi8(a: __m128i) -> i8 { unsafe { simd_reduce_max(a.as_i8x16()) } } @@ -5031,7 +5443,8 @@ pub fn _mm_reduce_max_epi8(a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_max_epi8(k: __mmask16, a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_max_epi8(k: __mmask16, a: __m128i) -> i8 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_i8x16(), i8x16::splat(-128))) } } @@ -5041,7 +5454,8 @@ pub fn _mm_mask_reduce_max_epi8(k: __mmask16, a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_max_epu16(a: __m256i) -> u16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_max_epu16(a: __m256i) -> u16 { unsafe { simd_reduce_max(a.as_u16x16()) } } @@ -5051,7 +5465,8 @@ pub fn _mm256_reduce_max_epu16(a: __m256i) -> u16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_max_epu16(k: __mmask16, a: __m256i) -> u16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_max_epu16(k: __mmask16, a: __m256i) -> u16 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_u16x16(), u16x16::ZERO)) } } @@ -5061,7 +5476,8 @@ pub fn _mm256_mask_reduce_max_epu16(k: __mmask16, a: __m256i) -> u16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_max_epu16(a: __m128i) -> u16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_max_epu16(a: __m128i) -> u16 { unsafe { simd_reduce_max(a.as_u16x8()) } } @@ -5071,7 +5487,8 @@ pub fn _mm_reduce_max_epu16(a: __m128i) -> u16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_max_epu16(k: __mmask8, a: __m128i) -> u16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_max_epu16(k: __mmask8, a: __m128i) -> u16 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_u16x8(), u16x8::ZERO)) } } @@ -5081,7 +5498,8 @@ pub fn _mm_mask_reduce_max_epu16(k: __mmask8, a: __m128i) -> u16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_max_epu8(a: __m256i) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_max_epu8(a: __m256i) -> u8 { unsafe { simd_reduce_max(a.as_u8x32()) } } @@ -5091,7 +5509,8 @@ pub fn _mm256_reduce_max_epu8(a: __m256i) -> u8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_max_epu8(k: __mmask32, a: __m256i) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_max_epu8(k: __mmask32, a: __m256i) -> u8 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_u8x32(), u8x32::ZERO)) } } @@ -5101,7 +5520,8 @@ pub fn _mm256_mask_reduce_max_epu8(k: __mmask32, a: __m256i) -> u8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_max_epu8(a: __m128i) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_max_epu8(a: __m128i) -> u8 { unsafe { simd_reduce_max(a.as_u8x16()) } } @@ -5111,7 +5531,8 @@ pub fn _mm_reduce_max_epu8(a: __m128i) -> u8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_max_epu8(k: __mmask16, a: __m128i) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_max_epu8(k: __mmask16, a: __m128i) -> u8 { unsafe { simd_reduce_max(simd_select_bitmask(k, a.as_u8x16(), u8x16::ZERO)) } } @@ -5121,7 +5542,8 @@ pub fn _mm_mask_reduce_max_epu8(k: __mmask16, a: __m128i) -> u8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_min_epi16(a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_min_epi16(a: __m256i) -> i16 { unsafe { simd_reduce_min(a.as_i16x16()) } } @@ -5131,7 +5553,8 @@ pub fn _mm256_reduce_min_epi16(a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_min_epi16(k: __mmask16, a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_min_epi16(k: __mmask16, a: __m256i) -> i16 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_i16x16(), i16x16::splat(0x7fff))) } } @@ -5141,7 +5564,8 @@ pub fn _mm256_mask_reduce_min_epi16(k: __mmask16, a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_min_epi16(a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_min_epi16(a: __m128i) -> i16 { unsafe { simd_reduce_min(a.as_i16x8()) } } @@ -5151,7 +5575,8 @@ pub fn _mm_reduce_min_epi16(a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_min_epi16(k: __mmask8, a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_min_epi16(k: __mmask8, a: __m128i) -> i16 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_i16x8(), i16x8::splat(0x7fff))) } } @@ -5161,7 +5586,8 @@ pub fn _mm_mask_reduce_min_epi16(k: __mmask8, a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_min_epi8(a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_min_epi8(a: __m256i) -> i8 { unsafe { simd_reduce_min(a.as_i8x32()) } } @@ -5171,7 +5597,8 @@ pub fn _mm256_reduce_min_epi8(a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_min_epi8(k: __mmask32, a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_min_epi8(k: __mmask32, a: __m256i) -> i8 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_i8x32(), i8x32::splat(0x7f))) } } @@ -5181,7 +5608,8 @@ pub fn _mm256_mask_reduce_min_epi8(k: __mmask32, a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_min_epi8(a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_min_epi8(a: __m128i) -> i8 { unsafe { simd_reduce_min(a.as_i8x16()) } } @@ -5191,7 +5619,8 @@ pub fn _mm_reduce_min_epi8(a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_min_epi8(k: __mmask16, a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_min_epi8(k: __mmask16, a: __m128i) -> i8 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_i8x16(), i8x16::splat(0x7f))) } } @@ -5201,7 +5630,8 @@ pub fn _mm_mask_reduce_min_epi8(k: __mmask16, a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_min_epu16(a: __m256i) -> u16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_min_epu16(a: __m256i) -> u16 { unsafe { simd_reduce_min(a.as_u16x16()) } } @@ -5211,7 +5641,8 @@ pub fn _mm256_reduce_min_epu16(a: __m256i) -> u16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_min_epu16(k: __mmask16, a: __m256i) -> u16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_min_epu16(k: __mmask16, a: __m256i) -> u16 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_u16x16(), u16x16::splat(0xffff))) } } @@ -5221,7 +5652,8 @@ pub fn _mm256_mask_reduce_min_epu16(k: __mmask16, a: __m256i) -> u16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_min_epu16(a: __m128i) -> u16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_min_epu16(a: __m128i) -> u16 { unsafe { simd_reduce_min(a.as_u16x8()) } } @@ -5231,7 +5663,8 @@ pub fn _mm_reduce_min_epu16(a: __m128i) -> u16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_min_epu16(k: __mmask8, a: __m128i) -> u16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_min_epu16(k: __mmask8, a: __m128i) -> u16 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_u16x8(), u16x8::splat(0xffff))) } } @@ -5241,7 +5674,8 @@ pub fn _mm_mask_reduce_min_epu16(k: __mmask8, a: __m128i) -> u16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_min_epu8(a: __m256i) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_min_epu8(a: __m256i) -> u8 { unsafe { simd_reduce_min(a.as_u8x32()) } } @@ -5251,7 +5685,8 @@ pub fn _mm256_reduce_min_epu8(a: __m256i) -> u8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_min_epu8(k: __mmask32, a: __m256i) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_min_epu8(k: __mmask32, a: __m256i) -> u8 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_u8x32(), u8x32::splat(0xff))) } } @@ -5261,7 +5696,8 @@ pub fn _mm256_mask_reduce_min_epu8(k: __mmask32, a: __m256i) -> u8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_min_epu8(a: __m128i) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_min_epu8(a: __m128i) -> u8 { unsafe { simd_reduce_min(a.as_u8x16()) } } @@ -5271,7 +5707,8 @@ pub fn _mm_reduce_min_epu8(a: __m128i) -> u8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_min_epu8(k: __mmask16, a: __m128i) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_min_epu8(k: __mmask16, a: __m128i) -> u8 { unsafe { simd_reduce_min(simd_select_bitmask(k, a.as_u8x16(), u8x16::splat(0xff))) } } @@ -5281,7 +5718,8 @@ pub fn _mm_mask_reduce_min_epu8(k: __mmask16, a: __m128i) -> u8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_mul_epi16(a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_mul_epi16(a: __m256i) -> i16 { unsafe { simd_reduce_mul_ordered(a.as_i16x16(), 1) } } @@ -5291,7 +5729,8 @@ pub fn _mm256_reduce_mul_epi16(a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_mul_epi16(k: __mmask16, a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_mul_epi16(k: __mmask16, a: __m256i) -> i16 { unsafe { simd_reduce_mul_ordered(simd_select_bitmask(k, a.as_i16x16(), i16x16::splat(1)), 1) } } @@ -5301,7 +5740,8 @@ pub fn _mm256_mask_reduce_mul_epi16(k: __mmask16, a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_mul_epi16(a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_mul_epi16(a: __m128i) -> i16 { unsafe { simd_reduce_mul_ordered(a.as_i16x8(), 1) } } @@ -5311,7 +5751,8 @@ pub fn _mm_reduce_mul_epi16(a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_mul_epi16(k: __mmask8, a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_mul_epi16(k: __mmask8, a: __m128i) -> i16 { unsafe { simd_reduce_mul_ordered(simd_select_bitmask(k, a.as_i16x8(), i16x8::splat(1)), 1) } } @@ -5321,7 +5762,8 @@ pub fn _mm_mask_reduce_mul_epi16(k: __mmask8, a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_mul_epi8(a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_mul_epi8(a: __m256i) -> i8 { unsafe { simd_reduce_mul_ordered(a.as_i8x32(), 1) } } @@ -5331,7 +5773,8 @@ pub fn _mm256_reduce_mul_epi8(a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_mul_epi8(k: __mmask32, a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_mul_epi8(k: __mmask32, a: __m256i) -> i8 { unsafe { simd_reduce_mul_ordered(simd_select_bitmask(k, a.as_i8x32(), i8x32::splat(1)), 1) } } @@ -5341,7 +5784,8 @@ pub fn _mm256_mask_reduce_mul_epi8(k: __mmask32, a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_mul_epi8(a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_mul_epi8(a: __m128i) -> i8 { unsafe { simd_reduce_mul_ordered(a.as_i8x16(), 1) } } @@ -5351,7 +5795,8 @@ pub fn _mm_reduce_mul_epi8(a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_mul_epi8(k: __mmask16, a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_mul_epi8(k: __mmask16, a: __m128i) -> i8 { unsafe { simd_reduce_mul_ordered(simd_select_bitmask(k, a.as_i8x16(), i8x16::splat(1)), 1) } } @@ -5361,7 +5806,8 @@ pub fn _mm_mask_reduce_mul_epi8(k: __mmask16, a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_or_epi16(a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_or_epi16(a: __m256i) -> i16 { unsafe { simd_reduce_or(a.as_i16x16()) } } @@ -5371,7 +5817,8 @@ pub fn _mm256_reduce_or_epi16(a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_or_epi16(k: __mmask16, a: __m256i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_or_epi16(k: __mmask16, a: __m256i) -> i16 { unsafe { simd_reduce_or(simd_select_bitmask(k, a.as_i16x16(), i16x16::ZERO)) } } @@ -5381,7 +5828,8 @@ pub fn _mm256_mask_reduce_or_epi16(k: __mmask16, a: __m256i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_or_epi16(a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_or_epi16(a: __m128i) -> i16 { unsafe { simd_reduce_or(a.as_i16x8()) } } @@ -5391,7 +5839,8 @@ pub fn _mm_reduce_or_epi16(a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_or_epi16(k: __mmask8, a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_or_epi16(k: __mmask8, a: __m128i) -> i16 { unsafe { simd_reduce_or(simd_select_bitmask(k, a.as_i16x8(), i16x8::ZERO)) } } @@ -5401,7 +5850,8 @@ pub fn _mm_mask_reduce_or_epi16(k: __mmask8, a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_reduce_or_epi8(a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_or_epi8(a: __m256i) -> i8 { unsafe { simd_reduce_or(a.as_i8x32()) } } @@ -5411,7 +5861,8 @@ pub fn _mm256_reduce_or_epi8(a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_reduce_or_epi8(k: __mmask32, a: __m256i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_reduce_or_epi8(k: __mmask32, a: __m256i) -> i8 { unsafe { simd_reduce_or(simd_select_bitmask(k, a.as_i8x32(), i8x32::ZERO)) } } @@ -5421,7 +5872,8 @@ pub fn _mm256_mask_reduce_or_epi8(k: __mmask32, a: __m256i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_reduce_or_epi8(a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_or_epi8(a: __m128i) -> i8 { unsafe { simd_reduce_or(a.as_i8x16()) } } @@ -5431,7 +5883,8 @@ pub fn _mm_reduce_or_epi8(a: __m128i) -> i8 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_reduce_or_epi8(k: __mmask16, a: __m128i) -> i8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_reduce_or_epi8(k: __mmask16, a: __m128i) -> i8 { unsafe { simd_reduce_or(simd_select_bitmask(k, a.as_i8x16(), i8x16::ZERO)) } } @@ -5442,7 +5895,8 @@ pub fn _mm_mask_reduce_or_epi8(k: __mmask16, a: __m128i) -> i8 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu16 -pub unsafe fn _mm512_loadu_epi16(mem_addr: *const i16) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_loadu_epi16(mem_addr: *const i16) -> __m512i { ptr::read_unaligned(mem_addr as *const __m512i) } @@ -5453,7 +5907,8 @@ pub unsafe fn _mm512_loadu_epi16(mem_addr: *const i16) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu16 -pub unsafe fn _mm256_loadu_epi16(mem_addr: *const i16) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu_epi16(mem_addr: *const i16) -> __m256i { ptr::read_unaligned(mem_addr as *const __m256i) } @@ -5464,7 +5919,8 @@ pub unsafe fn _mm256_loadu_epi16(mem_addr: *const i16) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu16 -pub unsafe fn _mm_loadu_epi16(mem_addr: *const i16) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_epi16(mem_addr: *const i16) -> __m128i { ptr::read_unaligned(mem_addr as *const __m128i) } @@ -5475,7 +5931,8 @@ pub unsafe fn _mm_loadu_epi16(mem_addr: *const i16) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu8 -pub unsafe fn _mm512_loadu_epi8(mem_addr: *const i8) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_loadu_epi8(mem_addr: *const i8) -> __m512i { ptr::read_unaligned(mem_addr as *const __m512i) } @@ -5486,7 +5943,8 @@ pub unsafe fn _mm512_loadu_epi8(mem_addr: *const i8) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu8 -pub unsafe fn _mm256_loadu_epi8(mem_addr: *const i8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu_epi8(mem_addr: *const i8) -> __m256i { ptr::read_unaligned(mem_addr as *const __m256i) } @@ -5497,7 +5955,8 @@ pub unsafe fn _mm256_loadu_epi8(mem_addr: *const i8) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu8 -pub unsafe fn _mm_loadu_epi8(mem_addr: *const i8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_epi8(mem_addr: *const i8) -> __m128i { ptr::read_unaligned(mem_addr as *const __m128i) } @@ -5508,7 +5967,8 @@ pub unsafe fn _mm_loadu_epi8(mem_addr: *const i8) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu16 -pub unsafe fn _mm512_storeu_epi16(mem_addr: *mut i16, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_storeu_epi16(mem_addr: *mut i16, a: __m512i) { ptr::write_unaligned(mem_addr as *mut __m512i, a); } @@ -5519,7 +5979,8 @@ pub unsafe fn _mm512_storeu_epi16(mem_addr: *mut i16, a: __m512i) { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu16 -pub unsafe fn _mm256_storeu_epi16(mem_addr: *mut i16, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu_epi16(mem_addr: *mut i16, a: __m256i) { ptr::write_unaligned(mem_addr as *mut __m256i, a); } @@ -5530,7 +5991,8 @@ pub unsafe fn _mm256_storeu_epi16(mem_addr: *mut i16, a: __m256i) { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu16 -pub unsafe fn _mm_storeu_epi16(mem_addr: *mut i16, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_epi16(mem_addr: *mut i16, a: __m128i) { ptr::write_unaligned(mem_addr as *mut __m128i, a); } @@ -5541,7 +6003,8 @@ pub unsafe fn _mm_storeu_epi16(mem_addr: *mut i16, a: __m128i) { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu8 -pub unsafe fn _mm512_storeu_epi8(mem_addr: *mut i8, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_storeu_epi8(mem_addr: *mut i8, a: __m512i) { ptr::write_unaligned(mem_addr as *mut __m512i, a); } @@ -5552,7 +6015,8 @@ pub unsafe fn _mm512_storeu_epi8(mem_addr: *mut i8, a: __m512i) { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu8 -pub unsafe fn _mm256_storeu_epi8(mem_addr: *mut i8, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu_epi8(mem_addr: *mut i8, a: __m256i) { ptr::write_unaligned(mem_addr as *mut __m256i, a); } @@ -5563,7 +6027,8 @@ pub unsafe fn _mm256_storeu_epi8(mem_addr: *mut i8, a: __m256i) { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovups))] //should be vmovdqu8 -pub unsafe fn _mm_storeu_epi8(mem_addr: *mut i8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_epi8(mem_addr: *mut i8, a: __m128i) { ptr::write_unaligned(mem_addr as *mut __m128i, a); } @@ -5576,7 +6041,12 @@ pub unsafe fn _mm_storeu_epi8(mem_addr: *mut i8, a: __m128i) { #[target_feature(enable = "avx512bw")] #[cfg_attr(test, assert_instr(vmovdqu16))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_loadu_epi16(src: __m512i, k: __mmask32, mem_addr: *const i16) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_loadu_epi16( + src: __m512i, + k: __mmask32, + mem_addr: *const i16, +) -> __m512i { let mask = simd_select_bitmask(k, i16x32::splat(!0), i16x32::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i16x32()).as_m512i() } @@ -5590,7 +6060,8 @@ pub unsafe fn _mm512_mask_loadu_epi16(src: __m512i, k: __mmask32, mem_addr: *con #[target_feature(enable = "avx512bw")] #[cfg_attr(test, assert_instr(vmovdqu16))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_loadu_epi16(k: __mmask32, mem_addr: *const i16) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_loadu_epi16(k: __mmask32, mem_addr: *const i16) -> __m512i { _mm512_mask_loadu_epi16(_mm512_setzero_si512(), k, mem_addr) } @@ -5603,7 +6074,12 @@ pub unsafe fn _mm512_maskz_loadu_epi16(k: __mmask32, mem_addr: *const i16) -> __ #[target_feature(enable = "avx512bw")] #[cfg_attr(test, assert_instr(vmovdqu8))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_loadu_epi8(src: __m512i, k: __mmask64, mem_addr: *const i8) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_loadu_epi8( + src: __m512i, + k: __mmask64, + mem_addr: *const i8, +) -> __m512i { let mask = simd_select_bitmask(k, i8x64::splat(!0), i8x64::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i8x64()).as_m512i() } @@ -5617,7 +6093,8 @@ pub unsafe fn _mm512_mask_loadu_epi8(src: __m512i, k: __mmask64, mem_addr: *cons #[target_feature(enable = "avx512bw")] #[cfg_attr(test, assert_instr(vmovdqu8))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_maskz_loadu_epi8(k: __mmask64, mem_addr: *const i8) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_maskz_loadu_epi8(k: __mmask64, mem_addr: *const i8) -> __m512i { _mm512_mask_loadu_epi8(_mm512_setzero_si512(), k, mem_addr) } @@ -5630,7 +6107,12 @@ pub unsafe fn _mm512_maskz_loadu_epi8(k: __mmask64, mem_addr: *const i8) -> __m5 #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu16))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_loadu_epi16(src: __m256i, k: __mmask16, mem_addr: *const i16) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_loadu_epi16( + src: __m256i, + k: __mmask16, + mem_addr: *const i16, +) -> __m256i { let mask = simd_select_bitmask(k, i16x16::splat(!0), i16x16::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i16x16()).as_m256i() } @@ -5644,7 +6126,8 @@ pub unsafe fn _mm256_mask_loadu_epi16(src: __m256i, k: __mmask16, mem_addr: *con #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu16))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_loadu_epi16(k: __mmask16, mem_addr: *const i16) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_loadu_epi16(k: __mmask16, mem_addr: *const i16) -> __m256i { _mm256_mask_loadu_epi16(_mm256_setzero_si256(), k, mem_addr) } @@ -5657,7 +6140,12 @@ pub unsafe fn _mm256_maskz_loadu_epi16(k: __mmask16, mem_addr: *const i16) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu8))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_loadu_epi8(src: __m256i, k: __mmask32, mem_addr: *const i8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_loadu_epi8( + src: __m256i, + k: __mmask32, + mem_addr: *const i8, +) -> __m256i { let mask = simd_select_bitmask(k, i8x32::splat(!0), i8x32::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i8x32()).as_m256i() } @@ -5671,7 +6159,8 @@ pub unsafe fn _mm256_mask_loadu_epi8(src: __m256i, k: __mmask32, mem_addr: *cons #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu8))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_maskz_loadu_epi8(k: __mmask32, mem_addr: *const i8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_maskz_loadu_epi8(k: __mmask32, mem_addr: *const i8) -> __m256i { _mm256_mask_loadu_epi8(_mm256_setzero_si256(), k, mem_addr) } @@ -5684,7 +6173,12 @@ pub unsafe fn _mm256_maskz_loadu_epi8(k: __mmask32, mem_addr: *const i8) -> __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu16))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_loadu_epi16(src: __m128i, k: __mmask8, mem_addr: *const i16) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_loadu_epi16( + src: __m128i, + k: __mmask8, + mem_addr: *const i16, +) -> __m128i { let mask = simd_select_bitmask(k, i16x8::splat(!0), i16x8::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i16x8()).as_m128i() } @@ -5698,7 +6192,8 @@ pub unsafe fn _mm_mask_loadu_epi16(src: __m128i, k: __mmask8, mem_addr: *const i #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu16))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_loadu_epi16(k: __mmask8, mem_addr: *const i16) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_loadu_epi16(k: __mmask8, mem_addr: *const i16) -> __m128i { _mm_mask_loadu_epi16(_mm_setzero_si128(), k, mem_addr) } @@ -5711,7 +6206,12 @@ pub unsafe fn _mm_maskz_loadu_epi16(k: __mmask8, mem_addr: *const i16) -> __m128 #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu8))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_loadu_epi8(src: __m128i, k: __mmask16, mem_addr: *const i8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_loadu_epi8( + src: __m128i, + k: __mmask16, + mem_addr: *const i8, +) -> __m128i { let mask = simd_select_bitmask(k, i8x16::splat(!0), i8x16::ZERO); simd_masked_load!(SimdAlign::Unaligned, mask, mem_addr, src.as_i8x16()).as_m128i() } @@ -5725,7 +6225,8 @@ pub unsafe fn _mm_mask_loadu_epi8(src: __m128i, k: __mmask16, mem_addr: *const i #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu8))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_maskz_loadu_epi8(k: __mmask16, mem_addr: *const i8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_maskz_loadu_epi8(k: __mmask16, mem_addr: *const i8) -> __m128i { _mm_mask_loadu_epi8(_mm_setzero_si128(), k, mem_addr) } @@ -5737,7 +6238,8 @@ pub unsafe fn _mm_maskz_loadu_epi8(k: __mmask16, mem_addr: *const i8) -> __m128i #[target_feature(enable = "avx512bw")] #[cfg_attr(test, assert_instr(vmovdqu16))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_storeu_epi16(mem_addr: *mut i16, mask: __mmask32, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_storeu_epi16(mem_addr: *mut i16, mask: __mmask32, a: __m512i) { let mask = simd_select_bitmask(mask, i16x32::splat(!0), i16x32::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i16x32()); } @@ -5750,7 +6252,8 @@ pub unsafe fn _mm512_mask_storeu_epi16(mem_addr: *mut i16, mask: __mmask32, a: _ #[target_feature(enable = "avx512bw")] #[cfg_attr(test, assert_instr(vmovdqu8))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm512_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask64, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask64, a: __m512i) { let mask = simd_select_bitmask(mask, i8x64::splat(!0), i8x64::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i8x64()); } @@ -5763,7 +6266,8 @@ pub unsafe fn _mm512_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask64, a: __m #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu16))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_storeu_epi16(mem_addr: *mut i16, mask: __mmask16, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_storeu_epi16(mem_addr: *mut i16, mask: __mmask16, a: __m256i) { let mask = simd_select_bitmask(mask, i16x16::splat(!0), i16x16::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i16x16()); } @@ -5776,7 +6280,8 @@ pub unsafe fn _mm256_mask_storeu_epi16(mem_addr: *mut i16, mask: __mmask16, a: _ #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu8))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm256_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask32, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask32, a: __m256i) { let mask = simd_select_bitmask(mask, i8x32::splat(!0), i8x32::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i8x32()); } @@ -5789,7 +6294,8 @@ pub unsafe fn _mm256_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask32, a: __m #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu16))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_storeu_epi16(mem_addr: *mut i16, mask: __mmask8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_storeu_epi16(mem_addr: *mut i16, mask: __mmask8, a: __m128i) { let mask = simd_select_bitmask(mask, i16x8::splat(!0), i16x8::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i16x8()); } @@ -5802,7 +6308,8 @@ pub unsafe fn _mm_mask_storeu_epi16(mem_addr: *mut i16, mask: __mmask8, a: __m12 #[target_feature(enable = "avx512bw,avx512vl")] #[cfg_attr(test, assert_instr(vmovdqu8))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _mm_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask16, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask16, a: __m128i) { let mask = simd_select_bitmask(mask, i8x16::splat(!0), i8x16::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, a.as_i8x16()); } @@ -5814,7 +6321,8 @@ pub unsafe fn _mm_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask16, a: __m128 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { let r: i32x32 = simd_mul(simd_cast(a.as_i16x32()), simd_cast(b.as_i16x32())); let even: i32x16 = simd_shuffle!( @@ -5838,7 +6346,8 @@ pub fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let madd = _mm512_madd_epi16(a, b).as_i32x16(); transmute(simd_select_bitmask(k, madd, src.as_i32x16())) @@ -5852,7 +6361,8 @@ pub fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let madd = _mm512_madd_epi16(a, b).as_i32x16(); transmute(simd_select_bitmask(k, madd, i32x16::ZERO)) @@ -5866,7 +6376,8 @@ pub fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let madd = _mm256_madd_epi16(a, b).as_i32x8(); transmute(simd_select_bitmask(k, madd, src.as_i32x8())) @@ -5880,7 +6391,8 @@ pub fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let madd = _mm256_madd_epi16(a, b).as_i32x8(); transmute(simd_select_bitmask(k, madd, i32x8::ZERO)) @@ -5894,7 +6406,8 @@ pub fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let madd = _mm_madd_epi16(a, b).as_i32x4(); transmute(simd_select_bitmask(k, madd, src.as_i32x4())) @@ -5908,7 +6421,8 @@ pub fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -pub fn _mm_maskz_madd_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_madd_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let madd = _mm_madd_epi16(a, b).as_i32x4(); transmute(simd_select_bitmask(k, madd, i32x4::ZERO)) @@ -6397,7 +6911,8 @@ pub fn _mm_maskz_packus_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgw))] -pub fn _mm512_avg_epu16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_avg_epu16(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = simd_cast::<_, u32x32>(a.as_u16x32()); let b = simd_cast::<_, u32x32>(b.as_u16x32()); @@ -6413,7 +6928,8 @@ pub fn _mm512_avg_epu16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgw))] -pub fn _mm512_mask_avg_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_avg_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let avg = _mm512_avg_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, avg, src.as_u16x32())) @@ -6427,7 +6943,8 @@ pub fn _mm512_mask_avg_epu16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgw))] -pub fn _mm512_maskz_avg_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_avg_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let avg = _mm512_avg_epu16(a, b).as_u16x32(); transmute(simd_select_bitmask(k, avg, u16x32::ZERO)) @@ -6441,7 +6958,8 @@ pub fn _mm512_maskz_avg_epu16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgw))] -pub fn _mm256_mask_avg_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_avg_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let avg = _mm256_avg_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, avg, src.as_u16x16())) @@ -6455,7 +6973,8 @@ pub fn _mm256_mask_avg_epu16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgw))] -pub fn _mm256_maskz_avg_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_avg_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let avg = _mm256_avg_epu16(a, b).as_u16x16(); transmute(simd_select_bitmask(k, avg, u16x16::ZERO)) @@ -6469,7 +6988,8 @@ pub fn _mm256_maskz_avg_epu16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgw))] -pub fn _mm_mask_avg_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_avg_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let avg = _mm_avg_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, avg, src.as_u16x8())) @@ -6483,7 +7003,8 @@ pub fn _mm_mask_avg_epu16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgw))] -pub fn _mm_maskz_avg_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_avg_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let avg = _mm_avg_epu16(a, b).as_u16x8(); transmute(simd_select_bitmask(k, avg, u16x8::ZERO)) @@ -6497,7 +7018,8 @@ pub fn _mm_maskz_avg_epu16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgb))] -pub fn _mm512_avg_epu8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_avg_epu8(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = simd_cast::<_, u16x64>(a.as_u8x64()); let b = simd_cast::<_, u16x64>(b.as_u8x64()); @@ -6513,7 +7035,8 @@ pub fn _mm512_avg_epu8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgb))] -pub fn _mm512_mask_avg_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_avg_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let avg = _mm512_avg_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, avg, src.as_u8x64())) @@ -6527,7 +7050,8 @@ pub fn _mm512_mask_avg_epu8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgb))] -pub fn _mm512_maskz_avg_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_avg_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let avg = _mm512_avg_epu8(a, b).as_u8x64(); transmute(simd_select_bitmask(k, avg, u8x64::ZERO)) @@ -6541,7 +7065,8 @@ pub fn _mm512_maskz_avg_epu8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgb))] -pub fn _mm256_mask_avg_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_avg_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let avg = _mm256_avg_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, avg, src.as_u8x32())) @@ -6555,7 +7080,8 @@ pub fn _mm256_mask_avg_epu8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgb))] -pub fn _mm256_maskz_avg_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_avg_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let avg = _mm256_avg_epu8(a, b).as_u8x32(); transmute(simd_select_bitmask(k, avg, u8x32::ZERO)) @@ -6569,7 +7095,8 @@ pub fn _mm256_maskz_avg_epu8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgb))] -pub fn _mm_mask_avg_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_avg_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let avg = _mm_avg_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, avg, src.as_u8x16())) @@ -6583,7 +7110,8 @@ pub fn _mm_mask_avg_epu8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpavgb))] -pub fn _mm_maskz_avg_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_avg_epu8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let avg = _mm_avg_epu8(a, b).as_u8x16(); transmute(simd_select_bitmask(k, avg, u8x16::ZERO)) @@ -6693,7 +7221,8 @@ pub fn _mm_maskz_sll_epi16(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllw, IMM8 = 5))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_slli_epi16(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_slli_epi16(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 16 { @@ -6712,7 +7241,12 @@ pub fn _mm512_slli_epi16(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_slli_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_slli_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = if IMM8 >= 16 { @@ -6732,7 +7266,8 @@ pub fn _mm512_mask_slli_epi16(src: __m512i, k: __mmask32, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_slli_epi16(k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_slli_epi16(k: __mmask32, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 16 { @@ -6752,7 +7287,12 @@ pub fn _mm512_maskz_slli_epi16(k: __mmask32, a: __m512i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_slli_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_slli_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = if IMM8 >= 16 { @@ -6772,7 +7312,8 @@ pub fn _mm256_mask_slli_epi16(src: __m256i, k: __mmask16, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_slli_epi16(k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_slli_epi16(k: __mmask16, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 16 { @@ -6792,7 +7333,12 @@ pub fn _mm256_maskz_slli_epi16(k: __mmask16, a: __m256i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_slli_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_slli_epi16( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = if IMM8 >= 16 { @@ -6812,7 +7358,8 @@ pub fn _mm_mask_slli_epi16(src: __m128i, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_slli_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_slli_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 16 { @@ -6831,7 +7378,8 @@ pub fn _mm_maskz_slli_epi16(k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvw))] -pub fn _mm512_sllv_epi16(a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sllv_epi16(a: __m512i, count: __m512i) -> __m512i { unsafe { let count = count.as_u16x32(); let no_overflow: u16x32 = simd_lt(count, u16x32::splat(u16::BITS as u16)); @@ -6847,7 +7395,13 @@ pub fn _mm512_sllv_epi16(a: __m512i, count: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvw))] -pub fn _mm512_mask_sllv_epi16(src: __m512i, k: __mmask32, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sllv_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, + count: __m512i, +) -> __m512i { unsafe { let shf = _mm512_sllv_epi16(a, count).as_i16x32(); transmute(simd_select_bitmask(k, shf, src.as_i16x32())) @@ -6861,7 +7415,8 @@ pub fn _mm512_mask_sllv_epi16(src: __m512i, k: __mmask32, a: __m512i, count: __m #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvw))] -pub fn _mm512_maskz_sllv_epi16(k: __mmask32, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sllv_epi16(k: __mmask32, a: __m512i, count: __m512i) -> __m512i { unsafe { let shf = _mm512_sllv_epi16(a, count).as_i16x32(); transmute(simd_select_bitmask(k, shf, i16x32::ZERO)) @@ -6875,7 +7430,8 @@ pub fn _mm512_maskz_sllv_epi16(k: __mmask32, a: __m512i, count: __m512i) -> __m5 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvw))] -pub fn _mm256_sllv_epi16(a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sllv_epi16(a: __m256i, count: __m256i) -> __m256i { unsafe { let count = count.as_u16x16(); let no_overflow: u16x16 = simd_lt(count, u16x16::splat(u16::BITS as u16)); @@ -6891,7 +7447,13 @@ pub fn _mm256_sllv_epi16(a: __m256i, count: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvw))] -pub fn _mm256_mask_sllv_epi16(src: __m256i, k: __mmask16, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sllv_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, + count: __m256i, +) -> __m256i { unsafe { let shf = _mm256_sllv_epi16(a, count).as_i16x16(); transmute(simd_select_bitmask(k, shf, src.as_i16x16())) @@ -6905,7 +7467,8 @@ pub fn _mm256_mask_sllv_epi16(src: __m256i, k: __mmask16, a: __m256i, count: __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvw))] -pub fn _mm256_maskz_sllv_epi16(k: __mmask16, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sllv_epi16(k: __mmask16, a: __m256i, count: __m256i) -> __m256i { unsafe { let shf = _mm256_sllv_epi16(a, count).as_i16x16(); transmute(simd_select_bitmask(k, shf, i16x16::ZERO)) @@ -6919,7 +7482,8 @@ pub fn _mm256_maskz_sllv_epi16(k: __mmask16, a: __m256i, count: __m256i) -> __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvw))] -pub fn _mm_sllv_epi16(a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sllv_epi16(a: __m128i, count: __m128i) -> __m128i { unsafe { let count = count.as_u16x8(); let no_overflow: u16x8 = simd_lt(count, u16x8::splat(u16::BITS as u16)); @@ -6935,7 +7499,8 @@ pub fn _mm_sllv_epi16(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvw))] -pub fn _mm_mask_sllv_epi16(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sllv_epi16(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_sllv_epi16(a, count).as_i16x8(); transmute(simd_select_bitmask(k, shf, src.as_i16x8())) @@ -6949,7 +7514,8 @@ pub fn _mm_mask_sllv_epi16(src: __m128i, k: __mmask8, a: __m128i, count: __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsllvw))] -pub fn _mm_maskz_sllv_epi16(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sllv_epi16(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_sllv_epi16(a, count).as_i16x8(); transmute(simd_select_bitmask(k, shf, i16x8::ZERO)) @@ -7059,7 +7625,8 @@ pub fn _mm_maskz_srl_epi16(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlw, IMM8 = 5))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_srli_epi16(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srli_epi16(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); if IMM8 >= 16 { @@ -7078,7 +7645,12 @@ pub fn _mm512_srli_epi16(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_srli_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srli_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = if IMM8 >= 16 { @@ -7098,7 +7670,8 @@ pub fn _mm512_mask_srli_epi16(src: __m512i, k: __mmask32, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_srli_epi16(k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srli_epi16(k: __mmask32, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); //imm8 should be u32, it seems the document to verify is incorrect @@ -7119,7 +7692,12 @@ pub fn _mm512_maskz_srli_epi16(k: __mmask32, a: __m512i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_srli_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srli_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm256_srli_epi16::(a); @@ -7135,7 +7713,8 @@ pub fn _mm256_mask_srli_epi16(src: __m256i, k: __mmask16, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_srli_epi16(k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srli_epi16(k: __mmask16, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm256_srli_epi16::(a); @@ -7151,7 +7730,12 @@ pub fn _mm256_maskz_srli_epi16(k: __mmask16, a: __m256i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_srli_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srli_epi16( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm_srli_epi16::(a); @@ -7167,7 +7751,8 @@ pub fn _mm_mask_srli_epi16(src: __m128i, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_srli_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srli_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm_srli_epi16::(a); @@ -7182,7 +7767,8 @@ pub fn _mm_maskz_srli_epi16(k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvw))] -pub fn _mm512_srlv_epi16(a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srlv_epi16(a: __m512i, count: __m512i) -> __m512i { unsafe { let count = count.as_u16x32(); let no_overflow: u16x32 = simd_lt(count, u16x32::splat(u16::BITS as u16)); @@ -7198,7 +7784,13 @@ pub fn _mm512_srlv_epi16(a: __m512i, count: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvw))] -pub fn _mm512_mask_srlv_epi16(src: __m512i, k: __mmask32, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srlv_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, + count: __m512i, +) -> __m512i { unsafe { let shf = _mm512_srlv_epi16(a, count).as_i16x32(); transmute(simd_select_bitmask(k, shf, src.as_i16x32())) @@ -7212,7 +7804,8 @@ pub fn _mm512_mask_srlv_epi16(src: __m512i, k: __mmask32, a: __m512i, count: __m #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvw))] -pub fn _mm512_maskz_srlv_epi16(k: __mmask32, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srlv_epi16(k: __mmask32, a: __m512i, count: __m512i) -> __m512i { unsafe { let shf = _mm512_srlv_epi16(a, count).as_i16x32(); transmute(simd_select_bitmask(k, shf, i16x32::ZERO)) @@ -7226,7 +7819,8 @@ pub fn _mm512_maskz_srlv_epi16(k: __mmask32, a: __m512i, count: __m512i) -> __m5 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvw))] -pub fn _mm256_srlv_epi16(a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srlv_epi16(a: __m256i, count: __m256i) -> __m256i { unsafe { let count = count.as_u16x16(); let no_overflow: u16x16 = simd_lt(count, u16x16::splat(u16::BITS as u16)); @@ -7242,7 +7836,13 @@ pub fn _mm256_srlv_epi16(a: __m256i, count: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvw))] -pub fn _mm256_mask_srlv_epi16(src: __m256i, k: __mmask16, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srlv_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, + count: __m256i, +) -> __m256i { unsafe { let shf = _mm256_srlv_epi16(a, count).as_i16x16(); transmute(simd_select_bitmask(k, shf, src.as_i16x16())) @@ -7256,7 +7856,8 @@ pub fn _mm256_mask_srlv_epi16(src: __m256i, k: __mmask16, a: __m256i, count: __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvw))] -pub fn _mm256_maskz_srlv_epi16(k: __mmask16, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srlv_epi16(k: __mmask16, a: __m256i, count: __m256i) -> __m256i { unsafe { let shf = _mm256_srlv_epi16(a, count).as_i16x16(); transmute(simd_select_bitmask(k, shf, i16x16::ZERO)) @@ -7270,7 +7871,8 @@ pub fn _mm256_maskz_srlv_epi16(k: __mmask16, a: __m256i, count: __m256i) -> __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvw))] -pub fn _mm_srlv_epi16(a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srlv_epi16(a: __m128i, count: __m128i) -> __m128i { unsafe { let count = count.as_u16x8(); let no_overflow: u16x8 = simd_lt(count, u16x8::splat(u16::BITS as u16)); @@ -7286,7 +7888,8 @@ pub fn _mm_srlv_epi16(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvw))] -pub fn _mm_mask_srlv_epi16(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srlv_epi16(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srlv_epi16(a, count).as_i16x8(); transmute(simd_select_bitmask(k, shf, src.as_i16x8())) @@ -7300,7 +7903,8 @@ pub fn _mm_mask_srlv_epi16(src: __m128i, k: __mmask8, a: __m128i, count: __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrlvw))] -pub fn _mm_maskz_srlv_epi16(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srlv_epi16(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srlv_epi16(a, count).as_i16x8(); transmute(simd_select_bitmask(k, shf, i16x8::ZERO)) @@ -7410,7 +8014,8 @@ pub fn _mm_maskz_sra_epi16(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraw, IMM8 = 1))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_srai_epi16(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srai_epi16(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); transmute(simd_shr(a.as_i16x32(), i16x32::splat(IMM8.min(15) as i16))) @@ -7425,7 +8030,12 @@ pub fn _mm512_srai_epi16(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraw, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_srai_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srai_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = simd_shr(a.as_i16x32(), i16x32::splat(IMM8.min(15) as i16)); @@ -7441,7 +8051,8 @@ pub fn _mm512_mask_srai_epi16(src: __m512i, k: __mmask32, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraw, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_srai_epi16(k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srai_epi16(k: __mmask32, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = simd_shr(a.as_i16x32(), i16x32::splat(IMM8.min(15) as i16)); @@ -7457,7 +8068,12 @@ pub fn _mm512_maskz_srai_epi16(k: __mmask32, a: __m512i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraw, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_srai_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srai_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = simd_shr(a.as_i16x16(), i16x16::splat(IMM8.min(15) as i16)); @@ -7473,7 +8089,8 @@ pub fn _mm256_mask_srai_epi16(src: __m256i, k: __mmask16, a: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraw, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_srai_epi16(k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srai_epi16(k: __mmask16, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = simd_shr(a.as_i16x16(), i16x16::splat(IMM8.min(15) as i16)); @@ -7489,7 +8106,12 @@ pub fn _mm256_maskz_srai_epi16(k: __mmask16, a: __m256i) -> __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraw, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_srai_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srai_epi16( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = simd_shr(a.as_i16x8(), i16x8::splat(IMM8.min(15) as i16)); @@ -7505,7 +8127,8 @@ pub fn _mm_mask_srai_epi16(src: __m128i, k: __mmask8, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsraw, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_srai_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srai_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = simd_shr(a.as_i16x8(), i16x8::splat(IMM8.min(15) as i16)); @@ -7520,7 +8143,8 @@ pub fn _mm_maskz_srai_epi16(k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravw))] -pub fn _mm512_srav_epi16(a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_srav_epi16(a: __m512i, count: __m512i) -> __m512i { unsafe { let count = count.as_u16x32(); let no_overflow: u16x32 = simd_lt(count, u16x32::splat(u16::BITS as u16)); @@ -7536,7 +8160,13 @@ pub fn _mm512_srav_epi16(a: __m512i, count: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravw))] -pub fn _mm512_mask_srav_epi16(src: __m512i, k: __mmask32, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_srav_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, + count: __m512i, +) -> __m512i { unsafe { let shf = _mm512_srav_epi16(a, count).as_i16x32(); transmute(simd_select_bitmask(k, shf, src.as_i16x32())) @@ -7550,7 +8180,8 @@ pub fn _mm512_mask_srav_epi16(src: __m512i, k: __mmask32, a: __m512i, count: __m #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravw))] -pub fn _mm512_maskz_srav_epi16(k: __mmask32, a: __m512i, count: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_srav_epi16(k: __mmask32, a: __m512i, count: __m512i) -> __m512i { unsafe { let shf = _mm512_srav_epi16(a, count).as_i16x32(); transmute(simd_select_bitmask(k, shf, i16x32::ZERO)) @@ -7564,7 +8195,8 @@ pub fn _mm512_maskz_srav_epi16(k: __mmask32, a: __m512i, count: __m512i) -> __m5 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravw))] -pub fn _mm256_srav_epi16(a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_srav_epi16(a: __m256i, count: __m256i) -> __m256i { unsafe { let count = count.as_u16x16(); let no_overflow: u16x16 = simd_lt(count, u16x16::splat(u16::BITS as u16)); @@ -7580,7 +8212,13 @@ pub fn _mm256_srav_epi16(a: __m256i, count: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravw))] -pub fn _mm256_mask_srav_epi16(src: __m256i, k: __mmask16, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_srav_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, + count: __m256i, +) -> __m256i { unsafe { let shf = _mm256_srav_epi16(a, count).as_i16x16(); transmute(simd_select_bitmask(k, shf, src.as_i16x16())) @@ -7594,7 +8232,8 @@ pub fn _mm256_mask_srav_epi16(src: __m256i, k: __mmask16, a: __m256i, count: __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravw))] -pub fn _mm256_maskz_srav_epi16(k: __mmask16, a: __m256i, count: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_srav_epi16(k: __mmask16, a: __m256i, count: __m256i) -> __m256i { unsafe { let shf = _mm256_srav_epi16(a, count).as_i16x16(); transmute(simd_select_bitmask(k, shf, i16x16::ZERO)) @@ -7608,7 +8247,8 @@ pub fn _mm256_maskz_srav_epi16(k: __mmask16, a: __m256i, count: __m256i) -> __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravw))] -pub fn _mm_srav_epi16(a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_srav_epi16(a: __m128i, count: __m128i) -> __m128i { unsafe { let count = count.as_u16x8(); let no_overflow: u16x8 = simd_lt(count, u16x8::splat(u16::BITS as u16)); @@ -7624,7 +8264,8 @@ pub fn _mm_srav_epi16(a: __m128i, count: __m128i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravw))] -pub fn _mm_mask_srav_epi16(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_srav_epi16(src: __m128i, k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srav_epi16(a, count).as_i16x8(); transmute(simd_select_bitmask(k, shf, src.as_i16x8())) @@ -7638,7 +8279,8 @@ pub fn _mm_mask_srav_epi16(src: __m128i, k: __mmask8, a: __m128i, count: __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsravw))] -pub fn _mm_maskz_srav_epi16(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_srav_epi16(k: __mmask8, a: __m128i, count: __m128i) -> __m128i { unsafe { let shf = _mm_srav_epi16(a, count).as_i16x8(); transmute(simd_select_bitmask(k, shf, i16x8::ZERO)) @@ -7968,7 +8610,8 @@ pub fn _mm_maskz_permutexvar_epi16(k: __mmask8, idx: __m128i, a: __m128i) -> __m #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu16))] //should be vpblendmw -pub fn _mm512_mask_blend_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_blend_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask(k, b.as_i16x32(), a.as_i16x32())) } } @@ -7979,7 +8622,8 @@ pub fn _mm512_mask_blend_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu16))] //should be vpblendmw -pub fn _mm256_mask_blend_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_blend_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask(k, b.as_i16x16(), a.as_i16x16())) } } @@ -7990,7 +8634,8 @@ pub fn _mm256_mask_blend_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu16))] //should be vpblendmw -pub fn _mm_mask_blend_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_blend_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask(k, b.as_i16x8(), a.as_i16x8())) } } @@ -8001,7 +8646,8 @@ pub fn _mm_mask_blend_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu8))] //should be vpblendmb -pub fn _mm512_mask_blend_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_blend_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask(k, b.as_i8x64(), a.as_i8x64())) } } @@ -8012,7 +8658,8 @@ pub fn _mm512_mask_blend_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu8))] //should be vpblendmb -pub fn _mm256_mask_blend_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_blend_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask(k, b.as_i8x32(), a.as_i8x32())) } } @@ -8023,7 +8670,8 @@ pub fn _mm256_mask_blend_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu8))] //should be vpblendmb -pub fn _mm_mask_blend_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_blend_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask(k, b.as_i8x16(), a.as_i8x16())) } } @@ -8034,7 +8682,8 @@ pub fn _mm_mask_blend_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm512_broadcastw_epi16(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcastw_epi16(a: __m128i) -> __m512i { unsafe { let a = _mm512_castsi128_si512(a).as_i16x32(); let ret: i16x32 = simd_shuffle!( @@ -8056,7 +8705,8 @@ pub fn _mm512_broadcastw_epi16(a: __m128i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm512_mask_broadcastw_epi16(src: __m512i, k: __mmask32, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcastw_epi16(src: __m512i, k: __mmask32, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcastw_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, broadcast, src.as_i16x32())) @@ -8070,7 +8720,8 @@ pub fn _mm512_mask_broadcastw_epi16(src: __m512i, k: __mmask32, a: __m128i) -> _ #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm512_maskz_broadcastw_epi16(k: __mmask32, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcastw_epi16(k: __mmask32, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcastw_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, broadcast, i16x32::ZERO)) @@ -8084,7 +8735,8 @@ pub fn _mm512_maskz_broadcastw_epi16(k: __mmask32, a: __m128i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm256_mask_broadcastw_epi16(src: __m256i, k: __mmask16, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcastw_epi16(src: __m256i, k: __mmask16, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcastw_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, broadcast, src.as_i16x16())) @@ -8098,7 +8750,8 @@ pub fn _mm256_mask_broadcastw_epi16(src: __m256i, k: __mmask16, a: __m128i) -> _ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm256_maskz_broadcastw_epi16(k: __mmask16, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcastw_epi16(k: __mmask16, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcastw_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, broadcast, i16x16::ZERO)) @@ -8112,7 +8765,8 @@ pub fn _mm256_maskz_broadcastw_epi16(k: __mmask16, a: __m128i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm_mask_broadcastw_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_broadcastw_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let broadcast = _mm_broadcastw_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, broadcast, src.as_i16x8())) @@ -8126,7 +8780,8 @@ pub fn _mm_mask_broadcastw_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m12 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm_maskz_broadcastw_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_broadcastw_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { let broadcast = _mm_broadcastw_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, broadcast, i16x8::ZERO)) @@ -8140,7 +8795,8 @@ pub fn _mm_maskz_broadcastw_epi16(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastb))] -pub fn _mm512_broadcastb_epi8(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcastb_epi8(a: __m128i) -> __m512i { unsafe { let a = _mm512_castsi128_si512(a).as_i8x64(); let ret: i8x64 = simd_shuffle!( @@ -8163,7 +8819,8 @@ pub fn _mm512_broadcastb_epi8(a: __m128i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastb))] -pub fn _mm512_mask_broadcastb_epi8(src: __m512i, k: __mmask64, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcastb_epi8(src: __m512i, k: __mmask64, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcastb_epi8(a).as_i8x64(); transmute(simd_select_bitmask(k, broadcast, src.as_i8x64())) @@ -8177,7 +8834,8 @@ pub fn _mm512_mask_broadcastb_epi8(src: __m512i, k: __mmask64, a: __m128i) -> __ #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastb))] -pub fn _mm512_maskz_broadcastb_epi8(k: __mmask64, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcastb_epi8(k: __mmask64, a: __m128i) -> __m512i { unsafe { let broadcast = _mm512_broadcastb_epi8(a).as_i8x64(); transmute(simd_select_bitmask(k, broadcast, i8x64::ZERO)) @@ -8191,7 +8849,8 @@ pub fn _mm512_maskz_broadcastb_epi8(k: __mmask64, a: __m128i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastb))] -pub fn _mm256_mask_broadcastb_epi8(src: __m256i, k: __mmask32, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcastb_epi8(src: __m256i, k: __mmask32, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcastb_epi8(a).as_i8x32(); transmute(simd_select_bitmask(k, broadcast, src.as_i8x32())) @@ -8205,7 +8864,8 @@ pub fn _mm256_mask_broadcastb_epi8(src: __m256i, k: __mmask32, a: __m128i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastb))] -pub fn _mm256_maskz_broadcastb_epi8(k: __mmask32, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcastb_epi8(k: __mmask32, a: __m128i) -> __m256i { unsafe { let broadcast = _mm256_broadcastb_epi8(a).as_i8x32(); transmute(simd_select_bitmask(k, broadcast, i8x32::ZERO)) @@ -8219,7 +8879,8 @@ pub fn _mm256_maskz_broadcastb_epi8(k: __mmask32, a: __m128i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastb))] -pub fn _mm_mask_broadcastb_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_broadcastb_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { unsafe { let broadcast = _mm_broadcastb_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, broadcast, src.as_i8x16())) @@ -8233,7 +8894,8 @@ pub fn _mm_mask_broadcastb_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m12 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastb))] -pub fn _mm_maskz_broadcastb_epi8(k: __mmask16, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_broadcastb_epi8(k: __mmask16, a: __m128i) -> __m128i { unsafe { let broadcast = _mm_broadcastb_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, broadcast, i8x16::ZERO)) @@ -8247,7 +8909,8 @@ pub fn _mm_maskz_broadcastb_epi8(k: __mmask16, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhwd))] -pub fn _mm512_unpackhi_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpackhi_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = a.as_i16x32(); let b = b.as_i16x32(); @@ -8277,7 +8940,13 @@ pub fn _mm512_unpackhi_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhwd))] -pub fn _mm512_mask_unpackhi_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpackhi_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let unpackhi = _mm512_unpackhi_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, unpackhi, src.as_i16x32())) @@ -8291,7 +8960,8 @@ pub fn _mm512_mask_unpackhi_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhwd))] -pub fn _mm512_maskz_unpackhi_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpackhi_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let unpackhi = _mm512_unpackhi_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, unpackhi, i16x32::ZERO)) @@ -8305,7 +8975,13 @@ pub fn _mm512_maskz_unpackhi_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m5 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhwd))] -pub fn _mm256_mask_unpackhi_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpackhi_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let unpackhi = _mm256_unpackhi_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, unpackhi, src.as_i16x16())) @@ -8319,7 +8995,8 @@ pub fn _mm256_mask_unpackhi_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhwd))] -pub fn _mm256_maskz_unpackhi_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpackhi_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let unpackhi = _mm256_unpackhi_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, unpackhi, i16x16::ZERO)) @@ -8333,7 +9010,8 @@ pub fn _mm256_maskz_unpackhi_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhwd))] -pub fn _mm_mask_unpackhi_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpackhi_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpackhi = _mm_unpackhi_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, unpackhi, src.as_i16x8())) @@ -8347,7 +9025,8 @@ pub fn _mm_mask_unpackhi_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhwd))] -pub fn _mm_maskz_unpackhi_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpackhi_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpackhi = _mm_unpackhi_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, unpackhi, i16x8::ZERO)) @@ -8361,7 +9040,8 @@ pub fn _mm_maskz_unpackhi_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhbw))] -pub fn _mm512_unpackhi_epi8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpackhi_epi8(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = a.as_i8x64(); let b = b.as_i8x64(); @@ -8399,7 +9079,13 @@ pub fn _mm512_unpackhi_epi8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhbw))] -pub fn _mm512_mask_unpackhi_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpackhi_epi8( + src: __m512i, + k: __mmask64, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let unpackhi = _mm512_unpackhi_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, unpackhi, src.as_i8x64())) @@ -8413,7 +9099,8 @@ pub fn _mm512_mask_unpackhi_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m5 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhbw))] -pub fn _mm512_maskz_unpackhi_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpackhi_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let unpackhi = _mm512_unpackhi_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, unpackhi, i8x64::ZERO)) @@ -8427,7 +9114,13 @@ pub fn _mm512_maskz_unpackhi_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m51 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhbw))] -pub fn _mm256_mask_unpackhi_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpackhi_epi8( + src: __m256i, + k: __mmask32, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let unpackhi = _mm256_unpackhi_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, unpackhi, src.as_i8x32())) @@ -8441,7 +9134,8 @@ pub fn _mm256_mask_unpackhi_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhbw))] -pub fn _mm256_maskz_unpackhi_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpackhi_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let unpackhi = _mm256_unpackhi_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, unpackhi, i8x32::ZERO)) @@ -8455,7 +9149,8 @@ pub fn _mm256_maskz_unpackhi_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m25 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhbw))] -pub fn _mm_mask_unpackhi_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpackhi_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpackhi = _mm_unpackhi_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, unpackhi, src.as_i8x16())) @@ -8469,7 +9164,8 @@ pub fn _mm_mask_unpackhi_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpckhbw))] -pub fn _mm_maskz_unpackhi_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpackhi_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpackhi = _mm_unpackhi_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, unpackhi, i8x16::ZERO)) @@ -8483,7 +9179,8 @@ pub fn _mm_maskz_unpackhi_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklwd))] -pub fn _mm512_unpacklo_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpacklo_epi16(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = a.as_i16x32(); let b = b.as_i16x32(); @@ -8513,7 +9210,13 @@ pub fn _mm512_unpacklo_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklwd))] -pub fn _mm512_mask_unpacklo_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpacklo_epi16( + src: __m512i, + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let unpacklo = _mm512_unpacklo_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, unpacklo, src.as_i16x32())) @@ -8527,7 +9230,8 @@ pub fn _mm512_mask_unpacklo_epi16(src: __m512i, k: __mmask32, a: __m512i, b: __m #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklwd))] -pub fn _mm512_maskz_unpacklo_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpacklo_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let unpacklo = _mm512_unpacklo_epi16(a, b).as_i16x32(); transmute(simd_select_bitmask(k, unpacklo, i16x32::ZERO)) @@ -8541,7 +9245,13 @@ pub fn _mm512_maskz_unpacklo_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m5 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklwd))] -pub fn _mm256_mask_unpacklo_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpacklo_epi16( + src: __m256i, + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let unpacklo = _mm256_unpacklo_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, unpacklo, src.as_i16x16())) @@ -8555,7 +9265,8 @@ pub fn _mm256_mask_unpacklo_epi16(src: __m256i, k: __mmask16, a: __m256i, b: __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklwd))] -pub fn _mm256_maskz_unpacklo_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpacklo_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let unpacklo = _mm256_unpacklo_epi16(a, b).as_i16x16(); transmute(simd_select_bitmask(k, unpacklo, i16x16::ZERO)) @@ -8569,7 +9280,8 @@ pub fn _mm256_maskz_unpacklo_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklwd))] -pub fn _mm_mask_unpacklo_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpacklo_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpacklo = _mm_unpacklo_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, unpacklo, src.as_i16x8())) @@ -8583,7 +9295,8 @@ pub fn _mm_mask_unpacklo_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklwd))] -pub fn _mm_maskz_unpacklo_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpacklo_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpacklo = _mm_unpacklo_epi16(a, b).as_i16x8(); transmute(simd_select_bitmask(k, unpacklo, i16x8::ZERO)) @@ -8597,7 +9310,8 @@ pub fn _mm_maskz_unpacklo_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklbw))] -pub fn _mm512_unpacklo_epi8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_unpacklo_epi8(a: __m512i, b: __m512i) -> __m512i { unsafe { let a = a.as_i8x64(); let b = b.as_i8x64(); @@ -8635,7 +9349,13 @@ pub fn _mm512_unpacklo_epi8(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklbw))] -pub fn _mm512_mask_unpacklo_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_unpacklo_epi8( + src: __m512i, + k: __mmask64, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let unpacklo = _mm512_unpacklo_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, unpacklo, src.as_i8x64())) @@ -8649,7 +9369,8 @@ pub fn _mm512_mask_unpacklo_epi8(src: __m512i, k: __mmask64, a: __m512i, b: __m5 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklbw))] -pub fn _mm512_maskz_unpacklo_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_unpacklo_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let unpacklo = _mm512_unpacklo_epi8(a, b).as_i8x64(); transmute(simd_select_bitmask(k, unpacklo, i8x64::ZERO)) @@ -8663,7 +9384,13 @@ pub fn _mm512_maskz_unpacklo_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m51 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklbw))] -pub fn _mm256_mask_unpacklo_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_unpacklo_epi8( + src: __m256i, + k: __mmask32, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let unpacklo = _mm256_unpacklo_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, unpacklo, src.as_i8x32())) @@ -8677,7 +9404,8 @@ pub fn _mm256_mask_unpacklo_epi8(src: __m256i, k: __mmask32, a: __m256i, b: __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklbw))] -pub fn _mm256_maskz_unpacklo_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_unpacklo_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let unpacklo = _mm256_unpacklo_epi8(a, b).as_i8x32(); transmute(simd_select_bitmask(k, unpacklo, i8x32::ZERO)) @@ -8691,7 +9419,8 @@ pub fn _mm256_maskz_unpacklo_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m25 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklbw))] -pub fn _mm_mask_unpacklo_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_unpacklo_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpacklo = _mm_unpacklo_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, unpacklo, src.as_i8x16())) @@ -8705,7 +9434,8 @@ pub fn _mm_mask_unpacklo_epi8(src: __m128i, k: __mmask16, a: __m128i, b: __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpunpcklbw))] -pub fn _mm_maskz_unpacklo_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_unpacklo_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let unpacklo = _mm_unpacklo_epi8(a, b).as_i8x16(); transmute(simd_select_bitmask(k, unpacklo, i8x16::ZERO)) @@ -8719,7 +9449,8 @@ pub fn _mm_maskz_unpacklo_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu16))] -pub fn _mm512_mask_mov_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mov_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i { unsafe { let mov = a.as_i16x32(); transmute(simd_select_bitmask(k, mov, src.as_i16x32())) @@ -8733,7 +9464,8 @@ pub fn _mm512_mask_mov_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu16))] -pub fn _mm512_maskz_mov_epi16(k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mov_epi16(k: __mmask32, a: __m512i) -> __m512i { unsafe { let mov = a.as_i16x32(); transmute(simd_select_bitmask(k, mov, i16x32::ZERO)) @@ -8747,7 +9479,8 @@ pub fn _mm512_maskz_mov_epi16(k: __mmask32, a: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu16))] -pub fn _mm256_mask_mov_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mov_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i { unsafe { let mov = a.as_i16x16(); transmute(simd_select_bitmask(k, mov, src.as_i16x16())) @@ -8761,7 +9494,8 @@ pub fn _mm256_mask_mov_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu16))] -pub fn _mm256_maskz_mov_epi16(k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mov_epi16(k: __mmask16, a: __m256i) -> __m256i { unsafe { let mov = a.as_i16x16(); transmute(simd_select_bitmask(k, mov, i16x16::ZERO)) @@ -8775,7 +9509,8 @@ pub fn _mm256_maskz_mov_epi16(k: __mmask16, a: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu16))] -pub fn _mm_mask_mov_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mov_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let mov = a.as_i16x8(); transmute(simd_select_bitmask(k, mov, src.as_i16x8())) @@ -8789,7 +9524,8 @@ pub fn _mm_mask_mov_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu16))] -pub fn _mm_maskz_mov_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mov_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { let mov = a.as_i16x8(); transmute(simd_select_bitmask(k, mov, i16x8::ZERO)) @@ -8803,7 +9539,8 @@ pub fn _mm_maskz_mov_epi16(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu8))] -pub fn _mm512_mask_mov_epi8(src: __m512i, k: __mmask64, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mov_epi8(src: __m512i, k: __mmask64, a: __m512i) -> __m512i { unsafe { let mov = a.as_i8x64(); transmute(simd_select_bitmask(k, mov, src.as_i8x64())) @@ -8817,7 +9554,8 @@ pub fn _mm512_mask_mov_epi8(src: __m512i, k: __mmask64, a: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu8))] -pub fn _mm512_maskz_mov_epi8(k: __mmask64, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mov_epi8(k: __mmask64, a: __m512i) -> __m512i { unsafe { let mov = a.as_i8x64(); transmute(simd_select_bitmask(k, mov, i8x64::ZERO)) @@ -8831,7 +9569,8 @@ pub fn _mm512_maskz_mov_epi8(k: __mmask64, a: __m512i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu8))] -pub fn _mm256_mask_mov_epi8(src: __m256i, k: __mmask32, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mov_epi8(src: __m256i, k: __mmask32, a: __m256i) -> __m256i { unsafe { let mov = a.as_i8x32(); transmute(simd_select_bitmask(k, mov, src.as_i8x32())) @@ -8845,7 +9584,8 @@ pub fn _mm256_mask_mov_epi8(src: __m256i, k: __mmask32, a: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu8))] -pub fn _mm256_maskz_mov_epi8(k: __mmask32, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mov_epi8(k: __mmask32, a: __m256i) -> __m256i { unsafe { let mov = a.as_i8x32(); transmute(simd_select_bitmask(k, mov, i8x32::ZERO)) @@ -8859,7 +9599,8 @@ pub fn _mm256_maskz_mov_epi8(k: __mmask32, a: __m256i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu8))] -pub fn _mm_mask_mov_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mov_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { unsafe { let mov = a.as_i8x16(); transmute(simd_select_bitmask(k, mov, src.as_i8x16())) @@ -8873,7 +9614,8 @@ pub fn _mm_mask_mov_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vmovdqu8))] -pub fn _mm_maskz_mov_epi8(k: __mmask16, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mov_epi8(k: __mmask16, a: __m128i) -> __m128i { unsafe { let mov = a.as_i8x16(); transmute(simd_select_bitmask(k, mov, i8x16::ZERO)) @@ -8887,7 +9629,8 @@ pub fn _mm_maskz_mov_epi8(k: __mmask16, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm512_mask_set1_epi16(src: __m512i, k: __mmask32, a: i16) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_set1_epi16(src: __m512i, k: __mmask32, a: i16) -> __m512i { unsafe { let r = _mm512_set1_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, r, src.as_i16x32())) @@ -8901,7 +9644,8 @@ pub fn _mm512_mask_set1_epi16(src: __m512i, k: __mmask32, a: i16) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm512_maskz_set1_epi16(k: __mmask32, a: i16) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_set1_epi16(k: __mmask32, a: i16) -> __m512i { unsafe { let r = _mm512_set1_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, r, i16x32::ZERO)) @@ -8915,7 +9659,8 @@ pub fn _mm512_maskz_set1_epi16(k: __mmask32, a: i16) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm256_mask_set1_epi16(src: __m256i, k: __mmask16, a: i16) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_set1_epi16(src: __m256i, k: __mmask16, a: i16) -> __m256i { unsafe { let r = _mm256_set1_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, r, src.as_i16x16())) @@ -8929,7 +9674,8 @@ pub fn _mm256_mask_set1_epi16(src: __m256i, k: __mmask16, a: i16) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm256_maskz_set1_epi16(k: __mmask16, a: i16) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_set1_epi16(k: __mmask16, a: i16) -> __m256i { unsafe { let r = _mm256_set1_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, r, i16x16::ZERO)) @@ -8943,7 +9689,8 @@ pub fn _mm256_maskz_set1_epi16(k: __mmask16, a: i16) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm_mask_set1_epi16(src: __m128i, k: __mmask8, a: i16) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_set1_epi16(src: __m128i, k: __mmask8, a: i16) -> __m128i { unsafe { let r = _mm_set1_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, r, src.as_i16x8())) @@ -8957,7 +9704,8 @@ pub fn _mm_mask_set1_epi16(src: __m128i, k: __mmask8, a: i16) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcastw))] -pub fn _mm_maskz_set1_epi16(k: __mmask8, a: i16) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_set1_epi16(k: __mmask8, a: i16) -> __m128i { unsafe { let r = _mm_set1_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, r, i16x8::ZERO)) @@ -8971,7 +9719,8 @@ pub fn _mm_maskz_set1_epi16(k: __mmask8, a: i16) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] -pub fn _mm512_mask_set1_epi8(src: __m512i, k: __mmask64, a: i8) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_set1_epi8(src: __m512i, k: __mmask64, a: i8) -> __m512i { unsafe { let r = _mm512_set1_epi8(a).as_i8x64(); transmute(simd_select_bitmask(k, r, src.as_i8x64())) @@ -8985,7 +9734,8 @@ pub fn _mm512_mask_set1_epi8(src: __m512i, k: __mmask64, a: i8) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] -pub fn _mm512_maskz_set1_epi8(k: __mmask64, a: i8) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_set1_epi8(k: __mmask64, a: i8) -> __m512i { unsafe { let r = _mm512_set1_epi8(a).as_i8x64(); transmute(simd_select_bitmask(k, r, i8x64::ZERO)) @@ -8999,7 +9749,8 @@ pub fn _mm512_maskz_set1_epi8(k: __mmask64, a: i8) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] -pub fn _mm256_mask_set1_epi8(src: __m256i, k: __mmask32, a: i8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_set1_epi8(src: __m256i, k: __mmask32, a: i8) -> __m256i { unsafe { let r = _mm256_set1_epi8(a).as_i8x32(); transmute(simd_select_bitmask(k, r, src.as_i8x32())) @@ -9013,7 +9764,8 @@ pub fn _mm256_mask_set1_epi8(src: __m256i, k: __mmask32, a: i8) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] -pub fn _mm256_maskz_set1_epi8(k: __mmask32, a: i8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_set1_epi8(k: __mmask32, a: i8) -> __m256i { unsafe { let r = _mm256_set1_epi8(a).as_i8x32(); transmute(simd_select_bitmask(k, r, i8x32::ZERO)) @@ -9027,7 +9779,8 @@ pub fn _mm256_maskz_set1_epi8(k: __mmask32, a: i8) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] -pub fn _mm_mask_set1_epi8(src: __m128i, k: __mmask16, a: i8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_set1_epi8(src: __m128i, k: __mmask16, a: i8) -> __m128i { unsafe { let r = _mm_set1_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, r, src.as_i8x16())) @@ -9041,7 +9794,8 @@ pub fn _mm_mask_set1_epi8(src: __m128i, k: __mmask16, a: i8) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] -pub fn _mm_maskz_set1_epi8(k: __mmask16, a: i8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_set1_epi8(k: __mmask16, a: i8) -> __m128i { unsafe { let r = _mm_set1_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, r, i8x16::ZERO)) @@ -9056,7 +9810,8 @@ pub fn _mm_maskz_set1_epi8(k: __mmask16, a: i8) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshuflw, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_shufflelo_epi16(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shufflelo_epi16(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let a = a.as_i16x32(); @@ -9110,7 +9865,8 @@ pub fn _mm512_shufflelo_epi16(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshuflw, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_shufflelo_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shufflelo_epi16( src: __m512i, k: __mmask32, a: __m512i, @@ -9130,7 +9886,8 @@ pub fn _mm512_mask_shufflelo_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshuflw, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_shufflelo_epi16(k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shufflelo_epi16(k: __mmask32, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm512_shufflelo_epi16::(a); @@ -9146,7 +9903,8 @@ pub fn _mm512_maskz_shufflelo_epi16(k: __mmask32, a: __m512i) - #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshuflw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_shufflelo_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shufflelo_epi16( src: __m256i, k: __mmask16, a: __m256i, @@ -9166,7 +9924,8 @@ pub fn _mm256_mask_shufflelo_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshuflw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_shufflelo_epi16(k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shufflelo_epi16(k: __mmask16, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shuffle = _mm256_shufflelo_epi16::(a); @@ -9182,7 +9941,12 @@ pub fn _mm256_maskz_shufflelo_epi16(k: __mmask16, a: __m256i) - #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshuflw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_shufflelo_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shufflelo_epi16( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shuffle = _mm_shufflelo_epi16::(a); @@ -9198,7 +9962,8 @@ pub fn _mm_mask_shufflelo_epi16(src: __m128i, k: __mmask8, a: _ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshuflw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_shufflelo_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shufflelo_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shuffle = _mm_shufflelo_epi16::(a); @@ -9214,7 +9979,8 @@ pub fn _mm_maskz_shufflelo_epi16(k: __mmask8, a: __m128i) -> __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufhw, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_shufflehi_epi16(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shufflehi_epi16(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let a = a.as_i16x32(); @@ -9268,7 +10034,8 @@ pub fn _mm512_shufflehi_epi16(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufhw, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_mask_shufflehi_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shufflehi_epi16( src: __m512i, k: __mmask32, a: __m512i, @@ -9288,7 +10055,8 @@ pub fn _mm512_mask_shufflehi_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufhw, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_maskz_shufflehi_epi16(k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shufflehi_epi16(k: __mmask32, a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm512_shufflehi_epi16::(a); @@ -9304,7 +10072,8 @@ pub fn _mm512_maskz_shufflehi_epi16(k: __mmask32, a: __m512i) - #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufhw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_mask_shufflehi_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shufflehi_epi16( src: __m256i, k: __mmask16, a: __m256i, @@ -9324,7 +10093,8 @@ pub fn _mm256_mask_shufflehi_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufhw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_maskz_shufflehi_epi16(k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shufflehi_epi16(k: __mmask16, a: __m256i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shuffle = _mm256_shufflehi_epi16::(a); @@ -9340,7 +10110,12 @@ pub fn _mm256_maskz_shufflehi_epi16(k: __mmask16, a: __m256i) - #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufhw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm_mask_shufflehi_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shufflehi_epi16( + src: __m128i, + k: __mmask8, + a: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shuffle = _mm_shufflehi_epi16::(a); @@ -9356,7 +10131,8 @@ pub fn _mm_mask_shufflehi_epi16(src: __m128i, k: __mmask8, a: _ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshufhw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm_maskz_shufflehi_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shufflehi_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shuffle = _mm_shufflehi_epi16::(a); @@ -9466,7 +10242,8 @@ pub fn _mm_maskz_shuffle_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmw))] -pub fn _mm512_test_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_test_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { let and = _mm512_and_si512(a, b); let zero = _mm512_setzero_si512(); _mm512_cmpneq_epi16_mask(and, zero) @@ -9479,7 +10256,8 @@ pub fn _mm512_test_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmw))] -pub fn _mm512_mask_test_epi16_mask(k: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_test_epi16_mask(k: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { let and = _mm512_and_si512(a, b); let zero = _mm512_setzero_si512(); _mm512_mask_cmpneq_epi16_mask(k, and, zero) @@ -9492,7 +10270,8 @@ pub fn _mm512_mask_test_epi16_mask(k: __mmask32, a: __m512i, b: __m512i) -> __mm #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmw))] -pub fn _mm256_test_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_test_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_cmpneq_epi16_mask(and, zero) @@ -9505,7 +10284,8 @@ pub fn _mm256_test_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmw))] -pub fn _mm256_mask_test_epi16_mask(k: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_test_epi16_mask(k: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_mask_cmpneq_epi16_mask(k, and, zero) @@ -9518,7 +10298,8 @@ pub fn _mm256_mask_test_epi16_mask(k: __mmask16, a: __m256i, b: __m256i) -> __mm #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmw))] -pub fn _mm_test_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_test_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_cmpneq_epi16_mask(and, zero) @@ -9531,7 +10312,8 @@ pub fn _mm_test_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmw))] -pub fn _mm_mask_test_epi16_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_test_epi16_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_mask_cmpneq_epi16_mask(k, and, zero) @@ -9544,7 +10326,8 @@ pub fn _mm_mask_test_epi16_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmb))] -pub fn _mm512_test_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_test_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { let and = _mm512_and_si512(a, b); let zero = _mm512_setzero_si512(); _mm512_cmpneq_epi8_mask(and, zero) @@ -9557,7 +10340,8 @@ pub fn _mm512_test_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmb))] -pub fn _mm512_mask_test_epi8_mask(k: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_test_epi8_mask(k: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { let and = _mm512_and_si512(a, b); let zero = _mm512_setzero_si512(); _mm512_mask_cmpneq_epi8_mask(k, and, zero) @@ -9570,7 +10354,8 @@ pub fn _mm512_mask_test_epi8_mask(k: __mmask64, a: __m512i, b: __m512i) -> __mma #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmb))] -pub fn _mm256_test_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_test_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_cmpneq_epi8_mask(and, zero) @@ -9583,7 +10368,8 @@ pub fn _mm256_test_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmb))] -pub fn _mm256_mask_test_epi8_mask(k: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_test_epi8_mask(k: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_mask_cmpneq_epi8_mask(k, and, zero) @@ -9596,7 +10382,8 @@ pub fn _mm256_mask_test_epi8_mask(k: __mmask32, a: __m256i, b: __m256i) -> __mma #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmb))] -pub fn _mm_test_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_test_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_cmpneq_epi8_mask(and, zero) @@ -9609,7 +10396,8 @@ pub fn _mm_test_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestmb))] -pub fn _mm_mask_test_epi8_mask(k: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_test_epi8_mask(k: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_mask_cmpneq_epi8_mask(k, and, zero) @@ -9622,7 +10410,8 @@ pub fn _mm_mask_test_epi8_mask(k: __mmask16, a: __m128i, b: __m128i) -> __mmask1 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmw))] -pub fn _mm512_testn_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_testn_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { let and = _mm512_and_si512(a, b); let zero = _mm512_setzero_si512(); _mm512_cmpeq_epi16_mask(and, zero) @@ -9635,7 +10424,8 @@ pub fn _mm512_testn_epi16_mask(a: __m512i, b: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmw))] -pub fn _mm512_mask_testn_epi16_mask(k: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_testn_epi16_mask(k: __mmask32, a: __m512i, b: __m512i) -> __mmask32 { let and = _mm512_and_si512(a, b); let zero = _mm512_setzero_si512(); _mm512_mask_cmpeq_epi16_mask(k, and, zero) @@ -9648,7 +10438,8 @@ pub fn _mm512_mask_testn_epi16_mask(k: __mmask32, a: __m512i, b: __m512i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmw))] -pub fn _mm256_testn_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_testn_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_cmpeq_epi16_mask(and, zero) @@ -9661,7 +10452,8 @@ pub fn _mm256_testn_epi16_mask(a: __m256i, b: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmw))] -pub fn _mm256_mask_testn_epi16_mask(k: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_testn_epi16_mask(k: __mmask16, a: __m256i, b: __m256i) -> __mmask16 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_mask_cmpeq_epi16_mask(k, and, zero) @@ -9674,7 +10466,8 @@ pub fn _mm256_mask_testn_epi16_mask(k: __mmask16, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmw))] -pub fn _mm_testn_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testn_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_cmpeq_epi16_mask(and, zero) @@ -9687,7 +10480,8 @@ pub fn _mm_testn_epi16_mask(a: __m128i, b: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmw))] -pub fn _mm_mask_testn_epi16_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_testn_epi16_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask8 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_mask_cmpeq_epi16_mask(k, and, zero) @@ -9700,7 +10494,8 @@ pub fn _mm_mask_testn_epi16_mask(k: __mmask8, a: __m128i, b: __m128i) -> __mmask #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmb))] -pub fn _mm512_testn_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_testn_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { let and = _mm512_and_si512(a, b); let zero = _mm512_setzero_si512(); _mm512_cmpeq_epi8_mask(and, zero) @@ -9713,7 +10508,8 @@ pub fn _mm512_testn_epi8_mask(a: __m512i, b: __m512i) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmb))] -pub fn _mm512_mask_testn_epi8_mask(k: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_testn_epi8_mask(k: __mmask64, a: __m512i, b: __m512i) -> __mmask64 { let and = _mm512_and_si512(a, b); let zero = _mm512_setzero_si512(); _mm512_mask_cmpeq_epi8_mask(k, and, zero) @@ -9726,7 +10522,8 @@ pub fn _mm512_mask_testn_epi8_mask(k: __mmask64, a: __m512i, b: __m512i) -> __mm #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmb))] -pub fn _mm256_testn_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_testn_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_cmpeq_epi8_mask(and, zero) @@ -9739,7 +10536,8 @@ pub fn _mm256_testn_epi8_mask(a: __m256i, b: __m256i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmb))] -pub fn _mm256_mask_testn_epi8_mask(k: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_testn_epi8_mask(k: __mmask32, a: __m256i, b: __m256i) -> __mmask32 { let and = _mm256_and_si256(a, b); let zero = _mm256_setzero_si256(); _mm256_mask_cmpeq_epi8_mask(k, and, zero) @@ -9752,7 +10550,8 @@ pub fn _mm256_mask_testn_epi8_mask(k: __mmask32, a: __m256i, b: __m256i) -> __mm #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmb))] -pub fn _mm_testn_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_testn_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_cmpeq_epi8_mask(and, zero) @@ -9765,7 +10564,8 @@ pub fn _mm_testn_epi8_mask(a: __m128i, b: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vptestnmb))] -pub fn _mm_mask_testn_epi8_mask(k: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_testn_epi8_mask(k: __mmask16, a: __m128i, b: __m128i) -> __mmask16 { let and = _mm_and_si128(a, b); let zero = _mm_setzero_si128(); _mm_mask_cmpeq_epi8_mask(k, and, zero) @@ -9778,7 +10578,8 @@ pub fn _mm_mask_testn_epi8_mask(k: __mmask16, a: __m128i, b: __m128i) -> __mmask #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(mov))] //should be kmovq -pub unsafe fn _store_mask64(mem_addr: *mut __mmask64, a: __mmask64) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _store_mask64(mem_addr: *mut __mmask64, a: __mmask64) { ptr::write(mem_addr as *mut __mmask64, a); } @@ -9789,7 +10590,8 @@ pub unsafe fn _store_mask64(mem_addr: *mut __mmask64, a: __mmask64) { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(mov))] //should be kmovd -pub unsafe fn _store_mask32(mem_addr: *mut __mmask32, a: __mmask32) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _store_mask32(mem_addr: *mut __mmask32, a: __mmask32) { ptr::write(mem_addr as *mut __mmask32, a); } @@ -9800,7 +10602,8 @@ pub unsafe fn _store_mask32(mem_addr: *mut __mmask32, a: __mmask32) { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(mov))] //should be kmovq -pub unsafe fn _load_mask64(mem_addr: *const __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _load_mask64(mem_addr: *const __mmask64) -> __mmask64 { ptr::read(mem_addr as *const __mmask64) } @@ -9811,7 +10614,8 @@ pub unsafe fn _load_mask64(mem_addr: *const __mmask64) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(mov))] //should be kmovd -pub unsafe fn _load_mask32(mem_addr: *const __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _load_mask32(mem_addr: *const __mmask32) -> __mmask32 { ptr::read(mem_addr as *const __mmask32) } @@ -10010,7 +10814,8 @@ pub fn _mm_maskz_dbsad_epu8(k: __mmask8, a: __m128i, b: __m128i #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovw2m))] -pub fn _mm512_movepi16_mask(a: __m512i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movepi16_mask(a: __m512i) -> __mmask32 { let filter = _mm512_set1_epi16(1 << 15); let a = _mm512_and_si512(a, filter); _mm512_cmpeq_epi16_mask(a, filter) @@ -10023,7 +10828,8 @@ pub fn _mm512_movepi16_mask(a: __m512i) -> __mmask32 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovw2m))] -pub fn _mm256_movepi16_mask(a: __m256i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movepi16_mask(a: __m256i) -> __mmask16 { let filter = _mm256_set1_epi16(1 << 15); let a = _mm256_and_si256(a, filter); _mm256_cmpeq_epi16_mask(a, filter) @@ -10036,7 +10842,8 @@ pub fn _mm256_movepi16_mask(a: __m256i) -> __mmask16 { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovw2m))] -pub fn _mm_movepi16_mask(a: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movepi16_mask(a: __m128i) -> __mmask8 { let filter = _mm_set1_epi16(1 << 15); let a = _mm_and_si128(a, filter); _mm_cmpeq_epi16_mask(a, filter) @@ -10049,7 +10856,8 @@ pub fn _mm_movepi16_mask(a: __m128i) -> __mmask8 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovb2m))] -pub fn _mm512_movepi8_mask(a: __m512i) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movepi8_mask(a: __m512i) -> __mmask64 { let filter = _mm512_set1_epi8(1 << 7); let a = _mm512_and_si512(a, filter); _mm512_cmpeq_epi8_mask(a, filter) @@ -10061,9 +10869,11 @@ pub fn _mm512_movepi8_mask(a: __m512i) -> __mmask64 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -#[cfg_attr(test, assert_instr(vpmovmskb))] // should be vpmovb2m but compiled to vpmovmskb in the test shim because that takes less cycles than +#[cfg_attr(test, assert_instr(vpmovmskb))] +// should be vpmovb2m but compiled to vpmovmskb in the test shim because that takes less cycles than // using vpmovb2m plus converting the mask register to a standard register. -pub fn _mm256_movepi8_mask(a: __m256i) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movepi8_mask(a: __m256i) -> __mmask32 { let filter = _mm256_set1_epi8(1 << 7); let a = _mm256_and_si256(a, filter); _mm256_cmpeq_epi8_mask(a, filter) @@ -10075,9 +10885,11 @@ pub fn _mm256_movepi8_mask(a: __m256i) -> __mmask32 { #[inline] #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -#[cfg_attr(test, assert_instr(vpmovmskb))] // should be vpmovb2m but compiled to vpmovmskb in the test shim because that takes less cycles than +#[cfg_attr(test, assert_instr(vpmovmskb))] +// should be vpmovb2m but compiled to vpmovmskb in the test shim because that takes less cycles than // using vpmovb2m plus converting the mask register to a standard register. -pub fn _mm_movepi8_mask(a: __m128i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movepi8_mask(a: __m128i) -> __mmask16 { let filter = _mm_set1_epi8(1 << 7); let a = _mm_and_si128(a, filter); _mm_cmpeq_epi8_mask(a, filter) @@ -10090,7 +10902,8 @@ pub fn _mm_movepi8_mask(a: __m128i) -> __mmask16 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovm2w))] -pub fn _mm512_movm_epi16(k: __mmask32) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movm_epi16(k: __mmask32) -> __m512i { unsafe { let one = _mm512_set1_epi16( 1 << 15 @@ -10122,7 +10935,8 @@ pub fn _mm512_movm_epi16(k: __mmask32) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovm2w))] -pub fn _mm256_movm_epi16(k: __mmask16) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movm_epi16(k: __mmask16) -> __m256i { unsafe { let one = _mm256_set1_epi16( 1 << 15 @@ -10154,7 +10968,8 @@ pub fn _mm256_movm_epi16(k: __mmask16) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovm2w))] -pub fn _mm_movm_epi16(k: __mmask8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movm_epi16(k: __mmask8) -> __m128i { unsafe { let one = _mm_set1_epi16( 1 << 15 @@ -10186,7 +11001,8 @@ pub fn _mm_movm_epi16(k: __mmask8) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovm2b))] -pub fn _mm512_movm_epi8(k: __mmask64) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movm_epi8(k: __mmask64) -> __m512i { unsafe { let one = _mm512_set1_epi8(1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0) @@ -10202,7 +11018,8 @@ pub fn _mm512_movm_epi8(k: __mmask64) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovm2b))] -pub fn _mm256_movm_epi8(k: __mmask32) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movm_epi8(k: __mmask32) -> __m256i { unsafe { let one = _mm256_set1_epi8(1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0) @@ -10218,7 +11035,8 @@ pub fn _mm256_movm_epi8(k: __mmask32) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovm2b))] -pub fn _mm_movm_epi8(k: __mmask16) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movm_epi8(k: __mmask16) -> __m128i { unsafe { let one = _mm_set1_epi8(1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1 << 0) @@ -10233,7 +11051,8 @@ pub fn _mm_movm_epi8(k: __mmask16) -> __m128i { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _cvtmask32_u32(a: __mmask32) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _cvtmask32_u32(a: __mmask32) -> u32 { a } @@ -10243,7 +11062,8 @@ pub fn _cvtmask32_u32(a: __mmask32) -> u32 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _cvtu32_mask32(a: u32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _cvtu32_mask32(a: u32) -> __mmask32 { a } @@ -10253,7 +11073,8 @@ pub fn _cvtu32_mask32(a: u32) -> __mmask32 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kadd_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kadd_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { a.wrapping_add(b) } @@ -10263,7 +11084,8 @@ pub fn _kadd_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kadd_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kadd_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { a.wrapping_add(b) } @@ -10273,7 +11095,8 @@ pub fn _kadd_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kand_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kand_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { a & b } @@ -10283,7 +11106,8 @@ pub fn _kand_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kand_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kand_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { a & b } @@ -10293,7 +11117,8 @@ pub fn _kand_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _knot_mask32(a: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _knot_mask32(a: __mmask32) -> __mmask32 { !a } @@ -10303,7 +11128,8 @@ pub fn _knot_mask32(a: __mmask32) -> __mmask32 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _knot_mask64(a: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _knot_mask64(a: __mmask64) -> __mmask64 { !a } @@ -10313,7 +11139,8 @@ pub fn _knot_mask64(a: __mmask64) -> __mmask64 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kandn_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kandn_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { _knot_mask32(a) & b } @@ -10323,7 +11150,8 @@ pub fn _kandn_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kandn_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kandn_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { _knot_mask64(a) & b } @@ -10333,7 +11161,8 @@ pub fn _kandn_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { a | b } @@ -10343,7 +11172,8 @@ pub fn _kor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { a | b } @@ -10353,7 +11183,8 @@ pub fn _kor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kxor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kxor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { a ^ b } @@ -10363,7 +11194,8 @@ pub fn _kxor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kxor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kxor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { a ^ b } @@ -10373,7 +11205,8 @@ pub fn _kxor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kxnor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kxnor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { _knot_mask32(a ^ b) } @@ -10383,7 +11216,8 @@ pub fn _kxnor_mask32(a: __mmask32, b: __mmask32) -> __mmask32 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kxnor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kxnor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { _knot_mask64(a ^ b) } @@ -10394,7 +11228,8 @@ pub fn _kxnor_mask64(a: __mmask64, b: __mmask64) -> __mmask64 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _kortest_mask32_u8(a: __mmask32, b: __mmask32, all_ones: *mut u8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _kortest_mask32_u8(a: __mmask32, b: __mmask32, all_ones: *mut u8) -> u8 { let tmp = _kor_mask32(a, b); *all_ones = (tmp == 0xffffffff) as u8; (tmp == 0) as u8 @@ -10407,7 +11242,8 @@ pub unsafe fn _kortest_mask32_u8(a: __mmask32, b: __mmask32, all_ones: *mut u8) #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _kortest_mask64_u8(a: __mmask64, b: __mmask64, all_ones: *mut u8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _kortest_mask64_u8(a: __mmask64, b: __mmask64, all_ones: *mut u8) -> u8 { let tmp = _kor_mask64(a, b); *all_ones = (tmp == 0xffffffff_ffffffff) as u8; (tmp == 0) as u8 @@ -10420,7 +11256,8 @@ pub unsafe fn _kortest_mask64_u8(a: __mmask64, b: __mmask64, all_ones: *mut u8) #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kortestc_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kortestc_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { (_kor_mask32(a, b) == 0xffffffff) as u8 } @@ -10431,7 +11268,8 @@ pub fn _kortestc_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kortestc_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kortestc_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { (_kor_mask64(a, b) == 0xffffffff_ffffffff) as u8 } @@ -10442,7 +11280,8 @@ pub fn _kortestc_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kortestz_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kortestz_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { (_kor_mask32(a, b) == 0) as u8 } @@ -10453,7 +11292,8 @@ pub fn _kortestz_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kortestz_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kortestz_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { (_kor_mask64(a, b) == 0) as u8 } @@ -10464,7 +11304,8 @@ pub fn _kortestz_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { #[target_feature(enable = "avx512bw")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kshiftli_mask32(a: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kshiftli_mask32(a: __mmask32) -> __mmask32 { a.unbounded_shl(COUNT) } @@ -10475,7 +11316,8 @@ pub fn _kshiftli_mask32(a: __mmask32) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kshiftli_mask64(a: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kshiftli_mask64(a: __mmask64) -> __mmask64 { a.unbounded_shl(COUNT) } @@ -10486,7 +11328,8 @@ pub fn _kshiftli_mask64(a: __mmask64) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kshiftri_mask32(a: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kshiftri_mask32(a: __mmask32) -> __mmask32 { a.unbounded_shr(COUNT) } @@ -10497,7 +11340,8 @@ pub fn _kshiftri_mask32(a: __mmask32) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kshiftri_mask64(a: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kshiftri_mask64(a: __mmask64) -> __mmask64 { a.unbounded_shr(COUNT) } @@ -10509,7 +11353,8 @@ pub fn _kshiftri_mask64(a: __mmask64) -> __mmask64 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _ktest_mask32_u8(a: __mmask32, b: __mmask32, and_not: *mut u8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _ktest_mask32_u8(a: __mmask32, b: __mmask32, and_not: *mut u8) -> u8 { *and_not = (_kandn_mask32(a, b) == 0) as u8; (_kand_mask32(a, b) == 0) as u8 } @@ -10522,7 +11367,8 @@ pub unsafe fn _ktest_mask32_u8(a: __mmask32, b: __mmask32, and_not: *mut u8) -> #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _ktest_mask64_u8(a: __mmask64, b: __mmask64, and_not: *mut u8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _ktest_mask64_u8(a: __mmask64, b: __mmask64, and_not: *mut u8) -> u8 { *and_not = (_kandn_mask64(a, b) == 0) as u8; (_kand_mask64(a, b) == 0) as u8 } @@ -10534,7 +11380,8 @@ pub unsafe fn _ktest_mask64_u8(a: __mmask64, b: __mmask64, and_not: *mut u8) -> #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _ktestc_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _ktestc_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { (_kandn_mask32(a, b) == 0) as u8 } @@ -10545,7 +11392,8 @@ pub fn _ktestc_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _ktestc_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _ktestc_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { (_kandn_mask64(a, b) == 0) as u8 } @@ -10556,7 +11404,8 @@ pub fn _ktestc_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _ktestz_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _ktestz_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { (_kand_mask32(a, b) == 0) as u8 } @@ -10567,7 +11416,8 @@ pub fn _ktestz_mask32_u8(a: __mmask32, b: __mmask32) -> u8 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _ktestz_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _ktestz_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { (_kand_mask64(a, b) == 0) as u8 } @@ -10578,7 +11428,8 @@ pub fn _ktestz_mask64_u8(a: __mmask64, b: __mmask64) -> u8 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(mov))] // generate normal and code instead of kunpckwd -pub fn _mm512_kunpackw(a: __mmask32, b: __mmask32) -> __mmask32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kunpackw(a: __mmask32, b: __mmask32) -> __mmask32 { ((a & 0xffff) << 16) | (b & 0xffff) } @@ -10589,7 +11440,8 @@ pub fn _mm512_kunpackw(a: __mmask32, b: __mmask32) -> __mmask32 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(mov))] // generate normal and code instead of kunpckdq -pub fn _mm512_kunpackd(a: __mmask64, b: __mmask64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_kunpackd(a: __mmask64, b: __mmask64) -> __mmask64 { ((a & 0xffffffff) << 32) | (b & 0xffffffff) } @@ -10600,7 +11452,8 @@ pub fn _mm512_kunpackd(a: __mmask64, b: __mmask64) -> __mmask64 { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub fn _mm512_cvtepi16_epi8(a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi16_epi8(a: __m512i) -> __m256i { unsafe { let a = a.as_i16x32(); transmute::(simd_cast(a)) @@ -10614,7 +11467,8 @@ pub fn _mm512_cvtepi16_epi8(a: __m512i) -> __m256i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub fn _mm512_mask_cvtepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m256i { unsafe { let convert = _mm512_cvtepi16_epi8(a).as_i8x32(); transmute(simd_select_bitmask(k, convert, src.as_i8x32())) @@ -10628,7 +11482,8 @@ pub fn _mm512_mask_cvtepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m2 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub fn _mm512_maskz_cvtepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { unsafe { let convert = _mm512_cvtepi16_epi8(a).as_i8x32(); transmute(simd_select_bitmask(k, convert, i8x32::ZERO)) @@ -10642,7 +11497,8 @@ pub fn _mm512_maskz_cvtepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub fn _mm256_cvtepi16_epi8(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtepi16_epi8(a: __m256i) -> __m128i { unsafe { let a = a.as_i16x16(); transmute::(simd_cast(a)) @@ -10656,7 +11512,8 @@ pub fn _mm256_cvtepi16_epi8(a: __m256i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub fn _mm256_mask_cvtepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m128i { unsafe { let convert = _mm256_cvtepi16_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, convert, src.as_i8x16())) @@ -10670,7 +11527,8 @@ pub fn _mm256_mask_cvtepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m1 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub fn _mm256_maskz_cvtepi16_epi8(k: __mmask16, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi16_epi8(k: __mmask16, a: __m256i) -> __m128i { unsafe { let convert = _mm256_cvtepi16_epi8(a).as_i8x16(); transmute(simd_select_bitmask(k, convert, i8x16::ZERO)) @@ -10684,7 +11542,8 @@ pub fn _mm256_maskz_cvtepi16_epi8(k: __mmask16, a: __m256i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub fn _mm_cvtepi16_epi8(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtepi16_epi8(a: __m128i) -> __m128i { unsafe { let a = a.as_i16x8(); let v256: i16x16 = simd_shuffle!( @@ -10703,7 +11562,8 @@ pub fn _mm_cvtepi16_epi8(a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub fn _mm_mask_cvtepi16_epi8(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepi16_epi8(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let a = _mm_cvtepi16_epi8(a).as_i8x16(); let src = simd_shuffle!( @@ -10722,7 +11582,8 @@ pub fn _mm_mask_cvtepi16_epi8(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub fn _mm_maskz_cvtepi16_epi8(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepi16_epi8(k: __mmask8, a: __m128i) -> __m128i { _mm_mask_cvtepi16_epi8(_mm_setzero_si128(), k, a) } @@ -10733,7 +11594,8 @@ pub fn _mm_maskz_cvtepi16_epi8(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] -pub fn _mm512_cvtsepi16_epi8(a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm512_cvtsepi16_epi8(a: __m512i) -> __m256i { unsafe { simd_cast::<_, i8x32>(simd_imax( simd_imin(a.as_i16x32(), i16x32::splat(i8::MAX as _)), @@ -10750,7 +11612,8 @@ pub fn _mm512_cvtsepi16_epi8(a: __m512i) -> __m256i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] -pub fn _mm512_mask_cvtsepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm512_mask_cvtsepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m256i { unsafe { simd_select_bitmask(k, _mm512_cvtsepi16_epi8(a).as_i8x32(), src.as_i8x32()).as_m256i() } @@ -10763,7 +11626,8 @@ pub fn _mm512_mask_cvtsepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] -pub fn _mm512_maskz_cvtsepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm512_maskz_cvtsepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { unsafe { simd_select_bitmask(k, _mm512_cvtsepi16_epi8(a).as_i8x32(), i8x32::ZERO).as_m256i() } } @@ -10774,7 +11638,8 @@ pub fn _mm512_maskz_cvtsepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] -pub fn _mm256_cvtsepi16_epi8(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm256_cvtsepi16_epi8(a: __m256i) -> __m128i { unsafe { simd_cast::<_, i8x16>(simd_imax( simd_imin(a.as_i16x16(), i16x16::splat(i8::MAX as _)), @@ -10791,7 +11656,8 @@ pub fn _mm256_cvtsepi16_epi8(a: __m256i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] -pub fn _mm256_mask_cvtsepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm256_mask_cvtsepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m128i { unsafe { simd_select_bitmask(k, _mm256_cvtsepi16_epi8(a).as_i8x16(), src.as_i8x16()).as_m128i() } @@ -10804,7 +11670,8 @@ pub fn _mm256_mask_cvtsepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] -pub fn _mm256_maskz_cvtsepi16_epi8(k: __mmask16, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm256_maskz_cvtsepi16_epi8(k: __mmask16, a: __m256i) -> __m128i { unsafe { simd_select_bitmask(k, _mm256_cvtsepi16_epi8(a).as_i8x16(), i8x16::ZERO).as_m128i() } } @@ -10848,7 +11715,8 @@ pub fn _mm_maskz_cvtsepi16_epi8(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] -pub fn _mm512_cvtusepi16_epi8(a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm512_cvtusepi16_epi8(a: __m512i) -> __m256i { unsafe { simd_cast::<_, u8x32>(simd_imin(a.as_u16x32(), u16x32::splat(u8::MAX as _))).as_m256i() } @@ -10861,7 +11729,8 @@ pub fn _mm512_cvtusepi16_epi8(a: __m512i) -> __m256i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] -pub fn _mm512_mask_cvtusepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm512_mask_cvtusepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __m256i { unsafe { simd_select_bitmask(k, _mm512_cvtusepi16_epi8(a).as_u8x32(), src.as_u8x32()).as_m256i() } @@ -10874,7 +11743,8 @@ pub fn _mm512_mask_cvtusepi16_epi8(src: __m256i, k: __mmask32, a: __m512i) -> __ #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] -pub fn _mm512_maskz_cvtusepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm512_maskz_cvtusepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { unsafe { simd_select_bitmask(k, _mm512_cvtusepi16_epi8(a).as_u8x32(), u8x32::ZERO).as_m256i() } } @@ -10885,7 +11755,8 @@ pub fn _mm512_maskz_cvtusepi16_epi8(k: __mmask32, a: __m512i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] -pub fn _mm256_cvtusepi16_epi8(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm256_cvtusepi16_epi8(a: __m256i) -> __m128i { unsafe { simd_cast::<_, u8x16>(simd_imin(a.as_u16x16(), u16x16::splat(u8::MAX as _))).as_m128i() } @@ -10898,7 +11769,8 @@ pub fn _mm256_cvtusepi16_epi8(a: __m256i) -> __m128i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] -pub fn _mm256_mask_cvtusepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm256_mask_cvtusepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __m128i { unsafe { simd_select_bitmask(k, _mm256_cvtusepi16_epi8(a).as_u8x16(), src.as_u8x16()).as_m128i() } @@ -10911,7 +11783,8 @@ pub fn _mm256_mask_cvtusepi16_epi8(src: __m128i, k: __mmask16, a: __m256i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] -pub fn _mm256_maskz_cvtusepi16_epi8(k: __mmask16, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const fn _mm256_maskz_cvtusepi16_epi8(k: __mmask16, a: __m256i) -> __m128i { unsafe { simd_select_bitmask(k, _mm256_cvtusepi16_epi8(a).as_u8x16(), u8x16::ZERO).as_m128i() } } @@ -10955,7 +11828,8 @@ pub fn _mm_maskz_cvtusepi16_epi8(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbw))] -pub fn _mm512_cvtepi8_epi16(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepi8_epi16(a: __m256i) -> __m512i { unsafe { let a = a.as_i8x32(); transmute::(simd_cast(a)) @@ -10969,7 +11843,8 @@ pub fn _mm512_cvtepi8_epi16(a: __m256i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbw))] -pub fn _mm512_mask_cvtepi8_epi16(src: __m512i, k: __mmask32, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepi8_epi16(src: __m512i, k: __mmask32, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepi8_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, convert, src.as_i16x32())) @@ -10983,7 +11858,8 @@ pub fn _mm512_mask_cvtepi8_epi16(src: __m512i, k: __mmask32, a: __m256i) -> __m5 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbw))] -pub fn _mm512_maskz_cvtepi8_epi16(k: __mmask32, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepi8_epi16(k: __mmask32, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepi8_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, convert, i16x32::ZERO)) @@ -10997,7 +11873,8 @@ pub fn _mm512_maskz_cvtepi8_epi16(k: __mmask32, a: __m256i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbw))] -pub fn _mm256_mask_cvtepi8_epi16(src: __m256i, k: __mmask16, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepi8_epi16(src: __m256i, k: __mmask16, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi8_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, convert, src.as_i16x16())) @@ -11011,7 +11888,8 @@ pub fn _mm256_mask_cvtepi8_epi16(src: __m256i, k: __mmask16, a: __m128i) -> __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbw))] -pub fn _mm256_maskz_cvtepi8_epi16(k: __mmask16, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepi8_epi16(k: __mmask16, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepi8_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, convert, i16x16::ZERO)) @@ -11025,7 +11903,8 @@ pub fn _mm256_maskz_cvtepi8_epi16(k: __mmask16, a: __m128i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbw))] -pub fn _mm_mask_cvtepi8_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepi8_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi8_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, convert, src.as_i16x8())) @@ -11039,7 +11918,8 @@ pub fn _mm_mask_cvtepi8_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovsxbw))] -pub fn _mm_maskz_cvtepi8_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepi8_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepi8_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, convert, i16x8::ZERO)) @@ -11053,7 +11933,8 @@ pub fn _mm_maskz_cvtepi8_epi16(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbw))] -pub fn _mm512_cvtepu8_epi16(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtepu8_epi16(a: __m256i) -> __m512i { unsafe { let a = a.as_u8x32(); transmute::(simd_cast(a)) @@ -11067,7 +11948,8 @@ pub fn _mm512_cvtepu8_epi16(a: __m256i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbw))] -pub fn _mm512_mask_cvtepu8_epi16(src: __m512i, k: __mmask32, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_cvtepu8_epi16(src: __m512i, k: __mmask32, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepu8_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, convert, src.as_i16x32())) @@ -11081,7 +11963,8 @@ pub fn _mm512_mask_cvtepu8_epi16(src: __m512i, k: __mmask32, a: __m256i) -> __m5 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbw))] -pub fn _mm512_maskz_cvtepu8_epi16(k: __mmask32, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_cvtepu8_epi16(k: __mmask32, a: __m256i) -> __m512i { unsafe { let convert = _mm512_cvtepu8_epi16(a).as_i16x32(); transmute(simd_select_bitmask(k, convert, i16x32::ZERO)) @@ -11095,7 +11978,8 @@ pub fn _mm512_maskz_cvtepu8_epi16(k: __mmask32, a: __m256i) -> __m512i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbw))] -pub fn _mm256_mask_cvtepu8_epi16(src: __m256i, k: __mmask16, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_cvtepu8_epi16(src: __m256i, k: __mmask16, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu8_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, convert, src.as_i16x16())) @@ -11109,7 +11993,8 @@ pub fn _mm256_mask_cvtepu8_epi16(src: __m256i, k: __mmask16, a: __m128i) -> __m2 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbw))] -pub fn _mm256_maskz_cvtepu8_epi16(k: __mmask16, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_cvtepu8_epi16(k: __mmask16, a: __m128i) -> __m256i { unsafe { let convert = _mm256_cvtepu8_epi16(a).as_i16x16(); transmute(simd_select_bitmask(k, convert, i16x16::ZERO)) @@ -11123,7 +12008,8 @@ pub fn _mm256_maskz_cvtepu8_epi16(k: __mmask16, a: __m128i) -> __m256i { #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbw))] -pub fn _mm_mask_cvtepu8_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_cvtepu8_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu8_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, convert, src.as_i16x8())) @@ -11137,7 +12023,8 @@ pub fn _mm_mask_cvtepu8_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovzxbw))] -pub fn _mm_maskz_cvtepu8_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_cvtepu8_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { let convert = _mm_cvtepu8_epi16(a).as_i16x8(); transmute(simd_select_bitmask(k, convert, i16x8::ZERO)) @@ -11152,7 +12039,8 @@ pub fn _mm_maskz_cvtepu8_epi16(k: __mmask8, a: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpslldq, IMM8 = 3))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_bslli_epi128(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_bslli_epi128(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); const fn mask(shift: i32, i: u32) -> u32 { @@ -11247,7 +12135,8 @@ pub fn _mm512_bslli_epi128(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpsrldq, IMM8 = 3))] #[rustc_legacy_const_generics(1)] -pub fn _mm512_bsrli_epi128(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_bsrli_epi128(a: __m512i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); const fn mask(shift: i32, i: u32) -> u32 { @@ -11344,7 +12233,8 @@ pub fn _mm512_bsrli_epi128(a: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 1))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_alignr_epi8(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_alignr_epi8(a: __m512i, b: __m512i) -> __m512i { const fn mask(shift: u32, i: u32) -> u32 { let shift = shift % 16; let mod_i = i % 16; @@ -11454,7 +12344,8 @@ pub fn _mm512_alignr_epi8(a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 1))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_alignr_epi8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_alignr_epi8( src: __m512i, k: __mmask64, a: __m512i, @@ -11475,7 +12366,12 @@ pub fn _mm512_mask_alignr_epi8( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 1))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_alignr_epi8(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_alignr_epi8( + k: __mmask64, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm512_alignr_epi8::(a, b); @@ -11491,7 +12387,8 @@ pub fn _mm512_maskz_alignr_epi8(k: __mmask64, a: __m512i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(4)] #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 5))] -pub fn _mm256_mask_alignr_epi8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_alignr_epi8( src: __m256i, k: __mmask32, a: __m256i, @@ -11512,7 +12409,12 @@ pub fn _mm256_mask_alignr_epi8( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 5))] -pub fn _mm256_maskz_alignr_epi8(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_alignr_epi8( + k: __mmask32, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm256_alignr_epi8::(a, b); @@ -11528,7 +12430,8 @@ pub fn _mm256_maskz_alignr_epi8(k: __mmask32, a: __m256i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(4)] #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 5))] -pub fn _mm_mask_alignr_epi8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_alignr_epi8( src: __m128i, k: __mmask16, a: __m128i, @@ -11549,7 +12452,12 @@ pub fn _mm_mask_alignr_epi8( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[rustc_legacy_const_generics(3)] #[cfg_attr(test, assert_instr(vpalignr, IMM8 = 5))] -pub fn _mm_maskz_alignr_epi8(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_alignr_epi8( + k: __mmask16, + a: __m128i, + b: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let r = _mm_alignr_epi8::(a, b); @@ -11597,7 +12505,8 @@ pub unsafe fn _mm_mask_cvtsepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask8, a: #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub unsafe fn _mm512_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask32, a: __m512i) { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const unsafe fn _mm512_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask32, a: __m512i) { let result = _mm512_cvtepi16_epi8(a).as_i8x32(); let mask = simd_select_bitmask(k, i8x32::splat(!0), i8x32::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, result); @@ -11610,7 +12519,8 @@ pub unsafe fn _mm512_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask32, #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub unsafe fn _mm256_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask16, a: __m256i) { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const unsafe fn _mm256_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask16, a: __m256i) { let result = _mm256_cvtepi16_epi8(a).as_i8x16(); let mask = simd_select_bitmask(k, i8x16::splat(!0), i8x16::ZERO); simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, result); @@ -11623,7 +12533,8 @@ pub unsafe fn _mm256_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask16, #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovwb))] -pub unsafe fn _mm_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask8, a: __m128i) { +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +pub const unsafe fn _mm_mask_cvtepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask8, a: __m128i) { let result: i8x8 = simd_shuffle!( _mm_cvtepi16_epi8(a).as_i8x16(), i8x16::ZERO, @@ -11742,6 +12653,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; @@ -11750,7 +12662,7 @@ mod tests { use crate::mem::{self}; #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_abs_epi16() { + const unsafe fn test_mm512_abs_epi16() { let a = _mm512_set1_epi16(-1); let r = _mm512_abs_epi16(a); let e = _mm512_set1_epi16(1); @@ -11758,7 +12670,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_abs_epi16() { + const unsafe fn test_mm512_mask_abs_epi16() { let a = _mm512_set1_epi16(-1); let r = _mm512_mask_abs_epi16(a, 0, a); assert_eq_m512i(r, a); @@ -11770,7 +12682,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_abs_epi16() { + const unsafe fn test_mm512_maskz_abs_epi16() { let a = _mm512_set1_epi16(-1); let r = _mm512_maskz_abs_epi16(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -11782,7 +12694,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_abs_epi16() { + const unsafe fn test_mm256_mask_abs_epi16() { let a = _mm256_set1_epi16(-1); let r = _mm256_mask_abs_epi16(a, 0, a); assert_eq_m256i(r, a); @@ -11792,7 +12704,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_abs_epi16() { + const unsafe fn test_mm256_maskz_abs_epi16() { let a = _mm256_set1_epi16(-1); let r = _mm256_maskz_abs_epi16(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -11802,7 +12714,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_abs_epi16() { + const unsafe fn test_mm_mask_abs_epi16() { let a = _mm_set1_epi16(-1); let r = _mm_mask_abs_epi16(a, 0, a); assert_eq_m128i(r, a); @@ -11812,7 +12724,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_abs_epi16() { + const unsafe fn test_mm_maskz_abs_epi16() { let a = _mm_set1_epi16(-1); let r = _mm_maskz_abs_epi16(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -11822,7 +12734,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_abs_epi8() { + const unsafe fn test_mm512_abs_epi8() { let a = _mm512_set1_epi8(-1); let r = _mm512_abs_epi8(a); let e = _mm512_set1_epi8(1); @@ -11830,7 +12742,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_abs_epi8() { + const unsafe fn test_mm512_mask_abs_epi8() { let a = _mm512_set1_epi8(-1); let r = _mm512_mask_abs_epi8(a, 0, a); assert_eq_m512i(r, a); @@ -11848,7 +12760,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_abs_epi8() { + const unsafe fn test_mm512_maskz_abs_epi8() { let a = _mm512_set1_epi8(-1); let r = _mm512_maskz_abs_epi8(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -11865,7 +12777,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_abs_epi8() { + const unsafe fn test_mm256_mask_abs_epi8() { let a = _mm256_set1_epi8(-1); let r = _mm256_mask_abs_epi8(a, 0, a); assert_eq_m256i(r, a); @@ -11877,7 +12789,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_abs_epi8() { + const unsafe fn test_mm256_maskz_abs_epi8() { let a = _mm256_set1_epi8(-1); let r = _mm256_maskz_abs_epi8(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -11889,7 +12801,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_abs_epi8() { + const unsafe fn test_mm_mask_abs_epi8() { let a = _mm_set1_epi8(-1); let r = _mm_mask_abs_epi8(a, 0, a); assert_eq_m128i(r, a); @@ -11899,7 +12811,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_abs_epi8() { + const unsafe fn test_mm_maskz_abs_epi8() { let a = _mm_set1_epi8(-1); let r = _mm_maskz_abs_epi8(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -11910,7 +12822,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_add_epi16() { + const unsafe fn test_mm512_add_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(2); let r = _mm512_add_epi16(a, b); @@ -11919,7 +12831,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_add_epi16() { + const unsafe fn test_mm512_mask_add_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(2); let r = _mm512_mask_add_epi16(a, 0, a, b); @@ -11932,7 +12844,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_add_epi16() { + const unsafe fn test_mm512_maskz_add_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(2); let r = _mm512_maskz_add_epi16(0, a, b); @@ -11945,7 +12857,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_add_epi16() { + const unsafe fn test_mm256_mask_add_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(2); let r = _mm256_mask_add_epi16(a, 0, a, b); @@ -11956,7 +12868,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_add_epi16() { + const unsafe fn test_mm256_maskz_add_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(2); let r = _mm256_maskz_add_epi16(0, a, b); @@ -11967,7 +12879,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_add_epi16() { + const unsafe fn test_mm_mask_add_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(2); let r = _mm_mask_add_epi16(a, 0, a, b); @@ -11978,7 +12890,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_add_epi16() { + const unsafe fn test_mm_maskz_add_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(2); let r = _mm_maskz_add_epi16(0, a, b); @@ -11989,7 +12901,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_add_epi8() { + const unsafe fn test_mm512_add_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(2); let r = _mm512_add_epi8(a, b); @@ -11998,7 +12910,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_add_epi8() { + const unsafe fn test_mm512_mask_add_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(2); let r = _mm512_mask_add_epi8(a, 0, a, b); @@ -12018,7 +12930,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_add_epi8() { + const unsafe fn test_mm512_maskz_add_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(2); let r = _mm512_maskz_add_epi8(0, a, b); @@ -12037,7 +12949,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_add_epi8() { + const unsafe fn test_mm256_mask_add_epi8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(2); let r = _mm256_mask_add_epi8(a, 0, a, b); @@ -12050,7 +12962,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_add_epi8() { + const unsafe fn test_mm256_maskz_add_epi8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(2); let r = _mm256_maskz_add_epi8(0, a, b); @@ -12063,7 +12975,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_add_epi8() { + const unsafe fn test_mm_mask_add_epi8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(2); let r = _mm_mask_add_epi8(a, 0, a, b); @@ -12074,7 +12986,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_add_epi8() { + const unsafe fn test_mm_maskz_add_epi8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(2); let r = _mm_maskz_add_epi8(0, a, b); @@ -12085,7 +12997,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_adds_epu16() { + const unsafe fn test_mm512_adds_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(u16::MAX as i16); let r = _mm512_adds_epu16(a, b); @@ -12094,7 +13006,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_adds_epu16() { + const unsafe fn test_mm512_mask_adds_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(u16::MAX as i16); let r = _mm512_mask_adds_epu16(a, 0, a, b); @@ -12107,7 +13019,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_adds_epu16() { + const unsafe fn test_mm512_maskz_adds_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(u16::MAX as i16); let r = _mm512_maskz_adds_epu16(0, a, b); @@ -12120,7 +13032,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_adds_epu16() { + const unsafe fn test_mm256_mask_adds_epu16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(u16::MAX as i16); let r = _mm256_mask_adds_epu16(a, 0, a, b); @@ -12132,7 +13044,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_adds_epu16() { + const unsafe fn test_mm256_maskz_adds_epu16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(u16::MAX as i16); let r = _mm256_maskz_adds_epu16(0, a, b); @@ -12144,7 +13056,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_adds_epu16() { + const unsafe fn test_mm_mask_adds_epu16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(u16::MAX as i16); let r = _mm_mask_adds_epu16(a, 0, a, b); @@ -12156,7 +13068,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_adds_epu16() { + const unsafe fn test_mm_maskz_adds_epu16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(u16::MAX as i16); let r = _mm_maskz_adds_epu16(0, a, b); @@ -12168,7 +13080,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_adds_epu8() { + const unsafe fn test_mm512_adds_epu8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(u8::MAX as i8); let r = _mm512_adds_epu8(a, b); @@ -12177,7 +13089,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_adds_epu8() { + const unsafe fn test_mm512_mask_adds_epu8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(u8::MAX as i8); let r = _mm512_mask_adds_epu8(a, 0, a, b); @@ -12197,7 +13109,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_adds_epu8() { + const unsafe fn test_mm512_maskz_adds_epu8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(u8::MAX as i8); let r = _mm512_maskz_adds_epu8(0, a, b); @@ -12216,7 +13128,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_adds_epu8() { + const unsafe fn test_mm256_mask_adds_epu8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(u8::MAX as i8); let r = _mm256_mask_adds_epu8(a, 0, a, b); @@ -12229,7 +13141,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_adds_epu8() { + const unsafe fn test_mm256_maskz_adds_epu8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(u8::MAX as i8); let r = _mm256_maskz_adds_epu8(0, a, b); @@ -12242,7 +13154,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_adds_epu8() { + const unsafe fn test_mm_mask_adds_epu8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(u8::MAX as i8); let r = _mm_mask_adds_epu8(a, 0, a, b); @@ -12254,7 +13166,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_adds_epu8() { + const unsafe fn test_mm_maskz_adds_epu8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(u8::MAX as i8); let r = _mm_maskz_adds_epu8(0, a, b); @@ -12266,7 +13178,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_adds_epi16() { + const unsafe fn test_mm512_adds_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(i16::MAX); let r = _mm512_adds_epi16(a, b); @@ -12275,7 +13187,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_adds_epi16() { + const unsafe fn test_mm512_mask_adds_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(i16::MAX); let r = _mm512_mask_adds_epi16(a, 0, a, b); @@ -12288,7 +13200,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_adds_epi16() { + const unsafe fn test_mm512_maskz_adds_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(i16::MAX); let r = _mm512_maskz_adds_epi16(0, a, b); @@ -12301,7 +13213,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_adds_epi16() { + const unsafe fn test_mm256_mask_adds_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(i16::MAX); let r = _mm256_mask_adds_epi16(a, 0, a, b); @@ -12313,7 +13225,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_adds_epi16() { + const unsafe fn test_mm256_maskz_adds_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(i16::MAX); let r = _mm256_maskz_adds_epi16(0, a, b); @@ -12325,7 +13237,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_adds_epi16() { + const unsafe fn test_mm_mask_adds_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(i16::MAX); let r = _mm_mask_adds_epi16(a, 0, a, b); @@ -12336,7 +13248,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_adds_epi16() { + const unsafe fn test_mm_maskz_adds_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(i16::MAX); let r = _mm_maskz_adds_epi16(0, a, b); @@ -12347,7 +13259,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_adds_epi8() { + const unsafe fn test_mm512_adds_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(i8::MAX); let r = _mm512_adds_epi8(a, b); @@ -12356,7 +13268,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_adds_epi8() { + const unsafe fn test_mm512_mask_adds_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(i8::MAX); let r = _mm512_mask_adds_epi8(a, 0, a, b); @@ -12376,7 +13288,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_adds_epi8() { + const unsafe fn test_mm512_maskz_adds_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(i8::MAX); let r = _mm512_maskz_adds_epi8(0, a, b); @@ -12395,7 +13307,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_adds_epi8() { + const unsafe fn test_mm256_mask_adds_epi8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(i8::MAX); let r = _mm256_mask_adds_epi8(a, 0, a, b); @@ -12408,7 +13320,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_adds_epi8() { + const unsafe fn test_mm256_maskz_adds_epi8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(i8::MAX); let r = _mm256_maskz_adds_epi8(0, a, b); @@ -12421,7 +13333,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_adds_epi8() { + const unsafe fn test_mm_mask_adds_epi8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(i8::MAX); let r = _mm_mask_adds_epi8(a, 0, a, b); @@ -12433,7 +13345,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_adds_epi8() { + const unsafe fn test_mm_maskz_adds_epi8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(i8::MAX); let r = _mm_maskz_adds_epi8(0, a, b); @@ -12445,7 +13357,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_sub_epi16() { + const unsafe fn test_mm512_sub_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(2); let r = _mm512_sub_epi16(a, b); @@ -12454,7 +13366,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_sub_epi16() { + const unsafe fn test_mm512_mask_sub_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(2); let r = _mm512_mask_sub_epi16(a, 0, a, b); @@ -12467,7 +13379,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_sub_epi16() { + const unsafe fn test_mm512_maskz_sub_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(2); let r = _mm512_maskz_sub_epi16(0, a, b); @@ -12480,7 +13392,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_sub_epi16() { + const unsafe fn test_mm256_mask_sub_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(2); let r = _mm256_mask_sub_epi16(a, 0, a, b); @@ -12491,7 +13403,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_sub_epi16() { + const unsafe fn test_mm256_maskz_sub_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(2); let r = _mm256_maskz_sub_epi16(0, a, b); @@ -12502,7 +13414,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_sub_epi16() { + const unsafe fn test_mm_mask_sub_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(2); let r = _mm_mask_sub_epi16(a, 0, a, b); @@ -12513,7 +13425,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_sub_epi16() { + const unsafe fn test_mm_maskz_sub_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(2); let r = _mm_maskz_sub_epi16(0, a, b); @@ -12524,7 +13436,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_sub_epi8() { + const unsafe fn test_mm512_sub_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(2); let r = _mm512_sub_epi8(a, b); @@ -12533,7 +13445,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_sub_epi8() { + const unsafe fn test_mm512_mask_sub_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(2); let r = _mm512_mask_sub_epi8(a, 0, a, b); @@ -12553,7 +13465,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_sub_epi8() { + const unsafe fn test_mm512_maskz_sub_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(2); let r = _mm512_maskz_sub_epi8(0, a, b); @@ -12572,7 +13484,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_sub_epi8() { + const unsafe fn test_mm256_mask_sub_epi8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(2); let r = _mm256_mask_sub_epi8(a, 0, a, b); @@ -12585,7 +13497,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_sub_epi8() { + const unsafe fn test_mm256_maskz_sub_epi8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(2); let r = _mm256_maskz_sub_epi8(0, a, b); @@ -12598,7 +13510,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_sub_epi8() { + const unsafe fn test_mm_mask_sub_epi8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(2); let r = _mm_mask_sub_epi8(a, 0, a, b); @@ -12609,7 +13521,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_sub_epi8() { + const unsafe fn test_mm_maskz_sub_epi8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(2); let r = _mm_maskz_sub_epi8(0, a, b); @@ -12620,7 +13532,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_subs_epu16() { + const unsafe fn test_mm512_subs_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(u16::MAX as i16); let r = _mm512_subs_epu16(a, b); @@ -12629,7 +13541,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_subs_epu16() { + const unsafe fn test_mm512_mask_subs_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(u16::MAX as i16); let r = _mm512_mask_subs_epu16(a, 0, a, b); @@ -12642,7 +13554,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_subs_epu16() { + const unsafe fn test_mm512_maskz_subs_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(u16::MAX as i16); let r = _mm512_maskz_subs_epu16(0, a, b); @@ -12655,7 +13567,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_subs_epu16() { + const unsafe fn test_mm256_mask_subs_epu16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(u16::MAX as i16); let r = _mm256_mask_subs_epu16(a, 0, a, b); @@ -12666,7 +13578,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_subs_epu16() { + const unsafe fn test_mm256_maskz_subs_epu16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(u16::MAX as i16); let r = _mm256_maskz_subs_epu16(0, a, b); @@ -12677,7 +13589,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_subs_epu16() { + const unsafe fn test_mm_mask_subs_epu16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(u16::MAX as i16); let r = _mm_mask_subs_epu16(a, 0, a, b); @@ -12688,7 +13600,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_subs_epu16() { + const unsafe fn test_mm_maskz_subs_epu16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(u16::MAX as i16); let r = _mm_maskz_subs_epu16(0, a, b); @@ -12699,7 +13611,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_subs_epu8() { + const unsafe fn test_mm512_subs_epu8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(u8::MAX as i8); let r = _mm512_subs_epu8(a, b); @@ -12708,7 +13620,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_subs_epu8() { + const unsafe fn test_mm512_mask_subs_epu8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(u8::MAX as i8); let r = _mm512_mask_subs_epu8(a, 0, a, b); @@ -12728,7 +13640,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_subs_epu8() { + const unsafe fn test_mm512_maskz_subs_epu8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(u8::MAX as i8); let r = _mm512_maskz_subs_epu8(0, a, b); @@ -12747,7 +13659,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_subs_epu8() { + const unsafe fn test_mm256_mask_subs_epu8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(u8::MAX as i8); let r = _mm256_mask_subs_epu8(a, 0, a, b); @@ -12760,7 +13672,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_subs_epu8() { + const unsafe fn test_mm256_maskz_subs_epu8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(u8::MAX as i8); let r = _mm256_maskz_subs_epu8(0, a, b); @@ -12773,7 +13685,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_subs_epu8() { + const unsafe fn test_mm_mask_subs_epu8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(u8::MAX as i8); let r = _mm_mask_subs_epu8(a, 0, a, b); @@ -12784,7 +13696,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_subs_epu8() { + const unsafe fn test_mm_maskz_subs_epu8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(u8::MAX as i8); let r = _mm_maskz_subs_epu8(0, a, b); @@ -12795,7 +13707,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_subs_epi16() { + const unsafe fn test_mm512_subs_epi16() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(i16::MAX); let r = _mm512_subs_epi16(a, b); @@ -12804,7 +13716,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_subs_epi16() { + const unsafe fn test_mm512_mask_subs_epi16() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(i16::MAX); let r = _mm512_mask_subs_epi16(a, 0, a, b); @@ -12817,7 +13729,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_subs_epi16() { + const unsafe fn test_mm512_maskz_subs_epi16() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(i16::MAX); let r = _mm512_maskz_subs_epi16(0, a, b); @@ -12830,7 +13742,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_subs_epi16() { + const unsafe fn test_mm256_mask_subs_epi16() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(i16::MAX); let r = _mm256_mask_subs_epi16(a, 0, a, b); @@ -12842,7 +13754,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_subs_epi16() { + const unsafe fn test_mm256_maskz_subs_epi16() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(i16::MAX); let r = _mm256_maskz_subs_epi16(0, a, b); @@ -12854,7 +13766,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_subs_epi16() { + const unsafe fn test_mm_mask_subs_epi16() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(i16::MAX); let r = _mm_mask_subs_epi16(a, 0, a, b); @@ -12865,7 +13777,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_subs_epi16() { + const unsafe fn test_mm_maskz_subs_epi16() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(i16::MAX); let r = _mm_maskz_subs_epi16(0, a, b); @@ -12876,7 +13788,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_subs_epi8() { + const unsafe fn test_mm512_subs_epi8() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(i8::MAX); let r = _mm512_subs_epi8(a, b); @@ -12885,7 +13797,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_subs_epi8() { + const unsafe fn test_mm512_mask_subs_epi8() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(i8::MAX); let r = _mm512_mask_subs_epi8(a, 0, a, b); @@ -12905,7 +13817,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_subs_epi8() { + const unsafe fn test_mm512_maskz_subs_epi8() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(i8::MAX); let r = _mm512_maskz_subs_epi8(0, a, b); @@ -12924,7 +13836,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_subs_epi8() { + const unsafe fn test_mm256_mask_subs_epi8() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(i8::MAX); let r = _mm256_mask_subs_epi8(a, 0, a, b); @@ -12937,7 +13849,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_subs_epi8() { + const unsafe fn test_mm256_maskz_subs_epi8() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(i8::MAX); let r = _mm256_maskz_subs_epi8(0, a, b); @@ -12950,7 +13862,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_subs_epi8() { + const unsafe fn test_mm_mask_subs_epi8() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(i8::MAX); let r = _mm_mask_subs_epi8(a, 0, a, b); @@ -12962,7 +13874,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_subs_epi8() { + const unsafe fn test_mm_maskz_subs_epi8() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(i8::MAX); let r = _mm_maskz_subs_epi8(0, a, b); @@ -12974,7 +13886,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mulhi_epu16() { + const unsafe fn test_mm512_mulhi_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mulhi_epu16(a, b); @@ -12983,7 +13895,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_mulhi_epu16() { + const unsafe fn test_mm512_mask_mulhi_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mask_mulhi_epu16(a, 0, a, b); @@ -12996,7 +13908,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_mulhi_epu16() { + const unsafe fn test_mm512_maskz_mulhi_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_mulhi_epu16(0, a, b); @@ -13009,7 +13921,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_mulhi_epu16() { + const unsafe fn test_mm256_mask_mulhi_epu16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_mask_mulhi_epu16(a, 0, a, b); @@ -13020,7 +13932,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_mulhi_epu16() { + const unsafe fn test_mm256_maskz_mulhi_epu16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_mulhi_epu16(0, a, b); @@ -13031,7 +13943,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_mulhi_epu16() { + const unsafe fn test_mm_mask_mulhi_epu16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_mask_mulhi_epu16(a, 0, a, b); @@ -13042,7 +13954,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_mulhi_epu16() { + const unsafe fn test_mm_maskz_mulhi_epu16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_maskz_mulhi_epu16(0, a, b); @@ -13053,7 +13965,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mulhi_epi16() { + const unsafe fn test_mm512_mulhi_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mulhi_epi16(a, b); @@ -13062,7 +13974,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_mulhi_epi16() { + const unsafe fn test_mm512_mask_mulhi_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mask_mulhi_epi16(a, 0, a, b); @@ -13075,7 +13987,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_mulhi_epi16() { + const unsafe fn test_mm512_maskz_mulhi_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_mulhi_epi16(0, a, b); @@ -13088,7 +14000,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_mulhi_epi16() { + const unsafe fn test_mm256_mask_mulhi_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_mask_mulhi_epi16(a, 0, a, b); @@ -13099,7 +14011,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_mulhi_epi16() { + const unsafe fn test_mm256_maskz_mulhi_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_mulhi_epi16(0, a, b); @@ -13110,7 +14022,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_mulhi_epi16() { + const unsafe fn test_mm_mask_mulhi_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_mask_mulhi_epi16(a, 0, a, b); @@ -13121,7 +14033,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_mulhi_epi16() { + const unsafe fn test_mm_maskz_mulhi_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_maskz_mulhi_epi16(0, a, b); @@ -13211,7 +14123,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mullo_epi16() { + const unsafe fn test_mm512_mullo_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mullo_epi16(a, b); @@ -13220,7 +14132,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_mullo_epi16() { + const unsafe fn test_mm512_mask_mullo_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mask_mullo_epi16(a, 0, a, b); @@ -13233,7 +14145,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_mullo_epi16() { + const unsafe fn test_mm512_maskz_mullo_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_mullo_epi16(0, a, b); @@ -13246,7 +14158,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_mullo_epi16() { + const unsafe fn test_mm256_mask_mullo_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_mask_mullo_epi16(a, 0, a, b); @@ -13257,7 +14169,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_mullo_epi16() { + const unsafe fn test_mm256_maskz_mullo_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_mullo_epi16(0, a, b); @@ -13268,7 +14180,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_mullo_epi16() { + const unsafe fn test_mm_mask_mullo_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_mask_mullo_epi16(a, 0, a, b); @@ -13279,7 +14191,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_mullo_epi16() { + const unsafe fn test_mm_maskz_mullo_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_maskz_mullo_epi16(0, a, b); @@ -13290,7 +14202,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_max_epu16() { + const unsafe fn test_mm512_max_epu16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13305,7 +14217,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_max_epu16() { + const unsafe fn test_mm512_mask_max_epu16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13322,7 +14234,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_max_epu16() { + const unsafe fn test_mm512_maskz_max_epu16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13339,7 +14251,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_max_epu16() { + const unsafe fn test_mm256_mask_max_epu16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm256_set_epi16(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_mask_max_epu16(a, 0, a, b); @@ -13350,7 +14262,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_max_epu16() { + const unsafe fn test_mm256_maskz_max_epu16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm256_set_epi16(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_maskz_max_epu16(0, a, b); @@ -13361,7 +14273,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_max_epu16() { + const unsafe fn test_mm_mask_max_epu16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_set_epi16(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_mask_max_epu16(a, 0, a, b); @@ -13372,7 +14284,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_max_epu16() { + const unsafe fn test_mm_maskz_max_epu16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_set_epi16(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_maskz_max_epu16(0, a, b); @@ -13383,7 +14295,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_max_epu8() { + const unsafe fn test_mm512_max_epu8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -13404,7 +14316,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_max_epu8() { + const unsafe fn test_mm512_mask_max_epu8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -13432,7 +14344,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_max_epu8() { + const unsafe fn test_mm512_maskz_max_epu8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -13459,7 +14371,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_max_epu8() { + const unsafe fn test_mm256_mask_max_epu8() { #[rustfmt::skip] let a = _mm256_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13476,7 +14388,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_max_epu8() { + const unsafe fn test_mm256_maskz_max_epu8() { #[rustfmt::skip] let a = _mm256_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13493,7 +14405,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_max_epu8() { + const unsafe fn test_mm_mask_max_epu8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_mask_max_epu8(a, 0, a, b); @@ -13504,7 +14416,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_max_epu8() { + const unsafe fn test_mm_maskz_max_epu8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_maskz_max_epu8(0, a, b); @@ -13515,7 +14427,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_max_epi16() { + const unsafe fn test_mm512_max_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13530,7 +14442,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_max_epi16() { + const unsafe fn test_mm512_mask_max_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13547,7 +14459,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_max_epi16() { + const unsafe fn test_mm512_maskz_max_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13564,7 +14476,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_max_epi16() { + const unsafe fn test_mm256_mask_max_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm256_set_epi16(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_mask_max_epi16(a, 0, a, b); @@ -13575,7 +14487,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_max_epi16() { + const unsafe fn test_mm256_maskz_max_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm256_set_epi16(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_maskz_max_epi16(0, a, b); @@ -13586,7 +14498,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_max_epi16() { + const unsafe fn test_mm_mask_max_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_set_epi16(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_mask_max_epi16(a, 0, a, b); @@ -13597,7 +14509,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_max_epi16() { + const unsafe fn test_mm_maskz_max_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_set_epi16(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_maskz_max_epi16(0, a, b); @@ -13608,7 +14520,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_max_epi8() { + const unsafe fn test_mm512_max_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -13629,7 +14541,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_max_epi8() { + const unsafe fn test_mm512_mask_max_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -13657,7 +14569,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_max_epi8() { + const unsafe fn test_mm512_maskz_max_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -13684,7 +14596,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_max_epi8() { + const unsafe fn test_mm256_mask_max_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13701,7 +14613,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_max_epi8() { + const unsafe fn test_mm256_maskz_max_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13718,7 +14630,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_max_epi8() { + const unsafe fn test_mm_mask_max_epi8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_mask_max_epi8(a, 0, a, b); @@ -13729,7 +14641,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_max_epi8() { + const unsafe fn test_mm_maskz_max_epi8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_maskz_max_epi8(0, a, b); @@ -13740,7 +14652,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_min_epu16() { + const unsafe fn test_mm512_min_epu16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13755,7 +14667,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_min_epu16() { + const unsafe fn test_mm512_mask_min_epu16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13772,7 +14684,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_min_epu16() { + const unsafe fn test_mm512_maskz_min_epu16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13789,7 +14701,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_min_epu16() { + const unsafe fn test_mm256_mask_min_epu16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm256_set_epi16(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_mask_min_epu16(a, 0, a, b); @@ -13800,7 +14712,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_min_epu16() { + const unsafe fn test_mm256_maskz_min_epu16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm256_set_epi16(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_maskz_min_epu16(0, a, b); @@ -13811,7 +14723,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_min_epu16() { + const unsafe fn test_mm_mask_min_epu16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_set_epi16(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_mask_min_epu16(a, 0, a, b); @@ -13822,7 +14734,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_min_epu16() { + const unsafe fn test_mm_maskz_min_epu16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_set_epi16(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_maskz_min_epu16(0, a, b); @@ -13833,7 +14745,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_min_epu8() { + const unsafe fn test_mm512_min_epu8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -13854,7 +14766,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_min_epu8() { + const unsafe fn test_mm512_mask_min_epu8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -13882,7 +14794,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_min_epu8() { + const unsafe fn test_mm512_maskz_min_epu8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -13909,7 +14821,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_min_epu8() { + const unsafe fn test_mm256_mask_min_epu8() { #[rustfmt::skip] let a = _mm256_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13926,7 +14838,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_min_epu8() { + const unsafe fn test_mm256_maskz_min_epu8() { #[rustfmt::skip] let a = _mm256_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13943,7 +14855,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_min_epu8() { + const unsafe fn test_mm_mask_min_epu8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_mask_min_epu8(a, 0, a, b); @@ -13954,7 +14866,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_min_epu8() { + const unsafe fn test_mm_maskz_min_epu8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_maskz_min_epu8(0, a, b); @@ -13965,7 +14877,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_min_epi16() { + const unsafe fn test_mm512_min_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13980,7 +14892,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_min_epi16() { + const unsafe fn test_mm512_mask_min_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -13997,7 +14909,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_min_epi16() { + const unsafe fn test_mm512_maskz_min_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -14014,7 +14926,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_min_epi16() { + const unsafe fn test_mm256_mask_min_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm256_set_epi16(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_mask_min_epi16(a, 0, a, b); @@ -14025,7 +14937,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_min_epi16() { + const unsafe fn test_mm256_maskz_min_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm256_set_epi16(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm256_maskz_min_epi16(0, a, b); @@ -14036,7 +14948,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_min_epi16() { + const unsafe fn test_mm_mask_min_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_set_epi16(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_mask_min_epi16(a, 0, a, b); @@ -14047,7 +14959,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_min_epi16() { + const unsafe fn test_mm_maskz_min_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let b = _mm_set_epi16(7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_maskz_min_epi16(0, a, b); @@ -14058,7 +14970,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_min_epi8() { + const unsafe fn test_mm512_min_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -14079,7 +14991,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_min_epi8() { + const unsafe fn test_mm512_mask_min_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -14107,7 +15019,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_min_epi8() { + const unsafe fn test_mm512_maskz_min_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -14134,7 +15046,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_min_epi8() { + const unsafe fn test_mm256_mask_min_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -14151,7 +15063,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_min_epi8() { + const unsafe fn test_mm256_maskz_min_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); @@ -14168,7 +15080,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_min_epi8() { + const unsafe fn test_mm_mask_min_epi8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_mask_min_epi8(a, 0, a, b); @@ -14179,7 +15091,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_min_epi8() { + const unsafe fn test_mm_maskz_min_epi8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); let r = _mm_maskz_min_epi8(0, a, b); @@ -14190,7 +15102,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmplt_epu16_mask() { + const unsafe fn test_mm512_cmplt_epu16_mask() { let a = _mm512_set1_epi16(-2); let b = _mm512_set1_epi16(-1); let m = _mm512_cmplt_epu16_mask(a, b); @@ -14198,7 +15110,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmplt_epu16_mask() { + const unsafe fn test_mm512_mask_cmplt_epu16_mask() { let a = _mm512_set1_epi16(-2); let b = _mm512_set1_epi16(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14207,7 +15119,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmplt_epu16_mask() { + const unsafe fn test_mm256_cmplt_epu16_mask() { let a = _mm256_set1_epi16(-2); let b = _mm256_set1_epi16(-1); let m = _mm256_cmplt_epu16_mask(a, b); @@ -14215,7 +15127,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmplt_epu16_mask() { + const unsafe fn test_mm256_mask_cmplt_epu16_mask() { let a = _mm256_set1_epi16(-2); let b = _mm256_set1_epi16(-1); let mask = 0b01010101_01010101; @@ -14224,7 +15136,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmplt_epu16_mask() { + const unsafe fn test_mm_cmplt_epu16_mask() { let a = _mm_set1_epi16(-2); let b = _mm_set1_epi16(-1); let m = _mm_cmplt_epu16_mask(a, b); @@ -14232,7 +15144,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmplt_epu16_mask() { + const unsafe fn test_mm_mask_cmplt_epu16_mask() { let a = _mm_set1_epi16(-2); let b = _mm_set1_epi16(-1); let mask = 0b01010101; @@ -14241,7 +15153,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmplt_epu8_mask() { + const unsafe fn test_mm512_cmplt_epu8_mask() { let a = _mm512_set1_epi8(-2); let b = _mm512_set1_epi8(-1); let m = _mm512_cmplt_epu8_mask(a, b); @@ -14252,7 +15164,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmplt_epu8_mask() { + const unsafe fn test_mm512_mask_cmplt_epu8_mask() { let a = _mm512_set1_epi8(-2); let b = _mm512_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -14264,7 +15176,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmplt_epu8_mask() { + const unsafe fn test_mm256_cmplt_epu8_mask() { let a = _mm256_set1_epi8(-2); let b = _mm256_set1_epi8(-1); let m = _mm256_cmplt_epu8_mask(a, b); @@ -14272,7 +15184,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmplt_epu8_mask() { + const unsafe fn test_mm256_mask_cmplt_epu8_mask() { let a = _mm256_set1_epi8(-2); let b = _mm256_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14281,7 +15193,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmplt_epu8_mask() { + const unsafe fn test_mm_cmplt_epu8_mask() { let a = _mm_set1_epi8(-2); let b = _mm_set1_epi8(-1); let m = _mm_cmplt_epu8_mask(a, b); @@ -14289,7 +15201,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmplt_epu8_mask() { + const unsafe fn test_mm_mask_cmplt_epu8_mask() { let a = _mm_set1_epi8(-2); let b = _mm_set1_epi8(-1); let mask = 0b01010101_01010101; @@ -14298,7 +15210,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmplt_epi16_mask() { + const unsafe fn test_mm512_cmplt_epi16_mask() { let a = _mm512_set1_epi16(-2); let b = _mm512_set1_epi16(-1); let m = _mm512_cmplt_epi16_mask(a, b); @@ -14306,7 +15218,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmplt_epi16_mask() { + const unsafe fn test_mm512_mask_cmplt_epi16_mask() { let a = _mm512_set1_epi16(-2); let b = _mm512_set1_epi16(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14315,7 +15227,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmplt_epi16_mask() { + const unsafe fn test_mm256_cmplt_epi16_mask() { let a = _mm256_set1_epi16(-2); let b = _mm256_set1_epi16(-1); let m = _mm256_cmplt_epi16_mask(a, b); @@ -14323,7 +15235,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmplt_epi16_mask() { + const unsafe fn test_mm256_mask_cmplt_epi16_mask() { let a = _mm256_set1_epi16(-2); let b = _mm256_set1_epi16(-1); let mask = 0b01010101_01010101; @@ -14332,7 +15244,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmplt_epi16_mask() { + const unsafe fn test_mm_cmplt_epi16_mask() { let a = _mm_set1_epi16(-2); let b = _mm_set1_epi16(-1); let m = _mm_cmplt_epi16_mask(a, b); @@ -14340,7 +15252,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmplt_epi16_mask() { + const unsafe fn test_mm_mask_cmplt_epi16_mask() { let a = _mm_set1_epi16(-2); let b = _mm_set1_epi16(-1); let mask = 0b01010101; @@ -14349,7 +15261,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmplt_epi8_mask() { + const unsafe fn test_mm512_cmplt_epi8_mask() { let a = _mm512_set1_epi8(-2); let b = _mm512_set1_epi8(-1); let m = _mm512_cmplt_epi8_mask(a, b); @@ -14360,7 +15272,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmplt_epi8_mask() { + const unsafe fn test_mm512_mask_cmplt_epi8_mask() { let a = _mm512_set1_epi8(-2); let b = _mm512_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -14372,7 +15284,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmplt_epi8_mask() { + const unsafe fn test_mm256_cmplt_epi8_mask() { let a = _mm256_set1_epi8(-2); let b = _mm256_set1_epi8(-1); let m = _mm256_cmplt_epi8_mask(a, b); @@ -14380,7 +15292,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmplt_epi8_mask() { + const unsafe fn test_mm256_mask_cmplt_epi8_mask() { let a = _mm256_set1_epi8(-2); let b = _mm256_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14389,7 +15301,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmplt_epi8_mask() { + const unsafe fn test_mm_cmplt_epi8_mask() { let a = _mm_set1_epi8(-2); let b = _mm_set1_epi8(-1); let m = _mm_cmplt_epi8_mask(a, b); @@ -14397,7 +15309,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmplt_epi8_mask() { + const unsafe fn test_mm_mask_cmplt_epi8_mask() { let a = _mm_set1_epi8(-2); let b = _mm_set1_epi8(-1); let mask = 0b01010101_01010101; @@ -14406,7 +15318,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpgt_epu16_mask() { + const unsafe fn test_mm512_cmpgt_epu16_mask() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(1); let m = _mm512_cmpgt_epu16_mask(a, b); @@ -14414,7 +15326,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpgt_epu16_mask() { + const unsafe fn test_mm512_mask_cmpgt_epu16_mask() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14423,7 +15335,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpgt_epu16_mask() { + const unsafe fn test_mm256_cmpgt_epu16_mask() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(1); let m = _mm256_cmpgt_epu16_mask(a, b); @@ -14431,7 +15343,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpgt_epu16_mask() { + const unsafe fn test_mm256_mask_cmpgt_epu16_mask() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(1); let mask = 0b01010101_01010101; @@ -14440,7 +15352,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpgt_epu16_mask() { + const unsafe fn test_mm_cmpgt_epu16_mask() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(1); let m = _mm_cmpgt_epu16_mask(a, b); @@ -14448,7 +15360,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpgt_epu16_mask() { + const unsafe fn test_mm_mask_cmpgt_epu16_mask() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(1); let mask = 0b01010101; @@ -14457,7 +15369,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpgt_epu8_mask() { + const unsafe fn test_mm512_cmpgt_epu8_mask() { let a = _mm512_set1_epi8(2); let b = _mm512_set1_epi8(1); let m = _mm512_cmpgt_epu8_mask(a, b); @@ -14468,7 +15380,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpgt_epu8_mask() { + const unsafe fn test_mm512_mask_cmpgt_epu8_mask() { let a = _mm512_set1_epi8(2); let b = _mm512_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -14480,7 +15392,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpgt_epu8_mask() { + const unsafe fn test_mm256_cmpgt_epu8_mask() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(1); let m = _mm256_cmpgt_epu8_mask(a, b); @@ -14488,7 +15400,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpgt_epu8_mask() { + const unsafe fn test_mm256_mask_cmpgt_epu8_mask() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14497,7 +15409,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpgt_epu8_mask() { + const unsafe fn test_mm_cmpgt_epu8_mask() { let a = _mm_set1_epi8(2); let b = _mm_set1_epi8(1); let m = _mm_cmpgt_epu8_mask(a, b); @@ -14505,7 +15417,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpgt_epu8_mask() { + const unsafe fn test_mm_mask_cmpgt_epu8_mask() { let a = _mm_set1_epi8(2); let b = _mm_set1_epi8(1); let mask = 0b01010101_01010101; @@ -14514,7 +15426,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpgt_epi16_mask() { + const unsafe fn test_mm512_cmpgt_epi16_mask() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(-1); let m = _mm512_cmpgt_epi16_mask(a, b); @@ -14522,7 +15434,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpgt_epi16_mask() { + const unsafe fn test_mm512_mask_cmpgt_epi16_mask() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14531,7 +15443,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpgt_epi16_mask() { + const unsafe fn test_mm256_cmpgt_epi16_mask() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(-1); let m = _mm256_cmpgt_epi16_mask(a, b); @@ -14539,7 +15451,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpgt_epi16_mask() { + const unsafe fn test_mm256_mask_cmpgt_epi16_mask() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(-1); let mask = 0b001010101_01010101; @@ -14548,7 +15460,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpgt_epi16_mask() { + const unsafe fn test_mm_cmpgt_epi16_mask() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(-1); let m = _mm_cmpgt_epi16_mask(a, b); @@ -14556,7 +15468,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpgt_epi16_mask() { + const unsafe fn test_mm_mask_cmpgt_epi16_mask() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(-1); let mask = 0b01010101; @@ -14565,7 +15477,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpgt_epi8_mask() { + const unsafe fn test_mm512_cmpgt_epi8_mask() { let a = _mm512_set1_epi8(2); let b = _mm512_set1_epi8(-1); let m = _mm512_cmpgt_epi8_mask(a, b); @@ -14576,7 +15488,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpgt_epi8_mask() { + const unsafe fn test_mm512_mask_cmpgt_epi8_mask() { let a = _mm512_set1_epi8(2); let b = _mm512_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -14588,7 +15500,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpgt_epi8_mask() { + const unsafe fn test_mm256_cmpgt_epi8_mask() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(-1); let m = _mm256_cmpgt_epi8_mask(a, b); @@ -14596,7 +15508,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpgt_epi8_mask() { + const unsafe fn test_mm256_mask_cmpgt_epi8_mask() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14605,7 +15517,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpgt_epi8_mask() { + const unsafe fn test_mm_cmpgt_epi8_mask() { let a = _mm_set1_epi8(2); let b = _mm_set1_epi8(-1); let m = _mm_cmpgt_epi8_mask(a, b); @@ -14613,7 +15525,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpgt_epi8_mask() { + const unsafe fn test_mm_mask_cmpgt_epi8_mask() { let a = _mm_set1_epi8(2); let b = _mm_set1_epi8(-1); let mask = 0b01010101_01010101; @@ -14622,7 +15534,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmple_epu16_mask() { + const unsafe fn test_mm512_cmple_epu16_mask() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(-1); let m = _mm512_cmple_epu16_mask(a, b); @@ -14630,7 +15542,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmple_epu16_mask() { + const unsafe fn test_mm512_mask_cmple_epu16_mask() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14639,7 +15551,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmple_epu16_mask() { + const unsafe fn test_mm256_cmple_epu16_mask() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(-1); let m = _mm256_cmple_epu16_mask(a, b); @@ -14647,7 +15559,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmple_epu16_mask() { + const unsafe fn test_mm256_mask_cmple_epu16_mask() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(-1); let mask = 0b01010101_01010101; @@ -14656,7 +15568,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmple_epu16_mask() { + const unsafe fn test_mm_cmple_epu16_mask() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(-1); let m = _mm_cmple_epu16_mask(a, b); @@ -14664,7 +15576,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmple_epu16_mask() { + const unsafe fn test_mm_mask_cmple_epu16_mask() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(-1); let mask = 0b01010101; @@ -14673,7 +15585,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmple_epu8_mask() { + const unsafe fn test_mm512_cmple_epu8_mask() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(-1); let m = _mm512_cmple_epu8_mask(a, b); @@ -14684,7 +15596,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmple_epu8_mask() { + const unsafe fn test_mm512_mask_cmple_epu8_mask() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -14696,7 +15608,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmple_epu8_mask() { + const unsafe fn test_mm256_cmple_epu8_mask() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(-1); let m = _mm256_cmple_epu8_mask(a, b); @@ -14704,7 +15616,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmple_epu8_mask() { + const unsafe fn test_mm256_mask_cmple_epu8_mask() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14713,7 +15625,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmple_epu8_mask() { + const unsafe fn test_mm_cmple_epu8_mask() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(-1); let m = _mm_cmple_epu8_mask(a, b); @@ -14721,7 +15633,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmple_epu8_mask() { + const unsafe fn test_mm_mask_cmple_epu8_mask() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(-1); let mask = 0b01010101_01010101; @@ -14730,7 +15642,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmple_epi16_mask() { + const unsafe fn test_mm512_cmple_epi16_mask() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(-1); let m = _mm512_cmple_epi16_mask(a, b); @@ -14738,7 +15650,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmple_epi16_mask() { + const unsafe fn test_mm512_mask_cmple_epi16_mask() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14747,7 +15659,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmple_epi16_mask() { + const unsafe fn test_mm256_cmple_epi16_mask() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(-1); let m = _mm256_cmple_epi16_mask(a, b); @@ -14755,7 +15667,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmple_epi16_mask() { + const unsafe fn test_mm256_mask_cmple_epi16_mask() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(-1); let mask = 0b01010101_01010101; @@ -14764,7 +15676,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmple_epi16_mask() { + const unsafe fn test_mm_cmple_epi16_mask() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(-1); let m = _mm_cmple_epi16_mask(a, b); @@ -14772,7 +15684,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmple_epi16_mask() { + const unsafe fn test_mm_mask_cmple_epi16_mask() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(-1); let mask = 0b01010101; @@ -14781,7 +15693,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmple_epi8_mask() { + const unsafe fn test_mm512_cmple_epi8_mask() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(-1); let m = _mm512_cmple_epi8_mask(a, b); @@ -14792,7 +15704,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmple_epi8_mask() { + const unsafe fn test_mm512_mask_cmple_epi8_mask() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -14804,7 +15716,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmple_epi8_mask() { + const unsafe fn test_mm256_cmple_epi8_mask() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(-1); let m = _mm256_cmple_epi8_mask(a, b); @@ -14812,7 +15724,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmple_epi8_mask() { + const unsafe fn test_mm256_mask_cmple_epi8_mask() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14821,7 +15733,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmple_epi8_mask() { + const unsafe fn test_mm_cmple_epi8_mask() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(-1); let m = _mm_cmple_epi8_mask(a, b); @@ -14829,7 +15741,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmple_epi8_mask() { + const unsafe fn test_mm_mask_cmple_epi8_mask() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(-1); let mask = 0b01010101_01010101; @@ -14838,7 +15750,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpge_epu16_mask() { + const unsafe fn test_mm512_cmpge_epu16_mask() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let m = _mm512_cmpge_epu16_mask(a, b); @@ -14846,7 +15758,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpge_epu16_mask() { + const unsafe fn test_mm512_mask_cmpge_epu16_mask() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14855,7 +15767,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpge_epu16_mask() { + const unsafe fn test_mm256_cmpge_epu16_mask() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let m = _mm256_cmpge_epu16_mask(a, b); @@ -14863,7 +15775,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpge_epu16_mask() { + const unsafe fn test_mm256_mask_cmpge_epu16_mask() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let mask = 0b01010101_01010101; @@ -14872,7 +15784,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpge_epu16_mask() { + const unsafe fn test_mm_cmpge_epu16_mask() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let m = _mm_cmpge_epu16_mask(a, b); @@ -14880,7 +15792,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpge_epu16_mask() { + const unsafe fn test_mm_mask_cmpge_epu16_mask() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let mask = 0b01010101; @@ -14889,7 +15801,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpge_epu8_mask() { + const unsafe fn test_mm512_cmpge_epu8_mask() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(1); let m = _mm512_cmpge_epu8_mask(a, b); @@ -14900,7 +15812,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpge_epu8_mask() { + const unsafe fn test_mm512_mask_cmpge_epu8_mask() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -14912,7 +15824,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpge_epu8_mask() { + const unsafe fn test_mm256_cmpge_epu8_mask() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(1); let m = _mm256_cmpge_epu8_mask(a, b); @@ -14920,7 +15832,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpge_epu8_mask() { + const unsafe fn test_mm256_mask_cmpge_epu8_mask() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14929,7 +15841,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpge_epu8_mask() { + const unsafe fn test_mm_cmpge_epu8_mask() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(1); let m = _mm_cmpge_epu8_mask(a, b); @@ -14937,7 +15849,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpge_epu8_mask() { + const unsafe fn test_mm_mask_cmpge_epu8_mask() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(1); let mask = 0b01010101_01010101; @@ -14946,7 +15858,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpge_epi16_mask() { + const unsafe fn test_mm512_cmpge_epi16_mask() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(-1); let m = _mm512_cmpge_epi16_mask(a, b); @@ -14954,7 +15866,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpge_epi16_mask() { + const unsafe fn test_mm512_mask_cmpge_epi16_mask() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -14963,7 +15875,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpge_epi16_mask() { + const unsafe fn test_mm256_cmpge_epi16_mask() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(-1); let m = _mm256_cmpge_epi16_mask(a, b); @@ -14971,7 +15883,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpge_epi16_mask() { + const unsafe fn test_mm256_mask_cmpge_epi16_mask() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(-1); let mask = 0b01010101_01010101; @@ -14980,7 +15892,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpge_epi16_mask() { + const unsafe fn test_mm_cmpge_epi16_mask() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(-1); let m = _mm_cmpge_epi16_mask(a, b); @@ -14988,7 +15900,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpge_epi16_mask() { + const unsafe fn test_mm_mask_cmpge_epi16_mask() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(-1); let mask = 0b01010101; @@ -14997,7 +15909,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpge_epi8_mask() { + const unsafe fn test_mm512_cmpge_epi8_mask() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(-1); let m = _mm512_cmpge_epi8_mask(a, b); @@ -15008,7 +15920,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpge_epi8_mask() { + const unsafe fn test_mm512_mask_cmpge_epi8_mask() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -15020,7 +15932,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpge_epi8_mask() { + const unsafe fn test_mm256_cmpge_epi8_mask() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(-1); let m = _mm256_cmpge_epi8_mask(a, b); @@ -15028,7 +15940,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpge_epi8_mask() { + const unsafe fn test_mm256_mask_cmpge_epi8_mask() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15037,7 +15949,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpge_epi8_mask() { + const unsafe fn test_mm_cmpge_epi8_mask() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(-1); let m = _mm_cmpge_epi8_mask(a, b); @@ -15045,7 +15957,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpge_epi8_mask() { + const unsafe fn test_mm_mask_cmpge_epi8_mask() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(-1); let mask = 0b01010101_01010101; @@ -15054,7 +15966,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpeq_epu16_mask() { + const unsafe fn test_mm512_cmpeq_epu16_mask() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let m = _mm512_cmpeq_epu16_mask(a, b); @@ -15062,7 +15974,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpeq_epu16_mask() { + const unsafe fn test_mm512_mask_cmpeq_epu16_mask() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15071,7 +15983,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpeq_epu16_mask() { + const unsafe fn test_mm256_cmpeq_epu16_mask() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let m = _mm256_cmpeq_epu16_mask(a, b); @@ -15079,7 +15991,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpeq_epu16_mask() { + const unsafe fn test_mm256_mask_cmpeq_epu16_mask() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let mask = 0b01010101_01010101; @@ -15088,7 +16000,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpeq_epu16_mask() { + const unsafe fn test_mm_cmpeq_epu16_mask() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let m = _mm_cmpeq_epu16_mask(a, b); @@ -15096,7 +16008,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpeq_epu16_mask() { + const unsafe fn test_mm_mask_cmpeq_epu16_mask() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let mask = 0b01010101; @@ -15105,7 +16017,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpeq_epu8_mask() { + const unsafe fn test_mm512_cmpeq_epu8_mask() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(1); let m = _mm512_cmpeq_epu8_mask(a, b); @@ -15116,7 +16028,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpeq_epu8_mask() { + const unsafe fn test_mm512_mask_cmpeq_epu8_mask() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -15128,7 +16040,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpeq_epu8_mask() { + const unsafe fn test_mm256_cmpeq_epu8_mask() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(1); let m = _mm256_cmpeq_epu8_mask(a, b); @@ -15136,7 +16048,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpeq_epu8_mask() { + const unsafe fn test_mm256_mask_cmpeq_epu8_mask() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15145,7 +16057,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpeq_epu8_mask() { + const unsafe fn test_mm_cmpeq_epu8_mask() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(1); let m = _mm_cmpeq_epu8_mask(a, b); @@ -15153,7 +16065,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpeq_epu8_mask() { + const unsafe fn test_mm_mask_cmpeq_epu8_mask() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(1); let mask = 0b01010101_01010101; @@ -15162,7 +16074,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpeq_epi16_mask() { + const unsafe fn test_mm512_cmpeq_epi16_mask() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(-1); let m = _mm512_cmpeq_epi16_mask(a, b); @@ -15170,7 +16082,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpeq_epi16_mask() { + const unsafe fn test_mm512_mask_cmpeq_epi16_mask() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15179,7 +16091,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpeq_epi16_mask() { + const unsafe fn test_mm256_cmpeq_epi16_mask() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(-1); let m = _mm256_cmpeq_epi16_mask(a, b); @@ -15187,7 +16099,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpeq_epi16_mask() { + const unsafe fn test_mm256_mask_cmpeq_epi16_mask() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(-1); let mask = 0b01010101_01010101; @@ -15196,7 +16108,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpeq_epi16_mask() { + const unsafe fn test_mm_cmpeq_epi16_mask() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(-1); let m = _mm_cmpeq_epi16_mask(a, b); @@ -15204,7 +16116,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpeq_epi16_mask() { + const unsafe fn test_mm_mask_cmpeq_epi16_mask() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(-1); let mask = 0b01010101; @@ -15213,7 +16125,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpeq_epi8_mask() { + const unsafe fn test_mm512_cmpeq_epi8_mask() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(-1); let m = _mm512_cmpeq_epi8_mask(a, b); @@ -15224,7 +16136,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpeq_epi8_mask() { + const unsafe fn test_mm512_mask_cmpeq_epi8_mask() { let a = _mm512_set1_epi8(-1); let b = _mm512_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -15236,7 +16148,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpeq_epi8_mask() { + const unsafe fn test_mm256_cmpeq_epi8_mask() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(-1); let m = _mm256_cmpeq_epi8_mask(a, b); @@ -15244,7 +16156,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpeq_epi8_mask() { + const unsafe fn test_mm256_mask_cmpeq_epi8_mask() { let a = _mm256_set1_epi8(-1); let b = _mm256_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15253,7 +16165,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpeq_epi8_mask() { + const unsafe fn test_mm_cmpeq_epi8_mask() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(-1); let m = _mm_cmpeq_epi8_mask(a, b); @@ -15261,7 +16173,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpeq_epi8_mask() { + const unsafe fn test_mm_mask_cmpeq_epi8_mask() { let a = _mm_set1_epi8(-1); let b = _mm_set1_epi8(-1); let mask = 0b01010101_01010101; @@ -15270,7 +16182,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpneq_epu16_mask() { + const unsafe fn test_mm512_cmpneq_epu16_mask() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(1); let m = _mm512_cmpneq_epu16_mask(a, b); @@ -15278,7 +16190,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpneq_epu16_mask() { + const unsafe fn test_mm512_mask_cmpneq_epu16_mask() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15287,7 +16199,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpneq_epu16_mask() { + const unsafe fn test_mm256_cmpneq_epu16_mask() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(1); let m = _mm256_cmpneq_epu16_mask(a, b); @@ -15295,7 +16207,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpneq_epu16_mask() { + const unsafe fn test_mm256_mask_cmpneq_epu16_mask() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(1); let mask = 0b01010101_01010101; @@ -15304,7 +16216,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpneq_epu16_mask() { + const unsafe fn test_mm_cmpneq_epu16_mask() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(1); let m = _mm_cmpneq_epu16_mask(a, b); @@ -15312,7 +16224,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpneq_epu16_mask() { + const unsafe fn test_mm_mask_cmpneq_epu16_mask() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(1); let mask = 0b01010101; @@ -15321,7 +16233,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpneq_epu8_mask() { + const unsafe fn test_mm512_cmpneq_epu8_mask() { let a = _mm512_set1_epi8(2); let b = _mm512_set1_epi8(1); let m = _mm512_cmpneq_epu8_mask(a, b); @@ -15332,7 +16244,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpneq_epu8_mask() { + const unsafe fn test_mm512_mask_cmpneq_epu8_mask() { let a = _mm512_set1_epi8(2); let b = _mm512_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -15344,7 +16256,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpneq_epu8_mask() { + const unsafe fn test_mm256_cmpneq_epu8_mask() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(1); let m = _mm256_cmpneq_epu8_mask(a, b); @@ -15352,7 +16264,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpneq_epu8_mask() { + const unsafe fn test_mm256_mask_cmpneq_epu8_mask() { let a = _mm256_set1_epi8(2); let b = _mm256_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15361,7 +16273,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpneq_epu8_mask() { + const unsafe fn test_mm_cmpneq_epu8_mask() { let a = _mm_set1_epi8(2); let b = _mm_set1_epi8(1); let m = _mm_cmpneq_epu8_mask(a, b); @@ -15369,7 +16281,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpneq_epu8_mask() { + const unsafe fn test_mm_mask_cmpneq_epu8_mask() { let a = _mm_set1_epi8(2); let b = _mm_set1_epi8(1); let mask = 0b01010101_01010101; @@ -15378,7 +16290,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpneq_epi16_mask() { + const unsafe fn test_mm512_cmpneq_epi16_mask() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(-1); let m = _mm512_cmpneq_epi16_mask(a, b); @@ -15386,7 +16298,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpneq_epi16_mask() { + const unsafe fn test_mm512_mask_cmpneq_epi16_mask() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15395,7 +16307,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpneq_epi16_mask() { + const unsafe fn test_mm256_cmpneq_epi16_mask() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(-1); let m = _mm256_cmpneq_epi16_mask(a, b); @@ -15403,7 +16315,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpneq_epi16_mask() { + const unsafe fn test_mm256_mask_cmpneq_epi16_mask() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(-1); let mask = 0b01010101_01010101; @@ -15412,7 +16324,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpneq_epi16_mask() { + const unsafe fn test_mm_cmpneq_epi16_mask() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(-1); let m = _mm_cmpneq_epi16_mask(a, b); @@ -15420,7 +16332,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpneq_epi16_mask() { + const unsafe fn test_mm_mask_cmpneq_epi16_mask() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(-1); let mask = 0b01010101; @@ -15429,7 +16341,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmpneq_epi8_mask() { + const unsafe fn test_mm512_cmpneq_epi8_mask() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(-1); let m = _mm512_cmpneq_epi8_mask(a, b); @@ -15440,7 +16352,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmpneq_epi8_mask() { + const unsafe fn test_mm512_mask_cmpneq_epi8_mask() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -15452,7 +16364,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmpneq_epi8_mask() { + const unsafe fn test_mm256_cmpneq_epi8_mask() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(-1); let m = _mm256_cmpneq_epi8_mask(a, b); @@ -15460,7 +16372,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmpneq_epi8_mask() { + const unsafe fn test_mm256_mask_cmpneq_epi8_mask() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(-1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15469,7 +16381,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmpneq_epi8_mask() { + const unsafe fn test_mm_cmpneq_epi8_mask() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(-1); let m = _mm_cmpneq_epi8_mask(a, b); @@ -15477,7 +16389,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmpneq_epi8_mask() { + const unsafe fn test_mm_mask_cmpneq_epi8_mask() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(-1); let mask = 0b01010101_01010101; @@ -15486,7 +16398,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmp_epu16_mask() { + const unsafe fn test_mm512_cmp_epu16_mask() { let a = _mm512_set1_epi16(0); let b = _mm512_set1_epi16(1); let m = _mm512_cmp_epu16_mask::<_MM_CMPINT_LT>(a, b); @@ -15494,7 +16406,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmp_epu16_mask() { + const unsafe fn test_mm512_mask_cmp_epu16_mask() { let a = _mm512_set1_epi16(0); let b = _mm512_set1_epi16(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15503,7 +16415,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmp_epu16_mask() { + const unsafe fn test_mm256_cmp_epu16_mask() { let a = _mm256_set1_epi16(0); let b = _mm256_set1_epi16(1); let m = _mm256_cmp_epu16_mask::<_MM_CMPINT_LT>(a, b); @@ -15511,7 +16423,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmp_epu16_mask() { + const unsafe fn test_mm256_mask_cmp_epu16_mask() { let a = _mm256_set1_epi16(0); let b = _mm256_set1_epi16(1); let mask = 0b01010101_01010101; @@ -15520,7 +16432,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmp_epu16_mask() { + const unsafe fn test_mm_cmp_epu16_mask() { let a = _mm_set1_epi16(0); let b = _mm_set1_epi16(1); let m = _mm_cmp_epu16_mask::<_MM_CMPINT_LT>(a, b); @@ -15528,7 +16440,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmp_epu16_mask() { + const unsafe fn test_mm_mask_cmp_epu16_mask() { let a = _mm_set1_epi16(0); let b = _mm_set1_epi16(1); let mask = 0b01010101; @@ -15537,7 +16449,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmp_epu8_mask() { + const unsafe fn test_mm512_cmp_epu8_mask() { let a = _mm512_set1_epi8(0); let b = _mm512_set1_epi8(1); let m = _mm512_cmp_epu8_mask::<_MM_CMPINT_LT>(a, b); @@ -15548,7 +16460,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmp_epu8_mask() { + const unsafe fn test_mm512_mask_cmp_epu8_mask() { let a = _mm512_set1_epi8(0); let b = _mm512_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -15560,7 +16472,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmp_epu8_mask() { + const unsafe fn test_mm256_cmp_epu8_mask() { let a = _mm256_set1_epi8(0); let b = _mm256_set1_epi8(1); let m = _mm256_cmp_epu8_mask::<_MM_CMPINT_LT>(a, b); @@ -15568,7 +16480,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmp_epu8_mask() { + const unsafe fn test_mm256_mask_cmp_epu8_mask() { let a = _mm256_set1_epi8(0); let b = _mm256_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15577,7 +16489,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmp_epu8_mask() { + const unsafe fn test_mm_cmp_epu8_mask() { let a = _mm_set1_epi8(0); let b = _mm_set1_epi8(1); let m = _mm_cmp_epu8_mask::<_MM_CMPINT_LT>(a, b); @@ -15585,7 +16497,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmp_epu8_mask() { + const unsafe fn test_mm_mask_cmp_epu8_mask() { let a = _mm_set1_epi8(0); let b = _mm_set1_epi8(1); let mask = 0b01010101_01010101; @@ -15594,7 +16506,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmp_epi16_mask() { + const unsafe fn test_mm512_cmp_epi16_mask() { let a = _mm512_set1_epi16(0); let b = _mm512_set1_epi16(1); let m = _mm512_cmp_epi16_mask::<_MM_CMPINT_LT>(a, b); @@ -15602,7 +16514,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmp_epi16_mask() { + const unsafe fn test_mm512_mask_cmp_epi16_mask() { let a = _mm512_set1_epi16(0); let b = _mm512_set1_epi16(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15611,7 +16523,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmp_epi16_mask() { + const unsafe fn test_mm256_cmp_epi16_mask() { let a = _mm256_set1_epi16(0); let b = _mm256_set1_epi16(1); let m = _mm256_cmp_epi16_mask::<_MM_CMPINT_LT>(a, b); @@ -15619,7 +16531,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmp_epi16_mask() { + const unsafe fn test_mm256_mask_cmp_epi16_mask() { let a = _mm256_set1_epi16(0); let b = _mm256_set1_epi16(1); let mask = 0b01010101_01010101; @@ -15628,7 +16540,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmp_epi16_mask() { + const unsafe fn test_mm_cmp_epi16_mask() { let a = _mm_set1_epi16(0); let b = _mm_set1_epi16(1); let m = _mm_cmp_epi16_mask::<_MM_CMPINT_LT>(a, b); @@ -15636,7 +16548,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmp_epi16_mask() { + const unsafe fn test_mm_mask_cmp_epi16_mask() { let a = _mm_set1_epi16(0); let b = _mm_set1_epi16(1); let mask = 0b01010101; @@ -15645,7 +16557,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cmp_epi8_mask() { + const unsafe fn test_mm512_cmp_epi8_mask() { let a = _mm512_set1_epi8(0); let b = _mm512_set1_epi8(1); let m = _mm512_cmp_epi8_mask::<_MM_CMPINT_LT>(a, b); @@ -15656,7 +16568,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cmp_epi8_mask() { + const unsafe fn test_mm512_mask_cmp_epi8_mask() { let a = _mm512_set1_epi8(0); let b = _mm512_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101_01010101_01010101_01010101_01010101; @@ -15668,7 +16580,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cmp_epi8_mask() { + const unsafe fn test_mm256_cmp_epi8_mask() { let a = _mm256_set1_epi8(0); let b = _mm256_set1_epi8(1); let m = _mm256_cmp_epi8_mask::<_MM_CMPINT_LT>(a, b); @@ -15676,7 +16588,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cmp_epi8_mask() { + const unsafe fn test_mm256_mask_cmp_epi8_mask() { let a = _mm256_set1_epi8(0); let b = _mm256_set1_epi8(1); let mask = 0b01010101_01010101_01010101_01010101; @@ -15685,7 +16597,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cmp_epi8_mask() { + const unsafe fn test_mm_cmp_epi8_mask() { let a = _mm_set1_epi8(0); let b = _mm_set1_epi8(1); let m = _mm_cmp_epi8_mask::<_MM_CMPINT_LT>(a, b); @@ -15693,7 +16605,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cmp_epi8_mask() { + const unsafe fn test_mm_mask_cmp_epi8_mask() { let a = _mm_set1_epi8(0); let b = _mm_set1_epi8(1); let mask = 0b01010101_01010101; @@ -15702,91 +16614,91 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_add_epi16() { + const unsafe fn test_mm256_reduce_add_epi16() { let a = _mm256_set1_epi16(1); let e = _mm256_reduce_add_epi16(a); assert_eq!(16, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_add_epi16() { + const unsafe fn test_mm256_mask_reduce_add_epi16() { let a = _mm256_set1_epi16(1); let e = _mm256_mask_reduce_add_epi16(0b11111111_00000000, a); assert_eq!(8, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_add_epi16() { + const unsafe fn test_mm_reduce_add_epi16() { let a = _mm_set1_epi16(1); let e = _mm_reduce_add_epi16(a); assert_eq!(8, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_add_epi16() { + const unsafe fn test_mm_mask_reduce_add_epi16() { let a = _mm_set1_epi16(1); let e = _mm_mask_reduce_add_epi16(0b11110000, a); assert_eq!(4, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_add_epi8() { + const unsafe fn test_mm256_reduce_add_epi8() { let a = _mm256_set1_epi8(1); let e = _mm256_reduce_add_epi8(a); assert_eq!(32, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_add_epi8() { + const unsafe fn test_mm256_mask_reduce_add_epi8() { let a = _mm256_set1_epi8(1); let e = _mm256_mask_reduce_add_epi8(0b11111111_00000000_11111111_00000000, a); assert_eq!(16, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_add_epi8() { + const unsafe fn test_mm_reduce_add_epi8() { let a = _mm_set1_epi8(1); let e = _mm_reduce_add_epi8(a); assert_eq!(16, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_add_epi8() { + const unsafe fn test_mm_mask_reduce_add_epi8() { let a = _mm_set1_epi8(1); let e = _mm_mask_reduce_add_epi8(0b11111111_00000000, a); assert_eq!(8, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_and_epi16() { + const unsafe fn test_mm256_reduce_and_epi16() { let a = _mm256_set_epi16(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e = _mm256_reduce_and_epi16(a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_and_epi16() { + const unsafe fn test_mm256_mask_reduce_and_epi16() { let a = _mm256_set_epi16(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e = _mm256_mask_reduce_and_epi16(0b11111111_00000000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_and_epi16() { + const unsafe fn test_mm_reduce_and_epi16() { let a = _mm_set_epi16(1, 1, 1, 1, 2, 2, 2, 2); let e = _mm_reduce_and_epi16(a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_and_epi16() { + const unsafe fn test_mm_mask_reduce_and_epi16() { let a = _mm_set_epi16(1, 1, 1, 1, 2, 2, 2, 2); let e = _mm_mask_reduce_and_epi16(0b11110000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_and_epi8() { + const unsafe fn test_mm256_reduce_and_epi8() { let a = _mm256_set_epi8( 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, @@ -15796,7 +16708,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_and_epi8() { + const unsafe fn test_mm256_mask_reduce_and_epi8() { let a = _mm256_set_epi8( 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, @@ -15806,49 +16718,49 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_and_epi8() { + const unsafe fn test_mm_reduce_and_epi8() { let a = _mm_set_epi8(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e = _mm_reduce_and_epi8(a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_and_epi8() { + const unsafe fn test_mm_mask_reduce_and_epi8() { let a = _mm_set_epi8(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e = _mm_mask_reduce_and_epi8(0b11111111_00000000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_mul_epi16() { + const unsafe fn test_mm256_reduce_mul_epi16() { let a = _mm256_set_epi16(2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1); let e = _mm256_reduce_mul_epi16(a); assert_eq!(256, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_mul_epi16() { + const unsafe fn test_mm256_mask_reduce_mul_epi16() { let a = _mm256_set_epi16(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e = _mm256_mask_reduce_mul_epi16(0b11111111_00000000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_mul_epi16() { + const unsafe fn test_mm_reduce_mul_epi16() { let a = _mm_set_epi16(2, 2, 2, 2, 1, 1, 1, 1); let e = _mm_reduce_mul_epi16(a); assert_eq!(16, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_mul_epi16() { + const unsafe fn test_mm_mask_reduce_mul_epi16() { let a = _mm_set_epi16(1, 1, 1, 1, 2, 2, 2, 2); let e = _mm_mask_reduce_mul_epi16(0b11110000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_mul_epi8() { + const unsafe fn test_mm256_reduce_mul_epi8() { let a = _mm256_set_epi8( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, @@ -15858,7 +16770,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_mul_epi8() { + const unsafe fn test_mm256_mask_reduce_mul_epi8() { let a = _mm256_set_epi8( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, @@ -15868,49 +16780,49 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_mul_epi8() { + const unsafe fn test_mm_reduce_mul_epi8() { let a = _mm_set_epi8(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2); let e = _mm_reduce_mul_epi8(a); assert_eq!(8, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_mul_epi8() { + const unsafe fn test_mm_mask_reduce_mul_epi8() { let a = _mm_set_epi8(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2); let e = _mm_mask_reduce_mul_epi8(0b11111111_00000000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_max_epi16() { + const unsafe fn test_mm256_reduce_max_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i16 = _mm256_reduce_max_epi16(a); assert_eq!(15, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_max_epi16() { + const unsafe fn test_mm256_mask_reduce_max_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i16 = _mm256_mask_reduce_max_epi16(0b11111111_00000000, a); assert_eq!(7, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_max_epi16() { + const unsafe fn test_mm_reduce_max_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let e: i16 = _mm_reduce_max_epi16(a); assert_eq!(7, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_max_epi16() { + const unsafe fn test_mm_mask_reduce_max_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let e: i16 = _mm_mask_reduce_max_epi16(0b11110000, a); assert_eq!(3, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_max_epi8() { + const unsafe fn test_mm256_reduce_max_epi8() { let a = _mm256_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -15920,7 +16832,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_max_epi8() { + const unsafe fn test_mm256_mask_reduce_max_epi8() { let a = _mm256_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -15930,49 +16842,49 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_max_epi8() { + const unsafe fn test_mm_reduce_max_epi8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i8 = _mm_reduce_max_epi8(a); assert_eq!(15, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_max_epi8() { + const unsafe fn test_mm_mask_reduce_max_epi8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i8 = _mm_mask_reduce_max_epi8(0b11111111_00000000, a); assert_eq!(7, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_max_epu16() { + const unsafe fn test_mm256_reduce_max_epu16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u16 = _mm256_reduce_max_epu16(a); assert_eq!(15, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_max_epu16() { + const unsafe fn test_mm256_mask_reduce_max_epu16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u16 = _mm256_mask_reduce_max_epu16(0b11111111_00000000, a); assert_eq!(7, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_max_epu16() { + const unsafe fn test_mm_reduce_max_epu16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let e: u16 = _mm_reduce_max_epu16(a); assert_eq!(7, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_max_epu16() { + const unsafe fn test_mm_mask_reduce_max_epu16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let e: u16 = _mm_mask_reduce_max_epu16(0b11110000, a); assert_eq!(3, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_max_epu8() { + const unsafe fn test_mm256_reduce_max_epu8() { let a = _mm256_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -15982,7 +16894,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_max_epu8() { + const unsafe fn test_mm256_mask_reduce_max_epu8() { let a = _mm256_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -15992,49 +16904,49 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_max_epu8() { + const unsafe fn test_mm_reduce_max_epu8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u8 = _mm_reduce_max_epu8(a); assert_eq!(15, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_max_epu8() { + const unsafe fn test_mm_mask_reduce_max_epu8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u8 = _mm_mask_reduce_max_epu8(0b11111111_00000000, a); assert_eq!(7, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_min_epi16() { + const unsafe fn test_mm256_reduce_min_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i16 = _mm256_reduce_min_epi16(a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_min_epi16() { + const unsafe fn test_mm256_mask_reduce_min_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i16 = _mm256_mask_reduce_min_epi16(0b11111111_00000000, a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_min_epi16() { + const unsafe fn test_mm_reduce_min_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let e: i16 = _mm_reduce_min_epi16(a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_min_epi16() { + const unsafe fn test_mm_mask_reduce_min_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let e: i16 = _mm_mask_reduce_min_epi16(0b11110000, a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_min_epi8() { + const unsafe fn test_mm256_reduce_min_epi8() { let a = _mm256_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -16044,7 +16956,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_min_epi8() { + const unsafe fn test_mm256_mask_reduce_min_epi8() { let a = _mm256_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -16054,49 +16966,49 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_min_epi8() { + const unsafe fn test_mm_reduce_min_epi8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i8 = _mm_reduce_min_epi8(a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_min_epi8() { + const unsafe fn test_mm_mask_reduce_min_epi8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: i8 = _mm_mask_reduce_min_epi8(0b11111111_00000000, a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_min_epu16() { + const unsafe fn test_mm256_reduce_min_epu16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u16 = _mm256_reduce_min_epu16(a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_min_epu16() { + const unsafe fn test_mm256_mask_reduce_min_epu16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u16 = _mm256_mask_reduce_min_epu16(0b11111111_00000000, a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_min_epu16() { + const unsafe fn test_mm_reduce_min_epu16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let e: u16 = _mm_reduce_min_epu16(a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_min_epu16() { + const unsafe fn test_mm_mask_reduce_min_epu16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let e: u16 = _mm_mask_reduce_min_epu16(0b11110000, a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_min_epu8() { + const unsafe fn test_mm256_reduce_min_epu8() { let a = _mm256_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -16106,7 +17018,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_min_epu8() { + const unsafe fn test_mm256_mask_reduce_min_epu8() { let a = _mm256_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -16116,49 +17028,49 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_min_epu8() { + const unsafe fn test_mm_reduce_min_epu8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u8 = _mm_reduce_min_epu8(a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_min_epu8() { + const unsafe fn test_mm_mask_reduce_min_epu8() { let a = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e: u8 = _mm_mask_reduce_min_epu8(0b11111111_00000000, a); assert_eq!(0, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_or_epi16() { + const unsafe fn test_mm256_reduce_or_epi16() { let a = _mm256_set_epi16(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e = _mm256_reduce_or_epi16(a); assert_eq!(3, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_or_epi16() { + const unsafe fn test_mm256_mask_reduce_or_epi16() { let a = _mm256_set_epi16(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e = _mm256_mask_reduce_or_epi16(0b11111111_00000000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_or_epi16() { + const unsafe fn test_mm_reduce_or_epi16() { let a = _mm_set_epi16(1, 1, 1, 1, 2, 2, 2, 2); let e = _mm_reduce_or_epi16(a); assert_eq!(3, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_or_epi16() { + const unsafe fn test_mm_mask_reduce_or_epi16() { let a = _mm_set_epi16(1, 1, 1, 1, 2, 2, 2, 2); let e = _mm_mask_reduce_or_epi16(0b11110000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_reduce_or_epi8() { + const unsafe fn test_mm256_reduce_or_epi8() { let a = _mm256_set_epi8( 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, @@ -16168,7 +17080,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_reduce_or_epi8() { + const unsafe fn test_mm256_mask_reduce_or_epi8() { let a = _mm256_set_epi8( 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, @@ -16178,21 +17090,21 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_reduce_or_epi8() { + const unsafe fn test_mm_reduce_or_epi8() { let a = _mm_set_epi8(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e = _mm_reduce_or_epi8(a); assert_eq!(3, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_reduce_or_epi8() { + const unsafe fn test_mm_mask_reduce_or_epi8() { let a = _mm_set_epi8(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2); let e = _mm_mask_reduce_or_epi8(0b11111111_00000000, a); assert_eq!(1, e); } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_loadu_epi16() { + const unsafe fn test_mm512_loadu_epi16() { #[rustfmt::skip] let a: [i16; 32] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]; let r = _mm512_loadu_epi16(&a[0]); @@ -16202,7 +17114,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_loadu_epi16() { + const unsafe fn test_mm256_loadu_epi16() { let a: [i16; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let r = _mm256_loadu_epi16(&a[0]); let e = _mm256_set_epi16(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); @@ -16210,7 +17122,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_loadu_epi16() { + const unsafe fn test_mm_loadu_epi16() { let a: [i16; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; let r = _mm_loadu_epi16(&a[0]); let e = _mm_set_epi16(8, 7, 6, 5, 4, 3, 2, 1); @@ -16218,7 +17130,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_loadu_epi8() { + const unsafe fn test_mm512_loadu_epi8() { #[rustfmt::skip] let a: [i8; 64] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]; @@ -16230,7 +17142,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_loadu_epi8() { + const unsafe fn test_mm256_loadu_epi8() { #[rustfmt::skip] let a: [i8; 32] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]; let r = _mm256_loadu_epi8(&a[0]); @@ -16240,7 +17152,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_loadu_epi8() { + const unsafe fn test_mm_loadu_epi8() { let a: [i8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let r = _mm_loadu_epi8(&a[0]); let e = _mm_set_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); @@ -16248,7 +17160,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_storeu_epi16() { + const unsafe fn test_mm512_storeu_epi16() { let a = _mm512_set1_epi16(9); let mut r = _mm512_undefined_epi32(); _mm512_storeu_epi16(&mut r as *mut _ as *mut i16, a); @@ -16256,7 +17168,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_storeu_epi16() { + const unsafe fn test_mm256_storeu_epi16() { let a = _mm256_set1_epi16(9); let mut r = _mm256_set1_epi32(0); _mm256_storeu_epi16(&mut r as *mut _ as *mut i16, a); @@ -16264,7 +17176,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_storeu_epi16() { + const unsafe fn test_mm_storeu_epi16() { let a = _mm_set1_epi16(9); let mut r = _mm_set1_epi32(0); _mm_storeu_epi16(&mut r as *mut _ as *mut i16, a); @@ -16272,7 +17184,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_storeu_epi8() { + const unsafe fn test_mm512_storeu_epi8() { let a = _mm512_set1_epi8(9); let mut r = _mm512_undefined_epi32(); _mm512_storeu_epi8(&mut r as *mut _ as *mut i8, a); @@ -16280,7 +17192,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_storeu_epi8() { + const unsafe fn test_mm256_storeu_epi8() { let a = _mm256_set1_epi8(9); let mut r = _mm256_set1_epi32(0); _mm256_storeu_epi8(&mut r as *mut _ as *mut i8, a); @@ -16288,7 +17200,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_storeu_epi8() { + const unsafe fn test_mm_storeu_epi8() { let a = _mm_set1_epi8(9); let mut r = _mm_set1_epi32(0); _mm_storeu_epi8(&mut r as *mut _ as *mut i8, a); @@ -16296,7 +17208,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_loadu_epi16() { + const unsafe fn test_mm512_mask_loadu_epi16() { let src = _mm512_set1_epi16(42); let a = &[ 1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -16314,7 +17226,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_loadu_epi16() { + const unsafe fn test_mm512_maskz_loadu_epi16() { let a = &[ 1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -16331,7 +17243,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_storeu_epi16() { + const unsafe fn test_mm512_mask_storeu_epi16() { let mut r = [42_i16; 32]; let a = &[ 1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -16349,7 +17261,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_loadu_epi8() { + const unsafe fn test_mm512_mask_loadu_epi8() { let src = _mm512_set1_epi8(42); let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -16369,7 +17281,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_loadu_epi8() { + const unsafe fn test_mm512_maskz_loadu_epi8() { let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, @@ -16388,7 +17300,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_storeu_epi8() { + const unsafe fn test_mm512_mask_storeu_epi8() { let mut r = [42_i8; 64]; let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -16408,7 +17320,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_loadu_epi16() { + const unsafe fn test_mm256_mask_loadu_epi16() { let src = _mm256_set1_epi16(42); let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); @@ -16422,7 +17334,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_loadu_epi16() { + const unsafe fn test_mm256_maskz_loadu_epi16() { let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; @@ -16433,7 +17345,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_storeu_epi16() { + const unsafe fn test_mm256_mask_storeu_epi16() { let mut r = [42_i16; 16]; let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let a = _mm256_loadu_epi16(a.as_ptr()); @@ -16447,7 +17359,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_loadu_epi8() { + const unsafe fn test_mm256_mask_loadu_epi8() { let src = _mm256_set1_epi8(42); let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -16465,7 +17377,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_loadu_epi8() { + const unsafe fn test_mm256_maskz_loadu_epi8() { let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -16482,7 +17394,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_storeu_epi8() { + const unsafe fn test_mm256_mask_storeu_epi8() { let mut r = [42_i8; 32]; let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -16500,7 +17412,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_loadu_epi16() { + const unsafe fn test_mm_mask_loadu_epi16() { let src = _mm_set1_epi16(42); let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); @@ -16512,7 +17424,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_loadu_epi16() { + const unsafe fn test_mm_maskz_loadu_epi16() { let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11001010; @@ -16523,7 +17435,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_storeu_epi16() { + const unsafe fn test_mm_mask_storeu_epi16() { let mut r = [42_i16; 8]; let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8]; let a = _mm_loadu_epi16(a.as_ptr()); @@ -16535,7 +17447,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_loadu_epi8() { + const unsafe fn test_mm_mask_loadu_epi8() { let src = _mm_set1_epi8(42); let a = &[1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); @@ -16549,7 +17461,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_loadu_epi8() { + const unsafe fn test_mm_maskz_loadu_epi8() { let a = &[1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; @@ -16560,7 +17472,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_storeu_epi8() { + const unsafe fn test_mm_mask_storeu_epi8() { let mut r = [42_i8; 16]; let a = &[1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let a = _mm_loadu_epi8(a.as_ptr()); @@ -16574,7 +17486,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_madd_epi16() { + const unsafe fn test_mm512_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_madd_epi16(a, b); @@ -16583,7 +17495,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_madd_epi16() { + const unsafe fn test_mm512_mask_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mask_madd_epi16(a, 0, a, b); @@ -16611,7 +17523,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_madd_epi16() { + const unsafe fn test_mm512_maskz_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_madd_epi16(0, a, b); @@ -16622,7 +17534,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_madd_epi16() { + const unsafe fn test_mm256_mask_madd_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_mask_madd_epi16(a, 0, a, b); @@ -16642,7 +17554,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_madd_epi16() { + const unsafe fn test_mm256_maskz_madd_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_madd_epi16(0, a, b); @@ -16653,7 +17565,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_madd_epi16() { + const unsafe fn test_mm_mask_madd_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_mask_madd_epi16(a, 0, a, b); @@ -16664,7 +17576,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_madd_epi16() { + const unsafe fn test_mm_maskz_madd_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_maskz_madd_epi16(0, a, b); @@ -17123,7 +18035,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_avg_epu16() { + const unsafe fn test_mm512_avg_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_avg_epu16(a, b); @@ -17132,7 +18044,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_avg_epu16() { + const unsafe fn test_mm512_mask_avg_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mask_avg_epu16(a, 0, a, b); @@ -17145,7 +18057,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_avg_epu16() { + const unsafe fn test_mm512_maskz_avg_epu16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_avg_epu16(0, a, b); @@ -17158,7 +18070,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_avg_epu16() { + const unsafe fn test_mm256_mask_avg_epu16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_mask_avg_epu16(a, 0, a, b); @@ -17169,7 +18081,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_avg_epu16() { + const unsafe fn test_mm256_maskz_avg_epu16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_avg_epu16(0, a, b); @@ -17180,7 +18092,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_avg_epu16() { + const unsafe fn test_mm_mask_avg_epu16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_mask_avg_epu16(a, 0, a, b); @@ -17191,7 +18103,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_avg_epu16() { + const unsafe fn test_mm_maskz_avg_epu16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_maskz_avg_epu16(0, a, b); @@ -17202,7 +18114,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_avg_epu8() { + const unsafe fn test_mm512_avg_epu8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(1); let r = _mm512_avg_epu8(a, b); @@ -17211,7 +18123,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_avg_epu8() { + const unsafe fn test_mm512_mask_avg_epu8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(1); let r = _mm512_mask_avg_epu8(a, 0, a, b); @@ -17231,7 +18143,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_avg_epu8() { + const unsafe fn test_mm512_maskz_avg_epu8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(1); let r = _mm512_maskz_avg_epu8(0, a, b); @@ -17250,7 +18162,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_avg_epu8() { + const unsafe fn test_mm256_mask_avg_epu8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(1); let r = _mm256_mask_avg_epu8(a, 0, a, b); @@ -17263,7 +18175,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_avg_epu8() { + const unsafe fn test_mm256_maskz_avg_epu8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(1); let r = _mm256_maskz_avg_epu8(0, a, b); @@ -17276,7 +18188,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_avg_epu8() { + const unsafe fn test_mm_mask_avg_epu8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(1); let r = _mm_mask_avg_epu8(a, 0, a, b); @@ -17287,7 +18199,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_avg_epu8() { + const unsafe fn test_mm_maskz_avg_epu8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(1); let r = _mm_maskz_avg_epu8(0, a, b); @@ -17373,7 +18285,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_slli_epi16() { + const unsafe fn test_mm512_slli_epi16() { let a = _mm512_set1_epi16(1 << 15); let r = _mm512_slli_epi16::<1>(a); let e = _mm512_set1_epi16(0); @@ -17381,7 +18293,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_slli_epi16() { + const unsafe fn test_mm512_mask_slli_epi16() { let a = _mm512_set1_epi16(1 << 15); let r = _mm512_mask_slli_epi16::<1>(a, 0, a); assert_eq_m512i(r, a); @@ -17391,7 +18303,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_slli_epi16() { + const unsafe fn test_mm512_maskz_slli_epi16() { let a = _mm512_set1_epi16(1 << 15); let r = _mm512_maskz_slli_epi16::<1>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -17401,7 +18313,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_slli_epi16() { + const unsafe fn test_mm256_mask_slli_epi16() { let a = _mm256_set1_epi16(1 << 15); let r = _mm256_mask_slli_epi16::<1>(a, 0, a); assert_eq_m256i(r, a); @@ -17411,7 +18323,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_slli_epi16() { + const unsafe fn test_mm256_maskz_slli_epi16() { let a = _mm256_set1_epi16(1 << 15); let r = _mm256_maskz_slli_epi16::<1>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -17421,7 +18333,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_slli_epi16() { + const unsafe fn test_mm_mask_slli_epi16() { let a = _mm_set1_epi16(1 << 15); let r = _mm_mask_slli_epi16::<1>(a, 0, a); assert_eq_m128i(r, a); @@ -17431,7 +18343,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_slli_epi16() { + const unsafe fn test_mm_maskz_slli_epi16() { let a = _mm_set1_epi16(1 << 15); let r = _mm_maskz_slli_epi16::<1>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -17441,7 +18353,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_sllv_epi16() { + const unsafe fn test_mm512_sllv_epi16() { let a = _mm512_set1_epi16(1 << 15); let count = _mm512_set1_epi16(2); let r = _mm512_sllv_epi16(a, count); @@ -17450,7 +18362,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_sllv_epi16() { + const unsafe fn test_mm512_mask_sllv_epi16() { let a = _mm512_set1_epi16(1 << 15); let count = _mm512_set1_epi16(2); let r = _mm512_mask_sllv_epi16(a, 0, a, count); @@ -17461,7 +18373,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_sllv_epi16() { + const unsafe fn test_mm512_maskz_sllv_epi16() { let a = _mm512_set1_epi16(1 << 15); let count = _mm512_set1_epi16(2); let r = _mm512_maskz_sllv_epi16(0, a, count); @@ -17472,7 +18384,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_sllv_epi16() { + const unsafe fn test_mm256_sllv_epi16() { let a = _mm256_set1_epi16(1 << 15); let count = _mm256_set1_epi16(2); let r = _mm256_sllv_epi16(a, count); @@ -17481,7 +18393,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_sllv_epi16() { + const unsafe fn test_mm256_mask_sllv_epi16() { let a = _mm256_set1_epi16(1 << 15); let count = _mm256_set1_epi16(2); let r = _mm256_mask_sllv_epi16(a, 0, a, count); @@ -17492,7 +18404,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_sllv_epi16() { + const unsafe fn test_mm256_maskz_sllv_epi16() { let a = _mm256_set1_epi16(1 << 15); let count = _mm256_set1_epi16(2); let r = _mm256_maskz_sllv_epi16(0, a, count); @@ -17503,7 +18415,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_sllv_epi16() { + const unsafe fn test_mm_sllv_epi16() { let a = _mm_set1_epi16(1 << 15); let count = _mm_set1_epi16(2); let r = _mm_sllv_epi16(a, count); @@ -17512,7 +18424,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_sllv_epi16() { + const unsafe fn test_mm_mask_sllv_epi16() { let a = _mm_set1_epi16(1 << 15); let count = _mm_set1_epi16(2); let r = _mm_mask_sllv_epi16(a, 0, a, count); @@ -17523,7 +18435,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_sllv_epi16() { + const unsafe fn test_mm_maskz_sllv_epi16() { let a = _mm_set1_epi16(1 << 15); let count = _mm_set1_epi16(2); let r = _mm_maskz_sllv_epi16(0, a, count); @@ -17609,7 +18521,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_srli_epi16() { + const unsafe fn test_mm512_srli_epi16() { let a = _mm512_set1_epi16(1 << 1); let r = _mm512_srli_epi16::<2>(a); let e = _mm512_set1_epi16(0); @@ -17617,7 +18529,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_srli_epi16() { + const unsafe fn test_mm512_mask_srli_epi16() { let a = _mm512_set1_epi16(1 << 1); let r = _mm512_mask_srli_epi16::<2>(a, 0, a); assert_eq_m512i(r, a); @@ -17627,7 +18539,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_srli_epi16() { + const unsafe fn test_mm512_maskz_srli_epi16() { let a = _mm512_set1_epi16(1 << 1); let r = _mm512_maskz_srli_epi16::<2>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -17637,7 +18549,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_srli_epi16() { + const unsafe fn test_mm256_mask_srli_epi16() { let a = _mm256_set1_epi16(1 << 1); let r = _mm256_mask_srli_epi16::<2>(a, 0, a); assert_eq_m256i(r, a); @@ -17647,7 +18559,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_srli_epi16() { + const unsafe fn test_mm256_maskz_srli_epi16() { let a = _mm256_set1_epi16(1 << 1); let r = _mm256_maskz_srli_epi16::<2>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -17657,7 +18569,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_srli_epi16() { + const unsafe fn test_mm_mask_srli_epi16() { let a = _mm_set1_epi16(1 << 1); let r = _mm_mask_srli_epi16::<2>(a, 0, a); assert_eq_m128i(r, a); @@ -17667,7 +18579,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_srli_epi16() { + const unsafe fn test_mm_maskz_srli_epi16() { let a = _mm_set1_epi16(1 << 1); let r = _mm_maskz_srli_epi16::<2>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -17677,7 +18589,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_srlv_epi16() { + const unsafe fn test_mm512_srlv_epi16() { let a = _mm512_set1_epi16(1 << 1); let count = _mm512_set1_epi16(2); let r = _mm512_srlv_epi16(a, count); @@ -17686,7 +18598,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_srlv_epi16() { + const unsafe fn test_mm512_mask_srlv_epi16() { let a = _mm512_set1_epi16(1 << 1); let count = _mm512_set1_epi16(2); let r = _mm512_mask_srlv_epi16(a, 0, a, count); @@ -17697,7 +18609,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_srlv_epi16() { + const unsafe fn test_mm512_maskz_srlv_epi16() { let a = _mm512_set1_epi16(1 << 1); let count = _mm512_set1_epi16(2); let r = _mm512_maskz_srlv_epi16(0, a, count); @@ -17708,7 +18620,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_srlv_epi16() { + const unsafe fn test_mm256_srlv_epi16() { let a = _mm256_set1_epi16(1 << 1); let count = _mm256_set1_epi16(2); let r = _mm256_srlv_epi16(a, count); @@ -17717,7 +18629,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_srlv_epi16() { + const unsafe fn test_mm256_mask_srlv_epi16() { let a = _mm256_set1_epi16(1 << 1); let count = _mm256_set1_epi16(2); let r = _mm256_mask_srlv_epi16(a, 0, a, count); @@ -17728,7 +18640,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_srlv_epi16() { + const unsafe fn test_mm256_maskz_srlv_epi16() { let a = _mm256_set1_epi16(1 << 1); let count = _mm256_set1_epi16(2); let r = _mm256_maskz_srlv_epi16(0, a, count); @@ -17739,7 +18651,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_srlv_epi16() { + const unsafe fn test_mm_srlv_epi16() { let a = _mm_set1_epi16(1 << 1); let count = _mm_set1_epi16(2); let r = _mm_srlv_epi16(a, count); @@ -17748,7 +18660,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_srlv_epi16() { + const unsafe fn test_mm_mask_srlv_epi16() { let a = _mm_set1_epi16(1 << 1); let count = _mm_set1_epi16(2); let r = _mm_mask_srlv_epi16(a, 0, a, count); @@ -17759,7 +18671,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_srlv_epi16() { + const unsafe fn test_mm_maskz_srlv_epi16() { let a = _mm_set1_epi16(1 << 1); let count = _mm_set1_epi16(2); let r = _mm_maskz_srlv_epi16(0, a, count); @@ -17845,7 +18757,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_srai_epi16() { + const unsafe fn test_mm512_srai_epi16() { let a = _mm512_set1_epi16(8); let r = _mm512_srai_epi16::<2>(a); let e = _mm512_set1_epi16(2); @@ -17853,7 +18765,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_srai_epi16() { + const unsafe fn test_mm512_mask_srai_epi16() { let a = _mm512_set1_epi16(8); let r = _mm512_mask_srai_epi16::<2>(a, 0, a); assert_eq_m512i(r, a); @@ -17863,7 +18775,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_srai_epi16() { + const unsafe fn test_mm512_maskz_srai_epi16() { let a = _mm512_set1_epi16(8); let r = _mm512_maskz_srai_epi16::<2>(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -17873,7 +18785,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_srai_epi16() { + const unsafe fn test_mm256_mask_srai_epi16() { let a = _mm256_set1_epi16(8); let r = _mm256_mask_srai_epi16::<2>(a, 0, a); assert_eq_m256i(r, a); @@ -17883,7 +18795,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_srai_epi16() { + const unsafe fn test_mm256_maskz_srai_epi16() { let a = _mm256_set1_epi16(8); let r = _mm256_maskz_srai_epi16::<2>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -17893,7 +18805,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_srai_epi16() { + const unsafe fn test_mm_mask_srai_epi16() { let a = _mm_set1_epi16(8); let r = _mm_mask_srai_epi16::<2>(a, 0, a); assert_eq_m128i(r, a); @@ -17903,7 +18815,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_srai_epi16() { + const unsafe fn test_mm_maskz_srai_epi16() { let a = _mm_set1_epi16(8); let r = _mm_maskz_srai_epi16::<2>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -17913,7 +18825,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_srav_epi16() { + const unsafe fn test_mm512_srav_epi16() { let a = _mm512_set1_epi16(8); let count = _mm512_set1_epi16(2); let r = _mm512_srav_epi16(a, count); @@ -17922,7 +18834,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_srav_epi16() { + const unsafe fn test_mm512_mask_srav_epi16() { let a = _mm512_set1_epi16(8); let count = _mm512_set1_epi16(2); let r = _mm512_mask_srav_epi16(a, 0, a, count); @@ -17933,7 +18845,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_srav_epi16() { + const unsafe fn test_mm512_maskz_srav_epi16() { let a = _mm512_set1_epi16(8); let count = _mm512_set1_epi16(2); let r = _mm512_maskz_srav_epi16(0, a, count); @@ -17944,7 +18856,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_srav_epi16() { + const unsafe fn test_mm256_srav_epi16() { let a = _mm256_set1_epi16(8); let count = _mm256_set1_epi16(2); let r = _mm256_srav_epi16(a, count); @@ -17953,7 +18865,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_srav_epi16() { + const unsafe fn test_mm256_mask_srav_epi16() { let a = _mm256_set1_epi16(8); let count = _mm256_set1_epi16(2); let r = _mm256_mask_srav_epi16(a, 0, a, count); @@ -17964,7 +18876,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_srav_epi16() { + const unsafe fn test_mm256_maskz_srav_epi16() { let a = _mm256_set1_epi16(8); let count = _mm256_set1_epi16(2); let r = _mm256_maskz_srav_epi16(0, a, count); @@ -17975,7 +18887,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_srav_epi16() { + const unsafe fn test_mm_srav_epi16() { let a = _mm_set1_epi16(8); let count = _mm_set1_epi16(2); let r = _mm_srav_epi16(a, count); @@ -17984,7 +18896,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_srav_epi16() { + const unsafe fn test_mm_mask_srav_epi16() { let a = _mm_set1_epi16(8); let count = _mm_set1_epi16(2); let r = _mm_mask_srav_epi16(a, 0, a, count); @@ -17995,7 +18907,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_srav_epi16() { + const unsafe fn test_mm_maskz_srav_epi16() { let a = _mm_set1_epi16(8); let count = _mm_set1_epi16(2); let r = _mm_maskz_srav_epi16(0, a, count); @@ -18288,7 +19200,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_blend_epi16() { + const unsafe fn test_mm512_mask_blend_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(2); let r = _mm512_mask_blend_epi16(0b11111111_00000000_11111111_00000000, a, b); @@ -18299,7 +19211,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_blend_epi16() { + const unsafe fn test_mm256_mask_blend_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(2); let r = _mm256_mask_blend_epi16(0b11111111_00000000, a, b); @@ -18308,7 +19220,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_blend_epi16() { + const unsafe fn test_mm_mask_blend_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(2); let r = _mm_mask_blend_epi16(0b11110000, a, b); @@ -18317,7 +19229,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_blend_epi8() { + const unsafe fn test_mm512_mask_blend_epi8() { let a = _mm512_set1_epi8(1); let b = _mm512_set1_epi8(2); let r = _mm512_mask_blend_epi8( @@ -18334,7 +19246,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_blend_epi8() { + const unsafe fn test_mm256_mask_blend_epi8() { let a = _mm256_set1_epi8(1); let b = _mm256_set1_epi8(2); let r = _mm256_mask_blend_epi8(0b11111111_00000000_11111111_00000000, a, b); @@ -18345,7 +19257,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_blend_epi8() { + const unsafe fn test_mm_mask_blend_epi8() { let a = _mm_set1_epi8(1); let b = _mm_set1_epi8(2); let r = _mm_mask_blend_epi8(0b11111111_00000000, a, b); @@ -18354,7 +19266,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_broadcastw_epi16() { + const unsafe fn test_mm512_broadcastw_epi16() { let a = _mm_set_epi16(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_broadcastw_epi16(a); let e = _mm512_set1_epi16(24); @@ -18362,7 +19274,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_broadcastw_epi16() { + const unsafe fn test_mm512_mask_broadcastw_epi16() { let src = _mm512_set1_epi16(1); let a = _mm_set_epi16(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_mask_broadcastw_epi16(src, 0, a); @@ -18373,7 +19285,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_broadcastw_epi16() { + const unsafe fn test_mm512_maskz_broadcastw_epi16() { let a = _mm_set_epi16(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_maskz_broadcastw_epi16(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -18383,7 +19295,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_broadcastw_epi16() { + const unsafe fn test_mm256_mask_broadcastw_epi16() { let src = _mm256_set1_epi16(1); let a = _mm_set_epi16(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm256_mask_broadcastw_epi16(src, 0, a); @@ -18394,7 +19306,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_broadcastw_epi16() { + const unsafe fn test_mm256_maskz_broadcastw_epi16() { let a = _mm_set_epi16(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm256_maskz_broadcastw_epi16(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -18404,7 +19316,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_broadcastw_epi16() { + const unsafe fn test_mm_mask_broadcastw_epi16() { let src = _mm_set1_epi16(1); let a = _mm_set_epi16(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm_mask_broadcastw_epi16(src, 0, a); @@ -18415,7 +19327,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_broadcastw_epi16() { + const unsafe fn test_mm_maskz_broadcastw_epi16() { let a = _mm_set_epi16(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm_maskz_broadcastw_epi16(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -18425,7 +19337,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_broadcastb_epi8() { + const unsafe fn test_mm512_broadcastb_epi8() { let a = _mm_set_epi8( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ); @@ -18435,7 +19347,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_broadcastb_epi8() { + const unsafe fn test_mm512_mask_broadcastb_epi8() { let src = _mm512_set1_epi8(1); let a = _mm_set_epi8( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -18452,7 +19364,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_broadcastb_epi8() { + const unsafe fn test_mm512_maskz_broadcastb_epi8() { let a = _mm_set_epi8( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ); @@ -18467,7 +19379,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_broadcastb_epi8() { + const unsafe fn test_mm256_mask_broadcastb_epi8() { let src = _mm256_set1_epi8(1); let a = _mm_set_epi8( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -18480,7 +19392,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_broadcastb_epi8() { + const unsafe fn test_mm256_maskz_broadcastb_epi8() { let a = _mm_set_epi8( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ); @@ -18492,7 +19404,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_broadcastb_epi8() { + const unsafe fn test_mm_mask_broadcastb_epi8() { let src = _mm_set1_epi8(1); let a = _mm_set_epi8( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -18505,7 +19417,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_broadcastb_epi8() { + const unsafe fn test_mm_maskz_broadcastb_epi8() { let a = _mm_set_epi8( 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ); @@ -18517,7 +19429,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_unpackhi_epi16() { + const unsafe fn test_mm512_unpackhi_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18532,7 +19444,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_unpackhi_epi16() { + const unsafe fn test_mm512_mask_unpackhi_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18549,7 +19461,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_unpackhi_epi16() { + const unsafe fn test_mm512_maskz_unpackhi_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18566,7 +19478,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_unpackhi_epi16() { + const unsafe fn test_mm256_mask_unpackhi_epi16() { let a = _mm256_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm256_set_epi16( 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, @@ -18579,7 +19491,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_unpackhi_epi16() { + const unsafe fn test_mm256_maskz_unpackhi_epi16() { let a = _mm256_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm256_set_epi16( 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, @@ -18592,7 +19504,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_unpackhi_epi16() { + const unsafe fn test_mm_mask_unpackhi_epi16() { let a = _mm_set_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi16(33, 34, 35, 36, 37, 38, 39, 40); let r = _mm_mask_unpackhi_epi16(a, 0, a, b); @@ -18603,7 +19515,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_unpackhi_epi16() { + const unsafe fn test_mm_maskz_unpackhi_epi16() { let a = _mm_set_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi16(33, 34, 35, 36, 37, 38, 39, 40); let r = _mm_maskz_unpackhi_epi16(0, a, b); @@ -18614,7 +19526,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_unpackhi_epi8() { + const unsafe fn test_mm512_unpackhi_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -18635,7 +19547,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_unpackhi_epi8() { + const unsafe fn test_mm512_mask_unpackhi_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -18663,7 +19575,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_unpackhi_epi8() { + const unsafe fn test_mm512_maskz_unpackhi_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -18690,7 +19602,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_unpackhi_epi8() { + const unsafe fn test_mm256_mask_unpackhi_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18707,7 +19619,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_unpackhi_epi8() { + const unsafe fn test_mm256_maskz_unpackhi_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18724,7 +19636,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_unpackhi_epi8() { + const unsafe fn test_mm_mask_unpackhi_epi8() { let a = _mm_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm_set_epi8( 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, @@ -18737,7 +19649,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_unpackhi_epi8() { + const unsafe fn test_mm_maskz_unpackhi_epi8() { let a = _mm_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm_set_epi8( 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, @@ -18750,7 +19662,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_unpacklo_epi16() { + const unsafe fn test_mm512_unpacklo_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18765,7 +19677,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_unpacklo_epi16() { + const unsafe fn test_mm512_mask_unpacklo_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18782,7 +19694,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_unpacklo_epi16() { + const unsafe fn test_mm512_maskz_unpacklo_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18799,7 +19711,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_unpacklo_epi16() { + const unsafe fn test_mm256_mask_unpacklo_epi16() { let a = _mm256_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm256_set_epi16( 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, @@ -18812,7 +19724,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_unpacklo_epi16() { + const unsafe fn test_mm256_maskz_unpacklo_epi16() { let a = _mm256_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm256_set_epi16( 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, @@ -18825,7 +19737,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_unpacklo_epi16() { + const unsafe fn test_mm_mask_unpacklo_epi16() { let a = _mm_set_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi16(33, 34, 35, 36, 37, 38, 39, 40); let r = _mm_mask_unpacklo_epi16(a, 0, a, b); @@ -18836,7 +19748,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_unpacklo_epi16() { + const unsafe fn test_mm_maskz_unpacklo_epi16() { let a = _mm_set_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi16(33, 34, 35, 36, 37, 38, 39, 40); let r = _mm_maskz_unpacklo_epi16(0, a, b); @@ -18847,7 +19759,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_unpacklo_epi8() { + const unsafe fn test_mm512_unpacklo_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -18868,7 +19780,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_unpacklo_epi8() { + const unsafe fn test_mm512_mask_unpacklo_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -18896,7 +19808,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_unpacklo_epi8() { + const unsafe fn test_mm512_maskz_unpacklo_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, @@ -18923,7 +19835,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_unpacklo_epi8() { + const unsafe fn test_mm256_mask_unpacklo_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18940,7 +19852,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_unpacklo_epi8() { + const unsafe fn test_mm256_maskz_unpacklo_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); @@ -18957,7 +19869,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_unpacklo_epi8() { + const unsafe fn test_mm_mask_unpacklo_epi8() { let a = _mm_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm_set_epi8( 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, @@ -18972,7 +19884,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_unpacklo_epi8() { + const unsafe fn test_mm_maskz_unpacklo_epi8() { let a = _mm_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm_set_epi8( 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, @@ -18987,7 +19899,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_mov_epi16() { + const unsafe fn test_mm512_mask_mov_epi16() { let src = _mm512_set1_epi16(1); let a = _mm512_set1_epi16(2); let r = _mm512_mask_mov_epi16(src, 0, a); @@ -18997,7 +19909,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_mov_epi16() { + const unsafe fn test_mm512_maskz_mov_epi16() { let a = _mm512_set1_epi16(2); let r = _mm512_maskz_mov_epi16(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -19006,7 +19918,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_mov_epi16() { + const unsafe fn test_mm256_mask_mov_epi16() { let src = _mm256_set1_epi16(1); let a = _mm256_set1_epi16(2); let r = _mm256_mask_mov_epi16(src, 0, a); @@ -19016,7 +19928,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_mov_epi16() { + const unsafe fn test_mm256_maskz_mov_epi16() { let a = _mm256_set1_epi16(2); let r = _mm256_maskz_mov_epi16(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -19025,7 +19937,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_mov_epi16() { + const unsafe fn test_mm_mask_mov_epi16() { let src = _mm_set1_epi16(1); let a = _mm_set1_epi16(2); let r = _mm_mask_mov_epi16(src, 0, a); @@ -19035,7 +19947,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_mov_epi16() { + const unsafe fn test_mm_maskz_mov_epi16() { let a = _mm_set1_epi16(2); let r = _mm_maskz_mov_epi16(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -19044,7 +19956,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_mov_epi8() { + const unsafe fn test_mm512_mask_mov_epi8() { let src = _mm512_set1_epi8(1); let a = _mm512_set1_epi8(2); let r = _mm512_mask_mov_epi8(src, 0, a); @@ -19058,7 +19970,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_mov_epi8() { + const unsafe fn test_mm512_maskz_mov_epi8() { let a = _mm512_set1_epi8(2); let r = _mm512_maskz_mov_epi8(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -19070,7 +19982,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_mov_epi8() { + const unsafe fn test_mm256_mask_mov_epi8() { let src = _mm256_set1_epi8(1); let a = _mm256_set1_epi8(2); let r = _mm256_mask_mov_epi8(src, 0, a); @@ -19080,7 +19992,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_mov_epi8() { + const unsafe fn test_mm256_maskz_mov_epi8() { let a = _mm256_set1_epi8(2); let r = _mm256_maskz_mov_epi8(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -19089,7 +20001,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_mov_epi8() { + const unsafe fn test_mm_mask_mov_epi8() { let src = _mm_set1_epi8(1); let a = _mm_set1_epi8(2); let r = _mm_mask_mov_epi8(src, 0, a); @@ -19099,7 +20011,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_mov_epi8() { + const unsafe fn test_mm_maskz_mov_epi8() { let a = _mm_set1_epi8(2); let r = _mm_maskz_mov_epi8(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -19108,7 +20020,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_set1_epi16() { + const unsafe fn test_mm512_mask_set1_epi16() { let src = _mm512_set1_epi16(2); let a: i16 = 11; let r = _mm512_mask_set1_epi16(src, 0, a); @@ -19119,7 +20031,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_set1_epi16() { + const unsafe fn test_mm512_maskz_set1_epi16() { let a: i16 = 11; let r = _mm512_maskz_set1_epi16(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -19129,7 +20041,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_set1_epi16() { + const unsafe fn test_mm256_mask_set1_epi16() { let src = _mm256_set1_epi16(2); let a: i16 = 11; let r = _mm256_mask_set1_epi16(src, 0, a); @@ -19140,7 +20052,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_set1_epi16() { + const unsafe fn test_mm256_maskz_set1_epi16() { let a: i16 = 11; let r = _mm256_maskz_set1_epi16(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -19150,7 +20062,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_set1_epi16() { + const unsafe fn test_mm_mask_set1_epi16() { let src = _mm_set1_epi16(2); let a: i16 = 11; let r = _mm_mask_set1_epi16(src, 0, a); @@ -19161,7 +20073,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_set1_epi16() { + const unsafe fn test_mm_maskz_set1_epi16() { let a: i16 = 11; let r = _mm_maskz_set1_epi16(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -19171,7 +20083,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_set1_epi8() { + const unsafe fn test_mm512_mask_set1_epi8() { let src = _mm512_set1_epi8(2); let a: i8 = 11; let r = _mm512_mask_set1_epi8(src, 0, a); @@ -19186,7 +20098,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_set1_epi8() { + const unsafe fn test_mm512_maskz_set1_epi8() { let a: i8 = 11; let r = _mm512_maskz_set1_epi8(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -19199,7 +20111,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_set1_epi8() { + const unsafe fn test_mm256_mask_set1_epi8() { let src = _mm256_set1_epi8(2); let a: i8 = 11; let r = _mm256_mask_set1_epi8(src, 0, a); @@ -19210,7 +20122,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_set1_epi8() { + const unsafe fn test_mm256_maskz_set1_epi8() { let a: i8 = 11; let r = _mm256_maskz_set1_epi8(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -19220,7 +20132,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_set1_epi8() { + const unsafe fn test_mm_mask_set1_epi8() { let src = _mm_set1_epi8(2); let a: i8 = 11; let r = _mm_mask_set1_epi8(src, 0, a); @@ -19231,7 +20143,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_set1_epi8() { + const unsafe fn test_mm_maskz_set1_epi8() { let a: i8 = 11; let r = _mm_maskz_set1_epi8(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -19241,7 +20153,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_shufflelo_epi16() { + const unsafe fn test_mm512_shufflelo_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -19257,7 +20169,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_shufflelo_epi16() { + const unsafe fn test_mm512_mask_shufflelo_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -19279,7 +20191,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_shufflelo_epi16() { + const unsafe fn test_mm512_maskz_shufflelo_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -19298,7 +20210,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_shufflelo_epi16() { + const unsafe fn test_mm256_mask_shufflelo_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_mask_shufflelo_epi16::<0b00_01_01_11>(a, 0, a); assert_eq_m256i(r, a); @@ -19308,7 +20220,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_shufflelo_epi16() { + const unsafe fn test_mm256_maskz_shufflelo_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_maskz_shufflelo_epi16::<0b00_01_01_11>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -19318,7 +20230,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_shufflelo_epi16() { + const unsafe fn test_mm_mask_shufflelo_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm_mask_shufflelo_epi16::<0b00_01_01_11>(a, 0, a); assert_eq_m128i(r, a); @@ -19328,7 +20240,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_shufflelo_epi16() { + const unsafe fn test_mm_maskz_shufflelo_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm_maskz_shufflelo_epi16::<0b00_01_01_11>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -19338,7 +20250,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_shufflehi_epi16() { + const unsafe fn test_mm512_shufflehi_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -19354,7 +20266,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_shufflehi_epi16() { + const unsafe fn test_mm512_mask_shufflehi_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -19376,7 +20288,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_shufflehi_epi16() { + const unsafe fn test_mm512_maskz_shufflehi_epi16() { #[rustfmt::skip] let a = _mm512_set_epi16( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -19395,7 +20307,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_shufflehi_epi16() { + const unsafe fn test_mm256_mask_shufflehi_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_mask_shufflehi_epi16::<0b00_01_01_11>(a, 0, a); assert_eq_m256i(r, a); @@ -19405,7 +20317,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_shufflehi_epi16() { + const unsafe fn test_mm256_maskz_shufflehi_epi16() { let a = _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm256_maskz_shufflehi_epi16::<0b00_01_01_11>(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -19415,7 +20327,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_shufflehi_epi16() { + const unsafe fn test_mm_mask_shufflehi_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm_mask_shufflehi_epi16::<0b00_01_01_11>(a, 0, a); assert_eq_m128i(r, a); @@ -19425,7 +20337,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_shufflehi_epi16() { + const unsafe fn test_mm_maskz_shufflehi_epi16() { let a = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); let r = _mm_maskz_shufflehi_epi16::<0b00_01_01_11>(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -19556,7 +20468,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_test_epi16_mask() { + const unsafe fn test_mm512_test_epi16_mask() { let a = _mm512_set1_epi16(1 << 0); let b = _mm512_set1_epi16(1 << 0 | 1 << 1); let r = _mm512_test_epi16_mask(a, b); @@ -19565,7 +20477,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_test_epi16_mask() { + const unsafe fn test_mm512_mask_test_epi16_mask() { let a = _mm512_set1_epi16(1 << 0); let b = _mm512_set1_epi16(1 << 0 | 1 << 1); let r = _mm512_mask_test_epi16_mask(0, a, b); @@ -19576,7 +20488,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_test_epi16_mask() { + const unsafe fn test_mm256_test_epi16_mask() { let a = _mm256_set1_epi16(1 << 0); let b = _mm256_set1_epi16(1 << 0 | 1 << 1); let r = _mm256_test_epi16_mask(a, b); @@ -19585,7 +20497,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_test_epi16_mask() { + const unsafe fn test_mm256_mask_test_epi16_mask() { let a = _mm256_set1_epi16(1 << 0); let b = _mm256_set1_epi16(1 << 0 | 1 << 1); let r = _mm256_mask_test_epi16_mask(0, a, b); @@ -19596,7 +20508,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_test_epi16_mask() { + const unsafe fn test_mm_test_epi16_mask() { let a = _mm_set1_epi16(1 << 0); let b = _mm_set1_epi16(1 << 0 | 1 << 1); let r = _mm_test_epi16_mask(a, b); @@ -19605,7 +20517,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_test_epi16_mask() { + const unsafe fn test_mm_mask_test_epi16_mask() { let a = _mm_set1_epi16(1 << 0); let b = _mm_set1_epi16(1 << 0 | 1 << 1); let r = _mm_mask_test_epi16_mask(0, a, b); @@ -19616,7 +20528,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_test_epi8_mask() { + const unsafe fn test_mm512_test_epi8_mask() { let a = _mm512_set1_epi8(1 << 0); let b = _mm512_set1_epi8(1 << 0 | 1 << 1); let r = _mm512_test_epi8_mask(a, b); @@ -19626,7 +20538,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_test_epi8_mask() { + const unsafe fn test_mm512_mask_test_epi8_mask() { let a = _mm512_set1_epi8(1 << 0); let b = _mm512_set1_epi8(1 << 0 | 1 << 1); let r = _mm512_mask_test_epi8_mask(0, a, b); @@ -19642,7 +20554,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_test_epi8_mask() { + const unsafe fn test_mm256_test_epi8_mask() { let a = _mm256_set1_epi8(1 << 0); let b = _mm256_set1_epi8(1 << 0 | 1 << 1); let r = _mm256_test_epi8_mask(a, b); @@ -19651,7 +20563,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_test_epi8_mask() { + const unsafe fn test_mm256_mask_test_epi8_mask() { let a = _mm256_set1_epi8(1 << 0); let b = _mm256_set1_epi8(1 << 0 | 1 << 1); let r = _mm256_mask_test_epi8_mask(0, a, b); @@ -19662,7 +20574,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_test_epi8_mask() { + const unsafe fn test_mm_test_epi8_mask() { let a = _mm_set1_epi8(1 << 0); let b = _mm_set1_epi8(1 << 0 | 1 << 1); let r = _mm_test_epi8_mask(a, b); @@ -19671,7 +20583,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_test_epi8_mask() { + const unsafe fn test_mm_mask_test_epi8_mask() { let a = _mm_set1_epi8(1 << 0); let b = _mm_set1_epi8(1 << 0 | 1 << 1); let r = _mm_mask_test_epi8_mask(0, a, b); @@ -19682,7 +20594,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_testn_epi16_mask() { + const unsafe fn test_mm512_testn_epi16_mask() { let a = _mm512_set1_epi16(1 << 0); let b = _mm512_set1_epi16(1 << 0 | 1 << 1); let r = _mm512_testn_epi16_mask(a, b); @@ -19691,7 +20603,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_testn_epi16_mask() { + const unsafe fn test_mm512_mask_testn_epi16_mask() { let a = _mm512_set1_epi16(1 << 0); let b = _mm512_set1_epi16(1 << 0 | 1 << 1); let r = _mm512_mask_testn_epi16_mask(0, a, b); @@ -19702,7 +20614,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_testn_epi16_mask() { + const unsafe fn test_mm256_testn_epi16_mask() { let a = _mm256_set1_epi16(1 << 0); let b = _mm256_set1_epi16(1 << 0 | 1 << 1); let r = _mm256_testn_epi16_mask(a, b); @@ -19711,7 +20623,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_testn_epi16_mask() { + const unsafe fn test_mm256_mask_testn_epi16_mask() { let a = _mm256_set1_epi16(1 << 0); let b = _mm256_set1_epi16(1 << 0 | 1 << 1); let r = _mm256_mask_testn_epi16_mask(0, a, b); @@ -19722,7 +20634,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_testn_epi16_mask() { + const unsafe fn test_mm_testn_epi16_mask() { let a = _mm_set1_epi16(1 << 0); let b = _mm_set1_epi16(1 << 0 | 1 << 1); let r = _mm_testn_epi16_mask(a, b); @@ -19731,7 +20643,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_testn_epi16_mask() { + const unsafe fn test_mm_mask_testn_epi16_mask() { let a = _mm_set1_epi16(1 << 0); let b = _mm_set1_epi16(1 << 0 | 1 << 1); let r = _mm_mask_testn_epi16_mask(0, a, b); @@ -19742,7 +20654,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_testn_epi8_mask() { + const unsafe fn test_mm512_testn_epi8_mask() { let a = _mm512_set1_epi8(1 << 0); let b = _mm512_set1_epi8(1 << 0 | 1 << 1); let r = _mm512_testn_epi8_mask(a, b); @@ -19752,7 +20664,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_testn_epi8_mask() { + const unsafe fn test_mm512_mask_testn_epi8_mask() { let a = _mm512_set1_epi8(1 << 0); let b = _mm512_set1_epi8(1 << 0 | 1 << 1); let r = _mm512_mask_testn_epi8_mask(0, a, b); @@ -19768,7 +20680,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_testn_epi8_mask() { + const unsafe fn test_mm256_testn_epi8_mask() { let a = _mm256_set1_epi8(1 << 0); let b = _mm256_set1_epi8(1 << 0 | 1 << 1); let r = _mm256_testn_epi8_mask(a, b); @@ -19777,7 +20689,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_testn_epi8_mask() { + const unsafe fn test_mm256_mask_testn_epi8_mask() { let a = _mm256_set1_epi8(1 << 0); let b = _mm256_set1_epi8(1 << 0 | 1 << 1); let r = _mm256_mask_testn_epi8_mask(0, a, b); @@ -19788,7 +20700,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_testn_epi8_mask() { + const unsafe fn test_mm_testn_epi8_mask() { let a = _mm_set1_epi8(1 << 0); let b = _mm_set1_epi8(1 << 0 | 1 << 1); let r = _mm_testn_epi8_mask(a, b); @@ -19797,7 +20709,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_testn_epi8_mask() { + const unsafe fn test_mm_mask_testn_epi8_mask() { let a = _mm_set1_epi8(1 << 0); let b = _mm_set1_epi8(1 << 0 | 1 << 1); let r = _mm_mask_testn_epi8_mask(0, a, b); @@ -19808,7 +20720,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_store_mask64() { + const unsafe fn test_store_mask64() { let a: __mmask64 = 0b11111111_00000000_11111111_00000000_11111111_00000000_11111111_00000000; let mut r = 0; @@ -19817,7 +20729,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_store_mask32() { + const unsafe fn test_store_mask32() { let a: __mmask32 = 0b11111111_00000000_11111111_00000000; let mut r = 0; _store_mask32(&mut r, a); @@ -19825,7 +20737,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_load_mask64() { + const unsafe fn test_load_mask64() { let p: __mmask64 = 0b11111111_00000000_11111111_00000000_11111111_00000000_11111111_00000000; let r = _load_mask64(&p); @@ -19835,7 +20747,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_load_mask32() { + const unsafe fn test_load_mask32() { let p: __mmask32 = 0b11111111_00000000_11111111_00000000; let r = _load_mask32(&p); let e: __mmask32 = 0b11111111_00000000_11111111_00000000; @@ -19948,7 +20860,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_movepi16_mask() { + const unsafe fn test_mm512_movepi16_mask() { let a = _mm512_set1_epi16(1 << 15); let r = _mm512_movepi16_mask(a); let e: __mmask32 = 0b11111111_11111111_11111111_11111111; @@ -19956,7 +20868,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_movepi16_mask() { + const unsafe fn test_mm256_movepi16_mask() { let a = _mm256_set1_epi16(1 << 15); let r = _mm256_movepi16_mask(a); let e: __mmask16 = 0b11111111_11111111; @@ -19964,7 +20876,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_movepi16_mask() { + const unsafe fn test_mm_movepi16_mask() { let a = _mm_set1_epi16(1 << 15); let r = _mm_movepi16_mask(a); let e: __mmask8 = 0b11111111; @@ -19972,7 +20884,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_movepi8_mask() { + const unsafe fn test_mm512_movepi8_mask() { let a = _mm512_set1_epi8(1 << 7); let r = _mm512_movepi8_mask(a); let e: __mmask64 = @@ -19981,7 +20893,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_movepi8_mask() { + const unsafe fn test_mm256_movepi8_mask() { let a = _mm256_set1_epi8(1 << 7); let r = _mm256_movepi8_mask(a); let e: __mmask32 = 0b11111111_11111111_11111111_11111111; @@ -19989,7 +20901,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_movepi8_mask() { + const unsafe fn test_mm_movepi8_mask() { let a = _mm_set1_epi8(1 << 7); let r = _mm_movepi8_mask(a); let e: __mmask16 = 0b11111111_11111111; @@ -19997,7 +20909,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_movm_epi16() { + const unsafe fn test_mm512_movm_epi16() { let a: __mmask32 = 0b11111111_11111111_11111111_11111111; let r = _mm512_movm_epi16(a); let e = _mm512_set1_epi16( @@ -20022,7 +20934,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_movm_epi16() { + const unsafe fn test_mm256_movm_epi16() { let a: __mmask16 = 0b11111111_11111111; let r = _mm256_movm_epi16(a); let e = _mm256_set1_epi16( @@ -20047,7 +20959,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_movm_epi16() { + const unsafe fn test_mm_movm_epi16() { let a: __mmask8 = 0b11111111; let r = _mm_movm_epi16(a); let e = _mm_set1_epi16( @@ -20072,7 +20984,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_movm_epi8() { + const unsafe fn test_mm512_movm_epi8() { let a: __mmask64 = 0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111; let r = _mm512_movm_epi8(a); @@ -20082,7 +20994,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_movm_epi8() { + const unsafe fn test_mm256_movm_epi8() { let a: __mmask32 = 0b11111111_11111111_11111111_11111111; let r = _mm256_movm_epi8(a); let e = @@ -20091,7 +21003,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_movm_epi8() { + const unsafe fn test_mm_movm_epi8() { let a: __mmask16 = 0b11111111_11111111; let r = _mm_movm_epi8(a); let e = @@ -20100,7 +21012,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_cvtmask32_u32() { + const unsafe fn test_cvtmask32_u32() { let a: __mmask32 = 0b11001100_00110011_01100110_10011001; let r = _cvtmask32_u32(a); let e: u32 = 0b11001100_00110011_01100110_10011001; @@ -20108,7 +21020,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_cvtu32_mask32() { + const unsafe fn test_cvtu32_mask32() { let a: u32 = 0b11001100_00110011_01100110_10011001; let r = _cvtu32_mask32(a); let e: __mmask32 = 0b11001100_00110011_01100110_10011001; @@ -20116,7 +21028,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kadd_mask32() { + const unsafe fn test_kadd_mask32() { let a: __mmask32 = 11; let b: __mmask32 = 22; let r = _kadd_mask32(a, b); @@ -20125,7 +21037,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kadd_mask64() { + const unsafe fn test_kadd_mask64() { let a: __mmask64 = 11; let b: __mmask64 = 22; let r = _kadd_mask64(a, b); @@ -20134,7 +21046,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kand_mask32() { + const unsafe fn test_kand_mask32() { let a: __mmask32 = 0b11001100_00110011_11001100_00110011; let b: __mmask32 = 0b11001100_00110011_11001100_00110011; let r = _kand_mask32(a, b); @@ -20143,7 +21055,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kand_mask64() { + const unsafe fn test_kand_mask64() { let a: __mmask64 = 0b11001100_00110011_11001100_00110011_11001100_00110011_11001100_00110011; let b: __mmask64 = @@ -20155,7 +21067,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_knot_mask32() { + const unsafe fn test_knot_mask32() { let a: __mmask32 = 0b11001100_00110011_11001100_00110011; let r = _knot_mask32(a); let e: __mmask32 = 0b00110011_11001100_00110011_11001100; @@ -20163,7 +21075,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_knot_mask64() { + const unsafe fn test_knot_mask64() { let a: __mmask64 = 0b11001100_00110011_11001100_00110011_11001100_00110011_11001100_00110011; let r = _knot_mask64(a); @@ -20173,7 +21085,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kandn_mask32() { + const unsafe fn test_kandn_mask32() { let a: __mmask32 = 0b11001100_00110011_11001100_00110011; let b: __mmask32 = 0b11001100_00110011_11001100_00110011; let r = _kandn_mask32(a, b); @@ -20182,7 +21094,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kandn_mask64() { + const unsafe fn test_kandn_mask64() { let a: __mmask64 = 0b11001100_00110011_11001100_00110011_11001100_00110011_11001100_00110011; let b: __mmask64 = @@ -20194,7 +21106,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kor_mask32() { + const unsafe fn test_kor_mask32() { let a: __mmask32 = 0b00110011_11001100_00110011_11001100; let b: __mmask32 = 0b11001100_00110011_11001100_00110011; let r = _kor_mask32(a, b); @@ -20203,7 +21115,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kor_mask64() { + const unsafe fn test_kor_mask64() { let a: __mmask64 = 0b00110011_11001100_00110011_11001100_00110011_11001100_00110011_11001100; let b: __mmask64 = @@ -20215,7 +21127,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kxor_mask32() { + const unsafe fn test_kxor_mask32() { let a: __mmask32 = 0b00110011_11001100_00110011_11001100; let b: __mmask32 = 0b11001100_00110011_11001100_00110011; let r = _kxor_mask32(a, b); @@ -20224,7 +21136,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kxor_mask64() { + const unsafe fn test_kxor_mask64() { let a: __mmask64 = 0b00110011_11001100_00110011_11001100_00110011_11001100_00110011_11001100; let b: __mmask64 = @@ -20236,7 +21148,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kxnor_mask32() { + const unsafe fn test_kxnor_mask32() { let a: __mmask32 = 0b00110011_11001100_00110011_11001100; let b: __mmask32 = 0b11001100_00110011_11001100_00110011; let r = _kxnor_mask32(a, b); @@ -20245,7 +21157,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kxnor_mask64() { + const unsafe fn test_kxnor_mask64() { let a: __mmask64 = 0b00110011_11001100_00110011_11001100_00110011_11001100_00110011_11001100; let b: __mmask64 = @@ -20257,7 +21169,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kortest_mask32_u8() { + const unsafe fn test_kortest_mask32_u8() { let a: __mmask32 = 0b0110100101101001_0110100101101001; let b: __mmask32 = 0b1011011010110110_1011011010110110; let mut all_ones: u8 = 0; @@ -20267,7 +21179,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kortest_mask64_u8() { + const unsafe fn test_kortest_mask64_u8() { let a: __mmask64 = 0b0110100101101001_0110100101101001; let b: __mmask64 = 0b1011011010110110_1011011010110110; let mut all_ones: u8 = 0; @@ -20277,7 +21189,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kortestc_mask32_u8() { + const unsafe fn test_kortestc_mask32_u8() { let a: __mmask32 = 0b0110100101101001_0110100101101001; let b: __mmask32 = 0b1011011010110110_1011011010110110; let r = _kortestc_mask32_u8(a, b); @@ -20285,7 +21197,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kortestc_mask64_u8() { + const unsafe fn test_kortestc_mask64_u8() { let a: __mmask64 = 0b0110100101101001_0110100101101001; let b: __mmask64 = 0b1011011010110110_1011011010110110; let r = _kortestc_mask64_u8(a, b); @@ -20293,7 +21205,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kortestz_mask32_u8() { + const unsafe fn test_kortestz_mask32_u8() { let a: __mmask32 = 0b0110100101101001_0110100101101001; let b: __mmask32 = 0b1011011010110110_1011011010110110; let r = _kortestz_mask32_u8(a, b); @@ -20301,7 +21213,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kortestz_mask64_u8() { + const unsafe fn test_kortestz_mask64_u8() { let a: __mmask64 = 0b0110100101101001_0110100101101001; let b: __mmask64 = 0b1011011010110110_1011011010110110; let r = _kortestz_mask64_u8(a, b); @@ -20309,7 +21221,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kshiftli_mask32() { + const unsafe fn test_kshiftli_mask32() { let a: __mmask32 = 0b0110100101101001_0110100101101001; let r = _kshiftli_mask32::<3>(a); let e: __mmask32 = 0b0100101101001011_0100101101001000; @@ -20329,7 +21241,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kshiftli_mask64() { + const unsafe fn test_kshiftli_mask64() { let a: __mmask64 = 0b0110100101101001_0110100101101001; let r = _kshiftli_mask64::<3>(a); let e: __mmask64 = 0b0110100101101001011_0100101101001000; @@ -20349,7 +21261,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kshiftri_mask32() { + const unsafe fn test_kshiftri_mask32() { let a: __mmask32 = 0b1010100101101001_0110100101101001; let r = _kshiftri_mask32::<3>(a); let e: __mmask32 = 0b0001010100101101_0010110100101101; @@ -20369,7 +21281,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_kshiftri_mask64() { + const unsafe fn test_kshiftri_mask64() { let a: __mmask64 = 0b1010100101101001011_0100101101001000; let r = _kshiftri_mask64::<3>(a); let e: __mmask64 = 0b1010100101101001_0110100101101001; @@ -20393,7 +21305,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_ktest_mask32_u8() { + const unsafe fn test_ktest_mask32_u8() { let a: __mmask32 = 0b0110100100111100_0110100100111100; let b: __mmask32 = 0b1001011011000011_1001011011000011; let mut and_not: u8 = 0; @@ -20403,7 +21315,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_ktestc_mask32_u8() { + const unsafe fn test_ktestc_mask32_u8() { let a: __mmask32 = 0b0110100100111100_0110100100111100; let b: __mmask32 = 0b1001011011000011_1001011011000011; let r = _ktestc_mask32_u8(a, b); @@ -20411,7 +21323,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_ktestz_mask32_u8() { + const unsafe fn test_ktestz_mask32_u8() { let a: __mmask32 = 0b0110100100111100_0110100100111100; let b: __mmask32 = 0b1001011011000011_1001011011000011; let r = _ktestz_mask32_u8(a, b); @@ -20419,7 +21331,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_ktest_mask64_u8() { + const unsafe fn test_ktest_mask64_u8() { let a: __mmask64 = 0b0110100100111100_0110100100111100; let b: __mmask64 = 0b1001011011000011_1001011011000011; let mut and_not: u8 = 0; @@ -20429,7 +21341,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_ktestc_mask64_u8() { + const unsafe fn test_ktestc_mask64_u8() { let a: __mmask64 = 0b0110100100111100_0110100100111100; let b: __mmask64 = 0b1001011011000011_1001011011000011; let r = _ktestc_mask64_u8(a, b); @@ -20437,7 +21349,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_ktestz_mask64_u8() { + const unsafe fn test_ktestz_mask64_u8() { let a: __mmask64 = 0b0110100100111100_0110100100111100; let b: __mmask64 = 0b1001011011000011_1001011011000011; let r = _ktestz_mask64_u8(a, b); @@ -20445,7 +21357,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_kunpackw() { + const unsafe fn test_mm512_kunpackw() { let a: u32 = 0x00110011; let b: u32 = 0x00001011; let r = _mm512_kunpackw(a, b); @@ -20454,7 +21366,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_kunpackd() { + const unsafe fn test_mm512_kunpackd() { let a: u64 = 0x11001100_00110011; let b: u64 = 0x00101110_00001011; let r = _mm512_kunpackd(a, b); @@ -20463,7 +21375,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cvtepi16_epi8() { + const unsafe fn test_mm512_cvtepi16_epi8() { let a = _mm512_set1_epi16(2); let r = _mm512_cvtepi16_epi8(a); let e = _mm256_set1_epi8(2); @@ -20471,7 +21383,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cvtepi16_epi8() { + const unsafe fn test_mm512_mask_cvtepi16_epi8() { let src = _mm256_set1_epi8(1); let a = _mm512_set1_epi16(2); let r = _mm512_mask_cvtepi16_epi8(src, 0, a); @@ -20482,7 +21394,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_cvtepi16_epi8() { + const unsafe fn test_mm512_maskz_cvtepi16_epi8() { let a = _mm512_set1_epi16(2); let r = _mm512_maskz_cvtepi16_epi8(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -20492,7 +21404,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_cvtepi16_epi8() { + const unsafe fn test_mm256_cvtepi16_epi8() { let a = _mm256_set1_epi16(2); let r = _mm256_cvtepi16_epi8(a); let e = _mm_set1_epi8(2); @@ -20500,7 +21412,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cvtepi16_epi8() { + const unsafe fn test_mm256_mask_cvtepi16_epi8() { let src = _mm_set1_epi8(1); let a = _mm256_set1_epi16(2); let r = _mm256_mask_cvtepi16_epi8(src, 0, a); @@ -20511,7 +21423,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi16_epi8() { + const unsafe fn test_mm256_maskz_cvtepi16_epi8() { let a = _mm256_set1_epi16(2); let r = _mm256_maskz_cvtepi16_epi8(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -20521,7 +21433,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_cvtepi16_epi8() { + const unsafe fn test_mm_cvtepi16_epi8() { let a = _mm_set1_epi16(2); let r = _mm_cvtepi16_epi8(a); let e = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2); @@ -20529,7 +21441,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cvtepi16_epi8() { + const unsafe fn test_mm_mask_cvtepi16_epi8() { let src = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1); let a = _mm_set1_epi16(2); let r = _mm_mask_cvtepi16_epi8(src, 0, a); @@ -20540,7 +21452,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_cvtepi16_epi8() { + const unsafe fn test_mm_maskz_cvtepi16_epi8() { let a = _mm_set1_epi16(2); let r = _mm_maskz_cvtepi16_epi8(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -20727,7 +21639,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cvtepi8_epi16() { + const unsafe fn test_mm512_cvtepi8_epi16() { let a = _mm256_set1_epi8(2); let r = _mm512_cvtepi8_epi16(a); let e = _mm512_set1_epi16(2); @@ -20735,7 +21647,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cvtepi8_epi16() { + const unsafe fn test_mm512_mask_cvtepi8_epi16() { let src = _mm512_set1_epi16(1); let a = _mm256_set1_epi8(2); let r = _mm512_mask_cvtepi8_epi16(src, 0, a); @@ -20746,7 +21658,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_cvtepi8_epi16() { + const unsafe fn test_mm512_maskz_cvtepi8_epi16() { let a = _mm256_set1_epi8(2); let r = _mm512_maskz_cvtepi8_epi16(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -20756,7 +21668,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cvtepi8_epi16() { + const unsafe fn test_mm256_mask_cvtepi8_epi16() { let src = _mm256_set1_epi16(1); let a = _mm_set1_epi8(2); let r = _mm256_mask_cvtepi8_epi16(src, 0, a); @@ -20767,7 +21679,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_cvtepi8_epi16() { + const unsafe fn test_mm256_maskz_cvtepi8_epi16() { let a = _mm_set1_epi8(2); let r = _mm256_maskz_cvtepi8_epi16(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -20777,7 +21689,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cvtepi8_epi16() { + const unsafe fn test_mm_mask_cvtepi8_epi16() { let src = _mm_set1_epi16(1); let a = _mm_set1_epi8(2); let r = _mm_mask_cvtepi8_epi16(src, 0, a); @@ -20788,7 +21700,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_cvtepi8_epi16() { + const unsafe fn test_mm_maskz_cvtepi8_epi16() { let a = _mm_set1_epi8(2); let r = _mm_maskz_cvtepi8_epi16(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -20798,7 +21710,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_cvtepu8_epi16() { + const unsafe fn test_mm512_cvtepu8_epi16() { let a = _mm256_set1_epi8(2); let r = _mm512_cvtepu8_epi16(a); let e = _mm512_set1_epi16(2); @@ -20806,7 +21718,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cvtepu8_epi16() { + const unsafe fn test_mm512_mask_cvtepu8_epi16() { let src = _mm512_set1_epi16(1); let a = _mm256_set1_epi8(2); let r = _mm512_mask_cvtepu8_epi16(src, 0, a); @@ -20817,7 +21729,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_cvtepu8_epi16() { + const unsafe fn test_mm512_maskz_cvtepu8_epi16() { let a = _mm256_set1_epi8(2); let r = _mm512_maskz_cvtepu8_epi16(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -20827,7 +21739,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cvtepu8_epi16() { + const unsafe fn test_mm256_mask_cvtepu8_epi16() { let src = _mm256_set1_epi16(1); let a = _mm_set1_epi8(2); let r = _mm256_mask_cvtepu8_epi16(src, 0, a); @@ -20838,7 +21750,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_cvtepu8_epi16() { + const unsafe fn test_mm256_maskz_cvtepu8_epi16() { let a = _mm_set1_epi8(2); let r = _mm256_maskz_cvtepu8_epi16(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -20848,7 +21760,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cvtepu8_epi16() { + const unsafe fn test_mm_mask_cvtepu8_epi16() { let src = _mm_set1_epi16(1); let a = _mm_set1_epi8(2); let r = _mm_mask_cvtepu8_epi16(src, 0, a); @@ -20859,7 +21771,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_cvtepu8_epi16() { + const unsafe fn test_mm_maskz_cvtepu8_epi16() { let a = _mm_set1_epi8(2); let r = _mm_maskz_cvtepu8_epi16(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -20869,7 +21781,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_bslli_epi128() { + const unsafe fn test_mm512_bslli_epi128() { #[rustfmt::skip] let a = _mm512_set_epi8( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, @@ -20889,7 +21801,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_bsrli_epi128() { + const unsafe fn test_mm512_bsrli_epi128() { #[rustfmt::skip] let a = _mm512_set_epi8( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, @@ -20909,7 +21821,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_alignr_epi8() { + const unsafe fn test_mm512_alignr_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, @@ -20930,7 +21842,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_alignr_epi8() { + const unsafe fn test_mm512_mask_alignr_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, @@ -20958,7 +21870,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_maskz_alignr_epi8() { + const unsafe fn test_mm512_maskz_alignr_epi8() { #[rustfmt::skip] let a = _mm512_set_epi8( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, @@ -20985,7 +21897,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_alignr_epi8() { + const unsafe fn test_mm256_mask_alignr_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, @@ -21004,7 +21916,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_alignr_epi8() { + const unsafe fn test_mm256_maskz_alignr_epi8() { #[rustfmt::skip] let a = _mm256_set_epi8( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, @@ -21023,7 +21935,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_alignr_epi8() { + const unsafe fn test_mm_mask_alignr_epi8() { let a = _mm_set_epi8(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0); let b = _mm_set1_epi8(1); let r = _mm_mask_alignr_epi8::<14>(a, 0, a, b); @@ -21034,7 +21946,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_maskz_alignr_epi8() { + const unsafe fn test_mm_maskz_alignr_epi8() { let a = _mm_set_epi8(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0); let b = _mm_set1_epi8(1); let r = _mm_maskz_alignr_epi8::<14>(0, a, b); diff --git a/library/stdarch/crates/core_arch/src/x86_64/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86_64/avx512bw.rs index 466c36ef31e5..a8e5183e0c2f 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/avx512bw.rs @@ -6,7 +6,8 @@ use crate::core_arch::x86::*; #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _cvtmask64_u64(a: __mmask64) -> u64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _cvtmask64_u64(a: __mmask64) -> u64 { a } @@ -16,19 +17,21 @@ pub fn _cvtmask64_u64(a: __mmask64) -> u64 { #[inline] #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _cvtu64_mask64(a: u64) -> __mmask64 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _cvtu64_mask64(a: u64) -> __mmask64 { a } #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::{x86::*, x86_64::*}; #[simd_test(enable = "avx512bw")] - unsafe fn test_cvtmask64_u64() { + const unsafe fn test_cvtmask64_u64() { let a: __mmask64 = 0b11001100_00110011_01100110_10011001; let r = _cvtmask64_u64(a); let e: u64 = 0b11001100_00110011_01100110_10011001; @@ -36,7 +39,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_cvtu64_mask64() { + const unsafe fn test_cvtu64_mask64() { let a: u64 = 0b11001100_00110011_01100110_10011001; let r = _cvtu64_mask64(a); let e: __mmask64 = 0b11001100_00110011_01100110_10011001; From 3516ef11e421af4bffef72b2d53ff6e530dccad1 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:23:20 +0530 Subject: [PATCH 0236/3801] Make `avx512cd` functions const --- .../crates/core_arch/src/x86/avx512cd.rs | 121 +++++++++++------- 1 file changed, 73 insertions(+), 48 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512cd.rs b/library/stdarch/crates/core_arch/src/x86/avx512cd.rs index 78735fcc90f5..b163698b56c4 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512cd.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512cd.rs @@ -11,7 +11,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "avx512cd")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] // should be vpbroadcastmw2d -pub fn _mm512_broadcastmw_epi32(k: __mmask16) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcastmw_epi32(k: __mmask16) -> __m512i { _mm512_set1_epi32(k as i32) } @@ -22,7 +23,8 @@ pub fn _mm512_broadcastmw_epi32(k: __mmask16) -> __m512i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] // should be vpbroadcastmw2d -pub fn _mm256_broadcastmw_epi32(k: __mmask16) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcastmw_epi32(k: __mmask16) -> __m256i { _mm256_set1_epi32(k as i32) } @@ -33,7 +35,8 @@ pub fn _mm256_broadcastmw_epi32(k: __mmask16) -> __m256i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] // should be vpbroadcastmw2d -pub fn _mm_broadcastmw_epi32(k: __mmask16) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcastmw_epi32(k: __mmask16) -> __m128i { _mm_set1_epi32(k as i32) } @@ -44,7 +47,8 @@ pub fn _mm_broadcastmw_epi32(k: __mmask16) -> __m128i { #[target_feature(enable = "avx512cd")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] // should be vpbroadcastmb2q -pub fn _mm512_broadcastmb_epi64(k: __mmask8) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcastmb_epi64(k: __mmask8) -> __m512i { _mm512_set1_epi64(k as i64) } @@ -55,7 +59,8 @@ pub fn _mm512_broadcastmb_epi64(k: __mmask8) -> __m512i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] // should be vpbroadcastmb2q -pub fn _mm256_broadcastmb_epi64(k: __mmask8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcastmb_epi64(k: __mmask8) -> __m256i { _mm256_set1_epi64x(k as i64) } @@ -66,7 +71,8 @@ pub fn _mm256_broadcastmb_epi64(k: __mmask8) -> __m256i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpbroadcast))] // should be vpbroadcastmb2q -pub fn _mm_broadcastmb_epi64(k: __mmask8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcastmb_epi64(k: __mmask8) -> __m128i { _mm_set1_epi64x(k as i64) } @@ -311,7 +317,8 @@ pub fn _mm_maskz_conflict_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512cd")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntd))] -pub fn _mm512_lzcnt_epi32(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_lzcnt_epi32(a: __m512i) -> __m512i { unsafe { transmute(simd_ctlz(a.as_i32x16())) } } @@ -322,7 +329,8 @@ pub fn _mm512_lzcnt_epi32(a: __m512i) -> __m512i { #[target_feature(enable = "avx512cd")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntd))] -pub fn _mm512_mask_lzcnt_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_lzcnt_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { unsafe { let zerocount = _mm512_lzcnt_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, zerocount, src.as_i32x16())) @@ -336,7 +344,8 @@ pub fn _mm512_mask_lzcnt_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512 #[target_feature(enable = "avx512cd")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntd))] -pub fn _mm512_maskz_lzcnt_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_lzcnt_epi32(k: __mmask16, a: __m512i) -> __m512i { unsafe { let zerocount = _mm512_lzcnt_epi32(a).as_i32x16(); transmute(simd_select_bitmask(k, zerocount, i32x16::ZERO)) @@ -350,7 +359,8 @@ pub fn _mm512_maskz_lzcnt_epi32(k: __mmask16, a: __m512i) -> __m512i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntd))] -pub fn _mm256_lzcnt_epi32(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_lzcnt_epi32(a: __m256i) -> __m256i { unsafe { transmute(simd_ctlz(a.as_i32x8())) } } @@ -361,7 +371,8 @@ pub fn _mm256_lzcnt_epi32(a: __m256i) -> __m256i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntd))] -pub fn _mm256_mask_lzcnt_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_lzcnt_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { unsafe { let zerocount = _mm256_lzcnt_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, zerocount, src.as_i32x8())) @@ -375,7 +386,8 @@ pub fn _mm256_mask_lzcnt_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntd))] -pub fn _mm256_maskz_lzcnt_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_lzcnt_epi32(k: __mmask8, a: __m256i) -> __m256i { unsafe { let zerocount = _mm256_lzcnt_epi32(a).as_i32x8(); transmute(simd_select_bitmask(k, zerocount, i32x8::ZERO)) @@ -389,7 +401,8 @@ pub fn _mm256_maskz_lzcnt_epi32(k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntd))] -pub fn _mm_lzcnt_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_lzcnt_epi32(a: __m128i) -> __m128i { unsafe { transmute(simd_ctlz(a.as_i32x4())) } } @@ -400,7 +413,8 @@ pub fn _mm_lzcnt_epi32(a: __m128i) -> __m128i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntd))] -pub fn _mm_mask_lzcnt_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_lzcnt_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let zerocount = _mm_lzcnt_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, zerocount, src.as_i32x4())) @@ -414,7 +428,8 @@ pub fn _mm_mask_lzcnt_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntd))] -pub fn _mm_maskz_lzcnt_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_lzcnt_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { let zerocount = _mm_lzcnt_epi32(a).as_i32x4(); transmute(simd_select_bitmask(k, zerocount, i32x4::ZERO)) @@ -428,7 +443,8 @@ pub fn _mm_maskz_lzcnt_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512cd")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntq))] -pub fn _mm512_lzcnt_epi64(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_lzcnt_epi64(a: __m512i) -> __m512i { unsafe { transmute(simd_ctlz(a.as_i64x8())) } } @@ -439,7 +455,8 @@ pub fn _mm512_lzcnt_epi64(a: __m512i) -> __m512i { #[target_feature(enable = "avx512cd")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntq))] -pub fn _mm512_mask_lzcnt_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_lzcnt_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { unsafe { let zerocount = _mm512_lzcnt_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, zerocount, src.as_i64x8())) @@ -453,7 +470,8 @@ pub fn _mm512_mask_lzcnt_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i #[target_feature(enable = "avx512cd")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntq))] -pub fn _mm512_maskz_lzcnt_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_lzcnt_epi64(k: __mmask8, a: __m512i) -> __m512i { unsafe { let zerocount = _mm512_lzcnt_epi64(a).as_i64x8(); transmute(simd_select_bitmask(k, zerocount, i64x8::ZERO)) @@ -467,7 +485,8 @@ pub fn _mm512_maskz_lzcnt_epi64(k: __mmask8, a: __m512i) -> __m512i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntq))] -pub fn _mm256_lzcnt_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_lzcnt_epi64(a: __m256i) -> __m256i { unsafe { transmute(simd_ctlz(a.as_i64x4())) } } @@ -478,7 +497,8 @@ pub fn _mm256_lzcnt_epi64(a: __m256i) -> __m256i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntq))] -pub fn _mm256_mask_lzcnt_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_lzcnt_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { unsafe { let zerocount = _mm256_lzcnt_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, zerocount, src.as_i64x4())) @@ -492,7 +512,8 @@ pub fn _mm256_mask_lzcnt_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntq))] -pub fn _mm256_maskz_lzcnt_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_lzcnt_epi64(k: __mmask8, a: __m256i) -> __m256i { unsafe { let zerocount = _mm256_lzcnt_epi64(a).as_i64x4(); transmute(simd_select_bitmask(k, zerocount, i64x4::ZERO)) @@ -506,7 +527,8 @@ pub fn _mm256_maskz_lzcnt_epi64(k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntq))] -pub fn _mm_lzcnt_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_lzcnt_epi64(a: __m128i) -> __m128i { unsafe { transmute(simd_ctlz(a.as_i64x2())) } } @@ -517,7 +539,8 @@ pub fn _mm_lzcnt_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntq))] -pub fn _mm_mask_lzcnt_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_lzcnt_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let zerocount = _mm_lzcnt_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, zerocount, src.as_i64x2())) @@ -531,7 +554,8 @@ pub fn _mm_mask_lzcnt_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512cd,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vplzcntq))] -pub fn _mm_maskz_lzcnt_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_lzcnt_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { let zerocount = _mm_lzcnt_epi64(a).as_i64x2(); transmute(simd_select_bitmask(k, zerocount, i64x2::ZERO)) @@ -557,12 +581,13 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use crate::core_arch::x86::*; use stdarch_test::simd_test; #[simd_test(enable = "avx512cd")] - unsafe fn test_mm512_broadcastmw_epi32() { + const unsafe fn test_mm512_broadcastmw_epi32() { let a: __mmask16 = 2; let r = _mm512_broadcastmw_epi32(a); let e = _mm512_set1_epi32(2); @@ -570,7 +595,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm256_broadcastmw_epi32() { + const unsafe fn test_mm256_broadcastmw_epi32() { let a: __mmask16 = 2; let r = _mm256_broadcastmw_epi32(a); let e = _mm256_set1_epi32(2); @@ -578,7 +603,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm_broadcastmw_epi32() { + const unsafe fn test_mm_broadcastmw_epi32() { let a: __mmask16 = 2; let r = _mm_broadcastmw_epi32(a); let e = _mm_set1_epi32(2); @@ -586,7 +611,7 @@ mod tests { } #[simd_test(enable = "avx512cd")] - unsafe fn test_mm512_broadcastmb_epi64() { + const unsafe fn test_mm512_broadcastmb_epi64() { let a: __mmask8 = 2; let r = _mm512_broadcastmb_epi64(a); let e = _mm512_set1_epi64(2); @@ -594,7 +619,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm256_broadcastmb_epi64() { + const unsafe fn test_mm256_broadcastmb_epi64() { let a: __mmask8 = 2; let r = _mm256_broadcastmb_epi64(a); let e = _mm256_set1_epi64x(2); @@ -602,7 +627,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm_broadcastmb_epi64() { + const unsafe fn test_mm_broadcastmb_epi64() { let a: __mmask8 = 2; let r = _mm_broadcastmb_epi64(a); let e = _mm_set1_epi64x(2); @@ -1063,7 +1088,7 @@ mod tests { } #[simd_test(enable = "avx512cd")] - unsafe fn test_mm512_lzcnt_epi32() { + const unsafe fn test_mm512_lzcnt_epi32() { let a = _mm512_set1_epi32(1); let r = _mm512_lzcnt_epi32(a); let e = _mm512_set1_epi32(31); @@ -1071,7 +1096,7 @@ mod tests { } #[simd_test(enable = "avx512cd")] - unsafe fn test_mm512_mask_lzcnt_epi32() { + const unsafe fn test_mm512_mask_lzcnt_epi32() { let a = _mm512_set1_epi32(1); let r = _mm512_mask_lzcnt_epi32(a, 0, a); assert_eq_m512i(r, a); @@ -1081,7 +1106,7 @@ mod tests { } #[simd_test(enable = "avx512cd")] - unsafe fn test_mm512_maskz_lzcnt_epi32() { + const unsafe fn test_mm512_maskz_lzcnt_epi32() { let a = _mm512_set1_epi32(2); let r = _mm512_maskz_lzcnt_epi32(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -1091,7 +1116,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm256_lzcnt_epi32() { + const unsafe fn test_mm256_lzcnt_epi32() { let a = _mm256_set1_epi32(1); let r = _mm256_lzcnt_epi32(a); let e = _mm256_set1_epi32(31); @@ -1099,7 +1124,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm256_mask_lzcnt_epi32() { + const unsafe fn test_mm256_mask_lzcnt_epi32() { let a = _mm256_set1_epi32(1); let r = _mm256_mask_lzcnt_epi32(a, 0, a); assert_eq_m256i(r, a); @@ -1109,7 +1134,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm256_maskz_lzcnt_epi32() { + const unsafe fn test_mm256_maskz_lzcnt_epi32() { let a = _mm256_set1_epi32(1); let r = _mm256_maskz_lzcnt_epi32(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -1119,7 +1144,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm_lzcnt_epi32() { + const unsafe fn test_mm_lzcnt_epi32() { let a = _mm_set1_epi32(1); let r = _mm_lzcnt_epi32(a); let e = _mm_set1_epi32(31); @@ -1127,7 +1152,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm_mask_lzcnt_epi32() { + const unsafe fn test_mm_mask_lzcnt_epi32() { let a = _mm_set1_epi32(1); let r = _mm_mask_lzcnt_epi32(a, 0, a); assert_eq_m128i(r, a); @@ -1137,7 +1162,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm_maskz_lzcnt_epi32() { + const unsafe fn test_mm_maskz_lzcnt_epi32() { let a = _mm_set1_epi32(1); let r = _mm_maskz_lzcnt_epi32(0, a); assert_eq_m128i(r, _mm_setzero_si128()); @@ -1147,7 +1172,7 @@ mod tests { } #[simd_test(enable = "avx512cd")] - unsafe fn test_mm512_lzcnt_epi64() { + const unsafe fn test_mm512_lzcnt_epi64() { let a = _mm512_set1_epi64(1); let r = _mm512_lzcnt_epi64(a); let e = _mm512_set1_epi64(63); @@ -1155,7 +1180,7 @@ mod tests { } #[simd_test(enable = "avx512cd")] - unsafe fn test_mm512_mask_lzcnt_epi64() { + const unsafe fn test_mm512_mask_lzcnt_epi64() { let a = _mm512_set1_epi64(1); let r = _mm512_mask_lzcnt_epi64(a, 0, a); assert_eq_m512i(r, a); @@ -1165,7 +1190,7 @@ mod tests { } #[simd_test(enable = "avx512cd")] - unsafe fn test_mm512_maskz_lzcnt_epi64() { + const unsafe fn test_mm512_maskz_lzcnt_epi64() { let a = _mm512_set1_epi64(2); let r = _mm512_maskz_lzcnt_epi64(0, a); assert_eq_m512i(r, _mm512_setzero_si512()); @@ -1175,7 +1200,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm256_lzcnt_epi64() { + const unsafe fn test_mm256_lzcnt_epi64() { let a = _mm256_set1_epi64x(1); let r = _mm256_lzcnt_epi64(a); let e = _mm256_set1_epi64x(63); @@ -1183,7 +1208,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm256_mask_lzcnt_epi64() { + const unsafe fn test_mm256_mask_lzcnt_epi64() { let a = _mm256_set1_epi64x(1); let r = _mm256_mask_lzcnt_epi64(a, 0, a); assert_eq_m256i(r, a); @@ -1193,7 +1218,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm256_maskz_lzcnt_epi64() { + const unsafe fn test_mm256_maskz_lzcnt_epi64() { let a = _mm256_set1_epi64x(1); let r = _mm256_maskz_lzcnt_epi64(0, a); assert_eq_m256i(r, _mm256_setzero_si256()); @@ -1203,7 +1228,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm_lzcnt_epi64() { + const unsafe fn test_mm_lzcnt_epi64() { let a = _mm_set1_epi64x(1); let r = _mm_lzcnt_epi64(a); let e = _mm_set1_epi64x(63); @@ -1211,7 +1236,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm_mask_lzcnt_epi64() { + const unsafe fn test_mm_mask_lzcnt_epi64() { let a = _mm_set1_epi64x(1); let r = _mm_mask_lzcnt_epi64(a, 0, a); assert_eq_m128i(r, a); @@ -1221,7 +1246,7 @@ mod tests { } #[simd_test(enable = "avx512cd,avx512vl")] - unsafe fn test_mm_maskz_lzcnt_epi64() { + const unsafe fn test_mm_maskz_lzcnt_epi64() { let a = _mm_set1_epi64x(1); let r = _mm_maskz_lzcnt_epi64(0, a); assert_eq_m128i(r, _mm_setzero_si128()); From e7f6d4928b270af4caac73a10293ee85cd7e70a5 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:24:24 +0530 Subject: [PATCH 0237/3801] Make `avx512dq` functions const --- .../crates/core_arch/src/x86/avx512dq.rs | 874 +++++++++++------- 1 file changed, 536 insertions(+), 338 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512dq.rs b/library/stdarch/crates/core_arch/src/x86/avx512dq.rs index a69168750283..4ab5880c55d0 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512dq.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512dq.rs @@ -15,7 +15,8 @@ use crate::{ #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_and_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_and_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let and = _mm_and_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, and, src.as_f64x2())) @@ -30,7 +31,8 @@ pub fn _mm_mask_and_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_and_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_and_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let and = _mm_and_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, and, f64x2::ZERO)) @@ -46,7 +48,8 @@ pub fn _mm_maskz_and_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_and_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_and_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let and = _mm256_and_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, and, src.as_f64x4())) @@ -61,7 +64,8 @@ pub fn _mm256_mask_and_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_and_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_and_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let and = _mm256_and_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, and, f64x4::ZERO)) @@ -76,7 +80,8 @@ pub fn _mm256_maskz_and_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandp))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_and_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_and_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { transmute(simd_and(transmute::<_, u64x8>(a), transmute::<_, u64x8>(b))) } } @@ -89,7 +94,8 @@ pub fn _mm512_and_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_and_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_and_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let and = _mm512_and_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, and, src.as_f64x8())) @@ -104,7 +110,8 @@ pub fn _mm512_mask_and_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_and_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_and_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let and = _mm512_and_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, and, f64x8::ZERO)) @@ -120,7 +127,8 @@ pub fn _mm512_maskz_and_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_and_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_and_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let and = _mm_and_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, and, src.as_f32x4())) @@ -135,7 +143,8 @@ pub fn _mm_mask_and_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_and_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_and_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let and = _mm_and_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, and, f32x4::ZERO)) @@ -151,7 +160,8 @@ pub fn _mm_maskz_and_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_and_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_and_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let and = _mm256_and_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, and, src.as_f32x8())) @@ -166,7 +176,8 @@ pub fn _mm256_mask_and_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_and_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_and_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let and = _mm256_and_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, and, f32x8::ZERO)) @@ -181,7 +192,8 @@ pub fn _mm256_maskz_and_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_and_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_and_ps(a: __m512, b: __m512) -> __m512 { unsafe { transmute(simd_and( transmute::<_, u32x16>(a), @@ -199,7 +211,8 @@ pub fn _mm512_and_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_and_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_and_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let and = _mm512_and_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, and, src.as_f32x16())) @@ -214,7 +227,8 @@ pub fn _mm512_mask_and_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __ #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_and_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_and_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let and = _mm512_and_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, and, f32x16::ZERO)) @@ -232,7 +246,8 @@ pub fn _mm512_maskz_and_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandnpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_andnot_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_andnot_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let andnot = _mm_andnot_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, andnot, src.as_f64x2())) @@ -248,7 +263,8 @@ pub fn _mm_mask_andnot_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandnpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_andnot_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_andnot_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let andnot = _mm_andnot_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, andnot, f64x2::ZERO)) @@ -264,7 +280,8 @@ pub fn _mm_maskz_andnot_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandnpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_andnot_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_andnot_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let andnot = _mm256_andnot_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, andnot, src.as_f64x4())) @@ -280,7 +297,8 @@ pub fn _mm256_mask_andnot_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandnpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_andnot_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_andnot_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let andnot = _mm256_andnot_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, andnot, f64x4::ZERO)) @@ -295,7 +313,8 @@ pub fn _mm256_maskz_andnot_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandnp))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_andnot_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_andnot_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { _mm512_and_pd(_mm512_xor_pd(a, transmute(_mm512_set1_epi64(-1))), b) } } @@ -308,7 +327,8 @@ pub fn _mm512_andnot_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandnpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_andnot_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_andnot_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let andnot = _mm512_andnot_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, andnot, src.as_f64x8())) @@ -324,7 +344,8 @@ pub fn _mm512_mask_andnot_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandnpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_andnot_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_andnot_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let andnot = _mm512_andnot_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, andnot, f64x8::ZERO)) @@ -340,7 +361,8 @@ pub fn _mm512_maskz_andnot_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandnps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_andnot_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_andnot_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let andnot = _mm_andnot_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, andnot, src.as_f32x4())) @@ -356,7 +378,8 @@ pub fn _mm_mask_andnot_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandnps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_andnot_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_andnot_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let andnot = _mm_andnot_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, andnot, f32x4::ZERO)) @@ -372,7 +395,8 @@ pub fn _mm_maskz_andnot_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandnps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_andnot_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_andnot_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let andnot = _mm256_andnot_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, andnot, src.as_f32x8())) @@ -388,7 +412,8 @@ pub fn _mm256_mask_andnot_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vandnps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_andnot_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_andnot_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let andnot = _mm256_andnot_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, andnot, f32x8::ZERO)) @@ -403,7 +428,8 @@ pub fn _mm256_maskz_andnot_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandnps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_andnot_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_andnot_ps(a: __m512, b: __m512) -> __m512 { unsafe { _mm512_and_ps(_mm512_xor_ps(a, transmute(_mm512_set1_epi32(-1))), b) } } @@ -416,7 +442,8 @@ pub fn _mm512_andnot_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandnps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_andnot_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_andnot_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let andnot = _mm512_andnot_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, andnot, src.as_f32x16())) @@ -432,7 +459,8 @@ pub fn _mm512_mask_andnot_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vandnps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_andnot_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_andnot_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let andnot = _mm512_andnot_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, andnot, f32x16::ZERO)) @@ -450,7 +478,8 @@ pub fn _mm512_maskz_andnot_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_or_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_or_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let or = _mm_or_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, or, src.as_f64x2())) @@ -465,7 +494,8 @@ pub fn _mm_mask_or_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m1 #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_or_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_or_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let or = _mm_or_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, or, f64x2::ZERO)) @@ -481,7 +511,8 @@ pub fn _mm_maskz_or_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_or_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_or_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let or = _mm256_or_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, or, src.as_f64x4())) @@ -496,7 +527,8 @@ pub fn _mm256_mask_or_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> _ #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_or_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_or_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let or = _mm256_or_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, or, f64x4::ZERO)) @@ -511,7 +543,8 @@ pub fn _mm256_maskz_or_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vorp))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_or_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_or_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { transmute(simd_or(transmute::<_, u64x8>(a), transmute::<_, u64x8>(b))) } } @@ -524,7 +557,8 @@ pub fn _mm512_or_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_or_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_or_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let or = _mm512_or_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, or, src.as_f64x8())) @@ -539,7 +573,8 @@ pub fn _mm512_mask_or_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> _ #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_or_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_or_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let or = _mm512_or_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, or, f64x8::ZERO)) @@ -555,7 +590,8 @@ pub fn _mm512_maskz_or_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_or_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_or_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let or = _mm_or_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, or, src.as_f32x4())) @@ -570,7 +606,8 @@ pub fn _mm_mask_or_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_or_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_or_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let or = _mm_or_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, or, f32x4::ZERO)) @@ -586,7 +623,8 @@ pub fn _mm_maskz_or_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_or_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_or_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let or = _mm256_or_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, or, src.as_f32x8())) @@ -601,7 +639,8 @@ pub fn _mm256_mask_or_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m2 #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_or_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_or_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let or = _mm256_or_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, or, f32x8::ZERO)) @@ -616,7 +655,8 @@ pub fn _mm256_maskz_or_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_or_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_or_ps(a: __m512, b: __m512) -> __m512 { unsafe { transmute(simd_or( transmute::<_, u32x16>(a), @@ -634,7 +674,8 @@ pub fn _mm512_or_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_or_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_or_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let or = _mm512_or_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, or, src.as_f32x16())) @@ -649,7 +690,8 @@ pub fn _mm512_mask_or_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_or_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_or_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let or = _mm512_or_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, or, f32x16::ZERO)) @@ -667,7 +709,8 @@ pub fn _mm512_maskz_or_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vxorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_xor_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_xor_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let xor = _mm_xor_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, xor, src.as_f64x2())) @@ -682,7 +725,8 @@ pub fn _mm_mask_xor_pd(src: __m128d, k: __mmask8, a: __m128d, b: __m128d) -> __m #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vxorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_xor_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_xor_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { unsafe { let xor = _mm_xor_pd(a, b).as_f64x2(); transmute(simd_select_bitmask(k, xor, f64x2::ZERO)) @@ -698,7 +742,8 @@ pub fn _mm_maskz_xor_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m128d { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vxorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_xor_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_xor_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let xor = _mm256_xor_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, xor, src.as_f64x4())) @@ -713,7 +758,8 @@ pub fn _mm256_mask_xor_pd(src: __m256d, k: __mmask8, a: __m256d, b: __m256d) -> #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vxorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_xor_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_xor_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { unsafe { let xor = _mm256_xor_pd(a, b).as_f64x4(); transmute(simd_select_bitmask(k, xor, f64x4::ZERO)) @@ -728,7 +774,8 @@ pub fn _mm256_maskz_xor_pd(k: __mmask8, a: __m256d, b: __m256d) -> __m256d { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vxorp))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_xor_pd(a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_xor_pd(a: __m512d, b: __m512d) -> __m512d { unsafe { transmute(simd_xor(transmute::<_, u64x8>(a), transmute::<_, u64x8>(b))) } } @@ -741,7 +788,8 @@ pub fn _mm512_xor_pd(a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vxorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_xor_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_xor_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let xor = _mm512_xor_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, xor, src.as_f64x8())) @@ -756,7 +804,8 @@ pub fn _mm512_mask_xor_pd(src: __m512d, k: __mmask8, a: __m512d, b: __m512d) -> #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vxorpd))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_xor_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_xor_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { unsafe { let xor = _mm512_xor_pd(a, b).as_f64x8(); transmute(simd_select_bitmask(k, xor, f64x8::ZERO)) @@ -772,7 +821,8 @@ pub fn _mm512_maskz_xor_pd(k: __mmask8, a: __m512d, b: __m512d) -> __m512d { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_xor_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_xor_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let xor = _mm_xor_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, xor, src.as_f32x4())) @@ -787,7 +837,8 @@ pub fn _mm_mask_xor_ps(src: __m128, k: __mmask8, a: __m128, b: __m128) -> __m128 #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_xor_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_xor_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { unsafe { let xor = _mm_xor_ps(a, b).as_f32x4(); transmute(simd_select_bitmask(k, xor, f32x4::ZERO)) @@ -803,7 +854,8 @@ pub fn _mm_maskz_xor_ps(k: __mmask8, a: __m128, b: __m128) -> __m128 { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_xor_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_xor_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let xor = _mm256_xor_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, xor, src.as_f32x8())) @@ -818,7 +870,8 @@ pub fn _mm256_mask_xor_ps(src: __m256, k: __mmask8, a: __m256, b: __m256) -> __m #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_xor_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_xor_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { unsafe { let xor = _mm256_xor_ps(a, b).as_f32x8(); transmute(simd_select_bitmask(k, xor, f32x8::ZERO)) @@ -833,7 +886,8 @@ pub fn _mm256_maskz_xor_ps(k: __mmask8, a: __m256, b: __m256) -> __m256 { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_xor_ps(a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_xor_ps(a: __m512, b: __m512) -> __m512 { unsafe { transmute(simd_xor( transmute::<_, u32x16>(a), @@ -851,7 +905,8 @@ pub fn _mm512_xor_ps(a: __m512, b: __m512) -> __m512 { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_xor_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_xor_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let xor = _mm512_xor_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, xor, src.as_f32x16())) @@ -866,7 +921,8 @@ pub fn _mm512_mask_xor_ps(src: __m512, k: __mmask16, a: __m512, b: __m512) -> __ #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vxorps))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_xor_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_xor_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { unsafe { let xor = _mm512_xor_ps(a, b).as_f32x16(); transmute(simd_select_bitmask(k, xor, f32x16::ZERO)) @@ -882,7 +938,8 @@ pub fn _mm512_maskz_xor_ps(k: __mmask16, a: __m512, b: __m512) -> __m512 { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_broadcast_f32x2(a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_f32x2(a: __m128) -> __m256 { unsafe { let b: f32x8 = simd_shuffle!(a, a, [0, 1, 0, 1, 0, 1, 0, 1]); transmute(b) @@ -897,7 +954,8 @@ pub fn _mm256_broadcast_f32x2(a: __m128) -> __m256 { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vbroadcastf32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_broadcast_f32x2(src: __m256, k: __mmask8, a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcast_f32x2(src: __m256, k: __mmask8, a: __m128) -> __m256 { unsafe { let b = _mm256_broadcast_f32x2(a).as_f32x8(); transmute(simd_select_bitmask(k, b, src.as_f32x8())) @@ -912,7 +970,8 @@ pub fn _mm256_mask_broadcast_f32x2(src: __m256, k: __mmask8, a: __m128) -> __m25 #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vbroadcastf32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_broadcast_f32x2(k: __mmask8, a: __m128) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcast_f32x2(k: __mmask8, a: __m128) -> __m256 { unsafe { let b = _mm256_broadcast_f32x2(a).as_f32x8(); transmute(simd_select_bitmask(k, b, f32x8::ZERO)) @@ -926,7 +985,8 @@ pub fn _mm256_maskz_broadcast_f32x2(k: __mmask8, a: __m128) -> __m256 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_f32x2(a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_f32x2(a: __m128) -> __m512 { unsafe { let b: f32x16 = simd_shuffle!(a, a, [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]); transmute(b) @@ -941,7 +1001,8 @@ pub fn _mm512_broadcast_f32x2(a: __m128) -> __m512 { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vbroadcastf32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_f32x2(src: __m512, k: __mmask16, a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_f32x2(src: __m512, k: __mmask16, a: __m128) -> __m512 { unsafe { let b = _mm512_broadcast_f32x2(a).as_f32x16(); transmute(simd_select_bitmask(k, b, src.as_f32x16())) @@ -956,7 +1017,8 @@ pub fn _mm512_mask_broadcast_f32x2(src: __m512, k: __mmask16, a: __m128) -> __m5 #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vbroadcastf32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_f32x2(k: __mmask16, a: __m128) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_f32x2(k: __mmask16, a: __m128) -> __m512 { unsafe { let b = _mm512_broadcast_f32x2(a).as_f32x16(); transmute(simd_select_bitmask(k, b, f32x16::ZERO)) @@ -970,7 +1032,8 @@ pub fn _mm512_maskz_broadcast_f32x2(k: __mmask16, a: __m128) -> __m512 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_f32x8(a: __m256) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_f32x8(a: __m256) -> __m512 { unsafe { let b: f32x16 = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7]); transmute(b) @@ -984,7 +1047,8 @@ pub fn _mm512_broadcast_f32x8(a: __m256) -> __m512 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_f32x8(src: __m512, k: __mmask16, a: __m256) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_f32x8(src: __m512, k: __mmask16, a: __m256) -> __m512 { unsafe { let b = _mm512_broadcast_f32x8(a).as_f32x16(); transmute(simd_select_bitmask(k, b, src.as_f32x16())) @@ -998,7 +1062,8 @@ pub fn _mm512_mask_broadcast_f32x8(src: __m512, k: __mmask16, a: __m256) -> __m5 #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_f32x8(k: __mmask16, a: __m256) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_f32x8(k: __mmask16, a: __m256) -> __m512 { unsafe { let b = _mm512_broadcast_f32x8(a).as_f32x16(); transmute(simd_select_bitmask(k, b, f32x16::ZERO)) @@ -1012,7 +1077,8 @@ pub fn _mm512_maskz_broadcast_f32x8(k: __mmask16, a: __m256) -> __m512 { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_broadcast_f64x2(a: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_f64x2(a: __m128d) -> __m256d { unsafe { let b: f64x4 = simd_shuffle!(a, a, [0, 1, 0, 1]); transmute(b) @@ -1026,7 +1092,8 @@ pub fn _mm256_broadcast_f64x2(a: __m128d) -> __m256d { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_broadcast_f64x2(src: __m256d, k: __mmask8, a: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcast_f64x2(src: __m256d, k: __mmask8, a: __m128d) -> __m256d { unsafe { let b = _mm256_broadcast_f64x2(a).as_f64x4(); transmute(simd_select_bitmask(k, b, src.as_f64x4())) @@ -1040,7 +1107,8 @@ pub fn _mm256_mask_broadcast_f64x2(src: __m256d, k: __mmask8, a: __m128d) -> __m #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_broadcast_f64x2(k: __mmask8, a: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcast_f64x2(k: __mmask8, a: __m128d) -> __m256d { unsafe { let b = _mm256_broadcast_f64x2(a).as_f64x4(); transmute(simd_select_bitmask(k, b, f64x4::ZERO)) @@ -1054,7 +1122,8 @@ pub fn _mm256_maskz_broadcast_f64x2(k: __mmask8, a: __m128d) -> __m256d { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_f64x2(a: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_f64x2(a: __m128d) -> __m512d { unsafe { let b: f64x8 = simd_shuffle!(a, a, [0, 1, 0, 1, 0, 1, 0, 1]); transmute(b) @@ -1068,7 +1137,8 @@ pub fn _mm512_broadcast_f64x2(a: __m128d) -> __m512d { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_f64x2(src: __m512d, k: __mmask8, a: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_f64x2(src: __m512d, k: __mmask8, a: __m128d) -> __m512d { unsafe { let b = _mm512_broadcast_f64x2(a).as_f64x8(); transmute(simd_select_bitmask(k, b, src.as_f64x8())) @@ -1082,7 +1152,8 @@ pub fn _mm512_mask_broadcast_f64x2(src: __m512d, k: __mmask8, a: __m128d) -> __m #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_f64x2(k: __mmask8, a: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_f64x2(k: __mmask8, a: __m128d) -> __m512d { unsafe { let b = _mm512_broadcast_f64x2(a).as_f64x8(); transmute(simd_select_bitmask(k, b, f64x8::ZERO)) @@ -1095,7 +1166,8 @@ pub fn _mm512_maskz_broadcast_f64x2(k: __mmask8, a: __m128d) -> __m512d { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_broadcast_i32x2(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_broadcast_i32x2(a: __m128i) -> __m128i { unsafe { let a = a.as_i32x4(); let b: i32x4 = simd_shuffle!(a, a, [0, 1, 0, 1]); @@ -1111,7 +1183,8 @@ pub fn _mm_broadcast_i32x2(a: __m128i) -> __m128i { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vbroadcasti32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_broadcast_i32x2(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_broadcast_i32x2(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { let b = _mm_broadcast_i32x2(a).as_i32x4(); transmute(simd_select_bitmask(k, b, src.as_i32x4())) @@ -1126,7 +1199,8 @@ pub fn _mm_mask_broadcast_i32x2(src: __m128i, k: __mmask8, a: __m128i) -> __m128 #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vbroadcasti32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_broadcast_i32x2(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_broadcast_i32x2(k: __mmask8, a: __m128i) -> __m128i { unsafe { let b = _mm_broadcast_i32x2(a).as_i32x4(); transmute(simd_select_bitmask(k, b, i32x4::ZERO)) @@ -1139,7 +1213,8 @@ pub fn _mm_maskz_broadcast_i32x2(k: __mmask8, a: __m128i) -> __m128i { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_broadcast_i32x2(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_i32x2(a: __m128i) -> __m256i { unsafe { let a = a.as_i32x4(); let b: i32x8 = simd_shuffle!(a, a, [0, 1, 0, 1, 0, 1, 0, 1]); @@ -1155,7 +1230,8 @@ pub fn _mm256_broadcast_i32x2(a: __m128i) -> __m256i { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vbroadcasti32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_broadcast_i32x2(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcast_i32x2(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let b = _mm256_broadcast_i32x2(a).as_i32x8(); transmute(simd_select_bitmask(k, b, src.as_i32x8())) @@ -1170,7 +1246,8 @@ pub fn _mm256_mask_broadcast_i32x2(src: __m256i, k: __mmask8, a: __m128i) -> __m #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vbroadcasti32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_broadcast_i32x2(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcast_i32x2(k: __mmask8, a: __m128i) -> __m256i { unsafe { let b = _mm256_broadcast_i32x2(a).as_i32x8(); transmute(simd_select_bitmask(k, b, i32x8::ZERO)) @@ -1183,7 +1260,8 @@ pub fn _mm256_maskz_broadcast_i32x2(k: __mmask8, a: __m128i) -> __m256i { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_i32x2(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_i32x2(a: __m128i) -> __m512i { unsafe { let a = a.as_i32x4(); let b: i32x16 = simd_shuffle!(a, a, [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]); @@ -1199,7 +1277,8 @@ pub fn _mm512_broadcast_i32x2(a: __m128i) -> __m512i { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vbroadcasti32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_i32x2(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_i32x2(src: __m512i, k: __mmask16, a: __m128i) -> __m512i { unsafe { let b = _mm512_broadcast_i32x2(a).as_i32x16(); transmute(simd_select_bitmask(k, b, src.as_i32x16())) @@ -1214,7 +1293,8 @@ pub fn _mm512_mask_broadcast_i32x2(src: __m512i, k: __mmask16, a: __m128i) -> __ #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vbroadcasti32x2))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_i32x2(k: __mmask16, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_i32x2(k: __mmask16, a: __m128i) -> __m512i { unsafe { let b = _mm512_broadcast_i32x2(a).as_i32x16(); transmute(simd_select_bitmask(k, b, i32x16::ZERO)) @@ -1227,7 +1307,8 @@ pub fn _mm512_maskz_broadcast_i32x2(k: __mmask16, a: __m128i) -> __m512i { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_i32x8(a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_i32x8(a: __m256i) -> __m512i { unsafe { let a = a.as_i32x8(); let b: i32x16 = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7]); @@ -1242,7 +1323,8 @@ pub fn _mm512_broadcast_i32x8(a: __m256i) -> __m512i { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_i32x8(src: __m512i, k: __mmask16, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_i32x8(src: __m512i, k: __mmask16, a: __m256i) -> __m512i { unsafe { let b = _mm512_broadcast_i32x8(a).as_i32x16(); transmute(simd_select_bitmask(k, b, src.as_i32x16())) @@ -1256,7 +1338,8 @@ pub fn _mm512_mask_broadcast_i32x8(src: __m512i, k: __mmask16, a: __m256i) -> __ #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_i32x8(k: __mmask16, a: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_i32x8(k: __mmask16, a: __m256i) -> __m512i { unsafe { let b = _mm512_broadcast_i32x8(a).as_i32x16(); transmute(simd_select_bitmask(k, b, i32x16::ZERO)) @@ -1269,7 +1352,8 @@ pub fn _mm512_maskz_broadcast_i32x8(k: __mmask16, a: __m256i) -> __m512i { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_broadcast_i64x2(a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_broadcast_i64x2(a: __m128i) -> __m256i { unsafe { let a = a.as_i64x2(); let b: i64x4 = simd_shuffle!(a, a, [0, 1, 0, 1]); @@ -1284,7 +1368,8 @@ pub fn _mm256_broadcast_i64x2(a: __m128i) -> __m256i { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_broadcast_i64x2(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_broadcast_i64x2(src: __m256i, k: __mmask8, a: __m128i) -> __m256i { unsafe { let b = _mm256_broadcast_i64x2(a).as_i64x4(); transmute(simd_select_bitmask(k, b, src.as_i64x4())) @@ -1298,7 +1383,8 @@ pub fn _mm256_mask_broadcast_i64x2(src: __m256i, k: __mmask8, a: __m128i) -> __m #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_broadcast_i64x2(k: __mmask8, a: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_broadcast_i64x2(k: __mmask8, a: __m128i) -> __m256i { unsafe { let b = _mm256_broadcast_i64x2(a).as_i64x4(); transmute(simd_select_bitmask(k, b, i64x4::ZERO)) @@ -1311,7 +1397,8 @@ pub fn _mm256_maskz_broadcast_i64x2(k: __mmask8, a: __m128i) -> __m256i { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_broadcast_i64x2(a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_broadcast_i64x2(a: __m128i) -> __m512i { unsafe { let a = a.as_i64x2(); let b: i64x8 = simd_shuffle!(a, a, [0, 1, 0, 1, 0, 1, 0, 1]); @@ -1326,7 +1413,8 @@ pub fn _mm512_broadcast_i64x2(a: __m128i) -> __m512i { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_broadcast_i64x2(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_broadcast_i64x2(src: __m512i, k: __mmask8, a: __m128i) -> __m512i { unsafe { let b = _mm512_broadcast_i64x2(a).as_i64x8(); transmute(simd_select_bitmask(k, b, src.as_i64x8())) @@ -1340,7 +1428,8 @@ pub fn _mm512_mask_broadcast_i64x2(src: __m512i, k: __mmask8, a: __m128i) -> __m #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_broadcast_i64x2(k: __mmask8, a: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_broadcast_i64x2(k: __mmask8, a: __m128i) -> __m512i { unsafe { let b = _mm512_broadcast_i64x2(a).as_i64x8(); transmute(simd_select_bitmask(k, b, i64x8::ZERO)) @@ -1357,7 +1446,8 @@ pub fn _mm512_maskz_broadcast_i64x2(k: __mmask8, a: __m128i) -> __m512i { #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_extractf32x8_ps(a: __m512) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_extractf32x8_ps(a: __m512) -> __m256 { unsafe { static_assert_uimm_bits!(IMM8, 1); match IMM8 & 1 { @@ -1377,7 +1467,12 @@ pub fn _mm512_extractf32x8_ps(a: __m512) -> __m256 { #[cfg_attr(test, assert_instr(vextractf32x8, IMM8 = 1))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_extractf32x8_ps(src: __m256, k: __mmask8, a: __m512) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_extractf32x8_ps( + src: __m256, + k: __mmask8, + a: __m512, +) -> __m256 { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm512_extractf32x8_ps::(a); @@ -1395,7 +1490,8 @@ pub fn _mm512_mask_extractf32x8_ps(src: __m256, k: __mmask8, a: #[cfg_attr(test, assert_instr(vextractf32x8, IMM8 = 1))] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_extractf32x8_ps(k: __mmask8, a: __m512) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_extractf32x8_ps(k: __mmask8, a: __m512) -> __m256 { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm512_extractf32x8_ps::(a); @@ -1411,7 +1507,8 @@ pub fn _mm512_maskz_extractf32x8_ps(k: __mmask8, a: __m512) -> #[target_feature(enable = "avx512dq,avx512vl")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_extractf64x2_pd(a: __m256d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extractf64x2_pd(a: __m256d) -> __m128d { unsafe { static_assert_uimm_bits!(IMM8, 1); match IMM8 & 1 { @@ -1431,7 +1528,8 @@ pub fn _mm256_extractf64x2_pd(a: __m256d) -> __m128d { #[cfg_attr(test, assert_instr(vextractf64x2, IMM8 = 1))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_extractf64x2_pd( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_extractf64x2_pd( src: __m128d, k: __mmask8, a: __m256d, @@ -1453,7 +1551,8 @@ pub fn _mm256_mask_extractf64x2_pd( #[cfg_attr(test, assert_instr(vextractf64x2, IMM8 = 1))] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_extractf64x2_pd(k: __mmask8, a: __m256d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_extractf64x2_pd(k: __mmask8, a: __m256d) -> __m128d { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm256_extractf64x2_pd::(a); @@ -1469,7 +1568,8 @@ pub fn _mm256_maskz_extractf64x2_pd(k: __mmask8, a: __m256d) -> #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_extractf64x2_pd(a: __m512d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_extractf64x2_pd(a: __m512d) -> __m128d { unsafe { static_assert_uimm_bits!(IMM8, 2); match IMM8 & 3 { @@ -1491,7 +1591,8 @@ pub fn _mm512_extractf64x2_pd(a: __m512d) -> __m128d { #[cfg_attr(test, assert_instr(vextractf64x2, IMM8 = 3))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_extractf64x2_pd( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_extractf64x2_pd( src: __m128d, k: __mmask8, a: __m512d, @@ -1513,7 +1614,8 @@ pub fn _mm512_mask_extractf64x2_pd( #[cfg_attr(test, assert_instr(vextractf64x2, IMM8 = 3))] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_extractf64x2_pd(k: __mmask8, a: __m512d) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_extractf64x2_pd(k: __mmask8, a: __m512d) -> __m128d { unsafe { static_assert_uimm_bits!(IMM8, 2); let b = _mm512_extractf64x2_pd::(a).as_f64x2(); @@ -1529,7 +1631,8 @@ pub fn _mm512_maskz_extractf64x2_pd(k: __mmask8, a: __m512d) -> #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_extracti32x8_epi32(a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_extracti32x8_epi32(a: __m512i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 1); let a = a.as_i32x16(); @@ -1550,7 +1653,8 @@ pub fn _mm512_extracti32x8_epi32(a: __m512i) -> __m256i { #[cfg_attr(test, assert_instr(vextracti32x8, IMM8 = 1))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_extracti32x8_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_extracti32x8_epi32( src: __m256i, k: __mmask8, a: __m512i, @@ -1571,7 +1675,8 @@ pub fn _mm512_mask_extracti32x8_epi32( #[cfg_attr(test, assert_instr(vextracti32x8, IMM8 = 1))] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_extracti32x8_epi32(k: __mmask8, a: __m512i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_extracti32x8_epi32(k: __mmask8, a: __m512i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm512_extracti32x8_epi32::(a).as_i32x8(); @@ -1587,7 +1692,8 @@ pub fn _mm512_maskz_extracti32x8_epi32(k: __mmask8, a: __m512i) #[target_feature(enable = "avx512dq,avx512vl")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_extracti64x2_epi64(a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_extracti64x2_epi64(a: __m256i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 1); let a = a.as_i64x4(); @@ -1607,7 +1713,8 @@ pub fn _mm256_extracti64x2_epi64(a: __m256i) -> __m128i { #[cfg_attr(test, assert_instr(vextracti64x2, IMM8 = 1))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_extracti64x2_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_extracti64x2_epi64( src: __m128i, k: __mmask8, a: __m256i, @@ -1628,7 +1735,8 @@ pub fn _mm256_mask_extracti64x2_epi64( #[cfg_attr(test, assert_instr(vextracti64x2, IMM8 = 1))] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_extracti64x2_epi64(k: __mmask8, a: __m256i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_extracti64x2_epi64(k: __mmask8, a: __m256i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm256_extracti64x2_epi64::(a).as_i64x2(); @@ -1644,7 +1752,8 @@ pub fn _mm256_maskz_extracti64x2_epi64(k: __mmask8, a: __m256i) #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_extracti64x2_epi64(a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_extracti64x2_epi64(a: __m512i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 2); let a = a.as_i64x8(); @@ -1666,7 +1775,8 @@ pub fn _mm512_extracti64x2_epi64(a: __m512i) -> __m128i { #[cfg_attr(test, assert_instr(vextracti64x2, IMM8 = 3))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_extracti64x2_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_extracti64x2_epi64( src: __m128i, k: __mmask8, a: __m512i, @@ -1687,7 +1797,8 @@ pub fn _mm512_mask_extracti64x2_epi64( #[cfg_attr(test, assert_instr(vextracti64x2, IMM8 = 3))] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_extracti64x2_epi64(k: __mmask8, a: __m512i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_extracti64x2_epi64(k: __mmask8, a: __m512i) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 2); let b = _mm512_extracti64x2_epi64::(a).as_i64x2(); @@ -1705,7 +1816,8 @@ pub fn _mm512_maskz_extracti64x2_epi64(k: __mmask8, a: __m512i) #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_insertf32x8(a: __m512, b: __m256) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_insertf32x8(a: __m512, b: __m256) -> __m512 { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm512_castps256_ps512(b); @@ -1738,7 +1850,8 @@ pub fn _mm512_insertf32x8(a: __m512, b: __m256) -> __m512 { #[cfg_attr(test, assert_instr(vinsertf32x8, IMM8 = 1))] #[rustc_legacy_const_generics(4)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_insertf32x8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_insertf32x8( src: __m512, k: __mmask16, a: __m512, @@ -1761,7 +1874,12 @@ pub fn _mm512_mask_insertf32x8( #[cfg_attr(test, assert_instr(vinsertf32x8, IMM8 = 1))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_insertf32x8(k: __mmask16, a: __m512, b: __m256) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_insertf32x8( + k: __mmask16, + a: __m512, + b: __m256, +) -> __m512 { unsafe { static_assert_uimm_bits!(IMM8, 1); let c = _mm512_insertf32x8::(a, b).as_f32x16(); @@ -1777,7 +1895,8 @@ pub fn _mm512_maskz_insertf32x8(k: __mmask16, a: __m512, b: __m #[target_feature(enable = "avx512dq,avx512vl")] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_insertf64x2(a: __m256d, b: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_insertf64x2(a: __m256d, b: __m128d) -> __m256d { unsafe { static_assert_uimm_bits!(IMM8, 1); let b = _mm256_castpd128_pd256(b); @@ -1798,7 +1917,8 @@ pub fn _mm256_insertf64x2(a: __m256d, b: __m128d) -> __m256d { #[cfg_attr(test, assert_instr(vinsertf64x2, IMM8 = 1))] #[rustc_legacy_const_generics(4)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_insertf64x2( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_insertf64x2( src: __m256d, k: __mmask8, a: __m256d, @@ -1821,7 +1941,12 @@ pub fn _mm256_mask_insertf64x2( #[cfg_attr(test, assert_instr(vinsertf64x2, IMM8 = 1))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_insertf64x2(k: __mmask8, a: __m256d, b: __m128d) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_insertf64x2( + k: __mmask8, + a: __m256d, + b: __m128d, +) -> __m256d { unsafe { static_assert_uimm_bits!(IMM8, 1); let c = _mm256_insertf64x2::(a, b).as_f64x4(); @@ -1837,7 +1962,8 @@ pub fn _mm256_maskz_insertf64x2(k: __mmask8, a: __m256d, b: __m #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_insertf64x2(a: __m512d, b: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_insertf64x2(a: __m512d, b: __m128d) -> __m512d { unsafe { static_assert_uimm_bits!(IMM8, 2); let b = _mm512_castpd128_pd512(b); @@ -1860,7 +1986,8 @@ pub fn _mm512_insertf64x2(a: __m512d, b: __m128d) -> __m512d { #[cfg_attr(test, assert_instr(vinsertf64x2, IMM8 = 3))] #[rustc_legacy_const_generics(4)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_insertf64x2( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_insertf64x2( src: __m512d, k: __mmask8, a: __m512d, @@ -1883,7 +2010,12 @@ pub fn _mm512_mask_insertf64x2( #[cfg_attr(test, assert_instr(vinsertf64x2, IMM8 = 3))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_insertf64x2(k: __mmask8, a: __m512d, b: __m128d) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_insertf64x2( + k: __mmask8, + a: __m512d, + b: __m128d, +) -> __m512d { unsafe { static_assert_uimm_bits!(IMM8, 2); let c = _mm512_insertf64x2::(a, b).as_f64x8(); @@ -1899,7 +2031,8 @@ pub fn _mm512_maskz_insertf64x2(k: __mmask8, a: __m512d, b: __m #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_inserti32x8(a: __m512i, b: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_inserti32x8(a: __m512i, b: __m256i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 1); let a = a.as_i32x16(); @@ -1934,7 +2067,8 @@ pub fn _mm512_inserti32x8(a: __m512i, b: __m256i) -> __m512i { #[cfg_attr(test, assert_instr(vinserti32x8, IMM8 = 1))] #[rustc_legacy_const_generics(4)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_inserti32x8( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_inserti32x8( src: __m512i, k: __mmask16, a: __m512i, @@ -1957,7 +2091,12 @@ pub fn _mm512_mask_inserti32x8( #[cfg_attr(test, assert_instr(vinserti32x8, IMM8 = 1))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_inserti32x8(k: __mmask16, a: __m512i, b: __m256i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_inserti32x8( + k: __mmask16, + a: __m512i, + b: __m256i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 1); let c = _mm512_inserti32x8::(a, b).as_i32x16(); @@ -1973,7 +2112,8 @@ pub fn _mm512_maskz_inserti32x8(k: __mmask16, a: __m512i, b: __ #[target_feature(enable = "avx512dq,avx512vl")] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_inserti64x2(a: __m256i, b: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_inserti64x2(a: __m256i, b: __m128i) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 1); let a = a.as_i64x4(); @@ -1995,7 +2135,8 @@ pub fn _mm256_inserti64x2(a: __m256i, b: __m128i) -> __m256i { #[cfg_attr(test, assert_instr(vinserti64x2, IMM8 = 1))] #[rustc_legacy_const_generics(4)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_inserti64x2( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_inserti64x2( src: __m256i, k: __mmask8, a: __m256i, @@ -2018,7 +2159,12 @@ pub fn _mm256_mask_inserti64x2( #[cfg_attr(test, assert_instr(vinserti64x2, IMM8 = 1))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_inserti64x2(k: __mmask8, a: __m256i, b: __m128i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_inserti64x2( + k: __mmask8, + a: __m256i, + b: __m128i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 1); let c = _mm256_inserti64x2::(a, b).as_i64x4(); @@ -2034,7 +2180,8 @@ pub fn _mm256_maskz_inserti64x2(k: __mmask8, a: __m256i, b: __m #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(2)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_inserti64x2(a: __m512i, b: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_inserti64x2(a: __m512i, b: __m128i) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 2); let a = a.as_i64x8(); @@ -2058,7 +2205,8 @@ pub fn _mm512_inserti64x2(a: __m512i, b: __m128i) -> __m512i { #[cfg_attr(test, assert_instr(vinserti64x2, IMM8 = 3))] #[rustc_legacy_const_generics(4)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_inserti64x2( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_inserti64x2( src: __m512i, k: __mmask8, a: __m512i, @@ -2081,7 +2229,12 @@ pub fn _mm512_mask_inserti64x2( #[cfg_attr(test, assert_instr(vinserti64x2, IMM8 = 3))] #[rustc_legacy_const_generics(3)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_inserti64x2(k: __mmask8, a: __m512i, b: __m128i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_inserti64x2( + k: __mmask8, + a: __m512i, + b: __m128i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 2); let c = _mm512_inserti64x2::(a, b).as_i64x8(); @@ -4333,7 +4486,8 @@ pub fn _mm512_maskz_cvttps_epu64(k: __mmask8, a: __m256) -> __m512i { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmullq))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mullo_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mullo_epi64(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(simd_mul(a.as_i64x2(), b.as_i64x2())) } } @@ -4346,7 +4500,8 @@ pub fn _mm_mullo_epi64(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmullq))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_mask_mullo_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mullo_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let b = _mm_mullo_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, b, src.as_i64x2())) @@ -4362,7 +4517,8 @@ pub fn _mm_mask_mullo_epi64(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) - #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmullq))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_maskz_mullo_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mullo_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let b = _mm_mullo_epi64(a, b).as_i64x2(); transmute(simd_select_bitmask(k, b, i64x2::ZERO)) @@ -4377,7 +4533,8 @@ pub fn _mm_maskz_mullo_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmullq))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mullo_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mullo_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_mul(a.as_i64x4(), b.as_i64x4())) } } @@ -4390,7 +4547,8 @@ pub fn _mm256_mullo_epi64(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmullq))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_mask_mullo_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mullo_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let b = _mm256_mullo_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, b, src.as_i64x4())) @@ -4406,7 +4564,8 @@ pub fn _mm256_mask_mullo_epi64(src: __m256i, k: __mmask8, a: __m256i, b: __m256i #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmullq))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_maskz_mullo_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mullo_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let b = _mm256_mullo_epi64(a, b).as_i64x4(); transmute(simd_select_bitmask(k, b, i64x4::ZERO)) @@ -4421,7 +4580,8 @@ pub fn _mm256_maskz_mullo_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vpmullq))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mullo_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mullo_epi64(a: __m512i, b: __m512i) -> __m512i { unsafe { transmute(simd_mul(a.as_i64x8(), b.as_i64x8())) } } @@ -4434,7 +4594,8 @@ pub fn _mm512_mullo_epi64(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vpmullq))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_mask_mullo_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mullo_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let b = _mm512_mullo_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, b, src.as_i64x8())) @@ -4450,7 +4611,8 @@ pub fn _mm512_mask_mullo_epi64(src: __m512i, k: __mmask8, a: __m512i, b: __m512i #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vpmullq))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_maskz_mullo_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mullo_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { unsafe { let b = _mm512_mullo_epi64(a, b).as_i64x8(); transmute(simd_select_bitmask(k, b, i64x8::ZERO)) @@ -4465,7 +4627,8 @@ pub fn _mm512_maskz_mullo_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _cvtmask8_u32(a: __mmask8) -> u32 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _cvtmask8_u32(a: __mmask8) -> u32 { a as u32 } @@ -4475,7 +4638,8 @@ pub fn _cvtmask8_u32(a: __mmask8) -> u32 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _cvtu32_mask8(a: u32) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _cvtu32_mask8(a: u32) -> __mmask8 { a as __mmask8 } @@ -4485,7 +4649,8 @@ pub fn _cvtu32_mask8(a: u32) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kadd_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kadd_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { a.wrapping_add(b) } @@ -4495,7 +4660,8 @@ pub fn _kadd_mask16(a: __mmask16, b: __mmask16) -> __mmask16 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kadd_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kadd_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { a.wrapping_add(b) } @@ -4505,7 +4671,8 @@ pub fn _kadd_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kand_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kand_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { a & b } @@ -4515,7 +4682,8 @@ pub fn _kand_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kandn_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kandn_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { _knot_mask8(a) & b } @@ -4525,7 +4693,8 @@ pub fn _kandn_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _knot_mask8(a: __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _knot_mask8(a: __mmask8) -> __mmask8 { a ^ 0b11111111 } @@ -4535,7 +4704,8 @@ pub fn _knot_mask8(a: __mmask8) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kor_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kor_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { a | b } @@ -4545,7 +4715,8 @@ pub fn _kor_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kxnor_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kxnor_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { _knot_mask8(_kxor_mask8(a, b)) } @@ -4555,7 +4726,8 @@ pub fn _kxnor_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kxor_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kxor_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { a ^ b } @@ -4566,7 +4738,8 @@ pub fn _kxor_mask8(a: __mmask8, b: __mmask8) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _kortest_mask8_u8(a: __mmask8, b: __mmask8, all_ones: *mut u8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _kortest_mask8_u8(a: __mmask8, b: __mmask8, all_ones: *mut u8) -> u8 { let tmp = _kor_mask8(a, b); *all_ones = (tmp == 0xff) as u8; (tmp == 0) as u8 @@ -4579,7 +4752,8 @@ pub unsafe fn _kortest_mask8_u8(a: __mmask8, b: __mmask8, all_ones: *mut u8) -> #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kortestc_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kortestc_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { (_kor_mask8(a, b) == 0xff) as u8 } @@ -4590,7 +4764,8 @@ pub fn _kortestc_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kortestz_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kortestz_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { (_kor_mask8(a, b) == 0) as u8 } @@ -4601,7 +4776,8 @@ pub fn _kortestz_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kshiftli_mask8(a: __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kshiftli_mask8(a: __mmask8) -> __mmask8 { a.unbounded_shl(COUNT) } @@ -4612,7 +4788,8 @@ pub fn _kshiftli_mask8(a: __mmask8) -> __mmask8 { #[target_feature(enable = "avx512dq")] #[rustc_legacy_const_generics(1)] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _kshiftri_mask8(a: __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _kshiftri_mask8(a: __mmask8) -> __mmask8 { a.unbounded_shr(COUNT) } @@ -4624,7 +4801,8 @@ pub fn _kshiftri_mask8(a: __mmask8) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _ktest_mask16_u8(a: __mmask16, b: __mmask16, and_not: *mut u8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _ktest_mask16_u8(a: __mmask16, b: __mmask16, and_not: *mut u8) -> u8 { *and_not = (_kandn_mask16(a, b) == 0) as u8; (_kand_mask16(a, b) == 0) as u8 } @@ -4637,7 +4815,8 @@ pub unsafe fn _ktest_mask16_u8(a: __mmask16, b: __mmask16, and_not: *mut u8) -> #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _ktest_mask8_u8(a: __mmask8, b: __mmask8, and_not: *mut u8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _ktest_mask8_u8(a: __mmask8, b: __mmask8, and_not: *mut u8) -> u8 { *and_not = (_kandn_mask8(a, b) == 0) as u8; (_kand_mask8(a, b) == 0) as u8 } @@ -4649,7 +4828,8 @@ pub unsafe fn _ktest_mask8_u8(a: __mmask8, b: __mmask8, and_not: *mut u8) -> u8 #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _ktestc_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _ktestc_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { (_kandn_mask16(a, b) == 0) as u8 } @@ -4660,7 +4840,8 @@ pub fn _ktestc_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _ktestc_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _ktestc_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { (_kandn_mask8(a, b) == 0) as u8 } @@ -4671,7 +4852,8 @@ pub fn _ktestc_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _ktestz_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _ktestz_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { (_kand_mask16(a, b) == 0) as u8 } @@ -4682,7 +4864,8 @@ pub fn _ktestz_mask16_u8(a: __mmask16, b: __mmask16) -> u8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _ktestz_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _ktestz_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { (_kand_mask8(a, b) == 0) as u8 } @@ -4692,7 +4875,8 @@ pub fn _ktestz_mask8_u8(a: __mmask8, b: __mmask8) -> u8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _load_mask8(mem_addr: *const __mmask8) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _load_mask8(mem_addr: *const __mmask8) -> __mmask8 { *mem_addr } @@ -4702,7 +4886,8 @@ pub unsafe fn _load_mask8(mem_addr: *const __mmask8) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub unsafe fn _store_mask8(mem_addr: *mut __mmask8, a: __mmask8) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _store_mask8(mem_addr: *mut __mmask8, a: __mmask8) { *mem_addr = a; } @@ -4713,7 +4898,8 @@ pub unsafe fn _store_mask8(mem_addr: *mut __mmask8, a: __mmask8) { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_movepi32_mask(a: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movepi32_mask(a: __m128i) -> __mmask8 { let zero = _mm_setzero_si128(); _mm_cmplt_epi32_mask(a, zero) } @@ -4725,7 +4911,8 @@ pub fn _mm_movepi32_mask(a: __m128i) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_movepi32_mask(a: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movepi32_mask(a: __m256i) -> __mmask8 { let zero = _mm256_setzero_si256(); _mm256_cmplt_epi32_mask(a, zero) } @@ -4737,7 +4924,8 @@ pub fn _mm256_movepi32_mask(a: __m256i) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_movepi32_mask(a: __m512i) -> __mmask16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movepi32_mask(a: __m512i) -> __mmask16 { let zero = _mm512_setzero_si512(); _mm512_cmplt_epi32_mask(a, zero) } @@ -4749,7 +4937,8 @@ pub fn _mm512_movepi32_mask(a: __m512i) -> __mmask16 { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_movepi64_mask(a: __m128i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movepi64_mask(a: __m128i) -> __mmask8 { let zero = _mm_setzero_si128(); _mm_cmplt_epi64_mask(a, zero) } @@ -4761,7 +4950,8 @@ pub fn _mm_movepi64_mask(a: __m128i) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_movepi64_mask(a: __m256i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movepi64_mask(a: __m256i) -> __mmask8 { let zero = _mm256_setzero_si256(); _mm256_cmplt_epi64_mask(a, zero) } @@ -4773,7 +4963,8 @@ pub fn _mm256_movepi64_mask(a: __m256i) -> __mmask8 { #[inline] #[target_feature(enable = "avx512dq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_movepi64_mask(a: __m512i) -> __mmask8 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movepi64_mask(a: __m512i) -> __mmask8 { let zero = _mm512_setzero_si512(); _mm512_cmplt_epi64_mask(a, zero) } @@ -4786,7 +4977,8 @@ pub fn _mm512_movepi64_mask(a: __m512i) -> __mmask8 { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmovm2d))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_movm_epi32(k: __mmask8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movm_epi32(k: __mmask8) -> __m128i { let ones = _mm_set1_epi32(-1); _mm_maskz_mov_epi32(k, ones) } @@ -4799,7 +4991,8 @@ pub fn _mm_movm_epi32(k: __mmask8) -> __m128i { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmovm2d))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_movm_epi32(k: __mmask8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movm_epi32(k: __mmask8) -> __m256i { let ones = _mm256_set1_epi32(-1); _mm256_maskz_mov_epi32(k, ones) } @@ -4812,7 +5005,8 @@ pub fn _mm256_movm_epi32(k: __mmask8) -> __m256i { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vpmovm2d))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_movm_epi32(k: __mmask16) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movm_epi32(k: __mmask16) -> __m512i { let ones = _mm512_set1_epi32(-1); _mm512_maskz_mov_epi32(k, ones) } @@ -4825,7 +5019,8 @@ pub fn _mm512_movm_epi32(k: __mmask16) -> __m512i { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmovm2q))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm_movm_epi64(k: __mmask8) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_movm_epi64(k: __mmask8) -> __m128i { let ones = _mm_set1_epi64x(-1); _mm_maskz_mov_epi64(k, ones) } @@ -4838,7 +5033,8 @@ pub fn _mm_movm_epi64(k: __mmask8) -> __m128i { #[target_feature(enable = "avx512dq,avx512vl")] #[cfg_attr(test, assert_instr(vpmovm2q))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm256_movm_epi64(k: __mmask8) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_movm_epi64(k: __mmask8) -> __m256i { let ones = _mm256_set1_epi64x(-1); _mm256_maskz_mov_epi64(k, ones) } @@ -4851,7 +5047,8 @@ pub fn _mm256_movm_epi64(k: __mmask8) -> __m256i { #[target_feature(enable = "avx512dq")] #[cfg_attr(test, assert_instr(vpmovm2q))] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] -pub fn _mm512_movm_epi64(k: __mmask8) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_movm_epi64(k: __mmask8) -> __m512i { let ones = _mm512_set1_epi64(-1); _mm512_maskz_mov_epi64(k, ones) } @@ -7203,6 +7400,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { use super::*; + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; @@ -7226,7 +7424,7 @@ mod tests { const XOR_32: f32 = unsafe { transmute(0x66666666_u32) }; #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_and_pd() { + const unsafe fn test_mm_mask_and_pd() { let a = _mm_set1_pd(OPRND1_64); let b = _mm_set1_pd(OPRND2_64); let src = _mm_set_pd(1., 2.); @@ -7236,7 +7434,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_and_pd() { + const unsafe fn test_mm_maskz_and_pd() { let a = _mm_set1_pd(OPRND1_64); let b = _mm_set1_pd(OPRND2_64); let r = _mm_maskz_and_pd(0b01, a, b); @@ -7245,7 +7443,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_and_pd() { + const unsafe fn test_mm256_mask_and_pd() { let a = _mm256_set1_pd(OPRND1_64); let b = _mm256_set1_pd(OPRND2_64); let src = _mm256_set_pd(1., 2., 3., 4.); @@ -7255,7 +7453,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_and_pd() { + const unsafe fn test_mm256_maskz_and_pd() { let a = _mm256_set1_pd(OPRND1_64); let b = _mm256_set1_pd(OPRND2_64); let r = _mm256_maskz_and_pd(0b0101, a, b); @@ -7264,7 +7462,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_and_pd() { + const unsafe fn test_mm512_and_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let r = _mm512_and_pd(a, b); @@ -7273,7 +7471,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_and_pd() { + const unsafe fn test_mm512_mask_and_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let src = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); @@ -7283,7 +7481,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_and_pd() { + const unsafe fn test_mm512_maskz_and_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let r = _mm512_maskz_and_pd(0b01010101, a, b); @@ -7292,7 +7490,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_and_ps() { + const unsafe fn test_mm_mask_and_ps() { let a = _mm_set1_ps(OPRND1_32); let b = _mm_set1_ps(OPRND2_32); let src = _mm_set_ps(1., 2., 3., 4.); @@ -7302,7 +7500,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_and_ps() { + const unsafe fn test_mm_maskz_and_ps() { let a = _mm_set1_ps(OPRND1_32); let b = _mm_set1_ps(OPRND2_32); let r = _mm_maskz_and_ps(0b0101, a, b); @@ -7311,7 +7509,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_and_ps() { + const unsafe fn test_mm256_mask_and_ps() { let a = _mm256_set1_ps(OPRND1_32); let b = _mm256_set1_ps(OPRND2_32); let src = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); @@ -7321,7 +7519,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_and_ps() { + const unsafe fn test_mm256_maskz_and_ps() { let a = _mm256_set1_ps(OPRND1_32); let b = _mm256_set1_ps(OPRND2_32); let r = _mm256_maskz_and_ps(0b01010101, a, b); @@ -7330,7 +7528,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_and_ps() { + const unsafe fn test_mm512_and_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let r = _mm512_and_ps(a, b); @@ -7339,7 +7537,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_and_ps() { + const unsafe fn test_mm512_mask_and_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let src = _mm512_set_ps( @@ -7354,7 +7552,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_and_ps() { + const unsafe fn test_mm512_maskz_and_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let r = _mm512_maskz_and_ps(0b0101010101010101, a, b); @@ -7366,7 +7564,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_andnot_pd() { + const unsafe fn test_mm_mask_andnot_pd() { let a = _mm_set1_pd(OPRND1_64); let b = _mm_set1_pd(OPRND2_64); let src = _mm_set_pd(1., 2.); @@ -7376,7 +7574,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_andnot_pd() { + const unsafe fn test_mm_maskz_andnot_pd() { let a = _mm_set1_pd(OPRND1_64); let b = _mm_set1_pd(OPRND2_64); let r = _mm_maskz_andnot_pd(0b01, a, b); @@ -7385,7 +7583,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_andnot_pd() { + const unsafe fn test_mm256_mask_andnot_pd() { let a = _mm256_set1_pd(OPRND1_64); let b = _mm256_set1_pd(OPRND2_64); let src = _mm256_set_pd(1., 2., 3., 4.); @@ -7395,7 +7593,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_andnot_pd() { + const unsafe fn test_mm256_maskz_andnot_pd() { let a = _mm256_set1_pd(OPRND1_64); let b = _mm256_set1_pd(OPRND2_64); let r = _mm256_maskz_andnot_pd(0b0101, a, b); @@ -7404,7 +7602,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_andnot_pd() { + const unsafe fn test_mm512_andnot_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let r = _mm512_andnot_pd(a, b); @@ -7413,7 +7611,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_andnot_pd() { + const unsafe fn test_mm512_mask_andnot_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let src = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); @@ -7423,7 +7621,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_andnot_pd() { + const unsafe fn test_mm512_maskz_andnot_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let r = _mm512_maskz_andnot_pd(0b01010101, a, b); @@ -7432,7 +7630,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_andnot_ps() { + const unsafe fn test_mm_mask_andnot_ps() { let a = _mm_set1_ps(OPRND1_32); let b = _mm_set1_ps(OPRND2_32); let src = _mm_set_ps(1., 2., 3., 4.); @@ -7442,7 +7640,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_andnot_ps() { + const unsafe fn test_mm_maskz_andnot_ps() { let a = _mm_set1_ps(OPRND1_32); let b = _mm_set1_ps(OPRND2_32); let r = _mm_maskz_andnot_ps(0b0101, a, b); @@ -7451,7 +7649,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_andnot_ps() { + const unsafe fn test_mm256_mask_andnot_ps() { let a = _mm256_set1_ps(OPRND1_32); let b = _mm256_set1_ps(OPRND2_32); let src = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); @@ -7461,7 +7659,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_andnot_ps() { + const unsafe fn test_mm256_maskz_andnot_ps() { let a = _mm256_set1_ps(OPRND1_32); let b = _mm256_set1_ps(OPRND2_32); let r = _mm256_maskz_andnot_ps(0b01010101, a, b); @@ -7470,7 +7668,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_andnot_ps() { + const unsafe fn test_mm512_andnot_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let r = _mm512_andnot_ps(a, b); @@ -7479,7 +7677,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_andnot_ps() { + const unsafe fn test_mm512_mask_andnot_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let src = _mm512_set_ps( @@ -7494,7 +7692,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_andnot_ps() { + const unsafe fn test_mm512_maskz_andnot_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let r = _mm512_maskz_andnot_ps(0b0101010101010101, a, b); @@ -7506,7 +7704,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_or_pd() { + const unsafe fn test_mm_mask_or_pd() { let a = _mm_set1_pd(OPRND1_64); let b = _mm_set1_pd(OPRND2_64); let src = _mm_set_pd(1., 2.); @@ -7516,7 +7714,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_or_pd() { + const unsafe fn test_mm_maskz_or_pd() { let a = _mm_set1_pd(OPRND1_64); let b = _mm_set1_pd(OPRND2_64); let r = _mm_maskz_or_pd(0b01, a, b); @@ -7525,7 +7723,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_or_pd() { + const unsafe fn test_mm256_mask_or_pd() { let a = _mm256_set1_pd(OPRND1_64); let b = _mm256_set1_pd(OPRND2_64); let src = _mm256_set_pd(1., 2., 3., 4.); @@ -7535,7 +7733,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_or_pd() { + const unsafe fn test_mm256_maskz_or_pd() { let a = _mm256_set1_pd(OPRND1_64); let b = _mm256_set1_pd(OPRND2_64); let r = _mm256_maskz_or_pd(0b0101, a, b); @@ -7544,7 +7742,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_or_pd() { + const unsafe fn test_mm512_or_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let r = _mm512_or_pd(a, b); @@ -7553,7 +7751,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_or_pd() { + const unsafe fn test_mm512_mask_or_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let src = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); @@ -7563,7 +7761,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_or_pd() { + const unsafe fn test_mm512_maskz_or_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let r = _mm512_maskz_or_pd(0b01010101, a, b); @@ -7572,7 +7770,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_or_ps() { + const unsafe fn test_mm_mask_or_ps() { let a = _mm_set1_ps(OPRND1_32); let b = _mm_set1_ps(OPRND2_32); let src = _mm_set_ps(1., 2., 3., 4.); @@ -7582,7 +7780,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_or_ps() { + const unsafe fn test_mm_maskz_or_ps() { let a = _mm_set1_ps(OPRND1_32); let b = _mm_set1_ps(OPRND2_32); let r = _mm_maskz_or_ps(0b0101, a, b); @@ -7591,7 +7789,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_or_ps() { + const unsafe fn test_mm256_mask_or_ps() { let a = _mm256_set1_ps(OPRND1_32); let b = _mm256_set1_ps(OPRND2_32); let src = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); @@ -7601,7 +7799,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_or_ps() { + const unsafe fn test_mm256_maskz_or_ps() { let a = _mm256_set1_ps(OPRND1_32); let b = _mm256_set1_ps(OPRND2_32); let r = _mm256_maskz_or_ps(0b01010101, a, b); @@ -7610,7 +7808,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_or_ps() { + const unsafe fn test_mm512_or_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let r = _mm512_or_ps(a, b); @@ -7619,7 +7817,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_or_ps() { + const unsafe fn test_mm512_mask_or_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let src = _mm512_set_ps( @@ -7634,7 +7832,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_or_ps() { + const unsafe fn test_mm512_maskz_or_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let r = _mm512_maskz_or_ps(0b0101010101010101, a, b); @@ -7645,7 +7843,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_xor_pd() { + const unsafe fn test_mm_mask_xor_pd() { let a = _mm_set1_pd(OPRND1_64); let b = _mm_set1_pd(OPRND2_64); let src = _mm_set_pd(1., 2.); @@ -7655,7 +7853,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_xor_pd() { + const unsafe fn test_mm_maskz_xor_pd() { let a = _mm_set1_pd(OPRND1_64); let b = _mm_set1_pd(OPRND2_64); let r = _mm_maskz_xor_pd(0b01, a, b); @@ -7664,7 +7862,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_xor_pd() { + const unsafe fn test_mm256_mask_xor_pd() { let a = _mm256_set1_pd(OPRND1_64); let b = _mm256_set1_pd(OPRND2_64); let src = _mm256_set_pd(1., 2., 3., 4.); @@ -7674,7 +7872,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_xor_pd() { + const unsafe fn test_mm256_maskz_xor_pd() { let a = _mm256_set1_pd(OPRND1_64); let b = _mm256_set1_pd(OPRND2_64); let r = _mm256_maskz_xor_pd(0b0101, a, b); @@ -7683,7 +7881,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_xor_pd() { + const unsafe fn test_mm512_xor_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let r = _mm512_xor_pd(a, b); @@ -7692,7 +7890,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_xor_pd() { + const unsafe fn test_mm512_mask_xor_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let src = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); @@ -7702,7 +7900,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_xor_pd() { + const unsafe fn test_mm512_maskz_xor_pd() { let a = _mm512_set1_pd(OPRND1_64); let b = _mm512_set1_pd(OPRND2_64); let r = _mm512_maskz_xor_pd(0b01010101, a, b); @@ -7711,7 +7909,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_xor_ps() { + const unsafe fn test_mm_mask_xor_ps() { let a = _mm_set1_ps(OPRND1_32); let b = _mm_set1_ps(OPRND2_32); let src = _mm_set_ps(1., 2., 3., 4.); @@ -7721,7 +7919,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_xor_ps() { + const unsafe fn test_mm_maskz_xor_ps() { let a = _mm_set1_ps(OPRND1_32); let b = _mm_set1_ps(OPRND2_32); let r = _mm_maskz_xor_ps(0b0101, a, b); @@ -7730,7 +7928,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_xor_ps() { + const unsafe fn test_mm256_mask_xor_ps() { let a = _mm256_set1_ps(OPRND1_32); let b = _mm256_set1_ps(OPRND2_32); let src = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); @@ -7740,7 +7938,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_xor_ps() { + const unsafe fn test_mm256_maskz_xor_ps() { let a = _mm256_set1_ps(OPRND1_32); let b = _mm256_set1_ps(OPRND2_32); let r = _mm256_maskz_xor_ps(0b01010101, a, b); @@ -7749,7 +7947,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_xor_ps() { + const unsafe fn test_mm512_xor_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let r = _mm512_xor_ps(a, b); @@ -7758,7 +7956,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_xor_ps() { + const unsafe fn test_mm512_mask_xor_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let src = _mm512_set_ps( @@ -7773,7 +7971,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_xor_ps() { + const unsafe fn test_mm512_maskz_xor_ps() { let a = _mm512_set1_ps(OPRND1_32); let b = _mm512_set1_ps(OPRND2_32); let r = _mm512_maskz_xor_ps(0b0101010101010101, a, b); @@ -7785,7 +7983,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_broadcast_f32x2() { + const unsafe fn test_mm256_broadcast_f32x2() { let a = _mm_set_ps(1., 2., 3., 4.); let r = _mm256_broadcast_f32x2(a); let e = _mm256_set_ps(3., 4., 3., 4., 3., 4., 3., 4.); @@ -7793,7 +7991,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_broadcast_f32x2() { + const unsafe fn test_mm256_mask_broadcast_f32x2() { let a = _mm_set_ps(1., 2., 3., 4.); let b = _mm256_set_ps(5., 6., 7., 8., 9., 10., 11., 12.); let r = _mm256_mask_broadcast_f32x2(b, 0b01101001, a); @@ -7802,7 +8000,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_broadcast_f32x2() { + const unsafe fn test_mm256_maskz_broadcast_f32x2() { let a = _mm_set_ps(1., 2., 3., 4.); let r = _mm256_maskz_broadcast_f32x2(0b01101001, a); let e = _mm256_set_ps(0., 4., 3., 0., 3., 0., 0., 4.); @@ -7810,7 +8008,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_broadcast_f32x2() { + const unsafe fn test_mm512_broadcast_f32x2() { let a = _mm_set_ps(1., 2., 3., 4.); let r = _mm512_broadcast_f32x2(a); let e = _mm512_set_ps( @@ -7820,7 +8018,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_broadcast_f32x2() { + const unsafe fn test_mm512_mask_broadcast_f32x2() { let a = _mm_set_ps(1., 2., 3., 4.); let b = _mm512_set_ps( 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., @@ -7833,7 +8031,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_broadcast_f32x2() { + const unsafe fn test_mm512_maskz_broadcast_f32x2() { let a = _mm_set_ps(1., 2., 3., 4.); let r = _mm512_maskz_broadcast_f32x2(0b0110100100111100, a); let e = _mm512_set_ps( @@ -7843,7 +8041,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_broadcast_f32x8() { + const unsafe fn test_mm512_broadcast_f32x8() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_broadcast_f32x8(a); let e = _mm512_set_ps( @@ -7853,7 +8051,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_broadcast_f32x8() { + const unsafe fn test_mm512_mask_broadcast_f32x8() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm512_set_ps( 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., @@ -7866,7 +8064,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_broadcast_f32x8() { + const unsafe fn test_mm512_maskz_broadcast_f32x8() { let a = _mm256_set_ps(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_maskz_broadcast_f32x8(0b0110100100111100, a); let e = _mm512_set_ps( @@ -7876,7 +8074,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_broadcast_f64x2() { + const unsafe fn test_mm256_broadcast_f64x2() { let a = _mm_set_pd(1., 2.); let r = _mm256_broadcast_f64x2(a); let e = _mm256_set_pd(1., 2., 1., 2.); @@ -7884,7 +8082,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_broadcast_f64x2() { + const unsafe fn test_mm256_mask_broadcast_f64x2() { let a = _mm_set_pd(1., 2.); let b = _mm256_set_pd(3., 4., 5., 6.); let r = _mm256_mask_broadcast_f64x2(b, 0b0110, a); @@ -7893,7 +8091,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_broadcast_f64x2() { + const unsafe fn test_mm256_maskz_broadcast_f64x2() { let a = _mm_set_pd(1., 2.); let r = _mm256_maskz_broadcast_f64x2(0b0110, a); let e = _mm256_set_pd(0., 2., 1., 0.); @@ -7901,7 +8099,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_broadcast_f64x2() { + const unsafe fn test_mm512_broadcast_f64x2() { let a = _mm_set_pd(1., 2.); let r = _mm512_broadcast_f64x2(a); let e = _mm512_set_pd(1., 2., 1., 2., 1., 2., 1., 2.); @@ -7909,7 +8107,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_broadcast_f64x2() { + const unsafe fn test_mm512_mask_broadcast_f64x2() { let a = _mm_set_pd(1., 2.); let b = _mm512_set_pd(3., 4., 5., 6., 7., 8., 9., 10.); let r = _mm512_mask_broadcast_f64x2(b, 0b01101001, a); @@ -7918,7 +8116,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_broadcast_f64x2() { + const unsafe fn test_mm512_maskz_broadcast_f64x2() { let a = _mm_set_pd(1., 2.); let r = _mm512_maskz_broadcast_f64x2(0b01101001, a); let e = _mm512_set_pd(0., 2., 1., 0., 1., 0., 0., 2.); @@ -7926,7 +8124,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_broadcast_i32x2() { + const unsafe fn test_mm_broadcast_i32x2() { let a = _mm_set_epi32(1, 2, 3, 4); let r = _mm_broadcast_i32x2(a); let e = _mm_set_epi32(3, 4, 3, 4); @@ -7934,7 +8132,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_broadcast_i32x2() { + const unsafe fn test_mm_mask_broadcast_i32x2() { let a = _mm_set_epi32(1, 2, 3, 4); let b = _mm_set_epi32(5, 6, 7, 8); let r = _mm_mask_broadcast_i32x2(b, 0b0110, a); @@ -7943,7 +8141,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_broadcast_i32x2() { + const unsafe fn test_mm_maskz_broadcast_i32x2() { let a = _mm_set_epi32(1, 2, 3, 4); let r = _mm_maskz_broadcast_i32x2(0b0110, a); let e = _mm_set_epi32(0, 4, 3, 0); @@ -7951,7 +8149,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_broadcast_i32x2() { + const unsafe fn test_mm256_broadcast_i32x2() { let a = _mm_set_epi32(1, 2, 3, 4); let r = _mm256_broadcast_i32x2(a); let e = _mm256_set_epi32(3, 4, 3, 4, 3, 4, 3, 4); @@ -7959,7 +8157,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_broadcast_i32x2() { + const unsafe fn test_mm256_mask_broadcast_i32x2() { let a = _mm_set_epi32(1, 2, 3, 4); let b = _mm256_set_epi32(5, 6, 7, 8, 9, 10, 11, 12); let r = _mm256_mask_broadcast_i32x2(b, 0b01101001, a); @@ -7968,7 +8166,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_broadcast_i32x2() { + const unsafe fn test_mm256_maskz_broadcast_i32x2() { let a = _mm_set_epi32(1, 2, 3, 4); let r = _mm256_maskz_broadcast_i32x2(0b01101001, a); let e = _mm256_set_epi32(0, 4, 3, 0, 3, 0, 0, 4); @@ -7976,7 +8174,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_broadcast_i32x2() { + const unsafe fn test_mm512_broadcast_i32x2() { let a = _mm_set_epi32(1, 2, 3, 4); let r = _mm512_broadcast_i32x2(a); let e = _mm512_set_epi32(3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4); @@ -7984,7 +8182,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_broadcast_i32x2() { + const unsafe fn test_mm512_mask_broadcast_i32x2() { let a = _mm_set_epi32(1, 2, 3, 4); let b = _mm512_set_epi32(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); let r = _mm512_mask_broadcast_i32x2(b, 0b0110100100111100, a); @@ -7993,7 +8191,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_broadcast_i32x2() { + const unsafe fn test_mm512_maskz_broadcast_i32x2() { let a = _mm_set_epi32(1, 2, 3, 4); let r = _mm512_maskz_broadcast_i32x2(0b0110100100111100, a); let e = _mm512_set_epi32(0, 4, 3, 0, 3, 0, 0, 4, 0, 0, 3, 4, 3, 4, 0, 0); @@ -8001,7 +8199,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_broadcast_i32x8() { + const unsafe fn test_mm512_broadcast_i32x8() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm512_broadcast_i32x8(a); let e = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8); @@ -8009,7 +8207,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_broadcast_i32x8() { + const unsafe fn test_mm512_mask_broadcast_i32x8() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi32( 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, @@ -8020,7 +8218,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_broadcast_i32x8() { + const unsafe fn test_mm512_maskz_broadcast_i32x8() { let a = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm512_maskz_broadcast_i32x8(0b0110100100111100, a); let e = _mm512_set_epi32(0, 2, 3, 0, 5, 0, 0, 8, 0, 0, 3, 4, 5, 6, 0, 0); @@ -8028,7 +8226,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_broadcast_i64x2() { + const unsafe fn test_mm256_broadcast_i64x2() { let a = _mm_set_epi64x(1, 2); let r = _mm256_broadcast_i64x2(a); let e = _mm256_set_epi64x(1, 2, 1, 2); @@ -8036,7 +8234,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_broadcast_i64x2() { + const unsafe fn test_mm256_mask_broadcast_i64x2() { let a = _mm_set_epi64x(1, 2); let b = _mm256_set_epi64x(3, 4, 5, 6); let r = _mm256_mask_broadcast_i64x2(b, 0b0110, a); @@ -8045,7 +8243,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_broadcast_i64x2() { + const unsafe fn test_mm256_maskz_broadcast_i64x2() { let a = _mm_set_epi64x(1, 2); let r = _mm256_maskz_broadcast_i64x2(0b0110, a); let e = _mm256_set_epi64x(0, 2, 1, 0); @@ -8053,7 +8251,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_broadcast_i64x2() { + const unsafe fn test_mm512_broadcast_i64x2() { let a = _mm_set_epi64x(1, 2); let r = _mm512_broadcast_i64x2(a); let e = _mm512_set_epi64(1, 2, 1, 2, 1, 2, 1, 2); @@ -8061,7 +8259,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_broadcast_i64x2() { + const unsafe fn test_mm512_mask_broadcast_i64x2() { let a = _mm_set_epi64x(1, 2); let b = _mm512_set_epi64(3, 4, 5, 6, 7, 8, 9, 10); let r = _mm512_mask_broadcast_i64x2(b, 0b01101001, a); @@ -8070,7 +8268,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_broadcast_i64x2() { + const unsafe fn test_mm512_maskz_broadcast_i64x2() { let a = _mm_set_epi64x(1, 2); let r = _mm512_maskz_broadcast_i64x2(0b01101001, a); let e = _mm512_set_epi64(0, 2, 1, 0, 1, 0, 0, 2); @@ -8078,7 +8276,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_extractf32x8_ps() { + const unsafe fn test_mm512_extractf32x8_ps() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -8088,7 +8286,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_extractf32x8_ps() { + const unsafe fn test_mm512_mask_extractf32x8_ps() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -8099,7 +8297,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_extractf32x8_ps() { + const unsafe fn test_mm512_maskz_extractf32x8_ps() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -8109,7 +8307,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_extractf64x2_pd() { + const unsafe fn test_mm256_extractf64x2_pd() { let a = _mm256_set_pd(1., 2., 3., 4.); let r = _mm256_extractf64x2_pd::<1>(a); let e = _mm_set_pd(1., 2.); @@ -8117,7 +8315,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_extractf64x2_pd() { + const unsafe fn test_mm256_mask_extractf64x2_pd() { let a = _mm256_set_pd(1., 2., 3., 4.); let b = _mm_set_pd(5., 6.); let r = _mm256_mask_extractf64x2_pd::<1>(b, 0b01, a); @@ -8126,7 +8324,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_extractf64x2_pd() { + const unsafe fn test_mm256_maskz_extractf64x2_pd() { let a = _mm256_set_pd(1., 2., 3., 4.); let r = _mm256_maskz_extractf64x2_pd::<1>(0b01, a); let e = _mm_set_pd(0., 2.); @@ -8134,7 +8332,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_extractf64x2_pd() { + const unsafe fn test_mm512_extractf64x2_pd() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_extractf64x2_pd::<2>(a); let e = _mm_set_pd(3., 4.); @@ -8142,7 +8340,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_extractf64x2_pd() { + const unsafe fn test_mm512_mask_extractf64x2_pd() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm_set_pd(9., 10.); let r = _mm512_mask_extractf64x2_pd::<2>(b, 0b01, a); @@ -8151,7 +8349,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_extractf64x2_pd() { + const unsafe fn test_mm512_maskz_extractf64x2_pd() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_maskz_extractf64x2_pd::<2>(0b01, a); let e = _mm_set_pd(0., 4.); @@ -8159,7 +8357,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_extracti32x8_epi32() { + const unsafe fn test_mm512_extracti32x8_epi32() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_extracti32x8_epi32::<1>(a); let e = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); @@ -8167,7 +8365,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_extracti32x8_epi32() { + const unsafe fn test_mm512_mask_extracti32x8_epi32() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm256_set_epi32(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_mask_extracti32x8_epi32::<1>(b, 0b01101001, a); @@ -8176,7 +8374,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_extracti32x8_epi32() { + const unsafe fn test_mm512_maskz_extracti32x8_epi32() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_maskz_extracti32x8_epi32::<1>(0b01101001, a); let e = _mm256_set_epi32(0, 2, 3, 0, 5, 0, 0, 8); @@ -8184,7 +8382,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_extracti64x2_epi64() { + const unsafe fn test_mm256_extracti64x2_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let r = _mm256_extracti64x2_epi64::<1>(a); let e = _mm_set_epi64x(1, 2); @@ -8192,7 +8390,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_extracti64x2_epi64() { + const unsafe fn test_mm256_mask_extracti64x2_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm_set_epi64x(5, 6); let r = _mm256_mask_extracti64x2_epi64::<1>(b, 0b01, a); @@ -8201,7 +8399,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_extracti64x2_epi64() { + const unsafe fn test_mm256_maskz_extracti64x2_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let r = _mm256_maskz_extracti64x2_epi64::<1>(0b01, a); let e = _mm_set_epi64x(0, 2); @@ -8209,7 +8407,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_extracti64x2_epi64() { + const unsafe fn test_mm512_extracti64x2_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm512_extracti64x2_epi64::<2>(a); let e = _mm_set_epi64x(3, 4); @@ -8217,7 +8415,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_extracti64x2_epi64() { + const unsafe fn test_mm512_mask_extracti64x2_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi64x(9, 10); let r = _mm512_mask_extracti64x2_epi64::<2>(b, 0b01, a); @@ -8226,7 +8424,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_extracti64x2_epi64() { + const unsafe fn test_mm512_maskz_extracti64x2_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm512_maskz_extracti64x2_epi64::<2>(0b01, a); let e = _mm_set_epi64x(0, 4); @@ -8234,7 +8432,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_insertf32x8() { + const unsafe fn test_mm512_insertf32x8() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -8247,7 +8445,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_insertf32x8() { + const unsafe fn test_mm512_mask_insertf32x8() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -8263,7 +8461,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_insertf32x8() { + const unsafe fn test_mm512_maskz_insertf32x8() { let a = _mm512_set_ps( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -8276,7 +8474,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_insertf64x2() { + const unsafe fn test_mm256_insertf64x2() { let a = _mm256_set_pd(1., 2., 3., 4.); let b = _mm_set_pd(5., 6.); let r = _mm256_insertf64x2::<1>(a, b); @@ -8285,7 +8483,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_insertf64x2() { + const unsafe fn test_mm256_mask_insertf64x2() { let a = _mm256_set_pd(1., 2., 3., 4.); let b = _mm_set_pd(5., 6.); let src = _mm256_set_pd(7., 8., 9., 10.); @@ -8295,7 +8493,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_insertf64x2() { + const unsafe fn test_mm256_maskz_insertf64x2() { let a = _mm256_set_pd(1., 2., 3., 4.); let b = _mm_set_pd(5., 6.); let r = _mm256_maskz_insertf64x2::<1>(0b0110, a, b); @@ -8304,7 +8502,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_insertf64x2() { + const unsafe fn test_mm512_insertf64x2() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm_set_pd(9., 10.); let r = _mm512_insertf64x2::<2>(a, b); @@ -8313,7 +8511,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_insertf64x2() { + const unsafe fn test_mm512_mask_insertf64x2() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm_set_pd(9., 10.); let src = _mm512_set_pd(11., 12., 13., 14., 15., 16., 17., 18.); @@ -8323,7 +8521,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_insertf64x2() { + const unsafe fn test_mm512_maskz_insertf64x2() { let a = _mm512_set_pd(1., 2., 3., 4., 5., 6., 7., 8.); let b = _mm_set_pd(9., 10.); let r = _mm512_maskz_insertf64x2::<2>(0b01101001, a, b); @@ -8332,7 +8530,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_inserti32x8() { + const unsafe fn test_mm512_inserti32x8() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm256_set_epi32(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_inserti32x8::<1>(a, b); @@ -8343,7 +8541,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_inserti32x8() { + const unsafe fn test_mm512_mask_inserti32x8() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm256_set_epi32(17, 18, 19, 20, 21, 22, 23, 24); let src = _mm512_set_epi32( @@ -8357,7 +8555,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_inserti32x8() { + const unsafe fn test_mm512_maskz_inserti32x8() { let a = _mm512_set_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let b = _mm256_set_epi32(17, 18, 19, 20, 21, 22, 23, 24); let r = _mm512_maskz_inserti32x8::<1>(0b0110100100111100, a, b); @@ -8366,7 +8564,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_inserti64x2() { + const unsafe fn test_mm256_inserti64x2() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm_set_epi64x(5, 6); let r = _mm256_inserti64x2::<1>(a, b); @@ -8375,7 +8573,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_inserti64x2() { + const unsafe fn test_mm256_mask_inserti64x2() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm_set_epi64x(5, 6); let src = _mm256_set_epi64x(7, 8, 9, 10); @@ -8385,7 +8583,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_inserti64x2() { + const unsafe fn test_mm256_maskz_inserti64x2() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm_set_epi64x(5, 6); let r = _mm256_maskz_inserti64x2::<1>(0b0110, a, b); @@ -8394,7 +8592,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_inserti64x2() { + const unsafe fn test_mm512_inserti64x2() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi64x(9, 10); let r = _mm512_inserti64x2::<2>(a, b); @@ -8403,7 +8601,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_inserti64x2() { + const unsafe fn test_mm512_mask_inserti64x2() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi64x(9, 10); let src = _mm512_set_epi64(11, 12, 13, 14, 15, 16, 17, 18); @@ -8413,7 +8611,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_inserti64x2() { + const unsafe fn test_mm512_maskz_inserti64x2() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_set_epi64x(9, 10); let r = _mm512_maskz_inserti64x2::<2>(0b01101001, a, b); @@ -9654,7 +9852,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mullo_epi64() { + const unsafe fn test_mm_mullo_epi64() { let a = _mm_set_epi64x(1, 2); let b = _mm_set_epi64x(3, 4); let r = _mm_mullo_epi64(a, b); @@ -9663,7 +9861,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_mask_mullo_epi64() { + const unsafe fn test_mm_mask_mullo_epi64() { let a = _mm_set_epi64x(1, 2); let b = _mm_set_epi64x(3, 4); let c = _mm_set_epi64x(5, 6); @@ -9673,7 +9871,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_maskz_mullo_epi64() { + const unsafe fn test_mm_maskz_mullo_epi64() { let a = _mm_set_epi64x(1, 2); let b = _mm_set_epi64x(3, 4); let r = _mm_maskz_mullo_epi64(0b01, a, b); @@ -9682,7 +9880,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mullo_epi64() { + const unsafe fn test_mm256_mullo_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm256_set_epi64x(5, 6, 7, 8); let r = _mm256_mullo_epi64(a, b); @@ -9691,7 +9889,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_mask_mullo_epi64() { + const unsafe fn test_mm256_mask_mullo_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm256_set_epi64x(5, 6, 7, 8); let c = _mm256_set_epi64x(9, 10, 11, 12); @@ -9701,7 +9899,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_maskz_mullo_epi64() { + const unsafe fn test_mm256_maskz_mullo_epi64() { let a = _mm256_set_epi64x(1, 2, 3, 4); let b = _mm256_set_epi64x(5, 6, 7, 8); let r = _mm256_maskz_mullo_epi64(0b0110, a, b); @@ -9710,7 +9908,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mullo_epi64() { + const unsafe fn test_mm512_mullo_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi64(9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_mullo_epi64(a, b); @@ -9719,7 +9917,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_mask_mullo_epi64() { + const unsafe fn test_mm512_mask_mullo_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi64(9, 10, 11, 12, 13, 14, 15, 16); let c = _mm512_set_epi64(17, 18, 19, 20, 21, 22, 23, 24); @@ -9729,7 +9927,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_maskz_mullo_epi64() { + const unsafe fn test_mm512_maskz_mullo_epi64() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm512_set_epi64(9, 10, 11, 12, 13, 14, 15, 16); let r = _mm512_maskz_mullo_epi64(0b01101001, a, b); @@ -9738,7 +9936,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_cvtmask8_u32() { + const unsafe fn test_cvtmask8_u32() { let a: __mmask8 = 0b01101001; let r = _cvtmask8_u32(a); let e: u32 = 0b01101001; @@ -9746,7 +9944,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_cvtu32_mask8() { + const unsafe fn test_cvtu32_mask8() { let a: u32 = 0b01101001; let r = _cvtu32_mask8(a); let e: __mmask8 = 0b01101001; @@ -9754,7 +9952,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kadd_mask16() { + const unsafe fn test_kadd_mask16() { let a: __mmask16 = 27549; let b: __mmask16 = 23434; let r = _kadd_mask16(a, b); @@ -9763,7 +9961,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kadd_mask8() { + const unsafe fn test_kadd_mask8() { let a: __mmask8 = 98; let b: __mmask8 = 117; let r = _kadd_mask8(a, b); @@ -9772,7 +9970,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kand_mask8() { + const unsafe fn test_kand_mask8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10110011; let r = _kand_mask8(a, b); @@ -9781,7 +9979,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kandn_mask8() { + const unsafe fn test_kandn_mask8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10110011; let r = _kandn_mask8(a, b); @@ -9790,7 +9988,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_knot_mask8() { + const unsafe fn test_knot_mask8() { let a: __mmask8 = 0b01101001; let r = _knot_mask8(a); let e: __mmask8 = 0b10010110; @@ -9798,7 +9996,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kor_mask8() { + const unsafe fn test_kor_mask8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10110011; let r = _kor_mask8(a, b); @@ -9807,7 +10005,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kxnor_mask8() { + const unsafe fn test_kxnor_mask8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10110011; let r = _kxnor_mask8(a, b); @@ -9816,7 +10014,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kxor_mask8() { + const unsafe fn test_kxor_mask8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10110011; let r = _kxor_mask8(a, b); @@ -9825,7 +10023,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kortest_mask8_u8() { + const unsafe fn test_kortest_mask8_u8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10110110; let mut all_ones: u8 = 0; @@ -9835,7 +10033,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kortestc_mask8_u8() { + const unsafe fn test_kortestc_mask8_u8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10110110; let r = _kortestc_mask8_u8(a, b); @@ -9843,7 +10041,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kortestz_mask8_u8() { + const unsafe fn test_kortestz_mask8_u8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10110110; let r = _kortestz_mask8_u8(a, b); @@ -9851,7 +10049,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kshiftli_mask8() { + const unsafe fn test_kshiftli_mask8() { let a: __mmask8 = 0b01101001; let r = _kshiftli_mask8::<3>(a); let e: __mmask8 = 0b01001000; @@ -9871,7 +10069,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_kshiftri_mask8() { + const unsafe fn test_kshiftri_mask8() { let a: __mmask8 = 0b10101001; let r = _kshiftri_mask8::<3>(a); let e: __mmask8 = 0b00010101; @@ -9891,7 +10089,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_ktest_mask8_u8() { + const unsafe fn test_ktest_mask8_u8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10010110; let mut and_not: u8 = 0; @@ -9901,7 +10099,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_ktestc_mask8_u8() { + const unsafe fn test_ktestc_mask8_u8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10010110; let r = _ktestc_mask8_u8(a, b); @@ -9909,7 +10107,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_ktestz_mask8_u8() { + const unsafe fn test_ktestz_mask8_u8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10010110; let r = _ktestz_mask8_u8(a, b); @@ -9917,7 +10115,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_ktest_mask16_u8() { + const unsafe fn test_ktest_mask16_u8() { let a: __mmask16 = 0b0110100100111100; let b: __mmask16 = 0b1001011011000011; let mut and_not: u8 = 0; @@ -9927,7 +10125,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_ktestc_mask16_u8() { + const unsafe fn test_ktestc_mask16_u8() { let a: __mmask16 = 0b0110100100111100; let b: __mmask16 = 0b1001011011000011; let r = _ktestc_mask16_u8(a, b); @@ -9935,7 +10133,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_ktestz_mask16_u8() { + const unsafe fn test_ktestz_mask16_u8() { let a: __mmask16 = 0b0110100100111100; let b: __mmask16 = 0b1001011011000011; let r = _ktestz_mask16_u8(a, b); @@ -9943,7 +10141,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_load_mask8() { + const unsafe fn test_load_mask8() { let a: __mmask8 = 0b01101001; let r = _load_mask8(&a); let e: __mmask8 = 0b01101001; @@ -9951,7 +10149,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_store_mask8() { + const unsafe fn test_store_mask8() { let a: __mmask8 = 0b01101001; let mut r = 0; _store_mask8(&mut r, a); @@ -9960,7 +10158,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_movepi32_mask() { + const unsafe fn test_mm_movepi32_mask() { let a = _mm_set_epi32(0, -2, -3, 4); let r = _mm_movepi32_mask(a); let e = 0b0110; @@ -9968,7 +10166,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_movepi32_mask() { + const unsafe fn test_mm256_movepi32_mask() { let a = _mm256_set_epi32(0, -2, -3, 4, -5, 6, 7, -8); let r = _mm256_movepi32_mask(a); let e = 0b01101001; @@ -9976,7 +10174,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_movepi32_mask() { + const unsafe fn test_mm512_movepi32_mask() { let a = _mm512_set_epi32( 0, -2, -3, 4, -5, 6, 7, -8, 9, 10, -11, -12, -13, -14, 15, 16, ); @@ -9986,7 +10184,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_movepi64_mask() { + const unsafe fn test_mm_movepi64_mask() { let a = _mm_set_epi64x(0, -2); let r = _mm_movepi64_mask(a); let e = 0b01; @@ -9994,7 +10192,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_movepi64_mask() { + const unsafe fn test_mm256_movepi64_mask() { let a = _mm256_set_epi64x(0, -2, -3, 4); let r = _mm256_movepi64_mask(a); let e = 0b0110; @@ -10002,7 +10200,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_movepi64_mask() { + const unsafe fn test_mm512_movepi64_mask() { let a = _mm512_set_epi64(0, -2, -3, 4, -5, 6, 7, -8); let r = _mm512_movepi64_mask(a); let e = 0b01101001; @@ -10010,7 +10208,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_movm_epi32() { + const unsafe fn test_mm_movm_epi32() { let a = 0b0110; let r = _mm_movm_epi32(a); let e = _mm_set_epi32(0, -1, -1, 0); @@ -10018,7 +10216,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_movm_epi32() { + const unsafe fn test_mm256_movm_epi32() { let a = 0b01101001; let r = _mm256_movm_epi32(a); let e = _mm256_set_epi32(0, -1, -1, 0, -1, 0, 0, -1); @@ -10026,7 +10224,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_movm_epi32() { + const unsafe fn test_mm512_movm_epi32() { let a = 0b0110100100111100; let r = _mm512_movm_epi32(a); let e = _mm512_set_epi32(0, -1, -1, 0, -1, 0, 0, -1, 0, 0, -1, -1, -1, -1, 0, 0); @@ -10034,7 +10232,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm_movm_epi64() { + const unsafe fn test_mm_movm_epi64() { let a = 0b01; let r = _mm_movm_epi64(a); let e = _mm_set_epi64x(0, -1); @@ -10042,7 +10240,7 @@ mod tests { } #[simd_test(enable = "avx512dq,avx512vl")] - unsafe fn test_mm256_movm_epi64() { + const unsafe fn test_mm256_movm_epi64() { let a = 0b0110; let r = _mm256_movm_epi64(a); let e = _mm256_set_epi64x(0, -1, -1, 0); @@ -10050,7 +10248,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - unsafe fn test_mm512_movm_epi64() { + const unsafe fn test_mm512_movm_epi64() { let a = 0b01101001; let r = _mm512_movm_epi64(a); let e = _mm512_set_epi64(0, -1, -1, 0, -1, 0, 0, -1); From 6695809811f597cb654fb817fbcbc54c03a00669 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:26:40 +0530 Subject: [PATCH 0238/3801] Make `avx512vbmi2` functions const --- .../crates/core_arch/src/x86/avx512vbmi2.rs | 613 ++++++++++++------ 1 file changed, 397 insertions(+), 216 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs b/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs index e25fd4528dc2..da268f969c37 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs @@ -499,7 +499,8 @@ pub fn _mm_maskz_expand_epi8(k: __mmask16, a: __m128i) -> __m128i { #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] -pub fn _mm512_shldv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shldv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shl( a.as_i64x8(), @@ -516,7 +517,8 @@ pub fn _mm512_shldv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] -pub fn _mm512_mask_shldv_epi64(a: __m512i, k: __mmask8, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shldv_epi64(a: __m512i, k: __mmask8, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shldv_epi64(a, b, c).as_i64x8(); transmute(simd_select_bitmask(k, shf, a.as_i64x8())) @@ -530,7 +532,8 @@ pub fn _mm512_mask_shldv_epi64(a: __m512i, k: __mmask8, b: __m512i, c: __m512i) #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] -pub fn _mm512_maskz_shldv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shldv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shldv_epi64(a, b, c).as_i64x8(); transmute(simd_select_bitmask(k, shf, i64x8::ZERO)) @@ -544,7 +547,8 @@ pub fn _mm512_maskz_shldv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] -pub fn _mm256_shldv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shldv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shl( a.as_i64x4(), @@ -561,7 +565,8 @@ pub fn _mm256_shldv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] -pub fn _mm256_mask_shldv_epi64(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shldv_epi64(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shldv_epi64(a, b, c).as_i64x4(); transmute(simd_select_bitmask(k, shf, a.as_i64x4())) @@ -575,7 +580,8 @@ pub fn _mm256_mask_shldv_epi64(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] -pub fn _mm256_maskz_shldv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shldv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shldv_epi64(a, b, c).as_i64x4(); transmute(simd_select_bitmask(k, shf, i64x4::ZERO)) @@ -589,7 +595,8 @@ pub fn _mm256_maskz_shldv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] -pub fn _mm_shldv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shldv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shl( a.as_i64x2(), @@ -606,7 +613,8 @@ pub fn _mm_shldv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] -pub fn _mm_mask_shldv_epi64(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shldv_epi64(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shldv_epi64(a, b, c).as_i64x2(); transmute(simd_select_bitmask(k, shf, a.as_i64x2())) @@ -620,7 +628,8 @@ pub fn _mm_mask_shldv_epi64(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] -pub fn _mm_maskz_shldv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shldv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shldv_epi64(a, b, c).as_i64x2(); transmute(simd_select_bitmask(k, shf, i64x2::ZERO)) @@ -634,7 +643,8 @@ pub fn _mm_maskz_shldv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] -pub fn _mm512_shldv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shldv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shl( a.as_i32x16(), @@ -651,7 +661,8 @@ pub fn _mm512_shldv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] -pub fn _mm512_mask_shldv_epi32(a: __m512i, k: __mmask16, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shldv_epi32(a: __m512i, k: __mmask16, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shldv_epi32(a, b, c).as_i32x16(); transmute(simd_select_bitmask(k, shf, a.as_i32x16())) @@ -665,7 +676,8 @@ pub fn _mm512_mask_shldv_epi32(a: __m512i, k: __mmask16, b: __m512i, c: __m512i) #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] -pub fn _mm512_maskz_shldv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shldv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shldv_epi32(a, b, c).as_i32x16(); transmute(simd_select_bitmask(k, shf, i32x16::ZERO)) @@ -679,7 +691,8 @@ pub fn _mm512_maskz_shldv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] -pub fn _mm256_shldv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shldv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shl( a.as_i32x8(), @@ -696,7 +709,8 @@ pub fn _mm256_shldv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] -pub fn _mm256_mask_shldv_epi32(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shldv_epi32(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shldv_epi32(a, b, c).as_i32x8(); transmute(simd_select_bitmask(k, shf, a.as_i32x8())) @@ -710,7 +724,8 @@ pub fn _mm256_mask_shldv_epi32(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] -pub fn _mm256_maskz_shldv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shldv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shldv_epi32(a, b, c).as_i32x8(); transmute(simd_select_bitmask(k, shf, i32x8::ZERO)) @@ -724,7 +739,8 @@ pub fn _mm256_maskz_shldv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] -pub fn _mm_shldv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shldv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shl( a.as_i32x4(), @@ -741,7 +757,8 @@ pub fn _mm_shldv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] -pub fn _mm_mask_shldv_epi32(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shldv_epi32(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shldv_epi32(a, b, c).as_i32x4(); transmute(simd_select_bitmask(k, shf, a.as_i32x4())) @@ -755,7 +772,8 @@ pub fn _mm_mask_shldv_epi32(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] -pub fn _mm_maskz_shldv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shldv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shldv_epi32(a, b, c).as_i32x4(); transmute(simd_select_bitmask(k, shf, i32x4::ZERO)) @@ -769,7 +787,8 @@ pub fn _mm_maskz_shldv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] -pub fn _mm512_shldv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shldv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shl( a.as_i16x32(), @@ -786,7 +805,8 @@ pub fn _mm512_shldv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] -pub fn _mm512_mask_shldv_epi16(a: __m512i, k: __mmask32, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shldv_epi16(a: __m512i, k: __mmask32, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shldv_epi16(a, b, c).as_i16x32(); transmute(simd_select_bitmask(k, shf, a.as_i16x32())) @@ -800,7 +820,8 @@ pub fn _mm512_mask_shldv_epi16(a: __m512i, k: __mmask32, b: __m512i, c: __m512i) #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] -pub fn _mm512_maskz_shldv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shldv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shldv_epi16(a, b, c).as_i16x32(); transmute(simd_select_bitmask(k, shf, i16x32::ZERO)) @@ -814,7 +835,8 @@ pub fn _mm512_maskz_shldv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] -pub fn _mm256_shldv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shldv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shl( a.as_i16x16(), @@ -831,7 +853,8 @@ pub fn _mm256_shldv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] -pub fn _mm256_mask_shldv_epi16(a: __m256i, k: __mmask16, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shldv_epi16(a: __m256i, k: __mmask16, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shldv_epi16(a, b, c).as_i16x16(); transmute(simd_select_bitmask(k, shf, a.as_i16x16())) @@ -845,7 +868,8 @@ pub fn _mm256_mask_shldv_epi16(a: __m256i, k: __mmask16, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] -pub fn _mm256_maskz_shldv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shldv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shldv_epi16(a, b, c).as_i16x16(); transmute(simd_select_bitmask(k, shf, i16x16::ZERO)) @@ -859,7 +883,8 @@ pub fn _mm256_maskz_shldv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] -pub fn _mm_shldv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shldv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shl( a.as_i16x8(), @@ -876,7 +901,8 @@ pub fn _mm_shldv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] -pub fn _mm_mask_shldv_epi16(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shldv_epi16(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shldv_epi16(a, b, c).as_i16x8(); transmute(simd_select_bitmask(k, shf, a.as_i16x8())) @@ -890,7 +916,8 @@ pub fn _mm_mask_shldv_epi16(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] -pub fn _mm_maskz_shldv_epi16(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shldv_epi16(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shldv_epi16(a, b, c).as_i16x8(); transmute(simd_select_bitmask(k, shf, i16x8::ZERO)) @@ -904,7 +931,8 @@ pub fn _mm_maskz_shldv_epi16(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] -pub fn _mm512_shrdv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shrdv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shr( b.as_i64x8(), @@ -921,7 +949,8 @@ pub fn _mm512_shrdv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] -pub fn _mm512_mask_shrdv_epi64(a: __m512i, k: __mmask8, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shrdv_epi64(a: __m512i, k: __mmask8, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shrdv_epi64(a, b, c).as_i64x8(); transmute(simd_select_bitmask(k, shf, a.as_i64x8())) @@ -935,7 +964,8 @@ pub fn _mm512_mask_shrdv_epi64(a: __m512i, k: __mmask8, b: __m512i, c: __m512i) #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] -pub fn _mm512_maskz_shrdv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shrdv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shrdv_epi64(a, b, c).as_i64x8(); transmute(simd_select_bitmask(k, shf, i64x8::ZERO)) @@ -949,7 +979,8 @@ pub fn _mm512_maskz_shrdv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] -pub fn _mm256_shrdv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shrdv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shr( b.as_i64x4(), @@ -966,7 +997,8 @@ pub fn _mm256_shrdv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] -pub fn _mm256_mask_shrdv_epi64(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shrdv_epi64(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shrdv_epi64(a, b, c).as_i64x4(); transmute(simd_select_bitmask(k, shf, a.as_i64x4())) @@ -980,7 +1012,8 @@ pub fn _mm256_mask_shrdv_epi64(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] -pub fn _mm256_maskz_shrdv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shrdv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shrdv_epi64(a, b, c).as_i64x4(); transmute(simd_select_bitmask(k, shf, i64x4::ZERO)) @@ -994,7 +1027,8 @@ pub fn _mm256_maskz_shrdv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] -pub fn _mm_shrdv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shrdv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shr( b.as_i64x2(), @@ -1011,7 +1045,8 @@ pub fn _mm_shrdv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] -pub fn _mm_mask_shrdv_epi64(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shrdv_epi64(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shrdv_epi64(a, b, c).as_i64x2(); transmute(simd_select_bitmask(k, shf, a.as_i64x2())) @@ -1025,7 +1060,8 @@ pub fn _mm_mask_shrdv_epi64(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] -pub fn _mm_maskz_shrdv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shrdv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shrdv_epi64(a, b, c).as_i64x2(); transmute(simd_select_bitmask(k, shf, i64x2::ZERO)) @@ -1039,7 +1075,8 @@ pub fn _mm_maskz_shrdv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] -pub fn _mm512_shrdv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shrdv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shr( b.as_i32x16(), @@ -1056,7 +1093,8 @@ pub fn _mm512_shrdv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] -pub fn _mm512_mask_shrdv_epi32(a: __m512i, k: __mmask16, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shrdv_epi32(a: __m512i, k: __mmask16, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shrdv_epi32(a, b, c).as_i32x16(); transmute(simd_select_bitmask(k, shf, a.as_i32x16())) @@ -1070,7 +1108,8 @@ pub fn _mm512_mask_shrdv_epi32(a: __m512i, k: __mmask16, b: __m512i, c: __m512i) #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] -pub fn _mm512_maskz_shrdv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shrdv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shrdv_epi32(a, b, c).as_i32x16(); transmute(simd_select_bitmask(k, shf, i32x16::ZERO)) @@ -1084,7 +1123,8 @@ pub fn _mm512_maskz_shrdv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] -pub fn _mm256_shrdv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shrdv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shr( b.as_i32x8(), @@ -1101,7 +1141,8 @@ pub fn _mm256_shrdv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] -pub fn _mm256_mask_shrdv_epi32(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shrdv_epi32(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shrdv_epi32(a, b, c).as_i32x8(); transmute(simd_select_bitmask(k, shf, a.as_i32x8())) @@ -1115,7 +1156,8 @@ pub fn _mm256_mask_shrdv_epi32(a: __m256i, k: __mmask8, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] -pub fn _mm256_maskz_shrdv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shrdv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shrdv_epi32(a, b, c).as_i32x8(); transmute(simd_select_bitmask(k, shf, i32x8::ZERO)) @@ -1129,7 +1171,8 @@ pub fn _mm256_maskz_shrdv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] -pub fn _mm_shrdv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shrdv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shr( b.as_i32x4(), @@ -1146,7 +1189,8 @@ pub fn _mm_shrdv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] -pub fn _mm_mask_shrdv_epi32(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shrdv_epi32(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shrdv_epi32(a, b, c).as_i32x4(); transmute(simd_select_bitmask(k, shf, a.as_i32x4())) @@ -1160,7 +1204,8 @@ pub fn _mm_mask_shrdv_epi32(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] -pub fn _mm_maskz_shrdv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shrdv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shrdv_epi32(a, b, c).as_i32x4(); transmute(simd_select_bitmask(k, shf, i32x4::ZERO)) @@ -1174,7 +1219,8 @@ pub fn _mm_maskz_shrdv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] -pub fn _mm512_shrdv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shrdv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { transmute(simd_funnel_shr( b.as_i16x32(), @@ -1191,7 +1237,8 @@ pub fn _mm512_shrdv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] -pub fn _mm512_mask_shrdv_epi16(a: __m512i, k: __mmask32, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shrdv_epi16(a: __m512i, k: __mmask32, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shrdv_epi16(a, b, c).as_i16x32(); transmute(simd_select_bitmask(k, shf, a.as_i16x32())) @@ -1205,7 +1252,8 @@ pub fn _mm512_mask_shrdv_epi16(a: __m512i, k: __mmask32, b: __m512i, c: __m512i) #[target_feature(enable = "avx512vbmi2")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] -pub fn _mm512_maskz_shrdv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shrdv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i) -> __m512i { unsafe { let shf = _mm512_shrdv_epi16(a, b, c).as_i16x32(); transmute(simd_select_bitmask(k, shf, i16x32::ZERO)) @@ -1219,7 +1267,8 @@ pub fn _mm512_maskz_shrdv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] -pub fn _mm256_shrdv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shrdv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { transmute(simd_funnel_shr( b.as_i16x16(), @@ -1236,7 +1285,8 @@ pub fn _mm256_shrdv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] -pub fn _mm256_mask_shrdv_epi16(a: __m256i, k: __mmask16, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shrdv_epi16(a: __m256i, k: __mmask16, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shrdv_epi16(a, b, c).as_i16x16(); transmute(simd_select_bitmask(k, shf, a.as_i16x16())) @@ -1250,7 +1300,8 @@ pub fn _mm256_mask_shrdv_epi16(a: __m256i, k: __mmask16, b: __m256i, c: __m256i) #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] -pub fn _mm256_maskz_shrdv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shrdv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i) -> __m256i { unsafe { let shf = _mm256_shrdv_epi16(a, b, c).as_i16x16(); transmute(simd_select_bitmask(k, shf, i16x16::ZERO)) @@ -1264,7 +1315,8 @@ pub fn _mm256_maskz_shrdv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] -pub fn _mm_shrdv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shrdv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(simd_funnel_shr( b.as_i16x8(), @@ -1281,7 +1333,8 @@ pub fn _mm_shrdv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] -pub fn _mm_mask_shrdv_epi16(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shrdv_epi16(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shrdv_epi16(a, b, c).as_i16x8(); transmute(simd_select_bitmask(k, shf, a.as_i16x8())) @@ -1295,7 +1348,8 @@ pub fn _mm_mask_shrdv_epi16(a: __m128i, k: __mmask8, b: __m128i, c: __m128i) -> #[target_feature(enable = "avx512vbmi2,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] -pub fn _mm_maskz_shrdv_epi16(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shrdv_epi16(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { let shf = _mm_shrdv_epi16(a, b, c).as_i16x8(); transmute(simd_select_bitmask(k, shf, i16x8::ZERO)) @@ -1310,7 +1364,8 @@ pub fn _mm_maskz_shrdv_epi16(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_shldi_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shldi_epi64(a: __m512i, b: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_shldv_epi64(a, b, _mm512_set1_epi64(IMM8 as i64)) } @@ -1323,7 +1378,8 @@ pub fn _mm512_shldi_epi64(a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shldi_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shldi_epi64( src: __m512i, k: __mmask8, a: __m512i, @@ -1344,7 +1400,12 @@ pub fn _mm512_mask_shldi_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shldi_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shldi_epi64( + k: __mmask8, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm512_shldi_epi64::(a, b).as_i64x8(); @@ -1360,7 +1421,8 @@ pub fn _mm512_maskz_shldi_epi64(k: __mmask8, a: __m512i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_shldi_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shldi_epi64(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_shldv_epi64(a, b, _mm256_set1_epi64x(IMM8 as i64)) } @@ -1373,7 +1435,8 @@ pub fn _mm256_shldi_epi64(a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shldi_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shldi_epi64( src: __m256i, k: __mmask8, a: __m256i, @@ -1394,7 +1457,12 @@ pub fn _mm256_mask_shldi_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shldi_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shldi_epi64( + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm256_shldi_epi64::(a, b).as_i64x4(); @@ -1410,7 +1478,8 @@ pub fn _mm256_maskz_shldi_epi64(k: __mmask8, a: __m256i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm_shldi_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shldi_epi64(a: __m128i, b: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_shldv_epi64(a, b, _mm_set1_epi64x(IMM8 as i64)) } @@ -1423,7 +1492,8 @@ pub fn _mm_shldi_epi64(a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_shldi_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shldi_epi64( src: __m128i, k: __mmask8, a: __m128i, @@ -1444,7 +1514,12 @@ pub fn _mm_mask_shldi_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_shldi_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shldi_epi64( + k: __mmask8, + a: __m128i, + b: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm_shldi_epi64::(a, b).as_i64x2(); @@ -1460,7 +1535,8 @@ pub fn _mm_maskz_shldi_epi64(k: __mmask8, a: __m128i, b: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_shldi_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shldi_epi32(a: __m512i, b: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_shldv_epi32(a, b, _mm512_set1_epi32(IMM8)) } @@ -1473,7 +1549,8 @@ pub fn _mm512_shldi_epi32(a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shldi_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shldi_epi32( src: __m512i, k: __mmask16, a: __m512i, @@ -1494,7 +1571,12 @@ pub fn _mm512_mask_shldi_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shldi_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shldi_epi32( + k: __mmask16, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm512_shldi_epi32::(a, b).as_i32x16(); @@ -1510,7 +1592,8 @@ pub fn _mm512_maskz_shldi_epi32(k: __mmask16, a: __m512i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_shldi_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shldi_epi32(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_shldv_epi32(a, b, _mm256_set1_epi32(IMM8)) } @@ -1523,7 +1606,8 @@ pub fn _mm256_shldi_epi32(a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shldi_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shldi_epi32( src: __m256i, k: __mmask8, a: __m256i, @@ -1544,7 +1628,12 @@ pub fn _mm256_mask_shldi_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shldi_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shldi_epi32( + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm256_shldi_epi32::(a, b).as_i32x8(); @@ -1560,7 +1649,8 @@ pub fn _mm256_maskz_shldi_epi32(k: __mmask8, a: __m256i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm_shldi_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shldi_epi32(a: __m128i, b: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_shldv_epi32(a, b, _mm_set1_epi32(IMM8)) } @@ -1573,7 +1663,8 @@ pub fn _mm_shldi_epi32(a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_shldi_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shldi_epi32( src: __m128i, k: __mmask8, a: __m128i, @@ -1594,7 +1685,12 @@ pub fn _mm_mask_shldi_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_shldi_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shldi_epi32( + k: __mmask8, + a: __m128i, + b: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm_shldi_epi32::(a, b).as_i32x4(); @@ -1610,7 +1706,8 @@ pub fn _mm_maskz_shldi_epi32(k: __mmask8, a: __m128i, b: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm512_shldi_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shldi_epi16(a: __m512i, b: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_shldv_epi16(a, b, _mm512_set1_epi16(IMM8 as i16)) } @@ -1623,7 +1720,8 @@ pub fn _mm512_shldi_epi16(a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shldi_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shldi_epi16( src: __m512i, k: __mmask32, a: __m512i, @@ -1644,7 +1742,12 @@ pub fn _mm512_mask_shldi_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shldi_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shldi_epi16( + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm512_shldi_epi16::(a, b).as_i16x32(); @@ -1660,7 +1763,8 @@ pub fn _mm512_maskz_shldi_epi16(k: __mmask32, a: __m512i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm256_shldi_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shldi_epi16(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_shldv_epi16(a, b, _mm256_set1_epi16(IMM8 as i16)) } @@ -1673,7 +1777,8 @@ pub fn _mm256_shldi_epi16(a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shldi_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shldi_epi16( src: __m256i, k: __mmask16, a: __m256i, @@ -1694,7 +1799,12 @@ pub fn _mm256_mask_shldi_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shldi_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shldi_epi16( + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm256_shldi_epi16::(a, b).as_i16x16(); @@ -1710,7 +1820,8 @@ pub fn _mm256_maskz_shldi_epi16(k: __mmask16, a: __m256i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] #[rustc_legacy_const_generics(2)] -pub fn _mm_shldi_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shldi_epi16(a: __m128i, b: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_shldv_epi16(a, b, _mm_set1_epi16(IMM8 as i16)) } @@ -1723,7 +1834,8 @@ pub fn _mm_shldi_epi16(a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_shldi_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shldi_epi16( src: __m128i, k: __mmask8, a: __m128i, @@ -1744,7 +1856,12 @@ pub fn _mm_mask_shldi_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_shldi_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shldi_epi16( + k: __mmask8, + a: __m128i, + b: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm_shldi_epi16::(a, b).as_i16x8(); @@ -1760,7 +1877,8 @@ pub fn _mm_maskz_shldi_epi16(k: __mmask8, a: __m128i, b: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] //should be vpshrdq #[rustc_legacy_const_generics(2)] -pub fn _mm512_shrdi_epi64(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shrdi_epi64(a: __m512i, b: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_shrdv_epi64(a, b, _mm512_set1_epi64(IMM8 as i64)) } @@ -1773,7 +1891,8 @@ pub fn _mm512_shrdi_epi64(a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] //should be vpshrdq #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shrdi_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shrdi_epi64( src: __m512i, k: __mmask8, a: __m512i, @@ -1794,7 +1913,12 @@ pub fn _mm512_mask_shrdi_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 255))] //should be vpshrdq #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shrdi_epi64(k: __mmask8, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shrdi_epi64( + k: __mmask8, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm512_shrdi_epi64::(a, b).as_i64x8(); @@ -1810,7 +1934,8 @@ pub fn _mm512_maskz_shrdi_epi64(k: __mmask8, a: __m512i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] //should be vpshrdq #[rustc_legacy_const_generics(2)] -pub fn _mm256_shrdi_epi64(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shrdi_epi64(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_shrdv_epi64(a, b, _mm256_set1_epi64x(IMM8 as i64)) } @@ -1823,7 +1948,8 @@ pub fn _mm256_shrdi_epi64(a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] //should be vpshrdq #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shrdi_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shrdi_epi64( src: __m256i, k: __mmask8, a: __m256i, @@ -1844,7 +1970,12 @@ pub fn _mm256_mask_shrdi_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] //should be vpshrdq #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shrdi_epi64(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shrdi_epi64( + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm256_shrdi_epi64::(a, b).as_i64x4(); @@ -1860,7 +1991,8 @@ pub fn _mm256_maskz_shrdi_epi64(k: __mmask8, a: __m256i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] //should be vpshrdq #[rustc_legacy_const_generics(2)] -pub fn _mm_shrdi_epi64(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shrdi_epi64(a: __m128i, b: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_shrdv_epi64(a, b, _mm_set1_epi64x(IMM8 as i64)) } @@ -1873,7 +2005,8 @@ pub fn _mm_shrdi_epi64(a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] //should be vpshrdq #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_shrdi_epi64( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shrdi_epi64( src: __m128i, k: __mmask8, a: __m128i, @@ -1894,7 +2027,12 @@ pub fn _mm_mask_shrdi_epi64( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldq, IMM8 = 5))] //should be vpshrdq #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_shrdi_epi64(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shrdi_epi64( + k: __mmask8, + a: __m128i, + b: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm_shrdi_epi64::(a, b).as_i64x2(); @@ -1910,7 +2048,8 @@ pub fn _mm_maskz_shrdi_epi64(k: __mmask8, a: __m128i, b: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] //should be vpshldd #[rustc_legacy_const_generics(2)] -pub fn _mm512_shrdi_epi32(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shrdi_epi32(a: __m512i, b: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_shrdv_epi32(a, b, _mm512_set1_epi32(IMM8)) } @@ -1923,7 +2062,8 @@ pub fn _mm512_shrdi_epi32(a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] //should be vpshldd #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shrdi_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shrdi_epi32( src: __m512i, k: __mmask16, a: __m512i, @@ -1944,7 +2084,12 @@ pub fn _mm512_mask_shrdi_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] //should be vpshldd #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shrdi_epi32(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shrdi_epi32( + k: __mmask16, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm512_shrdi_epi32::(a, b).as_i32x16(); @@ -1960,7 +2105,8 @@ pub fn _mm512_maskz_shrdi_epi32(k: __mmask16, a: __m512i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] //should be vpshldd #[rustc_legacy_const_generics(2)] -pub fn _mm256_shrdi_epi32(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shrdi_epi32(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_shrdv_epi32(a, b, _mm256_set1_epi32(IMM8)) } @@ -1973,7 +2119,8 @@ pub fn _mm256_shrdi_epi32(a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] //should be vpshldd #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shrdi_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shrdi_epi32( src: __m256i, k: __mmask8, a: __m256i, @@ -1994,7 +2141,12 @@ pub fn _mm256_mask_shrdi_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] //should be vpshldd #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shrdi_epi32(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shrdi_epi32( + k: __mmask8, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm256_shrdi_epi32::(a, b).as_i32x8(); @@ -2010,7 +2162,8 @@ pub fn _mm256_maskz_shrdi_epi32(k: __mmask8, a: __m256i, b: __m #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] //should be vpshldd #[rustc_legacy_const_generics(2)] -pub fn _mm_shrdi_epi32(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shrdi_epi32(a: __m128i, b: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_shrdv_epi32(a, b, _mm_set1_epi32(IMM8)) } @@ -2023,7 +2176,8 @@ pub fn _mm_shrdi_epi32(a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] //should be vpshldd #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_shrdi_epi32( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shrdi_epi32( src: __m128i, k: __mmask8, a: __m128i, @@ -2044,7 +2198,12 @@ pub fn _mm_mask_shrdi_epi32( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldd, IMM8 = 5))] //should be vpshldd #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_shrdi_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shrdi_epi32( + k: __mmask8, + a: __m128i, + b: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm_shrdi_epi32::(a, b).as_i32x4(); @@ -2060,7 +2219,8 @@ pub fn _mm_maskz_shrdi_epi32(k: __mmask8, a: __m128i, b: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] //should be vpshrdw #[rustc_legacy_const_generics(2)] -pub fn _mm512_shrdi_epi16(a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_shrdi_epi16(a: __m512i, b: __m512i) -> __m512i { static_assert_uimm_bits!(IMM8, 8); _mm512_shrdv_epi16(a, b, _mm512_set1_epi16(IMM8 as i16)) } @@ -2073,7 +2233,8 @@ pub fn _mm512_shrdi_epi16(a: __m512i, b: __m512i) -> __m512i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] //should be vpshrdw #[rustc_legacy_const_generics(4)] -pub fn _mm512_mask_shrdi_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_shrdi_epi16( src: __m512i, k: __mmask32, a: __m512i, @@ -2094,7 +2255,12 @@ pub fn _mm512_mask_shrdi_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] //should be vpshrdw #[rustc_legacy_const_generics(3)] -pub fn _mm512_maskz_shrdi_epi16(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_shrdi_epi16( + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm512_shrdi_epi16::(a, b).as_i16x32(); @@ -2110,7 +2276,8 @@ pub fn _mm512_maskz_shrdi_epi16(k: __mmask32, a: __m512i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] //should be vpshrdw #[rustc_legacy_const_generics(2)] -pub fn _mm256_shrdi_epi16(a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_shrdi_epi16(a: __m256i, b: __m256i) -> __m256i { static_assert_uimm_bits!(IMM8, 8); _mm256_shrdv_epi16(a, b, _mm256_set1_epi16(IMM8 as i16)) } @@ -2123,7 +2290,8 @@ pub fn _mm256_shrdi_epi16(a: __m256i, b: __m256i) -> __m256i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] //should be vpshrdw #[rustc_legacy_const_generics(4)] -pub fn _mm256_mask_shrdi_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_shrdi_epi16( src: __m256i, k: __mmask16, a: __m256i, @@ -2144,7 +2312,12 @@ pub fn _mm256_mask_shrdi_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] //should be vpshrdw #[rustc_legacy_const_generics(3)] -pub fn _mm256_maskz_shrdi_epi16(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_shrdi_epi16( + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm256_shrdi_epi16::(a, b).as_i16x16(); @@ -2160,7 +2333,8 @@ pub fn _mm256_maskz_shrdi_epi16(k: __mmask16, a: __m256i, b: __ #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] //should be vpshrdw #[rustc_legacy_const_generics(2)] -pub fn _mm_shrdi_epi16(a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_shrdi_epi16(a: __m128i, b: __m128i) -> __m128i { static_assert_uimm_bits!(IMM8, 8); _mm_shrdv_epi16(a, b, _mm_set1_epi16(IMM8 as i16)) } @@ -2173,7 +2347,8 @@ pub fn _mm_shrdi_epi16(a: __m128i, b: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] //should be vpshrdw #[rustc_legacy_const_generics(4)] -pub fn _mm_mask_shrdi_epi16( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_shrdi_epi16( src: __m128i, k: __mmask8, a: __m128i, @@ -2194,7 +2369,12 @@ pub fn _mm_mask_shrdi_epi16( #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldw, IMM8 = 5))] //should be vpshrdw #[rustc_legacy_const_generics(3)] -pub fn _mm_maskz_shrdi_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_shrdi_epi16( + k: __mmask8, + a: __m128i, + b: __m128i, +) -> __m128i { unsafe { static_assert_uimm_bits!(IMM8, 8); let shf = _mm_shrdi_epi16::(a, b).as_i16x8(); @@ -2262,6 +2442,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; @@ -2581,7 +2762,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shldv_epi64() { + const unsafe fn test_mm512_shldv_epi64() { let a = _mm512_set1_epi64(1); let b = _mm512_set1_epi64(1 << 63); let c = _mm512_set1_epi64(2); @@ -2591,7 +2772,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shldv_epi64() { + const unsafe fn test_mm512_mask_shldv_epi64() { let a = _mm512_set1_epi64(1); let b = _mm512_set1_epi64(1 << 63); let c = _mm512_set1_epi64(2); @@ -2603,7 +2784,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shldv_epi64() { + const unsafe fn test_mm512_maskz_shldv_epi64() { let a = _mm512_set1_epi64(1); let b = _mm512_set1_epi64(1 << 63); let c = _mm512_set1_epi64(2); @@ -2615,7 +2796,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shldv_epi64() { + const unsafe fn test_mm256_shldv_epi64() { let a = _mm256_set1_epi64x(1); let b = _mm256_set1_epi64x(1 << 63); let c = _mm256_set1_epi64x(2); @@ -2625,7 +2806,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shldv_epi64() { + const unsafe fn test_mm256_mask_shldv_epi64() { let a = _mm256_set1_epi64x(1); let b = _mm256_set1_epi64x(1 << 63); let c = _mm256_set1_epi64x(2); @@ -2637,7 +2818,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shldv_epi64() { + const unsafe fn test_mm256_maskz_shldv_epi64() { let a = _mm256_set1_epi64x(1); let b = _mm256_set1_epi64x(1 << 63); let c = _mm256_set1_epi64x(2); @@ -2649,7 +2830,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shldv_epi64() { + const unsafe fn test_mm_shldv_epi64() { let a = _mm_set1_epi64x(1); let b = _mm_set1_epi64x(1 << 63); let c = _mm_set1_epi64x(2); @@ -2659,7 +2840,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shldv_epi64() { + const unsafe fn test_mm_mask_shldv_epi64() { let a = _mm_set1_epi64x(1); let b = _mm_set1_epi64x(1 << 63); let c = _mm_set1_epi64x(2); @@ -2671,7 +2852,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shldv_epi64() { + const unsafe fn test_mm_maskz_shldv_epi64() { let a = _mm_set1_epi64x(1); let b = _mm_set1_epi64x(1 << 63); let c = _mm_set1_epi64x(2); @@ -2683,7 +2864,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shldv_epi32() { + const unsafe fn test_mm512_shldv_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_set1_epi32(1 << 31); let c = _mm512_set1_epi32(2); @@ -2693,7 +2874,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shldv_epi32() { + const unsafe fn test_mm512_mask_shldv_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_set1_epi32(1 << 31); let c = _mm512_set1_epi32(2); @@ -2705,7 +2886,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shldv_epi32() { + const unsafe fn test_mm512_maskz_shldv_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_set1_epi32(1 << 31); let c = _mm512_set1_epi32(2); @@ -2717,7 +2898,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shldv_epi32() { + const unsafe fn test_mm256_shldv_epi32() { let a = _mm256_set1_epi32(1); let b = _mm256_set1_epi32(1 << 31); let c = _mm256_set1_epi32(2); @@ -2727,7 +2908,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shldv_epi32() { + const unsafe fn test_mm256_mask_shldv_epi32() { let a = _mm256_set1_epi32(1); let b = _mm256_set1_epi32(1 << 31); let c = _mm256_set1_epi32(2); @@ -2739,7 +2920,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shldv_epi32() { + const unsafe fn test_mm256_maskz_shldv_epi32() { let a = _mm256_set1_epi32(1); let b = _mm256_set1_epi32(1 << 31); let c = _mm256_set1_epi32(2); @@ -2751,7 +2932,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shldv_epi32() { + const unsafe fn test_mm_shldv_epi32() { let a = _mm_set1_epi32(1); let b = _mm_set1_epi32(1 << 31); let c = _mm_set1_epi32(2); @@ -2761,7 +2942,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shldv_epi32() { + const unsafe fn test_mm_mask_shldv_epi32() { let a = _mm_set1_epi32(1); let b = _mm_set1_epi32(1 << 31); let c = _mm_set1_epi32(2); @@ -2773,7 +2954,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shldv_epi32() { + const unsafe fn test_mm_maskz_shldv_epi32() { let a = _mm_set1_epi32(1); let b = _mm_set1_epi32(1 << 31); let c = _mm_set1_epi32(2); @@ -2785,7 +2966,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shldv_epi16() { + const unsafe fn test_mm512_shldv_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1 << 15); let c = _mm512_set1_epi16(2); @@ -2795,7 +2976,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shldv_epi16() { + const unsafe fn test_mm512_mask_shldv_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1 << 15); let c = _mm512_set1_epi16(2); @@ -2807,7 +2988,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shldv_epi16() { + const unsafe fn test_mm512_maskz_shldv_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1 << 15); let c = _mm512_set1_epi16(2); @@ -2819,7 +3000,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shldv_epi16() { + const unsafe fn test_mm256_shldv_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1 << 15); let c = _mm256_set1_epi16(2); @@ -2829,7 +3010,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shldv_epi16() { + const unsafe fn test_mm256_mask_shldv_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1 << 15); let c = _mm256_set1_epi16(2); @@ -2841,7 +3022,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shldv_epi16() { + const unsafe fn test_mm256_maskz_shldv_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1 << 15); let c = _mm256_set1_epi16(2); @@ -2853,7 +3034,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shldv_epi16() { + const unsafe fn test_mm_shldv_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1 << 15); let c = _mm_set1_epi16(2); @@ -2863,7 +3044,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shldv_epi16() { + const unsafe fn test_mm_mask_shldv_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1 << 15); let c = _mm_set1_epi16(2); @@ -2875,7 +3056,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shldv_epi16() { + const unsafe fn test_mm_maskz_shldv_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1 << 15); let c = _mm_set1_epi16(2); @@ -2887,7 +3068,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shrdv_epi64() { + const unsafe fn test_mm512_shrdv_epi64() { let a = _mm512_set1_epi64(2); let b = _mm512_set1_epi64(8); let c = _mm512_set1_epi64(1); @@ -2897,7 +3078,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shrdv_epi64() { + const unsafe fn test_mm512_mask_shrdv_epi64() { let a = _mm512_set1_epi64(2); let b = _mm512_set1_epi64(8); let c = _mm512_set1_epi64(1); @@ -2909,7 +3090,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shrdv_epi64() { + const unsafe fn test_mm512_maskz_shrdv_epi64() { let a = _mm512_set1_epi64(2); let b = _mm512_set1_epi64(8); let c = _mm512_set1_epi64(1); @@ -2921,7 +3102,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shrdv_epi64() { + const unsafe fn test_mm256_shrdv_epi64() { let a = _mm256_set1_epi64x(2); let b = _mm256_set1_epi64x(8); let c = _mm256_set1_epi64x(1); @@ -2931,7 +3112,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shrdv_epi64() { + const unsafe fn test_mm256_mask_shrdv_epi64() { let a = _mm256_set1_epi64x(2); let b = _mm256_set1_epi64x(8); let c = _mm256_set1_epi64x(1); @@ -2943,7 +3124,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shrdv_epi64() { + const unsafe fn test_mm256_maskz_shrdv_epi64() { let a = _mm256_set1_epi64x(2); let b = _mm256_set1_epi64x(8); let c = _mm256_set1_epi64x(1); @@ -2955,7 +3136,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shrdv_epi64() { + const unsafe fn test_mm_shrdv_epi64() { let a = _mm_set1_epi64x(2); let b = _mm_set1_epi64x(8); let c = _mm_set1_epi64x(1); @@ -2965,7 +3146,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shrdv_epi64() { + const unsafe fn test_mm_mask_shrdv_epi64() { let a = _mm_set1_epi64x(2); let b = _mm_set1_epi64x(8); let c = _mm_set1_epi64x(1); @@ -2977,7 +3158,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shrdv_epi64() { + const unsafe fn test_mm_maskz_shrdv_epi64() { let a = _mm_set1_epi64x(2); let b = _mm_set1_epi64x(8); let c = _mm_set1_epi64x(1); @@ -2989,7 +3170,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shrdv_epi32() { + const unsafe fn test_mm512_shrdv_epi32() { let a = _mm512_set1_epi32(2); let b = _mm512_set1_epi32(8); let c = _mm512_set1_epi32(1); @@ -2999,7 +3180,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shrdv_epi32() { + const unsafe fn test_mm512_mask_shrdv_epi32() { let a = _mm512_set1_epi32(2); let b = _mm512_set1_epi32(8); let c = _mm512_set1_epi32(1); @@ -3011,7 +3192,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shrdv_epi32() { + const unsafe fn test_mm512_maskz_shrdv_epi32() { let a = _mm512_set1_epi32(2); let b = _mm512_set1_epi32(8); let c = _mm512_set1_epi32(1); @@ -3023,7 +3204,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shrdv_epi32() { + const unsafe fn test_mm256_shrdv_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(8); let c = _mm256_set1_epi32(1); @@ -3033,7 +3214,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shrdv_epi32() { + const unsafe fn test_mm256_mask_shrdv_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(8); let c = _mm256_set1_epi32(1); @@ -3045,7 +3226,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shrdv_epi32() { + const unsafe fn test_mm256_maskz_shrdv_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(8); let c = _mm256_set1_epi32(1); @@ -3057,7 +3238,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shrdv_epi32() { + const unsafe fn test_mm_shrdv_epi32() { let a = _mm_set1_epi32(2); let b = _mm_set1_epi32(8); let c = _mm_set1_epi32(1); @@ -3067,7 +3248,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shrdv_epi32() { + const unsafe fn test_mm_mask_shrdv_epi32() { let a = _mm_set1_epi32(2); let b = _mm_set1_epi32(8); let c = _mm_set1_epi32(1); @@ -3079,7 +3260,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shrdv_epi32() { + const unsafe fn test_mm_maskz_shrdv_epi32() { let a = _mm_set1_epi32(2); let b = _mm_set1_epi32(8); let c = _mm_set1_epi32(1); @@ -3091,7 +3272,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shrdv_epi16() { + const unsafe fn test_mm512_shrdv_epi16() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(8); let c = _mm512_set1_epi16(1); @@ -3101,7 +3282,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shrdv_epi16() { + const unsafe fn test_mm512_mask_shrdv_epi16() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(8); let c = _mm512_set1_epi16(1); @@ -3113,7 +3294,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shrdv_epi16() { + const unsafe fn test_mm512_maskz_shrdv_epi16() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(8); let c = _mm512_set1_epi16(1); @@ -3125,7 +3306,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shrdv_epi16() { + const unsafe fn test_mm256_shrdv_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(8); let c = _mm256_set1_epi16(1); @@ -3135,7 +3316,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shrdv_epi16() { + const unsafe fn test_mm256_mask_shrdv_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(8); let c = _mm256_set1_epi16(1); @@ -3147,7 +3328,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shrdv_epi16() { + const unsafe fn test_mm256_maskz_shrdv_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(8); let c = _mm256_set1_epi16(1); @@ -3159,7 +3340,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shrdv_epi16() { + const unsafe fn test_mm_shrdv_epi16() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(8); let c = _mm_set1_epi16(1); @@ -3169,7 +3350,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shrdv_epi16() { + const unsafe fn test_mm_mask_shrdv_epi16() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(8); let c = _mm_set1_epi16(1); @@ -3181,7 +3362,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shrdv_epi16() { + const unsafe fn test_mm_maskz_shrdv_epi16() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(8); let c = _mm_set1_epi16(1); @@ -3193,7 +3374,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shldi_epi64() { + const unsafe fn test_mm512_shldi_epi64() { let a = _mm512_set1_epi64(1); let b = _mm512_set1_epi64(1 << 63); let r = _mm512_shldi_epi64::<2>(a, b); @@ -3202,7 +3383,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shldi_epi64() { + const unsafe fn test_mm512_mask_shldi_epi64() { let a = _mm512_set1_epi64(1); let b = _mm512_set1_epi64(1 << 63); let r = _mm512_mask_shldi_epi64::<2>(a, 0, a, b); @@ -3213,7 +3394,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shldi_epi64() { + const unsafe fn test_mm512_maskz_shldi_epi64() { let a = _mm512_set1_epi64(1); let b = _mm512_set1_epi64(1 << 63); let r = _mm512_maskz_shldi_epi64::<2>(0, a, b); @@ -3224,7 +3405,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shldi_epi64() { + const unsafe fn test_mm256_shldi_epi64() { let a = _mm256_set1_epi64x(1); let b = _mm256_set1_epi64x(1 << 63); let r = _mm256_shldi_epi64::<2>(a, b); @@ -3233,7 +3414,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shldi_epi64() { + const unsafe fn test_mm256_mask_shldi_epi64() { let a = _mm256_set1_epi64x(1); let b = _mm256_set1_epi64x(1 << 63); let r = _mm256_mask_shldi_epi64::<2>(a, 0, a, b); @@ -3244,7 +3425,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shldi_epi64() { + const unsafe fn test_mm256_maskz_shldi_epi64() { let a = _mm256_set1_epi64x(1); let b = _mm256_set1_epi64x(1 << 63); let r = _mm256_maskz_shldi_epi64::<2>(0, a, b); @@ -3255,7 +3436,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shldi_epi64() { + const unsafe fn test_mm_shldi_epi64() { let a = _mm_set1_epi64x(1); let b = _mm_set1_epi64x(1 << 63); let r = _mm_shldi_epi64::<2>(a, b); @@ -3264,7 +3445,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shldi_epi64() { + const unsafe fn test_mm_mask_shldi_epi64() { let a = _mm_set1_epi64x(1); let b = _mm_set1_epi64x(1 << 63); let r = _mm_mask_shldi_epi64::<2>(a, 0, a, b); @@ -3275,7 +3456,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shldi_epi64() { + const unsafe fn test_mm_maskz_shldi_epi64() { let a = _mm_set1_epi64x(1); let b = _mm_set1_epi64x(1 << 63); let r = _mm_maskz_shldi_epi64::<2>(0, a, b); @@ -3286,7 +3467,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shldi_epi32() { + const unsafe fn test_mm512_shldi_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_set1_epi32(1 << 31); let r = _mm512_shldi_epi32::<2>(a, b); @@ -3295,7 +3476,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shldi_epi32() { + const unsafe fn test_mm512_mask_shldi_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_set1_epi32(1 << 31); let r = _mm512_mask_shldi_epi32::<2>(a, 0, a, b); @@ -3306,7 +3487,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shldi_epi32() { + const unsafe fn test_mm512_maskz_shldi_epi32() { let a = _mm512_set1_epi32(1); let b = _mm512_set1_epi32(1 << 31); let r = _mm512_maskz_shldi_epi32::<2>(0, a, b); @@ -3317,7 +3498,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shldi_epi32() { + const unsafe fn test_mm256_shldi_epi32() { let a = _mm256_set1_epi32(1); let b = _mm256_set1_epi32(1 << 31); let r = _mm256_shldi_epi32::<2>(a, b); @@ -3326,7 +3507,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shldi_epi32() { + const unsafe fn test_mm256_mask_shldi_epi32() { let a = _mm256_set1_epi32(1); let b = _mm256_set1_epi32(1 << 31); let r = _mm256_mask_shldi_epi32::<2>(a, 0, a, b); @@ -3337,7 +3518,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shldi_epi32() { + const unsafe fn test_mm256_maskz_shldi_epi32() { let a = _mm256_set1_epi32(1); let b = _mm256_set1_epi32(1 << 31); let r = _mm256_maskz_shldi_epi32::<2>(0, a, b); @@ -3348,7 +3529,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shldi_epi32() { + const unsafe fn test_mm_shldi_epi32() { let a = _mm_set1_epi32(1); let b = _mm_set1_epi32(1 << 31); let r = _mm_shldi_epi32::<2>(a, b); @@ -3357,7 +3538,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shldi_epi32() { + const unsafe fn test_mm_mask_shldi_epi32() { let a = _mm_set1_epi32(1); let b = _mm_set1_epi32(1 << 31); let r = _mm_mask_shldi_epi32::<2>(a, 0, a, b); @@ -3368,7 +3549,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shldi_epi32() { + const unsafe fn test_mm_maskz_shldi_epi32() { let a = _mm_set1_epi32(1); let b = _mm_set1_epi32(1 << 31); let r = _mm_maskz_shldi_epi32::<2>(0, a, b); @@ -3379,7 +3560,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shldi_epi16() { + const unsafe fn test_mm512_shldi_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1 << 15); let r = _mm512_shldi_epi16::<2>(a, b); @@ -3388,7 +3569,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shldi_epi16() { + const unsafe fn test_mm512_mask_shldi_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1 << 15); let r = _mm512_mask_shldi_epi16::<2>(a, 0, a, b); @@ -3399,7 +3580,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shldi_epi16() { + const unsafe fn test_mm512_maskz_shldi_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1 << 15); let r = _mm512_maskz_shldi_epi16::<2>(0, a, b); @@ -3410,7 +3591,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shldi_epi16() { + const unsafe fn test_mm256_shldi_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1 << 15); let r = _mm256_shldi_epi16::<2>(a, b); @@ -3419,7 +3600,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shldi_epi16() { + const unsafe fn test_mm256_mask_shldi_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1 << 15); let r = _mm256_mask_shldi_epi16::<2>(a, 0, a, b); @@ -3430,7 +3611,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shldi_epi16() { + const unsafe fn test_mm256_maskz_shldi_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1 << 15); let r = _mm256_maskz_shldi_epi16::<2>(0, a, b); @@ -3441,7 +3622,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shldi_epi16() { + const unsafe fn test_mm_shldi_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1 << 15); let r = _mm_shldi_epi16::<2>(a, b); @@ -3450,7 +3631,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shldi_epi16() { + const unsafe fn test_mm_mask_shldi_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1 << 15); let r = _mm_mask_shldi_epi16::<2>(a, 0, a, b); @@ -3461,7 +3642,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shldi_epi16() { + const unsafe fn test_mm_maskz_shldi_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1 << 15); let r = _mm_maskz_shldi_epi16::<2>(0, a, b); @@ -3472,7 +3653,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shrdi_epi64() { + const unsafe fn test_mm512_shrdi_epi64() { let a = _mm512_set1_epi64(2); let b = _mm512_set1_epi64(8); let r = _mm512_shrdi_epi64::<1>(a, b); @@ -3481,7 +3662,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shrdi_epi64() { + const unsafe fn test_mm512_mask_shrdi_epi64() { let a = _mm512_set1_epi64(2); let b = _mm512_set1_epi64(8); let r = _mm512_mask_shrdi_epi64::<1>(a, 0, a, b); @@ -3492,7 +3673,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shrdi_epi64() { + const unsafe fn test_mm512_maskz_shrdi_epi64() { let a = _mm512_set1_epi64(2); let b = _mm512_set1_epi64(8); let r = _mm512_maskz_shrdi_epi64::<1>(0, a, b); @@ -3503,7 +3684,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shrdi_epi64() { + const unsafe fn test_mm256_shrdi_epi64() { let a = _mm256_set1_epi64x(2); let b = _mm256_set1_epi64x(8); let r = _mm256_shrdi_epi64::<1>(a, b); @@ -3512,7 +3693,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shrdi_epi64() { + const unsafe fn test_mm256_mask_shrdi_epi64() { let a = _mm256_set1_epi64x(2); let b = _mm256_set1_epi64x(8); let r = _mm256_mask_shrdi_epi64::<1>(a, 0, a, b); @@ -3523,7 +3704,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shrdi_epi64() { + const unsafe fn test_mm256_maskz_shrdi_epi64() { let a = _mm256_set1_epi64x(2); let b = _mm256_set1_epi64x(8); let r = _mm256_maskz_shrdi_epi64::<1>(0, a, b); @@ -3534,7 +3715,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shrdi_epi64() { + const unsafe fn test_mm_shrdi_epi64() { let a = _mm_set1_epi64x(2); let b = _mm_set1_epi64x(8); let r = _mm_shrdi_epi64::<1>(a, b); @@ -3543,7 +3724,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shrdi_epi64() { + const unsafe fn test_mm_mask_shrdi_epi64() { let a = _mm_set1_epi64x(2); let b = _mm_set1_epi64x(8); let r = _mm_mask_shrdi_epi64::<1>(a, 0, a, b); @@ -3554,7 +3735,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shrdi_epi64() { + const unsafe fn test_mm_maskz_shrdi_epi64() { let a = _mm_set1_epi64x(2); let b = _mm_set1_epi64x(8); let r = _mm_maskz_shrdi_epi64::<1>(0, a, b); @@ -3565,7 +3746,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shrdi_epi32() { + const unsafe fn test_mm512_shrdi_epi32() { let a = _mm512_set1_epi32(2); let b = _mm512_set1_epi32(8); let r = _mm512_shrdi_epi32::<1>(a, b); @@ -3574,7 +3755,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shrdi_epi32() { + const unsafe fn test_mm512_mask_shrdi_epi32() { let a = _mm512_set1_epi32(2); let b = _mm512_set1_epi32(8); let r = _mm512_mask_shrdi_epi32::<1>(a, 0, a, b); @@ -3585,7 +3766,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shrdi_epi32() { + const unsafe fn test_mm512_maskz_shrdi_epi32() { let a = _mm512_set1_epi32(2); let b = _mm512_set1_epi32(8); let r = _mm512_maskz_shrdi_epi32::<1>(0, a, b); @@ -3596,7 +3777,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shrdi_epi32() { + const unsafe fn test_mm256_shrdi_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(8); let r = _mm256_shrdi_epi32::<1>(a, b); @@ -3605,7 +3786,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shrdi_epi32() { + const unsafe fn test_mm256_mask_shrdi_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(8); let r = _mm256_mask_shrdi_epi32::<1>(a, 0, a, b); @@ -3616,7 +3797,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shrdi_epi32() { + const unsafe fn test_mm256_maskz_shrdi_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(8); let r = _mm256_maskz_shrdi_epi32::<1>(0, a, b); @@ -3627,7 +3808,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shrdi_epi32() { + const unsafe fn test_mm_shrdi_epi32() { let a = _mm_set1_epi32(2); let b = _mm_set1_epi32(8); let r = _mm_shrdi_epi32::<1>(a, b); @@ -3636,7 +3817,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shrdi_epi32() { + const unsafe fn test_mm_mask_shrdi_epi32() { let a = _mm_set1_epi32(2); let b = _mm_set1_epi32(8); let r = _mm_mask_shrdi_epi32::<1>(a, 0, a, b); @@ -3647,7 +3828,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shrdi_epi32() { + const unsafe fn test_mm_maskz_shrdi_epi32() { let a = _mm_set1_epi32(2); let b = _mm_set1_epi32(8); let r = _mm_maskz_shrdi_epi32::<1>(0, a, b); @@ -3658,7 +3839,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_shrdi_epi16() { + const unsafe fn test_mm512_shrdi_epi16() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(8); let r = _mm512_shrdi_epi16::<1>(a, b); @@ -3667,7 +3848,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_shrdi_epi16() { + const unsafe fn test_mm512_mask_shrdi_epi16() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(8); let r = _mm512_mask_shrdi_epi16::<1>(a, 0, a, b); @@ -3678,7 +3859,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_shrdi_epi16() { + const unsafe fn test_mm512_maskz_shrdi_epi16() { let a = _mm512_set1_epi16(2); let b = _mm512_set1_epi16(8); let r = _mm512_maskz_shrdi_epi16::<1>(0, a, b); @@ -3689,7 +3870,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_shrdi_epi16() { + const unsafe fn test_mm256_shrdi_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(8); let r = _mm256_shrdi_epi16::<1>(a, b); @@ -3698,7 +3879,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_shrdi_epi16() { + const unsafe fn test_mm256_mask_shrdi_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(8); let r = _mm256_mask_shrdi_epi16::<1>(a, 0, a, b); @@ -3709,7 +3890,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_shrdi_epi16() { + const unsafe fn test_mm256_maskz_shrdi_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(8); let r = _mm256_maskz_shrdi_epi16::<1>(0, a, b); @@ -3720,7 +3901,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_shrdi_epi16() { + const unsafe fn test_mm_shrdi_epi16() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(8); let r = _mm_shrdi_epi16::<1>(a, b); @@ -3729,7 +3910,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_shrdi_epi16() { + const unsafe fn test_mm_mask_shrdi_epi16() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(8); let r = _mm_mask_shrdi_epi16::<1>(a, 0, a, b); @@ -3740,7 +3921,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_shrdi_epi16() { + const unsafe fn test_mm_maskz_shrdi_epi16() { let a = _mm_set1_epi16(2); let b = _mm_set1_epi16(8); let r = _mm_maskz_shrdi_epi16::<1>(0, a, b); From 2e6bdf2b733dfa66f12ad9ababbb0404121014fc Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 18:28:32 +0530 Subject: [PATCH 0239/3801] Make `avx512bitalg` functions const --- .../crates/core_arch/src/x86/avx512bitalg.rs | 91 +++++++++++-------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs b/library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs index 1cbf0faea09f..832a58432208 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs @@ -43,7 +43,8 @@ unsafe extern "C" { #[target_feature(enable = "avx512bitalg")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntw))] -pub fn _mm512_popcnt_epi16(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_popcnt_epi16(a: __m512i) -> __m512i { unsafe { transmute(simd_ctpop(a.as_i16x32())) } } @@ -57,7 +58,8 @@ pub fn _mm512_popcnt_epi16(a: __m512i) -> __m512i { #[target_feature(enable = "avx512bitalg")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntw))] -pub fn _mm512_maskz_popcnt_epi16(k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_popcnt_epi16(k: __mmask32, a: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask( k, @@ -77,7 +79,8 @@ pub fn _mm512_maskz_popcnt_epi16(k: __mmask32, a: __m512i) -> __m512i { #[target_feature(enable = "avx512bitalg")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntw))] -pub fn _mm512_mask_popcnt_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_popcnt_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask( k, @@ -94,7 +97,8 @@ pub fn _mm512_mask_popcnt_epi16(src: __m512i, k: __mmask32, a: __m512i) -> __m51 #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntw))] -pub fn _mm256_popcnt_epi16(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_popcnt_epi16(a: __m256i) -> __m256i { unsafe { transmute(simd_ctpop(a.as_i16x16())) } } @@ -108,7 +112,8 @@ pub fn _mm256_popcnt_epi16(a: __m256i) -> __m256i { #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntw))] -pub fn _mm256_maskz_popcnt_epi16(k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_popcnt_epi16(k: __mmask16, a: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask( k, @@ -128,7 +133,8 @@ pub fn _mm256_maskz_popcnt_epi16(k: __mmask16, a: __m256i) -> __m256i { #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntw))] -pub fn _mm256_mask_popcnt_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_popcnt_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask( k, @@ -145,7 +151,8 @@ pub fn _mm256_mask_popcnt_epi16(src: __m256i, k: __mmask16, a: __m256i) -> __m25 #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntw))] -pub fn _mm_popcnt_epi16(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_popcnt_epi16(a: __m128i) -> __m128i { unsafe { transmute(simd_ctpop(a.as_i16x8())) } } @@ -159,7 +166,8 @@ pub fn _mm_popcnt_epi16(a: __m128i) -> __m128i { #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntw))] -pub fn _mm_maskz_popcnt_epi16(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_popcnt_epi16(k: __mmask8, a: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask( k, @@ -179,7 +187,8 @@ pub fn _mm_maskz_popcnt_epi16(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntw))] -pub fn _mm_mask_popcnt_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_popcnt_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask( k, @@ -196,7 +205,8 @@ pub fn _mm_mask_popcnt_epi16(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bitalg")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntb))] -pub fn _mm512_popcnt_epi8(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_popcnt_epi8(a: __m512i) -> __m512i { unsafe { transmute(simd_ctpop(a.as_i8x64())) } } @@ -210,7 +220,8 @@ pub fn _mm512_popcnt_epi8(a: __m512i) -> __m512i { #[target_feature(enable = "avx512bitalg")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntb))] -pub fn _mm512_maskz_popcnt_epi8(k: __mmask64, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_popcnt_epi8(k: __mmask64, a: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask( k, @@ -230,7 +241,8 @@ pub fn _mm512_maskz_popcnt_epi8(k: __mmask64, a: __m512i) -> __m512i { #[target_feature(enable = "avx512bitalg")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntb))] -pub fn _mm512_mask_popcnt_epi8(src: __m512i, k: __mmask64, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_popcnt_epi8(src: __m512i, k: __mmask64, a: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask( k, @@ -247,7 +259,8 @@ pub fn _mm512_mask_popcnt_epi8(src: __m512i, k: __mmask64, a: __m512i) -> __m512 #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntb))] -pub fn _mm256_popcnt_epi8(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_popcnt_epi8(a: __m256i) -> __m256i { unsafe { transmute(simd_ctpop(a.as_i8x32())) } } @@ -261,7 +274,8 @@ pub fn _mm256_popcnt_epi8(a: __m256i) -> __m256i { #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntb))] -pub fn _mm256_maskz_popcnt_epi8(k: __mmask32, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_popcnt_epi8(k: __mmask32, a: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask( k, @@ -281,7 +295,8 @@ pub fn _mm256_maskz_popcnt_epi8(k: __mmask32, a: __m256i) -> __m256i { #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntb))] -pub fn _mm256_mask_popcnt_epi8(src: __m256i, k: __mmask32, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_popcnt_epi8(src: __m256i, k: __mmask32, a: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask( k, @@ -298,7 +313,8 @@ pub fn _mm256_mask_popcnt_epi8(src: __m256i, k: __mmask32, a: __m256i) -> __m256 #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntb))] -pub fn _mm_popcnt_epi8(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_popcnt_epi8(a: __m128i) -> __m128i { unsafe { transmute(simd_ctpop(a.as_i8x16())) } } @@ -312,7 +328,8 @@ pub fn _mm_popcnt_epi8(a: __m128i) -> __m128i { #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntb))] -pub fn _mm_maskz_popcnt_epi8(k: __mmask16, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_popcnt_epi8(k: __mmask16, a: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask( k, @@ -332,7 +349,8 @@ pub fn _mm_maskz_popcnt_epi8(k: __mmask16, a: __m128i) -> __m128i { #[target_feature(enable = "avx512bitalg,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntb))] -pub fn _mm_mask_popcnt_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_popcnt_epi8(src: __m128i, k: __mmask16, a: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask( k, @@ -436,12 +454,13 @@ mod tests { // __mXXXi happens to be defined in terms of signed integers. #![allow(overflowing_literals)] + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; #[simd_test(enable = "avx512bitalg,avx512f")] - unsafe fn test_mm512_popcnt_epi16() { + const unsafe fn test_mm512_popcnt_epi16() { let test_data = _mm512_set_epi16( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1_FF, 0x3_FF, 0x7_FF, 0xF_FF, 0x1F_FF, 0x3F_FF, 0x7F_FF, 0xFF_FF, -1, -100, 255, 256, 2, 4, 8, 16, 32, 64, 128, 256, 512, @@ -456,7 +475,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f")] - unsafe fn test_mm512_maskz_popcnt_epi16() { + const unsafe fn test_mm512_maskz_popcnt_epi16() { let test_data = _mm512_set_epi16( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1_FF, 0x3_FF, 0x7_FF, 0xF_FF, 0x1F_FF, 0x3F_FF, 0x7F_FF, 0xFF_FF, -1, -100, 255, 256, 2, 4, 8, 16, 32, 64, 128, 256, 512, @@ -472,7 +491,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f")] - unsafe fn test_mm512_mask_popcnt_epi16() { + const unsafe fn test_mm512_mask_popcnt_epi16() { let test_data = _mm512_set_epi16( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1_FF, 0x3_FF, 0x7_FF, 0xF_FF, 0x1F_FF, 0x3F_FF, 0x7F_FF, 0xFF_FF, -1, -100, 255, 256, 2, 4, 8, 16, 32, 64, 128, 256, 512, @@ -488,7 +507,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm256_popcnt_epi16() { + const unsafe fn test_mm256_popcnt_epi16() { let test_data = _mm256_set_epi16( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1_FF, 0x3_FF, 0x7_FF, 0xF_FF, 0x1F_FF, 0x3F_FF, 0x7F_FF, @@ -500,7 +519,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm256_maskz_popcnt_epi16() { + const unsafe fn test_mm256_maskz_popcnt_epi16() { let test_data = _mm256_set_epi16( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1_FF, 0x3_FF, 0x7_FF, 0xF_FF, 0x1F_FF, 0x3F_FF, 0x7F_FF, @@ -512,7 +531,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm256_mask_popcnt_epi16() { + const unsafe fn test_mm256_mask_popcnt_epi16() { let test_data = _mm256_set_epi16( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1_FF, 0x3_FF, 0x7_FF, 0xF_FF, 0x1F_FF, 0x3F_FF, 0x7F_FF, @@ -526,7 +545,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm_popcnt_epi16() { + const unsafe fn test_mm_popcnt_epi16() { let test_data = _mm_set_epi16(0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F); let actual_result = _mm_popcnt_epi16(test_data); let reference_result = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7); @@ -534,7 +553,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm_maskz_popcnt_epi16() { + const unsafe fn test_mm_maskz_popcnt_epi16() { let test_data = _mm_set_epi16(0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F); let mask = 0xF0; let actual_result = _mm_maskz_popcnt_epi16(mask, test_data); @@ -543,7 +562,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm_mask_popcnt_epi16() { + const unsafe fn test_mm_mask_popcnt_epi16() { let test_data = _mm_set_epi16(0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F); let mask = 0xF0; let actual_result = _mm_mask_popcnt_epi16(test_data, mask, test_data); @@ -552,7 +571,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f")] - unsafe fn test_mm512_popcnt_epi8() { + const unsafe fn test_mm512_popcnt_epi8() { let test_data = _mm512_set_epi8( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64, 128, 171, 206, 100, 217, 109, 253, 190, 177, 254, 179, 215, 230, 68, 201, 172, 183, 154, 84, 56, 227, 189, @@ -569,7 +588,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f")] - unsafe fn test_mm512_maskz_popcnt_epi8() { + const unsafe fn test_mm512_maskz_popcnt_epi8() { let test_data = _mm512_set_epi8( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64, 128, 171, 206, 100, 217, 109, 253, 190, 177, 254, 179, 215, 230, 68, 201, 172, 183, 154, 84, 56, 227, 189, @@ -587,7 +606,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f")] - unsafe fn test_mm512_mask_popcnt_epi8() { + const unsafe fn test_mm512_mask_popcnt_epi8() { let test_data = _mm512_set_epi8( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64, 128, 171, 206, 100, 217, 109, 253, 190, 177, 254, 179, 215, 230, 68, 201, 172, 183, 154, 84, 56, 227, 189, @@ -605,7 +624,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm256_popcnt_epi8() { + const unsafe fn test_mm256_popcnt_epi8() { let test_data = _mm256_set_epi8( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64, 128, 171, 206, 100, 217, 109, 253, 190, 177, 254, 179, 215, 230, 68, 201, 172, @@ -619,7 +638,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm256_maskz_popcnt_epi8() { + const unsafe fn test_mm256_maskz_popcnt_epi8() { let test_data = _mm256_set_epi8( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64, 251, 73, 121, 143, 145, 85, 91, 137, 90, 225, 21, 249, 211, 155, 228, 70, @@ -634,7 +653,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm256_mask_popcnt_epi8() { + const unsafe fn test_mm256_mask_popcnt_epi8() { let test_data = _mm256_set_epi8( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64, 251, 73, 121, 143, 145, 85, 91, 137, 90, 225, 21, 249, 211, 155, 228, 70, @@ -649,7 +668,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm_popcnt_epi8() { + const unsafe fn test_mm_popcnt_epi8() { let test_data = _mm_set_epi8( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64, ); @@ -659,7 +678,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm_maskz_popcnt_epi8() { + const unsafe fn test_mm_maskz_popcnt_epi8() { let test_data = _mm_set_epi8( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 90, 225, 21, 249, 211, 155, 228, 70, ); @@ -670,7 +689,7 @@ mod tests { } #[simd_test(enable = "avx512bitalg,avx512f,avx512vl")] - unsafe fn test_mm_mask_popcnt_epi8() { + const unsafe fn test_mm_mask_popcnt_epi8() { let test_data = _mm_set_epi8( 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 90, 225, 21, 249, 211, 155, 228, 70, ); From 4506af45ddf0311558369451623cfd697b45f3b4 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 19:06:52 +0530 Subject: [PATCH 0240/3801] Make `avx512vpopcntdq` functions const --- .../core_arch/src/x86/avx512vpopcntdq.rs | 91 +++++++++++-------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs b/library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs index e47a14b24dfc..42bff33a286d 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs @@ -26,7 +26,8 @@ use stdarch_test::assert_instr; #[target_feature(enable = "avx512vpopcntdq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntd))] -pub fn _mm512_popcnt_epi32(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_popcnt_epi32(a: __m512i) -> __m512i { unsafe { transmute(simd_ctpop(a.as_i32x16())) } } @@ -40,7 +41,8 @@ pub fn _mm512_popcnt_epi32(a: __m512i) -> __m512i { #[target_feature(enable = "avx512vpopcntdq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntd))] -pub fn _mm512_maskz_popcnt_epi32(k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_popcnt_epi32(k: __mmask16, a: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask( k, @@ -60,7 +62,8 @@ pub fn _mm512_maskz_popcnt_epi32(k: __mmask16, a: __m512i) -> __m512i { #[target_feature(enable = "avx512vpopcntdq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntd))] -pub fn _mm512_mask_popcnt_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_popcnt_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask( k, @@ -77,7 +80,8 @@ pub fn _mm512_mask_popcnt_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m51 #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntd))] -pub fn _mm256_popcnt_epi32(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_popcnt_epi32(a: __m256i) -> __m256i { unsafe { transmute(simd_ctpop(a.as_i32x8())) } } @@ -91,7 +95,8 @@ pub fn _mm256_popcnt_epi32(a: __m256i) -> __m256i { #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntd))] -pub fn _mm256_maskz_popcnt_epi32(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_popcnt_epi32(k: __mmask8, a: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask( k, @@ -111,7 +116,8 @@ pub fn _mm256_maskz_popcnt_epi32(k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntd))] -pub fn _mm256_mask_popcnt_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_popcnt_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask( k, @@ -128,7 +134,8 @@ pub fn _mm256_mask_popcnt_epi32(src: __m256i, k: __mmask8, a: __m256i) -> __m256 #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntd))] -pub fn _mm_popcnt_epi32(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_popcnt_epi32(a: __m128i) -> __m128i { unsafe { transmute(simd_ctpop(a.as_i32x4())) } } @@ -142,7 +149,8 @@ pub fn _mm_popcnt_epi32(a: __m128i) -> __m128i { #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntd))] -pub fn _mm_maskz_popcnt_epi32(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_popcnt_epi32(k: __mmask8, a: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask( k, @@ -162,7 +170,8 @@ pub fn _mm_maskz_popcnt_epi32(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntd))] -pub fn _mm_mask_popcnt_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_popcnt_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask( k, @@ -179,7 +188,8 @@ pub fn _mm_mask_popcnt_epi32(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512vpopcntdq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntq))] -pub fn _mm512_popcnt_epi64(a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_popcnt_epi64(a: __m512i) -> __m512i { unsafe { transmute(simd_ctpop(a.as_i64x8())) } } @@ -193,7 +203,8 @@ pub fn _mm512_popcnt_epi64(a: __m512i) -> __m512i { #[target_feature(enable = "avx512vpopcntdq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntq))] -pub fn _mm512_maskz_popcnt_epi64(k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_popcnt_epi64(k: __mmask8, a: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask( k, @@ -213,7 +224,8 @@ pub fn _mm512_maskz_popcnt_epi64(k: __mmask8, a: __m512i) -> __m512i { #[target_feature(enable = "avx512vpopcntdq")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntq))] -pub fn _mm512_mask_popcnt_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_popcnt_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512i { unsafe { transmute(simd_select_bitmask( k, @@ -230,7 +242,8 @@ pub fn _mm512_mask_popcnt_epi64(src: __m512i, k: __mmask8, a: __m512i) -> __m512 #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntq))] -pub fn _mm256_popcnt_epi64(a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_popcnt_epi64(a: __m256i) -> __m256i { unsafe { transmute(simd_ctpop(a.as_i64x4())) } } @@ -244,7 +257,8 @@ pub fn _mm256_popcnt_epi64(a: __m256i) -> __m256i { #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntq))] -pub fn _mm256_maskz_popcnt_epi64(k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_popcnt_epi64(k: __mmask8, a: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask( k, @@ -264,7 +278,8 @@ pub fn _mm256_maskz_popcnt_epi64(k: __mmask8, a: __m256i) -> __m256i { #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntq))] -pub fn _mm256_mask_popcnt_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_popcnt_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256i { unsafe { transmute(simd_select_bitmask( k, @@ -281,7 +296,8 @@ pub fn _mm256_mask_popcnt_epi64(src: __m256i, k: __mmask8, a: __m256i) -> __m256 #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntq))] -pub fn _mm_popcnt_epi64(a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_popcnt_epi64(a: __m128i) -> __m128i { unsafe { transmute(simd_ctpop(a.as_i64x2())) } } @@ -295,7 +311,8 @@ pub fn _mm_popcnt_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntq))] -pub fn _mm_maskz_popcnt_epi64(k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_popcnt_epi64(k: __mmask8, a: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask( k, @@ -315,7 +332,8 @@ pub fn _mm_maskz_popcnt_epi64(k: __mmask8, a: __m128i) -> __m128i { #[target_feature(enable = "avx512vpopcntdq,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpopcntq))] -pub fn _mm_mask_popcnt_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_popcnt_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { unsafe { transmute(simd_select_bitmask( k, @@ -327,12 +345,13 @@ pub fn _mm_mask_popcnt_epi64(src: __m128i, k: __mmask8, a: __m128i) -> __m128i { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; use crate::core_arch::x86::*; #[simd_test(enable = "avx512vpopcntdq,avx512f")] - unsafe fn test_mm512_popcnt_epi32() { + const unsafe fn test_mm512_popcnt_epi32() { let test_data = _mm512_set_epi32( 0, 1, @@ -358,7 +377,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f")] - unsafe fn test_mm512_mask_popcnt_epi32() { + const unsafe fn test_mm512_mask_popcnt_epi32() { let test_data = _mm512_set_epi32( 0, 1, @@ -401,7 +420,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f")] - unsafe fn test_mm512_maskz_popcnt_epi32() { + const unsafe fn test_mm512_maskz_popcnt_epi32() { let test_data = _mm512_set_epi32( 0, 1, @@ -427,7 +446,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f,avx512vl")] - unsafe fn test_mm256_popcnt_epi32() { + const unsafe fn test_mm256_popcnt_epi32() { let test_data = _mm256_set_epi32(0, 1, -1, 2, 7, 0xFF_FE, 0x7F_FF_FF_FF, -100); let actual_result = _mm256_popcnt_epi32(test_data); let reference_result = _mm256_set_epi32(0, 1, 32, 1, 3, 15, 31, 28); @@ -435,7 +454,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f,avx512vl")] - unsafe fn test_mm256_mask_popcnt_epi32() { + const unsafe fn test_mm256_mask_popcnt_epi32() { let test_data = _mm256_set_epi32(0, 1, -1, 2, 7, 0xFF_FE, 0x7F_FF_FF_FF, -100); let mask = 0xF0; let actual_result = _mm256_mask_popcnt_epi32(test_data, mask, test_data); @@ -444,7 +463,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f,avx512vl")] - unsafe fn test_mm256_maskz_popcnt_epi32() { + const unsafe fn test_mm256_maskz_popcnt_epi32() { let test_data = _mm256_set_epi32(0, 1, -1, 2, 7, 0xFF_FE, 0x7F_FF_FF_FF, -100); let mask = 0xF0; let actual_result = _mm256_maskz_popcnt_epi32(mask, test_data); @@ -453,7 +472,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f,avx512vl")] - unsafe fn test_mm_popcnt_epi32() { + const unsafe fn test_mm_popcnt_epi32() { let test_data = _mm_set_epi32(0, 1, -1, -100); let actual_result = _mm_popcnt_epi32(test_data); let reference_result = _mm_set_epi32(0, 1, 32, 28); @@ -461,7 +480,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f,avx512vl")] - unsafe fn test_mm_mask_popcnt_epi32() { + const unsafe fn test_mm_mask_popcnt_epi32() { let test_data = _mm_set_epi32(0, 1, -1, -100); let mask = 0xE; let actual_result = _mm_mask_popcnt_epi32(test_data, mask, test_data); @@ -470,7 +489,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f,avx512vl")] - unsafe fn test_mm_maskz_popcnt_epi32() { + const unsafe fn test_mm_maskz_popcnt_epi32() { let test_data = _mm_set_epi32(0, 1, -1, -100); let mask = 0xE; let actual_result = _mm_maskz_popcnt_epi32(mask, test_data); @@ -479,7 +498,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f")] - unsafe fn test_mm512_popcnt_epi64() { + const unsafe fn test_mm512_popcnt_epi64() { let test_data = _mm512_set_epi64(0, 1, -1, 2, 7, 0xFF_FE, 0x7F_FF_FF_FF_FF_FF_FF_FF, -100); let actual_result = _mm512_popcnt_epi64(test_data); let reference_result = _mm512_set_epi64(0, 1, 64, 1, 3, 15, 63, 60); @@ -487,7 +506,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f")] - unsafe fn test_mm512_mask_popcnt_epi64() { + const unsafe fn test_mm512_mask_popcnt_epi64() { let test_data = _mm512_set_epi64(0, 1, -1, 2, 7, 0xFF_FE, 0x7F_FF_FF_FF_FF_FF_FF_FF, -100); let mask = 0xF0; let actual_result = _mm512_mask_popcnt_epi64(test_data, mask, test_data); @@ -497,7 +516,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512f")] - unsafe fn test_mm512_maskz_popcnt_epi64() { + const unsafe fn test_mm512_maskz_popcnt_epi64() { let test_data = _mm512_set_epi64(0, 1, -1, 2, 7, 0xFF_FE, 0x7F_FF_FF_FF_FF_FF_FF_FF, -100); let mask = 0xF0; let actual_result = _mm512_maskz_popcnt_epi64(mask, test_data); @@ -506,7 +525,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512vl")] - unsafe fn test_mm256_popcnt_epi64() { + const unsafe fn test_mm256_popcnt_epi64() { let test_data = _mm256_set_epi64x(0, 1, -1, -100); let actual_result = _mm256_popcnt_epi64(test_data); let reference_result = _mm256_set_epi64x(0, 1, 64, 60); @@ -514,7 +533,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512vl")] - unsafe fn test_mm256_mask_popcnt_epi64() { + const unsafe fn test_mm256_mask_popcnt_epi64() { let test_data = _mm256_set_epi64x(0, 1, -1, -100); let mask = 0xE; let actual_result = _mm256_mask_popcnt_epi64(test_data, mask, test_data); @@ -523,7 +542,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512vl")] - unsafe fn test_mm256_maskz_popcnt_epi64() { + const unsafe fn test_mm256_maskz_popcnt_epi64() { let test_data = _mm256_set_epi64x(0, 1, -1, -100); let mask = 0xE; let actual_result = _mm256_maskz_popcnt_epi64(mask, test_data); @@ -532,7 +551,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512vl")] - unsafe fn test_mm_popcnt_epi64() { + const unsafe fn test_mm_popcnt_epi64() { let test_data = _mm_set_epi64x(0, 1); let actual_result = _mm_popcnt_epi64(test_data); let reference_result = _mm_set_epi64x(0, 1); @@ -544,7 +563,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512vl")] - unsafe fn test_mm_mask_popcnt_epi64() { + const unsafe fn test_mm_mask_popcnt_epi64() { let test_data = _mm_set_epi64x(0, -100); let mask = 0x2; let actual_result = _mm_mask_popcnt_epi64(test_data, mask, test_data); @@ -558,7 +577,7 @@ mod tests { } #[simd_test(enable = "avx512vpopcntdq,avx512vl")] - unsafe fn test_mm_maskz_popcnt_epi64() { + const unsafe fn test_mm_maskz_popcnt_epi64() { let test_data = _mm_set_epi64x(0, 1); let mask = 0x2; let actual_result = _mm_maskz_popcnt_epi64(mask, test_data); From 92098dd82d4f03350a1e2ffbcb14ecf9bcf676a8 Mon Sep 17 00:00:00 2001 From: sayantn Date: Tue, 23 Sep 2025 19:11:35 +0530 Subject: [PATCH 0241/3801] Make `avx512fp16` functions const --- .../crates/core_arch/src/x86/avx512fp16.rs | 1105 ++++++++++------- .../stdarch/crates/core_arch/src/x86/f16c.rs | 11 +- 2 files changed, 671 insertions(+), 445 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs index 7185531606d2..de058c307308 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs @@ -9,7 +9,8 @@ use crate::ptr; #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_set_ph( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_ph( e7: f16, e6: f16, e5: f16, @@ -28,7 +29,8 @@ pub fn _mm_set_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_set_ph( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set_ph( e15: f16, e14: f16, e13: f16, @@ -57,7 +59,8 @@ pub fn _mm256_set_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_set_ph( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set_ph( e31: f16, e30: f16, e29: f16, @@ -104,7 +107,8 @@ pub fn _mm512_set_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_set_sh(a: f16) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set_sh(a: f16) -> __m128h { __m128h([a, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) } @@ -114,7 +118,8 @@ pub fn _mm_set_sh(a: f16) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_set1_ph(a: f16) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_set1_ph(a: f16) -> __m128h { unsafe { transmute(f16x8::splat(a)) } } @@ -124,7 +129,8 @@ pub fn _mm_set1_ph(a: f16) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_set1_ph(a: f16) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_set1_ph(a: f16) -> __m256h { unsafe { transmute(f16x16::splat(a)) } } @@ -134,7 +140,8 @@ pub fn _mm256_set1_ph(a: f16) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_set1_ph(a: f16) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_set1_ph(a: f16) -> __m512h { unsafe { transmute(f16x32::splat(a)) } } @@ -144,7 +151,8 @@ pub fn _mm512_set1_ph(a: f16) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_setr_ph( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setr_ph( e0: f16, e1: f16, e2: f16, @@ -163,7 +171,8 @@ pub fn _mm_setr_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_setr_ph( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setr_ph( e0: f16, e1: f16, e2: f16, @@ -192,7 +201,8 @@ pub fn _mm256_setr_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_setr_ph( +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setr_ph( e0: f16, e1: f16, e2: f16, @@ -238,7 +248,8 @@ pub fn _mm512_setr_ph( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_setzero_ph() -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_setzero_ph() -> __m128h { unsafe { transmute(f16x8::ZERO) } } @@ -248,7 +259,8 @@ pub fn _mm_setzero_ph() -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_setzero_ph() -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_setzero_ph() -> __m256h { f16x16::ZERO.as_m256h() } @@ -258,7 +270,8 @@ pub fn _mm256_setzero_ph() -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_setzero_ph() -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_setzero_ph() -> __m512h { f16x32::ZERO.as_m512h() } @@ -271,7 +284,8 @@ pub fn _mm512_setzero_ph() -> __m512h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_undefined_ph() -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_undefined_ph() -> __m128h { f16x8::ZERO.as_m128h() } @@ -284,7 +298,8 @@ pub fn _mm_undefined_ph() -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_undefined_ph() -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_undefined_ph() -> __m256h { f16x16::ZERO.as_m256h() } @@ -297,7 +312,8 @@ pub fn _mm256_undefined_ph() -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_undefined_ph() -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_undefined_ph() -> __m512h { f16x32::ZERO.as_m512h() } @@ -308,7 +324,8 @@ pub fn _mm512_undefined_ph() -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_castpd_ph(a: __m128d) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castpd_ph(a: __m128d) -> __m128h { unsafe { transmute(a) } } @@ -319,7 +336,8 @@ pub fn _mm_castpd_ph(a: __m128d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_castpd_ph(a: __m256d) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castpd_ph(a: __m256d) -> __m256h { unsafe { transmute(a) } } @@ -330,7 +348,8 @@ pub fn _mm256_castpd_ph(a: __m256d) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castpd_ph(a: __m512d) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castpd_ph(a: __m512d) -> __m512h { unsafe { transmute(a) } } @@ -341,7 +360,8 @@ pub fn _mm512_castpd_ph(a: __m512d) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_castph_pd(a: __m128h) -> __m128d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castph_pd(a: __m128h) -> __m128d { unsafe { transmute(a) } } @@ -352,7 +372,8 @@ pub fn _mm_castph_pd(a: __m128h) -> __m128d { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_castph_pd(a: __m256h) -> __m256d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castph_pd(a: __m256h) -> __m256d { unsafe { transmute(a) } } @@ -363,7 +384,8 @@ pub fn _mm256_castph_pd(a: __m256h) -> __m256d { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castph_pd(a: __m512h) -> __m512d { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castph_pd(a: __m512h) -> __m512d { unsafe { transmute(a) } } @@ -374,7 +396,8 @@ pub fn _mm512_castph_pd(a: __m512h) -> __m512d { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_castps_ph(a: __m128) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castps_ph(a: __m128) -> __m128h { unsafe { transmute(a) } } @@ -385,7 +408,8 @@ pub fn _mm_castps_ph(a: __m128) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_castps_ph(a: __m256) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castps_ph(a: __m256) -> __m256h { unsafe { transmute(a) } } @@ -396,7 +420,8 @@ pub fn _mm256_castps_ph(a: __m256) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castps_ph(a: __m512) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castps_ph(a: __m512) -> __m512h { unsafe { transmute(a) } } @@ -407,7 +432,8 @@ pub fn _mm512_castps_ph(a: __m512) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_castph_ps(a: __m128h) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castph_ps(a: __m128h) -> __m128 { unsafe { transmute(a) } } @@ -418,7 +444,8 @@ pub fn _mm_castph_ps(a: __m128h) -> __m128 { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_castph_ps(a: __m256h) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castph_ps(a: __m256h) -> __m256 { unsafe { transmute(a) } } @@ -429,7 +456,8 @@ pub fn _mm256_castph_ps(a: __m256h) -> __m256 { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castph_ps(a: __m512h) -> __m512 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castph_ps(a: __m512h) -> __m512 { unsafe { transmute(a) } } @@ -440,7 +468,8 @@ pub fn _mm512_castph_ps(a: __m512h) -> __m512 { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_castsi128_ph(a: __m128i) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castsi128_ph(a: __m128i) -> __m128h { unsafe { transmute(a) } } @@ -451,7 +480,8 @@ pub fn _mm_castsi128_ph(a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_castsi256_ph(a: __m256i) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castsi256_ph(a: __m256i) -> __m256h { unsafe { transmute(a) } } @@ -462,7 +492,8 @@ pub fn _mm256_castsi256_ph(a: __m256i) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castsi512_ph(a: __m512i) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castsi512_ph(a: __m512i) -> __m512h { unsafe { transmute(a) } } @@ -473,7 +504,8 @@ pub fn _mm512_castsi512_ph(a: __m512i) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_castph_si128(a: __m128h) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_castph_si128(a: __m128h) -> __m128i { unsafe { transmute(a) } } @@ -484,7 +516,8 @@ pub fn _mm_castph_si128(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_castph_si256(a: __m256h) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castph_si256(a: __m256h) -> __m256i { unsafe { transmute(a) } } @@ -495,7 +528,8 @@ pub fn _mm256_castph_si256(a: __m256h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castph_si512(a: __m512h) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castph_si512(a: __m512h) -> __m512i { unsafe { transmute(a) } } @@ -506,7 +540,8 @@ pub fn _mm512_castph_si512(a: __m512h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_castph256_ph128(a: __m256h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castph256_ph128(a: __m256h) -> __m128h { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]) } } @@ -517,7 +552,8 @@ pub fn _mm256_castph256_ph128(a: __m256h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castph512_ph128(a: __m512h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castph512_ph128(a: __m512h) -> __m128h { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]) } } @@ -528,7 +564,8 @@ pub fn _mm512_castph512_ph128(a: __m512h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castph512_ph256(a: __m512h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castph512_ph256(a: __m512h) -> __m256h { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) } } @@ -540,7 +577,8 @@ pub fn _mm512_castph512_ph256(a: __m512h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_castph128_ph256(a: __m128h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_castph128_ph256(a: __m128h) -> __m256h { unsafe { simd_shuffle!( a, @@ -558,7 +596,8 @@ pub fn _mm256_castph128_ph256(a: __m128h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castph128_ph512(a: __m128h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castph128_ph512(a: __m128h) -> __m512h { unsafe { simd_shuffle!( a, @@ -579,7 +618,8 @@ pub fn _mm512_castph128_ph512(a: __m128h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_castph256_ph512(a: __m256h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_castph256_ph512(a: __m256h) -> __m512h { unsafe { simd_shuffle!( a, @@ -600,7 +640,8 @@ pub fn _mm512_castph256_ph512(a: __m256h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_zextph128_ph256(a: __m128h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_zextph128_ph256(a: __m128h) -> __m256h { unsafe { simd_shuffle!( a, @@ -618,7 +659,8 @@ pub fn _mm256_zextph128_ph256(a: __m128h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_zextph256_ph512(a: __m256h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_zextph256_ph512(a: __m256h) -> __m512h { unsafe { simd_shuffle!( a, @@ -639,7 +681,8 @@ pub fn _mm512_zextph256_ph512(a: __m256h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_zextph128_ph512(a: __m128h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_zextph128_ph512(a: __m128h) -> __m512h { unsafe { simd_shuffle!( a, @@ -1083,7 +1126,8 @@ pub fn _mm_ucomineq_sh(a: __m128h, b: __m128h) -> i32 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm_load_ph(mem_addr: *const f16) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_ph(mem_addr: *const f16) -> __m128h { *mem_addr.cast() } @@ -1094,7 +1138,8 @@ pub unsafe fn _mm_load_ph(mem_addr: *const f16) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm256_load_ph(mem_addr: *const f16) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_load_ph(mem_addr: *const f16) -> __m256h { *mem_addr.cast() } @@ -1105,7 +1150,8 @@ pub unsafe fn _mm256_load_ph(mem_addr: *const f16) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm512_load_ph(mem_addr: *const f16) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_load_ph(mem_addr: *const f16) -> __m512h { *mem_addr.cast() } @@ -1116,7 +1162,8 @@ pub unsafe fn _mm512_load_ph(mem_addr: *const f16) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm_load_sh(mem_addr: *const f16) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_load_sh(mem_addr: *const f16) -> __m128h { _mm_set_sh(*mem_addr) } @@ -1165,7 +1212,8 @@ pub unsafe fn _mm_maskz_load_sh(k: __mmask8, mem_addr: *const f16) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm_loadu_ph(mem_addr: *const f16) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_loadu_ph(mem_addr: *const f16) -> __m128h { ptr::read_unaligned(mem_addr.cast()) } @@ -1176,7 +1224,8 @@ pub unsafe fn _mm_loadu_ph(mem_addr: *const f16) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm256_loadu_ph(mem_addr: *const f16) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_loadu_ph(mem_addr: *const f16) -> __m256h { ptr::read_unaligned(mem_addr.cast()) } @@ -1187,7 +1236,8 @@ pub unsafe fn _mm256_loadu_ph(mem_addr: *const f16) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm512_loadu_ph(mem_addr: *const f16) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_loadu_ph(mem_addr: *const f16) -> __m512h { ptr::read_unaligned(mem_addr.cast()) } @@ -1199,7 +1249,8 @@ pub unsafe fn _mm512_loadu_ph(mem_addr: *const f16) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_move_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_move_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let mut mov: f16 = simd_extract!(src, 0); if (k & 1) != 0 { @@ -1217,7 +1268,8 @@ pub fn _mm_mask_move_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __ #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_move_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_move_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let mut mov: f16 = 0.; if (k & 1) != 0 { @@ -1234,7 +1286,8 @@ pub fn _mm_maskz_move_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_move_sh(a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_move_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { let mov: f16 = simd_extract!(b, 0); simd_insert!(a, 0, mov) @@ -1248,7 +1301,8 @@ pub fn _mm_move_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm_store_ph(mem_addr: *mut f16, a: __m128h) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_ph(mem_addr: *mut f16, a: __m128h) { *mem_addr.cast() = a; } @@ -1259,7 +1313,8 @@ pub unsafe fn _mm_store_ph(mem_addr: *mut f16, a: __m128h) { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm256_store_ph(mem_addr: *mut f16, a: __m256h) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_store_ph(mem_addr: *mut f16, a: __m256h) { *mem_addr.cast() = a; } @@ -1270,7 +1325,8 @@ pub unsafe fn _mm256_store_ph(mem_addr: *mut f16, a: __m256h) { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm512_store_ph(mem_addr: *mut f16, a: __m512h) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_store_ph(mem_addr: *mut f16, a: __m512h) { *mem_addr.cast() = a; } @@ -1280,7 +1336,8 @@ pub unsafe fn _mm512_store_ph(mem_addr: *mut f16, a: __m512h) { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm_store_sh(mem_addr: *mut f16, a: __m128h) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_store_sh(mem_addr: *mut f16, a: __m128h) { *mem_addr = simd_extract!(a, 0); } @@ -1307,7 +1364,8 @@ pub unsafe fn _mm_mask_store_sh(mem_addr: *mut f16, k: __mmask8, a: __m128h) { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm_storeu_ph(mem_addr: *mut f16, a: __m128h) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm_storeu_ph(mem_addr: *mut f16, a: __m128h) { ptr::write_unaligned(mem_addr.cast(), a); } @@ -1318,7 +1376,8 @@ pub unsafe fn _mm_storeu_ph(mem_addr: *mut f16, a: __m128h) { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm256_storeu_ph(mem_addr: *mut f16, a: __m256h) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm256_storeu_ph(mem_addr: *mut f16, a: __m256h) { ptr::write_unaligned(mem_addr.cast(), a); } @@ -1329,7 +1388,8 @@ pub unsafe fn _mm256_storeu_ph(mem_addr: *mut f16, a: __m256h) { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub unsafe fn _mm512_storeu_ph(mem_addr: *mut f16, a: __m512h) { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const unsafe fn _mm512_storeu_ph(mem_addr: *mut f16, a: __m512h) { ptr::write_unaligned(mem_addr.cast(), a); } @@ -1340,7 +1400,8 @@ pub unsafe fn _mm512_storeu_ph(mem_addr: *mut f16, a: __m512h) { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_add_ph(a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_add(a, b) } } @@ -1352,7 +1413,8 @@ pub fn _mm_add_ph(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_add_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let r = _mm_add_ph(a, b); simd_select_bitmask(k, r, src) @@ -1367,7 +1429,8 @@ pub fn _mm_mask_add_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_add_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let r = _mm_add_ph(a, b); simd_select_bitmask(k, r, _mm_setzero_ph()) @@ -1381,7 +1444,8 @@ pub fn _mm_maskz_add_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_add_ph(a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_add_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { simd_add(a, b) } } @@ -1393,7 +1457,8 @@ pub fn _mm256_add_ph(a: __m256h, b: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_add_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_add_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { let r = _mm256_add_ph(a, b); simd_select_bitmask(k, r, src) @@ -1408,7 +1473,8 @@ pub fn _mm256_mask_add_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_add_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_add_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { let r = _mm256_add_ph(a, b); simd_select_bitmask(k, r, _mm256_setzero_ph()) @@ -1422,7 +1488,8 @@ pub fn _mm256_maskz_add_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_add_ph(a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_add_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { simd_add(a, b) } } @@ -1434,7 +1501,8 @@ pub fn _mm512_add_ph(a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_add_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_add_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { let r = _mm512_add_ph(a, b); simd_select_bitmask(k, r, src) @@ -1449,7 +1517,8 @@ pub fn _mm512_mask_add_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_add_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_add_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { let r = _mm512_add_ph(a, b); simd_select_bitmask(k, r, _mm512_setzero_ph()) @@ -1614,7 +1683,8 @@ pub fn _mm_maskz_add_round_sh(k: __mmask8, a: __m128h, b: _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_add_sh(a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_add_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_insert!(a, 0, _mm_cvtsh_h(a) + _mm_cvtsh_h(b)) } } @@ -1627,7 +1697,8 @@ pub fn _mm_add_sh(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_add_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_add_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let extractsrc: f16 = simd_extract!(src, 0); let mut add: f16 = extractsrc; @@ -1649,7 +1720,8 @@ pub fn _mm_mask_add_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_add_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_add_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let mut add: f16 = 0.; if (k & 0b00000001) != 0 { @@ -1668,7 +1740,8 @@ pub fn _mm_maskz_add_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_sub_ph(a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_sub(a, b) } } @@ -1680,7 +1753,8 @@ pub fn _mm_sub_ph(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_sub_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let r = _mm_sub_ph(a, b); simd_select_bitmask(k, r, src) @@ -1695,7 +1769,8 @@ pub fn _mm_mask_sub_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_sub_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let r = _mm_sub_ph(a, b); simd_select_bitmask(k, r, _mm_setzero_ph()) @@ -1709,7 +1784,8 @@ pub fn _mm_maskz_sub_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_sub_ph(a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_sub_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { simd_sub(a, b) } } @@ -1721,7 +1797,8 @@ pub fn _mm256_sub_ph(a: __m256h, b: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_sub_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_sub_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { let r = _mm256_sub_ph(a, b); simd_select_bitmask(k, r, src) @@ -1736,7 +1813,8 @@ pub fn _mm256_mask_sub_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_sub_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_sub_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { let r = _mm256_sub_ph(a, b); simd_select_bitmask(k, r, _mm256_setzero_ph()) @@ -1750,7 +1828,8 @@ pub fn _mm256_maskz_sub_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_sub_ph(a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_sub_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { simd_sub(a, b) } } @@ -1762,7 +1841,8 @@ pub fn _mm512_sub_ph(a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_sub_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_sub_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { let r = _mm512_sub_ph(a, b); simd_select_bitmask(k, r, src) @@ -1777,7 +1857,8 @@ pub fn _mm512_mask_sub_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_sub_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_sub_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { let r = _mm512_sub_ph(a, b); simd_select_bitmask(k, r, _mm512_setzero_ph()) @@ -1943,7 +2024,8 @@ pub fn _mm_maskz_sub_round_sh(k: __mmask8, a: __m128h, b: _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_sub_sh(a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_sub_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_insert!(a, 0, _mm_cvtsh_h(a) - _mm_cvtsh_h(b)) } } @@ -1956,7 +2038,8 @@ pub fn _mm_sub_sh(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_sub_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_sub_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let extractsrc: f16 = simd_extract!(src, 0); let mut add: f16 = extractsrc; @@ -1978,7 +2061,8 @@ pub fn _mm_mask_sub_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_sub_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_sub_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let mut add: f16 = 0.; if (k & 0b00000001) != 0 { @@ -1997,7 +2081,8 @@ pub fn _mm_maskz_sub_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mul_ph(a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mul_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_mul(a, b) } } @@ -2009,7 +2094,8 @@ pub fn _mm_mul_ph(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_mul_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mul_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let r = _mm_mul_ph(a, b); simd_select_bitmask(k, r, src) @@ -2024,7 +2110,8 @@ pub fn _mm_mask_mul_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_mul_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mul_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let r = _mm_mul_ph(a, b); simd_select_bitmask(k, r, _mm_setzero_ph()) @@ -2038,7 +2125,8 @@ pub fn _mm_maskz_mul_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mul_ph(a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mul_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { simd_mul(a, b) } } @@ -2050,7 +2138,8 @@ pub fn _mm256_mul_ph(a: __m256h, b: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_mul_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_mul_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { let r = _mm256_mul_ph(a, b); simd_select_bitmask(k, r, src) @@ -2065,7 +2154,8 @@ pub fn _mm256_mask_mul_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_mul_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_mul_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { let r = _mm256_mul_ph(a, b); simd_select_bitmask(k, r, _mm256_setzero_ph()) @@ -2079,7 +2169,8 @@ pub fn _mm256_maskz_mul_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mul_ph(a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mul_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { simd_mul(a, b) } } @@ -2091,7 +2182,8 @@ pub fn _mm512_mul_ph(a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_mul_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_mul_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { let r = _mm512_mul_ph(a, b); simd_select_bitmask(k, r, src) @@ -2106,7 +2198,8 @@ pub fn _mm512_mask_mul_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_mul_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_mul_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { let r = _mm512_mul_ph(a, b); simd_select_bitmask(k, r, _mm512_setzero_ph()) @@ -2272,7 +2365,8 @@ pub fn _mm_maskz_mul_round_sh(k: __mmask8, a: __m128h, b: _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mul_sh(a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mul_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_insert!(a, 0, _mm_cvtsh_h(a) * _mm_cvtsh_h(b)) } } @@ -2285,7 +2379,8 @@ pub fn _mm_mul_sh(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_mul_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_mul_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let extractsrc: f16 = simd_extract!(src, 0); let mut add: f16 = extractsrc; @@ -2307,7 +2402,8 @@ pub fn _mm_mask_mul_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_mul_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_mul_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let mut add: f16 = 0.; if (k & 0b00000001) != 0 { @@ -2326,7 +2422,8 @@ pub fn _mm_maskz_mul_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_div_ph(a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_div_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_div(a, b) } } @@ -2338,7 +2435,8 @@ pub fn _mm_div_ph(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_div_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_div_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let r = _mm_div_ph(a, b); simd_select_bitmask(k, r, src) @@ -2353,7 +2451,8 @@ pub fn _mm_mask_div_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_div_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_div_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let r = _mm_div_ph(a, b); simd_select_bitmask(k, r, _mm_setzero_ph()) @@ -2367,7 +2466,8 @@ pub fn _mm_maskz_div_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_div_ph(a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_div_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { simd_div(a, b) } } @@ -2379,7 +2479,8 @@ pub fn _mm256_div_ph(a: __m256h, b: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_div_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_div_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { let r = _mm256_div_ph(a, b); simd_select_bitmask(k, r, src) @@ -2394,7 +2495,8 @@ pub fn _mm256_mask_div_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_div_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_div_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { let r = _mm256_div_ph(a, b); simd_select_bitmask(k, r, _mm256_setzero_ph()) @@ -2408,7 +2510,8 @@ pub fn _mm256_maskz_div_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_div_ph(a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_div_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { simd_div(a, b) } } @@ -2420,7 +2523,8 @@ pub fn _mm512_div_ph(a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_div_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_div_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { let r = _mm512_div_ph(a, b); simd_select_bitmask(k, r, src) @@ -2435,7 +2539,8 @@ pub fn _mm512_mask_div_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivph))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_div_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_div_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { let r = _mm512_div_ph(a, b); simd_select_bitmask(k, r, _mm512_setzero_ph()) @@ -2601,7 +2706,8 @@ pub fn _mm_maskz_div_round_sh(k: __mmask8, a: __m128h, b: _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_div_sh(a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_div_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_insert!(a, 0, _mm_cvtsh_h(a) / _mm_cvtsh_h(b)) } } @@ -2614,7 +2720,8 @@ pub fn _mm_div_sh(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_div_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_div_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let extractsrc: f16 = simd_extract!(src, 0); let mut add: f16 = extractsrc; @@ -2636,7 +2743,8 @@ pub fn _mm_mask_div_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivsh))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_div_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_div_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { let mut add: f16 = 0.; if (k & 0b00000001) != 0 { @@ -3967,7 +4075,8 @@ pub fn _mm_maskz_fcmul_round_sch( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_abs_ph(v2: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_abs_ph(v2: __m128h) -> __m128h { unsafe { transmute(_mm_and_si128(transmute(v2), _mm_set1_epi16(i16::MAX))) } } @@ -3978,7 +4087,8 @@ pub fn _mm_abs_ph(v2: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_abs_ph(v2: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_abs_ph(v2: __m256h) -> __m256h { unsafe { transmute(_mm256_and_si256(transmute(v2), _mm256_set1_epi16(i16::MAX))) } } @@ -3989,7 +4099,8 @@ pub fn _mm256_abs_ph(v2: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_abs_ph(v2: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_abs_ph(v2: __m512h) -> __m512h { unsafe { transmute(_mm512_and_si512(transmute(v2), _mm512_set1_epi16(i16::MAX))) } } @@ -4002,7 +4113,8 @@ pub fn _mm512_abs_ph(v2: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_conj_pch(a: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_conj_pch(a: __m128h) -> __m128h { unsafe { transmute(_mm_xor_si128(transmute(a), _mm_set1_epi32(i32::MIN))) } } @@ -4015,7 +4127,8 @@ pub fn _mm_conj_pch(a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_conj_pch(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_conj_pch(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { unsafe { let r: __m128 = transmute(_mm_conj_pch(a)); transmute(simd_select_bitmask(k, r, transmute(src))) @@ -4031,7 +4144,8 @@ pub fn _mm_mask_conj_pch(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_conj_pch(k: __mmask8, a: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_conj_pch(k: __mmask8, a: __m128h) -> __m128h { _mm_mask_conj_pch(_mm_setzero_ph(), k, a) } @@ -4043,7 +4157,8 @@ pub fn _mm_maskz_conj_pch(k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_conj_pch(a: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_conj_pch(a: __m256h) -> __m256h { unsafe { transmute(_mm256_xor_si256(transmute(a), _mm256_set1_epi32(i32::MIN))) } } @@ -4056,7 +4171,8 @@ pub fn _mm256_conj_pch(a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_conj_pch(src: __m256h, k: __mmask8, a: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_conj_pch(src: __m256h, k: __mmask8, a: __m256h) -> __m256h { unsafe { let r: __m256 = transmute(_mm256_conj_pch(a)); transmute(simd_select_bitmask(k, r, transmute(src))) @@ -4072,7 +4188,8 @@ pub fn _mm256_mask_conj_pch(src: __m256h, k: __mmask8, a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_conj_pch(k: __mmask8, a: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_conj_pch(k: __mmask8, a: __m256h) -> __m256h { _mm256_mask_conj_pch(_mm256_setzero_ph(), k, a) } @@ -4084,7 +4201,8 @@ pub fn _mm256_maskz_conj_pch(k: __mmask8, a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_conj_pch(a: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_conj_pch(a: __m512h) -> __m512h { unsafe { transmute(_mm512_xor_si512(transmute(a), _mm512_set1_epi32(i32::MIN))) } } @@ -4097,7 +4215,8 @@ pub fn _mm512_conj_pch(a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_conj_pch(src: __m512h, k: __mmask16, a: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_conj_pch(src: __m512h, k: __mmask16, a: __m512h) -> __m512h { unsafe { let r: __m512 = transmute(_mm512_conj_pch(a)); transmute(simd_select_bitmask(k, r, transmute(src))) @@ -4113,7 +4232,8 @@ pub fn _mm512_mask_conj_pch(src: __m512h, k: __mmask16, a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_conj_pch(k: __mmask16, a: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_conj_pch(k: __mmask16, a: __m512h) -> __m512h { _mm512_mask_conj_pch(_mm512_setzero_ph(), k, a) } @@ -5198,7 +5318,8 @@ pub fn _mm_maskz_fcmadd_round_sch( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_fma(a, b, c) } } @@ -5211,7 +5332,8 @@ pub fn _mm_fmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmadd_ph(a, b, c), a) } } @@ -5224,7 +5346,8 @@ pub fn _mm_mask_fmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmadd_ph(a, b, c), c) } } @@ -5237,7 +5360,8 @@ pub fn _mm_mask3_fmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmadd_ph(a, b, c), _mm_setzero_ph()) } } @@ -5249,7 +5373,8 @@ pub fn _mm_maskz_fmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_fmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_fma(a, b, c) } } @@ -5262,7 +5387,8 @@ pub fn _mm256_fmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_fmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmadd_ph(a, b, c), a) } } @@ -5275,7 +5401,8 @@ pub fn _mm256_mask_fmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask3_fmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmadd_ph(a, b, c), c) } } @@ -5288,7 +5415,8 @@ pub fn _mm256_mask3_fmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) - #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_fmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmadd_ph(a, b, c), _mm256_setzero_ph()) } } @@ -5300,7 +5428,8 @@ pub fn _mm256_maskz_fmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) - #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_fmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_fma(a, b, c) } } @@ -5313,7 +5442,8 @@ pub fn _mm512_fmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_fmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmadd_ph(a, b, c), a) } } @@ -5326,7 +5456,8 @@ pub fn _mm512_mask_fmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask3_fmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmadd_ph(a, b, c), c) } } @@ -5339,7 +5470,8 @@ pub fn _mm512_mask3_fmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) - #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_fmadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmadd_ph(a, b, c), _mm512_setzero_ph()) } } @@ -5470,7 +5602,8 @@ pub fn _mm512_maskz_fmadd_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { let extracta: f16 = simd_extract!(a, 0); let extractb: f16 = simd_extract!(b, 0); @@ -5490,7 +5623,8 @@ pub fn _mm_fmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { let mut fmadd: f16 = simd_extract!(a, 0); if k & 1 != 0 { @@ -5512,7 +5646,8 @@ pub fn _mm_mask_fmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { let mut fmadd: f16 = simd_extract!(c, 0); if k & 1 != 0 { @@ -5534,7 +5669,8 @@ pub fn _mm_mask3_fmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fmadd_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmadd_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { let mut fmadd: f16 = 0.0; if k & 1 != 0 { @@ -5697,7 +5833,8 @@ pub fn _mm_maskz_fmadd_round_sh( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_fma(a, b, simd_neg(c)) } } @@ -5710,7 +5847,8 @@ pub fn _mm_fmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsub_ph(a, b, c), a) } } @@ -5723,7 +5861,8 @@ pub fn _mm_mask_fmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsub_ph(a, b, c), c) } } @@ -5736,7 +5875,8 @@ pub fn _mm_mask3_fmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsub_ph(a, b, c), _mm_setzero_ph()) } } @@ -5748,7 +5888,8 @@ pub fn _mm_maskz_fmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_fmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_fma(a, b, simd_neg(c)) } } @@ -5761,7 +5902,8 @@ pub fn _mm256_fmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_fmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsub_ph(a, b, c), a) } } @@ -5774,7 +5916,8 @@ pub fn _mm256_mask_fmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask3_fmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsub_ph(a, b, c), c) } } @@ -5787,7 +5930,8 @@ pub fn _mm256_mask3_fmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) - #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_fmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsub_ph(a, b, c), _mm256_setzero_ph()) } } @@ -5799,7 +5943,8 @@ pub fn _mm256_maskz_fmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) - #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_fmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_fma(a, b, simd_neg(c)) } } @@ -5812,7 +5957,8 @@ pub fn _mm512_fmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_fmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsub_ph(a, b, c), a) } } @@ -5825,7 +5971,8 @@ pub fn _mm512_mask_fmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask3_fmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsub_ph(a, b, c), c) } } @@ -5838,7 +5985,8 @@ pub fn _mm512_mask3_fmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) - #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_fmsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsub_ph(a, b, c), _mm512_setzero_ph()) } } @@ -5969,7 +6117,8 @@ pub fn _mm512_maskz_fmsub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { let extracta: f16 = simd_extract!(a, 0); let extractb: f16 = simd_extract!(b, 0); @@ -5989,7 +6138,8 @@ pub fn _mm_fmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { let mut fmsub: f16 = simd_extract!(a, 0); if k & 1 != 0 { @@ -6011,7 +6161,8 @@ pub fn _mm_mask_fmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { let mut fmsub: f16 = simd_extract!(c, 0); if k & 1 != 0 { @@ -6033,7 +6184,8 @@ pub fn _mm_mask3_fmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fmsub_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmsub_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { let mut fmsub: f16 = 0.0; if k & 1 != 0 { @@ -6187,7 +6339,8 @@ pub fn _mm_maskz_fmsub_round_sh( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_fma(simd_neg(a), b, c) } } @@ -6200,7 +6353,8 @@ pub fn _mm_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fnmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmadd_ph(a, b, c), a) } } @@ -6213,7 +6367,8 @@ pub fn _mm_mask_fnmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmadd_ph(a, b, c), c) } } @@ -6226,7 +6381,8 @@ pub fn _mm_mask3_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> _ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fnmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmadd_ph(a, b, c), _mm_setzero_ph()) } } @@ -6238,7 +6394,8 @@ pub fn _mm_maskz_fnmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> _ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_fma(simd_neg(a), b, c) } } @@ -6251,7 +6408,8 @@ pub fn _mm256_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_fnmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fnmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmadd_ph(a, b, c), a) } } @@ -6264,7 +6422,8 @@ pub fn _mm256_mask_fnmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) - #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask3_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmadd_ph(a, b, c), c) } } @@ -6277,7 +6436,8 @@ pub fn _mm256_mask3_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_fnmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fnmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmadd_ph(a, b, c), _mm256_setzero_ph()) } } @@ -6289,7 +6449,8 @@ pub fn _mm256_maskz_fnmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_fma(simd_neg(a), b, c) } } @@ -6302,7 +6463,8 @@ pub fn _mm512_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_fnmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fnmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmadd_ph(a, b, c), a) } } @@ -6315,7 +6477,8 @@ pub fn _mm512_mask_fnmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) - #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask3_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmadd_ph(a, b, c), c) } } @@ -6328,7 +6491,8 @@ pub fn _mm512_mask3_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_fnmadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fnmadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmadd_ph(a, b, c), _mm512_setzero_ph()) } } @@ -6459,7 +6623,8 @@ pub fn _mm512_maskz_fnmadd_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { let extracta: f16 = simd_extract!(a, 0); let extractb: f16 = simd_extract!(b, 0); @@ -6479,7 +6644,8 @@ pub fn _mm_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fnmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { let mut fnmadd: f16 = simd_extract!(a, 0); if k & 1 != 0 { @@ -6501,7 +6667,8 @@ pub fn _mm_mask_fnmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { let mut fnmadd: f16 = simd_extract!(c, 0); if k & 1 != 0 { @@ -6523,7 +6690,8 @@ pub fn _mm_mask3_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fnmadd_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmadd_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { let mut fnmadd: f16 = 0.0; if k & 1 != 0 { @@ -6685,7 +6853,8 @@ pub fn _mm_maskz_fnmadd_round_sh( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } } @@ -6698,7 +6867,8 @@ pub fn _mm_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fnmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmsub_ph(a, b, c), a) } } @@ -6711,7 +6881,8 @@ pub fn _mm_mask_fnmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmsub_ph(a, b, c), c) } } @@ -6724,7 +6895,8 @@ pub fn _mm_mask3_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> _ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fnmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmsub_ph(a, b, c), _mm_setzero_ph()) } } @@ -6736,7 +6908,8 @@ pub fn _mm_maskz_fnmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> _ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } } @@ -6749,7 +6922,8 @@ pub fn _mm256_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_fnmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fnmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmsub_ph(a, b, c), a) } } @@ -6762,7 +6936,8 @@ pub fn _mm256_mask_fnmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) - #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask3_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmsub_ph(a, b, c), c) } } @@ -6775,7 +6950,8 @@ pub fn _mm256_mask3_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_fnmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fnmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmsub_ph(a, b, c), _mm256_setzero_ph()) } } @@ -6787,7 +6963,8 @@ pub fn _mm256_maskz_fnmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } } @@ -6800,7 +6977,8 @@ pub fn _mm512_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_fnmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fnmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmsub_ph(a, b, c), a) } } @@ -6813,7 +6991,8 @@ pub fn _mm512_mask_fnmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) - #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask3_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmsub_ph(a, b, c), c) } } @@ -6826,7 +7005,8 @@ pub fn _mm512_mask3_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_fnmsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fnmsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmsub_ph(a, b, c), _mm512_setzero_ph()) } } @@ -6957,7 +7137,8 @@ pub fn _mm512_maskz_fnmsub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { let extracta: f16 = simd_extract!(a, 0); let extractb: f16 = simd_extract!(b, 0); @@ -6977,7 +7158,8 @@ pub fn _mm_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fnmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fnmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { let mut fnmsub: f16 = simd_extract!(a, 0); if k & 1 != 0 { @@ -6999,7 +7181,8 @@ pub fn _mm_mask_fnmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { let mut fnmsub: f16 = simd_extract!(c, 0); if k & 1 != 0 { @@ -7021,7 +7204,8 @@ pub fn _mm_mask3_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fnmsub_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fnmsub_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { let mut fnmsub: f16 = 0.0; if k & 1 != 0 { @@ -7183,7 +7367,8 @@ pub fn _mm_maskz_fnmsub_round_sh( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -7200,7 +7385,8 @@ pub fn _mm_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fmaddsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmaddsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmaddsub_ph(a, b, c), a) } } @@ -7213,7 +7399,8 @@ pub fn _mm_mask_fmaddsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmaddsub_ph(a, b, c), c) } } @@ -7226,7 +7413,8 @@ pub fn _mm_mask3_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fmaddsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmaddsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmaddsub_ph(a, b, c), _mm_setzero_ph()) } } @@ -7238,7 +7426,8 @@ pub fn _mm_maskz_fmaddsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -7259,7 +7448,8 @@ pub fn _mm256_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_fmaddsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmaddsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_ph(a, b, c), a) } } @@ -7272,7 +7462,8 @@ pub fn _mm256_mask_fmaddsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask3_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_ph(a, b, c), c) } } @@ -7285,7 +7476,8 @@ pub fn _mm256_mask3_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16 #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_fmaddsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmaddsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_ph(a, b, c), _mm256_setzero_ph()) } } @@ -7297,7 +7489,8 @@ pub fn _mm256_maskz_fmaddsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { let add = simd_fma(a, b, c); let sub = simd_fma(a, b, simd_neg(c)); @@ -7321,7 +7514,8 @@ pub fn _mm512_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_fmaddsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmaddsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_ph(a, b, c), a) } } @@ -7334,7 +7528,8 @@ pub fn _mm512_mask_fmaddsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask3_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_ph(a, b, c), c) } } @@ -7347,7 +7542,8 @@ pub fn _mm512_mask3_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_fmaddsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmaddsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_ph(a, b, c), _mm512_setzero_ph()) } } @@ -7481,7 +7677,8 @@ pub fn _mm512_maskz_fmaddsub_round_ph( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { _mm_fmaddsub_ph(a, b, unsafe { simd_neg(c) }) } @@ -7494,7 +7691,8 @@ pub fn _mm_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_fmsubadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_fmsubadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsubadd_ph(a, b, c), a) } } @@ -7507,7 +7705,8 @@ pub fn _mm_mask_fmsubadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask3_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask3_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsubadd_ph(a, b, c), c) } } @@ -7520,7 +7719,8 @@ pub fn _mm_mask3_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_maskz_fmsubadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_fmsubadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsubadd_ph(a, b, c), _mm_setzero_ph()) } } @@ -7532,7 +7732,8 @@ pub fn _mm_maskz_fmsubadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { _mm256_fmaddsub_ph(a, b, unsafe { simd_neg(c) }) } @@ -7545,7 +7746,8 @@ pub fn _mm256_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_fmsubadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_fmsubadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_ph(a, b, c), a) } } @@ -7558,7 +7760,8 @@ pub fn _mm256_mask_fmsubadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask3_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask3_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_ph(a, b, c), c) } } @@ -7571,7 +7774,8 @@ pub fn _mm256_mask3_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16 #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_maskz_fmsubadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_fmsubadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_ph(a, b, c), _mm256_setzero_ph()) } } @@ -7583,7 +7787,8 @@ pub fn _mm256_maskz_fmsubadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { _mm512_fmaddsub_ph(a, b, unsafe { simd_neg(c) }) } @@ -7596,7 +7801,8 @@ pub fn _mm512_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_fmsubadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_fmsubadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_ph(a, b, c), a) } } @@ -7609,7 +7815,8 @@ pub fn _mm512_mask_fmsubadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask3_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask3_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_ph(a, b, c), c) } } @@ -7622,7 +7829,8 @@ pub fn _mm512_mask3_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd))] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_maskz_fmsubadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_fmsubadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_ph(a, b, c), _mm512_setzero_ph()) } } @@ -11117,7 +11325,8 @@ pub fn _mm_maskz_reduce_round_sh( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_reduce_add_ph(a: __m128h) -> f16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_add_ph(a: __m128h) -> f16 { unsafe { let b = simd_shuffle!(a, a, [4, 5, 6, 7, 0, 1, 2, 3]); let a = _mm_add_ph(a, b); @@ -11134,7 +11343,8 @@ pub fn _mm_reduce_add_ph(a: __m128h) -> f16 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_reduce_add_ph(a: __m256h) -> f16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_add_ph(a: __m256h) -> f16 { unsafe { let p = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]); let q = simd_shuffle!(a, a, [8, 9, 10, 11, 12, 13, 14, 15]); @@ -11149,7 +11359,8 @@ pub fn _mm256_reduce_add_ph(a: __m256h) -> f16 { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_reduce_add_ph(a: __m512h) -> f16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_add_ph(a: __m512h) -> f16 { unsafe { let p = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); let q = simd_shuffle!( @@ -11170,7 +11381,8 @@ pub fn _mm512_reduce_add_ph(a: __m512h) -> f16 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_reduce_mul_ph(a: __m128h) -> f16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_reduce_mul_ph(a: __m128h) -> f16 { unsafe { let b = simd_shuffle!(a, a, [4, 5, 6, 7, 0, 1, 2, 3]); let a = _mm_mul_ph(a, b); @@ -11187,7 +11399,8 @@ pub fn _mm_reduce_mul_ph(a: __m128h) -> f16 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_reduce_mul_ph(a: __m256h) -> f16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_reduce_mul_ph(a: __m256h) -> f16 { unsafe { let p = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]); let q = simd_shuffle!(a, a, [8, 9, 10, 11, 12, 13, 14, 15]); @@ -11202,7 +11415,8 @@ pub fn _mm256_reduce_mul_ph(a: __m256h) -> f16 { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_reduce_mul_ph(a: __m512h) -> f16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_reduce_mul_ph(a: __m512h) -> f16 { unsafe { let p = simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); let q = simd_shuffle!( @@ -11566,7 +11780,8 @@ pub fn _mm_mask_fpclass_sh_mask(k1: __mmask8, a: __m128h) -> __ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_mask_blend_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_blend_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, b, a) } } @@ -11577,7 +11792,8 @@ pub fn _mm_mask_blend_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_mask_blend_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_blend_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, b, a) } } @@ -11588,7 +11804,8 @@ pub fn _mm256_mask_blend_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_mask_blend_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_blend_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, b, a) } } @@ -16304,7 +16521,8 @@ pub fn _mm_maskz_cvt_roundsh_sd(k: __mmask8, a: __m128d, b: __m1 #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_cvtsh_h(a: __m128h) -> f16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsh_h(a: __m128h) -> f16 { unsafe { simd_extract!(a, 0) } } @@ -16314,7 +16532,8 @@ pub fn _mm_cvtsh_h(a: __m128h) -> f16 { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm256_cvtsh_h(a: __m256h) -> f16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtsh_h(a: __m256h) -> f16 { unsafe { simd_extract!(a, 0) } } @@ -16324,7 +16543,8 @@ pub fn _mm256_cvtsh_h(a: __m256h) -> f16 { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm512_cvtsh_h(a: __m512h) -> f16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_cvtsh_h(a: __m512h) -> f16 { unsafe { simd_extract!(a, 0) } } @@ -16334,7 +16554,8 @@ pub fn _mm512_cvtsh_h(a: __m512h) -> f16 { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_cvtsi128_si16(a: __m128i) -> i16 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi128_si16(a: __m128i) -> i16 { unsafe { simd_extract!(a.as_i16x8(), 0) } } @@ -16344,7 +16565,8 @@ pub fn _mm_cvtsi128_si16(a: __m128i) -> i16 { #[inline] #[target_feature(enable = "avx512fp16")] #[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] -pub fn _mm_cvtsi16_si128(a: i16) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtsi16_si128(a: i16) -> __m128i { unsafe { transmute(simd_insert!(i16x8::ZERO, 0, a)) } } @@ -16708,6 +16930,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use crate::core_arch::x86::*; use crate::mem::transmute; use crate::ptr::{addr_of, addr_of_mut}; @@ -16737,14 +16960,14 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_set_ph() { + const unsafe fn test_mm_set_ph() { let r = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let e = _mm_setr_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); assert_eq_m128h(r, e); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_set_ph() { + const unsafe fn test_mm256_set_ph() { let r = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -16755,7 +16978,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_set_ph() { + const unsafe fn test_mm512_set_ph() { let r = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -16770,21 +16993,21 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_set_sh() { + const unsafe fn test_mm_set_sh() { let r = _mm_set_sh(1.0); let e = _mm_set_ph(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); assert_eq_m128h(r, e); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_set1_ph() { + const unsafe fn test_mm_set1_ph() { let r = _mm_set1_ph(1.0); let e = _mm_set_ph(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0); assert_eq_m128h(r, e); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_set1_ph() { + const unsafe fn test_mm256_set1_ph() { let r = _mm256_set1_ph(1.0); let e = _mm256_set_ph( 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, @@ -16793,7 +17016,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_set1_ph() { + const unsafe fn test_mm512_set1_ph() { let r = _mm512_set1_ph(1.0); let e = _mm512_set_ph( 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, @@ -16803,14 +17026,14 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_setr_ph() { + const unsafe fn test_mm_setr_ph() { let r = _mm_setr_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let e = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); assert_eq_m128h(r, e); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_setr_ph() { + const unsafe fn test_mm256_setr_ph() { let r = _mm256_setr_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -16821,7 +17044,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_setr_ph() { + const unsafe fn test_mm512_setr_ph() { let r = _mm512_setr_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -16836,28 +17059,28 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_setzero_ph() { + const unsafe fn test_mm_setzero_ph() { let r = _mm_setzero_ph(); let e = _mm_set1_ph(0.0); assert_eq_m128h(r, e); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_setzero_ph() { + const unsafe fn test_mm256_setzero_ph() { let r = _mm256_setzero_ph(); let e = _mm256_set1_ph(0.0); assert_eq_m256h(r, e); } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_setzero_ph() { + const unsafe fn test_mm512_setzero_ph() { let r = _mm512_setzero_ph(); let e = _mm512_set1_ph(0.0); assert_eq_m512h(r, e); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_castsi128_ph() { + const unsafe fn test_mm_castsi128_ph() { let a = _mm_set1_epi16(0x3c00); let r = _mm_castsi128_ph(a); let e = _mm_set1_ph(1.0); @@ -16865,7 +17088,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_castsi256_ph() { + const unsafe fn test_mm256_castsi256_ph() { let a = _mm256_set1_epi16(0x3c00); let r = _mm256_castsi256_ph(a); let e = _mm256_set1_ph(1.0); @@ -16873,7 +17096,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_castsi512_ph() { + const unsafe fn test_mm512_castsi512_ph() { let a = _mm512_set1_epi16(0x3c00); let r = _mm512_castsi512_ph(a); let e = _mm512_set1_ph(1.0); @@ -16881,7 +17104,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm_castph_si128() { + const unsafe fn test_mm_castph_si128() { let a = _mm_set1_ph(1.0); let r = _mm_castph_si128(a); let e = _mm_set1_epi16(0x3c00); @@ -16889,7 +17112,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm256_castph_si256() { + const unsafe fn test_mm256_castph_si256() { let a = _mm256_set1_ph(1.0); let r = _mm256_castph_si256(a); let e = _mm256_set1_epi16(0x3c00); @@ -16897,7 +17120,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_castph_si512() { + const unsafe fn test_mm512_castph_si512() { let a = _mm512_set1_ph(1.0); let r = _mm512_castph_si512(a); let e = _mm512_set1_epi16(0x3c00); @@ -16905,7 +17128,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_castps_ph() { + const unsafe fn test_mm_castps_ph() { let a = _mm_castsi128_ps(_mm_set1_epi16(0x3c00)); let r = _mm_castps_ph(a); let e = _mm_set1_ph(1.0); @@ -16913,7 +17136,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_castps_ph() { + const unsafe fn test_mm256_castps_ph() { let a = _mm256_castsi256_ps(_mm256_set1_epi16(0x3c00)); let r = _mm256_castps_ph(a); let e = _mm256_set1_ph(1.0); @@ -16921,7 +17144,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_castps_ph() { + const unsafe fn test_mm512_castps_ph() { let a = _mm512_castsi512_ps(_mm512_set1_epi16(0x3c00)); let r = _mm512_castps_ph(a); let e = _mm512_set1_ph(1.0); @@ -16929,7 +17152,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm_castph_ps() { + const unsafe fn test_mm_castph_ps() { let a = _mm_castsi128_ph(_mm_set1_epi32(0x3f800000)); let r = _mm_castph_ps(a); let e = _mm_set1_ps(1.0); @@ -16937,7 +17160,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm256_castph_ps() { + const unsafe fn test_mm256_castph_ps() { let a = _mm256_castsi256_ph(_mm256_set1_epi32(0x3f800000)); let r = _mm256_castph_ps(a); let e = _mm256_set1_ps(1.0); @@ -16945,7 +17168,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_castph_ps() { + const unsafe fn test_mm512_castph_ps() { let a = _mm512_castsi512_ph(_mm512_set1_epi32(0x3f800000)); let r = _mm512_castph_ps(a); let e = _mm512_set1_ps(1.0); @@ -16953,7 +17176,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_castpd_ph() { + const unsafe fn test_mm_castpd_ph() { let a = _mm_castsi128_pd(_mm_set1_epi16(0x3c00)); let r = _mm_castpd_ph(a); let e = _mm_set1_ph(1.0); @@ -16961,7 +17184,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_castpd_ph() { + const unsafe fn test_mm256_castpd_ph() { let a = _mm256_castsi256_pd(_mm256_set1_epi16(0x3c00)); let r = _mm256_castpd_ph(a); let e = _mm256_set1_ph(1.0); @@ -16969,7 +17192,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_castpd_ph() { + const unsafe fn test_mm512_castpd_ph() { let a = _mm512_castsi512_pd(_mm512_set1_epi16(0x3c00)); let r = _mm512_castpd_ph(a); let e = _mm512_set1_ph(1.0); @@ -16977,7 +17200,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm_castph_pd() { + const unsafe fn test_mm_castph_pd() { let a = _mm_castsi128_ph(_mm_set1_epi64x(0x3ff0000000000000)); let r = _mm_castph_pd(a); let e = _mm_set1_pd(1.0); @@ -16985,7 +17208,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm256_castph_pd() { + const unsafe fn test_mm256_castph_pd() { let a = _mm256_castsi256_ph(_mm256_set1_epi64x(0x3ff0000000000000)); let r = _mm256_castph_pd(a); let e = _mm256_set1_pd(1.0); @@ -16993,7 +17216,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_castph_pd() { + const unsafe fn test_mm512_castph_pd() { let a = _mm512_castsi512_ph(_mm512_set1_epi64(0x3ff0000000000000)); let r = _mm512_castph_pd(a); let e = _mm512_set1_pd(1.0); @@ -17001,7 +17224,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_castph256_ph128() { + const unsafe fn test_mm256_castph256_ph128() { let a = _mm256_setr_ph( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -17011,7 +17234,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm512_castph512_ph128() { + const unsafe fn test_mm512_castph512_ph128() { let a = _mm512_setr_ph( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32., @@ -17022,7 +17245,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm512_castph512_ph256() { + const unsafe fn test_mm512_castph512_ph256() { let a = _mm512_setr_ph( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32., @@ -17035,21 +17258,21 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_castph128_ph256() { + const unsafe fn test_mm256_castph128_ph256() { let a = _mm_setr_ph(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_castph128_ph256(a); assert_eq_m128h(_mm256_castph256_ph128(r), a); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm512_castph128_ph512() { + const unsafe fn test_mm512_castph128_ph512() { let a = _mm_setr_ph(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_castph128_ph512(a); assert_eq_m128h(_mm512_castph512_ph128(r), a); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm512_castph256_ph512() { + const unsafe fn test_mm512_castph256_ph512() { let a = _mm256_setr_ph( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -17058,7 +17281,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_zextph128_ph256() { + const unsafe fn test_mm256_zextph128_ph256() { let a = _mm_setr_ph(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm256_zextph128_ph256(a); let e = _mm256_setr_ph( @@ -17068,7 +17291,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_zextph128_ph512() { + const unsafe fn test_mm512_zextph128_ph512() { let a = _mm_setr_ph(1., 2., 3., 4., 5., 6., 7., 8.); let r = _mm512_zextph128_ph512(a); let e = _mm512_setr_ph( @@ -17079,7 +17302,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_zextph256_ph512() { + const unsafe fn test_mm512_zextph256_ph512() { let a = _mm256_setr_ph( 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); @@ -17346,14 +17569,14 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_load_ph() { + const unsafe fn test_mm_load_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_load_ph(addr_of!(a).cast()); assert_eq_m128h(a, b); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_load_ph() { + const unsafe fn test_mm256_load_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17362,7 +17585,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_load_ph() { + const unsafe fn test_mm512_load_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17373,7 +17596,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_load_sh() { + const unsafe fn test_mm_load_sh() { let a = _mm_set_sh(1.0); let b = _mm_load_sh(addr_of!(a).cast()); assert_eq_m128h(a, b); @@ -17399,7 +17622,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_loadu_ph() { + const unsafe fn test_mm_loadu_ph() { let array = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let r = _mm_loadu_ph(array.as_ptr()); let e = _mm_setr_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); @@ -17407,7 +17630,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_loadu_ph() { + const unsafe fn test_mm256_loadu_ph() { let array = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ]; @@ -17419,7 +17642,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_loadu_ph() { + const unsafe fn test_mm512_loadu_ph() { let array = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17435,7 +17658,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_move_sh() { + const unsafe fn test_mm_move_sh() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_sh(9.0); let r = _mm_move_sh(a, b); @@ -17444,7 +17667,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_move_sh() { + const unsafe fn test_mm_mask_move_sh() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_sh(9.0); let src = _mm_set_sh(10.0); @@ -17454,7 +17677,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_move_sh() { + const unsafe fn test_mm_maskz_move_sh() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_sh(9.0); let r = _mm_maskz_move_sh(0, a, b); @@ -17463,7 +17686,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_store_ph() { + const unsafe fn test_mm_store_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let mut b = _mm_setzero_ph(); _mm_store_ph(addr_of_mut!(b).cast(), a); @@ -17471,7 +17694,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_store_ph() { + const unsafe fn test_mm256_store_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17481,7 +17704,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_store_ph() { + const unsafe fn test_mm512_store_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17493,7 +17716,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_store_sh() { + const unsafe fn test_mm_store_sh() { let a = _mm_set_sh(1.0); let mut b = _mm_setzero_ph(); _mm_store_sh(addr_of_mut!(b).cast(), a); @@ -17511,7 +17734,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_storeu_ph() { + const unsafe fn test_mm_storeu_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let mut array = [0.0; 8]; _mm_storeu_ph(array.as_mut_ptr(), a); @@ -17519,7 +17742,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_storeu_ph() { + const unsafe fn test_mm256_storeu_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17529,7 +17752,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_storeu_ph() { + const unsafe fn test_mm512_storeu_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17541,7 +17764,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_add_ph() { + const unsafe fn test_mm_add_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); let r = _mm_add_ph(a, b); @@ -17550,7 +17773,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_add_ph() { + const unsafe fn test_mm_mask_add_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); let src = _mm_set_ph(10., 11., 12., 13., 14., 15., 16., 17.); @@ -17560,7 +17783,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_add_ph() { + const unsafe fn test_mm_maskz_add_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); let r = _mm_maskz_add_ph(0b01010101, a, b); @@ -17569,7 +17792,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_add_ph() { + const unsafe fn test_mm256_add_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17582,7 +17805,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_add_ph() { + const unsafe fn test_mm256_mask_add_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17600,7 +17823,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_add_ph() { + const unsafe fn test_mm256_maskz_add_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17615,7 +17838,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_add_ph() { + const unsafe fn test_mm512_add_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17632,7 +17855,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_add_ph() { + const unsafe fn test_mm512_mask_add_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17656,7 +17879,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_add_ph() { + const unsafe fn test_mm512_maskz_add_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17786,7 +18009,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_add_sh() { + const unsafe fn test_mm_add_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let r = _mm_add_sh(a, b); @@ -17795,7 +18018,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_add_sh() { + const unsafe fn test_mm_mask_add_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let src = _mm_set_sh(4.0); @@ -17808,7 +18031,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_add_sh() { + const unsafe fn test_mm_maskz_add_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let r = _mm_maskz_add_sh(0, a, b); @@ -17820,7 +18043,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_sub_ph() { + const unsafe fn test_mm_sub_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); let r = _mm_sub_ph(a, b); @@ -17829,7 +18052,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_sub_ph() { + const unsafe fn test_mm_mask_sub_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); let src = _mm_set_ph(10., 11., 12., 13., 14., 15., 16., 17.); @@ -17839,7 +18062,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_sub_ph() { + const unsafe fn test_mm_maskz_sub_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); let r = _mm_maskz_sub_ph(0b01010101, a, b); @@ -17848,7 +18071,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_sub_ph() { + const unsafe fn test_mm256_sub_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17864,7 +18087,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_sub_ph() { + const unsafe fn test_mm256_mask_sub_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17882,7 +18105,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_sub_ph() { + const unsafe fn test_mm256_maskz_sub_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17897,7 +18120,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_sub_ph() { + const unsafe fn test_mm512_sub_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17918,7 +18141,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_sub_ph() { + const unsafe fn test_mm512_mask_sub_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17942,7 +18165,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_sub_ph() { + const unsafe fn test_mm512_maskz_sub_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -18076,7 +18299,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_sub_sh() { + const unsafe fn test_mm_sub_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let r = _mm_sub_sh(a, b); @@ -18085,7 +18308,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_sub_sh() { + const unsafe fn test_mm_mask_sub_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let src = _mm_set_sh(4.0); @@ -18098,7 +18321,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_sub_sh() { + const unsafe fn test_mm_maskz_sub_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let r = _mm_maskz_sub_sh(0, a, b); @@ -18110,7 +18333,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mul_ph() { + const unsafe fn test_mm_mul_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); let r = _mm_mul_ph(a, b); @@ -18119,7 +18342,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_mul_ph() { + const unsafe fn test_mm_mask_mul_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); let src = _mm_set_ph(10., 11., 12., 13., 14., 15., 16., 17.); @@ -18129,7 +18352,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_mul_ph() { + const unsafe fn test_mm_maskz_mul_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0); let r = _mm_maskz_mul_ph(0b01010101, a, b); @@ -18138,7 +18361,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mul_ph() { + const unsafe fn test_mm256_mul_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -18154,7 +18377,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_mul_ph() { + const unsafe fn test_mm256_mask_mul_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -18172,7 +18395,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_mul_ph() { + const unsafe fn test_mm256_maskz_mul_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -18187,7 +18410,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mul_ph() { + const unsafe fn test_mm512_mul_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -18208,7 +18431,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_mul_ph() { + const unsafe fn test_mm512_mask_mul_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -18232,7 +18455,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_mul_ph() { + const unsafe fn test_mm512_maskz_mul_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -18366,7 +18589,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mul_sh() { + const unsafe fn test_mm_mul_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let r = _mm_mul_sh(a, b); @@ -18375,7 +18598,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_mul_sh() { + const unsafe fn test_mm_mask_mul_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let src = _mm_set_sh(4.0); @@ -18388,7 +18611,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_mul_sh() { + const unsafe fn test_mm_maskz_mul_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let r = _mm_maskz_mul_sh(0, a, b); @@ -18400,7 +18623,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_div_ph() { + const unsafe fn test_mm_div_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let r = _mm_div_ph(a, b); @@ -18409,7 +18632,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_div_ph() { + const unsafe fn test_mm_mask_div_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let src = _mm_set_ph(4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0); @@ -18419,7 +18642,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_div_ph() { + const unsafe fn test_mm_maskz_div_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let r = _mm_maskz_div_ph(0b01010101, a, b); @@ -18428,7 +18651,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_div_ph() { + const unsafe fn test_mm256_div_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let r = _mm256_div_ph(a, b); @@ -18437,7 +18660,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_div_ph() { + const unsafe fn test_mm256_mask_div_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let src = _mm256_set_ph( @@ -18452,7 +18675,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_div_ph() { + const unsafe fn test_mm256_maskz_div_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let r = _mm256_maskz_div_ph(0b0101010101010101, a, b); @@ -18463,7 +18686,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_div_ph() { + const unsafe fn test_mm512_div_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let r = _mm512_div_ph(a, b); @@ -18472,7 +18695,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_div_ph() { + const unsafe fn test_mm512_mask_div_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let src = _mm512_set_ph( @@ -18489,7 +18712,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_div_ph() { + const unsafe fn test_mm512_maskz_div_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let r = _mm512_maskz_div_ph(0b01010101010101010101010101010101, a, b); @@ -18588,7 +18811,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_div_sh() { + const unsafe fn test_mm_div_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let r = _mm_div_sh(a, b); @@ -18597,7 +18820,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_div_sh() { + const unsafe fn test_mm_mask_div_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let src = _mm_set_sh(4.0); @@ -18610,7 +18833,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_div_sh() { + const unsafe fn test_mm_maskz_div_sh() { let a = _mm_set_sh(1.0); let b = _mm_set_sh(2.0); let r = _mm_maskz_div_sh(0, a, b); @@ -19454,7 +19677,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_abs_ph() { + const unsafe fn test_mm_abs_ph() { let a = _mm_set_ph(-1.0, 0.0, 1.0, -2.0, 3.0, -4.0, 5.0, -6.0); let r = _mm_abs_ph(a); let e = _mm_set_ph(1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0); @@ -19462,7 +19685,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_abs_ph() { + const unsafe fn test_mm256_abs_ph() { let a = _mm256_set_ph( -1.0, 0.0, 1.0, -2.0, 3.0, -4.0, 5.0, -6.0, 7.0, -8.0, 9.0, -10.0, 11.0, -12.0, 13.0, -14.0, @@ -19475,7 +19698,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_abs_ph() { + const unsafe fn test_mm512_abs_ph() { let a = _mm512_set_ph( -1.0, 0.0, 1.0, -2.0, 3.0, -4.0, 5.0, -6.0, 7.0, -8.0, 9.0, -10.0, 11.0, -12.0, 13.0, -14.0, 15.0, -16.0, 17.0, -18.0, 19.0, -20.0, 21.0, -22.0, 23.0, -24.0, 25.0, -26.0, @@ -19491,7 +19714,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_conj_pch() { + const unsafe fn test_mm_conj_pch() { let a = _mm_set1_pch(0.0, 1.0); let r = _mm_conj_pch(a); let e = _mm_set1_pch(0.0, -1.0); @@ -19499,7 +19722,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_conj_pch() { + const unsafe fn test_mm_mask_conj_pch() { let a = _mm_set1_pch(0.0, 1.0); let src = _mm_setr_ph(2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0); let r = _mm_mask_conj_pch(src, 0b0101, a); @@ -19508,7 +19731,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_conj_pch() { + const unsafe fn test_mm_maskz_conj_pch() { let a = _mm_set1_pch(0.0, 1.0); let r = _mm_maskz_conj_pch(0b0101, a); let e = _mm_setr_ph(0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0); @@ -19516,7 +19739,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_conj_pch() { + const unsafe fn test_mm256_conj_pch() { let a = _mm256_set1_pch(0.0, 1.0); let r = _mm256_conj_pch(a); let e = _mm256_set1_pch(0.0, -1.0); @@ -19524,7 +19747,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_conj_pch() { + const unsafe fn test_mm256_mask_conj_pch() { let a = _mm256_set1_pch(0.0, 1.0); let src = _mm256_setr_ph( 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, @@ -19537,7 +19760,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_conj_pch() { + const unsafe fn test_mm256_maskz_conj_pch() { let a = _mm256_set1_pch(0.0, 1.0); let r = _mm256_maskz_conj_pch(0b01010101, a); let e = _mm256_setr_ph( @@ -19547,7 +19770,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_conj_pch() { + const unsafe fn test_mm512_conj_pch() { let a = _mm512_set1_pch(0.0, 1.0); let r = _mm512_conj_pch(a); let e = _mm512_set1_pch(0.0, -1.0); @@ -19555,7 +19778,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_conj_pch() { + const unsafe fn test_mm512_mask_conj_pch() { let a = _mm512_set1_pch(0.0, 1.0); let src = _mm512_setr_ph( 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, @@ -19572,7 +19795,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_conj_pch() { + const unsafe fn test_mm512_maskz_conj_pch() { let a = _mm512_set1_pch(0.0, 1.0); let r = _mm512_maskz_conj_pch(0b0101010101010101, a); let e = _mm512_setr_ph( @@ -20203,7 +20426,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fmadd_ph() { + const unsafe fn test_mm_fmadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20213,7 +20436,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fmadd_ph() { + const unsafe fn test_mm_mask_fmadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20223,7 +20446,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fmadd_ph() { + const unsafe fn test_mm_mask3_fmadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20233,7 +20456,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fmadd_ph() { + const unsafe fn test_mm_maskz_fmadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20243,7 +20466,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_fmadd_ph() { + const unsafe fn test_mm256_fmadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20253,7 +20476,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_fmadd_ph() { + const unsafe fn test_mm256_mask_fmadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20265,7 +20488,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask3_fmadd_ph() { + const unsafe fn test_mm256_mask3_fmadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20277,7 +20500,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_fmadd_ph() { + const unsafe fn test_mm256_maskz_fmadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20289,7 +20512,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_fmadd_ph() { + const unsafe fn test_mm512_fmadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20299,7 +20522,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_fmadd_ph() { + const unsafe fn test_mm512_mask_fmadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20312,7 +20535,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask3_fmadd_ph() { + const unsafe fn test_mm512_mask3_fmadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20325,7 +20548,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_fmadd_ph() { + const unsafe fn test_mm512_maskz_fmadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20402,7 +20625,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fmadd_sh() { + const unsafe fn test_mm_fmadd_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -20412,7 +20635,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fmadd_sh() { + const unsafe fn test_mm_mask_fmadd_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -20425,7 +20648,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fmadd_sh() { + const unsafe fn test_mm_mask3_fmadd_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -20438,7 +20661,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fmadd_sh() { + const unsafe fn test_mm_maskz_fmadd_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -20512,7 +20735,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fmsub_ph() { + const unsafe fn test_mm_fmsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20522,7 +20745,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fmsub_ph() { + const unsafe fn test_mm_mask_fmsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20532,7 +20755,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fmsub_ph() { + const unsafe fn test_mm_mask3_fmsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20542,7 +20765,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fmsub_ph() { + const unsafe fn test_mm_maskz_fmsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20552,7 +20775,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_fmsub_ph() { + const unsafe fn test_mm256_fmsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20562,7 +20785,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_fmsub_ph() { + const unsafe fn test_mm256_mask_fmsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20574,7 +20797,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask3_fmsub_ph() { + const unsafe fn test_mm256_mask3_fmsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20586,7 +20809,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_fmsub_ph() { + const unsafe fn test_mm256_maskz_fmsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20598,7 +20821,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_fmsub_ph() { + const unsafe fn test_mm512_fmsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20608,7 +20831,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_fmsub_ph() { + const unsafe fn test_mm512_mask_fmsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20621,7 +20844,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask3_fmsub_ph() { + const unsafe fn test_mm512_mask3_fmsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20634,7 +20857,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_fmsub_ph() { + const unsafe fn test_mm512_maskz_fmsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20711,7 +20934,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fmsub_sh() { + const unsafe fn test_mm_fmsub_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -20721,7 +20944,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fmsub_sh() { + const unsafe fn test_mm_mask_fmsub_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -20734,7 +20957,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fmsub_sh() { + const unsafe fn test_mm_mask3_fmsub_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -20747,7 +20970,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fmsub_sh() { + const unsafe fn test_mm_maskz_fmsub_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -20821,7 +21044,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fnmadd_ph() { + const unsafe fn test_mm_fnmadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20831,7 +21054,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fnmadd_ph() { + const unsafe fn test_mm_mask_fnmadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20841,7 +21064,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fnmadd_ph() { + const unsafe fn test_mm_mask3_fnmadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20851,7 +21074,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fnmadd_ph() { + const unsafe fn test_mm_maskz_fnmadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -20861,7 +21084,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_fnmadd_ph() { + const unsafe fn test_mm256_fnmadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20871,7 +21094,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_fnmadd_ph() { + const unsafe fn test_mm256_mask_fnmadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20883,7 +21106,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask3_fnmadd_ph() { + const unsafe fn test_mm256_mask3_fnmadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20895,7 +21118,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_fnmadd_ph() { + const unsafe fn test_mm256_maskz_fnmadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -20907,7 +21130,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_fnmadd_ph() { + const unsafe fn test_mm512_fnmadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20917,7 +21140,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_fnmadd_ph() { + const unsafe fn test_mm512_mask_fnmadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20930,7 +21153,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask3_fnmadd_ph() { + const unsafe fn test_mm512_mask3_fnmadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -20943,7 +21166,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_fnmadd_ph() { + const unsafe fn test_mm512_maskz_fnmadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21021,7 +21244,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fnmadd_sh() { + const unsafe fn test_mm_fnmadd_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -21031,7 +21254,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fnmadd_sh() { + const unsafe fn test_mm_mask_fnmadd_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -21044,7 +21267,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fnmadd_sh() { + const unsafe fn test_mm_mask3_fnmadd_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -21057,7 +21280,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fnmadd_sh() { + const unsafe fn test_mm_maskz_fnmadd_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -21131,7 +21354,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fnmsub_ph() { + const unsafe fn test_mm_fnmsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21141,7 +21364,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fnmsub_ph() { + const unsafe fn test_mm_mask_fnmsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21151,7 +21374,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fnmsub_ph() { + const unsafe fn test_mm_mask3_fnmsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21161,7 +21384,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fnmsub_ph() { + const unsafe fn test_mm_maskz_fnmsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21171,7 +21394,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_fnmsub_ph() { + const unsafe fn test_mm256_fnmsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21181,7 +21404,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_fnmsub_ph() { + const unsafe fn test_mm256_mask_fnmsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21193,7 +21416,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask3_fnmsub_ph() { + const unsafe fn test_mm256_mask3_fnmsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21205,7 +21428,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_fnmsub_ph() { + const unsafe fn test_mm256_maskz_fnmsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21217,7 +21440,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_fnmsub_ph() { + const unsafe fn test_mm512_fnmsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21227,7 +21450,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_fnmsub_ph() { + const unsafe fn test_mm512_mask_fnmsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21240,7 +21463,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask3_fnmsub_ph() { + const unsafe fn test_mm512_mask3_fnmsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21253,7 +21476,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_fnmsub_ph() { + const unsafe fn test_mm512_maskz_fnmsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21331,7 +21554,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fnmsub_sh() { + const unsafe fn test_mm_fnmsub_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -21341,7 +21564,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fnmsub_sh() { + const unsafe fn test_mm_mask_fnmsub_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -21354,7 +21577,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fnmsub_sh() { + const unsafe fn test_mm_mask3_fnmsub_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -21367,7 +21590,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fnmsub_sh() { + const unsafe fn test_mm_maskz_fnmsub_sh() { let a = _mm_setr_ph(1.0, 10., 11., 12., 13., 14., 15., 16.); let b = _mm_setr_ph(2.0, 20., 21., 22., 23., 24., 25., 26.); let c = _mm_setr_ph(3.0, 30., 31., 32., 33., 34., 35., 36.); @@ -21441,7 +21664,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fmaddsub_ph() { + const unsafe fn test_mm_fmaddsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21451,7 +21674,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fmaddsub_ph() { + const unsafe fn test_mm_mask_fmaddsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21461,7 +21684,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fmaddsub_ph() { + const unsafe fn test_mm_mask3_fmaddsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21471,7 +21694,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fmaddsub_ph() { + const unsafe fn test_mm_maskz_fmaddsub_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21481,7 +21704,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_fmaddsub_ph() { + const unsafe fn test_mm256_fmaddsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21493,7 +21716,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_fmaddsub_ph() { + const unsafe fn test_mm256_mask_fmaddsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21505,7 +21728,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask3_fmaddsub_ph() { + const unsafe fn test_mm256_mask3_fmaddsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21517,7 +21740,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_fmaddsub_ph() { + const unsafe fn test_mm256_maskz_fmaddsub_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21529,7 +21752,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_fmaddsub_ph() { + const unsafe fn test_mm512_fmaddsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21542,7 +21765,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_fmaddsub_ph() { + const unsafe fn test_mm512_mask_fmaddsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21555,7 +21778,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask3_fmaddsub_ph() { + const unsafe fn test_mm512_mask3_fmaddsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21568,7 +21791,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_fmaddsub_ph() { + const unsafe fn test_mm512_maskz_fmaddsub_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21649,7 +21872,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_fmsubadd_ph() { + const unsafe fn test_mm_fmsubadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21659,7 +21882,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_fmsubadd_ph() { + const unsafe fn test_mm_mask_fmsubadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21669,7 +21892,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask3_fmsubadd_ph() { + const unsafe fn test_mm_mask3_fmsubadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21679,7 +21902,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_fmsubadd_ph() { + const unsafe fn test_mm_maskz_fmsubadd_ph() { let a = _mm_set1_ph(1.0); let b = _mm_set1_ph(2.0); let c = _mm_set1_ph(3.0); @@ -21689,7 +21912,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_fmsubadd_ph() { + const unsafe fn test_mm256_fmsubadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21701,7 +21924,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_fmsubadd_ph() { + const unsafe fn test_mm256_mask_fmsubadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21713,7 +21936,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask3_fmsubadd_ph() { + const unsafe fn test_mm256_mask3_fmsubadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21725,7 +21948,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_maskz_fmsubadd_ph() { + const unsafe fn test_mm256_maskz_fmsubadd_ph() { let a = _mm256_set1_ph(1.0); let b = _mm256_set1_ph(2.0); let c = _mm256_set1_ph(3.0); @@ -21737,7 +21960,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_fmsubadd_ph() { + const unsafe fn test_mm512_fmsubadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21750,7 +21973,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_fmsubadd_ph() { + const unsafe fn test_mm512_mask_fmsubadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21763,7 +21986,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask3_fmsubadd_ph() { + const unsafe fn test_mm512_mask3_fmsubadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -21776,7 +21999,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_maskz_fmsubadd_ph() { + const unsafe fn test_mm512_maskz_fmsubadd_ph() { let a = _mm512_set1_ph(1.0); let b = _mm512_set1_ph(2.0); let c = _mm512_set1_ph(3.0); @@ -23741,42 +23964,42 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_reduce_add_ph() { + const unsafe fn test_mm_reduce_add_ph() { let a = _mm_set1_ph(2.0); let r = _mm_reduce_add_ph(a); assert_eq!(r, 16.0); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_reduce_add_ph() { + const unsafe fn test_mm256_reduce_add_ph() { let a = _mm256_set1_ph(2.0); let r = _mm256_reduce_add_ph(a); assert_eq!(r, 32.0); } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_reduce_add_ph() { + const unsafe fn test_mm512_reduce_add_ph() { let a = _mm512_set1_ph(2.0); let r = _mm512_reduce_add_ph(a); assert_eq!(r, 64.0); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_reduce_mul_ph() { + const unsafe fn test_mm_reduce_mul_ph() { let a = _mm_set1_ph(2.0); let r = _mm_reduce_mul_ph(a); assert_eq!(r, 256.0); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_reduce_mul_ph() { + const unsafe fn test_mm256_reduce_mul_ph() { let a = _mm256_set1_ph(2.0); let r = _mm256_reduce_mul_ph(a); assert_eq!(r, 65536.0); } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_reduce_mul_ph() { + const unsafe fn test_mm512_reduce_mul_ph() { let a = _mm512_set1_ph(2.0); let r = _mm512_reduce_mul_ph(a); assert_eq!(r, 16777216.0); @@ -24013,7 +24236,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_blend_ph() { + const unsafe fn test_mm_mask_blend_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let b = _mm_set_ph(-1.0, -2.0, -3.0, -4.0, -5.0, -6.0, -7.0, -8.0); let r = _mm_mask_blend_ph(0b01010101, a, b); @@ -24022,7 +24245,7 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm256_mask_blend_ph() { + const unsafe fn test_mm256_mask_blend_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -24039,7 +24262,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_mask_blend_ph() { + const unsafe fn test_mm512_mask_blend_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -27310,14 +27533,14 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm_cvtsh_h() { + const unsafe fn test_mm_cvtsh_h() { let a = _mm_setr_ph(1.0, 2.0, 3.0, 42.0, 5.0, 6.0, 7.0, 8.0); let r = _mm_cvtsh_h(a); assert_eq!(r, 1.0); } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm256_cvtsh_h() { + const unsafe fn test_mm256_cvtsh_h() { let a = _mm256_setr_ph( 1.0, 2.0, 3.0, 42.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -27326,7 +27549,7 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm512_cvtsh_h() { + const unsafe fn test_mm512_cvtsh_h() { let a = _mm512_setr_ph( 1.0, 2.0, 3.0, 42.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -27337,14 +27560,14 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm_cvtsi128_si16() { + const unsafe fn test_mm_cvtsi128_si16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let r = _mm_cvtsi128_si16(a); assert_eq!(r, 1); } #[simd_test(enable = "avx512fp16")] - unsafe fn test_mm_cvtsi16_si128() { + const unsafe fn test_mm_cvtsi16_si128() { let a = 1; let r = _mm_cvtsi16_si128(a); let e = _mm_setr_epi16(1, 0, 0, 0, 0, 0, 0, 0); diff --git a/library/stdarch/crates/core_arch/src/x86/f16c.rs b/library/stdarch/crates/core_arch/src/x86/f16c.rs index 519cc38294a3..09971939ba44 100644 --- a/library/stdarch/crates/core_arch/src/x86/f16c.rs +++ b/library/stdarch/crates/core_arch/src/x86/f16c.rs @@ -25,7 +25,8 @@ unsafe extern "unadjusted" { #[target_feature(enable = "f16c")] #[cfg_attr(test, assert_instr("vcvtph2ps"))] #[stable(feature = "x86_f16c_intrinsics", since = "1.68.0")] -pub fn _mm_cvtph_ps(a: __m128i) -> __m128 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_cvtph_ps(a: __m128i) -> __m128 { unsafe { let a: f16x8 = transmute(a); let a: f16x4 = simd_shuffle!(a, a, [0, 1, 2, 3]); @@ -41,7 +42,8 @@ pub fn _mm_cvtph_ps(a: __m128i) -> __m128 { #[target_feature(enable = "f16c")] #[cfg_attr(test, assert_instr("vcvtph2ps"))] #[stable(feature = "x86_f16c_intrinsics", since = "1.68.0")] -pub fn _mm256_cvtph_ps(a: __m128i) -> __m256 { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_cvtph_ps(a: __m128i) -> __m256 { unsafe { let a: f16x8 = transmute(a); simd_cast(a) @@ -103,6 +105,7 @@ pub fn _mm256_cvtps_ph(a: __m256) -> __m128i { #[cfg(test)] mod tests { + use crate::core_arch::assert_eq_const as assert_eq; use crate::{core_arch::x86::*, mem::transmute}; use stdarch_test::simd_test; @@ -116,7 +119,7 @@ mod tests { const F16_EIGHT: i16 = 0x4800; #[simd_test(enable = "f16c")] - unsafe fn test_mm_cvtph_ps() { + const unsafe fn test_mm_cvtph_ps() { let a = _mm_set_epi16(0, 0, 0, 0, F16_ONE, F16_TWO, F16_THREE, F16_FOUR); let r = _mm_cvtph_ps(a); let e = _mm_set_ps(1.0, 2.0, 3.0, 4.0); @@ -124,7 +127,7 @@ mod tests { } #[simd_test(enable = "f16c")] - unsafe fn test_mm256_cvtph_ps() { + const unsafe fn test_mm256_cvtph_ps() { let a = _mm_set_epi16( F16_ONE, F16_TWO, F16_THREE, F16_FOUR, F16_FIVE, F16_SIX, F16_SEVEN, F16_EIGHT, ); From e4b8c5a6a5d52532e8bb23196f1b0e3d1b9f90e4 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Mon, 1 Dec 2025 22:27:51 +0000 Subject: [PATCH 0242/3801] fix: `useless_conversion` wrongly unmangled macros --- clippy_lints/src/useless_conversion.rs | 5 ++++- tests/ui/useless_conversion.fixed | 11 +++++++++++ tests/ui/useless_conversion.rs | 11 +++++++++++ tests/ui/useless_conversion.stderr | 8 +++++++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index 0cf5b9431a34..c06313d1a4c4 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -354,7 +354,10 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { return; } - let sugg = snippet(cx, recv.span, "").into_owned(); + let mut applicability = Applicability::MachineApplicable; + let sugg = snippet_with_context(cx, recv.span, e.span.ctxt(), "", &mut applicability) + .0 + .into_owned(); span_lint_and_sugg( cx, USELESS_CONVERSION, diff --git a/tests/ui/useless_conversion.fixed b/tests/ui/useless_conversion.fixed index 9de7d2c67149..adf5e58d9a1a 100644 --- a/tests/ui/useless_conversion.fixed +++ b/tests/ui/useless_conversion.fixed @@ -442,3 +442,14 @@ fn issue14739() { let _ = R.map(|_x| 0); //~^ useless_conversion } + +fn issue16165() { + macro_rules! mac { + (iter $e:expr) => { + $e.iter() + }; + } + + for _ in mac!(iter [1, 2]) {} + //~^ useless_conversion +} diff --git a/tests/ui/useless_conversion.rs b/tests/ui/useless_conversion.rs index 38cd1175aa48..d95fe49e2e2b 100644 --- a/tests/ui/useless_conversion.rs +++ b/tests/ui/useless_conversion.rs @@ -442,3 +442,14 @@ fn issue14739() { let _ = R.into_iter().map(|_x| 0); //~^ useless_conversion } + +fn issue16165() { + macro_rules! mac { + (iter $e:expr) => { + $e.iter() + }; + } + + for _ in mac!(iter [1, 2]).into_iter() {} + //~^ useless_conversion +} diff --git a/tests/ui/useless_conversion.stderr b/tests/ui/useless_conversion.stderr index 3bfaf1411c2c..052c664f6f2e 100644 --- a/tests/ui/useless_conversion.stderr +++ b/tests/ui/useless_conversion.stderr @@ -389,5 +389,11 @@ error: useless conversion to the same type: `std::ops::Range` LL | let _ = R.into_iter().map(|_x| 0); | ^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `R` -error: aborting due to 43 previous errors +error: useless conversion to the same type: `std::slice::Iter<'_, i32>` + --> tests/ui/useless_conversion.rs:453:14 + | +LL | for _ in mac!(iter [1, 2]).into_iter() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `mac!(iter [1, 2])` + +error: aborting due to 44 previous errors From b07013c4fdfc0bb68044e4f39ab66d4f53e40dd9 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Mon, 1 Dec 2025 07:21:47 -0700 Subject: [PATCH 0243/3801] chore: Update annotate-snippets to 0.12.10 --- tests/ui/manual_async_fn.stderr | 36 +++++++++++++++++++ tests/ui/map_unwrap_or.stderr | 4 +++ tests/ui/match_same_arms.stderr | 1 - .../ui/non_canonical_partial_ord_impl.stderr | 2 ++ tests/ui/print_literal.stderr | 1 + 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/tests/ui/manual_async_fn.stderr b/tests/ui/manual_async_fn.stderr index 54a9b1d40a11..fe6a20589b96 100644 --- a/tests/ui/manual_async_fn.stderr +++ b/tests/ui/manual_async_fn.stderr @@ -9,6 +9,9 @@ LL | fn fut() -> impl Future { help: make the function `async` and return the output of the future directly | LL - fn fut() -> impl Future { +LL - +LL - async { 42 } +LL - } LL + async fn fut() -> i32 { 42 } | @@ -21,6 +24,9 @@ LL | fn fut2() ->impl Future { help: make the function `async` and return the output of the future directly | LL - fn fut2() ->impl Future { +LL - +LL - async { 42 } +LL - } LL + async fn fut2() -> i32 { 42 } | @@ -33,6 +39,9 @@ LL | fn fut3()-> impl Future { help: make the function `async` and return the output of the future directly | LL - fn fut3()-> impl Future { +LL - +LL - async { 42 } +LL - } LL + async fn fut3() -> i32 { 42 } | @@ -45,6 +54,9 @@ LL | fn empty_fut() -> impl Future { help: make the function `async` and return the output of the future directly | LL - fn empty_fut() -> impl Future { +LL - +LL - async {} +LL - } LL + async fn empty_fut() {} | @@ -57,6 +69,9 @@ LL | fn empty_fut2() ->impl Future { help: make the function `async` and return the output of the future directly | LL - fn empty_fut2() ->impl Future { +LL - +LL - async {} +LL - } LL + async fn empty_fut2() {} | @@ -69,6 +84,9 @@ LL | fn empty_fut3()-> impl Future { help: make the function `async` and return the output of the future directly | LL - fn empty_fut3()-> impl Future { +LL - +LL - async {} +LL - } LL + async fn empty_fut3() {} | @@ -81,6 +99,9 @@ LL | fn core_fut() -> impl core::future::Future { help: make the function `async` and return the output of the future directly | LL - fn core_fut() -> impl core::future::Future { +LL - +LL - async move { 42 } +LL - } LL + async fn core_fut() -> i32 { 42 } | @@ -116,6 +137,9 @@ LL | fn elided(_: &i32) -> impl Future + '_ { help: make the function `async` and return the output of the future directly | LL - fn elided(_: &i32) -> impl Future + '_ { +LL - +LL - async { 42 } +LL - } LL + async fn elided(_: &i32) -> i32 { 42 } | @@ -128,6 +152,9 @@ LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + help: make the function `async` and return the output of the future directly | LL - fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { +LL - +LL - async { 42 } +LL - } LL + async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 } | @@ -140,6 +167,9 @@ LL | pub fn issue_10450() -> impl Future { help: make the function `async` and return the output of the future directly | LL - pub fn issue_10450() -> impl Future { +LL - +LL - async { 42 } +LL - } LL + pub async fn issue_10450() -> i32 { 42 } | @@ -152,6 +182,9 @@ LL | pub(crate) fn issue_10450_2() -> impl Future { help: make the function `async` and return the output of the future directly | LL - pub(crate) fn issue_10450_2() -> impl Future { +LL - +LL - async { 42 } +LL - } LL + pub(crate) async fn issue_10450_2() -> i32 { 42 } | @@ -164,6 +197,9 @@ LL | pub(self) fn issue_10450_3() -> impl Future { help: make the function `async` and return the output of the future directly | LL - pub(self) fn issue_10450_3() -> impl Future { +LL - +LL - async { 42 } +LL - } LL + pub(self) async fn issue_10450_3() -> i32 { 42 } | diff --git a/tests/ui/map_unwrap_or.stderr b/tests/ui/map_unwrap_or.stderr index 0b6c9b7fcf19..b0b02f3f8d6b 100644 --- a/tests/ui/map_unwrap_or.stderr +++ b/tests/ui/map_unwrap_or.stderr @@ -12,6 +12,9 @@ LL | | .unwrap_or(0); help: use `map_or(, )` instead | LL - let _ = opt.map(|x| x + 1) +LL - +LL - // Should lint even though this call is on a separate line. +LL - .unwrap_or(0); LL + let _ = opt.map_or(0, |x| x + 1); | @@ -98,6 +101,7 @@ LL | | .unwrap_or(None); help: use `and_then()` instead | LL - .map(|x| Some(x + 1)) +LL - .unwrap_or(None); LL + .and_then(|x| Some(x + 1)); | diff --git a/tests/ui/match_same_arms.stderr b/tests/ui/match_same_arms.stderr index 8aa60f835766..bd0b7b2871ec 100644 --- a/tests/ui/match_same_arms.stderr +++ b/tests/ui/match_same_arms.stderr @@ -30,7 +30,6 @@ help: otherwise remove the non-wildcard arms | LL - 2 => 'b', LL - 3 => 'b', -LL + _ => 'b', | error: these match arms have identical bodies diff --git a/tests/ui/non_canonical_partial_ord_impl.stderr b/tests/ui/non_canonical_partial_ord_impl.stderr index 8e55603dd9da..a134df17691e 100644 --- a/tests/ui/non_canonical_partial_ord_impl.stderr +++ b/tests/ui/non_canonical_partial_ord_impl.stderr @@ -28,6 +28,8 @@ LL | | } help: change this to | LL - fn partial_cmp(&self, _: &Self) -> Option { +LL - todo!(); +LL - } LL + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } | diff --git a/tests/ui/print_literal.stderr b/tests/ui/print_literal.stderr index c136f52800f6..229f3bf269d3 100644 --- a/tests/ui/print_literal.stderr +++ b/tests/ui/print_literal.stderr @@ -310,6 +310,7 @@ LL | "name", 5, "x", 0.01 help: try | LL - "Hello {}: {2} is {3:.*} (which {3} with {1} places)", +LL - "name", 5, "x", 0.01 LL + "Hello name: x is {1:.*} (which {1} with {0} places)", 5, 0.01 | From 6bd9d7625d65b14a9c09a9dafa0cf7b9b6263e4f Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 30 Nov 2025 23:32:07 -0800 Subject: [PATCH 0244/3801] =?UTF-8?q?Assume=20the=20returned=20value=20in?= =?UTF-8?q?=20`.filter(=E2=80=A6).count()`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to how this helps in `slice::Iter::position`, LLVM sometimes loses track of how high this can get, so for `TrustedLen` iterators tell it what the upper bound is. --- library/core/src/iter/adapters/filter.rs | 41 ++++++++++++++++++- .../iter-filter-count-assume.rs | 34 +++++++++++++++ .../iter-filter-count-debug-check.rs | 34 +++++++++++++++ 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 tests/codegen-llvm/lib-optimizations/iter-filter-count-assume.rs create mode 100644 tests/ui/iterators/iter-filter-count-debug-check.rs diff --git a/library/core/src/iter/adapters/filter.rs b/library/core/src/iter/adapters/filter.rs index dd08cd6f61c4..b22419ccf080 100644 --- a/library/core/src/iter/adapters/filter.rs +++ b/library/core/src/iter/adapters/filter.rs @@ -4,7 +4,7 @@ use core::ops::ControlFlow; use crate::fmt; use crate::iter::adapters::SourceIter; -use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused}; +use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen}; use crate::num::NonZero; use crate::ops::Try; @@ -138,7 +138,13 @@ where move |x| predicate(&x) as usize } - self.iter.map(to_usize(self.predicate)).sum() + let before = self.iter.size_hint().1.unwrap_or(usize::MAX); + let total = self.iter.map(to_usize(self.predicate)).sum(); + // SAFETY: `total` and `before` came from the same iterator of type `I` + unsafe { + ::assume_count_le_upper_bound(total, before); + } + total } #[inline] @@ -214,3 +220,34 @@ unsafe impl InPlaceIterable for Filter { const EXPAND_BY: Option> = I::EXPAND_BY; const MERGE_BY: Option> = I::MERGE_BY; } + +trait SpecAssumeCount { + /// # Safety + /// + /// `count` must be an number of items actually read from the iterator. + /// + /// `upper` must either: + /// - have come from `size_hint().1` on the iterator, or + /// - be `usize::MAX` which will vacuously do nothing. + unsafe fn assume_count_le_upper_bound(count: usize, upper: usize); +} + +impl SpecAssumeCount for I { + #[inline] + #[rustc_inherit_overflow_checks] + default unsafe fn assume_count_le_upper_bound(count: usize, upper: usize) { + // In the default we can't trust the `upper` for soundness + // because it came from an untrusted `size_hint`. + + // In debug mode we might as well check that the size_hint wasn't too small + let _ = upper - count; + } +} + +impl SpecAssumeCount for I { + #[inline] + unsafe fn assume_count_le_upper_bound(count: usize, upper: usize) { + // SAFETY: The `upper` is trusted because it came from a `TrustedLen` iterator. + unsafe { crate::hint::assert_unchecked(count <= upper) } + } +} diff --git a/tests/codegen-llvm/lib-optimizations/iter-filter-count-assume.rs b/tests/codegen-llvm/lib-optimizations/iter-filter-count-assume.rs new file mode 100644 index 000000000000..7588b23efc3a --- /dev/null +++ b/tests/codegen-llvm/lib-optimizations/iter-filter-count-assume.rs @@ -0,0 +1,34 @@ +//@ compile-flags: -Copt-level=3 +//@ edition: 2024 + +#![crate_type = "lib"] + +// Similar to how we `assume` that `slice::Iter::position` is within the length, +// check that `count` also does that for `TrustedLen` iterators. +// See https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/Overflow-chk.20removed.20for.20array.20of.2059.2C.20but.20not.2060.2C.20elems/with/561070780 + +// CHECK-LABEL: @filter_count_untrusted +#[unsafe(no_mangle)] +pub fn filter_count_untrusted(bar: &[u8; 1234]) -> u16 { + // CHECK-NOT: llvm.assume + // CHECK: call void @{{.+}}unwrap_failed + // CHECK-NOT: llvm.assume + let mut iter = bar.iter(); + let iter = std::iter::from_fn(|| iter.next()); // Make it not TrustedLen + u16::try_from(iter.filter(|v| **v == 0).count()).unwrap() +} + +// CHECK-LABEL: @filter_count_trusted +#[unsafe(no_mangle)] +pub fn filter_count_trusted(bar: &[u8; 1234]) -> u16 { + // CHECK-NOT: unwrap_failed + // CHECK: %[[ASSUME:.+]] = icmp ult {{i64|i32|i16}} %{{.+}}, 1235 + // CHECK-NEXT: tail call void @llvm.assume(i1 %[[ASSUME]]) + // CHECK-NOT: unwrap_failed + let iter = bar.iter(); + u16::try_from(iter.filter(|v| **v == 0).count()).unwrap() +} + +// CHECK: ; core::result::unwrap_failed +// CHECK-NEXT: Function Attrs +// CHECK-NEXT: declare{{.+}}void @{{.+}}unwrap_failed diff --git a/tests/ui/iterators/iter-filter-count-debug-check.rs b/tests/ui/iterators/iter-filter-count-debug-check.rs new file mode 100644 index 000000000000..6e3a3f73920e --- /dev/null +++ b/tests/ui/iterators/iter-filter-count-debug-check.rs @@ -0,0 +1,34 @@ +//@ run-pass +//@ needs-unwind +//@ ignore-backends: gcc +//@ compile-flags: -C overflow-checks + +use std::panic; + +struct Lies(usize); + +impl Iterator for Lies { + type Item = usize; + + fn next(&mut self) -> Option { + if self.0 == 0 { + None + } else { + self.0 -= 1; + Some(self.0) + } + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(2)) + } +} + +fn main() { + let r = panic::catch_unwind(|| { + // This returns more items than its `size_hint` said was possible, + // which `Filter::count` detects via `overflow-checks`. + let _ = Lies(10).filter(|&x| x > 3).count(); + }); + assert!(r.is_err()); +} From 93cd4f8a0494700a59fb499289ece76b9ff89e51 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 27 Nov 2025 15:25:24 +0100 Subject: [PATCH 0245/3801] link funding page in `.github/FUNDING.yml` --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000000..6a3ab0c92074 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: ["rust-lang.org/funding"] From 5e0b1533469354abe4f2e447598cd08aea1c002c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Tue, 2 Dec 2025 11:47:22 +0100 Subject: [PATCH 0246/3801] Fix example which wrongly implied that the upper bound of edition ranges was inclusive And explicitly state the fact that the upper bound is exclusive since only giving an example is too implicit. --- src/doc/rustc-dev-guide/src/tests/directives.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 4226c1750ef2..7cf5869b719c 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -273,7 +273,9 @@ This affects which edition is used by `./x test` to run the test. For example: - A test with the `//@ edition: 2018` directive will only run under the 2018 edition. -- A test with the `//@ edition: 2015..2021` directive can be run under the 2015, 2018, and 2021 editions. +- A test with the `//@ edition: 2015..2021` directive can be run under the 2015 and the 2018 edition, + so the upper bound is exclusive just like in Rust + (note that there's no equivalent to Rust's `..=` where the upper bound is inclusive). However, CI will only run the test with the lowest edition in the range (which is 2015 in this example). - A test with the `//@ edition: 2018..` directive will run under 2018 edition or greater. However, CI will only run the test with the lowest edition in the range (which is 2018 in this example). From 741f23f80e3d50ad016cb7b844d065d32731a348 Mon Sep 17 00:00:00 2001 From: reucru01 Date: Fri, 24 Oct 2025 10:15:30 +0100 Subject: [PATCH 0247/3801] Modifies CI to pass profile to test tool --- library/stdarch/.github/workflows/main.yml | 4 +-- library/stdarch/ci/intrinsic-test-docker.sh | 1 + library/stdarch/ci/intrinsic-test.sh | 21 +++++++------ library/stdarch/ci/run-docker.sh | 1 + library/stdarch/ci/run.sh | 30 +++++++++---------- .../crates/intrinsic-test/src/common/cli.rs | 7 +++++ .../intrinsic-test/src/common/compare.rs | 16 ++++++++-- .../intrinsic-test/src/common/gen_rust.rs | 9 ++++-- .../crates/intrinsic-test/src/common/mod.rs | 4 ++- 9 files changed, 62 insertions(+), 31 deletions(-) diff --git a/library/stdarch/.github/workflows/main.yml b/library/stdarch/.github/workflows/main.yml index 28c15cf4734a..92083443e425 100644 --- a/library/stdarch/.github/workflows/main.yml +++ b/library/stdarch/.github/workflows/main.yml @@ -220,7 +220,7 @@ jobs: if: matrix.build_std != '' # Configure some env vars based on matrix configuration - - run: echo "PROFILE=--profile=${{matrix.profile}}" >> $GITHUB_ENV + - run: echo "PROFILE=${{matrix.profile}}" >> $GITHUB_ENV shell: bash - run: echo "NORUN=1" >> $GITHUB_ENV shell: bash @@ -280,7 +280,7 @@ jobs: if: ${{ matrix.build_std }} # Configure some env vars based on matrix configuration - - run: echo "PROFILE=--profile=${{ matrix.profile }}" >> $GITHUB_ENV + - run: echo "PROFILE=${{ matrix.profile }}" >> $GITHUB_ENV - run: ./ci/intrinsic-test-docker.sh ${{ matrix.target }} if: ${{ !startsWith(matrix.target, 'thumb') }} env: diff --git a/library/stdarch/ci/intrinsic-test-docker.sh b/library/stdarch/ci/intrinsic-test-docker.sh index f62d7e484f5b..beeff42c7621 100755 --- a/library/stdarch/ci/intrinsic-test-docker.sh +++ b/library/stdarch/ci/intrinsic-test-docker.sh @@ -30,6 +30,7 @@ run() { --env CARGO_HOME=/cargo \ --env CARGO_TARGET_DIR=/checkout/target \ --env TARGET="${1}" \ + --env PROFILE \ --env "${HOST_LINKER}"="cc" \ --env STDARCH_DISABLE_ASSERT_INSTR \ --env NOSTD \ diff --git a/library/stdarch/ci/intrinsic-test.sh b/library/stdarch/ci/intrinsic-test.sh index ff76a0c76996..89104e2672ad 100755 --- a/library/stdarch/ci/intrinsic-test.sh +++ b/library/stdarch/ci/intrinsic-test.sh @@ -6,7 +6,7 @@ set -ex export RUSTFLAGS="${RUSTFLAGS} -D warnings -Z merge-functions=disabled -Z verify-llvm-ir" export HOST_RUSTFLAGS="${RUSTFLAGS}" -export PROFILE="${PROFILE:="--profile=release"}" +export PROFILE="${PROFILE:="release"}" case ${TARGET} in # On 32-bit use a static relocation model which avoids some extra @@ -85,27 +85,29 @@ esac # Arm specific case "${TARGET}" in aarch64-unknown-linux-gnu*|armv7-unknown-linux-gnueabihf*) - CPPFLAGS="${TEST_CPPFLAGS}" RUSTFLAGS="${HOST_RUSTFLAGS}" RUST_LOG=info \ - cargo run "${INTRINSIC_TEST}" "${PROFILE}" \ + CPPFLAGS="${TEST_CPPFLAGS}" RUSTFLAGS="${HOST_RUSTFLAGS}" RUST_LOG=warn \ + cargo run "${INTRINSIC_TEST}" --release \ --bin intrinsic-test -- intrinsics_data/arm_intrinsics.json \ --runner "${TEST_RUNNER}" \ --cppcompiler "${TEST_CXX_COMPILER}" \ --skip "${TEST_SKIP_INTRINSICS}" \ --target "${TARGET}" \ + --profile "${PROFILE}" \ --sample-percentage "${TEST_SAMPLE_INTRINSICS_PERCENTAGE}" ;; aarch64_be-unknown-linux-gnu*) - CPPFLAGS="${TEST_CPPFLAGS}" RUSTFLAGS="${HOST_RUSTFLAGS}" RUST_LOG=info \ - cargo run "${INTRINSIC_TEST}" "${PROFILE}" \ + CPPFLAGS="${TEST_CPPFLAGS}" RUSTFLAGS="${HOST_RUSTFLAGS}" RUST_LOG=warn \ + cargo run "${INTRINSIC_TEST}" --release \ --bin intrinsic-test -- intrinsics_data/arm_intrinsics.json \ --runner "${TEST_RUNNER}" \ --cppcompiler "${TEST_CXX_COMPILER}" \ --skip "${TEST_SKIP_INTRINSICS}" \ --target "${TARGET}" \ - --sample-percentage "${TEST_SAMPLE_INTRINSICS_PERCENTAGE}" \ + --profile "${PROFILE}" \ --linker "${CARGO_TARGET_AARCH64_BE_UNKNOWN_LINUX_GNU_LINKER}" \ - --cxx-toolchain-dir "${AARCH64_BE_TOOLCHAIN}" + --cxx-toolchain-dir "${AARCH64_BE_TOOLCHAIN}" \ + --sample-percentage "${TEST_SAMPLE_INTRINSICS_PERCENTAGE}" ;; x86_64-unknown-linux-gnu*) @@ -114,13 +116,14 @@ case "${TARGET}" in # Hence the use of `env -u`. env -u CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER \ CPPFLAGS="${TEST_CPPFLAGS}" RUSTFLAGS="${HOST_RUSTFLAGS}" \ - RUST_LOG=info RUST_BACKTRACE=1 \ - cargo run "${INTRINSIC_TEST}" "${PROFILE}" \ + RUST_LOG=warn RUST_BACKTRACE=1 \ + cargo run "${INTRINSIC_TEST}" --release \ --bin intrinsic-test -- intrinsics_data/x86-intel.xml \ --runner "${TEST_RUNNER}" \ --skip "${TEST_SKIP_INTRINSICS}" \ --cppcompiler "${TEST_CXX_COMPILER}" \ --target "${TARGET}" \ + --profile "${PROFILE}" \ --sample-percentage "${TEST_SAMPLE_INTRINSICS_PERCENTAGE}" ;; *) diff --git a/library/stdarch/ci/run-docker.sh b/library/stdarch/ci/run-docker.sh index d7aa50a8c96f..28dfd5a24a9f 100755 --- a/library/stdarch/ci/run-docker.sh +++ b/library/stdarch/ci/run-docker.sh @@ -37,6 +37,7 @@ run() { --env NORUN \ --env RUSTFLAGS \ --env CARGO_UNSTABLE_BUILD_STD \ + --env PROFILE \ --volume "${HOME}/.cargo":/cargo \ --volume "$(rustc --print sysroot)":/rust:ro \ --volume "$(pwd)":/checkout:ro \ diff --git a/library/stdarch/ci/run.sh b/library/stdarch/ci/run.sh index 2bb77bae256f..a8925c470a10 100755 --- a/library/stdarch/ci/run.sh +++ b/library/stdarch/ci/run.sh @@ -12,7 +12,7 @@ set -ex export RUSTFLAGS="${RUSTFLAGS} -D warnings -Z merge-functions=disabled -Z verify-llvm-ir" export HOST_RUSTFLAGS="${RUSTFLAGS}" -export PROFILE="${PROFILE:="--profile=release"}" +export PROFILE="${PROFILE:="release"}" case ${TARGET} in # On Windows the linker performs identical COMDAT folding (ICF) by default @@ -63,7 +63,7 @@ cargo_test() { if [ "$NORUN" = "1" ]; then export subcmd="build" fi - cmd="$cmd ${subcmd} --target=$TARGET $1" + cmd="$cmd ${subcmd} --target=$TARGET --profile=$PROFILE $1" cmd="$cmd -- $2" case ${TARGET} in @@ -80,10 +80,10 @@ cargo_test() { CORE_ARCH="--manifest-path=crates/core_arch/Cargo.toml" STDARCH_EXAMPLES="--manifest-path=examples/Cargo.toml" -cargo_test "${CORE_ARCH} ${PROFILE}" +cargo_test "${CORE_ARCH}" if [ "$NOSTD" != "1" ]; then - cargo_test "${STDARCH_EXAMPLES} ${PROFILE}" + cargo_test "${STDARCH_EXAMPLES}" fi @@ -93,41 +93,41 @@ case ${TARGET} in export STDARCH_DISABLE_ASSERT_INSTR=1 export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+avx" - cargo_test "${PROFILE}" + cargo_test export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+avx512f" - cargo_test "${PROFILE}" + cargo_test ;; x86_64* | i686*) export STDARCH_DISABLE_ASSERT_INSTR=1 export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+avx" - cargo_test "${PROFILE}" + cargo_test ;; # FIXME: don't build anymore #mips-*gnu* | mipsel-*gnu*) # export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+msa,+fp64,+mips32r5" - # cargo_test "${PROFILE}" + # cargo_test # ;; mips64*) export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+msa" - cargo_test "${PROFILE}" + cargo_test ;; s390x*) export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+vector-enhancements-1" - cargo_test "${PROFILE}" + cargo_test ;; powerpc64*) export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+altivec" - cargo_test "${PROFILE}" + cargo_test export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+vsx" - cargo_test "${PROFILE}" + cargo_test ;; powerpc*) # qemu has a bug in PPC32 which leads to a crash when compiled with `vsx` export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+altivec" - cargo_test "${PROFILE}" + cargo_test ;; *) ;; @@ -138,7 +138,7 @@ if [ "$NORUN" != "1" ] && [ "$NOSTD" != 1 ]; then # Test examples ( cd examples - cargo test --target "$TARGET" "${PROFILE}" - echo test | cargo run --target "$TARGET" "${PROFILE}" hex + cargo test --target "${TARGET}" --profile "${PROFILE}" + echo test | cargo run --target "${TARGET}" --profile "${PROFILE}" hex ) fi diff --git a/library/stdarch/crates/intrinsic-test/src/common/cli.rs b/library/stdarch/crates/intrinsic-test/src/common/cli.rs index ff34ef3d2d3d..bed8259de8b6 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/cli.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/cli.rs @@ -41,6 +41,10 @@ pub struct Cli { #[arg(long, default_value_t = String::from("armv7-unknown-linux-gnueabihf"))] pub target: String, + /// Pass a profile (release, dev) + #[arg(long, default_value_t = String::from("release"))] + pub profile: String, + /// Set the linker #[arg(long)] pub linker: Option, @@ -59,6 +63,7 @@ pub struct ProcessedCli { pub cpp_compiler: Option, pub runner: String, pub target: String, + pub profile: String, pub linker: Option, pub cxx_toolchain_dir: Option, pub skip: Vec, @@ -70,6 +75,7 @@ impl ProcessedCli { let filename = cli_options.input; let runner = cli_options.runner.unwrap_or_default(); let target = cli_options.target; + let profile = cli_options.profile; let linker = cli_options.linker; let cxx_toolchain_dir = cli_options.cxx_toolchain_dir; let sample_percentage = cli_options.sample_percentage; @@ -103,6 +109,7 @@ impl ProcessedCli { cpp_compiler, runner, target, + profile, linker, cxx_toolchain_dir, skip, diff --git a/library/stdarch/crates/intrinsic-test/src/common/compare.rs b/library/stdarch/crates/intrinsic-test/src/common/compare.rs index c4c2a1e3e482..521434917159 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/compare.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/compare.rs @@ -11,7 +11,17 @@ fn runner_command(runner: &str) -> Command { cmd } -pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: &str) -> bool { +pub fn compare_outputs( + intrinsic_name_list: &Vec, + runner: &str, + target: &str, + profile: &str, +) -> bool { + let profile_dir = match profile { + "dev" => "debug", + _ => "release", + }; + let (c, rust) = rayon::join( || { runner_command(runner) @@ -21,7 +31,9 @@ pub fn compare_outputs(intrinsic_name_list: &Vec, runner: &str, target: }, || { runner_command(runner) - .arg(format!("./target/{target}/release/intrinsic-test-programs")) + .arg(format!( + "./target/{target}/{profile_dir}/intrinsic-test-programs" + )) .current_dir("rust_programs") .output() }, diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs index fb047e2612de..82b97701bb14 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs @@ -140,7 +140,12 @@ pub fn write_lib_rs( Ok(()) } -pub fn compile_rust_programs(toolchain: Option<&str>, target: &str, linker: Option<&str>) -> bool { +pub fn compile_rust_programs( + toolchain: Option<&str>, + target: &str, + profile: &str, + linker: Option<&str>, +) -> bool { /* If there has been a linker explicitly set from the command line then * we want to set it via setting it in the RUSTFLAGS*/ @@ -161,7 +166,7 @@ pub fn compile_rust_programs(toolchain: Option<&str>, target: &str, linker: Opti if toolchain.is_some_and(|val| !val.is_empty()) { cargo_command.arg(toolchain.unwrap()); } - cargo_command.args(["build", "--target", target, "--release"]); + cargo_command.args(["build", "--target", target, "--profile", profile]); let mut rust_flags = "-Cdebuginfo=0".to_string(); if let Some(linker) = linker { diff --git a/library/stdarch/crates/intrinsic-test/src/common/mod.rs b/library/stdarch/crates/intrinsic-test/src/common/mod.rs index 8b6bd943a742..a1062b3a87db 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/mod.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/mod.rs @@ -146,6 +146,7 @@ pub trait SupportedArchitectureTest { .unwrap(); let target = &self.cli_options().target; + let profile = &self.cli_options().profile; let toolchain = self.cli_options().toolchain.as_deref(); let linker = self.cli_options().linker.as_deref(); @@ -178,7 +179,7 @@ pub trait SupportedArchitectureTest { .collect::>() .unwrap(); - compile_rust_programs(toolchain, target, linker) + compile_rust_programs(toolchain, target, profile, linker) } fn compare_outputs(&self) -> bool { @@ -193,6 +194,7 @@ pub trait SupportedArchitectureTest { &intrinsics_name_list, &self.cli_options().runner, &self.cli_options().target, + &self.cli_options().profile, ) } else { true From 2f85d700e670559c3588cae31667e3e8004c9599 Mon Sep 17 00:00:00 2001 From: reucru01 Date: Tue, 28 Oct 2025 12:19:12 +0000 Subject: [PATCH 0248/3801] Fixes hardcoded path for WASM runner --- library/stdarch/ci/docker/wasm32-wasip1/Dockerfile | 2 -- library/stdarch/ci/run.sh | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/library/stdarch/ci/docker/wasm32-wasip1/Dockerfile b/library/stdarch/ci/docker/wasm32-wasip1/Dockerfile index 0527c0df1777..cb4a9b2948cc 100644 --- a/library/stdarch/ci/docker/wasm32-wasip1/Dockerfile +++ b/library/stdarch/ci/docker/wasm32-wasip1/Dockerfile @@ -11,5 +11,3 @@ ENV VERSION=v38.0.3 RUN curl -L https://github.com/bytecodealliance/wasmtime/releases/download/${VERSION}/wasmtime-${VERSION}-x86_64-linux.tar.xz | tar xJf - ENV PATH=$PATH:/wasmtime-${VERSION}-x86_64-linux - -ENV CARGO_TARGET_WASM32_WASIP1_RUNNER="wasmtime -Wexceptions --dir /checkout/target/wasm32-wasip1/release/deps::." diff --git a/library/stdarch/ci/run.sh b/library/stdarch/ci/run.sh index a8925c470a10..f40a305117b8 100755 --- a/library/stdarch/ci/run.sh +++ b/library/stdarch/ci/run.sh @@ -71,6 +71,12 @@ cargo_test() { # harness isn't trying to capture output, otherwise we won't get any useful # output. wasm32*) + if [ "$PROFILE" = "release" ]; then + dir="release" + else + dir="debug" + fi + export CARGO_TARGET_WASM32_WASIP1_RUNNER="wasmtime -Wexceptions --dir /checkout/target/wasm32-wasip1/$dir/deps::." cmd="$cmd --nocapture" ;; esac From 8d01e7289c09a93ca52b74d4f77a3d0fcec115a0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 4 Nov 2025 09:29:47 +0000 Subject: [PATCH 0249/3801] Call rustc_driver::main() for MIRI_BE_RUSTC=host This way we don't need a special case in MiriBeRustCompilerCalls. Co-Authored-By: Ralf Jung --- src/tools/miri/src/bin/miri.rs | 63 ++++++++++++++-------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 4bf51f83c4f7..efe707156c40 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -272,18 +272,13 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { } } -struct MiriBeRustCompilerCalls { - target_crate: bool, -} +/// This compiler produces rlibs that are meant for later consumption by Miri. +struct MiriDepCompilerCalls; -impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { +impl rustc_driver::Callbacks for MiriDepCompilerCalls { #[allow(rustc::potential_query_instability)] // rustc_codegen_ssa (where this code is copied from) also allows this lint fn config(&mut self, config: &mut Config) { - if !self.target_crate { - // For a host crate, we fully behave like rustc. - return; - } - // For a target crate, we emit an rlib that Miri can later consume. + // We don't need actual codegen, we just emit an rlib that Miri can later consume. config.make_codegen_backend = Some(Box::new(make_miri_codegen_backend)); // Avoid warnings about unsupported crate types. However, only do that we we are *not* being @@ -367,16 +362,12 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { _: &rustc_interface::interface::Compiler, tcx: TyCtxt<'tcx>, ) -> Compilation { - if self.target_crate { - // cargo-miri has patched the compiler flags to make these into check-only builds, - // but we are still emulating regular rustc builds, which would perform post-mono - // const-eval during collection. So let's also do that here, even if we might be - // running with `--emit=metadata`. In particular this is needed to make - // `compile_fail` doc tests trigger post-mono errors. - // In general `collect_and_partition_mono_items` is not safe to call in check-only - // builds, but we are setting `-Zalways-encode-mir` which avoids those issues. - let _ = tcx.collect_and_partition_mono_items(()); - } + // While the dummy codegen backend doesn't do any codegen, we are still emulating + // regular rustc builds, which would perform post-mono const-eval during collection. + // So let's also do that here. In particular this is needed to make `compile_fail` + // doc tests trigger post-mono errors. + let _ = tcx.collect_and_partition_mono_items(()); + Compilation::Continue } } @@ -457,32 +448,28 @@ fn main() { // If the environment asks us to actually be rustc, then do that. if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") { + if crate_kind == "host" { + // For host crates like proc macros and build scripts, we are an entirely normal rustc. + // These eventually produce actual binaries and never run in Miri. + match rustc_driver::main() { + // Empty match proves this function will never return. + } + } else if crate_kind != "target" { + panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}") + }; + // Earliest rustc setup. rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ()); rustc_driver::init_rustc_env_logger(&early_dcx); - let target_crate = if crate_kind == "target" { - true - } else if crate_kind == "host" { - false - } else { - panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}") - }; - let mut args = args; - // Don't insert `MIRI_DEFAULT_ARGS`, in particular, `--cfg=miri`, if we are building - // a "host" crate. That may cause procedural macros (and probably build scripts) to - // depend on Miri-only symbols, such as `miri_resolve_frame`: - // https://github.com/rust-lang/miri/issues/1760 - if target_crate { - // Splice in the default arguments after the program name. - // Some options have different defaults in Miri than in plain rustc; apply those by making - // them the first arguments after the binary name (but later arguments can overwrite them). - args.splice(1..1, miri::MIRI_DEFAULT_ARGS.iter().map(ToString::to_string)); - } + // Splice in the default arguments after the program name. + // Some options have different defaults in Miri than in plain rustc; apply those by making + // them the first arguments after the binary name (but later arguments can overwrite them). + args.splice(1..1, miri::MIRI_DEFAULT_ARGS.iter().map(ToString::to_string)); // We cannot use `rustc_driver::main` as we want it to use `args` as the CLI arguments. - run_compiler_and_exit(&args, &mut MiriBeRustCompilerCalls { target_crate }) + run_compiler_and_exit(&args, &mut MiriDepCompilerCalls) } // Add an ICE bug report hook. From 9c0cbe98ea1890eb261e63ef1cde58f89ee7df38 Mon Sep 17 00:00:00 2001 From: xonx4l Date: Sat, 8 Nov 2025 00:11:35 +0530 Subject: [PATCH 0250/3801] Merge E0412 into E0425 --- tests/ui/crashes/ice-6252.stderr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui/crashes/ice-6252.stderr b/tests/ui/crashes/ice-6252.stderr index 201a897b2319..b6a2597a44d5 100644 --- a/tests/ui/crashes/ice-6252.stderr +++ b/tests/ui/crashes/ice-6252.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PhantomData` in this scope +error[E0425]: cannot find type `PhantomData` in this scope --> tests/ui/crashes/ice-6252.rs:9:9 | LL | _n: PhantomData, @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::marker::PhantomData; | -error[E0412]: cannot find type `VAL` in this scope +error[E0425]: cannot find type `VAL` in this scope --> tests/ui/crashes/ice-6252.rs:12:63 | LL | impl TypeVal for Multiply where N: TypeVal {} @@ -31,5 +31,5 @@ LL | impl TypeVal for Multiply where N: TypeVal {} error: aborting due to 3 previous errors -Some errors have detailed explanations: E0046, E0412. +Some errors have detailed explanations: E0046, E0425. For more information about an error, try `rustc --explain E0046`. From f2af204d17aad5264372218c58dd7d87a6769307 Mon Sep 17 00:00:00 2001 From: yanglsh Date: Fri, 10 Oct 2025 00:16:12 +0800 Subject: [PATCH 0251/3801] fix: `zero_repeat_side_effects` misses curlies --- clippy_lints/src/zero_repeat_side_effects.rs | 72 ++++++++++++++++---- tests/ui/zero_repeat_side_effects.fixed | 32 ++++++++- tests/ui/zero_repeat_side_effects.rs | 26 ++++++- tests/ui/zero_repeat_side_effects.stderr | 52 ++++++++++---- 4 files changed, 151 insertions(+), 31 deletions(-) diff --git a/clippy_lints/src/zero_repeat_side_effects.rs b/clippy_lints/src/zero_repeat_side_effects.rs index a8351690068d..95085161c09c 100644 --- a/clippy_lints/src/zero_repeat_side_effects.rs +++ b/clippy_lints/src/zero_repeat_side_effects.rs @@ -4,10 +4,11 @@ use clippy_utils::source::{snippet, snippet_indent}; use rustc_ast::LitKind; use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; -use rustc_hir::{ConstArgKind, ExprKind, Node}; +use rustc_hir::{ConstArgKind, Expr, ExprKind, LetStmt, LocalSource, Node}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::IsSuggestable; +use rustc_middle::ty::{IsSuggestable, Ty}; use rustc_session::declare_lint_pass; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does @@ -44,7 +45,7 @@ declare_clippy_lint! { declare_lint_pass!(ZeroRepeatSideEffects => [ZERO_REPEAT_SIDE_EFFECTS]); impl LateLintPass<'_> for ZeroRepeatSideEffects { - fn check_expr(&mut self, cx: &LateContext<'_>, expr: &rustc_hir::Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if let Some(args) = VecArgs::hir(cx, expr) && let VecArgs::Repeat(inner_expr, len) = args && let ExprKind::Lit(l) = len.kind @@ -69,7 +70,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects { } } -fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr: &'_ rustc_hir::Expr<'_>, is_vec: bool) { +fn inner_check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, inner_expr: &'_ Expr<'_>, is_vec: bool) { // check if expr is a call or has a call inside it if inner_expr.can_have_side_effects() { let parent_hir_node = cx.tcx.parent_hir_node(expr.hir_id); @@ -81,19 +82,22 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr: let vec = if is_vec { "vec!" } else { "" }; let (span, sugg) = match parent_hir_node { - Node::LetStmt(l) => ( - l.span, - format!( - "{inner_expr};\n{indent}let {var_name}: {return_type} = {vec}[];", - var_name = snippet(cx, l.pat.span.source_callsite(), "..") - ), - ), + Node::LetStmt(l) + if matches!(l.source, LocalSource::AssignDesugar) + && let mut parent_iter = cx.tcx.hir_parent_iter(l.hir_id) + && let Some((_, Node::Stmt(_))) = parent_iter.next() + && let Some((_, Node::Block(_))) = parent_iter.next() + && let Some((_, Node::Expr(x))) = parent_iter.next() => + { + ( + x.span, + assign_expr_suggestion(cx, x, l.pat.span, &inner_expr, return_type, vec), + ) + }, + Node::LetStmt(l) => (l.span, let_stmt_suggestion(cx, l, &inner_expr, return_type, vec)), Node::Expr(x) if let ExprKind::Assign(l, _, _) = x.kind => ( x.span, - format!( - "{inner_expr};\n{indent}{var_name} = {vec}[] as {return_type}", - var_name = snippet(cx, l.span.source_callsite(), "..") - ), + assign_expr_suggestion(cx, x, l.span, &inner_expr, return_type, vec), ), // NOTE: don't use the stmt span to avoid touching the trailing semicolon Node::Stmt(_) => (expr.span, format!("{inner_expr};\n{indent}{vec}[] as {return_type}")), @@ -131,3 +135,41 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr: ); } } + +fn let_stmt_suggestion( + cx: &LateContext<'_>, + let_stmt: &LetStmt<'_>, + inner_expr: &str, + return_type: Ty<'_>, + vec_str: &str, +) -> String { + let indent = snippet_indent(cx, let_stmt.span).unwrap_or_default(); + format!( + "{inner_expr};\n{}let {var_name}: {return_type} = {vec_str}[];", + indent, + var_name = snippet(cx, let_stmt.pat.span.source_callsite(), "..") + ) +} + +fn assign_expr_suggestion( + cx: &LateContext<'_>, + outer_expr: &Expr<'_>, + assign_expr_span: Span, + inner_expr: &str, + return_type: Ty<'_>, + vec_str: &str, +) -> String { + let mut parent_hir_node = cx.tcx.parent_hir_node(outer_expr.hir_id); + if let Node::Stmt(stmt) = parent_hir_node { + parent_hir_node = cx.tcx.parent_hir_node(stmt.hir_id); + } + let needs_curly = !matches!(parent_hir_node, Node::Block(_)); + + let indent = snippet_indent(cx, outer_expr.span).unwrap_or_default(); + let var_name = snippet(cx, assign_expr_span.source_callsite(), ".."); + if needs_curly { + format!("{{\n {indent}{inner_expr};\n {indent}{var_name} = {vec_str}[] as {return_type}\n{indent}}}",) + } else { + format!("{inner_expr};\n{indent}{var_name} = {vec_str}[] as {return_type}") + } +} diff --git a/tests/ui/zero_repeat_side_effects.fixed b/tests/ui/zero_repeat_side_effects.fixed index b5fca36f3f08..4bdff6fd0f6c 100644 --- a/tests/ui/zero_repeat_side_effects.fixed +++ b/tests/ui/zero_repeat_side_effects.fixed @@ -1,6 +1,11 @@ #![warn(clippy::zero_repeat_side_effects)] -#![expect(clippy::unnecessary_operation, clippy::useless_vec, clippy::needless_late_init)] -#![allow(clippy::no_effect)] // only fires _after_ the fix +#![allow( + clippy::unnecessary_operation, + clippy::useless_vec, + clippy::needless_late_init, + clippy::single_match, + clippy::no_effect // only fires _after_ the fix +)] fn f() -> i32 { println!("side effect"); @@ -119,3 +124,26 @@ fn issue_14681() { }); //~^ zero_repeat_side_effects } + +fn issue_15824() { + fn f() {} + + match 0 { + 0 => { + f(); + _ = [] as [(); 0] + }, + //~^ zero_repeat_side_effects + _ => {}, + } + + let mut a = [(); 0]; + match 0 { + 0 => { + f(); + a = [] as [(); 0] + }, + //~^ zero_repeat_side_effects + _ => {}, + } +} diff --git a/tests/ui/zero_repeat_side_effects.rs b/tests/ui/zero_repeat_side_effects.rs index ea043d21638c..a1454d724c87 100644 --- a/tests/ui/zero_repeat_side_effects.rs +++ b/tests/ui/zero_repeat_side_effects.rs @@ -1,6 +1,11 @@ #![warn(clippy::zero_repeat_side_effects)] -#![expect(clippy::unnecessary_operation, clippy::useless_vec, clippy::needless_late_init)] -#![allow(clippy::no_effect)] // only fires _after_ the fix +#![allow( + clippy::unnecessary_operation, + clippy::useless_vec, + clippy::needless_late_init, + clippy::single_match, + clippy::no_effect // only fires _after_ the fix +)] fn f() -> i32 { println!("side effect"); @@ -102,3 +107,20 @@ fn issue_14681() { foo(&[Some(Some(S::new())); 0]); //~^ zero_repeat_side_effects } + +fn issue_15824() { + fn f() {} + + match 0 { + 0 => _ = [f(); 0], + //~^ zero_repeat_side_effects + _ => {}, + } + + let mut a = [(); 0]; + match 0 { + 0 => a = [f(); 0], + //~^ zero_repeat_side_effects + _ => {}, + } +} diff --git a/tests/ui/zero_repeat_side_effects.stderr b/tests/ui/zero_repeat_side_effects.stderr index 49e850d03534..f376a1501b00 100644 --- a/tests/ui/zero_repeat_side_effects.stderr +++ b/tests/ui/zero_repeat_side_effects.stderr @@ -1,5 +1,5 @@ error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:17:5 + --> tests/ui/zero_repeat_side_effects.rs:22:5 | LL | let a = [f(); 0]; | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let a: [i32; 0] = []; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:20:5 + --> tests/ui/zero_repeat_side_effects.rs:25:5 | LL | b = [f(); 0]; | ^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL ~ b = [] as [i32; 0]; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:25:5 + --> tests/ui/zero_repeat_side_effects.rs:30:5 | LL | let c = vec![f(); 0]; | ^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + let c: std::vec::Vec = vec![]; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:28:5 + --> tests/ui/zero_repeat_side_effects.rs:33:5 | LL | d = vec![f(); 0]; | ^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL ~ d = vec![] as std::vec::Vec; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:32:5 + --> tests/ui/zero_repeat_side_effects.rs:37:5 | LL | let e = [println!("side effect"); 0]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + let e: [(); 0] = []; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:36:5 + --> tests/ui/zero_repeat_side_effects.rs:41:5 | LL | let g = [{ f() }; 0]; | ^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + let g: [i32; 0] = []; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:40:10 + --> tests/ui/zero_repeat_side_effects.rs:45:10 | LL | drop(vec![f(); 0]); | ^^^^^^^^^^^^ @@ -87,7 +87,7 @@ LL ~ }); | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:44:5 + --> tests/ui/zero_repeat_side_effects.rs:49:5 | LL | vec![f(); 0]; | ^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL ~ vec![] as std::vec::Vec; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:46:5 + --> tests/ui/zero_repeat_side_effects.rs:51:5 | LL | [f(); 0]; | ^^^^^^^^ @@ -111,7 +111,7 @@ LL ~ [] as [i32; 0]; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:100:10 + --> tests/ui/zero_repeat_side_effects.rs:105:10 | LL | foo(&[Some(f()); 0]); | ^^^^^^^^^^^^^^ @@ -125,7 +125,7 @@ LL ~ }); | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:102:10 + --> tests/ui/zero_repeat_side_effects.rs:107:10 | LL | foo(&[Some(Some(S::new())); 0]); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -138,5 +138,33 @@ LL + [] as [std::option::Option>; 0] LL ~ }); | -error: aborting due to 11 previous errors +error: expression with side effects as the initial value in a zero-sized array initializer + --> tests/ui/zero_repeat_side_effects.rs:115:14 + | +LL | 0 => _ = [f(); 0], + | ^^^^^^^^^^^^ + | +help: consider performing the side effect separately + | +LL ~ 0 => { +LL + f(); +LL + _ = [] as [(); 0] +LL ~ }, + | + +error: expression with side effects as the initial value in a zero-sized array initializer + --> tests/ui/zero_repeat_side_effects.rs:122:14 + | +LL | 0 => a = [f(); 0], + | ^^^^^^^^^^^^ + | +help: consider performing the side effect separately + | +LL ~ 0 => { +LL + f(); +LL + a = [] as [(); 0] +LL ~ }, + | + +error: aborting due to 13 previous errors From f113df337548ae54d83657fdb54ba887fbfd5c31 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 2 Dec 2025 16:44:15 -0800 Subject: [PATCH 0252/3801] Remove pagetoc This has been subsumed by the update to mdbook 0.5. I just forgot to remove this in https://github.com/rust-lang/rustc-dev-guide/pull/2652. --- src/doc/rustc-dev-guide/README.md | 5 -- src/doc/rustc-dev-guide/book.toml | 2 - src/doc/rustc-dev-guide/pagetoc.css | 84 ---------------------- src/doc/rustc-dev-guide/pagetoc.js | 104 ---------------------------- 4 files changed, 195 deletions(-) delete mode 100644 src/doc/rustc-dev-guide/pagetoc.css delete mode 100644 src/doc/rustc-dev-guide/pagetoc.js diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index 1ad895aeda2e..fee7cf042e1f 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -65,11 +65,6 @@ following example. ENABLE_LINKCHECK=1 mdbook serve ``` -### Table of Contents - -Each page has a TOC that is automatically generated by `pagetoc.js`. -There is an associated `pagetoc.css`, for styling. - ## Synchronizing josh subtree with rustc This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. diff --git a/src/doc/rustc-dev-guide/book.toml b/src/doc/rustc-dev-guide/book.toml index efb13101c8de..15a597e5addb 100644 --- a/src/doc/rustc-dev-guide/book.toml +++ b/src/doc/rustc-dev-guide/book.toml @@ -15,9 +15,7 @@ edit-url-template = "https://github.com/rust-lang/rustc-dev-guide/edit/main/{pat additional-js = [ "mermaid.min.js", "mermaid-init.js", - "pagetoc.js", ] -additional-css = ["pagetoc.css"] [output.html.search] use-boolean-and = true diff --git a/src/doc/rustc-dev-guide/pagetoc.css b/src/doc/rustc-dev-guide/pagetoc.css deleted file mode 100644 index fa709194f375..000000000000 --- a/src/doc/rustc-dev-guide/pagetoc.css +++ /dev/null @@ -1,84 +0,0 @@ -/* Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL) */ - -:root { - --toc-width: 270px; - --center-content-toc-shift: calc(-1 * var(--toc-width) / 2); -} - -.nav-chapters { - /* adjust width of buttons that bring to the previous or the next page */ - min-width: 50px; -} - -@media only screen { - @media (max-width: 1179px) { - .sidebar-hidden #sidetoc { - display: none; - } - } - - @media (max-width: 1439px) { - .sidebar-visible #sidetoc { - display: none; - } - } - - @media (1180px <= width <= 1439px) { - .sidebar-hidden main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - @media (1440px <= width <= 1700px) { - .sidebar-visible main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - #sidetoc { - margin-left: calc(100% + 20px); - } - #pagetoc { - position: fixed; - /* adjust TOC width */ - width: var(--toc-width); - height: calc(100vh - var(--menu-bar-height) - 0.67em * 4); - overflow: auto; - } - #pagetoc a { - border-left: 1px solid var(--sidebar-bg); - color: var(--fg); - display: block; - padding-bottom: 5px; - padding-top: 5px; - padding-left: 10px; - text-align: left; - text-decoration: none; - } - #pagetoc a:hover, - #pagetoc a.active { - background: var(--sidebar-bg); - color: var(--sidebar-active) !important; - } - #pagetoc .active { - background: var(--sidebar-bg); - color: var(--sidebar-active); - } - #pagetoc .pagetoc-H2 { - padding-left: 20px; - } - #pagetoc .pagetoc-H3 { - padding-left: 40px; - } - #pagetoc .pagetoc-H4 { - padding-left: 60px; - } -} - -@media print { - #sidetoc { - display: none; - } -} diff --git a/src/doc/rustc-dev-guide/pagetoc.js b/src/doc/rustc-dev-guide/pagetoc.js deleted file mode 100644 index 927a5b10749b..000000000000 --- a/src/doc/rustc-dev-guide/pagetoc.js +++ /dev/null @@ -1,104 +0,0 @@ -// Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL) - -let activeHref = location.href; -function updatePageToc(elem = undefined) { - let selectedPageTocElem = elem; - const pagetoc = document.getElementById("pagetoc"); - - function getRect(element) { - return element.getBoundingClientRect(); - } - - function overflowTop(container, element) { - return getRect(container).top - getRect(element).top; - } - - function overflowBottom(container, element) { - return getRect(container).bottom - getRect(element).bottom; - } - - // We've not selected a heading to highlight, and the URL needs updating - // so we need to find a heading based on the URL - if (selectedPageTocElem === undefined && location.href !== activeHref) { - activeHref = location.href; - for (const pageTocElement of pagetoc.children) { - if (pageTocElement.href === activeHref) { - selectedPageTocElem = pageTocElement; - } - } - } - - // We still don't have a selected heading, let's try and find the most - // suitable heading based on the scroll position - if (selectedPageTocElem === undefined) { - const margin = window.innerHeight / 3; - - const headers = document.getElementsByClassName("header"); - for (let i = 0; i < headers.length; i++) { - const header = headers[i]; - if (selectedPageTocElem === undefined && getRect(header).top >= 0) { - if (getRect(header).top < margin) { - selectedPageTocElem = header; - } else { - selectedPageTocElem = headers[Math.max(0, i - 1)]; - } - } - // a very long last section's heading is over the screen - if (selectedPageTocElem === undefined && i === headers.length - 1) { - selectedPageTocElem = header; - } - } - } - - // Remove the active flag from all pagetoc elements - for (const pageTocElement of pagetoc.children) { - pageTocElement.classList.remove("active"); - } - - // If we have a selected heading, set it to active and scroll to it - if (selectedPageTocElem !== undefined) { - for (const pageTocElement of pagetoc.children) { - if (selectedPageTocElem.href.localeCompare(pageTocElement.href) === 0) { - pageTocElement.classList.add("active"); - if (overflowTop(pagetoc, pageTocElement) > 0) { - pagetoc.scrollTop = pageTocElement.offsetTop; - } - if (overflowBottom(pagetoc, pageTocElement) < 0) { - pagetoc.scrollTop -= overflowBottom(pagetoc, pageTocElement); - } - } - } - } -} - -if (document.getElementById("sidetoc") === null && - document.getElementsByClassName("header").length > 0) { - // The sidetoc element doesn't exist yet, let's create it - - // Create the empty sidetoc and pagetoc elements - const sidetoc = document.createElement("div"); - const pagetoc = document.createElement("div"); - sidetoc.id = "sidetoc"; - pagetoc.id = "pagetoc"; - sidetoc.appendChild(pagetoc); - - // And append them to the current DOM - const main = document.querySelector('main'); - main.insertBefore(sidetoc, main.firstChild); - - // Populate sidebar on load - window.addEventListener("load", () => { - for (const header of document.getElementsByClassName("header")) { - const link = document.createElement("a"); - link.innerHTML = header.innerHTML; - link.href = header.hash; - link.classList.add("pagetoc-" + header.parentElement.tagName); - document.getElementById("pagetoc").appendChild(link); - link.onclick = () => updatePageToc(link); - } - updatePageToc(); - }); - - // Update page table of contents selected heading on scroll - window.addEventListener("scroll", () => updatePageToc()); -} From 23e99d3ec4998928f0309a6e5dfeb5184f8fd9d5 Mon Sep 17 00:00:00 2001 From: Max Heller Date: Tue, 2 Dec 2025 20:54:14 -0500 Subject: [PATCH 0253/3801] Implement `Duration::div_duration_{floor,ceil}` --- library/core/src/time.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 51a01545f5cf..24b659484d57 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1132,6 +1132,46 @@ impl Duration { let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.as_inner() as f32); self_nanos / rhs_nanos } + + /// Divides `Duration` by `Duration` and returns `u128`, rounding the result towards zero. + /// + /// # Examples + /// ``` + /// #![feature(duration_integer_division)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 0); + /// assert_eq!(dur.div_duration_floor(Duration::new(1, 000_000_001)), 1); + /// assert_eq!(dur.div_duration_floor(Duration::new(1, 000_000_000)), 2); + /// assert_eq!(dur.div_duration_floor(Duration::new(0, 999_999_999)), 2); + /// ``` + #[unstable(feature = "duration_integer_division", issue = "149573")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn div_duration_floor(self, rhs: Duration) -> u128 { + self.as_nanos().div_floor(rhs.as_nanos()) + } + + /// Divides `Duration` by `Duration` and returns `u128`, rounding the result towards positive infinity. + /// + /// # Examples + /// ``` + /// #![feature(duration_integer_division)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 0); + /// assert_eq!(dur.div_duration_ceil(Duration::new(1, 000_000_001)), 2); + /// assert_eq!(dur.div_duration_ceil(Duration::new(1, 000_000_000)), 2); + /// assert_eq!(dur.div_duration_ceil(Duration::new(0, 999_999_999)), 3); + /// ``` + #[unstable(feature = "duration_integer_division", issue = "149573")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn div_duration_ceil(self, rhs: Duration) -> u128 { + self.as_nanos().div_ceil(rhs.as_nanos()) + } } #[stable(feature = "duration", since = "1.3.0")] From 7d0300b8a578d4c7498365576279dc7ef1cf211b Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Wed, 3 Dec 2025 12:03:13 +0000 Subject: [PATCH 0254/3801] Fix +vfp3,-d32 target configuration --- .../rustc_target/src/spec/targets/armv7_linux_androideabi.rs | 2 +- compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs | 2 +- .../src/spec/targets/armv7_unknown_linux_gnueabihf.rs | 2 +- .../src/spec/targets/armv7_unknown_linux_musleabihf.rs | 2 +- .../src/spec/targets/armv7_unknown_linux_uclibceabihf.rs | 2 +- .../src/spec/targets/armv7_unknown_netbsd_eabihf.rs | 2 +- .../rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs | 2 +- .../src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs | 2 +- compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs index ad8a14fdad53..3ccb99c9ab0f 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs @@ -28,7 +28,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), - features: "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".into(), + features: "+v7,+thumb-mode,+thumb2,+vfp3d16,-neon".into(), supported_sanitizers: SanitizerSet::ADDRESS, max_atomic_width: Some(64), ..base diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs index 0a8432ea8fe9..c358b530f742 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_freebsd.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), + features: "+v7,+vfp3d16,+thumb2,-neon".into(), max_atomic_width: Some(64), mcount: "\u{1}__gnu_mcount_nc".into(), ..base::freebsd::opts() diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs index cbf6d5d08dd0..639a9d225729 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_gnueabihf.rs @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Info about features at https://wiki.debian.org/ArmHardFloatPort - features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), + features: "+v7,+vfp3d16,+thumb2,-neon".into(), max_atomic_width: Some(64), mcount: "\u{1}__gnu_mcount_nc".into(), llvm_mcount_intrinsic: Some("llvm.arm.gnu.eabi.mcount".into()), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs index 9b5fcd87b120..fb7bd1226a37 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), + features: "+v7,+vfp3d16,+thumb2,-neon".into(), max_atomic_width: Some(64), mcount: "\u{1}mcount".into(), // FIXME(compiler-team#422): musl targets should be dynamically linked by default. diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs index 927c910da596..8fb38d315bf6 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_uclibceabihf.rs @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { // Info about features at https://wiki.debian.org/ArmHardFloatPort - features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), + features: "+v7,+vfp3d16,+thumb2,-neon".into(), cpu: "generic".into(), max_atomic_width: Some(64), mcount: "_mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs index 788944e64c84..8869210ce002 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_netbsd_eabihf.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), + features: "+v7,+vfp3d16,+thumb2,-neon".into(), max_atomic_width: Some(64), mcount: "__mcount".into(), ..base::netbsd::opts() diff --git a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs index e43e4fe85cad..27e81c5834f2 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_wrs_vxworks_eabihf.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), // Info about features at https://wiki.debian.org/ArmHardFloatPort - features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), + features: "+v7,+vfp3d16,+thumb2,-neon".into(), max_atomic_width: Some(64), ..base::vxworks::opts() }, diff --git a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs index 9433cbd46627..cb652e6a1e1b 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_kmc_solid_asp3_eabihf.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), linker: Some("arm-kmc-eabi-gcc".into()), - features: "+v7,+vfp3,-d32,+thumb2,-neon".into(), + features: "+v7,+vfp3d16,+thumb2,-neon".into(), relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs index e03fe3e78b9d..28efdbe2291f 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { llvm_floatabi: Some(FloatAbi::Hard), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), - features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".into(), + features: "+v7,+vfp3d16,+thumb2,-neon,+strict-align".into(), relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(64), From 4ed68f01dc23b2877140c515ee16c6b59801a7a2 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Wed, 3 Dec 2025 12:04:41 +0000 Subject: [PATCH 0255/3801] Remove redundant -d32 in target specs --- .../src/spec/targets/arm_unknown_linux_gnueabihf.rs | 2 +- .../src/spec/targets/arm_unknown_linux_musleabihf.rs | 2 +- compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs | 2 +- .../src/spec/targets/armv6_unknown_netbsd_eabihf.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs index e003a65be393..1cae42c14559 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_gnueabihf.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - features: "+strict-align,+v6,+vfp2,-d32".into(), + features: "+strict-align,+v6,+vfp2".into(), max_atomic_width: Some(64), mcount: "\u{1}__gnu_mcount_nc".into(), llvm_mcount_intrinsic: Some("llvm.arm.gnu.eabi.mcount".into()), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs index 76051403a559..99995e27af0d 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { llvm_floatabi: Some(FloatAbi::Hard), // Most of these settings are copied from the arm_unknown_linux_gnueabihf // target. - features: "+strict-align,+v6,+vfp2,-d32".into(), + features: "+strict-align,+v6,+vfp2".into(), max_atomic_width: Some(64), mcount: "\u{1}mcount".into(), // FIXME(compiler-team#422): musl targets should be dynamically linked by default. diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs index 20d91d6968a6..6d6dfeed96b0 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_freebsd.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - features: "+v6,+vfp2,-d32".into(), + features: "+v6,+vfp2".into(), max_atomic_width: Some(64), mcount: "\u{1}__gnu_mcount_nc".into(), llvm_mcount_intrinsic: Some("llvm.arm.gnu.eabi.mcount".into()), diff --git a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs index 0316bd92999b..cb931e6c0e33 100644 --- a/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv6_unknown_netbsd_eabihf.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - features: "+v6,+vfp2,-d32".into(), + features: "+v6,+vfp2".into(), max_atomic_width: Some(64), mcount: "__mcount".into(), ..base::netbsd::opts() From 0ab78c152300499d0c17344e4e12d299313910e7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 3 Dec 2025 12:21:03 +0000 Subject: [PATCH 0256/3801] `is_const_default_method` is completely handled by the `constness` query --- compiler/rustc_const_eval/src/check_consts/mod.rs | 6 ++++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 3 +-- compiler/rustc_middle/src/hir/map.rs | 1 - compiler/rustc_middle/src/ty/mod.rs | 5 ----- compiler/rustc_mir_transform/src/lib.rs | 3 +-- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 4a88d039ef3c..e9824400ab7a 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -95,8 +95,10 @@ pub fn rustc_allow_const_fn_unstable( /// unstable features, not even recursively), and those that are not. pub fn is_fn_or_trait_safe_to_expose_on_stable(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // A default body in a `const trait` is const-stable when the trait is const-stable. - if tcx.is_const_default_method(def_id) { - return is_fn_or_trait_safe_to_expose_on_stable(tcx, tcx.parent(def_id)); + if let Some(trait_id) = tcx.trait_of_assoc(def_id) + && tcx.is_const_trait(trait_id) + { + return is_fn_or_trait_safe_to_expose_on_stable(tcx, trait_id); } match tcx.lookup_const_stability(def_id) { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 9fac68039f52..4085fd5e70f1 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1132,8 +1132,7 @@ fn should_encode_mir( && (generics.requires_monomorphization(tcx) || tcx.cross_crate_inlinable(def_id))); // The function has a `const` modifier or is in a `const trait`. - let is_const_fn = tcx.is_const_fn(def_id.to_def_id()) - || tcx.is_const_default_method(def_id.to_def_id()); + let is_const_fn = tcx.is_const_fn(def_id.to_def_id()); (is_const_fn, opt) } // The others don't have MIR. diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 430cd329408f..bf3192d9df17 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -321,7 +321,6 @@ impl<'tcx> TyCtxt<'tcx> { BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.is_const_fn(def_id) => { ConstContext::ConstFn } - BodyOwnerKind::Fn if self.is_const_default_method(def_id) => ConstContext::ConstFn, BodyOwnerKind::Fn | BodyOwnerKind::Closure | BodyOwnerKind::GlobalAsm => return None, }; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 61b3059ab425..d3e0fbb955c4 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2224,11 +2224,6 @@ impl<'tcx> TyCtxt<'tcx> { self.trait_def(def_id).constness == hir::Constness::Const } - #[inline] - pub fn is_const_default_method(self, def_id: DefId) -> bool { - matches!(self.trait_of_assoc(def_id), Some(trait_id) if self.is_const_trait(trait_id)) - } - pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool { if self.def_kind(def_id) != DefKind::AssocFn { return false; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 18b798c01faa..9a964d5e01bb 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -429,8 +429,7 @@ fn mir_promoted( let const_qualifs = match tcx.def_kind(def) { DefKind::Fn | DefKind::AssocFn | DefKind::Closure - if tcx.constness(def) == hir::Constness::Const - || tcx.is_const_default_method(def.to_def_id()) => + if tcx.constness(def) == hir::Constness::Const => { tcx.mir_const_qualif(def) } From 7f61da9c69e5b88fadf3efc789a62c12ea751b2c Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Tue, 28 Oct 2025 17:16:51 +0000 Subject: [PATCH 0257/3801] account for safe target features in fndef<->closure and fndef<->fndef coerce-lubs --- clippy_utils/src/qualify_min_const_fn.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 1fc8e86f3193..462cc644d4be 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -150,7 +150,7 @@ fn check_rvalue<'tcx>( CastKind::PointerCoercion( PointerCoercion::UnsafeFnPointer | PointerCoercion::ClosureFnPointer(_) - | PointerCoercion::ReifyFnPointer, + | PointerCoercion::ReifyFnPointer(_), _, ), _, From 85cf2825f4b0bbfc405724bf887bc5bcb199d9c6 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Tue, 28 Oct 2025 17:16:51 +0000 Subject: [PATCH 0258/3801] account for safe target features in fndef<->closure and fndef<->fndef coerce-lubs --- src/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index e445f9457477..a0bee4e18214 100644 --- a/src/base.rs +++ b/src/base.rs @@ -689,7 +689,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: lval.write_cvalue(fx, res); } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _), + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer(_), _), ref operand, to_ty, ) => { From ccde7d48f3e83bb8f0fba30fa089b1f96ec8f095 Mon Sep 17 00:00:00 2001 From: Roy Ammerschuber Date: Mon, 10 Nov 2025 17:43:21 +0100 Subject: [PATCH 0259/3801] Support retagging of wildcard references in tree borrows --- .../tree_borrows/diagnostics.rs | 109 +++- .../src/borrow_tracker/tree_borrows/mod.rs | 15 +- .../src/borrow_tracker/tree_borrows/tree.rs | 477 +++++++++++------- .../borrow_tracker/tree_borrows/wildcard.rs | 47 +- .../illegal_read_despite_exposed1.rs | 6 +- ...llegal_read_despite_exposed1.stack.stderr} | 6 +- .../illegal_read_despite_exposed1.tree.stderr | 25 + .../illegal_read_despite_exposed2.rs | 10 +- ...llegal_read_despite_exposed2.stack.stderr} | 12 +- .../illegal_read_despite_exposed2.tree.stderr | 31 ++ .../illegal_write_despite_exposed1.rs | 7 +- ...legal_write_despite_exposed1.stack.stderr} | 6 +- ...illegal_write_despite_exposed1.tree.stderr | 25 + .../wildcard/cross_tree_from_main.rs | 36 ++ .../wildcard/cross_tree_from_main.stderr | 25 + .../wildcard/cross_tree_update_main.rs | 37 ++ .../wildcard/cross_tree_update_main.stderr | 25 + .../cross_tree_update_main_invalid_exposed.rs | 44 ++ ...ss_tree_update_main_invalid_exposed.stderr | 14 + .../wildcard/cross_tree_update_newer.rs | 47 ++ .../wildcard/cross_tree_update_newer.stderr | 25 + .../cross_tree_update_newer_exposed.rs | 48 ++ .../cross_tree_update_newer_exposed.stderr | 25 + .../wildcard/cross_tree_update_older.rs | 47 ++ .../wildcard/cross_tree_update_older.stderr | 25 + ...cross_tree_update_older_invalid_exposed.rs | 53 ++ ...s_tree_update_older_invalid_exposed.stderr | 25 + ...ross_tree_update_older_invalid_exposed2.rs | 59 +++ ..._tree_update_older_invalid_exposed2.stderr | 25 + .../wildcard/protected_wildcard.rs | 39 ++ .../wildcard/protected_wildcard.stderr | 37 ++ .../strongly_protected_wildcard.stderr | 9 +- .../wildcard/subtree_internal_relatedness.rs | 44 ++ .../subtree_internal_relatedness.stderr | 25 + .../subtree_internal_relatedness_wildcard.rs | 49 ++ ...btree_internal_relatedness_wildcard.stderr | 25 + .../fail/tree_borrows/write_to_shr.stderr | 26 - .../pass/tree_borrows/wildcard/formatting.rs | 36 ++ .../tree_borrows/wildcard/formatting.stderr | 17 + .../pass/tree_borrows/wildcard/reborrow.rs | 224 ++++++++ .../tree_borrows/wildcard/undetected_ub.rs | 84 +-- .../pass/tree_borrows/wildcard/wildcard.rs | 1 - src/tools/miri/tests/utils/macros.rs | 4 +- 43 files changed, 1661 insertions(+), 295 deletions(-) rename src/tools/miri/tests/fail/{stacked_borrows => both_borrows}/illegal_read_despite_exposed1.rs (70%) rename src/tools/miri/tests/fail/{stacked_borrows/illegal_read_despite_exposed1.stderr => both_borrows/illegal_read_despite_exposed1.stack.stderr} (82%) create mode 100644 src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed1.tree.stderr rename src/tools/miri/tests/fail/{stacked_borrows => both_borrows}/illegal_read_despite_exposed2.rs (65%) rename src/tools/miri/tests/fail/{stacked_borrows/illegal_read_despite_exposed2.stderr => both_borrows/illegal_read_despite_exposed2.stack.stderr} (60%) create mode 100644 src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed2.tree.stderr rename src/tools/miri/tests/fail/{stacked_borrows => both_borrows}/illegal_write_despite_exposed1.rs (69%) rename src/tools/miri/tests/fail/{stacked_borrows/illegal_write_despite_exposed1.stderr => both_borrows/illegal_write_despite_exposed1.stack.stderr} (82%) create mode 100644 src/tools/miri/tests/fail/both_borrows/illegal_write_despite_exposed1.tree.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_from_main.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_from_main.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.stderr delete mode 100644 src/tools/miri/tests/fail/tree_borrows/write_to_shr.stderr create mode 100644 src/tools/miri/tests/pass/tree_borrows/wildcard/formatting.rs create mode 100644 src/tools/miri/tests/pass/tree_borrows/wildcard/formatting.stderr create mode 100644 src/tools/miri/tests/pass/tree_borrows/wildcard/reborrow.rs diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs index c454bb43a2f5..a91f35a9dcad 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs @@ -488,6 +488,8 @@ struct DisplayFmtPadding { indent_middle: S, /// Indentation for the last child. indent_last: S, + /// Replaces `join_last` for a wildcard root. + wildcard_root: S, } /// How to show whether a location has been accessed /// @@ -561,6 +563,11 @@ impl DisplayFmt { }) .unwrap_or("") } + + /// Print extra text if the tag is exposed. + fn print_exposed(&self, exposed: bool) -> S { + if exposed { " (exposed)" } else { "" } + } } /// Track the indentation of the tree. @@ -607,23 +614,21 @@ fn char_repeat(c: char, n: usize) -> String { struct DisplayRepr { tag: BorTag, name: Option, + exposed: bool, rperm: Vec>, children: Vec, } impl DisplayRepr { - fn from(tree: &Tree, show_unnamed: bool) -> Option { + fn from(tree: &Tree, root: UniIndex, show_unnamed: bool) -> Option { let mut v = Vec::new(); - extraction_aux(tree, tree.root, show_unnamed, &mut v); + extraction_aux(tree, root, show_unnamed, &mut v); let Some(root) = v.pop() else { if show_unnamed { unreachable!( "This allocation contains no tags, not even a root. This should not happen." ); } - eprintln!( - "This allocation does not contain named tags. Use `miri_print_borrow_state(_, true)` to also print unnamed tags." - ); return None; }; assert!(v.is_empty()); @@ -637,6 +642,7 @@ impl DisplayRepr { ) { let node = tree.nodes.get(idx).unwrap(); let name = node.debug_info.name.clone(); + let exposed = node.is_exposed; let children_sorted = { let mut children = node.children.iter().cloned().collect::>(); children.sort_by_key(|idx| tree.nodes.get(*idx).unwrap().tag); @@ -661,12 +667,13 @@ impl DisplayRepr { for child_idx in children_sorted { extraction_aux(tree, child_idx, show_unnamed, &mut children); } - acc.push(DisplayRepr { tag: node.tag, name, rperm, children }); + acc.push(DisplayRepr { tag: node.tag, name, rperm, children, exposed }); } } } fn print( - &self, + main_root: &Option, + wildcard_subtrees: &[DisplayRepr], fmt: &DisplayFmt, indenter: &mut DisplayIndent, protected_tags: &FxHashMap, @@ -703,15 +710,41 @@ impl DisplayRepr { block.push(s); } // This is the actual work - print_aux( - self, - &range_padding, - fmt, - indenter, - protected_tags, - true, /* root _is_ the last child */ - &mut block, - ); + if let Some(root) = main_root { + print_aux( + root, + &range_padding, + fmt, + indenter, + protected_tags, + true, /* root _is_ the last child */ + false, /* not a wildcard_root*/ + &mut block, + ); + } + for tree in wildcard_subtrees.iter() { + let mut gap_line = String::new(); + gap_line.push_str(fmt.perm.open); + for (i, &pad) in range_padding.iter().enumerate() { + if i > 0 { + gap_line.push_str(fmt.perm.sep); + } + gap_line.push_str(&format!("{}{}", char_repeat(' ', pad), " ")); + } + gap_line.push_str(fmt.perm.close); + block.push(gap_line); + + print_aux( + tree, + &range_padding, + fmt, + indenter, + protected_tags, + true, /* root _is_ the last child */ + true, /* wildcard_root*/ + &mut block, + ); + } // Then it's just prettifying it with a border of dashes. { let wr = &fmt.wrapper; @@ -741,6 +774,7 @@ impl DisplayRepr { indent: &mut DisplayIndent, protected_tags: &FxHashMap, is_last_child: bool, + is_wildcard_root: bool, acc: &mut Vec, ) { let mut line = String::new(); @@ -760,7 +794,9 @@ impl DisplayRepr { indent.write(&mut line); { // padding - line.push_str(if is_last_child { + line.push_str(if is_wildcard_root { + fmt.padding.wildcard_root + } else if is_last_child { fmt.padding.join_last } else { fmt.padding.join_middle @@ -777,12 +813,22 @@ impl DisplayRepr { line.push_str(&fmt.print_tag(tree.tag, &tree.name)); let protector = protected_tags.get(&tree.tag); line.push_str(fmt.print_protector(protector)); + line.push_str(fmt.print_exposed(tree.exposed)); // Push the line to the accumulator then recurse. acc.push(line); let nb_children = tree.children.len(); for (i, child) in tree.children.iter().enumerate() { indent.increment(fmt, is_last_child); - print_aux(child, padding, fmt, indent, protected_tags, i + 1 == nb_children, acc); + print_aux( + child, + padding, + fmt, + indent, + protected_tags, + /* is_last_child */ i + 1 == nb_children, + /* is_wildcard_root */ false, + acc, + ); indent.decrement(fmt); } } @@ -803,6 +849,7 @@ const DEFAULT_FORMATTER: DisplayFmt = DisplayFmt { indent_last: " ", join_haschild: "┬", join_default: "─", + wildcard_root: "*", }, accessed: DisplayFmtAccess { yes: " ", no: "?", meh: "-" }, }; @@ -816,15 +863,27 @@ impl<'tcx> Tree { ) -> InterpResult<'tcx> { let mut indenter = DisplayIndent::new(); let ranges = self.locations.iter_all().map(|(range, _loc)| range).collect::>(); - if let Some(repr) = DisplayRepr::from(self, show_unnamed) { - repr.print( - &DEFAULT_FORMATTER, - &mut indenter, - protected_tags, - ranges, - /* print warning message about tags not shown */ !show_unnamed, + let main_tree = DisplayRepr::from(self, self.roots[0], show_unnamed); + let wildcard_subtrees = self.roots[1..] + .iter() + .filter_map(|root| DisplayRepr::from(self, *root, show_unnamed)) + .collect::>(); + + if main_tree.is_none() && wildcard_subtrees.is_empty() { + eprintln!( + "This allocation does not contain named tags. Use `miri_print_borrow_state(_, true)` to also print unnamed tags." ); } + + DisplayRepr::print( + &main_tree, + wildcard_subtrees.as_slice(), + &DEFAULT_FORMATTER, + &mut indenter, + protected_tags, + ranges, + /* print warning message about tags not shown */ !show_unnamed, + ); interp_ok(()) } } 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 2a1c98e5266b..e1da12282cd9 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -239,18 +239,14 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(new_prov); } }; + let new_prov = Provenance::Concrete { alloc_id, tag: new_tag }; log_creation(this, Some((alloc_id, base_offset, parent_prov)))?; - let orig_tag = match parent_prov { - ProvenanceExtra::Wildcard => return interp_ok(place.ptr().provenance), // TODO: handle retagging wildcard pointers - ProvenanceExtra::Concrete(tag) => tag, - }; - trace!( "reborrow: reference {:?} derived from {:?} (pointee {}): {:?}, size {}", new_tag, - orig_tag, + parent_prov, place.layout.ty, interpret::Pointer::new(alloc_id, base_offset), ptr_size.bytes() @@ -281,7 +277,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { assert_eq!(ptr_size, Size::ZERO); // we did the deref check above, size has to be 0 here // There's not actually any bytes here where accesses could even be tracked. // Just produce the new provenance, nothing else to do. - return interp_ok(Some(Provenance::Concrete { alloc_id, tag: new_tag })); + return interp_ok(Some(new_prov)); } let protected = new_perm.protector.is_some(); @@ -367,11 +363,10 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } } - // Record the parent-child pair in the tree. tree_borrows.new_child( base_offset, - orig_tag, + parent_prov, new_tag, inside_perms, new_perm.outside_perm, @@ -380,7 +375,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; drop(tree_borrows); - interp_ok(Some(Provenance::Concrete { alloc_id, tag: new_tag })) + interp_ok(Some(new_prov)) } fn tb_retag_place( diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 07edf20fc46c..7fc9fa786e10 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -91,11 +91,11 @@ impl LocationState { nodes: &mut UniValMap, wildcard_accesses: &mut UniValMap, access_kind: AccessKind, - access_cause: AccessCause, - access_range: Option, + access_cause: AccessCause, //diagnostics + access_range: Option, //diagnostics relatedness: AccessRelatedness, - span: Span, - location_range: Range, + span: Span, //diagnostics + location_range: Range, //diagnostics protected: bool, ) -> Result<(), TransitionError> { // Call this function now (i.e. only if we know `relatedness`), which @@ -294,8 +294,22 @@ pub struct Tree { pub(super) nodes: UniValMap, /// Associates with each location its state and wildcard access tracking. pub(super) locations: DedupRangeMap, - /// The index of the root node. - pub(super) root: UniIndex, + /// Contains both the root of the main tree as well as the roots of the wildcard subtrees. + /// + /// If we reborrow a reference which has wildcard provenance, then we do not know where in + /// the tree to attach them. Instead we create a new additional tree for this allocation + /// with this new reference as a root. We call this additional tree a wildcard subtree. + /// + /// The actual structure should be a single tree but with wildcard provenance we approximate + /// this with this ordered set of trees. Each wildcard subtree is the direct child of *some* exposed + /// tag (that is smaller than the root), but we do not know which. This also means that it can only be the + /// child of a tree that comes before it in the vec ensuring we don't have any cycles in our + /// approximated tree. + /// + /// Sorted according to `BorTag` from low to high. This also means the main root is `root[0]`. + /// + /// Has array size 2 because that still ensures the minimum size for SmallVec. + pub(super) roots: SmallVec<[UniIndex; 2]>, } /// A node in the borrow tree. Each node is uniquely identified by a tag via @@ -345,12 +359,13 @@ struct TreeVisitor<'tree> { } /// Whether to continue exploring the children recursively or not. +#[derive(Debug)] enum ContinueTraversal { Recurse, SkipSelfAndChildren, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub enum ChildrenVisitMode { VisitChildrenOfAccessed, SkipChildrenOfAccessed, @@ -384,7 +399,7 @@ struct TreeVisitorStack { impl TreeVisitorStack where NodeContinue: Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - NodeApp: Fn(NodeAppArgs<'_>) -> Result<(), Err>, + NodeApp: FnMut(NodeAppArgs<'_>) -> Result<(), Err>, { fn should_continue_at( &self, @@ -405,12 +420,13 @@ where (self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, loc: this.loc }) } + /// Returns the root of this tree. fn go_upwards_from_accessed( &mut self, this: &mut TreeVisitor<'_>, accessed_node: UniIndex, visit_children: ChildrenVisitMode, - ) -> Result<(), Err> { + ) -> Result { // We want to visit the accessed node's children first. // However, we will below walk up our parents and push their children (our cousins) // onto the stack. To ensure correct iteration order, this method thus finishes @@ -455,7 +471,7 @@ where } // Reverse the stack, as discussed above. self.stack.reverse(); - Ok(()) + Ok(last_node) } fn finish_foreign_accesses(&mut self, this: &mut TreeVisitor<'_>) -> Result<(), Err> { @@ -536,18 +552,20 @@ impl<'tree> TreeVisitor<'tree> { /// Finally, remember that the iteration order is not relevant for UB, it only affects /// diagnostics. It also affects tree traversal optimizations built on top of this, so /// those need to be reviewed carefully as well whenever this changes. + /// + /// Returns the index of the root of the accessed tree. fn traverse_this_parents_children_other( mut self, start_idx: UniIndex, f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - f_propagate: impl Fn(NodeAppArgs<'_>) -> Result<(), Err>, - ) -> Result<(), Err> { + f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + ) -> Result { let mut stack = TreeVisitorStack::new(f_continue, f_propagate); // Visits the accessed node itself, and all its parents, i.e. all nodes // undergoing a child access. Also pushes the children and the other // cousin nodes (i.e. all nodes undergoing a foreign access) to the stack // to be processed later. - stack.go_upwards_from_accessed( + let root = stack.go_upwards_from_accessed( &mut self, start_idx, ChildrenVisitMode::VisitChildrenOfAccessed, @@ -555,21 +573,24 @@ impl<'tree> TreeVisitor<'tree> { // Now visit all the foreign nodes we remembered earlier. // For this we go bottom-up, but also allow f_continue to skip entire // subtrees from being visited if it would be a NOP. - stack.finish_foreign_accesses(&mut self) + stack.finish_foreign_accesses(&mut self)?; + Ok(root) } /// Like `traverse_this_parents_children_other`, but skips the children of `start_idx`. + /// + /// Returns the index of the root of the accessed tree. fn traverse_nonchildren( mut self, start_idx: UniIndex, f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - f_propagate: impl Fn(NodeAppArgs<'_>) -> Result<(), Err>, - ) -> Result<(), Err> { + f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + ) -> Result { let mut stack = TreeVisitorStack::new(f_continue, f_propagate); // Visits the accessed node itself, and all its parents, i.e. all nodes // undergoing a child access. Also pushes the other cousin nodes to the // stack, but not the children of the accessed node. - stack.go_upwards_from_accessed( + let root = stack.go_upwards_from_accessed( &mut self, start_idx, ChildrenVisitMode::SkipChildrenOfAccessed, @@ -577,6 +598,27 @@ impl<'tree> TreeVisitor<'tree> { // Now visit all the foreign nodes we remembered earlier. // For this we go bottom-up, but also allow f_continue to skip entire // subtrees from being visited if it would be a NOP. + stack.finish_foreign_accesses(&mut self)?; + Ok(root) + } + + /// Traverses all children of `start_idx` including `start_idx` itself. + /// Uses `f_continue` to filter out subtrees and then processes each node + /// with `f_propagate` so that the children get processed before their + /// parents. + fn traverse_children_this( + mut self, + start_idx: UniIndex, + f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, + f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + ) -> Result<(), Err> { + let mut stack = TreeVisitorStack::new(f_continue, f_propagate); + + stack.stack.push(( + start_idx, + AccessRelatedness::ForeignAccess, + RecursionState::BeforeChildren, + )); stack.finish_foreign_accesses(&mut self) } } @@ -625,7 +667,7 @@ impl Tree { let wildcard_accesses = UniValMap::default(); DedupRangeMap::new(size, LocationTree { perms, wildcard_accesses }) }; - Self { root: root_idx, nodes, locations, tag_mapping } + Self { roots: SmallVec::from_slice(&[root_idx]), nodes, locations, tag_mapping } } } @@ -639,7 +681,7 @@ impl<'tcx> Tree { pub(super) fn new_child( &mut self, base_offset: Size, - parent_tag: BorTag, + parent_prov: ProvenanceExtra, new_tag: BorTag, inside_perms: DedupRangeMap, outside_perm: Permission, @@ -647,7 +689,11 @@ impl<'tcx> Tree { span: Span, ) -> InterpResult<'tcx> { let idx = self.tag_mapping.insert(new_tag); - let parent_idx = self.tag_mapping.get(&parent_tag).unwrap(); + let parent_idx = match parent_prov { + ProvenanceExtra::Concrete(parent_tag) => + Some(self.tag_mapping.get(&parent_tag).unwrap()), + ProvenanceExtra::Wildcard => None, + }; assert!(outside_perm.is_initial()); let default_strongest_idempotent = @@ -657,7 +703,7 @@ impl<'tcx> Tree { idx, Node { tag: new_tag, - parent: Some(parent_idx), + parent: parent_idx, children: SmallVec::default(), default_initial_perm: outside_perm, default_initial_idempotent_foreign_access: default_strongest_idempotent, @@ -665,9 +711,17 @@ impl<'tcx> Tree { debug_info: NodeDebugInfo::new(new_tag, outside_perm, span), }, ); - let parent_node = self.nodes.get_mut(parent_idx).unwrap(); - // Register new_tag as a child of parent_tag - parent_node.children.push(idx); + if let Some(parent_idx) = parent_idx { + let parent_node = self.nodes.get_mut(parent_idx).unwrap(); + // Register new_tag as a child of parent_tag + parent_node.children.push(idx); + } else { + // If the parent had wildcard provenance, then register the idx + // as a new wildcard root. + // This preserves the orderedness of `roots` because a newly created + // tag is greater than all previous tags. + self.roots.push(idx); + } // We need to know the weakest SIFA for `update_idempotent_foreign_access_after_retag`. let mut min_sifa = default_strongest_idempotent; @@ -691,19 +745,27 @@ impl<'tcx> Tree { // We need to ensure the consistency of the wildcard access tracking data structure. // For this, we insert the correct entry for this tag based on its parent, if it exists. + // If we are inserting a new wildcard root (with Wildcard as parent_prov) then we insert + // the special wildcard root initial state instead. for (_range, loc) in self.locations.iter_mut_all() { - if let Some(parent_access) = loc.wildcard_accesses.get(parent_idx) { - loc.wildcard_accesses.insert(idx, parent_access.for_new_child()); + if let Some(parent_idx) = parent_idx { + if let Some(parent_access) = loc.wildcard_accesses.get(parent_idx) { + loc.wildcard_accesses.insert(idx, parent_access.for_new_child()); + } + } else { + loc.wildcard_accesses.insert(idx, WildcardState::for_wildcard_root()); } } - - // Inserting the new perms might have broken the SIFA invariant (see - // `foreign_access_skipping.rs`) if the SIFA we inserted is weaker than that of some parent. - // We now weaken the recorded SIFA for our parents, until the invariant is restored. We - // could weaken them all to `None`, but it is more efficient to compute the SIFA for the new - // permission statically, and use that. For this we need the *minimum* SIFA (`None` needs - // more fixup than `Write`). - self.update_idempotent_foreign_access_after_retag(parent_idx, min_sifa); + // If the parent is a wildcard pointer, then it doesn't track SIFA and doesn't need to be updated. + if let Some(parent_idx) = parent_idx { + // Inserting the new perms might have broken the SIFA invariant (see + // `foreign_access_skipping.rs`) if the SIFA we inserted is weaker than that of some parent. + // We now weaken the recorded SIFA for our parents, until the invariant is restored. We + // could weaken them all to `None`, but it is more efficient to compute the SIFA for the new + // permission statically, and use that. For this we need the *minimum* SIFA (`None` needs + // more fixup than `Write`). + self.update_idempotent_foreign_access_after_retag(parent_idx, min_sifa); + } interp_ok(()) } @@ -772,52 +834,67 @@ impl<'tcx> Tree { span, )?; - // The order in which we check if any nodes are invalidated only - // matters to diagnostics, so we use the root as a default tag. let start_idx = match prov { - ProvenanceExtra::Concrete(tag) => self.tag_mapping.get(&tag).unwrap(), - ProvenanceExtra::Wildcard => self.root, + ProvenanceExtra::Concrete(tag) => Some(self.tag_mapping.get(&tag).unwrap()), + ProvenanceExtra::Wildcard => None, }; // Check if this breaks any strong protector. // (Weak protectors are already handled by `perform_access`.) for (loc_range, loc) in self.locations.iter_mut(access_range.start, access_range.size) { - TreeVisitor { nodes: &mut self.nodes, loc }.traverse_this_parents_children_other( - start_idx, - // Visit all children, skipping none. - |_| ContinueTraversal::Recurse, - |args: NodeAppArgs<'_>| { - let node = args.nodes.get(args.idx).unwrap(); - let perm = args.loc.perms.entry(args.idx); + // Checks the tree containing `idx` for strong protector violations. + // It does this in traversal order. + let mut check_tree = |idx| { + TreeVisitor { nodes: &mut self.nodes, loc }.traverse_this_parents_children_other( + idx, + // Visit all children, skipping none. + |_| ContinueTraversal::Recurse, + |args: NodeAppArgs<'_>| { + let node = args.nodes.get(args.idx).unwrap(); - let perm = perm.get().copied().unwrap_or_else(|| node.default_location_state()); - if global.borrow().protected_tags.get(&node.tag) - == Some(&ProtectorKind::StrongProtector) - // Don't check for protector if it is a Cell (see `unsafe_cell_deallocate` in `interior_mutability.rs`). - // Related to https://github.com/rust-lang/rust/issues/55005. - && !perm.permission.is_cell() - // Only trigger UB if the accessed bit is set, i.e. if the protector is actually protecting this offset. See #4579. - && perm.accessed - { - Err(TbError { - conflicting_info: &node.debug_info, - access_cause: diagnostics::AccessCause::Dealloc, - alloc_id, - error_offset: loc_range.start, - error_kind: TransitionError::ProtectedDealloc, - accessed_info: match prov { - ProvenanceExtra::Concrete(_) => - Some(&args.nodes.get(start_idx).unwrap().debug_info), - // We don't know from where the access came during a wildcard access. - ProvenanceExtra::Wildcard => None, - }, + let perm = args + .loc + .perms + .get(args.idx) + .copied() + .unwrap_or_else(|| node.default_location_state()); + if global.borrow().protected_tags.get(&node.tag) + == Some(&ProtectorKind::StrongProtector) + // Don't check for protector if it is a Cell (see `unsafe_cell_deallocate` in `interior_mutability.rs`). + // Related to https://github.com/rust-lang/rust/issues/55005. + && !perm.permission.is_cell() + // Only trigger UB if the accessed bit is set, i.e. if the protector is actually protecting this offset. See #4579. + && perm.accessed + { + Err(TbError { + conflicting_info: &node.debug_info, + access_cause: diagnostics::AccessCause::Dealloc, + alloc_id, + error_offset: loc_range.start, + error_kind: TransitionError::ProtectedDealloc, + accessed_info: start_idx + .map(|idx| &args.nodes.get(idx).unwrap().debug_info), + } + .build()) + } else { + Ok(()) } - .build()) - } else { - Ok(()) - } - }, - )?; + }, + ) + }; + // If we have a start index we first check its subtree in traversal order. + // This results in us showing the error of the closest node instead of an + // arbitrary one. + let accessed_root = start_idx.map(&mut check_tree).transpose()?; + // Afterwards we check all other trees. + // We iterate over the list in reverse order to ensure that we do not visit + // a parent before its child. + for &root in self.roots.iter().rev() { + if Some(root) == accessed_root { + continue; + } + check_tree(root)?; + } } interp_ok(()) } @@ -849,20 +926,20 @@ impl<'tcx> Tree { span: Span, // diagnostics ) -> InterpResult<'tcx> { #[cfg(feature = "expensive-consistency-checks")] - if matches!(prov, ProvenanceExtra::Wildcard) { + if self.roots.len() > 1 || matches!(prov, ProvenanceExtra::Wildcard) { self.verify_wildcard_consistency(global); } + let source_idx = match prov { ProvenanceExtra::Concrete(tag) => Some(self.tag_mapping.get(&tag).unwrap()), ProvenanceExtra::Wildcard => None, }; - if let Some((access_range, access_kind, access_cause)) = access_range_and_kind { // Default branch: this is a "normal" access through a known range. // We iterate over affected locations and traverse the tree for each of them. for (loc_range, loc) in self.locations.iter_mut(access_range.start, access_range.size) { loc.perform_access( - self.root, + self.roots.iter().copied(), &mut self.nodes, source_idx, loc_range, @@ -898,7 +975,7 @@ impl<'tcx> Tree { { let access_cause = diagnostics::AccessCause::FnExit(access_kind); loc.perform_access( - self.root, + self.roots.iter().copied(), &mut self.nodes, Some(source_idx), loc_range, @@ -920,7 +997,9 @@ impl<'tcx> Tree { /// Integration with the BorTag garbage collector impl Tree { pub fn remove_unreachable_tags(&mut self, live_tags: &FxHashSet) { - self.remove_useless_children(self.root, live_tags); + for i in 0..(self.roots.len()) { + self.remove_useless_children(self.roots[i], live_tags); + } // Right after the GC runs is a good moment to check if we can // merge some adjacent ranges that were made equal by the removal of some // tags (this does not necessarily mean that they have identical internal representations, @@ -1073,20 +1152,20 @@ impl<'tcx> LocationTree { /// * `visit_children`: Whether to skip updating the children of `access_source`. fn perform_access( &mut self, - root: UniIndex, + roots: impl Iterator, nodes: &mut UniValMap, access_source: Option, - loc_range: Range, - access_range: Option, + loc_range: Range, // diagnostics + access_range: Option, // diagnostics access_kind: AccessKind, - access_cause: diagnostics::AccessCause, + access_cause: diagnostics::AccessCause, // diagnostics global: &GlobalState, alloc_id: AllocId, // diagnostics span: Span, // diagnostics visit_children: ChildrenVisitMode, ) -> InterpResult<'tcx> { - if let Some(idx) = access_source { - self.perform_normal_access( + let accessed_root = if let Some(idx) = access_source { + Some(self.perform_normal_access( idx, nodes, loc_range.clone(), @@ -1097,13 +1176,38 @@ impl<'tcx> LocationTree { alloc_id, span, visit_children, - ) + )?) } else { - // `SkipChildrenOfAccessed` only gets set on protector release. - // Since a wildcard reference are never protected this assert shouldn't fail. + // `SkipChildrenOfAccessed` only gets set on protector release, which only + // occurs on a known node. assert!(matches!(visit_children, ChildrenVisitMode::VisitChildrenOfAccessed)); + None + }; + + let accessed_root_tag = accessed_root.map(|idx| nodes.get(idx).unwrap().tag); + if matches!(visit_children, ChildrenVisitMode::SkipChildrenOfAccessed) { + // FIXME: approximate which roots could be children of the accessed node and only skip them instead of all other trees. + return interp_ok(()); + } + for root in roots { + // We don't perform a wildcard access on the tree we already performed a + // normal access on. + if Some(root) == accessed_root { + continue; + } + // The choice of `max_local_tag` requires some thought. + // This can only be a local access for nodes that are a parent of the accessed node + // and are therefore smaller, so the accessed node itself is a valid choice for `max_local_tag`. + // However, using `accessed_root` is better since that will be smaller. It is still a valid choice + // because for nodes *in other trees*, if they are a parent of the accessed node then they + // are a parent of `accessed_root`. + // + // As a consequence of this, since the root of the main tree is the smallest tag in the entire + // allocation, if the access occurred in the main tree then other subtrees will only see foreign accesses. self.perform_wildcard_access( root, + access_source, + /*max_local_tag*/ accessed_root_tag, nodes, loc_range.clone(), access_range, @@ -1112,11 +1216,14 @@ impl<'tcx> LocationTree { global, alloc_id, span, - ) + )?; } + interp_ok(()) } /// Performs a normal access on the tree containing `access_source`. + /// + /// Returns the root index of this tree. /// * `access_source`: The index of the tag being accessed. /// * `visit_children`: Whether to skip the children of `access_source` /// during the access. Used for protector end access. @@ -1124,15 +1231,15 @@ impl<'tcx> LocationTree { &mut self, access_source: UniIndex, nodes: &mut UniValMap, - loc_range: Range, - access_range: Option, + loc_range: Range, // diagnostics + access_range: Option, // diagnostics access_kind: AccessKind, - access_cause: diagnostics::AccessCause, + access_cause: diagnostics::AccessCause, // diagnostics global: &GlobalState, alloc_id: AllocId, // diagnostics span: Span, // diagnostics visit_children: ChildrenVisitMode, - ) -> InterpResult<'tcx> { + ) -> InterpResult<'tcx, UniIndex> { // Performs the per-node work: // - insert the permission if it does not exist // - perform the access @@ -1141,7 +1248,7 @@ impl<'tcx> LocationTree { // - skip the traversal of the children in some cases // - do not record noop transitions // - // `perms_range` is only for diagnostics (it is the range of + // `loc_range` is only for diagnostics (it is the range of // the `RangeMap` on which we are currently working). let node_skipper = |args: &NodeAppArgs<'_>| -> ContinueTraversal { let node = args.nodes.get(args.idx).unwrap(); @@ -1150,7 +1257,7 @@ impl<'tcx> LocationTree { let old_state = perm.copied().unwrap_or_else(|| node.default_location_state()); old_state.skip_if_known_noop(access_kind, args.rel_pos) }; - let node_app = |args: NodeAppArgs<'_>| -> Result<(), _> { + let node_app = |args: NodeAppArgs<'_>| { let node = args.nodes.get_mut(args.idx).unwrap(); let mut perm = args.loc.perms.entry(args.idx); @@ -1164,7 +1271,7 @@ impl<'tcx> LocationTree { &mut args.loc.wildcard_accesses, access_kind, access_cause, - /* access_range */ access_range, + access_range, args.rel_pos, span, loc_range.clone(), @@ -1182,6 +1289,7 @@ impl<'tcx> LocationTree { .build() }) }; + let visitor = TreeVisitor { nodes, loc: self }; match visit_children { ChildrenVisitMode::VisitChildrenOfAccessed => @@ -1191,31 +1299,61 @@ impl<'tcx> LocationTree { } .into() } + /// Performs a wildcard access on the tree with root `root`. Takes the `access_relatedness` /// for each node from the `WildcardState` datastructure. /// * `root`: Root of the tree being accessed. + /// * `access_source`: the index of the accessed tag, if any. + /// This is only used for printing the correct tag on errors. + /// * `max_local_tag`: The access can only be local for nodes whose tag is + /// at most `max_local_tag`. fn perform_wildcard_access( &mut self, root: UniIndex, + access_source: Option, + max_local_tag: Option, nodes: &mut UniValMap, - loc_range: Range, - access_range: Option, + loc_range: Range, // diagnostics + access_range: Option, // diagnostics access_kind: AccessKind, - access_cause: diagnostics::AccessCause, + access_cause: diagnostics::AccessCause, // diagnostics global: &GlobalState, alloc_id: AllocId, // diagnostics span: Span, // diagnostics ) -> InterpResult<'tcx> { - let f_continue = - |idx: UniIndex, nodes: &UniValMap, loc: &LocationTree| -> ContinueTraversal { - let node = nodes.get(idx).unwrap(); - let perm = loc.perms.get(idx); - let wildcard_state = loc.wildcard_accesses.get(idx).cloned().unwrap_or_default(); + let get_relatedness = |idx: UniIndex, node: &Node, loc: &LocationTree| { + let wildcard_state = loc.wildcard_accesses.get(idx).cloned().unwrap_or_default(); + // If the tag is larger than `max_local_tag` then the access can only be foreign. + let only_foreign = max_local_tag.is_some_and(|max_local_tag| max_local_tag < node.tag); + wildcard_state.access_relatedness(access_kind, only_foreign) + }; + + // This does a traversal across the tree updating children before their parents. The + // difference to `perform_normal_access` is that we take the access relatedness from + // the wildcard tracking state of the node instead of from the visitor itself. + // + // Unlike for a normal access, the iteration order is important for improving the + // accuracy of wildcard accesses if `max_local_tag` is `Some`: processing the effects of this + // access further down the tree can cause exposed nodes to lose permissions, thus updating + // the wildcard data structure, which will be taken into account when processing the parent + // nodes. Also see the test `cross_tree_update_older_invalid_exposed2.rs` + // (Doing accesses in the opposite order cannot help with precision but the reasons are complicated; + // see .) + // + // Note, however, that this is an approximation: there can be situations where a node is + // marked as having an exposed foreign node, but actually that foreign node cannot be + // the source of the access due to `max_local_tag`. The wildcard tracking cannot know + // about `max_local_tag` so we will incorrectly assume that this might be a foreign access. + TreeVisitor { loc: self, nodes }.traverse_children_this( + root, + |args| -> ContinueTraversal { + let node = args.nodes.get(args.idx).unwrap(); + let perm = args.loc.perms.get(args.idx); let old_state = perm.copied().unwrap_or_else(|| node.default_location_state()); // If we know where, relative to this node, the wildcard access occurs, // then check if we can skip the entire subtree. - if let Some(relatedness) = wildcard_state.access_relatedness(access_kind) + if let Some(relatedness) = get_relatedness(args.idx, node, args.loc) && let Some(relatedness) = relatedness.to_relatedness() { // We can use the usual SIFA machinery to skip nodes. @@ -1223,78 +1361,64 @@ impl<'tcx> LocationTree { } else { ContinueTraversal::Recurse } - }; - // This does a traversal starting from the root through the tree updating - // the permissions of each node. - // The difference to `perform_access` is that we take the access - // relatedness from the wildcard tracking state of the node instead of - // from the visitor itself. - TreeVisitor { loc: self, nodes } - .traverse_this_parents_children_other( - root, - |args| f_continue(args.idx, args.nodes, args.loc), - |args| { - let node = args.nodes.get_mut(args.idx).unwrap(); - let mut entry = args.loc.perms.entry(args.idx); - let perm = entry.or_insert(node.default_location_state()); + }, + |args| { + let node = args.nodes.get_mut(args.idx).unwrap(); - let protected = global.borrow().protected_tags.contains_key(&node.tag); + let protected = global.borrow().protected_tags.contains_key(&node.tag); - let Some(wildcard_relatedness) = args - .loc - .wildcard_accesses - .get(args.idx) - .and_then(|s| s.access_relatedness(access_kind)) - else { - // There doesn't exist a valid exposed reference for this access to - // happen through. - // If this fails for one id, then it fails for all ids so this. - // Since we always check the root first, this means it should always - // fail on the root. - assert_eq!(root, args.idx); - return Err(no_valid_exposed_references_error( - alloc_id, - loc_range.start, - access_cause, - )); - }; - - let Some(relatedness) = wildcard_relatedness.to_relatedness() else { - // If the access type is Either, then we do not apply any transition - // to this node, but we still update each of its children. - // This is an imprecision! In the future, maybe we can still do some sort - // of best-effort update here. - return Ok(()); - }; - // We know the exact relatedness, so we can actually do precise checks. - perm.perform_transition( - args.idx, - args.nodes, - &mut args.loc.wildcard_accesses, - access_kind, + let Some(wildcard_relatedness) = get_relatedness(args.idx, node, args.loc) else { + // There doesn't exist a valid exposed reference for this access to + // happen through. + // This can only happen if `root` is the main root: We set + // `max_foreign_access==Write` on all wildcard roots, so at least a foreign access + // is always possible on all nodes in a wildcard subtree. + return Err(no_valid_exposed_references_error( + alloc_id, + loc_range.start, access_cause, - access_range, - relatedness, - span, - loc_range.clone(), - protected, - ) - .map_err(|trans| { - let node = args.nodes.get(args.idx).unwrap(); - TbError { - conflicting_info: &node.debug_info, - access_cause, - alloc_id, - error_offset: loc_range.start, - error_kind: trans, - // We don't know from where the access came during a wildcard access. - accessed_info: None, - } - .build() - }) - }, - ) - .into() + )); + }; + + let Some(relatedness) = wildcard_relatedness.to_relatedness() else { + // If the access type is Either, then we do not apply any transition + // to this node, but we still update each of its children. + // This is an imprecision! In the future, maybe we can still do some sort + // of best-effort update here. + return Ok(()); + }; + + let mut entry = args.loc.perms.entry(args.idx); + let perm = entry.or_insert(node.default_location_state()); + // We know the exact relatedness, so we can actually do precise checks. + perm.perform_transition( + args.idx, + args.nodes, + &mut args.loc.wildcard_accesses, + access_kind, + access_cause, + access_range, + relatedness, + span, + loc_range.clone(), + protected, + ) + .map_err(|trans| { + let node = args.nodes.get(args.idx).unwrap(); + TbError { + conflicting_info: &node.debug_info, + access_cause, + alloc_id, + error_offset: loc_range.start, + error_kind: trans, + accessed_info: access_source + .map(|idx| &args.nodes.get(idx).unwrap().debug_info), + } + .build() + }) + }, + )?; + interp_ok(()) } } @@ -1309,10 +1433,11 @@ impl Node { impl VisitProvenance for Tree { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { - // To ensure that the root never gets removed, we visit it - // (the `root` node of `Tree` is not an `Option<_>`) - visit(None, Some(self.nodes.get(self.root).unwrap().tag)); - + // To ensure that the roots never get removed, we visit them. + // FIXME: it should be possible to GC wildcard tree roots. + for id in self.roots.iter().copied() { + visit(None, Some(self.nodes.get(id).unwrap().tag)); + } // We also need to keep around any exposed tags through which // an access could still happen. for (_id, node) in self.nodes.iter() { diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs index 56a85e6f4ced..3b55a9e36ea6 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs @@ -88,10 +88,26 @@ impl WildcardState { } /// From where relative to the node with this wildcard info a read or write access could happen. - pub fn access_relatedness(&self, kind: AccessKind) -> Option { - match kind { + /// If `only_foreign` is true then we treat `LocalAccess` as impossible. This means we return + /// `None` if only a `LocalAccess` is possible, and we treat `EitherAccess` as a + /// `ForeignAccess`. + pub fn access_relatedness( + &self, + kind: AccessKind, + only_foreign: bool, + ) -> Option { + let rel = match kind { AccessKind::Read => self.read_access_relatedness(), AccessKind::Write => self.write_access_relatedness(), + }; + if only_foreign { + use WildcardAccessRelatedness as E; + match rel { + Some(E::EitherAccess | E::ForeignAccess) => Some(E::ForeignAccess), + Some(E::LocalAccess) | None => None, + } + } else { + rel } } @@ -131,6 +147,15 @@ impl WildcardState { ..Default::default() } } + /// Crates the initial `WildcardState` for a wildcard root. + /// This has `max_foreign_access==Write` as it actually is the child of *some* exposed node + /// through which we can receive foreign accesses. + /// + /// This is different from the main root which has `max_foreign_access==None`, since there + /// cannot be a foreign access to the root of the allocation. + pub fn for_wildcard_root() -> Self { + Self { max_foreign_access: WildcardAccessLevel::Write, ..Default::default() } + } /// Pushes the nodes of `children` onto the stack who's `max_foreign_access` /// needs to be updated. @@ -435,6 +460,10 @@ impl Tree { /// Checks that the wildcard tracking data structure is internally consistent and /// has the correct `exposed_as` values. pub fn verify_wildcard_consistency(&self, global: &GlobalState) { + // We rely on the fact that `roots` is ordered according to tag from low to high. + assert!(self.roots.is_sorted_by_key(|idx| self.nodes.get(*idx).unwrap().tag)); + let main_root_idx = self.roots[0]; + let protected_tags = &global.borrow().protected_tags; for (_, loc) in self.locations.iter_all() { let wildcard_accesses = &loc.wildcard_accesses; @@ -447,7 +476,8 @@ impl Tree { let state = wildcard_accesses.get(id).unwrap(); let expected_exposed_as = if node.is_exposed { - let perm = perms.get(id).unwrap(); + let perm = + perms.get(id).copied().unwrap_or_else(|| node.default_location_state()); perm.permission() .strongest_allowed_child_access(protected_tags.contains_key(&node.tag)) @@ -477,7 +507,16 @@ impl Tree { .max(parent_state.max_foreign_access) .max(parent_state.exposed_as) } else { - WildcardAccessLevel::None + if main_root_idx == id { + // There can never be a foreign access to the root of the allocation. + // So its foreign access level is always `None`. + WildcardAccessLevel::None + } else { + // For wildcard roots any access on a different subtree can be foreign + // to it. So a wildcard root has the maximum possible foreign access + // level. + WildcardAccessLevel::Write + } }; // Count how many children can be the source of wildcard reads or writes diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed1.rs b/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed1.rs similarity index 70% rename from src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed1.rs rename to src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed1.rs index 76516b7d924b..8cd72b589b8e 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed1.rs +++ b/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed1.rs @@ -1,4 +1,6 @@ +//@revisions: stack tree //@compile-flags: -Zmiri-permissive-provenance +//@[tree]compile-flags: -Zmiri-tree-borrows fn main() { unsafe { @@ -12,6 +14,8 @@ fn main() { // And we test that it has uniqueness by doing a conflicting write. *exposed_ptr = 0; // Stack: Unknown( at ALLOC[0x0], but that tag does not exist in the borrow stack for this location - --> tests/fail/stacked_borrows/illegal_read_despite_exposed1.rs:LL:CC + --> tests/fail/both_borrows/illegal_read_despite_exposed1.rs:LL:CC | LL | let _val = *root2; | ^^^^^^ this error occurs as part of an access at ALLOC[0x0..0x4] @@ -7,12 +7,12 @@ LL | let _val = *root2; = 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 [0x0..0x4] - --> tests/fail/stacked_borrows/illegal_read_despite_exposed1.rs:LL:CC + --> tests/fail/both_borrows/illegal_read_despite_exposed1.rs:LL:CC | LL | let root2 = &mut *exposed_ptr; | ^^^^^^^^^^^^^^^^^ help: was later invalidated at offsets [0x0..0x4] by a write access - --> tests/fail/stacked_borrows/illegal_read_despite_exposed1.rs:LL:CC + --> tests/fail/both_borrows/illegal_read_despite_exposed1.rs:LL:CC | LL | *exposed_ptr = 0; | ^^^^^^^^^^^^^^^^ diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed1.tree.stderr new file mode 100644 index 000000000000..e6c9a142c3f2 --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed1.tree.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/both_borrows/illegal_read_despite_exposed1.rs:LL:CC + | +LL | let _val = *root2; + | ^^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/both_borrows/illegal_read_despite_exposed1.rs:LL:CC + | +LL | let root2 = &mut *exposed_ptr; + | ^^^^^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/both_borrows/illegal_read_despite_exposed1.rs:LL:CC + | +LL | *exposed_ptr = 0; + | ^^^^^^^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/stacked_borrows/illegal_read_despite_exposed2.rs b/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed2.rs similarity index 65% rename from src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed2.rs rename to src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed2.rs index 97e0bf40c0dd..9e8c94031ce8 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_read_despite_exposed2.rs +++ b/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed2.rs @@ -1,4 +1,6 @@ +//@revisions: stack tree //@compile-flags: -Zmiri-permissive-provenance +//@[tree]compile-flags: -Zmiri-tree-borrows fn main() { unsafe { @@ -7,6 +9,8 @@ fn main() { let exposed_ptr = addr as *mut i32; // From the exposed ptr, we get a new unique ptr. let root2 = &mut *exposed_ptr; + // Activate the reference (unnecessary on Stacked Borrows). + *root2 = 42; // let _fool = root2 as *mut _; // this would fool us, since SRW(N+1) remains on the stack // Stack: Unknown( at ALLOC[0x0], but that tag does not exist in the borrow stack for this location - --> tests/fail/stacked_borrows/illegal_read_despite_exposed2.rs:LL:CC +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + --> tests/fail/both_borrows/illegal_read_despite_exposed2.rs:LL:CC | -LL | let _val = *root2; - | ^^^^^^ this error occurs as part of an access at ALLOC[0x0..0x4] +LL | *root2 = 3; + | ^^^^^^^^^^ this error occurs as part of an access at ALLOC[0x0..0x4] | = 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 [0x0..0x4] - --> tests/fail/stacked_borrows/illegal_read_despite_exposed2.rs:LL:CC + --> tests/fail/both_borrows/illegal_read_despite_exposed2.rs:LL:CC | LL | let root2 = &mut *exposed_ptr; | ^^^^^^^^^^^^^^^^^ help: was later invalidated at offsets [0x0..0x4] by a read access - --> tests/fail/stacked_borrows/illegal_read_despite_exposed2.rs:LL:CC + --> tests/fail/both_borrows/illegal_read_despite_exposed2.rs:LL:CC | LL | let _val = *exposed_ptr; | ^^^^^^^^^^^^ diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed2.tree.stderr new file mode 100644 index 000000000000..17ae8bc513da --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/illegal_read_despite_exposed2.tree.stderr @@ -0,0 +1,31 @@ +error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden + --> tests/fail/both_borrows/illegal_read_despite_exposed2.rs:LL:CC + | +LL | *root2 = 3; + | ^^^^^^^^^^ 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 has state Frozen which forbids this child write access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/both_borrows/illegal_read_despite_exposed2.rs:LL:CC + | +LL | let root2 = &mut *exposed_ptr; + | ^^^^^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Unique due to a child write access at offsets [0x0..0x4] + --> tests/fail/both_borrows/illegal_read_despite_exposed2.rs:LL:CC + | +LL | *root2 = 42; + | ^^^^^^^^^^^ + = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference +help: the accessed tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x4] + --> tests/fail/both_borrows/illegal_read_despite_exposed2.rs:LL:CC + | +LL | let _val = *exposed_ptr; + | ^^^^^^^^^^^^ + = help: this transition corresponds to a loss of write permissions + +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/stacked_borrows/illegal_write_despite_exposed1.rs b/src/tools/miri/tests/fail/both_borrows/illegal_write_despite_exposed1.rs similarity index 69% rename from src/tools/miri/tests/fail/stacked_borrows/illegal_write_despite_exposed1.rs rename to src/tools/miri/tests/fail/both_borrows/illegal_write_despite_exposed1.rs index 0e34c5c98fc1..a6c67f89980c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write_despite_exposed1.rs +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write_despite_exposed1.rs @@ -1,4 +1,6 @@ +//@revisions: stack tree //@compile-flags: -Zmiri-permissive-provenance +//@[tree]compile-flags: -Zmiri-tree-borrows fn main() { unsafe { @@ -12,6 +14,9 @@ fn main() { // (The write is still fine, using the `root as *mut i32` provenance which got exposed.) *exposed_ptr = 0; // Stack: Unknown( at ALLOC[0x0], but that tag does not exist in the borrow stack for this location - --> tests/fail/stacked_borrows/illegal_write_despite_exposed1.rs:LL:CC + --> tests/fail/both_borrows/illegal_write_despite_exposed1.rs:LL:CC | LL | let _val = *root2; | ^^^^^^ this error occurs as part of an access at ALLOC[0x0..0x4] @@ -7,12 +7,12 @@ LL | let _val = *root2; = 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 SharedReadOnly retag at offsets [0x0..0x4] - --> tests/fail/stacked_borrows/illegal_write_despite_exposed1.rs:LL:CC + --> tests/fail/both_borrows/illegal_write_despite_exposed1.rs:LL:CC | LL | let root2 = &*exposed_ptr; | ^^^^^^^^^^^^^ help: was later invalidated at offsets [0x0..0x4] by a write access - --> tests/fail/stacked_borrows/illegal_write_despite_exposed1.rs:LL:CC + --> tests/fail/both_borrows/illegal_write_despite_exposed1.rs:LL:CC | LL | *exposed_ptr = 0; | ^^^^^^^^^^^^^^^^ diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write_despite_exposed1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write_despite_exposed1.tree.stderr new file mode 100644 index 000000000000..2f6f7eb5e9db --- /dev/null +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write_despite_exposed1.tree.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/both_borrows/illegal_write_despite_exposed1.rs:LL:CC + | +LL | let _val = *root2; + | ^^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Frozen + --> tests/fail/both_borrows/illegal_write_despite_exposed1.rs:LL:CC + | +LL | let root2 = &*exposed_ptr; + | ^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/both_borrows/illegal_write_despite_exposed1.rs:LL:CC + | +LL | *exposed_ptr = 0; + | ^^^^^^^^^^^^^^^^ + = help: this transition corresponds to a loss of read permissions + +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/tree_borrows/wildcard/cross_tree_from_main.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_from_main.rs new file mode 100644 index 000000000000..40099076f627 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_from_main.rs @@ -0,0 +1,36 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks how accesses from one subtree affect other subtrees. +/// This test checks the case where the access is to the main tree. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + let int1 = ref1 as *mut u32 as usize; + let wild = int1 as *mut u32; + + let reb3 = unsafe { &mut *wild }; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├───────────┐ * + // │ │ │ │ + // └──────┬─────┘ │ │ + // │ │ │ + // │ │ │ + // ▼ ▼ ▼ + // ┌────────────┐ ┌───────────┐ ┌───────────┐ + // │ │ │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res) │ │ reb3(Res) │ + // │ │ │ │ │ │ + // └────────────┘ └───────────┘ └───────────┘ + + // ref2 is part of the main tree and therefore foreign to all subtrees. + // Therefore, this disables reb3. + *ref2 = 13; + + let _fail = *reb3; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_from_main.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_from_main.stderr new file mode 100644 index 000000000000..bdd75027c1f3 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_from_main.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/cross_tree_from_main.rs:LL:CC + | +LL | let _fail = *reb3; + | ^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/cross_tree_from_main.rs:LL:CC + | +LL | let reb3 = unsafe { &mut *wild }; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/cross_tree_from_main.rs:LL:CC + | +LL | *ref2 = 13; + | ^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/wildcard/cross_tree_update_main.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main.rs new file mode 100644 index 000000000000..a21dcfe2acf5 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main.rs @@ -0,0 +1,37 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks how accesses from one subtree affect other subtrees. +/// This tests how main is effected by an access through a subtree. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + let int1 = ref1 as *mut u32 as usize; + let wild = int1 as *mut u32; + + let reb = unsafe { &mut *wild }; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├───────────┐ * + // │ │ │ │ + // └──────┬─────┘ │ │ + // │ │ │ + // │ │ │ + // ▼ ▼ ▼ + // ┌────────────┐ ┌───────────┐ ┌───────────┐ + // │ │ │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res) │ │ reb(Res) │ + // │ │ │ │ │ │ + // └────────────┘ └───────────┘ └───────────┘ + + // Writes through the reborrowed reference causing a wildcard + // write on the main tree. This disables ref2 as it doesn't + // have any exposed children. + *reb = 13; + + let _fail = *ref2; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main.stderr new file mode 100644 index 000000000000..285ffc4763df --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/cross_tree_update_main.rs:LL:CC + | +LL | let _fail = *ref2; + | ^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/cross_tree_update_main.rs:LL:CC + | +LL | let ref2 = unsafe { &mut *ptr_base }; + | ^^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/cross_tree_update_main.rs:LL:CC + | +LL | *reb = 13; + | ^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed.rs new file mode 100644 index 000000000000..641ffb4304d5 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed.rs @@ -0,0 +1,44 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks how accesses from one subtree affect other subtrees. +/// This test checks that an access from a subtree performs a +/// wildcard access on all earlier trees, and that local +/// accesses are treated as access errors for tags that are +/// larger than the root of the accessed subtree. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + + // Activates ref1. + *ref1 = 4; + + let int1 = ref1 as *mut u32 as usize; + let wild = int1 as *mut u32; + + let ref2 = unsafe { &mut *wild }; + + // Freezes ref1. + let ref3 = unsafe { &mut *ptr_base }; + let _int3 = ref3 as *mut u32 as usize; + + // ┌──────────────┐ + // │ │ + // │ptr_base(Act) ├───────────┐ * + // │ │ │ │ + // └──────┬───────┘ │ │ + // │ │ │ + // │ │ │ + // ▼ ▼ ▼ + // ┌─────────────┐ ┌────────────┐ ┌───────────┐ + // │ │ │ │ │ │ + // │ ref1(Frz)* │ │ ref3(Res)* │ │ ref2(Res) │ + // │ │ │ │ │ │ + // └─────────────┘ └────────────┘ └───────────┘ + + // Performs a wildcard access on the main root. However, as there are + // no exposed tags with write permissions and a tag smaller than ref2 + // this access fails. + *ref2 = 13; //~ ERROR: /write access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed.stderr new file mode 100644 index 000000000000..3d91ec4db882 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed.stderr @@ -0,0 +1,14 @@ +error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed.rs:LL:CC + | +LL | *ref2 = 13; + | ^^^^^^^^^^ 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: there are no exposed tags which may perform this access here + +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/tree_borrows/wildcard/cross_tree_update_newer.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer.rs new file mode 100644 index 000000000000..a65508c78b59 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer.rs @@ -0,0 +1,47 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks how accesses from one subtree affect other subtrees. +/// This test checks that an access from an earlier created subtree +/// is foreign to a later created one. +pub fn main() { + let mut x: u32 = 42; + + let ref_base = &mut x; + + let int0 = ref_base as *mut u32 as usize; + let wild = int0 as *mut u32; + + let reb1 = unsafe { &mut *wild }; + + let reb2 = unsafe { &mut *wild }; + + let ref3 = &mut *reb1; + let _int3 = ref3 as *mut u32 as usize; + // ┌──────────────┐ + // │ │ + // │ptr_base(Res)*│ * * + // │ │ │ │ + // └──────────────┘ │ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ reb1(Res) ├ │ reb2(Res) ├ + // │ │ │ │ + // └──────┬─────┘ └────────────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref3(Res)* │ + // │ │ + // └────────────┘ + + // This access disables reb2 because ref3 cannot be a child of it + // as reb2 both has a higher tag and doesn't have any exposed children. + *ref3 = 13; + + let _fail = *reb2; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer.stderr new file mode 100644 index 000000000000..c1ab12f3405b --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/cross_tree_update_newer.rs:LL:CC + | +LL | let _fail = *reb2; + | ^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/cross_tree_update_newer.rs:LL:CC + | +LL | let reb2 = unsafe { &mut *wild }; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/cross_tree_update_newer.rs:LL:CC + | +LL | *ref3 = 13; + | ^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/wildcard/cross_tree_update_newer_exposed.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.rs new file mode 100644 index 000000000000..666eac1e7e61 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.rs @@ -0,0 +1,48 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks how accesses from one subtree affect other subtrees. +/// This test checks that an access from an earlier created subtree +/// is foreign to a later created one. +pub fn main() { + let mut x: u32 = 42; + + let ref_base = &mut x; + + let int0 = ref_base as *mut u32 as usize; + let wild = int0 as *mut u32; + + let reb1 = unsafe { &mut *wild }; + + let reb2 = unsafe { &mut *wild }; + let _int2 = reb2 as *mut u32 as usize; + + let ref3 = &mut *reb1; + let _int3 = ref3 as *mut u32 as usize; + // ┌──────────────┐ + // │ │ + // │ptr_base(Res)*│ * * + // │ │ │ │ + // └──────────────┘ │ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ reb1(Res) │ │ reb2(Res)* │ + // │ │ │ │ + // └──────┬─────┘ └────────────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref3(Res)* │ + // │ │ + // └────────────┘ + + // This access disables reb2 because ref3 cannot be a child of it + // as ref3's root has a lower tag than reb2. + *ref3 = 13; + + let _fail = *reb2; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.stderr new file mode 100644 index 000000000000..e1232c751192 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.rs:LL:CC + | +LL | let _fail = *reb2; + | ^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.rs:LL:CC + | +LL | let reb2 = unsafe { &mut *wild }; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/cross_tree_update_newer_exposed.rs:LL:CC + | +LL | *ref3 = 13; + | ^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/wildcard/cross_tree_update_older.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older.rs new file mode 100644 index 000000000000..35fbc30ff50b --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older.rs @@ -0,0 +1,47 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks how accesses from one subtree affect other subtrees. +/// This test checks that an access from a newer created subtree +/// performs a wildcard access on all earlier trees. +pub fn main() { + let mut x: u32 = 42; + + let ref_base = &mut x; + + let int0 = ref_base as *mut u32 as usize; + let wild = int0 as *mut u32; + + let reb1 = unsafe { &mut *wild }; + + let reb2 = unsafe { &mut *wild }; + + let ref3 = &mut *reb2; + let _int3 = ref3 as *mut u32 as usize; + // ┌──────────────┐ + // │ │ + // │ptr_base(Res)*│ * * + // │ │ │ │ + // └──────────────┘ │ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ reb1(Res) ├ │ reb2(Res) ├ + // │ │ │ │ + // └────────────┘ └──────┬─────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref3(Res)* │ + // │ │ + // └────────────┘ + + // this access disables reb2 because ref3 cannot be a child of it + // as reb1 does not have any exposed children. + *ref3 = 13; + + let _fail = *reb1; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older.stderr new file mode 100644 index 000000000000..54f041b555cb --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/cross_tree_update_older.rs:LL:CC + | +LL | let _fail = *reb1; + | ^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/cross_tree_update_older.rs:LL:CC + | +LL | let reb1 = unsafe { &mut *wild }; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/cross_tree_update_older.rs:LL:CC + | +LL | *ref3 = 13; + | ^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.rs new file mode 100644 index 000000000000..0f87bb445fcd --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.rs @@ -0,0 +1,53 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks how accesses from one subtree affect other subtrees. +/// This test checks that an access from a newer created subtree +/// performs a wildcard access on all earlier trees, and that +/// either accesses are treated as foreign for tags that are +/// larger than the root of the accessed subtree. +pub fn main() { + let mut x: u32 = 42; + + let ref_base = &mut x; + + let int0 = ref_base as *mut u32 as usize; + let wild = int0 as *mut u32; + + let reb1 = unsafe { &mut *wild }; + + let reb2 = unsafe { &mut *wild }; + + let ref3 = &mut *reb1; + let _int3 = ref3 as *mut u32 as usize; + + let ref4 = &mut *reb2; + let _int4 = ref4 as *mut u32 as usize; + // ┌──────────────┐ + // │ │ + // │ptr_base(Res)*│ * * + // │ │ │ │ + // └──────────────┘ │ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ reb1(Res) ├ │ reb2(Res) ├ + // │ │ │ │ + // └──────┬─────┘ └──────┬─────┘ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ ref3(Res)* │ │ ref4(Res)* │ + // │ │ │ │ + // └────────────┘ └────────────┘ + + // This access disables ref3 and reb1 because ref4 cannot be a child of it + // as reb2 has a smaller tag than ref3. + *ref4 = 13; + + // Fails because ref3 is disabled. + let _fail = *ref3; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.stderr new file mode 100644 index 000000000000..66787ef72f14 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.rs:LL:CC + | +LL | let _fail = *ref3; + | ^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.rs:LL:CC + | +LL | let ref3 = &mut *reb1; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed.rs:LL:CC + | +LL | *ref4 = 13; + | ^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.rs new file mode 100644 index 000000000000..f01ac26dc69c --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.rs @@ -0,0 +1,59 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks how accesses from one subtree affect other subtrees. +/// This test checks that an access from a newer created subtree +/// performs a wildcard access on all earlier trees, and that +/// either accesses are treated as foreign for tags that are +/// larger than the root of the accessed subtree. +/// This tests the special case where these updates get propagated +/// up the tree. +pub fn main() { + let mut x: u32 = 42; + + let ref_base = &mut x; + + let int0 = ref_base as *mut u32 as usize; + let wild = int0 as *mut u32; + + let reb1 = unsafe { &mut *wild }; + + let reb2 = unsafe { &mut *wild }; + + let ref3 = &mut *reb1; + let _int3 = ref3 as *mut u32 as usize; + + let ref4 = &mut *reb2; + let _int4 = ref4 as *mut u32 as usize; + // ┌──────────────┐ + // │ │ + // │ptr_base(Res)*│ * * + // │ │ │ │ + // └──────────────┘ │ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ reb1(Res) ├ │ reb2(Res) ├ + // │ │ │ │ + // └──────┬─────┘ └──────┬─────┘ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ ref3(Res)* │ │ ref4(Res)* │ + // │ │ │ │ + // └────────────┘ └────────────┘ + + // This access disables ref3 and reb1 because ref4 cannot be a child of it + // as reb2 has a smaller tag than ref3. + // + // Because of the update order during a wildcard access (child before parent) + // ref3 gets disabled before we update reb1. So reb1 has no exposed children + // with write access at the time it gets updated so it also gets disabled. + *ref4 = 13; + + // Fails because reb1 is disabled. + let _fail = *reb1; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.stderr new file mode 100644 index 000000000000..644d30cae035 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.rs:LL:CC + | +LL | let _fail = *reb1; + | ^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.rs:LL:CC + | +LL | let reb1 = unsafe { &mut *wild }; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/cross_tree_update_older_invalid_exposed2.rs:LL:CC + | +LL | *ref4 = 13; + | ^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/wildcard/protected_wildcard.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.rs new file mode 100644 index 000000000000..18fe931b9e35 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.rs @@ -0,0 +1,39 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks if we pass a reference derived from a wildcard pointer +/// that it gets correctly protected. +pub fn main() { + let mut x: u32 = 32; + let ref1 = &mut x; + + let ref2 = &mut *ref1; + let int2 = ref2 as *mut u32 as usize; + + let wild = int2 as *mut u32; + let wild_ref = unsafe { &mut *wild }; + + let mut protect = |_arg: &mut u32| { + // _arg is a protected pointer with wildcard parent. + + // ┌────────────┐ + // │ │ + // │ ref1(Res) │ * + // │ │ │ + // └──────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ ref2(Res)* │ │ _arg(Res) │ + // │ │ │ │ + // └────────────┘ └────────────┘ + + // Writes to ref1, causing a foreign write to ref2 and _arg. + // Since _arg is protected this is UB. + *ref1 = 13; //~ ERROR: /write access through .* is forbidden/ + }; + + // We pass a pointer with wildcard provenance to the function. + protect(wild_ref); +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr new file mode 100644 index 000000000000..e257a3511f75 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr @@ -0,0 +1,37 @@ +error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC + | +LL | *ref1 = 13; + | ^^^^^^^^^^ 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 foreign to the protected tag (i.e., it is not a child) + = help: this foreign write access would cause the protected tag (currently Reserved) to become Disabled + = help: protected tags must never be Disabled +help: the accessed tag was created here + --> tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC + | +LL | let mut protect = |_arg: &mut u32| { + | _______________________^ +... | +LL | | *ref1 = 13; +LL | | }; + | |_____^ +help: the protected tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC + | +LL | let mut protect = |_arg: &mut u32| { + | ^^^^ + = note: BACKTRACE (of the first span): + = note: inside closure at tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC +note: inside `main` + --> tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC + | +LL | protect(wild_ref); + | ^^^^^^^^^^^^^^^^^ + +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/tree_borrows/wildcard/strongly_protected_wildcard.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr index de92cf91e3e8..6e115b22feb1 100644 --- a/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden +error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden --> RUSTLIB/alloc/src/boxed.rs:LL:CC | LL | self.1.deallocate(From::from(ptr.cast()), layout); @@ -6,8 +6,13 @@ LL | self.1.deallocate(From::from(ptr.cast()), layout); | = 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 allocation of the accessed tag also contains the strongly protected tag + = help: the allocation of the accessed tag also contains the strongly protected tag = help: the strongly protected tag disallows deallocations +help: the accessed tag was created here + --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC + | +LL | drop(unsafe { Box::from_raw(raw as *mut i32) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: the strongly protected tag was created here, in the initial state Reserved --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC | diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.rs new file mode 100644 index 000000000000..7ce243abcefc --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.rs @@ -0,0 +1,44 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +// Checks if we correctly infer the relatedness of nodes that are +// part of the same wildcard root. +pub fn main() { + let mut x: u32 = 42; + + let ref_base = &mut x; + + let int1 = ref_base as *mut u32 as usize; + let wild = int1 as *mut u32; + + let reb = unsafe { &mut *wild }; + let ptr_reb = reb as *mut u32; + let ref1 = unsafe { &mut *ptr_reb }; + let ref2 = unsafe { &mut *ptr_reb }; + + // ┌──────────────┐ + // │ │ + // │ptr_base(Res)*│ * + // │ │ │ + // └──────────────┘ │ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ reb(Res) ├───────────┐ + // │ │ │ + // └──────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌───────────┐ + // │ │ │ │ + // │ ref1(Res) │ │ ref2(Res) │ + // │ │ │ │ + // └────────────┘ └───────────┘ + + // ref1 is foreign to ref2, so this should disable ref2. + *ref1 = 13; + + let _fail = *ref2; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.stderr new file mode 100644 index 000000000000..4b4f73a73b79 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.rs:LL:CC + | +LL | let _fail = *ref2; + | ^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.rs:LL:CC + | +LL | let ref2 = unsafe { &mut *ptr_reb }; + | ^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/subtree_internal_relatedness.rs:LL:CC + | +LL | *ref1 = 13; + | ^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.rs new file mode 100644 index 000000000000..7b115f788ae6 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.rs @@ -0,0 +1,49 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +// Checks if we correctly infer the relatedness of nodes that are +// part of the same wildcard root during a wildcard access. +pub fn main() { + let mut x: u32 = 42; + + let ref_base = &mut x; + + let int = ref_base as *mut u32 as usize; + let wild = int as *mut u32; + + let reb = unsafe { &mut *wild }; + let ptr_reb = reb as *mut u32; + let ref1 = unsafe { &mut *ptr_reb }; + let _int1 = ref1 as *mut u32 as usize; + let ref2 = unsafe { &mut *ptr_reb }; + + // ┌──────────────┐ + // │ │ + // │ptr_base(Res)*│ * + // │ │ │ + // └──────────────┘ │ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ reb(Res) ├───────────┐ + // │ │ │ + // └──────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌───────────┐ + // │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res) │ + // │ │ │ │ + // └────────────┘ └───────────┘ + + // Writes either through ref1 or ptr_base. + // This disables ref2 as the access is foreign to it in either case. + unsafe { *wild = 13 }; + + // This is fine because the earlier write could have come from ref1. + let _succ = *ref1; + // ref2 is disabled so this fails. + let _fail = *ref2; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.stderr new file mode 100644 index 000000000000..e1a8bebe91c9 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.rs:LL:CC + | +LL | let _fail = *ref2; + | ^^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.rs:LL:CC + | +LL | let ref2 = unsafe { &mut *ptr_reb }; + | ^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/subtree_internal_relatedness_wildcard.rs:LL:CC + | +LL | unsafe { *wild = 13 }; + | ^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/write_to_shr.stderr b/src/tools/miri/tests/fail/tree_borrows/write_to_shr.stderr deleted file mode 100644 index f57b28cbf44c..000000000000 --- a/src/tools/miri/tests/fail/tree_borrows/write_to_shr.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: Undefined Behavior: write access through is forbidden - --> $DIR/write_to_shr.rs:LL:CC - | -LL | *xmut = 31; - | ^^^^^^^^^^ write access through is forbidden - | - = 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: the accessed tag is a child of the conflicting tag - = help: the conflicting tag has state Frozen which forbids child write accesses -help: the accessed tag was created here - --> $DIR/write_to_shr.rs:LL:CC - | -LL | let xmut = unsafe { &mut *(xref as *const u64 as *mut u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: the conflicting tag was created here, in the initial state Frozen - --> $DIR/write_to_shr.rs:LL:CC - | -LL | let xref = unsafe { &*(x as *mut u64) }; - | ^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at $DIR/write_to_shr.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/tree_borrows/wildcard/formatting.rs b/src/tools/miri/tests/pass/tree_borrows/wildcard/formatting.rs new file mode 100644 index 000000000000..1f6b797a3d77 --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/wildcard/formatting.rs @@ -0,0 +1,36 @@ +// We disable the GC for this test because it would change what is printed. +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance -Zmiri-provenance-gc=0 + +#[path = "../../../utils/mod.rs"] +#[macro_use] +mod utils; + +fn main() { + unsafe { + let x = &0u8; + name!(x); + let xa = &*x; + name!(xa); + let xb = &*x; + name!(xb); + let wild = xb as *const u8 as usize as *const u8; + + let y = &*wild; + name!(y); + let ya = &*y; + name!(ya); + let yb = &*y; + name!(yb); + let _int = ya as *const u8 as usize; + + let z = &*wild; + name!(z); + + let u = &*wild; + name!(u); + let ua = &*u; + name!(ua); + let alloc_id = alloc_id!(x); + print_state!(alloc_id); + } +} diff --git a/src/tools/miri/tests/pass/tree_borrows/wildcard/formatting.stderr b/src/tools/miri/tests/pass/tree_borrows/wildcard/formatting.stderr new file mode 100644 index 000000000000..583c84534395 --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/wildcard/formatting.stderr @@ -0,0 +1,17 @@ +────────────────────────────────────────────────── +Warning: this tree is indicative only. Some tags may have been hidden. +0.. 1 +| Act | └─┬── +| Frz | └─┬── +| Frz | ├──── +| Frz | └──── (exposed) +| | +| Frz | *─┬── +| Frz | ├──── (exposed) +| Frz | └──── +| | +| Frz | *──── +| | +| Frz | *─┬── +| Frz | └──── +────────────────────────────────────────────────── diff --git a/src/tools/miri/tests/pass/tree_borrows/wildcard/reborrow.rs b/src/tools/miri/tests/pass/tree_borrows/wildcard/reborrow.rs new file mode 100644 index 000000000000..fbb50d5acd27 --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/wildcard/reborrow.rs @@ -0,0 +1,224 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +pub fn main() { + multiple_exposed_siblings1(); + multiple_exposed_siblings2(); + reborrow3(); + returned_mut_is_usable(); + only_foreign_is_temporary(); +} + +/// Checks that accessing through a reborrowed wildcard doesn't +/// disable any exposed reference. +fn multiple_exposed_siblings1() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + + let ref1 = unsafe { &mut *ptr_base }; + let int1 = ref1 as *mut u32 as usize; + + let ref2 = unsafe { &mut *ptr_base }; + let _int2 = ref2 as *mut u32 as usize; + + let wild = int1 as *mut u32; + + let reb = unsafe { &mut *wild }; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├────────────┐ * + // │ │ │ │ + // └──────┬─────┘ │ │ + // │ │ │ + // │ │ │ + // ▼ ▼ ▼ + // ┌────────────┐ ┌────────────┐ ┌────────────┐ + // │ │ │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res)* │ │ reb(Res) │ + // │ │ │ │ │ │ + // └────────────┘ └────────────┘ └────────────┘ + + // Could either have as a parent ref1 or ref2. + // So we can't disable either of them. + *reb = 13; + + // We can still access either ref1 or ref2. + // Although it is actually UB to access both of them. + assert_eq!(*ref2, 13); + assert_eq!(*ref1, 13); +} + +/// Checks that wildcard accesses do not invalidate any exposed +/// nodes through which the access could have happened. +/// It checks this for the case where some reborrowed wildcard +/// pointers are exposed as well. +fn multiple_exposed_siblings2() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let int = ptr_base as usize; + + let wild = int as *mut u32; + + let reb_ptr = unsafe { &mut *wild } as *mut u32; + + let ref1 = unsafe { &mut *reb_ptr }; + let _int1 = ref1 as *mut u32 as usize; + + let ref2 = unsafe { &mut *reb_ptr }; + let _int2 = ref2 as *mut u32 as usize; + + // ┌────────────┐ + // │ │ + // │ ptr_base* │ * + // │ │ │ + // └────────────┘ │ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ reb ├────────────┐ + // │ │ │ + // └──────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res)* │ + // │ │ │ │ + // └────────────┘ └────────────┘ + + // Writes either through ref1, ref2 or ptr_base, which are all exposed. + // Since we don't know which we do not apply any transitions to any of + // the references. + unsafe { wild.write(13) }; + + // We should be able to access either ref1 or ref2. + // Although it is actually UB to access ref1 and ref2 together. + assert_eq!(*ref2, 13); + assert_eq!(*ref1, 13); +} + +/// Checks that accessing a reborrowed wildcard reference doesn't +/// invalidate other reborrowed wildcard references, if they +/// are also exposed. +fn reborrow3() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let int = ptr_base as usize; + + let wild = int as *mut u32; + + let reb1 = unsafe { &mut *wild }; + let ref2 = &mut *reb1; + let _int = ref2 as *mut u32 as usize; + + let reb3 = unsafe { &mut *wild }; + + // ┌────────────┐ + // │ │ + // │ ptr_base* │ * * + // │ │ │ │ + // └────────────┘ │ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ reb1(Res) | │ reb3(Res) | + // │ │ │ │ + // └──────┬─────┘ └────────────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref2(Res)* │ + // │ │ + // └────────────┘ + + // This is the only valid ordering these accesses can happen in. + + // reb3 could be a child of ref2 so we don't disable ref2, reb1. + *reb3 = 1; + // Disables reb3 as it cannot be an ancestor of ref2. + *ref2 = 2; + // Disables ref2 (and reb3 if it wasn't already). + *reb1 = 3; +} + +/// Analogous to same test in `../tree-borrows.rs` but with returning a +/// reborrowed wildcard reference. +fn returned_mut_is_usable() { + let mut x: u32 = 32; + let ref1 = &mut x; + + let y = protect(ref1); + + fn protect(arg: &mut u32) -> &mut u32 { + // Reborrow `arg` through a wildcard. + let int = arg as *mut u32 as usize; + let wild = int as *mut u32; + let ref2 = unsafe { &mut *wild }; + + // Activate the reference so that it is vulnerable to foreign reads. + *ref2 = 42; + + ref2 + // An implicit read through `arg` is inserted here. + } + + *y = 4; +} + +/// When accessing an allocation through a tag that was created from wildcard reference +/// we treat nodes with a larger tag as if the access could only have been foreign to them. +/// This change in access relatedness should not be visible in later accesses. +fn only_foreign_is_temporary() { + let mut x = 0u32; + let wild = &mut x as *mut u32 as usize as *mut u32; + + let reb1 = unsafe { &mut *wild }; + let reb2 = unsafe { &mut *wild }; + let ref3 = &mut *reb1; + let _int = ref3 as *mut u32 as usize; + + let reb4 = unsafe { &mut *wild }; + + // + // + // * * * + // │ │ │ + // │ │ │ + // │ │ │ + // │ │ │ + // ▼ ▼ ▼ + // ┌────────────┐ ┌────────────┐ ┌────────────┐ + // │ │ │ │ │ │ + // │ reb1(Res) │ │ reb2(Res) │ │ reb4(Res) │ + // │ │ │ │ │ │ + // └──────┬─────┘ └────────────┘ └────────────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref3(Res)* │ + // │ │ + // └────────────┘ + + // Performs a foreign read on ref3 and doesn't update reb1. + // This temporarily treats ref3 as if only foreign accesses are possible to + // it. This is because the accessed tag reb2 has a larger tag than ref3. + let _x = *reb2; + // Should not update ref3, reb1 as we don't know if the access is local or foreign. + // This should stop treating ref3 as only foreign because the accessed tag reb4 + // has a larger tag than ref3. + *reb4 = 32; + // The previous write could have been local to ref3, so this access should still work. + *ref3 = 4; +} diff --git a/src/tools/miri/tests/pass/tree_borrows/wildcard/undetected_ub.rs b/src/tools/miri/tests/pass/tree_borrows/wildcard/undetected_ub.rs index c34fbcb50119..73392543f7d2 100644 --- a/src/tools/miri/tests/pass/tree_borrows/wildcard/undetected_ub.rs +++ b/src/tools/miri/tests/pass/tree_borrows/wildcard/undetected_ub.rs @@ -4,7 +4,7 @@ pub fn main() { uncertain_provenance(); protected_exposed(); - protected_wildcard(); + cross_tree_update_older_invalid_exposed(); } /// Currently, if we do not know for a tag if an access is local or foreign, @@ -101,45 +101,61 @@ pub fn protected_exposed() { } protect(ref1); - // ref2 is disabled, so this read causes UB, but we currently don't protect this. + // ref2 should be disabled, so this read causes UB, but we currently don't detect this. let _fail = *ref2; } -/// Currently, we do not assign protectors to wildcard references. -/// This test has UB because it does a foreign write to a protected reference. -/// However, that reference is a wildcard, so this doesn't get detected. -#[allow(unused_variables)] -pub fn protected_wildcard() { - let mut x: u32 = 32; - let ref1 = &mut x; - let ref2 = &mut *ref1; +/// Checks how accesses from one subtree affect other subtrees. +/// This test shows an example where we don't update a node whose exposed +/// children are greater than `max_local_tag`. +pub fn cross_tree_update_older_invalid_exposed() { + let mut x: [u32; 2] = [42, 43]; - let int = ref2 as *mut u32 as usize; - let wild = int as *mut u32; - let wild_ref = unsafe { &mut *wild }; + let ref_base = &mut x; - let mut protect = |arg: &mut u32| { - // arg is a protected pointer with wildcard provenance. + let int0 = ref_base as *mut u32 as usize; + let wild = int0 as *mut u32; - // ┌────────────┐ - // │ │ - // │ ref1(Res) │ - // │ │ - // └──────┬─────┘ - // │ - // │ - // ▼ - // ┌────────────┐ - // │ │ - // │ ref2(Res)* │ - // │ │ - // └────────────┘ + let reb1 = unsafe { &mut *wild }; + *reb1 = 44; - // Writes to ref1, disabling ref2, i.e. disabling all exposed references. - // Since a wildcard reference is protected, this is UB. But we currently don't detect this. - *ref1 = 13; - }; + // We need this reference to be at a different location, + // so that creating it doesn't freeze reb1. + let reb2 = unsafe { &mut *wild.wrapping_add(1) }; + let reb2_ptr = (reb2 as *mut u32).wrapping_sub(1); - // We pass a pointer with wildcard provenance to the function. - protect(wild_ref); + let ref3 = &mut *reb1; + let _int3 = ref3 as *mut u32 as usize; + + // ┌──────────────┐ + // │ │ + // │ptr_base(Res)*│ * * + // │ │ │ │ + // └──────────────┘ │ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ reb1(Act) │ │ reb2(Res) │ + // │ │ │ │ + // └──────┬─────┘ └────────────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref3(Res)* │ + // │ │ + // └────────────┘ + + // This access doesn't freeze reb1 even though no access could have come from its + // child ref3 (since ref3>reb2). This is because ref3 doesnt get disabled during this + // access. + // + // ref3 doesn't get frozen because it's still reserved. + let _y = unsafe { *reb2_ptr }; + + // reb1 should be frozen so a write should be UB. But we currently don't detect this. + *reb1 = 4; } diff --git a/src/tools/miri/tests/pass/tree_borrows/wildcard/wildcard.rs b/src/tools/miri/tests/pass/tree_borrows/wildcard/wildcard.rs index c406bfe01f62..01385313dc1e 100644 --- a/src/tools/miri/tests/pass/tree_borrows/wildcard/wildcard.rs +++ b/src/tools/miri/tests/pass/tree_borrows/wildcard/wildcard.rs @@ -151,7 +151,6 @@ fn protector_conflicted_release() { /// Analogous to same test in `../tree-borrows.rs` but with a protected wildcard reference. fn returned_mut_is_usable() { - // NOTE: Currently we ignore protectors on wildcard references. fn reborrow(x: &mut u8) -> &mut u8 { let y = &mut *x; // Activate the reference so that it is vulnerable to foreign reads. diff --git a/src/tools/miri/tests/utils/macros.rs b/src/tools/miri/tests/utils/macros.rs index 3f5b9f78ee01..25f40ed994f6 100644 --- a/src/tools/miri/tests/utils/macros.rs +++ b/src/tools/miri/tests/utils/macros.rs @@ -9,7 +9,7 @@ /// The id obtained can be passed directly to `print_state!`. macro_rules! alloc_id { ($ptr:expr) => { - $crate::utils::miri_get_alloc_id($ptr as *const u8 as *const ()) + $crate::utils::miri_get_alloc_id($ptr as *const _ as *const ()) }; } @@ -52,6 +52,6 @@ macro_rules! name { }; ($ptr:expr => $nth_parent:expr, $name:expr) => { let name = $name.as_bytes(); - $crate::utils::miri_pointer_name($ptr as *const u8 as *const (), $nth_parent, name); + $crate::utils::miri_pointer_name($ptr as *const _ as *const (), $nth_parent, name); }; } From 298d13e9d0caacd05d722a902eefa5e495f4db40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 3 Dec 2025 16:22:57 +0100 Subject: [PATCH 0260/3801] Revert "fixup warnings around the compiler" This reverts commit f20175293aa8372766250e56e2570f3c06640e0b. --- clippy_lints/src/manual_non_exhaustive.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/manual_non_exhaustive.rs b/clippy_lints/src/manual_non_exhaustive.rs index 08e7c7593cb2..0d783fde3313 100644 --- a/clippy_lints/src/manual_non_exhaustive.rs +++ b/clippy_lints/src/manual_non_exhaustive.rs @@ -92,8 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id))) .then_some((v.def_id, v.span)) }); - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - if let Ok((id, span)) = Itertools::exactly_one(iter) + if let Ok((id, span)) = iter.exactly_one() && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(..)) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); @@ -105,8 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { .iter() .filter(|field| !cx.effective_visibilities.is_exported(field.def_id)); if fields.len() > 1 - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - && let Ok(field) = Itertools::exactly_one(private_fields) + && let Ok(field) = private_fields.exactly_one() && let TyKind::Tup([]) = field.ty.kind { span_lint_and_then( From 8d70cfecbeee900ca8f7040362dcd3532fb3b895 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 2 Dec 2025 21:18:26 +0100 Subject: [PATCH 0261/3801] Add a section about `rustc_clean` --- .../rustc-dev-guide/src/tests/compiletest.md | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index c2aee82bdd74..a691380234cd 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -187,8 +187,26 @@ still pass. cause an Internal Compiler Error (ICE). This is a highly specialized directive to check that the incremental cache continues to work after an ICE. -[`tests/incremental`]: https://github.com/rust-lang/rust/tree/HEAD/tests/incremental +Incremental tests may use the attribute `#[rustc_clean(...)]` attribute. This attribute compares +the fingerprint from the current compilation session with the previous one. +The first revision should never have an active `rustc_clean` attribute, since it will always be dirty. +In the default mode, it asserts that the fingerprints must be the same. +The attribute takes the following arguments: + +* `cfg=""` — checks the cfg condition ``, and only runs the check if the config condition evaluates to true. + This can be used to only run the `rustc_clean` attribute in a specific revision. +* `except=",,..."` — asserts that the query results for the listed queries must be different, + rather than the same. +* `loaded_from_disk=",,..."` — asserts that the query results for the listed queries + were actually loaded from disk (not just marked green). + This can be useful to ensure that a test is actually exercising the deserialization + logic for a particular query result. This can be combined with `except`. + +A simple example of a test using `rustc_clean` is the [hello_world test]. + +[`tests/incremental`]: https://github.com/rust-lang/rust/tree/7b42543/tests/incremental +[hello_world test]: https://github.com/rust-lang/rust/blob/646a3f8c15baefb98dc6e0c1c1ba3356db702d2a/tests/incremental/hello_world.rs ### Debuginfo tests From 5c467cb4d17359960c4a8c4843977012e828b48f Mon Sep 17 00:00:00 2001 From: Paul Murphy Date: Wed, 3 Dec 2025 11:15:20 -0600 Subject: [PATCH 0262/3801] Allow PowerPC spe_acc as clobber-only register This register is only supported on the *powerpc*spe targets. It is only recognized by LLVM. gcc does not accept this as a clobber, nor does it support these targets. This is a volatile register, thus it is included with clobber_abi. --- src/asm.rs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index f237861b1595..ceb3dd3ffedf 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -209,10 +209,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } ("r", dummy_output_type(self.cx, reg.reg_class())) } else { - // `clobber_abi` can add lots of clobbers that are not supported by the target, - // such as AVX-512 registers, so we just ignore unsupported registers - let is_target_supported = - reg.reg_class().supported_types(asm_arch, true).iter().any( + let is_target_supported = match reg.reg_class() { + // `clobber_abi` clobbers spe_acc on all PowerPC targets. This + // register is unique to the powerpc*spe target, and the target + // is not supported by gcc. Ignore it. + InlineAsmRegClass::PowerPC( + PowerPCInlineAsmRegClass::spe_acc, + ) => false, + // `clobber_abi` can add lots of clobbers that are not supported by the target, + // such as AVX-512 registers, so we just ignore unsupported registers + x => x.supported_types(asm_arch, true).iter().any( |&(_, feature)| { if let Some(feature) = feature { self.tcx @@ -222,7 +228,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { true // Register class is unconditionally supported } }, - ); + ), + }; if is_target_supported && !clobbers.contains(®_name) { clobbers.push(reg_name); @@ -710,7 +717,8 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str { PowerPCInlineAsmRegClass::cr | PowerPCInlineAsmRegClass::ctr | PowerPCInlineAsmRegClass::lr - | PowerPCInlineAsmRegClass::xer, + | PowerPCInlineAsmRegClass::xer + | PowerPCInlineAsmRegClass::spe_acc, ) => { unreachable!("clobber-only") } @@ -793,7 +801,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl PowerPCInlineAsmRegClass::cr | PowerPCInlineAsmRegClass::ctr | PowerPCInlineAsmRegClass::lr - | PowerPCInlineAsmRegClass::xer, + | PowerPCInlineAsmRegClass::xer + | PowerPCInlineAsmRegClass::spe_acc, ) => { unreachable!("clobber-only") } From 00f3a35caa63bf9b698f871174498543152df004 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 1 Dec 2025 18:28:41 +0100 Subject: [PATCH 0263/3801] add a tidy test --- src/tools/tidy/src/alphabetical/tests.rs | 59 ++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/tools/tidy/src/alphabetical/tests.rs b/src/tools/tidy/src/alphabetical/tests.rs index 3e0dd798ab9d..5bfb37a098fc 100644 --- a/src/tools/tidy/src/alphabetical/tests.rs +++ b/src/tools/tidy/src/alphabetical/tests.rs @@ -337,3 +337,62 @@ fn test_numeric_bad() { "; bad(lines, "bad:3: line not in alphabetical order"); } + +#[test] +fn multiline() { + let lines = "\ + tidy-alphabetical-start + (b, + a); + ( + b, + a + ) + tidy-alphabetical-end + "; + good(lines); + + let lines = "\ + tidy-alphabetical-start + ( + b, + a + ) + (b, + a); + tidy-alphabetical-end + "; + good(lines); + + let lines = "\ + tidy-alphabetical-start + (c, + a); + ( + b, + a + ) + tidy-alphabetical-end + "; + bad(lines, "bad:5: line not in alphabetical order"); + + let lines = "\ + tidy-alphabetical-start + ( + c, + a + ) + (b, + a); + tidy-alphabetical-end + "; + bad(lines, "bad:6: line not in alphabetical order"); + + let lines = "\ + force_unwind_tables: Option = (None, parse_opt_bool, [TRACKED], + 'force use of unwind tables'), + incremental: Option = (None, parse_opt_string, [UNTRACKED], + 'enable incremental compilation'), + "; + good(lines); +} From cdc977d6ec8ced80199b562bc5443eba2af5cbaa Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Sat, 16 Aug 2025 14:26:34 +0200 Subject: [PATCH 0264/3801] refactor tidy alphabetical lint This slightly changes alphabetical lint semantics... specifically if an "item" is multiline (when the next line does not have the same indentation) we now consider all lines (ignoring starting whitespace) for ordering, not just the first one. --- src/tools/tidy/src/alphabetical.rs | 315 ++++++++++++++++++++--------- 1 file changed, 220 insertions(+), 95 deletions(-) diff --git a/src/tools/tidy/src/alphabetical.rs b/src/tools/tidy/src/alphabetical.rs index 3845e2269e9b..6a1e777d9f2a 100644 --- a/src/tools/tidy/src/alphabetical.rs +++ b/src/tools/tidy/src/alphabetical.rs @@ -9,19 +9,33 @@ //! // tidy-alphabetical-end //! ``` //! -//! The following lines are ignored: -//! - Empty lines -//! - Lines that are indented with more or less spaces than the first line -//! - Lines starting with `//`, `#` (except those starting with `#!`), `)`, `]`, `}` if the comment -//! has the same indentation as the first line -//! - Lines starting with a closing delimiter (`)`, `[`, `}`) are ignored. +//! Empty lines and lines starting (ignoring spaces) with `//` or `#` (except those starting with +//! `#!`) are considered comments are are sorted together with the next line (but do not affect +//! sorting). //! -//! If a line ends with an opening delimiter, we effectively join the following line to it before -//! checking it. E.g. `foo(\nbar)` is treated like `foo(bar)`. +//! If the following lines have higher indentation we effectively join them with the current line +//! before comparing it. If the next line with the same indentation starts (ignoring spaces) with +//! a closing delimiter (`)`, `[`, `}`) it is joined as well. +//! +//! E.g. +//! +//! ```rust,ignore ilustrative example for sorting mentioning non-existent functions +//! foo(a, +//! b); +//! bar( +//! a, +//! b +//! ); +//! // are treated for sorting purposes as +//! foo(a, b); +//! bar(a, b); +//! ``` use std::cmp::Ordering; -use std::fmt::Display; +use std::fs; +use std::io::{Seek, Write}; use std::iter::Peekable; +use std::ops::{Range, RangeBounds}; use std::path::Path; use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; @@ -38,94 +52,190 @@ fn is_close_bracket(c: char) -> bool { matches!(c, ')' | ']' | '}') } +fn is_empty_or_comment(line: &&str) -> bool { + let trimmed_line = line.trim_start_matches(' ').trim_end_matches('\n'); + + trimmed_line.is_empty() + || trimmed_line.starts_with("//") + || (trimmed_line.starts_with('#') && !trimmed_line.starts_with("#!")) +} + const START_MARKER: &str = "tidy-alphabetical-start"; const END_MARKER: &str = "tidy-alphabetical-end"; -fn check_section<'a>( - file: impl Display, - lines: impl Iterator, - check: &mut RunningCheck, -) { - let mut prev_line = String::new(); - let mut first_indent = None; - let mut in_split_line = None; - - for (idx, line) in lines { - if line.is_empty() { - continue; - } - - if line.contains(START_MARKER) { - check.error(format!( - "{file}:{} found `{START_MARKER}` expecting `{END_MARKER}`", - idx + 1 - )); - return; - } - - if line.contains(END_MARKER) { - return; - } - - let indent = first_indent.unwrap_or_else(|| { - let indent = indentation(line); - first_indent = Some(indent); - indent - }); - - let line = if let Some(prev_split_line) = in_split_line { - // Join the split lines. - in_split_line = None; - format!("{prev_split_line}{}", line.trim_start()) - } else { - line.to_string() - }; - - if indentation(&line) != indent { - continue; - } - - let trimmed_line = line.trim_start_matches(' '); - - if trimmed_line.starts_with("//") - || (trimmed_line.starts_with('#') && !trimmed_line.starts_with("#!")) - || trimmed_line.starts_with(is_close_bracket) - { - continue; - } - - if line.trim_end().ends_with('(') { - in_split_line = Some(line); - continue; - } - - let prev_line_trimmed_lowercase = prev_line.trim_start_matches(' '); - - if version_sort(trimmed_line, prev_line_trimmed_lowercase).is_lt() { - check.error(format!("{file}:{}: line not in alphabetical order", idx + 1)); - } - - prev_line = line; +/// Given contents of a section that is enclosed between [`START_MARKER`] and [`END_MARKER`], sorts +/// them according to the rules described at the top of the module. +fn sort_section(section: &str) -> String { + /// A sortable item + struct Item { + /// Full contents including comments and whitespace + full: String, + /// Trimmed contents for sorting + trimmed: String, } - check.error(format!("{file}: reached end of file expecting `{END_MARKER}`")); -} + let mut items = Vec::new(); + let mut lines = section.split_inclusive('\n').peekable(); -fn check_lines<'a>( - file: &impl Display, - mut lines: impl Iterator, - check: &mut RunningCheck, -) { - while let Some((idx, line)) = lines.next() { - if line.contains(END_MARKER) { - check.error(format!( - "{file}:{} found `{END_MARKER}` expecting `{START_MARKER}`", - idx + 1 - )); + let end_comments = loop { + let mut full = String::new(); + let mut trimmed = String::new(); + + while let Some(comment) = lines.next_if(is_empty_or_comment) { + full.push_str(comment); } - if line.contains(START_MARKER) { - check_section(file, &mut lines, check); + let Some(line) = lines.next() else { + // remember comments at the end of a block + break full; + }; + + let mut push = |line| { + full.push_str(line); + trimmed.push_str(line.trim_start_matches(' ').trim_end_matches('\n')) + }; + + push(line); + + let indent = indentation(line); + let mut multiline = false; + + // If the item is split between multiple lines... + while let Some(more_indented) = + lines.next_if(|&line: &&_| indent < indentation(line) || line == "\n") + { + multiline = true; + push(more_indented); + } + + if multiline + && let Some(indented) = + // Only append next indented line if it looks like a closing bracket. + // Otherwise we incorrectly merge code like this (can be seen in + // compiler/rustc_session/src/options.rs): + // + // force_unwind_tables: Option = (None, parse_opt_bool, [TRACKED], + // "force use of unwind tables"), + // incremental: Option = (None, parse_opt_string, [UNTRACKED], + // "enable incremental compilation"), + lines.next_if(|l| { + indentation(l) == indent + && l.trim_start_matches(' ').starts_with(is_close_bracket) + }) + { + push(indented); + } + + items.push(Item { full, trimmed }); + }; + + items.sort_by(|a, b| version_sort(&a.trimmed, &b.trimmed)); + items.into_iter().map(|l| l.full).chain([end_comments]).collect() +} + +fn check_lines<'a>(path: &Path, content: &'a str, tidy_ctx: &TidyCtx, check: &mut RunningCheck) { + let mut offset = 0; + + loop { + let rest = &content[offset..]; + let start = rest.find(START_MARKER); + let end = rest.find(END_MARKER); + + match (start, end) { + // error handling + + // end before start + (Some(start), Some(end)) if end < start => { + check.error(format!( + "{path}:{line_number} found `{END_MARKER}` expecting `{START_MARKER}`", + path = path.display(), + line_number = content[..offset + end].lines().count(), + )); + break; + } + + // end without a start + (None, Some(end)) => { + check.error(format!( + "{path}:{line_number} found `{END_MARKER}` expecting `{START_MARKER}`", + path = path.display(), + line_number = content[..offset + end].lines().count(), + )); + break; + } + + // start without an end + (Some(start), None) => { + check.error(format!( + "{path}:{line_number} `{START_MARKER}` without a matching `{END_MARKER}`", + path = path.display(), + line_number = content[..offset + start].lines().count(), + )); + break; + } + + // a second start in between start/end pair + (Some(start), Some(end)) + if rest[start + START_MARKER.len()..end].contains(START_MARKER) => + { + check.error(format!( + "{path}:{line_number} found `{START_MARKER}` expecting `{END_MARKER}`", + path = path.display(), + line_number = content[..offset + + sub_find(rest, start + START_MARKER.len()..end, START_MARKER) + .unwrap() + .start] + .lines() + .count() + )); + break; + } + + // happy happy path :3 + (Some(start), Some(end)) => { + assert!(start <= end); + + // "...␤// tidy-alphabetical-start␤...␤// tidy-alphabetical-end␤..." + // start_nl_end --^ ^-- end_nl_start ^-- end_nl_end + + // Position after the newline after start marker + let start_nl_end = sub_find(rest, start + START_MARKER.len().., "\n").unwrap().end; + + // Position before the new line before the end marker + let end_nl_start = rest[..end].rfind('\n').unwrap(); + + // Position after the newline after end marker + let end_nl_end = sub_find(rest, end + END_MARKER.len().., "\n") + .map(|r| r.end) + .unwrap_or(content.len() - offset); + + let section = &rest[start_nl_end..=end_nl_start]; + let sorted = sort_section(section); + + // oh nyooo :( + if sorted != section { + let base_line_number = content[..offset + start_nl_end].lines().count(); + let line_offset = sorted + .lines() + .zip(section.lines()) + .enumerate() + .find(|(_, (a, b))| a != b) + .unwrap() + .0; + let line_number = base_line_number + line_offset; + + check.error(format!( + "{path}:{line_number}: line not in alphabetical order (tip: use --bless to sort this list)", + path = path.display(), + )); + } + + // Start the next search after the end section + offset += end_nl_end; + } + + // No more alphabetical lists, yay :3 + (None, None) => break, } } } @@ -133,13 +243,14 @@ fn check_lines<'a>( pub fn check(path: &Path, tidy_ctx: TidyCtx) { let mut check = tidy_ctx.start_check(CheckId::new("alphabetical").path(path)); - let skip = - |path: &_, _is_dir| filter_dirs(path) || path.ends_with("tidy/src/alphabetical/tests.rs"); + let skip = |path: &_, _is_dir| { + filter_dirs(path) + || path.ends_with("tidy/src/alphabetical.rs") + || path.ends_with("tidy/src/alphabetical/tests.rs") + }; - walk(path, skip, &mut |entry, contents| { - let file = &entry.path().display(); - let lines = contents.lines().enumerate(); - check_lines(file, lines, &mut check) + walk(path, skip, &mut |entry, content| { + check_lines(entry.path(), content, &tidy_ctx, &mut check) }); } @@ -195,3 +306,17 @@ fn version_sort(a: &str, b: &str) -> Ordering { it1.next().cmp(&it2.next()) } + +/// Finds `pat` in `s[range]` and returns a range such that `s[ret] == pat`. +fn sub_find(s: &str, range: impl RangeBounds, pat: &str) -> Option> { + s[(range.start_bound().cloned(), range.end_bound().cloned())] + .find(pat) + .map(|pos| { + pos + match range.start_bound().cloned() { + std::ops::Bound::Included(x) => x, + std::ops::Bound::Excluded(x) => x + 1, + std::ops::Bound::Unbounded => 0, + } + }) + .map(|pos| pos..pos + pat.len()) +} From 4e9c504cbff017030b4df356f619c1ad2a50154c Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Sat, 16 Aug 2025 14:26:34 +0200 Subject: [PATCH 0265/3801] implement tidy bless for alphabetical blocks --- Cargo.lock | 1 + src/tools/tidy/Cargo.toml | 1 + src/tools/tidy/src/alphabetical.rs | 42 +++++++++++++++++++++--------- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2cc2e094e9f9..46de7c331258 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5615,6 +5615,7 @@ dependencies = [ "semver", "serde", "similar", + "tempfile", "termcolor", "toml 0.7.8", "walkdir", diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index c1f27de7ed4a..47b59543c59c 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -18,6 +18,7 @@ rustc-hash = "2.0.0" fluent-syntax = "0.12" similar = "2.5.0" toml = "0.7.8" +tempfile = "3.15.0" [features] build-metrics = ["dep:serde"] diff --git a/src/tools/tidy/src/alphabetical.rs b/src/tools/tidy/src/alphabetical.rs index 6a1e777d9f2a..4ef1775d4bed 100644 --- a/src/tools/tidy/src/alphabetical.rs +++ b/src/tools/tidy/src/alphabetical.rs @@ -214,20 +214,36 @@ fn check_lines<'a>(path: &Path, content: &'a str, tidy_ctx: &TidyCtx, check: &mu // oh nyooo :( if sorted != section { - let base_line_number = content[..offset + start_nl_end].lines().count(); - let line_offset = sorted - .lines() - .zip(section.lines()) - .enumerate() - .find(|(_, (a, b))| a != b) - .unwrap() - .0; - let line_number = base_line_number + line_offset; + if !tidy_ctx.is_bless_enabled() { + let base_line_number = content[..offset + start_nl_end].lines().count(); + let line_offset = sorted + .lines() + .zip(section.lines()) + .enumerate() + .find(|(_, (a, b))| a != b) + .unwrap() + .0; + let line_number = base_line_number + line_offset; - check.error(format!( - "{path}:{line_number}: line not in alphabetical order (tip: use --bless to sort this list)", - path = path.display(), - )); + check.error(format!( + "{path}:{line_number}: line not in alphabetical order (tip: use --bless to sort this list)", + path = path.display(), + )); + } else { + // Use atomic rename as to not corrupt the file upon crashes/ctrl+c + let mut tempfile = + tempfile::Builder::new().tempfile_in(path.parent().unwrap()).unwrap(); + + fs::copy(path, tempfile.path()).unwrap(); + + tempfile + .as_file_mut() + .seek(std::io::SeekFrom::Start((offset + start_nl_end) as u64)) + .unwrap(); + tempfile.as_file_mut().write_all(sorted.as_bytes()).unwrap(); + + tempfile.persist(path).unwrap(); + } } // Start the next search after the end section From 53f64405a86cc5e5fe63c27bb24734548045a71a Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Sat, 16 Aug 2025 14:26:34 +0200 Subject: [PATCH 0266/3801] bless tidy tests --- src/tools/tidy/src/alphabetical/tests.rs | 34 ++++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/tools/tidy/src/alphabetical/tests.rs b/src/tools/tidy/src/alphabetical/tests.rs index 5bfb37a098fc..6a756a84cf99 100644 --- a/src/tools/tidy/src/alphabetical/tests.rs +++ b/src/tools/tidy/src/alphabetical/tests.rs @@ -7,7 +7,7 @@ use crate::diagnostics::{TidyCtx, TidyFlags}; fn test(lines: &str, name: &str, expected_msg: &str, expected_bad: bool) { let tidy_ctx = TidyCtx::new(Path::new("/"), false, TidyFlags::default()); let mut check = tidy_ctx.start_check("alphabetical-test"); - check_lines(&name, lines.lines().enumerate(), &mut check); + check_lines(Path::new(name), lines, &tidy_ctx, &mut check); assert_eq!(expected_bad, check.is_bad()); let errors = check.get_errors(); @@ -95,7 +95,7 @@ fn test_rust_bad() { def // tidy-alphabetical-end "; - bad(lines, "bad:4: line not in alphabetical order"); + bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -107,7 +107,7 @@ fn test_toml_bad() { def # tidy-alphabetical-end "; - bad(lines, "bad:4: line not in alphabetical order"); + bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -121,7 +121,7 @@ fn test_features_bad() { #![feature(def)] tidy-alphabetical-end "; - bad(lines, "bad:4: line not in alphabetical order"); + bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -134,7 +134,7 @@ fn test_indent_bad() { def $ tidy-alphabetical-end "; - bad(lines, "bad:4: line not in alphabetical order"); + bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -150,7 +150,7 @@ fn test_split_bad() { ) && tidy-alphabetical-end "; - bad(lines, "bad:7: line not in alphabetical order"); + bad(lines, "bad:3: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -160,7 +160,7 @@ fn test_double_start() { abc tidy-alphabetical-start "; - bad(lines, "bad:3 found `tidy-alphabetical-start` expecting `tidy-alphabetical-end`"); + bad(lines, "bad:0 `tidy-alphabetical-start` without a matching `tidy-alphabetical-end`"); } #[test] @@ -179,7 +179,7 @@ fn test_missing_end() { tidy-alphabetical-start abc "; - bad(lines, "bad: reached end of file expecting `tidy-alphabetical-end`"); + bad(lines, "bad:0 `tidy-alphabetical-start` without a matching `tidy-alphabetical-end`"); } #[test] @@ -319,7 +319,7 @@ fn test_numeric_bad() { item2 # tidy-alphabetical-end "; - bad(lines, "bad:4: line not in alphabetical order"); + bad(lines, "bad:2: line not in alphabetical order (tip: use --bless to sort this list)"); let lines = "\ # tidy-alphabetical-start @@ -327,7 +327,7 @@ fn test_numeric_bad() { zve64d # tidy-alphabetical-end "; - bad(lines, "bad:3: line not in alphabetical order"); + bad(lines, "bad:1: line not in alphabetical order (tip: use --bless to sort this list)"); let lines = "\ # tidy-alphabetical-start @@ -335,7 +335,7 @@ fn test_numeric_bad() { 00 # tidy-alphabetical-end "; - bad(lines, "bad:3: line not in alphabetical order"); + bad(lines, "bad:1: line not in alphabetical order (tip: use --bless to sort this list)"); } #[test] @@ -347,7 +347,7 @@ fn multiline() { ( b, a - ) + ); tidy-alphabetical-end "; good(lines); @@ -357,7 +357,7 @@ fn multiline() { ( b, a - ) + ); (b, a); tidy-alphabetical-end @@ -371,22 +371,22 @@ fn multiline() { ( b, a - ) + ); tidy-alphabetical-end "; - bad(lines, "bad:5: line not in alphabetical order"); + bad(lines, "bad:1: line not in alphabetical order (tip: use --bless to sort this list)"); let lines = "\ tidy-alphabetical-start ( c, a - ) + ); (b, a); tidy-alphabetical-end "; - bad(lines, "bad:6: line not in alphabetical order"); + bad(lines, "bad:1: line not in alphabetical order (tip: use --bless to sort this list)"); let lines = "\ force_unwind_tables: Option = (None, parse_opt_bool, [TRACKED], From d318d3d6562b5b88d5bcbdf3cde5d015a7541b8d Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 1 Dec 2025 17:28:58 +0100 Subject: [PATCH 0267/3801] drive-by: tidy: fixup style --- src/tools/tidy/src/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/diagnostics.rs b/src/tools/tidy/src/diagnostics.rs index 159500751aa5..88816b5abeff 100644 --- a/src/tools/tidy/src/diagnostics.rs +++ b/src/tools/tidy/src/diagnostics.rs @@ -6,10 +6,10 @@ use std::sync::{Arc, Mutex}; use termcolor::Color; +/// CLI flags used by tidy. #[derive(Clone, Default)] -///CLI flags used by tidy. pub struct TidyFlags { - ///Applies style and formatting changes during a tidy run. + /// Applies style and formatting changes during a tidy run. bless: bool, } From ed1b831906b5ff3c00ee0372811cb801baaa15e0 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 18 Aug 2025 17:42:43 +0200 Subject: [PATCH 0268/3801] bless tidy --- compiler/rustc_type_ir/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index c1e301961267..8065db1e05dd 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -4,11 +4,11 @@ #![allow(rustc::usage_of_ty_tykind)] #![allow(rustc::usage_of_type_ir_inherent)] #![allow(rustc::usage_of_type_ir_traits)] +#![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr( feature = "nightly", feature(associated_type_defaults, never_type, rustc_attrs, negative_impls) )] -#![cfg_attr(feature = "nightly", allow(internal_features))] // tidy-alphabetical-end extern crate self as rustc_type_ir; From 29f31f16621f2402d92918896bf3b77d9e2a2683 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Tue, 2 Dec 2025 16:53:12 -0500 Subject: [PATCH 0269/3801] rustdoc: Add unstable `--merge-doctests=yes/no/auto` flag This is useful for changing the *default* for whether doctests are merged or not. Currently, that default is solely controlled by `edition = 2024`, which adds a high switching cost to get doctest merging. This flag allows opt-ing in even on earlier additions. Unlike the `edition = 2024` default, `--merge-doctests=yes` gives a hard error if merging fails instead of falling back to running standalone tests. The user has explicitly said they want merging, so we shouldn't silently do something else. `--merge-doctests=auto` is equivalent to the current 2024 edition behavior, but available on earlier editions. --- src/librustdoc/config.rs | 31 ++++++++++++++++ src/librustdoc/doctest.rs | 34 +++++++++++------ src/librustdoc/doctest/make.rs | 37 ++++++++++++------- src/librustdoc/doctest/markdown.rs | 4 +- src/librustdoc/lib.rs | 10 ++++- .../output-default.stdout | 4 ++ tests/rustdoc-ui/doctest/force-merge-fail.rs | 18 +++++++++ .../doctest/force-merge-fail.stderr | 6 +++ tests/rustdoc-ui/doctest/force-merge.rs | 25 +++++++++++++ tests/rustdoc-ui/doctest/force-merge.stdout | 8 ++++ tests/rustdoc-ui/doctest/force-no-merge.rs | 24 ++++++++++++ .../rustdoc-ui/doctest/force-no-merge.stdout | 7 ++++ .../rustdoc-ui/doctest/merge-doctests-auto.rs | 28 ++++++++++++++ .../doctest/merge-doctests-auto.stdout | 8 ++++ .../doctest/merge-doctests-invalid.rs | 2 + .../doctest/merge-doctests-invalid.stderr | 2 + .../doctest/merge-doctests-unstable.rs | 2 + .../doctest/merge-doctests-unstable.stderr | 2 + 18 files changed, 224 insertions(+), 28 deletions(-) create mode 100644 tests/rustdoc-ui/doctest/force-merge-fail.rs create mode 100644 tests/rustdoc-ui/doctest/force-merge-fail.stderr create mode 100644 tests/rustdoc-ui/doctest/force-merge.rs create mode 100644 tests/rustdoc-ui/doctest/force-merge.stdout create mode 100644 tests/rustdoc-ui/doctest/force-no-merge.rs create mode 100644 tests/rustdoc-ui/doctest/force-no-merge.stdout create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-auto.rs create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-auto.stdout create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-invalid.rs create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-unstable.rs create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 5d16dff24c69..e5a4593260a4 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -63,6 +63,15 @@ pub(crate) enum InputMode { HasFile(Input), } +/// Whether to run multiple doctests in the same binary. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] +pub(crate) enum MergeDoctests { + #[default] + Never, + Always, + Auto, +} + /// Configuration options for rustdoc. #[derive(Clone)] pub(crate) struct Options { @@ -121,6 +130,8 @@ pub(crate) struct Options { /// Optional path to persist the doctest executables to, defaults to a /// temporary directory if not set. pub(crate) persist_doctests: Option, + /// Whether to merge + pub(crate) merge_doctests: MergeDoctests, /// Runtool to run doctests with pub(crate) test_runtool: Option, /// Arguments to pass to the runtool @@ -801,6 +812,8 @@ impl Options { Ok(result) => result, Err(e) => dcx.fatal(format!("--merge option error: {e}")), }; + let merge_doctests = parse_merge_doctests(matches, edition, dcx); + tracing::debug!("merge_doctests: {merge_doctests:?}"); if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) { dcx.struct_warn( @@ -852,6 +865,7 @@ impl Options { crate_version, test_run_directory, persist_doctests, + merge_doctests, test_runtool, test_runtool_args, test_builder, @@ -1048,3 +1062,20 @@ fn parse_merge(m: &getopts::Matches) -> Result { Some(_) => Err("argument to --merge must be `none`, `shared`, or `finalize`"), } } + +fn parse_merge_doctests( + m: &getopts::Matches, + edition: Edition, + dcx: DiagCtxtHandle<'_>, +) -> MergeDoctests { + match m.opt_str("merge-doctests").as_deref() { + Some("y") | Some("yes") | Some("on") | Some("true") => MergeDoctests::Always, + Some("n") | Some("no") | Some("off") | Some("false") => MergeDoctests::Never, + Some("auto") => MergeDoctests::Auto, + None if edition < Edition::Edition2024 => MergeDoctests::Never, + None => MergeDoctests::Auto, + Some(_) => { + dcx.fatal("argument to --merge-doctests must be a boolean (true/false) or 'auto'") + } + } +} diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 481aa392007c..cab65181c940 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -33,7 +33,7 @@ use tempfile::{Builder as TempFileBuilder, TempDir}; use tracing::debug; use self::rust::HirCollector; -use crate::config::{Options as RustdocOptions, OutputFormat}; +use crate::config::{MergeDoctests, Options as RustdocOptions, OutputFormat}; use crate::html::markdown::{ErrorCodes, Ignore, LangString, MdRelLine}; use crate::lint::init_lints; @@ -265,6 +265,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions }; run_tests( + dcx, opts, &rustdoc_options, &unused_extern_reports, @@ -316,6 +317,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions } pub(crate) fn run_tests( + dcx: DiagCtxtHandle<'_>, opts: GlobalTestOptions, rustdoc_options: &Arc, unused_extern_reports: &Arc>>, @@ -368,6 +370,13 @@ pub(crate) fn run_tests( } continue; } + + if rustdoc_options.merge_doctests == MergeDoctests::Always { + let mut diag = dcx.struct_fatal("failed to merge doctests"); + diag.note("requested explicitly on the command line with `--merge-doctests=yes`"); + diag.emit(); + } + // We failed to compile all compatible tests as one so we push them into the // `standalone_tests` doctests. debug!("Failed to compile compatible doctests for edition {} all at once", edition); @@ -645,9 +654,9 @@ fn run_test( // tested as standalone tests. return (Duration::default(), Err(TestFailure::CompileError)); } - if !rustdoc_options.no_capture { - // If `no_capture` is disabled, then we don't display rustc's output when compiling - // the merged doctests. + if !rustdoc_options.no_capture && rustdoc_options.merge_doctests == MergeDoctests::Auto { + // If `no_capture` is disabled, and we might fallback to standalone tests, then we don't + // display rustc's output when compiling the merged doctests. compiler.stderr(Stdio::null()); } // bundled tests are an rlib, loaded by a separate runner executable @@ -728,10 +737,12 @@ fn run_test( // tested as standalone tests. return (instant.elapsed(), Err(TestFailure::CompileError)); } - if !rustdoc_options.no_capture { - // If `no_capture` is disabled, then we don't display rustc's output when compiling - // the merged doctests. + if !rustdoc_options.no_capture && rustdoc_options.merge_doctests == MergeDoctests::Auto { + // If `no_capture` is disabled and we're autodetecting whether to merge, + // we don't display rustc's output when compiling the merged doctests. runner_compiler.stderr(Stdio::null()); + } else { + runner_compiler.stderr(Stdio::inherit()); } runner_compiler.arg("--error-format=short"); debug!("compiler invocation for doctest runner: {runner_compiler:?}"); @@ -888,7 +899,7 @@ impl IndividualTestOptions { DirState::Perm(path) } else { - DirState::Temp(get_doctest_dir().expect("rustdoc needs a tempdir")) + DirState::Temp(get_doctest_dir(options).expect("rustdoc needs a tempdir")) }; Self { outdir, path: test_path } @@ -977,21 +988,20 @@ struct CreateRunnableDocTests { visited_tests: FxHashMap<(String, usize), usize>, unused_extern_reports: Arc>>, compiling_test_count: AtomicUsize, - can_merge_doctests: bool, + can_merge_doctests: MergeDoctests, } impl CreateRunnableDocTests { fn new(rustdoc_options: RustdocOptions, opts: GlobalTestOptions) -> CreateRunnableDocTests { - let can_merge_doctests = rustdoc_options.edition >= Edition::Edition2024; CreateRunnableDocTests { standalone_tests: Vec::new(), mergeable_tests: FxIndexMap::default(), - rustdoc_options: Arc::new(rustdoc_options), opts, visited_tests: FxHashMap::default(), unused_extern_reports: Default::default(), compiling_test_count: AtomicUsize::new(0), - can_merge_doctests, + can_merge_doctests: rustdoc_options.merge_doctests, + rustdoc_options: Arc::new(rustdoc_options), } } diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index e9f5024e494d..1f5956168d7e 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -20,6 +20,7 @@ use rustc_span::{DUMMY_SP, FileName, Span, kw}; use tracing::debug; use super::GlobalTestOptions; +use crate::config::MergeDoctests; use crate::display::Joined as _; use crate::html::markdown::LangString; @@ -41,7 +42,7 @@ pub(crate) struct BuildDocTestBuilder<'a> { source: &'a str, crate_name: Option<&'a str>, edition: Edition, - can_merge_doctests: bool, + can_merge_doctests: MergeDoctests, // If `test_id` is `None`, it means we're generating code for a code example "run" link. test_id: Option, lang_str: Option<&'a LangString>, @@ -55,7 +56,7 @@ impl<'a> BuildDocTestBuilder<'a> { source, crate_name: None, edition: DEFAULT_EDITION, - can_merge_doctests: false, + can_merge_doctests: MergeDoctests::Never, test_id: None, lang_str: None, span: DUMMY_SP, @@ -70,7 +71,7 @@ impl<'a> BuildDocTestBuilder<'a> { } #[inline] - pub(crate) fn can_merge_doctests(mut self, can_merge_doctests: bool) -> Self { + pub(crate) fn can_merge_doctests(mut self, can_merge_doctests: MergeDoctests) -> Self { self.can_merge_doctests = can_merge_doctests; self } @@ -117,10 +118,6 @@ impl<'a> BuildDocTestBuilder<'a> { span, global_crate_attrs, } = self; - let can_merge_doctests = can_merge_doctests - && lang_str.is_some_and(|lang_str| { - !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate - }); let result = rustc_driver::catch_fatal_errors(|| { rustc_span::create_session_if_not_set_then(edition, |_| { @@ -155,14 +152,26 @@ impl<'a> BuildDocTestBuilder<'a> { debug!("crate_attrs:\n{crate_attrs}{maybe_crate_attrs}"); debug!("crates:\n{crates}"); debug!("after:\n{everything_else}"); + debug!("merge-doctests: {can_merge_doctests:?}"); - // If it contains `#[feature]` or `#[no_std]`, we don't want it to be merged either. - let can_be_merged = can_merge_doctests - && !has_global_allocator - && crate_attrs.is_empty() - // If this is a merged doctest and a defined macro uses `$crate`, then the path will - // not work, so better not put it into merged doctests. - && !(has_macro_def && everything_else.contains("$crate")); + // Up until now, we've been dealing with settings for the whole crate. + // Now, infer settings for this particular test. + let can_be_merged = if can_merge_doctests == MergeDoctests::Auto { + let mut can_merge = false; + // Avoid tests with incompatible attributes. + can_merge |= lang_str.is_some_and(|lang_str| { + !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate + }); + // If it contains `#[feature]` or `#[no_std]`, we don't want it to be merged either. + can_merge &= !has_global_allocator + && crate_attrs.is_empty() + // If this is a merged doctest and a defined macro uses `$crate`, then the path will + // not work, so better not put it into merged doctests. + && !(has_macro_def && everything_else.contains("$crate")); + can_merge + } else { + can_merge_doctests != MergeDoctests::Never + }; DocTestBuilder { supports_color, has_main_fn, diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs index 7f26605f2562..45f1e8a7fb98 100644 --- a/src/librustdoc/doctest/markdown.rs +++ b/src/librustdoc/doctest/markdown.rs @@ -3,6 +3,7 @@ use std::fs::read_to_string; use std::sync::{Arc, Mutex}; +use rustc_errors::DiagCtxtHandle; use rustc_session::config::Input; use rustc_span::{DUMMY_SP, FileName}; use tempfile::tempdir; @@ -78,7 +79,7 @@ impl DocTestVisitor for MdCollector { } /// Runs any tests/code examples in the markdown file `options.input`. -pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> { +pub(crate) fn test(input: &Input, options: Options, dcx: DiagCtxtHandle<'_>) -> Result<(), String> { let input_str = match input { Input::File(path) => { read_to_string(path).map_err(|err| format!("{}: {err}", path.display()))? @@ -118,6 +119,7 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> { let CreateRunnableDocTests { opts, rustdoc_options, standalone_tests, mergeable_tests, .. } = collector; crate::doctest::run_tests( + dcx, opts, &rustdoc_options, &Arc::new(Mutex::new(Vec::new())), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e4601bfb20d7..be46c85311a0 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -544,6 +544,14 @@ fn opts() -> Vec { "[toolchain-shared-resources,invocation-specific,dep-info]", ), opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""), + opt( + Unstable, + Opt, + "", + "merge-doctests", + "Force all doctests to be compiled as a single binary, instead of one binary per test. If merging fails, rustdoc will emit a hard error.", + "yes|no|auto", + ), opt( Unstable, Multi, @@ -822,7 +830,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { options.should_test || output_format == config::OutputFormat::Doctest, config::markdown_input(&input), ) { - (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)), + (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options, dcx)), (true, None) => return doctest::run(dcx, input, options), (false, Some(md_input)) => { let md_input = md_input.to_owned(); diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index 49eaf7e2e1e0..4e28be347cbb 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -154,6 +154,10 @@ Options: Comma separated list of types of output for rustdoc to emit --no-run Compile doctests without running them + --merge-doctests yes|no|auto + Force all doctests to be compiled as a single binary, + instead of one binary per test. If merging fails, + rustdoc will emit a hard error. --remap-path-prefix FROM=TO Remap source names in compiler messages --show-type-layout diff --git a/tests/rustdoc-ui/doctest/force-merge-fail.rs b/tests/rustdoc-ui/doctest/force-merge-fail.rs new file mode 100644 index 000000000000..88c36268d072 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-fail.rs @@ -0,0 +1,18 @@ +//@ edition: 2018 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stderr: ".*doctest_bundle_2018.rs:\d+:\d+" -> "doctest_bundle_2018.rs:$$LINE:$$COL" + +//~? ERROR failed to merge doctests + +/// These two doctests will fail to force-merge, and should give a hard error as a result. +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name() -> u8; } +/// ``` +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name(); } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge-fail.stderr b/tests/rustdoc-ui/doctest/force-merge-fail.stderr new file mode 100644 index 000000000000..b87807dc5ed7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-fail.stderr @@ -0,0 +1,6 @@ +doctest_bundle_2018.rs:$LINE:$COL: error: `unmangled_name` redeclared with a different signature: this signature doesn't match the previous declaration +error: aborting due to 1 previous error +error: failed to merge doctests + | + = note: requested explicitly on the command line with `--merge-doctests=yes` + diff --git a/tests/rustdoc-ui/doctest/force-merge.rs b/tests/rustdoc-ui/doctest/force-merge.rs new file mode 100644 index 000000000000..bd2f474f8a56 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ edition: 2018 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this contains a +// "merged compilation took ..." message. + +/// ``` +/// let x = 12; +/// ``` +/// +/// These two doctests should be force-merged, even though this uses edition 2018. +/// +/// ``` +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge.stdout b/tests/rustdoc-ui/doctest/force-merge.stdout new file mode 100644 index 000000000000..94c7909ae0a6 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge.stdout @@ -0,0 +1,8 @@ + +running 2 tests +test $DIR/force-merge.rs - Foo (line 14) ... ok +test $DIR/force-merge.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + +all doctests ran in $TIME; merged doctests compilation took $TIME diff --git a/tests/rustdoc-ui/doctest/force-no-merge.rs b/tests/rustdoc-ui/doctest/force-no-merge.rs new file mode 100644 index 000000000000..9ddea5fc2e55 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-no-merge.rs @@ -0,0 +1,24 @@ +//@ edition: 2024 +//@ check-pass +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=no -Z unstable-options +//@ normalize-stderr: ".*doctest_bundle_2018.rs:\d+:\d+" -> "doctest_bundle_2018.rs:$$LINE:$$COL" + +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +/// These two doctests should not force-merge, even though this crate has edition 2024 and the +/// individual doctests are not annotated. +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name() -> u8; } +/// ``` +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name(); } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-no-merge.stdout b/tests/rustdoc-ui/doctest/force-no-merge.stdout new file mode 100644 index 000000000000..513ff7705497 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-no-merge.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/force-no-merge.rs - Foo (line 15) ... ok +test $DIR/force-no-merge.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/merge-doctests-auto.rs b/tests/rustdoc-ui/doctest/merge-doctests-auto.rs new file mode 100644 index 000000000000..2e7d0db7a346 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-auto.rs @@ -0,0 +1,28 @@ +//! `--merge-doctests=auto` should override the edition. + +//@ check-pass +//@ edition: 2018 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=auto -Z unstable-options + +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this contains a +// "merged compilation took ..." message. + +/// ``` +/// let x = 12; +/// ``` +/// +/// These two doctests should be auto-merged, even though this uses edition 2018. +/// +/// ``` +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/merge-doctests-auto.stdout b/tests/rustdoc-ui/doctest/merge-doctests-auto.stdout new file mode 100644 index 000000000000..a051ffd60636 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-auto.stdout @@ -0,0 +1,8 @@ + +running 2 tests +test $DIR/merge-doctests-auto.rs - Foo (line 17) ... ok +test $DIR/merge-doctests-auto.rs - Foo (line 23) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + +all doctests ran in $TIME; merged doctests compilation took $TIME diff --git a/tests/rustdoc-ui/doctest/merge-doctests-invalid.rs b/tests/rustdoc-ui/doctest/merge-doctests-invalid.rs new file mode 100644 index 000000000000..cf3a03a901ce --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-invalid.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --merge-doctests=bad-opt -Zunstable-options +//~? ERROR must be a boolean diff --git a/tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr b/tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr new file mode 100644 index 000000000000..d232c1b59edb --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr @@ -0,0 +1,2 @@ +error: argument to --merge-doctests must be a boolean (true/false) or 'auto' + diff --git a/tests/rustdoc-ui/doctest/merge-doctests-unstable.rs b/tests/rustdoc-ui/doctest/merge-doctests-unstable.rs new file mode 100644 index 000000000000..496e531659a3 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-unstable.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --merge-doctests=no +//~? RAW `-Z unstable-options` flag must also be passed diff --git a/tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr b/tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr new file mode 100644 index 000000000000..e8d75342bc8e --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr @@ -0,0 +1,2 @@ +error: the `-Z unstable-options` flag must also be passed to enable the flag `merge-doctests` + From 3aa4ece95d6ad46ced3ea895fcc634371ff32039 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Wed, 3 Dec 2025 15:48:16 -0500 Subject: [PATCH 0270/3801] Support `-C save-temps` in rustdoc This allows viewing failed merged doctests. --- src/librustdoc/doctest.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index cab65181c940..6e0025fe7064 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -123,8 +123,13 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> Ok(()) } -fn get_doctest_dir() -> io::Result { - TempFileBuilder::new().prefix("rustdoctest").tempdir() +fn get_doctest_dir(opts: &RustdocOptions) -> io::Result { + let mut builder = TempFileBuilder::new(); + builder.prefix("rustdoctest"); + if opts.codegen_options.save_temps { + builder.disable_cleanup(true); + } + builder.tempdir() } pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions) { @@ -197,7 +202,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let externs = options.externs.clone(); let json_unused_externs = options.json_unused_externs; - let temp_dir = match get_doctest_dir() + let temp_dir = match get_doctest_dir(&options) .map_err(|error| format!("failed to create temporary directory: {error:?}")) { Ok(temp_dir) => temp_dir, @@ -207,6 +212,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions crate::wrap_return(dcx, generate_args_file(&args_path, &options)); let extract_doctests = options.output_format == OutputFormat::Doctest; + let save_temps = options.codegen_options.save_temps; let result = interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); @@ -259,7 +265,9 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions eprintln!("{error}"); // Since some files in the temporary folder are still owned and alive, we need // to manually remove the folder. - let _ = std::fs::remove_dir_all(temp_dir.path()); + if !save_temps { + let _ = std::fs::remove_dir_all(temp_dir.path()); + } std::process::exit(1); } }; From 4122a226c8550f5e60eb3194e7afa1cf059c24e1 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 3 Dec 2025 22:58:55 +0100 Subject: [PATCH 0271/3801] Do not look for disallowed methods inside desugared code --- clippy_lints/src/disallowed_methods.rs | 3 +++ .../ui-toml/toml_disallowed_methods/clippy.toml | 2 ++ .../conf_disallowed_methods.rs | 16 ++++++++++++++++ .../conf_disallowed_methods.stderr | 8 +++++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/disallowed_methods.rs b/clippy_lints/src/disallowed_methods.rs index 8c067432cb4e..58403ad19235 100644 --- a/clippy_lints/src/disallowed_methods.rs +++ b/clippy_lints/src/disallowed_methods.rs @@ -88,6 +88,9 @@ impl_lint_pass!(DisallowedMethods => [DISALLOWED_METHODS]); impl<'tcx> LateLintPass<'tcx> for DisallowedMethods { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if expr.span.desugaring_kind().is_some() { + return; + } let (id, span) = match &expr.kind { ExprKind::Path(path) if let Res::Def(_, id) = cx.qpath_res(path, expr.hir_id) => (id, expr.span), ExprKind::MethodCall(name, ..) if let Some(id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => { diff --git a/tests/ui-toml/toml_disallowed_methods/clippy.toml b/tests/ui-toml/toml_disallowed_methods/clippy.toml index c7a326f28295..2c54b73d72d7 100644 --- a/tests/ui-toml/toml_disallowed_methods/clippy.toml +++ b/tests/ui-toml/toml_disallowed_methods/clippy.toml @@ -17,4 +17,6 @@ disallowed-methods = [ # re-exports "conf_disallowed_methods::identity", "conf_disallowed_methods::renamed", + # also used in desugaring + "std::future::Future::poll", ] diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs index 2dac01649a0f..621317246d6d 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs @@ -80,3 +80,19 @@ fn main() { renamed(1); //~^ disallowed_methods } + +mod issue16185 { + use std::pin::Pin; + use std::task::Context; + + async fn test(f: impl Future) { + // Should not lint even though desugaring uses + // disallowed method `std::future::Future::poll()`. + f.await + } + + fn explicit>(f: Pin<&mut F>, cx: &mut Context<'_>) { + f.poll(cx); + //~^ disallowed_methods + } +} diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr index 20474ad6e927..8e7e112a93f3 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr @@ -99,5 +99,11 @@ error: use of a disallowed method `conf_disallowed_methods::renamed` LL | renamed(1); | ^^^^^^^ -error: aborting due to 16 previous errors +error: use of a disallowed method `std::future::Future::poll` + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:95:11 + | +LL | f.poll(cx); + | ^^^^ + +error: aborting due to 17 previous errors From 680a336fe53ee10ae28b6b9cd9c0669c6d5ca0f6 Mon Sep 17 00:00:00 2001 From: Alejandra Gonzalez Date: Wed, 3 Dec 2025 23:17:39 +0100 Subject: [PATCH 0272/3801] Remove myself from rotation Turns out that I'm still in burnout, the two RFCs that I'm working on, the Rust-For-Linux support, some conferences, my blog, I got a new job that is also quite time consuming. I don't have the time to do reviews right now, I'm sorry to everyone on the team. I'll try to scale down as much as possible and then I'll come back to rotation. r? ghost --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 3bf62b6b3bba..6633b87f04e8 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -65,6 +65,7 @@ users_on_vacation = [ "Manishearth", "Alexendoo", "y21", + "blyxyas", ] [assign.owners] @@ -77,7 +78,6 @@ users_on_vacation = [ "@Alexendoo", "@dswij", "@Jarcho", - "@blyxyas", "@y21", "@samueltardieu", ] From 415953a317f04b0b5ad26b1ded3671a3e2a01532 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Wed, 3 Dec 2025 17:40:10 -0500 Subject: [PATCH 0273/3801] `--merge-doctests` is a default, not an override --- src/librustdoc/doctest/make.rs | 23 +++++++++-------- .../force-merge-default-not-override.rs | 25 +++++++++++++++++++ .../force-merge-default-not-override.stdout | 7 ++++++ 3 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 tests/rustdoc-ui/doctest/force-merge-default-not-override.rs create mode 100644 tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 1f5956168d7e..569206d6ec88 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -156,21 +156,22 @@ impl<'a> BuildDocTestBuilder<'a> { // Up until now, we've been dealing with settings for the whole crate. // Now, infer settings for this particular test. + // + // Avoid tests with incompatible attributes. + let opt_out = lang_str.is_some_and(|lang_str| { + lang_str.compile_fail || lang_str.test_harness || lang_str.standalone_crate + }); let can_be_merged = if can_merge_doctests == MergeDoctests::Auto { - let mut can_merge = false; - // Avoid tests with incompatible attributes. - can_merge |= lang_str.is_some_and(|lang_str| { - !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate - }); - // If it contains `#[feature]` or `#[no_std]`, we don't want it to be merged either. - can_merge &= !has_global_allocator - && crate_attrs.is_empty() + // We try to look at the contents of the test to detect whether it should be merged. + // This is not a complete list of possible failures, but it catches many cases. + let will_probably_fail = has_global_allocator + || !crate_attrs.is_empty() // If this is a merged doctest and a defined macro uses `$crate`, then the path will // not work, so better not put it into merged doctests. - && !(has_macro_def && everything_else.contains("$crate")); - can_merge + || (has_macro_def && everything_else.contains("$crate")); + !opt_out && !will_probably_fail } else { - can_merge_doctests != MergeDoctests::Never + can_merge_doctests != MergeDoctests::Never && !opt_out }; DocTestBuilder { supports_color, diff --git a/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs b/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs new file mode 100644 index 000000000000..9a1e86ade67f --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ edition: 2024 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this doesn't contains a +// "merged compilation took ..." message. + +/// ```standalone_crate +/// let x = 12; +/// ``` +/// +/// These two doctests should be not be merged, even though this passes `--merge-doctests=yes`. +/// +/// ```standalone_crate +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout b/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout new file mode 100644 index 000000000000..24b16ec82f45 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/force-merge-default-not-override.rs - Foo (line 14) ... ok +test $DIR/force-merge-default-not-override.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From f04ad994d5e47173c4afc25bacf5fa4ed3bd7078 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 3 Dec 2025 23:44:38 +0100 Subject: [PATCH 0274/3801] rust-analyzer settings: use --compile-time-deps --- src/tools/miri/etc/rust_analyzer_helix.toml | 2 ++ src/tools/miri/etc/rust_analyzer_vscode.json | 2 ++ src/tools/miri/etc/rust_analyzer_zed.json | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/tools/miri/etc/rust_analyzer_helix.toml b/src/tools/miri/etc/rust_analyzer_helix.toml index c46b246049ff..dd222c50431a 100644 --- a/src/tools/miri/etc/rust_analyzer_helix.toml +++ b/src/tools/miri/etc/rust_analyzer_helix.toml @@ -28,5 +28,7 @@ overrideCommand = [ "./miri", "check", "--no-default-features", + "-Zunstable-options", + "--compile-time-deps", "--message-format=json", ] diff --git a/src/tools/miri/etc/rust_analyzer_vscode.json b/src/tools/miri/etc/rust_analyzer_vscode.json index 8e647f5331f0..97ba212f8ef9 100644 --- a/src/tools/miri/etc/rust_analyzer_vscode.json +++ b/src/tools/miri/etc/rust_analyzer_vscode.json @@ -22,6 +22,8 @@ "./miri", "check", "--no-default-features", + "-Zunstable-options", + "--compile-time-deps", "--message-format=json", ], } diff --git a/src/tools/miri/etc/rust_analyzer_zed.json b/src/tools/miri/etc/rust_analyzer_zed.json index 839914c8b68e..7f60a931c46f 100644 --- a/src/tools/miri/etc/rust_analyzer_zed.json +++ b/src/tools/miri/etc/rust_analyzer_zed.json @@ -31,6 +31,8 @@ "./miri", "check", "--no-default-features", + "-Zunstable-options", + "--compile-time-deps", "--message-format=json" ] } From 0030e8ab1864d53d98de1e90ab3cf999b62ddcf1 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 4 Aug 2025 21:55:18 -0400 Subject: [PATCH 0275/3801] compiler-builtins: Change gating for outline atomic symbols Build outline atomic symbols on all targets that have `outline-atomics` enabled, rather than only on Linux. Since this is no longer OS-specific, also rename the module. --- .../src/{aarch64_linux.rs => aarch64_outline_atomics.rs} | 8 ++++---- library/compiler-builtins/compiler-builtins/src/lib.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) rename library/compiler-builtins/compiler-builtins/src/{aarch64_linux.rs => aarch64_outline_atomics.rs} (97%) diff --git a/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs b/library/compiler-builtins/compiler-builtins/src/aarch64_outline_atomics.rs similarity index 97% rename from library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs rename to library/compiler-builtins/compiler-builtins/src/aarch64_outline_atomics.rs index 01d7fb473291..df0cf7650222 100644 --- a/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs +++ b/library/compiler-builtins/compiler-builtins/src/aarch64_outline_atomics.rs @@ -196,7 +196,7 @@ macro_rules! compare_and_swap { "cbnz w17, 0b", "1:", "ret", - have_lse = sym crate::aarch64_linux::HAVE_LSE_ATOMICS, + have_lse = sym crate::aarch64_outline_atomics::HAVE_LSE_ATOMICS, } } } @@ -228,7 +228,7 @@ macro_rules! compare_and_swap_i128 { "cbnz w15, 0b", "1:", "ret", - have_lse = sym crate::aarch64_linux::HAVE_LSE_ATOMICS, + have_lse = sym crate::aarch64_outline_atomics::HAVE_LSE_ATOMICS, } } } @@ -256,7 +256,7 @@ macro_rules! swap { concat!(stxr!($ordering, $bytes), " w17, ", reg!($bytes, 16), ", [x1]"), "cbnz w17, 0b", "ret", - have_lse = sym crate::aarch64_linux::HAVE_LSE_ATOMICS, + have_lse = sym crate::aarch64_outline_atomics::HAVE_LSE_ATOMICS, } } } @@ -286,7 +286,7 @@ macro_rules! fetch_op { concat!(stxr!($ordering, $bytes), " w15, ", reg!($bytes, 17), ", [x1]"), "cbnz w15, 0b", "ret", - have_lse = sym crate::aarch64_linux::HAVE_LSE_ATOMICS, + have_lse = sym crate::aarch64_outline_atomics::HAVE_LSE_ATOMICS, } } } diff --git a/library/compiler-builtins/compiler-builtins/src/lib.rs b/library/compiler-builtins/compiler-builtins/src/lib.rs index a9dd6e531c5d..c993209699be 100644 --- a/library/compiler-builtins/compiler-builtins/src/lib.rs +++ b/library/compiler-builtins/compiler-builtins/src/lib.rs @@ -55,8 +55,8 @@ pub mod arm; #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] pub mod aarch64; -#[cfg(all(target_arch = "aarch64", target_os = "linux"))] -pub mod aarch64_linux; +#[cfg(all(target_arch = "aarch64", target_feature = "outline-atomics"))] +pub mod aarch64_outline_atomics; #[cfg(all( kernel_user_helpers, From 2105a2579b22a45fcaa8f4037dffc084c7cd0764 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 4 Aug 2025 21:55:18 -0400 Subject: [PATCH 0276/3801] Make the `RUST_LSE_INIT` constructor cross-platform Change the gating and link sections to enable this for any platforms that enable `outline-atomics`, rather than only Linux. Additionally, no longer run this if LSE is available, since in this case the outline versions will never be called. --- library/std/src/sys/configure_builtins.rs | 46 ++++++++++++++++++++--- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/configure_builtins.rs b/library/std/src/sys/configure_builtins.rs index 9d776b778dcb..f569ec0f5129 100644 --- a/library/std/src/sys/configure_builtins.rs +++ b/library/std/src/sys/configure_builtins.rs @@ -1,13 +1,49 @@ -/// Hook into .init_array to enable LSE atomic operations at startup, if -/// supported. -#[cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "compiler-builtins-c")))] +/// Enable LSE atomic operations at startup, if supported. +/// +/// Linker sections are based on what [`ctor`] does, with priorities to run slightly before user +/// code: +/// +/// - Apple uses the section `__mod_init_func`, `mod_init_funcs` is needed to set +/// `S_MOD_INIT_FUNC_POINTERS`. There doesn't seem to be a way to indicate priorities. +/// - Windows uses `.CRT$XCT`, which is run before user constructors (these should use `.CRT$XCU`). +/// - ELF uses `.init_array` with a priority of 90, which runs before our `ARGV_INIT_ARRAY` +/// initializer (priority 99). Both are within the 0-100 implementation-reserved range, per docs +/// for the [`prio-ctor-dtor`] warning, and this matches compiler-rt's `CONSTRUCTOR_PRIORITY`. +/// +/// To save startup time, the initializer is only run if outline atomic routines from +/// compiler-builtins may be used. If LSE is known to be available then the calls are never +/// emitted, and if we build the C intrinsics then it has its own initializer using the symbol +/// `__aarch64_have_lse_atomics`. +/// +/// Initialization is done in a global constructor to so we get the same behavior regardless of +/// whether Rust's `init` is used, or if we are in a `dylib` or `no_main` situation (as opposed +/// to doing it as part of pre-main startup). This also matches C implementations. +/// +/// Ideally `core` would have something similar, but detecting the CPU features requires the +/// auxiliary vector from the OS. We do the initialization in `std` rather than as part of +/// `compiler-builtins` because a builtins->std dependency isn't possible, and inlining parts of +/// `std-detect` would be much messier. +/// +/// [`ctor`]: https://github.com/mmastrac/rust-ctor/blob/63382b833ddcbfb8b064f4e86bfa1ed4026ff356/shared/src/macros/mod.rs#L522-L534 +/// [`prio-ctor-dtor`]: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html +#[cfg(all( + target_arch = "aarch64", + target_feature = "outline-atomics", + not(target_feature = "lse"), + not(feature = "compiler-builtins-c"), +))] #[used] -#[unsafe(link_section = ".init_array.90")] +#[cfg_attr(target_vendor = "apple", unsafe(link_section = "__DATA,__mod_init_func,mod_init_funcs"))] +#[cfg_attr(target_os = "windows", unsafe(link_section = ".CRT$XCT"))] +#[cfg_attr( + not(any(target_vendor = "apple", target_os = "windows")), + unsafe(link_section = ".init_array.90") +)] static RUST_LSE_INIT: extern "C" fn() = { extern "C" fn init_lse() { use crate::arch; - // This is provided by compiler-builtins::aarch64_linux. + // This is provided by compiler-builtins::aarch64_outline_atomics. unsafe extern "C" { fn __rust_enable_lse(); } From 1ed1b6e2674e0884479042ae1b6aac431f1c217c Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 5 Sep 2025 15:20:59 -0400 Subject: [PATCH 0277/3801] Enable `outline-atomics` by default on AArch64 Windows platforms Windows has a similar flag `/forceInterlockedFunctions`, which uses names such as `_InterlockedAdd64_rel`. --- .../rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs | 2 +- .../rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs index ce17280b153d..db3cf83ddc99 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs @@ -3,7 +3,7 @@ use crate::spec::{Arch, Cc, FramePointer, LinkerFlavor, Lld, Target, TargetMetad pub(crate) fn target() -> Target { let mut base = base::windows_gnullvm::opts(); base.max_atomic_width = Some(128); - base.features = "+v8a,+neon".into(); + base.features = "+v8a,+neon,+outline-atomics".into(); base.linker = Some("aarch64-w64-mingw32-clang".into()); base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "arm64pe"]); diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs index 0d06bec21f4a..e9f7f51a7a35 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs @@ -3,7 +3,7 @@ use crate::spec::{Arch, FramePointer, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); base.max_atomic_width = Some(128); - base.features = "+v8a,+neon".into(); + base.features = "+v8a,+neon,+outline-atomics".into(); // Microsoft recommends enabling frame pointers on Arm64 Windows. // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers From c45590397843909a1f36d4fd9d89cfc1e7551652 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 5 Sep 2025 15:23:00 -0400 Subject: [PATCH 0278/3801] Enable `outline-atomics` by default on AArch64 Android Per LLVM commit c5e7e649d537 ("[AArch64][Clang][Linux] Enable out-of-line atomics by default.") [1], Clang enables these on Android. Thus, do the same in Rust. [1]: https://github.com/llvm/llvm-project/commit/c5e7e649d537067de --- compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs index 3b158c13521e..d1810b6fa486 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { max_atomic_width: Some(128), // As documented in https://developer.android.com/ndk/guides/cpu-features.html // the neon (ASIMD) and FP must exist on all android aarch64 targets. - features: "+v8a,+neon".into(), + features: "+v8a,+neon,+outline-atomics".into(), // the AAPCS64 expects use of non-leaf frame pointers per // https://github.com/ARM-software/abi-aa/blob/4492d1570eb70c8fd146623e0db65b2d241f12e7/aapcs64/aapcs64.rst#the-frame-pointer // and we tend to encounter interesting bugs in AArch64 unwinding code if we do not From 21525f862d621bbeb9a131f3631111c402e1a447 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 5 Sep 2025 15:34:47 -0400 Subject: [PATCH 0279/3801] Enable `outline-atomics` by default on AArch64 Fuchsia Clang has done this by default since LLVM commit 1a963d3278c2 ("[Driver] Make -moutline-atomics default for aarch64-fuchsia targets"), [1], so do the same here. [1]: https://github.com/llvm/llvm-project/commit/1a963d3278c2daab7e12125371442cd129c09954 --- .../rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs index 6489e2bda809..8a07f98075a8 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs @@ -5,7 +5,7 @@ use crate::spec::{ pub(crate) fn target() -> Target { let mut base = base::fuchsia::opts(); base.cpu = "generic".into(); - base.features = "+v8a,+crc,+aes,+sha2,+neon".into(); + base.features = "+v8a,+crc,+aes,+sha2,+neon,+outline-atomics".into(); base.max_atomic_width = Some(128); base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS From 66c150c1fa29d15e1c5c06dfe708c8443faf42c3 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 5 Sep 2025 15:34:57 -0400 Subject: [PATCH 0280/3801] Enable `outline-atomics` by default on AArch64 OpenBSD Clang has recently started doing this, as of LLVM commit 5d774ec8d183 ("[Driver] Enable outline atomics for OpenBSD/aarch64") [1]. Thus, do the same here. [1]: https://github.com/llvm/llvm-project/commit/5d774ec8d183cbbb243c57f50d891822211d3ec2 --- .../rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs index e5e40cb38b91..14a2f007f1e8 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - features: "+v8a".into(), + features: "+v8a,+outline-atomics".into(), max_atomic_width: Some(128), stack_probes: StackProbeType::Inline, ..base::openbsd::opts() From f7b3c1d3c05c683ea22aca5db0726036786745ba Mon Sep 17 00:00:00 2001 From: beetrees Date: Fri, 4 Jul 2025 17:44:15 +0100 Subject: [PATCH 0281/3801] Rework `c_variadic` --- .../rustc_codegen_ssa/src/traits/intrinsic.rs | 4 +- library/core/src/ffi/mod.rs | 2 +- library/core/src/ffi/va_list.rs | 183 ++++--------- library/core/src/intrinsics/mod.rs | 8 +- library/std/src/ffi/mod.rs | 2 +- .../src/directives/directive_names.rs | 1 + tests/auxiliary/rust_test_helpers.c | 4 + tests/codegen-llvm/cffi/c-variadic-copy.rs | 4 +- tests/codegen-llvm/cffi/c-variadic-opt.rs | 8 +- tests/codegen-llvm/cffi/c-variadic.rs | 12 +- .../c-link-to-rust-va-list-fn/checkrust.rs | 15 +- tests/ui/abi/variadic-ffi.rs | 32 ++- .../pass-by-value-abi.aarch64.stderr | 80 ++++++ tests/ui/c-variadic/pass-by-value-abi.rs | 46 ++++ .../c-variadic/pass-by-value-abi.win.stderr | 83 ++++++ .../pass-by-value-abi.x86_64.stderr | 240 ++++++++++++++++++ tests/ui/c-variadic/variadic-ffi-4.rs | 19 +- tests/ui/c-variadic/variadic-ffi-4.stderr | 121 ++------- .../macro-dotdotdot-may-not-begin-a-type.rs | 2 +- .../variadic-ffi-semantic-restrictions.rs | 6 +- .../variadic-ffi-semantic-restrictions.stderr | 6 +- tests/ui/thir-print/c-variadic.stdout | 4 +- 22 files changed, 591 insertions(+), 291 deletions(-) create mode 100644 tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr create mode 100644 tests/ui/c-variadic/pass-by-value-abi.rs create mode 100644 tests/ui/c-variadic/pass-by-value-abi.win.stderr create mode 100644 tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index c5ecf43046c7..187e4b90656a 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -36,10 +36,10 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { vtable_byte_offset: u64, typeid: Self::Metadata, ) -> Self::Value; - /// Trait method used to inject `va_start` on the "spoofed" `VaListImpl` in + /// Trait method used to inject `va_start` on the "spoofed" `VaList` in /// Rust defined C-variadic functions. fn va_start(&mut self, val: Self::Value) -> Self::Value; - /// Trait method used to inject `va_end` on the "spoofed" `VaListImpl` before + /// Trait method used to inject `va_end` on the "spoofed" `VaList` before /// Rust defined C-variadic functions return. fn va_end(&mut self, val: Self::Value) -> Self::Value; } diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 1356ca217c9a..f1b928da7ef3 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -28,7 +28,7 @@ pub mod c_str; issue = "44930", reason = "the `c_variadic` feature has not been properly tested on all supported platforms" )] -pub use self::va_list::{VaArgSafe, VaList, VaListImpl}; +pub use self::va_list::{VaArgSafe, VaList}; #[unstable( feature = "c_variadic", diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index 233a2ee3e484..449e62ac00d3 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -4,15 +4,15 @@ #[cfg(not(target_arch = "xtensa"))] use crate::ffi::c_void; -#[allow(unused_imports)] use crate::fmt; -use crate::intrinsics::{va_arg, va_copy, va_end}; -use crate::marker::{PhantomData, PhantomInvariantLifetime}; -use crate::ops::{Deref, DerefMut}; +use crate::intrinsics::{va_arg, va_copy}; +use crate::marker::PhantomCovariantLifetime; -// The name is WIP, using `VaListImpl` for now. -// // Most targets explicitly specify the layout of `va_list`, this layout is matched here. +// For `va_list`s which are single-element array in C (and therefore experience array-to-pointer +// decay when passed as arguments in C), the `VaList` struct is annotated with +// `#[rustc_pass_indirectly_in_non_rustic_abis]`. This ensures that the compiler uses the correct +// ABI for functions like `extern "C" fn takes_va_list(va: VaList<'_>)` by passing `va` indirectly. crate::cfg_select! { all( target_arch = "aarch64", @@ -27,66 +27,60 @@ crate::cfg_select! { /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf #[repr(C)] #[derive(Debug)] - #[lang = "va_list"] - pub struct VaListImpl<'f> { - stack: *mut c_void, - gr_top: *mut c_void, - vr_top: *mut c_void, + struct VaListInner { + stack: *const c_void, + gr_top: *const c_void, + vr_top: *const c_void, gr_offs: i32, vr_offs: i32, - _marker: PhantomInvariantLifetime<'f>, } } all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)) => { /// PowerPC ABI implementation of a `va_list`. #[repr(C)] #[derive(Debug)] - #[lang = "va_list"] - pub struct VaListImpl<'f> { + #[rustc_pass_indirectly_in_non_rustic_abis] + struct VaListInner { gpr: u8, fpr: u8, reserved: u16, - overflow_arg_area: *mut c_void, - reg_save_area: *mut c_void, - _marker: PhantomInvariantLifetime<'f>, + overflow_arg_area: *const c_void, + reg_save_area: *const c_void, } } target_arch = "s390x" => { /// s390x ABI implementation of a `va_list`. #[repr(C)] #[derive(Debug)] - #[lang = "va_list"] - pub struct VaListImpl<'f> { + #[rustc_pass_indirectly_in_non_rustic_abis] + struct VaListInner { gpr: i64, fpr: i64, - overflow_arg_area: *mut c_void, - reg_save_area: *mut c_void, - _marker: PhantomInvariantLifetime<'f>, + overflow_arg_area: *const c_void, + reg_save_area: *const c_void, } } all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)) => { /// x86_64 ABI implementation of a `va_list`. #[repr(C)] #[derive(Debug)] - #[lang = "va_list"] - pub struct VaListImpl<'f> { + #[rustc_pass_indirectly_in_non_rustic_abis] + struct VaListInner { gp_offset: i32, fp_offset: i32, - overflow_arg_area: *mut c_void, - reg_save_area: *mut c_void, - _marker: PhantomInvariantLifetime<'f>, + overflow_arg_area: *const c_void, + reg_save_area: *const c_void, } } target_arch = "xtensa" => { /// Xtensa ABI implementation of a `va_list`. #[repr(C)] #[derive(Debug)] - #[lang = "va_list"] - pub struct VaListImpl<'f> { - stk: *mut i32, - reg: *mut i32, + #[rustc_pass_indirectly_in_non_rustic_abis] + struct VaListInner { + stk: *const i32, + reg: *const i32, ndx: i32, - _marker: PhantomInvariantLifetime<'f>, } } @@ -95,94 +89,32 @@ crate::cfg_select! { // - apple aarch64 (see https://github.com/rust-lang/rust/pull/56599) // - windows // - uefi - // - any other target for which we don't specify the `VaListImpl` above + // - any other target for which we don't specify the `VaListInner` above // // In this implementation the `va_list` type is just an alias for an opaque pointer. // That pointer is probably just the next variadic argument on the caller's stack. _ => { /// Basic implementation of a `va_list`. #[repr(transparent)] - #[lang = "va_list"] - pub struct VaListImpl<'f> { - ptr: *mut c_void, - - // Invariant over `'f`, so each `VaListImpl<'f>` object is tied to - // the region of the function it's defined in - _marker: PhantomInvariantLifetime<'f>, - } - - impl<'f> fmt::Debug for VaListImpl<'f> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "va_list* {:p}", self.ptr) - } - } - } -} - -crate::cfg_select! { - all( - any( - target_arch = "aarch64", - target_arch = "powerpc", - target_arch = "s390x", - target_arch = "x86_64" - ), - not(target_arch = "xtensa"), - any(not(target_arch = "aarch64"), not(target_vendor = "apple")), - not(target_family = "wasm"), - not(target_os = "uefi"), - not(windows), - ) => { - /// A wrapper for a `va_list` - #[repr(transparent)] #[derive(Debug)] - pub struct VaList<'a, 'f: 'a> { - inner: &'a mut VaListImpl<'f>, - _marker: PhantomData<&'a mut VaListImpl<'f>>, - } - - - impl<'f> VaListImpl<'f> { - /// Converts a [`VaListImpl`] into a [`VaList`] that is binary-compatible with C's `va_list`. - #[inline] - pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> { - VaList { inner: self, _marker: PhantomData } - } - } - } - - _ => { - /// A wrapper for a `va_list` - #[repr(transparent)] - #[derive(Debug)] - pub struct VaList<'a, 'f: 'a> { - inner: VaListImpl<'f>, - _marker: PhantomData<&'a mut VaListImpl<'f>>, - } - - impl<'f> VaListImpl<'f> { - /// Converts a [`VaListImpl`] into a [`VaList`] that is binary-compatible with C's `va_list`. - #[inline] - pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> { - VaList { inner: VaListImpl { ..*self }, _marker: PhantomData } - } + struct VaListInner { + ptr: *const c_void, } } } -impl<'a, 'f: 'a> Deref for VaList<'a, 'f> { - type Target = VaListImpl<'f>; - - #[inline] - fn deref(&self) -> &VaListImpl<'f> { - &self.inner - } +/// A variable argument list, equivalent to `va_list` in C. +#[repr(transparent)] +#[lang = "va_list"] +pub struct VaList<'a> { + inner: VaListInner, + _marker: PhantomCovariantLifetime<'a>, } -impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> { - #[inline] - fn deref_mut(&mut self) -> &mut VaListImpl<'f> { - &mut self.inner +impl fmt::Debug for VaList<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // No need to include `_marker` in debug output. + f.debug_tuple("VaList").field(&self.inner).finish() } } @@ -203,7 +135,7 @@ mod sealed { impl Sealed for *const T {} } -/// Types that are valid to read using [`VaListImpl::arg`]. +/// Types that are valid to read using [`VaList::arg`]. /// /// # Safety /// @@ -238,7 +170,7 @@ unsafe impl VaArgSafe for f64 {} unsafe impl VaArgSafe for *mut T {} unsafe impl VaArgSafe for *const T {} -impl<'f> VaListImpl<'f> { +impl<'f> VaList<'f> { /// Advance to and read the next variable argument. /// /// # Safety @@ -258,27 +190,13 @@ impl<'f> VaListImpl<'f> { // SAFETY: the caller must uphold the safety contract for `va_arg`. unsafe { va_arg(self) } } - - /// Copies the `va_list` at the current location. - pub unsafe fn with_copy(&self, f: F) -> R - where - F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R, - { - let mut ap = self.clone(); - let ret = f(ap.as_va_list()); - // SAFETY: the caller must uphold the safety contract for `va_end`. - unsafe { - va_end(&mut ap); - } - ret - } } -impl<'f> Clone for VaListImpl<'f> { +impl<'f> Clone for VaList<'f> { #[inline] fn clone(&self) -> Self { let mut dest = crate::mem::MaybeUninit::uninit(); - // SAFETY: we write to the `MaybeUninit`, thus it is initialized and `assume_init` is legal + // SAFETY: we write to the `MaybeUninit`, thus it is initialized and `assume_init` is legal. unsafe { va_copy(dest.as_mut_ptr(), self); dest.assume_init() @@ -286,18 +204,11 @@ impl<'f> Clone for VaListImpl<'f> { } } -impl<'f> Drop for VaListImpl<'f> { +impl<'f> Drop for VaList<'f> { fn drop(&mut self) { - // FIXME: this should call `va_end`, but there's no clean way to - // guarantee that `drop` always gets inlined into its caller, - // so the `va_end` would get directly called from the same function as - // the corresponding `va_copy`. `man va_end` states that C requires this, - // and LLVM basically follows the C semantics, so we need to make sure - // that `va_end` is always called from the same function as `va_copy`. - // For more details, see https://github.com/rust-lang/rust/pull/59625 - // and https://llvm.org/docs/LangRef.html#llvm-va-end-intrinsic. - // - // This works for now, since `va_end` is a no-op on all current LLVM targets. + // Rust requires that not calling `va_end` on a `va_list` does not cause undefined behaviour + // (as it is safe to leak values). As `va_end` is a no-op on all current LLVM targets, this + // destructor is empty. } } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 2115c5c9a85d..7571f4a1fc12 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -54,7 +54,7 @@ )] #![allow(missing_docs)] -use crate::ffi::va_list::{VaArgSafe, VaListImpl}; +use crate::ffi::va_list::{VaArgSafe, VaList}; use crate::marker::{ConstParamTy, Destruct, DiscriminantKind, PointeeSized, Tuple}; use crate::{mem, ptr}; @@ -3447,7 +3447,7 @@ pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize /// #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>); +pub unsafe fn va_copy<'f>(dest: *mut VaList<'f>, src: &VaList<'f>); /// Loads an argument of type `T` from the `va_list` `ap` and increment the /// argument `ap` points to. @@ -3465,7 +3465,7 @@ pub unsafe fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>); /// #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn va_arg(ap: &mut VaListImpl<'_>) -> T; +pub unsafe fn va_arg(ap: &mut VaList<'_>) -> T; /// Destroy the arglist `ap` after initialization with `va_start` or `va_copy`. /// @@ -3475,4 +3475,4 @@ pub unsafe fn va_arg(ap: &mut VaListImpl<'_>) -> T; /// #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn va_end(ap: &mut VaListImpl<'_>); +pub unsafe fn va_end(ap: &mut VaList<'_>); diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index f44e12d48add..999bd5e63dc4 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -172,7 +172,7 @@ pub use core::ffi::c_void; all supported platforms", issue = "44930" )] -pub use core::ffi::{VaArgSafe, VaList, VaListImpl}; +pub use core::ffi::{VaArgSafe, VaList}; #[stable(feature = "core_ffi_c", since = "1.64.0")] pub use core::ffi::{ c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint, diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index 7b1c0a18670d..e9824edfef60 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -121,6 +121,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-thumbv8m.base-none-eabi", "ignore-thumbv8m.main-none-eabi", "ignore-tvos", + "ignore-uefi", "ignore-unix", "ignore-unknown", "ignore-uwp", diff --git a/tests/auxiliary/rust_test_helpers.c b/tests/auxiliary/rust_test_helpers.c index 34cc7fd5dfbe..cd10d6b98ca7 100644 --- a/tests/auxiliary/rust_test_helpers.c +++ b/tests/auxiliary/rust_test_helpers.c @@ -314,6 +314,10 @@ double rust_interesting_average(uint64_t n, ...) { return sum; } +int32_t rust_va_list_next_i32(va_list* ap) { + return va_arg(*ap, int32_t); +} + int32_t rust_int8_to_int32(int8_t x) { return (int32_t)x; } diff --git a/tests/codegen-llvm/cffi/c-variadic-copy.rs b/tests/codegen-llvm/cffi/c-variadic-copy.rs index 4c61c4fcf68d..0cbdcb4bbb85 100644 --- a/tests/codegen-llvm/cffi/c-variadic-copy.rs +++ b/tests/codegen-llvm/cffi/c-variadic-copy.rs @@ -1,4 +1,4 @@ -// Tests that `VaListImpl::clone` gets inlined into a call to `llvm.va_copy` +// Tests that `VaList::clone` gets inlined into a call to `llvm.va_copy` #![crate_type = "lib"] #![feature(c_variadic)] @@ -12,5 +12,5 @@ extern "C" { pub unsafe extern "C" fn clone_variadic(ap: VaList) { let mut ap2 = ap.clone(); // CHECK: call void @llvm.va_copy - foreign_c_variadic_1(ap2.as_va_list(), 42i32); + foreign_c_variadic_1(ap2, 42i32); } diff --git a/tests/codegen-llvm/cffi/c-variadic-opt.rs b/tests/codegen-llvm/cffi/c-variadic-opt.rs index 7e544ee7f37d..3cc0c3e9f9bd 100644 --- a/tests/codegen-llvm/cffi/c-variadic-opt.rs +++ b/tests/codegen-llvm/cffi/c-variadic-opt.rs @@ -10,21 +10,21 @@ extern "C" { } // Ensure that `va_start` and `va_end` are properly injected even -// when the "spoofed" `VaListImpl` is not used. +// when the "spoofed" `VaList` is not used. #[no_mangle] pub unsafe extern "C" fn c_variadic_no_use(fmt: *const i8, mut ap: ...) -> i32 { // CHECK: call void @llvm.va_start - vprintf(fmt, ap.as_va_list()) + vprintf(fmt, ap) // CHECK: call void @llvm.va_end } -// Check that `VaListImpl::clone` gets inlined into a direct call to `llvm.va_copy` +// Check that `VaList::clone` gets inlined into a direct call to `llvm.va_copy` #[no_mangle] pub unsafe extern "C" fn c_variadic_clone(fmt: *const i8, mut ap: ...) -> i32 { // CHECK: call void @llvm.va_start let mut ap2 = ap.clone(); // CHECK: call void @llvm.va_copy - let res = vprintf(fmt, ap2.as_va_list()); + let res = vprintf(fmt, ap2); res // CHECK: call void @llvm.va_end } diff --git a/tests/codegen-llvm/cffi/c-variadic.rs b/tests/codegen-llvm/cffi/c-variadic.rs index 140d2f37f469..3ce421eb4a5c 100644 --- a/tests/codegen-llvm/cffi/c-variadic.rs +++ b/tests/codegen-llvm/cffi/c-variadic.rs @@ -1,6 +1,6 @@ //@ needs-unwind //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -// +//@ min-llvm-version: 21 #![crate_type = "lib"] #![feature(c_variadic)] @@ -25,23 +25,23 @@ pub unsafe extern "C" fn use_foreign_c_variadic_0() { } // Ensure that we do not remove the `va_list` passed to the foreign function when -// removing the "spoofed" `VaListImpl` that is used by Rust defined C-variadics. +// removing the "spoofed" `VaList` that is used by Rust defined C-variadics. pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap) + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %0) foreign_c_variadic_1(ap); } pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 42) + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %0, [[PARAM]] 42) foreign_c_variadic_1(ap, 42i32); } pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42) + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %0, [[PARAM]] 2, [[PARAM]] 42) foreign_c_variadic_1(ap, 2i32, 42i32); } pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42, [[PARAM]] 0) + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %0, [[PARAM]] 2, [[PARAM]] 42, [[PARAM]] 0) foreign_c_variadic_1(ap, 2i32, 42i32, 0i32); } diff --git a/tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs b/tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs index 63d8d713d622..dd2d09470994 100644 --- a/tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs +++ b/tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs @@ -2,7 +2,7 @@ #![feature(c_variadic)] #![feature(cfg_select)] -use std::ffi::{CStr, CString, VaList, VaListImpl, c_char, c_double, c_int, c_long, c_longlong}; +use std::ffi::{CStr, CString, VaList, c_char, c_double, c_int, c_long, c_longlong}; macro_rules! continue_if { ($cond:expr) => { @@ -58,11 +58,8 @@ pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize { continue_if!(ap.arg::() == 16); continue_if!(ap.arg::() == 'A' as c_int); continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!")); - ap.with_copy( - |mut ap| { - if compare_c_str(ap.arg::<*const c_char>(), "Correct") { 0 } else { 0xff } - }, - ) + let mut ap = ap.clone(); + if compare_c_str(ap.arg::<*const c_char>(), "Correct") { 0 } else { 0xff } } #[unsafe(no_mangle)] @@ -153,8 +150,8 @@ pub unsafe extern "C" fn check_varargs_5(_: c_int, mut ap: ...) -> usize { unsafe extern "C" { fn test_variadic(_: c_int, ...) -> usize; fn test_va_list_by_value(_: VaList) -> usize; - fn test_va_list_by_pointer(_: *mut VaListImpl) -> usize; - fn test_va_list_by_pointer_pointer(_: *mut *mut VaListImpl) -> usize; + fn test_va_list_by_pointer(_: *mut VaList) -> usize; + fn test_va_list_by_pointer_pointer(_: *mut *mut VaList) -> usize; } #[unsafe(no_mangle)] @@ -165,7 +162,7 @@ extern "C" fn run_test_variadic() -> usize { #[unsafe(no_mangle)] extern "C" fn run_test_va_list_by_value() -> usize { unsafe extern "C" fn helper(mut ap: ...) -> usize { - unsafe { test_va_list_by_value(ap.as_va_list()) } + unsafe { test_va_list_by_value(ap) } } unsafe { helper(1 as c_longlong, 2 as c_int, 3 as c_longlong) } diff --git a/tests/ui/abi/variadic-ffi.rs b/tests/ui/abi/variadic-ffi.rs index dfdbff33264b..3ffa0bea0ecf 100644 --- a/tests/ui/abi/variadic-ffi.rs +++ b/tests/ui/abi/variadic-ffi.rs @@ -10,37 +10,45 @@ extern "C" { fn rust_interesting_average(_: u64, ...) -> f64; fn rust_valist_interesting_average(_: u64, _: VaList) -> f64; + + fn rust_va_list_next_i32(_: *mut VaList<'_>) -> i32; } -pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 { - rust_valist_interesting_average(n, ap.as_va_list()) +pub unsafe extern "C" fn test_valist_forward(n: u64, ap: ...) -> f64 { + rust_valist_interesting_average(n, ap) } -pub unsafe extern "C-unwind" fn c_unwind_can_forward(n: u64, mut ap: ...) -> f64 { - rust_valist_interesting_average(n, ap.as_va_list()) +pub unsafe extern "C-unwind" fn c_unwind_can_forward(n: u64, ap: ...) -> f64 { + rust_valist_interesting_average(n, ap) } pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) { - let mut ap2 = ap.clone(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30); + let ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 30); // Advance one pair in the copy before checking let mut ap2 = ap.clone(); let _ = ap2.arg::(); let _ = ap2.arg::(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 50); // Advance one pair in the original let _ = ap.arg::(); let _ = ap.arg::(); - let mut ap2 = ap.clone(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + let ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 50); let mut ap2 = ap.clone(); let _ = ap2.arg::(); let _ = ap2.arg::(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 70); + assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 70); +} + +pub unsafe extern "C" fn test_ref(mut ap: ...) { + assert_eq!(rust_va_list_next_i32(&mut ap), 2); + assert_eq!(rust_va_list_next_i32(&mut ap), 4); + assert_eq!(rust_va_list_next_i32(&mut ap), 8); } pub fn main() { @@ -85,4 +93,8 @@ pub fn main() { unsafe { test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64); } + + unsafe { + test_ref(2, 4, 8); + } } diff --git a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr new file mode 100644 index 000000000000..fe11c4288618 --- /dev/null +++ b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr @@ -0,0 +1,80 @@ +error: fn_abi_of(take_va_list) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(32 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: $OFFSETS, + memory_index: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: CapturesAddress | NoAlias | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(32 bytes), + pointee_align: Some( + Align(8 bytes), + ), + }, + meta_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: C, + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:26:1 + | +LL | pub extern "C" fn take_va_list(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/c-variadic/pass-by-value-abi.rs b/tests/ui/c-variadic/pass-by-value-abi.rs new file mode 100644 index 000000000000..b65442af2472 --- /dev/null +++ b/tests/ui/c-variadic/pass-by-value-abi.rs @@ -0,0 +1,46 @@ +//@ check-fail +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" +//@ normalize-stderr: "valid_range: 0\.\.=\d+" -> "valid_range: 0..=$$MAX" +//@ normalize-stderr: "memory_index: \[[^\]]+\]" -> "memory_index: $$MEMORY_INDEX" +//@ normalize-stderr: "offsets: \[[^\]]+\]" -> "offsets: $$OFFSETS" +//@ revisions: x86_64 aarch64 win +//@ compile-flags: -O +//@ [x86_64] only-x86_64 +//@ [x86_64] ignore-windows +//@ [x86_64] ignore-uefi +//@ [aarch64] only-aarch64 +//@ [aarch64] ignore-windows +//@ [aarch64] ignore-apple +//@ [aarch64] ignore-uefi +// Windows dosen't use `#[rustc_pass_indirectly_in_non_rustic_abis]` and is tested in CI, so is here +// for comparison. +//@ [win] only-windows + +#![feature(rustc_attrs, c_variadic)] +#![crate_type = "lib"] + +// Can't use `minicore` here as this is testing the implementation in `core::ffi` specifically. +use std::ffi::VaList; + +#[rustc_abi(debug)] +pub extern "C" fn take_va_list(_: VaList<'_>) {} +//~^ ERROR fn_abi_of(take_va_list) = FnAbi { +//[x86_64]~^^ ERROR mode: Indirect { +//[x86_64]~^^^ ERROR on_stack: false, +//[aarch64]~^^^^ ERROR mode: Indirect { +//[aarch64]~^^^^^ ERROR on_stack: false, +//[win]~^^^^^^ ERROR mode: Direct( + +#[cfg(all(target_arch = "x86_64", not(windows)))] +#[rustc_abi(debug)] +pub extern "sysv64" fn take_va_list_sysv64(_: VaList<'_>) {} +//[x86_64]~^ ERROR fn_abi_of(take_va_list_sysv64) = FnAbi { +//[x86_64]~^^ ERROR mode: Indirect { +//[x86_64]~^^^ ERROR on_stack: false, + +#[cfg(all(target_arch = "x86_64", not(windows)))] +#[rustc_abi(debug)] +pub extern "win64" fn take_va_list_win64(_: VaList<'_>) {} +//[x86_64]~^ ERROR: fn_abi_of(take_va_list_win64) = FnAbi { +//[x86_64]~^^ ERROR mode: Indirect { +//[x86_64]~^^^ ERROR on_stack: false, diff --git a/tests/ui/c-variadic/pass-by-value-abi.win.stderr b/tests/ui/c-variadic/pass-by-value-abi.win.stderr new file mode 100644 index 000000000000..e84430859e02 --- /dev/null +++ b/tests/ui/c-variadic/pass-by-value-abi.win.stderr @@ -0,0 +1,83 @@ +error: fn_abi_of(take_va_list) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(8 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Scalar( + Initialized { + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: 0..=$MAX, + }, + ), + fields: Arbitrary { + offsets: $OFFSETS, + memory_index: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Direct( + ArgAttributes { + regular: NoUndef, + arg_ext: None, + pointee_size: Size(0 bytes), + pointee_align: None, + }, + ), + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: C, + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:26:1 + | +LL | pub extern "C" fn take_va_list(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr new file mode 100644 index 000000000000..73f1ccd5992a --- /dev/null +++ b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr @@ -0,0 +1,240 @@ +error: fn_abi_of(take_va_list) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(24 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: $OFFSETS, + memory_index: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: CapturesAddress | NoAlias | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(24 bytes), + pointee_align: Some( + Align(8 bytes), + ), + }, + meta_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: C, + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:26:1 + | +LL | pub extern "C" fn take_va_list(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: fn_abi_of(take_va_list_sysv64) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(24 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: $OFFSETS, + memory_index: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: CapturesAddress | NoAlias | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(24 bytes), + pointee_align: Some( + Align(8 bytes), + ), + }, + meta_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: X86( + SysV64, + ), + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:36:1 + | +LL | pub extern "sysv64" fn take_va_list_sysv64(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: fn_abi_of(take_va_list_win64) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(24 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: $OFFSETS, + memory_index: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: CapturesAddress | NoAlias | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(24 bytes), + pointee_align: Some( + Align(8 bytes), + ), + }, + meta_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: X86( + Win64, + ), + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:43:1 + | +LL | pub extern "win64" fn take_va_list_win64(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/c-variadic/variadic-ffi-4.rs b/tests/ui/c-variadic/variadic-ffi-4.rs index 806403794225..d9e2e617ce3a 100644 --- a/tests/ui/c-variadic/variadic-ffi-4.rs +++ b/tests/ui/c-variadic/variadic-ffi-4.rs @@ -2,37 +2,30 @@ #![no_std] #![feature(c_variadic)] -use core::ffi::{VaList, VaListImpl}; +use core::ffi::VaList; -pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { +pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaList<'f> { ap //~^ ERROR: lifetime may not live long enough - //~| ERROR: lifetime may not live long enough } -pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { +pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { ap //~ ERROR: lifetime may not live long enough } -pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { - let _ = ap.with_copy(|ap| ap); //~ ERROR: lifetime may not live long enough -} - -pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { *ap0 = ap1; //~^ ERROR: lifetime may not live long enough - //~| ERROR: lifetime may not live long enough } -pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { ap0 = &mut ap1; //~^ ERROR: `ap1` does not live long enough //~| ERROR: lifetime may not live long enough //~| ERROR: lifetime may not live long enough } -pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaList, mut ap1: ...) { *ap0 = ap1.clone(); //~^ ERROR: lifetime may not live long enough - //~| ERROR: lifetime may not live long enough } diff --git a/tests/ui/c-variadic/variadic-ffi-4.stderr b/tests/ui/c-variadic/variadic-ffi-4.stderr index fc9f8036083a..a230bb6f5861 100644 --- a/tests/ui/c-variadic/variadic-ffi-4.stderr +++ b/tests/ui/c-variadic/variadic-ffi-4.stderr @@ -1,113 +1,64 @@ error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:8:5 | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | -- -- has type `VaListImpl<'1>` - | | - | lifetime `'f` defined here -LL | ap - | ^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'f` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:8:5 - | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | -- -- has type `VaListImpl<'1>` +LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaList<'f> { + | -- -- has type `VaList<'1>` | | | lifetime `'f` defined here LL | ap | ^^ function was supposed to return data with lifetime `'f` but it is returning data with lifetime `'1` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:14:5 + --> $DIR/variadic-ffi-4.rs:13:5 | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - | -- has type `VaListImpl<'1>` +LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { + | -- has type `VaList<'1>` LL | ap | ^^ returning this value requires that `'1` must outlive `'static` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:18:31 + --> $DIR/variadic-ffi-4.rs:17:5 | -LL | let _ = ap.with_copy(|ap| ap); - | --- ^^ returning this value requires that `'1` must outlive `'2` - | | | - | | return type of closure is VaList<'2, '_> - | has type `VaList<'1, '_>` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:22:5 - | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` +LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | ------- ------- has type `VaList<'1>` | | - | has type `&mut VaListImpl<'1>` + | has type `&mut VaList<'2>` LL | *ap0 = ap1; | ^^^^ assignment requires that `'1` must outlive `'2` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:22:5 | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` +LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | ------- ------- has type `VaList<'2>` | | - | has type `&mut VaListImpl<'1>` -LL | *ap0 = ap1; - | ^^^^ assignment requires that `'2` must outlive `'1` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:28:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` - | | - | has type `&mut VaListImpl<'1>` + | has type `&mut VaList<'1>` LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` | - = note: requirement occurs because of a mutable reference to `VaListImpl<'_>` + = note: requirement occurs because of a mutable reference to `VaList<'_>` = note: mutable references are invariant over their type parameter = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:28:5 + --> $DIR/variadic-ffi-4.rs:22:5 | -LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` +LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | ------- ------- has type `VaList<'2>` | | - | has type `&mut VaListImpl<'1>` + | has type `&mut VaList<'1>` LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1` | - = note: requirement occurs because of a mutable reference to `VaListImpl<'_>` + = note: requirement occurs because of a mutable reference to `VaList<'_>` = note: mutable references are invariant over their type parameter = help: see for more information about variance error[E0597]: `ap1` does not live long enough - --> $DIR/variadic-ffi-4.rs:28:11 + --> $DIR/variadic-ffi-4.rs:22:11 | -LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | - ------- binding `ap1` declared here +LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | - ------- binding `ap1` declared here | | | let's call the lifetime of this reference `'3` LL | ap0 = &mut ap1; @@ -120,33 +71,15 @@ LL | } | - `ap1` dropped here while still borrowed error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:35:5 + --> $DIR/variadic-ffi-4.rs:29:5 | -LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` +LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | ------- ------- has type `VaList<'1>` | | - | has type `&mut VaListImpl<'1>` + | has type `&mut VaList<'2>` LL | *ap0 = ap1.clone(); - | ^^^^ assignment requires that `'2` must outlive `'1` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance + | ^^^^ assignment requires that `'1` must outlive `'2` -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:35:12 - | -LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` - | | - | has type `&mut VaListImpl<'1>` -LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ argument requires that `'1` must outlive `'2` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance - -error: aborting due to 11 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs b/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs index 8be99f22d2ee..b29f6915ae3d 100644 --- a/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs +++ b/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs @@ -1,4 +1,4 @@ -// A bare `...` represents `CVarArgs` (`VaListImpl<'_>`) in function argument type +// A bare `...` represents `CVarArgs` (`VaList<'_>`) in function argument type // position without being a proper type syntactically. // This test ensures that we do not regress certain MBE calls would we ever promote // `...` to a proper type syntactically. diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index 025c0e3ecaca..6f61425a8bd6 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -32,12 +32,12 @@ extern "C" fn f3_3(_: ..., x: isize) {} const unsafe extern "C" fn f4_1(x: isize, _: ...) {} //~^ ERROR functions cannot be both `const` and C-variadic -//~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +//~| ERROR destructor of `VaList<'_>` cannot be evaluated at compile-time const extern "C" fn f4_2(x: isize, _: ...) {} //~^ ERROR functions cannot be both `const` and C-variadic //~| ERROR functions with a C variable argument list must be unsafe -//~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +//~| ERROR destructor of `VaList<'_>` cannot be evaluated at compile-time const extern "C" fn f4_3(_: ..., x: isize, _: ...) {} //~^ ERROR functions cannot be both `const` and C-variadic @@ -65,7 +65,7 @@ impl X { const fn i_f5(x: isize, _: ...) {} //~^ ERROR `...` is not supported for non-extern functions //~| ERROR functions cannot be both `const` and C-variadic - //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time + //~| ERROR destructor of `VaList<'_>` cannot be evaluated at compile-time } trait T { diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index 0e02d4434233..318015737fa1 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -236,7 +236,7 @@ error: `...` must be the last argument of a C-variadic function LL | fn t_f6(_: ..., x: isize); | ^^^^^^ -error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +error[E0493]: destructor of `VaList<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:33:43 | LL | const unsafe extern "C" fn f4_1(x: isize, _: ...) {} @@ -244,7 +244,7 @@ LL | const unsafe extern "C" fn f4_1(x: isize, _: ...) {} | | | the destructor for this type cannot be evaluated in constant functions -error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +error[E0493]: destructor of `VaList<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:37:36 | LL | const extern "C" fn f4_2(x: isize, _: ...) {} @@ -252,7 +252,7 @@ LL | const extern "C" fn f4_2(x: isize, _: ...) {} | | | the destructor for this type cannot be evaluated in constant functions -error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +error[E0493]: destructor of `VaList<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 | LL | const fn i_f5(x: isize, _: ...) {} diff --git a/tests/ui/thir-print/c-variadic.stdout b/tests/ui/thir-print/c-variadic.stdout index d64b2b9aa9d1..f1905e04f72b 100644 --- a/tests/ui/thir-print/c-variadic.stdout +++ b/tests/ui/thir-print/c-variadic.stdout @@ -16,13 +16,13 @@ params: [ ) } Param { - ty: std::ffi::VaListImpl<'{erased}> + ty: std::ffi::VaList<'{erased}> ty_span: None self_kind: None hir_id: Some(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).3)) param: Some( Pat: { - ty: std::ffi::VaListImpl<'{erased}> + ty: std::ffi::VaList<'{erased}> span: $DIR/c-variadic.rs:7:34: 7:37 (#0) kind: PatKind { Missing From 376b284521061803356c7c711c194b31be027ce4 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 4 Nov 2025 19:32:06 +0100 Subject: [PATCH 0282/3801] document `VaList` ABI for more targets --- library/core/src/ffi/va_list.rs | 57 ++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index 449e62ac00d3..4c59ea0cc532 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -8,11 +8,29 @@ use crate::fmt; use crate::intrinsics::{va_arg, va_copy}; use crate::marker::PhantomCovariantLifetime; -// Most targets explicitly specify the layout of `va_list`, this layout is matched here. -// For `va_list`s which are single-element array in C (and therefore experience array-to-pointer -// decay when passed as arguments in C), the `VaList` struct is annotated with -// `#[rustc_pass_indirectly_in_non_rustic_abis]`. This ensures that the compiler uses the correct -// ABI for functions like `extern "C" fn takes_va_list(va: VaList<'_>)` by passing `va` indirectly. +// There are currently three flavors of how a C `va_list` is implemented for +// targets that Rust supports: +// +// - `va_list` is an opaque pointer +// - `va_list` is a struct +// - `va_list` is a single-element array, containing a struct +// +// The opaque pointer approach is the simplest to implement: the pointer just +// points to an array of arguments on the caller's stack. +// +// The struct and single-element array variants are more complex, but +// potentially more efficient because the additional state makes it +// possible to pass variadic arguments via registers. +// +// The Rust `VaList` type is ABI-compatible with the C `va_list`. +// The struct and pointer cases straightforwardly map to their Rust equivalents, +// but the single-element array case is special: in C, this type is subject to +// array-to-pointer decay. +// +// The `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute is used to match +// the pointer decay behavior in Rust, while otherwise matching Rust semantics. +// This attribute ensures that the compiler uses the correct ABI for functions +// like `extern "C" fn takes_va_list(va: VaList<'_>)` by passing `va` indirectly. crate::cfg_select! { all( target_arch = "aarch64", @@ -20,8 +38,9 @@ crate::cfg_select! { not(target_os = "uefi"), not(windows), ) => { - /// AArch64 ABI implementation of a `va_list`. See the - /// [AArch64 Procedure Call Standard] for more details. + /// AArch64 ABI implementation of a `va_list`. + /// + /// See the [AArch64 Procedure Call Standard] for more details. /// /// [AArch64 Procedure Call Standard]: /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf @@ -37,6 +56,12 @@ crate::cfg_select! { } all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)) => { /// PowerPC ABI implementation of a `va_list`. + /// + /// See the [LLVM source] and [GCC header] for more details. + /// + /// [LLVM source]: + /// https://github.com/llvm/llvm-project/blob/af9a4263a1a209953a1d339ef781a954e31268ff/llvm/lib/Target/PowerPC/PPCISelLowering.cpp#L4089-L4111 + /// [GCC header]: https://web.mit.edu/darwin/src/modules/gcc/gcc/ginclude/va-ppc.h #[repr(C)] #[derive(Debug)] #[rustc_pass_indirectly_in_non_rustic_abis] @@ -50,6 +75,11 @@ crate::cfg_select! { } target_arch = "s390x" => { /// s390x ABI implementation of a `va_list`. + /// + /// See the [S/390x ELF Application Binary Interface Supplement] for more details. + /// + /// [S/390x ELF Application Binary Interface Supplement]: + /// https://docs.google.com/gview?embedded=true&url=https://github.com/IBM/s390x-abi/releases/download/v1.7/lzsabi_s390x.pdf #[repr(C)] #[derive(Debug)] #[rustc_pass_indirectly_in_non_rustic_abis] @@ -61,7 +91,12 @@ crate::cfg_select! { } } all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)) => { - /// x86_64 ABI implementation of a `va_list`. + /// x86_64 System V ABI implementation of a `va_list`. + /// + /// See the [System V AMD64 ABI] for more details. + /// + /// [System V AMD64 ABI]: + /// https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf #[repr(C)] #[derive(Debug)] #[rustc_pass_indirectly_in_non_rustic_abis] @@ -74,6 +109,11 @@ crate::cfg_select! { } target_arch = "xtensa" => { /// Xtensa ABI implementation of a `va_list`. + /// + /// See the [LLVM source] for more details. + /// + /// [LLVM source]: + /// https://github.com/llvm/llvm-project/blob/af9a4263a1a209953a1d339ef781a954e31268ff/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp#L1211-L1215 #[repr(C)] #[derive(Debug)] #[rustc_pass_indirectly_in_non_rustic_abis] @@ -88,6 +128,7 @@ crate::cfg_select! { // // - apple aarch64 (see https://github.com/rust-lang/rust/pull/56599) // - windows + // - powerpc64 & powerpc64le // - uefi // - any other target for which we don't specify the `VaListInner` above // From 08979745c9bc87b38aa3a952593a08db25a83711 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 4 Dec 2025 11:13:24 +0100 Subject: [PATCH 0283/3801] split out `va_list` forwarding into its own test --- tests/codegen-llvm/cffi/c-variadic-va_list.rs | 36 +++++++++++++++++++ tests/codegen-llvm/cffi/c-variadic.rs | 22 ------------ 2 files changed, 36 insertions(+), 22 deletions(-) create mode 100644 tests/codegen-llvm/cffi/c-variadic-va_list.rs diff --git a/tests/codegen-llvm/cffi/c-variadic-va_list.rs b/tests/codegen-llvm/cffi/c-variadic-va_list.rs new file mode 100644 index 000000000000..e2652491f421 --- /dev/null +++ b/tests/codegen-llvm/cffi/c-variadic-va_list.rs @@ -0,0 +1,36 @@ +//@ needs-unwind +//@ compile-flags: -Copt-level=3 +//@ min-llvm-version: 21 + +#![crate_type = "lib"] +#![feature(c_variadic)] +#![no_std] +use core::ffi::VaList; + +// Ensure that we do not remove the `va_list` passed to the foreign function when +// removing the "spoofed" `VaList` that is used by Rust defined C-variadics. + +extern "C" { + fn foreign_c_variadic_1(_: VaList, ...); +} + +// CHECK-LABEL: use_foreign_c_variadic_1_0 +pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) { + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap) + foreign_c_variadic_1(ap); +} + +// CHECK-LABEL: use_foreign_c_variadic_1_1 +pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) { + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, i32 noundef 42) + foreign_c_variadic_1(ap, 42i32); +} +pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) { + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, i32 noundef 2, i32 noundef 42) + foreign_c_variadic_1(ap, 2i32, 42i32); +} + +pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) { + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, i32 noundef 2, i32 noundef 42, i32 noundef 0) + foreign_c_variadic_1(ap, 2i32, 42i32, 0i32); +} diff --git a/tests/codegen-llvm/cffi/c-variadic.rs b/tests/codegen-llvm/cffi/c-variadic.rs index 3ce421eb4a5c..7a2e2ba5047e 100644 --- a/tests/codegen-llvm/cffi/c-variadic.rs +++ b/tests/codegen-llvm/cffi/c-variadic.rs @@ -9,7 +9,6 @@ use core::ffi::VaList; extern "C" { fn foreign_c_variadic_0(_: i32, ...); - fn foreign_c_variadic_1(_: VaList, ...); } pub unsafe extern "C" fn use_foreign_c_variadic_0() { @@ -24,27 +23,6 @@ pub unsafe extern "C" fn use_foreign_c_variadic_0() { foreign_c_variadic_0(0, 42i32, 1024i32, 0i32); } -// Ensure that we do not remove the `va_list` passed to the foreign function when -// removing the "spoofed" `VaList` that is used by Rust defined C-variadics. -pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %0) - foreign_c_variadic_1(ap); -} - -pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %0, [[PARAM]] 42) - foreign_c_variadic_1(ap, 42i32); -} -pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %0, [[PARAM]] 2, [[PARAM]] 42) - foreign_c_variadic_1(ap, 2i32, 42i32); -} - -pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %0, [[PARAM]] 2, [[PARAM]] 42, [[PARAM]] 0) - foreign_c_variadic_1(ap, 2i32, 42i32, 0i32); -} - // Ensure that `va_start` and `va_end` are properly injected. #[no_mangle] pub unsafe extern "C" fn c_variadic(n: i32, mut ap: ...) -> i32 { From 88c2c81848019c6f7fc4d98984d53d989e2d5c0b Mon Sep 17 00:00:00 2001 From: Roy Ammerschuber Date: Wed, 3 Dec 2025 12:08:01 +0100 Subject: [PATCH 0284/3801] factor out tree_visitor into own file --- .../src/borrow_tracker/tree_borrows/mod.rs | 1 + .../src/borrow_tracker/tree_borrows/tree.rs | 301 +----------------- .../tree_borrows/tree_visitor.rs | 286 +++++++++++++++++ 3 files changed, 296 insertions(+), 292 deletions(-) create mode 100644 src/tools/miri/src/borrow_tracker/tree_borrows/tree_visitor.rs 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 e1da12282cd9..018421ad1064 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -13,6 +13,7 @@ pub mod diagnostics; mod foreign_access_skipping; mod perms; mod tree; +mod tree_visitor; mod unimap; mod wildcard; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 7fc9fa786e10..3532e2e0ba86 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -18,15 +18,16 @@ use rustc_data_structures::fx::FxHashSet; use rustc_span::Span; use smallvec::SmallVec; -use super::diagnostics::AccessCause; -use super::wildcard::WildcardState; -use crate::borrow_tracker::tree_borrows::Permission; -use crate::borrow_tracker::tree_borrows::diagnostics::{ - self, NodeDebugInfo, TbError, TransitionError, no_valid_exposed_references_error, +use super::Permission; +use super::diagnostics::{ + self, AccessCause, NodeDebugInfo, TbError, TransitionError, + no_valid_exposed_references_error, }; -use crate::borrow_tracker::tree_borrows::foreign_access_skipping::IdempotentForeignAccess; -use crate::borrow_tracker::tree_borrows::perms::PermTransition; -use crate::borrow_tracker::tree_borrows::unimap::{UniIndex, UniKeyMap, UniValMap}; +use super::foreign_access_skipping::IdempotentForeignAccess; +use super::perms::PermTransition; +use super::tree_visitor::{ChildrenVisitMode, ContinueTraversal, NodeAppArgs, TreeVisitor}; +use super::unimap::{UniIndex, UniKeyMap, UniValMap}; +use super::wildcard::WildcardState; use crate::borrow_tracker::{AccessKind, GlobalState, ProtectorKind}; use crate::*; @@ -339,290 +340,6 @@ pub(super) struct Node { pub debug_info: NodeDebugInfo, } -/// Data given to the transition function -struct NodeAppArgs<'visit> { - /// The index of the current node. - idx: UniIndex, - /// Relative position of the access. - rel_pos: AccessRelatedness, - /// The node map of this tree. - nodes: &'visit mut UniValMap, - /// The permissions map of this tree. - loc: &'visit mut LocationTree, -} -/// Internal contents of `Tree` with the minimum of mutable access for -/// For soundness do not modify the children or parent indexes of nodes -/// during traversal. -struct TreeVisitor<'tree> { - nodes: &'tree mut UniValMap, - loc: &'tree mut LocationTree, -} - -/// Whether to continue exploring the children recursively or not. -#[derive(Debug)] -enum ContinueTraversal { - Recurse, - SkipSelfAndChildren, -} - -#[derive(Clone, Copy, Debug)] -pub enum ChildrenVisitMode { - VisitChildrenOfAccessed, - SkipChildrenOfAccessed, -} - -enum RecursionState { - BeforeChildren, - AfterChildren, -} - -/// Stack of nodes left to explore in a tree traversal. -/// See the docs of `traverse_this_parents_children_other` for details on the -/// traversal order. -struct TreeVisitorStack { - /// Function describing whether to continue at a tag. - /// This is only invoked for foreign accesses. - f_continue: NodeContinue, - /// Function to apply to each tag. - f_propagate: NodeApp, - /// Mutable state of the visit: the tags left to handle. - /// Every tag pushed should eventually be handled, - /// and the precise order is relevant for diagnostics. - /// Since the traversal is piecewise bottom-up, we need to - /// remember whether we're here initially, or after visiting all children. - /// The last element indicates this. - /// This is just an artifact of how you hand-roll recursion, - /// it does not have a deeper meaning otherwise. - stack: Vec<(UniIndex, AccessRelatedness, RecursionState)>, -} - -impl TreeVisitorStack -where - NodeContinue: Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - NodeApp: FnMut(NodeAppArgs<'_>) -> Result<(), Err>, -{ - fn should_continue_at( - &self, - this: &mut TreeVisitor<'_>, - idx: UniIndex, - rel_pos: AccessRelatedness, - ) -> ContinueTraversal { - let args = NodeAppArgs { idx, rel_pos, nodes: this.nodes, loc: this.loc }; - (self.f_continue)(&args) - } - - fn propagate_at( - &mut self, - this: &mut TreeVisitor<'_>, - idx: UniIndex, - rel_pos: AccessRelatedness, - ) -> Result<(), Err> { - (self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, loc: this.loc }) - } - - /// Returns the root of this tree. - fn go_upwards_from_accessed( - &mut self, - this: &mut TreeVisitor<'_>, - accessed_node: UniIndex, - visit_children: ChildrenVisitMode, - ) -> Result { - // We want to visit the accessed node's children first. - // However, we will below walk up our parents and push their children (our cousins) - // onto the stack. To ensure correct iteration order, this method thus finishes - // by reversing the stack. This only works if the stack is empty initially. - assert!(self.stack.is_empty()); - // First, handle accessed node. A bunch of things need to - // be handled differently here compared to the further parents - // of `accesssed_node`. - { - self.propagate_at(this, accessed_node, AccessRelatedness::LocalAccess)?; - if matches!(visit_children, ChildrenVisitMode::VisitChildrenOfAccessed) { - let accessed_node = this.nodes.get(accessed_node).unwrap(); - // We `rev()` here because we reverse the entire stack later. - for &child in accessed_node.children.iter().rev() { - self.stack.push(( - child, - AccessRelatedness::ForeignAccess, - RecursionState::BeforeChildren, - )); - } - } - } - // Then, handle the accessed node's parents. Here, we need to - // make sure we only mark the "cousin" subtrees for later visitation, - // not the subtree that contains the accessed node. - let mut last_node = accessed_node; - while let Some(current) = this.nodes.get(last_node).unwrap().parent { - self.propagate_at(this, current, AccessRelatedness::LocalAccess)?; - let node = this.nodes.get(current).unwrap(); - // We `rev()` here because we reverse the entire stack later. - for &child in node.children.iter().rev() { - if last_node == child { - continue; - } - self.stack.push(( - child, - AccessRelatedness::ForeignAccess, - RecursionState::BeforeChildren, - )); - } - last_node = current; - } - // Reverse the stack, as discussed above. - self.stack.reverse(); - Ok(last_node) - } - - fn finish_foreign_accesses(&mut self, this: &mut TreeVisitor<'_>) -> Result<(), Err> { - while let Some((idx, rel_pos, step)) = self.stack.last_mut() { - let idx = *idx; - let rel_pos = *rel_pos; - match *step { - // How to do bottom-up traversal, 101: Before you handle a node, you handle all children. - // For this, you must first find the children, which is what this code here does. - RecursionState::BeforeChildren => { - // Next time we come back will be when all the children are handled. - *step = RecursionState::AfterChildren; - // Now push the children, except if we are told to skip this subtree. - let handle_children = self.should_continue_at(this, idx, rel_pos); - match handle_children { - ContinueTraversal::Recurse => { - let node = this.nodes.get(idx).unwrap(); - for &child in node.children.iter() { - self.stack.push((child, rel_pos, RecursionState::BeforeChildren)); - } - } - ContinueTraversal::SkipSelfAndChildren => { - // skip self - self.stack.pop(); - continue; - } - } - } - // All the children are handled, let's actually visit this node - RecursionState::AfterChildren => { - self.stack.pop(); - self.propagate_at(this, idx, rel_pos)?; - } - } - } - Ok(()) - } - - fn new(f_continue: NodeContinue, f_propagate: NodeApp) -> Self { - Self { f_continue, f_propagate, stack: Vec::new() } - } -} - -impl<'tree> TreeVisitor<'tree> { - /// Applies `f_propagate` to every vertex of the tree in a piecewise bottom-up way: First, visit - /// all ancestors of `start_idx` (starting with `start_idx` itself), then children of `start_idx`, then the rest, - /// going bottom-up in each of these two "pieces" / sections. - /// This ensures that errors are triggered in the following order - /// - first invalid accesses with insufficient permissions, closest to the accessed node first, - /// - then protector violations, bottom-up, starting with the children of the accessed node, and then - /// going upwards and outwards. - /// - /// The following graphic visualizes it, with numbers indicating visitation order and `start_idx` being - /// the node that is visited first ("1"): - /// - /// ```text - /// 3 - /// /| - /// / | - /// 9 2 - /// | |\ - /// | | \ - /// 8 1 7 - /// / \ - /// 4 6 - /// | - /// 5 - /// ``` - /// - /// `f_propagate` should follow the following format: for a given `Node` it updates its - /// `Permission` depending on the position relative to `start_idx` (given by an - /// `AccessRelatedness`). - /// `f_continue` is called earlier on foreign nodes, and describes whether to even start - /// visiting the subtree at that node. If it e.g. returns `SkipSelfAndChildren` on node 6 - /// above, then nodes 5 _and_ 6 would not be visited by `f_propagate`. It is not used for - /// notes having a child access (nodes 1, 2, 3). - /// - /// Finally, remember that the iteration order is not relevant for UB, it only affects - /// diagnostics. It also affects tree traversal optimizations built on top of this, so - /// those need to be reviewed carefully as well whenever this changes. - /// - /// Returns the index of the root of the accessed tree. - fn traverse_this_parents_children_other( - mut self, - start_idx: UniIndex, - f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, - ) -> Result { - let mut stack = TreeVisitorStack::new(f_continue, f_propagate); - // Visits the accessed node itself, and all its parents, i.e. all nodes - // undergoing a child access. Also pushes the children and the other - // cousin nodes (i.e. all nodes undergoing a foreign access) to the stack - // to be processed later. - let root = stack.go_upwards_from_accessed( - &mut self, - start_idx, - ChildrenVisitMode::VisitChildrenOfAccessed, - )?; - // Now visit all the foreign nodes we remembered earlier. - // For this we go bottom-up, but also allow f_continue to skip entire - // subtrees from being visited if it would be a NOP. - stack.finish_foreign_accesses(&mut self)?; - Ok(root) - } - - /// Like `traverse_this_parents_children_other`, but skips the children of `start_idx`. - /// - /// Returns the index of the root of the accessed tree. - fn traverse_nonchildren( - mut self, - start_idx: UniIndex, - f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, - ) -> Result { - let mut stack = TreeVisitorStack::new(f_continue, f_propagate); - // Visits the accessed node itself, and all its parents, i.e. all nodes - // undergoing a child access. Also pushes the other cousin nodes to the - // stack, but not the children of the accessed node. - let root = stack.go_upwards_from_accessed( - &mut self, - start_idx, - ChildrenVisitMode::SkipChildrenOfAccessed, - )?; - // Now visit all the foreign nodes we remembered earlier. - // For this we go bottom-up, but also allow f_continue to skip entire - // subtrees from being visited if it would be a NOP. - stack.finish_foreign_accesses(&mut self)?; - Ok(root) - } - - /// Traverses all children of `start_idx` including `start_idx` itself. - /// Uses `f_continue` to filter out subtrees and then processes each node - /// with `f_propagate` so that the children get processed before their - /// parents. - fn traverse_children_this( - mut self, - start_idx: UniIndex, - f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, - ) -> Result<(), Err> { - let mut stack = TreeVisitorStack::new(f_continue, f_propagate); - - stack.stack.push(( - start_idx, - AccessRelatedness::ForeignAccess, - RecursionState::BeforeChildren, - )); - stack.finish_foreign_accesses(&mut self) - } -} - impl Tree { /// Create a new tree, with only a root pointer. pub fn new(root_tag: BorTag, size: Size, span: Span) -> Self { diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree_visitor.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree_visitor.rs new file mode 100644 index 000000000000..aa9df89180b8 --- /dev/null +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree_visitor.rs @@ -0,0 +1,286 @@ +use super::tree::{AccessRelatedness, LocationTree, Node}; +use super::unimap::{UniIndex, UniValMap}; + +/// Data given to the transition function +pub struct NodeAppArgs<'visit> { + /// The index of the current node. + pub idx: UniIndex, + /// Relative position of the access. + pub rel_pos: AccessRelatedness, + /// The node map of this tree. + pub nodes: &'visit mut UniValMap, + /// The permissions map of this tree. + pub loc: &'visit mut LocationTree, +} +/// Internal contents of `Tree` with the minimum of mutable access for +/// For soundness do not modify the children or parent indexes of nodes +/// during traversal. +pub struct TreeVisitor<'tree> { + pub nodes: &'tree mut UniValMap, + pub loc: &'tree mut LocationTree, +} + +/// Whether to continue exploring the children recursively or not. +#[derive(Debug)] +pub enum ContinueTraversal { + Recurse, + SkipSelfAndChildren, +} + +#[derive(Clone, Copy, Debug)] +pub enum ChildrenVisitMode { + VisitChildrenOfAccessed, + SkipChildrenOfAccessed, +} + +enum RecursionState { + BeforeChildren, + AfterChildren, +} + +/// Stack of nodes left to explore in a tree traversal. +/// See the docs of `traverse_this_parents_children_other` for details on the +/// traversal order. +struct TreeVisitorStack { + /// Function describing whether to continue at a tag. + /// This is only invoked for foreign accesses. + f_continue: NodeContinue, + /// Function to apply to each tag. + f_propagate: NodeApp, + /// Mutable state of the visit: the tags left to handle. + /// Every tag pushed should eventually be handled, + /// and the precise order is relevant for diagnostics. + /// Since the traversal is piecewise bottom-up, we need to + /// remember whether we're here initially, or after visiting all children. + /// The last element indicates this. + /// This is just an artifact of how you hand-roll recursion, + /// it does not have a deeper meaning otherwise. + stack: Vec<(UniIndex, AccessRelatedness, RecursionState)>, +} + +impl TreeVisitorStack +where + NodeContinue: Fn(&NodeAppArgs<'_>) -> ContinueTraversal, + NodeApp: FnMut(NodeAppArgs<'_>) -> Result<(), Err>, +{ + fn should_continue_at( + &self, + this: &mut TreeVisitor<'_>, + idx: UniIndex, + rel_pos: AccessRelatedness, + ) -> ContinueTraversal { + let args = NodeAppArgs { idx, rel_pos, nodes: this.nodes, loc: this.loc }; + (self.f_continue)(&args) + } + + fn propagate_at( + &mut self, + this: &mut TreeVisitor<'_>, + idx: UniIndex, + rel_pos: AccessRelatedness, + ) -> Result<(), Err> { + (self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, loc: this.loc }) + } + + /// Returns the root of this tree. + fn go_upwards_from_accessed( + &mut self, + this: &mut TreeVisitor<'_>, + accessed_node: UniIndex, + visit_children: ChildrenVisitMode, + ) -> Result { + // We want to visit the accessed node's children first. + // However, we will below walk up our parents and push their children (our cousins) + // onto the stack. To ensure correct iteration order, this method thus finishes + // by reversing the stack. This only works if the stack is empty initially. + assert!(self.stack.is_empty()); + // First, handle accessed node. A bunch of things need to + // be handled differently here compared to the further parents + // of `accesssed_node`. + { + self.propagate_at(this, accessed_node, AccessRelatedness::LocalAccess)?; + if matches!(visit_children, ChildrenVisitMode::VisitChildrenOfAccessed) { + let accessed_node = this.nodes.get(accessed_node).unwrap(); + // We `rev()` here because we reverse the entire stack later. + for &child in accessed_node.children.iter().rev() { + self.stack.push(( + child, + AccessRelatedness::ForeignAccess, + RecursionState::BeforeChildren, + )); + } + } + } + // Then, handle the accessed node's parents. Here, we need to + // make sure we only mark the "cousin" subtrees for later visitation, + // not the subtree that contains the accessed node. + let mut last_node = accessed_node; + while let Some(current) = this.nodes.get(last_node).unwrap().parent { + self.propagate_at(this, current, AccessRelatedness::LocalAccess)?; + let node = this.nodes.get(current).unwrap(); + // We `rev()` here because we reverse the entire stack later. + for &child in node.children.iter().rev() { + if last_node == child { + continue; + } + self.stack.push(( + child, + AccessRelatedness::ForeignAccess, + RecursionState::BeforeChildren, + )); + } + last_node = current; + } + // Reverse the stack, as discussed above. + self.stack.reverse(); + Ok(last_node) + } + + fn finish_foreign_accesses(&mut self, this: &mut TreeVisitor<'_>) -> Result<(), Err> { + while let Some((idx, rel_pos, step)) = self.stack.last_mut() { + let idx = *idx; + let rel_pos = *rel_pos; + match *step { + // How to do bottom-up traversal, 101: Before you handle a node, you handle all children. + // For this, you must first find the children, which is what this code here does. + RecursionState::BeforeChildren => { + // Next time we come back will be when all the children are handled. + *step = RecursionState::AfterChildren; + // Now push the children, except if we are told to skip this subtree. + let handle_children = self.should_continue_at(this, idx, rel_pos); + match handle_children { + ContinueTraversal::Recurse => { + let node = this.nodes.get(idx).unwrap(); + for &child in node.children.iter() { + self.stack.push((child, rel_pos, RecursionState::BeforeChildren)); + } + } + ContinueTraversal::SkipSelfAndChildren => { + // skip self + self.stack.pop(); + continue; + } + } + } + // All the children are handled, let's actually visit this node + RecursionState::AfterChildren => { + self.stack.pop(); + self.propagate_at(this, idx, rel_pos)?; + } + } + } + Ok(()) + } + + fn new(f_continue: NodeContinue, f_propagate: NodeApp) -> Self { + Self { f_continue, f_propagate, stack: Vec::new() } + } +} + +impl<'tree> TreeVisitor<'tree> { + /// Applies `f_propagate` to every vertex of the tree in a piecewise bottom-up way: First, visit + /// all ancestors of `start_idx` (starting with `start_idx` itself), then children of `start_idx`, then the rest, + /// going bottom-up in each of these two "pieces" / sections. + /// This ensures that errors are triggered in the following order + /// - first invalid accesses with insufficient permissions, closest to the accessed node first, + /// - then protector violations, bottom-up, starting with the children of the accessed node, and then + /// going upwards and outwards. + /// + /// The following graphic visualizes it, with numbers indicating visitation order and `start_idx` being + /// the node that is visited first ("1"): + /// + /// ```text + /// 3 + /// /| + /// / | + /// 9 2 + /// | |\ + /// | | \ + /// 8 1 7 + /// / \ + /// 4 6 + /// | + /// 5 + /// ``` + /// + /// `f_propagate` should follow the following format: for a given `Node` it updates its + /// `Permission` depending on the position relative to `start_idx` (given by an + /// `AccessRelatedness`). + /// `f_continue` is called earlier on foreign nodes, and describes whether to even start + /// visiting the subtree at that node. If it e.g. returns `SkipSelfAndChildren` on node 6 + /// above, then nodes 5 _and_ 6 would not be visited by `f_propagate`. It is not used for + /// notes having a child access (nodes 1, 2, 3). + /// + /// Finally, remember that the iteration order is not relevant for UB, it only affects + /// diagnostics. It also affects tree traversal optimizations built on top of this, so + /// those need to be reviewed carefully as well whenever this changes. + /// + /// Returns the index of the root of the accessed tree. + pub fn traverse_this_parents_children_other( + mut self, + start_idx: UniIndex, + f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, + f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + ) -> Result { + let mut stack = TreeVisitorStack::new(f_continue, f_propagate); + // Visits the accessed node itself, and all its parents, i.e. all nodes + // undergoing a child access. Also pushes the children and the other + // cousin nodes (i.e. all nodes undergoing a foreign access) to the stack + // to be processed later. + let root = stack.go_upwards_from_accessed( + &mut self, + start_idx, + ChildrenVisitMode::VisitChildrenOfAccessed, + )?; + // Now visit all the foreign nodes we remembered earlier. + // For this we go bottom-up, but also allow f_continue to skip entire + // subtrees from being visited if it would be a NOP. + stack.finish_foreign_accesses(&mut self)?; + Ok(root) + } + + /// Like `traverse_this_parents_children_other`, but skips the children of `start_idx`. + /// + /// Returns the index of the root of the accessed tree. + pub fn traverse_nonchildren( + mut self, + start_idx: UniIndex, + f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, + f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + ) -> Result { + let mut stack = TreeVisitorStack::new(f_continue, f_propagate); + // Visits the accessed node itself, and all its parents, i.e. all nodes + // undergoing a child access. Also pushes the other cousin nodes to the + // stack, but not the children of the accessed node. + let root = stack.go_upwards_from_accessed( + &mut self, + start_idx, + ChildrenVisitMode::SkipChildrenOfAccessed, + )?; + // Now visit all the foreign nodes we remembered earlier. + // For this we go bottom-up, but also allow f_continue to skip entire + // subtrees from being visited if it would be a NOP. + stack.finish_foreign_accesses(&mut self)?; + Ok(root) + } + + /// Traverses all children of `start_idx` including `start_idx` itself. + /// Uses `f_continue` to filter out subtrees and then processes each node + /// with `f_propagate` so that the children get processed before their + /// parents. + pub fn traverse_children_this( + mut self, + start_idx: UniIndex, + f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, + f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + ) -> Result<(), Err> { + let mut stack = TreeVisitorStack::new(f_continue, f_propagate); + + stack.stack.push(( + start_idx, + AccessRelatedness::ForeignAccess, + RecursionState::BeforeChildren, + )); + stack.finish_foreign_accesses(&mut self) + } +} From 9622840f78198719da51fc1d3307086865cae5e0 Mon Sep 17 00:00:00 2001 From: Roy Ammerschuber Date: Wed, 3 Dec 2025 12:40:08 +0100 Subject: [PATCH 0285/3801] make tree_visitor generic --- .../src/borrow_tracker/tree_borrows/tree.rs | 96 +++++++++---------- .../tree_borrows/tree_visitor.rs | 51 +++++----- 2 files changed, 75 insertions(+), 72 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 3532e2e0ba86..ca68dc891020 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -20,8 +20,7 @@ use smallvec::SmallVec; use super::Permission; use super::diagnostics::{ - self, AccessCause, NodeDebugInfo, TbError, TransitionError, - no_valid_exposed_references_error, + self, AccessCause, NodeDebugInfo, TbError, TransitionError, no_valid_exposed_references_error, }; use super::foreign_access_skipping::IdempotentForeignAccess; use super::perms::PermTransition; @@ -562,42 +561,43 @@ impl<'tcx> Tree { // Checks the tree containing `idx` for strong protector violations. // It does this in traversal order. let mut check_tree = |idx| { - TreeVisitor { nodes: &mut self.nodes, loc }.traverse_this_parents_children_other( - idx, - // Visit all children, skipping none. - |_| ContinueTraversal::Recurse, - |args: NodeAppArgs<'_>| { - let node = args.nodes.get(args.idx).unwrap(); + TreeVisitor { nodes: &mut self.nodes, data: loc } + .traverse_this_parents_children_other( + idx, + // Visit all children, skipping none. + |_| ContinueTraversal::Recurse, + |args: NodeAppArgs<'_, _>| { + let node = args.nodes.get(args.idx).unwrap(); - let perm = args - .loc - .perms - .get(args.idx) - .copied() - .unwrap_or_else(|| node.default_location_state()); - if global.borrow().protected_tags.get(&node.tag) - == Some(&ProtectorKind::StrongProtector) - // Don't check for protector if it is a Cell (see `unsafe_cell_deallocate` in `interior_mutability.rs`). - // Related to https://github.com/rust-lang/rust/issues/55005. - && !perm.permission.is_cell() - // Only trigger UB if the accessed bit is set, i.e. if the protector is actually protecting this offset. See #4579. - && perm.accessed - { - Err(TbError { - conflicting_info: &node.debug_info, - access_cause: diagnostics::AccessCause::Dealloc, - alloc_id, - error_offset: loc_range.start, - error_kind: TransitionError::ProtectedDealloc, - accessed_info: start_idx - .map(|idx| &args.nodes.get(idx).unwrap().debug_info), + let perm = args + .data + .perms + .get(args.idx) + .copied() + .unwrap_or_else(|| node.default_location_state()); + if global.borrow().protected_tags.get(&node.tag) + == Some(&ProtectorKind::StrongProtector) + // Don't check for protector if it is a Cell (see `unsafe_cell_deallocate` in `interior_mutability.rs`). + // Related to https://github.com/rust-lang/rust/issues/55005. + && !perm.permission.is_cell() + // Only trigger UB if the accessed bit is set, i.e. if the protector is actually protecting this offset. See #4579. + && perm.accessed + { + Err(TbError { + conflicting_info: &node.debug_info, + access_cause: diagnostics::AccessCause::Dealloc, + alloc_id, + error_offset: loc_range.start, + error_kind: TransitionError::ProtectedDealloc, + accessed_info: start_idx + .map(|idx| &args.nodes.get(idx).unwrap().debug_info), + } + .build()) + } else { + Ok(()) } - .build()) - } else { - Ok(()) - } - }, - ) + }, + ) }; // If we have a start index we first check its subtree in traversal order. // This results in us showing the error of the closest node instead of an @@ -967,16 +967,16 @@ impl<'tcx> LocationTree { // // `loc_range` is only for diagnostics (it is the range of // the `RangeMap` on which we are currently working). - let node_skipper = |args: &NodeAppArgs<'_>| -> ContinueTraversal { + let node_skipper = |args: &NodeAppArgs<'_, LocationTree>| -> ContinueTraversal { let node = args.nodes.get(args.idx).unwrap(); - let perm = args.loc.perms.get(args.idx); + let perm = args.data.perms.get(args.idx); let old_state = perm.copied().unwrap_or_else(|| node.default_location_state()); old_state.skip_if_known_noop(access_kind, args.rel_pos) }; - let node_app = |args: NodeAppArgs<'_>| { + let node_app = |args: NodeAppArgs<'_, LocationTree>| { let node = args.nodes.get_mut(args.idx).unwrap(); - let mut perm = args.loc.perms.entry(args.idx); + let mut perm = args.data.perms.entry(args.idx); let state = perm.or_insert(node.default_location_state()); @@ -985,7 +985,7 @@ impl<'tcx> LocationTree { .perform_transition( args.idx, args.nodes, - &mut args.loc.wildcard_accesses, + &mut args.data.wildcard_accesses, access_kind, access_cause, access_range, @@ -1007,7 +1007,7 @@ impl<'tcx> LocationTree { }) }; - let visitor = TreeVisitor { nodes, loc: self }; + let visitor = TreeVisitor { nodes, data: self }; match visit_children { ChildrenVisitMode::VisitChildrenOfAccessed => visitor.traverse_this_parents_children_other(access_source, node_skipper, node_app), @@ -1061,16 +1061,16 @@ impl<'tcx> LocationTree { // marked as having an exposed foreign node, but actually that foreign node cannot be // the source of the access due to `max_local_tag`. The wildcard tracking cannot know // about `max_local_tag` so we will incorrectly assume that this might be a foreign access. - TreeVisitor { loc: self, nodes }.traverse_children_this( + TreeVisitor { data: self, nodes }.traverse_children_this( root, |args| -> ContinueTraversal { let node = args.nodes.get(args.idx).unwrap(); - let perm = args.loc.perms.get(args.idx); + let perm = args.data.perms.get(args.idx); let old_state = perm.copied().unwrap_or_else(|| node.default_location_state()); // If we know where, relative to this node, the wildcard access occurs, // then check if we can skip the entire subtree. - if let Some(relatedness) = get_relatedness(args.idx, node, args.loc) + if let Some(relatedness) = get_relatedness(args.idx, node, args.data) && let Some(relatedness) = relatedness.to_relatedness() { // We can use the usual SIFA machinery to skip nodes. @@ -1084,7 +1084,7 @@ impl<'tcx> LocationTree { let protected = global.borrow().protected_tags.contains_key(&node.tag); - let Some(wildcard_relatedness) = get_relatedness(args.idx, node, args.loc) else { + let Some(wildcard_relatedness) = get_relatedness(args.idx, node, args.data) else { // There doesn't exist a valid exposed reference for this access to // happen through. // This can only happen if `root` is the main root: We set @@ -1105,13 +1105,13 @@ impl<'tcx> LocationTree { return Ok(()); }; - let mut entry = args.loc.perms.entry(args.idx); + let mut entry = args.data.perms.entry(args.idx); let perm = entry.or_insert(node.default_location_state()); // We know the exact relatedness, so we can actually do precise checks. perm.perform_transition( args.idx, args.nodes, - &mut args.loc.wildcard_accesses, + &mut args.data.wildcard_accesses, access_kind, access_cause, access_range, diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree_visitor.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree_visitor.rs index aa9df89180b8..b1ceeecf577d 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree_visitor.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree_visitor.rs @@ -1,23 +1,25 @@ -use super::tree::{AccessRelatedness, LocationTree, Node}; +use std::marker::PhantomData; + +use super::tree::{AccessRelatedness, Node}; use super::unimap::{UniIndex, UniValMap}; /// Data given to the transition function -pub struct NodeAppArgs<'visit> { +pub struct NodeAppArgs<'visit, T> { /// The index of the current node. pub idx: UniIndex, /// Relative position of the access. pub rel_pos: AccessRelatedness, /// The node map of this tree. pub nodes: &'visit mut UniValMap, - /// The permissions map of this tree. - pub loc: &'visit mut LocationTree, + /// Additional data we want to be able to modify in f_propagate and read in f_continue. + pub data: &'visit mut T, } /// Internal contents of `Tree` with the minimum of mutable access for /// For soundness do not modify the children or parent indexes of nodes /// during traversal. -pub struct TreeVisitor<'tree> { +pub struct TreeVisitor<'tree, T> { pub nodes: &'tree mut UniValMap, - pub loc: &'tree mut LocationTree, + pub data: &'tree mut T, } /// Whether to continue exploring the children recursively or not. @@ -41,7 +43,7 @@ enum RecursionState { /// Stack of nodes left to explore in a tree traversal. /// See the docs of `traverse_this_parents_children_other` for details on the /// traversal order. -struct TreeVisitorStack { +struct TreeVisitorStack { /// Function describing whether to continue at a tag. /// This is only invoked for foreign accesses. f_continue: NodeContinue, @@ -56,36 +58,37 @@ struct TreeVisitorStack { /// This is just an artifact of how you hand-roll recursion, /// it does not have a deeper meaning otherwise. stack: Vec<(UniIndex, AccessRelatedness, RecursionState)>, + phantom: PhantomData, } -impl TreeVisitorStack +impl TreeVisitorStack where - NodeContinue: Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - NodeApp: FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + NodeContinue: Fn(&NodeAppArgs<'_, T>) -> ContinueTraversal, + NodeApp: FnMut(NodeAppArgs<'_, T>) -> Result<(), Err>, { fn should_continue_at( &self, - this: &mut TreeVisitor<'_>, + this: &mut TreeVisitor<'_, T>, idx: UniIndex, rel_pos: AccessRelatedness, ) -> ContinueTraversal { - let args = NodeAppArgs { idx, rel_pos, nodes: this.nodes, loc: this.loc }; + let args = NodeAppArgs { idx, rel_pos, nodes: this.nodes, data: this.data }; (self.f_continue)(&args) } fn propagate_at( &mut self, - this: &mut TreeVisitor<'_>, + this: &mut TreeVisitor<'_, T>, idx: UniIndex, rel_pos: AccessRelatedness, ) -> Result<(), Err> { - (self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, loc: this.loc }) + (self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, data: this.data }) } /// Returns the root of this tree. fn go_upwards_from_accessed( &mut self, - this: &mut TreeVisitor<'_>, + this: &mut TreeVisitor<'_, T>, accessed_node: UniIndex, visit_children: ChildrenVisitMode, ) -> Result { @@ -136,7 +139,7 @@ where Ok(last_node) } - fn finish_foreign_accesses(&mut self, this: &mut TreeVisitor<'_>) -> Result<(), Err> { + fn finish_foreign_accesses(&mut self, this: &mut TreeVisitor<'_, T>) -> Result<(), Err> { while let Some((idx, rel_pos, step)) = self.stack.last_mut() { let idx = *idx; let rel_pos = *rel_pos; @@ -173,11 +176,11 @@ where } fn new(f_continue: NodeContinue, f_propagate: NodeApp) -> Self { - Self { f_continue, f_propagate, stack: Vec::new() } + Self { f_continue, f_propagate, stack: Vec::new(), phantom: PhantomData } } } -impl<'tree> TreeVisitor<'tree> { +impl<'tree, T> TreeVisitor<'tree, T> { /// Applies `f_propagate` to every vertex of the tree in a piecewise bottom-up way: First, visit /// all ancestors of `start_idx` (starting with `start_idx` itself), then children of `start_idx`, then the rest, /// going bottom-up in each of these two "pieces" / sections. @@ -219,8 +222,8 @@ impl<'tree> TreeVisitor<'tree> { pub fn traverse_this_parents_children_other( mut self, start_idx: UniIndex, - f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + f_continue: impl Fn(&NodeAppArgs<'_, T>) -> ContinueTraversal, + f_propagate: impl FnMut(NodeAppArgs<'_, T>) -> Result<(), Err>, ) -> Result { let mut stack = TreeVisitorStack::new(f_continue, f_propagate); // Visits the accessed node itself, and all its parents, i.e. all nodes @@ -245,8 +248,8 @@ impl<'tree> TreeVisitor<'tree> { pub fn traverse_nonchildren( mut self, start_idx: UniIndex, - f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + f_continue: impl Fn(&NodeAppArgs<'_, T>) -> ContinueTraversal, + f_propagate: impl FnMut(NodeAppArgs<'_, T>) -> Result<(), Err>, ) -> Result { let mut stack = TreeVisitorStack::new(f_continue, f_propagate); // Visits the accessed node itself, and all its parents, i.e. all nodes @@ -271,8 +274,8 @@ impl<'tree> TreeVisitor<'tree> { pub fn traverse_children_this( mut self, start_idx: UniIndex, - f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, - f_propagate: impl FnMut(NodeAppArgs<'_>) -> Result<(), Err>, + f_continue: impl Fn(&NodeAppArgs<'_, T>) -> ContinueTraversal, + f_propagate: impl FnMut(NodeAppArgs<'_, T>) -> Result<(), Err>, ) -> Result<(), Err> { let mut stack = TreeVisitorStack::new(f_continue, f_propagate); From 69553f73871b1e4b358337bd109174163ecd05be Mon Sep 17 00:00:00 2001 From: reucru01 Date: Thu, 4 Dec 2025 12:18:28 +0000 Subject: [PATCH 0286/3801] Removes excess x86_64 test runs --- library/stdarch/ci/run.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/library/stdarch/ci/run.sh b/library/stdarch/ci/run.sh index f40a305117b8..58d9a60e34f2 100755 --- a/library/stdarch/ci/run.sh +++ b/library/stdarch/ci/run.sh @@ -95,15 +95,6 @@ fi # Test targets compiled with extra features. case ${TARGET} in - x86_64-unknown-linux-gnu) - export STDARCH_DISABLE_ASSERT_INSTR=1 - - export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+avx" - cargo_test - - export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+avx512f" - cargo_test - ;; x86_64* | i686*) export STDARCH_DISABLE_ASSERT_INSTR=1 From 701b9ba0fbaa79bb359a6e4e0377e671b2ffba92 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Dec 2025 14:53:08 +0100 Subject: [PATCH 0287/3801] Merge commit 'dab6863ce82346cf56c88b6f90a146200358207f' into subtree-update_cg_gcc_2025-12-04 --- CONTRIBUTING.md | 37 ++++ Cargo.lock | 4 +- build_system/src/build.rs | 12 +- build_system/src/config.rs | 7 +- build_system/src/test.rs | 6 - src/int.rs | 48 +---- src/intrinsic/mod.rs | 382 ++++++++++++++++-------------------- src/lib.rs | 20 +- tests/lang_tests_common.rs | 14 +- tests/run/int_intrinsics.rs | 72 +++++++ 10 files changed, 324 insertions(+), 278 deletions(-) create mode 100644 tests/run/int_intrinsics.rs diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54cba0e6de37..8f81ecca445a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,6 +25,43 @@ We encourage new contributors to join our communication channels and introduce t ## Understanding Core Concepts +### Sysroot & compilation flags + +#### What *is* the sysroot? +The **sysroot** is the directory that stores the compiled standard +library (`core`, `alloc`, `std`, `test`, …) and compiler built-ins. +Rustup ships these libraries **pre-compiled with LLVM**. + +**rustc_codegen_gcc** replaces LLVM with the GCC backend. + +The freshly compiled sysroot ends up in +`build/build_sysroot/...`. + +A rebuild of sysroot is needed when + +* the backend changes in a way that affects code generation, or +* the user switches toolchains / updates submodules. + +Both backend and sysroot can be built using different [profiles](https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles). +That is exactly what the `--sysroot`, `--release-sysroot` and `--release` flag supported by the build system script `y.sh` take care of. + + +#### Typical flag combinations + +| Command | Backend Profile | Sysroot Profile | Usage Scenario | +|--------------------------------------------|-------------------------------|----------------------------------|------------------------------------------------------------| +| `./y.sh build` |  dev* |  n/a |  Build backend in dev mode with optimized dependencies without rebuilding sysroot | +| `./y.sh build --release` |  release (optimized) |  n/a |  Build backend in release mode with optimized dependencies without rebuilding sysroot | +| `./y.sh build --release --sysroot` |  release (optimized) |  dev |  Build backend in release mode with optimized dependencies and sysroot in dev mode (unoptimized) | +| `./y.sh build --sysroot` |  dev* |  dev |  Build backend in dev mode with optimized dependencies and sysroot in dev mode (unoptimized) | +| `./y.sh build --release-sysroot --sysroot`|  dev* |  release (optimized) |  Build backend in dev mode and sysroot in release mode, both with optimized dependencies | + +\* In `dev` mode, dependencies are compiled with optimizations, while the code of the backend itself is not. + + +Note: `--release-sysroot` must be used together with `--sysroot`. + + ### Common Development Tasks #### Running Specific Tests diff --git a/Cargo.lock b/Cargo.lock index 00bdacaca676..dea1207b05da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,9 +65,9 @@ dependencies = [ [[package]] name = "gccjit_sys" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "263da4f60b7bb5d6a5b21efda961741051ebdbf0e380a09118b03cce66a8c77e" +checksum = "4f81d901767ddba371a619fa9bba657066a4d3c5607ee69bbb557c1c5ba9bf85" dependencies = [ "libc", ] diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 56503b239a3b..27476465d740 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -46,8 +46,16 @@ impl BuildArg { println!( r#" `build` command help: - - --sysroot : Build with sysroot"# + --sysroot : When used on its own, build backend in dev mode with optimized dependencies + and sysroot in dev mode (unoptimized) + When used together with --release, build backend in release mode with optimized dependencies + When used together with --release-sysroot, + build the sysroot in release mode with optimized dependencies instead of in dev mode + --release-sysroot : When combined with --sysroot, additionally + build the sysroot in release mode with optimized dependencies. + It has no effect if `--sysroot` is not specified. + It should not be used on its own. + --sysroot-panic-abort : Build the sysroot without unwinding support"# ); ConfigInfo::show_usage(); println!(" --help : Show this help"); diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 19255e1ba2b2..8eb6d8f019e1 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -459,14 +459,11 @@ impl ConfigInfo { pub fn show_usage() { println!( - "\ - --features [arg] : Add a new feature [arg] + " --features [arg] : Add a new feature [arg] --target-triple [arg] : Set the target triple to [arg] --target [arg] : Set the target to [arg] + --release : Build backend in release mode with optimized dependencies --out-dir : Location where the files will be generated - --release : Build in release mode - --release-sysroot : Build sysroot in release mode - --sysroot-panic-abort : Build the sysroot without unwinding support --config-file : Location of the config file to be used --gcc-path : Location of the GCC root folder --cg_gcc-path : Location of the rustc_codegen_gcc root folder (used diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 8aabfa894ce0..ca2a2a7dc2de 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -64,8 +64,6 @@ fn show_usage() { r#" `test` command help: - --release : Build codegen in release mode - --sysroot-panic-abort : Build the sysroot without unwinding support. --features [arg] : Add a new feature [arg] --use-system-gcc : Use system installed libgccjit --build-only : Only build rustc_codegen_gcc then exits @@ -92,7 +90,6 @@ struct TestArg { test_args: Vec, nb_parts: Option, current_part: Option, - sysroot_panic_abort: bool, config_info: ConfigInfo, sysroot_features: Vec, keep_lto_tests: bool, @@ -128,9 +125,6 @@ impl TestArg { test_arg.current_part = Some(get_number_after_arg(&mut args, "--current-part")?); } - "--sysroot-panic-abort" => { - test_arg.sysroot_panic_abort = true; - } "--keep-lto-tests" => { test_arg.keep_lto_tests = true; } diff --git a/src/int.rs b/src/int.rs index aa1d3b6b091c..49de0b490e88 100644 --- a/src/int.rs +++ b/src/int.rs @@ -287,51 +287,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // TODO(antoyo): remove duplication with intrinsic? let name = if self.is_native_int_type(lhs.get_type()) { match oop { - OverflowOp::Add => match new_kind { - Int(I8) => "__builtin_add_overflow", - Int(I16) => "__builtin_add_overflow", - Int(I32) => "__builtin_sadd_overflow", - Int(I64) => "__builtin_saddll_overflow", - Int(I128) => "__builtin_add_overflow", - - Uint(U8) => "__builtin_add_overflow", - Uint(U16) => "__builtin_add_overflow", - Uint(U32) => "__builtin_uadd_overflow", - Uint(U64) => "__builtin_uaddll_overflow", - Uint(U128) => "__builtin_add_overflow", - - _ => unreachable!(), - }, - OverflowOp::Sub => match new_kind { - Int(I8) => "__builtin_sub_overflow", - Int(I16) => "__builtin_sub_overflow", - Int(I32) => "__builtin_ssub_overflow", - Int(I64) => "__builtin_ssubll_overflow", - Int(I128) => "__builtin_sub_overflow", - - Uint(U8) => "__builtin_sub_overflow", - Uint(U16) => "__builtin_sub_overflow", - Uint(U32) => "__builtin_usub_overflow", - Uint(U64) => "__builtin_usubll_overflow", - Uint(U128) => "__builtin_sub_overflow", - - _ => unreachable!(), - }, - OverflowOp::Mul => match new_kind { - Int(I8) => "__builtin_mul_overflow", - Int(I16) => "__builtin_mul_overflow", - Int(I32) => "__builtin_smul_overflow", - Int(I64) => "__builtin_smulll_overflow", - Int(I128) => "__builtin_mul_overflow", - - Uint(U8) => "__builtin_mul_overflow", - Uint(U16) => "__builtin_mul_overflow", - Uint(U32) => "__builtin_umul_overflow", - Uint(U64) => "__builtin_umulll_overflow", - Uint(U128) => "__builtin_mul_overflow", - - _ => unreachable!(), - }, + OverflowOp::Add => "__builtin_add_overflow", + OverflowOp::Sub => "__builtin_sub_overflow", + OverflowOp::Mul => "__builtin_mul_overflow", } } else { let (func_name, width) = match oop { diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 8225df568641..23d16eda030c 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -441,43 +441,15 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc | sym::saturating_sub => { match int_type_width_signed(args[0].layout.ty, self) { Some((width, signed)) => match name { - sym::ctlz | sym::cttz => { - let func = self.current_func(); - let then_block = func.new_block("then"); - let else_block = func.new_block("else"); - let after_block = func.new_block("after"); + sym::ctlz => self.count_leading_zeroes(width, args[0].immediate()), - let arg = args[0].immediate(); - let result = func.new_local(None, self.u32_type, "zeros"); - let zero = self.cx.gcc_zero(arg.get_type()); - let cond = self.gcc_icmp(IntPredicate::IntEQ, arg, zero); - self.llbb().end_with_conditional(None, cond, then_block, else_block); - - let zero_result = self.cx.gcc_uint(self.u32_type, width); - then_block.add_assignment(None, result, zero_result); - then_block.end_with_jump(None, after_block); - - // NOTE: since jumps were added in a place - // count_leading_zeroes() does not expect, the current block - // in the state need to be updated. - self.switch_to_block(else_block); - - let zeros = match name { - sym::ctlz => self.count_leading_zeroes(width, arg), - sym::cttz => self.count_trailing_zeroes(width, arg), - _ => unreachable!(), - }; - self.llbb().add_assignment(None, result, zeros); - self.llbb().end_with_jump(None, after_block); - - // NOTE: since jumps were added in a place rustc does not - // expect, the current block in the state need to be updated. - self.switch_to_block(after_block); - - result.to_rvalue() + sym::ctlz_nonzero => { + self.count_leading_zeroes_nonzero(width, args[0].immediate()) + } + sym::cttz => self.count_trailing_zeroes(width, args[0].immediate()), + sym::cttz_nonzero => { + self.count_trailing_zeroes_nonzero(width, args[0].immediate()) } - sym::ctlz_nonzero => self.count_leading_zeroes(width, args[0].immediate()), - sym::cttz_nonzero => self.count_trailing_zeroes(width, args[0].immediate()), sym::ctpop => self.pop_count(args[0].immediate()), sym::bswap => { if width == 8 { @@ -912,179 +884,175 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.gcc_int_cast(result, result_type) } - fn count_leading_zeroes(&mut self, width: u64, arg: RValue<'gcc>) -> RValue<'gcc> { - // TODO(antoyo): use width? - let arg_type = arg.get_type(); - let result_type = self.u32_type; - let arg = if arg_type.is_signed(self.cx) { - let new_type = arg_type.to_unsigned(self.cx); - self.gcc_int_cast(arg, new_type) + fn count_zeroes(&mut self, width: u64, arg: RValue<'gcc>, count_leading: bool) -> RValue<'gcc> { + // if arg is 0, early return 0, else call count_leading_zeroes_nonzero or count_trailing_zeroes_nonzero + let func = self.current_func(); + let then_block = func.new_block("then"); + let else_block = func.new_block("else"); + let after_block = func.new_block("after"); + + let result = func.new_local(None, self.u32_type, "zeros"); + let zero = self.cx.gcc_zero(arg.get_type()); + let cond = self.gcc_icmp(IntPredicate::IntEQ, arg, zero); + self.llbb().end_with_conditional(None, cond, then_block, else_block); + + let zero_result = self.cx.gcc_uint(self.u32_type, width); + then_block.add_assignment(None, result, zero_result); + then_block.end_with_jump(None, after_block); + + // NOTE: since jumps were added in a place count_xxxxing_zeroes_nonzero() does not expect, + // the current block in the state need to be updated. + self.switch_to_block(else_block); + + let zeros = if count_leading { + self.count_leading_zeroes_nonzero(width, arg) } else { - arg + self.count_trailing_zeroes_nonzero(width, arg) }; - let arg_type = arg.get_type(); - let count_leading_zeroes = - // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here - // instead of using is_uint(). - if arg_type.is_uchar(self.cx) || arg_type.is_ushort(self.cx) || arg_type.is_uint(self.cx) { - "__builtin_clz" - } - else if arg_type.is_ulong(self.cx) { - "__builtin_clzl" - } - else if arg_type.is_ulonglong(self.cx) { - "__builtin_clzll" - } - else if width == 128 { - // Algorithm from: https://stackoverflow.com/a/28433850/389119 - let array_type = self.context.new_array_type(None, arg_type, 3); - let result = self.current_func() - .new_local(None, array_type, "count_loading_zeroes_results"); + self.llbb().add_assignment(None, result, zeros); + self.llbb().end_with_jump(None, after_block); - let sixty_four = self.const_uint(arg_type, 64); - let shift = self.lshr(arg, sixty_four); - let high = self.gcc_int_cast(shift, self.u64_type); - let low = self.gcc_int_cast(arg, self.u64_type); + // NOTE: since jumps were added in a place rustc does not + // expect, the current block in the state need to be updated. + self.switch_to_block(after_block); - let zero = self.context.new_rvalue_zero(self.usize_type); - let one = self.context.new_rvalue_one(self.usize_type); - let two = self.context.new_rvalue_from_long(self.usize_type, 2); - - let clzll = self.context.get_builtin_function("__builtin_clzll"); - - let first_elem = self.context.new_array_access(None, result, zero); - let first_value = self.gcc_int_cast(self.context.new_call(None, clzll, &[high]), arg_type); - self.llbb() - .add_assignment(self.location, first_elem, first_value); - - let second_elem = self.context.new_array_access(self.location, result, one); - let cast = self.gcc_int_cast(self.context.new_call(self.location, clzll, &[low]), arg_type); - let second_value = self.add(cast, sixty_four); - self.llbb() - .add_assignment(self.location, second_elem, second_value); - - let third_elem = self.context.new_array_access(self.location, result, two); - let third_value = self.const_uint(arg_type, 128); - self.llbb() - .add_assignment(self.location, third_elem, third_value); - - let not_high = self.context.new_unary_op(self.location, UnaryOp::LogicalNegate, self.u64_type, high); - let not_low = self.context.new_unary_op(self.location, UnaryOp::LogicalNegate, self.u64_type, low); - let not_low_and_not_high = not_low & not_high; - let index = not_high + not_low_and_not_high; - // NOTE: the following cast is necessary to avoid a GIMPLE verification failure in - // gcc. - // TODO(antoyo): do the correct verification in libgccjit to avoid an error at the - // compilation stage. - let index = self.context.new_cast(self.location, index, self.i32_type); - - let res = self.context.new_array_access(self.location, result, index); - - return self.gcc_int_cast(res.to_rvalue(), result_type); - } - else { - let count_leading_zeroes = self.context.get_builtin_function("__builtin_clzll"); - let arg = self.context.new_cast(self.location, arg, self.ulonglong_type); - let diff = self.ulonglong_type.get_size() as i64 - arg_type.get_size() as i64; - let diff = self.context.new_rvalue_from_long(self.int_type, diff * 8); - let res = self.context.new_call(self.location, count_leading_zeroes, &[arg]) - diff; - return self.context.new_cast(self.location, res, result_type); - }; - let count_leading_zeroes = self.context.get_builtin_function(count_leading_zeroes); - let res = self.context.new_call(self.location, count_leading_zeroes, &[arg]); - self.context.new_cast(self.location, res, result_type) + result.to_rvalue() } - fn count_trailing_zeroes(&mut self, _width: u64, arg: RValue<'gcc>) -> RValue<'gcc> { - let arg_type = arg.get_type(); - let result_type = self.u32_type; - let arg = if arg_type.is_signed(self.cx) { - let new_type = arg_type.to_unsigned(self.cx); - self.gcc_int_cast(arg, new_type) - } else { - arg - }; - let arg_type = arg.get_type(); - let (count_trailing_zeroes, expected_type) = - // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here - // instead of using is_uint(). - if arg_type.is_uchar(self.cx) || arg_type.is_ushort(self.cx) || arg_type.is_uint(self.cx) { - // NOTE: we don't need to & 0xFF for uchar because the result is undefined on zero. - ("__builtin_ctz", self.cx.uint_type) - } - else if arg_type.is_ulong(self.cx) { - ("__builtin_ctzl", self.cx.ulong_type) - } - else if arg_type.is_ulonglong(self.cx) { - ("__builtin_ctzll", self.cx.ulonglong_type) - } - else if arg_type.is_u128(self.cx) { - // Adapted from the algorithm to count leading zeroes from: https://stackoverflow.com/a/28433850/389119 - let array_type = self.context.new_array_type(None, arg_type, 3); - let result = self.current_func() - .new_local(None, array_type, "count_loading_zeroes_results"); - - let sixty_four = self.gcc_int(arg_type, 64); - let shift = self.gcc_lshr(arg, sixty_four); - let high = self.gcc_int_cast(shift, self.u64_type); - let low = self.gcc_int_cast(arg, self.u64_type); - - let zero = self.context.new_rvalue_zero(self.usize_type); - let one = self.context.new_rvalue_one(self.usize_type); - let two = self.context.new_rvalue_from_long(self.usize_type, 2); - - let ctzll = self.context.get_builtin_function("__builtin_ctzll"); - - let first_elem = self.context.new_array_access(self.location, result, zero); - let first_value = self.gcc_int_cast(self.context.new_call(self.location, ctzll, &[low]), arg_type); - self.llbb() - .add_assignment(self.location, first_elem, first_value); - - let second_elem = self.context.new_array_access(self.location, result, one); - let second_value = self.gcc_add(self.gcc_int_cast(self.context.new_call(self.location, ctzll, &[high]), arg_type), sixty_four); - self.llbb() - .add_assignment(self.location, second_elem, second_value); - - let third_elem = self.context.new_array_access(self.location, result, two); - let third_value = self.gcc_int(arg_type, 128); - self.llbb() - .add_assignment(self.location, third_elem, third_value); - - let not_low = self.context.new_unary_op(self.location, UnaryOp::LogicalNegate, self.u64_type, low); - let not_high = self.context.new_unary_op(self.location, UnaryOp::LogicalNegate, self.u64_type, high); - let not_low_and_not_high = not_low & not_high; - let index = not_low + not_low_and_not_high; - // NOTE: the following cast is necessary to avoid a GIMPLE verification failure in - // gcc. - // TODO(antoyo): do the correct verification in libgccjit to avoid an error at the - // compilation stage. - let index = self.context.new_cast(self.location, index, self.i32_type); - - let res = self.context.new_array_access(self.location, result, index); - - return self.gcc_int_cast(res.to_rvalue(), result_type); - } - else { - let count_trailing_zeroes = self.context.get_builtin_function("__builtin_ctzll"); - let arg_size = arg_type.get_size(); - let casted_arg = self.context.new_cast(self.location, arg, self.ulonglong_type); - let byte_diff = self.ulonglong_type.get_size() as i64 - arg_size as i64; - let diff = self.context.new_rvalue_from_long(self.int_type, byte_diff * 8); - let mask = self.context.new_rvalue_from_long(arg_type, -1); // To get the value with all bits set. - let masked = mask & self.context.new_unary_op(self.location, UnaryOp::BitwiseNegate, arg_type, arg); - let cond = self.context.new_comparison(self.location, ComparisonOp::Equals, masked, mask); - let diff = diff * self.context.new_cast(self.location, cond, self.int_type); - let res = self.context.new_call(self.location, count_trailing_zeroes, &[casted_arg]) - diff; - return self.context.new_cast(self.location, res, result_type); + fn count_zeroes_nonzero( + &mut self, + width: u64, + arg: RValue<'gcc>, + count_leading: bool, + ) -> RValue<'gcc> { + // Pre-condition: arg is guaranteed to not be 0 by caller + fn use_builtin_function<'a, 'gcc, 'tcx>( + builder: &mut Builder<'a, 'gcc, 'tcx>, + builtin: &str, + arg: RValue<'gcc>, + arg_type: gccjit::Type<'gcc>, + expected_type: gccjit::Type<'gcc>, + ) -> RValue<'gcc> { + let arg = if arg_type != expected_type { + builder.context.new_cast(builder.location, arg, expected_type) + } else { + arg }; - let count_trailing_zeroes = self.context.get_builtin_function(count_trailing_zeroes); - let arg = if arg_type != expected_type { - self.context.new_cast(self.location, arg, expected_type) + let builtin = builder.context.get_builtin_function(builtin); + let res = builder.context.new_call(builder.location, builtin, &[arg]); + builder.context.new_cast(builder.location, res, builder.u32_type) + } + + // TODO(antoyo): use width? + let result_type = self.u32_type; + let mut arg_type = arg.get_type(); + let arg = if arg_type.is_signed(self.cx) { + arg_type = arg_type.to_unsigned(self.cx); + self.gcc_int_cast(arg, arg_type) } else { arg }; - let res = self.context.new_call(self.location, count_trailing_zeroes, &[arg]); - self.context.new_cast(self.location, res, result_type) + // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here + // instead of using is_uint(). + if arg_type.is_uchar(self.cx) || arg_type.is_ushort(self.cx) || arg_type.is_uint(self.cx) { + let builtin = if count_leading { "__builtin_clz" } else { "__builtin_ctz" }; + use_builtin_function(self, builtin, arg, arg_type, self.cx.uint_type) + } else if arg_type.is_ulong(self.cx) { + let builtin = if count_leading { "__builtin_clzl" } else { "__builtin_ctzl" }; + use_builtin_function(self, builtin, arg, arg_type, self.cx.uint_type) + } else if arg_type.is_ulonglong(self.cx) { + let builtin = if count_leading { "__builtin_clzll" } else { "__builtin_ctzll" }; + use_builtin_function(self, builtin, arg, arg_type, self.cx.uint_type) + } else if width == 128 { + // arg is guaranteed to not be 0, so either its 64 high or 64 low bits are not 0 + // __buildin_clzll is UB when called with 0, so call it on the 64 high bits if they are not 0, + // else call it on the 64 low bits and add 64. In the else case, 64 low bits can't be 0 + // because arg is not 0. + // __buildin_ctzll is UB when called with 0, so call it on the 64 low bits if they are not 0, + // else call it on the 64 high bits and add 64. In the else case, 64 high bits can't be 0 + // because arg is not 0. + + let result = self.current_func().new_local(None, result_type, "count_zeroes_results"); + + let cz_then_block = self.current_func().new_block("cz_then"); + let cz_else_block = self.current_func().new_block("cz_else"); + let cz_after_block = self.current_func().new_block("cz_after"); + + let low = self.gcc_int_cast(arg, self.u64_type); + let sixty_four = self.const_uint(arg_type, 64); + let shift = self.lshr(arg, sixty_four); + let high = self.gcc_int_cast(shift, self.u64_type); + + let (first, second, builtin) = if count_leading { + (low, high, self.context.get_builtin_function("__builtin_clzll")) + } else { + (high, low, self.context.get_builtin_function("__builtin_ctzll")) + }; + + let zero_64 = self.const_uint(self.u64_type, 0); + let cond = self.gcc_icmp(IntPredicate::IntNE, second, zero_64); + self.llbb().end_with_conditional(self.location, cond, cz_then_block, cz_else_block); + self.switch_to_block(cz_then_block); + + let result_128 = + self.gcc_int_cast(self.context.new_call(None, builtin, &[second]), result_type); + + cz_then_block.add_assignment(self.location, result, result_128); + cz_then_block.end_with_jump(self.location, cz_after_block); + + self.switch_to_block(cz_else_block); + let count_more_zeroes = + self.gcc_int_cast(self.context.new_call(None, builtin, &[first]), result_type); + let sixty_four_result_type = self.const_uint(result_type, 64); + let count_result_type = self.add(count_more_zeroes, sixty_four_result_type); + cz_else_block.add_assignment(self.location, result, count_result_type); + cz_else_block.end_with_jump(self.location, cz_after_block); + self.switch_to_block(cz_after_block); + result.to_rvalue() + } else { + let byte_diff = self.ulonglong_type.get_size() as i64 - arg_type.get_size() as i64; + let diff = self.context.new_rvalue_from_long(self.int_type, byte_diff * 8); + let ull_arg = self.context.new_cast(self.location, arg, self.ulonglong_type); + + let res = if count_leading { + let count_leading_zeroes = self.context.get_builtin_function("__builtin_clzll"); + self.context.new_call(self.location, count_leading_zeroes, &[ull_arg]) - diff + } else { + let count_trailing_zeroes = self.context.get_builtin_function("__builtin_ctzll"); + let mask = self.context.new_rvalue_from_long(arg_type, -1); // To get the value with all bits set. + let masked = mask + & self.context.new_unary_op( + self.location, + UnaryOp::BitwiseNegate, + arg_type, + arg, + ); + let cond = + self.context.new_comparison(self.location, ComparisonOp::Equals, masked, mask); + let diff = diff * self.context.new_cast(self.location, cond, self.int_type); + + self.context.new_call(self.location, count_trailing_zeroes, &[ull_arg]) - diff + }; + self.context.new_cast(self.location, res, result_type) + } + } + + fn count_leading_zeroes(&mut self, width: u64, arg: RValue<'gcc>) -> RValue<'gcc> { + self.count_zeroes(width, arg, true) + } + + fn count_leading_zeroes_nonzero(&mut self, width: u64, arg: RValue<'gcc>) -> RValue<'gcc> { + // Pre-condition: arg is guaranteed to not be 0 by caller, else count_leading_zeros should be used + self.count_zeroes_nonzero(width, arg, true) + } + + fn count_trailing_zeroes(&mut self, width: u64, arg: RValue<'gcc>) -> RValue<'gcc> { + self.count_zeroes(width, arg, false) + } + + fn count_trailing_zeroes_nonzero(&mut self, width: u64, arg: RValue<'gcc>) -> RValue<'gcc> { + // Pre-condition: arg is guaranteed to not be 0 by caller, else count_trailing_zeros should be used + self.count_zeroes_nonzero(width, arg, false) } fn pop_count(&mut self, value: RValue<'gcc>) -> RValue<'gcc> { @@ -1196,14 +1164,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let res = func.new_local(self.location, result_type, "saturating_sum"); let supports_native_type = self.is_native_int_type(result_type); let overflow = if supports_native_type { - let func_name = match width { - 8 => "__builtin_add_overflow", - 16 => "__builtin_add_overflow", - 32 => "__builtin_sadd_overflow", - 64 => "__builtin_saddll_overflow", - 128 => "__builtin_add_overflow", - _ => unreachable!(), - }; + let func_name = "__builtin_add_overflow"; let overflow_func = self.context.get_builtin_function(func_name); self.overflow_call(overflow_func, &[lhs, rhs, res.get_address(self.location)], None) } else { @@ -1267,14 +1228,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let res = func.new_local(self.location, result_type, "saturating_diff"); let supports_native_type = self.is_native_int_type(result_type); let overflow = if supports_native_type { - let func_name = match width { - 8 => "__builtin_sub_overflow", - 16 => "__builtin_sub_overflow", - 32 => "__builtin_ssub_overflow", - 64 => "__builtin_ssubll_overflow", - 128 => "__builtin_sub_overflow", - _ => unreachable!(), - }; + let func_name = "__builtin_sub_overflow"; let overflow_func = self.context.get_builtin_function(func_name); self.overflow_call(overflow_func, &[lhs, rhs, res.get_address(self.location)], None) } else { diff --git a/src/lib.rs b/src/lib.rs index 662e303f94f2..c1506ee6176f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,7 @@ mod type_of; use std::any::Any; use std::ffi::CString; use std::fmt::Debug; +use std::fs; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; @@ -180,14 +181,18 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); +fn libgccjit_path(sysroot_path: &Path) -> PathBuf { + let sysroot_lib_dir = sysroot_path.join("lib"); + sysroot_lib_dir.join("libgccjit.so") +} + fn load_libgccjit_if_needed(sysroot_path: &Path) { if gccjit::is_loaded() { // Do not load a libgccjit second time. return; } - let sysroot_lib_dir = sysroot_path.join("lib"); - let libgccjit_target_lib_file = sysroot_lib_dir.join("libgccjit.so"); + let libgccjit_target_lib_file = libgccjit_path(sysroot_path); let path = libgccjit_target_lib_file.to_str().expect("libgccjit path"); let string = CString::new(path).expect("string to libgccjit path"); @@ -207,7 +212,16 @@ impl CodegenBackend for GccCodegenBackend { } fn init(&self, sess: &Session) { - load_libgccjit_if_needed(sess.opts.sysroot.path()); + // We use all_paths() instead of only path() in case the path specified by --sysroot is + // invalid. + // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. + for path in sess.opts.sysroot.all_paths() { + let libgccjit_target_lib_file = libgccjit_path(path); + if let Ok(true) = fs::exists(libgccjit_target_lib_file) { + load_libgccjit_if_needed(path); + break; + } + } #[cfg(feature = "master")] { diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index 311f256b7600..0f2cb9231062 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -91,7 +91,19 @@ pub fn main_inner(profile: Profile) { } } match profile { - Profile::Debug => {} + Profile::Debug => { + if test_target.is_ok() { + // m68k doesn't have lubsan for now + compiler.args(["-C", "llvm-args=sanitize-undefined"]); + } else { + compiler.args([ + "-C", + "llvm-args=sanitize-undefined", + "-C", + "link-args=-lubsan", + ]); + } + } Profile::Release => { compiler.args(["-C", "opt-level=3", "-C", "lto=no"]); } diff --git a/tests/run/int_intrinsics.rs b/tests/run/int_intrinsics.rs new file mode 100644 index 000000000000..c3d363c8428b --- /dev/null +++ b/tests/run/int_intrinsics.rs @@ -0,0 +1,72 @@ +// Compiler: +// +// Run-time: +#![feature(core_intrinsics, intrinsics)] +#![no_main] + +use std::intrinsics::black_box; + +#[rustc_intrinsic] +pub const fn ctlz(_x: T) -> u32; + +#[rustc_intrinsic] +pub const fn cttz(_x: T) -> u32; + +#[no_mangle] +extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { + macro_rules! check { + ($func_name:ident, $input:expr, $expected:expr, $res_ident:ident) => {{ + $res_ident += 1; + if $func_name(black_box($input)) != $expected { + return $res_ident; + } + }}; + } + let mut res = 0; + check!(ctlz, 0_u128, 128_u32, res); + check!(ctlz, 1_u128, 127_u32, res); + check!(ctlz, 0x4000_0000_0000_0000_0000_0000_0000_0000_u128, 1_u32, res); + check!(ctlz, 0x8000_0000_0000_0000_0000_0000_0000_0000_u128, 0_u32, res); + check!(cttz, 0_u128, 128_u32, res); + check!(cttz, 1_u128, 0_u32, res); + check!(cttz, 2_u128, 1_u32, res); + check!(cttz, 0x8000_0000_0000_0000_0000_0000_0000_0000_u128, 127_u32, res); + + check!(ctlz, 0_u64, 64_u32, res); + check!(ctlz, 1_u64, 63_u32, res); + check!(ctlz, 0x4000_0000_0000_0000_u64, 1_u32, res); + check!(ctlz, 0x8000_0000_0000_0000_u64, 0_u32, res); + check!(cttz, 0_u64, 64_u32, res); + check!(cttz, 1_u64, 0_u32, res); + check!(cttz, 2_u64, 1_u32, res); + check!(cttz, 0x8000_0000_0000_0000_u64, 63_u32, res); + + check!(ctlz, 0_u32, 32_u32, res); + check!(ctlz, 1_u32, 31_u32, res); + check!(ctlz, 0x4000_0000_u32, 1_u32, res); + check!(ctlz, 0x8000_0000_u32, 0_u32, res); + check!(cttz, 0_u32, 32_u32, res); + check!(cttz, 1_u32, 0_u32, res); + check!(cttz, 2_u32, 1_u32, res); + check!(cttz, 0x8000_0000_u32, 31_u32, res); + + check!(ctlz, 0_u16, 16_u32, res); + check!(ctlz, 1_u16, 15_u32, res); + check!(ctlz, 0x4000_u16, 1_u32, res); + check!(ctlz, 0x8000_u16, 0_u32, res); + check!(cttz, 0_u16, 16_u32, res); + check!(cttz, 1_u16, 0_u32, res); + check!(cttz, 2_u16, 1_u32, res); + check!(cttz, 0x8000_u16, 15_u32, res); + + check!(ctlz, 0_u8, 8_u32, res); + check!(ctlz, 1_u8, 7_u32, res); + check!(ctlz, 0x40_u8, 1_u32, res); + check!(ctlz, 0x80_u8, 0_u32, res); + check!(cttz, 0_u8, 8_u32, res); + check!(cttz, 1_u8, 0_u32, res); + check!(cttz, 2_u8, 1_u32, res); + check!(cttz, 0x80_u8, 7_u32, res); + + 0 +} From 1b71459736bdf6f3a4b9401ab5ed236c066f2865 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 12 Nov 2025 11:57:00 +0100 Subject: [PATCH 0288/3801] emit WF goals in relate, not in generalize --- .../src/polonius/liveness_constraints.rs | 19 ++- .../src/type_check/relate_tys.rs | 27 +++- .../src/infer/outlives/test_type_match.rs | 20 +++ .../src/infer/relate/generalize.rs | 118 +++++------------- .../rustc_infer/src/infer/relate/lattice.rs | 16 ++- .../src/infer/relate/type_relating.rs | 28 +++-- .../rustc_lint/src/impl_trait_overcaptures.rs | 17 ++- .../src/error_reporting/infer/mod.rs | 13 ++ .../src/traits/select/_match.rs | 14 +++ compiler/rustc_type_ir/src/relate.rs | 68 ++++------ compiler/rustc_type_ir/src/relate/combine.rs | 75 +++++++++++ .../src/relate/solver_relating.rs | 23 ++-- .../subtype-obligations-bivariant-args.rs | 52 ++++++++ 13 files changed, 335 insertions(+), 155 deletions(-) create mode 100644 tests/ui/traits/next-solver/generalize/subtype-obligations-bivariant-args.rs diff --git a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs index 2ba72180d66a..f1338b3bf1ee 100644 --- a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs +++ b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs @@ -1,8 +1,11 @@ use std::collections::BTreeMap; +use rustc_hir::def_id::DefId; use rustc_index::bit_set::SparseBitMatrix; use rustc_middle::mir::{Body, Location}; -use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::relate::{ + self, Relate, RelateResult, TypeRelation, relate_args_with_variances, +}; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeVisitable}; use rustc_mir_dataflow::points::PointIndex; @@ -256,6 +259,20 @@ impl<'tcx> TypeRelation> for VarianceExtractor<'_, 'tcx> { self.tcx } + fn relate_ty_args( + &mut self, + a_ty: Ty<'tcx>, + _: Ty<'tcx>, + def_id: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { + let variances = self.cx().variances_of(def_id); + relate_args_with_variances(self, variances, a_args, b_args)?; + Ok(a_ty) + } + fn relate_with_variance>>( &mut self, variance: ty::Variance, diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 7ac2dff12f75..18d5922f27d1 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,5 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; +use rustc_hir::def_id::DefId; use rustc_infer::infer::relate::{ PredicateEmittingRelation, Relate, RelateResult, StructurallyRelateAliases, TypeRelation, }; @@ -9,7 +10,7 @@ use rustc_infer::traits::solve::Goal; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; -use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys}; +use rustc_middle::ty::relate::combine::{combine_ty_args, super_combine_consts, super_combine_tys}; use rustc_middle::ty::{self, FnMutDelegate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; @@ -303,6 +304,28 @@ impl<'b, 'tcx> TypeRelation> for NllTypeRelating<'_, 'b, 'tcx> { self.type_checker.infcx.tcx } + fn relate_ty_args( + &mut self, + a_ty: Ty<'tcx>, + b_ty: Ty<'tcx>, + def_id: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { + let variances = self.cx().variances_of(def_id); + combine_ty_args( + &self.type_checker.infcx.infcx, + self, + a_ty, + b_ty, + variances, + a_args, + b_args, + |_| a_ty, + ) + } + #[instrument(skip(self, info), level = "trace", ret)] fn relate_with_variance>>( &mut self, @@ -328,7 +351,7 @@ impl<'b, 'tcx> TypeRelation> for NllTypeRelating<'_, 'b, 'tcx> { fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { let infcx = self.type_checker.infcx; - let a = self.type_checker.infcx.shallow_resolve(a); + let a = infcx.shallow_resolve(a); assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b); if a == b { diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index 6592360cf0a5..7be5daf61056 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -1,8 +1,10 @@ use std::collections::hash_map::Entry; use rustc_data_structures::fx::FxHashMap; +use rustc_hir::def_id::DefId; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_type_ir::relate::relate_args_with_variances; use tracing::instrument; use crate::infer::region_constraints::VerifyIfEq; @@ -137,6 +139,20 @@ impl<'tcx> TypeRelation> for MatchAgainstHigherRankedOutlives<'tcx> self.tcx } + fn relate_ty_args( + &mut self, + a_ty: Ty<'tcx>, + _: Ty<'tcx>, + def_id: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { + let variances = self.cx().variances_of(def_id); + relate_args_with_variances(self, variances, a_args, b_args)?; + Ok(a_ty) + } + #[instrument(level = "trace", skip(self))] fn relate_with_variance>>( &mut self, @@ -145,6 +161,10 @@ impl<'tcx> TypeRelation> for MatchAgainstHigherRankedOutlives<'tcx> a: T, b: T, ) -> RelateResult<'tcx, T> { + // FIXME(@lcnr): This is weird. We are ignoring the ambient variance + // here, effectively treating everything as being in either a covariant + // or contravariant context. + // // Opaque types args have lifetime parameters. // We must not check them to be equal, as we never insert anything to make them so. if variance != ty::Bivariant { self.relate(a, b) } else { Ok(a) } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index cc41957c110f..69c090b662e5 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -70,14 +70,13 @@ impl<'tcx> InferCtxt<'tcx> { // // We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and // `?1 <: ?3`. - let Generalization { value_may_be_infer: generalized_ty, has_unconstrained_ty_var } = self - .generalize( - relation.span(), - relation.structurally_relate_aliases(), - target_vid, - instantiation_variance, - source_ty, - )?; + let Generalization { value_may_be_infer: generalized_ty } = self.generalize( + relation.span(), + relation.structurally_relate_aliases(), + target_vid, + instantiation_variance, + source_ty, + )?; // Constrain `b_vid` to the generalized type `generalized_ty`. if let &ty::Infer(ty::TyVar(generalized_vid)) = generalized_ty.kind() { @@ -86,11 +85,6 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow_mut().type_variables().instantiate(target_vid, generalized_ty); } - // See the comment on `Generalization::has_unconstrained_ty_var`. - if has_unconstrained_ty_var { - relation.register_predicates([ty::ClauseKind::WellFormed(generalized_ty.into())]); - } - // Finally, relate `generalized_ty` to `source_ty`, as described in previous comment. // // FIXME(#16847): This code is non-ideal because all these subtype @@ -210,19 +204,15 @@ impl<'tcx> InferCtxt<'tcx> { ) -> RelateResult<'tcx, ()> { // FIXME(generic_const_exprs): Occurs check failures for unevaluated // constants and generic expressions are not yet handled correctly. - let Generalization { value_may_be_infer: generalized_ct, has_unconstrained_ty_var } = self - .generalize( - relation.span(), - relation.structurally_relate_aliases(), - target_vid, - ty::Invariant, - source_ct, - )?; + let Generalization { value_may_be_infer: generalized_ct } = self.generalize( + relation.span(), + relation.structurally_relate_aliases(), + target_vid, + ty::Invariant, + source_ct, + )?; debug_assert!(!generalized_ct.is_ct_infer()); - if has_unconstrained_ty_var { - bug!("unconstrained ty var when generalizing `{source_ct:?}`"); - } self.inner .borrow_mut() @@ -281,12 +271,10 @@ impl<'tcx> InferCtxt<'tcx> { ambient_variance, in_alias: false, cache: Default::default(), - has_unconstrained_ty_var: false, }; let value_may_be_infer = generalizer.relate(source_term, source_term)?; - let has_unconstrained_ty_var = generalizer.has_unconstrained_ty_var; - Ok(Generalization { value_may_be_infer, has_unconstrained_ty_var }) + Ok(Generalization { value_may_be_infer }) } } @@ -376,9 +364,6 @@ struct Generalizer<'me, 'tcx> { in_alias: bool, cache: SsoHashMap<(Ty<'tcx>, ty::Variance, bool), Ty<'tcx>>, - - /// See the field `has_unconstrained_ty_var` in `Generalization`. - has_unconstrained_ty_var: bool, } impl<'tcx> Generalizer<'_, 'tcx> { @@ -391,10 +376,8 @@ impl<'tcx> Generalizer<'_, 'tcx> { } /// Create a new type variable in the universe of the target when - /// generalizing an alias. This has to set `has_unconstrained_ty_var` - /// if we're currently in a bivariant context. - fn next_ty_var_for_alias(&mut self) -> Ty<'tcx> { - self.has_unconstrained_ty_var |= self.ambient_variance == ty::Bivariant; + /// generalizing an alias. + fn next_ty_var_for_alias(&self) -> Ty<'tcx> { self.infcx.next_ty_var_in_universe(self.span, self.for_universe) } @@ -461,29 +444,26 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { self.infcx.tcx } - fn relate_item_args( + fn relate_ty_args( &mut self, - item_def_id: DefId, - a_arg: ty::GenericArgsRef<'tcx>, - b_arg: ty::GenericArgsRef<'tcx>, - ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { - if self.ambient_variance == ty::Invariant { + a_ty: Ty<'tcx>, + _: Ty<'tcx>, + def_id: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + mk: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { + let args = if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). - relate::relate_args_invariantly(self, a_arg, b_arg) + relate::relate_args_invariantly(self, a_args, b_args) } else { let tcx = self.cx(); - let opt_variances = tcx.variances_of(item_def_id); - relate::relate_args_with_variances( - self, - item_def_id, - opt_variances, - a_arg, - b_arg, - false, - ) - } + let variances = tcx.variances_of(def_id); + relate::relate_args_with_variances(self, variances, a_args, b_args) + }?; + if args == a_args { Ok(a_ty) } else { Ok(mk(args)) } } #[instrument(level = "debug", skip(self, variance, b), ret)] @@ -545,14 +525,8 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { } } - // Bivariant: make a fresh var, but remember that - // it is unconstrained. See the comment in - // `Generalization`. - ty::Bivariant => self.has_unconstrained_ty_var = true, - - // Co/contravariant: this will be - // sufficiently constrained later on. - ty::Covariant | ty::Contravariant => (), + // We do need a fresh type variable otherwise. + ty::Bivariant | ty::Covariant | ty::Contravariant => (), } let origin = inner.type_variables().var_origin(vid); @@ -771,32 +745,8 @@ struct Generalization { /// for `?0` generalization returns an inference /// variable. /// - /// This has to be handled wotj care as it can + /// This has to be handled with care as it can /// otherwise very easily result in infinite /// recursion. pub value_may_be_infer: T, - - /// In general, we do not check whether all types which occur during - /// type checking are well-formed. We only check wf of user-provided types - /// and when actually using a type, e.g. for method calls. - /// - /// This means that when subtyping, we may end up with unconstrained - /// inference variables if a generalized type has bivariant parameters. - /// A parameter may only be bivariant if it is constrained by a projection - /// bound in a where-clause. As an example, imagine a type: - /// - /// struct Foo where A: Iterator { - /// data: A - /// } - /// - /// here, `A` will be covariant, but `B` is unconstrained. - /// - /// However, whatever it is, for `Foo` to be WF, it must be equal to `A::Item`. - /// If we have an input `Foo`, then after generalization we will wind - /// up with a type like `Foo`. When we enforce `Foo <: Foo`, - /// we will wind up with the requirement that `?A <: ?C`, but no particular - /// relationship between `?B` and `?D` (after all, these types may be completely - /// different). If we do nothing else, this may mean that `?D` goes unconstrained - /// (as in #41677). To avoid this we emit a `WellFormed` obligation in these cases. - pub has_unconstrained_ty_var: bool, } diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 4eb77a99be78..a05e2d40e829 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -17,8 +17,9 @@ //! //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order) +use rustc_hir::def_id::DefId; use rustc_middle::traits::solve::Goal; -use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys}; +use rustc_middle::ty::relate::combine::{combine_ty_args, super_combine_consts, super_combine_tys}; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt, TyVar, TypeVisitableExt}; use rustc_span::Span; @@ -75,6 +76,19 @@ impl<'tcx> TypeRelation> for LatticeOp<'_, 'tcx> { self.infcx.tcx } + fn relate_ty_args( + &mut self, + a_ty: Ty<'tcx>, + b_ty: Ty<'tcx>, + def_id: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + mk: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { + let variances = self.cx().variances_of(def_id); + combine_ty_args(self.infcx, self, a_ty, b_ty, variances, a_args, b_args, |args| mk(args)) + } + fn relate_with_variance>>( &mut self, variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 04ff776594e6..96a0375f5fba 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -1,8 +1,7 @@ +use rustc_hir::def_id::DefId; use rustc_middle::traits::solve::Goal; -use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys}; -use rustc_middle::ty::relate::{ - Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances, -}; +use rustc_middle::ty::relate::combine::{combine_ty_args, super_combine_consts, super_combine_tys}; +use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation, relate_args_invariantly}; use rustc_middle::ty::{self, DelayedSet, Ty, TyCtxt, TyVar}; use rustc_span::Span; use tracing::{debug, instrument}; @@ -79,21 +78,24 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, 'tcx> { self.infcx.tcx } - fn relate_item_args( + fn relate_ty_args( &mut self, - item_def_id: rustc_hir::def_id::DefId, - a_arg: ty::GenericArgsRef<'tcx>, - b_arg: ty::GenericArgsRef<'tcx>, - ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { + a_ty: Ty<'tcx>, + b_ty: Ty<'tcx>, + def_id: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). - relate_args_invariantly(self, a_arg, b_arg) + relate_args_invariantly(self, a_args, b_args)?; + Ok(a_ty) } else { - let tcx = self.cx(); - let opt_variances = tcx.variances_of(item_def_id); - relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, false) + let variances = self.cx().variances_of(def_id); + combine_ty_args(self.infcx, self, a_ty, b_ty, variances, a_args, b_args, |_| a_ty) } } diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index b9afb62cf1c6..f54afce0615f 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -12,7 +12,8 @@ use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_macros::LintDiagnostic; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::ty::relate::{ - Relate, RelateResult, TypeRelation, structurally_relate_consts, structurally_relate_tys, + Relate, RelateResult, TypeRelation, relate_args_with_variances, structurally_relate_consts, + structurally_relate_tys, }; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, @@ -502,6 +503,20 @@ impl<'tcx> TypeRelation> for FunctionalVariances<'tcx> { self.tcx } + fn relate_ty_args( + &mut self, + a_ty: Ty<'tcx>, + _: Ty<'tcx>, + def_id: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { + let variances = self.cx().variances_of(def_id); + relate_args_with_variances(self, variances, a_args, b_args)?; + Ok(a_ty) + } + fn relate_with_variance>>( &mut self, variance: ty::Variance, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index b280a6ec55af..32be23eed765 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -2069,6 +2069,19 @@ impl<'tcx> TypeRelation> for SameTypeModuloInfer<'_, 'tcx> { self.0.tcx } + fn relate_ty_args( + &mut self, + a_ty: Ty<'tcx>, + _: Ty<'tcx>, + _: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { + relate::relate_args_invariantly(self, a_args, b_args)?; + Ok(a_ty) + } + fn relate_with_variance>>( &mut self, _variance: ty::Variance, diff --git a/compiler/rustc_trait_selection/src/traits/select/_match.rs b/compiler/rustc_trait_selection/src/traits/select/_match.rs index 7c19c35a4f78..27de754aa7dc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/_match.rs +++ b/compiler/rustc_trait_selection/src/traits/select/_match.rs @@ -1,3 +1,4 @@ +use rustc_hir::def_id::DefId; use rustc_infer::infer::relate::{ self, Relate, RelateResult, TypeRelation, structurally_relate_tys, }; @@ -36,6 +37,19 @@ impl<'tcx> TypeRelation> for MatchAgainstFreshVars<'tcx> { self.tcx } + fn relate_ty_args( + &mut self, + a_ty: Ty<'tcx>, + _: Ty<'tcx>, + _: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { + relate::relate_args_invariantly(self, a_args, b_args)?; + Ok(a_ty) + } + fn relate_with_variance>>( &mut self, _: ty::Variance, diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index fc74cbf47823..4f843503d1af 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -73,20 +73,15 @@ pub trait TypeRelation: Sized { Relate::relate(self, a, b) } - /// Relate the two args for the given item. The default - /// is to look up the variance for the item and proceed - /// accordingly. - #[instrument(skip(self), level = "trace")] - fn relate_item_args( + fn relate_ty_args( &mut self, - item_def_id: I::DefId, + a_ty: I::Ty, + b_ty: I::Ty, + ty_def_id: I::DefId, a_arg: I::GenericArgs, b_arg: I::GenericArgs, - ) -> RelateResult { - let cx = self.cx(); - let opt_variances = cx.variances_of(item_def_id); - relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true) - } + mk: impl FnOnce(I::GenericArgs) -> I::Ty, + ) -> RelateResult; /// Switch variance for the purpose of relating `a` and `b`. fn relate_with_variance>( @@ -138,27 +133,17 @@ pub fn relate_args_invariantly>( pub fn relate_args_with_variances>( relation: &mut R, - ty_def_id: I::DefId, variances: I::VariancesOf, - a_arg: I::GenericArgs, - b_arg: I::GenericArgs, - fetch_ty_for_diag: bool, + a_args: I::GenericArgs, + b_args: I::GenericArgs, ) -> RelateResult { let cx = relation.cx(); - - let mut cached_ty = None; - let params = iter::zip(a_arg.iter(), b_arg.iter()).enumerate().map(|(i, (a, b))| { + let args = iter::zip(a_args.iter(), b_args.iter()).enumerate().map(|(i, (a, b))| { let variance = variances.get(i).unwrap(); - let variance_info = if variance == ty::Invariant && fetch_ty_for_diag { - let ty = *cached_ty.get_or_insert_with(|| cx.type_of(ty_def_id).instantiate(cx, a_arg)); - VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } - } else { - VarianceDiagInfo::default() - }; - relation.relate_with_variance(variance, variance_info, a, b) + relation.relate_with_variance(variance, VarianceDiagInfo::None, a, b) }); - - cx.mk_args_from_iter(params) + // FIXME: We can probably try to reuse `a_args` here if it did not change. + cx.mk_args_from_iter(args) } impl Relate for ty::FnSig { @@ -240,10 +225,7 @@ impl Relate for ty::AliasTy { } else { let cx = relation.cx(); let args = if let Some(variances) = cx.opt_alias_variances(a.kind(cx), a.def_id) { - relate_args_with_variances( - relation, a.def_id, variances, a.args, b.args, - false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle - )? + relate_args_with_variances(relation, variances, a.args, b.args)? } else { relate_args_invariantly(relation, a.args, b.args)? }; @@ -268,11 +250,9 @@ impl Relate for ty::AliasTerm { let args = match a.kind(relation.cx()) { ty::AliasTermKind::OpaqueTy => relate_args_with_variances( relation, - a.def_id, relation.cx().variances_of(a.def_id), a.args, b.args, - false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle )?, ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::FreeConst @@ -402,12 +382,13 @@ pub fn structurally_relate_tys>( (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a), (ty::Adt(a_def, a_args), ty::Adt(b_def, b_args)) if a_def == b_def => { - Ok(if a_args.is_empty() { - a + if a_args.is_empty() { + Ok(a) } else { - let args = relation.relate_item_args(a_def.def_id().into(), a_args, b_args)?; - if args == a_args { a } else { Ty::new_adt(cx, a_def, args) } - }) + relation.relate_ty_args(a, b, a_def.def_id().into(), a_args, b_args, |args| { + Ty::new_adt(cx, a_def, args) + }) + } } (ty::Foreign(a_id), ty::Foreign(b_id)) if a_id == b_id => Ok(Ty::new_foreign(cx, a_id)), @@ -516,12 +497,13 @@ pub fn structurally_relate_tys>( } (ty::FnDef(a_def_id, a_args), ty::FnDef(b_def_id, b_args)) if a_def_id == b_def_id => { - Ok(if a_args.is_empty() { - a + if a_args.is_empty() { + Ok(a) } else { - let args = relation.relate_item_args(a_def_id.into(), a_args, b_args)?; - if args == a_args { a } else { Ty::new_fn_def(cx, a_def_id, args) } - }) + relation.relate_ty_args(a, b, a_def_id.into(), a_args, b_args, |args| { + Ty::new_fn_def(cx, a_def_id, args) + }) + } } (ty::FnPtr(a_sig_tys, a_hdr), ty::FnPtr(b_sig_tys, b_hdr)) => { diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 8dd7c4df2442..64b87fac77f9 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -1,3 +1,5 @@ +use std::iter; + use tracing::debug; use super::{ @@ -6,6 +8,7 @@ use super::{ }; use crate::error::TypeError; use crate::inherent::*; +use crate::relate::VarianceDiagInfo; use crate::solve::Goal; use crate::visit::TypeVisitableExt as _; use crate::{self as ty, InferCtxtLike, Interner, TypingMode, Upcast}; @@ -219,3 +222,75 @@ where _ => structurally_relate_consts(relation, a, b), } } + +pub fn combine_ty_args( + infcx: &Infcx, + relation: &mut R, + a_ty: I::Ty, + b_ty: I::Ty, + variances: I::VariancesOf, + a_args: I::GenericArgs, + b_args: I::GenericArgs, + mk: impl FnOnce(I::GenericArgs) -> I::Ty, +) -> RelateResult +where + Infcx: InferCtxtLike, + I: Interner, + R: PredicateEmittingRelation, +{ + let cx = infcx.cx(); + let mut has_unconstrained_bivariant_arg = false; + let args = iter::zip(a_args.iter(), b_args.iter()).enumerate().map(|(i, (a, b))| { + let variance = variances.get(i).unwrap(); + let variance_info = match variance { + ty::Invariant => { + VarianceDiagInfo::Invariant { ty: a_ty, param_index: i.try_into().unwrap() } + } + ty::Covariant | ty::Contravariant => VarianceDiagInfo::default(), + ty::Bivariant => { + let has_non_region_infer = |arg: I::GenericArg| { + arg.has_non_region_infer() + && infcx.resolve_vars_if_possible(arg).has_non_region_infer() + }; + if has_non_region_infer(a) || has_non_region_infer(b) { + has_unconstrained_bivariant_arg = true; + } + VarianceDiagInfo::default() + } + }; + relation.relate_with_variance(variance, variance_info, a, b) + }); + let args = cx.mk_args_from_iter(args)?; + + // In general, we do not check whether all types which occur during + // type checking are well-formed. We only check wf of user-provided types + // and when actually using a type, e.g. for method calls. + // + // This means that when subtyping, we may end up with unconstrained + // inference variables if a generalized type has bivariant parameters. + // A parameter may only be bivariant if it is constrained by a projection + // bound in a where-clause. As an example, imagine a type: + // + // struct Foo where A: Iterator { + // data: A + // } + // + // here, `A` will be covariant, but `B` is unconstrained. However, whatever it is, + // for `Foo` to be WF, it must be equal to `A::Item`. + // + // If we have an input `Foo`, then after generalization we will wind + // up with a type like `Foo`. When we enforce `Foo <: Foo`, + // we will wind up with the requirement that `?A <: ?C`, but no particular + // relationship between `?B` and `?D` (after all, these types may be completely + // different). If we do nothing else, this may mean that `?D` goes unconstrained + // (as in #41677). To avoid this we emit a `WellFormed` when relating types with + // bivariant arguments. + if has_unconstrained_bivariant_arg { + relation.register_predicates([ + ty::ClauseKind::WellFormed(a_ty.into()), + ty::ClauseKind::WellFormed(b_ty.into()), + ]); + } + + if a_args == args { Ok(a_ty) } else { Ok(mk(args)) } +} diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index 79f6bc5dabb4..82ee4f75fcb0 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs @@ -2,6 +2,7 @@ use tracing::{debug, instrument}; use self::combine::{PredicateEmittingRelation, super_combine_consts, super_combine_tys}; use crate::data_structures::DelayedSet; +use crate::relate::combine::combine_ty_args; pub use crate::relate::*; use crate::solve::Goal; use crate::{self as ty, InferCtxtLike, Interner}; @@ -139,24 +140,26 @@ where self.infcx.cx() } - fn relate_item_args( + fn relate_ty_args( &mut self, - item_def_id: I::DefId, - a_arg: I::GenericArgs, - b_arg: I::GenericArgs, - ) -> RelateResult { + a_ty: I::Ty, + b_ty: I::Ty, + def_id: I::DefId, + a_args: I::GenericArgs, + b_args: I::GenericArgs, + _: impl FnOnce(I::GenericArgs) -> I::Ty, + ) -> RelateResult { if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). - relate_args_invariantly(self, a_arg, b_arg) + relate_args_invariantly(self, a_args, b_args)?; + Ok(a_ty) } else { - let tcx = self.cx(); - let opt_variances = tcx.variances_of(item_def_id); - relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, false) + let variances = self.cx().variances_of(def_id); + combine_ty_args(self.infcx, self, a_ty, b_ty, variances, a_args, b_args, |_| a_ty) } } - fn relate_with_variance>( &mut self, variance: ty::Variance, diff --git a/tests/ui/traits/next-solver/generalize/subtype-obligations-bivariant-args.rs b/tests/ui/traits/next-solver/generalize/subtype-obligations-bivariant-args.rs new file mode 100644 index 000000000000..9e25401f0f9a --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/subtype-obligations-bivariant-args.rs @@ -0,0 +1,52 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass + +// Regression test for trait-system-refactor-initiative#250. +// Subtyping previously handled bivariant arguments by emitting +// a `WellFormed` obligation when generalizing them. +// +// This obligation then got dropped inside of an ambiguous `Subtype` +// obligation so we never constrained the bivariant arg. + +// Test case 1 +enum State +where + S: Iterator, +{ + Active { upstream: S }, + WindDown, + Complete, +} + +impl State +where + S: Iterator, +{ + fn foo(self) { + let x = match self { + State::Active { .. } => None, + State::WindDown => None, + State::Complete => Some(State::Complete), + }; + let _: Option> = x; + } +} + +// Test case 2 +trait Trait { + type Assoc; +} +impl Trait for T { + type Assoc = T; +} + +struct Foo, U>(T); + +fn main() { + let x = None.unwrap(); + let y = x; + let _: Foo<_, _> = x; + let _: Foo = x; +} From e1be0d2e2a1640da4b19c86025e3fd95c5007b36 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 13 Nov 2025 16:18:22 +0100 Subject: [PATCH 0289/3801] MIR typeck: invariant ctxt fast path This removes variance information from some diagnostics. However, that variance information is not actually relevant here. Casting `*const dyn Cat<'a>` to `*const S>` is an error regardless of whether `S` requires its argument to be invariant. Wide-pointer casts always require the trait object arguments to be invariant. --- .../src/type_check/relate_tys.rs | 30 ++++++++++++------- ...-different-regions-id-trait.current.stderr | 4 --- ...obj-different-regions-id-trait.next.stderr | 4 --- ...ied-bounds-unnorm-associated-type-2.stderr | 3 -- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 18d5922f27d1..539912609baa 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -11,6 +11,7 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::relate::combine::{combine_ty_args, super_combine_consts, super_combine_tys}; +use rustc_middle::ty::relate::relate_args_invariantly; use rustc_middle::ty::{self, FnMutDelegate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; @@ -313,17 +314,24 @@ impl<'b, 'tcx> TypeRelation> for NllTypeRelating<'_, 'b, 'tcx> { b_args: ty::GenericArgsRef<'tcx>, _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, ) -> RelateResult<'tcx, Ty<'tcx>> { - let variances = self.cx().variances_of(def_id); - combine_ty_args( - &self.type_checker.infcx.infcx, - self, - a_ty, - b_ty, - variances, - a_args, - b_args, - |_| a_ty, - ) + if self.ambient_variance == ty::Invariant { + // Avoid fetching the variance if we are in an invariant context, + // slightly improves perf. + relate_args_invariantly(self, a_args, b_args)?; + Ok(a_ty) + } else { + let variances = self.cx().variances_of(def_id); + combine_ty_args( + &self.type_checker.infcx.infcx, + self, + a_ty, + b_ty, + variances, + a_args, + b_args, + |_| a_ty, + ) + } } #[instrument(skip(self, info), level = "trace", ret)] diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr index 4e43d3b93fa3..62f17a656855 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr @@ -6,10 +6,6 @@ LL | fn m<'a>() { LL | let unsend: *const dyn Cat<'a> = &(); LL | let _send = unsend as *const S>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - | - = note: requirement occurs because of the type `S>`, which makes the generic argument `dyn Cat<'_>` invariant - = note: the struct `S` is invariant over the parameter `T` - = help: see for more information about variance error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr index 4e43d3b93fa3..62f17a656855 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr @@ -6,10 +6,6 @@ LL | fn m<'a>() { LL | let unsend: *const dyn Cat<'a> = &(); LL | let _send = unsend as *const S>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - | - = note: requirement occurs because of the type `S>`, which makes the generic argument `dyn Cat<'_>` invariant - = note: the struct `S` is invariant over the parameter `T` - = help: see for more information about variance error: aborting due to 1 previous error diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type-2.stderr b/tests/ui/fn/implied-bounds-unnorm-associated-type-2.stderr index 85e3452fbf2c..95fac3ce51d2 100644 --- a/tests/ui/fn/implied-bounds-unnorm-associated-type-2.stderr +++ b/tests/ui/fn/implied-bounds-unnorm-associated-type-2.stderr @@ -9,9 +9,6 @@ LL | f::<'a, 'b>(()); | ^^^^^^^^^^^^^^^ generic argument requires that `'b` must outlive `'a` | = help: consider adding the following bound: `'b: 'a` - = note: requirement occurs because of a function pointer to `f` - = note: the function `f` is invariant over the parameter `'a` - = help: see for more information about variance error: aborting due to 1 previous error From 98d0421a714108d0de9095fadc8dd3c71f26a230 Mon Sep 17 00:00:00 2001 From: Young-Flash Date: Thu, 4 Dec 2025 23:27:19 +0800 Subject: [PATCH 0290/3801] internal: migrate `generate_delegate_trait` to SyntaxEditor api --- .../src/handlers/generate_delegate_trait.rs | 445 ++++++++++-------- 1 file changed, 250 insertions(+), 195 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs index e87dde5b8e42..03642756219a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs @@ -14,15 +14,15 @@ use ide_db::{ }; use itertools::Itertools; use syntax::{ - AstNode, Edition, NodeOrToken, SmolStr, SyntaxKind, ToSmolStr, + AstNode, Edition, SmolStr, SyntaxElement, SyntaxKind, ToSmolStr, ast::{ self, AssocItem, GenericArgList, GenericParamList, HasAttrs, HasGenericArgs, HasGenericParams, HasName, HasTypeBounds, HasVisibility as astHasVisibility, Path, WherePred, edit::{self, AstNodeEdit}, - make, + syntax_factory::SyntaxFactory, }, - ted::{self, Position}, + syntax_editor::SyntaxEditor, }; // Assist: generate_delegate_trait @@ -169,10 +169,15 @@ enum Delegee { } impl Delegee { + fn trait_(&self) -> &hir::Trait { + match self { + Delegee::Bound(it) | Delegee::Impls(it, _) => it, + } + } + fn signature(&self, db: &dyn HirDatabase, edition: Edition) -> String { let mut s = String::new(); - - let (Delegee::Bound(it) | Delegee::Impls(it, _)) = self; + let it = self.trait_(); for m in it.module(db).path_to_root(db).iter().rev() { if let Some(name) = m.name(db) { @@ -201,15 +206,12 @@ impl Struct { let db = ctx.db(); for (index, delegee) in field.impls.iter().enumerate() { - let trait_ = match delegee { - Delegee::Bound(b) => b, - Delegee::Impls(i, _) => i, - }; + let trait_ = delegee.trait_(); // Skip trait that has `Self` type, which cannot be delegated // // See [`test_self_ty`] - if has_self_type(*trait_, ctx).is_some() { + if has_self_type(*trait_, ctx) { continue; } @@ -254,9 +256,10 @@ fn generate_impl( delegee: &Delegee, edition: Edition, ) -> Option { + let make = SyntaxFactory::without_mappings(); let db = ctx.db(); let ast_strukt = &strukt.strukt; - let strukt_ty = make::ty_path(make::ext::ident_path(&strukt.name.to_string())); + let strukt_ty = make.ty_path(make.ident_path(&strukt.name.to_string())).into(); let strukt_params = ast_strukt.generic_param_list(); match delegee { @@ -264,7 +267,7 @@ fn generate_impl( let bound_def = ctx.sema.source(delegee.to_owned())?.value; let bound_params = bound_def.generic_param_list(); - let delegate = make::impl_trait( + let delegate = make.impl_trait( None, delegee.is_unsafe(db), bound_params.clone(), @@ -272,33 +275,28 @@ fn generate_impl( strukt_params.clone(), strukt_params.map(|params| params.to_generic_args()), delegee.is_auto(db), - make::ty(&delegee.name(db).display_no_db(edition).to_smolstr()), + make.ty(&delegee.name(db).display_no_db(edition).to_smolstr()), strukt_ty, bound_def.where_clause(), ast_strukt.where_clause(), None, - ) - .clone_for_update(); + ); // Goto link : https://doc.rust-lang.org/reference/paths.html#qualified-paths let qualified_path_type = - make::path_from_text(&format!("<{} as {}>", field_ty, delegate.trait_()?)); + make.path_from_text(&format!("<{} as {}>", field_ty, delegate.trait_()?)); - let delegate_assoc_items = delegate.get_or_create_assoc_item_list(); - if let Some(ai) = bound_def.assoc_item_list() { + // Collect assoc items + let assoc_items: Option> = bound_def.assoc_item_list().map(|ai| { ai.assoc_items() .filter(|item| matches!(item, AssocItem::MacroCall(_)).not()) - .for_each(|item| { - let assoc = process_assoc_item( - item.clone_for_update(), - qualified_path_type.clone(), - field_name, - ); - if let Some(assoc) = assoc { - delegate_assoc_items.add_item(assoc); - } - }); - }; + .filter_map(|item| { + process_assoc_item(item, qualified_path_type.clone(), field_name) + }) + .collect() + }); + + let delegate = finalize_delegate(&delegate, assoc_items, false)?; let target_scope = ctx.sema.scope(strukt.strukt.syntax())?; let source_scope = ctx.sema.scope(bound_def.syntax())?; @@ -324,7 +322,7 @@ fn generate_impl( .and_then(|wc| rename_strukt_args(ctx, ast_strukt, &wc, &args)); (field_ty, where_clause) } - None => (field_ty.clone_for_update(), None), + None => (field_ty.clone(), None), }; // 2) Handle instantiated generics in `field_ty`. @@ -347,38 +345,38 @@ fn generate_impl( ); // 2.2) Generate generic args applied on impl. - let transform_args = generate_args_for_impl( + let (transform_args, trait_gen_params) = generate_args_for_impl( old_impl_params, &old_impl.self_ty()?, &field_ty, - &trait_gen_params, + trait_gen_params, &old_impl_trait_args, ); // 2.3) Instantiate generics with `transform_impl`, this step also // remove unused params. - let trait_gen_args = old_impl.trait_()?.generic_arg_list().and_then(|trait_args| { - let trait_args = &mut trait_args.clone_for_update(); - if let Some(new_args) = transform_impl( - ctx, - ast_strukt, - &old_impl, - &transform_args, - trait_args.clone_subtree(), - ) { - *trait_args = new_args.clone_subtree(); - Some(new_args) - } else { - None - } - }); + let trait_gen_args = + old_impl.trait_()?.generic_arg_list().and_then(|mut trait_args| { + let trait_args = &mut trait_args; + if let Some(new_args) = transform_impl( + ctx, + ast_strukt, + &old_impl, + &transform_args, + trait_args.clone_subtree(), + ) { + *trait_args = new_args.clone_subtree(); + Some(new_args) + } else { + None + } + }); let type_gen_args = strukt_params.clone().map(|params| params.to_generic_args()); - let path_type = - make::ty(&trait_.name(db).display_no_db(edition).to_smolstr()).clone_for_update(); + let path_type = make.ty(&trait_.name(db).display_no_db(edition).to_smolstr()); let path_type = transform_impl(ctx, ast_strukt, &old_impl, &transform_args, path_type)?; // 3) Generate delegate trait impl - let delegate = make::impl_trait( + let delegate = make.impl_trait( None, trait_.is_unsafe(db), trait_gen_params, @@ -388,34 +386,27 @@ fn generate_impl( trait_.is_auto(db), path_type, strukt_ty, - old_impl.where_clause().map(|wc| wc.clone_for_update()), + old_impl.where_clause(), ty_where_clause, None, - ) - .clone_for_update(); + ); // Goto link : https://doc.rust-lang.org/reference/paths.html#qualified-paths let qualified_path_type = - make::path_from_text(&format!("<{} as {}>", field_ty, delegate.trait_()?)); + make.path_from_text(&format!("<{} as {}>", field_ty, delegate.trait_()?)); - // 4) Transform associated items in delegte trait impl - let delegate_assoc_items = delegate.get_or_create_assoc_item_list(); - for item in old_impl - .get_or_create_assoc_item_list() - .assoc_items() - .filter(|item| matches!(item, AssocItem::MacroCall(_)).not()) - { - let item = item.clone_for_update(); - let item = transform_impl(ctx, ast_strukt, &old_impl, &transform_args, item)?; + // 4) Transform associated items in delegate trait impl + let assoc_items: Option> = old_impl.assoc_item_list().map(|ail| { + ail.assoc_items() + .filter(|item| matches!(item, AssocItem::MacroCall(_)).not()) + .filter_map(|item| { + let item = + transform_impl(ctx, ast_strukt, &old_impl, &transform_args, item)?; + process_assoc_item(item, qualified_path_type.clone(), field_name) + }) + .collect() + }); - let assoc = process_assoc_item(item, qualified_path_type.clone(), field_name)?; - delegate_assoc_items.add_item(assoc); - } - - // 5) Remove useless where clauses - if let Some(wc) = delegate.where_clause() { - remove_useless_where_clauses(&delegate.trait_()?, &delegate.self_ty()?, wc); - } - Some(delegate) + finalize_delegate(&delegate, assoc_items, true) } } } @@ -446,6 +437,35 @@ fn transform_impl( N::cast(transform.apply(syntax.syntax())) } +/// Extracts the name from a generic parameter. +fn generic_param_name(param: &ast::GenericParam) -> Option { + match param { + ast::GenericParam::TypeParam(t) => t.name().map(|n| n.to_string()), + ast::GenericParam::ConstParam(c) => c.name().map(|n| n.to_string()), + ast::GenericParam::LifetimeParam(l) => l.lifetime().map(|lt| lt.to_string()), + } +} + +/// Filters generic params, keeping only those whose names are not in `names_to_remove`. +fn filter_generic_params( + gpl: ast::GenericParamList, + names_to_remove: &FxHashSet, +) -> Option { + let remaining_params: Vec<_> = gpl + .generic_params() + .filter(|param| { + generic_param_name(param).is_none_or(|name| !names_to_remove.contains(&name)) + }) + .collect(); + + if remaining_params.is_empty() { + None + } else { + let make = SyntaxFactory::without_mappings(); + Some(make.generic_param_list(remaining_params)) + } +} + fn remove_instantiated_params( self_ty: &ast::Type, old_impl_params: Option, @@ -454,10 +474,8 @@ fn remove_instantiated_params( match self_ty { ast::Type::PathType(path_type) => { old_impl_params.and_then(|gpl| { - // Remove generic parameters in field_ty (which is instantiated). - let new_gpl = gpl.clone_for_update(); - - path_type + // Collect generic args that should be removed (instantiated params) + let args_to_remove: FxHashSet = path_type .path()? .segments() .filter_map(|seg| seg.generic_arg_list()) @@ -466,16 +484,25 @@ fn remove_instantiated_params( // it shouldn't be removed now, which will be instantiated in // later `path_transform` .filter(|arg| !old_trait_args.contains(&arg.to_string())) - .for_each(|arg| new_gpl.remove_generic_arg(&arg)); - (new_gpl.generic_params().count() > 0).then_some(new_gpl) + .map(|arg| arg.to_string()) + .collect(); + + filter_generic_params(gpl, &args_to_remove) }) } _ => old_impl_params, } } -fn remove_useless_where_clauses(trait_ty: &ast::Type, self_ty: &ast::Type, wc: ast::WhereClause) { - let live_generics = [trait_ty, self_ty] +fn remove_useless_where_clauses(editor: &mut SyntaxEditor, delegate: &ast::Impl) { + let Some(wc) = delegate.where_clause() else { + return; + }; + let (Some(trait_ty), Some(self_ty)) = (delegate.trait_(), delegate.self_ty()) else { + return; + }; + + let live_generics = [&trait_ty, &self_ty] .into_iter() .flat_map(|ty| ty.generic_arg_list()) .flat_map(|gal| gal.generic_args()) @@ -484,36 +511,78 @@ fn remove_useless_where_clauses(trait_ty: &ast::Type, self_ty: &ast::Type, wc: a // Keep where-clauses that have generics after substitution, and remove the // rest. - let has_live_generics = |pred: &WherePred| { + let has_no_live_generics = |pred: &WherePred| { pred.syntax() .descendants_with_tokens() .filter_map(|e| e.into_token()) .any(|e| e.kind() == SyntaxKind::IDENT && live_generics.contains(&e.to_string())) .not() }; - wc.predicates().filter(has_live_generics).for_each(|pred| wc.remove_predicate(pred)); - if wc.predicates().count() == 0 { - // Remove useless whitespaces - [syntax::Direction::Prev, syntax::Direction::Next] - .into_iter() - .flat_map(|dir| { - wc.syntax() - .siblings_with_tokens(dir) - .skip(1) - .take_while(|node_or_tok| node_or_tok.kind() == SyntaxKind::WHITESPACE) - }) - .for_each(ted::remove); + let predicates_to_remove: Vec<_> = wc.predicates().filter(has_no_live_generics).collect(); + let remaining_predicates = wc.predicates().count() - predicates_to_remove.len(); - ted::insert( - ted::Position::after(wc.syntax()), - NodeOrToken::Token(make::token(SyntaxKind::WHITESPACE)), - ); - // Remove where clause - ted::remove(wc.syntax()); + if remaining_predicates == 0 { + // Remove the entire where clause + editor.delete(wc.syntax().clone()); + } else { + // Remove only the useless predicates + for pred in predicates_to_remove { + // Also remove the comma before or after the predicate + if let Some(previous) = pred.syntax().prev_sibling() { + // Remove from after previous sibling to predicate (inclusive) + if let Some(start) = previous.next_sibling_or_token() { + let end: SyntaxElement = pred.syntax().clone().into(); + editor.delete_all(start..=end); + } + } else if let Some(next) = pred.syntax().next_sibling() { + // Remove from predicate to before next sibling (exclusive) + if let Some(end) = next.prev_sibling_or_token() { + let start: SyntaxElement = pred.syntax().clone().into(); + editor.delete_all(start..=end); + } + } else { + editor.delete(pred.syntax().clone()); + } + } } } +/// Finalize the delegate impl by: +/// 1. Replacing the assoc_item_list with new items (if any) +/// 2. Removing useless where clauses +fn finalize_delegate( + delegate: &ast::Impl, + assoc_items: Option>, + remove_where_clauses: bool, +) -> Option { + let has_items = assoc_items.as_ref().is_some_and(|items| !items.is_empty()); + + if !has_items && !remove_where_clauses { + return Some(delegate.clone()); + } + + let mut editor = SyntaxEditor::new(delegate.syntax().clone_subtree()); + + // 1. Replace assoc_item_list if we have new items + if let Some(items) = assoc_items + && !items.is_empty() + { + let new_assoc_item_list = + syntax::ast::make::assoc_item_list(Some(items)).clone_for_update(); + if let Some(old_list) = delegate.assoc_item_list() { + editor.replace(old_list.syntax(), new_assoc_item_list.syntax()); + } + } + + // 2. Remove useless where clauses + if remove_where_clauses { + remove_useless_where_clauses(&mut editor, delegate); + } + + ast::Impl::cast(editor.finish().new_root().clone()) +} + // Generate generic args that should be apply to current impl. // // For example, say we have implementation `impl Trait for B`, @@ -524,10 +593,13 @@ fn generate_args_for_impl( old_impl_gpl: Option, self_ty: &ast::Type, field_ty: &ast::Type, - trait_params: &Option, + trait_params: Option, old_trait_args: &FxHashSet, -) -> Option { - let old_impl_args = old_impl_gpl.map(|gpl| gpl.to_generic_args().generic_args())?; +) -> (Option, Option) { + let Some(old_impl_args) = old_impl_gpl.map(|gpl| gpl.to_generic_args().generic_args()) else { + return (None, trait_params); + }; + // Create pairs of the args of `self_ty` and corresponding `field_ty` to // form the substitution list let mut arg_substs = FxHashMap::default(); @@ -542,6 +614,8 @@ fn generate_args_for_impl( } } + let mut params_to_remove = FxHashSet::default(); + let args = old_impl_args .map(|old_arg| { arg_substs.get(&old_arg.to_string()).map_or_else( @@ -549,14 +623,18 @@ fn generate_args_for_impl( |replace_with| { // The old_arg will be replaced, so it becomes redundant if trait_params.is_some() && old_trait_args.contains(&old_arg.to_string()) { - trait_params.as_ref().unwrap().remove_generic_arg(&old_arg) + params_to_remove.insert(old_arg.to_string()); } replace_with.clone() }, ) }) .collect_vec(); - args.is_empty().not().then(|| make::generic_arg_list(args)) + + let make = SyntaxFactory::without_mappings(); + let result = args.is_empty().not().then(|| make.generic_arg_list(args, false)); + let trait_params = trait_params.and_then(|gpl| filter_generic_params(gpl, ¶ms_to_remove)); + (result, trait_params) } fn rename_strukt_args( @@ -570,41 +648,37 @@ where { let hir_strukt = ctx.sema.to_struct_def(strukt)?; let hir_adt = hir::Adt::from(hir_strukt); - - let item = item.clone_for_update(); let scope = ctx.sema.scope(item.syntax())?; let transform = PathTransform::adt_transformation(&scope, &scope, hir_adt, args.clone()); N::cast(transform.apply(item.syntax())) } -fn has_self_type(trait_: hir::Trait, ctx: &AssistContext<'_>) -> Option<()> { - let trait_source = ctx.sema.source(trait_)?.value; - trait_source - .syntax() - .descendants_with_tokens() - .filter_map(|e| e.into_token()) - .find(|e| e.kind() == SyntaxKind::SELF_TYPE_KW) - .map(|_| ()) +fn has_self_type(trait_: hir::Trait, ctx: &AssistContext<'_>) -> bool { + ctx.sema + .source(trait_) + .and_then(|src| { + src.value + .syntax() + .descendants_with_tokens() + .filter_map(|e| e.into_token()) + .find(|e| e.kind() == SyntaxKind::SELF_TYPE_KW) + }) + .is_some() } fn resolve_name_conflicts( strukt_params: Option, old_impl_params: &Option, ) -> Option { + let make = SyntaxFactory::without_mappings(); match (strukt_params, old_impl_params) { (Some(old_strukt_params), Some(old_impl_params)) => { - let params = make::generic_param_list(std::iter::empty()).clone_for_update(); + let mut new_params: Vec = Vec::new(); for old_strukt_param in old_strukt_params.generic_params() { // Get old name from `strukt` - let name = SmolStr::from(match &old_strukt_param { - ast::GenericParam::ConstParam(c) => c.name()?.to_string(), - ast::GenericParam::LifetimeParam(l) => { - l.lifetime()?.lifetime_ident_token()?.to_string() - } - ast::GenericParam::TypeParam(t) => t.name()?.to_string(), - }); + let name = SmolStr::from(generic_param_name(&old_strukt_param)?); // The new name cannot be conflicted with generics in trait, and the renamed names. let param_list_to_names = |param_list: &GenericParamList| { @@ -613,8 +687,9 @@ fn resolve_name_conflicts( p => Some(p.to_string()), }) }; + let new_params_list = make.generic_param_list(new_params.clone()); let existing_names = param_list_to_names(old_impl_params) - .chain(param_list_to_names(¶ms)) + .chain(param_list_to_names(&new_params_list)) .collect_vec(); let mut name_generator = suggest_name::NameGenerator::new_with_names( existing_names.iter().map(|s| s.as_str()), @@ -623,25 +698,21 @@ fn resolve_name_conflicts( match old_strukt_param { ast::GenericParam::ConstParam(c) => { if let Some(const_ty) = c.ty() { - let const_param = make::const_param(make::name(&name), const_ty); - params.add_generic_param(ast::GenericParam::ConstParam( - const_param.clone_for_update(), - )); + let const_param = make.const_param(make.name(&name), const_ty); + new_params.push(ast::GenericParam::ConstParam(const_param)); } } p @ ast::GenericParam::LifetimeParam(_) => { - params.add_generic_param(p.clone_for_update()); + new_params.push(p.clone_for_update()); } ast::GenericParam::TypeParam(t) => { let type_bounds = t.type_bound_list(); - let type_param = make::type_param(make::name(&name), type_bounds); - params.add_generic_param(ast::GenericParam::TypeParam( - type_param.clone_for_update(), - )); + let type_param = make.type_param(make.name(&name), type_bounds); + new_params.push(ast::GenericParam::TypeParam(type_param)); } } } - Some(params) + Some(make.generic_param_list(new_params)) } (Some(old_strukt_gpl), None) => Some(old_strukt_gpl), _ => None, @@ -666,7 +737,8 @@ fn process_assoc_item( } fn const_assoc_item(item: syntax::ast::Const, qual_path_ty: ast::Path) -> Option { - let path_expr_segment = make::path_from_text(item.name()?.to_string().as_str()); + let make = SyntaxFactory::without_mappings(); + let path_expr_segment = make.path_from_text(item.name()?.to_string().as_str()); // We want rhs of the const assignment to be a qualified path // The general case for const assignment can be found [here](`https://doc.rust-lang.org/reference/items/constant-items.html`) @@ -674,15 +746,14 @@ fn const_assoc_item(item: syntax::ast::Const, qual_path_ty: ast::Path) -> Option // >::ConstName; // FIXME : We can't rely on `make::path_qualified` for now but it would be nice to replace the following with it. // make::path_qualified(qual_path_ty, path_expr_segment.as_single_segment().unwrap()); - let qualified_path = qualified_path(qual_path_ty, path_expr_segment); - let inner = make::item_const( + let qualified_path = make.path_from_text(&format!("{qual_path_ty}::{path_expr_segment}")); + let inner = make.item_const( item.attrs(), item.visibility(), item.name()?, item.ty()?, - make::expr_path(qualified_path), - ) - .clone_for_update(); + make.expr_path(qualified_path), + ); Some(AssocItem::Const(inner)) } @@ -692,59 +763,46 @@ fn func_assoc_item( qual_path_ty: Path, base_name: &str, ) -> Option { - let path_expr_segment = make::path_from_text(item.name()?.to_string().as_str()); - let qualified_path = qualified_path(qual_path_ty, path_expr_segment); + let make = SyntaxFactory::without_mappings(); + let path_expr_segment = make.path_from_text(item.name()?.to_string().as_str()); + let qualified_path = make.path_from_text(&format!("{qual_path_ty}::{path_expr_segment}")); let call = match item.param_list() { // Methods and funcs should be handled separately. // We ask if the func has a `self` param. Some(l) => match l.self_param() { Some(slf) => { - let mut self_kw = make::expr_path(make::path_from_text("self")); - self_kw = make::expr_field(self_kw, base_name); + let self_kw = make.expr_path(make.path_from_text("self")); + let self_kw = make.expr_field(self_kw, base_name).into(); let tail_expr_self = match slf.kind() { ast::SelfParamKind::Owned => self_kw, - ast::SelfParamKind::Ref => make::expr_ref(self_kw, false), - ast::SelfParamKind::MutRef => make::expr_ref(self_kw, true), + ast::SelfParamKind::Ref => make.expr_ref(self_kw, false), + ast::SelfParamKind::MutRef => make.expr_ref(self_kw, true), }; - let param_count = l.params().count(); - let args = convert_param_list_to_arg_list(l).clone_for_update(); - let pos_after_l_paren = Position::after(args.l_paren_token()?); - if param_count > 0 { - // Add SelfParam and a TOKEN::COMMA - ted::insert_all_raw( - pos_after_l_paren, - vec![ - NodeOrToken::Node(tail_expr_self.syntax().clone_for_update()), - NodeOrToken::Token(make::token(SyntaxKind::COMMA)), - NodeOrToken::Token(make::token(SyntaxKind::WHITESPACE)), - ], - ); - } else { - // Add SelfParam only - ted::insert_raw( - pos_after_l_paren, - NodeOrToken::Node(tail_expr_self.syntax().clone_for_update()), - ); - } + // Build argument list with self expression prepended + let other_args = convert_param_list_to_arg_list(l); + let all_args: Vec = + std::iter::once(tail_expr_self).chain(other_args.args()).collect(); + let args = make.arg_list(all_args); - make::expr_call(make::expr_path(qualified_path), args) - } - None => { - make::expr_call(make::expr_path(qualified_path), convert_param_list_to_arg_list(l)) + make.expr_call(make.expr_path(qualified_path), args).into() } + None => make + .expr_call(make.expr_path(qualified_path), convert_param_list_to_arg_list(l)) + .into(), }, - None => make::expr_call( - make::expr_path(qualified_path), - convert_param_list_to_arg_list(make::param_list(None, Vec::new())), - ), - } - .clone_for_update(); + None => make + .expr_call( + make.expr_path(qualified_path), + convert_param_list_to_arg_list(make.param_list(None, Vec::new())), + ) + .into(), + }; - let body = make::block_expr(vec![], Some(call.into())).clone_for_update(); - let func = make::fn_( + let body = make.block_expr(vec![], Some(call)); + let func = make.fn_( item.attrs(), item.visibility(), item.name()?, @@ -757,35 +815,32 @@ fn func_assoc_item( item.const_token().is_some(), item.unsafe_token().is_some(), item.gen_token().is_some(), - ) - .clone_for_update(); + ); Some(AssocItem::Fn(func.indent(edit::IndentLevel(1)))) } fn ty_assoc_item(item: syntax::ast::TypeAlias, qual_path_ty: Path) -> Option { - let path_expr_segment = make::path_from_text(item.name()?.to_string().as_str()); - let qualified_path = qualified_path(qual_path_ty, path_expr_segment); - let ty = make::ty_path(qualified_path); + let make = SyntaxFactory::without_mappings(); + let path_expr_segment = make.path_from_text(item.name()?.to_string().as_str()); + let qualified_path = make.path_from_text(&format!("{qual_path_ty}::{path_expr_segment}")); + let ty = make.ty_path(qualified_path).into(); let ident = item.name()?.to_string(); - let alias = make::ty_alias( - item.attrs(), - ident.as_str(), - item.generic_param_list(), - None, - item.where_clause(), - Some((ty, None)), - ) - .indent(edit::IndentLevel(1)); + let alias = make + .ty_alias( + item.attrs(), + ident.as_str(), + item.generic_param_list(), + None, + item.where_clause(), + Some((ty, None)), + ) + .indent(edit::IndentLevel(1)); Some(AssocItem::TypeAlias(alias)) } -fn qualified_path(qual_path_ty: ast::Path, path_expr_seg: ast::Path) -> ast::Path { - make::path_from_text(&format!("{qual_path_ty}::{path_expr_seg}")) -} - #[cfg(test)] mod test { From b405964c94fd40e7783ac5b9a2b1954509437213 Mon Sep 17 00:00:00 2001 From: Young-Flash Date: Thu, 4 Dec 2025 23:30:01 +0800 Subject: [PATCH 0291/3801] minor: fmt & clippy --- .../crates/syntax/src/ast/syntax_factory/constructors.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 9847d639d613..8efad0368a9d 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -71,7 +71,6 @@ impl SyntaxFactory { ast } - pub fn path_from_text(&self, text: &str) -> ast::Path { make::path_from_text(text).clone_for_update() } @@ -213,10 +212,10 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); - if let Some(self_param) = self_param { - if let Some(new_self_param) = ast.self_param() { - builder.map_node(self_param.syntax().clone(), new_self_param.syntax().clone()); - } + if let Some(self_param) = self_param + && let Some(new_self_param) = ast.self_param() + { + builder.map_node(self_param.syntax().clone(), new_self_param.syntax().clone()); } builder.map_children(input, ast.params().map(|p| p.syntax().clone())); builder.finish(&mut mapping); From 109e097127f8198c206926de879ece89be15b7e1 Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 28 Aug 2025 04:34:53 +0530 Subject: [PATCH 0292/3801] (Partially) Stabilize AVX512-FP16, except for functions that explicitly use `f16` in the signature --- .../crates/core_arch/src/x86/avx512fp16.rs | 1762 ++++++++--------- .../crates/core_arch/src/x86/avxneconvert.rs | 8 +- .../stdarch/crates/core_arch/src/x86/mod.rs | 4 +- .../crates/core_arch/src/x86_64/avx512fp16.rs | 24 +- .../crates/core_arch/src/x86_64/mod.rs | 2 +- 5 files changed, 900 insertions(+), 900 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs index de058c307308..df53a1b29450 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs @@ -247,7 +247,7 @@ pub const fn _mm512_setr_ph( /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setzero_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_setzero_ph() -> __m128h { unsafe { transmute(f16x8::ZERO) } @@ -258,7 +258,7 @@ pub const fn _mm_setzero_ph() -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_setzero_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_setzero_ph() -> __m256h { f16x16::ZERO.as_m256h() @@ -269,7 +269,7 @@ pub const fn _mm256_setzero_ph() -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_setzero_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_setzero_ph() -> __m512h { f16x32::ZERO.as_m512h() @@ -283,7 +283,7 @@ pub const fn _mm512_setzero_ph() -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_undefined_ph() -> __m128h { f16x8::ZERO.as_m128h() @@ -297,7 +297,7 @@ pub const fn _mm_undefined_ph() -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_undefined_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_undefined_ph() -> __m256h { f16x16::ZERO.as_m256h() @@ -311,7 +311,7 @@ pub const fn _mm256_undefined_ph() -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_undefined_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_undefined_ph() -> __m512h { f16x32::ZERO.as_m512h() @@ -323,7 +323,7 @@ pub const fn _mm512_undefined_ph() -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_castpd_ph(a: __m128d) -> __m128h { unsafe { transmute(a) } @@ -335,7 +335,7 @@ pub const fn _mm_castpd_ph(a: __m128d) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_castpd_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_castpd_ph(a: __m256d) -> __m256h { unsafe { transmute(a) } @@ -347,7 +347,7 @@ pub const fn _mm256_castpd_ph(a: __m256d) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castpd_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castpd_ph(a: __m512d) -> __m512h { unsafe { transmute(a) } @@ -359,7 +359,7 @@ pub const fn _mm512_castpd_ph(a: __m512d) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castph_pd) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_castph_pd(a: __m128h) -> __m128d { unsafe { transmute(a) } @@ -371,7 +371,7 @@ pub const fn _mm_castph_pd(a: __m128h) -> __m128d { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_castph_pd) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_castph_pd(a: __m256h) -> __m256d { unsafe { transmute(a) } @@ -383,7 +383,7 @@ pub const fn _mm256_castph_pd(a: __m256h) -> __m256d { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castph_pd) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castph_pd(a: __m512h) -> __m512d { unsafe { transmute(a) } @@ -395,7 +395,7 @@ pub const fn _mm512_castph_pd(a: __m512h) -> __m512d { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castps_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_castps_ph(a: __m128) -> __m128h { unsafe { transmute(a) } @@ -407,7 +407,7 @@ pub const fn _mm_castps_ph(a: __m128) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_castps_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_castps_ph(a: __m256) -> __m256h { unsafe { transmute(a) } @@ -419,7 +419,7 @@ pub const fn _mm256_castps_ph(a: __m256) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castps_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castps_ph(a: __m512) -> __m512h { unsafe { transmute(a) } @@ -431,7 +431,7 @@ pub const fn _mm512_castps_ph(a: __m512) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castph_ps) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_castph_ps(a: __m128h) -> __m128 { unsafe { transmute(a) } @@ -443,7 +443,7 @@ pub const fn _mm_castph_ps(a: __m128h) -> __m128 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_castph_ps) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_castph_ps(a: __m256h) -> __m256 { unsafe { transmute(a) } @@ -455,7 +455,7 @@ pub const fn _mm256_castph_ps(a: __m256h) -> __m256 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castph_ps) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castph_ps(a: __m512h) -> __m512 { unsafe { transmute(a) } @@ -467,7 +467,7 @@ pub const fn _mm512_castph_ps(a: __m512h) -> __m512 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castsi128_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_castsi128_ph(a: __m128i) -> __m128h { unsafe { transmute(a) } @@ -479,7 +479,7 @@ pub const fn _mm_castsi128_ph(a: __m128i) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_castsi256_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_castsi256_ph(a: __m256i) -> __m256h { unsafe { transmute(a) } @@ -491,7 +491,7 @@ pub const fn _mm256_castsi256_ph(a: __m256i) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castsi512_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castsi512_ph(a: __m512i) -> __m512h { unsafe { transmute(a) } @@ -503,7 +503,7 @@ pub const fn _mm512_castsi512_ph(a: __m512i) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castph_si128) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_castph_si128(a: __m128h) -> __m128i { unsafe { transmute(a) } @@ -515,7 +515,7 @@ pub const fn _mm_castph_si128(a: __m128h) -> __m128i { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_castph_si256) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_castph_si256(a: __m256h) -> __m256i { unsafe { transmute(a) } @@ -527,7 +527,7 @@ pub const fn _mm256_castph_si256(a: __m256h) -> __m256i { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castph_si512) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castph_si512(a: __m512h) -> __m512i { unsafe { transmute(a) } @@ -539,7 +539,7 @@ pub const fn _mm512_castph_si512(a: __m512h) -> __m512i { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_castph256_ph128) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_castph256_ph128(a: __m256h) -> __m128h { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]) } @@ -551,7 +551,7 @@ pub const fn _mm256_castph256_ph128(a: __m256h) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castph512_ph128) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castph512_ph128(a: __m512h) -> __m128h { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7]) } @@ -563,7 +563,7 @@ pub const fn _mm512_castph512_ph128(a: __m512h) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castph512_ph256) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castph512_ph256(a: __m512h) -> __m256h { unsafe { simd_shuffle!(a, a, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) } @@ -576,7 +576,7 @@ pub const fn _mm512_castph512_ph256(a: __m512h) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_castph128_ph256) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_castph128_ph256(a: __m128h) -> __m256h { unsafe { @@ -595,7 +595,7 @@ pub const fn _mm256_castph128_ph256(a: __m128h) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castph128_ph512) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castph128_ph512(a: __m128h) -> __m512h { unsafe { @@ -617,7 +617,7 @@ pub const fn _mm512_castph128_ph512(a: __m128h) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_castph256_ph512) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_castph256_ph512(a: __m256h) -> __m512h { unsafe { @@ -639,7 +639,7 @@ pub const fn _mm512_castph256_ph512(a: __m256h) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_zextph128_ph256) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_zextph128_ph256(a: __m128h) -> __m256h { unsafe { @@ -658,7 +658,7 @@ pub const fn _mm256_zextph128_ph256(a: __m128h) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_zextph256_ph512) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_zextph256_ph512(a: __m256h) -> __m512h { unsafe { @@ -680,7 +680,7 @@ pub const fn _mm512_zextph256_ph512(a: __m256h) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_zextph128_ph512) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_zextph128_ph512(a: __m128h) -> __m512h { unsafe { @@ -730,7 +730,7 @@ macro_rules! cmp_asm { // FIXME: use LLVM intrinsics #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cmp_ph_mask(a: __m128h, b: __m128h) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM5, 5); @@ -746,7 +746,7 @@ pub fn _mm_cmp_ph_mask(a: __m128h, b: __m128h) -> __mmask8 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cmp_ph_mask(k1: __mmask8, a: __m128h, b: __m128h) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM5, 5); @@ -761,7 +761,7 @@ pub fn _mm_mask_cmp_ph_mask(k1: __mmask8, a: __m128h, b: __m128 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cmp_ph_mask(a: __m256h, b: __m256h) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM5, 5); @@ -777,7 +777,7 @@ pub fn _mm256_cmp_ph_mask(a: __m256h, b: __m256h) -> __mmask16 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cmp_ph_mask( k1: __mmask16, a: __m256h, @@ -796,7 +796,7 @@ pub fn _mm256_mask_cmp_ph_mask( #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cmp_ph_mask(a: __m512h, b: __m512h) -> __mmask32 { unsafe { static_assert_uimm_bits!(IMM5, 5); @@ -812,7 +812,7 @@ pub fn _mm512_cmp_ph_mask(a: __m512h, b: __m512h) -> __mmask32 #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cmp_ph_mask( k1: __mmask32, a: __m512h, @@ -833,7 +833,7 @@ pub fn _mm512_mask_cmp_ph_mask( #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(2, 3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cmp_round_ph_mask( a: __m512h, b: __m512h, @@ -868,7 +868,7 @@ pub fn _mm512_cmp_round_ph_mask( #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(3, 4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cmp_round_ph_mask( k1: __mmask32, a: __m512h, @@ -903,7 +903,7 @@ pub fn _mm512_mask_cmp_round_ph_mask( #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(2, 3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cmp_round_sh_mask(a: __m128h, b: __m128h) -> __mmask8 { static_assert_uimm_bits!(IMM5, 5); static_assert_sae!(SAE); @@ -918,7 +918,7 @@ pub fn _mm_cmp_round_sh_mask(a: __m128h, b: __m #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(3, 4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cmp_round_sh_mask( k1: __mmask8, a: __m128h, @@ -938,7 +938,7 @@ pub fn _mm_mask_cmp_round_sh_mask( #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cmp_sh_mask(a: __m128h, b: __m128h) -> __mmask8 { static_assert_uimm_bits!(IMM5, 5); _mm_cmp_round_sh_mask::(a, b) @@ -951,7 +951,7 @@ pub fn _mm_cmp_sh_mask(a: __m128h, b: __m128h) -> __mmask8 { #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cmp_sh_mask(k1: __mmask8, a: __m128h, b: __m128h) -> __mmask8 { static_assert_uimm_bits!(IMM5, 5); _mm_mask_cmp_round_sh_mask::(k1, a, b) @@ -965,7 +965,7 @@ pub fn _mm_mask_cmp_sh_mask(k1: __mmask8, a: __m128h, b: __m128 #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(2, 3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_comi_round_sh(a: __m128h, b: __m128h) -> i32 { unsafe { static_assert_uimm_bits!(IMM5, 5); @@ -981,7 +981,7 @@ pub fn _mm_comi_round_sh(a: __m128h, b: __m128h #[inline] #[target_feature(enable = "avx512fp16")] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_comi_sh(a: __m128h, b: __m128h) -> i32 { static_assert_uimm_bits!(IMM5, 5); _mm_comi_round_sh::(a, b) @@ -993,7 +993,7 @@ pub fn _mm_comi_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comieq_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_comieq_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_EQ_OS>(a, b) } @@ -1004,7 +1004,7 @@ pub fn _mm_comieq_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comige_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_comige_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_GE_OS>(a, b) } @@ -1015,7 +1015,7 @@ pub fn _mm_comige_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comigt_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_comigt_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_GT_OS>(a, b) } @@ -1026,7 +1026,7 @@ pub fn _mm_comigt_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comile_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_comile_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_LE_OS>(a, b) } @@ -1037,7 +1037,7 @@ pub fn _mm_comile_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comilt_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_comilt_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_LT_OS>(a, b) } @@ -1048,7 +1048,7 @@ pub fn _mm_comilt_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comineq_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_comineq_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_NEQ_US>(a, b) } @@ -1059,7 +1059,7 @@ pub fn _mm_comineq_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ucomieq_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_ucomieq_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_EQ_OQ>(a, b) } @@ -1070,7 +1070,7 @@ pub fn _mm_ucomieq_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ucomige_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_ucomige_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_GE_OQ>(a, b) } @@ -1081,7 +1081,7 @@ pub fn _mm_ucomige_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ucomigt_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_ucomigt_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_GT_OQ>(a, b) } @@ -1092,7 +1092,7 @@ pub fn _mm_ucomigt_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ucomile_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_ucomile_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_LE_OQ>(a, b) } @@ -1103,7 +1103,7 @@ pub fn _mm_ucomile_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ucomilt_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_ucomilt_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_LT_OQ>(a, b) } @@ -1114,7 +1114,7 @@ pub fn _mm_ucomilt_sh(a: __m128h, b: __m128h) -> i32 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ucomineq_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_ucomineq_sh(a: __m128h, b: __m128h) -> i32 { _mm_comi_sh::<_CMP_NEQ_UQ>(a, b) } @@ -1248,7 +1248,7 @@ pub const unsafe fn _mm512_loadu_ph(mem_addr: *const f16) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mask_move_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_move_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -1267,7 +1267,7 @@ pub const fn _mm_mask_move_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskz_move_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_move_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -1285,7 +1285,7 @@ pub const fn _mm_maskz_move_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_sh) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_move_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -1399,7 +1399,7 @@ pub const unsafe fn _mm512_storeu_ph(mem_addr: *mut f16, a: __m512h) { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_add_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_add(a, b) } @@ -1412,7 +1412,7 @@ pub const fn _mm_add_ph(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_add_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -1428,7 +1428,7 @@ pub const fn _mm_mask_add_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_add_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -1443,7 +1443,7 @@ pub const fn _mm_maskz_add_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_add_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { simd_add(a, b) } @@ -1456,7 +1456,7 @@ pub const fn _mm256_add_ph(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_add_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { @@ -1472,7 +1472,7 @@ pub const fn _mm256_mask_add_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m25 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vaddph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_add_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { @@ -1487,7 +1487,7 @@ pub const fn _mm256_maskz_add_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_add_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { simd_add(a, b) } @@ -1500,7 +1500,7 @@ pub const fn _mm512_add_ph(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_add_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { @@ -1516,7 +1516,7 @@ pub const fn _mm512_mask_add_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_add_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { @@ -1539,7 +1539,7 @@ pub const fn _mm512_maskz_add_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_add_round_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -1562,7 +1562,7 @@ pub fn _mm512_add_round_ph(a: __m512h, b: __m512h) -> __m51 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_add_round_ph( src: __m512h, k: __mmask32, @@ -1590,7 +1590,7 @@ pub fn _mm512_mask_add_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_add_round_ph( k: __mmask32, a: __m512h, @@ -1618,7 +1618,7 @@ pub fn _mm512_maskz_add_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_add_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_add_round_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -1640,7 +1640,7 @@ pub fn _mm_add_round_sh(a: __m128h, b: __m128h) -> __m128h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_add_round_sh( src: __m128h, k: __mmask8, @@ -1669,7 +1669,7 @@ pub fn _mm_mask_add_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_add_round_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_add_round_sh::(f16x8::ZERO.as_m128h(), k, a, b) @@ -1682,7 +1682,7 @@ pub fn _mm_maskz_add_round_sh(k: __mmask8, a: __m128h, b: _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_add_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_insert!(a, 0, _mm_cvtsh_h(a) + _mm_cvtsh_h(b)) } @@ -1696,7 +1696,7 @@ pub const fn _mm_add_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_add_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -1719,7 +1719,7 @@ pub const fn _mm_mask_add_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vaddsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_add_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -1739,7 +1739,7 @@ pub const fn _mm_maskz_add_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_sub_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_sub(a, b) } @@ -1752,7 +1752,7 @@ pub const fn _mm_sub_ph(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_sub_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -1768,7 +1768,7 @@ pub const fn _mm_mask_sub_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_sub_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -1783,7 +1783,7 @@ pub const fn _mm_maskz_sub_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_sub_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { simd_sub(a, b) } @@ -1796,7 +1796,7 @@ pub const fn _mm256_sub_ph(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_sub_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { @@ -1812,7 +1812,7 @@ pub const fn _mm256_mask_sub_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m25 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsubph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_sub_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { @@ -1827,7 +1827,7 @@ pub const fn _mm256_maskz_sub_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_sub_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { simd_sub(a, b) } @@ -1840,7 +1840,7 @@ pub const fn _mm512_sub_ph(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_sub_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { @@ -1856,7 +1856,7 @@ pub const fn _mm512_mask_sub_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_sub_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { @@ -1879,7 +1879,7 @@ pub const fn _mm512_maskz_sub_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_sub_round_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -1902,7 +1902,7 @@ pub fn _mm512_sub_round_ph(a: __m512h, b: __m512h) -> __m51 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_sub_round_ph( src: __m512h, k: __mmask32, @@ -1931,7 +1931,7 @@ pub fn _mm512_mask_sub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_sub_round_ph( k: __mmask32, a: __m512h, @@ -1959,7 +1959,7 @@ pub fn _mm512_maskz_sub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_sub_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_sub_round_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -1981,7 +1981,7 @@ pub fn _mm_sub_round_sh(a: __m128h, b: __m128h) -> __m128h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_sub_round_sh( src: __m128h, k: __mmask8, @@ -2010,7 +2010,7 @@ pub fn _mm_mask_sub_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_sub_round_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_sub_round_sh::(f16x8::ZERO.as_m128h(), k, a, b) @@ -2023,7 +2023,7 @@ pub fn _mm_maskz_sub_round_sh(k: __mmask8, a: __m128h, b: _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_sub_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_insert!(a, 0, _mm_cvtsh_h(a) - _mm_cvtsh_h(b)) } @@ -2037,7 +2037,7 @@ pub const fn _mm_sub_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_sub_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2060,7 +2060,7 @@ pub const fn _mm_mask_sub_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsubsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_sub_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2080,7 +2080,7 @@ pub const fn _mm_maskz_sub_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mul_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_mul(a, b) } @@ -2093,7 +2093,7 @@ pub const fn _mm_mul_ph(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_mul_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2109,7 +2109,7 @@ pub const fn _mm_mask_mul_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_mul_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2124,7 +2124,7 @@ pub const fn _mm_maskz_mul_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mul_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { simd_mul(a, b) } @@ -2137,7 +2137,7 @@ pub const fn _mm256_mul_ph(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_mul_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { @@ -2153,7 +2153,7 @@ pub const fn _mm256_mask_mul_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m25 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmulph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_mul_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { @@ -2168,7 +2168,7 @@ pub const fn _mm256_maskz_mul_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mul_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { simd_mul(a, b) } @@ -2181,7 +2181,7 @@ pub const fn _mm512_mul_ph(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_mul_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { @@ -2197,7 +2197,7 @@ pub const fn _mm512_mask_mul_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_mul_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { @@ -2220,7 +2220,7 @@ pub const fn _mm512_maskz_mul_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mul_round_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -2243,7 +2243,7 @@ pub fn _mm512_mul_round_ph(a: __m512h, b: __m512h) -> __m51 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_mul_round_ph( src: __m512h, k: __mmask32, @@ -2272,7 +2272,7 @@ pub fn _mm512_mask_mul_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_mul_round_ph( k: __mmask32, a: __m512h, @@ -2300,7 +2300,7 @@ pub fn _mm512_maskz_mul_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mul_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_mul_round_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -2322,7 +2322,7 @@ pub fn _mm_mul_round_sh(a: __m128h, b: __m128h) -> __m128h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_mul_round_sh( src: __m128h, k: __mmask8, @@ -2351,7 +2351,7 @@ pub fn _mm_mask_mul_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_mul_round_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_mul_round_sh::(f16x8::ZERO.as_m128h(), k, a, b) @@ -2364,7 +2364,7 @@ pub fn _mm_maskz_mul_round_sh(k: __mmask8, a: __m128h, b: _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mul_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_insert!(a, 0, _mm_cvtsh_h(a) * _mm_cvtsh_h(b)) } @@ -2378,7 +2378,7 @@ pub const fn _mm_mul_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_mul_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2401,7 +2401,7 @@ pub const fn _mm_mask_mul_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmulsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_mul_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2421,7 +2421,7 @@ pub const fn _mm_maskz_mul_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_div_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_div(a, b) } @@ -2434,7 +2434,7 @@ pub const fn _mm_div_ph(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_div_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2450,7 +2450,7 @@ pub const fn _mm_mask_div_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_div_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2465,7 +2465,7 @@ pub const fn _mm_maskz_div_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_div_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { simd_div(a, b) } @@ -2478,7 +2478,7 @@ pub const fn _mm256_div_ph(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_div_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { @@ -2494,7 +2494,7 @@ pub const fn _mm256_mask_div_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m25 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vdivph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_div_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { @@ -2509,7 +2509,7 @@ pub const fn _mm256_maskz_div_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_div_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { simd_div(a, b) } @@ -2522,7 +2522,7 @@ pub const fn _mm512_div_ph(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_div_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { @@ -2538,7 +2538,7 @@ pub const fn _mm512_mask_div_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_div_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { @@ -2561,7 +2561,7 @@ pub const fn _mm512_maskz_div_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_div_round_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -2584,7 +2584,7 @@ pub fn _mm512_div_round_ph(a: __m512h, b: __m512h) -> __m51 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_div_round_ph( src: __m512h, k: __mmask32, @@ -2613,7 +2613,7 @@ pub fn _mm512_mask_div_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_div_round_ph( k: __mmask32, a: __m512h, @@ -2641,7 +2641,7 @@ pub fn _mm512_maskz_div_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_div_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_div_round_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -2663,7 +2663,7 @@ pub fn _mm_div_round_sh(a: __m128h, b: __m128h) -> __m128h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_div_round_sh( src: __m128h, k: __mmask8, @@ -2692,7 +2692,7 @@ pub fn _mm_mask_div_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_div_round_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_div_round_sh::(f16x8::ZERO.as_m128h(), k, a, b) @@ -2705,7 +2705,7 @@ pub fn _mm_maskz_div_round_sh(k: __mmask8, a: __m128h, b: _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_div_sh(a: __m128h, b: __m128h) -> __m128h { unsafe { simd_insert!(a, 0, _mm_cvtsh_h(a) / _mm_cvtsh_h(b)) } @@ -2719,7 +2719,7 @@ pub const fn _mm_div_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_div_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2742,7 +2742,7 @@ pub const fn _mm_mask_div_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vdivsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_div_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { @@ -2764,7 +2764,7 @@ pub const fn _mm_maskz_div_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mul_pch(a: __m128h, b: __m128h) -> __m128h { _mm_mask_mul_pch(_mm_undefined_ph(), 0xff, a, b) } @@ -2777,7 +2777,7 @@ pub fn _mm_mul_pch(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_mul_pch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { transmute(vfmulcph_128(transmute(a), transmute(b), transmute(src), k)) } } @@ -2790,7 +2790,7 @@ pub fn _mm_mask_mul_pch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_mul_pch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_mul_pch(_mm_setzero_ph(), k, a, b) } @@ -2803,7 +2803,7 @@ pub fn _mm_maskz_mul_pch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mul_pch(a: __m256h, b: __m256h) -> __m256h { _mm256_mask_mul_pch(_mm256_undefined_ph(), 0xff, a, b) } @@ -2816,7 +2816,7 @@ pub fn _mm256_mul_pch(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_mul_pch(src: __m256h, k: __mmask8, a: __m256h, b: __m256h) -> __m256h { unsafe { transmute(vfmulcph_256(transmute(a), transmute(b), transmute(src), k)) } } @@ -2829,7 +2829,7 @@ pub fn _mm256_mask_mul_pch(src: __m256h, k: __mmask8, a: __m256h, b: __m256h) -> #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_mul_pch(k: __mmask8, a: __m256h, b: __m256h) -> __m256h { _mm256_mask_mul_pch(_mm256_setzero_ph(), k, a, b) } @@ -2842,7 +2842,7 @@ pub fn _mm256_maskz_mul_pch(k: __mmask8, a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mul_pch(a: __m512h, b: __m512h) -> __m512h { _mm512_mask_mul_pch(_mm512_undefined_ph(), 0xffff, a, b) } @@ -2855,7 +2855,7 @@ pub fn _mm512_mul_pch(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_mul_pch(src: __m512h, k: __mmask16, a: __m512h, b: __m512h) -> __m512h { _mm512_mask_mul_round_pch::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -2868,7 +2868,7 @@ pub fn _mm512_mask_mul_pch(src: __m512h, k: __mmask16, a: __m512h, b: __m512h) - #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_mul_pch(k: __mmask16, a: __m512h, b: __m512h) -> __m512h { _mm512_mask_mul_pch(_mm512_setzero_ph(), k, a, b) } @@ -2890,7 +2890,7 @@ pub fn _mm512_maskz_mul_pch(k: __mmask16, a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mul_round_pch(a: __m512h, b: __m512h) -> __m512h { static_assert_rounding!(ROUNDING); _mm512_mask_mul_round_pch::(_mm512_undefined_ph(), 0xffff, a, b) @@ -2913,7 +2913,7 @@ pub fn _mm512_mul_round_pch(a: __m512h, b: __m512h) -> __m5 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_mul_round_pch( src: __m512h, k: __mmask16, @@ -2949,7 +2949,7 @@ pub fn _mm512_mask_mul_round_pch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_mul_round_pch( k: __mmask16, a: __m512h, @@ -2968,7 +2968,7 @@ pub fn _mm512_maskz_mul_round_pch( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mul_sch(a: __m128h, b: __m128h) -> __m128h { _mm_mask_mul_sch(f16x8::ZERO.as_m128h(), 0xff, a, b) } @@ -2982,7 +2982,7 @@ pub fn _mm_mul_sch(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_mul_sch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_mul_round_sch::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -2996,7 +2996,7 @@ pub fn _mm_mask_mul_sch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_mul_sch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_mul_sch(f16x8::ZERO.as_m128h(), k, a, b) } @@ -3019,7 +3019,7 @@ pub fn _mm_maskz_mul_sch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mul_round_sch(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_mul_round_sch::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -3043,7 +3043,7 @@ pub fn _mm_mul_round_sch(a: __m128h, b: __m128h) -> __m128h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_mul_round_sch( src: __m128h, k: __mmask8, @@ -3080,7 +3080,7 @@ pub fn _mm_mask_mul_round_sch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_mul_round_sch( k: __mmask8, a: __m128h, @@ -3098,7 +3098,7 @@ pub fn _mm_maskz_mul_round_sch( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fmul_pch(a: __m128h, b: __m128h) -> __m128h { _mm_mul_pch(a, b) } @@ -3111,7 +3111,7 @@ pub fn _mm_fmul_pch(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fmul_pch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_mul_pch(src, k, a, b) } @@ -3124,7 +3124,7 @@ pub fn _mm_mask_fmul_pch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fmul_pch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_maskz_mul_pch(k, a, b) } @@ -3137,7 +3137,7 @@ pub fn _mm_maskz_fmul_pch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_fmul_pch(a: __m256h, b: __m256h) -> __m256h { _mm256_mul_pch(a, b) } @@ -3150,7 +3150,7 @@ pub fn _mm256_fmul_pch(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_fmul_pch(src: __m256h, k: __mmask8, a: __m256h, b: __m256h) -> __m256h { _mm256_mask_mul_pch(src, k, a, b) } @@ -3163,7 +3163,7 @@ pub fn _mm256_mask_fmul_pch(src: __m256h, k: __mmask8, a: __m256h, b: __m256h) - #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_fmul_pch(k: __mmask8, a: __m256h, b: __m256h) -> __m256h { _mm256_maskz_mul_pch(k, a, b) } @@ -3175,7 +3175,7 @@ pub fn _mm256_maskz_fmul_pch(k: __mmask8, a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fmul_pch(a: __m512h, b: __m512h) -> __m512h { _mm512_mul_pch(a, b) } @@ -3188,7 +3188,7 @@ pub fn _mm512_fmul_pch(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fmul_pch(src: __m512h, k: __mmask16, a: __m512h, b: __m512h) -> __m512h { _mm512_mask_mul_pch(src, k, a, b) } @@ -3201,7 +3201,7 @@ pub fn _mm512_mask_fmul_pch(src: __m512h, k: __mmask16, a: __m512h, b: __m512h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fmul_pch(k: __mmask16, a: __m512h, b: __m512h) -> __m512h { _mm512_maskz_mul_pch(k, a, b) } @@ -3221,7 +3221,7 @@ pub fn _mm512_maskz_fmul_pch(k: __mmask16, a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fmul_round_pch(a: __m512h, b: __m512h) -> __m512h { static_assert_rounding!(ROUNDING); _mm512_mul_round_pch::(a, b) @@ -3243,7 +3243,7 @@ pub fn _mm512_fmul_round_pch(a: __m512h, b: __m512h) -> __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fmul_round_pch( src: __m512h, k: __mmask16, @@ -3270,7 +3270,7 @@ pub fn _mm512_mask_fmul_round_pch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fmul_round_pch( k: __mmask16, a: __m512h, @@ -3288,7 +3288,7 @@ pub fn _mm512_maskz_fmul_round_pch( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fmul_sch(a: __m128h, b: __m128h) -> __m128h { _mm_mul_sch(a, b) } @@ -3301,7 +3301,7 @@ pub fn _mm_fmul_sch(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fmul_sch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_mul_sch(src, k, a, b) } @@ -3314,7 +3314,7 @@ pub fn _mm_mask_fmul_sch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fmul_sch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_maskz_mul_sch(k, a, b) } @@ -3335,7 +3335,7 @@ pub fn _mm_maskz_fmul_sch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fmul_round_sch(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mul_round_sch::(a, b) @@ -3358,7 +3358,7 @@ pub fn _mm_fmul_round_sch(a: __m128h, b: __m128h) -> __m128 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fmul_round_sch( src: __m128h, k: __mmask8, @@ -3386,7 +3386,7 @@ pub fn _mm_mask_fmul_round_sch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fmul_round_sch( k: __mmask8, a: __m128h, @@ -3405,7 +3405,7 @@ pub fn _mm_maskz_fmul_round_sch( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cmul_pch(a: __m128h, b: __m128h) -> __m128h { _mm_mask_cmul_pch(_mm_undefined_ph(), 0xff, a, b) } @@ -3419,7 +3419,7 @@ pub fn _mm_cmul_pch(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cmul_pch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { transmute(vfcmulcph_128(transmute(a), transmute(b), transmute(src), k)) } } @@ -3433,7 +3433,7 @@ pub fn _mm_mask_cmul_pch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cmul_pch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_cmul_pch(_mm_setzero_ph(), k, a, b) } @@ -3447,7 +3447,7 @@ pub fn _mm_maskz_cmul_pch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cmul_pch(a: __m256h, b: __m256h) -> __m256h { _mm256_mask_cmul_pch(_mm256_undefined_ph(), 0xff, a, b) } @@ -3461,7 +3461,7 @@ pub fn _mm256_cmul_pch(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cmul_pch(src: __m256h, k: __mmask8, a: __m256h, b: __m256h) -> __m256h { unsafe { transmute(vfcmulcph_256(transmute(a), transmute(b), transmute(src), k)) } } @@ -3475,7 +3475,7 @@ pub fn _mm256_mask_cmul_pch(src: __m256h, k: __mmask8, a: __m256h, b: __m256h) - #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cmul_pch(k: __mmask8, a: __m256h, b: __m256h) -> __m256h { _mm256_mask_cmul_pch(_mm256_setzero_ph(), k, a, b) } @@ -3489,7 +3489,7 @@ pub fn _mm256_maskz_cmul_pch(k: __mmask8, a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cmul_pch(a: __m512h, b: __m512h) -> __m512h { _mm512_mask_cmul_pch(_mm512_undefined_ph(), 0xffff, a, b) } @@ -3503,7 +3503,7 @@ pub fn _mm512_cmul_pch(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cmul_pch(src: __m512h, k: __mmask16, a: __m512h, b: __m512h) -> __m512h { _mm512_mask_cmul_round_pch::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -3517,7 +3517,7 @@ pub fn _mm512_mask_cmul_pch(src: __m512h, k: __mmask16, a: __m512h, b: __m512h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cmul_pch(k: __mmask16, a: __m512h, b: __m512h) -> __m512h { _mm512_mask_cmul_pch(_mm512_setzero_ph(), k, a, b) } @@ -3540,7 +3540,7 @@ pub fn _mm512_maskz_cmul_pch(k: __mmask16, a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cmul_round_pch(a: __m512h, b: __m512h) -> __m512h { static_assert_rounding!(ROUNDING); _mm512_mask_cmul_round_pch::(_mm512_undefined_ph(), 0xffff, a, b) @@ -3564,7 +3564,7 @@ pub fn _mm512_cmul_round_pch(a: __m512h, b: __m512h) -> __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cmul_round_pch( src: __m512h, k: __mmask16, @@ -3601,7 +3601,7 @@ pub fn _mm512_mask_cmul_round_pch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cmul_round_pch( k: __mmask16, a: __m512h, @@ -3619,7 +3619,7 @@ pub fn _mm512_maskz_cmul_round_pch( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cmul_sch(a: __m128h, b: __m128h) -> __m128h { _mm_mask_cmul_sch(f16x8::ZERO.as_m128h(), 0xff, a, b) } @@ -3633,7 +3633,7 @@ pub fn _mm_cmul_sch(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cmul_sch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_cmul_round_sch::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -3647,7 +3647,7 @@ pub fn _mm_mask_cmul_sch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cmul_sch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_cmul_sch(f16x8::ZERO.as_m128h(), k, a, b) } @@ -3669,7 +3669,7 @@ pub fn _mm_maskz_cmul_sch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cmul_round_sch(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_cmul_round_sch::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -3693,7 +3693,7 @@ pub fn _mm_cmul_round_sch(a: __m128h, b: __m128h) -> __m128 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cmul_round_sch( src: __m128h, k: __mmask8, @@ -3730,7 +3730,7 @@ pub fn _mm_mask_cmul_round_sch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cmul_round_sch( k: __mmask8, a: __m128h, @@ -3749,7 +3749,7 @@ pub fn _mm_maskz_cmul_round_sch( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fcmul_pch(a: __m128h, b: __m128h) -> __m128h { _mm_cmul_pch(a, b) } @@ -3763,7 +3763,7 @@ pub fn _mm_fcmul_pch(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fcmul_pch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_cmul_pch(src, k, a, b) } @@ -3777,7 +3777,7 @@ pub fn _mm_mask_fcmul_pch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fcmul_pch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_maskz_cmul_pch(k, a, b) } @@ -3791,7 +3791,7 @@ pub fn _mm_maskz_fcmul_pch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_fcmul_pch(a: __m256h, b: __m256h) -> __m256h { _mm256_cmul_pch(a, b) } @@ -3805,7 +3805,7 @@ pub fn _mm256_fcmul_pch(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_fcmul_pch(src: __m256h, k: __mmask8, a: __m256h, b: __m256h) -> __m256h { _mm256_mask_cmul_pch(src, k, a, b) } @@ -3819,7 +3819,7 @@ pub fn _mm256_mask_fcmul_pch(src: __m256h, k: __mmask8, a: __m256h, b: __m256h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_fcmul_pch(k: __mmask8, a: __m256h, b: __m256h) -> __m256h { _mm256_maskz_cmul_pch(k, a, b) } @@ -3833,7 +3833,7 @@ pub fn _mm256_maskz_fcmul_pch(k: __mmask8, a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fcmul_pch(a: __m512h, b: __m512h) -> __m512h { _mm512_cmul_pch(a, b) } @@ -3847,7 +3847,7 @@ pub fn _mm512_fcmul_pch(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fcmul_pch(src: __m512h, k: __mmask16, a: __m512h, b: __m512h) -> __m512h { _mm512_mask_cmul_pch(src, k, a, b) } @@ -3861,7 +3861,7 @@ pub fn _mm512_mask_fcmul_pch(src: __m512h, k: __mmask16, a: __m512h, b: __m512h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fcmul_pch(k: __mmask16, a: __m512h, b: __m512h) -> __m512h { _mm512_maskz_cmul_pch(k, a, b) } @@ -3883,7 +3883,7 @@ pub fn _mm512_maskz_fcmul_pch(k: __mmask16, a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fcmul_round_pch(a: __m512h, b: __m512h) -> __m512h { static_assert_rounding!(ROUNDING); _mm512_cmul_round_pch::(a, b) @@ -3907,7 +3907,7 @@ pub fn _mm512_fcmul_round_pch(a: __m512h, b: __m512h) -> __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fcmul_round_pch( src: __m512h, k: __mmask16, @@ -3936,7 +3936,7 @@ pub fn _mm512_mask_fcmul_round_pch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fcmul_round_pch( k: __mmask16, a: __m512h, @@ -3955,7 +3955,7 @@ pub fn _mm512_maskz_fcmul_round_pch( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fcmul_sch(a: __m128h, b: __m128h) -> __m128h { _mm_cmul_sch(a, b) } @@ -3969,7 +3969,7 @@ pub fn _mm_fcmul_sch(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fcmul_sch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_cmul_sch(src, k, a, b) } @@ -3983,7 +3983,7 @@ pub fn _mm_mask_fcmul_sch(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fcmul_sch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_maskz_cmul_sch(k, a, b) } @@ -4005,7 +4005,7 @@ pub fn _mm_maskz_fcmul_sch(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fcmul_round_sch(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_cmul_round_sch::(a, b) @@ -4029,7 +4029,7 @@ pub fn _mm_fcmul_round_sch(a: __m128h, b: __m128h) -> __m12 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fcmul_round_sch( src: __m128h, k: __mmask8, @@ -4058,7 +4058,7 @@ pub fn _mm_mask_fcmul_round_sch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmulcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fcmul_round_sch( k: __mmask8, a: __m128h, @@ -4074,7 +4074,7 @@ pub fn _mm_maskz_fcmul_round_sch( /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_abs_ph(v2: __m128h) -> __m128h { unsafe { transmute(_mm_and_si128(transmute(v2), _mm_set1_epi16(i16::MAX))) } @@ -4086,7 +4086,7 @@ pub const fn _mm_abs_ph(v2: __m128h) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_abs_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_abs_ph(v2: __m256h) -> __m256h { unsafe { transmute(_mm256_and_si256(transmute(v2), _mm256_set1_epi16(i16::MAX))) } @@ -4098,7 +4098,7 @@ pub const fn _mm256_abs_ph(v2: __m256h) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_abs_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_abs_ph(v2: __m512h) -> __m512h { unsafe { transmute(_mm512_and_si512(transmute(v2), _mm512_set1_epi16(i16::MAX))) } @@ -4112,7 +4112,7 @@ pub const fn _mm512_abs_ph(v2: __m512h) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_conj_pch) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_conj_pch(a: __m128h) -> __m128h { unsafe { transmute(_mm_xor_si128(transmute(a), _mm_set1_epi32(i32::MIN))) } @@ -4126,7 +4126,7 @@ pub const fn _mm_conj_pch(a: __m128h) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mask_conj_pch) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_conj_pch(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { unsafe { @@ -4143,7 +4143,7 @@ pub const fn _mm_mask_conj_pch(src: __m128h, k: __mmask8, a: __m128h) -> __m128h /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskz_conj_pch) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_conj_pch(k: __mmask8, a: __m128h) -> __m128h { _mm_mask_conj_pch(_mm_setzero_ph(), k, a) @@ -4156,7 +4156,7 @@ pub const fn _mm_maskz_conj_pch(k: __mmask8, a: __m128h) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_conj_pch) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_conj_pch(a: __m256h) -> __m256h { unsafe { transmute(_mm256_xor_si256(transmute(a), _mm256_set1_epi32(i32::MIN))) } @@ -4170,7 +4170,7 @@ pub const fn _mm256_conj_pch(a: __m256h) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_mask_conj_pch) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_conj_pch(src: __m256h, k: __mmask8, a: __m256h) -> __m256h { unsafe { @@ -4187,7 +4187,7 @@ pub const fn _mm256_mask_conj_pch(src: __m256h, k: __mmask8, a: __m256h) -> __m2 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_maskz_conj_pch) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_conj_pch(k: __mmask8, a: __m256h) -> __m256h { _mm256_mask_conj_pch(_mm256_setzero_ph(), k, a) @@ -4200,7 +4200,7 @@ pub const fn _mm256_maskz_conj_pch(k: __mmask8, a: __m256h) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_conj_pch) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_conj_pch(a: __m512h) -> __m512h { unsafe { transmute(_mm512_xor_si512(transmute(a), _mm512_set1_epi32(i32::MIN))) } @@ -4214,7 +4214,7 @@ pub const fn _mm512_conj_pch(a: __m512h) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_mask_conj_pch) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_conj_pch(src: __m512h, k: __mmask16, a: __m512h) -> __m512h { unsafe { @@ -4231,7 +4231,7 @@ pub const fn _mm512_mask_conj_pch(src: __m512h, k: __mmask16, a: __m512h) -> __m /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_maskz_conj_pch) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_conj_pch(k: __mmask16, a: __m512h) -> __m512h { _mm512_mask_conj_pch(_mm512_setzero_ph(), k, a) @@ -4245,7 +4245,7 @@ pub const fn _mm512_maskz_conj_pch(k: __mmask16, a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fmadd_pch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { _mm_mask3_fmadd_pch(a, b, c, 0xff) } @@ -4259,7 +4259,7 @@ pub fn _mm_fmadd_pch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fmadd_pch(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { let r: __m128 = transmute(_mm_mask3_fmadd_pch(a, b, c, k)); // using `0xff` would have been fine here, but this is what CLang does @@ -4276,7 +4276,7 @@ pub fn _mm_mask_fmadd_pch(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fmadd_pch(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { transmute(vfmaddcph_mask3_128( @@ -4297,7 +4297,7 @@ pub fn _mm_mask3_fmadd_pch(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> _ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fmadd_pch(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { transmute(vfmaddcph_maskz_128( @@ -4317,7 +4317,7 @@ pub fn _mm_maskz_fmadd_pch(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_fmadd_pch(a: __m256h, b: __m256h, c: __m256h) -> __m256h { _mm256_mask3_fmadd_pch(a, b, c, 0xff) } @@ -4331,7 +4331,7 @@ pub fn _mm256_fmadd_pch(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_fmadd_pch(a: __m256h, k: __mmask8, b: __m256h, c: __m256h) -> __m256h { unsafe { let r: __m256 = transmute(_mm256_mask3_fmadd_pch(a, b, c, k)); // using `0xff` would have been fine here, but this is what CLang does @@ -4348,7 +4348,7 @@ pub fn _mm256_mask_fmadd_pch(a: __m256h, k: __mmask8, b: __m256h, c: __m256h) -> #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask3_fmadd_pch(a: __m256h, b: __m256h, c: __m256h, k: __mmask8) -> __m256h { unsafe { transmute(vfmaddcph_mask3_256( @@ -4369,7 +4369,7 @@ pub fn _mm256_mask3_fmadd_pch(a: __m256h, b: __m256h, c: __m256h, k: __mmask8) - #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_fmadd_pch(k: __mmask8, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { transmute(vfmaddcph_maskz_256( @@ -4389,7 +4389,7 @@ pub fn _mm256_maskz_fmadd_pch(k: __mmask8, a: __m256h, b: __m256h, c: __m256h) - #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fmadd_pch(a: __m512h, b: __m512h, c: __m512h) -> __m512h { _mm512_fmadd_round_pch::<_MM_FROUND_CUR_DIRECTION>(a, b, c) } @@ -4403,7 +4403,7 @@ pub fn _mm512_fmadd_pch(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fmadd_pch(a: __m512h, k: __mmask16, b: __m512h, c: __m512h) -> __m512h { _mm512_mask_fmadd_round_pch::<_MM_FROUND_CUR_DIRECTION>(a, k, b, c) } @@ -4417,7 +4417,7 @@ pub fn _mm512_mask_fmadd_pch(a: __m512h, k: __mmask16, b: __m512h, c: __m512h) - #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fmadd_pch(a: __m512h, b: __m512h, c: __m512h, k: __mmask16) -> __m512h { _mm512_mask3_fmadd_round_pch::<_MM_FROUND_CUR_DIRECTION>(a, b, c, k) } @@ -4431,7 +4431,7 @@ pub fn _mm512_mask3_fmadd_pch(a: __m512h, b: __m512h, c: __m512h, k: __mmask16) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fmadd_pch(k: __mmask16, a: __m512h, b: __m512h, c: __m512h) -> __m512h { _mm512_maskz_fmadd_round_pch::<_MM_FROUND_CUR_DIRECTION>(k, a, b, c) } @@ -4453,7 +4453,7 @@ pub fn _mm512_maskz_fmadd_pch(k: __mmask16, a: __m512h, b: __m512h, c: __m512h) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fmadd_round_pch(a: __m512h, b: __m512h, c: __m512h) -> __m512h { static_assert_rounding!(ROUNDING); _mm512_mask3_fmadd_round_pch::(a, b, c, 0xffff) @@ -4477,7 +4477,7 @@ pub fn _mm512_fmadd_round_pch(a: __m512h, b: __m512h, c: __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fmadd_round_pch( a: __m512h, k: __mmask16, @@ -4509,7 +4509,7 @@ pub fn _mm512_mask_fmadd_round_pch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fmadd_round_pch( a: __m512h, b: __m512h, @@ -4546,7 +4546,7 @@ pub fn _mm512_mask3_fmadd_round_pch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fmadd_round_pch( k: __mmask16, a: __m512h, @@ -4574,7 +4574,7 @@ pub fn _mm512_maskz_fmadd_round_pch( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fmadd_sch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { _mm_fmadd_round_sch::<_MM_FROUND_CUR_DIRECTION>(a, b, c) } @@ -4589,7 +4589,7 @@ pub fn _mm_fmadd_sch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fmadd_sch(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { _mm_mask_fmadd_round_sch::<_MM_FROUND_CUR_DIRECTION>(a, k, b, c) } @@ -4604,7 +4604,7 @@ pub fn _mm_mask_fmadd_sch(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fmadd_sch(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { _mm_mask3_fmadd_round_sch::<_MM_FROUND_CUR_DIRECTION>(a, b, c, k) } @@ -4619,7 +4619,7 @@ pub fn _mm_mask3_fmadd_sch(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fmadd_sch(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { _mm_maskz_fmadd_round_sch::<_MM_FROUND_CUR_DIRECTION>(k, a, b, c) } @@ -4641,7 +4641,7 @@ pub fn _mm_maskz_fmadd_sch(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fmadd_round_sch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -4674,7 +4674,7 @@ pub fn _mm_fmadd_round_sch(a: __m128h, b: __m128h, c: __m12 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fmadd_round_sch( a: __m128h, k: __mmask8, @@ -4708,7 +4708,7 @@ pub fn _mm_mask_fmadd_round_sch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fmadd_round_sch( a: __m128h, b: __m128h, @@ -4742,7 +4742,7 @@ pub fn _mm_mask3_fmadd_round_sch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fmadd_round_sch( k: __mmask8, a: __m128h, @@ -4770,7 +4770,7 @@ pub fn _mm_maskz_fmadd_round_sch( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fcmadd_pch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { _mm_mask3_fcmadd_pch(a, b, c, 0xff) } @@ -4785,7 +4785,7 @@ pub fn _mm_fcmadd_pch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fcmadd_pch(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { let r: __m128 = transmute(_mm_mask3_fcmadd_pch(a, b, c, k)); // using `0xff` would have been fine here, but this is what CLang does @@ -4803,7 +4803,7 @@ pub fn _mm_mask_fcmadd_pch(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fcmadd_pch(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { transmute(vfcmaddcph_mask3_128( @@ -4825,7 +4825,7 @@ pub fn _mm_mask3_fcmadd_pch(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fcmadd_pch(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { transmute(vfcmaddcph_maskz_128( @@ -4846,7 +4846,7 @@ pub fn _mm_maskz_fcmadd_pch(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_fcmadd_pch(a: __m256h, b: __m256h, c: __m256h) -> __m256h { _mm256_mask3_fcmadd_pch(a, b, c, 0xff) } @@ -4861,7 +4861,7 @@ pub fn _mm256_fcmadd_pch(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_fcmadd_pch(a: __m256h, k: __mmask8, b: __m256h, c: __m256h) -> __m256h { unsafe { let r: __m256 = transmute(_mm256_mask3_fcmadd_pch(a, b, c, k)); // using `0xff` would have been fine here, but this is what CLang does @@ -4879,7 +4879,7 @@ pub fn _mm256_mask_fcmadd_pch(a: __m256h, k: __mmask8, b: __m256h, c: __m256h) - #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask3_fcmadd_pch(a: __m256h, b: __m256h, c: __m256h, k: __mmask8) -> __m256h { unsafe { transmute(vfcmaddcph_mask3_256( @@ -4901,7 +4901,7 @@ pub fn _mm256_mask3_fcmadd_pch(a: __m256h, b: __m256h, c: __m256h, k: __mmask8) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_fcmadd_pch(k: __mmask8, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { transmute(vfcmaddcph_maskz_256( @@ -4922,7 +4922,7 @@ pub fn _mm256_maskz_fcmadd_pch(k: __mmask8, a: __m256h, b: __m256h, c: __m256h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fcmadd_pch(a: __m512h, b: __m512h, c: __m512h) -> __m512h { _mm512_fcmadd_round_pch::<_MM_FROUND_CUR_DIRECTION>(a, b, c) } @@ -4937,7 +4937,7 @@ pub fn _mm512_fcmadd_pch(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fcmadd_pch(a: __m512h, k: __mmask16, b: __m512h, c: __m512h) -> __m512h { _mm512_mask_fcmadd_round_pch::<_MM_FROUND_CUR_DIRECTION>(a, k, b, c) } @@ -4952,7 +4952,7 @@ pub fn _mm512_mask_fcmadd_pch(a: __m512h, k: __mmask16, b: __m512h, c: __m512h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fcmadd_pch(a: __m512h, b: __m512h, c: __m512h, k: __mmask16) -> __m512h { _mm512_mask3_fcmadd_round_pch::<_MM_FROUND_CUR_DIRECTION>(a, b, c, k) } @@ -4967,7 +4967,7 @@ pub fn _mm512_mask3_fcmadd_pch(a: __m512h, b: __m512h, c: __m512h, k: __mmask16) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fcmadd_pch(k: __mmask16, a: __m512h, b: __m512h, c: __m512h) -> __m512h { _mm512_maskz_fcmadd_round_pch::<_MM_FROUND_CUR_DIRECTION>(k, a, b, c) } @@ -4990,7 +4990,7 @@ pub fn _mm512_maskz_fcmadd_pch(k: __mmask16, a: __m512h, b: __m512h, c: __m512h) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fcmadd_round_pch(a: __m512h, b: __m512h, c: __m512h) -> __m512h { static_assert_rounding!(ROUNDING); _mm512_mask3_fcmadd_round_pch::(a, b, c, 0xffff) @@ -5015,7 +5015,7 @@ pub fn _mm512_fcmadd_round_pch(a: __m512h, b: __m512h, c: _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fcmadd_round_pch( a: __m512h, k: __mmask16, @@ -5048,7 +5048,7 @@ pub fn _mm512_mask_fcmadd_round_pch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fcmadd_round_pch( a: __m512h, b: __m512h, @@ -5086,7 +5086,7 @@ pub fn _mm512_mask3_fcmadd_round_pch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fcmadd_round_pch( k: __mmask16, a: __m512h, @@ -5115,7 +5115,7 @@ pub fn _mm512_maskz_fcmadd_round_pch( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fcmadd_sch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { _mm_fcmadd_round_sch::<_MM_FROUND_CUR_DIRECTION>(a, b, c) } @@ -5131,7 +5131,7 @@ pub fn _mm_fcmadd_sch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fcmadd_sch(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { _mm_mask_fcmadd_round_sch::<_MM_FROUND_CUR_DIRECTION>(a, k, b, c) } @@ -5147,7 +5147,7 @@ pub fn _mm_mask_fcmadd_sch(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fcmadd_sch(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { _mm_mask3_fcmadd_round_sch::<_MM_FROUND_CUR_DIRECTION>(a, b, c, k) } @@ -5163,7 +5163,7 @@ pub fn _mm_mask3_fcmadd_sch(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fcmadd_sch(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { _mm_maskz_fcmadd_round_sch::<_MM_FROUND_CUR_DIRECTION>(k, a, b, c) } @@ -5187,7 +5187,7 @@ pub fn _mm_maskz_fcmadd_sch(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fcmadd_round_sch(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -5221,7 +5221,7 @@ pub fn _mm_fcmadd_round_sch(a: __m128h, b: __m128h, c: __m1 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fcmadd_round_sch( a: __m128h, k: __mmask8, @@ -5256,7 +5256,7 @@ pub fn _mm_mask_fcmadd_round_sch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fcmadd_round_sch( a: __m128h, b: __m128h, @@ -5291,7 +5291,7 @@ pub fn _mm_mask3_fcmadd_round_sch( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfcmaddcsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fcmadd_round_sch( k: __mmask8, a: __m128h, @@ -5317,7 +5317,7 @@ pub fn _mm_maskz_fcmadd_round_sch( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_fma(a, b, c) } @@ -5331,7 +5331,7 @@ pub const fn _mm_fmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmadd_ph(a, b, c), a) } @@ -5345,7 +5345,7 @@ pub const fn _mm_mask_fmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmadd_ph(a, b, c), c) } @@ -5359,7 +5359,7 @@ pub const fn _mm_mask3_fmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmadd_ph(a, b, c), _mm_setzero_ph()) } @@ -5372,7 +5372,7 @@ pub const fn _mm_maskz_fmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_fmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_fma(a, b, c) } @@ -5386,7 +5386,7 @@ pub const fn _mm256_fmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_fmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmadd_ph(a, b, c), a) } @@ -5400,7 +5400,7 @@ pub const fn _mm256_mask_fmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m25 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask3_fmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmadd_ph(a, b, c), c) } @@ -5414,7 +5414,7 @@ pub const fn _mm256_mask3_fmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmas #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_fmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmadd_ph(a, b, c), _mm256_setzero_ph()) } @@ -5427,7 +5427,7 @@ pub const fn _mm256_maskz_fmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m2 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_fmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_fma(a, b, c) } @@ -5441,7 +5441,7 @@ pub const fn _mm512_fmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_fmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmadd_ph(a, b, c), a) } @@ -5455,7 +5455,7 @@ pub const fn _mm512_mask_fmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask3_fmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmadd_ph(a, b, c), c) } @@ -5469,7 +5469,7 @@ pub const fn _mm512_mask3_fmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmas #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_fmadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmadd_ph(a, b, c), _mm512_setzero_ph()) } @@ -5491,7 +5491,7 @@ pub const fn _mm512_maskz_fmadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m5 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fmadd_round_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -5516,7 +5516,7 @@ pub fn _mm512_fmadd_round_ph(a: __m512h, b: __m512h, c: __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fmadd_round_ph( a: __m512h, k: __mmask32, @@ -5546,7 +5546,7 @@ pub fn _mm512_mask_fmadd_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fmadd_round_ph( a: __m512h, b: __m512h, @@ -5576,7 +5576,7 @@ pub fn _mm512_mask3_fmadd_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fmadd_round_ph( k: __mmask32, a: __m512h, @@ -5601,7 +5601,7 @@ pub fn _mm512_maskz_fmadd_round_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -5622,7 +5622,7 @@ pub const fn _mm_fmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -5645,7 +5645,7 @@ pub const fn _mm_mask_fmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { @@ -5668,7 +5668,7 @@ pub const fn _mm_mask3_fmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fmadd_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -5700,7 +5700,7 @@ pub const fn _mm_maskz_fmadd_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fmadd_round_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -5730,7 +5730,7 @@ pub fn _mm_fmadd_round_sh(a: __m128h, b: __m128h, c: __m128 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fmadd_round_sh( a: __m128h, k: __mmask8, @@ -5767,7 +5767,7 @@ pub fn _mm_mask_fmadd_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fmadd_round_sh( a: __m128h, b: __m128h, @@ -5804,7 +5804,7 @@ pub fn _mm_mask3_fmadd_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fmadd_round_sh( k: __mmask8, a: __m128h, @@ -5832,7 +5832,7 @@ pub fn _mm_maskz_fmadd_round_sh( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_fma(a, b, simd_neg(c)) } @@ -5846,7 +5846,7 @@ pub const fn _mm_fmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsub_ph(a, b, c), a) } @@ -5860,7 +5860,7 @@ pub const fn _mm_mask_fmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsub_ph(a, b, c), c) } @@ -5874,7 +5874,7 @@ pub const fn _mm_mask3_fmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsub_ph(a, b, c), _mm_setzero_ph()) } @@ -5887,7 +5887,7 @@ pub const fn _mm_maskz_fmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_fmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_fma(a, b, simd_neg(c)) } @@ -5901,7 +5901,7 @@ pub const fn _mm256_fmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_fmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsub_ph(a, b, c), a) } @@ -5915,7 +5915,7 @@ pub const fn _mm256_mask_fmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m25 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask3_fmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsub_ph(a, b, c), c) } @@ -5929,7 +5929,7 @@ pub const fn _mm256_mask3_fmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmas #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_fmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsub_ph(a, b, c), _mm256_setzero_ph()) } @@ -5942,7 +5942,7 @@ pub const fn _mm256_maskz_fmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m2 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_fmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_fma(a, b, simd_neg(c)) } @@ -5956,7 +5956,7 @@ pub const fn _mm512_fmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_fmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsub_ph(a, b, c), a) } @@ -5970,7 +5970,7 @@ pub const fn _mm512_mask_fmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask3_fmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsub_ph(a, b, c), c) } @@ -5984,7 +5984,7 @@ pub const fn _mm512_mask3_fmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmas #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_fmsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsub_ph(a, b, c), _mm512_setzero_ph()) } @@ -6006,7 +6006,7 @@ pub const fn _mm512_maskz_fmsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m5 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fmsub_round_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -6031,7 +6031,7 @@ pub fn _mm512_fmsub_round_ph(a: __m512h, b: __m512h, c: __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fmsub_round_ph( a: __m512h, k: __mmask32, @@ -6061,7 +6061,7 @@ pub fn _mm512_mask_fmsub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fmsub_round_ph( a: __m512h, b: __m512h, @@ -6091,7 +6091,7 @@ pub fn _mm512_mask3_fmsub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fmsub_round_ph( k: __mmask32, a: __m512h, @@ -6116,7 +6116,7 @@ pub fn _mm512_maskz_fmsub_round_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -6137,7 +6137,7 @@ pub const fn _mm_fmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -6160,7 +6160,7 @@ pub const fn _mm_mask_fmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { @@ -6183,7 +6183,7 @@ pub const fn _mm_mask3_fmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fmsub_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -6215,7 +6215,7 @@ pub const fn _mm_maskz_fmsub_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fmsub_round_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -6245,7 +6245,7 @@ pub fn _mm_fmsub_round_sh(a: __m128h, b: __m128h, c: __m128 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fmsub_round_sh( a: __m128h, k: __mmask8, @@ -6282,7 +6282,7 @@ pub fn _mm_mask_fmsub_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fmsub_round_sh( a: __m128h, b: __m128h, @@ -6311,7 +6311,7 @@ pub fn _mm_mask3_fmsub_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fmsub_round_sh( k: __mmask8, a: __m128h, @@ -6338,7 +6338,7 @@ pub fn _mm_maskz_fmsub_round_sh( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_fma(simd_neg(a), b, c) } @@ -6352,7 +6352,7 @@ pub const fn _mm_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fnmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmadd_ph(a, b, c), a) } @@ -6366,7 +6366,7 @@ pub const fn _mm_mask_fnmadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmadd_ph(a, b, c), c) } @@ -6380,7 +6380,7 @@ pub const fn _mm_mask3_fnmadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fnmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmadd_ph(a, b, c), _mm_setzero_ph()) } @@ -6393,7 +6393,7 @@ pub const fn _mm_maskz_fnmadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_fma(simd_neg(a), b, c) } @@ -6407,7 +6407,7 @@ pub const fn _mm256_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_fnmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmadd_ph(a, b, c), a) } @@ -6421,7 +6421,7 @@ pub const fn _mm256_mask_fnmadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m2 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask3_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmadd_ph(a, b, c), c) } @@ -6435,7 +6435,7 @@ pub const fn _mm256_mask3_fnmadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mma #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_fnmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmadd_ph(a, b, c), _mm256_setzero_ph()) } @@ -6448,7 +6448,7 @@ pub const fn _mm256_maskz_fnmadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_fma(simd_neg(a), b, c) } @@ -6462,7 +6462,7 @@ pub const fn _mm512_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_fnmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmadd_ph(a, b, c), a) } @@ -6476,7 +6476,7 @@ pub const fn _mm512_mask_fnmadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m5 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask3_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmadd_ph(a, b, c), c) } @@ -6490,7 +6490,7 @@ pub const fn _mm512_mask3_fnmadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mma #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_fnmadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmadd_ph(a, b, c), _mm512_setzero_ph()) } @@ -6512,7 +6512,7 @@ pub const fn _mm512_maskz_fnmadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fnmadd_round_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -6537,7 +6537,7 @@ pub fn _mm512_fnmadd_round_ph(a: __m512h, b: __m512h, c: __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fnmadd_round_ph( a: __m512h, k: __mmask32, @@ -6567,7 +6567,7 @@ pub fn _mm512_mask_fnmadd_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fnmadd_round_ph( a: __m512h, b: __m512h, @@ -6597,7 +6597,7 @@ pub fn _mm512_mask3_fnmadd_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fnmadd_round_ph( k: __mmask32, a: __m512h, @@ -6622,7 +6622,7 @@ pub fn _mm512_maskz_fnmadd_round_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -6643,7 +6643,7 @@ pub const fn _mm_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fnmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -6666,7 +6666,7 @@ pub const fn _mm_mask_fnmadd_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { @@ -6689,7 +6689,7 @@ pub const fn _mm_mask3_fnmadd_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fnmadd_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -6721,7 +6721,7 @@ pub const fn _mm_maskz_fnmadd_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fnmadd_round_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -6751,7 +6751,7 @@ pub fn _mm_fnmadd_round_sh(a: __m128h, b: __m128h, c: __m12 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fnmadd_round_sh( a: __m128h, k: __mmask8, @@ -6788,7 +6788,7 @@ pub fn _mm_mask_fnmadd_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fnmadd_round_sh( a: __m128h, b: __m128h, @@ -6825,7 +6825,7 @@ pub fn _mm_mask3_fnmadd_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fnmadd_round_sh( k: __mmask8, a: __m128h, @@ -6852,7 +6852,7 @@ pub fn _mm_maskz_fnmadd_round_sh( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } @@ -6866,7 +6866,7 @@ pub const fn _mm_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fnmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmsub_ph(a, b, c), a) } @@ -6880,7 +6880,7 @@ pub const fn _mm_mask_fnmsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmsub_ph(a, b, c), c) } @@ -6894,7 +6894,7 @@ pub const fn _mm_mask3_fnmsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fnmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fnmsub_ph(a, b, c), _mm_setzero_ph()) } @@ -6907,7 +6907,7 @@ pub const fn _mm_maskz_fnmsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } @@ -6921,7 +6921,7 @@ pub const fn _mm256_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_fnmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmsub_ph(a, b, c), a) } @@ -6935,7 +6935,7 @@ pub const fn _mm256_mask_fnmsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m2 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask3_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmsub_ph(a, b, c), c) } @@ -6949,7 +6949,7 @@ pub const fn _mm256_mask3_fnmsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mma #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_fnmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fnmsub_ph(a, b, c), _mm256_setzero_ph()) } @@ -6962,7 +6962,7 @@ pub const fn _mm256_maskz_fnmsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_fma(simd_neg(a), b, simd_neg(c)) } @@ -6976,7 +6976,7 @@ pub const fn _mm512_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_fnmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmsub_ph(a, b, c), a) } @@ -6990,7 +6990,7 @@ pub const fn _mm512_mask_fnmsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m5 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask3_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmsub_ph(a, b, c), c) } @@ -7004,7 +7004,7 @@ pub const fn _mm512_mask3_fnmsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mma #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_fnmsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fnmsub_ph(a, b, c), _mm512_setzero_ph()) } @@ -7026,7 +7026,7 @@ pub const fn _mm512_maskz_fnmsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fnmsub_round_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -7051,7 +7051,7 @@ pub fn _mm512_fnmsub_round_ph(a: __m512h, b: __m512h, c: __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fnmsub_round_ph( a: __m512h, k: __mmask32, @@ -7081,7 +7081,7 @@ pub fn _mm512_mask_fnmsub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fnmsub_round_ph( a: __m512h, b: __m512h, @@ -7111,7 +7111,7 @@ pub fn _mm512_mask3_fnmsub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fnmsub_round_ph( k: __mmask32, a: __m512h, @@ -7136,7 +7136,7 @@ pub fn _mm512_maskz_fnmsub_round_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -7157,7 +7157,7 @@ pub const fn _mm_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fnmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -7180,7 +7180,7 @@ pub const fn _mm_mask_fnmsub_sh(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { @@ -7203,7 +7203,7 @@ pub const fn _mm_mask3_fnmsub_sh(a: __m128h, b: __m128h, c: __m128h, k: __mmask8 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fnmsub_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -7235,7 +7235,7 @@ pub const fn _mm_maskz_fnmsub_sh(k: __mmask8, a: __m128h, b: __m128h, c: __m128h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fnmsub_round_sh(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -7265,7 +7265,7 @@ pub fn _mm_fnmsub_round_sh(a: __m128h, b: __m128h, c: __m12 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fnmsub_round_sh( a: __m128h, k: __mmask8, @@ -7302,7 +7302,7 @@ pub fn _mm_mask_fnmsub_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask3_fnmsub_round_sh( a: __m128h, b: __m128h, @@ -7339,7 +7339,7 @@ pub fn _mm_mask3_fnmsub_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfnmsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_fnmsub_round_sh( k: __mmask8, a: __m128h, @@ -7366,7 +7366,7 @@ pub fn _mm_maskz_fnmsub_round_sh( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { @@ -7384,7 +7384,7 @@ pub const fn _mm_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fmaddsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmaddsub_ph(a, b, c), a) } @@ -7398,7 +7398,7 @@ pub const fn _mm_mask_fmaddsub_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmaddsub_ph(a, b, c), c) } @@ -7412,7 +7412,7 @@ pub const fn _mm_mask3_fmaddsub_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmas #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fmaddsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmaddsub_ph(a, b, c), _mm_setzero_ph()) } @@ -7425,7 +7425,7 @@ pub const fn _mm_maskz_fmaddsub_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m12 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { @@ -7447,7 +7447,7 @@ pub const fn _mm256_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_fmaddsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_ph(a, b, c), a) } @@ -7461,7 +7461,7 @@ pub const fn _mm256_mask_fmaddsub_ph(a: __m256h, k: __mmask16, b: __m256h, c: __ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask3_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_ph(a, b, c), c) } @@ -7475,7 +7475,7 @@ pub const fn _mm256_mask3_fmaddsub_ph(a: __m256h, b: __m256h, c: __m256h, k: __m #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_fmaddsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmaddsub_ph(a, b, c), _mm256_setzero_ph()) } @@ -7488,7 +7488,7 @@ pub const fn _mm256_maskz_fmaddsub_ph(k: __mmask16, a: __m256h, b: __m256h, c: _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { @@ -7513,7 +7513,7 @@ pub const fn _mm512_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_fmaddsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_ph(a, b, c), a) } @@ -7527,7 +7527,7 @@ pub const fn _mm512_mask_fmaddsub_ph(a: __m512h, k: __mmask32, b: __m512h, c: __ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask3_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_ph(a, b, c), c) } @@ -7541,7 +7541,7 @@ pub const fn _mm512_mask3_fmaddsub_ph(a: __m512h, b: __m512h, c: __m512h, k: __m #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_fmaddsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmaddsub_ph(a, b, c), _mm512_setzero_ph()) } @@ -7563,7 +7563,7 @@ pub const fn _mm512_maskz_fmaddsub_ph(k: __mmask32, a: __m512h, b: __m512h, c: _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fmaddsub_round_ph( a: __m512h, b: __m512h, @@ -7592,7 +7592,7 @@ pub fn _mm512_fmaddsub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fmaddsub_round_ph( a: __m512h, k: __mmask32, @@ -7622,7 +7622,7 @@ pub fn _mm512_mask_fmaddsub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fmaddsub_round_ph( a: __m512h, b: __m512h, @@ -7652,7 +7652,7 @@ pub fn _mm512_mask3_fmaddsub_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmaddsub, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fmaddsub_round_ph( k: __mmask32, a: __m512h, @@ -7676,7 +7676,7 @@ pub fn _mm512_maskz_fmaddsub_round_ph( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { _mm_fmaddsub_ph(a, b, unsafe { simd_neg(c) }) @@ -7690,7 +7690,7 @@ pub const fn _mm_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_fmsubadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsubadd_ph(a, b, c), a) } @@ -7704,7 +7704,7 @@ pub const fn _mm_mask_fmsubadd_ph(a: __m128h, k: __mmask8, b: __m128h, c: __m128 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask3_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmask8) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsubadd_ph(a, b, c), c) } @@ -7718,7 +7718,7 @@ pub const fn _mm_mask3_fmsubadd_ph(a: __m128h, b: __m128h, c: __m128h, k: __mmas #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_maskz_fmsubadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_fmsubadd_ph(a, b, c), _mm_setzero_ph()) } @@ -7731,7 +7731,7 @@ pub const fn _mm_maskz_fmsubadd_ph(k: __mmask8, a: __m128h, b: __m128h, c: __m12 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { _mm256_fmaddsub_ph(a, b, unsafe { simd_neg(c) }) @@ -7745,7 +7745,7 @@ pub const fn _mm256_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_fmsubadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_ph(a, b, c), a) } @@ -7759,7 +7759,7 @@ pub const fn _mm256_mask_fmsubadd_ph(a: __m256h, k: __mmask16, b: __m256h, c: __ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask3_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __mmask16) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_ph(a, b, c), c) } @@ -7773,7 +7773,7 @@ pub const fn _mm256_mask3_fmsubadd_ph(a: __m256h, b: __m256h, c: __m256h, k: __m #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_maskz_fmsubadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_fmsubadd_ph(a, b, c), _mm256_setzero_ph()) } @@ -7786,7 +7786,7 @@ pub const fn _mm256_maskz_fmsubadd_ph(k: __mmask16, a: __m256h, b: __m256h, c: _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { _mm512_fmaddsub_ph(a, b, unsafe { simd_neg(c) }) @@ -7800,7 +7800,7 @@ pub const fn _mm512_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_fmsubadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_ph(a, b, c), a) } @@ -7814,7 +7814,7 @@ pub const fn _mm512_mask_fmsubadd_ph(a: __m512h, k: __mmask32, b: __m512h, c: __ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask3_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __mmask32) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_ph(a, b, c), c) } @@ -7828,7 +7828,7 @@ pub const fn _mm512_mask3_fmsubadd_ph(a: __m512h, b: __m512h, c: __m512h, k: __m #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_maskz_fmsubadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_fmsubadd_ph(a, b, c), _mm512_setzero_ph()) } @@ -7850,7 +7850,7 @@ pub const fn _mm512_maskz_fmsubadd_ph(k: __mmask32, a: __m512h, b: __m512h, c: _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fmsubadd_round_ph( a: __m512h, b: __m512h, @@ -7879,7 +7879,7 @@ pub fn _mm512_fmsubadd_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fmsubadd_round_ph( a: __m512h, k: __mmask32, @@ -7909,7 +7909,7 @@ pub fn _mm512_mask_fmsubadd_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask3_fmsubadd_round_ph( a: __m512h, b: __m512h, @@ -7939,7 +7939,7 @@ pub fn _mm512_mask3_fmsubadd_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfmsubadd, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_fmsubadd_round_ph( k: __mmask32, a: __m512h, @@ -7963,7 +7963,7 @@ pub fn _mm512_maskz_fmsubadd_round_ph( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrcpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_rcp_ph(a: __m128h) -> __m128h { _mm_mask_rcp_ph(_mm_undefined_ph(), 0xff, a) } @@ -7976,7 +7976,7 @@ pub fn _mm_rcp_ph(a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrcpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_rcp_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { unsafe { vrcpph_128(a, src, k) } } @@ -7989,7 +7989,7 @@ pub fn _mm_mask_rcp_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrcpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_rcp_ph(k: __mmask8, a: __m128h) -> __m128h { _mm_mask_rcp_ph(_mm_setzero_ph(), k, a) } @@ -8001,7 +8001,7 @@ pub fn _mm_maskz_rcp_ph(k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrcpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_rcp_ph(a: __m256h) -> __m256h { _mm256_mask_rcp_ph(_mm256_undefined_ph(), 0xffff, a) } @@ -8014,7 +8014,7 @@ pub fn _mm256_rcp_ph(a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrcpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_rcp_ph(src: __m256h, k: __mmask16, a: __m256h) -> __m256h { unsafe { vrcpph_256(a, src, k) } } @@ -8027,7 +8027,7 @@ pub fn _mm256_mask_rcp_ph(src: __m256h, k: __mmask16, a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrcpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_rcp_ph(k: __mmask16, a: __m256h) -> __m256h { _mm256_mask_rcp_ph(_mm256_setzero_ph(), k, a) } @@ -8039,7 +8039,7 @@ pub fn _mm256_maskz_rcp_ph(k: __mmask16, a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrcpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_rcp_ph(a: __m512h) -> __m512h { _mm512_mask_rcp_ph(_mm512_undefined_ph(), 0xffffffff, a) } @@ -8052,7 +8052,7 @@ pub fn _mm512_rcp_ph(a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrcpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_rcp_ph(src: __m512h, k: __mmask32, a: __m512h) -> __m512h { unsafe { vrcpph_512(a, src, k) } } @@ -8065,7 +8065,7 @@ pub fn _mm512_mask_rcp_ph(src: __m512h, k: __mmask32, a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrcpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_rcp_ph(k: __mmask32, a: __m512h) -> __m512h { _mm512_mask_rcp_ph(_mm512_setzero_ph(), k, a) } @@ -8079,7 +8079,7 @@ pub fn _mm512_maskz_rcp_ph(k: __mmask32, a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrcpsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_rcp_sh(a: __m128h, b: __m128h) -> __m128h { _mm_mask_rcp_sh(f16x8::ZERO.as_m128h(), 0xff, a, b) } @@ -8093,7 +8093,7 @@ pub fn _mm_rcp_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrcpsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_rcp_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { vrcpsh(a, b, src, k) } } @@ -8107,7 +8107,7 @@ pub fn _mm_mask_rcp_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrcpsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_rcp_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_rcp_sh(f16x8::ZERO.as_m128h(), k, a, b) } @@ -8120,7 +8120,7 @@ pub fn _mm_maskz_rcp_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_rsqrt_ph(a: __m128h) -> __m128h { _mm_mask_rsqrt_ph(_mm_undefined_ph(), 0xff, a) } @@ -8134,7 +8134,7 @@ pub fn _mm_rsqrt_ph(a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_rsqrt_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { unsafe { vrsqrtph_128(a, src, k) } } @@ -8148,7 +8148,7 @@ pub fn _mm_mask_rsqrt_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_rsqrt_ph(k: __mmask8, a: __m128h) -> __m128h { _mm_mask_rsqrt_ph(_mm_setzero_ph(), k, a) } @@ -8161,7 +8161,7 @@ pub fn _mm_maskz_rsqrt_ph(k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_rsqrt_ph(a: __m256h) -> __m256h { _mm256_mask_rsqrt_ph(_mm256_undefined_ph(), 0xffff, a) } @@ -8175,7 +8175,7 @@ pub fn _mm256_rsqrt_ph(a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_rsqrt_ph(src: __m256h, k: __mmask16, a: __m256h) -> __m256h { unsafe { vrsqrtph_256(a, src, k) } } @@ -8189,7 +8189,7 @@ pub fn _mm256_mask_rsqrt_ph(src: __m256h, k: __mmask16, a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_rsqrt_ph(k: __mmask16, a: __m256h) -> __m256h { _mm256_mask_rsqrt_ph(_mm256_setzero_ph(), k, a) } @@ -8202,7 +8202,7 @@ pub fn _mm256_maskz_rsqrt_ph(k: __mmask16, a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_rsqrt_ph(a: __m512h) -> __m512h { _mm512_mask_rsqrt_ph(_mm512_undefined_ph(), 0xffffffff, a) } @@ -8216,7 +8216,7 @@ pub fn _mm512_rsqrt_ph(a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_rsqrt_ph(src: __m512h, k: __mmask32, a: __m512h) -> __m512h { unsafe { vrsqrtph_512(a, src, k) } } @@ -8230,7 +8230,7 @@ pub fn _mm512_mask_rsqrt_ph(src: __m512h, k: __mmask32, a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_rsqrt_ph(k: __mmask32, a: __m512h) -> __m512h { _mm512_mask_rsqrt_ph(_mm512_setzero_ph(), k, a) } @@ -8244,7 +8244,7 @@ pub fn _mm512_maskz_rsqrt_ph(k: __mmask32, a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrsqrtsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_rsqrt_sh(a: __m128h, b: __m128h) -> __m128h { _mm_mask_rsqrt_sh(f16x8::ZERO.as_m128h(), 0xff, a, b) } @@ -8258,7 +8258,7 @@ pub fn _mm_rsqrt_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrsqrtsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_rsqrt_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { vrsqrtsh(a, b, src, k) } } @@ -8272,7 +8272,7 @@ pub fn _mm_mask_rsqrt_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrsqrtsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_rsqrt_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_rsqrt_sh(f16x8::ZERO.as_m128h(), k, a, b) } @@ -8284,7 +8284,7 @@ pub fn _mm_maskz_rsqrt_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_sqrt_ph(a: __m128h) -> __m128h { unsafe { simd_fsqrt(a) } } @@ -8296,7 +8296,7 @@ pub fn _mm_sqrt_ph(a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_sqrt_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_sqrt_ph(a), src) } } @@ -8308,7 +8308,7 @@ pub fn _mm_mask_sqrt_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_sqrt_ph(k: __mmask8, a: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_sqrt_ph(a), _mm_setzero_ph()) } } @@ -8320,7 +8320,7 @@ pub fn _mm_maskz_sqrt_ph(k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_sqrt_ph(a: __m256h) -> __m256h { unsafe { simd_fsqrt(a) } } @@ -8332,7 +8332,7 @@ pub fn _mm256_sqrt_ph(a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_sqrt_ph(src: __m256h, k: __mmask16, a: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_sqrt_ph(a), src) } } @@ -8344,7 +8344,7 @@ pub fn _mm256_mask_sqrt_ph(src: __m256h, k: __mmask16, a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_sqrt_ph(k: __mmask16, a: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_sqrt_ph(a), _mm256_setzero_ph()) } } @@ -8356,7 +8356,7 @@ pub fn _mm256_maskz_sqrt_ph(k: __mmask16, a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_sqrt_ph(a: __m512h) -> __m512h { unsafe { simd_fsqrt(a) } } @@ -8368,7 +8368,7 @@ pub fn _mm512_sqrt_ph(a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_sqrt_ph(src: __m512h, k: __mmask32, a: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_sqrt_ph(a), src) } } @@ -8380,7 +8380,7 @@ pub fn _mm512_mask_sqrt_ph(src: __m512h, k: __mmask32, a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_sqrt_ph(k: __mmask32, a: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_sqrt_ph(a), _mm512_setzero_ph()) } } @@ -8400,7 +8400,7 @@ pub fn _mm512_maskz_sqrt_ph(k: __mmask32, a: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtph, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_sqrt_round_ph(a: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -8423,7 +8423,7 @@ pub fn _mm512_sqrt_round_ph(a: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_sqrt_round_ph( src: __m512h, k: __mmask32, @@ -8450,7 +8450,7 @@ pub fn _mm512_mask_sqrt_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_sqrt_round_ph(k: __mmask32, a: __m512h) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -8466,7 +8466,7 @@ pub fn _mm512_maskz_sqrt_round_ph(k: __mmask32, a: __m512h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_sqrt_sh(a: __m128h, b: __m128h) -> __m128h { _mm_mask_sqrt_sh(f16x8::ZERO.as_m128h(), 0xff, a, b) } @@ -8479,7 +8479,7 @@ pub fn _mm_sqrt_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_sqrt_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_sqrt_round_sh::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -8492,7 +8492,7 @@ pub fn _mm_mask_sqrt_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_sqrt_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_sqrt_sh(f16x8::ZERO.as_m128h(), k, a, b) } @@ -8513,7 +8513,7 @@ pub fn _mm_maskz_sqrt_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_sqrt_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_sqrt_round_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -8535,7 +8535,7 @@ pub fn _mm_sqrt_round_sh(a: __m128h, b: __m128h) -> __m128h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_sqrt_round_sh( src: __m128h, k: __mmask8, @@ -8564,7 +8564,7 @@ pub fn _mm_mask_sqrt_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vsqrtsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_sqrt_round_sh( k: __mmask8, a: __m128h, @@ -8582,7 +8582,7 @@ pub fn _mm_maskz_sqrt_round_sh( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_max_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { vmaxph_128(a, b) } } @@ -8596,7 +8596,7 @@ pub fn _mm_max_ph(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_max_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_max_ph(a, b), src) } } @@ -8610,7 +8610,7 @@ pub fn _mm_mask_max_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_max_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_max_ph(a, b), _mm_setzero_ph()) } } @@ -8623,7 +8623,7 @@ pub fn _mm_maskz_max_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_max_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { vmaxph_256(a, b) } } @@ -8637,7 +8637,7 @@ pub fn _mm256_max_ph(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_max_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_max_ph(a, b), src) } } @@ -8651,7 +8651,7 @@ pub fn _mm256_mask_max_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_max_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_max_ph(a, b), _mm256_setzero_ph()) } } @@ -8664,7 +8664,7 @@ pub fn _mm256_maskz_max_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmaxph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_max_ph(a: __m512h, b: __m512h) -> __m512h { _mm512_max_round_ph::<_MM_FROUND_CUR_DIRECTION>(a, b) } @@ -8678,7 +8678,7 @@ pub fn _mm512_max_ph(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmaxph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_max_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_max_ph(a, b), src) } } @@ -8692,7 +8692,7 @@ pub fn _mm512_mask_max_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmaxph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_max_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_max_ph(a, b), _mm512_setzero_ph()) } } @@ -8707,7 +8707,7 @@ pub fn _mm512_maskz_max_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmaxph, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_max_round_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { static_assert_sae!(SAE); @@ -8725,7 +8725,7 @@ pub fn _mm512_max_round_ph(a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmaxph, SAE = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_max_round_ph( src: __m512h, k: __mmask32, @@ -8748,7 +8748,7 @@ pub fn _mm512_mask_max_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vmaxph, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_max_round_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { static_assert_sae!(SAE); @@ -8765,7 +8765,7 @@ pub fn _mm512_maskz_max_round_ph(k: __mmask32, a: __m512h, b: __ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_max_sh(a: __m128h, b: __m128h) -> __m128h { _mm_mask_max_sh(_mm_undefined_ph(), 0xff, a, b) } @@ -8779,7 +8779,7 @@ pub fn _mm_max_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_max_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_max_round_sh::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -8793,7 +8793,7 @@ pub fn _mm_mask_max_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_max_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_max_sh(f16x8::ZERO.as_m128h(), k, a, b) } @@ -8808,7 +8808,7 @@ pub fn _mm_maskz_max_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxsh, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_max_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_sae!(SAE); _mm_mask_max_round_sh::(_mm_undefined_ph(), 0xff, a, b) @@ -8825,7 +8825,7 @@ pub fn _mm_max_round_sh(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxsh, SAE = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_max_round_sh( src: __m128h, k: __mmask8, @@ -8849,7 +8849,7 @@ pub fn _mm_mask_max_round_sh( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vmaxsh, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_max_round_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { static_assert_sae!(SAE); _mm_mask_max_round_sh::(f16x8::ZERO.as_m128h(), k, a, b) @@ -8863,7 +8863,7 @@ pub fn _mm_maskz_max_round_sh(k: __mmask8, a: __m128h, b: __m128 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_min_ph(a: __m128h, b: __m128h) -> __m128h { unsafe { vminph_128(a, b) } } @@ -8877,7 +8877,7 @@ pub fn _mm_min_ph(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_min_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_min_ph(a, b), src) } } @@ -8891,7 +8891,7 @@ pub fn _mm_mask_min_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_min_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, _mm_min_ph(a, b), _mm_setzero_ph()) } } @@ -8904,7 +8904,7 @@ pub fn _mm_maskz_min_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_min_ph(a: __m256h, b: __m256h) -> __m256h { unsafe { vminph_256(a, b) } } @@ -8918,7 +8918,7 @@ pub fn _mm256_min_ph(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_min_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_min_ph(a, b), src) } } @@ -8932,7 +8932,7 @@ pub fn _mm256_mask_min_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_min_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_min_ph(a, b), _mm256_setzero_ph()) } } @@ -8945,7 +8945,7 @@ pub fn _mm256_maskz_min_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vminph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_min_ph(a: __m512h, b: __m512h) -> __m512h { _mm512_min_round_ph::<_MM_FROUND_CUR_DIRECTION>(a, b) } @@ -8959,7 +8959,7 @@ pub fn _mm512_min_ph(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vminph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_min_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_min_ph(a, b), src) } } @@ -8973,7 +8973,7 @@ pub fn _mm512_mask_min_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vminph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_min_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_min_ph(a, b), _mm512_setzero_ph()) } } @@ -8987,7 +8987,7 @@ pub fn _mm512_maskz_min_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vminph, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_min_round_ph(a: __m512h, b: __m512h) -> __m512h { unsafe { static_assert_sae!(SAE); @@ -9005,7 +9005,7 @@ pub fn _mm512_min_round_ph(a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vminph, SAE = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_min_round_ph( src: __m512h, k: __mmask32, @@ -9028,7 +9028,7 @@ pub fn _mm512_mask_min_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vminph, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_min_round_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { static_assert_sae!(SAE); @@ -9045,7 +9045,7 @@ pub fn _mm512_maskz_min_round_ph(k: __mmask32, a: __m512h, b: __ #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_min_sh(a: __m128h, b: __m128h) -> __m128h { _mm_mask_min_sh(_mm_undefined_ph(), 0xff, a, b) } @@ -9059,7 +9059,7 @@ pub fn _mm_min_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_min_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_min_round_sh::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -9073,7 +9073,7 @@ pub fn _mm_mask_min_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_min_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_min_sh(f16x8::ZERO.as_m128h(), k, a, b) } @@ -9088,7 +9088,7 @@ pub fn _mm_maskz_min_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminsh, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_min_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_sae!(SAE); _mm_mask_min_round_sh::(_mm_undefined_ph(), 0xff, a, b) @@ -9105,7 +9105,7 @@ pub fn _mm_min_round_sh(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminsh, SAE = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_min_round_sh( src: __m128h, k: __mmask8, @@ -9129,7 +9129,7 @@ pub fn _mm_mask_min_round_sh( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vminsh, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_min_round_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { static_assert_sae!(SAE); _mm_mask_min_round_sh::(f16x8::ZERO.as_m128h(), k, a, b) @@ -9143,7 +9143,7 @@ pub fn _mm_maskz_min_round_sh(k: __mmask8, a: __m128h, b: __m128 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vgetexpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_getexp_ph(a: __m128h) -> __m128h { _mm_mask_getexp_ph(_mm_undefined_ph(), 0xff, a) } @@ -9157,7 +9157,7 @@ pub fn _mm_getexp_ph(a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vgetexpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_getexp_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { unsafe { vgetexpph_128(a, src, k) } } @@ -9171,7 +9171,7 @@ pub fn _mm_mask_getexp_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vgetexpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_getexp_ph(k: __mmask8, a: __m128h) -> __m128h { _mm_mask_getexp_ph(_mm_setzero_ph(), k, a) } @@ -9184,7 +9184,7 @@ pub fn _mm_maskz_getexp_ph(k: __mmask8, a: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vgetexpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_getexp_ph(a: __m256h) -> __m256h { _mm256_mask_getexp_ph(_mm256_undefined_ph(), 0xffff, a) } @@ -9198,7 +9198,7 @@ pub fn _mm256_getexp_ph(a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vgetexpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_getexp_ph(src: __m256h, k: __mmask16, a: __m256h) -> __m256h { unsafe { vgetexpph_256(a, src, k) } } @@ -9212,7 +9212,7 @@ pub fn _mm256_mask_getexp_ph(src: __m256h, k: __mmask16, a: __m256h) -> __m256h #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vgetexpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_getexp_ph(k: __mmask16, a: __m256h) -> __m256h { _mm256_mask_getexp_ph(_mm256_setzero_ph(), k, a) } @@ -9225,7 +9225,7 @@ pub fn _mm256_maskz_getexp_ph(k: __mmask16, a: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_getexp_ph(a: __m512h) -> __m512h { _mm512_mask_getexp_ph(_mm512_undefined_ph(), 0xffffffff, a) } @@ -9239,7 +9239,7 @@ pub fn _mm512_getexp_ph(a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_getexp_ph(src: __m512h, k: __mmask32, a: __m512h) -> __m512h { _mm512_mask_getexp_round_ph::<_MM_FROUND_CUR_DIRECTION>(src, k, a) } @@ -9253,7 +9253,7 @@ pub fn _mm512_mask_getexp_ph(src: __m512h, k: __mmask32, a: __m512h) -> __m512h #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_getexp_ph(k: __mmask32, a: __m512h) -> __m512h { _mm512_mask_getexp_ph(_mm512_setzero_ph(), k, a) } @@ -9268,7 +9268,7 @@ pub fn _mm512_maskz_getexp_ph(k: __mmask32, a: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpph, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_getexp_round_ph(a: __m512h) -> __m512h { static_assert_sae!(SAE); _mm512_mask_getexp_round_ph::(_mm512_undefined_ph(), 0xffffffff, a) @@ -9284,7 +9284,7 @@ pub fn _mm512_getexp_round_ph(a: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpph, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_getexp_round_ph( src: __m512h, k: __mmask32, @@ -9306,7 +9306,7 @@ pub fn _mm512_mask_getexp_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpph, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_getexp_round_ph(k: __mmask32, a: __m512h) -> __m512h { static_assert_sae!(SAE); _mm512_mask_getexp_round_ph::(_mm512_setzero_ph(), k, a) @@ -9321,7 +9321,7 @@ pub fn _mm512_maskz_getexp_round_ph(k: __mmask32, a: __m512h) -> #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_getexp_sh(a: __m128h, b: __m128h) -> __m128h { _mm_mask_getexp_sh(f16x8::ZERO.as_m128h(), 0xff, a, b) } @@ -9336,7 +9336,7 @@ pub fn _mm_getexp_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_getexp_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_getexp_round_sh::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -9351,7 +9351,7 @@ pub fn _mm_mask_getexp_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_getexp_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_getexp_sh(f16x8::ZERO.as_m128h(), k, a, b) } @@ -9367,7 +9367,7 @@ pub fn _mm_maskz_getexp_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpsh, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_getexp_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_sae!(SAE); _mm_mask_getexp_round_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -9384,7 +9384,7 @@ pub fn _mm_getexp_round_sh(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpsh, SAE = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_getexp_round_sh( src: __m128h, k: __mmask8, @@ -9408,7 +9408,7 @@ pub fn _mm_mask_getexp_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vgetexpsh, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_getexp_round_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { static_assert_sae!(SAE); _mm_mask_getexp_round_sh::(f16x8::ZERO.as_m128h(), k, a, b) @@ -9436,7 +9436,7 @@ pub fn _mm_maskz_getexp_round_sh(k: __mmask8, a: __m128h, b: __m #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vgetmantph, NORM = 0, SIGN = 0))] #[rustc_legacy_const_generics(1, 2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_getmant_ph( a: __m128h, ) -> __m128h { @@ -9468,7 +9468,7 @@ pub fn _mm_getmant_ph( a: __m256h, ) -> __m256h { @@ -9574,7 +9574,7 @@ pub fn _mm256_getmant_ph( a: __m512h, ) -> __m512h { @@ -9680,7 +9680,7 @@ pub fn _mm512_getmant_ph( a: __m128h, b: __m128h, @@ -9911,7 +9911,7 @@ pub fn _mm_getmant_sh(a: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); _mm_mask_roundscale_ph::(_mm_undefined_ph(), 0xff, a) @@ -10131,7 +10131,7 @@ pub fn _mm_roundscale_ph(a: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_roundscale_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -10156,7 +10156,7 @@ pub fn _mm_mask_roundscale_ph(src: __m128h, k: __mmask8, a: __m #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_roundscale_ph(k: __mmask8, a: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); _mm_mask_roundscale_ph::(_mm_setzero_ph(), k, a) @@ -10178,7 +10178,7 @@ pub fn _mm_maskz_roundscale_ph(k: __mmask8, a: __m128h) -> __m1 #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_roundscale_ph(a: __m256h) -> __m256h { static_assert_uimm_bits!(IMM8, 8); _mm256_mask_roundscale_ph::(_mm256_undefined_ph(), 0xffff, a) @@ -10201,7 +10201,7 @@ pub fn _mm256_roundscale_ph(a: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_roundscale_ph( src: __m256h, k: __mmask16, @@ -10230,7 +10230,7 @@ pub fn _mm256_mask_roundscale_ph( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_roundscale_ph(k: __mmask16, a: __m256h) -> __m256h { static_assert_uimm_bits!(IMM8, 8); _mm256_mask_roundscale_ph::(_mm256_setzero_ph(), k, a) @@ -10252,7 +10252,7 @@ pub fn _mm256_maskz_roundscale_ph(k: __mmask16, a: __m256h) -> #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_roundscale_ph(a: __m512h) -> __m512h { static_assert_uimm_bits!(IMM8, 8); _mm512_mask_roundscale_ph::(_mm512_undefined_ph(), 0xffffffff, a) @@ -10275,7 +10275,7 @@ pub fn _mm512_roundscale_ph(a: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_roundscale_ph( src: __m512h, k: __mmask32, @@ -10302,7 +10302,7 @@ pub fn _mm512_mask_roundscale_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_roundscale_ph(k: __mmask32, a: __m512h) -> __m512h { static_assert_uimm_bits!(IMM8, 8); _mm512_mask_roundscale_ph::(_mm512_setzero_ph(), k, a) @@ -10325,7 +10325,7 @@ pub fn _mm512_maskz_roundscale_ph(k: __mmask32, a: __m512h) -> #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(1, 2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_roundscale_round_ph(a: __m512h) -> __m512h { static_assert_uimm_bits!(IMM8, 8); static_assert_sae!(SAE); @@ -10350,7 +10350,7 @@ pub fn _mm512_roundscale_round_ph(a: __m512h) - #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(3, 4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_roundscale_round_ph( src: __m512h, k: __mmask32, @@ -10380,7 +10380,7 @@ pub fn _mm512_mask_roundscale_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscaleph, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(2, 3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_roundscale_round_ph( k: __mmask32, a: __m512h, @@ -10407,7 +10407,7 @@ pub fn _mm512_maskz_roundscale_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscalesh, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_roundscale_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); _mm_mask_roundscale_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -10430,7 +10430,7 @@ pub fn _mm_roundscale_sh(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscalesh, IMM8 = 0))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_roundscale_sh( src: __m128h, k: __mmask8, @@ -10458,7 +10458,7 @@ pub fn _mm_mask_roundscale_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscalesh, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_roundscale_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); _mm_mask_roundscale_sh::(f16x8::ZERO.as_m128h(), k, a, b) @@ -10483,7 +10483,7 @@ pub fn _mm_maskz_roundscale_sh(k: __mmask8, a: __m128h, b: __m1 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscalesh, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(2, 3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_roundscale_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); static_assert_sae!(SAE); @@ -10509,7 +10509,7 @@ pub fn _mm_roundscale_round_sh(a: __m128h, b: _ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscalesh, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(4, 5)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_roundscale_round_sh( src: __m128h, k: __mmask8, @@ -10542,7 +10542,7 @@ pub fn _mm_mask_roundscale_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vrndscalesh, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(3, 4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_roundscale_round_sh( k: __mmask8, a: __m128h, @@ -10560,7 +10560,7 @@ pub fn _mm_maskz_roundscale_round_sh( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vscalefph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_scalef_ph(a: __m128h, b: __m128h) -> __m128h { _mm_mask_scalef_ph(_mm_undefined_ph(), 0xff, a, b) } @@ -10572,7 +10572,7 @@ pub fn _mm_scalef_ph(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vscalefph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_scalef_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { vscalefph_128(a, b, src, k) } } @@ -10584,7 +10584,7 @@ pub fn _mm_mask_scalef_ph(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vscalefph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_scalef_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_scalef_ph(_mm_setzero_ph(), k, a, b) } @@ -10596,7 +10596,7 @@ pub fn _mm_maskz_scalef_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vscalefph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_scalef_ph(a: __m256h, b: __m256h) -> __m256h { _mm256_mask_scalef_ph(_mm256_undefined_ph(), 0xffff, a, b) } @@ -10608,7 +10608,7 @@ pub fn _mm256_scalef_ph(a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vscalefph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_scalef_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { vscalefph_256(a, b, src, k) } } @@ -10620,7 +10620,7 @@ pub fn _mm256_mask_scalef_ph(src: __m256h, k: __mmask16, a: __m256h, b: __m256h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vscalefph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_scalef_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { _mm256_mask_scalef_ph(_mm256_setzero_ph(), k, a, b) } @@ -10632,7 +10632,7 @@ pub fn _mm256_maskz_scalef_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_scalef_ph(a: __m512h, b: __m512h) -> __m512h { _mm512_mask_scalef_ph(_mm512_undefined_ph(), 0xffffffff, a, b) } @@ -10644,7 +10644,7 @@ pub fn _mm512_scalef_ph(a: __m512h, b: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_scalef_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) -> __m512h { _mm512_mask_scalef_round_ph::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -10656,7 +10656,7 @@ pub fn _mm512_mask_scalef_ph(src: __m512h, k: __mmask32, a: __m512h, b: __m512h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_scalef_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { _mm512_mask_scalef_ph(_mm512_setzero_ph(), k, a, b) } @@ -10677,7 +10677,7 @@ pub fn _mm512_maskz_scalef_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_scalef_round_ph(a: __m512h, b: __m512h) -> __m512h { static_assert_rounding!(ROUNDING); _mm512_mask_scalef_round_ph::(_mm512_undefined_ph(), 0xffffffff, a, b) @@ -10699,7 +10699,7 @@ pub fn _mm512_scalef_round_ph(a: __m512h, b: __m512h) -> __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefph, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_scalef_round_ph( src: __m512h, k: __mmask32, @@ -10728,7 +10728,7 @@ pub fn _mm512_mask_scalef_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_scalef_round_ph( k: __mmask32, a: __m512h, @@ -10746,7 +10746,7 @@ pub fn _mm512_maskz_scalef_round_ph( #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_scalef_sh(a: __m128h, b: __m128h) -> __m128h { _mm_mask_scalef_sh(f16x8::ZERO.as_m128h(), 0xff, a, b) } @@ -10759,7 +10759,7 @@ pub fn _mm_scalef_sh(a: __m128h, b: __m128h) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_scalef_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_scalef_round_sh::<_MM_FROUND_CUR_DIRECTION>(src, k, a, b) } @@ -10772,7 +10772,7 @@ pub fn _mm_mask_scalef_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128h) -> #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefsh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_scalef_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { _mm_mask_scalef_sh(f16x8::ZERO.as_m128h(), k, a, b) } @@ -10794,7 +10794,7 @@ pub fn _mm_maskz_scalef_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefsh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_scalef_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_scalef_round_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -10817,7 +10817,7 @@ pub fn _mm_scalef_round_sh(a: __m128h, b: __m128h) -> __m12 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefsh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_scalef_round_sh( src: __m128h, k: __mmask8, @@ -10847,7 +10847,7 @@ pub fn _mm_mask_scalef_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vscalefsh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_scalef_round_sh( k: __mmask8, a: __m128h, @@ -10873,7 +10873,7 @@ pub fn _mm_maskz_scalef_round_sh( #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_reduce_ph(a: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); _mm_mask_reduce_ph::(_mm_undefined_ph(), 0xff, a) @@ -10896,7 +10896,7 @@ pub fn _mm_reduce_ph(a: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_reduce_ph(src: __m128h, k: __mmask8, a: __m128h) -> __m128h { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -10921,7 +10921,7 @@ pub fn _mm_mask_reduce_ph(src: __m128h, k: __mmask8, a: __m128h #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_reduce_ph(k: __mmask8, a: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); _mm_mask_reduce_ph::(_mm_setzero_ph(), k, a) @@ -10943,7 +10943,7 @@ pub fn _mm_maskz_reduce_ph(k: __mmask8, a: __m128h) -> __m128h #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_reduce_ph(a: __m256h) -> __m256h { static_assert_uimm_bits!(IMM8, 8); _mm256_mask_reduce_ph::(_mm256_undefined_ph(), 0xffff, a) @@ -10966,7 +10966,7 @@ pub fn _mm256_reduce_ph(a: __m256h) -> __m256h { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_reduce_ph(src: __m256h, k: __mmask16, a: __m256h) -> __m256h { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -10991,7 +10991,7 @@ pub fn _mm256_mask_reduce_ph(src: __m256h, k: __mmask16, a: __m #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_reduce_ph(k: __mmask16, a: __m256h) -> __m256h { static_assert_uimm_bits!(IMM8, 8); _mm256_mask_reduce_ph::(_mm256_setzero_ph(), k, a) @@ -11013,7 +11013,7 @@ pub fn _mm256_maskz_reduce_ph(k: __mmask16, a: __m256h) -> __m2 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_reduce_ph(a: __m512h) -> __m512h { static_assert_uimm_bits!(IMM8, 8); _mm512_mask_reduce_ph::(_mm512_undefined_ph(), 0xffffffff, a) @@ -11036,7 +11036,7 @@ pub fn _mm512_reduce_ph(a: __m512h) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_reduce_ph(src: __m512h, k: __mmask32, a: __m512h) -> __m512h { static_assert_uimm_bits!(IMM8, 8); _mm512_mask_reduce_round_ph::(src, k, a) @@ -11059,7 +11059,7 @@ pub fn _mm512_mask_reduce_ph(src: __m512h, k: __mmask32, a: __m #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_reduce_ph(k: __mmask32, a: __m512h) -> __m512h { static_assert_uimm_bits!(IMM8, 8); _mm512_mask_reduce_ph::(_mm512_setzero_ph(), k, a) @@ -11083,7 +11083,7 @@ pub fn _mm512_maskz_reduce_ph(k: __mmask32, a: __m512h) -> __m5 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(1, 2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_reduce_round_ph(a: __m512h) -> __m512h { static_assert_uimm_bits!(IMM8, 8); static_assert_sae!(SAE); @@ -11109,7 +11109,7 @@ pub fn _mm512_reduce_round_ph(a: __m512h) -> __ #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(3, 4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_reduce_round_ph( src: __m512h, k: __mmask32, @@ -11141,7 +11141,7 @@ pub fn _mm512_mask_reduce_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreduceph, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(2, 3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_reduce_round_ph( k: __mmask32, a: __m512h, @@ -11168,7 +11168,7 @@ pub fn _mm512_maskz_reduce_round_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreducesh, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_reduce_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); _mm_mask_reduce_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -11192,7 +11192,7 @@ pub fn _mm_reduce_sh(a: __m128h, b: __m128h) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreducesh, IMM8 = 0))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_reduce_sh( src: __m128h, k: __mmask8, @@ -11221,7 +11221,7 @@ pub fn _mm_mask_reduce_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreducesh, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_reduce_sh(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); _mm_mask_reduce_sh::(f16x8::ZERO.as_m128h(), k, a, b) @@ -11246,7 +11246,7 @@ pub fn _mm_maskz_reduce_sh(k: __mmask8, a: __m128h, b: __m128h) #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreducesh, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(2, 3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_reduce_round_sh(a: __m128h, b: __m128h) -> __m128h { static_assert_uimm_bits!(IMM8, 8); static_assert_sae!(SAE); @@ -11273,7 +11273,7 @@ pub fn _mm_reduce_round_sh(a: __m128h, b: __m12 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreducesh, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(4, 5)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_reduce_round_sh( src: __m128h, k: __mmask8, @@ -11307,7 +11307,7 @@ pub fn _mm_mask_reduce_round_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vreducesh, IMM8 = 0, SAE = 8))] #[rustc_legacy_const_generics(3, 4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_reduce_round_sh( k: __mmask8, a: __m128h, @@ -11582,7 +11582,7 @@ macro_rules! fpclass_asm { // FIXME: use LLVM intrinsics #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfpclassph, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fpclass_ph_mask(a: __m128h) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -11609,7 +11609,7 @@ pub fn _mm_fpclass_ph_mask(a: __m128h) -> __mmask8 { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfpclassph, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fpclass_ph_mask(k1: __mmask8, a: __m128h) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -11635,7 +11635,7 @@ pub fn _mm_mask_fpclass_ph_mask(k1: __mmask8, a: __m128h) -> __ #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfpclassph, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_fpclass_ph_mask(a: __m256h) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -11662,7 +11662,7 @@ pub fn _mm256_fpclass_ph_mask(a: __m256h) -> __mmask16 { #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vfpclassph, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_fpclass_ph_mask(k1: __mmask16, a: __m256h) -> __mmask16 { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -11688,7 +11688,7 @@ pub fn _mm256_mask_fpclass_ph_mask(k1: __mmask16, a: __m256h) - #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfpclassph, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_fpclass_ph_mask(a: __m512h) -> __mmask32 { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -11715,7 +11715,7 @@ pub fn _mm512_fpclass_ph_mask(a: __m512h) -> __mmask32 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfpclassph, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_fpclass_ph_mask(k1: __mmask32, a: __m512h) -> __mmask32 { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -11741,7 +11741,7 @@ pub fn _mm512_mask_fpclass_ph_mask(k1: __mmask32, a: __m512h) - #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfpclasssh, IMM8 = 0))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_fpclass_sh_mask(a: __m128h) -> __mmask8 { _mm_mask_fpclass_sh_mask::(0xff, a) } @@ -11765,7 +11765,7 @@ pub fn _mm_fpclass_sh_mask(a: __m128h) -> __mmask8 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vfpclasssh, IMM8 = 0))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_fpclass_sh_mask(k1: __mmask8, a: __m128h) -> __mmask8 { unsafe { static_assert_uimm_bits!(IMM8, 8); @@ -11779,7 +11779,7 @@ pub fn _mm_mask_fpclass_sh_mask(k1: __mmask8, a: __m128h) -> __ /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mask_blend_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_mask_blend_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { unsafe { simd_select_bitmask(k, b, a) } @@ -11791,7 +11791,7 @@ pub const fn _mm_mask_blend_ph(k: __mmask8, a: __m128h, b: __m128h) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_mask_blend_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm256_mask_blend_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m256h { unsafe { simd_select_bitmask(k, b, a) } @@ -11803,7 +11803,7 @@ pub const fn _mm256_mask_blend_ph(k: __mmask16, a: __m256h, b: __m256h) -> __m25 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_mask_blend_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm512_mask_blend_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m512h { unsafe { simd_select_bitmask(k, b, a) } @@ -11815,7 +11815,7 @@ pub const fn _mm512_mask_blend_ph(k: __mmask32, a: __m512h, b: __m512h) -> __m51 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_permutex2var_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_permutex2var_ph(a: __m128h, idx: __m128i, b: __m128h) -> __m128h { _mm_castsi128_ph(_mm_permutex2var_epi16( _mm_castph_si128(a), @@ -11830,7 +11830,7 @@ pub fn _mm_permutex2var_ph(a: __m128h, idx: __m128i, b: __m128h) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_permutex2var_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_permutex2var_ph(a: __m256h, idx: __m256i, b: __m256h) -> __m256h { _mm256_castsi256_ph(_mm256_permutex2var_epi16( _mm256_castph_si256(a), @@ -11845,7 +11845,7 @@ pub fn _mm256_permutex2var_ph(a: __m256h, idx: __m256i, b: __m256h) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_permutex2var_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_permutex2var_ph(a: __m512h, idx: __m512i, b: __m512h) -> __m512h { _mm512_castsi512_ph(_mm512_permutex2var_epi16( _mm512_castph_si512(a), @@ -11860,7 +11860,7 @@ pub fn _mm512_permutex2var_ph(a: __m512h, idx: __m512i, b: __m512h) -> __m512h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_permutexvar_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_permutexvar_ph(idx: __m128i, a: __m128h) -> __m128h { _mm_castsi128_ph(_mm_permutexvar_epi16(idx, _mm_castph_si128(a))) } @@ -11871,7 +11871,7 @@ pub fn _mm_permutexvar_ph(idx: __m128i, a: __m128h) -> __m128h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_permutexvar_ph) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_permutexvar_ph(idx: __m256i, a: __m256h) -> __m256h { _mm256_castsi256_ph(_mm256_permutexvar_epi16(idx, _mm256_castph_si256(a))) } @@ -11882,7 +11882,7 @@ pub fn _mm256_permutexvar_ph(idx: __m256i, a: __m256h) -> __m256h { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm512_permutexvar_ph) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_permutexvar_ph(idx: __m512i, a: __m512h) -> __m512h { _mm512_castsi512_ph(_mm512_permutexvar_epi16(idx, _mm512_castph_si512(a))) } @@ -11894,7 +11894,7 @@ pub fn _mm512_permutexvar_ph(idx: __m512i, a: __m512h) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtepi16_ph(a: __m128i) -> __m128h { unsafe { vcvtw2ph_128(a.as_i16x8(), _MM_FROUND_CUR_DIRECTION) } } @@ -11907,7 +11907,7 @@ pub fn _mm_cvtepi16_ph(a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtepi16_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { unsafe { simd_select_bitmask(k, _mm_cvtepi16_ph(a), src) } } @@ -11919,7 +11919,7 @@ pub fn _mm_mask_cvtepi16_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtepi16_ph(k: __mmask8, a: __m128i) -> __m128h { _mm_mask_cvtepi16_ph(_mm_setzero_ph(), k, a) } @@ -11931,7 +11931,7 @@ pub fn _mm_maskz_cvtepi16_ph(k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtepi16_ph(a: __m256i) -> __m256h { unsafe { vcvtw2ph_256(a.as_i16x16(), _MM_FROUND_CUR_DIRECTION) } } @@ -11944,7 +11944,7 @@ pub fn _mm256_cvtepi16_ph(a: __m256i) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtepi16_ph(src: __m256h, k: __mmask16, a: __m256i) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_cvtepi16_ph(a), src) } } @@ -11956,7 +11956,7 @@ pub fn _mm256_mask_cvtepi16_ph(src: __m256h, k: __mmask16, a: __m256i) -> __m256 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtepi16_ph(k: __mmask16, a: __m256i) -> __m256h { _mm256_mask_cvtepi16_ph(_mm256_setzero_ph(), k, a) } @@ -11968,7 +11968,7 @@ pub fn _mm256_maskz_cvtepi16_ph(k: __mmask16, a: __m256i) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtepi16_ph(a: __m512i) -> __m512h { unsafe { vcvtw2ph_512(a.as_i16x32(), _MM_FROUND_CUR_DIRECTION) } } @@ -11981,7 +11981,7 @@ pub fn _mm512_cvtepi16_ph(a: __m512i) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtepi16_ph(src: __m512h, k: __mmask32, a: __m512i) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_cvtepi16_ph(a), src) } } @@ -11993,7 +11993,7 @@ pub fn _mm512_mask_cvtepi16_ph(src: __m512h, k: __mmask32, a: __m512i) -> __m512 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtepi16_ph(k: __mmask32, a: __m512i) -> __m512h { _mm512_mask_cvtepi16_ph(_mm512_setzero_ph(), k, a) } @@ -12014,7 +12014,7 @@ pub fn _mm512_maskz_cvtepi16_ph(k: __mmask32, a: __m512i) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtw2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundepi16_ph(a: __m512i) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -12039,7 +12039,7 @@ pub fn _mm512_cvt_roundepi16_ph(a: __m512i) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtw2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundepi16_ph( src: __m512h, k: __mmask32, @@ -12067,7 +12067,7 @@ pub fn _mm512_mask_cvt_roundepi16_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtw2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundepi16_ph(k: __mmask32, a: __m512i) -> __m512h { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundepi16_ph::(_mm512_setzero_ph(), k, a) @@ -12080,7 +12080,7 @@ pub fn _mm512_maskz_cvt_roundepi16_ph(k: __mmask32, a: __m5 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtepu16_ph(a: __m128i) -> __m128h { unsafe { vcvtuw2ph_128(a.as_u16x8(), _MM_FROUND_CUR_DIRECTION) } } @@ -12093,7 +12093,7 @@ pub fn _mm_cvtepu16_ph(a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtepu16_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { unsafe { simd_select_bitmask(k, _mm_cvtepu16_ph(a), src) } } @@ -12105,7 +12105,7 @@ pub fn _mm_mask_cvtepu16_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtepu16_ph(k: __mmask8, a: __m128i) -> __m128h { _mm_mask_cvtepu16_ph(_mm_setzero_ph(), k, a) } @@ -12117,7 +12117,7 @@ pub fn _mm_maskz_cvtepu16_ph(k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtepu16_ph(a: __m256i) -> __m256h { unsafe { vcvtuw2ph_256(a.as_u16x16(), _MM_FROUND_CUR_DIRECTION) } } @@ -12130,7 +12130,7 @@ pub fn _mm256_cvtepu16_ph(a: __m256i) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtepu16_ph(src: __m256h, k: __mmask16, a: __m256i) -> __m256h { unsafe { simd_select_bitmask(k, _mm256_cvtepu16_ph(a), src) } } @@ -12142,7 +12142,7 @@ pub fn _mm256_mask_cvtepu16_ph(src: __m256h, k: __mmask16, a: __m256i) -> __m256 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtepu16_ph(k: __mmask16, a: __m256i) -> __m256h { _mm256_mask_cvtepu16_ph(_mm256_setzero_ph(), k, a) } @@ -12154,7 +12154,7 @@ pub fn _mm256_maskz_cvtepu16_ph(k: __mmask16, a: __m256i) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtepu16_ph(a: __m512i) -> __m512h { unsafe { vcvtuw2ph_512(a.as_u16x32(), _MM_FROUND_CUR_DIRECTION) } } @@ -12167,7 +12167,7 @@ pub fn _mm512_cvtepu16_ph(a: __m512i) -> __m512h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtepu16_ph(src: __m512h, k: __mmask32, a: __m512i) -> __m512h { unsafe { simd_select_bitmask(k, _mm512_cvtepu16_ph(a), src) } } @@ -12179,7 +12179,7 @@ pub fn _mm512_mask_cvtepu16_ph(src: __m512h, k: __mmask32, a: __m512i) -> __m512 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuw2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtepu16_ph(k: __mmask32, a: __m512i) -> __m512h { _mm512_mask_cvtepu16_ph(_mm512_setzero_ph(), k, a) } @@ -12200,7 +12200,7 @@ pub fn _mm512_maskz_cvtepu16_ph(k: __mmask32, a: __m512i) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuw2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundepu16_ph(a: __m512i) -> __m512h { unsafe { static_assert_rounding!(ROUNDING); @@ -12225,7 +12225,7 @@ pub fn _mm512_cvt_roundepu16_ph(a: __m512i) -> __m512h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuw2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundepu16_ph( src: __m512h, k: __mmask32, @@ -12253,7 +12253,7 @@ pub fn _mm512_mask_cvt_roundepu16_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuw2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundepu16_ph(k: __mmask32, a: __m512i) -> __m512h { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundepu16_ph::(_mm512_setzero_ph(), k, a) @@ -12266,7 +12266,7 @@ pub fn _mm512_maskz_cvt_roundepu16_ph(k: __mmask32, a: __m5 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtdq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtepi32_ph(a: __m128i) -> __m128h { _mm_mask_cvtepi32_ph(_mm_setzero_ph(), 0xff, a) } @@ -12279,7 +12279,7 @@ pub fn _mm_cvtepi32_ph(a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtdq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtepi32_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { unsafe { vcvtdq2ph_128(a.as_i32x4(), src, k) } } @@ -12292,7 +12292,7 @@ pub fn _mm_mask_cvtepi32_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtdq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtepi32_ph(k: __mmask8, a: __m128i) -> __m128h { _mm_mask_cvtepi32_ph(_mm_setzero_ph(), k, a) } @@ -12304,7 +12304,7 @@ pub fn _mm_maskz_cvtepi32_ph(k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtdq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtepi32_ph(a: __m256i) -> __m128h { unsafe { vcvtdq2ph_256(a.as_i32x8(), _MM_FROUND_CUR_DIRECTION) } } @@ -12317,7 +12317,7 @@ pub fn _mm256_cvtepi32_ph(a: __m256i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtdq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtepi32_ph(src: __m128h, k: __mmask8, a: __m256i) -> __m128h { unsafe { simd_select_bitmask(k, _mm256_cvtepi32_ph(a), src) } } @@ -12329,7 +12329,7 @@ pub fn _mm256_mask_cvtepi32_ph(src: __m128h, k: __mmask8, a: __m256i) -> __m128h #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtdq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtepi32_ph(k: __mmask8, a: __m256i) -> __m128h { _mm256_mask_cvtepi32_ph(_mm_setzero_ph(), k, a) } @@ -12341,7 +12341,7 @@ pub fn _mm256_maskz_cvtepi32_ph(k: __mmask8, a: __m256i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtdq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtepi32_ph(a: __m512i) -> __m256h { unsafe { vcvtdq2ph_512(a.as_i32x16(), _MM_FROUND_CUR_DIRECTION) } } @@ -12354,7 +12354,7 @@ pub fn _mm512_cvtepi32_ph(a: __m512i) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtdq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtepi32_ph(src: __m256h, k: __mmask16, a: __m512i) -> __m256h { unsafe { simd_select_bitmask(k, _mm512_cvtepi32_ph(a), src) } } @@ -12366,7 +12366,7 @@ pub fn _mm512_mask_cvtepi32_ph(src: __m256h, k: __mmask16, a: __m512i) -> __m256 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtdq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtepi32_ph(k: __mmask16, a: __m512i) -> __m256h { _mm512_mask_cvtepi32_ph(f16x16::ZERO.as_m256h(), k, a) } @@ -12387,7 +12387,7 @@ pub fn _mm512_maskz_cvtepi32_ph(k: __mmask16, a: __m512i) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtdq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundepi32_ph(a: __m512i) -> __m256h { unsafe { static_assert_rounding!(ROUNDING); @@ -12412,7 +12412,7 @@ pub fn _mm512_cvt_roundepi32_ph(a: __m512i) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtdq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundepi32_ph( src: __m256h, k: __mmask16, @@ -12440,7 +12440,7 @@ pub fn _mm512_mask_cvt_roundepi32_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtdq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundepi32_ph(k: __mmask16, a: __m512i) -> __m256h { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundepi32_ph::(f16x16::ZERO.as_m256h(), k, a) @@ -12454,7 +12454,7 @@ pub fn _mm512_maskz_cvt_roundepi32_ph(k: __mmask16, a: __m5 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsi2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvti32_sh(a: __m128h, b: i32) -> __m128h { unsafe { vcvtsi2sh(a, b, _MM_FROUND_CUR_DIRECTION) } } @@ -12476,7 +12476,7 @@ pub fn _mm_cvti32_sh(a: __m128h, b: i32) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsi2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundi32_sh(a: __m128h, b: i32) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -12491,7 +12491,7 @@ pub fn _mm_cvt_roundi32_sh(a: __m128h, b: i32) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtudq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtepu32_ph(a: __m128i) -> __m128h { _mm_mask_cvtepu32_ph(_mm_setzero_ph(), 0xff, a) } @@ -12504,7 +12504,7 @@ pub fn _mm_cvtepu32_ph(a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtudq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtepu32_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { unsafe { vcvtudq2ph_128(a.as_u32x4(), src, k) } } @@ -12517,7 +12517,7 @@ pub fn _mm_mask_cvtepu32_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtudq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtepu32_ph(k: __mmask8, a: __m128i) -> __m128h { _mm_mask_cvtepu32_ph(_mm_setzero_ph(), k, a) } @@ -12529,7 +12529,7 @@ pub fn _mm_maskz_cvtepu32_ph(k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtudq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtepu32_ph(a: __m256i) -> __m128h { unsafe { vcvtudq2ph_256(a.as_u32x8(), _MM_FROUND_CUR_DIRECTION) } } @@ -12542,7 +12542,7 @@ pub fn _mm256_cvtepu32_ph(a: __m256i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtudq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtepu32_ph(src: __m128h, k: __mmask8, a: __m256i) -> __m128h { unsafe { simd_select_bitmask(k, _mm256_cvtepu32_ph(a), src) } } @@ -12554,7 +12554,7 @@ pub fn _mm256_mask_cvtepu32_ph(src: __m128h, k: __mmask8, a: __m256i) -> __m128h #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtudq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtepu32_ph(k: __mmask8, a: __m256i) -> __m128h { _mm256_mask_cvtepu32_ph(_mm_setzero_ph(), k, a) } @@ -12566,7 +12566,7 @@ pub fn _mm256_maskz_cvtepu32_ph(k: __mmask8, a: __m256i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtudq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtepu32_ph(a: __m512i) -> __m256h { unsafe { vcvtudq2ph_512(a.as_u32x16(), _MM_FROUND_CUR_DIRECTION) } } @@ -12579,7 +12579,7 @@ pub fn _mm512_cvtepu32_ph(a: __m512i) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtudq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtepu32_ph(src: __m256h, k: __mmask16, a: __m512i) -> __m256h { unsafe { simd_select_bitmask(k, _mm512_cvtepu32_ph(a), src) } } @@ -12591,7 +12591,7 @@ pub fn _mm512_mask_cvtepu32_ph(src: __m256h, k: __mmask16, a: __m512i) -> __m256 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtudq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtepu32_ph(k: __mmask16, a: __m512i) -> __m256h { _mm512_mask_cvtepu32_ph(f16x16::ZERO.as_m256h(), k, a) } @@ -12612,7 +12612,7 @@ pub fn _mm512_maskz_cvtepu32_ph(k: __mmask16, a: __m512i) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtudq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundepu32_ph(a: __m512i) -> __m256h { unsafe { static_assert_rounding!(ROUNDING); @@ -12637,7 +12637,7 @@ pub fn _mm512_cvt_roundepu32_ph(a: __m512i) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtudq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundepu32_ph( src: __m256h, k: __mmask16, @@ -12665,7 +12665,7 @@ pub fn _mm512_mask_cvt_roundepu32_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtudq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundepu32_ph(k: __mmask16, a: __m512i) -> __m256h { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundepu32_ph::(f16x16::ZERO.as_m256h(), k, a) @@ -12679,7 +12679,7 @@ pub fn _mm512_maskz_cvt_roundepu32_ph(k: __mmask16, a: __m5 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtusi2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtu32_sh(a: __m128h, b: u32) -> __m128h { unsafe { vcvtusi2sh(a, b, _MM_FROUND_CUR_DIRECTION) } } @@ -12701,7 +12701,7 @@ pub fn _mm_cvtu32_sh(a: __m128h, b: u32) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtusi2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundu32_sh(a: __m128h, b: u32) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -12716,7 +12716,7 @@ pub fn _mm_cvt_roundu32_sh(a: __m128h, b: u32) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtepi64_ph(a: __m128i) -> __m128h { _mm_mask_cvtepi64_ph(_mm_setzero_ph(), 0xff, a) } @@ -12729,7 +12729,7 @@ pub fn _mm_cvtepi64_ph(a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtepi64_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { unsafe { vcvtqq2ph_128(a.as_i64x2(), src, k) } } @@ -12742,7 +12742,7 @@ pub fn _mm_mask_cvtepi64_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtepi64_ph(k: __mmask8, a: __m128i) -> __m128h { _mm_mask_cvtepi64_ph(_mm_setzero_ph(), k, a) } @@ -12754,7 +12754,7 @@ pub fn _mm_maskz_cvtepi64_ph(k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtepi64_ph(a: __m256i) -> __m128h { _mm256_mask_cvtepi64_ph(_mm_setzero_ph(), 0xff, a) } @@ -12767,7 +12767,7 @@ pub fn _mm256_cvtepi64_ph(a: __m256i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtepi64_ph(src: __m128h, k: __mmask8, a: __m256i) -> __m128h { unsafe { vcvtqq2ph_256(a.as_i64x4(), src, k) } } @@ -12780,7 +12780,7 @@ pub fn _mm256_mask_cvtepi64_ph(src: __m128h, k: __mmask8, a: __m256i) -> __m128h #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtepi64_ph(k: __mmask8, a: __m256i) -> __m128h { _mm256_mask_cvtepi64_ph(_mm_setzero_ph(), k, a) } @@ -12792,7 +12792,7 @@ pub fn _mm256_maskz_cvtepi64_ph(k: __mmask8, a: __m256i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtepi64_ph(a: __m512i) -> __m128h { unsafe { vcvtqq2ph_512(a.as_i64x8(), _MM_FROUND_CUR_DIRECTION) } } @@ -12805,7 +12805,7 @@ pub fn _mm512_cvtepi64_ph(a: __m512i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtepi64_ph(src: __m128h, k: __mmask8, a: __m512i) -> __m128h { unsafe { simd_select_bitmask(k, _mm512_cvtepi64_ph(a), src) } } @@ -12817,7 +12817,7 @@ pub fn _mm512_mask_cvtepi64_ph(src: __m128h, k: __mmask8, a: __m512i) -> __m128h #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtepi64_ph(k: __mmask8, a: __m512i) -> __m128h { _mm512_mask_cvtepi64_ph(f16x8::ZERO.as_m128h(), k, a) } @@ -12838,7 +12838,7 @@ pub fn _mm512_maskz_cvtepi64_ph(k: __mmask8, a: __m512i) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtqq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundepi64_ph(a: __m512i) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -12863,7 +12863,7 @@ pub fn _mm512_cvt_roundepi64_ph(a: __m512i) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtqq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundepi64_ph( src: __m128h, k: __mmask8, @@ -12891,7 +12891,7 @@ pub fn _mm512_mask_cvt_roundepi64_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtqq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundepi64_ph(k: __mmask8, a: __m512i) -> __m128h { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundepi64_ph::(f16x8::ZERO.as_m128h(), k, a) @@ -12904,7 +12904,7 @@ pub fn _mm512_maskz_cvt_roundepi64_ph(k: __mmask8, a: __m51 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtepu64_ph(a: __m128i) -> __m128h { _mm_mask_cvtepu64_ph(_mm_setzero_ph(), 0xff, a) } @@ -12917,7 +12917,7 @@ pub fn _mm_cvtepu64_ph(a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtepu64_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { unsafe { vcvtuqq2ph_128(a.as_u64x2(), src, k) } } @@ -12930,7 +12930,7 @@ pub fn _mm_mask_cvtepu64_ph(src: __m128h, k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtepu64_ph(k: __mmask8, a: __m128i) -> __m128h { _mm_mask_cvtepu64_ph(_mm_setzero_ph(), k, a) } @@ -12942,7 +12942,7 @@ pub fn _mm_maskz_cvtepu64_ph(k: __mmask8, a: __m128i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtepu64_ph(a: __m256i) -> __m128h { _mm256_mask_cvtepu64_ph(_mm_setzero_ph(), 0xff, a) } @@ -12955,7 +12955,7 @@ pub fn _mm256_cvtepu64_ph(a: __m256i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtepu64_ph(src: __m128h, k: __mmask8, a: __m256i) -> __m128h { unsafe { vcvtuqq2ph_256(a.as_u64x4(), src, k) } } @@ -12968,7 +12968,7 @@ pub fn _mm256_mask_cvtepu64_ph(src: __m128h, k: __mmask8, a: __m256i) -> __m128h #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtuqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtepu64_ph(k: __mmask8, a: __m256i) -> __m128h { _mm256_mask_cvtepu64_ph(_mm_setzero_ph(), k, a) } @@ -12980,7 +12980,7 @@ pub fn _mm256_maskz_cvtepu64_ph(k: __mmask8, a: __m256i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtepu64_ph(a: __m512i) -> __m128h { unsafe { vcvtuqq2ph_512(a.as_u64x8(), _MM_FROUND_CUR_DIRECTION) } } @@ -12993,7 +12993,7 @@ pub fn _mm512_cvtepu64_ph(a: __m512i) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtepu64_ph(src: __m128h, k: __mmask8, a: __m512i) -> __m128h { unsafe { simd_select_bitmask(k, _mm512_cvtepu64_ph(a), src) } } @@ -13005,7 +13005,7 @@ pub fn _mm512_mask_cvtepu64_ph(src: __m128h, k: __mmask8, a: __m512i) -> __m128h #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuqq2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtepu64_ph(k: __mmask8, a: __m512i) -> __m128h { _mm512_mask_cvtepu64_ph(f16x8::ZERO.as_m128h(), k, a) } @@ -13026,7 +13026,7 @@ pub fn _mm512_maskz_cvtepu64_ph(k: __mmask8, a: __m512i) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuqq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundepu64_ph(a: __m512i) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -13051,7 +13051,7 @@ pub fn _mm512_cvt_roundepu64_ph(a: __m512i) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuqq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundepu64_ph( src: __m128h, k: __mmask8, @@ -13079,7 +13079,7 @@ pub fn _mm512_mask_cvt_roundepu64_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtuqq2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundepu64_ph(k: __mmask8, a: __m512i) -> __m128h { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundepu64_ph::(f16x8::ZERO.as_m128h(), k, a) @@ -13092,7 +13092,7 @@ pub fn _mm512_maskz_cvt_roundepu64_ph(k: __mmask8, a: __m51 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtps2phx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtxps_ph(a: __m128) -> __m128h { _mm_mask_cvtxps_ph(_mm_setzero_ph(), 0xff, a) } @@ -13105,7 +13105,7 @@ pub fn _mm_cvtxps_ph(a: __m128) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtps2phx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtxps_ph(src: __m128h, k: __mmask8, a: __m128) -> __m128h { unsafe { vcvtps2phx_128(a, src, k) } } @@ -13118,7 +13118,7 @@ pub fn _mm_mask_cvtxps_ph(src: __m128h, k: __mmask8, a: __m128) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtps2phx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtxps_ph(k: __mmask8, a: __m128) -> __m128h { _mm_mask_cvtxps_ph(_mm_setzero_ph(), k, a) } @@ -13130,7 +13130,7 @@ pub fn _mm_maskz_cvtxps_ph(k: __mmask8, a: __m128) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtps2phx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtxps_ph(a: __m256) -> __m128h { _mm256_mask_cvtxps_ph(_mm_setzero_ph(), 0xff, a) } @@ -13143,7 +13143,7 @@ pub fn _mm256_cvtxps_ph(a: __m256) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtps2phx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtxps_ph(src: __m128h, k: __mmask8, a: __m256) -> __m128h { unsafe { vcvtps2phx_256(a, src, k) } } @@ -13156,7 +13156,7 @@ pub fn _mm256_mask_cvtxps_ph(src: __m128h, k: __mmask8, a: __m256) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtps2phx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtxps_ph(k: __mmask8, a: __m256) -> __m128h { _mm256_mask_cvtxps_ph(_mm_setzero_ph(), k, a) } @@ -13168,7 +13168,7 @@ pub fn _mm256_maskz_cvtxps_ph(k: __mmask8, a: __m256) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtps2phx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtxps_ph(a: __m512) -> __m256h { _mm512_mask_cvtxps_ph(f16x16::ZERO.as_m256h(), 0xffff, a) } @@ -13181,7 +13181,7 @@ pub fn _mm512_cvtxps_ph(a: __m512) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtps2phx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtxps_ph(src: __m256h, k: __mmask16, a: __m512) -> __m256h { unsafe { vcvtps2phx_512(a, src, k, _MM_FROUND_CUR_DIRECTION) } } @@ -13194,7 +13194,7 @@ pub fn _mm512_mask_cvtxps_ph(src: __m256h, k: __mmask16, a: __m512) -> __m256h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtps2phx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtxps_ph(k: __mmask16, a: __m512) -> __m256h { _mm512_mask_cvtxps_ph(f16x16::ZERO.as_m256h(), k, a) } @@ -13215,7 +13215,7 @@ pub fn _mm512_maskz_cvtxps_ph(k: __mmask16, a: __m512) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtps2phx, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtx_roundps_ph(a: __m512) -> __m256h { static_assert_rounding!(ROUNDING); _mm512_mask_cvtx_roundps_ph::(f16x16::ZERO.as_m256h(), 0xffff, a) @@ -13238,7 +13238,7 @@ pub fn _mm512_cvtx_roundps_ph(a: __m512) -> __m256h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtps2phx, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtx_roundps_ph( src: __m256h, k: __mmask16, @@ -13267,7 +13267,7 @@ pub fn _mm512_mask_cvtx_roundps_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtps2phx, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtx_roundps_ph(k: __mmask16, a: __m512) -> __m256h { static_assert_rounding!(ROUNDING); _mm512_mask_cvtx_roundps_ph::(f16x16::ZERO.as_m256h(), k, a) @@ -13281,7 +13281,7 @@ pub fn _mm512_maskz_cvtx_roundps_ph(k: __mmask16, a: __m512 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtss2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtss_sh(a: __m128h, b: __m128) -> __m128h { _mm_mask_cvtss_sh(f16x8::ZERO.as_m128h(), 0xff, a, b) } @@ -13295,7 +13295,7 @@ pub fn _mm_cvtss_sh(a: __m128h, b: __m128) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtss2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtss_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128) -> __m128h { unsafe { vcvtss2sh(a, b, src, k, _MM_FROUND_CUR_DIRECTION) } } @@ -13309,7 +13309,7 @@ pub fn _mm_mask_cvtss_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128) -> __ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtss2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtss_sh(k: __mmask8, a: __m128h, b: __m128) -> __m128h { _mm_mask_cvtss_sh(f16x8::ZERO.as_m128h(), k, a, b) } @@ -13331,7 +13331,7 @@ pub fn _mm_maskz_cvtss_sh(k: __mmask8, a: __m128h, b: __m128) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtss2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundss_sh(a: __m128h, b: __m128) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_cvt_roundss_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -13355,7 +13355,7 @@ pub fn _mm_cvt_roundss_sh(a: __m128h, b: __m128) -> __m128h #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtss2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvt_roundss_sh( src: __m128h, k: __mmask8, @@ -13386,7 +13386,7 @@ pub fn _mm_mask_cvt_roundss_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtss2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvt_roundss_sh( k: __mmask8, a: __m128h, @@ -13403,7 +13403,7 @@ pub fn _mm_maskz_cvt_roundss_sh( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtpd2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtpd_ph(a: __m128d) -> __m128h { _mm_mask_cvtpd_ph(_mm_setzero_ph(), 0xff, a) } @@ -13416,7 +13416,7 @@ pub fn _mm_cvtpd_ph(a: __m128d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtpd2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtpd_ph(src: __m128h, k: __mmask8, a: __m128d) -> __m128h { unsafe { vcvtpd2ph_128(a, src, k) } } @@ -13429,7 +13429,7 @@ pub fn _mm_mask_cvtpd_ph(src: __m128h, k: __mmask8, a: __m128d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtpd2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtpd_ph(k: __mmask8, a: __m128d) -> __m128h { _mm_mask_cvtpd_ph(_mm_setzero_ph(), k, a) } @@ -13441,7 +13441,7 @@ pub fn _mm_maskz_cvtpd_ph(k: __mmask8, a: __m128d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtpd2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtpd_ph(a: __m256d) -> __m128h { _mm256_mask_cvtpd_ph(_mm_setzero_ph(), 0xff, a) } @@ -13454,7 +13454,7 @@ pub fn _mm256_cvtpd_ph(a: __m256d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtpd2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtpd_ph(src: __m128h, k: __mmask8, a: __m256d) -> __m128h { unsafe { vcvtpd2ph_256(a, src, k) } } @@ -13467,7 +13467,7 @@ pub fn _mm256_mask_cvtpd_ph(src: __m128h, k: __mmask8, a: __m256d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtpd2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtpd_ph(k: __mmask8, a: __m256d) -> __m128h { _mm256_mask_cvtpd_ph(_mm_setzero_ph(), k, a) } @@ -13479,7 +13479,7 @@ pub fn _mm256_maskz_cvtpd_ph(k: __mmask8, a: __m256d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtpd2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtpd_ph(a: __m512d) -> __m128h { _mm512_mask_cvtpd_ph(f16x8::ZERO.as_m128h(), 0xff, a) } @@ -13492,7 +13492,7 @@ pub fn _mm512_cvtpd_ph(a: __m512d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtpd2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtpd_ph(src: __m128h, k: __mmask8, a: __m512d) -> __m128h { unsafe { vcvtpd2ph_512(a, src, k, _MM_FROUND_CUR_DIRECTION) } } @@ -13505,7 +13505,7 @@ pub fn _mm512_mask_cvtpd_ph(src: __m128h, k: __mmask8, a: __m512d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtpd2ph))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtpd_ph(k: __mmask8, a: __m512d) -> __m128h { _mm512_mask_cvtpd_ph(f16x8::ZERO.as_m128h(), k, a) } @@ -13526,7 +13526,7 @@ pub fn _mm512_maskz_cvtpd_ph(k: __mmask8, a: __m512d) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtpd2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundpd_ph(a: __m512d) -> __m128h { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundpd_ph::(f16x8::ZERO.as_m128h(), 0xff, a) @@ -13549,7 +13549,7 @@ pub fn _mm512_cvt_roundpd_ph(a: __m512d) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtpd2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundpd_ph( src: __m128h, k: __mmask8, @@ -13578,7 +13578,7 @@ pub fn _mm512_mask_cvt_roundpd_ph( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtpd2ph, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundpd_ph(k: __mmask8, a: __m512d) -> __m128h { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundpd_ph::(f16x8::ZERO.as_m128h(), k, a) @@ -13592,7 +13592,7 @@ pub fn _mm512_maskz_cvt_roundpd_ph(k: __mmask8, a: __m512d) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsd2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtsd_sh(a: __m128h, b: __m128d) -> __m128h { _mm_mask_cvtsd_sh(f16x8::ZERO.as_m128h(), 0xff, a, b) } @@ -13606,7 +13606,7 @@ pub fn _mm_cvtsd_sh(a: __m128h, b: __m128d) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsd2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtsd_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128d) -> __m128h { unsafe { vcvtsd2sh(a, b, src, k, _MM_FROUND_CUR_DIRECTION) } } @@ -13620,7 +13620,7 @@ pub fn _mm_mask_cvtsd_sh(src: __m128h, k: __mmask8, a: __m128h, b: __m128d) -> _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsd2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtsd_sh(k: __mmask8, a: __m128h, b: __m128d) -> __m128h { _mm_mask_cvtsd_sh(f16x8::ZERO.as_m128h(), k, a, b) } @@ -13642,7 +13642,7 @@ pub fn _mm_maskz_cvtsd_sh(k: __mmask8, a: __m128h, b: __m128d) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsd2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundsd_sh(a: __m128h, b: __m128d) -> __m128h { static_assert_rounding!(ROUNDING); _mm_mask_cvt_roundsd_sh::(f16x8::ZERO.as_m128h(), 0xff, a, b) @@ -13666,7 +13666,7 @@ pub fn _mm_cvt_roundsd_sh(a: __m128h, b: __m128d) -> __m128 #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsd2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvt_roundsd_sh( src: __m128h, k: __mmask8, @@ -13697,7 +13697,7 @@ pub fn _mm_mask_cvt_roundsd_sh( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsd2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvt_roundsd_sh( k: __mmask8, a: __m128h, @@ -13714,7 +13714,7 @@ pub fn _mm_maskz_cvt_roundsd_sh( #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtph_epi16(a: __m128h) -> __m128i { _mm_mask_cvtph_epi16(_mm_undefined_si128(), 0xff, a) } @@ -13727,7 +13727,7 @@ pub fn _mm_cvtph_epi16(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtph_epi16(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvtph2w_128(a, src.as_i16x8(), k)) } } @@ -13739,7 +13739,7 @@ pub fn _mm_mask_cvtph_epi16(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtph_epi16(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvtph_epi16(_mm_setzero_si128(), k, a) } @@ -13751,7 +13751,7 @@ pub fn _mm_maskz_cvtph_epi16(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtph_epi16(a: __m256h) -> __m256i { _mm256_mask_cvtph_epi16(_mm256_undefined_si256(), 0xffff, a) } @@ -13764,7 +13764,7 @@ pub fn _mm256_cvtph_epi16(a: __m256h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtph_epi16(src: __m256i, k: __mmask16, a: __m256h) -> __m256i { unsafe { transmute(vcvtph2w_256(a, src.as_i16x16(), k)) } } @@ -13776,7 +13776,7 @@ pub fn _mm256_mask_cvtph_epi16(src: __m256i, k: __mmask16, a: __m256h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtph_epi16(k: __mmask16, a: __m256h) -> __m256i { _mm256_mask_cvtph_epi16(_mm256_setzero_si256(), k, a) } @@ -13788,7 +13788,7 @@ pub fn _mm256_maskz_cvtph_epi16(k: __mmask16, a: __m256h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtph_epi16(a: __m512h) -> __m512i { _mm512_mask_cvtph_epi16(_mm512_undefined_epi32(), 0xffffffff, a) } @@ -13801,7 +13801,7 @@ pub fn _mm512_cvtph_epi16(a: __m512h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtph_epi16(src: __m512i, k: __mmask32, a: __m512h) -> __m512i { unsafe { transmute(vcvtph2w_512( @@ -13820,7 +13820,7 @@ pub fn _mm512_mask_cvtph_epi16(src: __m512i, k: __mmask32, a: __m512h) -> __m512 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtph_epi16(k: __mmask32, a: __m512h) -> __m512i { _mm512_mask_cvtph_epi16(_mm512_setzero_si512(), k, a) } @@ -13841,7 +13841,7 @@ pub fn _mm512_maskz_cvtph_epi16(k: __mmask32, a: __m512h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2w, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundph_epi16(a: __m512h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epi16::(_mm512_undefined_epi32(), 0xffffffff, a) @@ -13864,7 +13864,7 @@ pub fn _mm512_cvt_roundph_epi16(a: __m512h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2w, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundph_epi16( src: __m512i, k: __mmask32, @@ -13892,7 +13892,7 @@ pub fn _mm512_mask_cvt_roundph_epi16( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2w, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundph_epi16(k: __mmask32, a: __m512h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epi16::(_mm512_setzero_si512(), k, a) @@ -13905,7 +13905,7 @@ pub fn _mm512_maskz_cvt_roundph_epi16(k: __mmask32, a: __m5 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtph_epu16(a: __m128h) -> __m128i { _mm_mask_cvtph_epu16(_mm_undefined_si128(), 0xff, a) } @@ -13918,7 +13918,7 @@ pub fn _mm_cvtph_epu16(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtph_epu16(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvtph2uw_128(a, src.as_u16x8(), k)) } } @@ -13930,7 +13930,7 @@ pub fn _mm_mask_cvtph_epu16(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtph_epu16(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvtph_epu16(_mm_setzero_si128(), k, a) } @@ -13942,7 +13942,7 @@ pub fn _mm_maskz_cvtph_epu16(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtph_epu16(a: __m256h) -> __m256i { _mm256_mask_cvtph_epu16(_mm256_undefined_si256(), 0xffff, a) } @@ -13955,7 +13955,7 @@ pub fn _mm256_cvtph_epu16(a: __m256h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtph_epu16(src: __m256i, k: __mmask16, a: __m256h) -> __m256i { unsafe { transmute(vcvtph2uw_256(a, src.as_u16x16(), k)) } } @@ -13967,7 +13967,7 @@ pub fn _mm256_mask_cvtph_epu16(src: __m256i, k: __mmask16, a: __m256h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtph_epu16(k: __mmask16, a: __m256h) -> __m256i { _mm256_mask_cvtph_epu16(_mm256_setzero_si256(), k, a) } @@ -13979,7 +13979,7 @@ pub fn _mm256_maskz_cvtph_epu16(k: __mmask16, a: __m256h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtph_epu16(a: __m512h) -> __m512i { _mm512_mask_cvtph_epu16(_mm512_undefined_epi32(), 0xffffffff, a) } @@ -13992,7 +13992,7 @@ pub fn _mm512_cvtph_epu16(a: __m512h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtph_epu16(src: __m512i, k: __mmask32, a: __m512h) -> __m512i { unsafe { transmute(vcvtph2uw_512( @@ -14011,7 +14011,7 @@ pub fn _mm512_mask_cvtph_epu16(src: __m512i, k: __mmask32, a: __m512h) -> __m512 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtph_epu16(k: __mmask32, a: __m512h) -> __m512i { _mm512_mask_cvtph_epu16(_mm512_setzero_si512(), k, a) } @@ -14026,7 +14026,7 @@ pub fn _mm512_maskz_cvtph_epu16(k: __mmask32, a: __m512h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uw, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundph_epu16(a: __m512h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvt_roundph_epu16::(_mm512_undefined_epi32(), 0xffffffff, a) @@ -14043,7 +14043,7 @@ pub fn _mm512_cvt_roundph_epu16(a: __m512h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uw, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundph_epu16( src: __m512i, k: __mmask32, @@ -14065,7 +14065,7 @@ pub fn _mm512_mask_cvt_roundph_epu16( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uw, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundph_epu16(k: __mmask32, a: __m512h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvt_roundph_epu16::(_mm512_setzero_si512(), k, a) @@ -14078,7 +14078,7 @@ pub fn _mm512_maskz_cvt_roundph_epu16(k: __mmask32, a: __m512h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttph_epi16(a: __m128h) -> __m128i { _mm_mask_cvttph_epi16(_mm_undefined_si128(), 0xff, a) } @@ -14091,7 +14091,7 @@ pub fn _mm_cvttph_epi16(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvttph_epi16(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvttph2w_128(a, src.as_i16x8(), k)) } } @@ -14104,7 +14104,7 @@ pub fn _mm_mask_cvttph_epi16(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvttph_epi16(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvttph_epi16(_mm_setzero_si128(), k, a) } @@ -14116,7 +14116,7 @@ pub fn _mm_maskz_cvttph_epi16(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvttph_epi16(a: __m256h) -> __m256i { _mm256_mask_cvttph_epi16(_mm256_undefined_si256(), 0xffff, a) } @@ -14129,7 +14129,7 @@ pub fn _mm256_cvttph_epi16(a: __m256h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvttph_epi16(src: __m256i, k: __mmask16, a: __m256h) -> __m256i { unsafe { transmute(vcvttph2w_256(a, src.as_i16x16(), k)) } } @@ -14142,7 +14142,7 @@ pub fn _mm256_mask_cvttph_epi16(src: __m256i, k: __mmask16, a: __m256h) -> __m25 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvttph_epi16(k: __mmask16, a: __m256h) -> __m256i { _mm256_mask_cvttph_epi16(_mm256_setzero_si256(), k, a) } @@ -14154,7 +14154,7 @@ pub fn _mm256_maskz_cvttph_epi16(k: __mmask16, a: __m256h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvttph_epi16(a: __m512h) -> __m512i { _mm512_mask_cvttph_epi16(_mm512_undefined_epi32(), 0xffffffff, a) } @@ -14167,7 +14167,7 @@ pub fn _mm512_cvttph_epi16(a: __m512h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvttph_epi16(src: __m512i, k: __mmask32, a: __m512h) -> __m512i { unsafe { transmute(vcvttph2w_512( @@ -14187,7 +14187,7 @@ pub fn _mm512_mask_cvttph_epi16(src: __m512i, k: __mmask32, a: __m512h) -> __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2w))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvttph_epi16(k: __mmask32, a: __m512h) -> __m512i { _mm512_mask_cvttph_epi16(_mm512_setzero_si512(), k, a) } @@ -14202,7 +14202,7 @@ pub fn _mm512_maskz_cvttph_epi16(k: __mmask32, a: __m512h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2w, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtt_roundph_epi16(a: __m512h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epi16::(_mm512_undefined_epi32(), 0xffffffff, a) @@ -14219,7 +14219,7 @@ pub fn _mm512_cvtt_roundph_epi16(a: __m512h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2w, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtt_roundph_epi16( src: __m512i, k: __mmask32, @@ -14242,7 +14242,7 @@ pub fn _mm512_mask_cvtt_roundph_epi16( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2w, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtt_roundph_epi16(k: __mmask32, a: __m512h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epi16::(_mm512_setzero_si512(), k, a) @@ -14255,7 +14255,7 @@ pub fn _mm512_maskz_cvtt_roundph_epi16(k: __mmask32, a: __m512h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttph_epu16(a: __m128h) -> __m128i { _mm_mask_cvttph_epu16(_mm_undefined_si128(), 0xff, a) } @@ -14268,7 +14268,7 @@ pub fn _mm_cvttph_epu16(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvttph_epu16(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvttph2uw_128(a, src.as_u16x8(), k)) } } @@ -14281,7 +14281,7 @@ pub fn _mm_mask_cvttph_epu16(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvttph_epu16(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvttph_epu16(_mm_setzero_si128(), k, a) } @@ -14293,7 +14293,7 @@ pub fn _mm_maskz_cvttph_epu16(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvttph_epu16(a: __m256h) -> __m256i { _mm256_mask_cvttph_epu16(_mm256_undefined_si256(), 0xffff, a) } @@ -14306,7 +14306,7 @@ pub fn _mm256_cvttph_epu16(a: __m256h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvttph_epu16(src: __m256i, k: __mmask16, a: __m256h) -> __m256i { unsafe { transmute(vcvttph2uw_256(a, src.as_u16x16(), k)) } } @@ -14319,7 +14319,7 @@ pub fn _mm256_mask_cvttph_epu16(src: __m256i, k: __mmask16, a: __m256h) -> __m25 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvttph_epu16(k: __mmask16, a: __m256h) -> __m256i { _mm256_mask_cvttph_epu16(_mm256_setzero_si256(), k, a) } @@ -14331,7 +14331,7 @@ pub fn _mm256_maskz_cvttph_epu16(k: __mmask16, a: __m256h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvttph_epu16(a: __m512h) -> __m512i { _mm512_mask_cvttph_epu16(_mm512_undefined_epi32(), 0xffffffff, a) } @@ -14344,7 +14344,7 @@ pub fn _mm512_cvttph_epu16(a: __m512h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvttph_epu16(src: __m512i, k: __mmask32, a: __m512h) -> __m512i { unsafe { transmute(vcvttph2uw_512( @@ -14364,7 +14364,7 @@ pub fn _mm512_mask_cvttph_epu16(src: __m512i, k: __mmask32, a: __m512h) -> __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uw))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvttph_epu16(k: __mmask32, a: __m512h) -> __m512i { _mm512_mask_cvttph_epu16(_mm512_setzero_si512(), k, a) } @@ -14379,7 +14379,7 @@ pub fn _mm512_maskz_cvttph_epu16(k: __mmask32, a: __m512h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uw, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtt_roundph_epu16(a: __m512h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epu16::(_mm512_undefined_epi32(), 0xffffffff, a) @@ -14396,7 +14396,7 @@ pub fn _mm512_cvtt_roundph_epu16(a: __m512h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uw, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtt_roundph_epu16( src: __m512i, k: __mmask32, @@ -14419,7 +14419,7 @@ pub fn _mm512_mask_cvtt_roundph_epu16( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uw, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtt_roundph_epu16(k: __mmask32, a: __m512h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epu16::(_mm512_setzero_si512(), k, a) @@ -14432,7 +14432,7 @@ pub fn _mm512_maskz_cvtt_roundph_epu16(k: __mmask32, a: __m512h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtph_epi32(a: __m128h) -> __m128i { _mm_mask_cvtph_epi32(_mm_undefined_si128(), 0xff, a) } @@ -14444,7 +14444,7 @@ pub fn _mm_cvtph_epi32(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtph_epi32(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvtph2dq_128(a, src.as_i32x4(), k)) } } @@ -14456,7 +14456,7 @@ pub fn _mm_mask_cvtph_epi32(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtph_epi32(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvtph_epi32(_mm_setzero_si128(), k, a) } @@ -14468,7 +14468,7 @@ pub fn _mm_maskz_cvtph_epi32(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtph_epi32(a: __m128h) -> __m256i { _mm256_mask_cvtph_epi32(_mm256_undefined_si256(), 0xff, a) } @@ -14480,7 +14480,7 @@ pub fn _mm256_cvtph_epi32(a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtph_epi32(src: __m256i, k: __mmask8, a: __m128h) -> __m256i { unsafe { transmute(vcvtph2dq_256(a, src.as_i32x8(), k)) } } @@ -14492,7 +14492,7 @@ pub fn _mm256_mask_cvtph_epi32(src: __m256i, k: __mmask8, a: __m128h) -> __m256i #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtph_epi32(k: __mmask8, a: __m128h) -> __m256i { _mm256_mask_cvtph_epi32(_mm256_setzero_si256(), k, a) } @@ -14504,7 +14504,7 @@ pub fn _mm256_maskz_cvtph_epi32(k: __mmask8, a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtph_epi32(a: __m256h) -> __m512i { _mm512_mask_cvtph_epi32(_mm512_undefined_epi32(), 0xffff, a) } @@ -14516,7 +14516,7 @@ pub fn _mm512_cvtph_epi32(a: __m256h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtph_epi32(src: __m512i, k: __mmask16, a: __m256h) -> __m512i { unsafe { transmute(vcvtph2dq_512( @@ -14535,7 +14535,7 @@ pub fn _mm512_mask_cvtph_epi32(src: __m512i, k: __mmask16, a: __m256h) -> __m512 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtph_epi32(k: __mmask16, a: __m256h) -> __m512i { _mm512_mask_cvtph_epi32(_mm512_setzero_si512(), k, a) } @@ -14556,7 +14556,7 @@ pub fn _mm512_maskz_cvtph_epi32(k: __mmask16, a: __m256h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2dq, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundph_epi32(a: __m256h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epi32::(_mm512_undefined_epi32(), 0xffff, a) @@ -14578,7 +14578,7 @@ pub fn _mm512_cvt_roundph_epi32(a: __m256h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2dq, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundph_epi32( src: __m512i, k: __mmask16, @@ -14606,7 +14606,7 @@ pub fn _mm512_mask_cvt_roundph_epi32( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2dq, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundph_epi32(k: __mmask16, a: __m256h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epi32::(_mm512_setzero_si512(), k, a) @@ -14619,7 +14619,7 @@ pub fn _mm512_maskz_cvt_roundph_epi32(k: __mmask16, a: __m2 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2si))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtsh_i32(a: __m128h) -> i32 { unsafe { vcvtsh2si32(a, _MM_FROUND_CUR_DIRECTION) } } @@ -14640,7 +14640,7 @@ pub fn _mm_cvtsh_i32(a: __m128h) -> i32 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2si, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundsh_i32(a: __m128h) -> i32 { unsafe { static_assert_rounding!(ROUNDING); @@ -14655,7 +14655,7 @@ pub fn _mm_cvt_roundsh_i32(a: __m128h) -> i32 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtph_epu32(a: __m128h) -> __m128i { _mm_mask_cvtph_epu32(_mm_undefined_si128(), 0xff, a) } @@ -14667,7 +14667,7 @@ pub fn _mm_cvtph_epu32(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtph_epu32(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvtph2udq_128(a, src.as_u32x4(), k)) } } @@ -14679,7 +14679,7 @@ pub fn _mm_mask_cvtph_epu32(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtph_epu32(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvtph_epu32(_mm_setzero_si128(), k, a) } @@ -14691,7 +14691,7 @@ pub fn _mm_maskz_cvtph_epu32(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtph_epu32(a: __m128h) -> __m256i { _mm256_mask_cvtph_epu32(_mm256_undefined_si256(), 0xff, a) } @@ -14703,7 +14703,7 @@ pub fn _mm256_cvtph_epu32(a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtph_epu32(src: __m256i, k: __mmask8, a: __m128h) -> __m256i { unsafe { transmute(vcvtph2udq_256(a, src.as_u32x8(), k)) } } @@ -14715,7 +14715,7 @@ pub fn _mm256_mask_cvtph_epu32(src: __m256i, k: __mmask8, a: __m128h) -> __m256i #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtph_epu32(k: __mmask8, a: __m128h) -> __m256i { _mm256_mask_cvtph_epu32(_mm256_setzero_si256(), k, a) } @@ -14727,7 +14727,7 @@ pub fn _mm256_maskz_cvtph_epu32(k: __mmask8, a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtph_epu32(a: __m256h) -> __m512i { _mm512_mask_cvtph_epu32(_mm512_undefined_epi32(), 0xffff, a) } @@ -14739,7 +14739,7 @@ pub fn _mm512_cvtph_epu32(a: __m256h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtph_epu32(src: __m512i, k: __mmask16, a: __m256h) -> __m512i { unsafe { transmute(vcvtph2udq_512( @@ -14758,7 +14758,7 @@ pub fn _mm512_mask_cvtph_epu32(src: __m512i, k: __mmask16, a: __m256h) -> __m512 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtph_epu32(k: __mmask16, a: __m256h) -> __m512i { _mm512_mask_cvtph_epu32(_mm512_setzero_si512(), k, a) } @@ -14779,7 +14779,7 @@ pub fn _mm512_maskz_cvtph_epu32(k: __mmask16, a: __m256h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2udq, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundph_epu32(a: __m256h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epu32::(_mm512_undefined_epi32(), 0xffff, a) @@ -14801,7 +14801,7 @@ pub fn _mm512_cvt_roundph_epu32(a: __m256h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2udq, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundph_epu32( src: __m512i, k: __mmask16, @@ -14829,7 +14829,7 @@ pub fn _mm512_mask_cvt_roundph_epu32( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2udq, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundph_epu32(k: __mmask16, a: __m256h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epu32::(_mm512_setzero_si512(), k, a) @@ -14842,7 +14842,7 @@ pub fn _mm512_maskz_cvt_roundph_epu32(k: __mmask16, a: __m2 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2usi))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtsh_u32(a: __m128h) -> u32 { unsafe { vcvtsh2usi32(a, _MM_FROUND_CUR_DIRECTION) } } @@ -14857,7 +14857,7 @@ pub fn _mm_cvtsh_u32(a: __m128h) -> u32 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2usi, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundsh_u32(a: __m128h) -> u32 { unsafe { static_assert_rounding!(SAE); @@ -14872,7 +14872,7 @@ pub fn _mm_cvt_roundsh_u32(a: __m128h) -> u32 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttph_epi32(a: __m128h) -> __m128i { _mm_mask_cvttph_epi32(_mm_undefined_si128(), 0xff, a) } @@ -14884,7 +14884,7 @@ pub fn _mm_cvttph_epi32(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvttph_epi32(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvttph2dq_128(a, src.as_i32x4(), k)) } } @@ -14896,7 +14896,7 @@ pub fn _mm_mask_cvttph_epi32(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvttph_epi32(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvttph_epi32(_mm_setzero_si128(), k, a) } @@ -14908,7 +14908,7 @@ pub fn _mm_maskz_cvttph_epi32(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvttph_epi32(a: __m128h) -> __m256i { _mm256_mask_cvttph_epi32(_mm256_undefined_si256(), 0xff, a) } @@ -14920,7 +14920,7 @@ pub fn _mm256_cvttph_epi32(a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvttph_epi32(src: __m256i, k: __mmask8, a: __m128h) -> __m256i { unsafe { transmute(vcvttph2dq_256(a, src.as_i32x8(), k)) } } @@ -14932,7 +14932,7 @@ pub fn _mm256_mask_cvttph_epi32(src: __m256i, k: __mmask8, a: __m128h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvttph_epi32(k: __mmask8, a: __m128h) -> __m256i { _mm256_mask_cvttph_epi32(_mm256_setzero_si256(), k, a) } @@ -14944,7 +14944,7 @@ pub fn _mm256_maskz_cvttph_epi32(k: __mmask8, a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvttph_epi32(a: __m256h) -> __m512i { _mm512_mask_cvttph_epi32(_mm512_undefined_epi32(), 0xffff, a) } @@ -14956,7 +14956,7 @@ pub fn _mm512_cvttph_epi32(a: __m256h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvttph_epi32(src: __m512i, k: __mmask16, a: __m256h) -> __m512i { unsafe { transmute(vcvttph2dq_512( @@ -14975,7 +14975,7 @@ pub fn _mm512_mask_cvttph_epi32(src: __m512i, k: __mmask16, a: __m256h) -> __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2dq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvttph_epi32(k: __mmask16, a: __m256h) -> __m512i { _mm512_mask_cvttph_epi32(_mm512_setzero_si512(), k, a) } @@ -14990,7 +14990,7 @@ pub fn _mm512_maskz_cvttph_epi32(k: __mmask16, a: __m256h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2dq, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtt_roundph_epi32(a: __m256h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epi32::(_mm512_undefined_epi32(), 0xffff, a) @@ -15006,7 +15006,7 @@ pub fn _mm512_cvtt_roundph_epi32(a: __m256h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2dq, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtt_roundph_epi32( src: __m512i, k: __mmask16, @@ -15028,7 +15028,7 @@ pub fn _mm512_mask_cvtt_roundph_epi32( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2dq, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtt_roundph_epi32(k: __mmask16, a: __m256h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epi32::(_mm512_setzero_si512(), k, a) @@ -15041,7 +15041,7 @@ pub fn _mm512_maskz_cvtt_roundph_epi32(k: __mmask16, a: __m256h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttsh2si))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttsh_i32(a: __m128h) -> i32 { unsafe { vcvttsh2si32(a, _MM_FROUND_CUR_DIRECTION) } } @@ -15056,7 +15056,7 @@ pub fn _mm_cvttsh_i32(a: __m128h) -> i32 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttsh2si, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtt_roundsh_i32(a: __m128h) -> i32 { unsafe { static_assert_sae!(SAE); @@ -15071,7 +15071,7 @@ pub fn _mm_cvtt_roundsh_i32(a: __m128h) -> i32 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttph_epu32(a: __m128h) -> __m128i { _mm_mask_cvttph_epu32(_mm_undefined_si128(), 0xff, a) } @@ -15083,7 +15083,7 @@ pub fn _mm_cvttph_epu32(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvttph_epu32(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvttph2udq_128(a, src.as_u32x4(), k)) } } @@ -15095,7 +15095,7 @@ pub fn _mm_mask_cvttph_epu32(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvttph_epu32(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvttph_epu32(_mm_setzero_si128(), k, a) } @@ -15107,7 +15107,7 @@ pub fn _mm_maskz_cvttph_epu32(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvttph_epu32(a: __m128h) -> __m256i { _mm256_mask_cvttph_epu32(_mm256_undefined_si256(), 0xff, a) } @@ -15119,7 +15119,7 @@ pub fn _mm256_cvttph_epu32(a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvttph_epu32(src: __m256i, k: __mmask8, a: __m128h) -> __m256i { unsafe { transmute(vcvttph2udq_256(a, src.as_u32x8(), k)) } } @@ -15131,7 +15131,7 @@ pub fn _mm256_mask_cvttph_epu32(src: __m256i, k: __mmask8, a: __m128h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvttph_epu32(k: __mmask8, a: __m128h) -> __m256i { _mm256_mask_cvttph_epu32(_mm256_setzero_si256(), k, a) } @@ -15143,7 +15143,7 @@ pub fn _mm256_maskz_cvttph_epu32(k: __mmask8, a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvttph_epu32(a: __m256h) -> __m512i { _mm512_mask_cvttph_epu32(_mm512_undefined_epi32(), 0xffff, a) } @@ -15155,7 +15155,7 @@ pub fn _mm512_cvttph_epu32(a: __m256h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvttph_epu32(src: __m512i, k: __mmask16, a: __m256h) -> __m512i { unsafe { transmute(vcvttph2udq_512( @@ -15174,7 +15174,7 @@ pub fn _mm512_mask_cvttph_epu32(src: __m512i, k: __mmask16, a: __m256h) -> __m51 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2udq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvttph_epu32(k: __mmask16, a: __m256h) -> __m512i { _mm512_mask_cvttph_epu32(_mm512_setzero_si512(), k, a) } @@ -15189,7 +15189,7 @@ pub fn _mm512_maskz_cvttph_epu32(k: __mmask16, a: __m256h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2udq, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtt_roundph_epu32(a: __m256h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epu32::(_mm512_undefined_epi32(), 0xffff, a) @@ -15205,7 +15205,7 @@ pub fn _mm512_cvtt_roundph_epu32(a: __m256h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2udq, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtt_roundph_epu32( src: __m512i, k: __mmask16, @@ -15227,7 +15227,7 @@ pub fn _mm512_mask_cvtt_roundph_epu32( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2udq, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtt_roundph_epu32(k: __mmask16, a: __m256h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epu32::(_mm512_setzero_si512(), k, a) @@ -15240,7 +15240,7 @@ pub fn _mm512_maskz_cvtt_roundph_epu32(k: __mmask16, a: __m256h) #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttsh2usi))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttsh_u32(a: __m128h) -> u32 { unsafe { vcvttsh2usi32(a, _MM_FROUND_CUR_DIRECTION) } } @@ -15255,7 +15255,7 @@ pub fn _mm_cvttsh_u32(a: __m128h) -> u32 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttsh2usi, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtt_roundsh_u32(a: __m128h) -> u32 { unsafe { static_assert_sae!(SAE); @@ -15270,7 +15270,7 @@ pub fn _mm_cvtt_roundsh_u32(a: __m128h) -> u32 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtph_epi64(a: __m128h) -> __m128i { _mm_mask_cvtph_epi64(_mm_undefined_si128(), 0xff, a) } @@ -15282,7 +15282,7 @@ pub fn _mm_cvtph_epi64(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtph_epi64(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvtph2qq_128(a, src.as_i64x2(), k)) } } @@ -15294,7 +15294,7 @@ pub fn _mm_mask_cvtph_epi64(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtph_epi64(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvtph_epi64(_mm_setzero_si128(), k, a) } @@ -15306,7 +15306,7 @@ pub fn _mm_maskz_cvtph_epi64(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtph_epi64(a: __m128h) -> __m256i { _mm256_mask_cvtph_epi64(_mm256_undefined_si256(), 0xff, a) } @@ -15318,7 +15318,7 @@ pub fn _mm256_cvtph_epi64(a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtph_epi64(src: __m256i, k: __mmask8, a: __m128h) -> __m256i { unsafe { transmute(vcvtph2qq_256(a, src.as_i64x4(), k)) } } @@ -15330,7 +15330,7 @@ pub fn _mm256_mask_cvtph_epi64(src: __m256i, k: __mmask8, a: __m128h) -> __m256i #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtph_epi64(k: __mmask8, a: __m128h) -> __m256i { _mm256_mask_cvtph_epi64(_mm256_setzero_si256(), k, a) } @@ -15342,7 +15342,7 @@ pub fn _mm256_maskz_cvtph_epi64(k: __mmask8, a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtph_epi64(a: __m128h) -> __m512i { _mm512_mask_cvtph_epi64(_mm512_undefined_epi32(), 0xff, a) } @@ -15354,7 +15354,7 @@ pub fn _mm512_cvtph_epi64(a: __m128h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtph_epi64(src: __m512i, k: __mmask8, a: __m128h) -> __m512i { unsafe { transmute(vcvtph2qq_512( @@ -15373,7 +15373,7 @@ pub fn _mm512_mask_cvtph_epi64(src: __m512i, k: __mmask8, a: __m128h) -> __m512i #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtph_epi64(k: __mmask8, a: __m128h) -> __m512i { _mm512_mask_cvtph_epi64(_mm512_setzero_si512(), k, a) } @@ -15394,7 +15394,7 @@ pub fn _mm512_maskz_cvtph_epi64(k: __mmask8, a: __m128h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2qq, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundph_epi64(a: __m128h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epi64::(_mm512_undefined_epi32(), 0xff, a) @@ -15416,7 +15416,7 @@ pub fn _mm512_cvt_roundph_epi64(a: __m128h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2qq, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundph_epi64( src: __m512i, k: __mmask8, @@ -15444,7 +15444,7 @@ pub fn _mm512_mask_cvt_roundph_epi64( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2qq, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundph_epi64(k: __mmask8, a: __m128h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epi64::(_mm512_setzero_si512(), k, a) @@ -15457,7 +15457,7 @@ pub fn _mm512_maskz_cvt_roundph_epi64(k: __mmask8, a: __m12 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtph_epu64(a: __m128h) -> __m128i { _mm_mask_cvtph_epu64(_mm_undefined_si128(), 0xff, a) } @@ -15469,7 +15469,7 @@ pub fn _mm_cvtph_epu64(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtph_epu64(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvtph2uqq_128(a, src.as_u64x2(), k)) } } @@ -15481,7 +15481,7 @@ pub fn _mm_mask_cvtph_epu64(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtph_epu64(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvtph_epu64(_mm_setzero_si128(), k, a) } @@ -15493,7 +15493,7 @@ pub fn _mm_maskz_cvtph_epu64(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtph_epu64(a: __m128h) -> __m256i { _mm256_mask_cvtph_epu64(_mm256_undefined_si256(), 0xff, a) } @@ -15505,7 +15505,7 @@ pub fn _mm256_cvtph_epu64(a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtph_epu64(src: __m256i, k: __mmask8, a: __m128h) -> __m256i { unsafe { transmute(vcvtph2uqq_256(a, src.as_u64x4(), k)) } } @@ -15517,7 +15517,7 @@ pub fn _mm256_mask_cvtph_epu64(src: __m256i, k: __mmask8, a: __m128h) -> __m256i #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtph_epu64(k: __mmask8, a: __m128h) -> __m256i { _mm256_mask_cvtph_epu64(_mm256_setzero_si256(), k, a) } @@ -15529,7 +15529,7 @@ pub fn _mm256_maskz_cvtph_epu64(k: __mmask8, a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtph_epu64(a: __m128h) -> __m512i { _mm512_mask_cvtph_epu64(_mm512_undefined_epi32(), 0xff, a) } @@ -15541,7 +15541,7 @@ pub fn _mm512_cvtph_epu64(a: __m128h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtph_epu64(src: __m512i, k: __mmask8, a: __m128h) -> __m512i { unsafe { transmute(vcvtph2uqq_512( @@ -15560,7 +15560,7 @@ pub fn _mm512_mask_cvtph_epu64(src: __m512i, k: __mmask8, a: __m128h) -> __m512i #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtph_epu64(k: __mmask8, a: __m128h) -> __m512i { _mm512_mask_cvtph_epu64(_mm512_setzero_si512(), k, a) } @@ -15581,7 +15581,7 @@ pub fn _mm512_maskz_cvtph_epu64(k: __mmask8, a: __m128h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uqq, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundph_epu64(a: __m128h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epu64::(_mm512_undefined_epi32(), 0xff, a) @@ -15603,7 +15603,7 @@ pub fn _mm512_cvt_roundph_epu64(a: __m128h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uqq, ROUNDING = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundph_epu64( src: __m512i, k: __mmask8, @@ -15631,7 +15631,7 @@ pub fn _mm512_mask_cvt_roundph_epu64( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2uqq, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundph_epu64(k: __mmask8, a: __m128h) -> __m512i { static_assert_rounding!(ROUNDING); _mm512_mask_cvt_roundph_epu64::(_mm512_setzero_si512(), k, a) @@ -15644,7 +15644,7 @@ pub fn _mm512_maskz_cvt_roundph_epu64(k: __mmask8, a: __m12 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttph_epi64(a: __m128h) -> __m128i { _mm_mask_cvttph_epi64(_mm_undefined_si128(), 0xff, a) } @@ -15656,7 +15656,7 @@ pub fn _mm_cvttph_epi64(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvttph_epi64(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvttph2qq_128(a, src.as_i64x2(), k)) } } @@ -15668,7 +15668,7 @@ pub fn _mm_mask_cvttph_epi64(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvttph_epi64(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvttph_epi64(_mm_setzero_si128(), k, a) } @@ -15680,7 +15680,7 @@ pub fn _mm_maskz_cvttph_epi64(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvttph_epi64(a: __m128h) -> __m256i { _mm256_mask_cvttph_epi64(_mm256_undefined_si256(), 0xff, a) } @@ -15692,7 +15692,7 @@ pub fn _mm256_cvttph_epi64(a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvttph_epi64(src: __m256i, k: __mmask8, a: __m128h) -> __m256i { unsafe { transmute(vcvttph2qq_256(a, src.as_i64x4(), k)) } } @@ -15704,7 +15704,7 @@ pub fn _mm256_mask_cvttph_epi64(src: __m256i, k: __mmask8, a: __m128h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvttph_epi64(k: __mmask8, a: __m128h) -> __m256i { _mm256_mask_cvttph_epi64(_mm256_setzero_si256(), k, a) } @@ -15716,7 +15716,7 @@ pub fn _mm256_maskz_cvttph_epi64(k: __mmask8, a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvttph_epi64(a: __m128h) -> __m512i { _mm512_mask_cvttph_epi64(_mm512_undefined_epi32(), 0xff, a) } @@ -15728,7 +15728,7 @@ pub fn _mm512_cvttph_epi64(a: __m128h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvttph_epi64(src: __m512i, k: __mmask8, a: __m128h) -> __m512i { unsafe { transmute(vcvttph2qq_512( @@ -15747,7 +15747,7 @@ pub fn _mm512_mask_cvttph_epi64(src: __m512i, k: __mmask8, a: __m128h) -> __m512 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2qq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvttph_epi64(k: __mmask8, a: __m128h) -> __m512i { _mm512_mask_cvttph_epi64(_mm512_setzero_si512(), k, a) } @@ -15762,7 +15762,7 @@ pub fn _mm512_maskz_cvttph_epi64(k: __mmask8, a: __m128h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2qq, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtt_roundph_epi64(a: __m128h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epi64::(_mm512_undefined_epi32(), 0xff, a) @@ -15778,7 +15778,7 @@ pub fn _mm512_cvtt_roundph_epi64(a: __m128h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2qq, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtt_roundph_epi64( src: __m512i, k: __mmask8, @@ -15800,7 +15800,7 @@ pub fn _mm512_mask_cvtt_roundph_epi64( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2qq, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtt_roundph_epi64(k: __mmask8, a: __m128h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epi64::(_mm512_setzero_si512(), k, a) @@ -15813,7 +15813,7 @@ pub fn _mm512_maskz_cvtt_roundph_epi64(k: __mmask8, a: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttph_epu64(a: __m128h) -> __m128i { _mm_mask_cvttph_epu64(_mm_undefined_si128(), 0xff, a) } @@ -15825,7 +15825,7 @@ pub fn _mm_cvttph_epu64(a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvttph_epu64(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { unsafe { transmute(vcvttph2uqq_128(a, src.as_u64x2(), k)) } } @@ -15837,7 +15837,7 @@ pub fn _mm_mask_cvttph_epu64(src: __m128i, k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvttph_epu64(k: __mmask8, a: __m128h) -> __m128i { _mm_mask_cvttph_epu64(_mm_setzero_si128(), k, a) } @@ -15849,7 +15849,7 @@ pub fn _mm_maskz_cvttph_epu64(k: __mmask8, a: __m128h) -> __m128i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvttph_epu64(a: __m128h) -> __m256i { _mm256_mask_cvttph_epu64(_mm256_undefined_si256(), 0xff, a) } @@ -15861,7 +15861,7 @@ pub fn _mm256_cvttph_epu64(a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvttph_epu64(src: __m256i, k: __mmask8, a: __m128h) -> __m256i { unsafe { transmute(vcvttph2uqq_256(a, src.as_u64x4(), k)) } } @@ -15873,7 +15873,7 @@ pub fn _mm256_mask_cvttph_epu64(src: __m256i, k: __mmask8, a: __m128h) -> __m256 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvttph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvttph_epu64(k: __mmask8, a: __m128h) -> __m256i { _mm256_mask_cvttph_epu64(_mm256_setzero_si256(), k, a) } @@ -15885,7 +15885,7 @@ pub fn _mm256_maskz_cvttph_epu64(k: __mmask8, a: __m128h) -> __m256i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvttph_epu64(a: __m128h) -> __m512i { _mm512_mask_cvttph_epu64(_mm512_undefined_epi32(), 0xff, a) } @@ -15897,7 +15897,7 @@ pub fn _mm512_cvttph_epu64(a: __m128h) -> __m512i { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvttph_epu64(src: __m512i, k: __mmask8, a: __m128h) -> __m512i { unsafe { transmute(vcvttph2uqq_512( @@ -15916,7 +15916,7 @@ pub fn _mm512_mask_cvttph_epu64(src: __m512i, k: __mmask8, a: __m128h) -> __m512 #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uqq))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvttph_epu64(k: __mmask8, a: __m128h) -> __m512i { _mm512_mask_cvttph_epu64(_mm512_setzero_si512(), k, a) } @@ -15931,7 +15931,7 @@ pub fn _mm512_maskz_cvttph_epu64(k: __mmask8, a: __m128h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uqq, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtt_roundph_epu64(a: __m128h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epu64::(_mm512_undefined_epi32(), 0xff, a) @@ -15947,7 +15947,7 @@ pub fn _mm512_cvtt_roundph_epu64(a: __m128h) -> __m512i { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uqq, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtt_roundph_epu64( src: __m512i, k: __mmask8, @@ -15969,7 +15969,7 @@ pub fn _mm512_mask_cvtt_roundph_epu64( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttph2uqq, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtt_roundph_epu64(k: __mmask8, a: __m128h) -> __m512i { static_assert_sae!(SAE); _mm512_mask_cvtt_roundph_epu64::(_mm512_setzero_si512(), k, a) @@ -15982,7 +15982,7 @@ pub fn _mm512_maskz_cvtt_roundph_epu64(k: __mmask8, a: __m128h) #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2psx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtxph_ps(a: __m128h) -> __m128 { _mm_mask_cvtxph_ps(_mm_setzero_ps(), 0xff, a) } @@ -15995,7 +15995,7 @@ pub fn _mm_cvtxph_ps(a: __m128h) -> __m128 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2psx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtxph_ps(src: __m128, k: __mmask8, a: __m128h) -> __m128 { unsafe { vcvtph2psx_128(a, src, k) } } @@ -16008,7 +16008,7 @@ pub fn _mm_mask_cvtxph_ps(src: __m128, k: __mmask8, a: __m128h) -> __m128 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2psx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtxph_ps(k: __mmask8, a: __m128h) -> __m128 { _mm_mask_cvtxph_ps(_mm_setzero_ps(), k, a) } @@ -16020,7 +16020,7 @@ pub fn _mm_maskz_cvtxph_ps(k: __mmask8, a: __m128h) -> __m128 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2psx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtxph_ps(a: __m128h) -> __m256 { _mm256_mask_cvtxph_ps(_mm256_setzero_ps(), 0xff, a) } @@ -16033,7 +16033,7 @@ pub fn _mm256_cvtxph_ps(a: __m128h) -> __m256 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2psx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtxph_ps(src: __m256, k: __mmask8, a: __m128h) -> __m256 { unsafe { vcvtph2psx_256(a, src, k) } } @@ -16046,7 +16046,7 @@ pub fn _mm256_mask_cvtxph_ps(src: __m256, k: __mmask8, a: __m128h) -> __m256 { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2psx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtxph_ps(k: __mmask8, a: __m128h) -> __m256 { _mm256_mask_cvtxph_ps(_mm256_setzero_ps(), k, a) } @@ -16058,7 +16058,7 @@ pub fn _mm256_maskz_cvtxph_ps(k: __mmask8, a: __m128h) -> __m256 { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2psx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtxph_ps(a: __m256h) -> __m512 { _mm512_mask_cvtxph_ps(_mm512_setzero_ps(), 0xffff, a) } @@ -16071,7 +16071,7 @@ pub fn _mm512_cvtxph_ps(a: __m256h) -> __m512 { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2psx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtxph_ps(src: __m512, k: __mmask16, a: __m256h) -> __m512 { unsafe { vcvtph2psx_512(a, src, k, _MM_FROUND_CUR_DIRECTION) } } @@ -16084,7 +16084,7 @@ pub fn _mm512_mask_cvtxph_ps(src: __m512, k: __mmask16, a: __m256h) -> __m512 { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2psx))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtxph_ps(k: __mmask16, a: __m256h) -> __m512 { _mm512_mask_cvtxph_ps(_mm512_setzero_ps(), k, a) } @@ -16099,7 +16099,7 @@ pub fn _mm512_maskz_cvtxph_ps(k: __mmask16, a: __m256h) -> __m512 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2psx, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtx_roundph_ps(a: __m256h) -> __m512 { static_assert_sae!(SAE); _mm512_mask_cvtx_roundph_ps::(_mm512_setzero_ps(), 0xffff, a) @@ -16116,7 +16116,7 @@ pub fn _mm512_cvtx_roundph_ps(a: __m256h) -> __m512 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2psx, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtx_roundph_ps( src: __m512, k: __mmask16, @@ -16139,7 +16139,7 @@ pub fn _mm512_mask_cvtx_roundph_ps( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2psx, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtx_roundph_ps(k: __mmask16, a: __m256h) -> __m512 { static_assert_sae!(SAE); _mm512_mask_cvtx_roundph_ps::(_mm512_setzero_ps(), k, a) @@ -16153,7 +16153,7 @@ pub fn _mm512_maskz_cvtx_roundph_ps(k: __mmask16, a: __m256h) -> #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2ss))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtsh_ss(a: __m128, b: __m128h) -> __m128 { _mm_mask_cvtsh_ss(a, 0xff, a, b) } @@ -16167,7 +16167,7 @@ pub fn _mm_cvtsh_ss(a: __m128, b: __m128h) -> __m128 { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2ss))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtsh_ss(src: __m128, k: __mmask8, a: __m128, b: __m128h) -> __m128 { unsafe { vcvtsh2ss(a, b, src, k, _MM_FROUND_CUR_DIRECTION) } } @@ -16181,7 +16181,7 @@ pub fn _mm_mask_cvtsh_ss(src: __m128, k: __mmask8, a: __m128, b: __m128h) -> __m #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2ss))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtsh_ss(k: __mmask8, a: __m128, b: __m128h) -> __m128 { _mm_mask_cvtsh_ss(_mm_set_ss(0.0), k, a, b) } @@ -16197,7 +16197,7 @@ pub fn _mm_maskz_cvtsh_ss(k: __mmask8, a: __m128, b: __m128h) -> __m128 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2ss, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundsh_ss(a: __m128, b: __m128h) -> __m128 { static_assert_sae!(SAE); _mm_mask_cvt_roundsh_ss::(_mm_undefined_ps(), 0xff, a, b) @@ -16215,7 +16215,7 @@ pub fn _mm_cvt_roundsh_ss(a: __m128, b: __m128h) -> __m128 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2ss, SAE = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvt_roundsh_ss( src: __m128, k: __mmask8, @@ -16240,7 +16240,7 @@ pub fn _mm_mask_cvt_roundsh_ss( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2ss, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvt_roundsh_ss(k: __mmask8, a: __m128, b: __m128h) -> __m128 { static_assert_sae!(SAE); _mm_mask_cvt_roundsh_ss::(_mm_set_ss(0.0), k, a, b) @@ -16253,7 +16253,7 @@ pub fn _mm_maskz_cvt_roundsh_ss(k: __mmask8, a: __m128, b: __m12 #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2pd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtph_pd(a: __m128h) -> __m128d { _mm_mask_cvtph_pd(_mm_setzero_pd(), 0xff, a) } @@ -16266,7 +16266,7 @@ pub fn _mm_cvtph_pd(a: __m128h) -> __m128d { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2pd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtph_pd(src: __m128d, k: __mmask8, a: __m128h) -> __m128d { unsafe { vcvtph2pd_128(a, src, k) } } @@ -16279,7 +16279,7 @@ pub fn _mm_mask_cvtph_pd(src: __m128d, k: __mmask8, a: __m128h) -> __m128d { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2pd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtph_pd(k: __mmask8, a: __m128h) -> __m128d { _mm_mask_cvtph_pd(_mm_setzero_pd(), k, a) } @@ -16291,7 +16291,7 @@ pub fn _mm_maskz_cvtph_pd(k: __mmask8, a: __m128h) -> __m128d { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2pd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_cvtph_pd(a: __m128h) -> __m256d { _mm256_mask_cvtph_pd(_mm256_setzero_pd(), 0xff, a) } @@ -16304,7 +16304,7 @@ pub fn _mm256_cvtph_pd(a: __m128h) -> __m256d { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2pd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_mask_cvtph_pd(src: __m256d, k: __mmask8, a: __m128h) -> __m256d { unsafe { vcvtph2pd_256(a, src, k) } } @@ -16317,7 +16317,7 @@ pub fn _mm256_mask_cvtph_pd(src: __m256d, k: __mmask8, a: __m128h) -> __m256d { #[inline] #[target_feature(enable = "avx512fp16,avx512vl")] #[cfg_attr(test, assert_instr(vcvtph2pd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm256_maskz_cvtph_pd(k: __mmask8, a: __m128h) -> __m256d { _mm256_mask_cvtph_pd(_mm256_setzero_pd(), k, a) } @@ -16329,7 +16329,7 @@ pub fn _mm256_maskz_cvtph_pd(k: __mmask8, a: __m128h) -> __m256d { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2pd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvtph_pd(a: __m128h) -> __m512d { _mm512_mask_cvtph_pd(_mm512_setzero_pd(), 0xff, a) } @@ -16342,7 +16342,7 @@ pub fn _mm512_cvtph_pd(a: __m128h) -> __m512d { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2pd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvtph_pd(src: __m512d, k: __mmask8, a: __m128h) -> __m512d { unsafe { vcvtph2pd_512(a, src, k, _MM_FROUND_CUR_DIRECTION) } } @@ -16355,7 +16355,7 @@ pub fn _mm512_mask_cvtph_pd(src: __m512d, k: __mmask8, a: __m128h) -> __m512d { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2pd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvtph_pd(k: __mmask8, a: __m128h) -> __m512d { _mm512_mask_cvtph_pd(_mm512_setzero_pd(), k, a) } @@ -16370,7 +16370,7 @@ pub fn _mm512_maskz_cvtph_pd(k: __mmask8, a: __m128h) -> __m512d { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2pd, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_cvt_roundph_pd(a: __m128h) -> __m512d { static_assert_sae!(SAE); _mm512_mask_cvt_roundph_pd::(_mm512_setzero_pd(), 0xff, a) @@ -16387,7 +16387,7 @@ pub fn _mm512_cvt_roundph_pd(a: __m128h) -> __m512d { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2pd, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_mask_cvt_roundph_pd( src: __m512d, k: __mmask8, @@ -16410,7 +16410,7 @@ pub fn _mm512_mask_cvt_roundph_pd( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtph2pd, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm512_maskz_cvt_roundph_pd(k: __mmask8, a: __m128h) -> __m512d { static_assert_sae!(SAE); _mm512_mask_cvt_roundph_pd::(_mm512_setzero_pd(), k, a) @@ -16424,7 +16424,7 @@ pub fn _mm512_maskz_cvt_roundph_pd(k: __mmask8, a: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2sd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtsh_sd(a: __m128d, b: __m128h) -> __m128d { _mm_mask_cvtsh_sd(a, 0xff, a, b) } @@ -16438,7 +16438,7 @@ pub fn _mm_cvtsh_sd(a: __m128d, b: __m128h) -> __m128d { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2sd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvtsh_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128h) -> __m128d { unsafe { vcvtsh2sd(a, b, src, k, _MM_FROUND_CUR_DIRECTION) } } @@ -16451,7 +16451,7 @@ pub fn _mm_mask_cvtsh_sd(src: __m128d, k: __mmask8, a: __m128d, b: __m128h) -> _ #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2sd))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvtsh_sd(k: __mmask8, a: __m128d, b: __m128h) -> __m128d { _mm_mask_cvtsh_sd(_mm_set_sd(0.0), k, a, b) } @@ -16467,7 +16467,7 @@ pub fn _mm_maskz_cvtsh_sd(k: __mmask8, a: __m128d, b: __m128h) -> __m128d { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2sd, SAE = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundsh_sd(a: __m128d, b: __m128h) -> __m128d { static_assert_sae!(SAE); _mm_mask_cvt_roundsh_sd::(a, 0xff, a, b) @@ -16485,7 +16485,7 @@ pub fn _mm_cvt_roundsh_sd(a: __m128d, b: __m128h) -> __m128d { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2sd, SAE = 8))] #[rustc_legacy_const_generics(4)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_mask_cvt_roundsh_sd( src: __m128d, k: __mmask8, @@ -16509,7 +16509,7 @@ pub fn _mm_mask_cvt_roundsh_sd( #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2sd, SAE = 8))] #[rustc_legacy_const_generics(3)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_maskz_cvt_roundsh_sd(k: __mmask8, a: __m128d, b: __m128h) -> __m128d { static_assert_sae!(SAE); _mm_mask_cvt_roundsh_sd::(_mm_set_sd(0.0), k, a, b) @@ -16553,7 +16553,7 @@ pub const fn _mm512_cvtsh_h(a: __m512h) -> f16 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si16) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_cvtsi128_si16(a: __m128i) -> i16 { unsafe { simd_extract!(a.as_i16x8(), 0) } @@ -16564,7 +16564,7 @@ pub const fn _mm_cvtsi128_si16(a: __m128i) -> i16 { /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi16_si128) #[inline] #[target_feature(enable = "avx512fp16")] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] pub const fn _mm_cvtsi16_si128(a: i16) -> __m128i { unsafe { transmute(simd_insert!(i16x8::ZERO, 0, a)) } diff --git a/library/stdarch/crates/core_arch/src/x86/avxneconvert.rs b/library/stdarch/crates/core_arch/src/x86/avxneconvert.rs index b92ec823ec64..a53d6d97e8a0 100644 --- a/library/stdarch/crates/core_arch/src/x86/avxneconvert.rs +++ b/library/stdarch/crates/core_arch/src/x86/avxneconvert.rs @@ -87,7 +87,7 @@ pub unsafe fn _mm256_cvtneebf16_ps(a: *const __m256bh) -> __m256 { #[inline] #[target_feature(enable = "avxneconvert")] #[cfg_attr(test, assert_instr(vcvtneeph2ps))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub unsafe fn _mm_cvtneeph_ps(a: *const __m128h) -> __m128 { transmute(cvtneeph2ps_128(a)) } @@ -99,7 +99,7 @@ pub unsafe fn _mm_cvtneeph_ps(a: *const __m128h) -> __m128 { #[inline] #[target_feature(enable = "avxneconvert")] #[cfg_attr(test, assert_instr(vcvtneeph2ps))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub unsafe fn _mm256_cvtneeph_ps(a: *const __m256h) -> __m256 { transmute(cvtneeph2ps_256(a)) } @@ -135,7 +135,7 @@ pub unsafe fn _mm256_cvtneobf16_ps(a: *const __m256bh) -> __m256 { #[inline] #[target_feature(enable = "avxneconvert")] #[cfg_attr(test, assert_instr(vcvtneoph2ps))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub unsafe fn _mm_cvtneoph_ps(a: *const __m128h) -> __m128 { transmute(cvtneoph2ps_128(a)) } @@ -147,7 +147,7 @@ pub unsafe fn _mm_cvtneoph_ps(a: *const __m128h) -> __m128 { #[inline] #[target_feature(enable = "avxneconvert")] #[cfg_attr(test, assert_instr(vcvtneoph2ps))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub unsafe fn _mm256_cvtneoph_ps(a: *const __m256h) -> __m256 { transmute(cvtneoph2ps_256(a)) } diff --git a/library/stdarch/crates/core_arch/src/x86/mod.rs b/library/stdarch/crates/core_arch/src/x86/mod.rs index 7612cffd078a..c40fbd3ca317 100644 --- a/library/stdarch/crates/core_arch/src/x86/mod.rs +++ b/library/stdarch/crates/core_arch/src/x86/mod.rs @@ -401,7 +401,7 @@ types! { } types! { - #![unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] + #![stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] /// 128-bit wide set of 8 `f16` types, x86-specific /// @@ -768,7 +768,7 @@ mod avxneconvert; pub use self::avxneconvert::*; mod avx512fp16; -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub use self::avx512fp16::*; mod kl; diff --git a/library/stdarch/crates/core_arch/src/x86_64/avx512fp16.rs b/library/stdarch/crates/core_arch/src/x86_64/avx512fp16.rs index 955c6ccc7526..d0123f22d727 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/avx512fp16.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/avx512fp16.rs @@ -10,7 +10,7 @@ use stdarch_test::assert_instr; #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsi2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvti64_sh(a: __m128h, b: i64) -> __m128h { unsafe { vcvtsi642sh(a, b, _MM_FROUND_CUR_DIRECTION) } } @@ -32,7 +32,7 @@ pub fn _mm_cvti64_sh(a: __m128h, b: i64) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsi2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundi64_sh(a: __m128h, b: i64) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -48,7 +48,7 @@ pub fn _mm_cvt_roundi64_sh(a: __m128h, b: i64) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtusi2sh))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtu64_sh(a: __m128h, b: u64) -> __m128h { unsafe { vcvtusi642sh(a, b, _MM_FROUND_CUR_DIRECTION) } } @@ -70,7 +70,7 @@ pub fn _mm_cvtu64_sh(a: __m128h, b: u64) -> __m128h { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtusi2sh, ROUNDING = 8))] #[rustc_legacy_const_generics(2)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundu64_sh(a: __m128h, b: u64) -> __m128h { unsafe { static_assert_rounding!(ROUNDING); @@ -85,7 +85,7 @@ pub fn _mm_cvt_roundu64_sh(a: __m128h, b: u64) -> __m128h { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2si))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtsh_i64(a: __m128h) -> i64 { unsafe { vcvtsh2si64(a, _MM_FROUND_CUR_DIRECTION) } } @@ -106,7 +106,7 @@ pub fn _mm_cvtsh_i64(a: __m128h) -> i64 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2si, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundsh_i64(a: __m128h) -> i64 { unsafe { static_assert_rounding!(ROUNDING); @@ -121,7 +121,7 @@ pub fn _mm_cvt_roundsh_i64(a: __m128h) -> i64 { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2usi))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtsh_u64(a: __m128h) -> u64 { unsafe { vcvtsh2usi64(a, _MM_FROUND_CUR_DIRECTION) } } @@ -142,7 +142,7 @@ pub fn _mm_cvtsh_u64(a: __m128h) -> u64 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvtsh2usi, ROUNDING = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvt_roundsh_u64(a: __m128h) -> u64 { unsafe { static_assert_rounding!(ROUNDING); @@ -157,7 +157,7 @@ pub fn _mm_cvt_roundsh_u64(a: __m128h) -> u64 { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttsh2si))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttsh_i64(a: __m128h) -> i64 { unsafe { vcvttsh2si64(a, _MM_FROUND_CUR_DIRECTION) } } @@ -172,7 +172,7 @@ pub fn _mm_cvttsh_i64(a: __m128h) -> i64 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttsh2si, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtt_roundsh_i64(a: __m128h) -> i64 { unsafe { static_assert_sae!(SAE); @@ -187,7 +187,7 @@ pub fn _mm_cvtt_roundsh_i64(a: __m128h) -> i64 { #[inline] #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttsh2usi))] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvttsh_u64(a: __m128h) -> u64 { unsafe { vcvttsh2usi64(a, _MM_FROUND_CUR_DIRECTION) } } @@ -202,7 +202,7 @@ pub fn _mm_cvttsh_u64(a: __m128h) -> u64 { #[target_feature(enable = "avx512fp16")] #[cfg_attr(test, assert_instr(vcvttsh2usi, SAE = 8))] #[rustc_legacy_const_generics(1)] -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub fn _mm_cvtt_roundsh_u64(a: __m128h) -> u64 { unsafe { static_assert_sae!(SAE); diff --git a/library/stdarch/crates/core_arch/src/x86_64/mod.rs b/library/stdarch/crates/core_arch/src/x86_64/mod.rs index 7d681882bef0..c6dc7a85e785 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/mod.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/mod.rs @@ -75,7 +75,7 @@ mod bt; pub use self::bt::*; mod avx512fp16; -#[unstable(feature = "stdarch_x86_avx512_f16", issue = "127213")] +#[stable(feature = "stdarch_x86_avx512fp16", since = "CURRENT_RUSTC_VERSION")] pub use self::avx512fp16::*; mod amx; From 897099e693c52c90baa7f3c5897668b0577f69de Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Dec 2025 17:53:01 +0100 Subject: [PATCH 0293/3801] Regenerate intrinsics --- src/intrinsic/archs.rs | 123 +++++++++++++++++++++++++++++++++-------- 1 file changed, 99 insertions(+), 24 deletions(-) diff --git a/src/intrinsic/archs.rs b/src/intrinsic/archs.rs index bb8bcbf66f38..43e7c352c34a 100644 --- a/src/intrinsic/archs.rs +++ b/src/intrinsic/archs.rs @@ -70,10 +70,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sve.sm4e" => "__builtin_sve_svsm4e_u32", "sve.sm4ekey" => "__builtin_sve_svsm4ekey_u32", "sve.wrffr" => "__builtin_sve_svwrffr", - "tcancel" => "__builtin_arm_tcancel", - "tcommit" => "__builtin_arm_tcommit", - "tstart" => "__builtin_arm_tstart", - "ttest" => "__builtin_arm_ttest", _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), } } @@ -1632,6 +1628,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vabs.f8.128B" => "__builtin_HEXAGON_V6_vabs_f8_128B", "V6.vabs.hf" => "__builtin_HEXAGON_V6_vabs_hf", "V6.vabs.hf.128B" => "__builtin_HEXAGON_V6_vabs_hf_128B", + "V6.vabs.qf16.hf" => "__builtin_HEXAGON_V6_vabs_qf16_hf", + "V6.vabs.qf16.hf.128B" => "__builtin_HEXAGON_V6_vabs_qf16_hf_128B", + "V6.vabs.qf16.qf16" => "__builtin_HEXAGON_V6_vabs_qf16_qf16", + "V6.vabs.qf16.qf16.128B" => "__builtin_HEXAGON_V6_vabs_qf16_qf16_128B", + "V6.vabs.qf32.qf32" => "__builtin_HEXAGON_V6_vabs_qf32_qf32", + "V6.vabs.qf32.qf32.128B" => "__builtin_HEXAGON_V6_vabs_qf32_qf32_128B", + "V6.vabs.qf32.sf" => "__builtin_HEXAGON_V6_vabs_qf32_sf", + "V6.vabs.qf32.sf.128B" => "__builtin_HEXAGON_V6_vabs_qf32_sf_128B", "V6.vabs.sf" => "__builtin_HEXAGON_V6_vabs_sf", "V6.vabs.sf.128B" => "__builtin_HEXAGON_V6_vabs_sf_128B", "V6.vabsb" => "__builtin_HEXAGON_V6_vabsb", @@ -1744,6 +1748,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vaddwsat.128B" => "__builtin_HEXAGON_V6_vaddwsat_128B", "V6.vaddwsat.dv" => "__builtin_HEXAGON_V6_vaddwsat_dv", "V6.vaddwsat.dv.128B" => "__builtin_HEXAGON_V6_vaddwsat_dv_128B", + "V6.valign4" => "__builtin_HEXAGON_V6_valign4", + "V6.valign4.128B" => "__builtin_HEXAGON_V6_valign4_128B", "V6.valignb" => "__builtin_HEXAGON_V6_valignb", "V6.valignb.128B" => "__builtin_HEXAGON_V6_valignb_128B", "V6.valignbi" => "__builtin_HEXAGON_V6_valignbi", @@ -1862,14 +1868,30 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vcl0w.128B" => "__builtin_HEXAGON_V6_vcl0w_128B", "V6.vcombine" => "__builtin_HEXAGON_V6_vcombine", "V6.vcombine.128B" => "__builtin_HEXAGON_V6_vcombine_128B", + "V6.vconv.bf.qf32" => "__builtin_HEXAGON_V6_vconv_bf_qf32", + "V6.vconv.bf.qf32.128B" => "__builtin_HEXAGON_V6_vconv_bf_qf32_128B", + "V6.vconv.f8.qf16" => "__builtin_HEXAGON_V6_vconv_f8_qf16", + "V6.vconv.f8.qf16.128B" => "__builtin_HEXAGON_V6_vconv_f8_qf16_128B", "V6.vconv.h.hf" => "__builtin_HEXAGON_V6_vconv_h_hf", "V6.vconv.h.hf.128B" => "__builtin_HEXAGON_V6_vconv_h_hf_128B", + "V6.vconv.h.hf.rnd" => "__builtin_HEXAGON_V6_vconv_h_hf_rnd", + "V6.vconv.h.hf.rnd.128B" => "__builtin_HEXAGON_V6_vconv_h_hf_rnd_128B", "V6.vconv.hf.h" => "__builtin_HEXAGON_V6_vconv_hf_h", "V6.vconv.hf.h.128B" => "__builtin_HEXAGON_V6_vconv_hf_h_128B", "V6.vconv.hf.qf16" => "__builtin_HEXAGON_V6_vconv_hf_qf16", "V6.vconv.hf.qf16.128B" => "__builtin_HEXAGON_V6_vconv_hf_qf16_128B", "V6.vconv.hf.qf32" => "__builtin_HEXAGON_V6_vconv_hf_qf32", "V6.vconv.hf.qf32.128B" => "__builtin_HEXAGON_V6_vconv_hf_qf32_128B", + "V6.vconv.qf16.f8" => "__builtin_HEXAGON_V6_vconv_qf16_f8", + "V6.vconv.qf16.f8.128B" => "__builtin_HEXAGON_V6_vconv_qf16_f8_128B", + "V6.vconv.qf16.hf" => "__builtin_HEXAGON_V6_vconv_qf16_hf", + "V6.vconv.qf16.hf.128B" => "__builtin_HEXAGON_V6_vconv_qf16_hf_128B", + "V6.vconv.qf16.qf16" => "__builtin_HEXAGON_V6_vconv_qf16_qf16", + "V6.vconv.qf16.qf16.128B" => "__builtin_HEXAGON_V6_vconv_qf16_qf16_128B", + "V6.vconv.qf32.qf32" => "__builtin_HEXAGON_V6_vconv_qf32_qf32", + "V6.vconv.qf32.qf32.128B" => "__builtin_HEXAGON_V6_vconv_qf32_qf32_128B", + "V6.vconv.qf32.sf" => "__builtin_HEXAGON_V6_vconv_qf32_sf", + "V6.vconv.qf32.sf.128B" => "__builtin_HEXAGON_V6_vconv_qf32_sf_128B", "V6.vconv.sf.qf32" => "__builtin_HEXAGON_V6_vconv_sf_qf32", "V6.vconv.sf.qf32.128B" => "__builtin_HEXAGON_V6_vconv_sf_qf32_128B", "V6.vconv.sf.w" => "__builtin_HEXAGON_V6_vconv_sf_w", @@ -1984,6 +2006,22 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.veqh.or.128B" => "__builtin_HEXAGON_V6_veqh_or_128B", "V6.veqh.xor" => "__builtin_HEXAGON_V6_veqh_xor", "V6.veqh.xor.128B" => "__builtin_HEXAGON_V6_veqh_xor_128B", + "V6.veqhf" => "__builtin_HEXAGON_V6_veqhf", + "V6.veqhf.128B" => "__builtin_HEXAGON_V6_veqhf_128B", + "V6.veqhf.and" => "__builtin_HEXAGON_V6_veqhf_and", + "V6.veqhf.and.128B" => "__builtin_HEXAGON_V6_veqhf_and_128B", + "V6.veqhf.or" => "__builtin_HEXAGON_V6_veqhf_or", + "V6.veqhf.or.128B" => "__builtin_HEXAGON_V6_veqhf_or_128B", + "V6.veqhf.xor" => "__builtin_HEXAGON_V6_veqhf_xor", + "V6.veqhf.xor.128B" => "__builtin_HEXAGON_V6_veqhf_xor_128B", + "V6.veqsf" => "__builtin_HEXAGON_V6_veqsf", + "V6.veqsf.128B" => "__builtin_HEXAGON_V6_veqsf_128B", + "V6.veqsf.and" => "__builtin_HEXAGON_V6_veqsf_and", + "V6.veqsf.and.128B" => "__builtin_HEXAGON_V6_veqsf_and_128B", + "V6.veqsf.or" => "__builtin_HEXAGON_V6_veqsf_or", + "V6.veqsf.or.128B" => "__builtin_HEXAGON_V6_veqsf_or_128B", + "V6.veqsf.xor" => "__builtin_HEXAGON_V6_veqsf_xor", + "V6.veqsf.xor.128B" => "__builtin_HEXAGON_V6_veqsf_xor_128B", "V6.veqw" => "__builtin_HEXAGON_V6_veqw", "V6.veqw.128B" => "__builtin_HEXAGON_V6_veqw_128B", "V6.veqw.and" => "__builtin_HEXAGON_V6_veqw_and", @@ -2096,6 +2134,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vgtw.or.128B" => "__builtin_HEXAGON_V6_vgtw_or_128B", "V6.vgtw.xor" => "__builtin_HEXAGON_V6_vgtw_xor", "V6.vgtw.xor.128B" => "__builtin_HEXAGON_V6_vgtw_xor_128B", + "V6.vilog2.hf" => "__builtin_HEXAGON_V6_vilog2_hf", + "V6.vilog2.hf.128B" => "__builtin_HEXAGON_V6_vilog2_hf_128B", + "V6.vilog2.qf16" => "__builtin_HEXAGON_V6_vilog2_qf16", + "V6.vilog2.qf16.128B" => "__builtin_HEXAGON_V6_vilog2_qf16_128B", + "V6.vilog2.qf32" => "__builtin_HEXAGON_V6_vilog2_qf32", + "V6.vilog2.qf32.128B" => "__builtin_HEXAGON_V6_vilog2_qf32_128B", + "V6.vilog2.sf" => "__builtin_HEXAGON_V6_vilog2_sf", + "V6.vilog2.sf.128B" => "__builtin_HEXAGON_V6_vilog2_sf_128B", "V6.vinsertwr" => "__builtin_HEXAGON_V6_vinsertwr", "V6.vinsertwr.128B" => "__builtin_HEXAGON_V6_vinsertwr_128B", "V6.vlalignb" => "__builtin_HEXAGON_V6_vlalignb", @@ -2350,6 +2396,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vnavgub.128B" => "__builtin_HEXAGON_V6_vnavgub_128B", "V6.vnavgw" => "__builtin_HEXAGON_V6_vnavgw", "V6.vnavgw.128B" => "__builtin_HEXAGON_V6_vnavgw_128B", + "V6.vneg.qf16.hf" => "__builtin_HEXAGON_V6_vneg_qf16_hf", + "V6.vneg.qf16.hf.128B" => "__builtin_HEXAGON_V6_vneg_qf16_hf_128B", + "V6.vneg.qf16.qf16" => "__builtin_HEXAGON_V6_vneg_qf16_qf16", + "V6.vneg.qf16.qf16.128B" => "__builtin_HEXAGON_V6_vneg_qf16_qf16_128B", + "V6.vneg.qf32.qf32" => "__builtin_HEXAGON_V6_vneg_qf32_qf32", + "V6.vneg.qf32.qf32.128B" => "__builtin_HEXAGON_V6_vneg_qf32_qf32_128B", + "V6.vneg.qf32.sf" => "__builtin_HEXAGON_V6_vneg_qf32_sf", + "V6.vneg.qf32.sf.128B" => "__builtin_HEXAGON_V6_vneg_qf32_sf_128B", "V6.vnormamth" => "__builtin_HEXAGON_V6_vnormamth", "V6.vnormamth.128B" => "__builtin_HEXAGON_V6_vnormamth_128B", "V6.vnormamtw" => "__builtin_HEXAGON_V6_vnormamtw", @@ -2684,6 +2738,24 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "iocsrwr.d" => "__builtin_loongarch_iocsrwr_d", "iocsrwr.h" => "__builtin_loongarch_iocsrwr_h", "iocsrwr.w" => "__builtin_loongarch_iocsrwr_w", + "lasx.cast.128" => "__builtin_lasx_cast_128", + "lasx.cast.128.d" => "__builtin_lasx_cast_128_d", + "lasx.cast.128.s" => "__builtin_lasx_cast_128_s", + "lasx.concat.128" => "__builtin_lasx_concat_128", + "lasx.concat.128.d" => "__builtin_lasx_concat_128_d", + "lasx.concat.128.s" => "__builtin_lasx_concat_128_s", + "lasx.extract.128.hi" => "__builtin_lasx_extract_128_hi", + "lasx.extract.128.hi.d" => "__builtin_lasx_extract_128_hi_d", + "lasx.extract.128.hi.s" => "__builtin_lasx_extract_128_hi_s", + "lasx.extract.128.lo" => "__builtin_lasx_extract_128_lo", + "lasx.extract.128.lo.d" => "__builtin_lasx_extract_128_lo_d", + "lasx.extract.128.lo.s" => "__builtin_lasx_extract_128_lo_s", + "lasx.insert.128.hi" => "__builtin_lasx_insert_128_hi", + "lasx.insert.128.hi.d" => "__builtin_lasx_insert_128_hi_d", + "lasx.insert.128.hi.s" => "__builtin_lasx_insert_128_hi_s", + "lasx.insert.128.lo" => "__builtin_lasx_insert_128_lo", + "lasx.insert.128.lo.d" => "__builtin_lasx_insert_128_lo_d", + "lasx.insert.128.lo.s" => "__builtin_lasx_insert_128_lo_s", "lasx.vext2xv.d.b" => "__builtin_lasx_vext2xv_d_b", "lasx.vext2xv.d.h" => "__builtin_lasx_vext2xv_d_h", "lasx.vext2xv.d.w" => "__builtin_lasx_vext2xv_d_w", @@ -4950,8 +5022,20 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "f16x2.to.e5m2x2.rn.relu" => "__nvvm_f16x2_to_e5m2x2_rn_relu", "f2bf16.rn" => "__nvvm_f2bf16_rn", "f2bf16.rn.relu" => "__nvvm_f2bf16_rn_relu", + "f2bf16.rn.relu.satfinite" => "__nvvm_f2bf16_rn_relu_satfinite", + "f2bf16.rn.satfinite" => "__nvvm_f2bf16_rn_satfinite", "f2bf16.rz" => "__nvvm_f2bf16_rz", "f2bf16.rz.relu" => "__nvvm_f2bf16_rz_relu", + "f2bf16.rz.relu.satfinite" => "__nvvm_f2bf16_rz_relu_satfinite", + "f2bf16.rz.satfinite" => "__nvvm_f2bf16_rz_satfinite", + "f2f16.rn" => "__nvvm_f2f16_rn", + "f2f16.rn.relu" => "__nvvm_f2f16_rn_relu", + "f2f16.rn.relu.satfinite" => "__nvvm_f2f16_rn_relu_satfinite", + "f2f16.rn.satfinite" => "__nvvm_f2f16_rn_satfinite", + "f2f16.rz" => "__nvvm_f2f16_rz", + "f2f16.rz.relu" => "__nvvm_f2f16_rz_relu", + "f2f16.rz.relu.satfinite" => "__nvvm_f2f16_rz_relu_satfinite", + "f2f16.rz.satfinite" => "__nvvm_f2f16_rz_satfinite", "f2h.rn" => "__nvvm_f2h_rn", "f2h.rn.ftz" => "__nvvm_f2h_rn_ftz", "f2i.rm" => "__nvvm_f2i_rm", @@ -5035,20 +5119,28 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "ff.to.ue8m0x2.rz.satfinite" => "__nvvm_ff_to_ue8m0x2_rz_satfinite", "ff2bf16x2.rn" => "__nvvm_ff2bf16x2_rn", "ff2bf16x2.rn.relu" => "__nvvm_ff2bf16x2_rn_relu", + "ff2bf16x2.rn.relu.satfinite" => "__nvvm_ff2bf16x2_rn_relu_satfinite", + "ff2bf16x2.rn.satfinite" => "__nvvm_ff2bf16x2_rn_satfinite", "ff2bf16x2.rs" => "__nvvm_ff2bf16x2_rs", "ff2bf16x2.rs.relu" => "__nvvm_ff2bf16x2_rs_relu", "ff2bf16x2.rs.relu.satfinite" => "__nvvm_ff2bf16x2_rs_relu_satfinite", "ff2bf16x2.rs.satfinite" => "__nvvm_ff2bf16x2_rs_satfinite", "ff2bf16x2.rz" => "__nvvm_ff2bf16x2_rz", "ff2bf16x2.rz.relu" => "__nvvm_ff2bf16x2_rz_relu", + "ff2bf16x2.rz.relu.satfinite" => "__nvvm_ff2bf16x2_rz_relu_satfinite", + "ff2bf16x2.rz.satfinite" => "__nvvm_ff2bf16x2_rz_satfinite", "ff2f16x2.rn" => "__nvvm_ff2f16x2_rn", "ff2f16x2.rn.relu" => "__nvvm_ff2f16x2_rn_relu", + "ff2f16x2.rn.relu.satfinite" => "__nvvm_ff2f16x2_rn_relu_satfinite", + "ff2f16x2.rn.satfinite" => "__nvvm_ff2f16x2_rn_satfinite", "ff2f16x2.rs" => "__nvvm_ff2f16x2_rs", "ff2f16x2.rs.relu" => "__nvvm_ff2f16x2_rs_relu", "ff2f16x2.rs.relu.satfinite" => "__nvvm_ff2f16x2_rs_relu_satfinite", "ff2f16x2.rs.satfinite" => "__nvvm_ff2f16x2_rs_satfinite", "ff2f16x2.rz" => "__nvvm_ff2f16x2_rz", "ff2f16x2.rz.relu" => "__nvvm_ff2f16x2_rz_relu", + "ff2f16x2.rz.relu.satfinite" => "__nvvm_ff2f16x2_rz_relu_satfinite", + "ff2f16x2.rz.satfinite" => "__nvvm_ff2f16x2_rz_satfinite", "floor.d" => "__nvvm_floor_d", "floor.f" => "__nvvm_floor_f", "floor.ftz.f" => "__nvvm_floor_ftz_f", @@ -5942,6 +6034,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "altivec.vupklsb" => "__builtin_altivec_vupklsb", "altivec.vupklsh" => "__builtin_altivec_vupklsh", "altivec.vupklsw" => "__builtin_altivec_vupklsw", + "amo.ldat" => "__builtin_amo_ldat", + "amo.lwat" => "__builtin_amo_lwat", "bcdadd" => "__builtin_ppc_bcdadd", "bcdadd.p" => "__builtin_ppc_bcdadd_p", "bcdcopysign" => "__builtin_ppc_bcdcopysign", @@ -6202,6 +6296,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "vsx.xvminsp" => "__builtin_vsx_xvminsp", "vsx.xvredp" => "__builtin_vsx_xvredp", "vsx.xvresp" => "__builtin_vsx_xvresp", + "vsx.xvrlw" => "__builtin_vsx_xvrlw", "vsx.xvrsqrtedp" => "__builtin_vsx_xvrsqrtedp", "vsx.xvrsqrtesp" => "__builtin_vsx_xvrsqrtesp", "vsx.xvtdivdp" => "__builtin_vsx_xvtdivdp", @@ -10158,24 +10253,16 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "stui" => "__builtin_ia32_stui", "subborrow.u32" => "__builtin_ia32_subborrow_u32", "subborrow.u64" => "__builtin_ia32_subborrow_u64", - "t2rpntlvwz0" => "__builtin_ia32_t2rpntlvwz0", "t2rpntlvwz0rs" => "__builtin_ia32_t2rpntlvwz0rs", "t2rpntlvwz0rst1" => "__builtin_ia32_t2rpntlvwz0rst1", - "t2rpntlvwz0t1" => "__builtin_ia32_t2rpntlvwz0t1", - "t2rpntlvwz1" => "__builtin_ia32_t2rpntlvwz1", "t2rpntlvwz1rs" => "__builtin_ia32_t2rpntlvwz1rs", "t2rpntlvwz1rst1" => "__builtin_ia32_t2rpntlvwz1rst1", - "t2rpntlvwz1t1" => "__builtin_ia32_t2rpntlvwz1t1", "tbm.bextri.u32" => "__builtin_ia32_bextri_u32", "tbm.bextri.u64" => "__builtin_ia32_bextri_u64", "tcmmimfp16ps" => "__builtin_ia32_tcmmimfp16ps", "tcmmimfp16ps.internal" => "__builtin_ia32_tcmmimfp16ps_internal", "tcmmrlfp16ps" => "__builtin_ia32_tcmmrlfp16ps", "tcmmrlfp16ps.internal" => "__builtin_ia32_tcmmrlfp16ps_internal", - "tconjtcmmimfp16ps" => "__builtin_ia32_tconjtcmmimfp16ps", - "tconjtcmmimfp16ps.internal" => "__builtin_ia32_tconjtcmmimfp16ps_internal", - "tconjtfp16" => "__builtin_ia32_tconjtfp16", - "tconjtfp16.internal" => "__builtin_ia32_tconjtfp16_internal", "tcvtrowd2ps" => "__builtin_ia32_tcvtrowd2ps", "tcvtrowd2ps.internal" => "__builtin_ia32_tcvtrowd2ps_internal", "tcvtrowps2bf16h" => "__builtin_ia32_tcvtrowps2bf16h", @@ -10225,18 +10312,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "tmmultf32ps" => "__builtin_ia32_tmmultf32ps", "tmmultf32ps.internal" => "__builtin_ia32_tmmultf32ps_internal", "tpause" => "__builtin_ia32_tpause", - "ttcmmimfp16ps" => "__builtin_ia32_ttcmmimfp16ps", - "ttcmmimfp16ps.internal" => "__builtin_ia32_ttcmmimfp16ps_internal", - "ttcmmrlfp16ps" => "__builtin_ia32_ttcmmrlfp16ps", - "ttcmmrlfp16ps.internal" => "__builtin_ia32_ttcmmrlfp16ps_internal", - "ttdpbf16ps" => "__builtin_ia32_ttdpbf16ps", - "ttdpbf16ps.internal" => "__builtin_ia32_ttdpbf16ps_internal", - "ttdpfp16ps" => "__builtin_ia32_ttdpfp16ps", - "ttdpfp16ps.internal" => "__builtin_ia32_ttdpfp16ps_internal", - "ttmmultf32ps" => "__builtin_ia32_ttmmultf32ps", - "ttmmultf32ps.internal" => "__builtin_ia32_ttmmultf32ps_internal", - "ttransposed" => "__builtin_ia32_ttransposed", - "ttransposed.internal" => "__builtin_ia32_ttransposed_internal", "umonitor" => "__builtin_ia32_umonitor", "umwait" => "__builtin_ia32_umwait", "urdmsr" => "__builtin_ia32_urdmsr", From 573d6a5b9b473407dee1a1a98efda03ccf5fc921 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 16:56:52 +0000 Subject: [PATCH 0294/3801] Bump jws in /editors/code Bumps and [jws](https://github.com/brianloveswords/node-jws). These dependencies needed to be updated together. Updates `jws` from 3.2.2 to 3.2.3 - [Release notes](https://github.com/brianloveswords/node-jws/releases) - [Changelog](https://github.com/auth0/node-jws/blob/master/CHANGELOG.md) - [Commits](https://github.com/brianloveswords/node-jws/compare/v3.2.2...v3.2.3) Updates `jws` from 4.0.0 to 4.0.1 - [Release notes](https://github.com/brianloveswords/node-jws/releases) - [Changelog](https://github.com/auth0/node-jws/blob/master/CHANGELOG.md) - [Commits](https://github.com/brianloveswords/node-jws/compare/v3.2.2...v3.2.3) --- updated-dependencies: - dependency-name: jws dependency-version: 3.2.3 dependency-type: indirect - dependency-name: jws dependency-version: 4.0.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- .../editors/code/package-lock.json | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json index d49d19fbe10c..00d83e906848 100644 --- a/src/tools/rust-analyzer/editors/code/package-lock.json +++ b/src/tools/rust-analyzer/editors/code/package-lock.json @@ -1486,6 +1486,7 @@ "integrity": "sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.25.0", "@typescript-eslint/types": "8.25.0", @@ -1869,6 +1870,7 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2838,6 +2840,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -3319,6 +3322,7 @@ "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -4406,6 +4410,7 @@ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", "license": "MIT", + "peer": true, "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -4508,25 +4513,25 @@ } }, "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", "dev": true, "license": "MIT", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz", + "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==", "dev": true, "license": "MIT", "dependencies": { - "jwa": "^1.4.1", + "jwa": "^1.4.2", "safe-buffer": "^5.0.1" } }, @@ -4544,25 +4549,25 @@ } }, "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", "dev": true, "license": "MIT", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", "dev": true, "license": "MIT", "dependencies": { - "jwa": "^2.0.0", + "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, @@ -6673,6 +6678,7 @@ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" From ce050d6571c0bf4e37af08a6f45e92a54c7a22eb Mon Sep 17 00:00:00 2001 From: Redddy Date: Fri, 5 Dec 2025 02:02:48 +0900 Subject: [PATCH 0295/3801] Add Zed to quickstart --- src/doc/rustc-dev-guide/src/building/quickstart.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/building/quickstart.md b/src/doc/rustc-dev-guide/src/building/quickstart.md index 97314d803695..42058246cd05 100644 --- a/src/doc/rustc-dev-guide/src/building/quickstart.md +++ b/src/doc/rustc-dev-guide/src/building/quickstart.md @@ -66,6 +66,6 @@ questions, [the full chapter](./how-to-build-and-run.md) might contain the answers, and if it doesn't, feel free to ask for help on [Zulip](https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp). -If you use VSCode, Vim, Emacs or Helix, `./x setup` will ask you if you want to +If you use VSCode, Vim, Emacs, Helix or Zed, `./x setup` will ask you if you want to set up the editor config. For more information, check out [suggested workflows](./suggested.md). From 130d4b0ab6dc5b08871529ba3bbd55accc6f2da4 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Thu, 4 Dec 2025 12:29:45 +0800 Subject: [PATCH 0296/3801] Add config hide placeholders type hints In the inferred type hints, expand the line too long. add config to disable it. Example --- ```json {"rust-analyzer.inlayHints.typeHints.hideInferredTypes": true} ``` ```rust use std::collections::HashMap; fn foo(iter: Vec, std::io::Error>>) { let output = iter.into_iter().collect::, _>>().unwrap(); } ``` **Before this PR** ```rust let output: Vec> = iter.into_iter().collect::>, _ = Error>>().unwrap(); ``` **After this PR** ```rust let output: Vec> = iter.into_iter().collect::, _>>().unwrap(); ``` --- .../crates/ide/src/inlay_hints.rs | 2 ++ .../ide/src/inlay_hints/placeholders.rs | 20 ++++++++++++++++++- .../crates/ide/src/static_index.rs | 1 + .../rust-analyzer/src/cli/analysis_stats.rs | 1 + .../crates/rust-analyzer/src/config.rs | 4 ++++ .../docs/book/src/configuration_generated.md | 7 +++++++ .../rust-analyzer/editors/code/package.json | 10 ++++++++++ 7 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index deacc7fafbc0..260da900f402 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -320,6 +320,7 @@ pub struct InlayHintsConfig<'a> { pub implied_dyn_trait_hints: bool, pub lifetime_elision_hints: LifetimeElisionHints, pub param_names_for_lifetime_elision_hints: bool, + pub hide_inferred_type_hints: bool, pub hide_named_constructor_hints: bool, pub hide_closure_initialization_hints: bool, pub hide_closure_parameter_hints: bool, @@ -900,6 +901,7 @@ mod tests { adjustment_hints_mode: AdjustmentHintsMode::Prefix, adjustment_hints_hide_outside_unsafe: false, binding_mode_hints: false, + hide_inferred_type_hints: false, hide_named_constructor_hints: false, hide_closure_initialization_hints: false, hide_closure_parameter_hints: false, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/placeholders.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/placeholders.rs index 96d2c17c03bb..e535b92a5792 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/placeholders.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/placeholders.rs @@ -20,7 +20,7 @@ pub(super) fn type_hints( display_target: DisplayTarget, placeholder: InferType, ) -> Option<()> { - if !config.type_hints { + if !config.type_hints || config.hide_inferred_type_hints { return None; } @@ -73,4 +73,22 @@ fn foo() { "#, ); } + + #[test] + fn hide_inferred_types() { + check_with_config( + InlayHintsConfig { + type_hints: true, + hide_inferred_type_hints: true, + ..DISABLED_CONFIG + }, + r#" +struct S(T); + +fn foo() { + let t: (_, _, [_; _]) = (1_u32, S(2), [false] as _); +} + "#, + ); + } } diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 0cf2e15bc6f0..f3cda9156bbb 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -183,6 +183,7 @@ impl StaticIndex<'_> { adjustment_hints_hide_outside_unsafe: false, implicit_drop_hints: false, implied_dyn_trait_hints: false, + hide_inferred_type_hints: false, hide_named_constructor_hints: false, hide_closure_initialization_hints: false, hide_closure_parameter_hints: false, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index ed0b64668559..bd3f05977ef0 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -1222,6 +1222,7 @@ impl flags::AnalysisStats { implied_dyn_trait_hints: true, lifetime_elision_hints: ide::LifetimeElisionHints::Always, param_names_for_lifetime_elision_hints: true, + hide_inferred_type_hints: false, hide_named_constructor_hints: false, hide_closure_initialization_hints: false, hide_closure_parameter_hints: false, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index c380621d81a1..1a2ea97204aa 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -304,6 +304,9 @@ config_data! { /// Hide inlay parameter type hints for closures. inlayHints_typeHints_hideClosureParameter: bool = false, + /// Hide inlay type hints for inferred types. + inlayHints_typeHints_hideInferredTypes: bool = false, + /// Hide inlay type hints for constructors. inlayHints_typeHints_hideNamedConstructor: bool = false, @@ -1937,6 +1940,7 @@ impl Config { hide_named_constructor_hints: self .inlayHints_typeHints_hideNamedConstructor() .to_owned(), + hide_inferred_type_hints: self.inlayHints_typeHints_hideInferredTypes().to_owned(), hide_closure_initialization_hints: self .inlayHints_typeHints_hideClosureInitialization() .to_owned(), diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index fe1ea57c9b18..b36576b4bb20 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1118,6 +1118,13 @@ Default: `false` Hide inlay parameter type hints for closures. +## rust-analyzer.inlayHints.typeHints.hideInferredTypes {#inlayHints.typeHints.hideInferredTypes} + +Default: `false` + +Hide inlay type hints for inferred types. + + ## rust-analyzer.inlayHints.typeHints.hideNamedConstructor {#inlayHints.typeHints.hideNamedConstructor} Default: `false` diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 8475864427e1..abe85d6c9d72 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -2466,6 +2466,16 @@ } } }, + { + "title": "Inlay Hints", + "properties": { + "rust-analyzer.inlayHints.typeHints.hideInferredTypes": { + "markdownDescription": "Hide inlay type hints for inferred types.", + "default": false, + "type": "boolean" + } + } + }, { "title": "Inlay Hints", "properties": { From d21adb9158d1b3628855f49c58a3b65fc24c4332 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 4 Dec 2025 20:21:27 +0100 Subject: [PATCH 0297/3801] bootstrap: add `rustc-dev` install target --- src/bootstrap/src/core/build_steps/dist.rs | 4 ++-- src/bootstrap/src/core/build_steps/install.rs | 11 +++++++++++ src/bootstrap/src/core/builder/mod.rs | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 40149ee09427..caf0af35e401 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -892,8 +892,8 @@ impl Step for Std { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct RustcDev { /// The compiler that will build rustc which will be shipped in this component. - build_compiler: Compiler, - target: TargetSelection, + pub build_compiler: Compiler, + pub target: TargetSelection, } impl RustcDev { diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index d52cc52abbd3..d23fe029bcc7 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -279,6 +279,17 @@ install!((self, builder, _config), }); install_sh(builder, "rustc", self.build_compiler, Some(self.target), &tarball); }; + RustcDev, alias = "rustc-dev", Self::should_build(_config), IS_HOST: true, { + if let Some(tarball) = builder.ensure(dist::RustcDev { + build_compiler: self.build_compiler, target: self.target + }) { + install_sh(builder, "rustc-dev", self.build_compiler, Some(self.target), &tarball); + } else { + builder.info( + &format!("skipping Install RustcDev stage{} ({})", self.build_compiler.stage + 1, self.target), + ); + } + }; RustcCodegenCranelift, alias = "rustc-codegen-cranelift", Self::should_build(_config), IS_HOST: true, { if let Some(tarball) = builder.ensure(dist::CraneliftCodegenBackend { compilers: RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target), diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 961d0cd855ae..0bf70883a47a 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -998,6 +998,7 @@ impl<'a> Builder<'a> { // binary path, we must install rustc before the tools. Otherwise, the rust-installer will // install the same binaries twice for each tool, leaving backup files (*.old) as a result. install::Rustc, + install::RustcDev, install::Cargo, install::RustAnalyzer, install::Rustfmt, From 013250c571191e9b7f3418dff0290f2ea9b56f22 Mon Sep 17 00:00:00 2001 From: eihqnh Date: Thu, 4 Dec 2025 14:10:47 +0800 Subject: [PATCH 0298/3801] fix: Skip cfg attributes when stripping macro input attributes --- .../src/macro_expansion_tests/proc_macros.rs | 19 +++++++++++++++ .../crates/hir-expand/src/cfg_process.rs | 24 +++++++------------ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs index 521624691066..6f30ca04af8c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs @@ -341,3 +341,22 @@ struct Foo; #[helper_should_be_ignored] struct Foo;"#]], ); } + +#[test] +fn attribute_macro_stripping_with_cfg() { + check( + r#" +//- proc_macros: generate_suffixed_type +#[cfg(all())] +#[proc_macros::generate_suffixed_type] +struct S; +"#, + expect![[r#" +#[cfg(all())] +#[proc_macros::generate_suffixed_type] +struct S; + +struct S; +struct SSuffix;"#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs index 227a62ff9f21..a0de36548e9f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs @@ -162,25 +162,19 @@ fn macro_input_callback( } } Meta::TokenTree { path, tt } => { - if path.segments.len() != 1 + if path.is1("cfg") { + let cfg_expr = CfgExpr::parse_from_ast( + &mut TokenTreeChildren::new(&tt).peekable(), + ); + if cfg_options().check(&cfg_expr) == Some(false) { + return ControlFlow::Break(ItemIsCfgedOut); + } + strip_current_attr = true; + } else if path.segments.len() != 1 || !is_item_tree_filtered_attr(path.segments[0].text()) { strip_current_attr = should_strip_attr(); } - - if path.segments.len() == 1 { - let name = path.segments[0].text(); - - if name == "cfg" { - let cfg_expr = CfgExpr::parse_from_ast( - &mut TokenTreeChildren::new(&tt).peekable(), - ); - if cfg_options().check(&cfg_expr) == Some(false) { - return ControlFlow::Break(ItemIsCfgedOut); - } - strip_current_attr = true; - } - } } Meta::Path { path } => { if path.segments.len() != 1 From 74387157c7edaf8a0ace3cbb54c42d2dfa7b8f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 4 Dec 2025 21:17:40 +0100 Subject: [PATCH 0299/3801] Revert "Rollup merge of #149147 - chenyukang:yukang-fix-unused_assignments-macro-gen-147648, r=JonathanBrouwer" This reverts commit 82a17b30d8cd379a43c3ee8d12598e89e3be0fbd, reversing changes made to 5019bdaefeebecac42b778ae98def56cab69ab30. --- compiler/rustc_mir_transform/src/liveness.rs | 5 ----- tests/ui/liveness/auxiliary/aux_issue_147648.rs | 7 ------- .../liveness/unused-assignments-from-macro-147648.rs | 10 ---------- 3 files changed, 22 deletions(-) delete mode 100644 tests/ui/liveness/auxiliary/aux_issue_147648.rs delete mode 100644 tests/ui/liveness/unused-assignments-from-macro-147648.rs diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 7ee7c3a81c7e..1d1ba455a81e 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -75,11 +75,6 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den return DenseBitSet::new_empty(0); } - // Don't run unused pass for items generated by foreign macros - if tcx.def_span(parent).in_external_macro(tcx.sess.source_map()) { - return DenseBitSet::new_empty(0); - } - let mut body = &*tcx.mir_promoted(def_id).0.borrow(); let mut body_mem; diff --git a/tests/ui/liveness/auxiliary/aux_issue_147648.rs b/tests/ui/liveness/auxiliary/aux_issue_147648.rs deleted file mode 100644 index ccb5ad6b8fc0..000000000000 --- a/tests/ui/liveness/auxiliary/aux_issue_147648.rs +++ /dev/null @@ -1,7 +0,0 @@ -#[macro_export] -macro_rules! unused_assign { - ($x:ident) => { - let mut $x = 1; - $x = 2; - }; -} diff --git a/tests/ui/liveness/unused-assignments-from-macro-147648.rs b/tests/ui/liveness/unused-assignments-from-macro-147648.rs deleted file mode 100644 index c32c281538b4..000000000000 --- a/tests/ui/liveness/unused-assignments-from-macro-147648.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ check-pass -//@ aux-build:aux_issue_147648.rs - -#![deny(unused_assignments)] - -extern crate aux_issue_147648; - -fn main() { - aux_issue_147648::unused_assign!(y); -} From 091c62bcf8ee84299fba4394056f72fad196008d Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 4 Dec 2025 18:15:35 -0500 Subject: [PATCH 0300/3801] triagebot: Enable the range-diff feature --- library/compiler-builtins/triagebot.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/compiler-builtins/triagebot.toml b/library/compiler-builtins/triagebot.toml index eba5cdd88b94..57f9a0849839 100644 --- a/library/compiler-builtins/triagebot.toml +++ b/library/compiler-builtins/triagebot.toml @@ -19,3 +19,8 @@ check-commits = false # Enable issue transfers within the org # Documentation at: https://forge.rust-lang.org/triagebot/transfer.html [transfer] + +# Enable comments linking to triagebot range-diff when a PR is rebased +# onto a different base commit +# Documentation at: https://forge.rust-lang.org/triagebot/range-diff.html +[range-diff] From ac7e6c6a97b1dfb19718b5a5387838eb203cd326 Mon Sep 17 00:00:00 2001 From: quaternic <57393910+quaternic@users.noreply.github.com> Date: Wed, 3 Dec 2025 08:57:36 +0200 Subject: [PATCH 0301/3801] Optimized implementation for uN::{gather,scatter}_bits --- library/core/src/num/int_bits.rs | 173 ++++++++++++++++++++++++++++ library/core/src/num/mod.rs | 1 + library/core/src/num/uint_macros.rs | 44 +------ 3 files changed, 178 insertions(+), 40 deletions(-) create mode 100644 library/core/src/num/int_bits.rs diff --git a/library/core/src/num/int_bits.rs b/library/core/src/num/int_bits.rs new file mode 100644 index 000000000000..38eac6ece17b --- /dev/null +++ b/library/core/src/num/int_bits.rs @@ -0,0 +1,173 @@ +//! Implementations for `uN::gather_bits` and `uN::scatter_bits` +//! +//! For the purposes of this implementation, the operations can be thought +//! of as operating on the input bits as a list, starting from the least +//! significant bit. Gathering is like `Vec::retain` that deletes bits +//! where the mask has a zero. Scattering is like doing the inverse by +//! inserting the zeros that gathering would delete. +//! +//! Key observation: Each bit that is gathered/scattered needs to be +//! shifted by the count of zeroes up to the corresponding mask bit. +//! +//! With that in mind, the general idea is to decompose the operation into +//! a sequence of stages `k in 0..log2(BITS)`, where each stage shifts +//! some of the bits by `n = 1 << k`. The masks for each stage are computed +//! via prefix counts of zeroes in the mask. +//! +//! # Gathering +//! +//! Consider the input as a sequence of runs of data (bitstrings A,B,C,...), +//! split by fixed-width groups of zeros ('.'), initially at width `n = 1`. +//! Counting the groups of zeros, each stage shifts the odd-indexed runs of +//! data right by `n`, effectively swapping them with the preceding zeros. +//! For the next stage, `n` is doubled as all the zeros are now paired. +//! ```text +//! .A.B.C.D.E.F.G.H +//! ..AB..CD..EF..GH +//! ....ABCD....EFGH +//! ........ABCDEFGH +//! ``` +//! What makes this nontrivial is that the lengths of the bitstrings are not +//! the same and, using lowercase for individual bits, the above might look +//! more like +//! ```text +//! .a.bbb.ccccc.dd.e..g.hh +//! ..abbb..cccccdd..e..ghh +//! ....abbbcccccdd....eghh +//! ........abbbcccccddeghh +//! ``` +//! +//! # Scattering +//! +//! For `scatter_bits`, the stages are reversed. We start with a single run of +//! data in the low bits. Each stage then splits each run of data in two by +//! shifting part of it left by `n`, which is halved each stage. +//! ```text +//! ........ABCDEFGH +//! ....ABCD....EFGH +//! ..AB..CD..EF..GH +//! .A.B.C.D.E.F.G.H +//! ``` +//! +//! # Stage masks +//! +//! To facilitate the shifts at each stage, we compute a mask that covers both +//! the bitstrings to shift, and the zeros they shift into. +//! ```text +//! .A.B.C.D.E.F.G.H +//! ## ## ## ## +//! ..AB..CD..EF..GH +//! #### #### +//! ....ABCD....EFGH +//! ######## +//! ........ABCDEFGH +//! ``` + +macro_rules! uint_impl { + ($U:ident) => { + pub(super) mod $U { + const STAGES: usize = $U::BITS.ilog2() as usize; + #[inline] + const fn prepare(m: $U) -> [$U; STAGES] { + // We'll start with `zeros` as a mask of the bits to be removed, + // and compute into `masks` the parts that shift at each stage. + let mut zeros = !m; + let mut masks = [0; STAGES]; + let mut n = 1; + let mut k = 0; + while n < $U::BITS { + // Suppose `zeros` has bits set at ranges `{ a..a+n, b..b+n, ... }`. + // Then `parity` will be computed as `{ a.. } XOR { b.. } XOR ...`, + // which will be the ranges `{ a..b, c..d, e.. }` + let mut parity = zeros; + let mut j = n; + while j < $U::BITS { + parity ^= parity << j; + j <<= 1; + } + masks[k] = parity; + + // Toggle off the bits that are shifted into: + // { a..a+n, b..b+n, ... } & !{ a..b, c..d, e.. } + // == { b..b+n, d..d+n, ... } + zeros &= !parity; + // Expand the remaining ranges down to the bits that were + // shifted from: { b-n..b+n, d-n..d+n, ... } + zeros ^= zeros >> n; + + n <<= 1; + k += 1; + } + masks + } + + #[inline(always)] + pub(in super::super) const fn gather_impl(mut x: $U, sparse: $U) -> $U { + let masks = prepare(sparse); + x &= sparse; + let mut k = 0; + while k < STAGES { + let n = 1 << k; + // Consider each two runs of data with their leading + // groups of `n` 0-bits. Suppose that the run that is + // shifted right has length `a`, and the other one has + // length `b`. Assume that only zeros are shifted in. + // ```text + // [0; n], [X; a], [0; n], [Y; b] // x + // [0; n], [X; a], [0; n], [0; b] // q + // [0; n], [0; a + n], [Y; b] // x ^= q + // [0; n + n], [X; a], [0; b] // q >> n + // [0; n], [0; n], [X; a], [Y; b] // x ^= q << n + // ``` + // Only zeros are shifted out, satisfying the assumption + // for the next group. + + // In effect, the upper run of data is swapped with the + // group of `n` zeros below it. + let q = x & masks[k]; + x ^= q; + x ^= q >> n; + + k += 1; + } + x + } + #[inline(always)] + pub(in super::super) const fn scatter_impl(mut x: $U, sparse: $U) -> $U { + let masks = prepare(sparse); + let mut k = STAGES; + while k > 0 { + k -= 1; + let n = 1 << k; + // Consider each run of data with the `2 * n` arbitrary bits + // above it. Suppose that the run has length `a + b`, with + // `a` being the length of the part that needs to be + // shifted. Assume that only zeros are shifted in. + // ```text + // [_; n], [_; n], [X; a], [Y; b] // x + // [0; n], [_; n], [X; a], [0; b] // q + // [_; n], [0; n + a], [Y; b] // x ^= q + // [_; n], [X; a], [0; b + n] // q << n + // [_; n], [X; a], [0; n], [Y; b] // x ^= q << n + // ``` + // Only zeros are shifted out, satisfying the assumption + // for the next group. + + // In effect, `n` 0-bits are inserted somewhere in each run + // of data to spread it, and the two groups of `n` bits + // above are XOR'd together. + let q = x & masks[k]; + x ^= q; + x ^= q << n; + } + x & sparse + } + } + }; +} + +uint_impl!(u8); +uint_impl!(u16); +uint_impl!(u32); +uint_impl!(u64); +uint_impl!(u128); diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 35141dfeb3a6..558426c94e5d 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -44,6 +44,7 @@ mod int_macros; // import int_impl! mod uint_macros; // import uint_impl! mod error; +mod int_bits; mod int_log10; mod int_sqrt; pub(crate) mod libm; diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index c8224e92b17e..90e94092b1eb 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -492,27 +492,8 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn gather_bits(self, mut mask: Self) -> Self { - let mut bit_position = 1; - let mut result = 0; - - // Iterate through the mask bits, unsetting the lowest bit after - // each iteration. We fill the bits in the result starting from the - // least significant bit. - while mask != 0 { - // Find the next lowest set bit in the mask - let next_mask_bit = mask.isolate_lowest_one(); - - // Retrieve the masked bit and if present, set it in the result - let src_bit = (self & next_mask_bit) != 0; - result |= if src_bit { bit_position } else { 0 }; - - // Unset lowest set bit in the mask, prepare next position to set - mask ^= next_mask_bit; - bit_position <<= 1; - } - - result + pub const fn gather_bits(self, mask: Self) -> Self { + crate::num::int_bits::$ActualT::gather_impl(self as $ActualT, mask as $ActualT) as $SelfT } /// Returns an integer with the least significant bits of `self` @@ -528,25 +509,8 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn scatter_bits(mut self, mut mask: Self) -> Self { - let mut result = 0; - - // Iterate through the mask bits, unsetting the lowest bit after - // each iteration and right-shifting `self` by one to get the next - // bit into the least significant bit position. - while mask != 0 { - // Find the next bit position to potentially set - let next_mask_bit = mask.isolate_lowest_one(); - - // If bit is set, deposit it at the masked bit position - result |= if (self & 1) != 0 { next_mask_bit } else { 0 }; - - // Unset lowest set bit in the mask, shift in next `self` bit - mask ^= next_mask_bit; - self >>= 1; - } - - result + pub const fn scatter_bits(self, mask: Self) -> Self { + crate::num::int_bits::$ActualT::scatter_impl(self as $ActualT, mask as $ActualT) as $SelfT } /// Reverses the order of bits in the integer. The least significant bit becomes the most significant bit, From 382e9fa4a36729601c4a2e94c0cb48edf408fa76 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 2 Dec 2025 16:31:37 -0500 Subject: [PATCH 0302/3801] ci: Update the default branch name --- library/compiler-builtins/.github/workflows/main.yaml | 2 +- library/compiler-builtins/PUBLISHING.md | 2 +- library/compiler-builtins/ci/bench-icount.sh | 2 +- library/compiler-builtins/ci/ci-util.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index c8faecfcb2cc..4ed85ee69c6c 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -1,6 +1,6 @@ name: CI on: - push: { branches: [master] } + push: { branches: [main] } pull_request: concurrency: diff --git a/library/compiler-builtins/PUBLISHING.md b/library/compiler-builtins/PUBLISHING.md index 3df682ab04a4..c521910641f5 100644 --- a/library/compiler-builtins/PUBLISHING.md +++ b/library/compiler-builtins/PUBLISHING.md @@ -5,7 +5,7 @@ It's not great, but it works for now. PRs to improve this process would be greatly appreciated! 1. Make sure you've got a clean working tree and it's updated with the latest - changes on `master` + changes on `main` 2. Edit `Cargo.toml` to bump the version number 3. Commit this change 4. Run `git tag` to create a tag for this version diff --git a/library/compiler-builtins/ci/bench-icount.sh b/library/compiler-builtins/ci/bench-icount.sh index 12228b9da971..64405fdd02dc 100755 --- a/library/compiler-builtins/ci/bench-icount.sh +++ b/library/compiler-builtins/ci/bench-icount.sh @@ -15,7 +15,7 @@ iai_home="iai-home" # Use the arch as a tag to disambiguate artifacts tag="$(echo "$target" | cut -d'-' -f1)" -# Download the baseline from master +# Download the baseline from main ./ci/ci-util.py locate-baseline --download --extract --tag "$tag" # Run benchmarks once diff --git a/library/compiler-builtins/ci/ci-util.py b/library/compiler-builtins/ci/ci-util.py index c1db17c6c901..cb582db35194 100755 --- a/library/compiler-builtins/ci/ci-util.py +++ b/library/compiler-builtins/ci/ci-util.py @@ -49,7 +49,7 @@ USAGE = cleandoc( REPO_ROOT = Path(__file__).parent.parent GIT = ["git", "-C", REPO_ROOT] -DEFAULT_BRANCH = "master" +DEFAULT_BRANCH = "main" WORKFLOW_NAME = "CI" # Workflow that generates the benchmark artifacts ARTIFACT_PREFIX = "baseline-icount*" @@ -186,7 +186,7 @@ class Context: def _init_change_list(self): """Create a list of files that have been changed. This uses GITHUB_REF if - available, otherwise a diff between `HEAD` and `master`. + available, otherwise a diff between `HEAD` and `main`. """ # For pull requests, GitHub creates a ref `refs/pull/1234/merge` (1234 being From 1cfe3585e723f40537130e17f04b5e26cd0c306b Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 4 Dec 2025 17:14:53 -0500 Subject: [PATCH 0303/3801] bench: Update the benchmark runner to gungraun 0.17 `iai-callgrind` was renamed to `gungraun` and had a new release. Update everything to match. There shouldn't be any changes to observable behavior here. --- .../.github/workflows/main.yaml | 10 +++---- library/compiler-builtins/.gitignore | 1 + library/compiler-builtins/CONTRIBUTING.md | 6 ++-- library/compiler-builtins/Cargo.toml | 2 +- .../builtins-test/Cargo.toml | 6 ++-- .../builtins-test/benches/mem_icount.rs | 4 +-- library/compiler-builtins/ci/bench-icount.sh | 30 +++++++++++-------- library/compiler-builtins/ci/ci-util.py | 2 +- .../compiler-builtins/libm-test/Cargo.toml | 6 ++-- .../libm-test/benches/icount.rs | 12 ++++++-- 10 files changed, 45 insertions(+), 34 deletions(-) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 4ed85ee69c6c..63809fe04b59 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -247,13 +247,13 @@ jobs: - name: Set up dependencies run: | sudo apt-get update - sudo apt-get install -y valgrind gdb libc6-dbg # Needed for iai-callgrind + sudo apt-get install -y valgrind gdb libc6-dbg # Needed for gungraun rustup update "$BENCHMARK_RUSTC" --no-self-update rustup default "$BENCHMARK_RUSTC" - # Install the version of iai-callgrind-runner that is specified in Cargo.toml - iai_version="$(cargo metadata --format-version=1 --features icount | - jq -r '.packages[] | select(.name == "iai-callgrind").version')" - cargo binstall -y iai-callgrind-runner --version "$iai_version" + # Install the version of gungraun-runner that is specified in Cargo.toml + gungraun_version="$(cargo metadata --format-version=1 --features icount | + jq -r '.packages[] | select(.name == "gungraun").version')" + cargo binstall -y gungraun-runner --version "$gungraun_version" sudo apt-get install valgrind - uses: Swatinem/rust-cache@v2 with: diff --git a/library/compiler-builtins/.gitignore b/library/compiler-builtins/.gitignore index f12b871c2f78..abe346659d4c 100644 --- a/library/compiler-builtins/.gitignore +++ b/library/compiler-builtins/.gitignore @@ -9,6 +9,7 @@ compiler-rt # Benchmark cache baseline-* iai-home +gungraun-home # Temporary files *.bk diff --git a/library/compiler-builtins/CONTRIBUTING.md b/library/compiler-builtins/CONTRIBUTING.md index 9ae4f893c60d..f74d3f8ba127 100644 --- a/library/compiler-builtins/CONTRIBUTING.md +++ b/library/compiler-builtins/CONTRIBUTING.md @@ -150,8 +150,8 @@ cargo bench --no-default-features \ ``` There are also benchmarks that check instruction count behind the `icount` -feature. These require [`iai-callgrind-runner`] (via Cargo) and [Valgrind] -to be installed, which means these only run on limited platforms. +feature. These require [`gungraun-runner`] (via Cargo) and [Valgrind] to be +installed, which means these only run on limited platforms. Instruction count benchmarks are run as part of CI to flag performance regresions. @@ -163,7 +163,7 @@ cargo bench --no-default-features \ --bench icount --bench mem_icount ``` -[`iai-callgrind-runner`]: https://crates.io/crates/iai-callgrind-runner +[`gungraun-runner`]: https://crates.io/crates/gungraun-runner [Valgrind]: https://valgrind.org/ ## Subtree synchronization diff --git a/library/compiler-builtins/Cargo.toml b/library/compiler-builtins/Cargo.toml index 956d738f3b1f..6b4e691a1ebe 100644 --- a/library/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/Cargo.toml @@ -51,5 +51,5 @@ codegen-units = 1 lto = "fat" [profile.bench] -# Required for iai-callgrind +# Required for gungraun debug = true diff --git a/library/compiler-builtins/builtins-test/Cargo.toml b/library/compiler-builtins/builtins-test/Cargo.toml index 00a9d8579d11..2bcffe349318 100644 --- a/library/compiler-builtins/builtins-test/Cargo.toml +++ b/library/compiler-builtins/builtins-test/Cargo.toml @@ -14,7 +14,7 @@ rand_xoshiro = "0.7" # To compare float builtins against rustc_apfloat = "0.2.3" # Really a dev dependency, but dev dependencies can't be optional -iai-callgrind = { version = "0.15.2", optional = true } +gungraun = { version = "0.17.0", optional = true } [dependencies.compiler_builtins] path = "../builtins-shim" @@ -46,8 +46,8 @@ no-sys-f16-f64-convert = [] # Skip tests that rely on f16 symbols being available on the system no-sys-f16 = ["no-sys-f16-f64-convert"] -# Enable icount benchmarks (requires iai-callgrind and valgrind) -icount = ["dep:iai-callgrind"] +# Enable icount benchmarks (requires gungraun-runner and valgrind locally) +icount = ["dep:gungraun"] # Enable report generation without bringing in more dependencies by default benchmarking-reports = ["criterion/plotters", "criterion/html_reports"] diff --git a/library/compiler-builtins/builtins-test/benches/mem_icount.rs b/library/compiler-builtins/builtins-test/benches/mem_icount.rs index bd88cf80c7de..966ceea86d8d 100644 --- a/library/compiler-builtins/builtins-test/benches/mem_icount.rs +++ b/library/compiler-builtins/builtins-test/benches/mem_icount.rs @@ -1,11 +1,11 @@ -//! Benchmarks that use Callgrind (via `iai_callgrind`) to report instruction count metrics. This +//! Benchmarks that use Callgrind (via `gungraun`) to report instruction count metrics. This //! is stable enough to be tested in CI. use std::hint::black_box; use std::{ops, slice}; use compiler_builtins::mem::{memcmp, memcpy, memmove, memset}; -use iai_callgrind::{library_benchmark, library_benchmark_group, main}; +use gungraun::{library_benchmark, library_benchmark_group, main}; const PAGE_SIZE: usize = 0x1000; // 4 kiB const MAX_ALIGN: usize = 512; // assume we may use avx512 operations one day diff --git a/library/compiler-builtins/ci/bench-icount.sh b/library/compiler-builtins/ci/bench-icount.sh index 64405fdd02dc..56aa1df07e46 100755 --- a/library/compiler-builtins/ci/bench-icount.sh +++ b/library/compiler-builtins/ci/bench-icount.sh @@ -10,7 +10,7 @@ if [ -z "$target" ]; then target="$host_target" fi -iai_home="iai-home" +gungraun_home="gungraun-home" # Use the arch as a tag to disambiguate artifacts tag="$(echo "$target" | cut -d'-' -f1)" @@ -18,6 +18,10 @@ tag="$(echo "$target" | cut -d'-' -f1)" # Download the baseline from main ./ci/ci-util.py locate-baseline --download --extract --tag "$tag" +# FIXME: migration from iai-named baselines to gungraun, can be dropped +# after the first run with gungraun. +[ -d "iai-home" ] && mv "iai-home" "$gungraun_home" + # Run benchmarks once function run_icount_benchmarks() { cargo_args=( @@ -26,19 +30,19 @@ function run_icount_benchmarks() { "--features" "unstable,unstable-float,icount" ) - iai_args=( - "--home" "$(pwd)/$iai_home" - "--callgrind-limits=ir=5.0" + gungraun_args=( + "--home" "$(pwd)/$gungraun_home" + "--callgrind-limits=ir=5.0%" "--save-summary" ) - # Parse `cargo_arg0 cargo_arg1 -- iai_arg0 iai_arg1` syntax - parsing_iai_args=0 + # Parse `cargo_arg0 cargo_arg1 -- gungraun_arg0 gungraun_arg1` syntax + parsing_gungraun_args=0 while [ "$#" -gt 0 ]; do - if [ "$parsing_iai_args" == "1" ]; then - iai_args+=("$1") + if [ "$parsing_gungraun_args" == "1" ]; then + gungraun_args+=("$1") elif [ "$1" == "--" ]; then - parsing_iai_args=1 + parsing_gungraun_args=1 else cargo_args+=("$1") fi @@ -46,9 +50,9 @@ function run_icount_benchmarks() { shift done - # Run iai-callgrind benchmarks. Do this in a subshell with `&& true` to - # capture rather than exit on error. - (cargo bench "${cargo_args[@]}" -- "${iai_args[@]}") && true + # Run gungraun benchmarks. Do this in a subshell with `&& true` to capture + # rather than exit on error. + (cargo bench "${cargo_args[@]}" -- "${gungraun_args[@]}") && true exit_code="$?" if [ "$exit_code" -eq 0 ]; then @@ -68,4 +72,4 @@ run_icount_benchmarks -- --save-baseline=hardfloat # Name and tar the new baseline name="baseline-icount-$tag-$(date -u +'%Y%m%d%H%M')-${GITHUB_SHA:0:12}" echo "BASELINE_NAME=$name" >>"$GITHUB_ENV" -tar cJf "$name.tar.xz" "$iai_home" +tar cJf "$name.tar.xz" "$gungraun_home" diff --git a/library/compiler-builtins/ci/ci-util.py b/library/compiler-builtins/ci/ci-util.py index cb582db35194..113820b70215 100755 --- a/library/compiler-builtins/ci/ci-util.py +++ b/library/compiler-builtins/ci/ci-util.py @@ -38,7 +38,7 @@ USAGE = cleandoc( `--tag` can be specified to look for artifacts with a specific tag, such as for a specific architecture. - Note that `--extract` will overwrite files in `iai-home`. + Note that `--extract` will overwrite files in `gungraun-home`. handle-bench-regressions PR_NUMBER Exit with success if the pull request contains a line starting with diff --git a/library/compiler-builtins/libm-test/Cargo.toml b/library/compiler-builtins/libm-test/Cargo.toml index 0af6b0c1da5c..adecfc1af6b8 100644 --- a/library/compiler-builtins/libm-test/Cargo.toml +++ b/library/compiler-builtins/libm-test/Cargo.toml @@ -21,8 +21,8 @@ build-musl = ["dep:musl-math-sys"] # Enable report generation without bringing in more dependencies by default benchmarking-reports = ["criterion/plotters", "criterion/html_reports"] -# Enable icount benchmarks (requires iai-callgrind and valgrind) -icount = ["dep:iai-callgrind"] +# Enable icount benchmarks (requires gungraun-runner and valgrind locally) +icount = ["dep:gungraun"] # Run with a reduced set of benchmarks, such as for CI short-benchmarks = [] @@ -31,7 +31,7 @@ short-benchmarks = [] anyhow = "1.0.98" # This is not directly used but is required so we can enable `gmp-mpfr-sys/force-cross`. gmp-mpfr-sys = { version = "1.6.5", optional = true, default-features = false } -iai-callgrind = { version = "0.15.2", optional = true } +gungraun = { version = "0.17.0", optional = true } indicatif = { version = "0.18.0", default-features = false } libm = { path = "../libm", features = ["unstable-public-internals"] } libm-macros = { path = "../crates/libm-macros" } diff --git a/library/compiler-builtins/libm-test/benches/icount.rs b/library/compiler-builtins/libm-test/benches/icount.rs index 0b85771225dd..fb856d9be451 100644 --- a/library/compiler-builtins/libm-test/benches/icount.rs +++ b/library/compiler-builtins/libm-test/benches/icount.rs @@ -1,10 +1,10 @@ -//! Benchmarks that use `iai-cachegrind` to be reasonably CI-stable. +//! Benchmarks that use `gungraun` to be reasonably CI-stable. #![feature(f16)] #![feature(f128)] use std::hint::black_box; -use iai_callgrind::{library_benchmark, library_benchmark_group, main}; +use gungraun::{library_benchmark, library_benchmark_group, main}; use libm::support::{HInt, Hexf, hf16, hf32, hf64, hf128, u256}; use libm_test::generate::spaced; use libm_test::{CheckBasis, CheckCtx, GeneratorKind, MathOp, OpRustArgs, TupleCall, op}; @@ -156,7 +156,13 @@ fn icount_bench_u256_shr(cases: Vec<(u256, u32)>) { library_benchmark_group!( name = icount_bench_u128_group; - benchmarks = icount_bench_u128_widen_mul, icount_bench_u256_narrowing_div, icount_bench_u256_add, icount_bench_u256_sub, icount_bench_u256_shl, icount_bench_u256_shr + benchmarks = + icount_bench_u128_widen_mul, + icount_bench_u256_narrowing_div, + icount_bench_u256_add, + icount_bench_u256_sub, + icount_bench_u256_shl, + icount_bench_u256_shr ); #[library_benchmark] From 66e9c33dcb854428dbb83afcf4303af09f8e910c Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 5 Dec 2025 04:56:09 +0000 Subject: [PATCH 0304/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 864339abf952f07098dd82610256338520167d4a. --- 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 5c4de1da0312..45bf94eb4de4 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -3ff30e7eafc1da7104c3960187d17939172428ed +864339abf952f07098dd82610256338520167d4a From 1769b0b680788b87d06f2d5b3fcc14271990825a Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 5 Dec 2025 07:04:18 +0200 Subject: [PATCH 0305/3801] Handle lint attributes via hir-expand attr handling This avoids code duplication. --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 4 +- .../rust-analyzer/crates/hir/src/semantics.rs | 66 +++++++++- .../crates/ide-diagnostics/src/lib.rs | 119 ++++-------------- 3 files changed, 90 insertions(+), 99 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 2210bb79cd63..63da5a3a37cf 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -117,8 +117,8 @@ pub use crate::{ diagnostics::*, has_source::HasSource, semantics::{ - PathResolution, PathResolutionPerNs, Semantics, SemanticsImpl, SemanticsScope, TypeInfo, - VisibleTraits, + LintAttr, PathResolution, PathResolutionPerNs, Semantics, SemanticsImpl, SemanticsScope, + TypeInfo, VisibleTraits, }, }; diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 82e60bff5e96..195fafad5cbc 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -39,8 +39,8 @@ use smallvec::{SmallVec, smallvec}; use span::{FileId, SyntaxContext}; use stdx::{TupleExt, always}; use syntax::{ - AstNode, AstToken, Direction, SyntaxKind, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, - TextSize, + AstNode, AstToken, Direction, SmolStr, SmolStrBuilder, SyntaxElement, SyntaxKind, SyntaxNode, + SyntaxNodePtr, SyntaxToken, T, TextRange, TextSize, algo::skip_trivia_token, ast::{self, HasAttrs as _, HasGenericParams}, }; @@ -174,6 +174,15 @@ impl<'db, DB: ?Sized> ops::Deref for Semantics<'db, DB> { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum LintAttr { + Allow, + Expect, + Warn, + Deny, + Forbid, +} + // Note: while this variant of `Semantics<'_, _>` might seem unused, as it does not // find actual use within the rust-analyzer project itself, it exists to enable the use // within e.g. tracked salsa functions in third-party crates that build upon `ra_ap_hir`. @@ -254,6 +263,59 @@ impl Semantics<'_, DB> { .filter_map(ast::NameLike::cast) } + pub fn lint_attrs( + &self, + krate: Crate, + item: ast::AnyHasAttrs, + ) -> impl Iterator { + let mut cfg_options = None; + let cfg_options = || *cfg_options.get_or_insert_with(|| krate.id.cfg_options(self.db)); + let mut result = Vec::new(); + hir_expand::attrs::expand_cfg_attr::( + ast::attrs_including_inner(&item), + cfg_options, + |attr, _, _, _| { + let hir_expand::attrs::Meta::TokenTree { path, tt } = attr else { + return ControlFlow::Continue(()); + }; + if path.segments.len() != 1 { + return ControlFlow::Continue(()); + } + let lint_attr = match path.segments[0].text() { + "allow" => LintAttr::Allow, + "expect" => LintAttr::Expect, + "warn" => LintAttr::Warn, + "deny" => LintAttr::Deny, + "forbid" => LintAttr::Forbid, + _ => return ControlFlow::Continue(()), + }; + let mut lint = SmolStrBuilder::new(); + for token in + tt.syntax().children_with_tokens().filter_map(SyntaxElement::into_token) + { + match token.kind() { + T![:] | T![::] => lint.push_str(token.text()), + kind if kind.is_any_identifier() => lint.push_str(token.text()), + T![,] => { + let lint = mem::replace(&mut lint, SmolStrBuilder::new()).finish(); + if !lint.is_empty() { + result.push((lint_attr, lint)); + } + } + _ => {} + } + } + let lint = lint.finish(); + if !lint.is_empty() { + result.push((lint_attr, lint)); + } + + ControlFlow::Continue(()) + }, + ); + result.into_iter() + } + pub fn resolve_range_pat(&self, range_pat: &ast::RangePat) -> Option { self.imp.resolve_range_pat(range_pat).map(Struct::from) } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index 41ae85445569..c7827f13f409 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -83,9 +83,8 @@ mod handlers { #[cfg(test)] mod tests; -use std::{iter, sync::LazyLock}; +use std::sync::LazyLock; -use either::Either; use hir::{ Crate, DisplayTarget, InFile, Semantics, db::ExpandDatabase, diagnostics::AnyDiagnostic, }; @@ -97,11 +96,9 @@ use ide_db::{ imports::insert_use::InsertUseConfig, label::Label, source_change::SourceChange, - syntax_helpers::node_ext::parse_tt_as_comma_sep_paths, }; -use itertools::Itertools; use syntax::{ - AstPtr, Edition, NodeOrToken, SmolStr, SyntaxKind, SyntaxNode, SyntaxNodePtr, T, TextRange, + AstPtr, Edition, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ast::{self, AstNode}, }; @@ -483,7 +480,7 @@ pub fn semantic_diagnostics( // The edition isn't accurate (each diagnostics may have its own edition due to macros), // but it's okay as it's only being used for error recovery. - handle_lints(&ctx.sema, &mut lints, editioned_file_id.edition(db)); + handle_lints(&ctx.sema, krate, &mut lints, editioned_file_id.edition(db)); res.retain(|d| d.severity != Severity::Allow); @@ -591,6 +588,7 @@ fn build_lints_map( fn handle_lints( sema: &Semantics<'_, RootDatabase>, + krate: hir::Crate, diagnostics: &mut [(InFile, &mut Diagnostic)], edition: Edition, ) { @@ -606,10 +604,10 @@ fn handle_lints( } let mut diag_severity = - lint_severity_at(sema, node, &lint_groups(&diag.code, edition), edition); + lint_severity_at(sema, krate, node, &lint_groups(&diag.code, edition)); if let outline_diag_severity @ Some(_) = - find_outline_mod_lint_severity(sema, node, diag, edition) + find_outline_mod_lint_severity(sema, krate, node, diag, edition) { diag_severity = outline_diag_severity; } @@ -632,6 +630,7 @@ fn default_lint_severity(lint: &Lint, edition: Edition) -> Severity { fn find_outline_mod_lint_severity( sema: &Semantics<'_, RootDatabase>, + krate: hir::Crate, node: &InFile, diag: &Diagnostic, edition: Edition, @@ -648,8 +647,8 @@ fn find_outline_mod_lint_severity( let lint_groups = lint_groups(&diag.code, edition); lint_attrs( sema, - &ast::AnyHasAttrs::cast(module_source_file.value).expect("SourceFile always has attrs"), - edition, + krate, + ast::AnyHasAttrs::cast(module_source_file.value).expect("SourceFile always has attrs"), ) .for_each(|(lint, severity)| { if lint_groups.contains(&lint) { @@ -661,106 +660,36 @@ fn find_outline_mod_lint_severity( fn lint_severity_at( sema: &Semantics<'_, RootDatabase>, + krate: hir::Crate, node: &InFile, lint_groups: &LintGroups, - edition: Edition, ) -> Option { node.value .ancestors() .filter_map(ast::AnyHasAttrs::cast) .find_map(|ancestor| { - lint_attrs(sema, &ancestor, edition) + lint_attrs(sema, krate, ancestor) .find_map(|(lint, severity)| lint_groups.contains(&lint).then_some(severity)) }) .or_else(|| { - lint_severity_at(sema, &sema.find_parent_file(node.file_id)?, lint_groups, edition) + lint_severity_at(sema, krate, &sema.find_parent_file(node.file_id)?, lint_groups) }) } // FIXME: Switch this to analysis' `expand_cfg_attr`. -fn lint_attrs<'a>( - sema: &'a Semantics<'a, RootDatabase>, - ancestor: &'a ast::AnyHasAttrs, - edition: Edition, -) -> impl Iterator + 'a { - ast::attrs_including_inner(ancestor) - .filter_map(|attr| { - attr.as_simple_call().and_then(|(name, value)| match &*name { - "allow" | "expect" => Some(Either::Left(iter::once((Severity::Allow, value)))), - "warn" => Some(Either::Left(iter::once((Severity::Warning, value)))), - "forbid" | "deny" => Some(Either::Left(iter::once((Severity::Error, value)))), - "cfg_attr" => { - let mut lint_attrs = Vec::new(); - cfg_attr_lint_attrs(sema, &value, &mut lint_attrs); - Some(Either::Right(lint_attrs.into_iter())) - } - _ => None, - }) - }) - .flatten() - .flat_map(move |(severity, lints)| { - parse_tt_as_comma_sep_paths(lints, edition).into_iter().flat_map(move |lints| { - // Rejoin the idents with `::`, so we have no spaces in between. - lints.into_iter().map(move |lint| { - ( - lint.segments().filter_map(|segment| segment.name_ref()).join("::").into(), - severity, - ) - }) - }) - }) -} - -fn cfg_attr_lint_attrs( +fn lint_attrs( sema: &Semantics<'_, RootDatabase>, - value: &ast::TokenTree, - lint_attrs: &mut Vec<(Severity, ast::TokenTree)>, -) { - let prev_len = lint_attrs.len(); - - let mut iter = value.token_trees_and_tokens().filter(|it| match it { - NodeOrToken::Node(_) => true, - NodeOrToken::Token(it) => !it.kind().is_trivia(), - }); - - // Skip the condition. - for value in &mut iter { - if value.as_token().is_some_and(|it| it.kind() == T![,]) { - break; - } - } - - while let Some(value) = iter.next() { - if let Some(token) = value.as_token() - && token.kind() == SyntaxKind::IDENT - { - let severity = match token.text() { - "allow" | "expect" => Some(Severity::Allow), - "warn" => Some(Severity::Warning), - "forbid" | "deny" => Some(Severity::Error), - "cfg_attr" => { - if let Some(NodeOrToken::Node(value)) = iter.next() { - cfg_attr_lint_attrs(sema, &value, lint_attrs); - } - None - } - _ => None, - }; - if let Some(severity) = severity { - let lints = iter.next(); - if let Some(NodeOrToken::Node(lints)) = lints { - lint_attrs.push((severity, lints)); - } - } - } - } - - if prev_len != lint_attrs.len() - && let Some(false) | None = sema.check_cfg_attr(value) - { - // Discard the attributes when the condition is false. - lint_attrs.truncate(prev_len); - } + krate: hir::Crate, + ancestor: ast::AnyHasAttrs, +) -> impl Iterator { + sema.lint_attrs(krate, ancestor).map(|(lint_attr, lint)| { + let severity = match lint_attr { + hir::LintAttr::Allow | hir::LintAttr::Expect => Severity::Allow, + hir::LintAttr::Warn => Severity::Warning, + hir::LintAttr::Deny | hir::LintAttr::Forbid => Severity::Error, + }; + (lint, severity) + }) } #[derive(Debug)] From c8f0d643c0d154158d22dde5a9a50fe42c70ccad Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 5 Dec 2025 04:17:14 -0500 Subject: [PATCH 0306/3801] bench: Add `strip = false` to the bench profile This is already the default but gungraun requires it, so make it explicit. --- library/compiler-builtins/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/library/compiler-builtins/Cargo.toml b/library/compiler-builtins/Cargo.toml index 6b4e691a1ebe..8501f4e630b5 100644 --- a/library/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/Cargo.toml @@ -53,3 +53,4 @@ lto = "fat" [profile.bench] # Required for gungraun debug = true +strip = false From b09903f791eb849dfdd515c4086a10be658b5c1b Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 5 Dec 2025 04:46:20 -0500 Subject: [PATCH 0307/3801] bench: Disambiguate benchmark names in `mem_icount` The latest release of gungraun uses global symbols to register tests. Since it doesn't know about modules, these conflict. Add the module name so this isn't an issue, but keep the modules around because they are useful for organization. --- .../builtins-test/benches/mem_icount.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/library/compiler-builtins/builtins-test/benches/mem_icount.rs b/library/compiler-builtins/builtins-test/benches/mem_icount.rs index 966ceea86d8d..37595e825843 100644 --- a/library/compiler-builtins/builtins-test/benches/mem_icount.rs +++ b/library/compiler-builtins/builtins-test/benches/mem_icount.rs @@ -108,7 +108,7 @@ mod mcpy { ], setup = setup, )] - fn bench((len, mut dst, src): (usize, AlignedSlice, AlignedSlice)) { + fn bench_cpy((len, mut dst, src): (usize, AlignedSlice, AlignedSlice)) { unsafe { black_box(memcpy( black_box(dst.as_mut_ptr()), @@ -118,7 +118,7 @@ mod mcpy { } } - library_benchmark_group!(name = memcpy; benchmarks = bench); + library_benchmark_group!(name = memcpy; benchmarks = bench_cpy); } mod mset { @@ -157,7 +157,7 @@ mod mset { ], setup = setup, )] - fn bench((len, mut dst): (usize, AlignedSlice)) { + fn bench_set((len, mut dst): (usize, AlignedSlice)) { unsafe { black_box(memset( black_box(dst.as_mut_ptr()), @@ -167,7 +167,7 @@ mod mset { } } - library_benchmark_group!(name = memset; benchmarks = bench); + library_benchmark_group!(name = memset; benchmarks = bench_set); } mod mcmp { @@ -225,7 +225,7 @@ mod mcmp { ], setup = setup )] - fn bench((len, mut dst, src): (usize, AlignedSlice, AlignedSlice)) { + fn bench_cmp((len, mut dst, src): (usize, AlignedSlice, AlignedSlice)) { unsafe { black_box(memcmp( black_box(dst.as_mut_ptr()), @@ -235,7 +235,7 @@ mod mcmp { } } - library_benchmark_group!(name = memcmp; benchmarks = bench); + library_benchmark_group!(name = memcmp; benchmarks = bench_cmp); } mod mmove { @@ -384,7 +384,7 @@ mod mmove { ], setup = setup_forward )] - fn forward((len, spread, mut buf): (usize, usize, AlignedSlice)) { + fn forward_move((len, spread, mut buf): (usize, usize, AlignedSlice)) { // Test moving from the start of the buffer toward the end unsafe { black_box(memmove( @@ -478,7 +478,7 @@ mod mmove { ], setup = setup_backward )] - fn backward((len, spread, mut buf): (usize, usize, AlignedSlice)) { + fn backward_move((len, spread, mut buf): (usize, usize, AlignedSlice)) { // Test moving from the end of the buffer toward the start unsafe { black_box(memmove( @@ -489,7 +489,7 @@ mod mmove { } } - library_benchmark_group!(name = memmove; benchmarks = forward, backward); + library_benchmark_group!(name = memmove; benchmarks = forward_move, backward_move); } use mcmp::memcmp; From 15d03decfb63a5a325185b20bd3aa5481e652457 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 5 Dec 2025 04:59:08 -0500 Subject: [PATCH 0308/3801] ci: bench: Enable all `icount` benches in CI So far we haven't been running the `mem_icount` benches in CI, but this would be useful. Use a glob pattern for the test so this and future icount benchmarks all get run. --- library/compiler-builtins/ci/bench-icount.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/ci/bench-icount.sh b/library/compiler-builtins/ci/bench-icount.sh index 56aa1df07e46..1d7d23dcce45 100755 --- a/library/compiler-builtins/ci/bench-icount.sh +++ b/library/compiler-builtins/ci/bench-icount.sh @@ -25,7 +25,7 @@ tag="$(echo "$target" | cut -d'-' -f1)" # Run benchmarks once function run_icount_benchmarks() { cargo_args=( - "--bench" "icount" + "--bench" "*icount*" "--no-default-features" "--features" "unstable,unstable-float,icount" ) From e2d9d4981e6545ed28aa81452e864ceac5100020 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 5 Dec 2025 12:53:10 +0200 Subject: [PATCH 0309/3801] Do not create stale expressions in body lowering --- .../crates/hir-def/src/expr_store/lower.rs | 169 ++++++++---------- .../src/handlers/mutability_errors.rs | 6 +- 2 files changed, 75 insertions(+), 100 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 26a50b53251f..77930c49ce9a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -434,7 +434,7 @@ pub struct ExprCollector<'db> { current_try_block_label: Option, label_ribs: Vec, - current_binding_owner: Option, + unowned_bindings: Vec, awaitable_context: Option, } @@ -536,7 +536,7 @@ impl<'db> ExprCollector<'db> { current_try_block_label: None, is_lowering_coroutine: false, label_ribs: Vec::new(), - current_binding_owner: None, + unowned_bindings: Vec::new(), awaitable_context: None, current_block_legacy_macro_defs_count: FxHashMap::default(), outer_impl_trait: false, @@ -1062,12 +1062,10 @@ impl<'db> ExprCollector<'db> { Some(ast::BlockModifier::Const(_)) => { self.with_label_rib(RibKind::Constant, |this| { this.with_awaitable_block(Awaitable::No("constant block"), |this| { - let (result_expr_id, prev_binding_owner) = - this.initialize_binding_owner(syntax_ptr); - let inner_expr = this.collect_block(e); - this.store.exprs[result_expr_id] = Expr::Const(inner_expr); - this.current_binding_owner = prev_binding_owner; - result_expr_id + this.with_binding_owner(|this| { + let inner_expr = this.collect_block(e); + this.alloc_expr(Expr::Const(inner_expr), syntax_ptr) + }) }) }) } @@ -1278,64 +1276,65 @@ impl<'db> ExprCollector<'db> { } } ast::Expr::ClosureExpr(e) => self.with_label_rib(RibKind::Closure, |this| { - let (result_expr_id, prev_binding_owner) = - this.initialize_binding_owner(syntax_ptr); - let mut args = Vec::new(); - let mut arg_types = Vec::new(); - if let Some(pl) = e.param_list() { - let num_params = pl.params().count(); - args.reserve_exact(num_params); - arg_types.reserve_exact(num_params); - for param in pl.params() { - let pat = this.collect_pat_top(param.pat()); - let type_ref = - param.ty().map(|it| this.lower_type_ref_disallow_impl_trait(it)); - args.push(pat); - arg_types.push(type_ref); + this.with_binding_owner(|this| { + let mut args = Vec::new(); + let mut arg_types = Vec::new(); + if let Some(pl) = e.param_list() { + let num_params = pl.params().count(); + args.reserve_exact(num_params); + arg_types.reserve_exact(num_params); + for param in pl.params() { + let pat = this.collect_pat_top(param.pat()); + let type_ref = + param.ty().map(|it| this.lower_type_ref_disallow_impl_trait(it)); + args.push(pat); + arg_types.push(type_ref); + } } - } - let ret_type = e - .ret_type() - .and_then(|r| r.ty()) - .map(|it| this.lower_type_ref_disallow_impl_trait(it)); + let ret_type = e + .ret_type() + .and_then(|r| r.ty()) + .map(|it| this.lower_type_ref_disallow_impl_trait(it)); - let prev_is_lowering_coroutine = mem::take(&mut this.is_lowering_coroutine); - let prev_try_block_label = this.current_try_block_label.take(); + let prev_is_lowering_coroutine = mem::take(&mut this.is_lowering_coroutine); + let prev_try_block_label = this.current_try_block_label.take(); - let awaitable = if e.async_token().is_some() { - Awaitable::Yes - } else { - Awaitable::No("non-async closure") - }; - let body = - this.with_awaitable_block(awaitable, |this| this.collect_expr_opt(e.body())); - - let closure_kind = if this.is_lowering_coroutine { - let movability = if e.static_token().is_some() { - Movability::Static + let awaitable = if e.async_token().is_some() { + Awaitable::Yes } else { - Movability::Movable + Awaitable::No("non-async closure") }; - ClosureKind::Coroutine(movability) - } else if e.async_token().is_some() { - ClosureKind::Async - } else { - ClosureKind::Closure - }; - let capture_by = - if e.move_token().is_some() { CaptureBy::Value } else { CaptureBy::Ref }; - this.is_lowering_coroutine = prev_is_lowering_coroutine; - this.current_binding_owner = prev_binding_owner; - this.current_try_block_label = prev_try_block_label; - this.store.exprs[result_expr_id] = Expr::Closure { - args: args.into(), - arg_types: arg_types.into(), - ret_type, - body, - closure_kind, - capture_by, - }; - result_expr_id + let body = this + .with_awaitable_block(awaitable, |this| this.collect_expr_opt(e.body())); + + let closure_kind = if this.is_lowering_coroutine { + let movability = if e.static_token().is_some() { + Movability::Static + } else { + Movability::Movable + }; + ClosureKind::Coroutine(movability) + } else if e.async_token().is_some() { + ClosureKind::Async + } else { + ClosureKind::Closure + }; + let capture_by = + if e.move_token().is_some() { CaptureBy::Value } else { CaptureBy::Ref }; + this.is_lowering_coroutine = prev_is_lowering_coroutine; + this.current_try_block_label = prev_try_block_label; + this.alloc_expr( + Expr::Closure { + args: args.into(), + arg_types: arg_types.into(), + ret_type, + body, + closure_kind, + capture_by, + }, + syntax_ptr, + ) + }) }), ast::Expr::BinExpr(e) => { let op = e.op_kind(); @@ -1371,11 +1370,7 @@ impl<'db> ExprCollector<'db> { let initializer = self.collect_expr_opt(initializer); let repeat = self.with_label_rib(RibKind::Constant, |this| { if let Some(repeat) = repeat { - let syntax_ptr = AstPtr::new(&repeat); - this.collect_as_a_binding_owner_bad( - |this| this.collect_expr(repeat), - syntax_ptr, - ) + this.with_binding_owner(|this| this.collect_expr(repeat)) } else { this.missing_expr() } @@ -1632,31 +1627,13 @@ impl<'db> ExprCollector<'db> { } } - fn initialize_binding_owner( - &mut self, - syntax_ptr: AstPtr, - ) -> (ExprId, Option) { - let result_expr_id = self.alloc_expr(Expr::Missing, syntax_ptr); - let prev_binding_owner = self.current_binding_owner.take(); - self.current_binding_owner = Some(result_expr_id); - - (result_expr_id, prev_binding_owner) - } - - /// FIXME: This function is bad. It will produce a dangling `Missing` expr which wastes memory. Currently - /// it is used only for const blocks and repeat expressions, which are also hacky and ideally should have - /// their own body. Don't add more usage for this function so that we can remove this function after - /// separating those bodies. - fn collect_as_a_binding_owner_bad( - &mut self, - job: impl FnOnce(&mut ExprCollector<'_>) -> ExprId, - syntax_ptr: AstPtr, - ) -> ExprId { - let (id, prev_owner) = self.initialize_binding_owner(syntax_ptr); - let tmp = job(self); - self.store.exprs[id] = mem::replace(&mut self.store.exprs[tmp], Expr::Missing); - self.current_binding_owner = prev_owner; - id + fn with_binding_owner(&mut self, create_expr: impl FnOnce(&mut Self) -> ExprId) -> ExprId { + let prev_unowned_bindings_len = self.unowned_bindings.len(); + let expr_id = create_expr(self); + for binding in self.unowned_bindings.drain(prev_unowned_bindings_len..) { + self.store.binding_owners.insert(binding, expr_id); + } + expr_id } /// Desugar `try { ; }` into `': { ; ::std::ops::Try::from_output() }`, @@ -2368,11 +2345,7 @@ impl<'db> ExprCollector<'db> { ast::Pat::ConstBlockPat(const_block_pat) => { if let Some(block) = const_block_pat.block_expr() { let expr_id = self.with_label_rib(RibKind::Constant, |this| { - let syntax_ptr = AstPtr::new(&block.clone().into()); - this.collect_as_a_binding_owner_bad( - |this| this.collect_block(block), - syntax_ptr, - ) + this.with_binding_owner(|this| this.collect_block(block)) }); Pat::ConstBlock(expr_id) } else { @@ -3376,9 +3349,7 @@ impl ExprCollector<'_> { hygiene: HygieneId, ) -> BindingId { let binding = self.store.bindings.alloc(Binding { name, mode, problems: None, hygiene }); - if let Some(owner) = self.current_binding_owner { - self.store.binding_owners.insert(binding, owner); - } + self.unowned_bindings.push(binding); binding } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs index 18280a4addec..2887a32825db 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs @@ -995,6 +995,10 @@ fn fn_once(mut x: impl FnOnce(u8) -> u8) -> u8 { } "#, ); + // FIXME: There should be no "unused variable" here, and there should be a mutability error, + // but our MIR infra is horribly broken and due to the order in which expressions are lowered + // there is no `StorageLive` for `x` in the closure (in fact, `x` should not even be a variable + // of the closure, the environment should be, but as I said, our MIR infra is horribly broken). check_diagnostics( r#" //- minicore: copy, fn @@ -1003,8 +1007,8 @@ fn f() { || { || { let x = 2; + // ^ 💡 warn: unused variable || { || { x = 5; } } - //^^^^^ 💡 error: cannot mutate immutable variable `x` } } }; From 5f397632e32856ca011bae4c9ffb76dcb0ecaa1c Mon Sep 17 00:00:00 2001 From: quaternic <57393910+quaternic@users.noreply.github.com> Date: Tue, 12 Aug 2025 18:08:22 +0300 Subject: [PATCH 0310/3801] require some basic operators in trait DInt --- .../libm/src/math/support/int_traits.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/library/compiler-builtins/libm/src/math/support/int_traits.rs b/library/compiler-builtins/libm/src/math/support/int_traits.rs index f1aa1e5b9b4d..55b609affd2e 100644 --- a/library/compiler-builtins/libm/src/math/support/int_traits.rs +++ b/library/compiler-builtins/libm/src/math/support/int_traits.rs @@ -296,7 +296,14 @@ int_impl!(i128, u128); /// Trait for integers twice the bit width of another integer. This is implemented for all /// primitives except for `u8`, because there is not a smaller primitive. -pub trait DInt: MinInt { +pub trait DInt: + MinInt + + ops::Add + + ops::Sub + + ops::Shl + + ops::Shr + + Ord +{ /// Integer that is half the bit width of the integer this trait is implemented for type H: HInt; From 3a93154addb80079317b43ef9b41d8420ca3a053 Mon Sep 17 00:00:00 2001 From: quaternic <57393910+quaternic@users.noreply.github.com> Date: Tue, 12 Aug 2025 18:11:04 +0300 Subject: [PATCH 0311/3801] Implement accelerated computation of (x << e) % y in unsigned integers --- .../math/support/int_traits/narrowing_div.rs | 1 - .../libm/src/math/support/mod.rs | 3 + .../libm/src/math/support/modular.rs | 301 ++++++++++++++++++ 3 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 library/compiler-builtins/libm/src/math/support/modular.rs diff --git a/library/compiler-builtins/libm/src/math/support/int_traits/narrowing_div.rs b/library/compiler-builtins/libm/src/math/support/int_traits/narrowing_div.rs index 3da0843cc540..e76fc5ae9f4c 100644 --- a/library/compiler-builtins/libm/src/math/support/int_traits/narrowing_div.rs +++ b/library/compiler-builtins/libm/src/math/support/int_traits/narrowing_div.rs @@ -7,7 +7,6 @@ use crate::support::{CastInto, DInt, HInt, Int, MinInt, u256}; /// This is the inverse of widening multiplication: /// - for any `x` and nonzero `y`: `x.widen_mul(y).checked_narrowing_div_rem(y) == Some((x, 0))`, /// - and for any `r in 0..y`: `x.carrying_mul(y, r).checked_narrowing_div_rem(y) == Some((x, r))`, -#[allow(dead_code)] pub trait NarrowingDiv: DInt + MinInt { /// Computes `(self / n, self % n))` /// diff --git a/library/compiler-builtins/libm/src/math/support/mod.rs b/library/compiler-builtins/libm/src/math/support/mod.rs index 7b529eb760b7..f35b9de3ed5c 100644 --- a/library/compiler-builtins/libm/src/math/support/mod.rs +++ b/library/compiler-builtins/libm/src/math/support/mod.rs @@ -8,6 +8,7 @@ pub(crate) mod feature_detect; mod float_traits; pub mod hex_float; mod int_traits; +mod modular; #[allow(unused_imports)] pub use big::{i256, u256}; @@ -30,6 +31,8 @@ pub use hex_float::hf128; pub use hex_float::{hf32, hf64}; #[allow(unused_imports)] pub use int_traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt, NarrowingDiv}; +#[allow(unused_imports)] +pub use modular::linear_mul_reduction; /// Hint to the compiler that the current path is cold. pub fn cold_path() { diff --git a/library/compiler-builtins/libm/src/math/support/modular.rs b/library/compiler-builtins/libm/src/math/support/modular.rs new file mode 100644 index 000000000000..dbf1f0513a0d --- /dev/null +++ b/library/compiler-builtins/libm/src/math/support/modular.rs @@ -0,0 +1,301 @@ +/* SPDX-License-Identifier: MIT OR Apache-2.0 */ + +//! To keep the equations somewhat concise, the following conventions are used: +//! - all integer operations are in the mathematical sense, without overflow +//! - concatenation means multiplication: `2xq = 2 * x * q` +//! - `R = (1 << U::BITS)` is the modulus of wrapping arithmetic in `U` + +use crate::support::int_traits::NarrowingDiv; +use crate::support::{DInt, HInt, Int}; + +/// Compute the remainder `(x << e) % y` with unbounded integers. +/// Requires `x < 2y` and `y.leading_zeros() >= 2` +#[allow(dead_code)] +pub fn linear_mul_reduction(x: U, mut e: u32, mut y: U) -> U +where + U: HInt + Int, + U::D: NarrowingDiv, +{ + assert!(y <= U::MAX >> 2); + assert!(x < (y << 1)); + let _0 = U::ZERO; + let _1 = U::ONE; + + // power of two divisors + if (y & (y - _1)).is_zero() { + if e < U::BITS { + // shift and only keep low bits + return (x << e) & (y - _1); + } else { + // would shift out all the bits + return _0; + } + } + + // Use the identity `(x << e) % y == ((x << (e + s)) % (y << s)) >> s` + // to shift the divisor so it has exactly two leading zeros to satisfy + // the precondition of `Reducer::new` + let s = y.leading_zeros() - 2; + e += s; + y <<= s; + + // `m: Reducer` keeps track of the remainder `x` in a form that makes it + // very efficient to do `x <<= k` modulo `y` for integers `k < U::BITS` + let mut m = Reducer::new(x, y); + + // Use the faster special case with constant `k == U::BITS - 1` while we can + while e >= U::BITS - 1 { + m.word_reduce(); + e -= U::BITS - 1; + } + // Finish with the variable shift operation + m.shift_reduce(e); + + // The partial remainder is in `[0, 2y)` ... + let r = m.partial_remainder(); + // ... so check and correct, and compensate for the earlier shift. + r.checked_sub(y).unwrap_or(r) >> s +} + +/// Helper type for computing the reductions. The implementation has a number +/// of seemingly weird choices, but everything is aimed at streamlining +/// `Reducer::word_reduce` into its current form. +/// +/// Implicitly contains: +/// n in (R/8, R/4) +/// x in [0, 2n) +/// The value of `n` is fixed for a given `Reducer`, +/// but the value of `x` is modified by the methods. +#[derive(Debug, Clone, PartialEq, Eq)] +struct Reducer { + // m = 2n + m: U, + // q = (RR/2) / m + // r = (RR/2) % m + // Then RR/2 = qm + r, where `0 <= r < m` + // The value `q` is only needed during construction, so isn't saved. + r: U, + // The value `x` is implicitly stored as `2 * q * x`: + _2xq: U::D, +} + +impl Reducer +where + U: HInt, + U: Int, +{ + /// Construct a reducer for `(x << _) mod n`. + /// + /// Requires `R/8 < n < R/4` and `x < 2n`. + fn new(x: U, n: U) -> Self + where + U::D: NarrowingDiv, + { + let _1 = U::ONE; + assert!(n > (_1 << (U::BITS - 3))); + assert!(n < (_1 << (U::BITS - 2))); + let m = n << 1; + assert!(x < m); + + // We need to compute the parameters + // `q = (RR/2) / m` + // `r = (RR/2) % m` + + // Since `m` is in `(R/4, R/2)`, the quotient `q` is in `[R, 2R)`, and + // it would overflow in `U` if computed directly. Instead, we compute + // `f = q - R`, which is in `[0, R)`. To do so, we simply subtract `Rm` + // from the dividend, which doesn't change the remainder: + // `f = R(R/2 - m) / m` + // `r = R(R/2 - m) % m` + let dividend = ((_1 << (U::BITS - 1)) - m).widen_hi(); + let (f, r) = dividend.checked_narrowing_div_rem(m).unwrap(); + + // As `x < m`, `xq < qm <= RR/2` + // Thus `2xq = 2xR + 2xf` does not overflow in `U::D`. + let _2x = x + x; + let _2xq = _2x.widen_hi() + _2x.widen_mul(f); + Self { m, r, _2xq } + } + + /// Extract the current remainder `x` in the range `[0, 2n)` + fn partial_remainder(&self) -> U { + // `RR/2 = qm + r`, where `0 <= r < m` + // `2xq = uR + v`, where `0 <= v < R` + + // The goal is to extract the current value of `x` from the value `2xq` + // that we actually have. A bit simplified, we could multiply it by `m` + // to obtain `2xqm == 2x(RR/2 - r) == xRR - 2xr`, where `2xr < RR`. + // We could just round that up to the next multiple of `RR` to get `x`, + // but we can avoid having to multiply the full double-wide `2xq` by + // making a couple of adjustments: + + // First, let's only use the high half `u` for the product, and + // include an additional error term due to the truncation: + // `mu = xR - (2xr + mv)/R` + + // Next, show bounds for the error term + // `0 <= mv < mR` follows from `0 <= v < R` + // `0 <= 2xr < mR` follows from `0 <= x < m < R/2` and `0 <= r < m` + // Adding those together, we have: + // `0 <= (mv + 2xr)/R < 2m` + // Which also implies: + // `0 < 2m - (mv + 2xr)/R <= 2m < R` + + // For that reason, we can use `u + 2` as the factor to obtain + // `m(u + 2) = xR + (2m - (mv + 2xr)/R)` + // By the previous inequality, the second term fits neatly in the lower + // half, so we get exactly `x` as the high half. + let u = self._2xq.hi(); + let _2 = U::ONE + U::ONE; + self.m.widen_mul(u + _2).hi() + + // Additionally, we should ensure that `u + 2` cannot overflow: + // Since `x < m` and `2qm <= RR`, + // `2xq <= 2q(m-1) <= RR - 2q` + // As we also have `q > R`, + // `2xq < RR - 2R` + // which is sufficient. + } + + /// Replace the remainder `x` with `(x << k) - un`, + /// for a suitable quotient `u`, which is returned. + /// + /// Requires that `k < U::BITS`. + fn shift_reduce(&mut self, k: u32) -> U { + assert!(k < U::BITS); + + // First, split the shifted value: + // `2xq << k = aRR/2 + b`, where `0 <= b < RR/2` + let a = self._2xq.hi() >> (U::BITS - 1 - k); + let (low, high) = (self._2xq << k).lo_hi(); + let b = U::D::from_lo_hi(low, high & (U::MAX >> 1)); + + // Then, subtract `2anq = aqm`: + // ``` + // (2xq << k) - aqm + // = aRR/2 + b - aqm + // = a(RR/2 - qm) + b + // = ar + b + // ``` + self._2xq = a.widen_mul(self.r) + b; + a + + // Since `a` is at most the high half of `2xq`, we have + // `a + 2 < R` (shown above, in `partial_remainder`) + // Using that together with `b < RR/2` and `r < m < R/2`, + // we get `(a + 2)r + b < RR`, so + // `ar + b < RR - 2r = 2mq` + // which shows that the new remainder still satisfies `x < m`. + } + + // NB: `word_reduce()` is just the special case `shift_reduce(U::BITS - 1)` + // that optimizes especially well. The correspondence is that `a == u` and + // `b == (v >> 1).widen_hi()` + // + /// Replace the remainder `x` with `x(R/2) - un`, + /// for a suitable quotient `u`, which is returned. + fn word_reduce(&mut self) -> U { + // To do so, we replace `2xq = uR + v` with + // ``` + // 2 * (x(R/2) - un) * q + // = xqR - 2unq + // = xqR - uqm + // = uRR/2 + vR/2 - uRR/2 + ur + // = ur + (v/2)R + // ``` + let (v, u) = self._2xq.lo_hi(); + self._2xq = u.widen_mul(self.r) + U::widen_hi(v >> 1); + u + + // Additional notes: + // 1. As `v` is the low bits of `2xq`, it is even and can be halved. + // 2. The new remainder is `(xr + mv/2) / R` (see below) + // and since `v < R`, `r < m`, `x < m < R/2`, + // that is also strictly less than `m`. + // ``` + // (x(R/2) - un)R + // = xRR/2 - (m/2)uR + // = x(qm + r) - (m/2)(2xq - v) + // = xqm + xr - xqm + mv/2 + // = xr + mv/2 + // ``` + } +} + +#[cfg(test)] +mod test { + use crate::support::linear_mul_reduction; + use crate::support::modular::Reducer; + + #[test] + fn reducer_ops() { + for n in 33..=63_u8 { + for x in 0..2 * n { + let temp = Reducer::new(x, n); + let n = n as u32; + let x0 = temp.partial_remainder() as u32; + assert_eq!(x as u32, x0); + for k in 0..=7 { + let mut red = temp.clone(); + let u = red.shift_reduce(k) as u32; + let x1 = red.partial_remainder() as u32; + assert_eq!(x1, (x0 << k) - u * n); + assert!(x1 < 2 * n); + assert!((red._2xq as u32).is_multiple_of(2 * x1)); + + // `word_reduce` is equivalent to + // `shift_reduce(U::BITS - 1)` + if k == 7 { + let mut alt = temp.clone(); + let w = alt.word_reduce(); + assert_eq!(u, w as u32); + assert_eq!(alt, red); + } + } + } + } + } + #[test] + fn reduction_u8() { + for y in 1..64u8 { + for x in 0..2 * y { + let mut r = x % y; + for e in 0..100 { + assert_eq!(r, linear_mul_reduction(x, e, y)); + // maintain the correct expected remainder + r <<= 1; + if r >= y { + r -= y; + } + } + } + } + } + #[test] + fn reduction_u128() { + assert_eq!( + linear_mul_reduction::(17, 100, 123456789), + (17 << 100) % 123456789 + ); + + // power-of-two divisor + assert_eq!( + linear_mul_reduction(0xdead_beef, 100, 1_u128 << 116), + 0xbeef << 100 + ); + + let x = 10_u128.pow(37); + let y = 11_u128.pow(36); + assert!(x < y); + let mut r = x; + for e in 0..1000 { + assert_eq!(r, linear_mul_reduction(x, e, y)); + // maintain the correct expected remainder + r <<= 1; + if r >= y { + r -= y; + } + assert!(r != 0); + } + } +} From c2e43fffbc7936c33c68062f71892899bac23ba7 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Fri, 5 Dec 2025 16:15:20 +0900 Subject: [PATCH 0312/3801] moved tests --- src/tools/tidy/src/issues.txt | 1 - .../issue-3429.rs => closures/simple-capture-and-call.rs} | 0 .../issue-2642.rs => for-loop-while/nested-loop-break-unit.rs} | 0 .../issue-47673.rs => imports/duplicate-empty-imports.rs} | 0 .../{issues/issue-3500.rs => match/match-ref-option-pattern.rs} | 0 .../match-stack-overflow-72933-.rs} | 0 .../{issues/issue-3993.rs => privacy/private-item-simple-2.rs} | 0 .../issue-3993.stderr => privacy/private-item-simple-2.stderr} | 0 tests/ui/{issues/issue-47380.rs => str/str-add-operator-2.rs} | 0 .../{issues/issue-47380.stderr => str/str-add-operator-2.stderr} | 0 tests/ui/{issues/issue-47377.rs => str/str-add-operator.rs} | 0 .../{issues/issue-47377.stderr => str/str-add-operator.stderr} | 0 .../normalize-associated-type-in-where-clause.rs} | 0 .../{issues/issue-2151.rs => type/never-type-inference-fail.rs} | 0 .../issue-2151.stderr => type/never-type-inference-fail.stderr} | 0 tests/ui/typeck/{issue-10969.rs => non-function-call-error-2.rs} | 0 .../{issue-10969.stderr => non-function-call-error-2.stderr} | 0 .../{issues/issue-22468.rs => typeck/non-function-call-error.rs} | 0 .../issue-22468.stderr => typeck/non-function-call-error.stderr} | 0 19 files changed, 1 deletion(-) rename tests/ui/{issues/issue-3429.rs => closures/simple-capture-and-call.rs} (100%) rename tests/ui/{issues/issue-2642.rs => for-loop-while/nested-loop-break-unit.rs} (100%) rename tests/ui/{issues/issue-47673.rs => imports/duplicate-empty-imports.rs} (100%) rename tests/ui/{issues/issue-3500.rs => match/match-ref-option-pattern.rs} (100%) rename tests/ui/{issues/issue-72933-match-stack-overflow.rs => match/match-stack-overflow-72933-.rs} (100%) rename tests/ui/{issues/issue-3993.rs => privacy/private-item-simple-2.rs} (100%) rename tests/ui/{issues/issue-3993.stderr => privacy/private-item-simple-2.stderr} (100%) rename tests/ui/{issues/issue-47380.rs => str/str-add-operator-2.rs} (100%) rename tests/ui/{issues/issue-47380.stderr => str/str-add-operator-2.stderr} (100%) rename tests/ui/{issues/issue-47377.rs => str/str-add-operator.rs} (100%) rename tests/ui/{issues/issue-47377.stderr => str/str-add-operator.stderr} (100%) rename tests/ui/{issues/issue-51044.rs => traits/normalize-associated-type-in-where-clause.rs} (100%) rename tests/ui/{issues/issue-2151.rs => type/never-type-inference-fail.rs} (100%) rename tests/ui/{issues/issue-2151.stderr => type/never-type-inference-fail.stderr} (100%) rename tests/ui/typeck/{issue-10969.rs => non-function-call-error-2.rs} (100%) rename tests/ui/typeck/{issue-10969.stderr => non-function-call-error-2.stderr} (100%) rename tests/ui/{issues/issue-22468.rs => typeck/non-function-call-error.rs} (100%) rename tests/ui/{issues/issue-22468.stderr => typeck/non-function-call-error.stderr} (100%) diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 0f3f2f37ebf2..1500c82c411a 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -2892,7 +2892,6 @@ ui/typeck/issue-105946.rs ui/typeck/issue-106929.rs ui/typeck/issue-107087.rs ui/typeck/issue-107775.rs -ui/typeck/issue-10969.rs ui/typeck/issue-110017-format-into-help-deletes-macro.rs ui/typeck/issue-110052.rs ui/typeck/issue-112007-leaked-writeln-macro-internals.rs diff --git a/tests/ui/issues/issue-3429.rs b/tests/ui/closures/simple-capture-and-call.rs similarity index 100% rename from tests/ui/issues/issue-3429.rs rename to tests/ui/closures/simple-capture-and-call.rs diff --git a/tests/ui/issues/issue-2642.rs b/tests/ui/for-loop-while/nested-loop-break-unit.rs similarity index 100% rename from tests/ui/issues/issue-2642.rs rename to tests/ui/for-loop-while/nested-loop-break-unit.rs diff --git a/tests/ui/issues/issue-47673.rs b/tests/ui/imports/duplicate-empty-imports.rs similarity index 100% rename from tests/ui/issues/issue-47673.rs rename to tests/ui/imports/duplicate-empty-imports.rs diff --git a/tests/ui/issues/issue-3500.rs b/tests/ui/match/match-ref-option-pattern.rs similarity index 100% rename from tests/ui/issues/issue-3500.rs rename to tests/ui/match/match-ref-option-pattern.rs diff --git a/tests/ui/issues/issue-72933-match-stack-overflow.rs b/tests/ui/match/match-stack-overflow-72933-.rs similarity index 100% rename from tests/ui/issues/issue-72933-match-stack-overflow.rs rename to tests/ui/match/match-stack-overflow-72933-.rs diff --git a/tests/ui/issues/issue-3993.rs b/tests/ui/privacy/private-item-simple-2.rs similarity index 100% rename from tests/ui/issues/issue-3993.rs rename to tests/ui/privacy/private-item-simple-2.rs diff --git a/tests/ui/issues/issue-3993.stderr b/tests/ui/privacy/private-item-simple-2.stderr similarity index 100% rename from tests/ui/issues/issue-3993.stderr rename to tests/ui/privacy/private-item-simple-2.stderr diff --git a/tests/ui/issues/issue-47380.rs b/tests/ui/str/str-add-operator-2.rs similarity index 100% rename from tests/ui/issues/issue-47380.rs rename to tests/ui/str/str-add-operator-2.rs diff --git a/tests/ui/issues/issue-47380.stderr b/tests/ui/str/str-add-operator-2.stderr similarity index 100% rename from tests/ui/issues/issue-47380.stderr rename to tests/ui/str/str-add-operator-2.stderr diff --git a/tests/ui/issues/issue-47377.rs b/tests/ui/str/str-add-operator.rs similarity index 100% rename from tests/ui/issues/issue-47377.rs rename to tests/ui/str/str-add-operator.rs diff --git a/tests/ui/issues/issue-47377.stderr b/tests/ui/str/str-add-operator.stderr similarity index 100% rename from tests/ui/issues/issue-47377.stderr rename to tests/ui/str/str-add-operator.stderr diff --git a/tests/ui/issues/issue-51044.rs b/tests/ui/traits/normalize-associated-type-in-where-clause.rs similarity index 100% rename from tests/ui/issues/issue-51044.rs rename to tests/ui/traits/normalize-associated-type-in-where-clause.rs diff --git a/tests/ui/issues/issue-2151.rs b/tests/ui/type/never-type-inference-fail.rs similarity index 100% rename from tests/ui/issues/issue-2151.rs rename to tests/ui/type/never-type-inference-fail.rs diff --git a/tests/ui/issues/issue-2151.stderr b/tests/ui/type/never-type-inference-fail.stderr similarity index 100% rename from tests/ui/issues/issue-2151.stderr rename to tests/ui/type/never-type-inference-fail.stderr diff --git a/tests/ui/typeck/issue-10969.rs b/tests/ui/typeck/non-function-call-error-2.rs similarity index 100% rename from tests/ui/typeck/issue-10969.rs rename to tests/ui/typeck/non-function-call-error-2.rs diff --git a/tests/ui/typeck/issue-10969.stderr b/tests/ui/typeck/non-function-call-error-2.stderr similarity index 100% rename from tests/ui/typeck/issue-10969.stderr rename to tests/ui/typeck/non-function-call-error-2.stderr diff --git a/tests/ui/issues/issue-22468.rs b/tests/ui/typeck/non-function-call-error.rs similarity index 100% rename from tests/ui/issues/issue-22468.rs rename to tests/ui/typeck/non-function-call-error.rs diff --git a/tests/ui/issues/issue-22468.stderr b/tests/ui/typeck/non-function-call-error.stderr similarity index 100% rename from tests/ui/issues/issue-22468.stderr rename to tests/ui/typeck/non-function-call-error.stderr From d6db951b22dc3deb48a637aca54c5bb0a3db4795 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 5 Dec 2025 12:14:03 +0100 Subject: [PATCH 0313/3801] only run `pass-by-value-abi` on 64-bit windows the 32-bit variant differs only in the alignment/size, and I can't test it locally --- tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr | 2 +- tests/ui/c-variadic/pass-by-value-abi.rs | 3 ++- tests/ui/c-variadic/pass-by-value-abi.win.stderr | 2 +- tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr | 6 +++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr index fe11c4288618..a86b28d98ecc 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr @@ -71,7 +71,7 @@ error: fn_abi_of(take_va_list) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/pass-by-value-abi.rs:26:1 + --> $DIR/pass-by-value-abi.rs:27:1 | LL | pub extern "C" fn take_va_list(_: VaList<'_>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/c-variadic/pass-by-value-abi.rs b/tests/ui/c-variadic/pass-by-value-abi.rs index b65442af2472..1e3935067cc2 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.rs +++ b/tests/ui/c-variadic/pass-by-value-abi.rs @@ -12,9 +12,10 @@ //@ [aarch64] ignore-windows //@ [aarch64] ignore-apple //@ [aarch64] ignore-uefi -// Windows dosen't use `#[rustc_pass_indirectly_in_non_rustic_abis]` and is tested in CI, so is here +// Windows doesn't use `#[rustc_pass_indirectly_in_non_rustic_abis]` and is tested in CI, so is here // for comparison. //@ [win] only-windows +//@ [win] only-x86_64 #![feature(rustc_attrs, c_variadic)] #![crate_type = "lib"] diff --git a/tests/ui/c-variadic/pass-by-value-abi.win.stderr b/tests/ui/c-variadic/pass-by-value-abi.win.stderr index e84430859e02..8ff93961f667 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.win.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.win.stderr @@ -74,7 +74,7 @@ error: fn_abi_of(take_va_list) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/pass-by-value-abi.rs:26:1 + --> $DIR/pass-by-value-abi.rs:27:1 | LL | pub extern "C" fn take_va_list(_: VaList<'_>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr index 73f1ccd5992a..aafe89d59e33 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr @@ -71,7 +71,7 @@ error: fn_abi_of(take_va_list) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/pass-by-value-abi.rs:26:1 + --> $DIR/pass-by-value-abi.rs:27:1 | LL | pub extern "C" fn take_va_list(_: VaList<'_>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -151,7 +151,7 @@ error: fn_abi_of(take_va_list_sysv64) = FnAbi { ), can_unwind: false, } - --> $DIR/pass-by-value-abi.rs:36:1 + --> $DIR/pass-by-value-abi.rs:37:1 | LL | pub extern "sysv64" fn take_va_list_sysv64(_: VaList<'_>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ error: fn_abi_of(take_va_list_win64) = FnAbi { ), can_unwind: false, } - --> $DIR/pass-by-value-abi.rs:43:1 + --> $DIR/pass-by-value-abi.rs:44:1 | LL | pub extern "win64" fn take_va_list_win64(_: VaList<'_>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 1b396d7b7beb1b53dabe91dfc417d16b96c7671e Mon Sep 17 00:00:00 2001 From: Young-Flash Date: Fri, 5 Dec 2025 20:27:30 +0800 Subject: [PATCH 0314/3801] minor: add missing SyntaxFactory::assoc_item_list --- .../src/handlers/generate_delegate_trait.rs | 8 ++++---- .../src/ast/syntax_factory/constructors.rs | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs index 03642756219a..ab350e975df1 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs @@ -296,7 +296,7 @@ fn generate_impl( .collect() }); - let delegate = finalize_delegate(&delegate, assoc_items, false)?; + let delegate = finalize_delegate(&make, &delegate, assoc_items, false)?; let target_scope = ctx.sema.scope(strukt.strukt.syntax())?; let source_scope = ctx.sema.scope(bound_def.syntax())?; @@ -406,7 +406,7 @@ fn generate_impl( .collect() }); - finalize_delegate(&delegate, assoc_items, true) + finalize_delegate(&make, &delegate, assoc_items, true) } } } @@ -552,6 +552,7 @@ fn remove_useless_where_clauses(editor: &mut SyntaxEditor, delegate: &ast::Impl) /// 1. Replacing the assoc_item_list with new items (if any) /// 2. Removing useless where clauses fn finalize_delegate( + make: &SyntaxFactory, delegate: &ast::Impl, assoc_items: Option>, remove_where_clauses: bool, @@ -568,8 +569,7 @@ fn finalize_delegate( if let Some(items) = assoc_items && !items.is_empty() { - let new_assoc_item_list = - syntax::ast::make::assoc_item_list(Some(items)).clone_for_update(); + let new_assoc_item_list = make.assoc_item_list(items); if let Some(old_list) = delegate.assoc_item_list() { editor.replace(old_list.syntax(), new_assoc_item_list.syntax()); } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 8efad0368a9d..560dd77662ca 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -1454,6 +1454,23 @@ impl SyntaxFactory { ast } + pub fn assoc_item_list( + &self, + items: impl IntoIterator, + ) -> ast::AssocItemList { + let (items, input) = iterator_input(items); + let items_vec: Vec<_> = items.into_iter().collect(); + let ast = make::assoc_item_list(Some(items_vec)).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input, ast.assoc_items().map(|item| item.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + pub fn attr_outer(&self, meta: ast::Meta) -> ast::Attr { let ast = make::attr_outer(meta.clone()).clone_for_update(); From a27bd22519f4b2acf3b2e05091250f0ce7b3f569 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 5 Dec 2025 12:45:58 +0100 Subject: [PATCH 0315/3801] clean-up This mostly qualifies variable names with either `is_empty_` or `len_`, to make it easier to understand which of the two methods they relate to --- clippy_lints/src/len_zero.rs | 173 +++++++++++++++++------------------ 1 file changed, 84 insertions(+), 89 deletions(-) diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 877bd34a732b..7c1d62951eaf 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -156,8 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero { && let Some(ty_id) = cx.qpath_res(ty_path, imp.self_ty.hir_id).opt_def_id() && let Some(local_id) = ty_id.as_local() && let ty_hir_id = cx.tcx.local_def_id_to_hir_id(local_id) - && let Some(output) = - parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()) + && let Some(output) = LenOutput::new(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()) { let (name, kind) = match cx.tcx.hir_node(ty_hir_id) { Node::ForeignItem(x) => (x.ident.name, "extern type"), @@ -401,13 +400,6 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Iden } } -#[derive(Debug, Clone, Copy)] -enum LenOutput { - Integral, - Option(DefId), - Result(DefId), -} - fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { if let ty::Alias(_, alias_ty) = ty.kind() && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(alias_ty.def_id) @@ -439,42 +431,49 @@ fn is_first_generic_integral<'tcx>(segment: &'tcx PathSegment<'tcx>) -> bool { } } -fn parse_len_output<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option { - if let Some(segment) = extract_future_output(cx, sig.output()) { - let res = segment.res; - - if matches!(res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) { - return Some(LenOutput::Integral); - } - - if let Res::Def(_, def_id) = res - && let Some(res) = match cx.tcx.get_diagnostic_name(def_id) { - Some(sym::Option) => Some(LenOutput::Option(def_id)), - Some(sym::Result) => Some(LenOutput::Result(def_id)), - _ => None, - } - && is_first_generic_integral(segment) - { - return Some(res); - } - - return None; - } - - match *sig.output().kind() { - ty::Int(_) | ty::Uint(_) => Some(LenOutput::Integral), - ty::Adt(adt, subs) => match cx.tcx.get_diagnostic_name(adt.did()) { - Some(sym::Option) => subs.type_at(0).is_integral().then(|| LenOutput::Option(adt.did())), - Some(sym::Result) => subs.type_at(0).is_integral().then(|| LenOutput::Result(adt.did())), - _ => None, - }, - _ => None, - } +#[derive(Debug, Clone, Copy)] +enum LenOutput { + Integral, + Option(DefId), + Result(DefId), } impl LenOutput { - fn matches_is_empty_output<'tcx>(self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - if let Some(segment) = extract_future_output(cx, ty) { + fn new<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option { + if let Some(segment) = extract_future_output(cx, sig.output()) { + let res = segment.res; + + if matches!(res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) { + return Some(Self::Integral); + } + + if let Res::Def(_, def_id) = res + && let Some(res) = match cx.tcx.get_diagnostic_name(def_id) { + Some(sym::Option) => Some(Self::Option(def_id)), + Some(sym::Result) => Some(Self::Result(def_id)), + _ => None, + } + && is_first_generic_integral(segment) + { + return Some(res); + } + + return None; + } + + match *sig.output().kind() { + ty::Int(_) | ty::Uint(_) => Some(Self::Integral), + ty::Adt(adt, subs) => match cx.tcx.get_diagnostic_name(adt.did()) { + Some(sym::Option) => subs.type_at(0).is_integral().then(|| Self::Option(adt.did())), + Some(sym::Result) => subs.type_at(0).is_integral().then(|| Self::Result(adt.did())), + _ => None, + }, + _ => None, + } + } + + fn matches_is_empty_output<'tcx>(self, cx: &LateContext<'tcx>, is_empty_output: Ty<'tcx>) -> bool { + if let Some(segment) = extract_future_output(cx, is_empty_output) { return match (self, segment.res) { (_, Res::PrimTy(PrimTy::Bool)) => true, (Self::Option(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Option, def_id) => true, @@ -483,48 +482,51 @@ impl LenOutput { }; } - match (self, ty.kind()) { + match (self, is_empty_output.kind()) { (_, &ty::Bool) => true, (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), (Self::Result(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), _ => false, } } +} - fn expected_sig(self, self_kind: ImplicitSelfKind) -> String { - let self_ref = match self_kind { - ImplicitSelfKind::RefImm => "&", - ImplicitSelfKind::RefMut => "&mut ", - _ => "", - }; - match self { - Self::Integral => format!("expected signature: `({self_ref}self) -> bool`"), - Self::Option(_) => { - format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Option") - }, - Self::Result(..) => { - format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Result") - }, - } +/// The expected signature of `is_empty`, based on that of `len` +fn expected_is_empty_sig(len_output: LenOutput, len_self_kind: ImplicitSelfKind) -> String { + let self_ref = match len_self_kind { + ImplicitSelfKind::RefImm => "&", + ImplicitSelfKind::RefMut => "&mut ", + _ => "", + }; + match len_output { + LenOutput::Integral => format!("expected signature: `({self_ref}self) -> bool`"), + LenOutput::Option(_) => { + format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Option") + }, + LenOutput::Result(..) => { + format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Result") + }, } } /// Checks if the given signature matches the expectations for `is_empty` fn check_is_empty_sig<'tcx>( cx: &LateContext<'tcx>, - sig: FnSig<'tcx>, - self_kind: ImplicitSelfKind, + is_empty_sig: FnSig<'tcx>, + len_self_kind: ImplicitSelfKind, len_output: LenOutput, ) -> bool { - match &**sig.inputs_and_output { - [arg, res] if len_output.matches_is_empty_output(cx, *res) => { - matches!( - (arg.kind(), self_kind), - (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::RefImm) - | (ty::Ref(_, _, Mutability::Mut), ImplicitSelfKind::RefMut) - ) || (!arg.is_ref() && matches!(self_kind, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut)) - }, - _ => false, + if let [is_empty_self_arg, is_empty_output] = &**is_empty_sig.inputs_and_output + && len_output.matches_is_empty_output(cx, *is_empty_output) + { + match (is_empty_self_arg.kind(), len_self_kind) { + (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::RefImm) + | (ty::Ref(_, _, Mutability::Mut), ImplicitSelfKind::RefMut) => true, + (_, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut) if !is_empty_self_arg.is_ref() => true, + _ => false, + } + } else { + false } } @@ -532,9 +534,9 @@ fn check_is_empty_sig<'tcx>( #[expect(clippy::too_many_arguments)] fn check_for_is_empty( cx: &LateContext<'_>, - span: Span, - self_kind: ImplicitSelfKind, - output: LenOutput, + len_span: Span, + len_self_kind: ImplicitSelfKind, + len_output: LenOutput, impl_ty: DefId, item_name: Symbol, item_kind: &str, @@ -556,20 +558,14 @@ fn check_for_is_empty( .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(sym::is_empty)) .find(|item| item.is_fn()); - let (msg, is_empty_span, self_kind) = match is_empty { + let (msg, is_empty_span, is_empty_expected_sig) = match is_empty { None => ( - format!( - "{item_kind} `{}` has a public `len` method, but no `is_empty` method", - item_name.as_str(), - ), + format!("{item_kind} `{item_name}` has a public `len` method, but no `is_empty` method"), None, None, ), Some(is_empty) if !cx.effective_visibilities.is_exported(is_empty.def_id.expect_local()) => ( - format!( - "{item_kind} `{}` has a public `len` method, but a private `is_empty` method", - item_name.as_str(), - ), + format!("{item_kind} `{item_name}` has a public `len` method, but a private `is_empty` method"), Some(cx.tcx.def_span(is_empty.def_id)), None, ), @@ -578,29 +574,28 @@ fn check_for_is_empty( && check_is_empty_sig( cx, cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(), - self_kind, - output, + len_self_kind, + len_output, )) => { ( format!( - "{item_kind} `{}` has a public `len` method, but the `is_empty` method has an unexpected signature", - item_name.as_str(), + "{item_kind} `{item_name}` has a public `len` method, but the `is_empty` method has an unexpected signature", ), Some(cx.tcx.def_span(is_empty.def_id)), - Some(self_kind), + Some(expected_is_empty_sig(len_output, len_self_kind)), ) }, Some(_) => return, }; if !fulfill_or_allowed(cx, LEN_WITHOUT_IS_EMPTY, [len_method_hir_id, ty_decl_hir_id]) { - span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, span, msg, |db| { + span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, len_span, msg, |db| { if let Some(span) = is_empty_span { db.span_note(span, "`is_empty` defined here"); } - if let Some(self_kind) = self_kind { - db.note(output.expected_sig(self_kind)); + if let Some(expected_sig) = is_empty_expected_sig { + db.note(expected_sig); } }); } From d6b561376e932fc136f2443cc733d830ec160b6d Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 5 Dec 2025 13:53:02 +0100 Subject: [PATCH 0316/3801] fix(len_without_is_empty): allow `is_empty(&self)` with `len(&mut self)` --- clippy_lints/src/len_zero.rs | 8 ++++++-- tests/ui/len_without_is_empty.rs | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 7c1d62951eaf..f5a832f3adfd 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -495,7 +495,7 @@ impl LenOutput { fn expected_is_empty_sig(len_output: LenOutput, len_self_kind: ImplicitSelfKind) -> String { let self_ref = match len_self_kind { ImplicitSelfKind::RefImm => "&", - ImplicitSelfKind::RefMut => "&mut ", + ImplicitSelfKind::RefMut => "&(mut) ", _ => "", }; match len_output { @@ -520,8 +520,12 @@ fn check_is_empty_sig<'tcx>( && len_output.matches_is_empty_output(cx, *is_empty_output) { match (is_empty_self_arg.kind(), len_self_kind) { + // if `len` takes `&self`, `is_empty` should do so as well (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::RefImm) - | (ty::Ref(_, _, Mutability::Mut), ImplicitSelfKind::RefMut) => true, + // if `len` takes `&mut self`, `is_empty` may take that _or_ `&self` (#16190) + | (ty::Ref(_, _, Mutability::Mut | Mutability::Not), ImplicitSelfKind::RefMut) => true, + // if len takes `self`, `is_empty` should do so as well + // XXX: we might want to relax this to allow `&self` and `&mut self` (_, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut) if !is_empty_self_arg.is_ref() => true, _ => false, } diff --git a/tests/ui/len_without_is_empty.rs b/tests/ui/len_without_is_empty.rs index 011833072d76..509348628dd6 100644 --- a/tests/ui/len_without_is_empty.rs +++ b/tests/ui/len_without_is_empty.rs @@ -473,4 +473,16 @@ impl Alias2 { } } +// Issue #16190 +pub struct RefMutLenButRefIsEmpty; +impl RefMutLenButRefIsEmpty { + pub fn len(&mut self) -> usize { + todo!() + } + + pub fn is_empty(&self) -> bool { + todo!() + } +} + fn main() {} From 8f59eb017753e4e72f0d2b0a736ba9172002e321 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Thu, 4 Dec 2025 20:59:53 +0100 Subject: [PATCH 0317/3801] Move attribute lints to `rustc_lint` --- Cargo.lock | 3 +- compiler/rustc_attr_parsing/messages.ftl | 31 ----- .../src/attributes/inline.rs | 5 +- .../src/attributes/link_attrs.rs | 5 +- .../src/attributes/macro_attrs.rs | 15 +-- .../src/attributes/prelude.rs | 2 - .../src/attributes/test_attrs.rs | 13 +- compiler/rustc_attr_parsing/src/context.rs | 20 ++- compiler/rustc_attr_parsing/src/interface.rs | 17 ++- compiler/rustc_attr_parsing/src/lib.rs | 2 - compiler/rustc_attr_parsing/src/lints.rs | 114 ------------------ compiler/rustc_attr_parsing/src/safety.rs | 3 + .../src/session_diagnostics.rs | 65 +--------- .../rustc_attr_parsing/src/target_checking.rs | 31 ++++- .../rustc_attr_parsing/src/validate_attr.rs | 5 +- compiler/rustc_errors/src/lib.rs | 16 +-- compiler/rustc_hir/Cargo.toml | 1 + compiler/rustc_hir/src/lints.rs | 44 +------ compiler/rustc_hir_analysis/Cargo.toml | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 14 ++- compiler/rustc_lint/messages.ftl | 34 ++++++ compiler/rustc_lint/src/early/diagnostics.rs | 54 ++++++++- compiler/rustc_lint/src/lib.rs | 2 +- compiler/rustc_lint/src/lints.rs | 65 ++++++++++ compiler/rustc_lint_defs/src/lib.rs | 32 +++++ compiler/rustc_middle/src/ty/context.rs | 16 +-- compiler/rustc_session/src/session.rs | 17 +-- 27 files changed, 284 insertions(+), 344 deletions(-) delete mode 100644 compiler/rustc_attr_parsing/src/lints.rs diff --git a/Cargo.lock b/Cargo.lock index 2cc2e094e9f9..003bc6adb0e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3945,6 +3945,7 @@ dependencies = [ "rustc_hashes", "rustc_hir_id", "rustc_index", + "rustc_lint_defs", "rustc_macros", "rustc_serialize", "rustc_span", @@ -3962,7 +3963,6 @@ dependencies = [ "rustc_abi", "rustc_arena", "rustc_ast", - "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3970,6 +3970,7 @@ dependencies = [ "rustc_hir", "rustc_index", "rustc_infer", + "rustc_lint", "rustc_lint_defs", "rustc_macros", "rustc_middle", diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index a2a5f8ab1423..0d53ed9d97a5 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -14,18 +14,6 @@ attr_parsing_deprecated_item_suggestion = .help = add `#![feature(deprecated_suggestion)]` to the crate root .note = see #94785 for more details -attr_parsing_empty_attribute = - unused attribute - .suggestion = {$valid_without_list -> - [true] remove these parentheses - *[other] remove this attribute - } - .note = {$valid_without_list -> - [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all - *[other] using `{$attr_path}` with an empty list has no effect - } - - attr_parsing_empty_confusables = expected at least one confusable name attr_parsing_empty_link_name = @@ -119,19 +107,9 @@ attr_parsing_invalid_repr_hint_no_value = attr_parsing_invalid_since = 'since' must be a Rust version number, such as "1.31.0" -attr_parsing_invalid_style = {$is_used_as_inner -> - [false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]` - *[other] the `#![{$name}]` attribute can only be used at the crate root - } - .note = This attribute does not have an `!`, which means it is applied to this {$target} - attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target} .help = `#[{$name}]` can {$only}be applied to {$applied} .suggestion = remove the attribute -attr_parsing_invalid_target_lint = `#[{$name}]` attribute cannot be used on {$target} - .warn = {-attr_parsing_previously_accepted} - .help = `#[{$name}]` can {$only}be applied to {$applied} - .suggestion = remove the attribute attr_parsing_limit_invalid = `limit` must be a non-negative integer @@ -250,19 +228,10 @@ attr_parsing_unsupported_literal_generic = attr_parsing_unsupported_literal_suggestion = consider removing the prefix -attr_parsing_unused_duplicate = - unused attribute - .suggestion = remove this attribute - .note = attribute also specified here - .warn = {-attr_parsing_previously_accepted} - attr_parsing_unused_multiple = multiple `{$name}` attributes .suggestion = remove this attribute .note = attribute also specified here --attr_parsing_previously_accepted = - this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - attr_parsing_whole_archive_needs_static = linking modifier `whole-archive` is only compatible with `static` linking kind diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index eda272fb7f2b..fba1a663c057 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -3,6 +3,7 @@ // SingleAttributeParser which is what we have two of here. use rustc_hir::attrs::{AttributeKind, InlineAttr}; +use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; use super::prelude::*; @@ -56,9 +57,7 @@ impl SingleAttributeParser for InlineParser { } } ArgParser::NameValue(_) => { - let suggestions = cx.suggestions(); - let span = cx.attr_span; - cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); + cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT); return None; } } diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 5a4a4e759910..46fa8ee71343 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -2,6 +2,7 @@ use rustc_feature::Features; use rustc_hir::attrs::AttributeKind::{LinkName, LinkOrdinal, LinkSection}; use rustc_hir::attrs::*; use rustc_session::Session; +use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; use rustc_session::parse::feature_err; use rustc_span::kw; use rustc_target::spec::{Arch, BinaryFormat}; @@ -71,9 +72,7 @@ impl CombineAttributeParser for LinkParser { // Specifically `#[link = "dl"]` is accepted with a FCW // For more information, see https://github.com/rust-lang/rust/pull/143193 ArgParser::NameValue(nv) if nv.value_as_str().is_some_and(|v| v == sym::dl) => { - let suggestions = cx.suggestions(); - let span = cx.attr_span; - cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); + cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT); return None; } _ => { diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 787003519e78..d2fa1d440f40 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -1,5 +1,6 @@ use rustc_errors::DiagArgValue; use rustc_hir::attrs::MacroUseArgs; +use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS; use super::prelude::*; use crate::session_diagnostics::IllFormedAttributeInputLint; @@ -152,23 +153,13 @@ impl SingleAttributeParser for MacroExportParser { ArgParser::NoArgs => false, ArgParser::List(list) => { let Some(l) = list.single() else { - let span = cx.attr_span; - let suggestions = cx.suggestions(); - cx.emit_lint( - AttributeLintKind::InvalidMacroExportArguments { suggestions }, - span, - ); + cx.warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS); return None; }; match l.meta_item().and_then(|i| i.path().word_sym()) { Some(sym::local_inner_macros) => true, _ => { - let span = cx.attr_span; - let suggestions = cx.suggestions(); - cx.emit_lint( - AttributeLintKind::InvalidMacroExportArguments { suggestions }, - span, - ); + cx.warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS); return None; } } diff --git a/compiler/rustc_attr_parsing/src/attributes/prelude.rs b/compiler/rustc_attr_parsing/src/attributes/prelude.rs index 980366b5c372..65c408fa6358 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prelude.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prelude.rs @@ -4,8 +4,6 @@ pub(super) use rustc_feature::{AttributeTemplate, template}; #[doc(hidden)] pub(super) use rustc_hir::attrs::AttributeKind; #[doc(hidden)] -pub(super) use rustc_hir::lints::AttributeLintKind; -#[doc(hidden)] pub(super) use rustc_hir::{MethodKind, Target}; #[doc(hidden)] pub(super) use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index 23ecc0bf7d29..e0b006030758 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -1,3 +1,5 @@ +use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; + use super::prelude::*; pub(crate) struct IgnoreParser; @@ -20,20 +22,13 @@ impl SingleAttributeParser for IgnoreParser { ArgParser::NoArgs => None, ArgParser::NameValue(name_value) => { let Some(str_value) = name_value.value_as_str() else { - let suggestions = cx.suggestions(); - let span = cx.attr_span; - cx.emit_lint( - AttributeLintKind::IllFormedAttributeInput { suggestions }, - span, - ); + cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT); return None; }; Some(str_value) } ArgParser::List(_) => { - let suggestions = cx.suggestions(); - let span = cx.attr_span; - cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); + cx.warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT); return None; } }, diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index dcb7341b4b5e..bc74eaad50bc 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -11,6 +11,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::lints::{AttributeLint, AttributeLintKind}; use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId}; use rustc_session::Session; +use rustc_session::lint::{Lint, LintId}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; use crate::AttributeParser; @@ -381,7 +382,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing /// must be delayed until after HIR is built. This method will take care of the details of /// that. - pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) { + pub(crate) fn emit_lint(&mut self, lint: &'static Lint, kind: AttributeLintKind, span: Span) { if !matches!( self.stage.should_emit(), ShouldEmit::ErrorsAndLints | ShouldEmit::EarlyFatal { also_emit_lints: true } @@ -389,11 +390,12 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { return; } let id = self.target_id; - (self.emit_lint)(AttributeLint { id, span, kind: lint }); + (self.emit_lint)(AttributeLint { lint_id: LintId::of(lint), id, span, kind }); } pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) { self.emit_lint( + rustc_session::lint::builtin::UNUSED_ATTRIBUTES, AttributeLintKind::UnusedDuplicate { this: unused_span, other: used_span, @@ -409,6 +411,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { unused_span: Span, ) { self.emit_lint( + rustc_session::lint::builtin::UNUSED_ATTRIBUTES, AttributeLintKind::UnusedDuplicate { this: unused_span, other: used_span, @@ -632,14 +635,25 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { } pub(crate) fn warn_empty_attribute(&mut self, span: Span) { - let attr_path = self.attr_path.clone(); + let attr_path = self.attr_path.clone().to_string(); let valid_without_list = self.template.word; self.emit_lint( + rustc_session::lint::builtin::UNUSED_ATTRIBUTES, AttributeLintKind::EmptyAttribute { first_span: span, attr_path, valid_without_list }, span, ); } + pub(crate) fn warn_ill_formed_attribute_input(&mut self, lint: &'static Lint) { + let suggestions = self.suggestions(); + let span = self.attr_span; + self.emit_lint( + lint, + AttributeLintKind::IllFormedAttributeInput { suggestions, docs: None }, + span, + ); + } + pub(crate) fn suggestions(&self) -> Vec { let style = match self.parsed_description { // If the outer and inner spans are equal, we are parsing an embedded attribute diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 87e29b7b0de6..b26a4a29cd2e 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -8,6 +8,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::lints::AttributeLint; use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId, Target}; use rustc_session::Session; +use rustc_session::lint::BuiltinLintDiag; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage}; @@ -115,7 +116,12 @@ impl<'sess> AttributeParser<'sess, Early> { OmitDoc::Skip, std::convert::identity, |lint| { - crate::lints::emit_attribute_lint(&lint, sess); + sess.psess.buffer_lint( + lint.lint_id.lint, + lint.span, + lint.id, + BuiltinLintDiag::AttributeLint(lint.kind), + ) }, ) } @@ -183,8 +189,13 @@ impl<'sess> AttributeParser<'sess, Early> { sess, stage: Early { emit_errors }, }; - let mut emit_lint = |lint| { - crate::lints::emit_attribute_lint(&lint, sess); + let mut emit_lint = |lint: AttributeLint| { + sess.psess.buffer_lint( + lint.lint_id.lint, + lint.span, + lint.id, + BuiltinLintDiag::AttributeLint(lint.kind), + ) }; if let Some(safety) = attr_safety { parser.check_attribute_safety( diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 7a7f2555287a..7cef70f88e1c 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -97,7 +97,6 @@ mod interface; /// like lists or name-value pairs. pub mod parser; -mod lints; mod safety; mod session_diagnostics; mod target_checking; @@ -111,7 +110,6 @@ pub use attributes::cfg_select::*; pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version}; pub use context::{Early, Late, OmitDoc, ShouldEmit}; pub use interface::AttributeParser; -pub use lints::emit_attribute_lint; pub use session_diagnostics::ParsedDescription; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_attr_parsing/src/lints.rs b/compiler/rustc_attr_parsing/src/lints.rs deleted file mode 100644 index a23884d7f71e..000000000000 --- a/compiler/rustc_attr_parsing/src/lints.rs +++ /dev/null @@ -1,114 +0,0 @@ -use std::borrow::Cow; - -use rustc_errors::{DiagArgValue, LintEmitter}; -use rustc_hir::Target; -use rustc_hir::lints::{AttributeLint, AttributeLintKind}; -use rustc_span::sym; - -use crate::session_diagnostics; - -pub fn emit_attribute_lint(lint: &AttributeLint, lint_emitter: L) { - let AttributeLint { id, span, kind } = lint; - - match kind { - &AttributeLintKind::UnusedDuplicate { this, other, warning } => lint_emitter - .emit_node_span_lint( - rustc_session::lint::builtin::UNUSED_ATTRIBUTES, - *id, - *span, - session_diagnostics::UnusedDuplicate { this, other, warning }, - ), - AttributeLintKind::IllFormedAttributeInput { suggestions } => { - lint_emitter.emit_node_span_lint( - rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT, - *id, - *span, - session_diagnostics::IllFormedAttributeInput { - num_suggestions: suggestions.len(), - suggestions: DiagArgValue::StrListSepByAnd( - suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), - ), - }, - ); - } - AttributeLintKind::InvalidMacroExportArguments { suggestions } => lint_emitter - .emit_node_span_lint( - rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS, - *id, - *span, - session_diagnostics::IllFormedAttributeInput { - num_suggestions: suggestions.len(), - suggestions: DiagArgValue::StrListSepByAnd( - suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), - ), - }, - ), - AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => { - lint_emitter.emit_node_span_lint( - rustc_session::lint::builtin::UNUSED_ATTRIBUTES, - *id, - *first_span, - session_diagnostics::EmptyAttributeList { - attr_span: *first_span, - attr_path: attr_path.clone(), - valid_without_list: *valid_without_list, - }, - ) - } - AttributeLintKind::InvalidTarget { name, target, applied, only } => lint_emitter - .emit_node_span_lint( - // This check is here because `deprecated` had its own lint group and removing this would be a breaking change - if name.segments[0].name == sym::deprecated - && ![ - Target::Closure, - Target::Expression, - Target::Statement, - Target::Arm, - Target::MacroCall, - ] - .contains(target) - { - rustc_session::lint::builtin::USELESS_DEPRECATED - } else { - rustc_session::lint::builtin::UNUSED_ATTRIBUTES - }, - *id, - *span, - session_diagnostics::InvalidTargetLint { - name: name.clone(), - target: target.plural_name(), - applied: DiagArgValue::StrListSepByAnd( - applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(), - ), - only, - attr_span: *span, - }, - ), - - &AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => { - lint_emitter.emit_node_span_lint( - rustc_session::lint::builtin::UNUSED_ATTRIBUTES, - *id, - *span, - session_diagnostics::InvalidAttrStyle { - name: name.clone(), - is_used_as_inner, - target_span: (!is_used_as_inner).then_some(target_span), - target, - }, - ) - } - &AttributeLintKind::UnsafeAttrOutsideUnsafe { - attribute_name_span, - sugg_spans: (left, right), - } => lint_emitter.emit_node_span_lint( - rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE, - *id, - *span, - session_diagnostics::UnsafeAttrOutsideUnsafeLint { - span: attribute_name_span, - suggestion: session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion { left, right }, - }, - ), - } -} diff --git a/compiler/rustc_attr_parsing/src/safety.rs b/compiler/rustc_attr_parsing/src/safety.rs index ff385bf13aaa..52baf2136173 100644 --- a/compiler/rustc_attr_parsing/src/safety.rs +++ b/compiler/rustc_attr_parsing/src/safety.rs @@ -2,6 +2,8 @@ use rustc_ast::Safety; use rustc_feature::{AttributeSafety, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir::AttrPath; use rustc_hir::lints::{AttributeLint, AttributeLintKind}; +use rustc_session::lint::LintId; +use rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE; use rustc_span::{Span, sym}; use crate::context::Stage; @@ -74,6 +76,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { ); } else { emit_lint(AttributeLint { + lint_id: LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE), id: target_id, span: path_span, kind: AttributeLintKind::UnsafeAttrOutsideUnsafe { diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index f94f0867451f..c4f6f9c6a38c 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -6,8 +6,8 @@ use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, }; use rustc_feature::AttributeTemplate; -use rustc_hir::{AttrPath, Target}; -use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; +use rustc_hir::AttrPath; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; use crate::fluent_generated as fluent; @@ -417,25 +417,6 @@ pub(crate) struct UnusedMultiple { pub name: Symbol, } -#[derive(LintDiagnostic)] -#[diag(attr_parsing_unused_duplicate)] -pub(crate) struct UnusedDuplicate { - #[suggestion(code = "", applicability = "machine-applicable")] - pub this: Span, - #[note] - pub other: Span, - #[warning] - pub warning: bool, -} - -// FIXME(jdonszelmann): duplicated in rustc_lints, should be moved here completely. -#[derive(LintDiagnostic)] -#[diag(attr_parsing_ill_formed_attribute_input)] -pub(crate) struct IllFormedAttributeInput { - pub num_suggestions: usize, - pub suggestions: DiagArgValue, -} - #[derive(Diagnostic)] #[diag(attr_parsing_ill_formed_attribute_input)] pub(crate) struct IllFormedAttributeInputLint { @@ -501,29 +482,6 @@ pub(crate) struct EmptyConfusables { pub span: Span, } -#[derive(LintDiagnostic)] -#[diag(attr_parsing_empty_attribute)] -#[note] -pub(crate) struct EmptyAttributeList { - #[suggestion(code = "", applicability = "machine-applicable")] - pub attr_span: Span, - pub attr_path: AttrPath, - pub valid_without_list: bool, -} - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_invalid_target_lint)] -#[warning] -#[help] -pub(crate) struct InvalidTargetLint { - pub name: AttrPath, - pub target: &'static str, - pub applied: DiagArgValue, - pub only: &'static str, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] - pub attr_span: Span, -} - #[derive(Diagnostic)] #[help] #[diag(attr_parsing_invalid_target)] @@ -803,15 +761,6 @@ pub(crate) struct UnsafeAttrOutsideUnsafe { pub suggestion: UnsafeAttrOutsideUnsafeSuggestion, } -#[derive(LintDiagnostic)] -#[diag(attr_parsing_unsafe_attr_outside_unsafe)] -pub(crate) struct UnsafeAttrOutsideUnsafeLint { - #[label] - pub span: Span, - #[subdiagnostic] - pub suggestion: UnsafeAttrOutsideUnsafeSuggestion, -} - #[derive(Subdiagnostic)] #[multipart_suggestion( attr_parsing_unsafe_attr_outside_unsafe_suggestion, @@ -881,16 +830,6 @@ pub(crate) struct SuffixedLiteralInAttribute { pub span: Span, } -#[derive(LintDiagnostic)] -#[diag(attr_parsing_invalid_style)] -pub(crate) struct InvalidAttrStyle { - pub name: AttrPath, - pub is_used_as_inner: bool, - #[note] - pub target_span: Option, - pub target: Target, -} - #[derive(Diagnostic)] #[diag(attr_parsing_empty_link_name, code = E0454)] pub(crate) struct EmptyLinkName { diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index fabd364d3d7f..88efb910c160 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -5,6 +5,7 @@ use rustc_errors::DiagArgValue; use rustc_feature::Features; use rustc_hir::lints::AttributeLintKind; use rustc_hir::{MethodKind, Target}; +use rustc_span::sym; use crate::AttributeParser; use crate::context::{AcceptContext, Stage}; @@ -102,13 +103,31 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { let allowed_targets = allowed_targets.allowed_targets(); let (applied, only) = allowed_targets_applied(allowed_targets, target, cx.features); let name = cx.attr_path.clone(); + + let lint = if name.segments[0].name == sym::deprecated + && ![ + Target::Closure, + Target::Expression, + Target::Statement, + Target::Arm, + Target::MacroCall, + ] + .contains(&target) + { + rustc_session::lint::builtin::USELESS_DEPRECATED + } else { + rustc_session::lint::builtin::UNUSED_ATTRIBUTES + }; + let attr_span = cx.attr_span; cx.emit_lint( + lint, AttributeLintKind::InvalidTarget { - name, - target, + name: name.to_string(), + target: target.plural_name(), only: if only { "only " } else { "" }, applied, + attr_span, }, attr_span, ); @@ -145,15 +164,15 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { return; } - let lint = AttributeLintKind::InvalidStyle { - name: cx.attr_path.clone(), + let kind = AttributeLintKind::InvalidStyle { + name: cx.attr_path.to_string(), is_used_as_inner: cx.attr_style == AttrStyle::Inner, - target, + target: target.name(), target_span: cx.target_span, }; let attr_span = cx.attr_span; - cx.emit_lint(lint, attr_span); + cx.emit_lint(rustc_session::lint::builtin::UNUSED_ATTRIBUTES, kind, attr_span); } } diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index c57e0baea05f..cd28677b6a8f 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -11,6 +11,7 @@ use rustc_ast::{ use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; use rustc_hir::AttrPath; +use rustc_hir::lints::AttributeLintKind; use rustc_parse::parse_in; use rustc_session::errors::report_lit_error; use rustc_session::lint::BuiltinLintDiag; @@ -202,10 +203,10 @@ fn emit_malformed_attribute( ILL_FORMED_ATTRIBUTE_INPUT, span, ast::CRATE_NODE_ID, - BuiltinLintDiag::IllFormedAttributeInput { + BuiltinLintDiag::AttributeLint(AttributeLintKind::IllFormedAttributeInput { suggestions: suggestions.clone(), docs: template.docs, - }, + }), ); } else { suggestions.sort(); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 5a7a178582e3..12e6700e0b8d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -64,8 +64,8 @@ pub use rustc_error_messages::{ fallback_fluent_bundle, fluent_bundle, into_diag_arg_using_display, }; use rustc_hashes::Hash128; +use rustc_lint_defs::LintExpectationId; pub use rustc_lint_defs::{Applicability, listify, pluralize}; -use rustc_lint_defs::{Lint, LintExpectationId}; use rustc_macros::{Decodable, Encodable}; pub use rustc_span::ErrorGuaranteed; pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker}; @@ -106,20 +106,6 @@ rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24); #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24); -/// Used to avoid depending on `rustc_middle` in `rustc_attr_parsing`. -/// Always the `TyCtxt`. -pub trait LintEmitter: Copy { - type Id: Copy; - #[track_caller] - fn emit_node_span_lint( - self, - lint: &'static Lint, - hir_id: Self::Id, - span: impl Into, - decorator: impl for<'a> LintDiagnostic<'a, ()> + DynSend + 'static, - ); -} - #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)] pub enum SuggestionStyle { /// Hide the suggested code when displaying this suggestion inline. diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 1008a3e787d0..13e73acf0737 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -16,6 +16,7 @@ rustc_error_messages = { path = "../rustc_error_messages" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir_id = { path = "../rustc_hir_id" } rustc_index = { path = "../rustc_index" } +rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_hir/src/lints.rs b/compiler/rustc_hir/src/lints.rs index a4c60fd2cc1a..eba2d182d2c4 100644 --- a/compiler/rustc_hir/src/lints.rs +++ b/compiler/rustc_hir/src/lints.rs @@ -1,8 +1,10 @@ use rustc_data_structures::fingerprint::Fingerprint; +pub use rustc_lint_defs::AttributeLintKind; +use rustc_lint_defs::LintId; use rustc_macros::HashStable_Generic; use rustc_span::Span; -use crate::{AttrPath, HirId, Target}; +use crate::HirId; #[derive(Debug)] pub struct DelayedLints { @@ -24,46 +26,8 @@ pub enum DelayedLint { #[derive(Debug, HashStable_Generic)] pub struct AttributeLint { + pub lint_id: LintId, pub id: Id, pub span: Span, pub kind: AttributeLintKind, } - -#[derive(Debug, HashStable_Generic)] -pub enum AttributeLintKind { - /// Copy of `IllFormedAttributeInput` - /// specifically for the `invalid_macro_export_arguments` lint until that is removed, - /// see - InvalidMacroExportArguments { - suggestions: Vec, - }, - UnusedDuplicate { - this: Span, - other: Span, - warning: bool, - }, - IllFormedAttributeInput { - suggestions: Vec, - }, - EmptyAttribute { - first_span: Span, - attr_path: AttrPath, - valid_without_list: bool, - }, - InvalidTarget { - name: AttrPath, - target: Target, - applied: Vec, - only: &'static str, - }, - InvalidStyle { - name: AttrPath, - is_used_as_inner: bool, - target: Target, - target_span: Span, - }, - UnsafeAttrOutsideUnsafe { - attribute_name_span: Span, - sugg_spans: (Span, Span), - }, -} diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index e5017794d8f2..8d114862b3fe 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -13,7 +13,6 @@ itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } -rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } @@ -21,6 +20,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } +rustc_lint = { path = "../rustc_lint" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 1d2a456b555e..538fb8c7df1e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -158,7 +158,19 @@ pub fn provide(providers: &mut Providers) { fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) { match lint { DelayedLint::AttributeParsing(attribute_lint) => { - rustc_attr_parsing::emit_attribute_lint(attribute_lint, tcx) + tcx.node_span_lint( + attribute_lint.lint_id.lint, + attribute_lint.id, + attribute_lint.span, + |diag| { + rustc_lint::decorate_attribute_lint( + tcx.sess, + Some(tcx), + &attribute_lint.kind, + diag, + ); + }, + ); } } } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 75e7af4c1173..1bcdda96e13a 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -245,6 +245,19 @@ lint_dropping_copy_types = calls to `std::mem::drop` with a value that implement lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing .label = argument has type `{$arg_ty}` +lint_empty_attribute = + unused attribute + .suggestion = {$valid_without_list -> + [true] remove these parentheses + *[other] remove this attribute + } + .note = {$valid_without_list -> + [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all + *[other] using `{$attr_path}` with an empty list has no effect + } + +-lint_previously_accepted = + this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! lint_enum_intrinsics_mem_discriminant = the return value of `mem::discriminant` is unspecified when called with a non-enum type .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum @@ -458,6 +471,17 @@ lint_invalid_reference_casting_note_book = for more information, visit + [false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]` + *[other] the `#![{$name}]` attribute can only be used at the crate root + } + .note = This attribute does not have an `!`, which means it is applied to this {$target} + +lint_invalid_target = `#[{$name}]` attribute cannot be used on {$target} + .warn = {-lint_previously_accepted} + .help = `#[{$name}]` can {$only}be applied to {$applied} + .suggestion = remove the attribute + lint_lintpass_by_hand = implementing `LintPass` by hand .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead @@ -890,6 +914,10 @@ lint_unpredictable_fn_pointer_comparisons = function pointer comparisons do not lint_unqualified_local_imports = `use` of a local item without leading `self::`, `super::`, or `crate::` +lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe + .label = usage of unsafe attribute +lint_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)` + lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´ lint_untranslatable_diag = diagnostics should be created using translatable messages @@ -922,6 +950,12 @@ lint_unused_def = unused {$pre}`{$def}`{$post} that must be used lint_unused_delim = unnecessary {$delim} around {$item} .suggestion = remove these {$delim} +lint_unused_duplicate = + unused attribute + .suggestion = remove this attribute + .note = attribute also specified here + .warn = {-lint_previously_accepted} + lint_unused_import_braces = braces around {$node} is unnecessary lint_unused_imports = {$num_snippets -> diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 87ccd114ee97..b654bc848ecf 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -4,6 +4,7 @@ use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_errors::{ Applicability, Diag, DiagArgValue, LintDiagnostic, elided_lifetime_in_path_suggestion, }; +use rustc_hir::lints::AttributeLintKind; use rustc_middle::middle::stability; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -301,7 +302,21 @@ pub fn decorate_builtin_lint( BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag) } - BuiltinLintDiag::IllFormedAttributeInput { suggestions, docs } => { + BuiltinLintDiag::AttributeLint(kind) => decorate_attribute_lint(sess, tcx, &kind, diag), + } +} + +pub fn decorate_attribute_lint( + _sess: &Session, + _tcx: Option>, + kind: &AttributeLintKind, + diag: &mut Diag<'_, ()>, +) { + match kind { + &AttributeLintKind::UnusedDuplicate { this, other, warning } => { + lints::UnusedDuplicate { this, other, warning }.decorate_lint(diag) + } + AttributeLintKind::IllFormedAttributeInput { suggestions, docs } => { lints::IllFormedAttributeInput { num_suggestions: suggestions.len(), suggestions: DiagArgValue::StrListSepByAnd( @@ -312,5 +327,42 @@ pub fn decorate_builtin_lint( } .decorate_lint(diag) } + AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => { + lints::EmptyAttributeList { + attr_span: *first_span, + attr_path: attr_path.clone(), + valid_without_list: *valid_without_list, + } + .decorate_lint(diag) + } + AttributeLintKind::InvalidTarget { name, target, applied, only, attr_span } => { + lints::InvalidTargetLint { + name: name.clone(), + target, + applied: DiagArgValue::StrListSepByAnd( + applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(), + ), + only, + attr_span: *attr_span, + } + .decorate_lint(diag) + } + &AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => { + lints::InvalidAttrStyle { + name: name.clone(), + is_used_as_inner, + target_span: (!is_used_as_inner).then_some(target_span), + target, + } + .decorate_lint(diag) + } + &AttributeLintKind::UnsafeAttrOutsideUnsafe { + attribute_name_span, + sugg_spans: (left, right), + } => lints::UnsafeAttrOutsideUnsafeLint { + span: attribute_name_span, + suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right }, + } + .decorate_lint(diag), } } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 78b76e083d41..23afbf6c0d7b 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -129,7 +129,7 @@ use unused::*; #[rustfmt::skip] pub use builtin::{MissingDoc, SoftLints}; pub use context::{CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore}; -pub use early::diagnostics::decorate_builtin_lint; +pub use early::diagnostics::{decorate_attribute_lint, decorate_builtin_lint}; pub use early::{EarlyCheckNode, check_ast_node}; pub use late::{check_crate, late_lint_mod, unerased_lint_store}; pub use levels::LintLevelsBuilder; diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 51708bc04583..4f28d503af3c 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3126,3 +3126,68 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { } } } + +#[derive(LintDiagnostic)] +#[diag(lint_empty_attribute)] +#[note] +pub(crate) struct EmptyAttributeList { + #[suggestion(code = "", applicability = "machine-applicable")] + pub attr_span: Span, + pub attr_path: String, + pub valid_without_list: bool, +} + +#[derive(LintDiagnostic)] +#[diag(lint_invalid_target)] +#[warning] +#[help] +pub(crate) struct InvalidTargetLint { + pub name: String, + pub target: &'static str, + pub applied: DiagArgValue, + pub only: &'static str, + #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + pub attr_span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(lint_invalid_style)] +pub(crate) struct InvalidAttrStyle { + pub name: String, + pub is_used_as_inner: bool, + #[note] + pub target_span: Option, + pub target: &'static str, +} + +#[derive(LintDiagnostic)] +#[diag(lint_unused_duplicate)] +pub(crate) struct UnusedDuplicate { + #[suggestion(code = "", applicability = "machine-applicable")] + pub this: Span, + #[note] + pub other: Span, + #[warning] + pub warning: bool, +} + +#[derive(LintDiagnostic)] +#[diag(lint_unsafe_attr_outside_unsafe)] +pub(crate) struct UnsafeAttrOutsideUnsafeLint { + #[label] + pub span: Span, + #[subdiagnostic] + pub suggestion: UnsafeAttrOutsideUnsafeSuggestion, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + lint_unsafe_attr_outside_unsafe_suggestion, + applicability = "machine-applicable" +)] +pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { + #[suggestion_part(code = "unsafe(")] + pub left: Span, + #[suggestion_part(code = ")")] + pub right: Span, +} diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index abdc41eb57c2..3c6e7d04a29d 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -696,10 +696,42 @@ pub enum BuiltinLintDiag { extern_crate: Symbol, local_crate: Symbol, }, + AttributeLint(AttributeLintKind), +} + +#[derive(Debug, HashStable_Generic)] +pub enum AttributeLintKind { + UnusedDuplicate { + this: Span, + other: Span, + warning: bool, + }, IllFormedAttributeInput { suggestions: Vec, docs: Option<&'static str>, }, + EmptyAttribute { + first_span: Span, + attr_path: String, + valid_without_list: bool, + }, + InvalidTarget { + name: String, + target: &'static str, + applied: Vec, + only: &'static str, + attr_span: Span, + }, + InvalidStyle { + name: String, + is_used_as_inner: bool, + target: &'static str, + target_span: Span, + }, + UnsafeAttrOutsideUnsafe { + attribute_name_span: Span, + sugg_spans: (Span, Span), + }, } pub type RegisteredTools = FxIndexSet; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0cd36d5e971d..a16c2232c3a6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -30,7 +30,7 @@ use rustc_data_structures::sync::{ self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal, }; use rustc_errors::{ - Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, LintEmitter, MultiSpan, + Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan, }; use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{CtorKind, CtorOf, DefKind}; @@ -1534,20 +1534,6 @@ pub struct TyCtxt<'tcx> { gcx: &'tcx GlobalCtxt<'tcx>, } -impl<'tcx> LintEmitter for TyCtxt<'tcx> { - type Id = HirId; - - fn emit_node_span_lint( - self, - lint: &'static Lint, - hir_id: HirId, - span: impl Into, - decorator: impl for<'a> LintDiagnostic<'a, ()>, - ) { - self.emit_node_span_lint(lint, hir_id, span, decorator); - } -} - // Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. Its // field are asserted to implement these traits below, so this is trivially safe, and it greatly // speeds-up compilation of this crate and its dependents. diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index e52475cdd5bd..acc65fc11a2a 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -6,7 +6,6 @@ use std::sync::atomic::AtomicBool; use std::{env, io}; use rand::{RngCore, rng}; -use rustc_ast::NodeId; use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; @@ -22,7 +21,7 @@ use rustc_errors::timings::TimingSectionHandler; use rustc_errors::translation::Translator; use rustc_errors::{ Diag, DiagCtxt, DiagCtxtHandle, DiagMessage, Diagnostic, ErrorGuaranteed, FatalAbort, - LintEmitter, TerminalUrl, fallback_fluent_bundle, + TerminalUrl, fallback_fluent_bundle, }; use rustc_hir::limit::Limit; use rustc_macros::HashStable_Generic; @@ -160,20 +159,6 @@ pub struct Session { pub invocation_temp: Option, } -impl LintEmitter for &'_ Session { - type Id = NodeId; - - fn emit_node_span_lint( - self, - lint: &'static rustc_lint_defs::Lint, - node_id: Self::Id, - span: impl Into, - decorator: impl for<'a> rustc_errors::LintDiagnostic<'a, ()> + DynSend + 'static, - ) { - self.psess.buffer_lint(lint, span, node_id, decorator); - } -} - #[derive(Clone, Copy)] pub enum CodegenUnits { /// Specified by the user. In this case we try fairly hard to produce the From 24219203940952557b66e5f8e532e4a78ade256e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Dec 2025 22:40:12 +0100 Subject: [PATCH 0318/3801] f*::min/max: fix comparing with libm and IEEE operations --- library/core/src/intrinsics/mod.rs | 48 +++++++++++++++--------------- library/core/src/num/f128.rs | 30 ++++++++++--------- library/core/src/num/f16.rs | 30 ++++++++++--------- library/core/src/num/f32.rs | 30 ++++++++++--------- library/core/src/num/f64.rs | 30 ++++++++++--------- 5 files changed, 88 insertions(+), 80 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 2115c5c9a85d..a9735a7e6f31 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2949,9 +2949,9 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize); /// Returns the minimum of two `f16` values, ignoring NaN. /// -/// This behaves like IEEE 754-2008 minNum. In particular: -/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal -/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -2965,9 +2965,9 @@ pub const fn minnumf16(x: f16, y: f16) -> f16; /// Returns the minimum of two `f32` values, ignoring NaN. /// -/// This behaves like IEEE 754-2008 minNum. In particular: -/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal -/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -2982,9 +2982,9 @@ pub const fn minnumf32(x: f32, y: f32) -> f32; /// Returns the minimum of two `f64` values, ignoring NaN. /// -/// This behaves like IEEE 754-2008 minNum. In particular: -/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal -/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -2999,9 +2999,9 @@ pub const fn minnumf64(x: f64, y: f64) -> f64; /// Returns the minimum of two `f128` values, ignoring NaN. /// -/// This behaves like IEEE 754-2008 minNum. In particular: -/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal -/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3115,9 +3115,9 @@ pub const fn minimumf128(x: f128, y: f128) -> f128 { /// Returns the maximum of two `f16` values, ignoring NaN. /// -/// This behaves like IEEE 754-2008 maxNum. In particular: -/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal -/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3131,9 +3131,9 @@ pub const fn maxnumf16(x: f16, y: f16) -> f16; /// Returns the maximum of two `f32` values, ignoring NaN. /// -/// This behaves like IEEE 754-2008 maxNum. In particular: -/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal -/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3148,9 +3148,9 @@ pub const fn maxnumf32(x: f32, y: f32) -> f32; /// Returns the maximum of two `f64` values, ignoring NaN. /// -/// This behaves like IEEE 754-2008 maxNum. In particular: -/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal -/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. @@ -3165,9 +3165,9 @@ pub const fn maxnumf64(x: f64, y: f64) -> f64; /// Returns the maximum of two `f128` values, ignoring NaN. /// -/// This behaves like IEEE 754-2008 maxNum. In particular: -/// If one of the arguments is NaN, then the other argument is returned. If the inputs compare equal -/// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. +/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If +/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0` +/// and `-0.0`), either input may be returned non-deterministically. /// /// Note that, unlike most intrinsics, this is safe to call; /// it does not require an `unsafe` block. diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 9b9cc80a606c..3d1f48ca6e1a 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -694,14 +694,15 @@ impl f128 { /// Returns the maximum of the two numbers, ignoring NaN. /// - /// If exactly one of the arguments is NaN, then the other argument is returned. If both - /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual - /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such - /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is + /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked + /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs + /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned + /// non-deterministically. /// - /// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs; - /// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity. - /// This also matches the behavior of libm’s `fmax`. + /// The handling of NaNs follows the IEEE 754-2019 semantics for `maximumNumber`, treating all + /// NaNs the same way to ensure the operation is associative. The handling of signed zeros + /// follows the IEEE 754-2008 semantics for `maxNum`. /// /// ``` /// #![feature(f128)] @@ -725,14 +726,15 @@ impl f128 { /// Returns the minimum of the two numbers, ignoring NaN. /// - /// If exactly one of the arguments is NaN, then the other argument is returned. If both - /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual - /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such - /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is + /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked + /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs + /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned + /// non-deterministically. /// - /// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs; - /// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity. - /// This also matches the behavior of libm’s `fmin`. + /// The handling of NaNs follows the IEEE 754-2019 semantics for `minimumNumber`, treating all + /// NaNs the same way to ensure the operation is associative. The handling of signed zeros + /// follows the IEEE 754-2008 semantics for `minNum`. /// /// ``` /// #![feature(f128)] diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index ab765ebcb7fa..937394b339cc 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -687,14 +687,15 @@ impl f16 { /// Returns the maximum of the two numbers, ignoring NaN. /// - /// If exactly one of the arguments is NaN, then the other argument is returned. If both - /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual - /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such - /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is + /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked + /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs + /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned + /// non-deterministically. /// - /// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs; - /// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity. - /// This also matches the behavior of libm’s `fmax`. + /// The handling of NaNs follows the IEEE 754-2019 semantics for `maximumNumber`, treating all + /// NaNs the same way to ensure the operation is associative. The handling of signed zeros + /// follows the IEEE 754-2008 semantics for `maxNum`. /// /// ``` /// #![feature(f16)] @@ -717,14 +718,15 @@ impl f16 { /// Returns the minimum of the two numbers, ignoring NaN. /// - /// If exactly one of the arguments is NaN, then the other argument is returned. If both - /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual - /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such - /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is + /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked + /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs + /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned + /// non-deterministically. /// - /// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs; - /// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity. - /// This also matches the behavior of libm’s `fmin`. + /// The handling of NaNs follows the IEEE 754-2019 semantics for `minimumNumber`, treating all + /// NaNs the same way to ensure the operation is associative. The handling of signed zeros + /// follows the IEEE 754-2008 semantics for `minNum`. /// /// ``` /// #![feature(f16)] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 361f273ead01..04760ddc1d67 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -897,14 +897,15 @@ impl f32 { /// Returns the maximum of the two numbers, ignoring NaN. /// - /// If exactly one of the arguments is NaN, then the other argument is returned. If both - /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual - /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such - /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is + /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked + /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs + /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned + /// non-deterministically. /// - /// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs; - /// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity. - /// This also matches the behavior of libm’s `fmax`. + /// The handling of NaNs follows the IEEE 754-2019 semantics for `maximumNumber`, treating all + /// NaNs the same way to ensure the operation is associative. The handling of signed zeros + /// follows the IEEE 754-2008 semantics for `maxNum`. /// /// ``` /// let x = 1.0f32; @@ -923,14 +924,15 @@ impl f32 { /// Returns the minimum of the two numbers, ignoring NaN. /// - /// If exactly one of the arguments is NaN, then the other argument is returned. If both - /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual - /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such - /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is + /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked + /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs + /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned + /// non-deterministically. /// - /// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs; - /// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity. - /// This also matches the behavior of libm’s `fmin`. + /// The handling of NaNs follows the IEEE 754-2019 semantics for `minimumNumber`, treating all + /// NaNs the same way to ensure the operation is associative. The handling of signed zeros + /// follows the IEEE 754-2008 semantics for `minNum`. /// /// ``` /// let x = 1.0f32; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 17a908643a41..e7cab39dca44 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -915,14 +915,15 @@ impl f64 { /// Returns the maximum of the two numbers, ignoring NaN. /// - /// If exactly one of the arguments is NaN, then the other argument is returned. If both - /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual - /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such - /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is + /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked + /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs + /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned + /// non-deterministically. /// - /// This follows the IEEE 754-2008 semantics for `maxNum`, except for handling of signaling NaNs; - /// this function handles all NaNs the same way and avoids `maxNum`'s problems with associativity. - /// This also matches the behavior of libm’s `fmax`. + /// The handling of NaNs follows the IEEE 754-2019 semantics for `maximumNumber`, treating all + /// NaNs the same way to ensure the operation is associative. The handling of signed zeros + /// follows the IEEE 754-2008 semantics for `maxNum`. /// /// ``` /// let x = 1.0_f64; @@ -941,14 +942,15 @@ impl f64 { /// Returns the minimum of the two numbers, ignoring NaN. /// - /// If exactly one of the arguments is NaN, then the other argument is returned. If both - /// arguments are NaN, the return value is NaN, with the bit pattern picked using the usual - /// [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs compare equal (such - /// as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. + /// If exactly one of the arguments is NaN (quiet or signaling), then the other argument is + /// returned. If both arguments are NaN, the return value is NaN, with the bit pattern picked + /// using the usual [rules for arithmetic operations](f32#nan-bit-patterns). If the inputs + /// compare equal (such as for the case of `+0.0` and `-0.0`), either input may be returned + /// non-deterministically. /// - /// This follows the IEEE 754-2008 semantics for `minNum`, except for handling of signaling NaNs; - /// this function handles all NaNs the same way and avoids `minNum`'s problems with associativity. - /// This also matches the behavior of libm’s `fmin`. + /// The handling of NaNs follows the IEEE 754-2019 semantics for `minimumNumber`, treating all + /// NaNs the same way to ensure the operation is associative. The handling of signed zeros + /// follows the IEEE 754-2008 semantics for `minNum`. /// /// ``` /// let x = 1.0_f64; From a1f4caf46751d3e166a35897fa064c394c3a16dd Mon Sep 17 00:00:00 2001 From: Paul Murphy Date: Thu, 4 Dec 2025 17:52:55 -0600 Subject: [PATCH 0319/3801] Restrict spe_acc to PowerPC SPE targets Update the tests, add powerpc-*-gnuspe testing, and create a distinct clobber_abi list for PowerPC SPE targets. Note, the SPE target does not have vector, vector-scalar, or floating-point specific registers. --- compiler/rustc_target/src/asm/mod.rs | 24 +- compiler/rustc_target/src/asm/powerpc.rs | 12 +- tests/codegen-llvm/asm/powerpc-clobbers.rs | 31 +- tests/ui/asm/powerpc/bad-reg.aix64.stderr | 238 ++--- tests/ui/asm/powerpc/bad-reg.powerpc.stderr | 268 ++--- tests/ui/asm/powerpc/bad-reg.powerpc64.stderr | 258 ++--- .../ui/asm/powerpc/bad-reg.powerpc64le.stderr | 238 ++--- .../ui/asm/powerpc/bad-reg.powerpcspe.stderr | 938 ++++++++++++++++++ tests/ui/asm/powerpc/bad-reg.rs | 52 +- 9 files changed, 1547 insertions(+), 512 deletions(-) create mode 100644 tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index c6d22a51774c..05b24d710948 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::Symbol; -use crate::spec::{Arch, RelocModel, Target}; +use crate::spec::{Abi, Arch, RelocModel, Target}; pub struct ModifierInfo { pub modifier: char, @@ -936,6 +936,7 @@ pub enum InlineAsmClobberAbi { RiscVE, LoongArch, PowerPC, + PowerPCSPE, S390x, Bpf, Msp430, @@ -1000,7 +1001,11 @@ impl InlineAsmClobberAbi { _ => Err(&["C", "system"]), }, InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => match name { - "C" | "system" => Ok(InlineAsmClobberAbi::PowerPC), + "C" | "system" => Ok(if target.abi == Abi::Spe { + InlineAsmClobberAbi::PowerPCSPE + } else { + InlineAsmClobberAbi::PowerPC + }), _ => Err(&["C", "system"]), }, InlineAsmArch::S390x => match name { @@ -1271,8 +1276,21 @@ impl InlineAsmClobberAbi { ctr, lr, xer, + } + }, + InlineAsmClobberAbi::PowerPCSPE => clobbered_regs! { + PowerPC PowerPCInlineAsmReg { + // r0, r3-r12 + r0, + r3, r4, r5, r6, r7, + r8, r9, r10, r11, r12, - // These are only supported on PowerPC SPE targets. + // cr0-cr1, cr5-cr7, ctr, lr, xer, spe_acc + cr0, cr1, + cr5, cr6, cr7, + ctr, + lr, + xer, spe_acc, } }, diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs index 4fbe8adcbc61..fd0e118fcc87 100644 --- a/compiler/rustc_target/src/asm/powerpc.rs +++ b/compiler/rustc_target/src/asm/powerpc.rs @@ -115,6 +115,16 @@ fn reserved_v20to31( } } +fn spe_acc_target_check( + _arch: InlineAsmArch, + _reloc_model: RelocModel, + _target_features: &FxIndexSet, + target: &Target, + _is_clobber: bool, +) -> Result<(), &'static str> { + if target.abi == Abi::Spe { Ok(()) } else { Err("spe_acc is only available on spe targets") } +} + def_regs! { PowerPC PowerPCInlineAsmReg PowerPCInlineAsmRegClass { r0: reg = ["r0", "0"], @@ -286,7 +296,7 @@ def_regs! { ctr: ctr = ["ctr"], lr: lr = ["lr"], xer: xer = ["xer"], - spe_acc: spe_acc = ["spe_acc"], + spe_acc: spe_acc = ["spe_acc"] % spe_acc_target_check, #error = ["r1", "1", "sp"] => "the stack pointer cannot be used as an operand for inline asm", #error = ["r2", "2"] => diff --git a/tests/codegen-llvm/asm/powerpc-clobbers.rs b/tests/codegen-llvm/asm/powerpc-clobbers.rs index 6abf82cb0f4b..c146d58e4ab6 100644 --- a/tests/codegen-llvm/asm/powerpc-clobbers.rs +++ b/tests/codegen-llvm/asm/powerpc-clobbers.rs @@ -1,11 +1,13 @@ //@ add-minicore -//@ revisions: powerpc powerpc64 powerpc64le aix64 +//@ revisions: powerpc powerpc64 powerpc64le aix64 powerpcspe //@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu //@[powerpc] needs-llvm-components: powerpc //@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu //@[powerpc64] needs-llvm-components: powerpc //@[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu //@[powerpc64le] needs-llvm-components: powerpc +//@[powerpcspe] compile-flags: --target powerpc-unknown-linux-gnuspe +//@[powerpcspe] needs-llvm-components: powerpc //@[aix64] compile-flags: --target powerpc64-ibm-aix //@[aix64] needs-llvm-components: powerpc // ignore-tidy-linelength @@ -67,12 +69,22 @@ pub unsafe fn vs32_clobber() { asm!("", out("vs32") _, options(nostack, nomem, preserves_flags)); } +// This register is only available on SPE targets. +// CHECK-LABEL: @spe_acc_clobber +// powerpcspe: call void asm sideeffect "", "~{spe_acc}"() +#[no_mangle] +pub unsafe fn spe_acc_clobber() { + #[cfg(target_abi = "spe")] + asm!("", out("spe_acc") _, options(nostack, nomem, preserves_flags)); +} + // Output format depends on the availability of altivec and vsx // CHECK-LABEL: @clobber_abi -// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() -// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() -// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() -// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() +// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpcspe: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() #[no_mangle] pub unsafe fn clobber_abi() { asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); @@ -104,10 +116,11 @@ pub unsafe fn clobber_preservesflags() { // Output format depends on the availability of altivec and vsx // CHECK-LABEL: @clobber_abi_no_preserves_flags #[no_mangle] -// powerpc: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() -// powerpc64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() -// powerpc64le: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() -// aix64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() +// powerpc: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64le: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// aix64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpcspe: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer},~{spe_acc}"() pub unsafe fn clobber_abi_no_preserves_flags() { // Use a nop to prevent aliasing of identical functions here. asm!("nop", clobber_abi("C"), options(nostack, nomem)); diff --git a/tests/ui/asm/powerpc/bad-reg.aix64.stderr b/tests/ui/asm/powerpc/bad-reg.aix64.stderr index 4490053215b5..c7373780e382 100644 --- a/tests/ui/asm/powerpc/bad-reg.aix64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.aix64.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:137:18 + --> $DIR/bad-reg.rs:139:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:140:18 + --> $DIR/bad-reg.rs:142:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:143:26 + --> $DIR/bad-reg.rs:145:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:146:26 + --> $DIR/bad-reg.rs:148:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:150:18 + --> $DIR/bad-reg.rs:152:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:153:18 + --> $DIR/bad-reg.rs:155:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:156:26 + --> $DIR/bad-reg.rs:158:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:159:26 + --> $DIR/bad-reg.rs:161:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:163:18 + --> $DIR/bad-reg.rs:165:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:166:18 + --> $DIR/bad-reg.rs:168:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:169:26 + --> $DIR/bad-reg.rs:171:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:172:26 + --> $DIR/bad-reg.rs:174:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:176:18 + --> $DIR/bad-reg.rs:178:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:179:18 + --> $DIR/bad-reg.rs:181:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:182:26 + --> $DIR/bad-reg.rs:184:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:185:26 + --> $DIR/bad-reg.rs:187:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:189:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:199:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:201:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:203:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:205:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:206:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:220:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:222:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:224:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:226:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:226:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:264:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:266:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:268:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:270:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:270:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:328:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:330:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:332:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,21 +693,27 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:334:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` | | | register `vs63` +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:63:27 + --> $DIR/bad-reg.rs:65:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -715,7 +721,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:28 + --> $DIR/bad-reg.rs:68:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -723,7 +729,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:74:35 + --> $DIR/bad-reg.rs:76:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -731,7 +737,7 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:104:28 + --> $DIR/bad-reg.rs:106:28 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -739,7 +745,7 @@ LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:107:29 + --> $DIR/bad-reg.rs:109:29 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -747,7 +753,7 @@ LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:114:36 + --> $DIR/bad-reg.rs:116:36 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^ @@ -755,7 +761,7 @@ LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is ava = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:137:27 + --> $DIR/bad-reg.rs:139:27 | LL | asm!("", in("cr") x); | ^ @@ -763,7 +769,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:140:28 + --> $DIR/bad-reg.rs:142:28 | LL | asm!("", out("cr") x); | ^ @@ -771,7 +777,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:143:33 + --> $DIR/bad-reg.rs:145:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -779,7 +785,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:150:28 + --> $DIR/bad-reg.rs:152:28 | LL | asm!("", in("ctr") x); | ^ @@ -787,7 +793,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:153:29 + --> $DIR/bad-reg.rs:155:29 | LL | asm!("", out("ctr") x); | ^ @@ -795,7 +801,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:156:34 + --> $DIR/bad-reg.rs:158:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -803,7 +809,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:163:27 + --> $DIR/bad-reg.rs:165:27 | LL | asm!("", in("lr") x); | ^ @@ -811,7 +817,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:166:28 + --> $DIR/bad-reg.rs:168:28 | LL | asm!("", out("lr") x); | ^ @@ -819,7 +825,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:169:33 + --> $DIR/bad-reg.rs:171:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -827,7 +833,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:176:28 + --> $DIR/bad-reg.rs:178:28 | LL | asm!("", in("xer") x); | ^ @@ -835,7 +841,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:179:29 + --> $DIR/bad-reg.rs:181:29 | LL | asm!("", out("xer") x); | ^ @@ -843,12 +849,18 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:182:34 + --> $DIR/bad-reg.rs:184:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 112 previous errors +error: cannot use register `spe_acc`: spe_acc is only available on spe targets + --> $DIR/bad-reg.rs:338:18 + | +LL | asm!("", out("spe_acc") _); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 114 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr index 651e8cdfd3d5..5c4cd71c2d1a 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:137:18 + --> $DIR/bad-reg.rs:139:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:140:18 + --> $DIR/bad-reg.rs:142:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:143:26 + --> $DIR/bad-reg.rs:145:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:146:26 + --> $DIR/bad-reg.rs:148:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:150:18 + --> $DIR/bad-reg.rs:152:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:153:18 + --> $DIR/bad-reg.rs:155:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:156:26 + --> $DIR/bad-reg.rs:158:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:159:26 + --> $DIR/bad-reg.rs:161:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:163:18 + --> $DIR/bad-reg.rs:165:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:166:18 + --> $DIR/bad-reg.rs:168:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:169:26 + --> $DIR/bad-reg.rs:171:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:172:26 + --> $DIR/bad-reg.rs:174:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:176:18 + --> $DIR/bad-reg.rs:178:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:179:18 + --> $DIR/bad-reg.rs:181:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:182:26 + --> $DIR/bad-reg.rs:184:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:185:26 + --> $DIR/bad-reg.rs:187:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:189:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:199:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:201:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:203:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:205:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:206:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:220:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:222:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:224:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:226:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:226:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:264:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:266:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:268:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:270:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:270:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:328:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:330:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:332:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,147 +693,153 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:334:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` | | | register `vs63` +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", in("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", in("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:60:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", out("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:68:18 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:69:26 + --> $DIR/bad-reg.rs:71:26 | LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:71:26 + --> $DIR/bad-reg.rs:73:26 | LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:74:26 + --> $DIR/bad-reg.rs:76:26 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:77:26 + --> $DIR/bad-reg.rs:79:26 | LL | asm!("/* {} */", out(vreg) _); // requires altivec | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:96:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", in("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:98:18 + --> $DIR/bad-reg.rs:100:18 | LL | asm!("", out("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:102:18 | LL | asm!("", in("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:102:18 + --> $DIR/bad-reg.rs:104:18 | LL | asm!("", out("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:104:18 + --> $DIR/bad-reg.rs:106:18 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:107:18 + --> $DIR/bad-reg.rs:109:18 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:110:26 + --> $DIR/bad-reg.rs:112:26 | LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:112:26 + --> $DIR/bad-reg.rs:114:26 | LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:114:26 + --> $DIR/bad-reg.rs:116:26 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:117:26 + --> $DIR/bad-reg.rs:119:26 | LL | asm!("/* {} */", out(vsreg) _); // requires vsx | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:137:27 + --> $DIR/bad-reg.rs:139:27 | LL | asm!("", in("cr") x); | ^ @@ -841,7 +847,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:140:28 + --> $DIR/bad-reg.rs:142:28 | LL | asm!("", out("cr") x); | ^ @@ -849,7 +855,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:143:33 + --> $DIR/bad-reg.rs:145:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -857,7 +863,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:150:28 + --> $DIR/bad-reg.rs:152:28 | LL | asm!("", in("ctr") x); | ^ @@ -865,7 +871,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:153:29 + --> $DIR/bad-reg.rs:155:29 | LL | asm!("", out("ctr") x); | ^ @@ -873,7 +879,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:156:34 + --> $DIR/bad-reg.rs:158:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -881,7 +887,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:163:27 + --> $DIR/bad-reg.rs:165:27 | LL | asm!("", in("lr") x); | ^ @@ -889,7 +895,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:166:28 + --> $DIR/bad-reg.rs:168:28 | LL | asm!("", out("lr") x); | ^ @@ -897,7 +903,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:169:33 + --> $DIR/bad-reg.rs:171:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -905,7 +911,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:176:28 + --> $DIR/bad-reg.rs:178:28 | LL | asm!("", in("xer") x); | ^ @@ -913,7 +919,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:179:29 + --> $DIR/bad-reg.rs:181:29 | LL | asm!("", out("xer") x); | ^ @@ -921,12 +927,18 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:182:34 + --> $DIR/bad-reg.rs:184:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 127 previous errors +error: cannot use register `spe_acc`: spe_acc is only available on spe targets + --> $DIR/bad-reg.rs:338:18 + | +LL | asm!("", out("spe_acc") _); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 129 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr index 552fb0504b8d..151bb5682e03 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:137:18 + --> $DIR/bad-reg.rs:139:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:140:18 + --> $DIR/bad-reg.rs:142:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:143:26 + --> $DIR/bad-reg.rs:145:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:146:26 + --> $DIR/bad-reg.rs:148:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:150:18 + --> $DIR/bad-reg.rs:152:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:153:18 + --> $DIR/bad-reg.rs:155:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:156:26 + --> $DIR/bad-reg.rs:158:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:159:26 + --> $DIR/bad-reg.rs:161:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:163:18 + --> $DIR/bad-reg.rs:165:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:166:18 + --> $DIR/bad-reg.rs:168:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:169:26 + --> $DIR/bad-reg.rs:171:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:172:26 + --> $DIR/bad-reg.rs:174:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:176:18 + --> $DIR/bad-reg.rs:178:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:179:18 + --> $DIR/bad-reg.rs:181:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:182:26 + --> $DIR/bad-reg.rs:184:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:185:26 + --> $DIR/bad-reg.rs:187:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:189:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:199:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:201:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:203:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:205:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:206:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:220:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:222:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:224:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:226:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:226:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:264:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:266:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:268:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:270:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:270:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:328:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:330:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:332:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,21 +693,27 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:334:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` | | | register `vs63` +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:57:27 + --> $DIR/bad-reg.rs:59:27 | LL | asm!("", in("v0") v64x2); // requires vsx | ^^^^^ @@ -715,7 +721,7 @@ LL | asm!("", in("v0") v64x2); // requires vsx = note: this is required to use type `i64x2` with register class `vreg` error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:60:28 + --> $DIR/bad-reg.rs:62:28 | LL | asm!("", out("v0") v64x2); // requires vsx | ^^^^^ @@ -723,7 +729,7 @@ LL | asm!("", out("v0") v64x2); // requires vsx = note: this is required to use type `i64x2` with register class `vreg` error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:63:27 + --> $DIR/bad-reg.rs:65:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -731,7 +737,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:28 + --> $DIR/bad-reg.rs:68:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -739,7 +745,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:71:35 + --> $DIR/bad-reg.rs:73:35 | LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx | ^^^^^ @@ -747,7 +753,7 @@ LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx = note: this is required to use type `i64x2` with register class `vreg` error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:74:35 + --> $DIR/bad-reg.rs:76:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -755,67 +761,67 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:96:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", in("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:98:18 + --> $DIR/bad-reg.rs:100:18 | LL | asm!("", out("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:102:18 | LL | asm!("", in("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:102:18 + --> $DIR/bad-reg.rs:104:18 | LL | asm!("", out("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:104:18 + --> $DIR/bad-reg.rs:106:18 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:107:18 + --> $DIR/bad-reg.rs:109:18 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:110:26 + --> $DIR/bad-reg.rs:112:26 | LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:112:26 + --> $DIR/bad-reg.rs:114:26 | LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:114:26 + --> $DIR/bad-reg.rs:116:26 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:117:26 + --> $DIR/bad-reg.rs:119:26 | LL | asm!("/* {} */", out(vsreg) _); // requires vsx | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:137:27 + --> $DIR/bad-reg.rs:139:27 | LL | asm!("", in("cr") x); | ^ @@ -823,7 +829,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:140:28 + --> $DIR/bad-reg.rs:142:28 | LL | asm!("", out("cr") x); | ^ @@ -831,7 +837,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:143:33 + --> $DIR/bad-reg.rs:145:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -839,7 +845,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:150:28 + --> $DIR/bad-reg.rs:152:28 | LL | asm!("", in("ctr") x); | ^ @@ -847,7 +853,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:153:29 + --> $DIR/bad-reg.rs:155:29 | LL | asm!("", out("ctr") x); | ^ @@ -855,7 +861,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:156:34 + --> $DIR/bad-reg.rs:158:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -863,7 +869,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:163:27 + --> $DIR/bad-reg.rs:165:27 | LL | asm!("", in("lr") x); | ^ @@ -871,7 +877,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:166:28 + --> $DIR/bad-reg.rs:168:28 | LL | asm!("", out("lr") x); | ^ @@ -879,7 +885,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:169:33 + --> $DIR/bad-reg.rs:171:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -887,7 +893,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:176:28 + --> $DIR/bad-reg.rs:178:28 | LL | asm!("", in("xer") x); | ^ @@ -895,7 +901,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:179:29 + --> $DIR/bad-reg.rs:181:29 | LL | asm!("", out("xer") x); | ^ @@ -903,12 +909,18 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:182:34 + --> $DIR/bad-reg.rs:184:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 122 previous errors +error: cannot use register `spe_acc`: spe_acc is only available on spe targets + --> $DIR/bad-reg.rs:338:18 + | +LL | asm!("", out("spe_acc") _); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 124 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr index 4490053215b5..c7373780e382 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:137:18 + --> $DIR/bad-reg.rs:139:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:140:18 + --> $DIR/bad-reg.rs:142:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:143:26 + --> $DIR/bad-reg.rs:145:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:146:26 + --> $DIR/bad-reg.rs:148:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:150:18 + --> $DIR/bad-reg.rs:152:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:153:18 + --> $DIR/bad-reg.rs:155:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:156:26 + --> $DIR/bad-reg.rs:158:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:159:26 + --> $DIR/bad-reg.rs:161:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:163:18 + --> $DIR/bad-reg.rs:165:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:166:18 + --> $DIR/bad-reg.rs:168:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:169:26 + --> $DIR/bad-reg.rs:171:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:172:26 + --> $DIR/bad-reg.rs:174:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:176:18 + --> $DIR/bad-reg.rs:178:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:179:18 + --> $DIR/bad-reg.rs:181:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:182:26 + --> $DIR/bad-reg.rs:184:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:185:26 + --> $DIR/bad-reg.rs:187:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:189:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:199:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:201:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:203:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:205:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:206:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:220:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:222:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:224:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:226:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:226:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:264:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:266:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:268:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:270:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:270:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:328:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:330:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:332:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,21 +693,27 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:334:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` | | | register `vs63` +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:63:27 + --> $DIR/bad-reg.rs:65:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -715,7 +721,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:28 + --> $DIR/bad-reg.rs:68:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -723,7 +729,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:74:35 + --> $DIR/bad-reg.rs:76:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -731,7 +737,7 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:104:28 + --> $DIR/bad-reg.rs:106:28 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -739,7 +745,7 @@ LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:107:29 + --> $DIR/bad-reg.rs:109:29 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -747,7 +753,7 @@ LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:114:36 + --> $DIR/bad-reg.rs:116:36 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^ @@ -755,7 +761,7 @@ LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is ava = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:137:27 + --> $DIR/bad-reg.rs:139:27 | LL | asm!("", in("cr") x); | ^ @@ -763,7 +769,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:140:28 + --> $DIR/bad-reg.rs:142:28 | LL | asm!("", out("cr") x); | ^ @@ -771,7 +777,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:143:33 + --> $DIR/bad-reg.rs:145:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -779,7 +785,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:150:28 + --> $DIR/bad-reg.rs:152:28 | LL | asm!("", in("ctr") x); | ^ @@ -787,7 +793,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:153:29 + --> $DIR/bad-reg.rs:155:29 | LL | asm!("", out("ctr") x); | ^ @@ -795,7 +801,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:156:34 + --> $DIR/bad-reg.rs:158:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -803,7 +809,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:163:27 + --> $DIR/bad-reg.rs:165:27 | LL | asm!("", in("lr") x); | ^ @@ -811,7 +817,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:166:28 + --> $DIR/bad-reg.rs:168:28 | LL | asm!("", out("lr") x); | ^ @@ -819,7 +825,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:169:33 + --> $DIR/bad-reg.rs:171:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -827,7 +833,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:176:28 + --> $DIR/bad-reg.rs:178:28 | LL | asm!("", in("xer") x); | ^ @@ -835,7 +841,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:179:29 + --> $DIR/bad-reg.rs:181:29 | LL | asm!("", out("xer") x); | ^ @@ -843,12 +849,18 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:182:34 + --> $DIR/bad-reg.rs:184:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 112 previous errors +error: cannot use register `spe_acc`: spe_acc is only available on spe targets + --> $DIR/bad-reg.rs:338:18 + | +LL | asm!("", out("spe_acc") _); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 114 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr b/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr new file mode 100644 index 000000000000..2b4657bf358e --- /dev/null +++ b/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr @@ -0,0 +1,938 @@ +error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:38:18 + | +LL | asm!("", out("sp") _); + | ^^^^^^^^^^^ + +error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:40:18 + | +LL | asm!("", out("r2") _); + | ^^^^^^^^^^^ + +error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:46:18 + | +LL | asm!("", out("r30") _); + | ^^^^^^^^^^^^ + +error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:48:18 + | +LL | asm!("", out("fp") _); + | ^^^^^^^^^^^ + +error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:50:18 + | +LL | asm!("", out("vrsave") _); + | ^^^^^^^^^^^^^^^ + +error: register class `cr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:139:18 + | +LL | asm!("", in("cr") x); + | ^^^^^^^^^^ + +error: register class `cr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:142:18 + | +LL | asm!("", out("cr") x); + | ^^^^^^^^^^^ + +error: register class `cr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:145:26 + | +LL | asm!("/* {} */", in(cr) x); + | ^^^^^^^^ + +error: register class `cr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:148:26 + | +LL | asm!("/* {} */", out(cr) _); + | ^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:152:18 + | +LL | asm!("", in("ctr") x); + | ^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:155:18 + | +LL | asm!("", out("ctr") x); + | ^^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:158:26 + | +LL | asm!("/* {} */", in(ctr) x); + | ^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:161:26 + | +LL | asm!("/* {} */", out(ctr) _); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:165:18 + | +LL | asm!("", in("lr") x); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:168:18 + | +LL | asm!("", out("lr") x); + | ^^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:171:26 + | +LL | asm!("/* {} */", in(lr) x); + | ^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:174:26 + | +LL | asm!("/* {} */", out(lr) _); + | ^^^^^^^^^ + +error: register class `xer` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:178:18 + | +LL | asm!("", in("xer") x); + | ^^^^^^^^^^^ + +error: register class `xer` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:181:18 + | +LL | asm!("", out("xer") x); + | ^^^^^^^^^^^^ + +error: register class `xer` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:184:26 + | +LL | asm!("/* {} */", in(xer) x); + | ^^^^^^^^^ + +error: register class `xer` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:187:26 + | +LL | asm!("/* {} */", out(xer) _); + | ^^^^^^^^^^ + +error: register `cr0` conflicts with register `cr` + --> $DIR/bad-reg.rs:191:31 + | +LL | asm!("", out("cr") _, out("cr0") _); + | ----------- ^^^^^^^^^^^^ register `cr0` + | | + | register `cr` + +error: register `cr1` conflicts with register `cr` + --> $DIR/bad-reg.rs:193:31 + | +LL | asm!("", out("cr") _, out("cr1") _); + | ----------- ^^^^^^^^^^^^ register `cr1` + | | + | register `cr` + +error: register `cr2` conflicts with register `cr` + --> $DIR/bad-reg.rs:195:31 + | +LL | asm!("", out("cr") _, out("cr2") _); + | ----------- ^^^^^^^^^^^^ register `cr2` + | | + | register `cr` + +error: register `cr3` conflicts with register `cr` + --> $DIR/bad-reg.rs:197:31 + | +LL | asm!("", out("cr") _, out("cr3") _); + | ----------- ^^^^^^^^^^^^ register `cr3` + | | + | register `cr` + +error: register `cr4` conflicts with register `cr` + --> $DIR/bad-reg.rs:199:31 + | +LL | asm!("", out("cr") _, out("cr4") _); + | ----------- ^^^^^^^^^^^^ register `cr4` + | | + | register `cr` + +error: register `cr5` conflicts with register `cr` + --> $DIR/bad-reg.rs:201:31 + | +LL | asm!("", out("cr") _, out("cr5") _); + | ----------- ^^^^^^^^^^^^ register `cr5` + | | + | register `cr` + +error: register `cr6` conflicts with register `cr` + --> $DIR/bad-reg.rs:203:31 + | +LL | asm!("", out("cr") _, out("cr6") _); + | ----------- ^^^^^^^^^^^^ register `cr6` + | | + | register `cr` + +error: register `cr7` conflicts with register `cr` + --> $DIR/bad-reg.rs:205:31 + | +LL | asm!("", out("cr") _, out("cr7") _); + | ----------- ^^^^^^^^^^^^ register `cr7` + | | + | register `cr` + +error: register `vs0` conflicts with register `f0` + --> $DIR/bad-reg.rs:208:31 + | +LL | asm!("", out("f0") _, out("vs0") _); + | ----------- ^^^^^^^^^^^^ register `vs0` + | | + | register `f0` + +error: register `vs1` conflicts with register `f1` + --> $DIR/bad-reg.rs:210:31 + | +LL | asm!("", out("f1") _, out("vs1") _); + | ----------- ^^^^^^^^^^^^ register `vs1` + | | + | register `f1` + +error: register `vs2` conflicts with register `f2` + --> $DIR/bad-reg.rs:212:31 + | +LL | asm!("", out("f2") _, out("vs2") _); + | ----------- ^^^^^^^^^^^^ register `vs2` + | | + | register `f2` + +error: register `vs3` conflicts with register `f3` + --> $DIR/bad-reg.rs:214:31 + | +LL | asm!("", out("f3") _, out("vs3") _); + | ----------- ^^^^^^^^^^^^ register `vs3` + | | + | register `f3` + +error: register `vs4` conflicts with register `f4` + --> $DIR/bad-reg.rs:216:31 + | +LL | asm!("", out("f4") _, out("vs4") _); + | ----------- ^^^^^^^^^^^^ register `vs4` + | | + | register `f4` + +error: register `vs5` conflicts with register `f5` + --> $DIR/bad-reg.rs:218:31 + | +LL | asm!("", out("f5") _, out("vs5") _); + | ----------- ^^^^^^^^^^^^ register `vs5` + | | + | register `f5` + +error: register `vs6` conflicts with register `f6` + --> $DIR/bad-reg.rs:220:31 + | +LL | asm!("", out("f6") _, out("vs6") _); + | ----------- ^^^^^^^^^^^^ register `vs6` + | | + | register `f6` + +error: register `vs7` conflicts with register `f7` + --> $DIR/bad-reg.rs:222:31 + | +LL | asm!("", out("f7") _, out("vs7") _); + | ----------- ^^^^^^^^^^^^ register `vs7` + | | + | register `f7` + +error: register `vs8` conflicts with register `f8` + --> $DIR/bad-reg.rs:224:31 + | +LL | asm!("", out("f8") _, out("vs8") _); + | ----------- ^^^^^^^^^^^^ register `vs8` + | | + | register `f8` + +error: register `vs9` conflicts with register `f9` + --> $DIR/bad-reg.rs:226:31 + | +LL | asm!("", out("f9") _, out("vs9") _); + | ----------- ^^^^^^^^^^^^ register `vs9` + | | + | register `f9` + +error: register `vs10` conflicts with register `f10` + --> $DIR/bad-reg.rs:228:32 + | +LL | asm!("", out("f10") _, out("vs10") _); + | ------------ ^^^^^^^^^^^^^ register `vs10` + | | + | register `f10` + +error: register `vs11` conflicts with register `f11` + --> $DIR/bad-reg.rs:230:32 + | +LL | asm!("", out("f11") _, out("vs11") _); + | ------------ ^^^^^^^^^^^^^ register `vs11` + | | + | register `f11` + +error: register `vs12` conflicts with register `f12` + --> $DIR/bad-reg.rs:232:32 + | +LL | asm!("", out("f12") _, out("vs12") _); + | ------------ ^^^^^^^^^^^^^ register `vs12` + | | + | register `f12` + +error: register `vs13` conflicts with register `f13` + --> $DIR/bad-reg.rs:234:32 + | +LL | asm!("", out("f13") _, out("vs13") _); + | ------------ ^^^^^^^^^^^^^ register `vs13` + | | + | register `f13` + +error: register `vs14` conflicts with register `f14` + --> $DIR/bad-reg.rs:236:32 + | +LL | asm!("", out("f14") _, out("vs14") _); + | ------------ ^^^^^^^^^^^^^ register `vs14` + | | + | register `f14` + +error: register `vs15` conflicts with register `f15` + --> $DIR/bad-reg.rs:238:32 + | +LL | asm!("", out("f15") _, out("vs15") _); + | ------------ ^^^^^^^^^^^^^ register `vs15` + | | + | register `f15` + +error: register `vs16` conflicts with register `f16` + --> $DIR/bad-reg.rs:240:32 + | +LL | asm!("", out("f16") _, out("vs16") _); + | ------------ ^^^^^^^^^^^^^ register `vs16` + | | + | register `f16` + +error: register `vs17` conflicts with register `f17` + --> $DIR/bad-reg.rs:242:32 + | +LL | asm!("", out("f17") _, out("vs17") _); + | ------------ ^^^^^^^^^^^^^ register `vs17` + | | + | register `f17` + +error: register `vs18` conflicts with register `f18` + --> $DIR/bad-reg.rs:244:32 + | +LL | asm!("", out("f18") _, out("vs18") _); + | ------------ ^^^^^^^^^^^^^ register `vs18` + | | + | register `f18` + +error: register `vs19` conflicts with register `f19` + --> $DIR/bad-reg.rs:246:32 + | +LL | asm!("", out("f19") _, out("vs19") _); + | ------------ ^^^^^^^^^^^^^ register `vs19` + | | + | register `f19` + +error: register `vs20` conflicts with register `f20` + --> $DIR/bad-reg.rs:248:32 + | +LL | asm!("", out("f20") _, out("vs20") _); + | ------------ ^^^^^^^^^^^^^ register `vs20` + | | + | register `f20` + +error: register `vs21` conflicts with register `f21` + --> $DIR/bad-reg.rs:250:32 + | +LL | asm!("", out("f21") _, out("vs21") _); + | ------------ ^^^^^^^^^^^^^ register `vs21` + | | + | register `f21` + +error: register `vs22` conflicts with register `f22` + --> $DIR/bad-reg.rs:252:32 + | +LL | asm!("", out("f22") _, out("vs22") _); + | ------------ ^^^^^^^^^^^^^ register `vs22` + | | + | register `f22` + +error: register `vs23` conflicts with register `f23` + --> $DIR/bad-reg.rs:254:32 + | +LL | asm!("", out("f23") _, out("vs23") _); + | ------------ ^^^^^^^^^^^^^ register `vs23` + | | + | register `f23` + +error: register `vs24` conflicts with register `f24` + --> $DIR/bad-reg.rs:256:32 + | +LL | asm!("", out("f24") _, out("vs24") _); + | ------------ ^^^^^^^^^^^^^ register `vs24` + | | + | register `f24` + +error: register `vs25` conflicts with register `f25` + --> $DIR/bad-reg.rs:258:32 + | +LL | asm!("", out("f25") _, out("vs25") _); + | ------------ ^^^^^^^^^^^^^ register `vs25` + | | + | register `f25` + +error: register `vs26` conflicts with register `f26` + --> $DIR/bad-reg.rs:260:32 + | +LL | asm!("", out("f26") _, out("vs26") _); + | ------------ ^^^^^^^^^^^^^ register `vs26` + | | + | register `f26` + +error: register `vs27` conflicts with register `f27` + --> $DIR/bad-reg.rs:262:32 + | +LL | asm!("", out("f27") _, out("vs27") _); + | ------------ ^^^^^^^^^^^^^ register `vs27` + | | + | register `f27` + +error: register `vs28` conflicts with register `f28` + --> $DIR/bad-reg.rs:264:32 + | +LL | asm!("", out("f28") _, out("vs28") _); + | ------------ ^^^^^^^^^^^^^ register `vs28` + | | + | register `f28` + +error: register `vs29` conflicts with register `f29` + --> $DIR/bad-reg.rs:266:32 + | +LL | asm!("", out("f29") _, out("vs29") _); + | ------------ ^^^^^^^^^^^^^ register `vs29` + | | + | register `f29` + +error: register `vs30` conflicts with register `f30` + --> $DIR/bad-reg.rs:268:32 + | +LL | asm!("", out("f30") _, out("vs30") _); + | ------------ ^^^^^^^^^^^^^ register `vs30` + | | + | register `f30` + +error: register `vs31` conflicts with register `f31` + --> $DIR/bad-reg.rs:270:32 + | +LL | asm!("", out("f31") _, out("vs31") _); + | ------------ ^^^^^^^^^^^^^ register `vs31` + | | + | register `f31` + +error: register `v0` conflicts with register `vs32` + --> $DIR/bad-reg.rs:272:33 + | +LL | asm!("", out("vs32") _, out("v0") _); + | ------------- ^^^^^^^^^^^ register `v0` + | | + | register `vs32` + +error: register `v1` conflicts with register `vs33` + --> $DIR/bad-reg.rs:274:33 + | +LL | asm!("", out("vs33") _, out("v1") _); + | ------------- ^^^^^^^^^^^ register `v1` + | | + | register `vs33` + +error: register `v2` conflicts with register `vs34` + --> $DIR/bad-reg.rs:276:33 + | +LL | asm!("", out("vs34") _, out("v2") _); + | ------------- ^^^^^^^^^^^ register `v2` + | | + | register `vs34` + +error: register `v3` conflicts with register `vs35` + --> $DIR/bad-reg.rs:278:33 + | +LL | asm!("", out("vs35") _, out("v3") _); + | ------------- ^^^^^^^^^^^ register `v3` + | | + | register `vs35` + +error: register `v4` conflicts with register `vs36` + --> $DIR/bad-reg.rs:280:33 + | +LL | asm!("", out("vs36") _, out("v4") _); + | ------------- ^^^^^^^^^^^ register `v4` + | | + | register `vs36` + +error: register `v5` conflicts with register `vs37` + --> $DIR/bad-reg.rs:282:33 + | +LL | asm!("", out("vs37") _, out("v5") _); + | ------------- ^^^^^^^^^^^ register `v5` + | | + | register `vs37` + +error: register `v6` conflicts with register `vs38` + --> $DIR/bad-reg.rs:284:33 + | +LL | asm!("", out("vs38") _, out("v6") _); + | ------------- ^^^^^^^^^^^ register `v6` + | | + | register `vs38` + +error: register `v7` conflicts with register `vs39` + --> $DIR/bad-reg.rs:286:33 + | +LL | asm!("", out("vs39") _, out("v7") _); + | ------------- ^^^^^^^^^^^ register `v7` + | | + | register `vs39` + +error: register `v8` conflicts with register `vs40` + --> $DIR/bad-reg.rs:288:33 + | +LL | asm!("", out("vs40") _, out("v8") _); + | ------------- ^^^^^^^^^^^ register `v8` + | | + | register `vs40` + +error: register `v9` conflicts with register `vs41` + --> $DIR/bad-reg.rs:290:33 + | +LL | asm!("", out("vs41") _, out("v9") _); + | ------------- ^^^^^^^^^^^ register `v9` + | | + | register `vs41` + +error: register `v10` conflicts with register `vs42` + --> $DIR/bad-reg.rs:292:33 + | +LL | asm!("", out("vs42") _, out("v10") _); + | ------------- ^^^^^^^^^^^^ register `v10` + | | + | register `vs42` + +error: register `v11` conflicts with register `vs43` + --> $DIR/bad-reg.rs:294:33 + | +LL | asm!("", out("vs43") _, out("v11") _); + | ------------- ^^^^^^^^^^^^ register `v11` + | | + | register `vs43` + +error: register `v12` conflicts with register `vs44` + --> $DIR/bad-reg.rs:296:33 + | +LL | asm!("", out("vs44") _, out("v12") _); + | ------------- ^^^^^^^^^^^^ register `v12` + | | + | register `vs44` + +error: register `v13` conflicts with register `vs45` + --> $DIR/bad-reg.rs:298:33 + | +LL | asm!("", out("vs45") _, out("v13") _); + | ------------- ^^^^^^^^^^^^ register `v13` + | | + | register `vs45` + +error: register `v14` conflicts with register `vs46` + --> $DIR/bad-reg.rs:300:33 + | +LL | asm!("", out("vs46") _, out("v14") _); + | ------------- ^^^^^^^^^^^^ register `v14` + | | + | register `vs46` + +error: register `v15` conflicts with register `vs47` + --> $DIR/bad-reg.rs:302:33 + | +LL | asm!("", out("vs47") _, out("v15") _); + | ------------- ^^^^^^^^^^^^ register `v15` + | | + | register `vs47` + +error: register `v16` conflicts with register `vs48` + --> $DIR/bad-reg.rs:304:33 + | +LL | asm!("", out("vs48") _, out("v16") _); + | ------------- ^^^^^^^^^^^^ register `v16` + | | + | register `vs48` + +error: register `v17` conflicts with register `vs49` + --> $DIR/bad-reg.rs:306:33 + | +LL | asm!("", out("vs49") _, out("v17") _); + | ------------- ^^^^^^^^^^^^ register `v17` + | | + | register `vs49` + +error: register `v18` conflicts with register `vs50` + --> $DIR/bad-reg.rs:308:33 + | +LL | asm!("", out("vs50") _, out("v18") _); + | ------------- ^^^^^^^^^^^^ register `v18` + | | + | register `vs50` + +error: register `v19` conflicts with register `vs51` + --> $DIR/bad-reg.rs:310:33 + | +LL | asm!("", out("vs51") _, out("v19") _); + | ------------- ^^^^^^^^^^^^ register `v19` + | | + | register `vs51` + +error: register `v20` conflicts with register `vs52` + --> $DIR/bad-reg.rs:312:33 + | +LL | asm!("", out("vs52") _, out("v20") _); + | ------------- ^^^^^^^^^^^^ register `v20` + | | + | register `vs52` + +error: register `v21` conflicts with register `vs53` + --> $DIR/bad-reg.rs:314:33 + | +LL | asm!("", out("vs53") _, out("v21") _); + | ------------- ^^^^^^^^^^^^ register `v21` + | | + | register `vs53` + +error: register `v22` conflicts with register `vs54` + --> $DIR/bad-reg.rs:316:33 + | +LL | asm!("", out("vs54") _, out("v22") _); + | ------------- ^^^^^^^^^^^^ register `v22` + | | + | register `vs54` + +error: register `v23` conflicts with register `vs55` + --> $DIR/bad-reg.rs:318:33 + | +LL | asm!("", out("vs55") _, out("v23") _); + | ------------- ^^^^^^^^^^^^ register `v23` + | | + | register `vs55` + +error: register `v24` conflicts with register `vs56` + --> $DIR/bad-reg.rs:320:33 + | +LL | asm!("", out("vs56") _, out("v24") _); + | ------------- ^^^^^^^^^^^^ register `v24` + | | + | register `vs56` + +error: register `v25` conflicts with register `vs57` + --> $DIR/bad-reg.rs:322:33 + | +LL | asm!("", out("vs57") _, out("v25") _); + | ------------- ^^^^^^^^^^^^ register `v25` + | | + | register `vs57` + +error: register `v26` conflicts with register `vs58` + --> $DIR/bad-reg.rs:324:33 + | +LL | asm!("", out("vs58") _, out("v26") _); + | ------------- ^^^^^^^^^^^^ register `v26` + | | + | register `vs58` + +error: register `v27` conflicts with register `vs59` + --> $DIR/bad-reg.rs:326:33 + | +LL | asm!("", out("vs59") _, out("v27") _); + | ------------- ^^^^^^^^^^^^ register `v27` + | | + | register `vs59` + +error: register `v28` conflicts with register `vs60` + --> $DIR/bad-reg.rs:328:33 + | +LL | asm!("", out("vs60") _, out("v28") _); + | ------------- ^^^^^^^^^^^^ register `v28` + | | + | register `vs60` + +error: register `v29` conflicts with register `vs61` + --> $DIR/bad-reg.rs:330:33 + | +LL | asm!("", out("vs61") _, out("v29") _); + | ------------- ^^^^^^^^^^^^ register `v29` + | | + | register `vs61` + +error: register `v30` conflicts with register `vs62` + --> $DIR/bad-reg.rs:332:33 + | +LL | asm!("", out("vs62") _, out("v30") _); + | ------------- ^^^^^^^^^^^^ register `v30` + | | + | register `vs62` + +error: register `v31` conflicts with register `vs63` + --> $DIR/bad-reg.rs:334:33 + | +LL | asm!("", out("vs63") _, out("v31") _); + | ------------- ^^^^^^^^^^^^ register `v31` + | | + | register `vs63` + +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + +error: cannot use register `r13`: r13 is a reserved register on this target + --> $DIR/bad-reg.rs:42:18 + | +LL | asm!("", out("r13") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:44:18 + | +LL | asm!("", out("r29") _); + | ^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:55:18 + | +LL | asm!("", in("v0") v32x4); // requires altivec + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:57:18 + | +LL | asm!("", out("v0") v32x4); // requires altivec + | ^^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:59:18 + | +LL | asm!("", in("v0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:62:18 + | +LL | asm!("", out("v0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:65:18 + | +LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:68:18 + | +LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:71:26 + | +LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:73:26 + | +LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:76:26 + | +LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:79:26 + | +LL | asm!("/* {} */", out(vreg) _); // requires altivec + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:98:18 + | +LL | asm!("", in("vs0") v32x4); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:100:18 + | +LL | asm!("", out("vs0") v32x4); // requires vsx + | ^^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:102:18 + | +LL | asm!("", in("vs0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:104:18 + | +LL | asm!("", out("vs0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:106:18 + | +LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:109:18 + | +LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:112:26 + | +LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:114:26 + | +LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:116:26 + | +LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:119:26 + | +LL | asm!("/* {} */", out(vsreg) _); // requires vsx + | ^^^^^^^^^^^^ + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:139:27 + | +LL | asm!("", in("cr") x); + | ^ + | + = note: register class `cr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:142:28 + | +LL | asm!("", out("cr") x); + | ^ + | + = note: register class `cr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:145:33 + | +LL | asm!("/* {} */", in(cr) x); + | ^ + | + = note: register class `cr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:152:28 + | +LL | asm!("", in("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:155:29 + | +LL | asm!("", out("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:158:34 + | +LL | asm!("/* {} */", in(ctr) x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:165:27 + | +LL | asm!("", in("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:168:28 + | +LL | asm!("", out("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:171:33 + | +LL | asm!("/* {} */", in(lr) x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:178:28 + | +LL | asm!("", in("xer") x); + | ^ + | + = note: register class `xer` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:181:29 + | +LL | asm!("", out("xer") x); + | ^ + | + = note: register class `xer` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:184:34 + | +LL | asm!("/* {} */", in(xer) x); + | ^ + | + = note: register class `xer` supports these types: + +error: aborting due to 128 previous errors + diff --git a/tests/ui/asm/powerpc/bad-reg.rs b/tests/ui/asm/powerpc/bad-reg.rs index 7ceae5c6d8d3..c06dcf668d1b 100644 --- a/tests/ui/asm/powerpc/bad-reg.rs +++ b/tests/ui/asm/powerpc/bad-reg.rs @@ -1,5 +1,5 @@ //@ add-minicore -//@ revisions: powerpc powerpc64 powerpc64le aix64 +//@ revisions: powerpc powerpc64 powerpc64le aix64 powerpcspe //@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu //@[powerpc] needs-llvm-components: powerpc //@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu @@ -8,6 +8,8 @@ //@[powerpc64le] needs-llvm-components: powerpc //@[aix64] compile-flags: --target powerpc64-ibm-aix //@[aix64] needs-llvm-components: powerpc +//@[powerpcspe] compile-flags: --target powerpc-unknown-linux-gnuspe +//@[powerpcspe] needs-llvm-components: powerpc //@ ignore-backends: gcc // ignore-tidy-linelength @@ -40,7 +42,7 @@ fn f() { asm!("", out("r13") _); //~^ ERROR cannot use register `r13`: r13 is a reserved register on this target asm!("", out("r29") _); - //[powerpc]~^ ERROR cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm + //[powerpc,powerpcspe]~^ ERROR cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm asm!("", out("r30") _); //~^ ERROR invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm asm!("", out("fp") _); @@ -51,31 +53,31 @@ fn f() { // vreg asm!("", out("v0") _); // always ok asm!("", in("v0") v32x4); // requires altivec - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx asm!("", out("v0") v32x4); // requires altivec - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx asm!("", in("v0") v64x2); // requires vsx - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64]~^^ ERROR `vsx` target feature is not enabled asm!("", out("v0") v64x2); // requires vsx - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64]~^^ ERROR `vsx` target feature is not enabled asm!("", in("v0") x); // FIXME: should be ok if vsx is available - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("", out("v0") x); // FIXME: should be ok if vsx is available - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("/* {} */", in(vreg) v32x4); // requires altivec - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx asm!("/* {} */", in(vreg) v64x2); // requires vsx - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64]~^^ ERROR `vsx` target feature is not enabled asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("/* {} */", out(vreg) _); // requires altivec - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx // v20-v31 (vs52-vs63) are reserved on AIX with vec-default ABI (this ABI is not currently used in Rust's builtin AIX targets). asm!("", out("v20") _); asm!("", out("v21") _); @@ -94,28 +96,28 @@ fn f() { // vsreg asm!("", out("vs0") _); // always ok asm!("", in("vs0") v32x4); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("", out("vs0") v32x4); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("", in("vs0") v64x2); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("", out("vs0") v64x2); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("", in("vs0") x); // FIXME: should be ok if vsx is available - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature //[powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("", out("vs0") x); // FIXME: should be ok if vsx is available - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature //[powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("/* {} */", in(vsreg) v32x4); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("/* {} */", in(vsreg) v64x2); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature //[powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("/* {} */", out(vsreg) _); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature // v20-v31 (vs52-vs63) are reserved on AIX with vec-default ABI (this ABI is not currently used in Rust's builtin AIX targets). asm!("", out("vs52") _); @@ -331,5 +333,11 @@ fn f() { //~^ ERROR register `v30` conflicts with register `vs62` asm!("", out("vs63") _, out("v31") _); //~^ ERROR register `v31` conflicts with register `vs63` + + // powerpc-*spe target specific tests + asm!("", out("spe_acc") _); + //[aix64,powerpc,powerpc64,powerpc64le]~^ ERROR cannot use register `spe_acc`: spe_acc is only available on spe targets + asm!("/* {} */", out(spe_acc) _); + //~^ ERROR can only be used as a clobber } } From 76bee3a0444d67f4e89a5f0e3e713a3dcc1f8ba8 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 28 Nov 2025 14:16:56 -0500 Subject: [PATCH 0320/3801] Move the libgccjit.so file in a target directory Since GCC is not multi-target, we need multiple libgccjit.so. Our solution to have a directory per target so that we can have multiple libgccjit.so. --- compiler/rustc_codegen_gcc/src/lib.rs | 12 ++++++------ src/bootstrap/src/core/build_steps/gcc.rs | 11 +++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index c1506ee6176f..1bdc62f7f29c 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -181,18 +181,18 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); -fn libgccjit_path(sysroot_path: &Path) -> PathBuf { +fn libgccjit_path(sysroot_path: &Path, target_triple: &str) -> PathBuf { let sysroot_lib_dir = sysroot_path.join("lib"); - sysroot_lib_dir.join("libgccjit.so") + sysroot_lib_dir.join(target_triple).join("libgccjit.so") } -fn load_libgccjit_if_needed(sysroot_path: &Path) { +fn load_libgccjit_if_needed(sysroot_path: &Path, target_triple: &str) { if gccjit::is_loaded() { // Do not load a libgccjit second time. return; } - let libgccjit_target_lib_file = libgccjit_path(sysroot_path); + let libgccjit_target_lib_file = libgccjit_path(sysroot_path, target_triple); let path = libgccjit_target_lib_file.to_str().expect("libgccjit path"); let string = CString::new(path).expect("string to libgccjit path"); @@ -216,9 +216,9 @@ impl CodegenBackend for GccCodegenBackend { // invalid. // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. for path in sess.opts.sysroot.all_paths() { - let libgccjit_target_lib_file = libgccjit_path(path); + let libgccjit_target_lib_file = libgccjit_path(path, &sess.target.llvm_target); if let Ok(true) = fs::exists(libgccjit_target_lib_file) { - load_libgccjit_if_needed(path); + load_libgccjit_if_needed(path, &sess.target.llvm_target); break; } } diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index def794c98a41..d638dd45f3ac 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -27,6 +27,7 @@ pub struct Gcc { #[derive(Clone)] pub struct GccOutput { pub libgccjit: PathBuf, + target: TargetSelection, } impl GccOutput { @@ -46,7 +47,9 @@ impl GccOutput { format!("Cannot find libgccjit at {}", self.libgccjit.display()) ); - let dst = directory.join(target_filename); + let dest_dir = directory.join(self.target); + t!(fs::create_dir_all(&dest_dir)); + let dst = dest_dir.join(target_filename); builder.copy_link(&actual_libgccjit_path, &dst, FileType::NativeLibrary); } } @@ -70,7 +73,7 @@ impl Step for Gcc { // If GCC has already been built, we avoid building it again. let metadata = match get_gcc_build_status(builder, target) { - GccBuildStatus::AlreadyBuilt(path) => return GccOutput { libgccjit: path }, + GccBuildStatus::AlreadyBuilt(path) => return GccOutput { libgccjit: path, target }, GccBuildStatus::ShouldBuild(m) => m, }; @@ -80,14 +83,14 @@ impl Step for Gcc { let libgccjit_path = libgccjit_built_path(&metadata.install_dir); if builder.config.dry_run() { - return GccOutput { libgccjit: libgccjit_path }; + return GccOutput { libgccjit: libgccjit_path, target }; } build_gcc(&metadata, builder, target); t!(metadata.stamp.write()); - GccOutput { libgccjit: libgccjit_path } + GccOutput { libgccjit: libgccjit_path, target } } } From c0d4f5fab1104ef8b96750352917e018d0d99e04 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 28 Nov 2025 14:16:56 -0500 Subject: [PATCH 0321/3801] Move the libgccjit.so file in a target directory Since GCC is not multi-target, we need multiple libgccjit.so. Our solution to have a directory per target so that we can have multiple libgccjit.so. --- src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c1506ee6176f..1bdc62f7f29c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -181,18 +181,18 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); -fn libgccjit_path(sysroot_path: &Path) -> PathBuf { +fn libgccjit_path(sysroot_path: &Path, target_triple: &str) -> PathBuf { let sysroot_lib_dir = sysroot_path.join("lib"); - sysroot_lib_dir.join("libgccjit.so") + sysroot_lib_dir.join(target_triple).join("libgccjit.so") } -fn load_libgccjit_if_needed(sysroot_path: &Path) { +fn load_libgccjit_if_needed(sysroot_path: &Path, target_triple: &str) { if gccjit::is_loaded() { // Do not load a libgccjit second time. return; } - let libgccjit_target_lib_file = libgccjit_path(sysroot_path); + let libgccjit_target_lib_file = libgccjit_path(sysroot_path, target_triple); let path = libgccjit_target_lib_file.to_str().expect("libgccjit path"); let string = CString::new(path).expect("string to libgccjit path"); @@ -216,9 +216,9 @@ impl CodegenBackend for GccCodegenBackend { // invalid. // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. for path in sess.opts.sysroot.all_paths() { - let libgccjit_target_lib_file = libgccjit_path(path); + let libgccjit_target_lib_file = libgccjit_path(path, &sess.target.llvm_target); if let Ok(true) = fs::exists(libgccjit_target_lib_file) { - load_libgccjit_if_needed(path); + load_libgccjit_if_needed(path, &sess.target.llvm_target); break; } } From ea0995a91a2e4b44d54e99480d117683016c120b Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 28 Nov 2025 15:17:35 -0500 Subject: [PATCH 0322/3801] Ignore failing GCC test --- tests/mir-opt/inline/inline_instruction_set.rs | 1 + tests/ui/check-cfg/values-target-json.rs | 1 + tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs | 1 + tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs | 1 + tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs | 1 + .../cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs | 1 + tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs | 1 + .../cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs | 1 + .../cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs | 1 + tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs | 1 + tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs | 1 + .../ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs | 1 + .../ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs | 1 + tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs | 1 + tests/ui/force-inlining/asm.rs | 1 + tests/ui/issues/issue-37131.rs | 1 + tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs | 1 + tests/ui/print-request/supported-crate-types.rs | 2 ++ tests/ui/repr/repr_align_greater_usize.rs | 1 + .../abi-incompatible-target-feature-attribute-fcw.rs | 1 + tests/ui/target-feature/feature-hierarchy.rs | 1 + tests/ui/target-feature/no-llvm-leaks.rs | 1 + 22 files changed, 23 insertions(+) diff --git a/tests/mir-opt/inline/inline_instruction_set.rs b/tests/mir-opt/inline/inline_instruction_set.rs index fe2aaffa2a09..5baef21c6de7 100644 --- a/tests/mir-opt/inline/inline_instruction_set.rs +++ b/tests/mir-opt/inline/inline_instruction_set.rs @@ -4,6 +4,7 @@ // //@ compile-flags: --target thumbv4t-none-eabi //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index 2912c83b58de..defb286ed19b 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs @@ -5,6 +5,7 @@ //@ no-auto-check-cfg //@ needs-llvm-components: x86 //@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json +//@ ignore-backends: gcc #![feature(lang_items, no_core, auto_traits, rustc_attrs)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs index fc5db3cd7543..7cf63352234d 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs index e35138bf7cb8..8896235614e3 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs index b9d9fc92c8e2..4565d89f0dc8 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm //@ add-minicore +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs index 1ed5df459c7b..2d6b71502fce 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ incremental (required to trigger the bug) //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs index db9a51969a9f..5528865fc840 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs @@ -2,6 +2,7 @@ //@ build-pass //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items, intrinsics)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs index 290688f8ed95..8bbce0d7948b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, lang_items, no_core)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs index f23677e1ed71..3f99dcbdbb46 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, lang_items, no_core)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs index d4a6c1fa07c1..213b69b6fa20 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs @@ -2,6 +2,7 @@ //@ edition: 2018 //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index 023f50d636bf..bcae7f0c47f1 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs index 5326dd5765f1..53e98d2eb1bc 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs index 19abd1740e65..bfc8ad458359 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] diff --git a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs index 4971fcb6cb5b..33276576385f 100644 --- a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ needs-llvm-components: msp430 //@ compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ ignore-backends: gcc #![no_core] #![feature(no_core, lang_items)] diff --git a/tests/ui/force-inlining/asm.rs b/tests/ui/force-inlining/asm.rs index d48af8253d83..d48b9fc01be6 100644 --- a/tests/ui/force-inlining/asm.rs +++ b/tests/ui/force-inlining/asm.rs @@ -2,6 +2,7 @@ //@ build-fail //@ compile-flags: --crate-type=lib --target thumbv4t-none-eabi //@ needs-llvm-components: arm +//@ ignore-backends: gcc // Checks that forced inlining won't mix asm with incompatible instruction sets. diff --git a/tests/ui/issues/issue-37131.rs b/tests/ui/issues/issue-37131.rs index e91c76e1390e..875495d08ed7 100644 --- a/tests/ui/issues/issue-37131.rs +++ b/tests/ui/issues/issue-37131.rs @@ -7,5 +7,6 @@ //@ compile-flags: --target=thumbv6m-none-eabi //@ ignore-arm //@ needs-llvm-components: arm +//@ ignore-backends: gcc fn main() { } diff --git a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs index 58f0a74e674d..e8d277e36d28 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target x86_64-pc-windows-msvc //@ compile-flags: --crate-type lib --emit link //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![no_core] #![feature(no_core)] extern crate minicore; diff --git a/tests/ui/print-request/supported-crate-types.rs b/tests/ui/print-request/supported-crate-types.rs index 50185a231eeb..d816e33b413f 100644 --- a/tests/ui/print-request/supported-crate-types.rs +++ b/tests/ui/print-request/supported-crate-types.rs @@ -17,9 +17,11 @@ //@[wasm] compile-flags: --target=wasm32-unknown-unknown --print=supported-crate-types -Zunstable-options //@[wasm] needs-llvm-components: webassembly +//@[wasm] ignore-backends: gcc //@[musl] compile-flags: --target=x86_64-unknown-linux-musl --print=supported-crate-types -Zunstable-options //@[musl] needs-llvm-components: x86 +//@[musl] ignore-backends: gcc //@[linux] compile-flags: --target=x86_64-unknown-linux-gnu --print=supported-crate-types -Zunstable-options //@[linux] needs-llvm-components: x86 diff --git a/tests/ui/repr/repr_align_greater_usize.rs b/tests/ui/repr/repr_align_greater_usize.rs index d8eb03ef9525..52a4d23b1eca 100644 --- a/tests/ui/repr/repr_align_greater_usize.rs +++ b/tests/ui/repr/repr_align_greater_usize.rs @@ -5,6 +5,7 @@ //@[aarch32] build-pass //@[aarch32] needs-llvm-components: arm //@[aarch32] compile-flags: --target=thumbv7m-none-eabi +//@ ignore-backends: gcc // We should fail to compute alignment for types aligned higher than usize::MAX. // We can't handle alignments that require all 32 bits, so this only affects 16-bit. diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs index 8449b8ce0928..dba9e2366d9e 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target=aarch64-unknown-none-softfloat //@ needs-llvm-components: aarch64 //@ add-minicore +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] #![deny(aarch64_softfloat_neon)] diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs index 2e10c0e6e690..a14af97d7234 100644 --- a/tests/ui/target-feature/feature-hierarchy.rs +++ b/tests/ui/target-feature/feature-hierarchy.rs @@ -5,6 +5,7 @@ //@ [aarch64-sve2] needs-llvm-components: aarch64 //@ build-pass //@ add-minicore +//@ ignore-backends: gcc #![no_core] #![crate_type = "rlib"] #![feature(intrinsics, rustc_attrs, no_core, staged_api)] diff --git a/tests/ui/target-feature/no-llvm-leaks.rs b/tests/ui/target-feature/no-llvm-leaks.rs index fa72c88ead02..e4d964497ef3 100644 --- a/tests/ui/target-feature/no-llvm-leaks.rs +++ b/tests/ui/target-feature/no-llvm-leaks.rs @@ -2,6 +2,7 @@ //@ revisions: aarch64 x86-64 //@ [aarch64] compile-flags: -Ctarget-feature=+neon,+fp16,+fhm --target=aarch64-unknown-linux-gnu //@ [aarch64] needs-llvm-components: aarch64 +//@ [aarch64] ignore-backends: gcc //@ [x86-64] compile-flags: -Ctarget-feature=+sse4.2,+rdrand --target=x86_64-unknown-linux-gnu //@ [x86-64] needs-llvm-components: x86 //@ build-pass From 2a88ea189261650700564bde7f84fc1f06468d27 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 29 Nov 2025 09:50:03 -0500 Subject: [PATCH 0323/3801] Bless tests --- .../cmse-nonsecure-call/generics.stderr | 24 ++++++++--------- .../cmse-nonsecure-call/infer.rs | 1 + .../cmse-nonsecure-call/infer.stderr | 8 +++--- .../params-via-stack.stderr | 10 +++---- .../return-via-stack.stderr | 18 ++++++------- .../undeclared-lifetime.stderr | 2 +- .../wrong-abi-location-1.stderr | 2 +- .../wrong-abi-location-2.stderr | 2 +- .../cmse-nonsecure-entry/c-variadic.stderr | 8 +++--- .../cmse-nonsecure-entry/generics.stderr | 26 +++++++++---------- .../cmse-nonsecure-entry/infer.rs | 1 + .../cmse-nonsecure-entry/infer.stderr | 8 +++--- .../params-via-stack.stderr | 10 +++---- .../return-via-stack.stderr | 18 ++++++------- .../feature-gate-abi-msp430-interrupt.stderr | 14 +++++----- tests/ui/force-inlining/asm.stderr | 8 +++--- .../raw-dylib/windows/unsupported-abi.stderr | 4 +-- .../repr_align_greater_usize.msp430.stderr | 4 +-- ...atible-target-feature-attribute-fcw.stderr | 8 +++--- 19 files changed, 89 insertions(+), 87 deletions(-) diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr index a3848182ef14..64dbcd42033d 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr @@ -1,11 +1,11 @@ error: function pointer types may not have generic parameters - --> $DIR/generics.rs:14:40 + --> $DIR/generics.rs:15:40 | LL | f1: extern "cmse-nonsecure-call" fn(U, u32, u32, u32) -> u64, | ^^^^^^^^^ error[E0425]: cannot find type `U` in this scope - --> $DIR/generics.rs:14:50 + --> $DIR/generics.rs:15:50 | LL | struct Test { | - similarly named type parameter `T` defined here @@ -23,7 +23,7 @@ LL | struct Test { | +++ error[E0562]: `impl Trait` is not allowed in `fn` pointer parameters - --> $DIR/generics.rs:17:41 + --> $DIR/generics.rs:18:41 | LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl Copy, | ^^^^^^^^^ @@ -31,7 +31,7 @@ LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl C = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `fn` pointer return types - --> $DIR/generics.rs:17:70 + --> $DIR/generics.rs:18:70 | LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl Copy, | ^^^^^^^^^ @@ -39,7 +39,7 @@ LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl C = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `fn` pointer parameters - --> $DIR/generics.rs:20:42 + --> $DIR/generics.rs:21:42 | LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> (impl Copy, u32), | ^^^^^^^^^ @@ -47,7 +47,7 @@ LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `fn` pointer return types - --> $DIR/generics.rs:20:78 + --> $DIR/generics.rs:21:78 | LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> (impl Copy, u32), | ^^^^^^^^^ @@ -55,19 +55,19 @@ LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures - --> $DIR/generics.rs:23:41 + --> $DIR/generics.rs:24:41 | LL | f4: extern "cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, | ^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures - --> $DIR/generics.rs:24:41 + --> $DIR/generics.rs:25:41 | LL | f5: extern "cmse-nonsecure-call" fn(Wrapper, u32, u32, u32) -> u64, | ^^^^^^^^^^ error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:30:71 + --> $DIR/generics.rs:31:71 | LL | type WithTraitObject = extern "cmse-nonsecure-call" fn(&dyn Trait) -> &dyn Trait; | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -76,7 +76,7 @@ LL | type WithTraitObject = extern "cmse-nonsecure-call" fn(&dyn Trait) -> &dyn = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:34:60 + --> $DIR/generics.rs:35:60 | LL | extern "cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn Trait; | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -85,7 +85,7 @@ LL | extern "cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn Tra = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:41:60 + --> $DIR/generics.rs:42:60 | LL | extern "cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTransparent; | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -94,7 +94,7 @@ LL | extern "cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTranspare = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0045]: C-variadic functions with the "cmse-nonsecure-call" calling convention are not supported - --> $DIR/generics.rs:44:20 + --> $DIR/generics.rs:45:20 | LL | type WithVarArgs = extern "cmse-nonsecure-call" fn(u32, ...); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.rs index 3452dc268e59..231a21cd874b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.stderr index aab314c1ff25..398236b089b4 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.stderr @@ -1,23 +1,23 @@ error[E0282]: type annotations needed - --> $DIR/infer.rs:16:13 + --> $DIR/infer.rs:17:13 | LL | let _ = mem::transmute:: _, extern "cmse-nonsecure-call" fn() -> _>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:21:13 + --> $DIR/infer.rs:22:13 | LL | let _ = mem::transmute:: (i32, _), extern "cmse-nonsecure-call" fn() -> (i32, _)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:26:13 + --> $DIR/infer.rs:27:13 | LL | let _ = mem::transmute:: (), extern "cmse-nonsecure-call" fn(_: _) -> ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:32:9 + --> $DIR/infer.rs:33:9 | LL | mem::transmute:: (), extern "cmse-nonsecure-call" fn(_: (i32, _)) -> ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr index 5a059e4df7b1..a3201844035c 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:16:64 + --> $DIR/params-via-stack.rs:17:64 | LL | f1: extern "cmse-nonsecure-call" fn(u32, u32, u32, u32, x: u32, y: u32), | ^^^ ^^^ does not fit in the available registers @@ -9,7 +9,7 @@ LL | f1: extern "cmse-nonsecure-call" fn(u32, u32, u32, u32, x: u32, y: u32) = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:17:61 + --> $DIR/params-via-stack.rs:18:61 | LL | f2: extern "cmse-nonsecure-call" fn(u32, u32, u32, u16, u16), | ^^^ does not fit in the available registers @@ -17,7 +17,7 @@ LL | f2: extern "cmse-nonsecure-call" fn(u32, u32, u32, u16, u16), = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:18:51 + --> $DIR/params-via-stack.rs:19:51 | LL | f3: extern "cmse-nonsecure-call" fn(u32, u64, u32), | ^^^ does not fit in the available registers @@ -25,7 +25,7 @@ LL | f3: extern "cmse-nonsecure-call" fn(u32, u64, u32), = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:19:56 + --> $DIR/params-via-stack.rs:20:56 | LL | f4: extern "cmse-nonsecure-call" fn(AlignRelevant, u32), | ^^^ does not fit in the available registers @@ -33,7 +33,7 @@ LL | f4: extern "cmse-nonsecure-call" fn(AlignRelevant, u32), = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:20:41 + --> $DIR/params-via-stack.rs:21:41 | LL | f5: extern "cmse-nonsecure-call" fn([u32; 5]), | ^^^^^^^^ does not fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr index ddf969c1bce1..4351444225b5 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:36:48 + --> $DIR/return-via-stack.rs:37:48 | LL | u128: extern "cmse-nonsecure-call" fn() -> u128, | ^^^^ this type doesn't fit in the available registers @@ -8,7 +8,7 @@ LL | u128: extern "cmse-nonsecure-call" fn() -> u128, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:37:48 + --> $DIR/return-via-stack.rs:38:48 | LL | i128: extern "cmse-nonsecure-call" fn() -> i128, | ^^^^ this type doesn't fit in the available registers @@ -17,7 +17,7 @@ LL | i128: extern "cmse-nonsecure-call" fn() -> i128, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:26:46 + --> $DIR/return-via-stack.rs:27:46 | LL | f1: extern "cmse-nonsecure-call" fn() -> ReprCU64, | ^^^^^^^^ this type doesn't fit in the available registers @@ -26,7 +26,7 @@ LL | f1: extern "cmse-nonsecure-call" fn() -> ReprCU64, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:27:46 + --> $DIR/return-via-stack.rs:28:46 | LL | f2: extern "cmse-nonsecure-call" fn() -> ReprCBytes, | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -35,7 +35,7 @@ LL | f2: extern "cmse-nonsecure-call" fn() -> ReprCBytes, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:28:46 + --> $DIR/return-via-stack.rs:29:46 | LL | f3: extern "cmse-nonsecure-call" fn() -> U64Compound, | ^^^^^^^^^^^ this type doesn't fit in the available registers @@ -44,7 +44,7 @@ LL | f3: extern "cmse-nonsecure-call" fn() -> U64Compound, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:29:46 + --> $DIR/return-via-stack.rs:30:46 | LL | f4: extern "cmse-nonsecure-call" fn() -> ReprCAlign16, | ^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -53,7 +53,7 @@ LL | f4: extern "cmse-nonsecure-call" fn() -> ReprCAlign16, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:30:46 + --> $DIR/return-via-stack.rs:31:46 | LL | f5: extern "cmse-nonsecure-call" fn() -> [u8; 5], | ^^^^^^^ this type doesn't fit in the available registers @@ -62,7 +62,7 @@ LL | f5: extern "cmse-nonsecure-call" fn() -> [u8; 5], = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:52:46 + --> $DIR/return-via-stack.rs:53:46 | LL | f1: extern "cmse-nonsecure-call" fn() -> ReprRustUnionU64, | ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -71,7 +71,7 @@ LL | f1: extern "cmse-nonsecure-call" fn() -> ReprRustUnionU64, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:53:46 + --> $DIR/return-via-stack.rs:54:46 | LL | f2: extern "cmse-nonsecure-call" fn() -> ReprCUnionU64, | ^^^^^^^^^^^^^ this type doesn't fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr index 7300bdb72cdd..99255e9f22b1 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/undeclared-lifetime.rs:15:43 + --> $DIR/undeclared-lifetime.rs:16:43 | LL | id::(PhantomData); | ^^ undeclared lifetime diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr index b9cccecc64bf..2ed3a6569719 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr @@ -1,5 +1,5 @@ error[E0781]: the `"cmse-nonsecure-call"` ABI is only allowed on function pointers - --> $DIR/wrong-abi-location-1.rs:10:1 + --> $DIR/wrong-abi-location-1.rs:11:1 | LL | pub extern "cmse-nonsecure-call" fn test() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr index 437d7b80b1fd..0fe8341b8d7d 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr @@ -1,5 +1,5 @@ error[E0781]: the `"cmse-nonsecure-call"` ABI is only allowed on function pointers - --> $DIR/wrong-abi-location-2.rs:10:1 + --> $DIR/wrong-abi-location-2.rs:11:1 | LL | / extern "cmse-nonsecure-call" { LL | | fn test(); diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr index 5b0924d6f2af..c8f4ef98c124 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr @@ -1,5 +1,5 @@ error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions - --> $DIR/c-variadic.rs:14:60 + --> $DIR/c-variadic.rs:15:60 | LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { | ----------------------------- ^^^^^^ @@ -9,13 +9,13 @@ LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: functions cannot be both `async` and C-variadic - --> $DIR/c-variadic.rs:19:1 + --> $DIR/c-variadic.rs:20:1 | LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { | ^^^^^ `async` because of this ^^^^^^ C-variadic because of this error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions - --> $DIR/c-variadic.rs:19:68 + --> $DIR/c-variadic.rs:20:68 | LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { | ----------------------------- ^^^^^^ @@ -25,7 +25,7 @@ LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/c-variadic.rs:25:1 + --> $DIR/c-variadic.rs:26:1 | LL | async unsafe extern "cmse-nonsecure-entry" fn async_is_not_allowed() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr index 5ddd29883f86..653e8f73012b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -1,53 +1,53 @@ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:31:8 + --> $DIR/generics.rs:32:8 | LL | _: U, | ^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:64:48 + --> $DIR/generics.rs:65:48 | LL | extern "cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { | ^^^^^^^^^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:79:57 + --> $DIR/generics.rs:80:57 | LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy { | ^^^^^^^^^ error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:79:71 + --> $DIR/generics.rs:80:71 | LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy { | ^^^^^^^^^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:86:8 + --> $DIR/generics.rs:87:8 | LL | v: (impl Copy, i32), | ^^^^^^^^^^^^^^^^ error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:88:6 + --> $DIR/generics.rs:89:6 | LL | ) -> (impl Copy, i32) { | ^^^^^^^^^^^^^^^^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:14:57 + --> $DIR/generics.rs:15:57 | LL | extern "cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 { | ^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:20:12 + --> $DIR/generics.rs:21:12 | LL | _: Wrapper, | ^^^^^^^^^^ error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:46:65 + --> $DIR/generics.rs:47:65 | LL | extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait { | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -56,7 +56,7 @@ LL | extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:51:80 + --> $DIR/generics.rs:52:80 | LL | extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) -> &'static dyn Trait { | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -65,7 +65,7 @@ LL | extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:59:81 + --> $DIR/generics.rs:60:81 | LL | extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> WrapperTransparent { | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -74,13 +74,13 @@ LL | extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:69:57 + --> $DIR/generics.rs:70:57 | LL | extern "cmse-nonsecure-entry" fn return_impl_trait() -> impl Copy { | ^^^^^^^^^ error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:74:64 + --> $DIR/generics.rs:75:64 | LL | extern "cmse-nonsecure-entry" fn return_impl_trait_nested() -> (impl Copy, i32) { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.rs index 75a08ff40356..ceb09c8ad6f7 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.stderr index 4243771c3e67..f9352a8a2fbf 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.stderr @@ -1,23 +1,23 @@ error[E0282]: type annotations needed - --> $DIR/infer.rs:16:13 + --> $DIR/infer.rs:17:13 | LL | let _ = mem::transmute:: _, extern "cmse-nonsecure-entry" fn() -> _>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:21:13 + --> $DIR/infer.rs:22:13 | LL | let _ = mem::transmute:: (i32, _), extern "cmse-nonsecure-entry" fn() -> (i32, _)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:26:13 + --> $DIR/infer.rs:27:13 | LL | let _ = mem::transmute:: (), extern "cmse-nonsecure-entry" fn(_: _) -> ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:31:13 + --> $DIR/infer.rs:32:13 | LL | let _ = mem::transmute::< | _____________^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr index 3d523fc7be67..af8277d314ba 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:15:76 + --> $DIR/params-via-stack.rs:16:76 | LL | pub extern "cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {} | ^^^ ^^^ does not fit in the available registers @@ -9,7 +9,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:17:76 + --> $DIR/params-via-stack.rs:18:76 | LL | pub extern "cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {} | ^^^ does not fit in the available registers @@ -17,7 +17,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:19:60 + --> $DIR/params-via-stack.rs:20:60 | LL | pub extern "cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} | ^^^ does not fit in the available registers @@ -25,7 +25,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:21:62 + --> $DIR/params-via-stack.rs:22:62 | LL | pub extern "cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} | ^^^ does not fit in the available registers @@ -33,7 +33,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:25:44 + --> $DIR/params-via-stack.rs:26:44 | LL | pub extern "cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} | ^^^^^^^^ does not fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr index 07ee31bef23c..c5effed92ae9 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:24:46 + --> $DIR/return-via-stack.rs:25:46 | LL | pub extern "cmse-nonsecure-entry" fn f1() -> ReprCU64 { | ^^^^^^^^ this type doesn't fit in the available registers @@ -8,7 +8,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f1() -> ReprCU64 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:29:46 + --> $DIR/return-via-stack.rs:30:46 | LL | pub extern "cmse-nonsecure-entry" fn f2() -> ReprCBytes { | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -17,7 +17,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f2() -> ReprCBytes { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:34:46 + --> $DIR/return-via-stack.rs:35:46 | LL | pub extern "cmse-nonsecure-entry" fn f3() -> U64Compound { | ^^^^^^^^^^^ this type doesn't fit in the available registers @@ -26,7 +26,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f3() -> U64Compound { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:39:46 + --> $DIR/return-via-stack.rs:40:46 | LL | pub extern "cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { | ^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -35,7 +35,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:46:46 + --> $DIR/return-via-stack.rs:47:46 | LL | pub extern "cmse-nonsecure-entry" fn f5() -> [u8; 5] { | ^^^^^^^ this type doesn't fit in the available registers @@ -44,7 +44,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f5() -> [u8; 5] { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:52:48 + --> $DIR/return-via-stack.rs:53:48 | LL | pub extern "cmse-nonsecure-entry" fn u128() -> u128 { | ^^^^ this type doesn't fit in the available registers @@ -53,7 +53,7 @@ LL | pub extern "cmse-nonsecure-entry" fn u128() -> u128 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:58:48 + --> $DIR/return-via-stack.rs:59:48 | LL | pub extern "cmse-nonsecure-entry" fn i128() -> i128 { | ^^^^ this type doesn't fit in the available registers @@ -62,7 +62,7 @@ LL | pub extern "cmse-nonsecure-entry" fn i128() -> i128 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:75:54 + --> $DIR/return-via-stack.rs:76:54 | LL | pub extern "cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { | ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -71,7 +71,7 @@ LL | pub extern "cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:80:51 + --> $DIR/return-via-stack.rs:81:51 | LL | pub extern "cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 { | ^^^^^^^^^^^^^ this type doesn't fit in the available registers diff --git a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr index 4a995b4efa6f..f90918a64b38 100644 --- a/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr +++ b/tests/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr @@ -1,5 +1,5 @@ error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:10:8 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:11:8 | LL | extern "msp430-interrupt" fn f() {} | ^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | extern "msp430-interrupt" fn f() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:14:12 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:15:12 | LL | extern "msp430-interrupt" fn m(); | ^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | extern "msp430-interrupt" fn m(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:17:12 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:18:12 | LL | extern "msp430-interrupt" fn dm() {} | ^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | extern "msp430-interrupt" fn dm() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:23:12 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:24:12 | LL | extern "msp430-interrupt" fn m() {} | ^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | extern "msp430-interrupt" fn m() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:28:12 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:29:12 | LL | extern "msp430-interrupt" fn im() {} | ^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | extern "msp430-interrupt" fn im() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:32:18 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:33:18 | LL | type TA = extern "msp430-interrupt" fn(); | ^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | type TA = extern "msp430-interrupt" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the extern "msp430-interrupt" ABI is experimental and subject to change - --> $DIR/feature-gate-abi-msp430-interrupt.rs:35:8 + --> $DIR/feature-gate-abi-msp430-interrupt.rs:36:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/force-inlining/asm.stderr b/tests/ui/force-inlining/asm.stderr index 1744c0215bb4..a73b3f665ae2 100644 --- a/tests/ui/force-inlining/asm.stderr +++ b/tests/ui/force-inlining/asm.stderr @@ -1,5 +1,5 @@ error: `instruction_set_a32` could not be inlined into `t32` but is required to be inlined - --> $DIR/asm.rs:45:5 + --> $DIR/asm.rs:46:5 | LL | instruction_set_a32(); | ^^^^^^^^^^^^^^^^^^^^^ ...`instruction_set_a32` called here @@ -7,7 +7,7 @@ LL | instruction_set_a32(); = note: could not be inlined due to: incompatible instruction set error: `inline_always_and_using_inline_asm` could not be inlined into `t32` but is required to be inlined - --> $DIR/asm.rs:49:5 + --> $DIR/asm.rs:50:5 | LL | inline_always_and_using_inline_asm(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...`inline_always_and_using_inline_asm` called here @@ -15,7 +15,7 @@ LL | inline_always_and_using_inline_asm(); = note: could not be inlined due to: cannot move inline-asm across instruction sets error: `instruction_set_a32` could not be inlined into `default` but is required to be inlined - --> $DIR/asm.rs:54:5 + --> $DIR/asm.rs:55:5 | LL | instruction_set_a32(); | ^^^^^^^^^^^^^^^^^^^^^ ...`instruction_set_a32` called here @@ -23,7 +23,7 @@ LL | instruction_set_a32(); = note: could not be inlined due to: incompatible instruction set error: `instruction_set_t32` could not be inlined into `default` but is required to be inlined - --> $DIR/asm.rs:56:5 + --> $DIR/asm.rs:57:5 | LL | instruction_set_t32(); | ^^^^^^^^^^^^^^^^^^^^^ ...`instruction_set_t32` called here diff --git a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr index 8727e55f4cef..5a574636245d 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr @@ -1,5 +1,5 @@ warning: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported-abi.rs:13:1 + --> $DIR/unsupported-abi.rs:14:1 | LL | / extern "stdcall" { LL | | @@ -15,7 +15,7 @@ LL | | } = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture - --> $DIR/unsupported-abi.rs:16:5 + --> $DIR/unsupported-abi.rs:17:5 | LL | fn f(x: i32); | ^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr_align_greater_usize.msp430.stderr b/tests/ui/repr/repr_align_greater_usize.msp430.stderr index db25cb1b5f2e..a7b06acb6752 100644 --- a/tests/ui/repr/repr_align_greater_usize.msp430.stderr +++ b/tests/ui/repr/repr_align_greater_usize.msp430.stderr @@ -1,5 +1,5 @@ error[E0589]: alignment must not be greater than `isize::MAX` bytes - --> $DIR/repr_align_greater_usize.rs:22:8 + --> $DIR/repr_align_greater_usize.rs:23:8 | LL | #[repr(align(32768))] | ^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[repr(align(32768))] = note: `isize::MAX` is 32767 for the current target error[E0589]: alignment must not be greater than `isize::MAX` bytes - --> $DIR/repr_align_greater_usize.rs:25:8 + --> $DIR/repr_align_greater_usize.rs:26:8 | LL | #[repr(align(65536))] | ^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr index e3bb8bef9a00..9595d1aba477 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr @@ -1,5 +1,5 @@ error: enabling the `neon` target feature on the current target is unsound due to ABI issues - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:12:18 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:13:18 | LL | #[target_feature(enable = "neon")] | ^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[target_feature(enable = "neon")] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #134375 note: the lint level is defined here - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:7:9 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:8:9 | LL | #![deny(aarch64_softfloat_neon)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ error: aborting due to 1 previous error Future incompatibility report: Future breakage diagnostic: error: enabling the `neon` target feature on the current target is unsound due to ABI issues - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:12:18 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:13:18 | LL | #[target_feature(enable = "neon")] | ^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | #[target_feature(enable = "neon")] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #134375 note: the lint level is defined here - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:7:9 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:8:9 | LL | #![deny(aarch64_softfloat_neon)] | ^^^^^^^^^^^^^^^^^^^^^^ From 2a74c626d66995293f5341a932c7003939253ef0 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 29 Nov 2025 11:09:23 -0500 Subject: [PATCH 0324/3801] Move to rustlib directory --- compiler/rustc_codegen_gcc/src/lib.rs | 5 +++-- src/bootstrap/src/core/build_steps/gcc.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 1bdc62f7f29c..c40ee39ba6e4 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -182,8 +182,9 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); fn libgccjit_path(sysroot_path: &Path, target_triple: &str) -> PathBuf { - let sysroot_lib_dir = sysroot_path.join("lib"); - sysroot_lib_dir.join(target_triple).join("libgccjit.so") + let sysroot_lib_dir = sysroot_path.join("lib").join("rustlib"); + let libgccjit_target_lib_file = + sysroot_lib_dir.join(target_triple).join("lib").join("libgccjit.so"); } fn load_libgccjit_if_needed(sysroot_path: &Path, target_triple: &str) { diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index d638dd45f3ac..fc87c48f17b6 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -47,7 +47,7 @@ impl GccOutput { format!("Cannot find libgccjit at {}", self.libgccjit.display()) ); - let dest_dir = directory.join(self.target); + let dest_dir = directory.join("rustlib").join(self.target).join("lib"); t!(fs::create_dir_all(&dest_dir)); let dst = dest_dir.join(target_filename); builder.copy_link(&actual_libgccjit_path, &dst, FileType::NativeLibrary); From 8e77eeb0178af56928d4b8b1d18e71ac82e1e76b Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 29 Nov 2025 11:09:23 -0500 Subject: [PATCH 0325/3801] Move to rustlib directory --- src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1bdc62f7f29c..c40ee39ba6e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -182,8 +182,9 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); fn libgccjit_path(sysroot_path: &Path, target_triple: &str) -> PathBuf { - let sysroot_lib_dir = sysroot_path.join("lib"); - sysroot_lib_dir.join(target_triple).join("libgccjit.so") + let sysroot_lib_dir = sysroot_path.join("lib").join("rustlib"); + let libgccjit_target_lib_file = + sysroot_lib_dir.join(target_triple).join("lib").join("libgccjit.so"); } fn load_libgccjit_if_needed(sysroot_path: &Path, target_triple: &str) { From 58f3f313b3789a9aa36d99687e4b7f85f7499619 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 29 Nov 2025 12:19:14 -0500 Subject: [PATCH 0326/3801] Fix lib path --- compiler/rustc_codegen_gcc/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index c40ee39ba6e4..6c072e7daca2 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -98,6 +98,7 @@ use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames}; +use rustc_session::filesearch::make_target_lib_path; use rustc_span::Symbol; use rustc_target::spec::{Arch, RelocModel}; use tempfile::TempDir; @@ -182,9 +183,7 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); fn libgccjit_path(sysroot_path: &Path, target_triple: &str) -> PathBuf { - let sysroot_lib_dir = sysroot_path.join("lib").join("rustlib"); - let libgccjit_target_lib_file = - sysroot_lib_dir.join(target_triple).join("lib").join("libgccjit.so"); + make_target_lib_path(sysroot_path, target_triple).join("libgccjit.so") } fn load_libgccjit_if_needed(sysroot_path: &Path, target_triple: &str) { From b00418c0f5752f11aa2455abe927dd593957e3c7 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 29 Nov 2025 12:19:14 -0500 Subject: [PATCH 0327/3801] Fix lib path --- src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c40ee39ba6e4..6c072e7daca2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -98,6 +98,7 @@ use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames}; +use rustc_session::filesearch::make_target_lib_path; use rustc_span::Symbol; use rustc_target::spec::{Arch, RelocModel}; use tempfile::TempDir; @@ -182,9 +183,7 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); fn libgccjit_path(sysroot_path: &Path, target_triple: &str) -> PathBuf { - let sysroot_lib_dir = sysroot_path.join("lib").join("rustlib"); - let libgccjit_target_lib_file = - sysroot_lib_dir.join(target_triple).join("lib").join("libgccjit.so"); + make_target_lib_path(sysroot_path, target_triple).join("libgccjit.so") } fn load_libgccjit_if_needed(sysroot_path: &Path, target_triple: &str) { From 42059a3041bfceabbee8edd42b26c643901886cd Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 5 Dec 2025 09:58:37 -0500 Subject: [PATCH 0328/3801] Remove libgccjit_path function --- compiler/rustc_codegen_gcc/src/lib.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 6c072e7daca2..a77239e23b4e 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -182,17 +182,12 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); -fn libgccjit_path(sysroot_path: &Path, target_triple: &str) -> PathBuf { - make_target_lib_path(sysroot_path, target_triple).join("libgccjit.so") -} - -fn load_libgccjit_if_needed(sysroot_path: &Path, target_triple: &str) { +fn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) { if gccjit::is_loaded() { // Do not load a libgccjit second time. return; } - let libgccjit_target_lib_file = libgccjit_path(sysroot_path, target_triple); let path = libgccjit_target_lib_file.to_str().expect("libgccjit path"); let string = CString::new(path).expect("string to libgccjit path"); @@ -216,9 +211,10 @@ impl CodegenBackend for GccCodegenBackend { // invalid. // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. for path in sess.opts.sysroot.all_paths() { - let libgccjit_target_lib_file = libgccjit_path(path, &sess.target.llvm_target); - if let Ok(true) = fs::exists(libgccjit_target_lib_file) { - load_libgccjit_if_needed(path, &sess.target.llvm_target); + let libgccjit_target_lib_file = + make_target_lib_path(path, &sess.target.llvm_target).join("libgccjit.so"); + if let Ok(true) = fs::exists(&libgccjit_target_lib_file) { + load_libgccjit_if_needed(&libgccjit_target_lib_file); break; } } From ff29461e1a03d52687f81da8d9ce44f5358d5f21 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 5 Dec 2025 09:58:37 -0500 Subject: [PATCH 0329/3801] Remove libgccjit_path function --- src/lib.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6c072e7daca2..a77239e23b4e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -182,17 +182,12 @@ pub struct GccCodegenBackend { static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); -fn libgccjit_path(sysroot_path: &Path, target_triple: &str) -> PathBuf { - make_target_lib_path(sysroot_path, target_triple).join("libgccjit.so") -} - -fn load_libgccjit_if_needed(sysroot_path: &Path, target_triple: &str) { +fn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) { if gccjit::is_loaded() { // Do not load a libgccjit second time. return; } - let libgccjit_target_lib_file = libgccjit_path(sysroot_path, target_triple); let path = libgccjit_target_lib_file.to_str().expect("libgccjit path"); let string = CString::new(path).expect("string to libgccjit path"); @@ -216,9 +211,10 @@ impl CodegenBackend for GccCodegenBackend { // invalid. // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. for path in sess.opts.sysroot.all_paths() { - let libgccjit_target_lib_file = libgccjit_path(path, &sess.target.llvm_target); - if let Ok(true) = fs::exists(libgccjit_target_lib_file) { - load_libgccjit_if_needed(path, &sess.target.llvm_target); + let libgccjit_target_lib_file = + make_target_lib_path(path, &sess.target.llvm_target).join("libgccjit.so"); + if let Ok(true) = fs::exists(&libgccjit_target_lib_file) { + load_libgccjit_if_needed(&libgccjit_target_lib_file); break; } } From 2081b7a66317272a511294ee18300b5e7f1bab46 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 5 Dec 2025 14:39:30 +0100 Subject: [PATCH 0330/3801] chore(len_without_is_empty): extract to a separate module It didn't share any logic at all with the lints in `len_zero.rs`, whereas the helper functions were partially mixed together, so that the file was hard to navigate --- clippy_lints/src/declared_lints.rs | 2 +- clippy_lints/src/len_without_is_empty.rs | 342 ++++++++++++++++++++++ clippy_lints/src/len_zero.rs | 344 +---------------------- clippy_lints/src/lib.rs | 2 + 4 files changed, 352 insertions(+), 338 deletions(-) create mode 100644 clippy_lints/src/len_without_is_empty.rs diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 17bcc3824a7b..1a02c2166454 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -245,8 +245,8 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::large_stack_arrays::LARGE_STACK_ARRAYS_INFO, crate::large_stack_frames::LARGE_STACK_FRAMES_INFO, crate::legacy_numeric_constants::LEGACY_NUMERIC_CONSTANTS_INFO, + crate::len_without_is_empty::LEN_WITHOUT_IS_EMPTY_INFO, crate::len_zero::COMPARISON_TO_EMPTY_INFO, - crate::len_zero::LEN_WITHOUT_IS_EMPTY_INFO, crate::len_zero::LEN_ZERO_INFO, crate::let_if_seq::USELESS_LET_IF_SEQ_INFO, crate::let_underscore::LET_UNDERSCORE_FUTURE_INFO, diff --git a/clippy_lints/src/len_without_is_empty.rs b/clippy_lints/src/len_without_is_empty.rs new file mode 100644 index 000000000000..1d219d7c3b74 --- /dev/null +++ b/clippy_lints/src/len_without_is_empty.rs @@ -0,0 +1,342 @@ +use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; +use clippy_utils::res::MaybeDef; +use clippy_utils::{fulfill_or_allowed, get_parent_as_impl, sym}; +use rustc_hir::def::Res; +use rustc_hir::def_id::{DefId, DefIdSet}; +use rustc_hir::{ + FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind, ImplicitSelfKind, Item, ItemKind, Mutability, + Node, OpaqueTyOrigin, PathSegment, PrimTy, QPath, TraitItemId, TyKind, +}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::{self, FnSig, Ty}; +use rustc_session::declare_lint_pass; +use rustc_span::symbol::kw; +use rustc_span::{Ident, Span, Symbol}; +use rustc_trait_selection::traits::supertrait_def_ids; + +declare_clippy_lint! { + /// ### What it does + /// Checks for items that implement `.len()` but not + /// `.is_empty()`. + /// + /// ### Why is this bad? + /// It is good custom to have both methods, because for + /// some data structures, asking about the length will be a costly operation, + /// whereas `.is_empty()` can usually answer in constant time. Also it used to + /// lead to false positives on the [`len_zero`](#len_zero) lint – currently that + /// lint will ignore such entities. + /// + /// ### Example + /// ```ignore + /// impl X { + /// pub fn len(&self) -> usize { + /// .. + /// } + /// } + /// ``` + #[clippy::version = "pre 1.29.0"] + pub LEN_WITHOUT_IS_EMPTY, + style, + "traits or impls with a public `len` method but no corresponding `is_empty` method" +} + +declare_lint_pass!(LenWithoutIsEmpty => [LEN_WITHOUT_IS_EMPTY]); + +impl<'tcx> LateLintPass<'tcx> for LenWithoutIsEmpty { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { + if let ItemKind::Trait(_, _, _, ident, _, _, trait_items) = item.kind + && !item.span.from_expansion() + { + check_trait_items(cx, item, ident, trait_items); + } + } + + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { + if item.ident.name == sym::len + && let ImplItemKind::Fn(sig, _) = &item.kind + && sig.decl.implicit_self.has_implicit_self() + && sig.decl.inputs.len() == 1 + && cx.effective_visibilities.is_exported(item.owner_id.def_id) + && matches!(sig.decl.output, FnRetTy::Return(_)) + && let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id()) + && imp.of_trait.is_none() + && let TyKind::Path(ty_path) = &imp.self_ty.kind + && let Some(ty_id) = cx.qpath_res(ty_path, imp.self_ty.hir_id).opt_def_id() + && let Some(local_id) = ty_id.as_local() + && let ty_hir_id = cx.tcx.local_def_id_to_hir_id(local_id) + && let Some(output) = LenOutput::new(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()) + { + let (name, kind) = match cx.tcx.hir_node(ty_hir_id) { + Node::ForeignItem(x) => (x.ident.name, "extern type"), + Node::Item(x) => match x.kind { + ItemKind::Struct(ident, ..) => (ident.name, "struct"), + ItemKind::Enum(ident, ..) => (ident.name, "enum"), + ItemKind::Union(ident, ..) => (ident.name, "union"), + _ => (x.kind.ident().unwrap().name, "type"), + }, + _ => return, + }; + check_for_is_empty( + cx, + sig.span, + sig.decl.implicit_self, + output, + ty_id, + name, + kind, + item.hir_id(), + ty_hir_id, + ); + } + } +} + +fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemId]) { + fn is_named_self(cx: &LateContext<'_>, item: TraitItemId, name: Symbol) -> bool { + cx.tcx.item_name(item.owner_id) == name + && matches!( + cx.tcx.fn_arg_idents(item.owner_id), + [Some(Ident { + name: kw::SelfLower, + .. + })], + ) + } + + // fill the set with current and super traits + fn fill_trait_set(traitt: DefId, set: &mut DefIdSet, cx: &LateContext<'_>) { + if set.insert(traitt) { + for supertrait in supertrait_def_ids(cx.tcx, traitt) { + fill_trait_set(supertrait, set, cx); + } + } + } + + if cx.effective_visibilities.is_exported(visited_trait.owner_id.def_id) + && trait_items.iter().any(|&i| is_named_self(cx, i, sym::len)) + { + let mut current_and_super_traits = DefIdSet::default(); + fill_trait_set(visited_trait.owner_id.to_def_id(), &mut current_and_super_traits, cx); + let is_empty_method_found = current_and_super_traits + .items() + .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(sym::is_empty)) + .any(|i| i.is_method() && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1); + + if !is_empty_method_found { + span_lint( + cx, + LEN_WITHOUT_IS_EMPTY, + visited_trait.span, + format!( + "trait `{}` has a `len` method but no (possibly inherited) `is_empty` method", + ident.name + ), + ); + } + } +} + +fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { + if let ty::Alias(_, alias_ty) = ty.kind() + && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(alias_ty.def_id) + && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin + && let [GenericBound::Trait(trait_ref)] = &opaque.bounds + && let Some(segment) = trait_ref.trait_ref.path.segments.last() + && let Some(generic_args) = segment.args + && let [constraint] = generic_args.constraints + && let Some(ty) = constraint.ty() + && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind + && let [segment] = path.segments + { + return Some(segment); + } + + None +} + +fn is_first_generic_integral<'tcx>(segment: &'tcx PathSegment<'tcx>) -> bool { + if let Some(generic_args) = segment.args + && let [GenericArg::Type(ty), ..] = &generic_args.args + && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind + && let [segment, ..] = &path.segments + && matches!(segment.res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) + { + true + } else { + false + } +} + +#[derive(Debug, Clone, Copy)] +enum LenOutput { + Integral, + Option(DefId), + Result(DefId), +} + +impl LenOutput { + fn new<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option { + if let Some(segment) = extract_future_output(cx, sig.output()) { + let res = segment.res; + + if matches!(res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) { + return Some(Self::Integral); + } + + if let Res::Def(_, def_id) = res + && let Some(res) = match cx.tcx.get_diagnostic_name(def_id) { + Some(sym::Option) => Some(Self::Option(def_id)), + Some(sym::Result) => Some(Self::Result(def_id)), + _ => None, + } + && is_first_generic_integral(segment) + { + return Some(res); + } + + return None; + } + + match *sig.output().kind() { + ty::Int(_) | ty::Uint(_) => Some(Self::Integral), + ty::Adt(adt, subs) => match cx.tcx.get_diagnostic_name(adt.did()) { + Some(sym::Option) => subs.type_at(0).is_integral().then(|| Self::Option(adt.did())), + Some(sym::Result) => subs.type_at(0).is_integral().then(|| Self::Result(adt.did())), + _ => None, + }, + _ => None, + } + } + + fn matches_is_empty_output<'tcx>(self, cx: &LateContext<'tcx>, is_empty_output: Ty<'tcx>) -> bool { + if let Some(segment) = extract_future_output(cx, is_empty_output) { + return match (self, segment.res) { + (_, Res::PrimTy(PrimTy::Bool)) => true, + (Self::Option(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Option, def_id) => true, + (Self::Result(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Result, def_id) => true, + _ => false, + }; + } + + match (self, is_empty_output.kind()) { + (_, &ty::Bool) => true, + (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), + (Self::Result(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), + _ => false, + } + } +} + +/// The expected signature of `is_empty`, based on that of `len` +fn expected_is_empty_sig(len_output: LenOutput, len_self_kind: ImplicitSelfKind) -> String { + let self_ref = match len_self_kind { + ImplicitSelfKind::RefImm => "&", + ImplicitSelfKind::RefMut => "&(mut) ", + _ => "", + }; + match len_output { + LenOutput::Integral => format!("expected signature: `({self_ref}self) -> bool`"), + LenOutput::Option(_) => { + format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Option") + }, + LenOutput::Result(..) => { + format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Result") + }, + } +} + +/// Checks if the given signature matches the expectations for `is_empty` +fn check_is_empty_sig<'tcx>( + cx: &LateContext<'tcx>, + is_empty_sig: FnSig<'tcx>, + len_self_kind: ImplicitSelfKind, + len_output: LenOutput, +) -> bool { + if let [is_empty_self_arg, is_empty_output] = &**is_empty_sig.inputs_and_output + && len_output.matches_is_empty_output(cx, *is_empty_output) + { + match (is_empty_self_arg.kind(), len_self_kind) { + // if `len` takes `&self`, `is_empty` should do so as well + (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::RefImm) + // if `len` takes `&mut self`, `is_empty` may take that _or_ `&self` (#16190) + | (ty::Ref(_, _, Mutability::Mut | Mutability::Not), ImplicitSelfKind::RefMut) => true, + // if len takes `self`, `is_empty` should do so as well + // XXX: we might want to relax this to allow `&self` and `&mut self` + (_, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut) if !is_empty_self_arg.is_ref() => true, + _ => false, + } + } else { + false + } +} + +/// Checks if the given type has an `is_empty` method with the appropriate signature. +#[expect(clippy::too_many_arguments)] +fn check_for_is_empty( + cx: &LateContext<'_>, + len_span: Span, + len_self_kind: ImplicitSelfKind, + len_output: LenOutput, + impl_ty: DefId, + item_name: Symbol, + item_kind: &str, + len_method_hir_id: HirId, + ty_decl_hir_id: HirId, +) { + // Implementor may be a type alias, in which case we need to get the `DefId` of the aliased type to + // find the correct inherent impls. + let impl_ty = if let Some(adt) = cx.tcx.type_of(impl_ty).skip_binder().ty_adt_def() { + adt.did() + } else { + return; + }; + + let is_empty = cx + .tcx + .inherent_impls(impl_ty) + .iter() + .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(sym::is_empty)) + .find(|item| item.is_fn()); + + let (msg, is_empty_span, is_empty_expected_sig) = match is_empty { + None => ( + format!("{item_kind} `{item_name}` has a public `len` method, but no `is_empty` method"), + None, + None, + ), + Some(is_empty) if !cx.effective_visibilities.is_exported(is_empty.def_id.expect_local()) => ( + format!("{item_kind} `{item_name}` has a public `len` method, but a private `is_empty` method"), + Some(cx.tcx.def_span(is_empty.def_id)), + None, + ), + Some(is_empty) + if !(is_empty.is_method() + && check_is_empty_sig( + cx, + cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(), + len_self_kind, + len_output, + )) => + { + ( + format!( + "{item_kind} `{item_name}` has a public `len` method, but the `is_empty` method has an unexpected signature", + ), + Some(cx.tcx.def_span(is_empty.def_id)), + Some(expected_is_empty_sig(len_output, len_self_kind)), + ) + }, + Some(_) => return, + }; + + if !fulfill_or_allowed(cx, LEN_WITHOUT_IS_EMPTY, [len_method_hir_id, ty_decl_hir_id]) { + span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, len_span, msg, |db| { + if let Some(span) = is_empty_span { + db.span_note(span, "`is_empty` defined here"); + } + if let Some(expected_sig) = is_empty_expected_sig { + db.note(expected_sig); + } + }); + } +} diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index f5a832f3adfd..2e576da38b89 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -1,27 +1,20 @@ use clippy_config::Conf; -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::Msrv; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; use clippy_utils::source::{SpanRangeExt, snippet_with_context}; use clippy_utils::sugg::{Sugg, has_enclosing_paren}; use clippy_utils::ty::implements_trait; -use clippy_utils::{fulfill_or_allowed, get_parent_as_impl, parent_item_name, peel_ref_operators, sym}; +use clippy_utils::{parent_item_name, peel_ref_operators, sym}; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::def::Res; -use rustc_hir::def_id::{DefId, DefIdSet}; -use rustc_hir::{ - BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind, ImplicitSelfKind, - Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatExprKind, PatKind, PathSegment, PrimTy, QPath, RustcVersion, - StabilityLevel, StableSince, TraitItemId, TyKind, -}; +use rustc_hir::def_id::DefId; +use rustc_hir::{BinOpKind, Expr, ExprKind, PatExprKind, PatKind, RustcVersion, StabilityLevel, StableSince}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, FnSig, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use rustc_span::source_map::Spanned; -use rustc_span::symbol::kw; -use rustc_span::{Ident, Span, Symbol}; -use rustc_trait_selection::traits::supertrait_def_ids; +use rustc_span::{Span, Symbol}; declare_clippy_lint! { /// ### What it does @@ -58,32 +51,6 @@ declare_clippy_lint! { "checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` could be used instead" } -declare_clippy_lint! { - /// ### What it does - /// Checks for items that implement `.len()` but not - /// `.is_empty()`. - /// - /// ### Why is this bad? - /// It is good custom to have both methods, because for - /// some data structures, asking about the length will be a costly operation, - /// whereas `.is_empty()` can usually answer in constant time. Also it used to - /// lead to false positives on the [`len_zero`](#len_zero) lint – currently that - /// lint will ignore such entities. - /// - /// ### Example - /// ```ignore - /// impl X { - /// pub fn len(&self) -> usize { - /// .. - /// } - /// } - /// ``` - #[clippy::version = "pre 1.29.0"] - pub LEN_WITHOUT_IS_EMPTY, - style, - "traits or impls with a public `len` method but no corresponding `is_empty` method" -} - declare_clippy_lint! { /// ### What it does /// Checks for comparing to an empty slice such as `""` or `[]`, @@ -126,7 +93,7 @@ pub struct LenZero { msrv: Msrv, } -impl_lint_pass!(LenZero => [LEN_ZERO, LEN_WITHOUT_IS_EMPTY, COMPARISON_TO_EMPTY]); +impl_lint_pass!(LenZero => [LEN_ZERO, COMPARISON_TO_EMPTY]); impl LenZero { pub fn new(conf: &'static Conf) -> Self { @@ -135,53 +102,6 @@ impl LenZero { } impl<'tcx> LateLintPass<'tcx> for LenZero { - fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Trait(_, _, _, ident, _, _, trait_items) = item.kind - && !item.span.from_expansion() - { - check_trait_items(cx, item, ident, trait_items); - } - } - - fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { - if item.ident.name == sym::len - && let ImplItemKind::Fn(sig, _) = &item.kind - && sig.decl.implicit_self.has_implicit_self() - && sig.decl.inputs.len() == 1 - && cx.effective_visibilities.is_exported(item.owner_id.def_id) - && matches!(sig.decl.output, FnRetTy::Return(_)) - && let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id()) - && imp.of_trait.is_none() - && let TyKind::Path(ty_path) = &imp.self_ty.kind - && let Some(ty_id) = cx.qpath_res(ty_path, imp.self_ty.hir_id).opt_def_id() - && let Some(local_id) = ty_id.as_local() - && let ty_hir_id = cx.tcx.local_def_id_to_hir_id(local_id) - && let Some(output) = LenOutput::new(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()) - { - let (name, kind) = match cx.tcx.hir_node(ty_hir_id) { - Node::ForeignItem(x) => (x.ident.name, "extern type"), - Node::Item(x) => match x.kind { - ItemKind::Struct(ident, ..) => (ident.name, "struct"), - ItemKind::Enum(ident, ..) => (ident.name, "enum"), - ItemKind::Union(ident, ..) => (ident.name, "union"), - _ => (x.kind.ident().unwrap().name, "type"), - }, - _ => return, - }; - check_for_is_empty( - cx, - sig.span, - sig.decl.implicit_self, - output, - ty_id, - name, - kind, - item.hir_id(), - ty_hir_id, - ); - } - } - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Let(lt) = expr.kind && match lt.pat.kind { @@ -355,256 +275,6 @@ fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span { } } -fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemId]) { - fn is_named_self(cx: &LateContext<'_>, item: TraitItemId, name: Symbol) -> bool { - cx.tcx.item_name(item.owner_id) == name - && matches!( - cx.tcx.fn_arg_idents(item.owner_id), - [Some(Ident { - name: kw::SelfLower, - .. - })], - ) - } - - // fill the set with current and super traits - fn fill_trait_set(traitt: DefId, set: &mut DefIdSet, cx: &LateContext<'_>) { - if set.insert(traitt) { - for supertrait in supertrait_def_ids(cx.tcx, traitt) { - fill_trait_set(supertrait, set, cx); - } - } - } - - if cx.effective_visibilities.is_exported(visited_trait.owner_id.def_id) - && trait_items.iter().any(|&i| is_named_self(cx, i, sym::len)) - { - let mut current_and_super_traits = DefIdSet::default(); - fill_trait_set(visited_trait.owner_id.to_def_id(), &mut current_and_super_traits, cx); - let is_empty_method_found = current_and_super_traits - .items() - .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(sym::is_empty)) - .any(|i| i.is_method() && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1); - - if !is_empty_method_found { - span_lint( - cx, - LEN_WITHOUT_IS_EMPTY, - visited_trait.span, - format!( - "trait `{}` has a `len` method but no (possibly inherited) `is_empty` method", - ident.name - ), - ); - } - } -} - -fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { - if let ty::Alias(_, alias_ty) = ty.kind() - && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(alias_ty.def_id) - && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin - && let [GenericBound::Trait(trait_ref)] = &opaque.bounds - && let Some(segment) = trait_ref.trait_ref.path.segments.last() - && let Some(generic_args) = segment.args - && let [constraint] = generic_args.constraints - && let Some(ty) = constraint.ty() - && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind - && let [segment] = path.segments - { - return Some(segment); - } - - None -} - -fn is_first_generic_integral<'tcx>(segment: &'tcx PathSegment<'tcx>) -> bool { - if let Some(generic_args) = segment.args - && let [GenericArg::Type(ty), ..] = &generic_args.args - && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind - && let [segment, ..] = &path.segments - && matches!(segment.res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) - { - true - } else { - false - } -} - -#[derive(Debug, Clone, Copy)] -enum LenOutput { - Integral, - Option(DefId), - Result(DefId), -} - -impl LenOutput { - fn new<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option { - if let Some(segment) = extract_future_output(cx, sig.output()) { - let res = segment.res; - - if matches!(res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) { - return Some(Self::Integral); - } - - if let Res::Def(_, def_id) = res - && let Some(res) = match cx.tcx.get_diagnostic_name(def_id) { - Some(sym::Option) => Some(Self::Option(def_id)), - Some(sym::Result) => Some(Self::Result(def_id)), - _ => None, - } - && is_first_generic_integral(segment) - { - return Some(res); - } - - return None; - } - - match *sig.output().kind() { - ty::Int(_) | ty::Uint(_) => Some(Self::Integral), - ty::Adt(adt, subs) => match cx.tcx.get_diagnostic_name(adt.did()) { - Some(sym::Option) => subs.type_at(0).is_integral().then(|| Self::Option(adt.did())), - Some(sym::Result) => subs.type_at(0).is_integral().then(|| Self::Result(adt.did())), - _ => None, - }, - _ => None, - } - } - - fn matches_is_empty_output<'tcx>(self, cx: &LateContext<'tcx>, is_empty_output: Ty<'tcx>) -> bool { - if let Some(segment) = extract_future_output(cx, is_empty_output) { - return match (self, segment.res) { - (_, Res::PrimTy(PrimTy::Bool)) => true, - (Self::Option(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Option, def_id) => true, - (Self::Result(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Result, def_id) => true, - _ => false, - }; - } - - match (self, is_empty_output.kind()) { - (_, &ty::Bool) => true, - (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), - (Self::Result(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), - _ => false, - } - } -} - -/// The expected signature of `is_empty`, based on that of `len` -fn expected_is_empty_sig(len_output: LenOutput, len_self_kind: ImplicitSelfKind) -> String { - let self_ref = match len_self_kind { - ImplicitSelfKind::RefImm => "&", - ImplicitSelfKind::RefMut => "&(mut) ", - _ => "", - }; - match len_output { - LenOutput::Integral => format!("expected signature: `({self_ref}self) -> bool`"), - LenOutput::Option(_) => { - format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Option") - }, - LenOutput::Result(..) => { - format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Result") - }, - } -} - -/// Checks if the given signature matches the expectations for `is_empty` -fn check_is_empty_sig<'tcx>( - cx: &LateContext<'tcx>, - is_empty_sig: FnSig<'tcx>, - len_self_kind: ImplicitSelfKind, - len_output: LenOutput, -) -> bool { - if let [is_empty_self_arg, is_empty_output] = &**is_empty_sig.inputs_and_output - && len_output.matches_is_empty_output(cx, *is_empty_output) - { - match (is_empty_self_arg.kind(), len_self_kind) { - // if `len` takes `&self`, `is_empty` should do so as well - (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::RefImm) - // if `len` takes `&mut self`, `is_empty` may take that _or_ `&self` (#16190) - | (ty::Ref(_, _, Mutability::Mut | Mutability::Not), ImplicitSelfKind::RefMut) => true, - // if len takes `self`, `is_empty` should do so as well - // XXX: we might want to relax this to allow `&self` and `&mut self` - (_, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut) if !is_empty_self_arg.is_ref() => true, - _ => false, - } - } else { - false - } -} - -/// Checks if the given type has an `is_empty` method with the appropriate signature. -#[expect(clippy::too_many_arguments)] -fn check_for_is_empty( - cx: &LateContext<'_>, - len_span: Span, - len_self_kind: ImplicitSelfKind, - len_output: LenOutput, - impl_ty: DefId, - item_name: Symbol, - item_kind: &str, - len_method_hir_id: HirId, - ty_decl_hir_id: HirId, -) { - // Implementor may be a type alias, in which case we need to get the `DefId` of the aliased type to - // find the correct inherent impls. - let impl_ty = if let Some(adt) = cx.tcx.type_of(impl_ty).skip_binder().ty_adt_def() { - adt.did() - } else { - return; - }; - - let is_empty = cx - .tcx - .inherent_impls(impl_ty) - .iter() - .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(sym::is_empty)) - .find(|item| item.is_fn()); - - let (msg, is_empty_span, is_empty_expected_sig) = match is_empty { - None => ( - format!("{item_kind} `{item_name}` has a public `len` method, but no `is_empty` method"), - None, - None, - ), - Some(is_empty) if !cx.effective_visibilities.is_exported(is_empty.def_id.expect_local()) => ( - format!("{item_kind} `{item_name}` has a public `len` method, but a private `is_empty` method"), - Some(cx.tcx.def_span(is_empty.def_id)), - None, - ), - Some(is_empty) - if !(is_empty.is_method() - && check_is_empty_sig( - cx, - cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(), - len_self_kind, - len_output, - )) => - { - ( - format!( - "{item_kind} `{item_name}` has a public `len` method, but the `is_empty` method has an unexpected signature", - ), - Some(cx.tcx.def_span(is_empty.def_id)), - Some(expected_is_empty_sig(len_output, len_self_kind)), - ) - }, - Some(_) => return, - }; - - if !fulfill_or_allowed(cx, LEN_WITHOUT_IS_EMPTY, [len_method_hir_id, ty_decl_hir_id]) { - span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, len_span, msg, |db| { - if let Some(span) = is_empty_span { - db.span_note(span, "`is_empty` defined here"); - } - if let Some(expected_sig) = is_empty_expected_sig { - db.note(expected_sig); - } - }); - } -} - fn is_empty_string(expr: &Expr<'_>) -> bool { if let ExprKind::Lit(lit) = expr.kind && let LitKind::Str(lit, _) = lit.node diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index cad36b7f197a..5b39d8844797 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -182,6 +182,7 @@ mod large_include_file; mod large_stack_arrays; mod large_stack_frames; mod legacy_numeric_constants; +mod len_without_is_empty; mod len_zero; mod let_if_seq; mod let_underscore; @@ -539,6 +540,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(|_| Box::new(unnecessary_mut_passed::UnnecessaryMutPassed)), Box::new(|_| Box::>::default()), Box::new(move |_| Box::new(len_zero::LenZero::new(conf))), + Box::new(|_| Box::new(len_without_is_empty::LenWithoutIsEmpty)), Box::new(move |_| Box::new(attrs::Attributes::new(conf))), Box::new(|_| Box::new(blocks_in_conditions::BlocksInConditions)), Box::new(|_| Box::new(unicode::Unicode)), From 2122285ff9a52830c5458860ec36d7878bb91439 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Fri, 5 Dec 2025 23:15:58 +0800 Subject: [PATCH 0331/3801] Fix not complete `format!("{{{$0")` and underscore Example --- ```rust fn main() { let foobar = 1; format_args!("{{{f$0"); } ``` **Before this PR** No complete **After this PR** ```rust fn main() { let foobar = 1; format_args!("{{{foobar"); } ``` --- ```rust fn main() { let foo_bar = 1; format_args!("{foo_$0}"); } ``` **Before this PR** No complete **After this PR** ```rust fn main() { let foo_bar = 1; format_args!("{foo_bar}"); } ``` --- .../src/completions/format_string.rs | 94 +++++++++++++++++-- 1 file changed, 87 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs index 5ae65b05bc42..eaacd8d1a8fe 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs @@ -22,13 +22,8 @@ pub(crate) fn format_string( let cursor_in_lit = cursor - lit_start; let prefix = &original.text()[..cursor_in_lit.into()]; - let braces = prefix.char_indices().rev().skip_while(|&(_, c)| c.is_alphanumeric()).next_tuple(); - let brace_offset = match braces { - // escaped brace - Some(((_, '{'), (_, '{'))) => return, - Some(((idx, '{'), _)) => lit_start + TextSize::from(idx as u32 + 1), - _ => return, - }; + let Some(brace_offset) = unescaped_brace(prefix) else { return }; + let brace_offset = lit_start + brace_offset + TextSize::of('{'); let source_range = TextRange::new(brace_offset, cursor); ctx.locals.iter().sorted_by_key(|&(k, _)| k.clone()).for_each(|(name, _)| { @@ -59,6 +54,15 @@ pub(crate) fn format_string( }); } +fn unescaped_brace(prefix: &str) -> Option { + let is_ident_char = |ch: char| ch.is_alphanumeric() || ch == '_'; + prefix + .trim_end_matches(is_ident_char) + .strip_suffix('{') + .filter(|it| it.chars().rev().take_while(|&ch| ch == '{').count() % 2 == 0) + .map(|s| TextSize::new(s.len() as u32)) +} + #[cfg(test)] mod tests { use expect_test::expect; @@ -96,6 +100,82 @@ fn main() { ); } + #[test] + fn no_completion_after_escaped() { + check_no_kw( + r#" +//- minicore: fmt +fn main() { + let foobar = 1; + format_args!("{{f$0"); +} +"#, + expect![[]], + ); + check_no_kw( + r#" +//- minicore: fmt +fn main() { + let foobar = 1; + format_args!("some text {{{{f$0"); +} +"#, + expect![[]], + ); + } + + #[test] + fn completes_unescaped_after_escaped() { + check_edit( + "foobar", + r#" +//- minicore: fmt +fn main() { + let foobar = 1; + format_args!("{{{f$0"); +} +"#, + r#" +fn main() { + let foobar = 1; + format_args!("{{{foobar"); +} +"#, + ); + check_edit( + "foobar", + r#" +//- minicore: fmt +fn main() { + let foobar = 1; + format_args!("{{{{{f$0"); +} +"#, + r#" +fn main() { + let foobar = 1; + format_args!("{{{{{foobar"); +} +"#, + ); + check_edit( + "foobar", + r#" +//- minicore: fmt +fn main() { + let foobar = 1; + format_args!("}}{f$0"); +} +"#, + r#" +fn main() { + let foobar = 1; + format_args!("}}{foobar"); +} +"#, + ); + } + #[test] fn completes_locals() { check_edit( From 803cfb9ddf67ff39535a142bc4459eec28f3fef3 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Fri, 5 Dec 2025 17:09:11 +0100 Subject: [PATCH 0332/3801] Fix armv8r-none-eabihf tier It's listed as Tier 2 in `armv8r-none-eabihf.md`, but Tier 3 in `arm-none-eabi.md`. Updated to reflect current state of Tier 2. --- src/doc/rustc/src/platform-support/arm-none-eabi.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index aaa80e429718..81545db6c51f 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -16,6 +16,7 @@ their own document. - Arm R-Profile Architectures - [`armv7r-none-eabi` and `armv7r-none-eabihf`](armv7r-none-eabi.md) - [`armebv7r-none-eabi` and `armebv7r-none-eabihf`](armebv7r-none-eabi.md) + - [`armv8r-none-eabihf`](armv8r-none-eabihf.md) - Arm M-Profile Architectures - [`thumbv6m-none-eabi`](thumbv6m-none-eabi.md) - [`thumbv7m-none-eabi`](thumbv7m-none-eabi.md) @@ -30,7 +31,7 @@ their own document. - Arm A-Profile Architectures - [`armv7a-none-eabihf`](armv7a-none-eabi.md) - Arm R-Profile Architectures - - [`armv8r-none-eabihf`](armv8r-none-eabihf.md) + - None - Arm M-Profile Architectures - None - *Legacy* Arm Architectures From c9055034744c98739e087a2a7f3197f4e547aed2 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 5 Dec 2025 18:18:58 +0000 Subject: [PATCH 0333/3801] fix: `panicking_unwrap` FP on field access with implicit deref --- clippy_lints/src/unwrap.rs | 9 +++++++-- .../ui/checked_unwrap/simple_conditionals.rs | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index 8ed3df8731b3..a95f2b681add 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -180,14 +180,19 @@ impl Local { field_indices, .. } => { + let field_projections = place + .projections + .iter() + .filter(|proj| matches!(proj.kind, ProjectionKind::Field(_, _))) + .collect::>(); is_potentially_local_place(*local_id, place) // If there were projections other than field projections, err on the side of caution and say that they // _might_ be mutating something. // // The reason we use `<=` and not `==` is that a mutation of `struct` or `struct.field1` should count as // mutation of the child fields such as `struct.field1.field2` - && place.projections.len() <= field_indices.len() - && iter::zip(&place.projections, field_indices.iter().copied().rev()).all(|(proj, field_idx)| { + && field_projections.len() <= field_indices.len() + && iter::zip(&field_projections, field_indices.iter().copied().rev()).all(|(proj, field_idx)| { match proj.kind { ProjectionKind::Field(f_idx, _) => f_idx == field_idx, // If this is a projection we don't expect, it _might_ be mutating something diff --git a/tests/ui/checked_unwrap/simple_conditionals.rs b/tests/ui/checked_unwrap/simple_conditionals.rs index c6476a7507a1..bab20b091d38 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.rs +++ b/tests/ui/checked_unwrap/simple_conditionals.rs @@ -472,3 +472,22 @@ fn issue15321() { //~^ unnecessary_unwrap } } + +mod issue16188 { + struct Foo { + value: Option, + } + + impl Foo { + pub fn bar(&mut self) { + let print_value = |v: i32| { + println!("{}", v); + }; + + if self.value.is_none() { + self.value = Some(10); + print_value(self.value.unwrap()); + } + } + } +} From dfee0dad260cf22efd0d56e0b07021d0fc86a564 Mon Sep 17 00:00:00 2001 From: Sasha Pourcelot Date: Fri, 5 Dec 2025 18:06:42 +0000 Subject: [PATCH 0334/3801] Add test for misspelled feature name --- tests/ui/feature-gates/unknown-feature.rs | 13 +++++++++++- tests/ui/feature-gates/unknown-feature.stderr | 20 +++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/tests/ui/feature-gates/unknown-feature.rs b/tests/ui/feature-gates/unknown-feature.rs index 20fd932d4c2f..2ecc9b82a48d 100644 --- a/tests/ui/feature-gates/unknown-feature.rs +++ b/tests/ui/feature-gates/unknown-feature.rs @@ -1,3 +1,14 @@ -#![feature(unknown_rust_feature)] //~ ERROR unknown feature +#![feature( + unknown_rust_feature, + //~^ ERROR unknown feature + + // Typo for lang feature + associated_types_default, + //~^ ERROR unknown feature + + // Typo for lib feature + core_intrnisics, + //~^ ERROR unknown feature +)] fn main() {} diff --git a/tests/ui/feature-gates/unknown-feature.stderr b/tests/ui/feature-gates/unknown-feature.stderr index 0a731ddcc0b6..a0cadb3f817f 100644 --- a/tests/ui/feature-gates/unknown-feature.stderr +++ b/tests/ui/feature-gates/unknown-feature.stderr @@ -1,9 +1,21 @@ error[E0635]: unknown feature `unknown_rust_feature` - --> $DIR/unknown-feature.rs:1:12 + --> $DIR/unknown-feature.rs:2:5 | -LL | #![feature(unknown_rust_feature)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | unknown_rust_feature, + | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0635]: unknown feature `associated_types_default` + --> $DIR/unknown-feature.rs:6:5 + | +LL | associated_types_default, + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0635]: unknown feature `core_intrnisics` + --> $DIR/unknown-feature.rs:10:5 + | +LL | core_intrnisics, + | ^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0635`. From 21b89a9bf51954effc0eeb94070000776a496c4a Mon Sep 17 00:00:00 2001 From: Tobias Decking Date: Thu, 8 May 2025 09:12:53 +0200 Subject: [PATCH 0335/3801] Remove remaining traces of AT&T assembly syntax --- .../src/int/specialized_div_rem/mod.rs | 6 +- .../compiler-builtins/src/mem/x86_64.rs | 52 ++++--- .../compiler-builtins/src/probestack.rs | 133 +++++++++--------- .../compiler-builtins/src/x86.rs | 33 +++-- .../compiler-builtins/src/x86_64.rs | 29 ++-- 5 files changed, 122 insertions(+), 131 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/src/int/specialized_div_rem/mod.rs b/library/compiler-builtins/compiler-builtins/src/int/specialized_div_rem/mod.rs index 7841e4f33cd6..5ffe1f59b4db 100644 --- a/library/compiler-builtins/compiler-builtins/src/int/specialized_div_rem/mod.rs +++ b/library/compiler-builtins/compiler-builtins/src/int/specialized_div_rem/mod.rs @@ -196,13 +196,12 @@ unsafe fn u128_by_u64_div_rem(duo: u128, div: u64) -> (u64, u64) { unsafe { // divides the combined registers rdx:rax (`duo` is split into two 64 bit parts to do this) // by `div`. The quotient is stored in rax and the remainder in rdx. - // FIXME: Use the Intel syntax once we drop LLVM 9 support on rust-lang/rust. core::arch::asm!( "div {0}", in(reg) div, inlateout("rax") duo_lo => quo, inlateout("rdx") duo_hi => rem, - options(att_syntax, pure, nomem, nostack) + options(pure, nomem, nostack), ); } (quo, rem) @@ -283,13 +282,12 @@ unsafe fn u64_by_u32_div_rem(duo: u64, div: u32) -> (u32, u32) { unsafe { // divides the combined registers rdx:rax (`duo` is split into two 32 bit parts to do this) // by `div`. The quotient is stored in rax and the remainder in rdx. - // FIXME: Use the Intel syntax once we drop LLVM 9 support on rust-lang/rust. core::arch::asm!( "div {0}", in(reg) div, inlateout("rax") duo_lo => quo, inlateout("rdx") duo_hi => rem, - options(att_syntax, pure, nomem, nostack) + options(pure, nomem, nostack), ); } (quo, rem) diff --git a/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs b/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs index fb29eb11b231..cb780ec036bb 100644 --- a/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs +++ b/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs @@ -22,13 +22,12 @@ use core::{intrinsics, mem}; #[inline(always)] #[cfg(target_feature = "ermsb")] pub unsafe fn copy_forward(dest: *mut u8, src: *const u8, count: usize) { - // FIXME: Use the Intel syntax once we drop LLVM 9 support on rust-lang/rust. - core::arch::asm!( - "repe movsb (%rsi), (%rdi)", + asm!( + "repe movsb [rdi], [rsi]", inout("rcx") count => _, inout("rdi") dest => _, inout("rsi") src => _, - options(att_syntax, nostack, preserves_flags) + options(nostack, preserves_flags) ); } @@ -42,21 +41,21 @@ pub unsafe fn copy_forward(mut dest: *mut u8, mut src: *const u8, count: usize) inout("ecx") pre_byte_count => _, inout("rdi") dest => dest, inout("rsi") src => src, - options(att_syntax, nostack, preserves_flags) + options(nostack, preserves_flags) ); asm!( "rep movsq", inout("rcx") qword_count => _, inout("rdi") dest => dest, inout("rsi") src => src, - options(att_syntax, nostack, preserves_flags) + options(nostack, preserves_flags) ); asm!( "rep movsb", inout("ecx") byte_count => _, inout("rdi") dest => _, inout("rsi") src => _, - options(att_syntax, nostack, preserves_flags) + options(nostack, preserves_flags) ); } @@ -67,14 +66,14 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) { asm!( "std", "rep movsb", - "sub $7, %rsi", - "sub $7, %rdi", - "mov {qword_count:r}, %rcx", + "sub rsi, 7", + "sub rdi, 7", + "mov rcx, {qword_count:r}", "rep movsq", "test {pre_byte_count:e}, {pre_byte_count:e}", - "add $7, %rsi", - "add $7, %rdi", - "mov {pre_byte_count:e}, %ecx", + "add rsi, 7", + "add rdi, 7", + "mov ecx, {pre_byte_count:e}", "rep movsb", "cld", pre_byte_count = in(reg) pre_byte_count, @@ -83,20 +82,19 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) { inout("rdi") dest.add(count - 1) => _, inout("rsi") src.add(count - 1) => _, // We modify flags, but we restore it afterwards - options(att_syntax, nostack, preserves_flags) + options(nostack, preserves_flags) ); } #[inline(always)] #[cfg(target_feature = "ermsb")] pub unsafe fn set_bytes(dest: *mut u8, c: u8, count: usize) { - // FIXME: Use the Intel syntax once we drop LLVM 9 support on rust-lang/rust. - core::arch::asm!( - "repe stosb %al, (%rdi)", + asm!( + "repe stosb [rdi], al", inout("rcx") count => _, inout("rdi") dest => _, inout("al") c => _, - options(att_syntax, nostack, preserves_flags) + options(nostack, preserves_flags) ) } @@ -111,21 +109,21 @@ pub unsafe fn set_bytes(mut dest: *mut u8, c: u8, count: usize) { inout("ecx") pre_byte_count => _, inout("rdi") dest => dest, in("rax") c, - options(att_syntax, nostack, preserves_flags) + options(nostack, preserves_flags) ); asm!( "rep stosq", inout("rcx") qword_count => _, inout("rdi") dest => dest, in("rax") c, - options(att_syntax, nostack, preserves_flags) + options(nostack, preserves_flags) ); asm!( "rep stosb", inout("ecx") byte_count => _, inout("rdi") dest => _, in("rax") c, - options(att_syntax, nostack, preserves_flags) + options(nostack, preserves_flags) ); } @@ -212,10 +210,10 @@ pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize { let x = { let r; asm!( - "movdqa ({addr:r}), {dest}", + "movdqa {dest}, [{addr:r}]", addr = in(reg) s, dest = out(xmm_reg) r, - options(att_syntax, nostack), + options(nostack, preserves_flags), ); r }; @@ -232,10 +230,10 @@ pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize { let x = { let r; asm!( - "movdqa ({addr:r}), {dest}", + "movdqa {dest}, [{addr:r}]", addr = in(reg) s, dest = out(xmm_reg) r, - options(att_syntax, nostack), + options(nostack, preserves_flags), ); r }; @@ -277,10 +275,10 @@ pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize { let mut cs = { let r: u64; asm!( - "mov ({addr}), {dest}", + "mov {dest}, [{addr}]", addr = in(reg) s, dest = out(reg) r, - options(att_syntax, nostack), + options(nostack, preserves_flags), ); r }; diff --git a/library/compiler-builtins/compiler-builtins/src/probestack.rs b/library/compiler-builtins/compiler-builtins/src/probestack.rs index 72975485a776..1cab64ea113c 100644 --- a/library/compiler-builtins/compiler-builtins/src/probestack.rs +++ b/library/compiler-builtins/compiler-builtins/src/probestack.rs @@ -47,11 +47,11 @@ // We only define stack probing for these architectures today. #![cfg(any(target_arch = "x86_64", target_arch = "x86"))] -// Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax, +// Our goal here is to touch each page between `rsp+8` and `rsp+8-rax`, // ensuring that if any pages are unmapped we'll make a page fault. // -// The ABI here is that the stack frame size is located in `%rax`. Upon -// return we're not supposed to modify `%rsp` or `%rax`. +// The ABI here is that the stack frame size is located in `rax`. Upon +// return we're not supposed to modify `rsp` or `rax`. #[cfg(target_arch = "x86_64")] #[unsafe(naked)] #[rustc_std_internal_symbol] @@ -59,50 +59,50 @@ pub unsafe extern "custom" fn __rust_probestack() { core::arch::naked_asm!( " .cfi_startproc - pushq %rbp + push rbp .cfi_adjust_cfa_offset 8 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp + .cfi_offset rbp, -16 + mov rbp, rsp + .cfi_def_cfa_register rbp - mov %rax,%r11 // duplicate %rax as we're clobbering %r11 + mov r11, rax // duplicate rax as we're clobbering r11 // Main loop, taken in one page increments. We're decrementing rsp by // a page each time until there's less than a page remaining. We're // guaranteed that this function isn't called unless there's more than a // page needed. // - // Note that we're also testing against `8(%rsp)` to account for the 8 + // Note that we're also testing against `[rsp + 8]` to account for the 8 // bytes pushed on the stack originally with our return address. Using - // `8(%rsp)` simulates us testing the stack pointer in the caller's + // `[rsp + 8]` simulates us testing the stack pointer in the caller's // context. - // It's usually called when %rax >= 0x1000, but that's not always true. + // It's usually called when rax >= 0x1000, but that's not always true. // Dynamic stack allocation, which is needed to implement unsized - // rvalues, triggers stackprobe even if %rax < 0x1000. - // Thus we have to check %r11 first to avoid segfault. - cmp $0x1000,%r11 + // rvalues, triggers stackprobe even if rax < 0x1000. + // Thus we have to check r11 first to avoid segfault. + cmp r11, 0x1000 jna 3f 2: - sub $0x1000,%rsp - test %rsp,8(%rsp) - sub $0x1000,%r11 - cmp $0x1000,%r11 + sub rsp, 0x1000 + test qword ptr [rsp + 8], rsp + sub r11, 0x1000 + cmp r11, 0x1000 ja 2b 3: // Finish up the last remaining stack space requested, getting the last // bits out of r11 - sub %r11,%rsp - test %rsp,8(%rsp) + sub rsp, r11 + test qword ptr [rsp + 8], rsp // Restore the stack pointer to what it previously was when entering // this function. The caller will readjust the stack pointer after we // return. - add %rax,%rsp + add rsp, rax leave - .cfi_def_cfa_register %rsp + .cfi_def_cfa_register rsp .cfi_adjust_cfa_offset -8 ", #[cfg(not(all(target_env = "sgx", target_vendor = "fortanix")))] @@ -112,14 +112,13 @@ pub unsafe extern "custom" fn __rust_probestack() { // for this target, [manually patch for LVI]. // // [manually patch for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions - pop %r11 + pop r11 lfence - jmp *%r11 + jmp r11 ", " .cfi_endproc ", - options(att_syntax) ) } @@ -135,36 +134,35 @@ pub unsafe extern "custom" fn __rust_probestack() { core::arch::naked_asm!( " .cfi_startproc - push %ebp + push ebp .cfi_adjust_cfa_offset 4 - .cfi_offset %ebp, -8 - mov %esp, %ebp - .cfi_def_cfa_register %ebp - push %ecx - mov %eax,%ecx + .cfi_offset ebp, -8 + mov ebp, esp + .cfi_def_cfa_register ebp + push ecx + mov ecx, eax - cmp $0x1000,%ecx + cmp ecx, 0x1000 jna 3f 2: - sub $0x1000,%esp - test %esp,8(%esp) - sub $0x1000,%ecx - cmp $0x1000,%ecx + sub esp, 0x1000 + test dword ptr [esp + 8], esp + sub ecx, 0x1000 + cmp ecx, 0x1000 ja 2b 3: - sub %ecx,%esp - test %esp,8(%esp) + sub esp, ecx + test dword ptr [esp + 8], esp - add %eax,%esp - pop %ecx + add esp, eax + pop ecx leave - .cfi_def_cfa_register %esp + .cfi_def_cfa_register esp .cfi_adjust_cfa_offset -4 ret .cfi_endproc - ", - options(att_syntax) + ", ) } @@ -176,8 +174,8 @@ pub unsafe extern "custom" fn __rust_probestack() { // REF: Rust commit(74e80468347) // rust\src\llvm-project\llvm\lib\Target\X86\X86FrameLowering.cpp: 805 // Comments in LLVM: -// MSVC x32's _chkstk and cygwin/mingw's _alloca adjust %esp themselves. -// MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp +// MSVC x32's _chkstk and cygwin/mingw's _alloca adjust esp themselves. +// MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust `rsp` // themselves. #[unsafe(naked)] #[rustc_std_internal_symbol] @@ -185,40 +183,39 @@ pub unsafe extern "custom" fn __rust_probestack() { core::arch::naked_asm!( " .cfi_startproc - push %ebp + push ebp .cfi_adjust_cfa_offset 4 - .cfi_offset %ebp, -8 - mov %esp, %ebp - .cfi_def_cfa_register %ebp - push %ecx - push %edx - mov %eax,%ecx + .cfi_offset ebp, -8 + mov ebp, esp + .cfi_def_cfa_register ebp + push ecx + push edx + mov ecx, eax - cmp $0x1000,%ecx + cmp ecx, 0x1000 jna 3f 2: - sub $0x1000,%esp - test %esp,8(%esp) - sub $0x1000,%ecx - cmp $0x1000,%ecx + sub esp, 0x1000 + test dword ptr [esp + 8], esp + sub ecx, 0x1000 + cmp ecx, 0x1000 ja 2b 3: - sub %ecx,%esp - test %esp,8(%esp) - mov 4(%ebp),%edx - mov %edx, 12(%esp) - add %eax,%esp - pop %edx - pop %ecx + sub esp, ecx + test dword ptr [esp + 8], esp + mov edx, dword ptr [ebp + 4] + mov dword ptr [esp + 12], edx + add esp, eax + pop edx + pop ecx leave - sub %eax, %esp - .cfi_def_cfa_register %esp + sub esp, eax + .cfi_def_cfa_register esp .cfi_adjust_cfa_offset -4 ret .cfi_endproc - ", - options(att_syntax) + ", ) } diff --git a/library/compiler-builtins/compiler-builtins/src/x86.rs b/library/compiler-builtins/compiler-builtins/src/x86.rs index 51940b3b338a..1a3c41860945 100644 --- a/library/compiler-builtins/compiler-builtins/src/x86.rs +++ b/library/compiler-builtins/compiler-builtins/src/x86.rs @@ -22,26 +22,25 @@ intrinsics! { pub unsafe extern "custom" fn _alloca() { // __chkstk and _alloca are the same function core::arch::naked_asm!( - "push %ecx", - "cmp $0x1000,%eax", - "lea 8(%esp),%ecx", // esp before calling this routine -> ecx - "jb 1f", + "push ecx", + "cmp eax, 0x1000", + "lea ecx, [esp + 8]", // esp before calling this routine -> ecx + "jb 3f", "2:", - "sub $0x1000,%ecx", - "test %ecx,(%ecx)", - "sub $0x1000,%eax", - "cmp $0x1000,%eax", + "sub ecx, 0x1000", + "test [ecx], ecx", + "sub eax, 0x1000", + "cmp eax, 0x1000", "ja 2b", - "1:", - "sub %eax,%ecx", - "test %ecx,(%ecx)", - "lea 4(%esp),%eax", // load pointer to the return address into eax - "mov %ecx,%esp", // install the new top of stack pointer into esp - "mov -4(%eax),%ecx", // restore ecx - "push (%eax)", // push return address onto the stack - "sub %esp,%eax", // restore the original value in eax + "3:", + "sub ecx, eax", + "test [ecx], ecx", + "lea eax, [esp + 4]", // load pointer to the return address into eax + "mov esp, ecx", // install the new top of stack pointer into esp + "mov ecx, [eax - 4]", // restore ecx + "push [eax]", // push return address onto the stack + "sub eax, esp", // restore the original value in eax "ret", - options(att_syntax) ); } } diff --git a/library/compiler-builtins/compiler-builtins/src/x86_64.rs b/library/compiler-builtins/compiler-builtins/src/x86_64.rs index f9ae784d5752..99a527ee9ac5 100644 --- a/library/compiler-builtins/compiler-builtins/src/x86_64.rs +++ b/library/compiler-builtins/compiler-builtins/src/x86_64.rs @@ -12,24 +12,23 @@ intrinsics! { #[cfg(any(all(windows, target_env = "gnu"), target_os = "cygwin", target_os = "uefi"))] pub unsafe extern "custom" fn ___chkstk_ms() { core::arch::naked_asm!( - "push %rcx", - "push %rax", - "cmp $0x1000,%rax", - "lea 24(%rsp),%rcx", - "jb 1f", + "push rcx", + "push rax", + "cmp rax, 0x1000", + "lea rcx, [rsp + 24]", + "jb 3f", "2:", - "sub $0x1000,%rcx", - "test %rcx,(%rcx)", - "sub $0x1000,%rax", - "cmp $0x1000,%rax", + "sub rcx, 0x1000", + "test [rcx], rcx", + "sub rax, 0x1000", + "cmp rax, 0x1000", "ja 2b", - "1:", - "sub %rax,%rcx", - "test %rcx,(%rcx)", - "pop %rax", - "pop %rcx", + "3:", + "sub rcx, rax", + "test [rcx], rcx", + "pop rax", + "pop rcx", "ret", - options(att_syntax) ); } } From e6b6de40c23893fbce3e37f708175cb4f7e6e1ae Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Fri, 5 Dec 2025 19:33:24 +0000 Subject: [PATCH 0336/3801] bump version number --- src/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version b/src/version index 95784efddbc4..8db4a57b3d02 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.93.0 +1.94.0 From a57470ff727f5b527504d85b5eddfb2415ed9522 Mon Sep 17 00:00:00 2001 From: Sasha Pourcelot Date: Thu, 4 Dec 2025 14:33:47 +0000 Subject: [PATCH 0337/3801] Look for typos when reporting an unknown nightly feature --- .../rustc_parse/src/parser/diagnostics.rs | 24 +++++++-------- compiler/rustc_passes/messages.ftl | 2 ++ compiler/rustc_passes/src/errors.rs | 15 ++++++++++ compiler/rustc_passes/src/stability.rs | 30 +++++++++++++++---- compiler/rustc_span/src/symbol.rs | 22 ++++++++++++++ tests/ui/feature-gates/unknown-feature.rs | 4 ++- tests/ui/feature-gates/unknown-feature.stderr | 14 ++++++++- 7 files changed, 89 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index bd495f6ec1ac..d4667a09af6d 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -16,7 +16,6 @@ use rustc_errors::{ pluralize, }; use rustc_session::errors::ExprParenthesesNeeded; -use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::source_map::Spanned; use rustc_span::symbol::used_keywords; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, SpanSnippetError, Symbol, kw, sym}; @@ -222,6 +221,8 @@ impl std::fmt::Display for UnaryFixity { style = "verbose" )] struct MisspelledKw { + // We use a String here because `Symbol::into_diag_arg` calls `Symbol::to_ident_string`, which + // prefix the keyword with a `r#` because it aims to print the symbol as an identifier. similar_kw: String, #[primary_span] span: Span, @@ -229,20 +230,15 @@ struct MisspelledKw { } /// Checks if the given `lookup` identifier is similar to any keyword symbol in `candidates`. +/// +/// This is a specialized version of [`Symbol::find_similar`] that constructs an error when a +/// candidate is found. fn find_similar_kw(lookup: Ident, candidates: &[Symbol]) -> Option { - let lowercase = lookup.name.as_str().to_lowercase(); - let lowercase_sym = Symbol::intern(&lowercase); - if candidates.contains(&lowercase_sym) { - Some(MisspelledKw { similar_kw: lowercase, span: lookup.span, is_incorrect_case: true }) - } else if let Some(similar_sym) = find_best_match_for_name(candidates, lookup.name, None) { - Some(MisspelledKw { - similar_kw: similar_sym.to_string(), - span: lookup.span, - is_incorrect_case: false, - }) - } else { - None - } + lookup.name.find_similar(candidates).map(|(similar_kw, is_incorrect_case)| MisspelledKw { + similar_kw: similar_kw.to_string(), + is_incorrect_case, + span: lookup.span, + }) } struct MultiSugg { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 09ac3ae1c3a9..70e91c081776 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -421,6 +421,8 @@ passes_missing_panic_handler = passes_missing_stability_attr = {$descr} has missing stability attribute +passes_misspelled_feature = there is a feature with a similar name: `{$actual_name}` + passes_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `{$export_name_attr}` .label = `{$no_mangle_attr}` is ignored .note = `{$export_name_attr}` takes precedence diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index e4826cccd32f..6aa0f5212af7 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1183,6 +1183,21 @@ pub(crate) struct UnknownFeature { #[primary_span] pub span: Span, pub feature: Symbol, + #[subdiagnostic] + pub suggestion: Option, +} + +#[derive(Subdiagnostic)] +#[suggestion( + passes_misspelled_feature, + style = "verbose", + code = "{actual_name}", + applicability = "maybe-incorrect" +)] +pub(crate) struct MisspelledFeature { + #[primary_span] + pub span: Span, + pub actual_name: Symbol, } #[derive(Diagnostic)] diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 39830db2b11d..9d94c4cc6225 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -6,7 +6,7 @@ use std::num::NonZero; use rustc_ast_lowering::stability::extern_abi_stability; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet}; -use rustc_feature::{EnabledLangFeature, EnabledLibFeature}; +use rustc_feature::{EnabledLangFeature, EnabledLibFeature, UNSTABLE_LANG_FEATURES}; use rustc_hir::attrs::{AttributeKind, DeprecatedSince}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId}; @@ -1062,11 +1062,13 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { // no unknown features, because the collection also does feature attribute validation. let local_defined_features = tcx.lib_features(LOCAL_CRATE); if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() { + let crates = tcx.crates(()); + // Loading the implications of all crates is unavoidable to be able to emit the partial // stabilization diagnostic, but it can be avoided when there are no // `remaining_lib_features`. let mut all_implications = remaining_implications.clone(); - for &cnum in tcx.crates(()) { + for &cnum in crates { all_implications .extend_unord(tcx.stability_implications(cnum).items().map(|(k, v)| (*k, *v))); } @@ -1079,7 +1081,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { &all_implications, ); - for &cnum in tcx.crates(()) { + for &cnum in crates { if remaining_lib_features.is_empty() && remaining_implications.is_empty() { break; } @@ -1091,10 +1093,26 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { &all_implications, ); } - } - for (feature, span) in remaining_lib_features { - tcx.dcx().emit_err(errors::UnknownFeature { span, feature }); + if !remaining_lib_features.is_empty() { + let lang_features = + UNSTABLE_LANG_FEATURES.iter().map(|feature| feature.name).collect::>(); + let lib_features = crates + .into_iter() + .flat_map(|&cnum| { + tcx.lib_features(cnum).stability.keys().copied().into_sorted_stable_ord() + }) + .collect::>(); + + let valid_feature_names = [lang_features, lib_features].concat(); + + for (feature, span) in remaining_lib_features { + let suggestion = feature + .find_similar(&valid_feature_names) + .map(|(actual_name, _)| errors::MisspelledFeature { span, actual_name }); + tcx.dcx().emit_err(errors::UnknownFeature { span, feature, suggestion }); + } + } } for (&implied_by, &feature) in remaining_implications.to_sorted_stable_ord() { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7e513160de0c..171539b42a6e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -14,6 +14,7 @@ use rustc_data_structures::stable_hasher::{ use rustc_data_structures::sync::Lock; use rustc_macros::{Decodable, Encodable, HashStable_Generic, symbols}; +use crate::edit_distance::find_best_match_for_name; use crate::{DUMMY_SP, Edition, Span, with_session_globals}; #[cfg(test)] @@ -2843,6 +2844,27 @@ impl Symbol { // Avoid creating an empty identifier, because that asserts in debug builds. if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() } } + + /// Checks if `self` is similar to any symbol in `candidates`. + /// + /// The returned boolean represents whether the candidate is the same symbol with a different + /// casing. + /// + /// All the candidates are assumed to be lowercase. + pub fn find_similar( + self, + candidates: &[Symbol], + ) -> Option<(Symbol, /* is incorrect case */ bool)> { + let lowercase = self.as_str().to_lowercase(); + let lowercase_sym = Symbol::intern(&lowercase); + if candidates.contains(&lowercase_sym) { + Some((lowercase_sym, true)) + } else if let Some(similar_sym) = find_best_match_for_name(candidates, self, None) { + Some((similar_sym, false)) + } else { + None + } + } } impl fmt::Debug for Symbol { diff --git a/tests/ui/feature-gates/unknown-feature.rs b/tests/ui/feature-gates/unknown-feature.rs index 2ecc9b82a48d..a9e8e046eb16 100644 --- a/tests/ui/feature-gates/unknown-feature.rs +++ b/tests/ui/feature-gates/unknown-feature.rs @@ -1,14 +1,16 @@ #![feature( unknown_rust_feature, //~^ ERROR unknown feature - + // Typo for lang feature associated_types_default, //~^ ERROR unknown feature + //~| HELP there is a feature with a similar name // Typo for lib feature core_intrnisics, //~^ ERROR unknown feature + //~| HELP there is a feature with a similar name )] fn main() {} diff --git a/tests/ui/feature-gates/unknown-feature.stderr b/tests/ui/feature-gates/unknown-feature.stderr index a0cadb3f817f..1e5b953e99ca 100644 --- a/tests/ui/feature-gates/unknown-feature.stderr +++ b/tests/ui/feature-gates/unknown-feature.stderr @@ -9,12 +9,24 @@ error[E0635]: unknown feature `associated_types_default` | LL | associated_types_default, | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: there is a feature with a similar name: `associated_type_defaults` + | +LL - associated_types_default, +LL + associated_type_defaults, + | error[E0635]: unknown feature `core_intrnisics` - --> $DIR/unknown-feature.rs:10:5 + --> $DIR/unknown-feature.rs:11:5 | LL | core_intrnisics, | ^^^^^^^^^^^^^^^ + | +help: there is a feature with a similar name: `core_intrinsics` + | +LL - core_intrnisics, +LL + core_intrinsics, + | error: aborting due to 3 previous errors From 38ab135542d45b882f7e2bdaf07cd3a04673b2ec Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 5 Dec 2025 14:45:30 -0600 Subject: [PATCH 0338/3801] alloc: specialize String::extend for slices of str --- library/alloc/src/string.rs | 47 ++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 4a2689e01ff1..69dce9b1de17 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -47,6 +47,8 @@ use core::iter::FusedIterator; #[cfg(not(no_global_oom_handling))] use core::iter::from_fn; #[cfg(not(no_global_oom_handling))] +use core::num::Saturating; +#[cfg(not(no_global_oom_handling))] use core::ops::Add; #[cfg(not(no_global_oom_handling))] use core::ops::AddAssign; @@ -1097,6 +1099,23 @@ impl String { self.vec.extend_from_slice(string.as_bytes()) } + #[cfg(not(no_global_oom_handling))] + #[inline] + fn push_str_slice(&mut self, slice: &[&str]) { + // use saturating arithmetic to ensure that in the case of an overflow, reserve() throws OOM + let additional: Saturating = slice.iter().map(|x| Saturating(x.len())).sum(); + self.reserve(additional.0); + let (ptr, len, cap) = core::mem::take(self).into_raw_parts(); + unsafe { + let mut dst = ptr.add(len); + for new in slice { + core::ptr::copy_nonoverlapping(new.as_ptr(), dst, new.len()); + dst = dst.add(new.len()); + } + *self = String::from_raw_parts(ptr, len + additional.0, cap); + } + } + /// Copies elements from `src` range to the end of the string. /// /// # Panics @@ -2489,7 +2508,7 @@ impl<'a> Extend<&'a char> for String { #[stable(feature = "rust1", since = "1.0.0")] impl<'a> Extend<&'a str> for String { fn extend>(&mut self, iter: I) { - iter.into_iter().for_each(move |s| self.push_str(s)); + ::spec_extend_into(iter, self) } #[inline] @@ -2498,6 +2517,32 @@ impl<'a> Extend<&'a str> for String { } } +#[cfg(not(no_global_oom_handling))] +trait SpecExtendStr { + fn spec_extend_into(self, s: &mut String); +} + +#[cfg(not(no_global_oom_handling))] +impl<'a, T: IntoIterator> SpecExtendStr for T { + default fn spec_extend_into(self, target: &mut String) { + self.into_iter().for_each(move |s| target.push_str(s)); + } +} + +#[cfg(not(no_global_oom_handling))] +impl SpecExtendStr for [&str] { + fn spec_extend_into(self, target: &mut String) { + target.push_str_slice(&self); + } +} + +#[cfg(not(no_global_oom_handling))] +impl SpecExtendStr for [&str; N] { + fn spec_extend_into(self, target: &mut String) { + target.push_str_slice(&self[..]); + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_str2", since = "1.45.0")] impl Extend> for String { From ec65d89176827a8ff0e87ce553739bcae0a0265b Mon Sep 17 00:00:00 2001 From: quaternic <57393910+quaternic@users.noreply.github.com> Date: Fri, 5 Dec 2025 14:29:37 +0200 Subject: [PATCH 0339/3801] Document the purpose of a helper module --- library/compiler-builtins/libm/src/math/support/modular.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/compiler-builtins/libm/src/math/support/modular.rs b/library/compiler-builtins/libm/src/math/support/modular.rs index dbf1f0513a0d..e599ede0776e 100644 --- a/library/compiler-builtins/libm/src/math/support/modular.rs +++ b/library/compiler-builtins/libm/src/math/support/modular.rs @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: MIT OR Apache-2.0 */ +//! This module provides accelerated modular multiplication by large powers +//! of two, which is needed for computing floating point remainders in `fmod` +//! and similar functions. +//! //! To keep the equations somewhat concise, the following conventions are used: //! - all integer operations are in the mathematical sense, without overflow //! - concatenation means multiplication: `2xq = 2 * x * q` From e2ee56b206f3aa71a2a2d1bb3fbc54ad32210730 Mon Sep 17 00:00:00 2001 From: quaternic <57393910+quaternic@users.noreply.github.com> Date: Fri, 1 Aug 2025 02:20:04 +0300 Subject: [PATCH 0340/3801] libm: Optimize `fmod` This is kind of a retry at rust-lang/compiler-builtins#898. One of the problems there was that it would have added overhead and regressed performance for typical inputs. Unlike that PR, this doesn't aim for sub-linear scaling; the cost of evaluating `fmod(x, y)` is still roughly proportional to `log2(|x/y|)`. However, the constant factor is much better. Running the `random`-benchmarks locally, I got walltime reductions of fmodf16: -56.9% fmodf: -85.0% fmod: -95.4% fmodf128: -98.7% --- .../libm/src/math/generic/fmod.rs | 66 ++++++++++++++++--- .../libm/src/math/support/mod.rs | 2 - .../libm/src/math/support/modular.rs | 1 - 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/library/compiler-builtins/libm/src/math/generic/fmod.rs b/library/compiler-builtins/libm/src/math/generic/fmod.rs index 29acc8a4d5df..3c3fd44b27cc 100644 --- a/library/compiler-builtins/libm/src/math/generic/fmod.rs +++ b/library/compiler-builtins/libm/src/math/generic/fmod.rs @@ -1,8 +1,12 @@ /* SPDX-License-Identifier: MIT OR Apache-2.0 */ -use crate::support::{CastFrom, Float, Int, MinInt}; +use crate::support::{CastFrom, CastInto, Float, HInt, Int, MinInt, NarrowingDiv}; #[inline] -pub fn fmod(x: F, y: F) -> F { +pub fn fmod(x: F, y: F) -> F +where + F::Int: HInt, + ::D: NarrowingDiv, +{ let _1 = F::Int::ONE; let sx = x.to_bits() & F::SIGN_MASK; let ux = x.to_bits() & !F::SIGN_MASK; @@ -29,7 +33,7 @@ pub fn fmod(x: F, y: F) -> F { // To compute `(num << ex) % (div << ey)`, first // evaluate `rem = (num << (ex - ey)) % div` ... - let rem = reduction(num, ex - ey, div); + let rem = reduction::(num, ex - ey, div); // ... so the result will be `rem << ey` if rem.is_zero() { @@ -58,11 +62,55 @@ fn into_sig_exp(mut bits: F::Int) -> (F::Int, u32) { } /// Compute the remainder `(x * 2.pow(e)) % y` without overflow. -fn reduction(mut x: I, e: u32, y: I) -> I { - x %= y; - for _ in 0..e { - x <<= 1; - x = x.checked_sub(y).unwrap_or(x); +fn reduction(mut x: F::Int, e: u32, y: F::Int) -> F::Int +where + F: Float, + F::Int: HInt, + <::Int as HInt>::D: NarrowingDiv, +{ + // `f16` only has 5 exponent bits, so even `f16::MAX = 65504.0` is only + // a 40-bit integer multiple of the smallest subnormal. + if F::BITS == 16 { + debug_assert!(F::EXP_MAX - F::EXP_MIN == 29); + debug_assert!(e <= 29); + let u: u16 = x.cast(); + let v: u16 = y.cast(); + let u = (u as u64) << e; + let v = v as u64; + return F::Int::cast_from((u % v) as u16); } - x + + // Ensure `x < 2y` for later steps + if x >= (y << 1) { + // This case is only reached with subnormal divisors, + // but it might be better to just normalize all significands + // to make this unnecessary. The further calls could potentially + // benefit from assuming a specific fixed leading bit position. + x %= y; + } + + // The simple implementation seems to be fastest for a short reduction + // at this size. The limit here was chosen empirically on an Intel Nehalem. + // Less old CPUs that have faster `u64 * u64 -> u128` might not benefit, + // and 32-bit systems or architectures without hardware multipliers might + // want to do this in more cases. + if F::BITS == 64 && e < 32 { + // Assumes `x < 2y` + for _ in 0..e { + x = x.checked_sub(y).unwrap_or(x); + x <<= 1; + } + return x.checked_sub(y).unwrap_or(x); + } + + // Fast path for short reductions + if e < F::BITS { + let w = x.widen() << e; + if let Some((_, r)) = w.checked_narrowing_div_rem(y) { + return r; + } + } + + // Assumes `x < 2y` + crate::support::linear_mul_reduction(x, e, y) } diff --git a/library/compiler-builtins/libm/src/math/support/mod.rs b/library/compiler-builtins/libm/src/math/support/mod.rs index f35b9de3ed5c..15ab010dc8d5 100644 --- a/library/compiler-builtins/libm/src/math/support/mod.rs +++ b/library/compiler-builtins/libm/src/math/support/mod.rs @@ -29,9 +29,7 @@ pub use hex_float::hf16; pub use hex_float::hf128; #[allow(unused_imports)] pub use hex_float::{hf32, hf64}; -#[allow(unused_imports)] pub use int_traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt, NarrowingDiv}; -#[allow(unused_imports)] pub use modular::linear_mul_reduction; /// Hint to the compiler that the current path is cold. diff --git a/library/compiler-builtins/libm/src/math/support/modular.rs b/library/compiler-builtins/libm/src/math/support/modular.rs index e599ede0776e..cc0edf2f2bc0 100644 --- a/library/compiler-builtins/libm/src/math/support/modular.rs +++ b/library/compiler-builtins/libm/src/math/support/modular.rs @@ -14,7 +14,6 @@ use crate::support::{DInt, HInt, Int}; /// Compute the remainder `(x << e) % y` with unbounded integers. /// Requires `x < 2y` and `y.leading_zeros() >= 2` -#[allow(dead_code)] pub fn linear_mul_reduction(x: U, mut e: u32, mut y: U) -> U where U: HInt + Int, From 2261a505d90b0a33b093cf148f6efc7cf0479de2 Mon Sep 17 00:00:00 2001 From: Juho Kahala <57393910+quaternic@users.noreply.github.com> Date: Sat, 6 Dec 2025 02:59:12 +0200 Subject: [PATCH 0341/3801] Remove incorrectly placed preserves_flags, and other inline asm fixes * `repe` is "repeat while equal", which only makes sense for string comparisons. Change it to `rep`. (The encoding is the same so there is no performance change.) * Remove an unneeded `test`. This was added in ae557bde4efc ("Skip rep movsb in copy_backward if possible"). The `jz` was removed in ef37a23d8417 ("Remove branches around rep movsb/stosb") but the `test` was missed. * Remove an incorrect `preserves_flags`; `add` and `sub` affect flags. Discussion: https://github.com/rust-lang/compiler-builtins/pull/911 Fixes: ef37a23d8417 ("Remove branches around rep movsb/stosb") Fixes: c30322aafc9c ("Align destination in mem* instructions.") [ Added details to the commit message - Trevor ] --- .../compiler-builtins/compiler-builtins/src/mem/x86_64.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs b/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs index cb780ec036bb..bf36a286ac95 100644 --- a/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs +++ b/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs @@ -23,7 +23,7 @@ use core::{intrinsics, mem}; #[cfg(target_feature = "ermsb")] pub unsafe fn copy_forward(dest: *mut u8, src: *const u8, count: usize) { asm!( - "repe movsb [rdi], [rsi]", + "rep movsb [rdi], [rsi]", inout("rcx") count => _, inout("rdi") dest => _, inout("rsi") src => _, @@ -70,7 +70,6 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) { "sub rdi, 7", "mov rcx, {qword_count:r}", "rep movsq", - "test {pre_byte_count:e}, {pre_byte_count:e}", "add rsi, 7", "add rdi, 7", "mov ecx, {pre_byte_count:e}", @@ -81,8 +80,7 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) { inout("ecx") byte_count => _, inout("rdi") dest.add(count - 1) => _, inout("rsi") src.add(count - 1) => _, - // We modify flags, but we restore it afterwards - options(nostack, preserves_flags) + options(nostack) ); } @@ -90,7 +88,7 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) { #[cfg(target_feature = "ermsb")] pub unsafe fn set_bytes(dest: *mut u8, c: u8, count: usize) { asm!( - "repe stosb [rdi], al", + "rep stosb [rdi], al", inout("rcx") count => _, inout("rdi") dest => _, inout("al") c => _, From cf83387d2feefcb396f68b076d0210d764c9f733 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 5 Dec 2025 20:37:07 -0700 Subject: [PATCH 0342/3801] rustdoc: add test case for alias bug Reproduces --- .../rustdoc-merge-directory-alias/dep1.rs | 10 +++ .../rustdoc-merge-directory-alias/dep2.rs | 4 ++ .../rustdoc-merge-directory-alias/rmake.rs | 66 +++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 tests/run-make/rustdoc-merge-directory-alias/dep1.rs create mode 100644 tests/run-make/rustdoc-merge-directory-alias/dep2.rs create mode 100644 tests/run-make/rustdoc-merge-directory-alias/rmake.rs diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep1.rs b/tests/run-make/rustdoc-merge-directory-alias/dep1.rs new file mode 100644 index 000000000000..d1b32ccc69de --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/dep1.rs @@ -0,0 +1,10 @@ +pub struct Dep1; +pub struct Dep2; +pub struct Dep3; +pub struct Dep4; + +//@ hasraw crates.js 'dep1' +//@ hasraw search.index/name/*.js 'Dep1' +//@ has dep1/index.html +#[doc(alias="dep1_missing")] +pub struct Dep5; diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep2.rs b/tests/run-make/rustdoc-merge-directory-alias/dep2.rs new file mode 100644 index 000000000000..2df4452413c2 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/dep2.rs @@ -0,0 +1,4 @@ +//@ hasraw crates.js 'dep2' +//@ hasraw search.index/name/*.js 'Second' +//@ has dep2/index.html +pub struct Second; diff --git a/tests/run-make/rustdoc-merge-directory-alias/rmake.rs b/tests/run-make/rustdoc-merge-directory-alias/rmake.rs new file mode 100644 index 000000000000..934e695826ac --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/rmake.rs @@ -0,0 +1,66 @@ +// Running --merge=finalize without an input crate root should not trigger ICE. +// Issue: https://github.com/rust-lang/rust/issues/146646 + +//@ needs-target-std + +use run_make_support::{htmldocck, path, rustdoc}; + +fn main() { + let out_dir = path("out"); + let merged_dir = path("merged"); + let parts_out_dir = path("parts"); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + let output = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + rustdoc() + .input("dep2.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep2.json").exists()); + + let output2 = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output2.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + let output3 = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output3.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + htmldocck().arg(&out_dir).arg("dep1.rs").run(); + htmldocck().arg(&out_dir).arg("dep2.rs").run(); +} From fb3a0895e0c806c57ca28e84d3aac9768696b940 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 5 Dec 2025 20:45:31 -0700 Subject: [PATCH 0343/3801] rustdoc: avoid dangling alias pointers after merge --- src/librustdoc/html/render/search_index.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index da6840c72f5b..777a0a95fc83 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -721,7 +721,13 @@ impl SerializedSearchIndex { } }, ), - self.alias_pointers[id].and_then(|alias| map.get(&alias).copied()), + self.alias_pointers[id].and_then(|alias| { + if self.names[alias].is_empty() { + None + } else { + map.get(&alias).copied() + } + }), ); } new.generic_inverted_index = self From 38a2a3da3c9374eb11dbe63e68d57fb3315f869f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 5 Dec 2025 20:58:02 -0700 Subject: [PATCH 0344/3801] rustdoc: test for loading index when user said no Also mentioned, as a perf problem, in --- .../rustdoc-merge-directory-alias/dep1.rs | 2 +- .../dep_missing.rs | 4 ++++ .../rustdoc-merge-directory-alias/rmake.rs | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep1.rs b/tests/run-make/rustdoc-merge-directory-alias/dep1.rs index d1b32ccc69de..b62f31c982b7 100644 --- a/tests/run-make/rustdoc-merge-directory-alias/dep1.rs +++ b/tests/run-make/rustdoc-merge-directory-alias/dep1.rs @@ -6,5 +6,5 @@ pub struct Dep4; //@ hasraw crates.js 'dep1' //@ hasraw search.index/name/*.js 'Dep1' //@ has dep1/index.html -#[doc(alias="dep1_missing")] +#[doc(alias = "dep1_missing")] pub struct Dep5; diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs b/tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs new file mode 100644 index 000000000000..74236aef47ea --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs @@ -0,0 +1,4 @@ +//@ !hasraw crates.js 'dep_missing' +//@ !hasraw search.index/name/*.js 'DepMissing' +//@ has dep_missing/index.html +pub struct DepMissing; diff --git a/tests/run-make/rustdoc-merge-directory-alias/rmake.rs b/tests/run-make/rustdoc-merge-directory-alias/rmake.rs index 934e695826ac..096eb4a487c1 100644 --- a/tests/run-make/rustdoc-merge-directory-alias/rmake.rs +++ b/tests/run-make/rustdoc-merge-directory-alias/rmake.rs @@ -61,6 +61,28 @@ fn main() { .run(); output3.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + // dep_missing is different, because --parts-out-dir is not supplied + rustdoc().input("dep_missing.rs").out_dir(&out_dir).run(); + assert!(parts_out_dir.join("dep2.json").exists()); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + let output4 = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output4.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + htmldocck().arg(&out_dir).arg("dep1.rs").run(); htmldocck().arg(&out_dir).arg("dep2.rs").run(); + htmldocck().arg(&out_dir).arg("dep_missing.rs").run(); } From 6fb8d9fd92881ef06a49c253b0bb7f05c20431f4 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 5 Dec 2025 21:00:19 -0700 Subject: [PATCH 0345/3801] rustdoc: avoid loading index when user says no --- src/librustdoc/html/render/search_index.rs | 14 ++++++++------ src/librustdoc/html/render/write_shared.rs | 10 ++++++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 777a0a95fc83..a4cbef8c3917 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -24,6 +24,7 @@ use tracing::instrument; use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate}; use crate::clean::{self, utils}; +use crate::config::ShouldMerge; use crate::error::Error; use crate::formats::cache::{Cache, OrphanImplItem}; use crate::formats::item_type::ItemType; @@ -722,11 +723,7 @@ impl SerializedSearchIndex { }, ), self.alias_pointers[id].and_then(|alias| { - if self.names[alias].is_empty() { - None - } else { - map.get(&alias).copied() - } + if self.names[alias].is_empty() { None } else { map.get(&alias).copied() } }), ); } @@ -1254,6 +1251,7 @@ pub(crate) fn build_index( tcx: TyCtxt<'_>, doc_root: &Path, resource_suffix: &str, + should_merge: &ShouldMerge, ) -> Result { let mut search_index = std::mem::take(&mut cache.search_index); @@ -1304,7 +1302,11 @@ pub(crate) fn build_index( // // if there's already a search index, load it into memory and add the new entries to it // otherwise, do nothing - let mut serialized_index = SerializedSearchIndex::load(doc_root, resource_suffix)?; + let mut serialized_index = if should_merge.read_rendered_cci { + SerializedSearchIndex::load(doc_root, resource_suffix)? + } else { + SerializedSearchIndex::default() + }; // The crate always goes first in this list let crate_name = krate.name(tcx); diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 9a8df5393139..6bf116c3b75a 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -66,8 +66,14 @@ pub(crate) fn write_shared( // Write shared runs within a flock; disable thread dispatching of IO temporarily. let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file); - let search_index = - build_index(krate, &mut cx.shared.cache, tcx, &cx.dst, &cx.shared.resource_suffix)?; + let search_index = build_index( + krate, + &mut cx.shared.cache, + tcx, + &cx.dst, + &cx.shared.resource_suffix, + &opt.should_merge, + )?; let crate_name = krate.name(cx.tcx()); let crate_name = crate_name.as_str(); // rand From de3100e56077343ae5491655b6162615ae573cfb Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 6 Dec 2025 04:53:34 +0000 Subject: [PATCH 0346/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 36b2369c91d32c2659887ed6fe3d570640f44fd2. --- 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 45bf94eb4de4..b6a1415f1834 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -864339abf952f07098dd82610256338520167d4a +36b2369c91d32c2659887ed6fe3d570640f44fd2 From c5113ca1e2fd2eb24cd5ee1dc07f9ec224a7c2c9 Mon Sep 17 00:00:00 2001 From: EFanZh Date: Sat, 6 Dec 2025 12:55:15 +0800 Subject: [PATCH 0347/3801] Implement `Vec::from_fn` --- library/alloc/src/vec/mod.rs | 53 +++++++++++++++++++ tests/ui/suggestions/deref-path-method.stderr | 2 +- tests/ui/ufcs/bad-builder.stderr | 2 +- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 2adce8d27039..d2bc5d9bce39 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -745,6 +745,59 @@ impl Vec { unsafe { Self::from_parts_in(ptr, length, capacity, Global) } } + /// Creates a `Vec` where each element is produced by calling `f` with + /// that element's index while walking forward through the `Vec`. + /// + /// This is essentially the same as writing + /// + /// ```text + /// vec![f(0), f(1), f(2), …, f(length - 2), f(length - 1)] + /// ``` + /// and is similar to `(0..i).map(f)`, just for `Vec`s not iterators. + /// + /// If `length == 0`, this produces an empty `Vec` without ever calling `f`. + /// + /// # Example + /// + /// ```rust + /// #![feature(vec_from_fn)] + /// + /// let vec = Vec::from_fn(5, |i| i); + /// + /// // indexes are: 0 1 2 3 4 + /// assert_eq!(vec, [0, 1, 2, 3, 4]); + /// + /// let vec2 = Vec::from_fn(8, |i| i * 2); + /// + /// // indexes are: 0 1 2 3 4 5 6 7 + /// assert_eq!(vec2, [0, 2, 4, 6, 8, 10, 12, 14]); + /// + /// let bool_vec = Vec::from_fn(5, |i| i % 2 == 0); + /// + /// // indexes are: 0 1 2 3 4 + /// assert_eq!(bool_vec, [true, false, true, false, true]); + /// ``` + /// + /// The `Vec` is generated in ascending index order, starting from the front + /// and going towards the back, so you can use closures with mutable state: + /// ``` + /// #![feature(vec_from_fn)] + /// + /// let mut state = 1; + /// let a = Vec::from_fn(6, |_| { let x = state; state *= 2; x }); + /// + /// assert_eq!(a, [1, 2, 4, 8, 16, 32]); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[inline] + #[unstable(feature = "vec_from_fn", reason = "new API", issue = "149698")] + pub fn from_fn(length: usize, f: F) -> Self + where + F: FnMut(usize) -> T, + { + (0..length).map(f).collect() + } + /// Decomposes a `Vec` into its raw components: `(pointer, length, capacity)`. /// /// Returns the raw pointer to the underlying data, the length of diff --git a/tests/ui/suggestions/deref-path-method.stderr b/tests/ui/suggestions/deref-path-method.stderr index dc2f6f66437e..0dec424555ed 100644 --- a/tests/ui/suggestions/deref-path-method.stderr +++ b/tests/ui/suggestions/deref-path-method.stderr @@ -9,7 +9,7 @@ note: if you're trying to build a new `Vec<_, _>` consider using one of the foll Vec::::with_capacity Vec::::try_with_capacity Vec::::from_raw_parts - and 6 others + and 7 others --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: the function `contains` is implemented on `[_]` | diff --git a/tests/ui/ufcs/bad-builder.stderr b/tests/ui/ufcs/bad-builder.stderr index a3528cb1e7d8..2504a3d09253 100644 --- a/tests/ui/ufcs/bad-builder.stderr +++ b/tests/ui/ufcs/bad-builder.stderr @@ -9,7 +9,7 @@ note: if you're trying to build a new `Vec` consider using one of the followi Vec::::with_capacity Vec::::try_with_capacity Vec::::from_raw_parts - and 6 others + and 7 others --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: there is an associated function `new` with a similar name | From a8ffa1cbb035ddeb6e5c6326ffca26f58e7bb2b6 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sat, 6 Dec 2025 15:12:20 +0800 Subject: [PATCH 0348/3801] docs: update default branch name of `rust-lang/rust` --- book/src/development/infrastructure/sync.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/development/infrastructure/sync.md b/book/src/development/infrastructure/sync.md index 2bbdf47a8358..4506ff15d8ff 100644 --- a/book/src/development/infrastructure/sync.md +++ b/book/src/development/infrastructure/sync.md @@ -79,7 +79,7 @@ to be run inside the `rust` directory): ```bash git fetch upstream # assuming upstream is the rust-lang/rust remote git switch rustup - git merge upstream/master --no-ff + git merge upstream/main --no-ff ``` > Note: This is one of the few instances where a merge commit is allowed in > a PR. @@ -99,7 +99,7 @@ to be run inside the `rust` directory): All the following commands have to be run inside the `rust` directory. -1. Make sure you have checked out the latest `master` of `rust-lang/rust`. +1. Make sure you have checked out the latest `main` of `rust-lang/rust`. 2. Sync the `rust-lang/rust-clippy` master to the rust-copy of Clippy: ```bash git switch -c clippy-subtree-update From 65a4f94b71ef3c012e158766f3b846406721ac42 Mon Sep 17 00:00:00 2001 From: Juho Kahala <57393910+quaternic@users.noreply.github.com> Date: Sat, 6 Dec 2025 10:00:15 +0200 Subject: [PATCH 0349/3801] libm: Implement `exp` and its variants for i586 with inline assembly Resolve the severe imprecision (~2%) that is due to inconsistent rounding. Closes: https://github.com/rust-lang/compiler-builtins/issues/1021 --- .../libm-test/src/precision.rs | 34 +++++------ .../libm/src/math/arch/i586.rs | 59 +++++++++++++++++++ .../libm/src/math/arch/mod.rs | 5 ++ .../compiler-builtins/libm/src/math/exp.rs | 6 ++ .../compiler-builtins/libm/src/math/exp10.rs | 6 ++ .../compiler-builtins/libm/src/math/exp10f.rs | 6 ++ .../compiler-builtins/libm/src/math/exp2.rs | 6 ++ .../compiler-builtins/libm/src/math/exp2f.rs | 6 ++ .../compiler-builtins/libm/src/math/expf.rs | 6 ++ 9 files changed, 115 insertions(+), 19 deletions(-) diff --git a/library/compiler-builtins/libm-test/src/precision.rs b/library/compiler-builtins/libm-test/src/precision.rs index c441922d302b..968ac7170c08 100644 --- a/library/compiler-builtins/libm-test/src/precision.rs +++ b/library/compiler-builtins/libm-test/src/precision.rs @@ -83,6 +83,19 @@ pub fn default_ulp(ctx: &CheckCtx) -> u32 { Bn::Tgamma => 20, }; + // These have a separate implementation on i586 + if cfg!(x86_no_sse) { + match ctx.fn_ident { + Id::Exp => ulp = 1, + Id::Exp2 => ulp = 1, + Id::Exp10 => ulp = 1, + Id::Expf => ulp = 0, + Id::Exp2f => ulp = 0, + Id::Exp10f => ulp = 0, + _ => (), + } + } + // There are some cases where musl's approximation is less accurate than ours. For these // cases, increase the ULP. if ctx.basis == Musl { @@ -98,6 +111,8 @@ pub fn default_ulp(ctx: &CheckCtx) -> u32 { Id::Cbrt => ulp = 2, // FIXME(#401): musl has an incorrect result here. Id::Fdim => ulp = 2, + Id::Exp2f => ulp = 1, + Id::Expf => ulp = 1, Id::Sincosf => ulp = 500, Id::Tgamma => ulp = 20, _ => (), @@ -124,8 +139,6 @@ pub fn default_ulp(ctx: &CheckCtx) -> u32 { Id::Asinh => ulp = 3, Id::Asinhf => ulp = 3, Id::Cbrt => ulp = 1, - Id::Exp10 | Id::Exp10f => ulp = 1_000_000, - Id::Exp2 | Id::Exp2f => ulp = 10_000_000, Id::Log1p | Id::Log1pf => ulp = 2, Id::Tan => ulp = 2, _ => (), @@ -218,15 +231,6 @@ impl MaybeOverride<(f32,)> for SpecialCase { return XFAIL("expm1 representable numbers"); } - if cfg!(x86_no_sse) - && ctx.base_name == BaseName::Exp2 - && !expected.is_infinite() - && actual.is_infinite() - { - // We return infinity when there is a representable value. Test input: 127.97238 - return XFAIL("586 exp2 representable numbers"); - } - if ctx.base_name == BaseName::Sinh && input.0.abs() > 80.0 && actual.is_nan() { // we return some NaN that should be real values or infinite if ctx.basis == CheckBasis::Musl { @@ -278,14 +282,6 @@ impl MaybeOverride<(f64,)> for SpecialCase { return XFAIL("i586 rint rounding mode"); } - if cfg!(x86_no_sse) - && (ctx.fn_ident == Identifier::Exp10 || ctx.fn_ident == Identifier::Exp2) - { - // FIXME: i586 has very imprecise results with ULP > u32::MAX for these - // operations so we can't reasonably provide a limit. - return XFAIL_NOCHECK; - } - if ctx.base_name == BaseName::J0 && input.0 < -1e300 { // Errors get huge close to -inf return XFAIL_NOCHECK; diff --git a/library/compiler-builtins/libm/src/math/arch/i586.rs b/library/compiler-builtins/libm/src/math/arch/i586.rs index b9a66762063d..d9bb93fbf585 100644 --- a/library/compiler-builtins/libm/src/math/arch/i586.rs +++ b/library/compiler-builtins/libm/src/math/arch/i586.rs @@ -60,3 +60,62 @@ pub fn floor(mut x: f64) -> f64 { } x } +/// Implements the exponential functions with `x87` assembly. +/// +/// This relies on the instruction `f2xm1`, which computes `2^x - 1` (for +/// |x| < 1). This transcendental instruction is documented to produce results +/// with error below 1ulp (in the native double-extended precision format). This +/// translates to correctly rounded results for f32, but results in f64 may have +/// 1ulp error, which may depend on the hardware. +macro_rules! x87exp { + ($float_ty:ident, $word_size:literal, $fn_name:ident, $load_op:literal) => { + pub fn $fn_name(mut x: $float_ty) -> $float_ty { unsafe { + core::arch::asm!( + // Prepare the register stack as + // ``` + // st(0) = y = x*log2(base) + // st(1) = 1.0 + // st(2) = round(y) + // ``` + concat!($load_op, " ", $word_size, " ptr [{x}]"), + "fld1", + "fld st(1)", + "frndint", + "fxch st(2)", + + // Compare y with round(y) to determine if y is finite and + // not an integer. If so, compute `exp2(y - round(y))` into + // st(1). Otherwise skip ahead with `st(1) = 1.0` + "fucom st(2)", + "fstsw ax", + "test ax, 0x4000", + "jnz 2f", + "fsub st(0), st(2)", // st(0) = y - round(y) + "f2xm1", // st(0) = 2^st(0) - 1.0 + "fadd st(1), st(0)", // st(1) = 1 + st(0) = exp2(y - round(y)) + "2:", + + // Finally, scale by `exp2(round(y))` and clear the stack. + "fstp st(0)", + "fscale", + concat!("fstp ", $word_size, " ptr [{x}]"), + "fstp st(0)", + x = in(reg) &mut x, + out("ax") _, + out("st(0)") _, out("st(1)") _, + out("st(2)") _, out("st(3)") _, + out("st(4)") _, out("st(5)") _, + out("st(6)") _, out("st(7)") _, + options(nostack), + ); + x + }} + }; +} + +x87exp!(f32, "dword", x87_exp2f, "fld"); +x87exp!(f64, "qword", x87_exp2, "fld"); +x87exp!(f32, "dword", x87_exp10f, "fldl2t\nfmul"); +x87exp!(f64, "qword", x87_exp10, "fldl2t\nfmul"); +x87exp!(f32, "dword", x87_expf, "fldl2e\nfmul"); +x87exp!(f64, "qword", x87_exp, "fldl2e\nfmul"); diff --git a/library/compiler-builtins/libm/src/math/arch/mod.rs b/library/compiler-builtins/libm/src/math/arch/mod.rs index 984ae7f3129f..ba859c679d0d 100644 --- a/library/compiler-builtins/libm/src/math/arch/mod.rs +++ b/library/compiler-builtins/libm/src/math/arch/mod.rs @@ -48,3 +48,8 @@ cfg_if! { pub use i586::{ceil, floor}; } } +cfg_if! { + if #[cfg(x86_no_sse)] { + pub use i586::{x87_exp10f, x87_exp10, x87_expf, x87_exp, x87_exp2f, x87_exp2}; + } +} diff --git a/library/compiler-builtins/libm/src/math/exp.rs b/library/compiler-builtins/libm/src/math/exp.rs index 78ce5dd134ac..cb939ad5d8bf 100644 --- a/library/compiler-builtins/libm/src/math/exp.rs +++ b/library/compiler-builtins/libm/src/math/exp.rs @@ -83,6 +83,12 @@ const P5: f64 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ /// (where *e* is the base of the natural system of logarithms, approximately 2.71828). #[cfg_attr(assert_no_panic, no_panic::no_panic)] pub fn exp(mut x: f64) -> f64 { + select_implementation! { + name: x87_exp, + use_arch_required: x86_no_sse, + args: x, + } + let x1p1023 = f64::from_bits(0x7fe0000000000000); // 0x1p1023 === 2 ^ 1023 let x1p_149 = f64::from_bits(0x36a0000000000000); // 0x1p-149 === 2 ^ -149 diff --git a/library/compiler-builtins/libm/src/math/exp10.rs b/library/compiler-builtins/libm/src/math/exp10.rs index 1f49f5e96979..e0af1945b922 100644 --- a/library/compiler-builtins/libm/src/math/exp10.rs +++ b/library/compiler-builtins/libm/src/math/exp10.rs @@ -9,6 +9,12 @@ const P10: &[f64] = &[ /// Calculates 10 raised to the power of `x` (f64). #[cfg_attr(assert_no_panic, no_panic::no_panic)] pub fn exp10(x: f64) -> f64 { + select_implementation! { + name: x87_exp10, + use_arch_required: x86_no_sse, + args: x, + } + let (mut y, n) = modf(x); let u: u64 = n.to_bits(); /* fabs(n) < 16 without raising invalid on nan */ diff --git a/library/compiler-builtins/libm/src/math/exp10f.rs b/library/compiler-builtins/libm/src/math/exp10f.rs index 22a264211d03..f0a311c2d191 100644 --- a/library/compiler-builtins/libm/src/math/exp10f.rs +++ b/library/compiler-builtins/libm/src/math/exp10f.rs @@ -9,6 +9,12 @@ const P10: &[f32] = &[ /// Calculates 10 raised to the power of `x` (f32). #[cfg_attr(assert_no_panic, no_panic::no_panic)] pub fn exp10f(x: f32) -> f32 { + select_implementation! { + name: x87_exp10f, + use_arch_required: x86_no_sse, + args: x, + } + let (mut y, n) = modff(x); let u = n.to_bits(); /* fabsf(n) < 8 without raising invalid on nan */ diff --git a/library/compiler-builtins/libm/src/math/exp2.rs b/library/compiler-builtins/libm/src/math/exp2.rs index 6e4cbc29dcc9..08b71587f6de 100644 --- a/library/compiler-builtins/libm/src/math/exp2.rs +++ b/library/compiler-builtins/libm/src/math/exp2.rs @@ -324,6 +324,12 @@ static TBL: [u64; TBLSIZE * 2] = [ /// Calculate `2^x`, that is, 2 raised to the power `x`. #[cfg_attr(assert_no_panic, no_panic::no_panic)] pub fn exp2(mut x: f64) -> f64 { + select_implementation! { + name: x87_exp2, + use_arch_required: x86_no_sse, + args: x, + } + let redux = f64::from_bits(0x4338000000000000) / TBLSIZE as f64; let p1 = f64::from_bits(0x3fe62e42fefa39ef); let p2 = f64::from_bits(0x3fcebfbdff82c575); diff --git a/library/compiler-builtins/libm/src/math/exp2f.rs b/library/compiler-builtins/libm/src/math/exp2f.rs index 733d2f1a8473..ceff6822c596 100644 --- a/library/compiler-builtins/libm/src/math/exp2f.rs +++ b/library/compiler-builtins/libm/src/math/exp2f.rs @@ -75,6 +75,12 @@ static EXP2FT: [u64; TBLSIZE] = [ /// Calculate `2^x`, that is, 2 raised to the power `x`. #[cfg_attr(assert_no_panic, no_panic::no_panic)] pub fn exp2f(mut x: f32) -> f32 { + select_implementation! { + name: x87_exp2f, + use_arch_required: x86_no_sse, + args: x, + } + let redux = f32::from_bits(0x4b400000) / TBLSIZE as f32; let p1 = f32::from_bits(0x3f317218); let p2 = f32::from_bits(0x3e75fdf0); diff --git a/library/compiler-builtins/libm/src/math/expf.rs b/library/compiler-builtins/libm/src/math/expf.rs index dbbfdbba9253..5541ab79a9c1 100644 --- a/library/compiler-builtins/libm/src/math/expf.rs +++ b/library/compiler-builtins/libm/src/math/expf.rs @@ -32,6 +32,12 @@ const P2: f32 = -2.7667332906e-3; /* -0xb55215.0p-32 */ /// (where *e* is the base of the natural system of logarithms, approximately 2.71828). #[cfg_attr(assert_no_panic, no_panic::no_panic)] pub fn expf(mut x: f32) -> f32 { + select_implementation! { + name: x87_expf, + use_arch_required: x86_no_sse, + args: x, + } + let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127 let x1p_126 = f32::from_bits(0x800000); // 0x1p-126f === 2 ^ -126 /*original 0x1p-149f ??????????? */ let mut hx = x.to_bits(); From e87befcf988a203f3a3edbd936d1e6c98cd03cb3 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 6 Dec 2025 03:22:14 -0500 Subject: [PATCH 0350/3801] ci: Enable benchmarks on Aarch64 This was originally attempted at [1], but the numbers seemed to indicate that tests weren't being run or counted completely. That issue appears to be resolved, so add benchmarks for Aarch64. [1]: https://github.com/rust-lang/compiler-builtins/pull/930 --- library/compiler-builtins/.github/workflows/main.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 63809fe04b59..0ab32d698b2c 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -239,6 +239,8 @@ jobs: include: - target: x86_64-unknown-linux-gnu os: ubuntu-24.04 + - target: aarch64-unknown-linux-gnu + os: ubuntu-24.04-arm runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@master From 6b159bd84547e89ebdce9ec84279f7c029c05662 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 24 Jul 2025 06:06:30 -0500 Subject: [PATCH 0351/3801] Update Cargo.toml `authors` fields Jorge hasn't been very involved with these crates for a while (thank you for getting these super important projects going!). Update the `authors` field to include, as far as I am aware, everyone who has effectively maintained `compiler-builtins` at some point in time. This field is dropped from non-published crates. --- library/compiler-builtins/builtins-shim/Cargo.toml | 7 ++++++- library/compiler-builtins/builtins-test/Cargo.toml | 1 - library/compiler-builtins/compiler-builtins/Cargo.toml | 7 ++++++- library/compiler-builtins/crates/panic-handler/Cargo.toml | 1 - library/compiler-builtins/libm/Cargo.toml | 7 ++++++- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/library/compiler-builtins/builtins-shim/Cargo.toml b/library/compiler-builtins/builtins-shim/Cargo.toml index 707ebdbc77b2..ac77224f5ce1 100644 --- a/library/compiler-builtins/builtins-shim/Cargo.toml +++ b/library/compiler-builtins/builtins-shim/Cargo.toml @@ -11,7 +11,12 @@ [package] name = "compiler_builtins" version = "0.1.160" -authors = ["Jorge Aparicio "] +authors = [ + "Alex Crichton ", + "Amanieu d'Antras ", + "Jorge Aparicio ", + "Trevor Gross ", +] description = "Compiler intrinsics used by the Rust compiler." repository = "https://github.com/rust-lang/compiler-builtins" license = "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)" diff --git a/library/compiler-builtins/builtins-test/Cargo.toml b/library/compiler-builtins/builtins-test/Cargo.toml index 2bcffe349318..9346ea65420b 100644 --- a/library/compiler-builtins/builtins-test/Cargo.toml +++ b/library/compiler-builtins/builtins-test/Cargo.toml @@ -1,7 +1,6 @@ [package] name = "builtins-test" version = "0.1.0" -authors = ["Alex Crichton "] edition = "2024" publish = false license = "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)" diff --git a/library/compiler-builtins/compiler-builtins/Cargo.toml b/library/compiler-builtins/compiler-builtins/Cargo.toml index 8bbe136ce33e..0845861dcfe3 100644 --- a/library/compiler-builtins/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/compiler-builtins/Cargo.toml @@ -7,7 +7,12 @@ [package] name = "compiler_builtins" version = "0.1.160" -authors = ["Jorge Aparicio "] +authors = [ + "Alex Crichton ", + "Amanieu d'Antras ", + "Jorge Aparicio ", + "Trevor Gross ", +] description = "Compiler intrinsics used by the Rust compiler." repository = "https://github.com/rust-lang/compiler-builtins" license = "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)" diff --git a/library/compiler-builtins/crates/panic-handler/Cargo.toml b/library/compiler-builtins/crates/panic-handler/Cargo.toml index a6764fc481b6..70898368d8e7 100644 --- a/library/compiler-builtins/crates/panic-handler/Cargo.toml +++ b/library/compiler-builtins/crates/panic-handler/Cargo.toml @@ -1,7 +1,6 @@ [package] name = "panic-handler" version = "0.1.0" -authors = ["Alex Crichton "] edition = "2024" publish = false diff --git a/library/compiler-builtins/libm/Cargo.toml b/library/compiler-builtins/libm/Cargo.toml index 63b4d3c27798..5b5ca34fd2c9 100644 --- a/library/compiler-builtins/libm/Cargo.toml +++ b/library/compiler-builtins/libm/Cargo.toml @@ -1,7 +1,12 @@ [package] name = "libm" version = "0.2.15" -authors = ["Jorge Aparicio "] +authors = [ + "Alex Crichton ", + "Amanieu d'Antras ", + "Jorge Aparicio ", + "Trevor Gross ", +] description = "libm in pure Rust" categories = ["no-std"] keywords = ["libm", "math"] From 77825a264367ac4eafd4011e58a743411b687432 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Dec 2025 10:15:15 +0100 Subject: [PATCH 0352/3801] ubuntu riscv64 is broken even with extensive retries --- src/tools/miri/.github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index d6c702848494..4eeba3022892 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -31,13 +31,13 @@ jobs: os: ubuntu-24.04-arm multiarch: armhf gcc_cross: arm-linux-gnueabihf - - host_target: riscv64gc-unknown-linux-gnu - os: ubuntu-latest - multiarch: riscv64 - gcc_cross: riscv64-linux-gnu - qemu: true # Ubuntu mirrors are not reliable enough for these architectures # (see ). + # - host_target: riscv64gc-unknown-linux-gnu + # os: ubuntu-latest + # multiarch: riscv64 + # gcc_cross: riscv64-linux-gnu + # qemu: true # - host_target: s390x-unknown-linux-gnu # os: ubuntu-latest # multiarch: s390x From 71b093fd2c79a4de1354f8b00adba64d0bce25b6 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 5 Dec 2025 15:06:07 +0100 Subject: [PATCH 0353/3801] Emit `check-cfg` lints during attribute parsing rather than evaluation#149215 --- .../rustc_attr_parsing/src/attributes/cfg.rs | 82 +++++++------------ .../src/attributes/cfg_old.rs | 9 +- compiler/rustc_builtin_macros/src/cfg.rs | 8 +- .../rustc_builtin_macros/src/cfg_select.rs | 16 +--- compiler/rustc_codegen_ssa/src/back/link.rs | 7 +- compiler/rustc_expand/src/config.rs | 32 ++------ compiler/rustc_expand/src/expand.rs | 2 +- .../rustc_hir/src/attrs/data_structures.rs | 2 +- compiler/rustc_lint/src/early/diagnostics.rs | 16 ++-- compiler/rustc_lint_defs/src/lib.rs | 4 +- compiler/rustc_metadata/src/native_libs.rs | 7 +- compiler/rustc_resolve/src/diagnostics.rs | 2 +- 12 files changed, 64 insertions(+), 123 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index bd228315b2c9..490e28ed64c5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -2,16 +2,16 @@ use std::convert::identity; use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; -use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, NodeId, ast, token}; +use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, ast, token}; use rustc_errors::{Applicability, PResult}; use rustc_feature::{AttrSuggestionStyle, AttributeTemplate, Features, template}; use rustc_hir::attrs::CfgEntry; +use rustc_hir::lints::AttributeLintKind; use rustc_hir::{AttrPath, RustcVersion}; use rustc_parse::parser::{ForceCollect, Parser}; use rustc_parse::{exp, parse_in}; use rustc_session::Session; use rustc_session::config::ExpectedValues; -use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::UNEXPECTED_CFGS; use rustc_session::parse::{ParseSess, feature_err}; use rustc_span::{ErrorGuaranteed, Span, Symbol, sym}; @@ -23,10 +23,7 @@ use crate::session_diagnostics::{ AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg, ParsedDescription, }; -use crate::{ - AttributeParser, CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics, - try_gate_cfg, -}; +use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics, try_gate_cfg}; pub const CFG_TEMPLATE: AttributeTemplate = template!( List: &["predicate"], @@ -195,43 +192,46 @@ fn parse_name_value( } }; - Ok(CfgEntry::NameValue { name, name_span, value, span }) + match cx.sess.psess.check_config.expecteds.get(&name) { + Some(ExpectedValues::Some(values)) if !values.contains(&value.map(|(v, _)| v)) => cx + .emit_lint( + UNEXPECTED_CFGS, + AttributeLintKind::UnexpectedCfgValue((name, name_span), value), + span, + ), + None if cx.sess.psess.check_config.exhaustive_names => cx.emit_lint( + UNEXPECTED_CFGS, + AttributeLintKind::UnexpectedCfgName((name, name_span), value), + span, + ), + _ => { /* not unexpected */ } + } + + Ok(CfgEntry::NameValue { name, value: value.map(|(v, _)| v), span }) } -pub fn eval_config_entry( - sess: &Session, - cfg_entry: &CfgEntry, - id: NodeId, - emit_lints: ShouldEmit, -) -> EvalConfigResult { +pub fn eval_config_entry(sess: &Session, cfg_entry: &CfgEntry) -> EvalConfigResult { match cfg_entry { CfgEntry::All(subs, ..) => { - let mut all = None; for sub in subs { - let res = eval_config_entry(sess, sub, id, emit_lints); - // We cannot short-circuit because `eval_config_entry` emits some lints + let res = eval_config_entry(sess, sub); if !res.as_bool() { - all.get_or_insert(res); + return res; } } - all.unwrap_or_else(|| EvalConfigResult::True) + EvalConfigResult::True } CfgEntry::Any(subs, span) => { - let mut any = None; for sub in subs { - let res = eval_config_entry(sess, sub, id, emit_lints); - // We cannot short-circuit because `eval_config_entry` emits some lints + let res = eval_config_entry(sess, sub); if res.as_bool() { - any.get_or_insert(res); + return res; } } - any.unwrap_or_else(|| EvalConfigResult::False { - reason: cfg_entry.clone(), - reason_span: *span, - }) + EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } } CfgEntry::Not(sub, span) => { - if eval_config_entry(sess, sub, id, emit_lints).as_bool() { + if eval_config_entry(sess, sub).as_bool() { EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } } else { EvalConfigResult::True @@ -244,32 +244,8 @@ pub fn eval_config_entry( EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } } } - CfgEntry::NameValue { name, name_span, value, span } => { - if let ShouldEmit::ErrorsAndLints = emit_lints { - match sess.psess.check_config.expecteds.get(name) { - Some(ExpectedValues::Some(values)) - if !values.contains(&value.map(|(v, _)| v)) => - { - id.emit_span_lint( - sess, - UNEXPECTED_CFGS, - *span, - BuiltinLintDiag::UnexpectedCfgValue((*name, *name_span), *value), - ); - } - None if sess.psess.check_config.exhaustive_names => { - id.emit_span_lint( - sess, - UNEXPECTED_CFGS, - *span, - BuiltinLintDiag::UnexpectedCfgName((*name, *name_span), *value), - ); - } - _ => { /* not unexpected */ } - } - } - - if sess.psess.config.contains(&(*name, value.map(|(v, _)| v))) { + CfgEntry::NameValue { name, value, span } => { + if sess.psess.config.contains(&(*name, *value)) { EvalConfigResult::True } else { EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span } diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs index 70228d1e1510..adae3fa635f4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs @@ -2,6 +2,7 @@ use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, Nod use rustc_ast_pretty::pprust; use rustc_feature::{Features, GatedCfg, find_gated_cfg}; use rustc_hir::RustcVersion; +use rustc_hir::lints::AttributeLintKind; use rustc_session::Session; use rustc_session::config::ExpectedValues; use rustc_session::lint::builtin::UNEXPECTED_CFGS; @@ -51,10 +52,10 @@ pub fn cfg_matches( sess, UNEXPECTED_CFGS, cfg.span, - BuiltinLintDiag::UnexpectedCfgValue( + BuiltinLintDiag::AttributeLint(AttributeLintKind::UnexpectedCfgValue( (cfg.name, cfg.name_span), cfg.value.map(|v| (v, cfg.value_span.unwrap())), - ), + )), ); } None if sess.psess.check_config.exhaustive_names => { @@ -62,10 +63,10 @@ pub fn cfg_matches( sess, UNEXPECTED_CFGS, cfg.span, - BuiltinLintDiag::UnexpectedCfgName( + BuiltinLintDiag::AttributeLint(AttributeLintKind::UnexpectedCfgName( (cfg.name, cfg.name_span), cfg.value.map(|v| (v, cfg.value_span.unwrap())), - ), + )), ); } _ => { /* not unexpected */ } diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index b24e3065622d..7bc9080ba022 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -26,13 +26,7 @@ pub(crate) fn expand_cfg( ExpandResult::Ready(match parse_cfg(cx, sp, tts) { Ok(cfg) => { - let matches_cfg = attr::eval_config_entry( - cx.sess, - &cfg, - cx.current_expansion.lint_node_id, - ShouldEmit::ErrorsAndLints, - ) - .as_bool(); + let matches_cfg = attr::eval_config_entry(cx.sess, &cfg).as_bool(); MacEager::expr(cx.expr_bool(sp, matches_cfg)) } diff --git a/compiler/rustc_builtin_macros/src/cfg_select.rs b/compiler/rustc_builtin_macros/src/cfg_select.rs index b77a121ca0b9..dc8077b2a1ff 100644 --- a/compiler/rustc_builtin_macros/src/cfg_select.rs +++ b/compiler/rustc_builtin_macros/src/cfg_select.rs @@ -1,7 +1,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_attr_parsing as attr; use rustc_attr_parsing::{ - CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, ShouldEmit, parse_cfg_select, + CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, parse_cfg_select, }; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; use rustc_span::{Ident, Span, sym}; @@ -10,21 +10,13 @@ use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable}; /// Selects the first arm whose predicate evaluates to true. fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> { - let mut result = None; for (cfg, tt, arm_span) in branches.reachable { - if let EvalConfigResult::True = attr::eval_config_entry( - &ecx.sess, - &cfg, - ecx.current_expansion.lint_node_id, - ShouldEmit::ErrorsAndLints, - ) { - // FIXME(#149215) Ideally we should short-circuit here, but `eval_config_entry` currently emits lints so we cannot do this yet. - result.get_or_insert((tt, arm_span)); + if let EvalConfigResult::True = attr::eval_config_entry(&ecx.sess, &cfg) { + return Some((tt, arm_span)); } } - let wildcard = branches.wildcard.map(|(_, tt, span)| (tt, span)); - result.or(wildcard) + branches.wildcard.map(|(_, tt, span)| (tt, span)) } pub(super) fn expand_cfg_select<'cx>( diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index d35c3b6bb189..70db6794742d 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -13,8 +13,7 @@ use find_msvc_tools; use itertools::Itertools; use regex::Regex; use rustc_arena::TypedArena; -use rustc_ast::CRATE_NODE_ID; -use rustc_attr_parsing::{ShouldEmit, eval_config_entry}; +use rustc_attr_parsing::eval_config_entry; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; @@ -3029,9 +3028,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) { fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { - Some(ref cfg) => { - eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool() - } + Some(ref cfg) => eval_config_entry(sess, cfg).as_bool(), None => true, } } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 0b3ac472e0e8..492c845df171 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -163,10 +163,7 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec .iter() .flat_map(|attr| strip_unconfigured.process_cfg_attr(attr)) .take_while(|attr| { - !is_cfg(attr) - || strip_unconfigured - .cfg_true(attr, strip_unconfigured.lint_node_id, ShouldEmit::Nothing) - .as_bool() + !is_cfg(attr) || strip_unconfigured.cfg_true(attr, ShouldEmit::Nothing).as_bool() }) .collect() } @@ -309,14 +306,7 @@ impl<'a> StripUnconfigured<'a> { ); } - if !attr::eval_config_entry( - self.sess, - &cfg_predicate, - ast::CRATE_NODE_ID, - ShouldEmit::ErrorsAndLints, - ) - .as_bool() - { + if !attr::eval_config_entry(self.sess, &cfg_predicate).as_bool() { return vec![trace_attr]; } @@ -400,23 +390,17 @@ impl<'a> StripUnconfigured<'a> { /// Determines if a node with the given attributes should be included in this configuration. fn in_cfg(&self, attrs: &[Attribute]) -> bool { - attrs.iter().all(|attr| { - !is_cfg(attr) - || self.cfg_true(attr, self.lint_node_id, ShouldEmit::ErrorsAndLints).as_bool() - }) + attrs + .iter() + .all(|attr| !is_cfg(attr) || self.cfg_true(attr, ShouldEmit::ErrorsAndLints).as_bool()) } - pub(crate) fn cfg_true( - &self, - attr: &Attribute, - node: NodeId, - emit_errors: ShouldEmit, - ) -> EvalConfigResult { + pub(crate) fn cfg_true(&self, attr: &Attribute, emit_errors: ShouldEmit) -> EvalConfigResult { let Some(cfg) = AttributeParser::parse_single( self.sess, attr, attr.span, - node, + self.lint_node_id, self.features, emit_errors, parse_cfg, @@ -426,7 +410,7 @@ impl<'a> StripUnconfigured<'a> { return EvalConfigResult::True; }; - eval_config_entry(self.sess, &cfg, self.lint_node_id, emit_errors) + eval_config_entry(self.sess, &cfg) } /// If attributes are not allowed on expressions, emit an error for `attr` diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 20fb321307ac..90563b21d2e8 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2213,7 +2213,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { attr: ast::Attribute, pos: usize, ) -> EvalConfigResult { - let res = self.cfg().cfg_true(&attr, node.node_id(), ShouldEmit::ErrorsAndLints); + let res = self.cfg().cfg_true(&attr, ShouldEmit::ErrorsAndLints); if res.as_bool() { // A trace attribute left in AST in place of the original `cfg` attribute. // It can later be used by lints or other diagnostics. diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index d3cc1dd6cf75..aff79d055838 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -190,7 +190,7 @@ pub enum CfgEntry { Any(ThinVec, Span), Not(Box, Span), Bool(bool, Span), - NameValue { name: Symbol, name_span: Span, value: Option<(Symbol, Span)>, span: Span }, + NameValue { name: Symbol, value: Option, span: Span }, Version(Option, Span), } diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index b654bc848ecf..5345c9a4a985 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -169,12 +169,6 @@ pub fn decorate_builtin_lint( } .decorate_lint(diag); } - BuiltinLintDiag::UnexpectedCfgName(name, value) => { - check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag); - } - BuiltinLintDiag::UnexpectedCfgValue(name, value) => { - check_cfg::unexpected_cfg_value(sess, tcx, name, value).decorate_lint(diag); - } BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { let suggestion = match sugg { Some((right_sp, sugg)) => lints::DeprecatedWhereClauseLocationSugg::MoveToEnd { @@ -307,8 +301,8 @@ pub fn decorate_builtin_lint( } pub fn decorate_attribute_lint( - _sess: &Session, - _tcx: Option>, + sess: &Session, + tcx: Option>, kind: &AttributeLintKind, diag: &mut Diag<'_, ()>, ) { @@ -364,5 +358,11 @@ pub fn decorate_attribute_lint( suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right }, } .decorate_lint(diag), + &AttributeLintKind::UnexpectedCfgName(name, value) => { + check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag) + } + &AttributeLintKind::UnexpectedCfgValue(name, value) => { + check_cfg::unexpected_cfg_value(sess, tcx, name, value).decorate_lint(diag) + } } } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 3c6e7d04a29d..cc4062775ad3 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -636,8 +636,6 @@ pub enum BuiltinLintDiag { }, BreakWithLabelAndLoop(Span), UnicodeTextFlow(Span, String), - UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>), - UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>), DeprecatedWhereclauseLocation(Span, Option<(Span, String)>), SingleUseLifetime { /// Span of the parameter which declares this lifetime. @@ -732,6 +730,8 @@ pub enum AttributeLintKind { attribute_name_span: Span, sugg_spans: (Span, Span), }, + UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>), + UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>), } pub type RegisteredTools = FxIndexSet; diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 250657bc6806..e08460c3d4c9 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -2,8 +2,7 @@ use std::ops::ControlFlow; use std::path::{Path, PathBuf}; use rustc_abi::ExternAbi; -use rustc_ast::CRATE_NODE_ID; -use rustc_attr_parsing::{ShouldEmit, eval_config_entry}; +use rustc_attr_parsing::eval_config_entry; use rustc_data_structures::fx::FxHashSet; use rustc_hir::attrs::{AttributeKind, NativeLibKind, PeImportNameType}; use rustc_hir::find_attr; @@ -188,9 +187,7 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { - Some(ref cfg) => { - eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool() - } + Some(ref cfg) => eval_config_entry(sess, cfg).as_bool(), None => true, } } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 33c111708e36..a675c62ddf70 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -3070,7 +3070,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { continue; } - let item_was = if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 { + let item_was = if let CfgEntry::NameValue { value: Some(feature), .. } = cfg.0 { errors::ItemWas::BehindFeature { feature, span: cfg.1 } } else { errors::ItemWas::CfgOut { span: cfg.1 } From e7df90412c208f3e18af8ed60781a343dd87645a Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 5 Dec 2025 15:08:04 +0100 Subject: [PATCH 0354/3801] Changes to uitests --- .../ui/feature-gates/feature-gate-link_cfg.rs | 2 +- .../feature-gate-link_cfg.stderr | 4 ++-- tests/ui/link-native-libs/link-cfg-works.rs | 2 +- tests/ui/macros/cfg.rs | 3 ++- tests/ui/macros/cfg.stderr | 17 ++++++++++--- tests/ui/macros/cfg_select.rs | 2 ++ tests/ui/macros/cfg_select.stderr | 24 +++++++++++++++++-- 7 files changed, 44 insertions(+), 10 deletions(-) diff --git a/tests/ui/feature-gates/feature-gate-link_cfg.rs b/tests/ui/feature-gates/feature-gate-link_cfg.rs index d30ee3bcfdb1..286c3d0a4977 100644 --- a/tests/ui/feature-gates/feature-gate-link_cfg.rs +++ b/tests/ui/feature-gates/feature-gate-link_cfg.rs @@ -1,4 +1,4 @@ -#[link(name = "foo", cfg(foo))] +#[link(name = "foo", cfg(false))] //~^ ERROR: is unstable extern "C" {} diff --git a/tests/ui/feature-gates/feature-gate-link_cfg.stderr b/tests/ui/feature-gates/feature-gate-link_cfg.stderr index bfe7f74a9213..0e9707c6c962 100644 --- a/tests/ui/feature-gates/feature-gate-link_cfg.stderr +++ b/tests/ui/feature-gates/feature-gate-link_cfg.stderr @@ -1,8 +1,8 @@ error[E0658]: link cfg is unstable --> $DIR/feature-gate-link_cfg.rs:1:22 | -LL | #[link(name = "foo", cfg(foo))] - | ^^^^^^^^ +LL | #[link(name = "foo", cfg(false))] + | ^^^^^^^^^^ | = help: add `#![feature(link_cfg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/link-native-libs/link-cfg-works.rs b/tests/ui/link-native-libs/link-cfg-works.rs index 7b936bc43b1a..0e02933ce01c 100644 --- a/tests/ui/link-native-libs/link-cfg-works.rs +++ b/tests/ui/link-native-libs/link-cfg-works.rs @@ -7,7 +7,7 @@ extern crate link_cfg_works_transitive_dylib; extern crate link_cfg_works_transitive_rlib; -#[link(name = "foo", cfg(foo))] +#[link(name = "foo", cfg(false))] extern "C" {} fn main() {} diff --git a/tests/ui/macros/cfg.rs b/tests/ui/macros/cfg.rs index d992ec82e2fd..f0c51b2942f1 100644 --- a/tests/ui/macros/cfg.rs +++ b/tests/ui/macros/cfg.rs @@ -2,5 +2,6 @@ fn main() { cfg!(); //~ ERROR macro requires a cfg-pattern cfg!(123); //~ ERROR malformed `cfg` macro input cfg!(foo = 123); //~ ERROR malformed `cfg` macro input - cfg!(foo, bar); //~ ERROR expected 1 cfg-pattern + cfg!(false, false); //~ ERROR expected 1 cfg-pattern + cfg!(foo); //~ WARN unexpected `cfg` condition name: `foo` } diff --git a/tests/ui/macros/cfg.stderr b/tests/ui/macros/cfg.stderr index 9a4c187f37b2..06529a5b7a61 100644 --- a/tests/ui/macros/cfg.stderr +++ b/tests/ui/macros/cfg.stderr @@ -29,9 +29,20 @@ LL | cfg!(foo = 123); error: expected 1 cfg-pattern --> $DIR/cfg.rs:5:5 | -LL | cfg!(foo, bar); - | ^^^^^^^^^^^^^^ +LL | cfg!(false, false); + | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +warning: unexpected `cfg` condition name: `foo` + --> $DIR/cfg.rs:6:10 + | +LL | cfg!(foo); + | ^^^ + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +error: aborting due to 4 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index 2a627cc05b93..a54c385747fa 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -89,9 +89,11 @@ cfg_select! { cfg_select! { a + 1 => {} //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `+` + //~| WARN unexpected `cfg` condition name } cfg_select! { cfg!() => {} //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `!` + //~| WARN unexpected `cfg` condition name } diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 3a5d2b0a1e1e..d79e1b9b5c10 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -60,12 +60,32 @@ LL | a + 1 => {} | ^ expected one of `(`, `::`, `=>`, or `=` error: expected one of `(`, `::`, `=>`, or `=`, found `!` - --> $DIR/cfg_select.rs:95:8 + --> $DIR/cfg_select.rs:96:8 | LL | cfg!() => {} | ^ expected one of `(`, `::`, `=>`, or `=` -error: aborting due to 9 previous errors; 1 warning emitted +warning: unexpected `cfg` condition name: `a` + --> $DIR/cfg_select.rs:90:5 + | +LL | a + 1 => {} + | ^ help: found config with similar value: `target_feature = "a"` + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(a)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `cfg` + --> $DIR/cfg_select.rs:96:5 + | +LL | cfg!() => {} + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(cfg)` + = note: see for more information about checking conditional configuration + +error: aborting due to 9 previous errors; 3 warnings emitted Some errors have detailed explanations: E0537, E0539. For more information about an error, try `rustc --explain E0537`. From 01576a6de101ca85a8b43f2c3db2028c876a355c Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 6 Dec 2025 10:38:15 +0100 Subject: [PATCH 0355/3801] Add regression test for nested cfgs --- tests/ui/check-cfg/nested-cfg.rs | 8 ++++++++ tests/ui/check-cfg/nested-cfg.stderr | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/ui/check-cfg/nested-cfg.rs create mode 100644 tests/ui/check-cfg/nested-cfg.stderr diff --git a/tests/ui/check-cfg/nested-cfg.rs b/tests/ui/check-cfg/nested-cfg.rs new file mode 100644 index 000000000000..2b3a21f88dc5 --- /dev/null +++ b/tests/ui/check-cfg/nested-cfg.rs @@ -0,0 +1,8 @@ +//@ check-pass + +#[cfg(unknown)] //~ WARN unexpected `cfg` condition name +#[cfg(false)] +#[cfg(unknown)] // Should not warn +fn foo() {} + +fn main() {} diff --git a/tests/ui/check-cfg/nested-cfg.stderr b/tests/ui/check-cfg/nested-cfg.stderr new file mode 100644 index 000000000000..6fdae732bbe5 --- /dev/null +++ b/tests/ui/check-cfg/nested-cfg.stderr @@ -0,0 +1,23 @@ +warning: unexpected `cfg` condition name: `unknown` + --> $DIR/nested-cfg.rs:3:7 + | +LL | #[cfg(unknown)] + | ^^^^^^^ + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(unknown)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default +help: found config with similar value + | +LL - #[cfg(unknown)] +LL + #[cfg(target_os = "unknown")] + | +help: found config with similar value + | +LL - #[cfg(unknown)] +LL + #[cfg(target_vendor = "unknown")] + | + +warning: 1 warning emitted + From 1647f4495515c0dc327f7de431ebaafd1c80d7d8 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 21 Nov 2025 15:44:14 +0200 Subject: [PATCH 0356/3801] feat: Support fstat in linux refactor: rename `macos_fbsd_solarish_write_stat_buf` to `write_stat_buf` refactor: rename `macos_fbsd_solarish_fstat` to `fstat` feat: support `fstat` in linux test: testing support of `fstat` in linux fix: missed add `Os::Linux` for supported OSs in `fstat` feat: add nanosecond fields to file metadata in `EvalContextExtPrivate` add `fstat` to foreign items in unix enhance test of `fstat` fix the test --- .../miri/src/shims/unix/foreign_items.rs | 5 +++ .../src/shims/unix/freebsd/foreign_items.rs | 2 +- src/tools/miri/src/shims/unix/fs.rs | 28 +++++++-------- .../src/shims/unix/linux/foreign_items.rs | 6 +++- .../src/shims/unix/macos/foreign_items.rs | 4 +-- .../src/shims/unix/solarish/foreign_items.rs | 2 +- src/tools/miri/tests/pass-dep/libc/libc-fs.rs | 34 +++++++++++++++++++ 7 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 114f1a321faa..95a0a063bfdd 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -345,6 +345,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.symlink(target, linkpath)?; this.write_scalar(result, dest)?; } + "fstat" => { + let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + let result = this.fstat(fd, buf)?; + this.write_scalar(result, dest)?; + } "rename" => { let [oldpath, newpath] = this.check_shim_sig( shim_sig!(extern "C" fn(*const _, *const _) -> i32), 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 413df85ee3aa..2a1969049cf7 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -150,7 +150,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "fstat" | "fstat@FBSD_1.0" => { let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_solarish_fstat(fd, buf)?; + let result = this.fstat(fd, buf)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r@FBSD_1.0" => { diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 16214d7ef14e..0b98ab34917d 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -118,7 +118,7 @@ impl UnixFileDescription for FileHandle { impl<'tcx> EvalContextExtPrivate<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> { - fn macos_fbsd_solarish_write_stat_buf( + fn write_stat_buf( &mut self, metadata: FileMetadata, buf_op: &OpTy<'tcx>, @@ -141,8 +141,11 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> { ("st_gid", metadata.gid.into()), ("st_rdev", 0), ("st_atime", access_sec.into()), + ("st_atime_nsec", access_nsec.into()), ("st_mtime", modified_sec.into()), + ("st_mtime_nsec", modified_nsec.into()), ("st_ctime", 0), + ("st_ctime_nsec", 0), ("st_size", metadata.size.into()), ("st_blocks", 0), ("st_blksize", 0), @@ -550,7 +553,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Err(err) => return this.set_last_error_and_return_i32(err), }; - interp_ok(Scalar::from_i32(this.macos_fbsd_solarish_write_stat_buf(metadata, buf_op)?)) + interp_ok(Scalar::from_i32(this.write_stat_buf(metadata, buf_op)?)) } // `lstat` is used to get symlink metadata. @@ -583,22 +586,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Err(err) => return this.set_last_error_and_return_i32(err), }; - interp_ok(Scalar::from_i32(this.macos_fbsd_solarish_write_stat_buf(metadata, buf_op)?)) + interp_ok(Scalar::from_i32(this.write_stat_buf(metadata, buf_op)?)) } - fn macos_fbsd_solarish_fstat( - &mut self, - fd_op: &OpTy<'tcx>, - buf_op: &OpTy<'tcx>, - ) -> InterpResult<'tcx, Scalar> { + fn fstat(&mut self, fd_op: &OpTy<'tcx>, buf_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos) - { - panic!( - "`macos_fbsd_solaris_fstat` should not be called on {}", - this.tcx.sess.target.os - ); + if !matches!( + &this.tcx.sess.target.os, + Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos | Os::Linux + ) { + panic!("`fstat` should not be called on {}", this.tcx.sess.target.os); } let fd = this.read_scalar(fd_op)?.to_i32()?; @@ -614,7 +612,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Ok(metadata) => metadata, Err(err) => return this.set_last_error_and_return_i32(err), }; - interp_ok(Scalar::from_i32(this.macos_fbsd_solarish_write_stat_buf(metadata, buf_op)?)) + interp_ok(Scalar::from_i32(this.write_stat_buf(metadata, buf_op)?)) } fn linux_statx( 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 79052698f4ba..5ced0b7f32ef 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -53,7 +53,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?; this.write_scalar(result, dest)?; } - + "fstat" => { + let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + let result = this.fstat(fd, buf)?; + this.write_scalar(result, dest)?; + } // epoll, eventfd "epoll_create1" => { let [flag] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index 1b273593de63..731b9aa5d55f 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -56,9 +56,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.macos_fbsd_solarish_lstat(path, buf)?; this.write_scalar(result, dest)?; } - "fstat" | "fstat64" | "fstat$INODE64" => { + "fstat$INODE64" => { let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_solarish_fstat(fd, buf)?; + let result = this.fstat(fd, buf)?; this.write_scalar(result, dest)?; } "opendir$INODE64" => { 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 6335e6bc9662..d081a1f2d028 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -102,7 +102,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "fstat" | "fstat64" => { let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_solarish_fstat(fd, buf)?; + let result = this.fstat(fd, buf)?; this.write_scalar(result, dest)?; } "readdir" => { diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs index 41c3e3a12246..b1872e807653 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs @@ -42,6 +42,7 @@ fn main() { test_posix_fallocate::(libc::posix_fallocate64); #[cfg(target_os = "linux")] test_sync_file_range(); + test_fstat(); test_isatty(); test_read_and_uninit(); test_nofollow_not_symlink(); @@ -452,6 +453,39 @@ fn test_sync_file_range() { assert_eq!(result_2, 0); } +fn test_fstat() { + use std::mem::MaybeUninit; + use std::os::unix::io::AsRawFd; + + let path = utils::prepare_with_content("miri_test_libc_fstat.txt", b"hello"); + let file = File::open(&path).unwrap(); + let fd = file.as_raw_fd(); + + let mut stat: libc::stat = unsafe { MaybeUninit::zeroed().assume_init() }; + let res = unsafe { libc::fstat(fd, &mut stat) }; + assert_eq!(res, 0); + + assert_eq!(stat.st_size, 5); + assert_eq!(stat.st_mode & libc::S_IFMT, libc::S_IFREG); + + let _st_nlink = stat.st_nlink; + let _st_blksize = stat.st_blksize; + let _st_blocks = stat.st_blocks; + let _st_ino = stat.st_ino; + let _st_dev = stat.st_dev; + let _st_uid = stat.st_uid; + let _st_gid = stat.st_gid; + let _st_rdev = stat.st_rdev; + let _st_atime = stat.st_atime; + let _st_mtime = stat.st_mtime; + let _st_ctime = stat.st_ctime; + let _st_atime_nsec = stat.st_atime_nsec; + let _st_mtime_nsec = stat.st_mtime_nsec; + let _st_ctime_nsec = stat.st_ctime_nsec; + + remove_file(&path).unwrap(); +} + fn test_isatty() { // Testing whether our isatty shim returns the right value would require controlling whether // these streams are actually TTYs, which is hard. From 8b9d1d7d80cc506ba25768eda5c9eabba3def7e6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Dec 2025 11:23:47 +0100 Subject: [PATCH 0357/3801] use correct stat type and fix some redundancy --- src/tools/miri/src/shims/unix/freebsd/foreign_items.rs | 2 +- src/tools/miri/src/shims/unix/fs.rs | 9 +++++---- src/tools/miri/src/shims/unix/linux/foreign_items.rs | 5 ----- src/tools/miri/src/shims/unix/solarish/foreign_items.rs | 5 ----- src/tools/miri/tests/pass-dep/libc/libc-fs.rs | 6 ++++-- 5 files changed, 10 insertions(+), 17 deletions(-) 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 2a1969049cf7..9f7a19269c17 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -148,7 +148,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.macos_fbsd_solarish_lstat(path, buf)?; this.write_scalar(result, dest)?; } - "fstat" | "fstat@FBSD_1.0" => { + "fstat@FBSD_1.0" => { let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.fstat(fd, buf)?; 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 0b98ab34917d..8329cd47bb76 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -130,7 +130,11 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> { let (modified_sec, modified_nsec) = metadata.modified.unwrap_or((0, 0)); let mode = metadata.mode.to_uint(this.libc_ty_layout("mode_t").size)?; - let buf = this.deref_pointer_as(buf_op, this.libc_ty_layout("stat"))?; + // We do *not* use `deref_pointer_as` here since determining the right pointee type + // is highly non-trivial: it depends on which exact alias of the function was invoked + // (e.g. `fstat` vs `fstat64`), and then on FreeBSD it also depends on the ABI level + // which can be different between the libc used by std and the libc used by everyone else. + let buf = this.deref_pointer(buf_op)?; this.write_int_fields_named( &[ ("st_dev", metadata.dev.into()), @@ -156,9 +160,6 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> { if matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd) { this.write_int_fields_named( &[ - ("st_atime_nsec", access_nsec.into()), - ("st_mtime_nsec", modified_nsec.into()), - ("st_ctime_nsec", 0), ("st_birthtime", created_sec.into()), ("st_birthtime_nsec", created_nsec.into()), ("st_flags", 0), 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 5ced0b7f32ef..4c76b08a454e 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -53,11 +53,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?; this.write_scalar(result, dest)?; } - "fstat" => { - let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.fstat(fd, buf)?; - this.write_scalar(result, dest)?; - } // epoll, eventfd "epoll_create1" => { let [flag] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; 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 d081a1f2d028..b5eca70c3bf0 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -100,11 +100,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.macos_fbsd_solarish_lstat(path, buf)?; this.write_scalar(result, dest)?; } - "fstat" | "fstat64" => { - let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.fstat(fd, buf)?; - this.write_scalar(result, dest)?; - } "readdir" => { let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.readdir64("dirent", dirp)?; diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs index b1872e807653..3a4ac2a1b3ee 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs @@ -461,13 +461,15 @@ fn test_fstat() { let file = File::open(&path).unwrap(); let fd = file.as_raw_fd(); - let mut stat: libc::stat = unsafe { MaybeUninit::zeroed().assume_init() }; - let res = unsafe { libc::fstat(fd, &mut stat) }; + let mut stat = MaybeUninit::::uninit(); + let res = unsafe { libc::fstat(fd, stat.as_mut_ptr()) }; assert_eq!(res, 0); + let stat = unsafe { stat.assume_init_ref() }; assert_eq!(stat.st_size, 5); assert_eq!(stat.st_mode & libc::S_IFMT, libc::S_IFREG); + // Check that all fields are initialized. let _st_nlink = stat.st_nlink; let _st_blksize = stat.st_blksize; let _st_blocks = stat.st_blocks; From 44aaae38ac858cda6491c62cd8e897bb6e566f86 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Dec 2025 11:41:11 +0100 Subject: [PATCH 0358/3801] remove readdir_r on FreeBSD: it is deprecated, unused, and untested --- .../src/shims/unix/freebsd/foreign_items.rs | 6 ---- src/tools/miri/src/shims/unix/fs.rs | 33 +++---------------- .../src/shims/unix/macos/foreign_items.rs | 2 +- 3 files changed, 5 insertions(+), 36 deletions(-) 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 9f7a19269c17..c48301c72416 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -153,12 +153,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.fstat(fd, buf)?; this.write_scalar(result, dest)?; } - "readdir_r" | "readdir_r@FBSD_1.0" => { - let [dirp, entry, result] = - this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; - this.write_scalar(result, dest)?; - } "readdir" | "readdir@FBSD_1.0" => { let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.readdir64("dirent", dirp)?; diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 8329cd47bb76..650972be5574 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -1030,7 +1030,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(Scalar::from_maybe_pointer(entry.unwrap_or_else(Pointer::null), this)) } - fn macos_fbsd_readdir_r( + fn macos_readdir_r( &mut self, dirp_op: &OpTy<'tcx>, entry_op: &OpTy<'tcx>, @@ -1038,9 +1038,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd) { - panic!("`macos_fbsd_readdir_r` should not be called on {}", this.tcx.sess.target.os); - } + this.assert_target_os(Os::MacOs, "readdir_r"); let dirp = this.read_target_usize(dirp_op)?; let result_place = this.deref_pointer_as(result_op, this.machine.layouts.mut_raw_ptr)?; @@ -1096,39 +1094,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let file_type = this.file_type_to_d_type(dir_entry.file_type())?; - // Common fields. this.write_int_fields_named( &[ ("d_reclen", 0), ("d_namlen", file_name_len.into()), ("d_type", file_type.into()), + ("d_ino", ino.into()), + ("d_seekoff", 0), ], &entry_place, )?; - // Special fields. - match this.tcx.sess.target.os { - Os::MacOs => { - #[rustfmt::skip] - this.write_int_fields_named( - &[ - ("d_ino", ino.into()), - ("d_seekoff", 0), - ], - &entry_place, - )?; - } - Os::FreeBsd => { - #[rustfmt::skip] - this.write_int_fields_named( - &[ - ("d_fileno", ino.into()), - ("d_off", 0), - ], - &entry_place, - )?; - } - _ => unreachable!(), - } this.write_scalar(this.read_scalar(entry_op)?, &result_place)?; Scalar::from_i32(0) diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index 731b9aa5d55f..6e1b554afda6 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -69,7 +69,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "readdir_r" | "readdir_r$INODE64" => { let [dirp, entry, result] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; + let result = this.macos_readdir_r(dirp, entry, result)?; this.write_scalar(result, dest)?; } "realpath$DARWIN_EXTSN" => { From a26b26ac6f44c9be593929545088e329dd6428df Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Dec 2025 11:46:38 +0100 Subject: [PATCH 0359/3801] cleanup: the *64 functions are Linux-specific --- .../miri/src/shims/unix/foreign_items.rs | 71 +----------------- .../src/shims/unix/linux/foreign_items.rs | 74 +++++++++++++++++++ .../src/shims/unix/macos/foreign_items.rs | 4 +- .../src/shims/unix/solarish/foreign_items.rs | 4 +- src/tools/miri/tests/pass-dep/libc/libc-fs.rs | 2 +- 5 files changed, 80 insertions(+), 75 deletions(-) diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 95a0a063bfdd..378a8537fc73 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -235,33 +235,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { trace!("Called pwrite({:?}, {:?}, {:?}, {:?})", fd, buf, count, offset); this.write(fd, buf, count, Some(offset), dest)?; } - "pread64" => { - let [fd, buf, count, offset] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32, *mut _, usize, libc::off64_t) -> isize), - link_name, - abi, - args, - )?; - let fd = this.read_scalar(fd)?.to_i32()?; - let buf = this.read_pointer(buf)?; - let count = this.read_target_usize(count)?; - let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; - this.read(fd, buf, count, Some(offset), dest)?; - } - "pwrite64" => { - let [fd, buf, n, offset] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32, *const _, usize, libc::off64_t) -> isize), - link_name, - abi, - args, - )?; - let fd = this.read_scalar(fd)?.to_i32()?; - let buf = this.read_pointer(buf)?; - let count = this.read_target_usize(n)?; - let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; - trace!("Called pwrite64({:?}, {:?}, {:?}, {:?})", fd, buf, count, offset); - this.write(fd, buf, count, Some(offset), dest)?; - } "close" => { let [fd] = this.check_shim_sig( shim_sig!(extern "C" fn(i32) -> i32), @@ -317,7 +290,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // File and file system access - "open" | "open64" => { + "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) = @@ -400,18 +373,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.closedir(dirp)?; this.write_scalar(result, dest)?; } - "lseek64" => { - 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, - )?; - let fd = this.read_scalar(fd)?.to_i32()?; - let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; - let whence = this.read_scalar(whence)?.to_i32()?; - this.lseek64(fd, offset, whence, dest)?; - } "lseek" => { let [fd, offset, whence] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off_t, i32) -> libc::off_t), @@ -424,18 +385,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let whence = this.read_scalar(whence)?.to_i32()?; this.lseek64(fd, offset, whence, dest)?; } - "ftruncate64" => { - let [fd, length] = this.check_shim_sig( - shim_sig!(extern "C" fn(i32, libc::off64_t) -> i32), - link_name, - abi, - args, - )?; - let fd = this.read_scalar(fd)?.to_i32()?; - let length = this.read_scalar(length)?.to_int(length.layout.size)?; - let result = this.ftruncate64(fd, length)?; - this.write_scalar(result, dest)?; - } "ftruncate" => { let [fd, length] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, libc::off_t) -> i32), @@ -516,24 +465,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } - "posix_fallocate64" => { - // posix_fallocate64 is only supported on Linux and Android - this.check_target_os(&[Os::Linux, Os::Android], link_name)?; - 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, - )?; - - let fd = this.read_scalar(fd)?.to_i32()?; - let offset = this.read_scalar(offset)?.to_i64()?; - let len = this.read_scalar(len)?.to_i64()?; - - let result = this.posix_fallocate(fd, offset, len)?; - this.write_scalar(result, dest)?; - } - "realpath" => { let [path, resolved_path] = this.check_shim_sig( shim_sig!(extern "C" fn(*const _, *mut _) -> *mut _), 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 4c76b08a454e..a7cb2ed11b2b 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -36,6 +36,80 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // File related shims + "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 result = this.open(path_raw, flag, varargs)?; + this.write_scalar(result, dest)?; + } + "pread64" => { + let [fd, buf, count, offset] = this.check_shim_sig( + shim_sig!(extern "C" fn(i32, *mut _, usize, libc::off64_t) -> isize), + link_name, + abi, + args, + )?; + let fd = this.read_scalar(fd)?.to_i32()?; + let buf = this.read_pointer(buf)?; + let count = this.read_target_usize(count)?; + let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; + this.read(fd, buf, count, Some(offset), dest)?; + } + "pwrite64" => { + let [fd, buf, n, offset] = this.check_shim_sig( + shim_sig!(extern "C" fn(i32, *const _, usize, libc::off64_t) -> isize), + link_name, + abi, + args, + )?; + let fd = this.read_scalar(fd)?.to_i32()?; + let buf = this.read_pointer(buf)?; + let count = this.read_target_usize(n)?; + let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; + trace!("Called pwrite64({:?}, {:?}, {:?}, {:?})", fd, buf, count, offset); + this.write(fd, buf, count, Some(offset), dest)?; + } + "lseek64" => { + 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, + )?; + let fd = this.read_scalar(fd)?.to_i32()?; + let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; + let whence = this.read_scalar(whence)?.to_i32()?; + this.lseek64(fd, offset, whence, dest)?; + } + "ftruncate64" => { + let [fd, length] = this.check_shim_sig( + shim_sig!(extern "C" fn(i32, libc::off64_t) -> i32), + link_name, + abi, + args, + )?; + let fd = this.read_scalar(fd)?.to_i32()?; + let length = this.read_scalar(length)?.to_int(length.layout.size)?; + let result = this.ftruncate64(fd, length)?; + this.write_scalar(result, dest)?; + } + "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, + )?; + + let fd = this.read_scalar(fd)?.to_i32()?; + let offset = this.read_scalar(offset)?.to_i64()?; + let len = this.read_scalar(len)?.to_i64()?; + + let result = this.posix_fallocate(fd, offset, len)?; + this.write_scalar(result, dest)?; + } "readdir64" => { let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.readdir64("dirent64", dirp)?; diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index 6e1b554afda6..ed22457ec01a 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -46,12 +46,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.close(result)?; this.write_scalar(result, dest)?; } - "stat" | "stat64" | "stat$INODE64" => { + "stat" | "stat$INODE64" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.macos_fbsd_solarish_stat(path, buf)?; this.write_scalar(result, dest)?; } - "lstat" | "lstat64" | "lstat$INODE64" => { + "lstat" | "lstat$INODE64" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.macos_fbsd_solarish_lstat(path, buf)?; this.write_scalar(result, 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 b5eca70c3bf0..ae7230877a71 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -90,12 +90,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // File related shims - "stat" | "stat64" => { + "stat" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.macos_fbsd_solarish_stat(path, buf)?; this.write_scalar(result, dest)?; } - "lstat" | "lstat64" => { + "lstat" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.macos_fbsd_solarish_lstat(path, buf)?; this.write_scalar(result, dest)?; diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs index 3a4ac2a1b3ee..99685d6d976b 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs @@ -38,7 +38,7 @@ fn main() { test_posix_fadvise(); #[cfg(not(target_os = "macos"))] test_posix_fallocate::(libc::posix_fallocate); - #[cfg(any(target_os = "linux", target_os = "android"))] + #[cfg(target_os = "linux")] test_posix_fallocate::(libc::posix_fallocate64); #[cfg(target_os = "linux")] test_sync_file_range(); From a2910ce5b494c211780d5ca296f99785082fae75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 5 Dec 2025 20:16:15 +0100 Subject: [PATCH 0360/3801] Update windows-gnullvm platform support doc --- .../src/platform-support/windows-gnullvm.md | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/doc/rustc/src/platform-support/windows-gnullvm.md b/src/doc/rustc/src/platform-support/windows-gnullvm.md index b469af015313..e5db656e89f7 100644 --- a/src/doc/rustc/src/platform-support/windows-gnullvm.md +++ b/src/doc/rustc/src/platform-support/windows-gnullvm.md @@ -2,9 +2,11 @@ **Tier: 2 (with host tools)** -Windows targets similar to `*-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of GCC/Binutils. +Windows targets similar to `*-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of +GCC/Binutils. Target triples available so far: + - `aarch64-pc-windows-gnullvm` - `i686-pc-windows-gnullvm` - `x86_64-pc-windows-gnullvm` @@ -16,10 +18,11 @@ Target triples available so far: ## Requirements -The easiest way to obtain these targets is cross-compilation, but native build from `x86_64-pc-windows-gnu` is possible with few hacks which I don't recommend. -Std support is expected to be on par with `*-windows-gnu`. +Building those targets requires an LLVM-based C toolchain, for example, [llvm-mingw][1] or [MSYS2][2] with CLANG* +environment. -Binaries for this target should be at least on par with `*-windows-gnu` in terms of requirements and functionality. +Binaries for this target should be at least on par with `*-windows-gnu` in terms of requirements and functionality, +except for implicit self-contained mode (explained in [the section below](#building-rust-programs)). Those targets follow Windows calling convention for `extern "C"`. @@ -27,37 +30,32 @@ Like with any other Windows target, created binaries are in PE format. ## Building the target -These targets can be easily cross-compiled -using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain or [MSYS2 CLANG*](https://www.msys2.org/docs/environments/) environments. -Just fill `[target.*]` sections for both build and resulting compiler and set installation prefix in `bootstrap.toml`. -Then run `./x.py install`. -In my case I had ran `./x.py install --host x86_64-pc-windows-gnullvm --target x86_64-pc-windows-gnullvm` inside MSYS2 MINGW64 shell -so `x86_64-pc-windows-gnu` was my build toolchain. - -Native bootstrapping is doable in two ways: -- cross-compile gnullvm host toolchain and use it as build toolchain for the next build, -- copy libunwind libraries and rename them to mimic libgcc like here: https://github.com/msys2/MINGW-packages/blob/68e640756df2df6df6afa60f025e3f936e7b977c/mingw-w64-rust/PKGBUILD#L108-L109, stage0 compiler will be mostly broken but good enough to build the next stage. - -The second option might stop working anytime, so it's not recommended. +Both native and cross-compilation builds are supported and function similarly to other Rust targets. ## Building Rust programs -Rust does ship a pre-compiled std library for those targets. -That means one can easily cross-compile for those targets from other hosts if C proper toolchain is installed. +Rust ships both std and host tools for those targets. That allows using them as both the host and the target. -Alternatively full toolchain can be built as described in the previous section. +When used as the host and building pure Rust programs, no additional C toolchain is required. +The only requirements are to install `rust-mingw` component and to set `rust-lld` as the linker. +Otherwise, you will need to install the C toolchain mentioned previously. +There is no automatic fallback to `rust-lld` when the C toolchain is missing yet, but it may be added in the future. ## Testing -Created binaries work fine on Windows or Wine using native hardware. Testing AArch64 on x86_64 is problematic though and requires spending some time with QEMU. -Most of x86_64 testsuite does pass when cross-compiling, -with exception for `rustdoc` and `ui-fulldeps` that fail with and error regarding a missing library, -they do pass in native builds though. -The only failing test is std's `process::tests::test_proc_thread_attributes` for unknown reason. +Created binaries work fine on Windows and Linux with Wine using native hardware. +Testing AArch64 on x86_64 is problematic, though, and requires launching a whole AArch64 system with QEMU. + +Most of the x86_64 testsuite does pass, but because it isn't run on CI, different failures are expected over time. ## Cross-compilation toolchains and C code -Compatible C code can be built with Clang's `aarch64-pc-windows-gnu`, `i686-pc-windows-gnullvm` and `x86_64-pc-windows-gnu` targets as long as LLVM-based C toolchains are used. -Those include: -- [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) -- [MSYS2 with CLANG* environment](https://www.msys2.org/docs/environments) +Compatible C code can be built with Clang's `aarch64-pc-windows-gnu`, `i686-pc-windows-gnullvm` and +`x86_64-pc-windows-gnu` targets as long as LLVM-based C toolchains are used. Those include: + +- [llvm-mingw][1] +- [MSYS2][2] with CLANG* environment + +[1]: https://github.com/mstorsjo/llvm-mingw + +[2]: https://www.msys2.org/docs/environments From 7ad3301e03ec73dec2b304826a84e2eae461e2fc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Dec 2025 13:57:59 +0100 Subject: [PATCH 0361/3801] show span when there is an error invoking a global ctor/dtor or the thread main fn --- src/tools/miri/README.md | 1 + src/tools/miri/src/concurrency/thread.rs | 23 +++++++--- src/tools/miri/src/diagnostics.rs | 21 ++++++++- src/tools/miri/src/helpers.rs | 26 +++++++++-- src/tools/miri/src/lib.rs | 1 + src/tools/miri/src/shims/global_ctor.rs | 9 ++-- src/tools/miri/src/shims/tls.rs | 45 ++++++++++--------- .../miri/src/shims/unix/foreign_items.rs | 5 ++- .../src/shims/unix/macos/foreign_items.rs | 7 ++- .../libc_pthread_create_too_few_args.rs | 2 +- .../libc_pthread_create_too_few_args.stderr | 8 +++- .../libc_pthread_create_too_many_args.rs | 2 +- .../libc_pthread_create_too_many_args.stderr | 8 +++- .../concurrency/tls_pthread_dtor_wrong_abi.rs | 21 +++++++++ .../tls_pthread_dtor_wrong_abi.stderr | 13 ++++++ .../tests/fail/shims/ctor_wrong_ret_type.rs | 2 +- .../fail/shims/ctor_wrong_ret_type.stderr | 12 ++++- .../fail/shims/macos_tlv_atexit_wrong_abi.rs | 18 ++++++++ .../shims/macos_tlv_atexit_wrong_abi.stderr | 13 ++++++ 19 files changed, 188 insertions(+), 49 deletions(-) create mode 100644 src/tools/miri/tests/fail-dep/concurrency/tls_pthread_dtor_wrong_abi.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/tls_pthread_dtor_wrong_abi.stderr create mode 100644 src/tools/miri/tests/fail/shims/macos_tlv_atexit_wrong_abi.rs create mode 100644 src/tools/miri/tests/fail/shims/macos_tlv_atexit_wrong_abi.stderr diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 1c6a2daa093d..32494141589a 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -624,6 +624,7 @@ Definite bugs found: * [Mockall reading uninitialized memory when mocking `std::io::Read::read`, even if all expectations are satisfied](https://github.com/asomers/mockall/issues/647) (caught by Miri running Tokio's test suite) * [`ReentrantLock` not correctly dealing with reuse of addresses for TLS storage of different threads](https://github.com/rust-lang/rust/pull/141248) * [Rare Deadlock in the thread (un)parking example code](https://github.com/rust-lang/rust/issues/145816) +* [`winit` registering a global constructor with the wrong ABI on Windows](https://github.com/rust-windowing/winit/issues/4435) Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment): diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index c7ae335d0479..5016e3b66ca6 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -14,7 +14,7 @@ use rustc_hir::def_id::DefId; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::Mutability; use rustc_middle::ty::layout::TyAndLayout; -use rustc_span::Span; +use rustc_span::{DUMMY_SP, Span}; use rustc_target::spec::Os; use crate::concurrency::GlobalDataRaceHandler; @@ -174,6 +174,10 @@ pub struct Thread<'tcx> { /// The virtual call stack. stack: Vec>>, + /// A span that explains where the thread (or more specifically, its current root + /// frame) "comes from". + pub(crate) origin_span: Span, + /// The function to call when the stack ran empty, to figure out what to do next. /// Conceptually, this is the interpreter implementation of the things that happen 'after' the /// Rust language entry point for this thread returns (usually implemented by the C or OS runtime). @@ -303,6 +307,7 @@ impl<'tcx> Thread<'tcx> { state: ThreadState::Enabled, thread_name: name.map(|name| Vec::from(name.as_bytes())), stack: Vec::new(), + origin_span: DUMMY_SP, top_user_relevant_frame: None, join_status: ThreadJoinStatus::Joinable, unwind_payloads: Vec::new(), @@ -318,6 +323,7 @@ impl VisitProvenance for Thread<'_> { unwind_payloads: panic_payload, last_error, stack, + origin_span: _, top_user_relevant_frame: _, state: _, thread_name: _, @@ -584,6 +590,10 @@ impl<'tcx> ThreadManager<'tcx> { &self.threads[self.active_thread] } + pub fn thread_ref(&self, thread_id: ThreadId) -> &Thread<'tcx> { + &self.threads[thread_id] + } + /// Mark the thread as detached, which means that no other thread will try /// to join it and the thread is responsible for cleaning up. /// @@ -704,8 +714,9 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { #[inline] fn run_on_stack_empty(&mut self) -> InterpResult<'tcx, Poll<()>> { let this = self.eval_context_mut(); - let mut callback = this - .active_thread_mut() + let active_thread = this.active_thread_mut(); + active_thread.origin_span = DUMMY_SP; // reset, the old value no longer applied + let mut callback = active_thread .on_stack_empty .take() .expect("`on_stack_empty` not set up, or already running"); @@ -891,11 +902,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); // Create the new thread + let current_span = this.machine.current_user_relevant_span(); let new_thread_id = this.machine.threads.create_thread({ let mut state = tls::TlsDtorsState::default(); Box::new(move |m| state.on_stack_empty(m)) }); - let current_span = this.machine.current_user_relevant_span(); match &mut this.machine.data_race { GlobalDataRaceHandler::None => {} GlobalDataRaceHandler::Vclocks(data_race) => @@ -934,12 +945,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // it. let ret_place = this.allocate(ret_layout, MiriMemoryKind::Machine.into())?; - this.call_function( + this.call_thread_root_function( instance, start_abi, &[func_arg], Some(&ret_place), - ReturnContinuation::Stop { cleanup: true }, + current_span, )?; // Restore the old active thread frame. diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 8e252d306b29..01f77f261d70 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -444,7 +444,11 @@ pub fn report_result<'tcx>( write!(primary_msg, "{}", format_interp_error(ecx.tcx.dcx(), res)).unwrap(); if labels.is_empty() { - labels.push(format!("{} occurred here", title.unwrap_or("error"))); + labels.push(format!( + "{} occurred {}", + title.unwrap_or("error"), + if stacktrace.is_empty() { "due to this code" } else { "here" } + )); } report_msg( @@ -552,7 +556,14 @@ pub fn report_msg<'tcx>( thread: Option, machine: &MiriMachine<'tcx>, ) { - let span = stacktrace.first().map_or(DUMMY_SP, |fi| fi.span); + let span = match stacktrace.first() { + Some(fi) => fi.span, + None => + match thread { + Some(thread_id) => machine.threads.thread_ref(thread_id).origin_span, + None => DUMMY_SP, + }, + }; let sess = machine.tcx.sess; let level = match diag_level { DiagLevel::Error => Level::Error, @@ -620,6 +631,12 @@ pub fn report_msg<'tcx>( err.note(format!("{frame_info} at {span}")); } } + } else if stacktrace.len() == 0 && !span.is_dummy() { + err.note(format!( + "this {} occurred while pushing a call frame onto an empty stack", + level.to_str() + )); + err.note("the span indicates which code caused the function to be called, but may not be the literal call site"); } err.emit(); diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 383a4e2ea4b0..75b7e9f5966f 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -472,6 +472,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) } + /// Call a function in an "empty" thread. + fn call_thread_root_function( + &mut self, + f: ty::Instance<'tcx>, + caller_abi: ExternAbi, + args: &[ImmTy<'tcx>], + dest: Option<&MPlaceTy<'tcx>>, + span: Span, + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + assert!(this.active_thread_stack().is_empty()); + assert!(this.active_thread_ref().origin_span.is_dummy()); + this.active_thread_mut().origin_span = span; + this.call_function(f, caller_abi, args, dest, ReturnContinuation::Stop { cleanup: true }) + } + /// Visits the memory covered by `place`, sensitive to freezing: the 2nd parameter /// of `action` will be true if this is frozen, false if this is in an `UnsafeCell`. /// The range is relative to `place`. @@ -995,11 +1011,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(()) } - /// Lookup an array of immediates from any linker sections matching the provided predicate. + /// Lookup an array of immediates from any linker sections matching the provided predicate, + /// with the spans of where they were found. fn lookup_link_section( &mut self, include_name: impl Fn(&str) -> bool, - ) -> InterpResult<'tcx, Vec>> { + ) -> InterpResult<'tcx, Vec<(ImmTy<'tcx>, Span)>> { let this = self.eval_context_mut(); let tcx = this.tcx.tcx; @@ -1012,6 +1029,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; if include_name(link_section.as_str()) { let instance = ty::Instance::mono(tcx, def_id); + let span = tcx.def_span(def_id); let const_val = this.eval_global(instance).unwrap_or_else(|err| { panic!( "failed to evaluate static in required link_section: {def_id:?}\n{err:?}" @@ -1019,12 +1037,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }); match const_val.layout.ty.kind() { ty::FnPtr(..) => { - array.push(this.read_immediate(&const_val)?); + array.push((this.read_immediate(&const_val)?, span)); } ty::Array(elem_ty, _) if matches!(elem_ty.kind(), ty::FnPtr(..)) => { let mut elems = this.project_array_fields(&const_val)?; while let Some((_idx, elem)) = elems.next(this)? { - array.push(this.read_immediate(&elem)?); + array.push((this.read_immediate(&elem)?, span)); } } _ => diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index b30395b738b1..fe501b8d7b30 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -39,6 +39,7 @@ clippy::needless_question_mark, clippy::needless_lifetimes, clippy::too_long_first_doc_paragraph, + clippy::len_zero, // We don't use translatable diagnostics rustc::diagnostic_outside_of_impl, // We are not implementing queries here so it's fine diff --git a/src/tools/miri/src/shims/global_ctor.rs b/src/tools/miri/src/shims/global_ctor.rs index c56251bbe63a..d3296e4445f7 100644 --- a/src/tools/miri/src/shims/global_ctor.rs +++ b/src/tools/miri/src/shims/global_ctor.rs @@ -3,6 +3,7 @@ use std::task::Poll; use rustc_abi::ExternAbi; +use rustc_span::Span; use rustc_target::spec::BinaryFormat; use crate::*; @@ -15,7 +16,7 @@ enum GlobalCtorStatePriv<'tcx> { #[default] Init, /// The list of constructor functions that we still have to call. - Ctors(Vec>), + Ctors(Vec<(ImmTy<'tcx>, Span)>), Done, } @@ -67,19 +68,19 @@ impl<'tcx> GlobalCtorState<'tcx> { break 'new_state Ctors(ctors); } Ctors(ctors) => { - if let Some(ctor) = ctors.pop() { + if let Some((ctor, span)) = ctors.pop() { let this = this.eval_context_mut(); let ctor = ctor.to_scalar().to_pointer(this)?; let thread_callback = this.get_ptr_fn(ctor)?.as_instance()?; // The signature of this function is `unsafe extern "C" fn()`. - this.call_function( + this.call_thread_root_function( thread_callback, ExternAbi::C { unwind: false }, &[], None, - ReturnContinuation::Stop { cleanup: true }, + span, )?; return interp_ok(Poll::Pending); // we stay in this state (but `ctors` got shorter) diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index 2159c41ab16c..3ecd9b1ead38 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -6,6 +6,7 @@ use std::task::Poll; use rustc_abi::{ExternAbi, HasDataLayout, Size}; use rustc_middle::ty; +use rustc_span::Span; use rustc_target::spec::Os; use crate::*; @@ -17,7 +18,7 @@ pub struct TlsEntry<'tcx> { /// The data for this key. None is used to represent NULL. /// (We normalize this early to avoid having to do a NULL-ptr-test each time we access the data.) data: BTreeMap, - dtor: Option>, + dtor: Option<(ty::Instance<'tcx>, Span)>, } #[derive(Default, Debug)] @@ -38,7 +39,7 @@ pub struct TlsData<'tcx> { /// On macOS, each thread holds a list of destructor functions with their /// respective data arguments. - macos_thread_dtors: BTreeMap, Scalar)>>, + macos_thread_dtors: BTreeMap, Scalar, Span)>>, } impl<'tcx> Default for TlsData<'tcx> { @@ -57,7 +58,7 @@ impl<'tcx> TlsData<'tcx> { #[expect(clippy::arithmetic_side_effects)] pub fn create_tls_key( &mut self, - dtor: Option>, + dtor: Option<(ty::Instance<'tcx>, Span)>, max_size: Size, ) -> InterpResult<'tcx, TlsKey> { let new_key = self.next_key; @@ -126,8 +127,9 @@ impl<'tcx> TlsData<'tcx> { thread: ThreadId, dtor: ty::Instance<'tcx>, data: Scalar, + span: Span, ) -> InterpResult<'tcx> { - self.macos_thread_dtors.entry(thread).or_default().push((dtor, data)); + self.macos_thread_dtors.entry(thread).or_default().push((dtor, data, span)); interp_ok(()) } @@ -154,7 +156,7 @@ impl<'tcx> TlsData<'tcx> { &mut self, key: Option, thread_id: ThreadId, - ) -> Option<(ty::Instance<'tcx>, Scalar, TlsKey)> { + ) -> Option<(ty::Instance<'tcx>, Scalar, TlsKey, Span)> { use std::ops::Bound::*; let thread_local = &mut self.keys; @@ -172,11 +174,10 @@ impl<'tcx> TlsData<'tcx> { for (&key, TlsEntry { data, dtor }) in thread_local.range_mut((start, Unbounded)) { match data.entry(thread_id) { BTreeEntry::Occupied(entry) => { - if let Some(dtor) = dtor { + if let Some((dtor, span)) = dtor { // Set TLS data to NULL, and call dtor with old value. let data_scalar = entry.remove(); - let ret = Some((*dtor, data_scalar, key)); - return ret; + return Some((*dtor, data_scalar, key, *span)); } } BTreeEntry::Vacant(_) => {} @@ -205,7 +206,7 @@ impl VisitProvenance for TlsData<'_> { for scalar in keys.values().flat_map(|v| v.data.values()) { scalar.visit_provenance(visit); } - for (_, scalar) in macos_thread_dtors.values().flatten() { + for (_, scalar, _) in macos_thread_dtors.values().flatten() { scalar.visit_provenance(visit); } } @@ -222,7 +223,7 @@ enum TlsDtorsStatePriv<'tcx> { PthreadDtors(RunningDtorState), /// For Windows Dtors, we store the list of functions that we still have to call. /// These are functions from the magic `.CRT$XLB` linker section. - WindowsDtors(Vec>), + WindowsDtors(Vec<(ImmTy<'tcx>, Span)>), Done, } @@ -273,8 +274,8 @@ impl<'tcx> TlsDtorsState<'tcx> { } } WindowsDtors(dtors) => { - if let Some(dtor) = dtors.pop() { - this.schedule_windows_tls_dtor(dtor)?; + if let Some((dtor, span)) = dtors.pop() { + this.schedule_windows_tls_dtor(dtor, span)?; return interp_ok(Poll::Pending); // we stay in this state (but `dtors` got shorter) } else { // No more destructors to run. @@ -297,7 +298,7 @@ impl<'tcx> EvalContextPrivExt<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Schedule TLS destructors for Windows. /// On windows, TLS destructors are managed by std. - fn lookup_windows_tls_dtors(&mut self) -> InterpResult<'tcx, Vec>> { + fn lookup_windows_tls_dtors(&mut self) -> InterpResult<'tcx, Vec<(ImmTy<'tcx>, Span)>> { let this = self.eval_context_mut(); // Windows has a special magic linker section that is run on certain events. @@ -305,7 +306,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(this.lookup_link_section(|section| section == ".CRT$XLB")?) } - fn schedule_windows_tls_dtor(&mut self, dtor: ImmTy<'tcx>) -> InterpResult<'tcx> { + fn schedule_windows_tls_dtor(&mut self, dtor: ImmTy<'tcx>, span: Span) -> InterpResult<'tcx> { let this = self.eval_context_mut(); let dtor = dtor.to_scalar().to_pointer(this)?; @@ -320,12 +321,12 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // The signature of this function is `unsafe extern "system" fn(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID)`. // FIXME: `h` should be a handle to the current module and what `pv` should be is unknown // but both are ignored by std. - this.call_function( + this.call_thread_root_function( thread_callback, ExternAbi::System { unwind: false }, &[null_ptr.clone(), ImmTy::from_scalar(reason, this.machine.layouts.u32), null_ptr], None, - ReturnContinuation::Stop { cleanup: true }, + span, )?; interp_ok(()) } @@ -338,15 +339,15 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // registers another destructor, it will be run next. // See https://github.com/apple-oss-distributions/dyld/blob/d552c40cd1de105f0ec95008e0e0c0972de43456/dyld/DyldRuntimeState.cpp#L2277 let dtor = this.machine.tls.macos_thread_dtors.get_mut(&thread_id).and_then(Vec::pop); - if let Some((instance, data)) = dtor { + if let Some((instance, data, span)) = dtor { trace!("Running macos dtor {:?} on {:?} at {:?}", instance, data, thread_id); - this.call_function( + this.call_thread_root_function( instance, ExternAbi::C { unwind: false }, &[ImmTy::from_scalar(data, this.machine.layouts.mut_raw_ptr)], None, - ReturnContinuation::Stop { cleanup: true }, + span, )?; return interp_ok(Poll::Pending); @@ -370,7 +371,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // We ran each dtor once, start over from the beginning. None => this.machine.tls.fetch_tls_dtor(None, active_thread), }; - if let Some((instance, ptr, key)) = dtor { + if let Some((instance, ptr, key, span)) = dtor { state.last_key = Some(key); trace!("Running TLS dtor {:?} on {:?} at {:?}", instance, ptr, active_thread); assert!( @@ -378,12 +379,12 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "data can't be NULL when dtor is called!" ); - this.call_function( + this.call_thread_root_function( instance, ExternAbi::C { unwind: false }, &[ImmTy::from_scalar(ptr, this.machine.layouts.mut_raw_ptr)], None, - ReturnContinuation::Stop { cleanup: true }, + span, )?; return interp_ok(Poll::Pending); diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 378a8537fc73..64b8376ff4aa 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -634,7 +634,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Extract the function type out of the signature (that seems easier than constructing it ourselves). let dtor = if !this.ptr_is_null(dtor)? { - Some(this.get_ptr_fn(dtor)?.as_instance()?) + Some(( + this.get_ptr_fn(dtor)?.as_instance()?, + this.machine.current_user_relevant_span(), + )) } else { None }; diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index ed22457ec01a..dd7b95bdc82b 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -158,7 +158,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let dtor = this.get_ptr_fn(dtor)?.as_instance()?; let data = this.read_scalar(data)?; let active_thread = this.active_thread(); - this.machine.tls.add_macos_thread_dtor(active_thread, dtor, data)?; + this.machine.tls.add_macos_thread_dtor( + active_thread, + dtor, + data, + this.machine.current_user_relevant_span(), + )?; } // Querying system information diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs index 520bc9572f86..6fec6500cc96 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs @@ -1,5 +1,4 @@ //@ignore-target: windows # No pthreads on Windows -//~^ERROR: calling a function with more arguments than it expected //! The thread function must have exactly one argument. @@ -17,6 +16,7 @@ fn main() { mem::transmute(thread_start); assert_eq!( libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), + //~^ERROR: calling a function with more arguments than it expected 0 ); assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr index 4d5a80c828cd..fef91e85470d 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr @@ -1,9 +1,13 @@ error: Undefined Behavior: calling a function with more arguments than it expected + --> tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs:LL:CC + | +LL | libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred due to this code | - = note: Undefined Behavior occurred here - = note: (no span available) = 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 + = note: this error occurred while pushing a call frame onto an empty stack + = note: the span indicates which code caused the function to be called, but may not be the literal call site error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs index 92d8a765e511..cb55b0f92ee6 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs @@ -1,5 +1,4 @@ //@ignore-target: windows # No pthreads on Windows -//~^ERROR: calling a function with fewer arguments than it requires //! The thread function must have exactly one argument. @@ -17,6 +16,7 @@ fn main() { mem::transmute(thread_start); assert_eq!( libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), + //~^ERROR: calling a function with fewer arguments than it requires 0 ); assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr index 1bc79411197c..4d70576d784c 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr @@ -1,9 +1,13 @@ error: Undefined Behavior: calling a function with fewer arguments than it requires + --> tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs:LL:CC + | +LL | libc::pthread_create(&mut native, ptr::null(), thread_start, ptr::null_mut()), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred due to this code | - = note: Undefined Behavior occurred here - = note: (no span available) = 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 + = note: this error occurred while pushing a call frame onto an empty stack + = note: the span indicates which code caused the function to be called, but may not be the literal call site error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/concurrency/tls_pthread_dtor_wrong_abi.rs b/src/tools/miri/tests/fail-dep/concurrency/tls_pthread_dtor_wrong_abi.rs new file mode 100644 index 000000000000..b5eec2db201c --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/tls_pthread_dtor_wrong_abi.rs @@ -0,0 +1,21 @@ +//@ignore-target: windows # No pthreads on Windows + +use std::{mem, ptr}; + +pub type Key = libc::pthread_key_t; + +pub unsafe fn create(dtor: unsafe fn(*mut u8)) -> Key { + let mut key = 0; + assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0); + //~^ERROR: calling a function with calling convention "Rust" + key +} + +unsafe fn dtor(_ptr: *mut u8) {} + +fn main() { + unsafe { + let key = create(dtor); + libc::pthread_setspecific(key, ptr::without_provenance(1)); + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/tls_pthread_dtor_wrong_abi.stderr b/src/tools/miri/tests/fail-dep/concurrency/tls_pthread_dtor_wrong_abi.stderr new file mode 100644 index 000000000000..32e92319cdf3 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/tls_pthread_dtor_wrong_abi.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: calling a function with calling convention "Rust" using calling convention "C" + --> tests/fail-dep/concurrency/tls_pthread_dtor_wrong_abi.rs:LL:CC + | +LL | assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred due to this code + | + = 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 + = note: this error occurred while pushing a call frame onto an empty stack + = note: the span indicates which code caused the function to be called, but may not be the literal call site + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.rs b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.rs index 1e10f682e71e..3629e4387e7f 100644 --- a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.rs +++ b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.rs @@ -1,5 +1,4 @@ unsafe extern "C" fn ctor() -> i32 { - //~^ERROR: calling a function with return type i32 passing return place of type () 0 } @@ -31,6 +30,7 @@ macro_rules! ctor { )] #[used] static $ident: unsafe extern "C" fn() -> i32 = $ctor; + //~^ERROR: calling a function with return type i32 passing return place of type () }; } diff --git a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr index 68c56044be88..1b4cd23e41a8 100644 --- a/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr +++ b/src/tools/miri/tests/fail/shims/ctor_wrong_ret_type.stderr @@ -1,11 +1,19 @@ error: Undefined Behavior: calling a function with return type i32 passing return place of type () + --> tests/fail/shims/ctor_wrong_ret_type.rs:LL:CC + | +LL | static $ident: unsafe extern "C" fn() -> i32 = $ctor; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred due to this code +... +LL | ctor! { CTOR = ctor } + | --------------------- in this macro invocation | - = note: Undefined Behavior occurred here - = note: (no span available) = 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 = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets = help: if you think this code should be accepted anyway, please report an issue with Miri + = note: this error occurred while pushing a call frame onto an empty stack + = note: the span indicates which code caused the function to be called, but may not be the literal call site + = note: this error originates in the macro `ctor` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/shims/macos_tlv_atexit_wrong_abi.rs b/src/tools/miri/tests/fail/shims/macos_tlv_atexit_wrong_abi.rs new file mode 100644 index 000000000000..5d5cb749f896 --- /dev/null +++ b/src/tools/miri/tests/fail/shims/macos_tlv_atexit_wrong_abi.rs @@ -0,0 +1,18 @@ +//@only-target: darwin + +use std::{mem, ptr}; + +extern "C" { + fn _tlv_atexit(dtor: unsafe extern "C" fn(*mut u8), arg: *mut u8); +} + +fn register(dtor: unsafe fn(*mut u8)) { + unsafe { + _tlv_atexit(mem::transmute(dtor), ptr::null_mut()); + //~^ERROR: calling a function with calling convention "Rust" + } +} + +fn main() { + register(|_| ()); +} diff --git a/src/tools/miri/tests/fail/shims/macos_tlv_atexit_wrong_abi.stderr b/src/tools/miri/tests/fail/shims/macos_tlv_atexit_wrong_abi.stderr new file mode 100644 index 000000000000..0fc87f13f16d --- /dev/null +++ b/src/tools/miri/tests/fail/shims/macos_tlv_atexit_wrong_abi.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: calling a function with calling convention "Rust" using calling convention "C" + --> tests/fail/shims/macos_tlv_atexit_wrong_abi.rs:LL:CC + | +LL | _tlv_atexit(mem::transmute(dtor), ptr::null_mut()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred due to this code + | + = 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 + = note: this error occurred while pushing a call frame onto an empty stack + = note: the span indicates which code caused the function to be called, but may not be the literal call site + +error: aborting due to 1 previous error + From a9e56e4b7aaadf9095032ddd410a8b9a35e2d744 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Dec 2025 15:23:19 +0100 Subject: [PATCH 0362/3801] fix empty stack in deadlock error message --- src/tools/miri/src/concurrency/thread.rs | 2 +- src/tools/miri/src/diagnostics.rs | 76 ++++++++++--------- src/tools/miri/src/shims/unix/sync.rs | 2 +- .../libc_pthread_mutex_deadlock.stderr | 14 ++-- .../libc_pthread_mutex_normal_reentrant.rs | 2 +- ...libc_pthread_mutex_normal_reentrant.stderr | 2 +- ...k_read_write_deadlock_single_thread.stderr | 2 +- ..._pthread_rwlock_write_read_deadlock.stderr | 14 ++-- ...k_write_read_deadlock_single_thread.stderr | 2 +- ...pthread_rwlock_write_write_deadlock.stderr | 14 ++-- ..._write_write_deadlock_single_thread.stderr | 2 +- .../concurrency/windows_join_main.stderr | 18 ++--- .../concurrency/windows_join_self.stderr | 14 ++-- .../libc/eventfd_block_read_twice.stderr | 4 +- .../libc/eventfd_block_write_twice.stderr | 4 +- .../libc/fcntl_fsetfl_while_blocking.rs | 1 - .../libc/fcntl_fsetfl_while_blocking.stderr | 9 +-- .../libc/libc_epoll_block_two_thread.stderr | 4 +- .../socketpair-close-while-blocked.stderr | 4 +- .../libc/socketpair_block_read_twice.stderr | 4 +- .../libc/socketpair_block_write_twice.stderr | 4 +- .../concurrency/mutex-leak-move-deadlock.rs | 3 + .../mutex-leak-move-deadlock.stderr | 2 +- 23 files changed, 101 insertions(+), 102 deletions(-) diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index c7ae335d0479..feed70cb18fd 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -823,7 +823,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { // sleep until the first callback. interp_ok(SchedulingAction::Sleep(sleep_time)) } else { - throw_machine_stop!(TerminationInfo::Deadlock); + throw_machine_stop!(TerminationInfo::GlobalDeadlock); } } } diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 8e252d306b29..a5505836da99 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -32,7 +32,10 @@ pub enum TerminationInfo { history: tree_diagnostics::HistoryData, }, Int2PtrWithStrictProvenance, - Deadlock, + /// All threads are blocked. + GlobalDeadlock, + /// Some thread discovered a deadlock condition (e.g. in a mutex with reentrancy checking). + LocalDeadlock, MultipleSymbolDefinitions { link_name: Symbol, first: SpanData, @@ -76,7 +79,8 @@ impl fmt::Display for TerminationInfo { ), StackedBorrowsUb { msg, .. } => write!(f, "{msg}"), TreeBorrowsUb { title, .. } => write!(f, "{title}"), - Deadlock => write!(f, "the evaluated program deadlocked"), + GlobalDeadlock => write!(f, "the evaluated program deadlocked"), + LocalDeadlock => write!(f, "a thread deadlocked"), MultipleSymbolDefinitions { link_name, .. } => write!(f, "multiple definitions of symbol `{link_name}`"), SymbolShimClashing { link_name, .. } => @@ -245,10 +249,39 @@ pub fn report_result<'tcx>( Some("unsupported operation"), StackedBorrowsUb { .. } | TreeBorrowsUb { .. } | DataRace { .. } => Some("Undefined Behavior"), - Deadlock => { + LocalDeadlock => { labels.push(format!("this thread got stuck here")); None } + GlobalDeadlock => { + // Global deadlocks are reported differently: just show all blocked threads. + // The "active" thread might actually be terminated, so we ignore it. + let mut any_pruned = false; + for (thread, stack) in ecx.machine.threads.all_blocked_stacks() { + let stacktrace = Frame::generate_stacktrace_from_stack(stack); + let (stacktrace, was_pruned) = prune_stacktrace(stacktrace, &ecx.machine); + any_pruned |= was_pruned; + report_msg( + DiagLevel::Error, + format!("the evaluated program deadlocked"), + vec![format!( + "thread `{}` got stuck here", + ecx.machine.threads.get_thread_display_name(thread) + )], + vec![], + vec![], + &stacktrace, + Some(thread), + &ecx.machine, + ) + } + if any_pruned { + ecx.tcx.dcx().note( + "some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace" + ); + } + return None; + } MultipleSymbolDefinitions { .. } | SymbolShimClashing { .. } => None, }; #[rustfmt::skip] @@ -408,9 +441,7 @@ pub fn report_result<'tcx>( }; let stacktrace = ecx.generate_stacktrace(); - let (stacktrace, mut any_pruned) = prune_stacktrace(stacktrace, &ecx.machine); - - let mut show_all_threads = false; + let (stacktrace, pruned) = prune_stacktrace(stacktrace, &ecx.machine); // We want to dump the allocation if this is `InvalidUninitBytes`. // Since `format_interp_error` consumes `e`, we compute the outut early. @@ -425,15 +456,6 @@ pub fn report_result<'tcx>( .unwrap(); writeln!(extra, "{:?}", ecx.dump_alloc(*alloc_id)).unwrap(); } - MachineStop(info) => { - let info = info.downcast_ref::().expect("invalid MachineStop payload"); - match info { - TerminationInfo::Deadlock => { - show_all_threads = true; - } - _ => {} - } - } _ => {} } @@ -460,28 +482,8 @@ pub fn report_result<'tcx>( eprint!("{extra}"); // newlines are already in the string - if show_all_threads { - for (thread, stack) in ecx.machine.threads.all_blocked_stacks() { - if thread != ecx.active_thread() { - let stacktrace = Frame::generate_stacktrace_from_stack(stack); - let (stacktrace, was_pruned) = prune_stacktrace(stacktrace, &ecx.machine); - any_pruned |= was_pruned; - report_msg( - DiagLevel::Error, - format!("the evaluated program deadlocked"), - vec![format!("this thread got stuck here")], - vec![], - vec![], - &stacktrace, - Some(thread), - &ecx.machine, - ) - } - } - } - // Include a note like `std` does when we omit frames from a backtrace - if any_pruned { + if pruned { ecx.tcx.dcx().note( "some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace", ); @@ -563,7 +565,7 @@ pub fn report_msg<'tcx>( err.span(span); // Show main message. - if span != DUMMY_SP { + if !span.is_dummy() { for line in span_msg { err.span_label(span, line); } diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index 39014f34c897..39ad66041820 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -538,7 +538,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_ub_format!( "trying to acquire default mutex already locked by the current thread" ), - MutexKind::Normal => throw_machine_stop!(TerminationInfo::Deadlock), + MutexKind::Normal => throw_machine_stop!(TerminationInfo::LocalDeadlock), MutexKind::ErrorCheck => this.eval_libc_i32("EDEADLK"), MutexKind::Recursive => { this.mutex_lock(&mutex.mutex_ref)?; diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr index c80cbf835a38..e3b0036c9aa9 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr @@ -1,14 +1,8 @@ -error: the evaluated program deadlocked - --> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC - | -LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); - | ^ this thread got stuck here - error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -23,6 +17,12 @@ LL | | }) LL | | .join() | |_______________^ +error: the evaluated program deadlocked + --> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC + | +LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); + | ^ thread `unnamed-ID` got stuck here + note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to 2 previous errors diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.rs index b88257992a5c..3008705ebfde 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.rs @@ -12,6 +12,6 @@ fn main() { assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); // A "normal" mutex properly tries to acquire the lock even if its is already held // by the current thread -- and then we deadlock. - libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR: the evaluated program deadlocked + libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR: a thread deadlocked } } diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr index c611d0ff7b00..782322d5c32b 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr @@ -1,4 +1,4 @@ -error: the evaluated program deadlocked +error: a thread deadlocked --> tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.rs:LL:CC | LL | libc::pthread_mutex_lock(&mut mutex as *mut _); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr index 763a52963a4d..ea8cbcada970 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.rs:LL:CC | LL | libc::pthread_rwlock_wrlock(rw.get()); - | ^ this thread got stuck here + | ^ thread `main` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr index f174d387f76e..255632870efc 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr @@ -1,14 +1,8 @@ -error: the evaluated program deadlocked - --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC - | -LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); - | ^ this thread got stuck here - error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -23,6 +17,12 @@ LL | | }) LL | | .join() | |_______________^ +error: the evaluated program deadlocked + --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC + | +LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); + | ^ thread `unnamed-ID` got stuck here + note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to 2 previous errors diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr index 4c8d3fddb97c..0208a5bae4f5 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.rs:LL:CC | LL | libc::pthread_rwlock_rdlock(rw.get()); - | ^ this thread got stuck here + | ^ thread `main` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr index 06b8e1246e01..6891b989d05f 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr @@ -1,14 +1,8 @@ -error: the evaluated program deadlocked - --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC - | -LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); - | ^ this thread got stuck here - error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -23,6 +17,12 @@ LL | | }) LL | | .join() | |_______________^ +error: the evaluated program deadlocked + --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC + | +LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); + | ^ thread `unnamed-ID` got stuck here + note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to 2 previous errors diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr index e6a4b2814d83..314e60b02360 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.rs:LL:CC | LL | libc::pthread_rwlock_wrlock(rw.get()); - | ^ this thread got stuck here + | ^ thread `main` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr index 0ab89676db37..d9cc93d0fc49 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr @@ -1,16 +1,8 @@ -error: the evaluated program deadlocked - --> tests/fail-dep/concurrency/windows_join_main.rs:LL:CC - | -LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this thread got stuck here - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) - error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -26,6 +18,14 @@ LL | | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_O LL | | .join() | |___________^ +error: the evaluated program deadlocked + --> tests/fail-dep/concurrency/windows_join_main.rs:LL:CC + | +LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread `unnamed-ID` got stuck here + | + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to 2 previous errors diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr index bdfab966d6d9..f5515983da2b 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr @@ -1,14 +1,8 @@ -error: the evaluated program deadlocked - --> tests/fail-dep/concurrency/windows_join_self.rs:LL:CC - | -LL | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0); - | ^ this thread got stuck here - error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -26,6 +20,12 @@ LL | | }) LL | | .join() | |___________^ +error: the evaluated program deadlocked + --> tests/fail-dep/concurrency/windows_join_self.rs:LL:CC + | +LL | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0); + | ^ thread `unnamed-ID` got stuck here + note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to 2 previous errors diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr index 6253fe6d2c76..53ae7ea82bd9 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -18,7 +18,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC | LL | let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; - | ^ this thread got stuck here + | ^ thread `unnamed-ID` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr index aecc54c2fd88..62810f17be88 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -18,7 +18,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC | LL | libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() - | ^ this thread got stuck here + | ^ thread `unnamed-ID` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.rs b/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.rs index cfebb7c64351..c7a2c5b4d297 100644 --- a/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.rs +++ b/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.rs @@ -1,5 +1,4 @@ //@ignore-target: windows # Sockets/pipes are not implemented yet -//~^ ERROR: the evaluated program deadlocked //@compile-flags: -Zmiri-deterministic-concurrency use std::thread; diff --git a/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr b/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr index e451fdb9d19f..307762fb12c6 100644 --- a/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr @@ -1,15 +1,10 @@ -error: the evaluated program deadlocked - | - = note: this thread got stuck here - = note: (no span available) - error: the evaluated program deadlocked --> tests/fail-dep/libc/fcntl_fsetfl_while_blocking.rs:LL:CC | LL | let _res = unsafe { libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr index 14390d632738..dba12d190317 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -18,7 +18,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC | LL | check_epoll_wait::(epfd, &expected, -1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this thread got stuck here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread `unnamed-ID` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr index 97b5df7fb17f..a7c660e1adcc 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -18,7 +18,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair-close-while-blocked.rs:LL:CC | LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - | ^ this thread got stuck here + | ^ thread `unnamed-ID` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr index 38db735e9b4d..faab75f7840b 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -18,7 +18,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC | LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - | ^ this thread got stuck here + | ^ thread `unnamed-ID` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr index a2f1c67b5efc..9f95d98beb6f 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ this thread got stuck here + | ^ thread `main` got stuck here | = note: BACKTRACE: = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC @@ -18,7 +18,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC | LL | let res = unsafe { libc::write(fds[0], data.as_ptr() as *const libc::c_void, data.len()) }; - | ^ this thread got stuck here + | ^ thread `unnamed-ID` got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs index b996fcaf45df..9c73f6c03edd 100644 --- a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs +++ b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs @@ -3,6 +3,9 @@ //@normalize-stderr-test: "LL \| .*" -> "LL | $$CODE" //@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "\n *= note:.*" -> "" +// On macOS we use chekced pthread mutexes which changes the error +//@normalize-stderr-test: "this thread got stuck here" -> "thread `main` got stuck here" +//@normalize-stderr-test: "a thread deadlocked" -> "the evaluated program deadlocked" use std::mem; use std::sync::Mutex; diff --git a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr index cc487c62d08d..7784132a54ce 100644 --- a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr +++ b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> RUSTLIB/std/$FILE:LL:CC | LL | $CODE - | ^ this thread got stuck here + | ^ thread `main` got stuck here | note: inside `main` --> tests/fail/concurrency/mutex-leak-move-deadlock.rs:LL:CC From a3a041da11202dd4c5fbbac4dbc1461e4c783f90 Mon Sep 17 00:00:00 2001 From: Justin Tracey Date: Sat, 6 Dec 2025 11:16:14 -0500 Subject: [PATCH 0363/3801] rustdoc book: mention inner doc attribute --- src/doc/rustdoc/src/write-documentation/the-doc-attribute.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md index 4d7f1a4aafc9..3af53fa58e18 100644 --- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md +++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md @@ -4,8 +4,8 @@ The `#[doc]` attribute lets you control various aspects of how `rustdoc` does its job. The most basic function of `#[doc]` is to handle the actual documentation -text. That is, `///` is syntax sugar for `#[doc]`. This means that these two -are the same: +text. That is, `///` is syntax sugar for `#[doc]` (as is `//!` for `#![doc]`). +This means that these two are the same: ```rust,no_run /// This is a doc comment. From c788c7cb77509b8704da3174fe7c7ecad041f3ad Mon Sep 17 00:00:00 2001 From: irelaxcn Date: Sun, 7 Dec 2025 00:41:43 +0800 Subject: [PATCH 0364/3801] Fix `map_entry` FP when it would cause `MutexGuard` to be held across an await point. --- clippy_lints/src/entry.rs | 48 ++++++++++++++++++++++++++++++--------- tests/ui/entry.fixed | 24 ++++++++++++++++++++ tests/ui/entry.rs | 24 ++++++++++++++++++++ 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index a5ec6777b434..bdfe2e49e66e 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -3,11 +3,12 @@ use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_appl use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_expr; use clippy_utils::{ - SpanlessEq, can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified, - peel_hir_expr_while, + SpanlessEq, can_move_expr_to_closure_no_visit, desugar_await, higher, is_expr_final_block_expr, + is_expr_used_or_unified, paths, peel_hir_expr_while, }; use core::fmt::{self, Write}; use rustc_errors::Applicability; +use rustc_hir::def_id::DefId; use rustc_hir::hir_id::HirIdSet; use rustc_hir::intravisit::{Visitor, walk_body, walk_expr}; use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp}; @@ -382,6 +383,8 @@ struct InsertSearcher<'cx, 'tcx> { loops: Vec, /// Local variables created in the expression. These don't need to be captured. locals: HirIdSet, + /// Whether the map is a non-async-aware `MutexGuard`. + map_is_mutex_guard: bool, } impl<'tcx> InsertSearcher<'_, 'tcx> { /// Visit the expression as a branch in control flow. Multiple insert calls can be used, but @@ -524,15 +527,22 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> { ExprKind::If(cond_expr, then_expr, Some(else_expr)) => { self.is_single_insert = false; self.visit_non_tail_expr(cond_expr); - // Each branch may contain it's own insert expression. + // Each branch may contain its own insert expression. let mut is_map_used = self.visit_cond_arm(then_expr); is_map_used |= self.visit_cond_arm(else_expr); self.is_map_used = is_map_used; }, ExprKind::Match(scrutinee_expr, arms, _) => { + // If the map is a non-async-aware `MutexGuard` and + // `.await` expression appears alongside map insertion in the same `then` or `else` block, + // we cannot suggest using `entry()` because it would hold the lock across the await point, + // triggering `await_holding_lock` and risking deadlock. + if self.map_is_mutex_guard && desugar_await(expr).is_some() { + self.can_use_entry = false; + } self.is_single_insert = false; self.visit_non_tail_expr(scrutinee_expr); - // Each branch may contain it's own insert expression. + // Each branch may contain its own insert expression. let mut is_map_used = self.is_map_used; for arm in arms { self.visit_pat(arm.pat); @@ -725,16 +735,32 @@ fn find_insert_calls<'tcx>( edits: Vec::new(), loops: Vec::new(), locals: HirIdSet::default(), + map_is_mutex_guard: false, }; + // Check if the map is a non-async-aware `MutexGuard` + if let rustc_middle::ty::Adt(adt, _) = cx.typeck_results().expr_ty(contains_expr.map).kind() + && is_mutex_guard(cx, adt.did()) + { + s.map_is_mutex_guard = true; + } + s.visit_expr(expr); - let allow_insert_closure = s.allow_insert_closure; - let is_single_insert = s.is_single_insert; + if !s.can_use_entry { + return None; + } + let is_key_used_and_no_copy = s.is_key_used && !is_copy(cx, cx.typeck_results().expr_ty(contains_expr.key)); - let edits = s.edits; - s.can_use_entry.then_some(InsertSearchResults { - edits, - allow_insert_closure, - is_single_insert, + Some(InsertSearchResults { + edits: s.edits, + allow_insert_closure: s.allow_insert_closure, + is_single_insert: s.is_single_insert, is_key_used_and_no_copy, }) } + +fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool { + match cx.tcx.get_diagnostic_name(def_id) { + Some(name) => matches!(name, sym::MutexGuard | sym::RwLockReadGuard | sym::RwLockWriteGuard), + None => paths::PARKING_LOT_GUARDS.iter().any(|guard| guard.matches(cx, def_id)), + } +} diff --git a/tests/ui/entry.fixed b/tests/ui/entry.fixed index f2df9f0204ea..1e36ca4f1f09 100644 --- a/tests/ui/entry.fixed +++ b/tests/ui/entry.fixed @@ -248,4 +248,28 @@ mod issue14449 { } } +// Don't suggest when it would cause `MutexGuard` to be held across an await point. +mod issue_16173 { + use std::collections::HashMap; + use std::sync::Mutex; + + async fn f() {} + + async fn foo() { + let mu_map = Mutex::new(HashMap::new()); + if !mu_map.lock().unwrap().contains_key(&0) { + f().await; + mu_map.lock().unwrap().insert(0, 0); + } + + if mu_map.lock().unwrap().contains_key(&1) { + todo!(); + } else { + mu_map.lock().unwrap().insert(1, 42); + todo!(); + f().await; + } + } +} + fn main() {} diff --git a/tests/ui/entry.rs b/tests/ui/entry.rs index 166eea417ac2..b3da0ef3ffd6 100644 --- a/tests/ui/entry.rs +++ b/tests/ui/entry.rs @@ -254,4 +254,28 @@ mod issue14449 { } } +// Don't suggest when it would cause `MutexGuard` to be held across an await point. +mod issue_16173 { + use std::collections::HashMap; + use std::sync::Mutex; + + async fn f() {} + + async fn foo() { + let mu_map = Mutex::new(HashMap::new()); + if !mu_map.lock().unwrap().contains_key(&0) { + f().await; + mu_map.lock().unwrap().insert(0, 0); + } + + if mu_map.lock().unwrap().contains_key(&1) { + todo!(); + } else { + mu_map.lock().unwrap().insert(1, 42); + todo!(); + f().await; + } + } +} + fn main() {} From bd2d4eb79e459487c80a98ccd7475253652e7b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pu=C4=8Dil?= Date: Sat, 6 Dec 2025 18:09:29 +0100 Subject: [PATCH 0365/3801] rustc book: fix `*-pc-windows-msvc` link label in sidebar As far as I know, `*-unknown-windows-msvc` is not a thing. At least if I search for "unknown-windows-msvc" in the entire [rust-lang](https://github.com/rust-lang) organization (https://github.com/search?q=org%3Arust-lang+%22unknown-windows-msvc%22++&type=code&state=open), it gives only this occurrence and 3 other occurrences in https://github.com/rust-lang/lld, which was archived in 2019. I believe `*-pc-windows-msvc` is the correct replacement because that is the name of the page the link points to: https://github.com/rust-lang/rust/blob/ba86c0460b0233319e01fd789a42a7276eade805/src/doc/rustc/src/platform-support/windows-msvc.md?plain=1#L1 --- src/doc/rustc/src/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 3da3571c2718..832b5a69d47c 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -130,7 +130,7 @@ - [\*-unknown-openbsd](platform-support/openbsd.md) - [\*-unknown-redox](platform-support/redox.md) - [\*-unknown-uefi](platform-support/unknown-uefi.md) - - [\*-unknown-windows-msvc](platform-support/windows-msvc.md) + - [\*-pc-windows-msvc](platform-support/windows-msvc.md) - [\*-uwp-windows-msvc](platform-support/uwp-windows-msvc.md) - [\*-wrs-vxworks](platform-support/vxworks.md) - [wasm32-wasip1](platform-support/wasm32-wasip1.md) From 234df83fe309fc4c3a5c3c87393110b1a5c8274d Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 28 Sep 2025 18:12:17 -0400 Subject: [PATCH 0366/3801] Add warn-by-default lint for visibility on `const _` declarations Add a warn-by-default `unused_visibility` lint for visibility qualifiers on `const _` declarations - e.g. `pub const _: () = ();`. These have no effect. --- .../rustc_ast_passes/src/ast_validation.rs | 15 +++++++++++-- compiler/rustc_lint/messages.ftl | 3 +++ compiler/rustc_lint/src/early/diagnostics.rs | 3 +++ compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_lint/src/lints.rs | 7 +++++++ compiler/rustc_lint_defs/src/builtin.rs | 21 +++++++++++++++++++ compiler/rustc_lint_defs/src/lib.rs | 1 + .../absolute_paths.no_short.stderr | 6 +++--- .../ui-toml/absolute_paths/absolute_paths.rs | 2 +- tests/ui/consts/promoted_const_call3.rs | 4 ++-- tests/ui/consts/ptr_is_null.rs | 10 ++++----- ...-dont-override-forbid-in-same-scope.stderr | 18 ++++++++++++++++ tests/ui/lint/outer-forbid.stderr | 18 ++++++++++++++++ tests/ui/lint/unused-visibilities.fixed | 12 +++++++++++ tests/ui/lint/unused-visibilities.rs | 12 +++++++++++ tests/ui/lint/unused-visibilities.stderr | 20 ++++++++++++++++++ tests/ui/traits/const-traits/call.rs | 2 +- 17 files changed, 141 insertions(+), 14 deletions(-) create mode 100644 tests/ui/lint/unused-visibilities.fixed create mode 100644 tests/ui/lint/unused-visibilities.rs create mode 100644 tests/ui/lint/unused-visibilities.stderr diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 2790916891a1..06a35e691929 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -33,7 +33,7 @@ use rustc_session::Session; use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::{ DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN, - PATTERNS_IN_FNS_WITHOUT_BODY, + PATTERNS_IN_FNS_WITHOUT_BODY, UNUSED_VISIBILITIES, }; use rustc_session::parse::feature_err; use rustc_span::{Ident, Span, kw, sym}; @@ -1339,7 +1339,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } }); } - ItemKind::Const(box ConstItem { defaultness, rhs, .. }) => { + ItemKind::Const(box ConstItem { defaultness, ident, rhs, .. }) => { self.check_defaultness(item.span, *defaultness); if rhs.is_none() { self.dcx().emit_err(errors::ConstWithoutBody { @@ -1347,6 +1347,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> { replace_span: self.ending_semi_or_hi(item.span), }); } + if ident.name == kw::Underscore + && !matches!(item.vis.kind, VisibilityKind::Inherited) + { + self.lint_buffer.buffer_lint( + UNUSED_VISIBILITIES, + item.id, + item.vis.span, + BuiltinLintDiag::UnusedVisibility(item.vis.span), + ) + } + visit::walk_item(self, item); } ItemKind::Static(box StaticItem { expr, safety, .. }) => { diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 1bcdda96e13a..fac26b52176d 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -978,6 +978,9 @@ lint_unused_op = unused {$op} that must be used lint_unused_result = unused result of type `{$ty}` +lint_unused_visibilities = visibility qualifiers have no effect on `const _` declarations + .suggestion = remove the qualifier + lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result lint_useless_ptr_null_checks_fn_ptr = function pointers are not nullable, so checking them for null will always return false diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index b654bc848ecf..ff364e5f814a 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -302,6 +302,9 @@ pub fn decorate_builtin_lint( BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag) } + BuiltinLintDiag::UnusedVisibility(span) => { + lints::UnusedVisibility { span }.decorate_lint(diag) + } BuiltinLintDiag::AttributeLint(kind) => decorate_attribute_lint(sess, tcx, &kind, diag), } } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index a5f9eabf89c4..4e7a3e405176 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -291,6 +291,7 @@ fn register_builtins(store: &mut LintStore) { "unused", UNUSED_IMPORTS, UNUSED_VARIABLES, + UNUSED_VISIBILITIES, UNUSED_ASSIGNMENTS, DEAD_CODE, UNUSED_MUT, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 4f28d503af3c..a10a5e7d5f26 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3191,3 +3191,10 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { #[suggestion_part(code = ")")] pub right: Span, } + +#[derive(LintDiagnostic)] +#[diag(lint_unused_visibilities)] +pub(crate) struct UnusedVisibility { + #[suggestion(style = "short", code = "", applicability = "machine-applicable")] + pub span: Span, +} diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 2f0333160f52..e8bd8f8f7099 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -143,6 +143,7 @@ declare_lint_pass! { UNUSED_QUALIFICATIONS, UNUSED_UNSAFE, UNUSED_VARIABLES, + UNUSED_VISIBILITIES, USELESS_DEPRECATED, VARARGS_WITHOUT_PATTERN, WARNINGS, @@ -693,6 +694,26 @@ declare_lint! { "detect variables which are not used in any way" } +declare_lint! { + /// The `unused_visibilities` lint detects visibility qualifiers (like `pub`) + /// on a `const _` item. + /// + /// ### Example + /// + /// ```rust + /// pub const _: () = {}; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// These qualifiers have no effect. + pub UNUSED_VISIBILITIES, + Warn, + "detect visibility qualifiers on `const _` items" +} + declare_lint! { /// The `unused_assignments` lint detects assignments that will never be read. /// diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 3c6e7d04a29d..19ba27a27eaf 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -696,6 +696,7 @@ pub enum BuiltinLintDiag { extern_crate: Symbol, local_crate: Symbol, }, + UnusedVisibility(Span), AttributeLint(AttributeLintKind), } diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr index 70d71f6c4ea1..c94b7777f3e9 100644 --- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr @@ -71,10 +71,10 @@ LL | impl core::fmt::Display for X | ^^^^^^^^^^^^^^^^^^ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:14 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:10 | -LL | pub const _: crate::S = { - | ^^^^^^^^ +LL | const _: crate::S = { + | ^^^^^^^^ error: consider bringing this path into scope with the `use` keyword --> tests/ui-toml/absolute_paths/absolute_paths.rs:114:9 diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs index c024f2f513ce..a3982b8f6540 100644 --- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs @@ -110,7 +110,7 @@ mod m1 { } //~[no_short]v absolute_paths -pub const _: crate::S = { +const _: crate::S = { let crate::S = m1::S; //~[no_short] absolute_paths crate::m1::S diff --git a/tests/ui/consts/promoted_const_call3.rs b/tests/ui/consts/promoted_const_call3.rs index dc05a3b58442..82e9eac31d5c 100644 --- a/tests/ui/consts/promoted_const_call3.rs +++ b/tests/ui/consts/promoted_const_call3.rs @@ -4,12 +4,12 @@ pub const C: () = { //~^ ERROR: destructor of `String` cannot be evaluated at compile-time }; -pub const _: () = { +const _: () = { let _: &'static _ = &id(&String::new()); //~^ ERROR: destructor of `String` cannot be evaluated at compile-time }; -pub const _: () = { +const _: () = { let _: &'static _ = &std::mem::ManuallyDrop::new(String::new()); //~^ ERROR: temporary value dropped while borrowed }; diff --git a/tests/ui/consts/ptr_is_null.rs b/tests/ui/consts/ptr_is_null.rs index 8b41f5718e8d..9f8a1697fd70 100644 --- a/tests/ui/consts/ptr_is_null.rs +++ b/tests/ui/consts/ptr_is_null.rs @@ -5,12 +5,12 @@ const FOO: &usize = &42; -pub const _: () = assert!(!(FOO as *const usize).is_null()); +const _: () = assert!(!(FOO as *const usize).is_null()); -pub const _: () = assert!(!(42 as *const usize).is_null()); +const _: () = assert!(!(42 as *const usize).is_null()); -pub const _: () = assert!((0 as *const usize).is_null()); +const _: () = assert!((0 as *const usize).is_null()); -pub const _: () = assert!(std::ptr::null::().is_null()); +const _: () = assert!(std::ptr::null::().is_null()); -pub const _: () = assert!(!("foo" as *const str).is_null()); +const _: () = assert!(!("foo" as *const str).is_null()); diff --git a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr index 77c8d1eab584..506791fd1726 100644 --- a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr +++ b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr @@ -413,3 +413,21 @@ note: the lint level is defined here LL | #![forbid(forbidden_lint_groups)] | ^^^^^^^^^^^^^^^^^^^^^ +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/lint/outer-forbid.stderr b/tests/ui/lint/outer-forbid.stderr index 64a1077462ab..7810ca223f8a 100644 --- a/tests/ui/lint/outer-forbid.stderr +++ b/tests/ui/lint/outer-forbid.stderr @@ -453,3 +453,21 @@ note: the lint level is defined here LL | #![forbid(forbidden_lint_groups)] | ^^^^^^^^^^^^^^^^^^^^^ +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/lint/unused-visibilities.fixed b/tests/ui/lint/unused-visibilities.fixed new file mode 100644 index 000000000000..3dd7cde0c9e2 --- /dev/null +++ b/tests/ui/lint/unused-visibilities.fixed @@ -0,0 +1,12 @@ +//@ check-pass +//@ run-rustfix + +#![warn(unused_visibilities)] + + const _: () = {}; +//~^WARN visibility qualifiers have no effect on `const _` declarations + + const _: () = {}; +//~^WARN visibility qualifiers have no effect on `const _` declarations + +fn main() {} diff --git a/tests/ui/lint/unused-visibilities.rs b/tests/ui/lint/unused-visibilities.rs new file mode 100644 index 000000000000..51bcd34599ad --- /dev/null +++ b/tests/ui/lint/unused-visibilities.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ run-rustfix + +#![warn(unused_visibilities)] + +pub const _: () = {}; +//~^WARN visibility qualifiers have no effect on `const _` declarations + +pub(self) const _: () = {}; +//~^WARN visibility qualifiers have no effect on `const _` declarations + +fn main() {} diff --git a/tests/ui/lint/unused-visibilities.stderr b/tests/ui/lint/unused-visibilities.stderr new file mode 100644 index 000000000000..032e2821d987 --- /dev/null +++ b/tests/ui/lint/unused-visibilities.stderr @@ -0,0 +1,20 @@ +warning: visibility qualifiers have no effect on `const _` declarations + --> $DIR/unused-visibilities.rs:6:1 + | +LL | pub const _: () = {}; + | ^^^ help: remove the qualifier + | +note: the lint level is defined here + --> $DIR/unused-visibilities.rs:4:9 + | +LL | #![warn(unused_visibilities)] + | ^^^^^^^^^^^^^^^^^^^ + +warning: visibility qualifiers have no effect on `const _` declarations + --> $DIR/unused-visibilities.rs:9:1 + | +LL | pub(self) const _: () = {}; + | ^^^^^^^^^ help: remove the qualifier + +warning: 2 warnings emitted + diff --git a/tests/ui/traits/const-traits/call.rs b/tests/ui/traits/const-traits/call.rs index b1080fe78bb5..360c08e1b7fe 100644 --- a/tests/ui/traits/const-traits/call.rs +++ b/tests/ui/traits/const-traits/call.rs @@ -3,7 +3,7 @@ #![feature(const_closures, const_trait_impl)] #![allow(incomplete_features)] -pub const _: () = { +const _: () = { assert!((const || true)()); //~^ ERROR }: [const] Fn()` is not satisfied }; From 8cc9c5ebb19a8d594ac36e2e33307f5def7b60fc Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 28 Sep 2025 18:12:17 -0400 Subject: [PATCH 0367/3801] Add warn-by-default lint for visibility on `const _` declarations Add a warn-by-default `unused_visibility` lint for visibility qualifiers on `const _` declarations - e.g. `pub const _: () = ();`. These have no effect. --- tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr | 6 +++--- tests/ui-toml/absolute_paths/absolute_paths.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr b/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr index 70d71f6c4ea1..c94b7777f3e9 100644 --- a/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr +++ b/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr @@ -71,10 +71,10 @@ LL | impl core::fmt::Display for X | ^^^^^^^^^^^^^^^^^^ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:14 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:10 | -LL | pub const _: crate::S = { - | ^^^^^^^^ +LL | const _: crate::S = { + | ^^^^^^^^ error: consider bringing this path into scope with the `use` keyword --> tests/ui-toml/absolute_paths/absolute_paths.rs:114:9 diff --git a/tests/ui-toml/absolute_paths/absolute_paths.rs b/tests/ui-toml/absolute_paths/absolute_paths.rs index c024f2f513ce..a3982b8f6540 100644 --- a/tests/ui-toml/absolute_paths/absolute_paths.rs +++ b/tests/ui-toml/absolute_paths/absolute_paths.rs @@ -110,7 +110,7 @@ mod m1 { } //~[no_short]v absolute_paths -pub const _: crate::S = { +const _: crate::S = { let crate::S = m1::S; //~[no_short] absolute_paths crate::m1::S From 4cc2f952e41ac4c3bbd0e5e8737238f06529fb7b Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Tue, 30 Sep 2025 10:05:20 -0400 Subject: [PATCH 0368/3801] Elaborate lint explanation --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index e8bd8f8f7099..740530daf2bd 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -708,7 +708,7 @@ declare_lint! { /// /// ### Explanation /// - /// These qualifiers have no effect. + /// These qualifiers have no effect, as `const _` items are unnameable. pub UNUSED_VISIBILITIES, Warn, "detect visibility qualifiers on `const _` items" From 6b5da2f17798a2232d793fc06daeb764a04b9386 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Wed, 3 Dec 2025 11:37:54 -0500 Subject: [PATCH 0369/3801] Don't warn when underscore is passed to macro --- compiler/rustc_ast_passes/src/ast_validation.rs | 1 + tests/ui/lint/unused-visibilities.fixed | 17 +++++++++++++++++ tests/ui/lint/unused-visibilities.rs | 17 +++++++++++++++++ tests/ui/lint/unused-visibilities.stderr | 13 ++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 06a35e691929..ddb19f5e7915 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1349,6 +1349,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } if ident.name == kw::Underscore && !matches!(item.vis.kind, VisibilityKind::Inherited) + && ident.span.eq_ctxt(item.vis.span) { self.lint_buffer.buffer_lint( UNUSED_VISIBILITIES, diff --git a/tests/ui/lint/unused-visibilities.fixed b/tests/ui/lint/unused-visibilities.fixed index 3dd7cde0c9e2..97c1a5c73249 100644 --- a/tests/ui/lint/unused-visibilities.fixed +++ b/tests/ui/lint/unused-visibilities.fixed @@ -9,4 +9,21 @@ const _: () = {}; //~^WARN visibility qualifiers have no effect on `const _` declarations +macro_rules! foo { + () => { + const _: () = {}; + //~^WARN visibility qualifiers have no effect on `const _` declarations + }; +} + +foo!(); + +macro_rules! bar { + ($tt:tt) => { + pub const $tt: () = {}; + }; +} + +bar!(_); + fn main() {} diff --git a/tests/ui/lint/unused-visibilities.rs b/tests/ui/lint/unused-visibilities.rs index 51bcd34599ad..4bcbd1201e4a 100644 --- a/tests/ui/lint/unused-visibilities.rs +++ b/tests/ui/lint/unused-visibilities.rs @@ -9,4 +9,21 @@ pub const _: () = {}; pub(self) const _: () = {}; //~^WARN visibility qualifiers have no effect on `const _` declarations +macro_rules! foo { + () => { + pub const _: () = {}; + //~^WARN visibility qualifiers have no effect on `const _` declarations + }; +} + +foo!(); + +macro_rules! bar { + ($tt:tt) => { + pub const $tt: () = {}; + }; +} + +bar!(_); + fn main() {} diff --git a/tests/ui/lint/unused-visibilities.stderr b/tests/ui/lint/unused-visibilities.stderr index 032e2821d987..f70d654b30b1 100644 --- a/tests/ui/lint/unused-visibilities.stderr +++ b/tests/ui/lint/unused-visibilities.stderr @@ -16,5 +16,16 @@ warning: visibility qualifiers have no effect on `const _` declarations LL | pub(self) const _: () = {}; | ^^^^^^^^^ help: remove the qualifier -warning: 2 warnings emitted +warning: visibility qualifiers have no effect on `const _` declarations + --> $DIR/unused-visibilities.rs:14:9 + | +LL | pub const _: () = {}; + | ^^^ help: remove the qualifier +... +LL | foo!(); + | ------ in this macro invocation + | + = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 3 warnings emitted From 9e7200967eb051f1635e13196003c5d4d8c8ace0 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 5 Dec 2025 11:22:30 -0500 Subject: [PATCH 0370/3801] Add note to lint message --- compiler/rustc_lint/messages.ftl | 1 + compiler/rustc_lint/src/lints.rs | 1 + tests/ui/lint/unused-visibilities.stderr | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index fac26b52176d..5754bc9621a1 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -979,6 +979,7 @@ lint_unused_op = unused {$op} that must be used lint_unused_result = unused result of type `{$ty}` lint_unused_visibilities = visibility qualifiers have no effect on `const _` declarations + .note = there is no declared name for the qualifier to affect .suggestion = remove the qualifier lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index a10a5e7d5f26..1bec316ce45a 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3194,6 +3194,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { #[derive(LintDiagnostic)] #[diag(lint_unused_visibilities)] +#[note] pub(crate) struct UnusedVisibility { #[suggestion(style = "short", code = "", applicability = "machine-applicable")] pub span: Span, diff --git a/tests/ui/lint/unused-visibilities.stderr b/tests/ui/lint/unused-visibilities.stderr index f70d654b30b1..3aefb869dafd 100644 --- a/tests/ui/lint/unused-visibilities.stderr +++ b/tests/ui/lint/unused-visibilities.stderr @@ -4,6 +4,7 @@ warning: visibility qualifiers have no effect on `const _` declarations LL | pub const _: () = {}; | ^^^ help: remove the qualifier | + = note: there is no declared name for the qualifier to affect note: the lint level is defined here --> $DIR/unused-visibilities.rs:4:9 | @@ -15,6 +16,8 @@ warning: visibility qualifiers have no effect on `const _` declarations | LL | pub(self) const _: () = {}; | ^^^^^^^^^ help: remove the qualifier + | + = note: there is no declared name for the qualifier to affect warning: visibility qualifiers have no effect on `const _` declarations --> $DIR/unused-visibilities.rs:14:9 @@ -25,6 +28,7 @@ LL | pub const _: () = {}; LL | foo!(); | ------ in this macro invocation | + = note: there is no declared name for the qualifier to affect = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 3 warnings emitted From 43fa060c38e06df99985007ecfff8b86c9fad7c5 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 6 Dec 2025 13:41:32 -0500 Subject: [PATCH 0371/3801] Expand lint note --- compiler/rustc_lint/messages.ftl | 2 +- tests/ui/lint/unused-visibilities.stderr | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 5754bc9621a1..bc1c246b8f03 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -979,7 +979,7 @@ lint_unused_op = unused {$op} that must be used lint_unused_result = unused result of type `{$ty}` lint_unused_visibilities = visibility qualifiers have no effect on `const _` declarations - .note = there is no declared name for the qualifier to affect + .note = `const _` does not declare a name, so there is nothing for the qualifier to apply to .suggestion = remove the qualifier lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result diff --git a/tests/ui/lint/unused-visibilities.stderr b/tests/ui/lint/unused-visibilities.stderr index 3aefb869dafd..e5ff2a7fcae8 100644 --- a/tests/ui/lint/unused-visibilities.stderr +++ b/tests/ui/lint/unused-visibilities.stderr @@ -4,7 +4,7 @@ warning: visibility qualifiers have no effect on `const _` declarations LL | pub const _: () = {}; | ^^^ help: remove the qualifier | - = note: there is no declared name for the qualifier to affect + = note: `const _` does not declare a name, so there is nothing for the qualifier to apply to note: the lint level is defined here --> $DIR/unused-visibilities.rs:4:9 | @@ -17,7 +17,7 @@ warning: visibility qualifiers have no effect on `const _` declarations LL | pub(self) const _: () = {}; | ^^^^^^^^^ help: remove the qualifier | - = note: there is no declared name for the qualifier to affect + = note: `const _` does not declare a name, so there is nothing for the qualifier to apply to warning: visibility qualifiers have no effect on `const _` declarations --> $DIR/unused-visibilities.rs:14:9 @@ -28,7 +28,7 @@ LL | pub const _: () = {}; LL | foo!(); | ------ in this macro invocation | - = note: there is no declared name for the qualifier to affect + = note: `const _` does not declare a name, so there is nothing for the qualifier to apply to = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 3 warnings emitted From 74734878c877ce1d2c34687948b518294262a8c4 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 6 Dec 2025 21:23:21 +0200 Subject: [PATCH 0372/3801] Don't implement sizedness check via `all_field_tys()` Since we don't implement it currently for perf reasons, but here we only need a struct's tail field, it will be wrong. --- .../crates/hir-ty/src/next_solver/interner.rs | 13 +++------ .../crates/hir-ty/src/next_solver/util.rs | 8 ++--- .../hir-ty/src/tests/method_resolution.rs | 29 +++++++++++++++++++ 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 2e52dcea6c5b..e77b77bf4a90 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -690,15 +690,10 @@ impl<'db> inherent::AdtDef> for AdtDef { interner: DbInterner<'db>, sizedness: SizedTraitKind, ) -> Option, Ty<'db>>> { - if self.is_struct() { - let tail_ty = self.all_field_tys(interner).skip_binder().into_iter().last()?; - - let constraint_ty = sizedness_constraint_for_ty(interner, sizedness, tail_ty)?; - - Some(EarlyBinder::bind(constraint_ty)) - } else { - None - } + let tail_ty = self.struct_tail_ty(interner)?; + tail_ty + .map_bound(|tail_ty| sizedness_constraint_for_ty(interner, sizedness, tail_ty)) + .transpose() } fn destructor( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs index 972c8e2da7b1..bc4b5fdbfc52 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs @@ -422,12 +422,10 @@ pub fn sizedness_constraint_for_ty<'db>( .next_back() .and_then(|ty| sizedness_constraint_for_ty(interner, sizedness, ty)), - Adt(adt, args) => { - let tail_ty = - EarlyBinder::bind(adt.all_field_tys(interner).skip_binder().into_iter().last()?) - .instantiate(interner, args); + Adt(adt, args) => adt.struct_tail_ty(interner).and_then(|tail_ty| { + let tail_ty = tail_ty.instantiate(interner, args); sizedness_constraint_for_ty(interner, sizedness, tail_ty) - } + }), Placeholder(..) | Bound(..) | Infer(..) => { panic!("unexpected type `{ty:?}` in sizedness_constraint_for_ty") diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs index 274d33a211f0..c8ed8aa2584c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs @@ -2229,3 +2229,32 @@ fn test(x: *mut u8) { "#, ); } + +#[test] +fn unsized_struct() { + check_types( + r#" +//- minicore: sized, phantom_data +use core::marker::PhantomData; + +const UI_DEV_CREATE: Ioctl = Ioctl(PhantomData); + +struct Ioctl(PhantomData); + +struct NoArgs([u8]); + +impl Ioctl { + fn ioctl(self) {} +} + +impl Ioctl { + fn ioctl(self) -> u32 { 0 } +} + +fn main() { + UI_DEV_CREATE.ioctl(); + // ^^^^^^^^^^^^^^^^^^^^^ u32 +} + "#, + ); +} From fb92c70c89f8b009748629b3da73bcfaede11e5a Mon Sep 17 00:00:00 2001 From: yanglsh Date: Wed, 1 Oct 2025 01:16:37 +0800 Subject: [PATCH 0373/3801] fix: `map_entry` suggests wrongly for insert with cfg-ed out code --- clippy_lints/src/entry.rs | 8 ++++++-- tests/ui/entry.fixed | 10 ++++++++++ tests/ui/entry.rs | 10 ++++++++++ tests/ui/entry.stderr | 23 ++++++++++++++++++++++- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index bdfe2e49e66e..75ab890a8a7f 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -4,7 +4,7 @@ use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_expr; use clippy_utils::{ SpanlessEq, can_move_expr_to_closure_no_visit, desugar_await, higher, is_expr_final_block_expr, - is_expr_used_or_unified, paths, peel_hir_expr_while, + is_expr_used_or_unified, paths, peel_hir_expr_while, span_contains_non_whitespace, }; use core::fmt::{self, Write}; use rustc_errors::Applicability; @@ -167,7 +167,11 @@ impl<'tcx> LateLintPass<'tcx> for HashMapPass { "if let {}::{entry_kind} = {map_str}.entry({key_str}) {body_str}", map_ty.entry_path(), )) - } else if let Some(insertion) = then_search.as_single_insertion() { + } else if let Some(insertion) = then_search.as_single_insertion() + && let span_in_between = then_expr.span.shrink_to_lo().between(insertion.call.span) + && let span_in_between = span_in_between.split_at(1).1 + && !span_contains_non_whitespace(cx, span_in_between, true) + { let value_str = snippet_with_context(cx, insertion.value.span, then_expr.span.ctxt(), "..", &mut app).0; if contains_expr.negated { if insertion.value.can_have_side_effects() { diff --git a/tests/ui/entry.fixed b/tests/ui/entry.fixed index 1e36ca4f1f09..75e173b9a84d 100644 --- a/tests/ui/entry.fixed +++ b/tests/ui/entry.fixed @@ -273,3 +273,13 @@ mod issue_16173 { } fn main() {} + +fn issue15781(m: &mut std::collections::HashMap, k: i32, v: i32) { + fn very_important_fn() {} + m.entry(k).or_insert_with(|| { + //~^ map_entry + #[cfg(test)] + very_important_fn(); + v + }); +} diff --git a/tests/ui/entry.rs b/tests/ui/entry.rs index b3da0ef3ffd6..7e3308c87356 100644 --- a/tests/ui/entry.rs +++ b/tests/ui/entry.rs @@ -279,3 +279,13 @@ mod issue_16173 { } fn main() {} + +fn issue15781(m: &mut std::collections::HashMap, k: i32, v: i32) { + fn very_important_fn() {} + if !m.contains_key(&k) { + //~^ map_entry + #[cfg(test)] + very_important_fn(); + m.insert(k, v); + } +} diff --git a/tests/ui/entry.stderr b/tests/ui/entry.stderr index 009b78d29073..4a29b3860e89 100644 --- a/tests/ui/entry.stderr +++ b/tests/ui/entry.stderr @@ -246,5 +246,26 @@ LL + e.insert(42); LL + } | -error: aborting due to 11 previous errors +error: usage of `contains_key` followed by `insert` on a `HashMap` + --> tests/ui/entry.rs:285:5 + | +LL | / if !m.contains_key(&k) { +LL | | +LL | | #[cfg(test)] +LL | | very_important_fn(); +LL | | m.insert(k, v); +LL | | } + | |_____^ + | +help: try + | +LL ~ m.entry(k).or_insert_with(|| { +LL + +LL + #[cfg(test)] +LL + very_important_fn(); +LL + v +LL + }); + | + +error: aborting due to 12 previous errors From 7fdf06693a92d9d781cb794ef5b20e564f8b3eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 6 Dec 2025 22:02:23 +0100 Subject: [PATCH 0374/3801] Fix off-by-one staging output when testing the library --- src/bootstrap/src/core/build_steps/test.rs | 9 +++++++-- src/bootstrap/src/core/builder/cargo.rs | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 7e46b85ff9af..eb3ea1ab5120 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2818,10 +2818,15 @@ fn run_cargo_test<'a>( builder: &Builder<'_>, ) -> bool { let compiler = cargo.compiler(); + let stage = match cargo.mode() { + Mode::Std => compiler.stage, + _ => compiler.stage + 1, + }; + let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, target, builder); let _time = helpers::timeit(builder); - let _group = - description.into().and_then(|what| builder.msg_test(what, target, compiler.stage + 1)); + + let _group = description.into().and_then(|what| builder.msg_test(what, target, stage)); #[cfg(feature = "build-metrics")] builder.metrics.begin_test_suite( diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 093a754f1a4b..2ca52c72e5ec 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -98,6 +98,7 @@ pub struct Cargo { command: BootstrapCommand, args: Vec, compiler: Compiler, + mode: Mode, target: TargetSelection, rustflags: Rustflags, rustdocflags: Rustflags, @@ -141,6 +142,10 @@ impl Cargo { self.compiler } + pub fn mode(&self) -> Mode { + self.mode + } + pub fn into_cmd(self) -> BootstrapCommand { self.into() } @@ -1404,6 +1409,7 @@ impl Builder<'_> { command: cargo, args: vec![], compiler, + mode, target, rustflags, rustdocflags, From e9d18d5b6077b8de8d90e49e5be4964c9f97ceff Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 7 Dec 2025 02:14:39 +0200 Subject: [PATCH 0375/3801] Update supported Rust version to 1.90.0 We no longer work properly with older versions. --- src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 6ae527abb1ff..3dea21e56485 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -14,7 +14,7 @@ extern crate ra_ap_rustc_type_ir as rustc_type_ir; /// Any toolchain less than this version will likely not work with rust-analyzer built from this revision. pub const MINIMUM_SUPPORTED_TOOLCHAIN_VERSION: semver::Version = semver::Version { major: 1, - minor: 78, + minor: 90, patch: 0, pre: semver::Prerelease::EMPTY, build: semver::BuildMetadata::EMPTY, From 79893a050eb5b4e3104dcef8781924b83b483a1e Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Mon, 1 Dec 2025 19:02:25 +0900 Subject: [PATCH 0376/3801] cleaned up some tests merged tests/ui/issues/issue-2951.rs with tests/ui/type/type-parameter-names.rs Merged tests/ui/for-loop-while/break-continue-in-loop-while-contiditoin-1.rs with tests/ui/for-loop-while/break-continue-in-loop-while-contiditoin-2.rs Removed tests/ui/issues/issue-2383.rs duplicated of library\alloc\src\collections\vec_deque\tests.rs Removed tests/ui/issues/issue-20714.rs duplicated of tests/ui/empty/empty-struct-unit-expr.rs Added comment to tests/ui/match/match-option-result-mismatch.rs, tests/ui/numeric/ref-int.rs, tests/ui/box/self-assignment.rs --- tests/ui/box/self-assignment.rs | 8 ++-- tests/ui/empty/empty-struct-unit-expr.rs | 3 +- tests/ui/empty/empty-struct-unit-expr.stderr | 10 ++--- ...reak-continue-in-loop-while-condition-2.rs | 8 ---- ...-continue-in-loop-while-condition-2.stderr | 9 ---- ...break-continue-in-loop-while-condition.rs} | 32 +++++++++++--- ...k-continue-in-loop-while-condition.stderr} | 44 +++++++++++-------- tests/ui/issues/issue-20714.rs | 5 --- tests/ui/issues/issue-20714.stderr | 20 --------- tests/ui/issues/issue-2383.rs | 8 ---- tests/ui/issues/issue-2951.rs | 13 ------ tests/ui/issues/issue-2951.stderr | 20 --------- .../ui/match/match-option-result-mismatch.rs | 7 ++- .../match/match-option-result-mismatch.stderr | 7 +-- tests/ui/numeric/ref-int.rs | 1 + tests/ui/type/type-parameter-names.rs | 18 ++++++-- tests/ui/type/type-parameter-names.stderr | 21 ++++++++- 17 files changed, 106 insertions(+), 128 deletions(-) delete mode 100644 tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.rs delete mode 100644 tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.stderr rename tests/ui/for-loop-while/{break-continue-in-loop-while-condition-1.rs => break-continue-in-loop-while-condition.rs} (58%) rename tests/ui/for-loop-while/{break-continue-in-loop-while-condition-1.stderr => break-continue-in-loop-while-condition.stderr} (59%) delete mode 100644 tests/ui/issues/issue-20714.rs delete mode 100644 tests/ui/issues/issue-20714.stderr delete mode 100644 tests/ui/issues/issue-2383.rs delete mode 100644 tests/ui/issues/issue-2951.rs delete mode 100644 tests/ui/issues/issue-2951.stderr diff --git a/tests/ui/box/self-assignment.rs b/tests/ui/box/self-assignment.rs index 50c432288ce1..3689ddac5d10 100644 --- a/tests/ui/box/self-assignment.rs +++ b/tests/ui/box/self-assignment.rs @@ -1,8 +1,10 @@ //@ run-pass +//! regression test for + #![allow(dead_code)] pub fn main() { - let mut x: Box<_> = Box::new(3); - x = x; - assert_eq!(*x, 3); + let mut x: Box<_> = Box::new(3); + x = x; + assert_eq!(*x, 3); } diff --git a/tests/ui/empty/empty-struct-unit-expr.rs b/tests/ui/empty/empty-struct-unit-expr.rs index c71ea3bdce72..5a0d57edb13d 100644 --- a/tests/ui/empty/empty-struct-unit-expr.rs +++ b/tests/ui/empty/empty-struct-unit-expr.rs @@ -1,4 +1,5 @@ // Can't use unit struct as constructor function +// related issue //@ aux-build:empty-struct.rs @@ -8,7 +9,7 @@ use empty_struct::*; struct Empty2; enum E { - Empty4 + Empty4, } fn main() { diff --git a/tests/ui/empty/empty-struct-unit-expr.stderr b/tests/ui/empty/empty-struct-unit-expr.stderr index e97209527fe3..511c144f926c 100644 --- a/tests/ui/empty/empty-struct-unit-expr.stderr +++ b/tests/ui/empty/empty-struct-unit-expr.stderr @@ -1,5 +1,5 @@ error[E0618]: expected function, found struct `Empty2` - --> $DIR/empty-struct-unit-expr.rs:15:14 + --> $DIR/empty-struct-unit-expr.rs:16:14 | LL | struct Empty2; | ------------- struct `Empty2` defined here @@ -16,9 +16,9 @@ LL + let e2 = Empty2; | error[E0618]: expected function, found enum variant `E::Empty4` - --> $DIR/empty-struct-unit-expr.rs:16:14 + --> $DIR/empty-struct-unit-expr.rs:17:14 | -LL | Empty4 +LL | Empty4, | ------ enum variant `E::Empty4` defined here ... LL | let e4 = E::Empty4(); @@ -33,7 +33,7 @@ LL + let e4 = E::Empty4; | error[E0618]: expected function, found struct `XEmpty2` - --> $DIR/empty-struct-unit-expr.rs:18:15 + --> $DIR/empty-struct-unit-expr.rs:19:15 | LL | let xe2 = XEmpty2(); | ^^^^^^^-- @@ -47,7 +47,7 @@ LL + let xe2 = XEmpty2; | error[E0618]: expected function, found enum variant `XE::XEmpty4` - --> $DIR/empty-struct-unit-expr.rs:19:15 + --> $DIR/empty-struct-unit-expr.rs:20:15 | LL | let xe4 = XE::XEmpty4(); | ^^^^^^^^^^^-- diff --git a/tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.rs b/tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.rs deleted file mode 100644 index dece55968b6a..000000000000 --- a/tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[allow(unreachable_code)] - -fn main() { - loop { - break while continue { //~ ERROR E0590 - } - } -} diff --git a/tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.stderr b/tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.stderr deleted file mode 100644 index e1b5ae325120..000000000000 --- a/tests/ui/for-loop-while/break-continue-in-loop-while-condition-2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-50802.rs:5:21 - | -LL | break while continue { - | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0590`. diff --git a/tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.rs b/tests/ui/for-loop-while/break-continue-in-loop-while-condition.rs similarity index 58% rename from tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.rs rename to tests/ui/for-loop-while/break-continue-in-loop-while-condition.rs index e7f933ab22ea..d1fcb6dbb537 100644 --- a/tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.rs +++ b/tests/ui/for-loop-while/break-continue-in-loop-while-condition.rs @@ -1,3 +1,6 @@ +//! regression test for #37576, #50802 +//! Tests that using unlabeled `break` or `continue` within a loop or while's condition. + fn main() { 'test_1: while break 'test_1 {} while break {} @@ -7,9 +10,13 @@ fn main() { while let true = break {} //~^ ERROR `break` or `continue` with no label - loop { 'test_3: while break 'test_3 {} } - loop { while break {} } - //~^ ERROR `break` or `continue` with no label + loop { + 'test_3: while break 'test_3 {} + } + loop { + while break {} + //~^ ERROR `break` or `continue` with no label + } loop { 'test_4: while break 'test_4 {} @@ -29,9 +36,13 @@ fn main() { while let true = continue {} //~^ ERROR `break` or `continue` with no label - loop { 'test_7: while continue 'test_7 {} } - loop { while continue {} } - //~^ ERROR `break` or `continue` with no label + loop { + 'test_7: while continue 'test_7 {} + } + loop { + while continue {} + //~^ ERROR `break` or `continue` with no label + } loop { 'test_8: while continue 'test_8 {} @@ -42,4 +53,13 @@ fn main() { //~^ ERROR `break` or `continue` with no label continue; } + + 'test_9: loop { + break while continue 'test_9 {}; + } + loop { + break while continue { + //~^ ERROR `break` or `continue` with no label + }; + } } diff --git a/tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.stderr b/tests/ui/for-loop-while/break-continue-in-loop-while-condition.stderr similarity index 59% rename from tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.stderr rename to tests/ui/for-loop-while/break-continue-in-loop-while-condition.stderr index d19e1f45393a..dac6dc2e30bc 100644 --- a/tests/ui/for-loop-while/break-continue-in-loop-while-condition-1.stderr +++ b/tests/ui/for-loop-while/break-continue-in-loop-while-condition.stderr @@ -1,51 +1,57 @@ error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:3:11 + --> $DIR/break-continue-in-loop-while-condition.rs:6:11 | LL | while break {} | ^^^^^ unlabeled `break` in the condition of a `while` loop error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:7:22 + --> $DIR/break-continue-in-loop-while-condition.rs:10:22 | LL | while let true = break {} | ^^^^^ unlabeled `break` in the condition of a `while` loop error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:11:18 - | -LL | loop { while break {} } - | ^^^^^ unlabeled `break` in the condition of a `while` loop - -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:19:15 + --> $DIR/break-continue-in-loop-while-condition.rs:17:15 | LL | while break {} | ^^^^^ unlabeled `break` in the condition of a `while` loop error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:25:11 + --> $DIR/break-continue-in-loop-while-condition.rs:26:15 + | +LL | while break {} + | ^^^^^ unlabeled `break` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:32:11 | LL | while continue {} | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:29:22 + --> $DIR/break-continue-in-loop-while-condition.rs:36:22 | LL | while let true = continue {} | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:33:18 - | -LL | loop { while continue {} } - | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop - -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:41:15 + --> $DIR/break-continue-in-loop-while-condition.rs:43:15 | LL | while continue {} | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop -error: aborting due to 8 previous errors +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:52:15 + | +LL | while continue {} + | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:61:21 + | +LL | break while continue { + | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0590`. diff --git a/tests/ui/issues/issue-20714.rs b/tests/ui/issues/issue-20714.rs deleted file mode 100644 index 3aa39bb7388f..000000000000 --- a/tests/ui/issues/issue-20714.rs +++ /dev/null @@ -1,5 +0,0 @@ -struct G; - -fn main() { - let g = G(); //~ ERROR: expected function, found struct `G` -} diff --git a/tests/ui/issues/issue-20714.stderr b/tests/ui/issues/issue-20714.stderr deleted file mode 100644 index f537a01582b6..000000000000 --- a/tests/ui/issues/issue-20714.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0618]: expected function, found struct `G` - --> $DIR/issue-20714.rs:4:13 - | -LL | struct G; - | -------- struct `G` defined here -... -LL | let g = G(); - | ^-- - | | - | call expression requires function - | -help: `G` is a unit struct, and does not take parentheses to be constructed - | -LL - let g = G(); -LL + let g = G; - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/issues/issue-2383.rs b/tests/ui/issues/issue-2383.rs deleted file mode 100644 index 5d60018ae673..000000000000 --- a/tests/ui/issues/issue-2383.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass - -use std::collections::VecDeque; - -pub fn main() { - let mut q = VecDeque::new(); - q.push_front(10); -} diff --git a/tests/ui/issues/issue-2951.rs b/tests/ui/issues/issue-2951.rs deleted file mode 100644 index e28516fa3073..000000000000 --- a/tests/ui/issues/issue-2951.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ dont-require-annotations: NOTE - -fn foo(x: T, y: U) { - let mut xx = x; - xx = y; - //~^ ERROR mismatched types - //~| NOTE expected type parameter `T`, found type parameter `U` - //~| NOTE expected type parameter `T` - //~| NOTE found type parameter `U` -} - -fn main() { -} diff --git a/tests/ui/issues/issue-2951.stderr b/tests/ui/issues/issue-2951.stderr deleted file mode 100644 index d4b45935bf9a..000000000000 --- a/tests/ui/issues/issue-2951.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-2951.rs:5:10 - | -LL | fn foo(x: T, y: U) { - | - - found type parameter - | | - | expected type parameter -LL | let mut xx = x; - | - expected due to this value -LL | xx = y; - | ^ expected type parameter `T`, found type parameter `U` - | - = note: expected type parameter `T` - found type parameter `U` - = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-option-result-mismatch.rs b/tests/ui/match/match-option-result-mismatch.rs index 7fdc6e179e47..e7c185cf09b8 100644 --- a/tests/ui/match/match-option-result-mismatch.rs +++ b/tests/ui/match/match-option-result-mismatch.rs @@ -1,6 +1,9 @@ +//! regression test for + fn main() { - match None { //~ NOTE this expression has type `Option<_>` - Err(_) => () + match None { + //~^ NOTE this expression has type `Option<_>` + Err(_) => (), //~^ ERROR mismatched types //~| NOTE expected enum `Option<_>` //~| NOTE found enum `Result<_, _>` diff --git a/tests/ui/match/match-option-result-mismatch.stderr b/tests/ui/match/match-option-result-mismatch.stderr index 2a757b44dc83..212d322fe2d9 100644 --- a/tests/ui/match/match-option-result-mismatch.stderr +++ b/tests/ui/match/match-option-result-mismatch.stderr @@ -1,16 +1,17 @@ error[E0308]: mismatched types - --> $DIR/issue-3680.rs:3:9 + --> $DIR/match-option-result-mismatch.rs:6:9 | LL | match None { | ---- this expression has type `Option<_>` -LL | Err(_) => () +LL | +LL | Err(_) => (), | ^^^^^^ expected `Option<_>`, found `Result<_, _>` | = note: expected enum `Option<_>` found enum `Result<_, _>` help: try wrapping the pattern in `Some` | -LL | Some(Err(_)) => () +LL | Some(Err(_)) => (), | +++++ + error: aborting due to 1 previous error diff --git a/tests/ui/numeric/ref-int.rs b/tests/ui/numeric/ref-int.rs index a4f9b3718446..da4f4fc07082 100644 --- a/tests/ui/numeric/ref-int.rs +++ b/tests/ui/numeric/ref-int.rs @@ -1,4 +1,5 @@ //@ run-pass +//! regression test for pub fn main() { let x = 1; diff --git a/tests/ui/type/type-parameter-names.rs b/tests/ui/type/type-parameter-names.rs index fbd1885f543f..0b427314f133 100644 --- a/tests/ui/type/type-parameter-names.rs +++ b/tests/ui/type/type-parameter-names.rs @@ -1,14 +1,24 @@ // Test that we print out the names of type parameters correctly in // our error messages. +// related issue //@ dont-require-annotations: NOTE fn foo(x: Foo) -> Bar { x -//~^ ERROR mismatched types -//~| NOTE expected type parameter `Bar`, found type parameter `Foo` -//~| NOTE expected type parameter `Bar` -//~| NOTE found type parameter `Foo` + //~^ ERROR mismatched types + //~| NOTE expected type parameter `Bar`, found type parameter `Foo` + //~| NOTE expected type parameter `Bar` + //~| NOTE found type parameter `Foo` +} + +fn bar(x: Foo, y: Bar) { + let mut xx = x; + xx = y; + //~^ ERROR mismatched types + //~| NOTE expected type parameter `Foo`, found type parameter `Bar` + //~| NOTE expected type parameter `Foo` + //~| NOTE found type parameter `Bar` } fn main() {} diff --git a/tests/ui/type/type-parameter-names.stderr b/tests/ui/type/type-parameter-names.stderr index 795a260688c4..f84449ef0d36 100644 --- a/tests/ui/type/type-parameter-names.stderr +++ b/tests/ui/type/type-parameter-names.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/type-parameter-names.rs:7:5 + --> $DIR/type-parameter-names.rs:8:5 | LL | fn foo(x: Foo) -> Bar { | --- --- --- expected `Bar` because of return type @@ -15,6 +15,23 @@ LL | x = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters = note: the caller chooses a type for `Bar` which can be different from `Foo` -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/type-parameter-names.rs:17:10 + | +LL | fn bar(x: Foo, y: Bar) { + | --- --- found type parameter + | | + | expected type parameter +LL | let mut xx = x; + | - expected due to this value +LL | xx = y; + | ^ expected type parameter `Foo`, found type parameter `Bar` + | + = note: expected type parameter `Foo` + found type parameter `Bar` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. From 5f9aca7e74ca901cd6e3fad6dbc6a5a14f160ea1 Mon Sep 17 00:00:00 2001 From: RustyYato Date: Fri, 5 Dec 2025 12:24:31 -0700 Subject: [PATCH 0377/3801] Add `#[inline]` to `Layout::is_size_align_valid` add Alignment::new_unchecked::precondition_check to allowlist --- library/core/src/alloc/layout.rs | 1 + tests/codegen-units/item-collection/opaque-return-impls.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 73d929fbc7f4..a4e25b8734a9 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -65,6 +65,7 @@ impl Layout { } } + #[inline] const fn is_size_align_valid(size: usize, align: usize) -> bool { let Some(align) = Alignment::new(align) else { return false }; if size > Self::max_size_for_align(align) { diff --git a/tests/codegen-units/item-collection/opaque-return-impls.rs b/tests/codegen-units/item-collection/opaque-return-impls.rs index 1659b62175b7..d54951b933fd 100644 --- a/tests/codegen-units/item-collection/opaque-return-impls.rs +++ b/tests/codegen-units/item-collection/opaque-return-impls.rs @@ -47,6 +47,7 @@ pub fn foo2() -> Box { //~ MONO_ITEM fn std::alloc::Global::alloc_impl //~ MONO_ITEM fn std::boxed::Box::::new //~ MONO_ITEM fn std::alloc::Layout::from_size_align_unchecked::precondition_check +//~ MONO_ITEM fn std::ptr::Alignment::new_unchecked::precondition_check //~ MONO_ITEM fn std::ptr::NonNull::::new_unchecked::precondition_check struct Counter { From 85f7a6ed610933f32966483dc4aff2399928f3e9 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 7 Dec 2025 13:40:38 +1100 Subject: [PATCH 0378/3801] Move Android-related discovery out of `core::debuggers` While some of this information is needed by debugger discovery, it is also needed by non-debuginfo tests, so the code doesn't belong in the `debuggers` module. --- src/bootstrap/src/core/{debuggers => }/android.rs | 0 src/bootstrap/src/core/build_steps/test.rs | 11 ++++------- src/bootstrap/src/core/debuggers/mod.rs | 2 -- src/bootstrap/src/core/mod.rs | 1 + 4 files changed, 5 insertions(+), 9 deletions(-) rename src/bootstrap/src/core/{debuggers => }/android.rs (100%) diff --git a/src/bootstrap/src/core/debuggers/android.rs b/src/bootstrap/src/core/android.rs similarity index 100% rename from src/bootstrap/src/core/debuggers/android.rs rename to src/bootstrap/src/core/android.rs diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 7e46b85ff9af..64c8c1e56613 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -29,7 +29,7 @@ use crate::core::builder::{ }; use crate::core::config::TargetSelection; use crate::core::config::flags::{Subcommand, get_completion, top_level_help}; -use crate::core::debuggers; +use crate::core::{android, debuggers}; use crate::utils::build_stamp::{self, BuildStamp}; use crate::utils::exec::{BootstrapCommand, command}; use crate::utils::helpers::{ @@ -2114,12 +2114,9 @@ Please disable assertions with `rust.debug-assertions = false`. builder.config.python.as_ref().expect("python is required for running rustdoc tests"), ); - // FIXME(#148099): Currently we set these Android-related flags in all - // modes, even though they should only be needed in "debuginfo" mode, - // because the GDB-discovery code in compiletest currently assumes that - // `--android-cross-path` is always set for Android targets. - if let Some(debuggers::Android { adb_path, adb_test_dir, android_cross_path }) = - debuggers::discover_android(builder, target) + // Discover and set some flags related to running tests on Android targets. + if let Some(android::Android { adb_path, adb_test_dir, android_cross_path }) = + android::discover_android(builder, target) { cmd.arg("--adb-path").arg(adb_path); cmd.arg("--adb-test-dir").arg(adb_test_dir); diff --git a/src/bootstrap/src/core/debuggers/mod.rs b/src/bootstrap/src/core/debuggers/mod.rs index 011ce4081a43..a11eda8e686e 100644 --- a/src/bootstrap/src/core/debuggers/mod.rs +++ b/src/bootstrap/src/core/debuggers/mod.rs @@ -1,10 +1,8 @@ //! Code for discovering debuggers and debugger-related configuration, so that //! it can be passed to compiletest when running debuginfo tests. -pub(crate) use self::android::{Android, discover_android}; pub(crate) use self::gdb::{Gdb, discover_gdb}; pub(crate) use self::lldb::{Lldb, discover_lldb}; -mod android; mod gdb; mod lldb; diff --git a/src/bootstrap/src/core/mod.rs b/src/bootstrap/src/core/mod.rs index f27a09c81c55..4df2ed319da6 100644 --- a/src/bootstrap/src/core/mod.rs +++ b/src/bootstrap/src/core/mod.rs @@ -1,3 +1,4 @@ +pub(crate) mod android; pub(crate) mod build_steps; pub(crate) mod builder; pub(crate) mod config; From 8f35bd17cc4f88d3069a78d30890e1cfcf007ef1 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 6 Dec 2025 22:22:09 +1100 Subject: [PATCH 0379/3801] Move ambient gdb discovery from compiletest to bootstrap --- src/bootstrap/src/core/android.rs | 6 ++- src/bootstrap/src/core/build_steps/test.rs | 10 ++--- src/bootstrap/src/core/debuggers/gdb.rs | 37 ++++++++++++++++-- src/tools/compiletest/src/common.rs | 2 +- src/tools/compiletest/src/debuggers.rs | 38 ------------------- src/tools/compiletest/src/lib.rs | 4 +- .../compiletest/src/runtest/debuginfo.rs | 8 ++-- 7 files changed, 51 insertions(+), 54 deletions(-) diff --git a/src/bootstrap/src/core/android.rs b/src/bootstrap/src/core/android.rs index b1ad9ca555fb..60f7ca4dbcd0 100644 --- a/src/bootstrap/src/core/android.rs +++ b/src/bootstrap/src/core/android.rs @@ -10,11 +10,15 @@ pub(crate) struct Android { } pub(crate) fn discover_android(builder: &Builder<'_>, target: TargetSelection) -> Option { + if !target.contains("android") { + return None; + } + let adb_path = "adb"; // See . let adb_test_dir = "/data/local/tmp/work"; - let android_cross_path = if target.contains("android") && !builder.config.dry_run() { + let android_cross_path = if !builder.config.dry_run() { builder.cc(target).parent().unwrap().parent().unwrap().to_owned() } else { PathBuf::new() diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 64c8c1e56613..4237d39d7425 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2115,17 +2115,17 @@ Please disable assertions with `rust.debug-assertions = false`. ); // Discover and set some flags related to running tests on Android targets. - if let Some(android::Android { adb_path, adb_test_dir, android_cross_path }) = - android::discover_android(builder, target) - { + let android = android::discover_android(builder, target); + if let Some(android::Android { adb_path, adb_test_dir, android_cross_path }) = &android { cmd.arg("--adb-path").arg(adb_path); cmd.arg("--adb-test-dir").arg(adb_test_dir); cmd.arg("--android-cross-path").arg(android_cross_path); } if mode == "debuginfo" { - if let Some(debuggers::Gdb { gdb }) = debuggers::discover_gdb(builder) { - cmd.arg("--gdb").arg(gdb); + if let Some(debuggers::Gdb { gdb }) = debuggers::discover_gdb(builder, android.as_ref()) + { + cmd.arg("--gdb").arg(gdb.as_ref()); } if let Some(debuggers::Lldb { lldb_exe, lldb_version }) = diff --git a/src/bootstrap/src/core/debuggers/gdb.rs b/src/bootstrap/src/core/debuggers/gdb.rs index ddad0909e4f0..2eb441ee9852 100644 --- a/src/bootstrap/src/core/debuggers/gdb.rs +++ b/src/bootstrap/src/core/debuggers/gdb.rs @@ -1,13 +1,42 @@ +use std::borrow::Cow; use std::path::Path; +use crate::core::android; use crate::core::builder::Builder; +use crate::utils::exec::BootstrapCommand; pub(crate) struct Gdb<'a> { - pub(crate) gdb: &'a Path, + pub(crate) gdb: Cow<'a, Path>, } -pub(crate) fn discover_gdb<'a>(builder: &'a Builder<'_>) -> Option> { - let gdb = builder.config.gdb.as_deref()?; +pub(crate) fn discover_gdb<'a>( + builder: &'a Builder<'_>, + android: Option<&android::Android>, +) -> Option> { + // If there's an explicitly-configured gdb, use that. + if let Some(gdb) = builder.config.gdb.as_deref() { + // FIXME(Zalathar): Consider returning None if gdb is an empty string, + // as a way to explicitly disable ambient gdb discovery. + let gdb = Cow::Borrowed(gdb); + return Some(Gdb { gdb }); + } - Some(Gdb { gdb }) + // Otherwise, fall back to whatever gdb is sitting around in PATH. + // (That's the historical behavior, but maybe we should require opt-in?) + + let gdb: Cow<'_, Path> = match android { + Some(android::Android { android_cross_path, .. }) => { + android_cross_path.join("bin/gdb").into() + } + None => Path::new("gdb").into(), + }; + + // Check whether an ambient gdb exists, by running `gdb --version`. + let output = { + let mut gdb_command = BootstrapCommand::new(gdb.as_ref()).allow_failure(); + gdb_command.arg("--version"); + gdb_command.run_capture(builder) + }; + + if output.is_success() { Some(Gdb { gdb }) } else { None } } diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index d8472691afdf..02b93593cbbd 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -566,7 +566,7 @@ pub struct Config { /// /// FIXME: take a look at this; this is piggy-backing off of gdb code paths but only for /// `arm-linux-androideabi` target. - pub android_cross_path: Utf8PathBuf, + pub android_cross_path: Option, /// Extra parameter to run adb on `arm-linux-androideabi`. /// diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index 791c5f03c21a..b0d0372454e2 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -54,15 +54,6 @@ pub(crate) fn configure_lldb(config: &Config) -> Option> { Some(Arc::new(Config { debugger: Some(Debugger::Lldb), ..config.clone() })) } -/// Returns `true` if the given target is an Android target for the -/// purposes of GDB testing. -pub(crate) fn is_android_gdb_target(target: &str) -> bool { - matches!( - &target[..], - "arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" - ) -} - /// Returns `true` if the given target is a MSVC target for the purposes of CDB testing. fn is_pc_windows_msvc_target(target: &str) -> bool { target.ends_with("-pc-windows-msvc") @@ -129,35 +120,6 @@ pub(crate) fn extract_cdb_version(full_version_line: &str) -> Option<[u16; 4]> { Some([major, minor, patch, build]) } -pub(crate) fn discover_gdb( - gdb: Option, - target: &str, - android_cross_path: &Utf8Path, -) -> Option { - #[cfg(not(windows))] - const GDB_FALLBACK: &str = "gdb"; - #[cfg(windows)] - const GDB_FALLBACK: &str = "gdb.exe"; - - let fallback_gdb = || { - if is_android_gdb_target(target) { - let mut gdb_path = android_cross_path.to_string(); - gdb_path.push_str("/bin/gdb"); - gdb_path - } else { - GDB_FALLBACK.to_owned() - } - }; - - let gdb = match gdb { - None => fallback_gdb(), - Some(ref s) if s.is_empty() => fallback_gdb(), // may be empty if configure found no gdb - Some(ref s) => s.to_owned(), - }; - - Some(Utf8PathBuf::from(gdb)) -} - pub(crate) fn query_gdb_version(gdb: &Utf8Path) -> Option { let mut version_line = None; if let Ok(output) = Command::new(&gdb).arg("--version").output() { diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index acd0d70d081f..f3bd467db3e4 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -256,12 +256,12 @@ fn parse_config(args: Vec) -> Config { } let target = opt_str2(matches.opt_str("target")); - let android_cross_path = opt_path(matches, "android-cross-path"); + let android_cross_path = matches.opt_str("android-cross-path").map(Utf8PathBuf::from); // FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config! let cdb = debuggers::discover_cdb(matches.opt_str("cdb"), &target); let cdb_version = cdb.as_deref().and_then(debuggers::query_cdb_version); // FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config! - let gdb = debuggers::discover_gdb(matches.opt_str("gdb"), &target, &android_cross_path); + let gdb = matches.opt_str("gdb").map(Utf8PathBuf::from); let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version); // FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config! let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from); diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index 5ef4366b68be..ac935910205b 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -8,7 +8,7 @@ use tracing::debug; use super::debugger::DebuggerCommands; use super::{Debugger, Emit, ProcRes, TestCx, Truncated, WillExecute}; -use crate::debuggers::{extract_gdb_version, is_android_gdb_target}; +use crate::debuggers::extract_gdb_version; impl TestCx<'_> { pub(super) fn run_debuginfo_test(&self) { @@ -122,13 +122,15 @@ impl TestCx<'_> { let exe_file = self.make_exe_name(); let debugger_run_result; - if is_android_gdb_target(&self.config.target) { + // If bootstrap gave us an `--android-cross-path`, assume the target + // needs Android-specific handling. + if let Some(android_cross_path) = self.config.android_cross_path.as_deref() { cmds = cmds.replace("run", "continue"); // write debugger script let mut script_str = String::with_capacity(2048); script_str.push_str(&format!("set charset {}\n", Self::charset())); - script_str.push_str(&format!("set sysroot {}\n", &self.config.android_cross_path)); + script_str.push_str(&format!("set sysroot {android_cross_path}\n")); script_str.push_str(&format!("file {}\n", exe_file)); script_str.push_str("target remote :5039\n"); script_str.push_str(&format!( From 7766ee68694c6c6a2db3a4633826ef853cba8de4 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 14 Jun 2025 08:54:55 +0200 Subject: [PATCH 0380/3801] Make `ModuleId` a tracked struct optimize some stuff Optimize `pub(crate)` visibility resolution Optimize private visibility resolution --- .../rust-analyzer/crates/hir-def/src/attrs.rs | 13 +- .../rust-analyzer/crates/hir-def/src/db.rs | 23 +- .../crates/hir-def/src/expr_store/lower.rs | 25 +- .../hir-def/src/expr_store/tests/body.rs | 4 +- .../src/expr_store/tests/body/block.rs | 18 +- .../crates/hir-def/src/find_path.rs | 114 ++++---- .../crates/hir-def/src/import_map.rs | 23 +- .../crates/hir-def/src/item_scope.rs | 31 +- .../crates/hir-def/src/lang_item.rs | 7 +- .../rust-analyzer/crates/hir-def/src/lib.rs | 180 +++--------- .../hir-def/src/macro_expansion_tests/mbe.rs | 16 +- .../hir-def/src/macro_expansion_tests/mod.rs | 7 +- .../crates/hir-def/src/nameres.rs | 241 ++++++++-------- .../crates/hir-def/src/nameres/assoc.rs | 18 +- .../hir-def/src/nameres/attr_resolution.rs | 4 +- .../crates/hir-def/src/nameres/collector.rs | 265 +++++++----------- .../crates/hir-def/src/nameres/diagnostics.rs | 29 +- .../hir-def/src/nameres/path_resolution.rs | 111 ++++---- .../hir-def/src/nameres/tests/incremental.rs | 69 ++--- .../hir-def/src/nameres/tests/macros.rs | 10 +- .../crates/hir-def/src/resolver.rs | 49 ++-- .../crates/hir-def/src/signatures.rs | 4 +- .../rust-analyzer/crates/hir-def/src/src.rs | 4 +- .../crates/hir-def/src/test_db.rs | 12 +- .../crates/hir-def/src/visibility.rs | 87 +++--- .../crates/hir-ty/src/consteval/tests.rs | 2 +- .../hir-ty/src/diagnostics/decl_check.rs | 2 +- .../diagnostics/match_check/pat_analysis.rs | 2 +- .../hir-ty/src/diagnostics/unsafe_check.rs | 2 +- .../crates/hir-ty/src/display.rs | 14 +- .../rust-analyzer/crates/hir-ty/src/drop.rs | 4 +- .../crates/hir-ty/src/dyn_compatibility.rs | 12 +- .../hir-ty/src/dyn_compatibility/tests.rs | 2 +- .../hir-ty/src/infer/closure/analysis.rs | 6 +- .../crates/hir-ty/src/layout/tests.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/lower.rs | 5 +- .../crates/hir-ty/src/method_resolution.rs | 6 +- .../hir-ty/src/method_resolution/probe.rs | 4 +- .../crates/hir-ty/src/mir/borrowck.rs | 8 +- .../crates/hir-ty/src/mir/eval.rs | 2 +- .../crates/hir-ty/src/mir/eval/tests.rs | 4 +- .../crates/hir-ty/src/mir/lower/tests.rs | 2 +- .../crates/hir-ty/src/next_solver/interner.rs | 6 +- .../crates/hir-ty/src/next_solver/ty.rs | 2 +- .../crates/hir-ty/src/opaques.rs | 2 +- .../crates/hir-ty/src/specialization.rs | 2 +- .../crates/hir-ty/src/test_db.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/tests.rs | 18 +- .../hir-ty/src/tests/closure_captures.rs | 4 +- .../crates/hir-ty/src/tests/incremental.rs | 28 +- .../rust-analyzer/crates/hir-ty/src/traits.rs | 12 +- .../crates/hir-ty/src/variance.rs | 2 +- .../rust-analyzer/crates/hir/src/attrs.rs | 10 +- .../crates/hir/src/has_source.rs | 16 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 158 ++++++----- .../rust-analyzer/crates/hir/src/semantics.rs | 12 +- .../hir/src/semantics/child_by_source.rs | 5 +- .../crates/hir/src/semantics/source_to_def.rs | 10 +- .../rust-analyzer/crates/hir/src/symbols.rs | 9 +- .../crates/hir/src/term_search/tactics.rs | 2 +- .../src/handlers/add_missing_impl_members.rs | 2 +- .../src/handlers/add_missing_match_arms.rs | 35 +-- .../src/handlers/apply_demorgan.rs | 2 +- .../ide-assists/src/handlers/auto_import.rs | 9 +- .../src/handlers/convert_bool_to_enum.rs | 7 +- .../src/handlers/convert_for_to_while_let.rs | 2 +- .../src/handlers/convert_from_to_tryfrom.rs | 2 +- .../src/handlers/convert_into_to_from.rs | 6 +- .../handlers/convert_iter_for_each_to_for.rs | 4 +- .../convert_tuple_return_type_to_struct.rs | 8 +- .../handlers/destructure_struct_binding.rs | 7 +- .../src/handlers/expand_glob_import.rs | 8 +- .../src/handlers/extract_function.rs | 5 +- .../extract_struct_from_enum_variant.rs | 3 +- .../src/handlers/fix_visibility.rs | 4 +- .../generate_default_from_enum_variant.rs | 2 +- .../src/handlers/generate_default_from_new.rs | 2 +- .../src/handlers/generate_delegate_methods.rs | 2 +- .../src/handlers/generate_delegate_trait.rs | 2 +- .../src/handlers/generate_deref.rs | 14 +- .../handlers/generate_from_impl_for_enum.rs | 2 +- .../src/handlers/generate_function.rs | 17 +- .../ide-assists/src/handlers/generate_new.rs | 6 +- .../generate_single_field_struct_from.rs | 4 +- .../ide-assists/src/handlers/inline_call.rs | 4 +- .../ide-assists/src/handlers/inline_macro.rs | 2 +- .../src/handlers/qualify_method_call.rs | 4 +- .../ide-assists/src/handlers/qualify_path.rs | 2 +- .../replace_derive_with_manual_impl.rs | 4 +- .../replace_qualified_name_with_use.rs | 2 +- .../ide-assists/src/handlers/term_search.rs | 2 +- .../src/handlers/toggle_async_sugar.rs | 2 +- .../crates/ide-completion/src/completions.rs | 2 +- .../src/completions/attribute/derive.rs | 2 +- .../src/completions/attribute/macro_use.rs | 2 +- .../crates/ide-completion/src/lib.rs | 2 +- .../ide-completion/src/render/variant.rs | 2 +- .../ide-completion/src/tests/flyimport.rs | 2 +- .../rust-analyzer/crates/ide-db/src/defs.rs | 8 +- .../crates/ide-db/src/famous_defs.rs | 2 +- .../crates/ide-db/src/helpers.rs | 2 +- .../ide-db/src/imports/import_assets.rs | 2 +- .../crates/ide-db/src/path_transform.rs | 6 +- .../rust-analyzer/crates/ide-db/src/rename.rs | 2 +- .../rust-analyzer/crates/ide-db/src/search.rs | 20 +- .../crates/ide-db/src/symbol_index.rs | 2 +- .../ide-db/src/test_data/test_doc_alias.txt | 22 +- .../test_symbol_index_collection.txt | 104 +++---- .../test_symbols_exclude_imports.txt | 2 +- .../test_data/test_symbols_with_imports.txt | 4 +- .../rust-analyzer/crates/ide-db/src/traits.rs | 2 +- .../src/handlers/missing_fields.rs | 4 +- .../src/handlers/private_field.rs | 2 +- .../trait_impl_redundant_assoc_item.rs | 2 +- .../src/handlers/unlinked_file.rs | 4 +- .../src/handlers/unresolved_field.rs | 2 +- .../crates/ide-diagnostics/src/lib.rs | 4 +- .../crates/ide/src/expand_macro.rs | 2 +- .../crates/ide/src/goto_definition.rs | 4 +- .../crates/ide/src/goto_implementation.rs | 2 +- .../crates/ide/src/hover/render.rs | 2 +- .../crates/ide/src/inlay_hints.rs | 2 +- .../rust-analyzer/crates/ide/src/interpret.rs | 2 +- .../rust-analyzer/crates/ide/src/moniker.rs | 9 +- .../crates/ide/src/navigation_target.rs | 8 +- .../rust-analyzer/crates/ide/src/runnables.rs | 6 +- .../crates/ide/src/static_index.rs | 2 +- .../ide/src/syntax_highlighting/highlight.rs | 4 +- .../test_data/highlight_block_mod_items.html | 2 +- .../ide/src/syntax_highlighting/tests.rs | 2 +- .../crates/ide/src/test_explorer.rs | 6 +- .../rust-analyzer/src/cli/analysis_stats.rs | 6 +- .../rust-analyzer/src/cli/diagnostics.rs | 10 +- .../crates/rust-analyzer/src/cli/run_tests.rs | 2 +- .../src/cli/unresolved_references.rs | 10 +- 135 files changed, 1025 insertions(+), 1188 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs index ab36b707f269..607638f32b4e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs @@ -45,8 +45,8 @@ use syntax::{ use tt::{TextRange, TextSize}; use crate::{ - AdtId, AstIdLoc, AttrDefId, FieldId, FunctionId, GenericDefId, HasModule, InternedModuleId, - LifetimeParamId, LocalFieldId, MacroId, TypeOrConstParamId, VariantId, + AdtId, AstIdLoc, AttrDefId, FieldId, FunctionId, GenericDefId, HasModule, LifetimeParamId, + LocalFieldId, MacroId, ModuleId, TypeOrConstParamId, VariantId, db::DefDatabase, hir::generics::{GenericParams, LocalLifetimeParamId, LocalTypeOrConstParamId}, nameres::ModuleOrigin, @@ -295,9 +295,8 @@ fn attrs_source( ) -> (InFile, Option>, Crate) { let (owner, krate) = match owner { AttrDefId::ModuleId(id) => { - let id = id.loc(db); let def_map = id.def_map(db); - let (definition, declaration) = match def_map[id.local_id].origin { + let (definition, declaration) = match def_map[id].origin { ModuleOrigin::CrateRoot { definition } => { let file = db.parse(definition).tree(); (InFile::new(definition.into(), ast::AnyHasAttrs::from(file)), None) @@ -318,7 +317,7 @@ fn attrs_source( (block.with_value(definition.into()), None) } }; - return (definition, declaration, id.krate); + return (definition, declaration, def_map.krate()); } AttrDefId::AdtId(AdtId::StructId(it)) => attrs_from_ast_id_loc(db, it), AttrDefId::AdtId(AdtId::UnionId(it)) => attrs_from_ast_id_loc(db, it), @@ -1201,14 +1200,14 @@ impl AttrFlags { } #[inline] - pub fn doc_keyword(db: &dyn DefDatabase, owner: InternedModuleId) -> Option { + pub fn doc_keyword(db: &dyn DefDatabase, owner: ModuleId) -> Option { if !AttrFlags::query(db, AttrDefId::ModuleId(owner)).contains(AttrFlags::HAS_DOC_KEYWORD) { return None; } return doc_keyword(db, owner); #[salsa::tracked] - fn doc_keyword(db: &dyn DefDatabase, owner: InternedModuleId) -> Option { + fn doc_keyword(db: &dyn DefDatabase, owner: ModuleId) -> Option { collect_attrs(db, AttrDefId::ModuleId(owner), |attr| { if let Meta::TokenTree { path, tt } = attr && path.is1("doc") diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index cc311a41dbf8..ccd4bc9be84a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -8,13 +8,12 @@ use la_arena::ArenaMap; use triomphe::Arc; use crate::{ - AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, CrateRootModuleId, DefWithBodyId, - EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, - ExternCrateLoc, FunctionId, FunctionLoc, GenericDefId, HasModule, ImplId, ImplLoc, - InternedModuleId, LocalFieldId, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, - MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, - StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, - VariantId, + AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, + EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, + FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, + MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, + ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, + TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, attrs::AttrFlags, expr_store::{ Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes, @@ -276,8 +275,8 @@ fn include_macro_invoc( } fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: Crate) -> bool { - let root_module = CrateRootModuleId::from(crate_id).module(db); - let attrs = AttrFlags::query(db, AttrDefId::ModuleId(InternedModuleId::new(db, root_module))); + let root_module = crate_def_map(db, crate_id).root_module_id(); + let attrs = AttrFlags::query(db, AttrDefId::ModuleId(root_module)); attrs.contains(AttrFlags::IS_NO_STD) } @@ -298,7 +297,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { let loc: Macro2Loc = it.lookup(db); MacroDefId { - krate: loc.container.krate, + krate: loc.container.krate(db), kind: kind(loc.expander, loc.id.file_id, loc.id.value.upcast()), local_inner: false, allow_internal_unsafe: loc.allow_internal_unsafe, @@ -309,7 +308,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { let loc: MacroRulesLoc = it.lookup(db); MacroDefId { - krate: loc.container.krate, + krate: loc.container.krate(db), kind: kind(loc.expander, loc.id.file_id, loc.id.value.upcast()), local_inner: loc.flags.contains(MacroRulesLocFlags::LOCAL_INNER), allow_internal_unsafe: loc @@ -322,7 +321,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { let loc = it.lookup(db); MacroDefId { - krate: loc.container.krate, + krate: loc.container.krate(db), kind: MacroDefKind::ProcMacro(loc.id, loc.expander, loc.kind), local_inner: false, allow_internal_unsafe: false, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 26a50b53251f..df4cff0b8a17 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -437,6 +437,7 @@ pub struct ExprCollector<'db> { current_binding_owner: Option, awaitable_context: Option, + krate: base_db::Crate, } #[derive(Clone, Debug)] @@ -524,9 +525,10 @@ impl<'db> ExprCollector<'db> { ) -> ExprCollector<'_> { let (def_map, local_def_map) = module.local_def_map(db); let expander = Expander::new(db, current_file_id, def_map); + let krate = module.krate(db); ExprCollector { db, - cfg_options: module.krate().cfg_options(db), + cfg_options: krate.cfg_options(db), module, def_map, local_def_map, @@ -540,12 +542,13 @@ impl<'db> ExprCollector<'db> { awaitable_context: None, current_block_legacy_macro_defs_count: FxHashMap::default(), outer_impl_trait: false, + krate, } } #[inline] pub(crate) fn lang_items(&self) -> &'db LangItems { - self.lang_items.get_or_init(|| crate::lang_item::lang_items(self.db, self.module.krate)) + self.lang_items.get_or_init(|| crate::lang_item::lang_items(self.db, self.def_map.krate())) } #[inline] @@ -1915,9 +1918,8 @@ impl<'db> ExprCollector<'db> { T: ast::AstNode, { let macro_call_ptr = self.expander.in_file(syntax_ptr); - let module = self.module.local_id; - let block_call = self.def_map.modules[self.module.local_id].scope.macro_invoc( + let block_call = self.def_map.modules[self.module].scope.macro_invoc( self.expander.in_file(self.expander.ast_id_map().ast_id_for_ptr(syntax_ptr)), ); let res = match block_call { @@ -1929,7 +1931,7 @@ impl<'db> ExprCollector<'db> { .resolve_path( self.local_def_map, self.db, - module, + self.module, path, crate::item_scope::BuiltinShadowMode::Other, Some(MacroSubNs::Bang), @@ -1940,7 +1942,7 @@ impl<'db> ExprCollector<'db> { self.expander.enter_expand( self.db, mcall, - self.module.krate(), + self.krate, resolver, &mut |ptr, call| { _ = self.store.expansions.insert(ptr.map(|(it, _)| it), call); @@ -2058,7 +2060,8 @@ impl<'db> ExprCollector<'db> { return; }; let name = name.as_name(); - let macro_id = self.def_map.modules[DefMap::ROOT].scope.get(&name).take_macros(); + let macro_id = + self.def_map.modules[self.def_map.root].scope.get(&name).take_macros(); self.collect_macro_def(statements, macro_id); } ast::Stmt::Item(ast::Item::MacroRules(macro_)) => { @@ -2072,7 +2075,7 @@ impl<'db> ExprCollector<'db> { let name = name.as_name(); let macro_defs_count = self.current_block_legacy_macro_defs_count.entry(name.clone()).or_insert(0); - let macro_id = self.def_map.modules[DefMap::ROOT] + let macro_id = self.def_map.modules[self.def_map.root] .scope .get_legacy_macro(&name) .and_then(|it| it.get(*macro_defs_count)) @@ -2118,7 +2121,7 @@ impl<'db> ExprCollector<'db> { match block_id.map(|block_id| (block_def_map(self.db, block_id), block_id)) { Some((def_map, block_id)) => { self.store.block_scopes.push(block_id); - (def_map.module_id(DefMap::ROOT), def_map) + (def_map.root_module_id(), def_map) } None => (self.module, self.def_map), }; @@ -2201,7 +2204,7 @@ impl<'db> ExprCollector<'db> { let (resolved, _) = self.def_map.resolve_path( self.local_def_map, self.db, - self.module.local_id, + self.module, &name.clone().into(), BuiltinShadowMode::Other, None, @@ -3131,7 +3134,7 @@ impl<'db> ExprCollector<'db> { let precision_expr = self.make_count(precision, argmap); let width_expr = self.make_count(width, argmap); - if self.module.krate().workspace_data(self.db).is_atleast_187() { + if self.krate.workspace_data(self.db).is_atleast_187() { // These need to match the constants in library/core/src/fmt/rt.rs. let align = match alignment { Some(FormatAlignment::Left) => 0, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs index 4a775568bc22..22ade4387582 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs @@ -32,14 +32,14 @@ fn def_map_at(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String { let (db, position) = TestDB::with_position(ra_fixture); let module = db.module_at_position(position); - module.def_map(&db).dump(&db) + salsa::plumbing::attach(&db, || module.def_map(&db).dump(&db)) } fn check_block_scopes_at(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let (db, position) = TestDB::with_position(ra_fixture); let module = db.module_at_position(position); - let actual = module.def_map(&db).dump_block_scopes(&db); + let actual = salsa::plumbing::attach(&db, || format!("{module:#?}")); expect.assert_eq(&actual); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs index 4501ff4df5e7..836a079e777f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs @@ -189,10 +189,17 @@ fn f() { } "#, expect![[r#" - BlockId(3801) in BlockRelativeModuleId { block: Some(BlockId(3800)), local_id: Idx::(1) } - BlockId(3800) in BlockRelativeModuleId { block: None, local_id: Idx::(0) } - crate scope - "#]], + ModuleIdLt { + [salsa id]: Id(3003), + krate: Crate( + Id(1c00), + ), + block: Some( + BlockId( + 3c01, + ), + ), + }"#]], ); } @@ -460,7 +467,7 @@ fn foo() { } #[test] -fn is_visible_from_same_def_map() { +fn is_visible_from_same_def_map_regression_9481() { // Regression test for https://github.com/rust-lang/rust-analyzer/issues/9481 check_at( r#" @@ -478,7 +485,6 @@ fn outer() { - tests : type (block scope)::tests - - name : _ - outer : value (glob) crate diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index e8a6ebcffa0a..5d1cac8e93c4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -39,20 +39,23 @@ pub fn find_path( // within block modules, forcing a `self` or `crate` prefix will not allow using inner items, so // default to plain paths. let item_module = item.module(db)?; - if item_module.is_within_block() { + if item_module.block(db).is_some() { prefix_kind = PrefixKind::Plain; } - cfg.prefer_no_std = cfg.prefer_no_std || db.crate_supports_no_std(from.krate()); + cfg.prefer_no_std = cfg.prefer_no_std || db.crate_supports_no_std(from.krate(db)); + let from_def_map = from.def_map(db); find_path_inner( &FindPathCtx { db, prefix: prefix_kind, cfg, ignore_local_imports, - is_std_item: item_module.krate().data(db).origin.is_lang(), + is_std_item: item_module.krate(db).data(db).origin.is_lang(), from, - from_def_map: from.def_map(db), + from_crate: from.krate(db), + crate_root: from_def_map.crate_root(db), + from_def_map, fuel: Cell::new(FIND_PATH_FUEL), }, item, @@ -100,6 +103,8 @@ struct FindPathCtx<'db> { ignore_local_imports: bool, is_std_item: bool, from: ModuleId, + from_crate: Crate, + crate_root: ModuleId, from_def_map: &'db DefMap, fuel: Cell, } @@ -116,7 +121,7 @@ fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Opt let may_be_in_scope = match ctx.prefix { PrefixKind::Plain | PrefixKind::BySelf => true, - PrefixKind::ByCrate => ctx.from.is_crate_root(), + PrefixKind::ByCrate => ctx.crate_root == ctx.from, }; if may_be_in_scope { // - if the item is already in scope, return the name under which it is @@ -163,8 +168,9 @@ fn find_path_for_module( // recursive base case, we can't find a path of length 0 return None; } - if let Some(crate_root) = module_id.as_crate_root() { - if !maybe_extern || crate_root == ctx.from.derive_crate_root() { + let module_crate_root = module_id.def_map(ctx.db).crate_root(ctx.db); + if module_crate_root == module_id { + if !maybe_extern || module_crate_root == ctx.crate_root { // - if the item is the crate root, return `crate` return Some(Choice { path: ModPath::from_segments(PathKind::Crate, None), @@ -175,19 +181,19 @@ fn find_path_for_module( } // - otherwise if the item is the crate root of a dependency crate, return the name from the extern prelude - let root_local_def_map = ctx.from.derive_crate_root().local_def_map(ctx.db).1; + let root_local_def_map = ctx.crate_root.local_def_map(ctx.db).1; // rev here so we prefer looking at renamed extern decls first for (name, (def_id, _extern_crate)) in root_local_def_map.extern_prelude().rev() { - if crate_root != def_id { + if module_crate_root != def_id { continue; } let name_already_occupied_in_type_ns = ctx .from_def_map - .with_ancestor_maps(ctx.db, ctx.from.local_id, &mut |def_map, local_id| { + .with_ancestor_maps(ctx.db, ctx.from, &mut |def_map, local_id| { def_map[local_id] .scope .type_(name) - .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id.into())) + .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id)) }) .is_some(); let kind = if name_already_occupied_in_type_ns { @@ -204,7 +210,7 @@ fn find_path_for_module( let may_be_in_scope = match ctx.prefix { PrefixKind::Plain | PrefixKind::BySelf => true, - PrefixKind::ByCrate => ctx.from.is_crate_root(), + PrefixKind::ByCrate => ctx.crate_root == ctx.from, }; if may_be_in_scope { let scope_name = find_in_scope( @@ -226,7 +232,7 @@ fn find_path_for_module( } // - if the module can be referenced as self, super or crate, do that - if let Some(kind) = is_kw_kind_relative_to_from(ctx.from_def_map, module_id, ctx.from) + if let Some(kind) = is_kw_kind_relative_to_from(ctx.db, ctx.from_def_map, module_id, ctx.from) && (ctx.prefix != PrefixKind::ByCrate || kind == PathKind::Crate) { return Some(Choice { @@ -259,7 +265,7 @@ fn find_in_scope( ignore_local_imports: bool, ) -> Option { // FIXME: We could have multiple applicable names here, but we currently only return the first - def_map.with_ancestor_maps(db, from.local_id, &mut |def_map, local_id| { + def_map.with_ancestor_maps(db, from, &mut |def_map, local_id| { def_map[local_id].scope.names_of(item, |name, _, declared| { (declared || !ignore_local_imports).then(|| name.clone()) }) @@ -276,7 +282,7 @@ fn find_in_prelude( ) -> Option { let (prelude_module, _) = local_def_map.prelude()?; let prelude_def_map = prelude_module.def_map(db); - let prelude_scope = &prelude_def_map[prelude_module.local_id].scope; + let prelude_scope = &prelude_def_map[prelude_module].scope; let (name, vis, _declared) = prelude_scope.name_of(item)?; if !vis.is_visible_from(db, from) { return None; @@ -284,7 +290,7 @@ fn find_in_prelude( // Check if the name is in current scope and it points to the same def. let found_and_same_def = - local_def_map.with_ancestor_maps(db, from.local_id, &mut |def_map, local_id| { + local_def_map.with_ancestor_maps(db, from, &mut |def_map, local_id| { let per_ns = def_map[local_id].scope.get(name); let same_def = match item { ItemInNs::Types(it) => per_ns.take_types()? == it, @@ -302,22 +308,21 @@ fn find_in_prelude( } fn is_kw_kind_relative_to_from( + db: &dyn DefDatabase, def_map: &DefMap, item: ModuleId, from: ModuleId, ) -> Option { - if item.krate != from.krate || item.is_within_block() || from.is_within_block() { + if item.krate(db) != from.krate(db) || item.block(db).is_some() || from.block(db).is_some() { return None; } - let item = item.local_id; - let from = from.local_id; if item == from { // - if the item is the module we're in, use `self` Some(PathKind::SELF) } else if let Some(parent_id) = def_map[from].parent { if item == parent_id { // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly) - Some(if parent_id == DefMap::ROOT { PathKind::Crate } else { PathKind::Super(1) }) + Some(if parent_id == def_map.root { PathKind::Crate } else { PathKind::Super(1) }) } else { None } @@ -340,13 +345,13 @@ fn calculate_best_path( tracing::warn!( "ran out of fuel while searching for a path for item {item:?} of krate {:?} from krate {:?}", item.krate(ctx.db), - ctx.from.krate() + ctx.from_crate ); return; } ctx.fuel.set(fuel - 1); - if item.krate(ctx.db) == Some(ctx.from.krate) { + if item.krate(ctx.db) == Some(ctx.from_crate) { // Item was defined in the same crate that wants to import it. It cannot be found in any // dependency in this case. calculate_best_path_local(ctx, visited_modules, item, max_len, best_choice) @@ -361,7 +366,7 @@ fn calculate_best_path( // too (unless we can't name it at all). It could *also* be (re)exported by the same crate // that wants to import it here, but we always prefer to use the external path here. - ctx.from.krate.data(ctx.db).dependencies.iter().for_each(|dep| { + ctx.from_crate.data(ctx.db).dependencies.iter().for_each(|dep| { find_in_dep(ctx, visited_modules, item, max_len, best_choice, dep.crate_id) }); } @@ -374,7 +379,7 @@ fn find_in_sysroot( max_len: usize, best_choice: &mut Option, ) { - let dependencies = &ctx.from.krate.data(ctx.db).dependencies; + let dependencies = &ctx.from_crate.data(ctx.db).dependencies; let mut search = |lang, best_choice: &mut _| { if let Some(dep) = dependencies.iter().filter(|it| it.is_sysroot()).find(|dep| { match dep.crate_id.data(ctx.db).origin { @@ -464,26 +469,19 @@ fn calculate_best_path_local( best_choice: &mut Option, ) { // FIXME: cache the `find_local_import_locations` output? - find_local_import_locations( - ctx.db, - item, - ctx.from, - ctx.from_def_map, - visited_modules, - |visited_modules, name, module_id| { - // we are looking for paths of length up to best_path_len, any longer will make it be - // less optimal. The -1 is due to us pushing name onto it afterwards. - if let Some(choice) = find_path_for_module( - ctx, - visited_modules, - module_id, - false, - best_choice.as_ref().map_or(max_len, |it| it.path.len()) - 1, - ) { - Choice::try_select(best_choice, choice, ctx.cfg.prefer_prelude, name.clone()); - } - }, - ); + find_local_import_locations(ctx, item, visited_modules, |visited_modules, name, module_id| { + // we are looking for paths of length up to best_path_len, any longer will make it be + // less optimal. The -1 is due to us pushing name onto it afterwards. + if let Some(choice) = find_path_for_module( + ctx, + visited_modules, + module_id, + false, + best_choice.as_ref().map_or(max_len, |it| it.path.len()) - 1, + ) { + Choice::try_select(best_choice, choice, ctx.cfg.prefer_prelude, name.clone()); + } + }); } #[derive(Debug)] @@ -561,14 +559,13 @@ fn path_kind_len(kind: PathKind) -> usize { /// Finds locations in `from.krate` from which `item` can be imported by `from`. fn find_local_import_locations( - db: &dyn DefDatabase, + ctx: &FindPathCtx<'_>, item: ItemInNs, - from: ModuleId, - def_map: &DefMap, visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, mut cb: impl FnMut(&mut FxHashSet<(ItemInNs, ModuleId)>, &Name, ModuleId), ) { let _p = tracing::info_span!("find_local_import_locations").entered(); + let db = ctx.db; // `from` can import anything below `from` with visibility of at least `from`, and anything // above `from` with any visibility. That means we do not need to descend into private siblings @@ -576,15 +573,16 @@ fn find_local_import_locations( // Compute the initial worklist. We start with all direct child modules of `from` as well as all // of its (recursive) parent modules. - let mut worklist = def_map[from.local_id] + let mut worklist = ctx.from_def_map[ctx.from] .children .values() - .map(|&child| def_map.module_id(child)) - .chain(iter::successors(from.containing_module(db), |m| m.containing_module(db))) + .copied() + .chain(iter::successors(ctx.from.containing_module(db), |m| m.containing_module(db))) .zip(iter::repeat(false)) .collect::>(); - let def_map = def_map.crate_root().def_map(db); + let def_map = + if ctx.crate_root == ctx.from { ctx.from_def_map } else { ctx.crate_root.def_map(db) }; let mut block_def_map; let mut cursor = 0; @@ -595,17 +593,17 @@ fn find_local_import_locations( continue; } *processed = true; - let data = if module.block.is_some() { + let data = if module.block(db).is_some() { // Re-query the block's DefMap block_def_map = module.def_map(db); - &block_def_map[module.local_id] + &block_def_map[module] } else { // Reuse the root DefMap - &def_map[module.local_id] + &def_map[module] }; if let Some((name, vis, declared)) = data.scope.name_of(item) - && vis.is_visible_from(db, from) + && vis.is_visible_from(db, ctx.from) { let is_pub_or_explicit = match vis { Visibility::Module(_, VisibilityExplicitness::Explicit) => { @@ -632,7 +630,7 @@ fn find_local_import_locations( // Descend into all modules visible from `from`. for (module, vis) in data.scope.modules_in_scope() { - if module.krate != from.krate { + if module.krate(db) != ctx.from.krate(db) { // We don't need to look at modules from other crates as our item has to be in the // current crate continue; @@ -641,7 +639,7 @@ fn find_local_import_locations( continue; } - if vis.is_visible_from(db, from) { + if vis.is_visible_from(db, ctx.from) { worklist.push((module, false)); } } @@ -694,7 +692,7 @@ mod tests { .resolve_path( local_def_map, &db, - module.local_id, + module, &mod_path, crate::item_scope::BuiltinShadowMode::Module, None, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 67cf466276c5..6c5d226cac1b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -13,11 +13,11 @@ use stdx::format_to; use triomphe::Arc; use crate::{ - AssocItemId, AttrDefId, Complete, FxIndexMap, InternedModuleId, ModuleDefId, ModuleId, TraitId, + AssocItemId, AttrDefId, Complete, FxIndexMap, ModuleDefId, ModuleId, TraitId, attrs::AttrFlags, db::DefDatabase, item_scope::{ImportOrExternCrate, ItemInNs}, - nameres::{DefMap, assoc::TraitItems, crate_def_map}, + nameres::{assoc::TraitItems, crate_def_map}, visibility::Visibility, }; @@ -134,7 +134,7 @@ impl ImportMap { let mut map = FxIndexMap::default(); // We look only into modules that are public(ly reexported), starting with the crate root. - let root = def_map.module_id(DefMap::ROOT); + let root = def_map.root_module_id(); let mut worklist = vec![root]; let mut visited = FxHashSet::default(); @@ -142,13 +142,11 @@ impl ImportMap { if !visited.insert(module) { continue; } - let ext_def_map; - let mod_data = if module.krate == krate { - &def_map[module.local_id] + let mod_data = if module.krate(db) == krate { + &def_map[module] } else { // The crate might reexport a module defined in another crate. - ext_def_map = module.def_map(db); - &ext_def_map[module.local_id] + &module.def_map(db)[module] }; let visible_items = mod_data.scope.entries().filter_map(|(name, per_ns)| { @@ -167,9 +165,7 @@ impl ImportMap { } else { match item { ItemInNs::Types(id) | ItemInNs::Values(id) => match id { - ModuleDefId::ModuleId(it) => { - Some(AttrDefId::ModuleId(InternedModuleId::new(db, it))) - } + ModuleDefId::ModuleId(it) => Some(AttrDefId::ModuleId(it)), ModuleDefId::FunctionId(it) => Some(it.into()), ModuleDefId::AdtId(it) => Some(it.into()), ModuleDefId::EnumVariantId(it) => Some(it.into()), @@ -640,9 +636,8 @@ mod tests { assert!(def_map.block_id().is_none(), "block local items should not be in `ImportMap`"); while let Some(parent) = module.containing_module(db) { - let parent_data = &def_map[parent.local_id]; - let (name, _) = - parent_data.children.iter().find(|(_, id)| **id == module.local_id).unwrap(); + let parent_data = &def_map[parent]; + let (name, _) = parent_data.children.iter().find(|(_, id)| **id == module).unwrap(); segments.push(name); module = parent; } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index 1bfe649ebdf9..3ffeebfaf2c9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -17,7 +17,7 @@ use thin_vec::ThinVec; use crate::{ AdtId, BuiltinType, ConstId, ExternBlockId, ExternCrateId, FxIndexMap, HasModule, ImplId, - LocalModuleId, Lookup, MacroCallStyles, MacroId, ModuleDefId, ModuleId, TraitId, UseId, + Lookup, MacroCallStyles, MacroId, ModuleDefId, ModuleId, TraitId, UseId, db::DefDatabase, per_ns::{Item, MacrosItem, PerNs, TypesItem, ValuesItem}, visibility::Visibility, @@ -25,9 +25,9 @@ use crate::{ #[derive(Debug, Default)] pub struct PerNsGlobImports { - types: FxHashSet<(LocalModuleId, Name)>, - values: FxHashSet<(LocalModuleId, Name)>, - macros: FxHashSet<(LocalModuleId, Name)>, + types: FxHashSet<(ModuleId, Name)>, + values: FxHashSet<(ModuleId, Name)>, + macros: FxHashSet<(ModuleId, Name)>, } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -133,13 +133,13 @@ pub struct GlobId { } impl PerNsGlobImports { - pub(crate) fn contains_type(&self, module_id: LocalModuleId, name: Name) -> bool { + pub(crate) fn contains_type(&self, module_id: ModuleId, name: Name) -> bool { self.types.contains(&(module_id, name)) } - pub(crate) fn contains_value(&self, module_id: LocalModuleId, name: Name) -> bool { + pub(crate) fn contains_value(&self, module_id: ModuleId, name: Name) -> bool { self.values.contains(&(module_id, name)) } - pub(crate) fn contains_macro(&self, module_id: LocalModuleId, name: Name) -> bool { + pub(crate) fn contains_macro(&self, module_id: ModuleId, name: Name) -> bool { self.macros.contains(&(module_id, name)) } } @@ -261,14 +261,12 @@ impl ItemScope { pub fn fully_resolve_import(&self, db: &dyn DefDatabase, mut import: ImportId) -> PerNs { let mut res = PerNs::none(); - let mut def_map; let mut scope = self; while let Some(&m) = scope.use_imports_macros.get(&ImportOrExternCrate::Import(import)) { match m { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; - def_map = module_id.def_map(db); - scope = &def_map[module_id.local_id].scope; + scope = &module_id.def_map(db)[module_id].scope; import = i; } ImportOrDef::Def(ModuleDefId::MacroId(def)) => { @@ -283,8 +281,7 @@ impl ItemScope { match m { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; - def_map = module_id.def_map(db); - scope = &def_map[module_id.local_id].scope; + scope = &module_id.def_map(db)[module_id].scope; import = i; } ImportOrDef::Def(def) => { @@ -299,8 +296,7 @@ impl ItemScope { match m { ImportOrDef::Import(i) => { let module_id = i.use_.lookup(db).container; - def_map = module_id.def_map(db); - scope = &def_map[module_id.local_id].scope; + scope = &module_id.def_map(db)[module_id].scope; import = i; } ImportOrDef::Def(def) => { @@ -578,7 +574,7 @@ impl ItemScope { pub(crate) fn push_res_with_import( &mut self, glob_imports: &mut PerNsGlobImports, - lookup: (LocalModuleId, Name), + lookup: (ModuleId, Name), def: PerNs, import: Option, ) -> bool { @@ -922,10 +918,7 @@ impl ItemInNs { /// Returns the crate defining this item (or `None` if `self` is built-in). pub fn krate(&self, db: &dyn DefDatabase) -> Option { - match self { - ItemInNs::Types(id) | ItemInNs::Values(id) => id.module(db).map(|m| m.krate), - ItemInNs::Macros(id) => Some(id.module(db).krate), - } + self.module(db).map(|module_id| module_id.krate(db)) } pub fn module(&self, db: &dyn DefDatabase) -> Option { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 04acb8b712db..9fdfb5f5b32e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -111,11 +111,12 @@ pub fn lang_items(db: &dyn DefDatabase, start_crate: Crate) -> LangItems { // while nameres. // // See https://github.com/rust-lang/rust-analyzer/pull/20475 for details. - for (_, (krate, _)) in crate_local_def_map(db, start_crate).local(db).extern_prelude() { + for (_, (module, _)) in crate_local_def_map(db, start_crate).local(db).extern_prelude() { // Some crates declares themselves as extern crate like `extern crate self as core`. // Ignore these to prevent cycles. - if krate.krate != start_crate { - result.merge_prefer_self(lang_items(db, krate.krate)); + let krate = module.krate(db); + if krate != start_crate { + result.merge_prefer_self(lang_items(db, krate)); } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index ad247e0d6897..97af8ad93def 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -71,7 +71,6 @@ use hir_expand::{ name::Name, proc_macro::{CustomProcMacroExpander, ProcMacroKind}, }; -use la_arena::Idx; use nameres::DefMap; use span::{AstIdNode, Edition, FileAstId, SyntaxContext}; use stdx::impl_from; @@ -412,14 +411,14 @@ pub enum MacroExpander { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ProcMacroLoc { - pub container: CrateRootModuleId, + pub container: ModuleId, pub id: AstId, pub expander: CustomProcMacroExpander, pub kind: ProcMacroKind, pub edition: Edition, } impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro); -impl_loc!(ProcMacroLoc, id: Fn, container: CrateRootModuleId); +impl_loc!(ProcMacroLoc, id: Fn, container: ModuleId); #[derive(Debug, Hash, PartialEq, Eq, Clone)] pub struct BlockLoc { @@ -429,164 +428,75 @@ pub struct BlockLoc { } impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block); -/// A `ModuleId` that is always a crate's root module. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct CrateRootModuleId { - krate: Crate, -} - -impl CrateRootModuleId { - pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap { - crate_def_map(db, self.krate) - } - - pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) { - let def_map = crate_local_def_map(db, self.krate); - (def_map.def_map(db), def_map.local(db)) - } - - pub fn krate(self) -> Crate { - self.krate - } -} - -impl HasModule for CrateRootModuleId { - #[inline] - fn module(&self, _db: &dyn DefDatabase) -> ModuleId { - ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT } - } - - #[inline] - fn krate(&self, _db: &dyn DefDatabase) -> Crate { - self.krate - } -} - -impl PartialEq for CrateRootModuleId { - fn eq(&self, other: &ModuleId) -> bool { - other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate - } -} -impl PartialEq for ModuleId { - fn eq(&self, other: &CrateRootModuleId) -> bool { - other == self - } -} - -impl From for ModuleId { - fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self { - ModuleId { krate, block: None, local_id: DefMap::ROOT } - } -} - -impl From for ModuleDefId { - fn from(value: CrateRootModuleId) -> Self { - ModuleDefId::ModuleId(value.into()) - } -} - -impl From for CrateRootModuleId { - fn from(krate: Crate) -> Self { - CrateRootModuleId { krate } - } -} - -impl TryFrom for CrateRootModuleId { - type Error = (); - - fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result { - if block.is_none() && local_id == DefMap::ROOT { - Ok(CrateRootModuleId { krate }) - } else { - Err(()) - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct ModuleId { - krate: Crate, +#[salsa_macros::tracked(debug)] +#[derive(PartialOrd, Ord)] +pub struct ModuleIdLt<'db> { + /// The crate this module belongs to. + pub krate: Crate, /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the /// `BlockId` of that block expression. If `None`, this module is part of the crate-level /// `DefMap` of `krate`. - block: Option, - /// The module's ID in its originating `DefMap`. - pub local_id: LocalModuleId, + pub block: Option, } +pub type ModuleId = ModuleIdLt<'static>; +impl ModuleIdLt<'_> { + /// # Safety + /// + /// The caller must ensure that the `ModuleId` is not leaked outside of query computations. + pub unsafe fn to_static(self) -> ModuleId { + unsafe { std::mem::transmute(self) } + } +} impl ModuleId { + /// # Safety + /// + /// The caller must ensure that the `ModuleId` comes from the given database. + pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> { + unsafe { std::mem::transmute(self) } + } + pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap { - match self.block { + match self.block(db) { Some(block) => block_def_map(db, block), - None => crate_def_map(db, self.krate), + None => crate_def_map(db, self.krate(db)), } } pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) { - match self.block { + match self.block(db) { Some(block) => (block_def_map(db, block), self.only_local_def_map(db)), None => { - let def_map = crate_local_def_map(db, self.krate); + let def_map = crate_local_def_map(db, self.krate(db)); (def_map.def_map(db), def_map.local(db)) } } } pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> &LocalDefMap { - crate_local_def_map(db, self.krate).local(db) + crate_local_def_map(db, self.krate(db)).local(db) } pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap { - crate_def_map(db, self.krate) - } - - pub fn krate(self) -> Crate { - self.krate + crate_def_map(db, self.krate(db)) } pub fn name(self, db: &dyn DefDatabase) -> Option { let def_map = self.def_map(db); - let parent = def_map[self.local_id].parent?; + let parent = def_map[self].parent?; def_map[parent].children.iter().find_map(|(name, module_id)| { - if *module_id == self.local_id { Some(name.clone()) } else { None } + if *module_id == self { Some(name.clone()) } else { None } }) } /// Returns the module containing `self`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. pub fn containing_module(self, db: &dyn DefDatabase) -> Option { - self.def_map(db).containing_module(self.local_id) + self.def_map(db).containing_module(self) } - pub fn containing_block(self) -> Option { - self.block - } - - pub fn is_block_module(self) -> bool { - self.block.is_some() && self.local_id == DefMap::ROOT - } - - pub fn is_within_block(self) -> bool { - self.block.is_some() - } - - /// Returns the [`CrateRootModuleId`] for this module if it is the crate root module. - pub fn as_crate_root(&self) -> Option { - if self.local_id == DefMap::ROOT && self.block.is_none() { - Some(CrateRootModuleId { krate: self.krate }) - } else { - None - } - } - - /// Returns the [`CrateRootModuleId`] for this module. - pub fn derive_crate_root(&self) -> CrateRootModuleId { - CrateRootModuleId { krate: self.krate } - } - - /// Whether this module represents the crate root module - pub fn is_crate_root(&self) -> bool { - self.local_id == DefMap::ROOT && self.block.is_none() + pub fn is_block_module(self, db: &dyn DefDatabase) -> bool { + self.block(db).is_some() && self.def_map(db).root_module_id() == self } } @@ -597,9 +507,6 @@ impl HasModule for ModuleId { } } -/// An ID of a module, **local** to a `DefMap`. -pub type LocalModuleId = Idx; - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)] pub struct FieldId { // FIXME: Store this as an erased `salsa::Id` to save space @@ -682,7 +589,7 @@ pub struct LifetimeParamId { pub local_id: LocalLifetimeParamId, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum ItemContainerId { ExternBlockId(ExternBlockId), ModuleId(ModuleId), @@ -956,16 +863,9 @@ impl CallableDefId { } } -// FIXME: We probably should use this in more places. -/// This is used to avoid interning the whole `AttrDefId`, so we intern just modules and not everything. -#[salsa_macros::interned(debug, no_lifetime)] -pub struct InternedModuleId { - pub loc: ModuleId, -} - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum AttrDefId { - ModuleId(InternedModuleId), + ModuleId(ModuleId), AdtId(AdtId), FunctionId(FunctionId), EnumVariantId(EnumVariantId), @@ -1058,7 +958,7 @@ pub trait HasModule { #[inline] #[doc(alias = "crate")] fn krate(&self, db: &dyn DefDatabase) -> Crate { - self.module(db).krate + self.module(db).krate(db) } } @@ -1162,7 +1062,7 @@ impl HasModule for Macro2Id { impl HasModule for ProcMacroId { #[inline] fn module(&self, db: &dyn DefDatabase) -> ModuleId { - self.lookup(db).container.into() + self.lookup(db).container } } @@ -1235,7 +1135,7 @@ impl HasModule for GenericDefId { impl HasModule for AttrDefId { fn module(&self, db: &dyn DefDatabase) -> ModuleId { match self { - AttrDefId::ModuleId(it) => it.loc(db), + AttrDefId::ModuleId(it) => *it, AttrDefId::AdtId(it) => it.module(db), AttrDefId::FunctionId(it) => it.module(db), AttrDefId::EnumVariantId(it) => it.module(db), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs index 947a54f88862..a12674f353c8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs @@ -35,9 +35,9 @@ macro_rules! f { }; } -struct#0:MacroRules[BE8F, 0]@58..64#14336# MyTraitMap2#0:MacroCall[BE8F, 0]@31..42#ROOT2024# {#0:MacroRules[BE8F, 0]@72..73#14336# - map#0:MacroRules[BE8F, 0]@86..89#14336#:#0:MacroRules[BE8F, 0]@89..90#14336# #0:MacroRules[BE8F, 0]@89..90#14336#::#0:MacroRules[BE8F, 0]@91..93#14336#std#0:MacroRules[BE8F, 0]@93..96#14336#::#0:MacroRules[BE8F, 0]@96..98#14336#collections#0:MacroRules[BE8F, 0]@98..109#14336#::#0:MacroRules[BE8F, 0]@109..111#14336#HashSet#0:MacroRules[BE8F, 0]@111..118#14336#<#0:MacroRules[BE8F, 0]@118..119#14336#(#0:MacroRules[BE8F, 0]@119..120#14336#)#0:MacroRules[BE8F, 0]@120..121#14336#>#0:MacroRules[BE8F, 0]@121..122#14336#,#0:MacroRules[BE8F, 0]@122..123#14336# -}#0:MacroRules[BE8F, 0]@132..133#14336# +struct#0:MacroRules[BE8F, 0]@58..64#15360# MyTraitMap2#0:MacroCall[BE8F, 0]@31..42#ROOT2024# {#0:MacroRules[BE8F, 0]@72..73#15360# + map#0:MacroRules[BE8F, 0]@86..89#15360#:#0:MacroRules[BE8F, 0]@89..90#15360# #0:MacroRules[BE8F, 0]@89..90#15360#::#0:MacroRules[BE8F, 0]@91..93#15360#std#0:MacroRules[BE8F, 0]@93..96#15360#::#0:MacroRules[BE8F, 0]@96..98#15360#collections#0:MacroRules[BE8F, 0]@98..109#15360#::#0:MacroRules[BE8F, 0]@109..111#15360#HashSet#0:MacroRules[BE8F, 0]@111..118#15360#<#0:MacroRules[BE8F, 0]@118..119#15360#(#0:MacroRules[BE8F, 0]@119..120#15360#)#0:MacroRules[BE8F, 0]@120..121#15360#>#0:MacroRules[BE8F, 0]@121..122#15360#,#0:MacroRules[BE8F, 0]@122..123#15360# +}#0:MacroRules[BE8F, 0]@132..133#15360# "#]], ); } @@ -197,7 +197,7 @@ macro_rules! mk_struct { #[macro_use] mod foo; -struct#1:MacroRules[DB0C, 0]@59..65#14336# Foo#0:MacroCall[DB0C, 0]@32..35#ROOT2024#(#1:MacroRules[DB0C, 0]@70..71#14336#u32#0:MacroCall[DB0C, 0]@41..44#ROOT2024#)#1:MacroRules[DB0C, 0]@74..75#14336#;#1:MacroRules[DB0C, 0]@75..76#14336# +struct#1:MacroRules[DB0C, 0]@59..65#15360# Foo#0:MacroCall[DB0C, 0]@32..35#ROOT2024#(#1:MacroRules[DB0C, 0]@70..71#15360#u32#0:MacroCall[DB0C, 0]@41..44#ROOT2024#)#1:MacroRules[DB0C, 0]@74..75#15360#;#1:MacroRules[DB0C, 0]@75..76#15360# "#]], ); } @@ -423,10 +423,10 @@ m! { foo, bar } macro_rules! m { ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } ); } -impl#\14336# Bar#\14336# {#\14336# - fn#\14336# foo#\ROOT2024#(#\14336#)#\14336# {#\14336#}#\14336# - fn#\14336# bar#\ROOT2024#(#\14336#)#\14336# {#\14336#}#\14336# -}#\14336# +impl#\15360# Bar#\15360# {#\15360# + fn#\15360# foo#\ROOT2024#(#\15360#)#\15360# {#\15360#}#\15360# + fn#\15360# bar#\ROOT2024#(#\15360#)#\15360# {#\15360#}#\15360# +}#\15360# "#]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index 98b3115814d4..78af976e1b13 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -131,8 +131,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream let db = TestDB::with_files_extra_proc_macros(ra_fixture, extra_proc_macros); let krate = db.fetch_test_crate(); let def_map = crate_def_map(&db, krate); - let local_id = DefMap::ROOT; - let source = def_map[local_id].definition_source(&db); + let source = def_map[def_map.root].definition_source(&db); let source_file = match source.value { ModuleSource::SourceFile(it) => it, ModuleSource::Module(_) | ModuleSource::BlockExpr(_) => panic!(), @@ -209,7 +208,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream expanded_text.replace_range(range, &text); } - for decl_id in def_map[local_id].scope.declarations() { + for decl_id in def_map[def_map.root].scope.declarations() { // FIXME: I'm sure there's already better way to do this let src = match decl_id { ModuleDefId::AdtId(AdtId::StructId(struct_id)) => { @@ -260,7 +259,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream } } - for impl_id in def_map[local_id].scope.impls() { + for impl_id in def_map[def_map.root].scope.impls() { let src = impl_id.lookup(&db).source(&db); if let Some(macro_file) = src.file_id.macro_file() && let MacroKind::DeriveBuiltIn | MacroKind::Derive = macro_file.kind(&db) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index aefbf6306e70..3f29619bcb62 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -58,7 +58,7 @@ pub mod proc_macro; #[cfg(test)] mod tests; -use std::ops::Deref; +use std::ops::{Deref, DerefMut, Index, IndexMut}; use base_db::Crate; use hir_expand::{ @@ -67,7 +67,6 @@ use hir_expand::{ }; use intern::Symbol; use itertools::Itertools; -use la_arena::Arena; use rustc_hash::{FxHashMap, FxHashSet}; use span::{Edition, FileAstId, FileId, ROOT_ERASED_FILE_AST_ID}; use stdx::format_to; @@ -76,8 +75,8 @@ use triomphe::Arc; use tt::TextRange; use crate::{ - AstId, BlockId, BlockLoc, CrateRootModuleId, ExternCrateId, FunctionId, FxIndexMap, - LocalModuleId, Lookup, MacroCallStyles, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId, + AstId, BlockId, BlockLoc, ExternCrateId, FunctionId, FxIndexMap, Lookup, MacroCallStyles, + MacroExpander, MacroId, ModuleId, ModuleIdLt, ProcMacroId, UseId, db::DefDatabase, item_scope::{BuiltinShadowMode, ItemScope}, item_tree::TreeId, @@ -109,7 +108,7 @@ pub struct LocalDefMap { // FIXME: There are probably some other things that could be here, but this is less severe and you // need to be careful with things that block def maps also have. /// The extern prelude which contains all root modules of external crates that are in scope. - extern_prelude: FxIndexMap)>, + extern_prelude: FxIndexMap)>, } impl std::hash::Hash for LocalDefMap { @@ -135,8 +134,7 @@ impl LocalDefMap { pub(crate) fn extern_prelude( &self, - ) -> impl DoubleEndedIterator))> + '_ - { + ) -> impl DoubleEndedIterator))> + '_ { self.extern_prelude.iter().map(|(name, &def)| (name, def)) } } @@ -157,8 +155,9 @@ pub struct DefMap { /// When this is a block def map, this will hold the block id of the block and module that /// contains this block. block: Option, + pub root: ModuleId, /// The modules and their data declared in this crate. - pub modules: Arena, + pub modules: ModulesMap, /// The prelude module for this crate. This either comes from an import /// marked with the `prelude_import` attribute, or (in the normal case) from /// a dependency (`std` or `core`). @@ -245,33 +244,22 @@ struct BlockInfo { /// The `BlockId` this `DefMap` was created from. block: BlockId, /// The containing module. - parent: BlockRelativeModuleId, + parent: ModuleId, } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -struct BlockRelativeModuleId { - block: Option, - local_id: LocalModuleId, -} - -impl BlockRelativeModuleId { - fn def_map(self, db: &dyn DefDatabase, krate: Crate) -> &DefMap { - self.into_module(krate).def_map(db) - } - - fn into_module(self, krate: Crate) -> ModuleId { - ModuleId { krate, block: self.block, local_id: self.local_id } - } - - fn is_block_module(self) -> bool { - self.block.is_some() && self.local_id == DefMap::ROOT - } -} - -impl std::ops::Index for DefMap { +impl std::ops::Index for DefMap { type Output = ModuleData; - fn index(&self, id: LocalModuleId) -> &ModuleData { - &self.modules[id] + + fn index(&self, id: ModuleId) -> &ModuleData { + self.modules + .get(&id) + .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap {:#?}: {id:#?}", self.root)) + } +} + +impl std::ops::IndexMut for DefMap { + fn index_mut(&mut self, id: ModuleId) -> &mut ModuleData { + &mut self.modules[id] } } @@ -358,8 +346,8 @@ pub struct ModuleData { /// Parent module in the same `DefMap`. /// /// [`None`] for block modules because they are always its `DefMap`'s root. - pub parent: Option, - pub children: FxIndexMap, + pub parent: Option, + pub children: FxIndexMap, pub scope: ItemScope, } @@ -392,11 +380,19 @@ pub(crate) fn crate_local_def_map(db: &dyn DefDatabase, crate_id: Crate) -> DefM .entered(); let root_file_id = crate_id.root_file_id(db); - let module_data = - ModuleData::new(ModuleOrigin::CrateRoot { definition: root_file_id }, Visibility::Public); + let module_data = ModuleData::new( + ModuleOrigin::CrateRoot { definition: root_file_id }, + Visibility::Public, + None, + ); - let def_map = - DefMap::empty(crate_id, Arc::new(DefMapCrateData::new(krate.edition)), module_data, None); + let def_map = DefMap::empty( + db, + crate_id, + Arc::new(DefMapCrateData::new(krate.edition)), + module_data, + None, + ); let (def_map, local_def_map) = collector::collect_defs(db, def_map, TreeId::new(root_file_id.into(), None), None); @@ -407,22 +403,18 @@ pub(crate) fn crate_local_def_map(db: &dyn DefDatabase, crate_id: Crate) -> DefM pub fn block_def_map(db: &dyn DefDatabase, block_id: BlockId) -> DefMap { let BlockLoc { ast_id, module } = block_id.lookup(db); - let visibility = Visibility::Module( - ModuleId { krate: module.krate, local_id: DefMap::ROOT, block: module.block }, - VisibilityExplicitness::Implicit, - ); + let visibility = Visibility::Module(module, VisibilityExplicitness::Implicit); let module_data = - ModuleData::new(ModuleOrigin::BlockExpr { block: ast_id, id: block_id }, visibility); + ModuleData::new(ModuleOrigin::BlockExpr { block: ast_id, id: block_id }, visibility, None); - let local_def_map = crate_local_def_map(db, module.krate); + let krate = module.krate(db); + let local_def_map = crate_local_def_map(db, krate); let def_map = DefMap::empty( - module.krate, + db, + krate, local_def_map.def_map(db).data.clone(), module_data, - Some(BlockInfo { - block: block_id, - parent: BlockRelativeModuleId { block: module.block, local_id: module.local_id }, - }), + Some(BlockInfo { block: block_id, parent: module }), ); let (def_map, _) = collector::collect_defs( @@ -435,25 +427,24 @@ pub fn block_def_map(db: &dyn DefDatabase, block_id: BlockId) -> DefMap { } impl DefMap { - /// The module id of a crate or block root. - pub const ROOT: LocalModuleId = LocalModuleId::from_raw(la_arena::RawIdx::from_u32(0)); - pub fn edition(&self) -> Edition { self.data.edition } fn empty( + db: &dyn DefDatabase, krate: Crate, crate_data: Arc, module_data: ModuleData, block: Option, ) -> DefMap { - let mut modules: Arena = Arena::default(); - let root = modules.alloc(module_data); - assert_eq!(root, Self::ROOT); + let mut modules = ModulesMap::new(); + let root = unsafe { ModuleIdLt::new(db, krate, block.map(|it| it.block)).to_static() }; + modules.insert(root, module_data); DefMap { block, + root, modules, krate, prelude: None, @@ -471,6 +462,7 @@ impl DefMap { diagnostics, modules, derive_helpers_in_scope, + root: _, block: _, krate: _, prelude: _, @@ -495,7 +487,7 @@ impl DefMap { &'a self, db: &'a dyn DefDatabase, file_id: FileId, - ) -> impl Iterator + 'a { + ) -> impl Iterator + 'a { self.modules .iter() .filter(move |(_id, data)| { @@ -504,7 +496,7 @@ impl DefMap { .map(|(id, _data)| id) } - pub fn modules(&self) -> impl Iterator + '_ { + pub fn modules(&self) -> impl Iterator + '_ { self.modules.iter() } @@ -543,40 +535,32 @@ impl DefMap { self.krate } - pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId { - let block = self.block.map(|b| b.block); - ModuleId { krate: self.krate, local_id, block } - } - - pub fn crate_root(&self) -> CrateRootModuleId { - CrateRootModuleId { krate: self.krate } + #[inline] + pub fn crate_root(&self, db: &dyn DefDatabase) -> ModuleId { + match self.block { + Some(_) => crate_def_map(db, self.krate()).root, + None => self.root, + } } /// This is the same as [`Self::crate_root`] for crate def maps, but for block def maps, it /// returns the root block module. pub fn root_module_id(&self) -> ModuleId { - self.module_id(Self::ROOT) + self.root } /// If this `DefMap` is for a block expression, returns the module containing the block (which /// might again be a block, or a module inside a block). pub fn parent(&self) -> Option { - let BlockRelativeModuleId { block, local_id } = self.block?.parent; - Some(ModuleId { krate: self.krate, block, local_id }) + Some(self.block?.parent) } /// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. - pub fn containing_module(&self, local_mod: LocalModuleId) -> Option { + pub fn containing_module(&self, local_mod: ModuleId) -> Option { match self[local_mod].parent { - Some(parent) => Some(self.module_id(parent)), - None => { - self.block.map( - |BlockInfo { parent: BlockRelativeModuleId { block, local_id }, .. }| { - ModuleId { krate: self.krate, block, local_id } - }, - ) - } + Some(parent) => Some(parent), + None => self.block.map(|BlockInfo { parent, .. }| parent), } } @@ -594,30 +578,21 @@ impl DefMap { // even), as this should be a great debugging aid. pub fn dump(&self, db: &dyn DefDatabase) -> String { let mut buf = String::new(); - let mut arc; let mut current_map = self; while let Some(block) = current_map.block { - go(&mut buf, db, current_map, "(block scope)", Self::ROOT); + go(&mut buf, db, current_map, "(block scope)", current_map.root); buf.push('\n'); - arc = block.parent.def_map(db, self.krate); - current_map = arc; + current_map = block.parent.def_map(db); } - go(&mut buf, db, current_map, "crate", Self::ROOT); + go(&mut buf, db, current_map, "crate", current_map.root); return buf; - fn go( - buf: &mut String, - db: &dyn DefDatabase, - map: &DefMap, - path: &str, - module: LocalModuleId, - ) { + fn go(buf: &mut String, db: &dyn DefDatabase, map: &DefMap, path: &str, module: ModuleId) { format_to!(buf, "{}\n", path); - map.modules[module].scope.dump(db, buf); + map[module].scope.dump(db, buf); - for (name, child) in - map.modules[module].children.iter().sorted_by(|a, b| Ord::cmp(&a.0, &b.0)) + for (name, child) in map[module].children.iter().sorted_by(|a, b| Ord::cmp(&a.0, &b.0)) { let path = format!("{path}::{}", name.display(db, Edition::LATEST)); buf.push('\n'); @@ -625,20 +600,6 @@ impl DefMap { } } } - - pub fn dump_block_scopes(&self, db: &dyn DefDatabase) -> String { - let mut buf = String::new(); - let mut arc; - let mut current_map = self; - while let Some(block) = current_map.block { - format_to!(buf, "{:?} in {:?}\n", block.block, block.parent); - arc = block.parent.def_map(db, self.krate); - current_map = arc; - } - - format_to!(buf, "crate scope\n"); - buf - } } impl DefMap { @@ -658,7 +619,7 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - original_module: LocalModuleId, + original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, expected_macro_subns: Option, @@ -681,7 +642,7 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - original_module: LocalModuleId, + original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, ) -> (PerNs, Option, ResolvePathResultPrefixInfo) { @@ -704,16 +665,16 @@ impl DefMap { pub(crate) fn with_ancestor_maps( &self, db: &dyn DefDatabase, - local_mod: LocalModuleId, - f: &mut dyn FnMut(&DefMap, LocalModuleId) -> Option, + local_mod: ModuleId, + f: &mut dyn FnMut(&DefMap, ModuleId) -> Option, ) -> Option { if let Some(it) = f(self, local_mod) { return Some(it); } let mut block = self.block; while let Some(block_info) = block { - let parent = block_info.parent.def_map(db, self.krate); - if let Some(it) = f(parent, block_info.parent.local_id) { + let parent = block_info.parent.def_map(db); + if let Some(it) = f(parent, block_info.parent) { return Some(it); } block = parent.block; @@ -724,11 +685,15 @@ impl DefMap { } impl ModuleData { - pub(crate) fn new(origin: ModuleOrigin, visibility: Visibility) -> Self { + pub(crate) fn new( + origin: ModuleOrigin, + visibility: Visibility, + parent: Option, + ) -> Self { ModuleData { origin, visibility, - parent: None, + parent, children: Default::default(), scope: ItemScope::default(), } @@ -852,3 +817,53 @@ fn sub_namespace_match( None => true, } } + +/// A newtype wrapper around `FxHashMap` that implements `IndexMut`. +#[derive(Debug, PartialEq, Eq)] +pub struct ModulesMap { + inner: FxIndexMap, +} + +impl ModulesMap { + fn new() -> Self { + Self { inner: FxIndexMap::default() } + } + + fn iter(&self) -> impl Iterator + '_ { + self.inner.iter().map(|(&k, v)| (k, v)) + } + + fn iter_mut(&mut self) -> impl Iterator + '_ { + self.inner.iter_mut().map(|(&k, v)| (k, v)) + } +} + +impl Deref for ModulesMap { + type Target = FxIndexMap; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for ModulesMap { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +impl Index for ModulesMap { + type Output = ModuleData; + + fn index(&self, id: ModuleId) -> &ModuleData { + self.inner.get(&id).unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) + } +} + +impl IndexMut for ModulesMap { + fn index_mut(&mut self, id: ModuleId) -> &mut ModuleData { + self.inner + .get_mut(&id) + .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) + } +} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs index b67853347bde..9d2b2109fbcb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/assoc.rs @@ -165,7 +165,7 @@ impl<'a> AssocItemCollector<'a> { local_def_map, ast_id_map: db.ast_id_map(file_id), span_map: db.span_map(file_id), - cfg_options: module_id.krate.cfg_options(db), + cfg_options: module_id.krate(db).cfg_options(db), file_id, container, items: Vec::new(), @@ -197,7 +197,7 @@ impl<'a> AssocItemCollector<'a> { AttrsOrCfg::Enabled { attrs } => attrs, AttrsOrCfg::CfgDisabled(cfg) => { self.diagnostics.push(DefDiagnostic::unconfigured_code( - self.module_id.local_id, + self.module_id, InFile::new(self.file_id, ast_id.erase()), cfg.0, self.cfg_options.clone(), @@ -213,7 +213,7 @@ impl<'a> AssocItemCollector<'a> { match self.def_map.resolve_attr_macro( self.local_def_map, self.db, - self.module_id.local_id, + self.module_id, ast_id_with_path, attr, attr_id, @@ -226,9 +226,9 @@ impl<'a> AssocItemCollector<'a> { // crate failed), skip expansion like we would if it was // disabled. This is analogous to the handling in // `DefCollector::collect_macros`. - if let Some(err) = exp.as_expand_error(self.module_id.krate) { + if let Some(err) = exp.as_expand_error(self.module_id.krate(self.db)) { self.diagnostics.push(DefDiagnostic::macro_error( - self.module_id.local_id, + self.module_id, ast_id, (*attr.path).clone(), err, @@ -244,7 +244,7 @@ impl<'a> AssocItemCollector<'a> { Ok(_) => (), Err(_) => { self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, + self.module_id, MacroCallKind::Attr { ast_id, attr_args: None, @@ -307,7 +307,7 @@ impl<'a> AssocItemCollector<'a> { .resolve_path( self.local_def_map, self.db, - self.module_id.local_id, + self.module_id, path, crate::item_scope::BuiltinShadowMode::Other, Some(MacroSubNs::Bang), @@ -322,7 +322,7 @@ impl<'a> AssocItemCollector<'a> { &path, ctxt, ExpandTo::Items, - self.module_id.krate(), + self.module_id.krate(self.db), resolver, &mut |ptr, call_id| { self.macro_calls.push((ptr.map(|(_, it)| it.upcast()), call_id)) @@ -338,7 +338,7 @@ impl<'a> AssocItemCollector<'a> { }, Err(_) => { self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, + self.module_id, MacroCallKind::FnLike { ast_id, expand_to: ExpandTo::Items, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs index fb755026c3e0..ec05c02bd635 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs @@ -12,7 +12,7 @@ use syntax::ast; use triomphe::Arc; use crate::{ - AstIdWithPath, LocalModuleId, MacroId, UnresolvedMacro, + AstIdWithPath, MacroId, ModuleId, UnresolvedMacro, db::DefDatabase, item_scope::BuiltinShadowMode, nameres::{LocalDefMap, path_resolution::ResolveMode}, @@ -33,7 +33,7 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - original_module: LocalModuleId, + original_module: ModuleId, ast_id: AstIdWithPath, attr: &Attr, attr_id: AttrId, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 9aa7febdfd02..08edf41c5694 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -3,7 +3,7 @@ //! `DefCollector::collect` contains the fixed-point iteration loop which //! resolves imports and expands macros. -use std::{cmp::Ordering, iter, mem}; +use std::{iter, mem}; use base_db::{BuiltDependency, Crate, CrateOrigin, LangCrateOrigin}; use cfg::{CfgAtom, CfgExpr, CfgOptions}; @@ -27,12 +27,11 @@ use syntax::ast; use triomphe::Arc; use crate::{ - AdtId, AssocItemId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, ExternBlockLoc, - ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, FxIndexMap, ImplLoc, Intern, - ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, - MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId, - ProcMacroLoc, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, - UseLoc, + AdtId, AssocItemId, AstId, AstIdWithPath, ConstLoc, EnumLoc, ExternBlockLoc, ExternCrateId, + ExternCrateLoc, FunctionId, FunctionLoc, FxIndexMap, ImplLoc, Intern, ItemContainerId, Lookup, + Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, + ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, + UnionLoc, UnresolvedMacro, UseId, UseLoc, db::DefDatabase, item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports}, item_tree::{ @@ -177,14 +176,14 @@ impl Import { #[derive(Debug, Eq, PartialEq)] struct ImportDirective { /// The module this import directive is in. - module_id: LocalModuleId, + module_id: ModuleId, import: Import, status: PartialResolvedImport, } #[derive(Clone, Debug, Eq, PartialEq)] struct MacroDirective<'db> { - module_id: LocalModuleId, + module_id: ModuleId, depth: usize, kind: MacroDirectiveKind<'db>, container: ItemContainerId, @@ -224,7 +223,7 @@ struct DefCollector<'db> { crate_local_def_map: Option<&'db LocalDefMap>, // The dependencies of the current crate, including optional deps like `test`. deps: FxIndexMap, - glob_imports: FxHashMap>, + glob_imports: FxHashMap>, unresolved_imports: Vec, indeterminate_imports: Vec<(ImportDirective, PerNs)>, unresolved_macros: Vec>, @@ -232,7 +231,7 @@ struct DefCollector<'db> { // resolve. When we emit diagnostics for unresolved imports, we only do so if the import // doesn't start with an unresolved crate's name. unresolved_extern_crates: FxHashSet, - mod_dirs: FxHashMap, + mod_dirs: FxHashMap, cfg_options: &'db CfgOptions, /// List of procedural macros defined by this crate. This is read from the dynamic library /// built by the build system, and is the list of proc-macros we can actually expand. It is @@ -337,9 +336,14 @@ impl<'db> DefCollector<'db> { continue; } - self.local_def_map - .extern_prelude - .insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None)); + // This eagerly draws a dependency edge between the crate def maps even if the + // things the crates are not used. This is not great, but at the same time we would + // like to compute our dependency def maps in parallel here anyways in the future + // which will have the same effect. + self.local_def_map.extern_prelude.insert( + name.clone(), + (crate_def_map(self.db, dep.crate_id).root_module_id(), None), + ); } } @@ -349,10 +353,11 @@ impl<'db> DefCollector<'db> { return; } + let module_id = self.def_map.root; ModCollector { def_collector: self, macro_depth: 0, - module_id: DefMap::ROOT, + module_id, tree_id: TreeId::new(file_id.into(), None), item_tree, mod_dir: ModDir::root(), @@ -367,10 +372,11 @@ impl<'db> DefCollector<'db> { if is_cfg_enabled { self.inject_prelude(); + let module_id = self.def_map.root; ModCollector { def_collector: self, macro_depth: 0, - module_id: DefMap::ROOT, + module_id, tree_id, item_tree, mod_dir: ModDir::root(), @@ -433,7 +439,8 @@ impl<'db> DefCollector<'db> { // Additionally, while the proc macro entry points must be `pub`, they are not publicly // exported in type/value namespace. This function reduces the visibility of all items // in the crate root that aren't proc macros. - let root = &mut self.def_map.modules[DefMap::ROOT]; + let module_id = self.def_map.root_module_id(); + let root = &mut self.def_map.modules[module_id]; root.scope.censor_non_proc_macros(self.def_map.krate); } } @@ -537,7 +544,7 @@ impl<'db> DefCollector<'db> { let (per_ns, _) = self.def_map.resolve_path( self.crate_local_def_map.unwrap_or(&self.local_def_map), self.db, - DefMap::ROOT, + self.def_map.root_module_id(), &path, BuiltinShadowMode::Other, None, @@ -592,7 +599,7 @@ impl<'db> DefCollector<'db> { }; let proc_macro_id = ProcMacroLoc { - container: self.def_map.crate_root(), + container: self.def_map.root_module_id(), id: ast_id, expander, kind, @@ -636,7 +643,7 @@ impl<'db> DefCollector<'db> { /// ``` fn define_macro_rules( &mut self, - module_id: LocalModuleId, + module_id: ModuleId, name: Name, macro_: MacroRulesId, export: bool, @@ -648,7 +655,7 @@ impl<'db> DefCollector<'db> { // In Rust, `#[macro_export]` macros are unconditionally visible at the // crate root, even if the parent modules is **not** visible. if export { - let module_id = DefMap::ROOT; + let module_id = self.def_map.root; self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( module_id, @@ -666,7 +673,7 @@ impl<'db> DefCollector<'db> { /// the definition of current module. /// And also, `macro_use` on a module will import all legacy macros visible inside to /// current legacy scope, with possible shadowing. - fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroId) { + fn define_legacy_macro(&mut self, module_id: ModuleId, name: Name, mac: MacroId) { // Always shadowing self.def_map.modules[module_id].scope.define_legacy_macro(name, mac); } @@ -676,7 +683,7 @@ impl<'db> DefCollector<'db> { /// The scoped of macro 2.0 macro is equal to normal function fn define_macro_def( &mut self, - module_id: LocalModuleId, + module_id: ModuleId, name: Name, macro_: Macro2Id, vis: &RawVisibility, @@ -705,7 +712,7 @@ impl<'db> DefCollector<'db> { /// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped. /// And unconditionally exported. fn define_proc_macro(&mut self, name: Name, macro_: ProcMacroId) { - let module_id = DefMap::ROOT; + let module_id = self.def_map.root; self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( module_id, @@ -730,7 +737,7 @@ impl<'db> DefCollector<'db> { let def_map = crate_def_map(self.db, krate); // `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!` // macros. - let root_scope = &def_map[DefMap::ROOT].scope; + let root_scope = &def_map[def_map.root].scope; match names { Some(names) => { for name in names { @@ -803,7 +810,7 @@ impl<'db> DefCollector<'db> { res } - fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport { + fn resolve_import(&self, module_id: ModuleId, import: &Import) -> PartialResolvedImport { let _p = tracing::info_span!("resolve_import", import_path = %import.path.display(self.db, Edition::LATEST)) .entered(); tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition); @@ -916,11 +923,10 @@ impl<'db> DefCollector<'db> { // implementation seems to work the same though. cov_mark::hit!(std_prelude); self.def_map.prelude = Some((m, Some(id))); - } else if m.krate != self.def_map.krate { + } else if m.krate(self.db) != self.def_map.krate { cov_mark::hit!(glob_across_crates); // glob import from other crate => we can just import everything once - let item_map = m.def_map(self.db); - let scope = &item_map[m.local_id].scope; + let scope = &m.def_map(self.db)[m].scope; // Module scoped macros is included let items = scope @@ -942,12 +948,10 @@ impl<'db> DefCollector<'db> { // glob import from same crate => we do an initial // import, and then need to propagate any further // additions - let def_map; - let scope = if m.block == self.def_map.block_id() { - &self.def_map[m.local_id].scope + let scope = if m.block(self.db) == self.def_map.block_id() { + &self.def_map[m].scope } else { - def_map = m.def_map(self.db); - &def_map[m.local_id].scope + &m.def_map(self.db)[m].scope }; // Module scoped macros is included @@ -976,11 +980,12 @@ impl<'db> DefCollector<'db> { Some(ImportOrExternCrate::Glob(glob)), ); // record the glob import in case we add further items - let glob_imports = self.glob_imports.entry(m.local_id).or_default(); + let glob_imports = self.glob_imports.entry(m).or_default(); match glob_imports.iter_mut().find(|(mid, _, _)| *mid == module_id) { None => glob_imports.push((module_id, vis, glob)), Some((_, old_vis, _)) => { - if let Some(new_vis) = old_vis.max(vis, &self.def_map) { + if let Some(new_vis) = old_vis.max(self.db, vis, &self.def_map) + { *old_vis = new_vis; } } @@ -1056,20 +1061,19 @@ impl<'db> DefCollector<'db> { fn update( &mut self, // The module for which `resolutions` have been resolve - module_id: LocalModuleId, + module_id: ModuleId, resolutions: &[(Option, PerNs)], // Visibility this import will have vis: Visibility, import: Option, ) { - self.db.unwind_if_revision_cancelled(); self.update_recursive(module_id, resolutions, vis, import, 0) } fn update_recursive( &mut self, // The module for which `resolutions` have been resolved. - module_id: LocalModuleId, + module_id: ModuleId, resolutions: &[(Option, PerNs)], // All resolutions are imported with this visibility; the visibilities in // the `PerNs` values are ignored and overwritten @@ -1104,7 +1108,7 @@ impl<'db> DefCollector<'db> { let should_update = match old_vis { None => true, Some(old_vis) => { - let max_vis = old_vis.max(vis, &self.def_map).unwrap_or_else(|| { + let max_vis = old_vis.max(self.db, vis, &self.def_map).unwrap_or_else(|| { panic!("`Tr as _` imports with unrelated visibilities {old_vis:?} and {vis:?} (trait {tr:?})"); }); @@ -1146,7 +1150,7 @@ impl<'db> DefCollector<'db> { .collect::>(); for (glob_importing_module, glob_import_vis, glob) in glob_imports { - let vis = glob_import_vis.min(vis, &self.def_map).unwrap_or(glob_import_vis); + let vis = glob_import_vis.min(self.db, vis, &self.def_map).unwrap_or(glob_import_vis); self.update_recursive( glob_importing_module, resolutions, @@ -1159,20 +1163,20 @@ impl<'db> DefCollector<'db> { fn push_res_and_update_glob_vis( &mut self, - module_id: LocalModuleId, + module_id: ModuleId, name: &Name, mut defs: PerNs, vis: Visibility, def_import_type: Option, ) -> bool { if let Some(def) = defs.types.as_mut() { - def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis); + def.vis = def.vis.min(self.db, vis, &self.def_map).unwrap_or(vis); } if let Some(def) = defs.values.as_mut() { - def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis); + def.vis = def.vis.min(self.db, vis, &self.def_map).unwrap_or(vis); } if let Some(def) = defs.macros.as_mut() { - def.vis = def.vis.min(vis, &self.def_map).unwrap_or(vis); + def.vis = def.vis.min(self.db, vis, &self.def_map).unwrap_or(vis); } let mut changed = false; @@ -1188,7 +1192,7 @@ impl<'db> DefCollector<'db> { && def.def == prev_def.def && self.from_glob_import.contains_type(module_id, name.clone()) && def.vis != prev_def.vis - && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis) + && def.vis.max(self.db, prev_def.vis, &self.def_map) == Some(def.vis) { changed = true; // This import is being handled here, don't pass it down to @@ -1202,7 +1206,7 @@ impl<'db> DefCollector<'db> { && def.def == prev_def.def && self.from_glob_import.contains_value(module_id, name.clone()) && def.vis != prev_def.vis - && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis) + && def.vis.max(self.db, prev_def.vis, &self.def_map) == Some(def.vis) { changed = true; // See comment above. @@ -1215,7 +1219,7 @@ impl<'db> DefCollector<'db> { && def.def == prev_def.def && self.from_glob_import.contains_macro(module_id, name.clone()) && def.vis != prev_def.vis - && def.vis.max(prev_def.vis, &self.def_map) == Some(def.vis) + && def.vis.max(self.db, prev_def.vis, &self.def_map) == Some(def.vis) { changed = true; // See comment above. @@ -1555,7 +1559,7 @@ impl<'db> DefCollector<'db> { fn collect_macro_expansion( &mut self, - module_id: LocalModuleId, + module_id: ModuleId, macro_call_id: MacroCallId, depth: usize, container: ItemContainerId, @@ -1713,7 +1717,7 @@ impl<'db> DefCollector<'db> { struct ModCollector<'a, 'db> { def_collector: &'a mut DefCollector<'db>, macro_depth: usize, - module_id: LocalModuleId, + module_id: ModuleId, tree_id: TreeId, item_tree: &'db ItemTree, mod_dir: ModDir, @@ -1721,14 +1725,13 @@ struct ModCollector<'a, 'db> { impl ModCollector<'_, '_> { fn collect_in_top_module(&mut self, items: &[ModItemId]) { - let module = self.def_collector.def_map.module_id(self.module_id); - self.collect(items, module.into()) + self.collect(items, self.module_id.into()) } fn collect(&mut self, items: &[ModItemId], container: ItemContainerId) { let krate = self.def_collector.def_map.krate; - let is_crate_root = - self.module_id == DefMap::ROOT && self.def_collector.def_map.block.is_none(); + let is_crate_root = self.module_id == self.def_collector.def_map.root + && self.def_collector.def_map.block.is_none(); // Note: don't assert that inserted value is fresh: it's simply not true // for macros. @@ -1737,10 +1740,10 @@ impl ModCollector<'_, '_> { // Prelude module is always considered to be `#[macro_use]`. if let Some((prelude_module, _use)) = self.def_collector.def_map.prelude { // Don't insert macros from the prelude into blocks, as they can be shadowed by other macros. - if prelude_module.krate != krate && is_crate_root { + if is_crate_root && prelude_module.krate(self.def_collector.db) != krate { cov_mark::hit!(prelude_is_macro_use); self.def_collector.import_macros_from_extern_crate( - prelude_module.krate, + prelude_module.krate(self.def_collector.db), None, None, ); @@ -1781,7 +1784,6 @@ impl ModCollector<'_, '_> { return; } - let module = self.def_collector.def_map.module_id(module_id); let def_map = &mut self.def_collector.def_map; let local_def_map = self.def_collector.crate_local_def_map.unwrap_or(&self.def_collector.local_def_map); @@ -1789,9 +1791,11 @@ impl ModCollector<'_, '_> { match item { ModItemId::Mod(m) => self.collect_module(m, attrs), ModItemId::Use(item_tree_id) => { - let id = - UseLoc { container: module, id: InFile::new(self.file_id(), item_tree_id) } - .intern(db); + let id = UseLoc { + container: module_id, + id: InFile::new(self.file_id(), item_tree_id), + } + .intern(db); let is_prelude = attrs.by_key(sym::prelude_import).exists(); Import::from_use(self.item_tree, item_tree_id, id, is_prelude, |import| { self.def_collector.unresolved_imports.push(ImportDirective { @@ -1806,7 +1810,7 @@ impl ModCollector<'_, '_> { &self.item_tree[item_tree_id]; let id = ExternCrateLoc { - container: module, + container: module_id, id: InFile::new(self.tree_id.file_id(), item_tree_id), } .intern(db); @@ -1815,12 +1819,12 @@ impl ModCollector<'_, '_> { let is_self = *name == sym::self_; let resolved = if is_self { cov_mark::hit!(extern_crate_self_as); - Some(def_map.crate_root()) + Some(def_map.crate_root(db)) } else { self.def_collector .deps .get(name) - .map(|dep| CrateRootModuleId { krate: dep.crate_id }) + .map(|dep| crate_def_map(db, dep.crate_id).root_module_id()) }; let name = match alias { @@ -1845,7 +1849,7 @@ impl ModCollector<'_, '_> { self.process_macro_use_extern_crate( id, attrs.by_key(sym::macro_use).attrs(), - resolved.krate, + resolved.krate(self.def_collector.db), ); } } @@ -1877,7 +1881,7 @@ impl ModCollector<'_, '_> { } ModItemId::ExternBlock(block) => { let extern_block_id = ExternBlockLoc { - container: module, + container: module_id, id: InFile::new(self.file_id(), block), } .intern(db); @@ -1890,11 +1894,11 @@ impl ModCollector<'_, '_> { ) } ModItemId::MacroCall(mac) => self.collect_macro_call(mac, container), - ModItemId::MacroRules(id) => self.collect_macro_rules(id, module), - ModItemId::Macro2(id) => self.collect_macro_def(id, module), + ModItemId::MacroRules(id) => self.collect_macro_rules(id, module_id), + ModItemId::Macro2(id) => self.collect_macro_def(id, module_id), ModItemId::Impl(imp) => { let impl_id = - ImplLoc { container: module, id: InFile::new(self.file_id(), imp) } + ImplLoc { container: module_id, id: InFile::new(self.file_id(), imp) } .intern(db); self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id) } @@ -1908,7 +1912,7 @@ impl ModCollector<'_, '_> { if self.def_collector.def_map.block.is_none() && self.def_collector.is_proc_macro - && self.module_id == DefMap::ROOT + && self.module_id == self.def_collector.def_map.root && let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) { self.def_collector.export_proc_macro( @@ -1926,7 +1930,7 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, - StructLoc { container: module, id: InFile::new(self.file_id(), id) } + StructLoc { container: module_id, id: InFile::new(self.file_id(), id) } .intern(db) .into(), &it.name, @@ -1940,7 +1944,7 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, - UnionLoc { container: module, id: InFile::new(self.file_id(), id) } + UnionLoc { container: module_id, id: InFile::new(self.file_id(), id) } .intern(db) .into(), &it.name, @@ -1950,9 +1954,11 @@ impl ModCollector<'_, '_> { } ModItemId::Enum(id) => { let it = &self.item_tree[id]; - let enum_ = - EnumLoc { container: module, id: InFile::new(self.tree_id.file_id(), id) } - .intern(db); + let enum_ = EnumLoc { + container: module_id, + id: InFile::new(self.tree_id.file_id(), id), + } + .intern(db); let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def(self.def_collector, enum_.into(), &it.name, vis, false); @@ -1997,7 +2003,7 @@ impl ModCollector<'_, '_> { let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def( self.def_collector, - TraitLoc { container: module, id: InFile::new(self.file_id(), id) } + TraitLoc { container: module_id, id: InFile::new(self.file_id(), id) } .intern(db) .into(), &it.name, @@ -2172,9 +2178,10 @@ impl ModCollector<'_, '_> { declaration: FileAstId, definition: Option<(EditionedFileId, bool)>, visibility: &crate::visibility::RawVisibility, - ) -> LocalModuleId { - let def_map = &mut self.def_collector.def_map; - let vis = def_map + ) -> ModuleId { + let vis = self + .def_collector + .def_map .resolve_visibility( self.def_collector.crate_local_def_map.unwrap_or(&self.def_collector.local_def_map), self.def_collector.db, @@ -2195,21 +2202,25 @@ impl ModCollector<'_, '_> { }, }; + let module = unsafe { + crate::ModuleIdLt::new( + self.def_collector.db, + self.def_collector.def_map.krate, + self.def_collector.def_map.block_id(), + ) + .to_static() + }; + let def_map = &mut self.def_collector.def_map; let modules = &mut def_map.modules; - let res = modules.alloc(ModuleData::new(origin, vis)); - modules[res].parent = Some(self.module_id); - - if let Some((target, source)) = Self::borrow_modules(modules.as_mut(), res, self.module_id) - { - for (name, macs) in source.scope.legacy_macros() { - for &mac in macs { - target.scope.define_legacy_macro(name.clone(), mac); - } + let mut data = ModuleData::new(origin, vis, Some(self.module_id)); + for (name, macs) in modules[self.module_id].scope.legacy_macros() { + for &mac in macs { + data.scope.define_legacy_macro(name.clone(), mac); } } - modules[self.module_id].children.insert(name.clone(), res); + modules[self.module_id].children.insert(name.clone(), module); + modules.insert(module, data); - let module = def_map.module_id(res); let def = ModuleDefId::from(module); def_map.modules[self.module_id].scope.declare(def); @@ -2219,7 +2230,7 @@ impl ModCollector<'_, '_> { vis, None, ); - res + module } /// Resolves attributes on an item. @@ -2516,12 +2527,10 @@ impl ModCollector<'_, '_> { }); } - fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) { - let Some((source, target)) = Self::borrow_modules( - self.def_collector.def_map.modules.as_mut(), - module_id, - self.module_id, - ) else { + fn import_all_legacy_macros(&mut self, module_id: ModuleId) { + let [Some(source), Some(target)] = + self.def_collector.def_map.modules.get_disjoint_mut([&module_id, &self.module_id]) + else { return; }; @@ -2532,29 +2541,6 @@ impl ModCollector<'_, '_> { } } - /// Mutably borrow two modules at once, retu - fn borrow_modules( - modules: &mut [ModuleData], - a: LocalModuleId, - b: LocalModuleId, - ) -> Option<(&mut ModuleData, &mut ModuleData)> { - let a = a.into_raw().into_u32() as usize; - let b = b.into_raw().into_u32() as usize; - - let (a, b) = match a.cmp(&b) { - Ordering::Equal => return None, - Ordering::Less => { - let (prefix, b) = modules.split_at_mut(b); - (&mut prefix[a], &mut b[0]) - } - Ordering::Greater => { - let (prefix, a) = modules.split_at_mut(a); - (&mut a[0], &mut prefix[b]) - } - }; - Some((a, b)) - } - fn emit_unconfigured_diagnostic(&mut self, ast_id: ErasedAstId, cfg: &CfgExpr) { self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code( self.module_id, @@ -2574,48 +2560,15 @@ impl ModCollector<'_, '_> { mod tests { use test_fixture::WithFixture; - use crate::{nameres::DefMapCrateData, test_db::TestDB}; + use crate::test_db::TestDB; use super::*; - fn do_collect_defs(db: &dyn DefDatabase, def_map: DefMap) -> DefMap { - let mut collector = DefCollector { - db, - def_map, - local_def_map: LocalDefMap::default(), - crate_local_def_map: None, - deps: FxIndexMap::default(), - glob_imports: FxHashMap::default(), - unresolved_imports: Vec::new(), - indeterminate_imports: Vec::new(), - unresolved_macros: Vec::new(), - mod_dirs: FxHashMap::default(), - cfg_options: &CfgOptions::default(), - proc_macros: Default::default(), - from_glob_import: Default::default(), - skip_attrs: Default::default(), - prev_active_attrs: Default::default(), - is_proc_macro: false, - unresolved_extern_crates: Default::default(), - }; - collector.seed_with_top_level(); - collector.collect(); - collector.def_map - } - - fn do_resolve(not_ra_fixture: &str) -> DefMap { - let (db, file_id) = TestDB::with_single_file(not_ra_fixture); + fn do_resolve(not_ra_fixture: &str) { + let (db, _) = TestDB::with_single_file(not_ra_fixture); let krate = db.test_crate(); - let edition = krate.data(&db).edition; - let module_origin = ModuleOrigin::CrateRoot { definition: file_id }; - let def_map = DefMap::empty( - krate, - Arc::new(DefMapCrateData::new(edition)), - ModuleData::new(module_origin, Visibility::Public), - None, - ); - do_collect_defs(&db, def_map) + crate_def_map(&db, krate); } #[test] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs index 6a07c56aeebe..be28e085094e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs @@ -7,7 +7,7 @@ use hir_expand::{ErasedAstId, ExpandErrorKind, MacroCallKind, attrs::AttrId, mod use la_arena::Idx; use syntax::ast; -use crate::{AstId, nameres::LocalModuleId}; +use crate::{AstId, nameres::ModuleId}; #[derive(Debug, PartialEq, Eq)] pub enum DefDiagnosticKind { @@ -43,13 +43,13 @@ impl DefDiagnostics { #[derive(Debug, PartialEq, Eq)] pub struct DefDiagnostic { - pub in_module: LocalModuleId, + pub in_module: ModuleId, pub kind: DefDiagnosticKind, } impl DefDiagnostic { pub(super) fn unresolved_module( - container: LocalModuleId, + container: ModuleId, declaration: AstId, candidates: Box<[String]>, ) -> Self { @@ -60,7 +60,7 @@ impl DefDiagnostic { } pub(super) fn unresolved_extern_crate( - container: LocalModuleId, + container: ModuleId, declaration: AstId, ) -> Self { Self { @@ -70,7 +70,7 @@ impl DefDiagnostic { } pub(super) fn unresolved_import( - container: LocalModuleId, + container: ModuleId, id: AstId, index: Idx, ) -> Self { @@ -78,7 +78,7 @@ impl DefDiagnostic { } pub fn macro_error( - container: LocalModuleId, + container: ModuleId, ast: AstId, path: ModPath, err: ExpandErrorKind, @@ -87,7 +87,7 @@ impl DefDiagnostic { } pub fn unconfigured_code( - container: LocalModuleId, + container: ModuleId, ast_id: ErasedAstId, cfg: CfgExpr, opts: CfgOptions, @@ -100,33 +100,26 @@ impl DefDiagnostic { // FIXME: Whats the difference between this and unresolved_proc_macro pub(crate) fn unresolved_macro_call( - container: LocalModuleId, + container: ModuleId, ast: MacroCallKind, path: ModPath, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnresolvedMacroCall { ast, path } } } - pub(super) fn unimplemented_builtin_macro( - container: LocalModuleId, - ast: AstId, - ) -> Self { + pub(super) fn unimplemented_builtin_macro(container: ModuleId, ast: AstId) -> Self { Self { in_module: container, kind: DefDiagnosticKind::UnimplementedBuiltinMacro { ast } } } pub(super) fn invalid_derive_target( - container: LocalModuleId, + container: ModuleId, ast: AstId, id: AttrId, ) -> Self { Self { in_module: container, kind: DefDiagnosticKind::InvalidDeriveTarget { ast, id } } } - pub(super) fn malformed_derive( - container: LocalModuleId, - ast: AstId, - id: AttrId, - ) -> Self { + pub(super) fn malformed_derive(container: ModuleId, ast: AstId, id: AttrId) -> Self { Self { in_module: container, kind: DefDiagnosticKind::MalformedDerive { ast, id } } } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs index 184a57410d02..e4b1d2a98735 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs @@ -19,7 +19,7 @@ use span::Edition; use stdx::TupleExt; use crate::{ - AdtId, LocalModuleId, ModuleDefId, + AdtId, ModuleDefId, ModuleId, db::DefDatabase, item_scope::{BUILTIN_SCOPE, ImportOrExternCrate}, item_tree::FieldsShape, @@ -97,7 +97,7 @@ impl DefMap { local_def_map: &LocalDefMap, db: &dyn DefDatabase, // module to import to - original_module: LocalModuleId, + original_module: ModuleId, // pub(path) // ^^^^ this visibility: &RawVisibility, @@ -130,8 +130,8 @@ impl DefMap { // DefMap they're written in, so we restrict them when that happens. if let Visibility::Module(m, mv) = vis { // ...unless we're resolving visibility for an associated item in an impl. - if self.block_id() != m.block && !within_impl { - vis = Visibility::Module(self.module_id(Self::ROOT), mv); + if self.block_id() != m.block(db) && !within_impl { + vis = Visibility::Module(self.root, mv); tracing::debug!( "visibility {:?} points outside DefMap, adjusting to {:?}", m, @@ -142,7 +142,7 @@ impl DefMap { vis } RawVisibility::PubSelf(explicitness) => { - Visibility::Module(self.module_id(original_module), *explicitness) + Visibility::Module(original_module, *explicitness) } RawVisibility::Public => Visibility::Public, RawVisibility::PubCrate => Visibility::PubCrate(self.krate), @@ -158,7 +158,7 @@ impl DefMap { db: &dyn DefDatabase, mode: ResolveMode, // module to import to - mut original_module: LocalModuleId, + mut original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, // Pass `MacroSubNs` if we know we're resolving macro names and which kind of macro we're @@ -198,17 +198,17 @@ impl DefMap { loop { match current_map.block { - Some(block) if original_module == Self::ROOT => { + Some(block) if original_module == current_map.root => { // Block modules "inherit" names from its parent module. - original_module = block.parent.local_id; - current_map = block.parent.def_map(db, current_map.krate); + original_module = block.parent; + current_map = block.parent.def_map(db); } // Proper (non-block) modules, including those in block `DefMap`s, don't. _ => { - if original_module != Self::ROOT && current_map.block.is_some() { + if original_module != current_map.root && current_map.block.is_some() { // A module inside a block. Do not resolve items declared in upper blocks, but we do need to get // the prelude items (which are not inserted into blocks because they can be overridden there). - original_module = Self::ROOT; + original_module = current_map.root; current_map = crate_def_map(db, self.krate); let new = current_map.resolve_path_fp_in_all_preludes( @@ -245,7 +245,7 @@ impl DefMap { local_def_map: &LocalDefMap, db: &dyn DefDatabase, mode: ResolveMode, - original_module: LocalModuleId, + original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, expected_macro_subns: Option, @@ -255,15 +255,15 @@ impl DefMap { PathKind::DollarCrate(krate) => { if krate == self.krate { cov_mark::hit!(macro_dollar_crate_self); - PerNs::types(self.crate_root().into(), Visibility::Public, None) + PerNs::types(self.crate_root(db).into(), Visibility::Public, None) } else { let def_map = crate_def_map(db, krate); - let module = def_map.module_id(Self::ROOT); + let module = def_map.root; cov_mark::hit!(macro_dollar_crate_other); PerNs::types(module.into(), Visibility::Public, None) } } - PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public, None), + PathKind::Crate => PerNs::types(self.crate_root(db).into(), Visibility::Public, None), // plain import or absolute path in 2015: crate-relative with // fallback to extern prelude (with the simplification in // rust-lang/rust#57745) @@ -310,14 +310,10 @@ impl DefMap { } PathKind::Super(lvl) => { let mut local_id = original_module; - let mut ext; let mut def_map = self; // Adjust `local_id` to `self`, i.e. the nearest non-block module. - if def_map.module_id(local_id).is_block_module() { - (ext, local_id) = adjust_to_nearest_non_block_module(db, def_map, local_id); - def_map = ext; - } + (def_map, local_id) = adjust_to_nearest_non_block_module(db, def_map, local_id); // Go up the module tree but skip block modules as `super` always refers to the // nearest non-block module. @@ -325,12 +321,8 @@ impl DefMap { // Loop invariant: at the beginning of each loop, `local_id` must refer to a // non-block module. if let Some(parent) = def_map.modules[local_id].parent { - local_id = parent; - if def_map.module_id(local_id).is_block_module() { - (ext, local_id) = - adjust_to_nearest_non_block_module(db, def_map, local_id); - def_map = ext; - } + (def_map, local_id) = + adjust_to_nearest_non_block_module(db, def_map, parent); } else { stdx::always!(def_map.block.is_none()); tracing::debug!("super path in root module"); @@ -338,9 +330,6 @@ impl DefMap { } } - let module = def_map.module_id(local_id); - stdx::never!(module.is_block_module()); - if self.block != def_map.block { // If we have a different `DefMap` from `self` (the original `DefMap` we started // with), resolve the remaining path segments in that `DefMap`. @@ -358,7 +347,7 @@ impl DefMap { ); } - PerNs::types(module.into(), Visibility::Public, None) + PerNs::types(local_id.into(), Visibility::Public, None) } PathKind::Abs => match self.resolve_path_abs(local_def_map, &mut segments, path) { Either::Left(it) => it, @@ -385,7 +374,7 @@ impl DefMap { local_def_map: &LocalDefMap, db: &dyn DefDatabase, mode: ResolveMode, - original_module: LocalModuleId, + original_module: ModuleId, path: &ModPath, shadow: BuiltinShadowMode, ) -> ResolvePathResult { @@ -467,7 +456,7 @@ impl DefMap { mut curr_per_ns: PerNs, path: &ModPath, shadow: BuiltinShadowMode, - original_module: LocalModuleId, + original_module: ModuleId, ) -> ResolvePathResult { while let Some((i, segment)) = segments.next() { let curr = match curr_per_ns.take_types_full() { @@ -485,7 +474,7 @@ impl DefMap { curr_per_ns = match curr.def { ModuleDefId::ModuleId(module) => { - if module.krate != self.krate { + if module.krate(db) != self.krate { // FIXME: Inefficient let path = ModPath::from_segments( PathKind::SELF, @@ -501,7 +490,7 @@ impl DefMap { LocalDefMap::EMPTY, db, mode, - module.local_id, + module, &path, shadow, None, @@ -518,11 +507,11 @@ impl DefMap { } let def_map; - let module_data = if module.block == self.block_id() { - &self[module.local_id] + let module_data = if module.block(db) == self.block_id() { + &self[module] } else { def_map = module.def_map(db); - &def_map[module.local_id] + &def_map[module] }; // Since it is a qualified path here, it should not contains legacy macros @@ -649,7 +638,7 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - module: LocalModuleId, + module: ModuleId, name: &Name, shadow: BuiltinShadowMode, expected_macro_subns: Option, @@ -684,7 +673,7 @@ impl DefMap { }; let extern_prelude = || { - if self.block.is_some() && module == DefMap::ROOT { + if self.block.is_some() && module == self.root { // Don't resolve extern prelude in pseudo-modules of blocks, because // they might been shadowed by local names. return PerNs::none(); @@ -693,7 +682,7 @@ impl DefMap { }; let macro_use_prelude = || self.resolve_in_macro_use_prelude(name); let prelude = || { - if self.block.is_some() && module == DefMap::ROOT { + if self.block.is_some() && module == self.root { return PerNs::none(); } self.resolve_in_prelude(db, name) @@ -746,18 +735,18 @@ impl DefMap { &self, local_def_map: &LocalDefMap, db: &dyn DefDatabase, - module: LocalModuleId, + module: ModuleId, name: &Name, ) -> PerNs { let from_crate_root = match self.block { Some(_) => { - let def_map = self.crate_root().def_map(db); - def_map[Self::ROOT].scope.get(name) + let def_map = self.crate_root(db).def_map(db); + def_map[def_map.root].scope.get(name) } - None => self[Self::ROOT].scope.get(name), + None => self[self.root].scope.get(name), }; let from_extern_prelude = || { - if self.block.is_some() && module == DefMap::ROOT { + if self.block.is_some() && module == self.root { // Don't resolve extern prelude in pseudo-module of a block. return PerNs::none(); } @@ -770,14 +759,14 @@ impl DefMap { fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs { if let Some((prelude, _use)) = self.prelude { let keep; - let def_map = if prelude.krate == self.krate { + let def_map = if prelude.krate(db) == self.krate { self } else { // Extend lifetime keep = prelude.def_map(db); keep }; - def_map[prelude.local_id].scope.get(name) + def_map[prelude].scope.get(name) } else { PerNs::none() } @@ -785,23 +774,23 @@ impl DefMap { } /// Given a block module, returns its nearest non-block module and the `DefMap` it belongs to. +#[inline] fn adjust_to_nearest_non_block_module<'db>( db: &'db dyn DefDatabase, - def_map: &'db DefMap, - mut local_id: LocalModuleId, -) -> (&'db DefMap, LocalModuleId) { - // INVARIANT: `local_id` in `def_map` must be a block module. - stdx::always!(def_map.module_id(local_id).is_block_module()); - - // This needs to be a local variable due to our mighty lifetime. - let mut def_map = def_map; - loop { - let BlockInfo { parent, .. } = def_map.block.expect("block module without parent module"); - - def_map = parent.def_map(db, def_map.krate); - local_id = parent.local_id; - if !parent.is_block_module() { + mut def_map: &'db DefMap, + mut local_id: ModuleId, +) -> (&'db DefMap, ModuleId) { + if def_map.root_module_id() != local_id { + // if we aren't the root, we are either not a block module, or a non-block module inside a + // block def map. + return (def_map, local_id); + } + while let Some(BlockInfo { parent, .. }) = def_map.block { + def_map = parent.def_map(db); + local_id = parent; + if def_map.root_module_id() != local_id { return (def_map, local_id); } } + (def_map, local_id) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs index 40283f67cc5c..57243346019f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs @@ -63,7 +63,7 @@ pub const BAZ: u32 = 0; let all_crates_before = db.all_crates(); { - // Add a dependency a -> b. + // Add dependencies: c -> b, b -> a. let mut new_crate_graph = CrateGraphBuilder::default(); let mut add_crate = |crate_name, root_file_idx: usize| { @@ -111,10 +111,13 @@ pub const BAZ: u32 = 0; crate_def_map(&db, krate); } }, - &[("crate_local_def_map", 1)], + // `c` gets invalidated as its dependency `b` changed + // `b` gets invalidated due to its new dependency edge to `a` + &[("crate_local_def_map", 2)], expect![[r#" [ "crate_local_def_map", + "crate_local_def_map", ] "#]], ); @@ -280,20 +283,20 @@ fn f() { foo } "ast_id_map_shim", "parse_shim", "real_span_map_shim", - "file_item_tree_query", - "ast_id_map_shim", - "parse_shim", - "real_span_map_shim", - "file_item_tree_query", - "ast_id_map_shim", - "parse_shim", - "real_span_map_shim", "crate_local_def_map", "proc_macros_for_crate_shim", "file_item_tree_query", "ast_id_map_shim", "parse_shim", "real_span_map_shim", + "file_item_tree_query", + "ast_id_map_shim", + "parse_shim", + "real_span_map_shim", + "file_item_tree_query", + "ast_id_map_shim", + "parse_shim", + "real_span_map_shim", "macro_def_shim", "file_item_tree_query", "ast_id_map_shim", @@ -404,32 +407,32 @@ pub struct S {} "ast_id_map_shim", "parse_shim", "real_span_map_shim", - "decl_macro_expander_shim", - "file_item_tree_query", - "ast_id_map_shim", - "parse_shim", - "real_span_map_shim", - "file_item_tree_query", - "ast_id_map_shim", - "parse_shim", - "real_span_map_shim", - "macro_def_shim", - "file_item_tree_query", - "ast_id_map_shim", - "parse_macro_expansion_shim", - "macro_arg_shim", - "decl_macro_expander_shim", - "macro_def_shim", - "file_item_tree_query", - "ast_id_map_shim", - "parse_macro_expansion_shim", - "macro_arg_shim", "crate_local_def_map", "proc_macros_for_crate_shim", "file_item_tree_query", "ast_id_map_shim", "parse_shim", "real_span_map_shim", + "decl_macro_expander_shim", + "file_item_tree_query", + "ast_id_map_shim", + "parse_shim", + "real_span_map_shim", + "file_item_tree_query", + "ast_id_map_shim", + "parse_shim", + "real_span_map_shim", + "macro_def_shim", + "file_item_tree_query", + "ast_id_map_shim", + "parse_macro_expansion_shim", + "macro_arg_shim", + "decl_macro_expander_shim", + "macro_def_shim", + "file_item_tree_query", + "ast_id_map_shim", + "parse_macro_expansion_shim", + "macro_arg_shim", "macro_def_shim", "file_item_tree_query", "ast_id_map_shim", @@ -509,7 +512,8 @@ m!(Z); &db, || { let crate_def_map = crate_def_map(&db, krate); - let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); + let module_data = &crate_def_map + [crate_def_map.modules_for_file(&db, pos.file_id.file_id(&db)).next().unwrap()]; assert_eq!(module_data.scope.resolutions().count(), 4); }, &[("file_item_tree_query", 6), ("parse_macro_expansion_shim", 3)], @@ -558,7 +562,8 @@ m!(Z); &db, || { let crate_def_map = crate_def_map(&db, krate); - let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); + let module_data = &crate_def_map + [crate_def_map.modules_for_file(&db, pos.file_id.file_id(&db)).next().unwrap()]; assert_eq!(module_data.scope.resolutions().count(), 4); }, &[("file_item_tree_query", 1), ("parse_macro_expansion_shim", 0)], diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs index a5fd0488e785..c8eb968b3587 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs @@ -784,7 +784,7 @@ macro_rules! foo { pub use core::clone::Clone; "#, - |map| assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1), + |map| assert_eq!(map.modules[map.root].scope.impls().len(), 1), ); } @@ -806,7 +806,7 @@ pub macro Copy {} #[rustc_builtin_macro] pub macro Clone {} "#, - |map| assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 2), + |map| assert_eq!(map.modules[map.root].scope.impls().len(), 2), ); } @@ -849,7 +849,7 @@ pub macro derive($item:item) {} #[rustc_builtin_macro] pub macro Clone {} "#, - |map| assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1), + |map| assert_eq!(map.modules[map.root].scope.impls().len(), 1), ); } @@ -1502,7 +1502,7 @@ fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a } let krate = *db.all_crates().last().expect("no crate graph present"); let def_map = crate_def_map(&db, krate); - let root_module = &def_map[DefMap::ROOT].scope; + let root_module = &def_map[def_map.root].scope; assert!( root_module.legacy_macros().count() == 0, "`#[macro_use]` shouldn't bring macros into textual macro scope", @@ -1609,7 +1609,7 @@ macro_rules! derive { () => {} } #[derive(Clone)] struct S; "#, - |map| assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1), + |map| assert_eq!(map.modules[map.root].scope.impls().len(), 1), ); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index ccea043739c2..263f603a0bfb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -16,11 +16,11 @@ use syntax::ast::HasName; use triomphe::Arc; use crate::{ - AdtId, AstIdLoc, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, - EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, - GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, - Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, - TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UseId, VariantId, + AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, + ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, ImplId, + ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, + ModuleId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, + TypeParamId, UseId, VariantId, builtin_type::BuiltinType, db::DefDatabase, expr_store::{ @@ -55,7 +55,7 @@ pub struct Resolver<'db> { struct ModuleItemMap<'db> { def_map: &'db DefMap, local_def_map: &'db LocalDefMap, - module_id: LocalModuleId, + module_id: ModuleId, } impl fmt::Debug for ModuleItemMap<'_> { @@ -608,14 +608,14 @@ impl<'db> Resolver<'db> { }, ); local_def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| { - res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into()))); + res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def))); }); BUILTIN_SCOPE.iter().for_each(|(name, &def)| { res.add_per_ns(name, def); }); if let Some((prelude, _use)) = def_map.prelude() { let prelude_def_map = prelude.def_map(db); - for (name, def) in prelude_def_map[prelude.local_id].scope.entries() { + for (name, def) in prelude_def_map[prelude].scope.entries() { res.add_per_ns(name, def) } } @@ -647,7 +647,7 @@ impl<'db> Resolver<'db> { self.module_scope .local_def_map .extern_prelude() - .map(|(name, module_id)| (name.clone(), module_id.0.into())) + .map(|(name, module_id)| (name.clone(), module_id.0)) } pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet { @@ -674,7 +674,7 @@ impl<'db> Resolver<'db> { // Fill in the prelude traits if let Some((prelude, _use)) = self.module_scope.def_map.prelude() { let prelude_def_map = prelude.def_map(db); - traits.extend(prelude_def_map[prelude.local_id].scope.traits()); + traits.extend(prelude_def_map[prelude].scope.traits()); } // Fill in module visible traits traits.extend(self.module_scope.def_map[self.module_scope.module_id].scope.traits()); @@ -691,8 +691,7 @@ impl<'db> Resolver<'db> { } pub fn module(&self) -> ModuleId { - let (def_map, _, local_id) = self.item_scope_(); - def_map.module_id(local_id) + self.item_scope_().2 } pub fn item_scope(&self) -> &ItemScope { @@ -886,7 +885,7 @@ impl<'db> Resolver<'db> { resolver.scopes.push(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, - module_id: DefMap::ROOT, + module_id: def_map.root, })); // FIXME: This adds as many module scopes as there are blocks, but resolving in each // already traverses all parents, so this is O(n²). I think we could only store the @@ -985,7 +984,7 @@ impl<'db> Resolver<'db> { } /// The innermost block scope that contains items or the module scope that contains this resolver. - fn item_scope_(&self) -> (&DefMap, &LocalDefMap, LocalModuleId) { + fn item_scope_(&self) -> (&DefMap, &LocalDefMap, ModuleId) { self.scopes() .find_map(|scope| match scope { Scope::BlockScope(m) => Some((m.def_map, m.local_def_map, m.module_id)), @@ -1091,7 +1090,7 @@ fn resolver_for_scope_<'db>( let local_def_map = block.lookup(db).module.only_local_def_map(db); // Using `DefMap::ROOT` is okay here since inside modules other than the root, // there can't directly be expressions. - r = r.push_block_scope(def_map, local_def_map, DefMap::ROOT); + r = r.push_block_scope(def_map, local_def_map, def_map.root); // FIXME: This adds as many module scopes as there are blocks, but resolving in each // already traverses all parents, so this is O(n²). I think we could only store the // innermost module scope instead? @@ -1124,7 +1123,7 @@ impl<'db> Resolver<'db> { self, def_map: &'db DefMap, local_def_map: &'db LocalDefMap, - module_id: LocalModuleId, + module_id: ModuleId, ) -> Resolver<'db> { self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, module_id })) } @@ -1284,9 +1283,9 @@ pub trait HasResolver: Copy { impl HasResolver for ModuleId { fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { let (mut def_map, local_def_map) = self.local_def_map(db); - let mut module_id = self.local_id; + let mut module_id = self; - if !self.is_within_block() { + if self.block(db).is_none() { return Resolver { scopes: vec![], module_scope: ModuleItemMap { def_map, local_def_map, module_id }, @@ -1296,9 +1295,9 @@ impl HasResolver for ModuleId { let mut modules: SmallVec<[_; 1]> = smallvec![]; while let Some(parent) = def_map.parent() { let block_def_map = mem::replace(&mut def_map, parent.def_map(db)); - let block_module_id = mem::replace(&mut module_id, parent.local_id); + let block_module_id = mem::replace(&mut module_id, parent); modules.push((block_def_map, block_module_id)); - if !parent.is_within_block() { + if parent.block(db).is_none() { break; } } @@ -1313,16 +1312,6 @@ impl HasResolver for ModuleId { } } -impl HasResolver for CrateRootModuleId { - fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { - let (def_map, local_def_map) = self.local_def_map(db); - Resolver { - scopes: vec![], - module_scope: ModuleItemMap { def_map, local_def_map, module_id: DefMap::ROOT }, - } - } -} - impl HasResolver for TraitId { fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { lookup_resolver(db, self).push_generic_params_scope(db, self.into()) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs index e8ccf56059f0..a13ef484baa5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs @@ -860,7 +860,7 @@ fn lower_fields( mut field_name: impl FnMut(usize, &Field) -> Name, override_visibility: Option>, ) -> Option<(Arena, ExpressionStore, ExpressionStoreSourceMap)> { - let cfg_options = module.krate.cfg_options(db); + let cfg_options = module.krate(db).cfg_options(db); let mut col = ExprCollector::new(db, module, fields.file_id); let override_visibility = override_visibility.map(|vis| { LazyCell::new(|| { @@ -938,7 +938,7 @@ impl EnumVariants { let ast_id_map = db.ast_id_map(source.file_id); let mut diagnostics = ThinVec::new(); - let cfg_options = loc.container.krate.cfg_options(db); + let cfg_options = loc.container.krate(db).cfg_options(db); let mut index = 0; let Some(variants) = source.value.variant_list() else { return (EnumVariants { variants: Box::default() }, None); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/src.rs b/src/tools/rust-analyzer/crates/hir-def/src/src.rs index 153fd195f0ad..6fe016f1e680 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/src.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/src.rs @@ -148,7 +148,7 @@ impl HasChildSource for VariantId { let mut map = ArenaMap::new(); match &src.value { ast::StructKind::Tuple(fl) => { - let cfg_options = container.krate.cfg_options(db); + let cfg_options = container.krate(db).cfg_options(db); let mut idx = 0; for fd in fl.fields() { let enabled = AttrFlags::is_cfg_enabled_for(&fd, cfg_options).is_ok(); @@ -163,7 +163,7 @@ impl HasChildSource for VariantId { } } ast::StructKind::Record(fl) => { - let cfg_options = container.krate.cfg_options(db); + let cfg_options = container.krate(db).cfg_options(db); let mut idx = 0; for fd in fl.fields() { let enabled = AttrFlags::is_cfg_enabled_for(&fd, cfg_options).is_ok(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs index 3bb9c361b3c8..cdb49b297042 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/test_db.rs @@ -13,7 +13,7 @@ use syntax::{AstNode, algo, ast}; use triomphe::Arc; use crate::{ - LocalModuleId, Lookup, ModuleDefId, ModuleId, + Lookup, ModuleDefId, ModuleId, db::DefDatabase, nameres::{DefMap, ModuleSource, block_def_map, crate_def_map}, src::HasSource, @@ -154,7 +154,7 @@ impl TestDB { let crate_def_map = crate_def_map(self, krate); for (local_id, data) in crate_def_map.modules() { if data.origin.file_id().map(|file_id| file_id.file_id(self)) == Some(file_id) { - return crate_def_map.module_id(local_id); + return local_id; } } } @@ -168,7 +168,7 @@ impl TestDB { def_map = match self.block_at_position(def_map, position) { Some(it) => it, - None => return def_map.module_id(module), + None => return module, }; loop { let new_map = self.block_at_position(def_map, position); @@ -178,16 +178,16 @@ impl TestDB { } _ => { // FIXME: handle `mod` inside block expression - return def_map.module_id(DefMap::ROOT); + return def_map.root; } } } } /// Finds the smallest/innermost module in `def_map` containing `position`. - fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModuleId { + fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> ModuleId { let mut size = None; - let mut res = DefMap::ROOT; + let mut res = def_map.root; for (module, data) in def_map.modules() { let src = data.definition_source(self); // We're not comparing the `base_db::EditionedFileId`, but rather the VFS `FileId`, because diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index 948f6ed8c32b..a1645de6ec23 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -9,8 +9,8 @@ use syntax::ast::{self, HasVisibility}; use triomphe::Arc; use crate::{ - AssocItemId, HasModule, ItemContainerId, LocalFieldId, LocalModuleId, ModuleId, TraitId, - VariantId, db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, + AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, TraitId, VariantId, + db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, }; pub use crate::item_tree::{RawVisibility, VisibilityExplicitness}; @@ -44,7 +44,7 @@ impl Visibility { pub fn is_visible_from(self, db: &dyn DefDatabase, from_module: ModuleId) -> bool { let to_module = match self { Visibility::Module(m, _) => m, - Visibility::PubCrate(krate) => return from_module.krate == krate, + Visibility::PubCrate(krate) => return from_module.krate(db) == krate, Visibility::Public => return true, }; if from_module == to_module { @@ -52,30 +52,37 @@ impl Visibility { return true; } // if they're not in the same crate, it can't be visible - if from_module.krate != to_module.krate { + if from_module.krate(db) != to_module.krate(db) { return false; } let def_map = from_module.def_map(db); - Self::is_visible_from_def_map_(db, def_map, to_module, from_module.local_id) + Self::is_visible_from_def_map_(db, def_map, to_module, from_module) } pub(crate) fn is_visible_from_def_map( self, db: &dyn DefDatabase, def_map: &DefMap, - from_module: LocalModuleId, + from_module: ModuleId, ) -> bool { + if cfg!(debug_assertions) { + _ = def_map.modules[from_module]; + } let to_module = match self { Visibility::Module(m, _) => m, - Visibility::PubCrate(krate) => return def_map.krate() == krate, + Visibility::PubCrate(krate) => return from_module.krate(db) == krate, Visibility::Public => return true, }; + if from_module == to_module { + // if the modules are the same, visibility is trivially satisfied + return true; + } // if they're not in the same crate, it can't be visible - if def_map.krate() != to_module.krate { + if def_map.krate() != to_module.krate(db) { return false; } - if from_module == to_module.local_id && def_map.block_id() == to_module.block { + if from_module == to_module && def_map.block_id() == to_module.block(db) { // if the modules are the same, visibility is trivially satisfied return true; } @@ -86,9 +93,9 @@ impl Visibility { db: &dyn DefDatabase, def_map: &DefMap, mut to_module: ModuleId, - mut from_module: LocalModuleId, + mut from_module: ModuleId, ) -> bool { - debug_assert_eq!(to_module.krate, def_map.krate()); + debug_assert_eq!(to_module.krate(db), def_map.krate()); // `to_module` might be the root module of a block expression. Those have the same // visibility as the containing module (even though no items are directly nameable from // there, getting this right is important for method resolution). @@ -98,7 +105,7 @@ impl Visibility { // currently computing, so we must not call the `def_map` query for it. let def_map_block = def_map.block_id(); loop { - match (to_module.block, def_map_block) { + match (to_module.block(db), def_map_block) { // `to_module` is not a block, so there is no parent def map to use. (None, _) => (), // `to_module` is at `def_map`'s block, no need to move further. @@ -117,7 +124,7 @@ impl Visibility { let mut def_map = def_map; let mut parent_arc; loop { - if def_map.module_id(from_module) == to_module { + if from_module == to_module { return true; } match def_map[from_module].parent { @@ -127,7 +134,7 @@ impl Visibility { Some(module) => { parent_arc = module.def_map(db); def_map = parent_arc; - from_module = module.local_id; + from_module = module; } // Reached the root module, nothing left to check. None => return false, @@ -141,7 +148,12 @@ impl Visibility { /// /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only /// visible in unrelated modules). - pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option { + pub(crate) fn max( + self, + db: &dyn DefDatabase, + other: Visibility, + def_map: &DefMap, + ) -> Option { match (self, other) { (_, Visibility::Public) | (Visibility::Public, _) => Some(Visibility::Public), (Visibility::PubCrate(krate), Visibility::PubCrate(krateb)) => { @@ -153,11 +165,7 @@ impl Visibility { } (Visibility::Module(mod_, _), Visibility::PubCrate(krate)) | (Visibility::PubCrate(krate), Visibility::Module(mod_, _)) => { - if mod_.krate == krate { - Some(Visibility::PubCrate(krate)) - } else { - None - } + if mod_.krate(db) == krate { Some(Visibility::PubCrate(krate)) } else { None } } (Visibility::Module(mod_a, expl_a), Visibility::Module(mod_b, expl_b)) => { if mod_a == mod_b { @@ -175,26 +183,24 @@ impl Visibility { )); } - if mod_a.krate() != def_map.krate() || mod_b.krate() != def_map.krate() { + if mod_a.krate(db) != def_map.krate() || mod_b.krate(db) != def_map.krate() { return None; } let def_block = def_map.block_id(); - if mod_a.containing_block() != def_block || mod_b.containing_block() != def_block { + if mod_a.block(db) != def_block || mod_b.block(db) != def_block { return None; } - let mut a_ancestors = - iter::successors(Some(mod_a.local_id), |&m| def_map[m].parent); + let mut a_ancestors = iter::successors(Some(mod_a), |&m| def_map[m].parent); - if a_ancestors.any(|m| m == mod_b.local_id) { + if a_ancestors.any(|m| m == mod_b) { // B is above A return Some(Visibility::Module(mod_b, expl_b)); } - let mut b_ancestors = - iter::successors(Some(mod_b.local_id), |&m| def_map[m].parent); - if b_ancestors.any(|m| m == mod_a.local_id) { + let mut b_ancestors = iter::successors(Some(mod_b), |&m| def_map[m].parent); + if b_ancestors.any(|m| m == mod_a) { // A is above B return Some(Visibility::Module(mod_a, expl_a)); } @@ -208,7 +214,12 @@ impl Visibility { /// /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only /// visible in unrelated modules). - pub(crate) fn min(self, other: Visibility, def_map: &DefMap) -> Option { + pub(crate) fn min( + self, + db: &dyn DefDatabase, + other: Visibility, + def_map: &DefMap, + ) -> Option { match (self, other) { (vis, Visibility::Public) | (Visibility::Public, vis) => Some(vis), (Visibility::PubCrate(krate), Visibility::PubCrate(krateb)) => { @@ -220,10 +231,10 @@ impl Visibility { } (Visibility::Module(mod_, exp), Visibility::PubCrate(krate)) | (Visibility::PubCrate(krate), Visibility::Module(mod_, exp)) => { - if mod_.krate == krate { Some(Visibility::Module(mod_, exp)) } else { None } + if mod_.krate(db) == krate { Some(Visibility::Module(mod_, exp)) } else { None } } (Visibility::Module(mod_a, expl_a), Visibility::Module(mod_b, expl_b)) => { - if mod_a == mod_b { + if mod_a.krate(db) != mod_b.krate(db) { // Most module visibilities are `pub(self)`, and assuming no errors // this will be the common and thus fast path. return Some(Visibility::Module( @@ -238,26 +249,24 @@ impl Visibility { )); } - if mod_a.krate() != def_map.krate() || mod_b.krate() != def_map.krate() { + if mod_a.krate(db) != def_map.krate() || mod_b.krate(db) != def_map.krate() { return None; } let def_block = def_map.block_id(); - if mod_a.containing_block() != def_block || mod_b.containing_block() != def_block { + if mod_a.block(db) != def_block || mod_b.block(db) != def_block { return None; } - let mut a_ancestors = - iter::successors(Some(mod_a.local_id), |&m| def_map[m].parent); + let mut a_ancestors = iter::successors(Some(mod_a), |&m| def_map[m].parent); - if a_ancestors.any(|m| m == mod_b.local_id) { + if a_ancestors.any(|m| m == mod_b) { // B is above A return Some(Visibility::Module(mod_a, expl_a)); } - let mut b_ancestors = - iter::successors(Some(mod_b.local_id), |&m| def_map[m].parent); - if b_ancestors.any(|m| m == mod_a.local_id) { + let mut b_ancestors = iter::successors(Some(mod_b), |&m| def_map[m].parent); + if b_ancestors.any(|m| m == mod_a) { // A is above B return Some(Visibility::Module(mod_b, expl_b)); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index f25147622f06..2dc937d76031 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -126,7 +126,7 @@ fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result, ConstEv let interner = DbInterner::new_no_crate(db); let module_id = db.module_for_file(file_id.file_id(db)); let def_map = module_id.def_map(db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; let const_id = scope .declarations() .find_map(|x| match x { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index 79dc6e367226..a6852b87f601 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -164,7 +164,7 @@ impl<'a> DeclValidator<'a> { else { return; }; - let module_data = &module_id.def_map(self.db)[module_id.local_id]; + let module_data = &module_id.def_map(self.db)[module_id]; let Some(module_src) = module_data.declaration_source(self.db) else { return; }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index e7ee7c62b9fd..91448d5806f9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -113,7 +113,7 @@ impl<'a, 'db> MatchCheckCtx<'a, 'db> { /// Returns whether the given ADT is from another crate declared `#[non_exhaustive]`. fn is_foreign_non_exhaustive(&self, adt: hir_def::AdtId) -> bool { - let is_local = adt.krate(self.db) == self.module.krate(); + let is_local = adt.krate(self.db) == self.module.krate(self.db); !is_local && AttrFlags::query(self.db, adt.into()).contains(AttrFlags::NON_EXHAUSTIVE) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs index 6160962e3bb7..bbc381ba5d51 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -165,7 +165,7 @@ impl<'db> UnsafeVisitor<'db> { DefWithBodyId::FunctionId(func) => TargetFeatures::from_fn(db, func), _ => TargetFeatures::default(), }; - let krate = resolver.module().krate(); + let krate = resolver.krate(); let edition = krate.data(db).edition; let target_feature_is_safe = match &krate.workspace_data(db).target { Ok(target) => target_feature_is_safe_in_target(target), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 16c292273134..e1d62a9c7a3e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -18,7 +18,6 @@ use hir_def::{ item_scope::ItemInNs, item_tree::FieldsShape, lang_item::LangItems, - nameres::DefMap, signatures::VariantFields, type_ref::{ ConstRef, LifetimeRef, LifetimeRefId, TraitBoundModifier, TypeBound, TypeRef, TypeRefId, @@ -310,7 +309,7 @@ pub trait HirDisplay<'db> { allow_opaque: bool, ) -> Result { let mut result = String::new(); - let interner = DbInterner::new_with(db, module_id.krate()); + let interner = DbInterner::new_with(db, module_id.krate(db)); match self.hir_fmt(&mut HirFormatter { db, interner, @@ -321,7 +320,7 @@ pub trait HirDisplay<'db> { entity_limit: None, omit_verbose_types: false, closure_style: ClosureStyle::ImplFn, - display_target: DisplayTarget::from_crate(db, module_id.krate()), + display_target: DisplayTarget::from_crate(db, module_id.krate(db)), display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque }, show_container_bounds: false, display_lifetimes: DisplayLifetime::OnlyNamedOrStatic, @@ -1516,7 +1515,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> { _ => false, }) .collect::>(); - let krate = param.id.parent().module(db).krate(); + let krate = param.id.parent().module(db).krate(db); write_bounds_like_dyn_trait_with_prefix( f, "impl", @@ -2031,13 +2030,14 @@ pub fn write_visibility<'db>( Visibility::PubCrate(_) => write!(f, "pub(crate) "), Visibility::Module(vis_id, _) => { let def_map = module_id.def_map(f.db); - let root_module_id = def_map.module_id(DefMap::ROOT); + let root_module_id = def_map.root_module_id(); if vis_id == module_id { // pub(self) or omitted Ok(()) - } else if root_module_id == vis_id && !root_module_id.is_within_block() { + } else if root_module_id == vis_id && root_module_id.block(f.db).is_none() { write!(f, "pub(crate) ") - } else if module_id.containing_module(f.db) == Some(vis_id) && !vis_id.is_block_module() + } else if module_id.containing_module(f.db) == Some(vis_id) + && !vis_id.is_block_module(f.db) { write!(f, "pub(super) ") } else { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs index def3c44927a1..3ae6451d6952 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs @@ -25,12 +25,12 @@ fn has_destructor(interner: DbInterner<'_>, adt: AdtId) -> bool { let Some(drop_trait) = interner.lang_items().Drop else { return false; }; - let impls = match module.containing_block() { + let impls = match module.block(db) { Some(block) => match TraitImpls::for_block(db, block) { Some(it) => &**it, None => return false, }, - None => TraitImpls::for_crate(db, module.krate()), + None => TraitImpls::for_crate(db, module.krate(db)), }; !impls.for_trait_and_self_ty(drop_trait, &SimplifiedType::Adt(adt.into())).is_empty() } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index 4c1590a4502e..506c4abc8377 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs @@ -3,9 +3,9 @@ use std::ops::ControlFlow; use hir_def::{ - AssocItemId, ConstId, CrateRootModuleId, FunctionId, GenericDefId, HasModule, TraitId, - TypeAliasId, TypeOrConstParamId, TypeParamId, hir::generics::LocalTypeOrConstParamId, - signatures::TraitFlags, + AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId, TypeAliasId, + TypeOrConstParamId, TypeParamId, hir::generics::LocalTypeOrConstParamId, + nameres::crate_def_map, signatures::TraitFlags, }; use rustc_hash::FxHashSet; use rustc_type_ir::{ @@ -130,7 +130,7 @@ pub fn dyn_compatibility_of_trait_query( } pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool { - let krate = def.module(db).krate(); + let krate = def.module(db).krate(db); let interner = DbInterner::new_with(db, krate); let Some(sized) = interner.lang_items().Sized else { return false; @@ -295,7 +295,7 @@ where }) } AssocItemId::TypeAliasId(it) => { - let def_map = CrateRootModuleId::from(trait_.krate(db)).def_map(db); + let def_map = crate_def_map(db, trait_.krate(db)); if def_map.is_unstable_feature_enabled(&intern::sym::generic_associated_type_extended) { ControlFlow::Continue(()) } else { @@ -402,7 +402,7 @@ fn receiver_is_dispatchable<'db>( let sig = sig.instantiate_identity(); let module = trait_.module(db); - let interner = DbInterner::new_with(db, module.krate()); + let interner = DbInterner::new_with(db, module.krate(db)); let self_param_id = TypeParamId::from_unchecked(TypeOrConstParamId { parent: trait_.into(), local_id: LocalTypeOrConstParamId::from_raw(la_arena::RawIdx::from_u32(0)), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs index f90cd608e997..5c9b06e39a70 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs @@ -35,7 +35,7 @@ fn check_dyn_compatibility<'a>( for (trait_id, name) in file_ids.into_iter().flat_map(|file_id| { let module_id = db.module_for_file(file_id.file_id(&db)); let def_map = module_id.def_map(&db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; scope .declarations() .filter_map(|def| { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs index 251e7f7cf6b8..d6d63891bb06 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs @@ -47,7 +47,7 @@ impl<'db> HirPlace<'db> { |_, _, _| { unreachable!("Closure field only happens in MIR"); }, - ctx.owner.module(ctx.db).krate(), + ctx.owner.module(ctx.db).krate(ctx.db), ); } ty @@ -149,7 +149,7 @@ impl<'db> CapturedItem<'db> { } } } - if is_raw_identifier(&result, owner.module(db).krate().data(db).edition) { + if is_raw_identifier(&result, owner.module(db).krate(db).data(db).edition) { result.insert_str(0, "r#"); } result @@ -843,7 +843,7 @@ impl<'db> InferenceContext<'_, 'db> { |_, _, _| { unreachable!("Closure field only happens in MIR"); }, - self.owner.module(self.db).krate(), + self.owner.module(self.db).krate(self.db), ); if ty.is_raw_ptr() || ty.is_union() { capture.kind = CaptureKind::ByRef(BorrowKind::Shared); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index 43215253ba16..be6a76478a11 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs @@ -45,7 +45,7 @@ fn eval_goal( .find_map(|file_id| { let module_id = db.module_for_file(file_id.file_id(&db)); let def_map = module_id.def_map(&db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; let adt_or_type_alias_id = scope.declarations().find_map(|x| match x { hir_def::ModuleDefId::AdtId(x) => { let name = match x { @@ -118,7 +118,7 @@ fn eval_expr( crate::attach_db(&db, || { let module_id = db.module_for_file(file_id.file_id(&db)); let def_map = module_id.def_map(&db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; let function_id = scope .declarations() .find_map(|x| match x { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 301e89556df2..dd34bbe2fd02 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -1755,13 +1755,12 @@ pub(crate) fn trait_environment_query<'db>( def: GenericDefId, ) -> ParamEnv<'db> { let module = def.module(db); - let interner = DbInterner::new_with(db, module.krate()); + let interner = DbInterner::new_with(db, module.krate(db)); let predicates = GenericPredicates::query_all(db, def); let clauses = rustc_type_ir::elaborate::elaborate(interner, predicates.iter_identity_copied()); let clauses = Clauses::new_from_iter(interner, clauses); // FIXME: We should normalize projections here, like rustc does. - ParamEnv { clauses } } @@ -2280,7 +2279,7 @@ pub(crate) fn associated_type_by_name_including_super_traits<'db>( name: &Name, ) -> Option<(TraitRef<'db>, TypeAliasId)> { let module = trait_ref.def_id.0.module(db); - let interner = DbInterner::new_with(db, module.krate()); + let interner = DbInterner::new_with(db, module.krate(db)); rustc_type_ir::elaborate::supertraits(interner, Binder::dummy(trait_ref)).find_map(|t| { let trait_id = t.as_ref().skip_binder().def_id.0; let assoc_type = trait_id.trait_items(db).associated_type_by_name(name)?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index a5ec2a3fec66..868ae00329b3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -633,7 +633,7 @@ impl InherentImpls { block: Option, for_each: &mut dyn FnMut(&InherentImpls), ) { - let blocks = std::iter::successors(block, |block| block.loc(db).module.containing_block()); + let blocks = std::iter::successors(block, |block| block.loc(db).module.block(db)); blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each); for_each(Self::for_crate(db, krate)); } @@ -798,7 +798,7 @@ impl TraitImpls { block: Option, for_each: &mut dyn FnMut(&TraitImpls), ) { - let blocks = std::iter::successors(block, |block| block.loc(db).module.containing_block()); + let blocks = std::iter::successors(block, |block| block.loc(db).module.block(db)); blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each); Self::for_crate_and_deps(db, krate).iter().map(|it| &**it).for_each(for_each); } @@ -820,7 +820,7 @@ impl TraitImpls { // This breaks when they are equal (both will stop immediately), therefore we handle this case // specifically. let blocks_iter = |block: Option| { - std::iter::successors(block, |block| block.loc(db).module.containing_block()) + std::iter::successors(block, |block| block.loc(db).module.block(db)) }; let for_each_block = |current_block: Option, other_block: Option| { blocks_iter(current_block) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs index 02f86815edd2..6af47ab68bfc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs @@ -980,8 +980,8 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { }; InherentImpls::for_each_crate_and_block( self.db(), - module.krate(), - module.containing_block(), + module.krate(self.db()), + module.block(self.db()), &mut |impls| { for &impl_def_id in impls.for_self_ty(self_ty) { self.assemble_inherent_impl_probe(impl_def_id, receiver_steps); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index 031654a25984..4d76a9f3fb3d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs @@ -97,7 +97,7 @@ pub fn borrowck_query<'db>( ) -> Result]>, MirLowerError<'db>> { let _p = tracing::info_span!("borrowck_query").entered(); let module = def.module(db); - let interner = DbInterner::new_with(db, module.krate()); + let interner = DbInterner::new_with(db, module.krate(db)); let env = db.trait_environment_for_body(def); let mut res = vec![]; // This calculates opaques defining scope which is a bit costly therefore is put outside `all_mir_bodies()`. @@ -148,7 +148,7 @@ fn moved_out_of_ref<'db>( infcx, ty, make_fetch_closure_field(db), - body.owner.module(db).krate(), + body.owner.module(db).krate(db), ); } if is_dereference_of_ref @@ -244,7 +244,7 @@ fn partially_moved<'db>( infcx, ty, make_fetch_closure_field(db), - body.owner.module(db).krate(), + body.owner.module(db).krate(db), ); } if !infcx.type_is_copy_modulo_regions(env, ty) && !ty.references_non_lt_error() { @@ -397,7 +397,7 @@ fn place_case<'db>( infcx, ty, make_fetch_closure_field(db), - body.owner.module(db).krate(), + body.owner.module(db).krate(db), ); } if is_part_of { ProjectionCase::DirectPart } else { ProjectionCase::Direct } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 02e322f03781..35b45174c209 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -635,7 +635,7 @@ impl<'db> Evaluator<'db> { trait_env: Option>, ) -> Result<'db, Evaluator<'db>> { let module = owner.module(db); - let crate_id = module.krate(); + let crate_id = module.krate(db); let target_data_layout = match db.target_data_layout(crate_id) { Ok(target_data_layout) => target_data_layout, Err(e) => return Err(MirEvalError::TargetDataLayoutNotAvailable(e)), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs index 2c0c3427cbde..c13b76c12579 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs @@ -20,7 +20,7 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), let interner = DbInterner::new_no_crate(db); let module_id = db.module_for_file(file_id.file_id(db)); let def_map = module_id.def_map(db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; let func_id = scope .declarations() .find_map(|x| match x { @@ -90,7 +90,7 @@ fn check_pass_and_stdio( line_index(range.end()) ) }; - let krate = db.module_for_file(file_id.file_id(&db)).krate(); + let krate = db.module_for_file(file_id.file_id(&db)).krate(&db); e.pretty_print( &mut err, &db, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/tests.rs index 38fc7ad78a28..357f617a21e1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/tests.rs @@ -9,7 +9,7 @@ fn lower_mir(#[rust_analyzer::rust_fixture] ra_fixture: &str) { let file_id = *file_ids.last().unwrap(); let module_id = db.module_for_file(file_id.file_id(&db)); let def_map = module_id.def_map(&db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; let funcs = scope.declarations().filter_map(|x| match x { hir_def::ModuleDefId::FunctionId(it) => Some(it), _ => None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 2e52dcea6c5b..2541ed43ec38 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -1694,7 +1694,7 @@ impl<'db> Interner for DbInterner<'db> { mut f: impl FnMut(Self::ImplId), ) { let krate = self.krate.expect("trait solving requires setting `DbInterner::krate`"); - let trait_block = trait_def_id.0.loc(self.db).container.containing_block(); + let trait_block = trait_def_id.0.loc(self.db).container.block(self.db); let mut consider_impls_for_simplified_type = |simp: SimplifiedType| { let type_block = simp.def().and_then(|def_id| { let module = match def_id { @@ -1713,7 +1713,7 @@ impl<'db> Interner for DbInterner<'db> { | SolverDefId::EnumVariantId(_) | SolverDefId::Ctor(_) => return None, }; - module.containing_block() + module.block(self.db) }); TraitImpls::for_each_crate_and_block_trait_and_type( self.db, @@ -1828,7 +1828,7 @@ impl<'db> Interner for DbInterner<'db> { fn for_each_blanket_impl(self, trait_def_id: Self::TraitId, mut f: impl FnMut(Self::ImplId)) { let Some(krate) = self.krate else { return }; - let block = trait_def_id.0.loc(self.db).container.containing_block(); + let block = trait_def_id.0.loc(self.db).container.block(self.db); TraitImpls::for_each_crate_and_block(self.db, krate, block, &mut |impls| { for &impl_ in impls.blanket_impls(trait_def_id.0) { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs index c0a7c9adc485..ff89f8e059a5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs @@ -656,7 +656,7 @@ impl<'db> Ty<'db> { } TyKind::Coroutine(coroutine_id, _args) => { let InternedCoroutine(owner, _) = coroutine_id.0.loc(db); - let krate = owner.module(db).krate(); + let krate = owner.module(db).krate(db); if let Some(future_trait) = hir_def::lang_item::lang_items(db, krate).Future { // This is only used by type walking. // Parameters will be walked outside, and projection predicate is not used. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs index dbac20074b28..4c6b585016fa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs @@ -118,7 +118,7 @@ pub(crate) fn tait_hidden_types<'db>( let loc = type_alias.loc(db); let module = loc.module(db); - let interner = DbInterner::new_with(db, module.krate()); + let interner = DbInterner::new_with(db, module.krate(db)); let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); let mut ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs index 495a9937f6c9..9ae9a8e2a993 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs @@ -148,7 +148,7 @@ pub(crate) fn specializes( // `#[allow_internal_unstable(specialization)]`, but `#[allow_internal_unstable]` // is an internal feature, std is not using it for specialization nor is likely to // ever use it, and we don't have the span information necessary to replicate that. - let def_map = crate_def_map(db, module.krate()); + let def_map = crate_def_map(db, module.krate(db)); if !def_map.is_unstable_feature_enabled(&sym::specialization) && !def_map.is_unstable_feature_enabled(&sym::min_specialization) { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs index 7044ca5d23ae..7bd314cb8e39 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/test_db.rs @@ -138,9 +138,9 @@ impl TestDB { let file_id = file_id.into(); for &krate in self.relevant_crates(file_id).iter() { let crate_def_map = crate_def_map(self, krate); - for (local_id, data) in crate_def_map.modules() { + for (module_id, data) in crate_def_map.modules() { if data.origin.file_id().map(|file_id| file_id.file_id(self)) == Some(file_id) { - return Some(crate_def_map.module_id(local_id)); + return Some(module_id); } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index 1acb0b82b146..a31353f1e336 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -16,7 +16,7 @@ mod traits; use base_db::{Crate, SourceDatabase}; use expect_test::Expect; use hir_def::{ - AssocItemId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleDefId, SyntheticSyntax, + AssocItemId, DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, SyntheticSyntax, db::DefDatabase, expr_store::{Body, BodySourceMap}, hir::{ExprId, Pat, PatId}, @@ -114,7 +114,7 @@ fn check_impl( None => continue, }; let def_map = module.def_map(&db); - visit_module(&db, def_map, module.local_id, &mut |it| { + visit_module(&db, def_map, module, &mut |it| { let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), @@ -122,7 +122,7 @@ fn check_impl( ModuleDefId::StaticId(it) => it.into(), _ => return, }; - defs.push((def, module.krate())) + defs.push((def, module.krate(&db))) }); } defs.sort_by_key(|(def, _)| match def { @@ -412,7 +412,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { let def_map = module.def_map(&db); let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new(); - visit_module(&db, def_map, module.local_id, &mut |it| { + visit_module(&db, def_map, module, &mut |it| { let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), @@ -420,7 +420,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { ModuleDefId::StaticId(it) => it.into(), _ => return, }; - defs.push((def, module.krate())) + defs.push((def, module.krate(&db))) }); defs.sort_by_key(|(def, _)| match def { DefWithBodyId::FunctionId(it) => { @@ -454,7 +454,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { pub(crate) fn visit_module( db: &TestDB, crate_def_map: &DefMap, - module_id: LocalModuleId, + module_id: ModuleId, cb: &mut dyn FnMut(ModuleDefId), ) { visit_scope(db, crate_def_map, &crate_def_map[module_id].scope, cb); @@ -517,7 +517,7 @@ pub(crate) fn visit_module( } } } - ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it.local_id, cb), + ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it, cb), _ => (), } } @@ -593,7 +593,7 @@ fn salsa_bug() { crate::attach_db(&db, || { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { InferenceResult::for_body( &db, match def { @@ -637,7 +637,7 @@ fn salsa_bug() { crate::attach_db(&db, || { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { InferenceResult::for_body( &db, match def { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs index ef71681636ef..ff55ff54cefb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs @@ -24,7 +24,7 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec let def_map = module.def_map(&db); let mut defs = Vec::new(); - visit_module(&db, def_map, module.local_id, &mut |it| defs.push(it)); + visit_module(&db, def_map, module, &mut |it| defs.push(it)); let mut captures_info = Vec::new(); for def in defs { @@ -75,7 +75,7 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec let capture_ty = capture .ty .skip_binder() - .display_test(db, DisplayTarget::from_crate(db, module.krate())) + .display_test(db, DisplayTarget::from_crate(db, module.krate(db))) .to_string(); let spans = capture .spans() diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index fd564a300dce..7b0c1d35442e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -22,7 +22,7 @@ fn foo() -> i32 { || { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { InferenceResult::for_body(&db, it.into()); } @@ -66,7 +66,7 @@ fn foo() -> i32 { || { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { InferenceResult::for_body(&db, it.into()); } @@ -109,7 +109,7 @@ fn baz() -> i32 { || { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { InferenceResult::for_body(&db, it.into()); } @@ -178,7 +178,7 @@ fn baz() -> i32 { || { let module = db.module_for_file(pos.file_id.file_id(&db)); let crate_def_map = module.def_map(&db); - visit_module(&db, crate_def_map, module.local_id, &mut |def| { + visit_module(&db, crate_def_map, module, &mut |def| { if let ModuleDefId::FunctionId(it) = def { InferenceResult::for_body(&db, it.into()); } @@ -232,7 +232,7 @@ $0", || { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - TraitImpls::for_crate(&db, module.krate()); + TraitImpls::for_crate(&db, module.krate(&db)); }, &[("TraitImpls::for_crate_", 1)], expect_test::expect![[r#" @@ -268,7 +268,7 @@ pub struct NewStruct { || { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - TraitImpls::for_crate(&db, module.krate()); + TraitImpls::for_crate(&db, module.krate(&db)); }, &[("TraitImpls::for_crate_", 1)], expect_test::expect![[r#" @@ -303,7 +303,7 @@ $0", || { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - TraitImpls::for_crate(&db, module.krate()); + TraitImpls::for_crate(&db, module.krate(&db)); }, &[("TraitImpls::for_crate_", 1)], expect_test::expect![[r#" @@ -340,7 +340,7 @@ pub enum SomeEnum { || { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - TraitImpls::for_crate(&db, module.krate()); + TraitImpls::for_crate(&db, module.krate(&db)); }, &[("TraitImpls::for_crate_", 1)], expect_test::expect![[r#" @@ -375,7 +375,7 @@ $0", || { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - TraitImpls::for_crate(&db, module.krate()); + TraitImpls::for_crate(&db, module.krate(&db)); }, &[("TraitImpls::for_crate_", 1)], expect_test::expect![[r#" @@ -409,7 +409,7 @@ fn bar() -> f32 { || { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - TraitImpls::for_crate(&db, module.krate()); + TraitImpls::for_crate(&db, module.krate(&db)); }, &[("TraitImpls::for_crate_", 1)], expect_test::expect![[r#" @@ -448,7 +448,7 @@ $0", || { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - TraitImpls::for_crate(&db, module.krate()); + TraitImpls::for_crate(&db, module.krate(&db)); }, &[("TraitImpls::for_crate_", 1)], expect_test::expect![[r#" @@ -490,7 +490,7 @@ impl SomeStruct { || { let module = db.module_for_file(pos.file_id.file_id(&db)); let _crate_def_map = module.def_map(&db); - TraitImpls::for_crate(&db, module.krate()); + TraitImpls::for_crate(&db, module.krate(&db)); }, &[("TraitImpls::for_crate_", 1)], expect_test::expect![[r#" @@ -546,7 +546,7 @@ fn main() { let module = db.module_for_file(file_id.file_id(&db)); let crate_def_map = module.def_map(&db); let mut defs: Vec = vec![]; - visit_module(&db, crate_def_map, module.local_id, &mut |it| { + visit_module(&db, crate_def_map, module, &mut |it| { let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), @@ -643,7 +643,7 @@ fn main() { let crate_def_map = module.def_map(&db); let mut defs: Vec = vec![]; - visit_module(&db, crate_def_map, module.local_id, &mut |it| { + visit_module(&db, crate_def_map, module, &mut |it| { let def = match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::EnumVariantId(it) => it.into(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index b1a2802264e4..2f8c31ec6074 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -207,10 +207,10 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id | TyKind::Uint(_) | TyKind::Float(_) => def_map.is_rustc_coherence_is_core(), - TyKind::Adt(adt_def, _) => adt_def.def_id().0.module(db).krate() == def_map.krate(), + TyKind::Adt(adt_def, _) => adt_def.def_id().0.module(db).krate(db) == def_map.krate(), TyKind::Dynamic(it, _) => it .principal_def_id() - .is_some_and(|trait_id| trait_id.0.module(db).krate() == def_map.krate()), + .is_some_and(|trait_id| trait_id.0.module(db).krate(db) == def_map.krate()), _ => true, }; @@ -283,12 +283,12 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool return true; }; - let local_crate = impl_.lookup(db).container.krate(); + let local_crate = impl_.lookup(db).container.krate(db); let is_local = |tgt_crate| tgt_crate == local_crate; let trait_ref = impl_trait.instantiate_identity(); let trait_id = trait_ref.def_id.0; - if is_local(trait_id.module(db).krate()) { + if is_local(trait_id.module(db).krate(db)) { // trait to be implemented is local return true; } @@ -322,10 +322,10 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool // FIXME: param coverage // - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`) let is_not_orphan = trait_ref.args.types().any(|ty| match unwrap_fundamental(ty).kind() { - TyKind::Adt(adt_def, _) => is_local(adt_def.def_id().0.module(db).krate()), + TyKind::Adt(adt_def, _) => is_local(adt_def.def_id().0.module(db).krate(db)), TyKind::Error(_) => true, TyKind::Dynamic(it, _) => { - it.principal_def_id().is_some_and(|trait_id| is_local(trait_id.0.module(db).krate())) + it.principal_def_id().is_some_and(|trait_id| is_local(trait_id.0.module(db).krate(db))) } _ => false, }); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index df9d53f3e579..5c0af6dafb52 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs @@ -874,7 +874,7 @@ struct FixedPoint(&'static FixedPoint<(), T, U>, V); let mut defs: Vec = Vec::new(); let module = db.module_for_file_opt(file_id.file_id(&db)).unwrap(); let def_map = module.def_map(&db); - crate::tests::visit_module(&db, def_map, module.local_id, &mut |it| { + crate::tests::visit_module(&db, def_map, module, &mut |it| { defs.push(match it { ModuleDefId::FunctionId(it) => it.into(), ModuleDefId::AdtId(it) => it.into(), diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs index 2f412d88ab33..d1056f31e19e 100644 --- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs @@ -3,8 +3,7 @@ use cfg::CfgExpr; use either::Either; use hir_def::{ - AssocItemId, AttrDefId, FieldId, InternedModuleId, LifetimeParamId, ModuleDefId, - TypeOrConstParamId, + AssocItemId, AttrDefId, FieldId, LifetimeParamId, ModuleDefId, TypeOrConstParamId, attrs::{AttrFlags, Docs, IsInnerDoc}, expr_store::path::Path, item_scope::ItemInNs, @@ -213,8 +212,8 @@ impl_has_attrs_enum![TypeParam, ConstParam, LifetimeParam for GenericParam]; impl HasAttrs for Module { #[inline] - fn attr_id(self, db: &dyn HirDatabase) -> AttrsOwner { - AttrsOwner::AttrDef(AttrDefId::ModuleId(InternedModuleId::new(db, self.id))) + fn attr_id(self, _: &dyn HirDatabase) -> AttrsOwner { + AttrsOwner::AttrDef(AttrDefId::ModuleId(self.id)) } } @@ -243,7 +242,7 @@ impl HasAttrs for AssocItem { impl HasAttrs for crate::Crate { #[inline] fn attr_id(self, db: &dyn HirDatabase) -> AttrsOwner { - self.root_module().attr_id(db) + self.root_module(db).attr_id(db) } } @@ -274,7 +273,6 @@ fn resolve_doc_path_on_( ) -> Option { let resolver = match attr_id { AttrsOwner::AttrDef(AttrDefId::ModuleId(it)) => { - let it = it.loc(db); if is_inner_doc.yes() { it.resolver(db) } else if let Some(parent) = Module::from(it).parent(db) { diff --git a/src/tools/rust-analyzer/crates/hir/src/has_source.rs b/src/tools/rust-analyzer/crates/hir/src/has_source.rs index 9ea1456a4124..1aa799400106 100644 --- a/src/tools/rust-analyzer/crates/hir/src/has_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/has_source.rs @@ -35,23 +35,23 @@ impl Module { /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. pub fn definition_source(self, db: &dyn HirDatabase) -> InFile { let def_map = self.id.def_map(db); - def_map[self.id.local_id].definition_source(db) + def_map[self.id].definition_source(db) } /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. pub fn definition_source_range(self, db: &dyn HirDatabase) -> InFile { let def_map = self.id.def_map(db); - def_map[self.id.local_id].definition_source_range(db) + def_map[self.id].definition_source_range(db) } pub fn definition_source_file_id(self, db: &dyn HirDatabase) -> HirFileId { let def_map = self.id.def_map(db); - def_map[self.id.local_id].definition_source_file_id() + def_map[self.id].definition_source_file_id() } pub fn is_mod_rs(self, db: &dyn HirDatabase) -> bool { let def_map = self.id.def_map(db); - match def_map[self.id.local_id].origin { + match def_map[self.id].origin { ModuleOrigin::File { is_mod_rs, .. } => is_mod_rs, _ => false, } @@ -59,7 +59,7 @@ impl Module { pub fn as_source_file_id(self, db: &dyn HirDatabase) -> Option { let def_map = self.id.def_map(db); - match def_map[self.id.local_id].origin { + match def_map[self.id].origin { ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition, .. } => { Some(definition) } @@ -69,21 +69,21 @@ impl Module { pub fn is_inline(self, db: &dyn HirDatabase) -> bool { let def_map = self.id.def_map(db); - def_map[self.id.local_id].origin.is_inline() + def_map[self.id].origin.is_inline() } /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. /// `None` for the crate root. pub fn declaration_source(self, db: &dyn HirDatabase) -> Option> { let def_map = self.id.def_map(db); - def_map[self.id.local_id].declaration_source(db) + def_map[self.id].declaration_source(db) } /// Returns a text range which declares this module, either a `mod foo;` or a `mod foo {}`. /// `None` for the crate root. pub fn declaration_source_range(self, db: &dyn HirDatabase) -> Option> { let def_map = self.id.def_map(db); - def_map[self.id.local_id].declaration_source_range(db) + def_map[self.id].declaration_source_range(db) } } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 63da5a3a37cf..56560e24c08c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -48,11 +48,11 @@ use arrayvec::ArrayVec; use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin}; use either::Either; use hir_def::{ - AdtId, AssocItemId, AssocItemLoc, CallableDefId, ConstId, ConstParamId, CrateRootModuleId, - DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, - GenericParamId, HasModule, ImplId, InternedModuleId, ItemContainerId, LifetimeParamId, - LocalFieldId, Lookup, MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId, - TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, + AdtId, AssocItemId, AssocItemLoc, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, + EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, + HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, + MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, TypeOrConstParamId, + TypeParamId, UnionId, attrs::AttrFlags, expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, hir::{ @@ -258,13 +258,13 @@ impl Crate { .flatten() } - pub fn root_module(self) -> Module { - Module { id: CrateRootModuleId::from(self.id).into() } + pub fn root_module(self, db: &dyn HirDatabase) -> Module { + Module { id: crate_def_map(db, self.id).root_module_id() } } pub fn modules(self, db: &dyn HirDatabase) -> Vec { let def_map = crate_def_map(db, self.id); - def_map.modules().map(|(id, _)| def_map.module_id(id).into()).collect() + def_map.modules().map(|(id, _)| id.into()).collect() } pub fn root_file(self, db: &dyn HirDatabase) -> FileId { @@ -520,7 +520,7 @@ impl ModuleDef { impl HasCrate for ModuleDef { fn krate(&self, db: &dyn HirDatabase) -> Crate { match self.module(db) { - Some(module) => module.krate(), + Some(module) => module.krate(db), None => Crate::core(db).unwrap_or_else(|| db.all_crates()[0].into()), } } @@ -550,29 +550,29 @@ impl Module { } /// Returns the crate this module is part of. - pub fn krate(self) -> Crate { - Crate { id: self.id.krate() } + pub fn krate(self, db: &dyn HirDatabase) -> Crate { + Crate { id: self.id.krate(db) } } /// Topmost parent of this module. Every module has a `crate_root`, but some /// might be missing `krate`. This can happen if a module's file is not included /// in the module tree of any target in `Cargo.toml`. pub fn crate_root(self, db: &dyn HirDatabase) -> Module { - let def_map = crate_def_map(db, self.id.krate()); - Module { id: def_map.crate_root().into() } + let def_map = crate_def_map(db, self.id.krate(db)); + Module { id: def_map.crate_root(db).into() } } - pub fn is_crate_root(self) -> bool { - DefMap::ROOT == self.id.local_id + pub fn is_crate_root(self, db: &dyn HirDatabase) -> bool { + self.crate_root(db) == self } /// Iterates over all child modules. pub fn children(self, db: &dyn HirDatabase) -> impl Iterator { let def_map = self.id.def_map(db); - let children = def_map[self.id.local_id] + let children = def_map[self.id] .children .values() - .map(|module_id| Module { id: def_map.module_id(*module_id) }) + .map(|module_id| Module { id: *module_id }) .collect::>(); children.into_iter() } @@ -580,14 +580,14 @@ impl Module { /// Finds a parent module. pub fn parent(self, db: &dyn HirDatabase) -> Option { let def_map = self.id.def_map(db); - let parent_id = def_map.containing_module(self.id.local_id)?; + let parent_id = def_map.containing_module(self.id)?; Some(Module { id: parent_id }) } /// Finds nearest non-block ancestor `Module` (`self` included). pub fn nearest_non_block_module(self, db: &dyn HirDatabase) -> Module { let mut id = self.id; - while id.is_block_module() { + while id.is_block_module(db) { id = id.containing_module(db).expect("block without parent module"); } Module { id } @@ -609,7 +609,7 @@ impl Module { db: &dyn HirDatabase, visible_from: Option, ) -> Vec<(Name, ScopeDef)> { - self.id.def_map(db)[self.id.local_id] + self.id.def_map(db)[self.id] .scope .entries() .filter_map(|(name, def)| { @@ -646,19 +646,19 @@ impl Module { style_lints: bool, ) { let _p = tracing::info_span!("diagnostics", name = ?self.name(db)).entered(); - let edition = self.id.krate().data(db).edition; + let edition = self.id.krate(db).data(db).edition; let def_map = self.id.def_map(db); for diag in def_map.diagnostics() { - if diag.in_module != self.id.local_id { + if diag.in_module != self.id { // FIXME: This is accidentally quadratic. continue; } emit_def_diagnostic(db, acc, diag, edition, def_map.krate()); } - if !self.id.is_block_module() { + if !self.id.is_block_module(db) { // These are reported by the body of block modules - let scope = &def_map[self.id.local_id].scope; + let scope = &def_map[self.id].scope; scope.all_macro_calls().for_each(|it| macro_call_diagnostics(db, it, acc)); } @@ -666,7 +666,7 @@ impl Module { match def { ModuleDef::Module(m) => { // Only add diagnostics from inline modules - if def_map[m.id.local_id].origin.is_inline() { + if def_map[m.id].origin.is_inline() { m.diagnostics(db, acc, style_lints) } acc.extend(def.diagnostics(db, style_lints)) @@ -765,7 +765,7 @@ impl Module { } self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m)); - let interner = DbInterner::new_with(db, self.id.krate()); + let interner = DbInterner::new_with(db, self.id.krate(db)); let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); let mut impl_assoc_items_scratch = vec![]; @@ -790,7 +790,7 @@ impl Module { let ast_id_map = db.ast_id_map(file_id); for diag in impl_def.id.impl_items_with_diagnostics(db).1.iter() { - emit_def_diagnostic(db, acc, diag, edition, loc.container.krate()); + emit_def_diagnostic(db, acc, diag, edition, loc.container.krate(db)); } if impl_signature.target_trait.is_none() @@ -939,7 +939,7 @@ impl Module { pub fn declarations(self, db: &dyn HirDatabase) -> Vec { let def_map = self.id.def_map(db); - let scope = &def_map[self.id.local_id].scope; + let scope = &def_map[self.id].scope; scope .declarations() .map(ModuleDef::from) @@ -949,13 +949,13 @@ impl Module { pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec { let def_map = self.id.def_map(db); - let scope = &def_map[self.id.local_id].scope; + let scope = &def_map[self.id].scope; scope.legacy_macros().flat_map(|(_, it)| it).map(|&it| it.into()).collect() } pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec { let def_map = self.id.def_map(db); - def_map[self.id.local_id].scope.impls().map(Impl::from).collect() + def_map[self.id].scope.impls().map(Impl::from).collect() } /// Finds a path that can be used to refer to the given item from within @@ -990,7 +990,7 @@ impl Module { #[inline] pub fn doc_keyword(self, db: &dyn HirDatabase) -> Option { - AttrFlags::doc_keyword(db, InternedModuleId::new(db, self.id)) + AttrFlags::doc_keyword(db, self.id) } /// Whether it has `#[path = "..."]` attribute. @@ -1196,7 +1196,7 @@ fn precise_macro_call_location( impl HasVisibility for Module { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { let def_map = self.id.def_map(db); - let module_data = &def_map[self.id.local_id]; + let module_data = &def_map[self.id]; module_data.visibility } } @@ -1541,7 +1541,7 @@ impl Enum { pub fn variant_body_ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> { let interner = DbInterner::new_no_crate(db); Type::new_for_crate( - self.id.lookup(db).container.krate(), + self.id.lookup(db).container.krate(db), match EnumSignature::variant_body_type(db, self.id) { layout::IntegerType::Pointer(sign) => match sign { true => Ty::new_int(interner, rustc_type_ir::IntTy::Isize), @@ -1927,7 +1927,7 @@ impl DefWithBody { pub fn debug_mir(self, db: &dyn HirDatabase) -> String { let body = db.mir_body(self.id()); match body { - Ok(body) => body.pretty_print(db, self.module(db).krate().to_display_target(db)), + Ok(body) => body.pretty_print(db, self.module(db).krate(db).to_display_target(db)), Err(e) => format!("error:\n{e:?}"), } } @@ -1938,7 +1938,7 @@ impl DefWithBody { acc: &mut Vec>, style_lints: bool, ) { - let krate = self.module(db).id.krate(); + let krate = self.module(db).id.krate(db); let (body, source_map) = db.body_with_source_map(self.into()); let sig_source_map = match self { @@ -1952,7 +1952,7 @@ impl DefWithBody { }; for (_, def_map) in body.blocks(db) { - Module { id: def_map.module_id(DefMap::ROOT) }.diagnostics(db, acc, style_lints); + Module { id: def_map.root_module_id() }.diagnostics(db, acc, style_lints); } expr_store_diagnostics(db, acc, &source_map); @@ -2398,7 +2398,7 @@ impl Function { /// is this a `fn main` or a function with an `export_name` of `main`? pub fn is_main(self, db: &dyn HirDatabase) -> bool { self.exported_main(db) - || self.module(db).is_crate_root() && db.function_signature(self.id).name == sym::main + || self.module(db).is_crate_root(db) && db.function_signature(self.id).name == sym::main } /// Is this a function with an `export_name` of `main`? @@ -2657,7 +2657,7 @@ impl ExternCrateDecl { pub fn resolved_crate(self, db: &dyn HirDatabase) -> Option { let loc = self.id.lookup(db); - let krate = loc.container.krate(); + let krate = loc.container.krate(db); let name = self.name(db); if name == sym::self_ { Some(krate.into()) @@ -3239,8 +3239,8 @@ impl ItemInNs { /// Returns the crate defining this item (or `None` if `self` is built-in). pub fn krate(&self, db: &dyn HirDatabase) -> Option { match self { - ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate()), - ItemInNs::Macros(id) => Some(id.module(db).krate()), + ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate(db)), + ItemInNs::Macros(id) => Some(id.module(db).krate(db)), } } @@ -4323,7 +4323,7 @@ impl Impl { } pub fn all_in_module(db: &dyn HirDatabase, module: Module) -> Vec { - module.id.def_map(db)[module.id.local_id].scope.impls().map(Into::into).collect() + module.id.def_map(db)[module.id].scope.impls().map(Into::into).collect() } /// **Note:** This is an **approximation** that strives to give the *human-perceived notion* of an "impl for type", @@ -4348,15 +4348,13 @@ impl Impl { if let Some(module) = method_resolution::simplified_type_module(db, &simplified_ty) { InherentImpls::for_each_crate_and_block( db, - module.krate(), - module.containing_block(), + module.krate(db), + module.block(db), &mut |impls| extend_with_impls(impls.for_self_ty(&simplified_ty)), ); - std::iter::successors(module.containing_block(), |block| { - block.loc(db).module.containing_block() - }) - .filter_map(|block| TraitImpls::for_block(db, block).as_deref()) - .for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls)); + std::iter::successors(module.block(db), |block| block.loc(db).module.block(db)) + .filter_map(|block| TraitImpls::for_block(db, block).as_deref()) + .for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls)); for &krate in &**db.all_crates() { TraitImpls::for_crate(db, krate) .for_self_ty(&simplified_ty, &mut extend_with_impls); @@ -4376,10 +4374,10 @@ impl Impl { let mut handle_impls = |impls: &TraitImpls| { impls.for_trait(trait_.id, |impls| all.extend(impls.iter().copied().map(Impl::from))); }; - for krate in module.krate().transitive_rev_deps(db) { + for krate in module.krate(db).transitive_rev_deps(db) { handle_impls(TraitImpls::for_crate(db, krate)); } - if let Some(block) = module.containing_block() + if let Some(block) = module.block(db) && let Some(impls) = TraitImpls::for_block(db, block) { handle_impls(impls); @@ -4431,7 +4429,7 @@ impl Impl { MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, .. } => { let module_id = self.id.lookup(db).container; ( - crate_def_map(db, module_id.krate())[module_id.local_id] + module_id.def_map(db)[module_id] .scope .derive_macro_invoc(ast_id, derive_attr_index)?, derive_index, @@ -5329,8 +5327,8 @@ impl<'db> Type<'db> { if let Some(module) = method_resolution::simplified_type_module(db, &simplified_type) { InherentImpls::for_each_crate_and_block( db, - module.krate(), - module.containing_block(), + module.krate(db), + module.block(db), &mut |impls| { handle_impls(impls.for_self_ty(&simplified_type)); }, @@ -5466,7 +5464,7 @@ impl<'db> Type<'db> { f: impl FnOnce(&MethodResolutionContext<'_, 'db>) -> R, ) -> R { let module = resolver.module(); - let interner = DbInterner::new_with(db, module.krate()); + let interner = DbInterner::new_with(db, module.krate(db)); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let unstable_features = MethodResolutionUnstableFeatures::from_def_map(resolver.top_level_def_map()); @@ -6140,12 +6138,12 @@ impl ScopeDef { pub fn krate(&self, db: &dyn HirDatabase) -> Option { match self { - ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate()), - ScopeDef::GenericParam(it) => Some(it.module(db).krate()), + ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate(db)), + ScopeDef::GenericParam(it) => Some(it.module(db).krate(db)), ScopeDef::ImplSelfType(_) => None, - ScopeDef::AdtSelfType(it) => Some(it.module(db).krate()), - ScopeDef::Local(it) => Some(it.module(db).krate()), - ScopeDef::Label(it) => Some(it.module(db).krate()), + ScopeDef::AdtSelfType(it) => Some(it.module(db).krate(db)), + ScopeDef::Local(it) => Some(it.module(db).krate(db)), + ScopeDef::Label(it) => Some(it.module(db).krate(db)), ScopeDef::Unknown => None, } } @@ -6205,61 +6203,61 @@ pub trait HasCrate { impl HasCrate for T { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate().into() + self.module(db).krate(db).into() } } impl HasCrate for AssocItem { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Struct { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Union { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Enum { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Field { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.parent_def(db).module(db).krate() + self.parent_def(db).module(db).krate(db) } } impl HasCrate for Variant { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Function { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Const { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for TypeAlias { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } @@ -6271,37 +6269,37 @@ impl HasCrate for Type<'_> { impl HasCrate for Macro { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Trait { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Static { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Adt { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Impl { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Module { - fn krate(&self, _: &dyn HirDatabase) -> Crate { - Module::krate(*self) + fn krate(&self, db: &dyn HirDatabase) -> Crate { + Module::krate(*self, db) } } @@ -6319,8 +6317,8 @@ impl HasContainer for Module { fn container(&self, db: &dyn HirDatabase) -> ItemContainer { // FIXME: handle block expressions as modules (their parent is in a different DefMap) let def_map = self.id.def_map(db); - match def_map[self.id.local_id].parent { - Some(parent_id) => ItemContainer::Module(Module { id: def_map.module_id(parent_id) }), + match def_map[self.id].parent { + Some(parent_id) => ItemContainer::Module(Module { id: parent_id }), None => ItemContainer::Crate(def_map.krate().into()), } } @@ -6479,7 +6477,7 @@ pub fn resolve_absolute_path<'a, I: Iterator + Clone + 'a>( .filter_map(|&krate| { let segments = segments.clone(); let mut def_map = crate_def_map(db, krate); - let mut module = &def_map[DefMap::ROOT]; + let mut module = &def_map[def_map.root_module_id()]; let mut segments = segments.with_position().peekable(); while let Some((_, segment)) = segments.next_if(|&(position, _)| { !matches!(position, itertools::Position::Last | itertools::Position::Only) @@ -6493,7 +6491,7 @@ pub fn resolve_absolute_path<'a, I: Iterator + Clone + 'a>( _ => None, })?; def_map = res.def_map(db); - module = &def_map[res.local_id]; + module = &def_map[res]; } let (_, item_name) = segments.next()?; let res = module.scope.get(&Name::new_symbol_root(item_name)); diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 195fafad5cbc..ffb518b1e66f 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -442,13 +442,13 @@ impl<'db> SemanticsImpl<'db> { /// If not crate is found for the file, try to return the last crate in topological order. pub fn first_crate(&self, file: FileId) -> Option { match self.file_to_module_defs(file).next() { - Some(module) => Some(module.krate()), + Some(module) => Some(module.krate(self.db)), None => self.db.all_crates().last().copied().map(Into::into), } } pub fn attach_first_edition_opt(&self, file: FileId) -> Option { - let krate = self.file_to_module_defs(file).next()?.krate(); + let krate = self.file_to_module_defs(file).next()?.krate(self.db); Some(EditionedFileId::new(self.db, file, krate.edition(self.db), krate.id)) } @@ -478,8 +478,8 @@ impl<'db> SemanticsImpl<'db> { match file_id { HirFileId::FileId(file_id) => { let module = self.file_to_module_defs(file_id.file_id(self.db)).next()?; - let def_map = crate_def_map(self.db, module.krate().id); - match def_map[module.id.local_id].origin { + let def_map = crate_def_map(self.db, module.krate(self.db).id); + match def_map[module.id].origin { ModuleOrigin::CrateRoot { .. } => None, ModuleOrigin::File { declaration, declaration_tree_id, .. } => { let file_id = declaration_tree_id.file_id(); @@ -505,7 +505,7 @@ impl<'db> SemanticsImpl<'db> { /// the `SyntaxNode` of the *definition* file, not of the *declaration*. pub fn module_definition_node(&self, module: Module) -> InFile { let def_map = module.id.def_map(self.db); - let definition = def_map[module.id.local_id].origin.definition_source(self.db); + let definition = def_map[module.id].origin.definition_source(self.db); let definition = definition.map(|it| it.node()); let root_node = find_root(&definition.value); self.cache(root_node, definition.file_id); @@ -534,7 +534,7 @@ impl<'db> SemanticsImpl<'db> { let file_id = self.find_file(attr.syntax()).file_id; let krate = match file_id { HirFileId::FileId(file_id) => { - self.file_to_module_defs(file_id.file_id(self.db)).next()?.krate().id + self.file_to_module_defs(file_id.file_id(self.db)).next()?.krate(self.db).id } HirFileId::MacroFile(macro_file) => self.db.lookup_intern_macro_call(macro_file).krate, }; diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index 165ac7e4a08d..c1f72debe54f 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -20,7 +20,6 @@ use hir_def::{ }, hir::generics::GenericParams, item_scope::ItemScope, - nameres::DefMap, src::{HasChildSource, HasSource}, }; @@ -87,7 +86,7 @@ impl ChildBySource for ImplId { impl ChildBySource for ModuleId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { let def_map = self.def_map(db); - let module_data = &def_map[self.local_id]; + let module_data = &def_map[*self]; module_data.scope.child_by_source_to(db, res, file_id); } } @@ -226,7 +225,7 @@ impl ChildBySource for DefWithBodyId { for (block, def_map) in body.blocks(db) { // All block expressions are merged into the same map, because they logically all add // inner items to the containing `DefWithBodyId`. - def_map[DefMap::ROOT].scope.child_by_source_to(db, res, file_id); + def_map[def_map.root].scope.child_by_source_to(db, res, file_id); res[keys::BLOCK].insert(block.lookup(db).ast_id.to_ptr(db), block); } } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 44df4d8fc8c8..257405992731 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -183,11 +183,7 @@ impl SourceToDefCtx<'_, '_> { // Note: `mod` declarations in block modules cannot be supported here let crate_def_map = crate_def_map(self.db, crate_id); let n_mods = mods.len(); - let modules = |file| { - crate_def_map - .modules_for_file(self.db, file) - .map(|local_id| crate_def_map.module_id(local_id)) - }; + let modules = |file| crate_def_map.modules_for_file(self.db, file); mods.extend(modules(file)); if mods.len() == n_mods { mods.extend( @@ -239,8 +235,8 @@ impl SourceToDefCtx<'_, '_> { let child_name = src.value.name()?.as_name(); let def_map = parent_module.def_map(self.db); - let &child_id = def_map[parent_module.local_id].children.get(&child_name)?; - Some(def_map.module_id(child_id)) + let &child_id = def_map[parent_module].children.get(&child_name)?; + Some(child_id) } pub(super) fn source_file_to_def(&mut self, src: InFile<&ast::SourceFile>) -> Option { diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 1530e697a3f2..a9320fdda7e1 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -255,7 +255,7 @@ impl<'a> SymbolCollector<'a> { }; let def_map = module_id.def_map(self.db); - let scope = &def_map[module_id.local_id].scope; + let scope = &def_map[module_id].scope; for impl_id in scope.impls() { self.collect_from_impl(impl_id); @@ -329,10 +329,7 @@ impl<'a> SymbolCollector<'a> { // Descend into the blocks and enqueue collection of all modules within. for (_, def_map) in body.blocks(self.db) { for (id, _) in def_map.modules() { - self.work.push(SymbolCollectorWork { - module_id: def_map.module_id(id), - parent: name.clone(), - }); + self.work.push(SymbolCollectorWork { module_id: id, parent: name.clone() }); } } } @@ -451,7 +448,7 @@ impl<'a> SymbolCollector<'a> { fn push_module(&mut self, module_id: ModuleId, name: &Name) { let def_map = module_id.def_map(self.db); - let module_data = &def_map[module_id.local_id]; + let module_data = &def_map[module_id]; let Some(declaration) = module_data.origin.declaration() else { return }; let module = declaration.to_node(self.db); let Some(name_node) = module.name() else { return }; diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs index 979ec8c49fe7..05a89e76529b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs @@ -762,7 +762,7 @@ pub(super) fn make_tuple<'a, 'lt, 'db, DB: HirDatabase>( .filter(|_| should_continue()) .map(|params| { let tys: Vec> = params.iter().map(|it| it.ty(db)).collect(); - let tuple_ty = Type::new_tuple(module.krate().into(), &tys); + let tuple_ty = Type::new_tuple(module.krate(db).into(), &tys); let expr = Expr::Tuple { ty: tuple_ty.clone(), params }; lookup.insert(tuple_ty, iter::once(expr.clone())); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs index e970bb7167d1..65ca1ceae11e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -130,7 +130,7 @@ fn add_missing_impl_members_inner( if let IgnoreAssocItems::DocHiddenAttrPresent = ignore_items { // Relax condition for local crates. let db = ctx.db(); - if trait_.module(db).krate().origin(db).is_local() { + if trait_.module(db).krate(db).origin(db).is_local() { ign_item = IgnoreAssocItems::No; } } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 248ce2ad6115..10c3ff0e4d2b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -92,24 +92,25 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) bool, bool, ) = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr, self_ty.as_ref()) { - let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate()); + let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate(ctx.db())); let variants = enum_def.variants(ctx.db()); - let has_hidden_variants = - variants.iter().any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + let has_hidden_variants = variants + .iter() + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let missing_pats = variants .into_iter() .filter_map(|variant| { Some(( build_pat(ctx, &make, module, variant, cfg)?, - variant.should_be_hidden(ctx.db(), module.krate()), + variant.should_be_hidden(ctx.db(), module.krate(ctx.db())), )) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); - let option_enum = FamousDefs(&ctx.sema, module.krate()).core_option_Option(); + let option_enum = FamousDefs(&ctx.sema, module.krate(ctx.db())).core_option_Option(); let missing_pats: Box> = if matches!(enum_def, ExtendedEnum::Enum { enum_: e, .. } if Some(e) == option_enum) { // Match `Some` variant first. @@ -120,8 +121,9 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) }; (missing_pats.peekable(), is_non_exhaustive, has_hidden_variants) } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr, self_ty.as_ref()) { - let is_non_exhaustive = - enum_defs.iter().any(|enum_def| enum_def.is_non_exhaustive(ctx.db(), module.krate())); + let is_non_exhaustive = enum_defs + .iter() + .any(|enum_def| enum_def.is_non_exhaustive(ctx.db(), module.krate(ctx.db()))); let mut n_arms = 1; let variants_of_enums: Vec> = enum_defs @@ -145,7 +147,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let has_hidden_variants = variants_of_enums .iter() .flatten() - .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let missing_pats = variants_of_enums .into_iter() @@ -154,7 +156,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .map(|variants| { let is_hidden = variants .iter() - .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let patterns = variants .into_iter() .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg)); @@ -170,15 +172,16 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) } else if let Some((enum_def, len)) = resolve_array_of_enum_def(&ctx.sema, &expr, self_ty.as_ref()) { - let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate()); + let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate(ctx.db())); let variants = enum_def.variants(ctx.db()); if len.pow(variants.len() as u32) > 256 { return None; } - let has_hidden_variants = - variants.iter().any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + let has_hidden_variants = variants + .iter() + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let variants_of_enums = vec![variants; len]; @@ -189,7 +192,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .map(|variants| { let is_hidden = variants .iter() - .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); + .any(|variant| variant.should_be_hidden(ctx.db(), module.krate(ctx.db()))); let patterns = variants .into_iter() .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg)); @@ -401,7 +404,7 @@ impl ExtendedVariant { fn should_be_hidden(self, db: &RootDatabase, krate: Crate) -> bool { match self { ExtendedVariant::Variant { variant: var, .. } => { - var.attrs(db).is_doc_hidden() && var.module(db).krate() != krate + var.attrs(db).is_doc_hidden() && var.module(db).krate(db) != krate } _ => false, } @@ -424,7 +427,7 @@ impl ExtendedEnum { fn is_non_exhaustive(&self, db: &RootDatabase, krate: Crate) -> bool { match self { ExtendedEnum::Enum { enum_: e, .. } => { - e.attrs(db).is_non_exhaustive() && e.module(db).krate() != krate + e.attrs(db).is_non_exhaustive() && e.module(db).krate(db) != krate } _ => false, } @@ -502,7 +505,7 @@ fn build_pat( let db = ctx.db(); match var { ExtendedVariant::Variant { variant: var, use_self } => { - let edition = module.krate().edition(db); + let edition = module.krate(db).edition(db); let path = if use_self { make::path_from_segments( [ diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs index 3281adbcc3bb..d193e8a9d8dc 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs @@ -260,7 +260,7 @@ fn validate_method_call_expr( let receiver = method_call.receiver()?; let it_type = sema.type_of_expr(&receiver)?.adjusted(); let module = sema.scope(receiver.syntax())?.module(); - let krate = module.krate(); + let krate = module.krate(ctx.db()); let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; it_type.impls_trait(sema.db, iter_trait, &[]).then_some((name_ref, arg_expr)) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs index bb6a10d40b71..cc2bf8174941 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs @@ -114,7 +114,8 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< proposed_imports.sort_by_key(|import| { Reverse(relevance_score(ctx, import, expected.as_ref(), current_module.as_ref())) }); - let edition = current_module.map(|it| it.krate().edition(ctx.db())).unwrap_or(Edition::CURRENT); + let edition = + current_module.map(|it| it.krate(ctx.db()).edition(ctx.db())).unwrap_or(Edition::CURRENT); let group_label = group_label(import_assets.import_candidate()); for import in proposed_imports { @@ -316,11 +317,11 @@ fn module_distance_heuristic(db: &dyn HirDatabase, current: &Module, item: &Modu let distinct_length = current_path.len() + item_path.len() - 2 * prefix_length; // cost of importing from another crate - let crate_boundary_cost = if current.krate() == item.krate() { + let crate_boundary_cost = if current.krate(db) == item.krate(db) { 0 - } else if item.krate().origin(db).is_local() { + } else if item.krate(db).origin(db).is_local() { 2 - } else if item.krate().is_builtin(db) { + } else if item.krate(db).is_builtin(db) { 3 } else { 4 diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs index 2ad13362378e..1ae5f6491744 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_to_enum.rs @@ -329,7 +329,7 @@ fn augment_references_with_imports( ) -> Vec { let mut visited_modules = FxHashSet::default(); - let edition = target_module.krate().edition(ctx.db()); + let edition = target_module.krate(ctx.db()).edition(ctx.db()); references .into_iter() .filter_map(|FileReference { range, name, .. }| { @@ -345,8 +345,9 @@ fn augment_references_with_imports( ImportScope::find_insert_use_container(name.syntax(), &ctx.sema).and_then( |import_scope| { - let cfg = - ctx.config.find_path_config(ctx.sema.is_nightly(target_module.krate())); + let cfg = ctx.config.find_path_config( + ctx.sema.is_nightly(target_module.krate(ctx.sema.db)), + ); let path = ref_module .find_use_path( ctx.sema.db, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs index 156286d564f2..ef2dc355b8a7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_for_to_while_let.rs @@ -150,7 +150,7 @@ fn impls_core_iter(sema: &hir::Semantics<'_, ide_db::RootDatabase>, iterable: &a let module = sema.scope(iterable.syntax())?.module(); - let krate = module.krate(); + let krate = module.krate(sema.db); let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; cov_mark::hit!(test_already_impls_iterator); Some(it_typ.impls_trait(sema.db, iter_trait, &[])) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs index 7d8b763d8b87..6a74d214512f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs @@ -64,7 +64,7 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_> let tail_expr = from_fn.body()?.tail_expr()?; if resolve_target_trait(&ctx.sema, &impl_)? - != FamousDefs(&ctx.sema, module.krate()).core_convert_From()? + != FamousDefs(&ctx.sema, module.krate(ctx.db())).core_convert_From()? { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs index 8f02d28b8245..e33010242351 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs @@ -39,11 +39,11 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) - let module = ctx.sema.scope(impl_.syntax())?.module(); let trait_ = resolve_target_trait(&ctx.sema, &impl_)?; - if trait_ != FamousDefs(&ctx.sema, module.krate()).core_convert_Into()? { + if trait_ != FamousDefs(&ctx.sema, module.krate(ctx.db())).core_convert_Into()? { return None; } - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate())); + let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate(ctx.sema.db))); let src_type_path = { let src_type_path = src_type.syntax().descendants().find_map(ast::Path::cast)?; @@ -53,7 +53,7 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) - }; mod_path_to_ast( &module.find_path(ctx.db(), src_type_def, cfg)?, - module.krate().edition(ctx.db()), + module.krate(ctx.db()).edition(ctx.db()), ) }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs index c8a244b2136d..0c0458468df8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs @@ -186,7 +186,7 @@ fn impls_core_iter(sema: &hir::Semantics<'_, ide_db::RootDatabase>, iterable: &a let module = sema.scope(iterable.syntax())?.module(); - let krate = module.krate(); + let krate = module.krate(sema.db); let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; cov_mark::hit!(test_already_impls_iterator); Some(it_typ.impls_trait(sema.db, iter_trait, &[])) @@ -214,7 +214,7 @@ fn validate_method_call_expr( let it_type = sema.type_of_expr(&receiver)?.adjusted(); let module = sema.scope(receiver.syntax())?.module(); - let krate = module.krate(); + let krate = module.krate(ctx.db()); let iter_trait = FamousDefs(sema, krate).core_iter_Iterator()?; it_type.impls_trait(sema.db, iter_trait, &[]).then_some((expr, receiver)) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs index 9876e14203fe..0e5e6185d054 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs @@ -199,7 +199,8 @@ fn augment_references_with_imports( { visited_modules.insert(ref_module); - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(ref_module.krate())); + let cfg = + ctx.config.find_path_config(ctx.sema.is_nightly(ref_module.krate(ctx.sema.db))); let import_scope = ImportScope::find_insert_use_container(new_name.syntax(), &ctx.sema); let path = ref_module @@ -211,7 +212,10 @@ fn augment_references_with_imports( ) .map(|mod_path| { make::path_concat( - mod_path_to_ast(&mod_path, target_module.krate().edition(ctx.db())), + mod_path_to_ast( + &mod_path, + target_module.krate(ctx.db()).edition(ctx.db()), + ), make::path_from_text(struct_name), ) }); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index 46f210804da3..bb5d11221087 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -88,13 +88,14 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option) -> Option (true, current_module.krate().root_module()), - VisibilityKind::PubCrate => (false, current_module.krate().root_module()), + VisibilityKind::Pub => (true, current_module.krate(ctx.db()).root_module(ctx.db())), + VisibilityKind::PubCrate => { + (false, current_module.krate(ctx.db()).root_module(ctx.db())) + } _ => (false, current_module), } }; @@ -167,7 +169,7 @@ fn build_expanded_import( let names_to_import = find_names_to_import(filtered_defs, imported_defs); let expanded = make::use_tree_list(names_to_import.iter().map(|n| { let path = make::ext::ident_path( - &n.display(ctx.db(), current_module.krate().edition(ctx.db())).to_string(), + &n.display(ctx.db(), current_module.krate(ctx.db()).edition(ctx.db())).to_string(), ); make::use_tree(path, None, None, false) })) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 44d020a1b46c..4b7314be4609 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -206,10 +206,11 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op { let scope = builder.make_import_scope_mut(scope); let control_flow_enum = - FamousDefs(&ctx.sema, module.krate()).core_ops_ControlFlow(); + FamousDefs(&ctx.sema, module.krate(ctx.db())).core_ops_ControlFlow(); if let Some(control_flow_enum) = control_flow_enum { - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate())); + let cfg = + ctx.config.find_path_config(ctx.sema.is_nightly(module.krate(ctx.sema.db))); let mod_path = module.find_use_path( ctx.sema.db, ModuleDef::from(control_flow_enum), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index 2cec3296c87e..386652a42292 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -400,7 +400,8 @@ fn process_references( let segment = builder.make_mut(segment); let scope_node = builder.make_syntax_mut(scope_node); if !visited_modules.contains(&module) { - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate())); + let cfg = + ctx.config.find_path_config(ctx.sema.is_nightly(module.krate(ctx.sema.db))); let mod_path = module.find_use_path( ctx.sema.db, *enum_module_def, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs index 55de537debf3..0fd8057a3958 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs @@ -59,7 +59,7 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) let (vis_owner, target, target_file, target_name) = target_data_for_def(ctx.db(), def)?; - let missing_visibility = if current_module.krate() == target_module.krate() { + let missing_visibility = if current_module.krate(ctx.db()) == target_module.krate(ctx.db()) { make::visibility_pub_crate() } else { make::visibility_pub() @@ -70,7 +70,7 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) Some(name) => { format!( "Change visibility of {} to {missing_visibility}", - name.display(ctx.db(), current_module.krate().edition(ctx.db())) + name.display(ctx.db(), current_module.krate(ctx.db()).edition(ctx.db())) ) } }; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs index 056edb00b687..b4a17c376ac6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs @@ -75,7 +75,7 @@ fn existing_default_impl( ) -> Option<()> { let variant = sema.to_def(variant)?; let enum_ = variant.parent_enum(sema.db); - let krate = enum_.module(sema.db).krate(); + let krate = enum_.module(sema.db).krate(sema.db); let default_trait = FamousDefs(sema, krate).core_default_Default()?; let enum_type = enum_.ty(sema.db); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs index 47233fb399d7..48400d436aa6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_default_from_new.rs @@ -137,7 +137,7 @@ fn is_default_implemented(ctx: &AssistContext<'_>, impl_: &Impl) -> bool { }; let ty = impl_def.self_ty(db); - let krate = impl_def.module(db).krate(); + let krate = impl_def.module(db).krate(ctx.db()); let default = FamousDefs(&ctx.sema, krate).core_default_Default(); let default_trait = match default { Some(value) => value, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs index b2e791abf72d..c1eb1a74ecde 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs @@ -57,7 +57,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' let strukt = ctx.find_node_at_offset::()?; let strukt_name = strukt.name()?; let current_module = ctx.sema.scope(strukt.syntax())?.module(); - let current_edition = current_module.krate().edition(ctx.db()); + let current_edition = current_module.krate(ctx.db()).edition(ctx.db()); let (field_name, field_ty, target) = match ctx.find_node_at_offset::() { Some(field) => { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs index e87dde5b8e42..a2d49063e69e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_trait.rs @@ -124,7 +124,7 @@ impl Field { let db = ctx.sema.db; let module = ctx.sema.file_to_module_def(ctx.vfs_file_id())?; - let edition = module.krate().edition(ctx.db()); + let edition = module.krate(ctx.db()).edition(ctx.db()); let (name, range, ty) = match f { Either::Left(f) => { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs index b02e3e435c81..494c87e6d136 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs @@ -57,8 +57,8 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( }; let module = ctx.sema.to_def(&strukt)?.module(ctx.db()); - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate())); - let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?; + let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate(ctx.db()))); + let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate(ctx.db()))?; let trait_path = module.find_path(ctx.db(), ModuleDef::Trait(trait_), cfg)?; let field_type = field.ty()?; @@ -77,7 +77,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( field_name.syntax(), deref_type_to_generate, trait_path, - module.krate().edition(ctx.db()), + module.krate(ctx.db()).edition(ctx.db()), ) }, ) @@ -99,8 +99,8 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() }; let module = ctx.sema.to_def(&strukt)?.module(ctx.db()); - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate())); - let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?; + let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate(ctx.sema.db))); + let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate(ctx.db()))?; let trait_path = module.find_path(ctx.db(), ModuleDef::Trait(trait_), cfg)?; let field_type = field.ty()?; @@ -118,7 +118,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() field_list_index, deref_type_to_generate, trait_path, - module.krate().edition(ctx.db()), + module.krate(ctx.db()).edition(ctx.db()), ) }, ) @@ -163,7 +163,7 @@ fn existing_deref_impl( strukt: &ast::Struct, ) -> Option { let strukt = sema.to_def(strukt)?; - let krate = strukt.module(sema.db).krate(); + let krate = strukt.module(sema.db).krate(sema.db); let deref_trait = FamousDefs(sema, krate).core_ops_Deref()?; let deref_mut_trait = FamousDefs(sema, krate).core_ops_DerefMut()?; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs index 199c85d98d6f..24f271ded80b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs @@ -121,7 +121,7 @@ fn existing_from_impl( ) -> Option<()> { let db = sema.db; let variant = sema.to_def(variant)?; - let krate = variant.module(db).krate(); + let krate = variant.module(db).krate(db); let from_trait = FamousDefs(sema, krate).core_convert_From()?; let interner = DbInterner::new_with(db, krate.base()); use hir::next_solver::infer::DbInternerInferExt; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs index a9cf2c1bae1a..bd66c02b4150 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs @@ -71,7 +71,7 @@ fn gen_fn(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { fn_target_info(ctx, path, &call, fn_name)?; if let Some(m) = target_module - && !is_editable_crate(m.krate(), ctx.db()) + && !is_editable_crate(m.krate(ctx.db()), ctx.db()) { return None; } @@ -143,7 +143,7 @@ fn gen_method(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let adt = receiver_ty.as_adt()?; let target_module = adt.module(ctx.sema.db); - if !is_editable_crate(target_module.krate(), ctx.db()) { + if !is_editable_crate(target_module.krate(ctx.db()), ctx.db()) { return None; } @@ -241,7 +241,7 @@ impl FunctionBuilder { ) -> Option { let target_module = target_module.or_else(|| ctx.sema.scope(target.syntax()).map(|it| it.module()))?; - let target_edition = target_module.krate().edition(ctx.db()); + let target_edition = target_module.krate(ctx.db()).edition(ctx.db()); let current_module = ctx.sema.scope(call.syntax())?.module(); let visibility = calculate_necessary_visibility(current_module, target_module, ctx); @@ -311,7 +311,7 @@ impl FunctionBuilder { target_module: Module, target: GeneratedFunctionTarget, ) -> Option { - let target_edition = target_module.krate().edition(ctx.db()); + let target_edition = target_module.krate(ctx.db()).edition(ctx.db()); let current_module = ctx.sema.scope(call.syntax())?.module(); let visibility = calculate_necessary_visibility(current_module, target_module, ctx); @@ -546,7 +546,7 @@ fn assoc_fn_target_info( let current_module = ctx.sema.scope(call.syntax())?.module(); let module = adt.module(ctx.sema.db); let target_module = if current_module == module { None } else { Some(module) }; - if current_module.krate() != module.krate() { + if current_module.krate(ctx.db()) != module.krate(ctx.db()) { return None; } let (impl_, file) = get_adt_source(ctx, &adt, fn_name)?; @@ -1149,7 +1149,10 @@ fn fn_arg_type( convert_reference_type(ty.strip_references(), ctx.db(), famous_defs) .map(|conversion| { conversion - .convert_type(ctx.db(), target_module.krate().to_display_target(ctx.db())) + .convert_type( + ctx.db(), + target_module.krate(ctx.db()).to_display_target(ctx.db()), + ) .to_string() }) .or_else(|| ty.display_source_code(ctx.db(), target_module.into(), true).ok()) @@ -1235,7 +1238,7 @@ fn calculate_necessary_visibility( let current_module = current_module.nearest_non_block_module(db); let target_module = target_module.nearest_non_block_module(db); - if target_module.krate() != current_module.krate() { + if target_module.krate(ctx.db()) != current_module.krate(ctx.db()) { Visibility::Pub } else if current_module.path_to_root(db).contains(&target_module) { Visibility::None diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs index cd968b97105a..4b923ab556b8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs @@ -77,14 +77,16 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?)); - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(current_module.krate())); + let cfg = ctx + .config + .find_path_config(ctx.sema.is_nightly(current_module.krate(ctx.sema.db))); let type_path = current_module.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, cfg, )?; - let edition = current_module.krate().edition(ctx.db()); + let edition = current_module.krate(ctx.db()).edition(ctx.db()); let expr = use_trivial_constructor( ctx.sema.db, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs index bdb42f9c1fae..d3022ceda379 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs @@ -178,7 +178,7 @@ fn make_constructors( types: &[ast::Type], ) -> Vec> { let (db, sema) = (ctx.db(), &ctx.sema); - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate())); + let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate(ctx.sema.db))); types .iter() .map(|ty| { @@ -187,7 +187,7 @@ fn make_constructors( return Some(make::expr_tuple([]).into()); } let item_in_ns = ModuleDef::Adt(ty.as_adt()?).into(); - let edition = module.krate().edition(db); + let edition = module.krate(db).edition(db); let ty_path = module.find_path(db, item_for_path_search(db, item_in_ns)?, cfg)?; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs index 5367350052cb..fa4f2a78c8b7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs @@ -110,7 +110,7 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) -> let mut inline_refs_for_file = |file_id: EditionedFileId, refs: Vec| { let file_id = file_id.file_id(ctx.db()); builder.edit_file(file_id); - let call_krate = ctx.sema.file_to_module_def(file_id).map(|it| it.krate()); + let call_krate = ctx.sema.file_to_module_def(file_id).map(|it| it.krate(ctx.db())); let count = refs.len(); // The collects are required as we are otherwise iterating while mutating 🙅‍♀️🙅‍♂️ let (name_refs, name_refs_use) = split_refs_and_uses(builder, refs, Some); @@ -196,7 +196,7 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< let name_ref: ast::NameRef = ctx.find_node_at_offset()?; let call_info = CallInfo::from_name_ref( name_ref.clone(), - ctx.sema.file_to_module_def(ctx.vfs_file_id())?.krate().into(), + ctx.sema.file_to_module_def(ctx.vfs_file_id())?.krate(ctx.db()).into(), )?; let (function, label) = match &call_info.node { ast::CallableExpr::Call(call) => { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_macro.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_macro.rs index b09bef36ae15..280bd7f2ca9a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_macro.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_macro.rs @@ -38,7 +38,7 @@ use crate::{AssistContext, AssistId, Assists}; pub(crate) fn inline_macro(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let unexpanded = ctx.find_node_at_offset::()?; let macro_call = ctx.sema.to_def(&unexpanded)?; - let target_crate_id = ctx.sema.file_to_module_def(ctx.vfs_file_id())?.krate().into(); + let target_crate_id = ctx.sema.file_to_module_def(ctx.vfs_file_id())?.krate(ctx.db()).into(); let text_range = unexpanded.syntax().text_range(); acc.add( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs index d8dbefd59e28..495a84d62b07 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs @@ -42,10 +42,10 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> let resolved_call = ctx.sema.resolve_method_call(&call)?; let current_module = ctx.sema.scope(call.syntax())?.module(); - let current_edition = current_module.krate().edition(ctx.db()); + let current_edition = current_module.krate(ctx.db()).edition(ctx.db()); let target_module_def = ModuleDef::from(resolved_call); let item_in_ns = ItemInNs::from(target_module_def); - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(current_module.krate())); + let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(current_module.krate(ctx.sema.db))); let receiver_path = current_module.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs index 8834ad97652e..b3cf2969650a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs @@ -82,7 +82,7 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option proposed_imports.dedup_by(|a, b| a.import_path == b.import_path); let current_edition = - current_module.map(|it| it.krate().edition(ctx.db())).unwrap_or(Edition::CURRENT); + current_module.map(|it| it.krate(ctx.db()).edition(ctx.db())).unwrap_or(Edition::CURRENT); // prioritize more relevant imports proposed_imports.sort_by_key(|import| { Reverse(super::auto_import::relevance_score( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 2bf4406cc6a9..11b3fd22faa3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -69,7 +69,7 @@ pub(crate) fn replace_derive_with_manual_impl( let args = attr.token_tree()?; let current_module = ctx.sema.scope(adt.syntax())?.module(); - let current_crate = current_module.krate(); + let current_crate = current_module.krate(ctx.db()); let current_edition = current_crate.edition(ctx.db()); let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(current_crate)); @@ -193,7 +193,7 @@ fn impl_def_from_trait( let target_scope = sema.scope(annotated_name.syntax())?; // Keep assoc items of local crates even if they have #[doc(hidden)] attr. - let ignore_items = if trait_.module(sema.db).krate().origin(sema.db).is_local() { + let ignore_items = if trait_.module(sema.db).krate(sema.db).origin(sema.db).is_local() { IgnoreAssocItems::No } else { IgnoreAssocItems::DocHiddenAttrPresent diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs index e9f0e190d40f..009fc077ce6c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs @@ -58,7 +58,7 @@ pub(crate) fn replace_qualified_name_with_use( let path_to_qualifier = starts_with_name_ref .then(|| { let mod_ = ctx.sema.scope(original_path.syntax())?.module(); - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(mod_.krate())); + let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(mod_.krate(ctx.sema.db))); mod_.find_use_path(ctx.sema.db, module, ctx.config.insert_use.prefix_kind, cfg) }) .flatten(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs index d64a76eb8b37..849dfa49ddb0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs @@ -55,7 +55,7 @@ pub(crate) fn term_search(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< path.gen_source_code( &scope, &mut formatter, - ctx.config.find_path_config(ctx.sema.is_nightly(scope.module().krate())), + ctx.config.find_path_config(ctx.sema.is_nightly(scope.module().krate(ctx.sema.db))), scope.krate().to_display_target(ctx.db()), ) .ok() diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs index fa6fca8150ac..fa6ccb9a5f12 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs @@ -132,7 +132,7 @@ pub(crate) fn desugar_async_into_impl_future( let scope = ctx.sema.scope(function.syntax())?; let module = scope.module(); - let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate())); + let cfg = ctx.config.find_path_config(ctx.sema.is_nightly(module.krate(ctx.sema.db))); let future_trait = FamousDefs(&ctx.sema, scope.krate()).core_future_Future()?; let trait_path = module.find_path(ctx.db(), ModuleDef::Trait(future_trait), cfg)?; let edition = scope.krate().edition(ctx.db()); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index abae3cb36802..b28764f6fc5a 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs @@ -190,7 +190,7 @@ impl Completions { path_ctx: &PathCompletionCtx<'_>, ) { ctx.process_all_names(&mut |name, res, doc_aliases| match res { - ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root() => { + ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => { self.add_module(ctx, path_ctx, m, name, doc_aliases); } _ => (), diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs index 267d92b6c090..57ea609a40e0 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs @@ -56,7 +56,7 @@ pub(crate) fn complete_derive_path( _ => return, }; - match (core, mac.module(ctx.db).krate()) { + match (core, mac.module(ctx.db).krate(ctx.db)) { // show derive dependencies for `core`/`std` derives (Some(core), mac_krate) if core == mac_krate => {} _ => return acc.add_macro(ctx, path_ctx, mac, name), diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs index 0641a4f6c3fe..136315c61f58 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/macro_use.rs @@ -15,7 +15,7 @@ pub(super) fn complete_macro_use( let Some(extern_crate) = ctx.sema.to_def(extern_crate) else { return }; let Some(krate) = extern_crate.resolved_crate(ctx.db) else { return }; - for mod_def in krate.root_module().declarations(ctx.db) { + for mod_def in krate.root_module(ctx.db).declarations(ctx.db) { if let ModuleDef::Macro(mac) = mod_def { let mac_name = mac.name(ctx.db); let mac_name = mac_name.as_str(); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index 6dfa183136bd..31e33db104c7 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -286,7 +286,7 @@ pub fn resolve_completion_edits( let scope = ImportScope::find_insert_use_container(position_for_import, &sema)?; let current_module = sema.scope(position_for_import)?.module(); - let current_crate = current_module.krate(); + let current_crate = current_module.krate(db); let current_edition = current_crate.edition(db); let new_ast = scope.clone_for_update(); let mut import_insert = TextEdit::builder(); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs index cfd6340f1eea..ce35ab135f3c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs @@ -106,7 +106,7 @@ pub(crate) fn visible_fields( .collect::>(); let has_invisible_field = n_fields - fields.len() > 0; let is_foreign_non_exhaustive = - item.attrs(ctx.db).is_non_exhaustive() && item.krate(ctx.db) != module.krate(); + item.attrs(ctx.db).is_non_exhaustive() && item.krate(ctx.db) != module.krate(ctx.db); let fields_omitted = has_invisible_field || is_foreign_non_exhaustive; Some((fields, fields_omitted)) } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index 94530bf51d5f..cf86618de69e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -780,9 +780,9 @@ fn main() { } "#, expect![[r#" - me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED + me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED "#]], ); } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs index 9ce85b2bf330..788f9b73fa19 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs @@ -64,9 +64,9 @@ impl Definition { pub fn krate(&self, db: &RootDatabase) -> Option { Some(match self { - Definition::Module(m) => m.krate(), + Definition::Module(m) => m.krate(db), &Definition::Crate(it) => it, - _ => self.module(db)?.krate(), + _ => self.module(db)?.krate(db), }) } @@ -93,7 +93,7 @@ impl Definition { Definition::ExternCrateDecl(it) => it.module(db), Definition::DeriveHelper(it) => it.derive().module(db), Definition::InlineAsmOperand(it) => it.parent(db).module(db), - Definition::ToolModule(t) => t.krate().root_module(), + Definition::ToolModule(t) => t.krate().root_module(db), Definition::BuiltinAttr(_) | Definition::BuiltinType(_) | Definition::BuiltinLifetime(_) @@ -374,7 +374,7 @@ pub fn find_std_module( ) -> Option { let db = famous_defs.0.db; let std_crate = famous_defs.std()?; - let std_root_module = std_crate.root_module(); + let std_root_module = std_crate.root_module(famous_defs.0.db); std_root_module.children(db).find(|module| { module.name(db).is_some_and(|module| module.display(db, edition).to_string() == name) }) diff --git a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs index 8eea2b81bab6..f28ce53e91c0 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs @@ -232,7 +232,7 @@ impl FamousDefs<'_, '_> { lang_crate => lang_crate, }; let std_crate = self.find_lang_crate(lang_crate)?; - let mut module = std_crate.root_module(); + let mut module = std_crate.root_module(db); for segment in path { module = module.children(db).find_map(|child| { let name = child.name(db)?; diff --git a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs index 1e54058dd16c..08cf1eeed33b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs @@ -80,7 +80,7 @@ pub fn visit_file_defs( } module.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into())); - let is_root = module.is_crate_root(); + let is_root = module.is_crate_root(db); module .legacy_macros(db) .into_iter() diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index c49ade235043..90e3bb61f44d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -315,7 +315,7 @@ impl<'db> ImportAssets<'db> { allow_unstable: sema.is_nightly(scope.krate()), }; let db = sema.db; - let krate = self.module_with_candidate.krate(); + let krate = self.module_with_candidate.krate(sema.db); let scope_definitions = self.scope_definitions(sema); let mod_path = |item| { get_mod_path( diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index bc5958ec5854..48305c20823c 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -152,7 +152,7 @@ impl<'a> PathTransform<'a> { db, node, &db.expansion_span_map(file_id), - self.target_scope.module().krate().into(), + self.target_scope.module().krate(db).into(), ) } } @@ -174,7 +174,7 @@ impl<'a> PathTransform<'a> { let mut type_substs: FxHashMap = Default::default(); let mut const_substs: FxHashMap = Default::default(); let mut defaulted_params: Vec = Default::default(); - let target_edition = target_module.krate().edition(self.source_scope.db); + let target_edition = target_module.krate(db).edition(self.source_scope.db); self.generic_def .into_iter() .flat_map(|it| it.type_or_const_params(db)) @@ -219,7 +219,7 @@ impl<'a> PathTransform<'a> { } (Either::Left(k), None) => { if let Some(default) = - k.default(db, target_module.krate().to_display_target(db)) + k.default(db, target_module.krate(db).to_display_target(db)) && let Some(default) = default.expr() { const_substs.insert(k, default.syntax().clone_for_update()); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index a8800c142a22..82eee69f0d25 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -246,7 +246,7 @@ fn rename_mod( ) -> Result { let mut source_change = SourceChange::default(); - if module.is_crate_root() { + if module.is_crate_root(sema.db) { return Ok(source_change); } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index f52b34500792..a48438cfa86f 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -294,9 +294,9 @@ impl Definition { // def is crate root if let &Definition::Module(module) = self - && module.is_crate_root() + && module.is_crate_root(db) { - return SearchScope::reverse_dependencies(db, module.krate()); + return SearchScope::reverse_dependencies(db, module.krate(db)); } let module = match self.module(db) { @@ -367,22 +367,22 @@ impl Definition { return match macro_def.kind(db) { hir::MacroKind::Declarative => { if macro_def.attrs(db).is_macro_export() { - SearchScope::reverse_dependencies(db, module.krate()) + SearchScope::reverse_dependencies(db, module.krate(db)) } else { - SearchScope::krate(db, module.krate()) + SearchScope::krate(db, module.krate(db)) } } hir::MacroKind::AttrBuiltIn | hir::MacroKind::DeriveBuiltIn | hir::MacroKind::DeclarativeBuiltIn => SearchScope::crate_graph(db), hir::MacroKind::Derive | hir::MacroKind::Attr | hir::MacroKind::ProcMacro => { - SearchScope::reverse_dependencies(db, module.krate()) + SearchScope::reverse_dependencies(db, module.krate(db)) } }; } if let Definition::DeriveHelper(_) = self { - return SearchScope::reverse_dependencies(db, module.krate()); + return SearchScope::reverse_dependencies(db, module.krate(db)); } if let Some(vis) = self.visibility(db) { @@ -391,7 +391,7 @@ impl Definition { SearchScope::module_and_children(db, module.into()) } Visibility::PubCrate(krate) => SearchScope::krate(db, krate.into()), - Visibility::Public => SearchScope::reverse_dependencies(db, module.krate()), + Visibility::Public => SearchScope::reverse_dependencies(db, module.krate(db)), }; } @@ -907,13 +907,13 @@ impl<'a> FindUsages<'a> { } } // special case crate modules as these do not have a proper name - (_, Definition::Module(module)) if module.is_crate_root() => { + (_, Definition::Module(module)) if module.is_crate_root(self.sema.db) => { // FIXME: This assumes the crate name is always equal to its display name when it // really isn't // we should instead look at the dependency edge name and recursively search our way // up the ancestors module - .krate() + .krate(self.sema.db) .display_name(self.sema.db) .map(|crate_name| crate_name.crate_name().symbol().as_str().into()) } @@ -1002,7 +1002,7 @@ impl<'a> FindUsages<'a> { let scope = search_scope.intersection(&SearchScope::module_and_children(self.sema.db, module)); - let is_crate_root = module.is_crate_root().then(|| Finder::new("crate")); + let is_crate_root = module.is_crate_root(self.sema.db).then(|| Finder::new("crate")); let finder = &Finder::new("super"); for (text, file_id, search_range) in Self::scope_files(sema.db, &scope) { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index ef67fbf6fe00..c5ead45a20ae 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -241,7 +241,7 @@ impl SymbolIndex { SymbolIndex::new(SymbolCollector::new_module( db, module, - !module.krate().origin(db).is_local(), + !module.krate(db).origin(db).is_local(), )) }) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt index 427a51055948..c8a9231fa99e 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt @@ -1,12 +1,8 @@ [ ( Module { - id: ModuleId { - krate: Crate( - Id(2c00), - ), - block: None, - local_id: Idx::(0), + id: ModuleIdLt { + [salsa id]: Id(3800), }, }, [ @@ -16,7 +12,7 @@ Struct( Struct { id: StructId( - 3801, + 3c01, ), }, ), @@ -50,7 +46,7 @@ Struct( Struct { id: StructId( - 3800, + 3c00, ), }, ), @@ -84,7 +80,7 @@ Struct( Struct { id: StructId( - 3800, + 3c00, ), }, ), @@ -118,7 +114,7 @@ Struct( Struct { id: StructId( - 3800, + 3c00, ), }, ), @@ -152,7 +148,7 @@ Struct( Struct { id: StructId( - 3800, + 3c00, ), }, ), @@ -186,7 +182,7 @@ Struct( Struct { id: StructId( - 3801, + 3c01, ), }, ), @@ -220,7 +216,7 @@ Struct( Struct { id: StructId( - 3800, + 3c00, ), }, ), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt index cc130194cb05..cc879cf84fc6 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -1,12 +1,8 @@ [ ( Module { - id: ModuleId { - krate: Crate( - Id(2c00), - ), - block: None, - local_id: Idx::(0), + id: ModuleIdLt { + [salsa id]: Id(3800), }, }, [ @@ -15,7 +11,7 @@ def: Variant( Variant { id: EnumVariantId( - 7800, + 7c00, ), }, ), @@ -49,7 +45,7 @@ def: TypeAlias( TypeAlias { id: TypeAliasId( - 6c00, + 7000, ), }, ), @@ -81,7 +77,7 @@ def: Variant( Variant { id: EnumVariantId( - 7801, + 7c01, ), }, ), @@ -115,7 +111,7 @@ def: Const( Const { id: ConstId( - 6400, + 6800, ), }, ), @@ -147,7 +143,7 @@ def: Const( Const { id: ConstId( - 6402, + 6802, ), }, ), @@ -180,7 +176,7 @@ Enum( Enum { id: EnumId( - 5000, + 5400, ), }, ), @@ -214,7 +210,7 @@ Macro { id: Macro2Id( Macro2Id( - 4c00, + 5000, ), ), }, @@ -248,7 +244,7 @@ Macro { id: Macro2Id( Macro2Id( - 4c00, + 5000, ), ), }, @@ -281,7 +277,7 @@ def: Static( Static { id: StaticId( - 6800, + 6c00, ), }, ), @@ -314,7 +310,7 @@ Struct( Struct { id: StructId( - 4801, + 4c01, ), }, ), @@ -348,7 +344,7 @@ Struct( Struct { id: StructId( - 4800, + 4c00, ), }, ), @@ -356,7 +352,7 @@ loc: DeclarationLocation { hir_file_id: MacroFile( MacroCallId( - Id(4000), + Id(4400), ), ), ptr: SyntaxNodePtr { @@ -382,7 +378,7 @@ Struct( Struct { id: StructId( - 4805, + 4c05, ), }, ), @@ -418,7 +414,7 @@ Struct( Struct { id: StructId( - 4806, + 4c06, ), }, ), @@ -454,7 +450,7 @@ Struct( Struct { id: StructId( - 4807, + 4c07, ), }, ), @@ -488,7 +484,7 @@ Struct( Struct { id: StructId( - 4802, + 4c02, ), }, ), @@ -521,7 +517,7 @@ def: Trait( Trait { id: TraitId( - 5c00, + 6000, ), }, ), @@ -554,7 +550,7 @@ Macro { id: Macro2Id( Macro2Id( - 4c00, + 5000, ), ), }, @@ -588,7 +584,7 @@ Union( Union { id: UnionId( - 5400, + 5800, ), }, ), @@ -620,12 +616,8 @@ name: "a_mod", def: Module( Module { - id: ModuleId { - krate: Crate( - Id(2c00), - ), - block: None, - local_id: Idx::(1), + id: ModuleIdLt { + [salsa id]: Id(3801), }, }, ), @@ -656,12 +648,8 @@ name: "b_mod", def: Module( Module { - id: ModuleId { - krate: Crate( - Id(2c00), - ), - block: None, - local_id: Idx::(2), + id: ModuleIdLt { + [salsa id]: Id(3802), }, }, ), @@ -694,7 +682,7 @@ Macro { id: MacroRulesId( MacroRulesId( - 3c01, + 4001, ), ), }, @@ -727,7 +715,7 @@ def: Function( Function { id: FunctionId( - 6002, + 6402, ), }, ), @@ -761,7 +749,7 @@ def: Function( Function { id: FunctionId( - 6001, + 6401, ), }, ), @@ -796,7 +784,7 @@ Macro { id: MacroRulesId( MacroRulesId( - 3c00, + 4000, ), ), }, @@ -829,7 +817,7 @@ def: Function( Function { id: FunctionId( - 6000, + 6400, ), }, ), @@ -862,7 +850,7 @@ Macro { id: MacroRulesId( MacroRulesId( - 3c01, + 4001, ), ), }, @@ -895,7 +883,7 @@ def: Function( Function { id: FunctionId( - 6003, + 6403, ), }, ), @@ -928,12 +916,8 @@ ), ( Module { - id: ModuleId { - krate: Crate( - Id(2c00), - ), - block: None, - local_id: Idx::(1), + id: ModuleIdLt { + [salsa id]: Id(3801), }, }, [ @@ -943,7 +927,7 @@ Struct( Struct { id: StructId( - 4803, + 4c03, ), }, ), @@ -975,12 +959,8 @@ ), ( Module { - id: ModuleId { - krate: Crate( - Id(2c00), - ), - block: None, - local_id: Idx::(2), + id: ModuleIdLt { + [salsa id]: Id(3802), }, }, [ @@ -989,7 +969,7 @@ def: Trait( Trait { id: TraitId( - 5c00, + 6000, ), }, ), @@ -1022,7 +1002,7 @@ Macro { id: Macro2Id( Macro2Id( - 4c00, + 5000, ), ), }, @@ -1056,7 +1036,7 @@ Struct( Struct { id: StructId( - 4804, + 4c04, ), }, ), @@ -1090,7 +1070,7 @@ Macro { id: Macro2Id( Macro2Id( - 4c00, + 5000, ), ), }, @@ -1124,7 +1104,7 @@ Struct( Struct { id: StructId( - 4804, + 4c04, ), }, ), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt index 3ab837aa613f..dc512fe1b87a 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt @@ -5,7 +5,7 @@ Struct( Struct { id: StructId( - 3800, + 3c00, ), }, ), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt index a6a808d616a7..0b2522775d4d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt @@ -5,7 +5,7 @@ Struct( Struct { id: StructId( - 3800, + 3c00, ), }, ), @@ -39,7 +39,7 @@ Struct( Struct { id: StructId( - 3800, + 3c00, ), }, ), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/traits.rs b/src/tools/rust-analyzer/crates/ide-db/src/traits.rs index 7b9fdb1e1cf3..7200e7fbe5ae 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/traits.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/traits.rs @@ -34,7 +34,7 @@ pub fn get_missing_assoc_items( // may share the same name as a function or constant. let mut impl_fns_consts = FxHashSet::default(); let mut impl_type = FxHashSet::default(); - let edition = imp.module(sema.db).krate().edition(sema.db); + let edition = imp.module(sema.db).krate(sema.db).edition(sema.db); for item in imp.items(sema.db) { match item { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index ab7256d63c40..2a251382d465 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -221,8 +221,8 @@ fn get_default_constructor( let krate = ctx .sema .file_to_module_def(d.file.original_file(ctx.sema.db).file_id(ctx.sema.db))? - .krate(); - let module = krate.root_module(); + .krate(ctx.sema.db); + let module = krate.root_module(ctx.sema.db); // Look for a ::new() associated function let has_new_func = ty diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/private_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/private_field.rs index 23f046007592..90c27bdcef79 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/private_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/private_field.rs @@ -37,7 +37,7 @@ pub(crate) fn field_is_private_fixes( fix_range: TextRange, ) -> Option> { let def_crate = private_field.krate(sema.db); - let usage_crate = sema.file_to_module_def(usage_file_id.file_id(sema.db))?.krate(); + let usage_crate = sema.file_to_module_def(usage_file_id.file_id(sema.db))?.krate(sema.db); let mut visibility_text = if usage_crate == def_crate { "pub(crate) " } else { "pub " }; let source = private_field.source(sema.db)?; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs index fc2648efb407..cb3aac3717f8 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs @@ -83,7 +83,7 @@ fn quickfix_for_redundant_assoc_item( let root = db.parse_or_expand(d.file_id); // don't modify trait def in outer crate let current_crate = ctx.sema.scope(&d.impl_.syntax_node_ptr().to_node(&root))?.krate(); - let trait_def_crate = d.trait_.module(db).krate(); + let trait_def_crate = d.trait_.module(db).krate(db); if trait_def_crate != current_crate { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs index 3a6e480f55ed..1283a11700e1 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs @@ -3,7 +3,7 @@ use std::iter; use hir::crate_def_map; -use hir::{DefMap, InFile, ModuleSource}; +use hir::{InFile, ModuleSource}; use ide_db::base_db::RootQueryDb; use ide_db::text_edit::TextEdit; use ide_db::{ @@ -106,7 +106,7 @@ fn fixes( // FIXME: This shouldnt need to access the crate def map directly let crate_def_map = crate_def_map(ctx.sema.db, krate); - let root_module = &crate_def_map[DefMap::ROOT]; + let root_module = &crate_def_map[crate_def_map.root_module_id()]; let Some(root_file_id) = root_module.origin.file_id() else { continue }; let Some(crate_root_path) = source_root.path_for_file(&root_file_id.file_id(ctx.sema.db)) else { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs index 358e0c43c2a9..59ec259adf36 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -83,7 +83,7 @@ fn field_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField<'_>) -> Opti make::ty("()") }; - if !is_editable_crate(target_module.krate(), ctx.sema.db) + if !is_editable_crate(target_module.krate(ctx.sema.db), ctx.sema.db) || SyntaxKind::from_keyword(field_name, ctx.edition).is_some() { return None; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index c7827f13f409..fe04bd175c96 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -342,12 +342,12 @@ pub fn semantic_diagnostics( let module = sema.file_to_module_def(file_id); let is_nightly = matches!( - module.and_then(|m| db.toolchain_channel(m.krate().into())), + module.and_then(|m| db.toolchain_channel(m.krate(db).into())), Some(ReleaseChannel::Nightly) | None ); let krate = match module { - Some(module) => module.krate(), + Some(module) => module.krate(db), None => { match db.all_crates().last() { Some(last) => (*last).into(), diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 9d38a860a08d..d43f13b79dfc 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -28,7 +28,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< let sema = Semantics::new(db); let file_id = sema.attach_first_edition(position.file_id); let file = sema.parse(file_id); - let krate = sema.file_to_module_def(file_id.file_id(db))?.krate().into(); + let krate = sema.file_to_module_def(file_id.file_id(db))?.krate(db).into(); let tok = pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind { SyntaxKind::IDENT => 1, diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs index e1db370d4462..b00aa4d0ca67 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs @@ -139,7 +139,7 @@ pub(crate) fn goto_definition( if let Definition::ExternCrateDecl(crate_def) = def { return crate_def .resolved_crate(db) - .map(|it| it.root_module().to_nav(sema.db)) + .map(|it| it.root_module(db).to_nav(db)) .into_iter() .flatten() .collect(); @@ -262,7 +262,7 @@ fn try_lookup_macro_def_in_macro_use( let extern_crate = sema.to_def(&extern_crate)?; let krate = extern_crate.resolved_crate(sema.db)?; - for mod_def in krate.root_module().declarations(sema.db) { + for mod_def in krate.root_module(sema.db).declarations(sema.db) { if let ModuleDef::Macro(mac) = mod_def && mac.name(sema.db).as_str() == token.text() && let Some(nav) = mac.try_to_nav(sema) diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs index a29da4f25803..4bf9b82cc877 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs @@ -384,7 +384,7 @@ trait Bar {} fn test() { #[derive(Copy)] - // ^^^^^^^^^^^^ + // ^^^^ struct Foo$0; impl Foo {} diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index a8929859bc87..9dc72a87af16 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -464,7 +464,7 @@ pub(super) fn path( item_name: Option, edition: Edition, ) -> String { - let crate_name = module.krate().display_name(db).as_ref().map(|it| it.to_string()); + let crate_name = module.krate(db).display_name(db).as_ref().map(|it| it.to_string()); let module_path = module .path_to_root(db) .into_iter() diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index 260da900f402..03674978d53d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -811,7 +811,7 @@ fn hint_iterator<'db>( ) -> Option<(hir::Trait, hir::TypeAlias, hir::Type<'db>)> { let db = sema.db; let strukt = ty.strip_references().as_adt()?; - let krate = strukt.module(db).krate(); + let krate = strukt.module(db).krate(db); if krate != famous_defs.core()? { return None; } diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs index 05cd145033bf..791da00bb695 100644 --- a/src/tools/rust-analyzer/crates/ide/src/interpret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs @@ -45,7 +45,7 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura None => format!("file://{path} range {text_range:?}"), } }; - let display_target = def.module(db).krate().to_display_target(db); + let display_target = def.module(db).krate(db).to_display_target(db); let start_time = Instant::now(); let res = match def { DefWithBody::Function(it) => it.eval(db, span_formatter), diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs index 4aa9eb98a1e1..1c1389ca7a15 100644 --- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs +++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs @@ -284,10 +284,10 @@ fn def_to_non_local_moniker( from_crate: Crate, ) -> Option { let module = match definition { - Definition::Module(module) if module.is_crate_root() => module, + Definition::Module(module) if module.is_crate_root(db) => module, _ => definition.module(db)?, }; - let krate = module.krate(); + let krate = module.krate(db); let edition = krate.edition(db); // Add descriptors for this definition and every enclosing definition. @@ -321,7 +321,7 @@ fn def_to_non_local_moniker( }); } else { match def { - Definition::Module(module) if module.is_crate_root() => { + Definition::Module(module) if module.is_crate_root(db) => { // only include `crate` namespace by itself because we prefer // `rust-analyzer cargo foo . bar/` over `rust-analyzer cargo foo . crate/bar/` if reverse_description.is_empty() { @@ -389,7 +389,8 @@ fn display<'db, T: HirDisplay<'db>>(db: &'db RootDatabase, module: hir::Module, Ok(result) => result, // Fallback on display variant that always succeeds Err(_) => { - let fallback_result = it.display(db, module.krate().to_display_target(db)).to_string(); + let fallback_result = + it.display(db, module.krate(db).to_display_target(db)).to_string(); tracing::error!( display = %fallback_result, "`display_source_code` failed; falling back to using display" ); diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index 4c4d57f0f40c..67472507f66e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -160,7 +160,7 @@ impl NavigationTarget { ); res.docs = module.docs(db).map(Documentation::into_owned); res.description = Some( - module.display(db, module.krate().to_display_target(db)).to_string(), + module.display(db, module.krate(db).to_display_target(db)).to_string(), ); res }, @@ -468,7 +468,7 @@ impl ToNav for hir::Module { impl ToNav for hir::Crate { fn to_nav(&self, db: &RootDatabase) -> UpmappingResult { - self.root_module().to_nav(db) + self.root_module(db).to_nav(db) } } @@ -511,7 +511,7 @@ impl TryToNav for hir::ExternCrateDecl { let focus = value .rename() .map_or_else(|| value.name_ref().map(Either::Left), |it| it.name().map(Either::Right)); - let krate = self.module(db).krate(); + let krate = self.module(db).krate(db); Some(orig_range_with_focus(db, file_id, value.syntax(), focus).map( |(FileRange { file_id, range: full_range }, focus_range)| { @@ -539,7 +539,7 @@ impl TryToNav for hir::Field { ) -> Option> { let db = sema.db; let src = self.source(db)?; - let krate = self.parent_def(db).module(db).krate(); + let krate = self.parent_def(db).module(db).krate(db); let field_source = match &src.value { FieldSource::Named(it) => { diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index 9e17ab2bab75..a61be93ea968 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -372,7 +372,7 @@ pub(crate) fn runnable_mod( .rev() .filter_map(|module| { module.name(sema.db).map(|mod_name| { - mod_name.display(sema.db, module.krate().edition(sema.db)).to_string() + mod_name.display(sema.db, module.krate(sema.db).edition(sema.db)).to_string() }) }) .join("::"); @@ -401,7 +401,7 @@ pub(crate) fn runnable_impl( sema: &Semantics<'_, RootDatabase>, def: &hir::Impl, ) -> Option { - let display_target = def.module(sema.db).krate().to_display_target(sema.db); + let display_target = def.module(sema.db).krate(sema.db).to_display_target(sema.db); let edition = display_target.edition; let attrs = def.attrs(sema.db); if !has_runnable_doc_test(sema.db, &attrs) { @@ -466,7 +466,7 @@ fn runnable_mod_outline_definition( .rev() .filter_map(|module| { module.name(sema.db).map(|mod_name| { - mod_name.display(sema.db, module.krate().edition(sema.db)).to_string() + mod_name.display(sema.db, module.krate(sema.db).edition(sema.db)).to_string() }) }) .join("::"); diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index f3cda9156bbb..30e8d62ea210 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -102,7 +102,7 @@ pub struct StaticIndexedFile { fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = - Crate::all(db).into_iter().map(|krate| krate.root_module()).collect(); + Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect(); let mut modules = Vec::new(); while let Some(module) = worklist.pop() { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index 8937f8249c84..044fd3f5ac9a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs @@ -501,7 +501,7 @@ pub(super) fn highlight_def( ), Definition::Module(module) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module)); - if module.is_crate_root() { + if module.is_crate_root(db) { h |= HlMod::CrateRoot; } @@ -747,7 +747,7 @@ fn highlight_method_call( h |= HlMod::Trait; } - let def_crate = func.module(sema.db).krate(); + let def_crate = func.module(sema.db).krate(sema.db); let is_from_other_crate = krate.as_ref().map_or(false, |krate| def_crate != *krate); let is_from_builtin_crate = def_crate.is_builtin(sema.db); let is_public = func.visibility(sema.db) == hir::Visibility::Public; diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html index e3daeef84109..982e89dfab69 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html @@ -54,7 +54,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd foo!(Bar); fn func(_: y::Bar) { mod inner { - struct Innerest<const C: usize> { field: [(); {C}] } + struct Innerest<const C: usize> { field: [u32; {C}], field2: &Innerest } } } } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index b7510e3abaea..89a5e434f90c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -1183,7 +1183,7 @@ fn main() { foo!(Bar); fn func(_: y::Bar) { mod inner { - struct Innerest { field: [(); {C}] } + struct Innerest { field: [u32; {C}], field2: &Innerest } } } } diff --git a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs index bd60ffe55912..4792566f5f5b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs +++ b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs @@ -135,11 +135,11 @@ fn find_module_id_and_test_parents( module: Module, ) -> Option<(Vec, String)> { let Some(parent) = module.parent(sema.db) else { - let name = module.krate().display_name(sema.db)?.to_string(); + let name = module.krate(sema.db).display_name(sema.db)?.to_string(); return Some(( vec![TestItem { id: name.clone(), - kind: TestItemKind::Crate(module.krate().into()), + kind: TestItemKind::Crate(module.krate(sema.db).into()), label: name.clone(), parent: None, file: None, @@ -181,7 +181,7 @@ pub(crate) fn discover_tests_in_crate( let kind = TestItemKind::Crate(crate_id); let crate_test_id = crate_test_id.to_string(); let crate_id: Crate = crate_id.into(); - let module = crate_id.root_module(); + let module = crate_id.root_module(db); let mut r = vec![TestItem { id: crate_test_id.clone(), kind, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index bd3f05977ef0..f39ab1301f8f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -206,7 +206,7 @@ impl flags::AnalysisStats { let mut visited_modules = FxHashSet::default(); let mut visit_queue = Vec::new(); for &krate in &krates { - let module = krate.root_module(); + let module = krate.root_module(db); let file_id = module.definition_source_file_id(db); let file_id = file_id.original_file(db); @@ -769,7 +769,7 @@ impl flags::AnalysisStats { for &body_id in bodies { let name = body_id.name(db).unwrap_or_else(Name::missing); let module = body_id.module(db); - let display_target = module.krate().to_display_target(db); + let display_target = module.krate(db).to_display_target(db); if let Some(only_name) = self.only.as_deref() && name.display(db, Edition::LATEST).to_string() != only_name && full_name(db, body_id, module) != only_name @@ -1290,7 +1290,7 @@ impl flags::AnalysisStats { fn full_name(db: &RootDatabase, body_id: DefWithBody, module: hir::Module) -> String { module - .krate() + .krate(db) .display_name(db) .map(|it| it.canonical_name().as_str().to_owned()) .into_iter() diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs index 82590c8e707f..776069f155f0 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs @@ -68,8 +68,12 @@ impl flags::Diagnostics { if !visited_files.contains(&file_id) { let message = format!("processing {}", _vfs.file_path(file_id.file_id(db))); bar.set_message(move || message.clone()); - let crate_name = - module.krate().display_name(db).as_deref().unwrap_or(&sym::unknown).to_owned(); + let crate_name = module + .krate(db) + .display_name(db) + .as_deref() + .unwrap_or(&sym::unknown) + .to_owned(); for diagnostic in analysis .full_diagnostics( &DiagnosticsConfig::test_sample(), @@ -122,7 +126,7 @@ impl flags::Diagnostics { fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = - Crate::all(db).into_iter().map(|krate| krate.root_module()).collect(); + Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect(); let mut modules = Vec::new(); while let Some(module) = worklist.pop() { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs index 60b33f0a3086..82ace8c8b315 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs @@ -78,7 +78,7 @@ fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = Crate::all(db) .into_iter() .filter(|x| x.origin(db).is_local()) - .map(|krate| krate.root_module()) + .map(|krate| krate.root_module(db)) .collect(); let mut modules = Vec::new(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs index a400f86778f4..294add682d01 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs @@ -64,8 +64,12 @@ impl flags::UnresolvedReferences { let file_id = module.definition_source_file_id(db).original_file(db); let file_id = file_id.file_id(db); if !visited_files.contains(&file_id) { - let crate_name = - module.krate().display_name(db).as_deref().unwrap_or(&sym::unknown).to_owned(); + let crate_name = module + .krate(db) + .display_name(db) + .as_deref() + .unwrap_or(&sym::unknown) + .to_owned(); let file_path = vfs.file_path(file_id); eprintln!("processing crate: {crate_name}, module: {file_path}",); @@ -93,7 +97,7 @@ impl flags::UnresolvedReferences { fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = - Crate::all(db).into_iter().map(|krate| krate.root_module()).collect(); + Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect(); let mut modules = Vec::new(); while let Some(module) = worklist.pop() { From a1a9514f6fa4416312f41fc005fc6ae3c615c64d Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 30 Nov 2025 13:56:00 +0100 Subject: [PATCH 0381/3801] Turn `BlockLoc` into a tracked struct --- .../rust-analyzer/crates/hir-def/src/db.rs | 15 ++--- .../crates/hir-def/src/expr_store/lower.rs | 4 +- .../src/expr_store/tests/body/block.rs | 52 ++++++++++++++- .../crates/hir-def/src/find_path.rs | 66 +++++++++---------- .../crates/hir-def/src/import_map.rs | 6 +- .../crates/hir-def/src/item_tree.rs | 8 +-- .../rust-analyzer/crates/hir-def/src/lib.rs | 61 +++++++++++------ .../crates/hir-def/src/nameres.rs | 32 +++++---- .../crates/hir-def/src/resolver.rs | 4 +- .../crates/hir-def/src/visibility.rs | 30 +++++---- .../rust-analyzer/crates/hir-ty/src/infer.rs | 23 +++---- .../crates/hir-ty/src/method_resolution.rs | 49 +++++++------- src/tools/rust-analyzer/crates/hir/src/lib.rs | 8 +-- .../hir/src/semantics/child_by_source.rs | 2 +- 14 files changed, 214 insertions(+), 146 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index ccd4bc9be84a..98df8d0ff445 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -8,12 +8,12 @@ use la_arena::ArenaMap; use triomphe::Arc; use crate::{ - AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, - EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, - FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, - MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, - ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, - TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, + AssocItemId, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, EnumVariantId, + EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, + FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroExpander, + MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, + StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, + UnionLoc, UseId, UseLoc, VariantId, attrs::AttrFlags, expr_store::{ Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes, @@ -82,9 +82,6 @@ pub trait InternDatabase: RootQueryDb { #[salsa::interned] fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId; // endregion: items - - #[salsa::interned] - fn intern_block(&self, loc: BlockLoc) -> BlockId; } #[query_group::query_group] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index df4cff0b8a17..f374dd2cc9ef 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -31,7 +31,7 @@ use triomphe::Arc; use tt::TextRange; use crate::{ - AdtId, BlockId, BlockLoc, DefWithBodyId, FunctionId, GenericDefId, ImplId, MacroId, + AdtId, BlockId, BlockIdLt, DefWithBodyId, FunctionId, GenericDefId, ImplId, MacroId, ModuleDefId, ModuleId, TraitId, TypeAliasId, UnresolvedMacro, attrs::AttrFlags, builtin_type::BuiltinUint, @@ -2114,7 +2114,7 @@ impl<'db> ExprCollector<'db> { ) -> ExprId { let block_id = self.expander.ast_id_map().ast_id_for_block(&block).map(|file_local_id| { let ast_id = self.expander.in_file(file_local_id); - self.db.intern_block(BlockLoc { ast_id, module: self.module }) + unsafe { BlockIdLt::new(self.db, ast_id, self.module).to_static() } }); let (module, def_map) = diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs index 836a079e777f..2d60f44092c5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs @@ -195,9 +195,55 @@ fn f() { Id(1c00), ), block: Some( - BlockId( - 3c01, - ), + BlockIdLt { + [salsa id]: Id(3c01), + ast_id: InFileWrapper { + file_id: FileId( + EditionedFileIdData { + editioned_file_id: EditionedFileId( + 0, + Edition2024, + ), + krate: Crate( + Id(1c00), + ), + }, + ), + value: FileAstId::(ErasedFileAstId { kind: BlockExpr, index: 0, hash: F9BF }), + }, + module: ModuleIdLt { + [salsa id]: Id(3002), + krate: Crate( + Id(1c00), + ), + block: Some( + BlockIdLt { + [salsa id]: Id(3c00), + ast_id: InFileWrapper { + file_id: FileId( + EditionedFileIdData { + editioned_file_id: EditionedFileId( + 0, + Edition2024, + ), + krate: Crate( + Id(1c00), + ), + }, + ), + value: FileAstId::(ErasedFileAstId { kind: BlockExpr, index: 0, hash: C181 }), + }, + module: ModuleIdLt { + [salsa id]: Id(3000), + krate: Crate( + Id(1c00), + ), + block: None, + }, + }, + ), + }, + }, ), }"#]], ); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index 5d1cac8e93c4..cc0594f00d61 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -12,7 +12,7 @@ use intern::sym; use rustc_hash::FxHashSet; use crate::{ - FindPathConfig, ModuleDefId, ModuleId, + FindPathConfig, ModuleDefId, ModuleIdLt, db::DefDatabase, item_scope::ItemInNs, nameres::DefMap, @@ -24,7 +24,7 @@ use crate::{ pub fn find_path( db: &dyn DefDatabase, item: ItemInNs, - from: ModuleId, + from: ModuleIdLt<'_>, mut prefix_kind: PrefixKind, ignore_local_imports: bool, mut cfg: FindPathConfig, @@ -102,14 +102,14 @@ struct FindPathCtx<'db> { cfg: FindPathConfig, ignore_local_imports: bool, is_std_item: bool, - from: ModuleId, + from: ModuleIdLt<'db>, from_crate: Crate, - crate_root: ModuleId, + crate_root: ModuleIdLt<'db>, from_def_map: &'db DefMap, fuel: Cell, } -/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId +/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleIdLt<'_> fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Option { // - if the item is a module, jump straight to module search if !ctx.is_std_item @@ -157,10 +157,10 @@ fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Opt } #[tracing::instrument(skip_all)] -fn find_path_for_module( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, - module_id: ModuleId, +fn find_path_for_module<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, + module_id: ModuleIdLt<'db>, maybe_extern: bool, max_len: usize, ) -> Option { @@ -217,7 +217,7 @@ fn find_path_for_module( ctx.db, ctx.from_def_map, ctx.from, - ItemInNs::Types(module_id.into()), + ItemInNs::Types(unsafe { module_id.to_static() }.into()), ctx.ignore_local_imports, ); if let Some(scope_name) = scope_name { @@ -244,7 +244,7 @@ fn find_path_for_module( } // - if the module is in the prelude, return it by that path - let item = ItemInNs::Types(module_id.into()); + let item = ItemInNs::Types(unsafe { module_id.to_static() }.into()); if let Some(choice) = find_in_prelude(ctx.db, ctx.from_def_map, item, ctx.from) { return Some(choice); } @@ -257,10 +257,10 @@ fn find_path_for_module( best_choice } -fn find_in_scope( - db: &dyn DefDatabase, +fn find_in_scope<'db>( + db: &'db dyn DefDatabase, def_map: &DefMap, - from: ModuleId, + from: ModuleIdLt<'db>, item: ItemInNs, ignore_local_imports: bool, ) -> Option { @@ -278,7 +278,7 @@ fn find_in_prelude( db: &dyn DefDatabase, local_def_map: &DefMap, item: ItemInNs, - from: ModuleId, + from: ModuleIdLt<'_>, ) -> Option { let (prelude_module, _) = local_def_map.prelude()?; let prelude_def_map = prelude_module.def_map(db); @@ -310,8 +310,8 @@ fn find_in_prelude( fn is_kw_kind_relative_to_from( db: &dyn DefDatabase, def_map: &DefMap, - item: ModuleId, - from: ModuleId, + item: ModuleIdLt<'_>, + from: ModuleIdLt<'_>, ) -> Option { if item.krate(db) != from.krate(db) || item.block(db).is_some() || from.block(db).is_some() { return None; @@ -332,9 +332,9 @@ fn is_kw_kind_relative_to_from( } #[tracing::instrument(skip_all)] -fn calculate_best_path( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, +fn calculate_best_path<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -372,9 +372,9 @@ fn calculate_best_path( } } -fn find_in_sysroot( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, +fn find_in_sysroot<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -418,9 +418,9 @@ fn find_in_sysroot( }); } -fn find_in_dep( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, +fn find_in_dep<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -461,9 +461,9 @@ fn find_in_dep( } } -fn calculate_best_path_local( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, +fn calculate_best_path_local<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -558,11 +558,11 @@ fn path_kind_len(kind: PathKind) -> usize { } /// Finds locations in `from.krate` from which `item` can be imported by `from`. -fn find_local_import_locations( - ctx: &FindPathCtx<'_>, +fn find_local_import_locations<'db>( + ctx: &'db FindPathCtx<'db>, item: ItemInNs, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, - mut cb: impl FnMut(&mut FxHashSet<(ItemInNs, ModuleId)>, &Name, ModuleId), + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, + mut cb: impl FnMut(&mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, &Name, ModuleIdLt<'db>), ) { let _p = tracing::info_span!("find_local_import_locations").entered(); let db = ctx.db; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 6c5d226cac1b..433aead77adb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -496,7 +496,7 @@ mod tests { use expect_test::{Expect, expect}; use test_fixture::WithFixture; - use crate::{ItemContainerId, Lookup, nameres::assoc::TraitItems, test_db::TestDB}; + use crate::{ItemContainerId, Lookup, ModuleIdLt, nameres::assoc::TraitItems, test_db::TestDB}; use super::*; @@ -628,8 +628,8 @@ mod tests { expect.assert_eq(&actual) } - fn render_path(db: &dyn DefDatabase, info: &ImportInfo) -> String { - let mut module = info.container; + fn render_path<'db>(db: &'db dyn DefDatabase, info: &ImportInfo) -> String { + let mut module: ModuleIdLt<'db> = info.container; let mut segments = vec![&info.name]; let def_map = module.def_map(db); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 2a104fff2b92..1228d1999bcb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -58,7 +58,7 @@ use syntax::{SyntaxKind, ast, match_ast}; use thin_vec::ThinVec; use triomphe::Arc; -use crate::{BlockId, Lookup, db::DefDatabase}; +use crate::{BlockId, db::DefDatabase}; pub(crate) use crate::item_tree::{ attrs::*, @@ -150,10 +150,10 @@ pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc let _p = tracing::info_span!("block_item_tree_query", ?block).entered(); static EMPTY: OnceLock> = OnceLock::new(); - let loc = block.lookup(db); - let block = loc.ast_id.to_node(db); + let ast_id = block.ast_id(db); + let block = ast_id.to_node(db); - let ctx = lower::Ctx::new(db, loc.ast_id.file_id); + let ctx = lower::Ctx::new(db, ast_id.file_id); let mut item_tree = ctx.lower_block(&block); let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = &item_tree; if small_data.is_empty() diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 97af8ad93def..e58cb7bad705 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -420,13 +420,31 @@ pub struct ProcMacroLoc { impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro); impl_loc!(ProcMacroLoc, id: Fn, container: ModuleId); -#[derive(Debug, Hash, PartialEq, Eq, Clone)] -pub struct BlockLoc { +#[salsa_macros::tracked(debug)] +#[derive(PartialOrd, Ord)] +pub struct BlockIdLt<'db> { pub ast_id: AstId, /// The containing module. - pub module: ModuleId, + pub module: ModuleIdLt<'db>, +} +pub type BlockId = BlockIdLt<'static>; + +impl BlockIdLt<'_> { + /// # Safety + /// + /// The caller must ensure that the `ModuleId` is not leaked outside of query computations. + pub unsafe fn to_static(self) -> BlockId { + unsafe { std::mem::transmute(self) } + } +} +impl BlockId { + /// # Safety + /// + /// The caller must ensure that the `BlockId` comes from the given database. + pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> BlockIdLt<'db> { + unsafe { std::mem::transmute(self) } + } } -impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block); #[salsa_macros::tracked(debug)] #[derive(PartialOrd, Ord)] @@ -436,34 +454,26 @@ pub struct ModuleIdLt<'db> { /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the /// `BlockId` of that block expression. If `None`, this module is part of the crate-level /// `DefMap` of `krate`. - pub block: Option, + pub block: Option>, } pub type ModuleId = ModuleIdLt<'static>; -impl ModuleIdLt<'_> { +impl<'db> ModuleIdLt<'db> { /// # Safety /// /// The caller must ensure that the `ModuleId` is not leaked outside of query computations. pub unsafe fn to_static(self) -> ModuleId { unsafe { std::mem::transmute(self) } } -} -impl ModuleId { - /// # Safety - /// - /// The caller must ensure that the `ModuleId` comes from the given database. - pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> { - unsafe { std::mem::transmute(self) } - } - pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap { + pub fn def_map(self, db: &'db dyn DefDatabase) -> &'db DefMap { match self.block(db) { Some(block) => block_def_map(db, block), None => crate_def_map(db, self.krate(db)), } } - pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) { + pub(crate) fn local_def_map(self, db: &'db dyn DefDatabase) -> (&'db DefMap, &'db LocalDefMap) { match self.block(db) { Some(block) => (block_def_map(db, block), self.only_local_def_map(db)), None => { @@ -473,15 +483,15 @@ impl ModuleId { } } - pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> &LocalDefMap { + pub(crate) fn only_local_def_map(self, db: &'db dyn DefDatabase) -> &'db LocalDefMap { crate_local_def_map(db, self.krate(db)).local(db) } - pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap { + pub fn crate_def_map(self, db: &'db dyn DefDatabase) -> &'db DefMap { crate_def_map(db, self.krate(db)) } - pub fn name(self, db: &dyn DefDatabase) -> Option { + pub fn name(self, db: &'db dyn DefDatabase) -> Option { let def_map = self.def_map(db); let parent = def_map[self].parent?; def_map[parent].children.iter().find_map(|(name, module_id)| { @@ -491,15 +501,24 @@ impl ModuleId { /// Returns the module containing `self`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. - pub fn containing_module(self, db: &dyn DefDatabase) -> Option { + pub fn containing_module(self, db: &'db dyn DefDatabase) -> Option> { self.def_map(db).containing_module(self) } - pub fn is_block_module(self, db: &dyn DefDatabase) -> bool { + pub fn is_block_module(self, db: &'db dyn DefDatabase) -> bool { self.block(db).is_some() && self.def_map(db).root_module_id() == self } } +impl ModuleId { + /// # Safety + /// + /// The caller must ensure that the `ModuleId` comes from the given database. + pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> { + unsafe { std::mem::transmute(self) } + } +} + impl HasModule for ModuleId { #[inline] fn module(&self, _db: &dyn DefDatabase) -> ModuleId { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 3f29619bcb62..a85237662c43 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -75,7 +75,7 @@ use triomphe::Arc; use tt::TextRange; use crate::{ - AstId, BlockId, BlockLoc, ExternCrateId, FunctionId, FxIndexMap, Lookup, MacroCallStyles, + AstId, BlockId, BlockIdLt, ExternCrateId, FunctionId, FxIndexMap, Lookup, MacroCallStyles, MacroExpander, MacroId, ModuleId, ModuleIdLt, ProcMacroId, UseId, db::DefDatabase, item_scope::{BuiltinShadowMode, ItemScope}, @@ -247,12 +247,12 @@ struct BlockInfo { parent: ModuleId, } -impl std::ops::Index for DefMap { +impl std::ops::Index> for DefMap { type Output = ModuleData; - fn index(&self, id: ModuleId) -> &ModuleData { + fn index(&self, id: ModuleIdLt<'_>) -> &ModuleData { self.modules - .get(&id) + .get(&unsafe { id.to_static() }) .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap {:#?}: {id:#?}", self.root)) } } @@ -400,8 +400,10 @@ pub(crate) fn crate_local_def_map(db: &dyn DefDatabase, crate_id: Crate) -> DefM } #[salsa_macros::tracked(returns(ref))] -pub fn block_def_map(db: &dyn DefDatabase, block_id: BlockId) -> DefMap { - let BlockLoc { ast_id, module } = block_id.lookup(db); +pub fn block_def_map<'db>(db: &'db dyn DefDatabase, block_id: BlockIdLt<'db>) -> DefMap { + let block_id = unsafe { block_id.to_static() }; + let ast_id = block_id.ast_id(db); + let module = unsafe { block_id.module(db).to_static() }; let visibility = Visibility::Module(module, VisibilityExplicitness::Implicit); let module_data = @@ -557,7 +559,7 @@ impl DefMap { /// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. - pub fn containing_module(&self, local_mod: ModuleId) -> Option { + pub fn containing_module(&self, local_mod: ModuleIdLt<'_>) -> Option { match self[local_mod].parent { Some(parent) => Some(parent), None => self.block.map(|BlockInfo { parent, .. }| parent), @@ -662,11 +664,11 @@ impl DefMap { /// /// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns /// `None`, iteration continues. - pub(crate) fn with_ancestor_maps( + pub(crate) fn with_ancestor_maps<'db, T>( &self, - db: &dyn DefDatabase, - local_mod: ModuleId, - f: &mut dyn FnMut(&DefMap, ModuleId) -> Option, + db: &'db dyn DefDatabase, + local_mod: ModuleIdLt<'db>, + f: &mut dyn FnMut(&DefMap, ModuleIdLt<'db>) -> Option, ) -> Option { if let Some(it) = f(self, local_mod) { return Some(it); @@ -852,11 +854,13 @@ impl DerefMut for ModulesMap { } } -impl Index for ModulesMap { +impl Index> for ModulesMap { type Output = ModuleData; - fn index(&self, id: ModuleId) -> &ModuleData { - self.inner.get(&id).unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) + fn index(&self, id: ModuleIdLt<'_>) -> &ModuleData { + self.inner + .get(&unsafe { id.to_static() }) + .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 263f603a0bfb..45d5dc9fcd27 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -881,7 +881,7 @@ impl<'db> Resolver<'db> { })); if let Some(block) = expr_scopes.block(scope_id) { let def_map = block_def_map(db, block); - let local_def_map = block.lookup(db).module.only_local_def_map(db); + let local_def_map = block.module(db).only_local_def_map(db); resolver.scopes.push(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, @@ -1087,7 +1087,7 @@ fn resolver_for_scope_<'db>( for scope in scope_chain.into_iter().rev() { if let Some(block) = scopes.block(scope) { let def_map = block_def_map(db, block); - let local_def_map = block.lookup(db).module.only_local_def_map(db); + let local_def_map = block.module(db).only_local_def_map(db); // Using `DefMap::ROOT` is okay here since inside modules other than the root, // there can't directly be expressions. r = r.push_block_scope(def_map, local_def_map, def_map.root); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index a1645de6ec23..95554c63b97d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -9,8 +9,8 @@ use syntax::ast::{self, HasVisibility}; use triomphe::Arc; use crate::{ - AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, TraitId, VariantId, - db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, + AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, ModuleIdLt, TraitId, + VariantId, db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, }; pub use crate::item_tree::{RawVisibility, VisibilityExplicitness}; @@ -41,9 +41,13 @@ impl Visibility { } #[tracing::instrument(skip_all)] - pub fn is_visible_from(self, db: &dyn DefDatabase, from_module: ModuleId) -> bool { + pub fn is_visible_from<'db>( + self, + db: &'db dyn DefDatabase, + from_module: ModuleIdLt<'db>, + ) -> bool { let to_module = match self { - Visibility::Module(m, _) => m, + Visibility::Module(m, _) => unsafe { m.to_db(db) }, Visibility::PubCrate(krate) => return from_module.krate(db) == krate, Visibility::Public => return true, }; @@ -59,11 +63,11 @@ impl Visibility { Self::is_visible_from_def_map_(db, def_map, to_module, from_module) } - pub(crate) fn is_visible_from_def_map( + pub(crate) fn is_visible_from_def_map<'db>( self, - db: &dyn DefDatabase, - def_map: &DefMap, - from_module: ModuleId, + db: &'db dyn DefDatabase, + def_map: &'db DefMap, + from_module: ModuleIdLt<'db>, ) -> bool { if cfg!(debug_assertions) { _ = def_map.modules[from_module]; @@ -89,11 +93,11 @@ impl Visibility { Self::is_visible_from_def_map_(db, def_map, to_module, from_module) } - fn is_visible_from_def_map_( - db: &dyn DefDatabase, - def_map: &DefMap, - mut to_module: ModuleId, - mut from_module: ModuleId, + fn is_visible_from_def_map_<'db>( + db: &'db dyn DefDatabase, + def_map: &'db DefMap, + mut to_module: ModuleIdLt<'db>, + mut from_module: ModuleIdLt<'db>, ) -> bool { debug_assert_eq!(to_module.krate(db), def_map.krate()); // `to_module` might be the root module of a block expression. Those have the same diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index cafe0329692c..70868e4b95aa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -653,19 +653,16 @@ impl<'db> InferenceResult<'db> { } pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option> { match self.expr_adjustments.get(&id).and_then(|adjustments| { - adjustments - .iter() - .filter(|adj| { - // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140 - !matches!( - adj, - Adjustment { - kind: Adjust::NeverToAny, - target, - } if target.is_never() - ) - }) - .next_back() + adjustments.iter().rfind(|adj| { + // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140 + !matches!( + adj, + Adjustment { + kind: Adjust::NeverToAny, + target, + } if target.is_never() + ) + }) }) { Some(adjustment) => Some(adjustment.target), None => self.type_of_expr.get(id).copied(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index 868ae00329b3..d9cfe6d84c2b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -13,8 +13,8 @@ use tracing::{debug, instrument}; use base_db::Crate; use hir_def::{ - AssocItemId, BlockId, ConstId, FunctionId, GenericParamId, HasModule, ImplId, ItemContainerId, - ModuleId, TraitId, + AssocItemId, BlockIdLt, ConstId, FunctionId, GenericParamId, HasModule, ImplId, + ItemContainerId, ModuleId, TraitId, attrs::AttrFlags, expr_store::path::GenericArgs as HirGenericArgs, hir::ExprId, @@ -558,9 +558,9 @@ pub struct InherentImpls { } #[salsa::tracked] -impl InherentImpls { +impl<'db> InherentImpls { #[salsa::tracked(returns(ref))] - pub fn for_crate(db: &dyn HirDatabase, krate: Crate) -> Self { + pub fn for_crate(db: &'db dyn HirDatabase, krate: Crate) -> Self { let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered(); let crate_def_map = crate_def_map(db, krate); @@ -569,7 +569,7 @@ impl InherentImpls { } #[salsa::tracked(returns(ref))] - pub fn for_block(db: &dyn HirDatabase, block: BlockId) -> Option> { + pub fn for_block(db: &'db dyn HirDatabase, block: BlockIdLt<'db>) -> Option> { let _p = tracing::info_span!("inherent_impls_in_block_query").entered(); let block_def_map = block_def_map(db, block); @@ -627,13 +627,13 @@ impl InherentImpls { self.map.get(self_ty).map(|it| &**it).unwrap_or_default() } - pub fn for_each_crate_and_block( - db: &dyn HirDatabase, + pub fn for_each_crate_and_block<'db>( + db: &'db dyn HirDatabase, krate: Crate, - block: Option, + block: Option>, for_each: &mut dyn FnMut(&InherentImpls), ) { - let blocks = std::iter::successors(block, |block| block.loc(db).module.block(db)); + let blocks = std::iter::successors(block, |block| block.module(db).block(db)); blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each); for_each(Self::for_crate(db, krate)); } @@ -670,9 +670,9 @@ pub struct TraitImpls { } #[salsa::tracked] -impl TraitImpls { +impl<'db> TraitImpls { #[salsa::tracked(returns(ref))] - pub fn for_crate(db: &dyn HirDatabase, krate: Crate) -> Arc { + pub fn for_crate(db: &'db dyn HirDatabase, krate: Crate) -> Arc { let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered(); let crate_def_map = crate_def_map(db, krate); @@ -681,7 +681,7 @@ impl TraitImpls { } #[salsa::tracked(returns(ref))] - pub fn for_block(db: &dyn HirDatabase, block: BlockId) -> Option> { + pub fn for_block(db: &'db dyn HirDatabase, block: BlockIdLt<'db>) -> Option> { let _p = tracing::info_span!("inherent_impls_in_block_query").entered(); let block_def_map = block_def_map(db, block); @@ -690,7 +690,7 @@ impl TraitImpls { } #[salsa::tracked(returns(ref))] - pub fn for_crate_and_deps(db: &dyn HirDatabase, krate: Crate) -> Box<[Arc]> { + pub fn for_crate_and_deps(db: &'db dyn HirDatabase, krate: Crate) -> Box<[Arc]> { krate.transitive_deps(db).iter().map(|&dep| Self::for_crate(db, dep).clone()).collect() } } @@ -792,23 +792,23 @@ impl TraitImpls { } } - pub fn for_each_crate_and_block( - db: &dyn HirDatabase, + pub fn for_each_crate_and_block<'db>( + db: &'db dyn HirDatabase, krate: Crate, - block: Option, + block: Option>, for_each: &mut dyn FnMut(&TraitImpls), ) { - let blocks = std::iter::successors(block, |block| block.loc(db).module.block(db)); + let blocks = std::iter::successors(block, |block| block.module(db).block(db)); blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each); Self::for_crate_and_deps(db, krate).iter().map(|it| &**it).for_each(for_each); } /// Like [`Self::for_each_crate_and_block()`], but takes in account two blocks, one for a trait and one for a self type. - pub fn for_each_crate_and_block_trait_and_type( - db: &dyn HirDatabase, + pub fn for_each_crate_and_block_trait_and_type<'db>( + db: &'db dyn HirDatabase, krate: Crate, - type_block: Option, - trait_block: Option, + type_block: Option>, + trait_block: Option>, for_each: &mut dyn FnMut(&TraitImpls), ) { let in_self_and_deps = TraitImpls::for_crate_and_deps(db, krate); @@ -819,10 +819,11 @@ impl TraitImpls { // that means there can't be duplicate impls; if they meet, we stop the search of the deeper block. // This breaks when they are equal (both will stop immediately), therefore we handle this case // specifically. - let blocks_iter = |block: Option| { - std::iter::successors(block, |block| block.loc(db).module.block(db)) + let blocks_iter = |block: Option>| { + std::iter::successors(block, |block| block.module(db).block(db)) }; - let for_each_block = |current_block: Option, other_block: Option| { + let for_each_block = |current_block: Option>, + other_block: Option>| { blocks_iter(current_block) .take_while(move |&block| { other_block.is_none_or(|other_block| other_block != block) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 56560e24c08c..e57f031f009a 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -559,7 +559,7 @@ impl Module { /// in the module tree of any target in `Cargo.toml`. pub fn crate_root(self, db: &dyn HirDatabase) -> Module { let def_map = crate_def_map(db, self.id.krate(db)); - Module { id: def_map.crate_root(db).into() } + Module { id: def_map.crate_root(db) } } pub fn is_crate_root(self, db: &dyn HirDatabase) -> bool { @@ -590,7 +590,7 @@ impl Module { while id.is_block_module(db) { id = id.containing_module(db).expect("block without parent module"); } - Module { id } + Module { id: unsafe { id.to_static() } } } pub fn path_to_root(self, db: &dyn HirDatabase) -> Vec { @@ -2475,7 +2475,7 @@ impl Function { GenericArgs::new_from_iter(interner, []), ParamEnvAndCrate { param_env: db.trait_environment(self.id.into()), - krate: self.id.module(db).krate(), + krate: self.id.module(db).krate(db), }, )?; let (result, output) = interpret_mir(db, body, false, None)?; @@ -4352,7 +4352,7 @@ impl Impl { module.block(db), &mut |impls| extend_with_impls(impls.for_self_ty(&simplified_ty)), ); - std::iter::successors(module.block(db), |block| block.loc(db).module.block(db)) + std::iter::successors(module.block(db), |block| block.module(db).block(db)) .filter_map(|block| TraitImpls::for_block(db, block).as_deref()) .for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls)); for &krate in &**db.all_crates() { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index c1f72debe54f..d924aaa25ddc 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -226,7 +226,7 @@ impl ChildBySource for DefWithBodyId { // All block expressions are merged into the same map, because they logically all add // inner items to the containing `DefWithBodyId`. def_map[def_map.root].scope.child_by_source_to(db, res, file_id); - res[keys::BLOCK].insert(block.lookup(db).ast_id.to_ptr(db), block); + res[keys::BLOCK].insert(block.ast_id(db).to_ptr(db), block); } } } From d54fee82f43587656cfaea63ddba6fbd05005b83 Mon Sep 17 00:00:00 2001 From: Dawid Lachowicz Date: Sat, 6 Dec 2025 19:16:00 +0000 Subject: [PATCH 0382/3801] contracts: fix lowering final declaration without trailing semicolon Lowering for contract delcarations incorrectly handled the final declaration statement when it didn't end in a semicolon. This change fixes the issue. --- compiler/rustc_ast_lowering/src/contract.rs | 14 ++++++++++++- tests/ui/contracts/requires-block-stmt.rs | 22 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 tests/ui/contracts/requires-block-stmt.rs diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index 56413160e04d..6cffd8e119b7 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -23,7 +23,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // The order in which things are lowered is important! I.e to // refer to variables in contract_decls from postcond/precond, // we must lower it first! - let contract_decls = self.lower_stmts(&contract.declarations).0; + let contract_decls = self.lower_decls(contract); match (&contract.requires, &contract.ensures) { (Some(req), Some(ens)) => { @@ -124,6 +124,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } + fn lower_decls(&mut self, contract: &rustc_ast::FnContract) -> &'hir [rustc_hir::Stmt<'hir>] { + let (decls, decls_tail) = self.lower_stmts(&contract.declarations); + + if let Some(e) = decls_tail { + // include the tail expression in the declaration statements + let tail = self.stmt_expr(e.span, *e); + self.arena.alloc_from_iter(decls.into_iter().map(|d| *d).chain([tail].into_iter())) + } else { + decls + } + } + /// Lower the precondition check intrinsic. fn lower_precond(&mut self, req: &Box) -> rustc_hir::Stmt<'hir> { let lowered_req = self.lower_expr_mut(&req); diff --git a/tests/ui/contracts/requires-block-stmt.rs b/tests/ui/contracts/requires-block-stmt.rs new file mode 100644 index 000000000000..0f0801bb65f5 --- /dev/null +++ b/tests/ui/contracts/requires-block-stmt.rs @@ -0,0 +1,22 @@ +//@ run-pass +//@ compile-flags: -Zcontract-checks=yes + +#![expect(incomplete_features)] +#![feature(contracts)] +extern crate core; +use core::contracts::requires; + +// Compound statements (those using [ExpressionWithBlock] +// (https://doc.rust-lang.org/beta/reference/expressions.html#railroad-ExpressionWithBlock)) +// like blocks, if-expressions, and loops require no trailing semicolon. This +// regression test captures the case where the last statement in the contract +// declarations has no trailing semicolon. +#[requires( + {} + true +)] +fn foo() {} + +fn main() { + foo() +} From d53f7676d1685bf1b0de1c303cf497b22f189d81 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sat, 6 Dec 2025 23:22:33 +0900 Subject: [PATCH 0383/3801] Check associated type where-clauses for lifetimes --- compiler/rustc_ast_passes/src/feature_gate.rs | 15 +++++---------- ...associated-type-where-non-lifetime-const.rs | 13 +++++++++++++ ...ciated-type-where-non-lifetime-const.stderr | 13 +++++++++++++ .../associated-type-where-non-lifetime-type.rs | 18 ++++++++++++++++++ ...ociated-type-where-non-lifetime-type.stderr | 13 +++++++++++++ 5 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 tests/ui/associated-types/associated-type-where-non-lifetime-const.rs create mode 100644 tests/ui/associated-types/associated-type-where-non-lifetime-const.stderr create mode 100644 tests/ui/associated-types/associated-type-where-non-lifetime-type.rs create mode 100644 tests/ui/associated-types/associated-type-where-non-lifetime-type.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 2d87d8c84d7c..ee868296d9dc 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -301,17 +301,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_ty(self, ty) } - fn visit_generics(&mut self, g: &'a ast::Generics) { - for predicate in &g.where_clause.predicates { - match &predicate.kind { - ast::WherePredicateKind::BoundPredicate(bound_pred) => { - // A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). - self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params); - } - _ => {} - } + fn visit_where_predicate_kind(&mut self, kind: &'a ast::WherePredicateKind) { + if let ast::WherePredicateKind::BoundPredicate(bound) = kind { + // A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). + self.check_late_bound_lifetime_defs(&bound.bound_generic_params); } - visit::walk_generics(self, g); + visit::walk_where_predicate_kind(self, kind); } fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) { diff --git a/tests/ui/associated-types/associated-type-where-non-lifetime-const.rs b/tests/ui/associated-types/associated-type-where-non-lifetime-const.rs new file mode 100644 index 000000000000..31bf139e39cd --- /dev/null +++ b/tests/ui/associated-types/associated-type-where-non-lifetime-const.rs @@ -0,0 +1,13 @@ +//! regression test for #148627 + +#![feature(associated_type_defaults)] + +trait Trait { + type Assoc2 + = () + where + for [(); C]: Copy; + //~^ ERROR: only lifetime parameters can be used in this context +} + +fn main() {} diff --git a/tests/ui/associated-types/associated-type-where-non-lifetime-const.stderr b/tests/ui/associated-types/associated-type-where-non-lifetime-const.stderr new file mode 100644 index 000000000000..bd1d6e13893a --- /dev/null +++ b/tests/ui/associated-types/associated-type-where-non-lifetime-const.stderr @@ -0,0 +1,13 @@ +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/associated-type-where-non-lifetime-const.rs:9:19 + | +LL | for [(); C]: Copy; + | ^ + | + = 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: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-types/associated-type-where-non-lifetime-type.rs b/tests/ui/associated-types/associated-type-where-non-lifetime-type.rs new file mode 100644 index 000000000000..d4624619e6d8 --- /dev/null +++ b/tests/ui/associated-types/associated-type-where-non-lifetime-type.rs @@ -0,0 +1,18 @@ +//! regression test for #149233 + +trait Foo { + type Bar<'a> + where + Self: Sized; + fn test(&self); +} +impl Foo for () { + type Bar<'a> + = () + where + for T:; + //~^ ERROR: only lifetime parameters can be used in this context + fn test(&self) {} +} + +fn main() {} diff --git a/tests/ui/associated-types/associated-type-where-non-lifetime-type.stderr b/tests/ui/associated-types/associated-type-where-non-lifetime-type.stderr new file mode 100644 index 000000000000..a8a71b929d95 --- /dev/null +++ b/tests/ui/associated-types/associated-type-where-non-lifetime-type.stderr @@ -0,0 +1,13 @@ +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/associated-type-where-non-lifetime-type.rs:13:13 + | +LL | for T:; + | ^ + | + = 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: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. From ef33430266a91e8260cbac58b30811e0cb96df2c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 7 Dec 2025 10:57:13 +0100 Subject: [PATCH 0384/3801] run ptr_int tests with Tree Borrows --- src/tools/miri/tests/pass/ptr_int_casts.rs | 2 + .../miri/tests/pass/ptr_int_casts.tree.stderr | 89 ------------------- .../miri/tests/pass/ptr_int_from_exposed.rs | 2 + .../pass/ptr_int_from_exposed.tree.stderr | 19 ---- 4 files changed, 4 insertions(+), 108 deletions(-) delete mode 100644 src/tools/miri/tests/pass/ptr_int_casts.tree.stderr delete mode 100644 src/tools/miri/tests/pass/ptr_int_from_exposed.tree.stderr diff --git a/src/tools/miri/tests/pass/ptr_int_casts.rs b/src/tools/miri/tests/pass/ptr_int_casts.rs index 94391eac3b27..2d99a8a449b3 100644 --- a/src/tools/miri/tests/pass/ptr_int_casts.rs +++ b/src/tools/miri/tests/pass/ptr_int_casts.rs @@ -1,4 +1,6 @@ //@compile-flags: -Zmiri-permissive-provenance +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows use std::{mem, ptr}; fn eq_ref(x: &T, y: &T) -> bool { diff --git a/src/tools/miri/tests/pass/ptr_int_casts.tree.stderr b/src/tools/miri/tests/pass/ptr_int_casts.tree.stderr deleted file mode 100644 index 21c5b2b0dfe8..000000000000 --- a/src/tools/miri/tests/pass/ptr_int_casts.tree.stderr +++ /dev/null @@ -1,89 +0,0 @@ -warning: integer-to-pointer cast - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | assert_eq!(1 as *const i32 as usize, 1); - | ^^^^^^^^^^^^^^^ integer-to-pointer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead - = help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics - = help: Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used - = note: BACKTRACE: - = note: inside `ptr_int_casts` at tests/pass/ptr_int_casts.rs:LL:CC -note: inside `main` - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | ptr_int_casts(); - | ^^^^^^^^^^^^^^^ - -warning: integer-to-pointer cast - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | assert_eq!((1 as *const i32).wrapping_offset(4) as usize, 1 + 4 * 4); - | ^^^^^^^^^^^^^^^^^ integer-to-pointer cast - | - = note: BACKTRACE: - = note: inside `ptr_int_casts` at tests/pass/ptr_int_casts.rs:LL:CC -note: inside `main` - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | ptr_int_casts(); - | ^^^^^^^^^^^^^^^ - -warning: integer-to-pointer cast - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | *val = (1 as *const u8).wrapping_offset(-4); - | ^^^^^^^^^^^^^^^^ integer-to-pointer cast - | - = note: BACKTRACE: - = note: inside `ptr_int_casts` at tests/pass/ptr_int_casts.rs:LL:CC -note: inside `main` - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | ptr_int_casts(); - | ^^^^^^^^^^^^^^^ - -warning: integer-to-pointer cast - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | let y = y as *const _; - | ^^^^^^^^^^^^^ integer-to-pointer cast - | - = note: BACKTRACE: - = note: inside `ptr_int_casts` at tests/pass/ptr_int_casts.rs:LL:CC -note: inside `main` - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | ptr_int_casts(); - | ^^^^^^^^^^^^^^^ - -warning: integer-to-pointer cast - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | let x: fn() -> i32 = unsafe { mem::transmute(y as *mut u8) }; - | ^^^^^^^^^^^^ integer-to-pointer cast - | - = note: BACKTRACE: - = note: inside `ptr_int_casts` at tests/pass/ptr_int_casts.rs:LL:CC -note: inside `main` - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | ptr_int_casts(); - | ^^^^^^^^^^^^^^^ - -warning: integer-to-pointer cast - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | assert_eq!((-1i32) as usize as *const i32 as usize, (-1i32) as usize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast - | - = note: BACKTRACE: - = note: inside `ptr_int_casts` at tests/pass/ptr_int_casts.rs:LL:CC -note: inside `main` - --> tests/pass/ptr_int_casts.rs:LL:CC - | -LL | ptr_int_casts(); - | ^^^^^^^^^^^^^^^ - diff --git a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs index 98f8f15608e1..200e4b2ea3e9 100644 --- a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs +++ b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs @@ -1,4 +1,6 @@ //@compile-flags: -Zmiri-permissive-provenance +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows use std::ptr; diff --git a/src/tools/miri/tests/pass/ptr_int_from_exposed.tree.stderr b/src/tools/miri/tests/pass/ptr_int_from_exposed.tree.stderr deleted file mode 100644 index aac6d0f48d01..000000000000 --- a/src/tools/miri/tests/pass/ptr_int_from_exposed.tree.stderr +++ /dev/null @@ -1,19 +0,0 @@ -warning: integer-to-pointer cast - --> tests/pass/ptr_int_from_exposed.rs:LL:CC - | -LL | let ptr = ptr::with_exposed_provenance::(x_usize).wrapping_offset(-128); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead - = help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics - = help: Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used - = note: BACKTRACE: - = note: inside `ptr_roundtrip_out_of_bounds` at tests/pass/ptr_int_from_exposed.rs:LL:CC -note: inside `main` - --> tests/pass/ptr_int_from_exposed.rs:LL:CC - | -LL | ptr_roundtrip_out_of_bounds(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - From 8a99d48f84aed46c118395548bd652c9f72ffd11 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 7 Dec 2025 12:10:38 +0100 Subject: [PATCH 0385/3801] genmc: suppress compare_exchange warnings from dependencies --- src/tools/miri/doc/genmc.md | 47 +++--- .../miri/src/concurrency/genmc/helper.rs | 7 +- src/tools/miri/src/concurrency/genmc/mod.rs | 18 ++- .../shims/mutex_diff_thread_unlock.stderr | 62 +------- .../tests/genmc/pass/atomics/cas_simple.rs | 5 + .../genmc/pass/atomics/cas_simple.stderr | 18 +++ .../genmc/pass/std/arc.check_count.stderr | 124 --------------- src/tools/miri/tests/genmc/pass/std/arc.rs | 1 - .../genmc/pass/std/arc.try_upgrade.stderr | 150 ------------------ .../miri/tests/genmc/pass/std/empty_main.rs | 1 - .../tests/genmc/pass/std/empty_main.stderr | 43 ----- .../tests/genmc/pass/std/spawn_std_threads.rs | 1 - .../genmc/pass/std/spawn_std_threads.stderr | 128 --------------- .../tests/genmc/pass/std/thread_locals.rs | 1 - .../tests/genmc/pass/std/thread_locals.stderr | 111 ------------- 15 files changed, 62 insertions(+), 655 deletions(-) diff --git a/src/tools/miri/doc/genmc.md b/src/tools/miri/doc/genmc.md index 7da7a3d18948..e9d4849bc596 100644 --- a/src/tools/miri/doc/genmc.md +++ b/src/tools/miri/doc/genmc.md @@ -1,7 +1,6 @@ # **(WIP)** Documentation for Miri-GenMC -**NOTE: GenMC mode is not yet fully implemented, and has [several correctness issues](https://github.com/rust-lang/miri/issues/4572). Using GenMC mode currently requires manually compiling Miri, see [Usage](#usage).** - +**NOTE: GenMC mode is not yet fully implemented, and has [several correctness issues](https://github.com/rust-lang/miri/issues/4572) and [other limitations](#limitations). Using GenMC mode currently requires manually compiling Miri, see [Usage](#usage).** [GenMC](https://github.com/MPI-SWS/genmc) is a stateless model checker for exploring concurrent executions of a program. Miri-GenMC integrates that model checker into Miri. @@ -12,11 +11,14 @@ This includes all possible thread interleavings and all allowed return values fo It is hence still possible to have latent bugs in a test case even if they passed GenMC.) GenMC requires the input program to be bounded, i.e., have finitely many possible executions, otherwise it will not terminate. -Any loops that may run infinitely must be replaced or bounded (see below). +Any loops that may run infinitely must be replaced or bounded (see [below](#eliminating-unbounded-loops)). GenMC makes use of Dynamic Partial Order Reduction (DPOR) to reduce the number of executions that must be explored, but the runtime can still be super-exponential in the size of the input program (number of threads and amount of interaction between threads). Large programs may not be verifiable in a reasonable amount of time. +GenMC currently only supports Linux hosts. +Both the host and the target must be 64-bit little-endian. + ## Usage For testing/developing Miri-GenMC: @@ -50,16 +52,24 @@ Note that `cargo miri test` in GenMC mode is currently not supported. - `debug2`: Print the execution graph after every memory access. - `debug3`: Print reads-from values considered by GenMC. - `-Zmiri-genmc-verbose`: Show more information, such as estimated number of executions, and time taken for verification. - -#### Regular Miri parameters useful for GenMC mode - - `-Zmiri-disable-weak-memory-emulation`: Disable any weak memory effects (effectively upgrading all atomic orderings in the program to `SeqCst`). This option may reduce the number of explored program executions, but any bugs related to weak memory effects will be missed. This option can help determine if an error is caused by weak memory effects (i.e., if it disappears with this option enabled). -## Tips +## Limitations - +There are several limitations which can make GenMC miss bugs: +- GenMC does not support re-using freed memory for new allocations, so any bugs related to that will be missed. +- GenMC does not support `compare_exchange_weak`, so the consequences of spurious failures are not explored. + A warning will be emitted if this affects code you wrote (but not if it happens inside your dependencies). +- GenMC does not support the separate failure ordering of `compare_exchange`. Miri will take the maximum of the success and failure ordering and use that for the access; outcomes that rely on the real ordering being weaker will not be explored. + A warning will be emitted if this affects code you wrote (but not if it happens inside your dependencies). +- GenMC is incompatible with borrow tracking (Stacked/Tree Borrows). You need to set `-Zmiri-disable-stacked-borrows` to use GenMC. +- Like all C++ memory model verification tools, GenMC has to solve the [out-of-thin-air problem](https://www.cl.cam.ac.uk/~pes20/cpp/notes42.html). + It takes the [usual approach](https://plv.mpi-sws.org/scfix/paper.pdf) of requiring the union of "program-order" and "reads-from" to be acyclic. + This means it excludes certain behaviors allowed by the C++ memory model, some of which can occur on hardware that performs load buffering. + +## Tips ### Eliminating unbounded loops @@ -121,24 +131,11 @@ fn count_until_true_genmc(flag: &AtomicBool) -> u64 { -## Limitations - -Some or all of these limitations might get removed in the future: - -- Borrow tracking is currently incompatible (stacked/tree borrows). -- Only Linux is supported for now. -- No support for 32-bit or big-endian targets. -- No cross-target interpretation. - - - ## Development GenMC is written in C++, which complicates development a bit. The prerequisites for building Miri-GenMC are: -- A compiler with C++23 support. -- LLVM developments headers and clang. - +- A compiler with sufficient C++20 support (we are testing GCC 13). The actual code for GenMC is not contained in the Miri repo itself, but in a [separate GenMC repo](https://github.com/MPI-SWS/genmc) (with its own maintainers). These sources need to be available to build Miri-GenMC. @@ -149,6 +146,8 @@ The process for obtaining them is as follows: If you place this directory inside the Miri folder, it is recommended to call it `genmc-src` as that tells `./miri fmt` to avoid formatting the Rust files inside that folder. + + ### Formatting the C++ code For formatting the C++ code we provide a `.clang-format` file in the `genmc-sys` directory. @@ -157,7 +156,3 @@ With `clang-format` installed, run this command to format the c++ files (replace find ./genmc-sys/cpp/ -name "*.cpp" -o -name "*.hpp" | xargs clang-format --style=file:"./genmc-sys/.clang-format" -i ``` NOTE: this is currently not done automatically on pull requests to Miri. - - - - diff --git a/src/tools/miri/src/concurrency/genmc/helper.rs b/src/tools/miri/src/concurrency/genmc/helper.rs index ae16898106d8..f539e783fd3f 100644 --- a/src/tools/miri/src/concurrency/genmc/helper.rs +++ b/src/tools/miri/src/concurrency/genmc/helper.rs @@ -171,11 +171,8 @@ impl AtomicRwOrd { (AtomicReadOrd::Acquire, AtomicWriteOrd::Relaxed) => AtomicRwOrd::Acquire, (AtomicReadOrd::Relaxed, AtomicWriteOrd::Release) => AtomicRwOrd::Release, (AtomicReadOrd::Acquire, AtomicWriteOrd::Release) => AtomicRwOrd::AcqRel, - (AtomicReadOrd::SeqCst, AtomicWriteOrd::SeqCst) => AtomicRwOrd::SeqCst, - _ => - panic!( - "Unsupported memory ordering combination ({read_ordering:?}, {write_ordering:?})" - ), + (AtomicReadOrd::SeqCst, _) => AtomicRwOrd::SeqCst, + (_, AtomicWriteOrd::SeqCst) => AtomicRwOrd::SeqCst, } } diff --git a/src/tools/miri/src/concurrency/genmc/mod.rs b/src/tools/miri/src/concurrency/genmc/mod.rs index 73da0e11daaf..36b1d2afade4 100644 --- a/src/tools/miri/src/concurrency/genmc/mod.rs +++ b/src/tools/miri/src/concurrency/genmc/mod.rs @@ -402,8 +402,20 @@ impl GenmcCtx { // FIXME(genmc): remove once GenMC supports failure memory ordering in `compare_exchange`. let (effective_failure_ordering, _) = upgraded_success_ordering.split_memory_orderings(); - // Return a warning if the actual orderings don't match the upgraded ones. - if success != upgraded_success_ordering || effective_failure_ordering != fail { + + // Return a warning if we cannot explore all behaviors of this operation. + // Only emit this if the operation is "in user code": walk up across `#[track_caller]` + // frames, then check if the next frame is local. + let show_warning = || { + ecx.active_thread_stack() + .iter() + .rev() + .find(|f| !f.instance().def.requires_caller_location(*ecx.tcx)) + .is_none_or(|f| ecx.machine.is_local(f.instance())) + }; + if (success != upgraded_success_ordering || effective_failure_ordering != fail) + && show_warning() + { static DEDUP: SpanDedupDiagnostic = SpanDedupDiagnostic::new(); ecx.dedup_diagnostic(&DEDUP, |_first| { NonHaltingDiagnostic::GenmcCompareExchangeOrderingMismatch { @@ -415,7 +427,7 @@ impl GenmcCtx { }); } // FIXME(genmc): remove once GenMC implements spurious failures for `compare_exchange_weak`. - if can_fail_spuriously { + if can_fail_spuriously && show_warning() { static DEDUP: SpanDedupDiagnostic = SpanDedupDiagnostic::new(); ecx.dedup_diagnostic(&DEDUP, |_first| NonHaltingDiagnostic::GenmcCompareExchangeWeak); } diff --git a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr index e2148bedd318..db465969cda8 100644 --- a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr +++ b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr @@ -1,64 +1,4 @@ Running GenMC Verification... -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside `miri_start` - --> tests/genmc/fail/shims/mutex_diff_thread_unlock.rs:LL:CC - | -LL | let handle = std::thread::spawn(move || { - | __________________^ -LL | | let guard = guard; // avoid field capturing -LL | | drop(guard); -LL | | }); - | |______^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside `miri_start` - --> tests/genmc/fail/shims/mutex_diff_thread_unlock.rs:LL:CC - | -LL | let handle = std::thread::spawn(move || { - | __________________^ -LL | | let guard = guard; // avoid field capturing -LL | | drop(guard); -LL | | }); - | |______^ - error: Undefined Behavior: Invalid unlock() operation --> RUSTLIB/std/src/sync/poison/mutex.rs:LL:CC | @@ -82,5 +22,5 @@ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report -error: aborting due to 1 previous error; 2 warnings emitted +error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/genmc/pass/atomics/cas_simple.rs b/src/tools/miri/tests/genmc/pass/atomics/cas_simple.rs index e32c7cdf80c4..c19c81995d1b 100644 --- a/src/tools/miri/tests/genmc/pass/atomics/cas_simple.rs +++ b/src/tools/miri/tests/genmc/pass/atomics/cas_simple.rs @@ -30,5 +30,10 @@ fn miri_start(_argc: isize, _argv: *const *const u8) -> isize { if 2 != VALUE.load(SeqCst) { std::process::abort() } + + // Check that we emit warnings for cases that are not fully supported. + let _ = VALUE.compare_exchange(99, 99, SeqCst, Relaxed); + let _ = VALUE.compare_exchange_weak(99, 99, Relaxed, SeqCst); + 0 } diff --git a/src/tools/miri/tests/genmc/pass/atomics/cas_simple.stderr b/src/tools/miri/tests/genmc/pass/atomics/cas_simple.stderr index 7867be2dbe8e..4351b312c75d 100644 --- a/src/tools/miri/tests/genmc/pass/atomics/cas_simple.stderr +++ b/src/tools/miri/tests/genmc/pass/atomics/cas_simple.stderr @@ -1,2 +1,20 @@ Running GenMC Verification... +warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'SeqCst', the failure ordering 'Relaxed' is treated like 'SeqCst'. Miri with GenMC might miss bugs related to this memory access. + --> tests/genmc/pass/atomics/cas_simple.rs:LL:CC + | +LL | let _ = VALUE.compare_exchange(99, 99, SeqCst, Relaxed); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + +warning: GenMC currently does not model the failure ordering for `compare_exchange`. Success ordering 'Relaxed' was upgraded to 'SeqCst' to match failure ordering 'SeqCst'. Miri with GenMC might miss bugs related to this memory access. + --> tests/genmc/pass/atomics/cas_simple.rs:LL:CC + | +LL | let _ = VALUE.compare_exchange_weak(99, 99, Relaxed, SeqCst); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + +warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. + --> tests/genmc/pass/atomics/cas_simple.rs:LL:CC + | +LL | let _ = VALUE.compare_exchange_weak(99, 99, Relaxed, SeqCst); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code + Verification complete with 1 executions. No errors found. diff --git a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr index fdbb9eff2faa..a67635dee1be 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.check_count.stderr @@ -1,126 +1,2 @@ Running GenMC Verification... -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/id.rs:LL:CC - | -LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | let weak = Arc::downgrade(&data_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | let weak = Arc::downgrade(&data_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | let handle = std::thread::spawn(move || { - | __________________^ -... | -LL | | }); - | |______^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | let handle = std::thread::spawn(move || { - | __________________^ -... | -LL | | }); - | |______^ - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relaxed).is_ok() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | handle.join().unwrap(); - | ^^^^^^^^^^^^^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/rt.rs:LL:CC - | -LL | / CLEANUP.call_once(|| unsafe { -LL | | // Flush stdout and disable buffering. -LL | | crate::io::cleanup(); -... | -LL | | }); - | |______^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sync/once.rs:LL:CC - | -LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC - | -LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - Verification complete with 4 executions. No errors found. diff --git a/src/tools/miri/tests/genmc/pass/std/arc.rs b/src/tools/miri/tests/genmc/pass/std/arc.rs index dee29127856d..addf6408c006 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.rs +++ b/src/tools/miri/tests/genmc/pass/std/arc.rs @@ -1,6 +1,5 @@ //@compile-flags: -Zmiri-genmc -Zmiri-disable-stacked-borrows //@revisions: check_count try_upgrade -//@normalize-stderr-test: "\n *= note: inside `std::.*" -> "" // Check that various operations on `std::sync::Arc` are handled properly in GenMC mode. // diff --git a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr index a5423f9a398b..f527b6120232 100644 --- a/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr +++ b/src/tools/miri/tests/genmc/pass/std/arc.try_upgrade.stderr @@ -1,152 +1,2 @@ Running GenMC Verification... -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/id.rs:LL:CC - | -LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | let weak = Arc::downgrade(&data_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | let weak = Arc::downgrade(&data_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | let handle = std::thread::spawn(move || { - | __________________^ -... | -LL | | }); - | |______^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | let handle = std::thread::spawn(move || { - | __________________^ -... | -LL | | }); - | |______^ - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relaxed).is_ok() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: -note: inside `main` - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | handle.join().unwrap(); - | ^^^^^^^^^^^^^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/rt.rs:LL:CC - | -LL | / CLEANUP.call_once(|| unsafe { -LL | | // Flush stdout and disable buffering. -LL | | crate::io::cleanup(); -... | -LL | | }); - | |______^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sync/once.rs:LL:CC - | -LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC - | -LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | if self.inner()?.strong.fetch_update(Acquire, Relaxed, checked_increment).is_ok() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE on thread `unnamed-ID`: -note: inside closure - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | if let Some(strong) = weak_.upgrade() { - | ^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | if self.inner()?.strong.fetch_update(Acquire, Relaxed, checked_increment).is_ok() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE on thread `unnamed-ID`: -note: inside closure - --> tests/genmc/pass/std/arc.rs:LL:CC - | -LL | if let Some(strong) = weak_.upgrade() { - | ^^^^^^^^^^^^^^^ - Verification complete with 7 executions. No errors found. diff --git a/src/tools/miri/tests/genmc/pass/std/empty_main.rs b/src/tools/miri/tests/genmc/pass/std/empty_main.rs index f0e4155ccd5d..2ffc3388fb36 100644 --- a/src/tools/miri/tests/genmc/pass/std/empty_main.rs +++ b/src/tools/miri/tests/genmc/pass/std/empty_main.rs @@ -1,5 +1,4 @@ //@compile-flags: -Zmiri-genmc -Zmiri-disable-stacked-borrows -//@normalize-stderr-test: "\n *= note: inside `std::.*" -> "" // A lot of code runs before main, which we should be able to handle in GenMC mode. diff --git a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr index de07943b0d8d..7867be2dbe8e 100644 --- a/src/tools/miri/tests/genmc/pass/std/empty_main.stderr +++ b/src/tools/miri/tests/genmc/pass/std/empty_main.stderr @@ -1,45 +1,2 @@ Running GenMC Verification... -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/id.rs:LL:CC - | -LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/rt.rs:LL:CC - | -LL | / CLEANUP.call_once(|| unsafe { -LL | | // Flush stdout and disable buffering. -LL | | crate::io::cleanup(); -... | -LL | | }); - | |______^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sync/once.rs:LL:CC - | -LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC - | -LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - Verification complete with 1 executions. No errors found. diff --git a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.rs b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.rs index e32979dc2b51..dadbee47b986 100644 --- a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.rs +++ b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.rs @@ -1,5 +1,4 @@ //@compile-flags: -Zmiri-genmc -Zmiri-disable-stacked-borrows -//@normalize-stderr-test: "\n *= note: inside `std::.*" -> "" // We should be able to spawn and join standard library threads in GenMC mode. // Since these threads do nothing, we should only explore 1 program execution. diff --git a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr index 701934a7cd7f..7867be2dbe8e 100644 --- a/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr +++ b/src/tools/miri/tests/genmc/pass/std/spawn_std_threads.stderr @@ -1,130 +1,2 @@ Running GenMC Verification... -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/id.rs:LL:CC - | -LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside closure - --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC - | -LL | let handles: Vec<_> = (0..N).map(|_| std::thread::spawn(thread_func)).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: inside closure at RUSTLIB/core/src/iter/adapters/map.rs:LL:CC - = note: inside ` as std::iter::Iterator>::fold::<(), {closure@std::iter::adapters::map::map_fold, (), {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}, {closure@std::iter::Iterator::for_each::call, {closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>::{closure#0}}>::{closure#0}}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC - = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::fold::<(), {closure@std::iter::Iterator::for_each::call, {closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>::{closure#0}}>` at RUSTLIB/core/src/iter/adapters/map.rs:LL:CC - = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::for_each::<{closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC - = note: inside `> as std::vec::spec_extend::SpecExtend, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::spec_extend` at RUSTLIB/alloc/src/vec/spec_extend.rs:LL:CC - = note: inside `> as std::vec::spec_from_iter_nested::SpecFromIterNested, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::from_iter` at RUSTLIB/alloc/src/vec/spec_from_iter_nested.rs:LL:CC - = note: inside `> as std::vec::spec_from_iter::SpecFromIter, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::from_iter` at RUSTLIB/alloc/src/vec/spec_from_iter.rs:LL:CC - = note: inside `> as std::iter::FromIterator>>::from_iter::, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>` at RUSTLIB/alloc/src/vec/mod.rs:LL:CC - = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::collect::>>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC - | -LL | let handles: Vec<_> = (0..N).map(|_| std::thread::spawn(thread_func)).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside closure - --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC - | -LL | let handles: Vec<_> = (0..N).map(|_| std::thread::spawn(thread_func)).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: inside closure at RUSTLIB/core/src/iter/adapters/map.rs:LL:CC - = note: inside ` as std::iter::Iterator>::fold::<(), {closure@std::iter::adapters::map::map_fold, (), {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}, {closure@std::iter::Iterator::for_each::call, {closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>::{closure#0}}>::{closure#0}}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC - = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::fold::<(), {closure@std::iter::Iterator::for_each::call, {closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>::{closure#0}}>` at RUSTLIB/core/src/iter/adapters/map.rs:LL:CC - = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::for_each::<{closure@std::vec::Vec>::extend_trusted, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>::{closure#0}}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC - = note: inside `> as std::vec::spec_extend::SpecExtend, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::spec_extend` at RUSTLIB/alloc/src/vec/spec_extend.rs:LL:CC - = note: inside `> as std::vec::spec_from_iter_nested::SpecFromIterNested, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::from_iter` at RUSTLIB/alloc/src/vec/spec_from_iter_nested.rs:LL:CC - = note: inside `> as std::vec::spec_from_iter::SpecFromIter, std::iter::Map, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>>::from_iter` at RUSTLIB/alloc/src/vec/spec_from_iter.rs:LL:CC - = note: inside `> as std::iter::FromIterator>>::from_iter::, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>>` at RUSTLIB/alloc/src/vec/mod.rs:LL:CC - = note: inside `, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}> as std::iter::Iterator>::collect::>>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC - | -LL | let handles: Vec<_> = (0..N).map(|_| std::thread::spawn(thread_func)).collect(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relaxed).is_ok() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: -note: inside closure - --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC - | -LL | handles.into_iter().for_each(|handle| handle.join().unwrap()); - | ^^^^^^^^^^^^^ - = note: inside closure at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC - = note: inside `> as std::iter::Iterator>::fold::<(), {closure@std::iter::Iterator::for_each::call, {closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>::{closure#0}}>` at RUSTLIB/alloc/src/vec/into_iter.rs:LL:CC - = note: inside `> as std::iter::Iterator>::for_each::<{closure@tests/genmc/pass/std/spawn_std_threads.rs:LL:CC}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/spawn_std_threads.rs:LL:CC - | -LL | handles.into_iter().for_each(|handle| handle.join().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/rt.rs:LL:CC - | -LL | / CLEANUP.call_once(|| unsafe { -LL | | // Flush stdout and disable buffering. -LL | | crate::io::cleanup(); -... | -LL | | }); - | |______^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sync/once.rs:LL:CC - | -LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC - | -LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - Verification complete with 1 executions. No errors found. diff --git a/src/tools/miri/tests/genmc/pass/std/thread_locals.rs b/src/tools/miri/tests/genmc/pass/std/thread_locals.rs index 4dac775d3407..d76975d2e92c 100644 --- a/src/tools/miri/tests/genmc/pass/std/thread_locals.rs +++ b/src/tools/miri/tests/genmc/pass/std/thread_locals.rs @@ -1,5 +1,4 @@ //@compile-flags: -Zmiri-ignore-leaks -Zmiri-genmc -Zmiri-disable-stacked-borrows -//@normalize-stderr-test: "\n *= note: inside `std::.*" -> "" use std::alloc::{Layout, alloc}; use std::cell::Cell; diff --git a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr index fd6538fd70fa..bde951866d01 100644 --- a/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr +++ b/src/tools/miri/tests/genmc/pass/std/thread_locals.stderr @@ -1,113 +1,2 @@ Running GenMC Verification... -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/thread/id.rs:LL:CC - | -LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/thread_locals.rs:LL:CC - | -LL | / std::thread::spawn(|| { -LL | | R.set(unsafe { malloc() }); -LL | | let r_ptr = R.get(); -LL | | let _ = X.compare_exchange(std::ptr::null_mut(), r_ptr, SeqCst, SeqCst); -LL | | }), - | |__________^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/thread_locals.rs:LL:CC - | -LL | / std::thread::spawn(|| { -LL | | R.set(unsafe { malloc() }); -LL | | let r_ptr = R.get(); -LL | | let _ = X.compare_exchange(std::ptr::null_mut(), r_ptr, SeqCst, SeqCst); -LL | | }), - | |__________^ - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/alloc/src/sync.rs:LL:CC - | -LL | if this.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relaxed).is_ok() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: -note: inside closure - --> tests/genmc/pass/std/thread_locals.rs:LL:CC - | -LL | handles.into_iter().for_each(|handle| handle.join().unwrap()); - | ^^^^^^^^^^^^^ - = note: inside closure at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC - = note: inside closure at RUSTLIB/core/src/ops/try_trait.rs:LL:CC - = note: inside closure at RUSTLIB/core/src/array/iter/iter_inner.rs:LL:CC - = note: inside `::try_fold::<(), {closure@std::array::iter::iter_inner::PolymorphicIter<[std::mem::MaybeUninit>]>::try_fold<(), {closure@std::ops::try_trait::NeverShortCircuit<()>::wrap_mut_2<(), std::thread::JoinHandle<()>, {closure@std::iter::Iterator::for_each::call, {closure@tests/genmc/pass/std/thread_locals.rs:LL:CC}>::{closure#0}}>::{closure#0}}, std::ops::try_trait::NeverShortCircuit<()>>::{closure#0}}, std::ops::try_trait::NeverShortCircuit<()>>` at RUSTLIB/core/src/ops/index_range.rs:LL:CC - = note: inside `, 3> as std::iter::Iterator>::fold::<(), {closure@std::iter::Iterator::for_each::call, {closure@tests/genmc/pass/std/thread_locals.rs:LL:CC}>::{closure#0}}>` at RUSTLIB/core/src/array/iter.rs:LL:CC - = note: inside `, 3> as std::iter::Iterator>::for_each::<{closure@tests/genmc/pass/std/thread_locals.rs:LL:CC}>` at RUSTLIB/core/src/iter/traits/iterator.rs:LL:CC -note: inside `main` - --> tests/genmc/pass/std/thread_locals.rs:LL:CC - | -LL | handles.into_iter().for_each(|handle| handle.join().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/rt.rs:LL:CC - | -LL | / CLEANUP.call_once(|| unsafe { -LL | | // Flush stdout and disable buffering. -LL | | crate::io::cleanup(); -... | -LL | | }); - | |______^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sync/once.rs:LL:CC - | -LL | self.inner.call(true, &mut |p| f.take().unwrap()(p)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sync/once.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC - | -LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - Verification complete with 2 executions. No errors found. From 3e33ed8fbb1759f4e252bea9ec9d0c0118321a00 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 7 Dec 2025 20:49:22 +0800 Subject: [PATCH 0386/3801] Fix pub in enum variant field for no_such_field Example --- ```rust //- /main.rs mod foo; fn main() { foo::Foo::Variant { bar: 3, $0baz: false}; } //- /foo.rs pub enum Foo { Variant { bar: i32 } } ``` **Before this PR** ```rust pub enum Foo { Variant { bar: i32, pub(crate) baz: bool } } ``` **After this PR** ```rust pub enum Foo { Variant { bar: i32, baz: bool } } ``` --- .../src/handlers/no_such_field.rs | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs index 0edab5e0b3b1..bcfe3a8aa5ce 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs @@ -102,7 +102,8 @@ fn missing_record_expr_field_fixes( let indent = IndentLevel::from_node(last_field_syntax); let mut new_field = new_field.to_string(); - if usage_file_id != def_file_id { + // FIXME: check submodule instead of FileId + if usage_file_id != def_file_id && !matches!(def_id, hir::VariantDef::Variant(_)) { new_field = format!("pub(crate) {new_field}"); } new_field = format!("\n{indent}{new_field}"); @@ -357,6 +358,34 @@ pub struct Foo { ) } + #[test] + fn test_add_enum_variant_field_in_other_file_from_usage() { + check_fix( + r#" +//- /main.rs +mod foo; + +fn main() { + foo::Foo::Variant { bar: 3, $0baz: false}; +} +//- /foo.rs +pub enum Foo { + Variant { + bar: i32 + } +} +"#, + r#" +pub enum Foo { + Variant { + bar: i32, + baz: bool + } +} +"#, + ) + } + #[test] fn test_tuple_field_on_record_struct() { check_no_fix( From 87f9ea206eb868963ccc80f53efdc84590fcbdc7 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Wed, 3 Dec 2025 15:40:02 +0100 Subject: [PATCH 0387/3801] add tests for tidy alphabetical blessing --- src/tools/tidy/src/alphabetical/tests.rs | 107 +++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/src/tools/tidy/src/alphabetical/tests.rs b/src/tools/tidy/src/alphabetical/tests.rs index 6a756a84cf99..7c3438df41a7 100644 --- a/src/tools/tidy/src/alphabetical/tests.rs +++ b/src/tools/tidy/src/alphabetical/tests.rs @@ -29,6 +29,23 @@ fn bad(lines: &str, expected_msg: &str) { test(lines, "bad", expected_msg, true); } +#[track_caller] +fn bless_test(before: &str, after: &str) { + let tempfile = tempfile::Builder::new().tempfile().unwrap(); + std::fs::write(tempfile.path(), before).unwrap(); + + let tidy_ctx = TidyCtx::new(Path::new("/aaaa"), false, TidyFlags::new(&["--bless".to_owned()])); + + let mut check = tidy_ctx.start_check("alphabetical-test"); + check_lines(tempfile.path(), before, &tidy_ctx, &mut check); + + assert!(!check.is_bad()); + let new = std::fs::read_to_string(tempfile.path()).unwrap(); + assert_eq!(new, after); + + good(&new); +} + #[test] fn test_no_markers() { let lines = "\ @@ -396,3 +413,93 @@ fn multiline() { "; good(lines); } + +#[test] +fn bless_smoke() { + let before = "\ + tidy-alphabetical-start + 08 + 1 + 11 + 03 + tidy-alphabetical-end + "; + let after = "\ + tidy-alphabetical-start + 1 + 03 + 08 + 11 + tidy-alphabetical-end + "; + + bless_test(before, after); +} + +#[test] +fn bless_multiline() { + let before = "\ + tidy-alphabetical-start + 08 { + z} + 08 { + x + } + 1 + 08 {y} + 02 + 11 ( + 0 + ) + 03 + addition + notaddition + tidy-alphabetical-end + "; + let after = "\ + tidy-alphabetical-start + 1 + 02 + 03 + addition + 08 { + x + } + 08 {y} + 08 { + z} + 11 ( + 0 + ) + notaddition + tidy-alphabetical-end + "; + + bless_test(before, after); +} + +#[test] +fn bless_funny_numbers() { + // Because `2` is indented it gets merged into one entry with `1` and gets + // interpreted by version sort as `12`, which is greater than `3`. + // + // This is neither a wanted nor an unwanted behavior, this test just checks + // that it hasn't changed. + + let before = "\ + tidy-alphabetical-start + 1 + 2 + 3 + tidy-alphabetical-end + "; + let after = "\ + tidy-alphabetical-start + 3 + 1 + 2 + tidy-alphabetical-end + "; + + bless_test(before, after); +} From 3bbd6ea19a57edcd45ad1558754c1b59aabd836e Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Sun, 7 Dec 2025 13:45:49 +0100 Subject: [PATCH 0388/3801] attempt to fix tidyselftest on windows --- src/tools/tidy/src/alphabetical/tests.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tools/tidy/src/alphabetical/tests.rs b/src/tools/tidy/src/alphabetical/tests.rs index 7c3438df41a7..4a1d263f1a4f 100644 --- a/src/tools/tidy/src/alphabetical/tests.rs +++ b/src/tools/tidy/src/alphabetical/tests.rs @@ -31,16 +31,19 @@ fn bad(lines: &str, expected_msg: &str) { #[track_caller] fn bless_test(before: &str, after: &str) { - let tempfile = tempfile::Builder::new().tempfile().unwrap(); - std::fs::write(tempfile.path(), before).unwrap(); + // NB: convert to a temporary *path* (closing the file), so that `check_lines` can then + // atomically replace the file with a blessed version (on windows that requires the file + // to not be open) + let temp_path = tempfile::Builder::new().tempfile().unwrap().into_temp_path(); + std::fs::write(&temp_path, before).unwrap(); - let tidy_ctx = TidyCtx::new(Path::new("/aaaa"), false, TidyFlags::new(&["--bless".to_owned()])); + let tidy_ctx = TidyCtx::new(Path::new("/"), false, TidyFlags::new(&["--bless".to_owned()])); let mut check = tidy_ctx.start_check("alphabetical-test"); - check_lines(tempfile.path(), before, &tidy_ctx, &mut check); + check_lines(&temp_path, before, &tidy_ctx, &mut check); assert!(!check.is_bad()); - let new = std::fs::read_to_string(tempfile.path()).unwrap(); + let new = std::fs::read_to_string(temp_path).unwrap(); assert_eq!(new, after); good(&new); From 89a81425713c7e86fb1944cd1a4d4ad1a56e1ac4 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 7 Dec 2025 21:18:34 +0800 Subject: [PATCH 0389/3801] No complete unit RetType in resugar async assoc item Example --- ```rust use core::future::Future; trait DesugaredAsyncTrait { fn foo(&self) -> impl Future + Send; } impl DesugaredAsyncTrait for () { $0 } ``` **Before this PR** ```rust use core::future::Future; trait DesugaredAsyncTrait { fn foo(&self) -> impl Future + Send; } impl DesugaredAsyncTrait for () { async fn foo(&self) -> () { $0 } } ``` **After this PR** ```rust use core::future::Future; trait DesugaredAsyncTrait { fn foo(&self) -> impl Future + Send; } impl DesugaredAsyncTrait for () { async fn foo(&self) { $0 } } ``` --- .../src/completions/item_list/trait_impl.rs | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs index cdd77e79b5cd..4072f05a41f4 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -344,7 +344,13 @@ fn get_transformed_fn( } _ => None, })?; - ted::replace(ty.syntax(), output.syntax()); + if let ast::Type::TupleType(ty) = &output + && ty.fields().next().is_none() + { + ted::remove(fn_.ret_type()?.syntax()); + } else { + ted::replace(ty.syntax(), output.syntax()); + } } _ => (), } @@ -1617,6 +1623,35 @@ impl DesugaredAsyncTrait for () { $0 } } +"#, + ); + + check_edit( + "async fn foo", + r#" +//- minicore: future, send, sized +use core::future::Future; + +trait DesugaredAsyncTrait { + fn foo(&self) -> impl Future + Send; +} + +impl DesugaredAsyncTrait for () { + $0 +} +"#, + r#" +use core::future::Future; + +trait DesugaredAsyncTrait { + fn foo(&self) -> impl Future + Send; +} + +impl DesugaredAsyncTrait for () { + async fn foo(&self) { + $0 +} +} "#, ); } From 7553f464308db4d5508e81dd4d4ad92252186a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 4 Dec 2025 10:41:13 +0000 Subject: [PATCH 0390/3801] inline constant typeck constraint --- .../src/polonius/typeck_constraints.rs | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/typeck_constraints.rs b/compiler/rustc_borrowck/src/polonius/typeck_constraints.rs index e4e52962bf7f..7d406837f5ae 100644 --- a/compiler/rustc_borrowck/src/polonius/typeck_constraints.rs +++ b/compiler/rustc_borrowck/src/polonius/typeck_constraints.rs @@ -45,7 +45,6 @@ pub(super) fn convert_typeck_constraints<'tcx>( { localize_statement_constraint( tcx, - body, stmt, &outlives_constraint, point, @@ -74,7 +73,6 @@ pub(super) fn convert_typeck_constraints<'tcx>( /// needed CFG `from`-`to` intra-block nodes. fn localize_statement_constraint<'tcx>( tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, stmt: &Statement<'tcx>, outlives_constraint: &OutlivesConstraint<'tcx>, current_point: PointIndex, @@ -114,28 +112,22 @@ fn localize_statement_constraint<'tcx>( }, "there should be no common regions between the LHS and RHS of an assignment" ); - - let lhs_ty = body.local_decls[lhs.local].ty; - let successor_point = current_point; - compute_constraint_direction( - tcx, - outlives_constraint, - &lhs_ty, - current_point, - successor_point, - universal_regions, - ) } _ => { - // For the other cases, we localize an outlives constraint to where it arises. - LocalizedOutlivesConstraint { - source: outlives_constraint.sup, - from: current_point, - target: outlives_constraint.sub, - to: current_point, - } + // Assignments should be the only statement that can both generate constraints that + // apply on entry (specific to the RHS place) *and* others that only apply on exit (the + // subset of RHS regions that actually flow into the LHS): i.e., where midpoints would + // be used to ensure the former happen before the latter, within the same MIR Location. } } + + // We generally localize an outlives constraint to where it arises. + LocalizedOutlivesConstraint { + source: outlives_constraint.sup, + from: current_point, + target: outlives_constraint.sub, + to: current_point, + } } /// For a given outlives constraint arising from a MIR terminator, localize the constraint with the From 38f795dd028fd02b28278c43a828907e34f82cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 4 Dec 2025 11:18:06 +0000 Subject: [PATCH 0391/3801] update comments --- .../rustc_borrowck/src/polonius/typeck_constraints.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/typeck_constraints.rs b/compiler/rustc_borrowck/src/polonius/typeck_constraints.rs index 7d406837f5ae..cfe9376fb502 100644 --- a/compiler/rustc_borrowck/src/polonius/typeck_constraints.rs +++ b/compiler/rustc_borrowck/src/polonius/typeck_constraints.rs @@ -142,14 +142,12 @@ fn localize_terminator_constraint<'tcx>( universal_regions: &UniversalRegions<'tcx>, ) -> LocalizedOutlivesConstraint { // FIXME: check if other terminators need the same handling as `Call`s, in particular - // Assert/Yield/Drop. A handful of tests are failing with Drop related issues, as well as some - // coroutine tests, and that may be why. + // Assert/Yield/Drop. match &terminator.kind { // FIXME: also handle diverging calls. TerminatorKind::Call { destination, target: Some(target), .. } => { - // Calls are similar to assignments, and thus follow the same pattern. If there is a - // target for the call we also relate what flows into the destination here to entry to - // that successor. + // If there is a target for the call we also relate what flows into the destination here + // to entry to that successor. let destination_ty = destination.ty(&body.local_decls, tcx); let successor_location = Location { block: *target, statement_index: 0 }; let successor_point = liveness.point_from_location(successor_location); From 34c61d1a72a93a98d21c2ff9464940c32536892e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 7 Dec 2025 14:51:56 +0100 Subject: [PATCH 0392/3801] fix: Disable postcard use temporarily --- src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index e31ab86bdd2d..d6a8d27bfc42 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -58,7 +58,9 @@ impl ProcMacroServerProcess { if v.pre.as_str() == "nightly" { *v > VERSION } else { *v >= VERSION } }); - let formats: &[_] = if has_working_format_flag { + let formats: &[_] = if std::env::var_os("RUST_ANALYZER_USE_POSTCARD").is_some() + && has_working_format_flag + { &[ (Some("postcard-legacy"), Protocol::LegacyPostcard { mode: SpanMode::Id }), (Some("json-legacy"), Protocol::LegacyJson { mode: SpanMode::Id }), From 0bd9a2fafc1e041b3fcf030264b19912f7dda0d3 Mon Sep 17 00:00:00 2001 From: Dawid Lachowicz Date: Sun, 7 Dec 2025 15:42:23 +0000 Subject: [PATCH 0393/3801] contracts: clean up feature flag warning duplicated across tests There is no need for every contracts test to assert the same warning for using the `contracts` feature flag, as such use `#![expect(incomplete_features)]` in the tests, and add one test to specifically check for the warning. --- tests/ui/contracts/associated-item.rs | 2 +- .../contracts/async-fn-contract-ice-145333.rs | 2 +- .../async-fn-contract-ice-145333.stderr | 11 +---------- .../contract-annotation-limitations.rs | 2 +- .../contract-annotation-limitations.stderr | 11 +---------- ...ct-attributes-generics.chk_const_fail.stderr | 11 ----------- ...act-attributes-generics.chk_fail_post.stderr | 11 ----------- ...ract-attributes-generics.chk_fail_pre.stderr | 11 ----------- ...contract-attributes-generics.chk_pass.stderr | 11 ----------- .../contracts/contract-attributes-generics.rs | 2 +- ...ntract-attributes-generics.unchk_pass.stderr | 11 ----------- ...ontract-attributes-nest.chk_fail_post.stderr | 11 ----------- ...contract-attributes-nest.chk_fail_pre.stderr | 11 ----------- .../contract-attributes-nest.chk_pass.stderr | 11 ----------- tests/ui/contracts/contract-attributes-nest.rs | 2 +- ...tract-attributes-nest.unchk_fail_post.stderr | 11 ----------- ...ntract-attributes-nest.unchk_fail_pre.stderr | 11 ----------- .../contract-attributes-nest.unchk_pass.stderr | 11 ----------- ...ontract-attributes-tail.chk_fail_post.stderr | 11 ----------- ...contract-attributes-tail.chk_fail_pre.stderr | 11 ----------- .../contract-attributes-tail.chk_pass.stderr | 11 ----------- tests/ui/contracts/contract-attributes-tail.rs | 2 +- ...tract-attributes-tail.unchk_fail_post.stderr | 11 ----------- ...ntract-attributes-tail.unchk_fail_pre.stderr | 11 ----------- .../contract-attributes-tail.unchk_pass.stderr | 11 ----------- .../contract-captures-via-closure-copy.rs | 2 +- .../contract-captures-via-closure-copy.stderr | 11 ----------- .../contract-captures-via-closure-noncopy.rs | 2 +- ...contract-captures-via-closure-noncopy.stderr | 11 +---------- .../contracts/contract-const-fn.all_pass.stderr | 11 ----------- tests/ui/contracts/contract-const-fn.rs | 2 +- .../contract-const-fn.runtime_fail_post.stderr | 11 ----------- .../contract-const-fn.runtime_fail_pre.stderr | 11 ----------- ...ntracts-disabled-side-effect-declarations.rs | 2 +- ...cts-disabled-side-effect-declarations.stderr | 11 ----------- .../contracts-disabled-side-effect-ensures.rs | 2 +- ...ontracts-disabled-side-effect-ensures.stderr | 11 ----------- ...ts-ensures-early-fn-exit.chk_fail_ret.stderr | 11 ----------- ...ts-ensures-early-fn-exit.chk_fail_try.stderr | 11 ----------- ...s-ensures-early-fn-exit.chk_fail_yeet.stderr | 11 ----------- ...tracts-ensures-early-fn-exit.chk_pass.stderr | 11 ----------- .../contracts-ensures-early-fn-exit.rs | 2 +- ...acts-ensures-early-fn-exit.unchk_pass.stderr | 11 ----------- ...cts-ensures-is-not-inherited-when-nesting.rs | 2 +- ...ensures-is-not-inherited-when-nesting.stderr | 11 ----------- ...ts-requires-is-not-inherited-when-nesting.rs | 2 +- ...equires-is-not-inherited-when-nesting.stderr | 11 ----------- .../declared-vars-referring-to-params.rs | 2 +- .../declared-vars-referring-to-params.stderr | 11 ----------- .../contracts/declared-vars-used-in-ensures.rs | 2 +- .../declared-vars-used-in-ensures.stderr | 11 ----------- ...eclared-vars-used-in-requires-and-ensures.rs | 2 +- ...red-vars-used-in-requires-and-ensures.stderr | 11 ----------- .../disallow-contract-annotation-on-non-fn.rs | 2 +- ...isallow-contract-annotation-on-non-fn.stderr | 11 +---------- tests/ui/contracts/empty-ensures.rs | 2 +- tests/ui/contracts/empty-ensures.stderr | 11 +---------- tests/ui/contracts/empty-requires.rs | 2 +- tests/ui/contracts/empty-requires.stderr | 11 +---------- tests/ui/contracts/incomplete-feature.rs | 17 +++++++++++++++++ ...ed-item.stderr => incomplete-feature.stderr} | 2 +- .../contract-lang-items.chk_fail_post.stderr | 11 ----------- .../contract-lang-items.chk_pass.stderr | 11 ----------- .../internal_machinery/contract-lang-items.rs | 2 +- .../contract-lang-items.unchk_pass.stderr | 11 ----------- .../internal_machinery/lowering/basics.rs | 2 +- .../internal_machinery/lowering/basics.stderr | 11 ----------- .../requires-bool-expr-with-semicolon.rs | 2 +- .../requires-bool-expr-with-semicolon.stderr | 11 +---------- .../contracts/requires-no-final-expression.rs | 2 +- .../requires-no-final-expression.stderr | 11 +---------- 71 files changed, 50 insertions(+), 512 deletions(-) delete mode 100644 tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr delete mode 100644 tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr delete mode 100644 tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr delete mode 100644 tests/ui/contracts/contract-attributes-generics.chk_pass.stderr delete mode 100644 tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr delete mode 100644 tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr delete mode 100644 tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr delete mode 100644 tests/ui/contracts/contract-attributes-nest.chk_pass.stderr delete mode 100644 tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr delete mode 100644 tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr delete mode 100644 tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr delete mode 100644 tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr delete mode 100644 tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr delete mode 100644 tests/ui/contracts/contract-attributes-tail.chk_pass.stderr delete mode 100644 tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr delete mode 100644 tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr delete mode 100644 tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr delete mode 100644 tests/ui/contracts/contract-captures-via-closure-copy.stderr delete mode 100644 tests/ui/contracts/contract-const-fn.all_pass.stderr delete mode 100644 tests/ui/contracts/contract-const-fn.runtime_fail_post.stderr delete mode 100644 tests/ui/contracts/contract-const-fn.runtime_fail_pre.stderr delete mode 100644 tests/ui/contracts/contracts-disabled-side-effect-declarations.stderr delete mode 100644 tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr delete mode 100644 tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr delete mode 100644 tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr delete mode 100644 tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr delete mode 100644 tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr delete mode 100644 tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr delete mode 100644 tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr delete mode 100644 tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr delete mode 100644 tests/ui/contracts/declared-vars-referring-to-params.stderr delete mode 100644 tests/ui/contracts/declared-vars-used-in-ensures.stderr delete mode 100644 tests/ui/contracts/declared-vars-used-in-requires-and-ensures.stderr create mode 100644 tests/ui/contracts/incomplete-feature.rs rename tests/ui/contracts/{associated-item.stderr => incomplete-feature.stderr} (90%) delete mode 100644 tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr delete mode 100644 tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr delete mode 100644 tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr delete mode 100644 tests/ui/contracts/internal_machinery/lowering/basics.stderr diff --git a/tests/ui/contracts/associated-item.rs b/tests/ui/contracts/associated-item.rs index 4a2d05abbc53..86ff05f6c0f4 100644 --- a/tests/ui/contracts/associated-item.rs +++ b/tests/ui/contracts/associated-item.rs @@ -3,8 +3,8 @@ //@ compile-flags: --crate-type=lib //@ check-pass +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use extern crate core; diff --git a/tests/ui/contracts/async-fn-contract-ice-145333.rs b/tests/ui/contracts/async-fn-contract-ice-145333.rs index a6de8a786af9..e9e2877cd2de 100644 --- a/tests/ui/contracts/async-fn-contract-ice-145333.rs +++ b/tests/ui/contracts/async-fn-contract-ice-145333.rs @@ -1,7 +1,7 @@ //@ compile-flags: --crate-type=lib //@ edition: 2021 +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete #[core::contracts::ensures(|ret| *ret)] //~^ ERROR contract annotations are not yet supported on async or gen functions diff --git a/tests/ui/contracts/async-fn-contract-ice-145333.stderr b/tests/ui/contracts/async-fn-contract-ice-145333.stderr index 77f5379e6fb5..031cff5cad1b 100644 --- a/tests/ui/contracts/async-fn-contract-ice-145333.stderr +++ b/tests/ui/contracts/async-fn-contract-ice-145333.stderr @@ -4,14 +4,5 @@ error: contract annotations are not yet supported on async or gen functions LL | #[core::contracts::ensures(|ret| *ret)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/async-fn-contract-ice-145333.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/contracts/contract-annotation-limitations.rs b/tests/ui/contracts/contract-annotation-limitations.rs index 10b3bacab5cf..0ecc1d15aa7b 100644 --- a/tests/ui/contracts/contract-annotation-limitations.rs +++ b/tests/ui/contracts/contract-annotation-limitations.rs @@ -1,8 +1,8 @@ //! Test for some of the existing limitations and the current error messages. //! Some of these limitations may be removed in the future. +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #![allow(dead_code)] /// Represent a 5-star system. diff --git a/tests/ui/contracts/contract-annotation-limitations.stderr b/tests/ui/contracts/contract-annotation-limitations.stderr index 14338cf4b868..c0dc37fee4c4 100644 --- a/tests/ui/contracts/contract-annotation-limitations.stderr +++ b/tests/ui/contracts/contract-annotation-limitations.stderr @@ -10,14 +10,5 @@ error: contract annotations is only supported in functions with bodies LL | #[core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-annotation-limitations.rs:4:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr b/tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr b/tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-generics.chk_pass.stderr b/tests/ui/contracts/contract-attributes-generics.chk_pass.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-generics.rs b/tests/ui/contracts/contract-attributes-generics.rs index 3763ce116f84..6fd4c0a9790b 100644 --- a/tests/ui/contracts/contract-attributes-generics.rs +++ b/tests/ui/contracts/contract-attributes-generics.rs @@ -16,8 +16,8 @@ //@ [chk_fail_post] compile-flags: -Zcontract-checks=yes //@ [chk_const_fail] compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] use std::ops::Sub; diff --git a/tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr b/tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr b/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.rs b/tests/ui/contracts/contract-attributes-nest.rs index d367687b84e3..89bd0a2b1136 100644 --- a/tests/ui/contracts/contract-attributes-nest.rs +++ b/tests/ui/contracts/contract-attributes-nest.rs @@ -16,8 +16,8 @@ //@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes //@ [chk_fail_post] compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #[core::contracts::requires(x.baz > 0)] #[core::contracts::ensures(|ret| *ret > 100)] diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr b/tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.chk_pass.stderr b/tests/ui/contracts/contract-attributes-tail.chk_pass.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.rs b/tests/ui/contracts/contract-attributes-tail.rs index 43edfe5e803f..361725474099 100644 --- a/tests/ui/contracts/contract-attributes-tail.rs +++ b/tests/ui/contracts/contract-attributes-tail.rs @@ -16,8 +16,8 @@ //@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes //@ [chk_fail_post] compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #[core::contracts::requires(x.baz > 0)] #[core::contracts::ensures(|ret| *ret > 100)] diff --git a/tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr b/tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-captures-via-closure-copy.rs b/tests/ui/contracts/contract-captures-via-closure-copy.rs index bc7e5b9b6f10..a5453503b4bd 100644 --- a/tests/ui/contracts/contract-captures-via-closure-copy.rs +++ b/tests/ui/contracts/contract-captures-via-closure-copy.rs @@ -1,8 +1,8 @@ //@ run-crash //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] struct Baz { baz: i32 diff --git a/tests/ui/contracts/contract-captures-via-closure-copy.stderr b/tests/ui/contracts/contract-captures-via-closure-copy.stderr deleted file mode 100644 index d92db601608f..000000000000 --- a/tests/ui/contracts/contract-captures-via-closure-copy.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-captures-via-closure-copy.rs:4:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-captures-via-closure-noncopy.rs b/tests/ui/contracts/contract-captures-via-closure-noncopy.rs index 1ec2feb045a3..c7aa72d2b0f6 100644 --- a/tests/ui/contracts/contract-captures-via-closure-noncopy.rs +++ b/tests/ui/contracts/contract-captures-via-closure-noncopy.rs @@ -1,8 +1,8 @@ //@ edition:2015..2021 //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] struct Baz { baz: i32 diff --git a/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr index 29adeaec3e16..5f55faed80c8 100644 --- a/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr +++ b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr @@ -1,12 +1,3 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-captures-via-closure-noncopy.rs:4:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `Baz: std::marker::Copy` is not satisfied in `{closure@$DIR/contract-captures-via-closure-noncopy.rs:13:42: 13:57}` --> $DIR/contract-captures-via-closure-noncopy.rs:13:1 | @@ -32,6 +23,6 @@ LL + #[derive(Copy)] LL | struct Baz { | -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/contracts/contract-const-fn.all_pass.stderr b/tests/ui/contracts/contract-const-fn.all_pass.stderr deleted file mode 100644 index e5b1df655823..000000000000 --- a/tests/ui/contracts/contract-const-fn.all_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-const-fn.rs:17:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-const-fn.rs b/tests/ui/contracts/contract-const-fn.rs index fe8dd37b1f52..c79ab33e8ec8 100644 --- a/tests/ui/contracts/contract-const-fn.rs +++ b/tests/ui/contracts/contract-const-fn.rs @@ -14,8 +14,8 @@ //@ [all_pass] compile-flags: -Zcontract-checks=yes //@ [runtime_fail_pre] compile-flags: -Zcontract-checks=yes //@ [runtime_fail_post] compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::*; diff --git a/tests/ui/contracts/contract-const-fn.runtime_fail_post.stderr b/tests/ui/contracts/contract-const-fn.runtime_fail_post.stderr deleted file mode 100644 index e5b1df655823..000000000000 --- a/tests/ui/contracts/contract-const-fn.runtime_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-const-fn.rs:17:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-const-fn.runtime_fail_pre.stderr b/tests/ui/contracts/contract-const-fn.runtime_fail_pre.stderr deleted file mode 100644 index e5b1df655823..000000000000 --- a/tests/ui/contracts/contract-const-fn.runtime_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-const-fn.rs:17:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-disabled-side-effect-declarations.rs b/tests/ui/contracts/contracts-disabled-side-effect-declarations.rs index fc07729e9132..4b2d4a80237f 100644 --- a/tests/ui/contracts/contracts-disabled-side-effect-declarations.rs +++ b/tests/ui/contracts/contracts-disabled-side-effect-declarations.rs @@ -1,6 +1,6 @@ //@ run-pass +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::requires; diff --git a/tests/ui/contracts/contracts-disabled-side-effect-declarations.stderr b/tests/ui/contracts/contracts-disabled-side-effect-declarations.stderr deleted file mode 100644 index 4c8a12538433..000000000000 --- a/tests/ui/contracts/contracts-disabled-side-effect-declarations.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-disabled-side-effect-declarations.rs:2:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs b/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs index a3a77b0de9a2..1488b8f8d3fd 100644 --- a/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs +++ b/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs @@ -1,6 +1,6 @@ //@ run-pass +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::ensures; diff --git a/tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr b/tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr deleted file mode 100644 index dd9ebe9bd355..000000000000 --- a/tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-disabled-side-effect-ensures.rs:2:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.rs b/tests/ui/contracts/contracts-ensures-early-fn-exit.rs index 44ae07d8c95c..71c69fa83ccb 100644 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.rs +++ b/tests/ui/contracts/contracts-ensures-early-fn-exit.rs @@ -13,8 +13,8 @@ //@ [chk_fail_yeet] compile-flags: -Zcontract-checks=yes //! This test ensures that ensures clauses are checked for different return points of a function. +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #![feature(yeet_expr)] /// This ensures will fail in different return points depending on the input. diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs index f01a852fbff3..0fc9e5590f02 100644 --- a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs +++ b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #[core::contracts::ensures(|ret| *ret > 0)] fn outer() -> i32 { diff --git a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr deleted file mode 100644 index 49a372b53c7d..000000000000 --- a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-is-not-inherited-when-nesting.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs index 2c2a4a697855..3ac539adb247 100644 --- a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs +++ b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] struct Outer { outer: std::cell::Cell } diff --git a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr deleted file mode 100644 index 48898c4434ad..000000000000 --- a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-requires-is-not-inherited-when-nesting.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/declared-vars-referring-to-params.rs b/tests/ui/contracts/declared-vars-referring-to-params.rs index 52885da048e2..d915dc09cfe2 100644 --- a/tests/ui/contracts/declared-vars-referring-to-params.rs +++ b/tests/ui/contracts/declared-vars-referring-to-params.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::{ensures, requires}; diff --git a/tests/ui/contracts/declared-vars-referring-to-params.stderr b/tests/ui/contracts/declared-vars-referring-to-params.stderr deleted file mode 100644 index 0ad9064e8606..000000000000 --- a/tests/ui/contracts/declared-vars-referring-to-params.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/declared-vars-referring-to-params.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/declared-vars-used-in-ensures.rs b/tests/ui/contracts/declared-vars-used-in-ensures.rs index 9703709e2b8e..ddab57483668 100644 --- a/tests/ui/contracts/declared-vars-used-in-ensures.rs +++ b/tests/ui/contracts/declared-vars-used-in-ensures.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::{ensures, requires}; diff --git a/tests/ui/contracts/declared-vars-used-in-ensures.stderr b/tests/ui/contracts/declared-vars-used-in-ensures.stderr deleted file mode 100644 index 000a1b239932..000000000000 --- a/tests/ui/contracts/declared-vars-used-in-ensures.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/declared-vars-used-in-ensures.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.rs b/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.rs index e066a95314a9..6b7896101ca0 100644 --- a/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.rs +++ b/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::{ensures, requires}; diff --git a/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.stderr b/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.stderr deleted file mode 100644 index 52b163553fba..000000000000 --- a/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/declared-vars-used-in-requires-and-ensures.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs index 69be906782a6..fecac593f0e5 100644 --- a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs +++ b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs @@ -1,7 +1,7 @@ //! Checks for compilation errors related to adding contracts to non-function items. +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #![allow(dead_code)] #[core::contracts::requires(true)] diff --git a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr index 0a7fff8183e0..864e94997a2e 100644 --- a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr +++ b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr @@ -40,14 +40,5 @@ error: contract annotations can only be used on functions LL | #[core::contracts::requires(true)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/disallow-contract-annotation-on-non-fn.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 7 previous errors diff --git a/tests/ui/contracts/empty-ensures.rs b/tests/ui/contracts/empty-ensures.rs index d897f27bf6c9..0a5239111786 100644 --- a/tests/ui/contracts/empty-ensures.rs +++ b/tests/ui/contracts/empty-ensures.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::ensures; diff --git a/tests/ui/contracts/empty-ensures.stderr b/tests/ui/contracts/empty-ensures.stderr index 407a253bd856..6a19d234b52c 100644 --- a/tests/ui/contracts/empty-ensures.stderr +++ b/tests/ui/contracts/empty-ensures.stderr @@ -1,12 +1,3 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/empty-ensures.rs:2:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: expected a `Fn(&_)` closure, found `()` --> $DIR/empty-ensures.rs:8:1 | @@ -20,6 +11,6 @@ LL | #[ensures()] note: required by a bound in `build_check_ensures` --> $SRC_DIR/core/src/contracts.rs:LL:COL -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/contracts/empty-requires.rs b/tests/ui/contracts/empty-requires.rs index e3c72dcd66a1..dedcc10d52cb 100644 --- a/tests/ui/contracts/empty-requires.rs +++ b/tests/ui/contracts/empty-requires.rs @@ -1,7 +1,7 @@ //@ dont-require-annotations: NOTE //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::requires; diff --git a/tests/ui/contracts/empty-requires.stderr b/tests/ui/contracts/empty-requires.stderr index b48e547b8cda..702b8a23c55e 100644 --- a/tests/ui/contracts/empty-requires.stderr +++ b/tests/ui/contracts/empty-requires.stderr @@ -1,18 +1,9 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/empty-requires.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/empty-requires.rs:9:1 | LL | #[requires()] | ^^^^^^^^^^^^^ expected `bool`, found `()` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/contracts/incomplete-feature.rs b/tests/ui/contracts/incomplete-feature.rs new file mode 100644 index 000000000000..f1351e2f87e3 --- /dev/null +++ b/tests/ui/contracts/incomplete-feature.rs @@ -0,0 +1,17 @@ +//@ run-pass +//@ compile-flags: -Zcontract-checks=yes + +// This test specifically checks that the [incomplete_features] warning is +// emitted when the `contracts` feature gate is enabled, so that it can be +// marked as `expect`ed in other tests in order to reduce duplication. +#![feature(contracts)] +//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] +extern crate core; +use core::contracts::requires; + +#[requires(true)] +fn foo() {} + +fn main() { + foo() +} diff --git a/tests/ui/contracts/associated-item.stderr b/tests/ui/contracts/incomplete-feature.stderr similarity index 90% rename from tests/ui/contracts/associated-item.stderr rename to tests/ui/contracts/incomplete-feature.stderr index 20651026b87a..7683926df073 100644 --- a/tests/ui/contracts/associated-item.stderr +++ b/tests/ui/contracts/incomplete-feature.stderr @@ -1,5 +1,5 @@ warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/associated-item.rs:6:12 + --> $DIR/incomplete-feature.rs:7:12 | LL | #![feature(contracts)] | ^^^^^^^^^ diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr deleted file mode 100644 index acce6b1fbc72..000000000000 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:8:12 - | -LL | #![feature(contracts)] // to access core::contracts - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr deleted file mode 100644 index acce6b1fbc72..000000000000 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:8:12 - | -LL | #![feature(contracts)] // to access core::contracts - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.rs b/tests/ui/contracts/internal_machinery/contract-lang-items.rs index ad88ebfe22e3..d67560103644 100644 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.rs +++ b/tests/ui/contracts/internal_machinery/contract-lang-items.rs @@ -5,8 +5,8 @@ // //@ [chk_fail_post] run-crash +#![expect(incomplete_features)] #![feature(contracts)] // to access core::contracts -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #![feature(contracts_internals)] // to access check_requires lang item #![feature(core_intrinsics)] fn foo(x: Baz) -> i32 { diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr deleted file mode 100644 index acce6b1fbc72..000000000000 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:8:12 - | -LL | #![feature(contracts)] // to access core::contracts - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/internal_machinery/lowering/basics.rs b/tests/ui/contracts/internal_machinery/lowering/basics.rs index 9160517a7932..7b3a769af825 100644 --- a/tests/ui/contracts/internal_machinery/lowering/basics.rs +++ b/tests/ui/contracts/internal_machinery/lowering/basics.rs @@ -1,6 +1,6 @@ //@ run-pass +#![expect(incomplete_features)] #![feature(contracts, cfg_contract_checks, contracts_internals, core_intrinsics)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; diff --git a/tests/ui/contracts/internal_machinery/lowering/basics.stderr b/tests/ui/contracts/internal_machinery/lowering/basics.stderr deleted file mode 100644 index 118229694a90..000000000000 --- a/tests/ui/contracts/internal_machinery/lowering/basics.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basics.rs:2:12 - | -LL | #![feature(contracts, cfg_contract_checks, contracts_internals, core_intrinsics)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/requires-bool-expr-with-semicolon.rs b/tests/ui/contracts/requires-bool-expr-with-semicolon.rs index d0b3ed661ed6..3a1a6549a343 100644 --- a/tests/ui/contracts/requires-bool-expr-with-semicolon.rs +++ b/tests/ui/contracts/requires-bool-expr-with-semicolon.rs @@ -1,7 +1,7 @@ //@ dont-require-annotations: NOTE //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::requires; diff --git a/tests/ui/contracts/requires-bool-expr-with-semicolon.stderr b/tests/ui/contracts/requires-bool-expr-with-semicolon.stderr index fd38fa4edcf5..559c710b1456 100644 --- a/tests/ui/contracts/requires-bool-expr-with-semicolon.stderr +++ b/tests/ui/contracts/requires-bool-expr-with-semicolon.stderr @@ -1,18 +1,9 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/requires-bool-expr-with-semicolon.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/requires-bool-expr-with-semicolon.rs:9:1 | LL | #[requires(true;)] | ^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/contracts/requires-no-final-expression.rs b/tests/ui/contracts/requires-no-final-expression.rs index 474b29d63ba6..0188a9f607a3 100644 --- a/tests/ui/contracts/requires-no-final-expression.rs +++ b/tests/ui/contracts/requires-no-final-expression.rs @@ -1,7 +1,7 @@ //@ dont-require-annotations: NOTE //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::requires; diff --git a/tests/ui/contracts/requires-no-final-expression.stderr b/tests/ui/contracts/requires-no-final-expression.stderr index 0db164857394..ae71ee3c996c 100644 --- a/tests/ui/contracts/requires-no-final-expression.stderr +++ b/tests/ui/contracts/requires-no-final-expression.stderr @@ -1,18 +1,9 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/requires-no-final-expression.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/requires-no-final-expression.rs:9:1 | LL | #[requires(let y = 1;)] | ^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. From ae8429c4a9038853de20f0613c04998fa5a7cc57 Mon Sep 17 00:00:00 2001 From: binarycat Date: Sun, 7 Dec 2025 12:17:17 -0600 Subject: [PATCH 0394/3801] mailmap: add binarycat --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 1118955016bd..a586e7047769 100644 --- a/.mailmap +++ b/.mailmap @@ -83,6 +83,7 @@ Ben Sago Ben Striegel Benjamin Jackman Benoît Cortier +binarycat lolbinarycat Bheesham Persaud Bheesham Persaud bjorn3 <17426603+bjorn3@users.noreply.github.com> bjorn3 <17426603+bjorn3@users.noreply.github.com> From b3e2074c6c4d7acaed9f78ea0bc0dc60e67c4bd1 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 5 Dec 2025 20:49:06 -0500 Subject: [PATCH 0395/3801] ci: Simplify untar path list output Currently the benchmark CI jobs prints multiple pages of paths from the extracted archive, since `tar` is run with `v`. This is a lot of output that is usually just noise in CI. Switch to printing the paths from python instead, limiting to a depth of three segments (and deduplicating). Removing it completely was an option, but it's still nice to have a hint about what gets updated. --- library/compiler-builtins/ci/ci-util.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/library/compiler-builtins/ci/ci-util.py b/library/compiler-builtins/ci/ci-util.py index 113820b70215..ef9ce455178e 100755 --- a/library/compiler-builtins/ci/ci-util.py +++ b/library/compiler-builtins/ci/ci-util.py @@ -390,6 +390,7 @@ def locate_baseline(flags: list[str]) -> None: artifact_glob = f"{ARTIFACT_PREFIX}{f"-{tag}" if tag else ""}*" + # Skip checking because this will fail if the file already exists, which is fine. sp.run( ["gh", "run", "download", str(job_id), f"--pattern={artifact_glob}"], check=False, @@ -409,7 +410,17 @@ def locate_baseline(flags: list[str]) -> None: candidate_baselines.sort(reverse=True) baseline_archive = candidate_baselines[0] eprint(f"extracting {baseline_archive}") - sp.run(["tar", "xJvf", baseline_archive], check=True) + + all_paths = sp.check_output(["tar", "tJf", baseline_archive], encoding="utf8") + sp.run(["tar", "xJf", baseline_archive], check=True) + + # Print a short summary of paths, we don't use `tar v` since the list is huge + short_paths = re.findall(r"^(?:[^/\n]+/?){1,3}", all_paths, re.MULTILINE) + + print("Extracted:") + for path in sorted(set(short_paths)): + print(f"* {path}") + eprint("baseline extracted successfully") From 01735687d8b050402f7920e19dcfb8e0b9890288 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 7 Dec 2025 18:30:49 +0000 Subject: [PATCH 0396/3801] ci: Update the default branch name in remaining workflow files Missed as part of 936db7f5e890 ("ci: Update the default branch name"). --- library/compiler-builtins/.github/workflows/publish.yaml | 2 +- library/compiler-builtins/.github/workflows/rustc-pull.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/compiler-builtins/.github/workflows/publish.yaml b/library/compiler-builtins/.github/workflows/publish.yaml index 85a33c039d2a..d6f1dc398e8e 100644 --- a/library/compiler-builtins/.github/workflows/publish.yaml +++ b/library/compiler-builtins/.github/workflows/publish.yaml @@ -5,7 +5,7 @@ permissions: contents: write on: - push: { branches: [master] } + push: { branches: [main] } jobs: release-plz: diff --git a/library/compiler-builtins/.github/workflows/rustc-pull.yml b/library/compiler-builtins/.github/workflows/rustc-pull.yml index ad7693e17b0e..617db14f46ee 100644 --- a/library/compiler-builtins/.github/workflows/rustc-pull.yml +++ b/library/compiler-builtins/.github/workflows/rustc-pull.yml @@ -17,7 +17,7 @@ jobs: zulip-stream-id: 219381 zulip-topic: 'compiler-builtins subtree sync automation' zulip-bot-email: "compiler-builtins-ci-bot@rust-lang.zulipchat.com" - pr-base-branch: master + pr-base-branch: main branch-name: rustc-pull secrets: zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }} From 19b809e8bca6e0f43526116f0ffd3361955622db Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 7 Dec 2025 14:27:50 -0500 Subject: [PATCH 0397/3801] ci: Print CPU information for benchmarks Make it easier to explain possible changes to results on CI. --- library/compiler-builtins/ci/bench-icount.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/compiler-builtins/ci/bench-icount.sh b/library/compiler-builtins/ci/bench-icount.sh index 1d7d23dcce45..6d92b50a6dae 100755 --- a/library/compiler-builtins/ci/bench-icount.sh +++ b/library/compiler-builtins/ci/bench-icount.sh @@ -10,6 +10,10 @@ if [ -z "$target" ]; then target="$host_target" fi +# Print machine information +uname -a +lscpu || true + gungraun_home="gungraun-home" # Use the arch as a tag to disambiguate artifacts From d6139b1347cccd60643257e8f52c9ed6a5e0ff9f Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 7 Dec 2025 14:31:02 -0500 Subject: [PATCH 0398/3801] ci: Switch the x86 Apple job to the `macos-15-intel` runner `macos-13` is being phased out. Now that GitHub has x86 runners with MacOS 15, switch those. --- library/compiler-builtins/.github/workflows/main.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 0ab32d698b2c..38995cf0f0ff 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -89,7 +89,7 @@ jobs: - target: x86_64-unknown-linux-gnu os: ubuntu-24.04 - target: x86_64-apple-darwin - os: macos-13 + os: macos-15-intel - target: i686-pc-windows-msvc os: windows-2025 - target: x86_64-pc-windows-msvc From bb549da8f6e050f7cf206488265d300370f5cd7e Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Sun, 7 Dec 2025 16:51:27 -0500 Subject: [PATCH 0399/3801] test: update duplicate many_digits test to use f64 instead of f32 Replace the f32 test case with an f64 equivalent to improve coverage for parsing large digit counts in double-precision floating-point conversion. --- library/coretests/tests/num/dec2flt/parse.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/coretests/tests/num/dec2flt/parse.rs b/library/coretests/tests/num/dec2flt/parse.rs index dccb6b5528d4..65f1289d531b 100644 --- a/library/coretests/tests/num/dec2flt/parse.rs +++ b/library/coretests/tests/num/dec2flt/parse.rs @@ -204,8 +204,8 @@ fn many_digits() { "1.175494140627517859246175898662808184331245864732796240031385942718174675986064769972472277004271745681762695312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-38" ); assert_float_result_bits_eq!( - 0x7ffffe, - f32, - "1.175494140627517859246175898662808184331245864732796240031385942718174675986064769972472277004271745681762695312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-38" + 0x7ffffffffffffe, + f64, + "2.8480945388892171379514712013899006561925415836684281158317117472799232118121416898288331376688117187382156519616555919469923055562697333532151065976805407006156569379201589813489881051279092585294136284133893120582268661680741374638184352784785121471797815387841323043061183721896440504100014432145713413240639315126126485370149254502658324386101932795656342787961697168715161403422599767855490566539165801964388919848888980308652852766053138934233069066651644954964960514065582826296567812754916294792554028205611526494813491373571799099361175786448799007387647056059512705071170383000860694587462575533337769237800154235626508997957207085308694919708914563870082480025309479610576861709891209343110514894825624524442569257542956506767950486391782760620117187500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-306" ); } From 22a7457d12d7eb268e3d8b0ba50f6cd7153af9b4 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Fri, 5 Dec 2025 19:50:20 +0900 Subject: [PATCH 0400/3801] Cleaned up some tests Merged tests/ui/typeck/non-function-call-error-2 with tests/ui/typeck/non-function-call-error Add comment to tests/ui/traits/normalize-associated-type-in-where-clause.rs Merged tests/ui/privacy/private-item-simple-2.rs with tests/ui/privacy/private-item-simple.rs Merged tests/ui/str/str-add-operator-2.rs with tests/ui/str/str-add-operator.rs Add comment to tests/ui/imports/duplicate-empty-imports.rs Add comment to tests/ui/for-loop-while/nested-loop-break-unit.rs Add comment to tests/ui/match/match-ref-option-pattern.rs Add comment to tests/ui/closures/simple-capture-and-call.rs Add comment to tests/ui/type/never-type-inference-fail.rs Add comment to tests/ui/match/match-stack-overflow-72933.rs --- tests/ui/closures/simple-capture-and-call.rs | 9 +++---- .../for-loop-while/nested-loop-break-unit.rs | 1 + tests/ui/imports/duplicate-empty-imports.rs | 1 + tests/ui/match/match-ref-option-pattern.rs | 1 + tests/ui/match/match-stack-overflow-72933-.rs | 3 ++- tests/ui/privacy/private-item-simple-2.rs | 10 -------- tests/ui/privacy/private-item-simple-2.stderr | 15 ------------ tests/ui/privacy/private-item-simple.rs | 6 +++++ tests/ui/privacy/private-item-simple.stderr | 18 +++++++++++--- tests/ui/str/str-add-operator-2.rs | 5 ---- tests/ui/str/str-add-operator-2.stderr | 18 -------------- tests/ui/str/str-add-operator.rs | 1 + tests/ui/str/str-add-operator.stderr | 2 +- ...rmalize-associated-type-in-where-clause.rs | 18 +++++++------- tests/ui/type/never-type-inference-fail.rs | 2 ++ .../ui/type/never-type-inference-fail.stderr | 2 +- tests/ui/typeck/non-function-call-error-2.rs | 7 ------ .../typeck/non-function-call-error-2.stderr | 23 ------------------ tests/ui/typeck/non-function-call-error.rs | 10 ++++++++ .../ui/typeck/non-function-call-error.stderr | 24 +++++++++++++++++-- 20 files changed, 77 insertions(+), 99 deletions(-) delete mode 100644 tests/ui/privacy/private-item-simple-2.rs delete mode 100644 tests/ui/privacy/private-item-simple-2.stderr delete mode 100644 tests/ui/str/str-add-operator-2.rs delete mode 100644 tests/ui/str/str-add-operator-2.stderr delete mode 100644 tests/ui/typeck/non-function-call-error-2.rs delete mode 100644 tests/ui/typeck/non-function-call-error-2.stderr diff --git a/tests/ui/closures/simple-capture-and-call.rs b/tests/ui/closures/simple-capture-and-call.rs index 39d657573db7..112324eb7204 100644 --- a/tests/ui/closures/simple-capture-and-call.rs +++ b/tests/ui/closures/simple-capture-and-call.rs @@ -1,7 +1,8 @@ +//! regression test for issue #1895 //@ run-pass -pub fn main() { - let x = 1_usize; - let y = || x; - let _z = y(); +fn main() { + let x = 1_usize; + let y = || x; + let _z = y(); } diff --git a/tests/ui/for-loop-while/nested-loop-break-unit.rs b/tests/ui/for-loop-while/nested-loop-break-unit.rs index ad5721495090..b31d9ee8f50d 100644 --- a/tests/ui/for-loop-while/nested-loop-break-unit.rs +++ b/tests/ui/for-loop-while/nested-loop-break-unit.rs @@ -1,3 +1,4 @@ +//! regression test for issue #2642 //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/imports/duplicate-empty-imports.rs b/tests/ui/imports/duplicate-empty-imports.rs index d395ac677e75..7768dcfbbdac 100644 --- a/tests/ui/imports/duplicate-empty-imports.rs +++ b/tests/ui/imports/duplicate-empty-imports.rs @@ -1,3 +1,4 @@ +//! regression test for issue #47673 //@ check-pass #![allow(unused_imports)] diff --git a/tests/ui/match/match-ref-option-pattern.rs b/tests/ui/match/match-ref-option-pattern.rs index 0860d0f59260..a6de2361503a 100644 --- a/tests/ui/match/match-ref-option-pattern.rs +++ b/tests/ui/match/match-ref-option-pattern.rs @@ -1,3 +1,4 @@ +//! regression test for issue #3500 //@ run-pass pub fn main() { diff --git a/tests/ui/match/match-stack-overflow-72933-.rs b/tests/ui/match/match-stack-overflow-72933-.rs index 6d091a910819..0883278be839 100644 --- a/tests/ui/match/match-stack-overflow-72933-.rs +++ b/tests/ui/match/match-stack-overflow-72933-.rs @@ -1,6 +1,7 @@ +//! regression test for issue #72933 //@ build-pass // ignore-tidy-filelength -#![crate_type="rlib"] +#![crate_type = "rlib"] fn banana(v: &str) -> u32 { match v { diff --git a/tests/ui/privacy/private-item-simple-2.rs b/tests/ui/privacy/private-item-simple-2.rs deleted file mode 100644 index 9dea54ea779e..000000000000 --- a/tests/ui/privacy/private-item-simple-2.rs +++ /dev/null @@ -1,10 +0,0 @@ -use zoo::fly; //~ ERROR: function `fly` is private - -mod zoo { - fn fly() {} -} - - -fn main() { - fly(); -} diff --git a/tests/ui/privacy/private-item-simple-2.stderr b/tests/ui/privacy/private-item-simple-2.stderr deleted file mode 100644 index cf839a131406..000000000000 --- a/tests/ui/privacy/private-item-simple-2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0603]: function `fly` is private - --> $DIR/issue-3993.rs:1:10 - | -LL | use zoo::fly; - | ^^^ private function - | -note: the function `fly` is defined here - --> $DIR/issue-3993.rs:4:5 - | -LL | fn fly() {} - | ^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/privacy/private-item-simple.rs b/tests/ui/privacy/private-item-simple.rs index 1f718ed9201a..68b20991a626 100644 --- a/tests/ui/privacy/private-item-simple.rs +++ b/tests/ui/privacy/private-item-simple.rs @@ -1,3 +1,5 @@ +//! regression test for issue #3993 + mod a { fn f() {} } @@ -5,3 +7,7 @@ mod a { fn main() { a::f(); //~ ERROR function `f` is private } + +fn foo() { + use a::f; //~ ERROR function `f` is private +} diff --git a/tests/ui/privacy/private-item-simple.stderr b/tests/ui/privacy/private-item-simple.stderr index 330d892e939d..95165857940e 100644 --- a/tests/ui/privacy/private-item-simple.stderr +++ b/tests/ui/privacy/private-item-simple.stderr @@ -1,15 +1,27 @@ error[E0603]: function `f` is private - --> $DIR/private-item-simple.rs:6:8 + --> $DIR/private-item-simple.rs:12:12 + | +LL | use a::f; + | ^ private function + | +note: the function `f` is defined here + --> $DIR/private-item-simple.rs:4:5 + | +LL | fn f() {} + | ^^^^^^ + +error[E0603]: function `f` is private + --> $DIR/private-item-simple.rs:8:8 | LL | a::f(); | ^ private function | note: the function `f` is defined here - --> $DIR/private-item-simple.rs:2:5 + --> $DIR/private-item-simple.rs:4:5 | LL | fn f() {} | ^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/str/str-add-operator-2.rs b/tests/ui/str/str-add-operator-2.rs deleted file mode 100644 index 61e096622252..000000000000 --- a/tests/ui/str/str-add-operator-2.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let b = "hello"; - println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; - //~^ ERROR E0369 -} diff --git a/tests/ui/str/str-add-operator-2.stderr b/tests/ui/str/str-add-operator-2.stderr deleted file mode 100644 index 4fca0296e437..000000000000 --- a/tests/ui/str/str-add-operator-2.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0369]: cannot add `&str` to `&str` - --> $DIR/issue-47380.rs:3:35 - | -LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; - | - ^ ---------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str - | - = note: string concatenation requires an owned `String` on the left -help: create an owned `String` from a string reference - | -LL | println!("🦀🦀🦀🦀🦀"); let _a = b.to_owned() + ", World!"; - | +++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/str/str-add-operator.rs b/tests/ui/str/str-add-operator.rs index 7a2e0fe6d21d..9c489f2091f8 100644 --- a/tests/ui/str/str-add-operator.rs +++ b/tests/ui/str/str-add-operator.rs @@ -1,3 +1,4 @@ +//! regression test for issue #47377, #47380 // ignore-tidy-tab fn main() { let b = "hello"; diff --git a/tests/ui/str/str-add-operator.stderr b/tests/ui/str/str-add-operator.stderr index 12e5c15d77fc..2354819d7fa1 100644 --- a/tests/ui/str/str-add-operator.stderr +++ b/tests/ui/str/str-add-operator.stderr @@ -1,5 +1,5 @@ error[E0369]: cannot add `&str` to `&str` - --> $DIR/issue-47377.rs:4:14 + --> $DIR/str-add-operator.rs:5:14 | LL | let _a = b + ", World!"; | - ^ ---------- &str diff --git a/tests/ui/traits/normalize-associated-type-in-where-clause.rs b/tests/ui/traits/normalize-associated-type-in-where-clause.rs index d7761b50b4c4..25ca4a41aa85 100644 --- a/tests/ui/traits/normalize-associated-type-in-where-clause.rs +++ b/tests/ui/traits/normalize-associated-type-in-where-clause.rs @@ -1,30 +1,30 @@ //@ run-pass -// regression test for issue #50825 -// Check that the feature gate normalizes associated types. +//! regression test for issue #50825, #51044 +//! Check that the feature gate normalizes associated types. #![allow(dead_code)] struct Foo(T); struct Duck; struct Quack; -trait Hello where A: Animal { +trait Hello +where + A: Animal, +{ } trait Animal { type Noise; } -trait Loud { -} +trait Loud {} -impl Loud for f32 { -} +impl Loud for f32 {} impl Animal for Duck { type Noise = Quack; } -impl Hello for Foo where f32: Loud<::Noise> { -} +impl Hello for Foo where f32: Loud<::Noise> {} fn main() {} diff --git a/tests/ui/type/never-type-inference-fail.rs b/tests/ui/type/never-type-inference-fail.rs index 82cf49de8227..76ee3c5f5d56 100644 --- a/tests/ui/type/never-type-inference-fail.rs +++ b/tests/ui/type/never-type-inference-fail.rs @@ -1,3 +1,5 @@ +//! regression test for issue #2151 + fn main() { let x = panic!(); //~ ERROR type annotations needed x.clone(); diff --git a/tests/ui/type/never-type-inference-fail.stderr b/tests/ui/type/never-type-inference-fail.stderr index b130f162414d..1d2457103f1c 100644 --- a/tests/ui/type/never-type-inference-fail.stderr +++ b/tests/ui/type/never-type-inference-fail.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/issue-2151.rs:2:9 + --> $DIR/never-type-inference-fail.rs:4:9 | LL | let x = panic!(); | ^ diff --git a/tests/ui/typeck/non-function-call-error-2.rs b/tests/ui/typeck/non-function-call-error-2.rs deleted file mode 100644 index 0b78fc1bb7fa..000000000000 --- a/tests/ui/typeck/non-function-call-error-2.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn func(i: i32) { - i(); //~ERROR expected function, found `i32` -} -fn main() { - let i = 0i32; - i(); //~ERROR expected function, found `i32` -} diff --git a/tests/ui/typeck/non-function-call-error-2.stderr b/tests/ui/typeck/non-function-call-error-2.stderr deleted file mode 100644 index f64b61aaeb05..000000000000 --- a/tests/ui/typeck/non-function-call-error-2.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0618]: expected function, found `i32` - --> $DIR/issue-10969.rs:2:5 - | -LL | fn func(i: i32) { - | - `i` has type `i32` -LL | i(); - | ^-- - | | - | call expression requires function - -error[E0618]: expected function, found `i32` - --> $DIR/issue-10969.rs:6:5 - | -LL | let i = 0i32; - | - `i` has type `i32` -LL | i(); - | ^-- - | | - | call expression requires function - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/typeck/non-function-call-error.rs b/tests/ui/typeck/non-function-call-error.rs index 197a19c038c4..c61cf93d138a 100644 --- a/tests/ui/typeck/non-function-call-error.rs +++ b/tests/ui/typeck/non-function-call-error.rs @@ -1,9 +1,19 @@ +//! Regression test for issue #10969, #22468 + fn main() { let foo = "bar"; let x = foo("baz"); //~^ ERROR: expected function, found `&str` + + let i = 0i32; + i(); + //~^ ERROR expected function, found `i32` } fn foo(file: &str) -> bool { true } + +fn func(i: i32) { + i(); //~ERROR expected function, found `i32` +} diff --git a/tests/ui/typeck/non-function-call-error.stderr b/tests/ui/typeck/non-function-call-error.stderr index 052888d2029b..f4797ac3d8b7 100644 --- a/tests/ui/typeck/non-function-call-error.stderr +++ b/tests/ui/typeck/non-function-call-error.stderr @@ -1,5 +1,5 @@ error[E0618]: expected function, found `&str` - --> $DIR/issue-22468.rs:3:13 + --> $DIR/non-function-call-error.rs:5:13 | LL | let foo = "bar"; | --- `foo` has type `&str` @@ -11,6 +11,26 @@ LL | let x = foo("baz"); LL | fn foo(file: &str) -> bool { | -------------------------- this function of the same name is available here, but it's shadowed by the local binding -error: aborting due to 1 previous error +error[E0618]: expected function, found `i32` + --> $DIR/non-function-call-error.rs:9:5 + | +LL | let i = 0i32; + | - `i` has type `i32` +LL | i(); + | ^-- + | | + | call expression requires function + +error[E0618]: expected function, found `i32` + --> $DIR/non-function-call-error.rs:18:5 + | +LL | fn func(i: i32) { + | - `i` has type `i32` +LL | i(); + | ^-- + | | + | call expression requires function + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0618`. From aec8ce4693a3bfca7ec09cd94386689b730743f8 Mon Sep 17 00:00:00 2001 From: benodiwal Date: Mon, 8 Dec 2025 04:41:05 +0530 Subject: [PATCH 0401/3801] fix: fixed Impl display to show trait generic args --- .../rust-analyzer/crates/hir/src/display.rs | 7 ++- .../crates/ide/src/hover/tests.rs | 57 +++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index 07e61a83c440..afdac484a117 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir/src/display.rs @@ -192,9 +192,10 @@ fn write_impl_header<'db>(impl_: &Impl, f: &mut HirFormatter<'_, 'db>) -> Result let def_id = GenericDefId::ImplId(impl_.id); write_generic_params(def_id, f)?; - if let Some(trait_) = impl_.trait_(db) { - let trait_data = db.trait_signature(trait_.id); - write!(f, " {} for", trait_data.name.display(db, f.edition()))?; + if let Some(trait_ref) = impl_.trait_ref(db) { + f.write_char(' ')?; + trait_ref.hir_fmt(f)?; + f.write_str(" for")?; } f.write_char(' ')?; diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index 071eacf6604c..5330b7eb9941 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -11169,3 +11169,60 @@ fn foo() { "#]], ); } + +#[test] +fn hover_trait_impl_shows_generic_args() { + // Single generic arg + check( + r#" +trait Foo { + fn foo(&self) {} +} + +impl Foo<()> for T { + fn fo$0o(&self) {} +} + +fn bar() { + ().foo(); +} +"#, + expect![[r#" + *foo* + + ```rust + ra_test_fixture + ``` + + ```rust + impl Foo<()> for T + fn foo(&self) + ``` + "#]], + ); + + // Multiple generic args + check( + r#" +trait Foo { + fn foo(&self) {} +} + +impl Foo for T { + fn fo$0o(&self) {} +} +"#, + expect![[r#" + *foo* + + ```rust + ra_test_fixture + ``` + + ```rust + impl Foo for T + fn foo(&self) + ``` + "#]], + ); +} From f8bbf2ca0685b3d14795823bfff50ac2a0332d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 27 Nov 2025 12:21:35 +0100 Subject: [PATCH 0402/3801] split out blob decode trait --- compiler/rustc_hir/src/definitions.rs | 8 +- compiler/rustc_hir/src/lang_items.rs | 4 +- compiler/rustc_hir/src/stability.rs | 10 +- compiler/rustc_hir/src/version.rs | 4 +- compiler/rustc_macros/src/lib.rs | 13 +- compiler/rustc_macros/src/serialize.rs | 17 +- compiler/rustc_metadata/src/locator.rs | 1 + compiler/rustc_metadata/src/rmeta/decoder.rs | 296 ++++++++++++------ .../src/rmeta/decoder/cstore_impl.rs | 11 +- .../src/rmeta/def_path_hash_map.rs | 7 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_metadata/src/rmeta/mod.rs | 11 +- compiler/rustc_metadata/src/rmeta/table.rs | 7 +- compiler/rustc_middle/src/middle/mod.rs | 4 +- .../rustc_middle/src/query/on_disk_cache.rs | 54 ++-- compiler/rustc_middle/src/ty/mod.rs | 6 +- compiler/rustc_session/src/config.rs | 6 +- compiler/rustc_session/src/cstore.rs | 6 +- compiler/rustc_session/src/options.rs | 8 +- compiler/rustc_span/src/def_id.rs | 4 +- compiler/rustc_span/src/edition.rs | 4 +- compiler/rustc_span/src/lib.rs | 45 +-- compiler/rustc_target/src/spec/mod.rs | 6 +- 23 files changed, 331 insertions(+), 203 deletions(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 07d5bcdd6ee9..01f84c90ec7a 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -11,7 +11,7 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::unord::UnordMap; use rustc_hashes::Hash64; use rustc_index::IndexVec; -use rustc_macros::{Decodable, Encodable}; +use rustc_macros::{BlobDecodable, Decodable, Encodable}; use rustc_span::{Symbol, kw, sym}; use tracing::{debug, instrument}; @@ -127,7 +127,7 @@ pub struct Definitions { /// A unique identifier that we can use to lookup a definition /// precisely. It combines the index of the definition's parent (if /// any) with a `DisambiguatedDefPathData`. -#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable)] +#[derive(Copy, Clone, PartialEq, Debug, Encodable, BlobDecodable)] pub struct DefKey { /// The parent path. pub parent: Option, @@ -176,7 +176,7 @@ impl DefKey { /// between them. This introduces some artificial ordering dependency /// but means that if you have, e.g., two impls for the same type in /// the same module, they do get distinct `DefId`s. -#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable)] +#[derive(Copy, Clone, PartialEq, Debug, Encodable, BlobDecodable)] pub struct DisambiguatedDefPathData { pub data: DefPathData, pub disambiguator: u32, @@ -270,7 +270,7 @@ impl DefPath { } /// New variants should only be added in synchronization with `enum DefKind`. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, BlobDecodable)] pub enum DefPathData { // Root: these should only be used for the root nodes, because // they are treated specially by the `def_path` function. diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 51e798d1e83b..4ac3e4e83e80 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -10,7 +10,7 @@ use rustc_ast::attr::AttributeExt; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +use rustc_macros::{BlobDecodable, Encodable, HashStable_Generic}; use rustc_span::{Span, Symbol, kw, sym}; use crate::def_id::DefId; @@ -75,7 +75,7 @@ macro_rules! language_item_table { $( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )* ) => { /// A representation of all the valid lang items in Rust. - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, BlobDecodable)] pub enum LangItem { $( #[doc = concat!("The `", stringify!($name), "` lang item.")] diff --git a/compiler/rustc_hir/src/stability.rs b/compiler/rustc_hir/src/stability.rs index 2b3a2a793163..9297f8e6cdcd 100644 --- a/compiler/rustc_hir/src/stability.rs +++ b/compiler/rustc_hir/src/stability.rs @@ -1,6 +1,6 @@ use std::num::NonZero; -use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute}; +use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic, PrintAttribute}; use rustc_span::{ErrorGuaranteed, Symbol, sym}; use crate::RustcVersion; @@ -21,7 +21,7 @@ pub const VERSION_PLACEHOLDER: &str = concat!("CURRENT_RUSTC_VERSIO", "N"); /// /// - `#[stable]` /// - `#[unstable]` -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Encodable, BlobDecodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(HashStable_Generic, PrintAttribute)] pub struct Stability { pub level: StabilityLevel, @@ -103,7 +103,7 @@ impl PartialConstStability { } /// The available stability levels. -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] +#[derive(Encodable, BlobDecodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(HashStable_Generic, PrintAttribute)] pub enum StabilityLevel { /// `#[unstable]` @@ -146,7 +146,7 @@ pub enum StabilityLevel { } /// Rust release in which a feature is stabilized. -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)] +#[derive(Encodable, BlobDecodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)] #[derive(HashStable_Generic, PrintAttribute)] pub enum StableSince { /// also stores the original symbol for printing @@ -172,7 +172,7 @@ impl StabilityLevel { } } -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] +#[derive(Encodable, BlobDecodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(HashStable_Generic, PrintAttribute)] pub enum UnstableReason { None, diff --git a/compiler/rustc_hir/src/version.rs b/compiler/rustc_hir/src/version.rs index bc2c38a49350..03182088d4c0 100644 --- a/compiler/rustc_hir/src/version.rs +++ b/compiler/rustc_hir/src/version.rs @@ -4,12 +4,12 @@ use std::sync::OnceLock; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::{ - Decodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version, + BlobDecodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version, }; use crate::attrs::PrintAttribute; -#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Encodable, BlobDecodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(HashStable_Generic, PrintAttribute)] pub struct RustcVersion { pub major: u16, diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index a6f53d92e100..9f55143ecf53 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -78,7 +78,18 @@ decl_derive!([Decodable] => serialize::decodable_derive); decl_derive!([Encodable] => serialize::encodable_derive); decl_derive!([TyDecodable] => serialize::type_decodable_derive); decl_derive!([TyEncodable] => serialize::type_encodable_derive); -decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive); +decl_derive!([MetadataDecodable] => + /// This constrains the decoder to be specifically the decoder that can decode LazyArrays in metadata. + /// Therefore, we only use this on things containing LazyArray really. + /// Anything else should either be `NoContext`, if possible `BlobDecodable`, or otherwise just `Decodable`. + serialize::meta_decodable_derive +); +decl_derive!([BlobDecodable] => + /// For anything that is "simple" to decode, without needing anything but the original data, + /// but for which the Decoder can customize some things + /// (unlike Decodable_NoContext which individual decoders can't customize). + serialize::blob_decodable_derive +); decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive); decl_derive!( [TypeFoldable, attributes(type_foldable)] => diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index c7aaaf0da467..abf566288df4 100644 --- a/compiler/rustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs @@ -16,14 +16,21 @@ pub(super) fn type_decodable_derive( decodable_body(s, decoder_ty) } +pub(super) fn blob_decodable_derive( + mut s: synstructure::Structure<'_>, +) -> proc_macro2::TokenStream { + let decoder_ty = quote! { __D }; + s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_span::BlobDecoder }); + s.add_bounds(synstructure::AddBounds::Generics); + + decodable_body(s, decoder_ty) +} + pub(super) fn meta_decodable_derive( mut s: synstructure::Structure<'_>, ) -> proc_macro2::TokenStream { - if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { - s.add_impl_generic(parse_quote! { 'tcx }); - } - s.add_impl_generic(parse_quote! { '__a }); - let decoder_ty = quote! { DecodeContext<'__a, 'tcx> }; + let decoder_ty = quote! { __D }; + s.add_impl_generic(parse_quote! { #decoder_ty: LazyDecoder }); s.add_bounds(synstructure::AddBounds::Generics); decodable_body(s, decoder_ty) diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 9fef22f9558d..6a441706a22b 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -224,6 +224,7 @@ use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned}; use rustc_data_structures::svh::Svh; use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_fs_util::try_canonicalize; +use rustc_middle::ty::TyCtxt; use rustc_session::cstore::CrateSource; use rustc_session::filesearch::FileSearch; use rustc_session::search_paths::PathKind; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 25e7574d3b37..b1cac381e05b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1,6 +1,7 @@ // Decoding metadata from a single crate's metadata use std::iter::TrustedLen; +use std::ops::{Deref, DerefMut}; use std::path::{Path, PathBuf}; use std::sync::{Arc, OnceLock}; use std::{io, mem}; @@ -33,7 +34,8 @@ use rustc_session::config::TargetModifier; use rustc_session::cstore::{CrateSource, ExternCrate}; use rustc_span::hygiene::HygieneDecodeContext; use rustc_span::{ - BytePos, ByteSymbol, DUMMY_SP, Pos, SpanData, SpanDecoder, Symbol, SyntaxContext, kw, + BlobDecoder, BytePos, ByteSymbol, DUMMY_SP, Pos, SpanData, SpanDecoder, Symbol, SyntaxContext, + kw, }; use tracing::debug; @@ -154,22 +156,106 @@ struct ImportedSourceFile { translated_source_file: Arc, } -pub(super) struct DecodeContext<'a, 'tcx> { +/// Decode context used when we just have a blob, +/// and we still have to read the header etc. +pub(super) struct BlobDecodeContext<'a> { opaque: MemDecoder<'a>, - cdata: Option>, blob: &'a MetadataBlob, + lazy_state: LazyState, +} + +/// trait for anything containing `LazyState` and is a decoder. +// TODO: might need to live in rustc_middle +pub(super) trait LazyDecoder: BlobDecoder { + fn set_lazy_state(&mut self, state: LazyState); + fn get_lazy_state(&self) -> LazyState; + + fn read_lazy(&mut self) -> LazyValue { + self.read_lazy_offset_then(|pos| LazyValue::from_position(pos)) + } + + fn read_lazy_array(&mut self, len: usize) -> LazyArray { + self.read_lazy_offset_then(|pos| LazyArray::from_position_and_num_elems(pos, len)) + } + + fn read_lazy_table(&mut self, width: usize, len: usize) -> LazyTable { + self.read_lazy_offset_then(|pos| LazyTable::from_position_and_encoded_size(pos, width, len)) + } + + #[inline] + fn read_lazy_offset_then(&mut self, f: impl Fn(NonZero) -> T) -> T { + let distance = self.read_usize(); + let position = match self.get_lazy_state() { + LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"), + LazyState::NodeStart(start) => { + let start = start.get(); + assert!(distance <= start); + start - distance + } + LazyState::Previous(last_pos) => last_pos.get() + distance, + }; + let position = NonZero::new(position).unwrap(); + self.set_lazy_state(LazyState::Previous(position)); + f(position) + } +} + +impl<'a> LazyDecoder for BlobDecodeContext<'a> { + fn set_lazy_state(&mut self, state: LazyState) { + self.lazy_state = state; + } + + fn get_lazy_state(&self) -> LazyState { + self.lazy_state + } +} + +/// This is the decode context used when crate metadata was already read. +/// Decoding of some types, like `Span` require some information to already been read. +pub(super) struct MetadataDecodeContext<'a, 'tcx> { + blob_decoder: BlobDecodeContext<'a>, + cdata: Option>, sess: Option<&'tcx Session>, tcx: Option>, - lazy_state: LazyState, - // Used for decoding interpret::AllocIds in a cached & thread-safe manner. alloc_decoding_session: Option>, } +impl<'a, 'tcx> LazyDecoder for MetadataDecodeContext<'a, 'tcx> { + fn set_lazy_state(&mut self, state: LazyState) { + self.lazy_state = state; + } + + fn get_lazy_state(&self) -> LazyState { + self.lazy_state + } +} + +impl<'a, 'tcx> DerefMut for MetadataDecodeContext<'a, 'tcx> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.blob_decoder + } +} + +impl<'a, 'tcx> Deref for MetadataDecodeContext<'a, 'tcx> { + type Target = BlobDecodeContext<'a>; + + fn deref(&self) -> &Self::Target { + &self.blob_decoder + } +} + +pub(super) trait BlobMetadata<'a, 'tcx>: Copy { + type Context: BlobDecoder + LazyDecoder; + + fn blob(self) -> &'a MetadataBlob; + fn decoder(self, pos: usize) -> Self::Context; +} + /// Abstract over the various ways one can create metadata decoders. pub(super) trait Metadata<'a, 'tcx>: Copy { - fn blob(self) -> &'a MetadataBlob; + fn _blob(self) -> &'a MetadataBlob; fn cdata(self) -> Option> { None @@ -180,23 +266,25 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { fn tcx(self) -> Option> { None } +} - fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> { +impl<'a, 'tcx, T> BlobMetadata<'a, 'tcx> for T +where + T: Metadata<'a, 'tcx>, +{ + type Context = MetadataDecodeContext<'a, 'tcx>; + + fn blob(self) -> &'a MetadataBlob { + self._blob() + } + + fn decoder(self, pos: usize) -> MetadataDecodeContext<'a, 'tcx> { let tcx = self.tcx(); - DecodeContext { - // FIXME: This unwrap should never panic because we check that it won't when creating - // `MetadataBlob`. Ideally we'd just have a `MetadataDecoder` and hand out subslices of - // it as we do elsewhere in the compiler using `MetadataDecoder::split_at`. But we own - // the data for the decoder so holding onto the `MemDecoder` too would make us a - // self-referential struct which is downright goofy because `MetadataBlob` is already - // self-referential. Probably `MemDecoder` should contain an `OwnedSlice`, but that - // demands a significant refactoring due to our crate graph. - opaque: MemDecoder::new(self.blob(), pos).unwrap(), + MetadataDecodeContext { + blob_decoder: self.blob().decoder(pos), cdata: self.cdata(), - blob: self.blob(), sess: self.sess().or(tcx.map(|tcx| tcx.sess)), tcx, - lazy_state: LazyState::NoNode, alloc_decoding_session: self .cdata() .map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()), @@ -204,16 +292,32 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { } } -impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob { - #[inline] +impl<'a, 'tcx> BlobMetadata<'a, 'tcx> for &'a MetadataBlob { + type Context = BlobDecodeContext<'a>; + fn blob(self) -> &'a MetadataBlob { self } + + fn decoder(self, pos: usize) -> Self::Context { + BlobDecodeContext { + // FIXME: This unwrap should never panic because we check that it won't when creating + // `MetadataBlob`. Ideally we'd just have a `MetadataDecoder` and hand out subslices of + // it as we do elsewhere in the compiler using `MetadataDecoder::split_at`. But we own + // the data for the decoder so holding onto the `MemDecoder` too would make us a + // self-referential struct which is downright goofy because `MetadataBlob` is already + // self-referential. Probably `MemDecoder` should contain an `OwnedSlice`, but that + // demands a significant refactoring due to our crate graph. + opaque: MemDecoder::new(self, pos).unwrap(), + lazy_state: LazyState::NoNode, + blob: self.blob(), + } + } } impl<'a, 'tcx> Metadata<'a, 'tcx> for CrateMetadataRef<'a> { #[inline] - fn blob(self) -> &'a MetadataBlob { + fn _blob(self) -> &'a MetadataBlob { &self.cdata.blob } #[inline] @@ -224,7 +328,7 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for CrateMetadataRef<'a> { impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, &'tcx Session) { #[inline] - fn blob(self) -> &'a MetadataBlob { + fn _blob(self) -> &'a MetadataBlob { &self.0.cdata.blob } #[inline] @@ -239,7 +343,7 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, &'tcx Session) { impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) { #[inline] - fn blob(self) -> &'a MetadataBlob { + fn _blob(self) -> &'a MetadataBlob { &self.0.cdata.blob } #[inline] @@ -254,23 +358,23 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) { impl LazyValue { #[inline] - fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(self, metadata: M) -> T::Value<'tcx> + fn decode<'a, 'tcx, M: BlobMetadata<'a, 'tcx>>(self, metadata: M) -> T::Value<'tcx> where - T::Value<'tcx>: Decodable>, + T::Value<'tcx>: Decodable, { let mut dcx = metadata.decoder(self.position.get()); - dcx.lazy_state = LazyState::NodeStart(self.position); + dcx.set_lazy_state(LazyState::NodeStart(self.position)); T::Value::decode(&mut dcx) } } -struct DecodeIterator<'a, 'tcx, T> { +struct DecodeIterator { elem_counter: std::ops::Range, - dcx: DecodeContext<'a, 'tcx>, + dcx: D, _phantom: PhantomData T>, } -impl<'a, 'tcx, T: Decodable>> Iterator for DecodeIterator<'a, 'tcx, T> { +impl> Iterator for DecodeIterator { type Item = T; #[inline(always)] @@ -284,35 +388,30 @@ impl<'a, 'tcx, T: Decodable>> Iterator for DecodeIterato } } -impl<'a, 'tcx, T: Decodable>> ExactSizeIterator - for DecodeIterator<'a, 'tcx, T> -{ +impl> ExactSizeIterator for DecodeIterator { fn len(&self) -> usize { self.elem_counter.len() } } -unsafe impl<'a, 'tcx, T: Decodable>> TrustedLen - for DecodeIterator<'a, 'tcx, T> -{ -} +unsafe impl> TrustedLen for DecodeIterator {} impl LazyArray { #[inline] - fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>( + fn decode<'a, 'tcx, M: BlobMetadata<'a, 'tcx>>( self, metadata: M, - ) -> DecodeIterator<'a, 'tcx, T::Value<'tcx>> + ) -> DecodeIterator, M::Context> where - T::Value<'tcx>: Decodable>, + T::Value<'tcx>: Decodable, { let mut dcx = metadata.decoder(self.position.get()); - dcx.lazy_state = LazyState::NodeStart(self.position); + dcx.set_lazy_state(LazyState::NodeStart(self.position)); DecodeIterator { elem_counter: (0..self.num_elems), dcx, _phantom: PhantomData } } } -impl<'a, 'tcx> DecodeContext<'a, 'tcx> { +impl<'a, 'tcx> MetadataDecodeContext<'a, 'tcx> { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { let Some(tcx) = self.tcx else { @@ -324,11 +423,6 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { tcx } - #[inline] - pub(crate) fn blob(&self) -> &'a MetadataBlob { - self.blob - } - #[inline] fn cdata(&self) -> CrateMetadataRef<'a> { debug_assert!(self.cdata.is_some(), "missing CrateMetadata in DecodeContext"); @@ -339,34 +433,12 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { self.cdata().map_encoded_cnum_to_current(cnum) } +} +impl<'a> BlobDecodeContext<'a> { #[inline] - fn read_lazy_offset_then(&mut self, f: impl Fn(NonZero) -> T) -> T { - let distance = self.read_usize(); - let position = match self.lazy_state { - LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"), - LazyState::NodeStart(start) => { - let start = start.get(); - assert!(distance <= start); - start - distance - } - LazyState::Previous(last_pos) => last_pos.get() + distance, - }; - let position = NonZero::new(position).unwrap(); - self.lazy_state = LazyState::Previous(position); - f(position) - } - - fn read_lazy(&mut self) -> LazyValue { - self.read_lazy_offset_then(|pos| LazyValue::from_position(pos)) - } - - fn read_lazy_array(&mut self, len: usize) -> LazyArray { - self.read_lazy_offset_then(|pos| LazyArray::from_position_and_num_elems(pos, len)) - } - - fn read_lazy_table(&mut self, width: usize, len: usize) -> LazyTable { - self.read_lazy_offset_then(|pos| LazyTable::from_position_and_encoded_size(pos, width, len)) + pub(crate) fn blob(&self) -> &'a MetadataBlob { + self.blob } #[inline] @@ -397,7 +469,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { } } -impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { +impl<'a, 'tcx> TyDecoder<'tcx> for MetadataDecodeContext<'a, 'tcx> { const CLEAR_CROSS_CRATE: bool = true; #[inline] @@ -426,12 +498,12 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { where F: FnOnce(&mut Self) -> R, { - let new_opaque = self.opaque.split_at(pos); - let old_opaque = mem::replace(&mut self.opaque, new_opaque); - let old_state = mem::replace(&mut self.lazy_state, LazyState::NoNode); + let new_opaque = self.blob_decoder.opaque.split_at(pos); + let old_opaque = mem::replace(&mut self.blob_decoder.opaque, new_opaque); + let old_state = mem::replace(&mut self.blob_decoder.lazy_state, LazyState::NoNode); let r = f(self); - self.opaque = old_opaque; - self.lazy_state = old_state; + self.blob_decoder.opaque = old_opaque; + self.blob_decoder.lazy_state = old_state; r } @@ -444,14 +516,14 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { } } -impl<'a, 'tcx> Decodable> for ExpnIndex { +impl<'a, 'tcx> Decodable> for ExpnIndex { #[inline] - fn decode(d: &mut DecodeContext<'a, 'tcx>) -> ExpnIndex { + fn decode(d: &mut MetadataDecodeContext<'a, 'tcx>) -> ExpnIndex { ExpnIndex::from_u32(d.read_u32()) } } -impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> { +impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> { fn decode_attr_id(&mut self) -> rustc_span::AttrId { let sess = self.sess.expect("can't decode AttrId without Session"); sess.psess.attr_id_generator.mk_attr_id() @@ -462,10 +534,6 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> { self.map_encoded_cnum_to_current(cnum) } - fn decode_def_index(&mut self) -> DefIndex { - DefIndex::from_u32(self.read_u32()) - } - fn decode_def_id(&mut self) -> DefId { DefId { krate: Decodable::decode(self), index: Decodable::decode(self) } } @@ -554,7 +622,25 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> { }; data.span() } +} +impl<'a, 'tcx> BlobDecoder for MetadataDecodeContext<'a, 'tcx> { + fn decode_def_index(&mut self) -> DefIndex { + self.blob_decoder.decode_def_index() + } + fn decode_symbol(&mut self) -> Symbol { + self.blob_decoder.decode_symbol() + } + + fn decode_byte_symbol(&mut self) -> ByteSymbol { + self.blob_decoder.decode_byte_symbol() + } +} + +impl<'a> BlobDecoder for BlobDecodeContext<'a> { + fn decode_def_index(&mut self) -> DefIndex { + DefIndex::from_u32(self.read_u32()) + } fn decode_symbol(&mut self) -> Symbol { self.decode_symbol_or_byte_symbol( Symbol::new, @@ -572,8 +658,8 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> { } } -impl<'a, 'tcx> Decodable> for SpanData { - fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SpanData { +impl<'a, 'tcx> Decodable> for SpanData { + fn decode(decoder: &mut MetadataDecodeContext<'a, 'tcx>) -> SpanData { let tag = SpanTag::decode(decoder); let ctxt = tag.context().unwrap_or_else(|| SyntaxContext::decode(decoder)); @@ -677,43 +763,50 @@ impl<'a, 'tcx> Decodable> for SpanData { } } -impl<'a, 'tcx> Decodable> for &'tcx [(ty::Clause<'tcx>, Span)] { - fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self { +impl<'a, 'tcx> Decodable> for &'tcx [(ty::Clause<'tcx>, Span)] { + fn decode(d: &mut MetadataDecodeContext<'a, 'tcx>) -> Self { ty::codec::RefDecodable::decode(d) } } -impl<'a, 'tcx, T> Decodable> for LazyValue { - fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self { +impl Decodable for LazyValue { + fn decode(decoder: &mut D) -> Self { decoder.read_lazy() } } -impl<'a, 'tcx, T> Decodable> for LazyArray { +impl Decodable for LazyArray { #[inline] - fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self { + fn decode(decoder: &mut D) -> Self { let len = decoder.read_usize(); if len == 0 { LazyArray::default() } else { decoder.read_lazy_array(len) } } } -impl<'a, 'tcx, I: Idx, T> Decodable> for LazyTable { - fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self { +impl Decodable for LazyTable { + fn decode(decoder: &mut D) -> Self { let width = decoder.read_usize(); let len = decoder.read_usize(); decoder.read_lazy_table(width, len) } } -implement_ty_decoder!(DecodeContext<'a, 'tcx>); +mod meta { + use super::*; + implement_ty_decoder!(MetadataDecodeContext<'a, 'tcx>); +} +mod blob { + use super::*; + implement_ty_decoder!(BlobDecodeContext<'a>); +} impl MetadataBlob { pub(crate) fn check_compatibility( &self, cfg_version: &'static str, ) -> Result<(), Option> { - if !self.blob().starts_with(METADATA_HEADER) { - if self.blob().starts_with(b"rust") { + if !self.starts_with(METADATA_HEADER) { + if self.starts_with(b"rust") { return Err(Some("".to_owned())); } return Err(None); @@ -731,7 +824,7 @@ impl MetadataBlob { fn root_pos(&self) -> NonZero { let offset = METADATA_HEADER.len(); - let pos_bytes = self.blob()[offset..][..8].try_into().unwrap(); + let pos_bytes = self[offset..][..8].try_into().unwrap(); let pos = u64::from_le_bytes(pos_bytes); NonZero::new(pos as usize).unwrap() } @@ -1897,11 +1990,12 @@ impl CrateMetadata { }; // Need `CrateMetadataRef` to decode `DefId`s in simplified types. + let cref = CrateMetadataRef { cdata: &cdata, cstore }; cdata.incoherent_impls = cdata .root .incoherent_impls - .decode(CrateMetadataRef { cdata: &cdata, cstore }) - .map(|incoherent_impls| (incoherent_impls.self_ty, incoherent_impls.impls)) + .decode(cref) + .map(|incoherent_impls| (incoherent_impls.self_ty.decode(cref), incoherent_impls.impls)) .collect(); cdata diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 4831395f3164..24cfdc05e5cb 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -15,12 +15,13 @@ use rustc_middle::query::{ExternProviders, LocalCrate}; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::util::Providers; +use rustc_serialize::Decoder; use rustc_session::cstore::{CrateStore, ExternCrate}; use rustc_session::{Session, StableCrateId}; use rustc_span::hygiene::ExpnId; use rustc_span::{Span, Symbol, kw}; -use super::{Decodable, DecodeContext, DecodeIterator}; +use super::{Decodable, DecodeIterator}; use crate::creader::{CStore, LoadedMacro}; use crate::rmeta::AttrFlags; use crate::rmeta::table::IsDefault; @@ -65,8 +66,8 @@ impl ProcessQueryValue<'_, Result, E>> for Option { } } -impl<'a, 'tcx, T: Copy + Decodable>> ProcessQueryValue<'tcx, &'tcx [T]> - for Option> +impl<'tcx, D: Decoder, T: Copy + Decodable> ProcessQueryValue<'tcx, &'tcx [T]> + for Option> { #[inline(always)] fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx [T] { @@ -74,8 +75,8 @@ impl<'a, 'tcx, T: Copy + Decodable>> ProcessQueryValue<' } } -impl<'a, 'tcx, T: Copy + Decodable>> - ProcessQueryValue<'tcx, Option<&'tcx [T]>> for Option> +impl<'tcx, D: Decoder, T: Copy + Decodable> ProcessQueryValue<'tcx, Option<&'tcx [T]>> + for Option> { #[inline(always)] fn process_decoded(self, tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> Option<&'tcx [T]> { diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index a17b3e1047d0..949d7630f673 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -3,7 +3,8 @@ use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::def_id::{DefIndex, DefPathHash}; -use crate::rmeta::{DecodeContext, EncodeContext}; +use crate::rmeta::EncodeContext; +use crate::rmeta::decoder::BlobDecodeContext; pub(crate) enum DefPathHashMapRef<'tcx> { OwnedFromMetadata(odht::HashTable), @@ -40,8 +41,8 @@ impl<'a, 'tcx> Encodable> for DefPathHashMapRef<'tcx> { } } -impl<'a, 'tcx> Decodable> for DefPathHashMapRef<'static> { - fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> { +impl<'a> Decodable> for DefPathHashMapRef<'static> { + fn decode(d: &mut BlobDecodeContext<'a>) -> DefPathHashMapRef<'static> { let len = d.read_usize(); let pos = d.position(); let o = d.blob().bytes().clone().slice(|blob| &blob[pos..pos + len]); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4085fd5e70f1..94bba9445610 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2205,7 +2205,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .incoherent_impls .iter() .map(|(&simp, impls)| IncoherentImpls { - self_ty: simp, + self_ty: self.lazy(simp), impls: self.lazy_array(impls.iter().map(|def_id| def_id.local_def_index)), }) .collect(); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index ac042c2ca75d..b1b9bcfcc506 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -1,8 +1,8 @@ use std::marker::PhantomData; use std::num::NonZero; +use decoder::LazyDecoder; pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob, TargetModifiers}; -use decoder::{DecodeContext, Metadata}; use def_path_hash_map::DefPathHashMapRef; use encoder::EncodeContext; pub use encoder::{EncodedMetadata, encode_metadata, rendered_const}; @@ -19,7 +19,8 @@ use rustc_hir::{PreciseCapturingArgKind, attrs}; use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet; use rustc_macros::{ - Decodable, Encodable, MetadataDecodable, MetadataEncodable, TyDecodable, TyEncodable, + BlobDecodable, Decodable, Encodable, MetadataDecodable, MetadataEncodable, TyDecodable, + TyEncodable, }; use rustc_middle::metadata::ModChild; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; @@ -201,7 +202,7 @@ pub(crate) struct ProcMacroData { /// See #76720 for more details. /// /// If you do modify this struct, also bump the [`METADATA_VERSION`] constant. -#[derive(MetadataEncodable, MetadataDecodable)] +#[derive(MetadataEncodable, BlobDecodable)] pub(crate) struct CrateHeader { pub(crate) triple: TargetTuple, pub(crate) hash: Svh, @@ -323,7 +324,7 @@ impl RawDefId { } } -#[derive(Encodable, Decodable)] +#[derive(Encodable, BlobDecodable)] pub(crate) struct CrateDep { pub name: Symbol, pub hash: Svh, @@ -341,7 +342,7 @@ pub(crate) struct TraitImpls { #[derive(MetadataEncodable, MetadataDecodable)] pub(crate) struct IncoherentImpls { - self_ty: SimplifiedType, + self_ty: LazyValue, impls: LazyArray, } diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 4ce313f32a75..aaaed76bda9d 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -1,6 +1,7 @@ use rustc_hir::def::CtorOf; use rustc_index::Idx; +use crate::rmeta::decoder::BlobMetadata; use crate::rmeta::*; pub(super) trait IsDefault: Default { @@ -522,7 +523,11 @@ where for<'tcx> T::Value<'tcx>: FixedSizeEncoding, { /// Given the metadata, extract out the value at a particular index (if any). - pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(&self, metadata: M, i: I) -> T::Value<'tcx> { + pub(super) fn get<'a, 'tcx, M: BlobMetadata<'a, 'tcx>>( + &self, + metadata: M, + i: I, + ) -> T::Value<'tcx> { // Access past the end of the table returns a Default if i.index() >= self.len { return Default::default(); diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index 9091d492c26b..5739d132b66c 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -6,11 +6,11 @@ pub mod exported_symbols; pub mod lang_items; pub mod lib_features { use rustc_data_structures::unord::UnordMap; - use rustc_macros::{HashStable, TyDecodable, TyEncodable}; + use rustc_macros::{BlobDecodable, Encodable, HashStable}; use rustc_span::{Span, Symbol}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] - #[derive(HashStable, TyEncodable, TyDecodable)] + #[derive(HashStable, Encodable, BlobDecodable)] pub enum FeatureStability { AcceptedSince(Symbol), Unstable { old_name: Option }, diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index e8952d0492d1..c882d5d499bd 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -20,8 +20,8 @@ use rustc_span::hygiene::{ }; use rustc_span::source_map::Spanned; use rustc_span::{ - BytePos, ByteSymbol, CachingSourceMapView, ExpnData, ExpnHash, Pos, RelativeBytePos, - SourceFile, Span, SpanDecoder, SpanEncoder, StableSourceFileId, Symbol, + BlobDecoder, BytePos, ByteSymbol, CachingSourceMapView, ExpnData, ExpnHash, Pos, + RelativeBytePos, SourceFile, Span, SpanDecoder, SpanEncoder, StableSourceFileId, Symbol, }; use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; @@ -672,36 +672,12 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> { Span::new(lo, hi, ctxt, parent) } - fn decode_symbol(&mut self) -> Symbol { - self.decode_symbol_or_byte_symbol( - Symbol::new, - |this| Symbol::intern(this.read_str()), - |opaque| Symbol::intern(opaque.read_str()), - ) - } - - fn decode_byte_symbol(&mut self) -> ByteSymbol { - self.decode_symbol_or_byte_symbol( - ByteSymbol::new, - |this| ByteSymbol::intern(this.read_byte_str()), - |opaque| ByteSymbol::intern(opaque.read_byte_str()), - ) - } - fn decode_crate_num(&mut self) -> CrateNum { let stable_id = StableCrateId::decode(self); let cnum = self.tcx.stable_crate_id_to_crate_num(stable_id); cnum } - // This impl makes sure that we get a runtime error when we try decode a - // `DefIndex` that is not contained in a `DefId`. Such a case would be problematic - // because we would not know how to transform the `DefIndex` to the current - // context. - fn decode_def_index(&mut self) -> DefIndex { - panic!("trying to decode `DefIndex` outside the context of a `DefId`") - } - // Both the `CrateNum` and the `DefIndex` of a `DefId` can change in between two // compilation sessions. We use the `DefPathHash`, which is stable across // sessions, to map the old `DefId` to the new one. @@ -725,6 +701,32 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> { } } +impl<'a, 'tcx> BlobDecoder for CacheDecoder<'a, 'tcx> { + fn decode_symbol(&mut self) -> Symbol { + self.decode_symbol_or_byte_symbol( + Symbol::new, + |this| Symbol::intern(this.read_str()), + |opaque| Symbol::intern(opaque.read_str()), + ) + } + + fn decode_byte_symbol(&mut self) -> ByteSymbol { + self.decode_symbol_or_byte_symbol( + ByteSymbol::new, + |this| ByteSymbol::intern(this.read_byte_str()), + |opaque| ByteSymbol::intern(opaque.read_byte_str()), + ) + } + + // This impl makes sure that we get a runtime error when we try decode a + // `DefIndex` that is not contained in a `DefId`. Such a case would be problematic + // because we would not know how to transform the `DefIndex` to the current + // context. + fn decode_def_index(&mut self) -> DefIndex { + panic!("trying to decode `DefIndex` outside the context of a `DefId`") + } +} + impl<'a, 'tcx> Decodable> for &'tcx UnordSet { #[inline] fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d3e0fbb955c4..b4c20d7cadf9 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -41,8 +41,8 @@ use rustc_hir::{LangItem, attrs as attr, find_attr}; use rustc_index::IndexVec; use rustc_index::bit_set::BitMatrix; use rustc_macros::{ - Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, - extension, + BlobDecodable, Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, + TypeVisitable, extension, }; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::{Decodable, Encodable}; @@ -264,7 +264,7 @@ impl Asyncness { } } -#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)] +#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, BlobDecodable, HashStable)] pub enum Visibility { /// Visible everywhere (including in other crates). Public, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f97a29e064b6..9b19961fcee4 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -21,7 +21,7 @@ use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, DiagArgValue, DiagCtxtFlags, IntoDiagArg}; use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; -use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; use rustc_span::{ @@ -543,7 +543,7 @@ impl SwitchWithOptPath { } #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic)] -#[derive(Encodable, Decodable)] +#[derive(Encodable, BlobDecodable)] pub enum SymbolManglingVersion { Legacy, V0, @@ -1521,7 +1521,7 @@ pub enum EntryFnType { }, } -#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)] +#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, BlobDecodable)] #[derive(HashStable_Generic)] pub enum CrateType { Executable, diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 30f6256a75ef..8aef4b179f88 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -12,7 +12,7 @@ use rustc_hir::def_id::{ CrateNum, DefId, LOCAL_CRATE, LocalDefId, StableCrateId, StableCrateIdMap, }; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; -use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic}; use rustc_span::{Span, Symbol}; use crate::search_paths::PathKind; @@ -36,7 +36,7 @@ impl CrateSource { } } -#[derive(Encodable, Decodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] +#[derive(Encodable, BlobDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] #[derive(HashStable_Generic)] pub enum CrateDepKind { /// A dependency that is only used for its macros. @@ -59,7 +59,7 @@ impl CrateDepKind { } } -#[derive(Copy, Debug, PartialEq, Clone, Encodable, Decodable, HashStable_Generic)] +#[derive(Copy, Debug, PartialEq, Clone, Encodable, BlobDecodable, HashStable_Generic)] pub enum LinkagePreference { RequireDynamic, RequireStatic, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 872a48efa366..d9792142a884 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -10,7 +10,7 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_errors::{ColorConfig, LanguageIdentifier, TerminalUrl}; use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; -use rustc_macros::{Decodable, Encodable}; +use rustc_macros::{BlobDecodable, Encodable}; use rustc_span::edition::Edition; use rustc_span::{RealFileName, SourceFileHashAlgorithm}; use rustc_target::spec::{ @@ -75,7 +75,7 @@ pub struct ExtendedTargetModifierInfo { /// A recorded -Zopt_name=opt_value (or -Copt_name=opt_value) /// which alter the ABI or effectiveness of exploit mitigations. -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, BlobDecodable)] pub struct TargetModifier { /// Option enum value pub opt: OptionsTargetModifiers, @@ -248,7 +248,7 @@ macro_rules! top_level_tmod_enum { ($user_value:ident){$($pout:tt)*}; ) => { #[allow(non_camel_case_types)] - #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, Decodable)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, BlobDecodable)] pub enum OptionsTargetModifiers { $($variant($substruct_enum)),* } @@ -520,7 +520,7 @@ macro_rules! tmod_enum { ($user_value:ident){$($pout:tt)*}; ) => { #[allow(non_camel_case_types)] - #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, Decodable)] + #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, BlobDecodable)] pub enum $tmod_enum_name { $($eout),* } diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 77f01548bca2..484e626d4638 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -7,7 +7,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, use rustc_data_structures::unhash::Unhasher; use rustc_hashes::Hash64; use rustc_index::Idx; -use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Encodable}; use crate::{HashStableContext, SpanDecoder, SpanEncoder, Symbol}; @@ -141,7 +141,7 @@ impl StableOrd for DefPathHash { /// For more information on the possibility of hash collisions in rustc, /// see the discussion in [`DefId`]. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] -#[derive(Hash, HashStable_Generic, Encodable, Decodable)] +#[derive(Hash, HashStable_Generic, Encodable, BlobDecodable)] pub struct StableCrateId(pub(crate) Hash64); impl StableCrateId { diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index 28335734f4de..a27c5f62c1e5 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -1,10 +1,10 @@ use std::fmt; use std::str::FromStr; -use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +use rustc_macros::{BlobDecodable, Encodable, HashStable_Generic}; /// The edition of the compiler. (See [RFC 2052](https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md).) -#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, Decodable, Eq)] +#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, BlobDecodable, Eq)] #[derive(HashStable_Generic)] pub enum Edition { // When adding new editions, be sure to do the following: diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 31f82860b73d..c6490b358ef8 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1296,20 +1296,37 @@ impl Encodable for AttrId { } } -/// This trait is used to allow decoder specific encodings of certain types. -/// It is similar to rustc_type_ir's TyDecoder. -pub trait SpanDecoder: Decoder { - fn decode_span(&mut self) -> Span; +pub trait BlobDecoder: Decoder { fn decode_symbol(&mut self) -> Symbol; fn decode_byte_symbol(&mut self) -> ByteSymbol; + fn decode_def_index(&mut self) -> DefIndex; +} + +/// This trait is used to allow decoder specific encodings of certain types. +/// It is similar to rustc_type_ir's TyDecoder. +pub trait SpanDecoder: BlobDecoder { + fn decode_span(&mut self) -> Span; fn decode_expn_id(&mut self) -> ExpnId; fn decode_syntax_context(&mut self) -> SyntaxContext; fn decode_crate_num(&mut self) -> CrateNum; - fn decode_def_index(&mut self) -> DefIndex; fn decode_def_id(&mut self) -> DefId; fn decode_attr_id(&mut self) -> AttrId; } +impl BlobDecoder for MemDecoder<'_> { + fn decode_symbol(&mut self) -> Symbol { + Symbol::intern(self.read_str()) + } + + fn decode_byte_symbol(&mut self) -> ByteSymbol { + ByteSymbol::intern(self.read_byte_str()) + } + + fn decode_def_index(&mut self) -> DefIndex { + panic!("cannot decode `DefIndex` with `MemDecoder`"); + } +} + impl SpanDecoder for MemDecoder<'_> { fn decode_span(&mut self) -> Span { let lo = Decodable::decode(self); @@ -1318,14 +1335,6 @@ impl SpanDecoder for MemDecoder<'_> { Span::new(lo, hi, SyntaxContext::root(), None) } - fn decode_symbol(&mut self) -> Symbol { - Symbol::intern(self.read_str()) - } - - fn decode_byte_symbol(&mut self) -> ByteSymbol { - ByteSymbol::intern(self.read_byte_str()) - } - fn decode_expn_id(&mut self) -> ExpnId { panic!("cannot decode `ExpnId` with `MemDecoder`"); } @@ -1338,10 +1347,6 @@ impl SpanDecoder for MemDecoder<'_> { CrateNum::from_u32(self.read_u32()) } - fn decode_def_index(&mut self) -> DefIndex { - panic!("cannot decode `DefIndex` with `MemDecoder`"); - } - fn decode_def_id(&mut self) -> DefId { DefId { krate: Decodable::decode(self), index: Decodable::decode(self) } } @@ -1357,13 +1362,13 @@ impl Decodable for Span { } } -impl Decodable for Symbol { +impl Decodable for Symbol { fn decode(s: &mut D) -> Symbol { s.decode_symbol() } } -impl Decodable for ByteSymbol { +impl Decodable for ByteSymbol { fn decode(s: &mut D) -> ByteSymbol { s.decode_byte_symbol() } @@ -1387,7 +1392,7 @@ impl Decodable for CrateNum { } } -impl Decodable for DefIndex { +impl Decodable for DefIndex { fn decode(s: &mut D) -> DefIndex { s.decode_def_index() } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 424026bdceab..c76e345bb7b6 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -52,7 +52,7 @@ use rustc_abi::{ use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_error_messages::{DiagArgValue, IntoDiagArg, into_diag_arg_using_display}; use rustc_fs_util::try_canonicalize; -use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::{Symbol, kw, sym}; use serde_json::Value; @@ -830,7 +830,7 @@ impl LinkerFeatures { } crate::target_spec_enum! { - #[derive(Encodable, Decodable, HashStable_Generic)] + #[derive(Encodable, BlobDecodable, HashStable_Generic)] pub enum PanicStrategy { Unwind = "unwind", Abort = "abort", @@ -840,7 +840,7 @@ crate::target_spec_enum! { parse_error_type = "panic strategy"; } -#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)] +#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, BlobDecodable, HashStable_Generic)] pub enum OnBrokenPipe { Default, Kill, From 40a77eb1a2f3327630a9a6b883aa1dc62f70a430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 27 Nov 2025 17:27:12 +0100 Subject: [PATCH 0403/3801] make cdata required --- compiler/rustc_metadata/src/rmeta/decoder.rs | 58 ++++++++------------ 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index b1cac381e05b..5bc61e431d03 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -214,12 +214,12 @@ impl<'a> LazyDecoder for BlobDecodeContext<'a> { /// Decoding of some types, like `Span` require some information to already been read. pub(super) struct MetadataDecodeContext<'a, 'tcx> { blob_decoder: BlobDecodeContext<'a>, - cdata: Option>, + cdata: CrateMetadataRef<'a>, sess: Option<&'tcx Session>, tcx: Option>, // Used for decoding interpret::AllocIds in a cached & thread-safe manner. - alloc_decoding_session: Option>, + alloc_decoding_session: AllocDecodingSession<'a>, } impl<'a, 'tcx> LazyDecoder for MetadataDecodeContext<'a, 'tcx> { @@ -257,9 +257,7 @@ pub(super) trait BlobMetadata<'a, 'tcx>: Copy { pub(super) trait Metadata<'a, 'tcx>: Copy { fn _blob(self) -> &'a MetadataBlob; - fn cdata(self) -> Option> { - None - } + fn cdata(self) -> CrateMetadataRef<'a>; fn sess(self) -> Option<&'tcx Session> { None } @@ -280,14 +278,13 @@ where fn decoder(self, pos: usize) -> MetadataDecodeContext<'a, 'tcx> { let tcx = self.tcx(); + let cdata = self.cdata(); MetadataDecodeContext { blob_decoder: self.blob().decoder(pos), - cdata: self.cdata(), + cdata, sess: self.sess().or(tcx.map(|tcx| tcx.sess)), tcx, - alloc_decoding_session: self - .cdata() - .map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()), + alloc_decoding_session: cdata.cdata.alloc_decoding_state.new_decoding_session(), } } } @@ -321,8 +318,8 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for CrateMetadataRef<'a> { &self.cdata.blob } #[inline] - fn cdata(self) -> Option> { - Some(self) + fn cdata(self) -> CrateMetadataRef<'a> { + self } } @@ -332,8 +329,8 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, &'tcx Session) { &self.0.cdata.blob } #[inline] - fn cdata(self) -> Option> { - Some(self.0) + fn cdata(self) -> CrateMetadataRef<'a> { + self.0 } #[inline] fn sess(self) -> Option<&'tcx Session> { @@ -347,8 +344,8 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) { &self.0.cdata.blob } #[inline] - fn cdata(self) -> Option> { - Some(self.0) + fn cdata(self) -> CrateMetadataRef<'a> { + self.0 } #[inline] fn tcx(self) -> Option> { @@ -423,15 +420,9 @@ impl<'a, 'tcx> MetadataDecodeContext<'a, 'tcx> { tcx } - #[inline] - fn cdata(&self) -> CrateMetadataRef<'a> { - debug_assert!(self.cdata.is_some(), "missing CrateMetadata in DecodeContext"); - self.cdata.unwrap() - } - #[inline] fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { - self.cdata().map_encoded_cnum_to_current(cnum) + self.cdata.map_encoded_cnum_to_current(cnum) } } @@ -483,7 +474,7 @@ impl<'a, 'tcx> TyDecoder<'tcx> for MetadataDecodeContext<'a, 'tcx> { { let tcx = self.tcx(); - let key = ty::CReaderCacheKey { cnum: Some(self.cdata().cnum), pos: shorthand }; + let key = ty::CReaderCacheKey { cnum: Some(self.cdata.cnum), pos: shorthand }; if let Some(&ty) = tcx.ty_rcache.borrow().get(&key) { return ty; @@ -508,11 +499,8 @@ impl<'a, 'tcx> TyDecoder<'tcx> for MetadataDecodeContext<'a, 'tcx> { } fn decode_alloc_id(&mut self) -> rustc_middle::mir::interpret::AllocId { - if let Some(alloc_decoding_session) = self.alloc_decoding_session { - alloc_decoding_session.decode_alloc_id(self) - } else { - bug!("Attempting to decode interpret::AllocId without CrateMetadata") - } + let ads = self.alloc_decoding_session; + ads.decode_alloc_id(self) } } @@ -539,8 +527,7 @@ impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> { } fn decode_syntax_context(&mut self) -> SyntaxContext { - let cdata = self.cdata(); - + let cdata = self.cdata; let Some(sess) = self.sess else { bug!( "Cannot decode SyntaxContext without Session.\ @@ -561,7 +548,7 @@ impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> { } fn decode_expn_id(&mut self) -> ExpnId { - let local_cdata = self.cdata(); + let local_cdata = self.cdata; let Some(sess) = self.sess else { bug!( @@ -712,18 +699,17 @@ impl<'a, 'tcx> Decodable> for SpanData { // we can call `imported_source_file` for the proper crate, and binary search // through the returned slice using our span. let source_file = if tag.kind() == SpanKind::Local { - decoder.cdata().imported_source_file(metadata_index, sess) + decoder.cdata.imported_source_file(metadata_index, sess) } else { // When we encode a proc-macro crate, all `Span`s should be encoded // with `TAG_VALID_SPAN_LOCAL` - if decoder.cdata().root.is_proc_macro_crate() { + if decoder.cdata.root.is_proc_macro_crate() { // Decode `CrateNum` as u32 - using `CrateNum::decode` will ICE // since we don't have `cnum_map` populated. let cnum = u32::decode(decoder); panic!( "Decoding of crate {:?} tried to access proc-macro dep {:?}", - decoder.cdata().root.header.name, - cnum + decoder.cdata.root.header.name, cnum ); } // tag is TAG_VALID_SPAN_FOREIGN, checked by `debug_assert` above @@ -733,7 +719,7 @@ impl<'a, 'tcx> Decodable> for SpanData { cnum ); - let foreign_data = decoder.cdata().cstore.get_crate_data(cnum); + let foreign_data = decoder.cdata.cstore.get_crate_data(cnum); foreign_data.imported_source_file(metadata_index, sess) }; From 395b508ce6213bd5deb2c7876679cea05495f2a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 27 Nov 2025 17:38:44 +0100 Subject: [PATCH 0404/3801] remove unnecessary method --- compiler/rustc_metadata/src/rmeta/decoder.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 5bc61e431d03..ba19be36efac 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -432,11 +432,6 @@ impl<'a> BlobDecodeContext<'a> { self.blob } - #[inline] - fn read_raw_bytes(&mut self, len: usize) -> &[u8] { - self.opaque.read_raw_bytes(len) - } - fn decode_symbol_or_byte_symbol( &mut self, new_from_index: impl Fn(u32) -> S, From fa5f075d1c4721eda13a4ae65ba5d3376cc164f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 28 Nov 2025 00:14:34 +0100 Subject: [PATCH 0405/3801] add TyCtxt everywhere replacing nothing or passed sessions --- compiler/rustc_metadata/src/creader.rs | 8 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 498 ++++++++---------- .../src/rmeta/decoder/cstore_impl.rs | 106 ++-- compiler/rustc_metadata/src/rmeta/table.rs | 8 +- .../rustc_resolve/src/build_reduced_graph.rs | 8 +- compiler/rustc_resolve/src/ident.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 2 +- compiler/rustc_resolve/src/macros.rs | 2 +- src/librustdoc/clean/inline.rs | 4 +- 10 files changed, 288 insertions(+), 352 deletions(-) diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 95862ce01687..e0aae4c4b3a0 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -276,8 +276,9 @@ impl CStore { .filter_map(|(cnum, data)| data.as_deref().map(|data| (cnum, data))) } - pub fn all_proc_macro_def_ids(&self) -> impl Iterator { - self.iter_crate_data().flat_map(|(krate, data)| data.proc_macros_for_crate(krate, self)) + pub fn all_proc_macro_def_ids(&self, tcx: TyCtxt<'_>) -> impl Iterator { + self.iter_crate_data() + .flat_map(move |(krate, data)| data.proc_macros_for_crate(tcx, krate, self)) } fn push_dependencies_in_postorder(&self, deps: &mut IndexSet, cnum: CrateNum) { @@ -683,6 +684,7 @@ impl CStore { }; let crate_metadata = CrateMetadata::new( + tcx, self, metadata, crate_root, @@ -778,7 +780,7 @@ impl CStore { self.used_extern_options.insert(name); match self.maybe_resolve_crate(tcx, name, dep_kind, origin) { Ok(cnum) => { - self.set_used_recursively(cnum); + self.set_used_recursively(tcx, cnum); Some(cnum) } Err(err) => { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index ba19be36efac..df0d1b7d085f 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -29,7 +29,6 @@ use rustc_middle::{bug, implement_ty_decoder}; use rustc_proc_macro::bridge::client::ProcMacro; use rustc_serialize::opaque::MemDecoder; use rustc_serialize::{Decodable, Decoder}; -use rustc_session::Session; use rustc_session::config::TargetModifier; use rustc_session::cstore::{CrateSource, ExternCrate}; use rustc_span::hygiene::HygieneDecodeContext; @@ -165,7 +164,6 @@ pub(super) struct BlobDecodeContext<'a> { } /// trait for anything containing `LazyState` and is a decoder. -// TODO: might need to live in rustc_middle pub(super) trait LazyDecoder: BlobDecoder { fn set_lazy_state(&mut self, state: LazyState); fn get_lazy_state(&self) -> LazyState; @@ -215,8 +213,7 @@ impl<'a> LazyDecoder for BlobDecodeContext<'a> { pub(super) struct MetadataDecodeContext<'a, 'tcx> { blob_decoder: BlobDecodeContext<'a>, cdata: CrateMetadataRef<'a>, - sess: Option<&'tcx Session>, - tcx: Option>, + tcx: TyCtxt<'tcx>, // Used for decoding interpret::AllocIds in a cached & thread-safe manner. alloc_decoding_session: AllocDecodingSession<'a>, @@ -246,50 +243,14 @@ impl<'a, 'tcx> Deref for MetadataDecodeContext<'a, 'tcx> { } } -pub(super) trait BlobMetadata<'a, 'tcx>: Copy { +pub(super) trait Metadata<'a>: Copy { type Context: BlobDecoder + LazyDecoder; fn blob(self) -> &'a MetadataBlob; fn decoder(self, pos: usize) -> Self::Context; } -/// Abstract over the various ways one can create metadata decoders. -pub(super) trait Metadata<'a, 'tcx>: Copy { - fn _blob(self) -> &'a MetadataBlob; - - fn cdata(self) -> CrateMetadataRef<'a>; - fn sess(self) -> Option<&'tcx Session> { - None - } - fn tcx(self) -> Option> { - None - } -} - -impl<'a, 'tcx, T> BlobMetadata<'a, 'tcx> for T -where - T: Metadata<'a, 'tcx>, -{ - type Context = MetadataDecodeContext<'a, 'tcx>; - - fn blob(self) -> &'a MetadataBlob { - self._blob() - } - - fn decoder(self, pos: usize) -> MetadataDecodeContext<'a, 'tcx> { - let tcx = self.tcx(); - let cdata = self.cdata(); - MetadataDecodeContext { - blob_decoder: self.blob().decoder(pos), - cdata, - sess: self.sess().or(tcx.map(|tcx| tcx.sess)), - tcx, - alloc_decoding_session: cdata.cdata.alloc_decoding_state.new_decoding_session(), - } - } -} - -impl<'a, 'tcx> BlobMetadata<'a, 'tcx> for &'a MetadataBlob { +impl<'a> Metadata<'a> for &'a MetadataBlob { type Context = BlobDecodeContext<'a>; fn blob(self) -> &'a MetadataBlob { @@ -312,50 +273,26 @@ impl<'a, 'tcx> BlobMetadata<'a, 'tcx> for &'a MetadataBlob { } } -impl<'a, 'tcx> Metadata<'a, 'tcx> for CrateMetadataRef<'a> { - #[inline] - fn _blob(self) -> &'a MetadataBlob { - &self.cdata.blob - } - #[inline] - fn cdata(self) -> CrateMetadataRef<'a> { - self - } -} +impl<'a, 'tcx> Metadata<'a> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) { + type Context = MetadataDecodeContext<'a, 'tcx>; -impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, &'tcx Session) { - #[inline] - fn _blob(self) -> &'a MetadataBlob { + fn blob(self) -> &'a MetadataBlob { &self.0.cdata.blob } - #[inline] - fn cdata(self) -> CrateMetadataRef<'a> { - self.0 - } - #[inline] - fn sess(self) -> Option<&'tcx Session> { - Some(self.1) - } -} -impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) { - #[inline] - fn _blob(self) -> &'a MetadataBlob { - &self.0.cdata.blob - } - #[inline] - fn cdata(self) -> CrateMetadataRef<'a> { - self.0 - } - #[inline] - fn tcx(self) -> Option> { - Some(self.1) + fn decoder(self, pos: usize) -> MetadataDecodeContext<'a, 'tcx> { + MetadataDecodeContext { + blob_decoder: self.blob().decoder(pos), + cdata: self.0, + tcx: self.1, + alloc_decoding_session: self.0.cdata.alloc_decoding_state.new_decoding_session(), + } } } impl LazyValue { #[inline] - fn decode<'a, 'tcx, M: BlobMetadata<'a, 'tcx>>(self, metadata: M) -> T::Value<'tcx> + fn decode<'a, 'tcx, M: Metadata<'a>>(self, metadata: M) -> T::Value<'tcx> where T::Value<'tcx>: Decodable, { @@ -395,7 +332,7 @@ unsafe impl> TrustedLen for DecodeIterator {} impl LazyArray { #[inline] - fn decode<'a, 'tcx, M: BlobMetadata<'a, 'tcx>>( + fn decode<'a, 'tcx, M: Metadata<'a>>( self, metadata: M, ) -> DecodeIterator, M::Context> @@ -409,17 +346,6 @@ impl LazyArray { } impl<'a, 'tcx> MetadataDecodeContext<'a, 'tcx> { - #[inline] - fn tcx(&self) -> TyCtxt<'tcx> { - let Some(tcx) = self.tcx else { - bug!( - "No TyCtxt found for decoding. \ - You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." - ); - }; - tcx - } - #[inline] fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { self.cdata.map_encoded_cnum_to_current(cnum) @@ -460,14 +386,14 @@ impl<'a, 'tcx> TyDecoder<'tcx> for MetadataDecodeContext<'a, 'tcx> { #[inline] fn interner(&self) -> TyCtxt<'tcx> { - self.tcx() + self.tcx } fn cached_ty_for_shorthand(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx> where F: FnOnce(&mut Self) -> Ty<'tcx>, { - let tcx = self.tcx(); + let tcx = self.tcx; let key = ty::CReaderCacheKey { cnum: Some(self.cdata.cnum), pos: shorthand }; @@ -508,8 +434,7 @@ impl<'a, 'tcx> Decodable> for ExpnIndex { impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> { fn decode_attr_id(&mut self) -> rustc_span::AttrId { - let sess = self.sess.expect("can't decode AttrId without Session"); - sess.psess.attr_id_generator.mk_attr_id() + self.tcx.sess.psess.attr_id_generator.mk_attr_id() } fn decode_crate_num(&mut self) -> CrateNum { @@ -523,12 +448,7 @@ impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> { fn decode_syntax_context(&mut self) -> SyntaxContext { let cdata = self.cdata; - let Some(sess) = self.sess else { - bug!( - "Cannot decode SyntaxContext without Session.\ - You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." - ); - }; + let tcx = self.tcx; let cname = cdata.root.name(); rustc_span::hygiene::decode_syntax_context(self, &cdata.hygiene_context, |_, id| { @@ -536,22 +456,16 @@ impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> { cdata .root .syntax_contexts - .get(cdata, id) + .get((cdata, tcx), id) .unwrap_or_else(|| panic!("Missing SyntaxContext {id:?} for crate {cname:?}")) - .decode((cdata, sess)) + .decode((cdata, tcx)) }) } fn decode_expn_id(&mut self) -> ExpnId { let local_cdata = self.cdata; - let Some(sess) = self.sess else { - bug!( - "Cannot decode ExpnId without Session. \ - You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." - ); - }; - + let tcx = self.tcx; let cnum = CrateNum::decode(self); let index = u32::decode(self); @@ -568,15 +482,15 @@ impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> { let expn_data = crate_data .root .expn_data - .get(crate_data, index) + .get((crate_data, tcx), index) .unwrap() - .decode((crate_data, sess)); + .decode((crate_data, tcx)); let expn_hash = crate_data .root .expn_hashes - .get(crate_data, index) + .get((crate_data, tcx), index) .unwrap() - .decode((crate_data, sess)); + .decode((crate_data, tcx)); (expn_data, expn_hash) }); expn_id @@ -655,12 +569,7 @@ impl<'a, 'tcx> Decodable> for SpanData { let len = tag.length().unwrap_or_else(|| BytePos::decode(decoder)); let hi = lo + len; - let Some(sess) = decoder.sess else { - bug!( - "Cannot decode Span without Session. \ - You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." - ) - }; + let tcx = decoder.tcx; // Index of the file in the corresponding crate's list of encoded files. let metadata_index = u32::decode(decoder); @@ -694,7 +603,7 @@ impl<'a, 'tcx> Decodable> for SpanData { // we can call `imported_source_file` for the proper crate, and binary search // through the returned slice using our span. let source_file = if tag.kind() == SpanKind::Local { - decoder.cdata.imported_source_file(metadata_index, sess) + decoder.cdata.imported_source_file(tcx, metadata_index) } else { // When we encode a proc-macro crate, all `Span`s should be encoded // with `TAG_VALID_SPAN_LOCAL` @@ -715,7 +624,7 @@ impl<'a, 'tcx> Decodable> for SpanData { ); let foreign_data = decoder.cdata.cstore.get_crate_data(cnum); - foreign_data.imported_source_file(metadata_index, sess) + foreign_data.imported_source_file(tcx, metadata_index) }; // Make sure our span is well-formed. @@ -1052,7 +961,7 @@ impl<'a> CrateMetadataRef<'a> { bug!("missing `{descr}` for {:?}", self.local_def_id(id)) } - fn raw_proc_macro(self, id: DefIndex) -> &'a ProcMacro { + fn raw_proc_macro(self, tcx: TyCtxt<'_>, id: DefIndex) -> &'a ProcMacro { // DefIndex's in root.proc_macro_data have a one-to-one correspondence // with items in 'raw_proc_macros'. let pos = self @@ -1061,7 +970,7 @@ impl<'a> CrateMetadataRef<'a> { .as_ref() .unwrap() .macros - .decode(self) + .decode((self, tcx)) .position(|i| i == id) .unwrap(); &self.raw_proc_macros.unwrap()[pos] @@ -1083,20 +992,20 @@ impl<'a> CrateMetadataRef<'a> { self.opt_item_name(item_index).expect("no encoded ident for item") } - fn opt_item_ident(self, item_index: DefIndex, sess: &Session) -> Option { + fn opt_item_ident(self, tcx: TyCtxt<'_>, item_index: DefIndex) -> Option { let name = self.opt_item_name(item_index)?; let span = self .root .tables .def_ident_span - .get(self, item_index) + .get((self, tcx), item_index) .unwrap_or_else(|| self.missing("def_ident_span", item_index)) - .decode((self, sess)); + .decode((self, tcx)); Some(Ident::new(name, span)) } - fn item_ident(self, item_index: DefIndex, sess: &Session) -> Ident { - self.opt_item_ident(item_index, sess).expect("no encoded ident for item") + fn item_ident(self, tcx: TyCtxt<'_>, item_index: DefIndex) -> Ident { + self.opt_item_ident(tcx, item_index).expect("no encoded ident for item") } #[inline] @@ -1104,25 +1013,25 @@ impl<'a> CrateMetadataRef<'a> { if cnum == LOCAL_CRATE { self.cnum } else { self.cnum_map[cnum] } } - fn def_kind(self, item_id: DefIndex) -> DefKind { + fn def_kind(self, tcx: TyCtxt<'_>, item_id: DefIndex) -> DefKind { self.root .tables .def_kind - .get(self, item_id) + .get((self, tcx), item_id) .unwrap_or_else(|| self.missing("def_kind", item_id)) } - fn get_span(self, index: DefIndex, sess: &Session) -> Span { + fn get_span(self, tcx: TyCtxt<'_>, index: DefIndex) -> Span { self.root .tables .def_span - .get(self, index) + .get((self, tcx), index) .unwrap_or_else(|| self.missing("def_span", index)) - .decode((self, sess)) + .decode((self, tcx)) } - fn load_proc_macro<'tcx>(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtension { - let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) { + fn load_proc_macro<'tcx>(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> SyntaxExtension { + let (name, kind, helper_attrs) = match *self.raw_proc_macro(tcx, id) { ProcMacro::CustomDerive { trait_name, attributes, client } => { let helper_attrs = attributes.iter().cloned().map(Symbol::intern).collect::>(); @@ -1141,11 +1050,11 @@ impl<'a> CrateMetadataRef<'a> { }; let sess = tcx.sess; - let attrs: Vec<_> = self.get_item_attrs(id, sess).collect(); + let attrs: Vec<_> = self.get_item_attrs(tcx, id).collect(); SyntaxExtension::new( sess, kind, - self.get_span(id, sess), + self.get_span(tcx, id), helper_attrs, self.root.edition, Symbol::intern(name), @@ -1156,6 +1065,7 @@ impl<'a> CrateMetadataRef<'a> { fn get_variant( self, + tcx: TyCtxt<'_>, kind: DefKind, index: DefIndex, parent_did: DefId, @@ -1167,7 +1077,8 @@ impl<'a> CrateMetadataRef<'a> { _ => bug!(), }; - let data = self.root.tables.variant_data.get(self, index).unwrap().decode(self); + let data = + self.root.tables.variant_data.get((self, tcx), index).unwrap().decode((self, tcx)); let variant_did = if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None }; @@ -1180,13 +1091,13 @@ impl<'a> CrateMetadataRef<'a> { variant_did, ctor, data.discr, - self.get_associated_item_or_field_def_ids(index) + self.get_associated_item_or_field_def_ids(tcx, index) .map(|did| ty::FieldDef { did, name: self.item_name(did.index), - vis: self.get_visibility(did.index), - safety: self.get_safety(did.index), - value: self.get_default_field(did.index), + vis: self.get_visibility(tcx, did.index), + safety: self.get_safety(tcx, did.index), + value: self.get_default_field(tcx, did.index), }) .collect(), parent_did, @@ -1196,8 +1107,8 @@ impl<'a> CrateMetadataRef<'a> { ) } - fn get_adt_def<'tcx>(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> { - let kind = self.def_kind(item_id); + fn get_adt_def<'tcx>(self, tcx: TyCtxt<'tcx>, item_id: DefIndex) -> ty::AdtDef<'tcx> { + let kind = self.def_kind(tcx, item_id); let did = self.local_def_id(item_id); let adt_kind = match kind { @@ -1206,25 +1117,26 @@ impl<'a> CrateMetadataRef<'a> { DefKind::Union => ty::AdtKind::Union, _ => bug!("get_adt_def called on a non-ADT {:?}", did), }; - let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self); + let repr = + self.root.tables.repr_options.get((self, tcx), item_id).unwrap().decode((self, tcx)); let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind { self.root .tables .module_children_non_reexports - .get(self, item_id) + .get((self, tcx), item_id) .expect("variants are not encoded for an enum") - .decode(self) + .decode((self, tcx)) .filter_map(|index| { - let kind = self.def_kind(index); + let kind = self.def_kind(tcx, index); match kind { DefKind::Ctor(..) => None, - _ => Some(self.get_variant(kind, index, did)), + _ => Some(self.get_variant(tcx, kind, index, did)), } }) .collect() } else { - std::iter::once(self.get_variant(kind, item_id, did)).collect() + std::iter::once(self.get_variant(tcx, kind, item_id, did)).collect() }; variants.sort_by_key(|(idx, _)| *idx); @@ -1237,44 +1149,44 @@ impl<'a> CrateMetadataRef<'a> { ) } - fn get_visibility(self, id: DefIndex) -> Visibility { + fn get_visibility(self, tcx: TyCtxt<'_>, id: DefIndex) -> Visibility { self.root .tables .visibility - .get(self, id) + .get((self, tcx), id) .unwrap_or_else(|| self.missing("visibility", id)) - .decode(self) + .decode((self, tcx)) .map_id(|index| self.local_def_id(index)) } - fn get_safety(self, id: DefIndex) -> Safety { - self.root.tables.safety.get(self, id) + fn get_safety(self, tcx: TyCtxt<'_>, id: DefIndex) -> Safety { + self.root.tables.safety.get((self, tcx), id) } - fn get_default_field(self, id: DefIndex) -> Option { - self.root.tables.default_fields.get(self, id).map(|d| d.decode(self)) + fn get_default_field(self, tcx: TyCtxt<'_>, id: DefIndex) -> Option { + self.root.tables.default_fields.get((self, tcx), id).map(|d| d.decode((self, tcx))) } - fn get_expn_that_defined(self, id: DefIndex, sess: &Session) -> ExpnId { + fn get_expn_that_defined(self, tcx: TyCtxt<'_>, id: DefIndex) -> ExpnId { self.root .tables .expn_that_defined - .get(self, id) + .get((self, tcx), id) .unwrap_or_else(|| self.missing("expn_that_defined", id)) - .decode((self, sess)) + .decode((self, tcx)) } - fn get_debugger_visualizers(self) -> Vec { - self.root.debugger_visualizers.decode(self).collect::>() + fn get_debugger_visualizers(self, tcx: TyCtxt<'_>) -> Vec { + self.root.debugger_visualizers.decode((self, tcx)).collect::>() } /// Iterates over all the stability attributes in the given crate. - fn get_lib_features(self) -> LibFeatures { + fn get_lib_features(self, tcx: TyCtxt<'_>) -> LibFeatures { LibFeatures { stability: self .root .lib_features - .decode(self) + .decode((self, tcx)) .map(|(sym, stab)| (sym, (stab, DUMMY_SP))) .collect(), } @@ -1284,7 +1196,7 @@ impl<'a> CrateMetadataRef<'a> { /// has an `implied_by` meta item, then the mapping from the implied feature to the actual /// feature is a stability implication). fn get_stability_implications<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Symbol)] { - tcx.arena.alloc_from_iter(self.root.stability_implications.decode(self)) + tcx.arena.alloc_from_iter(self.root.stability_implications.decode((self, tcx))) } /// Iterates over the lang items in the given crate. @@ -1292,15 +1204,15 @@ impl<'a> CrateMetadataRef<'a> { tcx.arena.alloc_from_iter( self.root .lang_items - .decode(self) + .decode((self, tcx)) .map(move |(def_index, index)| (self.local_def_id(def_index), index)), ) } fn get_stripped_cfg_items<'tcx>( self, - cnum: CrateNum, tcx: TyCtxt<'tcx>, + cnum: CrateNum, ) -> &'tcx [StrippedCfgItem] { let item_names = self .root @@ -1311,12 +1223,12 @@ impl<'a> CrateMetadataRef<'a> { } /// Iterates over the diagnostic items in the given crate. - fn get_diagnostic_items(self) -> DiagnosticItems { + fn get_diagnostic_items(self, tcx: TyCtxt<'_>) -> DiagnosticItems { let mut id_to_name = DefIdMap::default(); let name_to_id = self .root .diagnostic_items - .decode(self) + .decode((self, tcx)) .map(|(name, def_index)| { let id = self.local_def_id(def_index); id_to_name.insert(id, name); @@ -1326,10 +1238,10 @@ impl<'a> CrateMetadataRef<'a> { DiagnosticItems { id_to_name, name_to_id } } - fn get_mod_child(self, id: DefIndex, sess: &Session) -> ModChild { - let ident = self.item_ident(id, sess); - let res = Res::Def(self.def_kind(id), self.local_def_id(id)); - let vis = self.get_visibility(id); + fn get_mod_child(self, tcx: TyCtxt<'_>, id: DefIndex) -> ModChild { + let ident = self.item_ident(tcx, id); + let res = Res::Def(self.def_kind(tcx, id), self.local_def_id(id)); + let vis = self.get_visibility(tcx, id); ModChild { ident, res, vis, reexport_chain: Default::default() } } @@ -1338,30 +1250,27 @@ impl<'a> CrateMetadataRef<'a> { /// including both proper items and reexports. /// Module here is understood in name resolution sense - it can be a `mod` item, /// or a crate root, or an enum, or a trait. - fn get_module_children( - self, - id: DefIndex, - sess: &'a Session, - ) -> impl Iterator { + fn get_module_children(self, tcx: TyCtxt<'_>, id: DefIndex) -> impl Iterator { gen move { if let Some(data) = &self.root.proc_macro_data { // If we are loading as a proc macro, we want to return // the view of this crate as a proc macro crate. if id == CRATE_DEF_INDEX { - for child_index in data.macros.decode(self) { - yield self.get_mod_child(child_index, sess); + for child_index in data.macros.decode((self, tcx)) { + yield self.get_mod_child(tcx, child_index); } } } else { // Iterate over all children. - let non_reexports = self.root.tables.module_children_non_reexports.get(self, id); - for child_index in non_reexports.unwrap().decode(self) { - yield self.get_mod_child(child_index, sess); + let non_reexports = + self.root.tables.module_children_non_reexports.get((self, tcx), id); + for child_index in non_reexports.unwrap().decode((self, tcx)) { + yield self.get_mod_child(tcx, child_index); } - let reexports = self.root.tables.module_children_reexports.get(self, id); + let reexports = self.root.tables.module_children_reexports.get((self, tcx), id); if !reexports.is_default() { - for reexport in reexports.decode((self, sess)) { + for reexport in reexports.decode((self, tcx)) { yield reexport; } } @@ -1369,46 +1278,51 @@ impl<'a> CrateMetadataRef<'a> { } } - fn is_ctfe_mir_available(self, id: DefIndex) -> bool { - self.root.tables.mir_for_ctfe.get(self, id).is_some() + fn is_ctfe_mir_available(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool { + self.root.tables.mir_for_ctfe.get((self, tcx), id).is_some() } - fn is_item_mir_available(self, id: DefIndex) -> bool { - self.root.tables.optimized_mir.get(self, id).is_some() + fn is_item_mir_available(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool { + self.root.tables.optimized_mir.get((self, tcx), id).is_some() } - fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool { + fn get_fn_has_self_parameter(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool { self.root .tables .fn_arg_idents - .get(self, id) + .get((self, tcx), id) .expect("argument names not encoded for a function") - .decode((self, sess)) + .decode((self, tcx)) .nth(0) .is_some_and(|ident| matches!(ident, Some(Ident { name: kw::SelfLower, .. }))) } - fn get_associated_item_or_field_def_ids(self, id: DefIndex) -> impl Iterator { + fn get_associated_item_or_field_def_ids( + self, + tcx: TyCtxt<'_>, + id: DefIndex, + ) -> impl Iterator { self.root .tables .associated_item_or_field_def_ids - .get(self, id) + .get((self, tcx), id) .unwrap_or_else(|| self.missing("associated_item_or_field_def_ids", id)) - .decode(self) + .decode((self, tcx)) .map(move |child_index| self.local_def_id(child_index)) } - fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem { - let kind = match self.def_kind(id) { + fn get_associated_item(self, tcx: TyCtxt<'_>, id: DefIndex) -> ty::AssocItem { + let kind = match self.def_kind(tcx, id) { DefKind::AssocConst => ty::AssocKind::Const { name: self.item_name(id) }, DefKind::AssocFn => ty::AssocKind::Fn { name: self.item_name(id), - has_self: self.get_fn_has_self_parameter(id, sess), + has_self: self.get_fn_has_self_parameter(tcx, id), }, DefKind::AssocTy => { - let data = if let Some(rpitit_info) = self.root.tables.opt_rpitit_info.get(self, id) + let data = if let Some(rpitit_info) = + self.root.tables.opt_rpitit_info.get((self, tcx), id) { - ty::AssocTypeData::Rpitit(rpitit_info.decode(self)) + ty::AssocTypeData::Rpitit(rpitit_info.decode((self, tcx))) } else { ty::AssocTypeData::Normal(self.item_name(id)) }; @@ -1416,30 +1330,33 @@ impl<'a> CrateMetadataRef<'a> { } _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)), }; - let container = self.root.tables.assoc_container.get(self, id).unwrap().decode(self); + let container = + self.root.tables.assoc_container.get((self, tcx), id).unwrap().decode((self, tcx)); ty::AssocItem { kind, def_id: self.local_def_id(id), container } } - fn get_ctor(self, node_id: DefIndex) -> Option<(CtorKind, DefId)> { - match self.def_kind(node_id) { + fn get_ctor(self, tcx: TyCtxt<'_>, node_id: DefIndex) -> Option<(CtorKind, DefId)> { + match self.def_kind(tcx, node_id) { DefKind::Struct | DefKind::Variant => { - let vdata = self.root.tables.variant_data.get(self, node_id).unwrap().decode(self); + let vdata = self + .root + .tables + .variant_data + .get((self, tcx), node_id) + .unwrap() + .decode((self, tcx)); vdata.ctor.map(|(kind, index)| (kind, self.local_def_id(index))) } _ => None, } } - fn get_item_attrs( - self, - id: DefIndex, - sess: &'a Session, - ) -> impl Iterator { + fn get_item_attrs(self, tcx: TyCtxt<'_>, id: DefIndex) -> impl Iterator { self.root .tables .attributes - .get(self, id) + .get((self, tcx), id) .unwrap_or_else(|| { // Structure and variant constructors don't have any attributes encoded for them, // but we assume that someone passing a constructor ID actually wants to look at @@ -1450,10 +1367,10 @@ impl<'a> CrateMetadataRef<'a> { self.root .tables .attributes - .get(self, parent_id) + .get((self, tcx), parent_id) .expect("no encoded attributes for a structure or variant") }) - .decode((self, sess)) + .decode((self, tcx)) } fn get_inherent_implementations_for_type<'tcx>( @@ -1465,27 +1382,27 @@ impl<'a> CrateMetadataRef<'a> { self.root .tables .inherent_impls - .get(self, id) - .decode(self) + .get((self, tcx), id) + .decode((self, tcx)) .map(|index| self.local_def_id(index)), ) } /// Decodes all traits in the crate (for rustdoc and rustc diagnostics). - fn get_traits(self) -> impl Iterator { - self.root.traits.decode(self).map(move |index| self.local_def_id(index)) + fn get_traits(self, tcx: TyCtxt<'_>) -> impl Iterator { + self.root.traits.decode((self, tcx)).map(move |index| self.local_def_id(index)) } /// Decodes all trait impls in the crate (for rustdoc). - fn get_trait_impls(self) -> impl Iterator { + fn get_trait_impls(self, tcx: TyCtxt<'_>) -> impl Iterator { self.cdata.trait_impls.values().flat_map(move |impls| { - impls.decode(self).map(move |(impl_index, _)| self.local_def_id(impl_index)) + impls.decode((self, tcx)).map(move |(impl_index, _)| self.local_def_id(impl_index)) }) } fn get_incoherent_impls<'tcx>(self, tcx: TyCtxt<'tcx>, simp: SimplifiedType) -> &'tcx [DefId] { if let Some(impls) = self.cdata.incoherent_impls.get(&simp) { - tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx))) + tcx.arena.alloc_from_iter(impls.decode((self, tcx)).map(|idx| self.local_def_id(idx))) } else { &[] } @@ -1510,7 +1427,7 @@ impl<'a> CrateMetadataRef<'a> { if let Some(impls) = self.trait_impls.get(&key) { tcx.arena.alloc_from_iter( impls - .decode(self) + .decode((self, tcx)) .map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty)), ) } else { @@ -1518,21 +1435,21 @@ impl<'a> CrateMetadataRef<'a> { } } - fn get_native_libraries(self, sess: &'a Session) -> impl Iterator { - self.root.native_libraries.decode((self, sess)) + fn get_native_libraries(self, tcx: TyCtxt<'_>) -> impl Iterator { + self.root.native_libraries.decode((self, tcx)) } - fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span { + fn get_proc_macro_quoted_span(self, tcx: TyCtxt<'_>, index: usize) -> Span { self.root .tables .proc_macro_quoted_spans - .get(self, index) + .get((self, tcx), index) .unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}")) - .decode((self, sess)) + .decode((self, tcx)) } - fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator { - self.root.foreign_modules.decode((self, sess)) + fn get_foreign_modules(self, tcx: TyCtxt<'_>) -> impl Iterator { + self.root.foreign_modules.decode((self, tcx)) } fn get_dylib_dependency_formats<'tcx>( @@ -1540,25 +1457,30 @@ impl<'a> CrateMetadataRef<'a> { tcx: TyCtxt<'tcx>, ) -> &'tcx [(CrateNum, LinkagePreference)] { tcx.arena.alloc_from_iter( - self.root.dylib_dependency_formats.decode(self).enumerate().flat_map(|(i, link)| { - let cnum = CrateNum::new(i + 1); // We skipped LOCAL_CRATE when encoding - link.map(|link| (self.cnum_map[cnum], link)) - }), + self.root.dylib_dependency_formats.decode((self, tcx)).enumerate().flat_map( + |(i, link)| { + let cnum = CrateNum::new(i + 1); // We skipped LOCAL_CRATE when encoding + link.map(|link| (self.cnum_map[cnum], link)) + }, + ), ) } fn get_missing_lang_items<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] { - tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self)) + tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode((self, tcx))) } - fn get_exportable_items(self) -> impl Iterator { - self.root.exportable_items.decode(self).map(move |index| self.local_def_id(index)) + fn get_exportable_items(self, tcx: TyCtxt<'_>) -> impl Iterator { + self.root.exportable_items.decode((self, tcx)).map(move |index| self.local_def_id(index)) } - fn get_stable_order_of_exportable_impls(self) -> impl Iterator { + fn get_stable_order_of_exportable_impls( + self, + tcx: TyCtxt<'_>, + ) -> impl Iterator { self.root .stable_order_of_exportable_impls - .decode(self) + .decode((self, tcx)) .map(move |v| (self.local_def_id(v.0), v.1)) } @@ -1576,12 +1498,17 @@ impl<'a> CrateMetadataRef<'a> { tcx.arena.alloc_from_iter(self.root.exported_generic_symbols.decode((self, tcx))) } - fn get_macro(self, id: DefIndex, sess: &Session) -> ast::MacroDef { - match self.def_kind(id) { + fn get_macro(self, tcx: TyCtxt<'_>, id: DefIndex) -> ast::MacroDef { + match self.def_kind(tcx, id) { DefKind::Macro(_) => { - let macro_rules = self.root.tables.is_macro_rules.get(self, id); - let body = - self.root.tables.macro_definition.get(self, id).unwrap().decode((self, sess)); + let macro_rules = self.root.tables.is_macro_rules.get((self, tcx), id); + let body = self + .root + .tables + .macro_definition + .get((self, tcx), id) + .unwrap() + .decode((self, tcx)); ast::MacroDef { macro_rules, body: Box::new(body) } } _ => bug!(), @@ -1590,11 +1517,9 @@ impl<'a> CrateMetadataRef<'a> { #[inline] fn def_key(self, index: DefIndex) -> DefKey { - *self - .def_key_cache - .lock() - .entry(index) - .or_insert_with(|| self.root.tables.def_keys.get(self, index).unwrap().decode(self)) + *self.def_key_cache.lock().entry(index).or_insert_with(|| { + self.root.tables.def_keys.get(&self.blob, index).unwrap().decode(&self.blob) + }) } // Returns the path leading to the thing with this `id`. @@ -1610,7 +1535,7 @@ impl<'a> CrateMetadataRef<'a> { // relax the Default restriction will likely fix this. let fingerprint = Fingerprint::new( self.root.stable_crate_id.as_u64(), - self.root.tables.def_path_hashes.get(self, index), + self.root.tables.def_path_hashes.get(&self.blob, index), ); DefPathHash::new(self.root.stable_crate_id, fingerprint.split().1) } @@ -1620,9 +1545,13 @@ impl<'a> CrateMetadataRef<'a> { self.def_path_hash_map.def_path_hash_to_def_index(&hash) } - fn expn_hash_to_expn_id(self, sess: &Session, index_guess: u32, hash: ExpnHash) -> ExpnId { + fn expn_hash_to_expn_id(self, tcx: TyCtxt<'_>, index_guess: u32, hash: ExpnHash) -> ExpnId { let index_guess = ExpnIndex::from_u32(index_guess); - let old_hash = self.root.expn_hashes.get(self, index_guess).map(|lazy| lazy.decode(self)); + let old_hash = self + .root + .expn_hashes + .get((self, tcx), index_guess) + .map(|lazy| lazy.decode((self, tcx))); let index = if old_hash == Some(hash) { // Fast path: the expn and its index is unchanged from the @@ -1639,8 +1568,8 @@ impl<'a> CrateMetadataRef<'a> { UnhashMap::with_capacity_and_hasher(end_id as usize, Default::default()); for i in 0..end_id { let i = ExpnIndex::from_u32(i); - if let Some(hash) = self.root.expn_hashes.get(self, i) { - map.insert(hash.decode(self), i); + if let Some(hash) = self.root.expn_hashes.get((self, tcx), i) { + map.insert(hash.decode((self, tcx)), i); } } map @@ -1648,7 +1577,7 @@ impl<'a> CrateMetadataRef<'a> { map[&hash] }; - let data = self.root.expn_data.get(self, index).unwrap().decode((self, sess)); + let data = self.root.expn_data.get((self, tcx), index).unwrap().decode((self, tcx)); rustc_span::hygiene::register_expn_id(self.cnum, index, data, hash) } @@ -1677,9 +1606,9 @@ impl<'a> CrateMetadataRef<'a> { /// /// Proc macro crates don't currently export spans, so this function does not have /// to work for them. - fn imported_source_file(self, source_file_index: u32, sess: &Session) -> ImportedSourceFile { + fn imported_source_file(self, tcx: TyCtxt<'_>, source_file_index: u32) -> ImportedSourceFile { fn filter<'a>( - sess: &Session, + tcx: TyCtxt<'_>, real_source_base_dir: &Option, path: Option<&'a Path>, ) -> Option<&'a Path> { @@ -1687,13 +1616,13 @@ impl<'a> CrateMetadataRef<'a> { // Only spend time on further checks if we have what to translate *to*. real_source_base_dir.is_some() // Some tests need the translation to be always skipped. - && sess.opts.unstable_opts.translate_remapped_path_to_local_path + && tcx.sess.opts.unstable_opts.translate_remapped_path_to_local_path }) .filter(|virtual_dir| { // Don't translate away `/rustc/$hash` if we're still remapping to it, // since that means we're still building `std`/`rustc` that need it, // and we don't want the real path to leak into codegen/debuginfo. - !sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir) + !tcx.sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir) }) } @@ -1702,11 +1631,11 @@ impl<'a> CrateMetadataRef<'a> { real_source_base_dir: &Option, name: &mut rustc_span::FileName| { let virtual_source_base_dir = [ - filter(sess, real_source_base_dir, virtual_source_base_dir.map(Path::new)), + filter(tcx, real_source_base_dir, virtual_source_base_dir.map(Path::new)), filter( - sess, + tcx, real_source_base_dir, - sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref(), + tcx.sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref(), ), ]; @@ -1737,7 +1666,7 @@ impl<'a> CrateMetadataRef<'a> { // https://rust-lang.github.io/rfcs/3127-trim-paths.html#handling-sysroot-paths. // Other imported paths are not currently remapped (see #66251). let (user_remapped, applied) = - sess.source_map().path_mapping().map_prefix(&new_path); + tcx.sess.source_map().path_mapping().map_prefix(&new_path); let new_name = if applied { rustc_span::RealFileName::Remapped { local_path: Some(new_path.clone()), @@ -1756,7 +1685,8 @@ impl<'a> CrateMetadataRef<'a> { real_source_base_dir: &Option, subdir: &str, name: &mut rustc_span::FileName| { - if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base + if let Some(virtual_dir) = + &tcx.sess.opts.unstable_opts.simulate_remapped_rust_src_base && let Some(real_dir) = real_source_base_dir && let rustc_span::FileName::Real(old_name) = name { @@ -1793,9 +1723,9 @@ impl<'a> CrateMetadataRef<'a> { let source_file_to_import = self .root .source_map - .get(self, source_file_index) + .get((self, tcx), source_file_index) .expect("missing source file") - .decode(self); + .decode((self, tcx)); // We can't reuse an existing SourceFile, so allocate a new one // containing the information we need. @@ -1823,7 +1753,7 @@ impl<'a> CrateMetadataRef<'a> { // compiler is bootstrapped. try_to_translate_real_to_virtual( option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"), - &sess.opts.real_rust_source_base_dir, + &tcx.sess.opts.real_rust_source_base_dir, "library", &mut name, ); @@ -1834,7 +1764,7 @@ impl<'a> CrateMetadataRef<'a> { // with `remap-debuginfo = true`. try_to_translate_real_to_virtual( option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"), - &sess.opts.real_rustc_dev_source_base_dir, + &tcx.sess.opts.real_rustc_dev_source_base_dir, "compiler", &mut name, ); @@ -1846,7 +1776,7 @@ impl<'a> CrateMetadataRef<'a> { // the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`. try_to_translate_virtual_to_real( option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"), - &sess.opts.real_rust_source_base_dir, + &tcx.sess.opts.real_rust_source_base_dir, &mut name, ); @@ -1857,11 +1787,11 @@ impl<'a> CrateMetadataRef<'a> { // the `rustc-dev` component in `Src::run` in `src/bootstrap/dist.rs`. try_to_translate_virtual_to_real( option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"), - &sess.opts.real_rustc_dev_source_base_dir, + &tcx.sess.opts.real_rustc_dev_source_base_dir, &mut name, ); - let local_version = sess.source_map().new_imported_source_file( + let local_version = tcx.sess.source_map().new_imported_source_file( name, src_hash, checksum_hash, @@ -1894,35 +1824,40 @@ impl<'a> CrateMetadataRef<'a> { .clone() } - fn get_attr_flags(self, index: DefIndex) -> AttrFlags { - self.root.tables.attr_flags.get(self, index) + fn get_attr_flags(self, tcx: TyCtxt<'_>, index: DefIndex) -> AttrFlags { + self.root.tables.attr_flags.get((self, tcx), index) } - fn get_intrinsic(self, index: DefIndex) -> Option { - self.root.tables.intrinsic.get(self, index).map(|d| d.decode(self)) + fn get_intrinsic(self, tcx: TyCtxt<'_>, index: DefIndex) -> Option { + self.root.tables.intrinsic.get((self, tcx), index).map(|d| d.decode((self, tcx))) } - fn get_doc_link_resolutions(self, index: DefIndex) -> DocLinkResMap { + fn get_doc_link_resolutions(self, tcx: TyCtxt<'_>, index: DefIndex) -> DocLinkResMap { self.root .tables .doc_link_resolutions - .get(self, index) + .get((self, tcx), index) .expect("no resolutions for a doc link") - .decode(self) + .decode((self, tcx)) } - fn get_doc_link_traits_in_scope(self, index: DefIndex) -> impl Iterator { + fn get_doc_link_traits_in_scope( + self, + tcx: TyCtxt<'_>, + index: DefIndex, + ) -> impl Iterator { self.root .tables .doc_link_traits_in_scope - .get(self, index) + .get((self, tcx), index) .expect("no traits in scope for a doc link") - .decode(self) + .decode((self, tcx)) } } impl CrateMetadata { pub(crate) fn new( + tcx: TyCtxt<'_>, cstore: &CStore, blob: MetadataBlob, root: CrateRoot, @@ -1975,8 +1910,10 @@ impl CrateMetadata { cdata.incoherent_impls = cdata .root .incoherent_impls - .decode(cref) - .map(|incoherent_impls| (incoherent_impls.self_ty.decode(cref), incoherent_impls.impls)) + .decode((cref, tcx)) + .map(|incoherent_impls| { + (incoherent_impls.self_ty.decode((cref, tcx)), incoherent_impls.impls) + }) .collect(); cdata @@ -2069,13 +2006,14 @@ impl CrateMetadata { pub(crate) fn proc_macros_for_crate( &self, + tcx: TyCtxt<'_>, krate: CrateNum, cstore: &CStore, ) -> impl Iterator { gen move { for def_id in self.root.proc_macro_data.as_ref().into_iter().flat_map(move |data| { data.macros - .decode(CrateMetadataRef { cdata: self, cstore }) + .decode((CrateMetadataRef { cdata: self, cstore }, tcx)) .map(move |index| DefId { index, krate }) }) { yield def_id; diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 24cfdc05e5cb..ac4faae5a87a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -16,8 +16,8 @@ use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::util::Providers; use rustc_serialize::Decoder; +use rustc_session::StableCrateId; use rustc_session::cstore::{CrateStore, ExternCrate}; -use rustc_session::{Session, StableCrateId}; use rustc_span::hygiene::ExpnId; use rustc_span::{Span, Symbol, kw}; @@ -99,7 +99,7 @@ macro_rules! provide_one { .root .tables .$name - .get($cdata, $def_id.index) + .get(($cdata, $tcx), $def_id.index) .map(|lazy| lazy.decode(($cdata, $tcx))) .process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name))) } @@ -108,7 +108,7 @@ macro_rules! provide_one { ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_defaulted_array }) => { provide_one! { $tcx, $def_id, $other, $cdata, $name => { - let lazy = $cdata.root.tables.$name.get($cdata, $def_id.index); + let lazy = $cdata.root.tables.$name.get(($cdata, $tcx), $def_id.index); let value = if lazy.is_default() { &[] as &[_] } else { @@ -126,7 +126,7 @@ macro_rules! provide_one { .root .tables .$name - .get($cdata, $def_id.index) + .get(($cdata, $tcx), $def_id.index) .process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name))) } } @@ -252,7 +252,7 @@ provide! { tcx, def_id, other, cdata, lookup_default_body_stability => { table } lookup_deprecation_entry => { table } params_in_repr => { table } - def_kind => { cdata.def_kind(def_id.index) } + def_kind => { cdata.def_kind(tcx, def_id.index) } impl_parent => { table } defaultness => { table_direct } constness => { table_direct } @@ -263,7 +263,7 @@ provide! { tcx, def_id, other, cdata, .root .tables .coerce_unsized_info - .get(cdata, def_id.index) + .get((cdata, tcx), def_id.index) .map(|lazy| lazy.decode((cdata, tcx))) .process_decoded(tcx, || panic!("{def_id:?} does not have coerce_unsized_info"))) } mir_const_qualif => { table } @@ -279,7 +279,7 @@ provide! { tcx, def_id, other, cdata, .root .tables .eval_static_initializer - .get(cdata, def_id.index) + .get((cdata, tcx), def_id.index) .map(|lazy| lazy.decode((cdata, tcx))) .unwrap_or_else(|| panic!("{def_id:?} does not have eval_static_initializer"))) } @@ -292,7 +292,7 @@ provide! { tcx, def_id, other, cdata, .root .tables .deduced_param_attrs - .get(cdata, def_id.index) + .get((cdata, tcx), def_id.index) .map(|lazy| { &*tcx.arena.alloc_from_iter(lazy.decode((cdata, tcx))) }) @@ -305,25 +305,25 @@ provide! { tcx, def_id, other, cdata, .root .tables .trait_impl_trait_tys - .get(cdata, def_id.index) + .get((cdata, tcx), def_id.index) .map(|lazy| lazy.decode((cdata, tcx))) .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys"))) } associated_types_for_impl_traits_in_trait_or_impl => { table } - visibility => { cdata.get_visibility(def_id.index) } - adt_def => { cdata.get_adt_def(def_id.index, tcx) } + visibility => { cdata.get_visibility(tcx, def_id.index) } + adt_def => { cdata.get_adt_def(tcx, def_id.index) } adt_destructor => { table } adt_async_destructor => { table } associated_item_def_ids => { - tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index)) + tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(tcx, def_id.index)) } - associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) } + associated_item => { cdata.get_associated_item(tcx, def_id.index) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } - attrs_for_def => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) } - is_mir_available => { cdata.is_item_mir_available(def_id.index) } - is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) } + attrs_for_def => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(tcx, def_id.index)) } + is_mir_available => { cdata.is_item_mir_available(tcx, def_id.index) } + is_ctfe_mir_available => { cdata.is_ctfe_mir_available(tcx, def_id.index) } cross_crate_inlinable => { table_direct } dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) } @@ -355,8 +355,8 @@ provide! { tcx, def_id, other, cdata, reachable_non_generics } - native_libraries => { cdata.get_native_libraries(tcx.sess).collect() } - foreign_modules => { cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect() } + native_libraries => { cdata.get_native_libraries(tcx).collect() } + foreign_modules => { cdata.get_foreign_modules(tcx).map(|m| (m.def_id, m)).collect() } crate_hash => { cdata.root.header.hash } crate_host_hash => { cdata.host_hash } crate_name => { cdata.root.header.name } @@ -364,23 +364,23 @@ provide! { tcx, def_id, other, cdata, extra_filename => { cdata.root.extra_filename.clone() } - traits => { tcx.arena.alloc_from_iter(cdata.get_traits()) } - trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) } + traits => { tcx.arena.alloc_from_iter(cdata.get_traits(tcx)) } + trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls(tcx)) } implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) } crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) } dep_kind => { cdata.dep_kind } module_children => { - tcx.arena.alloc_from_iter(cdata.get_module_children(def_id.index, tcx.sess)) + tcx.arena.alloc_from_iter(cdata.get_module_children(tcx, def_id.index)) } - lib_features => { cdata.get_lib_features() } + lib_features => { cdata.get_lib_features(tcx) } stability_implications => { cdata.get_stability_implications(tcx).iter().copied().collect() } - stripped_cfg_items => { cdata.get_stripped_cfg_items(cdata.cnum, tcx) } - intrinsic_raw => { cdata.get_intrinsic(def_id.index) } + stripped_cfg_items => { cdata.get_stripped_cfg_items(tcx, cdata.cnum) } + intrinsic_raw => { cdata.get_intrinsic(tcx, def_id.index) } defined_lang_items => { cdata.get_lang_items(tcx) } - diagnostic_items => { cdata.get_diagnostic_items() } + diagnostic_items => { cdata.get_diagnostic_items(tcx) } missing_lang_items => { cdata.get_missing_lang_items(tcx) } missing_extern_crate_item => { @@ -388,20 +388,20 @@ provide! { tcx, def_id, other, cdata, } used_crate_source => { Arc::clone(&cdata.source) } - debugger_visualizers => { cdata.get_debugger_visualizers() } + debugger_visualizers => { cdata.get_debugger_visualizers(tcx) } - exportable_items => { tcx.arena.alloc_from_iter(cdata.get_exportable_items()) } - stable_order_of_exportable_impls => { tcx.arena.alloc(cdata.get_stable_order_of_exportable_impls().collect()) } + exportable_items => { tcx.arena.alloc_from_iter(cdata.get_exportable_items(tcx)) } + stable_order_of_exportable_impls => { tcx.arena.alloc(cdata.get_stable_order_of_exportable_impls(tcx).collect()) } exported_non_generic_symbols => { cdata.exported_non_generic_symbols(tcx) } exported_generic_symbols => { cdata.exported_generic_symbols(tcx) } crate_extern_paths => { cdata.source().paths().cloned().collect() } - expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) } - default_field => { cdata.get_default_field(def_id.index) } - is_doc_hidden => { cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) } - doc_link_resolutions => { tcx.arena.alloc(cdata.get_doc_link_resolutions(def_id.index)) } + expn_that_defined => { cdata.get_expn_that_defined(tcx, def_id.index) } + default_field => { cdata.get_default_field(tcx, def_id.index) } + is_doc_hidden => { cdata.get_attr_flags(tcx,def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) } + doc_link_resolutions => { tcx.arena.alloc(cdata.get_doc_link_resolutions(tcx, def_id.index)) } doc_link_traits_in_scope => { - tcx.arena.alloc_from_iter(cdata.get_doc_link_traits_in_scope(def_id.index)) + tcx.arena.alloc_from_iter(cdata.get_doc_link_traits_in_scope(tcx, def_id.index)) } anon_const_kind => { table } const_of_item => { table } @@ -551,38 +551,38 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { } impl CStore { - pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> { - self.get_crate_data(def.krate).get_ctor(def.index) + pub fn ctor_untracked(&self, tcx: TyCtxt<'_>, def: DefId) -> Option<(CtorKind, DefId)> { + self.get_crate_data(def.krate).get_ctor(tcx, def.index) } - pub fn load_macro_untracked(&self, id: DefId, tcx: TyCtxt<'_>) -> LoadedMacro { + pub fn load_macro_untracked(&self, tcx: TyCtxt<'_>, id: DefId) -> LoadedMacro { let sess = tcx.sess; let _prof_timer = sess.prof.generic_activity("metadata_load_macro"); let data = self.get_crate_data(id.krate); if data.root.is_proc_macro_crate() { - LoadedMacro::ProcMacro(data.load_proc_macro(id.index, tcx)) + LoadedMacro::ProcMacro(data.load_proc_macro(tcx, id.index)) } else { LoadedMacro::MacroDef { - def: data.get_macro(id.index, sess), - ident: data.item_ident(id.index, sess), - attrs: data.get_item_attrs(id.index, sess).collect(), - span: data.get_span(id.index, sess), + def: data.get_macro(tcx, id.index), + ident: data.item_ident(tcx, id.index), + attrs: data.get_item_attrs(tcx, id.index).collect(), + span: data.get_span(tcx, id.index), edition: data.root.edition, } } } - pub fn def_span_untracked(&self, def_id: DefId, sess: &Session) -> Span { - self.get_crate_data(def_id.krate).get_span(def_id.index, sess) + pub fn def_span_untracked(&self, tcx: TyCtxt<'_>, def_id: DefId) -> Span { + self.get_crate_data(def_id.krate).get_span(tcx, def_id.index) } - pub fn def_kind_untracked(&self, def: DefId) -> DefKind { - self.get_crate_data(def.krate).def_kind(def.index) + pub fn def_kind_untracked(&self, tcx: TyCtxt<'_>, def: DefId) -> DefKind { + self.get_crate_data(def.krate).def_kind(tcx, def.index) } - pub fn expn_that_defined_untracked(&self, def_id: DefId, sess: &Session) -> ExpnId { - self.get_crate_data(def_id.krate).get_expn_that_defined(def_id.index, sess) + pub fn expn_that_defined_untracked(&self, tcx: TyCtxt<'_>, def_id: DefId) -> ExpnId { + self.get_crate_data(def_id.krate).get_expn_that_defined(tcx, def_id.index) } /// Only public-facing way to traverse all the definitions in a non-local crate. @@ -594,20 +594,20 @@ impl CStore { pub fn get_proc_macro_quoted_span_untracked( &self, + tcx: TyCtxt<'_>, cnum: CrateNum, id: usize, - sess: &Session, ) -> Span { - self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess) + self.get_crate_data(cnum).get_proc_macro_quoted_span(tcx, id) } - pub fn set_used_recursively(&mut self, cnum: CrateNum) { + pub fn set_used_recursively(&mut self, tcx: TyCtxt<'_>, cnum: CrateNum) { let cmeta = self.get_crate_data_mut(cnum); if !cmeta.used { cmeta.used = true; let dependencies = mem::take(&mut cmeta.dependencies); for &dep_cnum in &dependencies { - self.set_used_recursively(dep_cnum); + self.set_used_recursively(tcx, dep_cnum); } self.get_crate_data_mut(cnum).dependencies = dependencies; } @@ -700,13 +700,13 @@ fn provide_cstore_hooks(providers: &mut Providers) { providers.hooks.expn_hash_to_expn_id = |tcx, cnum, index_guess, hash| { let cstore = CStore::from_tcx(tcx); - cstore.get_crate_data(cnum).expn_hash_to_expn_id(tcx.sess, index_guess, hash) + cstore.get_crate_data(cnum).expn_hash_to_expn_id(tcx, index_guess, hash) }; providers.hooks.import_source_files = |tcx, cnum| { let cstore = CStore::from_tcx(tcx); let cdata = cstore.get_crate_data(cnum); for file_index in 0..cdata.root.source_map.size() { - cdata.imported_source_file(file_index as u32, tcx.sess); + cdata.imported_source_file(tcx, file_index as u32); } }; } diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index aaaed76bda9d..3b5a38181d58 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -1,7 +1,7 @@ use rustc_hir::def::CtorOf; use rustc_index::Idx; -use crate::rmeta::decoder::BlobMetadata; +use crate::rmeta::decoder::Metadata; use crate::rmeta::*; pub(super) trait IsDefault: Default { @@ -523,11 +523,7 @@ where for<'tcx> T::Value<'tcx>: FixedSizeEncoding, { /// Given the metadata, extract out the value at a particular index (if any). - pub(super) fn get<'a, 'tcx, M: BlobMetadata<'a, 'tcx>>( - &self, - metadata: M, - i: I, - ) -> T::Value<'tcx> { + pub(super) fn get<'a, 'tcx, M: Metadata<'a>>(&self, metadata: M, i: I) -> T::Value<'tcx> { // Access past the end of the table returns a Default if i.index() >= self.len { return Default::default(); diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index cd12d5ad10cf..26658aef3359 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -141,7 +141,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // Query `def_kind` is not used because query system overhead is too expensive here. - let def_kind = self.cstore().def_kind_untracked(def_id); + let def_kind = self.cstore().def_kind_untracked(self.tcx, def_id); if def_kind.is_module_like() { let parent = self .tcx @@ -149,7 +149,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .map(|parent_id| self.get_nearest_non_block_module(parent_id)); // Query `expn_that_defined` is not used because // hashing spans in its result is expensive. - let expn_id = self.cstore().expn_that_defined_untracked(def_id, self.tcx.sess); + let expn_id = self.cstore().expn_that_defined_untracked(self.tcx, def_id); return Some(self.new_extern_module( parent, ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))), @@ -196,7 +196,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match def_id.as_local() { Some(local_def_id) => self.local_macro_map[&local_def_id], None => *self.extern_macro_map.borrow_mut().entry(def_id).or_insert_with(|| { - let loaded_macro = self.cstore().load_macro_untracked(def_id, self.tcx); + let loaded_macro = self.cstore().load_macro_untracked(self.tcx, def_id); let macro_data = match loaded_macro { LoadedMacro::MacroDef { def, ident, attrs, span, edition } => { self.compile_macro(&def, ident, &attrs, span, ast::DUMMY_NODE_ID, edition) @@ -213,7 +213,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// find them for suggestions. pub(crate) fn register_macros_for_all_crates(&mut self) { if !self.all_crate_macros_already_registered { - for def_id in self.cstore().all_proc_macro_def_ids() { + for def_id in self.cstore().all_proc_macro_def_ids(self.tcx) { self.get_macro_by_def_id(def_id); } self.all_crate_macros_already_registered = true; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index f59b5a0aad9a..e38d4370d5d2 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1235,7 +1235,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let struct_ctor = match def_id.as_local() { Some(def_id) => self.struct_constructors.get(&def_id).cloned(), None => { - let ctor = self.cstore().ctor_untracked(def_id); + let ctor = self.cstore().ctor_untracked(self.tcx(), def_id); ctor.map(|(ctor_kind, ctor_def_id)| { let ctor_res = Res::Def( DefKind::Ctor(rustc_hir::def::CtorOf::Struct, ctor_kind), diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3ab6c7dcc006..71baef458bbf 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2024,7 +2024,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let struct_ctor = match def_id.as_local() { Some(def_id) => self.r.struct_constructors.get(&def_id).cloned(), None => { - let ctor = self.r.cstore().ctor_untracked(def_id); + let ctor = self.r.cstore().ctor_untracked(self.r.tcx(), def_id); ctor.map(|(ctor_kind, ctor_def_id)| { let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ed47f3124f93..35d54615772b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2316,7 +2316,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match def_id.as_local() { Some(def_id) => self.tcx.source_span(def_id), // Query `def_span` is not used because hashing its result span is expensive. - None => self.cstore().def_span_untracked(def_id, self.tcx.sess), + None => self.cstore().def_span_untracked(self.tcx(), def_id), } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 10a0078547ad..6bba985d87dd 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -477,7 +477,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span { - self.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.tcx.sess) + self.cstore().get_proc_macro_quoted_span_untracked(self.tcx, krate, id) } fn declare_proc_macro(&mut self, id: NodeId) { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 189d3a70ad62..849df566b4bd 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -239,7 +239,7 @@ pub(crate) fn get_item_path(tcx: TyCtxt<'_>, def_id: DefId, kind: ItemType) -> V // Check to see if it is a macro 2.0 or built-in macro // More information in . if matches!( - CStore::from_tcx(tcx).load_macro_untracked(def_id, tcx), + CStore::from_tcx(tcx).load_macro_untracked(tcx, def_id), LoadedMacro::MacroDef { def, .. } if !def.macro_rules ) { once(crate_name).chain(relative).collect() @@ -772,7 +772,7 @@ fn build_macro( name: Symbol, macro_kinds: MacroKinds, ) -> clean::ItemKind { - match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) { + match CStore::from_tcx(cx.tcx).load_macro_untracked(cx.tcx, def_id) { // FIXME: handle attributes and derives that aren't proc macros, and macros with multiple // kinds LoadedMacro::MacroDef { def, .. } => match macro_kinds { From 8c7889bd18a93a7c82db0dcdf6c661594a5a8093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 1 Dec 2025 11:48:22 +0100 Subject: [PATCH 0406/3801] document various traits --- compiler/rustc_macros/src/lib.rs | 79 +++++++++++++++++--- compiler/rustc_macros/src/serialize.rs | 2 +- compiler/rustc_metadata/src/locator.rs | 1 - compiler/rustc_metadata/src/rmeta/decoder.rs | 12 ++- compiler/rustc_metadata/src/rmeta/mod.rs | 13 ++-- compiler/rustc_span/src/lib.rs | 14 ++++ 6 files changed, 97 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 9f55143ecf53..8cd6c0264448 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -72,25 +72,80 @@ decl_derive!( hash_stable::hash_stable_no_context_derive ); -decl_derive!([Decodable_NoContext] => serialize::decodable_nocontext_derive); +// Encoding and Decoding derives +decl_derive!([Decodable_NoContext] => + /// See docs on derive [`Decodable`]. + /// + /// Derives `Decodable for T where D: Decoder`. + serialize::decodable_nocontext_derive +); decl_derive!([Encodable_NoContext] => serialize::encodable_nocontext_derive); -decl_derive!([Decodable] => serialize::decodable_derive); +decl_derive!([Decodable] => + /// Derives `Decodable for T where D: SpanDecoder` + /// + /// # Deriving decoding traits + /// + /// > Some shared docs about decoding traits, since this is likely the first trait you find + /// + /// The difference between these derives can be subtle! + /// At a high level, there's the `T: Decodable` trait that says some type `T` + /// can be decoded using a decoder `D`. There are various decoders! + /// The different derives place different *trait* bounds on this type `D`. + /// + /// Even though this derive, based on its name, seems like the most vanilla one, + /// it actually places a pretty strict bound on `D`: `SpanDecoder`. + /// It means that types that derive this can contain spans, among other things, + /// and still be decoded. The reason this is hard is that at least in metadata, + /// spans can only be decoded later, once some information from the header + /// is already decoded to properly deal with spans. + /// + /// The hierarchy is roughly: + /// + /// - derive [`Decodable_NoContext`] is the most relaxed bounds that could be placed on `D`, + /// and is only really suited for structs and enums containing primitive types. + /// - derive [`BlobDecodable`] may be a better default, than deriving `Decodable`: + /// it places fewer requirements on `D`, while still allowing some complex types to be decoded. + /// - derive [`LazyDecodable`]: Only for types containing `Lazy{Array,Table,Value}`. + /// - derive [`Decodable`] for structures containing spans. Requires `D: SpanDecoder` + /// - derive [`TyDecodable`] for types that require access to the `TyCtxt` while decoding. + /// For example: arena allocated types. + serialize::decodable_derive +); decl_derive!([Encodable] => serialize::encodable_derive); -decl_derive!([TyDecodable] => serialize::type_decodable_derive); +decl_derive!([TyDecodable] => + /// See docs on derive [`Decodable`]. + /// + /// Derives `Decodable for T where D: TyDecoder`. + serialize::type_decodable_derive +); decl_derive!([TyEncodable] => serialize::type_encodable_derive); -decl_derive!([MetadataDecodable] => - /// This constrains the decoder to be specifically the decoder that can decode LazyArrays in metadata. - /// Therefore, we only use this on things containing LazyArray really. - /// Anything else should either be `NoContext`, if possible `BlobDecodable`, or otherwise just `Decodable`. - serialize::meta_decodable_derive +decl_derive!([LazyDecodable] => + /// See docs on derive [`Decodable`]. + /// + /// Derives `Decodable for T where D: LazyDecoder`. + /// This constrains the decoder to be specifically the decoder that can decode + /// `LazyArray`s, `LazyValue`s amd `LazyTable`s in metadata. + /// Therefore, we only need this on things containing LazyArray really. + /// + /// Most decodable derives mirror an encodable derive. + /// [`LazyDecodable`] and [`BlobDecodable`] together roughly mirror [`MetadataEncodable`] + serialize::lazy_decodable_derive ); decl_derive!([BlobDecodable] => - /// For anything that is "simple" to decode, without needing anything but the original data, - /// but for which the Decoder can customize some things - /// (unlike Decodable_NoContext which individual decoders can't customize). + /// See docs on derive [`Decodable`]. + /// + /// Derives `Decodable for T where D: BlobDecoder`. + /// + /// Most decodable derives mirror an encodable derive. + /// [`LazyDecodable`] and [`BlobDecodable`] together roughly mirror [`MetadataEncodable`] serialize::blob_decodable_derive ); -decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive); +decl_derive!([MetadataEncodable] => + /// Most encodable derives mirror a decodable derive. + /// [`MetadataEncodable`] is roughly mirrored by the combination of [`LazyDecodable`] and [`BlobDecodable`] + serialize::meta_encodable_derive +); + decl_derive!( [TypeFoldable, attributes(type_foldable)] => /// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported). diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index abf566288df4..5ae6fb241c98 100644 --- a/compiler/rustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs @@ -26,7 +26,7 @@ pub(super) fn blob_decodable_derive( decodable_body(s, decoder_ty) } -pub(super) fn meta_decodable_derive( +pub(super) fn lazy_decodable_derive( mut s: synstructure::Structure<'_>, ) -> proc_macro2::TokenStream { let decoder_ty = quote! { __D }; diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 6a441706a22b..9fef22f9558d 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -224,7 +224,6 @@ use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned}; use rustc_data_structures::svh::Svh; use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_fs_util::try_canonicalize; -use rustc_middle::ty::TyCtxt; use rustc_session::cstore::CrateSource; use rustc_session::filesearch::FileSearch; use rustc_session::search_paths::PathKind; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index df0d1b7d085f..bf7818b49933 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -155,15 +155,20 @@ struct ImportedSourceFile { translated_source_file: Arc, } -/// Decode context used when we just have a blob, -/// and we still have to read the header etc. +/// Decode context used when we just have a blob of metadata from which we have to decode a header +/// and [`CrateRoot`]. After that, [`MetadataDecodeContext`] can be used. +/// Most notably, [`BlobDecodeContext]` doesn't implement [`SpanDecoder`] pub(super) struct BlobDecodeContext<'a> { opaque: MemDecoder<'a>, blob: &'a MetadataBlob, lazy_state: LazyState, } -/// trait for anything containing `LazyState` and is a decoder. +/// This trait abstracts over decoders that can decode lazy values using [`LazyState`]: +/// +/// - [`LazyValue`] +/// - [`LazyArray`] +/// - [`LazyTable`] pub(super) trait LazyDecoder: BlobDecoder { fn set_lazy_state(&mut self, state: LazyState); fn get_lazy_state(&self) -> LazyState; @@ -210,6 +215,7 @@ impl<'a> LazyDecoder for BlobDecodeContext<'a> { /// This is the decode context used when crate metadata was already read. /// Decoding of some types, like `Span` require some information to already been read. +/// Can be constructed from a [`TyCtxt`] and [`CrateMetadataRef`] (see the [`Metadata`] trait) pub(super) struct MetadataDecodeContext<'a, 'tcx> { blob_decoder: BlobDecodeContext<'a>, cdata: CrateMetadataRef<'a>, diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index b1b9bcfcc506..8ac1dd83ee5d 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -19,8 +19,7 @@ use rustc_hir::{PreciseCapturingArgKind, attrs}; use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet; use rustc_macros::{ - BlobDecodable, Decodable, Encodable, MetadataDecodable, MetadataEncodable, TyDecodable, - TyEncodable, + BlobDecodable, Decodable, Encodable, LazyDecodable, MetadataEncodable, TyDecodable, TyEncodable, }; use rustc_middle::metadata::ModChild; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; @@ -188,7 +187,7 @@ type SyntaxContextTable = LazyTable>>; type ExpnDataTable = LazyTable>>; type ExpnHashTable = LazyTable>>; -#[derive(MetadataEncodable, MetadataDecodable)] +#[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct ProcMacroData { proc_macro_decls_static: DefIndex, stability: Option, @@ -237,7 +236,7 @@ pub(crate) struct CrateHeader { /// compilation session. If we were to serialize a proc-macro crate like /// a normal crate, much of what we serialized would be unusable in addition /// to being unused. -#[derive(MetadataEncodable, MetadataDecodable)] +#[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct CrateRoot { /// A header used to detect if this is the right crate to load. header: CrateHeader, @@ -334,13 +333,13 @@ pub(crate) struct CrateDep { pub is_private: bool, } -#[derive(MetadataEncodable, MetadataDecodable)] +#[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct TraitImpls { trait_id: (u32, DefIndex), impls: LazyArray<(DefIndex, Option)>, } -#[derive(MetadataEncodable, MetadataDecodable)] +#[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct IncoherentImpls { self_ty: LazyValue, impls: LazyArray, @@ -352,7 +351,7 @@ macro_rules! define_tables { - defaulted: $($name1:ident: Table<$IDX1:ty, $T1:ty>,)+ - optional: $($name2:ident: Table<$IDX2:ty, $T2:ty>,)+ ) => { - #[derive(MetadataEncodable, MetadataDecodable)] + #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct LazyTables { $($name1: LazyTable<$IDX1, $T1>,)+ $($name2: LazyTable<$IDX2, Option<$T2>>,)+ diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index c6490b358ef8..6a359c5f4656 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1304,6 +1304,20 @@ pub trait BlobDecoder: Decoder { /// This trait is used to allow decoder specific encodings of certain types. /// It is similar to rustc_type_ir's TyDecoder. +/// +/// Specifically for metadata, an important note is that spans can only be decoded once +/// some other metadata is already read. +/// Spans have to be properly mapped into the decoding crate's sourcemap, +/// and crate numbers have to be converted sometimes. +/// This can only be done once the `CrateRoot` is available. +/// +/// As such, some methods that used to be in the `SpanDecoder` trait +/// are now in the `BlobDecoder` trait. This hierarchy is not mirrored for `Encoder`s. +/// `BlobDecoder` has methods for deserializing types that are more complex than just those +/// that can be decoded with `Decoder`, but which can be decoded on their own, *before* any other metadata is. +/// Importantly, that means that types that can be decoded with `BlobDecoder` can show up in the crate root. +/// The place where this distinction is relevant is in `rustc_metadata` where metadata is decoded using either the +/// `MetadataDecodeContext` or the `BlobDecodeContext`. pub trait SpanDecoder: BlobDecoder { fn decode_span(&mut self) -> Span; fn decode_expn_id(&mut self) -> ExpnId; From d40aad9c2daa6d9b4d0475747cfe5183ff76e187 Mon Sep 17 00:00:00 2001 From: benodiwal Date: Mon, 8 Dec 2025 11:57:31 +0530 Subject: [PATCH 0407/3801] fix: updated to use hir-def representation --- src/tools/rust-analyzer/crates/hir/src/display.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index afdac484a117..d0d8c4877d21 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir/src/display.rs @@ -192,9 +192,10 @@ fn write_impl_header<'db>(impl_: &Impl, f: &mut HirFormatter<'_, 'db>) -> Result let def_id = GenericDefId::ImplId(impl_.id); write_generic_params(def_id, f)?; - if let Some(trait_ref) = impl_.trait_ref(db) { + let impl_data = db.impl_signature(impl_.id); + if let Some(target_trait) = &impl_data.target_trait { f.write_char(' ')?; - trait_ref.hir_fmt(f)?; + hir_display_with_store(&impl_data.store[target_trait.path], &impl_data.store).hir_fmt(f)?; f.write_str(" for")?; } From 260b1ffc2cc6e2b83c68e6357417022db262f511 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Mon, 8 Dec 2025 09:37:11 +0800 Subject: [PATCH 0408/3801] compiletest: require `host`/`target` flags specified Instead of allowing them to be missing and using some placeholder "(none)" value instead. --- src/tools/compiletest/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index f3bd467db3e4..625d839dece1 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -255,7 +255,9 @@ fn parse_config(args: Vec) -> Config { } } - let target = opt_str2(matches.opt_str("target")); + let host = matches.opt_str("host").expect("`--host` must be unconditionally specified"); + let target = matches.opt_str("target").expect("`--target` must be unconditionally specified"); + let android_cross_path = matches.opt_str("android-cross-path").map(Utf8PathBuf::from); // FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config! let cdb = debuggers::discover_cdb(matches.opt_str("cdb"), &target); @@ -433,7 +435,7 @@ fn parse_config(args: Vec) -> Config { optimize_tests: matches.opt_present("optimize-tests"), rust_randomized_layout: matches.opt_present("rust-randomized-layout"), target, - host: opt_str2(matches.opt_str("host")), + host, cdb, cdb_version, gdb, From a7ad2142e35a1aa7e51b052b9ffad83e653e6340 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Mon, 8 Dec 2025 09:38:31 +0800 Subject: [PATCH 0409/3801] compiletest: make presence/absence of adb-related options clear Instead of possibly falling back to "(none)" when they are not specified. --- src/tools/compiletest/src/lib.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 625d839dece1..cd875d78f231 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -259,6 +259,13 @@ fn parse_config(args: Vec) -> Config { let target = matches.opt_str("target").expect("`--target` must be unconditionally specified"); let android_cross_path = matches.opt_str("android-cross-path").map(Utf8PathBuf::from); + + // FIXME: `adb_path` should be an `Option`... + let adb_path = matches.opt_str("adb-path").map(Utf8PathBuf::from).unwrap_or_default(); + // FIXME: `adb_test_dir` should be an `Option`... + let adb_test_dir = matches.opt_str("adb-test-dir").map(Utf8PathBuf::from).unwrap_or_default(); + let adb_device_status = target.contains("android") && !adb_test_dir.as_str().is_empty(); + // FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config! let cdb = debuggers::discover_cdb(matches.opt_str("cdb"), &target); let cdb_version = cdb.as_deref().and_then(debuggers::query_cdb_version); @@ -445,11 +452,9 @@ fn parse_config(args: Vec) -> Config { llvm_version, system_llvm: matches.opt_present("system-llvm"), android_cross_path, - adb_path: Utf8PathBuf::from(opt_str2(matches.opt_str("adb-path"))), - adb_test_dir: Utf8PathBuf::from(opt_str2(matches.opt_str("adb-test-dir"))), - adb_device_status: opt_str2(matches.opt_str("target")).contains("android") - && "(none)" != opt_str2(matches.opt_str("adb-test-dir")) - && !opt_str2(matches.opt_str("adb-test-dir")).is_empty(), + adb_path, + adb_test_dir, + adb_device_status, verbose: matches.opt_present("verbose"), only_modified: matches.opt_present("only-modified"), color, From 72541e9a511f4844000ca42a60516eddb2bfa892 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Mon, 8 Dec 2025 09:41:46 +0800 Subject: [PATCH 0410/3801] compiletest: retire `opt_str2` We either have the value of a flag specified, or we don't. Use `Option<...>` to represent that -- don't invent a new "(none)" sentinel value... --- src/tools/compiletest/src/lib.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index cd875d78f231..ff4cd81d33ff 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -500,13 +500,6 @@ fn parse_config(args: Vec) -> Config { } } -fn opt_str2(maybestr: Option) -> String { - match maybestr { - None => "(none)".to_owned(), - Some(s) => s, - } -} - /// Called by `main` after the config has been parsed. fn run_tests(config: Arc) { debug!(?config, "run_tests"); From 29d4cbafa418c9546546d8867bdd07afa8fbcda3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 09:46:16 +0000 Subject: [PATCH 0411/3801] Rustup to rustc 1.94.0-nightly (ba2142a19 2025-12-07) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 4bbbc12cdd0b..461dbcdb0fb5 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-11-28" +channel = "nightly-2025-12-08" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" From 942a08b559714576ee97bb2f4001f20547de427d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 8 Dec 2025 10:48:42 +0100 Subject: [PATCH 0412/3801] Revert "early return on duplicate span lowerings" This reverts commit 0087253015d1191b97b5e312c2409e008db87ed6. --- compiler/rustc_ast_lowering/src/lib.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ab5caff86204..dff46ece6543 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -225,13 +225,6 @@ struct SpanLowerer { impl SpanLowerer { fn lower(&self, span: Span) -> Span { if self.is_incremental { - // early return: span lowering takes some time since it accesses the query dependency graph - // to make sure we rerun the right code paths when spans change. When we've already lowered a span, - // or don't have to, bail out ASAP. - if span.is_dummy() || span.parent().is_some_and(|i| i == self.def_id) { - return span; - } - span.with_parent(Some(self.def_id)) } else { // Do not make spans relative when not using incremental compilation. From 5139ab431ff1d9a21f9ce0505e33642e79107d93 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 09:55:17 +0000 Subject: [PATCH 0413/3801] Fix rustc testsuite --- src/lib.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 5fdecd014ac0..b47b9afa4f07 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,7 +47,7 @@ use rustc_codegen_ssa::{CodegenResults, TargetConfig}; use rustc_log::tracing::info; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; -use rustc_session::config::OutputFilenames; +use rustc_session::config::{OutputFilenames, PrintKind, PrintRequest}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{Abi, Arch, Env, Os}; @@ -160,6 +160,16 @@ impl CodegenBackend for CraneliftCodegenBackend { } } + fn print(&self, req: &PrintRequest, out: &mut String, _sess: &Session) { + match req.kind { + // FIXME have a default impl that returns false + PrintKind::BackendHasZstd => { + out.push_str("false\n"); + } + _ => {} + } + } + fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] let target_features = match sess.target.arch { From 3c55c98ec86765fb8d0b877ae293f19a62e51d66 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Mon, 8 Dec 2025 10:08:32 +0000 Subject: [PATCH 0414/3801] replace version placeholder --- compiler/rustc_feature/src/accepted.rs | 6 ++--- compiler/rustc_feature/src/removed.rs | 2 +- compiler/rustc_feature/src/unstable.rs | 4 +-- .../alloc/src/collections/vec_deque/mod.rs | 4 +-- library/alloc/src/fmt.rs | 2 +- library/alloc/src/string.rs | 2 +- library/alloc/src/vec/mod.rs | 2 +- library/core/src/char/methods.rs | 4 +-- library/core/src/fmt/builders.rs | 8 +++--- library/core/src/fmt/mod.rs | 2 +- library/core/src/mem/maybe_uninit.rs | 16 ++++++------ library/core/src/num/int_macros.rs | 12 ++++----- library/core/src/num/uint_macros.rs | 8 +++--- library/core/src/ptr/const_ptr.rs | 4 +-- library/core/src/ptr/mut_ptr.rs | 4 +-- library/core/src/slice/mod.rs | 8 +++--- library/core/src/time.rs | 4 +-- library/std/src/lib.rs | 2 +- library/std_detect/src/detect/arch/mod.rs | 2 +- library/std_detect/src/detect/arch/s390x.rs | 26 +++++++++---------- 20 files changed, 61 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 7e765918d7b6..13c1f2219bed 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -61,7 +61,7 @@ declare_features! ( /// Allows explicit discriminants on non-unit enum variants. (accepted, arbitrary_enum_discriminant, "1.66.0", Some(60553)), /// Allows #[cfg(...)] on inline assembly templates and operands. - (accepted, asm_cfg, "CURRENT_RUSTC_VERSION", Some(140364)), + (accepted, asm_cfg, "1.93.0", Some(140364)), /// Allows using `const` operands in inline assembly. (accepted, asm_const, "1.82.0", Some(93332)), /// Allows using `label` operands in inline assembly. @@ -218,7 +218,7 @@ declare_features! ( /// Allows access to crate names passed via `--extern` through prelude. (accepted, extern_prelude, "1.30.0", Some(44660)), /// Allows using `system` as a calling convention with varargs. - (accepted, extern_system_varargs, "CURRENT_RUSTC_VERSION", Some(136946)), + (accepted, extern_system_varargs, "1.93.0", Some(136946)), /// Allows using F16C intrinsics from `core::arch::{x86, x86_64}`. (accepted, f16c_target_feature, "1.68.0", Some(44839)), /// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions. @@ -392,7 +392,7 @@ declare_features! ( /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414). (accepted, rvalue_static_promotion, "1.21.0", Some(38865)), /// Allows use of the `vector` and related s390x target features. - (accepted, s390x_target_feature_vector, "CURRENT_RUSTC_VERSION", Some(145649)), + (accepted, s390x_target_feature_vector, "1.93.0", Some(145649)), /// Allows `Self` in type definitions (RFC 2300). (accepted, self_in_typedefs, "1.32.0", Some(49303)), /// Allows `Self` struct constructor (RFC 2302). diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index cd61facb39bb..e5d66364c2a6 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -190,7 +190,7 @@ declare_features! ( /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8 (removed, negate_unsigned, "1.0.0", Some(29645), None), /// Allows diverging expressions to fall back to `!` rather than `()`. - (removed, never_type_fallback, "CURRENT_RUSTC_VERSION", Some(65992), Some("removed in favor of unconditional fallback"), 148871), + (removed, never_type_fallback, "1.93.0", Some(65992), Some("removed in favor of unconditional fallback"), 148871), /// Allows `#[no_coverage]` on functions. /// The feature was renamed to `coverage_attribute` and the attribute to `#[coverage(on|off)]` (removed, no_coverage, "1.74.0", Some(84605), Some("renamed to `coverage_attribute`"), 114656), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 3ef4eb00c354..5880af0909bf 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -410,7 +410,7 @@ declare_features! ( (unstable, c_variadic, "1.34.0", Some(44930)), /// Allows defining c-variadic naked functions with any extern ABI that is allowed /// on c-variadic foreign functions. - (unstable, c_variadic_naked_functions, "CURRENT_RUSTC_VERSION", Some(148767)), + (unstable, c_variadic_naked_functions, "1.93.0", Some(148767)), /// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled. (unstable, cfg_contract_checks, "1.86.0", Some(128044)), /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. @@ -484,7 +484,7 @@ declare_features! ( /// Allows deriving the From trait on single-field structs. (unstable, derive_from, "1.91.0", Some(144889)), /// Allows giving non-const impls custom diagnostic messages if attempted to be used as const - (unstable, diagnostic_on_const, "CURRENT_RUSTC_VERSION", Some(143874)), + (unstable, diagnostic_on_const, "1.93.0", Some(143874)), /// Allows `#[doc(cfg(...))]`. (unstable, doc_cfg, "1.21.0", Some(43781)), /// Allows `#[doc(masked)]`. diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index ea9d5b128ebe..0e01d0d19e7a 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2053,7 +2053,7 @@ impl VecDeque { /// assert_eq!(deque, [1, 2, 3, 4]); /// assert_eq!(deque.pop_front_if(pred), None); /// ``` - #[stable(feature = "vec_deque_pop_if", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_deque_pop_if", since = "1.93.0")] pub fn pop_front_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option { let first = self.front_mut()?; if predicate(first) { self.pop_front() } else { None } @@ -2075,7 +2075,7 @@ impl VecDeque { /// assert_eq!(deque, [0, 1, 2, 3]); /// assert_eq!(deque.pop_back_if(pred), None); /// ``` - #[stable(feature = "vec_deque_pop_if", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_deque_pop_if", since = "1.93.0")] pub fn pop_back_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option { let last = self.back_mut()?; if predicate(last) { self.pop_back() } else { None } diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 4d6fe220a09a..3d7c580be8c9 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -602,7 +602,7 @@ pub use core::fmt::{DebugAsHex, FormattingOptions, Sign}; pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{Formatter, Result, Write}; -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] pub use core::fmt::{FromFn, from_fn}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{LowerExp, UpperExp}; diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index f5ba71c28833..78ab4b4bbadd 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -937,7 +937,7 @@ impl String { /// assert_eq!(rebuilt, "hello"); /// ``` #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "vec_into_raw_parts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_into_raw_parts", since = "1.93.0")] pub fn into_raw_parts(self) -> (*mut u8, usize, usize) { self.vec.into_raw_parts() } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 2adce8d27039..d397e1ed313e 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -781,7 +781,7 @@ impl Vec { /// assert_eq!(rebuilt, [4294967295, 0, 1]); /// ``` #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "vec_into_raw_parts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_into_raw_parts", since = "1.93.0")] pub fn into_raw_parts(self) -> (*mut T, usize, usize) { let mut me = ManuallyDrop::new(self); (me.as_mut_ptr(), me.len(), me.capacity()) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index d1de2c560615..89cb06972392 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -74,12 +74,12 @@ impl char { /// The maximum number of bytes required to [encode](char::encode_utf8) a `char` to /// UTF-8 encoding. - #[stable(feature = "char_max_len_assoc", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "char_max_len_assoc", since = "1.93.0")] pub const MAX_LEN_UTF8: usize = 4; /// The maximum number of two-byte units required to [encode](char::encode_utf16) a `char` /// to UTF-16 encoding. - #[stable(feature = "char_max_len_assoc", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "char_max_len_assoc", since = "1.93.0")] pub const MAX_LEN_UTF16: usize = 2; /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index 4ea6c6ba8fb9..197cddd3fa9d 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -1226,7 +1226,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// assert_eq!(format!("{}", wrapped), "'a'"); /// assert_eq!(format!("{:?}", wrapped), "'a'"); /// ``` -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] #[must_use = "returns a type implementing Debug and Display, which do not have any effects unless they are used"] pub fn from_fn) -> fmt::Result>(f: F) -> FromFn { FromFn(f) @@ -1235,10 +1235,10 @@ pub fn from_fn) -> fmt::Result>(f: F) -> FromFn /// Implements [`fmt::Debug`] and [`fmt::Display`] via the provided closure. /// /// Created with [`from_fn`]. -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] pub struct FromFn(F); -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] impl fmt::Debug for FromFn where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, @@ -1248,7 +1248,7 @@ where } } -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] impl fmt::Display for FromFn where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 7a80023ce64e..e20109c3cc9a 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -41,7 +41,7 @@ pub use num_buffer::{NumBuffer, NumBufferTrait}; #[stable(feature = "debug_builders", since = "1.2.0")] pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] pub use self::builders::{FromFn, from_fn}; /// The type returned by formatter methods. diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index e00cf45fcab2..cff6c0457d02 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -1140,8 +1140,8 @@ impl [MaybeUninit] { /// ``` /// /// [`write_clone_of_slice`]: slice::write_clone_of_slice - #[stable(feature = "maybe_uninit_write_slice", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "maybe_uninit_write_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_write_slice", since = "1.93.0")] + #[rustc_const_stable(feature = "maybe_uninit_write_slice", since = "1.93.0")] pub const fn write_copy_of_slice(&mut self, src: &[T]) -> &mut [T] where T: Copy, @@ -1201,7 +1201,7 @@ impl [MaybeUninit] { /// ``` /// /// [`write_copy_of_slice`]: slice::write_copy_of_slice - #[stable(feature = "maybe_uninit_write_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_write_slice", since = "1.93.0")] pub fn write_clone_of_slice(&mut self, src: &[T]) -> &mut [T] where T: Clone, @@ -1463,7 +1463,7 @@ impl [MaybeUninit] { /// requirement the compiler knows about it is that the data pointer must be /// non-null. Dropping such a `Vec` however will cause undefined /// behaviour. - #[stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_slice", since = "1.93.0")] #[inline(always)] #[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")] pub const unsafe fn assume_init_drop(&mut self) @@ -1485,8 +1485,8 @@ impl [MaybeUninit] { /// Calling this when the content is not yet fully initialized causes undefined /// behavior: it is up to the caller to guarantee that every `MaybeUninit` in /// the slice really is in an initialized state. - #[stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_slice", since = "1.93.0")] + #[rustc_const_stable(feature = "maybe_uninit_slice", since = "1.93.0")] #[inline(always)] pub const unsafe fn assume_init_ref(&self) -> &[T] { // SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that @@ -1504,8 +1504,8 @@ impl [MaybeUninit] { /// behavior: it is up to the caller to guarantee that every `MaybeUninit` in the /// slice really is in an initialized state. For instance, `.assume_init_mut()` cannot /// be used to initialize a `MaybeUninit` slice. - #[stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_slice", since = "1.93.0")] + #[rustc_const_stable(feature = "maybe_uninit_slice", since = "1.93.0")] #[inline(always)] pub const unsafe fn assume_init_mut(&mut self) -> &mut [T] { // SAFETY: similar to safety notes for `slice_get_ref`, but we have a diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 99662768a29f..bc451197289e 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1275,8 +1275,8 @@ macro_rules! int_impl { /// i.e. when [`checked_neg`] would return `None`. /// #[doc = concat!("[`checked_neg`]: ", stringify!($SelfT), "::checked_neg")] - #[stable(feature = "unchecked_neg", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_neg", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_neg", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_neg", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -1392,8 +1392,8 @@ macro_rules! int_impl { /// i.e. when [`checked_shl`] would return `None`. /// #[doc = concat!("[`checked_shl`]: ", stringify!($SelfT), "::checked_shl")] - #[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_shifts", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_shifts", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -1564,8 +1564,8 @@ macro_rules! int_impl { /// i.e. when [`checked_shr`] would return `None`. /// #[doc = concat!("[`checked_shr`]: ", stringify!($SelfT), "::checked_shr")] - #[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_shifts", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_shifts", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index c8224e92b17e..64adeda35288 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1851,8 +1851,8 @@ macro_rules! uint_impl { /// i.e. when [`checked_shl`] would return `None`. /// #[doc = concat!("[`checked_shl`]: ", stringify!($SelfT), "::checked_shl")] - #[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_shifts", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_shifts", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -2020,8 +2020,8 @@ macro_rules! uint_impl { /// i.e. when [`checked_shr`] would return `None`. /// #[doc = concat!("[`checked_shr`]: ", stringify!($SelfT), "::checked_shr")] - #[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_shifts", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_shifts", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 2860bf0a6e69..00b71f9a997c 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1462,8 +1462,8 @@ impl *const [T] { /// Gets a raw pointer to the underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "core_slice_as_array", since = "1.93.0")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")] #[inline] #[must_use] pub const fn as_array(self) -> Option<*const [T; N]> { diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index f8dc6ef7ed71..8976154c61db 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1712,8 +1712,8 @@ impl *mut [T] { /// Gets a raw, mutable pointer to the underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "core_slice_as_array", since = "1.93.0")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")] #[inline] #[must_use] pub const fn as_mut_array(self) -> Option<*mut [T; N]> { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f03f2045444d..edc31c04ef9b 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -842,8 +842,8 @@ impl [T] { /// Gets a reference to the underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "core_slice_as_array", since = "1.93.0")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")] #[inline] #[must_use] pub const fn as_array(&self) -> Option<&[T; N]> { @@ -861,8 +861,8 @@ impl [T] { /// Gets a mutable reference to the slice's underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "core_slice_as_array", since = "1.93.0")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")] #[inline] #[must_use] pub const fn as_mut_array(&mut self) -> Option<&mut [T; N]> { diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 51a01545f5cf..20895c988c45 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -325,8 +325,8 @@ impl Duration { /// assert_eq!(10_u64.pow(15), duration.as_secs()); /// assert_eq!(321, duration.subsec_nanos()); /// ``` - #[stable(feature = "duration_from_nanos_u128", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "duration_from_nanos_u128", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "duration_from_nanos_u128", since = "1.93.0")] + #[rustc_const_stable(feature = "duration_from_nanos_u128", since = "1.93.0")] #[must_use] #[inline] #[track_caller] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 0401e9b39ff4..4f8094dc1f2f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -668,7 +668,7 @@ pub mod arch { pub use std_detect::is_loongarch_feature_detected; #[unstable(feature = "is_riscv_feature_detected", issue = "111192")] pub use std_detect::is_riscv_feature_detected; - #[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "stdarch_s390x_feature_detection", since = "1.93.0")] pub use std_detect::is_s390x_feature_detected; #[stable(feature = "simd_x86", since = "1.27.0")] pub use std_detect::is_x86_feature_detected; diff --git a/library/std_detect/src/detect/arch/mod.rs b/library/std_detect/src/detect/arch/mod.rs index 23e7a30b985b..2be7f091c285 100644 --- a/library/std_detect/src/detect/arch/mod.rs +++ b/library/std_detect/src/detect/arch/mod.rs @@ -60,7 +60,7 @@ cfg_select! { pub use loongarch::*; } target_arch = "s390x" => { - #[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "stdarch_s390x_feature_detection", since = "1.93.0")] pub use s390x::*; } _ => { diff --git a/library/std_detect/src/detect/arch/s390x.rs b/library/std_detect/src/detect/arch/s390x.rs index 6122e8f5b837..a04283f90a02 100644 --- a/library/std_detect/src/detect/arch/s390x.rs +++ b/library/std_detect/src/detect/arch/s390x.rs @@ -9,7 +9,7 @@ features! { /// /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) /// the macro expands to `true`. - #[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "stdarch_s390x_feature_detection", since = "1.93.0")] @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] concurrent_functions: "concurrent-functions"; /// s390x concurrent-functions facility @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] deflate_conversion: "deflate-conversion"; @@ -32,30 +32,30 @@ features! { /// s390x message-security-assist-extension9 facility @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension12: "message-security-assist-extension12"; /// s390x message-security-assist-extension12 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; /// s390x miscellaneous-extensions-2 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; /// s390x miscellaneous-extensions-3 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; /// s390x miscellaneous-extensions-4 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] nnp_assist: "nnp-assist"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] nnp_assist: "nnp-assist"; /// s390x nnp-assist facility @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] transactional_execution: "transactional-execution"; /// s390x transactional-execution facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector: "vector"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector: "vector"; /// s390x vector facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_1: "vector-enhancements-1"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_enhancements_1: "vector-enhancements-1"; /// s390x vector-enhancements-1 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_2: "vector-enhancements-2"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_enhancements_2: "vector-enhancements-2"; /// s390x vector-enhancements-2 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_3: "vector-enhancements-3"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_enhancements_3: "vector-enhancements-3"; /// s390x vector-enhancements-3 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal: "vector-packed-decimal"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_packed_decimal: "vector-packed-decimal"; /// s390x vector-packed-decimal facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement"; /// s390x vector-packed-decimal-enhancement facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2"; /// s390x vector-packed-decimal-enhancement-2 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3"; /// s390x vector-packed-decimal-enhancement-3 facility } From f80e3ac62471499664d0317cf4c54d4c258037d5 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Mon, 8 Dec 2025 10:08:52 +0000 Subject: [PATCH 0415/3801] bump channel --- src/ci/channel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/channel b/src/ci/channel index bf867e0ae5b6..65b2df87f7df 100644 --- a/src/ci/channel +++ b/src/ci/channel @@ -1 +1 @@ -nightly +beta From fd6e372a97fd63907ac87826ea1567e5d2c01c20 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:13:25 +0000 Subject: [PATCH 0416/3801] Fix Cirrus CI --- .cirrus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cirrus.yml b/.cirrus.yml index 3ed89beceb7f..9be095dbf2d8 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,7 +1,7 @@ task: name: freebsd freebsd_instance: - image_family: freebsd-14-2 + image_family: freebsd-15-0-amd64-ufs setup_rust_script: - pkg install -y git-tiny binutils - curl https://sh.rustup.rs -sSf --output rustup.sh From ba27d3d8a68534ee2f418cce3cfaa0f5b0d79d90 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:09:16 +0000 Subject: [PATCH 0417/3801] Fix gimli assertion for anonymous sources --- src/debuginfo/line_info.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index 6fe22f5c6dd9..a6ffe6c2bf39 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -117,8 +117,7 @@ impl DebugContext { } filename => { // For anonymous sources, create an empty directory instead of using the default - let empty_dir = LineString::new(b"", line_program.encoding(), line_strings); - let dir_id = line_program.add_directory(empty_dir); + let dir_id = line_program.default_directory(); let dummy_file_name = LineString::new( filename.prefer_remapped_unconditionally().to_string().into_bytes(), From 8b0e6756e0c40e5f64cf356344e593c02a982d4a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:09:50 +0000 Subject: [PATCH 0418/3801] Only generate line tables with -Cdebuginfo=line-table-only --- src/debuginfo/line_info.rs | 6 +--- src/debuginfo/mod.rs | 59 +++++++++++++++++++++++++------------- src/debuginfo/types.rs | 3 +- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index a6ffe6c2bf39..db58ee890911 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -5,7 +5,7 @@ use std::path::{Component, Path}; use cranelift_codegen::MachSrcLoc; use cranelift_codegen::binemit::CodeOffset; -use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable}; +use gimli::write::{FileId, FileInfo, LineProgram, LineString, LineStringTable}; use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene}; use crate::debuginfo::FunctionDebugContext; @@ -175,10 +175,6 @@ impl FunctionDebugContext { assert_ne!(func_end, 0); - let entry = debug_context.dwarf.unit.get_mut(self.entry_id); - entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); - entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end))); - func_end } } diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 494002f525c8..8c43db92fe05 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -42,14 +42,14 @@ pub(crate) struct DebugContext { created_files: FxHashMap<(StableSourceFileId, SourceFileHash), FileId>, stack_pointer_register: Register, namespace_map: DefIdMap, - array_size_type: UnitEntryId, + array_size_type: Option, filename_display_preference: FileNameDisplayPreference, embed_source: bool, } pub(crate) struct FunctionDebugContext { - entry_id: UnitEntryId, + entry_id: Option, function_source_loc: (FileId, u64, u64), source_loc_set: IndexSet<(FileId, u64, u64)>, } @@ -154,18 +154,23 @@ impl DebugContext { root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } - let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type); - let array_size_type_entry = dwarf.unit.get_mut(array_size_type); - array_size_type_entry.set( - gimli::DW_AT_name, - AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")), - ); - array_size_type_entry - .set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned)); - array_size_type_entry.set( - gimli::DW_AT_byte_size, - AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), - ); + let array_size_type = if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly { + None + } else { + let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type); + let array_size_type_entry = dwarf.unit.get_mut(array_size_type); + array_size_type_entry.set( + gimli::DW_AT_name, + AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")), + ); + array_size_type_entry + .set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned)); + array_size_type_entry.set( + gimli::DW_AT_byte_size, + AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), + ); + Some(array_size_type) + }; Some(DebugContext { endian, @@ -217,6 +222,14 @@ impl DebugContext { ) -> FunctionDebugContext { let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span); + if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly { + return FunctionDebugContext { + entry_id: None, + function_source_loc: (file_id, line, column), + source_loc_set: IndexSet::new(), + }; + } + let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); let mut name = String::new(); @@ -274,7 +287,7 @@ impl DebugContext { } FunctionDebugContext { - entry_id, + entry_id: Some(entry_id), function_source_loc: (file_id, line, column), source_loc_set: IndexSet::new(), } @@ -288,6 +301,10 @@ impl DebugContext { def_id: DefId, data_id: DataId, ) { + if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly { + return; + } + let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() }; if nested { return; @@ -353,10 +370,12 @@ impl FunctionDebugContext { .0 .push(Range::StartLength { begin: address_for_func(func_id), length: u64::from(end) }); - let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id); - // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. - func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); - // Using Udata for DW_AT_high_pc requires at least DWARF4 - func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); + if let Some(entry_id) = self.entry_id { + let entry = debug_context.dwarf.unit.get_mut(entry_id); + // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. + entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); + // Using Udata for DW_AT_high_pc requires at least DWARF4 + entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); + } } } diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs index a292429cdfad..18a0632a0939 100644 --- a/src/debuginfo/types.rs +++ b/src/debuginfo/types.rs @@ -109,7 +109,8 @@ impl DebugContext { let subrange_id = self.dwarf.unit.add(array_type_id, gimli::DW_TAG_subrange_type); let subrange_entry = self.dwarf.unit.get_mut(subrange_id); - subrange_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type)); + subrange_entry + .set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type.unwrap())); subrange_entry.set(gimli::DW_AT_lower_bound, AttributeValue::Udata(0)); subrange_entry.set(gimli::DW_AT_count, AttributeValue::Udata(len)); From 8c582e1f530b967dcbf2a549f70fce08819da3a1 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 7 Dec 2025 15:27:50 +1100 Subject: [PATCH 0419/3801] Don't require `test::Coverage` to implement Ord This derive was an artifact of test-only method `Cache::all` wanting to automatically sort its output to hide HashMap iteration order. We can achieve an equivalent result by requiring the caller to provide a projection function that returns results that _are_ sortable. --- src/bootstrap/src/core/build_steps/test.rs | 2 +- src/bootstrap/src/core/builder/tests.rs | 3 +-- src/bootstrap/src/utils/cache.rs | 20 +++++++++++--------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 09c98bd7c88b..67cd5b8d67c3 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1582,7 +1582,7 @@ test!(AssemblyLlvm { /// Runs the coverage test suite at `tests/coverage` in some or all of the /// coverage test modes. -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Coverage { pub compiler: Compiler, pub target: TargetSelection, diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index b8ba1b4c2c34..965b75f24c20 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -345,8 +345,7 @@ fn test_test_coverage() { let config = configure_with_args(cmd, &[], &[TEST_TRIPLE_1]); let mut cache = run_build(&config.paths.clone(), config); - let modes = - cache.all::().iter().map(|(step, ())| step.mode).collect::>(); + let modes = cache.inspect_all_steps_of_type::(|step, ()| step.mode); assert_eq!(modes, expected); } } diff --git a/src/bootstrap/src/utils/cache.rs b/src/bootstrap/src/utils/cache.rs index 5098e2f03c43..8c5b3529979d 100644 --- a/src/bootstrap/src/utils/cache.rs +++ b/src/bootstrap/src/utils/cache.rs @@ -270,16 +270,18 @@ impl Cache { #[cfg(test)] impl Cache { - pub fn all(&mut self) -> Vec<(S, S::Output)> { - let cache = self.cache.get_mut(); - let type_id = TypeId::of::(); - let mut v = cache - .remove(&type_id) - .map(|b| b.downcast::>().expect("correct type")) - .map(|m| m.into_iter().collect::>()) + pub(crate) fn inspect_all_steps_of_type( + &self, + map_fn: impl Fn(&S, &S::Output) -> T, + ) -> Vec { + let cache = self.cache.borrow(); + let mut values = cache + .get(&TypeId::of::()) + .map(|any| any.downcast_ref::>().expect("correct type")) + .map(|m| m.iter().map(|(step, output)| map_fn(step, output)).collect::>()) .unwrap_or_default(); - v.sort_by_key(|(s, _)| s.clone()); - v + values.sort(); + values } pub fn contains(&self) -> bool { From dc8cdb1c00da2649fb7ff56b56af11b4e9592802 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 7 Dec 2025 15:14:26 +1100 Subject: [PATCH 0420/3801] Use a `CompiletestMode` enum in bootstrap --- src/bootstrap/src/core/build_steps/test.rs | 116 +++++++++++------- .../src/core/build_steps/test/compiletest.rs | 71 +++++++++++ src/bootstrap/src/core/builder/tests.rs | 3 +- 3 files changed, 142 insertions(+), 48 deletions(-) create mode 100644 src/bootstrap/src/core/build_steps/test/compiletest.rs diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 67cd5b8d67c3..a699cd23fb60 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3,6 +3,9 @@ //! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules. //! However, this contains ~all test parts we expect people to be able to build and run locally. +// (This file should be split up, but having tidy block all changes is not helpful.) +// ignore-tidy-filelength + use std::collections::HashSet; use std::env::split_paths; use std::ffi::{OsStr, OsString}; @@ -17,6 +20,7 @@ use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags}; use crate::core::build_steps::llvm::get_llvm_version; use crate::core::build_steps::run::{get_completion_paths, get_help_path}; use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget; +use crate::core::build_steps::test::compiletest::CompiletestMode; use crate::core::build_steps::tool::{ self, RustcPrivateCompilers, SourceType, TEST_FLOAT_PARSE_ALLOW_FEATURES, Tool, ToolTargetBuildMode, get_tool_target_compiler, @@ -39,6 +43,8 @@ use crate::utils::helpers::{ use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests}; use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, envify}; +mod compiletest; + /// Runs `cargo test` on various internal tools used by bootstrap. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateBootstrap { @@ -1085,7 +1091,7 @@ impl Step for RustdocJSNotStd { builder.ensure(Compiletest { test_compiler: self.compiler, target: self.target, - mode: "rustdoc-js", + mode: CompiletestMode::RustdocJs, suite: "rustdoc-js", path: "tests/rustdoc-js", compare_mode: None, @@ -1478,7 +1484,7 @@ macro_rules! test { builder.ensure(Compiletest { test_compiler: self.test_compiler, target: self.target, - mode: $mode, + mode: const { $mode }, suite: $suite, path: $path, compare_mode: (const { @@ -1493,34 +1499,39 @@ macro_rules! test { }; } -test!(Ui { path: "tests/ui", mode: "ui", suite: "ui", default: true }); +test!(Ui { path: "tests/ui", mode: CompiletestMode::Ui, suite: "ui", default: true }); -test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes", default: true }); +test!(Crashes { + path: "tests/crashes", + mode: CompiletestMode::Crashes, + suite: "crashes", + default: true, +}); test!(CodegenLlvm { path: "tests/codegen-llvm", - mode: "codegen", + mode: CompiletestMode::Codegen, suite: "codegen-llvm", default: true }); test!(CodegenUnits { path: "tests/codegen-units", - mode: "codegen-units", + mode: CompiletestMode::CodegenUnits, suite: "codegen-units", default: true, }); test!(Incremental { path: "tests/incremental", - mode: "incremental", + mode: CompiletestMode::Incremental, suite: "incremental", default: true, }); test!(Debuginfo { path: "tests/debuginfo", - mode: "debuginfo", + mode: CompiletestMode::Debuginfo, suite: "debuginfo", default: true, compare_mode: Some("split-dwarf"), @@ -1528,7 +1539,7 @@ test!(Debuginfo { test!(UiFullDeps { path: "tests/ui-fulldeps", - mode: "ui", + mode: CompiletestMode::Ui, suite: "ui-fulldeps", default: true, IS_HOST: true, @@ -1536,14 +1547,14 @@ test!(UiFullDeps { test!(Rustdoc { path: "tests/rustdoc", - mode: "rustdoc", + mode: CompiletestMode::Rustdoc, suite: "rustdoc", default: true, IS_HOST: true, }); test!(RustdocUi { path: "tests/rustdoc-ui", - mode: "ui", + mode: CompiletestMode::Ui, suite: "rustdoc-ui", default: true, IS_HOST: true, @@ -1551,7 +1562,7 @@ test!(RustdocUi { test!(RustdocJson { path: "tests/rustdoc-json", - mode: "rustdoc-json", + mode: CompiletestMode::RustdocJson, suite: "rustdoc-json", default: true, IS_HOST: true, @@ -1559,23 +1570,28 @@ test!(RustdocJson { test!(Pretty { path: "tests/pretty", - mode: "pretty", + mode: CompiletestMode::Pretty, suite: "pretty", default: true, IS_HOST: true, }); -test!(RunMake { path: "tests/run-make", mode: "run-make", suite: "run-make", default: true }); +test!(RunMake { + path: "tests/run-make", + mode: CompiletestMode::RunMake, + suite: "run-make", + default: true, +}); test!(RunMakeCargo { path: "tests/run-make-cargo", - mode: "run-make", + mode: CompiletestMode::RunMake, suite: "run-make-cargo", default: true }); test!(AssemblyLlvm { path: "tests/assembly-llvm", - mode: "assembly", + mode: CompiletestMode::Assembly, suite: "assembly-llvm", default: true }); @@ -1586,13 +1602,14 @@ test!(AssemblyLlvm { pub struct Coverage { pub compiler: Compiler, pub target: TargetSelection, - pub mode: &'static str, + pub(crate) mode: CompiletestMode, } impl Coverage { const PATH: &'static str = "tests/coverage"; const SUITE: &'static str = "coverage"; - const ALL_MODES: &[&str] = &["coverage-map", "coverage-run"]; + const ALL_MODES: &[CompiletestMode] = + &[CompiletestMode::CoverageMap, CompiletestMode::CoverageRun]; } impl Step for Coverage { @@ -1608,7 +1625,7 @@ impl Step for Coverage { // - `./x test coverage-run -- tests/coverage/trivial.rs` run = run.suite_path(Self::PATH); for mode in Self::ALL_MODES { - run = run.alias(mode); + run = run.alias(mode.as_str()); } run } @@ -1631,15 +1648,15 @@ impl Step for Coverage { for path in &run.paths { match path { PathSet::Set(_) => { - for mode in Self::ALL_MODES { - if path.assert_single_path().path == Path::new(mode) { + for &mode in Self::ALL_MODES { + if path.assert_single_path().path == Path::new(mode.as_str()) { modes.push(mode); break; } } } PathSet::Suite(_) => { - modes.extend(Self::ALL_MODES); + modes.extend_from_slice(Self::ALL_MODES); break; } } @@ -1647,7 +1664,9 @@ impl Step for Coverage { // Skip any modes that were explicitly skipped/excluded on the command-line. // FIXME(Zalathar): Integrate this into central skip handling somehow? - modes.retain(|mode| !run.builder.config.skip.iter().any(|skip| skip == Path::new(mode))); + modes.retain(|mode| { + !run.builder.config.skip.iter().any(|skip| skip == Path::new(mode.as_str())) + }); // FIXME(Zalathar): Make these commands skip all coverage tests, as expected: // - `./x test --skip=tests` @@ -1678,7 +1697,7 @@ impl Step for Coverage { test!(CoverageRunRustdoc { path: "tests/coverage-run-rustdoc", - mode: "coverage-run", + mode: CompiletestMode::CoverageRun, suite: "coverage-run-rustdoc", default: true, IS_HOST: true, @@ -1712,7 +1731,7 @@ impl Step for MirOpt { builder.ensure(Compiletest { test_compiler: self.compiler, target, - mode: "mir-opt", + mode: CompiletestMode::MirOpt, suite: "mir-opt", path: "tests/mir-opt", compare_mode: None, @@ -1755,7 +1774,7 @@ struct Compiletest { /// The compiler that we're testing. test_compiler: Compiler, target: TargetSelection, - mode: &'static str, + mode: CompiletestMode, suite: &'static str, path: &'static str, compare_mode: Option<&'static str>, @@ -1791,7 +1810,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let suite_path = self.path; // Skip codegen tests if they aren't enabled in configuration. - if !builder.config.codegen_tests && mode == "codegen" { + if !builder.config.codegen_tests && mode == CompiletestMode::Codegen { return; } @@ -1829,7 +1848,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the target, }); } - if mode == "run-make" { + if mode == CompiletestMode::RunMake { builder.tool_exe(Tool::RunMakeSupport); } @@ -1886,7 +1905,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // suites, `run-make` and `run-make-cargo`. That way, contributors who do not need to run // the `run-make` tests that need in-tree cargo do not need to spend time building in-tree // cargo. - if mode == "run-make" { + if mode == CompiletestMode::RunMake { // We need to pass the compiler that was used to compile run-make-support, // because we have to use the same compiler to compile rmake.rs recipes. let stage0_rustc_path = builder.compiler(0, test_compiler.host); @@ -1910,17 +1929,18 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } // Avoid depending on rustdoc when we don't need it. - if mode == "rustdoc" - || mode == "run-make" - || (mode == "ui" && is_rustdoc) - || mode == "rustdoc-js" - || mode == "rustdoc-json" - || suite == "coverage-run-rustdoc" + if matches!( + mode, + CompiletestMode::RunMake + | CompiletestMode::Rustdoc + | CompiletestMode::RustdocJs + | CompiletestMode::RustdocJson + ) || matches!(suite, "rustdoc-ui" | "coverage-run-rustdoc") { cmd.arg("--rustdoc-path").arg(builder.rustdoc_for_compiler(test_compiler)); } - if mode == "rustdoc-json" { + if mode == CompiletestMode::RustdocJson { // Use the stage0 compiler for jsondocck let json_compiler = builder.compiler(0, builder.host_target); cmd.arg("--jsondocck-path") @@ -1930,7 +1950,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the ); } - if matches!(mode, "coverage-map" | "coverage-run") { + if matches!(mode, CompiletestMode::CoverageMap | CompiletestMode::CoverageRun) { let coverage_dump = builder.tool_exe(Tool::CoverageDump); cmd.arg("--coverage-dump-path").arg(coverage_dump); } @@ -1957,7 +1977,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--sysroot-base").arg(sysroot); cmd.arg("--suite").arg(suite); - cmd.arg("--mode").arg(mode); + cmd.arg("--mode").arg(mode.as_str()); cmd.arg("--target").arg(target.rustc_target_arg()); cmd.arg("--host").arg(&*test_compiler.host.triple); cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target)); @@ -2036,7 +2056,7 @@ Please disable assertions with `rust.debug-assertions = false`. if let Some(ref nodejs) = builder.config.nodejs { cmd.arg("--nodejs").arg(nodejs); - } else if mode == "rustdoc-js" { + } else if mode == CompiletestMode::RustdocJs { panic!("need nodejs to run rustdoc-js suite"); } if builder.config.rust_optimize_tests { @@ -2055,7 +2075,7 @@ Please disable assertions with `rust.debug-assertions = false`. let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] }; flags.push(format!( "-Cdebuginfo={}", - if mode == "codegen" { + if mode == CompiletestMode::Codegen { // codegen tests typically check LLVM IR and are sensitive to additional debuginfo. // So do not apply `rust.debuginfo-level-tests` for codegen tests. if builder.config.rust_debuginfo_level_tests @@ -2122,7 +2142,7 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--android-cross-path").arg(android_cross_path); } - if mode == "debuginfo" { + if mode == CompiletestMode::Debuginfo { if let Some(debuggers::Gdb { gdb }) = debuggers::discover_gdb(builder, android.as_ref()) { cmd.arg("--gdb").arg(gdb.as_ref()); @@ -2155,7 +2175,7 @@ Please disable assertions with `rust.debug-assertions = false`. // in rustdoc-js mode, allow filters to be rs files or js files. // use a late-initialized Vec to avoid cloning for other modes. let mut paths_v; - if mode == "rustdoc-js" { + if mode == CompiletestMode::RustdocJs { paths_v = paths.to_vec(); for p in &mut paths_v { if let Some(ext) = p.extension() @@ -2237,7 +2257,9 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--host-rustcflags").arg(link_llvm); } - if !builder.config.dry_run() && matches!(mode, "run-make" | "coverage-run") { + if !builder.config.dry_run() + && matches!(mode, CompiletestMode::RunMake | CompiletestMode::CoverageRun) + { // The llvm/bin directory contains many useful cross-platform // tools. Pass the path to run-make tests so they can use them. // (The coverage-run tests also need these tools to process @@ -2249,7 +2271,7 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--llvm-bin-dir").arg(llvm_bin_path); } - if !builder.config.dry_run() && mode == "run-make" { + if !builder.config.dry_run() && mode == CompiletestMode::RunMake { // If LLD is available, add it to the PATH if builder.config.lld_enabled { let lld_install_root = @@ -2269,7 +2291,7 @@ Please disable assertions with `rust.debug-assertions = false`. // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. - if !builder.config.dry_run() && mode == "run-make" { + if !builder.config.dry_run() && mode == CompiletestMode::RunMake { let mut cflags = builder.cc_handled_clags(target, CLang::C); cflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C)); let mut cxxflags = builder.cc_handled_clags(target, CLang::Cxx); @@ -2385,7 +2407,7 @@ Please disable assertions with `rust.debug-assertions = false`. builder.metrics.begin_test_suite( build_helper::metrics::TestSuiteMetadata::Compiletest { suite: suite.into(), - mode: mode.into(), + mode: mode.to_string(), compare_mode: None, target: self.target.triple.to_string(), host: self.test_compiler.host.triple.to_string(), @@ -2408,7 +2430,7 @@ Please disable assertions with `rust.debug-assertions = false`. builder.metrics.begin_test_suite( build_helper::metrics::TestSuiteMetadata::Compiletest { suite: suite.into(), - mode: mode.into(), + mode: mode.to_string(), compare_mode: Some(compare_mode.into()), target: self.target.triple.to_string(), host: self.test_compiler.host.triple.to_string(), diff --git a/src/bootstrap/src/core/build_steps/test/compiletest.rs b/src/bootstrap/src/core/build_steps/test/compiletest.rs new file mode 100644 index 000000000000..359f6bb1a6ef --- /dev/null +++ b/src/bootstrap/src/core/build_steps/test/compiletest.rs @@ -0,0 +1,71 @@ +use std::fmt; + +/// Enum of all the "test modes" understood by compiletest. +/// +/// Some of these mode names happen to overlap with the names of test suite +/// directories, but the relationship between modes and suites is not 1:1. +/// For example: +/// - Mode `ui` is used by suites `tests/ui` and `tests/rustdoc-ui` +/// - Suite `tests/coverage` uses modes `coverage-map` and `coverage-run` +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) enum CompiletestMode { + // tidy-alphabetical-start + Assembly, + Codegen, + CodegenUnits, + CoverageMap, + CoverageRun, + Crashes, + Debuginfo, + Incremental, + MirOpt, + Pretty, + RunMake, + Rustdoc, + RustdocJs, + RustdocJson, + Ui, + // tidy-alphabetical-end +} + +impl CompiletestMode { + /// Returns a string representing this mode, which can be passed to + /// compiletest via a command-line argument. + /// + /// These mode names must be kept in sync with the ones understood by + /// compiletest's `TestMode`, but they change so rarely that doing so + /// manually should not be burdensome. + pub(crate) const fn as_str(self) -> &'static str { + match self { + // tidy-alphabetical-start + Self::Assembly => "assembly", + Self::Codegen => "codegen", + Self::CodegenUnits => "codegen-units", + Self::CoverageMap => "coverage-map", + Self::CoverageRun => "coverage-run", + Self::Crashes => "crashes", + Self::Debuginfo => "debuginfo", + Self::Incremental => "incremental", + Self::MirOpt => "mir-opt", + Self::Pretty => "pretty", + Self::RunMake => "run-make", + Self::Rustdoc => "rustdoc", + Self::RustdocJs => "rustdoc-js", + Self::RustdocJson => "rustdoc-json", + Self::Ui => "ui", + // tidy-alphabetical-end + } + } +} + +impl fmt::Display for CompiletestMode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +impl fmt::Debug for CompiletestMode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ::fmt(self, f) + } +} diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 965b75f24c20..709d646bb359 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -345,7 +345,8 @@ fn test_test_coverage() { let config = configure_with_args(cmd, &[], &[TEST_TRIPLE_1]); let mut cache = run_build(&config.paths.clone(), config); - let modes = cache.inspect_all_steps_of_type::(|step, ()| step.mode); + let modes = + cache.inspect_all_steps_of_type::(|step, ()| step.mode.as_str()); assert_eq!(modes, expected); } } From 5f5286beb2d09b16c4c0bdbc7a1ab61898a64029 Mon Sep 17 00:00:00 2001 From: Theemathas Chirananthavat Date: Sat, 29 Nov 2025 14:42:43 +0700 Subject: [PATCH 0421/3801] Rewrite `String::replace_range` This simplifies the code, provides better panic messages, and avoids an integer overflow. --- library/alloc/src/string.rs | 35 ++++++++++-------------------- library/alloctests/tests/string.rs | 23 +++++++++++++++----- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 4a2689e01ff1..7e35c43de519 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -50,8 +50,6 @@ use core::iter::from_fn; use core::ops::Add; #[cfg(not(no_global_oom_handling))] use core::ops::AddAssign; -#[cfg(not(no_global_oom_handling))] -use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::{self, Range, RangeBounds}; use core::str::pattern::{Pattern, Utf8Pattern}; use core::{fmt, hash, ptr, slice}; @@ -2049,30 +2047,19 @@ impl String { where R: RangeBounds, { - // Memory safety - // - // Replace_range does not have the memory safety issues of a vector Splice. - // of the vector version. The data is just plain bytes. + // We avoid #81138 (nondeterministic RangeBounds impls) because we only use `range` once, here. + let checked_range = slice::range(range, ..self.len()); - // WARNING: Inlining this variable would be unsound (#81138) - let start = range.start_bound(); - match start { - Included(&n) => assert!(self.is_char_boundary(n)), - Excluded(&n) => assert!(self.is_char_boundary(n + 1)), - Unbounded => {} - }; - // WARNING: Inlining this variable would be unsound (#81138) - let end = range.end_bound(); - match end { - Included(&n) => assert!(self.is_char_boundary(n + 1)), - Excluded(&n) => assert!(self.is_char_boundary(n)), - Unbounded => {} - }; + assert!( + self.is_char_boundary(checked_range.start), + "start of range should be a character boundary" + ); + assert!( + self.is_char_boundary(checked_range.end), + "end of range should be a character boundary" + ); - // Using `range` again would be unsound (#81138) - // We assume the bounds reported by `range` remain the same, but - // an adversarial implementation could change between calls - unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes()); + unsafe { self.as_mut_vec() }.splice(checked_range, replace_with.bytes()); } /// Replaces the leftmost occurrence of a pattern with another string, in-place. diff --git a/library/alloctests/tests/string.rs b/library/alloctests/tests/string.rs index ecc5b9dc82ed..71557f284f47 100644 --- a/library/alloctests/tests/string.rs +++ b/library/alloctests/tests/string.rs @@ -616,8 +616,15 @@ fn test_replace_range() { } #[test] -#[should_panic] -fn test_replace_range_char_boundary() { +#[should_panic = "start of range should be a character boundary"] +fn test_replace_range_start_char_boundary() { + let mut s = "Hello, 世界!".to_owned(); + s.replace_range(8.., ""); +} + +#[test] +#[should_panic = "end of range should be a character boundary"] +fn test_replace_range_end_char_boundary() { let mut s = "Hello, 世界!".to_owned(); s.replace_range(..8, ""); } @@ -632,28 +639,32 @@ fn test_replace_range_inclusive_range() { } #[test] -#[should_panic] +#[should_panic = "range end index 6 out of range for slice of length 5"] fn test_replace_range_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..6, "789"); } #[test] -#[should_panic] +#[should_panic = "range end index 5 out of range for slice of length 5"] fn test_replace_range_inclusive_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..=5, "789"); } +// The overflowed index value is target-dependent, +// so we don't check for its exact value in the panic message #[test] -#[should_panic] +#[should_panic = "out of range for slice of length 3"] fn test_replace_range_start_overflow() { let mut s = String::from("123"); s.replace_range((Excluded(usize::MAX), Included(0)), ""); } +// The overflowed index value is target-dependent, +// so we don't check for its exact value in the panic message #[test] -#[should_panic] +#[should_panic = "out of range for slice of length 3"] fn test_replace_range_end_overflow() { let mut s = String::from("456"); s.replace_range((Included(0), Included(usize::MAX)), ""); From e24f0fa3c54951d1a5843b54ebe052faaa3a3cd2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 11:07:33 +0000 Subject: [PATCH 0422/3801] Update dependencies --- Cargo.lock | 58 ++++++++++++++++++++++++++++++------------------------ Cargo.toml | 2 +- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc27d9c6b542..617c7f0e34cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,9 +37,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cranelift-assembler-x64" @@ -282,18 +282,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.177" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" -version = "0.8.8" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-link 0.2.1", ] [[package]] @@ -304,9 +304,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "mach2" @@ -319,9 +319,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "object" @@ -337,27 +337,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] [[package]] name = "regalloc2" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd8138ce7c3d7c13be4f61893154b5d711bd798d2d7be3ecb8dcc7e7a06ca98" +checksum = "4e249c660440317032a71ddac302f25f1d5dff387667bcc3978d1f77aa31ac34" dependencies = [ "allocator-api2", "bumpalo", @@ -440,15 +440,15 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "syn" -version = "2.0.104" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -457,15 +457,15 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "wasmtime-internal-jit-icache-coherence" @@ -494,6 +494,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-sys" version = "0.52.0" @@ -534,7 +540,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", diff --git a/Cargo.toml b/Cargo.toml index 02d0d2ab3c58..58e61cd0b9d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ gimli = { version = "0.32", default-features = false, features = ["write"] } object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" -libloading = { version = "0.8.0", optional = true } +libloading = { version = "0.9.0", optional = true } smallvec = "1.8.1" [patch.crates-io] From 3f48189e97dfd3f527b6be288c3a8aeaf8773ae2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 8 Dec 2025 13:55:32 +0100 Subject: [PATCH 0423/3801] ftruncate: return proper error code for non-file-backed FDs --- src/tools/miri/src/shims/unix/fs.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 650972be5574..e17456c3bc0e 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -1157,10 +1157,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return this.set_last_error_and_return_i32(LibcError("EBADF")); }; - // FIXME: Support ftruncate64 for all FDs - let file = fd.downcast::().ok_or_else(|| { - err_unsup_format!("`ftruncate64` is only supported on file-backed file descriptors") - })?; + let Some(file) = fd.downcast::() else { + // The docs say that EINVAL is returned when the FD "does not reference a regular file + // or a POSIX shared memory object" (and we don't support shmem objects). + return interp_ok(this.eval_libc("EINVAL")); + }; if file.writable { if let Ok(length) = length.try_into() { @@ -1202,10 +1203,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let Some(fd) = this.machine.fds.get(fd_num) else { return interp_ok(this.eval_libc("EBADF")); }; - let file = match fd.downcast::() { - Some(file_handle) => file_handle, + let Some(file) = fd.downcast::() else { // Man page specifies to return ENODEV if `fd` is not a regular file. - None => return interp_ok(this.eval_libc("ENODEV")), + return interp_ok(this.eval_libc("ENODEV")); }; if !file.writable { From 0f4ec281558a40645b125fda43f36d7006180e54 Mon Sep 17 00:00:00 2001 From: SATVIKsynopsis Date: Sun, 7 Dec 2025 16:58:31 +0530 Subject: [PATCH 0424/3801] lint: treat unsafe binders in improper_ctypes instead of ICE Replaced _binder with _ --- compiler/rustc_lint/messages.ftl | 2 ++ compiler/rustc_lint/src/types/improper_ctypes.rs | 4 +++- .../lint/improper-ctypes/unsafe-binder-basic.rs | 10 ++++++++++ .../improper-ctypes/unsafe-binder-basic.stderr | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs create mode 100644 tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 1bcdda96e13a..a90a9c91ef13 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -416,6 +416,8 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re lint_improper_ctypes_union_layout_reason = this union has unspecified layout lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive +lint_improper_ctypes_unsafe_binder = unsafe binders are incompatible with foreign function interfaces + lint_int_to_ptr_transmutes = transmuting an integer to a pointer creates a pointer without provenance .note = this is dangerous because dereferencing the resulting pointer is undefined behavior .note_exposed_provenance = exposed provenance semantics can be used to create a pointer based on some previously exposed provenance diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 9e38ea6b685b..38094c67c34a 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -669,7 +669,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { FfiSafe } - ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), + ty::UnsafeBinder(_) => { + FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_unsafe_binder, help: None } + } ty::Param(..) | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..) diff --git a/tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs new file mode 100644 index 000000000000..5d4279fc834d --- /dev/null +++ b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs @@ -0,0 +1,10 @@ +#![feature(unsafe_binders)] +#![expect(incomplete_features)] +#![deny(improper_ctypes)] + +extern "C" { + fn exit_2(x: unsafe<'a> &'a ()); + //~^ ERROR `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe +} + +fn main() {} diff --git a/tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr new file mode 100644 index 000000000000..4b8d51690f1a --- /dev/null +++ b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr @@ -0,0 +1,15 @@ +error: `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe + --> $DIR/unsafe-binder-basic.rs:6:18 + | +LL | fn exit_2(x: unsafe<'a> &'a ()); + | ^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: unsafe binders are incompatible with foreign function interfaces +note: the lint level is defined here + --> $DIR/unsafe-binder-basic.rs:3:9 + | +LL | #![deny(improper_ctypes)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From 17d001d782e14634e5669323ba625f21a742eaa3 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 8 Dec 2025 15:42:35 +0200 Subject: [PATCH 0425/3801] bootstrap readme: make easy to read when editor wrapping is not enabled This also makes it more consistent with other text in the file --- src/bootstrap/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index ab07a2df3047..e46fed7c426a 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -221,7 +221,10 @@ please file issues on the [Rust issue tracker][rust-issue-tracker]. ## Testing -To run bootstrap tests, execute `x test bootstrap`. If you want to bless snapshot tests, then install `cargo-insta` (`cargo install cargo-insta`) and then run `cargo insta review --manifest-path src/bootstrap/Cargo.toml`. +To run bootstrap tests, execute `x test bootstrap`. +If you want to bless snapshot tests, +then install `cargo-insta` (`cargo install cargo-insta`), +and then run `cargo insta review --manifest-path src/bootstrap/Cargo.toml`. ## Changelog From 611c956c78fc9f95bd8af1f9b0567669959d1efe Mon Sep 17 00:00:00 2001 From: dianqk Date: Mon, 8 Dec 2025 21:57:05 +0800 Subject: [PATCH 0426/3801] test: Add test for 146133 Even if a crate is marked as #![no_builtins], we can still generate bitcode for rlib, but we cannot emit bitcode to the linker in rustc's LTO. --- .../no-builtins-linker-plugin-lto/main.rs | 3 ++ .../no_builtins.rs | 4 ++ .../no-builtins-linker-plugin-lto/rmake.rs | 53 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 tests/run-make/no-builtins-linker-plugin-lto/main.rs create mode 100644 tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs create mode 100644 tests/run-make/no-builtins-linker-plugin-lto/rmake.rs diff --git a/tests/run-make/no-builtins-linker-plugin-lto/main.rs b/tests/run-make/no-builtins-linker-plugin-lto/main.rs new file mode 100644 index 000000000000..f96605be8949 --- /dev/null +++ b/tests/run-make/no-builtins-linker-plugin-lto/main.rs @@ -0,0 +1,3 @@ +fn main() { + no_builtins::foo(); +} diff --git a/tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs b/tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs new file mode 100644 index 000000000000..a56c1d6b4133 --- /dev/null +++ b/tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs @@ -0,0 +1,4 @@ +#![no_builtins] + +#[inline(never)] +pub fn foo() {} diff --git a/tests/run-make/no-builtins-linker-plugin-lto/rmake.rs b/tests/run-make/no-builtins-linker-plugin-lto/rmake.rs new file mode 100644 index 000000000000..713308567737 --- /dev/null +++ b/tests/run-make/no-builtins-linker-plugin-lto/rmake.rs @@ -0,0 +1,53 @@ +//@ only-x86_64-unknown-linux-gnu + +use std::fs; +use std::path::Path; + +use run_make_support::{cwd, has_extension, llvm_ar, llvm_bcanalyzer, rust_lib_name, rustc}; + +// A regression test for #146133. + +fn main() { + // Compile a `#![no_builtins]` rlib crate with `-Clinker-plugin-lto`. + // It is acceptable to generate bitcode for rlib, so there is no need to check something. + rustc().input("no_builtins.rs").crate_type("rlib").linker_plugin_lto("on").run(); + + // Checks that rustc's LTO doesn't emit any bitcode to the linker. + let stdout = rustc() + .input("main.rs") + .extern_("no_builtins", rust_lib_name("no_builtins")) + .lto("thin") + .print("link-args") + .arg("-Csave-temps") + .arg("-Clinker-features=-lld") + .run() + .stdout_utf8(); + for object in stdout + .split_whitespace() + .map(|s| s.trim_matches('"')) + .filter(|path| has_extension(path, "rlib") || has_extension(path, "o")) + { + let object_path = if !fs::exists(object).unwrap() { + cwd().join(object) + } else { + Path::new(object).to_path_buf() + }; + if has_extension(object, "rlib") { + let ar_stdout = llvm_ar().arg("t").arg(&object_path).run().stdout_utf8(); + llvm_ar().extract().arg(&object_path).run(); + for object in ar_stdout.split_whitespace().filter(|o| has_extension(o, "o")) { + let object_path = cwd().join(object); + not_bitcode(&object_path); + } + } else { + not_bitcode(&object_path); + } + } +} + +fn not_bitcode(object: &Path) { + llvm_bcanalyzer() + .input(object) + .run_fail() + .assert_stderr_contains("llvm-bcanalyzer: Invalid record at top-level"); +} From 79d792f103486346ea54f3b90416294a9a73f2e8 Mon Sep 17 00:00:00 2001 From: quaternic <57393910+quaternic@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:45:33 +0200 Subject: [PATCH 0427/3801] use more descriptive variable names --- library/core/src/num/int_bits.rs | 56 +++++++++++++++----------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/library/core/src/num/int_bits.rs b/library/core/src/num/int_bits.rs index 38eac6ece17b..44be6de47327 100644 --- a/library/core/src/num/int_bits.rs +++ b/library/core/src/num/int_bits.rs @@ -7,12 +7,12 @@ //! inserting the zeros that gathering would delete. //! //! Key observation: Each bit that is gathered/scattered needs to be -//! shifted by the count of zeroes up to the corresponding mask bit. +//! shifted by the count of zeros up to the corresponding mask bit. //! //! With that in mind, the general idea is to decompose the operation into -//! a sequence of stages `k in 0..log2(BITS)`, where each stage shifts -//! some of the bits by `n = 1 << k`. The masks for each stage are computed -//! via prefix counts of zeroes in the mask. +//! a sequence of stages in `0..log2(BITS)`, where each stage shifts some +//! of the bits by `n = 1 << stage`. The masks for each stage are computed +//! via prefix counts of zeros in the mask. //! //! # Gathering //! @@ -28,8 +28,7 @@ //! ........ABCDEFGH //! ``` //! What makes this nontrivial is that the lengths of the bitstrings are not -//! the same and, using lowercase for individual bits, the above might look -//! more like +//! the same. Using lowercase for individual bits, the above might look like //! ```text //! .a.bbb.ccccc.dd.e..g.hh //! ..abbb..cccccdd..e..ghh @@ -68,24 +67,24 @@ macro_rules! uint_impl { pub(super) mod $U { const STAGES: usize = $U::BITS.ilog2() as usize; #[inline] - const fn prepare(m: $U) -> [$U; STAGES] { + const fn prepare(sparse: $U) -> [$U; STAGES] { // We'll start with `zeros` as a mask of the bits to be removed, // and compute into `masks` the parts that shift at each stage. - let mut zeros = !m; + let mut zeros = !sparse; let mut masks = [0; STAGES]; - let mut n = 1; - let mut k = 0; - while n < $U::BITS { + let mut stage = 0; + while stage < STAGES { + let n = 1 << stage; // Suppose `zeros` has bits set at ranges `{ a..a+n, b..b+n, ... }`. // Then `parity` will be computed as `{ a.. } XOR { b.. } XOR ...`, - // which will be the ranges `{ a..b, c..d, e.. }` + // which will be the ranges `{ a..b, c..d, e.. }`. let mut parity = zeros; - let mut j = n; - while j < $U::BITS { - parity ^= parity << j; - j <<= 1; + let mut len = n; + while len < $U::BITS { + parity ^= parity << len; + len <<= 1; } - masks[k] = parity; + masks[stage] = parity; // Toggle off the bits that are shifted into: // { a..a+n, b..b+n, ... } & !{ a..b, c..d, e.. } @@ -95,8 +94,7 @@ macro_rules! uint_impl { // shifted from: { b-n..b+n, d-n..d+n, ... } zeros ^= zeros >> n; - n <<= 1; - k += 1; + stage += 1; } masks } @@ -105,9 +103,9 @@ macro_rules! uint_impl { pub(in super::super) const fn gather_impl(mut x: $U, sparse: $U) -> $U { let masks = prepare(sparse); x &= sparse; - let mut k = 0; - while k < STAGES { - let n = 1 << k; + let mut stage = 0; + while stage < STAGES { + let n = 1 << stage; // Consider each two runs of data with their leading // groups of `n` 0-bits. Suppose that the run that is // shifted right has length `a`, and the other one has @@ -124,21 +122,21 @@ macro_rules! uint_impl { // In effect, the upper run of data is swapped with the // group of `n` zeros below it. - let q = x & masks[k]; + let q = x & masks[stage]; x ^= q; x ^= q >> n; - k += 1; + stage += 1; } x } #[inline(always)] pub(in super::super) const fn scatter_impl(mut x: $U, sparse: $U) -> $U { let masks = prepare(sparse); - let mut k = STAGES; - while k > 0 { - k -= 1; - let n = 1 << k; + let mut stage = STAGES; + while stage > 0 { + stage -= 1; + let n = 1 << stage; // Consider each run of data with the `2 * n` arbitrary bits // above it. Suppose that the run has length `a + b`, with // `a` being the length of the part that needs to be @@ -156,7 +154,7 @@ macro_rules! uint_impl { // In effect, `n` 0-bits are inserted somewhere in each run // of data to spread it, and the two groups of `n` bits // above are XOR'd together. - let q = x & masks[k]; + let q = x & masks[stage]; x ^= q; x ^= q << n; } From ba462864f1175690d1925cb5b1c6bf0a0c3cb579 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 10 Oct 2025 12:59:41 -0700 Subject: [PATCH 0428/3801] std: Use more `unix.rs` code on WASI targets This commit is a large change to the implementation of filesystem and other system-related operations on WASI targets. Previously the standard library explicitly used the `wasi` crate at the 0.11.x version track which means that it used WASIp1 APIs directly. This meant that `std` was hard-coded to use WASIp1 syscalls and there was no separate implementation for the WASIp{2,3} targets, for example. The high-level goal of this commit is to decouple this interaction and avoid the use of the `wasi` crate on the WASIp2 target. Historically when WASIp1 was originally added to Rust the wasi-libc library was in a much different position than it is today. Nowadays Rust already depends on wasi-libc on WASI targets for things like memory allocation and environment variable management. As a libc library it also has all the functions necessary to implement all filesystem operations Rust wants. Recently wasi-libc additionally was updated to use WASIp2 APIs directly on the `wasm32-wasip2` target instead of using `wasm32-wasip1` APIs. This commit is leveraging this work by enabling Rust to completely sever the dependence on WASIp1 APIs when compiling for `wasm32-wasip2`. This is also intended to make it easier to migrate to `wasm32-wasip3` internally in the future where now only libc need be updated and Rust doesn't need to explicitly change as well. The overall premise of this commit is that there's no need for WASI-specific implementation modules throughout the standard library. Instead the libc-style bindings already implemented for Unix-like targets are sufficient. This means that Rust will now be using libc-style interfaces to interact with the filesystem, for example, and wasi-libc is the one responsible for translating these POSIX-ish functions into WASIp{1,2} calls. Concrete changes here are: * `std` for `wasm32-wasip2` no longer depends on `wasi 0.11.x` * The implementation of `std::os::wasi::fs`, which was previously unstable and still is, now has portions gated to only work on the WASIp1 target which use the `wasi` crate directly. Traits have been trimmed down in some cases, updated in others, or now present a different API on WASIp1 and WASIp2. It's expected this'll get further cleanup in the future. * The `std::sys::fd::wasi` module is deleted and `unix` is used instead. * The `std::sys::fs::wasi` module is deleted and `unix` is used instead. * The `std::sys::io::io_slice::wasi` module is deleted and `unix` is used instead. * The `std::sys::pal::{wasip1,wasip2}` modules are now merged together as their difference is much smaller than before. * The `std::sys::pal::wasi::time` is deleted and the `unix` variant is used directly instead. * The `std::sys::stdio::wasip{1,2}` modules are deleted and the `unix` variant is used instead. * The `std::sys::thread::wasip{1,2}` modules are deleted and the `unix` variant is used instead. Overall Rust's libstd is effectively more tightly bound to libc when compiled to WASI targets. This is intended to mirror how it's expected all other languages will also bind to WASI. This additionally has the nice goal of drastically reducing the WASI-specific maintenance burden in libstd (in theory) and the only real changes required here are extra definitions being added to `libc` (done in separate PRs). This might be required for more symbols in the future but for now everything should be mostly complete. --- library/Cargo.lock | 4 +- library/std/Cargo.toml | 4 +- library/std/src/os/wasi/fs.rs | 310 ++---- library/std/src/os/wasi/net/mod.rs | 5 +- library/std/src/sys/fd/mod.rs | 6 +- library/std/src/sys/fd/unix.rs | 10 +- library/std/src/sys/fd/wasi.rs | 331 ------- library/std/src/sys/fs/mod.rs | 12 +- library/std/src/sys/fs/unix.rs | 55 +- library/std/src/sys/fs/wasi.rs | 913 ------------------ library/std/src/sys/io/io_slice/iovec.rs | 2 +- library/std/src/sys/io/io_slice/wasi.rs | 76 -- library/std/src/sys/io/mod.rs | 6 +- .../std/src/sys/net/connection/socket/mod.rs | 6 +- .../std/src/sys/net/connection/socket/unix.rs | 6 +- .../src/sys/net/connection/socket/wasip2.rs | 408 -------- library/std/src/sys/net/connection/wasip1.rs | 20 +- library/std/src/sys/pal/mod.rs | 10 +- library/std/src/sys/pal/unix/time.rs | 7 + .../sys/pal/{wasip2 => wasi}/cabi_realloc.rs | 0 library/std/src/sys/pal/wasi/helpers.rs | 63 ++ library/std/src/sys/pal/wasi/mod.rs | 39 + .../std/src/sys/pal/{wasip1 => wasi}/os.rs | 32 +- .../std/src/sys/pal/wasi/stack_overflow.rs | 7 + library/std/src/sys/pal/wasip1/helpers.rs | 114 --- library/std/src/sys/pal/wasip1/mod.rs | 38 - library/std/src/sys/pal/wasip1/time.rs | 65 -- library/std/src/sys/pal/wasip2/mod.rs | 35 - library/std/src/sys/pal/wasip2/time.rs | 58 -- library/std/src/sys/stdio/mod.rs | 10 +- library/std/src/sys/stdio/unix.rs | 7 +- library/std/src/sys/stdio/wasip1.rs | 117 --- library/std/src/sys/stdio/wasip2.rs | 120 --- library/std/src/sys/thread/mod.rs | 28 +- library/std/src/sys/thread/unix.rs | 3 + library/std/src/sys/thread/wasip1.rs | 183 ---- library/std/src/sys/thread/wasip2.rs | 32 - tests/rustdoc-js-std/unbox-type-result.js | 1 - triagebot.toml | 3 +- 39 files changed, 343 insertions(+), 2803 deletions(-) delete mode 100644 library/std/src/sys/fd/wasi.rs delete mode 100644 library/std/src/sys/fs/wasi.rs delete mode 100644 library/std/src/sys/io/io_slice/wasi.rs delete mode 100644 library/std/src/sys/net/connection/socket/wasip2.rs rename library/std/src/sys/pal/{wasip2 => wasi}/cabi_realloc.rs (100%) create mode 100644 library/std/src/sys/pal/wasi/helpers.rs create mode 100644 library/std/src/sys/pal/wasi/mod.rs rename library/std/src/sys/pal/{wasip1 => wasi}/os.rs (88%) create mode 100644 library/std/src/sys/pal/wasi/stack_overflow.rs delete mode 100644 library/std/src/sys/pal/wasip1/helpers.rs delete mode 100644 library/std/src/sys/pal/wasip1/mod.rs delete mode 100644 library/std/src/sys/pal/wasip1/time.rs delete mode 100644 library/std/src/sys/pal/wasip2/mod.rs delete mode 100644 library/std/src/sys/pal/wasip2/time.rs delete mode 100644 library/std/src/sys/stdio/wasip1.rs delete mode 100644 library/std/src/sys/stdio/wasip2.rs delete mode 100644 library/std/src/sys/thread/wasip1.rs delete mode 100644 library/std/src/sys/thread/wasip2.rs diff --git a/library/Cargo.lock b/library/Cargo.lock index accbbe9d236f..513d3f136698 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.177" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" dependencies = [ "rustc-std-workspace-core", ] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 3a673cf23b83..83a0826ac425 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -33,7 +33,7 @@ miniz_oxide = { version = "0.8.0", optional = true, default-features = false } addr2line = { version = "0.25.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.177", default-features = false, features = [ +libc = { version = "0.2.178", default-features = false, features = [ 'rustc-dep-of-std', ], public = true } @@ -78,7 +78,7 @@ hermit-abi = { version = "0.5.0", features = [ 'rustc-dep-of-std', ], public = true } -[target.'cfg(target_os = "wasi")'.dependencies] +[target.'cfg(all(target_os = "wasi", target_env = "p1"))'.dependencies] wasi = { version = "0.11.0", features = [ 'rustc-dep-of-std', ], default-features = false } diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs index 5ea91dd6521a..9145283dae6e 100644 --- a/library/std/src/os/wasi/fs.rs +++ b/library/std/src/os/wasi/fs.rs @@ -1,4 +1,4 @@ -//! WASI-specific extensions to primitives in the [`std::fs`] module. +//! WASIp1-specific extensions to primitives in the [`std::fs`] module. //! //! [`std::fs`]: crate::fs @@ -8,11 +8,16 @@ #[allow(unused_imports)] use io::{Read, Write}; +#[cfg(target_env = "p1")] use crate::ffi::OsStr; -use crate::fs::{self, File, Metadata, OpenOptions}; -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::path::{Path, PathBuf}; -use crate::sys_common::{AsInner, AsInnerMut, FromInner}; +use crate::fs::{self, File, OpenOptions}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; +#[cfg(target_env = "p1")] +use crate::os::fd::AsRawFd; +use crate::path::Path; +#[cfg(target_env = "p1")] +use crate::sys::err2io; +use crate::sys_common::{AsInner, AsInnerMut}; /// WASI-specific extensions to [`File`]. pub trait FileExt { @@ -27,10 +32,7 @@ pub trait FileExt { /// /// Note that similar to [`File::read`], it is not an error to return with a /// short read. - fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { - let bufs = &mut [IoSliceMut::new(buf)]; - self.read_vectored_at(bufs, offset) - } + fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result; /// Reads a number of bytes starting from a given offset. /// @@ -45,6 +47,13 @@ pub trait FileExt { /// return with a short read. fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result; + /// Reads some bytes starting from a given offset into the buffer. + /// + /// This equivalent to the [`read_at`](FileExt::read_at) method, except that it is passed a + /// [`BorrowedCursor`] rather than `&mut [u8]` to allow use with uninitialized buffers. The new + /// data will be appended to any existing contents of `buf`. + fn read_buf_at(&self, buf: BorrowedCursor<'_>, offset: u64) -> io::Result<()>; + /// Reads the exact number of byte required to fill `buf` from the given offset. /// /// The offset is relative to the start of the file and thus independent @@ -102,10 +111,7 @@ pub trait FileExt { /// /// Note that similar to [`File::write`], it is not an error to return a /// short write. - fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { - let bufs = &[IoSlice::new(buf)]; - self.write_vectored_at(bufs, offset) - } + fn write_at(&self, buf: &[u8], offset: u64) -> io::Result; /// Writes a number of bytes starting from a given offset. /// @@ -164,54 +170,49 @@ pub trait FileExt { /// /// This corresponds to the `fd_fdstat_set_flags` syscall. #[doc(alias = "fd_fdstat_set_flags")] + #[cfg(target_env = "p1")] fn fdstat_set_flags(&self, flags: u16) -> io::Result<()>; /// Adjusts the rights associated with this file. /// /// This corresponds to the `fd_fdstat_set_rights` syscall. #[doc(alias = "fd_fdstat_set_rights")] + #[cfg(target_env = "p1")] fn fdstat_set_rights(&self, rights: u64, inheriting: u64) -> io::Result<()>; /// Provides file advisory information on a file descriptor. /// /// This corresponds to the `fd_advise` syscall. #[doc(alias = "fd_advise")] + #[cfg(target_env = "p1")] fn advise(&self, offset: u64, len: u64, advice: u8) -> io::Result<()>; /// Forces the allocation of space in a file. /// /// This corresponds to the `fd_allocate` syscall. #[doc(alias = "fd_allocate")] + #[cfg(target_env = "p1")] fn allocate(&self, offset: u64, len: u64) -> io::Result<()>; /// Creates a directory. /// /// This corresponds to the `path_create_directory` syscall. #[doc(alias = "path_create_directory")] + #[cfg(target_env = "p1")] fn create_directory>(&self, dir: P) -> io::Result<()>; - /// Reads the contents of a symbolic link. - /// - /// This corresponds to the `path_readlink` syscall. - #[doc(alias = "path_readlink")] - fn read_link>(&self, path: P) -> io::Result; - - /// Returns the attributes of a file or directory. - /// - /// This corresponds to the `path_filestat_get` syscall. - #[doc(alias = "path_filestat_get")] - fn metadata_at>(&self, lookup_flags: u32, path: P) -> io::Result; - /// Unlinks a file. /// /// This corresponds to the `path_unlink_file` syscall. #[doc(alias = "path_unlink_file")] + #[cfg(target_env = "p1")] fn remove_file>(&self, path: P) -> io::Result<()>; /// Removes a directory. /// /// This corresponds to the `path_remove_directory` syscall. #[doc(alias = "path_remove_directory")] + #[cfg(target_env = "p1")] fn remove_directory>(&self, path: P) -> io::Result<()>; } @@ -222,23 +223,41 @@ pub trait FileExt { // FIXME: bind poll_oneoff maybe? - probably should wait for I/O to settle // FIXME: bind random_get maybe? - on crates.io for unix -impl FileExt for fs::File { +impl FileExt for File { + fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { + self.as_inner().read_at(buf, offset) + } + + fn read_buf_at(&self, buf: BorrowedCursor<'_>, offset: u64) -> io::Result<()> { + self.as_inner().read_buf_at(buf, offset) + } + fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { - self.as_inner().as_inner().pread(bufs, offset) + self.as_inner().read_vectored_at(bufs, offset) + } + + fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { + self.as_inner().write_at(buf, offset) } fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { - self.as_inner().as_inner().pwrite(bufs, offset) + self.as_inner().write_vectored_at(bufs, offset) } + #[cfg(target_env = "p1")] fn fdstat_set_flags(&self, flags: u16) -> io::Result<()> { - self.as_inner().as_inner().set_flags(flags) + unsafe { wasi::fd_fdstat_set_flags(self.as_raw_fd() as wasi::Fd, flags).map_err(err2io) } } + #[cfg(target_env = "p1")] fn fdstat_set_rights(&self, rights: u64, inheriting: u64) -> io::Result<()> { - self.as_inner().as_inner().set_rights(rights, inheriting) + unsafe { + wasi::fd_fdstat_set_rights(self.as_raw_fd() as wasi::Fd, rights, inheriting) + .map_err(err2io) + } } + #[cfg(target_env = "p1")] fn advise(&self, offset: u64, len: u64, advice: u8) -> io::Result<()> { let advice = match advice { a if a == wasi::ADVICE_NORMAL.raw() => wasi::ADVICE_NORMAL, @@ -255,149 +274,46 @@ impl FileExt for fs::File { } }; - self.as_inner().as_inner().advise(offset, len, advice) + unsafe { + wasi::fd_advise(self.as_raw_fd() as wasi::Fd, offset, len, advice).map_err(err2io) + } } + #[cfg(target_env = "p1")] fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { - self.as_inner().as_inner().allocate(offset, len) + unsafe { wasi::fd_allocate(self.as_raw_fd() as wasi::Fd, offset, len).map_err(err2io) } } + #[cfg(target_env = "p1")] fn create_directory>(&self, dir: P) -> io::Result<()> { - self.as_inner().as_inner().create_directory(osstr2str(dir.as_ref().as_ref())?) - } - - fn read_link>(&self, path: P) -> io::Result { - self.as_inner().read_link(path.as_ref()) - } - - fn metadata_at>(&self, lookup_flags: u32, path: P) -> io::Result { - let m = self.as_inner().metadata_at(lookup_flags, path.as_ref())?; - Ok(FromInner::from_inner(m)) + let path = osstr2str(dir.as_ref().as_ref())?; + unsafe { wasi::path_create_directory(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) } } + #[cfg(target_env = "p1")] fn remove_file>(&self, path: P) -> io::Result<()> { - self.as_inner().as_inner().unlink_file(osstr2str(path.as_ref().as_ref())?) + let path = osstr2str(path.as_ref().as_ref())?; + unsafe { wasi::path_unlink_file(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) } } + #[cfg(target_env = "p1")] fn remove_directory>(&self, path: P) -> io::Result<()> { - self.as_inner().as_inner().remove_directory(osstr2str(path.as_ref().as_ref())?) + let path = osstr2str(path.as_ref().as_ref())?; + unsafe { wasi::path_remove_directory(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) } } } -/// WASI-specific extensions to [`fs::OpenOptions`]. +/// WASI-specific extensions to [`OpenOptions`]. pub trait OpenOptionsExt { - /// Pass custom `dirflags` argument to `path_open`. - /// - /// This option configures the `dirflags` argument to the - /// `path_open` syscall which `OpenOptions` will eventually call. The - /// `dirflags` argument configures how the file is looked up, currently - /// primarily affecting whether symlinks are followed or not. - /// - /// By default this value is `__WASI_LOOKUP_SYMLINK_FOLLOW`, or symlinks are - /// followed. You can call this method with 0 to disable following symlinks - fn lookup_flags(&mut self, flags: u32) -> &mut Self; - - /// Indicates whether `OpenOptions` must open a directory or not. - /// - /// This method will configure whether the `__WASI_O_DIRECTORY` flag is - /// passed when opening a file. When passed it will require that the opened - /// path is a directory. - /// - /// This option is by default `false` - fn directory(&mut self, dir: bool) -> &mut Self; - - /// Indicates whether `__WASI_FDFLAG_DSYNC` is passed in the `fs_flags` - /// field of `path_open`. - /// - /// This option is by default `false` - fn dsync(&mut self, dsync: bool) -> &mut Self; - - /// Indicates whether `__WASI_FDFLAG_NONBLOCK` is passed in the `fs_flags` - /// field of `path_open`. - /// - /// This option is by default `false` - fn nonblock(&mut self, nonblock: bool) -> &mut Self; - - /// Indicates whether `__WASI_FDFLAG_RSYNC` is passed in the `fs_flags` - /// field of `path_open`. - /// - /// This option is by default `false` - fn rsync(&mut self, rsync: bool) -> &mut Self; - - /// Indicates whether `__WASI_FDFLAG_SYNC` is passed in the `fs_flags` - /// field of `path_open`. - /// - /// This option is by default `false` - fn sync(&mut self, sync: bool) -> &mut Self; - - /// Indicates the value that should be passed in for the `fs_rights_base` - /// parameter of `path_open`. - /// - /// This option defaults based on the `read` and `write` configuration of - /// this `OpenOptions` builder. If this method is called, however, the - /// exact mask passed in will be used instead. - fn fs_rights_base(&mut self, rights: u64) -> &mut Self; - - /// Indicates the value that should be passed in for the - /// `fs_rights_inheriting` parameter of `path_open`. - /// - /// The default for this option is the same value as what will be passed - /// for the `fs_rights_base` parameter but if this method is called then - /// the specified value will be used instead. - fn fs_rights_inheriting(&mut self, rights: u64) -> &mut Self; - - /// Open a file or directory. - /// - /// This corresponds to the `path_open` syscall. - #[doc(alias = "path_open")] - fn open_at>(&self, file: &File, path: P) -> io::Result; + /// Pass custom flags to the `flags` argument of `open`. + fn custom_flags(&mut self, flags: i32) -> &mut Self; } impl OpenOptionsExt for OpenOptions { - fn lookup_flags(&mut self, flags: u32) -> &mut OpenOptions { - self.as_inner_mut().lookup_flags(flags); + fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions { + self.as_inner_mut().custom_flags(flags); self } - - fn directory(&mut self, dir: bool) -> &mut OpenOptions { - self.as_inner_mut().directory(dir); - self - } - - fn dsync(&mut self, enabled: bool) -> &mut OpenOptions { - self.as_inner_mut().dsync(enabled); - self - } - - fn nonblock(&mut self, enabled: bool) -> &mut OpenOptions { - self.as_inner_mut().nonblock(enabled); - self - } - - fn rsync(&mut self, enabled: bool) -> &mut OpenOptions { - self.as_inner_mut().rsync(enabled); - self - } - - fn sync(&mut self, enabled: bool) -> &mut OpenOptions { - self.as_inner_mut().sync(enabled); - self - } - - fn fs_rights_base(&mut self, rights: u64) -> &mut OpenOptions { - self.as_inner_mut().fs_rights_base(rights); - self - } - - fn fs_rights_inheriting(&mut self, rights: u64) -> &mut OpenOptions { - self.as_inner_mut().fs_rights_inheriting(rights); - self - } - - fn open_at>(&self, file: &File, path: P) -> io::Result { - let inner = file.as_inner().open_at(path.as_ref(), self.as_inner())?; - Ok(File::from_inner(inner)) - } } /// WASI-specific extensions to [`fs::Metadata`]. @@ -408,37 +324,17 @@ pub trait MetadataExt { fn ino(&self) -> u64; /// Returns the `st_nlink` field of the internal `filestat_t` fn nlink(&self) -> u64; - /// Returns the `st_size` field of the internal `filestat_t` - fn size(&self) -> u64; - /// Returns the `st_atim` field of the internal `filestat_t` - fn atim(&self) -> u64; - /// Returns the `st_mtim` field of the internal `filestat_t` - fn mtim(&self) -> u64; - /// Returns the `st_ctim` field of the internal `filestat_t` - fn ctim(&self) -> u64; } impl MetadataExt for fs::Metadata { fn dev(&self) -> u64 { - self.as_inner().as_wasi().dev + self.as_inner().as_inner().st_dev } fn ino(&self) -> u64 { - self.as_inner().as_wasi().ino + self.as_inner().as_inner().st_ino } fn nlink(&self) -> u64 { - self.as_inner().as_wasi().nlink - } - fn size(&self) -> u64 { - self.as_inner().as_wasi().size - } - fn atim(&self) -> u64 { - self.as_inner().as_wasi().atim - } - fn mtim(&self) -> u64 { - self.as_inner().as_wasi().mtim - } - fn ctim(&self) -> u64 { - self.as_inner().as_wasi().ctim + self.as_inner().as_inner().st_nlink } } @@ -451,28 +347,19 @@ pub trait FileTypeExt { fn is_block_device(&self) -> bool; /// Returns `true` if this file type is a character device. fn is_char_device(&self) -> bool; - /// Returns `true` if this file type is a socket datagram. - fn is_socket_dgram(&self) -> bool; - /// Returns `true` if this file type is a socket stream. - fn is_socket_stream(&self) -> bool; /// Returns `true` if this file type is any type of socket. - fn is_socket(&self) -> bool { - self.is_socket_stream() || self.is_socket_dgram() - } + fn is_socket(&self) -> bool; } impl FileTypeExt for fs::FileType { fn is_block_device(&self) -> bool { - self.as_inner().bits() == wasi::FILETYPE_BLOCK_DEVICE + self.as_inner().is(libc::S_IFBLK) } fn is_char_device(&self) -> bool { - self.as_inner().bits() == wasi::FILETYPE_CHARACTER_DEVICE + self.as_inner().is(libc::S_IFCHR) } - fn is_socket_dgram(&self) -> bool { - self.as_inner().bits() == wasi::FILETYPE_SOCKET_DGRAM - } - fn is_socket_stream(&self) -> bool { - self.as_inner().bits() == wasi::FILETYPE_SOCKET_STREAM + fn is_socket(&self) -> bool { + self.as_inner().is(libc::S_IFSOCK) } } @@ -492,6 +379,7 @@ impl DirEntryExt for fs::DirEntry { /// /// This corresponds to the `path_link` syscall. #[doc(alias = "path_link")] +#[cfg(target_env = "p1")] pub fn link, U: AsRef>( old_fd: &File, old_flags: u32, @@ -499,43 +387,58 @@ pub fn link, U: AsRef>( new_fd: &File, new_path: U, ) -> io::Result<()> { - old_fd.as_inner().as_inner().link( - old_flags, - osstr2str(old_path.as_ref().as_ref())?, - new_fd.as_inner().as_inner(), - osstr2str(new_path.as_ref().as_ref())?, - ) + unsafe { + wasi::path_link( + old_fd.as_raw_fd() as wasi::Fd, + old_flags, + osstr2str(old_path.as_ref().as_ref())?, + new_fd.as_raw_fd() as wasi::Fd, + osstr2str(new_path.as_ref().as_ref())?, + ) + .map_err(err2io) + } } /// Renames a file or directory. /// /// This corresponds to the `path_rename` syscall. #[doc(alias = "path_rename")] +#[cfg(target_env = "p1")] pub fn rename, U: AsRef>( old_fd: &File, old_path: P, new_fd: &File, new_path: U, ) -> io::Result<()> { - old_fd.as_inner().as_inner().rename( - osstr2str(old_path.as_ref().as_ref())?, - new_fd.as_inner().as_inner(), - osstr2str(new_path.as_ref().as_ref())?, - ) + unsafe { + wasi::path_rename( + old_fd.as_raw_fd() as wasi::Fd, + osstr2str(old_path.as_ref().as_ref())?, + new_fd.as_raw_fd() as wasi::Fd, + osstr2str(new_path.as_ref().as_ref())?, + ) + .map_err(err2io) + } } /// Creates a symbolic link. /// /// This corresponds to the `path_symlink` syscall. #[doc(alias = "path_symlink")] +#[cfg(target_env = "p1")] pub fn symlink, U: AsRef>( old_path: P, fd: &File, new_path: U, ) -> io::Result<()> { - fd.as_inner() - .as_inner() - .symlink(osstr2str(old_path.as_ref().as_ref())?, osstr2str(new_path.as_ref().as_ref())?) + unsafe { + wasi::path_symlink( + osstr2str(old_path.as_ref().as_ref())?, + fd.as_raw_fd() as wasi::Fd, + osstr2str(new_path.as_ref().as_ref())?, + ) + .map_err(err2io) + } } /// Creates a symbolic link. @@ -546,6 +449,7 @@ pub fn symlink_path, U: AsRef>(old_path: P, new_path: U) -> crate::sys::fs::symlink(old_path.as_ref(), new_path.as_ref()) } +#[cfg(target_env = "p1")] fn osstr2str(f: &OsStr) -> io::Result<&str> { f.to_str().ok_or_else(|| io::const_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) } diff --git a/library/std/src/os/wasi/net/mod.rs b/library/std/src/os/wasi/net/mod.rs index 4704dd574517..9430cd3b05ee 100644 --- a/library/std/src/os/wasi/net/mod.rs +++ b/library/std/src/os/wasi/net/mod.rs @@ -2,7 +2,8 @@ #![unstable(feature = "wasi_ext", issue = "71213")] -use crate::sys_common::AsInner; +use crate::os::fd::AsRawFd; +use crate::sys::err2io; use crate::{io, net}; /// WASI-specific extensions to [`std::net::TcpListener`]. @@ -17,6 +18,6 @@ pub trait TcpListenerExt { impl TcpListenerExt for net::TcpListener { fn sock_accept(&self, flags: u16) -> io::Result { - self.as_inner().as_inner().as_inner().sock_accept(flags) + unsafe { wasi::sock_accept(self.as_raw_fd() as wasi::Fd, flags).map_err(err2io) } } } diff --git a/library/std/src/sys/fd/mod.rs b/library/std/src/sys/fd/mod.rs index 330499ecc18f..02d61a62f4e6 100644 --- a/library/std/src/sys/fd/mod.rs +++ b/library/std/src/sys/fd/mod.rs @@ -3,7 +3,7 @@ #![forbid(unsafe_op_in_unsafe_fn)] cfg_select! { - target_family = "unix" => { + any(target_family = "unix", target_os = "wasi") => { mod unix; pub use unix::*; } @@ -19,9 +19,5 @@ cfg_select! { mod sgx; pub use sgx::*; } - target_os = "wasi" => { - mod wasi; - pub use wasi::*; - } _ => {} } diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index a631e1d91393..33fff36b35b0 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -35,7 +35,7 @@ cfg_select! { use crate::cmp; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read}; -use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; +use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::sys::cvt; #[cfg(all(target_os = "android", target_pointer_width = "64"))] use crate::sys::pal::weak::syscall; @@ -152,7 +152,8 @@ impl FileDesc { target_os = "espidf", target_os = "horizon", target_os = "vita", - target_os = "nuttx" + target_os = "nuttx", + target_os = "wasi", ))) } @@ -385,7 +386,8 @@ impl FileDesc { target_os = "espidf", target_os = "horizon", target_os = "vita", - target_os = "nuttx" + target_os = "nuttx", + target_os = "wasi", ))) } @@ -560,6 +562,7 @@ impl FileDesc { target_os = "redox", target_os = "vxworks", target_os = "nto", + target_os = "wasi", )))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { @@ -583,6 +586,7 @@ impl FileDesc { target_os = "redox", target_os = "vxworks", target_os = "nto", + target_os = "wasi", ))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { diff --git a/library/std/src/sys/fd/wasi.rs b/library/std/src/sys/fd/wasi.rs deleted file mode 100644 index a468b31168af..000000000000 --- a/library/std/src/sys/fd/wasi.rs +++ /dev/null @@ -1,331 +0,0 @@ -#![expect(dead_code)] - -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; -use crate::mem; -use crate::net::Shutdown; -use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::sys::pal::err2io; -use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; - -#[derive(Debug)] -pub struct WasiFd { - fd: OwnedFd, -} - -fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] { - assert_eq!(size_of::>(), size_of::()); - assert_eq!(align_of::>(), align_of::()); - // SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout. - // We decorate our `IoSliceMut` with `repr(transparent)` (see `io.rs`), and - // `crate::io::IoSliceMut` is a `repr(transparent)` wrapper around our type, so this is - // guaranteed. - unsafe { mem::transmute(a) } -} - -fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] { - assert_eq!(size_of::>(), size_of::()); - assert_eq!(align_of::>(), align_of::()); - // SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout. - // We decorate our `IoSlice` with `repr(transparent)` (see `io.rs`), and - // `crate::io::IoSlice` is a `repr(transparent)` wrapper around our type, so this is - // guaranteed. - unsafe { mem::transmute(a) } -} - -impl WasiFd { - pub fn datasync(&self) -> io::Result<()> { - unsafe { wasi::fd_datasync(self.as_raw_fd() as wasi::Fd).map_err(err2io) } - } - - pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { - unsafe { wasi::fd_pread(self.as_raw_fd() as wasi::Fd, iovec(bufs), offset).map_err(err2io) } - } - - pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { - unsafe { - wasi::fd_pwrite(self.as_raw_fd() as wasi::Fd, ciovec(bufs), offset).map_err(err2io) - } - } - - pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - unsafe { wasi::fd_read(self.as_raw_fd() as wasi::Fd, iovec(bufs)).map_err(err2io) } - } - - pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> { - unsafe { - let bufs = [wasi::Iovec { - buf: buf.as_mut().as_mut_ptr() as *mut u8, - buf_len: buf.capacity(), - }]; - match wasi::fd_read(self.as_raw_fd() as wasi::Fd, &bufs) { - Ok(n) => { - buf.advance(n); - Ok(()) - } - Err(e) => Err(err2io(e)), - } - } - } - - pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result { - unsafe { wasi::fd_write(self.as_raw_fd() as wasi::Fd, ciovec(bufs)).map_err(err2io) } - } - - pub fn seek(&self, pos: SeekFrom) -> io::Result { - let (whence, offset) = match pos { - SeekFrom::Start(pos) => (wasi::WHENCE_SET, pos as i64), - SeekFrom::End(pos) => (wasi::WHENCE_END, pos), - SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos), - }; - unsafe { wasi::fd_seek(self.as_raw_fd() as wasi::Fd, offset, whence).map_err(err2io) } - } - - pub fn tell(&self) -> io::Result { - unsafe { wasi::fd_tell(self.as_raw_fd() as wasi::Fd).map_err(err2io) } - } - - // FIXME: __wasi_fd_fdstat_get - - pub fn set_flags(&self, flags: wasi::Fdflags) -> io::Result<()> { - unsafe { wasi::fd_fdstat_set_flags(self.as_raw_fd() as wasi::Fd, flags).map_err(err2io) } - } - - pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> { - unsafe { - wasi::fd_fdstat_set_rights(self.as_raw_fd() as wasi::Fd, base, inheriting) - .map_err(err2io) - } - } - - pub fn sync(&self) -> io::Result<()> { - unsafe { wasi::fd_sync(self.as_raw_fd() as wasi::Fd).map_err(err2io) } - } - - pub(crate) fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> { - unsafe { - wasi::fd_advise(self.as_raw_fd() as wasi::Fd, offset, len, advice).map_err(err2io) - } - } - - pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { - unsafe { wasi::fd_allocate(self.as_raw_fd() as wasi::Fd, offset, len).map_err(err2io) } - } - - pub fn create_directory(&self, path: &str) -> io::Result<()> { - unsafe { wasi::path_create_directory(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) } - } - - pub fn link( - &self, - old_flags: wasi::Lookupflags, - old_path: &str, - new_fd: &WasiFd, - new_path: &str, - ) -> io::Result<()> { - unsafe { - wasi::path_link( - self.as_raw_fd() as wasi::Fd, - old_flags, - old_path, - new_fd.as_raw_fd() as wasi::Fd, - new_path, - ) - .map_err(err2io) - } - } - - pub fn open( - &self, - dirflags: wasi::Lookupflags, - path: &str, - oflags: wasi::Oflags, - fs_rights_base: wasi::Rights, - fs_rights_inheriting: wasi::Rights, - fs_flags: wasi::Fdflags, - ) -> io::Result { - unsafe { - wasi::path_open( - self.as_raw_fd() as wasi::Fd, - dirflags, - path, - oflags, - fs_rights_base, - fs_rights_inheriting, - fs_flags, - ) - .map(|fd| WasiFd::from_raw_fd(fd as RawFd)) - .map_err(err2io) - } - } - - pub fn readdir(&self, buf: &mut [u8], cookie: wasi::Dircookie) -> io::Result { - unsafe { - wasi::fd_readdir(self.as_raw_fd() as wasi::Fd, buf.as_mut_ptr(), buf.len(), cookie) - .map_err(err2io) - } - } - - pub fn readlink(&self, path: &str, buf: &mut [u8]) -> io::Result { - unsafe { - wasi::path_readlink(self.as_raw_fd() as wasi::Fd, path, buf.as_mut_ptr(), buf.len()) - .map_err(err2io) - } - } - - pub fn rename(&self, old_path: &str, new_fd: &WasiFd, new_path: &str) -> io::Result<()> { - unsafe { - wasi::path_rename( - self.as_raw_fd() as wasi::Fd, - old_path, - new_fd.as_raw_fd() as wasi::Fd, - new_path, - ) - .map_err(err2io) - } - } - - pub(crate) fn filestat_get(&self) -> io::Result { - unsafe { wasi::fd_filestat_get(self.as_raw_fd() as wasi::Fd).map_err(err2io) } - } - - pub fn filestat_set_times( - &self, - atim: wasi::Timestamp, - mtim: wasi::Timestamp, - fstflags: wasi::Fstflags, - ) -> io::Result<()> { - unsafe { - wasi::fd_filestat_set_times(self.as_raw_fd() as wasi::Fd, atim, mtim, fstflags) - .map_err(err2io) - } - } - - pub fn filestat_set_size(&self, size: u64) -> io::Result<()> { - unsafe { wasi::fd_filestat_set_size(self.as_raw_fd() as wasi::Fd, size).map_err(err2io) } - } - - pub(crate) fn path_filestat_get( - &self, - flags: wasi::Lookupflags, - path: &str, - ) -> io::Result { - unsafe { - wasi::path_filestat_get(self.as_raw_fd() as wasi::Fd, flags, path).map_err(err2io) - } - } - - pub fn path_filestat_set_times( - &self, - flags: wasi::Lookupflags, - path: &str, - atim: wasi::Timestamp, - mtim: wasi::Timestamp, - fstflags: wasi::Fstflags, - ) -> io::Result<()> { - unsafe { - wasi::path_filestat_set_times( - self.as_raw_fd() as wasi::Fd, - flags, - path, - atim, - mtim, - fstflags, - ) - .map_err(err2io) - } - } - - pub fn symlink(&self, old_path: &str, new_path: &str) -> io::Result<()> { - unsafe { - wasi::path_symlink(old_path, self.as_raw_fd() as wasi::Fd, new_path).map_err(err2io) - } - } - - pub fn unlink_file(&self, path: &str) -> io::Result<()> { - unsafe { wasi::path_unlink_file(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) } - } - - pub fn remove_directory(&self, path: &str) -> io::Result<()> { - unsafe { wasi::path_remove_directory(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) } - } - - pub fn sock_accept(&self, flags: wasi::Fdflags) -> io::Result { - unsafe { wasi::sock_accept(self.as_raw_fd() as wasi::Fd, flags).map_err(err2io) } - } - - pub fn sock_recv( - &self, - ri_data: &mut [IoSliceMut<'_>], - ri_flags: wasi::Riflags, - ) -> io::Result<(usize, wasi::Roflags)> { - unsafe { - wasi::sock_recv(self.as_raw_fd() as wasi::Fd, iovec(ri_data), ri_flags).map_err(err2io) - } - } - - pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::Siflags) -> io::Result { - unsafe { - wasi::sock_send(self.as_raw_fd() as wasi::Fd, ciovec(si_data), si_flags).map_err(err2io) - } - } - - pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> { - let how = match how { - Shutdown::Read => wasi::SDFLAGS_RD, - Shutdown::Write => wasi::SDFLAGS_WR, - Shutdown::Both => wasi::SDFLAGS_WR | wasi::SDFLAGS_RD, - }; - unsafe { wasi::sock_shutdown(self.as_raw_fd() as wasi::Fd, how).map_err(err2io) } - } -} - -impl AsInner for WasiFd { - #[inline] - fn as_inner(&self) -> &OwnedFd { - &self.fd - } -} - -impl AsInnerMut for WasiFd { - #[inline] - fn as_inner_mut(&mut self) -> &mut OwnedFd { - &mut self.fd - } -} - -impl IntoInner for WasiFd { - fn into_inner(self) -> OwnedFd { - self.fd - } -} - -impl FromInner for WasiFd { - fn from_inner(owned_fd: OwnedFd) -> Self { - Self { fd: owned_fd } - } -} - -impl AsFd for WasiFd { - fn as_fd(&self) -> BorrowedFd<'_> { - self.fd.as_fd() - } -} - -impl AsRawFd for WasiFd { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd.as_raw_fd() - } -} - -impl IntoRawFd for WasiFd { - fn into_raw_fd(self) -> RawFd { - self.fd.into_raw_fd() - } -} - -impl FromRawFd for WasiFd { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - unsafe { Self { fd: FromRawFd::from_raw_fd(raw_fd) } } - } -} diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index eaea28871241..4a66227ce5f4 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -6,12 +6,14 @@ use crate::path::{Path, PathBuf}; pub mod common; cfg_select! { - target_family = "unix" => { + any(target_family = "unix", target_os = "wasi") => { mod unix; use unix as imp; + #[cfg(not(target_os = "wasi"))] pub use unix::{chown, fchown, lchown, mkfifo}; - #[cfg(not(target_os = "fuchsia"))] + #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] pub use unix::chroot; + #[cfg(not(target_os = "wasi"))] pub(crate) use unix::debug_assert_fd_is_open; #[cfg(any(target_os = "linux", target_os = "android"))] pub(super) use unix::CachedFileMetadata; @@ -43,10 +45,6 @@ cfg_select! { mod vexos; use vexos as imp; } - target_os = "wasi" => { - mod wasi; - use wasi as imp; - } _ => { mod unsupported; use unsupported as imp; @@ -54,7 +52,7 @@ cfg_select! { } // FIXME: Replace this with platform-specific path conversion functions. -#[cfg(not(any(target_family = "unix", target_os = "windows")))] +#[cfg(not(any(target_family = "unix", target_os = "windows", target_os = "wasi")))] #[inline] pub fn with_native_path(path: &Path, f: &dyn Fn(&Path) -> io::Result) -> io::Result { f(path) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 47d9ee226653..507d093d2b2f 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -31,6 +31,7 @@ use libc::fstatat64; target_os = "redox", target_os = "solaris", target_os = "vita", + target_os = "wasi", all(target_os = "linux", target_env = "musl"), ))] use libc::readdir as readdir64; @@ -47,6 +48,7 @@ use libc::readdir as readdir64; target_os = "redox", target_os = "solaris", target_os = "vita", + target_os = "wasi", )))] use libc::readdir_r as readdir64_r; #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] @@ -80,8 +82,11 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt::{self, Write as _}; use crate::fs::TryLockError; use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; -use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd}; +use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd}; +#[cfg(target_family = "unix")] use crate::os::unix::prelude::*; +#[cfg(target_os = "wasi")] +use crate::os::wasi::prelude::*; use crate::path::{Path, PathBuf}; use crate::sync::Arc; use crate::sys::common::small_c_string::run_path_with_cstr; @@ -285,6 +290,7 @@ unsafe impl Sync for Dir {} target_os = "redox", target_os = "solaris", target_os = "vita", + target_os = "wasi", ))] pub struct DirEntry { dir: Arc, @@ -310,6 +316,7 @@ pub struct DirEntry { target_os = "redox", target_os = "solaris", target_os = "vita", + target_os = "wasi", ))] struct dirent64_min { d_ino: u64, @@ -335,6 +342,7 @@ struct dirent64_min { target_os = "redox", target_os = "solaris", target_os = "vita", + target_os = "wasi", )))] pub struct DirEntry { dir: Arc, @@ -480,7 +488,7 @@ impl FileAttr { } } -#[cfg(not(any(target_os = "netbsd", target_os = "nto", target_os = "aix")))] +#[cfg(not(any(target_os = "netbsd", target_os = "nto", target_os = "aix", target_os = "wasi")))] impl FileAttr { #[cfg(not(any( target_os = "vxworks", @@ -595,18 +603,18 @@ impl FileAttr { } } -#[cfg(target_os = "nto")] +#[cfg(any(target_os = "nto", target_os = "wasi"))] impl FileAttr { pub fn modified(&self) -> io::Result { - SystemTime::new(self.stat.st_mtim.tv_sec, self.stat.st_mtim.tv_nsec) + SystemTime::new(self.stat.st_mtim.tv_sec, self.stat.st_mtim.tv_nsec.into()) } pub fn accessed(&self) -> io::Result { - SystemTime::new(self.stat.st_atim.tv_sec, self.stat.st_atim.tv_nsec) + SystemTime::new(self.stat.st_atim.tv_sec, self.stat.st_atim.tv_nsec.into()) } pub fn created(&self) -> io::Result { - SystemTime::new(self.stat.st_ctim.tv_sec, self.stat.st_ctim.tv_nsec) + SystemTime::new(self.stat.st_ctim.tv_sec, self.stat.st_ctim.tv_nsec.into()) } } @@ -632,6 +640,7 @@ impl FilePermissions { self.mode |= 0o222; } } + #[cfg(not(target_os = "wasi"))] pub fn mode(&self) -> u32 { self.mode as u32 } @@ -715,6 +724,7 @@ impl Iterator for ReadDir { target_os = "redox", target_os = "solaris", target_os = "vita", + target_os = "wasi", ))] fn next(&mut self) -> Option> { use crate::sys::os::{errno, set_errno}; @@ -812,6 +822,7 @@ impl Iterator for ReadDir { target_os = "redox", target_os = "solaris", target_os = "vita", + target_os = "wasi", )))] fn next(&mut self) -> Option> { if self.end_of_stream { @@ -1002,6 +1013,7 @@ impl DirEntry { target_os = "solaris", target_os = "vita", target_os = "vxworks", + target_os = "wasi", target_vendor = "apple", ))] pub fn ino(&self) -> u64 { @@ -1057,6 +1069,7 @@ impl DirEntry { target_os = "nto", target_os = "vita", target_os = "hurd", + target_os = "wasi", )))] fn name_cstr(&self) -> &CStr { unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) } @@ -1073,6 +1086,7 @@ impl DirEntry { target_os = "nto", target_os = "vita", target_os = "hurd", + target_os = "wasi", ))] fn name_cstr(&self) -> &CStr { &self.name @@ -1121,6 +1135,7 @@ impl OpenOptions { pub fn custom_flags(&mut self, flags: i32) { self.custom_flags = flags; } + #[cfg(not(target_os = "wasi"))] pub fn mode(&mut self, mode: u32) { self.mode = mode as mode_t; } @@ -1769,6 +1784,7 @@ impl DirBuilder { run_path_with_cstr(p, &|p| cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) }).map(|_| ())) } + #[cfg(not(target_os = "wasi"))] pub fn set_mode(&mut self, mode: u32) { self.mode = mode as mode_t; } @@ -2217,7 +2233,7 @@ pub fn set_times_nofollow(p: &CStr, times: FileTimes) -> io::Result<()> { set_times_impl(p, times, false) } -#[cfg(target_os = "espidf")] +#[cfg(any(target_os = "espidf", target_os = "wasi"))] fn open_to_and_set_permissions( to: &Path, _reader_metadata: &crate::fs::Metadata, @@ -2228,7 +2244,7 @@ fn open_to_and_set_permissions( Ok((writer, writer_metadata)) } -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] fn open_to_and_set_permissions( to: &Path, reader_metadata: &crate::fs::Metadata, @@ -2376,6 +2392,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { Ok(bytes_copied as u64) } +#[cfg(not(target_os = "wasi"))] pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { run_path_with_cstr(path, &|path| { cvt(unsafe { libc::chown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) }) @@ -2383,12 +2400,13 @@ pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { }) } +#[cfg(not(target_os = "wasi"))] pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> { cvt(unsafe { libc::fchown(fd, uid as libc::uid_t, gid as libc::gid_t) })?; Ok(()) } -#[cfg(not(target_os = "vxworks"))] +#[cfg(not(any(target_os = "vxworks", target_os = "wasi")))] pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { run_path_with_cstr(path, &|path| { cvt(unsafe { libc::lchown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) }) @@ -2402,7 +2420,7 @@ pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { Err(io::const_error!(io::ErrorKind::Unsupported, "lchown not supported by vxworks")) } -#[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))] +#[cfg(not(any(target_os = "fuchsia", target_os = "vxworks", target_os = "wasi")))] pub fn chroot(dir: &Path) -> io::Result<()> { run_path_with_cstr(dir, &|dir| cvt(unsafe { libc::chroot(dir.as_ptr()) }).map(|_| ())) } @@ -2413,6 +2431,7 @@ pub fn chroot(dir: &Path) -> io::Result<()> { Err(io::const_error!(io::ErrorKind::Unsupported, "chroot not supported by vxworks")) } +#[cfg(not(target_os = "wasi"))] pub fn mkfifo(path: &Path, mode: u32) -> io::Result<()> { run_path_with_cstr(path, &|path| { cvt(unsafe { libc::mkfifo(path.as_ptr(), mode.try_into().unwrap()) }).map(|_| ()) @@ -2451,11 +2470,11 @@ mod remove_dir_impl { #[cfg(all(target_os = "linux", target_env = "gnu"))] use libc::{fdopendir, openat64 as openat, unlinkat}; - use super::{Dir, DirEntry, InnerReadDir, ReadDir, lstat}; + use super::{ + AsRawFd, Dir, DirEntry, FromRawFd, InnerReadDir, IntoRawFd, OwnedFd, RawFd, ReadDir, lstat, + }; use crate::ffi::CStr; use crate::io; - use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd}; - use crate::os::unix::prelude::{OwnedFd, RawFd}; use crate::path::{Path, PathBuf}; use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::{cvt, cvt_r}; @@ -2543,6 +2562,16 @@ mod remove_dir_impl { // open the directory passing ownership of the fd let (dir, fd) = fdreaddir(fd)?; + + // For WASI all directory entries for this directory are read first + // before any removal is done. This works around the fact that the + // WASIp1 API for reading directories is not well-designed for handling + // mutations between invocations of reading a directory. By reading all + // the entries at once this ensures that, at least without concurrent + // modifications, it should be possible to delete everything. + #[cfg(target_os = "wasi")] + let dir = dir.collect::>(); + for child in dir { let child = child?; let child_name = child.name_cstr(); diff --git a/library/std/src/sys/fs/wasi.rs b/library/std/src/sys/fs/wasi.rs deleted file mode 100644 index 92eb35317415..000000000000 --- a/library/std/src/sys/fs/wasi.rs +++ /dev/null @@ -1,913 +0,0 @@ -use crate::ffi::{CStr, OsStr, OsString}; -use crate::fs::TryLockError; -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; -use crate::mem::{self, ManuallyDrop}; -use crate::os::raw::c_int; -use crate::os::wasi::ffi::{OsStrExt, OsStringExt}; -use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; -use crate::path::{Path, PathBuf}; -use crate::sync::Arc; -use crate::sys::common::small_c_string::run_path_with_cstr; -use crate::sys::fd::WasiFd; -pub use crate::sys::fs::common::exists; -use crate::sys::time::SystemTime; -use crate::sys::{unsupported, unsupported_err}; -use crate::sys_common::{AsInner, FromInner, IntoInner, ignore_notfound}; -use crate::{fmt, iter, ptr}; - -pub struct File { - fd: WasiFd, -} - -#[derive(Clone)] -pub struct FileAttr { - meta: wasi::Filestat, -} - -pub struct ReadDir { - inner: Arc, - state: ReadDirState, -} - -enum ReadDirState { - /// Fill `buf` with `buf.len()` bytes starting from `next_read_offset`. - FillBuffer { - next_read_offset: wasi::Dircookie, - buf: Vec, - }, - ProcessEntry { - buf: Vec, - next_read_offset: Option, - offset: usize, - }, - /// There is no more data to get in [`Self::FillBuffer`]; keep returning - /// entries via ProcessEntry until `buf` is exhausted. - RunUntilExhaustion { - buf: Vec, - offset: usize, - }, - Done, -} - -struct ReadDirInner { - root: PathBuf, - dir: File, -} - -pub struct DirEntry { - meta: wasi::Dirent, - name: Vec, - inner: Arc, -} - -#[derive(Clone, Debug, Default)] -pub struct OpenOptions { - read: bool, - write: bool, - append: bool, - dirflags: wasi::Lookupflags, - fdflags: wasi::Fdflags, - oflags: wasi::Oflags, - rights_base: Option, - rights_inheriting: Option, -} - -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct FilePermissions { - readonly: bool, -} - -#[derive(Copy, Clone, Debug, Default)] -pub struct FileTimes { - accessed: Option, - modified: Option, -} - -#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] -pub struct FileType { - bits: wasi::Filetype, -} - -#[derive(Debug)] -pub struct DirBuilder {} - -impl FileAttr { - pub fn size(&self) -> u64 { - self.meta.size - } - - pub fn perm(&self) -> FilePermissions { - // not currently implemented in wasi yet - FilePermissions { readonly: false } - } - - pub fn file_type(&self) -> FileType { - FileType { bits: self.meta.filetype } - } - - pub fn modified(&self) -> io::Result { - Ok(SystemTime::from_wasi_timestamp(self.meta.mtim)) - } - - pub fn accessed(&self) -> io::Result { - Ok(SystemTime::from_wasi_timestamp(self.meta.atim)) - } - - pub fn created(&self) -> io::Result { - Ok(SystemTime::from_wasi_timestamp(self.meta.ctim)) - } - - pub(crate) fn as_wasi(&self) -> &wasi::Filestat { - &self.meta - } -} - -impl FilePermissions { - pub fn readonly(&self) -> bool { - self.readonly - } - - pub fn set_readonly(&mut self, readonly: bool) { - self.readonly = readonly; - } -} - -impl FileTimes { - pub fn set_accessed(&mut self, t: SystemTime) { - self.accessed = Some(t); - } - - pub fn set_modified(&mut self, t: SystemTime) { - self.modified = Some(t); - } -} - -impl FileType { - pub fn is_dir(&self) -> bool { - self.bits == wasi::FILETYPE_DIRECTORY - } - - pub fn is_file(&self) -> bool { - self.bits == wasi::FILETYPE_REGULAR_FILE - } - - pub fn is_symlink(&self) -> bool { - self.bits == wasi::FILETYPE_SYMBOLIC_LINK - } - - pub(crate) fn bits(&self) -> wasi::Filetype { - self.bits - } -} - -impl ReadDir { - fn new(dir: File, root: PathBuf) -> ReadDir { - ReadDir { - inner: Arc::new(ReadDirInner { dir, root }), - state: ReadDirState::FillBuffer { next_read_offset: 0, buf: vec![0; 128] }, - } - } -} - -impl fmt::Debug for ReadDir { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ReadDir").finish_non_exhaustive() - } -} - -impl core::iter::FusedIterator for ReadDir {} - -impl Iterator for ReadDir { - type Item = io::Result; - - fn next(&mut self) -> Option> { - match &mut self.state { - ReadDirState::FillBuffer { next_read_offset, buf } => { - let result = self.inner.dir.fd.readdir(buf, *next_read_offset); - match result { - Ok(read_bytes) => { - if read_bytes < buf.len() { - buf.truncate(read_bytes); - self.state = - ReadDirState::RunUntilExhaustion { buf: mem::take(buf), offset: 0 }; - } else { - debug_assert_eq!(read_bytes, buf.len()); - self.state = ReadDirState::ProcessEntry { - buf: mem::take(buf), - offset: 0, - next_read_offset: Some(*next_read_offset), - }; - } - self.next() - } - Err(e) => { - self.state = ReadDirState::Done; - return Some(Err(e)); - } - } - } - ReadDirState::ProcessEntry { buf, next_read_offset, offset } => { - let contents = &buf[*offset..]; - const DIRENT_SIZE: usize = size_of::(); - if contents.len() >= DIRENT_SIZE { - let (dirent, data) = contents.split_at(DIRENT_SIZE); - let dirent = - unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) }; - // If the file name was truncated, then we need to reinvoke - // `readdir` so we truncate our buffer to start over and reread this - // descriptor. - if data.len() < dirent.d_namlen as usize { - if buf.len() < dirent.d_namlen as usize + DIRENT_SIZE { - buf.resize(dirent.d_namlen as usize + DIRENT_SIZE, 0); - } - if let Some(next_read_offset) = *next_read_offset { - self.state = - ReadDirState::FillBuffer { next_read_offset, buf: mem::take(buf) }; - } else { - self.state = ReadDirState::Done; - } - - return self.next(); - } - next_read_offset.as_mut().map(|cookie| { - *cookie = dirent.d_next; - }); - *offset = *offset + DIRENT_SIZE + dirent.d_namlen as usize; - - let name = &data[..(dirent.d_namlen as usize)]; - - // These names are skipped on all other platforms, so let's skip - // them here too - if name == b"." || name == b".." { - return self.next(); - } - - return Some(Ok(DirEntry { - meta: dirent, - name: name.to_vec(), - inner: self.inner.clone(), - })); - } else if let Some(next_read_offset) = *next_read_offset { - self.state = ReadDirState::FillBuffer { next_read_offset, buf: mem::take(buf) }; - } else { - self.state = ReadDirState::Done; - } - self.next() - } - ReadDirState::RunUntilExhaustion { buf, offset } => { - if *offset >= buf.len() { - self.state = ReadDirState::Done; - } else { - self.state = ReadDirState::ProcessEntry { - buf: mem::take(buf), - offset: *offset, - next_read_offset: None, - }; - } - - self.next() - } - ReadDirState::Done => None, - } - } -} - -impl DirEntry { - pub fn path(&self) -> PathBuf { - let name = OsStr::from_bytes(&self.name); - self.inner.root.join(name) - } - - pub fn file_name(&self) -> OsString { - OsString::from_vec(self.name.clone()) - } - - pub fn metadata(&self) -> io::Result { - metadata_at(&self.inner.dir.fd, 0, OsStr::from_bytes(&self.name).as_ref()) - } - - pub fn file_type(&self) -> io::Result { - Ok(FileType { bits: self.meta.d_type }) - } - - pub fn ino(&self) -> wasi::Inode { - self.meta.d_ino - } -} - -impl OpenOptions { - pub fn new() -> OpenOptions { - let mut base = OpenOptions::default(); - base.dirflags = wasi::LOOKUPFLAGS_SYMLINK_FOLLOW; - base - } - - pub fn read(&mut self, read: bool) { - self.read = read; - } - - pub fn write(&mut self, write: bool) { - self.write = write; - } - - pub fn truncate(&mut self, truncate: bool) { - self.oflag(wasi::OFLAGS_TRUNC, truncate); - } - - pub fn create(&mut self, create: bool) { - self.oflag(wasi::OFLAGS_CREAT, create); - } - - pub fn create_new(&mut self, create_new: bool) { - self.oflag(wasi::OFLAGS_EXCL, create_new); - self.oflag(wasi::OFLAGS_CREAT, create_new); - } - - pub fn directory(&mut self, directory: bool) { - self.oflag(wasi::OFLAGS_DIRECTORY, directory); - } - - fn oflag(&mut self, bit: wasi::Oflags, set: bool) { - if set { - self.oflags |= bit; - } else { - self.oflags &= !bit; - } - } - - pub fn append(&mut self, append: bool) { - self.append = append; - self.fdflag(wasi::FDFLAGS_APPEND, append); - } - - pub fn dsync(&mut self, set: bool) { - self.fdflag(wasi::FDFLAGS_DSYNC, set); - } - - pub fn nonblock(&mut self, set: bool) { - self.fdflag(wasi::FDFLAGS_NONBLOCK, set); - } - - pub fn rsync(&mut self, set: bool) { - self.fdflag(wasi::FDFLAGS_RSYNC, set); - } - - pub fn sync(&mut self, set: bool) { - self.fdflag(wasi::FDFLAGS_SYNC, set); - } - - fn fdflag(&mut self, bit: wasi::Fdflags, set: bool) { - if set { - self.fdflags |= bit; - } else { - self.fdflags &= !bit; - } - } - - pub fn fs_rights_base(&mut self, rights: wasi::Rights) { - self.rights_base = Some(rights); - } - - pub fn fs_rights_inheriting(&mut self, rights: wasi::Rights) { - self.rights_inheriting = Some(rights); - } - - fn rights_base(&self) -> wasi::Rights { - if let Some(rights) = self.rights_base { - return rights; - } - - // If rights haven't otherwise been specified try to pick a reasonable - // set. This can always be overridden by users via extension traits, and - // implementations may give us fewer rights silently than we ask for. So - // given that, just look at `read` and `write` and bucket permissions - // based on that. - let mut base = 0; - if self.read { - base |= wasi::RIGHTS_FD_READ; - base |= wasi::RIGHTS_FD_READDIR; - } - if self.write || self.append { - base |= wasi::RIGHTS_FD_WRITE; - base |= wasi::RIGHTS_FD_DATASYNC; - base |= wasi::RIGHTS_FD_ALLOCATE; - base |= wasi::RIGHTS_FD_FILESTAT_SET_SIZE; - } - - // FIXME: some of these should probably be read-only or write-only... - base |= wasi::RIGHTS_FD_ADVISE; - base |= wasi::RIGHTS_FD_FDSTAT_SET_FLAGS; - base |= wasi::RIGHTS_FD_FILESTAT_GET; - base |= wasi::RIGHTS_FD_FILESTAT_SET_TIMES; - base |= wasi::RIGHTS_FD_SEEK; - base |= wasi::RIGHTS_FD_SYNC; - base |= wasi::RIGHTS_FD_TELL; - base |= wasi::RIGHTS_PATH_CREATE_DIRECTORY; - base |= wasi::RIGHTS_PATH_CREATE_FILE; - base |= wasi::RIGHTS_PATH_FILESTAT_GET; - base |= wasi::RIGHTS_PATH_LINK_SOURCE; - base |= wasi::RIGHTS_PATH_LINK_TARGET; - base |= wasi::RIGHTS_PATH_OPEN; - base |= wasi::RIGHTS_PATH_READLINK; - base |= wasi::RIGHTS_PATH_REMOVE_DIRECTORY; - base |= wasi::RIGHTS_PATH_RENAME_SOURCE; - base |= wasi::RIGHTS_PATH_RENAME_TARGET; - base |= wasi::RIGHTS_PATH_SYMLINK; - base |= wasi::RIGHTS_PATH_UNLINK_FILE; - base |= wasi::RIGHTS_POLL_FD_READWRITE; - - base - } - - fn rights_inheriting(&self) -> wasi::Rights { - self.rights_inheriting.unwrap_or_else(|| self.rights_base()) - } - - pub fn lookup_flags(&mut self, flags: wasi::Lookupflags) { - self.dirflags = flags; - } -} - -impl File { - pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { - let (dir, file) = open_parent(path)?; - open_at(&dir, &file, opts) - } - - pub fn open_at(&self, path: &Path, opts: &OpenOptions) -> io::Result { - open_at(&self.fd, path, opts) - } - - pub fn file_attr(&self) -> io::Result { - self.fd.filestat_get().map(|meta| FileAttr { meta }) - } - - pub fn metadata_at(&self, flags: wasi::Lookupflags, path: &Path) -> io::Result { - metadata_at(&self.fd, flags, path) - } - - pub fn fsync(&self) -> io::Result<()> { - self.fd.sync() - } - - pub fn datasync(&self) -> io::Result<()> { - self.fd.datasync() - } - - pub fn lock(&self) -> io::Result<()> { - unsupported() - } - - pub fn lock_shared(&self) -> io::Result<()> { - unsupported() - } - - pub fn try_lock(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(unsupported_err())) - } - - pub fn try_lock_shared(&self) -> Result<(), TryLockError> { - Err(TryLockError::Error(unsupported_err())) - } - - pub fn unlock(&self) -> io::Result<()> { - unsupported() - } - - pub fn truncate(&self, size: u64) -> io::Result<()> { - self.fd.filestat_set_size(size) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.read_vectored(&mut [IoSliceMut::new(buf)]) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.fd.read(bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - true - } - - pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { - self.fd.read_buf(cursor) - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - self.write_vectored(&[IoSlice::new(buf)]) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - self.fd.write(bufs) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - true - } - - pub fn flush(&self) -> io::Result<()> { - Ok(()) - } - - pub fn seek(&self, pos: SeekFrom) -> io::Result { - self.fd.seek(pos) - } - - pub fn size(&self) -> Option> { - None - } - - pub fn tell(&self) -> io::Result { - self.fd.tell() - } - - pub fn duplicate(&self) -> io::Result { - // https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-rationale.md#why-no-dup - unsupported() - } - - pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { - // Permissions haven't been fully figured out in wasi yet, so this is - // likely temporary - unsupported() - } - - pub fn set_times(&self, times: FileTimes) -> io::Result<()> { - self.fd.filestat_set_times( - to_wasi_timestamp_or_now(times.accessed)?, - to_wasi_timestamp_or_now(times.modified)?, - times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM) - | times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM), - ) - } - - pub fn read_link(&self, file: &Path) -> io::Result { - read_link(&self.fd, file) - } -} - -impl AsInner for File { - #[inline] - fn as_inner(&self) -> &WasiFd { - &self.fd - } -} - -impl IntoInner for File { - fn into_inner(self) -> WasiFd { - self.fd - } -} - -impl FromInner for File { - fn from_inner(fd: WasiFd) -> File { - File { fd } - } -} - -impl AsFd for File { - fn as_fd(&self) -> BorrowedFd<'_> { - self.fd.as_fd() - } -} - -impl AsRawFd for File { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd.as_raw_fd() - } -} - -impl IntoRawFd for File { - fn into_raw_fd(self) -> RawFd { - self.fd.into_raw_fd() - } -} - -impl FromRawFd for File { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - unsafe { Self { fd: FromRawFd::from_raw_fd(raw_fd) } } - } -} - -impl DirBuilder { - pub fn new() -> DirBuilder { - DirBuilder {} - } - - pub fn mkdir(&self, p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p)?; - dir.create_directory(osstr2str(file.as_ref())?) - } -} - -impl fmt::Debug for File { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("File").field("fd", &self.as_raw_fd()).finish() - } -} - -pub fn readdir(p: &Path) -> io::Result { - let mut opts = OpenOptions::new(); - opts.directory(true); - opts.read(true); - let dir = File::open(p, &opts)?; - Ok(ReadDir::new(dir, p.to_path_buf())) -} - -pub fn unlink(p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p)?; - dir.unlink_file(osstr2str(file.as_ref())?) -} - -pub fn rename(old: &Path, new: &Path) -> io::Result<()> { - let (old, old_file) = open_parent(old)?; - let (new, new_file) = open_parent(new)?; - old.rename(osstr2str(old_file.as_ref())?, &new, osstr2str(new_file.as_ref())?) -} - -pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { - // Permissions haven't been fully figured out in wasi yet, so this is - // likely temporary - unsupported() -} - -#[inline(always)] -pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> { - let (dir, file) = open_parent(p)?; - set_times_impl(&dir, &file, times, wasi::LOOKUPFLAGS_SYMLINK_FOLLOW) -} - -#[inline(always)] -pub fn set_times_nofollow(p: &Path, times: FileTimes) -> io::Result<()> { - let (dir, file) = open_parent(p)?; - set_times_impl(&dir, &file, times, 0) -} - -fn to_wasi_timestamp_or_now(time: Option) -> io::Result { - match time { - Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts), - Some(_) => Err(io::const_error!( - io::ErrorKind::InvalidInput, - "timestamp is too large to set as a file time", - )), - None => Ok(0), - } -} - -fn set_times_impl( - fd: &WasiFd, - path: &Path, - times: FileTimes, - flags: wasi::Lookupflags, -) -> io::Result<()> { - fd.path_filestat_set_times( - flags, - osstr2str(path.as_ref())?, - to_wasi_timestamp_or_now(times.accessed)?, - to_wasi_timestamp_or_now(times.modified)?, - times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM) - | times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM), - ) -} - -pub fn rmdir(p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p)?; - dir.remove_directory(osstr2str(file.as_ref())?) -} - -pub fn readlink(p: &Path) -> io::Result { - let (dir, file) = open_parent(p)?; - read_link(&dir, &file) -} - -fn read_link(fd: &WasiFd, file: &Path) -> io::Result { - // Try to get a best effort initial capacity for the vector we're going to - // fill. Note that if it's not a symlink we don't use a file to avoid - // allocating gigabytes if you read_link a huge movie file by accident. - // Additionally we add 1 to the initial size so if it doesn't change until - // when we call `readlink` the returned length will be less than the - // capacity, guaranteeing that we got all the data. - let meta = metadata_at(fd, 0, file)?; - let initial_size = if meta.file_type().is_symlink() { - (meta.size() as usize).saturating_add(1) - } else { - 1 // this'll fail in just a moment - }; - - // Now that we have an initial guess of how big to make our buffer, call - // `readlink` in a loop until it fails or reports it filled fewer bytes than - // we asked for, indicating we got everything. - let file = osstr2str(file.as_ref())?; - let mut destination = vec![0u8; initial_size]; - loop { - let len = fd.readlink(file, &mut destination)?; - if len < destination.len() { - destination.truncate(len); - destination.shrink_to_fit(); - return Ok(PathBuf::from(OsString::from_vec(destination))); - } - let amt_to_add = destination.len(); - destination.extend(iter::repeat(0).take(amt_to_add)); - } -} - -pub fn symlink(original: &Path, link: &Path) -> io::Result<()> { - let (link, link_file) = open_parent(link)?; - link.symlink(osstr2str(original.as_ref())?, osstr2str(link_file.as_ref())?) -} - -pub fn link(original: &Path, link: &Path) -> io::Result<()> { - let (original, original_file) = open_parent(original)?; - let (link, link_file) = open_parent(link)?; - // Pass 0 as the flags argument, meaning don't follow symlinks. - original.link(0, osstr2str(original_file.as_ref())?, &link, osstr2str(link_file.as_ref())?) -} - -pub fn stat(p: &Path) -> io::Result { - let (dir, file) = open_parent(p)?; - metadata_at(&dir, wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, &file) -} - -pub fn lstat(p: &Path) -> io::Result { - let (dir, file) = open_parent(p)?; - metadata_at(&dir, 0, &file) -} - -fn metadata_at(fd: &WasiFd, flags: wasi::Lookupflags, path: &Path) -> io::Result { - let meta = fd.path_filestat_get(flags, osstr2str(path.as_ref())?)?; - Ok(FileAttr { meta }) -} - -pub fn canonicalize(_p: &Path) -> io::Result { - // This seems to not be in wasi's API yet, and we may need to end up - // emulating it ourselves. For now just return an error. - unsupported() -} - -fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result { - let fd = fd.open( - opts.dirflags, - osstr2str(path.as_ref())?, - opts.oflags, - opts.rights_base(), - opts.rights_inheriting(), - opts.fdflags, - )?; - Ok(File { fd }) -} - -/// Attempts to open a bare path `p`. -/// -/// WASI has no fundamental capability to do this. All syscalls and operations -/// are relative to already-open file descriptors. The C library, however, -/// manages a map of pre-opened file descriptors to their path, and then the C -/// library provides an API to look at this. In other words, when you want to -/// open a path `p`, you have to find a previously opened file descriptor in a -/// global table and then see if `p` is relative to that file descriptor. -/// -/// This function, if successful, will return two items: -/// -/// * The first is a `ManuallyDrop`. This represents a pre-opened file -/// descriptor which we don't have ownership of, but we can use. You shouldn't -/// actually drop the `fd`. -/// -/// * The second is a path that should be a part of `p` and represents a -/// relative traversal from the file descriptor specified to the desired -/// location `p`. -/// -/// If successful you can use the returned file descriptor to perform -/// file-descriptor-relative operations on the path returned as well. The -/// `rights` argument indicates what operations are desired on the returned file -/// descriptor, and if successful the returned file descriptor should have the -/// appropriate rights for performing `rights` actions. -/// -/// Note that this can fail if `p` doesn't look like it can be opened relative -/// to any pre-opened file descriptor. -fn open_parent(p: &Path) -> io::Result<(ManuallyDrop, PathBuf)> { - run_path_with_cstr(p, &|p| { - let mut buf = Vec::::with_capacity(512); - loop { - unsafe { - let mut relative_path = buf.as_ptr().cast(); - let mut abs_prefix = ptr::null(); - let fd = __wasilibc_find_relpath( - p.as_ptr(), - &mut abs_prefix, - &mut relative_path, - buf.capacity(), - ); - if fd == -1 { - if io::Error::last_os_error().raw_os_error() == Some(libc::ENOMEM) { - // Trigger the internal buffer resizing logic of `Vec` by requiring - // more space than the current capacity. - let cap = buf.capacity(); - buf.set_len(cap); - buf.reserve(1); - continue; - } - let msg = format!( - "failed to find a pre-opened file descriptor \ - through which {p:?} could be opened", - ); - return Err(io::Error::new(io::ErrorKind::Uncategorized, msg)); - } - let relative = CStr::from_ptr(relative_path).to_bytes().to_vec(); - - return Ok(( - ManuallyDrop::new(WasiFd::from_raw_fd(fd as c_int)), - PathBuf::from(OsString::from_vec(relative)), - )); - } - } - - unsafe extern "C" { - pub fn __wasilibc_find_relpath( - path: *const libc::c_char, - abs_prefix: *mut *const libc::c_char, - relative_path: *mut *const libc::c_char, - relative_path_len: libc::size_t, - ) -> libc::c_int; - } - }) -} - -pub fn osstr2str(f: &OsStr) -> io::Result<&str> { - f.to_str().ok_or_else(|| io::const_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) -} - -pub fn copy(from: &Path, to: &Path) -> io::Result { - use crate::fs::File; - - let mut reader = File::open(from)?; - let mut writer = File::create(to)?; - - io::copy(&mut reader, &mut writer) -} - -pub fn remove_dir_all(path: &Path) -> io::Result<()> { - let (parent, path) = open_parent(path)?; - remove_dir_all_recursive(&parent, &path) -} - -fn remove_dir_all_recursive(parent: &WasiFd, path: &Path) -> io::Result<()> { - // Open up a file descriptor for the directory itself. Note that we don't - // follow symlinks here and we specifically open directories. - // - // At the root invocation of this function this will correctly handle - // symlinks passed to the top-level `remove_dir_all`. At the recursive - // level this will double-check that after the `readdir` call deduced this - // was a directory it's still a directory by the time we open it up. - // - // If the opened file was actually a symlink then the symlink is deleted, - // not the directory recursively. - let mut opts = OpenOptions::new(); - opts.lookup_flags(0); - opts.directory(true); - opts.read(true); - let fd = open_at(parent, path, &opts)?; - if fd.file_attr()?.file_type().is_symlink() { - return parent.unlink_file(osstr2str(path.as_ref())?); - } - - // this "root" is only used by `DirEntry::path` which we don't use below so - // it's ok for this to be a bogus value - let dummy_root = PathBuf::new(); - - // Iterate over all the entries in this directory, and travel recursively if - // necessary - // - // Note that all directory entries for this directory are read first before - // any removal is done. This works around the fact that the WASIp1 API for - // reading directories is not well-designed for handling mutations between - // invocations of reading a directory. By reading all the entries at once - // this ensures that, at least without concurrent modifications, it should - // be possible to delete everything. - for entry in ReadDir::new(fd, dummy_root).collect::>() { - let entry = entry?; - let path = crate::str::from_utf8(&entry.name).map_err(|_| { - io::const_error!(io::ErrorKind::Uncategorized, "invalid utf-8 file name found") - })?; - - let result: io::Result<()> = try { - if entry.file_type()?.is_dir() { - remove_dir_all_recursive(&entry.inner.dir.fd, path.as_ref())?; - } else { - entry.inner.dir.fd.unlink_file(path)?; - } - }; - // ignore internal NotFound errors - if let Err(err) = &result - && err.kind() != io::ErrorKind::NotFound - { - return result; - } - } - - // Once all this directory's contents are deleted it should be safe to - // delete the directory tiself. - ignore_notfound(parent.remove_directory(osstr2str(path.as_ref())?)) -} diff --git a/library/std/src/sys/io/io_slice/iovec.rs b/library/std/src/sys/io/io_slice/iovec.rs index df56358969a3..d549aca250d5 100644 --- a/library/std/src/sys/io/io_slice/iovec.rs +++ b/library/std/src/sys/io/io_slice/iovec.rs @@ -1,6 +1,6 @@ #[cfg(target_os = "hermit")] use hermit_abi::iovec; -#[cfg(any(target_family = "unix", target_os = "trusty"))] +#[cfg(any(target_family = "unix", target_os = "trusty", target_os = "wasi"))] use libc::iovec; use crate::ffi::c_void; diff --git a/library/std/src/sys/io/io_slice/wasi.rs b/library/std/src/sys/io/io_slice/wasi.rs deleted file mode 100644 index 87acbbd924e5..000000000000 --- a/library/std/src/sys/io/io_slice/wasi.rs +++ /dev/null @@ -1,76 +0,0 @@ -use crate::marker::PhantomData; -use crate::slice; - -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct IoSlice<'a> { - vec: wasi::Ciovec, - _p: PhantomData<&'a [u8]>, -} - -impl<'a> IoSlice<'a> { - #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { - IoSlice { vec: wasi::Ciovec { buf: buf.as_ptr(), buf_len: buf.len() }, _p: PhantomData } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.buf_len < n { - panic!("advancing IoSlice beyond its length"); - } - - unsafe { - self.vec.buf_len -= n; - self.vec.buf = self.vec.buf.add(n); - } - } - - #[inline] - pub const fn as_slice(&self) -> &'a [u8] { - unsafe { slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len) } - } -} - -#[repr(transparent)] -pub struct IoSliceMut<'a> { - vec: wasi::Iovec, - _p: PhantomData<&'a mut [u8]>, -} - -impl<'a> IoSliceMut<'a> { - #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { - IoSliceMut { - vec: wasi::Iovec { buf: buf.as_mut_ptr(), buf_len: buf.len() }, - _p: PhantomData, - } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.buf_len < n { - panic!("advancing IoSlice beyond its length"); - } - - unsafe { - self.vec.buf_len -= n; - self.vec.buf = self.vec.buf.add(n); - } - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len) } - } - - #[inline] - pub const fn into_slice(self) -> &'a mut [u8] { - unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) } - } - - #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) } - } -} diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs index e2c5e7f88d49..b4e4e6ec7312 100644 --- a/library/std/src/sys/io/mod.rs +++ b/library/std/src/sys/io/mod.rs @@ -2,7 +2,7 @@ mod io_slice { cfg_select! { - any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty") => { + any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty", target_os = "wasi") => { mod iovec; pub use iovec::*; } @@ -10,10 +10,6 @@ mod io_slice { mod windows; pub use windows::*; } - target_os = "wasi" => { - mod wasi; - pub use wasi::*; - } target_os = "uefi" => { mod uefi; pub use uefi::*; diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs index 1d941dec1b79..63d5c1d23124 100644 --- a/library/std/src/sys/net/connection/socket/mod.rs +++ b/library/std/src/sys/net/connection/socket/mod.rs @@ -22,14 +22,10 @@ cfg_select! { mod solid; pub use solid::*; } - target_family = "unix" => { + any(target_family = "unix", target_os = "wasi") => { mod unix; pub use unix::*; } - all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { - mod wasip2; - pub use wasip2::*; - } target_os = "windows" => { mod windows; pub use windows::*; diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index c892daf0d39c..d30f6054077d 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -4,7 +4,7 @@ use libc::{MSG_PEEK, c_int, c_void, size_t, sockaddr, socklen_t}; use crate::ffi::CStr; use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Shutdown, SocketAddr}; -use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::sys::fd::FileDesc; use crate::sys::net::{getsockopt, setsockopt}; use crate::sys::pal::IsMinusOne; @@ -107,7 +107,7 @@ impl Socket { } } - #[cfg(not(target_os = "vxworks"))] + #[cfg(not(any(target_os = "vxworks", target_os = "wasi")))] pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> { unsafe { let mut fds = [0, 0]; @@ -275,6 +275,7 @@ impl Socket { self.0.duplicate().map(Socket) } + #[cfg(not(target_os = "wasi"))] pub fn send_with_flags(&self, buf: &[u8], flags: c_int) -> io::Result { let len = cmp::min(buf.len(), ::MAX as usize) as wrlen_t; let ret = cvt(unsafe { @@ -361,6 +362,7 @@ impl Socket { self.recv_from_with_flags(buf, MSG_PEEK) } + #[cfg(not(target_os = "wasi"))] pub fn write(&self, buf: &[u8]) -> io::Result { self.0.write(buf) } diff --git a/library/std/src/sys/net/connection/socket/wasip2.rs b/library/std/src/sys/net/connection/socket/wasip2.rs deleted file mode 100644 index f86034266c26..000000000000 --- a/library/std/src/sys/net/connection/socket/wasip2.rs +++ /dev/null @@ -1,408 +0,0 @@ -#![deny(unsafe_op_in_unsafe_fn)] - -pub(super) use libc as netc; -use libc::{c_int, c_void, size_t}; - -use super::{getsockopt, setsockopt, socket_addr_from_c, socket_addr_to_c}; -use crate::ffi::CStr; -use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{Shutdown, SocketAddr}; -use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::sys::unsupported; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::{Duration, Instant}; -use crate::{cmp, mem, str}; - -#[allow(non_camel_case_types)] -pub type wrlen_t = size_t; - -#[doc(hidden)] -pub trait IsMinusOne { - fn is_minus_one(&self) -> bool; -} - -macro_rules! impl_is_minus_one { - ($($t:ident)*) => ($(impl IsMinusOne for $t { - fn is_minus_one(&self) -> bool { - *self == -1 - } - })*) -} - -impl_is_minus_one! { i8 i16 i32 i64 isize } - -pub fn cvt(t: T) -> crate::io::Result { - if t.is_minus_one() { Err(crate::io::Error::last_os_error()) } else { Ok(t) } -} - -pub fn cvt_r(mut f: F) -> crate::io::Result -where - T: IsMinusOne, - F: FnMut() -> T, -{ - loop { - match cvt(f()) { - Err(ref e) if e.is_interrupted() => {} - other => return other, - } - } -} - -pub fn cvt_gai(err: c_int) -> io::Result<()> { - if err == 0 { - return Ok(()); - } - - if err == netc::EAI_SYSTEM { - return Err(io::Error::last_os_error()); - } - - let detail = unsafe { - str::from_utf8(CStr::from_ptr(netc::gai_strerror(err)).to_bytes()).unwrap().to_owned() - }; - - Err(io::Error::new( - io::ErrorKind::Uncategorized, - &format!("failed to lookup address information: {detail}")[..], - )) -} - -pub fn init() {} - -pub struct WasiSocket(OwnedFd); - -pub struct Socket(WasiSocket); - -impl Socket { - pub fn new(family: c_int, ty: c_int) -> io::Result { - let fd = cvt(unsafe { netc::socket(family, ty, 0) })?; - Ok(unsafe { Self::from_raw_fd(fd) }) - } - - pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { - let (addr, len) = socket_addr_to_c(addr); - cvt_r(|| unsafe { netc::connect(self.as_raw_fd(), addr.as_ptr(), len) })?; - Ok(()) - } - - pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { - self.set_nonblocking(true)?; - let r = self.connect(addr); - self.set_nonblocking(false)?; - - match r { - Ok(_) => return Ok(()), - // there's no ErrorKind for EINPROGRESS - Err(ref e) if e.raw_os_error() == Some(netc::EINPROGRESS) => {} - Err(e) => return Err(e), - } - - let mut pollfd = netc::pollfd { fd: self.as_raw_fd(), events: netc::POLLOUT, revents: 0 }; - - if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let start = Instant::now(); - - loop { - let elapsed = start.elapsed(); - if elapsed >= timeout { - return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); - } - - let timeout = timeout - elapsed; - let mut timeout = timeout - .as_secs() - .saturating_mul(1_000) - .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000); - if timeout == 0 { - timeout = 1; - } - - let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; - - match unsafe { netc::poll(&mut pollfd, 1, timeout) } { - -1 => { - let err = io::Error::last_os_error(); - if !err.is_interrupted() { - return Err(err); - } - } - 0 => {} - _ => { - // WASI poll does not return POLLHUP or POLLERR in revents. Check if the - // connection actually succeeded and return ok only when the socket is - // ready and no errors were found. - if let Some(e) = self.take_error()? { - return Err(e); - } - - return Ok(()); - } - } - } - } - - pub fn accept( - &self, - storage: *mut netc::sockaddr, - len: *mut netc::socklen_t, - ) -> io::Result { - let fd = cvt_r(|| unsafe { netc::accept(self.as_raw_fd(), storage, len) })?; - Ok(unsafe { Self::from_raw_fd(fd) }) - } - - pub fn duplicate(&self) -> io::Result { - unsupported() - } - - fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> { - let ret = cvt(unsafe { - netc::recv( - self.as_raw_fd(), - buf.as_mut().as_mut_ptr() as *mut c_void, - buf.capacity(), - flags, - ) - })?; - unsafe { - buf.advance(ret as usize); - } - Ok(()) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), 0)?; - Ok(buf.len()) - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), netc::MSG_PEEK)?; - Ok(buf.len()) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.recv_with_flags(buf, 0) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - io::default_read_vectored(|b| self.read(b), bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - false - } - - fn recv_from_with_flags( - &self, - buf: &mut [u8], - flags: c_int, - ) -> io::Result<(usize, SocketAddr)> { - let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = size_of_val(&storage) as netc::socklen_t; - - let n = cvt(unsafe { - netc::recvfrom( - self.as_raw_fd(), - buf.as_mut_ptr() as *mut c_void, - buf.len(), - flags, - core::ptr::addr_of_mut!(storage) as *mut _, - &mut addrlen, - ) - })?; - Ok((n as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? })) - } - - pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, 0) - } - - pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, netc::MSG_PEEK) - } - - fn write(&self, buf: &[u8]) -> io::Result { - let len = cmp::min(buf.len(), ::MAX as usize) as wrlen_t; - let ret = cvt(unsafe { - netc::send(self.as_raw(), buf.as_ptr() as *const c_void, len, netc::MSG_NOSIGNAL) - })?; - Ok(ret as usize) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - io::default_write_vectored(|b| self.write(b), bufs) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - false - } - - pub fn set_timeout(&self, dur: Option, kind: c_int) -> io::Result<()> { - let timeout = match dur { - Some(dur) => { - if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let secs = dur.as_secs().try_into().unwrap_or(netc::time_t::MAX); - let mut timeout = netc::timeval { - tv_sec: secs, - tv_usec: dur.subsec_micros() as netc::suseconds_t, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => netc::timeval { tv_sec: 0, tv_usec: 0 }, - }; - unsafe { setsockopt(self, netc::SOL_SOCKET, kind, timeout) } - } - - pub fn timeout(&self, kind: c_int) -> io::Result> { - let raw: netc::timeval = unsafe { getsockopt(self, netc::SOL_SOCKET, kind)? }; - if raw.tv_sec == 0 && raw.tv_usec == 0 { - Ok(None) - } else { - let sec = raw.tv_sec as u64; - let nsec = (raw.tv_usec as u32) * 1000; - Ok(Some(Duration::new(sec, nsec))) - } - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - let how = match how { - Shutdown::Write => netc::SHUT_WR, - Shutdown::Read => netc::SHUT_RD, - Shutdown::Both => netc::SHUT_RDWR, - }; - cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?; - Ok(()) - } - - pub fn set_linger(&self, _linger: Option) -> io::Result<()> { - unsupported() - } - - pub fn linger(&self) -> io::Result> { - unsupported() - } - - pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { - unsafe { setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, nodelay as c_int) } - } - - pub fn nodelay(&self) -> io::Result { - let raw: c_int = unsafe { getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)? }; - Ok(raw != 0) - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let mut nonblocking = nonblocking as c_int; - cvt(unsafe { netc::ioctl(self.as_raw_fd(), netc::FIONBIO, &mut nonblocking) }).map(drop) - } - - pub fn take_error(&self) -> io::Result> { - let raw: c_int = unsafe { getsockopt(self, netc::SOL_SOCKET, netc::SO_ERROR)? }; - if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } - } - - // This is used by sys_common code to abstract over Windows and Unix. - pub fn as_raw(&self) -> RawFd { - self.as_raw_fd() - } -} - -impl AsInner for WasiSocket { - #[inline] - fn as_inner(&self) -> &OwnedFd { - &self.0 - } -} - -impl IntoInner for WasiSocket { - fn into_inner(self) -> OwnedFd { - self.0 - } -} - -impl FromInner for WasiSocket { - fn from_inner(owned_fd: OwnedFd) -> Self { - Self(owned_fd) - } -} - -impl AsFd for WasiSocket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl AsRawFd for WasiSocket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl IntoRawFd for WasiSocket { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} - -impl FromRawFd for WasiSocket { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } - } -} - -impl AsInner for Socket { - #[inline] - fn as_inner(&self) -> &WasiSocket { - &self.0 - } -} - -impl IntoInner for Socket { - fn into_inner(self) -> WasiSocket { - self.0 - } -} - -impl FromInner for Socket { - fn from_inner(sock: WasiSocket) -> Socket { - Socket(sock) - } -} - -impl AsFd for Socket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl AsRawFd for Socket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl IntoRawFd for Socket { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} - -impl FromRawFd for Socket { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } - } -} diff --git a/library/std/src/sys/net/connection/wasip1.rs b/library/std/src/sys/net/connection/wasip1.rs index 048dafdcd7f7..3a0ac5552a64 100644 --- a/library/std/src/sys/net/connection/wasip1.rs +++ b/library/std/src/sys/net/connection/wasip1.rs @@ -4,32 +4,32 @@ use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs}; use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; -use crate::sys::fd::WasiFd; +use crate::sys::fd::FileDesc; use crate::sys::{err2io, unsupported}; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::Duration; -pub struct Socket(WasiFd); +pub struct Socket(FileDesc); pub struct TcpStream { inner: Socket, } -impl AsInner for Socket { +impl AsInner for Socket { #[inline] - fn as_inner(&self) -> &WasiFd { + fn as_inner(&self) -> &FileDesc { &self.0 } } -impl IntoInner for Socket { - fn into_inner(self) -> WasiFd { +impl IntoInner for Socket { + fn into_inner(self) -> FileDesc { self.0 } } -impl FromInner for Socket { - fn from_inner(inner: WasiFd) -> Socket { +impl FromInner for Socket { + fn from_inner(inner: FileDesc) -> Socket { Socket(inner) } } @@ -97,7 +97,7 @@ impl TcpStream { } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.socket().as_inner().read(bufs) + self.socket().as_inner().read_vectored(bufs) } pub fn is_read_vectored(&self) -> bool { @@ -109,7 +109,7 @@ impl TcpStream { } pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - self.socket().as_inner().write(bufs) + self.socket().as_inner().write_vectored(bufs) } pub fn is_write_vectored(&self) -> bool { diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index e11df38a8ee6..2bd3ec8188a7 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -53,13 +53,9 @@ cfg_select! { mod vexos; pub use self::vexos::*; } - all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { - mod wasip2; - pub use self::wasip2::*; - } - all(target_os = "wasi", target_env = "p1") => { - mod wasip1; - pub use self::wasip1::*; + target_os = "wasi" => { + mod wasi; + pub use self::wasi::*; } target_family = "wasm" => { mod wasm; diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index c207f41cad4b..24f13853b96b 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -1,5 +1,6 @@ use core::num::niche_types::Nanoseconds; +use crate::sys_common::AsInner; use crate::time::Duration; use crate::{fmt, io}; @@ -298,6 +299,12 @@ impl Instant { } } +impl AsInner for Instant { + fn as_inner(&self) -> &Timespec { + &self.t + } +} + impl fmt::Debug for Instant { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Instant") diff --git a/library/std/src/sys/pal/wasip2/cabi_realloc.rs b/library/std/src/sys/pal/wasi/cabi_realloc.rs similarity index 100% rename from library/std/src/sys/pal/wasip2/cabi_realloc.rs rename to library/std/src/sys/pal/wasi/cabi_realloc.rs diff --git a/library/std/src/sys/pal/wasi/helpers.rs b/library/std/src/sys/pal/wasi/helpers.rs new file mode 100644 index 000000000000..6bc41d469584 --- /dev/null +++ b/library/std/src/sys/pal/wasi/helpers.rs @@ -0,0 +1,63 @@ +#![forbid(unsafe_op_in_unsafe_fn)] + +use crate::io as std_io; + +#[inline] +pub fn is_interrupted(errno: i32) -> bool { + errno == libc::EINTR +} + +pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { + use std_io::ErrorKind::*; + match errno as libc::c_int { + libc::E2BIG => ArgumentListTooLong, + libc::EADDRINUSE => AddrInUse, + libc::EADDRNOTAVAIL => AddrNotAvailable, + libc::EBUSY => ResourceBusy, + libc::ECONNABORTED => ConnectionAborted, + libc::ECONNREFUSED => ConnectionRefused, + libc::ECONNRESET => ConnectionReset, + libc::EDEADLK => Deadlock, + libc::EDQUOT => QuotaExceeded, + libc::EEXIST => AlreadyExists, + libc::EFBIG => FileTooLarge, + libc::EHOSTUNREACH => HostUnreachable, + libc::EINTR => Interrupted, + libc::EINVAL => InvalidInput, + libc::EISDIR => IsADirectory, + libc::ELOOP => FilesystemLoop, + libc::ENOENT => NotFound, + libc::ENOMEM => OutOfMemory, + libc::ENOSPC => StorageFull, + libc::ENOSYS => Unsupported, + libc::EMLINK => TooManyLinks, + libc::ENAMETOOLONG => InvalidFilename, + libc::ENETDOWN => NetworkDown, + libc::ENETUNREACH => NetworkUnreachable, + libc::ENOTCONN => NotConnected, + libc::ENOTDIR => NotADirectory, + libc::EPIPE => BrokenPipe, + libc::EROFS => ReadOnlyFilesystem, + libc::ESPIPE => NotSeekable, + libc::ESTALE => StaleNetworkFileHandle, + libc::ETIMEDOUT => TimedOut, + libc::ETXTBSY => ExecutableFileBusy, + libc::EXDEV => CrossesDevices, + libc::EINPROGRESS => InProgress, + libc::EOPNOTSUPP => Unsupported, + libc::EACCES | libc::EPERM => PermissionDenied, + libc::EWOULDBLOCK => WouldBlock, + + _ => Uncategorized, + } +} + +pub fn abort_internal() -> ! { + unsafe { libc::abort() } +} + +#[inline] +#[cfg(target_env = "p1")] +pub(crate) fn err2io(err: wasi::Errno) -> std_io::Error { + std_io::Error::from_raw_os_error(err.raw().into()) +} diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs new file mode 100644 index 000000000000..42629a91e1af --- /dev/null +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -0,0 +1,39 @@ +//! System bindings for the WASI platforms. +//! +//! This module contains the facade (aka platform-specific) implementations of +//! OS level functionality for WASI. Currently this includes both WASIp1 and +//! WASIp2. + +#[allow(unused)] +#[path = "../wasm/atomics/futex.rs"] +pub mod futex; + +pub mod os; +#[path = "../unsupported/pipe.rs"] +pub mod pipe; +pub mod stack_overflow; +#[path = "../unix/time.rs"] +pub mod time; + +#[path = "../unsupported/common.rs"] +#[deny(unsafe_op_in_unsafe_fn)] +#[allow(unused)] +mod common; + +pub use common::*; + +mod helpers; + +// The following exports are listed individually to work around Rust's glob +// import conflict rules. If we glob export `helpers` and `common` together, +// then the compiler complains about conflicts. + +#[cfg(target_env = "p1")] +pub(crate) use helpers::err2io; +pub(crate) use helpers::{abort_internal, decode_error_kind, is_interrupted}; +#[cfg(not(target_env = "p1"))] +pub use os::IsMinusOne; +pub use os::{cvt, cvt_r}; + +#[cfg(not(target_env = "p1"))] +mod cabi_realloc; diff --git a/library/std/src/sys/pal/wasip1/os.rs b/library/std/src/sys/pal/wasi/os.rs similarity index 88% rename from library/std/src/sys/pal/wasip1/os.rs rename to library/std/src/sys/pal/wasi/os.rs index 151ba254ec4c..367c63dfc59e 100644 --- a/library/std/src/sys/pal/wasip1/os.rs +++ b/library/std/src/sys/pal/wasi/os.rs @@ -19,13 +19,20 @@ pub mod libc { } } -pub fn errno() -> i32 { - unsafe extern "C" { - #[thread_local] - static errno: libc::c_int; - } +unsafe extern "C" { + #[thread_local] + #[link_name = "errno"] + static mut libc_errno: libc::c_int; +} - unsafe { errno as i32 } +pub fn errno() -> i32 { + unsafe { libc_errno as i32 } +} + +pub fn set_errno(val: i32) { + unsafe { + libc_errno = val; + } } pub fn error_string(errno: i32) -> String { @@ -149,3 +156,16 @@ impl_is_minus_one! { i8 i16 i32 i64 isize } pub fn cvt(t: T) -> io::Result { if t.is_minus_one() { Err(io::Error::last_os_error()) } else { Ok(t) } } + +pub fn cvt_r(mut f: F) -> crate::io::Result +where + T: IsMinusOne, + F: FnMut() -> T, +{ + loop { + match cvt(f()) { + Err(ref e) if e.is_interrupted() => {} + other => return other, + } + } +} diff --git a/library/std/src/sys/pal/wasi/stack_overflow.rs b/library/std/src/sys/pal/wasi/stack_overflow.rs new file mode 100644 index 000000000000..9fef1ef5ab58 --- /dev/null +++ b/library/std/src/sys/pal/wasi/stack_overflow.rs @@ -0,0 +1,7 @@ +pub struct Handler; + +impl Handler { + pub unsafe fn new() -> Handler { + Handler + } +} diff --git a/library/std/src/sys/pal/wasip1/helpers.rs b/library/std/src/sys/pal/wasip1/helpers.rs deleted file mode 100644 index 404747f0dc75..000000000000 --- a/library/std/src/sys/pal/wasip1/helpers.rs +++ /dev/null @@ -1,114 +0,0 @@ -#![forbid(unsafe_op_in_unsafe_fn)] - -use crate::io as std_io; - -#[inline] -pub fn is_interrupted(errno: i32) -> bool { - errno == wasi::ERRNO_INTR.raw().into() -} - -pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { - use std_io::ErrorKind; - - let Ok(errno) = u16::try_from(errno) else { - return ErrorKind::Uncategorized; - }; - - macro_rules! match_errno { - ($($($errno:ident)|+ => $errkind:ident),*, _ => $wildcard:ident $(,)?) => { - match errno { - $(e if $(e == ::wasi::$errno.raw())||+ => ErrorKind::$errkind),*, - _ => ErrorKind::$wildcard, - } - }; - } - - match_errno! { - ERRNO_2BIG => ArgumentListTooLong, - ERRNO_ACCES => PermissionDenied, - ERRNO_ADDRINUSE => AddrInUse, - ERRNO_ADDRNOTAVAIL => AddrNotAvailable, - ERRNO_AFNOSUPPORT => Unsupported, - ERRNO_AGAIN => WouldBlock, - // ALREADY => "connection already in progress", - // BADF => "bad file descriptor", - // BADMSG => "bad message", - ERRNO_BUSY => ResourceBusy, - // CANCELED => "operation canceled", - // CHILD => "no child processes", - ERRNO_CONNABORTED => ConnectionAborted, - ERRNO_CONNREFUSED => ConnectionRefused, - ERRNO_CONNRESET => ConnectionReset, - ERRNO_DEADLK => Deadlock, - // DESTADDRREQ => "destination address required", - ERRNO_DOM => InvalidInput, - // DQUOT => /* reserved */, - ERRNO_EXIST => AlreadyExists, - // FAULT => "bad address", - ERRNO_FBIG => FileTooLarge, - ERRNO_HOSTUNREACH => HostUnreachable, - // IDRM => "identifier removed", - // ILSEQ => "illegal byte sequence", - // INPROGRESS => "operation in progress", - ERRNO_INTR => Interrupted, - ERRNO_INVAL => InvalidInput, - ERRNO_IO => Uncategorized, - // ISCONN => "socket is connected", - ERRNO_ISDIR => IsADirectory, - ERRNO_LOOP => FilesystemLoop, - // MFILE => "file descriptor value too large", - ERRNO_MLINK => TooManyLinks, - // MSGSIZE => "message too large", - // MULTIHOP => /* reserved */, - ERRNO_NAMETOOLONG => InvalidFilename, - ERRNO_NETDOWN => NetworkDown, - // NETRESET => "connection aborted by network", - ERRNO_NETUNREACH => NetworkUnreachable, - // NFILE => "too many files open in system", - // NOBUFS => "no buffer space available", - ERRNO_NODEV => NotFound, - ERRNO_NOENT => NotFound, - // NOEXEC => "executable file format error", - // NOLCK => "no locks available", - // NOLINK => /* reserved */, - ERRNO_NOMEM => OutOfMemory, - // NOMSG => "no message of the desired type", - // NOPROTOOPT => "protocol not available", - ERRNO_NOSPC => StorageFull, - ERRNO_NOSYS => Unsupported, - ERRNO_NOTCONN => NotConnected, - ERRNO_NOTDIR => NotADirectory, - ERRNO_NOTEMPTY => DirectoryNotEmpty, - // NOTRECOVERABLE => "state not recoverable", - // NOTSOCK => "not a socket", - ERRNO_NOTSUP => Unsupported, - // NOTTY => "inappropriate I/O control operation", - ERRNO_NXIO => NotFound, - // OVERFLOW => "value too large to be stored in data type", - // OWNERDEAD => "previous owner died", - ERRNO_PERM => PermissionDenied, - ERRNO_PIPE => BrokenPipe, - // PROTO => "protocol error", - ERRNO_PROTONOSUPPORT => Unsupported, - // PROTOTYPE => "protocol wrong type for socket", - // RANGE => "result too large", - ERRNO_ROFS => ReadOnlyFilesystem, - ERRNO_SPIPE => NotSeekable, - ERRNO_SRCH => NotFound, - // STALE => /* reserved */, - ERRNO_TIMEDOUT => TimedOut, - ERRNO_TXTBSY => ResourceBusy, - ERRNO_XDEV => CrossesDevices, - ERRNO_NOTCAPABLE => PermissionDenied, - _ => Uncategorized, - } -} - -pub fn abort_internal() -> ! { - unsafe { libc::abort() } -} - -#[inline] -pub(crate) fn err2io(err: wasi::Errno) -> std_io::Error { - std_io::Error::from_raw_os_error(err.raw().into()) -} diff --git a/library/std/src/sys/pal/wasip1/mod.rs b/library/std/src/sys/pal/wasip1/mod.rs deleted file mode 100644 index ae5da3c1f77b..000000000000 --- a/library/std/src/sys/pal/wasip1/mod.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! System bindings for the wasm/web platform -//! -//! This module contains the facade (aka platform-specific) implementations of -//! OS level functionality for wasm. -//! -//! This is all super highly experimental and not actually intended for -//! wide/production use yet, it's still all in the experimental category. This -//! will likely change over time. -//! -//! Currently all functions here are basically stubs that immediately return -//! errors. The hope is that with a portability lint we can turn actually just -//! remove all this and just omit parts of the standard library if we're -//! compiling for wasm. That way it's a compile time error for something that's -//! guaranteed to be a runtime error! - -#[allow(unused)] -#[path = "../wasm/atomics/futex.rs"] -pub mod futex; - -pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; -pub mod time; - -#[path = "../unsupported/common.rs"] -#[deny(unsafe_op_in_unsafe_fn)] -#[allow(unused)] -mod common; - -pub use common::*; - -mod helpers; - -// The following exports are listed individually to work around Rust's glob -// import conflict rules. If we glob export `helpers` and `common` together, -// then the compiler complains about conflicts. - -pub(crate) use helpers::{abort_internal, decode_error_kind, err2io, is_interrupted}; diff --git a/library/std/src/sys/pal/wasip1/time.rs b/library/std/src/sys/pal/wasip1/time.rs deleted file mode 100644 index 0d8d0b59ac14..000000000000 --- a/library/std/src/sys/pal/wasip1/time.rs +++ /dev/null @@ -1,65 +0,0 @@ -#![forbid(unsafe_op_in_unsafe_fn)] - -use crate::time::Duration; - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct Instant(Duration); - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct SystemTime(Duration); - -pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0)); - -fn current_time(clock: wasi::Clockid) -> Duration { - let ts = unsafe { - wasi::clock_time_get( - clock, 1, // precision... seems ignored though? - ) - .unwrap() - }; - Duration::new((ts / 1_000_000_000) as u64, (ts % 1_000_000_000) as u32) -} - -impl Instant { - pub fn now() -> Instant { - Instant(current_time(wasi::CLOCKID_MONOTONIC)) - } - - pub fn checked_sub_instant(&self, other: &Instant) -> Option { - self.0.checked_sub(other.0) - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(Instant(self.0.checked_add(*other)?)) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(Instant(self.0.checked_sub(*other)?)) - } -} - -impl SystemTime { - pub fn now() -> SystemTime { - SystemTime(current_time(wasi::CLOCKID_REALTIME)) - } - - pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime { - SystemTime(Duration::from_nanos(ts)) - } - - pub fn to_wasi_timestamp(&self) -> Option { - self.0.as_nanos().try_into().ok() - } - - pub fn sub_time(&self, other: &SystemTime) -> Result { - self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(SystemTime(self.0.checked_add(*other)?)) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(SystemTime(self.0.checked_sub(*other)?)) - } -} diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs deleted file mode 100644 index c1d89da2677c..000000000000 --- a/library/std/src/sys/pal/wasip2/mod.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! System bindings for the wasi preview 2 target. -//! -//! This is the next evolution of the original wasi target, and is intended to -//! replace that target over time. -//! -//! To begin with, this target mirrors the wasi target 1 to 1, but over -//! time this will change significantly. - -#[allow(unused)] -#[path = "../wasm/atomics/futex.rs"] -pub mod futex; - -#[path = "../wasip1/os.rs"] -pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; -pub mod time; - -#[path = "../unsupported/common.rs"] -#[deny(unsafe_op_in_unsafe_fn)] -#[allow(unused)] -mod common; - -pub use common::*; - -#[path = "../wasip1/helpers.rs"] -mod helpers; - -// The following exports are listed individually to work around Rust's glob -// import conflict rules. If we glob export `helpers` and `common` together, -// then the compiler complains about conflicts. - -pub(crate) use helpers::{abort_internal, decode_error_kind, err2io, is_interrupted}; - -mod cabi_realloc; diff --git a/library/std/src/sys/pal/wasip2/time.rs b/library/std/src/sys/pal/wasip2/time.rs deleted file mode 100644 index 434891839944..000000000000 --- a/library/std/src/sys/pal/wasip2/time.rs +++ /dev/null @@ -1,58 +0,0 @@ -use crate::time::Duration; - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct Instant(Duration); - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct SystemTime(Duration); - -pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0)); - -impl Instant { - pub fn now() -> Instant { - Instant(Duration::from_nanos(wasip2::clocks::monotonic_clock::now())) - } - - pub fn checked_sub_instant(&self, other: &Instant) -> Option { - self.0.checked_sub(other.0) - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(Instant(self.0.checked_add(*other)?)) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(Instant(self.0.checked_sub(*other)?)) - } - - pub(crate) fn as_duration(&self) -> &Duration { - &self.0 - } -} - -impl SystemTime { - pub fn now() -> SystemTime { - let now = wasip2::clocks::wall_clock::now(); - SystemTime(Duration::new(now.seconds, now.nanoseconds)) - } - - pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime { - SystemTime(Duration::from_nanos(ts)) - } - - pub fn to_wasi_timestamp(&self) -> Option { - self.0.as_nanos().try_into().ok() - } - - pub fn sub_time(&self, other: &SystemTime) -> Result { - self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(SystemTime(self.0.checked_add(*other)?)) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(SystemTime(self.0.checked_sub(*other)?)) - } -} diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs index d51ea9ad726b..86d0f3fe49cb 100644 --- a/library/std/src/sys/stdio/mod.rs +++ b/library/std/src/sys/stdio/mod.rs @@ -1,7 +1,7 @@ #![forbid(unsafe_op_in_unsafe_fn)] cfg_select! { - any(target_family = "unix", target_os = "hermit") => { + any(target_family = "unix", target_os = "hermit", target_os = "wasi") => { mod unix; pub use unix::*; } @@ -37,14 +37,6 @@ cfg_select! { mod vexos; pub use vexos::*; } - all(target_os = "wasi", target_env = "p1") => { - mod wasip1; - pub use wasip1::*; - } - all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { - mod wasip2; - pub use wasip2::*; - } target_os = "xous" => { mod xous; pub use xous::*; diff --git a/library/std/src/sys/stdio/unix.rs b/library/std/src/sys/stdio/unix.rs index 8535e3539e9f..ffed376a8e96 100644 --- a/library/std/src/sys/stdio/unix.rs +++ b/library/std/src/sys/stdio/unix.rs @@ -1,14 +1,11 @@ #[cfg(target_os = "hermit")] use hermit_abi::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; -#[cfg(target_family = "unix")] +#[cfg(any(target_family = "unix", target_os = "wasi"))] use libc::{EBADF, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; -#[cfg(target_os = "hermit")] -use crate::os::hermit::io::FromRawFd; -#[cfg(target_family = "unix")] -use crate::os::unix::io::FromRawFd; +use crate::os::fd::FromRawFd; use crate::sys::fd::FileDesc; pub struct Stdin; diff --git a/library/std/src/sys/stdio/wasip1.rs b/library/std/src/sys/stdio/wasip1.rs deleted file mode 100644 index b70efd026f94..000000000000 --- a/library/std/src/sys/stdio/wasip1.rs +++ /dev/null @@ -1,117 +0,0 @@ -#![forbid(unsafe_op_in_unsafe_fn)] - -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::mem::ManuallyDrop; -use crate::os::raw; -use crate::os::wasi::io::{AsRawFd, FromRawFd}; -use crate::sys::fd::WasiFd; - -pub struct Stdin; -pub struct Stdout; -pub struct Stderr; - -impl Stdin { - pub const fn new() -> Stdin { - Stdin - } -} - -impl AsRawFd for Stdin { - #[inline] - fn as_raw_fd(&self) -> raw::c_int { - 0 - } -} - -impl io::Read for Stdin { - fn read(&mut self, data: &mut [u8]) -> io::Result { - self.read_vectored(&mut [IoSliceMut::new(data)]) - } - - fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { - ManuallyDrop::new(unsafe { WasiFd::from_raw_fd(self.as_raw_fd()) }).read_buf(buf) - } - - fn read_vectored(&mut self, data: &mut [IoSliceMut<'_>]) -> io::Result { - ManuallyDrop::new(unsafe { WasiFd::from_raw_fd(self.as_raw_fd()) }).read(data) - } - - #[inline] - fn is_read_vectored(&self) -> bool { - true - } -} - -impl Stdout { - pub const fn new() -> Stdout { - Stdout - } -} - -impl AsRawFd for Stdout { - #[inline] - fn as_raw_fd(&self) -> raw::c_int { - 1 - } -} - -impl io::Write for Stdout { - fn write(&mut self, data: &[u8]) -> io::Result { - self.write_vectored(&[IoSlice::new(data)]) - } - - fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { - ManuallyDrop::new(unsafe { WasiFd::from_raw_fd(self.as_raw_fd()) }).write(data) - } - - #[inline] - fn is_write_vectored(&self) -> bool { - true - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl Stderr { - pub const fn new() -> Stderr { - Stderr - } -} - -impl AsRawFd for Stderr { - #[inline] - fn as_raw_fd(&self) -> raw::c_int { - 2 - } -} - -impl io::Write for Stderr { - fn write(&mut self, data: &[u8]) -> io::Result { - self.write_vectored(&[IoSlice::new(data)]) - } - - fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { - ManuallyDrop::new(unsafe { WasiFd::from_raw_fd(self.as_raw_fd()) }).write(data) - } - - #[inline] - fn is_write_vectored(&self) -> bool { - true - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE; - -pub fn is_ebadf(err: &io::Error) -> bool { - err.raw_os_error() == Some(wasi::ERRNO_BADF.raw().into()) -} - -pub fn panic_output() -> Option { - Some(Stderr::new()) -} diff --git a/library/std/src/sys/stdio/wasip2.rs b/library/std/src/sys/stdio/wasip2.rs deleted file mode 100644 index 1fcb49a083dd..000000000000 --- a/library/std/src/sys/stdio/wasip2.rs +++ /dev/null @@ -1,120 +0,0 @@ -use wasip2::cli; -use wasip2::io::streams::{Error, InputStream, OutputStream, StreamError}; - -use crate::io::{self, BorrowedBuf, BorrowedCursor}; - -pub struct Stdin(Option); -pub struct Stdout(Option); -pub struct Stderr(Option); - -fn error_to_io(err: Error) -> io::Error { - // There exists a function in `wasi:filesystem` to optionally acquire an - // error code from an error, but the streams in use in this module are - // exclusively used with stdio meaning that a filesystem error is not - // possible here. - // - // In lieu of an error code, which WASIp2 does not specify, this instead - // carries along the `to_debug_string` implementation that the host - // supplies. If this becomes too expensive in the future this could also - // become `io::Error::from_raw_os_error(libc::EIO)` or similar. - io::Error::new(io::ErrorKind::Other, err.to_debug_string()) -} - -impl Stdin { - pub const fn new() -> Stdin { - Stdin(None) - } - - fn stream(&mut self) -> &InputStream { - self.0.get_or_insert_with(cli::stdin::get_stdin) - } -} - -impl io::Read for Stdin { - fn read(&mut self, data: &mut [u8]) -> io::Result { - let mut buf = BorrowedBuf::from(data); - self.read_buf(buf.unfilled())?; - Ok(buf.len()) - } - - fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> io::Result<()> { - match self.stream().blocking_read(u64::try_from(buf.capacity()).unwrap()) { - Ok(result) => { - buf.append(&result); - Ok(()) - } - Err(StreamError::Closed) => Ok(()), - Err(StreamError::LastOperationFailed(e)) => Err(error_to_io(e)), - } - } -} - -impl Stdout { - pub const fn new() -> Stdout { - Stdout(None) - } - - fn stream(&mut self) -> &OutputStream { - self.0.get_or_insert_with(cli::stdout::get_stdout) - } -} - -fn write(stream: &OutputStream, buf: &[u8]) -> io::Result { - // WASIp2's `blocking_write_and_flush` function is defined as accepting no - // more than 4096 bytes. Larger writes can be issued by manually using - // `check_write`, `write`, and `blocking_flush`, but for now just go ahead - // and use `blocking_write_and_flush` and report a short write and let a - // higher level loop over the result. - const MAX: usize = 4096; - let buf = &buf[..buf.len().min(MAX)]; - match stream.blocking_write_and_flush(buf) { - Ok(()) => Ok(buf.len()), - Err(StreamError::Closed) => Ok(0), - Err(StreamError::LastOperationFailed(e)) => Err(error_to_io(e)), - } -} - -impl io::Write for Stdout { - fn write(&mut self, data: &[u8]) -> io::Result { - write(self.stream(), data) - } - - fn flush(&mut self) -> io::Result<()> { - // Note that `OutputStream` has a `flush` function but for stdio all - // writes are accompanied with a flush which means that this flush - // doesn't need to do anything. - Ok(()) - } -} - -impl Stderr { - pub const fn new() -> Stderr { - Stderr(None) - } - - fn stream(&mut self) -> &OutputStream { - self.0.get_or_insert_with(cli::stderr::get_stderr) - } -} - -impl io::Write for Stderr { - fn write(&mut self, data: &[u8]) -> io::Result { - write(self.stream(), data) - } - - fn flush(&mut self) -> io::Result<()> { - // See `Stdout::flush` for why this is a noop. - Ok(()) - } -} - -pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE; - -pub fn is_ebadf(_err: &io::Error) -> bool { - // WASIp2 stdio streams are always available so ebadf never shows up. - false -} - -pub fn panic_output() -> Option { - Some(Stderr::new()) -} diff --git a/library/std/src/sys/thread/mod.rs b/library/std/src/sys/thread/mod.rs index b98be62be0ad..cb6bf6518f81 100644 --- a/library/std/src/sys/thread/mod.rs +++ b/library/std/src/sys/thread/mod.rs @@ -48,7 +48,7 @@ cfg_select! { mod unsupported; pub use unsupported::{Thread, current_os_id, set_name, yield_now, DEFAULT_MIN_STACK_SIZE}; } - target_family = "unix" => { + any(target_family = "unix", target_os = "wasi") => { mod unix; pub use unix::{Thread, available_parallelism, current_os_id, sleep, yield_now, DEFAULT_MIN_STACK_SIZE}; #[cfg(not(any( @@ -58,6 +58,7 @@ cfg_select! { target_os = "redox", target_os = "hurd", target_os = "aix", + target_os = "wasi", )))] pub use unix::set_name; #[cfg(any( @@ -71,6 +72,7 @@ cfg_select! { target_os = "hurd", target_os = "fuchsia", target_os = "vxworks", + target_os = "wasi", ))] pub use unix::sleep_until; #[expect(dead_code)] @@ -82,6 +84,7 @@ cfg_select! { target_os = "redox", target_os = "hurd", target_os = "aix", + target_os = "wasi", ))] pub use unsupported::set_name; } @@ -92,27 +95,6 @@ cfg_select! { mod unsupported; pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, DEFAULT_MIN_STACK_SIZE}; } - all(target_os = "wasi", target_env = "p1") => { - mod wasip1; - pub use wasip1::{DEFAULT_MIN_STACK_SIZE, sleep, yield_now}; - #[cfg(target_feature = "atomics")] - pub use wasip1::{Thread, available_parallelism}; - #[expect(dead_code)] - mod unsupported; - pub use unsupported::{current_os_id, set_name}; - #[cfg(not(target_feature = "atomics"))] - pub use unsupported::{Thread, available_parallelism}; - } - all(target_os = "wasi", any(target_env = "p2", target_env = "p3")) => { - mod wasip2; - pub use wasip2::{sleep, sleep_until}; - #[expect(dead_code)] - mod unsupported; - // Note that unlike WASIp1 even if the wasm `atomics` feature is enabled - // there is no support for threads, not even experimentally, not even in - // wasi-libc. Thus this is unconditionally unsupported. - pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, yield_now, DEFAULT_MIN_STACK_SIZE}; - } all(target_family = "wasm", target_feature = "atomics") => { mod wasm; pub use wasm::sleep; @@ -150,7 +132,7 @@ cfg_select! { target_os = "hurd", target_os = "fuchsia", target_os = "vxworks", - all(target_os = "wasi", not(target_env = "p1")), + target_os = "wasi", )))] pub fn sleep_until(deadline: crate::time::Instant) { use crate::time::Instant; diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 4adc94d0e5c9..18cdea0e1b1b 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -5,6 +5,7 @@ target_os = "redox", target_os = "hurd", target_os = "aix", + target_os = "wasi", )))] use crate::ffi::CStr; use crate::mem::{self, DropGuard, ManuallyDrop}; @@ -127,6 +128,7 @@ impl Thread { assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret)); } + #[cfg(not(target_os = "wasi"))] pub fn id(&self) -> libc::pthread_t { self.id } @@ -588,6 +590,7 @@ pub fn sleep(dur: Duration) { target_os = "hurd", target_os = "fuchsia", target_os = "vxworks", + target_os = "wasi", ))] pub fn sleep_until(deadline: crate::time::Instant) { use crate::time::Instant; diff --git a/library/std/src/sys/thread/wasip1.rs b/library/std/src/sys/thread/wasip1.rs deleted file mode 100644 index 9287a9c5485c..000000000000 --- a/library/std/src/sys/thread/wasip1.rs +++ /dev/null @@ -1,183 +0,0 @@ -#![forbid(unsafe_op_in_unsafe_fn)] - -#[cfg(target_feature = "atomics")] -use crate::io; -use crate::mem; -#[cfg(target_feature = "atomics")] -use crate::num::NonZero; -#[cfg(target_feature = "atomics")] -use crate::sys::os; -#[cfg(target_feature = "atomics")] -use crate::thread::ThreadInit; -use crate::time::Duration; -#[cfg(target_feature = "atomics")] -use crate::{cmp, ptr}; - -// Add a few symbols not in upstream `libc` just yet. -#[cfg(target_feature = "atomics")] -mod libc { - pub use libc::*; - - pub use crate::ffi; - - // defined in wasi-libc - // https://github.com/WebAssembly/wasi-libc/blob/a6f871343313220b76009827ed0153586361c0d5/libc-top-half/musl/include/alltypes.h.in#L108 - #[repr(C)] - union pthread_attr_union { - __i: [ffi::c_int; if size_of::() == 8 { 14 } else { 9 }], - __vi: [ffi::c_int; if size_of::() == 8 { 14 } else { 9 }], - __s: [ffi::c_ulong; if size_of::() == 8 { 7 } else { 9 }], - } - - #[repr(C)] - pub struct pthread_attr_t { - __u: pthread_attr_union, - } - - #[allow(non_camel_case_types)] - pub type pthread_t = *mut ffi::c_void; - - pub const _SC_NPROCESSORS_ONLN: ffi::c_int = 84; - - unsafe extern "C" { - pub fn pthread_create( - native: *mut pthread_t, - attr: *const pthread_attr_t, - f: extern "C" fn(*mut ffi::c_void) -> *mut ffi::c_void, - value: *mut ffi::c_void, - ) -> ffi::c_int; - pub fn pthread_join(native: pthread_t, value: *mut *mut ffi::c_void) -> ffi::c_int; - pub fn pthread_attr_init(attrp: *mut pthread_attr_t) -> ffi::c_int; - pub fn pthread_attr_setstacksize( - attr: *mut pthread_attr_t, - stack_size: libc::size_t, - ) -> ffi::c_int; - pub fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> ffi::c_int; - pub fn pthread_detach(thread: pthread_t) -> ffi::c_int; - } -} - -#[cfg(target_feature = "atomics")] -pub struct Thread { - id: libc::pthread_t, -} - -#[cfg(target_feature = "atomics")] -impl Drop for Thread { - fn drop(&mut self) { - let ret = unsafe { libc::pthread_detach(self.id) }; - debug_assert_eq!(ret, 0); - } -} - -pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024; - -#[cfg(target_feature = "atomics")] -impl Thread { - // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(stack: usize, init: Box) -> io::Result { - let data = Box::into_raw(init); - let mut native: libc::pthread_t = unsafe { mem::zeroed() }; - let mut attr: libc::pthread_attr_t = unsafe { mem::zeroed() }; - assert_eq!(unsafe { libc::pthread_attr_init(&mut attr) }, 0); - - let stack_size = cmp::max(stack, DEFAULT_MIN_STACK_SIZE); - - match unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) } { - 0 => {} - n => { - assert_eq!(n, libc::EINVAL); - // EINVAL means |stack_size| is either too small or not a - // multiple of the system page size. Because it's definitely - // >= PTHREAD_STACK_MIN, it must be an alignment issue. - // Round up to the nearest page and try again. - let page_size = os::page_size(); - let stack_size = - (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); - assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0); - } - }; - - let ret = unsafe { libc::pthread_create(&mut native, &attr, thread_start, data as *mut _) }; - // Note: if the thread creation fails and this assert fails, then data will - // be leaked. However, an alternative design could cause double-free - // which is clearly worse. - assert_eq!(unsafe { libc::pthread_attr_destroy(&mut attr) }, 0); - - return if ret != 0 { - // The thread failed to start and as a result data was not consumed. Therefore, it is - // safe to reconstruct the box so that it gets deallocated. - unsafe { - drop(Box::from_raw(data)); - } - Err(io::Error::from_raw_os_error(ret)) - } else { - Ok(Thread { id: native }) - }; - - extern "C" fn thread_start(data: *mut libc::c_void) -> *mut libc::c_void { - // SAFETY: we are simply recreating the box that was leaked earlier. - let init = unsafe { Box::from_raw(data as *mut ThreadInit) }; - let rust_start = init.init(); - rust_start(); - ptr::null_mut() - } - } - - pub fn join(self) { - let id = mem::ManuallyDrop::new(self).id; - let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - if ret != 0 { - rtabort!("failed to join thread: {}", io::Error::from_raw_os_error(ret)); - } - } -} - -#[cfg(target_feature = "atomics")] -pub fn available_parallelism() -> io::Result> { - match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { - -1 => Err(io::Error::last_os_error()), - cpus => NonZero::new(cpus as usize).ok_or(io::Error::UNKNOWN_THREAD_COUNT), - } -} - -pub fn yield_now() { - let ret = unsafe { wasi::sched_yield() }; - debug_assert_eq!(ret, Ok(())); -} - -pub fn sleep(dur: Duration) { - let mut nanos = dur.as_nanos(); - while nanos > 0 { - const USERDATA: wasi::Userdata = 0x0123_45678; - - let clock = wasi::SubscriptionClock { - id: wasi::CLOCKID_MONOTONIC, - timeout: u64::try_from(nanos).unwrap_or(u64::MAX), - precision: 0, - flags: 0, - }; - nanos -= u128::from(clock.timeout); - - let in_ = wasi::Subscription { - userdata: USERDATA, - u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } }, - }; - unsafe { - let mut event: wasi::Event = mem::zeroed(); - let res = wasi::poll_oneoff(&in_, &mut event, 1); - match (res, event) { - ( - Ok(1), - wasi::Event { - userdata: USERDATA, - error: wasi::ERRNO_SUCCESS, - type_: wasi::EVENTTYPE_CLOCK, - .. - }, - ) => {} - _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), - } - } - } -} diff --git a/library/std/src/sys/thread/wasip2.rs b/library/std/src/sys/thread/wasip2.rs deleted file mode 100644 index 420cad2a5e4a..000000000000 --- a/library/std/src/sys/thread/wasip2.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::time::{Duration, Instant}; - -pub fn sleep(dur: Duration) { - // Sleep in increments of `u64::MAX` nanoseconds until the `dur` is - // entirely drained. - let mut remaining = dur.as_nanos(); - while remaining > 0 { - let amt = u64::try_from(remaining).unwrap_or(u64::MAX); - wasip2::clocks::monotonic_clock::subscribe_duration(amt).block(); - remaining -= u128::from(amt); - } -} - -pub fn sleep_until(deadline: Instant) { - match u64::try_from(deadline.into_inner().as_duration().as_nanos()) { - // If the point in time we're sleeping to fits within a 64-bit - // number of nanoseconds then directly use `subscribe_instant`. - Ok(deadline) => { - wasip2::clocks::monotonic_clock::subscribe_instant(deadline).block(); - } - // ... otherwise we're sleeping for 500+ years relative to the - // "start" of what the system is using as a clock so speed/accuracy - // is not so much of a concern. Use `sleep` instead. - Err(_) => { - let now = Instant::now(); - - if let Some(delay) = deadline.checked_duration_since(now) { - sleep(delay); - } - } - } -} diff --git a/tests/rustdoc-js-std/unbox-type-result.js b/tests/rustdoc-js-std/unbox-type-result.js index 1f5cba58adf6..e4765d87637c 100644 --- a/tests/rustdoc-js-std/unbox-type-result.js +++ b/tests/rustdoc-js-std/unbox-type-result.js @@ -8,7 +8,6 @@ const EXPECTED = [ query: "File -> Metadata", others: [ { path: "std::fs::File", name: "metadata" }, - { path: "std::fs::File", name: "metadata_at" }, ] }, { diff --git a/triagebot.toml b/triagebot.toml index 6ad8dd6b4c88..db859bd54efb 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -455,8 +455,7 @@ trigger_files = [ [autolabel."O-wasi"] trigger_files = [ - "library/std/src/sys/pal/wasip1", - "library/std/src/sys/pal/wasip2", + "library/std/src/sys/pal/wasi", "library/std/src/os/wasi" ] From e0c09b546a1278ec185ba3d9348223ab11e1f394 Mon Sep 17 00:00:00 2001 From: Eduard Stefes Date: Mon, 8 Dec 2025 15:50:21 +0100 Subject: [PATCH 0429/3801] fix va_list test by adding a llvmir signext check s390x has no option to directly pass 32bit values therefor i32 parameters need an optional llvmir signext attribute. --- tests/codegen-llvm/cffi/c-variadic-va_list.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/codegen-llvm/cffi/c-variadic-va_list.rs b/tests/codegen-llvm/cffi/c-variadic-va_list.rs index e2652491f421..b2f5ffc3495b 100644 --- a/tests/codegen-llvm/cffi/c-variadic-va_list.rs +++ b/tests/codegen-llvm/cffi/c-variadic-va_list.rs @@ -22,15 +22,15 @@ pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) { // CHECK-LABEL: use_foreign_c_variadic_1_1 pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, i32 noundef 42) + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, i32 noundef{{( signext)?}} 42) foreign_c_variadic_1(ap, 42i32); } pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, i32 noundef 2, i32 noundef 42) + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, i32 noundef{{( signext)?}} 2, i32 noundef{{( signext)?}} 42) foreign_c_variadic_1(ap, 2i32, 42i32); } pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) { - // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, i32 noundef 2, i32 noundef 42, i32 noundef 0) + // CHECK: call void ({{.*}}, ...) @foreign_c_variadic_1({{.*}} %ap, i32 noundef{{( signext)?}} 2, i32 noundef{{( signext)?}} 42, i32 noundef{{( signext)?}} 0) foreign_c_variadic_1(ap, 2i32, 42i32, 0i32); } From b1993dce20001b5a9a062ce9035bcee0eb711fd0 Mon Sep 17 00:00:00 2001 From: km247 Date: Sat, 30 Aug 2025 12:12:08 -0500 Subject: [PATCH 0430/3801] Implement lint to check for usages of `from_raw_parts` where the same expression is used for the length and the capacity --- CHANGELOG.md | 1 + README.md | 2 +- book/src/README.md | 2 +- clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + clippy_lints/src/same_length_and_capacity.rs | 105 +++++++++++++++++++ clippy_utils/src/sym.rs | 1 + tests/ui/same_length_and_capacity.rs | 27 +++++ tests/ui/same_length_and_capacity.stderr | 20 ++++ 9 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 clippy_lints/src/same_length_and_capacity.rs create mode 100644 tests/ui/same_length_and_capacity.rs create mode 100644 tests/ui/same_length_and_capacity.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c81fa47eca9..84accb363988 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6839,6 +6839,7 @@ Released 2018-09-13 [`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#reversed_empty_ranges [`same_functions_in_if_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_functions_in_if_condition [`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push +[`same_length_and_capacity`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_length_and_capacity [`same_name_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_name_method [`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some [`seek_from_current`]: https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current diff --git a/README.md b/README.md index 20a5e997e629..78498c73ae78 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are over 800 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category. diff --git a/book/src/README.md b/book/src/README.md index 5d2c3972b060..c5b264c9f703 100644 --- a/book/src/README.md +++ b/book/src/README.md @@ -5,7 +5,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are over 800 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 1a02c2166454..c982463a3227 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -666,6 +666,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::returns::LET_AND_RETURN_INFO, crate::returns::NEEDLESS_RETURN_INFO, crate::returns::NEEDLESS_RETURN_WITH_QUESTION_MARK_INFO, + crate::same_length_and_capacity::SAME_LENGTH_AND_CAPACITY_INFO, crate::same_name_method::SAME_NAME_METHOD_INFO, crate::self_named_constructors::SELF_NAMED_CONSTRUCTORS_INFO, crate::semicolon_block::SEMICOLON_INSIDE_BLOCK_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 5b39d8844797..e92d1a2ac789 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -318,6 +318,7 @@ mod replace_box; mod reserve_after_initialization; mod return_self_not_must_use; mod returns; +mod same_length_and_capacity; mod same_name_method; mod self_named_constructors; mod semicolon_block; @@ -852,6 +853,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(|_| Box::new(volatile_composites::VolatileComposites)), Box::new(|_| Box::::default()), Box::new(move |_| Box::new(manual_ilog2::ManualIlog2::new(conf))), + Box::new(|_| Box::new(same_length_and_capacity::SameLengthAndCapacity)), // add late passes here, used by `cargo dev new_lint` ]; store.late_passes.extend(late_lints); diff --git a/clippy_lints/src/same_length_and_capacity.rs b/clippy_lints/src/same_length_and_capacity.rs new file mode 100644 index 000000000000..042dec35f7c9 --- /dev/null +++ b/clippy_lints/src/same_length_and_capacity.rs @@ -0,0 +1,105 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::res::MaybeDef; +use clippy_utils::{eq_expr_value, sym}; +use rustc_hir::{Expr, ExprKind, LangItem, QPath}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; +use rustc_span::symbol::sym as rustc_sym; + +declare_clippy_lint! { + /// ### What it does + /// + /// Checks for usages of `Vec::from_raw_parts` and `String::from_raw_parts` + /// where the same expression is used for the length and the capacity. + /// + /// ### Why is this bad? + /// + /// If the same expression is being passed for the length and + /// capacity, it is most likely a semantic error. In the case of a + /// Vec, for example, the only way to end up with one that has + /// the same length and capacity is by going through a boxed slice, + /// e.g. `Box::from(some_vec)`, which shrinks the capacity to match + /// the length. + /// + /// ### Example + /// + /// ```no_run + /// #![feature(vec_into_raw_parts)] + /// let mut original: Vec:: = Vec::with_capacity(20); + /// original.extend([1, 2, 3, 4, 5]); + /// + /// let (ptr, mut len, cap) = original.into_raw_parts(); + /// + /// // I will add three more integers: + /// unsafe { + /// let ptr = ptr as *mut i32; + /// + /// for i in 6..9 { + /// *ptr.add(i - 1) = i as i32; + /// len += 1; + /// } + /// } + /// + /// // But I forgot the capacity was separate from the length: + /// let reconstructed = unsafe { Vec::from_raw_parts(ptr, len, len) }; + /// ``` + /// + /// Use instead: + /// ```no_run + /// #![feature(vec_into_raw_parts)] + /// let mut original: Vec:: = Vec::with_capacity(20); + /// original.extend([1, 2, 3, 4, 5]); + /// + /// let (ptr, mut len, cap) = original.into_raw_parts(); + /// + /// // I will add three more integers: + /// unsafe { + /// let ptr = ptr as *mut i32; + /// + /// for i in 6..9 { + /// *ptr.add(i - 1) = i as i32; + /// len += 1; + /// } + /// } + /// + /// // This time, leverage the previously saved capacity: + /// let reconstructed = unsafe { Vec::from_raw_parts(ptr, len, cap) }; + /// ``` + #[clippy::version = "1.93.0"] + pub SAME_LENGTH_AND_CAPACITY, + pedantic, + "`from_raw_parts` with same length and capacity" +} +declare_lint_pass!(SameLengthAndCapacity => [SAME_LENGTH_AND_CAPACITY]); + +impl<'tcx> LateLintPass<'tcx> for SameLengthAndCapacity { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::Call(path_expr, args) = expr.kind + && let ExprKind::Path(QPath::TypeRelative(ty, fn_path)) = path_expr.kind + && fn_path.ident.name == sym::from_raw_parts + && args.len() >= 3 + && eq_expr_value(cx, &args[1], &args[2]) + { + let middle_ty = cx.typeck_results().node_type(ty.hir_id); + if middle_ty.is_diag_item(cx, rustc_sym::Vec) { + span_lint_and_help( + cx, + SAME_LENGTH_AND_CAPACITY, + expr.span, + "usage of `Vec::from_raw_parts` with the same expression for length and capacity", + None, + "try `Box::from(slice::from_raw_parts(...)).into::>()`", + ); + } else if middle_ty.is_lang_item(cx, LangItem::String) { + span_lint_and_help( + cx, + SAME_LENGTH_AND_CAPACITY, + expr.span, + "usage of `String::from_raw_parts` with the same expression for length and capacity", + None, + "try `String::from(str::from_utf8_unchecked(slice::from_raw_parts(...)))`", + ); + } + } + } +} diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 00f4a9c7e586..9a7987e60812 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -167,6 +167,7 @@ generate! { from_ne_bytes, from_ptr, from_raw, + from_raw_parts, from_str_radix, fs, fuse, diff --git a/tests/ui/same_length_and_capacity.rs b/tests/ui/same_length_and_capacity.rs new file mode 100644 index 000000000000..999fcf89881d --- /dev/null +++ b/tests/ui/same_length_and_capacity.rs @@ -0,0 +1,27 @@ +#![warn(clippy::same_length_and_capacity)] + +fn main() { + let mut my_vec: Vec = Vec::with_capacity(20); + my_vec.extend([1, 2, 3, 4, 5]); + let (ptr, mut len, cap) = my_vec.into_raw_parts(); + len = 8; + + let _reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len, len) }; + //~^ same_length_and_capacity + + // Don't want to lint different expressions for len and cap + let _properly_reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len, cap) }; + + // Don't want to lint if len and cap are distinct variables but happen to be equal + let len_from_cap = cap; + let _another_properly_reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len_from_cap, cap) }; + + let my_string = String::from("hello"); + let (string_ptr, string_len, string_cap) = my_string.into_raw_parts(); + + let _reconstructed_string = unsafe { String::from_raw_parts(string_ptr, string_len, string_len) }; + //~^ same_length_and_capacity + + // Don't want to lint different expressions for len and cap + let _properly_reconstructed_string = unsafe { String::from_raw_parts(string_ptr, string_len, string_cap) }; +} diff --git a/tests/ui/same_length_and_capacity.stderr b/tests/ui/same_length_and_capacity.stderr new file mode 100644 index 000000000000..6fc852831269 --- /dev/null +++ b/tests/ui/same_length_and_capacity.stderr @@ -0,0 +1,20 @@ +error: usage of `Vec::from_raw_parts` with the same expression for length and capacity + --> tests/ui/same_length_and_capacity.rs:9:39 + | +LL | let _reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len, len) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try `Box::from(slice::from_raw_parts(...)).into::>()` + = note: `-D clippy::same-length-and-capacity` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::same_length_and_capacity)]` + +error: usage of `String::from_raw_parts` with the same expression for length and capacity + --> tests/ui/same_length_and_capacity.rs:22:42 + | +LL | let _reconstructed_string = unsafe { String::from_raw_parts(string_ptr, string_len, string_len) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try `String::from(str::from_utf8_unchecked(slice::from_raw_parts(...)))` + +error: aborting due to 2 previous errors + From c03344429d9b482b85d66e1d0589e813afc4d2b9 Mon Sep 17 00:00:00 2001 From: Roy Ammerschuber Date: Wed, 3 Dec 2025 10:57:38 +0100 Subject: [PATCH 0431/3801] tree borrows: split perform_protector_end_access from perform_access --- .../src/borrow_tracker/tree_borrows/mod.rs | 11 +- .../src/borrow_tracker/tree_borrows/tree.rs | 118 ++++++++++-------- 2 files changed, 71 insertions(+), 58 deletions(-) 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 e1da12282cd9..5322b067aec6 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -59,7 +59,9 @@ impl<'tcx> Tree { let span = machine.current_user_relevant_span(); self.perform_access( prov, - Some((range, access_kind, diagnostics::AccessCause::Explicit(access_kind))), + range, + access_kind, + diagnostics::AccessCause::Explicit(access_kind), global, alloc_id, span, @@ -93,8 +95,7 @@ impl<'tcx> Tree { alloc_id: AllocId, // diagnostics ) -> InterpResult<'tcx> { let span = machine.current_user_relevant_span(); - // `None` makes it the magic on-protector-end operation - self.perform_access(ProvenanceExtra::Concrete(tag), None, global, alloc_id, span)?; + self.perform_protector_end_access(tag, global, alloc_id, span)?; self.update_exposure_for_protector_release(tag); @@ -343,7 +344,9 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { tree_borrows.perform_access( parent_prov, - Some((range_in_alloc, AccessKind::Read, diagnostics::AccessCause::Reborrow)), + range_in_alloc, + AccessKind::Read, + diagnostics::AccessCause::Reborrow, this.machine.borrow_tracker.as_ref().unwrap(), alloc_id, this.machine.current_user_relevant_span(), diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 7fc9fa786e10..547ea5f9cc8b 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -828,7 +828,9 @@ impl<'tcx> Tree { ) -> InterpResult<'tcx> { self.perform_access( prov, - Some((access_range, AccessKind::Write, diagnostics::AccessCause::Dealloc)), + access_range, + AccessKind::Write, + diagnostics::AccessCause::Dealloc, global, alloc_id, span, @@ -903,14 +905,6 @@ impl<'tcx> Tree { /// to each location of the first component of `access_range_and_kind`, /// on every tag of the allocation. /// - /// If `access_range_and_kind` is `None`, this is interpreted as the special - /// access that is applied on protector release: - /// - the access will be applied only to accessed locations of the allocation, - /// - it will not be visible to children, - /// - it will be recorded as a `FnExit` diagnostic access - /// - and it will be a read except if the location is `Unique`, i.e. has been written to, - /// in which case it will be a write. - /// /// `LocationState::perform_access` will take care of raising transition /// errors and updating the `accessed` status of each location, /// this traversal adds to that: @@ -920,7 +914,9 @@ impl<'tcx> Tree { pub fn perform_access( &mut self, prov: ProvenanceExtra, - access_range_and_kind: Option<(AllocRange, AccessKind, diagnostics::AccessCause)>, + access_range: AllocRange, + access_kind: AccessKind, + access_cause: AccessCause, // diagnostics global: &GlobalState, alloc_id: AllocId, // diagnostics span: Span, // diagnostics @@ -934,61 +930,75 @@ impl<'tcx> Tree { ProvenanceExtra::Concrete(tag) => Some(self.tag_mapping.get(&tag).unwrap()), ProvenanceExtra::Wildcard => None, }; - if let Some((access_range, access_kind, access_cause)) = access_range_and_kind { - // Default branch: this is a "normal" access through a known range. - // We iterate over affected locations and traverse the tree for each of them. - for (loc_range, loc) in self.locations.iter_mut(access_range.start, access_range.size) { + // We iterate over affected locations and traverse the tree for each of them. + for (loc_range, loc) in self.locations.iter_mut(access_range.start, access_range.size) { + loc.perform_access( + self.roots.iter().copied(), + &mut self.nodes, + source_idx, + loc_range, + Some(access_range), + access_kind, + access_cause, + global, + alloc_id, + span, + ChildrenVisitMode::VisitChildrenOfAccessed, + )?; + } + interp_ok(()) + } + /// This is the special access that is applied on protector release: + /// - the access will be applied only to accessed locations of the allocation, + /// - it will not be visible to children, + /// - it will be recorded as a `FnExit` diagnostic access + /// - and it will be a read except if the location is `Unique`, i.e. has been written to, + /// in which case it will be a write. + /// - otherwise identical to `Tree::perform_access` + pub fn perform_protector_end_access( + &mut self, + tag: BorTag, + global: &GlobalState, + alloc_id: AllocId, // diagnostics + span: Span, // diagnostics + ) -> InterpResult<'tcx> { + #[cfg(feature = "expensive-consistency-checks")] + if self.roots.len() > 1 { + self.verify_wildcard_consistency(global); + } + + let source_idx = self.tag_mapping.get(&tag).unwrap(); + + // This is a special access through the entire allocation. + // It actually only affects `accessed` locations, so we need + // to filter on those before initiating the traversal. + // + // In addition this implicit access should not be visible to children, + // thus the use of `traverse_nonchildren`. + // See the test case `returned_mut_is_usable` from + // `tests/pass/tree_borrows/tree-borrows.rs` for an example of + // why this is important. + for (loc_range, loc) in self.locations.iter_mut_all() { + // Only visit accessed permissions + if let Some(p) = loc.perms.get(source_idx) + && let Some(access_kind) = p.permission.protector_end_access() + && p.accessed + { + let access_cause = diagnostics::AccessCause::FnExit(access_kind); loc.perform_access( self.roots.iter().copied(), &mut self.nodes, - source_idx, + Some(source_idx), loc_range, - Some(access_range), + None, access_kind, access_cause, global, alloc_id, span, - ChildrenVisitMode::VisitChildrenOfAccessed, + ChildrenVisitMode::SkipChildrenOfAccessed, )?; } - } else { - // This is a special access through the entire allocation. - // It actually only affects `accessed` locations, so we need - // to filter on those before initiating the traversal. - // - // In addition this implicit access should not be visible to children, - // thus the use of `traverse_nonchildren`. - // See the test case `returned_mut_is_usable` from - // `tests/pass/tree_borrows/tree-borrows.rs` for an example of - // why this is important. - - // Wildcard references are never protected. So this can never be - // called with a wildcard reference. - let source_idx = source_idx.unwrap(); - - for (loc_range, loc) in self.locations.iter_mut_all() { - // Only visit accessed permissions - if let Some(p) = loc.perms.get(source_idx) - && let Some(access_kind) = p.permission.protector_end_access() - && p.accessed - { - let access_cause = diagnostics::AccessCause::FnExit(access_kind); - loc.perform_access( - self.roots.iter().copied(), - &mut self.nodes, - Some(source_idx), - loc_range, - None, - access_kind, - access_cause, - global, - alloc_id, - span, - ChildrenVisitMode::SkipChildrenOfAccessed, - )?; - } - } } interp_ok(()) } From bbb2f274bb153e6b1f9ec02f5d3cde783bb9fff8 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 2 Dec 2025 17:06:10 +0900 Subject: [PATCH 0432/3801] Mention sharing the solver with rust-analyzer --- src/doc/rustc-dev-guide/src/SUMMARY.md | 1 + .../sharing-crates-with-rust-analyzer.md | 192 ++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index c136d37160c5..1490db880919 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -185,6 +185,7 @@ - [Proof trees](./solve/proof-trees.md) - [Opaque types](./solve/opaque-types.md) - [Significant changes and quirks](./solve/significant-changes.md) + - [Sharing the trait solver with rust-analyzer](./solve/sharing-crates-with-rust-analyzer.md) - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md) - [Variance](./variance.md) - [Coherence checking](./coherence.md) diff --git a/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md b/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md new file mode 100644 index 000000000000..bf0d4fe3a11b --- /dev/null +++ b/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md @@ -0,0 +1,192 @@ +# Sharing the trait solver with rust-analyzer + +rust-analyzer can be viewed as a compiler frontend: it performs tasks similar to the parts of rustc +that run before code generation, such as parsing, lexing, AST construction and lowering, HIR +lowering, and even limited MIR building and const evaluation. + +However, because rust-analyzer is primarily a language server, its architecture differs in several +important ways from that of rustc. +Despite these differences, a substantial portion of its responsibilities—most notably type +inference and trait solving—overlap with the compiler. + +To avoid duplication and to maintain consistency between the two implementations, rust-analyzer +reuses several crates from rustc, relying on shared abstractions wherever possible. + +## Shared Crates + +Currently, rust-analyzer depends on several `rustc_*` crates from the compiler: + +- `rustc_abi` +- `rustc_ast_ir` +- `rustc_index` +- `rustc_lexer` +- `rustc_next_trait_solver` +- `rustc_parse_format` +- `rustc_pattern_analysis` +- `rustc_type_ir` + +Since these crates are not published on `crates.io` as part of the compiler's normal distribution +process, rust-analyzer maintains its own publishing pipeline. +It uses the [rustc-auto-publish script][rustc-auto-publish] to publish these crates to `crates.io` +with the prefix `ra-ap-rustc_*` +(for example: https://crates.io/crates/ra-ap-rustc_next_trait_solver). +rust-analyzer then depends on these re-published crates in its own build. + +For trait solving specifically, the primary shared crates are `rustc_type_ir` and +`rustc_next_trait_solver`, which provide the core IR and solver logic used by both compiler +frontends. + +## The Abstraction Layer + +Because rust-analyzer is a language server, it must handle frequently changing source code and +partially invalid or incomplete source codes. +This requires an infrastructure quite different from rustc's, especially in the layers between +the source code and the HIR—for example, `Ty` and its backing interner. + +To bridge these differences, the compiler provides `rustc_type_ir` as an abstraction layer shared +between rustc and rust-analyzer. +This crate defines the fundamental interfaces used to represent types, predicates, and the context +required by the trait solver. +Both rustc and rust-analyzer implement these traits for their own concrete type representations, +and `rustc_next_trait_solver` is written to be generic over these abstractions. + +In addition to these interfaces, `rustc_type_ir` also includes several non-trivial components built +on top of the abstraction layer—such as elaboration logic and the search graph machinery used by the +solver. + +## Design Concepts + +`rustc_next_trait_solver` is intended to depend only on the abstract interfaces defined in +`rustc_type_ir`. +To support this, the type-system traits in `rustc_type_ir` must expose every interface the solver +requires—for example, [creating a new inference type variable][ir new_infer] +([rustc][rustc new_infer], [rust-analyzer][r-a new_infer]). +For items that do not need compiler-specific representations, `rustc_type_ir` defines them directly +as structs or enums parameterized over these traits—for example, [`TraitRef`][ir tr]. + +The following are some notable items from the `rustc_type_ir` crate. + +### `trait Interner` + +The central trait in this design is [`Interner`][ir interner], which specifies all +implementation-specific details for both rustc and rust-analyzer. +Among its essential responsibilities: + +- it **specifies** the concrete types used by the implementation via its + [associated types][ir interner assocs]; these form the backbone of how each compiler frontend + instantiates the shared IR, +- it provides the context required by the solver (e.g., querying [lang items][ir require_lang_item], + enumerating [all blanket impls for a trait][ir for_each_blanket_impl]); +- and it must implement [`IrPrint`][ir irprint] for formatting and tracing. + In practice, these `IrPrint` impls simply route to existing formatting logic inside rustc or + rust-analyzer. + +In rustc, [`TyCtxt` implements `Interner`][rustc interner impl]: it exposes the rustc's query +methods, and the required `Interner` trait methods are implemented by invoking those queries. +In rust-analyzer, the implementing type is named [`DbInterner`][r-a interner impl] (as it performs +most interning through the [salsa] database), and most of its methods are backed by salsa queries +rather than rustc queries. + +### `mod inherent` + +Another notable item in `rustc_type_ir` is the [`inherent` module][ir inherent]. +This module provides *forward definitions* of inherent methods—expressed as traits—corresponding to +methods that exist on compiler-specific types such as `Ty` or `GenericArg`. +These definitions allow the generic crates (such as `rustc_next_trait_solver`) to call methods that +are implemented differently in rustc and rust-analyzer. + +Code in generic crates should import these definitions with: + +```rust +use inherent::*; +``` + +These forward definitions **must never be used inside the concrete implementations themselves**. +Crates that implement the traits from `mod inherent` should call the actual inherent methods on +their concrete types once those types are nameable. + +You can find rustc’s implementations of these traits in the +[rustc_middle::ty::inherent][rustc inherent impl] module. +For rust-analyzer, the corresponding implementations are located across several modules under +`hir_ty::next_solver`, such as [hir_ty::next_solver::region][r-a inherent impl]. + +### `trait InferCtxtLike` and `trait SolverDelegate` + +These two traits correspond to the role of [`InferCtxt`][rustc inferctxt] in rustc. + +[`InferCtxtLike`][ir inferctxtlike] must be defined in `rustc_infer` due to coherence +constraints(orphan rules). +As a result, it cannot provide functionality that lives in `rustc_trait_selection`. +Instead, behavior that depends on trait-solving logic is abstracted into a separate trait, +[`SolverDelegate`][ir solverdelegate]. +Its implementator in rustc is [simply a newtype struct over `InferCtxt`][rustc solverdelegate impl] +in `rustc_trait_selection`. + +(In rust-analyzer, it is also implemented for a newtype wrapper over its own +[`InferCtxt`][r-a inferctxtlike impl], primarily to mirror rustc’s structure, although this is not +strictly necessary because all solver-related logic already resides in the `hir-ty` crate.) + +In the long term, the ideal design is to move all of the logic currently expressed through +`SolverDelegate` into `rustc_next_trait_solver`, with any required core operations added directly to +`InferCtxtLike`. +This would allow more of the solver’s behavior to live entirely inside the shared solver crate. + +### `rustc_type_ir::search_graph::{Cx, Delegate}` + +The abstraction traits [`Cx`][ir searchgraph cx impl] and [`Delegate`][ir searchgraph delegate impl] +are already implemented within `rustc_next_trait_solver` itself. +Therefore, users of the shared crates—both rustc and rust-analyzer—do not need to provide their own +implementations. + +These traits exist primarily to support fuzzing of the search graph independently of the full trait +solver. +This infrastructure is used by the external fuzzing project: +. + +## Long-term plans for supporting rust-analyzer + +In general, we aim to support rust-analyzer just as well as rustc in these shared crates—provided +doing so does not substantially harm rustc's performance or maintainability. +(e.g., [#145377][pr 145377], [#146111][pr 146111], [#146182][pr 146182] and [#147723][pr 147723]) + +Shared crates that require nightly-only features must guard such code behind a `nightly` feature +flag, since rust-analyzer is built with the stable toolchain. + +Looking forward, we plan to uplift more shared logic into `rustc_type_ir`. +There are still duplicated implementations between rustc and rust-analyzer—such as `ObligationCtxt` +([rustc][rustc oblctxt], [rust-analyzer][r-a oblctxt]) and type coercion logic +([rustc][rustc coerce], [rust-analyzer][r-a coerce])—that we would like to unify over time. + +[rustc-auto-publish]: https://github.com/rust-analyzer/rustc-auto-publish +[ir new_infer]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/inherent/trait.Ty.html#tymethod.new_infer +[rustc new_infer]: https://github.com/rust-lang/rust/blob/63b1db05801271e400954e41b8600a3cf1482363/compiler/rustc_middle/src/ty/sty.rs#L413-L420 +[r-a new_infer]: https://github.com/rust-lang/rust-analyzer/blob/34f47d9298c478c12c6c4c0348771d1b05706e09/crates/hir-ty/src/next_solver/ty.rs#L59-L92 +[ir tr]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/struct.TraitRef.html +[ir interner]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.Interner.html +[ir interner assocs]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.Interner.html#required-associated-types +[ir require_lang_item]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.Interner.html#tymethod.require_lang_item +[ir for_each_blanket_impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.Interner.html#tymethod.for_each_blanket_impl +[ir irprint]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/ir_print/trait.IrPrint.html +[rustc interner impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#impl-Interner-for-TyCtxt%3C'tcx%3E +[r-a interner impl]: https://github.com/rust-lang/rust-analyzer/blob/a50c1ccc9cf3dab1afdc857a965a9992fbad7a53/crates/hir-ty/src/next_solver/interner.rs +[salsa]: https://github.com/salsa-rs/salsa +[ir inherent]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/inherent/index.html +[rustc inherent impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_middle/ty/inherent/index.html +[r-a inherent impl]: https://github.com/rust-lang/rust-analyzer/blob/a50c1ccc9cf3dab1afdc857a965a9992fbad7a53/crates/hir-ty/src/next_solver/region.rs +[ir inferctxtlike]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.InferCtxtLike.html +[rustc inferctxt]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html +[rustc inferctxtlike impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/src/rustc_infer/infer/context.rs.html#14-332 +[r-a inferctxtlike impl]: https://github.com/rust-lang/rust-analyzer/blob/a50c1ccc9cf3dab1afdc857a965a9992fbad7a53/crates/hir-ty/src/next_solver/infer/context.rs +[ir solverdelegate]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_next_trait_solver/delegate/trait.SolverDelegate.html +[rustc solverdelegate impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_trait_selection/solve/delegate/struct.SolverDelegate.html +[r-a solverdelegate impl]: https://github.com/rust-lang/rust-analyzer/blob/a50c1ccc9cf3dab1afdc857a965a9992fbad7a53/crates/hir-ty/src/next_solver/solver.rs#L27-L330 +[ir searchgraph cx impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/src/rustc_type_ir/interner.rs.html#550-575 +[ir searchgraph delegate impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/src/rustc_next_trait_solver/solve/search_graph.rs.html#20-123 +[pr 145377]: https://github.com/rust-lang/rust/pull/145377 +[pr 146111]: https://github.com/rust-lang/rust/pull/146111 +[pr 146182]: https://github.com/rust-lang/rust/pull/146182 +[pr 147723]: https://github.com/rust-lang/rust/pull/147723 +[rustc oblctxt]: https://github.com/rust-lang/rust/blob/63b1db05801271e400954e41b8600a3cf1482363/compiler/rustc_trait_selection/src/traits/engine.rs#L48-L386 +[r-a oblctxt]: https://github.com/rust-lang/rust-analyzer/blob/34f47d9298c478c12c6c4c0348771d1b05706e09/crates/hir-ty/src/next_solver/obligation_ctxt.rs +[rustc coerce]: https://github.com/rust-lang/rust/blob/63b1db05801271e400954e41b8600a3cf1482363/compiler/rustc_hir_typeck/src/coercion.rs +[r-a coerce]: https://github.com/rust-lang/rust-analyzer/blob/34f47d9298c478c12c6c4c0348771d1b05706e09/crates/hir-ty/src/infer/coerce.rs \ No newline at end of file From 6693a568aff4d4f41007898d070c157f08a6d2db Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:20:48 +0000 Subject: [PATCH 0433/3801] Merge commit 'e24f0fa3c54951d1a5843b54ebe052faaa3a3cd2' into sync_cg_clif-2025-12-08 --- .cirrus.yml | 2 +- Cargo.lock | 159 ++++++++++-------- Cargo.toml | 26 +-- build_system/abi_cafe.rs | 2 +- build_system/bench.rs | 39 +++-- build_system/build_backend.rs | 7 +- build_system/build_sysroot.rs | 43 ++--- build_system/main.rs | 7 +- build_system/tests.rs | 8 +- build_system/utils.rs | 4 +- ...-simd-Disable-broken-reduce_sum-test.patch | 26 --- rust-toolchain | 2 +- scripts/rustup.sh | 4 +- src/common.rs | 20 ++- src/debuginfo/line_info.rs | 9 +- src/debuginfo/mod.rs | 59 ++++--- src/debuginfo/types.rs | 3 +- src/lib.rs | 12 +- 18 files changed, 224 insertions(+), 208 deletions(-) delete mode 100644 patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch diff --git a/.cirrus.yml b/.cirrus.yml index 3ed89beceb7f..9be095dbf2d8 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,7 +1,7 @@ task: name: freebsd freebsd_instance: - image_family: freebsd-14-2 + image_family: freebsd-15-0-amd64-ufs setup_rust_script: - pkg install -y git-tiny binutils - curl https://sh.rustup.rs -sSf --output rustup.sh diff --git a/Cargo.lock b/Cargo.lock index 09b6c6b87c30..617c7f0e34cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,15 +10,15 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "bitflags" @@ -37,48 +37,48 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cranelift-assembler-x64" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f502c60b6af2025c312b37788c089943ef03156a2910da1aa046bb39eb8f61c7" +checksum = "bf7631e609c97f063f9777aae405e8492abf9bf92336d7aa3f875403dd4ffd7d" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b7e21a74bcf08443a4ef800a4a257063e5c51ee4d7a3bd58da5262d10340830" +checksum = "9c030edccdc4a5bbf28fbfe7701b5cd1f9854b4445184dd34af2a7e8f8db6f45" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f337d268865c292ad5df0669a9bbf6223ca41460292a20ad5b0a57b8e9f27f93" +checksum = "bb544c1242d0ca98baf01873ebba96c79d5df155d5108d9bb699aefc741f5e6d" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0e60319a8242c8d1c7b5a2444d140c416f903f75e0d84da3256fceb822bab85" +checksum = "f0325aecbafec053d3d3f082edfdca7937e2945e7f09c5ff9672e05198312282" [[package]] name = "cranelift-codegen" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78dee669e447a1c68760bf7acee33835e99d564f0137b067f74d4718dfc9970d" +checksum = "abb3236fd319ae897ba00c8a25105081de5c1348576def0e96c062ad259f87a7" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601f629d172b7230f41dd0e78ee797efaf7ec1a5e113c8f395f4027dff6a92ca" +checksum = "7b8791c911a361c539130ace34fb726b16aca4216470ec75d75264b1495c8a3a" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -114,33 +114,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15755c2660902c7d59d96f6551a66ef629650dc3fd405f9dad841e8c58c1a4a2" +checksum = "12ead718c2a10990870c19b2497b5a04b8aae6024485e33da25b5d02e35819e0" [[package]] name = "cranelift-control" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727bfca18705101a294ab9077ad214a8b762ea2bc9844389d0db233d7c61ec3b" +checksum = "c0a57fc972b5651047efddccb99440d103d9d8c13393ccebde15ddd5b6a1181b" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15564c6f0c72750ca4374f40b044857cbc8087571e46d4c7ccdbdcc29b1dec8b" +checksum = "5aae980b4a1678b601eab2f52e372ed0b3c9565a31c17f380008cb97b3a699c5" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c681f2731f1cf68eed9f3b6811571823a5ac498f59c52b73736b68599defb3" +checksum = "a78877016b607982ca1708c0dd4ce23bde04581a39854c9b43a1dca43625b54c" dependencies = [ "cranelift-codegen", "log", @@ -150,15 +150,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40cedc02f08307da019a3e06d3f20f772f829ff813aec975accb012f8930b688" +checksum = "5dc46a68b46d4f53f9f2f02ab8d3a34b00f03a21c124a7a965b8cbf5fdb6773b" [[package]] name = "cranelift-jit" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2864461448c72d15ae3311ea63df9c7e35f22f04683785f6715a0cf17e6577d" +checksum = "7df920009af919ad9df52eb7b47b1895145822e0c29da9b715a876fc8ecc6d82" dependencies = [ "anyhow", "cranelift-codegen", @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b31d249bbbccc4c1ae54701087d4d49d05951897691eef44f4a60e70252743b" +checksum = "ddcf313629071ce74de8e59f02092f5453d1a01047607fc4ad36886b8bd1486c" dependencies = [ "anyhow", "cranelift-codegen", @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db03ab51c60710eb83d0217725b77db4062aca83b35359f5e6aa99ed1c275977" +checksum = "03faa07ec8cf373250a8252eb773d098ff88259fa1c19ee1ecde8012839f4097" dependencies = [ "cranelift-codegen", "libc", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7131e0eb45ee10b0bd6082d0c0114c2e9a670b034d46774b39d0fc5c0ed7cedf" +checksum = "7cca62c14f3c2e4f438192562bbf82d1a98a59543cc66ba04fb658ba99f515a6" dependencies = [ "anyhow", "cranelift-codegen", @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.125.1" +version = "0.126.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7a06c330b7994a891ad5b622ebc9aefcd17beae832dd25f577cf60c13426bf" +checksum = "0484cb32c527a742e1bba09ef174acac0afb1dcf623ef1adda42849200edcd2e" [[package]] name = "crc32fast" @@ -246,9 +246,9 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "gimli" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" dependencies = [ "fallible-iterator", "indexmap", @@ -282,18 +282,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" -version = "0.8.8" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-link 0.2.1", ] [[package]] @@ -304,9 +304,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "log" -version = "0.4.27" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "mach2" @@ -319,9 +319,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "object" @@ -337,27 +337,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] [[package]] name = "regalloc2" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd8138ce7c3d7c13be4f61893154b5d711bd798d2d7be3ecb8dcc7e7a06ca98" +checksum = "4e249c660440317032a71ddac302f25f1d5dff387667bcc3978d1f77aa31ac34" dependencies = [ "allocator-api2", "bumpalo", @@ -405,18 +405,27 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +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.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -431,15 +440,15 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "syn" -version = "2.0.104" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -448,21 +457,21 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "38.0.1" +version = "39.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d0a76f1a6e887cc1b551b02dfd6e2ce5f6738e8cacd9ad7284f6ac1aac4698f" +checksum = "3f67986f5c499274ae5b2ba5b173bba0b95d1381f5ca70d8eec657f2392117d8" dependencies = [ "anyhow", "cfg-if", @@ -472,9 +481,9 @@ dependencies = [ [[package]] name = "wasmtime-internal-math" -version = "38.0.1" +version = "39.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b900df4252ad86547e7f2b2c00201b006db4e864893bedfb3aca32b23d81868a" +checksum = "a681733e9b5d5d8804ee6cacd59f92c0d87ba2274f42ee1d4e5a943828d0075d" dependencies = [ "libm", ] @@ -485,6 +494,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-sys" version = "0.52.0" @@ -525,7 +540,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", diff --git a/Cargo.toml b/Cargo.toml index f2001123e579..58e61cd0b9d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,28 +8,28 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.125.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.125.0" } -cranelift-module = { version = "0.125.0" } -cranelift-native = { version = "0.125.0" } -cranelift-jit = { version = "0.125.0", optional = true } -cranelift-object = { version = "0.125.0" } +cranelift-codegen = { version = "0.126.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.126.0" } +cranelift-module = { version = "0.126.0" } +cranelift-native = { version = "0.126.0" } +cranelift-jit = { version = "0.126.0", optional = true } +cranelift-object = { version = "0.126.0" } target-lexicon = "0.13" gimli = { version = "0.32", default-features = false, features = ["write"] } object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" -libloading = { version = "0.8.0", optional = true } +libloading = { version = "0.9.0", optional = true } smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } diff --git a/build_system/abi_cafe.rs b/build_system/abi_cafe.rs index 5a393a217c27..762b2be8f440 100644 --- a/build_system/abi_cafe.rs +++ b/build_system/abi_cafe.rs @@ -11,7 +11,7 @@ static ABI_CAFE_REPO: GitRepo = GitRepo::github( "abi-cafe", ); -static ABI_CAFE: CargoProject = CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe_target"); +static ABI_CAFE: CargoProject = CargoProject::new(ABI_CAFE_REPO.source_dir(), "abi_cafe_target"); pub(crate) fn run( sysroot_kind: SysrootKind, diff --git a/build_system/bench.rs b/build_system/bench.rs index 192cb499536f..91353ba8a874 100644 --- a/build_system/bench.rs +++ b/build_system/bench.rs @@ -39,7 +39,26 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { let rustc_clif = &compiler.rustc; let rustflags = &compiler.rustflags.join("\x1f"); let manifest_path = SIMPLE_RAYTRACER_REPO.source_dir().to_path(dirs).join("Cargo.toml"); - let target_dir = dirs.build_dir.join("simple_raytracer"); + let target_dir = dirs.build_dir.join("simple-raytracer_target"); + + let raytracer_cg_llvm = dirs + .build_dir + .join(get_file_name(&compiler.rustc, "raytracer_cg_llvm", "bin")) + .to_str() + .unwrap() + .to_owned(); + let raytracer_cg_clif = dirs + .build_dir + .join(get_file_name(&compiler.rustc, "raytracer_cg_clif", "bin")) + .to_str() + .unwrap() + .to_owned(); + let raytracer_cg_clif_opt = dirs + .build_dir + .join(get_file_name(&compiler.rustc, "raytracer_cg_clif_opt", "bin")) + .to_str() + .unwrap() + .to_owned(); let clean_cmd = format!( "RUSTC=rustc cargo clean --manifest-path {manifest_path} --target-dir {target_dir}", @@ -47,19 +66,19 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { target_dir = target_dir.display(), ); let llvm_build_cmd = format!( - "RUSTC=rustc cargo build --manifest-path {manifest_path} --target-dir {target_dir} && (rm build/raytracer_cg_llvm || true) && ln build/simple_raytracer/debug/main build/raytracer_cg_llvm", + "RUSTC=rustc cargo build --manifest-path {manifest_path} --target-dir {target_dir} && (rm {raytracer_cg_llvm} || true) && ln {target_dir}/debug/main {raytracer_cg_llvm}", manifest_path = manifest_path.display(), target_dir = target_dir.display(), ); let clif_build_cmd = format!( - "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} && (rm build/raytracer_cg_clif || true) && ln build/simple_raytracer/debug/main build/raytracer_cg_clif", + "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} && (rm {raytracer_cg_clif} || true) && ln {target_dir}/debug/main {raytracer_cg_clif}", cargo_clif = cargo_clif.display(), rustc_clif = rustc_clif.display(), manifest_path = manifest_path.display(), target_dir = target_dir.display(), ); let clif_build_opt_cmd = format!( - "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} --release && (rm build/raytracer_cg_clif_opt || true) && ln build/simple_raytracer/release/main build/raytracer_cg_clif_opt", + "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" CARGO_BUILD_INCREMENTAL=true {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} --release && (rm {raytracer_cg_clif_opt} || true) && ln {target_dir}/release/main {raytracer_cg_clif_opt}", cargo_clif = cargo_clif.display(), rustc_clif = rustc_clif.display(), manifest_path = manifest_path.display(), @@ -92,20 +111,14 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { let bench_run_markdown = dirs.build_dir.join("bench_run.md"); - let raytracer_cg_llvm = - Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_llvm", "bin")); - let raytracer_cg_clif = - Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_clif", "bin")); - let raytracer_cg_clif_opt = - Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_clif_opt", "bin")); let mut bench_run = hyperfine_command( 0, bench_runs, None, &[ - ("", raytracer_cg_llvm.to_str().unwrap()), - ("", raytracer_cg_clif.to_str().unwrap()), - ("", raytracer_cg_clif_opt.to_str().unwrap()), + ("build/raytracer_cg_llvm", &raytracer_cg_llvm), + ("build/raytracer_cg_clif", &raytracer_cg_clif), + ("build/raytracer_cg_clif_opt", &raytracer_cg_clif_opt), ], &bench_run_markdown, ); diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs index b9fa0ff2d94c..c0a8cc95614f 100644 --- a/build_system/build_backend.rs +++ b/build_system/build_backend.rs @@ -6,7 +6,7 @@ use crate::rustc_info::get_file_name; use crate::shared_utils::{rustflags_from_env, rustflags_to_cmd_env}; use crate::utils::{CargoProject, Compiler, LogGroup}; -static CG_CLIF: CargoProject = CargoProject::new(&RelPath::source("."), "cg_clif"); +static CG_CLIF: CargoProject = CargoProject::new(RelPath::source("."), "cg_clif"); pub(crate) fn build_backend( dirs: &Dirs, @@ -22,6 +22,11 @@ pub(crate) fn build_backend( rustflags.push("-Zallow-features=rustc_private,f16,f128".to_owned()); rustflags_to_cmd_env(&mut cmd, "RUSTFLAGS", &rustflags); + // Use incr comp despite release mode unless incremental builds are explicitly disabled + if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() { + cmd.env("CARGO_BUILD_INCREMENTAL", "true"); + } + if env::var("CG_CLIF_EXPENSIVE_CHECKS").is_ok() { // Enabling debug assertions implicitly enables the clif ir verifier cmd.env("CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS", "true"); diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 70504ee8007d..e7363e37a45d 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -140,7 +140,7 @@ impl SysrootTarget { static STDLIB_SRC: RelPath = RelPath::build("stdlib"); static STANDARD_LIBRARY: CargoProject = - CargoProject::new(&RelPath::build("stdlib/library/sysroot"), "stdlib_target"); + CargoProject::new(RelPath::build("stdlib/library/sysroot"), "stdlib_target"); fn build_sysroot_for_triple( dirs: &Dirs, @@ -161,35 +161,18 @@ fn build_sysroot_for_triple( fn build_llvm_sysroot_for_triple(compiler: Compiler) -> SysrootTarget { let default_sysroot = crate::rustc_info::get_default_sysroot(&compiler.rustc); - let mut target_libs = SysrootTarget { triple: compiler.triple, libs: vec![] }; + let std_manifest_path = default_sysroot + .join("lib") + .join("rustlib") + .join(format!("manifest-rust-std-{}", compiler.triple)); - for entry in fs::read_dir( - default_sysroot.join("lib").join("rustlib").join(&target_libs.triple).join("lib"), - ) - .unwrap() - { - let entry = entry.unwrap(); - if entry.file_type().unwrap().is_dir() { - continue; - } - let file = entry.path(); - let file_name_str = file.file_name().unwrap().to_str().unwrap(); - if (file_name_str.contains("rustc_") - && !file_name_str.contains("rustc_std_workspace_") - && !file_name_str.contains("rustc_demangle") - && !file_name_str.contains("rustc_literal_escaper")) - || file_name_str.contains("chalk") - || file_name_str.contains("tracing") - || file_name_str.contains("regex") - { - // These are large crates that are part of the rustc-dev component and are not - // necessary to run regular programs. - continue; - } - target_libs.libs.push(file); - } + let libs = fs::read_to_string(std_manifest_path) + .unwrap() + .lines() + .map(|entry| default_sysroot.join(entry.strip_prefix("file:").unwrap())) + .collect(); - target_libs + SysrootTarget { triple: compiler.triple, libs } } fn build_clif_sysroot_for_triple( @@ -251,6 +234,10 @@ fn build_clif_sysroot_for_triple( if compiler.triple.contains("apple") { build_cmd.env("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO", "packed"); } + // Use incr comp despite release mode unless incremental builds are explicitly disabled + if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() { + build_cmd.env("CARGO_BUILD_INCREMENTAL", "true"); + } spawn_and_wait(build_cmd); for entry in fs::read_dir(build_dir.join("deps")).unwrap() { diff --git a/build_system/main.rs b/build_system/main.rs index fc0093128300..6251687babc6 100644 --- a/build_system/main.rs +++ b/build_system/main.rs @@ -59,11 +59,6 @@ fn main() { } env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1"); - // Force incr comp even in release mode unless in CI or incremental builds are explicitly disabled - if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() { - env::set_var("CARGO_BUILD_INCREMENTAL", "true"); - } - let mut args = env::args().skip(1); let command = match args.next().as_deref() { Some("prepare") => Command::Prepare, @@ -79,7 +74,7 @@ fn main() { } }; - let mut out_dir = PathBuf::from("."); + let mut out_dir = std::env::current_dir().unwrap(); let mut download_dir = None; let mut sysroot_kind = SysrootKind::Clif; let mut use_unstable_features = true; diff --git a/build_system/tests.rs b/build_system/tests.rs index dd8cf929bc2f..3b6a2e7a055c 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -129,7 +129,7 @@ pub(crate) static RAND_REPO: GitRepo = GitRepo::github( "rand", ); -static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand_target"); +static RAND: CargoProject = CargoProject::new(RAND_REPO.source_dir(), "rand_target"); pub(crate) static REGEX_REPO: GitRepo = GitRepo::github( "rust-lang", @@ -139,15 +139,15 @@ pub(crate) static REGEX_REPO: GitRepo = GitRepo::github( "regex", ); -static REGEX: CargoProject = CargoProject::new(®EX_REPO.source_dir(), "regex_target"); +static REGEX: CargoProject = CargoProject::new(REGEX_REPO.source_dir(), "regex_target"); static PORTABLE_SIMD_SRC: RelPath = RelPath::build("portable-simd"); -static PORTABLE_SIMD: CargoProject = CargoProject::new(&PORTABLE_SIMD_SRC, "portable-simd_target"); +static PORTABLE_SIMD: CargoProject = CargoProject::new(PORTABLE_SIMD_SRC, "portable-simd_target"); static SYSROOT_TESTS_SRC: RelPath = RelPath::build("sysroot_tests"); -static SYSROOT_TESTS: CargoProject = CargoProject::new(&SYSROOT_TESTS_SRC, "sysroot_tests_target"); +static SYSROOT_TESTS: CargoProject = CargoProject::new(SYSROOT_TESTS_SRC, "sysroot_tests_target"); const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ TestCase::custom("test.rust-random/rand", &|runner| { diff --git a/build_system/utils.rs b/build_system/utils.rs index 3266aa0ce8b6..5c7cefa120a7 100644 --- a/build_system/utils.rs +++ b/build_system/utils.rs @@ -75,12 +75,12 @@ impl Compiler { } pub(crate) struct CargoProject { - source: &'static RelPath, + source: RelPath, target: &'static str, } impl CargoProject { - pub(crate) const fn new(path: &'static RelPath, target: &'static str) -> CargoProject { + pub(crate) const fn new(path: RelPath, target: &'static str) -> CargoProject { CargoProject { source: path, target } } diff --git a/patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch b/patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch deleted file mode 100644 index b1fd6224632b..000000000000 --- a/patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5489384bc265e9e6fc2efaa63d93a4d51ebec2f5 Mon Sep 17 00:00:00 2001 -From: bjorn3 <17426603+bjorn3@users.noreply.github.com> -Date: Thu, 22 Aug 2024 19:22:58 +0000 -Subject: [PATCH] Disable broken reduce_sum test - -It was broken by an upstream change to the .sum() implementation on -float iterators. ---- - crates/core_simd/tests/ops_macros.rs | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs -index aa565a1..5e6ac41 100644 ---- a/crates/core_simd/tests/ops_macros.rs -+++ b/crates/core_simd/tests/ops_macros.rs -@@ -646,6 +646,7 @@ macro_rules! impl_float_tests { - } - - fn reduce_sum() { -+ return; - test_helpers::test_1(&|x| { - test_helpers::prop_assert_biteq! ( - Vector::::from_array(x).reduce_sum(), --- -2.34.1 - diff --git a/rust-toolchain b/rust-toolchain index 17c2cc5ac660..461dbcdb0fb5 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-11-08" +channel = "nightly-2025-12-08" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" diff --git a/scripts/rustup.sh b/scripts/rustup.sh index fdfd03029b16..1a82193303e2 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -43,7 +43,7 @@ case $1 in cg_clif=$(pwd) pushd ../rust - git pull origin master + git pull origin main branch=sync_cg_clif-$(date +%Y-%m-%d) git checkout -b "$branch" "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git main @@ -63,7 +63,7 @@ case $1 in cg_clif=$(pwd) pushd ../rust - git fetch origin master + git fetch origin main git -c advice.detachedHead=false checkout "$RUST_VERS" "$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust popd diff --git a/src/common.rs b/src/common.rs index 38676eaac3d5..b11f42408f58 100644 --- a/src/common.rs +++ b/src/common.rs @@ -377,26 +377,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { size.is_multiple_of(align), "size must be a multiple of alignment (size={size}, align={align})" ); + debug_assert!(align.is_power_of_two(), "alignment must be a power of two (align={align})"); let abi_align = if self.tcx.sess.target.arch == Arch::S390x { 8 } else { 16 }; + // Cranelift can only guarantee alignment up to the ABI alignment provided by the target. + // If the requested alignment is less than the abi_align it can be used directly. if align <= abi_align { let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, - // FIXME Don't force the size to a multiple of bytes once Cranelift gets - // a way to specify stack slot alignment. - size: size.div_ceil(abi_align) * abi_align, - align_shift: 4, + size, + // The maximum value of ilog2 is 31 which will always fit in a u8. + align_shift: align.ilog2().try_into().unwrap(), + key: None, }); Pointer::stack_slot(stack_slot) } else { - // Alignment is too big to handle using the above hack. Dynamically realign a stack slot + // Alignment is larger than the ABI alignment guaranteed. Dynamically realign a stack slot // instead. This wastes some space for the realignment. let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, - // FIXME Don't force the size to a multiple of bytes once Cranelift gets - // a way to specify stack slot alignment. - size: (size + align) / abi_align * abi_align, - align_shift: 4, + size: size + align, + align_shift: abi_align.ilog2().try_into().unwrap(), + key: None, }); let base_ptr = self.bcx.ins().stack_addr(self.pointer_type, stack_slot, 0); let misalign_offset = self.bcx.ins().band_imm(base_ptr, i64::from(align - 1)); diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index 6fe22f5c6dd9..db58ee890911 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -5,7 +5,7 @@ use std::path::{Component, Path}; use cranelift_codegen::MachSrcLoc; use cranelift_codegen::binemit::CodeOffset; -use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable}; +use gimli::write::{FileId, FileInfo, LineProgram, LineString, LineStringTable}; use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene}; use crate::debuginfo::FunctionDebugContext; @@ -117,8 +117,7 @@ impl DebugContext { } filename => { // For anonymous sources, create an empty directory instead of using the default - let empty_dir = LineString::new(b"", line_program.encoding(), line_strings); - let dir_id = line_program.add_directory(empty_dir); + let dir_id = line_program.default_directory(); let dummy_file_name = LineString::new( filename.prefer_remapped_unconditionally().to_string().into_bytes(), @@ -176,10 +175,6 @@ impl FunctionDebugContext { assert_ne!(func_end, 0); - let entry = debug_context.dwarf.unit.get_mut(self.entry_id); - entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); - entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end))); - func_end } } diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 494002f525c8..8c43db92fe05 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -42,14 +42,14 @@ pub(crate) struct DebugContext { created_files: FxHashMap<(StableSourceFileId, SourceFileHash), FileId>, stack_pointer_register: Register, namespace_map: DefIdMap, - array_size_type: UnitEntryId, + array_size_type: Option, filename_display_preference: FileNameDisplayPreference, embed_source: bool, } pub(crate) struct FunctionDebugContext { - entry_id: UnitEntryId, + entry_id: Option, function_source_loc: (FileId, u64, u64), source_loc_set: IndexSet<(FileId, u64, u64)>, } @@ -154,18 +154,23 @@ impl DebugContext { root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } - let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type); - let array_size_type_entry = dwarf.unit.get_mut(array_size_type); - array_size_type_entry.set( - gimli::DW_AT_name, - AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")), - ); - array_size_type_entry - .set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned)); - array_size_type_entry.set( - gimli::DW_AT_byte_size, - AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), - ); + let array_size_type = if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly { + None + } else { + let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type); + let array_size_type_entry = dwarf.unit.get_mut(array_size_type); + array_size_type_entry.set( + gimli::DW_AT_name, + AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")), + ); + array_size_type_entry + .set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned)); + array_size_type_entry.set( + gimli::DW_AT_byte_size, + AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), + ); + Some(array_size_type) + }; Some(DebugContext { endian, @@ -217,6 +222,14 @@ impl DebugContext { ) -> FunctionDebugContext { let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span); + if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly { + return FunctionDebugContext { + entry_id: None, + function_source_loc: (file_id, line, column), + source_loc_set: IndexSet::new(), + }; + } + let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); let mut name = String::new(); @@ -274,7 +287,7 @@ impl DebugContext { } FunctionDebugContext { - entry_id, + entry_id: Some(entry_id), function_source_loc: (file_id, line, column), source_loc_set: IndexSet::new(), } @@ -288,6 +301,10 @@ impl DebugContext { def_id: DefId, data_id: DataId, ) { + if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly { + return; + } + let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() }; if nested { return; @@ -353,10 +370,12 @@ impl FunctionDebugContext { .0 .push(Range::StartLength { begin: address_for_func(func_id), length: u64::from(end) }); - let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id); - // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. - func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); - // Using Udata for DW_AT_high_pc requires at least DWARF4 - func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); + if let Some(entry_id) = self.entry_id { + let entry = debug_context.dwarf.unit.get_mut(entry_id); + // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. + entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); + // Using Udata for DW_AT_high_pc requires at least DWARF4 + entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); + } } } diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs index a292429cdfad..18a0632a0939 100644 --- a/src/debuginfo/types.rs +++ b/src/debuginfo/types.rs @@ -109,7 +109,8 @@ impl DebugContext { let subrange_id = self.dwarf.unit.add(array_type_id, gimli::DW_TAG_subrange_type); let subrange_entry = self.dwarf.unit.get_mut(subrange_id); - subrange_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type)); + subrange_entry + .set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type.unwrap())); subrange_entry.set(gimli::DW_AT_lower_bound, AttributeValue::Udata(0)); subrange_entry.set(gimli::DW_AT_count, AttributeValue::Udata(len)); diff --git a/src/lib.rs b/src/lib.rs index 5fdecd014ac0..b47b9afa4f07 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,7 +47,7 @@ use rustc_codegen_ssa::{CodegenResults, TargetConfig}; use rustc_log::tracing::info; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; -use rustc_session::config::OutputFilenames; +use rustc_session::config::{OutputFilenames, PrintKind, PrintRequest}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{Abi, Arch, Env, Os}; @@ -160,6 +160,16 @@ impl CodegenBackend for CraneliftCodegenBackend { } } + fn print(&self, req: &PrintRequest, out: &mut String, _sess: &Session) { + match req.kind { + // FIXME have a default impl that returns false + PrintKind::BackendHasZstd => { + out.push_str("false\n"); + } + _ => {} + } + } + fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] let target_features = match sess.target.arch { From cb49fe585458f2d0b2d4a37a53c72a989ad9a284 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:26:26 +0000 Subject: [PATCH 0434/3801] Update list of allowed cg_clif dependencies --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index bac426495c2f..592ba9c5c794 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -589,6 +589,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ "region", "rustc-hash", "serde", + "serde_core", "serde_derive", "smallvec", "stable_deref_trait", From 8cf942d89fcaef9eea4a472cd2213856ba27ccc5 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 8 Dec 2025 19:56:47 +0300 Subject: [PATCH 0435/3801] Add inline attribute to generated delegation function if needed --- compiler/rustc_ast_lowering/src/delegation.rs | 28 +++++ tests/pretty/delegation_inline_attribute.pp | 94 ++++++++++++++++ tests/pretty/delegation_inline_attribute.rs | 104 ++++++++++++++++++ tests/pretty/hir-delegation.pp | 2 + 4 files changed, 228 insertions(+) create mode 100644 tests/pretty/delegation_inline_attribute.pp create mode 100644 tests/pretty/delegation_inline_attribute.rs diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index e6e88eff2d5b..0e7db7c9503c 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -44,6 +44,7 @@ use hir::{BodyId, HirId}; use rustc_abi::ExternAbi; use rustc_ast::*; use rustc_errors::ErrorGuaranteed; +use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; use rustc_middle::ty::{Asyncness, ResolverAstLowering}; @@ -87,6 +88,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl); match sig_id { Ok(sig_id) => { + self.add_inline_attribute_if_needed(span); + let is_method = self.is_method(sig_id, span); let (param_count, c_variadic) = self.param_count(sig_id); let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span); @@ -100,6 +103,31 @@ impl<'hir> LoweringContext<'_, 'hir> { } } + fn add_inline_attribute_if_needed(&mut self, span: Span) { + const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO; + let create_inline_attr_slice = + || [hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span))]; + + let new_attributes = match self.attrs.get(&PARENT_ID) { + Some(attrs) => { + // Check if reuse already specifies any inline attribute, if so, do nothing + if attrs + .iter() + .any(|a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..)))) + { + return; + } + + self.arena.alloc_from_iter( + attrs.into_iter().map(|a| a.clone()).chain(create_inline_attr_slice()), + ) + } + None => self.arena.alloc_from_iter(create_inline_attr_slice()), + }; + + self.attrs.insert(PARENT_ID, new_attributes); + } + fn get_delegation_sig_id( &self, item_id: NodeId, diff --git a/tests/pretty/delegation_inline_attribute.pp b/tests/pretty/delegation_inline_attribute.pp new file mode 100644 index 000000000000..4b3b2aa8f80a --- /dev/null +++ b/tests/pretty/delegation_inline_attribute.pp @@ -0,0 +1,94 @@ +//@ pretty-compare-only +//@ pretty-mode:hir +//@ pp-exact:delegation_inline_attribute.pp + +#![allow(incomplete_features)] +#![feature(fn_delegation)] +#[attr = MacroUse {arguments: UseAll}] +extern crate std; +#[prelude_import] +use ::std::prelude::rust_2015::*; + +mod to_reuse { + fn foo(x: usize) -> usize { x } +} + +// Check that #[inline(hint)] is added to foo reuse +#[attr = Inline(Hint)] +fn bar(arg0: _) -> _ { to_reuse::foo(self + 1) } + +trait Trait { + fn foo(&self) { } + fn foo1(&self) { } + fn foo2(&self) { } + fn foo3(&self) { } + fn foo4(&self) { } +} + +impl Trait for u8 { } + +struct S(u8); + +mod to_import { + fn check(arg: &'_ u8) -> &'_ u8 { arg } +} + +impl Trait for S { + // Check that #[inline(hint)] is added to foo reuse + #[attr = Inline(Hint)] + fn foo(self: _) + -> + _ { + { + // Check that #[inline(hint)] is added to foo0 reuse inside another reuse + #[attr = Inline(Hint)] + fn foo0(arg0: _) -> _ { to_reuse::foo(self + 1) } + + // Check that #[inline(hint)] is added when other attributes present in inner reuse + #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] + #[attr = MustUse] + #[attr = Cold] + #[attr = Inline(Hint)] + fn foo1(arg0: _) -> _ { to_reuse::foo(self / 2) } + + // Check that #[inline(never)] is preserved in inner reuse + #[attr = Inline(Never)] + fn foo2(arg0: _) -> _ { to_reuse::foo(self / 2) } + + // Check that #[inline(always)] is preserved in inner reuse + #[attr = Inline(Always)] + fn foo3(arg0: _) -> _ { to_reuse::foo(self / 2) } + + // Check that #[inline(never)] is preserved when there are other attributes in inner reuse + #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] + #[attr = Inline(Never)] + #[attr = MustUse] + #[attr = Cold] + fn foo4(arg0: _) -> _ { to_reuse::foo(self / 2) } + }.foo() + } + + // Check that #[inline(hint)] is added when there are other attributes present in trait reuse + #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] + #[attr = MustUse] + #[attr = Cold] + #[attr = Inline(Hint)] + fn foo1(self: _) -> _ { self.0.foo1() } + + // Check that #[inline(never)] is preserved in trait reuse + #[attr = Inline(Never)] + fn foo2(self: _) -> _ { self.0.foo2() } + + // Check that #[inline(always)] is preserved in trait reuse + #[attr = Inline(Always)] + fn foo3(self: _) -> _ { self.0.foo3() } + + // Check that #[inline(never)] is preserved when there are other attributes in trait reuse + #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] + #[attr = Inline(Never)] + #[attr = MustUse] + #[attr = Cold] + fn foo4(self: _) -> _ { self.0.foo4() } +} + +fn main() { } diff --git a/tests/pretty/delegation_inline_attribute.rs b/tests/pretty/delegation_inline_attribute.rs new file mode 100644 index 000000000000..0716cfc51f5d --- /dev/null +++ b/tests/pretty/delegation_inline_attribute.rs @@ -0,0 +1,104 @@ +//@ pretty-compare-only +//@ pretty-mode:hir +//@ pp-exact:delegation_inline_attribute.pp + +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +mod to_reuse { + pub fn foo(x: usize) -> usize { + x + } +} + +// Check that #[inline(hint)] is added to foo reuse +reuse to_reuse::foo as bar { + self + 1 +} + +trait Trait { + fn foo(&self) {} + fn foo1(&self) {} + fn foo2(&self) {} + fn foo3(&self) {} + fn foo4(&self) {} +} + +impl Trait for u8 {} + +struct S(u8); + +mod to_import { + pub fn check(arg: &u8) -> &u8 { arg } +} + +impl Trait for S { + // Check that #[inline(hint)] is added to foo reuse + reuse Trait::foo { + // Check that #[inline(hint)] is added to foo0 reuse inside another reuse + reuse to_reuse::foo as foo0 { + self + 1 + } + + // Check that #[inline(hint)] is added when other attributes present in inner reuse + #[cold] + #[must_use] + #[deprecated] + reuse to_reuse::foo as foo1 { + self / 2 + } + + // Check that #[inline(never)] is preserved in inner reuse + #[inline(never)] + reuse to_reuse::foo as foo2 { + self / 2 + } + + // Check that #[inline(always)] is preserved in inner reuse + #[inline(always)] + reuse to_reuse::foo as foo3 { + self / 2 + } + + // Check that #[inline(never)] is preserved when there are other attributes in inner reuse + #[cold] + #[must_use] + #[inline(never)] + #[deprecated] + reuse to_reuse::foo as foo4 { + self / 2 + } + } + + // Check that #[inline(hint)] is added when there are other attributes present in trait reuse + #[cold] + #[must_use] + #[deprecated] + reuse Trait::foo1 { + self.0 + } + + // Check that #[inline(never)] is preserved in trait reuse + #[inline(never)] + reuse Trait::foo2 { + self.0 + } + + // Check that #[inline(always)] is preserved in trait reuse + #[inline(always)] + reuse Trait::foo3 { + self.0 + } + + // Check that #[inline(never)] is preserved when there are other attributes in trait reuse + #[cold] + #[must_use] + #[inline(never)] + #[deprecated] + reuse Trait::foo4 { + self.0 + } +} + +fn main() { +} diff --git a/tests/pretty/hir-delegation.pp b/tests/pretty/hir-delegation.pp index f8ad02f2fccc..b5f7a14eb2fc 100644 --- a/tests/pretty/hir-delegation.pp +++ b/tests/pretty/hir-delegation.pp @@ -12,6 +12,7 @@ use ::std::prelude::rust_2015::*; fn b(e: C) { } trait G { + #[attr = Inline(Hint)] fn b(arg0: _) -> _ { b({ }) } } @@ -19,6 +20,7 @@ mod m { fn add(a: u32, b: u32) -> u32 { a + b } } +#[attr = Inline(Hint)] fn add(arg0: _, arg1: _) -> _ { m::add(arg0, arg1) } fn main() { { let _ = add(1, 2); }; } From 4648af67516fe0387f287486b5f19f7518032423 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 8 Dec 2025 18:42:10 +0100 Subject: [PATCH 0436/3801] Remove `[no-mentions]` handler in our triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- triagebot.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 6633b87f04e8..09dec7675e7e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -22,9 +22,6 @@ allow-unauthenticated = [ [mentions."clippy_lints/src/doc"] cc = ["@notriddle"] -# Prevents mentions in commits to avoid users being spammed -[no-mentions] - # Have rustbot inform users about the *No Merge Policy* [no-merges] exclude_titles = ["Rustup"] # exclude syncs from rust-lang/rust From 27a4aabffc40beda87c5990cb9b3c95e56177da9 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Mon, 8 Dec 2025 18:52:46 +0100 Subject: [PATCH 0437/3801] =?UTF-8?q?Fix=20typo=20"an"=20=E2=86=92=20"and"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 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 8b3e943b4ccd..d14d0ad2f0ea 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1324,7 +1324,7 @@ impl Read for &File { /// /// # Platform-specific behavior /// - /// This function currently returns `true` on Unix an `false` on Windows. + /// This function currently returns `true` on Unix and `false` on Windows. /// Note that this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior @@ -1385,7 +1385,7 @@ impl Write for &File { /// /// # Platform-specific behavior /// - /// This function currently returns `true` on Unix an `false` on Windows. + /// This function currently returns `true` on Unix and `false` on Windows. /// Note that this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior From 51f9b90b2b8a7167410d770db4f890f4a008ceb5 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 8 Dec 2025 18:58:56 +0100 Subject: [PATCH 0438/3801] Remove `[no-mentions]` handler in our triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- library/stdarch/triagebot.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/stdarch/triagebot.toml b/library/stdarch/triagebot.toml index 2c281c8f7d42..621f39b2cbbf 100644 --- a/library/stdarch/triagebot.toml +++ b/library/stdarch/triagebot.toml @@ -56,7 +56,3 @@ Thanks! # Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html [issue-links] check-commits = false - -# Prevents mentions in commits to avoid users being spammed -# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html -[no-mentions] From ac2a424fb36a2c894c08e19ae28e6c30d01ec70e Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 8 Dec 2025 19:03:21 +0100 Subject: [PATCH 0439/3801] Remove `[no-mentions]` handler in our triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- src/doc/rustc-dev-guide/triagebot.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/triagebot.toml b/src/doc/rustc-dev-guide/triagebot.toml index 4a8852391520..fbfe74234148 100644 --- a/src/doc/rustc-dev-guide/triagebot.toml +++ b/src/doc/rustc-dev-guide/triagebot.toml @@ -53,10 +53,6 @@ allow-unauthenticated = [ # Documentation at: https://forge.rust-lang.org/triagebot/note.html [note] -# Prevents mentions in commits to avoid users being spammed -# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html -[no-mentions] - # Canonicalize issue numbers to avoid closing the wrong issue # when commits are included in subtrees, as well as warning links in commits. # Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html From d828665b5fdb9aeab1ff8be518923818f7be2932 Mon Sep 17 00:00:00 2001 From: Urgau <3616612+Urgau@users.noreply.github.com> Date: Mon, 8 Dec 2025 19:19:22 +0100 Subject: [PATCH 0440/3801] Remove `[no-mentions]` handler in our triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- src/tools/rust-analyzer/triagebot.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tools/rust-analyzer/triagebot.toml b/src/tools/rust-analyzer/triagebot.toml index c9862495bc0c..ac4efd0a24bc 100644 --- a/src/tools/rust-analyzer/triagebot.toml +++ b/src/tools/rust-analyzer/triagebot.toml @@ -25,6 +25,3 @@ labels = ["has-merge-commits", "S-waiting-on-author"] # Canonicalize issue numbers to avoid closing the wrong issue when upstreaming this subtree [canonicalize-issue-links] - -# Prevents mentions in commits to avoid users being spammed -[no-mentions] From 1314419ccdec8f54da53a812322c8053774f88c9 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 8 Dec 2025 19:23:10 +0100 Subject: [PATCH 0441/3801] Remove `[no-mentions]` handler in our triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- triagebot.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 13da0a87def3..eb0c7b011f60 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -2,6 +2,3 @@ # Prevents un-canonicalized issue links (to avoid wrong issues being linked in r-l/rust) [issue-links] - -# Prevents mentions in commits to avoid users being spammed -[no-mentions] From 5516e54726ab45ea3f122d986ff046395c90d1e0 Mon Sep 17 00:00:00 2001 From: Urgau <3616612+Urgau@users.noreply.github.com> Date: Mon, 8 Dec 2025 19:25:31 +0100 Subject: [PATCH 0442/3801] Remove `[no-mentions]` handler in our triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- src/tools/miri/triagebot.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tools/miri/triagebot.toml b/src/tools/miri/triagebot.toml index 910e5f56e1e4..b9edd03f7a22 100644 --- a/src/tools/miri/triagebot.toml +++ b/src/tools/miri/triagebot.toml @@ -53,8 +53,5 @@ new_draft = true # Canonicalize issue numbers to avoid closing the wrong issue when upstreaming this subtree. [canonicalize-issue-links] -# Prevents mentions in commits to avoid users being spammed. -[no-mentions] - # Show range-diff links on force pushes. [range-diff] From b8581ddecc2adb994f8ddd54a8c3dc3205dec547 Mon Sep 17 00:00:00 2001 From: Urgau <3616612+Urgau@users.noreply.github.com> Date: Mon, 8 Dec 2025 19:34:19 +0100 Subject: [PATCH 0443/3801] Remove `[no-mentions]` handler in the triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- triagebot.toml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 6ad8dd6b4c88..c459f69d06bb 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1680,12 +1680,6 @@ days-threshold = 28 # Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html [issue-links] -# Prevents mentions in commits to avoid users being spammed -# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html -[no-mentions] -# Subtree update authors can't fix it, no point in warning. -exclude-titles = ["subtree update"] - # Allow members to formally register concerns (`@rustbot concern my concern`) # Documentation at: https://forge.rust-lang.org/triagebot/concern.html [concern] From 5a1936fd3fd21fd2f7459ab6f6b886b7aea5ad30 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 19:11:04 +0000 Subject: [PATCH 0444/3801] Revert build_llvm_sysroot_for_triple back from reading the manifest to filtering Reading the manifest doesn't work when running in the context of the rust build system. --- .../build_system/build_sysroot.rs | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs index e7363e37a45d..7b4c604580c1 100644 --- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs +++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs @@ -161,18 +161,35 @@ fn build_sysroot_for_triple( fn build_llvm_sysroot_for_triple(compiler: Compiler) -> SysrootTarget { let default_sysroot = crate::rustc_info::get_default_sysroot(&compiler.rustc); - let std_manifest_path = default_sysroot - .join("lib") - .join("rustlib") - .join(format!("manifest-rust-std-{}", compiler.triple)); + let mut target_libs = SysrootTarget { triple: compiler.triple, libs: vec![] }; - let libs = fs::read_to_string(std_manifest_path) - .unwrap() - .lines() - .map(|entry| default_sysroot.join(entry.strip_prefix("file:").unwrap())) - .collect(); + for entry in fs::read_dir( + default_sysroot.join("lib").join("rustlib").join(&target_libs.triple).join("lib"), + ) + .unwrap() + { + let entry = entry.unwrap(); + if entry.file_type().unwrap().is_dir() { + continue; + } + let file = entry.path(); + let file_name_str = file.file_name().unwrap().to_str().unwrap(); + if (file_name_str.contains("rustc_") + && !file_name_str.contains("rustc_std_workspace_") + && !file_name_str.contains("rustc_demangle") + && !file_name_str.contains("rustc_literal_escaper")) + || file_name_str.contains("chalk") + || file_name_str.contains("tracing") + || file_name_str.contains("regex") + { + // These are large crates that are part of the rustc-dev component and are not + // necessary to run regular programs. + continue; + } + target_libs.libs.push(file); + } - SysrootTarget { triple: compiler.triple, libs } + target_libs } fn build_clif_sysroot_for_triple( From 66381e3d790c8a5ea8f3e736e561dacb88780fdc Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 19:11:04 +0000 Subject: [PATCH 0445/3801] Revert build_llvm_sysroot_for_triple back from reading the manifest to filtering Reading the manifest doesn't work when running in the context of the rust build system. --- build_system/build_sysroot.rs | 37 +++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index e7363e37a45d..7b4c604580c1 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -161,18 +161,35 @@ fn build_sysroot_for_triple( fn build_llvm_sysroot_for_triple(compiler: Compiler) -> SysrootTarget { let default_sysroot = crate::rustc_info::get_default_sysroot(&compiler.rustc); - let std_manifest_path = default_sysroot - .join("lib") - .join("rustlib") - .join(format!("manifest-rust-std-{}", compiler.triple)); + let mut target_libs = SysrootTarget { triple: compiler.triple, libs: vec![] }; - let libs = fs::read_to_string(std_manifest_path) - .unwrap() - .lines() - .map(|entry| default_sysroot.join(entry.strip_prefix("file:").unwrap())) - .collect(); + for entry in fs::read_dir( + default_sysroot.join("lib").join("rustlib").join(&target_libs.triple).join("lib"), + ) + .unwrap() + { + let entry = entry.unwrap(); + if entry.file_type().unwrap().is_dir() { + continue; + } + let file = entry.path(); + let file_name_str = file.file_name().unwrap().to_str().unwrap(); + if (file_name_str.contains("rustc_") + && !file_name_str.contains("rustc_std_workspace_") + && !file_name_str.contains("rustc_demangle") + && !file_name_str.contains("rustc_literal_escaper")) + || file_name_str.contains("chalk") + || file_name_str.contains("tracing") + || file_name_str.contains("regex") + { + // These are large crates that are part of the rustc-dev component and are not + // necessary to run regular programs. + continue; + } + target_libs.libs.push(file); + } - SysrootTarget { triple: compiler.triple, libs } + target_libs } fn build_clif_sysroot_for_triple( From 90d2477e4e35927b20237b27869200fb1d47e7bf Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 4 Dec 2025 09:49:31 -0800 Subject: [PATCH 0446/3801] Add release notes for 1.92.0 --- RELEASES.md | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index b14cc499b46d..0dffe931e6eb 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,88 @@ +Version 1.92.0 (2025-12-11) +========================== + + + +Language +-------- +- [Document `MaybeUninit` representation and validity](https://github.com/rust-lang/rust/pull/140463) +- [Allow `&raw [mut | const]` for union field in safe code](https://github.com/rust-lang/rust/pull/141469) +- [Prefer item bounds of associated types over where-bounds for auto-traits and `Sized`](https://github.com/rust-lang/rust/pull/144064) +- [Do not materialize `X` in `[X; 0]` when `X` is unsizing a const](https://github.com/rust-lang/rust/pull/145277) +- [Support combining `#[track_caller]` and `#[no_mangle]` (requires every declaration specifying `#[track_caller]` as well)](https://github.com/rust-lang/rust/pull/145724) +- [Make never type lints `never_type_fallback_flowing_into_unsafe` and `dependency_on_unit_never_type_fallback` deny-by-default](https://github.com/rust-lang/rust/pull/146167) +- [Allow specifying multiple bounds for same associated item, except in trait objects](https://github.com/rust-lang/rust/pull/146593) +- [Slightly strengthen higher-ranked region handling in coherence](https://github.com/rust-lang/rust/pull/146725) +- [The `unused_must_use` lint no longer warns on `Result<(), Uninhabited>` (for instance, `Result<(), !>`), or `ControlFlow`](https://github.com/rust-lang/rust/pull/147382). This avoids having to check for an error that can never happen. + + + +Compiler +-------- +- [Make `mips64el-unknown-linux-muslabi64` link dynamically](https://github.com/rust-lang/rust/pull/146858) +- [Remove current code for embedding command-line args in PDB](https://github.com/rust-lang/rust/pull/147022) + Command-line information is typically not needed by debugging tools, and the removed code + was causing problems for incremental builds even on targets that don't use PDB debuginfo. + + + +Libraries +--------- +- [Specialize `Iterator::eq{_by}` for `TrustedLen` iterators](https://github.com/rust-lang/rust/pull/137122) +- [Simplify `Extend` for tuples](https://github.com/rust-lang/rust/pull/138799) +- [Added details to `Debug` for `EncodeWide`](https://github.com/rust-lang/rust/pull/140153). +- [`iter::Repeat::last`](https://github.com/rust-lang/rust/pull/147258) and [`count`](https://github.com/rust-lang/rust/pull/146410) will now panic, rather than looping infinitely. + + + +Stabilized APIs +--------------- + +- [`NonZero::div_ceil`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.div_ceil) +- [`Location::file_as_c_str`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file_as_c_str) +- [`RwLockWriteGuard::downgrade`](https://doc.rust-lang.org/stable/std/sync/struct.RwLockWriteGuard.html#method.downgrade) +- [`Box::new_zeroed`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed) +- [`Box::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed_slice) +- [`Rc::new_zeroed`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed) +- [`Rc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed_slice) +- [`Arc::new_zeroed`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed) +- [`Arc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed_slice) +- [`btree_map::Entry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.insert_entry) +- [`btree_map::VacantEntry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.VacantEntry.html#method.insert_entry) +- [`impl Extend for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CGroup%3E-for-TokenStream) +- [`impl Extend for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CLiteral%3E-for-TokenStream) +- [`impl Extend for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CPunct%3E-for-TokenStream) +- [`impl Extend for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CIdent%3E-for-TokenStream) + +These previously stable APIs are now stable in const contexts: + +- [`<[_]>::rotate_left`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_left) +- [`<[_]>::rotate_right`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_right) + + + +Cargo +----- +- [Added a new chapter](https://github.com/rust-lang/cargo/issues/16119) to the Cargo book, ["Optimizing Build Performance"](https://doc.rust-lang.org/stable/cargo/guide/build-performance.html). + + + +Rustdoc +----- +- [If a trait item appears in rustdoc search, hide the corresponding impl items](https://github.com/rust-lang/rust/pull/145898). Previously a search for "last" would show both `Iterator::last` as well as impl methods like `std::vec::IntoIter::last`. Now these impl methods will be hidden, freeing up space for inherent methods like `BTreeSet::last`. +- [Relax rules for identifiers in search](https://github.com/rust-lang/rust/pull/147860). Previously you could only search for identifiers that were valid in rust code, now searches only need to be valid as part of an identifier. For example, you can now perform a search that starts with a digit. + + + +Compatibility Notes +------------------- +* [Fix backtraces with `-C panic=abort` on Linux by generating unwind tables by default](https://github.com/rust-lang/rust/pull/143613). Build with `-C force-unwind-tables=no` to keep omitting unwind tables. +- As part of the larger effort refactoring compiler built-in attributes and their diagnostics, [the future-compatibility lint `invalid_macro_export_arguments` is upgraded to deny-by-default and will be reported in dependencies too.](https://github.com/rust-lang/rust/pull/143857) +- [Update the minimum external LLVM to 20](https://github.com/rust-lang/rust/pull/145071) +- [Prevent downstream `impl DerefMut for Pin`](https://github.com/rust-lang/rust/pull/145608) +- [Don't apply temporary lifetime extension rules to the arguments of non-extended `pin!` and formatting macros](https://github.com/rust-lang/rust/pull/145838) + + Version 1.91.1 (2025-11-10) =========================== From 01e2cf8f44b0d99c019f292140cfc58b9bc67501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 15 Sep 2025 02:28:43 -0700 Subject: [PATCH 0447/3801] Handle macro invocation in attribute during parse ``` error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found macro `concat` --> $DIR/macro-in-attribute.rs:4:21 | LL | #[deprecated(note = concat!("a", "b"))] | ^^^^^^^^^^^^^^^^^ macros are not allowed here ``` --- compiler/rustc_attr_parsing/messages.ftl | 1 + compiler/rustc_attr_parsing/src/parser.rs | 40 ++++++++++++++----- .../src/session_diagnostics.rs | 2 + .../rustc_parse/src/parser/diagnostics.rs | 2 +- tests/ui/parser/macro/macro-in-attribute.rs | 9 +++++ .../ui/parser/macro/macro-in-attribute.stderr | 8 ++++ 6 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 tests/ui/parser/macro/macro-in-attribute.rs create mode 100644 tests/ui/parser/macro/macro-in-attribute.stderr diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 0d53ed9d97a5..5cb34f96d130 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -87,6 +87,7 @@ attr_parsing_invalid_link_modifier = attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr} .remove_neg_sugg = negative numbers are not literals, try removing the `-` sign .quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal + .label = macros are not allowed here attr_parsing_invalid_predicate = invalid predicate `{$predicate}` diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 7474471f2fe0..23f0e4fa0330 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -13,7 +13,7 @@ use rustc_ast_pretty::pprust; use rustc_errors::{Diag, PResult}; use rustc_hir::{self as hir, AttrPath}; use rustc_parse::exp; -use rustc_parse::parser::{Parser, PathStyle, token_descr}; +use rustc_parse::parser::{ForceCollect, Parser, PathStyle, token_descr}; use rustc_session::errors::{create_lit_error, report_lit_error}; use rustc_session::parse::ParseSess; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, sym}; @@ -488,6 +488,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { descr: token_descr(&self.parser.token), quote_ident_sugg: None, remove_neg_sugg: None, + macro_call: None, }; // Suggest quoting idents, e.g. in `#[cfg(key = value)]`. We don't use `Token::ident` and @@ -496,20 +497,37 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { if self.parser.prev_token == token::Eq && let token::Ident(..) = self.parser.token.kind { - let before = self.parser.token.span.shrink_to_lo(); - while let token::Ident(..) = self.parser.token.kind { - self.parser.bump(); + if self.parser.look_ahead(1, |t| matches!(t.kind, token::TokenKind::Bang)) { + let snapshot = self.parser.create_snapshot_for_diagnostic(); + let stmt = self.parser.parse_stmt_without_recovery(false, ForceCollect::No, false); + match stmt { + Ok(Some(stmt)) => { + // The user tried to write something like + // `#[deprecated(note = concat!("a", "b"))]`. + err.descr = format!("macro {}", err.descr); + err.macro_call = Some(stmt.span); + err.span = stmt.span; + } + Ok(None) => {} + Err(err) => { + err.cancel(); + self.parser.restore_snapshot(snapshot); + } + } + } else { + let before = self.parser.token.span.shrink_to_lo(); + while let token::Ident(..) = self.parser.token.kind { + self.parser.bump(); + } + err.quote_ident_sugg = Some(InvalidMetaItemQuoteIdentSugg { + before, + after: self.parser.prev_token.span.shrink_to_hi(), + }); } - err.quote_ident_sugg = Some(InvalidMetaItemQuoteIdentSugg { - before, - after: self.parser.prev_token.span.shrink_to_hi(), - }); } if self.parser.token == token::Minus - && self - .parser - .look_ahead(1, |t| matches!(t.kind, rustc_ast::token::TokenKind::Literal { .. })) + && self.parser.look_ahead(1, |t| matches!(t.kind, token::TokenKind::Literal { .. })) { err.remove_neg_sugg = Some(InvalidMetaItemRemoveNegSugg { negative_sign: self.parser.token.span }); diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index c4f6f9c6a38c..95eca25fd362 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -804,6 +804,8 @@ pub(crate) struct InvalidMetaItem { pub quote_ident_sugg: Option, #[subdiagnostic] pub remove_neg_sugg: Option, + #[label] + pub macro_call: Option, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index d4667a09af6d..4f6860fead8d 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -284,7 +284,7 @@ impl<'a> Parser<'a> { } /// Replace `self` with `snapshot.parser`. - pub(super) fn restore_snapshot(&mut self, snapshot: SnapshotParser<'a>) { + pub fn restore_snapshot(&mut self, snapshot: SnapshotParser<'a>) { *self = snapshot.parser; } diff --git a/tests/ui/parser/macro/macro-in-attribute.rs b/tests/ui/parser/macro/macro-in-attribute.rs new file mode 100644 index 000000000000..57808c6fd27d --- /dev/null +++ b/tests/ui/parser/macro/macro-in-attribute.rs @@ -0,0 +1,9 @@ +// Test for #146325. +// Ensure that when we encounter a macro invocation in an attribute, we don't suggest nonsense. + +#[deprecated(note = concat!("a", "b"))] +struct X; +//~^^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found macro `concat` +//~| NOTE: macros are not allowed here + +fn main() {} diff --git a/tests/ui/parser/macro/macro-in-attribute.stderr b/tests/ui/parser/macro/macro-in-attribute.stderr new file mode 100644 index 000000000000..e0ae51365a85 --- /dev/null +++ b/tests/ui/parser/macro/macro-in-attribute.stderr @@ -0,0 +1,8 @@ +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found macro `concat` + --> $DIR/macro-in-attribute.rs:4:21 + | +LL | #[deprecated(note = concat!("a", "b"))] + | ^^^^^^^^^^^^^^^^^ macros are not allowed here + +error: aborting due to 1 previous error + From 0b0e826c0fc09eb54487658ab782e816d92619d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 28 Sep 2025 20:52:57 +0000 Subject: [PATCH 0448/3801] Rework attribute recovery logic --- compiler/rustc_ast/src/ast.rs | 13 +++ compiler/rustc_attr_parsing/messages.ftl | 2 +- compiler/rustc_attr_parsing/src/parser.rs | 80 ++++++++++--------- .../src/session_diagnostics.rs | 2 +- tests/ui/attributes/malformed-fn-align.rs | 2 +- tests/ui/attributes/malformed-fn-align.stderr | 4 +- ...-66340-deprecated-attr-non-meta-grammar.rs | 2 +- ...40-deprecated-attr-non-meta-grammar.stderr | 4 +- tests/ui/parser/attribute/attr-bad-meta-4.rs | 2 +- .../parser/attribute/attr-bad-meta-4.stderr | 4 +- .../parser/attribute/attr-unquoted-ident.rs | 19 +++-- .../attribute/attr-unquoted-ident.stderr | 25 ++++-- tests/ui/parser/macro/expr-in-attribute.rs | 9 +++ .../ui/parser/macro/expr-in-attribute.stderr | 8 ++ tests/ui/parser/macro/macro-in-attribute.rs | 2 +- .../ui/parser/macro/macro-in-attribute.stderr | 2 +- 16 files changed, 116 insertions(+), 64 deletions(-) create mode 100644 tests/ui/parser/macro/expr-in-attribute.rs create mode 100644 tests/ui/parser/macro/expr-in-attribute.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index db7cace49ae8..b696ebeba992 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1259,6 +1259,19 @@ pub enum StmtKind { MacCall(Box), } +impl StmtKind { + pub fn descr(&self) -> &'static str { + match self { + StmtKind::Let(_) => "local", + StmtKind::Item(_) => "item", + StmtKind::Expr(_) => "expression", + StmtKind::Semi(_) => "statement", + StmtKind::Empty => "semicolon", + StmtKind::MacCall(_) => "macro", + } + } +} + #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct MacCallStmt { pub mac: Box, diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 5cb34f96d130..02ddf8ac0023 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -87,7 +87,7 @@ attr_parsing_invalid_link_modifier = attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr} .remove_neg_sugg = negative numbers are not literals, try removing the `-` sign .quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal - .label = macros are not allowed here + .label = {$descr}s are not allowed here attr_parsing_invalid_predicate = invalid predicate `{$predicate}` diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 23f0e4fa0330..819e5630561d 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -8,7 +8,7 @@ use std::fmt::{Debug, Display}; use rustc_ast::token::{self, Delimiter, MetaVarKind}; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path}; +use rustc_ast::{AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path, StmtKind, UnOp}; use rustc_ast_pretty::pprust; use rustc_errors::{Diag, PResult}; use rustc_hir::{self as hir, AttrPath}; @@ -488,51 +488,55 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { descr: token_descr(&self.parser.token), quote_ident_sugg: None, remove_neg_sugg: None, - macro_call: None, + label: None, }; + if let token::OpenInvisible(_) = self.parser.token.kind { + // Do not attempt to suggest anything when encountered as part of a macro expansion. + return self.parser.dcx().create_err(err); + } + // Suggest quoting idents, e.g. in `#[cfg(key = value)]`. We don't use `Token::ident` and // don't `uninterpolate` the token to avoid suggesting anything butchered or questionable // when macro metavariables are involved. - if self.parser.prev_token == token::Eq - && let token::Ident(..) = self.parser.token.kind - { - if self.parser.look_ahead(1, |t| matches!(t.kind, token::TokenKind::Bang)) { - let snapshot = self.parser.create_snapshot_for_diagnostic(); - let stmt = self.parser.parse_stmt_without_recovery(false, ForceCollect::No, false); - match stmt { - Ok(Some(stmt)) => { - // The user tried to write something like - // `#[deprecated(note = concat!("a", "b"))]`. - err.descr = format!("macro {}", err.descr); - err.macro_call = Some(stmt.span); - err.span = stmt.span; - } - Ok(None) => {} - Err(err) => { - err.cancel(); - self.parser.restore_snapshot(snapshot); + let snapshot = self.parser.create_snapshot_for_diagnostic(); + let stmt = self.parser.parse_stmt_without_recovery(false, ForceCollect::No, false); + match stmt { + Ok(Some(stmt)) => { + // The user tried to write something like + // `#[deprecated(note = concat!("a", "b"))]`. + err.descr = stmt.kind.descr().to_string(); + err.label = Some(stmt.span); + err.span = stmt.span; + if let StmtKind::Expr(expr) = &stmt.kind + && let ExprKind::Unary(UnOp::Neg, val) = &expr.kind + && let ExprKind::Lit(_) = val.kind + { + err.remove_neg_sugg = Some(InvalidMetaItemRemoveNegSugg { + negative_sign: expr.span.until(val.span), + }); + } else if let StmtKind::Expr(expr) = &stmt.kind + && let ExprKind::Path(None, Path { segments, .. }) = &expr.kind + && segments.len() == 1 + { + while let token::Ident(..) | token::Literal(_) | token::Dot = + self.parser.token.kind + { + // We've got a word, so we try to consume the rest of a potential sentence. + // We include `.` to correctly handle things like `A sentence here.`. + self.parser.bump(); } + err.quote_ident_sugg = Some(InvalidMetaItemQuoteIdentSugg { + before: expr.span.shrink_to_lo(), + after: self.parser.prev_token.span.shrink_to_hi(), + }); } - } else { - let before = self.parser.token.span.shrink_to_lo(); - while let token::Ident(..) = self.parser.token.kind { - self.parser.bump(); - } - err.quote_ident_sugg = Some(InvalidMetaItemQuoteIdentSugg { - before, - after: self.parser.prev_token.span.shrink_to_hi(), - }); } - } - - if self.parser.token == token::Minus - && self.parser.look_ahead(1, |t| matches!(t.kind, token::TokenKind::Literal { .. })) - { - err.remove_neg_sugg = - Some(InvalidMetaItemRemoveNegSugg { negative_sign: self.parser.token.span }); - self.parser.bump(); - self.parser.bump(); + Ok(None) => {} + Err(e) => { + e.cancel(); + self.parser.restore_snapshot(snapshot); + } } self.parser.dcx().create_err(err) diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 95eca25fd362..2b3108a8d3ed 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -805,7 +805,7 @@ pub(crate) struct InvalidMetaItem { #[subdiagnostic] pub remove_neg_sugg: Option, #[label] - pub macro_call: Option, + pub label: Option, } #[derive(Subdiagnostic)] diff --git a/tests/ui/attributes/malformed-fn-align.rs b/tests/ui/attributes/malformed-fn-align.rs index c76eda65a75b..219218f03479 100644 --- a/tests/ui/attributes/malformed-fn-align.rs +++ b/tests/ui/attributes/malformed-fn-align.rs @@ -26,7 +26,7 @@ fn f3() {} #[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on functions fn f4() {} -#[rustc_align(-1)] //~ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-` +#[rustc_align(-1)] //~ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found fn f5() {} #[rustc_align(3)] //~ ERROR invalid alignment value: not a power of two diff --git a/tests/ui/attributes/malformed-fn-align.stderr b/tests/ui/attributes/malformed-fn-align.stderr index 33f789b62695..b419df8ea2d1 100644 --- a/tests/ui/attributes/malformed-fn-align.stderr +++ b/tests/ui/attributes/malformed-fn-align.stderr @@ -37,11 +37,11 @@ error[E0589]: invalid alignment value: not a power of two LL | #[rustc_align(0)] | ^ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression --> $DIR/malformed-fn-align.rs:29:15 | LL | #[rustc_align(-1)] - | ^ + | ^^ expressions are not allowed here | help: negative numbers are not literals, try removing the `-` sign | diff --git a/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs b/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs index 378d0a3e7235..cdf2b76a1ccc 100644 --- a/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs +++ b/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs @@ -7,5 +7,5 @@ fn main() { } #[deprecated(note = test)] -//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `test` +//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found fn foo() {} diff --git a/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr b/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr index cd985ab5a182..379c7f581224 100644 --- a/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr +++ b/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr @@ -1,8 +1,8 @@ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `test` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression --> $DIR/issue-66340-deprecated-attr-non-meta-grammar.rs:9:21 | LL | #[deprecated(note = test)] - | ^^^^ + | ^^^^ expressions are not allowed here | help: surround the identifier with quotation marks to make it into a string literal | diff --git a/tests/ui/parser/attribute/attr-bad-meta-4.rs b/tests/ui/parser/attribute/attr-bad-meta-4.rs index 606b41e89a5f..bfd2958ad565 100644 --- a/tests/ui/parser/attribute/attr-bad-meta-4.rs +++ b/tests/ui/parser/attribute/attr-bad-meta-4.rs @@ -9,7 +9,7 @@ macro_rules! mac { mac!(an(arbitrary token stream)); #[cfg(feature = -1)] -//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-` +//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found fn handler() {} fn main() {} diff --git a/tests/ui/parser/attribute/attr-bad-meta-4.stderr b/tests/ui/parser/attribute/attr-bad-meta-4.stderr index 1d939942fb9a..8f4edca226d3 100644 --- a/tests/ui/parser/attribute/attr-bad-meta-4.stderr +++ b/tests/ui/parser/attribute/attr-bad-meta-4.stderr @@ -1,8 +1,8 @@ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression --> $DIR/attr-bad-meta-4.rs:11:17 | LL | #[cfg(feature = -1)] - | ^ + | ^^ expressions are not allowed here | help: negative numbers are not literals, try removing the `-` sign | diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.rs b/tests/ui/parser/attribute/attr-unquoted-ident.rs index 8a0c65b783a7..152448bf8a0f 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.rs +++ b/tests/ui/parser/attribute/attr-unquoted-ident.rs @@ -4,14 +4,21 @@ fn main() { #[cfg(key=foo)] - //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `foo` - //~| HELP surround the identifier with quotation marks to make it into a string literal + //~^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found + //~| HELP: surround the identifier with quotation marks to make it into a string literal + //~| NOTE: expressions are not allowed here println!(); #[cfg(key="bar")] println!(); #[cfg(key=foo bar baz)] - //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `foo` - //~| HELP surround the identifier with quotation marks to make it into a string literal + //~^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found + //~| HELP: surround the identifier with quotation marks to make it into a string literal + //~| NOTE: expressions are not allowed here + println!(); + #[cfg(key=foo 1 bar 2.0 baz.)] + //~^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found + //~| HELP: surround the identifier with quotation marks to make it into a string literal + //~| NOTE: expressions are not allowed here println!(); } @@ -19,7 +26,7 @@ fn main() { macro_rules! make { ($name:ident) => { #[doc(alias = $name)] pub struct S; } - //~^ ERROR expected unsuffixed literal, found identifier `nickname` + //~^ ERROR: expected unsuffixed literal, found identifier `nickname` } -make!(nickname); //~ NOTE in this expansion +make!(nickname); //~ NOTE: in this expansion diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.stderr b/tests/ui/parser/attribute/attr-unquoted-ident.stderr index 8a2785280adc..f1af60dec9bb 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.stderr +++ b/tests/ui/parser/attribute/attr-unquoted-ident.stderr @@ -1,27 +1,38 @@ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `foo` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression --> $DIR/attr-unquoted-ident.rs:6:15 | LL | #[cfg(key=foo)] - | ^^^ + | ^^^ expressions are not allowed here | help: surround the identifier with quotation marks to make it into a string literal | LL | #[cfg(key="foo")] | + + -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `foo` - --> $DIR/attr-unquoted-ident.rs:12:15 +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/attr-unquoted-ident.rs:13:15 | LL | #[cfg(key=foo bar baz)] - | ^^^ + | ^^^ expressions are not allowed here | help: surround the identifier with quotation marks to make it into a string literal | LL | #[cfg(key="foo bar baz")] | + + +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/attr-unquoted-ident.rs:18:15 + | +LL | #[cfg(key=foo 1 bar 2.0 baz.)] + | ^^^ expressions are not allowed here + | +help: surround the identifier with quotation marks to make it into a string literal + | +LL | #[cfg(key="foo 1 bar 2.0 baz.")] + | + + + error: expected unsuffixed literal, found identifier `nickname` - --> $DIR/attr-unquoted-ident.rs:21:38 + --> $DIR/attr-unquoted-ident.rs:28:38 | LL | ($name:ident) => { #[doc(alias = $name)] pub struct S; } | ^^^^^ @@ -31,5 +42,5 @@ LL | make!(nickname); | = note: this error originates in the macro `make` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/parser/macro/expr-in-attribute.rs b/tests/ui/parser/macro/expr-in-attribute.rs new file mode 100644 index 000000000000..8c8934493361 --- /dev/null +++ b/tests/ui/parser/macro/expr-in-attribute.rs @@ -0,0 +1,9 @@ +// Test for #146325. +// Ensure that when we encounter an expr invocation in an attribute, we don't suggest nonsense. + +#[deprecated(note = a!=b)] +struct X; +//~^^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression +//~| NOTE: expressions are not allowed here + +fn main() {} diff --git a/tests/ui/parser/macro/expr-in-attribute.stderr b/tests/ui/parser/macro/expr-in-attribute.stderr new file mode 100644 index 000000000000..08d6f12d1e64 --- /dev/null +++ b/tests/ui/parser/macro/expr-in-attribute.stderr @@ -0,0 +1,8 @@ +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/expr-in-attribute.rs:4:21 + | +LL | #[deprecated(note = a!=b)] + | ^^^^ expressions are not allowed here + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/macro-in-attribute.rs b/tests/ui/parser/macro/macro-in-attribute.rs index 57808c6fd27d..efb7de9f01c4 100644 --- a/tests/ui/parser/macro/macro-in-attribute.rs +++ b/tests/ui/parser/macro/macro-in-attribute.rs @@ -3,7 +3,7 @@ #[deprecated(note = concat!("a", "b"))] struct X; -//~^^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found macro `concat` +//~^^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found //~| NOTE: macros are not allowed here fn main() {} diff --git a/tests/ui/parser/macro/macro-in-attribute.stderr b/tests/ui/parser/macro/macro-in-attribute.stderr index e0ae51365a85..08fb66440757 100644 --- a/tests/ui/parser/macro/macro-in-attribute.stderr +++ b/tests/ui/parser/macro/macro-in-attribute.stderr @@ -1,4 +1,4 @@ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found macro `concat` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found macro --> $DIR/macro-in-attribute.rs:4:21 | LL | #[deprecated(note = concat!("a", "b"))] From c1500f986f2a814378714b5a7939f4d43350c121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 3 Nov 2025 19:21:31 +0000 Subject: [PATCH 0449/3801] review comment --- compiler/rustc_ast/src/ast.rs | 2 +- tests/ui/parser/macro/macro-in-attribute.rs | 2 +- tests/ui/parser/macro/macro-in-attribute.stderr | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b696ebeba992..78da2fa9163c 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1267,7 +1267,7 @@ impl StmtKind { StmtKind::Expr(_) => "expression", StmtKind::Semi(_) => "statement", StmtKind::Empty => "semicolon", - StmtKind::MacCall(_) => "macro", + StmtKind::MacCall(_) => "macro call", } } } diff --git a/tests/ui/parser/macro/macro-in-attribute.rs b/tests/ui/parser/macro/macro-in-attribute.rs index efb7de9f01c4..7a4b3b22baa9 100644 --- a/tests/ui/parser/macro/macro-in-attribute.rs +++ b/tests/ui/parser/macro/macro-in-attribute.rs @@ -4,6 +4,6 @@ #[deprecated(note = concat!("a", "b"))] struct X; //~^^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found -//~| NOTE: macros are not allowed here +//~| NOTE: macro calls are not allowed here fn main() {} diff --git a/tests/ui/parser/macro/macro-in-attribute.stderr b/tests/ui/parser/macro/macro-in-attribute.stderr index 08fb66440757..d057c93ede07 100644 --- a/tests/ui/parser/macro/macro-in-attribute.stderr +++ b/tests/ui/parser/macro/macro-in-attribute.stderr @@ -1,8 +1,8 @@ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found macro +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found macro call --> $DIR/macro-in-attribute.rs:4:21 | LL | #[deprecated(note = concat!("a", "b"))] - | ^^^^^^^^^^^^^^^^^ macros are not allowed here + | ^^^^^^^^^^^^^^^^^ macro calls are not allowed here error: aborting due to 1 previous error From 761cb57aef119745ed8eab68f03508a1e5950d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Dec 2025 01:20:58 +0000 Subject: [PATCH 0450/3801] fix test --- tests/ui/macros/cfg_select.rs | 2 +- tests/ui/macros/cfg_select.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index 2a627cc05b93..586e4037d7c1 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -68,7 +68,7 @@ cfg_select! { cfg_select! { () => {} - //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `(` + //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression } cfg_select! { diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 3a5d2b0a1e1e..a14e24334661 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -27,11 +27,11 @@ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `=>` LL | => {} | ^^ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `(` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression --> $DIR/cfg_select.rs:70:5 | LL | () => {} - | ^ + | ^^ expressions are not allowed here error[E0539]: malformed `cfg_select` macro input --> $DIR/cfg_select.rs:75:5 From 5c91f2c4d3635192cbed539c0c3ef88e4bfdd2a5 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 8 Dec 2025 22:41:13 +1100 Subject: [PATCH 0451/3801] Make `--print=backend-has-zstd` work by default on any backend Using a defaulted `CodegenBackend` method that querying for zstd support should automatically print a safe value of `false` on any backend that doesn't specifically indicate the presence or absence of zstd. --- compiler/rustc_codegen_cranelift/src/lib.rs | 12 +----------- compiler/rustc_codegen_llvm/src/lib.rs | 8 ++++---- compiler/rustc_codegen_ssa/src/traits/backend.rs | 8 ++++++++ compiler/rustc_driver_impl/src/lib.rs | 5 ++++- src/tools/compiletest/src/directives/needs.rs | 4 ++++ 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index b47b9afa4f07..5fdecd014ac0 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -47,7 +47,7 @@ use rustc_codegen_ssa::{CodegenResults, TargetConfig}; use rustc_log::tracing::info; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; -use rustc_session::config::{OutputFilenames, PrintKind, PrintRequest}; +use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; use rustc_target::spec::{Abi, Arch, Env, Os}; @@ -160,16 +160,6 @@ impl CodegenBackend for CraneliftCodegenBackend { } } - fn print(&self, req: &PrintRequest, out: &mut String, _sess: &Session) { - match req.kind { - // FIXME have a default impl that returns false - PrintKind::BackendHasZstd => { - out.push_str("false\n"); - } - _ => {} - } - } - fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] let target_features = match sess.target.arch { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 8c0c0afcc1dd..0da5810518c5 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -257,10 +257,6 @@ impl CodegenBackend for LlvmCodegenBackend { } writeln!(out).unwrap(); } - PrintKind::BackendHasZstd => { - let has_zstd = llvm::LLVMRustLLVMHasZstdCompression(); - writeln!(out, "{has_zstd}").unwrap(); - } PrintKind::CodeModels => { writeln!(out, "Available code models:").unwrap(); for name in &["tiny", "small", "kernel", "medium", "large"] { @@ -314,6 +310,10 @@ impl CodegenBackend for LlvmCodegenBackend { llvm_util::print_version(); } + fn has_zstd(&self) -> bool { + llvm::LLVMRustLLVMHasZstdCompression() + } + fn target_config(&self, sess: &Session) -> TargetConfig { target_config(sess) } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 85bff4540814..cb74e2e46d65 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -78,6 +78,14 @@ pub trait CodegenBackend { fn print_version(&self) {} + /// Value printed by `--print=backend-has-zstd`. + /// + /// Used by compiletest to determine whether tests involving zstd compression + /// (e.g. `-Zdebuginfo-compression=zstd`) should be executed or skipped. + fn has_zstd(&self) -> bool { + false + } + /// The metadata loader used to load rlib and dylib metadata. /// /// Alternative codegen backends may want to use different rlib or dylib formats than the diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 0853f638509f..63fc9c96f450 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -798,8 +798,11 @@ fn print_crate_info( let calling_conventions = rustc_abi::all_names(); println_info!("{}", calling_conventions.join("\n")); } + BackendHasZstd => { + let has_zstd: bool = codegen_backend.has_zstd(); + println_info!("{has_zstd}"); + } RelocationModels - | BackendHasZstd | CodeModels | TlsModels | TargetCPUs diff --git a/src/tools/compiletest/src/directives/needs.rs b/src/tools/compiletest/src/directives/needs.rs index 208e96166021..92b596c70ae9 100644 --- a/src/tools/compiletest/src/directives/needs.rs +++ b/src/tools/compiletest/src/directives/needs.rs @@ -432,6 +432,10 @@ fn has_symlinks() -> bool { } fn llvm_has_zstd(config: &Config) -> bool { + // FIXME(#149764): This actually queries the compiler's _default_ backend, + // which is usually LLVM, but can be another backend depending on the value + // of `rust.codegen-backends` in bootstrap.toml. + // The compiler already knows whether LLVM was built with zstd or not, // so compiletest can just ask the compiler. let output = query_rustc_output( From d38a5a6d1d3a988d43ceb247d378317d2e157c9e Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 8 Dec 2025 22:41:13 +1100 Subject: [PATCH 0452/3801] Make `--print=backend-has-zstd` work by default on any backend Using a defaulted `CodegenBackend` method that querying for zstd support should automatically print a safe value of `false` on any backend that doesn't specifically indicate the presence or absence of zstd. --- src/lib.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b47b9afa4f07..5fdecd014ac0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,7 +47,7 @@ use rustc_codegen_ssa::{CodegenResults, TargetConfig}; use rustc_log::tracing::info; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; -use rustc_session::config::{OutputFilenames, PrintKind, PrintRequest}; +use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; use rustc_target::spec::{Abi, Arch, Env, Os}; @@ -160,16 +160,6 @@ impl CodegenBackend for CraneliftCodegenBackend { } } - fn print(&self, req: &PrintRequest, out: &mut String, _sess: &Session) { - match req.kind { - // FIXME have a default impl that returns false - PrintKind::BackendHasZstd => { - out.push_str("false\n"); - } - _ => {} - } - } - fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] let target_features = match sess.target.arch { From ef9928781a40b84fa3e768ea0da393e47352bfee Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 9 Dec 2025 12:34:35 +0800 Subject: [PATCH 0453/3801] Add complex tests for assist generate_fn_type_alias --- .../src/handlers/generate_fn_type_alias.rs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs index 0b7eca2290f6..7fd94b4bedc8 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs @@ -269,6 +269,22 @@ fn foo(a: A, b: B) -> i32 { return 42; } ); } + #[test] + fn generate_fn_alias_unnamed_complex_types() { + check_assist_by_label( + generate_fn_type_alias, + r#" +fn fo$0o(x: Vec) {} +"#, + r#" +type ${0:FooFn} = fn(Vec); + +fn foo(x: Vec) {} +"#, + ParamStyle::Unnamed.label(), + ); + } + #[test] fn generate_fn_alias_unnamed_self() { check_assist_by_label( @@ -405,6 +421,22 @@ fn foo(a: A, b: B) -> i32 { return 42; } ); } + #[test] + fn generate_fn_alias_named_complex_types() { + check_assist_by_label( + generate_fn_type_alias, + r#" +fn fo$0o(x: Vec) {} +"#, + r#" +type ${0:FooFn} = fn(x: Vec); + +fn foo(x: Vec) {} +"#, + ParamStyle::Named.label(), + ); + } + #[test] fn generate_fn_alias_named_self() { check_assist_by_label( From 51da96d7d23625c18559552f5c5649bbbc5bf215 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 7 Dec 2025 14:51:56 +0100 Subject: [PATCH 0454/3801] fix: Disable postcard use temporarily --- src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index e31ab86bdd2d..d6a8d27bfc42 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -58,7 +58,9 @@ impl ProcMacroServerProcess { if v.pre.as_str() == "nightly" { *v > VERSION } else { *v >= VERSION } }); - let formats: &[_] = if has_working_format_flag { + let formats: &[_] = if std::env::var_os("RUST_ANALYZER_USE_POSTCARD").is_some() + && has_working_format_flag + { &[ (Some("postcard-legacy"), Protocol::LegacyPostcard { mode: SpanMode::Id }), (Some("json-legacy"), Protocol::LegacyJson { mode: SpanMode::Id }), From 27590b0832bedfc0a3bead82634a365ced74d88b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 9 Dec 2025 08:29:55 +0100 Subject: [PATCH 0455/3801] fix manual_let_else --- .../src/borrow_tracker/stacked_borrows/mod.rs | 13 +++--- .../src/borrow_tracker/tree_borrows/mod.rs | 40 +++++++++---------- src/tools/miri/src/concurrency/weak_memory.rs | 5 +-- src/tools/miri/src/eval.rs | 4 +- src/tools/miri/src/lib.rs | 7 +++- src/tools/miri/src/shims/backtrace.rs | 11 ++--- src/tools/miri/src/shims/native_lib/mod.rs | 9 ++--- src/tools/miri/src/shims/time.rs | 14 ++----- src/tools/miri/src/shims/unix/freebsd/sync.rs | 21 +++------- .../miri/src/shims/unix/linux_like/sync.rs | 7 +--- src/tools/miri/src/shims/unix/sync.rs | 13 +++--- src/tools/miri/src/shims/windows/fs.rs | 21 ++-------- 12 files changed, 59 insertions(+), 106 deletions(-) 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 e8d97491acaf..a21898c506ab 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -826,15 +826,12 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> { // FIXME: If we cannot determine the size (because the unsized tail is an `extern type`), // bail out -- we cannot reasonably figure out which memory range to reborrow. // See https://github.com/rust-lang/unsafe-code-guidelines/issues/276. - let size = match size { - Some(size) => size, - None => { - static DEDUP: AtomicBool = AtomicBool::new(false); - if !DEDUP.swap(true, std::sync::atomic::Ordering::Relaxed) { - this.emit_diagnostic(NonHaltingDiagnostic::ExternTypeReborrow); - } - return interp_ok(place.clone()); + let Some(size) = size else { + static DEDUP: AtomicBool = AtomicBool::new(false); + if !DEDUP.swap(true, std::sync::atomic::Ordering::Relaxed) { + this.emit_diagnostic(NonHaltingDiagnostic::ExternTypeReborrow); } + return interp_ok(place.clone()); }; // Compute new borrow. 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 018421ad1064..6b1194e5e5da 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -219,26 +219,18 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; trace!("Reborrow of size {:?}", ptr_size); - let (alloc_id, base_offset, parent_prov) = match this.ptr_try_get_alloc_id(place.ptr(), 0) { - Ok(data) => { - // Unlike SB, we *do* a proper retag for size 0 if can identify the allocation. - // After all, the pointer may be lazily initialized outside this initial range. - data - } - Err(_) => { - assert_eq!(ptr_size, Size::ZERO); // we did the deref check above, size has to be 0 here - // This pointer doesn't come with an AllocId, so there's no - // memory to do retagging in. - let new_prov = place.ptr().provenance; - trace!( - "reborrow of size 0: reusing {:?} (pointee {})", - place.ptr(), - place.layout.ty, - ); - log_creation(this, None)?; - // Keep original provenance. - return interp_ok(new_prov); - } + // Unlike SB, we *do* a proper retag for size 0 if can identify the allocation. + // After all, the pointer may be lazily initialized outside this initial range. + let Ok((alloc_id, base_offset, parent_prov)) = this.ptr_try_get_alloc_id(place.ptr(), 0) + else { + assert_eq!(ptr_size, Size::ZERO); // we did the deref check above, size has to be 0 here + // This pointer doesn't come with an AllocId, so there's no + // memory to do retagging in. + let new_prov = place.ptr().provenance; + trace!("reborrow of size 0: reusing {:?} (pointee {})", place.ptr(), place.layout.ty,); + log_creation(this, None)?; + // Keep original provenance. + return interp_ok(new_prov); }; let new_prov = Provenance::Concrete { alloc_id, tag: new_tag }; @@ -609,8 +601,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let (tag, alloc_id) = match ptr.provenance { Some(Provenance::Concrete { tag, alloc_id }) => (tag, alloc_id), - _ => { - eprintln!("Can't give the name {name} to Wildcard pointer"); + Some(Provenance::Wildcard) => { + eprintln!("Can't give the name {name} to wildcard pointer"); + return interp_ok(()); + } + None => { + eprintln!("Can't give the name {name} to pointer without provenance"); return interp_ok(()); } }; diff --git a/src/tools/miri/src/concurrency/weak_memory.rs b/src/tools/miri/src/concurrency/weak_memory.rs index 2255e0d48174..6fe73fec0f57 100644 --- a/src/tools/miri/src/concurrency/weak_memory.rs +++ b/src/tools/miri/src/concurrency/weak_memory.rs @@ -208,11 +208,10 @@ impl StoreBufferAlloc { range: AllocRange, ) -> InterpResult<'tcx, Option>> { let access_type = self.store_buffers.borrow().access_type(range); - let pos = match access_type { - AccessType::PerfectlyOverlapping(pos) => pos, + let AccessType::PerfectlyOverlapping(pos) = access_type else { // If there is nothing here yet, that means there wasn't an atomic write yet so // we can't return anything outdated. - _ => return interp_ok(None), + return interp_ok(None); }; let store_buffer = Ref::map(self.store_buffers.borrow(), |buffer| &buffer[pos]); interp_ok(Some(store_buffer)) diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 01a54bbb3374..0423b0ea5abd 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -543,9 +543,7 @@ where { // Parse argv[0]. Slashes aren't escaped. Literal double quotes are not allowed. let mut cmd = { - let arg0 = if let Some(arg0) = args.next() { - arg0 - } else { + let Some(arg0) = args.next() else { return vec![0]; }; let arg0 = arg0.as_ref(); diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index fe501b8d7b30..9776ef825e72 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -46,7 +46,12 @@ rustc::potential_query_instability, rustc::untranslatable_diagnostic, )] -#![warn(rust_2018_idioms, unqualified_local_imports, clippy::as_conversions)] +#![warn( + rust_2018_idioms, + unqualified_local_imports, + clippy::as_conversions, + clippy::manual_let_else +)] // Needed for rustdoc from bootstrap (with `-Znormalize-docs`). #![recursion_limit = "256"] diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index bd3914b652ac..1ca814ee7aff 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -92,21 +92,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let (alloc_id, offset, _prov) = this.ptr_get_alloc_id(ptr, 0)?; // This has to be an actual global fn ptr, not a dlsym function. - let fn_instance = if let Some(GlobalAlloc::Function { instance, .. }) = - this.tcx.try_get_global_alloc(alloc_id) - { - instance - } else { + let Some(GlobalAlloc::Function { instance, .. }) = this.tcx.try_get_global_alloc(alloc_id) + else { throw_ub_format!("expected static function pointer, found {:?}", ptr); }; let lo = this.tcx.sess.source_map().lookup_char_pos(BytePos(offset.bytes().try_into().unwrap())); - let name = fn_instance.to_string(); + let name = instance.to_string(); let filename = lo.file.name.prefer_remapped_unconditionally().to_string(); - interp_ok((fn_instance, lo, name, filename)) + interp_ok((instance, lo, name, filename)) } fn handle_miri_resolve_frame( diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index 445f9618e7e3..12abe841c052 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -459,12 +459,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); // Get the pointer to the function in the shared object file if it exists. - let code_ptr = match this.get_func_ptr_explicitly_from_lib(link_name) { - Some(ptr) => ptr, - None => { - // Shared object file does not export this function -- try the shims next. - return interp_ok(false); - } + let Some(code_ptr) = this.get_func_ptr_explicitly_from_lib(link_name) else { + // Shared object file does not export this function -- try the shims next. + return interp_ok(false); }; // Do we have ptrace? diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index 614cc75c6d58..2bbae80a0b91 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -337,11 +337,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let duration = this.deref_pointer_as(duration, this.libc_ty_layout("timespec"))?; let _rem = this.read_pointer(rem)?; // Signal handlers are not supported, so rem will never be written to. - let duration = match this.read_timespec(&duration)? { - Some(duration) => duration, - None => { - return this.set_last_error_and_return_i32(LibcError("EINVAL")); - } + let Some(duration) = this.read_timespec(&duration)? else { + return this.set_last_error_and_return_i32(LibcError("EINVAL")); }; this.block_thread( @@ -378,11 +375,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_unsup_format!("clock_nanosleep: only CLOCK_MONOTONIC is supported"); } - let duration = match this.read_timespec(×pec)? { - Some(duration) => duration, - None => { - return this.set_last_error_and_return_i32(LibcError("EINVAL")); - } + let Some(duration) = this.read_timespec(×pec)? else { + return this.set_last_error_and_return_i32(LibcError("EINVAL")); }; let timeout_anchor = if flags == 0 { diff --git a/src/tools/miri/src/shims/unix/freebsd/sync.rs b/src/tools/miri/src/shims/unix/freebsd/sync.rs index bd1ee3155372..ae8a167080b9 100644 --- a/src/tools/miri/src/shims/unix/freebsd/sync.rs +++ b/src/tools/miri/src/shims/unix/freebsd/sync.rs @@ -101,12 +101,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `uaddr2` points to a `struct _umtx_time`. let umtx_time_place = this.ptr_to_mplace(uaddr2, umtx_time_layout); - let umtx_time = match this.read_umtx_time(&umtx_time_place)? { - Some(ut) => ut, - None => { - return this - .set_last_error_and_return(LibcError("EINVAL"), dest); - } + let Some(umtx_time) = this.read_umtx_time(&umtx_time_place)? else { + return this.set_last_error_and_return(LibcError("EINVAL"), dest); }; let anchor = if umtx_time.abs_time { @@ -122,12 +118,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `uaddr2` points to a `struct timespec`. let timespec = this.ptr_to_mplace(uaddr2, timespec_layout); - let duration = match this.read_timespec(×pec)? { - Some(duration) => duration, - None => { - return this - .set_last_error_and_return(LibcError("EINVAL"), dest); - } + let Some(duration) = this.read_timespec(×pec)? else { + return this.set_last_error_and_return(LibcError("EINVAL"), dest); }; // FreeBSD does not seem to document which clock is used when the timeout @@ -220,10 +212,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let timespec_place = this.project_field(ut, FieldIdx::from_u32(0))?; // Inner `timespec` must still be valid. - let duration = match this.read_timespec(×pec_place)? { - Some(dur) => dur, - None => return interp_ok(None), - }; + let Some(duration) = this.read_timespec(×pec_place)? else { return interp_ok(None) }; let flags_place = this.project_field(ut, FieldIdx::from_u32(1))?; let flags = this.read_scalar(&flags_place)?.to_u32()?; 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 8ff7fe0a4563..00df4ee2b2ae 100644 --- a/src/tools/miri/src/shims/unix/linux_like/sync.rs +++ b/src/tools/miri/src/shims/unix/linux_like/sync.rs @@ -71,11 +71,8 @@ pub fn futex<'tcx>( let timeout = if ecx.ptr_is_null(timeout.ptr())? { None } else { - let duration = match ecx.read_timespec(&timeout)? { - Some(duration) => duration, - None => { - return ecx.set_last_error_and_return(LibcError("EINVAL"), dest); - } + let Some(duration) = ecx.read_timespec(&timeout)? else { + return ecx.set_last_error_and_return(LibcError("EINVAL"), dest); }; let timeout_clock = if op & futex_realtime == futex_realtime { ecx.check_no_isolation( diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index 39ad66041820..58a612102b18 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -887,15 +887,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let mutex_ref = mutex_get_data(this, mutex_op)?.mutex_ref.clone(); // Extract the timeout. - let duration = match this + let Some(duration) = this .read_timespec(&this.deref_pointer_as(timeout_op, this.libc_ty_layout("timespec"))?)? - { - Some(duration) => duration, - None => { - let einval = this.eval_libc("EINVAL"); - this.write_scalar(einval, dest)?; - return interp_ok(()); - } + else { + let einval = this.eval_libc("EINVAL"); + this.write_scalar(einval, dest)?; + return interp_ok(()); }; let (clock, anchor) = if macos_relative_np { diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs index 775c08388c07..ad22df2425af 100644 --- a/src/tools/miri/src/shims/windows/fs.rs +++ b/src/tools/miri/src/shims/windows/fs.rs @@ -321,11 +321,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.windows_ty_layout("BY_HANDLE_FILE_INFORMATION"), )?; - let fd_num = if let Handle::File(fd_num) = file { - fd_num - } else { - this.invalid_handle("GetFileInformationByHandle")? - }; + let Handle::File(fd_num) = file else { this.invalid_handle("GetFileInformationByHandle")? }; let Some(desc) = this.machine.fds.get(fd_num) else { this.invalid_handle("GetFileInformationByHandle")? @@ -448,10 +444,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_unsup_format!("`NtWriteFile` `Key` parameter is non-null, which is unsupported"); } - let fd = match handle { - Handle::File(fd) => fd, - _ => this.invalid_handle("NtWriteFile")?, - }; + let Handle::File(fd) = handle else { this.invalid_handle("NtWriteFile")? }; let Some(desc) = this.machine.fds.get(fd) else { this.invalid_handle("NtWriteFile")? }; @@ -561,10 +554,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; let io_status_info = this.project_field_named(&io_status_block, "Information")?; - let fd = match handle { - Handle::File(fd) => fd, - _ => this.invalid_handle("NtWriteFile")?, - }; + let Handle::File(fd) = handle else { this.invalid_handle("NtWriteFile")? }; let Some(desc) = this.machine.fds.get(fd) else { this.invalid_handle("NtReadFile")? }; @@ -620,10 +610,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let new_fp_ptr = this.read_pointer(new_fp)?; let move_method = this.read_scalar(move_method)?.to_u32()?; - let fd = match file { - Handle::File(fd) => fd, - _ => this.invalid_handle("SetFilePointerEx")?, - }; + let Handle::File(fd) = file else { this.invalid_handle("SetFilePointerEx")? }; let Some(desc) = this.machine.fds.get(fd) else { throw_unsup_format!("`SetFilePointerEx` is only supported on file backed handles"); From 34392a99c0434c93bdaab5c6655f83417303c21c Mon Sep 17 00:00:00 2001 From: DrAsu33 <3537555264@qq.com> Date: Sat, 29 Nov 2025 06:22:41 +0000 Subject: [PATCH 0456/3801] Fix(alloc): Correctly handle ZST alignment for IntoIter::nth_back This commit consolidates all changes, including the core logic fix for IntoIter::nth_back and the addition of the Miri regression test in `library/alloctests/tests/vec.rs`, to prevent Undefined Behavior (UB) when dealing with highly-aligned Zero-Sized Types. --- library/alloc/src/vec/into_iter.rs | 7 ++++++- library/alloctests/tests/vec.rs | 32 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 358bdeacae79..af1bd5317973 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -411,7 +411,12 @@ impl DoubleEndedIterator for IntoIter { // SAFETY: same as for advance_by() self.end = unsafe { self.end.sub(step_size) }; } - let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size); + let to_drop = if T::IS_ZST { + // ZST may cause unalignment + ptr::slice_from_raw_parts_mut(ptr::NonNull::::dangling().as_ptr(), step_size) + } else { + ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size) + }; // SAFETY: same as for advance_by() unsafe { ptr::drop_in_place(to_drop); diff --git a/library/alloctests/tests/vec.rs b/library/alloctests/tests/vec.rs index dd42230d2e00..cd5b14f6eff3 100644 --- a/library/alloctests/tests/vec.rs +++ b/library/alloctests/tests/vec.rs @@ -2717,3 +2717,35 @@ fn vec_null_ptr_roundtrip() { let new = roundtripped.with_addr(ptr.addr()); unsafe { new.read() }; } + +// Regression test for Undefined Behavior (UB) caused by IntoIter::nth_back (#148682) +// when dealing with high-aligned Zero-Sized Types (ZSTs). +use std::collections::{BTreeMap, BinaryHeap, HashMap, LinkedList, VecDeque}; +#[test] +fn zst_collections_iter_nth_back_regression() { + #[repr(align(8))] + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] + struct Thing; + let v = vec![Thing, Thing]; + let _ = v.into_iter().nth_back(1); + let mut d = VecDeque::new(); + d.push_back(Thing); + d.push_back(Thing); + let _ = d.into_iter().nth_back(1); + let mut map = BTreeMap::new(); + map.insert(0, Thing); + map.insert(1, Thing); + let _ = map.into_values().nth_back(0); + let mut hash_map = HashMap::new(); + hash_map.insert(1, Thing); + hash_map.insert(2, Thing); + let _ = hash_map.into_values().nth(1); + let mut heap = BinaryHeap::new(); + heap.push(Thing); + heap.push(Thing); + let _ = heap.into_iter().nth_back(1); + let mut list = LinkedList::new(); + list.push_back(Thing); + list.push_back(Thing); + let _ = list.into_iter().nth_back(1); +} From d1d1181789b2139d2c685ac69913858023f7aaa6 Mon Sep 17 00:00:00 2001 From: xiaolinny Date: Tue, 9 Dec 2025 17:07:18 +0800 Subject: [PATCH 0457/3801] chore: fix some minor issues in the comments Signed-off-by: xiaolinny --- library/std/src/io/buffered/tests.rs | 2 +- .../src/rustdoc-internals/rustdoc-json-test-suite.md | 10 +++++----- .../repeat-expr/copy-check-deferred-after-fallback.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs index 068dca819775..fc77b02a8e82 100644 --- a/library/std/src/io/buffered/tests.rs +++ b/library/std/src/io/buffered/tests.rs @@ -172,7 +172,7 @@ fn test_buffered_reader_stream_position_panic() { // cause internal buffer to be filled but read only partially let mut buffer = [0, 0]; assert!(reader.read_exact(&mut buffer).is_ok()); - // rewinding the internal reader will cause buffer to loose sync + // rewinding the internal reader will cause buffer to lose sync let inner = reader.get_mut(); assert!(inner.seek(SeekFrom::Start(0)).is_ok()); // overflow when subtracting the remaining buffer size from current position diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md index e19a8204ab41..5781a12ca44c 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md @@ -4,7 +4,7 @@ This page is specifically about the test suite named `rustdoc-json`, which tests For other test suites used for testing rustdoc, see [§Rustdoc test suites](../tests/compiletest.md#rustdoc-test-suites). Tests are run with compiletest, and have access to the usual set of [directives](../tests/directives.md). -Frequenly used directives here are: +Frequently used directives here are: - [`//@ aux-build`][aux-build] to have dependencies. - `//@ edition: 2021` (or some other edition). @@ -23,8 +23,8 @@ Also, talk about how it works ## jsondocck -[jsondocck] processes direcives given in comments, to assert that the values in the output are expected. -It's alot like [htmldocck](./rustdoc-test-suite.md) in that way. +[jsondocck] processes directives given in comments, to assert that the values in the output are expected. +It's a lot like [htmldocck](./rustdoc-test-suite.md) in that way. It uses [JSONPath] as a query language, which takes a path, and returns a *list* of values that that path is said to match to. @@ -48,7 +48,7 @@ These are defined in [`directive.rs`]. Values can be either JSON values, or variables. - JSON values are JSON literals, e.g. `true`, `"string"`, `{"key": "value"}`. - These often need to be quoted using `'`, to be processed as 1 value. See [§Argument spliting](#argument-spliting) + These often need to be quoted using `'`, to be processed as 1 value. See [§Argument splitting](#argument-splitting) - Variables can be used to store the value in one path, and use it in later queries. They are set with the `//@ set = ` directive, and accessed with `$` @@ -57,7 +57,7 @@ Values can be either JSON values, or variables. //@ is $.some.other.path $foo ``` -### Argument spliting +### Argument splitting Arguments to directives are split using the [shlex] crate, which implements POSIX shell escaping. This is because both `` and `` arguments to [directives](#directives) frequently have both diff --git a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs index a6bd5b299c96..02cd9f4a3b29 100644 --- a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs +++ b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs @@ -1,6 +1,6 @@ // Test when deferring repeat expr copy checks to end of typechecking whether they're // checked before integer fallback occurs or not. We accomplish this by having a repeat -// count that can only be inferred after integer fallback has occured. This test will +// count that can only be inferred after integer fallback has occurred. This test will // pass if we were to check repeat exprs after integer fallback. use std::marker::PhantomData; From 79b30d64e76cdc44275822b481c0dd1832b81d0e Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 9 Dec 2025 10:52:13 +0100 Subject: [PATCH 0458/3801] thread, grid, and block dim/idx can only return non-negative values --- .../stdarch/crates/core_arch/src/nvptx/mod.rs | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/nvptx/mod.rs b/library/stdarch/crates/core_arch/src/nvptx/mod.rs index 8d16dfb53d43..5471ef819801 100644 --- a/library/stdarch/crates/core_arch/src/nvptx/mod.rs +++ b/library/stdarch/crates/core_arch/src/nvptx/mod.rs @@ -23,29 +23,29 @@ unsafe extern "C" { #[link_name = "llvm.nvvm.barrier0"] fn syncthreads() -> (); #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.x"] - fn block_dim_x() -> i32; + fn block_dim_x() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.y"] - fn block_dim_y() -> i32; + fn block_dim_y() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.z"] - fn block_dim_z() -> i32; + fn block_dim_z() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.ctaid.x"] - fn block_idx_x() -> i32; + fn block_idx_x() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.ctaid.y"] - fn block_idx_y() -> i32; + fn block_idx_y() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.ctaid.z"] - fn block_idx_z() -> i32; + fn block_idx_z() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.nctaid.x"] - fn grid_dim_x() -> i32; + fn grid_dim_x() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.nctaid.y"] - fn grid_dim_y() -> i32; + fn grid_dim_y() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.nctaid.z"] - fn grid_dim_z() -> i32; + fn grid_dim_z() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.tid.x"] - fn thread_idx_x() -> i32; + fn thread_idx_x() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.tid.y"] - fn thread_idx_y() -> i32; + fn thread_idx_y() -> u32; #[link_name = "llvm.nvvm.read.ptx.sreg.tid.z"] - fn thread_idx_z() -> i32; + fn thread_idx_z() -> u32; } /// Synchronizes all threads in the block. @@ -58,84 +58,84 @@ pub unsafe fn _syncthreads() -> () { /// x-th thread-block dimension. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _block_dim_x() -> i32 { +pub unsafe fn _block_dim_x() -> u32 { block_dim_x() } /// y-th thread-block dimension. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _block_dim_y() -> i32 { +pub unsafe fn _block_dim_y() -> u32 { block_dim_y() } /// z-th thread-block dimension. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _block_dim_z() -> i32 { +pub unsafe fn _block_dim_z() -> u32 { block_dim_z() } /// x-th thread-block index. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _block_idx_x() -> i32 { +pub unsafe fn _block_idx_x() -> u32 { block_idx_x() } /// y-th thread-block index. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _block_idx_y() -> i32 { +pub unsafe fn _block_idx_y() -> u32 { block_idx_y() } /// z-th thread-block index. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _block_idx_z() -> i32 { +pub unsafe fn _block_idx_z() -> u32 { block_idx_z() } /// x-th block-grid dimension. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _grid_dim_x() -> i32 { +pub unsafe fn _grid_dim_x() -> u32 { grid_dim_x() } /// y-th block-grid dimension. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _grid_dim_y() -> i32 { +pub unsafe fn _grid_dim_y() -> u32 { grid_dim_y() } /// z-th block-grid dimension. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _grid_dim_z() -> i32 { +pub unsafe fn _grid_dim_z() -> u32 { grid_dim_z() } /// x-th thread index. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _thread_idx_x() -> i32 { +pub unsafe fn _thread_idx_x() -> u32 { thread_idx_x() } /// y-th thread index. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _thread_idx_y() -> i32 { +pub unsafe fn _thread_idx_y() -> u32 { thread_idx_y() } /// z-th thread index. #[inline] #[unstable(feature = "stdarch_nvptx", issue = "111199")] -pub unsafe fn _thread_idx_z() -> i32 { +pub unsafe fn _thread_idx_z() -> u32 { thread_idx_z() } From 75df299225d56977ebacca0400c4fcaa3b316726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 9 Dec 2025 11:30:03 +0100 Subject: [PATCH 0459/3801] Mirror `ubuntu:24.04` on ghcr --- .github/workflows/ghcr.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ghcr.yml b/.github/workflows/ghcr.yml index a89867efe666..ddb3b2ce0dd5 100644 --- a/.github/workflows/ghcr.yml +++ b/.github/workflows/ghcr.yml @@ -55,6 +55,8 @@ jobs: images=( # Mirrored because used by the tidy job, which doesn't cache Docker images "ubuntu:22.04" + # Mirrored because used by x86-64-gnu-miri + "ubuntu:24.04" # Mirrored because used by all linux CI jobs, including tidy "moby/buildkit:buildx-stable-1" # Mirrored because used when CI is running inside a Docker container From 51780a53f65906e5fd3ee213fb005a0864cfc06a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 17 Oct 2025 20:45:51 +0300 Subject: [PATCH 0460/3801] resolve: Preserve ambiguous glob reexports in crate metadata So in cross-crate scenarios they can work in the same way as in crate-local scenarios. --- compiler/rustc_metadata/src/lib.rs | 1 + compiler/rustc_metadata/src/rmeta/decoder.rs | 15 +++ .../src/rmeta/decoder/cstore_impl.rs | 10 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 ++ compiler/rustc_metadata/src/rmeta/mod.rs | 3 +- .../rustc_metadata/src/rmeta/parameterized.rs | 1 + compiler/rustc_middle/src/metadata.rs | 14 +++ compiler/rustc_middle/src/ty/mod.rs | 3 +- .../rustc_resolve/src/build_reduced_graph.rs | 79 +++++++++++----- compiler/rustc_resolve/src/diagnostics.rs | 7 +- compiler/rustc_resolve/src/imports.rs | 50 +++++++--- compiler/rustc_resolve/src/lib.rs | 27 +++++- tests/ui/imports/ambiguous-2.rs | 5 +- tests/ui/imports/ambiguous-2.stderr | 45 +++++++++ tests/ui/imports/ambiguous-4.rs | 5 +- tests/ui/imports/ambiguous-4.stderr | 45 +++++++++ .../ambiguous-glob-vs-expanded-extern.rs | 6 ++ .../ambiguous-glob-vs-expanded-extern.stderr | 47 ++++++++++ .../ui/imports/auxiliary/glob-vs-expanded.rs | 11 +++ tests/ui/imports/extern-with-ambiguous-2.rs | 5 +- .../ui/imports/extern-with-ambiguous-2.stderr | 23 +++++ tests/ui/imports/extern-with-ambiguous-3.rs | 5 +- .../ui/imports/extern-with-ambiguous-3.stderr | 23 +++++ .../ui/imports/glob-conflict-cross-crate-1.rs | 10 +- .../glob-conflict-cross-crate-1.stderr | 84 +++++++++++++++-- .../ui/imports/glob-conflict-cross-crate-2.rs | 4 +- .../glob-conflict-cross-crate-2.stderr | 42 ++++++++- .../ui/imports/glob-conflict-cross-crate-3.rs | 6 +- .../glob-conflict-cross-crate-3.stderr | 91 +++++++++++++++++++ tests/ui/imports/issue-114682-2.rs | 15 +-- tests/ui/imports/issue-114682-2.stderr | 88 +++++++++++++++++- tests/ui/imports/issue-114682-3.rs | 4 +- tests/ui/imports/issue-114682-3.stderr | 18 ++++ tests/ui/imports/issue-114682-4.rs | 5 +- tests/ui/imports/issue-114682-4.stderr | 60 ++++++++++++ tests/ui/imports/issue-114682-5.rs | 7 +- tests/ui/imports/issue-114682-5.stderr | 77 ++++++++++++++++ tests/ui/imports/issue-114682-6.rs | 5 +- tests/ui/imports/issue-114682-6.stderr | 45 +++++++++ 39 files changed, 896 insertions(+), 103 deletions(-) create mode 100644 tests/ui/imports/ambiguous-2.stderr create mode 100644 tests/ui/imports/ambiguous-4.stderr create mode 100644 tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs create mode 100644 tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr create mode 100644 tests/ui/imports/auxiliary/glob-vs-expanded.rs create mode 100644 tests/ui/imports/extern-with-ambiguous-2.stderr create mode 100644 tests/ui/imports/extern-with-ambiguous-3.stderr create mode 100644 tests/ui/imports/glob-conflict-cross-crate-3.stderr create mode 100644 tests/ui/imports/issue-114682-3.stderr create mode 100644 tests/ui/imports/issue-114682-4.stderr create mode 100644 tests/ui/imports/issue-114682-5.stderr create mode 100644 tests/ui/imports/issue-114682-6.stderr diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 01060eb7e32c..114301083883 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -9,6 +9,7 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(proc_macro_internals)] +#![feature(result_option_map_or_default)] #![feature(trusted_len)] // tidy-alphabetical-end diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index bf7818b49933..65cbdc675962 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1284,6 +1284,21 @@ impl<'a> CrateMetadataRef<'a> { } } + fn get_ambig_module_children( + self, + tcx: TyCtxt<'_>, + id: DefIndex, + ) -> impl Iterator { + gen move { + let children = self.root.tables.ambig_module_children.get((self, tcx), id); + if !children.is_default() { + for child in children.decode((self, tcx)) { + yield child; + } + } + } + } + fn is_ctfe_mir_available(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool { self.root.tables.mir_for_ctfe.get((self, tcx), id).is_some() } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index ac4faae5a87a..c48cf36930f4 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -8,7 +8,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::bug; -use rustc_middle::metadata::ModChild; +use rustc_middle::metadata::{AmbigModChild, ModChild}; use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::middle::stability::DeprecationEntry; use rustc_middle::query::{ExternProviders, LocalCrate}; @@ -585,6 +585,14 @@ impl CStore { self.get_crate_data(def_id.krate).get_expn_that_defined(tcx, def_id.index) } + pub fn ambig_module_children_untracked( + &self, + tcx: TyCtxt<'_>, + def_id: DefId, + ) -> impl Iterator { + self.get_crate_data(def_id.krate).get_ambig_module_children(tcx, def_id.index) + } + /// Only public-facing way to traverse all the definitions in a non-local crate. /// Critically useful for this third-party project: . /// See for context. diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 94bba9445610..86719581a209 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1731,6 +1731,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_defaulted_array!(self.tables.module_children_reexports[def_id] <- module_children.iter().filter(|child| !child.reexport_chain.is_empty())); + + let ambig_module_children = tcx + .resolutions(()) + .ambig_module_children + .get(&local_def_id) + .map_or_default(|v| &v[..]); + record_defaulted_array!(self.tables.ambig_module_children[def_id] <- + ambig_module_children); } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 8ac1dd83ee5d..c5230685bfaf 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -21,7 +21,7 @@ use rustc_index::bit_set::DenseBitSet; use rustc_macros::{ BlobDecodable, Decodable, Encodable, LazyDecodable, MetadataEncodable, TyDecodable, TyEncodable, }; -use rustc_middle::metadata::ModChild; +use rustc_middle::metadata::{AmbigModChild, ModChild}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs; @@ -399,6 +399,7 @@ define_tables! { // That's why the encoded list needs to contain `ModChild` structures describing all the names // individually instead of `DefId`s. module_children_reexports: Table>, + ambig_module_children: Table>, cross_crate_inlinable: Table, asyncness: Table, constness: Table, diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs index d8bae5a54e31..d6ccad798112 100644 --- a/compiler/rustc_metadata/src/rmeta/parameterized.rs +++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs @@ -94,6 +94,7 @@ trivially_parameterized_over_tcx! { rustc_hir::def_id::DefIndex, rustc_hir::definitions::DefKey, rustc_index::bit_set::DenseBitSet, + rustc_middle::metadata::AmbigModChild, rustc_middle::metadata::ModChild, rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs, rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile, diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index 57c8960943b1..2b0be9865799 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -44,3 +44,17 @@ pub struct ModChild { /// Empty if the module child is a proper item. pub reexport_chain: SmallVec<[Reexport; 2]>, } + +#[derive(Debug, TyEncodable, TyDecodable, HashStable)] +pub enum AmbigModChildKind { + GlobVsGlob, + GlobVsExpanded, +} + +/// Same as `ModChild`, however, it includes ambiguity error. +#[derive(Debug, TyEncodable, TyDecodable, HashStable)] +pub struct AmbigModChild { + pub main: ModChild, + pub second: ModChild, + pub kind: AmbigModChildKind, +} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b4c20d7cadf9..2f2f35d3633d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -108,7 +108,7 @@ pub use self::typeck_results::{ Rust2024IncompatiblePatInfo, TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind, }; use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason}; -use crate::metadata::ModChild; +use crate::metadata::{AmbigModChild, ModChild}; use crate::middle::privacy::EffectiveVisibilities; use crate::mir::{Body, CoroutineLayout, CoroutineSavedLocal, SourceInfo}; use crate::query::{IntoQueryParam, Providers}; @@ -173,6 +173,7 @@ pub struct ResolverGlobalCtxt { pub extern_crate_map: UnordMap, pub maybe_unused_trait_imports: FxIndexSet, pub module_children: LocalDefIdMap>, + pub ambig_module_children: LocalDefIdMap>, pub glob_map: FxIndexMap>, pub main_def: Option, pub trait_impls: FxIndexMap>, diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 26658aef3359..b9c945a440f8 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -22,7 +22,7 @@ use rustc_hir::def::{self, *}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::LoadedMacro; -use rustc_middle::metadata::ModChild; +use rustc_middle::metadata::{AmbigModChildKind, ModChild, Reexport}; use rustc_middle::ty::{Feed, Visibility}; use rustc_middle::{bug, span_bug}; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind}; @@ -36,9 +36,9 @@ use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use crate::ref_mut::CmCell; use crate::{ - BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot, - NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, Used, - VisResolutionError, errors, + AmbiguityKind, BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, + ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, + ResolutionError, Resolver, Segment, Used, VisResolutionError, errors, }; type Res = def::Res; @@ -81,9 +81,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { res: Res, vis: Visibility, span: Span, - expn_id: LocalExpnId, + expansion: LocalExpnId, + ambiguity: Option<(NameBinding<'ra>, AmbiguityKind)>, ) { - let binding = self.arenas.new_res_binding(res, vis, span, expn_id); + let binding = self.arenas.alloc_name_binding(NameBindingData { + kind: NameBindingKind::Res(res), + ambiguity, + // External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment. + warn_ambiguity: true, + vis, + span, + expansion, + }); // Even if underscore names cannot be looked up, we still need to add them to modules, // because they can be fetched by glob imports from those modules, and bring traits // into scope both directly and through glob imports. @@ -232,9 +241,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } pub(crate) fn build_reduced_graph_external(&self, module: Module<'ra>) { - for (i, child) in self.tcx.module_children(module.def_id()).into_iter().enumerate() { - let parent_scope = ParentScope::module(module, self.arenas); - self.build_reduced_graph_for_external_crate_res(child, parent_scope, i) + let def_id = module.def_id(); + let children = self.tcx.module_children(def_id); + let parent_scope = ParentScope::module(module, self.arenas); + for (i, child) in children.iter().enumerate() { + self.build_reduced_graph_for_external_crate_res(child, parent_scope, i, None) + } + for (i, child) in + self.cstore().ambig_module_children_untracked(self.tcx, def_id).enumerate() + { + self.build_reduced_graph_for_external_crate_res( + &child.main, + parent_scope, + children.len() + i, + Some((&child.second, child.kind)), + ) } } @@ -244,18 +265,36 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { child: &ModChild, parent_scope: ParentScope<'ra>, child_index: usize, + ambig_child: Option<(&ModChild, AmbigModChildKind)>, ) { let parent = parent_scope.module; + let child_span = |this: &Self, reexport_chain: &[Reexport], res: def::Res<_>| { + this.def_span( + reexport_chain + .first() + .and_then(|reexport| reexport.id()) + .unwrap_or_else(|| res.def_id()), + ) + }; let ModChild { ident, res, vis, ref reexport_chain } = *child; - let span = self.def_span( - reexport_chain - .first() - .and_then(|reexport| reexport.id()) - .unwrap_or_else(|| res.def_id()), - ); + let span = child_span(self, reexport_chain, res); let res = res.expect_non_local(); let expansion = parent_scope.expansion; + let ambig = ambig_child.map(|(ambig_child, ambig_kind)| { + let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child; + let span = child_span(self, reexport_chain, res); + let res = res.expect_non_local(); + let ambig_kind = match ambig_kind { + AmbigModChildKind::GlobVsGlob => AmbiguityKind::GlobVsGlob, + AmbigModChildKind::GlobVsExpanded => AmbiguityKind::GlobVsExpanded, + }; + (self.arenas.new_res_binding(res, vis, span, expansion), ambig_kind) + }); + // Record primary definitions. + let define_extern = |ns| { + self.define_extern(parent, ident, ns, child_index, res, vis, span, expansion, ambig) + }; match res { Res::Def( DefKind::Mod @@ -272,9 +311,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { _, ) | Res::PrimTy(..) - | Res::ToolMod => { - self.define_extern(parent, ident, TypeNS, child_index, res, vis, span, expansion) - } + | Res::ToolMod => define_extern(TypeNS), Res::Def( DefKind::Fn | DefKind::AssocFn @@ -283,10 +320,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | DefKind::AssocConst | DefKind::Ctor(..), _, - ) => self.define_extern(parent, ident, ValueNS, child_index, res, vis, span, expansion), - Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => { - self.define_extern(parent, ident, MacroNS, child_index, res, vis, span, expansion) - } + ) => define_extern(ValueNS), + Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => define_extern(MacroNS), Res::Def( DefKind::TyParam | DefKind::ConstParam diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 33c111708e36..19b8d6c9dead 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -148,12 +148,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let diag = self.ambiguity_diagnostic(ambiguity_error); if ambiguity_error.warning { - let NameBindingKind::Import { import, .. } = ambiguity_error.b1.0.kind else { - unreachable!() + let node_id = match ambiguity_error.b1.0.kind { + NameBindingKind::Import { import, .. } => import.root_id, + NameBindingKind::Res(_) => CRATE_NODE_ID, }; self.lint_buffer.buffer_lint( AMBIGUOUS_GLOB_IMPORTS, - import.root_id, + node_id, diag.ident.span, diag, ); diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index f844e7b9cc12..4ef87af56050 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -9,7 +9,7 @@ use rustc_errors::codes::*; use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err}; use rustc_hir::def::{self, DefKind, PartialRes}; use rustc_hir::def_id::{DefId, LocalDefIdMap}; -use rustc_middle::metadata::{ModChild, Reexport}; +use rustc_middle::metadata::{AmbigModChild, AmbigModChildKind, ModChild, Reexport}; use rustc_middle::span_bug; use rustc_middle::ty::Visibility; use rustc_session::lint::BuiltinLintDiag; @@ -21,7 +21,6 @@ use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::LocalExpnId; use rustc_span::{Ident, Span, Symbol, kw, sym}; -use smallvec::SmallVec; use tracing::debug; use crate::Namespace::{self, *}; @@ -227,7 +226,7 @@ impl<'ra> ImportData<'ra> { } } - fn simplify(&self, r: &Resolver<'_, '_>) -> Reexport { + pub(crate) fn simplify(&self, r: &Resolver<'_, '_>) -> Reexport { let to_def_id = |id| r.local_def_id(id).to_def_id(); match self.kind { ImportKind::Single { id, .. } => Reexport::Single(to_def_id(id)), @@ -571,10 +570,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn finalize_imports(&mut self) { let mut module_children = Default::default(); + let mut ambig_module_children = Default::default(); for module in &self.local_modules { - self.finalize_resolutions_in(*module, &mut module_children); + self.finalize_resolutions_in(*module, &mut module_children, &mut ambig_module_children); } self.module_children = module_children; + self.ambig_module_children = ambig_module_children; let mut seen_spans = FxHashSet::default(); let mut errors = vec![]; @@ -1546,6 +1547,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &self, module: Module<'ra>, module_children: &mut LocalDefIdMap>, + ambig_module_children: &mut LocalDefIdMap>, ) { // Since import resolution is finished, globs will not define any more names. *module.globs.borrow_mut(self) = Vec::new(); @@ -1553,26 +1555,46 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let Some(def_id) = module.opt_def_id() else { return }; let mut children = Vec::new(); + let mut ambig_children = Vec::new(); module.for_each_child(self, |this, ident, _, binding| { let res = binding.res().expect_non_local(); - let error_ambiguity = binding.is_ambiguity_recursive() && !binding.warn_ambiguity; - if res != def::Res::Err && !error_ambiguity { - let mut reexport_chain = SmallVec::new(); - let mut next_binding = binding; - while let NameBindingKind::Import { binding, import, .. } = next_binding.kind { - reexport_chain.push(import.simplify(this)); - next_binding = binding; - } + if res != def::Res::Err { + let child = |reexport_chain| ModChild { + ident: ident.0, + res, + vis: binding.vis, + reexport_chain, + }; + if let Some((ambig_binding1, ambig_binding2, ambig_kind)) = + binding.descent_to_ambiguity() + { + let main = child(ambig_binding1.reexport_chain(this)); + let second = ModChild { + ident: ident.0, + res: ambig_binding2.res().expect_non_local(), + vis: ambig_binding2.vis, + reexport_chain: ambig_binding2.reexport_chain(this), + }; + let kind = match ambig_kind { + AmbiguityKind::GlobVsGlob => AmbigModChildKind::GlobVsGlob, + AmbiguityKind::GlobVsExpanded => AmbigModChildKind::GlobVsExpanded, + _ => unreachable!(), + }; - children.push(ModChild { ident: ident.0, res, vis: binding.vis, reexport_chain }); + ambig_children.push(AmbigModChild { main, second, kind }) + } else { + children.push(child(binding.reexport_chain(this))); + } } }); if !children.is_empty() { - // Should be fine because this code is only called for local modules. module_children.insert(def_id.expect_local(), children); } + if !ambig_children.is_empty() { + ambig_module_children.insert(def_id.expect_local(), ambig_children); + } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 35d54615772b..8132bf577d88 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -64,7 +64,7 @@ use rustc_hir::definitions::DisambiguatorState; use rustc_hir::{PrimTy, TraitCandidate}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::CStore; -use rustc_middle::metadata::ModChild; +use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; use rustc_middle::span_bug; @@ -927,6 +927,18 @@ impl<'ra> NameBindingData<'ra> { } } + fn descent_to_ambiguity( + self: NameBinding<'ra>, + ) -> Option<(NameBinding<'ra>, NameBinding<'ra>, AmbiguityKind)> { + match self.ambiguity { + Some((ambig_binding, ambig_kind)) => Some((self, ambig_binding, ambig_kind)), + None => match self.kind { + NameBindingKind::Import { binding, .. } => binding.descent_to_ambiguity(), + _ => None, + }, + } + } + fn is_ambiguity_recursive(&self) -> bool { self.ambiguity.is_some() || match self.kind { @@ -990,6 +1002,16 @@ impl<'ra> NameBindingData<'ra> { self.res().macro_kinds() } + fn reexport_chain(self: NameBinding<'ra>, r: &Resolver<'_, '_>) -> SmallVec<[Reexport; 2]> { + let mut reexport_chain = SmallVec::new(); + let mut next_binding = self; + while let NameBindingKind::Import { binding, import, .. } = next_binding.kind { + reexport_chain.push(import.simplify(r)); + next_binding = binding; + } + reexport_chain + } + // Suppose that we resolved macro invocation with `invoc_parent_expansion` to binding `binding` // at some expansion round `max(invoc, binding)` when they both emerged from macros. // Then this function returns `true` if `self` may emerge from a macro *after* that @@ -1123,6 +1145,7 @@ pub struct Resolver<'ra, 'tcx> { /// `CrateNum` resolutions of `extern crate` items. extern_crate_map: UnordMap, module_children: LocalDefIdMap>, + ambig_module_children: LocalDefIdMap>, trait_map: NodeMap>, /// A map from nodes to anonymous modules. @@ -1580,6 +1603,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { extra_lifetime_params_map: Default::default(), extern_crate_map: Default::default(), module_children: Default::default(), + ambig_module_children: Default::default(), trait_map: NodeMap::default(), empty_module, local_modules, @@ -1766,6 +1790,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { effective_visibilities, extern_crate_map, module_children: self.module_children, + ambig_module_children: self.ambig_module_children, glob_map, maybe_unused_trait_imports, main_def, diff --git a/tests/ui/imports/ambiguous-2.rs b/tests/ui/imports/ambiguous-2.rs index 087431485ad6..65c971c00b9a 100644 --- a/tests/ui/imports/ambiguous-2.rs +++ b/tests/ui/imports/ambiguous-2.rs @@ -1,10 +1,9 @@ -//@ check-pass //@ aux-build: ../ambiguous-1.rs // https://github.com/rust-lang/rust/pull/113099#issuecomment-1633574396 extern crate ambiguous_1; fn main() { - ambiguous_1::id(); - //^ FIXME: `id` should be identified as an ambiguous item. + ambiguous_1::id(); //~ ERROR `id` is ambiguous + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/ambiguous-2.stderr b/tests/ui/imports/ambiguous-2.stderr new file mode 100644 index 000000000000..d428e58a78fd --- /dev/null +++ b/tests/ui/imports/ambiguous-2.stderr @@ -0,0 +1,45 @@ +error: `id` is ambiguous + --> $DIR/ambiguous-2.rs:7:18 + | +LL | ambiguous_1::id(); + | ^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `id` could refer to the function defined here + --> $DIR/auxiliary/../ambiguous-1.rs:13:13 + | +LL | pub use self::evp::*; + | ^^^^^^^^^ +note: `id` could also refer to the function defined here + --> $DIR/auxiliary/../ambiguous-1.rs:15:13 + | +LL | pub use self::handwritten::*; + | ^^^^^^^^^^^^^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +error: aborting due to 1 previous error + +Future incompatibility report: Future breakage diagnostic: +error: `id` is ambiguous + --> $DIR/ambiguous-2.rs:7:18 + | +LL | ambiguous_1::id(); + | ^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `id` could refer to the function defined here + --> $DIR/auxiliary/../ambiguous-1.rs:13:13 + | +LL | pub use self::evp::*; + | ^^^^^^^^^ +note: `id` could also refer to the function defined here + --> $DIR/auxiliary/../ambiguous-1.rs:15:13 + | +LL | pub use self::handwritten::*; + | ^^^^^^^^^^^^^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/ambiguous-4.rs b/tests/ui/imports/ambiguous-4.rs index d604dca30eed..e66d231f93cc 100644 --- a/tests/ui/imports/ambiguous-4.rs +++ b/tests/ui/imports/ambiguous-4.rs @@ -1,10 +1,9 @@ //@ edition:2015 -//@ check-pass //@ aux-build: ../ambiguous-4-extern.rs extern crate ambiguous_4_extern; fn main() { - ambiguous_4_extern::id(); - //^ FIXME: `id` should be identified as an ambiguous item. + ambiguous_4_extern::id(); //~ ERROR `id` is ambiguous + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/ambiguous-4.stderr b/tests/ui/imports/ambiguous-4.stderr new file mode 100644 index 000000000000..cf4127cbbb1c --- /dev/null +++ b/tests/ui/imports/ambiguous-4.stderr @@ -0,0 +1,45 @@ +error: `id` is ambiguous + --> $DIR/ambiguous-4.rs:7:25 + | +LL | ambiguous_4_extern::id(); + | ^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `id` could refer to the function defined here + --> $DIR/auxiliary/../ambiguous-4-extern.rs:13:9 + | +LL | pub use evp::*; + | ^^^ +note: `id` could also refer to the function defined here + --> $DIR/auxiliary/../ambiguous-4-extern.rs:14:9 + | +LL | pub use handwritten::*; + | ^^^^^^^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +error: aborting due to 1 previous error + +Future incompatibility report: Future breakage diagnostic: +error: `id` is ambiguous + --> $DIR/ambiguous-4.rs:7:25 + | +LL | ambiguous_4_extern::id(); + | ^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `id` could refer to the function defined here + --> $DIR/auxiliary/../ambiguous-4-extern.rs:13:9 + | +LL | pub use evp::*; + | ^^^ +note: `id` could also refer to the function defined here + --> $DIR/auxiliary/../ambiguous-4-extern.rs:14:9 + | +LL | pub use handwritten::*; + | ^^^^^^^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs new file mode 100644 index 000000000000..de632119ecba --- /dev/null +++ b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs @@ -0,0 +1,6 @@ +//@ aux-crate: glob_vs_expanded=glob-vs-expanded.rs + +fn main() { + glob_vs_expanded::mac!(); //~ ERROR `mac` is ambiguous + //~| WARN this was previously accepted +} diff --git a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr new file mode 100644 index 000000000000..c2e775e6c862 --- /dev/null +++ b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr @@ -0,0 +1,47 @@ +error: `mac` is ambiguous + --> $DIR/ambiguous-glob-vs-expanded-extern.rs:4:23 + | +LL | glob_vs_expanded::mac!(); + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution +note: `mac` could refer to the macro defined here + --> $DIR/auxiliary/glob-vs-expanded.rs:11:1 + | +LL | define_mac!(); + | ^^^^^^^^^^^^^ +note: `mac` could also refer to the macro defined here + --> $DIR/auxiliary/glob-vs-expanded.rs:5:9 + | +LL | pub use inner::*; + | ^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: this error originates in the macro `define_mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +Future incompatibility report: Future breakage diagnostic: +error: `mac` is ambiguous + --> $DIR/ambiguous-glob-vs-expanded-extern.rs:4:23 + | +LL | glob_vs_expanded::mac!(); + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution +note: `mac` could refer to the macro defined here + --> $DIR/auxiliary/glob-vs-expanded.rs:11:1 + | +LL | define_mac!(); + | ^^^^^^^^^^^^^ +note: `mac` could also refer to the macro defined here + --> $DIR/auxiliary/glob-vs-expanded.rs:5:9 + | +LL | pub use inner::*; + | ^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: this error originates in the macro `define_mac` (in Nightly builds, run with -Z macro-backtrace for more info) + diff --git a/tests/ui/imports/auxiliary/glob-vs-expanded.rs b/tests/ui/imports/auxiliary/glob-vs-expanded.rs new file mode 100644 index 000000000000..fcbe54f73264 --- /dev/null +++ b/tests/ui/imports/auxiliary/glob-vs-expanded.rs @@ -0,0 +1,11 @@ +#![feature(decl_macro)] + +// Glob import in macro namespace +mod inner { pub macro mac() {} } +pub use inner::*; + +// Macro-expanded single import in macro namespace +macro_rules! define_mac { + () => { pub macro mac() {} } +} +define_mac!(); diff --git a/tests/ui/imports/extern-with-ambiguous-2.rs b/tests/ui/imports/extern-with-ambiguous-2.rs index dcab2bcc18ea..477d29ad0120 100644 --- a/tests/ui/imports/extern-with-ambiguous-2.rs +++ b/tests/ui/imports/extern-with-ambiguous-2.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ edition: 2021 //@ aux-build: extern-with-ambiguous-2-extern.rs @@ -11,8 +10,6 @@ mod s { } use s::*; use extern_with_ambiguous_2_extern::*; -use error::*; -//^ FIXME: An ambiguity error should be thrown for `error`, -// as there is ambiguity present within `extern-with-ambiguous-2-extern.rs`. +use error::*; //~ ERROR `error` is ambiguous fn main() {} diff --git a/tests/ui/imports/extern-with-ambiguous-2.stderr b/tests/ui/imports/extern-with-ambiguous-2.stderr new file mode 100644 index 000000000000..2fd66932e4ed --- /dev/null +++ b/tests/ui/imports/extern-with-ambiguous-2.stderr @@ -0,0 +1,23 @@ +error[E0659]: `error` is ambiguous + --> $DIR/extern-with-ambiguous-2.rs:13:5 + | +LL | use error::*; + | ^^^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `error` could refer to the module imported here + --> $DIR/extern-with-ambiguous-2.rs:11:5 + | +LL | use s::*; + | ^^^^ + = help: consider adding an explicit import of `error` to disambiguate +note: `error` could also refer to the module imported here + --> $DIR/extern-with-ambiguous-2.rs:12:5 + | +LL | use extern_with_ambiguous_2_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `error` to disambiguate + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/extern-with-ambiguous-3.rs b/tests/ui/imports/extern-with-ambiguous-3.rs index c65fedbe2c1d..c0c4741ec56a 100644 --- a/tests/ui/imports/extern-with-ambiguous-3.rs +++ b/tests/ui/imports/extern-with-ambiguous-3.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ edition: 2021 //@ aux-build: extern-with-ambiguous-3-extern.rs // https://github.com/rust-lang/rust/pull/113099#issuecomment-1643974121 @@ -12,8 +11,6 @@ mod s { } use s::*; use extern_with_ambiguous_3_extern::*; -use error::*; -//^ FIXME: An ambiguity error should be thrown for `error`, -// as there is ambiguity present within `extern-with-ambiguous-3-extern.rs`. +use error::*; //~ ERROR `error` is ambiguous fn main() {} diff --git a/tests/ui/imports/extern-with-ambiguous-3.stderr b/tests/ui/imports/extern-with-ambiguous-3.stderr new file mode 100644 index 000000000000..95a1175c56b3 --- /dev/null +++ b/tests/ui/imports/extern-with-ambiguous-3.stderr @@ -0,0 +1,23 @@ +error[E0659]: `error` is ambiguous + --> $DIR/extern-with-ambiguous-3.rs:14:5 + | +LL | use error::*; + | ^^^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `error` could refer to the module imported here + --> $DIR/extern-with-ambiguous-3.rs:12:5 + | +LL | use s::*; + | ^^^^ + = help: consider adding an explicit import of `error` to disambiguate +note: `error` could also refer to the module imported here + --> $DIR/extern-with-ambiguous-3.rs:13:5 + | +LL | use extern_with_ambiguous_3_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `error` to disambiguate + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.rs b/tests/ui/imports/glob-conflict-cross-crate-1.rs index 6e3200329616..08ce6166b5c1 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-1.rs @@ -4,10 +4,8 @@ extern crate glob_conflict; fn main() { - glob_conflict::f(); //~ ERROR cannot find function `f` in crate `glob_conflict` - //^ FIXME: `glob_conflict::f` should raise an - // ambiguity error instead of a not found error. - glob_conflict::glob::f(); //~ ERROR cannot find function `f` in module `glob_conflict::glob` - //^ FIXME: `glob_conflict::glob::f` should raise an - // ambiguity error instead of a not found error. + glob_conflict::f(); //~ ERROR `f` is ambiguous + //~| WARN this was previously accepted + glob_conflict::glob::f(); //~ ERROR `f` is ambiguous + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr index cf40076ecb86..54b7976b057e 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -1,15 +1,87 @@ -error[E0425]: cannot find function `f` in crate `glob_conflict` +error: `f` is ambiguous --> $DIR/glob-conflict-cross-crate-1.rs:7:20 | LL | glob_conflict::f(); - | ^ not found in `glob_conflict` + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:12:9 + | +LL | pub use m1::*; + | ^^ +note: `f` could also refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:13:9 + | +LL | pub use m2::*; + | ^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default -error[E0425]: cannot find function `f` in module `glob_conflict::glob` - --> $DIR/glob-conflict-cross-crate-1.rs:10:26 +error: `f` is ambiguous + --> $DIR/glob-conflict-cross-crate-1.rs:9:26 | LL | glob_conflict::glob::f(); - | ^ not found in `glob_conflict::glob` + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:12:9 + | +LL | pub use m1::*; + | ^^ +note: `f` could also refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:13:9 + | +LL | pub use m2::*; + | ^^ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0425`. +Future incompatibility report: Future breakage diagnostic: +error: `f` is ambiguous + --> $DIR/glob-conflict-cross-crate-1.rs:7:20 + | +LL | glob_conflict::f(); + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:12:9 + | +LL | pub use m1::*; + | ^^ +note: `f` could also refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:13:9 + | +LL | pub use m2::*; + | ^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +Future breakage diagnostic: +error: `f` is ambiguous + --> $DIR/glob-conflict-cross-crate-1.rs:9:26 + | +LL | glob_conflict::glob::f(); + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:12:9 + | +LL | pub use m1::*; + | ^^ +note: `f` could also refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:13:9 + | +LL | pub use m2::*; + | ^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.rs b/tests/ui/imports/glob-conflict-cross-crate-2.rs index b764685dd579..b4dd3d8eeb44 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-2.rs @@ -5,6 +5,6 @@ extern crate glob_conflict_cross_crate_2_extern; use glob_conflict_cross_crate_2_extern::*; fn main() { - let _a: C = 1; //~ ERROR cannot find type `C` in this scope - //^ FIXME: `C` should be identified as an ambiguous item. + let _a: C = 1; //~ ERROR `C` is ambiguous + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.stderr b/tests/ui/imports/glob-conflict-cross-crate-2.stderr index 41912ed63f42..cbc2180c14f4 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-2.stderr @@ -1,9 +1,45 @@ -error[E0425]: cannot find type `C` in this scope +error: `C` is ambiguous --> $DIR/glob-conflict-cross-crate-2.rs:8:13 | LL | let _a: C = 1; - | ^ not found in this scope + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:9:9 + | +LL | pub use a::*; + | ^ +note: `C` could also refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0425`. +Future incompatibility report: Future breakage diagnostic: +error: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-2.rs:8:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:9:9 + | +LL | pub use a::*; + | ^ +note: `C` could also refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/glob-conflict-cross-crate-3.rs b/tests/ui/imports/glob-conflict-cross-crate-3.rs index 7797b5b7c069..31c234b9250f 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-3.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-3.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ aux-build:glob-conflict-cross-crate-2-extern.rs extern crate glob_conflict_cross_crate_2_extern; @@ -12,5 +11,8 @@ use a::*; fn main() { let _a: C = 1; - //^ FIXME: `C` should be identified as an ambiguous item. + //~^ ERROR `C` is ambiguous + //~| ERROR `C` is ambiguous + //~| WARN this was previously accepted + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/glob-conflict-cross-crate-3.stderr b/tests/ui/imports/glob-conflict-cross-crate-3.stderr new file mode 100644 index 000000000000..213eafda20b7 --- /dev/null +++ b/tests/ui/imports/glob-conflict-cross-crate-3.stderr @@ -0,0 +1,91 @@ +error: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-3.rs:13:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:9:9 + | +LL | pub use a::*; + | ^ +note: `C` could also refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +error: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-3.rs:13:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:9:5 + | +LL | use glob_conflict_cross_crate_2_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `C` to disambiguate +note: `C` could also refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:10:5 + | +LL | use a::*; + | ^^^^ + = help: consider adding an explicit import of `C` to disambiguate + +error: aborting due to 2 previous errors + +Future incompatibility report: Future breakage diagnostic: +error: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-3.rs:13:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:9:9 + | +LL | pub use a::*; + | ^ +note: `C` could also refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +Future breakage diagnostic: +error: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-3.rs:13:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:9:5 + | +LL | use glob_conflict_cross_crate_2_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `C` to disambiguate +note: `C` could also refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:10:5 + | +LL | use a::*; + | ^^^^ + = help: consider adding an explicit import of `C` to disambiguate + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/issue-114682-2.rs b/tests/ui/imports/issue-114682-2.rs index e99bcf77ab62..a9459c5b02ef 100644 --- a/tests/ui/imports/issue-114682-2.rs +++ b/tests/ui/imports/issue-114682-2.rs @@ -3,17 +3,10 @@ extern crate issue_114682_2_extern; -use issue_114682_2_extern::max; +use issue_114682_2_extern::max; //~ ERROR `max` is ambiguous + //~| WARN this was previously accepted -type A = issue_114682_2_extern::max; -//~^ ERROR: expected type, found function `issue_114682_2_extern::max` -// FIXME: -// The above error was emitted due to `(Mod(issue_114682_2_extern), Namespace(Type), Ident(max))` -// being identified as an ambiguous item. -// However, there are two points worth discussing: -// First, should this ambiguous item be omitted considering the maximum visibility -// of `issue_114682_2_extern::m::max` in the type namespace is only within the extern crate. -// Second, if we retain the ambiguous item of the extern crate, should it be treated -// as an ambiguous item within the local crate for the same reasoning? +type A = issue_114682_2_extern::max; //~ ERROR `max` is ambiguous + //~| WARN this was previously accepted fn main() {} diff --git a/tests/ui/imports/issue-114682-2.stderr b/tests/ui/imports/issue-114682-2.stderr index 972bcecb56bc..07c696651c38 100644 --- a/tests/ui/imports/issue-114682-2.stderr +++ b/tests/ui/imports/issue-114682-2.stderr @@ -1,9 +1,87 @@ -error[E0573]: expected type, found function `issue_114682_2_extern::max` - --> $DIR/issue-114682-2.rs:8:10 +error: `max` is ambiguous + --> $DIR/issue-114682-2.rs:6:28 + | +LL | use issue_114682_2_extern::max; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `max` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:17:9 + | +LL | pub use self::e::*; + | ^^^^^^^ +note: `max` could also refer to the module defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 + | +LL | pub use self::d::*; + | ^^^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +error: `max` is ambiguous + --> $DIR/issue-114682-2.rs:9:33 | LL | type A = issue_114682_2_extern::max; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `max` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:17:9 + | +LL | pub use self::e::*; + | ^^^^^^^ +note: `max` could also refer to the module defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 + | +LL | pub use self::d::*; + | ^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors + +Future incompatibility report: Future breakage diagnostic: +error: `max` is ambiguous + --> $DIR/issue-114682-2.rs:6:28 + | +LL | use issue_114682_2_extern::max; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `max` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:17:9 + | +LL | pub use self::e::*; + | ^^^^^^^ +note: `max` could also refer to the module defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 + | +LL | pub use self::d::*; + | ^^^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +Future breakage diagnostic: +error: `max` is ambiguous + --> $DIR/issue-114682-2.rs:9:33 + | +LL | type A = issue_114682_2_extern::max; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `max` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:17:9 + | +LL | pub use self::e::*; + | ^^^^^^^ +note: `max` could also refer to the module defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 + | +LL | pub use self::d::*; + | ^^^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default -For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/imports/issue-114682-3.rs b/tests/ui/imports/issue-114682-3.rs index 6dc4df17a2da..ac603b49e321 100644 --- a/tests/ui/imports/issue-114682-3.rs +++ b/tests/ui/imports/issue-114682-3.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ aux-build: issue-114682-3-extern.rs // https://github.com/rust-lang/rust/pull/114682#issuecomment-1880625909 @@ -19,6 +18,5 @@ pub use self::auto::*; fn main() { let a: u8 = 1; a.ext(); - //^ FIXME: it should report `ext` not found because `SettingsExt` - // is an ambiguous item in `issue-114682-3-extern.rs`. + //~^ ERROR no method named `ext` found for type `u8` in the current scope } diff --git a/tests/ui/imports/issue-114682-3.stderr b/tests/ui/imports/issue-114682-3.stderr new file mode 100644 index 000000000000..6af7a4e02614 --- /dev/null +++ b/tests/ui/imports/issue-114682-3.stderr @@ -0,0 +1,18 @@ +error[E0599]: no method named `ext` found for type `u8` in the current scope + --> $DIR/issue-114682-3.rs:20:7 + | +LL | fn ext(&self) {} + | --- the method is available for `u8` here +... +LL | a.ext(); + | ^^^ method not found in `u8` + | + = help: items from traits can only be used if the trait is in scope +help: trait `SettingsExt` which provides `ext` is implemented but not in scope; perhaps you want to import it + | +LL + use auto::SettingsExt; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/imports/issue-114682-4.rs b/tests/ui/imports/issue-114682-4.rs index 32c2ca7b2609..01921928a007 100644 --- a/tests/ui/imports/issue-114682-4.rs +++ b/tests/ui/imports/issue-114682-4.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ aux-build: issue-114682-4-extern.rs // https://github.com/rust-lang/rust/pull/114682#issuecomment-1880755441 @@ -6,7 +5,9 @@ extern crate issue_114682_4_extern; use issue_114682_4_extern::*; -fn a() -> Result { // FIXME: `Result` should be identified as an ambiguous item. +//~v ERROR type alias takes 1 generic argument but 2 generic arguments were supplied +fn a() -> Result { //~ ERROR `Result` is ambiguous + //~| WARN this was previously accepted Ok(1) } diff --git a/tests/ui/imports/issue-114682-4.stderr b/tests/ui/imports/issue-114682-4.stderr new file mode 100644 index 000000000000..5e677cd7ae72 --- /dev/null +++ b/tests/ui/imports/issue-114682-4.stderr @@ -0,0 +1,60 @@ +error: `Result` is ambiguous + --> $DIR/issue-114682-4.rs:9:11 + | +LL | fn a() -> Result { + | ^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `Result` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-4-extern.rs:9:9 + | +LL | pub use a::*; + | ^ +note: `Result` could also refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-4-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +error[E0107]: type alias takes 1 generic argument but 2 generic arguments were supplied + --> $DIR/issue-114682-4.rs:9:11 + | +LL | fn a() -> Result { + | ^^^^^^ ---- help: remove the unnecessary generic argument + | | + | expected 1 generic argument + | +note: type alias defined here, with 1 generic parameter: `T` + --> $DIR/auxiliary/issue-114682-4-extern.rs:2:14 + | +LL | pub type Result = std::result::Result; + | ^^^^^^ - + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. +Future incompatibility report: Future breakage diagnostic: +error: `Result` is ambiguous + --> $DIR/issue-114682-4.rs:9:11 + | +LL | fn a() -> Result { + | ^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `Result` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-4-extern.rs:9:9 + | +LL | pub use a::*; + | ^ +note: `Result` could also refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-4-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/issue-114682-5.rs b/tests/ui/imports/issue-114682-5.rs index 7c6132ebd6ff..be33960e40b8 100644 --- a/tests/ui/imports/issue-114682-5.rs +++ b/tests/ui/imports/issue-114682-5.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ edition: 2018 //@ aux-build: issue-114682-5-extern-1.rs //@ aux-build: issue-114682-5-extern-2.rs @@ -9,7 +8,9 @@ extern crate issue_114682_5_extern_2; use issue_114682_5_extern_2::p::*; use issue_114682_5_extern_1::Url; -// FIXME: The `issue_114682_5_extern_1` should be considered an ambiguous item, -// as it has already been recognized as ambiguous in `issue_114682_5_extern_2`. +//~^ ERROR `issue_114682_5_extern_1` is ambiguous +//~| ERROR `issue_114682_5_extern_1` is ambiguous +//~| ERROR unresolved import `issue_114682_5_extern_1::Url` +//~| WARN this was previously accepted fn main() {} diff --git a/tests/ui/imports/issue-114682-5.stderr b/tests/ui/imports/issue-114682-5.stderr new file mode 100644 index 000000000000..427a5b16765b --- /dev/null +++ b/tests/ui/imports/issue-114682-5.stderr @@ -0,0 +1,77 @@ +error[E0432]: unresolved import `issue_114682_5_extern_1::Url` + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Url` in `types::issue_114682_5_extern_1` + | +help: consider importing this struct instead + | +LL | use ::issue_114682_5_extern_1::Url; + | ++ + +error[E0659]: `issue_114682_5_extern_1` is ambiguous + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution + = note: `issue_114682_5_extern_1` could refer to a crate passed with `--extern` + = help: use `::issue_114682_5_extern_1` to refer to this crate unambiguously +note: `issue_114682_5_extern_1` could also refer to the module imported here + --> $DIR/issue-114682-5.rs:9:5 + | +LL | use issue_114682_5_extern_2::p::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `issue_114682_5_extern_1` to disambiguate + = help: or use `crate::issue_114682_5_extern_1` to refer to this module unambiguously + +error: `issue_114682_5_extern_1` is ambiguous + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `issue_114682_5_extern_1` could refer to the module defined here + --> $DIR/auxiliary/issue-114682-5-extern-2.rs:6:13 + | +LL | pub use crate::types::*; + | ^^^^^^^^^^^^ +note: `issue_114682_5_extern_1` could also refer to the crate defined here + --> $DIR/auxiliary/issue-114682-5-extern-2.rs:7:13 + | +LL | pub use crate::*; + | ^^^^^ + = help: use `::issue_114682_5_extern_1` to refer to this crate unambiguously + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0432, E0659. +For more information about an error, try `rustc --explain E0432`. +Future incompatibility report: Future breakage diagnostic: +error: `issue_114682_5_extern_1` is ambiguous + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `issue_114682_5_extern_1` could refer to the module defined here + --> $DIR/auxiliary/issue-114682-5-extern-2.rs:6:13 + | +LL | pub use crate::types::*; + | ^^^^^^^^^^^^ +note: `issue_114682_5_extern_1` could also refer to the crate defined here + --> $DIR/auxiliary/issue-114682-5-extern-2.rs:7:13 + | +LL | pub use crate::*; + | ^^^^^ + = help: use `::issue_114682_5_extern_1` to refer to this crate unambiguously + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/issue-114682-6.rs b/tests/ui/imports/issue-114682-6.rs index d47b9f8a4e85..92173f4b8464 100644 --- a/tests/ui/imports/issue-114682-6.rs +++ b/tests/ui/imports/issue-114682-6.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ aux-build: issue-114682-6-extern.rs // https://github.com/rust-lang/rust/pull/114682#issuecomment-1880755441 @@ -7,7 +6,7 @@ extern crate issue_114682_6_extern; use issue_114682_6_extern::*; fn main() { - let log = 2; - //^ `log` should be identified as an ambiguous item. + let log = 2; //~ ERROR `log` is ambiguous + //~| WARN this was previously accepted let _ = log; } diff --git a/tests/ui/imports/issue-114682-6.stderr b/tests/ui/imports/issue-114682-6.stderr new file mode 100644 index 000000000000..67ad25798c19 --- /dev/null +++ b/tests/ui/imports/issue-114682-6.stderr @@ -0,0 +1,45 @@ +error: `log` is ambiguous + --> $DIR/issue-114682-6.rs:9:9 + | +LL | let log = 2; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `log` could refer to the function defined here + --> $DIR/auxiliary/issue-114682-6-extern.rs:8:9 + | +LL | pub use self::a::*; + | ^^^^^^^ +note: `log` could also refer to the function defined here + --> $DIR/auxiliary/issue-114682-6-extern.rs:9:9 + | +LL | pub use self::b::*; + | ^^^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +error: aborting due to 1 previous error + +Future incompatibility report: Future breakage diagnostic: +error: `log` is ambiguous + --> $DIR/issue-114682-6.rs:9:9 + | +LL | let log = 2; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `log` could refer to the function defined here + --> $DIR/auxiliary/issue-114682-6-extern.rs:8:9 + | +LL | pub use self::a::*; + | ^^^^^^^ +note: `log` could also refer to the function defined here + --> $DIR/auxiliary/issue-114682-6-extern.rs:9:9 + | +LL | pub use self::b::*; + | ^^^^^^^ + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + From df38e1521d62e9f04ec339badf9de6317c8602a0 Mon Sep 17 00:00:00 2001 From: tison Date: Tue, 9 Dec 2025 20:38:47 +0800 Subject: [PATCH 0461/3801] Add const default for OnceCell and OnceLock Signed-off-by: tison --- library/core/src/cell/once.rs | 3 ++- library/std/src/lib.rs | 1 + library/std/src/sync/once_lock.rs | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 6c71e2216a71..af4469fad2cc 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -353,7 +353,8 @@ impl OnceCell { } #[stable(feature = "once_cell", since = "1.70.0")] -impl Default for OnceCell { +#[rustc_const_unstable(feature = "const_default", issue = "143894")] +impl const Default for OnceCell { #[inline] fn default() -> Self { Self::new() diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 0401e9b39ff4..65ea85f36d93 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -274,6 +274,7 @@ #![feature(cfg_sanitizer_cfi)] #![feature(cfg_target_thread_local)] #![feature(cfi_encoding)] +#![feature(const_default)] #![feature(const_trait_impl)] #![feature(core_float_math)] #![feature(decl_macro)] diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index d1bbe0ff843c..b9a7077e420e 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -582,7 +582,8 @@ impl RefUnwindSafe for OnceLock {} impl UnwindSafe for OnceLock {} #[stable(feature = "once_cell", since = "1.70.0")] -impl Default for OnceLock { +#[rustc_const_unstable(feature = "const_default", issue = "143894")] +impl const Default for OnceLock { /// Creates a new uninitialized cell. /// /// # Example From 2a2da782d32f25d69b66880b5dca640e2be8fe3e Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Thu, 4 Dec 2025 21:53:11 +0000 Subject: [PATCH 0462/3801] add check for uninhabited types along side never --- compiler/rustc_mir_build/src/builder/mod.rs | 21 ++++++++++++++++++- .../uninhabited-unreachable-warning-149571.rs | 10 +++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/ui/uninhabited/uninhabited-unreachable-warning-149571.rs diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 206eb9126f54..14a24265a8f4 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -839,6 +839,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.infcx.typing_env(self.param_env), ); + // check if the function's return type is inhabited + // this was added here because of this regression + // https://github.com/rust-lang/rust/issues/149571 + let output_is_inhabited = + if matches!(self.tcx.def_kind(self.def_id), DefKind::Fn | DefKind::AssocFn) { + self.tcx + .fn_sig(self.def_id) + .instantiate_identity() + .skip_binder() + .output() + .is_inhabited_from( + self.tcx, + self.parent_module, + self.infcx.typing_env(self.param_env), + ) + } else { + true + }; + if !ty_is_inhabited { // Unreachable code warnings are already emitted during type checking. // However, during type checking, full type information is being @@ -849,7 +868,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // uninhabited types (e.g. empty enums). The check above is used so // that we do not emit the same warning twice if the uninhabited type // is indeed `!`. - if !ty.is_never() { + if !ty.is_never() && output_is_inhabited { lints.push((target_bb, ty, term.source_info.span)); } diff --git a/tests/ui/uninhabited/uninhabited-unreachable-warning-149571.rs b/tests/ui/uninhabited/uninhabited-unreachable-warning-149571.rs new file mode 100644 index 000000000000..a389562d649e --- /dev/null +++ b/tests/ui/uninhabited/uninhabited-unreachable-warning-149571.rs @@ -0,0 +1,10 @@ +#![deny(unreachable_code)] +//@ run-pass + +use std::convert::Infallible; + +pub fn foo(f: impl FnOnce() -> Infallible) -> Infallible { + f() +} + +fn main() {} From 6159c1971fba705963377f1a90824f0269fa8682 Mon Sep 17 00:00:00 2001 From: irelaxcn Date: Tue, 9 Dec 2025 21:37:53 +0800 Subject: [PATCH 0463/3801] Fix `if_then_some_else_none` FP when the `then` block contains `.await` --- clippy_lints/src/if_then_some_else_none.rs | 16 ++++++++++++---- tests/ui/if_then_some_else_none.fixed | 10 ++++++++++ tests/ui/if_then_some_else_none.rs | 10 ++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs index 7f3ef58c93d1..314c8e1dd54c 100644 --- a/clippy_lints/src/if_then_some_else_none.rs +++ b/clippy_lints/src/if_then_some_else_none.rs @@ -4,10 +4,12 @@ use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context}; use clippy_utils::sugg::Sugg; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{ - as_some_expr, contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, - is_none_expr, peel_blocks, sym, + as_some_expr, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, is_none_expr, + peel_blocks, sym, }; +use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -76,8 +78,14 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { && !is_else_clause(cx.tcx, expr) && !is_in_const_context(cx) && self.msrv.meets(cx, msrvs::BOOL_THEN) - && !contains_return(then_block.stmts) - && then_block.expr.is_none_or(|expr| !contains_return(expr)) + && for_each_expr_without_closures(then_block, |e| { + if matches!(e.kind, ExprKind::Ret(..) | ExprKind::Yield(..)) { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + }) + .is_none() { let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) { sym::then_some diff --git a/tests/ui/if_then_some_else_none.fixed b/tests/ui/if_then_some_else_none.fixed index 7da9401a308f..9d4cbe6baf07 100644 --- a/tests/ui/if_then_some_else_none.fixed +++ b/tests/ui/if_then_some_else_none.fixed @@ -218,3 +218,13 @@ mod issue15770 { Ok(()) } } + +mod issue16176 { + pub async fn foo() -> u32 { + todo!() + } + + pub async fn bar(cond: bool) -> Option { + if cond { Some(foo().await) } else { None } // OK + } +} diff --git a/tests/ui/if_then_some_else_none.rs b/tests/ui/if_then_some_else_none.rs index 02962f83ce8a..6b1ece61e775 100644 --- a/tests/ui/if_then_some_else_none.rs +++ b/tests/ui/if_then_some_else_none.rs @@ -274,3 +274,13 @@ mod issue15770 { Ok(()) } } + +mod issue16176 { + pub async fn foo() -> u32 { + todo!() + } + + pub async fn bar(cond: bool) -> Option { + if cond { Some(foo().await) } else { None } // OK + } +} From 1986be2bcdddf0cd53cf9cb6a4ac59dc66bb86ae Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Fri, 28 Nov 2025 10:10:07 +0000 Subject: [PATCH 0464/3801] Moved `struct Placeholder` --- .../src/diagnostics/bound_region_errors.rs | 39 +++++----- .../src/diagnostics/region_errors.rs | 8 +- .../rustc_borrowck/src/handle_placeholders.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 4 +- .../rustc_borrowck/src/region_infer/mod.rs | 14 ++-- .../region_infer/opaque_types/region_ctxt.rs | 2 +- .../rustc_borrowck/src/region_infer/values.rs | 77 +++++++++++-------- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +- .../src/type_check/relate_tys.rs | 7 +- .../rustc_borrowck/src/universal_regions.rs | 49 ++++++++---- .../src/check/compare_impl_item.rs | 6 +- .../src/infer/canonical/canonicalizer.rs | 24 +++--- .../rustc_infer/src/infer/canonical/mod.rs | 16 ++-- .../src/infer/lexical_region_resolve/mod.rs | 8 +- compiler/rustc_infer/src/infer/mod.rs | 22 +++--- .../src/infer/outlives/obligations.rs | 2 +- .../infer/region_constraints/leak_check.rs | 8 +- .../src/infer/region_constraints/mod.rs | 20 ++--- .../src/infer/relate/higher_ranked.rs | 12 +-- .../rustc_infer/src/infer/snapshot/fudge.rs | 12 +-- compiler/rustc_middle/src/ty/consts.rs | 7 +- compiler/rustc_middle/src/ty/context.rs | 6 +- compiler/rustc_middle/src/ty/mod.rs | 41 ++++------ compiler/rustc_middle/src/ty/print/pretty.rs | 20 ++--- compiler/rustc_middle/src/ty/region.rs | 7 +- .../rustc_middle/src/ty/structural_impls.rs | 12 +-- compiler/rustc_middle/src/ty/sty.rs | 5 +- .../src/error_reporting/infer/region.rs | 4 +- .../src/traits/coherence.rs | 27 +++---- .../rustc_trait_selection/src/traits/mod.rs | 13 ++-- .../rustc_trait_selection/src/traits/util.rs | 12 +-- compiler/rustc_type_ir/src/binder.rs | 55 ++++++++++++- compiler/rustc_type_ir/src/ir_print.rs | 30 +++++--- compiler/rustc_type_ir/src/lib.rs | 2 +- 34 files changed, 326 insertions(+), 251 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 15b2a5ef2e21..254d28d243ff 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -52,8 +52,8 @@ impl<'tcx> UniverseInfo<'tcx> { pub(crate) fn report_erroneous_element( &self, mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, - placeholder: ty::PlaceholderRegion, - error_element: RegionElement, + placeholder: ty::PlaceholderRegion<'tcx>, + error_element: RegionElement<'tcx>, cause: ObligationCause<'tcx>, ) { match *self { @@ -152,8 +152,8 @@ pub(crate) trait TypeOpInfo<'tcx> { fn report_erroneous_element( &self, mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>, - placeholder: ty::PlaceholderRegion, - error_element: RegionElement, + placeholder: ty::PlaceholderRegion<'tcx>, + error_element: RegionElement<'tcx>, cause: ObligationCause<'tcx>, ) { let tcx = mbcx.infcx.tcx; @@ -169,23 +169,22 @@ pub(crate) trait TypeOpInfo<'tcx> { let placeholder_region = ty::Region::new_placeholder( tcx, - ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound }, + ty::Placeholder::new(adjusted_universe.into(), placeholder.bound), ); - let error_region = if let RegionElement::PlaceholderRegion(error_placeholder) = - error_element - { - let adjusted_universe = - error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32()); - adjusted_universe.map(|adjusted| { - ty::Region::new_placeholder( - tcx, - ty::Placeholder { universe: adjusted.into(), bound: error_placeholder.bound }, - ) - }) - } else { - None - }; + let error_region = + if let RegionElement::PlaceholderRegion(error_placeholder) = error_element { + let adjusted_universe = + error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32()); + adjusted_universe.map(|adjusted| { + ty::Region::new_placeholder( + tcx, + ty::Placeholder::new(adjusted.into(), error_placeholder.bound), + ) + }) + } else { + None + }; debug!(?placeholder_region); @@ -440,7 +439,7 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>( placeholder_region: ty::Region<'tcx>, error_region: Option>, region_constraints: &RegionConstraintData<'tcx>, - mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin, + mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin<'tcx>, mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex, ) -> Option> { let placeholder_universe = match placeholder_region.kind() { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 05826bea66bf..408e0f7e03f6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -109,15 +109,15 @@ pub(crate) enum RegionErrorKind<'tcx> { /// The placeholder free region. longer_fr: RegionVid, /// The region element that erroneously must be outlived by `longer_fr`. - error_element: RegionElement, + error_element: RegionElement<'tcx>, /// The placeholder region. - placeholder: ty::PlaceholderRegion, + placeholder: ty::PlaceholderRegion<'tcx>, }, /// Any other lifetime error. RegionError { /// The origin of the region. - fr_origin: NllRegionVariableOrigin, + fr_origin: NllRegionVariableOrigin<'tcx>, /// The region that should outlive `shorter_fr`. longer_fr: RegionVid, /// The region that should be shorter, but we can't prove it. @@ -427,7 +427,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pub(crate) fn report_region_error( &mut self, fr: RegionVid, - fr_origin: NllRegionVariableOrigin, + fr_origin: NllRegionVariableOrigin<'tcx>, outlived_fr: RegionVid, outlives_suggestion: &mut OutlivesSuggestionBuilder, ) { diff --git a/compiler/rustc_borrowck/src/handle_placeholders.rs b/compiler/rustc_borrowck/src/handle_placeholders.rs index d23ecf6c7079..60be521c29af 100644 --- a/compiler/rustc_borrowck/src/handle_placeholders.rs +++ b/compiler/rustc_borrowck/src/handle_placeholders.rs @@ -32,7 +32,7 @@ pub(crate) struct LoweredConstraints<'tcx> { pub(crate) type_tests: Vec>, pub(crate) liveness_constraints: LivenessValues, pub(crate) universe_causes: FxIndexMap>, - pub(crate) placeholder_indices: PlaceholderIndices, + pub(crate) placeholder_indices: PlaceholderIndices<'tcx>, } impl<'d, 'tcx, A: scc::Annotation> SccAnnotations<'d, 'tcx, A> { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 20411fcc16fb..8d61ffde116c 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -661,7 +661,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> { pub(crate) fn next_region_var( &self, - origin: RegionVariableOrigin, + origin: RegionVariableOrigin<'tcx>, get_ctxt_fn: F, ) -> ty::Region<'tcx> where @@ -683,7 +683,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> { #[instrument(skip(self, get_ctxt_fn), level = "debug")] pub(crate) fn next_nll_region_var( &self, - origin: NllRegionVariableOrigin, + origin: NllRegionVariableOrigin<'tcx>, get_ctxt_fn: F, ) -> ty::Region<'tcx> where diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index e98c60e63380..847e1ebe56fb 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -110,7 +110,7 @@ pub struct RegionInferenceContext<'tcx> { /// The final inferred values of the region variables; we compute /// one value per SCC. To get the value for any given *region*, /// you first find which scc it is a part of. - scc_values: RegionValues, + scc_values: RegionValues<'tcx, ConstraintSccIndex>, /// Type constraints that we check after solving. type_tests: Vec>, @@ -125,7 +125,7 @@ pub(crate) struct RegionDefinition<'tcx> { /// What kind of variable is this -- a free region? existential /// variable? etc. (See the `NllRegionVariableOrigin` for more /// info.) - pub(crate) origin: NllRegionVariableOrigin, + pub(crate) origin: NllRegionVariableOrigin<'tcx>, /// Which universe is this region variable defined in? This is /// most often `ty::UniverseIndex::ROOT`, but when we encounter @@ -453,7 +453,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Returns `true` if the region `r` contains the point `p`. /// /// Panics if called before `solve()` executes, - pub(crate) fn region_contains(&self, r: RegionVid, p: impl ToElementIndex) -> bool { + pub(crate) fn region_contains(&self, r: RegionVid, p: impl ToElementIndex<'tcx>) -> bool { let scc = self.constraint_sccs.scc(r); self.scc_values.contains(scc, p) } @@ -481,7 +481,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn placeholders_contained_in( &self, r: RegionVid, - ) -> impl Iterator { + ) -> impl Iterator> { let scc = self.constraint_sccs.scc(r); self.scc_values.placeholders_contained_in(scc) } @@ -1311,7 +1311,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn check_bound_universal_region( &self, longer_fr: RegionVid, - placeholder: ty::PlaceholderRegion, + placeholder: ty::PlaceholderRegion<'tcx>, errors_buffer: &mut RegionErrors<'tcx>, ) { debug!("check_bound_universal_region(fr={:?}, placeholder={:?})", longer_fr, placeholder,); @@ -1523,7 +1523,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn region_from_element( &self, longer_fr: RegionVid, - element: &RegionElement, + element: &RegionElement<'tcx>, ) -> RegionVid { match *element { RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), @@ -1564,7 +1564,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn best_blame_constraint( &self, from_region: RegionVid, - from_region_origin: NllRegionVariableOrigin, + from_region_origin: NllRegionVariableOrigin<'tcx>, to_region: RegionVid, ) -> (BlameConstraint<'tcx>, Vec>) { assert!(from_region != to_region, "Trying to blame a region for itself!"); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs index 90b15cbdd2cc..ada8908e220a 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs @@ -27,7 +27,7 @@ pub(super) struct RegionCtxt<'a, 'tcx> { pub(super) constraint_sccs: ConstraintSccs, pub(super) scc_annotations: IndexVec, pub(super) rev_scc_graph: ReverseSccGraph, - pub(super) scc_values: RegionValues, + pub(super) scc_values: RegionValues<'tcx, ConstraintSccIndex>, } impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index eb611fa34757..0063af25d781 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -10,8 +10,8 @@ use rustc_middle::ty::{self, RegionVid}; use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex}; use tracing::debug; -use crate::BorrowIndex; use crate::polonius::LiveLoans; +use crate::{BorrowIndex, TyCtxt}; rustc_index::newtype_index! { /// A single integer representing a `ty::Placeholder`. @@ -22,7 +22,7 @@ rustc_index::newtype_index! { /// An individual element in a region value -- the value of a /// particular region variable consists of a set of these elements. #[derive(Debug, Clone, PartialEq)] -pub(crate) enum RegionElement { +pub(crate) enum RegionElement<'tcx> { /// A point in the control-flow graph. Location(Location), @@ -32,7 +32,7 @@ pub(crate) enum RegionElement { /// A placeholder (e.g., instantiated from a `for<'a> fn(&'a u32)` /// type). - PlaceholderRegion(ty::PlaceholderRegion), + PlaceholderRegion(ty::PlaceholderRegion<'tcx>), } /// Records the CFG locations where each region is live. When we initially compute liveness, we use @@ -196,25 +196,28 @@ impl LivenessValues { /// NLL. #[derive(Debug, Default)] #[derive(Clone)] // FIXME(#146079) -pub(crate) struct PlaceholderIndices { - indices: FxIndexSet, +pub(crate) struct PlaceholderIndices<'tcx> { + indices: FxIndexSet>, } -impl PlaceholderIndices { +impl<'tcx> PlaceholderIndices<'tcx> { /// Returns the `PlaceholderIndex` for the inserted `PlaceholderRegion` - pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { + pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion<'tcx>) -> PlaceholderIndex { let (index, _) = self.indices.insert_full(placeholder); index.into() } - pub(crate) fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { + pub(crate) fn lookup_index( + &self, + placeholder: ty::PlaceholderRegion<'tcx>, + ) -> PlaceholderIndex { self.indices.get_index_of(&placeholder).unwrap().into() } pub(crate) fn lookup_placeholder( &self, placeholder: PlaceholderIndex, - ) -> ty::PlaceholderRegion { + ) -> ty::PlaceholderRegion<'tcx> { self.indices[placeholder.index()] } @@ -241,9 +244,9 @@ impl PlaceholderIndices { /// Here, the variable `'0` would contain the free region `'a`, /// because (since it is returned) it must live for at least `'a`. But /// it would also contain various points from within the function. -pub(crate) struct RegionValues { +pub(crate) struct RegionValues<'tcx, N: Idx> { location_map: Rc, - placeholder_indices: PlaceholderIndices, + placeholder_indices: PlaceholderIndices<'tcx>, points: SparseIntervalMatrix, free_regions: SparseBitMatrix, @@ -252,14 +255,14 @@ pub(crate) struct RegionValues { placeholders: SparseBitMatrix, } -impl RegionValues { +impl<'tcx, N: Idx> RegionValues<'tcx, N> { /// Creates a new set of "region values" that tracks causal information. /// Each of the regions in num_region_variables will be initialized with an /// empty set of points and no causal information. pub(crate) fn new( location_map: Rc, num_universal_regions: usize, - placeholder_indices: PlaceholderIndices, + placeholder_indices: PlaceholderIndices<'tcx>, ) -> Self { let num_points = location_map.num_points(); let num_placeholders = placeholder_indices.len(); @@ -274,7 +277,7 @@ impl RegionValues { /// Adds the given element to the value for the given region. Returns whether /// the element is newly added (i.e., was not already present). - pub(crate) fn add_element(&mut self, r: N, elem: impl ToElementIndex) -> bool { + pub(crate) fn add_element(&mut self, r: N, elem: impl ToElementIndex<'tcx>) -> bool { debug!("add(r={:?}, elem={:?})", r, elem); elem.add_to_row(self, r) } @@ -293,7 +296,7 @@ impl RegionValues { } /// Returns `true` if the region `r` contains the given element. - pub(crate) fn contains(&self, r: N, elem: impl ToElementIndex) -> bool { + pub(crate) fn contains(&self, r: N, elem: impl ToElementIndex<'tcx>) -> bool { elem.contained_in_row(self, r) } @@ -359,7 +362,7 @@ impl RegionValues { pub(crate) fn placeholders_contained_in( &self, r: N, - ) -> impl Iterator { + ) -> impl Iterator> { self.placeholders .row(r) .into_iter() @@ -368,7 +371,7 @@ impl RegionValues { } /// Returns all the elements contained in a given region's value. - pub(crate) fn elements_contained_in(&self, r: N) -> impl Iterator { + pub(crate) fn elements_contained_in(&self, r: N) -> impl Iterator> { let points_iter = self.locations_outlived_by(r).map(RegionElement::Location); let free_regions_iter = @@ -386,42 +389,50 @@ impl RegionValues { } } -pub(crate) trait ToElementIndex: Debug + Copy { - fn add_to_row(self, values: &mut RegionValues, row: N) -> bool; +pub(crate) trait ToElementIndex<'tcx>: Debug + Copy { + fn add_to_row(self, values: &mut RegionValues<'tcx, N>, row: N) -> bool; - fn contained_in_row(self, values: &RegionValues, row: N) -> bool; + fn contained_in_row(self, values: &RegionValues<'tcx, N>, row: N) -> bool; } -impl ToElementIndex for Location { - fn add_to_row(self, values: &mut RegionValues, row: N) -> bool { +impl ToElementIndex<'_> for Location { + fn add_to_row(self, values: &mut RegionValues<'_, N>, row: N) -> bool { let index = values.location_map.point_from_location(self); values.points.insert(row, index) } - fn contained_in_row(self, values: &RegionValues, row: N) -> bool { + fn contained_in_row(self, values: &RegionValues<'_, N>, row: N) -> bool { let index = values.location_map.point_from_location(self); values.points.contains(row, index) } } -impl ToElementIndex for RegionVid { - fn add_to_row(self, values: &mut RegionValues, row: N) -> bool { +impl ToElementIndex<'_> for RegionVid { + fn add_to_row(self, values: &mut RegionValues<'_, N>, row: N) -> bool { values.free_regions.insert(row, self) } - fn contained_in_row(self, values: &RegionValues, row: N) -> bool { + fn contained_in_row(self, values: &RegionValues<'_, N>, row: N) -> bool { values.free_regions.contains(row, self) } } -impl ToElementIndex for ty::PlaceholderRegion { - fn add_to_row(self, values: &mut RegionValues, row: N) -> bool { - let index = values.placeholder_indices.lookup_index(self); +impl<'tcx> ToElementIndex<'tcx> for ty::PlaceholderRegion<'tcx> { + fn add_to_row(self, values: &mut RegionValues<'tcx, N>, row: N) -> bool + where + Self: Into, ty::BoundRegion>>, + { + let placeholder: ty::Placeholder, ty::BoundRegion> = self.into(); + let index = values.placeholder_indices.lookup_index(placeholder); values.placeholders.insert(row, index) } - fn contained_in_row(self, values: &RegionValues, row: N) -> bool { - let index = values.placeholder_indices.lookup_index(self); + fn contained_in_row(self, values: &RegionValues<'tcx, N>, row: N) -> bool + where + Self: Into, ty::BoundRegion>>, + { + let placeholder: ty::Placeholder, ty::BoundRegion> = self.into(); + let index = values.placeholder_indices.lookup_index(placeholder); values.placeholders.contains(row, index) } } @@ -441,7 +452,9 @@ pub(crate) fn pretty_print_points( } /// For debugging purposes, returns a pretty-printed string of the given region elements. -fn pretty_print_region_elements(elements: impl IntoIterator) -> String { +fn pretty_print_region_elements<'tcx>( + elements: impl IntoIterator>, +) -> String { let mut result = String::new(); result.push('{'); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 43005fca2984..e51f059b8de1 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -258,7 +258,7 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> { /// /// To keep everything in sync, do not insert this set /// directly. Instead, use the `placeholder_region` helper. - pub(crate) placeholder_indices: PlaceholderIndices, + pub(crate) placeholder_indices: PlaceholderIndices<'tcx>, /// Each time we add a placeholder to `placeholder_indices`, we /// also create a corresponding "representative" region vid for @@ -289,7 +289,7 @@ impl<'tcx> MirTypeckRegionConstraints<'tcx> { pub(crate) fn placeholder_region( &mut self, infcx: &InferCtxt<'tcx>, - placeholder: ty::PlaceholderRegion, + placeholder: ty::PlaceholderRegion<'tcx>, ) -> ty::Region<'tcx> { let placeholder_index = self.placeholder_indices.insert(placeholder); match self.placeholder_index_to_region.get(placeholder_index) { diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 539912609baa..045507ceb4b4 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -184,7 +184,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { universe }); - let placeholder = ty::PlaceholderRegion { universe, bound: br }; + let placeholder = ty::PlaceholderRegion::new(universe, br); debug!(?placeholder); let placeholder_reg = self.next_placeholder_region(placeholder); debug!(?placeholder_reg); @@ -257,7 +257,10 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { } #[instrument(skip(self), level = "debug")] - fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> { + fn next_placeholder_region( + &mut self, + placeholder: ty::PlaceholderRegion<'tcx>, + ) -> ty::Region<'tcx> { let reg = self.type_checker.constraints.placeholder_region(self.type_checker.infcx, placeholder); diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 64a7b4084349..aee1eb94dc81 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -454,8 +454,6 @@ struct UniversalRegionsBuilder<'infcx, 'tcx> { mir_def: LocalDefId, } -const FR: NllRegionVariableOrigin = NllRegionVariableOrigin::FreeRegion; - impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { fn build(self) -> UniversalRegions<'tcx> { debug!("build(mir_def={:?})", self.mir_def); @@ -466,8 +464,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars()); // Create the "global" region that is always free in all contexts: 'static. - let fr_static = - self.infcx.next_nll_region_var(FR, || RegionCtxt::Free(kw::Static)).as_var(); + let fr_static = self + .infcx + .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::Free(kw::Static) + }) + .as_var(); // We've now added all the global regions. The next ones we // add will be external. @@ -500,7 +502,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { debug!(?r); let region_vid = { let name = r.get_name_or_anon(self.infcx.tcx); - self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name)) + self.infcx.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::LateBound(name) + }) }; debug!(?region_vid); @@ -526,7 +530,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let r = ty::Region::new_late_param(self.infcx.tcx, self.mir_def.to_def_id(), kind); let region_vid = { let name = r.get_name_or_anon(self.infcx.tcx); - self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name)) + self.infcx.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::LateBound(name) + }) }; debug!(?region_vid); @@ -553,7 +559,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let reg_vid = self .infcx - .next_nll_region_var(FR, || RegionCtxt::Free(sym::c_dash_variadic)) + .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::Free(sym::c_dash_variadic) + }) .as_var(); let region = ty::Region::new_var(self.infcx.tcx, reg_vid); @@ -569,8 +577,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } } - let fr_fn_body = - self.infcx.next_nll_region_var(FR, || RegionCtxt::Free(sym::fn_body)).as_var(); + let fr_fn_body = self + .infcx + .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::Free(sym::fn_body) + }) + .as_var(); let num_universals = self.infcx.num_region_vars(); @@ -613,8 +625,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { debug!("defining_ty (pre-replacement): {:?}", defining_ty); - let defining_ty = - self.infcx.replace_free_regions_with_nll_infer_vars(FR, defining_ty); + let defining_ty = self.infcx.replace_free_regions_with_nll_infer_vars( + NllRegionVariableOrigin::FreeRegion, + defining_ty, + ); match *defining_ty.kind() { ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args), @@ -638,8 +652,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // Do not ICE when checking default_field_values consts with lifetimes (#135649) && DefKind::Field != tcx.def_kind(tcx.parent(typeck_root_def_id)) { - let args = - self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_args); + let args = self.infcx.replace_free_regions_with_nll_infer_vars( + NllRegionVariableOrigin::FreeRegion, + identity_args, + ); DefiningTy::Const(self.mir_def.to_def_id(), args) } else { // FIXME this line creates a dependency between borrowck and typeck. @@ -659,7 +675,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { InlineConstArgsParts { parent_args: identity_args, ty }, ) .args; - let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, args); + let args = self.infcx.replace_free_regions_with_nll_infer_vars( + NllRegionVariableOrigin::FreeRegion, + args, + ); DefiningTy::InlineConst(self.mir_def.to_def_id(), args) } } @@ -856,7 +875,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> { #[instrument(skip(self), level = "debug")] fn replace_free_regions_with_nll_infer_vars( &self, - origin: NllRegionVariableOrigin, + origin: NllRegionVariableOrigin<'tcx>, value: T, ) -> T where diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index fa497cc21e40..c18faa785b16 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -590,10 +590,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( ty, Ty::new_placeholder( tcx, - ty::Placeholder { + ty::Placeholder::new( universe, - bound: ty::BoundTy { var: idx, kind: ty::BoundTyKind::Anon }, - }, + ty::BoundTy { var: idx, kind: ty::BoundTyKind::Anon }, + ), ), ) }) diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index e445def4faa7..c07b41b56caa 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -684,22 +684,22 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { CanonicalVarKind::Region(u) => CanonicalVarKind::Region(reverse_universe_map[&u]), CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]), CanonicalVarKind::PlaceholderTy(placeholder) => { - CanonicalVarKind::PlaceholderTy(ty::Placeholder { - universe: reverse_universe_map[&placeholder.universe], - ..placeholder - }) + CanonicalVarKind::PlaceholderTy(ty::Placeholder::new( + reverse_universe_map[&placeholder.universe], + placeholder.bound, + )) } CanonicalVarKind::PlaceholderRegion(placeholder) => { - CanonicalVarKind::PlaceholderRegion(ty::Placeholder { - universe: reverse_universe_map[&placeholder.universe], - ..placeholder - }) + CanonicalVarKind::PlaceholderRegion(ty::Placeholder::new( + reverse_universe_map[&placeholder.universe], + placeholder.bound, + )) } CanonicalVarKind::PlaceholderConst(placeholder) => { - CanonicalVarKind::PlaceholderConst(ty::Placeholder { - universe: reverse_universe_map[&placeholder.universe], - ..placeholder - }) + CanonicalVarKind::PlaceholderConst(ty::Placeholder::new( + reverse_universe_map[&placeholder.universe], + placeholder.bound, + )) } }) .collect() diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index f99f228e19d8..9af0e17be4e2 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -109,9 +109,9 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::Float => self.next_float_var().into(), - CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, bound }) => { + CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, bound, .. }) => { let universe_mapped = universe_map(universe); - let placeholder_mapped = ty::PlaceholderType { universe: universe_mapped, bound }; + let placeholder_mapped = ty::PlaceholderType::new(universe_mapped, bound); Ty::new_placeholder(self.tcx, placeholder_mapped).into() } @@ -119,18 +119,22 @@ impl<'tcx> InferCtxt<'tcx> { .next_region_var_in_universe(RegionVariableOrigin::Misc(span), universe_map(ui)) .into(), - CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, bound }) => { + CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { + universe, bound, .. + }) => { let universe_mapped = universe_map(universe); - let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, bound }; + let placeholder_mapped = ty::PlaceholderRegion::new(universe_mapped, bound); ty::Region::new_placeholder(self.tcx, placeholder_mapped).into() } CanonicalVarKind::Const(ui) => { self.next_const_var_in_universe(span, universe_map(ui)).into() } - CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }) => { + CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { + universe, bound, .. + }) => { let universe_mapped = universe_map(universe); - let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, bound }; + let placeholder_mapped = ty::PlaceholderConst::new(universe_mapped, bound); ty::Const::new_placeholder(self.tcx, placeholder_mapped).into() } } diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 3adcfb427278..5134b7b7ca8f 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -31,7 +31,7 @@ use crate::infer::{RegionRelations, RegionVariableOrigin, SubregionOrigin}; #[instrument(level = "debug", skip(region_rels, var_infos, data))] pub(crate) fn resolve<'tcx>( region_rels: &RegionRelations<'_, 'tcx>, - var_infos: VarInfos, + var_infos: VarInfos<'tcx>, data: RegionConstraintData<'tcx>, ) -> (LexicalRegionResolutions<'tcx>, Vec>) { let mut errors = vec![]; @@ -80,7 +80,7 @@ pub enum RegionResolutionError<'tcx> { /// `sub_r <= sup_r` does not hold. SubSupConflict( RegionVid, - RegionVariableOrigin, + RegionVariableOrigin<'tcx>, SubregionOrigin<'tcx>, Region<'tcx>, SubregionOrigin<'tcx>, @@ -92,7 +92,7 @@ pub enum RegionResolutionError<'tcx> { /// cannot name the placeholder `'b`. UpperBoundUniverseConflict( RegionVid, - RegionVariableOrigin, + RegionVariableOrigin<'tcx>, ty::UniverseIndex, // the universe index of the region variable SubregionOrigin<'tcx>, // cause of the constraint Region<'tcx>, // the placeholder `'b` @@ -122,7 +122,7 @@ type RegionGraph<'tcx> = LinkedGraph<(), Constraint<'tcx>>; struct LexicalResolver<'cx, 'tcx> { region_rels: &'cx RegionRelations<'cx, 'tcx>, - var_infos: VarInfos, + var_infos: VarInfos<'tcx>, data: RegionConstraintData<'tcx>, } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index dc4ee0d88a06..53567c6071e3 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -421,7 +421,7 @@ pub enum BoundRegionConversionTime { /// /// See `error_reporting` module for more details. #[derive(Copy, Clone, Debug)] -pub enum RegionVariableOrigin { +pub enum RegionVariableOrigin<'tcx> { /// Region variables created for ill-categorized reasons. /// /// They mostly indicate places in need of refactoring. @@ -453,11 +453,11 @@ pub enum RegionVariableOrigin { /// This origin is used for the inference variables that we create /// during NLL region processing. - Nll(NllRegionVariableOrigin), + Nll(NllRegionVariableOrigin<'tcx>), } #[derive(Copy, Clone, Debug)] -pub enum NllRegionVariableOrigin { +pub enum NllRegionVariableOrigin<'tcx> { /// During NLL region processing, we create variables for free /// regions that we encounter in the function signature and /// elsewhere. This origin indices we've got one of those. @@ -465,7 +465,7 @@ pub enum NllRegionVariableOrigin { /// "Universal" instantiation of a higher-ranked region (e.g., /// from a `for<'a> T` binder). Meant to represent "any region". - Placeholder(ty::PlaceholderRegion), + Placeholder(ty::PlaceholderRegion<'tcx>), Existential { name: Option, @@ -838,7 +838,7 @@ impl<'tcx> InferCtxt<'tcx> { /// Creates a fresh region variable with the next available index. /// The variable will be created in the maximum universe created /// thus far, allowing it to name any region created thus far. - pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region<'tcx> { + pub fn next_region_var(&self, origin: RegionVariableOrigin<'tcx>) -> ty::Region<'tcx> { self.next_region_var_in_universe(origin, self.universe()) } @@ -847,7 +847,7 @@ impl<'tcx> InferCtxt<'tcx> { /// `next_region_var` and just use the maximal universe. pub fn next_region_var_in_universe( &self, - origin: RegionVariableOrigin, + origin: RegionVariableOrigin<'tcx>, universe: ty::UniverseIndex, ) -> ty::Region<'tcx> { let region_var = @@ -878,7 +878,7 @@ impl<'tcx> InferCtxt<'tcx> { /// Just a convenient wrapper of `next_region_var` for using during NLL. #[instrument(skip(self), level = "debug")] - pub fn next_nll_region_var(&self, origin: NllRegionVariableOrigin) -> ty::Region<'tcx> { + pub fn next_nll_region_var(&self, origin: NllRegionVariableOrigin<'tcx>) -> ty::Region<'tcx> { self.next_region_var(RegionVariableOrigin::Nll(origin)) } @@ -886,7 +886,7 @@ impl<'tcx> InferCtxt<'tcx> { #[instrument(skip(self), level = "debug")] pub fn next_nll_region_var_in_universe( &self, - origin: NllRegionVariableOrigin, + origin: NllRegionVariableOrigin<'tcx>, universe: ty::UniverseIndex, ) -> ty::Region<'tcx> { self.next_region_var_in_universe(RegionVariableOrigin::Nll(origin), universe) @@ -954,7 +954,7 @@ impl<'tcx> InferCtxt<'tcx> { self.tainted_by_errors.set(Some(e)); } - pub fn region_var_origin(&self, vid: ty::RegionVid) -> RegionVariableOrigin { + pub fn region_var_origin(&self, vid: ty::RegionVid) -> RegionVariableOrigin<'tcx> { let mut inner = self.inner.borrow_mut(); let inner = &mut *inner; inner.unwrap_region_constraints().var_origin(vid) @@ -962,7 +962,7 @@ impl<'tcx> InferCtxt<'tcx> { /// Clone the list of variable regions. This is used only during NLL processing /// to put the set of region variables into the NLL region context. - pub fn get_region_var_infos(&self) -> VarInfos { + pub fn get_region_var_infos(&self) -> VarInfos<'tcx> { let inner = self.inner.borrow(); assert!(!UndoLogs::>::in_snapshot(&inner.undo_log)); let storage = inner.region_constraint_storage.as_ref().expect("regions already resolved"); @@ -1649,7 +1649,7 @@ impl<'tcx> SubregionOrigin<'tcx> { } } -impl RegionVariableOrigin { +impl<'tcx> RegionVariableOrigin<'tcx> { pub fn span(&self) -> Span { match *self { RegionVariableOrigin::Misc(a) diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index a640dcb1b4e1..f06f50785ecc 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -394,7 +394,7 @@ where &mut self, origin: infer::SubregionOrigin<'tcx>, region: ty::Region<'tcx>, - placeholder_ty: ty::PlaceholderType, + placeholder_ty: ty::PlaceholderType<'tcx>, ) { let verify_bound = self .verify_bound diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 4d76bc2e17a1..4ef1ea5a1c4d 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -105,7 +105,7 @@ struct LeakCheck<'a, 'tcx> { // is repurposed to store some placeholder `P` such that the weaker // condition `S: P` must hold. (This is true if `S: S1` transitively and `S1 // = P`.) - scc_placeholders: IndexVec>, + scc_placeholders: IndexVec>>, // For each SCC S, track the minimum universe that flows into it. Note that // this is both the minimum of the universes for every region that is a @@ -258,15 +258,15 @@ impl<'a, 'tcx> LeakCheck<'a, 'tcx> { fn placeholder_error( &self, - placeholder1: ty::PlaceholderRegion, - placeholder2: ty::PlaceholderRegion, + placeholder1: ty::PlaceholderRegion<'tcx>, + placeholder2: ty::PlaceholderRegion<'tcx>, ) -> TypeError<'tcx> { self.error(placeholder1, ty::Region::new_placeholder(self.tcx, placeholder2)) } fn error( &self, - placeholder: ty::PlaceholderRegion, + placeholder: ty::PlaceholderRegion<'tcx>, other_region: ty::Region<'tcx>, ) -> TypeError<'tcx> { debug!("error: placeholder={:?}, other_region={:?}", placeholder, other_region); diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 85f5e55a8e1e..ae7481b5d1e7 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -23,7 +23,7 @@ mod leak_check; #[derive(Clone, Default)] pub struct RegionConstraintStorage<'tcx> { /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. - pub(super) var_infos: IndexVec, + pub(super) var_infos: IndexVec>, pub(super) data: RegionConstraintData<'tcx>, @@ -57,7 +57,7 @@ pub struct RegionConstraintCollector<'a, 'tcx> { undo_log: &'a mut InferCtxtUndoLogs<'tcx>, } -pub type VarInfos = IndexVec; +pub type VarInfos<'tcx> = IndexVec>; /// The full set of region constraints gathered up by the collector. /// Describes constraints between the region variables and other @@ -125,7 +125,7 @@ pub struct Verify<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)] pub enum GenericKind<'tcx> { Param(ty::ParamTy), - Placeholder(ty::PlaceholderType), + Placeholder(ty::PlaceholderType<'tcx>), Alias(ty::AliasTy<'tcx>), } @@ -269,8 +269,8 @@ pub(crate) enum CombineMapType { type CombineMap<'tcx> = FxHashMap, RegionVid>; #[derive(Debug, Clone, Copy)] -pub struct RegionVariableInfo { - pub origin: RegionVariableOrigin, +pub struct RegionVariableInfo<'tcx> { + pub origin: RegionVariableOrigin<'tcx>, // FIXME: This is only necessary for `fn take_and_reset_data` and // `lexical_region_resolve`. We should rework `lexical_region_resolve` // in the near/medium future anyways and could move the unverse info @@ -374,7 +374,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { pub(super) fn new_region_var( &mut self, universe: ty::UniverseIndex, - origin: RegionVariableOrigin, + origin: RegionVariableOrigin<'tcx>, ) -> RegionVid { let vid = self.storage.var_infos.push(RegionVariableInfo { origin, universe }); @@ -386,7 +386,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } /// Returns the origin for the given variable. - pub(super) fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin { + pub(super) fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin<'tcx> { self.storage.var_infos[vid].origin } @@ -624,10 +624,10 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } } - pub fn vars_since_snapshot( - &self, + pub fn vars_since_snapshot<'a>( + &'a self, value_count: usize, - ) -> (Range, Vec) { + ) -> (Range, Vec>) { let range = RegionVid::from(value_count)..RegionVid::from(self.storage.unification_table.len()); ( diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs index 16fe591b29bb..7a0f70e979b8 100644 --- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs +++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs @@ -34,21 +34,15 @@ impl<'tcx> InferCtxt<'tcx> { let delegate = FnMutDelegate { regions: &mut |br: ty::BoundRegion| { - ty::Region::new_placeholder( - self.tcx, - ty::PlaceholderRegion { universe: next_universe, bound: br }, - ) + ty::Region::new_placeholder(self.tcx, ty::PlaceholderRegion::new(next_universe, br)) }, types: &mut |bound_ty: ty::BoundTy| { - Ty::new_placeholder( - self.tcx, - ty::PlaceholderType { universe: next_universe, bound: bound_ty }, - ) + Ty::new_placeholder(self.tcx, ty::PlaceholderType::new(next_universe, bound_ty)) }, consts: &mut |bound_const: ty::BoundConst| { ty::Const::new_placeholder( self.tcx, - ty::PlaceholderConst { universe: next_universe, bound: bound_const }, + ty::PlaceholderConst::new(next_universe, bound_const), ) }, }; diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index 3730d215a901..6709c822dc7b 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -113,7 +113,7 @@ impl<'tcx> InferCtxt<'tcx> { fn fudge_inference>>( &self, - snapshot_vars: SnapshotVarData, + snapshot_vars: SnapshotVarData<'tcx>, value: T, ) -> T { // Micro-optimization: if no variables have been created, then @@ -126,16 +126,16 @@ impl<'tcx> InferCtxt<'tcx> { } } -struct SnapshotVarData { - region_vars: (Range, Vec), +struct SnapshotVarData<'tcx> { + region_vars: (Range, Vec>), type_vars: (Range, Vec), int_vars: Range, float_vars: Range, const_vars: (Range, Vec), } -impl SnapshotVarData { - fn new(infcx: &InferCtxt<'_>, vars_pre_snapshot: VariableLengths) -> SnapshotVarData { +impl<'tcx> SnapshotVarData<'tcx> { + fn new(infcx: &InferCtxt<'tcx>, vars_pre_snapshot: VariableLengths) -> SnapshotVarData<'tcx> { let mut inner = infcx.inner.borrow_mut(); let region_vars = inner .unwrap_region_constraints() @@ -165,7 +165,7 @@ impl SnapshotVarData { struct InferenceFudger<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, - snapshot_vars: SnapshotVarData, + snapshot_vars: SnapshotVarData<'tcx>, } impl<'a, 'tcx> TypeFolder> for InferenceFudger<'a, 'tcx> { diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 95adb561c704..787ea5f9363d 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -107,7 +107,10 @@ impl<'tcx> Const<'tcx> { } #[inline] - pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst) -> Const<'tcx> { + pub fn new_placeholder( + tcx: TyCtxt<'tcx>, + placeholder: ty::PlaceholderConst<'tcx>, + ) -> Const<'tcx> { Const::new(tcx, ty::ConstKind::Placeholder(placeholder)) } @@ -192,7 +195,7 @@ impl<'tcx> rustc_type_ir::inherent::Const> for Const<'tcx> { Const::new_canonical_bound(tcx, var) } - fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst) -> Self { + fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst<'tcx>) -> Self { Const::new_placeholder(tcx, placeholder) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 88f0a2a7c23c..471bd1d937e9 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -148,7 +148,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type BoundTy = ty::BoundTy; type Symbol = Symbol; - type PlaceholderTy = ty::PlaceholderType; + type PlaceholderTy = ty::PlaceholderType<'tcx>; type ErrorGuaranteed = ErrorGuaranteed; type BoundExistentialPredicates = &'tcx List>; @@ -158,7 +158,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Safety = hir::Safety; type Abi = ExternAbi; type Const = ty::Const<'tcx>; - type PlaceholderConst = ty::PlaceholderConst; + type PlaceholderConst = ty::PlaceholderConst<'tcx>; type ParamConst = ty::ParamConst; type BoundConst = ty::BoundConst; @@ -170,7 +170,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type EarlyParamRegion = ty::EarlyParamRegion; type LateParamRegion = ty::LateParamRegion; type BoundRegion = ty::BoundRegion; - type PlaceholderRegion = ty::PlaceholderRegion; + type PlaceholderRegion = ty::PlaceholderRegion<'tcx>; type RegionAssumptions = &'tcx ty::List>; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d3e0fbb955c4..f732a7c91d1f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -886,20 +886,9 @@ impl<'tcx> DefinitionSiteHiddenType<'tcx> { } } -/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are -/// identified by both a universe, as well as a name residing within that universe. Distinct bound -/// regions/types/consts within the same universe simply have an unknown relationship to one -/// another. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -#[derive(HashStable, TyEncodable, TyDecodable)] -pub struct Placeholder { - pub universe: UniverseIndex, - pub bound: T, -} +pub type PlaceholderRegion<'tcx> = ty::Placeholder, BoundRegion>; -pub type PlaceholderRegion = Placeholder; - -impl<'tcx> rustc_type_ir::inherent::PlaceholderLike> for PlaceholderRegion { +impl<'tcx> rustc_type_ir::inherent::PlaceholderLike> for PlaceholderRegion<'tcx> { type Bound = BoundRegion; fn universe(self) -> UniverseIndex { @@ -911,21 +900,21 @@ impl<'tcx> rustc_type_ir::inherent::PlaceholderLike> for Placeholde } fn with_updated_universe(self, ui: UniverseIndex) -> Self { - Placeholder { universe: ui, ..self } + ty::Placeholder::new(ui, self.bound) } fn new(ui: UniverseIndex, bound: BoundRegion) -> Self { - Placeholder { universe: ui, bound } + ty::Placeholder::new(ui, bound) } fn new_anon(ui: UniverseIndex, var: BoundVar) -> Self { - Placeholder { universe: ui, bound: BoundRegion { var, kind: BoundRegionKind::Anon } } + ty::Placeholder::new(ui, BoundRegion { var, kind: BoundRegionKind::Anon }) } } -pub type PlaceholderType = Placeholder; +pub type PlaceholderType<'tcx> = ty::Placeholder, BoundTy>; -impl<'tcx> rustc_type_ir::inherent::PlaceholderLike> for PlaceholderType { +impl<'tcx> rustc_type_ir::inherent::PlaceholderLike> for PlaceholderType<'tcx> { type Bound = BoundTy; fn universe(self) -> UniverseIndex { @@ -937,15 +926,15 @@ impl<'tcx> rustc_type_ir::inherent::PlaceholderLike> for Placeholde } fn with_updated_universe(self, ui: UniverseIndex) -> Self { - Placeholder { universe: ui, ..self } + ty::Placeholder::new(ui, self.bound) } fn new(ui: UniverseIndex, bound: BoundTy) -> Self { - Placeholder { universe: ui, bound } + ty::Placeholder::new(ui, bound) } fn new_anon(ui: UniverseIndex, var: BoundVar) -> Self { - Placeholder { universe: ui, bound: BoundTy { var, kind: BoundTyKind::Anon } } + ty::Placeholder::new(ui, BoundTy { var, kind: BoundTyKind::Anon }) } } @@ -965,9 +954,9 @@ impl<'tcx> rustc_type_ir::inherent::BoundVarLike> for BoundConst { } } -pub type PlaceholderConst = Placeholder; +pub type PlaceholderConst<'tcx> = ty::Placeholder, BoundConst>; -impl<'tcx> rustc_type_ir::inherent::PlaceholderLike> for PlaceholderConst { +impl<'tcx> rustc_type_ir::inherent::PlaceholderLike> for PlaceholderConst<'tcx> { type Bound = BoundConst; fn universe(self) -> UniverseIndex { @@ -979,15 +968,15 @@ impl<'tcx> rustc_type_ir::inherent::PlaceholderLike> for Placeholde } fn with_updated_universe(self, ui: UniverseIndex) -> Self { - Placeholder { universe: ui, ..self } + ty::Placeholder::new(ui, self.bound) } fn new(ui: UniverseIndex, bound: BoundConst) -> Self { - Placeholder { universe: ui, bound } + ty::Placeholder::new(ui, bound) } fn new_anon(ui: UniverseIndex, var: BoundVar) -> Self { - Placeholder { universe: ui, bound: BoundConst { var } } + ty::Placeholder::new(ui, BoundConst { var }) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 6a4122ad6717..798e14c6f378 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3274,6 +3274,16 @@ define_print! { p.reset_type_limit(); self.term.print(p)?; } + + ty::PlaceholderType<'tcx> { + match self.bound.kind { + ty::BoundTyKind::Anon => write!(p, "{self:?}")?, + ty::BoundTyKind::Param(def_id) => match p.should_print_verbose() { + true => write!(p, "{self:?}")?, + false => write!(p, "{}", p.tcx().item_name(def_id))?, + }, + } + } } define_print_and_forward_display! { @@ -3338,16 +3348,6 @@ define_print_and_forward_display! { write!(p, "{}", self.name)?; } - ty::PlaceholderType { - match self.bound.kind { - ty::BoundTyKind::Anon => write!(p, "{self:?}")?, - ty::BoundTyKind::Param(def_id) => match p.should_print_verbose() { - true => write!(p, "{self:?}")?, - false => write!(p, "{}", p.tcx().item_name(def_id))?, - }, - } - } - ty::ParamConst { write!(p, "{}", self.name)?; } diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index f0687f2bc726..61994d928dec 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -97,7 +97,10 @@ impl<'tcx> Region<'tcx> { } #[inline] - pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion) -> Region<'tcx> { + pub fn new_placeholder( + tcx: TyCtxt<'tcx>, + placeholder: ty::PlaceholderRegion<'tcx>, + ) -> Region<'tcx> { tcx.intern_region(ty::RePlaceholder(placeholder)) } @@ -170,7 +173,7 @@ impl<'tcx> rustc_type_ir::inherent::Region> for Region<'tcx> { Region::new_canonical_bound(tcx, var) } - fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion) -> Self { + fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion<'tcx>) -> Self { Region::new_placeholder(tcx, placeholder) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index cff415e9036a..4f70830002ce 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -184,16 +184,6 @@ impl fmt::Debug for ty::BoundTy { } } -impl fmt::Debug for ty::Placeholder { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.universe == ty::UniverseIndex::ROOT { - write!(f, "!{:?}", self.bound) - } else { - write!(f, "!{}_{:?}", self.universe.index(), self.bound) - } - } -} - impl<'tcx> fmt::Debug for GenericArg<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind() { @@ -294,8 +284,8 @@ TrivialTypeTraversalImpls! { // interners). TrivialTypeTraversalAndLiftImpls! { // tidy-alphabetical-start + crate::ty::BoundTy, crate::ty::ParamTy, - crate::ty::PlaceholderType, crate::ty::instance::ReifyReason, rustc_hir::def_id::DefId, // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index e71bb9b6bb26..72573d96dc54 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -39,6 +39,7 @@ pub type FnSig<'tcx> = ir::FnSig>; pub type Binder<'tcx, T> = ir::Binder, T>; pub type EarlyBinder<'tcx, T> = ir::EarlyBinder, T>; pub type TypingMode<'tcx> = ir::TypingMode>; +pub type Placeholder<'tcx, T> = ir::Placeholder, T>; pub trait Article { fn article(&self) -> &'static str; @@ -508,7 +509,7 @@ impl<'tcx> Ty<'tcx> { } #[inline] - pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType) -> Ty<'tcx> { + pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType<'tcx>) -> Ty<'tcx> { Ty::new(tcx, Placeholder(placeholder)) } @@ -957,7 +958,7 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> { Ty::new_param(tcx, param.index, param.name) } - fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType) -> Self { + fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType<'tcx>) -> Self { Ty::new_placeholder(tcx, placeholder) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index da888acc4755..fdaf2d619dd5 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -980,7 +980,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn report_sub_sup_conflict( &self, generic_param_scope: LocalDefId, - var_origin: RegionVariableOrigin, + var_origin: RegionVariableOrigin<'tcx>, sub_origin: SubregionOrigin<'tcx>, sub_region: Region<'tcx>, sup_origin: SubregionOrigin<'tcx>, @@ -1051,7 +1051,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if sub_region.is_error() | sup_region.is_error() { err.delay_as_bug() } else { err.emit() } } - fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'_> { + fn report_inference_failure(&self, var_origin: RegionVariableOrigin<'tcx>) -> Diag<'_> { let br_string = |br: ty::BoundRegionKind| { let mut s = match br { ty::BoundRegionKind::Named(def_id) => self.tcx.item_name(def_id).to_string(), diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 45357be56399..2aae5f2cde1e 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -566,13 +566,10 @@ fn plug_infer_with_placeholders<'tcx>( ty, Ty::new_placeholder( self.infcx.tcx, - ty::Placeholder { - universe: self.universe, - bound: ty::BoundTy { - var: self.next_var(), - kind: ty::BoundTyKind::Anon, - }, - }, + ty::Placeholder::new( + self.universe, + ty::BoundTy { var: self.next_var(), kind: ty::BoundTyKind::Anon }, + ), ), ) else { @@ -595,10 +592,10 @@ fn plug_infer_with_placeholders<'tcx>( ct, ty::Const::new_placeholder( self.infcx.tcx, - ty::Placeholder { - universe: self.universe, - bound: ty::BoundConst { var: self.next_var() }, - }, + ty::Placeholder::new( + self.universe, + ty::BoundConst { var: self.next_var() }, + ), ), ) else { @@ -626,13 +623,13 @@ fn plug_infer_with_placeholders<'tcx>( r, ty::Region::new_placeholder( self.infcx.tcx, - ty::Placeholder { - universe: self.universe, - bound: ty::BoundRegion { + ty::Placeholder::new( + self.universe, + ty::BoundRegion { var: self.next_var(), kind: ty::BoundRegionKind::Anon, }, - }, + ), ), ) else { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index ccde214f6aa3..5839a8c2e295 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -756,10 +756,10 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>( self.idx += 1; Ty::new_placeholder( self.tcx, - ty::PlaceholderType { - universe: ty::UniverseIndex::ROOT, - bound: ty::BoundTy { var: idx, kind: ty::BoundTyKind::Anon }, - }, + ty::PlaceholderType::new( + ty::UniverseIndex::ROOT, + ty::BoundTy { var: idx, kind: ty::BoundTyKind::Anon }, + ), ) } else { t.super_fold_with(self) @@ -772,10 +772,7 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>( self.idx += 1; ty::Const::new_placeholder( self.tcx, - ty::PlaceholderConst { - universe: ty::UniverseIndex::ROOT, - bound: ty::BoundConst { var: idx }, - }, + ty::PlaceholderConst::new(ty::UniverseIndex::ROOT, ty::BoundConst { var: idx }), ) } else { c.super_fold_with(self) diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index e1d1ad1b3765..19ccf6a55bf1 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -220,9 +220,9 @@ pub fn with_replaced_escaping_bound_vars< /// The inverse of [`BoundVarReplacer`]: replaces placeholders with the bound vars from which they came. pub struct PlaceholderReplacer<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, - mapped_regions: FxIndexMap, - mapped_types: FxIndexMap, - mapped_consts: FxIndexMap, + mapped_regions: FxIndexMap, ty::BoundRegion>, + mapped_types: FxIndexMap, ty::BoundTy>, + mapped_consts: FxIndexMap, ty::BoundConst>, universe_indices: &'a [Option], current_index: ty::DebruijnIndex, } @@ -230,9 +230,9 @@ pub struct PlaceholderReplacer<'a, 'tcx> { impl<'a, 'tcx> PlaceholderReplacer<'a, 'tcx> { pub fn replace_placeholders>>( infcx: &'a InferCtxt<'tcx>, - mapped_regions: FxIndexMap, - mapped_types: FxIndexMap, - mapped_consts: FxIndexMap, + mapped_regions: FxIndexMap, ty::BoundRegion>, + mapped_types: FxIndexMap, ty::BoundTy>, + mapped_consts: FxIndexMap, ty::BoundConst>, universe_indices: &'a [Option], value: T, ) -> T { diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 94b950357e1e..d005ae95d6f1 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -1,3 +1,4 @@ +use std::fmt; use std::marker::PhantomData; use std::ops::{ControlFlow, Deref}; @@ -12,7 +13,7 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldabl use crate::inherent::*; use crate::lift::Lift; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, DebruijnIndex, Interner}; +use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex}; /// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -948,3 +949,55 @@ pub enum BoundVarIndexKind { Bound(DebruijnIndex), Canonical, } + +/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are +/// identified by both a universe, as well as a name residing within that universe. Distinct bound +/// regions/types/consts within the same universe simply have an unknown relationship to one +/// another. +#[derive_where(Clone, PartialEq, Ord, Hash; I: Interner, T)] +#[derive_where(PartialOrd; I: Interner, T: Ord)] +#[derive_where(Copy; I: Interner, T: Copy, T)] +#[derive_where(Eq; T)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[cfg_attr( + feature = "nightly", + derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) +)] +pub struct Placeholder { + pub universe: UniverseIndex, + pub bound: T, + #[type_foldable(identity)] + #[type_visitable(ignore)] + _tcx: PhantomData I>, +} + +impl Placeholder { + pub fn new(universe: UniverseIndex, bound: T) -> Self { + Placeholder { universe, bound, _tcx: PhantomData } + } +} + +impl fmt::Debug for ty::Placeholder { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.universe == ty::UniverseIndex::ROOT { + write!(f, "!{:?}", self.bound) + } else { + write!(f, "!{}_{:?}", self.universe.index(), self.bound) + } + } +} + +impl Lift for Placeholder +where + T: Lift, +{ + type Lifted = Placeholder; + + fn lift_to_interner(self, cx: U) -> Option { + Some(Placeholder { + universe: self.universe, + bound: self.bound.lift_to_interner(cx)?, + _tcx: PhantomData, + }) + } +} diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index 82bb8791b846..5af2bd811bab 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -3,7 +3,8 @@ use std::fmt; use crate::{ AliasTerm, AliasTy, Binder, ClosureKind, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig, HostEffectPredicate, Interner, NormalizesTo, OutlivesPredicate, - PatternKind, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef, UnevaluatedConst, + PatternKind, Placeholder, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef, + UnevaluatedConst, }; pub trait IrPrint { @@ -23,15 +24,6 @@ macro_rules! define_display_via_print { } } -impl fmt::Display for Binder -where - I: IrPrint>, -{ - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - >>::print(self, fmt) - } -} - macro_rules! define_debug_via_print { ($($ty:ident),+ $(,)?) => { $( @@ -71,6 +63,24 @@ where } } +impl fmt::Display for Binder +where + I: IrPrint>, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + >>::print(self, fmt) + } +} + +impl fmt::Display for Placeholder +where + I: IrPrint>, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + >>::print(self, fmt) + } +} + #[cfg(feature = "nightly")] mod into_diag_arg_impls { use rustc_error_messages::{DiagArgValue, IntoDiagArg}; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 8065db1e05dd..31fe0aac1de4 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -61,7 +61,7 @@ pub use InferTy::*; pub use RegionKind::*; pub use TyKind::*; pub use Variance::*; -pub use binder::*; +pub use binder::{Placeholder, *}; pub use canonical::*; pub use const_kind::*; pub use flags::*; From 4c6544b06ef037f8d0e29f1c010486609442a891 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 9 Dec 2025 12:14:28 +0100 Subject: [PATCH 0465/3801] Run clippy both with and without default features on the GCC backend --- src/bootstrap/src/core/build_steps/clippy.rs | 22 +++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index d8b74b43cfab..f80cf58fbb2a 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -379,15 +379,23 @@ impl Step for CodegenGcc { let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, Mode::Codegen, target)) .with_prefix("rustc_codegen_gcc-check"); - run_cargo( + let args = lint_args(builder, &self.config, &[]); + run_cargo(builder, cargo, args.clone(), &stamp, vec![], true, false); + + // Same but we disable the features enabled by default. + let mut cargo = prepare_tool_cargo( builder, - cargo, - lint_args(builder, &self.config, &[]), - &stamp, - vec![], - true, - false, + build_compiler, + Mode::Codegen, + target, + Kind::Clippy, + "compiler/rustc_codegen_gcc", + SourceType::InTree, + &[], ); + self.build_compiler.configure_cargo(&mut cargo); + cargo.arg("--no-default-features"); + run_cargo(builder, cargo, args, &stamp, vec![], true, false); } fn metadata(&self) -> Option { From 2bda6713c7a225e73b266ea50748e04188efed38 Mon Sep 17 00:00:00 2001 From: is57primenumber <58158444+is57primenumber@users.noreply.github.com> Date: Tue, 9 Dec 2025 22:34:04 +0900 Subject: [PATCH 0466/3801] Add regression test for closure loop vectorization --- tests/assembly-llvm/slp-vectorize-closure.rs | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/assembly-llvm/slp-vectorize-closure.rs diff --git a/tests/assembly-llvm/slp-vectorize-closure.rs b/tests/assembly-llvm/slp-vectorize-closure.rs new file mode 100644 index 000000000000..fcdb469a2413 --- /dev/null +++ b/tests/assembly-llvm/slp-vectorize-closure.rs @@ -0,0 +1,28 @@ +//! Loop inside closure correctly compiled to assembly using SSE instructions. +//! Regression test for . +//! also see +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 +//@ only-x86_64 +// to test SSE instructions + +#![crate_type = "lib"] + +// CHECK-LABEL: for_in_closure +// CHECK: {{paddb|psubb}} +#[inline(never)] +#[no_mangle] +pub fn for_in_closure() { + let mut v = [[0u8; 4]; 60]; + + let mut closure = || { + for item in &mut v { + item[0] += 1; + item[1] += 1; + item[2] += 1; + item[3] += 1; + } + }; + + closure(); +} From 50e9839d4849d932810ebba52a664d39baed5253 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Tue, 9 Dec 2025 00:31:56 +0800 Subject: [PATCH 0467/3801] Don't suggest wrapping attr in unsafe if it may come from proc macro --- compiler/rustc_attr_parsing/src/safety.rs | 19 ++++++++-- .../src/session_diagnostics.rs | 2 +- compiler/rustc_lint/src/early/diagnostics.rs | 14 +++---- compiler/rustc_lint/src/lints.rs | 2 +- compiler/rustc_lint_defs/src/lib.rs | 2 +- .../auxiliary/unsafe-attributes-pm-in-2024.rs | 29 +++++++++++++++ .../unsafe-attributes-from-pm-in-2024.rs | 18 +++++++++ .../unsafe-attributes-from-pm-in-2024.stderr | 37 +++++++++++++++++++ 8 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm-in-2024.rs create mode 100644 tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.rs create mode 100644 tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.stderr diff --git a/compiler/rustc_attr_parsing/src/safety.rs b/compiler/rustc_attr_parsing/src/safety.rs index 52baf2136173..817785108a1e 100644 --- a/compiler/rustc_attr_parsing/src/safety.rs +++ b/compiler/rustc_attr_parsing/src/safety.rs @@ -62,16 +62,28 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { Some(unsafe_since) => path_span.edition() >= unsafe_since, }; + let mut not_from_proc_macro = true; + if diag_span.from_expansion() + && let Ok(mut snippet) = self.sess.source_map().span_to_snippet(diag_span) + { + snippet.retain(|c| !c.is_whitespace()); + if snippet.contains("!(") || snippet.starts_with("#[") && snippet.ends_with("]") + { + not_from_proc_macro = false; + } + } + if emit_error { self.stage.emit_err( self.sess, crate::session_diagnostics::UnsafeAttrOutsideUnsafe { span: path_span, - suggestion: + suggestion: not_from_proc_macro.then(|| { crate::session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion { left: diag_span.shrink_to_lo(), right: diag_span.shrink_to_hi(), - }, + } + }), }, ); } else { @@ -81,7 +93,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { span: path_span, kind: AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span: path_span, - sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()), + sugg_spans: not_from_proc_macro + .then(|| (diag_span.shrink_to_lo(), diag_span.shrink_to_hi())), }, }) } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index c4f6f9c6a38c..cf3f3760d962 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -758,7 +758,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafe { #[label] pub span: Span, #[subdiagnostic] - pub suggestion: UnsafeAttrOutsideUnsafeSuggestion, + pub suggestion: Option, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 589594a3ec5e..c44e0ba67daa 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -353,14 +353,14 @@ pub fn decorate_attribute_lint( } .decorate_lint(diag) } - &AttributeLintKind::UnsafeAttrOutsideUnsafe { - attribute_name_span, - sugg_spans: (left, right), - } => lints::UnsafeAttrOutsideUnsafeLint { - span: attribute_name_span, - suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right }, + &AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span, sugg_spans } => { + lints::UnsafeAttrOutsideUnsafeLint { + span: attribute_name_span, + suggestion: sugg_spans + .map(|(left, right)| lints::UnsafeAttrOutsideUnsafeSuggestion { left, right }), + } + .decorate_lint(diag) } - .decorate_lint(diag), &AttributeLintKind::UnexpectedCfgName(name, value) => { check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag) } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 1bec316ce45a..20262c9c6bcf 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3177,7 +3177,7 @@ pub(crate) struct UnsafeAttrOutsideUnsafeLint { #[label] pub span: Span, #[subdiagnostic] - pub suggestion: UnsafeAttrOutsideUnsafeSuggestion, + pub suggestion: Option, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 376310838cc7..bb153afecc4c 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -729,7 +729,7 @@ pub enum AttributeLintKind { }, UnsafeAttrOutsideUnsafe { attribute_name_span: Span, - sugg_spans: (Span, Span), + sugg_spans: Option<(Span, Span)>, }, UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>), UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>), diff --git a/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm-in-2024.rs b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm-in-2024.rs new file mode 100644 index 000000000000..5f44223df90c --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm-in-2024.rs @@ -0,0 +1,29 @@ +//@ edition: 2024 + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn missing_unsafe(_input: TokenStream) -> TokenStream { + "#[no_mangle] pub fn abc() {}".parse().unwrap() +} + +#[proc_macro_attribute] +pub fn attr_missing_unsafe(_attr: TokenStream, _input: TokenStream) -> TokenStream { + "#[no_mangle] pub fn bar() {}".parse().unwrap() +} + +#[proc_macro_derive(AttrMissingUnsafe)] +pub fn derive_attr_missing_unsafe(_input: TokenStream) -> TokenStream { + "#[no_mangle] pub fn baz() {}".parse().unwrap() +} + +#[proc_macro] +pub fn macro_rules_missing_unsafe(_input: TokenStream) -> TokenStream { + "macro_rules! make_fn { + () => { #[no_mangle] pub fn foo() { } }; + }" + .parse() + .unwrap() +} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.rs new file mode 100644 index 000000000000..dca05cc27f6e --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.rs @@ -0,0 +1,18 @@ +// Test for unsafe attributes generated by a proc-macro. + +//@ proc-macro: unsafe-attributes-pm-in-2024.rs +//@ ignore-backends: gcc + +unsafe_attributes_pm_in_2024::missing_unsafe!(); //~ ERROR unsafe attribute used without unsafe + +#[unsafe_attributes_pm_in_2024::attr_missing_unsafe] //~ ERROR unsafe attribute used without unsafe +pub fn bar() {} + +#[derive(unsafe_attributes_pm_in_2024::AttrMissingUnsafe)] //~ ERROR unsafe attribute used without unsafe +struct Baz; + +unsafe_attributes_pm_in_2024::macro_rules_missing_unsafe!(); //~ ERROR unsafe attribute used without unsafe + +make_fn!(); + +fn main() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.stderr new file mode 100644 index 000000000000..fa36b148bf3d --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.stderr @@ -0,0 +1,37 @@ +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-from-pm-in-2024.rs:6:1 + | +LL | unsafe_attributes_pm_in_2024::missing_unsafe!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute + | + = note: this error originates in the macro `unsafe_attributes_pm_in_2024::missing_unsafe` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-from-pm-in-2024.rs:8:1 + | +LL | #[unsafe_attributes_pm_in_2024::attr_missing_unsafe] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute + | + = note: this error originates in the attribute macro `unsafe_attributes_pm_in_2024::attr_missing_unsafe` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-from-pm-in-2024.rs:11:10 + | +LL | #[derive(unsafe_attributes_pm_in_2024::AttrMissingUnsafe)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute + | + = note: this error originates in the derive macro `unsafe_attributes_pm_in_2024::AttrMissingUnsafe` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-from-pm-in-2024.rs:14:1 + | +LL | unsafe_attributes_pm_in_2024::macro_rules_missing_unsafe!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute +LL | +LL | make_fn!(); + | ---------- in this macro invocation + | + = note: this error originates in the macro `make_fn` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors + From 4501327be4fb0aa85a6e2d8bb29c43da658e09bf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 9 Dec 2025 15:42:22 +0100 Subject: [PATCH 0468/3801] Fix clippy lint in `cg_gcc` --- compiler/rustc_codegen_gcc/src/builder.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 1787415b72e6..df1e64c75b96 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -500,11 +500,11 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { } fn set_rvalue_location<'a, 'gcc, 'tcx>( - bx: &mut Builder<'a, 'gcc, 'tcx>, + _bx: &mut Builder<'a, 'gcc, 'tcx>, rvalue: RValue<'gcc>, ) -> RValue<'gcc> { - if let Some(location) = bx.location { - #[cfg(feature = "master")] + #[cfg(feature = "master")] + if let Some(location) = _bx.location { rvalue.set_location(location); } rvalue From e6143962f9802e88018a7084ef836203c90cef45 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 9 Dec 2025 15:42:22 +0100 Subject: [PATCH 0469/3801] Fix clippy lint in `cg_gcc` --- src/builder.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 1787415b72e6..df1e64c75b96 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -500,11 +500,11 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { } fn set_rvalue_location<'a, 'gcc, 'tcx>( - bx: &mut Builder<'a, 'gcc, 'tcx>, + _bx: &mut Builder<'a, 'gcc, 'tcx>, rvalue: RValue<'gcc>, ) -> RValue<'gcc> { - if let Some(location) = bx.location { - #[cfg(feature = "master")] + #[cfg(feature = "master")] + if let Some(location) = _bx.location { rvalue.set_location(location); } rvalue From 676550b308e78097dcf852747bedfadca1dc91ea Mon Sep 17 00:00:00 2001 From: benodiwal Date: Tue, 9 Dec 2025 18:49:55 +0530 Subject: [PATCH 0470/3801] fix: resolve const generic param-env panic in type projection --- .../hir-ty/src/infer/closure/analysis.rs | 2 + .../rust-analyzer/crates/hir-ty/src/layout.rs | 4 +- .../rust-analyzer/crates/hir-ty/src/mir.rs | 3 +- .../crates/hir-ty/src/mir/borrowck.rs | 11 +++- .../crates/hir-ty/src/mir/eval.rs | 1 + .../crates/hir-ty/src/mir/lower/tests.rs | 59 +++++++++++++++++++ 6 files changed, 73 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs index d6d63891bb06..308c01865ae3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs @@ -43,6 +43,7 @@ impl<'db> HirPlace<'db> { for p in &self.projections { ty = p.projected_ty( &ctx.table.infer_ctxt, + ctx.table.param_env, ty, |_, _, _| { unreachable!("Closure field only happens in MIR"); @@ -839,6 +840,7 @@ impl<'db> InferenceContext<'_, 'db> { for (i, p) in capture.place.projections.iter().enumerate() { ty = p.projected_ty( &self.table.infer_ctxt, + self.table.param_env, ty, |_, _, _| { unreachable!("Closure field only happens in MIR"); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 565063fb138c..4b20d6eb3220 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -25,7 +25,7 @@ use crate::{ consteval::try_const_usize, db::HirDatabase, next_solver::{ - DbInterner, GenericArgs, ParamEnv, Ty, TyKind, TypingMode, + DbInterner, GenericArgs, Ty, TyKind, TypingMode, infer::{DbInternerInferExt, traits::ObligationCause}, }, }; @@ -170,7 +170,7 @@ pub fn layout_of_ty_query<'db>( let cx = LayoutCx::new(dl); let infer_ctxt = interner.infer_ctxt().build(TypingMode::PostAnalysis); let cause = ObligationCause::dummy(); - let ty = infer_ctxt.at(&cause, ParamEnv::empty()).deeply_normalize(ty).unwrap_or(ty); + let ty = infer_ctxt.at(&cause, trait_env.param_env).deeply_normalize(ty).unwrap_or(ty); let result = match ty.kind() { TyKind::Adt(def, args) => { match def.inner().id { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs index 3cafb6aa2503..836c20a43348 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs @@ -157,6 +157,7 @@ impl<'db, V: PartialEq> ProjectionElem<'db, V> { pub fn projected_ty( &self, infcx: &InferCtxt<'db>, + env: ParamEnv<'db>, mut base: Ty<'db>, closure_field: impl FnOnce(InternedClosureId, GenericArgs<'db>, usize) -> Ty<'db>, krate: Crate, @@ -173,8 +174,6 @@ impl<'db, V: PartialEq> ProjectionElem<'db, V> { if matches!(base.kind(), TyKind::Alias(..)) { let mut ocx = ObligationCtxt::new(infcx); - // FIXME: we should get this from caller - let env = ParamEnv::empty(); match ocx.structurally_normalize_ty(&ObligationCause::dummy(), env, base) { Ok(it) => base = it, Err(_) => return Ty::new_error(interner, ErrorGuaranteed), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index 4d76a9f3fb3d..b39c9bc06559 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs @@ -106,7 +106,7 @@ pub fn borrowck_query<'db>( // FIXME(next-solver): Opaques. let infcx = interner.infer_ctxt().build(typing_mode); res.push(BorrowckResult { - mutability_of_locals: mutability_of_locals(&infcx, &body), + mutability_of_locals: mutability_of_locals(&infcx, env, &body), moved_out_of_ref: moved_out_of_ref(&infcx, env, &body), partially_moved: partially_moved(&infcx, env, &body), borrow_regions: borrow_regions(db, &body), @@ -146,6 +146,7 @@ fn moved_out_of_ref<'db>( } ty = proj.projected_ty( infcx, + env, ty, make_fetch_closure_field(db), body.owner.module(db).krate(db), @@ -242,6 +243,7 @@ fn partially_moved<'db>( for proj in p.projection.lookup(&body.projection_store) { ty = proj.projected_ty( infcx, + env, ty, make_fetch_closure_field(db), body.owner.module(db).krate(db), @@ -374,6 +376,7 @@ enum ProjectionCase { fn place_case<'db>( infcx: &InferCtxt<'db>, + env: ParamEnv<'db>, body: &MirBody<'db>, lvalue: &Place<'db>, ) -> ProjectionCase { @@ -395,6 +398,7 @@ fn place_case<'db>( } ty = proj.projected_ty( infcx, + env, ty, make_fetch_closure_field(db), body.owner.module(db).krate(db), @@ -535,6 +539,7 @@ fn record_usage_for_operand<'db>( fn mutability_of_locals<'db>( infcx: &InferCtxt<'db>, + env: ParamEnv<'db>, body: &MirBody<'db>, ) -> ArenaMap, MutabilityReason> { let db = infcx.interner.db; @@ -547,7 +552,7 @@ fn mutability_of_locals<'db>( for statement in &block.statements { match &statement.kind { StatementKind::Assign(place, value) => { - match place_case(infcx, body, place) { + match place_case(infcx, env, body, place) { ProjectionCase::Direct => { if ever_init_map.get(place.local).copied().unwrap_or_default() { push_mut_span(place.local, statement.span, &mut result); @@ -596,7 +601,7 @@ fn mutability_of_locals<'db>( }, p, ) = value - && place_case(infcx, body, p) != ProjectionCase::Indirect + && place_case(infcx, env, body, p) != ProjectionCase::Indirect { push_mut_span(p.local, statement.span, &mut result); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 35b45174c209..3b4913cae3fb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -722,6 +722,7 @@ impl<'db> Evaluator<'db> { let (ty, proj) = pair; let r = proj.projected_ty( &self.infcx, + self.param_env.param_env, ty, |c, subst, f| { let InternedClosure(def, _) = self.db.lookup_intern_closure(c); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/tests.rs index 357f617a21e1..73399dab7fbd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/tests.rs @@ -1,3 +1,4 @@ +use hir_def::DefWithBodyId; use test_fixture::WithFixture; use crate::{db::HirDatabase, setup_tracing, test_db::TestDB}; @@ -49,3 +50,61 @@ fn foo() { "#, ); } + +fn check_borrowck(#[rust_analyzer::rust_fixture] ra_fixture: &str) { + let _tracing = setup_tracing(); + let (db, file_ids) = TestDB::with_many_files(ra_fixture); + crate::attach_db(&db, || { + let file_id = *file_ids.last().unwrap(); + let module_id = db.module_for_file(file_id.file_id(&db)); + let def_map = module_id.def_map(&db); + let scope = &def_map[module_id].scope; + + let mut bodies: Vec = Vec::new(); + + for decl in scope.declarations() { + if let hir_def::ModuleDefId::FunctionId(f) = decl { + bodies.push(f.into()); + } + } + + for impl_id in scope.impls() { + let impl_items = impl_id.impl_items(&db); + for (_, item) in impl_items.items.iter() { + if let hir_def::AssocItemId::FunctionId(f) = item { + bodies.push((*f).into()); + } + } + } + + for body in bodies { + let _ = db.borrowck(body); + } + }) +} + +#[test] +fn regression_21173_const_generic_impl_with_assoc_type() { + check_borrowck( + r#" +pub trait Tr { + type Assoc; + fn f(&self, handle: Self::Assoc) -> i32; +} + +pub struct ConstGeneric; + +impl Tr for &ConstGeneric { + type Assoc = AssocTy; + + fn f(&self, a: Self::Assoc) -> i32 { + a.x + } +} + +pub struct AssocTy { + x: i32, +} + "#, + ); +} From 3551aeb5c3c4570e170cd433892eaa3f2507ce2e Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 5 Dec 2025 21:02:51 +0000 Subject: [PATCH 0471/3801] fix: `tuple_array_conversions` FP when binded vars are used before conversion --- clippy_lints/src/tuple_array_conversions.rs | 41 +++++++++++++++------ tests/ui/tuple_array_conversions.rs | 23 ++++++++++++ tests/ui/tuple_array_conversions.stderr | 10 ++++- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/clippy_lints/src/tuple_array_conversions.rs b/clippy_lints/src/tuple_array_conversions.rs index 5d0945bece55..98bf9f9fea58 100644 --- a/clippy_lints/src/tuple_array_conversions.rs +++ b/clippy_lints/src/tuple_array_conversions.rs @@ -1,9 +1,9 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::is_from_proc_macro; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeResPath; -use clippy_utils::visitors::for_each_local_use_after_expr; +use clippy_utils::visitors::local_used_once; +use clippy_utils::{get_enclosing_block, is_from_proc_macro}; use itertools::Itertools; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind, Node, PatKind}; @@ -11,7 +11,6 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use std::iter::once; -use std::ops::ControlFlow; declare_clippy_lint! { /// ### What it does @@ -86,7 +85,7 @@ fn check_array<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: & ExprKind::Path(_) => Some(elements.iter().collect()), _ => None, }) - && all_bindings_are_for_conv(cx, &[ty], expr, elements, &locals, ToType::Array) + && all_bindings_are_for_conv(cx, &[ty], elements, &locals, ToType::Array) && !is_from_proc_macro(cx, expr) { span_lint_and_help( @@ -123,7 +122,7 @@ fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: & ExprKind::Path(_) => Some(elements.iter().collect()), _ => None, }) - && all_bindings_are_for_conv(cx, tys, expr, elements, &locals, ToType::Tuple) + && all_bindings_are_for_conv(cx, tys, elements, &locals, ToType::Tuple) && !is_from_proc_macro(cx, expr) { span_lint_and_help( @@ -148,7 +147,6 @@ fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: & fn all_bindings_are_for_conv<'tcx>( cx: &LateContext<'tcx>, final_tys: &[Ty<'tcx>], - expr: &Expr<'_>, elements: &[Expr<'_>], locals: &[&Expr<'_>], kind: ToType, @@ -166,13 +164,30 @@ fn all_bindings_are_for_conv<'tcx>( _ => None, }) .all_equal() - // Fix #11124, very convenient utils function! ❤️ - && locals - .iter() - .all(|&l| for_each_local_use_after_expr(cx, l, expr.hir_id, |_| ControlFlow::Break::<()>(())).is_continue()) + && locals.iter().zip(local_parents.iter()).all(|(&l, &parent)| { + if let Node::LetStmt(_) = parent { + return true; + } + + let Some(b) = get_enclosing_block(cx, l) else { + return true; + }; + local_used_once(cx, b, l).is_some() + }) && local_parents.first().is_some_and(|node| { let Some(ty) = match node { - Node::Pat(pat) => Some(pat.hir_id), + Node::Pat(pat) + if let PatKind::Tuple(pats, _) | PatKind::Slice(pats, None, []) = &pat.kind + && pats.iter().zip(locals.iter()).all(|(p, l)| { + if let PatKind::Binding(_, id, _, _) = p.kind { + id == *l + } else { + true + } + }) => + { + Some(pat.hir_id) + }, Node::LetStmt(l) => Some(l.hir_id), _ => None, } @@ -186,7 +201,9 @@ fn all_bindings_are_for_conv<'tcx>( tys.len() == elements.len() && tys.iter().chain(final_tys.iter().copied()).all_equal() }, (ToType::Tuple, ty::Array(ty, len)) => { - let Some(len) = len.try_to_target_usize(cx.tcx) else { return false }; + let Some(len) = len.try_to_target_usize(cx.tcx) else { + return false; + }; len as usize == elements.len() && final_tys.iter().chain(once(ty)).all_equal() }, _ => false, diff --git a/tests/ui/tuple_array_conversions.rs b/tests/ui/tuple_array_conversions.rs index 772c41df090e..17e6a252b266 100644 --- a/tests/ui/tuple_array_conversions.rs +++ b/tests/ui/tuple_array_conversions.rs @@ -116,3 +116,26 @@ fn msrv_juust_right() { let x = &[1, 2]; let x = (x[0], x[1]); } + +fn issue16192() { + fn do_something(tuple: (u32, u32)) {} + fn produce_array() -> [u32; 2] { + [1, 2] + } + + let [a, b] = produce_array(); + for tuple in [(a, b), (b, a)] { + do_something(tuple); + } + + let [a, b] = produce_array(); + let x = b; + do_something((a, b)); + + let [a, b] = produce_array(); + do_something((b, a)); + + let [a, b] = produce_array(); + do_something((a, b)); + //~^ tuple_array_conversions +} diff --git a/tests/ui/tuple_array_conversions.stderr b/tests/ui/tuple_array_conversions.stderr index 6dafb8d285d4..4c15769b7487 100644 --- a/tests/ui/tuple_array_conversions.stderr +++ b/tests/ui/tuple_array_conversions.stderr @@ -80,5 +80,13 @@ LL | let x = [x.0, x.1]; | = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed -error: aborting due to 10 previous errors +error: it looks like you're trying to convert an array to a tuple + --> tests/ui/tuple_array_conversions.rs:139:18 + | +LL | do_something((a, b)); + | ^^^^^^ + | + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed + +error: aborting due to 11 previous errors From 20fabb48b90b00c59c79354dc819fb5148fa1c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 4 Nov 2025 18:00:38 +0000 Subject: [PATCH 0472/3801] Use return type `Span` on async fns instead of whole fn def `Span` --- compiler/rustc_ast_lowering/src/lib.rs | 5 ++--- .../ui/async-await/async-await-let-else.stderr | 2 +- .../async-fn/recurse-ice-129215.stderr | 4 ++-- ...ync-example-desugared-boxed-in-trait.stderr | 4 ++-- .../async-example-desugared-boxed.stderr | 2 +- .../async-example-desugared-manual.stderr | 2 +- .../in-trait/async-generics-and-bounds.stderr | 18 ++++++++---------- .../async-await/in-trait/async-generics.stderr | 18 ++++++++---------- ...-project-to-specializable-projection.stderr | 8 ++++---- .../inference_var_self_argument.stderr | 4 ++-- .../ui/async-await/issue-64130-3-other.stderr | 2 +- tests/ui/async-await/issues/issue-67893.stderr | 4 ++-- .../partial-drop-partial-reinit.stderr | 2 +- tests/ui/c-variadic/not-async.stderr | 12 ++++++------ .../cmse-nonsecure-entry/c-variadic.stderr | 4 ++-- .../in-trait/async-and-ret-ref.stderr | 10 +++++----- .../note-and-explain-ReVar-124973.stderr | 6 +++--- .../lifetimes/issue-76168-hr-outlives-3.stderr | 18 ++++++------------ .../type-match-with-late-bound.stderr | 13 +++++-------- .../hkl_forbidden4.stderr | 4 ++-- 20 files changed, 64 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index dff46ece6543..19e826cf18f3 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1670,7 +1670,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let output = match coro { Some(coro) => { let fn_def_id = self.local_def_id(fn_node_id); - self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span) + self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind) } None => match &decl.output { FnRetTy::Ty(ty) => { @@ -1755,9 +1755,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn_def_id: LocalDefId, coro: CoroutineKind, fn_kind: FnDeclKind, - fn_span: Span, ) -> hir::FnRetTy<'hir> { - let span = self.lower_span(fn_span); + let span = self.lower_span(output.span()); let (opaque_ty_node_id, allowed_features) = match coro { CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None), diff --git a/tests/ui/async-await/async-await-let-else.stderr b/tests/ui/async-await/async-await-let-else.stderr index 5883f34f87de..b5b56d3242f4 100644 --- a/tests/ui/async-await/async-await-let-else.stderr +++ b/tests/ui/async-await/async-await-let-else.stderr @@ -22,7 +22,7 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely --> $DIR/async-await-let-else.rs:47:13 | LL | async fn foo2(x: Option) { - | ------------------------------ within this `impl Future` + | - within this `impl Future` ... LL | is_send(foo2(Some(true))); | ------- ^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely diff --git a/tests/ui/async-await/async-fn/recurse-ice-129215.stderr b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr index 98c7be2a5a3f..232246590cf1 100644 --- a/tests/ui/async-await/async-fn/recurse-ice-129215.stderr +++ b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr @@ -7,10 +7,10 @@ LL | a() = help: the trait `Future` is not implemented for `()` error[E0277]: `()` is not a future - --> $DIR/recurse-ice-129215.rs:3:1 + --> $DIR/recurse-ice-129215.rs:3:13 | LL | async fn a() { - | ^^^^^^^^^^^^ `()` is not a future + | ^ `()` is not a future | = help: the trait `Future` is not implemented for `()` diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index 54df0edf5a8e..c98df134072e 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -1,8 +1,8 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:11:5 + --> $DIR/async-example-desugared-boxed-in-trait.rs:11:28 | LL | async fn foo(&self) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin>>`, found future + | ^^^ expected `Pin>>`, found future | note: type in trait --> $DIR/async-example-desugared-boxed-in-trait.rs:7:22 diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr index b7f2879727f2..d3765a7e6e6f 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr @@ -2,7 +2,7 @@ warning: impl trait in impl method signature does not match trait method signatu --> $DIR/async-example-desugared-boxed.rs:14:22 | LL | async fn foo(&self) -> i32; - | --------------------------- return type from trait method defined here + | --- return type from trait method defined here ... LL | fn foo(&self) -> Pin + '_>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr index 86546df88c17..3328dea37fe4 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr @@ -2,7 +2,7 @@ warning: impl trait in impl method signature does not match trait method signatu --> $DIR/async-example-desugared-manual.rs:22:22 | LL | async fn foo(&self) -> i32; - | --------------------------- return type from trait method defined here + | --- return type from trait method defined here ... LL | fn foo(&self) -> MyFuture { | ^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr index 183b0fa152aa..52fd887b296f 100644 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr @@ -1,11 +1,10 @@ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics-and-bounds.rs:8:5 + --> $DIR/async-generics-and-bounds.rs:8:28 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | the parameter type `T` must be valid for the anonymous lifetime as defined here... - | ...so that the reference type `&(T, U)` does not outlive the data it points at + | - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at + | | + | the parameter type `T` must be valid for the anonymous lifetime as defined here... | help: consider adding an explicit lifetime bound | @@ -13,13 +12,12 @@ LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Has | ++++ ++ ++ +++++++ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics-and-bounds.rs:8:5 + --> $DIR/async-generics-and-bounds.rs:8:28 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | the parameter type `U` must be valid for the anonymous lifetime as defined here... - | ...so that the reference type `&(T, U)` does not outlive the data it points at + | - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at + | | + | the parameter type `U` must be valid for the anonymous lifetime as defined here... | help: consider adding an explicit lifetime bound | diff --git a/tests/ui/async-await/in-trait/async-generics.stderr b/tests/ui/async-await/in-trait/async-generics.stderr index 8916ef5ab683..3f44e4cdb677 100644 --- a/tests/ui/async-await/in-trait/async-generics.stderr +++ b/tests/ui/async-await/in-trait/async-generics.stderr @@ -1,11 +1,10 @@ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics.rs:5:5 + --> $DIR/async-generics.rs:5:28 | LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^ - | | | - | | the parameter type `T` must be valid for the anonymous lifetime as defined here... - | ...so that the reference type `&(T, U)` does not outlive the data it points at + | - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at + | | + | the parameter type `T` must be valid for the anonymous lifetime as defined here... | help: consider adding an explicit lifetime bound | @@ -13,13 +12,12 @@ LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: 'a; | ++++ ++ ++ +++++++++++ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics.rs:5:5 + --> $DIR/async-generics.rs:5:28 | LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^ - | | | - | | the parameter type `U` must be valid for the anonymous lifetime as defined here... - | ...so that the reference type `&(T, U)` does not outlive the data it points at + | - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at + | | + | the parameter type `U` must be valid for the anonymous lifetime as defined here... | help: consider adding an explicit lifetime bound | diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr index 823d8d5b92fc..d0c11565f4e9 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr @@ -1,14 +1,14 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/dont-project-to-specializable-projection.rs:14:5 + --> $DIR/dont-project-to-specializable-projection.rs:14:35 | LL | default async fn foo(_: T) -> &'static str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found future + | ^^^^^^^^^^^^ expected associated type, found future | note: type in trait - --> $DIR/dont-project-to-specializable-projection.rs:10:5 + --> $DIR/dont-project-to-specializable-projection.rs:10:27 | LL | async fn foo(_: T) -> &'static str; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ = note: expected signature `fn(_) -> impl Future` found signature `fn(_) -> impl Future` diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr index 1fccc32470ff..c4240a095e68 100644 --- a/tests/ui/async-await/inference_var_self_argument.stderr +++ b/tests/ui/async-await/inference_var_self_argument.stderr @@ -8,10 +8,10 @@ LL | async fn foo(self: &dyn Foo) { = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/inference_var_self_argument.rs:5:5 + --> $DIR/inference_var_self_argument.rs:5:33 | LL | async fn foo(self: &dyn Foo) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible + | ^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit diff --git a/tests/ui/async-await/issue-64130-3-other.stderr b/tests/ui/async-await/issue-64130-3-other.stderr index d683366ed473..531a7028f7e0 100644 --- a/tests/ui/async-await/issue-64130-3-other.stderr +++ b/tests/ui/async-await/issue-64130-3-other.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl Future $DIR/issue-64130-3-other.rs:25:12 | LL | async fn bar() { - | -------------- within this `impl Future` + | - within this `impl Future` ... LL | is_qux(bar()); | ^^^^^ unsatisfied trait bound diff --git a/tests/ui/async-await/issues/issue-67893.stderr b/tests/ui/async-await/issues/issue-67893.stderr index 34f28dd53c7b..610ed60bc8fd 100644 --- a/tests/ui/async-await/issues/issue-67893.stderr +++ b/tests/ui/async-await/issues/issue-67893.stderr @@ -6,10 +6,10 @@ LL | g(issue_67893::run()) | | | required by a bound introduced by this call | - ::: $DIR/auxiliary/issue_67893.rs:9:1 + ::: $DIR/auxiliary/issue_67893.rs:9:19 | LL | pub async fn run() { - | ------------------ within this `impl Future` + | - within this `impl Future` | = help: within `impl Future`, the trait `Send` is not implemented for `std::sync::MutexGuard<'_, ()>` note: required because it's used within this `async` fn body diff --git a/tests/ui/async-await/partial-drop-partial-reinit.stderr b/tests/ui/async-await/partial-drop-partial-reinit.stderr index cef835f7aed8..cf4b408ad12b 100644 --- a/tests/ui/async-await/partial-drop-partial-reinit.stderr +++ b/tests/ui/async-await/partial-drop-partial-reinit.stderr @@ -7,7 +7,7 @@ LL | gimme_send(foo()); | required by a bound introduced by this call ... LL | async fn foo() { - | -------------- within this `impl Future` + | - within this `impl Future` | help: within `impl Future`, the trait `Send` is not implemented for `NotSend` --> $DIR/partial-drop-partial-reinit.rs:19:1 diff --git a/tests/ui/c-variadic/not-async.stderr b/tests/ui/c-variadic/not-async.stderr index fc5eb10bec4f..bb8cc64e15fa 100644 --- a/tests/ui/c-variadic/not-async.stderr +++ b/tests/ui/c-variadic/not-async.stderr @@ -14,9 +14,9 @@ error[E0700]: hidden type for `impl Future` captures lifetime that --> $DIR/not-async.rs:5:65 | LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, _: ...) {} - | --------------------------------------------------------------- ^^ - | | - | opaque type defined here + | -^^ + | | + | opaque type defined here | = note: hidden type `{async fn body of fn_cannot_be_async()}` captures lifetime `'_` @@ -24,9 +24,9 @@ error[E0700]: hidden type for `impl Future` captures lifetime that --> $DIR/not-async.rs:12:73 | LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, _: ...) {} - | ------------------------------------------------------------------- ^^ - | | - | opaque type defined here + | -^^ + | | + | opaque type defined here | = note: hidden type `{async fn body of S::method_cannot_be_async()}` captures lifetime `'_` diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr index c8f4ef98c124..2a2d769c7cf8 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr @@ -25,10 +25,10 @@ LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/c-variadic.rs:26:1 + --> $DIR/c-variadic.rs:26:69 | LL | async unsafe extern "cmse-nonsecure-entry" fn async_is_not_allowed() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: aborting due to 4 previous errors diff --git a/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr b/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr index 19ffff9d3f2b..75d722402096 100644 --- a/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr +++ b/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr @@ -1,11 +1,11 @@ error[E0310]: the associated type `impl T` may not live long enough - --> $DIR/async-and-ret-ref.rs:7:5 + --> $DIR/async-and-ret-ref.rs:7:23 | LL | async fn foo() -> &'static impl T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the associated type `impl T` must be valid for the static lifetime... - | ...so that the reference type `&'static impl T` does not outlive the data it points at + | ^^^^^^^^^^^^^^^ + | | + | the associated type `impl T` must be valid for the static lifetime... + | ...so that the reference type `&'static impl T` does not outlive the data it points at error: aborting due to 1 previous error diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.stderr b/tests/ui/inference/note-and-explain-ReVar-124973.stderr index bb37e6231a32..2b5e79e9a1c6 100644 --- a/tests/ui/inference/note-and-explain-ReVar-124973.stderr +++ b/tests/ui/inference/note-and-explain-ReVar-124973.stderr @@ -8,9 +8,9 @@ error[E0700]: hidden type for `impl Future` captures lifetime that --> $DIR/note-and-explain-ReVar-124973.rs:5:76 | LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, _: ...) {} - | -------------------------------------------------------------------------- ^^ - | | - | opaque type defined here + | -^^ + | | + | opaque type defined here | = note: hidden type `{async fn body of multiple_named_lifetimes<'a, 'b>()}` captures lifetime `'_` diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr index 945d38d17f63..bb8e84724257 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr @@ -34,24 +34,18 @@ LL | for<'a> >::Output: Future + 'a, = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:6:1 + --> $DIR/issue-76168-hr-outlives-3.rs:6:26 | -LL | / async fn wrapper(f: F) -... | -LL | | F:, -LL | | for<'a> >::Output: Future + 'a, - | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` +LL | async fn wrapper(f: F) + | ^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:6:1 + --> $DIR/issue-76168-hr-outlives-3.rs:6:26 | -LL | / async fn wrapper(f: F) -... | -LL | | F:, -LL | | for<'a> >::Output: Future + 'a, - | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` +LL | async fn wrapper(f: F) + | ^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr index 15902bf16de5..c325718b3033 100644 --- a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr +++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr @@ -8,15 +8,12 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0309]: the placeholder type `F` may not live long enough - --> $DIR/type-match-with-late-bound.rs:8:1 + --> $DIR/type-match-with-late-bound.rs:8:32 | -LL | async fn walk2<'a, T: 'a>(_: T) - | ^ -- the placeholder type `F` must be valid for the lifetime `'a` as defined here... - | _| - | | -LL | | where -LL | | for F: 'a, - | |_________________^ ...so that the type `F` will meet its required lifetime bounds... +LL | async fn walk2<'a, T: 'a>(_: T) + | -- ^ ...so that the type `F` will meet its required lifetime bounds... + | | + | the placeholder type `F` must be valid for the lifetime `'a` as defined here... | note: ...that is required by this bound --> $DIR/type-match-with-late-bound.rs:10:15 diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index 2aacf9698379..87313e349524 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -18,10 +18,10 @@ LL | call(operation).await | ^^^^^^^^^^^^^^^ expected `{async fn body of operation()}`, got `FutNothing<'_>` | note: previous use here - --> $DIR/hkl_forbidden4.rs:12:1 + --> $DIR/hkl_forbidden4.rs:12:35 | LL | async fn operation(_: &mut ()) -> () { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to 2 previous errors From 76f02cf142b24ce73794c72d196094192144d47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 4 Nov 2025 18:08:36 +0000 Subject: [PATCH 0473/3801] Add test for `dyn Trait` in `async fn` return type --- .../async-fn/dyn-in-return-type.rs | 10 ++++++++ .../async-fn/dyn-in-return-type.stderr | 25 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/ui/async-await/async-fn/dyn-in-return-type.rs create mode 100644 tests/ui/async-await/async-fn/dyn-in-return-type.stderr diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.rs b/tests/ui/async-await/async-fn/dyn-in-return-type.rs new file mode 100644 index 000000000000..ec793bf80f28 --- /dev/null +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.rs @@ -0,0 +1,10 @@ +//@ edition:2024 + +async fn f() -> dyn core::fmt::Debug { +//~^ ERROR return type cannot be a trait object without pointer indirection +//~| HELP consider returning an `impl Trait` instead of a `dyn Trait` +//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + loop {} +} + +fn main() {} diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr new file mode 100644 index 000000000000..6b1b092f5555 --- /dev/null +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr @@ -0,0 +1,25 @@ +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-in-return-type.rs:3:38 + | +LL | async fn f() -> dyn core::fmt::Debug { + | ______________________________________^ +... | +LL | | } + | |_^ doesn't have a size known at compile-time + | +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL | async fn f() -> dyn core::fmt::Debug impl { + | ++++ +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL ~ async fn f() -> dyn core::fmt::Debug Box + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0746`. From 7868d20bd585906c19557ae7221ae5cc74a8f5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 4 Nov 2025 18:11:51 +0000 Subject: [PATCH 0474/3801] Account for `async fn` with `dyn Trait` return type in `impl Trait` suggestion --- .../src/error_reporting/traits/suggestions.rs | 16 +++++++++++++++- .../async-fn/dyn-in-return-type.stderr | 13 +++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 1094f00e42f2..16bb4c186447 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1891,7 +1891,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.primary_message("return type cannot be a trait object without pointer indirection"); err.children.clear(); - let span = obligation.cause.span; + let mut span = obligation.cause.span; + if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id) + && let parent = self.tcx.parent(obligation.cause.body_id.into()) + && let DefKind::Fn = self.tcx.def_kind(parent) + && self.tcx.asyncness(parent).is_async() + && let Some(parent) = parent.as_local() + && let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) = + self.tcx.hir_node_by_def_id(parent) + { + // Do not suggest (#147894) + // async fn foo() -> dyn Display impl { .. } + // and + // async fn foo() -> dyn Display Box + span = fn_sig.decl.output.span(); + } let body = self.tcx.hir_body_owned_by(obligation.cause.body_id); let mut visitor = ReturnsVisitor::default(); diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr index 6b1b092f5555..bd2ee4c208ca 100644 --- a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr @@ -9,16 +9,13 @@ LL | | } | help: consider returning an `impl Trait` instead of a `dyn Trait` | -LL | async fn f() -> dyn core::fmt::Debug impl { - | ++++ +LL - async fn f() -> dyn core::fmt::Debug { +LL + async fn f() -> impl core::fmt::Debug { + | help: alternatively, box the return type, and wrap all of the returned values in `Box::new` | -LL ~ async fn f() -> dyn core::fmt::Debug Box - | +LL | async fn f() -> Box { + | ++++ + error: aborting due to 1 previous error From fabf5746a20876e49a8ce9fce3e6c859ba49f39b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 4 Nov 2025 18:31:31 +0000 Subject: [PATCH 0475/3801] Add test for `type Alias = dyn Trait` in return type --- .../dyn-trait-type-alias-return-type.rs | 8 ++++++++ .../dyn-trait-type-alias-return-type.stderr | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/ui/type-alias/dyn-trait-type-alias-return-type.rs create mode 100644 tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs new file mode 100644 index 000000000000..f96cd989a4ce --- /dev/null +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs @@ -0,0 +1,8 @@ +type T = dyn core::fmt::Debug; + +fn f() -> T { loop {} } +//~^ ERROR return type cannot be a trait object without pointer indirection +//~| HELP +//~| HELP + +fn main() {} diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr new file mode 100644 index 000000000000..d67ba7759551 --- /dev/null +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr @@ -0,0 +1,18 @@ +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-trait-type-alias-return-type.rs:3:11 + | +LL | fn f() -> T { loop {} } + | ^ doesn't have a size known at compile-time + | +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL | fn f() -> impl T { loop {} } + | ++++ +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL | fn f() -> Box { Box::new(loop {}) } + | +++++++ + +++++++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0746`. From 60b227acccf40cff72df2104fbdedc8185e8a57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 4 Nov 2025 18:41:04 +0000 Subject: [PATCH 0476/3801] Recognize `type Alias = dyn Trait` in `fn` return types ``` error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time --> $DIR/dyn-trait-type-alias-return-type.rs:4:11 | LL | fn f() -> T { loop {} } | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` note: this type alias is unsized --> $DIR/dyn-trait-type-alias-return-type.rs:1:1 | LL | type T = dyn core::fmt::Debug; | ^^^^^^ = note: the return type of a function must have a statically known size ``` --- .../src/error_reporting/traits/suggestions.rs | 13 +++++++ .../clippy/tests/ui/future_not_send.stderr | 37 +++++++++---------- .../dyn-trait-type-alias-return-type.rs | 10 +++-- .../dyn-trait-type-alias-return-type.stderr | 19 +++++----- tests/ui/unsized/issue-91801.rs | 2 +- tests/ui/unsized/issue-91801.stderr | 17 ++++----- 6 files changed, 54 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 16bb4c186447..822025b986b8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1886,6 +1886,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let ty::Dynamic(_, _) = trait_pred.self_ty().skip_binder().kind() else { return false; }; + if let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) = + self.tcx.hir_node_by_def_id(obligation.cause.body_id) + && let hir::FnRetTy::Return(ty) = fn_sig.decl.output + && let hir::TyKind::Path(qpath) = ty.kind + && let hir::QPath::Resolved(None, path) = qpath + && let Res::Def(DefKind::TyAlias, def_id) = path.res + { + // Do not suggest + // type T = dyn Trait; + // fn foo() -> impl T { .. } + err.span_note(self.tcx.def_span(def_id), "this type alias is unsized"); + return false; + } err.code(E0746); err.primary_message("return type cannot be a trait object without pointer indirection"); diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr index e366dc2d2195..8b8af1ebaed3 100644 --- a/src/tools/clippy/tests/ui/future_not_send.stderr +++ b/src/tools/clippy/tests/ui/future_not_send.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:8:1 + --> tests/ui/future_not_send.rs:8:62 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` + | ^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:11:20 @@ -23,10 +23,10 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:14:1 + --> tests/ui/future_not_send.rs:14:41 | LL | pub async fn public_future(rc: Rc<[u8]>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` + | ^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:17:20 @@ -39,10 +39,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:24:1 + --> tests/ui/future_not_send.rs:24:63 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future2` is not `Send` + | ^^^^ future returned by `private_future2` is not `Send` | note: captured value is not `Send` --> tests/ui/future_not_send.rs:24:26 @@ -58,10 +58,10 @@ LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { = note: `std::cell::Cell` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:30:1 + --> tests/ui/future_not_send.rs:30:42 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future2` is not `Send` + | ^ future returned by `public_future2` is not `Send` | note: captured value is not `Send` --> tests/ui/future_not_send.rs:30:29 @@ -71,10 +71,10 @@ LL | pub async fn public_future2(rc: Rc<[u8]>) {} = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:42:5 + --> tests/ui/future_not_send.rs:42:39 | LL | async fn private_future(&self) -> usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` + | ^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:45:24 @@ -87,10 +87,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:49:5 + --> tests/ui/future_not_send.rs:49:38 | LL | pub async fn public_future(&self) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` + | ^ future returned by `public_future` is not `Send` | note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> tests/ui/future_not_send.rs:49:32 @@ -100,13 +100,10 @@ LL | pub async fn public_future(&self) { = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:61:1 + --> tests/ui/future_not_send.rs:61:37 | -LL | / async fn generic_future(t: T) -> T -LL | | -LL | | where -LL | | T: Send, - | |____________^ future returned by `generic_future` is not `Send` +LL | async fn generic_future(t: T) -> T + | ^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:67:20 @@ -118,10 +115,10 @@ LL | async { true }.await; = note: `T` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:83:1 + --> tests/ui/future_not_send.rs:83:51 | LL | async fn generic_future_always_unsend(_: Rc) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `generic_future_always_unsend` is not `Send` + | ^ future returned by `generic_future_always_unsend` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:86:20 diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs index f96cd989a4ce..fe1322a48d65 100644 --- a/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs @@ -1,8 +1,10 @@ type T = dyn core::fmt::Debug; - +//~^ NOTE this type alias is unsized + fn f() -> T { loop {} } -//~^ ERROR return type cannot be a trait object without pointer indirection -//~| HELP -//~| HELP +//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time +//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` +//~| NOTE doesn't have a size known at compile-time +//~| NOTE the return type of a function must have a statically known size fn main() {} diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr index d67ba7759551..fc7f9f49d165 100644 --- a/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr @@ -1,18 +1,17 @@ -error[E0746]: return type cannot be a trait object without pointer indirection - --> $DIR/dyn-trait-type-alias-return-type.rs:3:11 +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:4:11 | LL | fn f() -> T { loop {} } | ^ doesn't have a size known at compile-time | -help: consider returning an `impl Trait` instead of a `dyn Trait` + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: this type alias is unsized + --> $DIR/dyn-trait-type-alias-return-type.rs:1:1 | -LL | fn f() -> impl T { loop {} } - | ++++ -help: alternatively, box the return type, and wrap all of the returned values in `Box::new` - | -LL | fn f() -> Box { Box::new(loop {}) } - | +++++++ + +++++++++ + +LL | type T = dyn core::fmt::Debug; + | ^^^^^^ + = note: the return type of a function must have a statically known size error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0746`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unsized/issue-91801.rs b/tests/ui/unsized/issue-91801.rs index d906a08a55a2..8b4a3d214d5e 100644 --- a/tests/ui/unsized/issue-91801.rs +++ b/tests/ui/unsized/issue-91801.rs @@ -6,7 +6,7 @@ pub static ALL_VALIDATORS: &[(&'static str, &'static Validator)] = &[("validate that credits and debits balance", &validate_something)]; fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> { - //~^ ERROR return type cannot be a trait object without pointer indirection + //~^ ERROR E0277 return Box::new(move |something: &'_ Something| -> Result<(), ()> { first(something).or_else(|_| second(something)) }); diff --git a/tests/ui/unsized/issue-91801.stderr b/tests/ui/unsized/issue-91801.stderr index 28e10f9caa41..73f9de92458e 100644 --- a/tests/ui/unsized/issue-91801.stderr +++ b/tests/ui/unsized/issue-91801.stderr @@ -1,18 +1,17 @@ -error[E0746]: return type cannot be a trait object without pointer indirection +error[E0277]: the size for values of type `(dyn Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a)` cannot be known at compilation time --> $DIR/issue-91801.rs:8:77 | LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> { | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: consider returning an `impl Trait` instead of a `dyn Trait` + = help: the trait `Sized` is not implemented for `(dyn Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a)` +note: this type alias is unsized + --> $DIR/issue-91801.rs:3:1 | -LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> impl Validator<'a> { - | ++++ -help: alternatively, box the return type, and wrap all of the returned values in `Box::new` - | -LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box> { - | +++++++ + +LL | type Validator<'a> = dyn 'a + Send + Sync + Fn(&'a Something) -> Result<(), ()>; + | ^^^^^^^^^^^^^^^^^^ + = note: the return type of a function must have a statically known size error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0746`. +For more information about this error, try `rustc --explain E0277`. From e2168b1da1fbdeb9bfd5bee53cb358552fdbc3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 5 Nov 2025 18:28:44 +0000 Subject: [PATCH 0477/3801] Point at async fn return type instead of body in E0746 --- .../src/error_reporting/traits/suggestions.rs | 1 + tests/ui/async-await/async-fn/dyn-in-return-type.stderr | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 822025b986b8..e7f588a77f77 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1918,6 +1918,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // and // async fn foo() -> dyn Display Box span = fn_sig.decl.output.span(); + err.span(span); } let body = self.tcx.hir_body_owned_by(obligation.cause.body_id); diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr index bd2ee4c208ca..341d9561fd7a 100644 --- a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr @@ -1,11 +1,8 @@ error[E0746]: return type cannot be a trait object without pointer indirection - --> $DIR/dyn-in-return-type.rs:3:38 + --> $DIR/dyn-in-return-type.rs:3:17 | -LL | async fn f() -> dyn core::fmt::Debug { - | ______________________________________^ -... | -LL | | } - | |_^ doesn't have a size known at compile-time +LL | async fn f() -> dyn core::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ | help: consider returning an `impl Trait` instead of a `dyn Trait` | From 8c63852f1916cad2a9e5b125e879c38ba401bb84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 5 Nov 2025 18:48:40 +0000 Subject: [PATCH 0478/3801] Provide boxing suggestion for `type Alias = dyn Trait` return type --- .../src/error_reporting/traits/suggestions.rs | 11 +++++++++++ .../dyn-trait-type-alias-return-type.fixed | 18 ++++++++++++++++++ .../dyn-trait-type-alias-return-type.rs | 10 +++++++++- .../dyn-trait-type-alias-return-type.stderr | 19 ++++++++++++++++--- tests/ui/unsized/issue-91801.stderr | 4 ++++ 5 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index e7f588a77f77..5ef6d05c419c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1897,6 +1897,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // type T = dyn Trait; // fn foo() -> impl T { .. } err.span_note(self.tcx.def_span(def_id), "this type alias is unsized"); + err.multipart_suggestion( + format!( + "consider boxing the return type, and wrapping all of the returned values in \ + `Box::new`", + ), + vec![ + (ty.span.shrink_to_lo(), "Box<".to_string()), + (ty.span.shrink_to_hi(), ">".to_string()), + ], + Applicability::MaybeIncorrect, + ); return false; } diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed b/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed new file mode 100644 index 000000000000..93472f808a8a --- /dev/null +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed @@ -0,0 +1,18 @@ +//@ run-rustfix +type T = dyn core::fmt::Debug; +//~^ NOTE this type alias is unsized + +fn f() -> Box { loop {} } +//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time +//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` +//~| NOTE doesn't have a size known at compile-time +//~| NOTE the return type of a function must have a statically known size +//~| HELP consider boxing the return type + +fn main() { + f(); + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size +} diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs index fe1322a48d65..da9f8d07f8e0 100644 --- a/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs @@ -1,3 +1,4 @@ +//@ run-rustfix type T = dyn core::fmt::Debug; //~^ NOTE this type alias is unsized @@ -6,5 +7,12 @@ fn f() -> T { loop {} } //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` //~| NOTE doesn't have a size known at compile-time //~| NOTE the return type of a function must have a statically known size +//~| HELP consider boxing the return type -fn main() {} +fn main() { + f(); + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size +} diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr index fc7f9f49d165..658abbe8f780 100644 --- a/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr @@ -1,17 +1,30 @@ error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time - --> $DIR/dyn-trait-type-alias-return-type.rs:4:11 + --> $DIR/dyn-trait-type-alias-return-type.rs:5:11 | LL | fn f() -> T { loop {} } | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` note: this type alias is unsized - --> $DIR/dyn-trait-type-alias-return-type.rs:1:1 + --> $DIR/dyn-trait-type-alias-return-type.rs:2:1 | LL | type T = dyn core::fmt::Debug; | ^^^^^^ = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn f() -> Box { loop {} } + | ++++ + -error: aborting due to 1 previous error +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:13:5 + | +LL | f(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` + = note: the return type of a function must have a statically known size + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unsized/issue-91801.stderr b/tests/ui/unsized/issue-91801.stderr index 73f9de92458e..192cdc767dd9 100644 --- a/tests/ui/unsized/issue-91801.stderr +++ b/tests/ui/unsized/issue-91801.stderr @@ -11,6 +11,10 @@ note: this type alias is unsized LL | type Validator<'a> = dyn 'a + Send + Sync + Fn(&'a Something) -> Result<(), ()>; | ^^^^^^^^^^^^^^^^^^ = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box> { + | ++++ + error: aborting due to 1 previous error From f7eaaf79e0520547b128a3066b5a59980f3b5844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 5 Nov 2025 19:59:08 +0000 Subject: [PATCH 0479/3801] Account for async fn in traits and impls --- .../src/error_reporting/traits/suggestions.rs | 13 ++++-- .../async-fn/dyn-in-return-type.fixed | 30 +++++++++++++ .../async-fn/dyn-in-return-type.rs | 24 ++++++++++- .../async-fn/dyn-in-return-type.stderr | 36 +++++++++++++++- .../dyn-trait-type-alias-return-type.fixed | 21 ++++++++++ .../dyn-trait-type-alias-return-type.rs | 21 ++++++++++ .../dyn-trait-type-alias-return-type.stderr | 42 +++++++++++++++++-- 7 files changed, 176 insertions(+), 11 deletions(-) create mode 100644 tests/ui/async-await/async-fn/dyn-in-return-type.fixed diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 5ef6d05c419c..fd845e31c909 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1886,7 +1886,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let ty::Dynamic(_, _) = trait_pred.self_ty().skip_binder().kind() else { return false; }; - if let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) = + if let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) + | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. }) + | Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(fn_sig, _), .. }) = self.tcx.hir_node_by_def_id(obligation.cause.body_id) && let hir::FnRetTy::Return(ty) = fn_sig.decl.output && let hir::TyKind::Path(qpath) = ty.kind @@ -1918,11 +1920,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut span = obligation.cause.span; if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id) && let parent = self.tcx.parent(obligation.cause.body_id.into()) - && let DefKind::Fn = self.tcx.def_kind(parent) + && let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(parent) && self.tcx.asyncness(parent).is_async() && let Some(parent) = parent.as_local() - && let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) = - self.tcx.hir_node_by_def_id(parent) + && let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) + | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. }) + | Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(fn_sig, _), .. + }) = self.tcx.hir_node_by_def_id(parent) { // Do not suggest (#147894) // async fn foo() -> dyn Display impl { .. } diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.fixed b/tests/ui/async-await/async-fn/dyn-in-return-type.fixed new file mode 100644 index 000000000000..6a717f628460 --- /dev/null +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.fixed @@ -0,0 +1,30 @@ +//@ edition:2024 +//@ run-rustfix + +async fn f() -> Box { +//~^ ERROR return type cannot be a trait object without pointer indirection +//~| HELP consider returning an `impl Trait` instead of a `dyn Trait` +//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") +} +trait T { + async fn f(&self) -> Box { + //~^ ERROR return type cannot be a trait object without pointer indirection + //~| HELP consider returning an `impl Trait` instead of a `dyn Trait` + //~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") + } +} +impl T for () { + async fn f(&self) -> Box { + //~^ ERROR return type cannot be a trait object without pointer indirection + //~| HELP consider returning an `impl Trait` instead of a `dyn Trait` + //~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") + } +} + +fn main() { + let _ = f(); + let _ = ().f(); +} diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.rs b/tests/ui/async-await/async-fn/dyn-in-return-type.rs index ec793bf80f28..47d5e371f55f 100644 --- a/tests/ui/async-await/async-fn/dyn-in-return-type.rs +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.rs @@ -1,10 +1,30 @@ //@ edition:2024 +//@ run-rustfix async fn f() -> dyn core::fmt::Debug { //~^ ERROR return type cannot be a trait object without pointer indirection //~| HELP consider returning an `impl Trait` instead of a `dyn Trait` //~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` - loop {} + Box::new("") +} +trait T { + async fn f(&self) -> dyn core::fmt::Debug { + //~^ ERROR return type cannot be a trait object without pointer indirection + //~| HELP consider returning an `impl Trait` instead of a `dyn Trait` + //~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") + } +} +impl T for () { + async fn f(&self) -> dyn core::fmt::Debug { + //~^ ERROR return type cannot be a trait object without pointer indirection + //~| HELP consider returning an `impl Trait` instead of a `dyn Trait` + //~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") + } } -fn main() {} +fn main() { + let _ = f(); + let _ = ().f(); +} diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr index 341d9561fd7a..0d8a92d33cf9 100644 --- a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr @@ -1,5 +1,5 @@ error[E0746]: return type cannot be a trait object without pointer indirection - --> $DIR/dyn-in-return-type.rs:3:17 + --> $DIR/dyn-in-return-type.rs:4:17 | LL | async fn f() -> dyn core::fmt::Debug { | ^^^^^^^^^^^^^^^^^^^^ @@ -14,6 +14,38 @@ help: alternatively, box the return type, and wrap all of the returned values in LL | async fn f() -> Box { | ++++ + -error: aborting due to 1 previous error +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-in-return-type.rs:11:26 + | +LL | async fn f(&self) -> dyn core::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + | +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL - async fn f(&self) -> dyn core::fmt::Debug { +LL + async fn f(&self) -> impl core::fmt::Debug { + | +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL | async fn f(&self) -> Box { + | ++++ + + +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-in-return-type.rs:19:26 + | +LL | async fn f(&self) -> dyn core::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + | +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL - async fn f(&self) -> dyn core::fmt::Debug { +LL + async fn f(&self) -> impl core::fmt::Debug { + | +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL | async fn f(&self) -> Box { + | ++++ + + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0746`. diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed b/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed index 93472f808a8a..ba94e1967df3 100644 --- a/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed @@ -1,6 +1,8 @@ //@ run-rustfix type T = dyn core::fmt::Debug; //~^ NOTE this type alias is unsized +//~| NOTE this type alias is unsized +//~| NOTE this type alias is unsized fn f() -> Box { loop {} } //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time @@ -9,10 +11,29 @@ fn f() -> Box { loop {} } //~| NOTE the return type of a function must have a statically known size //~| HELP consider boxing the return type +trait X { + fn f(&self) -> Box { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +impl X for () { + fn f(&self) -> Box { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + fn main() { f(); //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` //~| NOTE doesn't have a size known at compile-time //~| NOTE the return type of a function must have a statically known size + ().f(); } diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs index da9f8d07f8e0..76f6e7c44342 100644 --- a/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs @@ -1,6 +1,8 @@ //@ run-rustfix type T = dyn core::fmt::Debug; //~^ NOTE this type alias is unsized +//~| NOTE this type alias is unsized +//~| NOTE this type alias is unsized fn f() -> T { loop {} } //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time @@ -9,10 +11,29 @@ fn f() -> T { loop {} } //~| NOTE the return type of a function must have a statically known size //~| HELP consider boxing the return type +trait X { + fn f(&self) -> T { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +impl X for () { + fn f(&self) -> T { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + fn main() { f(); //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` //~| NOTE doesn't have a size known at compile-time //~| NOTE the return type of a function must have a statically known size + ().f(); } diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr index 658abbe8f780..bb6951687048 100644 --- a/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time - --> $DIR/dyn-trait-type-alias-return-type.rs:5:11 + --> $DIR/dyn-trait-type-alias-return-type.rs:7:11 | LL | fn f() -> T { loop {} } | ^ doesn't have a size known at compile-time @@ -17,7 +17,43 @@ LL | fn f() -> Box { loop {} } | ++++ + error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time - --> $DIR/dyn-trait-type-alias-return-type.rs:13:5 + --> $DIR/dyn-trait-type-alias-return-type.rs:24:20 + | +LL | fn f(&self) -> T { loop {} } + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: this type alias is unsized + --> $DIR/dyn-trait-type-alias-return-type.rs:2:1 + | +LL | type T = dyn core::fmt::Debug; + | ^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn f(&self) -> Box { loop {} } + | ++++ + + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:15:20 + | +LL | fn f(&self) -> T { loop {} } + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: this type alias is unsized + --> $DIR/dyn-trait-type-alias-return-type.rs:2:1 + | +LL | type T = dyn core::fmt::Debug; + | ^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn f(&self) -> Box { loop {} } + | ++++ + + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:33:5 | LL | f(); | ^^^ doesn't have a size known at compile-time @@ -25,6 +61,6 @@ LL | f(); = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` = note: the return type of a function must have a statically known size -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. From 94aa13a09c940202da24ad0a1ffcd986e4df2df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 4 Nov 2025 18:41:04 +0000 Subject: [PATCH 0480/3801] Recognize `type Alias = dyn Trait` in `fn` return types ``` error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time --> $DIR/dyn-trait-type-alias-return-type.rs:4:11 | LL | fn f() -> T { loop {} } | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` note: this type alias is unsized --> $DIR/dyn-trait-type-alias-return-type.rs:1:1 | LL | type T = dyn core::fmt::Debug; | ^^^^^^ = note: the return type of a function must have a statically known size ``` --- tests/ui/future_not_send.stderr | 37 +++++++++++++++------------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/tests/ui/future_not_send.stderr b/tests/ui/future_not_send.stderr index e366dc2d2195..8b8af1ebaed3 100644 --- a/tests/ui/future_not_send.stderr +++ b/tests/ui/future_not_send.stderr @@ -1,8 +1,8 @@ error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:8:1 + --> tests/ui/future_not_send.rs:8:62 | LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` + | ^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:11:20 @@ -23,10 +23,10 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell) -> bool { = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:14:1 + --> tests/ui/future_not_send.rs:14:41 | LL | pub async fn public_future(rc: Rc<[u8]>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` + | ^ future returned by `public_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:17:20 @@ -39,10 +39,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:24:1 + --> tests/ui/future_not_send.rs:24:63 | LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future2` is not `Send` + | ^^^^ future returned by `private_future2` is not `Send` | note: captured value is not `Send` --> tests/ui/future_not_send.rs:24:26 @@ -58,10 +58,10 @@ LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell) -> bool { = note: `std::cell::Cell` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:30:1 + --> tests/ui/future_not_send.rs:30:42 | LL | pub async fn public_future2(rc: Rc<[u8]>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future2` is not `Send` + | ^ future returned by `public_future2` is not `Send` | note: captured value is not `Send` --> tests/ui/future_not_send.rs:30:29 @@ -71,10 +71,10 @@ LL | pub async fn public_future2(rc: Rc<[u8]>) {} = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:42:5 + --> tests/ui/future_not_send.rs:42:39 | LL | async fn private_future(&self) -> usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send` + | ^^^^^ future returned by `private_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:45:24 @@ -87,10 +87,10 @@ LL | async { true }.await; = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:49:5 + --> tests/ui/future_not_send.rs:49:38 | LL | pub async fn public_future(&self) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send` + | ^ future returned by `public_future` is not `Send` | note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> tests/ui/future_not_send.rs:49:32 @@ -100,13 +100,10 @@ LL | pub async fn public_future(&self) { = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:61:1 + --> tests/ui/future_not_send.rs:61:37 | -LL | / async fn generic_future(t: T) -> T -LL | | -LL | | where -LL | | T: Send, - | |____________^ future returned by `generic_future` is not `Send` +LL | async fn generic_future(t: T) -> T + | ^ future returned by `generic_future` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:67:20 @@ -118,10 +115,10 @@ LL | async { true }.await; = note: `T` doesn't implement `std::marker::Sync` error: future cannot be sent between threads safely - --> tests/ui/future_not_send.rs:83:1 + --> tests/ui/future_not_send.rs:83:51 | LL | async fn generic_future_always_unsend(_: Rc) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `generic_future_always_unsend` is not `Send` + | ^ future returned by `generic_future_always_unsend` is not `Send` | note: future is not `Send` as this value is used across an await --> tests/ui/future_not_send.rs:86:20 From 06500aa2ddba47bc3511236dcdca640c83ee5252 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 9 Dec 2025 17:59:24 +0100 Subject: [PATCH 0481/3801] Add message when running clippy with `--no-default-features` for cg_gcc --- src/bootstrap/src/core/build_steps/clippy.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index f80cf58fbb2a..085c2d952e30 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -394,6 +394,7 @@ impl Step for CodegenGcc { &[], ); self.build_compiler.configure_cargo(&mut cargo); + println!("Now running clippy on `rustc_codegen_gcc` with `--no-default-features`"); cargo.arg("--no-default-features"); run_cargo(builder, cargo, args, &stamp, vec![], true, false); } From 6cd44a472c7a9374c975921815cf8a88029108d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Dec 2025 16:20:07 +0000 Subject: [PATCH 0482/3801] Make typo in field and name suggestions verbose --- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 2 +- .../diagnostic-derive.stderr | 24 +++- .../argument-suggestions/issue-109831.stderr | 8 +- tests/ui/associated-item/issue-87638.stderr | 22 +-- tests/ui/associated-types/issue-19883.stderr | 11 +- tests/ui/associated-types/issue-22037.stderr | 11 +- .../attributes/align-on-fields-143987.stderr | 8 +- ...ruct-pattern-box-pattern-ice-121463.stderr | 20 +-- tests/ui/closures/issue-90871.stderr | 6 +- .../ui-testing-optout.stderr | 16 ++- .../generic_const_exprs/error_in_ty.stderr | 8 +- .../unevaluated-const-ice-119731.stderr | 24 +++- ...arent_generics_of_nested_in_default.stderr | 8 +- .../ice-unhandled-type-122191.stderr | 8 +- .../const-pattern-rewrite-error-32086.stderr | 16 ++- tests/ui/delegation/bad-resolve.stderr | 16 ++- .../deriving-meta-unknown-trait.stderr | 14 +- tests/ui/did_you_mean/println-typo.stderr | 7 +- .../typo-suggestion-improvement-46332.stderr | 8 +- tests/ui/expr/if/bad-if-let-suggestion.stderr | 32 ++++- .../format-args-capture-issue-102057.stderr | 40 +++++- .../format-args-capture-issue-94010.stderr | 16 ++- .../equality-bound.stderr | 59 ++++++-- .../hygiene/rustc-macro-transparency.stderr | 11 +- tests/ui/imports/glob-resolve1.stderr | 21 ++- tests/ui/macros/macro-context.stderr | 6 +- tests/ui/macros/macro-name-typo.stderr | 7 +- .../macros/macro-path-prelude-fail-3.stderr | 7 +- tests/ui/macros/macro-reexport-removed.stderr | 8 +- tests/ui/macros/macro_undefined.stderr | 7 +- tests/ui/parser/emoji-identifiers.stderr | 8 +- tests/ui/parser/kw-in-trait-bounds.stderr | 32 ++++- .../ui/parser/recover/raw-no-const-mut.stderr | 8 +- ...h-enum-struct-variant-field-missing.stderr | 11 +- .../ui/pattern/pattern-error-continue.stderr | 11 +- .../name-resolution.stderr | 120 ++++++++++++++-- ...n-with-missing-fields-resolve-error.stderr | 8 +- .../proc-macro/gen-macro-rules-hygiene.stderr | 14 +- .../ui/proc-macro/lints_in_proc_macros.stderr | 7 +- tests/ui/proc-macro/mixed-site-span.stderr | 14 +- .../ui/proc-macro/parent-source-spans.stderr | 21 ++- tests/ui/proc-macro/resolve-error.stderr | 76 +++++++++-- tests/ui/regions/outlives-with-missing.stderr | 8 +- tests/ui/resolve/112590-2.stderr | 10 +- tests/ui/resolve/issue-10200.stderr | 7 +- tests/ui/resolve/issue-49074.stderr | 8 +- tests/ui/resolve/levenshtein.stderr | 53 +++++++- tests/ui/resolve/privacy-enum-ctor.stderr | 28 +++- tests/ui/resolve/privacy-struct-ctor.stderr | 11 +- ...uggest-path-instead-of-mod-dot-item.stderr | 30 ++-- tests/ui/resolve/tuple-struct-alias.stderr | 8 +- ...e-with-name-similar-to-struct-field.stderr | 23 +++- .../typo-suggestion-mistyped-in-path.stderr | 30 ++-- tests/ui/span/suggestion-raw-68962.stderr | 16 ++- tests/ui/span/typo-suggestion.stderr | 8 +- .../stability-attribute/issue-109177.stderr | 8 +- .../struct-fields-shorthand-unresolved.stderr | 8 +- tests/ui/suggestions/attribute-typos.stderr | 21 ++- .../case-difference-suggestions.stderr | 128 +++++++++++++++--- ...-to-add-suggestions-with-no-changes.stderr | 7 +- .../issue-66968-suggest-sorted-words.stderr | 8 +- .../assoc_type_bound_with_struct.stderr | 6 +- .../ice-120503-async-const-method.stderr | 8 +- .../mismatched_generic_args.stderr | 8 +- tests/ui/traits/impl-for-module.stderr | 8 +- .../type-error-drop-elaboration.stderr | 8 +- tests/ui/type/issue-7607-1.stderr | 7 +- ...114423-ice-regression-in-suggestion.stderr | 8 +- tests/ui/typeck/issue-120856.stderr | 19 +-- tests/ui/typeck/issue-83693.stderr | 6 +- tests/ui/typeck/issue-88844.stderr | 7 +- tests/ui/ufcs/ufcs-partially-resolved.stderr | 110 ++++++++++++--- ...mismatch-closure-from-another-scope.stderr | 8 +- 74 files changed, 1165 insertions(+), 241 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 0e9ff962435f..06fd89837d51 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2296,7 +2296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let suggested_name = find_best_match_for_name(&[field.name], pat_field.ident.name, None); if let Some(suggested_name) = suggested_name { - err.span_suggestion( + err.span_suggestion_verbose( pat_field.ident.span, "a field with a similar name exists", suggested_name, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 33c111708e36..44d71947db85 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1963,7 +1963,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; (span, msg, suggestion.candidate.to_ident_string()) }; - err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect); + err.span_suggestion_verbose(span, msg, sugg, Applicability::MaybeIncorrect); true } diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 59b48e9f0ecc..8a0e753a9c52 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -570,19 +570,37 @@ error: cannot find attribute `warn_` in this scope --> $DIR/diagnostic-derive.rs:590:3 | LL | #[warn_(no_crate_example, code = E0123)] - | ^^^^^ help: a built-in attribute with a similar name exists: `warn` + | ^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[warn_(no_crate_example, code = E0123)] +LL + #[warn(no_crate_example, code = E0123)] + | error: cannot find attribute `lint` in this scope --> $DIR/diagnostic-derive.rs:597:3 | LL | #[lint(no_crate_example, code = E0123)] - | ^^^^ help: a built-in attribute with a similar name exists: `link` + | ^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[lint(no_crate_example, code = E0123)] +LL + #[link(no_crate_example, code = E0123)] + | error: cannot find attribute `lint` in this scope --> $DIR/diagnostic-derive.rs:604:3 | LL | #[lint(no_crate_example, code = E0123)] - | ^^^^ help: a built-in attribute with a similar name exists: `link` + | ^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[lint(no_crate_example, code = E0123)] +LL + #[link(no_crate_example, code = E0123)] + | error: cannot find attribute `multipart_suggestion` in this scope --> $DIR/diagnostic-derive.rs:644:3 diff --git a/tests/ui/argument-suggestions/issue-109831.stderr b/tests/ui/argument-suggestions/issue-109831.stderr index 6c25236ebb1b..852016c983f7 100644 --- a/tests/ui/argument-suggestions/issue-109831.stderr +++ b/tests/ui/argument-suggestions/issue-109831.stderr @@ -24,7 +24,13 @@ LL | struct A; | --------- similarly named unit struct `A` defined here ... LL | f(A, A, B, C); - | ^ help: a unit struct with a similar name exists: `A` + | ^ + | +help: a unit struct with a similar name exists + | +LL - f(A, A, B, C); +LL + f(A, A, B, A); + | error[E0061]: this function takes 3 arguments but 4 arguments were supplied --> $DIR/issue-109831.rs:7:5 diff --git a/tests/ui/associated-item/issue-87638.stderr b/tests/ui/associated-item/issue-87638.stderr index cf6083444b0e..cce20318a23b 100644 --- a/tests/ui/associated-item/issue-87638.stderr +++ b/tests/ui/associated-item/issue-87638.stderr @@ -5,10 +5,13 @@ LL | type Target; | ------------ associated type `Target` defined here ... LL | let _: ::Output; - | ^^^^^^ - | | - | not found in `Trait` - | help: maybe you meant this associated type: `Target` + | ^^^^^^ not found in `Trait` + | +help: maybe you meant this associated type + | +LL - let _: ::Output; +LL + let _: ::Target; + | error[E0576]: cannot find method or associated constant `BAR` in trait `Trait` --> $DIR/issue-87638.rs:20:27 @@ -17,10 +20,13 @@ LL | const FOO: usize; | ----------------- associated constant `FOO` defined here ... LL | let _ = ::BAR; - | ^^^ - | | - | not found in `Trait` - | help: maybe you meant this associated constant: `FOO` + | ^^^ not found in `Trait` + | +help: maybe you meant this associated constant + | +LL - let _ = ::BAR; +LL + let _ = ::FOO; + | error: aborting due to 2 previous errors diff --git a/tests/ui/associated-types/issue-19883.stderr b/tests/ui/associated-types/issue-19883.stderr index 35184e852cfe..435c2933e361 100644 --- a/tests/ui/associated-types/issue-19883.stderr +++ b/tests/ui/associated-types/issue-19883.stderr @@ -5,10 +5,13 @@ LL | type Output; | ------------ associated type `Output` defined here ... LL | >::Dst - | ^^^ - | | - | not found in `From` - | help: maybe you meant this associated type: `Output` + | ^^^ not found in `From` + | +help: maybe you meant this associated type + | +LL - >::Dst +LL + >::Output + | error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/issue-22037.stderr b/tests/ui/associated-types/issue-22037.stderr index b02dad97d354..0b5f18f81c0b 100644 --- a/tests/ui/associated-types/issue-22037.stderr +++ b/tests/ui/associated-types/issue-22037.stderr @@ -4,10 +4,13 @@ error[E0576]: cannot find associated type `X` in trait `A` LL | type Output; | ------------ associated type `Output` defined here LL | fn a(&self) -> ::X; - | ^ - | | - | not found in `A` - | help: maybe you meant this associated type: `Output` + | ^ not found in `A` + | +help: maybe you meant this associated type + | +LL - fn a(&self) -> ::X; +LL + fn a(&self) -> ::Output; + | error: aborting due to 1 previous error diff --git a/tests/ui/attributes/align-on-fields-143987.stderr b/tests/ui/attributes/align-on-fields-143987.stderr index c95543a74c1a..1ffbf4a37cb9 100644 --- a/tests/ui/attributes/align-on-fields-143987.stderr +++ b/tests/ui/attributes/align-on-fields-143987.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find type `usize8` in this scope --> $DIR/align-on-fields-143987.rs:17:8 | LL | x: usize8, - | ^^^^^^ help: a builtin type with a similar name exists: `usize` + | ^^^^^^ + | +help: a builtin type with a similar name exists + | +LL - x: usize8, +LL + x: usize, + | error: `#[rustc_align]` attribute cannot be used on struct fields --> $DIR/align-on-fields-143987.rs:10:5 diff --git a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr index 349546606a57..ae5c67eae9a6 100644 --- a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr +++ b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr @@ -2,19 +2,23 @@ error[E0433]: failed to resolve: use of undeclared type `E` --> $DIR/non-ADT-struct-pattern-box-pattern-ice-121463.rs:6:17 | LL | let mut a = E::StructVar { boxed: Box::new(5_i32) }; - | ^ - | | - | use of undeclared type `E` - | help: a trait with a similar name exists: `Eq` + | ^ use of undeclared type `E` + | +help: a trait with a similar name exists + | +LL | let mut a = Eq::StructVar { boxed: Box::new(5_i32) }; + | + error[E0433]: failed to resolve: use of undeclared type `E` --> $DIR/non-ADT-struct-pattern-box-pattern-ice-121463.rs:9:9 | LL | E::StructVar { box boxed } => { } - | ^ - | | - | use of undeclared type `E` - | help: a trait with a similar name exists: `Eq` + | ^ use of undeclared type `E` + | +help: a trait with a similar name exists + | +LL | Eq::StructVar { box boxed } => { } + | + error: aborting due to 2 previous errors diff --git a/tests/ui/closures/issue-90871.stderr b/tests/ui/closures/issue-90871.stderr index 071694def413..140f24982140 100644 --- a/tests/ui/closures/issue-90871.stderr +++ b/tests/ui/closures/issue-90871.stderr @@ -2,11 +2,15 @@ error[E0425]: cannot find type `n` in this scope --> $DIR/issue-90871.rs:4:22 | LL | type_ascribe!(2, n([u8; || 1])) - | ^ help: a trait with a similar name exists: `Fn` + | ^ | --> $SRC_DIR/core/src/ops/function.rs:LL:COL | = note: similarly named trait `Fn` defined here +help: a trait with a similar name exists + | +LL | type_ascribe!(2, Fn([u8; || 1])) + | + error[E0308]: mismatched types --> $DIR/issue-90871.rs:4:29 diff --git a/tests/ui/compiletest-self-test/ui-testing-optout.stderr b/tests/ui/compiletest-self-test/ui-testing-optout.stderr index b0d495edfb62..6a4950c55afd 100644 --- a/tests/ui/compiletest-self-test/ui-testing-optout.stderr +++ b/tests/ui/compiletest-self-test/ui-testing-optout.stderr @@ -11,7 +11,13 @@ error[E0425]: cannot find type `D` in this scope | ----------- similarly named type alias `A` defined here ... 7 | type C = D; - | ^ help: a type alias with a similar name exists: `A` + | ^ + | +help: a type alias with a similar name exists + | +7 - type C = D; +7 + type C = A; + | error[E0425]: cannot find type `F` in this scope --> $DIR/ui-testing-optout.rs:92:10 @@ -20,7 +26,13 @@ error[E0425]: cannot find type `F` in this scope | ----------- similarly named type alias `A` defined here ... 92 | type E = F; - | ^ help: a type alias with a similar name exists: `A` + | ^ + | +help: a type alias with a similar name exists + | +92 - type E = F; +92 + type E = A; + | error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr index d822fa5894a5..58f0d31b0960 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr @@ -2,9 +2,15 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/error_in_ty.rs:6:31 | LL | pub struct A {} - | - ^ help: a const parameter with a similar name exists: `z` + | - ^ | | | similarly named const parameter `z` defined here + | +help: a const parameter with a similar name exists + | +LL - pub struct A {} +LL + pub struct A {} + | error: `[usize; x]` is forbidden as the type of a const generic parameter --> $DIR/error_in_ty.rs:6:23 diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index d3a7e286fdd6..b547bdd7d07a 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -20,7 +20,13 @@ LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here ... LL | pub const fn v21() -> v18 {} - | ^^^ help: a type alias with a similar name exists: `v11` + | ^^^ + | +help: a type alias with a similar name exists + | +LL - pub const fn v21() -> v18 {} +LL + pub const fn v21() -> v11 {} + | error[E0425]: cannot find type `v18` in this scope --> $DIR/unevaluated-const-ice-119731.rs:35:31 @@ -29,7 +35,13 @@ LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here ... LL | pub const fn v21() -> v18 { - | ^^^ help: a type alias with a similar name exists: `v11` + | ^^^ + | +help: a type alias with a similar name exists + | +LL - pub const fn v21() -> v18 { +LL + pub const fn v21() -> v11 { + | error[E0422]: cannot find struct, variant or union type `v18` in this scope --> $DIR/unevaluated-const-ice-119731.rs:37:13 @@ -38,7 +50,13 @@ LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here ... LL | v18 { _p: () } - | ^^^ help: a type alias with a similar name exists: `v11` + | ^^^ + | +help: a type alias with a similar name exists + | +LL - v18 { _p: () } +LL + v11 { _p: () } + | warning: type `v11` should have an upper camel case name --> $DIR/unevaluated-const-ice-119731.rs:9:14 diff --git a/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr b/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr index 00eeecb9595f..9452e747a755 100644 --- a/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr +++ b/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr @@ -8,9 +8,15 @@ error[E0425]: cannot find value `B` in this scope --> $DIR/parent_generics_of_nested_in_default.rs:1:30 | LL | impl Tr {} - | - ^ help: a const parameter with a similar name exists: `A` + | - ^ | | | similarly named const parameter `A` defined here + | +help: a const parameter with a similar name exists + | +LL - impl Tr {} +LL + impl Tr {} + | error: defaults for generic parameters are not allowed here --> $DIR/parent_generics_of_nested_in_default.rs:1:6 diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr index bcb6a80a8f2b..5e2e3524ae9e 100644 --- a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr +++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr @@ -22,10 +22,16 @@ error[E0425]: cannot find function `value` in this scope --> $DIR/ice-unhandled-type-122191.rs:9:5 | LL | value() - | ^^^^^ help: a constant with a similar name exists: `VALUE` + | ^^^^^ ... LL | const VALUE: Foo = foo(); | ------------------------- similarly named constant `VALUE` defined here + | +help: a constant with a similar name exists + | +LL - value() +LL + VALUE() + | error[E0308]: mismatched types --> $DIR/ice-unhandled-type-122191.rs:17:9 diff --git a/tests/ui/consts/const-pattern-rewrite-error-32086.stderr b/tests/ui/consts/const-pattern-rewrite-error-32086.stderr index 47616b066321..9c8ac7008709 100644 --- a/tests/ui/consts/const-pattern-rewrite-error-32086.stderr +++ b/tests/ui/consts/const-pattern-rewrite-error-32086.stderr @@ -5,7 +5,13 @@ LL | struct S(u8); | ------------- similarly named tuple struct `S` defined here ... LL | let C(a) = S(11); - | ^ help: a tuple struct with a similar name exists: `S` + | ^ + | +help: a tuple struct with a similar name exists + | +LL - let C(a) = S(11); +LL + let S(a) = S(11); + | error[E0532]: expected tuple struct or tuple variant, found constant `C` --> $DIR/const-pattern-rewrite-error-32086.rs:7:9 @@ -14,7 +20,13 @@ LL | struct S(u8); | ------------- similarly named tuple struct `S` defined here ... LL | let C(..) = S(11); - | ^ help: a tuple struct with a similar name exists: `S` + | ^ + | +help: a tuple struct with a similar name exists + | +LL - let C(..) = S(11); +LL + let S(..) = S(11); + | error: aborting due to 2 previous errors diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index fc6811292a6f..4c015c226b18 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -53,7 +53,13 @@ LL | fn bar() {} | -------- similarly named associated function `bar` defined here ... LL | reuse ::baz; - | ^^^ help: an associated function with a similar name exists: `bar` + | ^^^ + | +help: an associated function with a similar name exists + | +LL - reuse ::baz; +LL + reuse ::bar; + | error[E0425]: cannot find function `foo` in this scope --> $DIR/bad-resolve.rs:35:11 @@ -68,7 +74,13 @@ LL | fn foo(&self, x: i32) -> i32 { x } | ---------------------------- similarly named associated function `foo` defined here ... LL | reuse Trait::foo2 { self.0 } - | ^^^^ help: an associated function with a similar name exists: `foo` + | ^^^^ + | +help: an associated function with a similar name exists + | +LL - reuse Trait::foo2 { self.0 } +LL + reuse Trait::foo { self.0 } + | error[E0046]: not all trait items implemented, missing: `Type` --> $DIR/bad-resolve.rs:22:1 diff --git a/tests/ui/derives/deriving-meta-unknown-trait.stderr b/tests/ui/derives/deriving-meta-unknown-trait.stderr index 7ee90ae9eb0c..1cf31502dfb8 100644 --- a/tests/ui/derives/deriving-meta-unknown-trait.stderr +++ b/tests/ui/derives/deriving-meta-unknown-trait.stderr @@ -2,23 +2,33 @@ error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] - | ^^^ help: a derive macro with a similar name exists: `Eq` + | ^^^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named derive macro `Eq` defined here +help: a derive macro with a similar name exists + | +LL - #[derive(Eqr)] +LL + #[derive(Eq)] + | error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] - | ^^^ help: a derive macro with a similar name exists: `Eq` + | ^^^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named derive macro `Eq` defined here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: a derive macro with a similar name exists + | +LL - #[derive(Eqr)] +LL + #[derive(Eq)] + | error: aborting due to 2 previous errors diff --git a/tests/ui/did_you_mean/println-typo.stderr b/tests/ui/did_you_mean/println-typo.stderr index 7dd6fbba620b..471d49b6ee2e 100644 --- a/tests/ui/did_you_mean/println-typo.stderr +++ b/tests/ui/did_you_mean/println-typo.stderr @@ -2,11 +2,16 @@ error: cannot find macro `prinltn` in this scope --> $DIR/println-typo.rs:4:5 | LL | prinltn!(); - | ^^^^^^^ help: a macro with a similar name exists: `println` + | ^^^^^^^ | --> $SRC_DIR/std/src/macros.rs:LL:COL | = note: similarly named macro `println` defined here +help: a macro with a similar name exists + | +LL - prinltn!(); +LL + println!(); + | error: aborting due to 1 previous error diff --git a/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr b/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr index 502f81518785..d677152314dc 100644 --- a/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr +++ b/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr @@ -5,7 +5,13 @@ LL | struct TyUint {} | ------------- similarly named struct `TyUint` defined here ... LL | TyUInt {}; - | ^^^^^^ help: a struct with a similar name exists (notice the capitalization): `TyUint` + | ^^^^^^ + | +help: a struct with a similar name exists (notice the capitalization) + | +LL - TyUInt {}; +LL + TyUint {}; + | error: aborting due to 1 previous error diff --git a/tests/ui/expr/if/bad-if-let-suggestion.stderr b/tests/ui/expr/if/bad-if-let-suggestion.stderr index 0d1f895bd82b..4244a3bb06ee 100644 --- a/tests/ui/expr/if/bad-if-let-suggestion.stderr +++ b/tests/ui/expr/if/bad-if-let-suggestion.stderr @@ -27,7 +27,13 @@ LL | fn a() { | ------ similarly named function `a` defined here ... LL | if (i + j) = i {} - | ^ help: a function with a similar name exists: `a` + | ^ + | +help: a function with a similar name exists + | +LL - if (i + j) = i {} +LL + if (a + j) = i {} + | error[E0425]: cannot find value `j` in this scope --> $DIR/bad-if-let-suggestion.rs:9:13 @@ -36,7 +42,13 @@ LL | fn a() { | ------ similarly named function `a` defined here ... LL | if (i + j) = i {} - | ^ help: a function with a similar name exists: `a` + | ^ + | +help: a function with a similar name exists + | +LL - if (i + j) = i {} +LL + if (i + a) = i {} + | error[E0425]: cannot find value `i` in this scope --> $DIR/bad-if-let-suggestion.rs:9:18 @@ -45,7 +57,13 @@ LL | fn a() { | ------ similarly named function `a` defined here ... LL | if (i + j) = i {} - | ^ help: a function with a similar name exists: `a` + | ^ + | +help: a function with a similar name exists + | +LL - if (i + j) = i {} +LL + if (i + j) = a {} + | error[E0425]: cannot find value `x` in this scope --> $DIR/bad-if-let-suggestion.rs:16:8 @@ -54,7 +72,13 @@ LL | fn a() { | ------ similarly named function `a` defined here ... LL | if x[0] = 1 {} - | ^ help: a function with a similar name exists: `a` + | ^ + | +help: a function with a similar name exists + | +LL - if x[0] = 1 {} +LL + if a[0] = 1 {} + | error[E0308]: mismatched types --> $DIR/bad-if-let-suggestion.rs:2:8 diff --git a/tests/ui/fmt/format-args-capture-issue-102057.stderr b/tests/ui/fmt/format-args-capture-issue-102057.stderr index f2d625e7f8dc..9a5bc5365df7 100644 --- a/tests/ui/fmt/format-args-capture-issue-102057.stderr +++ b/tests/ui/fmt/format-args-capture-issue-102057.stderr @@ -14,31 +14,61 @@ error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:9:22 | LL | format!("\x7Ba} {b}"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba} {b}"); +LL + format!("\x7Ba} {a}"); + | error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:11:25 | LL | format!("\x7Ba\x7D {b}"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba\x7D {b}"); +LL + format!("\x7Ba\x7D {a}"); + | error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:13:25 | LL | format!("\x7Ba} \x7Bb}"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba} \x7Bb}"); +LL + format!("\x7Ba} \x7Ba}"); + | error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:15:28 | LL | format!("\x7Ba\x7D \x7Bb}"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba\x7D \x7Bb}"); +LL + format!("\x7Ba\x7D \x7Ba}"); + | error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:17:28 | LL | format!("\x7Ba\x7D \x7Bb\x7D"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba\x7D \x7Bb\x7D"); +LL + format!("\x7Ba\x7D \x7Ba\x7D"); + | error: aborting due to 7 previous errors diff --git a/tests/ui/fmt/format-args-capture-issue-94010.stderr b/tests/ui/fmt/format-args-capture-issue-94010.stderr index ed90dc855360..ccdaf0c67b2b 100644 --- a/tests/ui/fmt/format-args-capture-issue-94010.stderr +++ b/tests/ui/fmt/format-args-capture-issue-94010.stderr @@ -4,7 +4,13 @@ error[E0425]: cannot find value `foo` in this scope LL | const FOO: i32 = 123; | --------------------- similarly named constant `FOO` defined here LL | println!("{foo:X}"); - | ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO` + | ^^^ + | +help: a constant with a similar name exists (notice the capitalization) + | +LL - println!("{foo:X}"); +LL + println!("{FOO:X}"); + | error[E0425]: cannot find value `foo` in this scope --> $DIR/format-args-capture-issue-94010.rs:5:18 @@ -13,7 +19,13 @@ LL | const FOO: i32 = 123; | --------------------- similarly named constant `FOO` defined here ... LL | println!("{:.foo$}", 0); - | ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO` + | ^^^ + | +help: a constant with a similar name exists (notice the capitalization) + | +LL - println!("{:.foo$}", 0); +LL + println!("{:.FOO$}", 0); + | error: aborting due to 2 previous errors diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr index 03fafe3e21c1..265c86ac5bb6 100644 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ b/tests/ui/generic-associated-types/equality-bound.stderr @@ -114,28 +114,46 @@ error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:20:79 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, - | ^ help: a struct with a similar name exists: `K` + | ^ ... LL | struct K {} | -------- similarly named struct `K` defined here + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, +LL + fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = K, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:31:68 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, - | ^ help: a struct with a similar name exists: `K` + | ^ ... LL | struct K {} | -------- similarly named struct `K` defined here + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, +LL + fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = K, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:42:76 | LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, - | ^ help: a struct with a similar name exists: `K` + | ^ ... LL | struct K {} | -------- similarly named struct `K` defined here + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, +LL + fn from_iter(_: T) -> Self where IntoIterator::Item = K, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:53:65 @@ -144,7 +162,13 @@ LL | struct K {} | -------- similarly named struct `K` defined here ... LL | fn from_iter(_: T) -> Self where T::Item = A, - | ^ help: a struct with a similar name exists: `K` + | ^ + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where T::Item = A, +LL + fn from_iter(_: T) -> Self where T::Item = K, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:64:62 @@ -153,7 +177,13 @@ LL | struct K {} | -------- similarly named struct `K` defined here ... LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, - | ^ help: a struct with a similar name exists: `K` + | ^ + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, +LL + fn from_iter(_: T) -> Self where IntoIterator::Item = K, T: IntoIterator, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:75:51 @@ -162,16 +192,25 @@ LL | struct K {} | -------- similarly named struct `K` defined here ... LL | fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, - | ^ help: a struct with a similar name exists: `K` + | ^ + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, +LL + fn from_iter(_: T) -> Self where T::Item = K, T: IntoIterator, + | error[E0433]: failed to resolve: use of undeclared type `I` --> $DIR/equality-bound.rs:9:41 | LL | fn sum3(i: J) -> i32 where I::Item = i32 { - | ^ - | | - | use of undeclared type `I` - | help: a type parameter with a similar name exists: `J` + | ^ use of undeclared type `I` + | +help: a type parameter with a similar name exists + | +LL - fn sum3(i: J) -> i32 where I::Item = i32 { +LL + fn sum3(i: J) -> i32 where J::Item = i32 { + | error: aborting due to 16 previous errors diff --git a/tests/ui/hygiene/rustc-macro-transparency.stderr b/tests/ui/hygiene/rustc-macro-transparency.stderr index 1bea8a0ee4f3..af67bfe66cc8 100644 --- a/tests/ui/hygiene/rustc-macro-transparency.stderr +++ b/tests/ui/hygiene/rustc-macro-transparency.stderr @@ -11,10 +11,13 @@ LL | struct SemiOpaque; | ------------------ similarly named unit struct `SemiOpaque` defined here ... LL | semiopaque; - | ^^^^^^^^^^ - | | - | not a value - | help: a unit struct with a similar name exists (notice the capitalization): `SemiOpaque` + | ^^^^^^^^^^ not a value + | +help: a unit struct with a similar name exists (notice the capitalization) + | +LL - semiopaque; +LL + SemiOpaque; + | error[E0423]: expected value, found macro `opaque` --> $DIR/rustc-macro-transparency.rs:30:5 diff --git a/tests/ui/imports/glob-resolve1.stderr b/tests/ui/imports/glob-resolve1.stderr index 1356255a0850..5e02c933836d 100644 --- a/tests/ui/imports/glob-resolve1.stderr +++ b/tests/ui/imports/glob-resolve1.stderr @@ -75,13 +75,18 @@ LL | pub enum B { | ---------- similarly named enum `B` defined here ... LL | foo::(); - | ^ help: an enum with a similar name exists: `B` + | ^ | note: enum `bar::A` exists but is inaccessible --> $DIR/glob-resolve1.rs:12:5 | LL | enum A { | ^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - foo::(); +LL + foo::(); + | error[E0425]: cannot find type `C` in this scope --> $DIR/glob-resolve1.rs:34:11 @@ -90,13 +95,18 @@ LL | pub enum B { | ---------- similarly named enum `B` defined here ... LL | foo::(); - | ^ help: an enum with a similar name exists: `B` + | ^ | note: struct `bar::C` exists but is inaccessible --> $DIR/glob-resolve1.rs:19:5 | LL | struct C; | ^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - foo::(); +LL + foo::(); + | error[E0425]: cannot find type `D` in this scope --> $DIR/glob-resolve1.rs:35:11 @@ -105,13 +115,18 @@ LL | pub enum B { | ---------- similarly named enum `B` defined here ... LL | foo::(); - | ^ help: an enum with a similar name exists: `B` + | ^ | note: type alias `bar::D` exists but is inaccessible --> $DIR/glob-resolve1.rs:21:5 | LL | type D = isize; | ^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - foo::(); +LL + foo::(); + | error: aborting due to 8 previous errors diff --git a/tests/ui/macros/macro-context.stderr b/tests/ui/macros/macro-context.stderr index edddfef9de3b..3ec1af3a82f8 100644 --- a/tests/ui/macros/macro-context.stderr +++ b/tests/ui/macros/macro-context.stderr @@ -46,12 +46,16 @@ error[E0425]: cannot find type `i` in this scope --> $DIR/macro-context.rs:3:13 | LL | () => ( i ; typeof ); - | ^ help: a builtin type with a similar name exists: `i8` + | ^ ... LL | let a: m!(); | ---- in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a builtin type with a similar name exists + | +LL | () => ( i8 ; typeof ); + | + error[E0425]: cannot find value `i` in this scope --> $DIR/macro-context.rs:3:13 diff --git a/tests/ui/macros/macro-name-typo.stderr b/tests/ui/macros/macro-name-typo.stderr index 1cc7ea6ec1b6..bca7dbe9369c 100644 --- a/tests/ui/macros/macro-name-typo.stderr +++ b/tests/ui/macros/macro-name-typo.stderr @@ -2,11 +2,16 @@ error: cannot find macro `printlx` in this scope --> $DIR/macro-name-typo.rs:2:5 | LL | printlx!("oh noes!"); - | ^^^^^^^ help: a macro with a similar name exists: `println` + | ^^^^^^^ | --> $SRC_DIR/std/src/macros.rs:LL:COL | = note: similarly named macro `println` defined here +help: a macro with a similar name exists + | +LL - printlx!("oh noes!"); +LL + println!("oh noes!"); + | error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-path-prelude-fail-3.stderr b/tests/ui/macros/macro-path-prelude-fail-3.stderr index 3d0a074deeb0..7bf166d0e56f 100644 --- a/tests/ui/macros/macro-path-prelude-fail-3.stderr +++ b/tests/ui/macros/macro-path-prelude-fail-3.stderr @@ -2,13 +2,18 @@ error: cannot find macro `inline` in this scope --> $DIR/macro-path-prelude-fail-3.rs:2:5 | LL | inline!(); - | ^^^^^^ help: a macro with a similar name exists: `line` + | ^^^^^^ | --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | = note: similarly named macro `line` defined here | = note: `inline` is in scope, but it is an attribute: `#[inline]` +help: a macro with a similar name exists + | +LL - inline!(); +LL + line!(); + | error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-reexport-removed.stderr b/tests/ui/macros/macro-reexport-removed.stderr index 8130fe0c4bda..752133162214 100644 --- a/tests/ui/macros/macro-reexport-removed.stderr +++ b/tests/ui/macros/macro-reexport-removed.stderr @@ -11,7 +11,13 @@ error: cannot find attribute `macro_reexport` in this scope --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] - | ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export` + | ^^^^^^^^^^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[macro_reexport(macro_one)] +LL + #[macro_export(macro_one)] + | error: aborting due to 2 previous errors diff --git a/tests/ui/macros/macro_undefined.stderr b/tests/ui/macros/macro_undefined.stderr index cc3efacbc541..ed58be8808b2 100644 --- a/tests/ui/macros/macro_undefined.stderr +++ b/tests/ui/macros/macro_undefined.stderr @@ -5,7 +5,12 @@ LL | macro_rules! kl { | --------------- similarly named macro `kl` defined here ... LL | k!(); - | ^ help: a macro with a similar name exists: `kl` + | ^ + | +help: a macro with a similar name exists + | +LL | kl!(); + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/emoji-identifiers.stderr b/tests/ui/parser/emoji-identifiers.stderr index ef4e647b9f50..016ed0401caf 100644 --- a/tests/ui/parser/emoji-identifiers.stderr +++ b/tests/ui/parser/emoji-identifiers.stderr @@ -91,7 +91,13 @@ LL | fn i_like_to_😅_a_lot() -> 👀 { | ----------------------------- similarly named function `i_like_to_😅_a_lot` defined here ... LL | let _ = i_like_to_😄_a_lot() ➖ 4; - | ^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `i_like_to_😅_a_lot` + | ^^^^^^^^^^^^^^^^^^ + | +help: a function with a similar name exists + | +LL - let _ = i_like_to_😄_a_lot() ➖ 4; +LL + let _ = i_like_to_😅_a_lot() ➖ 4; + | error: aborting due to 10 previous errors diff --git a/tests/ui/parser/kw-in-trait-bounds.stderr b/tests/ui/parser/kw-in-trait-bounds.stderr index 5a4adf3e37b4..5f86b1430616 100644 --- a/tests/ui/parser/kw-in-trait-bounds.stderr +++ b/tests/ui/parser/kw-in-trait-bounds.stderr @@ -94,37 +94,61 @@ error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:16:10 | LL | fn _g(_: impl struct, _: &dyn struct) - | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` + | ^^^^^^ ... LL | trait Struct {} | ------------ similarly named trait `Struct` defined here + | +help: a trait with a similar name exists (notice the capitalization) + | +LL - fn _g(_: impl struct, _: &dyn struct) +LL + fn _g(_: impl struct, _: &dyn struct) + | error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:30:8 | LL | B: struct, - | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` + | ^^^^^^ ... LL | trait Struct {} | ------------ similarly named trait `Struct` defined here + | +help: a trait with a similar name exists (notice the capitalization) + | +LL - B: struct, +LL + B: Struct, + | error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:16:29 | LL | fn _g(_: impl struct, _: &dyn struct) - | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` + | ^^^^^^ ... LL | trait Struct {} | ------------ similarly named trait `Struct` defined here + | +help: a trait with a similar name exists (notice the capitalization) + | +LL - fn _g(_: impl struct, _: &dyn struct) +LL + fn _g(_: impl Struct, _: &dyn struct) + | error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:16:45 | LL | fn _g(_: impl struct, _: &dyn struct) - | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` + | ^^^^^^ ... LL | trait Struct {} | ------------ similarly named trait `Struct` defined here + | +help: a trait with a similar name exists (notice the capitalization) + | +LL - fn _g(_: impl struct, _: &dyn struct) +LL + fn _g(_: impl struct, _: &dyn Struct) + | error: aborting due to 12 previous errors diff --git a/tests/ui/parser/recover/raw-no-const-mut.stderr b/tests/ui/parser/recover/raw-no-const-mut.stderr index 65032c807953..3007134f7f5c 100644 --- a/tests/ui/parser/recover/raw-no-const-mut.stderr +++ b/tests/ui/parser/recover/raw-no-const-mut.stderr @@ -101,7 +101,13 @@ LL | fn a() { | ------ similarly named function `a` defined here ... LL | f(&raw 2); - | ^ help: a function with a similar name exists: `a` + | ^ + | +help: a function with a similar name exists + | +LL - f(&raw 2); +LL + a(&raw 2); + | error: aborting due to 9 previous errors diff --git a/tests/ui/pattern/match-enum-struct-variant-field-missing.stderr b/tests/ui/pattern/match-enum-struct-variant-field-missing.stderr index 326595a7cb70..f449f00a6982 100644 --- a/tests/ui/pattern/match-enum-struct-variant-field-missing.stderr +++ b/tests/ui/pattern/match-enum-struct-variant-field-missing.stderr @@ -2,10 +2,13 @@ error[E0026]: variant `A::A` does not have a field named `fob` --> $DIR/match-enum-struct-variant-field-missing.rs:12:16 | LL | A::A { fob } => { - | ^^^ - | | - | variant `A::A` does not have this field - | help: a field with a similar name exists: `foo` + | ^^^ variant `A::A` does not have this field + | +help: a field with a similar name exists + | +LL - A::A { fob } => { +LL + A::A { foo } => { + | error: aborting due to 1 previous error diff --git a/tests/ui/pattern/pattern-error-continue.stderr b/tests/ui/pattern/pattern-error-continue.stderr index a9ac96e3eaff..de90d99a0ff1 100644 --- a/tests/ui/pattern/pattern-error-continue.stderr +++ b/tests/ui/pattern/pattern-error-continue.stderr @@ -56,10 +56,13 @@ error[E0433]: failed to resolve: use of undeclared type `E` --> $DIR/pattern-error-continue.rs:35:9 | LL | E::V => {} - | ^ - | | - | use of undeclared type `E` - | help: an enum with a similar name exists: `A` + | ^ use of undeclared type `E` + | +help: an enum with a similar name exists + | +LL - E::V => {} +LL + A::V => {} + | error: aborting due to 5 previous errors diff --git a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr index a5d9fd2b1a6e..44e42f142707 100644 --- a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr +++ b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr @@ -38,43 +38,85 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:10:34 | LL | fn bad_fn_item_1(x: bool, ((y if x) | y): bool) {} - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - fn bad_fn_item_1(x: bool, ((y if x) | y): bool) {} +LL + fn bad_fn_item_1(x: bool, ((y if y) | y): bool) {} + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:12:25 | LL | fn bad_fn_item_2(((x if y) | x): bool, y: bool) {} - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - fn bad_fn_item_2(((x if y) | x): bool, y: bool) {} +LL + fn bad_fn_item_2(((x if x) | x): bool, y: bool) {} + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:20:18 | LL | (x, y if x) => x && y, - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - (x, y if x) => x && y, +LL + (x, y if y) => x && y, + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:22:15 | LL | (x if y, y) => x && y, - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - (x if y, y) => x && y, +LL + (x if x, y) => x && y, + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:29:20 | LL | (x @ (y if x),) => x && y, - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - (x @ (y if x),) => x && y, +LL + (x @ (y if y),) => x && y, + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:37:20 | LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - ((Ok(x) if y) | (Err(y) if x),) => x && y, +LL + ((Ok(x) if x) | (Err(y) if x),) => x && y, + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:37:36 | LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - ((Ok(x) if y) | (Err(y) if x),) => x && y, +LL + ((Ok(x) if y) | (Err(y) if y),) => x && y, + | error[E0425]: cannot find value `nonexistent` in this scope --> $DIR/name-resolution.rs:44:15 @@ -86,49 +128,97 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:46:22 | LL | if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } +LL + if let ((x, y if y) | (x if y, y)) = (true, true) { x && y; } + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:46:33 | LL | if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } +LL + if let ((x, y if x) | (x if x, y)) = (true, true) { x && y; } + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:49:25 | LL | while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } +LL + while let ((x, y if y) | (x if y, y)) = (true, true) { x && y; } + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:49:36 | LL | while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } +LL + while let ((x, y if x) | (x if x, y)) = (true, true) { x && y; } + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:52:19 | LL | for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } +LL + for ((x, y if y) | (x if y, y)) in [(true, true)] { x && y; } + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:52:30 | LL | for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } +LL + for ((x, y if x) | (x if x, y)) in [(true, true)] { x && y; } + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:57:13 | LL | (|(x if y), (y if x)| x && y)(true, true); - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - (|(x if y), (y if x)| x && y)(true, true); +LL + (|(x if x), (y if x)| x && y)(true, true); + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:57:23 | LL | (|(x if y), (y if x)| x && y)(true, true); - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - (|(x if y), (y if x)| x && y)(true, true); +LL + (|(x if y), (y if y)| x && y)(true, true); + | error[E0308]: mismatched types --> $DIR/name-resolution.rs:75:18 diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr index b985b771754e..b8c6f1d867a1 100644 --- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr +++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr @@ -20,7 +20,13 @@ error[E0425]: cannot find value `a` in this scope LL | if let Foo::Bar { .. } = x { | --------------- this pattern doesn't include `a`, which is available in `Bar` LL | println!("{a}"); - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - println!("{a}"); +LL + println!("{x}"); + | error: aborting due to 3 previous errors diff --git a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr index ed8ee4dc52cb..46cdbaccaeb6 100644 --- a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr +++ b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr @@ -13,7 +13,7 @@ error[E0425]: cannot find value `local_use` in this scope --> $DIR/gen-macro-rules-hygiene.rs:13:1 | LL | gen_macro_rules!(); - | ^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` + | ^^^^^^^^^^^^^^^^^^ ... LL | generated!(); | ------------ in this macro invocation @@ -24,12 +24,17 @@ help: an identifier with the same name exists, but is not accessible due to macr LL | let local_use = 1; | ^^^^^^^^^ = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - gen_macro_rules!(); +LL + local_def; + | error[E0425]: cannot find value `local_def` in this scope --> $DIR/gen-macro-rules-hygiene.rs:22:9 | LL | local_def; - | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` + | ^^^^^^^^^ | help: an identifier with the same name is defined here, but is not accessible due to macro hygiene --> $DIR/gen-macro-rules-hygiene.rs:13:1 @@ -40,6 +45,11 @@ LL | gen_macro_rules!(); LL | generated!(); | ------------ in this macro invocation = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - local_def; +LL + local_use; + | error: aborting due to 3 previous errors diff --git a/tests/ui/proc-macro/lints_in_proc_macros.stderr b/tests/ui/proc-macro/lints_in_proc_macros.stderr index 016b236bda88..0b8df1b348d7 100644 --- a/tests/ui/proc-macro/lints_in_proc_macros.stderr +++ b/tests/ui/proc-macro/lints_in_proc_macros.stderr @@ -2,9 +2,14 @@ error[E0425]: cannot find value `foobar2` in this scope --> $DIR/lints_in_proc_macros.rs:10:5 | LL | bang_proc_macro2!(); - | ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `foobar` + | ^^^^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `bang_proc_macro2` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - bang_proc_macro2!(); +LL + foobar; + | error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr index 97e3f3e3dea8..2cc7ff8a8867 100644 --- a/tests/ui/proc-macro/mixed-site-span.stderr +++ b/tests/ui/proc-macro/mixed-site-span.stderr @@ -592,7 +592,7 @@ error[E0425]: cannot find value `local_use` in this scope --> $DIR/mixed-site-span.rs:23:9 | LL | proc_macro_rules!(); - | ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` + | ^^^^^^^^^^^^^^^^^^^ | help: an identifier with the same name exists, but is not accessible due to macro hygiene --> $DIR/mixed-site-span.rs:22:13 @@ -600,12 +600,17 @@ help: an identifier with the same name exists, but is not accessible due to macr LL | let local_use = 1; | ^^^^^^^^^ = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - proc_macro_rules!(); +LL + local_def; + | error[E0425]: cannot find value `local_def` in this scope --> $DIR/mixed-site-span.rs:28:9 | LL | local_def; - | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` + | ^^^^^^^^^ | help: an identifier with the same name is defined here, but is not accessible due to macro hygiene --> $DIR/mixed-site-span.rs:23:9 @@ -613,6 +618,11 @@ help: an identifier with the same name is defined here, but is not accessible du LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - local_def; +LL + local_use; + | error: aborting due to 52 previous errors diff --git a/tests/ui/proc-macro/parent-source-spans.stderr b/tests/ui/proc-macro/parent-source-spans.stderr index 28a70eea873d..87b8dae74f48 100644 --- a/tests/ui/proc-macro/parent-source-spans.stderr +++ b/tests/ui/proc-macro/parent-source-spans.stderr @@ -140,7 +140,7 @@ error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:30:5 | LL | parent_source_spans!($($tokens)*); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | one!("hello", "world"); | ---------------------- in this macro invocation @@ -150,12 +150,17 @@ LL | one!("hello", "world"); = note: similarly named tuple variant `Ok` defined here | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `one` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a tuple variant with a similar name exists + | +LL - parent_source_spans!($($tokens)*); +LL + Ok; + | error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:30:5 | LL | parent_source_spans!($($tokens)*); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | two!("yay", "rust"); | ------------------- in this macro invocation @@ -165,12 +170,17 @@ LL | two!("yay", "rust"); = note: similarly named tuple variant `Ok` defined here | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `two` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a tuple variant with a similar name exists + | +LL - parent_source_spans!($($tokens)*); +LL + Ok; + | error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:30:5 | LL | parent_source_spans!($($tokens)*); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | three!("hip", "hop"); | -------------------- in this macro invocation @@ -180,6 +190,11 @@ LL | three!("hip", "hop"); = note: similarly named tuple variant `Ok` defined here | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `three` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a tuple variant with a similar name exists + | +LL - parent_source_spans!($($tokens)*); +LL + Ok; + | error: aborting due to 21 previous errors diff --git a/tests/ui/proc-macro/resolve-error.stderr b/tests/ui/proc-macro/resolve-error.stderr index 45b71a3e7b3a..7efb751caaec 100644 --- a/tests/ui/proc-macro/resolve-error.stderr +++ b/tests/ui/proc-macro/resolve-error.stderr @@ -2,12 +2,18 @@ error: cannot find macro `bang_proc_macrp` in this scope --> $DIR/resolve-error.rs:60:5 | LL | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` + | ^^^^^^^^^^^^^^^ | ::: $DIR/auxiliary/test-macros.rs:10:1 | LL | pub fn empty(_: TokenStream) -> TokenStream { | ------------------------------------------- similarly named macro `bang_proc_macro` defined here + | +help: a macro with a similar name exists + | +LL - bang_proc_macrp!(); +LL + bang_proc_macro!(); + | error: cannot find macro `Dlona` in this scope --> $DIR/resolve-error.rs:57:5 @@ -22,7 +28,13 @@ LL | macro_rules! attr_proc_mac { | -------------------------- similarly named macro `attr_proc_mac` defined here ... LL | attr_proc_macra!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac` + | ^^^^^^^^^^^^^^^ + | +help: a macro with a similar name exists + | +LL - attr_proc_macra!(); +LL + attr_proc_mac!(); + | error: cannot find macro `FooWithLongNama` in this scope --> $DIR/resolve-error.rs:51:5 @@ -31,7 +43,13 @@ LL | macro_rules! FooWithLongNam { | --------------------------- similarly named macro `FooWithLongNam` defined here ... LL | FooWithLongNama!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam` + | ^^^^^^^^^^^^^^^ + | +help: a macro with a similar name exists + | +LL - FooWithLongNama!(); +LL + FooWithLongNam!(); + | error: cannot find derive macro `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:45:10 @@ -51,18 +69,24 @@ error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] - | ^^^^^ help: a derive macro with a similar name exists: `Clona` + | ^^^^^ | ::: $DIR/auxiliary/derive-clona.rs:6:1 | LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here + | +help: a derive macro with a similar name exists + | +LL - #[derive(Dlona)] +LL + #[derive(Clona)] + | error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] - | ^^^^^ help: a derive macro with a similar name exists: `Clona` + | ^^^^^ | ::: $DIR/auxiliary/derive-clona.rs:6:1 | @@ -70,28 +94,43 @@ LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: a derive macro with a similar name exists + | +LL - #[derive(Dlona)] +LL + #[derive(Clona)] + | error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] - | ^^^^^ help: a derive macro with a similar name exists: `Clone` + | ^^^^^ | --> $SRC_DIR/core/src/clone.rs:LL:COL | = note: similarly named derive macro `Clone` defined here +help: a derive macro with a similar name exists + | +LL - #[derive(Dlone)] +LL + #[derive(Clone)] + | error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] - | ^^^^^ help: a derive macro with a similar name exists: `Clone` + | ^^^^^ | --> $SRC_DIR/core/src/clone.rs:LL:COL | = note: similarly named derive macro `Clone` defined here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: a derive macro with a similar name exists + | +LL - #[derive(Dlone)] +LL + #[derive(Clone)] + | error: cannot find attribute `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:32:3 @@ -103,29 +142,41 @@ error: cannot find attribute `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:28:3 | LL | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` + | ^^^^^^^^^^^^^^^ | ::: $DIR/auxiliary/test-macros.rs:15:1 | LL | pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { | ---------------------------------------------------------------- similarly named attribute macro `attr_proc_macro` defined here + | +help: an attribute macro with a similar name exists + | +LL - #[attr_proc_macra] +LL + #[attr_proc_macro] + | error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + | ^^^^^^^^^^^^^^ | ::: $DIR/auxiliary/derive-foo.rs:6:1 | LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here + | +help: a derive macro with a similar name exists + | +LL - #[derive(FooWithLongNan)] +LL + #[derive(FooWithLongName)] + | error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + | ^^^^^^^^^^^^^^ | ::: $DIR/auxiliary/derive-foo.rs:6:1 | @@ -133,6 +184,11 @@ LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: a derive macro with a similar name exists + | +LL - #[derive(FooWithLongNan)] +LL + #[derive(FooWithLongName)] + | error: aborting due to 14 previous errors diff --git a/tests/ui/regions/outlives-with-missing.stderr b/tests/ui/regions/outlives-with-missing.stderr index b8762e9cb8f3..25fac1970635 100644 --- a/tests/ui/regions/outlives-with-missing.stderr +++ b/tests/ui/regions/outlives-with-missing.stderr @@ -5,7 +5,13 @@ LL | impl HandlerWrapper { | - similarly named type parameter `H` defined here ... LL | T: Send + Sync + 'static, - | ^ help: a type parameter with a similar name exists: `H` + | ^ + | +help: a type parameter with a similar name exists + | +LL - T: Send + Sync + 'static, +LL + H: Send + Sync + 'static, + | error: aborting due to 1 previous error diff --git a/tests/ui/resolve/112590-2.stderr b/tests/ui/resolve/112590-2.stderr index 28d23ccf8537..d6f4a8f22a45 100644 --- a/tests/ui/resolve/112590-2.stderr +++ b/tests/ui/resolve/112590-2.stderr @@ -63,12 +63,14 @@ error[E0433]: failed to resolve: use of unresolved module or unlinked crate `vec --> $DIR/112590-2.rs:24:24 | LL | let _t: Vec = vec::new(); - | ^^^ - | | - | use of unresolved module or unlinked crate `vec` - | help: a struct with a similar name exists (notice the capitalization): `Vec` + | ^^^ use of unresolved module or unlinked crate `vec` | = help: you might be missing a crate named `vec` +help: a struct with a similar name exists (notice the capitalization) + | +LL - let _t: Vec = vec::new(); +LL + let _t: Vec = Vec::new(); + | error: aborting due to 5 previous errors diff --git a/tests/ui/resolve/issue-10200.stderr b/tests/ui/resolve/issue-10200.stderr index 4b6d9b6f1dfa..62731960191f 100644 --- a/tests/ui/resolve/issue-10200.stderr +++ b/tests/ui/resolve/issue-10200.stderr @@ -5,9 +5,14 @@ LL | struct Foo(bool); | ----------------- similarly named tuple struct `Foo` defined here ... LL | foo(x) - | ^^^ help: a tuple struct with a similar name exists (notice the capitalization): `Foo` + | ^^^ | = note: function calls are not allowed in patterns: +help: a tuple struct with a similar name exists (notice the capitalization) + | +LL - foo(x) +LL + Foo(x) + | error: aborting due to 1 previous error diff --git a/tests/ui/resolve/issue-49074.stderr b/tests/ui/resolve/issue-49074.stderr index bbfeb4ea9483..16a4ede0c0b5 100644 --- a/tests/ui/resolve/issue-49074.stderr +++ b/tests/ui/resolve/issue-49074.stderr @@ -10,7 +10,13 @@ error: cannot find attribute `marco_use` in this scope --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo - | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` + | ^^^^^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[marco_use] // typo +LL + #[macro_use] // typo + | error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/levenshtein.stderr b/tests/ui/resolve/levenshtein.stderr index 7a1abd134330..48515b9e6bd5 100644 --- a/tests/ui/resolve/levenshtein.stderr +++ b/tests/ui/resolve/levenshtein.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find type `esize` in this scope --> $DIR/levenshtein.rs:5:11 | LL | fn foo(c: esize) {} // Misspelled primitive type name. - | ^^^^^ help: a builtin type with a similar name exists: `isize` + | ^^^^^ + | +help: a builtin type with a similar name exists + | +LL - fn foo(c: esize) {} // Misspelled primitive type name. +LL + fn foo(c: isize) {} // Misspelled primitive type name. + | error[E0425]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:10:10 @@ -11,17 +17,28 @@ LL | enum Bar { } | -------- similarly named enum `Bar` defined here LL | LL | type A = Baz; // Misspelled type name. - | ^^^ help: an enum with a similar name exists: `Bar` + | ^^^ + | +help: an enum with a similar name exists + | +LL - type A = Baz; // Misspelled type name. +LL + type A = Bar; // Misspelled type name. + | error[E0425]: cannot find type `Opiton` in this scope --> $DIR/levenshtein.rs:12:10 | LL | type B = Opiton; // Misspelled type name from the prelude. - | ^^^^^^ help: an enum with a similar name exists: `Option` + | ^^^^^^ | --> $SRC_DIR/core/src/option.rs:LL:COL | = note: similarly named enum `Option` defined here +help: an enum with a similar name exists + | +LL - type B = Opiton; // Misspelled type name from the prelude. +LL + type B = Option; // Misspelled type name from the prelude. + | error[E0425]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:16:14 @@ -36,7 +53,12 @@ LL | const MAX_ITEM: usize = 10; | --------------------------- similarly named constant `MAX_ITEM` defined here ... LL | let v = [0u32; MAXITEM]; // Misspelled constant name. - | ^^^^^^^ help: a constant with a similar name exists: `MAX_ITEM` + | ^^^^^^^ + | +help: a constant with a similar name exists + | +LL | let v = [0u32; MAX_ITEM]; // Misspelled constant name. + | + error[E0425]: cannot find type `first` in module `m` --> $DIR/levenshtein.rs:28:15 @@ -45,7 +67,13 @@ LL | pub struct First; | ----------------- similarly named struct `First` defined here ... LL | let b: m::first = m::second; // Misspelled item in module. - | ^^^^^ help: a struct with a similar name exists (notice the capitalization): `First` + | ^^^^^ + | +help: a struct with a similar name exists (notice the capitalization) + | +LL - let b: m::first = m::second; // Misspelled item in module. +LL + let b: m::First = m::second; // Misspelled item in module. + | error[E0425]: cannot find value `second` in module `m` --> $DIR/levenshtein.rs:28:26 @@ -54,7 +82,13 @@ LL | pub struct Second; | ------------------ similarly named unit struct `Second` defined here ... LL | let b: m::first = m::second; // Misspelled item in module. - | ^^^^^^ help: a unit struct with a similar name exists (notice the capitalization): `Second` + | ^^^^^^ + | +help: a unit struct with a similar name exists (notice the capitalization) + | +LL - let b: m::first = m::second; // Misspelled item in module. +LL + let b: m::first = m::Second; // Misspelled item in module. + | error[E0425]: cannot find function `foobar` in this scope --> $DIR/levenshtein.rs:26:5 @@ -63,7 +97,12 @@ LL | fn foo_bar() {} | ------------ similarly named function `foo_bar` defined here ... LL | foobar(); // Misspelled function name. - | ^^^^^^ help: a function with a similar name exists: `foo_bar` + | ^^^^^^ + | +help: a function with a similar name exists + | +LL | foo_bar(); // Misspelled function name. + | + error: aborting due to 8 previous errors diff --git a/tests/ui/resolve/privacy-enum-ctor.stderr b/tests/ui/resolve/privacy-enum-ctor.stderr index 81356c5040f8..5349108065dc 100644 --- a/tests/ui/resolve/privacy-enum-ctor.stderr +++ b/tests/ui/resolve/privacy-enum-ctor.stderr @@ -149,13 +149,18 @@ LL | pub enum E { | ---------- similarly named enum `E` defined here ... LL | let _: Z = m::n::Z; - | ^ help: an enum with a similar name exists: `E` + | ^ | note: enum `m::Z` exists but is inaccessible --> $DIR/privacy-enum-ctor.rs:12:9 | LL | pub(in crate::m) enum Z { | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - let _: Z = m::n::Z; +LL + let _: E = m::n::Z; + | error[E0423]: expected value, found enum `m::n::Z` --> $DIR/privacy-enum-ctor.rs:58:16 @@ -192,13 +197,18 @@ LL | pub enum E { | ---------- similarly named enum `E` defined here ... LL | let _: Z = m::n::Z::Fn; - | ^ help: an enum with a similar name exists: `E` + | ^ | note: enum `m::Z` exists but is inaccessible --> $DIR/privacy-enum-ctor.rs:12:9 | LL | pub(in crate::m) enum Z { | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - let _: Z = m::n::Z::Fn; +LL + let _: E = m::n::Z::Fn; + | error[E0425]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:65:12 @@ -207,13 +217,18 @@ LL | pub enum E { | ---------- similarly named enum `E` defined here ... LL | let _: Z = m::n::Z::Struct; - | ^ help: an enum with a similar name exists: `E` + | ^ | note: enum `m::Z` exists but is inaccessible --> $DIR/privacy-enum-ctor.rs:12:9 | LL | pub(in crate::m) enum Z { | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - let _: Z = m::n::Z::Struct; +LL + let _: E = m::n::Z::Struct; + | error[E0425]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:69:12 @@ -222,13 +237,18 @@ LL | pub enum E { | ---------- similarly named enum `E` defined here ... LL | let _: Z = m::n::Z::Unit {}; - | ^ help: an enum with a similar name exists: `E` + | ^ | note: enum `m::Z` exists but is inaccessible --> $DIR/privacy-enum-ctor.rs:12:9 | LL | pub(in crate::m) enum Z { | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - let _: Z = m::n::Z::Unit {}; +LL + let _: E = m::n::Z::Unit {}; + | error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:58:22 diff --git a/tests/ui/resolve/privacy-struct-ctor.stderr b/tests/ui/resolve/privacy-struct-ctor.stderr index 96c3e6e5122d..5a01d51d24ff 100644 --- a/tests/ui/resolve/privacy-struct-ctor.stderr +++ b/tests/ui/resolve/privacy-struct-ctor.stderr @@ -5,10 +5,13 @@ LL | pub struct S(u8); | ----------------- similarly named tuple struct `S` defined here ... LL | Z; - | ^ - | | - | constructor is not visible here due to private fields - | help: a tuple struct with a similar name exists: `S` + | ^ constructor is not visible here due to private fields + | +help: a tuple struct with a similar name exists + | +LL - Z; +LL + S; + | error[E0423]: expected value, found struct `S` --> $DIR/privacy-struct-ctor.rs:34:5 diff --git a/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr index 5db943cd10d0..89c0cd54faee 100644 --- a/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr +++ b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr @@ -73,9 +73,13 @@ LL | pub const I: i32 = 1; | --------------------- similarly named constant `I` defined here ... LL | v.push(a::b); - | ^^^- - | | - | help: a constant with a similar name exists: `I` + | ^^^^ + | +help: a constant with a similar name exists + | +LL - v.push(a::b); +LL + v.push(a::I); + | error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:52:5 @@ -104,9 +108,13 @@ LL | pub const I: i32 = 1; | --------------------- similarly named constant `I` defined here ... LL | a::b - | ^^^- - | | - | help: a constant with a similar name exists: `I` + | ^^^^ + | +help: a constant with a similar name exists + | +LL - a::b +LL + a::I + | error[E0423]: expected function, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:65:5 @@ -115,9 +123,13 @@ LL | pub const I: i32 = 1; | --------------------- similarly named constant `I` defined here ... LL | a::b() - | ^^^- - | | - | help: a constant with a similar name exists: `I` + | ^^^^ + | +help: a constant with a similar name exists + | +LL - a::b() +LL + a::I() + | error[E0423]: expected value, found module `a` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9 diff --git a/tests/ui/resolve/tuple-struct-alias.stderr b/tests/ui/resolve/tuple-struct-alias.stderr index bf026a499b8c..89b536708372 100644 --- a/tests/ui/resolve/tuple-struct-alias.stderr +++ b/tests/ui/resolve/tuple-struct-alias.stderr @@ -5,7 +5,13 @@ LL | struct S(u8, u16); | ------------------ similarly named tuple struct `S` defined here ... LL | A(..) => {} - | ^ help: a tuple struct with a similar name exists: `S` + | ^ + | +help: a tuple struct with a similar name exists + | +LL - A(..) => {} +LL + S(..) => {} + | error[E0423]: expected function, tuple struct or tuple variant, found type alias `A` --> $DIR/tuple-struct-alias.rs:5:13 diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index 039410f8795f..9c874d980cbe 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -5,7 +5,13 @@ LL | config: String, | ------ a field by that name exists in `Self` ... LL | Self { config } - | ^^^^^^ help: a local variable with a similar name exists: `cofig` + | ^^^^^^ + | +help: a local variable with a similar name exists + | +LL - Self { config } +LL + Self { cofig } + | error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 @@ -14,15 +20,26 @@ LL | config: String, | ------ a field by that name exists in `Self` ... LL | println!("{config}"); - | ^^^^^^ help: a local variable with a similar name exists: `cofig` + | ^^^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{config}"); +LL + println!("{cofig}"); + | error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20 | LL | println!("{config}"); - | ^^^^^^ help: a local variable with a similar name exists: `cofig` + | ^^^^^^ | = help: you might have meant to use the available field in a format string: `"{}", self.config` +help: a local variable with a similar name exists + | +LL - println!("{config}"); +LL + println!("{cofig}"); + | error[E0425]: cannot find value `bah` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:33:9 diff --git a/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr b/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr index 2d0d0d0f3867..fef1f52b86b7 100644 --- a/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr +++ b/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr @@ -2,10 +2,12 @@ error[E0433]: failed to resolve: could not find `Struc` in `module` --> $DIR/typo-suggestion-mistyped-in-path.rs:35:13 | LL | module::Struc::foo(); - | ^^^^^ - | | - | could not find `Struc` in `module` - | help: a struct with a similar name exists: `Struct` + | ^^^^^ could not find `Struc` in `module` + | +help: a struct with a similar name exists + | +LL | module::Struct::foo(); + | + error[E0599]: no function or associated item named `fob` found for struct `Struct` in the current scope --> $DIR/typo-suggestion-mistyped-in-path.rs:23:13 @@ -26,10 +28,12 @@ error[E0433]: failed to resolve: use of undeclared type `Struc` --> $DIR/typo-suggestion-mistyped-in-path.rs:27:5 | LL | Struc::foo(); - | ^^^^^ - | | - | use of undeclared type `Struc` - | help: a struct with a similar name exists: `Struct` + | ^^^^^ use of undeclared type `Struc` + | +help: a struct with a similar name exists + | +LL | Struct::foo(); + | + error[E0433]: failed to resolve: use of unresolved module or unlinked crate `modul` --> $DIR/typo-suggestion-mistyped-in-path.rs:31:5 @@ -46,10 +50,12 @@ error[E0433]: failed to resolve: use of undeclared type `Trai` --> $DIR/typo-suggestion-mistyped-in-path.rs:39:5 | LL | Trai::foo(); - | ^^^^ - | | - | use of undeclared type `Trai` - | help: a trait with a similar name exists: `Trait` + | ^^^^ use of undeclared type `Trai` + | +help: a trait with a similar name exists + | +LL | Trait::foo(); + | + error: aborting due to 5 previous errors diff --git a/tests/ui/span/suggestion-raw-68962.stderr b/tests/ui/span/suggestion-raw-68962.stderr index 2e25f5cbdf58..2271acf15a80 100644 --- a/tests/ui/span/suggestion-raw-68962.stderr +++ b/tests/ui/span/suggestion-raw-68962.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find value `fina` in this scope --> $DIR/suggestion-raw-68962.rs:7:5 | LL | fina; - | ^^^^ help: a local variable with a similar name exists: `r#final` + | ^^^^ + | +help: a local variable with a similar name exists + | +LL - fina; +LL + r#final; + | error[E0425]: cannot find function `f` in this scope --> $DIR/suggestion-raw-68962.rs:10:5 @@ -11,7 +17,13 @@ LL | fn r#fn() {} | --------- similarly named function `r#fn` defined here ... LL | f(); - | ^ help: a function with a similar name exists: `r#fn` + | ^ + | +help: a function with a similar name exists + | +LL - f(); +LL + r#fn(); + | error: aborting due to 2 previous errors diff --git a/tests/ui/span/typo-suggestion.stderr b/tests/ui/span/typo-suggestion.stderr index 61d4e06119c4..1f679221c002 100644 --- a/tests/ui/span/typo-suggestion.stderr +++ b/tests/ui/span/typo-suggestion.stderr @@ -8,7 +8,13 @@ error[E0425]: cannot find value `fob` in this scope --> $DIR/typo-suggestion.rs:8:26 | LL | println!("Hello {}", fob); - | ^^^ help: a local variable with a similar name exists: `foo` + | ^^^ + | +help: a local variable with a similar name exists + | +LL - println!("Hello {}", fob); +LL + println!("Hello {}", foo); + | error: aborting due to 2 previous errors diff --git a/tests/ui/stability-attribute/issue-109177.stderr b/tests/ui/stability-attribute/issue-109177.stderr index 9c2ac591ace0..6f89bde7f894 100644 --- a/tests/ui/stability-attribute/issue-109177.stderr +++ b/tests/ui/stability-attribute/issue-109177.stderr @@ -2,12 +2,18 @@ error[E0425]: cannot find function `foo1` in crate `similar_unstable_method` --> $DIR/issue-109177.rs:7:30 | LL | similar_unstable_method::foo1(); - | ^^^^ help: a function with a similar name exists: `foo` + | ^^^^ | ::: $DIR/auxiliary/similar-unstable-method.rs:5:1 | LL | pub fn foo() {} | ------------ similarly named function `foo` defined here + | +help: a function with a similar name exists + | +LL - similar_unstable_method::foo1(); +LL + similar_unstable_method::foo(); + | error[E0599]: no method named `foo1` found for struct `Foo` in the current scope --> $DIR/issue-109177.rs:11:9 diff --git a/tests/ui/structs/struct-fields-shorthand-unresolved.stderr b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr index b485c17c1b27..5d8321130958 100644 --- a/tests/ui/structs/struct-fields-shorthand-unresolved.stderr +++ b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find value `y` in this scope --> $DIR/struct-fields-shorthand-unresolved.rs:10:9 | LL | y - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - y +LL + x + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/attribute-typos.stderr b/tests/ui/suggestions/attribute-typos.stderr index 1816a27dcdc8..960e0b0f620f 100644 --- a/tests/ui/suggestions/attribute-typos.stderr +++ b/tests/ui/suggestions/attribute-typos.stderr @@ -8,23 +8,38 @@ error: cannot find attribute `rustc_dumm` in this scope --> $DIR/attribute-typos.rs:7:3 | LL | #[rustc_dumm] - | ^^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_dummy` + | ^^^^^^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL | #[rustc_dummy] + | + error: cannot find attribute `tests` in this scope --> $DIR/attribute-typos.rs:4:3 | LL | #[tests] - | ^^^^^ help: an attribute macro with a similar name exists: `test` + | ^^^^^ | --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | = note: similarly named attribute macro `test` defined here +help: an attribute macro with a similar name exists + | +LL - #[tests] +LL + #[test] + | error: cannot find attribute `deprcated` in this scope --> $DIR/attribute-typos.rs:1:3 | LL | #[deprcated] - | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated` + | ^^^^^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL | #[deprecated] + | + error: aborting due to 4 previous errors diff --git a/tests/ui/suggestions/case-difference-suggestions.stderr b/tests/ui/suggestions/case-difference-suggestions.stderr index c3d2410a6eb2..198c3c7a38c9 100644 --- a/tests/ui/suggestions/case-difference-suggestions.stderr +++ b/tests/ui/suggestions/case-difference-suggestions.stderr @@ -2,97 +2,193 @@ error[E0425]: cannot find value `Hello` in this scope --> $DIR/case-difference-suggestions.rs:5:20 | LL | println!("{}", Hello); - | ^^^^^ help: a local variable with a similar name exists: `hello` + | ^^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", Hello); +LL + println!("{}", hello); + | error[E0425]: cannot find value `myvariable` in this scope --> $DIR/case-difference-suggestions.rs:9:20 | LL | println!("{}", myvariable); - | ^^^^^^^^^^ help: a local variable with a similar name exists (notice the capitalization): `myVariable` + | ^^^^^^^^^^ + | +help: a local variable with a similar name exists (notice the capitalization) + | +LL - println!("{}", myvariable); +LL + println!("{}", myVariable); + | error[E0425]: cannot find value `User_Name` in this scope --> $DIR/case-difference-suggestions.rs:13:20 | LL | println!("{}", User_Name); - | ^^^^^^^^^ help: a local variable with a similar name exists: `user_name` + | ^^^^^^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", User_Name); +LL + println!("{}", user_name); + | error[E0425]: cannot find value `foo` in this scope --> $DIR/case-difference-suggestions.rs:17:20 | LL | println!("{}", foo); - | ^^^ help: a local variable with a similar name exists (notice the capitalization): `FOO` + | ^^^ + | +help: a local variable with a similar name exists (notice the capitalization) + | +LL - println!("{}", foo); +LL + println!("{}", FOO); + | error[E0425]: cannot find value `FFOO` in this scope --> $DIR/case-difference-suggestions.rs:22:20 | LL | println!("{}", FFOO); - | ^^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `FFO0` + | ^^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", FFOO); +LL + println!("{}", FFO0); + | error[E0425]: cannot find value `list` in this scope --> $DIR/case-difference-suggestions.rs:25:20 | LL | println!("{}", list); - | ^^^^ help: a local variable with a similar name exists: `l1st` + | ^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", list); +LL + println!("{}", l1st); + | error[E0425]: cannot find value `SS` in this scope --> $DIR/case-difference-suggestions.rs:28:20 | LL | println!("{}", SS); - | ^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `S5` + | ^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", SS); +LL + println!("{}", S5); + | error[E0425]: cannot find value `a55` in this scope --> $DIR/case-difference-suggestions.rs:31:20 | LL | println!("{}", a55); - | ^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `aS5` + | ^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", a55); +LL + println!("{}", aS5); + | error[E0425]: cannot find value `BB` in this scope --> $DIR/case-difference-suggestions.rs:34:20 | LL | println!("{}", BB); - | ^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `B8` + | ^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", BB); +LL + println!("{}", B8); + | error[E0425]: cannot find value `gg` in this scope --> $DIR/case-difference-suggestions.rs:37:20 | LL | println!("{}", gg); - | ^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `g9` + | ^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", gg); +LL + println!("{}", g9); + | error[E0425]: cannot find value `old` in this scope --> $DIR/case-difference-suggestions.rs:40:20 | LL | println!("{}", old); - | ^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `o1d` + | ^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", old); +LL + println!("{}", o1d); + | error[E0425]: cannot find value `newl` in this scope --> $DIR/case-difference-suggestions.rs:43:20 | LL | println!("{}", newl); - | ^^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `new1` + | ^^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", newl); +LL + println!("{}", new1); + | error[E0425]: cannot find value `app1e` in this scope --> $DIR/case-difference-suggestions.rs:46:20 | LL | println!("{}", app1e); - | ^^^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `apple` + | ^^^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", app1e); +LL + println!("{}", apple); + | error[E0425]: cannot find value `A` in this scope --> $DIR/case-difference-suggestions.rs:49:20 | LL | println!("{}", A); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", A); +LL + println!("{}", a); + | error[E0425]: cannot find value `world1U` in this scope --> $DIR/case-difference-suggestions.rs:52:20 | LL | println!("{}", world1U); - | ^^^^^^^ help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion): `worldlu` + | ^^^^^^^ + | +help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion) + | +LL - println!("{}", world1U); +LL + println!("{}", worldlu); + | error[E0425]: cannot find value `myv4r1able` in this scope --> $DIR/case-difference-suggestions.rs:55:20 | LL | println!("{}", myv4r1able); - | ^^^^^^^^^^ help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion): `myV4rlable` + | ^^^^^^^^^^ + | +help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion) + | +LL - println!("{}", myv4r1able); +LL + println!("{}", myV4rlable); + | error: aborting due to 16 previous errors diff --git a/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr b/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr index 112ed6fffd50..e54e5acffe8f 100644 --- a/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr +++ b/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr @@ -2,11 +2,16 @@ error[E0573]: expected type, found module `result` --> $DIR/do-not-attempt-to-add-suggestions-with-no-changes.rs:3:6 | LL | impl result { - | ^^^^^^ help: an enum with a similar name exists: `Result` + | ^^^^^^ | --> $SRC_DIR/core/src/result.rs:LL:COL | = note: similarly named enum `Result` defined here +help: an enum with a similar name exists + | +LL - impl result { +LL + impl Result { + | error[E0573]: expected type, found variant `Err` --> $DIR/do-not-attempt-to-add-suggestions-with-no-changes.rs:4:25 diff --git a/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr b/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr index ce0087fbfcba..b55353c9e6e4 100644 --- a/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr +++ b/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find value `a_variable_longer_name` in this scope --> $DIR/issue-66968-suggest-sorted-words.rs:3:20 | LL | println!("{}", a_variable_longer_name); - | ^^^^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `a_longer_variable_name` + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", a_variable_longer_name); +LL + println!("{}", a_longer_variable_name); + | error: aborting due to 1 previous error diff --git a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr index 40936ce1ec34..660bbc120d0e 100644 --- a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr +++ b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr @@ -84,11 +84,15 @@ error[E0404]: expected trait, found struct `String` --> $DIR/assoc_type_bound_with_struct.rs:19:51 | LL | fn issue_95327() where ::Assoc: String {} - | ^^^^^^ help: a trait with a similar name exists: `ToString` + | ^^^^^^ | --> $SRC_DIR/alloc/src/string.rs:LL:COL | = note: similarly named trait `ToString` defined here +help: a trait with a similar name exists + | +LL | fn issue_95327() where ::Assoc: ToString {} + | ++ error: aborting due to 6 previous errors diff --git a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr index e499451d8971..d2eea3a805d9 100644 --- a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr +++ b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr @@ -42,10 +42,16 @@ error[E0425]: cannot find function `main8` in this scope --> $DIR/ice-120503-async-const-method.rs:11:9 | LL | main8().await; - | ^^^^^ help: a function with a similar name exists: `main` + | ^^^^^ ... LL | fn main() {} | --------- similarly named function `main` defined here + | +help: a function with a similar name exists + | +LL - main8().await; +LL + main().await; + | error: aborting due to 5 previous errors diff --git a/tests/ui/traits/const-traits/mismatched_generic_args.stderr b/tests/ui/traits/const-traits/mismatched_generic_args.stderr index 8e12b40381fd..e8103313dc4f 100644 --- a/tests/ui/traits/const-traits/mismatched_generic_args.stderr +++ b/tests/ui/traits/const-traits/mismatched_generic_args.stderr @@ -5,7 +5,13 @@ LL | pub fn add(x: Quantity) -> Quantity { | - similarly named const parameter `U` defined here LL | LL | x + y - | ^ help: a const parameter with a similar name exists: `U` + | ^ + | +help: a const parameter with a similar name exists + | +LL - x + y +LL + x + U + | warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/mismatched_generic_args.rs:1:12 diff --git a/tests/ui/traits/impl-for-module.stderr b/tests/ui/traits/impl-for-module.stderr index b715c699e89f..1011a913a4ab 100644 --- a/tests/ui/traits/impl-for-module.stderr +++ b/tests/ui/traits/impl-for-module.stderr @@ -5,7 +5,13 @@ LL | trait A { | ------- similarly named trait `A` defined here ... LL | impl A for a { - | ^ help: a trait with a similar name exists: `A` + | ^ + | +help: a trait with a similar name exists + | +LL - impl A for a { +LL + impl A for A { + | error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr index 1cb33eabd902..e5c35d58b72d 100644 --- a/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr +++ b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr @@ -2,10 +2,16 @@ error[E0425]: cannot find function `value` in this scope --> $DIR/type-error-drop-elaboration.rs:12:5 | LL | value() - | ^^^^^ help: a constant with a similar name exists: `VALUE` + | ^^^^^ ... LL | const VALUE: Foo = foo(); | ------------------------- similarly named constant `VALUE` defined here + | +help: a constant with a similar name exists + | +LL - value() +LL + VALUE() + | error: aborting due to 1 previous error diff --git a/tests/ui/type/issue-7607-1.stderr b/tests/ui/type/issue-7607-1.stderr index ac6034da75f1..8edd0d31d791 100644 --- a/tests/ui/type/issue-7607-1.stderr +++ b/tests/ui/type/issue-7607-1.stderr @@ -2,11 +2,16 @@ error[E0425]: cannot find type `Fo` in this scope --> $DIR/issue-7607-1.rs:5:6 | LL | impl Fo { - | ^^ help: a trait with a similar name exists: `Fn` + | ^^ | --> $SRC_DIR/core/src/ops/function.rs:LL:COL | = note: similarly named trait `Fn` defined here +help: a trait with a similar name exists + | +LL - impl Fo { +LL + impl Fn { + | error: aborting due to 1 previous error diff --git a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr index 4ccfacfb0052..1d766e6e5cdb 100644 --- a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr +++ b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr @@ -14,7 +14,13 @@ error[E0425]: cannot find value `g` in this scope --> $DIR/issue-114423-ice-regression-in-suggestion.rs:11:22 | LL | let _ = RGB { r, g, b }; - | ^ help: a local variable with a similar name exists: `b` + | ^ + | +help: a local variable with a similar name exists + | +LL - let _ = RGB { r, g, b }; +LL + let _ = RGB { r, b, b }; + | error[E0308]: mismatched types --> $DIR/issue-114423-ice-regression-in-suggestion.rs:7:50 diff --git a/tests/ui/typeck/issue-120856.stderr b/tests/ui/typeck/issue-120856.stderr index e366744409f4..4ff9f345c48b 100644 --- a/tests/ui/typeck/issue-120856.stderr +++ b/tests/ui/typeck/issue-120856.stderr @@ -2,23 +2,26 @@ error[E0433]: failed to resolve: use of unresolved module or unlinked crate `n` --> $DIR/issue-120856.rs:1:37 | LL | pub type Archived = ::Archived; - | ^ - | | - | use of unresolved module or unlinked crate `n` - | help: a trait with a similar name exists: `Fn` + | ^ use of unresolved module or unlinked crate `n` | = help: you might be missing a crate named `n` +help: a trait with a similar name exists + | +LL | pub type Archived = ::Archived; + | + error[E0433]: failed to resolve: use of unresolved module or unlinked crate `m` --> $DIR/issue-120856.rs:1:25 | LL | pub type Archived = ::Archived; - | ^ - | | - | use of unresolved module or unlinked crate `m` - | help: a type parameter with a similar name exists: `T` + | ^ use of unresolved module or unlinked crate `m` | = help: you might be missing a crate named `m` +help: a type parameter with a similar name exists + | +LL - pub type Archived = ::Archived; +LL + pub type Archived = ::Archived; + | error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/issue-83693.stderr b/tests/ui/typeck/issue-83693.stderr index 521288c43402..2f83e5daff97 100644 --- a/tests/ui/typeck/issue-83693.stderr +++ b/tests/ui/typeck/issue-83693.stderr @@ -2,11 +2,15 @@ error[E0425]: cannot find type `F` in this scope --> $DIR/issue-83693.rs:6:6 | LL | impl F { - | ^ help: a trait with a similar name exists: `Fn` + | ^ | --> $SRC_DIR/core/src/ops/function.rs:LL:COL | = note: similarly named trait `Fn` defined here +help: a trait with a similar name exists + | +LL | impl Fn { + | + error[E0425]: cannot find type `TestResult` in this scope --> $DIR/issue-83693.rs:9:22 diff --git a/tests/ui/typeck/issue-88844.stderr b/tests/ui/typeck/issue-88844.stderr index a5f4310c34dd..6d21317dfd7f 100644 --- a/tests/ui/typeck/issue-88844.stderr +++ b/tests/ui/typeck/issue-88844.stderr @@ -5,7 +5,12 @@ LL | struct Struct { value: i32 } | ------------- similarly named struct `Struct` defined here ... LL | impl Stuct { - | ^^^^^ help: a struct with a similar name exists: `Struct` + | ^^^^^ + | +help: a struct with a similar name exists + | +LL | impl Struct { + | + error: aborting due to 1 previous error diff --git a/tests/ui/ufcs/ufcs-partially-resolved.stderr b/tests/ui/ufcs/ufcs-partially-resolved.stderr index a854ecb06222..e1df200feccf 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.stderr +++ b/tests/ui/ufcs/ufcs-partially-resolved.stderr @@ -5,17 +5,27 @@ LL | type Y = u16; | ------------- similarly named associated type `Y` defined here ... LL | let _: ::N; - | ^ help: an associated type with a similar name exists: `Y` + | ^ + | +help: an associated type with a similar name exists + | +LL - let _: ::N; +LL + let _: ::Y; + | error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:20:19 | LL | let _: ::N; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | let _: ::N; + | + error[E0404]: expected trait, found type alias `A` --> $DIR/ufcs-partially-resolved.rs:21:19 @@ -36,17 +46,27 @@ LL | fn Y() {} | ------ similarly named associated function `Y` defined here ... LL | ::N; - | ^ help: an associated function with a similar name exists: `Y` + | ^ + | +help: an associated function with a similar name exists + | +LL - ::N; +LL + ::Y; + | error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:23:12 | LL | ::N; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | ::N; + | + error[E0404]: expected trait, found type alias `A` --> $DIR/ufcs-partially-resolved.rs:24:12 @@ -64,21 +84,29 @@ error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:26:19 | LL | let _: ::Y; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | let _: ::Y; + | + error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:28:12 | LL | ::Y; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | ::Y; + | + error[E0576]: cannot find associated type `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:30:24 @@ -87,17 +115,27 @@ LL | type Y = u16; | ------------- similarly named associated type `Y` defined here ... LL | let _: ::N::NN; - | ^ help: an associated type with a similar name exists: `Y` + | ^ + | +help: an associated type with a similar name exists + | +LL - let _: ::N::NN; +LL + let _: ::Y::NN; + | error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:31:19 | LL | let _: ::N::NN; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | let _: ::N::NN; + | + error[E0404]: expected trait, found type alias `A` --> $DIR/ufcs-partially-resolved.rs:32:19 @@ -118,17 +156,27 @@ LL | type Y = u16; | ------------- similarly named associated type `Y` defined here ... LL | ::N::NN; - | ^ help: an associated type with a similar name exists: `Y` + | ^ + | +help: an associated type with a similar name exists + | +LL - ::N::NN; +LL + ::Y::NN; + | error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:34:12 | LL | ::N::NN; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | ::N::NN; + | + error[E0404]: expected trait, found type alias `A` --> $DIR/ufcs-partially-resolved.rs:35:12 @@ -146,21 +194,29 @@ error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:37:19 | LL | let _: ::Y::NN; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | let _: ::Y::NN; + | + error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:39:12 | LL | ::Y::NN; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | ::Y::NN; + | + error[E0405]: cannot find trait `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:41:23 @@ -229,9 +285,13 @@ LL | type X = u16; | ------------- similarly named associated type `X` defined here ... LL | let _: ::Z; - | ^^^^^^^^^^^^- - | | - | help: an associated type with a similar name exists: `X` + | ^^^^^^^^^^^^^ + | +help: an associated type with a similar name exists + | +LL - let _: ::Z; +LL + let _: ::X; + | error[E0575]: expected method or associated constant, found associated type `Dr::X` --> $DIR/ufcs-partially-resolved.rs:53:5 @@ -240,9 +300,13 @@ LL | fn Z() {} | ------ similarly named associated function `Z` defined here ... LL | ::X; - | ^^^^^^^^^^^^- - | | - | help: an associated function with a similar name exists: `Z` + | ^^^^^^^^^^^^^ + | +help: an associated function with a similar name exists + | +LL - ::X; +LL + ::Z; + | error[E0575]: expected associated type, found associated function `Dr::Z` --> $DIR/ufcs-partially-resolved.rs:54:12 @@ -251,9 +315,13 @@ LL | type X = u16; | ------------- similarly named associated type `X` defined here ... LL | let _: ::Z::N; - | ^^^^^^^^^^^^-^^^ - | | - | help: an associated type with a similar name exists: `X` + | ^^^^^^^^^^^^^^^^ + | +help: an associated type with a similar name exists + | +LL - let _: ::Z::N; +LL + let _: ::X::N; + | error[E0223]: ambiguous associated type --> $DIR/ufcs-partially-resolved.rs:36:12 diff --git a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr index 5f22c781345f..7e295c1d54f9 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr @@ -8,7 +8,13 @@ error[E0425]: cannot find value `y` in this scope --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:26 | LL | closure(&mut p, &y); - | ^ help: a local variable with a similar name exists: `p` + | ^ + | +help: a local variable with a similar name exists + | +LL - closure(&mut p, &y); +LL + closure(&mut p, &p); + | error[E0308]: mismatched types --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:17 From d0e4b5b159d2df4ba7c6c113171e3f6049d889f9 Mon Sep 17 00:00:00 2001 From: irelaxcn Date: Wed, 10 Dec 2025 01:34:25 +0800 Subject: [PATCH 0483/3801] Fix typo in deprecated lint `string_to_string` message --- clippy_lints/src/deprecated_lints.rs | 2 +- tests/ui/deprecated.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs index f010d17917f9..6e62e983d2f3 100644 --- a/clippy_lints/src/deprecated_lints.rs +++ b/clippy_lints/src/deprecated_lints.rs @@ -34,7 +34,7 @@ declare_with_version! { DEPRECATED(DEPRECATED_VERSION) = [ #[clippy::version = "pre 1.29.0"] ("clippy::should_assert_eq", "`assert!(a == b)` can now print the values the same way `assert_eq!(a, b) can"), #[clippy::version = "1.91.0"] - ("clippy::string_to_string", "`clippy:implicit_clone` covers those cases"), + ("clippy::string_to_string", "`clippy::implicit_clone` covers those cases"), #[clippy::version = "pre 1.29.0"] ("clippy::unsafe_vector_initialization", "the suggested alternative could be substantially slower"), #[clippy::version = "pre 1.29.0"] diff --git a/tests/ui/deprecated.stderr b/tests/ui/deprecated.stderr index cd225da611c4..fa70371b926f 100644 --- a/tests/ui/deprecated.stderr +++ b/tests/ui/deprecated.stderr @@ -61,7 +61,7 @@ error: lint `clippy::should_assert_eq` has been removed: `assert!(a == b)` can n LL | #![warn(clippy::should_assert_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: lint `clippy::string_to_string` has been removed: `clippy:implicit_clone` covers those cases +error: lint `clippy::string_to_string` has been removed: `clippy::implicit_clone` covers those cases --> tests/ui/deprecated.rs:15:9 | LL | #![warn(clippy::string_to_string)] From 1232c81a3eb6403b04a1795fe5e4bdb678f236fe Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 9 Dec 2025 22:56:23 +0100 Subject: [PATCH 0484/3801] Add needless_type_cast lint --- CHANGELOG.md | 1 + README.md | 2 +- book/src/README.md | 2 +- clippy_lints/src/casts/mod.rs | 32 ++ clippy_lints/src/casts/needless_type_cast.rs | 289 +++++++++++++++++++ clippy_lints/src/declared_lints.rs | 1 + tests/ui/needless_type_cast.fixed | 182 ++++++++++++ tests/ui/needless_type_cast.rs | 182 ++++++++++++ tests/ui/needless_type_cast.stderr | 71 +++++ 9 files changed, 760 insertions(+), 2 deletions(-) create mode 100644 clippy_lints/src/casts/needless_type_cast.rs create mode 100644 tests/ui/needless_type_cast.fixed create mode 100644 tests/ui/needless_type_cast.rs create mode 100644 tests/ui/needless_type_cast.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c81fa47eca9..dfbd07e69e53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6688,6 +6688,7 @@ Released 2018-09-13 [`needless_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return [`needless_return_with_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return_with_question_mark [`needless_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_splitn +[`needless_type_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_type_cast [`needless_update`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_update [`neg_cmp_op_on_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_cmp_op_on_partial_ord [`neg_multiply`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_multiply diff --git a/README.md b/README.md index 20a5e997e629..78498c73ae78 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are over 800 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category. diff --git a/book/src/README.md b/book/src/README.md index 5d2c3972b060..c5b264c9f703 100644 --- a/book/src/README.md +++ b/book/src/README.md @@ -5,7 +5,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are over 800 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 47cc1da0a6e9..494d6180d3cb 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -19,6 +19,7 @@ mod fn_to_numeric_cast; mod fn_to_numeric_cast_any; mod fn_to_numeric_cast_with_truncation; mod manual_dangling_ptr; +mod needless_type_cast; mod ptr_as_ptr; mod ptr_cast_constness; mod ref_as_ptr; @@ -813,6 +814,32 @@ declare_clippy_lint! { "casting a primitive method pointer to any integer type" } +declare_clippy_lint! { + /// ### What it does + /// Checks for bindings (constants, statics, or let bindings) that are defined + /// with one numeric type but are consistently cast to a different type in all usages. + /// + /// ### Why is this bad? + /// If a binding is always cast to a different type when used, it would be clearer + /// and more efficient to define it with the target type from the start. + /// + /// ### Example + /// ```no_run + /// const SIZE: u16 = 15; + /// let arr: [u8; SIZE as usize] = [0; SIZE as usize]; + /// ``` + /// + /// Use instead: + /// ```no_run + /// const SIZE: usize = 15; + /// let arr: [u8; SIZE] = [0; SIZE]; + /// ``` + #[clippy::version = "1.93.0"] + pub NEEDLESS_TYPE_CAST, + pedantic, + "binding defined with one type but always cast to another" +} + pub struct Casts { msrv: Msrv, } @@ -851,6 +878,7 @@ impl_lint_pass!(Casts => [ AS_POINTER_UNDERSCORE, MANUAL_DANGLING_PTR, CONFUSING_METHOD_TO_NUMERIC_CAST, + NEEDLESS_TYPE_CAST, ]); impl<'tcx> LateLintPass<'tcx> for Casts { @@ -920,4 +948,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts { cast_slice_different_sizes::check(cx, expr, self.msrv); ptr_cast_constness::check_null_ptr_cast_method(cx, expr); } + + fn check_body(&mut self, cx: &LateContext<'tcx>, body: &rustc_hir::Body<'tcx>) { + needless_type_cast::check(cx, body); + } } diff --git a/clippy_lints/src/casts/needless_type_cast.rs b/clippy_lints/src/casts/needless_type_cast.rs new file mode 100644 index 000000000000..ca6aa0f87bbf --- /dev/null +++ b/clippy_lints/src/casts/needless_type_cast.rs @@ -0,0 +1,289 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::visitors::{Descend, for_each_expr, for_each_expr_without_closures}; +use core::ops::ControlFlow; +use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{BlockCheckMode, Body, Expr, ExprKind, HirId, LetStmt, PatKind, StmtKind, UnsafeSource}; +use rustc_lint::LateContext; +use rustc_middle::ty::{Ty, TypeVisitableExt}; +use rustc_span::Span; + +use super::NEEDLESS_TYPE_CAST; + +struct BindingInfo<'a> { + source_ty: Ty<'a>, + ty_span: Span, +} + +struct UsageInfo<'a> { + cast_to: Option>, + in_generic_context: bool, +} + +pub(super) fn check<'a>(cx: &LateContext<'a>, body: &Body<'a>) { + let mut bindings: FxHashMap> = FxHashMap::default(); + + for_each_expr_without_closures(body.value, |expr| { + match expr.kind { + ExprKind::Block(block, _) => { + for stmt in block.stmts { + if let StmtKind::Let(let_stmt) = stmt.kind { + collect_binding_from_local(cx, let_stmt, &mut bindings); + } + } + }, + ExprKind::Let(let_expr) => { + collect_binding_from_let(cx, let_expr, &mut bindings); + }, + _ => {}, + } + ControlFlow::<()>::Continue(()) + }); + + #[allow(rustc::potential_query_instability)] + let mut binding_vec: Vec<_> = bindings.into_iter().collect(); + binding_vec.sort_by_key(|(_, info)| info.ty_span.lo()); + + for (hir_id, binding_info) in binding_vec { + check_binding_usages(cx, body, hir_id, &binding_info); + } +} + +fn collect_binding_from_let<'a>( + cx: &LateContext<'a>, + let_expr: &rustc_hir::LetExpr<'a>, + bindings: &mut FxHashMap>, +) { + if let_expr.ty.is_none() + || let_expr.span.from_expansion() + || has_generic_return_type(cx, let_expr.init) + || contains_unsafe(let_expr.init) + { + return; + } + + if let PatKind::Binding(_, hir_id, _, _) = let_expr.pat.kind + && let Some(ty_hir) = let_expr.ty + { + let ty = cx.typeck_results().pat_ty(let_expr.pat); + if ty.is_numeric() { + bindings.insert( + hir_id, + BindingInfo { + source_ty: ty, + ty_span: ty_hir.span, + }, + ); + } + } +} + +fn collect_binding_from_local<'a>( + cx: &LateContext<'a>, + let_stmt: &LetStmt<'a>, + bindings: &mut FxHashMap>, +) { + if let_stmt.ty.is_none() + || let_stmt.span.from_expansion() + || let_stmt + .init + .is_some_and(|init| has_generic_return_type(cx, init) || contains_unsafe(init)) + { + return; + } + + if let PatKind::Binding(_, hir_id, _, _) = let_stmt.pat.kind + && let Some(ty_hir) = let_stmt.ty + { + let ty = cx.typeck_results().pat_ty(let_stmt.pat); + if ty.is_numeric() { + bindings.insert( + hir_id, + BindingInfo { + source_ty: ty, + ty_span: ty_hir.span, + }, + ); + } + } +} + +fn contains_unsafe(expr: &Expr<'_>) -> bool { + for_each_expr_without_closures(expr, |e| { + if let ExprKind::Block(block, _) = e.kind + && let BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) = block.rules + { + return ControlFlow::Break(()); + } + ControlFlow::Continue(()) + }) + .is_some() +} + +fn has_generic_return_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + match &expr.kind { + ExprKind::Block(block, _) => { + if let Some(tail_expr) = block.expr { + return has_generic_return_type(cx, tail_expr); + } + false + }, + ExprKind::If(_, then_block, else_expr) => { + has_generic_return_type(cx, then_block) || else_expr.is_some_and(|e| has_generic_return_type(cx, e)) + }, + ExprKind::Match(_, arms, _) => arms.iter().any(|arm| has_generic_return_type(cx, arm.body)), + ExprKind::Loop(block, label, ..) => for_each_expr_without_closures(*block, |e| { + match e.kind { + ExprKind::Loop(..) => { + // Unlabeled breaks inside nested loops target the inner loop, not ours + return ControlFlow::Continue(Descend::No); + }, + ExprKind::Break(dest, Some(break_expr)) => { + let targets_this_loop = + dest.label.is_none() || dest.label.map(|l| l.ident) == label.map(|l| l.ident); + if targets_this_loop && has_generic_return_type(cx, break_expr) { + return ControlFlow::Break(()); + } + }, + _ => {}, + } + ControlFlow::Continue(Descend::Yes) + }) + .is_some(), + ExprKind::MethodCall(..) => { + if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { + let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let ret_ty = sig.output().skip_binder(); + return ret_ty.has_param(); + } + false + }, + ExprKind::Call(callee, _) => { + if let ExprKind::Path(qpath) = &callee.kind { + let res = cx.qpath_res(qpath, callee.hir_id); + if let Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) = res { + let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let ret_ty = sig.output().skip_binder(); + return ret_ty.has_param(); + } + } + false + }, + _ => false, + } +} + +fn is_generic_res(cx: &LateContext<'_>, res: Res) -> bool { + let has_type_params = |def_id| { + cx.tcx + .generics_of(def_id) + .own_params + .iter() + .any(|p| p.kind.is_ty_or_const()) + }; + match res { + Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => has_type_params(def_id), + // Ctor → Variant → ADT: constructor's parent is variant, variant's parent is the ADT + Res::Def(DefKind::Ctor(..), def_id) => has_type_params(cx.tcx.parent(cx.tcx.parent(def_id))), + _ => false, + } +} + +fn is_cast_in_generic_context<'a>(cx: &LateContext<'a>, cast_expr: &Expr<'a>) -> bool { + let mut current_id = cast_expr.hir_id; + + loop { + let parent_id = cx.tcx.parent_hir_id(current_id); + if parent_id == current_id { + return false; + } + + let parent = cx.tcx.hir_node(parent_id); + + match parent { + rustc_hir::Node::Expr(parent_expr) => { + match &parent_expr.kind { + ExprKind::Closure(_) => return false, + ExprKind::Call(callee, _) => { + if let ExprKind::Path(qpath) = &callee.kind { + let res = cx.qpath_res(qpath, callee.hir_id); + if is_generic_res(cx, res) { + return true; + } + } + }, + ExprKind::MethodCall(..) => { + if let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent_expr.hir_id) + && cx + .tcx + .generics_of(def_id) + .own_params + .iter() + .any(|p| p.kind.is_ty_or_const()) + { + return true; + } + }, + _ => {}, + } + current_id = parent_id; + }, + _ => return false, + } + } +} + +fn check_binding_usages<'a>(cx: &LateContext<'a>, body: &Body<'a>, hir_id: HirId, binding_info: &BindingInfo<'a>) { + let mut usages = Vec::new(); + + for_each_expr(cx, body.value, |expr| { + if let ExprKind::Path(ref qpath) = expr.kind + && !expr.span.from_expansion() + && let Res::Local(id) = cx.qpath_res(qpath, expr.hir_id) + && id == hir_id + { + let parent_id = cx.tcx.parent_hir_id(expr.hir_id); + let parent = cx.tcx.hir_node(parent_id); + + let usage = if let rustc_hir::Node::Expr(parent_expr) = parent + && let ExprKind::Cast(..) = parent_expr.kind + && !parent_expr.span.from_expansion() + { + UsageInfo { + cast_to: Some(cx.typeck_results().expr_ty(parent_expr)), + in_generic_context: is_cast_in_generic_context(cx, parent_expr), + } + } else { + UsageInfo { + cast_to: None, + in_generic_context: false, + } + }; + usages.push(usage); + } + ControlFlow::<()>::Continue(()) + }); + + let Some(first_target) = usages + .first() + .and_then(|u| u.cast_to) + .filter(|&t| t != binding_info.source_ty) + .filter(|&t| usages.iter().all(|u| u.cast_to == Some(t) && !u.in_generic_context)) + else { + return; + }; + + span_lint_and_sugg( + cx, + NEEDLESS_TYPE_CAST, + binding_info.ty_span, + format!( + "this binding is defined as `{}` but is always cast to `{}`", + binding_info.source_ty, first_target + ), + "consider defining it as", + first_target.to_string(), + Applicability::MaybeIncorrect, + ); +} diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 1a02c2166454..87d75234ebc0 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -70,6 +70,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO, crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO, crate::casts::MANUAL_DANGLING_PTR_INFO, + crate::casts::NEEDLESS_TYPE_CAST_INFO, crate::casts::PTR_AS_PTR_INFO, crate::casts::PTR_CAST_CONSTNESS_INFO, crate::casts::REF_AS_PTR_INFO, diff --git a/tests/ui/needless_type_cast.fixed b/tests/ui/needless_type_cast.fixed new file mode 100644 index 000000000000..32c348d3ca3a --- /dev/null +++ b/tests/ui/needless_type_cast.fixed @@ -0,0 +1,182 @@ +#![warn(clippy::needless_type_cast)] +#![allow(clippy::no_effect, clippy::unnecessary_cast, unused)] + +fn takes_i32(x: i32) -> i32 { + x +} + +fn generic(x: T) -> T { + x +} + +fn main() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = a as i32 + 5; + let _ = a as i32 * 2; + + let b: u16 = 20; + let _ = b; + let _ = b as u32; + + let c: u8 = 5; + let _ = c as u16; + let _ = c as u32; + + let d: i32 = 100; + let _ = d + 1; + + let e = 42u8; + let _ = e as i64; + let _ = e as i64 + 10; + + let f: usize = 1; + //~^ needless_type_cast + let _ = f as usize; +} + +fn test_function_call() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = takes_i32(a as i32); + let _ = takes_i32(a as i32); +} + +fn test_generic_call() { + let a: u8 = 10; + let _ = generic(a as i32); + let _ = generic(a as i32); +} + +fn test_method_on_cast() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = (a as i32).checked_add(5); + let _ = (a as i32).saturating_mul(2); +} + +fn test_iterator_sum() { + let a: i32 = 10; + //~^ needless_type_cast + let arr = [a as i32, a as i32]; + let _: i32 = arr.iter().copied().sum(); +} + +fn test_closure() { + let a: i32 = 10; + //~^ needless_type_cast + let _: i32 = [1i32, 2].iter().map(|x| x + a as i32).sum(); +} + +fn test_struct_field() { + struct S { + x: i32, + y: i32, + } + + let a: i32 = 10; + //~^ needless_type_cast + let _ = S { + x: a as i32, + y: a as i32, + }; +} + +fn test_option() { + let a: u8 = 10; + let _: Option = Some(a as i32); + let _: Option = Some(a as i32); +} + +fn test_mixed_context() { + let a: u8 = 10; + let _ = takes_i32(a as i32); + let _ = generic(a as i32); +} + +fn test_nested_block() { + if true { + let a: i32 = 10; + //~^ needless_type_cast + let _ = a as i32 + 1; + let _ = a as i32 * 2; + } +} + +fn test_match_expr() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = match 1 { + 1 => a as i32, + _ => a as i32, + }; +} + +fn test_return_expr() -> i32 { + let a: i32 = 10; + //~^ needless_type_cast + a as i32 +} + +fn test_closure_always_cast() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = [1, 2].iter().map(|_| a as i32).sum::(); + let _ = a as i32; +} + +fn test_closure_mixed_usage() { + let a: u8 = 10; + let _ = [1, 2].iter().map(|_| a as i32).sum::(); + let _ = a + 1; +} + +fn test_nested_generic_call() { + let a: u8 = 10; + let _ = generic(takes_i32(a as i32)); + let _ = generic(takes_i32(a as i32)); +} + +fn test_generic_initializer() { + // Should not lint: changing type would affect what generic() returns + let a: u8 = generic(10u8); + let _ = a as i32; + let _ = a as i32; +} + +fn test_unsafe_transmute() { + // Should not lint: initializer contains unsafe block + #[allow(clippy::useless_transmute)] + let x: u32 = unsafe { std::mem::transmute(0u32) }; + let _ = x as u64; +} + +fn test_if_with_generic() { + // Should not lint: one branch has generic return type + let x: u8 = if true { generic(1) } else { 2 }; + let _ = x as i32; +} + +fn test_match_with_generic() { + // Should not lint: one branch has generic return type + let x: u8 = match 1 { + 1 => generic(1), + _ => 2, + }; + let _ = x as i32; +} + +fn test_default() { + // Should not lint: Default::default() has generic return type + let x: u8 = Default::default(); + let _ = x as i32; +} + +fn test_loop_with_generic() { + // Should not lint: loop break has generic return type + #[allow(clippy::never_loop)] + let x: u8 = loop { + break generic(1); + }; + let _ = x as i32; +} diff --git a/tests/ui/needless_type_cast.rs b/tests/ui/needless_type_cast.rs new file mode 100644 index 000000000000..e28f620e035f --- /dev/null +++ b/tests/ui/needless_type_cast.rs @@ -0,0 +1,182 @@ +#![warn(clippy::needless_type_cast)] +#![allow(clippy::no_effect, clippy::unnecessary_cast, unused)] + +fn takes_i32(x: i32) -> i32 { + x +} + +fn generic(x: T) -> T { + x +} + +fn main() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = a as i32 + 5; + let _ = a as i32 * 2; + + let b: u16 = 20; + let _ = b; + let _ = b as u32; + + let c: u8 = 5; + let _ = c as u16; + let _ = c as u32; + + let d: i32 = 100; + let _ = d + 1; + + let e = 42u8; + let _ = e as i64; + let _ = e as i64 + 10; + + let f: u8 = 1; + //~^ needless_type_cast + let _ = f as usize; +} + +fn test_function_call() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = takes_i32(a as i32); + let _ = takes_i32(a as i32); +} + +fn test_generic_call() { + let a: u8 = 10; + let _ = generic(a as i32); + let _ = generic(a as i32); +} + +fn test_method_on_cast() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = (a as i32).checked_add(5); + let _ = (a as i32).saturating_mul(2); +} + +fn test_iterator_sum() { + let a: u8 = 10; + //~^ needless_type_cast + let arr = [a as i32, a as i32]; + let _: i32 = arr.iter().copied().sum(); +} + +fn test_closure() { + let a: u8 = 10; + //~^ needless_type_cast + let _: i32 = [1i32, 2].iter().map(|x| x + a as i32).sum(); +} + +fn test_struct_field() { + struct S { + x: i32, + y: i32, + } + + let a: u8 = 10; + //~^ needless_type_cast + let _ = S { + x: a as i32, + y: a as i32, + }; +} + +fn test_option() { + let a: u8 = 10; + let _: Option = Some(a as i32); + let _: Option = Some(a as i32); +} + +fn test_mixed_context() { + let a: u8 = 10; + let _ = takes_i32(a as i32); + let _ = generic(a as i32); +} + +fn test_nested_block() { + if true { + let a: u8 = 10; + //~^ needless_type_cast + let _ = a as i32 + 1; + let _ = a as i32 * 2; + } +} + +fn test_match_expr() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = match 1 { + 1 => a as i32, + _ => a as i32, + }; +} + +fn test_return_expr() -> i32 { + let a: u8 = 10; + //~^ needless_type_cast + a as i32 +} + +fn test_closure_always_cast() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = [1, 2].iter().map(|_| a as i32).sum::(); + let _ = a as i32; +} + +fn test_closure_mixed_usage() { + let a: u8 = 10; + let _ = [1, 2].iter().map(|_| a as i32).sum::(); + let _ = a + 1; +} + +fn test_nested_generic_call() { + let a: u8 = 10; + let _ = generic(takes_i32(a as i32)); + let _ = generic(takes_i32(a as i32)); +} + +fn test_generic_initializer() { + // Should not lint: changing type would affect what generic() returns + let a: u8 = generic(10u8); + let _ = a as i32; + let _ = a as i32; +} + +fn test_unsafe_transmute() { + // Should not lint: initializer contains unsafe block + #[allow(clippy::useless_transmute)] + let x: u32 = unsafe { std::mem::transmute(0u32) }; + let _ = x as u64; +} + +fn test_if_with_generic() { + // Should not lint: one branch has generic return type + let x: u8 = if true { generic(1) } else { 2 }; + let _ = x as i32; +} + +fn test_match_with_generic() { + // Should not lint: one branch has generic return type + let x: u8 = match 1 { + 1 => generic(1), + _ => 2, + }; + let _ = x as i32; +} + +fn test_default() { + // Should not lint: Default::default() has generic return type + let x: u8 = Default::default(); + let _ = x as i32; +} + +fn test_loop_with_generic() { + // Should not lint: loop break has generic return type + #[allow(clippy::never_loop)] + let x: u8 = loop { + break generic(1); + }; + let _ = x as i32; +} diff --git a/tests/ui/needless_type_cast.stderr b/tests/ui/needless_type_cast.stderr new file mode 100644 index 000000000000..3ee9df1043e7 --- /dev/null +++ b/tests/ui/needless_type_cast.stderr @@ -0,0 +1,71 @@ +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:13:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + | + = note: `-D clippy::needless-type-cast` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_type_cast)]` + +error: this binding is defined as `u8` but is always cast to `usize` + --> tests/ui/needless_type_cast.rs:33:12 + | +LL | let f: u8 = 1; + | ^^ help: consider defining it as: `usize` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:39:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:52:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:59:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:66:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:77:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:99:16 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:107:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:116:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:122:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: aborting due to 11 previous errors + From 85e3acc947064454d907cc5a4195a7dcbc4193a9 Mon Sep 17 00:00:00 2001 From: Roy Ammerschuber Date: Wed, 3 Dec 2025 11:56:07 +0100 Subject: [PATCH 0485/3801] tree borrows: put accesses diagnostics data into single struct --- .../tree_borrows/diagnostics.rs | 66 ++++++--- .../src/borrow_tracker/tree_borrows/tree.rs | 130 +++++++----------- 2 files changed, 94 insertions(+), 102 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs index a91f35a9dcad..055baca8542f 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs @@ -77,6 +77,32 @@ pub struct Event { pub span: Span, } +/// Diagnostics data about the current access and the location we are accessing. +/// Used to create history events and errors. +#[derive(Clone, Debug)] +pub struct DiagnosticInfo { + pub alloc_id: AllocId, + pub span: Span, + /// The range the diagnostic actually applies to. + /// This is always a subset of `access_range`. + pub transition_range: Range, + /// The range the access is happening to. Is `None` if this is the protector release access + pub access_range: Option, + pub access_cause: AccessCause, +} +impl DiagnosticInfo { + /// Creates a history event. + pub fn create_event(&self, transition: PermTransition, is_foreign: bool) -> Event { + Event { + transition, + is_foreign, + access_cause: self.access_cause, + access_range: self.access_range, + transition_range: self.transition_range.clone(), + span: self.span, + } + } +} /// List of all events that affected a tag. /// NOTE: not all of these events are relevant for a particular location, /// the events should be filtered before the generation of diagnostics. @@ -280,32 +306,29 @@ impl History { pub(super) struct TbError<'node> { /// What failure occurred. pub error_kind: TransitionError, - /// The allocation in which the error is happening. - pub alloc_id: AllocId, - /// The offset (into the allocation) at which the conflict occurred. - pub error_offset: u64, + /// Diagnostic data about the access that caused the error. + pub access_info: &'node DiagnosticInfo, /// The tag on which the error was triggered. /// On protector violations, this is the tag that was protected. /// On accesses rejected due to insufficient permissions, this is the /// tag that lacked those permissions. - pub conflicting_info: &'node NodeDebugInfo, - // What kind of access caused this error (read, write, reborrow, deallocation) - pub access_cause: AccessCause, + pub conflicting_node_info: &'node NodeDebugInfo, /// Which tag, if any, the access that caused this error was made through, i.e. /// which tag was used to read/write/deallocate. /// Not set on wildcard accesses. - pub accessed_info: Option<&'node NodeDebugInfo>, + pub accessed_node_info: Option<&'node NodeDebugInfo>, } impl TbError<'_> { /// Produce a UB error. pub fn build<'tcx>(self) -> InterpErrorKind<'tcx> { use TransitionError::*; - let cause = self.access_cause; - let accessed = self.accessed_info; + let cause = self.access_info.access_cause; + let error_offset = self.access_info.transition_range.start; + let accessed = self.accessed_node_info; let accessed_str = - self.accessed_info.map(|v| format!("{v}")).unwrap_or_else(|| "".into()); - let conflicting = self.conflicting_info; + self.accessed_node_info.map(|v| format!("{v}")).unwrap_or_else(|| "".into()); + let conflicting = self.conflicting_node_info; // An access is considered conflicting if it happened through a // different tag than the one who caused UB. // When doing a wildcard access (where `accessed` is `None`) we @@ -316,9 +339,8 @@ impl TbError<'_> { // all tags through which an access would cause UB. let accessed_is_conflicting = accessed.map(|a| a.tag) == Some(conflicting.tag); let title = format!( - "{cause} through {accessed_str} at {alloc_id:?}[{offset:#x}] is forbidden", - alloc_id = self.alloc_id, - offset = self.error_offset + "{cause} through {accessed_str} at {alloc_id:?}[{error_offset:#x}] is forbidden", + alloc_id = self.access_info.alloc_id ); let (title, details, conflicting_tag_name) = match self.error_kind { ChildAccessForbidden(perm) => { @@ -362,13 +384,13 @@ impl TbError<'_> { } }; let mut history = HistoryData::default(); - if let Some(accessed_info) = self.accessed_info + if let Some(accessed_info) = self.accessed_node_info && !accessed_is_conflicting { history.extend(accessed_info.history.forget(), "accessed", false); } history.extend( - self.conflicting_info.history.extract_relevant(self.error_offset, self.error_kind), + self.conflicting_node_info.history.extract_relevant(error_offset, self.error_kind), conflicting_tag_name, true, ); @@ -379,12 +401,12 @@ impl TbError<'_> { /// Cannot access this allocation with wildcard provenance, as there are no /// valid exposed references for this access kind. pub fn no_valid_exposed_references_error<'tcx>( - alloc_id: AllocId, - offset: u64, - access_cause: AccessCause, + DiagnosticInfo { alloc_id, transition_range, access_cause, .. }: &DiagnosticInfo, ) -> InterpErrorKind<'tcx> { - let title = - format!("{access_cause} through at {alloc_id:?}[{offset:#x}] is forbidden"); + let title = format!( + "{access_cause} through at {alloc_id:?}[{offset:#x}] is forbidden", + offset = transition_range.start + ); let details = vec![format!("there are no exposed tags which may perform this access here")]; let history = HistoryData::default(); err_machine_stop!(TerminationInfo::TreeBorrowsUb { title, details, history }) diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 7630c73f4dac..900e9c3729c8 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -18,12 +18,12 @@ use rustc_data_structures::fx::FxHashSet; use rustc_span::Span; use smallvec::SmallVec; -use super::Permission; use super::diagnostics::{ - self, AccessCause, NodeDebugInfo, TbError, TransitionError, no_valid_exposed_references_error, + AccessCause, DiagnosticInfo, NodeDebugInfo, TbError, TransitionError, + no_valid_exposed_references_error, }; use super::foreign_access_skipping::IdempotentForeignAccess; -use super::perms::PermTransition; +use super::perms::{PermTransition, Permission}; use super::tree_visitor::{ChildrenVisitMode, ContinueTraversal, NodeAppArgs, TreeVisitor}; use super::unimap::{UniIndex, UniKeyMap, UniValMap}; use super::wildcard::WildcardState; @@ -91,12 +91,9 @@ impl LocationState { nodes: &mut UniValMap, wildcard_accesses: &mut UniValMap, access_kind: AccessKind, - access_cause: AccessCause, //diagnostics - access_range: Option, //diagnostics relatedness: AccessRelatedness, - span: Span, //diagnostics - location_range: Range, //diagnostics protected: bool, + diagnostics: &DiagnosticInfo, ) -> Result<(), TransitionError> { // Call this function now (i.e. only if we know `relatedness`), which // ensures it is only called when `skip_if_known_noop` returns @@ -107,14 +104,9 @@ impl LocationState { if !transition.is_noop() { let node = nodes.get_mut(idx).unwrap(); // Record the event as part of the history. - node.debug_info.history.push(diagnostics::Event { - transition, - is_foreign: relatedness.is_foreign(), - access_cause, - access_range, - transition_range: location_range, - span, - }); + node.debug_info + .history + .push(diagnostics.create_event(transition, relatedness.is_foreign())); // We need to update the wildcard state, if the permission // of an exposed pointer changes. @@ -546,7 +538,7 @@ impl<'tcx> Tree { prov, access_range, AccessKind::Write, - diagnostics::AccessCause::Dealloc, + AccessCause::Dealloc, global, alloc_id, span, @@ -560,6 +552,13 @@ impl<'tcx> Tree { // Check if this breaks any strong protector. // (Weak protectors are already handled by `perform_access`.) for (loc_range, loc) in self.locations.iter_mut(access_range.start, access_range.size) { + let diagnostics = DiagnosticInfo { + alloc_id, + span, + transition_range: loc_range, + access_range: Some(access_range), + access_cause: AccessCause::Dealloc, + }; // Checks the tree containing `idx` for strong protector violations. // It does this in traversal order. let mut check_tree = |idx| { @@ -586,12 +585,10 @@ impl<'tcx> Tree { && perm.accessed { Err(TbError { - conflicting_info: &node.debug_info, - access_cause: diagnostics::AccessCause::Dealloc, - alloc_id, - error_offset: loc_range.start, error_kind: TransitionError::ProtectedDealloc, - accessed_info: start_idx + access_info: &diagnostics, + conflicting_node_info: &node.debug_info, + accessed_node_info: start_idx .map(|idx| &args.nodes.get(idx).unwrap().debug_info), } .build()) @@ -649,18 +646,21 @@ impl<'tcx> Tree { }; // We iterate over affected locations and traverse the tree for each of them. for (loc_range, loc) in self.locations.iter_mut(access_range.start, access_range.size) { + let diagnostics = DiagnosticInfo { + access_cause, + access_range: Some(access_range), + alloc_id, + span, + transition_range: loc_range, + }; loc.perform_access( self.roots.iter().copied(), &mut self.nodes, source_idx, - loc_range, - Some(access_range), access_kind, - access_cause, global, - alloc_id, - span, ChildrenVisitMode::VisitChildrenOfAccessed, + &diagnostics, )?; } interp_ok(()) @@ -701,19 +701,21 @@ impl<'tcx> Tree { && let Some(access_kind) = p.permission.protector_end_access() && p.accessed { - let access_cause = diagnostics::AccessCause::FnExit(access_kind); + let diagnostics = DiagnosticInfo { + access_cause: AccessCause::FnExit(access_kind), + access_range: None, + alloc_id, + span, + transition_range: loc_range, + }; loc.perform_access( self.roots.iter().copied(), &mut self.nodes, Some(source_idx), - loc_range, - None, access_kind, - access_cause, global, - alloc_id, - span, ChildrenVisitMode::SkipChildrenOfAccessed, + &diagnostics, )?; } } @@ -882,27 +884,19 @@ impl<'tcx> LocationTree { roots: impl Iterator, nodes: &mut UniValMap, access_source: Option, - loc_range: Range, // diagnostics - access_range: Option, // diagnostics access_kind: AccessKind, - access_cause: diagnostics::AccessCause, // diagnostics global: &GlobalState, - alloc_id: AllocId, // diagnostics - span: Span, // diagnostics visit_children: ChildrenVisitMode, + diagnostics: &DiagnosticInfo, ) -> InterpResult<'tcx> { let accessed_root = if let Some(idx) = access_source { Some(self.perform_normal_access( idx, nodes, - loc_range.clone(), - access_range, access_kind, - access_cause, global, - alloc_id, - span, visit_children, + diagnostics, )?) } else { // `SkipChildrenOfAccessed` only gets set on protector release, which only @@ -936,13 +930,9 @@ impl<'tcx> LocationTree { access_source, /*max_local_tag*/ accessed_root_tag, nodes, - loc_range.clone(), - access_range, access_kind, - access_cause, global, - alloc_id, - span, + diagnostics, )?; } interp_ok(()) @@ -958,14 +948,10 @@ impl<'tcx> LocationTree { &mut self, access_source: UniIndex, nodes: &mut UniValMap, - loc_range: Range, // diagnostics - access_range: Option, // diagnostics access_kind: AccessKind, - access_cause: diagnostics::AccessCause, // diagnostics global: &GlobalState, - alloc_id: AllocId, // diagnostics - span: Span, // diagnostics visit_children: ChildrenVisitMode, + diagnostics: &DiagnosticInfo, ) -> InterpResult<'tcx, UniIndex> { // Performs the per-node work: // - insert the permission if it does not exist @@ -997,21 +983,18 @@ impl<'tcx> LocationTree { args.nodes, &mut args.data.wildcard_accesses, access_kind, - access_cause, - access_range, args.rel_pos, - span, - loc_range.clone(), protected, + diagnostics, ) .map_err(|error_kind| { TbError { - conflicting_info: &args.nodes.get(args.idx).unwrap().debug_info, - access_cause, - alloc_id, - error_offset: loc_range.start, error_kind, - accessed_info: Some(&args.nodes.get(access_source).unwrap().debug_info), + access_info: diagnostics, + conflicting_node_info: &args.nodes.get(args.idx).unwrap().debug_info, + accessed_node_info: Some( + &args.nodes.get(access_source).unwrap().debug_info, + ), } .build() }) @@ -1040,13 +1023,9 @@ impl<'tcx> LocationTree { access_source: Option, max_local_tag: Option, nodes: &mut UniValMap, - loc_range: Range, // diagnostics - access_range: Option, // diagnostics access_kind: AccessKind, - access_cause: diagnostics::AccessCause, // diagnostics global: &GlobalState, - alloc_id: AllocId, // diagnostics - span: Span, // diagnostics + diagnostics: &DiagnosticInfo, ) -> InterpResult<'tcx> { let get_relatedness = |idx: UniIndex, node: &Node, loc: &LocationTree| { let wildcard_state = loc.wildcard_accesses.get(idx).cloned().unwrap_or_default(); @@ -1100,11 +1079,7 @@ impl<'tcx> LocationTree { // This can only happen if `root` is the main root: We set // `max_foreign_access==Write` on all wildcard roots, so at least a foreign access // is always possible on all nodes in a wildcard subtree. - return Err(no_valid_exposed_references_error( - alloc_id, - loc_range.start, - access_cause, - )); + return Err(no_valid_exposed_references_error(diagnostics)); }; let Some(relatedness) = wildcard_relatedness.to_relatedness() else { @@ -1123,22 +1098,17 @@ impl<'tcx> LocationTree { args.nodes, &mut args.data.wildcard_accesses, access_kind, - access_cause, - access_range, relatedness, - span, - loc_range.clone(), protected, + diagnostics, ) .map_err(|trans| { let node = args.nodes.get(args.idx).unwrap(); TbError { - conflicting_info: &node.debug_info, - access_cause, - alloc_id, - error_offset: loc_range.start, error_kind: trans, - accessed_info: access_source + access_info: diagnostics, + conflicting_node_info: &node.debug_info, + accessed_node_info: access_source .map(|idx| &args.nodes.get(idx).unwrap().debug_info), } .build() From a3b78e0320f9bdabb294cbef573d4fe0ddec771f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 23 Sep 2025 21:16:00 +0200 Subject: [PATCH 0486/3801] add `core::hint::prefetch_{read, write}_{data, instruction}` well, we don't expose `prefetch_write_instruction`, that one doesn't really make sense in practice. --- library/core/src/hint.rs | 112 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 71acede7e3eb..7a2752219eb5 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -823,3 +823,115 @@ where crate::intrinsics::select_unpredictable(condition, true_val, false_val).assume_init() } } + +/// The expected temporal locality of a memory prefetch operation. +/// +/// Locality expresses how likely the prefetched data is to be reused soon, +/// and therefore which level of cache it should be brought into. +/// +/// The locality is just a hint, and may be ignored on some targets or by the hardware. +/// +/// Used with functions like [`prefetch_read_data`] and [`prefetch_write_data`]. +/// +/// [`prefetch_read_data`]: crate::hint::prefetch_read_data +/// [`prefetch_write_data`]: crate::hint::prefetch_write_data +#[unstable(feature = "hint_prefetch", issue = "146941")] +#[non_exhaustive] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Locality { + /// Data is unlikely to be reused soon. + /// + /// Typically bypasses the caches so they are not polluted. + NonTemporal = 0, + /// Data is expected to be reused eventually. + /// + /// Typically prefetches into L3 cache (if the CPU supports it). + L3 = 1, + /// Data is expected to be reused in the near future. + /// + /// Typically prefetches into L2 cache. + L2 = 2, + /// Data is expected to be reused very soon. + /// + /// Typically prefetches into L1 cache. + L1 = 3, +} + +/// Prefetch the cache line containing `ptr` for a future read. +/// +/// A strategically placed prefetch can reduce cache miss latency if the data is accessed +/// soon after, but may also increase bandwidth usage or evict other cache lines. +/// +/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware. +/// +/// Passing a dangling or invalid pointer is permitted: the memory will not +/// actually be dereferenced, and no faults are raised. +/// +/// # Examples +/// +/// ``` +/// use std::hint::{Locality, prefetch_read_data}; +/// use std::mem::size_of_val; +/// +/// // Prefetch all of `slice` into the L1 cache. +/// fn prefetch_slice(slice: &[T]) { +/// // On most systems the cache line size is 64 bytes. +/// for offset in (0..size_of_val(slice)).step_by(64) { +/// prefetch_read_data(slice.as_ptr().wrapping_add(offset), Locality::L1); +/// } +/// } +/// ``` +#[inline(always)] +#[unstable(feature = "hint_prefetch", issue = "146941")] +pub const fn prefetch_read_data(ptr: *const T, locality: Locality) { + match locality { + Locality::NonTemporal => { + intrinsics::prefetch_read_data::(ptr) + } + Locality::L3 => intrinsics::prefetch_read_data::(ptr), + Locality::L2 => intrinsics::prefetch_read_data::(ptr), + Locality::L1 => intrinsics::prefetch_read_data::(ptr), + } +} + +/// Prefetch the cache line containing `ptr` for a future write. +/// +/// A strategically placed prefetch can reduce cache miss latency if the data is accessed +/// soon after, but may also increase bandwidth usage or evict other cache lines. +/// +/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware. +/// +/// Passing a dangling or invalid pointer is permitted: the memory will not +/// actually be dereferenced, and no faults are raised. +#[unstable(feature = "hint_prefetch", issue = "146941")] +pub const fn prefetch_write_data(ptr: *mut T, locality: Locality) { + match locality { + Locality::NonTemporal => { + intrinsics::prefetch_write_data::(ptr) + } + Locality::L3 => intrinsics::prefetch_write_data::(ptr), + Locality::L2 => intrinsics::prefetch_write_data::(ptr), + Locality::L1 => intrinsics::prefetch_write_data::(ptr), + } +} + +/// Prefetch the cache line containing `ptr` for a future read. +/// +/// A strategically placed prefetch can reduce cache miss latency if the instructions are +/// accessed soon after, but may also increase bandwidth usage or evict other cache lines. +/// +/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware. +/// +/// Passing a dangling or invalid pointer is permitted: the memory will not +/// actually be dereferenced, and no faults are raised. +#[unstable(feature = "hint_prefetch", issue = "146941")] +pub const fn prefetch_read_instruction(ptr: *const T, locality: Locality) { + match locality { + Locality::NonTemporal => { + intrinsics::prefetch_read_instruction::(ptr) + } + Locality::L3 => intrinsics::prefetch_read_instruction::(ptr), + Locality::L2 => intrinsics::prefetch_read_instruction::(ptr), + Locality::L1 => intrinsics::prefetch_read_instruction::(ptr), + } +} From 6407023007a69d4afd31b2ceff98e375bc5af43f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 25 Sep 2025 20:40:23 +0200 Subject: [PATCH 0487/3801] Add a separate function for a non-temporal read prefetch --- library/core/src/hint.rs | 68 +++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 7a2752219eb5..57fdb245c6a2 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -831,18 +831,14 @@ where /// /// The locality is just a hint, and may be ignored on some targets or by the hardware. /// -/// Used with functions like [`prefetch_read_data`] and [`prefetch_write_data`]. +/// Used with functions like [`prefetch_read`] and [`prefetch_write`]. /// -/// [`prefetch_read_data`]: crate::hint::prefetch_read_data -/// [`prefetch_write_data`]: crate::hint::prefetch_write_data +/// [`prefetch_read`]: crate::hint::prefetch_read +/// [`prefetch_write`]: crate::hint::prefetch_write #[unstable(feature = "hint_prefetch", issue = "146941")] #[non_exhaustive] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Locality { - /// Data is unlikely to be reused soon. - /// - /// Typically bypasses the caches so they are not polluted. - NonTemporal = 0, /// Data is expected to be reused eventually. /// /// Typically prefetches into L3 cache (if the CPU supports it). @@ -870,30 +866,46 @@ pub enum Locality { /// # Examples /// /// ``` -/// use std::hint::{Locality, prefetch_read_data}; +/// #![feature(hint_prefetch)] +/// use std::hint::{Locality, prefetch_read}; /// use std::mem::size_of_val; /// /// // Prefetch all of `slice` into the L1 cache. /// fn prefetch_slice(slice: &[T]) { /// // On most systems the cache line size is 64 bytes. /// for offset in (0..size_of_val(slice)).step_by(64) { -/// prefetch_read_data(slice.as_ptr().wrapping_add(offset), Locality::L1); +/// prefetch_read(slice.as_ptr().wrapping_add(offset), Locality::L1); /// } /// } /// ``` #[inline(always)] #[unstable(feature = "hint_prefetch", issue = "146941")] -pub const fn prefetch_read_data(ptr: *const T, locality: Locality) { +pub const fn prefetch_read(ptr: *const T, locality: Locality) { match locality { - Locality::NonTemporal => { - intrinsics::prefetch_read_data::(ptr) - } Locality::L3 => intrinsics::prefetch_read_data::(ptr), Locality::L2 => intrinsics::prefetch_read_data::(ptr), Locality::L1 => intrinsics::prefetch_read_data::(ptr), } } +/// Prefetch the cache line containing `ptr` for a single future read, but attempt to avoid +/// polluting the cache. +/// +/// A strategically placed prefetch can reduce cache miss latency if the data is accessed +/// soon after, but may also increase bandwidth usage or evict other cache lines. +/// +/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware. +/// +/// Passing a dangling or invalid pointer is permitted: the memory will not +/// actually be dereferenced, and no faults are raised. +#[inline(always)] +#[unstable(feature = "hint_prefetch", issue = "146941")] +pub const fn prefetch_read_non_temporal(ptr: *const T, locality: Locality) { + // The LLVM intrinsic does not currently support specifying the locality. + let _ = locality; + intrinsics::prefetch_read_data::(ptr) +} + /// Prefetch the cache line containing `ptr` for a future write. /// /// A strategically placed prefetch can reduce cache miss latency if the data is accessed @@ -903,19 +915,35 @@ pub const fn prefetch_read_data(ptr: *const T, locality: Locality) { /// /// Passing a dangling or invalid pointer is permitted: the memory will not /// actually be dereferenced, and no faults are raised. +#[inline(always)] #[unstable(feature = "hint_prefetch", issue = "146941")] -pub const fn prefetch_write_data(ptr: *mut T, locality: Locality) { +pub const fn prefetch_write(ptr: *mut T, locality: Locality) { match locality { - Locality::NonTemporal => { - intrinsics::prefetch_write_data::(ptr) - } Locality::L3 => intrinsics::prefetch_write_data::(ptr), Locality::L2 => intrinsics::prefetch_write_data::(ptr), Locality::L1 => intrinsics::prefetch_write_data::(ptr), } } -/// Prefetch the cache line containing `ptr` for a future read. +/// Prefetch the cache line containing `ptr` for a single future write, but attempt to avoid +/// polluting the cache. +/// +/// A strategically placed prefetch can reduce cache miss latency if the data is accessed +/// soon after, but may also increase bandwidth usage or evict other cache lines. +/// +/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware. +/// +/// Passing a dangling or invalid pointer is permitted: the memory will not +/// actually be dereferenced, and no faults are raised. +#[inline(always)] +#[unstable(feature = "hint_prefetch", issue = "146941")] +pub const fn prefetch_write_non_temporal(ptr: *const T, locality: Locality) { + // The LLVM intrinsic does not currently support specifying the locality. + let _ = locality; + intrinsics::prefetch_write_data::(ptr) +} + +/// Prefetch the cache line containing `ptr` into the instruction cache for a future read. /// /// A strategically placed prefetch can reduce cache miss latency if the instructions are /// accessed soon after, but may also increase bandwidth usage or evict other cache lines. @@ -924,12 +952,10 @@ pub const fn prefetch_write_data(ptr: *mut T, locality: Locality) { /// /// Passing a dangling or invalid pointer is permitted: the memory will not /// actually be dereferenced, and no faults are raised. +#[inline(always)] #[unstable(feature = "hint_prefetch", issue = "146941")] pub const fn prefetch_read_instruction(ptr: *const T, locality: Locality) { match locality { - Locality::NonTemporal => { - intrinsics::prefetch_read_instruction::(ptr) - } Locality::L3 => intrinsics::prefetch_read_instruction::(ptr), Locality::L2 => intrinsics::prefetch_read_instruction::(ptr), Locality::L1 => intrinsics::prefetch_read_instruction::(ptr), From b9e3e4162a66c6b520fa8c3bba6b9d33663c91e7 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 10 Dec 2025 00:17:57 +0100 Subject: [PATCH 0488/3801] remove explicit discriminants --- library/core/src/hint.rs | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 57fdb245c6a2..e2ac746d3149 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -842,15 +842,26 @@ pub enum Locality { /// Data is expected to be reused eventually. /// /// Typically prefetches into L3 cache (if the CPU supports it). - L3 = 1, + L3, /// Data is expected to be reused in the near future. /// /// Typically prefetches into L2 cache. - L2 = 2, + L2, /// Data is expected to be reused very soon. /// /// Typically prefetches into L1 cache. - L1 = 3, + L1, +} + +impl Locality { + /// Convert to the constant that LLVM associates with a locality. + const fn to_llvm(self) -> i32 { + match self { + Self::L3 => 1, + Self::L2 => 2, + Self::L1 => 3, + } + } } /// Prefetch the cache line containing `ptr` for a future read. @@ -882,9 +893,9 @@ pub enum Locality { #[unstable(feature = "hint_prefetch", issue = "146941")] pub const fn prefetch_read(ptr: *const T, locality: Locality) { match locality { - Locality::L3 => intrinsics::prefetch_read_data::(ptr), - Locality::L2 => intrinsics::prefetch_read_data::(ptr), - Locality::L1 => intrinsics::prefetch_read_data::(ptr), + Locality::L3 => intrinsics::prefetch_read_data::(ptr), + Locality::L2 => intrinsics::prefetch_read_data::(ptr), + Locality::L1 => intrinsics::prefetch_read_data::(ptr), } } @@ -919,9 +930,9 @@ pub const fn prefetch_read_non_temporal(ptr: *const T, locality: Locality) { #[unstable(feature = "hint_prefetch", issue = "146941")] pub const fn prefetch_write(ptr: *mut T, locality: Locality) { match locality { - Locality::L3 => intrinsics::prefetch_write_data::(ptr), - Locality::L2 => intrinsics::prefetch_write_data::(ptr), - Locality::L1 => intrinsics::prefetch_write_data::(ptr), + Locality::L3 => intrinsics::prefetch_write_data::(ptr), + Locality::L2 => intrinsics::prefetch_write_data::(ptr), + Locality::L1 => intrinsics::prefetch_write_data::(ptr), } } @@ -956,8 +967,8 @@ pub const fn prefetch_write_non_temporal(ptr: *const T, locality: Locality) { #[unstable(feature = "hint_prefetch", issue = "146941")] pub const fn prefetch_read_instruction(ptr: *const T, locality: Locality) { match locality { - Locality::L3 => intrinsics::prefetch_read_instruction::(ptr), - Locality::L2 => intrinsics::prefetch_read_instruction::(ptr), - Locality::L1 => intrinsics::prefetch_read_instruction::(ptr), + Locality::L3 => intrinsics::prefetch_read_instruction::(ptr), + Locality::L2 => intrinsics::prefetch_read_instruction::(ptr), + Locality::L1 => intrinsics::prefetch_read_instruction::(ptr), } } From 0488690d3e248a72a98945fbd4ced83a5ba05d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Dec 2025 00:10:08 +0000 Subject: [PATCH 0489/3801] Use `let`...`else` instead of `match foo { ... _ => return };` and `if let ... else return` in std --- library/alloc/src/collections/linked_list.rs | 5 ++--- library/alloc/src/raw_vec/mod.rs | 4 +--- library/alloc/src/string.rs | 21 +++++++++----------- library/alloc/src/vec/splice.rs | 9 ++++----- library/core/src/num/dec2flt/mod.rs | 6 +----- library/core/src/time.rs | 7 +++---- library/std/src/sys/pal/windows/pipe.rs | 5 +---- 7 files changed, 21 insertions(+), 36 deletions(-) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 8bc0e08a4b26..e738c29c237f 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1646,9 +1646,8 @@ impl<'a, T> CursorMut<'a, T> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn splice_after(&mut self, list: LinkedList) { unsafe { - let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { - Some(parts) => parts, - _ => return, + let Some((splice_head, splice_tail, splice_len)) = list.detach_all_nodes() else { + return; }; let node_next = match self.current { None => self.list.head, diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index 236e33e2f450..15b0823df9ec 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -788,9 +788,7 @@ impl RawVecInner { elem_layout: Layout, ) -> Result<(), TryReserveError> { // SAFETY: Precondition passed to caller - let (ptr, layout) = if let Some(mem) = unsafe { self.current_memory(elem_layout) } { - mem - } else { + let Some((ptr, layout)) = (unsafe { self.current_memory(elem_layout) }) else { return Ok(()); }; diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index f5ba71c28833..64abdca32d21 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -619,16 +619,14 @@ impl String { pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> { let mut iter = v.utf8_chunks(); - let first_valid = if let Some(chunk) = iter.next() { - let valid = chunk.valid(); - if chunk.invalid().is_empty() { - debug_assert_eq!(valid.len(), v.len()); - return Cow::Borrowed(valid); - } - valid - } else { + let Some(chunk) = iter.next() else { return Cow::Borrowed(""); }; + let first_valid = chunk.valid(); + if chunk.invalid().is_empty() { + debug_assert_eq!(first_valid.len(), v.len()); + return Cow::Borrowed(first_valid); + } const REPLACEMENT: &str = "\u{FFFD}"; @@ -720,11 +718,10 @@ impl String { // FIXME: the function can be simplified again when #48994 is closed. let mut ret = String::with_capacity(v.len()); for c in char::decode_utf16(v.iter().cloned()) { - if let Ok(c) = c { - ret.push(c); - } else { + let Ok(c) = c else { return Err(FromUtf16Error(())); - } + }; + ret.push(c); } Ok(ret) } diff --git a/library/alloc/src/vec/splice.rs b/library/alloc/src/vec/splice.rs index d571e35828ae..b08bb9cb6d19 100644 --- a/library/alloc/src/vec/splice.rs +++ b/library/alloc/src/vec/splice.rs @@ -112,12 +112,11 @@ impl Drain<'_, T, A> { }; for place in range_slice { - if let Some(new_item) = replace_with.next() { - unsafe { ptr::write(place, new_item) }; - vec.len += 1; - } else { + let Some(new_item) = replace_with.next() else { return false; - } + }; + unsafe { ptr::write(place, new_item) }; + vec.len += 1; } true } diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index dd4eccd24de0..eee8adf4f755 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -255,11 +255,7 @@ fn biased_fp_to_float(x: BiasedFp) -> F { #[inline(always)] // Will be inlined into a function with `#[inline(never)]`, see above pub fn dec2flt(s: &str) -> Result { let mut s = s.as_bytes(); - let c = if let Some(&c) = s.first() { - c - } else { - return Err(pfe_empty()); - }; + let Some(&c) = s.first() else { return Err(pfe_empty()) }; let negative = c == b'-'; if c == b'-' || c == b'+' { s = &s[1..]; diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 51a01545f5cf..b85179e925d1 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -672,11 +672,10 @@ impl Duration { let mut nanos = self.nanos.as_inner() + rhs.nanos.as_inner(); if nanos >= NANOS_PER_SEC { nanos -= NANOS_PER_SEC; - if let Some(new_secs) = secs.checked_add(1) { - secs = new_secs; - } else { + let Some(new_secs) = secs.checked_add(1) else { return None; - } + }; + secs = new_secs; } debug_assert!(nanos < NANOS_PER_SEC); Some(Duration::new(secs, nanos)) diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index d8e306068d73..32cf4695d4a1 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -530,10 +530,7 @@ impl<'a> AsyncPipe<'a> { impl<'a> Drop for AsyncPipe<'a> { fn drop(&mut self) { - match self.state { - State::Reading => {} - _ => return, - } + let State::Reading = self.state else { return }; // If we have a pending read operation, then we have to make sure that // it's *done* before we actually drop this type. The kernel requires From 92f21a806d3ce3eac22d7b46903064ade92faf93 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Mon, 8 Dec 2025 05:52:18 +0900 Subject: [PATCH 0490/3801] moved tests --- .../issue-46472.rs => borrowck/return-ref-to-temporary.rs} | 0 .../return-ref-to-temporary.stderr} | 0 .../issue-19499.rs => closures/closure-upvar-trait-caching.rs} | 0 .../ui/{issues/issue-24779.rs => closures/nested-closure-call.rs} | 0 .../repeated-debug-opt-flags.rs} | 0 tests/ui/{issues/issue-23253.rs => enum/enum-variant-no-field.rs} | 0 .../issue-23253.stderr => enum/enum-variant-no-field.stderr} | 0 .../issue-50442.rs => enum/enum-with-uninhabited-variant.rs} | 0 tests/ui/{issues/issue-18110.rs => expr/return-in-block-tuple.rs} | 0 .../{issues/issue-19398.rs => extern/extern-rust-trait-method.rs} | 0 .../ui/{issues/issue-3656.rs => ffi/ffi-struct-size-alignment.rs} | 0 tests/ui/{issues/issue-11382.rs => fmt/println-float.rs} | 0 .../ui/{issues/issue-43205.rs => indexing/ref-array-indexing.rs} | 0 .../trait-method-lifetime-suggestion.rs} | 0 .../trait-method-lifetime-suggestion.stderr} | 0 ...{lint-missing-doc-crate.rs => lint-missing-doc-crate-flags.rs} | 0 ...ssing-doc-crate.stderr => lint-missing-doc-crate-flags.stderr} | 0 .../issue-10656.rs => lint/lint-missing-docs-crate-attr.rs} | 0 .../lint-missing-docs-crate-attr.stderr} | 0 .../{issues/issue-19734.rs => macros/undefined-macro-in-impl.rs} | 0 .../issue-19734.stderr => macros/undefined-macro-in-impl.stderr} | 0 .../issue-4968.rs => match/match-const-tuple-type-mismatch.rs} | 0 .../match-const-tuple-type-mismatch.stderr} | 0 .../ui/{issues/issue-18464.rs => match/match-range-char-const.rs} | 0 tests/ui/{issues/issue-17933.rs => match/match-static-pattern.rs} | 0 .../issue-17933.stderr => match/match-static-pattern.stderr} | 0 tests/ui/{issues/issue-16783.rs => moves/array-copy-move.rs} | 0 tests/ui/{issues/issue-17373.rs => never_type/never-deref.rs} | 0 .../{issues/issue-17373.stderr => never_type/never-deref.stderr} | 0 .../issue-22644.rs => parser/cast-angle-bracket-precedence.rs} | 0 .../cast-angle-bracket-precedence.stderr} | 0 .../issue-27033.rs => pattern/match-at-pattern-shadows-name.rs} | 0 .../match-at-pattern-shadows-name.stderr} | 0 .../module-used-as-struct-constructor.rs} | 0 .../module-used-as-struct-constructor.stderr} | 0 .../issue-34047.rs => shadowed/match-binding-shadows-const.rs} | 0 .../match-binding-shadows-const.stderr} | 0 .../{issues/issue-17450.rs => statics/static-mut-unsafe-init.rs} | 0 .../issue-21291.rs => threads-sendsync/thread-join-unwrap.rs} | 0 .../issue-20162.rs => trait-bounds/sort-missing-ord-bound.rs} | 0 .../sort-missing-ord-bound.stderr} | 0 .../solver-cycles/assoc-equality-cycle.rs} | 0 .../solver-cycles/assoc-equality-cycle.stderr} | 0 .../issue-20772.rs => traits/solver-cycles/self-item-cycle.rs} | 0 .../solver-cycles/self-item-cycle.stderr} | 0 .../{issues/issue-18159.rs => typeck/missing-type-annotation.rs} | 0 .../issue-18159.stderr => typeck/missing-type-annotation.stderr} | 0 .../ui/{issues/issue-49854.rs => typeck/osstring-str-equality.rs} | 0 .../issue-18532.rs => typeck/return-expression-invalid-callee.rs} | 0 .../return-expression-invalid-callee.stderr} | 0 50 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-46472.rs => borrowck/return-ref-to-temporary.rs} (100%) rename tests/ui/{issues/issue-46472.stderr => borrowck/return-ref-to-temporary.stderr} (100%) rename tests/ui/{issues/issue-19499.rs => closures/closure-upvar-trait-caching.rs} (100%) rename tests/ui/{issues/issue-24779.rs => closures/nested-closure-call.rs} (100%) rename tests/ui/{issues/issue-24945-repeat-dash-opts.rs => codegen/repeated-debug-opt-flags.rs} (100%) rename tests/ui/{issues/issue-23253.rs => enum/enum-variant-no-field.rs} (100%) rename tests/ui/{issues/issue-23253.stderr => enum/enum-variant-no-field.stderr} (100%) rename tests/ui/{issues/issue-50442.rs => enum/enum-with-uninhabited-variant.rs} (100%) rename tests/ui/{issues/issue-18110.rs => expr/return-in-block-tuple.rs} (100%) rename tests/ui/{issues/issue-19398.rs => extern/extern-rust-trait-method.rs} (100%) rename tests/ui/{issues/issue-3656.rs => ffi/ffi-struct-size-alignment.rs} (100%) rename tests/ui/{issues/issue-11382.rs => fmt/println-float.rs} (100%) rename tests/ui/{issues/issue-43205.rs => indexing/ref-array-indexing.rs} (100%) rename tests/ui/{issues/issue-17758.rs => lifetimes/trait-method-lifetime-suggestion.rs} (100%) rename tests/ui/{issues/issue-17758.stderr => lifetimes/trait-method-lifetime-suggestion.stderr} (100%) rename tests/ui/lint/{lint-missing-doc-crate.rs => lint-missing-doc-crate-flags.rs} (100%) rename tests/ui/lint/{lint-missing-doc-crate.stderr => lint-missing-doc-crate-flags.stderr} (100%) rename tests/ui/{issues/issue-10656.rs => lint/lint-missing-docs-crate-attr.rs} (100%) rename tests/ui/{issues/issue-10656.stderr => lint/lint-missing-docs-crate-attr.stderr} (100%) rename tests/ui/{issues/issue-19734.rs => macros/undefined-macro-in-impl.rs} (100%) rename tests/ui/{issues/issue-19734.stderr => macros/undefined-macro-in-impl.stderr} (100%) rename tests/ui/{issues/issue-4968.rs => match/match-const-tuple-type-mismatch.rs} (100%) rename tests/ui/{issues/issue-4968.stderr => match/match-const-tuple-type-mismatch.stderr} (100%) rename tests/ui/{issues/issue-18464.rs => match/match-range-char-const.rs} (100%) rename tests/ui/{issues/issue-17933.rs => match/match-static-pattern.rs} (100%) rename tests/ui/{issues/issue-17933.stderr => match/match-static-pattern.stderr} (100%) rename tests/ui/{issues/issue-16783.rs => moves/array-copy-move.rs} (100%) rename tests/ui/{issues/issue-17373.rs => never_type/never-deref.rs} (100%) rename tests/ui/{issues/issue-17373.stderr => never_type/never-deref.stderr} (100%) rename tests/ui/{issues/issue-22644.rs => parser/cast-angle-bracket-precedence.rs} (100%) rename tests/ui/{issues/issue-22644.stderr => parser/cast-angle-bracket-precedence.stderr} (100%) rename tests/ui/{issues/issue-27033.rs => pattern/match-at-pattern-shadows-name.rs} (100%) rename tests/ui/{issues/issue-27033.stderr => pattern/match-at-pattern-shadows-name.stderr} (100%) rename tests/ui/{issues/issue-17001.rs => resolve/module-used-as-struct-constructor.rs} (100%) rename tests/ui/{issues/issue-17001.stderr => resolve/module-used-as-struct-constructor.stderr} (100%) rename tests/ui/{issues/issue-34047.rs => shadowed/match-binding-shadows-const.rs} (100%) rename tests/ui/{issues/issue-34047.stderr => shadowed/match-binding-shadows-const.stderr} (100%) rename tests/ui/{issues/issue-17450.rs => statics/static-mut-unsafe-init.rs} (100%) rename tests/ui/{issues/issue-21291.rs => threads-sendsync/thread-join-unwrap.rs} (100%) rename tests/ui/{issues/issue-20162.rs => trait-bounds/sort-missing-ord-bound.rs} (100%) rename tests/ui/{issues/issue-20162.stderr => trait-bounds/sort-missing-ord-bound.stderr} (100%) rename tests/ui/{issues/issue-21177.rs => traits/solver-cycles/assoc-equality-cycle.rs} (100%) rename tests/ui/{issues/issue-21177.stderr => traits/solver-cycles/assoc-equality-cycle.stderr} (100%) rename tests/ui/{issues/issue-20772.rs => traits/solver-cycles/self-item-cycle.rs} (100%) rename tests/ui/{issues/issue-20772.stderr => traits/solver-cycles/self-item-cycle.stderr} (100%) rename tests/ui/{issues/issue-18159.rs => typeck/missing-type-annotation.rs} (100%) rename tests/ui/{issues/issue-18159.stderr => typeck/missing-type-annotation.stderr} (100%) rename tests/ui/{issues/issue-49854.rs => typeck/osstring-str-equality.rs} (100%) rename tests/ui/{issues/issue-18532.rs => typeck/return-expression-invalid-callee.rs} (100%) rename tests/ui/{issues/issue-18532.stderr => typeck/return-expression-invalid-callee.stderr} (100%) diff --git a/tests/ui/issues/issue-46472.rs b/tests/ui/borrowck/return-ref-to-temporary.rs similarity index 100% rename from tests/ui/issues/issue-46472.rs rename to tests/ui/borrowck/return-ref-to-temporary.rs diff --git a/tests/ui/issues/issue-46472.stderr b/tests/ui/borrowck/return-ref-to-temporary.stderr similarity index 100% rename from tests/ui/issues/issue-46472.stderr rename to tests/ui/borrowck/return-ref-to-temporary.stderr diff --git a/tests/ui/issues/issue-19499.rs b/tests/ui/closures/closure-upvar-trait-caching.rs similarity index 100% rename from tests/ui/issues/issue-19499.rs rename to tests/ui/closures/closure-upvar-trait-caching.rs diff --git a/tests/ui/issues/issue-24779.rs b/tests/ui/closures/nested-closure-call.rs similarity index 100% rename from tests/ui/issues/issue-24779.rs rename to tests/ui/closures/nested-closure-call.rs diff --git a/tests/ui/issues/issue-24945-repeat-dash-opts.rs b/tests/ui/codegen/repeated-debug-opt-flags.rs similarity index 100% rename from tests/ui/issues/issue-24945-repeat-dash-opts.rs rename to tests/ui/codegen/repeated-debug-opt-flags.rs diff --git a/tests/ui/issues/issue-23253.rs b/tests/ui/enum/enum-variant-no-field.rs similarity index 100% rename from tests/ui/issues/issue-23253.rs rename to tests/ui/enum/enum-variant-no-field.rs diff --git a/tests/ui/issues/issue-23253.stderr b/tests/ui/enum/enum-variant-no-field.stderr similarity index 100% rename from tests/ui/issues/issue-23253.stderr rename to tests/ui/enum/enum-variant-no-field.stderr diff --git a/tests/ui/issues/issue-50442.rs b/tests/ui/enum/enum-with-uninhabited-variant.rs similarity index 100% rename from tests/ui/issues/issue-50442.rs rename to tests/ui/enum/enum-with-uninhabited-variant.rs diff --git a/tests/ui/issues/issue-18110.rs b/tests/ui/expr/return-in-block-tuple.rs similarity index 100% rename from tests/ui/issues/issue-18110.rs rename to tests/ui/expr/return-in-block-tuple.rs diff --git a/tests/ui/issues/issue-19398.rs b/tests/ui/extern/extern-rust-trait-method.rs similarity index 100% rename from tests/ui/issues/issue-19398.rs rename to tests/ui/extern/extern-rust-trait-method.rs diff --git a/tests/ui/issues/issue-3656.rs b/tests/ui/ffi/ffi-struct-size-alignment.rs similarity index 100% rename from tests/ui/issues/issue-3656.rs rename to tests/ui/ffi/ffi-struct-size-alignment.rs diff --git a/tests/ui/issues/issue-11382.rs b/tests/ui/fmt/println-float.rs similarity index 100% rename from tests/ui/issues/issue-11382.rs rename to tests/ui/fmt/println-float.rs diff --git a/tests/ui/issues/issue-43205.rs b/tests/ui/indexing/ref-array-indexing.rs similarity index 100% rename from tests/ui/issues/issue-43205.rs rename to tests/ui/indexing/ref-array-indexing.rs diff --git a/tests/ui/issues/issue-17758.rs b/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs similarity index 100% rename from tests/ui/issues/issue-17758.rs rename to tests/ui/lifetimes/trait-method-lifetime-suggestion.rs diff --git a/tests/ui/issues/issue-17758.stderr b/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr similarity index 100% rename from tests/ui/issues/issue-17758.stderr rename to tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr diff --git a/tests/ui/lint/lint-missing-doc-crate.rs b/tests/ui/lint/lint-missing-doc-crate-flags.rs similarity index 100% rename from tests/ui/lint/lint-missing-doc-crate.rs rename to tests/ui/lint/lint-missing-doc-crate-flags.rs diff --git a/tests/ui/lint/lint-missing-doc-crate.stderr b/tests/ui/lint/lint-missing-doc-crate-flags.stderr similarity index 100% rename from tests/ui/lint/lint-missing-doc-crate.stderr rename to tests/ui/lint/lint-missing-doc-crate-flags.stderr diff --git a/tests/ui/issues/issue-10656.rs b/tests/ui/lint/lint-missing-docs-crate-attr.rs similarity index 100% rename from tests/ui/issues/issue-10656.rs rename to tests/ui/lint/lint-missing-docs-crate-attr.rs diff --git a/tests/ui/issues/issue-10656.stderr b/tests/ui/lint/lint-missing-docs-crate-attr.stderr similarity index 100% rename from tests/ui/issues/issue-10656.stderr rename to tests/ui/lint/lint-missing-docs-crate-attr.stderr diff --git a/tests/ui/issues/issue-19734.rs b/tests/ui/macros/undefined-macro-in-impl.rs similarity index 100% rename from tests/ui/issues/issue-19734.rs rename to tests/ui/macros/undefined-macro-in-impl.rs diff --git a/tests/ui/issues/issue-19734.stderr b/tests/ui/macros/undefined-macro-in-impl.stderr similarity index 100% rename from tests/ui/issues/issue-19734.stderr rename to tests/ui/macros/undefined-macro-in-impl.stderr diff --git a/tests/ui/issues/issue-4968.rs b/tests/ui/match/match-const-tuple-type-mismatch.rs similarity index 100% rename from tests/ui/issues/issue-4968.rs rename to tests/ui/match/match-const-tuple-type-mismatch.rs diff --git a/tests/ui/issues/issue-4968.stderr b/tests/ui/match/match-const-tuple-type-mismatch.stderr similarity index 100% rename from tests/ui/issues/issue-4968.stderr rename to tests/ui/match/match-const-tuple-type-mismatch.stderr diff --git a/tests/ui/issues/issue-18464.rs b/tests/ui/match/match-range-char-const.rs similarity index 100% rename from tests/ui/issues/issue-18464.rs rename to tests/ui/match/match-range-char-const.rs diff --git a/tests/ui/issues/issue-17933.rs b/tests/ui/match/match-static-pattern.rs similarity index 100% rename from tests/ui/issues/issue-17933.rs rename to tests/ui/match/match-static-pattern.rs diff --git a/tests/ui/issues/issue-17933.stderr b/tests/ui/match/match-static-pattern.stderr similarity index 100% rename from tests/ui/issues/issue-17933.stderr rename to tests/ui/match/match-static-pattern.stderr diff --git a/tests/ui/issues/issue-16783.rs b/tests/ui/moves/array-copy-move.rs similarity index 100% rename from tests/ui/issues/issue-16783.rs rename to tests/ui/moves/array-copy-move.rs diff --git a/tests/ui/issues/issue-17373.rs b/tests/ui/never_type/never-deref.rs similarity index 100% rename from tests/ui/issues/issue-17373.rs rename to tests/ui/never_type/never-deref.rs diff --git a/tests/ui/issues/issue-17373.stderr b/tests/ui/never_type/never-deref.stderr similarity index 100% rename from tests/ui/issues/issue-17373.stderr rename to tests/ui/never_type/never-deref.stderr diff --git a/tests/ui/issues/issue-22644.rs b/tests/ui/parser/cast-angle-bracket-precedence.rs similarity index 100% rename from tests/ui/issues/issue-22644.rs rename to tests/ui/parser/cast-angle-bracket-precedence.rs diff --git a/tests/ui/issues/issue-22644.stderr b/tests/ui/parser/cast-angle-bracket-precedence.stderr similarity index 100% rename from tests/ui/issues/issue-22644.stderr rename to tests/ui/parser/cast-angle-bracket-precedence.stderr diff --git a/tests/ui/issues/issue-27033.rs b/tests/ui/pattern/match-at-pattern-shadows-name.rs similarity index 100% rename from tests/ui/issues/issue-27033.rs rename to tests/ui/pattern/match-at-pattern-shadows-name.rs diff --git a/tests/ui/issues/issue-27033.stderr b/tests/ui/pattern/match-at-pattern-shadows-name.stderr similarity index 100% rename from tests/ui/issues/issue-27033.stderr rename to tests/ui/pattern/match-at-pattern-shadows-name.stderr diff --git a/tests/ui/issues/issue-17001.rs b/tests/ui/resolve/module-used-as-struct-constructor.rs similarity index 100% rename from tests/ui/issues/issue-17001.rs rename to tests/ui/resolve/module-used-as-struct-constructor.rs diff --git a/tests/ui/issues/issue-17001.stderr b/tests/ui/resolve/module-used-as-struct-constructor.stderr similarity index 100% rename from tests/ui/issues/issue-17001.stderr rename to tests/ui/resolve/module-used-as-struct-constructor.stderr diff --git a/tests/ui/issues/issue-34047.rs b/tests/ui/shadowed/match-binding-shadows-const.rs similarity index 100% rename from tests/ui/issues/issue-34047.rs rename to tests/ui/shadowed/match-binding-shadows-const.rs diff --git a/tests/ui/issues/issue-34047.stderr b/tests/ui/shadowed/match-binding-shadows-const.stderr similarity index 100% rename from tests/ui/issues/issue-34047.stderr rename to tests/ui/shadowed/match-binding-shadows-const.stderr diff --git a/tests/ui/issues/issue-17450.rs b/tests/ui/statics/static-mut-unsafe-init.rs similarity index 100% rename from tests/ui/issues/issue-17450.rs rename to tests/ui/statics/static-mut-unsafe-init.rs diff --git a/tests/ui/issues/issue-21291.rs b/tests/ui/threads-sendsync/thread-join-unwrap.rs similarity index 100% rename from tests/ui/issues/issue-21291.rs rename to tests/ui/threads-sendsync/thread-join-unwrap.rs diff --git a/tests/ui/issues/issue-20162.rs b/tests/ui/trait-bounds/sort-missing-ord-bound.rs similarity index 100% rename from tests/ui/issues/issue-20162.rs rename to tests/ui/trait-bounds/sort-missing-ord-bound.rs diff --git a/tests/ui/issues/issue-20162.stderr b/tests/ui/trait-bounds/sort-missing-ord-bound.stderr similarity index 100% rename from tests/ui/issues/issue-20162.stderr rename to tests/ui/trait-bounds/sort-missing-ord-bound.stderr diff --git a/tests/ui/issues/issue-21177.rs b/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs similarity index 100% rename from tests/ui/issues/issue-21177.rs rename to tests/ui/traits/solver-cycles/assoc-equality-cycle.rs diff --git a/tests/ui/issues/issue-21177.stderr b/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr similarity index 100% rename from tests/ui/issues/issue-21177.stderr rename to tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr diff --git a/tests/ui/issues/issue-20772.rs b/tests/ui/traits/solver-cycles/self-item-cycle.rs similarity index 100% rename from tests/ui/issues/issue-20772.rs rename to tests/ui/traits/solver-cycles/self-item-cycle.rs diff --git a/tests/ui/issues/issue-20772.stderr b/tests/ui/traits/solver-cycles/self-item-cycle.stderr similarity index 100% rename from tests/ui/issues/issue-20772.stderr rename to tests/ui/traits/solver-cycles/self-item-cycle.stderr diff --git a/tests/ui/issues/issue-18159.rs b/tests/ui/typeck/missing-type-annotation.rs similarity index 100% rename from tests/ui/issues/issue-18159.rs rename to tests/ui/typeck/missing-type-annotation.rs diff --git a/tests/ui/issues/issue-18159.stderr b/tests/ui/typeck/missing-type-annotation.stderr similarity index 100% rename from tests/ui/issues/issue-18159.stderr rename to tests/ui/typeck/missing-type-annotation.stderr diff --git a/tests/ui/issues/issue-49854.rs b/tests/ui/typeck/osstring-str-equality.rs similarity index 100% rename from tests/ui/issues/issue-49854.rs rename to tests/ui/typeck/osstring-str-equality.rs diff --git a/tests/ui/issues/issue-18532.rs b/tests/ui/typeck/return-expression-invalid-callee.rs similarity index 100% rename from tests/ui/issues/issue-18532.rs rename to tests/ui/typeck/return-expression-invalid-callee.rs diff --git a/tests/ui/issues/issue-18532.stderr b/tests/ui/typeck/return-expression-invalid-callee.stderr similarity index 100% rename from tests/ui/issues/issue-18532.stderr rename to tests/ui/typeck/return-expression-invalid-callee.stderr From d440210f9a47572842ae6781303336ad4fe0f268 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Wed, 10 Dec 2025 08:58:34 +0900 Subject: [PATCH 0491/3801] Add a regression test for issue 145748 --- .../normalize/normalize-const-in-async-body.rs | 2 ++ .../non-defining-use-borrowck-issue-145748.rs | 14 ++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/ui/traits/next-solver/opaques/non-defining-use-borrowck-issue-145748.rs diff --git a/tests/ui/traits/next-solver/normalize/normalize-const-in-async-body.rs b/tests/ui/traits/next-solver/normalize/normalize-const-in-async-body.rs index 2b9454db3fac..4da078dbb4f4 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-const-in-async-body.rs +++ b/tests/ui/traits/next-solver/normalize/normalize-const-in-async-body.rs @@ -2,6 +2,8 @@ //@ check-pass //@ edition:2021 +// Regression test for https://github.com/rust-lang/rust/issues/129865. + pub async fn cleanse_old_array_async(_: &[u8; BUCKET_LEN]) {} pub const BUCKET_LEN: usize = 0; diff --git a/tests/ui/traits/next-solver/opaques/non-defining-use-borrowck-issue-145748.rs b/tests/ui/traits/next-solver/opaques/non-defining-use-borrowck-issue-145748.rs new file mode 100644 index 000000000000..ae70ffdfdaee --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/non-defining-use-borrowck-issue-145748.rs @@ -0,0 +1,14 @@ +//@ ignore-compare-mode-next-solver +//@ compile-flags: -Znext-solver +//@ check-pass + +// Make sure that we support non-defining uses in borrowck. +// Regression test for https://github.com/rust-lang/rust/issues/145748. + +pub fn f(_: &()) -> impl Fn() + '_ { + || { + let _ = f(&()); + } +} + +fn main() {} From fc3d61ee7c221f38eec38166f9a9f5f0e0bd3a7e Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Wed, 10 Dec 2025 09:35:24 +0800 Subject: [PATCH 0492/3801] compiletest: tidy up `adb_path`/`adb_test_dir` handling Be more faithful that they aren't always available. --- src/tools/compiletest/src/common.rs | 4 ++-- src/tools/compiletest/src/lib.rs | 8 +++----- src/tools/compiletest/src/runtest/debuginfo.rs | 12 ++++++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 02b93593cbbd..34153d93d463 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -575,7 +575,7 @@ pub struct Config { /// /// FIXME: take a look at this; this is piggy-backing off of gdb code paths but only for /// `arm-linux-androideabi` target. - pub adb_path: Utf8PathBuf, + pub adb_path: Option, /// Extra parameter to run test suite on `arm-linux-androideabi`. /// @@ -584,7 +584,7 @@ pub struct Config { /// /// FIXME: take a look at this; this is piggy-backing off of gdb code paths but only for /// `arm-linux-androideabi` target. - pub adb_test_dir: Utf8PathBuf, + pub adb_test_dir: Option, /// Status whether android device available or not. When unavailable, this will cause tests to /// panic when the test binary is attempted to be run. diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index ff4cd81d33ff..324ce2eaabee 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -260,11 +260,9 @@ fn parse_config(args: Vec) -> Config { let android_cross_path = matches.opt_str("android-cross-path").map(Utf8PathBuf::from); - // FIXME: `adb_path` should be an `Option`... - let adb_path = matches.opt_str("adb-path").map(Utf8PathBuf::from).unwrap_or_default(); - // FIXME: `adb_test_dir` should be an `Option`... - let adb_test_dir = matches.opt_str("adb-test-dir").map(Utf8PathBuf::from).unwrap_or_default(); - let adb_device_status = target.contains("android") && !adb_test_dir.as_str().is_empty(); + let adb_path = matches.opt_str("adb-path").map(Utf8PathBuf::from); + let adb_test_dir = matches.opt_str("adb-test-dir").map(Utf8PathBuf::from); + let adb_device_status = target.contains("android") && adb_test_dir.is_some(); // FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config! let cdb = debuggers::discover_cdb(matches.opt_str("cdb"), &target); diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index ac935910205b..83b61b9be57d 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -150,12 +150,16 @@ impl TestCx<'_> { debug!("script_str = {}", script_str); self.dump_output_file(&script_str, "debugger.script"); - let adb_path = &self.config.adb_path; + // Note: when `--android-cross-path` is specified, we expect both `adb_path` and + // `adb_test_dir` to be available. + let adb_path = self.config.adb_path.as_ref().expect("`adb_path` must be specified"); + let adb_test_dir = + self.config.adb_test_dir.as_ref().expect("`adb_test_dir` must be specified"); Command::new(adb_path) .arg("push") .arg(&exe_file) - .arg(&self.config.adb_test_dir) + .arg(adb_test_dir) .status() .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}")); @@ -167,9 +171,9 @@ impl TestCx<'_> { let adb_arg = format!( "export LD_LIBRARY_PATH={}; \ gdbserver{} :5039 {}/{}", - self.config.adb_test_dir.clone(), + adb_test_dir, if self.config.target.contains("aarch64") { "64" } else { "" }, - self.config.adb_test_dir.clone(), + adb_test_dir, exe_file.file_name().unwrap() ); From 4033d19b79244b347a87f3c58d0ad01962935360 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 30 Nov 2025 14:46:36 -0800 Subject: [PATCH 0493/3801] Experimentally add *heterogeneous* `try` blocks 148725 moved the default to being homogeneous; this adds heterogeneous ones back under an obvious-bikeshed syntax so people can experiment with that as well. Essentially resolves 149025 by letting them move to this syntax instead. --- compiler/rustc_ast/src/ast.rs | 10 ++- compiler/rustc_ast/src/visit.rs | 4 +- compiler/rustc_ast_lowering/src/expr.rs | 74 +++++++++++++------ compiler/rustc_ast_lowering/src/lib.rs | 21 +++++- compiler/rustc_ast_passes/src/feature_gate.rs | 10 ++- .../rustc_ast_pretty/src/pprust/state/expr.rs | 7 +- .../src/assert/context.rs | 2 +- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_parse/src/parser/expr.rs | 19 +++-- compiler/rustc_parse/src/parser/token_type.rs | 2 + compiler/rustc_span/src/symbol.rs | 2 + tests/pretty/try-blocks.rs | 6 ++ .../feature-gate-try_blocks_heterogeneous.rs | 9 +++ ...ature-gate-try_blocks_heterogeneous.stderr | 17 +++++ .../try-block-bad-type-heterogeneous.rs | 21 ++++++ .../try-block-bad-type-heterogeneous.stderr | 46 ++++++++++++ tests/ui/try-block/try-block-heterogeneous.rs | 19 +++++ tests/ui/unpretty/exhaustive.expanded.stdout | 8 +- tests/ui/unpretty/exhaustive.hir.stderr | 40 +++++----- tests/ui/unpretty/exhaustive.hir.stdout | 15 +++- tests/ui/unpretty/exhaustive.rs | 3 + 21 files changed, 278 insertions(+), 59 deletions(-) create mode 100644 tests/pretty/try-blocks.rs create mode 100644 tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs create mode 100644 tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr create mode 100644 tests/ui/try-block/try-block-bad-type-heterogeneous.rs create mode 100644 tests/ui/try-block/try-block-bad-type-heterogeneous.stderr create mode 100644 tests/ui/try-block/try-block-heterogeneous.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index db7cace49ae8..09dd5c389632 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1806,8 +1806,14 @@ pub enum ExprKind { /// A use expression (`x.use`). Span is of use keyword. Use(Box, Span), - /// A try block (`try { ... }`). - TryBlock(Box), + /// A try block (`try { ... }`), if the type is `None`, or + /// A try block (`try bikeshed Ty { ... }`) if the type is `Some`. + /// + /// Note that `try bikeshed` is a *deliberately ridiculous* placeholder + /// syntax to avoid deciding what keyword or symbol should go there. + /// It's that way for experimentation only; an RFC to decide the final + /// semantics and syntax would be needed to put it on stabilization-track. + TryBlock(Box, Option>), /// An assignment (`a = foo()`). /// The `Span` argument is the span of the `=` token. diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index dde773fd147d..7a0424d39575 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1048,8 +1048,8 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, kind), ExprKind::Try(subexpression) => visit_visitable!($($mut)? vis, subexpression), - ExprKind::TryBlock(body) => - visit_visitable!($($mut)? vis, body), + ExprKind::TryBlock(body, optional_type) => + visit_visitable!($($mut)? vis, body, optional_type), ExprKind::Lit(token) => visit_visitable!($($mut)? vis, token), ExprKind::IncludedBytes(bytes) => diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 524f8b054cb4..7230e1c42474 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,3 +1,4 @@ +use std::mem; use std::ops::ControlFlow; use std::sync::Arc; @@ -27,7 +28,9 @@ use super::{ GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt, }; use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure}; -use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, fluent_generated}; +use crate::{ + AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope, fluent_generated, +}; struct WillCreateDefIdsVisitor {} @@ -199,7 +202,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }) } - ExprKind::TryBlock(body) => self.lower_expr_try_block(body), + ExprKind::TryBlock(body, opt_ty) => { + self.lower_expr_try_block(body, opt_ty.as_deref()) + } ExprKind::Match(expr, arms, kind) => hir::ExprKind::Match( self.lower_expr(expr), self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))), @@ -562,9 +567,14 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Desugar `try { ; }` into `{ ; ::std::ops::Try::from_output() }`, /// `try { ; }` into `{ ; ::std::ops::Try::from_output(()) }` /// and save the block id to use it as a break target for desugaring of the `?` operator. - fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> { + fn lower_expr_try_block(&mut self, body: &Block, opt_ty: Option<&Ty>) -> hir::ExprKind<'hir> { let body_hir_id = self.lower_node_id(body.id); - self.with_catch_scope(body_hir_id, |this| { + let new_scope = if opt_ty.is_some() { + TryBlockScope::Heterogeneous(body_hir_id) + } else { + TryBlockScope::Homogeneous(body_hir_id) + }; + let whole_block = self.with_try_block_scope(new_scope, |this| { let mut block = this.lower_block_noalloc(body_hir_id, body, true); // Final expression of the block (if present) or `()` with span at the end of block @@ -598,8 +608,16 @@ impl<'hir> LoweringContext<'_, 'hir> { ok_wrapped_span, )); - hir::ExprKind::Block(this.arena.alloc(block), None) - }) + this.arena.alloc(block) + }); + + if let Some(ty) = opt_ty { + let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path)); + let block_expr = self.arena.alloc(self.expr_block(whole_block)); + hir::ExprKind::Type(block_expr, ty) + } else { + hir::ExprKind::Block(whole_block, None) + } } fn wrap_in_try_constructor( @@ -1617,10 +1635,14 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn with_catch_scope(&mut self, catch_id: hir::HirId, f: impl FnOnce(&mut Self) -> T) -> T { - let old_scope = self.catch_scope.replace(catch_id); + fn with_try_block_scope( + &mut self, + scope: TryBlockScope, + f: impl FnOnce(&mut Self) -> T, + ) -> T { + let old_scope = mem::replace(&mut self.try_block_scope, scope); let result = f(self); - self.catch_scope = old_scope; + self.try_block_scope = old_scope; result } @@ -1978,18 +2000,25 @@ impl<'hir> LoweringContext<'_, 'hir> { let residual_ident = Ident::with_dummy_span(sym::residual); let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident); let residual_expr = self.expr_ident_mut(try_span, residual_ident, residual_local_nid); + + let (constructor_item, target_id) = match self.try_block_scope { + TryBlockScope::Function => { + (hir::LangItem::TryTraitFromResidual, Err(hir::LoopIdError::OutsideLoopScope)) + } + TryBlockScope::Homogeneous(block_id) => { + (hir::LangItem::ResidualIntoTryType, Ok(block_id)) + } + TryBlockScope::Heterogeneous(block_id) => { + (hir::LangItem::TryTraitFromResidual, Ok(block_id)) + } + }; let from_residual_expr = self.wrap_in_try_constructor( - if self.catch_scope.is_some() { - hir::LangItem::ResidualIntoTryType - } else { - hir::LangItem::TryTraitFromResidual - }, + constructor_item, try_span, self.arena.alloc(residual_expr), unstable_span, ); - let ret_expr = if let Some(catch_id) = self.catch_scope { - let target_id = Ok(catch_id); + let ret_expr = if target_id.is_ok() { self.arena.alloc(self.expr( try_span, hir::ExprKind::Break( @@ -2044,11 +2073,14 @@ impl<'hir> LoweringContext<'_, 'hir> { yeeted_span, ); - if let Some(catch_id) = self.catch_scope { - let target_id = Ok(catch_id); - hir::ExprKind::Break(hir::Destination { label: None, target_id }, Some(from_yeet_expr)) - } else { - self.checked_return(Some(from_yeet_expr)) + match self.try_block_scope { + TryBlockScope::Homogeneous(block_id) | TryBlockScope::Heterogeneous(block_id) => { + hir::ExprKind::Break( + hir::Destination { label: None, target_id: Ok(block_id) }, + Some(from_yeet_expr), + ) + } + TryBlockScope::Function => self.checked_return(Some(from_yeet_expr)), } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ab5caff86204..7cd7f787c4ad 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -35,6 +35,7 @@ #![feature(if_let_guard)] // tidy-alphabetical-end +use std::mem; use std::sync::Arc; use rustc_ast::node_id::NodeMap; @@ -117,7 +118,7 @@ struct LoweringContext<'a, 'hir> { /// outside of an `async fn`. current_item: Option, - catch_scope: Option, + try_block_scope: TryBlockScope, loop_scope: Option, is_in_loop_condition: bool, is_in_dyn_type: bool, @@ -173,7 +174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { trait_map: Default::default(), // Lowering state. - catch_scope: None, + try_block_scope: TryBlockScope::Function, loop_scope: None, is_in_loop_condition: false, is_in_dyn_type: false, @@ -423,6 +424,18 @@ enum AstOwner<'a> { ForeignItem(&'a ast::ForeignItem), } +#[derive(Copy, Clone, Debug)] +enum TryBlockScope { + /// There isn't a `try` block, so a `?` will use `return`. + Function, + /// We're inside a `try { … }` block, so a `?` will block-break + /// from that block using a type depending only on the argument. + Homogeneous(HirId), + /// We're inside a `try as _ { … }` block, so a `?` will block-break + /// from that block using the type specified. + Heterogeneous(HirId), +} + fn index_crate<'a>( node_id_to_def_id: &NodeMap, krate: &'a Crate, @@ -943,10 +956,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let old_contract = self.contract_ensures.take(); - let catch_scope = self.catch_scope.take(); + let try_block_scope = mem::replace(&mut self.try_block_scope, TryBlockScope::Function); let loop_scope = self.loop_scope.take(); let ret = f(self); - self.catch_scope = catch_scope; + self.try_block_scope = try_block_scope; self.loop_scope = loop_scope; self.contract_ensures = old_contract; diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 2d87d8c84d7c..9b746508b33e 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -339,9 +339,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_expr(&mut self, e: &'a ast::Expr) { match e.kind { - ast::ExprKind::TryBlock(_) => { + ast::ExprKind::TryBlock(_, None) => { gate!(&self, try_blocks, e.span, "`try` expression is experimental"); } + ast::ExprKind::TryBlock(_, Some(_)) => { + gate!( + &self, + try_blocks_heterogeneous, + e.span, + "`try bikeshed` expression is experimental" + ); + } ast::ExprKind::Lit(token::Lit { kind: token::LitKind::Float | token::LitKind::Integer, suffix, diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index bdf73ac32f0d..7dce7f6d4195 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -818,10 +818,15 @@ impl<'a> State<'a> { ); self.word("?") } - ast::ExprKind::TryBlock(blk) => { + ast::ExprKind::TryBlock(blk, opt_ty) => { let cb = self.cbox(0); let ib = self.ibox(0); self.word_nbsp("try"); + if let Some(ty) = opt_ty { + self.word_nbsp("bikeshed"); + self.print_type(ty); + self.space(); + } self.print_block_with_attrs(blk, attrs, cb, ib) } ast::ExprKind::UnsafeBinderCast(kind, expr, ty) => { diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 31855cbd4e6c..21b20e2bb974 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -315,7 +315,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::Path(_, _) | ExprKind::Ret(_) | ExprKind::Try(_) - | ExprKind::TryBlock(_) + | ExprKind::TryBlock(_, _) | ExprKind::Type(_, _) | ExprKind::Underscore | ExprKind::While(_, _, _) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 3ef4eb00c354..ac01d98b4d1a 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -663,6 +663,8 @@ declare_features! ( (unstable, trivial_bounds, "1.28.0", Some(48214)), /// Allows using `try {...}` expressions. (unstable, try_blocks, "1.29.0", Some(31436)), + /// Allows using `try bikeshed TargetType {...}` expressions. + (unstable, try_blocks_heterogeneous, "CURRENT_RUSTC_VERSION", Some(149488)), /// Allows `impl Trait` to be used inside type aliases (RFC 2515). (unstable, type_alias_impl_trait, "1.38.0", Some(63063)), /// Allows creation of instances of a struct by moving fields that have diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 9e7d4bca37d0..fa5e61d24d91 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3544,15 +3544,20 @@ impl<'a> Parser<'a> { self.token.is_keyword(kw::Builtin) && self.look_ahead(1, |t| *t == token::Pound) } - /// Parses a `try {...}` expression (`try` token already eaten). + /// Parses a `try {...}` or `try bikeshed Ty {...}` expression (`try` token already eaten). fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, Box> { + let annotation = + if self.eat_keyword(exp!(Bikeshed)) { Some(self.parse_ty()?) } else { None }; + let (attrs, body) = self.parse_inner_attrs_and_block(None)?; if self.eat_keyword(exp!(Catch)) { Err(self.dcx().create_err(errors::CatchAfterTry { span: self.prev_token.span })) } else { let span = span_lo.to(body.span); - self.psess.gated_spans.gate(sym::try_blocks, span); - Ok(self.mk_expr_with_attrs(span, ExprKind::TryBlock(body), attrs)) + let gate_sym = + if annotation.is_none() { sym::try_blocks } else { sym::try_blocks_heterogeneous }; + self.psess.gated_spans.gate(gate_sym, span); + Ok(self.mk_expr_with_attrs(span, ExprKind::TryBlock(body, annotation), attrs)) } } @@ -3569,7 +3574,11 @@ impl<'a> Parser<'a> { fn is_try_block(&self) -> bool { self.token.is_keyword(kw::Try) - && self.look_ahead(1, |t| *t == token::OpenBrace || t.is_metavar_block()) + && self.look_ahead(1, |t| { + *t == token::OpenBrace + || t.is_metavar_block() + || t.kind == TokenKind::Ident(sym::bikeshed, IdentIsRaw::No) + }) && self.token_uninterpolated_span().at_least_rust_2018() } @@ -4264,7 +4273,7 @@ impl MutVisitor for CondChecker<'_> { | ExprKind::Closure(_) | ExprKind::Block(_, _) | ExprKind::Gen(_, _, _, _) - | ExprKind::TryBlock(_) + | ExprKind::TryBlock(_, _) | ExprKind::Underscore | ExprKind::Path(_, _) | ExprKind::Break(_, _) diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs index 08c5b06575cd..e5dda7cf9104 100644 --- a/compiler/rustc_parse/src/parser/token_type.rs +++ b/compiler/rustc_parse/src/parser/token_type.rs @@ -129,6 +129,7 @@ pub enum TokenType { // Keyword-like symbols. // tidy-alphabetical-start SymAttSyntax, + SymBikeshed, SymClobberAbi, SymInlateout, SymInout, @@ -556,6 +557,7 @@ macro_rules! exp { (Yield) => { exp!(@kw, Yield, KwYield) }; (AttSyntax) => { exp!(@sym, att_syntax, SymAttSyntax) }; + (Bikeshed) => { exp!(@sym, bikeshed, SymBikeshed) }; (ClobberAbi) => { exp!(@sym, clobber_abi, SymClobberAbi) }; (Inlateout) => { exp!(@sym, inlateout, SymInlateout) }; (Inout) => { exp!(@sym, inout, SymInout) }; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 171539b42a6e..c9aaba6cce3b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -572,6 +572,7 @@ symbols! { begin_panic, bench, bevy_ecs, + bikeshed, bikeshed_guaranteed_no_drop, bin, binaryheap_iter, @@ -2284,6 +2285,7 @@ symbols! { truncf64, truncf128, try_blocks, + try_blocks_heterogeneous, try_capture, try_from, try_from_fn, diff --git a/tests/pretty/try-blocks.rs b/tests/pretty/try-blocks.rs new file mode 100644 index 000000000000..fc0af2114769 --- /dev/null +++ b/tests/pretty/try-blocks.rs @@ -0,0 +1,6 @@ +//@ pp-exact +//@ edition: 2024 + +#![feature(try_blocks, try_blocks_heterogeneous)] + +fn main() { try { Some(1)? }; try bikeshed Result { 3 }; } diff --git a/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs new file mode 100644 index 000000000000..9f0073eac9ad --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs @@ -0,0 +1,9 @@ +//@ edition: 2018 + +pub fn main() { + let try_result = try bikeshed Option<_> { //~ ERROR `try bikeshed` expression is experimental + let x = 5; + x + }; + assert_eq!(try_result, Some(5)); +} diff --git a/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr new file mode 100644 index 000000000000..0d31dc507fdd --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr @@ -0,0 +1,17 @@ +error[E0658]: `try bikeshed` expression is experimental + --> $DIR/feature-gate-try_blocks_heterogeneous.rs:4:22 + | +LL | let try_result = try bikeshed Option<_> { + | ______________________^ +LL | | let x = 5; +LL | | x +LL | | }; + | |_____^ + | + = note: see issue #149488 for more information + = help: add `#![feature(try_blocks_heterogeneous)]` 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`. diff --git a/tests/ui/try-block/try-block-bad-type-heterogeneous.rs b/tests/ui/try-block/try-block-bad-type-heterogeneous.rs new file mode 100644 index 000000000000..b099651bf8a9 --- /dev/null +++ b/tests/ui/try-block/try-block-bad-type-heterogeneous.rs @@ -0,0 +1,21 @@ +//@ edition: 2018 + +#![feature(try_blocks_heterogeneous)] + +pub fn main() { + let res = try bikeshed Result { + Err("")?; //~ ERROR `?` couldn't convert the error + 5 + }; + + let res = try bikeshed Result { + "" //~ ERROR type mismatch + }; + + let res = try bikeshed Result { }; //~ ERROR type mismatch + + let res = try bikeshed () { }; + //~^ ERROR a `try` block must return `Result` or `Option` + + let res = try bikeshed i32 { 5 }; //~ ERROR a `try` block must return `Result` or `Option` +} diff --git a/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr b/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr new file mode 100644 index 000000000000..7c7cedd392e6 --- /dev/null +++ b/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr @@ -0,0 +1,46 @@ +error[E0277]: `?` couldn't convert the error to `TryFromSliceError` + --> $DIR/try-block-bad-type-heterogeneous.rs:7:16 + | +LL | Err("")?; + | -------^ the trait `From<&str>` is not implemented for `TryFromSliceError` + | | + | this can't be annotated with `?` because it has type `Result<_, &str>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait +help: the trait `From<&str>` is not implemented for `TryFromSliceError` + but trait `From` is implemented for it + --> $SRC_DIR/core/src/array/mod.rs:LL:COL + = help: for that trait implementation, expected `Infallible`, found `&str` + +error[E0271]: type mismatch resolving ` as Try>::Output == &str` + --> $DIR/try-block-bad-type-heterogeneous.rs:12:9 + | +LL | "" + | ^^ expected `&str`, found `i32` + +error[E0271]: type mismatch resolving ` as Try>::Output == ()` + --> $DIR/try-block-bad-type-heterogeneous.rs:15:47 + | +LL | let res = try bikeshed Result { }; + | ^ expected `()`, found `i32` + +error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`) + --> $DIR/try-block-bad-type-heterogeneous.rs:17:33 + | +LL | let res = try bikeshed () { }; + | ^ could not wrap the final value of the block as `()` doesn't implement `Try` + | + = help: the trait `Try` is not implemented for `()` + +error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`) + --> $DIR/try-block-bad-type-heterogeneous.rs:20:34 + | +LL | let res = try bikeshed i32 { 5 }; + | ^ could not wrap the final value of the block as `i32` doesn't implement `Try` + | + = help: the trait `Try` is not implemented for `i32` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/try-block/try-block-heterogeneous.rs b/tests/ui/try-block/try-block-heterogeneous.rs new file mode 100644 index 000000000000..0b17b7c8655d --- /dev/null +++ b/tests/ui/try-block/try-block-heterogeneous.rs @@ -0,0 +1,19 @@ +//@ check-pass +//@ edition: 2018 + +#![feature(try_blocks_heterogeneous)] + +fn foo() -> Result<(), u16> { Ok(()) } + +fn bar() -> Result<(), u32> { Ok(()) } + +fn whatever() -> Result<(), String> { + try bikeshed _ {} +} + +fn main() { + try bikeshed Result<(), u64> { + foo()?; + bar()?; + }; +} diff --git a/tests/ui/unpretty/exhaustive.expanded.stdout b/tests/ui/unpretty/exhaustive.expanded.stdout index 9e6797c727f0..1fc9e6a72693 100644 --- a/tests/ui/unpretty/exhaustive.expanded.stdout +++ b/tests/ui/unpretty/exhaustive.expanded.stdout @@ -28,6 +28,7 @@ #![feature(trace_macros)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(try_blocks_heterogeneous)] #![feature(yeet_expr)] #![allow(incomplete_features)] #[macro_use] @@ -222,7 +223,12 @@ mod expressions { } /// ExprKind::TryBlock - fn expr_try_block() { try {} try { return; } } + fn expr_try_block() { + try {} + try { return; } + try bikeshed Option<_> {} + try bikeshed Option { None? } + } /// ExprKind::Assign fn expr_assign() { let expr; expr = true; } diff --git a/tests/ui/unpretty/exhaustive.hir.stderr b/tests/ui/unpretty/exhaustive.hir.stderr index eb5c186bd2c0..f6800fc9c1e6 100644 --- a/tests/ui/unpretty/exhaustive.hir.stderr +++ b/tests/ui/unpretty/exhaustive.hir.stderr @@ -1,17 +1,17 @@ error[E0697]: closures cannot be static - --> $DIR/exhaustive.rs:210:9 + --> $DIR/exhaustive.rs:211:9 | LL | static || value; | ^^^^^^^^^ error[E0697]: closures cannot be static - --> $DIR/exhaustive.rs:211:9 + --> $DIR/exhaustive.rs:212:9 | LL | static move || value; | ^^^^^^^^^^^^^^ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/exhaustive.rs:240:13 + --> $DIR/exhaustive.rs:241:13 | LL | fn expr_await() { | --------------- this is not `async` @@ -20,19 +20,19 @@ LL | fut.await; | ^^^^^ only allowed inside `async` functions and blocks error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/exhaustive.rs:289:9 + --> $DIR/exhaustive.rs:292:9 | LL | _; | ^ `_` not allowed here error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:299:9 + --> $DIR/exhaustive.rs:302:9 | LL | x::(); | ^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:300:9 + --> $DIR/exhaustive.rs:303:9 | LL | x::(T, T) -> T; | ^^^^^^^^^^^^^^ only `Fn` traits may use parentheses @@ -44,31 +44,31 @@ LL + x:: -> T; | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:301:9 + --> $DIR/exhaustive.rs:304:9 | LL | crate::() -> ()::expressions::() -> ()::expr_path; | ^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:301:26 + --> $DIR/exhaustive.rs:304:26 | LL | crate::() -> ()::expressions::() -> ()::expr_path; | ^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:304:9 + --> $DIR/exhaustive.rs:307:9 | LL | core::()::marker::()::PhantomData; | ^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:304:19 + --> $DIR/exhaustive.rs:307:19 | LL | core::()::marker::()::PhantomData; | ^^^^^^^^^^ only `Fn` traits may use parentheses error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks - --> $DIR/exhaustive.rs:391:9 + --> $DIR/exhaustive.rs:394:9 | LL | yield; | ^^^^^ @@ -79,7 +79,7 @@ LL | #[coroutine] fn expr_yield() { | ++++++++++++ error[E0703]: invalid ABI: found `C++` - --> $DIR/exhaustive.rs:471:23 + --> $DIR/exhaustive.rs:474:23 | LL | unsafe extern "C++" {} | ^^^^^ invalid ABI @@ -87,7 +87,7 @@ LL | unsafe extern "C++" {} = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions error: `..` patterns are not allowed here - --> $DIR/exhaustive.rs:678:13 + --> $DIR/exhaustive.rs:681:13 | LL | let ..; | ^^ @@ -95,13 +95,13 @@ LL | let ..; = note: only allowed in tuple, tuple struct, and slice patterns error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:793:16 + --> $DIR/exhaustive.rs:796:16 | LL | let _: T() -> !; | ^^^^^^^^ only `Fn` traits may use parentheses error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:807:16 + --> $DIR/exhaustive.rs:810:16 | LL | let _: impl Send; | ^^^^^^^^^ @@ -112,7 +112,7 @@ LL | let _: impl Send; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:808:16 + --> $DIR/exhaustive.rs:811:16 | LL | let _: impl Send + 'static; | ^^^^^^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ LL | let _: impl Send + 'static; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:809:16 + --> $DIR/exhaustive.rs:812:16 | LL | let _: impl 'static + Send; | ^^^^^^^^^^^^^^^^^^^ @@ -134,7 +134,7 @@ LL | let _: impl 'static + Send; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:810:16 + --> $DIR/exhaustive.rs:813:16 | LL | let _: impl ?Sized; | ^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | let _: impl ?Sized; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:811:16 + --> $DIR/exhaustive.rs:814:16 | LL | let _: impl [const] Clone; | ^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL | let _: impl [const] Clone; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:812:16 + --> $DIR/exhaustive.rs:815:16 | LL | let _: impl for<'a> Send; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 873febbbd84d..9396e937d843 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -27,6 +27,7 @@ #![feature(trace_macros)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(try_blocks_heterogeneous)] #![feature(yeet_expr)] #![allow(incomplete_features)] #[attr = MacroUse {arguments: UseAll}] @@ -253,7 +254,19 @@ mod expressions { } /// ExprKind::TryBlock - fn expr_try_block() { { from_output(()) } { return; from_output(()) } } + fn expr_try_block() { + { from_output(()) } + { return; from_output(()) } + type_ascribe!({ from_output(()) }, Option<_>); + type_ascribe!({ + from_output(match branch(None) { + Break { 0: residual } => #[allow(unreachable_code)] + break from_residual(residual), + Continue { 0: val } => #[allow(unreachable_code)] + val, + }) + }, Option) + } /// ExprKind::Assign fn expr_assign() { let expr; expr = true; } diff --git a/tests/ui/unpretty/exhaustive.rs b/tests/ui/unpretty/exhaustive.rs index 0983a0a7e437..0bbc87845695 100644 --- a/tests/ui/unpretty/exhaustive.rs +++ b/tests/ui/unpretty/exhaustive.rs @@ -27,6 +27,7 @@ #![feature(trace_macros)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(try_blocks_heterogeneous)] #![feature(yeet_expr)] #![allow(incomplete_features)] @@ -244,6 +245,8 @@ mod expressions { fn expr_try_block() { try {} try { return; } + try bikeshed Option<_> { } + try bikeshed Option { None? } } /// ExprKind::Assign From f9e1031c1ed428f89b35e8c94d9dbdb09b9f8a2f Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 30 Nov 2025 15:09:29 -0800 Subject: [PATCH 0494/3801] Update clippy for the ast `TryBlock` change --- .../clippy/clippy_lints/src/suspicious_operation_groupings.rs | 2 +- src/tools/clippy/clippy_utils/src/ast_utils/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs index 0d809c17989d..af5e3ccb674a 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs @@ -545,7 +545,7 @@ fn ident_difference_expr_with_base_location( | (Field(_, _), Field(_, _)) | (AssignOp(_, _, _), AssignOp(_, _, _)) | (Assign(_, _, _), Assign(_, _, _)) - | (TryBlock(_), TryBlock(_)) + | (TryBlock(_, _), TryBlock(_, _)) | (Await(_, _), Await(_, _)) | (Gen(_, _, _, _), Gen(_, _, _, _)) | (Block(_, _), Block(_, _)) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 27b5a57c737d..08663782a1d5 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -199,7 +199,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { ) => eq_label(ll.as_ref(), rl.as_ref()) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk, (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lt, rt), (Block(lb, ll), Block(rb, rl)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lb, rb), - (TryBlock(l), TryBlock(r)) => eq_block(l, r), + (TryBlock(lb, lt), TryBlock(rb, rt)) => eq_block(lb, rb) && both(lt.as_deref(), rt.as_deref(), eq_ty), (Yield(l), Yield(r)) => eq_expr_opt(l.expr().map(Box::as_ref), r.expr().map(Box::as_ref)) && l.same_kind(r), (Ret(l), Ret(r)) => eq_expr_opt(l.as_deref(), r.as_deref()), (Break(ll, le), Break(rl, re)) => { From 9495686c40650b42f25085e807574982073fae89 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 30 Nov 2025 15:09:29 -0800 Subject: [PATCH 0495/3801] Update clippy for the ast `TryBlock` change --- clippy_lints/src/suspicious_operation_groupings.rs | 2 +- clippy_utils/src/ast_utils/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs index 0d809c17989d..af5e3ccb674a 100644 --- a/clippy_lints/src/suspicious_operation_groupings.rs +++ b/clippy_lints/src/suspicious_operation_groupings.rs @@ -545,7 +545,7 @@ fn ident_difference_expr_with_base_location( | (Field(_, _), Field(_, _)) | (AssignOp(_, _, _), AssignOp(_, _, _)) | (Assign(_, _, _), Assign(_, _, _)) - | (TryBlock(_), TryBlock(_)) + | (TryBlock(_, _), TryBlock(_, _)) | (Await(_, _), Await(_, _)) | (Gen(_, _, _, _), Gen(_, _, _, _)) | (Block(_, _), Block(_, _)) diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index 27b5a57c737d..08663782a1d5 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -199,7 +199,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { ) => eq_label(ll.as_ref(), rl.as_ref()) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk, (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lt, rt), (Block(lb, ll), Block(rb, rl)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lb, rb), - (TryBlock(l), TryBlock(r)) => eq_block(l, r), + (TryBlock(lb, lt), TryBlock(rb, rt)) => eq_block(lb, rb) && both(lt.as_deref(), rt.as_deref(), eq_ty), (Yield(l), Yield(r)) => eq_expr_opt(l.expr().map(Box::as_ref), r.expr().map(Box::as_ref)) && l.same_kind(r), (Ret(l), Ret(r)) => eq_expr_opt(l.as_deref(), r.as_deref()), (Break(ll, le), Break(rl, re)) => { From 35598c131890c716b088df74111978e0ad7fc343 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 30 Nov 2025 15:35:52 -0800 Subject: [PATCH 0496/3801] Also get rustfmt to at least compile --- src/tools/rustfmt/src/expr.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index 975f9be44e4d..de96f004dc87 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -363,12 +363,13 @@ pub(crate) fn format_expr( // Style Guide RFC for InlineAsm variant pending // https://github.com/rust-dev-tools/fmt-rfcs/issues/152 ast::ExprKind::InlineAsm(..) => Ok(context.snippet(expr.span).to_owned()), - ast::ExprKind::TryBlock(ref block) => { + ast::ExprKind::TryBlock(ref block, None) => { if let rw @ Ok(_) = rewrite_single_line_block(context, "try ", block, Some(&expr.attrs), None, shape) { rw } else { + // FIXME: 9 sounds like `"do catch ".len()`, so may predate the rename // 9 = `try ` let budget = shape.width.saturating_sub(9); Ok(format!( @@ -384,6 +385,8 @@ pub(crate) fn format_expr( )) } } + // FIXME: heterogeneous try blocks, which include a type so are harder to format + ast::ExprKind::TryBlock(_, Some(_)) => Err(RewriteError::Unknown), ast::ExprKind::Gen(capture_by, ref block, ref kind, _) => { let mover = if matches!(capture_by, ast::CaptureBy::Value { .. }) { "move " From fc5a6832eb6e2498bfcc56ec95391841ed06fca7 Mon Sep 17 00:00:00 2001 From: Cole Kauder-McMurrich Date: Wed, 10 Dec 2025 02:14:43 -0500 Subject: [PATCH 0497/3801] fix: is_transmutable always panicking --- .../rust-analyzer/crates/hir-ty/src/next_solver/solver.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs index b5ed770e161d..859e26e37641 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs @@ -225,7 +225,9 @@ impl<'db> SolverDelegate for SolverContext<'db> { _src: Ty<'db>, _assume: ::Const, ) -> Result { - unimplemented!() + // It's better to return some value while not fully implement + // then panic in the mean time + Ok(Certainty::Yes) } fn evaluate_const( From 225c5e08661ac58ddf054611f2d702969cce0e9e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 9 Dec 2025 09:01:12 +0100 Subject: [PATCH 0498/3801] Revert "Turn `BlockLoc` into a tracked struct" This reverts commit 64cabd87be97bb1fa9ac15a77e8fba64d06d426b. --- .../rust-analyzer/crates/hir-def/src/db.rs | 15 +++-- .../crates/hir-def/src/expr_store/lower.rs | 4 +- .../src/expr_store/tests/body/block.rs | 52 +-------------- .../crates/hir-def/src/find_path.rs | 66 +++++++++---------- .../crates/hir-def/src/import_map.rs | 6 +- .../crates/hir-def/src/item_tree.rs | 8 +-- .../rust-analyzer/crates/hir-def/src/lib.rs | 61 ++++++----------- .../crates/hir-def/src/nameres.rs | 32 ++++----- .../crates/hir-def/src/resolver.rs | 4 +- .../crates/hir-def/src/visibility.rs | 30 ++++----- .../rust-analyzer/crates/hir-ty/src/infer.rs | 23 ++++--- .../crates/hir-ty/src/method_resolution.rs | 49 +++++++------- src/tools/rust-analyzer/crates/hir/src/lib.rs | 4 +- .../hir/src/semantics/child_by_source.rs | 2 +- 14 files changed, 144 insertions(+), 212 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index 98df8d0ff445..ccd4bc9be84a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -8,12 +8,12 @@ use la_arena::ArenaMap; use triomphe::Arc; use crate::{ - AssocItemId, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, EnumVariantId, - EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, - FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroExpander, - MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, - StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, - UnionLoc, UseId, UseLoc, VariantId, + AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, + EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, + FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, + MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, + ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, + TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, attrs::AttrFlags, expr_store::{ Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes, @@ -82,6 +82,9 @@ pub trait InternDatabase: RootQueryDb { #[salsa::interned] fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId; // endregion: items + + #[salsa::interned] + fn intern_block(&self, loc: BlockLoc) -> BlockId; } #[query_group::query_group] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index f374dd2cc9ef..df4cff0b8a17 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -31,7 +31,7 @@ use triomphe::Arc; use tt::TextRange; use crate::{ - AdtId, BlockId, BlockIdLt, DefWithBodyId, FunctionId, GenericDefId, ImplId, MacroId, + AdtId, BlockId, BlockLoc, DefWithBodyId, FunctionId, GenericDefId, ImplId, MacroId, ModuleDefId, ModuleId, TraitId, TypeAliasId, UnresolvedMacro, attrs::AttrFlags, builtin_type::BuiltinUint, @@ -2114,7 +2114,7 @@ impl<'db> ExprCollector<'db> { ) -> ExprId { let block_id = self.expander.ast_id_map().ast_id_for_block(&block).map(|file_local_id| { let ast_id = self.expander.in_file(file_local_id); - unsafe { BlockIdLt::new(self.db, ast_id, self.module).to_static() } + self.db.intern_block(BlockLoc { ast_id, module: self.module }) }); let (module, def_map) = diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs index 2d60f44092c5..836a079e777f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs @@ -195,55 +195,9 @@ fn f() { Id(1c00), ), block: Some( - BlockIdLt { - [salsa id]: Id(3c01), - ast_id: InFileWrapper { - file_id: FileId( - EditionedFileIdData { - editioned_file_id: EditionedFileId( - 0, - Edition2024, - ), - krate: Crate( - Id(1c00), - ), - }, - ), - value: FileAstId::(ErasedFileAstId { kind: BlockExpr, index: 0, hash: F9BF }), - }, - module: ModuleIdLt { - [salsa id]: Id(3002), - krate: Crate( - Id(1c00), - ), - block: Some( - BlockIdLt { - [salsa id]: Id(3c00), - ast_id: InFileWrapper { - file_id: FileId( - EditionedFileIdData { - editioned_file_id: EditionedFileId( - 0, - Edition2024, - ), - krate: Crate( - Id(1c00), - ), - }, - ), - value: FileAstId::(ErasedFileAstId { kind: BlockExpr, index: 0, hash: C181 }), - }, - module: ModuleIdLt { - [salsa id]: Id(3000), - krate: Crate( - Id(1c00), - ), - block: None, - }, - }, - ), - }, - }, + BlockId( + 3c01, + ), ), }"#]], ); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index cc0594f00d61..5d1cac8e93c4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -12,7 +12,7 @@ use intern::sym; use rustc_hash::FxHashSet; use crate::{ - FindPathConfig, ModuleDefId, ModuleIdLt, + FindPathConfig, ModuleDefId, ModuleId, db::DefDatabase, item_scope::ItemInNs, nameres::DefMap, @@ -24,7 +24,7 @@ use crate::{ pub fn find_path( db: &dyn DefDatabase, item: ItemInNs, - from: ModuleIdLt<'_>, + from: ModuleId, mut prefix_kind: PrefixKind, ignore_local_imports: bool, mut cfg: FindPathConfig, @@ -102,14 +102,14 @@ struct FindPathCtx<'db> { cfg: FindPathConfig, ignore_local_imports: bool, is_std_item: bool, - from: ModuleIdLt<'db>, + from: ModuleId, from_crate: Crate, - crate_root: ModuleIdLt<'db>, + crate_root: ModuleId, from_def_map: &'db DefMap, fuel: Cell, } -/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleIdLt<'_> +/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Option { // - if the item is a module, jump straight to module search if !ctx.is_std_item @@ -157,10 +157,10 @@ fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Opt } #[tracing::instrument(skip_all)] -fn find_path_for_module<'db>( - ctx: &'db FindPathCtx<'db>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, - module_id: ModuleIdLt<'db>, +fn find_path_for_module( + ctx: &FindPathCtx<'_>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, + module_id: ModuleId, maybe_extern: bool, max_len: usize, ) -> Option { @@ -217,7 +217,7 @@ fn find_path_for_module<'db>( ctx.db, ctx.from_def_map, ctx.from, - ItemInNs::Types(unsafe { module_id.to_static() }.into()), + ItemInNs::Types(module_id.into()), ctx.ignore_local_imports, ); if let Some(scope_name) = scope_name { @@ -244,7 +244,7 @@ fn find_path_for_module<'db>( } // - if the module is in the prelude, return it by that path - let item = ItemInNs::Types(unsafe { module_id.to_static() }.into()); + let item = ItemInNs::Types(module_id.into()); if let Some(choice) = find_in_prelude(ctx.db, ctx.from_def_map, item, ctx.from) { return Some(choice); } @@ -257,10 +257,10 @@ fn find_path_for_module<'db>( best_choice } -fn find_in_scope<'db>( - db: &'db dyn DefDatabase, +fn find_in_scope( + db: &dyn DefDatabase, def_map: &DefMap, - from: ModuleIdLt<'db>, + from: ModuleId, item: ItemInNs, ignore_local_imports: bool, ) -> Option { @@ -278,7 +278,7 @@ fn find_in_prelude( db: &dyn DefDatabase, local_def_map: &DefMap, item: ItemInNs, - from: ModuleIdLt<'_>, + from: ModuleId, ) -> Option { let (prelude_module, _) = local_def_map.prelude()?; let prelude_def_map = prelude_module.def_map(db); @@ -310,8 +310,8 @@ fn find_in_prelude( fn is_kw_kind_relative_to_from( db: &dyn DefDatabase, def_map: &DefMap, - item: ModuleIdLt<'_>, - from: ModuleIdLt<'_>, + item: ModuleId, + from: ModuleId, ) -> Option { if item.krate(db) != from.krate(db) || item.block(db).is_some() || from.block(db).is_some() { return None; @@ -332,9 +332,9 @@ fn is_kw_kind_relative_to_from( } #[tracing::instrument(skip_all)] -fn calculate_best_path<'db>( - ctx: &'db FindPathCtx<'db>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, +fn calculate_best_path( + ctx: &FindPathCtx<'_>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -372,9 +372,9 @@ fn calculate_best_path<'db>( } } -fn find_in_sysroot<'db>( - ctx: &'db FindPathCtx<'db>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, +fn find_in_sysroot( + ctx: &FindPathCtx<'_>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -418,9 +418,9 @@ fn find_in_sysroot<'db>( }); } -fn find_in_dep<'db>( - ctx: &'db FindPathCtx<'db>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, +fn find_in_dep( + ctx: &FindPathCtx<'_>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -461,9 +461,9 @@ fn find_in_dep<'db>( } } -fn calculate_best_path_local<'db>( - ctx: &'db FindPathCtx<'db>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, +fn calculate_best_path_local( + ctx: &FindPathCtx<'_>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -558,11 +558,11 @@ fn path_kind_len(kind: PathKind) -> usize { } /// Finds locations in `from.krate` from which `item` can be imported by `from`. -fn find_local_import_locations<'db>( - ctx: &'db FindPathCtx<'db>, +fn find_local_import_locations( + ctx: &FindPathCtx<'_>, item: ItemInNs, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, - mut cb: impl FnMut(&mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, &Name, ModuleIdLt<'db>), + visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, + mut cb: impl FnMut(&mut FxHashSet<(ItemInNs, ModuleId)>, &Name, ModuleId), ) { let _p = tracing::info_span!("find_local_import_locations").entered(); let db = ctx.db; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 433aead77adb..6c5d226cac1b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -496,7 +496,7 @@ mod tests { use expect_test::{Expect, expect}; use test_fixture::WithFixture; - use crate::{ItemContainerId, Lookup, ModuleIdLt, nameres::assoc::TraitItems, test_db::TestDB}; + use crate::{ItemContainerId, Lookup, nameres::assoc::TraitItems, test_db::TestDB}; use super::*; @@ -628,8 +628,8 @@ mod tests { expect.assert_eq(&actual) } - fn render_path<'db>(db: &'db dyn DefDatabase, info: &ImportInfo) -> String { - let mut module: ModuleIdLt<'db> = info.container; + fn render_path(db: &dyn DefDatabase, info: &ImportInfo) -> String { + let mut module = info.container; let mut segments = vec![&info.name]; let def_map = module.def_map(db); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 1228d1999bcb..2a104fff2b92 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -58,7 +58,7 @@ use syntax::{SyntaxKind, ast, match_ast}; use thin_vec::ThinVec; use triomphe::Arc; -use crate::{BlockId, db::DefDatabase}; +use crate::{BlockId, Lookup, db::DefDatabase}; pub(crate) use crate::item_tree::{ attrs::*, @@ -150,10 +150,10 @@ pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc let _p = tracing::info_span!("block_item_tree_query", ?block).entered(); static EMPTY: OnceLock> = OnceLock::new(); - let ast_id = block.ast_id(db); - let block = ast_id.to_node(db); + let loc = block.lookup(db); + let block = loc.ast_id.to_node(db); - let ctx = lower::Ctx::new(db, ast_id.file_id); + let ctx = lower::Ctx::new(db, loc.ast_id.file_id); let mut item_tree = ctx.lower_block(&block); let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = &item_tree; if small_data.is_empty() diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index e58cb7bad705..97af8ad93def 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -420,31 +420,13 @@ pub struct ProcMacroLoc { impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro); impl_loc!(ProcMacroLoc, id: Fn, container: ModuleId); -#[salsa_macros::tracked(debug)] -#[derive(PartialOrd, Ord)] -pub struct BlockIdLt<'db> { +#[derive(Debug, Hash, PartialEq, Eq, Clone)] +pub struct BlockLoc { pub ast_id: AstId, /// The containing module. - pub module: ModuleIdLt<'db>, -} -pub type BlockId = BlockIdLt<'static>; - -impl BlockIdLt<'_> { - /// # Safety - /// - /// The caller must ensure that the `ModuleId` is not leaked outside of query computations. - pub unsafe fn to_static(self) -> BlockId { - unsafe { std::mem::transmute(self) } - } -} -impl BlockId { - /// # Safety - /// - /// The caller must ensure that the `BlockId` comes from the given database. - pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> BlockIdLt<'db> { - unsafe { std::mem::transmute(self) } - } + pub module: ModuleId, } +impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block); #[salsa_macros::tracked(debug)] #[derive(PartialOrd, Ord)] @@ -454,26 +436,34 @@ pub struct ModuleIdLt<'db> { /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the /// `BlockId` of that block expression. If `None`, this module is part of the crate-level /// `DefMap` of `krate`. - pub block: Option>, + pub block: Option, } pub type ModuleId = ModuleIdLt<'static>; -impl<'db> ModuleIdLt<'db> { +impl ModuleIdLt<'_> { /// # Safety /// /// The caller must ensure that the `ModuleId` is not leaked outside of query computations. pub unsafe fn to_static(self) -> ModuleId { unsafe { std::mem::transmute(self) } } +} +impl ModuleId { + /// # Safety + /// + /// The caller must ensure that the `ModuleId` comes from the given database. + pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> { + unsafe { std::mem::transmute(self) } + } - pub fn def_map(self, db: &'db dyn DefDatabase) -> &'db DefMap { + pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap { match self.block(db) { Some(block) => block_def_map(db, block), None => crate_def_map(db, self.krate(db)), } } - pub(crate) fn local_def_map(self, db: &'db dyn DefDatabase) -> (&'db DefMap, &'db LocalDefMap) { + pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) { match self.block(db) { Some(block) => (block_def_map(db, block), self.only_local_def_map(db)), None => { @@ -483,15 +473,15 @@ impl<'db> ModuleIdLt<'db> { } } - pub(crate) fn only_local_def_map(self, db: &'db dyn DefDatabase) -> &'db LocalDefMap { + pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> &LocalDefMap { crate_local_def_map(db, self.krate(db)).local(db) } - pub fn crate_def_map(self, db: &'db dyn DefDatabase) -> &'db DefMap { + pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap { crate_def_map(db, self.krate(db)) } - pub fn name(self, db: &'db dyn DefDatabase) -> Option { + pub fn name(self, db: &dyn DefDatabase) -> Option { let def_map = self.def_map(db); let parent = def_map[self].parent?; def_map[parent].children.iter().find_map(|(name, module_id)| { @@ -501,24 +491,15 @@ impl<'db> ModuleIdLt<'db> { /// Returns the module containing `self`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. - pub fn containing_module(self, db: &'db dyn DefDatabase) -> Option> { + pub fn containing_module(self, db: &dyn DefDatabase) -> Option { self.def_map(db).containing_module(self) } - pub fn is_block_module(self, db: &'db dyn DefDatabase) -> bool { + pub fn is_block_module(self, db: &dyn DefDatabase) -> bool { self.block(db).is_some() && self.def_map(db).root_module_id() == self } } -impl ModuleId { - /// # Safety - /// - /// The caller must ensure that the `ModuleId` comes from the given database. - pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> { - unsafe { std::mem::transmute(self) } - } -} - impl HasModule for ModuleId { #[inline] fn module(&self, _db: &dyn DefDatabase) -> ModuleId { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index a85237662c43..3f29619bcb62 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -75,7 +75,7 @@ use triomphe::Arc; use tt::TextRange; use crate::{ - AstId, BlockId, BlockIdLt, ExternCrateId, FunctionId, FxIndexMap, Lookup, MacroCallStyles, + AstId, BlockId, BlockLoc, ExternCrateId, FunctionId, FxIndexMap, Lookup, MacroCallStyles, MacroExpander, MacroId, ModuleId, ModuleIdLt, ProcMacroId, UseId, db::DefDatabase, item_scope::{BuiltinShadowMode, ItemScope}, @@ -247,12 +247,12 @@ struct BlockInfo { parent: ModuleId, } -impl std::ops::Index> for DefMap { +impl std::ops::Index for DefMap { type Output = ModuleData; - fn index(&self, id: ModuleIdLt<'_>) -> &ModuleData { + fn index(&self, id: ModuleId) -> &ModuleData { self.modules - .get(&unsafe { id.to_static() }) + .get(&id) .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap {:#?}: {id:#?}", self.root)) } } @@ -400,10 +400,8 @@ pub(crate) fn crate_local_def_map(db: &dyn DefDatabase, crate_id: Crate) -> DefM } #[salsa_macros::tracked(returns(ref))] -pub fn block_def_map<'db>(db: &'db dyn DefDatabase, block_id: BlockIdLt<'db>) -> DefMap { - let block_id = unsafe { block_id.to_static() }; - let ast_id = block_id.ast_id(db); - let module = unsafe { block_id.module(db).to_static() }; +pub fn block_def_map(db: &dyn DefDatabase, block_id: BlockId) -> DefMap { + let BlockLoc { ast_id, module } = block_id.lookup(db); let visibility = Visibility::Module(module, VisibilityExplicitness::Implicit); let module_data = @@ -559,7 +557,7 @@ impl DefMap { /// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. - pub fn containing_module(&self, local_mod: ModuleIdLt<'_>) -> Option { + pub fn containing_module(&self, local_mod: ModuleId) -> Option { match self[local_mod].parent { Some(parent) => Some(parent), None => self.block.map(|BlockInfo { parent, .. }| parent), @@ -664,11 +662,11 @@ impl DefMap { /// /// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns /// `None`, iteration continues. - pub(crate) fn with_ancestor_maps<'db, T>( + pub(crate) fn with_ancestor_maps( &self, - db: &'db dyn DefDatabase, - local_mod: ModuleIdLt<'db>, - f: &mut dyn FnMut(&DefMap, ModuleIdLt<'db>) -> Option, + db: &dyn DefDatabase, + local_mod: ModuleId, + f: &mut dyn FnMut(&DefMap, ModuleId) -> Option, ) -> Option { if let Some(it) = f(self, local_mod) { return Some(it); @@ -854,13 +852,11 @@ impl DerefMut for ModulesMap { } } -impl Index> for ModulesMap { +impl Index for ModulesMap { type Output = ModuleData; - fn index(&self, id: ModuleIdLt<'_>) -> &ModuleData { - self.inner - .get(&unsafe { id.to_static() }) - .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) + fn index(&self, id: ModuleId) -> &ModuleData { + self.inner.get(&id).unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 45d5dc9fcd27..263f603a0bfb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -881,7 +881,7 @@ impl<'db> Resolver<'db> { })); if let Some(block) = expr_scopes.block(scope_id) { let def_map = block_def_map(db, block); - let local_def_map = block.module(db).only_local_def_map(db); + let local_def_map = block.lookup(db).module.only_local_def_map(db); resolver.scopes.push(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, @@ -1087,7 +1087,7 @@ fn resolver_for_scope_<'db>( for scope in scope_chain.into_iter().rev() { if let Some(block) = scopes.block(scope) { let def_map = block_def_map(db, block); - let local_def_map = block.module(db).only_local_def_map(db); + let local_def_map = block.lookup(db).module.only_local_def_map(db); // Using `DefMap::ROOT` is okay here since inside modules other than the root, // there can't directly be expressions. r = r.push_block_scope(def_map, local_def_map, def_map.root); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index 95554c63b97d..a1645de6ec23 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -9,8 +9,8 @@ use syntax::ast::{self, HasVisibility}; use triomphe::Arc; use crate::{ - AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, ModuleIdLt, TraitId, - VariantId, db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, + AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, TraitId, VariantId, + db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, }; pub use crate::item_tree::{RawVisibility, VisibilityExplicitness}; @@ -41,13 +41,9 @@ impl Visibility { } #[tracing::instrument(skip_all)] - pub fn is_visible_from<'db>( - self, - db: &'db dyn DefDatabase, - from_module: ModuleIdLt<'db>, - ) -> bool { + pub fn is_visible_from(self, db: &dyn DefDatabase, from_module: ModuleId) -> bool { let to_module = match self { - Visibility::Module(m, _) => unsafe { m.to_db(db) }, + Visibility::Module(m, _) => m, Visibility::PubCrate(krate) => return from_module.krate(db) == krate, Visibility::Public => return true, }; @@ -63,11 +59,11 @@ impl Visibility { Self::is_visible_from_def_map_(db, def_map, to_module, from_module) } - pub(crate) fn is_visible_from_def_map<'db>( + pub(crate) fn is_visible_from_def_map( self, - db: &'db dyn DefDatabase, - def_map: &'db DefMap, - from_module: ModuleIdLt<'db>, + db: &dyn DefDatabase, + def_map: &DefMap, + from_module: ModuleId, ) -> bool { if cfg!(debug_assertions) { _ = def_map.modules[from_module]; @@ -93,11 +89,11 @@ impl Visibility { Self::is_visible_from_def_map_(db, def_map, to_module, from_module) } - fn is_visible_from_def_map_<'db>( - db: &'db dyn DefDatabase, - def_map: &'db DefMap, - mut to_module: ModuleIdLt<'db>, - mut from_module: ModuleIdLt<'db>, + fn is_visible_from_def_map_( + db: &dyn DefDatabase, + def_map: &DefMap, + mut to_module: ModuleId, + mut from_module: ModuleId, ) -> bool { debug_assert_eq!(to_module.krate(db), def_map.krate()); // `to_module` might be the root module of a block expression. Those have the same diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 70868e4b95aa..cafe0329692c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -653,16 +653,19 @@ impl<'db> InferenceResult<'db> { } pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option> { match self.expr_adjustments.get(&id).and_then(|adjustments| { - adjustments.iter().rfind(|adj| { - // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140 - !matches!( - adj, - Adjustment { - kind: Adjust::NeverToAny, - target, - } if target.is_never() - ) - }) + adjustments + .iter() + .filter(|adj| { + // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140 + !matches!( + adj, + Adjustment { + kind: Adjust::NeverToAny, + target, + } if target.is_never() + ) + }) + .next_back() }) { Some(adjustment) => Some(adjustment.target), None => self.type_of_expr.get(id).copied(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index d9cfe6d84c2b..868ae00329b3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -13,8 +13,8 @@ use tracing::{debug, instrument}; use base_db::Crate; use hir_def::{ - AssocItemId, BlockIdLt, ConstId, FunctionId, GenericParamId, HasModule, ImplId, - ItemContainerId, ModuleId, TraitId, + AssocItemId, BlockId, ConstId, FunctionId, GenericParamId, HasModule, ImplId, ItemContainerId, + ModuleId, TraitId, attrs::AttrFlags, expr_store::path::GenericArgs as HirGenericArgs, hir::ExprId, @@ -558,9 +558,9 @@ pub struct InherentImpls { } #[salsa::tracked] -impl<'db> InherentImpls { +impl InherentImpls { #[salsa::tracked(returns(ref))] - pub fn for_crate(db: &'db dyn HirDatabase, krate: Crate) -> Self { + pub fn for_crate(db: &dyn HirDatabase, krate: Crate) -> Self { let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered(); let crate_def_map = crate_def_map(db, krate); @@ -569,7 +569,7 @@ impl<'db> InherentImpls { } #[salsa::tracked(returns(ref))] - pub fn for_block(db: &'db dyn HirDatabase, block: BlockIdLt<'db>) -> Option> { + pub fn for_block(db: &dyn HirDatabase, block: BlockId) -> Option> { let _p = tracing::info_span!("inherent_impls_in_block_query").entered(); let block_def_map = block_def_map(db, block); @@ -627,13 +627,13 @@ impl InherentImpls { self.map.get(self_ty).map(|it| &**it).unwrap_or_default() } - pub fn for_each_crate_and_block<'db>( - db: &'db dyn HirDatabase, + pub fn for_each_crate_and_block( + db: &dyn HirDatabase, krate: Crate, - block: Option>, + block: Option, for_each: &mut dyn FnMut(&InherentImpls), ) { - let blocks = std::iter::successors(block, |block| block.module(db).block(db)); + let blocks = std::iter::successors(block, |block| block.loc(db).module.block(db)); blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each); for_each(Self::for_crate(db, krate)); } @@ -670,9 +670,9 @@ pub struct TraitImpls { } #[salsa::tracked] -impl<'db> TraitImpls { +impl TraitImpls { #[salsa::tracked(returns(ref))] - pub fn for_crate(db: &'db dyn HirDatabase, krate: Crate) -> Arc { + pub fn for_crate(db: &dyn HirDatabase, krate: Crate) -> Arc { let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered(); let crate_def_map = crate_def_map(db, krate); @@ -681,7 +681,7 @@ impl<'db> TraitImpls { } #[salsa::tracked(returns(ref))] - pub fn for_block(db: &'db dyn HirDatabase, block: BlockIdLt<'db>) -> Option> { + pub fn for_block(db: &dyn HirDatabase, block: BlockId) -> Option> { let _p = tracing::info_span!("inherent_impls_in_block_query").entered(); let block_def_map = block_def_map(db, block); @@ -690,7 +690,7 @@ impl<'db> TraitImpls { } #[salsa::tracked(returns(ref))] - pub fn for_crate_and_deps(db: &'db dyn HirDatabase, krate: Crate) -> Box<[Arc]> { + pub fn for_crate_and_deps(db: &dyn HirDatabase, krate: Crate) -> Box<[Arc]> { krate.transitive_deps(db).iter().map(|&dep| Self::for_crate(db, dep).clone()).collect() } } @@ -792,23 +792,23 @@ impl TraitImpls { } } - pub fn for_each_crate_and_block<'db>( - db: &'db dyn HirDatabase, + pub fn for_each_crate_and_block( + db: &dyn HirDatabase, krate: Crate, - block: Option>, + block: Option, for_each: &mut dyn FnMut(&TraitImpls), ) { - let blocks = std::iter::successors(block, |block| block.module(db).block(db)); + let blocks = std::iter::successors(block, |block| block.loc(db).module.block(db)); blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each); Self::for_crate_and_deps(db, krate).iter().map(|it| &**it).for_each(for_each); } /// Like [`Self::for_each_crate_and_block()`], but takes in account two blocks, one for a trait and one for a self type. - pub fn for_each_crate_and_block_trait_and_type<'db>( - db: &'db dyn HirDatabase, + pub fn for_each_crate_and_block_trait_and_type( + db: &dyn HirDatabase, krate: Crate, - type_block: Option>, - trait_block: Option>, + type_block: Option, + trait_block: Option, for_each: &mut dyn FnMut(&TraitImpls), ) { let in_self_and_deps = TraitImpls::for_crate_and_deps(db, krate); @@ -819,11 +819,10 @@ impl TraitImpls { // that means there can't be duplicate impls; if they meet, we stop the search of the deeper block. // This breaks when they are equal (both will stop immediately), therefore we handle this case // specifically. - let blocks_iter = |block: Option>| { - std::iter::successors(block, |block| block.module(db).block(db)) + let blocks_iter = |block: Option| { + std::iter::successors(block, |block| block.loc(db).module.block(db)) }; - let for_each_block = |current_block: Option>, - other_block: Option>| { + let for_each_block = |current_block: Option, other_block: Option| { blocks_iter(current_block) .take_while(move |&block| { other_block.is_none_or(|other_block| other_block != block) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index e57f031f009a..a50a736ccd0e 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -590,7 +590,7 @@ impl Module { while id.is_block_module(db) { id = id.containing_module(db).expect("block without parent module"); } - Module { id: unsafe { id.to_static() } } + Module { id } } pub fn path_to_root(self, db: &dyn HirDatabase) -> Vec { @@ -4352,7 +4352,7 @@ impl Impl { module.block(db), &mut |impls| extend_with_impls(impls.for_self_ty(&simplified_ty)), ); - std::iter::successors(module.block(db), |block| block.module(db).block(db)) + std::iter::successors(module.block(db), |block| block.loc(db).module.block(db)) .filter_map(|block| TraitImpls::for_block(db, block).as_deref()) .for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls)); for &krate in &**db.all_crates() { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index d924aaa25ddc..c1f72debe54f 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -226,7 +226,7 @@ impl ChildBySource for DefWithBodyId { // All block expressions are merged into the same map, because they logically all add // inner items to the containing `DefWithBodyId`. def_map[def_map.root].scope.child_by_source_to(db, res, file_id); - res[keys::BLOCK].insert(block.ast_id(db).to_ptr(db), block); + res[keys::BLOCK].insert(block.lookup(db).ast_id.to_ptr(db), block); } } } From a3970b079bdba2e8cafc58af3bff1ac0c088331e Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Wed, 10 Dec 2025 11:06:31 +0300 Subject: [PATCH 0499/3801] Build auxiliary in pretty tests --- src/tools/compiletest/src/runtest.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 54d6e0190ddc..79e3ecc2a9c3 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -439,6 +439,9 @@ impl<'test> TestCx<'test> { }; let mut rustc = Command::new(&self.config.rustc_path); + + self.build_all_auxiliary(&self.aux_output_dir(), &mut rustc); + rustc .arg(input) .args(&["-Z", &format!("unpretty={}", pretty_type)]) From ff43366dc24cbd7e6ee72489e6a05df5b1f17dab Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 9 Dec 2025 23:25:05 -0800 Subject: [PATCH 0500/3801] Update `wrapping_sh[lr]` docs and examples --- library/core/src/num/int_macros.rs | 28 ++++++++++++++++++++++++---- library/core/src/num/uint_macros.rs | 28 ++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 99662768a29f..c260cd63f7c4 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2288,6 +2288,13 @@ macro_rules! int_impl { /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where `mask` removes /// any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type. /// + /// Beware that, unlike most other `wrapping_*` methods on integers, this + /// does *not* give the same result as doing the shift in infinite precision + /// then truncating as needed. The behaviour matches what shift instructions + /// do on many processors, and is what the `<<` operator does when overflow + /// checks are disabled, but numerically it's weird. Consider, instead, + /// using [`Self::unbounded_shl`] which has nicer behaviour. + /// /// Note that this is *not* the same as a rotate-left; the RHS of a wrapping shift-left is restricted to /// the range of the type, rather than the bits shifted out of the LHS being returned to the other end. /// The primitive integer types all implement a [`rotate_left`](Self::rotate_left) function, @@ -2296,8 +2303,11 @@ macro_rules! int_impl { /// # Examples /// /// ``` - #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(7), -128);")] - #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);")] + #[doc = concat!("assert_eq!((-1_", stringify!($SelfT), ").wrapping_shl(7), -128);")] + #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(", stringify!($BITS), "), 42);")] + #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(1).wrapping_shl(", stringify!($BITS_MINUS_ONE), "), 0);")] + #[doc = concat!("assert_eq!((-1_", stringify!($SelfT), ").wrapping_shl(128), -1);")] + #[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".wrapping_shl(1025), 10);")] /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")] @@ -2315,6 +2325,13 @@ macro_rules! int_impl { /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where `mask` /// removes any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type. /// + /// Beware that, unlike most other `wrapping_*` methods on integers, this + /// does *not* give the same result as doing the shift in infinite precision + /// then truncating as needed. The behaviour matches what shift instructions + /// do on many processors, and is what the `>>` operator does when overflow + /// checks are disabled, but numerically it's weird. Consider, instead, + /// using [`Self::unbounded_shr`] which has nicer behaviour. + /// /// Note that this is *not* the same as a rotate-right; the RHS of a wrapping shift-right is restricted /// to the range of the type, rather than the bits shifted out of the LHS being returned to the other /// end. The primitive integer types all implement a [`rotate_right`](Self::rotate_right) function, @@ -2323,8 +2340,11 @@ macro_rules! int_impl { /// # Examples /// /// ``` - #[doc = concat!("assert_eq!((-128", stringify!($SelfT), ").wrapping_shr(7), -1);")] - /// assert_eq!((-128i16).wrapping_shr(64), -128); + #[doc = concat!("assert_eq!((-128_", stringify!($SelfT), ").wrapping_shr(7), -1);")] + #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(", stringify!($BITS), "), 42);")] + #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(1).wrapping_shr(", stringify!($BITS_MINUS_ONE), "), 0);")] + /// assert_eq!((-128_i16).wrapping_shr(64), -128); + #[doc = concat!("assert_eq!(10_", stringify!($SelfT), ".wrapping_shr(1025), 5);")] /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index c8224e92b17e..89f330a063ac 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2593,6 +2593,13 @@ macro_rules! uint_impl { /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. /// + /// Beware that, unlike most other `wrapping_*` methods on integers, this + /// does *not* give the same result as doing the shift in infinite precision + /// then truncating as needed. The behaviour matches what shift instructions + /// do on many processors, and is what the `<<` operator does when overflow + /// checks are disabled, but numerically it's weird. Consider, instead, + /// using [`Self::unbounded_shl`] which has nicer behaviour. + /// /// Note that this is *not* the same as a rotate-left; the /// RHS of a wrapping shift-left is restricted to the range /// of the type, rather than the bits shifted out of the LHS @@ -2603,8 +2610,11 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_shl(7), 128);")] - #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);")] + #[doc = concat!("assert_eq!(1_", stringify!($SelfT), ".wrapping_shl(7), 128);")] + #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(", stringify!($BITS), "), 42);")] + #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(1).wrapping_shl(", stringify!($BITS_MINUS_ONE), "), 0);")] + #[doc = concat!("assert_eq!(1_", stringify!($SelfT), ".wrapping_shl(128), 1);")] + #[doc = concat!("assert_eq!(5_", stringify!($SelfT), ".wrapping_shl(1025), 10);")] /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] @@ -2623,6 +2633,13 @@ macro_rules! uint_impl { /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. /// + /// Beware that, unlike most other `wrapping_*` methods on integers, this + /// does *not* give the same result as doing the shift in infinite precision + /// then truncating as needed. The behaviour matches what shift instructions + /// do on many processors, and is what the `>>` operator does when overflow + /// checks are disabled, but numerically it's weird. Consider, instead, + /// using [`Self::unbounded_shr`] which has nicer behaviour. + /// /// Note that this is *not* the same as a rotate-right; the /// RHS of a wrapping shift-right is restricted to the range /// of the type, rather than the bits shifted out of the LHS @@ -2633,8 +2650,11 @@ macro_rules! uint_impl { /// # Examples /// /// ``` - #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".wrapping_shr(7), 1);")] - #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);")] + #[doc = concat!("assert_eq!(128_", stringify!($SelfT), ".wrapping_shr(7), 1);")] + #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(", stringify!($BITS), "), 42);")] + #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(1).wrapping_shr(", stringify!($BITS_MINUS_ONE), "), 0);")] + #[doc = concat!("assert_eq!(128_", stringify!($SelfT), ".wrapping_shr(128), 128);")] + #[doc = concat!("assert_eq!(10_", stringify!($SelfT), ".wrapping_shr(1025), 5);")] /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] From 9e4e9e439076a81357d8ce996d76cc906f137a48 Mon Sep 17 00:00:00 2001 From: Theemathas Chirananthavat Date: Wed, 10 Dec 2025 15:38:16 +0700 Subject: [PATCH 0501/3801] Use `PointeeSized` bound for `TrivialClone` impls These `TrivialClone` impls previously had `?Sized` bounds, which are different from the `PointeeSized` bounds on the corresponding `Clone` and `Copy` impls. So, I've changed the `?Sized` bounds into `PointeeSized` bounds. This mistake was made presumably because the `TrivialClone` PR (https://github.com/rust-lang/rust/pull/135634) was opened in Jan 2025, but merged in Nov 2025. During that time, the sized hierachy PR (https://github.com/rust-lang/rust/pull/137944) was opened in Mar 2025, and merged in Jun 2025. The `TrivialClone` PR was not updated to account for the sized hierachy changes. --- library/core/src/marker.rs | 2 +- library/core/src/ptr/metadata.rs | 2 +- library/core/src/ptr/non_null.rs | 2 +- library/core/src/ptr/unique.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index e945cd77a75f..68f22767d6cf 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -860,7 +860,7 @@ impl Clone for PhantomData { #[doc(hidden)] #[unstable(feature = "trivial_clone", issue = "none")] -unsafe impl TrivialClone for PhantomData {} +unsafe impl TrivialClone for PhantomData {} #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_default", issue = "143894")] diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 998a5b031c28..1a5864316833 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -233,7 +233,7 @@ impl Clone for DynMetadata { } #[doc(hidden)] -unsafe impl TrivialClone for DynMetadata {} +unsafe impl TrivialClone for DynMetadata {} impl Eq for DynMetadata {} diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index aa3af2f18528..cb43d095f5d1 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1656,7 +1656,7 @@ impl Copy for NonNull {} #[doc(hidden)] #[unstable(feature = "trivial_clone", issue = "none")] -unsafe impl TrivialClone for NonNull {} +unsafe impl TrivialClone for NonNull {} #[unstable(feature = "coerce_unsized", issue = "18598")] impl CoerceUnsized> for NonNull where T: Unsize {} diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 5e7b1f703802..1bbe3ea242f6 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -168,7 +168,7 @@ impl Copy for Unique {} #[doc(hidden)] #[unstable(feature = "trivial_clone", issue = "none")] -unsafe impl TrivialClone for Unique {} +unsafe impl TrivialClone for Unique {} #[unstable(feature = "ptr_internals", issue = "none")] impl CoerceUnsized> for Unique where T: Unsize {} From 85aeb4f2593f120ccde53f5855676eaa9739734f Mon Sep 17 00:00:00 2001 From: Boxy Date: Sun, 9 Feb 2025 16:23:41 +0000 Subject: [PATCH 0502/3801] Forbid object lifetime changing pointer casts --- .../src/diagnostics/explain_borrow.rs | 1 + .../src/diagnostics/region_errors.rs | 17 ++ .../rustc_borrowck/src/region_infer/mod.rs | 1 + compiler/rustc_borrowck/src/type_check/mod.rs | 162 ++++++++--- compiler/rustc_middle/src/mir/query.rs | 1 + library/std/src/thread/lifecycle.rs | 7 +- .../ptr-ptr-to-ptr-ptr-different-regions.rs | 15 + tests/ui/cast/ptr-to-ptr-different-regions.rs | 12 +- .../cast/ptr-to-ptr-different-regions.stderr | 31 ++ .../ptr-to-ptr-indirect-different-regions.rs | 15 + ...r-to-ptr-indirect-different-regions.stderr | 31 ++ tests/ui/cast/ptr-to-ptr-principalless.rs | 74 +++++ tests/ui/cast/ptr-to-ptr-principalless.stderr | 274 ++++++++++++++++++ ...-different-regions-id-trait.current.stderr | 8 + ...obj-different-regions-id-trait.next.stderr | 8 + ...-trait-obj-different-regions-lt-ext.stderr | 8 + ...to-trait-obj-different-regions-misc.stderr | 64 ++++ tests/ui/cast/ptr-to-trait-obj-ok.rs | 23 +- 18 files changed, 696 insertions(+), 56 deletions(-) create mode 100644 tests/ui/cast/ptr-ptr-to-ptr-ptr-different-regions.rs create mode 100644 tests/ui/cast/ptr-to-ptr-different-regions.stderr create mode 100644 tests/ui/cast/ptr-to-ptr-indirect-different-regions.rs create mode 100644 tests/ui/cast/ptr-to-ptr-indirect-different-regions.stderr create mode 100644 tests/ui/cast/ptr-to-ptr-principalless.rs create mode 100644 tests/ui/cast/ptr-to-ptr-principalless.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 6bcfa9d8bf9a..bfdfa896cd2b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -410,6 +410,7 @@ impl<'tcx> BorrowExplanation<'tcx> { cx.add_sized_or_copy_bound_info(err, category, &path); if let ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: _, is_implicit_coercion: true, unsize_to: Some(unsize_ty), } = category diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 05826bea66bf..6ebc7db62699 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -541,6 +541,23 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.add_placeholder_from_predicate_note(&mut diag, &path); self.add_sized_or_copy_bound_info(&mut diag, category, &path); + for constraint in &path { + if let ConstraintCategory::Cast { is_raw_ptr_dyn_type_cast: true, .. } = + constraint.category + { + diag.span_note( + constraint.span, + format!("raw pointer casts of trait objects cannot extend lifetimes"), + ); + diag.note(format!( + "this was previously accepted by the compiler but was changed recently" + )); + diag.help(format!( + "see for more information" + )); + } + } + self.buffer_error(diag); } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index e98c60e63380..37b9d684e1a4 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1697,6 +1697,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // should be as limited as possible; the note is prone to false positives and this // constraint usually isn't best to blame. ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: _, unsize_to: Some(unsize_ty), is_implicit_coercion: true, } if to_region == self.universal_regions().fr_static diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 43005fca2984..c066cae697de 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1113,7 +1113,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ); let src_ty = self.normalize(src_ty, location); @@ -1121,7 +1125,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1142,7 +1150,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ); // The type that we see in the fcx is like @@ -1155,7 +1167,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1184,7 +1200,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1217,7 +1237,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1246,6 +1270,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { trait_ref, location.to_locations(), ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, is_implicit_coercion, unsize_to: Some(unsize_to), }, @@ -1271,7 +1296,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { *ty_from, *ty_to, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1334,7 +1363,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { *ty_elem, *ty_to, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1491,55 +1524,90 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { trait_ref, location.to_locations(), ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, is_implicit_coercion: true, unsize_to: None, }, ); - } else if let ty::Dynamic(src_tty, _src_lt) = + } else if let ty::Dynamic(src_tty, src_lt) = *self.struct_tail(src.ty, location).kind() && let ty::Dynamic(dst_tty, dst_lt) = *self.struct_tail(dst.ty, location).kind() - && src_tty.principal().is_some() - && dst_tty.principal().is_some() { - // This checks (lifetime part of) vtable validity for pointer casts, - // which is irrelevant when there are aren't principal traits on - // both sides (aka only auto traits). - // - // Note that other checks (such as denying `dyn Send` -> `dyn - // Debug`) are in `rustc_hir_typeck`. + match (src_tty.principal(), dst_tty.principal()) { + (Some(_), Some(_)) => { + // This checks (lifetime part of) vtable validity for pointer casts, + // which is irrelevant when there are aren't principal traits on + // both sides (aka only auto traits). + // + // Note that other checks (such as denying `dyn Send` -> `dyn + // Debug`) are in `rustc_hir_typeck`. - // Remove auto traits. - // Auto trait checks are handled in `rustc_hir_typeck` as FCW. - let src_obj = Ty::new_dynamic( - tcx, - tcx.mk_poly_existential_predicates( - &src_tty.without_auto_traits().collect::>(), + // Remove auto traits. + // Auto trait checks are handled in `rustc_hir_typeck`. + let src_obj = Ty::new_dynamic( + tcx, + tcx.mk_poly_existential_predicates( + &src_tty.without_auto_traits().collect::>(), + ), + src_lt, + ); + let dst_obj = Ty::new_dynamic( + tcx, + tcx.mk_poly_existential_predicates( + &dst_tty.without_auto_traits().collect::>(), + ), + dst_lt, + ); + + debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); + + // Trait parameters are invariant, the only part that actually has + // subtyping here is the lifetime bound of the dyn-type. + // + // For example in `dyn Trait<'a> + 'b <: dyn Trait<'c> + 'd` we would + // require that `'a == 'c` but only that `'b: 'd`. + // + // We must not allow freely casting lifetime bounds of dyn-types as it + // may allow for inaccessible VTable methods being callable: #136702 + self.sub_types( + src_obj, + dst_obj, + location.to_locations(), + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: true, + is_implicit_coercion: false, + unsize_to: None, + }, + ) + .unwrap(); + } + (None, None) => { + // The principalless (no non-auto traits) case: + // You can only cast `dyn Send + 'long` to `dyn Send + 'short`. + self.constraints.outlives_constraints.push( + OutlivesConstraint { + sup: src_lt.as_var(), + sub: dst_lt.as_var(), + locations: location.to_locations(), + span: location.to_locations().span(self.body), + category: ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: true, + is_implicit_coercion: false, + unsize_to: None, + }, + variance_info: ty::VarianceDiagInfo::default(), + from_closure: false, + }, + ); + } + (None, Some(_)) => bug!( + "introducing a principal should have errored in HIR typeck" ), - // FIXME: Once we disallow casting `*const dyn Trait + 'short` - // to `*const dyn Trait + 'long`, then this can just be `src_lt`. - dst_lt, - ); - let dst_obj = Ty::new_dynamic( - tcx, - tcx.mk_poly_existential_predicates( - &dst_tty.without_auto_traits().collect::>(), - ), - dst_lt, - ); - - debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); - - self.sub_types( - src_obj, - dst_obj, - location.to_locations(), - ConstraintCategory::Cast { - is_implicit_coercion: false, - unsize_to: None, - }, - ) - .unwrap(); + (Some(_), None) => { + bug!("dropping the principal should have been an unsizing cast") + } + } } } CastKind::Transmute => { diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 7629ae9817fe..70954b4cb782 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -108,6 +108,7 @@ pub enum ConstraintCategory<'tcx> { UseAsStatic, TypeAnnotation(AnnotationSource), Cast { + is_raw_ptr_dyn_type_cast: bool, /// Whether this cast is a coercion that was automatically inserted by the compiler. is_implicit_coercion: bool, /// Whether this is an unsizing coercion and if yes, this contains the target type. diff --git a/library/std/src/thread/lifecycle.rs b/library/std/src/thread/lifecycle.rs index 119322b909b5..a48594c606a3 100644 --- a/library/std/src/thread/lifecycle.rs +++ b/library/std/src/thread/lifecycle.rs @@ -111,7 +111,12 @@ where // SAFETY: dynamic size and alignment of the Box remain the same. See below for why the // lifetime change is justified. let rust_start = unsafe { - Box::from_raw(Box::into_raw(Box::new(rust_start)) as *mut (dyn FnOnce() + Send + 'static)) + let ptr = Box::into_raw(Box::new(rust_start)); + let ptr = crate::mem::transmute::< + *mut (dyn FnOnce() + Send + '_), + *mut (dyn FnOnce() + Send + 'static), + >(ptr); + Box::from_raw(ptr) }; let init = Box::new(ThreadInit { handle: thread.clone(), rust_start }); diff --git a/tests/ui/cast/ptr-ptr-to-ptr-ptr-different-regions.rs b/tests/ui/cast/ptr-ptr-to-ptr-ptr-different-regions.rs new file mode 100644 index 000000000000..bb4aeadbb433 --- /dev/null +++ b/tests/ui/cast/ptr-ptr-to-ptr-ptr-different-regions.rs @@ -0,0 +1,15 @@ +//@ check-pass + +// We allow extending lifetimes of object types if they are behind two layers +// of pointer indirection (as opposed to one). This is because this is the more +// general case of casting between two sized types (`*mut T as *mut U`). + +trait Trait { + fn foo(&self) {} +} + +fn bar<'a>(a: *mut *mut (dyn Trait + 'a)) -> *mut *mut (dyn Trait + 'static) { + a as _ +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-ptr-different-regions.rs b/tests/ui/cast/ptr-to-ptr-different-regions.rs index 0d525edc1332..f0021628be01 100644 --- a/tests/ui/cast/ptr-to-ptr-different-regions.rs +++ b/tests/ui/cast/ptr-to-ptr-different-regions.rs @@ -1,20 +1,24 @@ -//@ check-pass - // https://github.com/rust-lang/rust/issues/113257 #![deny(trivial_casts)] // The casts here are not trivial. -struct Foo<'a> { a: &'a () } +struct Foo<'a> { + a: &'a (), +} fn extend_lifetime_very_very_safely<'a>(v: *const Foo<'a>) -> *const Foo<'static> { - // This should pass because raw pointer casts can do anything they want. + // This should pass because raw pointer casts can do anything they want when + // VTables are not involved v as *const Foo<'static> } trait Trait {} +// We want to forbid this as extending lifetimes on object types may allow for +// uncallable VTable methods to become accessible. fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { ptr as _ + //~^ ERROR: lifetime may not live long enough } fn main() { diff --git a/tests/ui/cast/ptr-to-ptr-different-regions.stderr b/tests/ui/cast/ptr-to-ptr-different-regions.stderr new file mode 100644 index 000000000000..c5910be2396b --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-different-regions.stderr @@ -0,0 +1,31 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-different-regions.rs:20:5 + | +LL | fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { + | -- lifetime `'a` defined here +LL | ptr as _ + | ^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `dyn Trait` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-different-regions.rs:20:5 + | +LL | ptr as _ + | ^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `ptr` + | +LL - fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { +LL + fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'a) { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { +LL + fn assert_static<'a>(ptr: *mut (dyn Trait + 'static)) -> *mut (dyn Trait + 'static) { + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/cast/ptr-to-ptr-indirect-different-regions.rs b/tests/ui/cast/ptr-to-ptr-indirect-different-regions.rs new file mode 100644 index 000000000000..50f11c568ad2 --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-indirect-different-regions.rs @@ -0,0 +1,15 @@ +// We want to forbid extending lifetimes on object types behind ptrs +// as it may allow for uncallable VTable methods to become accessible. + +trait Trait { + fn foo(&self) {} +} + +struct MyWrap(T); + +fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> { + a as _ + //~^ ERROR: lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-ptr-indirect-different-regions.stderr b/tests/ui/cast/ptr-to-ptr-indirect-different-regions.stderr new file mode 100644 index 000000000000..43609fa570cb --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-indirect-different-regions.stderr @@ -0,0 +1,31 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-indirect-different-regions.rs:11:5 + | +LL | fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> { + | -- lifetime `'a` defined here +LL | a as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `MyWrap` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-indirect-different-regions.rs:11:5 + | +LL | a as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `a` + | +LL - fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> { +LL + fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'a)> { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> { +LL + fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'static)>) -> *mut MyWrap<(dyn Trait + 'static)> { + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/cast/ptr-to-ptr-principalless.rs b/tests/ui/cast/ptr-to-ptr-principalless.rs new file mode 100644 index 000000000000..0b1032d2669d --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-principalless.rs @@ -0,0 +1,74 @@ +// Test cases involving principal-less traits (dyn Send without a primary trait). + +struct Wrapper(T); + +// Cast to same auto trait + +fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'b) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +// Cast to different auto trait + +fn unprincipled2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +// Cast away principal trait +trait Trait {} + +fn unprincipled3<'a, 'b>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'b) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap3<'a, 'b>(x: *mut (dyn Trait + Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'b)>` is invalid +} + +fn unprincipled_wrap3_static<'a>( + x: *mut (dyn Trait + Send + 'a) +) -> *mut Wrapper { + x as _ + //~^ ERROR: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'static)>` is invalid +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-ptr-principalless.stderr b/tests/ui/cast/ptr-to-ptr-principalless.stderr new file mode 100644 index 000000000000..78f949232a1c --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-principalless.stderr @@ -0,0 +1,274 @@ +error[E0606]: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'b)>` is invalid + --> $DIR/ptr-to-ptr-principalless.rs:63:5 + | +LL | x as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error[E0606]: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'static)>` is invalid + --> $DIR/ptr-to-ptr-principalless.rs:70:5 + | +LL | x as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:8:5 + | +LL | fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'b) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Send` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:8:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:13:5 + | +LL | fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `dyn Send` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:13:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) { +LL + fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'a) { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) { +LL + fn unprincipled_static<'a>(x: *mut (dyn Send + 'static)) -> *mut (dyn Send + 'static) { + | + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:18:5 + | +LL | fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `Wrapper` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:18:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:23:5 + | +LL | fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `Wrapper` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:23:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +LL + fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +LL + fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'static)) -> *mut Wrapper { + | + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:30:5 + | +LL | fn unprincipled2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Sync` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:30:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:35:5 + | +LL | fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `dyn Sync` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:35:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) { +LL + fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'a) { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) { +LL + fn unprincipled2_static<'a>(x: *mut (dyn Send + 'static)) -> *mut (dyn Sync + 'static) { + | + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:40:5 + | +LL | fn unprincipled_wrap2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `Wrapper` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:40:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:45:5 + | +LL | fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `Wrapper` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:45:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +LL + fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +LL + fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'static)) -> *mut Wrapper { + | + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:53:5 + | +LL | fn unprincipled3<'a, 'b>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'b) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Send` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:53:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:58:5 + | +LL | fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `dyn Send` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:58:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) { +LL + fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'a) { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) { +LL + fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'static)) -> *mut (dyn Send + 'static) { + | + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0606`. diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr index 62f17a656855..af7744192223 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr @@ -6,6 +6,14 @@ LL | fn m<'a>() { LL | let unsend: *const dyn Cat<'a> = &(); LL | let _send = unsend as *const S>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17 + | +LL | let _send = unsend as *const S>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr index 62f17a656855..af7744192223 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr @@ -6,6 +6,14 @@ LL | fn m<'a>() { LL | let unsend: *const dyn Cat<'a> = &(); LL | let _send = unsend as *const S>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17 + | +LL | let _send = unsend as *const S>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr index b7319e3356bd..4b5927f094bc 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr @@ -5,6 +5,14 @@ LL | fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> { | -- lifetime `'a` defined here LL | x as _ | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-lt-ext.rs:12:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr index 88a89dc4ac1b..f2c060e4b279 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -12,6 +12,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 @@ -27,6 +34,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information help: `'b` and `'a` must be the same: replace one with the other @@ -44,6 +58,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:12:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:16:5 @@ -59,6 +80,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:16:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:20:5 @@ -97,6 +125,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 @@ -113,6 +148,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information help: `'b` and `'a` must be the same: replace one with the other | @@ -133,6 +175,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 @@ -149,6 +198,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information help: `'b` and `'a` must be the same: replace one with the other | @@ -168,6 +224,14 @@ LL | require_static(ptr as _) | | | `ptr` escapes the function body here | argument requires that `'a` must outlive `'static` + | +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:46:20 + | +LL | require_static(ptr as _) + | ^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 11 previous errors diff --git a/tests/ui/cast/ptr-to-trait-obj-ok.rs b/tests/ui/cast/ptr-to-trait-obj-ok.rs index dbeee9d29441..e6b3b23e2da2 100644 --- a/tests/ui/cast/ptr-to-trait-obj-ok.rs +++ b/tests/ui/cast/ptr-to-trait-obj-ok.rs @@ -1,12 +1,23 @@ //@ check-pass +// Casting pointers to object types has some special rules in order to +// ensure VTables stay valid. E.g. +// - Cannot introduce new autotraits +// - Cannot extend or shrink lifetimes in trait arguments +// - Cannot extend the lifetime of the object type +// +// This test is a mostly miscellaneous set of examples of casts that do +// uphold these rules + trait Trait<'a> {} fn remove_auto<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut dyn Trait<'a> { x as _ } -fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trait<'static> + 'b) { +fn cast_inherent_lt<'a: 'b, 'b>( + x: *mut (dyn Trait<'static> + 'a) +) -> *mut (dyn Trait<'static> + 'b) { x as _ } @@ -14,7 +25,11 @@ fn cast_away_higher_ranked<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut dyn Trait< x as _ } -fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { +fn unprincipled<'a: 'b, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { + x as _ +} + +fn remove_principal<'a: 'b, 'b, 't>(x: *mut (dyn Trait<'t> + Send + 'a)) -> *mut (dyn Send + 'b) { x as _ } @@ -29,7 +44,7 @@ fn remove_auto_wrap<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut Wrapper( +fn cast_inherent_lt_wrap<'a: 'b, 'b>( x: *mut (dyn Trait<'static> + 'a), ) -> *mut Wrapper + 'b> { x as _ @@ -39,7 +54,7 @@ fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapp x as _ } -fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +fn unprincipled_wrap<'a: 'b, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { x as _ } From c47bc5d1a98d11b8f6c579b3cde5498ca369e02a Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Wed, 10 Dec 2025 11:00:20 +0100 Subject: [PATCH 0503/3801] Remove ICE fix that was already backported to 1.91 --- CHANGELOG.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf619d254cec..283c47a368cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,11 +84,6 @@ Current stable, released 2025-12-11 * [`double_parens`] fixed FP when macros are involved [#15420](https://github.com/rust-lang/rust-clippy/pull/15420) -### ICE Fixes - -* [`len_zero`] fixed ICE when fn len has a return type without generic type params - [#15660](https://github.com/rust-lang/rust-clippy/pull/15660) - ## Rust 1.91 Current stable, released 2025-10-30 From f65d2df44808a4a110a3447fb8e0b6099a49188e Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 10 Dec 2025 18:35:13 +0800 Subject: [PATCH 0504/3801] Fix assist `and` -> `and_then` parameter - And fix fallback parentheses Example --- ```rust fn foo() { let foo = Some("foo"); return foo.and$0(Some("bar")); } ``` **Before this PR** ```rust fn foo() { let foo = Some("foo"); return foo.and_then(|| Some("bar")); } ``` **After this PR** ```rust fn foo() { let foo = Some("foo"); return foo.and_then(|it| Some("bar")); } ``` --- ```rust struct Func { f: fn() -> i32 } fn foo() { let foo = true; let func = Func { f: || 2 }; let x = foo.then$0(func.f); } ``` **Before this PR** ```text request handler panicked: Failed to make ast node `syntax::ast::generated::nodes::CallExpr` from text const C: () = func.f(); ``` **After this PR** ```rust struct Func { f: fn() -> i32 } fn foo() { let foo = true; let func = Func { f: || 2 }; let x = foo.then_some((func.f)()); } ``` --- .../src/handlers/replace_method_eager_lazy.rs | 93 +++++++++++++++++-- 1 file changed, 83 insertions(+), 10 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs index c85ec734c07a..6ca3e26ca018 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs @@ -1,4 +1,5 @@ -use ide_db::assists::AssistId; +use hir::Semantics; +use ide_db::{RootDatabase, assists::AssistId, defs::Definition}; use syntax::{ AstNode, ast::{self, Expr, HasArgList, make}, @@ -60,8 +61,8 @@ pub(crate) fn replace_with_lazy_method(acc: &mut Assists, ctx: &AssistContext<'_ format!("Replace {method_name} with {method_name_lazy}"), call.syntax().text_range(), |builder| { + let closured = into_closure(&last_arg, &method_name_lazy); builder.replace(method_name.syntax().text_range(), method_name_lazy); - let closured = into_closure(&last_arg); builder.replace_ast(last_arg, closured); }, ) @@ -79,7 +80,7 @@ fn lazy_method_name(name: &str) -> String { } } -fn into_closure(param: &Expr) -> Expr { +fn into_closure(param: &Expr, name_lazy: &str) -> Expr { (|| { if let ast::Expr::CallExpr(call) = param { if call.arg_list()?.args().count() == 0 { Some(call.expr()?) } else { None } @@ -87,7 +88,11 @@ fn into_closure(param: &Expr) -> Expr { None } })() - .unwrap_or_else(|| make::expr_closure(None, param.clone()).into()) + .unwrap_or_else(|| { + let pats = (name_lazy == "and_then") + .then(|| make::untyped_param(make::ext::simple_ident_pat(make::name("it")).into())); + make::expr_closure(pats, param.clone()).into() + }) } // Assist: replace_with_eager_method @@ -146,21 +151,39 @@ pub(crate) fn replace_with_eager_method(acc: &mut Assists, ctx: &AssistContext<' call.syntax().text_range(), |builder| { builder.replace(method_name.syntax().text_range(), method_name_eager); - let called = into_call(&last_arg); + let called = into_call(&last_arg, &ctx.sema); builder.replace_ast(last_arg, called); }, ) } -fn into_call(param: &Expr) -> Expr { +fn into_call(param: &Expr, sema: &Semantics<'_, RootDatabase>) -> Expr { (|| { if let ast::Expr::ClosureExpr(closure) = param { - if closure.param_list()?.params().count() == 0 { Some(closure.body()?) } else { None } + let mut params = closure.param_list()?.params(); + match params.next() { + Some(_) if params.next().is_none() => { + let params = sema.resolve_expr_as_callable(param)?.params(); + let used_param = Definition::Local(params.first()?.as_local(sema.db)?) + .usages(sema) + .at_least_one(); + if used_param { None } else { Some(closure.body()?) } + } + None => Some(closure.body()?), + Some(_) => None, + } } else { None } })() - .unwrap_or_else(|| make::expr_call(param.clone(), make::arg_list(Vec::new())).into()) + .unwrap_or_else(|| { + let callable = if needs_parens_in_call(param) { + make::expr_paren(param.clone()).into() + } else { + param.clone() + }; + make::expr_call(callable, make::arg_list(Vec::new())).into() + }) } fn eager_method_name(name: &str) -> Option<&str> { @@ -177,6 +200,12 @@ fn ends_is(name: &str, end: &str) -> bool { name.strip_suffix(end).is_some_and(|s| s.is_empty() || s.ends_with('_')) } +fn needs_parens_in_call(param: &Expr) -> bool { + let call = make::expr_call(make::ext::expr_unit(), make::arg_list(Vec::new())); + let callable = call.expr().expect("invalid make call"); + param.needs_parens_in_place_of(call.syntax(), callable.syntax()) +} + #[cfg(test)] mod tests { use crate::tests::check_assist; @@ -333,7 +362,7 @@ fn foo() { r#" fn foo() { let foo = Some("foo"); - return foo.and_then(|| Some("bar")); + return foo.and_then(|it| Some("bar")); } "#, ) @@ -347,7 +376,7 @@ fn foo() { //- minicore: option, fn fn foo() { let foo = Some("foo"); - return foo.and_then$0(|| Some("bar")); + return foo.and_then$0(|it| Some("bar")); } "#, r#" @@ -359,6 +388,26 @@ fn foo() { ) } + #[test] + fn replace_and_then_with_and_used_param() { + check_assist( + replace_with_eager_method, + r#" +//- minicore: option, fn +fn foo() { + let foo = Some("foo"); + return foo.and_then$0(|it| Some(it.strip_suffix("bar"))); +} +"#, + r#" +fn foo() { + let foo = Some("foo"); + return foo.and((|it| Some(it.strip_suffix("bar")))()); +} +"#, + ) + } + #[test] fn replace_then_some_with_then() { check_assist( @@ -395,6 +444,30 @@ fn foo() { let foo = true; let x = foo.then_some(2); } +"#, + ) + } + + #[test] + fn replace_then_with_then_some_needs_parens() { + check_assist( + replace_with_eager_method, + r#" +//- minicore: option, fn, bool_impl +struct Func { f: fn() -> i32 } +fn foo() { + let foo = true; + let func = Func { f: || 2 }; + let x = foo.then$0(func.f); +} +"#, + r#" +struct Func { f: fn() -> i32 } +fn foo() { + let foo = true; + let func = Func { f: || 2 }; + let x = foo.then_some((func.f)()); +} "#, ) } From df007cf8008732cec446bdde0d9604c0232121ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 20 Jun 2025 22:50:22 +0200 Subject: [PATCH 0505/3801] rewrite doc attribute (non-doc-comments) --- compiler/rustc_attr_parsing/messages.ftl | 29 + .../rustc_attr_parsing/src/attributes/doc.rs | 385 +++++++++++++ .../rustc_attr_parsing/src/attributes/mod.rs | 1 + .../rustc_attr_parsing/src/attributes/util.rs | 33 +- compiler/rustc_attr_parsing/src/context.rs | 5 +- .../src/session_diagnostics.rs | 67 +++ .../rustc_hir/src/attrs/data_structures.rs | 73 ++- .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_hir/src/attrs/pretty_printing.rs | 20 + compiler/rustc_hir/src/lints.rs | 42 ++ compiler/rustc_hir_typeck/src/method/probe.rs | 6 +- compiler/rustc_passes/messages.ftl | 32 -- compiler/rustc_passes/src/check_attr.rs | 519 +++++------------- compiler/rustc_passes/src/errors.rs | 64 +-- .../rustc_resolve/src/late/diagnostics.rs | 6 +- 15 files changed, 779 insertions(+), 504 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/doc.rs diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 02ddf8ac0023..4482266c6c2e 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -234,5 +234,34 @@ attr_parsing_unused_multiple = .suggestion = remove this attribute .note = attribute also specified here +attr_parsing_doc_alias_duplicated = doc alias is duplicated + .label = first defined here + attr_parsing_whole_archive_needs_static = linking modifier `whole-archive` is only compatible with `static` linking kind + +attr_parsing_unused_no_lints_note = + attribute `{$name}` without any lints has no effect + +attr_parsing_doc_alias_empty = + {$attr_str} attribute cannot have empty value + +attr_parsing_doc_alias_bad_char = + {$char_} character isn't allowed in {$attr_str} + +attr_parsing_doc_alias_start_end = + {$attr_str} cannot start or end with ' ' + +attr_parsing_doc_keyword_not_keyword = + nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]` + .help = only existing keywords are allowed in core/std + +attr_parsing_doc_inline_conflict = + conflicting doc inlining attributes + .help = remove one of the conflicting attributes + +attr_parsing_doc_inline_conflict_first = + this attribute... + +attr_parsing_doc_inline_conflict_second = + {"."}..conflicts with this attribute diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs new file mode 100644 index 000000000000..a5986170c192 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -0,0 +1,385 @@ +use rustc_attr_data_structures::lints::AttributeLintKind; +use rustc_attr_data_structures::{AttributeKind, DocAttribute, DocInline}; +use rustc_errors::MultiSpan; +use rustc_feature::template; +use rustc_span::{Span, Symbol, edition, sym}; + +use super::{AcceptMapping, AttributeParser}; +use crate::context::{AcceptContext, FinalizeContext, Stage}; +use crate::fluent_generated as fluent; +use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, PathParser}; +use crate::session_diagnostics::{ + DocAliasBadChar, DocAliasEmpty, DocAliasStartEnd, DocKeywordConflict, DocKeywordNotKeyword, +}; + +#[derive(Default)] +pub(crate) struct DocParser { + attribute: DocAttribute, +} + +impl DocParser { + fn parse_single_test_doc_attr_item<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + mip: &'c MetaItemParser<'_>, + ) { + let path = mip.path(); + let args = mip.args(); + + match path.word_sym() { + Some(sym::no_crate_inject) => { + if !args.no_args() { + cx.expected_no_args(args.span().unwrap()); + return; + } + + if self.attribute.no_crate_inject.is_some() { + cx.duplicate_key(path.span(), sym::no_crate_inject); + return; + } + + self.attribute.no_crate_inject = Some(path.span()) + } + Some(sym::attr) => { + let Some(list) = args.list() else { + cx.expected_list(args.span().unwrap_or(path.span())); + return; + }; + + self.attribute.test_attrs.push(todo!()); + } + _ => { + cx.expected_specific_argument( + mip.span(), + [sym::no_crate_inject.as_str(), sym::attr.as_str()].to_vec(), + ); + } + } + } + + fn add_alias<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + alias: Symbol, + span: Span, + is_list: bool, + ) { + let attr_str = + &format!("`#[doc(alias{})]`", if is_list { "(\"...\")" } else { " = \"...\"" }); + if alias == sym::empty { + cx.emit_err(DocAliasEmpty { span, attr_str }); + return; + } + + let alias_str = alias.as_str(); + if let Some(c) = + alias_str.chars().find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' ')) + { + cx.emit_err(DocAliasBadChar { span, attr_str, char_: c }); + return; + } + if alias_str.starts_with(' ') || alias_str.ends_with(' ') { + cx.emit_err(DocAliasStartEnd { span, attr_str }); + return; + } + + if let Some(first_definition) = self.attribute.aliases.get(&alias).copied() { + cx.emit_lint(AttributeLintKind::DuplicateDocAlias { first_definition }, span); + } + + self.attribute.aliases.insert(alias, span); + } + + fn parse_alias<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + path: &PathParser<'_>, + args: &ArgParser<'_>, + ) { + match args { + ArgParser::NoArgs => { + cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); + } + ArgParser::List(list) => { + for i in list.mixed() { + let Some(alias) = i.lit().and_then(|i| i.value_str()) else { + cx.expected_string_literal(i.span(), i.lit()); + continue; + }; + + self.add_alias(cx, alias, i.span(), false); + } + } + ArgParser::NameValue(nv) => { + let Some(alias) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return; + }; + self.add_alias(cx, alias, nv.value_span, false); + } + } + } + + fn parse_keyword<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + path: &PathParser<'_>, + args: &ArgParser<'_>, + ) { + let Some(nv) = args.name_value() else { + cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); + return; + }; + + let Some(keyword) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return; + }; + + fn is_doc_keyword(s: Symbol) -> bool { + // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we + // can remove the `SelfTy` case here, remove `sym::SelfTy`, and update the + // `#[doc(keyword = "SelfTy")` attribute in `library/std/src/keyword_docs.rs`. + s.is_reserved(|| edition::LATEST_STABLE_EDITION) || s.is_weak() || s == sym::SelfTy + } + + if !is_doc_keyword(keyword) { + cx.emit_err(DocKeywordNotKeyword { span: nv.value_span, keyword }); + } + + if self.attribute.keyword.is_some() { + cx.duplicate_key(path.span(), path.word_sym().unwrap()); + return; + } + + self.attribute.keyword = Some((keyword, path.span())); + } + + fn parse_inline<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + path: &PathParser<'_>, + args: &ArgParser<'_>, + inline: DocInline, + ) { + if !args.no_args() { + cx.expected_no_args(args.span().unwrap()); + return; + } + + let span = path.span(); + + if let Some((prev_inline, prev_span)) = self.attribute.inline { + if prev_inline == inline { + let mut spans = MultiSpan::from_spans(vec![prev_span, span]); + spans.push_span_label(prev_span, fluent::attr_parsing_doc_inline_conflict_first); + spans.push_span_label(span, fluent::attr_parsing_doc_inline_conflict_second); + cx.emit_err(DocKeywordConflict { spans }); + return; + } + } + + self.attribute.inline = Some((inline, span)); + } + + fn parse_single_doc_attr_item<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + mip: &MetaItemParser<'_>, + ) { + let path = mip.path(); + let args = mip.args(); + + macro_rules! no_args { + ($ident: ident) => {{ + if !args.no_args() { + cx.expected_no_args(args.span().unwrap()); + return; + } + + if self.attribute.$ident.is_some() { + cx.duplicate_key(path.span(), path.word_sym().unwrap()); + return; + } + + self.attribute.$ident = Some(path.span()); + }}; + } + macro_rules! string_arg { + ($ident: ident) => {{ + let Some(nv) = args.name_value() else { + cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); + return; + }; + + let Some(s) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return; + }; + + if self.attribute.$ident.is_some() { + cx.duplicate_key(path.span(), path.word_sym().unwrap()); + return; + } + + self.attribute.$ident = Some((s, path.span())); + }}; + } + + match path.word_sym() { + Some(sym::alias) => self.parse_alias(cx, path, args), + Some(sym::hidden) => no_args!(hidden), + Some(sym::html_favicon_url) => string_arg!(html_favicon_url), + Some(sym::html_logo_url) => string_arg!(html_logo_url), + Some(sym::html_no_source) => no_args!(html_no_source), + Some(sym::html_playground_url) => string_arg!(html_playground_url), + Some(sym::html_root_url) => string_arg!(html_root_url), + Some(sym::issue_tracker_base_url) => string_arg!(issue_tracker_base_url), + Some(sym::inline) => self.parse_inline(cx, path, args, DocInline::Inline), + Some(sym::no_inline) => self.parse_inline(cx, path, args, DocInline::NoInline), + Some(sym::masked) => no_args!(masked), + Some(sym::cfg) => no_args!(cfg), + Some(sym::cfg_hide) => no_args!(cfg_hide), + Some(sym::notable_trait) => no_args!(notable_trait), + Some(sym::keyword) => self.parse_keyword(cx, path, args), + Some(sym::fake_variadic) => no_args!(fake_variadic), + Some(sym::search_unbox) => no_args!(search_unbox), + Some(sym::rust_logo) => no_args!(rust_logo), + Some(sym::test) => { + let Some(list) = args.list() else { + cx.expected_list(args.span().unwrap_or(path.span())); + return; + }; + + for i in list.mixed() { + match i { + MetaItemOrLitParser::MetaItemParser(mip) => { + self.parse_single_test_doc_attr_item(cx, mip); + } + MetaItemOrLitParser::Lit(lit) => { + cx.unexpected_literal(lit.span); + } + MetaItemOrLitParser::Err(..) => { + // already had an error here, move on. + } + } + } + + // let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path); + // if i_meta.has_name(sym::spotlight) { + // self.tcx.emit_node_span_lint( + // INVALID_DOC_ATTRIBUTES, + // hir_id, + // i_meta.span, + // errors::DocTestUnknownSpotlight { path, span: i_meta.span }, + // ); + // } else if i_meta.has_name(sym::include) + // && let Some(value) = i_meta.value_str() + // { + // let applicability = if list.len() == 1 { + // Applicability::MachineApplicable + // } else { + // Applicability::MaybeIncorrect + // }; + // // If there are multiple attributes, the suggestion would suggest + // // deleting all of them, which is incorrect. + // self.tcx.emit_node_span_lint( + // INVALID_DOC_ATTRIBUTES, + // hir_id, + // i_meta.span, + // errors::DocTestUnknownInclude { + // path, + // value: value.to_string(), + // inner: match attr.style() { + // AttrStyle::Inner => "!", + // AttrStyle::Outer => "", + // }, + // sugg: (attr.span(), applicability), + // }, + // ); + // } else if i_meta.has_name(sym::passes) || i_meta.has_name(sym::no_default_passes) { + // self.tcx.emit_node_span_lint( + // INVALID_DOC_ATTRIBUTES, + // hir_id, + // i_meta.span, + // errors::DocTestUnknownPasses { path, span: i_meta.span }, + // ); + // } else if i_meta.has_name(sym::plugins) { + // self.tcx.emit_node_span_lint( + // INVALID_DOC_ATTRIBUTES, + // hir_id, + // i_meta.span, + // errors::DocTestUnknownPlugins { path, span: i_meta.span }, + // ); + // } else { + // self.tcx.emit_node_span_lint( + // INVALID_DOC_ATTRIBUTES, + // hir_id, + // i_meta.span, + // errors::DocTestUnknownAny { path }, + // ); + // } + } + _ => { + cx.expected_specific_argument( + mip.span(), + [ + sym::alias.as_str(), + sym::hidden.as_str(), + sym::html_favicon_url.as_str(), + sym::html_logo_url.as_str(), + sym::html_no_source.as_str(), + sym::html_playground_url.as_str(), + sym::html_root_url.as_str(), + sym::inline.as_str(), + sym::no_inline.as_str(), + sym::test.as_str(), + ] + .to_vec(), + ); + } + } + } + + fn accept_single_doc_attr<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + args: &'c ArgParser<'_>, + ) { + match args { + ArgParser::NoArgs => { + todo!() + } + ArgParser::List(items) => { + for i in items.mixed() { + match i { + MetaItemOrLitParser::MetaItemParser(mip) => { + self.parse_single_doc_attr_item(cx, mip); + } + MetaItemOrLitParser::Lit(lit) => todo!("error should've used equals"), + MetaItemOrLitParser::Err(..) => { + // already had an error here, move on. + } + } + } + } + ArgParser::NameValue(v) => { + panic!("this should be rare if at all possible"); + } + } + } +} + +impl AttributeParser for DocParser { + const ATTRIBUTES: AcceptMapping = &[( + &[sym::doc], + template!(List: "hidden|inline|...", NameValueStr: "string"), + |this, cx, args| { + this.accept_single_doc_attr(cx, args); + }, + )]; + + fn finalize(self, cx: &FinalizeContext<'_, '_, S>) -> Option { + todo!() + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 65e0957ca900..584f62ca51a3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -40,6 +40,7 @@ pub(crate) mod crate_level; pub(crate) mod debugger; pub(crate) mod deprecation; pub(crate) mod dummy; +pub(crate) mod doc; pub(crate) mod inline; pub(crate) mod link_attrs; pub(crate) mod lint_helpers; diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs index 520fd9da7c2a..ce555be6a47d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/util.rs +++ b/compiler/rustc_attr_parsing/src/attributes/util.rs @@ -32,35 +32,6 @@ pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) } -pub fn is_doc_alias_attrs_contain_symbol<'tcx, T: AttributeExt + 'tcx>( - attrs: impl Iterator, - symbol: Symbol, -) -> bool { - let doc_attrs = attrs.filter(|attr| attr.has_name(sym::doc)); - for attr in doc_attrs { - let Some(values) = attr.meta_item_list() else { - continue; - }; - let alias_values = values.iter().filter(|v| v.has_name(sym::alias)); - for v in alias_values { - if let Some(nested) = v.meta_item_list() { - // #[doc(alias("foo", "bar"))] - let mut iter = nested.iter().filter_map(|item| item.lit()).map(|item| item.symbol); - if iter.any(|s| s == symbol) { - return true; - } - } else if let Some(meta) = v.meta_item() - && let Some(lit) = meta.name_value_literal() - { - // #[doc(alias = "foo")] - if lit.symbol == symbol { - return true; - } - } - } - } - false -} /// Parse a single integer. /// @@ -121,3 +92,7 @@ impl AcceptContext<'_, '_, S> { None } } + +pub fn find_crate_name(attrs: &[impl AttributeExt]) -> Option { + first_attr_value_str_by_name(attrs, sym::crate_name) +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index bc74eaad50bc..af73bf7f9fd2 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -33,6 +33,7 @@ use crate::attributes::crate_level::{ }; use crate::attributes::debugger::DebuggerViualizerParser; use crate::attributes::deprecation::DeprecationParser; +use crate::attributes::doc::DocParser; use crate::attributes::dummy::DummyParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; use crate::attributes::link_attrs::{ @@ -162,7 +163,7 @@ attribute_parsers!( BodyStabilityParser, ConfusablesParser, ConstStabilityParser, - MacroUseParser, + NakedParser, StabilityParser, UsedParser, @@ -427,7 +428,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { &self, span: Span, found: String, - options: &'static [&'static str], + options: &[&'static str], ) -> ErrorGuaranteed { self.emit_err(UnknownMetaItem { span, item: found, expected: options }) } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 2b3108a8d3ed..f122b5a87549 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -4,6 +4,7 @@ use rustc_ast::{self as ast}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, + MultiSpan, }; use rustc_feature::AttributeTemplate; use rustc_hir::AttrPath; @@ -34,6 +35,40 @@ pub(crate) struct InvalidPredicate { pub predicate: String, } +#[derive(Diagnostic)] +#[diag(attr_parsing_doc_alias_empty)] +pub(crate) struct DocAliasEmpty<'a> { + #[primary_span] + pub span: Span, + pub attr_str: &'a str, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_doc_alias_bad_char)] +pub(crate) struct DocAliasBadChar<'a> { + #[primary_span] + pub span: Span, + pub attr_str: &'a str, + pub char_: char, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_doc_alias_start_end)] +pub(crate) struct DocAliasStartEnd<'a> { + #[primary_span] + pub span: Span, + pub attr_str: &'a str, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_doc_keyword_not_keyword)] +#[help] +pub(crate) struct DocKeywordNotKeyword { + #[primary_span] + pub span: Span, + pub keyword: Symbol, +} + /// Error code: E0541 pub(crate) struct UnknownMetaItem<'a> { pub span: Span, @@ -538,6 +573,38 @@ pub(crate) struct NakedFunctionIncompatibleAttribute { pub attr: String, } +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_alias_duplicated)] +pub(crate) struct DocAliasDuplicated { + #[label] + pub first_defn: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_doc_inline_conflict)] +#[help] +pub(crate) struct DocKeywordConflict { + #[primary_span] + pub spans: MultiSpan, +} + + #[derive(Subdiagnostic)] + pub(crate) enum UnusedNote { + #[note(attr_parsing_unused_empty_lints_note)] + EmptyList { name: Symbol }, + #[note(attr_parsing_unused_no_lints_note)] + NoLints { name: Symbol }, + } + + #[derive(LintDiagnostic)] + #[diag(attr_parsing_unused)] + pub(crate) struct Unused { + #[suggestion(code = "", applicability = "machine-applicable")] + pub attr_span: Span, + #[subdiagnostic] + pub note: UnusedNote, + } + #[derive(Diagnostic)] #[diag(attr_parsing_link_ordinal_out_of_range)] #[note] diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index aff79d055838..538c866567a9 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -5,6 +5,7 @@ pub use ReprAttr::*; use rustc_abi::Align; use rustc_ast::token::CommentKind; use rustc_ast::{AttrStyle, ast}; +use rustc_data_structures::fx::FxIndexMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute}; use rustc_span::def_id::DefId; @@ -420,6 +421,70 @@ impl WindowsSubsystemKind { } } +#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub enum DocInline { + Inline, + NoInline, +} + +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub struct DocAttribute { + pub aliases: FxIndexMap, + pub hidden: Option, + pub inline: Option<(DocInline, Span)>, + + // unstable + pub cfg: Option, + pub cfg_hide: Option, + + // builtin + pub fake_variadic: Option, + pub keyword: Option<(Symbol, Span)>, + pub masked: Option, + pub notable_trait: Option, + pub search_unbox: Option, + + // valid on crate + pub html_favicon_url: Option<(Symbol, Span)>, + pub html_logo_url: Option<(Symbol, Span)>, + pub html_playground_url: Option<(Symbol, Span)>, + pub html_root_url: Option<(Symbol, Span)>, + pub html_no_source: Option, + pub issue_tracker_base_url: Option<(Symbol, Span)>, + pub rust_logo: Option, + + // #[doc(test(...))] + pub test_attrs: ThinVec<()>, + pub no_crate_inject: Option, +} + +impl Default for DocAttribute { + fn default() -> Self { + Self { + aliases: FxIndexMap::default(), + hidden: None, + inline: None, + cfg: None, + cfg_hide: None, + fake_variadic: None, + keyword: None, + masked: None, + notable_trait: None, + search_unbox: None, + html_favicon_url: None, + html_logo_url: None, + html_playground_url: None, + html_root_url: None, + html_no_source: None, + issue_tracker_base_url: None, + rust_logo: None, + test_attrs: ThinVec::new(), + no_crate_inject: None, + } + } +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -551,7 +616,13 @@ pub enum AttributeKind { /// Represents `#[rustc_do_not_implement_via_object]`. DoNotImplementViaObject(Span), - /// Represents [`#[doc = "..."]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). + /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). + /// Represents all other uses of the [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html) + /// attribute. + Doc(Box), + + /// Represents specifically [`#[doc = "..."]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). + /// i.e. doc comments. DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol }, /// Represents `#[rustc_dummy]`. diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index a685eb99b833..ad120648c1ee 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -40,6 +40,7 @@ impl AttributeKind { DenyExplicitImpl(..) => No, Deprecation { .. } => Yes, DoNotImplementViaObject(..) => No, + Doc(_) => Yes, DocComment { .. } => Yes, Dummy => No, ExportName { .. } => Yes, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index ea86dfbd9c80..75886fb08a2e 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -4,6 +4,7 @@ use rustc_abi::Align; use rustc_ast::token::CommentKind; use rustc_ast::{AttrStyle, IntTy, UintTy}; use rustc_ast_pretty::pp::Printer; +use rustc_data_structures::fx::FxIndexMap; use rustc_span::hygiene::Transparency; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; use rustc_target::spec::SanitizerSet; @@ -64,6 +65,25 @@ impl PrintAttribute for ThinVec { p.word("]"); } } +impl PrintAttribute for FxIndexMap { + fn should_render(&self) -> bool { + self.is_empty() || self[0].should_render() + } + + fn print_attribute(&self, p: &mut Printer) { + let mut last_printed = false; + p.word("["); + for (i, _) in self { + if last_printed { + p.word_space(","); + } + i.print_attribute(p); + last_printed = i.should_render(); + } + p.word("]"); + } +} + macro_rules! print_skip { ($($t: ty),* $(,)?) => {$( impl PrintAttribute for $t { diff --git a/compiler/rustc_hir/src/lints.rs b/compiler/rustc_hir/src/lints.rs index eba2d182d2c4..abffb9437a51 100644 --- a/compiler/rustc_hir/src/lints.rs +++ b/compiler/rustc_hir/src/lints.rs @@ -31,3 +31,45 @@ pub struct AttributeLint { pub span: Span, pub kind: AttributeLintKind, } + +#[derive(Debug, HashStable_Generic)] +pub enum AttributeLintKind { + /// Copy of `IllFormedAttributeInput` + /// specifically for the `invalid_macro_export_arguments` lint until that is removed, + /// see + InvalidMacroExportArguments { + suggestions: Vec, + }, + UnusedDuplicate { + this: Span, + other: Span, + warning: bool, + }, + IllFormedAttributeInput { + suggestions: Vec, + }, + EmptyAttribute { + first_span: Span, + attr_path: AttrPath, + valid_without_list: bool, + }, + InvalidTarget { + name: AttrPath, + target: Target, + applied: Vec, + only: &'static str, + }, + InvalidStyle { + name: AttrPath, + is_used_as_inner: bool, + target: Target, + target_span: Span, + }, + UnsafeAttrOutsideUnsafe { + attribute_name_span: Span, + sugg_spans: (Span, Span), + }, + DuplicateDocAlias { + first_definition: Span, + }, +} diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index a8457134031c..e4e892ab10f4 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -3,7 +3,7 @@ use std::cell::{Cell, RefCell}; use std::cmp::max; use std::ops::Deref; -use rustc_attr_parsing::is_doc_alias_attrs_contain_symbol; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; use rustc_errors::Applicability; @@ -2535,7 +2535,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let hir_id = self.fcx.tcx.local_def_id_to_hir_id(local_def_id); let attrs = self.fcx.tcx.hir_attrs(hir_id); - if is_doc_alias_attrs_contain_symbol(attrs.into_iter(), method.name) { + if let Some(d) = find_attr!(attrs, AttributeKind::Doc(d) => d) + && d.aliases.contains_key(&method.name) + { return true; } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 70e91c081776..93cd9a9702f7 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -106,18 +106,9 @@ passes_diagnostic_diagnostic_on_unimplemented_only_for_traits = passes_diagnostic_item_first_defined = the diagnostic item is first defined here -passes_doc_alias_bad_char = - {$char_} character isn't allowed in {$attr_str} - passes_doc_alias_bad_location = {$attr_str} isn't allowed on {$location} -passes_doc_alias_duplicated = doc alias is duplicated - .label = first defined here - -passes_doc_alias_empty = - {$attr_str} attribute cannot have empty value - passes_doc_alias_malformed = doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` @@ -127,17 +118,6 @@ passes_doc_alias_not_an_alias = passes_doc_alias_not_string_literal = `#[doc(alias("a"))]` expects string literals -passes_doc_alias_start_end = - {$attr_str} cannot start or end with ' ' - -passes_doc_attr_expects_no_value = - `doc({$attr_name})` does not accept a value - .suggestion = use `doc({$attr_name})` - -passes_doc_attr_expects_string = - `doc({$attr_name})` expects a string value - .suggestion = use `doc({$attr_name} = "...")` - passes_doc_attr_not_crate_level = `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute @@ -163,15 +143,7 @@ passes_doc_expect_str = passes_doc_fake_variadic_not_valid = `#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity -passes_doc_inline_conflict = - conflicting doc inlining attributes - .help = remove one of the conflicting attributes -passes_doc_inline_conflict_first = - this attribute... - -passes_doc_inline_conflict_second = - {"."}..conflicts with this attribute passes_doc_inline_only_use = this attribute can only be applied to a `use` item @@ -188,10 +160,6 @@ passes_doc_keyword_attribute_empty_mod = passes_doc_keyword_attribute_not_mod = `#[doc({$attr_name} = "...")]` should be used on modules -passes_doc_keyword_not_keyword = - nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]` - .help = only existing keywords are allowed in core/std - passes_doc_keyword_only_impl = `#[doc(keyword = "...")]` should be used on impl blocks diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 128986798715..1a48e4360d86 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -141,8 +141,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { target: Target, item: Option>, ) { - let mut doc_aliases = FxHashMap::default(); - let mut specified_inline = None; let mut seen = FxHashMap::default(); let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { @@ -306,15 +304,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::doc, ..] => self.check_doc_attrs( - attr, - attr.span(), - attr_item.style, - hir_id, - target, - &mut specified_inline, - &mut doc_aliases, - ), [sym::no_link, ..] => self.check_no_link(hir_id, attr, span, target), [sym::rustc_no_implicit_autorefs, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) @@ -786,38 +775,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.dcx().emit_err(errors::DocExpectStr { attr_span: meta.span(), attr_name }); } - fn check_doc_alias_value( - &self, - meta: &MetaItemInner, - doc_alias: Symbol, - hir_id: HirId, - target: Target, - is_list: bool, - aliases: &mut FxHashMap, - ) { + fn check_doc_alias_value(&self, span: Span, alias: Symbol, hir_id: HirId, target: Target) { let tcx = self.tcx; - let span = meta.name_value_literal_span().unwrap_or_else(|| meta.span()); - let attr_str = - &format!("`#[doc(alias{})]`", if is_list { "(\"...\")" } else { " = \"...\"" }); - if doc_alias == sym::empty { - tcx.dcx().emit_err(errors::DocAliasEmpty { span, attr_str }); - return; - } - let doc_alias_str = doc_alias.as_str(); - if let Some(c) = doc_alias_str - .chars() - .find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' ')) - { - tcx.dcx().emit_err(errors::DocAliasBadChar { span, attr_str, char_: c }); - return; - } - if doc_alias_str.starts_with(' ') || doc_alias_str.ends_with(' ') { - tcx.dcx().emit_err(errors::DocAliasStartEnd { span, attr_str }); - return; - } - - let span = meta.span(); if let Some(location) = match target { Target::AssocTy => { if let DefKind::Impl { .. } = @@ -874,20 +834,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | Target::MacroCall | Target::Delegation { .. } => None, } { - tcx.dcx().emit_err(errors::DocAliasBadLocation { span, attr_str, location }); - return; - } - if self.tcx.hir_opt_name(hir_id) == Some(doc_alias) { - tcx.dcx().emit_err(errors::DocAliasNotAnAlias { span, attr_str }); - return; - } - if let Err(entry) = aliases.try_insert(doc_alias_str.to_owned(), span) { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - span, - errors::DocAliasDuplicated { first_defn: *entry.entry.get() }, - ); + // FIXME: emit proper error + // tcx.dcx().emit_err(errors::DocAliasBadLocation { + // span, + // errors::DocAliasDuplicated { first_defn: *entry.entry.get() }, + // ); } } @@ -927,7 +878,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_doc_keyword_and_attribute( &self, - meta: &MetaItemInner, + span: Span, hir_id: HirId, attr_kind: DocFakeItemKind, ) { @@ -938,16 +889,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { s.is_reserved(|| edition::LATEST_STABLE_EDITION) || s.is_weak() || s == sym::SelfTy } - // FIXME: This should support attributes with namespace like `diagnostic::do_not_recommend`. - fn is_builtin_attr(s: Symbol) -> bool { - rustc_feature::BUILTIN_ATTRIBUTE_MAP.contains_key(&s) - } - - let value = match meta.value_str() { - Some(value) if value != sym::empty => value, - _ => return self.doc_attr_str_error(meta, attr_kind.name()), - }; - let item_kind = match self.tcx.hir_node(hir_id) { hir::Node::Item(item) => Some(&item.kind), _ => None, @@ -955,21 +896,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match item_kind { Some(ItemKind::Mod(_, module)) => { if !module.item_ids.is_empty() { - self.dcx().emit_err(errors::DocKeywordAttributeEmptyMod { - span: meta.span(), - attr_name: attr_kind.name(), - }); + self.dcx() + .emit_err(errors::DocKeywordEmptyMod { span, attr_name: attr_kind.name() }); return; } } _ => { - self.dcx().emit_err(errors::DocKeywordAttributeNotMod { - span: meta.span(), - attr_name: attr_kind.name(), - }); + self.dcx().emit_err(errors::DocKeywordNotMod { span, attr_name: attr_kind.name() }); return; } } + match attr_kind { DocFakeItemKind::Keyword => { if !is_doc_keyword(value) { @@ -990,7 +927,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_doc_fake_variadic(&self, meta: &MetaItemInner, hir_id: HirId) { + fn check_doc_fake_variadic(&self, span: Span, hir_id: HirId) { let item_kind = match self.tcx.hir_node(hir_id) { hir::Node::Item(item) => Some(&item.kind), _ => None, @@ -1008,18 +945,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> { false }; if !is_valid { - self.dcx().emit_err(errors::DocFakeVariadicNotValid { span: meta.span() }); + self.dcx().emit_err(errors::DocFakeVariadicNotValid { span }); } } _ => { - self.dcx().emit_err(errors::DocKeywordOnlyImpl { span: meta.span() }); + self.dcx().emit_err(errors::DocKeywordOnlyImpl { span }); } } } - fn check_doc_search_unbox(&self, meta: &MetaItemInner, hir_id: HirId) { + fn check_doc_search_unbox(&self, span: Span, hir_id: HirId) { let hir::Node::Item(item) = self.tcx.hir_node(hir_id) else { - self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() }); + self.dcx().emit_err(errors::DocSearchUnboxInvalid { span }); return; }; match item.kind { @@ -1032,7 +969,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }) => {} ItemKind::TyAlias(_, generics, _) if generics.params.len() != 0 => {} _ => { - self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() }); + self.dcx().emit_err(errors::DocSearchUnboxInvalid { span }); } } } @@ -1046,60 +983,32 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// already seen an inlining attribute for this item. /// If so, `specified_inline` holds the value and the span of /// the first `inline`/`no_inline` attribute. - fn check_doc_inline( - &self, - style: AttrStyle, - meta: &MetaItemInner, - hir_id: HirId, - target: Target, - specified_inline: &mut Option<(bool, Span)>, - ) { + fn check_doc_inline(&self, span: Span, hir_id: HirId, target: Target) { match target { - Target::Use | Target::ExternCrate => { - let do_inline = meta.has_name(sym::inline); - if let Some((prev_inline, prev_span)) = *specified_inline { - if do_inline != prev_inline { - let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]); - spans.push_span_label(prev_span, fluent::passes_doc_inline_conflict_first); - spans.push_span_label( - meta.span(), - fluent::passes_doc_inline_conflict_second, - ); - self.dcx().emit_err(errors::DocKeywordConflict { spans }); - } - } else { - *specified_inline = Some((do_inline, meta.span())); - } - } + Target::Use | Target::ExternCrate => {} _ => { self.tcx.emit_node_span_lint( INVALID_DOC_ATTRIBUTES, hir_id, - meta.span(), + span, errors::DocInlineOnlyUse { - attr_span: meta.span(), - item_span: (style == AttrStyle::Outer).then(|| self.tcx.hir_span(hir_id)), + attr_span: span, + item_span: self.tcx.hir_span(hir_id), }, ); } } } - fn check_doc_masked( - &self, - style: AttrStyle, - meta: &MetaItemInner, - hir_id: HirId, - target: Target, - ) { + fn check_doc_masked(&self, span: Span, hir_id: HirId, target: Target) { if target != Target::ExternCrate { self.tcx.emit_node_span_lint( INVALID_DOC_ATTRIBUTES, hir_id, - meta.span(), + span, errors::DocMaskedOnlyExternCrate { - attr_span: meta.span(), - item_span: (style == AttrStyle::Outer).then(|| self.tcx.hir_span(hir_id)), + attr_span: span, + item_span: self.tcx.hir_span(hir_id), }, ); return; @@ -1109,125 +1018,38 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.tcx.emit_node_span_lint( INVALID_DOC_ATTRIBUTES, hir_id, - meta.span(), + span, errors::DocMaskedNotExternCrateSelf { - attr_span: meta.span(), - item_span: (style == AttrStyle::Outer).then(|| self.tcx.hir_span(hir_id)), + attr_span: span, + item_span: self.tcx.hir_span(hir_id), }, ); } } /// Checks that an attribute is *not* used at the crate level. Returns `true` if valid. - fn check_attr_not_crate_level( - &self, - meta: &MetaItemInner, - hir_id: HirId, - attr_name: &str, - ) -> bool { + fn check_attr_not_crate_level(&self, span: Span, hir_id: HirId, attr_name: &str) -> bool { if CRATE_HIR_ID == hir_id { - self.dcx().emit_err(errors::DocAttrNotCrateLevel { span: meta.span(), attr_name }); + self.dcx().emit_err(errors::DocAttrNotCrateLevel { span, attr_name }); return false; } true } /// Checks that an attribute is used at the crate level. Returns `true` if valid. - fn check_attr_crate_level( - &self, - attr_span: Span, - style: AttrStyle, - meta: &MetaItemInner, - hir_id: HirId, - ) -> bool { + fn check_attr_crate_level(&self, span: Span, hir_id: HirId) -> bool { if hir_id != CRATE_HIR_ID { - // insert a bang between `#` and `[...` - let bang_span = attr_span.lo() + BytePos(1); - let sugg = (style == AttrStyle::Outer - && self.tcx.hir_get_parent_item(hir_id) == CRATE_OWNER_ID) - .then_some(errors::AttrCrateLevelOnlySugg { - attr: attr_span.with_lo(bang_span).with_hi(bang_span), - }); self.tcx.emit_node_span_lint( INVALID_DOC_ATTRIBUTES, hir_id, - meta.span(), - errors::AttrCrateLevelOnly { sugg }, + span, + errors::AttrCrateLevelOnly {}, ); return false; } true } - fn check_doc_attr_string_value(&self, meta: &MetaItemInner, hir_id: HirId) { - if meta.value_str().is_none() { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::DocAttrExpectsString { attr_name: meta.name().unwrap() }, - ); - } - } - - fn check_doc_attr_no_value(&self, meta: &MetaItemInner, hir_id: HirId) { - if !meta.is_word() { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::DocAttrExpectsNoValue { attr_name: meta.name().unwrap() }, - ); - } - } - - /// Checks that `doc(test(...))` attribute contains only valid attributes and are at the right place. - fn check_test_attr( - &self, - attr_span: Span, - style: AttrStyle, - meta: &MetaItemInner, - hir_id: HirId, - ) { - if let Some(metas) = meta.meta_item_list() { - for i_meta in metas { - match (i_meta.name(), i_meta.meta_item()) { - (Some(sym::attr), _) => { - // Allowed everywhere like `#[doc]` - } - (Some(sym::no_crate_inject), _) => { - self.check_attr_crate_level(attr_span, style, meta, hir_id); - } - (_, Some(m)) => { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span(), - errors::DocTestUnknown { - path: rustc_ast_pretty::pprust::path_to_string(&m.path), - }, - ); - } - (_, None) => { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span(), - errors::DocTestLiteral, - ); - } - } - } - } else { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::DocTestTakesList, - ); - } - } - /// Check that the `#![doc(auto_cfg)]` attribute has the expected input. fn check_doc_auto_cfg(&self, meta: &MetaItem, hir_id: HirId) { match &meta.kind { @@ -1290,173 +1112,118 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// of one item. Read the documentation of [`check_doc_inline`] for more information. /// /// [`check_doc_inline`]: Self::check_doc_inline - fn check_doc_attrs( - &self, - attr: &Attribute, - attr_span: Span, - style: AttrStyle, - hir_id: HirId, - target: Target, - specified_inline: &mut Option<(bool, Span)>, - aliases: &mut FxHashMap, - ) { - if let Some(list) = attr.meta_item_list() { - for meta in &list { - if let Some(i_meta) = meta.meta_item() { - match i_meta.name() { - Some(sym::alias) => { - if self.check_attr_not_crate_level(meta, hir_id, "alias") { - self.check_doc_alias(meta, hir_id, target, aliases); - } - } + fn check_doc_attrs(&self, attr: &DocAttribute, hir_id: HirId, target: Target) { + let DocAttribute { + aliases, + // valid pretty much anywhere, not checked here? + // FIXME: should we? + hidden: _, + inline, + // FIXME: currently unchecked + cfg: _, + cfg_hide, + fake_variadic, + keyword, + masked, + // FIXME: currently unchecked + notable_trait: _, + search_unbox, + html_favicon_url, + html_logo_url, + html_playground_url, + html_root_url, + html_no_source, + issue_tracker_base_url, + rust_logo, + // allowed anywhere + test_attrs: _, + no_crate_inject, + } = attr; - Some(sym::keyword) => { - if self.check_attr_not_crate_level(meta, hir_id, "keyword") { - self.check_doc_keyword_and_attribute( - meta, - hir_id, - DocFakeItemKind::Keyword, - ); - } - } - - Some(sym::attribute) => { - if self.check_attr_not_crate_level(meta, hir_id, "attribute") { - self.check_doc_keyword_and_attribute( - meta, - hir_id, - DocFakeItemKind::Attribute, - ); - } - } - - Some(sym::fake_variadic) => { - if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") { - self.check_doc_fake_variadic(meta, hir_id); - } - } - - Some(sym::search_unbox) => { - if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") { - self.check_doc_search_unbox(meta, hir_id); - } - } - - Some(sym::test) => { - self.check_test_attr(attr_span, style, meta, hir_id); - } - - Some( - sym::html_favicon_url - | sym::html_logo_url - | sym::html_playground_url - | sym::issue_tracker_base_url - | sym::html_root_url, - ) => { - self.check_attr_crate_level(attr_span, style, meta, hir_id); - self.check_doc_attr_string_value(meta, hir_id); - } - - Some(sym::html_no_source) => { - self.check_attr_crate_level(attr_span, style, meta, hir_id); - self.check_doc_attr_no_value(meta, hir_id); - } - - Some(sym::auto_cfg) => { - self.check_doc_auto_cfg(i_meta, hir_id); - } - - Some(sym::inline | sym::no_inline) => { - self.check_doc_inline(style, meta, hir_id, target, specified_inline) - } - - Some(sym::masked) => self.check_doc_masked(style, meta, hir_id, target), - - Some(sym::cfg | sym::hidden | sym::notable_trait) => {} - - Some(sym::rust_logo) => { - if self.check_attr_crate_level(attr_span, style, meta, hir_id) - && !self.tcx.features().rustdoc_internals() - { - feature_err( - &self.tcx.sess, - sym::rustdoc_internals, - meta.span(), - fluent::passes_doc_rust_logo, - ) - .emit(); - } - } - - _ => { - let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path); - if i_meta.has_name(sym::spotlight) { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span, - errors::DocTestUnknownSpotlight { path, span: i_meta.span }, - ); - } else if i_meta.has_name(sym::include) - && let Some(value) = i_meta.value_str() - { - let applicability = if list.len() == 1 { - Applicability::MachineApplicable - } else { - Applicability::MaybeIncorrect - }; - // If there are multiple attributes, the suggestion would suggest - // deleting all of them, which is incorrect. - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span, - errors::DocTestUnknownInclude { - path, - value: value.to_string(), - inner: match style { - AttrStyle::Inner => "!", - AttrStyle::Outer => "", - }, - sugg: (attr.span(), applicability), - }, - ); - } else if i_meta.has_name(sym::passes) - || i_meta.has_name(sym::no_default_passes) - { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span, - errors::DocTestUnknownPasses { path, span: i_meta.span }, - ); - } else if i_meta.has_name(sym::plugins) { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span, - errors::DocTestUnknownPlugins { path, span: i_meta.span }, - ); - } else { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span, - errors::DocTestUnknownAny { path }, - ); - } - } - } - } else { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::DocInvalid, - ); - } + for (alias, span) in aliases { + if self.check_attr_not_crate_level(*span, hir_id, "alias") { + self.check_doc_alias_value(*span, *alias, hir_id, target); } } + + if let Some((_, span)) = keyword { + if self.check_attr_not_crate_level(*span, hir_id, "keyword") { + self.check_doc_keyword(*span, hir_id); + } + } + + // FIXME: check doc attribute + // self.check_doc_keyword(meta, hir_id); + // self.check_doc_keyword_and_attribute( + // meta, + // hir_id, + // DocFakeItemKind::Keyword, + // ); + // } + // } + // Some(sym::attribute) => { + // if self.check_attr_not_crate_level(meta, hir_id, "attribute") { + // self.check_doc_keyword_and_attribute( + // meta, + // hir_id, + // DocFakeItemKind::Attribute, + // ); + + if let Some(span) = fake_variadic { + if self.check_attr_not_crate_level(*span, hir_id, "fake_variadic") { + self.check_doc_fake_variadic(*span, hir_id); + } + } + + if let Some(span) = search_unbox { + if self.check_attr_not_crate_level(*span, hir_id, "search_unbox") { + self.check_doc_search_unbox(*span, hir_id); + } + } + + for i in [ + html_favicon_url, + html_logo_url, + html_playground_url, + issue_tracker_base_url, + html_root_url, + ] { + if let Some((_, span)) = i { + self.check_attr_crate_level(*span, hir_id); + } + } + + for i in [html_no_source, no_crate_inject] { + if let Some(span) = i { + self.check_attr_crate_level(*span, hir_id); + } + } + + if let Some((_, span)) = inline { + self.check_doc_inline(*span, hir_id, target) + } + + if let Some(span) = rust_logo { + if self.check_attr_crate_level(*span, hir_id) + && !self.tcx.features().rustdoc_internals() + { + feature_err( + &self.tcx.sess, + sym::rustdoc_internals, + *span, + fluent::passes_doc_rust_logo, + ) + .emit(); + } + } + + if let Some(span) = masked { + self.check_doc_masked(*span, hir_id, target); + } + + if let Some(span) = cfg_hide { + self.check_attr_crate_level(*span, hir_id); + } } fn check_has_incoherent_inherent_impls(&self, attr: &Attribute, span: Span, target: Target) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 6aa0f5212af7..926aba5082de 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -30,12 +30,6 @@ pub(crate) struct DocAttrExpectsString { pub(crate) attr_name: Symbol, } -#[derive(LintDiagnostic)] -#[diag(passes_doc_attr_expects_no_value)] -pub(crate) struct DocAttrExpectsNoValue { - pub(crate) attr_name: Symbol, -} - #[derive(Diagnostic)] #[diag(passes_autodiff_attr)] pub(crate) struct AutoDiffAttr { @@ -143,31 +137,6 @@ pub(crate) struct DocExpectStr<'a> { pub attr_name: &'a str, } -#[derive(Diagnostic)] -#[diag(passes_doc_alias_empty)] -pub(crate) struct DocAliasEmpty<'a> { - #[primary_span] - pub span: Span, - pub attr_str: &'a str, -} - -#[derive(Diagnostic)] -#[diag(passes_doc_alias_bad_char)] -pub(crate) struct DocAliasBadChar<'a> { - #[primary_span] - pub span: Span, - pub attr_str: &'a str, - pub char_: char, -} - -#[derive(Diagnostic)] -#[diag(passes_doc_alias_start_end)] -pub(crate) struct DocAliasStartEnd<'a> { - #[primary_span] - pub span: Span, - pub attr_str: &'a str, -} - #[derive(Diagnostic)] #[diag(passes_doc_alias_bad_location)] pub(crate) struct DocAliasBadLocation<'a> { @@ -185,13 +154,6 @@ pub(crate) struct DocAliasNotAnAlias<'a> { pub attr_str: &'a str, } -#[derive(LintDiagnostic)] -#[diag(passes_doc_alias_duplicated)] -pub(crate) struct DocAliasDuplicated { - #[label] - pub first_defn: Span, -} - #[derive(Diagnostic)] #[diag(passes_doc_alias_not_string_literal)] pub(crate) struct DocAliasNotStringLiteral { @@ -261,14 +223,6 @@ pub(crate) struct DocSearchUnboxInvalid { pub span: Span, } -#[derive(Diagnostic)] -#[diag(passes_doc_inline_conflict)] -#[help] -pub(crate) struct DocKeywordConflict { - #[primary_span] - pub spans: MultiSpan, -} - #[derive(LintDiagnostic)] #[diag(passes_doc_inline_only_use)] #[note] @@ -276,7 +230,7 @@ pub(crate) struct DocInlineOnlyUse { #[label] pub attr_span: Span, #[label(passes_not_a_use_item_label)] - pub item_span: Option, + pub item_span: Span, } #[derive(LintDiagnostic)] @@ -286,7 +240,7 @@ pub(crate) struct DocMaskedOnlyExternCrate { #[label] pub attr_span: Span, #[label(passes_not_an_extern_crate_label)] - pub item_span: Option, + pub item_span: Span, } #[derive(LintDiagnostic)] @@ -295,7 +249,7 @@ pub(crate) struct DocMaskedNotExternCrateSelf { #[label] pub attr_span: Span, #[label(passes_extern_crate_self_label)] - pub item_span: Option, + pub item_span: Span, } #[derive(Diagnostic)] @@ -1353,17 +1307,7 @@ pub(crate) struct IneffectiveUnstableImpl; #[derive(LintDiagnostic)] #[diag(passes_attr_crate_level)] #[note] -pub(crate) struct AttrCrateLevelOnly { - #[subdiagnostic] - pub sugg: Option, -} - -#[derive(Subdiagnostic)] -#[suggestion(passes_suggestion, applicability = "maybe-incorrect", code = "!", style = "verbose")] -pub(crate) struct AttrCrateLevelOnlySugg { - #[primary_span] - pub attr: Span, -} +pub(crate) struct AttrCrateLevelOnly {} /// "sanitize attribute not allowed here" #[derive(Diagnostic)] diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 71baef458bbf..a18913c1c1c7 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -10,7 +10,7 @@ use rustc_ast::{ Item, ItemKind, MethodCall, NodeId, Path, PathSegment, Ty, TyKind, }; use rustc_ast_pretty::pprust::where_bound_predicate_to_string; -use rustc_attr_parsing::is_doc_alias_attrs_contain_symbol; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{ @@ -903,7 +903,9 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // confused by them. continue; } - if is_doc_alias_attrs_contain_symbol(r.tcx.get_attrs(did, sym::doc), item_name) { + if let Some(d) = find_attr!(r.tcx.get_all_attrs(did), AttributeKind::Doc(d) => d) + && d.aliases.contains_key(&item_name) + { return Some(did); } } From 3f08e4dcd9ab5820c742a0b7f0a3f8fb32d1bd6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 22 Jun 2025 17:29:23 +0200 Subject: [PATCH 0506/3801] start using parsed doc attributes everywhere --- compiler/rustc_hir/src/hir.rs | 4 ---- compiler/rustc_lint/src/builtin.rs | 20 +++++--------------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 6444c862d520..e8a91dae0749 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1376,7 +1376,6 @@ impl AttributeExt for Attribute { fn doc_str(&self) -> Option { match &self { Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment), - Attribute::Unparsed(_) if self.has_name(sym::doc) => self.value_str(), _ => None, } } @@ -1391,9 +1390,6 @@ impl AttributeExt for Attribute { Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => { Some((*comment, *kind)) } - Attribute::Unparsed(_) if self.has_name(sym::doc) => { - self.value_str().map(|s| (s, CommentKind::Line)) - } _ => None, } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index dd0aa848ed2c..0805ef47079b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -25,7 +25,7 @@ use rustc_attr_parsing::AttributeParser; use rustc_errors::{Applicability, LintDiagnostic}; use rustc_feature::GateIssue; use rustc_hir as hir; -use rustc_hir::attrs::AttributeKind; +use rustc_hir::attrs::{AttributeKind, DocAttribute}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::intravisit::FnKind as HirFnKind; @@ -396,26 +396,16 @@ pub struct MissingDoc; impl_lint_pass!(MissingDoc => [MISSING_DOCS]); fn has_doc(attr: &hir::Attribute) -> bool { - if attr.is_doc_comment().is_some() { + if matches!(attr, hir::Attribute::Parsed(AttributeKind::DocComment { .. })) { return true; } - if !attr.has_name(sym::doc) { - return false; - } - - if attr.value_str().is_some() { + if let hir::Attribute::Parsed(AttributeKind::Doc(d)) = attr + && matches!(d.as_ref(), DocAttribute { hidden: Some(..), .. }) + { return true; } - if let Some(list) = attr.meta_item_list() { - for meta in list { - if meta.has_name(sym::hidden) { - return true; - } - } - } - false } From acb32df7b11d55d11c155aa22d03eeb33a581961 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 23 Oct 2025 16:59:19 +0200 Subject: [PATCH 0507/3801] Continue migration to new Attribute API for `doc` attribute --- Cargo.lock | 2 - compiler/rustc_ast/src/attr/mod.rs | 8 + compiler/rustc_attr_parsing/messages.ftl | 55 +++ .../rustc_attr_parsing/src/attributes/cfg.rs | 2 +- .../rustc_attr_parsing/src/attributes/doc.rs | 439 ++++++++++++------ .../rustc_attr_parsing/src/attributes/mod.rs | 2 +- .../rustc_attr_parsing/src/attributes/util.rs | 7 +- compiler/rustc_attr_parsing/src/context.rs | 2 + compiler/rustc_attr_parsing/src/interface.rs | 11 - compiler/rustc_attr_parsing/src/lib.rs | 3 +- .../src/session_diagnostics.rs | 114 ++++- .../rustc_hir/src/attrs/data_structures.rs | 33 +- compiler/rustc_hir/src/hir.rs | 4 + compiler/rustc_hir/src/lints.rs | 28 +- compiler/rustc_hir_typeck/Cargo.toml | 1 - compiler/rustc_hir_typeck/src/lib.rs | 2 - compiler/rustc_hir_typeck/src/method/probe.rs | 4 +- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/levels.rs | 6 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 17 +- compiler/rustc_middle/src/ty/util.rs | 12 +- compiler/rustc_passes/Cargo.toml | 1 - compiler/rustc_passes/messages.ftl | 63 +-- compiler/rustc_passes/src/check_attr.rs | 247 ++-------- compiler/rustc_passes/src/errors.rs | 135 +----- .../rustc_resolve/src/late/diagnostics.rs | 5 +- 26 files changed, 597 insertions(+), 608 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03a4d71f67c3..bb81cada72ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4011,7 +4011,6 @@ dependencies = [ "itertools", "rustc_abi", "rustc_ast", - "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -4433,7 +4432,6 @@ dependencies = [ "rustc_abi", "rustc_ast", "rustc_ast_lowering", - "rustc_ast_pretty", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 901b645b8c4e..d54d900128bd 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -220,6 +220,11 @@ impl AttributeExt for Attribute { fn is_automatically_derived_attr(&self) -> bool { self.has_name(sym::automatically_derived) } + + fn is_doc_hidden(&self) -> bool { + self.has_name(sym::doc) + && self.meta_item_list().is_some_and(|l| list_contains_name(&l, sym::hidden)) + } } impl Attribute { @@ -830,6 +835,9 @@ pub trait AttributeExt: Debug { /// commented module (for inner doc) vs within its parent module (for outer /// doc). fn doc_resolution_scope(&self) -> Option; + + /// Returns `true` if this attribute contains `doc(hidden)`. + fn is_doc_hidden(&self) -> bool; } // FIXME(fn_delegation): use function delegation instead of manually forwarding diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 4482266c6c2e..4d7716560fb2 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -256,6 +256,10 @@ attr_parsing_doc_keyword_not_keyword = nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]` .help = only existing keywords are allowed in core/std +attr_parsing_doc_attribute_not_attribute = + nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]` + .help = only existing builtin attributes are allowed in core/std + attr_parsing_doc_inline_conflict = conflicting doc inlining attributes .help = remove one of the conflicting attributes @@ -265,3 +269,54 @@ attr_parsing_doc_inline_conflict_first = attr_parsing_doc_inline_conflict_second = {"."}..conflicts with this attribute + +attr_parsing_doc_auto_cfg_expects_hide_or_show = + only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` + +attr_parsing_doc_auto_cfg_hide_show_unexpected_item = + `#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items + +attr_parsing_doc_auto_cfg_hide_show_expects_list = + `#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items + +attr_parsing_doc_invalid = + invalid `doc` attribute + +attr_parsing_doc_unknown_include = + unknown `doc` attribute `include` + .suggestion = use `doc = include_str!` instead + +attr_parsing_doc_unknown_spotlight = + unknown `doc` attribute `spotlight` + .note = `doc(spotlight)` was renamed to `doc(notable_trait)` + .suggestion = use `notable_trait` instead + .no_op_note = `doc(spotlight)` is now a no-op + +attr_parsing_doc_unknown_passes = + unknown `doc` attribute `{$name}` + .note = `doc` attribute `{$name}` no longer functions; see issue #44136 + .label = no longer functions + .no_op_note = `doc({$name})` is now a no-op + +attr_parsing_doc_unknown_plugins = + unknown `doc` attribute `plugins` + .note = `doc` attribute `plugins` no longer functions; see issue #44136 and CVE-2018-1000622 + .label = no longer functions + .no_op_note = `doc(plugins)` is now a no-op + +attr_parsing_doc_unknown_any = + unknown `doc` attribute `{$name}` + +attr_parsing_doc_auto_cfg_wrong_literal = + expected boolean for `#[doc(auto_cfg = ...)]` + +attr_parsing_doc_test_takes_list = + `#[doc(test(...)]` takes a list of attributes + +attr_parsing_doc_test_unknown = + unknown `doc(test)` attribute `{$name}` + +attr_parsing_doc_test_literal = `#![doc(test(...)]` does not take a literal + +attr_parsing_doc_alias_malformed = + doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 490e28ed64c5..6ffe25098308 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -171,7 +171,7 @@ fn parse_cfg_entry_target( Ok(CfgEntry::All(result, list.span)) } -fn parse_name_value( +pub(crate) fn parse_name_value( name: Symbol, name_span: Span, value: Option<&NameValueParser>, diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index a5986170c192..65651e617179 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -1,20 +1,99 @@ -use rustc_attr_data_structures::lints::AttributeLintKind; -use rustc_attr_data_structures::{AttributeKind, DocAttribute, DocInline}; +// FIXME: to be removed +#![allow(unused_imports)] + +use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit}; +use rustc_ast::token::CommentKind; use rustc_errors::MultiSpan; use rustc_feature::template; +use rustc_hir::attrs::{ + AttributeKind, CfgEntry, CfgHideShow, CfgInfo, DocAttribute, DocInline, HideOrShow, +}; +use rustc_hir::lints::AttributeLintKind; use rustc_span::{Span, Symbol, edition, sym}; +use thin_vec::ThinVec; +use super::prelude::{Allow, AllowedTargets, MethodKind, Target}; use super::{AcceptMapping, AttributeParser}; use crate::context::{AcceptContext, FinalizeContext, Stage}; use crate::fluent_generated as fluent; use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, PathParser}; use crate::session_diagnostics::{ - DocAliasBadChar, DocAliasEmpty, DocAliasStartEnd, DocKeywordConflict, DocKeywordNotKeyword, + DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttributeNotAttribute, + DocKeywordConflict, DocKeywordNotKeyword, }; -#[derive(Default)] +fn check_keyword(cx: &mut AcceptContext<'_, '_, S>, keyword: Symbol, span: Span) -> bool { + // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we + // can remove the `SelfTy` case here, remove `sym::SelfTy`, and update the + // `#[doc(keyword = "SelfTy")` attribute in `library/std/src/keyword_docs.rs`. + if keyword.is_reserved(|| edition::LATEST_STABLE_EDITION) + || keyword.is_weak() + || keyword == sym::SelfTy + { + return true; + } + cx.emit_err(DocKeywordNotKeyword { span, keyword }); + false +} + +fn check_attribute( + cx: &mut AcceptContext<'_, '_, S>, + attribute: Symbol, + span: Span, +) -> bool { + // FIXME: This should support attributes with namespace like `diagnostic::do_not_recommend`. + if rustc_feature::BUILTIN_ATTRIBUTE_MAP.contains_key(&attribute) { + return true; + } + cx.emit_err(DocAttributeNotAttribute { span, attribute }); + false +} + +fn parse_keyword_and_attribute<'c, S, F>( + cx: &'c mut AcceptContext<'_, '_, S>, + path: &PathParser<'_>, + args: &ArgParser<'_>, + attr_value: &mut Option<(Symbol, Span)>, + callback: F, +) where + S: Stage, + F: FnOnce(&mut AcceptContext<'_, '_, S>, Symbol, Span) -> bool, +{ + let Some(nv) = args.name_value() else { + cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); + return; + }; + + let Some(value) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return; + }; + + if !callback(cx, value, nv.value_span) { + return; + } + + if attr_value.is_some() { + cx.duplicate_key(path.span(), path.word_sym().unwrap()); + return; + } + + *attr_value = Some((value, path.span())); +} + +#[derive(Debug)] +struct DocComment { + style: AttrStyle, + kind: CommentKind, + span: Span, + comment: Symbol, +} + +#[derive(Default, Debug)] pub(crate) struct DocParser { attribute: DocAttribute, + nb_doc_attrs: usize, + doc_comment: Option, } impl DocParser { @@ -28,8 +107,8 @@ impl DocParser { match path.word_sym() { Some(sym::no_crate_inject) => { - if !args.no_args() { - cx.expected_no_args(args.span().unwrap()); + if let Err(span) = args.no_args() { + cx.expected_no_args(span); return; } @@ -42,17 +121,20 @@ impl DocParser { } Some(sym::attr) => { let Some(list) = args.list() else { - cx.expected_list(args.span().unwrap_or(path.span())); + cx.expected_list(cx.attr_span); return; }; - self.attribute.test_attrs.push(todo!()); + // FIXME: convert list into a Vec of `AttributeKind`. + for _ in list.mixed() { + // self.attribute.test_attrs.push(AttributeKind::parse()); + } } - _ => { - cx.expected_specific_argument( - mip.span(), - [sym::no_crate_inject.as_str(), sym::attr.as_str()].to_vec(), - ); + Some(name) => { + cx.emit_lint(AttributeLintKind::DocTestUnknown { name }, path.span()); + } + None => { + cx.emit_lint(AttributeLintKind::DocTestLiteral, path.span()); } } } @@ -98,7 +180,7 @@ impl DocParser { ) { match args { ArgParser::NoArgs => { - cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); + cx.emit_err(DocAliasMalformed { span: args.span().unwrap_or(path.span()) }); } ArgParser::List(list) => { for i in list.mixed() { @@ -120,41 +202,6 @@ impl DocParser { } } - fn parse_keyword<'c, S: Stage>( - &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - path: &PathParser<'_>, - args: &ArgParser<'_>, - ) { - let Some(nv) = args.name_value() else { - cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); - return; - }; - - let Some(keyword) = nv.value_as_str() else { - cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); - return; - }; - - fn is_doc_keyword(s: Symbol) -> bool { - // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we - // can remove the `SelfTy` case here, remove `sym::SelfTy`, and update the - // `#[doc(keyword = "SelfTy")` attribute in `library/std/src/keyword_docs.rs`. - s.is_reserved(|| edition::LATEST_STABLE_EDITION) || s.is_weak() || s == sym::SelfTy - } - - if !is_doc_keyword(keyword) { - cx.emit_err(DocKeywordNotKeyword { span: nv.value_span, keyword }); - } - - if self.attribute.keyword.is_some() { - cx.duplicate_key(path.span(), path.word_sym().unwrap()); - return; - } - - self.attribute.keyword = Some((keyword, path.span())); - } - fn parse_inline<'c, S: Stage>( &mut self, cx: &'c mut AcceptContext<'_, '_, S>, @@ -162,8 +209,8 @@ impl DocParser { args: &ArgParser<'_>, inline: DocInline, ) { - if !args.no_args() { - cx.expected_no_args(args.span().unwrap()); + if let Err(span) = args.no_args() { + cx.expected_no_args(span); return; } @@ -182,6 +229,103 @@ impl DocParser { self.attribute.inline = Some((inline, span)); } + fn parse_cfg<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + args: &ArgParser<'_>, + ) { + if let Some(cfg_entry) = super::cfg::parse_cfg(cx, args) { + self.attribute.cfg = Some(cfg_entry); + } + } + + fn parse_auto_cfg<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + path: &PathParser<'_>, + args: &ArgParser<'_>, + ) { + match args { + ArgParser::NoArgs => { + cx.expected_list(args.span().unwrap_or(path.span())); + } + ArgParser::List(list) => { + for meta in list.mixed() { + let MetaItemOrLitParser::MetaItemParser(item) = meta else { + cx.emit_lint(AttributeLintKind::DocAutoCfgExpectsHideOrShow, meta.span()); + continue; + }; + let (kind, attr_name) = match item.path().word_sym() { + Some(sym::hide) => (HideOrShow::Hide, sym::hide), + Some(sym::show) => (HideOrShow::Show, sym::show), + _ => { + cx.emit_lint( + AttributeLintKind::DocAutoCfgExpectsHideOrShow, + item.span(), + ); + continue; + } + }; + let ArgParser::List(list) = item.args() else { + cx.emit_lint( + AttributeLintKind::DocAutoCfgHideShowExpectsList { attr_name }, + item.span(), + ); + continue; + }; + + let mut cfg_hide_show = CfgHideShow { kind, values: ThinVec::new() }; + + for item in list.mixed() { + let MetaItemOrLitParser::MetaItemParser(sub_item) = item else { + cx.emit_lint( + AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name }, + item.span(), + ); + continue; + }; + match sub_item.args() { + a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => { + let Some(name) = sub_item.path().word_sym() else { + cx.expected_identifier(sub_item.path().span()); + continue; + }; + if let Ok(CfgEntry::NameValue { name, name_span, value, .. }) = + super::cfg::parse_name_value( + name, + sub_item.path().span(), + a.name_value(), + sub_item.span(), + cx, + ) + { + cfg_hide_show.values.push(CfgInfo { name, name_span, value }) + } + } + _ => { + cx.emit_lint( + AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { + attr_name, + }, + sub_item.span(), + ); + continue; + } + } + } + } + } + ArgParser::NameValue(nv) => { + let MetaItemLit { kind: LitKind::Bool(bool_value), span, .. } = nv.value_as_lit() + else { + cx.emit_lint(AttributeLintKind::DocAutoCfgWrongLiteral, nv.value_span); + return; + }; + self.attribute.auto_cfg_change = Some((*bool_value, *span)); + } + } + } + fn parse_single_doc_attr_item<'c, S: Stage>( &mut self, cx: &'c mut AcceptContext<'_, '_, S>, @@ -192,8 +336,8 @@ impl DocParser { macro_rules! no_args { ($ident: ident) => {{ - if !args.no_args() { - cx.expected_no_args(args.span().unwrap()); + if let Err(span) = args.no_args() { + cx.expected_no_args(span); return; } @@ -217,10 +361,12 @@ impl DocParser { return; }; - if self.attribute.$ident.is_some() { - cx.duplicate_key(path.span(), path.word_sym().unwrap()); - return; - } + // FIXME: It's errorring when the attribute is passed multiple times on the command + // line. + // if self.attribute.$ident.is_some() { + // cx.duplicate_key(path.span(), path.word_sym().unwrap()); + // return; + // } self.attribute.$ident = Some((s, path.span())); }}; @@ -238,16 +384,32 @@ impl DocParser { Some(sym::inline) => self.parse_inline(cx, path, args, DocInline::Inline), Some(sym::no_inline) => self.parse_inline(cx, path, args, DocInline::NoInline), Some(sym::masked) => no_args!(masked), - Some(sym::cfg) => no_args!(cfg), - Some(sym::cfg_hide) => no_args!(cfg_hide), + Some(sym::cfg) => self.parse_cfg(cx, args), Some(sym::notable_trait) => no_args!(notable_trait), - Some(sym::keyword) => self.parse_keyword(cx, path, args), + Some(sym::keyword) => parse_keyword_and_attribute( + cx, + path, + args, + &mut self.attribute.keyword, + check_keyword, + ), + Some(sym::attribute) => parse_keyword_and_attribute( + cx, + path, + args, + &mut self.attribute.attribute, + check_attribute, + ), Some(sym::fake_variadic) => no_args!(fake_variadic), Some(sym::search_unbox) => no_args!(search_unbox), Some(sym::rust_logo) => no_args!(rust_logo), + Some(sym::auto_cfg) => self.parse_auto_cfg(cx, path, args), Some(sym::test) => { let Some(list) = args.list() else { - cx.expected_list(args.span().unwrap_or(path.span())); + cx.emit_lint( + AttributeLintKind::DocTestTakesList, + args.span().unwrap_or(path.span()), + ); return; }; @@ -264,80 +426,32 @@ impl DocParser { } } } - - // let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path); - // if i_meta.has_name(sym::spotlight) { - // self.tcx.emit_node_span_lint( - // INVALID_DOC_ATTRIBUTES, - // hir_id, - // i_meta.span, - // errors::DocTestUnknownSpotlight { path, span: i_meta.span }, - // ); - // } else if i_meta.has_name(sym::include) - // && let Some(value) = i_meta.value_str() - // { - // let applicability = if list.len() == 1 { - // Applicability::MachineApplicable - // } else { - // Applicability::MaybeIncorrect - // }; - // // If there are multiple attributes, the suggestion would suggest - // // deleting all of them, which is incorrect. - // self.tcx.emit_node_span_lint( - // INVALID_DOC_ATTRIBUTES, - // hir_id, - // i_meta.span, - // errors::DocTestUnknownInclude { - // path, - // value: value.to_string(), - // inner: match attr.style() { - // AttrStyle::Inner => "!", - // AttrStyle::Outer => "", - // }, - // sugg: (attr.span(), applicability), - // }, - // ); - // } else if i_meta.has_name(sym::passes) || i_meta.has_name(sym::no_default_passes) { - // self.tcx.emit_node_span_lint( - // INVALID_DOC_ATTRIBUTES, - // hir_id, - // i_meta.span, - // errors::DocTestUnknownPasses { path, span: i_meta.span }, - // ); - // } else if i_meta.has_name(sym::plugins) { - // self.tcx.emit_node_span_lint( - // INVALID_DOC_ATTRIBUTES, - // hir_id, - // i_meta.span, - // errors::DocTestUnknownPlugins { path, span: i_meta.span }, - // ); - // } else { - // self.tcx.emit_node_span_lint( - // INVALID_DOC_ATTRIBUTES, - // hir_id, - // i_meta.span, - // errors::DocTestUnknownAny { path }, - // ); - // } } - _ => { - cx.expected_specific_argument( - mip.span(), - [ - sym::alias.as_str(), - sym::hidden.as_str(), - sym::html_favicon_url.as_str(), - sym::html_logo_url.as_str(), - sym::html_no_source.as_str(), - sym::html_playground_url.as_str(), - sym::html_root_url.as_str(), - sym::inline.as_str(), - sym::no_inline.as_str(), - sym::test.as_str(), - ] - .to_vec(), + Some(sym::spotlight) => { + cx.emit_lint(AttributeLintKind::DocUnknownSpotlight, path.span()); + } + Some(sym::include) if let Some(nv) = args.name_value() => { + let inner = match cx.attr_style { + AttrStyle::Outer => "", + AttrStyle::Inner => "!", + }; + cx.emit_lint( + AttributeLintKind::DocUnknownInclude { inner, value: nv.value_as_lit().symbol }, + path.span(), ); } + Some(name @ (sym::passes | sym::no_default_passes)) => { + cx.emit_lint(AttributeLintKind::DocUnknownPasses { name }, path.span()); + } + Some(sym::plugins) => { + cx.emit_lint(AttributeLintKind::DocUnknownPlugins, path.span()); + } + Some(name) => { + cx.emit_lint(AttributeLintKind::DocUnknownAny { name }, path.span()); + } + None => { + // FIXME: is there anything to do in this case? + } } } @@ -354,17 +468,30 @@ impl DocParser { for i in items.mixed() { match i { MetaItemOrLitParser::MetaItemParser(mip) => { + self.nb_doc_attrs += 1; self.parse_single_doc_attr_item(cx, mip); } - MetaItemOrLitParser::Lit(lit) => todo!("error should've used equals"), + MetaItemOrLitParser::Lit(lit) => { + cx.expected_name_value(lit.span, None); + } MetaItemOrLitParser::Err(..) => { // already had an error here, move on. } } } } - ArgParser::NameValue(v) => { - panic!("this should be rare if at all possible"); + ArgParser::NameValue(nv) => { + let Some(comment) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return; + }; + + self.doc_comment = Some(DocComment { + style: cx.attr_style, + kind: CommentKind::Block, + span: nv.value_span, + comment, + }); } } } @@ -373,13 +500,49 @@ impl DocParser { impl AttributeParser for DocParser { const ATTRIBUTES: AcceptMapping = &[( &[sym::doc], - template!(List: "hidden|inline|...", NameValueStr: "string"), + template!(List: &["hidden", "inline", "test"], NameValueStr: "string"), |this, cx, args| { this.accept_single_doc_attr(cx, args); }, )]; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::ExternCrate), + Allow(Target::Use), + Allow(Target::Static), + Allow(Target::Const), + Allow(Target::Fn), + Allow(Target::Mod), + Allow(Target::ForeignMod), + Allow(Target::TyAlias), + Allow(Target::Enum), + Allow(Target::Variant), + Allow(Target::Struct), + Allow(Target::Field), + Allow(Target::Union), + Allow(Target::Trait), + Allow(Target::TraitAlias), + Allow(Target::Impl { of_trait: true }), + Allow(Target::Impl { of_trait: false }), + Allow(Target::AssocConst), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::AssocTy), + Allow(Target::ForeignFn), + Allow(Target::ForeignStatic), + Allow(Target::ForeignTy), + Allow(Target::MacroDef), + Allow(Target::Crate), + ]); - fn finalize(self, cx: &FinalizeContext<'_, '_, S>) -> Option { - todo!() + fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { + if let Some(DocComment { style, kind, span, comment }) = self.doc_comment { + Some(AttributeKind::DocComment { style, kind, span, comment }) + } else if self.nb_doc_attrs != 0 { + Some(AttributeKind::Doc(Box::new(self.attribute))) + } else { + None + } } } diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 584f62ca51a3..64bcb02b0b74 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -39,8 +39,8 @@ pub(crate) mod confusables; pub(crate) mod crate_level; pub(crate) mod debugger; pub(crate) mod deprecation; -pub(crate) mod dummy; pub(crate) mod doc; +pub(crate) mod dummy; pub(crate) mod inline; pub(crate) mod link_attrs; pub(crate) mod lint_helpers; diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs index ce555be6a47d..105f7164bf3b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/util.rs +++ b/compiler/rustc_attr_parsing/src/attributes/util.rs @@ -5,7 +5,7 @@ use rustc_ast::attr::AttributeExt; use rustc_feature::is_builtin_attr_name; use rustc_hir::RustcVersion; use rustc_hir::limit::Limit; -use rustc_span::{Symbol, sym}; +use rustc_span::Symbol; use crate::context::{AcceptContext, Stage}; use crate::parser::{ArgParser, NameValueParser}; @@ -32,7 +32,6 @@ pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) } - /// Parse a single integer. /// /// Used by attributes that take a single integer as argument, such as @@ -92,7 +91,3 @@ impl AcceptContext<'_, '_, S> { None } } - -pub fn find_crate_name(attrs: &[impl AttributeExt]) -> Option { - first_attr_value_str_by_name(attrs, sym::crate_name) -} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index af73bf7f9fd2..5d15588033fd 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -163,6 +163,8 @@ attribute_parsers!( BodyStabilityParser, ConfusablesParser, ConstStabilityParser, + DocParser, + MacroUseParser, NakedParser, StabilityParser, diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index b26a4a29cd2e..363e1fcac507 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -298,17 +298,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { comment: *symbol, })) } - // // FIXME: make doc attributes go through a proper attribute parser - // ast::AttrKind::Normal(n) if n.has_name(sym::doc) => { - // let p = GenericMetaItemParser::from_attr(&n, self.dcx()); - // - // attributes.push(Attribute::Parsed(AttributeKind::DocComment { - // style: attr.style, - // kind: CommentKind::Line, - // span: attr.span, - // comment: p.args().name_value(), - // })) - // } ast::AttrKind::Normal(n) => { attr_paths.push(PathParser(Cow::Borrowed(&n.item.path))); let attr_path = AttrPath::from_ast(&n.item.path, lower_span); diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 7cef70f88e1c..37a3189f892e 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -80,6 +80,7 @@ #![feature(decl_macro)] #![recursion_limit = "256"] // tidy-alphabetical-end +#![feature(if_let_guard)] #[macro_use] /// All the individual attribute parsers for each of rustc's built-in attributes. @@ -107,7 +108,7 @@ pub use attributes::cfg::{ }; pub use attributes::cfg_old::*; pub use attributes::cfg_select::*; -pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version}; +pub use attributes::util::{is_builtin_attr, parse_version}; pub use context::{Early, Late, OmitDoc, ShouldEmit}; pub use interface::AttributeParser; pub use session_diagnostics::ParsedDescription; diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index f122b5a87549..26b615448e3b 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -69,6 +69,15 @@ pub(crate) struct DocKeywordNotKeyword { pub keyword: Symbol, } +#[derive(Diagnostic)] +#[diag(attr_parsing_doc_attribute_not_attribute)] +#[help] +pub(crate) struct DocAttributeNotAttribute { + #[primary_span] + pub span: Span, + pub attribute: Symbol, +} + /// Error code: E0541 pub(crate) struct UnknownMetaItem<'a> { pub span: Span, @@ -588,23 +597,6 @@ pub(crate) struct DocKeywordConflict { pub spans: MultiSpan, } - #[derive(Subdiagnostic)] - pub(crate) enum UnusedNote { - #[note(attr_parsing_unused_empty_lints_note)] - EmptyList { name: Symbol }, - #[note(attr_parsing_unused_no_lints_note)] - NoLints { name: Symbol }, - } - - #[derive(LintDiagnostic)] - #[diag(attr_parsing_unused)] - pub(crate) struct Unused { - #[suggestion(code = "", applicability = "machine-applicable")] - pub attr_span: Span, - #[subdiagnostic] - pub note: UnusedNote, - } - #[derive(Diagnostic)] #[diag(attr_parsing_link_ordinal_out_of_range)] #[note] @@ -1011,3 +1003,91 @@ pub(crate) struct CfgAttrBadDelim { #[subdiagnostic] pub sugg: MetaBadDelimSugg, } + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_auto_cfg_expects_hide_or_show)] +pub(crate) struct DocAutoCfgExpectsHideOrShow; + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_auto_cfg_hide_show_unexpected_item)] +pub(crate) struct DocAutoCfgHideShowUnexpectedItem { + pub attr_name: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_auto_cfg_hide_show_expects_list)] +pub(crate) struct DocAutoCfgHideShowExpectsList { + pub attr_name: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_invalid)] +pub(crate) struct DocInvalid; + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_unknown_include)] +pub(crate) struct DocUnknownInclude { + pub inner: &'static str, + pub value: Symbol, + #[suggestion(code = "#{inner}[doc = include_str!(\"{value}\")]")] + pub sugg: (Span, Applicability), +} + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_unknown_spotlight)] +#[note] +#[note(attr_parsing_no_op_note)] +pub(crate) struct DocUnknownSpotlight { + #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")] + pub sugg_span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_unknown_passes)] +#[note] +#[note(attr_parsing_no_op_note)] +pub(crate) struct DocUnknownPasses { + pub name: Symbol, + #[label] + pub note_span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_unknown_plugins)] +#[note] +#[note(attr_parsing_no_op_note)] +pub(crate) struct DocUnknownPlugins { + #[label] + pub label_span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_unknown_any)] +pub(crate) struct DocUnknownAny { + pub name: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_auto_cfg_wrong_literal)] +pub(crate) struct DocAutoCfgWrongLiteral; + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_test_takes_list)] +pub(crate) struct DocTestTakesList; + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_test_unknown)] +pub(crate) struct DocTestUnknown { + pub name: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(attr_parsing_doc_test_literal)] +pub(crate) struct DocTestLiteral; + +#[derive(Diagnostic)] +#[diag(attr_parsing_doc_alias_malformed)] +pub(crate) struct DocAliasMalformed { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 538c866567a9..39008914f9ef 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -428,6 +428,26 @@ pub enum DocInline { NoInline, } +#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub enum HideOrShow { + Hide, + Show, +} + +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub struct CfgInfo { + pub name: Symbol, + pub name_span: Span, + pub value: Option<(Symbol, Span)>, +} + +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub struct CfgHideShow { + pub kind: HideOrShow, + pub values: ThinVec, +} + #[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] pub struct DocAttribute { pub aliases: FxIndexMap, @@ -435,12 +455,15 @@ pub struct DocAttribute { pub inline: Option<(DocInline, Span)>, // unstable - pub cfg: Option, - pub cfg_hide: Option, + pub cfg: Option, + pub auto_cfg: ThinVec, + /// This is for `#[doc(auto_cfg = false|true)]`. + pub auto_cfg_change: Option<(bool, Span)>, // builtin pub fake_variadic: Option, pub keyword: Option<(Symbol, Span)>, + pub attribute: Option<(Symbol, Span)>, pub masked: Option, pub notable_trait: Option, pub search_unbox: Option, @@ -455,7 +478,7 @@ pub struct DocAttribute { pub rust_logo: Option, // #[doc(test(...))] - pub test_attrs: ThinVec<()>, + pub test_attrs: ThinVec, pub no_crate_inject: Option, } @@ -466,9 +489,11 @@ impl Default for DocAttribute { hidden: None, inline: None, cfg: None, - cfg_hide: None, + auto_cfg: ThinVec::new(), + auto_cfg_change: None, fake_variadic: None, keyword: None, + attribute: None, masked: None, notable_trait: None, search_unbox: None, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e8a91dae0749..e6a0f430b63a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1414,6 +1414,10 @@ impl AttributeExt for Attribute { ) ) } + + fn is_doc_hidden(&self) -> bool { + matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some()) + } } // FIXME(fn_delegation): use function delegation instead of manually forwarding diff --git a/compiler/rustc_hir/src/lints.rs b/compiler/rustc_hir/src/lints.rs index abffb9437a51..2d13ceabf8ca 100644 --- a/compiler/rustc_hir/src/lints.rs +++ b/compiler/rustc_hir/src/lints.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fingerprint::Fingerprint; pub use rustc_lint_defs::AttributeLintKind; use rustc_lint_defs::LintId; use rustc_macros::HashStable_Generic; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use crate::HirId; @@ -72,4 +72,30 @@ pub enum AttributeLintKind { DuplicateDocAlias { first_definition: Span, }, + DocAutoCfgExpectsHideOrShow, + DocAutoCfgHideShowUnexpectedItem { + attr_name: Symbol, + }, + DocAutoCfgHideShowExpectsList { + attr_name: Symbol, + }, + DocInvalid, + DocUnknownInclude { + inner: &'static str, + value: Symbol, + }, + DocUnknownSpotlight, + DocUnknownPasses { + name: Symbol, + }, + DocUnknownPlugins, + DocUnknownAny { + name: Symbol, + }, + DocAutoCfgWrongLiteral, + DocTestTakesList, + DocTestUnknown { + name: Symbol, + }, + DocTestLiteral, } diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index f00125c3e090..246134665174 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 734d8963d6fd..d3ef1d63e8ba 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -1,6 +1,4 @@ // tidy-alphabetical-start -#![allow(rustc::diagnostic_outside_of_impl)] -#![allow(rustc::untranslatable_diagnostic)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index e4e892ab10f4..1a25f6a582f2 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -3,12 +3,12 @@ use std::cell::{Cell, RefCell}; use std::cmp::max; use std::ops::Deref; -use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; use rustc_errors::Applicability; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::DefKind; -use rustc_hir::{self as hir, ExprKind, HirId, Node}; +use rustc_hir::{self as hir, ExprKind, HirId, Node, find_attr}; use rustc_hir_analysis::autoderef::{self, Autoderef}; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt}; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 0805ef47079b..ae973a3c49c2 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -825,7 +825,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: & let span = sugared_span.take().unwrap_or(attr.span); - if is_doc_comment || attr.has_name(sym::doc) { + if is_doc_comment { let sub = match attr.kind { AttrKind::DocComment(CommentKind::Line, _) | AttrKind::Normal(..) => { BuiltinUnusedDocCommentSub::PlainHelp diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index ac47897b5688..0f6452a2bc99 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -657,11 +657,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { } // `#[doc(hidden)]` disables missing_docs check. - if attr.has_name(sym::doc) - && attr - .meta_item_list() - .is_some_and(|l| ast::attr::list_contains_name(&l, sym::hidden)) - { + if attr.is_doc_hidden() { self.insert( LintId::of(MISSING_DOCS), LevelAndSource { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 86719581a209..9a1cf7f349fd 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -870,25 +870,20 @@ fn analyze_attr(attr: &hir::Attribute, state: &mut AnalyzeAttrState<'_>) -> bool && !rustc_feature::encode_cross_crate(name) { // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates. - } else if attr.doc_str().is_some() { + } else if let hir::Attribute::Parsed(AttributeKind::DocComment { .. }) = attr { // We keep all doc comments reachable to rustdoc because they might be "imported" into // downstream crates if they use `#[doc(inline)]` to copy an item's documentation into // their own. if state.is_exported { should_encode = true; } - } else if attr.has_name(sym::doc) { + } else if let hir::Attribute::Parsed(AttributeKind::Doc(d)) = attr { // If this is a `doc` attribute that doesn't have anything except maybe `inline` (as in // `#[doc(inline)]`), then we can remove it. It won't be inlinable in downstream crates. - if let Some(item_list) = attr.meta_item_list() { - for item in item_list { - if !item.has_name(sym::inline) { - should_encode = true; - if item.has_name(sym::hidden) { - state.is_doc_hidden = true; - break; - } - } + if d.inline.is_none() { + should_encode = true; + if d.hidden.is_some() { + state.is_doc_hidden = true; } } } else if let &[sym::diagnostic, seg] = &*attr.path() { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 782ea3906ef1..fc03ad52b4bf 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -4,12 +4,14 @@ use std::{fmt, iter}; use rustc_abi::{Float, Integer, IntegerType, Size}; use rustc_apfloat::Float as _; +use rustc_ast::attr::AttributeExt; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorGuaranteed; use rustc_hashes::Hash128; use rustc_hir as hir; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_hir::limit::Limit; @@ -1664,16 +1666,14 @@ pub fn reveal_opaque_types_in_bounds<'tcx>( /// Determines whether an item is directly annotated with `doc(hidden)`. fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - tcx.get_attrs(def_id, sym::doc) - .filter_map(|attr| attr.meta_item_list()) - .any(|items| items.iter().any(|item| item.has_name(sym::hidden))) + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); + attrs.iter().any(|attr| attr.is_doc_hidden()) } /// Determines whether an item is annotated with `doc(notable_trait)`. pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - tcx.get_attrs(def_id, sym::doc) - .filter_map(|attr| attr.meta_item_list()) - .any(|items| items.iter().any(|item| item.has_name(sym::notable_trait))) + let attrs = tcx.get_all_attrs(def_id); + attrs.iter().any(|attr| matches!(attr, hir::Attribute::Parsed(AttributeKind::Doc(doc)) if doc.notable_trait.is_some())) } /// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute). diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index ba81ef3103bd..10da57f56ecf 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_lowering = { path = "../rustc_ast_lowering" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 93cd9a9702f7..007ce22c01e6 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -107,39 +107,14 @@ passes_diagnostic_item_first_defined = the diagnostic item is first defined here passes_doc_alias_bad_location = - {$attr_str} isn't allowed on {$location} - -passes_doc_alias_malformed = - doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` + doc alias attribute isn't allowed on {$location} passes_doc_alias_not_an_alias = {$attr_str} is the same as the item's name -passes_doc_alias_not_string_literal = - `#[doc(alias("a"))]` expects string literals - passes_doc_attr_not_crate_level = `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute -passes_doc_attribute_not_attribute = - nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]` - .help = only existing builtin attributes are allowed in core/std - -passes_doc_auto_cfg_expects_hide_or_show = - only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` - -passes_doc_auto_cfg_hide_show_expects_list = - `#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items - -passes_doc_auto_cfg_hide_show_unexpected_item = - `#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items - -passes_doc_auto_cfg_wrong_literal = - expected boolean for `#[doc(auto_cfg = ...)]` - -passes_doc_expect_str = - doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")] - passes_doc_fake_variadic_not_valid = `#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity @@ -151,9 +126,6 @@ passes_doc_inline_only_use = .not_a_use_item_label = not a `use` item .note = read for more information -passes_doc_invalid = - invalid `doc` attribute - passes_doc_keyword_attribute_empty_mod = `#[doc({$attr_name} = "...")]` should be used on empty modules @@ -180,39 +152,6 @@ passes_doc_rust_logo = passes_doc_search_unbox_invalid = `#[doc(search_unbox)]` should be used on generic structs and enums -passes_doc_test_literal = `#![doc(test(...)]` does not take a literal - -passes_doc_test_takes_list = - `#[doc(test(...)]` takes a list of attributes - -passes_doc_test_unknown = - unknown `doc(test)` attribute `{$path}` - -passes_doc_test_unknown_any = - unknown `doc` attribute `{$path}` - -passes_doc_test_unknown_include = - unknown `doc` attribute `{$path}` - .suggestion = use `doc = include_str!` instead - -passes_doc_test_unknown_passes = - unknown `doc` attribute `{$path}` - .note = `doc` attribute `{$path}` no longer functions; see issue #44136 - .label = no longer functions - .no_op_note = `doc({$path})` is now a no-op - -passes_doc_test_unknown_plugins = - unknown `doc` attribute `{$path}` - .note = `doc` attribute `{$path}` no longer functions; see issue #44136 and CVE-2018-1000622 - .label = no longer functions - .no_op_note = `doc({$path})` is now a no-op - -passes_doc_test_unknown_spotlight = - unknown `doc` attribute `{$path}` - .note = `doc(spotlight)` was renamed to `doc(notable_trait)` - .suggestion = use `notable_trait` instead - .no_op_note = `doc(spotlight)` is now a no-op - passes_duplicate_diagnostic_item_in_crate = duplicate diagnostic item in crate `{$crate_name}`: `{$name}` .note = the diagnostic item is first defined in crate `{$orig_crate_name}` diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 1a48e4360d86..bae15de4bf88 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -10,22 +10,24 @@ use std::collections::hash_map::Entry; use std::slice; use rustc_abi::{Align, ExternAbi, Size}; -use rustc_ast::{AttrStyle, LitKind, MetaItem, MetaItemInner, MetaItemKind, ast}; +use rustc_ast::{AttrStyle, LitKind, MetaItemKind, ast}; use rustc_attr_parsing::{AttributeParser, Late}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; +use rustc_errors::{DiagCtxtHandle, IntoDiagArg, StashKey}; use rustc_feature::{ ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, }; -use rustc_hir::attrs::{AttributeKind, InlineAttr, MirDialect, MirPhase, ReprAttr, SanitizerSet}; +use rustc_hir::attrs::{ + AttributeKind, DocAttribute, InlineAttr, MirDialect, MirPhase, ReprAttr, SanitizerSet, +}; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ - self as hir, Attribute, CRATE_HIR_ID, CRATE_OWNER_ID, Constness, FnSig, ForeignItem, HirId, - Item, ItemKind, MethodKind, PartialConstStability, Safety, Stability, StabilityLevel, Target, - TraitItem, find_attr, + self as hir, Attribute, CRATE_HIR_ID, Constness, FnSig, ForeignItem, HirId, Item, ItemKind, + MethodKind, PartialConstStability, Safety, Stability, StabilityLevel, Target, TraitItem, + find_attr, }; use rustc_macros::LintDiagnostic; use rustc_middle::hir::nested_filter; @@ -43,7 +45,7 @@ use rustc_session::lint::builtin::{ }; use rustc_session::parse::feature_err; use rustc_span::edition::Edition; -use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, sym}; +use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; use rustc_trait_selection::traits::ObligationCtxt; @@ -106,21 +108,6 @@ impl IntoDiagArg for ProcMacroKind { } } -#[derive(Clone, Copy)] -enum DocFakeItemKind { - Attribute, - Keyword, -} - -impl DocFakeItemKind { - fn name(self) -> &'static str { - match self { - Self::Attribute => "attribute", - Self::Keyword => "keyword", - } - } -} - struct CheckAttrVisitor<'tcx> { tcx: TyCtxt<'tcx>, @@ -223,6 +210,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::MacroExport { span, .. }) => { self.check_macro_export(hir_id, *span, target) }, + Attribute::Parsed(AttributeKind::Doc(attr)) => self.check_doc_attrs(attr, hir_id, target), Attribute::Parsed( AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect @@ -771,13 +759,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn doc_attr_str_error(&self, meta: &MetaItemInner, attr_name: &str) { - self.dcx().emit_err(errors::DocExpectStr { attr_span: meta.span(), attr_name }); - } - - fn check_doc_alias_value(&self, span: Span, alias: Symbol, hir_id: HirId, target: Target) { - let tcx = self.tcx; - + fn check_doc_alias_value(&self, span: Span, hir_id: HirId, target: Target, alias: Symbol) { if let Some(location) = match target { Target::AssocTy => { if let DefKind::Impl { .. } = @@ -834,96 +816,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | Target::MacroCall | Target::Delegation { .. } => None, } { - // FIXME: emit proper error - // tcx.dcx().emit_err(errors::DocAliasBadLocation { - // span, - // errors::DocAliasDuplicated { first_defn: *entry.entry.get() }, - // ); + self.tcx.dcx().emit_err(errors::DocAliasBadLocation { span, location }); + return; } - } - - fn check_doc_alias( - &self, - meta: &MetaItemInner, - hir_id: HirId, - target: Target, - aliases: &mut FxHashMap, - ) { - if let Some(values) = meta.meta_item_list() { - for v in values { - match v.lit() { - Some(l) => match l.kind { - LitKind::Str(s, _) => { - self.check_doc_alias_value(v, s, hir_id, target, true, aliases); - } - _ => { - self.tcx - .dcx() - .emit_err(errors::DocAliasNotStringLiteral { span: v.span() }); - } - }, - None => { - self.tcx - .dcx() - .emit_err(errors::DocAliasNotStringLiteral { span: v.span() }); - } - } - } - } else if let Some(doc_alias) = meta.value_str() { - self.check_doc_alias_value(meta, doc_alias, hir_id, target, false, aliases) - } else { - self.dcx().emit_err(errors::DocAliasMalformed { span: meta.span() }); - } - } - - fn check_doc_keyword_and_attribute( - &self, - span: Span, - hir_id: HirId, - attr_kind: DocFakeItemKind, - ) { - fn is_doc_keyword(s: Symbol) -> bool { - // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we - // can remove the `SelfTy` case here, remove `sym::SelfTy`, and update the - // `#[doc(keyword = "SelfTy")` attribute in `library/std/src/keyword_docs.rs`. - s.is_reserved(|| edition::LATEST_STABLE_EDITION) || s.is_weak() || s == sym::SelfTy - } - - let item_kind = match self.tcx.hir_node(hir_id) { - hir::Node::Item(item) => Some(&item.kind), - _ => None, - }; - match item_kind { - Some(ItemKind::Mod(_, module)) => { - if !module.item_ids.is_empty() { - self.dcx() - .emit_err(errors::DocKeywordEmptyMod { span, attr_name: attr_kind.name() }); - return; - } - } - _ => { - self.dcx().emit_err(errors::DocKeywordNotMod { span, attr_name: attr_kind.name() }); - return; - } - } - - match attr_kind { - DocFakeItemKind::Keyword => { - if !is_doc_keyword(value) { - self.dcx().emit_err(errors::DocKeywordNotKeyword { - span: meta.name_value_literal_span().unwrap_or_else(|| meta.span()), - keyword: value, - }); - } - } - DocFakeItemKind::Attribute => { - if !is_builtin_attr(value) { - self.dcx().emit_err(errors::DocAttributeNotAttribute { - span: meta.name_value_literal_span().unwrap_or_else(|| meta.span()), - attribute: value, - }); - } - } + if self.tcx.hir_opt_name(hir_id) == Some(alias) { + self.tcx.dcx().emit_err(errors::DocAliasNotAnAlias { span, attr_str: alias }); + return; } } @@ -1027,6 +925,25 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } + fn check_doc_keyword_and_attribute(&self, span: Span, hir_id: HirId, attr_name: &'static str) { + let item_kind = match self.tcx.hir_node(hir_id) { + hir::Node::Item(item) => Some(&item.kind), + _ => None, + }; + match item_kind { + Some(ItemKind::Mod(_, module)) => { + if !module.item_ids.is_empty() { + self.dcx().emit_err(errors::DocKeywordAttributeEmptyMod { span, attr_name }); + return; + } + } + _ => { + self.dcx().emit_err(errors::DocKeywordAttributeNotMod { span, attr_name }); + return; + } + } + } + /// Checks that an attribute is *not* used at the crate level. Returns `true` if valid. fn check_attr_not_crate_level(&self, span: Span, hir_id: HirId, attr_name: &str) -> bool { if CRATE_HIR_ID == hir_id { @@ -1050,62 +967,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { true } - /// Check that the `#![doc(auto_cfg)]` attribute has the expected input. - fn check_doc_auto_cfg(&self, meta: &MetaItem, hir_id: HirId) { - match &meta.kind { - MetaItemKind::Word => {} - MetaItemKind::NameValue(lit) => { - if !matches!(lit.kind, LitKind::Bool(_)) { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span, - errors::DocAutoCfgWrongLiteral, - ); - } - } - MetaItemKind::List(list) => { - for item in list { - let Some(attr_name @ (sym::hide | sym::show)) = item.name() else { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span, - errors::DocAutoCfgExpectsHideOrShow, - ); - continue; - }; - if let Some(list) = item.meta_item_list() { - for item in list { - let valid = item.meta_item().is_some_and(|meta| { - meta.path.segments.len() == 1 - && matches!( - &meta.kind, - MetaItemKind::Word | MetaItemKind::NameValue(_) - ) - }); - if !valid { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - item.span(), - errors::DocAutoCfgHideShowUnexpectedItem { attr_name }, - ); - } - } - } else { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span, - errors::DocAutoCfgHideShowExpectsList { attr_name }, - ); - } - } - } - } - } - /// Runs various checks on `#[doc]` attributes. /// /// `specified_inline` should be initialized to `None` and kept for the scope @@ -1121,7 +982,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { inline, // FIXME: currently unchecked cfg: _, - cfg_hide, + // already check in attr_parsing + auto_cfg: _, + // already check in attr_parsing + auto_cfg_change: _, fake_variadic, keyword, masked, @@ -1138,36 +1002,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // allowed anywhere test_attrs: _, no_crate_inject, + attribute, } = attr; for (alias, span) in aliases { if self.check_attr_not_crate_level(*span, hir_id, "alias") { - self.check_doc_alias_value(*span, *alias, hir_id, target); + self.check_doc_alias_value(*span, hir_id, target, *alias); } } if let Some((_, span)) = keyword { - if self.check_attr_not_crate_level(*span, hir_id, "keyword") { - self.check_doc_keyword(*span, hir_id); - } + self.check_attr_not_crate_level(*span, hir_id, "keyword"); + self.check_doc_keyword_and_attribute(*span, hir_id, "keyword"); + } + if let Some((_, span)) = attribute { + self.check_attr_not_crate_level(*span, hir_id, "attribute"); + self.check_doc_keyword_and_attribute(*span, hir_id, "attribute"); } - - // FIXME: check doc attribute - // self.check_doc_keyword(meta, hir_id); - // self.check_doc_keyword_and_attribute( - // meta, - // hir_id, - // DocFakeItemKind::Keyword, - // ); - // } - // } - // Some(sym::attribute) => { - // if self.check_attr_not_crate_level(meta, hir_id, "attribute") { - // self.check_doc_keyword_and_attribute( - // meta, - // hir_id, - // DocFakeItemKind::Attribute, - // ); if let Some(span) = fake_variadic { if self.check_attr_not_crate_level(*span, hir_id, "fake_variadic") { @@ -1220,10 +1071,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Some(span) = masked { self.check_doc_masked(*span, hir_id, target); } - - if let Some(span) = cfg_hide { - self.check_attr_crate_level(*span, hir_id); - } } fn check_has_incoherent_inherent_impls(&self, attr: &Attribute, span: Span, target: Target) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 926aba5082de..b693aaf76923 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -24,12 +24,6 @@ pub(crate) struct IncorrectDoNotRecommendLocation; #[diag(passes_incorrect_do_not_recommend_args)] pub(crate) struct DoNotRecommendDoesNotExpectArgs; -#[derive(LintDiagnostic)] -#[diag(passes_doc_attr_expects_string)] -pub(crate) struct DocAttrExpectsString { - pub(crate) attr_name: Symbol, -} - #[derive(Diagnostic)] #[diag(passes_autodiff_attr)] pub(crate) struct AutoDiffAttr { @@ -129,43 +123,20 @@ pub(crate) struct AttrShouldBeAppliedToStatic { pub defn_span: Span, } -#[derive(Diagnostic)] -#[diag(passes_doc_expect_str)] -pub(crate) struct DocExpectStr<'a> { - #[primary_span] - pub attr_span: Span, - pub attr_name: &'a str, -} - #[derive(Diagnostic)] #[diag(passes_doc_alias_bad_location)] pub(crate) struct DocAliasBadLocation<'a> { #[primary_span] pub span: Span, - pub attr_str: &'a str, pub location: &'a str, } #[derive(Diagnostic)] #[diag(passes_doc_alias_not_an_alias)] -pub(crate) struct DocAliasNotAnAlias<'a> { - #[primary_span] - pub span: Span, - pub attr_str: &'a str, -} - -#[derive(Diagnostic)] -#[diag(passes_doc_alias_not_string_literal)] -pub(crate) struct DocAliasNotStringLiteral { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(passes_doc_alias_malformed)] -pub(crate) struct DocAliasMalformed { +pub(crate) struct DocAliasNotAnAlias { #[primary_span] pub span: Span, + pub attr_str: Symbol, } #[derive(Diagnostic)] @@ -176,24 +147,6 @@ pub(crate) struct DocKeywordAttributeEmptyMod { pub attr_name: &'static str, } -#[derive(Diagnostic)] -#[diag(passes_doc_keyword_not_keyword)] -#[help] -pub(crate) struct DocKeywordNotKeyword { - #[primary_span] - pub span: Span, - pub keyword: Symbol, -} - -#[derive(Diagnostic)] -#[diag(passes_doc_attribute_not_attribute)] -#[help] -pub(crate) struct DocAttributeNotAttribute { - #[primary_span] - pub span: Span, - pub attribute: Symbol, -} - #[derive(Diagnostic)] #[diag(passes_doc_keyword_attribute_not_mod)] pub(crate) struct DocKeywordAttributeNotMod { @@ -260,90 +213,6 @@ pub(crate) struct DocAttrNotCrateLevel<'a> { pub attr_name: &'a str, } -#[derive(LintDiagnostic)] -#[diag(passes_doc_test_unknown)] -pub(crate) struct DocTestUnknown { - pub path: String, -} - -#[derive(LintDiagnostic)] -#[diag(passes_doc_test_literal)] -pub(crate) struct DocTestLiteral; - -#[derive(LintDiagnostic)] -#[diag(passes_doc_test_takes_list)] -pub(crate) struct DocTestTakesList; - -#[derive(LintDiagnostic)] -#[diag(passes_doc_auto_cfg_wrong_literal)] -pub(crate) struct DocAutoCfgWrongLiteral; - -#[derive(LintDiagnostic)] -#[diag(passes_doc_auto_cfg_expects_hide_or_show)] -pub(crate) struct DocAutoCfgExpectsHideOrShow; - -#[derive(LintDiagnostic)] -#[diag(passes_doc_auto_cfg_hide_show_expects_list)] -pub(crate) struct DocAutoCfgHideShowExpectsList { - pub attr_name: Symbol, -} - -#[derive(LintDiagnostic)] -#[diag(passes_doc_auto_cfg_hide_show_unexpected_item)] -pub(crate) struct DocAutoCfgHideShowUnexpectedItem { - pub attr_name: Symbol, -} - -#[derive(LintDiagnostic)] -#[diag(passes_doc_test_unknown_any)] -pub(crate) struct DocTestUnknownAny { - pub path: String, -} - -#[derive(LintDiagnostic)] -#[diag(passes_doc_test_unknown_spotlight)] -#[note] -#[note(passes_no_op_note)] -pub(crate) struct DocTestUnknownSpotlight { - pub path: String, - #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")] - pub span: Span, -} - -#[derive(LintDiagnostic)] -#[diag(passes_doc_test_unknown_passes)] -#[note] -#[note(passes_no_op_note)] -pub(crate) struct DocTestUnknownPasses { - pub path: String, - #[label] - pub span: Span, -} - -#[derive(LintDiagnostic)] -#[diag(passes_doc_test_unknown_plugins)] -#[note] -#[note(passes_no_op_note)] -pub(crate) struct DocTestUnknownPlugins { - pub path: String, - #[label] - pub span: Span, -} - -#[derive(LintDiagnostic)] -#[diag(passes_doc_test_unknown_include)] -pub(crate) struct DocTestUnknownInclude { - pub path: String, - pub value: String, - pub inner: &'static str, - #[suggestion(code = "#{inner}[doc = include_str!(\"{value}\")]")] - pub sugg: (Span, Applicability), -} - -#[derive(LintDiagnostic)] -#[diag(passes_doc_invalid)] -pub(crate) struct DocInvalid; - #[derive(Diagnostic)] #[diag(passes_has_incoherent_inherent_impl)] pub(crate) struct HasIncoherentInherentImpl { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a18913c1c1c7..069944b638c7 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -10,7 +10,6 @@ use rustc_ast::{ Item, ItemKind, MethodCall, NodeId, Path, PathSegment, Ty, TyKind, }; use rustc_ast_pretty::pprust::where_bound_predicate_to_string; -use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{ @@ -18,6 +17,7 @@ use rustc_errors::{ struct_span_code_err, }; use rustc_hir as hir; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, MacroKinds}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; @@ -903,7 +903,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // confused by them. continue; } - if let Some(d) = find_attr!(r.tcx.get_all_attrs(did), AttributeKind::Doc(d) => d) + if let Some(d) = + hir::find_attr!(r.tcx.get_all_attrs(did), AttributeKind::Doc(d) => d) && d.aliases.contains_key(&item_name) { return Some(did); From 131323f91002ac5277c3ae05046757adb5c48965 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 25 Nov 2025 23:54:10 +0100 Subject: [PATCH 0508/3801] Migrate `doc(cfg)` to new `Attribute` API --- Cargo.lock | 1 + src/librustdoc/Cargo.toml | 1 + src/librustdoc/clean/cfg.rs | 494 +++++++++++-------- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 141 ++---- src/librustdoc/clean/types.rs | 79 ++- src/librustdoc/clean/utils.rs | 27 +- src/librustdoc/doctest.rs | 44 +- src/librustdoc/doctest/rust.rs | 61 ++- src/librustdoc/html/render/context.rs | 50 +- src/librustdoc/html/render/search_index.rs | 4 +- src/librustdoc/html/sources.rs | 6 +- src/librustdoc/lib.rs | 2 - src/librustdoc/passes/check_doc_cfg.rs | 100 ++-- src/librustdoc/passes/collect_trait_impls.rs | 22 +- src/librustdoc/passes/propagate_doc_cfg.rs | 64 +-- 16 files changed, 552 insertions(+), 546 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb81cada72ea..23708adcc499 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4870,6 +4870,7 @@ dependencies = [ "minifier", "pulldown-cmark-escape", "regex", + "rustc_proc_macro", "rustdoc-json-types", "serde", "serde_json", diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 0bc38220614f..371da896b9fc 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -18,6 +18,7 @@ minifier = { version = "0.3.5", default-features = false } pulldown-cmark-escape = { version = "0.11.0", features = ["simd"] } regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } +rustc_proc_macro = { path = "../../compiler/rustc_proc_macro" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" smallvec = "1.8.1" diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 6c77e41965dc..38d3a47f8ca0 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -9,11 +9,13 @@ use std::{fmt, mem, ops}; use itertools::Either; use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::attrs::AttributeKind; +use rustc_data_structures::thin_vec::{ThinVec, thin_vec}; +use rustc_hir::Attribute; +use rustc_hir::attrs::{AttributeKind, CfgEntry}; use rustc_middle::ty::TyCtxt; use rustc_session::parse::ParseSess; -use rustc_span::Span; use rustc_span::symbol::{Symbol, sym}; +use rustc_span::{DUMMY_SP, Span}; use {rustc_ast as ast, rustc_hir as hir}; use crate::display::{Joined as _, MaybeDisplay, Wrapped}; @@ -23,20 +25,7 @@ use crate::html::escape::Escape; mod tests; #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub(crate) enum Cfg { - /// Accepts all configurations. - True, - /// Denies all configurations. - False, - /// A generic configuration option, e.g., `test` or `target_os = "linux"`. - Cfg(Symbol, Option), - /// Negates a configuration requirement, i.e., `not(x)`. - Not(Box), - /// Union of a list of configuration requirements, i.e., `any(...)`. - Any(Vec), - /// Intersection of a list of configuration requirements, i.e., `all(...)`. - All(Vec), -} +pub(crate) struct Cfg(CfgEntry); #[derive(PartialEq, Debug)] pub(crate) struct InvalidCfgError { @@ -44,27 +33,95 @@ pub(crate) struct InvalidCfgError { pub(crate) span: Span, } +/// Whether the configuration consists of just `Cfg` or `Not`. +fn is_simple_cfg(cfg: &CfgEntry) -> bool { + match cfg { + CfgEntry::Bool(..) + | CfgEntry::NameValue { .. } + | CfgEntry::Not(..) + | CfgEntry::Version(..) => true, + CfgEntry::All(..) | CfgEntry::Any(..) => false, + } +} + +/// Whether the configuration consists of just `Cfg`, `Not` or `All`. +fn is_all_cfg(cfg: &CfgEntry) -> bool { + match cfg { + CfgEntry::Bool(..) + | CfgEntry::NameValue { .. } + | CfgEntry::Not(..) + | CfgEntry::Version(..) + | CfgEntry::All(..) => true, + CfgEntry::Any(..) => false, + } +} + +fn strip_hidden(cfg: &CfgEntry, hidden: &FxHashSet) -> Option { + match cfg { + CfgEntry::Bool(..) => Some(cfg.clone()), + CfgEntry::NameValue { .. } => { + if !hidden.contains(&SimpleCfg::from(cfg)) { + Some(cfg.clone()) + } else { + None + } + } + CfgEntry::Not(cfg, _) => { + if let Some(cfg) = strip_hidden(cfg, hidden) { + Some(CfgEntry::Not(Box::new(cfg), DUMMY_SP)) + } else { + None + } + } + CfgEntry::Any(cfgs, _) => { + let cfgs = + cfgs.iter().filter_map(|cfg| strip_hidden(cfg, hidden)).collect::>(); + if cfgs.is_empty() { None } else { Some(CfgEntry::Any(cfgs, DUMMY_SP)) } + } + CfgEntry::All(cfgs, _) => { + let cfgs = + cfgs.iter().filter_map(|cfg| strip_hidden(cfg, hidden)).collect::>(); + if cfgs.is_empty() { None } else { Some(CfgEntry::All(cfgs, DUMMY_SP)) } + } + CfgEntry::Version(..) => { + // FIXME: Should be handled. + Some(cfg.clone()) + } + } +} + +fn should_capitalize_first_letter(cfg: &CfgEntry) -> bool { + match cfg { + CfgEntry::Bool(..) | CfgEntry::Not(..) | CfgEntry::Version(..) => true, + CfgEntry::Any(sub_cfgs, _) | CfgEntry::All(sub_cfgs, _) => { + sub_cfgs.first().map(should_capitalize_first_letter).unwrap_or(false) + } + CfgEntry::NameValue { name, .. } => { + *name == sym::debug_assertions || *name == sym::target_endian + } + } +} + impl Cfg { /// Parses a `MetaItemInner` into a `Cfg`. fn parse_nested( nested_cfg: &MetaItemInner, - exclude: &FxHashSet, + exclude: &FxHashSet, ) -> Result, InvalidCfgError> { match nested_cfg { MetaItemInner::MetaItem(cfg) => Cfg::parse_without(cfg, exclude), - MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => match *b { - true => Ok(Some(Cfg::True)), - false => Ok(Some(Cfg::False)), - }, + MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => { + Ok(Some(Cfg(CfgEntry::Bool(*b, DUMMY_SP)))) + } MetaItemInner::Lit(lit) => { Err(InvalidCfgError { msg: "unexpected literal", span: lit.span }) } } } - pub(crate) fn parse_without( + fn parse_without( cfg: &MetaItem, - exclude: &FxHashSet, + exclude: &FxHashSet, ) -> Result, InvalidCfgError> { let name = match cfg.ident() { Some(ident) => ident.name, @@ -77,13 +134,29 @@ impl Cfg { }; match cfg.kind { MetaItemKind::Word => { - let cfg = Cfg::Cfg(name, None); - if exclude.contains(&cfg) { Ok(None) } else { Ok(Some(cfg)) } + if exclude.contains(&SimpleCfg::new(name)) { + Ok(None) + } else { + Ok(Some(Cfg(CfgEntry::NameValue { + name, + value: None, + name_span: DUMMY_SP, + span: DUMMY_SP, + }))) + } } MetaItemKind::NameValue(ref lit) => match lit.kind { LitKind::Str(value, _) => { - let cfg = Cfg::Cfg(name, Some(value)); - if exclude.contains(&cfg) { Ok(None) } else { Ok(Some(cfg)) } + if exclude.contains(&SimpleCfg::new_value(name, value)) { + Ok(None) + } else { + Ok(Some(Cfg(CfgEntry::NameValue { + name, + value: Some((value, DUMMY_SP)), + name_span: DUMMY_SP, + span: DUMMY_SP, + }))) + } } _ => Err(InvalidCfgError { // FIXME: if the main #[cfg] syntax decided to support non-string literals, @@ -97,8 +170,12 @@ impl Cfg { let mut sub_cfgs = items.iter().filter_map(|i| Cfg::parse_nested(i, exclude).transpose()); let ret = match name { - sym::all => sub_cfgs.try_fold(Cfg::True, |x, y| Ok(x & y?)), - sym::any => sub_cfgs.try_fold(Cfg::False, |x, y| Ok(x | y?)), + sym::all => { + sub_cfgs.try_fold(Cfg(CfgEntry::Bool(true, DUMMY_SP)), |x, y| Ok(x & y?)) + } + sym::any => { + sub_cfgs.try_fold(Cfg(CfgEntry::Bool(false, DUMMY_SP)), |x, y| Ok(x | y?)) + } sym::not => { if orig_len == 1 { let mut sub_cfgs = sub_cfgs.collect::>(); @@ -136,36 +213,32 @@ impl Cfg { /// /// Equivalent to `attr::cfg_matches`. pub(crate) fn matches(&self, psess: &ParseSess) -> bool { - match *self { - Cfg::False => false, - Cfg::True => true, - Cfg::Not(ref child) => !child.matches(psess), - Cfg::All(ref sub_cfgs) => sub_cfgs.iter().all(|sub_cfg| sub_cfg.matches(psess)), - Cfg::Any(ref sub_cfgs) => sub_cfgs.iter().any(|sub_cfg| sub_cfg.matches(psess)), - Cfg::Cfg(name, value) => psess.config.contains(&(name, value)), - } - } - - /// Whether the configuration consists of just `Cfg` or `Not`. - fn is_simple(&self) -> bool { - match self { - Cfg::False | Cfg::True | Cfg::Cfg(..) | Cfg::Not(..) => true, - Cfg::All(..) | Cfg::Any(..) => false, - } - } - - /// Whether the configuration consists of just `Cfg`, `Not` or `All`. - fn is_all(&self) -> bool { - match self { - Cfg::False | Cfg::True | Cfg::Cfg(..) | Cfg::Not(..) | Cfg::All(..) => true, - Cfg::Any(..) => false, + fn cfg_matches(cfg: &CfgEntry, psess: &ParseSess) -> bool { + match cfg { + CfgEntry::Bool(v, _) => *v, + CfgEntry::Not(child, _) => !cfg_matches(child, psess), + CfgEntry::All(sub_cfgs, _) => { + sub_cfgs.iter().all(|sub_cfg| cfg_matches(sub_cfg, psess)) + } + CfgEntry::Any(sub_cfgs, _) => { + sub_cfgs.iter().any(|sub_cfg| cfg_matches(sub_cfg, psess)) + } + CfgEntry::NameValue { name, value, .. } => { + psess.config.contains(&(*name, value.clone().map(|(s, _)| s))) + } + CfgEntry::Version(..) => { + // FIXME: should be handled. + false + } + } } + cfg_matches(&self.0, psess) } /// Renders the configuration for human display, as a short HTML description. pub(crate) fn render_short_html(&self) -> String { - let mut msg = Display(self, Format::ShortHtml).to_string(); - if self.should_capitalize_first_letter() + let mut msg = Display(&self.0, Format::ShortHtml).to_string(); + if should_capitalize_first_letter(&self.0) && let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) { msg[i..i + 1].make_ascii_uppercase(); @@ -183,9 +256,9 @@ impl Cfg { }; let mut msg = if matches!(format, Format::LongHtml) { - format!("Available{on}{}", Display(self, format)) + format!("Available{on}{}", Display(&self.0, format)) } else { - format!("Available{on}{}", Display(self, format)) + format!("Available{on}{}", Display(&self.0, format)) }; if self.should_append_only_to_description() { msg.push_str(" only"); @@ -205,27 +278,20 @@ impl Cfg { self.render_long_inner(Format::LongPlain) } - fn should_capitalize_first_letter(&self) -> bool { - match *self { - Cfg::False | Cfg::True | Cfg::Not(..) => true, - Cfg::Any(ref sub_cfgs) | Cfg::All(ref sub_cfgs) => { - sub_cfgs.first().map(Cfg::should_capitalize_first_letter).unwrap_or(false) - } - Cfg::Cfg(name, _) => name == sym::debug_assertions || name == sym::target_endian, - } - } - fn should_append_only_to_description(&self) -> bool { - match self { - Cfg::False | Cfg::True => false, - Cfg::Any(..) | Cfg::All(..) | Cfg::Cfg(..) => true, - Cfg::Not(box Cfg::Cfg(..)) => true, - Cfg::Not(..) => false, + match self.0 { + CfgEntry::Bool(..) => false, + CfgEntry::Any(..) + | CfgEntry::All(..) + | CfgEntry::NameValue { .. } + | CfgEntry::Version(..) => true, + CfgEntry::Not(box CfgEntry::NameValue { .. }, _) => true, + CfgEntry::Not(..) => false, } } fn should_use_with_in_description(&self) -> bool { - matches!(self, Cfg::Cfg(sym::target_feature, _)) + matches!(self.0, CfgEntry::NameValue { name, .. } if name == sym::target_feature) } /// Attempt to simplify this cfg by assuming that `assume` is already known to be true, will @@ -236,20 +302,20 @@ impl Cfg { pub(crate) fn simplify_with(&self, assume: &Self) -> Option { if self == assume { None - } else if let Cfg::All(a) = self { - let mut sub_cfgs: Vec = if let Cfg::All(b) = assume { + } else if let CfgEntry::All(a, _) = &self.0 { + let mut sub_cfgs: ThinVec = if let CfgEntry::All(b, _) = &assume.0 { a.iter().filter(|a| !b.contains(a)).cloned().collect() } else { - a.iter().filter(|&a| a != assume).cloned().collect() + a.iter().filter(|&a| *a != assume.0).cloned().collect() }; let len = sub_cfgs.len(); match len { 0 => None, - 1 => sub_cfgs.pop(), - _ => Some(Cfg::All(sub_cfgs)), + 1 => sub_cfgs.pop().map(Cfg), + _ => Some(Cfg(CfgEntry::All(sub_cfgs, DUMMY_SP))), } - } else if let Cfg::All(b) = assume - && b.contains(self) + } else if let CfgEntry::All(b, _) = &assume.0 + && b.contains(&self.0) { None } else { @@ -258,81 +324,50 @@ impl Cfg { } fn omit_preposition(&self) -> bool { - matches!(self, Cfg::True | Cfg::False) - } - - pub(crate) fn strip_hidden(&self, hidden: &FxHashSet) -> Option { - match self { - Self::True | Self::False => Some(self.clone()), - Self::Cfg(..) => { - if !hidden.contains(self) { - Some(self.clone()) - } else { - None - } - } - Self::Not(cfg) => { - if let Some(cfg) = cfg.strip_hidden(hidden) { - Some(Self::Not(Box::new(cfg))) - } else { - None - } - } - Self::Any(cfgs) => { - let cfgs = - cfgs.iter().filter_map(|cfg| cfg.strip_hidden(hidden)).collect::>(); - if cfgs.is_empty() { None } else { Some(Self::Any(cfgs)) } - } - Self::All(cfgs) => { - let cfgs = - cfgs.iter().filter_map(|cfg| cfg.strip_hidden(hidden)).collect::>(); - if cfgs.is_empty() { None } else { Some(Self::All(cfgs)) } - } - } + matches!(self.0, CfgEntry::Bool(..)) } } impl ops::Not for Cfg { type Output = Cfg; fn not(self) -> Cfg { - match self { - Cfg::False => Cfg::True, - Cfg::True => Cfg::False, - Cfg::Not(cfg) => *cfg, - s => Cfg::Not(Box::new(s)), - } + Cfg(match self.0 { + CfgEntry::Bool(v, s) => CfgEntry::Bool(!v, s), + CfgEntry::Not(cfg, _) => *cfg, + s => CfgEntry::Not(Box::new(s), DUMMY_SP), + }) } } impl ops::BitAndAssign for Cfg { fn bitand_assign(&mut self, other: Cfg) { - match (self, other) { - (Cfg::False, _) | (_, Cfg::True) => {} - (s, Cfg::False) => *s = Cfg::False, - (s @ Cfg::True, b) => *s = b, - (Cfg::All(a), Cfg::All(ref mut b)) => { + match (&mut self.0, other.0) { + (CfgEntry::Bool(false, _), _) | (_, CfgEntry::Bool(true, _)) => {} + (s, CfgEntry::Bool(false, _)) => *s = CfgEntry::Bool(false, DUMMY_SP), + (s @ CfgEntry::Bool(true, _), b) => *s = b, + (CfgEntry::All(a, _), CfgEntry::All(ref mut b, _)) => { for c in b.drain(..) { if !a.contains(&c) { a.push(c); } } } - (Cfg::All(a), ref mut b) => { + (CfgEntry::All(a, _), ref mut b) => { if !a.contains(b) { - a.push(mem::replace(b, Cfg::True)); + a.push(mem::replace(b, CfgEntry::Bool(true, DUMMY_SP))); } } - (s, Cfg::All(mut a)) => { - let b = mem::replace(s, Cfg::True); + (s, CfgEntry::All(mut a, _)) => { + let b = mem::replace(s, CfgEntry::Bool(true, DUMMY_SP)); if !a.contains(&b) { a.push(b); } - *s = Cfg::All(a); + *s = CfgEntry::All(a, DUMMY_SP); } (s, b) => { if *s != b { - let a = mem::replace(s, Cfg::True); - *s = Cfg::All(vec![a, b]); + let a = mem::replace(s, CfgEntry::Bool(true, DUMMY_SP)); + *s = CfgEntry::All(thin_vec![a, b], DUMMY_SP); } } } @@ -349,32 +384,34 @@ impl ops::BitAnd for Cfg { impl ops::BitOrAssign for Cfg { fn bitor_assign(&mut self, other: Cfg) { - match (self, other) { - (Cfg::True, _) | (_, Cfg::False) | (_, Cfg::True) => {} - (s @ Cfg::False, b) => *s = b, - (Cfg::Any(a), Cfg::Any(ref mut b)) => { + match (&mut self.0, other.0) { + (CfgEntry::Bool(true, _), _) + | (_, CfgEntry::Bool(false, _)) + | (_, CfgEntry::Bool(true, _)) => {} + (s @ CfgEntry::Bool(false, _), b) => *s = b, + (CfgEntry::Any(a, _), CfgEntry::Any(ref mut b, _)) => { for c in b.drain(..) { if !a.contains(&c) { a.push(c); } } } - (Cfg::Any(a), ref mut b) => { + (CfgEntry::Any(a, _), ref mut b) => { if !a.contains(b) { - a.push(mem::replace(b, Cfg::True)); + a.push(mem::replace(b, CfgEntry::Bool(true, DUMMY_SP))); } } - (s, Cfg::Any(mut a)) => { - let b = mem::replace(s, Cfg::True); + (s, CfgEntry::Any(mut a, _)) => { + let b = mem::replace(s, CfgEntry::Bool(true, DUMMY_SP)); if !a.contains(&b) { a.push(b); } - *s = Cfg::Any(a); + *s = CfgEntry::Any(a, DUMMY_SP); } (s, b) => { if *s != b { - let a = mem::replace(s, Cfg::True); - *s = Cfg::Any(vec![a, b]); + let a = mem::replace(s, CfgEntry::Bool(true, DUMMY_SP)); + *s = CfgEntry::Any(thin_vec![a, b], DUMMY_SP); } } } @@ -417,7 +454,7 @@ impl Format { } /// Pretty-print wrapper for a `Cfg`. Also indicates what form of rendering should be used. -struct Display<'a>(&'a Cfg, Format); +struct Display<'a>(&'a CfgEntry, Format); impl Display<'_> { fn code_wrappers(&self) -> Wrapped<&'static str> { @@ -427,17 +464,21 @@ impl Display<'_> { fn display_sub_cfgs( &self, fmt: &mut fmt::Formatter<'_>, - sub_cfgs: &[Cfg], + sub_cfgs: &[CfgEntry], separator: &str, ) -> fmt::Result { use fmt::Display as _; let short_longhand = self.1.is_long() && { - let all_crate_features = - sub_cfgs.iter().all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_)))); - let all_target_features = sub_cfgs - .iter() - .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::target_feature, Some(_)))); + let all_crate_features = sub_cfgs.iter().all(|sub_cfg| { + matches!(sub_cfg, CfgEntry::NameValue { name: sym::feature, value: Some(_), .. }) + }); + let all_target_features = sub_cfgs.iter().all(|sub_cfg| { + matches!( + sub_cfg, + CfgEntry::NameValue { name: sym::target_feature, value: Some(_), .. } + ) + }); if all_crate_features { fmt.write_str("crate features ")?; @@ -454,14 +495,14 @@ impl Display<'_> { sub_cfgs .iter() .map(|sub_cfg| { - if let Cfg::Cfg(_, Some(feat)) = sub_cfg + if let CfgEntry::NameValue { value: Some((feat, _)), .. } = sub_cfg && short_longhand { Either::Left(self.code_wrappers().wrap(feat)) } else { Either::Right( Wrapped::with_parens() - .when(!sub_cfg.is_all()) + .when(!is_all_cfg(sub_cfg)) .wrap(Display(sub_cfg, self.1)), ) } @@ -476,39 +517,45 @@ impl Display<'_> { impl fmt::Display for Display<'_> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.0 { - Cfg::Not(box Cfg::Any(sub_cfgs)) => { - let separator = - if sub_cfgs.iter().all(Cfg::is_simple) { " nor " } else { ", nor " }; + match &self.0 { + CfgEntry::Not(box CfgEntry::Any(sub_cfgs, _), _) => { + let separator = if sub_cfgs.iter().all(is_simple_cfg) { " nor " } else { ", nor " }; fmt.write_str("neither ")?; sub_cfgs .iter() .map(|sub_cfg| { Wrapped::with_parens() - .when(!sub_cfg.is_all()) + .when(!is_all_cfg(sub_cfg)) .wrap(Display(sub_cfg, self.1)) }) .joined(separator, fmt) } - Cfg::Not(box simple @ Cfg::Cfg(..)) => write!(fmt, "non-{}", Display(simple, self.1)), - Cfg::Not(box c) => write!(fmt, "not ({})", Display(c, self.1)), - - Cfg::Any(sub_cfgs) => { - let separator = if sub_cfgs.iter().all(Cfg::is_simple) { " or " } else { ", or " }; - self.display_sub_cfgs(fmt, sub_cfgs, separator) + CfgEntry::Not(box simple @ CfgEntry::NameValue { .. }, _) => { + write!(fmt, "non-{}", Display(simple, self.1)) } - Cfg::All(sub_cfgs) => self.display_sub_cfgs(fmt, sub_cfgs, " and "), + CfgEntry::Not(box c, _) => write!(fmt, "not ({})", Display(c, self.1)), - Cfg::True => fmt.write_str("everywhere"), - Cfg::False => fmt.write_str("nowhere"), + CfgEntry::Any(sub_cfgs, _) => { + let separator = if sub_cfgs.iter().all(is_simple_cfg) { " or " } else { ", or " }; + self.display_sub_cfgs(fmt, sub_cfgs.as_slice(), separator) + } + CfgEntry::All(sub_cfgs, _) => self.display_sub_cfgs(fmt, sub_cfgs.as_slice(), " and "), - &Cfg::Cfg(name, value) => { - let human_readable = match (name, value) { + CfgEntry::Bool(v, _) => { + if *v { + fmt.write_str("everywhere") + } else { + fmt.write_str("nowhere") + } + } + + &CfgEntry::NameValue { name, value, .. } => { + let human_readable = match (*name, value) { (sym::unix, None) => "Unix", (sym::windows, None) => "Windows", (sym::debug_assertions, None) => "debug-assertions enabled", - (sym::target_os, Some(os)) => match os.as_str() { + (sym::target_os, Some((os, _))) => match os.as_str() { "android" => "Android", "cygwin" => "Cygwin", "dragonfly" => "DragonFly BSD", @@ -533,7 +580,7 @@ impl fmt::Display for Display<'_> { "visionos" => "visionOS", _ => "", }, - (sym::target_arch, Some(arch)) => match arch.as_str() { + (sym::target_arch, Some((arch, _))) => match arch.as_str() { "aarch64" => "AArch64", "arm" => "ARM", "loongarch32" => "LoongArch LA32", @@ -556,14 +603,14 @@ impl fmt::Display for Display<'_> { "x86_64" => "x86-64", _ => "", }, - (sym::target_vendor, Some(vendor)) => match vendor.as_str() { + (sym::target_vendor, Some((vendor, _))) => match vendor.as_str() { "apple" => "Apple", "pc" => "PC", "sun" => "Sun", "fortanix" => "Fortanix", _ => "", }, - (sym::target_env, Some(env)) => match env.as_str() { + (sym::target_env, Some((env, _))) => match env.as_str() { "gnu" => "GNU", "msvc" => "MSVC", "musl" => "musl", @@ -572,16 +619,20 @@ impl fmt::Display for Display<'_> { "sgx" => "SGX", _ => "", }, - (sym::target_endian, Some(endian)) => return write!(fmt, "{endian}-endian"), - (sym::target_pointer_width, Some(bits)) => return write!(fmt, "{bits}-bit"), - (sym::target_feature, Some(feat)) => match self.1 { + (sym::target_endian, Some((endian, _))) => { + return write!(fmt, "{endian}-endian"); + } + (sym::target_pointer_width, Some((bits, _))) => { + return write!(fmt, "{bits}-bit"); + } + (sym::target_feature, Some((feat, _))) => match self.1 { Format::LongHtml => { return write!(fmt, "target feature {feat}"); } Format::LongPlain => return write!(fmt, "target feature `{feat}`"), Format::ShortHtml => return write!(fmt, "{feat}"), }, - (sym::feature, Some(feat)) => match self.1 { + (sym::feature, Some((feat, _))) => match self.1 { Format::LongHtml => { return write!(fmt, "crate feature {feat}"); } @@ -594,13 +645,47 @@ impl fmt::Display for Display<'_> { fmt.write_str(human_readable) } else { let value = value - .map(|v| fmt::from_fn(move |f| write!(f, "={}", self.1.escape(v.as_str())))) + .map(|(v, _)| { + fmt::from_fn(move |f| write!(f, "={}", self.1.escape(v.as_str()))) + }) .maybe_display(); self.code_wrappers() .wrap(format_args!("{}{value}", self.1.escape(name.as_str()))) .fmt(fmt) } } + + CfgEntry::Version(..) => { + // FIXME: Should we handle it? + Ok(()) + } + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +struct SimpleCfg { + name: Symbol, + value: Option, +} + +impl SimpleCfg { + fn new(name: Symbol) -> Self { + Self { name, value: None } + } + + fn new_value(name: Symbol, value: Symbol) -> Self { + Self { name, value: Some(value) } + } +} + +impl<'a> From<&'a CfgEntry> for SimpleCfg { + fn from(cfg: &'a CfgEntry) -> Self { + match cfg { + CfgEntry::NameValue { name, value, .. } => { + SimpleCfg { name: *name, value: (*value).map(|(v, _)| v) } + } + _ => SimpleCfg { name: sym::empty, value: None }, } } } @@ -610,7 +695,7 @@ impl fmt::Display for Display<'_> { pub(crate) struct CfgInfo { /// List of currently active `doc(auto_cfg(hide(...)))` cfgs, minus currently active /// `doc(auto_cfg(show(...)))` cfgs. - hidden_cfg: FxHashSet, + hidden_cfg: FxHashSet, /// Current computed `cfg`. Each time we enter a new item, this field is updated as well while /// taking into account the `hidden_cfg` information. current_cfg: Cfg, @@ -626,11 +711,11 @@ impl Default for CfgInfo { fn default() -> Self { Self { hidden_cfg: FxHashSet::from_iter([ - Cfg::Cfg(sym::test, None), - Cfg::Cfg(sym::doc, None), - Cfg::Cfg(sym::doctest, None), + SimpleCfg::new(sym::test), + SimpleCfg::new(sym::doc), + SimpleCfg::new(sym::doctest), ]), - current_cfg: Cfg::True, + current_cfg: Cfg(CfgEntry::Bool(true, DUMMY_SP)), auto_cfg_active: true, parent_is_doc_cfg: false, } @@ -672,21 +757,24 @@ fn handle_auto_cfg_hide_show( { for item in items { // FIXME: Report in case `Cfg::parse` reports an error? - if let Ok(Cfg::Cfg(key, value)) = Cfg::parse(item) { + let Ok(cfg) = Cfg::parse(item) else { continue }; + if let CfgEntry::NameValue { name, value, .. } = cfg.0 { + let value = value.map(|(v, _)| v); + let simple = SimpleCfg::from(&cfg.0); if is_show { - if let Some(span) = new_hide_attrs.get(&(key, value)) { + if let Some(span) = new_hide_attrs.get(&(name, value)) { show_hide_show_conflict_error(tcx, item.span(), *span); } else { - new_show_attrs.insert((key, value), item.span()); + new_show_attrs.insert((name, value), item.span()); } - cfg_info.hidden_cfg.remove(&Cfg::Cfg(key, value)); + cfg_info.hidden_cfg.remove(&simple); } else { - if let Some(span) = new_show_attrs.get(&(key, value)) { + if let Some(span) = new_show_attrs.get(&(name, value)) { show_hide_show_conflict_error(tcx, item.span(), *span); } else { - new_hide_attrs.insert((key, value), item.span()); + new_hide_attrs.insert((name, value), item.span()); } - cfg_info.hidden_cfg.insert(Cfg::Cfg(key, value)); + cfg_info.hidden_cfg.insert(simple); } } } @@ -737,28 +825,21 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator let mut doc_cfg = attrs .clone() - .filter(|attr| attr.has_name(sym::doc)) - .flat_map(|attr| attr.meta_item_list().unwrap_or_default()) - .filter(|attr| attr.has_name(sym::cfg)) + .filter_map(|attr| match attr { + Attribute::Parsed(AttributeKind::Doc(d)) => Some(d), + _ => None, + }) .peekable(); // If the item uses `doc(cfg(...))`, then we ignore the other `cfg(...)` attributes. if doc_cfg.peek().is_some() { - let sess = tcx.sess; // We overwrite existing `cfg`. if !cfg_info.parent_is_doc_cfg { - cfg_info.current_cfg = Cfg::True; + cfg_info.current_cfg = Cfg(CfgEntry::Bool(true, DUMMY_SP)); cfg_info.parent_is_doc_cfg = true; } for attr in doc_cfg { - if let Some(cfg_mi) = - attr.meta_item().and_then(|attr| rustc_expand::config::parse_cfg_old(attr, sess)) - { - match Cfg::parse(cfg_mi) { - Ok(new_cfg) => cfg_info.current_cfg &= new_cfg, - Err(e) => { - sess.dcx().span_err(e.span, e.msg); - } - } + if let Some(new_cfg) = attr.cfg.clone() { + cfg_info.current_cfg &= Cfg(new_cfg); } } } else { @@ -833,7 +914,12 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator // Treat `#[target_feature(enable = "feat")]` attributes as if they were // `#[doc(cfg(target_feature = "feat"))]` attributes as well. for (feature, _) in features { - cfg_info.current_cfg &= Cfg::Cfg(sym::target_feature, Some(*feature)); + cfg_info.current_cfg &= Cfg(CfgEntry::NameValue { + name: sym::target_feature, + value: Some((*feature, DUMMY_SP)), + name_span: DUMMY_SP, + span: DUMMY_SP, + }); } continue; } else if !cfg_info.parent_is_doc_cfg @@ -851,7 +937,7 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator if !cfg_info.auto_cfg_active && !cfg_info.parent_is_doc_cfg { None } else if cfg_info.parent_is_doc_cfg { - if cfg_info.current_cfg == Cfg::True { + if matches!(cfg_info.current_cfg.0, CfgEntry::Bool(true, _)) { None } else { Some(Arc::new(cfg_info.current_cfg.clone())) @@ -859,9 +945,9 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator } else { // If `doc(auto_cfg)` feature is enabled, we want to collect all `cfg` items, we remove the // hidden ones afterward. - match cfg_info.current_cfg.strip_hidden(&cfg_info.hidden_cfg) { - None | Some(Cfg::True) => None, - Some(cfg) => Some(Arc::new(cfg)), + match strip_hidden(&cfg_info.current_cfg.0, &cfg_info.hidden_cfg) { + None | Some(CfgEntry::Bool(true, _)) => None, + Some(cfg) => Some(Arc::new(Cfg(cfg))), } } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 849df566b4bd..c86a655c083a 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -640,7 +640,7 @@ pub(crate) fn build_impl( for_, items: trait_items, polarity, - kind: if utils::has_doc_flag(tcx, did, sym::fake_variadic) { + kind: if utils::has_doc_flag(tcx, did, |d| d.fake_variadic.is_some()) { ImplKind::FakeVariadic } else { ImplKind::Normal diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1f9ce68584ce..6fd578628388 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -34,13 +34,11 @@ use std::borrow::Cow; use std::collections::BTreeMap; use std::mem; -use rustc_ast::token::{Token, TokenKind}; -use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry}; use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::codes::*; use rustc_errors::{FatalError, struct_span_code_err}; -use rustc_hir::attrs::AttributeKind; +use rustc_hir::attrs::{AttributeKind, DocAttribute, DocInline}; use rustc_hir::def::{CtorKind, DefKind, MacroKinds, Res}; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId}; use rustc_hir::{LangItem, PredicateOrigin, find_attr}; @@ -198,12 +196,9 @@ fn generate_item_with_correct_attrs( // For glob re-exports the item may or may not exist to be re-exported (potentially the // cfgs on the path up until the glob can be removed, and only cfgs on the globbed item // itself matter), for non-inlined re-exports see #85043. - let import_is_inline = - hir_attr_lists(inline::load_attrs(cx, import_id.to_def_id()), sym::doc) - .get_word_attr(sym::inline) - .is_some() - || (is_glob_import(cx.tcx, import_id) - && (cx.document_hidden() || !cx.tcx.is_doc_hidden(def_id))); + let import_is_inline = find_attr!(inline::load_attrs(cx, import_id.to_def_id()), AttributeKind::Doc(d) if d.inline.is_some()) + || (is_glob_import(cx.tcx, import_id) + && (cx.document_hidden() || !cx.tcx.is_doc_hidden(def_id))); attrs.extend(get_all_import_attributes(cx, import_id, def_id, is_inline)); is_inline = is_inline || import_is_inline; } @@ -2635,63 +2630,6 @@ fn get_all_import_attributes<'hir>( attrs } -fn filter_tokens_from_list( - args_tokens: &TokenStream, - should_retain: impl Fn(&TokenTree) -> bool, -) -> Vec { - let mut tokens = Vec::with_capacity(args_tokens.len()); - let mut skip_next_comma = false; - for token in args_tokens.iter() { - match token { - TokenTree::Token(Token { kind: TokenKind::Comma, .. }, _) if skip_next_comma => { - skip_next_comma = false; - } - token if should_retain(token) => { - skip_next_comma = false; - tokens.push(token.clone()); - } - _ => { - skip_next_comma = true; - } - } - } - tokens -} - -fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool { - if is_inline { - ident == sym::hidden || ident == sym::inline || ident == sym::no_inline - } else { - ident == sym::cfg - } -} - -/// Remove attributes from `normal` that should not be inherited by `use` re-export. -/// Before calling this function, make sure `normal` is a `#[doc]` attribute. -fn filter_doc_attr(args: &mut hir::AttrArgs, is_inline: bool) { - match args { - hir::AttrArgs::Delimited(args) => { - let tokens = filter_tokens_from_list(&args.tokens, |token| { - !matches!( - token, - TokenTree::Token( - Token { - kind: TokenKind::Ident( - ident, - _, - ), - .. - }, - _, - ) if filter_doc_attr_ident(*ident, is_inline), - ) - }); - args.tokens = TokenStream::new(tokens); - } - hir::AttrArgs::Empty | hir::AttrArgs::Eq { .. } => {} - } -} - /// When inlining items, we merge their attributes (and all the reexports attributes too) with the /// final reexport. For example: /// @@ -2719,25 +2657,34 @@ fn add_without_unwanted_attributes<'hir>( import_parent: Option, ) { for attr in new_attrs { - if attr.is_doc_comment().is_some() { - attrs.push((Cow::Borrowed(attr), import_parent)); - continue; - } - let mut attr = attr.clone(); match attr { - hir::Attribute::Unparsed(ref mut normal) if let [ident] = &*normal.path.segments => { - let ident = ident.name; - if ident == sym::doc { - filter_doc_attr(&mut normal.args, is_inline); - attrs.push((Cow::Owned(attr), import_parent)); - } else if is_inline || ident != sym::cfg_trace { + hir::Attribute::Parsed(AttributeKind::DocComment { .. }) => { + attrs.push((Cow::Borrowed(attr), import_parent)); + } + hir::Attribute::Parsed(AttributeKind::Doc(box d)) => { + // Remove attributes from `normal` that should not be inherited by `use` re-export. + let DocAttribute { hidden, inline, cfg, .. } = d; + let mut attr = DocAttribute::default(); + if is_inline { + attr.inline = inline.clone(); + attr.hidden = hidden.clone(); + } else { + attr.cfg = cfg.clone(); + } + attrs.push(( + Cow::Owned(hir::Attribute::Parsed(AttributeKind::Doc(Box::new(attr)))), + import_parent, + )); + } + hir::Attribute::Unparsed(normal) if let [ident] = &*normal.path.segments => { + if is_inline || ident.name != sym::cfg_trace { // If it's not a `cfg()` attribute, we keep it. - attrs.push((Cow::Owned(attr), import_parent)); + attrs.push((Cow::Borrowed(attr), import_parent)); } } // FIXME: make sure to exclude `#[cfg_trace]` here when it is ported to the new parsers hir::Attribute::Parsed(..) => { - attrs.push((Cow::Owned(attr), import_parent)); + attrs.push((Cow::Borrowed(attr), import_parent)); } _ => {} } @@ -2939,7 +2886,7 @@ fn clean_impl<'tcx>( } else { ty::ImplPolarity::Positive }, - kind: if utils::has_doc_flag(tcx, def_id.to_def_id(), sym::fake_variadic) { + kind: if utils::has_doc_flag(tcx, def_id.to_def_id(), |d| d.fake_variadic.is_some()) { ImplKind::FakeVariadic } else { ImplKind::Normal @@ -2967,13 +2914,10 @@ fn clean_extern_crate<'tcx>( let attrs = cx.tcx.hir_attrs(krate.hir_id()); let ty_vis = cx.tcx.visibility(krate.owner_id); let please_inline = ty_vis.is_public() - && attrs.iter().any(|a| { - a.has_name(sym::doc) - && match a.meta_item_list() { - Some(l) => ast::attr::list_contains_name(&l, sym::inline), - None => false, - } - }) + && attrs.iter().any(|a| matches!( + a, + hir::Attribute::Parsed(AttributeKind::Doc(d)) if d.inline.is_some_and(|(i, _)| i == DocInline::Inline)) + ) && !cx.is_json_output(); let krate_owner_def_id = krate.owner_id.def_id; @@ -3035,7 +2979,11 @@ fn clean_use_statement_inner<'tcx>( let visibility = cx.tcx.visibility(import.owner_id); let attrs = cx.tcx.hir_attrs(import.hir_id()); - let inline_attr = hir_attr_lists(attrs, sym::doc).get_word_attr(sym::inline); + let inline_attr = find_attr!( + attrs, + AttributeKind::Doc(d) if d.inline.is_some_and(|(i, _)| i == DocInline::Inline) => d + ) + .and_then(|d| d.inline); let pub_underscore = visibility.is_public() && name == Some(kw::Underscore); let current_mod = cx.tcx.parent_module_from_def_id(import.owner_id.def_id); let import_def_id = import.owner_id.def_id; @@ -3053,10 +3001,10 @@ fn clean_use_statement_inner<'tcx>( let is_visible_from_parent_mod = visibility.is_accessible_from(parent_mod, cx.tcx) && !current_mod.is_top_level_module(); - if pub_underscore && let Some(ref inline) = inline_attr { + if pub_underscore && let Some((_, inline_span)) = inline_attr { struct_span_code_err!( cx.tcx.dcx(), - inline.span(), + inline_span, E0780, "anonymous imports cannot be inlined" ) @@ -3071,16 +3019,9 @@ fn clean_use_statement_inner<'tcx>( let mut denied = cx.is_json_output() || !(visibility.is_public() || (cx.document_private() && is_visible_from_parent_mod)) || pub_underscore - || attrs.iter().any(|a| { - a.has_name(sym::doc) - && match a.meta_item_list() { - Some(l) => { - ast::attr::list_contains_name(&l, sym::no_inline) - || ast::attr::list_contains_name(&l, sym::hidden) - } - None => false, - } - }); + || attrs.iter().any(|a| matches!( + a, + hir::Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some() || d.inline.is_some_and(|(i, _)| i == DocInline::NoInline))); // Also check whether imports were asked to be inlined, in case we're trying to re-export a // crate in Rust 2018+ diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index f1b0f4a68bea..12dcb198bd21 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -9,11 +9,11 @@ use itertools::Either; use rustc_abi::{ExternAbi, VariantIdx}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::thin_vec::ThinVec; -use rustc_hir::attrs::{AttributeKind, DeprecatedSince, Deprecation}; +use rustc_hir::attrs::{AttributeKind, DeprecatedSince, Deprecation, DocAttribute}; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::lang_items::LangItem; -use rustc_hir::{BodyId, ConstStability, Mutability, Stability, StableSince, find_attr}; +use rustc_hir::{Attribute, BodyId, ConstStability, Mutability, Stability, StableSince, find_attr}; use rustc_index::IndexVec; use rustc_metadata::rendered_const; use rustc_middle::span_bug; @@ -190,12 +190,13 @@ impl ExternalCrate { // Failing that, see if there's an attribute specifying where to find this // external crate let did = self.crate_num.as_def_id(); - tcx.get_attrs(did, sym::doc) - .flat_map(|attr| attr.meta_item_list().unwrap_or_default()) - .filter(|a| a.has_name(sym::html_root_url)) - .filter_map(|a| a.value_str()) + tcx.get_all_attrs(did) + .iter() + .find_map(|a| match a { + Attribute::Parsed(AttributeKind::Doc(d)) => d.html_root_url.map(|(url, _)| url), + _ => None, + }) .map(to_remote) - .next() .or_else(|| extern_url.map(to_remote)) // NOTE: only matters if `extern_url_takes_precedence` is false .unwrap_or(Unknown) // Well, at least we tried. } @@ -228,26 +229,34 @@ impl ExternalCrate { } pub(crate) fn keywords(&self, tcx: TyCtxt<'_>) -> impl Iterator { - self.retrieve_keywords_or_documented_attributes(tcx, sym::keyword) + self.retrieve_keywords_or_documented_attributes(tcx, true) } pub(crate) fn documented_attributes( &self, tcx: TyCtxt<'_>, ) -> impl Iterator { - self.retrieve_keywords_or_documented_attributes(tcx, sym::attribute) + self.retrieve_keywords_or_documented_attributes(tcx, false) } fn retrieve_keywords_or_documented_attributes( &self, tcx: TyCtxt<'_>, - name: Symbol, + look_for_keyword: bool, ) -> impl Iterator { let as_target = move |did: DefId, tcx: TyCtxt<'_>| -> Option<(DefId, Symbol)> { - tcx.get_attrs(did, sym::doc) - .flat_map(|attr| attr.meta_item_list().unwrap_or_default()) - .filter(|meta| meta.has_name(name)) - .find_map(|meta| meta.value_str()) - .map(|value| (did, value)) + tcx.get_all_attrs(did) + .iter() + .find_map(|attr| match attr { + Attribute::Parsed(AttributeKind::Doc(d)) => { + if look_for_keyword { + d.keyword + } else { + d.attribute + } + } + _ => None, + }) + .map(|(value, _)| (did, value)) }; self.mapped_root_modules(tcx, as_target) } @@ -993,28 +1002,14 @@ pub(crate) struct Attributes { } impl Attributes { - pub(crate) fn lists(&self, name: Symbol) -> impl Iterator { - hir_attr_lists(&self.other_attrs[..], name) - } - - pub(crate) fn has_doc_flag(&self, flag: Symbol) -> bool { - for attr in &self.other_attrs { - if !attr.has_name(sym::doc) { - continue; - } - - if let Some(items) = attr.meta_item_list() - && items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) - { - return true; - } - } - - false + pub(crate) fn has_doc_flag bool>(&self, callback: F) -> bool { + self.other_attrs + .iter() + .any(|a| matches!(a, Attribute::Parsed(AttributeKind::Doc(d)) if callback(d))) } pub(crate) fn is_doc_hidden(&self) -> bool { - self.has_doc_flag(sym::hidden) + find_attr!(&self.other_attrs, AttributeKind::Doc(d) if d.hidden.is_some()) } pub(crate) fn from_hir(attrs: &[hir::Attribute]) -> Attributes { @@ -1061,19 +1056,11 @@ impl Attributes { pub(crate) fn get_doc_aliases(&self) -> Box<[Symbol]> { let mut aliases = FxIndexSet::default(); - for attr in - hir_attr_lists(&self.other_attrs[..], sym::doc).filter(|a| a.has_name(sym::alias)) - { - if let Some(values) = attr.meta_item_list() { - for l in values { - if let Some(lit) = l.lit() - && let ast::LitKind::Str(s, _) = lit.kind - { - aliases.insert(s); - } + for attr in &self.other_attrs { + if let Attribute::Parsed(AttributeKind::Doc(d)) = attr { + for (alias, _) in &d.aliases { + aliases.insert(*alias); } - } else if let Some(value) = attr.value_str() { - aliases.insert(value); } } aliases.into_iter().collect::>().into() diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index cb5cd6523afe..4c3f26701bab 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -6,6 +6,8 @@ use std::{ascii, mem}; use rustc_ast::join_path_idents; use rustc_ast::tokenstream::TokenTree; use rustc_data_structures::thin_vec::{ThinVec, thin_vec}; +use rustc_hir::Attribute; +use rustc_hir::attrs::{AttributeKind, DocAttribute}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_metadata::rendered_const; @@ -46,7 +48,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { if cx.tcx.is_compiler_builtins(it.item_id.krate()) { cx.cache.masked_crates.insert(it.item_id.krate()); } else if it.is_extern_crate() - && it.attrs.has_doc_flag(sym::masked) + && it.attrs.has_doc_flag(|d| d.masked.is_some()) && let Some(def_id) = it.item_id.as_def_id() && let Some(local_def_id) = def_id.as_local() && let Some(cnum) = cx.tcx.extern_mod_stmt_cnum(local_def_id) @@ -562,24 +564,17 @@ pub(crate) fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Opti } } -/// Checks for the existence of `hidden` in the attribute below if `flag` is `sym::hidden`: -/// -/// ``` -/// #[doc(hidden)] -/// pub fn foo() {} -/// ``` -/// /// This function exists because it runs on `hir::Attributes` whereas the other is a /// `clean::Attributes` method. -pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool { - attrs_have_doc_flag(tcx.get_attrs(did, sym::doc), flag) -} - -pub(crate) fn attrs_have_doc_flag<'a>( - mut attrs: impl Iterator, - flag: Symbol, +pub(crate) fn has_doc_flag bool>( + tcx: TyCtxt<'_>, + did: DefId, + callback: F, ) -> bool { - attrs.any(|attr| attr.meta_item_list().is_some_and(|l| ast::attr::list_contains_name(&l, flag))) + tcx.get_all_attrs(did).iter().any(|attr| match attr { + Attribute::Parsed(AttributeKind::Doc(d)) => callback(d), + _ => false, + }) } /// A link to `doc.rust-lang.org` that includes the channel name. Use this instead of manual links diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 481aa392007c..7541311be05d 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -9,6 +9,7 @@ use std::hash::{Hash, Hasher}; use std::io::{self, Write}; use std::path::{Path, PathBuf}; use std::process::{self, Command, Stdio}; +use std::str::FromStr; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; @@ -19,14 +20,15 @@ pub(crate) use markdown::test as test_markdown; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxHasher, FxIndexMap, FxIndexSet}; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, DiagCtxtHandle}; -use rustc_hir as hir; -use rustc_hir::CRATE_HIR_ID; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::{Attribute, CRATE_HIR_ID}; use rustc_interface::interface; +use rustc_middle::ty::TyCtxt; +use rustc_proc_macro::{TokenStream, TokenTree}; use rustc_session::config::{self, CrateType, ErrorOutputType, Input}; use rustc_session::lint; use rustc_span::edition::Edition; -use rustc_span::symbol::sym; use rustc_span::{FileName, Span}; use rustc_target::spec::{Target, TargetTuple}; use tempfile::{Builder as TempFileBuilder, TempDir}; @@ -212,8 +214,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); - let crate_attrs = tcx.hir_attrs(CRATE_HIR_ID); - let opts = scrape_test_config(crate_name, crate_attrs, args_path); + let opts = scrape_test_config(tcx, crate_name, args_path); let hir_collector = HirCollector::new( ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), @@ -417,8 +418,8 @@ pub(crate) fn run_tests( // Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade. fn scrape_test_config( + tcx: TyCtxt<'_>, crate_name: String, - attrs: &[hir::Attribute], args_file: PathBuf, ) -> GlobalTestOptions { let mut opts = GlobalTestOptions { @@ -428,19 +429,26 @@ fn scrape_test_config( args_file, }; - let test_attrs: Vec<_> = attrs - .iter() - .filter(|a| a.has_name(sym::doc)) - .flat_map(|a| a.meta_item_list().unwrap_or_default()) - .filter(|a| a.has_name(sym::test)) - .collect(); - let attrs = test_attrs.iter().flat_map(|a| a.meta_item_list().unwrap_or(&[])); - - for attr in attrs { - if attr.has_name(sym::no_crate_inject) { - opts.no_crate_inject = true; + let source_map = tcx.sess.source_map(); + 'main: for attr in tcx.hir_attrs(CRATE_HIR_ID) { + let Attribute::Parsed(AttributeKind::Doc(d)) = attr else { continue }; + for attr_span in &d.test_attrs { + // FIXME: This is ugly, remove when `test_attrs` has been ported to new attribute API. + if let Ok(snippet) = source_map.span_to_snippet(*attr_span) + && let Ok(stream) = TokenStream::from_str(&snippet) + { + // NOTE: `test(attr(..))` is handled when discovering the individual tests + if stream.into_iter().any(|token| { + matches!( + token, + TokenTree::Ident(i) if i.to_string() == "no_crate_inject", + ) + }) { + opts.no_crate_inject = true; + break 'main; + } + } } - // NOTE: `test(attr(..))` is handled when discovering the individual tests } opts diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 4d3f976c2a6d..e119344a806a 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -2,16 +2,18 @@ use std::cell::Cell; use std::env; +use std::str::FromStr; use std::sync::Arc; -use rustc_ast_pretty::pprust; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; -use rustc_hir::{self as hir, CRATE_HIR_ID, intravisit}; +use rustc_hir::{self as hir, Attribute, CRATE_HIR_ID, intravisit}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; +use rustc_proc_macro::{TokenStream, TokenTree}; use rustc_resolve::rustdoc::span_of_fragments; use rustc_span::source_map::SourceMap; -use rustc_span::{BytePos, DUMMY_SP, FileName, Pos, Span, sym}; +use rustc_span::{BytePos, DUMMY_SP, FileName, Pos, Span}; use super::{DocTestVisitor, ScrapedDocTest}; use crate::clean::{Attributes, CfgInfo, extract_cfg_from_attrs}; @@ -126,23 +128,46 @@ impl HirCollector<'_> { return; } + let source_map = self.tcx.sess.source_map(); // Try collecting `#[doc(test(attr(...)))]` let old_global_crate_attrs_len = self.collector.global_crate_attrs.len(); - for doc_test_attrs in ast_attrs - .iter() - .filter(|a| a.has_name(sym::doc)) - .flat_map(|a| a.meta_item_list().unwrap_or_default()) - .filter(|a| a.has_name(sym::test)) - { - let Some(doc_test_attrs) = doc_test_attrs.meta_item_list() else { continue }; - for attr in doc_test_attrs - .iter() - .filter(|a| a.has_name(sym::attr)) - .flat_map(|a| a.meta_item_list().unwrap_or_default()) - .map(pprust::meta_list_item_to_string) - { - // Add the additional attributes to the global_crate_attrs vector - self.collector.global_crate_attrs.push(attr); + for attr in ast_attrs { + let Attribute::Parsed(AttributeKind::Doc(d)) = attr else { continue }; + for attr_span in &d.test_attrs { + // FIXME: This is ugly, remove when `test_attrs` has been ported to new attribute API. + if let Ok(snippet) = source_map.span_to_snippet(*attr_span) + && let Ok(stream) = TokenStream::from_str(&snippet) + { + let mut iter = stream.into_iter().peekable(); + while let Some(token) = iter.next() { + if let TokenTree::Ident(i) = token { + let i = i.to_string(); + let peek = iter.peek(); + match peek { + Some(TokenTree::Group(g)) => { + let g = g.to_string(); + iter.next(); + // Add the additional attributes to the global_crate_attrs vector + self.collector.global_crate_attrs.push(format!("{i}{g}")); + } + Some(TokenTree::Punct(p)) if p.as_char() == '=' => { + let p = p.to_string(); + iter.next(); + if let Some(last) = iter.next() { + // Add the additional attributes to the global_crate_attrs vector + self.collector + .global_crate_attrs + .push(format!("{i}{p}{last}")); + } + } + _ => { + // Add the additional attributes to the global_crate_attrs vector + self.collector.global_crate_attrs.push(i.to_string()); + } + } + } + } + } } } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index e42997d5b4a1..3d4dff4a17d2 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -8,11 +8,13 @@ use std::sync::mpsc::{Receiver, channel}; use askama::Template; use rustc_ast::join_path_syms; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_hir::Attribute; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{DefIdMap, LOCAL_CRATE}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; -use rustc_span::{BytePos, FileName, Symbol, sym}; +use rustc_span::{BytePos, FileName, Symbol}; use tracing::info; use super::print_item::{full_path, print_item, print_item_path}; @@ -260,7 +262,9 @@ impl<'tcx> Context<'tcx> { short_title, description: &desc, resource_suffix: &self.shared.resource_suffix, - rust_logo: has_doc_flag(self.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo), + rust_logo: has_doc_flag(self.tcx(), LOCAL_CRATE.as_def_id(), |d| { + d.rust_logo.is_some() + }), }; layout::render( &self.shared.layout, @@ -522,27 +526,25 @@ impl<'tcx> Context<'tcx> { // Crawl the crate attributes looking for attributes which control how we're // going to emit HTML - for attr in krate.module.attrs.lists(sym::doc) { - match (attr.name(), attr.value_str()) { - (Some(sym::html_favicon_url), Some(s)) => { - layout.favicon = s.to_string(); - } - (Some(sym::html_logo_url), Some(s)) => { - layout.logo = s.to_string(); - } - (Some(sym::html_playground_url), Some(s)) => { - playground = Some(markdown::Playground { - crate_name: Some(krate.name(tcx)), - url: s.to_string(), - }); - } - (Some(sym::issue_tracker_base_url), Some(s)) => { - issue_tracker_base_url = Some(s.to_string()); - } - (Some(sym::html_no_source), None) if attr.is_word() => { - include_sources = false; - } - _ => {} + for attr in &krate.module.attrs.other_attrs { + let Attribute::Parsed(AttributeKind::Doc(d)) = attr else { continue }; + if let Some((html_favicon_url, _)) = d.html_favicon_url { + layout.favicon = html_favicon_url.to_string(); + } + if let Some((html_logo_url, _)) = d.html_logo_url { + layout.logo = html_logo_url.to_string(); + } + if let Some((html_playground_url, _)) = d.html_playground_url { + playground = Some(markdown::Playground { + crate_name: Some(krate.name(tcx)), + url: html_playground_url.to_string(), + }); + } + if let Some((s, _)) = d.issue_tracker_base_url { + issue_tracker_base_url = Some(s.to_string()); + } + if d.html_no_source.is_some() { + include_sources = false; } } @@ -645,7 +647,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { static_root_path: shared.static_root_path.as_deref(), description: "List of all items in this crate", resource_suffix: &shared.resource_suffix, - rust_logo: has_doc_flag(self.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo), + rust_logo: has_doc_flag(self.tcx(), LOCAL_CRATE.as_def_id(), |d| d.rust_logo.is_some()), }; let all = shared.all.replace(AllTypes::new()); let mut sidebar = String::new(); diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index a4cbef8c3917..12b207dda569 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -1609,7 +1609,9 @@ pub(crate) fn build_index( let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache; let search_unbox = match id { RenderTypeId::Mut => false, - RenderTypeId::DefId(defid) => utils::has_doc_flag(tcx, defid, sym::search_unbox), + RenderTypeId::DefId(defid) => { + utils::has_doc_flag(tcx, defid, |d| d.search_unbox.is_some()) + } RenderTypeId::Primitive( PrimitiveType::Reference | PrimitiveType::RawPointer | PrimitiveType::Tuple, ) => true, diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index f04f94432b80..55f8ddab25b1 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, sym}; +use rustc_span::{FileName, FileNameDisplayPreference, RealFileName}; use tracing::info; use super::render::Context; @@ -236,7 +236,9 @@ impl SourceCollector<'_, '_> { static_root_path: shared.static_root_path.as_deref(), description: &desc, resource_suffix: &shared.resource_suffix, - rust_logo: has_doc_flag(self.cx.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo), + rust_logo: has_doc_flag(self.cx.tcx(), LOCAL_CRATE.as_def_id(), |d| { + d.rust_logo.is_some() + }), }; let source_context = SourceContext::Standalone { file_path }; let v = layout::render( diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e4601bfb20d7..a0e359032f9b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -32,11 +32,9 @@ extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_attr_parsing; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; -extern crate rustc_expand; extern crate rustc_feature; extern crate rustc_hir; extern crate rustc_hir_analysis; diff --git a/src/librustdoc/passes/check_doc_cfg.rs b/src/librustdoc/passes/check_doc_cfg.rs index 3284da77a022..63dc375a13c6 100644 --- a/src/librustdoc/passes/check_doc_cfg.rs +++ b/src/librustdoc/passes/check_doc_cfg.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused_imports)] + use rustc_hir::HirId; use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::TyCtxt; @@ -14,63 +16,59 @@ pub(crate) const CHECK_DOC_CFG: Pass = Pass { description: "checks `#[doc(cfg(...))]` for stability feature and unexpected cfgs", }; -pub(crate) fn check_doc_cfg(krate: Crate, cx: &mut DocContext<'_>) -> Crate { - let mut checker = DocCfgChecker { cx }; - checker.visit_crate(&krate); +pub(crate) fn check_doc_cfg(krate: Crate, _cx: &mut DocContext<'_>) -> Crate { + // let mut checker = DocCfgChecker { cx }; + // checker.visit_crate(&krate); krate } -struct RustdocCfgMatchesLintEmitter<'a>(TyCtxt<'a>, HirId); +// struct RustdocCfgMatchesLintEmitter<'a>(TyCtxt<'a>, HirId); -impl<'a> rustc_attr_parsing::CfgMatchesLintEmitter for RustdocCfgMatchesLintEmitter<'a> { - fn emit_span_lint( - &self, - sess: &rustc_session::Session, - lint: &'static rustc_lint::Lint, - sp: rustc_span::Span, - builtin_diag: rustc_lint_defs::BuiltinLintDiag, - ) { - self.0.node_span_lint(lint, self.1, sp, |diag| { - rustc_lint::decorate_builtin_lint(sess, Some(self.0), builtin_diag, diag) - }); - } -} +// impl<'a> rustc_attr_parsing::CfgMatchesLintEmitter for RustdocCfgMatchesLintEmitter<'a> { +// fn emit_span_lint( +// &self, +// sess: &rustc_session::Session, +// lint: &'static rustc_lint::Lint, +// sp: rustc_span::Span, +// builtin_diag: rustc_lint_defs::BuiltinLintDiag, +// ) { +// self.0.node_span_lint(lint, self.1, sp, |diag| { +// rustc_lint::decorate_builtin_lint(sess, Some(self.0), builtin_diag, diag) +// }); +// } +// } -struct DocCfgChecker<'a, 'tcx> { - cx: &'a mut DocContext<'tcx>, -} +// struct DocCfgChecker<'a, 'tcx> { +// cx: &'a mut DocContext<'tcx>, +// } -impl DocCfgChecker<'_, '_> { - fn check_attrs(&mut self, attrs: &Attributes, did: LocalDefId) { - let doc_cfgs = attrs - .other_attrs - .iter() - .filter(|attr| attr.has_name(sym::doc)) - .flat_map(|attr| attr.meta_item_list().unwrap_or_default()) - .filter(|attr| attr.has_name(sym::cfg)); +// impl DocCfgChecker<'_, '_> { +// fn check_attrs(&mut self, attrs: &Attributes, did: LocalDefId) { +// for attr in &attrs.other_attrs { +// let Attribute::Parsed(AttributeKind::Doc(d)) = attr else { continue }; +// let Some(doc_cfg) = d.cfg else { continue }; - for doc_cfg in doc_cfgs { - if let Some([cfg_mi]) = doc_cfg.meta_item_list() { - let _ = rustc_attr_parsing::cfg_matches( - cfg_mi, - &self.cx.tcx.sess, - RustdocCfgMatchesLintEmitter( - self.cx.tcx, - self.cx.tcx.local_def_id_to_hir_id(did), - ), - Some(self.cx.tcx.features()), - ); - } - } - } -} +// if let Some([cfg_mi]) = doc_cfg.meta_item_list() { +// let _ = rustc_attr_parsing::cfg_matches( +// cfg_mi, +// &self.cx.tcx.sess, +// RustdocCfgMatchesLintEmitter( +// self.cx.tcx, +// self.cx.tcx.local_def_id_to_hir_id(did), +// ), +// Some(self.cx.tcx.features()), +// ); +// } +// } +// } +// } -impl DocVisitor<'_> for DocCfgChecker<'_, '_> { - fn visit_item(&mut self, item: &'_ Item) { - if let Some(Some(local_did)) = item.def_id().map(|did| did.as_local()) { - self.check_attrs(&item.attrs, local_did); - } +// impl DocVisitor<'_> for DocCfgChecker<'_, '_> { +// fn visit_item(&mut self, item: &'_ Item) { +// if let Some(Some(local_did)) = item.def_id().map(|did| did.as_local()) { +// self.check_attrs(&item.attrs, local_did); +// } - self.visit_item_recur(item); - } -} +// self.visit_item_recur(item); +// } +// } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 2339a6b69cd8..d71c3eaa2dcb 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -3,9 +3,10 @@ //! struct implements that trait. use rustc_data_structures::fx::FxHashSet; +use rustc_hir::Attribute; +use rustc_hir::attrs::{AttributeKind, DocAttribute}; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE}; use rustc_middle::ty; -use rustc_span::symbol::sym; use tracing::debug; use super::Pass; @@ -65,17 +66,14 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> for &impl_def_id in tcx.trait_impls_in_crate(LOCAL_CRATE) { let mut parent = Some(tcx.parent(impl_def_id)); while let Some(did) = parent { - attr_buf.extend( - tcx.get_attrs(did, sym::doc) - .filter(|attr| { - if let Some([attr]) = attr.meta_item_list().as_deref() { - attr.has_name(sym::cfg) - } else { - false - } - }) - .cloned(), - ); + attr_buf.extend(tcx.get_all_attrs(did).iter().filter_map(|attr| match attr { + Attribute::Parsed(AttributeKind::Doc(d)) if d.cfg.is_some() => { + let mut new_attr = DocAttribute::default(); + new_attr.cfg = d.cfg.clone(); + Some(Attribute::Parsed(AttributeKind::Doc(Box::new(new_attr)))) + } + _ => None, + })); parent = tcx.opt_parent(did); } cx.with_param_env(impl_def_id, |cx| { diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index c0b48ab51c7e..422393592c76 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -1,8 +1,7 @@ //! Propagates [`#[doc(cfg(...))]`](https://github.com/rust-lang/rust/issues/43781) to child items. -use rustc_ast::token::{Token, TokenKind}; -use rustc_ast::tokenstream::{TokenStream, TokenTree}; -use rustc_hir::{AttrArgs, Attribute}; +use rustc_hir::Attribute; +use rustc_hir::attrs::{AttributeKind, DocAttribute}; use rustc_span::symbol::sym; use crate::clean::inline::{load_attrs, merge_attrs}; @@ -30,59 +29,22 @@ struct CfgPropagator<'a, 'tcx> { cfg_info: CfgInfo, } -/// Returns true if the provided `token` is a `cfg` ident. -fn is_cfg_token(token: &TokenTree) -> bool { - // We only keep `doc(cfg)` items. - matches!(token, TokenTree::Token(Token { kind: TokenKind::Ident(sym::cfg, _,), .. }, _,),) -} - -/// We only want to keep `#[cfg()]` and `#[doc(cfg())]` attributes so we rebuild a vec of -/// `TokenTree` with only the tokens we're interested into. -fn filter_non_cfg_tokens_from_list(args_tokens: &TokenStream) -> Vec { - let mut tokens = Vec::with_capacity(args_tokens.len()); - let mut skip_next_delimited = false; - for token in args_tokens.iter() { - match token { - TokenTree::Delimited(..) => { - if !skip_next_delimited { - tokens.push(token.clone()); - } - skip_next_delimited = false; - } - token if is_cfg_token(token) => { - skip_next_delimited = false; - tokens.push(token.clone()); - } - _ => { - skip_next_delimited = true; - } - } - } - tokens -} - /// This function goes through the attributes list (`new_attrs`) and extract the `cfg` tokens from /// it and put them into `attrs`. fn add_only_cfg_attributes(attrs: &mut Vec, new_attrs: &[Attribute]) { for attr in new_attrs { - if attr.is_doc_comment().is_some() { - continue; - } - let mut attr = attr.clone(); - if let Attribute::Unparsed(ref mut normal) = attr - && let [ident] = &*normal.path.segments + if let Attribute::Parsed(AttributeKind::Doc(d)) = attr + && d.cfg.is_some() { - let ident = ident.name; - if ident == sym::doc - && let AttrArgs::Delimited(args) = &mut normal.args - { - let tokens = filter_non_cfg_tokens_from_list(&args.tokens); - args.tokens = TokenStream::new(tokens); - attrs.push(attr); - } else if ident == sym::cfg_trace { - // If it's a `cfg()` attribute, we keep it. - attrs.push(attr); - } + let mut new_attr = DocAttribute::default(); + new_attr.cfg = d.cfg.clone(); + attrs.push(Attribute::Parsed(AttributeKind::Doc(Box::new(new_attr)))); + } else if let Attribute::Unparsed(normal) = attr + && let [ident] = &*normal.path.segments + && ident.name == sym::cfg_trace + { + // If it's a `cfg()` attribute, we keep it. + attrs.push(attr.clone()); } } } From 04bcd83eb5b987afd5b7d43f82c0b5eb2df62767 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Nov 2025 20:51:12 +0100 Subject: [PATCH 0509/3801] Move `doc = ""` parsing out of `DocParser` to keep doc attributes order --- .../rustc_attr_parsing/src/attributes/doc.rs | 28 +++----------- compiler/rustc_attr_parsing/src/interface.rs | 37 ++++++++++++++++++- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 65651e617179..fbe1ac63ab9c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -2,7 +2,6 @@ #![allow(unused_imports)] use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit}; -use rustc_ast::token::CommentKind; use rustc_errors::MultiSpan; use rustc_feature::template; use rustc_hir::attrs::{ @@ -81,19 +80,10 @@ fn parse_keyword_and_attribute<'c, S, F>( *attr_value = Some((value, path.span())); } -#[derive(Debug)] -struct DocComment { - style: AttrStyle, - kind: CommentKind, - span: Span, - comment: Symbol, -} - #[derive(Default, Debug)] pub(crate) struct DocParser { attribute: DocAttribute, nb_doc_attrs: usize, - doc_comment: Option, } impl DocParser { @@ -481,17 +471,11 @@ impl DocParser { } } ArgParser::NameValue(nv) => { - let Some(comment) = nv.value_as_str() else { + if nv.value_as_str().is_none() { cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); - return; - }; - - self.doc_comment = Some(DocComment { - style: cx.attr_style, - kind: CommentKind::Block, - span: nv.value_span, - comment, - }); + } else { + unreachable!("Should have been handled at the same time as sugar-syntaxed doc comments"); + } } } } @@ -537,9 +521,7 @@ impl AttributeParser for DocParser { ]); fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { - if let Some(DocComment { style, kind, span, comment }) = self.doc_comment { - Some(AttributeKind::DocComment { style, kind, span, comment }) - } else if self.nb_doc_attrs != 0 { + if self.nb_doc_attrs != 0 { Some(AttributeKind::Doc(Box::new(self.attribute))) } else { None diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 363e1fcac507..feb7bbcb6234 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use rustc_ast as ast; use rustc_ast::{AttrStyle, NodeId, Safety}; +use rustc_ast::token::CommentKind; use rustc_errors::DiagCtxtHandle; use rustc_feature::{AttributeTemplate, Features}; use rustc_hir::attrs::AttributeKind; @@ -281,7 +282,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { // that's expanded right? But no, sometimes, when parsing attributes on macros, // we already use the lowering logic and these are still there. So, when `omit_doc` // is set we *also* want to ignore these. - if omit_doc == OmitDoc::Skip && attr.has_name(sym::doc) { + let is_doc_attribute = attr.has_name(sym::doc); + if omit_doc == OmitDoc::Skip && is_doc_attribute { continue; } @@ -323,6 +325,39 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { continue; }; let args = parser.args(); + + // Special-case handling for `#[doc = "..."]`: if we go through with + // `DocParser`, the order of doc comments will be messed up because `///` + // doc comments are added into `attributes` whereas attributes parsed with + // `DocParser` are added into `parsed_attributes` which are then appended + // to `attributes`. So if you have: + // + // /// bla + // #[doc = "a"] + // /// blob + // + // You would get: + // + // bla + // blob + // a + if is_doc_attribute + && let ArgParser::NameValue(nv) = args + // If not a string key/value, it should emit an error, but to make + // things simpler, it's handled in `DocParser` because it's simpler to + // emit an error with `AcceptContext`. + && let Some(comment) = nv.value_as_str() + { + attributes.push(Attribute::Parsed(AttributeKind::DocComment { + style: attr.style, + kind: CommentKind::Block, + span: nv.value_span, + comment, + })); + continue; + } + + let path = parser.path(); for accept in accepts { let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext { shared: SharedContext { From 148e522112d65d23c8615e22da65a64e319674bb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Nov 2025 16:08:24 +0100 Subject: [PATCH 0510/3801] Correctly differentiate between sugared and raw doc comments --- compiler/rustc_ast/src/attr/mod.rs | 47 +++++++++++++++---- compiler/rustc_ast/src/token.rs | 26 +++++++++- compiler/rustc_ast_pretty/src/pprust/state.rs | 32 +++++++++---- .../rustc_attr_parsing/src/attributes/doc.rs | 4 +- compiler/rustc_attr_parsing/src/interface.rs | 8 ++-- .../rustc_hir/src/attrs/data_structures.rs | 4 +- .../rustc_hir/src/attrs/pretty_printing.rs | 3 +- compiler/rustc_hir/src/hir.rs | 8 ++-- compiler/rustc_resolve/src/rustdoc.rs | 42 +++++++---------- src/librustdoc/clean/types.rs | 2 +- 10 files changed, 117 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index d54d900128bd..94e7462d26df 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -13,7 +13,9 @@ use crate::ast::{ Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NormalAttr, Path, PathSegment, Safety, }; -use crate::token::{self, CommentKind, Delimiter, InvisibleOrigin, MetaVarKind, Token}; +use crate::token::{ + self, CommentKind, Delimiter, DocFragmentKind, InvisibleOrigin, MetaVarKind, Token, +}; use crate::tokenstream::{ DelimSpan, LazyAttrTokenStream, Spacing, TokenStream, TokenStreamIter, TokenTree, }; @@ -179,15 +181,21 @@ impl AttributeExt for Attribute { } /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment. - /// * `///doc` returns `Some(("doc", CommentKind::Line))`. - /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`. - /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`. + /// * `///doc` returns `Some(("doc", DocFragmentKind::Sugared(CommentKind::Line)))`. + /// * `/** doc */` returns `Some(("doc", DocFragmentKind::Sugared(CommentKind::Block)))`. + /// * `#[doc = "doc"]` returns `Some(("doc", DocFragmentKind::Raw))`. /// * `#[doc(...)]` returns `None`. - fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { + fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { match &self.kind { - AttrKind::DocComment(kind, data) => Some((*data, *kind)), + AttrKind::DocComment(kind, data) => Some((*data, DocFragmentKind::Sugared(*kind))), AttrKind::Normal(normal) if normal.item.path == sym::doc => { - normal.item.value_str().map(|s| (s, CommentKind::Line)) + if let Some(value) = normal.item.value_str() + && let Some(value_span) = normal.item.value_span() + { + Some((value, DocFragmentKind::Raw(value_span))) + } else { + None + } } _ => None, } @@ -305,6 +313,25 @@ impl AttrItem { } } + /// Returns the span in: + /// + /// ```text + /// #[attribute = "value"] + /// ^^^^^^^ + /// ``` + /// + /// It returns `None` in any other cases like: + /// + /// ```text + /// #[attr("value")] + /// ``` + fn value_span(&self) -> Option { + match &self.args { + AttrArgs::Eq { expr, .. } => Some(expr.span), + AttrArgs::Delimited(_) | AttrArgs::Empty => None, + } + } + pub fn meta(&self, span: Span) -> Option { Some(MetaItem { unsafety: Safety::Default, @@ -825,7 +852,7 @@ pub trait AttributeExt: Debug { /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`. /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`. /// * `#[doc(...)]` returns `None`. - fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)>; + fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)>; /// Returns outer or inner if this is a doc attribute or a sugared doc /// comment, otherwise None. @@ -910,7 +937,7 @@ impl Attribute { AttributeExt::is_proc_macro_attr(self) } - pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { - AttributeExt::doc_str_and_comment_kind(self) + pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { + AttributeExt::doc_str_and_fragment_kind(self) } } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index e1231312a2af..accf4d181632 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -16,7 +16,31 @@ use rustc_span::{Ident, Symbol}; use crate::ast; use crate::util::case::Case; -#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +/// Represents the kind of doc comment it is, ie `///` or `#[doc = ""]`. +#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum DocFragmentKind { + /// A sugared doc comment: `///` or `//!` or `/**` or `/*!`. + Sugared(CommentKind), + /// A "raw" doc comment: `#[doc = ""]`. The `Span` represents the string literal. + Raw(Span), +} + +impl DocFragmentKind { + pub fn is_sugared(self) -> bool { + matches!(self, Self::Sugared(_)) + } + + /// If it is `Sugared`, it will return its associated `CommentKind`, otherwise it will return + /// `CommentKind::Line`. + pub fn comment_kind(self) -> CommentKind { + match self { + Self::Sugared(kind) => kind, + Self::Raw(_) => CommentKind::Line, + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum CommentKind { Line, Block, diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 3dce0498efbf..35e47fed9f7a 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -10,7 +10,7 @@ use std::borrow::Cow; use std::sync::Arc; use rustc_ast::attr::AttrIdGenerator; -use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind}; +use rustc_ast::token::{self, CommentKind, Delimiter, DocFragmentKind, Token, TokenKind}; use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{Comment, CommentStyle}; @@ -381,15 +381,24 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool { } pub fn doc_comment_to_string( - comment_kind: CommentKind, + fragment_kind: DocFragmentKind, attr_style: ast::AttrStyle, data: Symbol, ) -> String { - match (comment_kind, attr_style) { - (CommentKind::Line, ast::AttrStyle::Outer) => format!("///{data}"), - (CommentKind::Line, ast::AttrStyle::Inner) => format!("//!{data}"), - (CommentKind::Block, ast::AttrStyle::Outer) => format!("/**{data}*/"), - (CommentKind::Block, ast::AttrStyle::Inner) => format!("/*!{data}*/"), + match fragment_kind { + DocFragmentKind::Sugared(comment_kind) => match (comment_kind, attr_style) { + (CommentKind::Line, ast::AttrStyle::Outer) => format!("///{data}"), + (CommentKind::Line, ast::AttrStyle::Inner) => format!("//!{data}"), + (CommentKind::Block, ast::AttrStyle::Outer) => format!("/**{data}*/"), + (CommentKind::Block, ast::AttrStyle::Inner) => format!("/*!{data}*/"), + }, + DocFragmentKind::Raw(_) => { + format!( + "#{}[doc = {:?}]", + if attr_style == ast::AttrStyle::Inner { "!" } else { "" }, + data.to_string(), + ) + } } } @@ -665,7 +674,11 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.word("]"); } ast::AttrKind::DocComment(comment_kind, data) => { - self.word(doc_comment_to_string(*comment_kind, attr.style, *data)); + self.word(doc_comment_to_string( + DocFragmentKind::Sugared(*comment_kind), + attr.style, + *data, + )); self.hardbreak() } } @@ -1029,7 +1042,8 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere /* Other */ token::DocComment(comment_kind, attr_style, data) => { - doc_comment_to_string(comment_kind, attr_style, data).into() + doc_comment_to_string(DocFragmentKind::Sugared(comment_kind), attr_style, data) + .into() } token::Eof => "".into(), } diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index fbe1ac63ab9c..1a7d8ec93f70 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -474,7 +474,9 @@ impl DocParser { if nv.value_as_str().is_none() { cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); } else { - unreachable!("Should have been handled at the same time as sugar-syntaxed doc comments"); + unreachable!( + "Should have been handled at the same time as sugar-syntaxed doc comments" + ); } } } diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index feb7bbcb6234..b1538b447da0 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use rustc_ast as ast; use rustc_ast::{AttrStyle, NodeId, Safety}; -use rustc_ast::token::CommentKind; +use rustc_ast::token::DocFragmentKind; use rustc_errors::DiagCtxtHandle; use rustc_feature::{AttributeTemplate, Features}; use rustc_hir::attrs::AttributeKind; @@ -295,7 +295,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attributes.push(Attribute::Parsed(AttributeKind::DocComment { style: attr.style, - kind: *comment_kind, + kind: DocFragmentKind::Sugared(*comment_kind), span: lower_span(attr.span), comment: *symbol, })) @@ -350,8 +350,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { { attributes.push(Attribute::Parsed(AttributeKind::DocComment { style: attr.style, - kind: CommentKind::Block, - span: nv.value_span, + kind: DocFragmentKind::Raw(nv.value_span), + span: attr.span, comment, })); continue; diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 39008914f9ef..87a4cf7823f5 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; pub use ReprAttr::*; use rustc_abi::Align; -use rustc_ast::token::CommentKind; +use rustc_ast::token::DocFragmentKind; use rustc_ast::{AttrStyle, ast}; use rustc_data_structures::fx::FxIndexMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; @@ -648,7 +648,7 @@ pub enum AttributeKind { /// Represents specifically [`#[doc = "..."]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). /// i.e. doc comments. - DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol }, + DocComment { style: AttrStyle, kind: DocFragmentKind, span: Span, comment: Symbol }, /// Represents `#[rustc_dummy]`. Dummy, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index 75886fb08a2e..29df586ed296 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -1,7 +1,7 @@ use std::num::NonZero; use rustc_abi::Align; -use rustc_ast::token::CommentKind; +use rustc_ast::token::{CommentKind, DocFragmentKind}; use rustc_ast::{AttrStyle, IntTy, UintTy}; use rustc_ast_pretty::pp::Printer; use rustc_data_structures::fx::FxIndexMap; @@ -167,6 +167,7 @@ print_debug!( Align, AttrStyle, CommentKind, + DocFragmentKind, Transparency, SanitizerSet, ); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e6a0f430b63a..afa1a33fe769 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4,7 +4,7 @@ use std::fmt; use rustc_abi::ExternAbi; use rustc_ast::attr::AttributeExt; -use rustc_ast::token::CommentKind; +use rustc_ast::token::DocFragmentKind; use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::{ self as ast, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitIntType, @@ -1385,7 +1385,7 @@ impl AttributeExt for Attribute { } #[inline] - fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { + fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { match &self { Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => { Some((*comment, *kind)) @@ -1503,8 +1503,8 @@ impl Attribute { } #[inline] - pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { - AttributeExt::doc_str_and_comment_kind(self) + pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { + AttributeExt::doc_str_and_fragment_kind(self) } } diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 3c0a89b7c8a7..0ac8e68ad968 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -10,6 +10,7 @@ use pulldown_cmark::{ use rustc_ast as ast; use rustc_ast::attr::AttributeExt; use rustc_ast::join_path_syms; +use rustc_ast::token::DocFragmentKind; use rustc_ast::util::comments::beautify_doc_string; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordSet; @@ -23,14 +24,6 @@ use tracing::{debug, trace}; #[cfg(test)] mod tests; -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum DocFragmentKind { - /// A doc fragment created from a `///` or `//!` doc comment. - SugaredDoc, - /// A doc fragment created from a "raw" `#[doc=""]` attribute. - RawDoc, -} - /// A portion of documentation, extracted from a `#[doc]` attribute. /// /// Each variant contains the line number within the complete doc-comment where the fragment @@ -125,7 +118,7 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) { // // In this case, you want "hello! another" and not "hello! another". let add = if docs.windows(2).any(|arr| arr[0].kind != arr[1].kind) - && docs.iter().any(|d| d.kind == DocFragmentKind::SugaredDoc) + && docs.iter().any(|d| d.kind.is_sugared()) { // In case we have a mix of sugared doc comments and "raw" ones, we want the sugared one to // "decide" how much the minimum indent will be. @@ -155,8 +148,7 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) { // Compare against either space or tab, ignoring whether they are // mixed or not. let whitespace = line.chars().take_while(|c| *c == ' ' || *c == '\t').count(); - whitespace - + (if fragment.kind == DocFragmentKind::SugaredDoc { 0 } else { add }) + whitespace + (if fragment.kind.is_sugared() { 0 } else { add }) }) .min() .unwrap_or(usize::MAX) @@ -171,7 +163,7 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) { continue; } - let indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 { + let indent = if !fragment.kind.is_sugared() && min_indent > 0 { min_indent - add } else { min_indent @@ -214,19 +206,17 @@ pub fn attrs_to_doc_fragments<'a, A: AttributeExt + Clone + 'a>( let mut doc_fragments = Vec::with_capacity(size_hint); let mut other_attrs = ThinVec::::with_capacity(if doc_only { 0 } else { size_hint }); for (attr, item_id) in attrs { - if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() { - let doc = beautify_doc_string(doc_str, comment_kind); - let (span, kind, from_expansion) = if let Some(span) = attr.is_doc_comment() { - (span, DocFragmentKind::SugaredDoc, span.from_expansion()) - } else { - let attr_span = attr.span(); - let (span, from_expansion) = match attr.value_span() { - Some(sp) => (sp.with_ctxt(attr_span.ctxt()), sp.from_expansion()), - None => (attr_span, attr_span.from_expansion()), - }; - (span, DocFragmentKind::RawDoc, from_expansion) + if let Some((doc_str, fragment_kind)) = attr.doc_str_and_fragment_kind() { + let doc = beautify_doc_string(doc_str, fragment_kind.comment_kind()); + let attr_span = attr.span(); + let (span, from_expansion) = match fragment_kind { + DocFragmentKind::Sugared(_) => (attr_span, attr_span.from_expansion()), + DocFragmentKind::Raw(value_span) => { + (value_span.with_ctxt(attr_span.ctxt()), value_span.from_expansion()) + } }; - let fragment = DocFragment { span, doc, kind, item_id, indent: 0, from_expansion }; + let fragment = + DocFragment { span, doc, kind: fragment_kind, item_id, indent: 0, from_expansion }; doc_fragments.push(fragment); } else if !doc_only { other_attrs.push(attr.clone()); @@ -571,7 +561,7 @@ pub fn source_span_for_markdown_range_inner( use rustc_span::BytePos; if let &[fragment] = &fragments - && fragment.kind == DocFragmentKind::RawDoc + && !fragment.kind.is_sugared() && let Ok(snippet) = map.span_to_snippet(fragment.span) && snippet.trim_end() == markdown.trim_end() && let Ok(md_range_lo) = u32::try_from(md_range.start) @@ -589,7 +579,7 @@ pub fn source_span_for_markdown_range_inner( )); } - let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc); + let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind.is_sugared()); if !is_all_sugared_doc { // This case ignores the markdown outside of the range so that it can diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 12dcb198bd21..40191d5c98e0 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2403,7 +2403,7 @@ mod size_asserts { use super::*; // tidy-alphabetical-start static_assert_size!(Crate, 16); // frequently moved by-value - static_assert_size!(DocFragment, 32); + static_assert_size!(DocFragment, 48); static_assert_size!(GenericArg, 32); static_assert_size!(GenericArgs, 24); static_assert_size!(GenericParamDef, 40); From 92edc499a69a24e69e6fcc2641dc9bca1098bd5b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Nov 2025 16:50:16 +0100 Subject: [PATCH 0511/3801] Correctly handle doc items inlining --- src/librustdoc/clean/mod.rs | 21 +++++++++++++-------- src/librustdoc/clean/types.rs | 31 ------------------------------- src/librustdoc/visit_ast.rs | 18 +++++++----------- 3 files changed, 20 insertions(+), 50 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6fd578628388..bea4398ccf86 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -196,9 +196,12 @@ fn generate_item_with_correct_attrs( // For glob re-exports the item may or may not exist to be re-exported (potentially the // cfgs on the path up until the glob can be removed, and only cfgs on the globbed item // itself matter), for non-inlined re-exports see #85043. - let import_is_inline = find_attr!(inline::load_attrs(cx, import_id.to_def_id()), AttributeKind::Doc(d) if d.inline.is_some()) - || (is_glob_import(cx.tcx, import_id) - && (cx.document_hidden() || !cx.tcx.is_doc_hidden(def_id))); + let import_is_inline = find_attr!( + inline::load_attrs(cx, import_id.to_def_id()), + AttributeKind::Doc(d) + if d.inline.is_some_and(|(inline, _)| inline == DocInline::Inline) + ) || (is_glob_import(cx.tcx, import_id) + && (cx.document_hidden() || !cx.tcx.is_doc_hidden(def_id))); attrs.extend(get_all_import_attributes(cx, import_id, def_id, is_inline)); is_inline = is_inline || import_is_inline; } @@ -2666,10 +2669,10 @@ fn add_without_unwanted_attributes<'hir>( let DocAttribute { hidden, inline, cfg, .. } = d; let mut attr = DocAttribute::default(); if is_inline { + attr.cfg = cfg.clone(); + } else { attr.inline = inline.clone(); attr.hidden = hidden.clone(); - } else { - attr.cfg = cfg.clone(); } attrs.push(( Cow::Owned(hir::Attribute::Parsed(AttributeKind::Doc(Box::new(attr)))), @@ -2914,10 +2917,12 @@ fn clean_extern_crate<'tcx>( let attrs = cx.tcx.hir_attrs(krate.hir_id()); let ty_vis = cx.tcx.visibility(krate.owner_id); let please_inline = ty_vis.is_public() - && attrs.iter().any(|a| matches!( + && attrs.iter().any(|a| { + matches!( a, - hir::Attribute::Parsed(AttributeKind::Doc(d)) if d.inline.is_some_and(|(i, _)| i == DocInline::Inline)) - ) + hir::Attribute::Parsed(AttributeKind::Doc(d)) + if d.inline.is_some_and(|(i, _)| i == DocInline::Inline)) + }) && !cx.is_json_output(); let krate_owner_def_id = krate.owner_id.def_id; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 40191d5c98e0..cefaf1102fb9 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -929,37 +929,6 @@ pub(crate) struct Module { pub(crate) span: Span, } -pub(crate) fn hir_attr_lists<'a, I: IntoIterator>( - attrs: I, - name: Symbol, -) -> impl Iterator + use<'a, I> { - attrs - .into_iter() - .filter(move |attr| attr.has_name(name)) - .filter_map(ast::attr::AttributeExt::meta_item_list) - .flatten() -} - -pub(crate) trait NestedAttributesExt { - /// Returns `true` if the attribute list contains a specific `word` - fn has_word(self, word: Symbol) -> bool - where - Self: Sized, - { - ::get_word_attr(self, word).is_some() - } - - /// Returns `Some(attr)` if the attribute list contains 'attr' - /// corresponding to a specific `word` - fn get_word_attr(self, word: Symbol) -> Option; -} - -impl> NestedAttributesExt for I { - fn get_word_attr(mut self, word: Symbol) -> Option { - self.find(|attr| attr.is_word() && attr.has_name(word)) - } -} - /// A link that has not yet been rendered. /// /// This link will be turned into a rendered link by [`Item::links`]. diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 51b2821eb1e5..d6da8615d57e 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -3,9 +3,10 @@ use std::mem; +use rustc_ast::attr::AttributeExt; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; -use rustc_hir::attrs::AttributeKind; +use rustc_hir::attrs::{AttributeKind, DocInline}; use rustc_hir::def::{DefKind, MacroKinds, Res}; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet}; use rustc_hir::intravisit::{Visitor, walk_body, walk_item}; @@ -14,11 +15,11 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::Span; use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; -use rustc_span::symbol::{Symbol, kw, sym}; +use rustc_span::symbol::{Symbol, kw}; use tracing::debug; +use crate::clean::reexport_chain; use crate::clean::utils::{inherits_doc_hidden, should_ignore_res}; -use crate::clean::{NestedAttributesExt, hir_attr_lists, reexport_chain}; use crate::core; /// This module is used to store stuff from Rust's AST in a more convenient @@ -246,8 +247,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let document_hidden = self.cx.document_hidden(); let use_attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. - let is_no_inline = hir_attr_lists(use_attrs, sym::doc).has_word(sym::no_inline) - || (document_hidden && hir_attr_lists(use_attrs, sym::doc).has_word(sym::hidden)); + let is_no_inline = find_attr!(use_attrs, AttributeKind::Doc(d) if d.inline.is_some_and(|(inline, _)| inline == DocInline::NoInline)) + || (document_hidden && use_attrs.iter().any(|attr| attr.is_doc_hidden())); if is_no_inline { return false; @@ -464,12 +465,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // If there was a private module in the current path then don't bother inlining // anything as it will probably be stripped anyway. if is_pub && self.inside_public_path { - let please_inline = attrs.iter().any(|item| match item.meta_item_list() { - Some(ref list) if item.has_name(sym::doc) => { - list.iter().any(|i| i.has_name(sym::inline)) - } - _ => false, - }); + let please_inline = find_attr!(attrs, AttributeKind::Doc(d) if d.inline.is_some_and(|(inline, _)| inline == DocInline::Inline)); let ident = match kind { hir::UseKind::Single(ident) => Some(ident.name), hir::UseKind::Glob => None, From 368a103902b00b4b0b93d30050ce2da7d5c2b0d9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Nov 2025 18:49:19 +0100 Subject: [PATCH 0512/3801] Fix `Cfg` add/or operations --- .../rustc_hir/src/attrs/data_structures.rs | 36 +++++++++++++++---- src/librustdoc/clean/cfg.rs | 24 ++++++------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 87a4cf7823f5..e35af0853651 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -197,14 +197,38 @@ pub enum CfgEntry { impl CfgEntry { pub fn span(&self) -> Span { - let (CfgEntry::All(_, span) - | CfgEntry::Any(_, span) - | CfgEntry::Not(_, span) - | CfgEntry::Bool(_, span) - | CfgEntry::NameValue { span, .. } - | CfgEntry::Version(_, span)) = self; + let (Self::All(_, span) + | Self::Any(_, span) + | Self::Not(_, span) + | Self::Bool(_, span) + | Self::NameValue { span, .. } + | Self::Version(_, span)) = self; *span } + + /// Same as `PartialEq` but doesn't check spans and ignore order of cfgs. + pub fn is_equivalent_to(&self, other: &Self) -> bool { + match (self, other) { + (Self::All(a, _), Self::All(b, _)) | (Self::Any(a, _), Self::Any(b, _)) => { + a.len() == b.len() && a.iter().all(|a| b.iter().any(|b| a.is_equivalent_to(b))) + } + (Self::Not(a, _), Self::Not(b, _)) => a.is_equivalent_to(b), + (Self::Bool(a, _), Self::Bool(b, _)) => a == b, + ( + Self::NameValue { name: name1, value: value1, .. }, + Self::NameValue { name: name2, value: value2, .. }, + ) => { + name1 == name2 + && match (value1, value2) { + (Some((a, _)), Some((b, _))) => a == b, + (None, None) => true, + _ => false, + } + } + (Self::Version(a, _), Self::Version(b, _)) => a == b, + _ => false, + } + } } /// Possible values for the `#[linkage]` attribute, allowing to specify the diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 38d3a47f8ca0..9b59e7ce6bef 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -280,13 +280,12 @@ impl Cfg { fn should_append_only_to_description(&self) -> bool { match self.0 { - CfgEntry::Bool(..) => false, CfgEntry::Any(..) | CfgEntry::All(..) | CfgEntry::NameValue { .. } - | CfgEntry::Version(..) => true, - CfgEntry::Not(box CfgEntry::NameValue { .. }, _) => true, - CfgEntry::Not(..) => false, + | CfgEntry::Version(..) + | CfgEntry::Not(box CfgEntry::NameValue { .. }, _) => true, + CfgEntry::Not(..) | CfgEntry::Bool(..) => false, } } @@ -347,25 +346,25 @@ impl ops::BitAndAssign for Cfg { (s @ CfgEntry::Bool(true, _), b) => *s = b, (CfgEntry::All(a, _), CfgEntry::All(ref mut b, _)) => { for c in b.drain(..) { - if !a.contains(&c) { + if !a.iter().any(|a| a.is_equivalent_to(&c)) { a.push(c); } } } (CfgEntry::All(a, _), ref mut b) => { - if !a.contains(b) { + if !a.iter().any(|a| a.is_equivalent_to(b)) { a.push(mem::replace(b, CfgEntry::Bool(true, DUMMY_SP))); } } (s, CfgEntry::All(mut a, _)) => { let b = mem::replace(s, CfgEntry::Bool(true, DUMMY_SP)); - if !a.contains(&b) { + if !a.iter().any(|a| a.is_equivalent_to(&b)) { a.push(b); } *s = CfgEntry::All(a, DUMMY_SP); } (s, b) => { - if *s != b { + if !s.is_equivalent_to(&b) { let a = mem::replace(s, CfgEntry::Bool(true, DUMMY_SP)); *s = CfgEntry::All(thin_vec![a, b], DUMMY_SP); } @@ -391,25 +390,25 @@ impl ops::BitOrAssign for Cfg { (s @ CfgEntry::Bool(false, _), b) => *s = b, (CfgEntry::Any(a, _), CfgEntry::Any(ref mut b, _)) => { for c in b.drain(..) { - if !a.contains(&c) { + if !a.iter().any(|a| a.is_equivalent_to(&c)) { a.push(c); } } } (CfgEntry::Any(a, _), ref mut b) => { - if !a.contains(b) { + if !a.iter().any(|a| a.is_equivalent_to(b)) { a.push(mem::replace(b, CfgEntry::Bool(true, DUMMY_SP))); } } (s, CfgEntry::Any(mut a, _)) => { let b = mem::replace(s, CfgEntry::Bool(true, DUMMY_SP)); - if !a.contains(&b) { + if !a.iter().any(|a| a.is_equivalent_to(&b)) { a.push(b); } *s = CfgEntry::Any(a, DUMMY_SP); } (s, b) => { - if *s != b { + if !s.is_equivalent_to(&b) { let a = mem::replace(s, CfgEntry::Bool(true, DUMMY_SP)); *s = CfgEntry::Any(thin_vec![a, b], DUMMY_SP); } @@ -757,6 +756,7 @@ fn handle_auto_cfg_hide_show( { for item in items { // FIXME: Report in case `Cfg::parse` reports an error? + let Ok(cfg) = Cfg::parse(item) else { continue }; if let CfgEntry::NameValue { name, value, .. } = cfg.0 { let value = value.map(|(v, _)| v); From d35ec316c5496b2eda68ba05b9dd28ba94bfa87e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 1 Dec 2025 15:31:10 +0100 Subject: [PATCH 0513/3801] Keep a list of `CfgEntry` instead of just one --- compiler/rustc_attr_parsing/src/attributes/doc.rs | 5 ++++- compiler/rustc_hir/src/attrs/data_structures.rs | 4 ++-- src/librustdoc/clean/cfg.rs | 12 ++++++------ src/librustdoc/passes/collect_trait_impls.rs | 2 +- src/librustdoc/passes/propagate_doc_cfg.rs | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 1a7d8ec93f70..5e48ade6b7cf 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -225,7 +225,7 @@ impl DocParser { args: &ArgParser<'_>, ) { if let Some(cfg_entry) = super::cfg::parse_cfg(cx, args) { - self.attribute.cfg = Some(cfg_entry); + self.attribute.cfg.push(cfg_entry); } } @@ -524,6 +524,9 @@ impl AttributeParser for DocParser { fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { if self.nb_doc_attrs != 0 { + if std::env::var("LOL").is_ok() { + eprintln!("+++++> {:#?}", self.attribute); + } Some(AttributeKind::Doc(Box::new(self.attribute))) } else { None diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index e35af0853651..323a1290bb2a 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -479,7 +479,7 @@ pub struct DocAttribute { pub inline: Option<(DocInline, Span)>, // unstable - pub cfg: Option, + pub cfg: ThinVec, pub auto_cfg: ThinVec, /// This is for `#[doc(auto_cfg = false|true)]`. pub auto_cfg_change: Option<(bool, Span)>, @@ -512,7 +512,7 @@ impl Default for DocAttribute { aliases: FxIndexMap::default(), hidden: None, inline: None, - cfg: None, + cfg: ThinVec::new(), auto_cfg: ThinVec::new(), auto_cfg_change: None, fake_variadic: None, diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 9b59e7ce6bef..727ad82eeca5 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -24,7 +24,7 @@ use crate::html::escape::Escape; #[cfg(test)] mod tests; -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Hash)] pub(crate) struct Cfg(CfgEntry); #[derive(PartialEq, Debug)] @@ -299,13 +299,13 @@ impl Cfg { /// /// See `tests::test_simplify_with` for examples. pub(crate) fn simplify_with(&self, assume: &Self) -> Option { - if self == assume { + if self.0.is_equivalent_to(&assume.0) { None } else if let CfgEntry::All(a, _) = &self.0 { let mut sub_cfgs: ThinVec = if let CfgEntry::All(b, _) = &assume.0 { - a.iter().filter(|a| !b.contains(a)).cloned().collect() + a.iter().filter(|a| !b.iter().any(|b| a.is_equivalent_to(b))).cloned().collect() } else { - a.iter().filter(|&a| *a != assume.0).cloned().collect() + a.iter().filter(|&a| !a.is_equivalent_to(&assume.0)).cloned().collect() }; let len = sub_cfgs.len(); match len { @@ -314,7 +314,7 @@ impl Cfg { _ => Some(Cfg(CfgEntry::All(sub_cfgs, DUMMY_SP))), } } else if let CfgEntry::All(b, _) = &assume.0 - && b.contains(&self.0) + && b.iter().any(|b| b.is_equivalent_to(&self.0)) { None } else { @@ -838,7 +838,7 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator cfg_info.parent_is_doc_cfg = true; } for attr in doc_cfg { - if let Some(new_cfg) = attr.cfg.clone() { + for new_cfg in attr.cfg.clone() { cfg_info.current_cfg &= Cfg(new_cfg); } } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index d71c3eaa2dcb..357d00ef6521 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -67,7 +67,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> let mut parent = Some(tcx.parent(impl_def_id)); while let Some(did) = parent { attr_buf.extend(tcx.get_all_attrs(did).iter().filter_map(|attr| match attr { - Attribute::Parsed(AttributeKind::Doc(d)) if d.cfg.is_some() => { + Attribute::Parsed(AttributeKind::Doc(d)) if !d.cfg.is_empty() => { let mut new_attr = DocAttribute::default(); new_attr.cfg = d.cfg.clone(); Some(Attribute::Parsed(AttributeKind::Doc(Box::new(new_attr)))) diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 422393592c76..95f5537f394c 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -34,7 +34,7 @@ struct CfgPropagator<'a, 'tcx> { fn add_only_cfg_attributes(attrs: &mut Vec, new_attrs: &[Attribute]) { for attr in new_attrs { if let Attribute::Parsed(AttributeKind::Doc(d)) = attr - && d.cfg.is_some() + && !d.cfg.is_empty() { let mut new_attr = DocAttribute::default(); new_attr.cfg = d.cfg.clone(); From 57870b7242e3b3446abad0bc1672b52a46d92e1f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 1 Dec 2025 17:03:39 +0100 Subject: [PATCH 0514/3801] Fix `doc(auto_cfg)` attribute parsing --- .../rustc_attr_parsing/src/attributes/doc.rs | 24 ++- .../rustc_hir/src/attrs/data_structures.rs | 8 +- src/librustdoc/clean/cfg.rs | 151 +++++++----------- 3 files changed, 82 insertions(+), 101 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 5e48ade6b7cf..fb99f43fced8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -224,7 +224,21 @@ impl DocParser { cx: &'c mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>, ) { - if let Some(cfg_entry) = super::cfg::parse_cfg(cx, args) { + // This function replaces cases like `cfg(all())` with `true`. + fn simplify_cfg(cfg_entry: &mut CfgEntry) { + match cfg_entry { + CfgEntry::All(cfgs, span) if cfgs.is_empty() => { + *cfg_entry = CfgEntry::Bool(true, *span) + } + CfgEntry::Any(cfgs, span) if cfgs.is_empty() => { + *cfg_entry = CfgEntry::Bool(false, *span) + } + CfgEntry::Not(cfg, _) => simplify_cfg(cfg), + _ => {} + } + } + if let Some(mut cfg_entry) = super::cfg::parse_cfg(cx, args) { + simplify_cfg(&mut cfg_entry); self.attribute.cfg.push(cfg_entry); } } @@ -237,7 +251,7 @@ impl DocParser { ) { match args { ArgParser::NoArgs => { - cx.expected_list(args.span().unwrap_or(path.span())); + self.attribute.auto_cfg_change.push((true, path.span())); } ArgParser::List(list) => { for meta in list.mixed() { @@ -303,6 +317,7 @@ impl DocParser { } } } + self.attribute.auto_cfg.push((cfg_hide_show, path.span())); } } ArgParser::NameValue(nv) => { @@ -311,7 +326,7 @@ impl DocParser { cx.emit_lint(AttributeLintKind::DocAutoCfgWrongLiteral, nv.value_span); return; }; - self.attribute.auto_cfg_change = Some((*bool_value, *span)); + self.attribute.auto_cfg_change.push((*bool_value, *span)); } } } @@ -524,9 +539,6 @@ impl AttributeParser for DocParser { fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { if self.nb_doc_attrs != 0 { - if std::env::var("LOL").is_ok() { - eprintln!("+++++> {:#?}", self.attribute); - } Some(AttributeKind::Doc(Box::new(self.attribute))) } else { None diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 323a1290bb2a..4e1de8e5aeae 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -480,9 +480,9 @@ pub struct DocAttribute { // unstable pub cfg: ThinVec, - pub auto_cfg: ThinVec, - /// This is for `#[doc(auto_cfg = false|true)]`. - pub auto_cfg_change: Option<(bool, Span)>, + pub auto_cfg: ThinVec<(CfgHideShow, Span)>, + /// This is for `#[doc(auto_cfg = false|true)]`/`#[doc(auto_cfg)]`. + pub auto_cfg_change: ThinVec<(bool, Span)>, // builtin pub fake_variadic: Option, @@ -514,7 +514,7 @@ impl Default for DocAttribute { inline: None, cfg: ThinVec::new(), auto_cfg: ThinVec::new(), - auto_cfg_change: None, + auto_cfg_change: ThinVec::new(), fake_variadic: None, keyword: None, attribute: None, diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 727ad82eeca5..292df1cf9550 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -10,13 +10,13 @@ use itertools::Either; use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::thin_vec::{ThinVec, thin_vec}; +use rustc_hir as hir; use rustc_hir::Attribute; -use rustc_hir::attrs::{AttributeKind, CfgEntry}; +use rustc_hir::attrs::{self, AttributeKind, CfgEntry, CfgHideShow, HideOrShow}; use rustc_middle::ty::TyCtxt; use rustc_session::parse::ParseSess; use rustc_span::symbol::{Symbol, sym}; use rustc_span::{DUMMY_SP, Span}; -use {rustc_ast as ast, rustc_hir as hir}; use crate::display::{Joined as _, MaybeDisplay, Wrapped}; use crate::html::escape::Escape; @@ -689,6 +689,12 @@ impl<'a> From<&'a CfgEntry> for SimpleCfg { } } +impl<'a> From<&'a attrs::CfgInfo> for SimpleCfg { + fn from(cfg: &'a attrs::CfgInfo) -> Self { + Self { name: cfg.name, value: cfg.value.map(|(value, _)| value) } + } +} + /// This type keeps track of (doc) cfg information as we go down the item tree. #[derive(Clone, Debug)] pub(crate) struct CfgInfo { @@ -746,37 +752,27 @@ fn show_hide_show_conflict_error( fn handle_auto_cfg_hide_show( tcx: TyCtxt<'_>, cfg_info: &mut CfgInfo, - sub_attr: &MetaItemInner, - is_show: bool, + attr: &CfgHideShow, + attr_span: Span, new_show_attrs: &mut FxHashMap<(Symbol, Option), rustc_span::Span>, new_hide_attrs: &mut FxHashMap<(Symbol, Option), rustc_span::Span>, ) { - if let MetaItemInner::MetaItem(item) = sub_attr - && let MetaItemKind::List(items) = &item.kind - { - for item in items { - // FIXME: Report in case `Cfg::parse` reports an error? - - let Ok(cfg) = Cfg::parse(item) else { continue }; - if let CfgEntry::NameValue { name, value, .. } = cfg.0 { - let value = value.map(|(v, _)| v); - let simple = SimpleCfg::from(&cfg.0); - if is_show { - if let Some(span) = new_hide_attrs.get(&(name, value)) { - show_hide_show_conflict_error(tcx, item.span(), *span); - } else { - new_show_attrs.insert((name, value), item.span()); - } - cfg_info.hidden_cfg.remove(&simple); - } else { - if let Some(span) = new_show_attrs.get(&(name, value)) { - show_hide_show_conflict_error(tcx, item.span(), *span); - } else { - new_hide_attrs.insert((name, value), item.span()); - } - cfg_info.hidden_cfg.insert(simple); - } + for value in &attr.values { + let simple = SimpleCfg::from(value); + if attr.kind == HideOrShow::Show { + if let Some(span) = new_hide_attrs.get(&(simple.name, simple.value)) { + show_hide_show_conflict_error(tcx, attr_span, *span); + } else { + new_show_attrs.insert((simple.name, simple.value), attr_span); } + cfg_info.hidden_cfg.remove(&simple); + } else { + if let Some(span) = new_show_attrs.get(&(simple.name, simple.value)) { + show_hide_show_conflict_error(tcx, attr_span, *span); + } else { + new_hide_attrs.insert((simple.name, simple.value), attr_span); + } + cfg_info.hidden_cfg.insert(simple); } } } @@ -797,7 +793,7 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator fn check_changed_auto_active_status( changed_auto_active_status: &mut Option, - attr: &ast::MetaItem, + attr_span: Span, cfg_info: &mut CfgInfo, tcx: TyCtxt<'_>, new_value: bool, @@ -807,14 +803,14 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator tcx.sess .dcx() .struct_span_err( - vec![*first_change, attr.span], + vec![*first_change, attr_span], "`auto_cfg` was disabled and enabled more than once on the same item", ) .emit(); return true; } } else { - *changed_auto_active_status = Some(attr.span); + *changed_auto_active_status = Some(attr_span); } cfg_info.auto_cfg_active = new_value; false @@ -826,7 +822,7 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator let mut doc_cfg = attrs .clone() .filter_map(|attr| match attr { - Attribute::Parsed(AttributeKind::Doc(d)) => Some(d), + Attribute::Parsed(AttributeKind::Doc(d)) if !d.cfg.is_empty() => Some(d), _ => None, }) .peekable(); @@ -850,64 +846,37 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator // We get all `doc(auto_cfg)`, `cfg` and `target_feature` attributes. for attr in attrs { - if let Some(ident) = attr.ident() - && ident.name == sym::doc - && let Some(attrs) = attr.meta_item_list() - { - for attr in attrs.iter().filter(|attr| attr.has_name(sym::auto_cfg)) { - let MetaItemInner::MetaItem(attr) = attr else { - continue; - }; - match &attr.kind { - MetaItemKind::Word => { - if check_changed_auto_active_status( - &mut changed_auto_active_status, - attr, - cfg_info, - tcx, - true, - ) { - return None; - } - } - MetaItemKind::NameValue(lit) => { - if let LitKind::Bool(value) = lit.kind { - if check_changed_auto_active_status( - &mut changed_auto_active_status, - attr, - cfg_info, - tcx, - value, - ) { - return None; - } - } - } - MetaItemKind::List(sub_attrs) => { - if check_changed_auto_active_status( - &mut changed_auto_active_status, - attr, - cfg_info, - tcx, - true, - ) { - return None; - } - for sub_attr in sub_attrs.iter() { - if let Some(ident) = sub_attr.ident() - && (ident.name == sym::show || ident.name == sym::hide) - { - handle_auto_cfg_hide_show( - tcx, - cfg_info, - &sub_attr, - ident.name == sym::show, - &mut new_show_attrs, - &mut new_hide_attrs, - ); - } - } - } + if let Attribute::Parsed(AttributeKind::Doc(d)) = attr { + for (new_value, span) in &d.auto_cfg_change { + if check_changed_auto_active_status( + &mut changed_auto_active_status, + *span, + cfg_info, + tcx, + *new_value, + ) { + return None; + } + } + if let Some((_, span)) = d.auto_cfg.first() { + if check_changed_auto_active_status( + &mut changed_auto_active_status, + *span, + cfg_info, + tcx, + true, + ) { + return None; + } + for (value, span) in &d.auto_cfg { + handle_auto_cfg_hide_show( + tcx, + cfg_info, + value, + *span, + &mut new_show_attrs, + &mut new_hide_attrs, + ); } } } else if let hir::Attribute::Parsed(AttributeKind::TargetFeature { features, .. }) = attr { From 5c47240ad16fc19d093176c606a7529b54401b9e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 2 Dec 2025 16:01:20 +0100 Subject: [PATCH 0515/3801] Correctly handle `doc(test(attr(...)))` --- Cargo.lock | 2 +- compiler/rustc_attr_parsing/src/attributes/doc.rs | 6 +++--- src/librustdoc/Cargo.toml | 2 +- src/librustdoc/doctest.rs | 2 +- src/librustdoc/doctest/rust.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23708adcc499..d818d87e0804 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4868,9 +4868,9 @@ dependencies = [ "indexmap", "itertools", "minifier", + "proc-macro2", "pulldown-cmark-escape", "regex", - "rustc_proc_macro", "rustdoc-json-types", "serde", "serde_json", diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index fb99f43fced8..26fb53baf2e4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -115,9 +115,9 @@ impl DocParser { return; }; - // FIXME: convert list into a Vec of `AttributeKind`. - for _ in list.mixed() { - // self.attribute.test_attrs.push(AttributeKind::parse()); + // FIXME: convert list into a Vec of `AttributeKind` because current code is awful. + for attr in list.mixed() { + self.attribute.test_attrs.push(attr.span()); } } Some(name) => { diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 371da896b9fc..dcfc1ffc251e 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -15,10 +15,10 @@ base64 = "0.21.7" indexmap = { version = "2", features = ["serde"] } itertools = "0.12" minifier = { version = "0.3.5", default-features = false } +proc-macro2 = "1.0.103" pulldown-cmark-escape = { version = "0.11.0", features = ["simd"] } regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } -rustc_proc_macro = { path = "../../compiler/rustc_proc_macro" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" smallvec = "1.8.1" diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 7541311be05d..19e8fe3e3ed2 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -17,6 +17,7 @@ use std::{panic, str}; pub(crate) use make::{BuildDocTestBuilder, DocTestBuilder}; pub(crate) use markdown::test as test_markdown; +use proc_macro2::{TokenStream, TokenTree}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxHasher, FxIndexMap, FxIndexSet}; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, DiagCtxtHandle}; @@ -25,7 +26,6 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::{Attribute, CRATE_HIR_ID}; use rustc_interface::interface; use rustc_middle::ty::TyCtxt; -use rustc_proc_macro::{TokenStream, TokenTree}; use rustc_session::config::{self, CrateType, ErrorOutputType, Input}; use rustc_session::lint; use rustc_span::edition::Edition; diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index e119344a806a..6f294ad96267 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -5,12 +5,12 @@ use std::env; use std::str::FromStr; use std::sync::Arc; +use proc_macro2::{TokenStream, TokenTree}; use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::{self as hir, Attribute, CRATE_HIR_ID, intravisit}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; -use rustc_proc_macro::{TokenStream, TokenTree}; use rustc_resolve::rustdoc::span_of_fragments; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, DUMMY_SP, FileName, Pos, Span}; From 976d45452a90780a3e0b850dfb635232fa2f3058 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 2 Dec 2025 17:25:43 +0100 Subject: [PATCH 0516/3801] Update rustdoc unit tests --- src/librustdoc/clean/cfg.rs | 3 + src/librustdoc/clean/cfg/tests.rs | 266 +++++++++++++++++----------- src/librustdoc/clean/types/tests.rs | 5 +- 3 files changed, 170 insertions(+), 104 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 292df1cf9550..99409cf838cd 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -25,6 +25,9 @@ use crate::html::escape::Escape; mod tests; #[derive(Clone, Debug, Hash)] +// Because `CfgEntry` includes `Span`, we must NEVER use `==`/`!=` operators on `Cfg` and instead +// use `is_equivalent_to`. +#[cfg_attr(test, derive(PartialEq))] pub(crate) struct Cfg(CfgEntry); #[derive(PartialEq, Debug)] diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index f0591295da64..4eb6c060cbd2 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -1,23 +1,62 @@ use rustc_ast::ast::LitIntType; use rustc_ast::{MetaItemInner, MetaItemLit, Path, Safety, StrStyle}; use rustc_data_structures::thin_vec::thin_vec; +use rustc_hir::attrs::CfgEntry; use rustc_span::symbol::{Ident, kw}; use rustc_span::{DUMMY_SP, create_default_session_globals_then}; use super::*; -fn word_cfg(s: &str) -> Cfg { - Cfg::Cfg(Symbol::intern(s), None) +fn word_cfg(name: &str) -> Cfg { + Cfg(word_cfg_e(name)) +} + +fn word_cfg_e(name: &str) -> CfgEntry { + CfgEntry::NameValue { + name: Symbol::intern(name), + name_span: DUMMY_SP, + value: None, + span: DUMMY_SP, + } } fn name_value_cfg(name: &str, value: &str) -> Cfg { - Cfg::Cfg(Symbol::intern(name), Some(Symbol::intern(value))) + Cfg(name_value_cfg_e(name, value)) +} + +fn name_value_cfg_e(name: &str, value: &str) -> CfgEntry { + CfgEntry::NameValue { + name: Symbol::intern(name), + name_span: DUMMY_SP, + value: Some((Symbol::intern(value), DUMMY_SP)), + span: DUMMY_SP, + } } fn dummy_lit(symbol: Symbol, kind: LitKind) -> MetaItemInner { MetaItemInner::Lit(MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP }) } +fn cfg_all(v: ThinVec) -> Cfg { + Cfg(cfg_all_e(v)) +} + +fn cfg_all_e(v: ThinVec) -> CfgEntry { + CfgEntry::All(v, DUMMY_SP) +} + +fn cfg_any(v: ThinVec) -> Cfg { + Cfg(cfg_any_e(v)) +} + +fn cfg_any_e(v: ThinVec) -> CfgEntry { + CfgEntry::Any(v, DUMMY_SP) +} + +fn cfg_not(v: CfgEntry) -> Cfg { + Cfg(CfgEntry::Not(Box::new(v), DUMMY_SP)) +} + fn dummy_meta_item_word(name: &str) -> MetaItemInner { MetaItemInner::MetaItem(MetaItem { unsafety: Safety::Default, @@ -63,40 +102,48 @@ macro_rules! dummy_meta_item_list { }; } +fn cfg_true() -> Cfg { + Cfg(CfgEntry::Bool(true, DUMMY_SP)) +} + +fn cfg_false() -> Cfg { + Cfg(CfgEntry::Bool(false, DUMMY_SP)) +} + #[test] fn test_cfg_not() { create_default_session_globals_then(|| { - assert_eq!(!Cfg::False, Cfg::True); - assert_eq!(!Cfg::True, Cfg::False); - assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test")))); + assert_eq!(!cfg_false(), cfg_true()); + assert_eq!(!cfg_true(), cfg_false()); + assert_eq!(!word_cfg("test"), cfg_not(word_cfg_e("test"))); assert_eq!( - !Cfg::All(vec![word_cfg("a"), word_cfg("b")]), - Cfg::Not(Box::new(Cfg::All(vec![word_cfg("a"), word_cfg("b")]))) + !cfg_all(thin_vec![word_cfg_e("a"), word_cfg_e("b")]), + cfg_not(cfg_all_e(thin_vec![word_cfg_e("a"), word_cfg_e("b")])) ); assert_eq!( - !Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), - Cfg::Not(Box::new(Cfg::Any(vec![word_cfg("a"), word_cfg("b")]))) + !cfg_any(thin_vec![word_cfg_e("a"), word_cfg_e("b")]), + cfg_not(cfg_any_e(thin_vec![word_cfg_e("a"), word_cfg_e("b")])) ); - assert_eq!(!Cfg::Not(Box::new(word_cfg("test"))), word_cfg("test")); + assert_eq!(!cfg_not(word_cfg_e("test")), word_cfg("test")); }) } #[test] fn test_cfg_and() { create_default_session_globals_then(|| { - let mut x = Cfg::False; - x &= Cfg::True; - assert_eq!(x, Cfg::False); + let mut x = cfg_false(); + x &= cfg_true(); + assert_eq!(x, cfg_false()); x = word_cfg("test"); - x &= Cfg::False; - assert_eq!(x, Cfg::False); + x &= cfg_false(); + assert_eq!(x, cfg_false()); x = word_cfg("test2"); - x &= Cfg::True; + x &= cfg_true(); assert_eq!(x, word_cfg("test2")); - x = Cfg::True; + x = cfg_true(); x &= word_cfg("test3"); assert_eq!(x, word_cfg("test3")); @@ -104,63 +151,69 @@ fn test_cfg_and() { assert_eq!(x, word_cfg("test3")); x &= word_cfg("test4"); - assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")])); + assert_eq!(x, cfg_all(thin_vec![word_cfg_e("test3"), word_cfg_e("test4")])); x &= word_cfg("test4"); - assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")])); + assert_eq!(x, cfg_all(thin_vec![word_cfg_e("test3"), word_cfg_e("test4")])); x &= word_cfg("test5"); - assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); - - x &= Cfg::All(vec![word_cfg("test6"), word_cfg("test7")]); assert_eq!( x, - Cfg::All(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), + cfg_all(thin_vec![word_cfg_e("test3"), word_cfg_e("test4"), word_cfg_e("test5")]) + ); + + x &= cfg_all(thin_vec![word_cfg_e("test6"), word_cfg_e("test7")]); + assert_eq!( + x, + cfg_all(thin_vec![ + word_cfg_e("test3"), + word_cfg_e("test4"), + word_cfg_e("test5"), + word_cfg_e("test6"), + word_cfg_e("test7"), ]) ); - x &= Cfg::All(vec![word_cfg("test6"), word_cfg("test7")]); + x &= cfg_all(thin_vec![word_cfg_e("test6"), word_cfg_e("test7")]); assert_eq!( x, - Cfg::All(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), + cfg_all(thin_vec![ + word_cfg_e("test3"), + word_cfg_e("test4"), + word_cfg_e("test5"), + word_cfg_e("test6"), + word_cfg_e("test7"), ]) ); - let mut y = Cfg::Any(vec![word_cfg("a"), word_cfg("b")]); + let mut y = cfg_any(thin_vec![word_cfg_e("a"), word_cfg_e("b")]); y &= x; assert_eq!( y, - Cfg::All(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), + cfg_all(thin_vec![ + word_cfg_e("test3"), + word_cfg_e("test4"), + word_cfg_e("test5"), + word_cfg_e("test6"), + word_cfg_e("test7"), + cfg_any_e(thin_vec![word_cfg_e("a"), word_cfg_e("b")]), ]) ); let mut z = word_cfg("test8"); - z &= Cfg::All(vec![word_cfg("test9"), word_cfg("test10")]); - assert_eq!(z, Cfg::All(vec![word_cfg("test9"), word_cfg("test10"), word_cfg("test8")])); + z &= cfg_all(thin_vec![word_cfg_e("test9"), word_cfg_e("test10")]); + assert_eq!( + z, + cfg_all(thin_vec![word_cfg_e("test9"), word_cfg_e("test10"), word_cfg_e("test8"),]), + ); let mut z = word_cfg("test11"); - z &= Cfg::All(vec![word_cfg("test11"), word_cfg("test12")]); - assert_eq!(z, Cfg::All(vec![word_cfg("test11"), word_cfg("test12")])); + z &= cfg_all(thin_vec![word_cfg_e("test11"), word_cfg_e("test12")]); + assert_eq!(z, cfg_all(thin_vec![word_cfg_e("test11"), word_cfg_e("test12")])); assert_eq!( word_cfg("a") & word_cfg("b") & word_cfg("c"), - Cfg::All(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) + cfg_all(thin_vec![word_cfg_e("a"), word_cfg_e("b"), word_cfg_e("c")]) ); }) } @@ -168,19 +221,19 @@ fn test_cfg_and() { #[test] fn test_cfg_or() { create_default_session_globals_then(|| { - let mut x = Cfg::True; - x |= Cfg::False; - assert_eq!(x, Cfg::True); + let mut x = cfg_true(); + x |= cfg_false(); + assert_eq!(x, cfg_true()); x = word_cfg("test"); - x |= Cfg::True; + x |= cfg_true(); assert_eq!(x, word_cfg("test")); x = word_cfg("test2"); - x |= Cfg::False; + x |= cfg_false(); assert_eq!(x, word_cfg("test2")); - x = Cfg::False; + x = cfg_false(); x |= word_cfg("test3"); assert_eq!(x, word_cfg("test3")); @@ -188,63 +241,69 @@ fn test_cfg_or() { assert_eq!(x, word_cfg("test3")); x |= word_cfg("test4"); - assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")])); + assert_eq!(x, cfg_any(thin_vec![word_cfg_e("test3"), word_cfg_e("test4")])); x |= word_cfg("test4"); - assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")])); + assert_eq!(x, cfg_any(thin_vec![word_cfg_e("test3"), word_cfg_e("test4")])); x |= word_cfg("test5"); - assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); - - x |= Cfg::Any(vec![word_cfg("test6"), word_cfg("test7")]); assert_eq!( x, - Cfg::Any(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), + cfg_any(thin_vec![word_cfg_e("test3"), word_cfg_e("test4"), word_cfg_e("test5")]) + ); + + x |= cfg_any(thin_vec![word_cfg_e("test6"), word_cfg_e("test7")]); + assert_eq!( + x, + cfg_any(thin_vec![ + word_cfg_e("test3"), + word_cfg_e("test4"), + word_cfg_e("test5"), + word_cfg_e("test6"), + word_cfg_e("test7"), ]) ); - x |= Cfg::Any(vec![word_cfg("test6"), word_cfg("test7")]); + x |= cfg_any(thin_vec![word_cfg_e("test6"), word_cfg_e("test7")]); assert_eq!( x, - Cfg::Any(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), + cfg_any(thin_vec![ + word_cfg_e("test3"), + word_cfg_e("test4"), + word_cfg_e("test5"), + word_cfg_e("test6"), + word_cfg_e("test7"), ]) ); - let mut y = Cfg::All(vec![word_cfg("a"), word_cfg("b")]); + let mut y = cfg_all(thin_vec![word_cfg_e("a"), word_cfg_e("b")]); y |= x; assert_eq!( y, - Cfg::Any(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - Cfg::All(vec![word_cfg("a"), word_cfg("b")]), + cfg_any(thin_vec![ + word_cfg_e("test3"), + word_cfg_e("test4"), + word_cfg_e("test5"), + word_cfg_e("test6"), + word_cfg_e("test7"), + cfg_all_e(thin_vec![word_cfg_e("a"), word_cfg_e("b")]), ]) ); let mut z = word_cfg("test8"); - z |= Cfg::Any(vec![word_cfg("test9"), word_cfg("test10")]); - assert_eq!(z, Cfg::Any(vec![word_cfg("test9"), word_cfg("test10"), word_cfg("test8")])); + z |= cfg_any(thin_vec![word_cfg_e("test9"), word_cfg_e("test10")]); + assert_eq!( + z, + cfg_any(thin_vec![word_cfg_e("test9"), word_cfg_e("test10"), word_cfg_e("test8")]) + ); let mut z = word_cfg("test11"); - z |= Cfg::Any(vec![word_cfg("test11"), word_cfg("test12")]); - assert_eq!(z, Cfg::Any(vec![word_cfg("test11"), word_cfg("test12")])); + z |= cfg_any(thin_vec![word_cfg_e("test11"), word_cfg_e("test12")]); + assert_eq!(z, cfg_any(thin_vec![word_cfg_e("test11"), word_cfg_e("test12")])); assert_eq!( word_cfg("a") | word_cfg("b") | word_cfg("c"), - Cfg::Any(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) + cfg_any(thin_vec![word_cfg_e("a"), word_cfg_e("b"), word_cfg_e("c")]) ); }) } @@ -254,11 +313,11 @@ fn test_parse_ok() { create_default_session_globals_then(|| { let r#true = Symbol::intern("true"); let mi = dummy_lit(r#true, LitKind::Bool(true)); - assert_eq!(Cfg::parse(&mi), Ok(Cfg::True)); + assert_eq!(Cfg::parse(&mi), Ok(cfg_true())); let r#false = Symbol::intern("false"); let mi = dummy_lit(r#false, LitKind::Bool(false)); - assert_eq!(Cfg::parse(&mi), Ok(Cfg::False)); + assert_eq!(Cfg::parse(&mi), Ok(cfg_false())); let mi = dummy_meta_item_word("all"); assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); @@ -464,33 +523,36 @@ fn test_simplify_with() { // This is a tiny subset of things that could be simplified, but it likely covers 90% of // real world usecases well. create_default_session_globals_then(|| { - let foo = word_cfg("foo"); - let bar = word_cfg("bar"); - let baz = word_cfg("baz"); - let quux = word_cfg("quux"); + let foo = word_cfg_e("foo"); + let bar = word_cfg_e("bar"); + let baz = word_cfg_e("baz"); + let quux = word_cfg_e("quux"); - let foobar = Cfg::All(vec![foo.clone(), bar.clone()]); - let barbaz = Cfg::All(vec![bar.clone(), baz.clone()]); - let foobarbaz = Cfg::All(vec![foo.clone(), bar.clone(), baz.clone()]); - let bazquux = Cfg::All(vec![baz.clone(), quux.clone()]); + let foobar = cfg_all(thin_vec![foo.clone(), bar.clone()]); + let barbaz = cfg_all(thin_vec![bar.clone(), baz.clone()]); + let foobarbaz = cfg_all(thin_vec![foo.clone(), bar.clone(), baz.clone()]); + let bazquux = cfg_all(thin_vec![baz.clone(), quux.clone()]); // Unrelated cfgs don't affect each other - assert_eq!(foo.simplify_with(&bar).as_ref(), Some(&foo)); + assert_eq!( + Cfg(foo.clone()).simplify_with(&Cfg(bar.clone())).as_ref(), + Some(&Cfg(foo.clone())) + ); assert_eq!(foobar.simplify_with(&bazquux).as_ref(), Some(&foobar)); // Identical cfgs are eliminated - assert_eq!(foo.simplify_with(&foo), None); + assert_eq!(Cfg(foo.clone()).simplify_with(&Cfg(foo.clone())), None); assert_eq!(foobar.simplify_with(&foobar), None); // Multiple cfgs eliminate a single assumed cfg - assert_eq!(foobar.simplify_with(&foo).as_ref(), Some(&bar)); - assert_eq!(foobar.simplify_with(&bar).as_ref(), Some(&foo)); + assert_eq!(foobar.simplify_with(&Cfg(foo.clone())).as_ref(), Some(&Cfg(bar.clone()))); + assert_eq!(foobar.simplify_with(&Cfg(bar)).as_ref(), Some(&Cfg(foo.clone()))); // A single cfg is eliminated by multiple assumed cfg containing it - assert_eq!(foo.simplify_with(&foobar), None); + assert_eq!(Cfg(foo.clone()).simplify_with(&foobar), None); // Multiple cfgs eliminate the matching subset of multiple assumed cfg - assert_eq!(foobar.simplify_with(&barbaz).as_ref(), Some(&foo)); + assert_eq!(foobar.simplify_with(&barbaz).as_ref(), Some(&Cfg(foo))); assert_eq!(foobar.simplify_with(&foobarbaz), None); }); } diff --git a/src/librustdoc/clean/types/tests.rs b/src/librustdoc/clean/types/tests.rs index 9499507b2c0f..915b7d851a3e 100644 --- a/src/librustdoc/clean/types/tests.rs +++ b/src/librustdoc/clean/types/tests.rs @@ -1,4 +1,5 @@ -use rustc_resolve::rustdoc::{DocFragmentKind, unindent_doc_fragments}; +use rustc_ast::token::{CommentKind, DocFragmentKind}; +use rustc_resolve::rustdoc::unindent_doc_fragments; use rustc_span::create_default_session_globals_then; use super::*; @@ -8,7 +9,7 @@ fn create_doc_fragment(s: &str) -> Vec { span: DUMMY_SP, item_id: None, doc: Symbol::intern(s), - kind: DocFragmentKind::SugaredDoc, + kind: DocFragmentKind::Sugared(CommentKind::Line), indent: 0, from_expansion: false, }] From 9c8c67bfdd864f6ba6eb1bf23b57cd81499c4e2d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 3 Dec 2025 15:55:57 +0100 Subject: [PATCH 0517/3801] Fix warning messages --- .../rustc_attr_parsing/src/attributes/doc.rs | 17 +- .../src/session_diagnostics.rs | 9 - .../rustc_hir/src/attrs/data_structures.rs | 6 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_passes/messages.ftl | 12 +- compiler/rustc_passes/src/check_attr.rs | 28 ++- compiler/rustc_passes/src/errors.rs | 8 + src/librustdoc/clean/mod.rs | 14 +- src/librustdoc/lib.rs | 14 ++ src/librustdoc/visit_ast.rs | 14 +- tests/rustdoc-ui/bad-render-options.rs | 36 ++- tests/rustdoc-ui/bad-render-options.stderr | 209 +++++++++++++++--- .../rustdoc-ui/cfg-hide-show-conflict.stderr | 8 +- .../check-doc-alias-attr-location.stderr | 16 +- tests/rustdoc-ui/check-doc-alias-attr.stderr | 61 +++-- tests/rustdoc-ui/doc-alias-assoc-const.stderr | 4 +- tests/rustdoc-ui/doc-alias-same-name.stderr | 6 +- .../rustdoc-ui/doc-include-suggestion.stderr | 2 +- tests/rustdoc-ui/lints/doc_cfg_hide.stderr | 8 +- tests/rustdoc-ui/lints/invalid-doc-attr.rs | 2 - .../rustdoc-ui/lints/invalid-doc-attr.stderr | 36 +-- 21 files changed, 377 insertions(+), 135 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 26fb53baf2e4..1fd7b702e92f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -2,7 +2,6 @@ #![allow(unused_imports)] use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit}; -use rustc_errors::MultiSpan; use rustc_feature::template; use rustc_hir::attrs::{ AttributeKind, CfgEntry, CfgHideShow, CfgInfo, DocAttribute, DocInline, HideOrShow, @@ -18,7 +17,7 @@ use crate::fluent_generated as fluent; use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, PathParser}; use crate::session_diagnostics::{ DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttributeNotAttribute, - DocKeywordConflict, DocKeywordNotKeyword, + DocKeywordNotKeyword, }; fn check_keyword(cx: &mut AcceptContext<'_, '_, S>, keyword: Symbol, span: Span) -> bool { @@ -204,19 +203,7 @@ impl DocParser { return; } - let span = path.span(); - - if let Some((prev_inline, prev_span)) = self.attribute.inline { - if prev_inline == inline { - let mut spans = MultiSpan::from_spans(vec![prev_span, span]); - spans.push_span_label(prev_span, fluent::attr_parsing_doc_inline_conflict_first); - spans.push_span_label(span, fluent::attr_parsing_doc_inline_conflict_second); - cx.emit_err(DocKeywordConflict { spans }); - return; - } - } - - self.attribute.inline = Some((inline, span)); + self.attribute.inline.push((inline, path.span())); } fn parse_cfg<'c, S: Stage>( diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 26b615448e3b..38ae597000d2 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -4,7 +4,6 @@ use rustc_ast::{self as ast}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, - MultiSpan, }; use rustc_feature::AttributeTemplate; use rustc_hir::AttrPath; @@ -589,14 +588,6 @@ pub(crate) struct DocAliasDuplicated { pub first_defn: Span, } -#[derive(Diagnostic)] -#[diag(attr_parsing_doc_inline_conflict)] -#[help] -pub(crate) struct DocKeywordConflict { - #[primary_span] - pub spans: MultiSpan, -} - #[derive(Diagnostic)] #[diag(attr_parsing_link_ordinal_out_of_range)] #[note] diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 4e1de8e5aeae..0419e219afe4 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -476,7 +476,9 @@ pub struct CfgHideShow { pub struct DocAttribute { pub aliases: FxIndexMap, pub hidden: Option, - pub inline: Option<(DocInline, Span)>, + // Because we need to emit the error if there is more than one `inline` attribute on an item + // at the same time as the other doc attributes, we store a list instead of using `Option`. + pub inline: ThinVec<(DocInline, Span)>, // unstable pub cfg: ThinVec, @@ -511,7 +513,7 @@ impl Default for DocAttribute { Self { aliases: FxIndexMap::default(), hidden: None, - inline: None, + inline: ThinVec::new(), cfg: ThinVec::new(), auto_cfg: ThinVec::new(), auto_cfg_change: ThinVec::new(), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 9a1cf7f349fd..2069c06c3f77 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -880,7 +880,7 @@ fn analyze_attr(attr: &hir::Attribute, state: &mut AnalyzeAttrState<'_>) -> bool } else if let hir::Attribute::Parsed(AttributeKind::Doc(d)) = attr { // If this is a `doc` attribute that doesn't have anything except maybe `inline` (as in // `#[doc(inline)]`), then we can remove it. It won't be inlinable in downstream crates. - if d.inline.is_none() { + if d.inline.is_empty() { should_encode = true; if d.hidden.is_some() { state.is_doc_hidden = true; diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 007ce22c01e6..4e8973e4928b 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -107,10 +107,10 @@ passes_diagnostic_item_first_defined = the diagnostic item is first defined here passes_doc_alias_bad_location = - doc alias attribute isn't allowed on {$location} + `#[doc(alias = "...")]` isn't allowed on {$location} passes_doc_alias_not_an_alias = - {$attr_str} is the same as the item's name + `#[doc(alias = "{$attr_str}"]` is the same as the item's name passes_doc_attr_not_crate_level = `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute @@ -118,7 +118,15 @@ passes_doc_attr_not_crate_level = passes_doc_fake_variadic_not_valid = `#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity +passes_doc_inline_conflict = + conflicting doc inlining attributes + .help = remove one of the conflicting attributes +passes_doc_inline_conflict_first = + this attribute... + +passes_doc_inline_conflict_second = + {"."}..conflicts with this attribute passes_doc_inline_only_use = this attribute can only be applied to a `use` item diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index bae15de4bf88..3f29d943e7d3 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -13,13 +13,14 @@ use rustc_abi::{Align, ExternAbi, Size}; use rustc_ast::{AttrStyle, LitKind, MetaItemKind, ast}; use rustc_attr_parsing::{AttributeParser, Late}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{DiagCtxtHandle, IntoDiagArg, StashKey}; +use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; use rustc_feature::{ ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, }; use rustc_hir::attrs::{ - AttributeKind, DocAttribute, InlineAttr, MirDialect, MirPhase, ReprAttr, SanitizerSet, + AttributeKind, DocAttribute, DocInline, InlineAttr, MirDialect, MirPhase, ReprAttr, + SanitizerSet, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalModDefId; @@ -881,7 +882,24 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// already seen an inlining attribute for this item. /// If so, `specified_inline` holds the value and the span of /// the first `inline`/`no_inline` attribute. - fn check_doc_inline(&self, span: Span, hir_id: HirId, target: Target) { + fn check_doc_inline(&self, hir_id: HirId, target: Target, inline: &[(DocInline, Span)]) { + let span = match inline { + [] => return, + [(_, span)] => *span, + [(inline, span), rest @ ..] => { + for (inline2, span2) in rest { + if inline2 != inline { + let mut spans = MultiSpan::from_spans(vec![*span, *span2]); + spans.push_span_label(*span, fluent::passes_doc_inline_conflict_first); + spans.push_span_label(*span2, fluent::passes_doc_inline_conflict_second); + self.dcx().emit_err(errors::DocInlineConflict { spans }); + return; + } + } + *span + } + }; + match target { Target::Use | Target::ExternCrate => {} _ => { @@ -1050,9 +1068,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - if let Some((_, span)) = inline { - self.check_doc_inline(*span, hir_id, target) - } + self.check_doc_inline(hir_id, target, inline); if let Some(span) = rust_logo { if self.check_attr_crate_level(*span, hir_id) diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index b693aaf76923..3a2908d14184 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -176,6 +176,14 @@ pub(crate) struct DocSearchUnboxInvalid { pub span: Span, } +#[derive(Diagnostic)] +#[diag(passes_doc_inline_conflict)] +#[help] +pub(crate) struct DocInlineConflict { + #[primary_span] + pub spans: MultiSpan, +} + #[derive(LintDiagnostic)] #[diag(passes_doc_inline_only_use)] #[note] diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bea4398ccf86..dd5c50d2ba37 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -199,7 +199,7 @@ fn generate_item_with_correct_attrs( let import_is_inline = find_attr!( inline::load_attrs(cx, import_id.to_def_id()), AttributeKind::Doc(d) - if d.inline.is_some_and(|(inline, _)| inline == DocInline::Inline) + if d.inline.first().is_some_and(|(inline, _)| *inline == DocInline::Inline) ) || (is_glob_import(cx.tcx, import_id) && (cx.document_hidden() || !cx.tcx.is_doc_hidden(def_id))); attrs.extend(get_all_import_attributes(cx, import_id, def_id, is_inline)); @@ -2921,7 +2921,7 @@ fn clean_extern_crate<'tcx>( matches!( a, hir::Attribute::Parsed(AttributeKind::Doc(d)) - if d.inline.is_some_and(|(i, _)| i == DocInline::Inline)) + if d.inline.first().is_some_and(|(i, _)| *i == DocInline::Inline)) }) && !cx.is_json_output(); @@ -2986,9 +2986,9 @@ fn clean_use_statement_inner<'tcx>( let attrs = cx.tcx.hir_attrs(import.hir_id()); let inline_attr = find_attr!( attrs, - AttributeKind::Doc(d) if d.inline.is_some_and(|(i, _)| i == DocInline::Inline) => d + AttributeKind::Doc(d) if d.inline.first().is_some_and(|(i, _)| *i == DocInline::Inline) => d ) - .and_then(|d| d.inline); + .and_then(|d| d.inline.first()); let pub_underscore = visibility.is_public() && name == Some(kw::Underscore); let current_mod = cx.tcx.parent_module_from_def_id(import.owner_id.def_id); let import_def_id = import.owner_id.def_id; @@ -3009,7 +3009,7 @@ fn clean_use_statement_inner<'tcx>( if pub_underscore && let Some((_, inline_span)) = inline_attr { struct_span_code_err!( cx.tcx.dcx(), - inline_span, + *inline_span, E0780, "anonymous imports cannot be inlined" ) @@ -3026,7 +3026,9 @@ fn clean_use_statement_inner<'tcx>( || pub_underscore || attrs.iter().any(|a| matches!( a, - hir::Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some() || d.inline.is_some_and(|(i, _)| i == DocInline::NoInline))); + hir::Attribute::Parsed(AttributeKind::Doc(d)) + if d.hidden.is_some() || d.inline.first().is_some_and(|(i, _)| *i == DocInline::NoInline) + )); // Also check whether imports were asked to be inlined, in case we're trying to re-export a // crate in Rust 2018+ diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index a0e359032f9b..13be1a04dbc5 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -32,6 +32,7 @@ extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_ast_pretty; +extern crate rustc_attr_parsing; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; @@ -75,6 +76,7 @@ use std::process; use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::lints::DelayedLint; use rustc_interface::interface; use rustc_middle::ty::TyCtxt; use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option}; @@ -900,6 +902,18 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { return; } + for owner_id in tcx.hir_crate_items(()).delayed_lint_items() { + if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) { + for lint in &delayed_lints.lints { + match lint { + DelayedLint::AttributeParsing(attribute_lint) => { + rustc_attr_parsing::emit_attribute_lint(attribute_lint, tcx) + } + } + } + } + } + if render_opts.dep_info().is_some() { rustc_interface::passes::write_dep_info(tcx); } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index d6da8615d57e..0f4460bed35a 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -247,8 +247,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let document_hidden = self.cx.document_hidden(); let use_attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. - let is_no_inline = find_attr!(use_attrs, AttributeKind::Doc(d) if d.inline.is_some_and(|(inline, _)| inline == DocInline::NoInline)) - || (document_hidden && use_attrs.iter().any(|attr| attr.is_doc_hidden())); + let is_no_inline = find_attr!( + use_attrs, + AttributeKind::Doc(d) + if d.inline.first().is_some_and(|(inline, _)| *inline == DocInline::NoInline) + ) || (document_hidden + && use_attrs.iter().any(|attr| attr.is_doc_hidden())); if is_no_inline { return false; @@ -465,7 +469,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // If there was a private module in the current path then don't bother inlining // anything as it will probably be stripped anyway. if is_pub && self.inside_public_path { - let please_inline = find_attr!(attrs, AttributeKind::Doc(d) if d.inline.is_some_and(|(inline, _)| inline == DocInline::Inline)); + let please_inline = find_attr!( + attrs, + AttributeKind::Doc(d) + if d.inline.first().is_some_and(|(inline, _)| *inline == DocInline::Inline) + ); let ident = match kind { hir::UseKind::Single(ident) => Some(ident.name), hir::UseKind::Glob => None, diff --git a/tests/rustdoc-ui/bad-render-options.rs b/tests/rustdoc-ui/bad-render-options.rs index f2cfd4b76fa8..0522f68cb6c2 100644 --- a/tests/rustdoc-ui/bad-render-options.rs +++ b/tests/rustdoc-ui/bad-render-options.rs @@ -1,11 +1,29 @@ // regression test for https://github.com/rust-lang/rust/issues/149187 -#![doc(html_favicon_url)] //~ ERROR: `doc(html_favicon_url)` expects a string value [invalid_doc_attributes] -#![doc(html_logo_url)] //~ ERROR: `doc(html_logo_url)` expects a string value [invalid_doc_attributes] -#![doc(html_playground_url)] //~ ERROR: `doc(html_playground_url)` expects a string value [invalid_doc_attributes] -#![doc(issue_tracker_base_url)] //~ ERROR expects a string value -#![doc(html_favicon_url = 1)] //~ ERROR expects a string value -#![doc(html_logo_url = 2)] //~ ERROR expects a string value -#![doc(html_playground_url = 3)] //~ ERROR expects a string value -#![doc(issue_tracker_base_url = 4)] //~ ERROR expects a string value -#![doc(html_no_source = "asdf")] //~ ERROR `doc(html_no_source)` does not accept a value [invalid_doc_attributes] +#![doc(html_favicon_url)] +//~^ ERROR: malformed `doc` attribute +//~| NOTE expected this to be of the form `html_favicon_url = "..."` +#![doc(html_logo_url)] +//~^ ERROR: malformed `doc` attribute +//~| NOTE expected this to be of the form `html_logo_url = "..."` +#![doc(html_playground_url)] +//~^ ERROR: malformed `doc` attribute +//~| NOTE expected this to be of the form `html_playground_url = "..."` +#![doc(issue_tracker_base_url)] +//~^ ERROR: malformed `doc` attribute +//~| NOTE expected this to be of the form `issue_tracker_base_url = "..."` +#![doc(html_favicon_url = 1)] +//~^ ERROR malformed `doc` attribute +//~| NOTE expected a string literal +#![doc(html_logo_url = 2)] +//~^ ERROR malformed `doc` attribute +//~| NOTE expected a string literal +#![doc(html_playground_url = 3)] +//~^ ERROR malformed `doc` attribute +//~| NOTE expected a string literal +#![doc(issue_tracker_base_url = 4)] +//~^ ERROR malformed `doc` attribute +//~| NOTE expected a string literal +#![doc(html_no_source = "asdf")] +//~^ ERROR malformed `doc` attribute +//~| NOTE didn't expect any arguments here diff --git a/tests/rustdoc-ui/bad-render-options.stderr b/tests/rustdoc-ui/bad-render-options.stderr index 9d503363c0bd..e7f33f4dff1d 100644 --- a/tests/rustdoc-ui/bad-render-options.stderr +++ b/tests/rustdoc-ui/bad-render-options.stderr @@ -1,58 +1,211 @@ -error: `doc(html_favicon_url)` expects a string value - --> $DIR/bad-render-options.rs:3:8 +error[E0539]: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:3:1 | LL | #![doc(html_favicon_url)] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^----------------^^ + | | + | expected this to be of the form `html_favicon_url = "..."` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(html_favicon_url)] +LL + #![doc = "string"] + | +LL - #![doc(html_favicon_url)] +LL + #![doc(hidden)] + | +LL - #![doc(html_favicon_url)] +LL + #![doc(inline)] + | +LL - #![doc(html_favicon_url)] +LL + #![doc(test)] | - = note: `#[deny(invalid_doc_attributes)]` on by default -error: `doc(html_logo_url)` expects a string value - --> $DIR/bad-render-options.rs:4:8 +error[E0539]: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:6:1 | LL | #![doc(html_logo_url)] - | ^^^^^^^^^^^^^ + | ^^^^^^^-------------^^ + | | + | expected this to be of the form `html_logo_url = "..."` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(html_logo_url)] +LL + #![doc = "string"] + | +LL - #![doc(html_logo_url)] +LL + #![doc(hidden)] + | +LL - #![doc(html_logo_url)] +LL + #![doc(inline)] + | +LL - #![doc(html_logo_url)] +LL + #![doc(test)] + | -error: `doc(html_playground_url)` expects a string value - --> $DIR/bad-render-options.rs:5:8 +error[E0539]: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:9:1 | LL | #![doc(html_playground_url)] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^-------------------^^ + | | + | expected this to be of the form `html_playground_url = "..."` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(html_playground_url)] +LL + #![doc = "string"] + | +LL - #![doc(html_playground_url)] +LL + #![doc(hidden)] + | +LL - #![doc(html_playground_url)] +LL + #![doc(inline)] + | +LL - #![doc(html_playground_url)] +LL + #![doc(test)] + | -error: `doc(issue_tracker_base_url)` expects a string value - --> $DIR/bad-render-options.rs:6:8 +error[E0539]: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:12:1 | LL | #![doc(issue_tracker_base_url)] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^----------------------^^ + | | + | expected this to be of the form `issue_tracker_base_url = "..."` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(issue_tracker_base_url)] +LL + #![doc = "string"] + | +LL - #![doc(issue_tracker_base_url)] +LL + #![doc(hidden)] + | +LL - #![doc(issue_tracker_base_url)] +LL + #![doc(inline)] + | +LL - #![doc(issue_tracker_base_url)] +LL + #![doc(test)] + | -error: `doc(html_favicon_url)` expects a string value - --> $DIR/bad-render-options.rs:7:8 +error[E0539]: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:15:1 | LL | #![doc(html_favicon_url = 1)] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(html_favicon_url = 1)] +LL + #![doc = "string"] + | +LL - #![doc(html_favicon_url = 1)] +LL + #![doc(hidden)] + | +LL - #![doc(html_favicon_url = 1)] +LL + #![doc(inline)] + | +LL - #![doc(html_favicon_url = 1)] +LL + #![doc(test)] + | -error: `doc(html_logo_url)` expects a string value - --> $DIR/bad-render-options.rs:8:8 +error[E0539]: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:18:1 | LL | #![doc(html_logo_url = 2)] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(html_logo_url = 2)] +LL + #![doc = "string"] + | +LL - #![doc(html_logo_url = 2)] +LL + #![doc(hidden)] + | +LL - #![doc(html_logo_url = 2)] +LL + #![doc(inline)] + | +LL - #![doc(html_logo_url = 2)] +LL + #![doc(test)] + | -error: `doc(html_playground_url)` expects a string value - --> $DIR/bad-render-options.rs:9:8 +error[E0539]: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:21:1 | LL | #![doc(html_playground_url = 3)] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(html_playground_url = 3)] +LL + #![doc = "string"] + | +LL - #![doc(html_playground_url = 3)] +LL + #![doc(hidden)] + | +LL - #![doc(html_playground_url = 3)] +LL + #![doc(inline)] + | +LL - #![doc(html_playground_url = 3)] +LL + #![doc(test)] + | -error: `doc(issue_tracker_base_url)` expects a string value - --> $DIR/bad-render-options.rs:10:8 +error[E0539]: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:24:1 | LL | #![doc(issue_tracker_base_url = 4)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(issue_tracker_base_url = 4)] +LL + #![doc = "string"] + | +LL - #![doc(issue_tracker_base_url = 4)] +LL + #![doc(hidden)] + | +LL - #![doc(issue_tracker_base_url = 4)] +LL + #![doc(inline)] + | +LL - #![doc(issue_tracker_base_url = 4)] +LL + #![doc(test)] + | -error: `doc(html_no_source)` does not accept a value - --> $DIR/bad-render-options.rs:11:8 +error[E0565]: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:27:1 | LL | #![doc(html_no_source = "asdf")] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^--------^^ + | | + | didn't expect any arguments here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(html_no_source = "asdf")] +LL + #![doc = "string"] + | +LL - #![doc(html_no_source = "asdf")] +LL + #![doc(hidden)] + | +LL - #![doc(html_no_source = "asdf")] +LL + #![doc(inline)] + | +LL - #![doc(html_no_source = "asdf")] +LL + #![doc(test)] + | error: aborting due to 9 previous errors +Some errors have detailed explanations: E0539, E0565. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/rustdoc-ui/cfg-hide-show-conflict.stderr b/tests/rustdoc-ui/cfg-hide-show-conflict.stderr index 22231e82cd7b..384a9f1a0b1f 100644 --- a/tests/rustdoc-ui/cfg-hide-show-conflict.stderr +++ b/tests/rustdoc-ui/cfg-hide-show-conflict.stderr @@ -1,14 +1,14 @@ error: same `cfg` was in `auto_cfg(hide(...))` and `auto_cfg(show(...))` on the same item - --> $DIR/cfg-hide-show-conflict.rs:3:31 + --> $DIR/cfg-hide-show-conflict.rs:3:8 | LL | #![doc(auto_cfg(show(windows, target_os = "linux")))] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^ | note: first change was here - --> $DIR/cfg-hide-show-conflict.rs:2:22 + --> $DIR/cfg-hide-show-conflict.rs:2:8 | LL | #![doc(auto_cfg(hide(target_os = "linux")))] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/check-doc-alias-attr-location.stderr b/tests/rustdoc-ui/check-doc-alias-attr-location.stderr index 85c9516236c9..b8e1863ce560 100644 --- a/tests/rustdoc-ui/check-doc-alias-attr-location.stderr +++ b/tests/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -1,26 +1,26 @@ error: `#[doc(alias = "...")]` isn't allowed on foreign module - --> $DIR/check-doc-alias-attr-location.rs:7:7 + --> $DIR/check-doc-alias-attr-location.rs:7:15 | LL | #[doc(alias = "foo")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: `#[doc(alias = "...")]` isn't allowed on implementation block - --> $DIR/check-doc-alias-attr-location.rs:10:7 + --> $DIR/check-doc-alias-attr-location.rs:10:15 | LL | #[doc(alias = "bar")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: `#[doc(alias = "...")]` isn't allowed on implementation block - --> $DIR/check-doc-alias-attr-location.rs:16:7 + --> $DIR/check-doc-alias-attr-location.rs:16:15 | LL | #[doc(alias = "foobar")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block - --> $DIR/check-doc-alias-attr-location.rs:18:11 + --> $DIR/check-doc-alias-attr-location.rs:18:19 | LL | #[doc(alias = "assoc")] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/rustdoc-ui/check-doc-alias-attr.stderr b/tests/rustdoc-ui/check-doc-alias-attr.stderr index 250568be3333..06d5c6535191 100644 --- a/tests/rustdoc-ui/check-doc-alias-attr.stderr +++ b/tests/rustdoc-ui/check-doc-alias-attr.stderr @@ -4,11 +4,28 @@ error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of s LL | #[doc(alias)] | ^^^^^ -error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` - --> $DIR/check-doc-alias-attr.rs:8:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/check-doc-alias-attr.rs:8:1 | LL | #[doc(alias = 0)] - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^-^^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(alias = 0)] +LL + #[doc = "string"] + | +LL - #[doc(alias = 0)] +LL + #[doc(hidden)] + | +LL - #[doc(alias = 0)] +LL + #[doc(inline)] + | +LL - #[doc(alias = 0)] +LL + #[doc(test)] + | error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:9:15 @@ -54,25 +71,42 @@ error: `#[doc(alias = "...")]` attribute cannot have empty value LL | #[doc(alias = "")] | ^^ -error: `#[doc(alias("a"))]` expects string literals - --> $DIR/check-doc-alias-attr.rs:19:13 +error[E0539]: malformed `doc` attribute input + --> $DIR/check-doc-alias-attr.rs:19:1 | LL | #[doc(alias(0))] - | ^ + | ^^^^^^^^^^^^-^^^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(alias(0))] +LL + #[doc = "string"] + | +LL - #[doc(alias(0))] +LL + #[doc(hidden)] + | +LL - #[doc(alias(0))] +LL + #[doc(inline)] + | +LL - #[doc(alias(0))] +LL + #[doc(test)] + | -error: '"' character isn't allowed in `#[doc(alias("..."))]` +error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:20:13 | LL | #[doc(alias("\""))] | ^^^^ -error: '\n' character isn't allowed in `#[doc(alias("..."))]` +error: '\n' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:21:13 | LL | #[doc(alias("\n"))] | ^^^^ -error: '\n' character isn't allowed in `#[doc(alias("..."))]` +error: '\n' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:22:13 | LL | #[doc(alias(" @@ -80,25 +114,25 @@ LL | #[doc(alias(" LL | | "))] | |_^ -error: '\t' character isn't allowed in `#[doc(alias("..."))]` +error: '\t' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:24:13 | LL | #[doc(alias("\t"))] | ^^^^ -error: `#[doc(alias("..."))]` cannot start or end with ' ' +error: `#[doc(alias = "...")]` cannot start or end with ' ' --> $DIR/check-doc-alias-attr.rs:25:13 | LL | #[doc(alias(" hello"))] | ^^^^^^^^ -error: `#[doc(alias("..."))]` cannot start or end with ' ' +error: `#[doc(alias = "...")]` cannot start or end with ' ' --> $DIR/check-doc-alias-attr.rs:26:13 | LL | #[doc(alias("hello "))] | ^^^^^^^^ -error: `#[doc(alias("..."))]` attribute cannot have empty value +error: `#[doc(alias = "...")]` attribute cannot have empty value --> $DIR/check-doc-alias-attr.rs:27:13 | LL | #[doc(alias(""))] @@ -106,3 +140,4 @@ LL | #[doc(alias(""))] error: aborting due to 17 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/rustdoc-ui/doc-alias-assoc-const.stderr b/tests/rustdoc-ui/doc-alias-assoc-const.stderr index cc628c39400b..7566ec840da7 100644 --- a/tests/rustdoc-ui/doc-alias-assoc-const.stderr +++ b/tests/rustdoc-ui/doc-alias-assoc-const.stderr @@ -1,8 +1,8 @@ error: `#[doc(alias = "...")]` isn't allowed on associated constant in trait implementation block - --> $DIR/doc-alias-assoc-const.rs:8:11 + --> $DIR/doc-alias-assoc-const.rs:8:19 | LL | #[doc(alias = "CONST_BAZ")] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doc-alias-same-name.stderr b/tests/rustdoc-ui/doc-alias-same-name.stderr index a9da75c0171c..a76ff5ee0b67 100644 --- a/tests/rustdoc-ui/doc-alias-same-name.stderr +++ b/tests/rustdoc-ui/doc-alias-same-name.stderr @@ -1,8 +1,8 @@ -error: `#[doc(alias = "...")]` is the same as the item's name - --> $DIR/doc-alias-same-name.rs:3:7 +error: `#[doc(alias = "Foo"]` is the same as the item's name + --> $DIR/doc-alias-same-name.rs:3:15 | LL | #[doc(alias = "Foo")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doc-include-suggestion.stderr b/tests/rustdoc-ui/doc-include-suggestion.stderr index 1b4b78a8f263..ea5261e5bbd4 100644 --- a/tests/rustdoc-ui/doc-include-suggestion.stderr +++ b/tests/rustdoc-ui/doc-include-suggestion.stderr @@ -2,7 +2,7 @@ error: unknown `doc` attribute `include` --> $DIR/doc-include-suggestion.rs:1:7 | LL | #[doc(include = "external-cross-doc.md")] - | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]` + | ^^^^^^^ help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]` | = note: `#[deny(invalid_doc_attributes)]` on by default diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr index c63c8d607fa0..acbe6ef69dd5 100644 --- a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr +++ b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr @@ -1,16 +1,16 @@ error: `#![doc(auto_cfg(hide(...)))]` expects a list of items - --> $DIR/doc_cfg_hide.rs:2:8 + --> $DIR/doc_cfg_hide.rs:2:17 | LL | #![doc(auto_cfg(hide = "test"))] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | = note: `#[deny(invalid_doc_attributes)]` on by default error: `#![doc(auto_cfg(hide(...)))]` expects a list of items - --> $DIR/doc_cfg_hide.rs:3:8 + --> $DIR/doc_cfg_hide.rs:3:17 | LL | #![doc(auto_cfg(hide))] - | ^^^^^^^^^^^^^^ + | ^^^^ error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items --> $DIR/doc_cfg_hide.rs:4:22 diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.rs b/tests/rustdoc-ui/lints/invalid-doc-attr.rs index e1cc08ca2427..a8c42b8fd79c 100644 --- a/tests/rustdoc-ui/lints/invalid-doc-attr.rs +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.rs @@ -6,8 +6,6 @@ #[doc(test(no_crate_inject))] //~^ ERROR can only be applied at the crate level -//~| HELP to apply to the crate, use an inner attribute -//~| SUGGESTION ! #[doc(inline)] //~^ ERROR can only be applied to a `use` item pub fn foo() {} diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr index 7621999a8ca5..82e1b62b57a6 100644 --- a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr @@ -1,18 +1,14 @@ error: this attribute can only be applied at the crate level - --> $DIR/invalid-doc-attr.rs:7:7 + --> $DIR/invalid-doc-attr.rs:7:12 | LL | #[doc(test(no_crate_inject))] - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = note: read for more information = note: `#[deny(invalid_doc_attributes)]` on by default -help: to apply to the crate, use an inner attribute - | -LL | #![doc(test(no_crate_inject))] - | + error: this attribute can only be applied to a `use` item - --> $DIR/invalid-doc-attr.rs:11:7 + --> $DIR/invalid-doc-attr.rs:9:7 | LL | #[doc(inline)] | ^^^^^^ only applicable on `use` items @@ -23,15 +19,15 @@ LL | pub fn foo() {} = note: read for more information error: this attribute can only be applied at the crate level - --> $DIR/invalid-doc-attr.rs:16:12 + --> $DIR/invalid-doc-attr.rs:14:17 | LL | #![doc(test(no_crate_inject))] - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = note: read for more information error: conflicting doc inlining attributes - --> $DIR/invalid-doc-attr.rs:26:7 + --> $DIR/invalid-doc-attr.rs:24:7 | LL | #[doc(inline)] | ^^^^^^ this attribute... @@ -41,7 +37,7 @@ LL | #[doc(no_inline)] = help: remove one of the conflicting attributes error: this attribute can only be applied to an `extern crate` item - --> $DIR/invalid-doc-attr.rs:32:7 + --> $DIR/invalid-doc-attr.rs:30:7 | LL | #[doc(masked)] | ^^^^^^ only applicable on `extern crate` items @@ -52,7 +48,7 @@ LL | pub struct Masked; = note: read for more information error: this attribute cannot be applied to an `extern crate self` item - --> $DIR/invalid-doc-attr.rs:36:7 + --> $DIR/invalid-doc-attr.rs:34:7 | LL | #[doc(masked)] | ^^^^^^ not applicable on `extern crate self` items @@ -63,21 +59,27 @@ LL | pub extern crate self as reexport; error: this attribute can only be applied to an `extern crate` item --> $DIR/invalid-doc-attr.rs:4:8 | -LL | #![doc(masked)] - | ^^^^^^ only applicable on `extern crate` items +LL | / #![crate_type = "lib"] +LL | | #![feature(doc_masked)] +LL | | +LL | | #![doc(masked)] + | | ^^^^^^ only applicable on `extern crate` items +... | +LL | | pub extern crate self as reexport; + | |__________________________________- not an `extern crate` item | = note: read for more information error: this attribute can only be applied at the crate level - --> $DIR/invalid-doc-attr.rs:19:11 + --> $DIR/invalid-doc-attr.rs:17:16 | LL | #[doc(test(no_crate_inject))] - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = note: read for more information error: this attribute can only be applied to a `use` item - --> $DIR/invalid-doc-attr.rs:21:11 + --> $DIR/invalid-doc-attr.rs:19:11 | LL | #[doc(inline)] | ^^^^^^ only applicable on `use` items From d1277ccffaff214fb6127930c70f29744e40a877 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Dec 2025 12:58:31 +0100 Subject: [PATCH 0518/3801] Update `check_doc_cfg` pass in rustdoc, remove old `rustc_attr_parsing::cfg_matches` API --- .../src/attributes/cfg_old.rs | 40 ------- src/librustdoc/passes/check_doc_cfg.rs | 100 +++++++++--------- 2 files changed, 49 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs index adae3fa635f4..29be000d476d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs @@ -4,8 +4,6 @@ use rustc_feature::{Features, GatedCfg, find_gated_cfg}; use rustc_hir::RustcVersion; use rustc_hir::lints::AttributeLintKind; use rustc_session::Session; -use rustc_session::config::ExpectedValues; -use rustc_session::lint::builtin::UNEXPECTED_CFGS; use rustc_session::lint::{BuiltinLintDiag, Lint}; use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, sym}; @@ -37,44 +35,6 @@ pub struct Condition { pub span: Span, } -/// Tests if a cfg-pattern matches the cfg set -pub fn cfg_matches( - cfg: &MetaItemInner, - sess: &Session, - lint_emitter: impl CfgMatchesLintEmitter, - features: Option<&Features>, -) -> bool { - eval_condition(cfg, sess, features, &mut |cfg| { - try_gate_cfg(cfg.name, cfg.span, sess, features); - match sess.psess.check_config.expecteds.get(&cfg.name) { - Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => { - lint_emitter.emit_span_lint( - sess, - UNEXPECTED_CFGS, - cfg.span, - BuiltinLintDiag::AttributeLint(AttributeLintKind::UnexpectedCfgValue( - (cfg.name, cfg.name_span), - cfg.value.map(|v| (v, cfg.value_span.unwrap())), - )), - ); - } - None if sess.psess.check_config.exhaustive_names => { - lint_emitter.emit_span_lint( - sess, - UNEXPECTED_CFGS, - cfg.span, - BuiltinLintDiag::AttributeLint(AttributeLintKind::UnexpectedCfgName( - (cfg.name, cfg.name_span), - cfg.value.map(|v| (v, cfg.value_span.unwrap())), - )), - ); - } - _ => { /* not unexpected */ } - } - sess.psess.config.contains(&(cfg.name, cfg.value)) - }) -} - pub fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) { let gate = find_gated_cfg(|sym| sym == name); if let (Some(feats), Some(gated_cfg)) = (features, gate) { diff --git a/src/librustdoc/passes/check_doc_cfg.rs b/src/librustdoc/passes/check_doc_cfg.rs index 63dc375a13c6..9e7fae5e14e4 100644 --- a/src/librustdoc/passes/check_doc_cfg.rs +++ b/src/librustdoc/passes/check_doc_cfg.rs @@ -1,9 +1,8 @@ -#![allow(dead_code, unused_imports)] - -use rustc_hir::HirId; +use rustc_attr_parsing::{ShouldEmit, eval_config_entry}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::LocalDefId; +use rustc_hir::{Attribute, HirId}; use rustc_middle::ty::TyCtxt; -use rustc_span::sym; use super::Pass; use crate::clean::{Attributes, Crate, Item}; @@ -16,59 +15,58 @@ pub(crate) const CHECK_DOC_CFG: Pass = Pass { description: "checks `#[doc(cfg(...))]` for stability feature and unexpected cfgs", }; -pub(crate) fn check_doc_cfg(krate: Crate, _cx: &mut DocContext<'_>) -> Crate { - // let mut checker = DocCfgChecker { cx }; - // checker.visit_crate(&krate); +pub(crate) fn check_doc_cfg(krate: Crate, cx: &mut DocContext<'_>) -> Crate { + let mut checker = DocCfgChecker { cx }; + checker.visit_crate(&krate); krate } -// struct RustdocCfgMatchesLintEmitter<'a>(TyCtxt<'a>, HirId); +struct RustdocCfgMatchesLintEmitter<'a>(TyCtxt<'a>, HirId); -// impl<'a> rustc_attr_parsing::CfgMatchesLintEmitter for RustdocCfgMatchesLintEmitter<'a> { -// fn emit_span_lint( -// &self, -// sess: &rustc_session::Session, -// lint: &'static rustc_lint::Lint, -// sp: rustc_span::Span, -// builtin_diag: rustc_lint_defs::BuiltinLintDiag, -// ) { -// self.0.node_span_lint(lint, self.1, sp, |diag| { -// rustc_lint::decorate_builtin_lint(sess, Some(self.0), builtin_diag, diag) -// }); -// } -// } +impl<'a> rustc_attr_parsing::CfgMatchesLintEmitter for RustdocCfgMatchesLintEmitter<'a> { + fn emit_span_lint( + &self, + sess: &rustc_session::Session, + lint: &'static rustc_lint::Lint, + sp: rustc_span::Span, + builtin_diag: rustc_lint_defs::BuiltinLintDiag, + ) { + self.0.node_span_lint(lint, self.1, sp, |diag| { + rustc_lint::decorate_builtin_lint(sess, Some(self.0), builtin_diag, diag) + }); + } +} -// struct DocCfgChecker<'a, 'tcx> { -// cx: &'a mut DocContext<'tcx>, -// } +struct DocCfgChecker<'a, 'tcx> { + cx: &'a mut DocContext<'tcx>, +} -// impl DocCfgChecker<'_, '_> { -// fn check_attrs(&mut self, attrs: &Attributes, did: LocalDefId) { -// for attr in &attrs.other_attrs { -// let Attribute::Parsed(AttributeKind::Doc(d)) = attr else { continue }; -// let Some(doc_cfg) = d.cfg else { continue }; +impl DocCfgChecker<'_, '_> { + fn check_attrs(&mut self, attrs: &Attributes, did: LocalDefId) { + for attr in &attrs.other_attrs { + let Attribute::Parsed(AttributeKind::Doc(d)) = attr else { continue }; -// if let Some([cfg_mi]) = doc_cfg.meta_item_list() { -// let _ = rustc_attr_parsing::cfg_matches( -// cfg_mi, -// &self.cx.tcx.sess, -// RustdocCfgMatchesLintEmitter( -// self.cx.tcx, -// self.cx.tcx.local_def_id_to_hir_id(did), -// ), -// Some(self.cx.tcx.features()), -// ); -// } -// } -// } -// } + for doc_cfg in &d.cfg { + let _ = eval_config_entry( + &self.cx.tcx.sess, + doc_cfg, + &RustdocCfgMatchesLintEmitter( + self.cx.tcx, + self.cx.tcx.local_def_id_to_hir_id(did), + ), + ShouldEmit::ErrorsAndLints, + ); + } + } + } +} -// impl DocVisitor<'_> for DocCfgChecker<'_, '_> { -// fn visit_item(&mut self, item: &'_ Item) { -// if let Some(Some(local_did)) = item.def_id().map(|did| did.as_local()) { -// self.check_attrs(&item.attrs, local_did); -// } +impl DocVisitor<'_> for DocCfgChecker<'_, '_> { + fn visit_item(&mut self, item: &'_ Item) { + if let Some(Some(local_did)) = item.def_id().map(|did| did.as_local()) { + self.check_attrs(&item.attrs, local_did); + } -// self.visit_item_recur(item); -// } -// } + self.visit_item_recur(item); + } +} From e4f57dd4b3f3f4dc0bd6c4b2484526375ef3c5cf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Dec 2025 15:48:56 +0100 Subject: [PATCH 0519/3801] Finish fixing ui tests --- .../rustc_attr_parsing/src/attributes/doc.rs | 7 +- compiler/rustc_attr_parsing/src/lib.rs | 1 + tests/rustdoc-ui/deprecated-attrs.stderr | 4 +- tests/rustdoc-ui/doc-alias-crate-level.rs | 3 - tests/rustdoc-ui/doc-alias-crate-level.stderr | 12 +- tests/rustdoc-ui/doc-alias.rs | 2 + tests/rustdoc-ui/doc-alias.stderr | 8 + tests/rustdoc-ui/doc-cfg-2.rs | 16 ++ tests/rustdoc-ui/doc-cfg-2.stderr | 60 ++++++ tests/rustdoc-ui/doc-cfg.rs | 17 +- tests/rustdoc-ui/doc-cfg.stderr | 183 ++++++++++-------- tests/rustdoc-ui/doctest/doc-test-attr.stderr | 4 +- tests/rustdoc-ui/invalid-cfg.rs | 16 +- tests/rustdoc-ui/invalid-cfg.stderr | 178 ++++++++++++++--- tests/rustdoc-ui/lints/doc-attr-2.rs | 11 ++ tests/rustdoc-ui/lints/doc-attr-2.stderr | 28 +++ tests/rustdoc-ui/lints/doc-attr.rs | 15 +- tests/rustdoc-ui/lints/doc-attr.stderr | 92 +++++---- 18 files changed, 471 insertions(+), 186 deletions(-) create mode 100644 tests/rustdoc-ui/doc-alias.rs create mode 100644 tests/rustdoc-ui/doc-alias.stderr create mode 100644 tests/rustdoc-ui/doc-cfg-2.rs create mode 100644 tests/rustdoc-ui/doc-cfg-2.stderr create mode 100644 tests/rustdoc-ui/lints/doc-attr-2.rs create mode 100644 tests/rustdoc-ui/lints/doc-attr-2.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 1fd7b702e92f..2e8249fb35be 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -442,7 +442,12 @@ impl DocParser { cx.emit_lint(AttributeLintKind::DocUnknownAny { name }, path.span()); } None => { - // FIXME: is there anything to do in this case? + let full_name = + path.segments().map(|s| s.as_str()).intersperse("::").collect::(); + cx.emit_lint( + AttributeLintKind::DocUnknownAny { name: Symbol::intern(&full_name) }, + path.span(), + ); } } } diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 37a3189f892e..3e9d8087a192 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -81,6 +81,7 @@ #![recursion_limit = "256"] // tidy-alphabetical-end #![feature(if_let_guard)] +#![feature(iter_intersperse)] #[macro_use] /// All the individual attribute parsers for each of rustc's built-in attributes. diff --git a/tests/rustdoc-ui/deprecated-attrs.stderr b/tests/rustdoc-ui/deprecated-attrs.stderr index 323257f944ce..6135b1496925 100644 --- a/tests/rustdoc-ui/deprecated-attrs.stderr +++ b/tests/rustdoc-ui/deprecated-attrs.stderr @@ -17,7 +17,7 @@ error: unknown `doc` attribute `passes` --> $DIR/deprecated-attrs.rs:9:8 | LL | #![doc(passes = "collapse-docs unindent-comments")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no longer functions + | ^^^^^^ no longer functions | = note: `doc` attribute `passes` no longer functions; see issue #44136 = note: `doc(passes)` is now a no-op @@ -26,7 +26,7 @@ error: unknown `doc` attribute `plugins` --> $DIR/deprecated-attrs.rs:14:8 | LL | #![doc(plugins = "xxx")] - | ^^^^^^^^^^^^^^^ no longer functions + | ^^^^^^^ no longer functions | = note: `doc` attribute `plugins` no longer functions; see issue #44136 and CVE-2018-1000622 = note: `doc(plugins)` is now a no-op diff --git a/tests/rustdoc-ui/doc-alias-crate-level.rs b/tests/rustdoc-ui/doc-alias-crate-level.rs index 70618ac01dfb..9ba7a63d7f10 100644 --- a/tests/rustdoc-ui/doc-alias-crate-level.rs +++ b/tests/rustdoc-ui/doc-alias-crate-level.rs @@ -1,4 +1 @@ #![doc(alias = "crate-level-not-working")] //~ ERROR - -#[doc(alias = "shouldn't work!")] //~ ERROR -pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-alias-crate-level.stderr b/tests/rustdoc-ui/doc-alias-crate-level.stderr index fc8095e03ca9..1742118a67c1 100644 --- a/tests/rustdoc-ui/doc-alias-crate-level.stderr +++ b/tests/rustdoc-ui/doc-alias-crate-level.stderr @@ -1,14 +1,8 @@ -error: '\'' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/doc-alias-crate-level.rs:3:15 - | -LL | #[doc(alias = "shouldn't work!")] - | ^^^^^^^^^^^^^^^^^ - error: `#![doc(alias = "...")]` isn't allowed as a crate-level attribute - --> $DIR/doc-alias-crate-level.rs:1:8 + --> $DIR/doc-alias-crate-level.rs:1:16 | LL | #![doc(alias = "crate-level-not-working")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doc-alias.rs b/tests/rustdoc-ui/doc-alias.rs new file mode 100644 index 000000000000..ae2a5b387191 --- /dev/null +++ b/tests/rustdoc-ui/doc-alias.rs @@ -0,0 +1,2 @@ +#[doc(alias = "shouldn't work!")] //~ ERROR +pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-alias.stderr b/tests/rustdoc-ui/doc-alias.stderr new file mode 100644 index 000000000000..1b3cc9426947 --- /dev/null +++ b/tests/rustdoc-ui/doc-alias.stderr @@ -0,0 +1,8 @@ +error: '\'' character isn't allowed in `#[doc(alias = "...")]` + --> $DIR/doc-alias.rs:1:15 + | +LL | #[doc(alias = "shouldn't work!")] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doc-cfg-2.rs b/tests/rustdoc-ui/doc-cfg-2.rs new file mode 100644 index 000000000000..bd6a2dc18be9 --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-2.rs @@ -0,0 +1,16 @@ +#![feature(doc_cfg)] + +#[doc(cfg(foo), cfg(bar))] +//~^ WARN unexpected `cfg` condition name: `foo` +//~| WARN unexpected `cfg` condition name: `bar` +#[doc(auto_cfg(42))] //~ ERROR +#[doc(auto_cfg(hide(true)))] //~ ERROR +#[doc(auto_cfg(hide(42)))] //~ ERROR +#[doc(auto_cfg(hide("a")))] //~ ERROR +#[doc(auto_cfg = 42)] //~ ERROR +#[doc(auto_cfg = "a")] //~ ERROR +// Shouldn't lint +#[doc(auto_cfg(hide(windows)))] +#[doc(auto_cfg(hide(feature = "windows")))] +#[doc(auto_cfg(hide(foo)))] +pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-cfg-2.stderr b/tests/rustdoc-ui/doc-cfg-2.stderr new file mode 100644 index 000000000000..f3d67abfb8dd --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-2.stderr @@ -0,0 +1,60 @@ +warning: unexpected `cfg` condition name: `foo` + --> $DIR/doc-cfg-2.rs:3:11 + | +LL | #[doc(cfg(foo), cfg(bar))] + | ^^^ + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `bar` + --> $DIR/doc-cfg-2.rs:3:21 + | +LL | #[doc(cfg(foo), cfg(bar))] + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(bar)` + = note: see for more information about checking conditional configuration + +error: only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` + --> $DIR/doc-cfg-2.rs:6:16 + | +LL | #[doc(auto_cfg(42))] + | ^^ + | + = note: `#[deny(invalid_doc_attributes)]` on by default + +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg-2.rs:7:21 + | +LL | #[doc(auto_cfg(hide(true)))] + | ^^^^ + +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg-2.rs:8:21 + | +LL | #[doc(auto_cfg(hide(42)))] + | ^^ + +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg-2.rs:9:21 + | +LL | #[doc(auto_cfg(hide("a")))] + | ^^^ + +error: expected boolean for `#[doc(auto_cfg = ...)]` + --> $DIR/doc-cfg-2.rs:10:18 + | +LL | #[doc(auto_cfg = 42)] + | ^^ + +error: expected boolean for `#[doc(auto_cfg = ...)]` + --> $DIR/doc-cfg-2.rs:11:18 + | +LL | #[doc(auto_cfg = "a")] + | ^^^ + +error: aborting due to 6 previous errors; 2 warnings emitted + diff --git a/tests/rustdoc-ui/doc-cfg.rs b/tests/rustdoc-ui/doc-cfg.rs index d72643e23556..f30d80aa9cda 100644 --- a/tests/rustdoc-ui/doc-cfg.rs +++ b/tests/rustdoc-ui/doc-cfg.rs @@ -1,22 +1,9 @@ #![feature(doc_cfg)] #[doc(cfg(), cfg(foo, bar))] -//~^ ERROR -//~^^ ERROR -#[doc(cfg(foo), cfg(bar))] -//~^ WARN unexpected `cfg` condition name: `foo` -//~^^ WARN unexpected `cfg` condition name: `bar` +//~^ ERROR malformed `doc` attribute input +//~| ERROR malformed `doc` attribute input #[doc(cfg())] //~ ERROR #[doc(cfg(foo, bar))] //~ ERROR -#[doc(auto_cfg(42))] //~ ERROR -#[doc(auto_cfg(hide(true)))] //~ ERROR -#[doc(auto_cfg(hide(42)))] //~ ERROR -#[doc(auto_cfg(hide("a")))] //~ ERROR #[doc(auto_cfg(hide(foo::bar)))] //~ ERROR -#[doc(auto_cfg = 42)] //~ ERROR -#[doc(auto_cfg = "a")] //~ ERROR -// Shouldn't lint -#[doc(auto_cfg(hide(windows)))] -#[doc(auto_cfg(hide(feature = "windows")))] -#[doc(auto_cfg(hide(foo)))] pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-cfg.stderr b/tests/rustdoc-ui/doc-cfg.stderr index 49e8c324facf..a4c6584d3294 100644 --- a/tests/rustdoc-ui/doc-cfg.stderr +++ b/tests/rustdoc-ui/doc-cfg.stderr @@ -1,90 +1,119 @@ -error: only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` - --> $DIR/doc-cfg.rs:11:7 - | -LL | #[doc(auto_cfg(42))] - | ^^^^^^^^^^^^ - | - = note: `#[deny(invalid_doc_attributes)]` on by default - -error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg.rs:12:21 - | -LL | #[doc(auto_cfg(hide(true)))] - | ^^^^ - -error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg.rs:13:21 - | -LL | #[doc(auto_cfg(hide(42)))] - | ^^ - -error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg.rs:14:21 - | -LL | #[doc(auto_cfg(hide("a")))] - | ^^^ - -error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg.rs:15:21 - | -LL | #[doc(auto_cfg(hide(foo::bar)))] - | ^^^^^^^^ - -error: expected boolean for `#[doc(auto_cfg = ...)]` - --> $DIR/doc-cfg.rs:16:7 - | -LL | #[doc(auto_cfg = 42)] - | ^^^^^^^^^^^^^ - -error: expected boolean for `#[doc(auto_cfg = ...)]` - --> $DIR/doc-cfg.rs:17:7 - | -LL | #[doc(auto_cfg = "a")] - | ^^^^^^^^^^^^^^ - -warning: unexpected `cfg` condition name: `foo` - --> $DIR/doc-cfg.rs:6:11 - | -LL | #[doc(cfg(foo), cfg(bar))] - | ^^^ - | - = help: expected names are: `FALSE` and `test` and 31 more - = help: to expect this configuration use `--check-cfg=cfg(foo)` - = note: see for more information about checking conditional configuration - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition name: `bar` - --> $DIR/doc-cfg.rs:6:21 - | -LL | #[doc(cfg(foo), cfg(bar))] - | ^^^ - | - = help: to expect this configuration use `--check-cfg=cfg(bar)` - = note: see for more information about checking conditional configuration - -error: `cfg` predicate is not specified - --> $DIR/doc-cfg.rs:3:7 +error[E0805]: malformed `doc` attribute input + --> $DIR/doc-cfg.rs:3:1 | LL | #[doc(cfg(), cfg(foo, bar))] - | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^--^^^^^^^^^^^^^^^^^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg(), cfg(foo, bar))] +LL + #[doc = "string"] + | +LL - #[doc(cfg(), cfg(foo, bar))] +LL + #[doc(hidden)] + | +LL - #[doc(cfg(), cfg(foo, bar))] +LL + #[doc(inline)] + | +LL - #[doc(cfg(), cfg(foo, bar))] +LL + #[doc(test)] + | -error: multiple `cfg` predicates are specified - --> $DIR/doc-cfg.rs:3:23 +error[E0805]: malformed `doc` attribute input + --> $DIR/doc-cfg.rs:3:1 | LL | #[doc(cfg(), cfg(foo, bar))] - | ^^^ + | ^^^^^^^^^^^^^^^^----------^^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg(), cfg(foo, bar))] +LL + #[doc = "string"] + | +LL - #[doc(cfg(), cfg(foo, bar))] +LL + #[doc(hidden)] + | +LL - #[doc(cfg(), cfg(foo, bar))] +LL + #[doc(inline)] + | +LL - #[doc(cfg(), cfg(foo, bar))] +LL + #[doc(test)] + | -error: `cfg` predicate is not specified - --> $DIR/doc-cfg.rs:9:7 +error[E0805]: malformed `doc` attribute input + --> $DIR/doc-cfg.rs:6:1 | LL | #[doc(cfg())] - | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^--^^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg())] +LL + #[doc = "string"] + | +LL - #[doc(cfg())] +LL + #[doc(hidden)] + | +LL - #[doc(cfg())] +LL + #[doc(inline)] + | +LL - #[doc(cfg())] +LL + #[doc(test)] + | -error: multiple `cfg` predicates are specified - --> $DIR/doc-cfg.rs:10:16 +error[E0805]: malformed `doc` attribute input + --> $DIR/doc-cfg.rs:7:1 | LL | #[doc(cfg(foo, bar))] - | ^^^ + | ^^^^^^^^^----------^^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg(foo, bar))] +LL + #[doc = "string"] + | +LL - #[doc(cfg(foo, bar))] +LL + #[doc(hidden)] + | +LL - #[doc(cfg(foo, bar))] +LL + #[doc(inline)] + | +LL - #[doc(cfg(foo, bar))] +LL + #[doc(test)] + | -error: aborting due to 11 previous errors; 2 warnings emitted +error[E0539]: malformed `doc` attribute input + --> $DIR/doc-cfg.rs:8:1 + | +LL | #[doc(auto_cfg(hide(foo::bar)))] + | ^^^^^^^^^^^^^^^^^^^^--------^^^^ + | | + | expected a valid identifier here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(auto_cfg(hide(foo::bar)))] +LL + #[doc = "string"] + | +LL - #[doc(auto_cfg(hide(foo::bar)))] +LL + #[doc(hidden)] + | +LL - #[doc(auto_cfg(hide(foo::bar)))] +LL + #[doc(inline)] + | +LL - #[doc(auto_cfg(hide(foo::bar)))] +LL + #[doc(test)] + | +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0539, E0805. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/rustdoc-ui/doctest/doc-test-attr.stderr b/tests/rustdoc-ui/doctest/doc-test-attr.stderr index 415251cc5e9d..cf7bce66ef40 100644 --- a/tests/rustdoc-ui/doctest/doc-test-attr.stderr +++ b/tests/rustdoc-ui/doctest/doc-test-attr.stderr @@ -7,10 +7,10 @@ LL | #![doc(test)] = note: `#[deny(invalid_doc_attributes)]` on by default error: `#[doc(test(...)]` takes a list of attributes - --> $DIR/doc-test-attr.rs:5:8 + --> $DIR/doc-test-attr.rs:5:13 | LL | #![doc(test = "hello")] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: unknown `doc(test)` attribute `a` --> $DIR/doc-test-attr.rs:7:13 diff --git a/tests/rustdoc-ui/invalid-cfg.rs b/tests/rustdoc-ui/invalid-cfg.rs index 7e54aeea1def..4d00edc0c7c2 100644 --- a/tests/rustdoc-ui/invalid-cfg.rs +++ b/tests/rustdoc-ui/invalid-cfg.rs @@ -1,21 +1,21 @@ #![feature(doc_cfg)] -#[doc(cfg = "x")] //~ ERROR not followed by parentheses -#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(cfg = "x")] //~ ERROR malformed `doc` attribute input +#[doc(cfg(x, y))] //~ ERROR malformed `doc` attribute input pub struct S {} // We check it also fails on private items. -#[doc(cfg = "x")] //~ ERROR not followed by parentheses -#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(cfg = "x")] //~ ERROR malformed `doc` attribute input +#[doc(cfg(x, y))] //~ ERROR malformed `doc` attribute input struct X {} // We check it also fails on hidden items. -#[doc(cfg = "x")] //~ ERROR not followed by parentheses -#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(cfg = "x")] //~ ERROR malformed `doc` attribute input +#[doc(cfg(x, y))] //~ ERROR malformed `doc` attribute input #[doc(hidden)] pub struct Y {} // We check it also fails on hidden AND private items. -#[doc(cfg = "x")] //~ ERROR not followed by parentheses -#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(cfg = "x")] //~ ERROR malformed `doc` attribute input +#[doc(cfg(x, y))] //~ ERROR malformed `doc` attribute input #[doc(hidden)] struct Z {} diff --git a/tests/rustdoc-ui/invalid-cfg.stderr b/tests/rustdoc-ui/invalid-cfg.stderr index 455626e07bd5..a23784509c8b 100644 --- a/tests/rustdoc-ui/invalid-cfg.stderr +++ b/tests/rustdoc-ui/invalid-cfg.stderr @@ -1,50 +1,180 @@ -error: `cfg` is not followed by parentheses - --> $DIR/invalid-cfg.rs:2:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:2:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^^^^^^^^^ expected this to be a list + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg = "x")] +LL + #[doc = "string"] + | +LL - #[doc(cfg = "x")] +LL + #[doc(hidden)] + | +LL - #[doc(cfg = "x")] +LL + #[doc(inline)] + | +LL - #[doc(cfg = "x")] +LL + #[doc(test)] + | -error: multiple `cfg` predicates are specified - --> $DIR/invalid-cfg.rs:3:14 +error[E0805]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:3:1 | LL | #[doc(cfg(x, y))] - | ^ + | ^^^^^^^^^------^^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg(x, y))] +LL + #[doc = "string"] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(hidden)] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(inline)] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(test)] + | -error: `cfg` is not followed by parentheses - --> $DIR/invalid-cfg.rs:7:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:7:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^^^^^^^^^ expected this to be a list + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg = "x")] +LL + #[doc = "string"] + | +LL - #[doc(cfg = "x")] +LL + #[doc(hidden)] + | +LL - #[doc(cfg = "x")] +LL + #[doc(inline)] + | +LL - #[doc(cfg = "x")] +LL + #[doc(test)] + | -error: multiple `cfg` predicates are specified - --> $DIR/invalid-cfg.rs:8:14 +error[E0805]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:8:1 | LL | #[doc(cfg(x, y))] - | ^ + | ^^^^^^^^^------^^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg(x, y))] +LL + #[doc = "string"] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(hidden)] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(inline)] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(test)] + | -error: `cfg` is not followed by parentheses - --> $DIR/invalid-cfg.rs:12:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:12:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^^^^^^^^^ expected this to be a list + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg = "x")] +LL + #[doc = "string"] + | +LL - #[doc(cfg = "x")] +LL + #[doc(hidden)] + | +LL - #[doc(cfg = "x")] +LL + #[doc(inline)] + | +LL - #[doc(cfg = "x")] +LL + #[doc(test)] + | -error: multiple `cfg` predicates are specified - --> $DIR/invalid-cfg.rs:13:14 +error[E0805]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:13:1 | LL | #[doc(cfg(x, y))] - | ^ + | ^^^^^^^^^------^^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg(x, y))] +LL + #[doc = "string"] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(hidden)] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(inline)] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(test)] + | -error: `cfg` is not followed by parentheses - --> $DIR/invalid-cfg.rs:18:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:18:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^^^^^^^^^ expected this to be a list + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg = "x")] +LL + #[doc = "string"] + | +LL - #[doc(cfg = "x")] +LL + #[doc(hidden)] + | +LL - #[doc(cfg = "x")] +LL + #[doc(inline)] + | +LL - #[doc(cfg = "x")] +LL + #[doc(test)] + | -error: multiple `cfg` predicates are specified - --> $DIR/invalid-cfg.rs:19:14 +error[E0805]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:19:1 | LL | #[doc(cfg(x, y))] - | ^ + | ^^^^^^^^^------^^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(cfg(x, y))] +LL + #[doc = "string"] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(hidden)] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(inline)] + | +LL - #[doc(cfg(x, y))] +LL + #[doc(test)] + | error: aborting due to 8 previous errors +Some errors have detailed explanations: E0539, E0805. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/rustdoc-ui/lints/doc-attr-2.rs b/tests/rustdoc-ui/lints/doc-attr-2.rs new file mode 100644 index 000000000000..e5198e347523 --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-attr-2.rs @@ -0,0 +1,11 @@ +#![doc(as_ptr)] +//~^ ERROR unknown `doc` attribute `as_ptr` + +#[doc(as_ptr)] +//~^ ERROR unknown `doc` attribute `as_ptr` +pub fn foo() {} + +#[doc(foo::bar, crate::bar::baz = "bye")] +//~^ ERROR unknown `doc` attribute `foo::bar` +//~| ERROR unknown `doc` attribute `crate::bar::baz` +fn bar() {} diff --git a/tests/rustdoc-ui/lints/doc-attr-2.stderr b/tests/rustdoc-ui/lints/doc-attr-2.stderr new file mode 100644 index 000000000000..c2bb45c5785e --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-attr-2.stderr @@ -0,0 +1,28 @@ +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr-2.rs:4:7 + | +LL | #[doc(as_ptr)] + | ^^^^^^ + | + = note: `#[deny(invalid_doc_attributes)]` on by default + +error: unknown `doc` attribute `foo::bar` + --> $DIR/doc-attr-2.rs:8:7 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^ + +error: unknown `doc` attribute `crate::bar::baz` + --> $DIR/doc-attr-2.rs:8:17 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^^^^^^^^ + +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr-2.rs:1:8 + | +LL | #![doc(as_ptr)] + | ^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc-ui/lints/doc-attr.rs b/tests/rustdoc-ui/lints/doc-attr.rs index 666aeb55cbec..b27faa81cb92 100644 --- a/tests/rustdoc-ui/lints/doc-attr.rs +++ b/tests/rustdoc-ui/lints/doc-attr.rs @@ -1,17 +1,8 @@ #![crate_type = "lib"] -#![doc(as_ptr)] -//~^ ERROR unknown `doc` attribute - -#[doc(as_ptr)] -//~^ ERROR unknown `doc` attribute -pub fn foo() {} #[doc(123)] -//~^ ERROR invalid `doc` attribute +//~^ ERROR malformed `doc` attribute #[doc("hello", "bar")] -//~^ ERROR invalid `doc` attribute -//~| ERROR invalid `doc` attribute -#[doc(foo::bar, crate::bar::baz = "bye")] -//~^ ERROR unknown `doc` attribute -//~| ERROR unknown `doc` attribute +//~^ ERROR malformed `doc` attribute +//~| ERROR malformed `doc` attribute fn bar() {} diff --git a/tests/rustdoc-ui/lints/doc-attr.stderr b/tests/rustdoc-ui/lints/doc-attr.stderr index 091ffc20d465..794b585a9de7 100644 --- a/tests/rustdoc-ui/lints/doc-attr.stderr +++ b/tests/rustdoc-ui/lints/doc-attr.stderr @@ -1,46 +1,72 @@ -error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:5:7 - | -LL | #[doc(as_ptr)] - | ^^^^^^ - | - = note: `#[deny(invalid_doc_attributes)]` on by default - -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:9:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/doc-attr.rs:3:1 | LL | #[doc(123)] - | ^^^ + | ^^^^^^---^^ + | | + | expected this to be of the form `... = "..."` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(123)] +LL + #[doc = "string"] + | +LL - #[doc(123)] +LL + #[doc(hidden)] + | +LL - #[doc(123)] +LL + #[doc(inline)] + | +LL - #[doc(123)] +LL + #[doc(test)] + | -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:11:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/doc-attr.rs:5:1 | LL | #[doc("hello", "bar")] - | ^^^^^^^ + | ^^^^^^-------^^^^^^^^^ + | | + | expected this to be of the form `... = "..."` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc("hello", "bar")] +LL + #[doc = "string"] + | +LL - #[doc("hello", "bar")] +LL + #[doc(hidden)] + | +LL - #[doc("hello", "bar")] +LL + #[doc(inline)] + | +LL - #[doc("hello", "bar")] +LL + #[doc(test)] + | -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:11:16 +error[E0539]: malformed `doc` attribute input + --> $DIR/doc-attr.rs:5:1 | LL | #[doc("hello", "bar")] - | ^^^^^ - -error: unknown `doc` attribute `foo::bar` - --> $DIR/doc-attr.rs:14:7 + | ^^^^^^^^^^^^^^^-----^^ + | | + | expected this to be of the form `... = "..."` | -LL | #[doc(foo::bar, crate::bar::baz = "bye")] - | ^^^^^^^^ - -error: unknown `doc` attribute `crate::bar::baz` - --> $DIR/doc-attr.rs:14:17 +help: try changing it to one of the following valid forms of the attribute | -LL | #[doc(foo::bar, crate::bar::baz = "bye")] - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:2:8 +LL - #[doc("hello", "bar")] +LL + #[doc = "string"] + | +LL - #[doc("hello", "bar")] +LL + #[doc(hidden)] + | +LL - #[doc("hello", "bar")] +LL + #[doc(inline)] + | +LL - #[doc("hello", "bar")] +LL + #[doc(test)] | -LL | #![doc(as_ptr)] - | ^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0539`. From 3fa499bab0313ad3893b7b765c71c1654924af32 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Dec 2025 16:50:14 +0100 Subject: [PATCH 0520/3801] Sort fluent messages --- compiler/rustc_attr_parsing/messages.ftl | 164 ++++++++++++----------- 1 file changed, 83 insertions(+), 81 deletions(-) diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 4d7716560fb2..2a98b87e7a7e 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -14,8 +14,91 @@ attr_parsing_deprecated_item_suggestion = .help = add `#![feature(deprecated_suggestion)]` to the crate root .note = see #94785 for more details +attr_parsing_doc_alias_bad_char = + {$char_} character isn't allowed in {$attr_str} + +attr_parsing_doc_alias_duplicated = doc alias is duplicated + .label = first defined here + +attr_parsing_doc_alias_empty = + {$attr_str} attribute cannot have empty value + +attr_parsing_doc_alias_malformed = + doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` + +attr_parsing_doc_alias_start_end = + {$attr_str} cannot start or end with ' ' + +attr_parsing_doc_attribute_not_attribute = + nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]` + .help = only existing builtin attributes are allowed in core/std + +attr_parsing_doc_auto_cfg_expects_hide_or_show = + only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` + +attr_parsing_doc_auto_cfg_hide_show_expects_list = + `#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items + +attr_parsing_doc_auto_cfg_hide_show_unexpected_item = + `#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items + +attr_parsing_doc_auto_cfg_wrong_literal = + expected boolean for `#[doc(auto_cfg = ...)]` + +attr_parsing_doc_invalid = + invalid `doc` attribute + +attr_parsing_doc_keyword_not_keyword = + nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]` + .help = only existing keywords are allowed in core/std + +attr_parsing_doc_test_literal = `#![doc(test(...)]` does not take a literal + +attr_parsing_doc_test_takes_list = + `#[doc(test(...)]` takes a list of attributes + +attr_parsing_doc_test_unknown = + unknown `doc(test)` attribute `{$name}` + +attr_parsing_doc_unknown_any = + unknown `doc` attribute `{$name}` + +attr_parsing_doc_unknown_include = + unknown `doc` attribute `include` + .suggestion = use `doc = include_str!` instead + +attr_parsing_doc_unknown_passes = + unknown `doc` attribute `{$name}` + .note = `doc` attribute `{$name}` no longer functions; see issue #44136 + .label = no longer functions + .no_op_note = `doc({$name})` is now a no-op + +attr_parsing_doc_unknown_plugins = + unknown `doc` attribute `plugins` + .note = `doc` attribute `plugins` no longer functions; see issue #44136 and CVE-2018-1000622 + .label = no longer functions + .no_op_note = `doc(plugins)` is now a no-op + +attr_parsing_doc_unknown_spotlight = + unknown `doc` attribute `spotlight` + .note = `doc(spotlight)` was renamed to `doc(notable_trait)` + .suggestion = use `notable_trait` instead + .no_op_note = `doc(spotlight)` is now a no-op + +attr_parsing_empty_attribute = + unused attribute + .suggestion = {$valid_without_list -> + [true] remove these parentheses + *[other] remove this attribute + } + .note = {$valid_without_list -> + [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all + *[other] using `{$attr_path}` with an empty list has no effect + } + attr_parsing_empty_confusables = expected at least one confusable name + attr_parsing_empty_link_name = link name must not be empty .label = empty link name @@ -239,84 +322,3 @@ attr_parsing_doc_alias_duplicated = doc alias is duplicated attr_parsing_whole_archive_needs_static = linking modifier `whole-archive` is only compatible with `static` linking kind - -attr_parsing_unused_no_lints_note = - attribute `{$name}` without any lints has no effect - -attr_parsing_doc_alias_empty = - {$attr_str} attribute cannot have empty value - -attr_parsing_doc_alias_bad_char = - {$char_} character isn't allowed in {$attr_str} - -attr_parsing_doc_alias_start_end = - {$attr_str} cannot start or end with ' ' - -attr_parsing_doc_keyword_not_keyword = - nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]` - .help = only existing keywords are allowed in core/std - -attr_parsing_doc_attribute_not_attribute = - nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]` - .help = only existing builtin attributes are allowed in core/std - -attr_parsing_doc_inline_conflict = - conflicting doc inlining attributes - .help = remove one of the conflicting attributes - -attr_parsing_doc_inline_conflict_first = - this attribute... - -attr_parsing_doc_inline_conflict_second = - {"."}..conflicts with this attribute - -attr_parsing_doc_auto_cfg_expects_hide_or_show = - only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` - -attr_parsing_doc_auto_cfg_hide_show_unexpected_item = - `#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items - -attr_parsing_doc_auto_cfg_hide_show_expects_list = - `#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items - -attr_parsing_doc_invalid = - invalid `doc` attribute - -attr_parsing_doc_unknown_include = - unknown `doc` attribute `include` - .suggestion = use `doc = include_str!` instead - -attr_parsing_doc_unknown_spotlight = - unknown `doc` attribute `spotlight` - .note = `doc(spotlight)` was renamed to `doc(notable_trait)` - .suggestion = use `notable_trait` instead - .no_op_note = `doc(spotlight)` is now a no-op - -attr_parsing_doc_unknown_passes = - unknown `doc` attribute `{$name}` - .note = `doc` attribute `{$name}` no longer functions; see issue #44136 - .label = no longer functions - .no_op_note = `doc({$name})` is now a no-op - -attr_parsing_doc_unknown_plugins = - unknown `doc` attribute `plugins` - .note = `doc` attribute `plugins` no longer functions; see issue #44136 and CVE-2018-1000622 - .label = no longer functions - .no_op_note = `doc(plugins)` is now a no-op - -attr_parsing_doc_unknown_any = - unknown `doc` attribute `{$name}` - -attr_parsing_doc_auto_cfg_wrong_literal = - expected boolean for `#[doc(auto_cfg = ...)]` - -attr_parsing_doc_test_takes_list = - `#[doc(test(...)]` takes a list of attributes - -attr_parsing_doc_test_unknown = - unknown `doc(test)` attribute `{$name}` - -attr_parsing_doc_test_literal = `#![doc(test(...)]` does not take a literal - -attr_parsing_doc_alias_malformed = - doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` From a36c462fb86cce3ca7abcdc9c577f68d76f0a4bf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Dec 2025 17:43:19 +0100 Subject: [PATCH 0521/3801] Update clippy code to new doc attribute API --- .../src/doc/doc_suspicious_footnotes.rs | 14 +++++++++----- src/tools/clippy/clippy_lints/src/doc/mod.rs | 2 +- .../src/doc/suspicious_doc_comments.rs | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs b/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs index 3330cc5defd3..1944cd7c91d3 100644 --- a/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs +++ b/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs @@ -1,10 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_ast::attr::AttributeExt as _; -use rustc_ast::token::CommentKind; +use rustc_ast::token::{CommentKind, DocFragmentKind}; use rustc_errors::Applicability; use rustc_hir::{AttrStyle, Attribute}; use rustc_lint::{LateContext, LintContext}; -use rustc_resolve::rustdoc::DocFragmentKind; use std::ops::Range; @@ -43,13 +42,18 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range, fragments: &F span, "looks like a footnote ref, but has no matching footnote", |diag| { - if this_fragment.kind == DocFragmentKind::SugaredDoc { - let (doc_attr, (_, doc_attr_comment_kind), attr_style) = attrs + if let DocFragmentKind::Sugared(_) = this_fragment.kind { + let (doc_attr, doc_attr_comment_kind, attr_style) = attrs .iter() .filter(|attr| attr.span().overlaps(this_fragment.span)) .rev() .find_map(|attr| { - Some((attr, attr.doc_str_and_comment_kind()?, attr.doc_resolution_scope()?)) + let (_, fragment) = attr.doc_str_and_fragment_kind()?; + let fragment = match fragment { + DocFragmentKind::Sugared(kind) => kind, + DocFragmentKind::Raw(_) => CommentKind::Line, + }; + Some((attr, fragment, attr.doc_resolution_scope()?)) }) .unwrap(); let (to_add, terminator) = match (doc_attr_comment_kind, attr_style) { diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs index 120da92da944..b11b2f8392c1 100644 --- a/src/tools/clippy/clippy_lints/src/doc/mod.rs +++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs @@ -861,7 +861,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ let (fragments, _) = attrs_to_doc_fragments( attrs.iter().filter_map(|attr| { - if attr.doc_str_and_comment_kind().is_none() || attr.span().in_external_macro(cx.sess().source_map()) { + if attr.doc_str_and_fragment_kind().is_none() || attr.span().in_external_macro(cx.sess().source_map()) { None } else { Some((attr, None)) diff --git a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs index 47d91b80e7ee..e751600f00a6 100644 --- a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs +++ b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_ast::AttrStyle; -use rustc_ast::token::CommentKind; +use rustc_ast::token::{CommentKind, DocFragmentKind}; use rustc_errors::Applicability; use rustc_hir::Attribute; use rustc_hir::attrs::AttributeKind; @@ -46,8 +46,8 @@ fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { && let Some(com) = comment.as_str().strip_prefix('!') { let sugg = match kind { - CommentKind::Line => format!("//!{com}"), - CommentKind::Block => format!("/*!{com}*/"), + DocFragmentKind::Sugared(CommentKind::Block) => format!("/*!{com}*/"), + DocFragmentKind::Sugared(CommentKind::Line) | DocFragmentKind::Raw(_) => format!("//!{com}"), }; Some((attr.span(), sugg)) } else { From aa3bf6fde949990eb75ae4f8d083109cfacba029 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Dec 2025 18:44:59 +0100 Subject: [PATCH 0522/3801] Update rustc_resolve unit tests --- compiler/rustc_resolve/src/rustdoc/tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_resolve/src/rustdoc/tests.rs b/compiler/rustc_resolve/src/rustdoc/tests.rs index 6a98ae066304..9fea6f6807e4 100644 --- a/compiler/rustc_resolve/src/rustdoc/tests.rs +++ b/compiler/rustc_resolve/src/rustdoc/tests.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::symbol::sym; -use rustc_span::{BytePos, Span}; +use rustc_span::{BytePos, DUMMY_SP, Span}; use super::{DocFragment, DocFragmentKind, source_span_for_markdown_range_inner}; @@ -17,7 +17,7 @@ fn single_backtick() { &[DocFragment { span: Span::with_root_ctxt(BytePos(8), BytePos(11)), item_id: None, - kind: DocFragmentKind::RawDoc, + kind: DocFragmentKind::Raw(DUMMY_SP), doc: sym::empty, // unused placeholder indent: 0, from_expansion: false, @@ -40,7 +40,7 @@ fn utf8() { &[DocFragment { span: Span::with_root_ctxt(BytePos(8), BytePos(14)), item_id: None, - kind: DocFragmentKind::RawDoc, + kind: DocFragmentKind::Raw(DUMMY_SP), doc: sym::empty, // unused placeholder indent: 0, from_expansion: false, From e013f772dadcaa6ea90927d95da12c177968c630 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Dec 2025 17:43:19 +0100 Subject: [PATCH 0523/3801] Update clippy code to new doc attribute API --- clippy_lints/src/doc/doc_suspicious_footnotes.rs | 14 +++++++++----- clippy_lints/src/doc/mod.rs | 2 +- clippy_lints/src/doc/suspicious_doc_comments.rs | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/clippy_lints/src/doc/doc_suspicious_footnotes.rs b/clippy_lints/src/doc/doc_suspicious_footnotes.rs index 3330cc5defd3..1944cd7c91d3 100644 --- a/clippy_lints/src/doc/doc_suspicious_footnotes.rs +++ b/clippy_lints/src/doc/doc_suspicious_footnotes.rs @@ -1,10 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_ast::attr::AttributeExt as _; -use rustc_ast::token::CommentKind; +use rustc_ast::token::{CommentKind, DocFragmentKind}; use rustc_errors::Applicability; use rustc_hir::{AttrStyle, Attribute}; use rustc_lint::{LateContext, LintContext}; -use rustc_resolve::rustdoc::DocFragmentKind; use std::ops::Range; @@ -43,13 +42,18 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range, fragments: &F span, "looks like a footnote ref, but has no matching footnote", |diag| { - if this_fragment.kind == DocFragmentKind::SugaredDoc { - let (doc_attr, (_, doc_attr_comment_kind), attr_style) = attrs + if let DocFragmentKind::Sugared(_) = this_fragment.kind { + let (doc_attr, doc_attr_comment_kind, attr_style) = attrs .iter() .filter(|attr| attr.span().overlaps(this_fragment.span)) .rev() .find_map(|attr| { - Some((attr, attr.doc_str_and_comment_kind()?, attr.doc_resolution_scope()?)) + let (_, fragment) = attr.doc_str_and_fragment_kind()?; + let fragment = match fragment { + DocFragmentKind::Sugared(kind) => kind, + DocFragmentKind::Raw(_) => CommentKind::Line, + }; + Some((attr, fragment, attr.doc_resolution_scope()?)) }) .unwrap(); let (to_add, terminator) = match (doc_attr_comment_kind, attr_style) { diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 120da92da944..b11b2f8392c1 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -861,7 +861,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ let (fragments, _) = attrs_to_doc_fragments( attrs.iter().filter_map(|attr| { - if attr.doc_str_and_comment_kind().is_none() || attr.span().in_external_macro(cx.sess().source_map()) { + if attr.doc_str_and_fragment_kind().is_none() || attr.span().in_external_macro(cx.sess().source_map()) { None } else { Some((attr, None)) diff --git a/clippy_lints/src/doc/suspicious_doc_comments.rs b/clippy_lints/src/doc/suspicious_doc_comments.rs index 47d91b80e7ee..e751600f00a6 100644 --- a/clippy_lints/src/doc/suspicious_doc_comments.rs +++ b/clippy_lints/src/doc/suspicious_doc_comments.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_ast::AttrStyle; -use rustc_ast::token::CommentKind; +use rustc_ast::token::{CommentKind, DocFragmentKind}; use rustc_errors::Applicability; use rustc_hir::Attribute; use rustc_hir::attrs::AttributeKind; @@ -46,8 +46,8 @@ fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { && let Some(com) = comment.as_str().strip_prefix('!') { let sugg = match kind { - CommentKind::Line => format!("//!{com}"), - CommentKind::Block => format!("/*!{com}*/"), + DocFragmentKind::Sugared(CommentKind::Block) => format!("/*!{com}*/"), + DocFragmentKind::Sugared(CommentKind::Line) | DocFragmentKind::Raw(_) => format!("//!{com}"), }; Some((attr.span(), sugg)) } else { From 4936973d49d653d01a114a00a14d427e37296775 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Dec 2025 01:23:38 +0100 Subject: [PATCH 0524/3801] Fix ui tests --- .../rustc_attr_parsing/src/attributes/doc.rs | 40 ++++- compiler/rustc_attr_parsing/src/interface.rs | 3 +- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 10 +- compiler/rustc_passes/src/check_attr.rs | 58 ++++--- tests/rustdoc-ui/bad-render-options.stderr | 63 ++++---- tests/rustdoc-ui/check-doc-alias-attr.stderr | 14 +- tests/rustdoc-ui/doc-cfg.stderr | 35 +++-- tests/rustdoc-ui/invalid-cfg.stderr | 56 ++++--- tests/rustdoc-ui/lints/doc-attr.stderr | 21 +-- tests/ui/attributes/doc-attr.rs | 6 +- tests/ui/attributes/doc-attr.stderr | 93 ++++++++--- tests/ui/attributes/doc-test-literal.rs | 2 +- tests/ui/attributes/doc-test-literal.stderr | 25 ++- .../extented-attribute-macro-error.rs | 1 + .../extented-attribute-macro-error.stderr | 8 +- .../ui/attributes/issue-115264-expr-field.rs | 2 + .../attributes/issue-115264-expr-field.stderr | 12 ++ tests/ui/attributes/issue-115264-pat-field.rs | 2 + .../attributes/issue-115264-pat-field.stderr | 12 ++ .../attributes/key-value-expansion-scope.rs | 16 ++ .../key-value-expansion-scope.stderr | 148 +++++++++++++++--- .../ui/attributes/key-value-expansion.stderr | 12 +- tests/ui/attributes/malformed-attrs.stderr | 66 ++++---- ...es-note-version-and-pr-issue-141619.stderr | 2 +- .../invalid-utf8-binary-file.rs | 4 +- .../invalid-utf8-binary-file.stderr | 8 +- tests/ui/lint/unused/useless-comment.rs | 16 +- tests/ui/lint/unused/useless-comment.stderr | 70 +++++++-- .../ui/malformed/malformed-regressions.stderr | 24 ++- .../attribute/attr-unquoted-ident.stderr | 13 -- .../rustdoc/check-doc-alias-attr-location.rs | 17 +- .../check-doc-alias-attr-location.stderr | 67 ++++++-- tests/ui/rustdoc/check-doc-alias-attr.stderr | 63 ++++++-- tests/ui/rustdoc/doc-alias-crate-level.stderr | 4 +- tests/ui/rustdoc/doc-alias-same-name.stderr | 6 +- tests/ui/rustdoc/doc-primitive.stderr | 2 +- tests/ui/rustdoc/doc-test-attr.stderr | 4 +- tests/ui/rustdoc/doc_keyword.rs | 6 +- tests/ui/rustdoc/doc_keyword.stderr | 30 ++-- tests/ui/rustdoc/duplicate_doc_alias.stderr | 8 +- 41 files changed, 730 insertions(+), 321 deletions(-) create mode 100644 tests/ui/attributes/issue-115264-expr-field.stderr create mode 100644 tests/ui/attributes/issue-115264-pat-field.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 2e8249fb35be..83a6c4fc44d9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -10,7 +10,7 @@ use rustc_hir::lints::AttributeLintKind; use rustc_span::{Span, Symbol, edition, sym}; use thin_vec::ThinVec; -use super::prelude::{Allow, AllowedTargets, MethodKind, Target}; +use super::prelude::{Allow, AllowedTargets, Error, MethodKind, Target}; use super::{AcceptMapping, AttributeParser}; use crate::context::{AcceptContext, FinalizeContext, Stage}; use crate::fluent_generated as fluent; @@ -459,7 +459,9 @@ impl DocParser { ) { match args { ArgParser::NoArgs => { - todo!() + let suggestions = cx.suggestions(); + let span = cx.attr_span; + cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); } ArgParser::List(items) => { for i in items.mixed() { @@ -493,12 +495,41 @@ impl DocParser { impl AttributeParser for DocParser { const ATTRIBUTES: AcceptMapping = &[( &[sym::doc], - template!(List: &["hidden", "inline", "test"], NameValueStr: "string"), + template!( + List: &[ + "alias", + "attribute", + "hidden", + "html_favicon_url", + "html_logo_url", + "html_no_source", + "html_playground_url", + "html_root_url", + "issue_tracker_base_url", + "inline", + "no_inline", + "masked", + "cfg", + "notable_trait", + "keyword", + "fake_variadic", + "search_unbox", + "rust_logo", + "auto_cfg", + "test", + "spotlight", + "include", + "no_default_passes", + "passes", + "plugins", + ], + NameValueStr: "string" + ), |this, cx, args| { this.accept_single_doc_attr(cx, args); }, )]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ Allow(Target::ExternCrate), Allow(Target::Use), Allow(Target::Static), @@ -527,6 +558,7 @@ impl AttributeParser for DocParser { Allow(Target::ForeignTy), Allow(Target::MacroDef), Allow(Target::Crate), + Error(Target::WherePredicate), ]); fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index b1538b447da0..5eefce75ace2 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; use rustc_ast as ast; -use rustc_ast::{AttrStyle, NodeId, Safety}; use rustc_ast::token::DocFragmentKind; +use rustc_ast::{AttrStyle, NodeId, Safety}; use rustc_errors::DiagCtxtHandle; use rustc_feature::{AttributeTemplate, Features}; use rustc_hir::attrs::AttributeKind; @@ -357,7 +357,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { continue; } - let path = parser.path(); for accept in accepts { let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext { shared: SharedContext { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 90563b21d2e8..33431556c76c 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2177,7 +2177,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { continue; } - if attr.is_doc_comment() { + if attr.doc_str_and_fragment_kind().is_some() { self.cx.sess.psess.buffer_lint( UNUSED_DOC_COMMENTS, current_span, diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index ae973a3c49c2..bf66c7f85508 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -813,19 +813,23 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: & let mut sugared_span: Option = None; while let Some(attr) = attrs.next() { - let is_doc_comment = attr.is_doc_comment(); + let (is_doc_comment, is_doc_attribute) = match &attr.kind { + AttrKind::DocComment(..) => (true, false), + AttrKind::Normal(normal) if normal.item.path == sym::doc => (true, true), + _ => (false, false), + }; if is_doc_comment { sugared_span = Some(sugared_span.map_or(attr.span, |span| span.with_hi(attr.span.hi()))); } - if attrs.peek().is_some_and(|next_attr| next_attr.is_doc_comment()) { + if !is_doc_attribute && attrs.peek().is_some_and(|next_attr| next_attr.is_doc_comment()) { continue; } let span = sugared_span.take().unwrap_or(attr.span); - if is_doc_comment { + if is_doc_comment || is_doc_attribute { let sub = match attr.kind { AttrKind::DocComment(CommentKind::Line, _) | AttrKind::Normal(..) => { BuiltinUnusedDocCommentSub::PlainHelp diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3f29d943e7d3..030839baad9b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1029,25 +1029,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - if let Some((_, span)) = keyword { - self.check_attr_not_crate_level(*span, hir_id, "keyword"); + if let Some((_, span)) = keyword + && self.check_attr_not_crate_level(*span, hir_id, "keyword") + { self.check_doc_keyword_and_attribute(*span, hir_id, "keyword"); } - if let Some((_, span)) = attribute { - self.check_attr_not_crate_level(*span, hir_id, "attribute"); + if let Some((_, span)) = attribute + && self.check_attr_not_crate_level(*span, hir_id, "attribute") + { self.check_doc_keyword_and_attribute(*span, hir_id, "attribute"); } - if let Some(span) = fake_variadic { - if self.check_attr_not_crate_level(*span, hir_id, "fake_variadic") { - self.check_doc_fake_variadic(*span, hir_id); - } + if let Some(span) = fake_variadic + && self.check_attr_not_crate_level(*span, hir_id, "fake_variadic") + { + self.check_doc_fake_variadic(*span, hir_id); } - if let Some(span) = search_unbox { - if self.check_attr_not_crate_level(*span, hir_id, "search_unbox") { - self.check_doc_search_unbox(*span, hir_id); - } + if let Some(span) = search_unbox + && self.check_attr_not_crate_level(*span, hir_id, "search_unbox") + { + self.check_doc_search_unbox(*span, hir_id); } for i in [ @@ -1070,18 +1072,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_doc_inline(hir_id, target, inline); - if let Some(span) = rust_logo { - if self.check_attr_crate_level(*span, hir_id) - && !self.tcx.features().rustdoc_internals() - { - feature_err( - &self.tcx.sess, - sym::rustdoc_internals, - *span, - fluent::passes_doc_rust_logo, - ) - .emit(); - } + if let Some(span) = rust_logo + && self.check_attr_crate_level(*span, hir_id) + && !self.tcx.features().rustdoc_internals() + { + feature_err( + &self.tcx.sess, + sym::rustdoc_internals, + *span, + fluent::passes_doc_rust_logo, + ) + .emit(); } if let Some(span) = masked { @@ -1984,7 +1985,14 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { .hir_attrs(where_predicate.hir_id) .iter() .filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym))) - .filter(|attr| !attr.is_parsed_attr()) + // FIXME: We shouldn't need to special-case `doc`! + .filter(|attr| { + matches!( + attr, + Attribute::Parsed(AttributeKind::DocComment { .. } | AttributeKind::Doc(_)) + | Attribute::Unparsed(_) + ) + }) .map(|attr| attr.span()) .collect::>(); if !spans.is_empty() { diff --git a/tests/rustdoc-ui/bad-render-options.stderr b/tests/rustdoc-ui/bad-render-options.stderr index e7f33f4dff1d..296a41337f33 100644 --- a/tests/rustdoc-ui/bad-render-options.stderr +++ b/tests/rustdoc-ui/bad-render-options.stderr @@ -12,14 +12,15 @@ LL - #![doc(html_favicon_url)] LL + #![doc = "string"] | LL - #![doc(html_favicon_url)] -LL + #![doc(hidden)] +LL + #![doc(alias)] | LL - #![doc(html_favicon_url)] -LL + #![doc(inline)] +LL + #![doc(attribute)] | LL - #![doc(html_favicon_url)] -LL + #![doc(test)] +LL + #![doc(auto_cfg)] | + = and 21 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:6:1 @@ -35,14 +36,15 @@ LL - #![doc(html_logo_url)] LL + #![doc = "string"] | LL - #![doc(html_logo_url)] -LL + #![doc(hidden)] +LL + #![doc(alias)] | LL - #![doc(html_logo_url)] -LL + #![doc(inline)] +LL + #![doc(attribute)] | LL - #![doc(html_logo_url)] -LL + #![doc(test)] +LL + #![doc(auto_cfg)] | + = and 21 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:9:1 @@ -58,14 +60,15 @@ LL - #![doc(html_playground_url)] LL + #![doc = "string"] | LL - #![doc(html_playground_url)] -LL + #![doc(hidden)] +LL + #![doc(alias)] | LL - #![doc(html_playground_url)] -LL + #![doc(inline)] +LL + #![doc(attribute)] | LL - #![doc(html_playground_url)] -LL + #![doc(test)] +LL + #![doc(auto_cfg)] | + = and 21 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:12:1 @@ -81,14 +84,15 @@ LL - #![doc(issue_tracker_base_url)] LL + #![doc = "string"] | LL - #![doc(issue_tracker_base_url)] -LL + #![doc(hidden)] +LL + #![doc(alias)] | LL - #![doc(issue_tracker_base_url)] -LL + #![doc(inline)] +LL + #![doc(attribute)] | LL - #![doc(issue_tracker_base_url)] -LL + #![doc(test)] +LL + #![doc(auto_cfg)] | + = and 21 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:15:1 @@ -104,14 +108,15 @@ LL - #![doc(html_favicon_url = 1)] LL + #![doc = "string"] | LL - #![doc(html_favicon_url = 1)] -LL + #![doc(hidden)] +LL + #![doc(alias)] | LL - #![doc(html_favicon_url = 1)] -LL + #![doc(inline)] +LL + #![doc(attribute)] | LL - #![doc(html_favicon_url = 1)] -LL + #![doc(test)] +LL + #![doc(auto_cfg)] | + = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:18:1 @@ -127,14 +132,15 @@ LL - #![doc(html_logo_url = 2)] LL + #![doc = "string"] | LL - #![doc(html_logo_url = 2)] -LL + #![doc(hidden)] +LL + #![doc(alias)] | LL - #![doc(html_logo_url = 2)] -LL + #![doc(inline)] +LL + #![doc(attribute)] | LL - #![doc(html_logo_url = 2)] -LL + #![doc(test)] +LL + #![doc(auto_cfg)] | + = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:21:1 @@ -150,14 +156,15 @@ LL - #![doc(html_playground_url = 3)] LL + #![doc = "string"] | LL - #![doc(html_playground_url = 3)] -LL + #![doc(hidden)] +LL + #![doc(alias)] | LL - #![doc(html_playground_url = 3)] -LL + #![doc(inline)] +LL + #![doc(attribute)] | LL - #![doc(html_playground_url = 3)] -LL + #![doc(test)] +LL + #![doc(auto_cfg)] | + = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:24:1 @@ -173,14 +180,15 @@ LL - #![doc(issue_tracker_base_url = 4)] LL + #![doc = "string"] | LL - #![doc(issue_tracker_base_url = 4)] -LL + #![doc(hidden)] +LL + #![doc(alias)] | LL - #![doc(issue_tracker_base_url = 4)] -LL + #![doc(inline)] +LL + #![doc(attribute)] | LL - #![doc(issue_tracker_base_url = 4)] -LL + #![doc(test)] +LL + #![doc(auto_cfg)] | + = and 22 other candidates error[E0565]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:27:1 @@ -196,14 +204,15 @@ LL - #![doc(html_no_source = "asdf")] LL + #![doc = "string"] | LL - #![doc(html_no_source = "asdf")] -LL + #![doc(hidden)] +LL + #![doc(alias)] | LL - #![doc(html_no_source = "asdf")] -LL + #![doc(inline)] +LL + #![doc(attribute)] | LL - #![doc(html_no_source = "asdf")] -LL + #![doc(test)] +LL + #![doc(auto_cfg)] | + = and 22 other candidates error: aborting due to 9 previous errors diff --git a/tests/rustdoc-ui/check-doc-alias-attr.stderr b/tests/rustdoc-ui/check-doc-alias-attr.stderr index 06d5c6535191..6c33f10e8785 100644 --- a/tests/rustdoc-ui/check-doc-alias-attr.stderr +++ b/tests/rustdoc-ui/check-doc-alias-attr.stderr @@ -18,14 +18,15 @@ LL - #[doc(alias = 0)] LL + #[doc = "string"] | LL - #[doc(alias = 0)] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(alias = 0)] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(alias = 0)] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:9:15 @@ -85,14 +86,15 @@ LL - #[doc(alias(0))] LL + #[doc = "string"] | LL - #[doc(alias(0))] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(alias(0))] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(alias(0))] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:20:13 diff --git a/tests/rustdoc-ui/doc-cfg.stderr b/tests/rustdoc-ui/doc-cfg.stderr index a4c6584d3294..0efeac66554c 100644 --- a/tests/rustdoc-ui/doc-cfg.stderr +++ b/tests/rustdoc-ui/doc-cfg.stderr @@ -12,14 +12,15 @@ LL - #[doc(cfg(), cfg(foo, bar))] LL + #[doc = "string"] | LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/doc-cfg.rs:3:1 @@ -35,14 +36,15 @@ LL - #[doc(cfg(), cfg(foo, bar))] LL + #[doc = "string"] | LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/doc-cfg.rs:6:1 @@ -58,14 +60,15 @@ LL - #[doc(cfg())] LL + #[doc = "string"] | LL - #[doc(cfg())] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg())] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg())] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/doc-cfg.rs:7:1 @@ -81,14 +84,15 @@ LL - #[doc(cfg(foo, bar))] LL + #[doc = "string"] | LL - #[doc(cfg(foo, bar))] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg(foo, bar))] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg(foo, bar))] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/doc-cfg.rs:8:1 @@ -104,14 +108,15 @@ LL - #[doc(auto_cfg(hide(foo::bar)))] LL + #[doc = "string"] | LL - #[doc(auto_cfg(hide(foo::bar)))] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(auto_cfg(hide(foo::bar)))] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(auto_cfg(hide(foo::bar)))] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error: aborting due to 5 previous errors diff --git a/tests/rustdoc-ui/invalid-cfg.stderr b/tests/rustdoc-ui/invalid-cfg.stderr index a23784509c8b..3363dbb56fb4 100644 --- a/tests/rustdoc-ui/invalid-cfg.stderr +++ b/tests/rustdoc-ui/invalid-cfg.stderr @@ -10,14 +10,15 @@ LL - #[doc(cfg = "x")] LL + #[doc = "string"] | LL - #[doc(cfg = "x")] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg = "x")] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg = "x")] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:3:1 @@ -33,14 +34,15 @@ LL - #[doc(cfg(x, y))] LL + #[doc = "string"] | LL - #[doc(cfg(x, y))] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg(x, y))] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg(x, y))] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:7:1 @@ -54,14 +56,15 @@ LL - #[doc(cfg = "x")] LL + #[doc = "string"] | LL - #[doc(cfg = "x")] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg = "x")] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg = "x")] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:8:1 @@ -77,14 +80,15 @@ LL - #[doc(cfg(x, y))] LL + #[doc = "string"] | LL - #[doc(cfg(x, y))] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg(x, y))] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg(x, y))] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:12:1 @@ -98,14 +102,15 @@ LL - #[doc(cfg = "x")] LL + #[doc = "string"] | LL - #[doc(cfg = "x")] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg = "x")] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg = "x")] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:13:1 @@ -121,14 +126,15 @@ LL - #[doc(cfg(x, y))] LL + #[doc = "string"] | LL - #[doc(cfg(x, y))] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg(x, y))] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg(x, y))] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:18:1 @@ -142,14 +148,15 @@ LL - #[doc(cfg = "x")] LL + #[doc = "string"] | LL - #[doc(cfg = "x")] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg = "x")] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg = "x")] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:19:1 @@ -165,14 +172,15 @@ LL - #[doc(cfg(x, y))] LL + #[doc = "string"] | LL - #[doc(cfg(x, y))] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(cfg(x, y))] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(cfg(x, y))] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error: aborting due to 8 previous errors diff --git a/tests/rustdoc-ui/lints/doc-attr.stderr b/tests/rustdoc-ui/lints/doc-attr.stderr index 794b585a9de7..1201bd5c71f1 100644 --- a/tests/rustdoc-ui/lints/doc-attr.stderr +++ b/tests/rustdoc-ui/lints/doc-attr.stderr @@ -12,14 +12,15 @@ LL - #[doc(123)] LL + #[doc = "string"] | LL - #[doc(123)] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc(123)] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc(123)] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/doc-attr.rs:5:1 @@ -35,14 +36,15 @@ LL - #[doc("hello", "bar")] LL + #[doc = "string"] | LL - #[doc("hello", "bar")] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc("hello", "bar")] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc("hello", "bar")] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/doc-attr.rs:5:1 @@ -58,14 +60,15 @@ LL - #[doc("hello", "bar")] LL + #[doc = "string"] | LL - #[doc("hello", "bar")] -LL + #[doc(hidden)] +LL + #[doc(alias)] | LL - #[doc("hello", "bar")] -LL + #[doc(inline)] +LL + #[doc(attribute)] | LL - #[doc("hello", "bar")] -LL + #[doc(test)] +LL + #[doc(auto_cfg)] | + = and 22 other candidates error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/doc-attr.rs b/tests/ui/attributes/doc-attr.rs index 666aeb55cbec..8d733be93567 100644 --- a/tests/ui/attributes/doc-attr.rs +++ b/tests/ui/attributes/doc-attr.rs @@ -7,10 +7,10 @@ pub fn foo() {} #[doc(123)] -//~^ ERROR invalid `doc` attribute +//~^ ERROR malformed `doc` attribute #[doc("hello", "bar")] -//~^ ERROR invalid `doc` attribute -//~| ERROR invalid `doc` attribute +//~^ ERROR malformed `doc` attribute +//~| ERROR malformed `doc` attribute #[doc(foo::bar, crate::bar::baz = "bye")] //~^ ERROR unknown `doc` attribute //~| ERROR unknown `doc` attribute diff --git a/tests/ui/attributes/doc-attr.stderr b/tests/ui/attributes/doc-attr.stderr index 091ffc20d465..9234c1a0719b 100644 --- a/tests/ui/attributes/doc-attr.stderr +++ b/tests/ui/attributes/doc-attr.stderr @@ -1,3 +1,75 @@ +error[E0539]: malformed `doc` attribute input + --> $DIR/doc-attr.rs:9:1 + | +LL | #[doc(123)] + | ^^^^^^---^^ + | | + | expected this to be of the form `... = "..."` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(123)] +LL + #[doc = "string"] + | +LL - #[doc(123)] +LL + #[doc(alias)] + | +LL - #[doc(123)] +LL + #[doc(attribute)] + | +LL - #[doc(123)] +LL + #[doc(auto_cfg)] + | + = and 22 other candidates + +error[E0539]: malformed `doc` attribute input + --> $DIR/doc-attr.rs:11:1 + | +LL | #[doc("hello", "bar")] + | ^^^^^^-------^^^^^^^^^ + | | + | expected this to be of the form `... = "..."` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc("hello", "bar")] +LL + #[doc = "string"] + | +LL - #[doc("hello", "bar")] +LL + #[doc(alias)] + | +LL - #[doc("hello", "bar")] +LL + #[doc(attribute)] + | +LL - #[doc("hello", "bar")] +LL + #[doc(auto_cfg)] + | + = and 22 other candidates + +error[E0539]: malformed `doc` attribute input + --> $DIR/doc-attr.rs:11:1 + | +LL | #[doc("hello", "bar")] + | ^^^^^^^^^^^^^^^-----^^ + | | + | expected this to be of the form `... = "..."` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc("hello", "bar")] +LL + #[doc = "string"] + | +LL - #[doc("hello", "bar")] +LL + #[doc(alias)] + | +LL - #[doc("hello", "bar")] +LL + #[doc(attribute)] + | +LL - #[doc("hello", "bar")] +LL + #[doc(auto_cfg)] + | + = and 22 other candidates + error: unknown `doc` attribute `as_ptr` --> $DIR/doc-attr.rs:5:7 | @@ -6,24 +78,6 @@ LL | #[doc(as_ptr)] | = note: `#[deny(invalid_doc_attributes)]` on by default -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:9:7 - | -LL | #[doc(123)] - | ^^^ - -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:11:7 - | -LL | #[doc("hello", "bar")] - | ^^^^^^^ - -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:11:16 - | -LL | #[doc("hello", "bar")] - | ^^^^^ - error: unknown `doc` attribute `foo::bar` --> $DIR/doc-attr.rs:14:7 | @@ -34,7 +88,7 @@ error: unknown `doc` attribute `crate::bar::baz` --> $DIR/doc-attr.rs:14:17 | LL | #[doc(foo::bar, crate::bar::baz = "bye")] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: unknown `doc` attribute `as_ptr` --> $DIR/doc-attr.rs:2:8 @@ -44,3 +98,4 @@ LL | #![doc(as_ptr)] error: aborting due to 7 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/doc-test-literal.rs b/tests/ui/attributes/doc-test-literal.rs index 92fe7846f14c..f9776e9924bd 100644 --- a/tests/ui/attributes/doc-test-literal.rs +++ b/tests/ui/attributes/doc-test-literal.rs @@ -1,4 +1,4 @@ #![doc(test(""))] -//~^ ERROR `#![doc(test(...)]` does not take a literal +//~^ ERROR malformed `doc` attribute input fn main() {} diff --git a/tests/ui/attributes/doc-test-literal.stderr b/tests/ui/attributes/doc-test-literal.stderr index 39e109a76ce5..3ffbdcbb9fee 100644 --- a/tests/ui/attributes/doc-test-literal.stderr +++ b/tests/ui/attributes/doc-test-literal.stderr @@ -1,10 +1,27 @@ -error: `#![doc(test(...)]` does not take a literal - --> $DIR/doc-test-literal.rs:1:13 +error[E0565]: malformed `doc` attribute input + --> $DIR/doc-test-literal.rs:1:1 | LL | #![doc(test(""))] - | ^^ + | ^^^^^^^^^^^^--^^^ + | | + | didn't expect a literal here | - = note: `#[deny(invalid_doc_attributes)]` on by default +help: try changing it to one of the following valid forms of the attribute + | +LL - #![doc(test(""))] +LL + #![doc = "string"] + | +LL - #![doc(test(""))] +LL + #![doc(alias)] + | +LL - #![doc(test(""))] +LL + #![doc(attribute)] + | +LL - #![doc(test(""))] +LL + #![doc(auto_cfg)] + | + = and 22 other candidates error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0565`. diff --git a/tests/ui/attributes/extented-attribute-macro-error.rs b/tests/ui/attributes/extented-attribute-macro-error.rs index 83060024dac9..f85a28ad706e 100644 --- a/tests/ui/attributes/extented-attribute-macro-error.rs +++ b/tests/ui/attributes/extented-attribute-macro-error.rs @@ -3,5 +3,6 @@ #![doc = include_str!("../not_existing_file.md")] struct Documented {} //~^^ ERROR couldn't read +//~| ERROR attribute value must be a literal fn main() {} diff --git a/tests/ui/attributes/extented-attribute-macro-error.stderr b/tests/ui/attributes/extented-attribute-macro-error.stderr index 7b93b98f64cd..ed46cba3d040 100644 --- a/tests/ui/attributes/extented-attribute-macro-error.stderr +++ b/tests/ui/attributes/extented-attribute-macro-error.stderr @@ -4,5 +4,11 @@ error: couldn't read the file LL | #![doc = include_str!("../not_existing_file.md")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: attribute value must be a literal + --> $DIR/extented-attribute-macro-error.rs:3:10 + | +LL | #![doc = include_str!("../not_existing_file.md")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/attributes/issue-115264-expr-field.rs b/tests/ui/attributes/issue-115264-expr-field.rs index 8adb68deb5b4..d8189626fb0f 100644 --- a/tests/ui/attributes/issue-115264-expr-field.rs +++ b/tests/ui/attributes/issue-115264-expr-field.rs @@ -12,6 +12,8 @@ struct X { fn main() { let _ = X { #[doc(alias = "StructItem")] + //~^ WARN: attribute cannot be used on struct fields + //~| WARN: this was previously accepted by the compiler but is being phased out foo: 123, }; } diff --git a/tests/ui/attributes/issue-115264-expr-field.stderr b/tests/ui/attributes/issue-115264-expr-field.stderr new file mode 100644 index 000000000000..6bb9dfc90c93 --- /dev/null +++ b/tests/ui/attributes/issue-115264-expr-field.stderr @@ -0,0 +1,12 @@ +warning: `#[doc]` attribute cannot be used on struct fields + --> $DIR/issue-115264-expr-field.rs:14:9 + | +LL | #[doc(alias = "StructItem")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements + = note: requested on the command line with `-W unused-attributes` + +warning: 1 warning emitted + diff --git a/tests/ui/attributes/issue-115264-pat-field.rs b/tests/ui/attributes/issue-115264-pat-field.rs index 53e3b4524d60..0c8966b5893f 100644 --- a/tests/ui/attributes/issue-115264-pat-field.rs +++ b/tests/ui/attributes/issue-115264-pat-field.rs @@ -12,6 +12,8 @@ struct X { fn main() { let X { #[doc(alias = "StructItem")] + //~^ WARN: attribute cannot be used on pattern fields + //~| WARN: this was previously accepted by the compiler but is being phased out foo } = X { foo: 123 diff --git a/tests/ui/attributes/issue-115264-pat-field.stderr b/tests/ui/attributes/issue-115264-pat-field.stderr new file mode 100644 index 000000000000..a5b221110789 --- /dev/null +++ b/tests/ui/attributes/issue-115264-pat-field.stderr @@ -0,0 +1,12 @@ +warning: `#[doc]` attribute cannot be used on pattern fields + --> $DIR/issue-115264-pat-field.rs:14:9 + | +LL | #[doc(alias = "StructItem")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements + = note: requested on the command line with `-W unused-attributes` + +warning: 1 warning emitted + diff --git a/tests/ui/attributes/key-value-expansion-scope.rs b/tests/ui/attributes/key-value-expansion-scope.rs index 6688d698f9ea..b30da2eda24a 100644 --- a/tests/ui/attributes/key-value-expansion-scope.rs +++ b/tests/ui/attributes/key-value-expansion-scope.rs @@ -1,19 +1,29 @@ #![doc = in_root!()] //~ ERROR cannot find macro `in_root` //~| WARN this was previously accepted by the compiler #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` //~| WARN this was previously accepted by the compiler #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal #[doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope + //~| ERROR attribute value must be a literal #[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #[doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope + //~| ERROR attribute value must be a literal #[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal fn before() { #![doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope + //~| ERROR attribute value must be a literal #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope + //~| ERROR attribute value must be a literal #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal } macro_rules! in_root { () => { "" } } @@ -48,8 +58,10 @@ mod macros_escape { } #[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal fn block() { #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal macro_rules! in_block { () => { "" } } @@ -61,13 +73,17 @@ fn block() { #[doc = in_root!()] // OK #[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #[doc = in_mod_escape!()] // OK #[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal fn after() { #![doc = in_root!()] // OK #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #![doc = in_mod_escape!()] // OK #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal } fn main() {} diff --git a/tests/ui/attributes/key-value-expansion-scope.stderr b/tests/ui/attributes/key-value-expansion-scope.stderr index 71a83d80617a..1ebed6b8b6fc 100644 --- a/tests/ui/attributes/key-value-expansion-scope.stderr +++ b/tests/ui/attributes/key-value-expansion-scope.stderr @@ -7,7 +7,7 @@ LL | #![doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:6:10 + --> $DIR/key-value-expansion-scope.rs:7:10 | LL | #![doc = in_block!()] | ^^^^^^^^ @@ -15,7 +15,7 @@ LL | #![doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_root` in this scope - --> $DIR/key-value-expansion-scope.rs:8:9 + --> $DIR/key-value-expansion-scope.rs:10:9 | LL | #[doc = in_root!()] | ^^^^^^^ @@ -23,7 +23,7 @@ LL | #[doc = in_root!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod` in this scope - --> $DIR/key-value-expansion-scope.rs:9:9 + --> $DIR/key-value-expansion-scope.rs:12:9 | LL | #[doc = in_mod!()] | ^^^^^^ @@ -31,7 +31,7 @@ LL | #[doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod_escape` in this scope - --> $DIR/key-value-expansion-scope.rs:10:9 + --> $DIR/key-value-expansion-scope.rs:14:9 | LL | #[doc = in_mod_escape!()] | ^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | #[doc = in_mod_escape!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:11:9 + --> $DIR/key-value-expansion-scope.rs:16:9 | LL | #[doc = in_block!()] | ^^^^^^^^ @@ -47,7 +47,7 @@ LL | #[doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_root` in this scope - --> $DIR/key-value-expansion-scope.rs:13:14 + --> $DIR/key-value-expansion-scope.rs:19:14 | LL | #![doc = in_root!()] | ^^^^^^^ @@ -55,7 +55,7 @@ LL | #![doc = in_root!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod` in this scope - --> $DIR/key-value-expansion-scope.rs:14:14 + --> $DIR/key-value-expansion-scope.rs:21:14 | LL | #![doc = in_mod!()] | ^^^^^^ @@ -63,7 +63,7 @@ LL | #![doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod_escape` in this scope - --> $DIR/key-value-expansion-scope.rs:15:14 + --> $DIR/key-value-expansion-scope.rs:23:14 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | #![doc = in_mod_escape!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:16:14 + --> $DIR/key-value-expansion-scope.rs:25:14 | LL | #![doc = in_block!()] | ^^^^^^^^ @@ -79,7 +79,7 @@ LL | #![doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:50:9 + --> $DIR/key-value-expansion-scope.rs:60:9 | LL | #[doc = in_block!()] | ^^^^^^^^ @@ -87,7 +87,7 @@ LL | #[doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:52:14 + --> $DIR/key-value-expansion-scope.rs:63:14 | LL | #![doc = in_block!()] | ^^^^^^^^ @@ -95,7 +95,7 @@ LL | #![doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod` in this scope - --> $DIR/key-value-expansion-scope.rs:63:9 + --> $DIR/key-value-expansion-scope.rs:75:9 | LL | #[doc = in_mod!()] | ^^^^^^ @@ -103,7 +103,7 @@ LL | #[doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:65:9 + --> $DIR/key-value-expansion-scope.rs:78:9 | LL | #[doc = in_block!()] | ^^^^^^^^ @@ -111,7 +111,7 @@ LL | #[doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod` in this scope - --> $DIR/key-value-expansion-scope.rs:68:14 + --> $DIR/key-value-expansion-scope.rs:82:14 | LL | #![doc = in_mod!()] | ^^^^^^ @@ -119,7 +119,7 @@ LL | #![doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:70:14 + --> $DIR/key-value-expansion-scope.rs:85:14 | LL | #![doc = in_block!()] | ^^^^^^^^ @@ -138,7 +138,7 @@ LL | #![doc = in_root!()] = note: `#[deny(out_of_scope_macro_calls)]` (part of `#[deny(future_incompatible)]`) on by default error: cannot find macro `in_mod_escape` in the current scope when looking from the crate root - --> $DIR/key-value-expansion-scope.rs:4:10 + --> $DIR/key-value-expansion-scope.rs:5:10 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from the crate root @@ -148,7 +148,7 @@ LL | #![doc = in_mod_escape!()] = help: import `macro_rules` with `use` to make it callable above its definition error: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` - --> $DIR/key-value-expansion-scope.rs:21:9 + --> $DIR/key-value-expansion-scope.rs:31:9 | LL | #[doc = in_mod!()] | ^^^^^^ not found from module `macros_stay` @@ -158,7 +158,7 @@ LL | #[doc = in_mod!()] = help: import `macro_rules` with `use` to make it callable above its definition error: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` - --> $DIR/key-value-expansion-scope.rs:24:14 + --> $DIR/key-value-expansion-scope.rs:34:14 | LL | #![doc = in_mod!()] | ^^^^^^ not found from module `macros_stay` @@ -168,7 +168,7 @@ LL | #![doc = in_mod!()] = help: import `macro_rules` with `use` to make it callable above its definition error: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` - --> $DIR/key-value-expansion-scope.rs:36:9 + --> $DIR/key-value-expansion-scope.rs:46:9 | LL | #[doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from module `macros_escape` @@ -178,7 +178,7 @@ LL | #[doc = in_mod_escape!()] = help: import `macro_rules` with `use` to make it callable above its definition error: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` - --> $DIR/key-value-expansion-scope.rs:39:14 + --> $DIR/key-value-expansion-scope.rs:49:14 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from module `macros_escape` @@ -187,7 +187,103 @@ LL | #![doc = in_mod_escape!()] = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -error: aborting due to 22 previous errors +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:3:10 + | +LL | #![doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:7:10 + | +LL | #![doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:10:9 + | +LL | #[doc = in_root!()] + | ^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:12:9 + | +LL | #[doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:14:9 + | +LL | #[doc = in_mod_escape!()] + | ^^^^^^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:16:9 + | +LL | #[doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:19:14 + | +LL | #![doc = in_root!()] + | ^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:21:14 + | +LL | #![doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:23:14 + | +LL | #![doc = in_mod_escape!()] + | ^^^^^^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:25:14 + | +LL | #![doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:60:9 + | +LL | #[doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:63:14 + | +LL | #![doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:75:9 + | +LL | #[doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:78:9 + | +LL | #[doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:82:14 + | +LL | #![doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:85:14 + | +LL | #![doc = in_block!()] + | ^^^^^^^^^^^ + +error: aborting due to 38 previous errors Future incompatibility report: Future breakage diagnostic: error: cannot find macro `in_root` in the current scope when looking from the crate root @@ -203,7 +299,7 @@ LL | #![doc = in_root!()] Future breakage diagnostic: error: cannot find macro `in_mod_escape` in the current scope when looking from the crate root - --> $DIR/key-value-expansion-scope.rs:4:10 + --> $DIR/key-value-expansion-scope.rs:5:10 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from the crate root @@ -215,7 +311,7 @@ LL | #![doc = in_mod_escape!()] Future breakage diagnostic: error: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` - --> $DIR/key-value-expansion-scope.rs:21:9 + --> $DIR/key-value-expansion-scope.rs:31:9 | LL | #[doc = in_mod!()] | ^^^^^^ not found from module `macros_stay` @@ -227,7 +323,7 @@ LL | #[doc = in_mod!()] Future breakage diagnostic: error: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` - --> $DIR/key-value-expansion-scope.rs:24:14 + --> $DIR/key-value-expansion-scope.rs:34:14 | LL | #![doc = in_mod!()] | ^^^^^^ not found from module `macros_stay` @@ -239,7 +335,7 @@ LL | #![doc = in_mod!()] Future breakage diagnostic: error: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` - --> $DIR/key-value-expansion-scope.rs:36:9 + --> $DIR/key-value-expansion-scope.rs:46:9 | LL | #[doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from module `macros_escape` @@ -251,7 +347,7 @@ LL | #[doc = in_mod_escape!()] Future breakage diagnostic: error: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` - --> $DIR/key-value-expansion-scope.rs:39:14 + --> $DIR/key-value-expansion-scope.rs:49:14 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from module `macros_escape` diff --git a/tests/ui/attributes/key-value-expansion.stderr b/tests/ui/attributes/key-value-expansion.stderr index d785bf978196..54d79c5bebb7 100644 --- a/tests/ui/attributes/key-value-expansion.stderr +++ b/tests/ui/attributes/key-value-expansion.stderr @@ -1,3 +1,9 @@ +error: attribute value must be a literal + --> $DIR/key-value-expansion.rs:21:6 + | +LL | bug!((column!())); + | ^^^^^^^^^^^ + error: attribute value must be a literal --> $DIR/key-value-expansion.rs:27:14 | @@ -20,11 +26,5 @@ LL | some_macro!(u8); | = note: this error originates in the macro `some_macro` (in Nightly builds, run with -Z macro-backtrace for more info) -error: attribute value must be a literal - --> $DIR/key-value-expansion.rs:21:6 - | -LL | bug!((column!())); - | ^^^^^^^^^^^ - error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 0ef62d70a15c..a6bd62fa1214 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -182,27 +182,6 @@ LL | #[allow_internal_unsafe = 1] = help: add `#![feature(allow_internal_unsafe)]` 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: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:41:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:77:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit - error[E0539]: malformed `windows_subsystem` attribute input --> $DIR/malformed-attrs.rs:26:1 | @@ -790,6 +769,16 @@ LL | #[diagnostic::on_unimplemented = 1] | = help: only `message`, `note` and `label` are allowed as options +error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` + --> $DIR/malformed-attrs.rs:41:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default + error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` --> $DIR/malformed-attrs.rs:52:1 | @@ -814,6 +803,15 @@ LL | | #[coroutine = 63] || {} LL | | } | |_^ +error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` + --> $DIR/malformed-attrs.rs:77:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + warning: `#[link_name]` attribute cannot be used on functions --> $DIR/malformed-attrs.rs:88:1 | @@ -875,7 +873,7 @@ error: aborting due to 76 previous errors; 8 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. Future incompatibility report: Future breakage diagnostic: -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` +error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` --> $DIR/malformed-attrs.rs:41:1 | LL | #[doc] @@ -883,19 +881,6 @@ LL | #[doc] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 - = note: for more information, visit - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - -Future breakage diagnostic: -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:77:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default Future breakage diagnostic: @@ -909,6 +894,17 @@ LL | #[inline = 5] = note: for more information, see issue #57571 = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default +Future breakage diagnostic: +error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` + --> $DIR/malformed-attrs.rs:77:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default + Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` --> $DIR/malformed-attrs.rs:98:1 diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr index bd8c56c61c3c..d9556560b01c 100644 --- a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr +++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr @@ -11,7 +11,7 @@ error: unknown `doc` attribute `include` --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:2:8 | LL | #![doc(include("README.md"))] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ | = note: `#[deny(invalid_doc_attributes)]` on by default diff --git a/tests/ui/include-macros/invalid-utf8-binary-file.rs b/tests/ui/include-macros/invalid-utf8-binary-file.rs index 0bbdbac611fd..c733f07c26f0 100644 --- a/tests/ui/include-macros/invalid-utf8-binary-file.rs +++ b/tests/ui/include-macros/invalid-utf8-binary-file.rs @@ -5,6 +5,8 @@ //! Ensure that ICE does not occur when reading an invalid UTF8 file with an absolute path. //! regression test for issue -#![doc = include_str!(concat!(env!("INVALID_UTF8_BIN")))] //~ ERROR: wasn't a utf-8 file +#![doc = include_str!(concat!(env!("INVALID_UTF8_BIN")))] +//~^ ERROR: wasn't a utf-8 file +//~| ERROR: attribute value must be a literal fn main() {} diff --git a/tests/ui/include-macros/invalid-utf8-binary-file.stderr b/tests/ui/include-macros/invalid-utf8-binary-file.stderr index 4ac4def1b00a..232cb5042b72 100644 --- a/tests/ui/include-macros/invalid-utf8-binary-file.stderr +++ b/tests/ui/include-macros/invalid-utf8-binary-file.stderr @@ -6,5 +6,11 @@ LL | #![doc = include_str!(concat!(env!("INVALID_UTF8_BIN")))] | = note: invalid utf-8 at byte `$BYTE` -error: aborting due to 1 previous error +error: attribute value must be a literal + --> $DIR/invalid-utf8-binary-file.rs:8:10 + | +LL | #![doc = include_str!(concat!(env!("INVALID_UTF8_BIN")))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/lint/unused/useless-comment.rs b/tests/ui/lint/unused/useless-comment.rs index 898665278e39..fee6cff640f6 100644 --- a/tests/ui/lint/unused/useless-comment.rs +++ b/tests/ui/lint/unused/useless-comment.rs @@ -1,6 +1,7 @@ #![feature(stmt_expr_attributes)] #![deny(unused_doc_comments)] +#![deny(unused_attributes)] macro_rules! mac { () => {} @@ -15,7 +16,10 @@ unsafe extern "C" { } fn foo() { /// a //~ ERROR unused doc comment - #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment + #[doc(test(attr(allow(dead_code))))] + //~^ ERROR unused doc comment + //~| ERROR `#[doc]` attribute cannot be used on statements + //~| WARN this was previously accepted by the compiler let x = 12; /// multi-line //~ ERROR unused doc comment @@ -24,7 +28,10 @@ fn foo() { match x { /// c //~ ERROR unused doc comment 1 => {}, - #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment + #[doc(test(attr(allow(dead_code))))] + //~^ ERROR unused doc comment + //~| ERROR `#[doc]` attribute cannot be used on match arms [unused_attributes] + //~| WARN this was previously accepted by the compiler _ => {} } @@ -38,7 +45,10 @@ fn foo() { /// bar //~ ERROR unused doc comment mac!(); - #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment + #[doc(test(attr(allow(dead_code))))] + //~^ ERROR unused doc comment + //~| ERROR `#[doc]` attribute cannot be used on statements + //~| WARN this was previously accepted by the compiler let x = /** comment */ 47; //~ ERROR unused doc comment /// dox //~ ERROR unused doc comment diff --git a/tests/ui/lint/unused/useless-comment.stderr b/tests/ui/lint/unused/useless-comment.stderr index 39873b82b757..3d3937e7a402 100644 --- a/tests/ui/lint/unused/useless-comment.stderr +++ b/tests/ui/lint/unused/useless-comment.stderr @@ -1,5 +1,5 @@ error: unused doc comment - --> $DIR/useless-comment.rs:9:1 + --> $DIR/useless-comment.rs:10:1 | LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations @@ -12,7 +12,7 @@ LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ error: unused doc comment - --> $DIR/useless-comment.rs:12:1 + --> $DIR/useless-comment.rs:13:1 | LL | /// a | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | unsafe extern "C" { } = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:13:1 + --> $DIR/useless-comment.rs:14:1 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | unsafe extern "C" { } = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:38:5 + --> $DIR/useless-comment.rs:45:5 | LL | /// bar | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations @@ -41,28 +41,29 @@ LL | /// bar = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion error: unused doc comment - --> $DIR/useless-comment.rs:17:5 + --> $DIR/useless-comment.rs:18:5 | LL | /// a | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | #[doc(test(attr(allow(dead_code))))] +... LL | let x = 12; | ----------- rustdoc does not generate documentation for statements | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:18:5 + --> $DIR/useless-comment.rs:19:5 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | let x = 12; | ----------- rustdoc does not generate documentation for statements | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:21:5 + --> $DIR/useless-comment.rs:25:5 | LL | / /// multi-line LL | | /// doc comment @@ -72,6 +73,7 @@ LL | / match x { LL | | /// c LL | | 1 => {}, LL | | #[doc(test(attr(allow(dead_code))))] +... | LL | | _ => {} LL | | } | |_____- rustdoc does not generate documentation for expressions @@ -79,7 +81,7 @@ LL | | } = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:25:9 + --> $DIR/useless-comment.rs:29:9 | LL | /// c | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,17 +91,18 @@ LL | 1 => {}, = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:27:9 + --> $DIR/useless-comment.rs:31:9 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | _ => {} | ------- rustdoc does not generate documentation for match arms | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:31:5 + --> $DIR/useless-comment.rs:38:5 | LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,7 +112,7 @@ LL | unsafe {} = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:34:5 + --> $DIR/useless-comment.rs:41:5 | LL | #[doc = "foo"] | ^^^^^^^^^^^^^^ @@ -120,7 +123,7 @@ LL | 3; = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:35:5 + --> $DIR/useless-comment.rs:42:5 | LL | #[doc = "bar"] | ^^^^^^^^^^^^^^ @@ -130,17 +133,18 @@ LL | 3; = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:41:5 + --> $DIR/useless-comment.rs:48:5 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | let x = /** comment */ 47; | -------------------------- rustdoc does not generate documentation for statements | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:42:13 + --> $DIR/useless-comment.rs:52:13 | LL | let x = /** comment */ 47; | ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions @@ -148,7 +152,7 @@ LL | let x = /** comment */ 47; = help: use `/* */` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:44:5 + --> $DIR/useless-comment.rs:54:5 | LL | /// dox | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -159,5 +163,37 @@ LL | | } | = help: use `//` for a plain comment -error: aborting due to 15 previous errors +error: `#[doc]` attribute cannot be used on statements + --> $DIR/useless-comment.rs:19:5 + | +LL | #[doc(test(attr(allow(dead_code))))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements +note: the lint level is defined here + --> $DIR/useless-comment.rs:4:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: `#[doc]` attribute cannot be used on match arms + --> $DIR/useless-comment.rs:31:9 + | +LL | #[doc(test(attr(allow(dead_code))))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements + +error: `#[doc]` attribute cannot be used on statements + --> $DIR/useless-comment.rs:48:5 + | +LL | #[doc(test(attr(allow(dead_code))))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements + +error: aborting due to 18 previous errors diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index 181207984877..29734fd84e6b 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr @@ -1,14 +1,3 @@ -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-regressions.rs:1:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - error[E0539]: malformed `link` attribute input --> $DIR/malformed-regressions.rs:7:1 | @@ -63,6 +52,16 @@ LL | fn main() {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: requested on the command line with `-W unused-attributes` +error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` + --> $DIR/malformed-regressions.rs:1:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default + error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` --> $DIR/malformed-regressions.rs:3:1 | @@ -85,7 +84,7 @@ error: aborting due to 5 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` +error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` --> $DIR/malformed-regressions.rs:1:1 | LL | #[doc] @@ -93,7 +92,6 @@ LL | #[doc] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 - = note: for more information, visit = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default Future breakage diagnostic: diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.stderr b/tests/ui/parser/attribute/attr-unquoted-ident.stderr index f1af60dec9bb..00fb539f8a86 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.stderr +++ b/tests/ui/parser/attribute/attr-unquoted-ident.stderr @@ -20,19 +20,6 @@ help: surround the identifier with quotation marks to make it into a string lite LL | #[cfg(key="foo bar baz")] | + + -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression - --> $DIR/attr-unquoted-ident.rs:18:15 - | -LL | #[cfg(key=foo 1 bar 2.0 baz.)] - | ^^^ expressions are not allowed here - | -help: surround the identifier with quotation marks to make it into a string literal - | -LL | #[cfg(key="foo 1 bar 2.0 baz.")] - | + + - -error: expected unsuffixed literal, found identifier `nickname` - --> $DIR/attr-unquoted-ident.rs:28:38 | LL | ($name:ident) => { #[doc(alias = $name)] pub struct S; } | ^^^^^ diff --git a/tests/ui/rustdoc/check-doc-alias-attr-location.rs b/tests/ui/rustdoc/check-doc-alias-attr-location.rs index 10609e5d8f4d..8ba6cfde2d6d 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr-location.rs +++ b/tests/ui/rustdoc/check-doc-alias-attr-location.rs @@ -21,11 +21,22 @@ impl Foo for Bar { type X = i32; fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X { //~^ ERROR - #[doc(alias = "stmt")] //~ ERROR + //~| WARN `#[doc]` attribute cannot be used on function params + //~| WARN: this was previously accepted by the compiler + #[doc(alias = "stmt")] + //~^ ERROR + //~| WARN `#[doc]` attribute cannot be used on statements + //~| WARN: this was previously accepted by the compiler let x = 0; - #[doc(alias = "expr")] //~ ERROR + #[doc(alias = "expr")] + //~^ ERROR + //~| WARN `#[doc]` attribute cannot be used on expressions + //~| WARN: this was previously accepted by the compiler match x { - #[doc(alias = "arm")] //~ ERROR + #[doc(alias = "arm")] + //~^ ERROR + //~| WARN `#[doc]` attribute cannot be used on match arms + //~| WARN: this was previously accepted by the compiler _ => 0 } } diff --git a/tests/ui/rustdoc/check-doc-alias-attr-location.stderr b/tests/ui/rustdoc/check-doc-alias-attr-location.stderr index 23c93a4ed8bd..24be42036f6f 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr-location.stderr +++ b/tests/ui/rustdoc/check-doc-alias-attr-location.stderr @@ -5,46 +5,83 @@ LL | fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X { | ^^^^^^^^^^^^^^^^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on foreign module - --> $DIR/check-doc-alias-attr-location.rs:9:7 + --> $DIR/check-doc-alias-attr-location.rs:9:15 | LL | #[doc(alias = "foo")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: `#[doc(alias = "...")]` isn't allowed on implementation block - --> $DIR/check-doc-alias-attr-location.rs:12:7 + --> $DIR/check-doc-alias-attr-location.rs:12:15 | LL | #[doc(alias = "bar")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: `#[doc(alias = "...")]` isn't allowed on implementation block - --> $DIR/check-doc-alias-attr-location.rs:18:7 + --> $DIR/check-doc-alias-attr-location.rs:18:15 | LL | #[doc(alias = "foobar")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block - --> $DIR/check-doc-alias-attr-location.rs:20:11 + --> $DIR/check-doc-alias-attr-location.rs:20:19 | LL | #[doc(alias = "assoc")] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on statement - --> $DIR/check-doc-alias-attr-location.rs:24:15 + --> $DIR/check-doc-alias-attr-location.rs:26:23 | LL | #[doc(alias = "stmt")] - | ^^^^^^^^^^^^^^ + | ^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on expression - --> $DIR/check-doc-alias-attr-location.rs:26:15 + --> $DIR/check-doc-alias-attr-location.rs:31:23 | LL | #[doc(alias = "expr")] - | ^^^^^^^^^^^^^^ + | ^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on match arm - --> $DIR/check-doc-alias-attr-location.rs:28:19 + --> $DIR/check-doc-alias-attr-location.rs:36:27 | LL | #[doc(alias = "arm")] - | ^^^^^^^^^^^^^ + | ^^^^^ -error: aborting due to 8 previous errors +warning: `#[doc]` attribute cannot be used on function params + --> $DIR/check-doc-alias-attr-location.rs:22:12 + | +LL | fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements + = note: requested on the command line with `-W unused-attributes` + +warning: `#[doc]` attribute cannot be used on statements + --> $DIR/check-doc-alias-attr-location.rs:26:9 + | +LL | #[doc(alias = "stmt")] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements + +warning: `#[doc]` attribute cannot be used on expressions + --> $DIR/check-doc-alias-attr-location.rs:31:9 + | +LL | #[doc(alias = "expr")] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements + +warning: `#[doc]` attribute cannot be used on match arms + --> $DIR/check-doc-alias-attr-location.rs:36:13 + | +LL | #[doc(alias = "arm")] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements + +error: aborting due to 8 previous errors; 4 warnings emitted diff --git a/tests/ui/rustdoc/check-doc-alias-attr.stderr b/tests/ui/rustdoc/check-doc-alias-attr.stderr index 250568be3333..6c33f10e8785 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr.stderr +++ b/tests/ui/rustdoc/check-doc-alias-attr.stderr @@ -4,11 +4,29 @@ error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of s LL | #[doc(alias)] | ^^^^^ -error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` - --> $DIR/check-doc-alias-attr.rs:8:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/check-doc-alias-attr.rs:8:1 | LL | #[doc(alias = 0)] - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^-^^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(alias = 0)] +LL + #[doc = "string"] + | +LL - #[doc(alias = 0)] +LL + #[doc(alias)] + | +LL - #[doc(alias = 0)] +LL + #[doc(attribute)] + | +LL - #[doc(alias = 0)] +LL + #[doc(auto_cfg)] + | + = and 22 other candidates error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:9:15 @@ -54,25 +72,43 @@ error: `#[doc(alias = "...")]` attribute cannot have empty value LL | #[doc(alias = "")] | ^^ -error: `#[doc(alias("a"))]` expects string literals - --> $DIR/check-doc-alias-attr.rs:19:13 +error[E0539]: malformed `doc` attribute input + --> $DIR/check-doc-alias-attr.rs:19:1 | LL | #[doc(alias(0))] - | ^ + | ^^^^^^^^^^^^-^^^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[doc(alias(0))] +LL + #[doc = "string"] + | +LL - #[doc(alias(0))] +LL + #[doc(alias)] + | +LL - #[doc(alias(0))] +LL + #[doc(attribute)] + | +LL - #[doc(alias(0))] +LL + #[doc(auto_cfg)] + | + = and 22 other candidates -error: '"' character isn't allowed in `#[doc(alias("..."))]` +error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:20:13 | LL | #[doc(alias("\""))] | ^^^^ -error: '\n' character isn't allowed in `#[doc(alias("..."))]` +error: '\n' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:21:13 | LL | #[doc(alias("\n"))] | ^^^^ -error: '\n' character isn't allowed in `#[doc(alias("..."))]` +error: '\n' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:22:13 | LL | #[doc(alias(" @@ -80,25 +116,25 @@ LL | #[doc(alias(" LL | | "))] | |_^ -error: '\t' character isn't allowed in `#[doc(alias("..."))]` +error: '\t' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:24:13 | LL | #[doc(alias("\t"))] | ^^^^ -error: `#[doc(alias("..."))]` cannot start or end with ' ' +error: `#[doc(alias = "...")]` cannot start or end with ' ' --> $DIR/check-doc-alias-attr.rs:25:13 | LL | #[doc(alias(" hello"))] | ^^^^^^^^ -error: `#[doc(alias("..."))]` cannot start or end with ' ' +error: `#[doc(alias = "...")]` cannot start or end with ' ' --> $DIR/check-doc-alias-attr.rs:26:13 | LL | #[doc(alias("hello "))] | ^^^^^^^^ -error: `#[doc(alias("..."))]` attribute cannot have empty value +error: `#[doc(alias = "...")]` attribute cannot have empty value --> $DIR/check-doc-alias-attr.rs:27:13 | LL | #[doc(alias(""))] @@ -106,3 +142,4 @@ LL | #[doc(alias(""))] error: aborting due to 17 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/rustdoc/doc-alias-crate-level.stderr b/tests/ui/rustdoc/doc-alias-crate-level.stderr index bd32609ade29..a40e31714f14 100644 --- a/tests/ui/rustdoc/doc-alias-crate-level.stderr +++ b/tests/ui/rustdoc/doc-alias-crate-level.stderr @@ -5,10 +5,10 @@ LL | #[doc(alias = "shouldn't work!")] | ^^^^^^^^^^^^^^^^^ error: `#![doc(alias = "...")]` isn't allowed as a crate-level attribute - --> $DIR/doc-alias-crate-level.rs:5:8 + --> $DIR/doc-alias-crate-level.rs:5:16 | LL | #![doc(alias = "not working!")] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/rustdoc/doc-alias-same-name.stderr b/tests/ui/rustdoc/doc-alias-same-name.stderr index a9da75c0171c..a76ff5ee0b67 100644 --- a/tests/ui/rustdoc/doc-alias-same-name.stderr +++ b/tests/ui/rustdoc/doc-alias-same-name.stderr @@ -1,8 +1,8 @@ -error: `#[doc(alias = "...")]` is the same as the item's name - --> $DIR/doc-alias-same-name.rs:3:7 +error: `#[doc(alias = "Foo"]` is the same as the item's name + --> $DIR/doc-alias-same-name.rs:3:15 | LL | #[doc(alias = "Foo")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rustdoc/doc-primitive.stderr b/tests/ui/rustdoc/doc-primitive.stderr index 8f6f330b3e5d..4ba310ca2410 100644 --- a/tests/ui/rustdoc/doc-primitive.stderr +++ b/tests/ui/rustdoc/doc-primitive.stderr @@ -2,7 +2,7 @@ error: unknown `doc` attribute `primitive` --> $DIR/doc-primitive.rs:3:7 | LL | #[doc(primitive = "foo")] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ | note: the lint level is defined here --> $DIR/doc-primitive.rs:1:9 diff --git a/tests/ui/rustdoc/doc-test-attr.stderr b/tests/ui/rustdoc/doc-test-attr.stderr index 51672314a431..1a4b5e45142a 100644 --- a/tests/ui/rustdoc/doc-test-attr.stderr +++ b/tests/ui/rustdoc/doc-test-attr.stderr @@ -11,10 +11,10 @@ LL | #![deny(invalid_doc_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^ error: `#[doc(test(...)]` takes a list of attributes - --> $DIR/doc-test-attr.rs:6:8 + --> $DIR/doc-test-attr.rs:6:13 | LL | #![doc(test = "hello")] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: unknown `doc(test)` attribute `a` --> $DIR/doc-test-attr.rs:8:13 diff --git a/tests/ui/rustdoc/doc_keyword.rs b/tests/ui/rustdoc/doc_keyword.rs index e0995f336da3..abf06d7a7866 100644 --- a/tests/ui/rustdoc/doc_keyword.rs +++ b/tests/ui/rustdoc/doc_keyword.rs @@ -1,14 +1,14 @@ #![crate_type = "lib"] #![feature(rustdoc_internals)] -#![doc(keyword = "hello")] +#![doc(keyword = "match")] //~^ ERROR `#![doc(keyword = "...")]` isn't allowed as a crate-level attribute -#[doc(keyword = "hell")] //~ ERROR `#[doc(keyword = "...")]` should be used on empty modules +#[doc(keyword = "match")] //~ ERROR `#[doc(keyword = "...")]` should be used on empty modules mod foo { fn hell() {} } -#[doc(keyword = "hall")] //~ ERROR `#[doc(keyword = "...")]` should be used on modules +#[doc(keyword = "match")] //~ ERROR `#[doc(keyword = "...")]` should be used on modules fn foo() {} diff --git a/tests/ui/rustdoc/doc_keyword.stderr b/tests/ui/rustdoc/doc_keyword.stderr index 584daae2f1aa..56da4b00724a 100644 --- a/tests/ui/rustdoc/doc_keyword.stderr +++ b/tests/ui/rustdoc/doc_keyword.stderr @@ -1,15 +1,3 @@ -error: `#[doc(keyword = "...")]` should be used on empty modules - --> $DIR/doc_keyword.rs:6:7 - | -LL | #[doc(keyword = "hell")] - | ^^^^^^^^^^^^^^^^ - -error: `#[doc(keyword = "...")]` should be used on modules - --> $DIR/doc_keyword.rs:11:7 - | -LL | #[doc(keyword = "hall")] - | ^^^^^^^^^^^^^^^^ - error: nonexistent keyword `tadam` used in `#[doc(keyword = "...")]` --> $DIR/doc_keyword.rs:22:17 | @@ -18,17 +6,29 @@ LL | #[doc(keyword = "tadam")] | = help: only existing keywords are allowed in core/std +error: `#[doc(keyword = "...")]` should be used on empty modules + --> $DIR/doc_keyword.rs:6:7 + | +LL | #[doc(keyword = "match")] + | ^^^^^^^ + +error: `#[doc(keyword = "...")]` should be used on modules + --> $DIR/doc_keyword.rs:11:7 + | +LL | #[doc(keyword = "match")] + | ^^^^^^^ + error: `#[doc(keyword = "...")]` should be used on modules --> $DIR/doc_keyword.rs:17:11 | LL | #[doc(keyword = "match")] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: `#![doc(keyword = "...")]` isn't allowed as a crate-level attribute --> $DIR/doc_keyword.rs:4:8 | -LL | #![doc(keyword = "hello")] - | ^^^^^^^^^^^^^^^^^ +LL | #![doc(keyword = "match")] + | ^^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui/rustdoc/duplicate_doc_alias.stderr b/tests/ui/rustdoc/duplicate_doc_alias.stderr index 4b2dd1f8eb68..eba48ca599b0 100644 --- a/tests/ui/rustdoc/duplicate_doc_alias.stderr +++ b/tests/ui/rustdoc/duplicate_doc_alias.stderr @@ -1,10 +1,10 @@ error: doc alias is duplicated - --> $DIR/duplicate_doc_alias.rs:4:7 + --> $DIR/duplicate_doc_alias.rs:4:15 | LL | #[doc(alias = "A")] - | ----------- first defined here + | --- first defined here LL | #[doc(alias = "A")] - | ^^^^^^^^^^^ + | ^^^ | note: the lint level is defined here --> $DIR/duplicate_doc_alias.rs:1:9 @@ -16,7 +16,7 @@ error: doc alias is duplicated --> $DIR/duplicate_doc_alias.rs:6:13 | LL | #[doc(alias = "B")] - | ----------- first defined here + | --- first defined here LL | #[doc(alias("B"))] | ^^^ From 348d9d98e07753c2adb0a303bc3855e0843efbcb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Dec 2025 22:54:56 +0100 Subject: [PATCH 0525/3801] Correctly iterate doc comments in intra-doc resolution in `rustc_resolve` --- compiler/rustc_ast/src/attr/mod.rs | 16 ++++++++++++++++ compiler/rustc_hir/src/hir.rs | 4 ++++ compiler/rustc_resolve/src/rustdoc.rs | 10 +--------- tests/rustdoc/doc-on-keyword.rs | 13 +++++++++++++ 4 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 tests/rustdoc/doc-on-keyword.rs diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 94e7462d26df..a5e630a09afe 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -233,6 +233,19 @@ impl AttributeExt for Attribute { self.has_name(sym::doc) && self.meta_item_list().is_some_and(|l| list_contains_name(&l, sym::hidden)) } + + fn is_doc_keyword_or_attribute(&self) -> bool { + if self.has_name(sym::doc) + && let Some(items) = self.meta_item_list() + { + for item in items { + if item.has_name(sym::keyword) || item.has_name(sym::attribute) { + return true; + } + } + } + false + } } impl Attribute { @@ -865,6 +878,9 @@ pub trait AttributeExt: Debug { /// Returns `true` if this attribute contains `doc(hidden)`. fn is_doc_hidden(&self) -> bool; + + /// Returns `true` is this attribute contains `doc(keyword)` or `doc(attribute)`. + fn is_doc_keyword_or_attribute(&self) -> bool; } // FIXME(fn_delegation): use function delegation instead of manually forwarding diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index afa1a33fe769..f5470adb87e0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1418,6 +1418,10 @@ impl AttributeExt for Attribute { fn is_doc_hidden(&self) -> bool { matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some()) } + + fn is_doc_keyword_or_attribute(&self) -> bool { + matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.attribute.is_some() || d.keyword.is_some()) + } } // FIXME(fn_delegation): use function delegation instead of manually forwarding diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 0ac8e68ad968..7f7c423acb40 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -367,16 +367,8 @@ pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool { /// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]` or `#[doc(attribute)]`. pub fn has_primitive_or_keyword_or_attribute_docs(attrs: &[impl AttributeExt]) -> bool { for attr in attrs { - if attr.has_name(sym::rustc_doc_primitive) { + if attr.has_name(sym::rustc_doc_primitive) || attr.is_doc_keyword_or_attribute() { return true; - } else if attr.has_name(sym::doc) - && let Some(items) = attr.meta_item_list() - { - for item in items { - if item.has_name(sym::keyword) || item.has_name(sym::attribute) { - return true; - } - } } } false diff --git a/tests/rustdoc/doc-on-keyword.rs b/tests/rustdoc/doc-on-keyword.rs new file mode 100644 index 000000000000..0c62eda60a6b --- /dev/null +++ b/tests/rustdoc/doc-on-keyword.rs @@ -0,0 +1,13 @@ +// While working on , the +// intra doc links on keyword/attribute items were not processed. + +#![feature(rustdoc_internals)] +#![crate_name = "foo"] + +//@ has 'foo/keyword.trait.html' +//@ has - '//a[@href="{{channel}}/core/marker/trait.Send.html"]' 'Send' +//@ has - '//a[@href="{{channel}}/core/marker/trait.Sync.html"]' 'Sync' +#[doc(keyword = "trait")] +// +/// [`Send`] and [Sync] +mod bar {} From 8d4f59bed7af3c8be61f1b96c5bbb25dc4d5b3a8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Dec 2025 23:13:09 +0100 Subject: [PATCH 0526/3801] Clean up code --- compiler/rustc_attr_parsing/src/attributes/doc.rs | 6 ++---- compiler/rustc_attr_parsing/src/context.rs | 1 - compiler/rustc_attr_parsing/src/lib.rs | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 83a6c4fc44d9..4c0a7a19e5b8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -1,6 +1,3 @@ -// FIXME: to be removed -#![allow(unused_imports)] - use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit}; use rustc_feature::template; use rustc_hir::attrs::{ @@ -13,7 +10,6 @@ use thin_vec::ThinVec; use super::prelude::{Allow, AllowedTargets, Error, MethodKind, Target}; use super::{AcceptMapping, AttributeParser}; use crate::context::{AcceptContext, FinalizeContext, Stage}; -use crate::fluent_generated as fluent; use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, PathParser}; use crate::session_diagnostics::{ DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttributeNotAttribute, @@ -355,6 +351,8 @@ impl DocParser { // FIXME: It's errorring when the attribute is passed multiple times on the command // line. + // The right fix for this would be to only check this rule if the attribute is + // not set on the command line but directly in the code. // if self.attribute.$ident.is_some() { // cx.duplicate_key(path.span(), path.word_sym().unwrap()); // return; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 5d15588033fd..f41ea3708788 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -165,7 +165,6 @@ attribute_parsers!( ConstStabilityParser, DocParser, MacroUseParser, - NakedParser, StabilityParser, UsedParser, diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 3e9d8087a192..cb02bb9d501f 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -78,10 +78,10 @@ // tidy-alphabetical-start #![feature(decl_macro)] -#![recursion_limit = "256"] -// tidy-alphabetical-end #![feature(if_let_guard)] #![feature(iter_intersperse)] +#![recursion_limit = "256"] +// tidy-alphabetical-end #[macro_use] /// All the individual attribute parsers for each of rustc's built-in attributes. From 2340f8054c7a97c44bcee69eb314c56667e337a0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 6 Dec 2025 21:29:35 +0100 Subject: [PATCH 0527/3801] Update to new lint API --- compiler/rustc_attr_parsing/messages.ftl | 65 -------------- .../rustc_attr_parsing/src/attributes/doc.rs | 73 ++++++++++++--- .../src/session_diagnostics.rs | 88 ------------------- compiler/rustc_hir/src/lints.rs | 70 +-------------- compiler/rustc_lint/messages.ftl | 52 +++++++++++ compiler/rustc_lint/src/early/diagnostics.rs | 50 +++++++++++ compiler/rustc_lint/src/lints.rs | 88 +++++++++++++++++++ compiler/rustc_lint_defs/src/lib.rs | 35 ++++++++ src/librustdoc/lib.rs | 14 ++- 9 files changed, 301 insertions(+), 234 deletions(-) diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 2a98b87e7a7e..f2642838b3c8 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -17,9 +17,6 @@ attr_parsing_deprecated_item_suggestion = attr_parsing_doc_alias_bad_char = {$char_} character isn't allowed in {$attr_str} -attr_parsing_doc_alias_duplicated = doc alias is duplicated - .label = first defined here - attr_parsing_doc_alias_empty = {$attr_str} attribute cannot have empty value @@ -33,69 +30,10 @@ attr_parsing_doc_attribute_not_attribute = nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]` .help = only existing builtin attributes are allowed in core/std -attr_parsing_doc_auto_cfg_expects_hide_or_show = - only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` - -attr_parsing_doc_auto_cfg_hide_show_expects_list = - `#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items - -attr_parsing_doc_auto_cfg_hide_show_unexpected_item = - `#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items - -attr_parsing_doc_auto_cfg_wrong_literal = - expected boolean for `#[doc(auto_cfg = ...)]` - -attr_parsing_doc_invalid = - invalid `doc` attribute - attr_parsing_doc_keyword_not_keyword = nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]` .help = only existing keywords are allowed in core/std -attr_parsing_doc_test_literal = `#![doc(test(...)]` does not take a literal - -attr_parsing_doc_test_takes_list = - `#[doc(test(...)]` takes a list of attributes - -attr_parsing_doc_test_unknown = - unknown `doc(test)` attribute `{$name}` - -attr_parsing_doc_unknown_any = - unknown `doc` attribute `{$name}` - -attr_parsing_doc_unknown_include = - unknown `doc` attribute `include` - .suggestion = use `doc = include_str!` instead - -attr_parsing_doc_unknown_passes = - unknown `doc` attribute `{$name}` - .note = `doc` attribute `{$name}` no longer functions; see issue #44136 - .label = no longer functions - .no_op_note = `doc({$name})` is now a no-op - -attr_parsing_doc_unknown_plugins = - unknown `doc` attribute `plugins` - .note = `doc` attribute `plugins` no longer functions; see issue #44136 and CVE-2018-1000622 - .label = no longer functions - .no_op_note = `doc(plugins)` is now a no-op - -attr_parsing_doc_unknown_spotlight = - unknown `doc` attribute `spotlight` - .note = `doc(spotlight)` was renamed to `doc(notable_trait)` - .suggestion = use `notable_trait` instead - .no_op_note = `doc(spotlight)` is now a no-op - -attr_parsing_empty_attribute = - unused attribute - .suggestion = {$valid_without_list -> - [true] remove these parentheses - *[other] remove this attribute - } - .note = {$valid_without_list -> - [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all - *[other] using `{$attr_path}` with an empty list has no effect - } - attr_parsing_empty_confusables = expected at least one confusable name @@ -317,8 +255,5 @@ attr_parsing_unused_multiple = .suggestion = remove this attribute .note = attribute also specified here -attr_parsing_doc_alias_duplicated = doc alias is duplicated - .label = first defined here - attr_parsing_whole_archive_needs_static = linking modifier `whole-archive` is only compatible with `static` linking kind diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 4c0a7a19e5b8..5714d33e861f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -116,10 +116,18 @@ impl DocParser { } } Some(name) => { - cx.emit_lint(AttributeLintKind::DocTestUnknown { name }, path.span()); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::DocTestUnknown { name }, + path.span(), + ); } None => { - cx.emit_lint(AttributeLintKind::DocTestLiteral, path.span()); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::DocTestLiteral, + path.span(), + ); } } } @@ -151,7 +159,11 @@ impl DocParser { } if let Some(first_definition) = self.attribute.aliases.get(&alias).copied() { - cx.emit_lint(AttributeLintKind::DuplicateDocAlias { first_definition }, span); + cx.emit_lint( + rustc_session::lint::builtin::UNUSED_ATTRIBUTES, + AttributeLintKind::DuplicateDocAlias { first_definition }, + span, + ); } self.attribute.aliases.insert(alias, span); @@ -239,7 +251,11 @@ impl DocParser { ArgParser::List(list) => { for meta in list.mixed() { let MetaItemOrLitParser::MetaItemParser(item) = meta else { - cx.emit_lint(AttributeLintKind::DocAutoCfgExpectsHideOrShow, meta.span()); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::DocAutoCfgExpectsHideOrShow, + meta.span(), + ); continue; }; let (kind, attr_name) = match item.path().word_sym() { @@ -247,6 +263,7 @@ impl DocParser { Some(sym::show) => (HideOrShow::Show, sym::show), _ => { cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, AttributeLintKind::DocAutoCfgExpectsHideOrShow, item.span(), ); @@ -255,6 +272,7 @@ impl DocParser { }; let ArgParser::List(list) = item.args() else { cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, AttributeLintKind::DocAutoCfgHideShowExpectsList { attr_name }, item.span(), ); @@ -266,6 +284,7 @@ impl DocParser { for item in list.mixed() { let MetaItemOrLitParser::MetaItemParser(sub_item) = item else { cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name }, item.span(), ); @@ -291,6 +310,7 @@ impl DocParser { } _ => { cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name, }, @@ -306,7 +326,11 @@ impl DocParser { ArgParser::NameValue(nv) => { let MetaItemLit { kind: LitKind::Bool(bool_value), span, .. } = nv.value_as_lit() else { - cx.emit_lint(AttributeLintKind::DocAutoCfgWrongLiteral, nv.value_span); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::DocAutoCfgWrongLiteral, + nv.value_span, + ); return; }; self.attribute.auto_cfg_change.push((*bool_value, *span)); @@ -397,6 +421,7 @@ impl DocParser { Some(sym::test) => { let Some(list) = args.list() else { cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, AttributeLintKind::DocTestTakesList, args.span().unwrap_or(path.span()), ); @@ -418,7 +443,11 @@ impl DocParser { } } Some(sym::spotlight) => { - cx.emit_lint(AttributeLintKind::DocUnknownSpotlight, path.span()); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::DocUnknownSpotlight { span: path.span() }, + path.span(), + ); } Some(sym::include) if let Some(nv) = args.name_value() => { let inner = match cx.attr_style { @@ -426,23 +455,41 @@ impl DocParser { AttrStyle::Inner => "!", }; cx.emit_lint( - AttributeLintKind::DocUnknownInclude { inner, value: nv.value_as_lit().symbol }, + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::DocUnknownInclude { + inner, + value: nv.value_as_lit().symbol, + span: path.span(), + }, path.span(), ); } Some(name @ (sym::passes | sym::no_default_passes)) => { - cx.emit_lint(AttributeLintKind::DocUnknownPasses { name }, path.span()); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::DocUnknownPasses { name, span: path.span() }, + path.span(), + ); } Some(sym::plugins) => { - cx.emit_lint(AttributeLintKind::DocUnknownPlugins, path.span()); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::DocUnknownPlugins { span: path.span() }, + path.span(), + ); } Some(name) => { - cx.emit_lint(AttributeLintKind::DocUnknownAny { name }, path.span()); + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::DocUnknownAny { name }, + path.span(), + ); } None => { let full_name = path.segments().map(|s| s.as_str()).intersperse("::").collect::(); cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, AttributeLintKind::DocUnknownAny { name: Symbol::intern(&full_name) }, path.span(), ); @@ -459,7 +506,11 @@ impl DocParser { ArgParser::NoArgs => { let suggestions = cx.suggestions(); let span = cx.attr_span; - cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); + cx.emit_lint( + rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT, + AttributeLintKind::IllFormedAttributeInput { suggestions, docs: None }, + span, + ); } ArgParser::List(items) => { for i in items.mixed() { diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 38ae597000d2..092bf67249f2 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -581,13 +581,6 @@ pub(crate) struct NakedFunctionIncompatibleAttribute { pub attr: String, } -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_alias_duplicated)] -pub(crate) struct DocAliasDuplicated { - #[label] - pub first_defn: Span, -} - #[derive(Diagnostic)] #[diag(attr_parsing_link_ordinal_out_of_range)] #[note] @@ -995,87 +988,6 @@ pub(crate) struct CfgAttrBadDelim { pub sugg: MetaBadDelimSugg, } -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_auto_cfg_expects_hide_or_show)] -pub(crate) struct DocAutoCfgExpectsHideOrShow; - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_auto_cfg_hide_show_unexpected_item)] -pub(crate) struct DocAutoCfgHideShowUnexpectedItem { - pub attr_name: Symbol, -} - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_auto_cfg_hide_show_expects_list)] -pub(crate) struct DocAutoCfgHideShowExpectsList { - pub attr_name: Symbol, -} - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_invalid)] -pub(crate) struct DocInvalid; - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_unknown_include)] -pub(crate) struct DocUnknownInclude { - pub inner: &'static str, - pub value: Symbol, - #[suggestion(code = "#{inner}[doc = include_str!(\"{value}\")]")] - pub sugg: (Span, Applicability), -} - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_unknown_spotlight)] -#[note] -#[note(attr_parsing_no_op_note)] -pub(crate) struct DocUnknownSpotlight { - #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")] - pub sugg_span: Span, -} - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_unknown_passes)] -#[note] -#[note(attr_parsing_no_op_note)] -pub(crate) struct DocUnknownPasses { - pub name: Symbol, - #[label] - pub note_span: Span, -} - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_unknown_plugins)] -#[note] -#[note(attr_parsing_no_op_note)] -pub(crate) struct DocUnknownPlugins { - #[label] - pub label_span: Span, -} - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_unknown_any)] -pub(crate) struct DocUnknownAny { - pub name: Symbol, -} - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_auto_cfg_wrong_literal)] -pub(crate) struct DocAutoCfgWrongLiteral; - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_test_takes_list)] -pub(crate) struct DocTestTakesList; - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_test_unknown)] -pub(crate) struct DocTestUnknown { - pub name: Symbol, -} - -#[derive(LintDiagnostic)] -#[diag(attr_parsing_doc_test_literal)] -pub(crate) struct DocTestLiteral; - #[derive(Diagnostic)] #[diag(attr_parsing_doc_alias_malformed)] pub(crate) struct DocAliasMalformed { diff --git a/compiler/rustc_hir/src/lints.rs b/compiler/rustc_hir/src/lints.rs index 2d13ceabf8ca..eba2d182d2c4 100644 --- a/compiler/rustc_hir/src/lints.rs +++ b/compiler/rustc_hir/src/lints.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fingerprint::Fingerprint; pub use rustc_lint_defs::AttributeLintKind; use rustc_lint_defs::LintId; use rustc_macros::HashStable_Generic; -use rustc_span::{Span, Symbol}; +use rustc_span::Span; use crate::HirId; @@ -31,71 +31,3 @@ pub struct AttributeLint { pub span: Span, pub kind: AttributeLintKind, } - -#[derive(Debug, HashStable_Generic)] -pub enum AttributeLintKind { - /// Copy of `IllFormedAttributeInput` - /// specifically for the `invalid_macro_export_arguments` lint until that is removed, - /// see - InvalidMacroExportArguments { - suggestions: Vec, - }, - UnusedDuplicate { - this: Span, - other: Span, - warning: bool, - }, - IllFormedAttributeInput { - suggestions: Vec, - }, - EmptyAttribute { - first_span: Span, - attr_path: AttrPath, - valid_without_list: bool, - }, - InvalidTarget { - name: AttrPath, - target: Target, - applied: Vec, - only: &'static str, - }, - InvalidStyle { - name: AttrPath, - is_used_as_inner: bool, - target: Target, - target_span: Span, - }, - UnsafeAttrOutsideUnsafe { - attribute_name_span: Span, - sugg_spans: (Span, Span), - }, - DuplicateDocAlias { - first_definition: Span, - }, - DocAutoCfgExpectsHideOrShow, - DocAutoCfgHideShowUnexpectedItem { - attr_name: Symbol, - }, - DocAutoCfgHideShowExpectsList { - attr_name: Symbol, - }, - DocInvalid, - DocUnknownInclude { - inner: &'static str, - value: Symbol, - }, - DocUnknownSpotlight, - DocUnknownPasses { - name: Symbol, - }, - DocUnknownPlugins, - DocUnknownAny { - name: Symbol, - }, - DocAutoCfgWrongLiteral, - DocTestTakesList, - DocTestUnknown { - name: Symbol, - }, - DocTestLiteral, -} diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 0553bc95caa2..94f638b676e8 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -233,6 +233,58 @@ lint_deprecated_where_clause_location = where clause not allowed here lint_diag_out_of_impl = diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls +lint_doc_alias_duplicated = doc alias is duplicated + .label = first defined here + +lint_doc_auto_cfg_expects_hide_or_show = + only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` + +lint_doc_auto_cfg_hide_show_expects_list = + `#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items + +lint_doc_auto_cfg_hide_show_unexpected_item = + `#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items + +lint_doc_auto_cfg_wrong_literal = + expected boolean for `#[doc(auto_cfg = ...)]` + +lint_doc_invalid = + invalid `doc` attribute + +lint_doc_test_literal = `#![doc(test(...)]` does not take a literal + +lint_doc_test_takes_list = + `#[doc(test(...)]` takes a list of attributes + +lint_doc_test_unknown = + unknown `doc(test)` attribute `{$name}` + +lint_doc_unknown_any = + unknown `doc` attribute `{$name}` + +lint_doc_unknown_include = + unknown `doc` attribute `include` + .suggestion = use `doc = include_str!` instead + +lint_doc_unknown_passes = + unknown `doc` attribute `{$name}` + .note = `doc` attribute `{$name}` no longer functions; see issue #44136 + .label = no longer functions + .no_op_note = `doc({$name})` is now a no-op + +lint_doc_unknown_plugins = + unknown `doc` attribute `plugins` + .note = `doc` attribute `plugins` no longer functions; see issue #44136 and CVE-2018-1000622 + .label = no longer functions + .no_op_note = `doc(plugins)` is now a no-op + +lint_doc_unknown_spotlight = + unknown `doc` attribute `spotlight` + .note = `doc(spotlight)` was renamed to `doc(notable_trait)` + .suggestion = use `notable_trait` instead + .no_op_note = `doc(spotlight)` is now a no-op + + lint_drop_glue = types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 589594a3ec5e..4eb50bda53a1 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -367,5 +367,55 @@ pub fn decorate_attribute_lint( &AttributeLintKind::UnexpectedCfgValue(name, value) => { check_cfg::unexpected_cfg_value(sess, tcx, name, value).decorate_lint(diag) } + &AttributeLintKind::DuplicateDocAlias { first_definition } => { + lints::DocAliasDuplicated { first_defn: first_definition }.decorate_lint(diag) + } + + &AttributeLintKind::DocAutoCfgExpectsHideOrShow => { + lints::DocAutoCfgExpectsHideOrShow.decorate_lint(diag) + } + + &AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name } => { + lints::DocAutoCfgHideShowUnexpectedItem { attr_name }.decorate_lint(diag) + } + + &AttributeLintKind::DocAutoCfgHideShowExpectsList { attr_name } => { + lints::DocAutoCfgHideShowExpectsList { attr_name }.decorate_lint(diag) + } + + &AttributeLintKind::DocInvalid => { lints::DocInvalid }.decorate_lint(diag), + + &AttributeLintKind::DocUnknownInclude { span, inner, value } => { + lints::DocUnknownInclude { inner, value, sugg: (span, Applicability::MaybeIncorrect) } + } + .decorate_lint(diag), + + &AttributeLintKind::DocUnknownSpotlight { span } => { + lints::DocUnknownSpotlight { sugg_span: span }.decorate_lint(diag) + } + + &AttributeLintKind::DocUnknownPasses { name, span } => { + lints::DocUnknownPasses { name, note_span: span }.decorate_lint(diag) + } + + &AttributeLintKind::DocUnknownPlugins { span } => { + lints::DocUnknownPlugins { label_span: span }.decorate_lint(diag) + } + + &AttributeLintKind::DocUnknownAny { name } => { + lints::DocUnknownAny { name }.decorate_lint(diag) + } + + &AttributeLintKind::DocAutoCfgWrongLiteral => { + lints::DocAutoCfgWrongLiteral.decorate_lint(diag) + } + + &AttributeLintKind::DocTestTakesList => lints::DocTestTakesList.decorate_lint(diag), + + &AttributeLintKind::DocTestUnknown { name } => { + lints::DocTestUnknown { name }.decorate_lint(diag) + } + + &AttributeLintKind::DocTestLiteral => lints::DocTestLiteral.decorate_lint(diag), } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 1bec316ce45a..4aeeddcac71d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3199,3 +3199,91 @@ pub(crate) struct UnusedVisibility { #[suggestion(style = "short", code = "", applicability = "machine-applicable")] pub span: Span, } + +#[derive(LintDiagnostic)] +#[diag(lint_doc_alias_duplicated)] +pub(crate) struct DocAliasDuplicated { + #[label] + pub first_defn: Span, +} + +#[derive(LintDiagnostic)] +#[diag(lint_doc_auto_cfg_expects_hide_or_show)] +pub(crate) struct DocAutoCfgExpectsHideOrShow; + +#[derive(LintDiagnostic)] +#[diag(lint_doc_auto_cfg_hide_show_unexpected_item)] +pub(crate) struct DocAutoCfgHideShowUnexpectedItem { + pub attr_name: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(lint_doc_auto_cfg_hide_show_expects_list)] +pub(crate) struct DocAutoCfgHideShowExpectsList { + pub attr_name: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(lint_doc_invalid)] +pub(crate) struct DocInvalid; + +#[derive(LintDiagnostic)] +#[diag(lint_doc_unknown_include)] +pub(crate) struct DocUnknownInclude { + pub inner: &'static str, + pub value: Symbol, + #[suggestion(code = "#{inner}[doc = include_str!(\"{value}\")]")] + pub sugg: (Span, Applicability), +} + +#[derive(LintDiagnostic)] +#[diag(lint_doc_unknown_spotlight)] +#[note] +#[note(lint_no_op_note)] +pub(crate) struct DocUnknownSpotlight { + #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")] + pub sugg_span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(lint_doc_unknown_passes)] +#[note] +#[note(lint_no_op_note)] +pub(crate) struct DocUnknownPasses { + pub name: Symbol, + #[label] + pub note_span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(lint_doc_unknown_plugins)] +#[note] +#[note(lint_no_op_note)] +pub(crate) struct DocUnknownPlugins { + #[label] + pub label_span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(lint_doc_unknown_any)] +pub(crate) struct DocUnknownAny { + pub name: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(lint_doc_auto_cfg_wrong_literal)] +pub(crate) struct DocAutoCfgWrongLiteral; + +#[derive(LintDiagnostic)] +#[diag(lint_doc_test_takes_list)] +pub(crate) struct DocTestTakesList; + +#[derive(LintDiagnostic)] +#[diag(lint_doc_test_unknown)] +pub(crate) struct DocTestUnknown { + pub name: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(lint_doc_test_literal)] +pub(crate) struct DocTestLiteral; diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 376310838cc7..28657c7474b4 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -733,6 +733,41 @@ pub enum AttributeLintKind { }, UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>), UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>), + DuplicateDocAlias { + first_definition: Span, + }, + DocAutoCfgExpectsHideOrShow, + DocAutoCfgHideShowUnexpectedItem { + attr_name: Symbol, + }, + DocAutoCfgHideShowExpectsList { + attr_name: Symbol, + }, + DocInvalid, + DocUnknownInclude { + span: Span, + inner: &'static str, + value: Symbol, + }, + DocUnknownSpotlight { + span: Span, + }, + DocUnknownPasses { + name: Symbol, + span: Span, + }, + DocUnknownPlugins { + span: Span, + }, + DocUnknownAny { + name: Symbol, + }, + DocAutoCfgWrongLiteral, + DocTestTakesList, + DocTestUnknown { + name: Symbol, + }, + DocTestLiteral, } pub type RegisteredTools = FxIndexSet; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 13be1a04dbc5..5e582eb61997 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -907,7 +907,19 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { for lint in &delayed_lints.lints { match lint { DelayedLint::AttributeParsing(attribute_lint) => { - rustc_attr_parsing::emit_attribute_lint(attribute_lint, tcx) + tcx.node_span_lint( + attribute_lint.lint_id.lint, + attribute_lint.id, + attribute_lint.span, + |diag| { + rustc_lint::decorate_attribute_lint( + tcx.sess, + Some(tcx), + &attribute_lint.kind, + diag, + ); + }, + ); } } } From 06238bd93e6a871f46b09519cd14676c2642a253 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 6 Dec 2025 22:33:24 +0100 Subject: [PATCH 0528/3801] Update rustdoc JSON output to new attribute API --- .../rustc_hir/src/attrs/data_structures.rs | 38 ++++++ src/librustdoc/json/conversions.rs | 129 ++++++++++++++++-- 2 files changed, 155 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 0419e219afe4..696d85631e16 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::fmt; use std::path::PathBuf; pub use ReprAttr::*; @@ -231,6 +232,43 @@ impl CfgEntry { } } +impl fmt::Display for CfgEntry { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fn write_entries( + name: &str, + entries: &[CfgEntry], + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + write!(f, "{name}(")?; + for (nb, entry) in entries.iter().enumerate() { + if nb != 0 { + f.write_str(", ")?; + } + entry.fmt(f)?; + } + f.write_str(")") + } + match self { + Self::All(entries, _) => write_entries("all", entries, f), + Self::Any(entries, _) => write_entries("any", entries, f), + Self::Not(entry, _) => write!(f, "not({entry})"), + Self::Bool(value, _) => write!(f, "{value}"), + Self::NameValue { name, value, .. } => { + match value { + // We use `as_str` and debug display to have characters escaped and `"` + // characters surrounding the string. + Some((value, _)) => write!(f, "{name} = {:?}", value.as_str()), + None => write!(f, "{name}"), + } + } + Self::Version(version, _) => match version { + Some(version) => write!(f, "{version}"), + None => Ok(()), + }, + } + } +} + /// Possible values for the `#[linkage]` attribute, allowing to specify the /// linkage type for a `MonoItem`. /// diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index edafc9e7a089..892cc483dbd6 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -7,14 +7,14 @@ use rustc_ast::ast; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::thin_vec::ThinVec; use rustc_hir as hir; -use rustc_hir::attrs::{self, DeprecatedSince}; +use rustc_hir::attrs::{self, DeprecatedSince, DocAttribute, DocInline, HideOrShow}; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; use rustc_hir::{HeaderSafety, Safety}; use rustc_metadata::rendered_const; use rustc_middle::ty::TyCtxt; use rustc_middle::{bug, ty}; -use rustc_span::{Pos, kw, sym}; +use rustc_span::{Pos, Symbol, kw, sym}; use rustdoc_json_types::*; use crate::clean::{self, ItemId}; @@ -46,7 +46,7 @@ impl JsonRenderer<'_> { .attrs .other_attrs .iter() - .filter_map(|a| maybe_from_hir_attr(a, item.item_id, self.tcx)) + .flat_map(|a| maybe_from_hir_attr(a, item.item_id, self.tcx)) .collect(); let span = item.span(self.tcx); let visibility = item.visibility(self.tcx); @@ -902,11 +902,7 @@ impl FromClean for ItemKind { /// Maybe convert a attribute from hir to json. /// /// Returns `None` if the attribute shouldn't be in the output. -fn maybe_from_hir_attr( - attr: &hir::Attribute, - item_id: ItemId, - tcx: TyCtxt<'_>, -) -> Option { +fn maybe_from_hir_attr(attr: &hir::Attribute, item_id: ItemId, tcx: TyCtxt<'_>) -> Vec { use attrs::AttributeKind as AK; let kind = match attr { @@ -914,12 +910,12 @@ fn maybe_from_hir_attr( hir::Attribute::Unparsed(_) => { // FIXME: We should handle `#[doc(hidden)]`. - return Some(other_attr(tcx, attr)); + return vec![other_attr(tcx, attr)]; } }; - Some(match kind { - AK::Deprecation { .. } => return None, // Handled separately into Item::deprecation. + vec![match kind { + AK::Deprecation { .. } => return Vec::new(), // Handled separately into Item::deprecation. AK::DocComment { .. } => unreachable!("doc comments stripped out earlier"), AK::MacroExport { .. } => Attribute::MacroExport, @@ -939,9 +935,118 @@ fn maybe_from_hir_attr( AK::NoMangle(_) => Attribute::NoMangle, AK::NonExhaustive(_) => Attribute::NonExhaustive, AK::AutomaticallyDerived(_) => Attribute::AutomaticallyDerived, + AK::Doc(d) => { + fn toggle_attr(ret: &mut Vec, name: &str, v: &Option) { + if v.is_some() { + ret.push(Attribute::Other(format!("#[doc({name})]"))); + } + } + + fn name_value_attr( + ret: &mut Vec, + name: &str, + v: &Option<(Symbol, rustc_span::Span)>, + ) { + if let Some((v, _)) = v { + // We use `as_str` and debug display to have characters escaped and `"` + // characters surrounding the string. + ret.push(Attribute::Other(format!("#[doc({name} = {:?})]", v.as_str()))); + } + } + + let DocAttribute { + aliases, + hidden, + inline, + cfg, + auto_cfg, + auto_cfg_change, + fake_variadic, + keyword, + attribute, + masked, + notable_trait, + search_unbox, + html_favicon_url, + html_logo_url, + html_playground_url, + html_root_url, + html_no_source, + issue_tracker_base_url, + rust_logo, + test_attrs, + no_crate_inject, + } = &**d; + + let mut ret = Vec::new(); + + for (alias, _) in aliases { + // We use `as_str` and debug display to have characters escaped and `"` characters + // surrounding the string. + ret.push(Attribute::Other(format!("#[doc(alias = {:?})]", alias.as_str()))); + } + toggle_attr(&mut ret, "hidden", hidden); + if let Some(inline) = inline.first() { + ret.push(Attribute::Other(format!( + "#[doc({})]", + match inline.0 { + DocInline::Inline => "inline", + DocInline::NoInline => "no_inline", + } + ))); + } + for sub_cfg in cfg { + ret.push(Attribute::Other(format!("#[doc(cfg({sub_cfg}))]"))); + } + for (auto_cfg, _) in auto_cfg { + let kind = match auto_cfg.kind { + HideOrShow::Hide => "hide", + HideOrShow::Show => "show", + }; + let mut out = format!("#[doc(auto_cfg({kind}("); + for (pos, value) in auto_cfg.values.iter().enumerate() { + if pos > 0 { + out.push_str(", "); + } + out.push_str(value.name.as_str()); + if let Some((value, _)) = value.value { + // We use `as_str` and debug display to have characters escaped and `"` + // characters surrounding the string. + out.push_str(&format!(" = {:?}", value.as_str())); + } + } + out.push_str(")))]"); + ret.push(Attribute::Other(out)); + } + for (change, _) in auto_cfg_change { + ret.push(Attribute::Other(format!("#[doc(auto_cfg = {change})]"))); + } + toggle_attr(&mut ret, "fake_variadic", fake_variadic); + name_value_attr(&mut ret, "keyword", keyword); + name_value_attr(&mut ret, "attribute", attribute); + toggle_attr(&mut ret, "masked", masked); + toggle_attr(&mut ret, "notable_trait", notable_trait); + toggle_attr(&mut ret, "search_unbox", search_unbox); + name_value_attr(&mut ret, "html_favicon_url", html_favicon_url); + name_value_attr(&mut ret, "html_logo_url", html_logo_url); + name_value_attr(&mut ret, "html_playground_url", html_playground_url); + name_value_attr(&mut ret, "html_root_url", html_root_url); + toggle_attr(&mut ret, "html_no_source", html_no_source); + name_value_attr(&mut ret, "issue_tracker_base_url", issue_tracker_base_url); + toggle_attr(&mut ret, "rust_logo", rust_logo); + let source_map = tcx.sess.source_map(); + for attr_span in test_attrs { + // FIXME: This is ugly, remove when `test_attrs` has been ported to new attribute API. + if let Ok(snippet) = source_map.span_to_snippet(*attr_span) { + ret.push(Attribute::Other(format!("#[doc(test(attr({snippet})))"))); + } + } + toggle_attr(&mut ret, "no_crate_inject", no_crate_inject); + return ret; + } _ => other_attr(tcx, attr), - }) + }] } fn other_attr(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Attribute { From 1da7684c7d0f1ec2bd9aa99a9844cff3296502ea Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 7 Dec 2025 12:18:53 +0100 Subject: [PATCH 0529/3801] Improve code and add more comments --- .../rustc_hir/src/attrs/data_structures.rs | 30 +--------------- src/librustdoc/clean/cfg.rs | 34 +++++++++---------- src/librustdoc/clean/types.rs | 18 ++++------ src/librustdoc/doctest/rust.rs | 9 +++++ src/librustdoc/passes/collect_trait_impls.rs | 3 ++ 5 files changed, 36 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 696d85631e16..09ef6dc18814 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -510,7 +510,7 @@ pub struct CfgHideShow { pub values: ThinVec, } -#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +#[derive(Clone, Debug, Default, HashStable_Generic, Encodable, Decodable, PrintAttribute)] pub struct DocAttribute { pub aliases: FxIndexMap, pub hidden: Option, @@ -546,34 +546,6 @@ pub struct DocAttribute { pub no_crate_inject: Option, } -impl Default for DocAttribute { - fn default() -> Self { - Self { - aliases: FxIndexMap::default(), - hidden: None, - inline: ThinVec::new(), - cfg: ThinVec::new(), - auto_cfg: ThinVec::new(), - auto_cfg_change: ThinVec::new(), - fake_variadic: None, - keyword: None, - attribute: None, - masked: None, - notable_trait: None, - search_unbox: None, - html_favicon_url: None, - html_logo_url: None, - html_playground_url: None, - html_root_url: None, - html_no_source: None, - issue_tracker_base_url: None, - rust_logo: None, - test_attrs: ThinVec::new(), - no_crate_inject: None, - } - } -} - /// Represents parsed *built-in* inert attributes. /// /// ## Overview diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 99409cf838cd..6cad4301b313 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -59,11 +59,11 @@ fn is_all_cfg(cfg: &CfgEntry) -> bool { } } -fn strip_hidden(cfg: &CfgEntry, hidden: &FxHashSet) -> Option { +fn strip_hidden(cfg: &CfgEntry, hidden: &FxHashSet) -> Option { match cfg { CfgEntry::Bool(..) => Some(cfg.clone()), CfgEntry::NameValue { .. } => { - if !hidden.contains(&SimpleCfg::from(cfg)) { + if !hidden.contains(&NameValueCfg::from(cfg)) { Some(cfg.clone()) } else { None @@ -109,7 +109,7 @@ impl Cfg { /// Parses a `MetaItemInner` into a `Cfg`. fn parse_nested( nested_cfg: &MetaItemInner, - exclude: &FxHashSet, + exclude: &FxHashSet, ) -> Result, InvalidCfgError> { match nested_cfg { MetaItemInner::MetaItem(cfg) => Cfg::parse_without(cfg, exclude), @@ -124,7 +124,7 @@ impl Cfg { fn parse_without( cfg: &MetaItem, - exclude: &FxHashSet, + exclude: &FxHashSet, ) -> Result, InvalidCfgError> { let name = match cfg.ident() { Some(ident) => ident.name, @@ -137,7 +137,7 @@ impl Cfg { }; match cfg.kind { MetaItemKind::Word => { - if exclude.contains(&SimpleCfg::new(name)) { + if exclude.contains(&NameValueCfg::new(name)) { Ok(None) } else { Ok(Some(Cfg(CfgEntry::NameValue { @@ -150,7 +150,7 @@ impl Cfg { } MetaItemKind::NameValue(ref lit) => match lit.kind { LitKind::Str(value, _) => { - if exclude.contains(&SimpleCfg::new_value(name, value)) { + if exclude.contains(&NameValueCfg::new_value(name, value)) { Ok(None) } else { Ok(Some(Cfg(CfgEntry::NameValue { @@ -666,12 +666,12 @@ impl fmt::Display for Display<'_> { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -struct SimpleCfg { +struct NameValueCfg { name: Symbol, value: Option, } -impl SimpleCfg { +impl NameValueCfg { fn new(name: Symbol) -> Self { Self { name, value: None } } @@ -681,18 +681,18 @@ impl SimpleCfg { } } -impl<'a> From<&'a CfgEntry> for SimpleCfg { +impl<'a> From<&'a CfgEntry> for NameValueCfg { fn from(cfg: &'a CfgEntry) -> Self { match cfg { CfgEntry::NameValue { name, value, .. } => { - SimpleCfg { name: *name, value: (*value).map(|(v, _)| v) } + NameValueCfg { name: *name, value: (*value).map(|(v, _)| v) } } - _ => SimpleCfg { name: sym::empty, value: None }, + _ => NameValueCfg { name: sym::empty, value: None }, } } } -impl<'a> From<&'a attrs::CfgInfo> for SimpleCfg { +impl<'a> From<&'a attrs::CfgInfo> for NameValueCfg { fn from(cfg: &'a attrs::CfgInfo) -> Self { Self { name: cfg.name, value: cfg.value.map(|(value, _)| value) } } @@ -703,7 +703,7 @@ impl<'a> From<&'a attrs::CfgInfo> for SimpleCfg { pub(crate) struct CfgInfo { /// List of currently active `doc(auto_cfg(hide(...)))` cfgs, minus currently active /// `doc(auto_cfg(show(...)))` cfgs. - hidden_cfg: FxHashSet, + hidden_cfg: FxHashSet, /// Current computed `cfg`. Each time we enter a new item, this field is updated as well while /// taking into account the `hidden_cfg` information. current_cfg: Cfg, @@ -719,9 +719,9 @@ impl Default for CfgInfo { fn default() -> Self { Self { hidden_cfg: FxHashSet::from_iter([ - SimpleCfg::new(sym::test), - SimpleCfg::new(sym::doc), - SimpleCfg::new(sym::doctest), + NameValueCfg::new(sym::test), + NameValueCfg::new(sym::doc), + NameValueCfg::new(sym::doctest), ]), current_cfg: Cfg(CfgEntry::Bool(true, DUMMY_SP)), auto_cfg_active: true, @@ -761,7 +761,7 @@ fn handle_auto_cfg_hide_show( new_hide_attrs: &mut FxHashMap<(Symbol, Option), rustc_span::Span>, ) { for value in &attr.values { - let simple = SimpleCfg::from(value); + let simple = NameValueCfg::from(value); if attr.kind == HideOrShow::Show { if let Some(span) = new_hide_attrs.get(&(simple.name, simple.value)) { show_hide_show_conflict_error(tcx, attr_span, *span); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index cefaf1102fb9..7a4650feac1c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -229,34 +229,28 @@ impl ExternalCrate { } pub(crate) fn keywords(&self, tcx: TyCtxt<'_>) -> impl Iterator { - self.retrieve_keywords_or_documented_attributes(tcx, true) + self.retrieve_keywords_or_documented_attributes(tcx, |d| d.keyword.map(|(v, _)| v)) } pub(crate) fn documented_attributes( &self, tcx: TyCtxt<'_>, ) -> impl Iterator { - self.retrieve_keywords_or_documented_attributes(tcx, false) + self.retrieve_keywords_or_documented_attributes(tcx, |d| d.attribute.map(|(v, _)| v)) } - fn retrieve_keywords_or_documented_attributes( + fn retrieve_keywords_or_documented_attributes Option>( &self, tcx: TyCtxt<'_>, - look_for_keyword: bool, + callback: F, ) -> impl Iterator { let as_target = move |did: DefId, tcx: TyCtxt<'_>| -> Option<(DefId, Symbol)> { tcx.get_all_attrs(did) .iter() .find_map(|attr| match attr { - Attribute::Parsed(AttributeKind::Doc(d)) => { - if look_for_keyword { - d.keyword - } else { - d.attribute - } - } + Attribute::Parsed(AttributeKind::Doc(d)) => callback(d), _ => None, }) - .map(|(value, _)| (did, value)) + .map(|value| (did, value)) }; self.mapped_root_modules(tcx, as_target) } diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 6f294ad96267..987e1c2ddbf9 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -143,6 +143,13 @@ impl HirCollector<'_> { if let TokenTree::Ident(i) = token { let i = i.to_string(); let peek = iter.peek(); + // From this ident, we can have things like: + // + // * Group: `allow(...)` + // * Name/value: `crate_name = "..."` + // * Tokens: `html_no_url` + // + // So we peek next element to know what case we are in. match peek { Some(TokenTree::Group(g)) => { let g = g.to_string(); @@ -150,6 +157,8 @@ impl HirCollector<'_> { // Add the additional attributes to the global_crate_attrs vector self.collector.global_crate_attrs.push(format!("{i}{g}")); } + // If next item is `=`, it means it's a name value so we will need + // to get the value as well. Some(TokenTree::Punct(p)) if p.as_char() == '=' => { let p = p.to_string(); iter.next(); diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 357d00ef6521..c2a69baf2989 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -68,6 +68,9 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> while let Some(did) = parent { attr_buf.extend(tcx.get_all_attrs(did).iter().filter_map(|attr| match attr { Attribute::Parsed(AttributeKind::Doc(d)) if !d.cfg.is_empty() => { + // The only doc attributes we're interested into for trait impls are the + // `cfg`s for the `doc_cfg` feature. So we create a new empty `DocAttribute` + // and then only clone the actual `DocAttribute::cfg` field. let mut new_attr = DocAttribute::default(); new_attr.cfg = d.cfg.clone(); Some(Attribute::Parsed(AttributeKind::Doc(Box::new(new_attr)))) From 4191e94715647b2490f0bb8040f589239ab65813 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 8 Dec 2025 18:06:36 +0100 Subject: [PATCH 0530/3801] Improve spans for `auto_cfg(hide/show)` errors --- compiler/rustc_hir/src/attrs/data_structures.rs | 10 ++++++++++ src/librustdoc/clean/cfg.rs | 14 ++++++-------- tests/rustdoc-ui/cfg-hide-show-conflict.stderr | 8 ++++---- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 09ef6dc18814..e4a55bf39333 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -504,6 +504,16 @@ pub struct CfgInfo { pub value: Option<(Symbol, Span)>, } +impl CfgInfo { + pub fn span_for_name_and_value(&self) -> Span { + if let Some((_, value_span)) = self.value { + self.name_span.with_hi(value_span.hi()) + } else { + self.name_span + } + } +} + #[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] pub struct CfgHideShow { pub kind: HideOrShow, diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 6cad4301b313..1413f7f56c96 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -47,7 +47,7 @@ fn is_simple_cfg(cfg: &CfgEntry) -> bool { } } -/// Whether the configuration consists of just `Cfg`, `Not` or `All`. +/// Returns `false` if is `Any`, otherwise returns `true`. fn is_all_cfg(cfg: &CfgEntry) -> bool { match cfg { CfgEntry::Bool(..) @@ -756,7 +756,6 @@ fn handle_auto_cfg_hide_show( tcx: TyCtxt<'_>, cfg_info: &mut CfgInfo, attr: &CfgHideShow, - attr_span: Span, new_show_attrs: &mut FxHashMap<(Symbol, Option), rustc_span::Span>, new_hide_attrs: &mut FxHashMap<(Symbol, Option), rustc_span::Span>, ) { @@ -764,16 +763,16 @@ fn handle_auto_cfg_hide_show( let simple = NameValueCfg::from(value); if attr.kind == HideOrShow::Show { if let Some(span) = new_hide_attrs.get(&(simple.name, simple.value)) { - show_hide_show_conflict_error(tcx, attr_span, *span); + show_hide_show_conflict_error(tcx, value.span_for_name_and_value(), *span); } else { - new_show_attrs.insert((simple.name, simple.value), attr_span); + new_show_attrs.insert((simple.name, simple.value), value.span_for_name_and_value()); } cfg_info.hidden_cfg.remove(&simple); } else { if let Some(span) = new_show_attrs.get(&(simple.name, simple.value)) { - show_hide_show_conflict_error(tcx, attr_span, *span); + show_hide_show_conflict_error(tcx, value.span_for_name_and_value(), *span); } else { - new_hide_attrs.insert((simple.name, simple.value), attr_span); + new_hide_attrs.insert((simple.name, simple.value), value.span_for_name_and_value()); } cfg_info.hidden_cfg.insert(simple); } @@ -871,12 +870,11 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator ) { return None; } - for (value, span) in &d.auto_cfg { + for (value, _) in &d.auto_cfg { handle_auto_cfg_hide_show( tcx, cfg_info, value, - *span, &mut new_show_attrs, &mut new_hide_attrs, ); diff --git a/tests/rustdoc-ui/cfg-hide-show-conflict.stderr b/tests/rustdoc-ui/cfg-hide-show-conflict.stderr index 384a9f1a0b1f..22231e82cd7b 100644 --- a/tests/rustdoc-ui/cfg-hide-show-conflict.stderr +++ b/tests/rustdoc-ui/cfg-hide-show-conflict.stderr @@ -1,14 +1,14 @@ error: same `cfg` was in `auto_cfg(hide(...))` and `auto_cfg(show(...))` on the same item - --> $DIR/cfg-hide-show-conflict.rs:3:8 + --> $DIR/cfg-hide-show-conflict.rs:3:31 | LL | #![doc(auto_cfg(show(windows, target_os = "linux")))] - | ^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ | note: first change was here - --> $DIR/cfg-hide-show-conflict.rs:2:8 + --> $DIR/cfg-hide-show-conflict.rs:2:22 | LL | #![doc(auto_cfg(hide(target_os = "linux")))] - | ^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error From 6230b56eaa04df03ee46100823ec4aedd78e522a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 8 Dec 2025 22:44:41 +0100 Subject: [PATCH 0531/3801] Update clippy code --- .../clippy_lints/src/doc/doc_suspicious_footnotes.rs | 9 ++++++++- .../clippy_lints/src/doc/suspicious_doc_comments.rs | 8 ++++---- src/tools/clippy/clippy_utils/src/attrs.rs | 7 +------ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs b/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs index 1944cd7c91d3..deca29a1885f 100644 --- a/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs +++ b/src/tools/clippy/clippy_lints/src/doc/doc_suspicious_footnotes.rs @@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_ast::attr::AttributeExt as _; use rustc_ast::token::{CommentKind, DocFragmentKind}; use rustc_errors::Applicability; +use rustc_hir::attrs::AttributeKind; use rustc_hir::{AttrStyle, Attribute}; use rustc_lint::{LateContext, LintContext}; @@ -45,7 +46,13 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range, fragments: &F if let DocFragmentKind::Sugared(_) = this_fragment.kind { let (doc_attr, doc_attr_comment_kind, attr_style) = attrs .iter() - .filter(|attr| attr.span().overlaps(this_fragment.span)) + .filter(|attr| { + matches!( + attr, + Attribute::Parsed(AttributeKind::DocComment { span, .. }) + if span.overlaps(this_fragment.span), + ) + }) .rev() .find_map(|attr| { let (_, fragment) = attr.doc_str_and_fragment_kind()?; diff --git a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs index e751600f00a6..178d688264b7 100644 --- a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs +++ b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs @@ -39,15 +39,15 @@ fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { .filter_map(|attr| { if let Attribute::Parsed(AttributeKind::DocComment { style: AttrStyle::Outer, - kind, + kind: DocFragmentKind::Sugared(comment_kind), comment, .. }) = attr && let Some(com) = comment.as_str().strip_prefix('!') { - let sugg = match kind { - DocFragmentKind::Sugared(CommentKind::Block) => format!("/*!{com}*/"), - DocFragmentKind::Sugared(CommentKind::Line) | DocFragmentKind::Raw(_) => format!("//!{com}"), + let sugg = match comment_kind { + CommentKind::Block => format!("/*!{com}*/"), + CommentKind::Line => format!("//!{com}"), }; Some((attr.span(), sugg)) } else { diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index 671b266ba008..2fd773b06781 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -2,7 +2,6 @@ use crate::source::SpanRangeExt; use crate::{sym, tokenize_with_text}; -use rustc_ast::attr; use rustc_ast::attr::AttributeExt; use rustc_errors::Applicability; use rustc_hir::attrs::AttributeKind; @@ -87,11 +86,7 @@ pub fn is_proc_macro(attrs: &[impl AttributeExt]) -> bool { /// Checks whether `attrs` contain `#[doc(hidden)]` pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool { - attrs - .iter() - .filter(|attr| attr.has_name(sym::doc)) - .filter_map(AttributeExt::meta_item_list) - .any(|l| attr::list_contains_name(&l, sym::hidden)) + attrs.iter().any(|attr| attr.is_doc_hidden()) } /// Checks whether the given ADT, or any of its fields/variants, are marked as `#[non_exhaustive]` From 40907f522d6e57abb83f80db7c62719bed7d8d46 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 8 Dec 2025 23:17:16 +0100 Subject: [PATCH 0532/3801] Fix doc alias suggestion --- compiler/rustc_attr_parsing/src/attributes/doc.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 5714d33e861f..a26f22c4455d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -137,10 +137,8 @@ impl DocParser { cx: &'c mut AcceptContext<'_, '_, S>, alias: Symbol, span: Span, - is_list: bool, ) { - let attr_str = - &format!("`#[doc(alias{})]`", if is_list { "(\"...\")" } else { " = \"...\"" }); + let attr_str = "`#[doc(alias = \"...\")]`"; if alias == sym::empty { cx.emit_err(DocAliasEmpty { span, attr_str }); return; @@ -186,7 +184,7 @@ impl DocParser { continue; }; - self.add_alias(cx, alias, i.span(), false); + self.add_alias(cx, alias, i.span()); } } ArgParser::NameValue(nv) => { @@ -194,7 +192,7 @@ impl DocParser { cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); return; }; - self.add_alias(cx, alias, nv.value_span, false); + self.add_alias(cx, alias, nv.value_span); } } } From 64aaeacd7168ae1995fed60974142db14e246840 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 9 Dec 2025 22:27:28 +0100 Subject: [PATCH 0533/3801] Update to new API, allowing to remove `check_doc_cfg.rs` file from librustdoc --- .../src/attributes/cfg_old.rs | 1 - .../rustc_attr_parsing/src/attributes/doc.rs | 11 ++- .../rustc_hir/src/attrs/data_structures.rs | 11 +-- library/std/build.rs | 3 + src/librustdoc/clean/cfg.rs | 43 ++++------- src/librustdoc/clean/cfg/tests.rs | 11 +-- src/librustdoc/lib.rs | 1 - src/librustdoc/passes/check_doc_cfg.rs | 72 ------------------- src/librustdoc/passes/mod.rs | 5 -- tests/rustdoc-ui/doc-cfg-2.rs | 2 + tests/rustdoc-ui/doc-cfg-2.stderr | 20 +++++- .../doc-cfg-check-cfg.cfg_empty.stderr | 12 ++-- tests/rustdoc-ui/issues/issue-91713.stdout | 2 - 13 files changed, 59 insertions(+), 135 deletions(-) delete mode 100644 src/librustdoc/passes/check_doc_cfg.rs diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs index 29be000d476d..acb234480d5d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs @@ -2,7 +2,6 @@ use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, Nod use rustc_ast_pretty::pprust; use rustc_feature::{Features, GatedCfg, find_gated_cfg}; use rustc_hir::RustcVersion; -use rustc_hir::lints::AttributeLintKind; use rustc_session::Session; use rustc_session::lint::{BuiltinLintDiag, Lint}; use rustc_session::parse::feature_err; diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index a26f22c4455d..ccb6a873fb12 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -294,7 +294,7 @@ impl DocParser { cx.expected_identifier(sub_item.path().span()); continue; }; - if let Ok(CfgEntry::NameValue { name, name_span, value, .. }) = + if let Ok(CfgEntry::NameValue { name, value, .. }) = super::cfg::parse_name_value( name, sub_item.path().span(), @@ -303,7 +303,14 @@ impl DocParser { cx, ) { - cfg_hide_show.values.push(CfgInfo { name, name_span, value }) + cfg_hide_show.values.push(CfgInfo { + name, + name_span: sub_item.path().span(), + // If `value` is `Some`, `a.name_value()` will always return + // `Some` as well. + value: value + .map(|v| (v, a.name_value().unwrap().value_span)), + }) } } _ => { diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index e4a55bf39333..b7f8be3ec88f 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -218,14 +218,7 @@ impl CfgEntry { ( Self::NameValue { name: name1, value: value1, .. }, Self::NameValue { name: name2, value: value2, .. }, - ) => { - name1 == name2 - && match (value1, value2) { - (Some((a, _)), Some((b, _))) => a == b, - (None, None) => true, - _ => false, - } - } + ) => name1 == name2 && value1 == value2, (Self::Version(a, _), Self::Version(b, _)) => a == b, _ => false, } @@ -257,7 +250,7 @@ impl fmt::Display for CfgEntry { match value { // We use `as_str` and debug display to have characters escaped and `"` // characters surrounding the string. - Some((value, _)) => write!(f, "{name} = {:?}", value.as_str()), + Some(value) => write!(f, "{name} = {:?}", value.as_str()), None => write!(f, "{name}"), } } diff --git a/library/std/build.rs b/library/std/build.rs index bee28e88491d..c0a6e30b3808 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -13,6 +13,9 @@ fn main() { println!("cargo:rustc-cfg=netbsd10"); } + // Needed for `#![doc(auto_cfg(hide(no_global_oom_handling)))]` attribute. + println!("cargo::rustc-check-cfg=cfg(no_global_oom_handling)"); + println!("cargo:rustc-check-cfg=cfg(restricted_std)"); if target_os == "linux" || target_os == "android" diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 1413f7f56c96..97a60c5a5098 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -140,12 +140,7 @@ impl Cfg { if exclude.contains(&NameValueCfg::new(name)) { Ok(None) } else { - Ok(Some(Cfg(CfgEntry::NameValue { - name, - value: None, - name_span: DUMMY_SP, - span: DUMMY_SP, - }))) + Ok(Some(Cfg(CfgEntry::NameValue { name, value: None, span: DUMMY_SP }))) } } MetaItemKind::NameValue(ref lit) => match lit.kind { @@ -155,8 +150,7 @@ impl Cfg { } else { Ok(Some(Cfg(CfgEntry::NameValue { name, - value: Some((value, DUMMY_SP)), - name_span: DUMMY_SP, + value: Some(value), span: DUMMY_SP, }))) } @@ -226,9 +220,7 @@ impl Cfg { CfgEntry::Any(sub_cfgs, _) => { sub_cfgs.iter().any(|sub_cfg| cfg_matches(sub_cfg, psess)) } - CfgEntry::NameValue { name, value, .. } => { - psess.config.contains(&(*name, value.clone().map(|(s, _)| s))) - } + CfgEntry::NameValue { name, value, .. } => psess.config.contains(&(*name, *value)), CfgEntry::Version(..) => { // FIXME: should be handled. false @@ -497,7 +489,7 @@ impl Display<'_> { sub_cfgs .iter() .map(|sub_cfg| { - if let CfgEntry::NameValue { value: Some((feat, _)), .. } = sub_cfg + if let CfgEntry::NameValue { value: Some(feat), .. } = sub_cfg && short_longhand { Either::Left(self.code_wrappers().wrap(feat)) @@ -557,7 +549,7 @@ impl fmt::Display for Display<'_> { (sym::unix, None) => "Unix", (sym::windows, None) => "Windows", (sym::debug_assertions, None) => "debug-assertions enabled", - (sym::target_os, Some((os, _))) => match os.as_str() { + (sym::target_os, Some(os)) => match os.as_str() { "android" => "Android", "cygwin" => "Cygwin", "dragonfly" => "DragonFly BSD", @@ -582,7 +574,7 @@ impl fmt::Display for Display<'_> { "visionos" => "visionOS", _ => "", }, - (sym::target_arch, Some((arch, _))) => match arch.as_str() { + (sym::target_arch, Some(arch)) => match arch.as_str() { "aarch64" => "AArch64", "arm" => "ARM", "loongarch32" => "LoongArch LA32", @@ -605,14 +597,14 @@ impl fmt::Display for Display<'_> { "x86_64" => "x86-64", _ => "", }, - (sym::target_vendor, Some((vendor, _))) => match vendor.as_str() { + (sym::target_vendor, Some(vendor)) => match vendor.as_str() { "apple" => "Apple", "pc" => "PC", "sun" => "Sun", "fortanix" => "Fortanix", _ => "", }, - (sym::target_env, Some((env, _))) => match env.as_str() { + (sym::target_env, Some(env)) => match env.as_str() { "gnu" => "GNU", "msvc" => "MSVC", "musl" => "musl", @@ -621,20 +613,20 @@ impl fmt::Display for Display<'_> { "sgx" => "SGX", _ => "", }, - (sym::target_endian, Some((endian, _))) => { + (sym::target_endian, Some(endian)) => { return write!(fmt, "{endian}-endian"); } - (sym::target_pointer_width, Some((bits, _))) => { + (sym::target_pointer_width, Some(bits)) => { return write!(fmt, "{bits}-bit"); } - (sym::target_feature, Some((feat, _))) => match self.1 { + (sym::target_feature, Some(feat)) => match self.1 { Format::LongHtml => { return write!(fmt, "target feature {feat}"); } Format::LongPlain => return write!(fmt, "target feature `{feat}`"), Format::ShortHtml => return write!(fmt, "{feat}"), }, - (sym::feature, Some((feat, _))) => match self.1 { + (sym::feature, Some(feat)) => match self.1 { Format::LongHtml => { return write!(fmt, "crate feature {feat}"); } @@ -647,9 +639,7 @@ impl fmt::Display for Display<'_> { fmt.write_str(human_readable) } else { let value = value - .map(|(v, _)| { - fmt::from_fn(move |f| write!(f, "={}", self.1.escape(v.as_str()))) - }) + .map(|v| fmt::from_fn(move |f| write!(f, "={}", self.1.escape(v.as_str())))) .maybe_display(); self.code_wrappers() .wrap(format_args!("{}{value}", self.1.escape(name.as_str()))) @@ -684,9 +674,7 @@ impl NameValueCfg { impl<'a> From<&'a CfgEntry> for NameValueCfg { fn from(cfg: &'a CfgEntry) -> Self { match cfg { - CfgEntry::NameValue { name, value, .. } => { - NameValueCfg { name: *name, value: (*value).map(|(v, _)| v) } - } + CfgEntry::NameValue { name, value, .. } => NameValueCfg { name: *name, value: *value }, _ => NameValueCfg { name: sym::empty, value: None }, } } @@ -886,8 +874,7 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator for (feature, _) in features { cfg_info.current_cfg &= Cfg(CfgEntry::NameValue { name: sym::target_feature, - value: Some((*feature, DUMMY_SP)), - name_span: DUMMY_SP, + value: Some(*feature), span: DUMMY_SP, }); } diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 4eb6c060cbd2..09316ead76ac 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -12,12 +12,7 @@ fn word_cfg(name: &str) -> Cfg { } fn word_cfg_e(name: &str) -> CfgEntry { - CfgEntry::NameValue { - name: Symbol::intern(name), - name_span: DUMMY_SP, - value: None, - span: DUMMY_SP, - } + CfgEntry::NameValue { name: Symbol::intern(name), value: None, span: DUMMY_SP } } fn name_value_cfg(name: &str, value: &str) -> Cfg { @@ -27,8 +22,8 @@ fn name_value_cfg(name: &str, value: &str) -> Cfg { fn name_value_cfg_e(name: &str, value: &str) -> CfgEntry { CfgEntry::NameValue { name: Symbol::intern(name), - name_span: DUMMY_SP, - value: Some((Symbol::intern(value), DUMMY_SP)), + + value: Some(Symbol::intern(value)), span: DUMMY_SP, } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 5e582eb61997..cc8a308688d2 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -32,7 +32,6 @@ extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_attr_parsing; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; diff --git a/src/librustdoc/passes/check_doc_cfg.rs b/src/librustdoc/passes/check_doc_cfg.rs deleted file mode 100644 index 9e7fae5e14e4..000000000000 --- a/src/librustdoc/passes/check_doc_cfg.rs +++ /dev/null @@ -1,72 +0,0 @@ -use rustc_attr_parsing::{ShouldEmit, eval_config_entry}; -use rustc_hir::attrs::AttributeKind; -use rustc_hir::def_id::LocalDefId; -use rustc_hir::{Attribute, HirId}; -use rustc_middle::ty::TyCtxt; - -use super::Pass; -use crate::clean::{Attributes, Crate, Item}; -use crate::core::DocContext; -use crate::visit::DocVisitor; - -pub(crate) const CHECK_DOC_CFG: Pass = Pass { - name: "check-doc-cfg", - run: Some(check_doc_cfg), - description: "checks `#[doc(cfg(...))]` for stability feature and unexpected cfgs", -}; - -pub(crate) fn check_doc_cfg(krate: Crate, cx: &mut DocContext<'_>) -> Crate { - let mut checker = DocCfgChecker { cx }; - checker.visit_crate(&krate); - krate -} - -struct RustdocCfgMatchesLintEmitter<'a>(TyCtxt<'a>, HirId); - -impl<'a> rustc_attr_parsing::CfgMatchesLintEmitter for RustdocCfgMatchesLintEmitter<'a> { - fn emit_span_lint( - &self, - sess: &rustc_session::Session, - lint: &'static rustc_lint::Lint, - sp: rustc_span::Span, - builtin_diag: rustc_lint_defs::BuiltinLintDiag, - ) { - self.0.node_span_lint(lint, self.1, sp, |diag| { - rustc_lint::decorate_builtin_lint(sess, Some(self.0), builtin_diag, diag) - }); - } -} - -struct DocCfgChecker<'a, 'tcx> { - cx: &'a mut DocContext<'tcx>, -} - -impl DocCfgChecker<'_, '_> { - fn check_attrs(&mut self, attrs: &Attributes, did: LocalDefId) { - for attr in &attrs.other_attrs { - let Attribute::Parsed(AttributeKind::Doc(d)) = attr else { continue }; - - for doc_cfg in &d.cfg { - let _ = eval_config_entry( - &self.cx.tcx.sess, - doc_cfg, - &RustdocCfgMatchesLintEmitter( - self.cx.tcx, - self.cx.tcx.local_def_id_to_hir_id(did), - ), - ShouldEmit::ErrorsAndLints, - ); - } - } - } -} - -impl DocVisitor<'_> for DocCfgChecker<'_, '_> { - fn visit_item(&mut self, item: &'_ Item) { - if let Some(Some(local_did)) = item.def_id().map(|did| did.as_local()) { - self.check_attrs(&item.attrs, local_did); - } - - self.visit_item_recur(item); - } -} diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index a1e8e7530623..18e1afaf8a24 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -32,9 +32,6 @@ pub(crate) use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS; mod check_doc_test_visibility; pub(crate) use self::check_doc_test_visibility::CHECK_DOC_TEST_VISIBILITY; -mod check_doc_cfg; -pub(crate) use self::check_doc_cfg::CHECK_DOC_CFG; - mod collect_trait_impls; pub(crate) use self::collect_trait_impls::COLLECT_TRAIT_IMPLS; @@ -75,7 +72,6 @@ pub(crate) enum Condition { /// The full list of passes. pub(crate) const PASSES: &[Pass] = &[ - CHECK_DOC_CFG, CHECK_DOC_TEST_VISIBILITY, PROPAGATE_DOC_CFG, STRIP_ALIASED_NON_LOCAL, @@ -93,7 +89,6 @@ pub(crate) const PASSES: &[Pass] = &[ pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[ ConditionalPass::always(COLLECT_TRAIT_IMPLS), ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY), - ConditionalPass::always(CHECK_DOC_CFG), ConditionalPass::always(STRIP_ALIASED_NON_LOCAL), ConditionalPass::always(PROPAGATE_DOC_CFG), ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden), diff --git a/tests/rustdoc-ui/doc-cfg-2.rs b/tests/rustdoc-ui/doc-cfg-2.rs index bd6a2dc18be9..7a5d1f3e3dbb 100644 --- a/tests/rustdoc-ui/doc-cfg-2.rs +++ b/tests/rustdoc-ui/doc-cfg-2.rs @@ -12,5 +12,7 @@ // Shouldn't lint #[doc(auto_cfg(hide(windows)))] #[doc(auto_cfg(hide(feature = "windows")))] +//~^ WARN unexpected `cfg` condition name: `feature` #[doc(auto_cfg(hide(foo)))] +//~^ WARN unexpected `cfg` condition name: `foo` pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-cfg-2.stderr b/tests/rustdoc-ui/doc-cfg-2.stderr index f3d67abfb8dd..1272e569897b 100644 --- a/tests/rustdoc-ui/doc-cfg-2.stderr +++ b/tests/rustdoc-ui/doc-cfg-2.stderr @@ -56,5 +56,23 @@ error: expected boolean for `#[doc(auto_cfg = ...)]` LL | #[doc(auto_cfg = "a")] | ^^^ -error: aborting due to 6 previous errors; 2 warnings emitted +warning: unexpected `cfg` condition name: `feature` + --> $DIR/doc-cfg-2.rs:14:21 + | +LL | #[doc(auto_cfg(hide(feature = "windows")))] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(feature, values("windows"))` + = note: see for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `foo` + --> $DIR/doc-cfg-2.rs:16:21 + | +LL | #[doc(auto_cfg(hide(foo)))] + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see for more information about checking conditional configuration + +error: aborting due to 6 previous errors; 4 warnings emitted diff --git a/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr b/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr index 0878f7edbf48..3f67b85900aa 100644 --- a/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr +++ b/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr @@ -1,8 +1,8 @@ warning: unexpected `cfg` condition name: `foo` - --> $DIR/doc-cfg-check-cfg.rs:12:12 + --> $DIR/doc-cfg-check-cfg.rs:15:11 | -LL | #![doc(cfg(foo))] - | ^^^ +LL | #[doc(cfg(foo))] + | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(foo)` = note: see for more information about checking conditional configuration @@ -18,10 +18,10 @@ LL | #[doc(cfg(foo))] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `foo` - --> $DIR/doc-cfg-check-cfg.rs:15:11 + --> $DIR/doc-cfg-check-cfg.rs:12:12 | -LL | #[doc(cfg(foo))] - | ^^^ +LL | #![doc(cfg(foo))] + | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(foo)` = note: see for more information about checking conditional configuration diff --git a/tests/rustdoc-ui/issues/issue-91713.stdout b/tests/rustdoc-ui/issues/issue-91713.stdout index c0cd454e8f3a..e7b8a1dccf80 100644 --- a/tests/rustdoc-ui/issues/issue-91713.stdout +++ b/tests/rustdoc-ui/issues/issue-91713.stdout @@ -1,5 +1,4 @@ Available passes for running rustdoc: - check-doc-cfg - checks `#[doc(cfg(...))]` for stability feature and unexpected cfgs check_doc_test_visibility - run various visibility-related lints on doctests propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items strip-aliased-non-local - strips all non-local private aliased items from the output @@ -15,7 +14,6 @@ calculate-doc-coverage - counts the number of items with and without documentati Default passes for rustdoc: collect-trait-impls check_doc_test_visibility - check-doc-cfg strip-aliased-non-local propagate-doc-cfg strip-hidden (when not --document-hidden-items) From 3ea946216700c1c6ede64a0d5db658419afc3017 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Dec 2025 12:27:26 +0100 Subject: [PATCH 0534/3801] Remove `Cfg::matches` and use `eval_config_entry` instead --- src/librustdoc/clean/cfg.rs | 29 ++++------------------------- src/librustdoc/doctest/rust.rs | 3 ++- src/librustdoc/lib.rs | 1 + 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 97a60c5a5098..7ab2a72d75b5 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -14,7 +14,6 @@ use rustc_hir as hir; use rustc_hir::Attribute; use rustc_hir::attrs::{self, AttributeKind, CfgEntry, CfgHideShow, HideOrShow}; use rustc_middle::ty::TyCtxt; -use rustc_session::parse::ParseSess; use rustc_span::symbol::{Symbol, sym}; use rustc_span::{DUMMY_SP, Span}; @@ -206,30 +205,6 @@ impl Cfg { Self::parse_nested(cfg, &FxHashSet::default()).map(|ret| ret.unwrap()) } - /// Checks whether the given configuration can be matched in the current session. - /// - /// Equivalent to `attr::cfg_matches`. - pub(crate) fn matches(&self, psess: &ParseSess) -> bool { - fn cfg_matches(cfg: &CfgEntry, psess: &ParseSess) -> bool { - match cfg { - CfgEntry::Bool(v, _) => *v, - CfgEntry::Not(child, _) => !cfg_matches(child, psess), - CfgEntry::All(sub_cfgs, _) => { - sub_cfgs.iter().all(|sub_cfg| cfg_matches(sub_cfg, psess)) - } - CfgEntry::Any(sub_cfgs, _) => { - sub_cfgs.iter().any(|sub_cfg| cfg_matches(sub_cfg, psess)) - } - CfgEntry::NameValue { name, value, .. } => psess.config.contains(&(*name, *value)), - CfgEntry::Version(..) => { - // FIXME: should be handled. - false - } - } - } - cfg_matches(&self.0, psess) - } - /// Renders the configuration for human display, as a short HTML description. pub(crate) fn render_short_html(&self) -> String { let mut msg = Display(&self.0, Format::ShortHtml).to_string(); @@ -320,6 +295,10 @@ impl Cfg { fn omit_preposition(&self) -> bool { matches!(self.0, CfgEntry::Bool(..)) } + + pub(crate) fn inner(&self) -> &CfgEntry { + &self.0 + } } impl ops::Not for Cfg { diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 987e1c2ddbf9..ee1419d17d6e 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -6,6 +6,7 @@ use std::str::FromStr; use std::sync::Arc; use proc_macro2::{TokenStream, TokenTree}; +use rustc_attr_parsing::eval_config_entry; use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::{self as hir, Attribute, CRATE_HIR_ID, intravisit}; @@ -123,7 +124,7 @@ impl HirCollector<'_> { let ast_attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id)); if let Some(ref cfg) = extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &mut CfgInfo::default()) - && !cfg.matches(&self.tcx.sess.psess) + && !eval_config_entry(&self.tcx.sess, cfg.inner()).as_bool() { return; } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index cc8a308688d2..5e582eb61997 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -32,6 +32,7 @@ extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_ast_pretty; +extern crate rustc_attr_parsing; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_errors; From 503b34ab0d22cf8bf658809ed71c1d27e8652717 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 8 Dec 2025 22:44:41 +0100 Subject: [PATCH 0535/3801] Update clippy code --- clippy_lints/src/doc/doc_suspicious_footnotes.rs | 9 ++++++++- clippy_lints/src/doc/suspicious_doc_comments.rs | 8 ++++---- clippy_utils/src/attrs.rs | 7 +------ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/clippy_lints/src/doc/doc_suspicious_footnotes.rs b/clippy_lints/src/doc/doc_suspicious_footnotes.rs index 1944cd7c91d3..deca29a1885f 100644 --- a/clippy_lints/src/doc/doc_suspicious_footnotes.rs +++ b/clippy_lints/src/doc/doc_suspicious_footnotes.rs @@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_ast::attr::AttributeExt as _; use rustc_ast::token::{CommentKind, DocFragmentKind}; use rustc_errors::Applicability; +use rustc_hir::attrs::AttributeKind; use rustc_hir::{AttrStyle, Attribute}; use rustc_lint::{LateContext, LintContext}; @@ -45,7 +46,13 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range, fragments: &F if let DocFragmentKind::Sugared(_) = this_fragment.kind { let (doc_attr, doc_attr_comment_kind, attr_style) = attrs .iter() - .filter(|attr| attr.span().overlaps(this_fragment.span)) + .filter(|attr| { + matches!( + attr, + Attribute::Parsed(AttributeKind::DocComment { span, .. }) + if span.overlaps(this_fragment.span), + ) + }) .rev() .find_map(|attr| { let (_, fragment) = attr.doc_str_and_fragment_kind()?; diff --git a/clippy_lints/src/doc/suspicious_doc_comments.rs b/clippy_lints/src/doc/suspicious_doc_comments.rs index e751600f00a6..178d688264b7 100644 --- a/clippy_lints/src/doc/suspicious_doc_comments.rs +++ b/clippy_lints/src/doc/suspicious_doc_comments.rs @@ -39,15 +39,15 @@ fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { .filter_map(|attr| { if let Attribute::Parsed(AttributeKind::DocComment { style: AttrStyle::Outer, - kind, + kind: DocFragmentKind::Sugared(comment_kind), comment, .. }) = attr && let Some(com) = comment.as_str().strip_prefix('!') { - let sugg = match kind { - DocFragmentKind::Sugared(CommentKind::Block) => format!("/*!{com}*/"), - DocFragmentKind::Sugared(CommentKind::Line) | DocFragmentKind::Raw(_) => format!("//!{com}"), + let sugg = match comment_kind { + CommentKind::Block => format!("/*!{com}*/"), + CommentKind::Line => format!("//!{com}"), }; Some((attr.span(), sugg)) } else { diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs index 671b266ba008..2fd773b06781 100644 --- a/clippy_utils/src/attrs.rs +++ b/clippy_utils/src/attrs.rs @@ -2,7 +2,6 @@ use crate::source::SpanRangeExt; use crate::{sym, tokenize_with_text}; -use rustc_ast::attr; use rustc_ast::attr::AttributeExt; use rustc_errors::Applicability; use rustc_hir::attrs::AttributeKind; @@ -87,11 +86,7 @@ pub fn is_proc_macro(attrs: &[impl AttributeExt]) -> bool { /// Checks whether `attrs` contain `#[doc(hidden)]` pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool { - attrs - .iter() - .filter(|attr| attr.has_name(sym::doc)) - .filter_map(AttributeExt::meta_item_list) - .any(|l| attr::list_contains_name(&l, sym::hidden)) + attrs.iter().any(|attr| attr.is_doc_hidden()) } /// Checks whether the given ADT, or any of its fields/variants, are marked as `#[non_exhaustive]` From 9fdec8194e6045133629d899bc4b7048d00311d4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Dec 2025 12:35:17 +0100 Subject: [PATCH 0536/3801] Fix new merge conflict --- .../parser/attribute/attr-unquoted-ident.rs | 5 ++++- .../attribute/attr-unquoted-ident.stderr | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.rs b/tests/ui/parser/attribute/attr-unquoted-ident.rs index 152448bf8a0f..6207662a6e19 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.rs +++ b/tests/ui/parser/attribute/attr-unquoted-ident.rs @@ -26,7 +26,10 @@ fn main() { macro_rules! make { ($name:ident) => { #[doc(alias = $name)] pub struct S; } - //~^ ERROR: expected unsuffixed literal, found identifier `nickname` + //~^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + //~| NOTE: expressions are not allowed here + //~| HELP: surround the identifier with quotation marks to make it into a string literal } make!(nickname); //~ NOTE: in this expansion +//~^ NOTE in this expansion of make diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.stderr b/tests/ui/parser/attribute/attr-unquoted-ident.stderr index 00fb539f8a86..48ca499ba78f 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.stderr +++ b/tests/ui/parser/attribute/attr-unquoted-ident.stderr @@ -20,14 +20,31 @@ help: surround the identifier with quotation marks to make it into a string lite LL | #[cfg(key="foo bar baz")] | + + +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/attr-unquoted-ident.rs:18:15 + | +LL | #[cfg(key=foo 1 bar 2.0 baz.)] + | ^^^ expressions are not allowed here + | +help: surround the identifier with quotation marks to make it into a string literal + | +LL | #[cfg(key="foo 1 bar 2.0 baz.")] + | + + + +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/attr-unquoted-ident.rs:28:38 | LL | ($name:ident) => { #[doc(alias = $name)] pub struct S; } - | ^^^^^ + | ^^^^^ expressions are not allowed here ... LL | make!(nickname); | --------------- in this macro invocation | = note: this error originates in the macro `make` (in Nightly builds, run with -Z macro-backtrace for more info) +help: surround the identifier with quotation marks to make it into a string literal + | +LL | ($name:ident) => { #[doc(alias = "$name")] pub struct S; } + | + + error: aborting due to 4 previous errors From b67a2d5379f8fa6f7b4f4d4c4d88aba485e19066 Mon Sep 17 00:00:00 2001 From: benodiwal Date: Wed, 10 Dec 2025 17:37:26 +0530 Subject: [PATCH 0537/3801] feat: show parameter hint for missing arguments --- .../crates/ide/src/inlay_hints.rs | 2 + .../crates/ide/src/inlay_hints/param_name.rs | 195 ++++++++++++++++++ .../crates/ide/src/static_index.rs | 1 + .../rust-analyzer/src/cli/analysis_stats.rs | 1 + .../crates/rust-analyzer/src/config.rs | 6 + .../docs/book/src/configuration_generated.md | 7 + .../rust-analyzer/editors/code/package.json | 10 + 7 files changed, 222 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index 03674978d53d..d05c7811b087 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -307,6 +307,7 @@ pub struct InlayHintsConfig<'a> { pub sized_bound: bool, pub discriminant_hints: DiscriminantHints, pub parameter_hints: bool, + pub parameter_hints_for_missing_arguments: bool, pub generic_parameter_hints: GenericParameterHints, pub chaining_hints: bool, pub adjustment_hints: AdjustmentHints, @@ -886,6 +887,7 @@ mod tests { render_colons: false, type_hints: false, parameter_hints: false, + parameter_hints_for_missing_arguments: false, sized_bound: false, generic_parameter_hints: GenericParameterHints { type_hints: false, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs index 8d0348767316..f1e62a5ab8ac 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs @@ -11,6 +11,7 @@ use hir::{EditionedFileId, Semantics}; use ide_db::{RootDatabase, famous_defs::FamousDefs}; use stdx::to_lower_snake_case; +use syntax::T; use syntax::ast::{self, AstNode, HasArgList, HasName, UnaryOp}; use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; @@ -88,9 +89,75 @@ pub(super) fn hints( }); acc.extend(hints); + + // Show hint for the next expected (missing) argument if enabled + if config.parameter_hints_for_missing_arguments { + let provided_args_count = arg_list.args().count(); + let params = callable.params(); + let total_params = params.len(); + + if provided_args_count < total_params + && let Some(next_param) = params.get(provided_args_count) + && let Some(param_name) = next_param.name(sema.db) + { + // Apply heuristics to hide obvious parameter hints + if should_hide_missing_param_hint(unary_function, function_name, param_name.as_str()) { + return Some(()); + } + + // Determine the position for the hint + if let Some(hint_range) = missing_arg_hint_position(&arg_list) { + let colon = if config.render_colons { ":" } else { "" }; + let label = InlayHintLabel::simple( + format!("{}{}", param_name.display(sema.db, krate.edition(sema.db)), colon), + None, + config.lazy_location_opt(|| { + let source = sema.source(next_param.clone())?; + let name_syntax = match source.value.as_ref() { + Either::Left(pat) => pat.name(), + Either::Right(param) => match param.pat()? { + ast::Pat::IdentPat(it) => it.name(), + _ => None, + }, + }?; + sema.original_range_opt(name_syntax.syntax()).map(|frange| { + ide_db::FileRange { + file_id: frange.file_id.file_id(sema.db), + range: frange.range, + } + }) + }), + ); + acc.push(InlayHint { + range: hint_range, + kind: InlayKind::Parameter, + label, + text_edit: None, + position: InlayHintPosition::Before, + pad_left: true, + pad_right: false, + resolve_parent: Some(expr.syntax().text_range()), + }); + } + } + } + Some(()) } +/// Determines the position where the hint for a missing argument should be placed. +/// Returns the range of the token where the hint should appear. +fn missing_arg_hint_position(arg_list: &ast::ArgList) -> Option { + // Always place the hint on the closing paren, so it appears before `)`. + // This way `foo()` becomes `foo(a)` visually with the hint. + arg_list + .syntax() + .children_with_tokens() + .filter_map(|it| it.into_token()) + .find(|t| t.kind() == T![')']) + .map(|t| t.text_range()) +} + fn get_callable<'db>( sema: &Semantics<'db, RootDatabase>, expr: &ast::Expr, @@ -153,6 +220,37 @@ fn should_hide_param_name_hint( is_argument_expr_similar_to_param_name(sema, argument, param_name) } +/// Determines whether to hide the parameter hint for a missing argument. +/// This is a simplified version of `should_hide_param_name_hint` that doesn't +/// require an actual argument expression. +fn should_hide_missing_param_hint( + unary_function: bool, + function_name: Option<&str>, + param_name: &str, +) -> bool { + let param_name = param_name.trim_matches('_'); + if param_name.is_empty() { + return true; + } + + if param_name.starts_with("ra_fixture") { + return true; + } + + if unary_function { + if let Some(function_name) = function_name + && is_param_name_suffix_of_fn_name(param_name, function_name) + { + return true; + } + if is_obvious_param(param_name) { + return true; + } + } + + false +} + /// Hide the parameter name of a unary function if it is a `_` - prefixed suffix of the function's name, or equal. /// /// `fn strip_suffix(suffix)` will be hidden. @@ -606,6 +704,103 @@ fn main() { // ^^^^^^ a_d_e baz(a.d.ec); // ^^^^^^ a_d_e +}"#, + ); + } + + #[track_caller] + fn check_missing_params(#[rust_analyzer::rust_fixture] ra_fixture: &str) { + check_with_config( + InlayHintsConfig { + parameter_hints: true, + parameter_hints_for_missing_arguments: true, + ..DISABLED_CONFIG + }, + ra_fixture, + ); + } + + #[test] + fn missing_param_hint_empty_call() { + // When calling foo() with no args, show hint for first param on the closing paren + check_missing_params( + r#" +fn foo(a: i32, b: i32) -> i32 { a + b } +fn main() { + foo(); + //^ a +}"#, + ); + } + + #[test] + fn missing_param_hint_after_first_arg() { + // foo(1,) - show hint for 'a' on '1', and 'b' on the trailing comma + check_missing_params( + r#" +fn foo(a: i32, b: i32) -> i32 { a + b } +fn main() { + foo(1,); + //^ a + //^ b +}"#, + ); + } + + #[test] + fn missing_param_hint_partial_args() { + // foo(1, 2,) - show hints for a, b on args, and c on trailing comma + check_missing_params( + r#" +fn foo(a: i32, b: i32, c: i32) -> i32 { a + b + c } +fn main() { + foo(1, 2,); + //^ a + //^ b + //^ c +}"#, + ); + } + + #[test] + fn missing_param_hint_method_call() { + // S.foo(1,) - show hint for 'a' on '1', and 'b' on trailing comma + check_missing_params( + r#" +struct S; +impl S { + fn foo(&self, a: i32, b: i32) -> i32 { a + b } +} +fn main() { + S.foo(1,); + //^ a + //^ b +}"#, + ); + } + + #[test] + fn missing_param_hint_no_hint_when_complete() { + // When all args provided, no missing hint - just regular param hints + check_missing_params( + r#" +fn foo(a: i32, b: i32) -> i32 { a + b } +fn main() { + foo(1, 2); + //^ a + //^ b +}"#, + ); + } + + #[test] + fn missing_param_hint_respects_heuristics() { + // The hint should be hidden if it matches heuristics (e.g., single param unary fn with same name) + check_missing_params( + r#" +fn foo(foo: i32) -> i32 { foo } +fn main() { + foo(); }"#, ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 30e8d62ea210..e87766376acb 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -169,6 +169,7 @@ impl StaticIndex<'_> { type_hints: true, sized_bound: false, parameter_hints: true, + parameter_hints_for_missing_arguments: false, generic_parameter_hints: crate::GenericParameterHints { type_hints: false, lifetime_hints: false, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index f39ab1301f8f..1a6cd784cf2f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -1205,6 +1205,7 @@ impl flags::AnalysisStats { sized_bound: false, discriminant_hints: ide::DiscriminantHints::Always, parameter_hints: true, + parameter_hints_for_missing_arguments: false, generic_parameter_hints: ide::GenericParameterHints { type_hints: true, lifetime_hints: true, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 1a2ea97204aa..007725be7406 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -280,6 +280,9 @@ config_data! { /// Show function parameter name inlay hints at the call site. inlayHints_parameterHints_enable: bool = true, + /// Show parameter name inlay hints for missing arguments at the call site. + inlayHints_parameterHints_missingArguments_enable: bool = false, + /// Show exclusive range inlay hints. inlayHints_rangeExclusiveHints_enable: bool = false, @@ -1916,6 +1919,9 @@ impl Config { type_hints: self.inlayHints_typeHints_enable().to_owned(), sized_bound: self.inlayHints_implicitSizedBoundHints_enable().to_owned(), parameter_hints: self.inlayHints_parameterHints_enable().to_owned(), + parameter_hints_for_missing_arguments: self + .inlayHints_parameterHints_missingArguments_enable() + .to_owned(), generic_parameter_hints: GenericParameterHints { type_hints: self.inlayHints_genericParameterHints_type_enable().to_owned(), lifetime_hints: self.inlayHints_genericParameterHints_lifetime_enable().to_owned(), diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index b36576b4bb20..1f5c672233ae 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1070,6 +1070,13 @@ Default: `true` Show function parameter name inlay hints at the call site. +## rust-analyzer.inlayHints.parameterHints.missingArguments.enable {#inlayHints.parameterHints.missingArguments.enable} + +Default: `false` + +Show parameter name inlay hints for missing arguments at the call site. + + ## rust-analyzer.inlayHints.rangeExclusiveHints.enable {#inlayHints.rangeExclusiveHints.enable} Default: `false` diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index abe85d6c9d72..98fe6a558b80 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -2396,6 +2396,16 @@ } } }, + { + "title": "Inlay Hints", + "properties": { + "rust-analyzer.inlayHints.parameterHints.missingArguments.enable": { + "markdownDescription": "Show parameter name inlay hints for missing arguments at the call site.", + "default": false, + "type": "boolean" + } + } + }, { "title": "Inlay Hints", "properties": { From fd8f92d94ad4ba990e3b289edf4518318a585d2a Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Wed, 10 Dec 2025 15:23:07 +0200 Subject: [PATCH 0538/3801] Move `format_args!()` lowering to a separate file It's growing out of control. --- .../crates/hir-def/src/expr_store/lower.rs | 689 +---------------- .../src/expr_store/lower/format_args.rs | 699 ++++++++++++++++++ 2 files changed, 702 insertions(+), 686 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 0b2af134c8ca..3448b734ff10 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -2,6 +2,7 @@ //! representation. mod asm; +mod format_args; mod generics; mod path; @@ -19,7 +20,7 @@ use intern::{Symbol, sym}; use rustc_hash::FxHashMap; use stdx::never; use syntax::{ - AstNode, AstPtr, AstToken as _, SyntaxNodePtr, + AstNode, AstPtr, SyntaxNodePtr, ast::{ self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasAttrs, HasGenericArgs, HasGenericParams, HasLoopBody, HasName, HasTypeBounds, IsString, RangeItem, @@ -34,7 +35,6 @@ use crate::{ AdtId, BlockId, BlockLoc, DefWithBodyId, FunctionId, GenericDefId, ImplId, MacroId, ModuleDefId, ModuleId, TraitId, TypeAliasId, UnresolvedMacro, attrs::AttrFlags, - builtin_type::BuiltinUint, db::DefDatabase, expr_store::{ Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder, @@ -47,13 +47,7 @@ use crate::{ hir::{ Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind, Expr, ExprId, Item, Label, LabelId, Literal, MatchArm, Movability, OffsetOf, Pat, PatId, - RecordFieldPat, RecordLitField, Statement, - format_args::{ - self, FormatAlignment, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind, - FormatArgumentsCollector, FormatCount, FormatDebugHex, FormatOptions, - FormatPlaceholder, FormatSign, FormatTrait, - }, - generics::GenericParams, + RecordFieldPat, RecordLitField, Statement, generics::GenericParams, }, item_scope::BuiltinShadowMode, item_tree::FieldsShape, @@ -2608,7 +2602,6 @@ impl<'db> ExprCollector<'db> { } // endregion: labels - // region: format fn expand_macros_to_string(&mut self, expr: ast::Expr) -> Option<(ast::String, bool)> { let m = match expr { ast::Expr::MacroExpr(m) => m, @@ -2628,676 +2621,6 @@ impl<'db> ExprCollector<'db> { Some((exp, false)) } - fn collect_format_args( - &mut self, - f: ast::FormatArgsExpr, - syntax_ptr: AstPtr, - ) -> ExprId { - let mut args = FormatArgumentsCollector::default(); - f.args().for_each(|arg| { - args.add(FormatArgument { - kind: match arg.name() { - Some(name) => FormatArgumentKind::Named(name.as_name()), - None => FormatArgumentKind::Normal, - }, - expr: self.collect_expr_opt(arg.expr()), - }); - }); - let template = f.template(); - let fmt_snippet = template.as_ref().and_then(|it| match it { - ast::Expr::Literal(literal) => match literal.kind() { - ast::LiteralKind::String(s) => Some(s.text().to_owned()), - _ => None, - }, - _ => None, - }); - let mut mappings = vec![]; - let (fmt, hygiene) = match template.and_then(|template| { - self.expand_macros_to_string(template.clone()).map(|it| (it, template)) - }) { - Some(((s, is_direct_literal), template)) => { - let call_ctx = self.expander.call_syntax_ctx(); - let hygiene = self.hygiene_id_for(s.syntax().text_range()); - let fmt = format_args::parse( - &s, - fmt_snippet, - args, - is_direct_literal, - |name, range| { - let expr_id = self.alloc_expr_desugared(Expr::Path(Path::from(name))); - if let Some(range) = range { - self.store - .template_map - .get_or_insert_with(Default::default) - .implicit_capture_to_source - .insert( - expr_id, - self.expander.in_file((AstPtr::new(&template), range)), - ); - } - if !hygiene.is_root() { - self.store.ident_hygiene.insert(expr_id.into(), hygiene); - } - expr_id - }, - |name, span| { - if let Some(span) = span { - mappings.push((span, name)) - } - }, - call_ctx, - ); - (fmt, hygiene) - } - None => ( - FormatArgs { - template: Default::default(), - arguments: args.finish(), - orphans: Default::default(), - }, - HygieneId::ROOT, - ), - }; - - // Create a list of all _unique_ (argument, format trait) combinations. - // E.g. "{0} {0:x} {0} {1}" -> [(0, Display), (0, LowerHex), (1, Display)] - let mut argmap = FxIndexSet::default(); - for piece in fmt.template.iter() { - let FormatArgsPiece::Placeholder(placeholder) = piece else { continue }; - if let Ok(index) = placeholder.argument.index { - argmap.insert((index, ArgumentType::Format(placeholder.format_trait))); - } - } - - let lit_pieces = fmt - .template - .iter() - .enumerate() - .filter_map(|(i, piece)| { - match piece { - FormatArgsPiece::Literal(s) => { - Some(self.alloc_expr_desugared(Expr::Literal(Literal::String(s.clone())))) - } - &FormatArgsPiece::Placeholder(_) => { - // Inject empty string before placeholders when not already preceded by a literal piece. - if i == 0 || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_)) - { - Some(self.alloc_expr_desugared(Expr::Literal(Literal::String( - Symbol::empty(), - )))) - } else { - None - } - } - } - }) - .collect(); - let lit_pieces = - self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: lit_pieces })); - let lit_pieces = self.alloc_expr_desugared(Expr::Ref { - expr: lit_pieces, - rawness: Rawness::Ref, - mutability: Mutability::Shared, - }); - let format_options = { - // Generate: - // &[format_spec_0, format_spec_1, format_spec_2] - let elements = fmt - .template - .iter() - .filter_map(|piece| { - let FormatArgsPiece::Placeholder(placeholder) = piece else { return None }; - Some(self.make_format_spec(placeholder, &mut argmap)) - }) - .collect(); - let array = self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements })); - self.alloc_expr_desugared(Expr::Ref { - expr: array, - rawness: Rawness::Ref, - mutability: Mutability::Shared, - }) - }; - - // Assume that rustc version >= 1.89.0 iff lang item `format_arguments` exists - // but `format_unsafe_arg` does not - let lang_items = self.lang_items(); - let fmt_args = lang_items.FormatArguments; - let fmt_unsafe_arg = lang_items.FormatUnsafeArg; - let use_format_args_since_1_89_0 = fmt_args.is_some() && fmt_unsafe_arg.is_none(); - - let idx = if use_format_args_since_1_89_0 { - self.collect_format_args_impl(syntax_ptr, fmt, argmap, lit_pieces, format_options) - } else { - self.collect_format_args_before_1_89_0_impl( - syntax_ptr, - fmt, - argmap, - lit_pieces, - format_options, - ) - }; - - self.store - .template_map - .get_or_insert_with(Default::default) - .format_args_to_captures - .insert(idx, (hygiene, mappings)); - idx - } - - /// `format_args!` expansion implementation for rustc versions < `1.89.0` - fn collect_format_args_before_1_89_0_impl( - &mut self, - syntax_ptr: AstPtr, - fmt: FormatArgs, - argmap: FxIndexSet<(usize, ArgumentType)>, - lit_pieces: ExprId, - format_options: ExprId, - ) -> ExprId { - let arguments = &*fmt.arguments.arguments; - - let args = if arguments.is_empty() { - let expr = self - .alloc_expr_desugared(Expr::Array(Array::ElementList { elements: Box::default() })); - self.alloc_expr_desugared(Expr::Ref { - expr, - rawness: Rawness::Ref, - mutability: Mutability::Shared, - }) - } else { - // Generate: - // &match (&arg0, &arg1, &…) { - // args => [ - // ::new_display(args.0), - // ::new_lower_hex(args.1), - // ::new_debug(args.0), - // … - // ] - // } - let args = argmap - .iter() - .map(|&(arg_index, ty)| { - let arg = self.alloc_expr_desugared(Expr::Ref { - expr: arguments[arg_index].expr, - rawness: Rawness::Ref, - mutability: Mutability::Shared, - }); - self.make_argument(arg, ty) - }) - .collect(); - let array = - self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args })); - self.alloc_expr_desugared(Expr::Ref { - expr: array, - rawness: Rawness::Ref, - mutability: Mutability::Shared, - }) - }; - - // Generate: - // ::new_v1_formatted( - // lit_pieces, - // args, - // format_options, - // unsafe { ::core::fmt::UnsafeArg::new() } - // ) - - let lang_items = self.lang_items(); - let new_v1_formatted = self.ty_rel_lang_path( - lang_items.FormatArguments, - Name::new_symbol_root(sym::new_v1_formatted), - ); - let unsafe_arg_new = - self.ty_rel_lang_path(lang_items.FormatUnsafeArg, Name::new_symbol_root(sym::new)); - let new_v1_formatted = - self.alloc_expr_desugared(new_v1_formatted.map_or(Expr::Missing, Expr::Path)); - - let unsafe_arg_new = - self.alloc_expr_desugared(unsafe_arg_new.map_or(Expr::Missing, Expr::Path)); - let unsafe_arg_new = - self.alloc_expr_desugared(Expr::Call { callee: unsafe_arg_new, args: Box::default() }); - let mut unsafe_arg_new = self.alloc_expr_desugared(Expr::Unsafe { - id: None, - statements: Box::new([]), - tail: Some(unsafe_arg_new), - }); - if !fmt.orphans.is_empty() { - unsafe_arg_new = self.alloc_expr_desugared(Expr::Block { - id: None, - // We collect the unused expressions here so that we still infer them instead of - // dropping them out of the expression tree. We cannot store them in the `Unsafe` - // block because then unsafe blocks within them will get a false "unused unsafe" - // diagnostic (rustc has a notion of builtin unsafe blocks, but we don't). - statements: fmt - .orphans - .into_iter() - .map(|expr| Statement::Expr { expr, has_semi: true }) - .collect(), - tail: Some(unsafe_arg_new), - label: None, - }); - } - - self.alloc_expr( - Expr::Call { - callee: new_v1_formatted, - args: Box::new([lit_pieces, args, format_options, unsafe_arg_new]), - }, - syntax_ptr, - ) - } - - /// `format_args!` expansion implementation for rustc versions >= `1.89.0`, - /// especially since [this PR](https://github.com/rust-lang/rust/pull/140748) - fn collect_format_args_impl( - &mut self, - syntax_ptr: AstPtr, - fmt: FormatArgs, - argmap: FxIndexSet<(usize, ArgumentType)>, - lit_pieces: ExprId, - format_options: ExprId, - ) -> ExprId { - let arguments = &*fmt.arguments.arguments; - - let (let_stmts, args) = if arguments.is_empty() { - ( - // Generate: - // [] - vec![], - self.alloc_expr_desugared(Expr::Array(Array::ElementList { - elements: Box::default(), - })), - ) - } else if argmap.len() == 1 && arguments.len() == 1 { - // Only one argument, so we don't need to make the `args` tuple. - // - // Generate: - // super let args = [::new_display(&arg)]; - let args = argmap - .iter() - .map(|&(arg_index, ty)| { - let ref_arg = self.alloc_expr_desugared(Expr::Ref { - expr: arguments[arg_index].expr, - rawness: Rawness::Ref, - mutability: Mutability::Shared, - }); - self.make_argument(ref_arg, ty) - }) - .collect(); - let args = - self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args })); - let args_name = Name::new_symbol_root(sym::args); - let args_binding = self.alloc_binding( - args_name.clone(), - BindingAnnotation::Unannotated, - HygieneId::ROOT, - ); - let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None }); - self.add_definition_to_binding(args_binding, args_pat); - // TODO: We don't have `super let` yet. - let let_stmt = Statement::Let { - pat: args_pat, - type_ref: None, - initializer: Some(args), - else_branch: None, - }; - (vec![let_stmt], self.alloc_expr_desugared(Expr::Path(args_name.into()))) - } else { - // Generate: - // super let args = (&arg0, &arg1, &...); - let args_name = Name::new_symbol_root(sym::args); - let args_binding = self.alloc_binding( - args_name.clone(), - BindingAnnotation::Unannotated, - HygieneId::ROOT, - ); - let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None }); - self.add_definition_to_binding(args_binding, args_pat); - let elements = arguments - .iter() - .map(|arg| { - self.alloc_expr_desugared(Expr::Ref { - expr: arg.expr, - rawness: Rawness::Ref, - mutability: Mutability::Shared, - }) - }) - .collect(); - let args_tuple = self.alloc_expr_desugared(Expr::Tuple { exprs: elements }); - // TODO: We don't have `super let` yet - let let_stmt1 = Statement::Let { - pat: args_pat, - type_ref: None, - initializer: Some(args_tuple), - else_branch: None, - }; - - // Generate: - // super let args = [ - // ::new_display(args.0), - // ::new_lower_hex(args.1), - // ::new_debug(args.0), - // … - // ]; - let args = argmap - .iter() - .map(|&(arg_index, ty)| { - let args_ident_expr = - self.alloc_expr_desugared(Expr::Path(args_name.clone().into())); - let arg = self.alloc_expr_desugared(Expr::Field { - expr: args_ident_expr, - name: Name::new_tuple_field(arg_index), - }); - self.make_argument(arg, ty) - }) - .collect(); - let array = - self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args })); - let args_binding = self.alloc_binding( - args_name.clone(), - BindingAnnotation::Unannotated, - HygieneId::ROOT, - ); - let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None }); - self.add_definition_to_binding(args_binding, args_pat); - let let_stmt2 = Statement::Let { - pat: args_pat, - type_ref: None, - initializer: Some(array), - else_branch: None, - }; - (vec![let_stmt1, let_stmt2], self.alloc_expr_desugared(Expr::Path(args_name.into()))) - }; - - // Generate: - // &args - let args = self.alloc_expr_desugared(Expr::Ref { - expr: args, - rawness: Rawness::Ref, - mutability: Mutability::Shared, - }); - - let call_block = { - // Generate: - // unsafe { - // ::new_v1_formatted( - // lit_pieces, - // args, - // format_options, - // ) - // } - - let new_v1_formatted = self.ty_rel_lang_path( - self.lang_items().FormatArguments, - Name::new_symbol_root(sym::new_v1_formatted), - ); - let new_v1_formatted = - self.alloc_expr_desugared(new_v1_formatted.map_or(Expr::Missing, Expr::Path)); - let args = [lit_pieces, args, format_options]; - let call = self - .alloc_expr_desugared(Expr::Call { callee: new_v1_formatted, args: args.into() }); - - Expr::Unsafe { id: None, statements: Box::default(), tail: Some(call) } - }; - - if !let_stmts.is_empty() { - // Generate: - // { - // super let … - // super let … - // ::new_…(…) - // } - let call = self.alloc_expr_desugared(call_block); - self.alloc_expr( - Expr::Block { - id: None, - statements: let_stmts.into(), - tail: Some(call), - label: None, - }, - syntax_ptr, - ) - } else { - self.alloc_expr(call_block, syntax_ptr) - } - } - - /// Generate a hir expression for a format_args placeholder specification. - /// - /// Generates - /// - /// ```text - /// ::…, // alignment - /// …u32, // flags - /// , // width - /// , // precision - /// ) - /// ``` - fn make_format_spec( - &mut self, - placeholder: &FormatPlaceholder, - argmap: &mut FxIndexSet<(usize, ArgumentType)>, - ) -> ExprId { - let lang_items = self.lang_items(); - let position = match placeholder.argument.index { - Ok(arg_index) => { - let (i, _) = - argmap.insert_full((arg_index, ArgumentType::Format(placeholder.format_trait))); - self.alloc_expr_desugared(Expr::Literal(Literal::Uint( - i as u128, - Some(BuiltinUint::Usize), - ))) - } - Err(_) => self.missing_expr(), - }; - let &FormatOptions { - ref width, - ref precision, - alignment, - fill, - sign, - alternate, - zero_pad, - debug_hex, - } = &placeholder.format_options; - - let precision_expr = self.make_count(precision, argmap); - let width_expr = self.make_count(width, argmap); - - if self.krate.workspace_data(self.db).is_atleast_187() { - // These need to match the constants in library/core/src/fmt/rt.rs. - let align = match alignment { - Some(FormatAlignment::Left) => 0, - Some(FormatAlignment::Right) => 1, - Some(FormatAlignment::Center) => 2, - None => 3, - }; - // This needs to match `Flag` in library/core/src/fmt/rt.rs. - let flags = fill.unwrap_or(' ') as u32 - | ((sign == Some(FormatSign::Plus)) as u32) << 21 - | ((sign == Some(FormatSign::Minus)) as u32) << 22 - | (alternate as u32) << 23 - | (zero_pad as u32) << 24 - | ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 25 - | ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 26 - | (width.is_some() as u32) << 27 - | (precision.is_some() as u32) << 28 - | align << 29 - | 1 << 31; // Highest bit always set. - let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( - flags as u128, - Some(BuiltinUint::U32), - ))); - - let position = - RecordLitField { name: Name::new_symbol_root(sym::position), expr: position }; - let flags = RecordLitField { name: Name::new_symbol_root(sym::flags), expr: flags }; - let precision = RecordLitField { - name: Name::new_symbol_root(sym::precision), - expr: precision_expr, - }; - let width = - RecordLitField { name: Name::new_symbol_root(sym::width), expr: width_expr }; - self.alloc_expr_desugared(Expr::RecordLit { - path: self.lang_path(lang_items.FormatPlaceholder).map(Box::new), - fields: Box::new([position, flags, precision, width]), - spread: None, - }) - } else { - let format_placeholder_new = { - let format_placeholder_new = self.ty_rel_lang_path( - lang_items.FormatPlaceholder, - Name::new_symbol_root(sym::new), - ); - match format_placeholder_new { - Some(path) => self.alloc_expr_desugared(Expr::Path(path)), - None => self.missing_expr(), - } - }; - // This needs to match `Flag` in library/core/src/fmt/rt.rs. - let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32) - | (((sign == Some(FormatSign::Minus)) as u32) << 1) - | ((alternate as u32) << 2) - | ((zero_pad as u32) << 3) - | (((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4) - | (((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5); - let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( - flags as u128, - Some(BuiltinUint::U32), - ))); - let fill = self.alloc_expr_desugared(Expr::Literal(Literal::Char(fill.unwrap_or(' ')))); - let align = { - let align = self.ty_rel_lang_path( - lang_items.FormatAlignment, - match alignment { - Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left), - Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right), - Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center), - None => Name::new_symbol_root(sym::Unknown), - }, - ); - match align { - Some(path) => self.alloc_expr_desugared(Expr::Path(path)), - None => self.missing_expr(), - } - }; - self.alloc_expr_desugared(Expr::Call { - callee: format_placeholder_new, - args: Box::new([position, fill, align, flags, precision_expr, width_expr]), - }) - } - } - - /// Generate a hir expression for a format_args Count. - /// - /// Generates: - /// - /// ```text - /// ::Is(…) - /// ``` - /// - /// or - /// - /// ```text - /// ::Param(…) - /// ``` - /// - /// or - /// - /// ```text - /// ::Implied - /// ``` - fn make_count( - &mut self, - count: &Option, - argmap: &mut FxIndexSet<(usize, ArgumentType)>, - ) -> ExprId { - let lang_items = self.lang_items(); - match count { - Some(FormatCount::Literal(n)) => { - let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( - *n as u128, - // FIXME: Change this to Some(BuiltinUint::U16) once we drop support for toolchains < 1.88 - None, - ))); - let count_is = match self - .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Is)) - { - Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)), - None => self.missing_expr(), - }; - self.alloc_expr_desugared(Expr::Call { callee: count_is, args: Box::new([args]) }) - } - Some(FormatCount::Argument(arg)) => { - if let Ok(arg_index) = arg.index { - let (i, _) = argmap.insert_full((arg_index, ArgumentType::Usize)); - - let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( - i as u128, - Some(BuiltinUint::Usize), - ))); - let count_param = match self - .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Param)) - { - Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), - None => self.missing_expr(), - }; - self.alloc_expr_desugared(Expr::Call { - callee: count_param, - args: Box::new([args]), - }) - } else { - // FIXME: This drops arg causing it to potentially not be resolved/type checked - // when typing? - self.missing_expr() - } - } - None => match self - .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Implied)) - { - Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), - None => self.missing_expr(), - }, - } - } - - /// Generate a hir expression representing an argument to a format_args invocation. - /// - /// Generates: - /// - /// ```text - /// ::new_…(arg) - /// ``` - fn make_argument(&mut self, arg: ExprId, ty: ArgumentType) -> ExprId { - use ArgumentType::*; - use FormatTrait::*; - - let new_fn = match self.ty_rel_lang_path( - self.lang_items().FormatArgument, - Name::new_symbol_root(match ty { - Format(Display) => sym::new_display, - Format(Debug) => sym::new_debug, - Format(LowerExp) => sym::new_lower_exp, - Format(UpperExp) => sym::new_upper_exp, - Format(Octal) => sym::new_octal, - Format(Pointer) => sym::new_pointer, - Format(Binary) => sym::new_binary, - Format(LowerHex) => sym::new_lower_hex, - Format(UpperHex) => sym::new_upper_hex, - Usize => sym::from_usize, - }), - ) { - Some(new_fn) => self.alloc_expr_desugared(Expr::Path(new_fn)), - None => self.missing_expr(), - }; - self.alloc_expr_desugared(Expr::Call { callee: new_fn, args: Box::new([arg]) }) - } - - // endregion: format - fn lang_path(&self, lang: Option>) -> Option { Some(Path::LangItem(lang?.into(), None)) } @@ -3424,12 +2747,6 @@ fn comma_follows_token(t: Option) -> bool { .is_some_and(|it| it.kind() == syntax::T![,]) } -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] -enum ArgumentType { - Format(FormatTrait), - Usize, -} - /// This function find the AST fragment that corresponds to an `AssociatedTypeBinding` in the HIR. pub fn hir_assoc_type_binding_to_ast( segment_args: &ast::GenericArgList, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs new file mode 100644 index 000000000000..aa7bf0e4e244 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs @@ -0,0 +1,699 @@ +//! Lowering of `format_args!()`. + +use base_db::FxIndexSet; +use hir_expand::name::{AsName, Name}; +use intern::{Symbol, sym}; +use syntax::{ + AstPtr, AstToken as _, + ast::{self, HasName}, +}; + +use crate::{ + builtin_type::BuiltinUint, + expr_store::{HygieneId, lower::ExprCollector, path::Path}, + hir::{ + Array, BindingAnnotation, Expr, ExprId, Literal, Pat, RecordLitField, Statement, + format_args::{ + self, FormatAlignment, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind, + FormatArgumentsCollector, FormatCount, FormatDebugHex, FormatOptions, + FormatPlaceholder, FormatSign, FormatTrait, + }, + }, + type_ref::{Mutability, Rawness}, +}; + +impl<'db> ExprCollector<'db> { + pub(super) fn collect_format_args( + &mut self, + f: ast::FormatArgsExpr, + syntax_ptr: AstPtr, + ) -> ExprId { + let mut args = FormatArgumentsCollector::default(); + f.args().for_each(|arg| { + args.add(FormatArgument { + kind: match arg.name() { + Some(name) => FormatArgumentKind::Named(name.as_name()), + None => FormatArgumentKind::Normal, + }, + expr: self.collect_expr_opt(arg.expr()), + }); + }); + let template = f.template(); + let fmt_snippet = template.as_ref().and_then(|it| match it { + ast::Expr::Literal(literal) => match literal.kind() { + ast::LiteralKind::String(s) => Some(s.text().to_owned()), + _ => None, + }, + _ => None, + }); + let mut mappings = vec![]; + let (fmt, hygiene) = match template.and_then(|template| { + self.expand_macros_to_string(template.clone()).map(|it| (it, template)) + }) { + Some(((s, is_direct_literal), template)) => { + let call_ctx = self.expander.call_syntax_ctx(); + let hygiene = self.hygiene_id_for(s.syntax().text_range()); + let fmt = format_args::parse( + &s, + fmt_snippet, + args, + is_direct_literal, + |name, range| { + let expr_id = self.alloc_expr_desugared(Expr::Path(Path::from(name))); + if let Some(range) = range { + self.store + .template_map + .get_or_insert_with(Default::default) + .implicit_capture_to_source + .insert( + expr_id, + self.expander.in_file((AstPtr::new(&template), range)), + ); + } + if !hygiene.is_root() { + self.store.ident_hygiene.insert(expr_id.into(), hygiene); + } + expr_id + }, + |name, span| { + if let Some(span) = span { + mappings.push((span, name)) + } + }, + call_ctx, + ); + (fmt, hygiene) + } + None => ( + FormatArgs { + template: Default::default(), + arguments: args.finish(), + orphans: Default::default(), + }, + HygieneId::ROOT, + ), + }; + + // Create a list of all _unique_ (argument, format trait) combinations. + // E.g. "{0} {0:x} {0} {1}" -> [(0, Display), (0, LowerHex), (1, Display)] + let mut argmap = FxIndexSet::default(); + for piece in fmt.template.iter() { + let FormatArgsPiece::Placeholder(placeholder) = piece else { continue }; + if let Ok(index) = placeholder.argument.index { + argmap.insert((index, ArgumentType::Format(placeholder.format_trait))); + } + } + + let lit_pieces = fmt + .template + .iter() + .enumerate() + .filter_map(|(i, piece)| { + match piece { + FormatArgsPiece::Literal(s) => { + Some(self.alloc_expr_desugared(Expr::Literal(Literal::String(s.clone())))) + } + &FormatArgsPiece::Placeholder(_) => { + // Inject empty string before placeholders when not already preceded by a literal piece. + if i == 0 || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_)) + { + Some(self.alloc_expr_desugared(Expr::Literal(Literal::String( + Symbol::empty(), + )))) + } else { + None + } + } + } + }) + .collect(); + let lit_pieces = + self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: lit_pieces })); + let lit_pieces = self.alloc_expr_desugared(Expr::Ref { + expr: lit_pieces, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }); + let format_options = { + // Generate: + // &[format_spec_0, format_spec_1, format_spec_2] + let elements = fmt + .template + .iter() + .filter_map(|piece| { + let FormatArgsPiece::Placeholder(placeholder) = piece else { return None }; + Some(self.make_format_spec(placeholder, &mut argmap)) + }) + .collect(); + let array = self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements })); + self.alloc_expr_desugared(Expr::Ref { + expr: array, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }) + }; + + // Assume that rustc version >= 1.89.0 iff lang item `format_arguments` exists + // but `format_unsafe_arg` does not + let lang_items = self.lang_items(); + let fmt_args = lang_items.FormatArguments; + let fmt_unsafe_arg = lang_items.FormatUnsafeArg; + let use_format_args_since_1_89_0 = fmt_args.is_some() && fmt_unsafe_arg.is_none(); + + let idx = if use_format_args_since_1_89_0 { + self.collect_format_args_impl(syntax_ptr, fmt, argmap, lit_pieces, format_options) + } else { + self.collect_format_args_before_1_89_0_impl( + syntax_ptr, + fmt, + argmap, + lit_pieces, + format_options, + ) + }; + + self.store + .template_map + .get_or_insert_with(Default::default) + .format_args_to_captures + .insert(idx, (hygiene, mappings)); + idx + } + + /// `format_args!` expansion implementation for rustc versions < `1.89.0` + fn collect_format_args_before_1_89_0_impl( + &mut self, + syntax_ptr: AstPtr, + fmt: FormatArgs, + argmap: FxIndexSet<(usize, ArgumentType)>, + lit_pieces: ExprId, + format_options: ExprId, + ) -> ExprId { + let arguments = &*fmt.arguments.arguments; + + let args = if arguments.is_empty() { + let expr = self + .alloc_expr_desugared(Expr::Array(Array::ElementList { elements: Box::default() })); + self.alloc_expr_desugared(Expr::Ref { + expr, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }) + } else { + // Generate: + // &match (&arg0, &arg1, &…) { + // args => [ + // ::new_display(args.0), + // ::new_lower_hex(args.1), + // ::new_debug(args.0), + // … + // ] + // } + let args = argmap + .iter() + .map(|&(arg_index, ty)| { + let arg = self.alloc_expr_desugared(Expr::Ref { + expr: arguments[arg_index].expr, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }); + self.make_argument(arg, ty) + }) + .collect(); + let array = + self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args })); + self.alloc_expr_desugared(Expr::Ref { + expr: array, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }) + }; + + // Generate: + // ::new_v1_formatted( + // lit_pieces, + // args, + // format_options, + // unsafe { ::core::fmt::UnsafeArg::new() } + // ) + + let lang_items = self.lang_items(); + let new_v1_formatted = self.ty_rel_lang_path( + lang_items.FormatArguments, + Name::new_symbol_root(sym::new_v1_formatted), + ); + let unsafe_arg_new = + self.ty_rel_lang_path(lang_items.FormatUnsafeArg, Name::new_symbol_root(sym::new)); + let new_v1_formatted = + self.alloc_expr_desugared(new_v1_formatted.map_or(Expr::Missing, Expr::Path)); + + let unsafe_arg_new = + self.alloc_expr_desugared(unsafe_arg_new.map_or(Expr::Missing, Expr::Path)); + let unsafe_arg_new = + self.alloc_expr_desugared(Expr::Call { callee: unsafe_arg_new, args: Box::default() }); + let mut unsafe_arg_new = self.alloc_expr_desugared(Expr::Unsafe { + id: None, + statements: Box::new([]), + tail: Some(unsafe_arg_new), + }); + if !fmt.orphans.is_empty() { + unsafe_arg_new = self.alloc_expr_desugared(Expr::Block { + id: None, + // We collect the unused expressions here so that we still infer them instead of + // dropping them out of the expression tree. We cannot store them in the `Unsafe` + // block because then unsafe blocks within them will get a false "unused unsafe" + // diagnostic (rustc has a notion of builtin unsafe blocks, but we don't). + statements: fmt + .orphans + .into_iter() + .map(|expr| Statement::Expr { expr, has_semi: true }) + .collect(), + tail: Some(unsafe_arg_new), + label: None, + }); + } + + self.alloc_expr( + Expr::Call { + callee: new_v1_formatted, + args: Box::new([lit_pieces, args, format_options, unsafe_arg_new]), + }, + syntax_ptr, + ) + } + + /// `format_args!` expansion implementation for rustc versions >= `1.89.0`, + /// especially since [this PR](https://github.com/rust-lang/rust/pull/140748) + fn collect_format_args_impl( + &mut self, + syntax_ptr: AstPtr, + fmt: FormatArgs, + argmap: FxIndexSet<(usize, ArgumentType)>, + lit_pieces: ExprId, + format_options: ExprId, + ) -> ExprId { + let arguments = &*fmt.arguments.arguments; + + let (let_stmts, args) = if arguments.is_empty() { + ( + // Generate: + // [] + vec![], + self.alloc_expr_desugared(Expr::Array(Array::ElementList { + elements: Box::default(), + })), + ) + } else if argmap.len() == 1 && arguments.len() == 1 { + // Only one argument, so we don't need to make the `args` tuple. + // + // Generate: + // super let args = [::new_display(&arg)]; + let args = argmap + .iter() + .map(|&(arg_index, ty)| { + let ref_arg = self.alloc_expr_desugared(Expr::Ref { + expr: arguments[arg_index].expr, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }); + self.make_argument(ref_arg, ty) + }) + .collect(); + let args = + self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args })); + let args_name = Name::new_symbol_root(sym::args); + let args_binding = self.alloc_binding( + args_name.clone(), + BindingAnnotation::Unannotated, + HygieneId::ROOT, + ); + let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None }); + self.add_definition_to_binding(args_binding, args_pat); + // TODO: We don't have `super let` yet. + let let_stmt = Statement::Let { + pat: args_pat, + type_ref: None, + initializer: Some(args), + else_branch: None, + }; + (vec![let_stmt], self.alloc_expr_desugared(Expr::Path(args_name.into()))) + } else { + // Generate: + // super let args = (&arg0, &arg1, &...); + let args_name = Name::new_symbol_root(sym::args); + let args_binding = self.alloc_binding( + args_name.clone(), + BindingAnnotation::Unannotated, + HygieneId::ROOT, + ); + let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None }); + self.add_definition_to_binding(args_binding, args_pat); + let elements = arguments + .iter() + .map(|arg| { + self.alloc_expr_desugared(Expr::Ref { + expr: arg.expr, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }) + }) + .collect(); + let args_tuple = self.alloc_expr_desugared(Expr::Tuple { exprs: elements }); + // TODO: We don't have `super let` yet + let let_stmt1 = Statement::Let { + pat: args_pat, + type_ref: None, + initializer: Some(args_tuple), + else_branch: None, + }; + + // Generate: + // super let args = [ + // ::new_display(args.0), + // ::new_lower_hex(args.1), + // ::new_debug(args.0), + // … + // ]; + let args = argmap + .iter() + .map(|&(arg_index, ty)| { + let args_ident_expr = + self.alloc_expr_desugared(Expr::Path(args_name.clone().into())); + let arg = self.alloc_expr_desugared(Expr::Field { + expr: args_ident_expr, + name: Name::new_tuple_field(arg_index), + }); + self.make_argument(arg, ty) + }) + .collect(); + let array = + self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args })); + let args_binding = self.alloc_binding( + args_name.clone(), + BindingAnnotation::Unannotated, + HygieneId::ROOT, + ); + let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None }); + self.add_definition_to_binding(args_binding, args_pat); + let let_stmt2 = Statement::Let { + pat: args_pat, + type_ref: None, + initializer: Some(array), + else_branch: None, + }; + (vec![let_stmt1, let_stmt2], self.alloc_expr_desugared(Expr::Path(args_name.into()))) + }; + + // Generate: + // &args + let args = self.alloc_expr_desugared(Expr::Ref { + expr: args, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }); + + let call_block = { + // Generate: + // unsafe { + // ::new_v1_formatted( + // lit_pieces, + // args, + // format_options, + // ) + // } + + let new_v1_formatted = self.ty_rel_lang_path( + self.lang_items().FormatArguments, + Name::new_symbol_root(sym::new_v1_formatted), + ); + let new_v1_formatted = + self.alloc_expr_desugared(new_v1_formatted.map_or(Expr::Missing, Expr::Path)); + let args = [lit_pieces, args, format_options]; + let call = self + .alloc_expr_desugared(Expr::Call { callee: new_v1_formatted, args: args.into() }); + + Expr::Unsafe { id: None, statements: Box::default(), tail: Some(call) } + }; + + if !let_stmts.is_empty() { + // Generate: + // { + // super let … + // super let … + // ::new_…(…) + // } + let call = self.alloc_expr_desugared(call_block); + self.alloc_expr( + Expr::Block { + id: None, + statements: let_stmts.into(), + tail: Some(call), + label: None, + }, + syntax_ptr, + ) + } else { + self.alloc_expr(call_block, syntax_ptr) + } + } + + /// Generate a hir expression for a format_args placeholder specification. + /// + /// Generates + /// + /// ```text + /// ::…, // alignment + /// …u32, // flags + /// , // width + /// , // precision + /// ) + /// ``` + fn make_format_spec( + &mut self, + placeholder: &FormatPlaceholder, + argmap: &mut FxIndexSet<(usize, ArgumentType)>, + ) -> ExprId { + let lang_items = self.lang_items(); + let position = match placeholder.argument.index { + Ok(arg_index) => { + let (i, _) = + argmap.insert_full((arg_index, ArgumentType::Format(placeholder.format_trait))); + self.alloc_expr_desugared(Expr::Literal(Literal::Uint( + i as u128, + Some(BuiltinUint::Usize), + ))) + } + Err(_) => self.missing_expr(), + }; + let &FormatOptions { + ref width, + ref precision, + alignment, + fill, + sign, + alternate, + zero_pad, + debug_hex, + } = &placeholder.format_options; + + let precision_expr = self.make_count(precision, argmap); + let width_expr = self.make_count(width, argmap); + + if self.krate.workspace_data(self.db).is_atleast_187() { + // These need to match the constants in library/core/src/fmt/rt.rs. + let align = match alignment { + Some(FormatAlignment::Left) => 0, + Some(FormatAlignment::Right) => 1, + Some(FormatAlignment::Center) => 2, + None => 3, + }; + // This needs to match `Flag` in library/core/src/fmt/rt.rs. + let flags = fill.unwrap_or(' ') as u32 + | ((sign == Some(FormatSign::Plus)) as u32) << 21 + | ((sign == Some(FormatSign::Minus)) as u32) << 22 + | (alternate as u32) << 23 + | (zero_pad as u32) << 24 + | ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 25 + | ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 26 + | (width.is_some() as u32) << 27 + | (precision.is_some() as u32) << 28 + | align << 29 + | 1 << 31; // Highest bit always set. + let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( + flags as u128, + Some(BuiltinUint::U32), + ))); + + let position = + RecordLitField { name: Name::new_symbol_root(sym::position), expr: position }; + let flags = RecordLitField { name: Name::new_symbol_root(sym::flags), expr: flags }; + let precision = RecordLitField { + name: Name::new_symbol_root(sym::precision), + expr: precision_expr, + }; + let width = + RecordLitField { name: Name::new_symbol_root(sym::width), expr: width_expr }; + self.alloc_expr_desugared(Expr::RecordLit { + path: self.lang_path(lang_items.FormatPlaceholder).map(Box::new), + fields: Box::new([position, flags, precision, width]), + spread: None, + }) + } else { + let format_placeholder_new = { + let format_placeholder_new = self.ty_rel_lang_path( + lang_items.FormatPlaceholder, + Name::new_symbol_root(sym::new), + ); + match format_placeholder_new { + Some(path) => self.alloc_expr_desugared(Expr::Path(path)), + None => self.missing_expr(), + } + }; + // This needs to match `Flag` in library/core/src/fmt/rt.rs. + let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32) + | (((sign == Some(FormatSign::Minus)) as u32) << 1) + | ((alternate as u32) << 2) + | ((zero_pad as u32) << 3) + | (((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4) + | (((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5); + let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( + flags as u128, + Some(BuiltinUint::U32), + ))); + let fill = self.alloc_expr_desugared(Expr::Literal(Literal::Char(fill.unwrap_or(' ')))); + let align = { + let align = self.ty_rel_lang_path( + lang_items.FormatAlignment, + match alignment { + Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left), + Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right), + Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center), + None => Name::new_symbol_root(sym::Unknown), + }, + ); + match align { + Some(path) => self.alloc_expr_desugared(Expr::Path(path)), + None => self.missing_expr(), + } + }; + self.alloc_expr_desugared(Expr::Call { + callee: format_placeholder_new, + args: Box::new([position, fill, align, flags, precision_expr, width_expr]), + }) + } + } + + /// Generate a hir expression for a format_args Count. + /// + /// Generates: + /// + /// ```text + /// ::Is(…) + /// ``` + /// + /// or + /// + /// ```text + /// ::Param(…) + /// ``` + /// + /// or + /// + /// ```text + /// ::Implied + /// ``` + fn make_count( + &mut self, + count: &Option, + argmap: &mut FxIndexSet<(usize, ArgumentType)>, + ) -> ExprId { + let lang_items = self.lang_items(); + match count { + Some(FormatCount::Literal(n)) => { + let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( + *n as u128, + // FIXME: Change this to Some(BuiltinUint::U16) once we drop support for toolchains < 1.88 + None, + ))); + let count_is = match self + .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Is)) + { + Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)), + None => self.missing_expr(), + }; + self.alloc_expr_desugared(Expr::Call { callee: count_is, args: Box::new([args]) }) + } + Some(FormatCount::Argument(arg)) => { + if let Ok(arg_index) = arg.index { + let (i, _) = argmap.insert_full((arg_index, ArgumentType::Usize)); + + let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint( + i as u128, + Some(BuiltinUint::Usize), + ))); + let count_param = match self + .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Param)) + { + Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), + None => self.missing_expr(), + }; + self.alloc_expr_desugared(Expr::Call { + callee: count_param, + args: Box::new([args]), + }) + } else { + // FIXME: This drops arg causing it to potentially not be resolved/type checked + // when typing? + self.missing_expr() + } + } + None => match self + .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Implied)) + { + Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), + None => self.missing_expr(), + }, + } + } + + /// Generate a hir expression representing an argument to a format_args invocation. + /// + /// Generates: + /// + /// ```text + /// ::new_…(arg) + /// ``` + fn make_argument(&mut self, arg: ExprId, ty: ArgumentType) -> ExprId { + use ArgumentType::*; + use FormatTrait::*; + + let new_fn = match self.ty_rel_lang_path( + self.lang_items().FormatArgument, + Name::new_symbol_root(match ty { + Format(Display) => sym::new_display, + Format(Debug) => sym::new_debug, + Format(LowerExp) => sym::new_lower_exp, + Format(UpperExp) => sym::new_upper_exp, + Format(Octal) => sym::new_octal, + Format(Pointer) => sym::new_pointer, + Format(Binary) => sym::new_binary, + Format(LowerHex) => sym::new_lower_hex, + Format(UpperHex) => sym::new_upper_hex, + Usize => sym::from_usize, + }), + ) { + Some(new_fn) => self.alloc_expr_desugared(Expr::Path(new_fn)), + None => self.missing_expr(), + }; + self.alloc_expr_desugared(Expr::Call { callee: new_fn, args: Box::new([arg]) }) + } +} + +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +enum ArgumentType { + Format(FormatTrait), + Usize, +} From 0eed5ab5503df59f07cc149223a3e368e334f502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 10 Dec 2025 12:41:56 +0100 Subject: [PATCH 0539/3801] introduce fcw macro --- compiler/rustc_lint/src/builtin.rs | 14 +- compiler/rustc_lint/src/if_let_rescope.rs | 6 +- .../rustc_lint/src/impl_trait_overcaptures.rs | 6 +- ..._expr_fragment_specifier_2024_migration.rs | 5 +- compiler/rustc_lint/src/non_fmt_panic.rs | 5 +- compiler/rustc_lint/src/shadowed_into_iter.rs | 9 +- compiler/rustc_lint/src/static_mut_refs.rs | 6 +- compiler/rustc_lint_defs/src/builtin.rs | 148 ++++++------------ compiler/rustc_lint_defs/src/lib.rs | 146 ++++++++++++++--- .../rustc-dev-guide/src/bug-fix-procedure.md | 4 +- src/doc/rustc-dev-guide/src/diagnostics.md | 3 +- .../rustc-dev-guide/src/guides/editions.md | 3 +- 12 files changed, 197 insertions(+), 158 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index dd0aa848ed2c..7546d3948a8f 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -35,9 +35,9 @@ use rustc_middle::lint::LevelAndSource; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, AssocContainer, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef}; -use rustc_session::lint::FutureIncompatibilityReason; // hardwired lints from rustc_lint_defs pub use rustc_session::lint::builtin::*; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; @@ -777,8 +777,7 @@ declare_lint! { Warn, "detects anonymous parameters", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #41686 ", + reason: fcw!(EditionError 2018 "trait-fn-parameters"), }; } @@ -1664,8 +1663,7 @@ declare_lint! { Warn, "`...` range patterns are deprecated", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "warnings-promoted-to-error"), }; } @@ -1800,8 +1798,7 @@ declare_lint! { Allow, "detects edition keywords being used as an identifier", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #49716 ", + reason: fcw!(EditionError 2018 "new-keywords"), }; } @@ -1845,8 +1842,7 @@ declare_lint! { Allow, "detects edition keywords being used as an identifier", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "gen-keyword"), }; } diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 2521c2b4eb6a..612d542a27de 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -11,9 +11,8 @@ use rustc_middle::ty::significant_drop_order::{ extract_component_with_significant_dtor, ty_dtor_span, }; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_session::lint::{FutureIncompatibilityReason, LintId}; +use rustc_session::lint::{LintId, fcw}; use rustc_session::{declare_lint, impl_lint_pass}; -use rustc_span::edition::Edition; use rustc_span::{DUMMY_SP, Span}; use smallvec::SmallVec; @@ -86,8 +85,7 @@ declare_lint! { "`if let` assigns a shorter lifetime to temporary values being pattern-matched against in Edition 2024 and \ rewriting in `match` is an option to preserve the semantics up to Edition 2021", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionSemanticsChange 2024 "temporary-if-let-scope"), }; } diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index f54afce0615f..2fc9d562dc56 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -19,9 +19,8 @@ use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_middle::{bug, span_bug}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::edition::Edition; use rustc_span::{Span, Symbol}; use rustc_trait_selection::errors::{ AddPreciseCapturingForOvercapture, impl_trait_overcapture_suggestion, @@ -71,8 +70,7 @@ declare_lint! { Allow, "`impl Trait` will capture more lifetimes than possibly intended in edition 2024", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionSemanticsChange 2024 "rpit-lifetime-capture"), }; } diff --git a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs index 7de6fbd941b4..f20605c91495 100644 --- a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs +++ b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs @@ -2,7 +2,7 @@ use rustc_ast::token::{Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::edition::Edition; use rustc_span::sym; @@ -72,8 +72,7 @@ declare_lint! { "The `expr` fragment specifier will accept more expressions in the 2024 edition. \ To keep the existing behavior, use the `expr_2021` fragment specifier.", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "Migration Guide ", + reason: fcw!(EditionSemanticsChange 2024 "macro-fragment-specifiers"), }; } diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 2eabeeaa88f9..f6295698b281 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -4,9 +4,8 @@ use rustc_hir::{self as hir, LangItem}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::{bug, ty}; use rustc_parse_format::{ParseMode, Parser, Piece}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::edition::Edition; use rustc_span::{InnerSpan, Span, Symbol, hygiene, sym}; use rustc_trait_selection::infer::InferCtxtExt; @@ -38,7 +37,7 @@ declare_lint! { Warn, "detect single-argument panic!() invocations in which the argument is not a format string", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021), + reason: fcw!(EditionSemanticsChange 2021 "panic-macro-consistency"), explain_reason: false, }; report_in_external_macro diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index cfb2a7fb6186..05bb2113db09 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -1,8 +1,7 @@ use rustc_hir::{self as hir, LangItem}; use rustc_middle::ty::{self, Ty}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, impl_lint_pass}; -use rustc_span::edition::Edition; use crate::lints::{ShadowedIntoIterDiag, ShadowedIntoIterDiagSub}; use crate::{LateContext, LateLintPass, LintContext}; @@ -31,8 +30,7 @@ declare_lint! { Warn, "detects calling `into_iter` on arrays in Rust 2015 and 2018", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021), - reference: "", + reason: fcw!(EditionSemanticsChange 2021 "IntoIterator-for-arrays"), }; } @@ -60,8 +58,7 @@ declare_lint! { Warn, "detects calling `into_iter` on boxed slices in Rust 2015, 2018, and 2021", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "" + reason: fcw!(EditionSemanticsChange 2024 "intoiterator-box-slice"), }; } diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 1c0df1f4234a..1decb4b78e61 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -1,9 +1,8 @@ use rustc_hir as hir; use rustc_hir::{Expr, Stmt}; use rustc_middle::ty::{Mutability, TyKind}; -use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::edition::Edition; use rustc_span::{BytePos, Span}; use crate::lints::{MutRefSugg, RefOfMutStatic}; @@ -53,8 +52,7 @@ declare_lint! { Warn, "creating a shared reference to mutable static", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "static-mut-references"), explain_reason: false, }; @edition Edition2024 => Deny; diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 740530daf2bd..baecc14424ec 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -7,9 +7,7 @@ //! When removing a lint, make sure to also add a call to `register_removed` in //! compiler/rustc_lint/src/lib.rs. -use rustc_span::edition::Edition; - -use crate::{FutureIncompatibilityReason, declare_lint, declare_lint_pass}; +use crate::{declare_lint, declare_lint_pass, fcw}; declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s @@ -182,8 +180,7 @@ declare_lint! { Warn, "applying forbid to lint-groups", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #81670 ", + reason: fcw!(FutureReleaseError #81670), report_in_deps: true, }; } @@ -219,8 +216,7 @@ declare_lint! { Deny, "ill-formed attribute inputs that were previously accepted and used in practice", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #57571 ", + reason: fcw!(FutureReleaseError #57571), report_in_deps: true, }; crate_level_only @@ -257,8 +253,7 @@ declare_lint! { Deny, "conflicts between `#[repr(..)]` hints that were previously accepted and used in practice", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #68585 ", + reason: fcw!(FutureReleaseError #68585), report_in_deps: true, }; } @@ -1267,8 +1262,7 @@ declare_lint! { Deny, "detect public re-exports of private extern crates", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #127909 ", + reason: fcw!(FutureReleaseError #127909), report_in_deps: true, }; } @@ -1298,8 +1292,7 @@ declare_lint! { Deny, "type parameter default erroneously allowed in invalid location", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #36887 ", + reason: fcw!(FutureReleaseError #36887), report_in_deps: true, }; } @@ -1438,8 +1431,7 @@ declare_lint! { Deny, "patterns in functions without body were erroneously allowed", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #35203 ", + reason: fcw!(FutureReleaseError #35203), }; } @@ -1480,8 +1472,7 @@ declare_lint! { Warn, "detects generic lifetime arguments in path segments with late bound lifetime parameters", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #42868 ", + reason: fcw!(FutureReleaseError #42868), }; } @@ -1520,8 +1511,7 @@ declare_lint! { Warn, "distinct impls distinguished only by the leak-check code", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::Custom("the behavior may change in a future release"), - reference: "issue #56105 ", + reason: fcw!("the behavior may change in a future release" #56105), }; } @@ -1624,8 +1614,7 @@ declare_lint! { Allow, "detects patterns whose meaning will change in Rust 2024", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionSemanticsChange 2024 "match-ergonomics"), }; } @@ -1772,8 +1761,7 @@ declare_lint! { Warn, "raw pointer to an inference variable", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #46906 ", + reason: fcw!(EditionError 2018 "tyvar-behind-raw-pointer"), }; } @@ -1839,8 +1827,7 @@ declare_lint! { Warn, "suggest using `dyn Trait` for trait objects", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "warnings-promoted-to-error"), }; } @@ -1894,8 +1881,7 @@ declare_lint! { "fully qualified paths that start with a module name \ instead of `crate`, `self`, or an extern crate name", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #53130 ", + reason: fcw!(EditionError 2018 "path-changes"), }; } @@ -1942,11 +1928,11 @@ declare_lint! { Warn, "detects name collision with an existing but unstable method", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::Custom( + reason: fcw!( "once this associated item is added to the standard library, \ the ambiguity may cause an error or change in behavior!" + #48919 ), - reference: "issue #48919 ", // Note: this item represents future incompatibility of all unstable functions in the // standard library, and thus should never be removed or changed to an error. }; @@ -2075,8 +2061,7 @@ declare_lint! { Deny, "detects proc macro derives using inaccessible names from parent modules", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #83583 ", + reason: fcw!(FutureReleaseError #83583), report_in_deps: true, }; } @@ -2179,8 +2164,7 @@ declare_lint! { "macro-expanded `macro_export` macros from the current crate \ cannot be referred to by absolute paths", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #52234 ", + reason: fcw!(FutureReleaseError #52234), report_in_deps: true, }; crate_level_only @@ -2301,8 +2285,7 @@ declare_lint! { Deny, "ambiguous associated items", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #57644 ", + reason: fcw!(FutureReleaseError #57644), }; } @@ -2317,8 +2300,7 @@ declare_lint! { Deny, "a feature gate that doesn't break dependent crates", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #64266 ", + reason: fcw!(FutureReleaseError #64266), report_in_deps: true, }; } @@ -2529,8 +2511,7 @@ declare_lint! { Allow, "unsafe operations in unsafe functions without an explicit unsafe block are deprecated", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "unsafe-op-in-unsafe-fn"), explain_reason: false }; @edition Edition2024 => Warn; @@ -2661,8 +2642,7 @@ declare_lint! { Warn, "detects a generic constant is used in a type without a emitting a warning", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #76200 ", + reason: fcw!(FutureReleaseError #76200), }; } @@ -2720,8 +2700,7 @@ declare_lint! { Warn, "uninhabited static", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #74840 ", + reason: fcw!(FutureReleaseError #74840), }; } @@ -2853,8 +2832,7 @@ declare_lint! { Warn, "detect unsupported use of `Self` from outer item", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #124186 ", + reason: fcw!(FutureReleaseError #124186), }; } @@ -2899,8 +2877,7 @@ declare_lint! { Deny, "trailing semicolon in macro body used as expression", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #79813 ", + reason: fcw!(FutureReleaseError #79813), report_in_deps: true, }; } @@ -2947,8 +2924,7 @@ declare_lint! { Deny, "detects derive helper attributes that are used before they are introduced", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #79202 ", + reason: fcw!(FutureReleaseError #79202), report_in_deps: true, }; } @@ -3131,8 +3107,7 @@ declare_lint! { Deny, "transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #78586 ", + reason: fcw!(FutureReleaseError #78586), report_in_deps: true, }; } @@ -3183,8 +3158,7 @@ declare_lint! { Warn, "unstable syntax can change at any point in the future, causing a hard error!", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #65860 ", + reason: fcw!(FutureReleaseError #65860), }; } @@ -3425,7 +3399,7 @@ declare_lint! { Allow, "detects closures affected by Rust 2021 changes", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021), + reason: fcw!(EditionSemanticsChange 2021 "disjoint-capture-in-closures"), explain_reason: false, }; } @@ -3520,8 +3494,7 @@ declare_lint! { Allow, "detects usage of old versions of or-patterns", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "or-patterns-macro-rules"), }; } @@ -3569,8 +3542,7 @@ declare_lint! { "detects the usage of trait methods which are ambiguous with traits added to the \ prelude in future editions", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "prelude"), }; } @@ -3609,8 +3581,7 @@ declare_lint! { "detects the usage of trait methods which are ambiguous with traits added to the \ prelude in future editions", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "prelude"), }; } @@ -3646,8 +3617,7 @@ declare_lint! { Allow, "identifiers that will be parsed as a prefix in Rust 2021", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021), - reference: "", + reason: fcw!(EditionError 2021 "reserving-syntax"), }; crate_level_only } @@ -3694,9 +3664,8 @@ declare_lint! { Warn, "use of unsupported calling convention", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, + reason: fcw!(FutureReleaseError #137018), report_in_deps: false, - reference: "issue #137018 ", }; } @@ -3739,8 +3708,7 @@ declare_lint! { Warn, "use of unsupported calling convention for function pointer", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #130260 ", + reason: fcw!(FutureReleaseError #130260), report_in_deps: true, }; } @@ -4174,8 +4142,7 @@ declare_lint! { Deny, "never type fallback affecting unsafe function calls", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionAndFutureReleaseSemanticsChange 2024 "never-type-fallback"), report_in_deps: true, }; @edition Edition2024 => Deny; @@ -4229,8 +4196,7 @@ declare_lint! { Deny, "never type fallback affecting unsafe function calls", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionAndFutureReleaseError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionAndFutureReleaseError 2024 "never-type-fallback"), report_in_deps: true, }; report_in_external_macro @@ -4265,8 +4231,7 @@ declare_lint! { Deny, "\"invalid_parameter\" isn't a valid argument for `#[macro_export]`", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #57571 ", + reason: fcw!(FutureReleaseError #57571), report_in_deps: true, }; } @@ -4503,8 +4468,7 @@ declare_lint! { Deny, "detects certain glob imports that require reporting an ambiguity error", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #114095 ", + reason: fcw!(FutureReleaseError #114095), report_in_deps: true, }; } @@ -4659,8 +4623,7 @@ declare_lint! { Deny, "elided lifetimes cannot be used in associated constants in impls", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #115010 ", + reason: fcw!(FutureReleaseError #115010), }; } @@ -4706,8 +4669,7 @@ declare_lint! { Deny, "detects certain macro bindings that should not be re-exported", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #120192 ", + reason: fcw!(FutureReleaseError #120192), report_in_deps: true, }; } @@ -4772,8 +4734,7 @@ declare_lint! { Warn, "impl contains type parameters that are not covered", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #124559 ", + reason: fcw!(FutureReleaseError #124559), }; } @@ -4820,8 +4781,7 @@ declare_lint! { Allow, "detects unsafe functions being used as safe functions", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "newly-unsafe-functions"), }; } @@ -4856,8 +4816,7 @@ declare_lint! { Allow, "detects missing unsafe keyword on extern declarations", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "unsafe-extern"), }; } @@ -4897,8 +4856,7 @@ declare_lint! { Allow, "detects unsafe attributes outside of unsafe", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "unsafe-attributes"), }; } @@ -4936,8 +4894,7 @@ declare_lint! { Deny, "detects out of scope calls to `macro_rules` in key-value attributes", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #124535 ", + reason: fcw!(FutureReleaseError #124535), report_in_deps: true, }; } @@ -5099,8 +5056,7 @@ declare_lint! { Allow, "Detect and warn on significant change in drop order in tail expression location", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), - reference: "", + reason: fcw!(EditionSemanticsChange 2024 "temporary-tail-expr-scope"), }; } @@ -5138,8 +5094,7 @@ declare_lint! { Allow, "will be parsed as a guarded string in Rust 2024", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), - reference: "", + reason: fcw!(EditionError 2024 "reserved-syntax"), }; crate_level_only } @@ -5180,8 +5135,7 @@ declare_lint! { Warn, "detects code that could be affected by ABI issues on aarch64 softfloat targets", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #134375 ", + reason: fcw!(FutureReleaseError #134375), report_in_deps: true, }; } @@ -5316,8 +5270,7 @@ declare_lint! { Warn, "repr(C) enums with discriminant values that do not fit into a C int", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #124403 ", + reason: fcw!(FutureReleaseError #124403), report_in_deps: false, }; } @@ -5363,8 +5316,7 @@ declare_lint! { Warn, "detects usage of `...` arguments without a pattern in non-foreign items", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseError, - reference: "issue #145544 ", + reason: fcw!(FutureReleaseError #145544), report_in_deps: false, }; } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 376310838cc7..1efb8355ca93 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::fmt::Display; use rustc_ast::AttrId; use rustc_ast::attr::AttributeExt; @@ -356,8 +357,6 @@ pub struct Lint { /// Extra information for a future incompatibility lint. #[derive(Copy, Clone, Debug)] pub struct FutureIncompatibleInfo { - /// e.g., a URL for an issue/PR/RFC or error code - pub reference: &'static str, /// The reason for the lint used by diagnostics to provide /// the right help message pub reason: FutureIncompatibilityReason, @@ -380,6 +379,17 @@ pub struct FutureIncompatibleInfo { pub report_in_deps: bool, } +#[derive(Copy, Clone, Debug)] +pub struct EditionFcw { + pub edition: Edition, + pub page_slug: &'static str, +} + +#[derive(Copy, Clone, Debug)] +pub struct ReleaseFcw { + pub issue_number: usize, +} + /// The reason for future incompatibility /// /// Future-incompatible lints come in roughly two categories: @@ -409,14 +419,14 @@ pub enum FutureIncompatibilityReason { /// hard errors (and the lint removed). Preferably when there is some /// confidence that the number of impacted projects is very small (few /// should have a broken dependency in their dependency tree). - FutureReleaseError, + FutureReleaseError(ReleaseFcw), /// Code that changes meaning in some way in a /// future release. /// /// Choose this variant when the semantics of existing code is changing, /// (as opposed to [`FutureIncompatibilityReason::FutureReleaseError`], /// which is for when code is going to be rejected in the future). - FutureReleaseSemanticsChange, + FutureReleaseSemanticsChange(ReleaseFcw), /// Previously accepted code that will become an /// error in the provided edition /// @@ -437,7 +447,7 @@ pub enum FutureIncompatibilityReason { /// See also [`FutureIncompatibilityReason::EditionSemanticsChange`] if /// you have code that is changing semantics across the edition (as /// opposed to being rejected). - EditionError(Edition), + EditionError(EditionFcw), /// Code that changes meaning in some way in /// the provided edition /// @@ -445,7 +455,7 @@ pub enum FutureIncompatibilityReason { /// except for situations where the semantics change across an edition. It /// slightly changes the text of the diagnostic, but is otherwise the /// same. - EditionSemanticsChange(Edition), + EditionSemanticsChange(EditionFcw), /// This will be an error in the provided edition *and* in a future /// release. /// @@ -455,7 +465,7 @@ pub enum FutureIncompatibilityReason { /// /// [`EditionError`]: FutureIncompatibilityReason::EditionError /// [`FutureReleaseError`]: FutureIncompatibilityReason::FutureReleaseError - EditionAndFutureReleaseError(Edition), + EditionAndFutureReleaseError(EditionFcw), /// This will change meaning in the provided edition *and* in a future /// release. /// @@ -466,14 +476,29 @@ pub enum FutureIncompatibilityReason { /// /// [`EditionSemanticsChange`]: FutureIncompatibilityReason::EditionSemanticsChange /// [`FutureReleaseSemanticsChange`]: FutureIncompatibilityReason::FutureReleaseSemanticsChange - EditionAndFutureReleaseSemanticsChange(Edition), + EditionAndFutureReleaseSemanticsChange(EditionFcw), /// A custom reason. /// /// Choose this variant if the built-in text of the diagnostic of the /// other variants doesn't match your situation. This is behaviorally /// equivalent to /// [`FutureIncompatibilityReason::FutureReleaseError`]. - Custom(&'static str), + Custom(&'static str, ReleaseFcw), + + /// Using the declare_lint macro a reason always needs to be specified. + /// So, this case can't actually be reached but a variant needs to exist for it. + /// Any code panics on seeing this varaint. Do not use. + Unreachable, +} + +impl FutureIncompatibleInfo { + pub const fn default_fields_for_macro() -> Self { + FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::Unreachable, + explain_reason: true, + report_in_deps: false, + } + } } impl FutureIncompatibilityReason { @@ -482,23 +507,52 @@ impl FutureIncompatibilityReason { Self::EditionError(e) | Self::EditionSemanticsChange(e) | Self::EditionAndFutureReleaseError(e) - | Self::EditionAndFutureReleaseSemanticsChange(e) => Some(e), + | Self::EditionAndFutureReleaseSemanticsChange(e) => Some(e.edition), - FutureIncompatibilityReason::FutureReleaseError - | FutureIncompatibilityReason::FutureReleaseSemanticsChange - | FutureIncompatibilityReason::Custom(_) => None, + FutureIncompatibilityReason::FutureReleaseError(_) + | FutureIncompatibilityReason::FutureReleaseSemanticsChange(_) + | FutureIncompatibilityReason::Custom(_, _) => None, + Self::Unreachable => unreachable!(), + } + } + + fn fmt_reason(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::FutureReleaseSemanticsChange(release_fcw) + | Self::FutureReleaseError(release_fcw) + | Self::Custom(_, release_fcw) => release_fcw.fmt_reason(f), + Self::EditionError(edition_fcw) + | Self::EditionSemanticsChange(edition_fcw) + | Self::EditionAndFutureReleaseError(edition_fcw) + | Self::EditionAndFutureReleaseSemanticsChange(edition_fcw) => { + edition_fcw.fmt_reason(f) + } + Self::Unreachable => unreachable!(), } } } -impl FutureIncompatibleInfo { - pub const fn default_fields_for_macro() -> Self { - FutureIncompatibleInfo { - reference: "", - reason: FutureIncompatibilityReason::FutureReleaseError, - explain_reason: true, - report_in_deps: false, - } +impl ReleaseFcw { + fn fmt_reason(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let issue_number = self.issue_number; + write!(f, "issue #{issue_number} ") + } +} + +impl EditionFcw { + fn fmt_reason(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "", + match self.edition { + Edition::Edition2015 => "rust-2015", + Edition::Edition2018 => "rust-2018", + Edition::Edition2021 => "rust-2021", + Edition::Edition2024 => "rust-2024", + Edition::EditionFuture => "future", + }, + self.page_slug, + ) } } @@ -901,3 +955,53 @@ macro_rules! declare_lint_pass { $crate::impl_lint_pass!($name => [$($lint),*]); }; } + +#[macro_export] +macro_rules! fcw { + (FutureReleaseError # $issue_number: literal) => { + $crate:: FutureIncompatibilityReason::FutureReleaseError($crate::ReleaseFcw { issue_number: $issue_number }) + }; + (FutureReleaseSemanticsChange # $issue_number: literal) => { + $crate::FutureIncompatibilityReason::FutureReleaseSemanticsChange($crate::ReleaseFcw { + issue_number: $issue_number, + }) + }; + ($description: literal # $issue_number: literal) => { + $crate::FutureIncompatibilityReason::Custom($description, $crate::ReleaseFcw { + issue_number: $issue_number, + }) + }; + (EditionError $edition_name: tt $page_slug: literal) => { + $crate::FutureIncompatibilityReason::EditionError($crate::EditionFcw { + edition: fcw!(@edition $edition_name), + page_slug: $page_slug, + }) + }; + (EditionSemanticsChange $edition_name: tt $page_slug: literal) => { + $crate::FutureIncompatibilityReason::EditionSemanticsChange($crate::EditionFcw { + edition: fcw!(@edition $edition_name), + page_slug: $page_slug, + }) + }; + (EditionAndFutureReleaseSemanticsChange $edition_name: tt $page_slug: literal) => { + $crate::FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange($crate::EditionFcw { + edition: fcw!(@edition $edition_name), + page_slug: $page_slug, + }) + }; + (EditionAndFutureReleaseError $edition_name: tt $page_slug: literal) => { + $crate::FutureIncompatibilityReason::EditionAndFutureReleaseError($crate::EditionFcw { + edition: fcw!(@edition $edition_name), + page_slug: $page_slug, + }) + }; + (@edition 2024) => { + rustc_span::edition::Edition::Edition2024 + }; + (@edition 2021) => { + rustc_span::edition::Edition::Edition2021 + }; + (@edition 2018) => { + rustc_span::edition::Edition::Edition2018 + }; +} diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md index 6b13c97023f5..92488e8daeab 100644 --- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md +++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md @@ -113,7 +113,7 @@ store.register_future_incompatible(sess, vec![ ..., FutureIncompatibleInfo { id: LintId::of(YOUR_ERROR_HERE), - reference: "issue #1234", // your tracking issue here! + reason: fcw!(FutureReleaseError #1234) // your tracking issue here! }, ]); @@ -238,7 +238,7 @@ compatibility lint": ```rust FutureIncompatibleInfo { id: LintId::of(OVERLAPPING_INHERENT_IMPLS), - reference: "issue #36889 ", + reason: fcw!(FutureReleaseError #1234), // your tracking issue here! }, ``` diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index 82191e0a6eaf..89c18b8e40f1 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -732,8 +732,7 @@ declare_lint! { Allow, "detects anonymous parameters", @future_incompatible = FutureIncompatibleInfo { - reference: "issue #41686 ", - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), + reason: fcw!(EditionError 2018 "slug-of-edition-guide-page") }; } ``` diff --git a/src/doc/rustc-dev-guide/src/guides/editions.md b/src/doc/rustc-dev-guide/src/guides/editions.md index 107d5e737e83..535d82f8403b 100644 --- a/src/doc/rustc-dev-guide/src/guides/editions.md +++ b/src/doc/rustc-dev-guide/src/guides/editions.md @@ -179,8 +179,7 @@ declare_lint! { Allow, "detects edition keywords being used as an identifier", @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018), - reference: "issue #49716 ", + reason: fcw!(EditionError 2018 "slug-of-edition-guide-page") }; } ``` From 1eabe65151de970f14a41c85a877db79d8b3c430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 10 Dec 2025 12:58:21 +0100 Subject: [PATCH 0540/3801] adapt formatting to use new fcw info structure --- compiler/rustc_hir_typeck/src/upvar.rs | 1 - compiler/rustc_lint_defs/src/builtin.rs | 1 - compiler/rustc_lint_defs/src/lib.rs | 16 ++++++------- compiler/rustc_middle/src/lint.rs | 32 +++++++++++++++---------- compiler/rustc_session/src/parse.rs | 2 +- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 0a7b458f3fb3..445386412058 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1043,7 +1043,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - lint.note("for more information, see "); let diagnostic_msg = format!( "add a dummy let to cause {migrated_variables_concat} to be fully captured" diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index baecc14424ec..93bd7f03c8b2 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3400,7 +3400,6 @@ declare_lint! { "detects closures affected by Rust 2021 changes", @future_incompatible = FutureIncompatibleInfo { reason: fcw!(EditionSemanticsChange 2021 "disjoint-capture-in-closures"), - explain_reason: false, }; } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 1efb8355ca93..d2219d11bece 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -516,31 +516,29 @@ impl FutureIncompatibilityReason { } } - fn fmt_reason(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + pub fn reference(&self) -> String { match self { Self::FutureReleaseSemanticsChange(release_fcw) | Self::FutureReleaseError(release_fcw) - | Self::Custom(_, release_fcw) => release_fcw.fmt_reason(f), + | Self::Custom(_, release_fcw) => release_fcw.to_string(), Self::EditionError(edition_fcw) | Self::EditionSemanticsChange(edition_fcw) | Self::EditionAndFutureReleaseError(edition_fcw) - | Self::EditionAndFutureReleaseSemanticsChange(edition_fcw) => { - edition_fcw.fmt_reason(f) - } + | Self::EditionAndFutureReleaseSemanticsChange(edition_fcw) => edition_fcw.to_string(), Self::Unreachable => unreachable!(), } } } -impl ReleaseFcw { - fn fmt_reason(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl Display for ReleaseFcw { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let issue_number = self.issue_number; write!(f, "issue #{issue_number} ") } } -impl EditionFcw { - fn fmt_reason(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl Display for EditionFcw { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "", diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index f70b7b6fad7a..bed902e8334b 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_errors::{Diag, MultiSpan}; use rustc_hir::{HirId, ItemLocalId}; +use rustc_lint_defs::EditionFcw; use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_session::Session; use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS}; @@ -395,45 +396,52 @@ pub fn lint_level( if let Some(future_incompatible) = future_incompatible { let explanation = match future_incompatible.reason { - FutureIncompatibilityReason::FutureReleaseError => { + FutureIncompatibilityReason::FutureReleaseError(_) => { "this was previously accepted by the compiler but is being phased out; \ it will become a hard error in a future release!" .to_owned() } - FutureIncompatibilityReason::FutureReleaseSemanticsChange => { + FutureIncompatibilityReason::FutureReleaseSemanticsChange(_) => { "this will change its meaning in a future release!".to_owned() } - FutureIncompatibilityReason::EditionError(edition) => { + FutureIncompatibilityReason::EditionError(EditionFcw { edition, .. }) => { let current_edition = sess.edition(); format!( "this is accepted in the current edition (Rust {current_edition}) but is a hard error in Rust {edition}!" ) } - FutureIncompatibilityReason::EditionSemanticsChange(edition) => { + FutureIncompatibilityReason::EditionSemanticsChange(EditionFcw { + edition, .. + }) => { format!("this changes meaning in Rust {edition}") } - FutureIncompatibilityReason::EditionAndFutureReleaseError(edition) => { + FutureIncompatibilityReason::EditionAndFutureReleaseError(EditionFcw { + edition, + .. + }) => { format!( "this was previously accepted by the compiler but is being phased out; \ it will become a hard error in Rust {edition} and in a future release in all editions!" ) } - FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(edition) => { + FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange( + EditionFcw { edition, .. }, + ) => { format!( "this changes meaning in Rust {edition} and in a future release in all editions!" ) } - FutureIncompatibilityReason::Custom(reason) => reason.to_owned(), + FutureIncompatibilityReason::Custom(reason, _) => reason.to_owned(), + FutureIncompatibilityReason::Unreachable => unreachable!(), }; if future_incompatible.explain_reason { err.warn(explanation); } - if !future_incompatible.reference.is_empty() { - let citation = - format!("for more information, see {}", future_incompatible.reference); - err.note(citation); - } + + let citation = + format!("for more information, see {}", future_incompatible.reason.reference()); + err.note(citation); } // Finally, run `decorate`. `decorate` can call `trimmed_path_str` (directly or indirectly), diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 8c70e18fb66d..edc5ae9e6f63 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -150,7 +150,7 @@ pub fn feature_warn_issue( let future_incompatible = lint.future_incompatible.as_ref().unwrap(); err.is_lint(lint.name_lower(), /* has_future_breakage */ false); err.warn(lint.desc); - err.note(format!("for more information, see {}", future_incompatible.reference)); + err.note(format!("for more information, see {}", future_incompatible.reason.reference())); // A later feature_err call can steal and cancel this warning. err.stash(span, StashKey::EarlySyntaxWarning); From 1ef1ec13d8d22bc768de42e55f09b2803c4e9735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 10 Dec 2025 13:38:07 +0100 Subject: [PATCH 0541/3801] bless the tests --- compiler/rustc_lint_defs/src/builtin.rs | 1 + compiler/rustc_lint_defs/src/lib.rs | 2 +- .../anon-params/anon-params-deprecated.stderr | 6 ++-- ...015-edition-error-various-positions.stderr | 20 +++++------ .../await-keyword/2015-edition-warning.stderr | 12 +++---- ...ice-mutability-error-slicing-121807.stderr | 2 +- .../trait-impl-argument-difference-ice.stderr | 2 +- .../const_panic_stability.e2018.stderr | 1 + ...dyn-2015-edition-keyword-ident-lint.stderr | 28 +++++++-------- .../edition-raw-pointer-method-2015.stderr | 2 +- ...89280-emitter-overflow-splice-lines.stderr | 2 +- tests/ui/fn/error-recovery-mismatch.stderr | 2 +- ...ference-variable-behind-raw-pointer.stderr | 2 +- tests/ui/lang-items/issue-83471.stderr | 2 +- .../future-incompatible-lint-group.stderr | 2 +- .../lint-pre-expansion-extern-module.stderr | 2 +- .../macros/expr_2021_cargo_fix_edition.stderr | 4 +-- tests/ui/macros/non-fmt-panic.stderr | 35 +++++++++++++++++++ tests/ui/rust-2018/async-ident-allowed.stderr | 2 +- tests/ui/rust-2018/async-ident.stderr | 28 +++++++-------- tests/ui/rust-2018/dyn-keyword.stderr | 2 +- .../edition-lint-fully-qualified-paths.stderr | 6 ++-- .../edition-lint-nested-empty-paths.stderr | 10 +++--- .../edition-lint-nested-paths.stderr | 8 ++--- tests/ui/rust-2018/edition-lint-paths.stderr | 18 +++++----- tests/ui/rust-2018/extern-crate-rename.stderr | 2 +- tests/ui/rust-2018/extern-crate-submod.stderr | 2 +- tests/ui/rust-2018/try-ident.stderr | 4 +-- tests/ui/rust-2018/try-macro.stderr | 2 +- ...ice-unwrap-probe-many-result-125876.stderr | 4 +-- 30 files changed, 126 insertions(+), 89 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 93bd7f03c8b2..baecc14424ec 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3400,6 +3400,7 @@ declare_lint! { "detects closures affected by Rust 2021 changes", @future_incompatible = FutureIncompatibleInfo { reason: fcw!(EditionSemanticsChange 2021 "disjoint-capture-in-closures"), + explain_reason: false, }; } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index d2219d11bece..d5f5c8740d0d 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -487,7 +487,7 @@ pub enum FutureIncompatibilityReason { /// Using the declare_lint macro a reason always needs to be specified. /// So, this case can't actually be reached but a variant needs to exist for it. - /// Any code panics on seeing this varaint. Do not use. + /// Any code panics on seeing this variant. Do not use. Unreachable, } diff --git a/tests/ui/anon-params/anon-params-deprecated.stderr b/tests/ui/anon-params/anon-params-deprecated.stderr index 541cb004b5b2..0f508bad70b4 100644 --- a/tests/ui/anon-params/anon-params-deprecated.stderr +++ b/tests/ui/anon-params/anon-params-deprecated.stderr @@ -5,7 +5,7 @@ LL | fn foo(i32); | ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see note: the lint level is defined here --> $DIR/anon-params-deprecated.rs:1:9 | @@ -19,7 +19,7 @@ LL | fn bar_with_default_impl(String, String) {} | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see warning: anonymous parameters are deprecated and will be removed in the next edition --> $DIR/anon-params-deprecated.rs:13:38 @@ -28,7 +28,7 @@ LL | fn bar_with_default_impl(String, String) {} | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see warning: 3 warnings emitted diff --git a/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr b/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr index 70900e612f48..a2be23099415 100644 --- a/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr +++ b/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr @@ -5,7 +5,7 @@ LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/2015-edition-error-various-positions.rs:3:9 | @@ -20,7 +20,7 @@ LL | pub struct await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:12:16 @@ -29,7 +29,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:12:23 @@ -38,7 +38,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:17:14 @@ -47,7 +47,7 @@ LL | struct Foo { await: () } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:21:15 @@ -56,7 +56,7 @@ LL | impl Foo { fn await() {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:25:14 @@ -65,7 +65,7 @@ LL | macro_rules! await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:32:5 @@ -74,7 +74,7 @@ LL | await!(); | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:35:11 @@ -83,7 +83,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:35:19 @@ -92,7 +92,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 10 previous errors diff --git a/tests/ui/async-await/await-keyword/2015-edition-warning.stderr b/tests/ui/async-await/await-keyword/2015-edition-warning.stderr index 9d19a09092b9..97c69f2e7288 100644 --- a/tests/ui/async-await/await-keyword/2015-edition-warning.stderr +++ b/tests/ui/async-await/await-keyword/2015-edition-warning.stderr @@ -5,7 +5,7 @@ LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/2015-edition-warning.rs:5:9 | @@ -20,7 +20,7 @@ LL | pub struct await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:16:16 @@ -29,7 +29,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:16:23 @@ -38,7 +38,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:23:11 @@ -47,7 +47,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:23:19 @@ -56,7 +56,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 6 previous errors diff --git a/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr b/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr index 8e1cd800b372..54aa756e581d 100644 --- a/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr +++ b/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr @@ -20,7 +20,7 @@ LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16; | ^^^^^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: Self::Assoc<'_>` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0185]: method `read_dword` has a `&self` declaration in the impl, but not in the trait diff --git a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr index 34fd29a8b50c..df1a5ce909a1 100644 --- a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr +++ b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr @@ -5,7 +5,7 @@ LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16; | ^^^^^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: Self::Assoc<'_>` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0185]: method `read_dword` has a `&self` declaration in the impl, but not in the trait diff --git a/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr index 943695d75fce..c33d5b003042 100644 --- a/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr +++ b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr @@ -4,6 +4,7 @@ warning: panic message is not a string literal LL | panic!({ "foo" }); | ^^^^^^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default diff --git a/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr b/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr index 0d53fb024aca..c0e794cee292 100644 --- a/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr +++ b/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr @@ -5,7 +5,7 @@ LL | pub mod dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:11:9 | @@ -20,7 +20,7 @@ LL | pub struct dyn; | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:22:16 @@ -29,7 +29,7 @@ LL | use outer_mod::dyn::dyn; | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:22:21 @@ -38,7 +38,7 @@ LL | use outer_mod::dyn::dyn; | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:29:11 @@ -47,7 +47,7 @@ LL | match dyn { dyn => {} } | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:29:17 @@ -56,7 +56,7 @@ LL | match dyn { dyn => {} } | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:34:17 @@ -65,7 +65,7 @@ LL | macro_defn::dyn(); | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:44:18 @@ -74,7 +74,7 @@ LL | macro_rules! dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:52:12 @@ -83,7 +83,7 @@ LL | pub fn dyn() -> ::outer_mod::dyn::dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:52:34 @@ -92,7 +92,7 @@ LL | pub fn dyn() -> ::outer_mod::dyn::dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:52:39 @@ -101,7 +101,7 @@ LL | pub fn dyn() -> ::outer_mod::dyn::dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:59:22 @@ -110,7 +110,7 @@ LL | ::outer_mod::dyn::dyn | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:59:27 @@ -119,7 +119,7 @@ LL | ::outer_mod::dyn::dyn | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:68:23 @@ -128,7 +128,7 @@ LL | pub fn boxed() -> dyn!( | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 14 previous errors diff --git a/tests/ui/editions/edition-raw-pointer-method-2015.stderr b/tests/ui/editions/edition-raw-pointer-method-2015.stderr index 3d8b3f633ce8..ad8beb049f9f 100644 --- a/tests/ui/editions/edition-raw-pointer-method-2015.stderr +++ b/tests/ui/editions/edition-raw-pointer-method-2015.stderr @@ -5,7 +5,7 @@ LL | let _ = y.is_null(); | ^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-raw-pointer-method-2015.rs:5:8 | diff --git a/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr index ed1ebe4466af..6878bde85b8b 100644 --- a/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr +++ b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr @@ -8,7 +8,7 @@ LL | | )) {} | |_____^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default help: try naming the parameter or explicitly ignoring it | diff --git a/tests/ui/fn/error-recovery-mismatch.stderr b/tests/ui/fn/error-recovery-mismatch.stderr index 400af46e2a27..7a320c6bc695 100644 --- a/tests/ui/fn/error-recovery-mismatch.stderr +++ b/tests/ui/fn/error-recovery-mismatch.stderr @@ -26,7 +26,7 @@ LL | fn fold(&self, _: T, &self._) {} | ^ help: try naming the parameter or explicitly ignoring it: `_: _` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods diff --git a/tests/ui/inference/inference-variable-behind-raw-pointer.stderr b/tests/ui/inference/inference-variable-behind-raw-pointer.stderr index 50202ea3db3e..360d4dd22ceb 100644 --- a/tests/ui/inference/inference-variable-behind-raw-pointer.stderr +++ b/tests/ui/inference/inference-variable-behind-raw-pointer.stderr @@ -5,7 +5,7 @@ LL | if data.is_null() {} | ^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see = note: `#[warn(tyvar_behind_raw_pointer)]` (part of `#[warn(rust_2018_compatibility)]`) on by default warning: 1 warning emitted diff --git a/tests/ui/lang-items/issue-83471.stderr b/tests/ui/lang-items/issue-83471.stderr index 0c2b403902e2..1d5b1c4cd3ed 100644 --- a/tests/ui/lang-items/issue-83471.stderr +++ b/tests/ui/lang-items/issue-83471.stderr @@ -47,7 +47,7 @@ LL | fn call(export_name); | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0718]: `fn` lang item must be applied to a trait with 1 generic argument diff --git a/tests/ui/lint/future-incompatible-lint-group.stderr b/tests/ui/lint/future-incompatible-lint-group.stderr index bac24740fb4e..ff1e54f5dea3 100644 --- a/tests/ui/lint/future-incompatible-lint-group.stderr +++ b/tests/ui/lint/future-incompatible-lint-group.stderr @@ -5,7 +5,7 @@ LL | fn f(u8) {} | ^^ help: try naming the parameter or explicitly ignoring it: `_: u8` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error: ambiguous associated item diff --git a/tests/ui/lint/lint-pre-expansion-extern-module.stderr b/tests/ui/lint/lint-pre-expansion-extern-module.stderr index 32c76da98b52..1de1784fc9c5 100644 --- a/tests/ui/lint/lint-pre-expansion-extern-module.stderr +++ b/tests/ui/lint/lint-pre-expansion-extern-module.stderr @@ -5,7 +5,7 @@ LL | pub fn try() {} | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see = note: `-W keyword-idents-2018` implied by `-W rust-2018-compatibility` = help: to override `-W rust-2018-compatibility` add `#[allow(keyword_idents_2018)]` diff --git a/tests/ui/macros/expr_2021_cargo_fix_edition.stderr b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr index 795d99449c26..17ec247bd4de 100644 --- a/tests/ui/macros/expr_2021_cargo_fix_edition.stderr +++ b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr @@ -5,7 +5,7 @@ LL | ($e:expr) => { | ^^^^ | = warning: this changes meaning in Rust 2024 - = note: for more information, see Migration Guide + = note: for more information, see note: the lint level is defined here --> $DIR/expr_2021_cargo_fix_edition.rs:4:9 | @@ -23,7 +23,7 @@ LL | ($($i:expr)*) => { }; | ^^^^ | = warning: this changes meaning in Rust 2024 - = note: for more information, see Migration Guide + = note: for more information, see help: to keep the existing behavior, use the `expr_2021` fragment specifier | LL | ($($i:expr_2021)*) => { }; diff --git a/tests/ui/macros/non-fmt-panic.stderr b/tests/ui/macros/non-fmt-panic.stderr index 43f59782ee72..8a89d5ea7939 100644 --- a/tests/ui/macros/non-fmt-panic.stderr +++ b/tests/ui/macros/non-fmt-panic.stderr @@ -4,6 +4,7 @@ warning: panic message contains a brace LL | panic!("here's a brace: {"); | ^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default help: add a "{}" format string to use the message literally @@ -17,6 +18,7 @@ warning: panic message contains a brace LL | unreachable!("here's a brace: {"); | ^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -29,6 +31,7 @@ warning: panic message contains a brace LL | std::panic!("another one: }"); | ^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -41,6 +44,7 @@ warning: panic message contains an unused formatting placeholder LL | core::panic!("Hello {}"); | ^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | @@ -57,6 +61,7 @@ warning: panic message contains unused formatting placeholders LL | assert!(false, "{:03x} {test} bla"); | ^^^^^^ ^^^^^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing arguments | @@ -73,6 +78,7 @@ warning: panic message is not a string literal LL | assert!(false, S); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -86,6 +92,7 @@ warning: panic message is not a string literal LL | assert!(false, 123); | ^^^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -99,6 +106,7 @@ warning: panic message is not a string literal LL | assert!(false, Some(123)); | ^^^^^^^^^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `Option` @@ -112,6 +120,7 @@ warning: panic message contains braces LL | debug_assert!(false, "{{}} bla"); | ^^^^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -124,6 +133,7 @@ warning: panic message is not a string literal LL | panic!(C); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -137,6 +147,7 @@ warning: panic message is not a string literal LL | panic!(S); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -150,6 +161,7 @@ warning: panic message is not a string literal LL | unreachable!(S); | ^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -163,6 +175,7 @@ warning: panic message is not a string literal LL | unreachable!(S); | ^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -176,6 +189,7 @@ warning: panic message is not a string literal LL | std::panic!(123); | ^^^ | + = note: for more information, see = note: this usage of `std::panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -194,6 +208,7 @@ warning: panic message is not a string literal LL | core::panic!(&*"abc"); | ^^^^^^^ | + = note: for more information, see = note: this usage of `core::panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -207,6 +222,7 @@ warning: panic message is not a string literal LL | panic!(Some(123)); | ^^^^^^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `Option` @@ -225,6 +241,7 @@ warning: panic message contains an unused formatting placeholder LL | panic!(concat!("{", "}")); | ^^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | @@ -241,6 +258,7 @@ warning: panic message contains braces LL | panic!(concat!("{", "{")); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -253,6 +271,7 @@ warning: panic message contains an unused formatting placeholder LL | fancy_panic::fancy_panic!("test {} 123"); | ^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 warning: panic message is not a string literal @@ -261,6 +280,7 @@ warning: panic message is not a string literal LL | panic!(a!()); | ^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -279,6 +299,7 @@ warning: panic message is not a string literal LL | unreachable!(a!()); | ^^^^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -292,6 +313,7 @@ warning: panic message is not a string literal LL | panic!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `panic!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -307,6 +329,7 @@ warning: panic message is not a string literal LL | unreachable!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `unreachable!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -322,6 +345,7 @@ warning: panic message is not a string literal LL | assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `assert!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -337,6 +361,7 @@ warning: panic message is not a string literal LL | debug_assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `debug_assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `debug_assert!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -352,6 +377,7 @@ warning: panic message is not a string literal LL | panic![123]; | ^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -370,6 +396,7 @@ warning: panic message is not a string literal LL | panic!{123}; | ^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -390,6 +417,7 @@ LL | panic!(v); | | | help: use std::panic::panic_any instead: `std::panic::panic_any` | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see @@ -399,6 +427,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see @@ -408,6 +437,7 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `T` @@ -426,6 +456,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `T` @@ -439,6 +470,7 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -457,6 +489,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -470,6 +503,7 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -488,6 +522,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message diff --git a/tests/ui/rust-2018/async-ident-allowed.stderr b/tests/ui/rust-2018/async-ident-allowed.stderr index 378c81d3c770..1bdfc7bae102 100644 --- a/tests/ui/rust-2018/async-ident-allowed.stderr +++ b/tests/ui/rust-2018/async-ident-allowed.stderr @@ -5,7 +5,7 @@ LL | let async = 3; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/async-ident-allowed.rs:3:9 | diff --git a/tests/ui/rust-2018/async-ident.stderr b/tests/ui/rust-2018/async-ident.stderr index 4ab061dd6f59..2c4cb7e1d96e 100644 --- a/tests/ui/rust-2018/async-ident.stderr +++ b/tests/ui/rust-2018/async-ident.stderr @@ -5,7 +5,7 @@ LL | fn async() {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/async-ident.rs:2:9 | @@ -20,7 +20,7 @@ LL | ($async:expr, async) => {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:17:6 @@ -29,7 +29,7 @@ LL | foo!(async); | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:26:11 @@ -38,7 +38,7 @@ LL | trait async {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:30:10 @@ -47,7 +47,7 @@ LL | impl async for MyStruct {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:36:12 @@ -56,7 +56,7 @@ LL | static async: u32 = 0; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:42:11 @@ -65,7 +65,7 @@ LL | const async: u32 = 0; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:48:15 @@ -74,7 +74,7 @@ LL | impl Foo { fn async() {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:53:12 @@ -83,7 +83,7 @@ LL | struct async {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:56:9 @@ -92,7 +92,7 @@ LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:56:16 @@ -101,7 +101,7 @@ LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:56:24 @@ -110,7 +110,7 @@ LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:67:19 @@ -119,7 +119,7 @@ LL | () => (pub fn async() {}) | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:74:6 @@ -128,7 +128,7 @@ LL | (async) => (1) | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 14 previous errors diff --git a/tests/ui/rust-2018/dyn-keyword.stderr b/tests/ui/rust-2018/dyn-keyword.stderr index f8245bc88f57..733583f32b9b 100644 --- a/tests/ui/rust-2018/dyn-keyword.stderr +++ b/tests/ui/rust-2018/dyn-keyword.stderr @@ -5,7 +5,7 @@ LL | let dyn = (); | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/dyn-keyword.rs:5:9 | diff --git a/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr b/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr index c0a322edcd64..b59604f6427e 100644 --- a/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr @@ -5,7 +5,7 @@ LL | let _: ::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-fully-qualified-paths.rs:4:9 | @@ -19,7 +19,7 @@ LL | let _: ::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -29,7 +29,7 @@ LL | let _: <::foo::Baz as foo::Foo>::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Baz` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: aborting due to 3 previous errors diff --git a/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr b/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr index 041572be8441..af02b30a99bd 100644 --- a/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr @@ -5,7 +5,7 @@ LL | use foo::{bar::{baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-nested-empty-paths.rs:4:9 | @@ -19,7 +19,7 @@ LL | use foo::{bar::{XX, baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-empty-paths.rs:21:5 @@ -28,7 +28,7 @@ LL | use foo::{bar::{XX, baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -38,7 +38,7 @@ LL | use foo::{bar::{baz::{}, baz1::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-empty-paths.rs:27:5 @@ -47,7 +47,7 @@ LL | use foo::{bar::{baz::{}, baz1::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 5 previous errors diff --git a/tests/ui/rust-2018/edition-lint-nested-paths.stderr b/tests/ui/rust-2018/edition-lint-nested-paths.stderr index 4a70bb7e5c87..0f60b16ac9aa 100644 --- a/tests/ui/rust-2018/edition-lint-nested-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-nested-paths.stderr @@ -5,7 +5,7 @@ LL | use foo::{a, b}; | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-nested-paths.rs:4:9 | @@ -19,7 +19,7 @@ LL | use foo::{a, b}; | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -29,7 +29,7 @@ LL | use foo::{self as x, c}; | ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-paths.rs:23:13 @@ -38,7 +38,7 @@ LL | use foo::{self as x, c}; | ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/rust-2018/edition-lint-paths.stderr b/tests/ui/rust-2018/edition-lint-paths.stderr index fde17338d98a..26db6e402a9e 100644 --- a/tests/ui/rust-2018/edition-lint-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-paths.stderr @@ -5,7 +5,7 @@ LL | use bar::Bar; | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-paths.rs:5:9 | @@ -19,7 +19,7 @@ LL | use bar; | ^^^ help: use `crate`: `crate::bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:25:9 @@ -28,7 +28,7 @@ LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:25:9 @@ -37,7 +37,7 @@ LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -47,7 +47,7 @@ LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -57,7 +57,7 @@ LL | use bar::Bar; | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:52:9 @@ -66,7 +66,7 @@ LL | use *; | ^ help: use `crate`: `crate::*` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:57:6 @@ -75,7 +75,7 @@ LL | impl ::foo::SomeTrait for u32 {} | ^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::SomeTrait` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:62:13 @@ -84,7 +84,7 @@ LL | let x = ::bar::Bar; | ^^^^^^^^^^ help: use `crate`: `crate::bar::Bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: aborting due to 9 previous errors diff --git a/tests/ui/rust-2018/extern-crate-rename.stderr b/tests/ui/rust-2018/extern-crate-rename.stderr index 36986c89c62b..bce9e73ee65a 100644 --- a/tests/ui/rust-2018/extern-crate-rename.stderr +++ b/tests/ui/rust-2018/extern-crate-rename.stderr @@ -5,7 +5,7 @@ LL | use my_crate::foo; | ^^^^^^^^^^^^^ help: use `crate`: `crate::my_crate::foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/extern-crate-rename.rs:8:9 | diff --git a/tests/ui/rust-2018/extern-crate-submod.stderr b/tests/ui/rust-2018/extern-crate-submod.stderr index 85e26d72a673..ed4266d3b091 100644 --- a/tests/ui/rust-2018/extern-crate-submod.stderr +++ b/tests/ui/rust-2018/extern-crate-submod.stderr @@ -5,7 +5,7 @@ LL | use m::edition_lint_paths::foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::m::edition_lint_paths::foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/extern-crate-submod.rs:9:9 | diff --git a/tests/ui/rust-2018/try-ident.stderr b/tests/ui/rust-2018/try-ident.stderr index aca623d7d482..3af2196ce35b 100644 --- a/tests/ui/rust-2018/try-ident.stderr +++ b/tests/ui/rust-2018/try-ident.stderr @@ -5,7 +5,7 @@ LL | try(); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/try-ident.rs:5:9 | @@ -20,7 +20,7 @@ LL | fn try() { | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see warning: 2 warnings emitted diff --git a/tests/ui/rust-2018/try-macro.stderr b/tests/ui/rust-2018/try-macro.stderr index 20105e1868f2..89366381c8c6 100644 --- a/tests/ui/rust-2018/try-macro.stderr +++ b/tests/ui/rust-2018/try-macro.stderr @@ -5,7 +5,7 @@ LL | try!(x); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/try-macro.rs:7:9 | diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr index 8bb2bb290d3d..2521341723a2 100644 --- a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr @@ -11,7 +11,7 @@ LL | std::ptr::from_ref(num).cast_mut().as_deref(); | ^^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see = note: `#[warn(tyvar_behind_raw_pointer)]` (part of `#[warn(rust_2018_compatibility)]`) on by default warning: type annotations needed @@ -21,7 +21,7 @@ LL | std::ptr::from_ref(num).cast_mut().as_deref(); | ^^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see error[E0599]: no method named `as_deref` found for raw pointer `*mut _` in the current scope --> $DIR/ice-unwrap-probe-many-result-125876.rs:5:40 From c923dc31e4ba4f7e56eb4e31e4083e69fc25fd15 Mon Sep 17 00:00:00 2001 From: dianqk Date: Wed, 10 Dec 2025 22:24:58 +0800 Subject: [PATCH 0542/3801] Update LLVM submodule --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 16b5ac8b0a54..89bab96463d4 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 16b5ac8b0a5456eb23c72e1bff3fc9bd6e824f84 +Subproject commit 89bab96463d42e979145166e0f8e6b8157fedc12 From 787886861746f88af4b502e8691099223494b51c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 4 Nov 2025 13:42:30 +0000 Subject: [PATCH 0543/3801] don't normalize where-clauses in wfcheck --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 0e8859facf58..0a6be9aa4b2f 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1147,17 +1147,16 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuarant /// /// Assuming the defaults are used, check that all predicates (bounds on the /// assoc type and where clauses on the trait) hold. -fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocItem, span: Span) { +fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocItem, _span: Span) { let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); debug!("check_associated_type_bounds: bounds={:?}", bounds); let wf_obligations = bounds.iter_identity_copied().flat_map(|(bound, bound_span)| { - let normalized_bound = wfcx.normalize(span, None, bound); traits::wf::clause_obligations( wfcx.infcx, wfcx.param_env, wfcx.body_def_id, - normalized_bound, + bound, bound_span, ) }); @@ -1525,7 +1524,6 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: assert_eq!(predicates.predicates.len(), predicates.spans.len()); let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| { - let p = wfcx.normalize(sp, None, p); traits::wf::clause_obligations(infcx, wfcx.param_env, wfcx.body_def_id, p, sp) }); let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect(); From fa775988245e635b20278551ecdc334193d754fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 4 Nov 2025 14:04:02 +0000 Subject: [PATCH 0544/3801] update tests and bless expectations just to show the diagnostics impact --- .../assoc-const-eq-bound-var-in-ty-not-wf.rs | 3 +- ...soc-const-eq-bound-var-in-ty-not-wf.stderr | 15 +--- tests/ui/associated-types/issue-38821.rs | 12 +-- tests/ui/associated-types/issue-38821.stderr | 85 ++++++++++++------- .../in-trait/refine-resolution-errors.rs | 1 + .../in-trait/refine-resolution-errors.stderr | 10 ++- .../ui/lifetimes/issue-76168-hr-outlives-3.rs | 3 - .../issue-76168-hr-outlives-3.stderr | 28 +----- tests/ui/methods/filter-relevant-fn-bounds.rs | 2 - .../methods/filter-relevant-fn-bounds.stderr | 32 ++----- .../regions-normalize-in-where-clause-list.rs | 1 + ...ions-normalize-in-where-clause-list.stderr | 27 +++++- .../regions-enum-not-wf.rs | 1 + .../regions-enum-not-wf.stderr | 16 +++- tests/ui/traits/deep-norm-pending.rs | 4 +- tests/ui/traits/deep-norm-pending.stderr | 20 +++-- 16 files changed, 137 insertions(+), 123 deletions(-) diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index 5232b895803e..8334e67ae9a1 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -21,8 +21,7 @@ fn take( K = { () } >, ) {} -//~^^^^^ ERROR implementation of `Project` is not general enough -//~^^^^ ERROR higher-ranked subtype error +//~^^^ ERROR higher-ranked subtype error //~| ERROR higher-ranked subtype error trait Project { type Out; } diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index a0329e2b15d1..9fac60763dae 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -12,18 +12,5 @@ LL | K = { () } | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: implementation of `Project` is not general enough - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:19:13 - | -LL | _: impl Trait< - | _____________^ -LL | | < fn(&'a str) -> &'a str as Project>::Out as Discard>::Out, -LL | | K = { () } -LL | | >, - | |_____^ implementation of `Project` is not general enough - | - = note: `Project` would have to be implemented for the type `for<'a> fn(&'a str) -> &'a str` - = note: ...but `Project` is actually implemented for the type `fn(&'0 str) -> &'0 str`, for some specific lifetime `'0` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/associated-types/issue-38821.rs b/tests/ui/associated-types/issue-38821.rs index 60d3b224a5bf..5212bc886f0d 100644 --- a/tests/ui/associated-types/issue-38821.rs +++ b/tests/ui/associated-types/issue-38821.rs @@ -32,16 +32,16 @@ pub trait Column: Expression {} //~| ERROR the trait bound `::SqlType: NotNull` is not satisfied //~| ERROR the trait bound `::SqlType: NotNull` is not satisfied //~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied pub enum ColumnInsertValue where //~^ ERROR the trait bound `::SqlType: NotNull` is not satisfied Col: Column, Expr: Expression::Nullable>, -//~^ ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~^ ERROR the trait bound `::SqlType: IntoNullable` is not satisfied { Expression(Col, Expr), Default(Col), diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index b03a3cf7f47e..01329f69c3be 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:35:1 + --> $DIR/issue-38821.rs:40:1 | LL | pub enum ColumnInsertValue where | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` @@ -16,8 +16,8 @@ help: consider extending the `where` clause, but there might be an alternative b LL | Expr: Expression::Nullable>, ::SqlType: NotNull | +++++++++++++++++++++++++++++++++++++ -error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 +error[E0277]: the trait bound `::SqlType: IntoNullable` is not satisfied + --> $DIR/issue-38821.rs:43:22 | LL | Expr: Expression::Nullable>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` @@ -82,10 +82,36 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 + --> $DIR/issue-38821.rs:23:10 | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ the trait `NotNull` is not implemented for `::SqlType` + | +note: required for `::SqlType` to implement `IntoNullable` + --> $DIR/issue-38821.rs:9:18 + | +LL | impl IntoNullable for T { + | ------- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `ColumnInsertValue` to implement `Debug` + --> $DIR/issue-38821.rs:23:10 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ +... LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` + | ------------------------------------------------ unsatisfied trait bound introduced in this `derive` macro +help: consider further restricting the associated type + | +LL | Expr: Expression::Nullable>, ::SqlType: NotNull, + | +++++++++++++++++++++++++++++++++++++++ + +error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied + --> $DIR/issue-38821.rs:23:17 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -112,24 +138,14 @@ LL | impl IntoNullable for T { | ------- ^^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here -help: consider further restricting the associated type - | -LL | Expr: Expression::Nullable>, ::SqlType: NotNull, - | +++++++++++++++++++++++++++++++++++++++ - -error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 +note: required for `ColumnInsertValue` to implement `Copy` + --> $DIR/issue-38821.rs:23:17 | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^ +... LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` - | -note: required for `::SqlType` to implement `IntoNullable` - --> $DIR/issue-38821.rs:9:18 - | -LL | impl IntoNullable for T { - | ------- ^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here + | ------------------------------------------------ unsatisfied trait bound introduced in this `derive` macro help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, @@ -183,10 +199,10 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 + --> $DIR/issue-38821.rs:23:23 | -LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -195,6 +211,14 @@ LL | impl IntoNullable for T { | ------- ^^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here +note: required for `ColumnInsertValue` to implement `Clone` + --> $DIR/issue-38821.rs:23:23 + | +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ +... +LL | Expr: Expression::Nullable>, + | ------------------------------------------------ unsatisfied trait bound introduced in this `derive` macro help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, @@ -216,10 +240,10 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 + --> $DIR/issue-38821.rs:23:10 | -LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -245,10 +269,10 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 + --> $DIR/issue-38821.rs:23:23 | -LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -257,7 +281,6 @@ LL | impl IntoNullable for T { | ------- ^^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied --> $DIR/issue-38821.rs:23:10 diff --git a/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs b/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs index 8433fb72b5e0..fa4ce66d54e6 100644 --- a/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs +++ b/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs @@ -14,6 +14,7 @@ impl Mirror for () { pub trait First { async fn first() -> <() as Mirror>::Assoc; + //~^ ERROR type annotations needed } impl First for () { diff --git a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr index fd53c9fef443..af71e52b87d7 100644 --- a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr +++ b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr @@ -28,7 +28,13 @@ help: consider relaxing the implicit `Sized` restriction LL | type Assoc: ?Sized; | ++++++++ -error: aborting due to 2 previous errors +error[E0282]: type annotations needed + --> $DIR/refine-resolution-errors.rs:16:25 + | +LL | async fn first() -> <() as Mirror>::Assoc; + | ^^^^^^^^^^^^^^^^^^^^^ cannot infer type -Some errors have detailed explanations: E0207, E0277. +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0207, E0277, E0282. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs index d6fda129e363..85eeb5d4c901 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs @@ -10,9 +10,6 @@ async fn wrapper(f: F) where F:, for<'a> >::Output: Future + 'a, -//~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` -//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` -//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` { //~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` let mut i = 41; diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr index bb8e84724257..6da9f7380d59 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr @@ -9,30 +9,6 @@ LL | | for<'a> >::Output: Future + 'a | = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` -error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:12:50 - | -LL | for<'a> >::Output: Future + 'a, - | ^^^^^^^^^^^^^^^^^^^ expected an `FnOnce(&'a mut i32)` closure, found `i32` - | - = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` - -error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:12:57 - | -LL | for<'a> >::Output: Future + 'a, - | ^^^^^^^^^^^ expected an `FnOnce(&'a mut i32)` closure, found `i32` - | - = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` - -error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:12:72 - | -LL | for<'a> >::Output: Future + 'a, - | ^^ expected an `FnOnce(&'a mut i32)` closure, found `i32` - | - = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` - error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` --> $DIR/issue-76168-hr-outlives-3.rs:6:26 | @@ -51,7 +27,7 @@ LL | async fn wrapper(f: F) = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:16:1 + --> $DIR/issue-76168-hr-outlives-3.rs:13:1 | LL | / { LL | | @@ -62,6 +38,6 @@ LL | | } | = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` -error: aborting due to 7 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/methods/filter-relevant-fn-bounds.rs b/tests/ui/methods/filter-relevant-fn-bounds.rs index 6233c9db53a0..7945eaa0daa2 100644 --- a/tests/ui/methods/filter-relevant-fn-bounds.rs +++ b/tests/ui/methods/filter-relevant-fn-bounds.rs @@ -9,8 +9,6 @@ impl Wrapper { //~^ ERROR the trait bound `for<'a> F: Output<'a>` is not satisfied where F: for<'a> FnOnce(>::Type), - //~^ ERROR the trait bound `for<'a> F: Output<'a>` is not satisfied - //~| ERROR the trait bound `for<'a> F: Output<'a>` is not satisfied { } } diff --git a/tests/ui/methods/filter-relevant-fn-bounds.stderr b/tests/ui/methods/filter-relevant-fn-bounds.stderr index 82103e62ddfe..4efe40ae0903 100644 --- a/tests/ui/methods/filter-relevant-fn-bounds.stderr +++ b/tests/ui/methods/filter-relevant-fn-bounds.stderr @@ -12,37 +12,15 @@ help: consider further restricting type parameter `F` with trait `Output` LL | F: for<'a> FnOnce(>::Type) + for<'a> Output<'a>, | ++++++++++++++++++++ -error[E0277]: the trait bound `for<'a> F: Output<'a>` is not satisfied - --> $DIR/filter-relevant-fn-bounds.rs:11:12 - | -LL | F: for<'a> FnOnce(>::Type), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Output<'a>` is not implemented for `F` - | -help: consider further restricting type parameter `F` with trait `Output` - | -LL | F: for<'a> FnOnce(>::Type) + for<'a> Output<'a>, - | ++++++++++++++++++++ - -error[E0277]: the trait bound `for<'a> F: Output<'a>` is not satisfied - --> $DIR/filter-relevant-fn-bounds.rs:11:20 - | -LL | F: for<'a> FnOnce(>::Type), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Output<'a>` is not implemented for `F` - | -help: consider further restricting type parameter `F` with trait `Output` - | -LL | F: for<'a> FnOnce(>::Type) + for<'a> Output<'a>, - | ++++++++++++++++++++ - -error[E0277]: expected a `FnOnce(<{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41} as Output<'a>>::Type)` closure, found `{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41}` - --> $DIR/filter-relevant-fn-bounds.rs:20:34 +error[E0277]: expected a `FnOnce(<{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41} as Output<'a>>::Type)` closure, found `{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41}` + --> $DIR/filter-relevant-fn-bounds.rs:18:34 | LL | wrapper.do_something_wrapper(|value| ()); - | -------------------- ^^^^^^^^^^ expected an `FnOnce(<{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41} as Output<'a>>::Type)` closure, found `{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41}` + | -------------------- ^^^^^^^^^^ expected an `FnOnce(<{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41} as Output<'a>>::Type)` closure, found `{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41}` | | | required by a bound introduced by this call | - = help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41}` + = help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41}` help: this trait has no implementations, consider adding one --> $DIR/filter-relevant-fn-bounds.rs:1:1 | @@ -57,6 +35,6 @@ LL | fn do_something_wrapper(self, _: F) LL | F: for<'a> FnOnce(>::Type), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper` -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/regions/regions-normalize-in-where-clause-list.rs b/tests/ui/regions/regions-normalize-in-where-clause-list.rs index 9b046e6baed6..bcc5da406b4e 100644 --- a/tests/ui/regions/regions-normalize-in-where-clause-list.rs +++ b/tests/ui/regions/regions-normalize-in-where-clause-list.rs @@ -25,6 +25,7 @@ fn bar<'a, 'b>() where <() as Project<'a, 'b>>::Item: Eq, //~^ ERROR cannot infer + //~| ERROR cannot infer { } diff --git a/tests/ui/regions/regions-normalize-in-where-clause-list.stderr b/tests/ui/regions/regions-normalize-in-where-clause-list.stderr index 9a5c9ae53de3..1a20055836ac 100644 --- a/tests/ui/regions/regions-normalize-in-where-clause-list.stderr +++ b/tests/ui/regions/regions-normalize-in-where-clause-list.stderr @@ -22,6 +22,31 @@ LL | <() as Project<'a, 'b>>::Item: Eq, = note: expected `Project<'a, 'b>` found `Project<'_, '_>` -error: aborting due to 1 previous error +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/regions-normalize-in-where-clause-list.rs:26:36 + | +LL | <() as Project<'a, 'b>>::Item: Eq, + | ^^ + | +note: first, the lifetime cannot outlive the lifetime `'a` as defined here... + --> $DIR/regions-normalize-in-where-clause-list.rs:24:8 + | +LL | fn bar<'a, 'b>() + | ^^ +note: ...but the lifetime must also be valid for the lifetime `'b` as defined here... + --> $DIR/regions-normalize-in-where-clause-list.rs:24:12 + | +LL | fn bar<'a, 'b>() + | ^^ +note: ...so that the types are compatible + --> $DIR/regions-normalize-in-where-clause-list.rs:26:36 + | +LL | <() as Project<'a, 'b>>::Item: Eq, + | ^^ + = note: expected `Project<'a, 'b>` + found `Project<'_, '_>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0803`. diff --git a/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.rs b/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.rs index 038f53034ab0..c5e9d147d567 100644 --- a/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.rs +++ b/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.rs @@ -34,6 +34,7 @@ enum RefIndirect<'a, T> { enum RefDouble<'a, 'b, T> { RefDoubleVariant1(&'a RequireOutlives<'b, T>), //~^ ERROR the parameter type `T` may not live long enough [E0309] + //~| ERROR the parameter type `T` may not live long enough [E0309] } fn main() {} diff --git a/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.stderr b/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.stderr index 5b605f3eef56..2799164bbda2 100644 --- a/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.stderr +++ b/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.stderr @@ -38,6 +38,20 @@ help: consider adding an explicit lifetime bound LL | enum RefDouble<'a, 'b, T: 'b> { | ++++ -error: aborting due to 3 previous errors +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/regions-enum-not-wf.rs:35:23 + | +LL | enum RefDouble<'a, 'b, T> { + | -- the parameter type `T` must be valid for the lifetime `'b` as defined here... +LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider adding an explicit lifetime bound + | +LL | enum RefDouble<'a, 'b, T: 'b> { + | ++++ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/traits/deep-norm-pending.rs b/tests/ui/traits/deep-norm-pending.rs index d6c498dcf2bd..9b1ec522bef3 100644 --- a/tests/ui/traits/deep-norm-pending.rs +++ b/tests/ui/traits/deep-norm-pending.rs @@ -7,11 +7,11 @@ trait Bar { //~^ ERROR the trait bound `T: Foo` is not satisfied } impl Bar for T -//~^ ERROR the trait bound `T: Foo` is not satisfied +//~^ ERROR the trait bound `T: Bar` is not satisfied +//~| ERROR the trait bound `T: Foo` is not satisfied where ::Assoc: Sized, //~^ ERROR the trait bound `T: Foo` is not satisfied - //~| ERROR the trait bound `T: Foo` is not satisfied { fn method() {} //~^ ERROR the trait bound `T: Foo` is not satisfied diff --git a/tests/ui/traits/deep-norm-pending.stderr b/tests/ui/traits/deep-norm-pending.stderr index c1d6120c390d..f2b59748ced9 100644 --- a/tests/ui/traits/deep-norm-pending.stderr +++ b/tests/ui/traits/deep-norm-pending.stderr @@ -3,6 +3,7 @@ error[E0277]: the trait bound `T: Foo` is not satisfied | LL | / impl Bar for T LL | | +LL | | LL | | where LL | | ::Assoc: Sized, | |_____________________________^ the trait `Foo` is not implemented for `T` @@ -85,12 +86,20 @@ help: consider further restricting type parameter `T` with trait `Foo` LL | ::Assoc: Sized, T: Foo | ++++++ -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:12:24 +error[E0277]: the trait bound `T: Bar` is not satisfied + --> $DIR/deep-norm-pending.rs:9:17 | +LL | impl Bar for T + | ^ the trait `Foo` is not implemented for `T` + | +note: required for `T` to implement `Bar` + --> $DIR/deep-norm-pending.rs:9:9 + | +LL | impl Bar for T + | ^^^ ^ +... LL | ::Assoc: Sized, - | ^^^^^ the trait `Foo` is not implemented for `T` - | + | ----- unsatisfied trait bound introduced here help: consider further restricting type parameter `T` with trait `Foo` | LL | ::Assoc: Sized, T: Foo @@ -109,12 +118,11 @@ LL | ::Assoc: Sized, T: Foo | ++++++ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:12:24 + --> $DIR/deep-norm-pending.rs:13:24 | LL | ::Assoc: Sized, | ^^^^^ the trait `Foo` is not implemented for `T` | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider further restricting type parameter `T` with trait `Foo` | LL | ::Assoc: Sized, T: Foo From cdf43ad5ef5986b42170cba38ce03c0f3e81c0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 26 Nov 2025 15:24:07 +0000 Subject: [PATCH 0545/3801] add test from modcholesky breakage --- .../wf/wf-where-clauses-pre-normalization.rs | 20 +++++++++++++++++++ .../wf-where-clauses-pre-normalization.stderr | 17 ++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 tests/ui/wf/wf-where-clauses-pre-normalization.rs create mode 100644 tests/ui/wf/wf-where-clauses-pre-normalization.stderr diff --git a/tests/ui/wf/wf-where-clauses-pre-normalization.rs b/tests/ui/wf/wf-where-clauses-pre-normalization.rs new file mode 100644 index 000000000000..16c102f1faef --- /dev/null +++ b/tests/ui/wf/wf-where-clauses-pre-normalization.rs @@ -0,0 +1,20 @@ +// This is a test, extracted from `modcholesky`, that used to pass wfcheck because we checked +// well-formedness of where-clauses *after* normalization. We generally want to move to always check +// WF pre-normalization. + +pub struct View(A); +pub trait Data { + type Elem; +} +impl<'a, A> Data for View<&'a A> { + type Elem = A; +} + +pub fn repro<'a, T>() +where + as Data>::Elem: Sized, + //~^ ERROR: the parameter type `T` may not live long enough +{ +} + +fn main() {} diff --git a/tests/ui/wf/wf-where-clauses-pre-normalization.stderr b/tests/ui/wf/wf-where-clauses-pre-normalization.stderr new file mode 100644 index 000000000000..a7836cae5db2 --- /dev/null +++ b/tests/ui/wf/wf-where-clauses-pre-normalization.stderr @@ -0,0 +1,17 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/wf-where-clauses-pre-normalization.rs:15:34 + | +LL | pub fn repro<'a, T>() + | -- the parameter type `T` must be valid for the lifetime `'a` as defined here... +LL | where +LL | as Data>::Elem: Sized, + | ^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound + | +LL | pub fn repro<'a, T: 'a>() + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0309`. From 99f7e785c5276bd9ec6014c97a5688e2283953de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 26 Nov 2025 15:45:48 +0000 Subject: [PATCH 0546/3801] mark crash test as requiring debug-assertions --- tests/crashes/133613.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/crashes/133613.rs b/tests/crashes/133613.rs index f01780d7cf42..066c50b49477 100644 --- a/tests/crashes/133613.rs +++ b/tests/crashes/133613.rs @@ -1,3 +1,4 @@ +//@ needs-rustc-debug-assertions //@ known-bug: #133613 struct Wrapper<'a>(); From 69db81658ef2f4c54e85c3b5510bbcdb92961b5a Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Wed, 10 Dec 2025 15:08:41 +0000 Subject: [PATCH 0547/3801] Move `collapsible_else_if` to `pedantic` --- clippy_lints/src/collapsible_if.rs | 2 +- .../collapsible_if/collapsible_else_if.fixed | 2 +- .../collapsible_if/collapsible_else_if.rs | 2 +- tests/ui/collapsible_else_if.fixed | 22 ++----------------- tests/ui/collapsible_else_if.rs | 22 ++----------------- tests/ui/collapsible_else_if.stderr | 2 +- 6 files changed, 8 insertions(+), 44 deletions(-) diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index b13e307a3f9c..0efcb3c77ff6 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -76,7 +76,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.51.0"] pub COLLAPSIBLE_ELSE_IF, - style, + pedantic, "nested `else`-`if` expressions that can be collapsed (e.g., `else { if x { ... } }`)" } diff --git a/tests/ui-toml/collapsible_if/collapsible_else_if.fixed b/tests/ui-toml/collapsible_if/collapsible_else_if.fixed index ec45dfd2033a..213b56b786b1 100644 --- a/tests/ui-toml/collapsible_if/collapsible_else_if.fixed +++ b/tests/ui-toml/collapsible_if/collapsible_else_if.fixed @@ -1,5 +1,5 @@ #![allow(clippy::eq_op, clippy::nonminimal_bool)] -#![warn(clippy::collapsible_if)] +#![warn(clippy::collapsible_else_if)] #[rustfmt::skip] fn main() { diff --git a/tests/ui-toml/collapsible_if/collapsible_else_if.rs b/tests/ui-toml/collapsible_if/collapsible_else_if.rs index 54315a3c32bf..2d4c2c54031e 100644 --- a/tests/ui-toml/collapsible_if/collapsible_else_if.rs +++ b/tests/ui-toml/collapsible_if/collapsible_else_if.rs @@ -1,5 +1,5 @@ #![allow(clippy::eq_op, clippy::nonminimal_bool)] -#![warn(clippy::collapsible_if)] +#![warn(clippy::collapsible_else_if)] #[rustfmt::skip] fn main() { diff --git a/tests/ui/collapsible_else_if.fixed b/tests/ui/collapsible_else_if.fixed index e7439beef186..d85bbf189075 100644 --- a/tests/ui/collapsible_else_if.fixed +++ b/tests/ui/collapsible_else_if.fixed @@ -1,5 +1,5 @@ #![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_ifs)] -#![warn(clippy::collapsible_if, clippy::collapsible_else_if)] +#![warn(clippy::collapsible_else_if)] #[rustfmt::skip] fn main() { @@ -88,30 +88,12 @@ fn issue_7318() { } fn issue_13365() { - // all the `expect`s that we should fulfill + // ensure we fulfill `#[expect]` if true { } else { #[expect(clippy::collapsible_else_if)] if false {} } - - if true { - } else { - #[expect(clippy::style)] - if false {} - } - - if true { - } else { - #[expect(clippy::all)] - if false {} - } - - if true { - } else { - #[expect(warnings)] - if false {} - } } fn issue14799() { diff --git a/tests/ui/collapsible_else_if.rs b/tests/ui/collapsible_else_if.rs index 434ba3654f98..10aef2792adb 100644 --- a/tests/ui/collapsible_else_if.rs +++ b/tests/ui/collapsible_else_if.rs @@ -1,5 +1,5 @@ #![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_ifs)] -#![warn(clippy::collapsible_if, clippy::collapsible_else_if)] +#![warn(clippy::collapsible_else_if)] #[rustfmt::skip] fn main() { @@ -104,30 +104,12 @@ fn issue_7318() { } fn issue_13365() { - // all the `expect`s that we should fulfill + // ensure we fulfill `#[expect]` if true { } else { #[expect(clippy::collapsible_else_if)] if false {} } - - if true { - } else { - #[expect(clippy::style)] - if false {} - } - - if true { - } else { - #[expect(clippy::all)] - if false {} - } - - if true { - } else { - #[expect(warnings)] - if false {} - } } fn issue14799() { diff --git a/tests/ui/collapsible_else_if.stderr b/tests/ui/collapsible_else_if.stderr index ce1da593a8e9..98109099bae6 100644 --- a/tests/ui/collapsible_else_if.stderr +++ b/tests/ui/collapsible_else_if.stderr @@ -151,7 +151,7 @@ LL | | } | |_____^ help: collapse nested if block: `if false {}` error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:157:12 + --> tests/ui/collapsible_else_if.rs:139:12 | LL | } else { | ____________^ From 4d697d243302066fcb5cb6a9daacf7e6cdc891c7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Dec 2025 15:16:41 +0100 Subject: [PATCH 0548/3801] Remove "tidy" tool for `tests/rustdoc` testsuite --- src/tools/compiletest/src/common.rs | 9 - src/tools/compiletest/src/executor.rs | 9 - src/tools/compiletest/src/lib.rs | 28 +-- src/tools/compiletest/src/runtest.rs | 164 +----------------- .../compiletest/src/runtest/compute_diff.rs | 57 ------ src/tools/compiletest/src/runtest/rustdoc.rs | 4 +- src/tools/compiletest/src/rustdoc_gui_test.rs | 2 - 7 files changed, 8 insertions(+), 265 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 02b93593cbbd..ddbe8601de20 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -9,7 +9,6 @@ use camino::{Utf8Path, Utf8PathBuf}; use semver::Version; use crate::edition::Edition; -use crate::executor::ColorConfig; use crate::fatal; use crate::util::{Utf8PathBufExt, add_dylib_path, string_enum}; @@ -597,11 +596,6 @@ pub struct Config { /// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump. pub verbose: bool, - /// Whether to use colors in test output. - /// - /// Note: the exact control mechanism is delegated to [`colored`]. - pub color: ColorConfig, - /// Where to find the remote test client process, if we're using it. /// /// Note: this is *only* used for target platform executables created by `run-make` test @@ -623,9 +617,6 @@ pub struct Config { /// created in `$test_suite_build_root/rustfix_missing_coverage.txt` pub rustfix_coverage: bool, - /// Whether to run `tidy` (html-tidy) when a rustdoc test fails. - pub has_html_tidy: bool, - /// Whether to run `enzyme` autodiff tests. pub has_enzyme: bool, diff --git a/src/tools/compiletest/src/executor.rs b/src/tools/compiletest/src/executor.rs index 4dd4b1f85aaa..c800d11d6b2f 100644 --- a/src/tools/compiletest/src/executor.rs +++ b/src/tools/compiletest/src/executor.rs @@ -341,15 +341,6 @@ pub(crate) struct CollectedTestDesc { pub(crate) should_fail: ShouldFail, } -/// Whether console output should be colored or not. -#[derive(Copy, Clone, Default, Debug)] -pub enum ColorConfig { - #[default] - AutoColor, - AlwaysColor, - NeverColor, -} - /// Tests with `//@ should-fail` are tests of compiletest itself, and should /// be reported as successful if and only if they would have _failed_. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index ff4cd81d33ff..7c237102ed84 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -24,7 +24,6 @@ use core::panic; use std::collections::HashSet; use std::fmt::Write; use std::io::{self, ErrorKind}; -use std::process::{Command, Stdio}; use std::sync::{Arc, OnceLock}; use std::time::SystemTime; use std::{env, fs, vec}; @@ -43,7 +42,7 @@ use crate::common::{ }; use crate::directives::{AuxProps, DirectivesCache, FileDirectives}; use crate::edition::parse_edition; -use crate::executor::{CollectedTest, ColorConfig}; +use crate::executor::CollectedTest; /// Creates the `Config` instance for this invocation of compiletest. /// @@ -136,8 +135,9 @@ fn parse_config(args: Vec) -> Config { "overwrite stderr/stdout files instead of complaining about a mismatch", ) .optflag("", "fail-fast", "stop as soon as possible after any test fails") - .optopt("", "color", "coloring: auto, always, never", "WHEN") .optopt("", "target", "the target to build for", "TARGET") + // FIXME: Should be removed once `bootstrap` will be updated to not use this option. + .optopt("", "color", "coloring: auto, always, never", "WHEN") .optopt("", "host", "the host to build for", "HOST") .optopt("", "cdb", "path to CDB to use for CDB debuginfo tests", "PATH") .optopt("", "gdb", "path to GDB to use for GDB debuginfo tests", "PATH") @@ -276,12 +276,6 @@ fn parse_config(args: Vec) -> Config { let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from); let lldb_version = matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version); - let color = match matches.opt_str("color").as_deref() { - Some("auto") | None => ColorConfig::AutoColor, - Some("always") => ColorConfig::AlwaysColor, - Some("never") => ColorConfig::NeverColor, - Some(x) => panic!("argument for --color must be auto, always, or never, but found `{}`", x), - }; // FIXME: this is very questionable, we really should be obtaining LLVM version info from // `bootstrap`, and not trying to be figuring out that in `compiletest` by running the // `FileCheck` binary. @@ -306,16 +300,6 @@ fn parse_config(args: Vec) -> Config { let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions"); let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions"); let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode"); - let has_html_tidy = if mode == TestMode::Rustdoc { - Command::new("tidy") - .arg("--version") - .stdout(Stdio::null()) - .status() - .map_or(false, |status| status.success()) - } else { - // Avoid spawning an external command when we know html-tidy won't be used. - false - }; let has_enzyme = matches.opt_present("has-enzyme"); let filters = if mode == TestMode::RunMake { matches @@ -457,11 +441,9 @@ fn parse_config(args: Vec) -> Config { adb_device_status, verbose: matches.opt_present("verbose"), only_modified: matches.opt_present("only-modified"), - color, remote_test_client: matches.opt_str("remote-test-client").map(Utf8PathBuf::from), compare_mode, rustfix_coverage: matches.opt_present("rustfix-coverage"), - has_html_tidy, has_enzyme, channel: matches.opt_str("channel").unwrap(), git_hash: matches.opt_present("git-hash"), @@ -1146,10 +1128,6 @@ fn check_for_overlapping_test_paths(found_path_stems: &HashSet) { } fn early_config_check(config: &Config) { - if !config.has_html_tidy && config.mode == TestMode::Rustdoc { - warning!("`tidy` (html-tidy.org) is not installed; diffs will not be generated"); - } - if !config.profiler_runtime && config.mode == TestMode::CoverageRun { let actioned = if config.bless { "blessed" } else { "checked" }; warning!("profiler runtime is not available, so `.coverage` files won't be {actioned}"); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 54d6e0190ddc..f28f70ed453e 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1,12 +1,11 @@ use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use std::ffi::OsString; -use std::fs::{self, File, create_dir_all}; +use std::fs::{self, create_dir_all}; use std::hash::{DefaultHasher, Hash, Hasher}; use std::io::prelude::*; -use std::io::{self, BufReader}; use std::process::{Child, Command, ExitStatus, Output, Stdio}; -use std::{env, fmt, iter, str}; +use std::{env, fmt, io, iter, str}; use build_helper::fs::remove_and_create_dir_all; use camino::{Utf8Path, Utf8PathBuf}; @@ -23,9 +22,9 @@ use crate::directives::TestProps; use crate::errors::{Error, ErrorKind, load_errors}; use crate::output_capture::ConsoleOut; use crate::read2::{Truncated, read2_abbreviated}; -use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff}; +use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff}; use crate::util::{Utf8PathBufExt, add_dylib_path, static_regex}; -use crate::{ColorConfig, help, json, stamp_file_path, warning}; +use crate::{json, stamp_file_path}; // Helper modules that implement test running logic for each test suite. // tidy-alphabetical-start @@ -2162,161 +2161,6 @@ impl<'test> TestCx<'test> { if cfg!(target_os = "freebsd") { "ISO-8859-1" } else { "UTF-8" } } - fn compare_to_default_rustdoc(&self, out_dir: &Utf8Path) { - if !self.config.has_html_tidy { - return; - } - writeln!(self.stdout, "info: generating a diff against nightly rustdoc"); - - let suffix = - self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly"); - let compare_dir = output_base_dir(self.config, self.testpaths, Some(&suffix)); - remove_and_create_dir_all(&compare_dir).unwrap_or_else(|e| { - panic!("failed to remove and recreate output directory `{compare_dir}`: {e}") - }); - - // We need to create a new struct for the lifetimes on `config` to work. - let new_rustdoc = TestCx { - config: &Config { - // FIXME: use beta or a user-specified rustdoc instead of - // hardcoding the default toolchain - rustdoc_path: Some("rustdoc".into()), - // Needed for building auxiliary docs below - rustc_path: "rustc".into(), - ..self.config.clone() - }, - ..*self - }; - - let output_file = TargetLocation::ThisDirectory(new_rustdoc.aux_output_dir_name()); - let mut rustc = new_rustdoc.make_compile_args( - &new_rustdoc.testpaths.file, - output_file, - Emit::None, - AllowUnused::Yes, - LinkToAux::Yes, - Vec::new(), - ); - let aux_dir = new_rustdoc.aux_output_dir(); - new_rustdoc.build_all_auxiliary(&aux_dir, &mut rustc); - - let proc_res = new_rustdoc.document(&compare_dir, DocKind::Html); - if !proc_res.status.success() { - writeln!(self.stderr, "failed to run nightly rustdoc"); - return; - } - - #[rustfmt::skip] - let tidy_args = [ - "--new-blocklevel-tags", "rustdoc-search,rustdoc-toolbar,rustdoc-topbar", - "--indent", "yes", - "--indent-spaces", "2", - "--wrap", "0", - "--show-warnings", "no", - "--markup", "yes", - "--quiet", "yes", - "-modify", - ]; - let tidy_dir = |dir| { - for entry in walkdir::WalkDir::new(dir) { - let entry = entry.expect("failed to read file"); - if entry.file_type().is_file() - && entry.path().extension().and_then(|p| p.to_str()) == Some("html") - { - let status = - Command::new("tidy").args(&tidy_args).arg(entry.path()).status().unwrap(); - // `tidy` returns 1 if it modified the file. - assert!(status.success() || status.code() == Some(1)); - } - } - }; - tidy_dir(out_dir); - tidy_dir(&compare_dir); - - let pager = { - let output = Command::new("git").args(&["config", "--get", "core.pager"]).output().ok(); - output.and_then(|out| { - if out.status.success() { - Some(String::from_utf8(out.stdout).expect("invalid UTF8 in git pager")) - } else { - None - } - }) - }; - - let diff_filename = format!("build/tmp/rustdoc-compare-{}.diff", std::process::id()); - - if !write_filtered_diff( - self, - &diff_filename, - out_dir, - &compare_dir, - self.config.verbose, - |file_type, extension| { - file_type.is_file() && (extension == Some("html") || extension == Some("js")) - }, - ) { - return; - } - - match self.config.color { - ColorConfig::AlwaysColor => colored::control::set_override(true), - ColorConfig::NeverColor => colored::control::set_override(false), - _ => {} - } - - if let Some(pager) = pager { - let pager = pager.trim(); - if self.config.verbose { - writeln!(self.stderr, "using pager {}", pager); - } - let output = Command::new(pager) - // disable paging; we want this to be non-interactive - .env("PAGER", "") - .stdin(File::open(&diff_filename).unwrap()) - // Capture output and print it explicitly so it will in turn be - // captured by output-capture. - .output() - .unwrap(); - assert!(output.status.success()); - writeln!(self.stdout, "{}", String::from_utf8_lossy(&output.stdout)); - writeln!(self.stderr, "{}", String::from_utf8_lossy(&output.stderr)); - } else { - warning!("no pager configured, falling back to unified diff"); - help!( - "try configuring a git pager (e.g. `delta`) with \ - `git config --global core.pager delta`" - ); - let mut out = io::stdout(); - let mut diff = BufReader::new(File::open(&diff_filename).unwrap()); - let mut line = Vec::new(); - loop { - line.truncate(0); - match diff.read_until(b'\n', &mut line) { - Ok(0) => break, - Ok(_) => {} - Err(e) => writeln!(self.stderr, "ERROR: {:?}", e), - } - match String::from_utf8(line.clone()) { - Ok(line) => { - if line.starts_with('+') { - write!(&mut out, "{}", line.green()).unwrap(); - } else if line.starts_with('-') { - write!(&mut out, "{}", line.red()).unwrap(); - } else if line.starts_with('@') { - write!(&mut out, "{}", line.blue()).unwrap(); - } else { - out.write_all(line.as_bytes()).unwrap(); - } - } - Err(_) => { - write!(&mut out, "{}", String::from_utf8_lossy(&line).reversed()).unwrap(); - } - } - } - }; - } - fn get_lines(&self, path: &Utf8Path, mut other_files: Option<&mut Vec>) -> Vec { let content = fs::read_to_string(path.as_std_path()).unwrap(); let mut ignore = false; diff --git a/src/tools/compiletest/src/runtest/compute_diff.rs b/src/tools/compiletest/src/runtest/compute_diff.rs index 3363127b3ea3..8418dcbaf963 100644 --- a/src/tools/compiletest/src/runtest/compute_diff.rs +++ b/src/tools/compiletest/src/runtest/compute_diff.rs @@ -1,9 +1,4 @@ use std::collections::VecDeque; -use std::fs::{File, FileType}; - -use camino::Utf8Path; - -use crate::runtest::TestCx; #[derive(Debug, PartialEq)] pub enum DiffLine { @@ -109,55 +104,3 @@ pub(crate) fn write_diff(expected: &str, actual: &str, context_size: usize) -> S } output } - -/// Filters based on filetype and extension whether to diff a file. -/// -/// Returns whether any data was actually written. -pub(crate) fn write_filtered_diff( - cx: &TestCx<'_>, - diff_filename: &str, - out_dir: &Utf8Path, - compare_dir: &Utf8Path, - verbose: bool, - filter: Filter, -) -> bool -where - Filter: Fn(FileType, Option<&str>) -> bool, -{ - use std::io::{Read, Write}; - let mut diff_output = File::create(diff_filename).unwrap(); - let mut wrote_data = false; - for entry in walkdir::WalkDir::new(out_dir.as_std_path()) { - let entry = entry.expect("failed to read file"); - let extension = entry.path().extension().and_then(|p| p.to_str()); - if filter(entry.file_type(), extension) { - let expected_path = compare_dir - .as_std_path() - .join(entry.path().strip_prefix(&out_dir.as_std_path()).unwrap()); - let expected = if let Ok(s) = std::fs::read(&expected_path) { s } else { continue }; - let actual_path = entry.path(); - let actual = std::fs::read(&actual_path).unwrap(); - let diff = unified_diff::diff( - &expected, - &expected_path.to_str().unwrap(), - &actual, - &actual_path.to_str().unwrap(), - 3, - ); - wrote_data |= !diff.is_empty(); - diff_output.write_all(&diff).unwrap(); - } - } - - if !wrote_data { - writeln!(cx.stdout, "note: diff is identical to nightly rustdoc"); - assert!(diff_output.metadata().unwrap().len() == 0); - return false; - } else if verbose { - writeln!(cx.stderr, "printing diff:"); - let mut buf = Vec::new(); - diff_output.read_to_end(&mut buf).unwrap(); - std::io::stderr().lock().write_all(&mut buf).unwrap(); - } - true -} diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index a4558de5f1c0..3c80521e51ec 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -28,9 +28,7 @@ impl TestCx<'_> { } let res = self.run_command_to_procres(&mut cmd); if !res.status.success() { - self.fatal_proc_rec_general("htmldocck failed!", None, &res, || { - self.compare_to_default_rustdoc(&out_dir); - }); + self.fatal_proc_rec("htmldocck failed!", &res); } } } diff --git a/src/tools/compiletest/src/rustdoc_gui_test.rs b/src/tools/compiletest/src/rustdoc_gui_test.rs index f6d026ab9cfd..c30f3d1e10ea 100644 --- a/src/tools/compiletest/src/rustdoc_gui_test.rs +++ b/src/tools/compiletest/src/rustdoc_gui_test.rs @@ -108,11 +108,9 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { adb_test_dir: Default::default(), adb_device_status: Default::default(), verbose: Default::default(), - color: Default::default(), remote_test_client: Default::default(), compare_mode: Default::default(), rustfix_coverage: Default::default(), - has_html_tidy: Default::default(), has_enzyme: Default::default(), channel: Default::default(), git_hash: Default::default(), From 450916305fe8482dfe2f192c0d288b0490d3a517 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 11 Jun 2025 21:29:06 +0200 Subject: [PATCH 0549/3801] Put negative implementors first and apply same ordering logic to foreign implementors --- src/librustdoc/formats/mod.rs | 4 ++ src/librustdoc/html/render/print_item.rs | 43 ++++++++++++++++-- src/librustdoc/html/render/write_shared.rs | 45 +++++++++++++++++-- .../html/render/write_shared/tests.rs | 6 +-- src/librustdoc/html/static/css/rustdoc.css | 3 ++ src/librustdoc/html/static/js/main.js | 39 ++++++++++++---- src/librustdoc/html/static/js/rustdoc.d.ts | 2 +- 7 files changed, 122 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs index 2e8b5d9f5948..80c110ec07f5 100644 --- a/src/librustdoc/formats/mod.rs +++ b/src/librustdoc/formats/mod.rs @@ -76,4 +76,8 @@ impl Impl { }; true } + + pub(crate) fn is_negative_trait_impl(&self) -> bool { + self.inner_impl().is_negative_trait_impl() + } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 0c511738d7c8..47e587626352 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -646,6 +646,27 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp }) } +/// Struct used to handle insertion of "negative impl" marker in the generated DOM. +/// +/// This marker appears once in all trait impl lists to divide negative impls from positive impls. +struct NegativeMarker { + inserted_negative_marker: bool, +} + +impl NegativeMarker { + fn new() -> Self { + Self { inserted_negative_marker: false } + } + + fn insert_if_needed(&mut self, w: &mut fmt::Formatter<'_>, implementor: &Impl) -> fmt::Result { + if !self.inserted_negative_marker && !implementor.is_negative_trait_impl() { + write!(w, "

")?; + self.inserted_negative_marker = true; + } + Ok(()) + } +} + fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt::Display { fmt::from_fn(|w| { let tcx = cx.tcx(); @@ -1072,7 +1093,9 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: "
", ) )?; + let mut negative_marker = NegativeMarker::new(); for implementor in concrete { + negative_marker.insert_if_needed(w, implementor)?; write!(w, "{}", render_implementor(cx, implementor, it, &implementor_dups, &[]))?; } w.write_str("
")?; @@ -1088,7 +1111,9 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: "
", ) )?; + let mut negative_marker = NegativeMarker::new(); for implementor in synthetic { + negative_marker.insert_if_needed(w, implementor)?; write!( w, "{}", @@ -2302,11 +2327,18 @@ where } #[derive(PartialEq, Eq)] -struct ImplString(String); +struct ImplString { + rendered: String, + is_negative: bool, +} impl ImplString { fn new(i: &Impl, cx: &Context<'_>) -> ImplString { - ImplString(format!("{}", print_impl(i.inner_impl(), false, cx))) + let impl_ = i.inner_impl(); + ImplString { + is_negative: impl_.is_negative_trait_impl(), + rendered: format!("{}", print_impl(impl_, false, cx)), + } } } @@ -2318,7 +2350,12 @@ impl PartialOrd for ImplString { impl Ord for ImplString { fn cmp(&self, other: &Self) -> Ordering { - compare_names(&self.0, &other.0) + // We sort negative impls first. + match (self.is_negative, other.is_negative) { + (false, true) => Ordering::Greater, + (true, false) => Ordering::Less, + _ => compare_names(&self.rendered, &other.rendered), + } } } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 6bf116c3b75a..ca33531174b1 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -14,6 +14,7 @@ //! or contains "invocation-specific". use std::cell::RefCell; +use std::cmp::Ordering; use std::ffi::{OsStr, OsString}; use std::fs::File; use std::io::{self, Write as _}; @@ -47,6 +48,7 @@ use crate::formats::item_type::ItemType; use crate::html::format::{print_impl, print_path}; use crate::html::layout; use crate::html::render::ordered_json::{EscapedJson, OrderedJson}; +use crate::html::render::print_item::compare_names; use crate::html::render::search_index::{SerializedSearchIndex, build_index}; use crate::html::render::sorted_template::{self, FileFormat, SortedTemplate}; use crate::html::render::{AssocItemLink, ImplRenderingParameters, StylePath}; @@ -667,7 +669,7 @@ impl TraitAliasPart { fn blank() -> SortedTemplate<::FileFormat> { SortedTemplate::from_before_after( r"(function() { - var implementors = Object.fromEntries([", + const implementors = Object.fromEntries([", r"]); if (window.register_implementors) { window.register_implementors(implementors); @@ -720,10 +722,12 @@ impl TraitAliasPart { { None } else { + let impl_ = imp.inner_impl(); Some(Implementor { - text: print_impl(imp.inner_impl(), false, cx).to_string(), + text: print_impl(impl_, false, cx).to_string(), synthetic: imp.inner_impl().kind.is_auto(), types: collect_paths_for_type(&imp.inner_impl().for_, cache), + is_negative: impl_.is_negative_trait_impl(), }) } }) @@ -742,8 +746,15 @@ impl TraitAliasPart { } path.push(format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1])); - let part = OrderedJson::array_sorted( - implementors.map(|implementor| OrderedJson::serialize(implementor).unwrap()), + let mut implementors = implementors.collect::>(); + implementors.sort_unstable(); + + let part = OrderedJson::array_unsorted( + implementors + .iter() + .map(OrderedJson::serialize) + .collect::, _>>() + .unwrap(), ); path_parts.push(path, OrderedJson::array_unsorted([crate_name_json, &part])); } @@ -751,10 +762,12 @@ impl TraitAliasPart { } } +#[derive(Eq)] struct Implementor { text: String, synthetic: bool, types: Vec, + is_negative: bool, } impl Serialize for Implementor { @@ -764,6 +777,7 @@ impl Serialize for Implementor { { let mut seq = serializer.serialize_seq(None)?; seq.serialize_element(&self.text)?; + seq.serialize_element(if self.is_negative { &1 } else { &0 })?; if self.synthetic { seq.serialize_element(&1)?; seq.serialize_element(&self.types)?; @@ -772,6 +786,29 @@ impl Serialize for Implementor { } } +impl PartialEq for Implementor { + fn eq(&self, other: &Self) -> bool { + self.cmp(other) == Ordering::Equal + } +} + +impl PartialOrd for Implementor { + fn partial_cmp(&self, other: &Self) -> Option { + Some(Ord::cmp(self, other)) + } +} + +impl Ord for Implementor { + fn cmp(&self, other: &Self) -> Ordering { + // We sort negative impls first. + match (self.is_negative, other.is_negative) { + (false, true) => Ordering::Greater, + (true, false) => Ordering::Less, + _ => compare_names(&self.text, &other.text), + } + } +} + /// Collect the list of aliased types and their aliases. /// /// diff --git a/src/librustdoc/html/render/write_shared/tests.rs b/src/librustdoc/html/render/write_shared/tests.rs index 1989a1f87aae..48d592c22f6f 100644 --- a/src/librustdoc/html/render/write_shared/tests.rs +++ b/src/librustdoc/html/render/write_shared/tests.rs @@ -68,7 +68,7 @@ fn trait_alias_template() { assert_eq!( but_last_line(&template.to_string()), r#"(function() { - var implementors = Object.fromEntries([]); + const implementors = Object.fromEntries([]); if (window.register_implementors) { window.register_implementors(implementors); } else { @@ -80,7 +80,7 @@ fn trait_alias_template() { assert_eq!( but_last_line(&template.to_string()), r#"(function() { - var implementors = Object.fromEntries([["a"]]); + const implementors = Object.fromEntries([["a"]]); if (window.register_implementors) { window.register_implementors(implementors); } else { @@ -92,7 +92,7 @@ fn trait_alias_template() { assert_eq!( but_last_line(&template.to_string()), r#"(function() { - var implementors = Object.fromEntries([["a"],["b"]]); + const implementors = Object.fromEntries([["a"],["b"]]); if (window.register_implementors) { window.register_implementors(implementors); } else { diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 7f4785694849..36f44a8072af 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -2976,6 +2976,9 @@ in src-script.js and main.js { margin-bottom: 0.75em; } +.negative-marker { + display: none; +} .variants > .docblock, .implementors-toggle > .docblock, diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index dff40485e9a9..fb6b70492181 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -800,21 +800,34 @@ function preLoadCss(cssUrl) { // window.register_implementors = imp => { - const implementors = document.getElementById("implementors-list"); - const synthetic_implementors = document.getElementById("synthetic-implementors-list"); + /** Takes an ID as input and returns a list of two elements. The first element is the DOM + * element with the given ID and the second is the "negative marker", meaning the location + * between the negative and non-negative impls. + * + * @param {string} id: ID of the DOM element. + * + * @return {[HTMLElement|null, HTMLElement|null]} + */ + function implementorsElems(id) { + const elem = document.getElementById(id); + return [elem, elem ? elem.querySelector(".negative-marker") : null]; + } + const implementors = implementorsElems("implementors-list"); + const synthetic_implementors = implementorsElems("synthetic-implementors-list"); const inlined_types = new Set(); const TEXT_IDX = 0; - const SYNTHETIC_IDX = 1; - const TYPES_IDX = 2; + const IS_NEG_IDX = 1; + const SYNTHETIC_IDX = 2; + const TYPES_IDX = 3; - if (synthetic_implementors) { + if (synthetic_implementors[0]) { // This `inlined_types` variable is used to avoid having the same implementation // showing up twice. For example "String" in the "Sync" doc page. // // By the way, this is only used by and useful for traits implemented automatically // (like "Send" and "Sync"). - onEachLazy(synthetic_implementors.getElementsByClassName("impl"), el => { + onEachLazy(synthetic_implementors[0].getElementsByClassName("impl"), el => { const aliases = el.getAttribute("data-aliases"); if (!aliases) { return; @@ -827,7 +840,7 @@ function preLoadCss(cssUrl) { } // @ts-expect-error - let currentNbImpls = implementors.getElementsByClassName("impl").length; + let currentNbImpls = implementors[0].getElementsByClassName("impl").length; // @ts-expect-error const traitName = document.querySelector(".main-heading h1 > .trait").textContent; const baseIdName = "impl-" + traitName + "-"; @@ -884,8 +897,16 @@ function preLoadCss(cssUrl) { addClass(display, "impl"); display.appendChild(anchor); display.appendChild(code); - // @ts-expect-error - list.appendChild(display); + + // If this is a negative implementor, we put it into the right location (just + // before the negative impl marker). + if (struct[IS_NEG_IDX]) { + // @ts-expect-error + list[1].before(display); + } else { + // @ts-expect-error + list[0].appendChild(display); + } currentNbImpls += 1; } } diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 18d3b6a455d3..60df4fc10b8c 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -520,7 +520,7 @@ declare namespace rustdoc { * Provided by generated `trait.impl` files. */ type Implementors = { - [key: string]: Array<[string, number, Array]> + [key: string]: Array<[string, 0|1, number, Array]> } type TypeImpls = { From 985178dacf81d2baa21d0261c2cc85b374d0dd8c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 11 Jun 2025 22:19:47 +0200 Subject: [PATCH 0550/3801] Add GUI test to ensure that negative impls are correctly sorted --- tests/rustdoc-gui/implementors.goml | 47 +++++++++++++++---- .../rustdoc-gui/src/lib2/implementors/lib.rs | 5 ++ tests/rustdoc-gui/src/lib2/lib.rs | 3 ++ 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/tests/rustdoc-gui/implementors.goml b/tests/rustdoc-gui/implementors.goml index b39b95c1a9bf..99fb9b9aff54 100644 --- a/tests/rustdoc-gui/implementors.goml +++ b/tests/rustdoc-gui/implementors.goml @@ -2,18 +2,45 @@ // have the same display than the "local" ones. go-to: "file://" + |DOC_PATH| + "/implementors/trait.Whatever.html" assert: "#implementors-list" -// There are supposed to be two implementors listed. -assert-count: ("#implementors-list .impl", 2) +// There are supposed to be four implementors listed. +assert-count: ("#implementors-list .impl", 4) +// There are supposed to be two non-negative implementors. +assert-count: ("#implementors-list .negative-marker ~ *", 2) // Now we check that both implementors have an anchor, an ID and a similar DOM. -assert: ("#implementors-list .impl:nth-child(1) > a.anchor") -assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever-for-Struct"}) -assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever-for-Struct"}) -assert: "#implementors-list .impl:nth-child(1) > .code-header" +define-function: ( + "check-dom", + [id], + block { + assert-attribute: (|id| + " > a.anchor", {"href": |id|}) + assert: |id| + " > .code-header" + }, +) -assert: ("#implementors-list .impl:nth-child(2) > a.anchor") -assert-attribute: ("#implementors-list .impl:nth-child(2)", {"id": "impl-Whatever-1"}) -assert-attribute: ("#implementors-list .impl:nth-child(2) > a.anchor", {"href": "#impl-Whatever-1"}) -assert: "#implementors-list .impl:nth-child(2) > .code-header" +call-function: ("check-dom", {"id": "#impl-Whatever-for-Struct2"}) +call-function: ("check-dom", {"id": "#impl-Whatever-2"}) +call-function: ("check-dom", {"id": "#impl-Whatever-for-Struct"}) +call-function: ("check-dom", {"id": "#impl-Whatever-3"}) + +// Ensure that negative impl are sorted first. +assert-property: ( + "#implementors-list > *:nth-child(1) > h3", + {"textContent": "impl !Whatever for Struct2"}, +) +assert-property: ( + "#implementors-list > *:nth-child(2) > h3", + {"textContent": "impl !Whatever for StructToImplOnReexport"}, +) +// Third one is the negative marker. +assert-attribute: ("#implementors-list > *:nth-child(3)", {"class": "negative-marker"}) +// This one is a `` so the selector is a bit different. +assert-property: ( + "#implementors-list > *:nth-child(4) section > h3", + {"textContent": "impl Whatever for Struct"}, +) +assert-property: ( + "#implementors-list > *:nth-child(5) > h3", + {"textContent": "impl Whatever for Foo"}, +) go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HasEmptyTraits.html" compare-elements-position-near-false: ( diff --git a/tests/rustdoc-gui/src/lib2/implementors/lib.rs b/tests/rustdoc-gui/src/lib2/implementors/lib.rs index 2842ac50dc1e..f08182003927 100644 --- a/tests/rustdoc-gui/src/lib2/implementors/lib.rs +++ b/tests/rustdoc-gui/src/lib2/implementors/lib.rs @@ -1,3 +1,5 @@ +#![feature(negative_impls)] + pub trait Whatever { type Foo; @@ -5,11 +7,14 @@ pub trait Whatever { } pub struct Struct; +pub struct Struct2; impl Whatever for Struct { type Foo = u8; } +impl !Whatever for Struct2 {} + impl http::HttpTrait for Struct {} mod traits { diff --git a/tests/rustdoc-gui/src/lib2/lib.rs b/tests/rustdoc-gui/src/lib2/lib.rs index 400488cbe857..b87fdeea89da 100644 --- a/tests/rustdoc-gui/src/lib2/lib.rs +++ b/tests/rustdoc-gui/src/lib2/lib.rs @@ -1,6 +1,7 @@ // ignore-tidy-linelength #![feature(doc_cfg)] +#![feature(negative_impls)] pub mod another_folder; pub mod another_mod; @@ -60,6 +61,8 @@ impl implementors::Whatever for Foo { type Foo = u32; } +impl !implementors::Whatever for StructToImplOnReexport {} + #[doc(inline)] pub use implementors::TraitToReexport; From 13091ddc932be37c0ad3db7581e5f7776cf429d0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 24 Jun 2025 17:05:43 +0200 Subject: [PATCH 0551/3801] Make implementors list visible only when filled --- src/librustdoc/html/static/css/noscript.css | 4 ++++ src/librustdoc/html/static/css/rustdoc.css | 6 ++++++ src/librustdoc/html/static/js/main.js | 14 ++++++++++---- tests/rustdoc-gui/implementors.goml | 7 ++++++- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index 5c02e2eb26a3..6b80d3e7bbee 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -29,6 +29,10 @@ nav.sub { display: none; } +#synthetic-implementors-list, #implementors-list { + display: block; +} + /* Begin: styles for themes Keep the default light and dark themes synchronized with the ones in rustdoc.css */ diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 36f44a8072af..a5e43e1d7d19 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1158,6 +1158,12 @@ div.where { margin-left: calc(var(--docblock-indent) + var(--impl-items-indent)); } +#synthetic-implementors-list, #implementors-list { + /* To prevent layout shift when loading the page with extra implementors being loaded + from JS, we hide the list until it's complete. */ + display: none; +} + .item-info code { font-size: 0.875rem; } diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index fb6b70492181..72d7e6131814 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -813,7 +813,7 @@ function preLoadCss(cssUrl) { return [elem, elem ? elem.querySelector(".negative-marker") : null]; } const implementors = implementorsElems("implementors-list"); - const synthetic_implementors = implementorsElems("synthetic-implementors-list"); + const syntheticImplementors = implementorsElems("synthetic-implementors-list"); const inlined_types = new Set(); const TEXT_IDX = 0; @@ -821,13 +821,13 @@ function preLoadCss(cssUrl) { const SYNTHETIC_IDX = 2; const TYPES_IDX = 3; - if (synthetic_implementors[0]) { + if (syntheticImplementors[0]) { // This `inlined_types` variable is used to avoid having the same implementation // showing up twice. For example "String" in the "Sync" doc page. // // By the way, this is only used by and useful for traits implemented automatically // (like "Send" and "Sync"). - onEachLazy(synthetic_implementors[0].getElementsByClassName("impl"), el => { + onEachLazy(syntheticImplementors[0].getElementsByClassName("impl"), el => { const aliases = el.getAttribute("data-aliases"); if (!aliases) { return; @@ -862,7 +862,7 @@ function preLoadCss(cssUrl) { struct_loop: for (const struct of structs) { - const list = struct[SYNTHETIC_IDX] ? synthetic_implementors : implementors; + const list = struct[SYNTHETIC_IDX] ? syntheticImplementors : implementors; // The types list is only used for synthetic impls. // If this changes, `main.js` and `write_shared.rs` both need changed. @@ -910,6 +910,12 @@ function preLoadCss(cssUrl) { currentNbImpls += 1; } } + if (implementors[0]) { + implementors[0].style.display = "block"; + } + if (syntheticImplementors[0]) { + syntheticImplementors[0].style.display = "block"; + } }; if (window.pending_implementors) { window.register_implementors(window.pending_implementors); diff --git a/tests/rustdoc-gui/implementors.goml b/tests/rustdoc-gui/implementors.goml index 99fb9b9aff54..d4542c6f7817 100644 --- a/tests/rustdoc-gui/implementors.goml +++ b/tests/rustdoc-gui/implementors.goml @@ -1,7 +1,7 @@ // The goal of this test is to check that the external trait implementors, generated with JS, // have the same display than the "local" ones. go-to: "file://" + |DOC_PATH| + "/implementors/trait.Whatever.html" -assert: "#implementors-list" +wait-for-css: ("#implementors-list", {"display": "block"}) // There are supposed to be four implementors listed. assert-count: ("#implementors-list .impl", 4) // There are supposed to be two non-negative implementors. @@ -66,3 +66,8 @@ assert-count: ("#implementors-list .impl", 1) go-to: "file://" + |DOC_PATH| + "/http/trait.HttpTrait.html" assert-count: ("#implementors-list .impl", 1) assert-attribute: ("#implementors-list .impl a.trait", {"href": "../http/trait.HttpTrait.html"}) + +// Now we check that if JS is disabled, the implementors list will be visible. +javascript: false +reload: +assert-css: ("#implementors-list", {"display": "block"}) From 183048c83ecd14e7ebcb60a9bca9ca8cf16374eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 10 Dec 2025 15:06:08 +0100 Subject: [PATCH 0552/3801] update docs --- .../rustc-dev-guide/src/bug-fix-procedure.md | 89 ++++++++++--------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md index 92488e8daeab..ab5e0cd68cfa 100644 --- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md +++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md @@ -91,40 +91,46 @@ future-compatibility warnings. These are a special category of lint warning. Adding a new future-compatibility warning can be done as follows. ```rust -// 1. Define the lint in `compiler/rustc_middle/src/lint/builtin.rs`: +// 1. Define the lint in `compiler/rustc_lint/src/builtin.rs` and +// add the metadata for the future incompatibility: declare_lint! { - pub YOUR_ERROR_HERE, + pub YOUR_LINT_HERE, Warn, "illegal use of foo bar baz" -} - -// 2. Add to the list of HardwiredLints in the same file: -impl LintPass for HardwiredLints { - fn get_lints(&self) -> LintArray { - lint_array!( - .., - YOUR_ERROR_HERE - ) - } -} - -// 3. Register the lint in `compiler/rustc_lint/src/lib.rs`: -store.register_future_incompatible(sess, vec![ - ..., - FutureIncompatibleInfo { - id: LintId::of(YOUR_ERROR_HERE), + @future_incompatible = FutureIncompatibleInfo { reason: fcw!(FutureReleaseError #1234) // your tracking issue here! }, -]); +} + +// 2. Add a decidacted lint pass for it. +// This step can be skipped if you emit the lint as part of an existing pass. + +#[derive(Default)] +pub struct MyLintPass { + ... +} + +impl {Early,Late}LintPass for MyLintPass { + ... +} + +impl_lint_pass!(MyLintPass => [YOUR_LINT_HERE]); + +// 3. emit the lint somewhere in your lint pass: +cx.emit_span_lint( + YOUR_LINT_HERE, + pat.span, + // some diagnostic struct + MyDiagnostic { + ... + }, +); -// 4. Report the lint: -tcx.lint_node( - lint::builtin::YOUR_ERROR_HERE, - path_id, - binding.span, - format!("some helper message here")); ``` +Finally, register the lint in `compiler/rustc_lint/src/lib.rs`. +There are many examples in that file that already show how to do so. + #### Helpful techniques It can often be challenging to filter out new warnings from older, pre-existing @@ -221,7 +227,10 @@ The first reference you will likely find is the lint definition [in declare_lint! { pub OVERLAPPING_INHERENT_IMPLS, Deny, // this may also say Warning - "two overlapping inherent impls define an item with the same name were erroneously allowed" + "two overlapping inherent impls define an item with the same name were erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reason: fcw!(FutureReleaseError #1234), // your tracking issue here! + }, } ``` @@ -231,19 +240,6 @@ the file as [part of a `lint_array!`][lintarraysource]; remove it too. [lintarraysource]: https://github.com/rust-lang/rust/blob/085d71c3efe453863739c1fb68fd9bd1beff214f/src/librustc/lint/builtin.rs#L252-L290 -Next, you see [a reference to `OVERLAPPING_INHERENT_IMPLS` in -`rustc_lint/src/lib.rs`][futuresource]. This is defining the lint as a "future -compatibility lint": - -```rust -FutureIncompatibleInfo { - id: LintId::of(OVERLAPPING_INHERENT_IMPLS), - reason: fcw!(FutureReleaseError #1234), // your tracking issue here! -}, -``` - -Remove this too. - #### Add the lint to the list of removed lints. In `compiler/rustc_lint/src/lib.rs` there is a list of "renamed and removed lints". @@ -269,6 +265,8 @@ self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS, msg); ``` +You'll also often find `node_span_lint` used for this. + We want to convert this into an error. In some cases, there may be an existing error for this scenario. In others, we will need to allocate a fresh diagnostic code. [Instructions for allocating a fresh diagnostic @@ -285,6 +283,17 @@ struct_span_code_err!(self.dcx(), self.tcx.span_of_impl(item1).unwrap(), E0592, .emit(); ``` +Or better: a structured diagnostic like this: + +```rust +#[derive(Diagnostic)] +struct MyDiagnostic { + #[label] + span: Span, + ... +} +``` + #### Update tests Finally, run the test suite. These should be some tests that used to reference From 99df3375e33f9da54764d87764ada1fb6783087a Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Thu, 11 Dec 2025 00:35:48 +0900 Subject: [PATCH 0553/3801] fix: Support dyn compatibility for old toolchains without `MetaSized` --- .../crates/hir-ty/src/dyn_compatibility.rs | 24 ++++---- .../hir-ty/src/tests/regression/new_solver.rs | 56 +++++++++++++++++++ 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index 506c4abc8377..64b15eb017a6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs @@ -427,9 +427,14 @@ fn receiver_is_dispatchable<'db>( }; let meta_sized_did = lang_items.MetaSized; - let Some(meta_sized_did) = meta_sized_did else { - return false; - }; + + // TODO: This is for supporting dyn compatibility for toolchains doesn't contain `MetaSized` + // trait. Uncomment and short circuit here once `MINIMUM_SUPPORTED_TOOLCHAIN_VERSION` + // become > 1.88.0 + // + // let Some(meta_sized_did) = meta_sized_did else { + // return false; + // }; // Type `U` // FIXME: That seems problematic to fake a generic param like that? @@ -450,17 +455,16 @@ fn receiver_is_dispatchable<'db>( }); let trait_predicate = TraitRef::new_from_args(interner, trait_.into(), args); - let meta_sized_predicate = - TraitRef::new(interner, meta_sized_did.into(), [unsized_self_ty]); + let meta_sized_predicate = meta_sized_did + .map(|did| TraitRef::new(interner, did.into(), [unsized_self_ty]).upcast(interner)); ParamEnv { clauses: Clauses::new_from_iter( interner, - generic_predicates.iter_identity_copied().chain([ - unsize_predicate.upcast(interner), - trait_predicate.upcast(interner), - meta_sized_predicate.upcast(interner), - ]), + generic_predicates + .iter_identity_copied() + .chain([unsize_predicate.upcast(interner), trait_predicate.upcast(interner)]) + .chain(meta_sized_predicate), ), } }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs index 5c1f85cb2a95..e11cc85e7ff1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs @@ -226,6 +226,62 @@ fn debug(_: &dyn Foo) {} impl Foo for i32 {} +fn main() { + debug(&1); +}"#, + ); + + // toolchains <= 1.88.0, before sized-hierarchy. + check_no_mismatches( + r#" +#[lang = "sized"] +pub trait Sized {} + +#[lang = "unsize"] +pub trait Unsize {} + +#[lang = "coerce_unsized"] +pub trait CoerceUnsized {} + +impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} + +impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} + +impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} + +impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} + +impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} + +impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a T {} + +impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} + +impl, U: ?Sized> CoerceUnsized<*const U> for *mut T {} + +impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} + +#[lang = "dispatch_from_dyn"] +pub trait DispatchFromDyn {} + +impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} + +impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} + +impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} + +impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} + +trait Foo { + fn bar(&self) -> u32 { + 0xCAFE + } +} + +fn debug(_: &dyn Foo) {} + +impl Foo for i32 {} + fn main() { debug(&1); }"#, From 8747b0abf1576144f49bbb84d47705e92417543d Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Thu, 11 Dec 2025 00:36:28 +0900 Subject: [PATCH 0554/3801] Bring back `MINIMUM_SUPPORTED_TOOLCHAIN_VERSION` to `1.78.0` --- src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 3dea21e56485..6ae527abb1ff 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -14,7 +14,7 @@ extern crate ra_ap_rustc_type_ir as rustc_type_ir; /// Any toolchain less than this version will likely not work with rust-analyzer built from this revision. pub const MINIMUM_SUPPORTED_TOOLCHAIN_VERSION: semver::Version = semver::Version { major: 1, - minor: 90, + minor: 78, patch: 0, pre: semver::Prerelease::EMPTY, build: semver::BuildMetadata::EMPTY, From f4ee932b88cc67478e2abff48a766a2b9590d27d Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 10 Dec 2025 16:05:42 +0000 Subject: [PATCH 0555/3801] initial const generics docs --- src/doc/rustc-dev-guide/src/SUMMARY.md | 1 + src/doc/rustc-dev-guide/src/const-generics.md | 222 ++++++++++++++++++ .../src/hir/ambig-unambig-ty-and-consts.md | 66 +++++- .../rustc-dev-guide/src/solve/invariants.md | 5 + 4 files changed, 285 insertions(+), 9 deletions(-) create mode 100644 src/doc/rustc-dev-guide/src/const-generics.md diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index c136d37160c5..cdf61390baf0 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -191,6 +191,7 @@ - [HIR Type checking](./hir-typeck/summary.md) - [Coercions](./hir-typeck/coercions.md) - [Method lookup](./hir-typeck/method-lookup.md) +- [Const Generics](./const-generics.md) - [Opaque types](./opaque-types-type-alias-impl-trait.md) - [Inference details](./opaque-types-impl-trait-inference.md) - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md) diff --git a/src/doc/rustc-dev-guide/src/const-generics.md b/src/doc/rustc-dev-guide/src/const-generics.md new file mode 100644 index 000000000000..ffde2051e07d --- /dev/null +++ b/src/doc/rustc-dev-guide/src/const-generics.md @@ -0,0 +1,222 @@ +# Const Generics + +## Kinds of const arguments + +Most of the kinds of `ty::Const` that exist have direct parallels to kinds of types that exist, for example `ConstKind::Param` is equivalent to `TyKind::Param`. + +The main interesting points here are: +- [`ConstKind::Unevaluated`], this is equivalent to `TyKind::Alias` and in the long term should be renamed (as well as introducing an `AliasConstKind` to parallel `ty::AliasKind`). +- [`ConstKind::Value`], this is the final value of a `ty::Const` after monomorphization. This is similar-ish to fully concrete to things like `TyKind::Str` or `TyKind::ADT`. + +For a complete list of *all* kinds of const arguments and how they are actually represented in the type system, see the [`ConstKind`] type. + +Inference Variables are quite boring and treated equivalently to type inference variables almost everywhere. Const Parameters are also similarly boring and equivalent to uses of type parameters almost everywhere. However, there are some interesting subtleties with how they are handled during parsing, name resolution, and AST lowering: [ambig-unambig-ty-and-consts]. + +## Anon Consts + +Anon Consts (short for anonymous const items) are how arbitrary expression are represented in const generics, for example an array length of `1 + 1` or `foo()` or even just `0`. These are unique to const generics and have no real type equivalent. + +### Desugaring + +```rust +struct Foo; +type Alias = [u8; 1 + 1]; +``` + +In this example we have a const argument of `1 + 1` (the array length) which is represented as an *anon const*. The desugaring would look something like: +```rust +struct Foo; + +const ANON: usize = 1 + 1; +type Alias = [u8; ANON]; +``` + +Where the array length in `[u8; ANON]` isn't itself an anon const containing a usage of `ANON`, but a kind of "direct" usage of the `ANON` const item ([`ConstKind::Unevaluated`]). + +Anon consts do not inherit any generic parameters of the item they are inside of: +```rust +struct Foo; +type Alias = [T; 1 + 1]; + +// Desugars To; + +struct Foo; + +const ANON: usize = 1 + 1; +type Alias = [T; ANON]; +``` + +Note how the `ANON` const has no generic parameters or where clauses, even though `Alias` has both a type parameter `T` and a where clauses `T: Sized`. This desugaring is part of how we enforce that anon consts can't make use of generic parameters. + +While it's useful to think of anon consts as being desugared to real const items, the compiler does not actually implement things this way. + +At AST lowering time we do not yet know the *type* of the anon const, so we can't desugar to a real HIR item with an explicitly written type. To work around this we have [`DefKind::AnonConst`] and [`hir::Node::AnonConst`] which are used to represent these anonymous const items that can't actually be desugared. + +The types of these anon consts are obtainable from the [`type_of`] query. However, the `type_of` query does not actually contain logic for computing the type (infact it just ICEs when called), instead HIR Ty lowering is responsible for *feeding* the value of the `type_of` query for any anon consts that get lowered. HIR Ty lowering can determine the type of the anon const by looking at the type of the Const Parameter that the anon const is an argument to. + +TODO: write a chapter on query feeding and link it here + +In some sense the desugarings from the previous examples are to: +```rust +struct Foo; +type Alias = [u8; 1 + 1]; + +// sort-of desugars to psuedo-rust: +struct Foo; + +const ANON = 1 + 1; +type Alias = [u8; ANON]; +``` + +Where when we go through HIR ty lowering for the array type in `Alias`, we will lower the array length too and feed `type_of(ANON) -> usize`. Effectively setting the type of the `ANON` const item during some later part of the compiler rather than when constructing the HIR. + +After all of this desugaring has taken place the final representation in the type system (ie as a `ty::Const`) is a `ConstKind::Unevaluated` with the `DefId` of the `AnonConst`. This is equivalent to how we would representa a usage of an actual const item if we were to represent them without going through an anon const (e.g. when `min_generic_const_args` is enabled). + +This allows the representation for const "aliases" to be the same as the representation of `TyKind::Alias`. Having a proper HIR body also allows for a *lot* of code re-use, e.g. we can reuse HIR typechecking and all of the lowering steps to MIR where we can then reuse const eval. + +### Enforcing lack of Generic Parameters + +There are three ways that we enforce anon consts can't use generic parameters: +1. Name Resolution will not resolve paths to generic parameters when inside of an anon const +2. HIR Ty lowering will error when a `Self` type alias to a type referencing generic parameters is encountered inside of an anon const +3. Anon Consts do not inherit where clauses or generics from their parent definition (ie [`generics_of`] does not contain a parent for anon consts) + +```rust +// *1* Errors in name resolution +type Alias = [u8; N + 1]; +//~^ ERROR: generic parameters may not be used in const operations + +// *2* Errors in HIR Ty lowering: +struct Foo(T); +impl Foo { + fn assoc() -> [u8; { let a: Self; 0 }] {} + //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants +} + +// *3* Errors due to lack of where clauses on the desugared anon const +trait Trait { + const ASSOC: usize; +} +fn foo() -> [u8; <()>::ASSOC] +//~^ ERROR: no associated item named `ASSOC` found for unit type `()` +where + (): Trait {} +``` + +The second point is particularly subtle as it is very easy to get HIR Ty lowering wrong and not properly enforce that anon consts can't use generic parameters. The existing check is too conservative and accidentally permits some generic parameters to wind up in the body of the anon const [#144547](https://github.com/rust-lang/rust/issues/144547). + +Erroneously allowing generic parameters in anon consts can sometimes lead to ICEs but can also lead to accepting illformed programs. + +The third point is also somewhat subtle, by not inheriting any of the where clauses of the parent item we can't wind up with the trait solving inferring inference variables to generic parameters based off where clauses in scope that mention generic parameters. For example inferring `?x=T` from the expression `<() as Trait>::ASSOC` and an in scope where clause of `(): Trait`. + +This also makes it much more likely that the compiler will ICE or atleast incidentally emit some kind of error if we *do* accidentally allow generic parameters in an anon const, as the anon const will have none of the necessary information in its environment to properly handle the generic parameters. + +```rust +fn foo() { + let a = [1_u8; size_of::<*mut T>()]; +} +``` + +The one exception to all of the above is repeat counts of array expressions. As a *backwards compatibility hack* we allow the repeat count const argument to use generic parameters. + +However, to avoid most of the problems involved in allowing generic parameters in anon const const arguments we require that the constant be evaluated before monomorphization (e.g. during type checking). In some sense we only allow generic parameters here when they are semantically unused. + +In the previous example the anon const can be evaluated for any type parameter `T` because raw pointers to sized types always have the same size (e.g. `8` on 64bit platforms). + +When detecting that we evaluated an anon const that syntactically contained generic parameters, but did not actually depend on them for evaluation to succeed, we emit the [`const_evaluatable_unchecked` FCW][cec_fcw]. This is intended to become a hard error once we stabilize more ways of using generic parameters in const arguments, for example `min_generic_const_args` or (the now dead) `generic_const_exprs`. + +The implementation for this FCW can be found here: [`const_eval_resolve_for_typeck`] + +### Incompatibilities with `generic_const_parameter_types` + +Supporting const paramters such as `const N: [u8; M]` or `const N: Foo` does not work very nicely with the current anon consts setup. There are two reasons for this: +1. As anon consts cannot use generic parameters, their type *also* can't reference generic parameters. This means it is fundamentally not possible to use an anon const as an argument to a const parameeter whose type still references generic parameters. + + ```rust + #![feature(adt_const_params, generic_const_parameter_types)] + + fn foo() {} + + fn bar() { + // There is no way to specify the const argument to `M` + foo::(); + } + ``` + +2. We currently require knowing the type of anon consts when lowering them during HIR ty lowering. With generic const parameter types it may be the case that the currently known type contains inference variables (ie may not be fully known yet). + + ```rust + #![feature(adt_const_params, generic_const_parameter_types)] + + fn foo() {} + + fn bar() { + // The const argument to `N` must be explicitly specified + // even though it is able to be inferred + foo::<_, { [1_u8; 3] }>(); + } + ``` + +It is currently unclear what the right way to make `generic_const_parameter_types` work nicely with the rest of const generics is. + +`generic_const_exprs` would have allowed for anon consts with types referencing generic parameters, but that design wound up unworkable. + +`min_generic_const_args` will allow for some expressions (for example array construction) to be representable without an anon const and therefore without running into these issues, though whether this is *enough* has yet to be determined. + +## Checking types of Const Arguments + +In order for a const argument to be well formed it must have the same type as the const parameter it is an argument to. For example a const argument of type `bool` for an array length is not well formed, as an array's length parameter has type `usize`. + +```rust +type Alias = [u8; B]; +//~^ ERROR: +``` + +To check this we have [`ClauseKind::ConstArgHasType(ty::Const, Ty)`][const_arg_has_type], where for each Const Parameter defined on an item we also desugar an equivalent `ConstArgHasType` clause into its list of where cluases. This ensures that whenever we check wellformedness of anything by proving all of its clauses, we also check happen to check that all of the Const Arguments have the correct type. + +```rust +fn foo() {} + +// desugars to in psuedo-rust + +fn foo() +where +// ConstArgHasType(N, usize) + N: usize, {} +``` + +Proving `ConstArgHasType` goals is implemented by first computing the type of the const argument, then equating it with the provided type. A rough outline of how the type of a Const Argument may be computed: +- [`ConstKind::Param(N)`][`ConstKind::Param`] can be looked up in the [`ParamEnv`] to find a `ConstArgHasType(N, ty)` clause +- [`ConstKind::Value`] stores the type of the value inside itself so can trivially be accessed +- [`ConstKind::Unevaluated`] can have its type computed by calling the `type_of` query +- See the implementation of proving `ConstArgHasType` goals for more detailed information + +`ConstArgHasType` is *the* soundness critical way that we check Const Arguments have the correct type. However, we do *indirectly* check the types of Const Arguments a different way in some cases. + +```rust +type Alias = [u8; true]; + +// desugars to + +const ANON: usize = true; +type Alias = [u8; ANON]; +``` + +By feeding the type of an anon const with the type of the Const Parameter we guarantee that the `ConstArgHasType` goal involving the anon const will succeed. In cases where the type of the anon const doesn't match the type of the Const Parameter what actually happens is a *type checking* error when type checking the anon const's body. + +Looking at the above example, this corresponds to `[u8; ANON]` being a well formed type because `ANON` has type `usize`, but the *body* of `ANON` being illformed and resulting in a type checking error because `true` can't be returned from a const item of type `usize`. + +[ambig-unambig-ty-and-consts]: ./hir/ambig-unambig-ty-and-consts.md +[`ConstKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html +[`ConstKind::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Infer +[`ConstKind::Param`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Param +[`ConstKind::Unevaluated`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Unevaluated +[`ConstKind::Value`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Value +[const_arg_has_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ClauseKind.html#variant.ConstArgHasType +[`ParamEnv`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html +[`generics_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#impl-TyCtxt%3C'tcx%3E/method.generics_of +[`type_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.type_of +[`DefKind::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/enum.DefKind.html#variant.AnonConst +[`hir::Node::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html#variant.AnonConst# +[cec_fcw]: https://github.com/rust-lang/rust/issues/76200 +[`const_eval_resolve_for_typeck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.const_eval_resolve_for_typeck diff --git a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md b/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md index d4f504ad2a98..64a15b7f9aa8 100644 --- a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md +++ b/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md @@ -1,6 +1,6 @@ # Ambig/Unambig Types and Consts -Types and Consts args in the HIR can be in two kinds of positions ambiguous (ambig) or unambiguous (unambig). Ambig positions are where +Types and Consts args in the AST/HIR can be in two kinds of positions ambiguous (ambig) or unambiguous (unambig). Ambig positions are where it would be valid to parse either a type or a const, unambig positions are where only one kind would be valid to parse. @@ -21,29 +21,69 @@ fn func(arg: T) { ``` -Most types/consts in ambig positions are able to be disambiguated as either a type or const during parsing. Single segment paths are always represented as types in the AST but may get resolved to a const parameter during name resolution, then lowered to a const argument during ast-lowering. The only generic arguments which remain ambiguous after lowering are inferred generic arguments (`_`) in path segments. For example, in `Foo<_>` it is not clear whether the `_` argument is an inferred type argument, or an inferred const argument. +Most types/consts in ambig positions are able to be disambiguated as either a type or const during parsing. The only exceptions to this are paths and inferred generic arguments. -In unambig positions, inferred arguments are represented with [`hir::TyKind::Infer`][ty_infer] or [`hir::ConstArgKind::Infer`][const_infer] depending on whether it is a type or const position respectively. -In ambig positions, inferred arguments are represented with `hir::GenericArg::Infer`. +## Paths + +```rust +struct Foo; + +fn foo(_: Foo) {} +``` + +At parse time we parse all unbraced generic arguments as *types* (ie they wind up as [`ast::GenericArg::Ty`]). In the above example this means we would parse the generic argument to `Foo` as an `ast::GenericArg::Ty` wrapping a [`ast::Ty::Path(N)`]. + +Then during name resolution: +- When encountering a single segment path with no generic arguments in generic argument position, we will first try to resolve it in the type namespace and if that fails we then attempt to resolve in the value namespace. +- All other kinds of paths we only try to resolve in the type namespace + +See [`LateResolutionVisitor::visit_generic_arg`] for where this is implemented. + +Finally during AST lowering when we attempt to lower a type argument, we first check if it is a `Ty::Path` and if it resolved to something in the value namespace. If it did then we create an *anon const* and lower to a const argument instead of a type argument. + +See [`LoweringContext::lower_generic_arg`] for where this is implemented. + +Note that the ambiguity for paths is not propgated into the HIR; there's no `hir::GenericArg::Path` which is turned into either a `Ty` or `Const` during HIR ty lowering (though we could do such a thing). + +## Inferred arguments (`_`) + +```rust +struct Foo; + +fn foo() { + let _unused: Foo<_>; +} +``` + +The only generic arguments which remain ambiguous after lowering are inferred generic arguments (`_`) in path segments. In the above example it is not clear at parse time whether the `_` argument to `Foo` is an inferred type argument, or an inferred const argument. + +In ambig AST positions, inferred argumentsd are parsed as an [`ast::GenericArg::Ty`] wrapping a [`ast::Ty::Infer`]. Then during AST lowering when lowering an `ast::GenericArg::Ty` we check if it is an inferred type and if so lower to a [`hir::GenericArg::Infer`]. + +In unambig AST positions, inferred arguments are parsed as either `ast::Ty::Infer` or [`ast::AnonConst`]. The `AnonConst` case is quite strange, we use [`ast::ExprKind::Underscore`] to represent the "body" of the "anon const" although in reality we do not actually lower this to an anon const in the HIR. + +It may be worth seeing if we can refactor the AST to have `ast::GenericArg::Infer` and then get rid of this overloaded meaning of `AnonConst`, as well as the reuse of `ast::Ty::Infer` in ambig positions. + +In unambig AST positions, during AST lowering we lower inferred arguments to [`hir::TyKind::Infer`][ty_infer] or [`hir::ConstArgKind::Infer`][const_infer] depending on whether it is a type or const position respectively. +In ambig AST positions, during AST lowering we lower inferred arguments to [`hir::GenericArg::Infer`][generic_arg_infer]. See [`LoweringContext::lower_generic_arg`] for where this is implemented. A naive implementation of this would result in there being potentially 5 places where you might think an inferred type/const could be found in the HIR from looking at the structure of the HIR: -1. In unambig type position as a `hir::TyKind::Infer` -2. In unambig const arg position as a `hir::ConstArgKind::Infer` +1. In unambig type position as a `TyKind::Infer` +2. In unambig const arg position as a `ConstArgKind::Infer` 3. In an ambig position as a [`GenericArg::Type(TyKind::Infer)`][generic_arg_ty] 4. In an ambig position as a [`GenericArg::Const(ConstArgKind::Infer)`][generic_arg_const] -5. In an ambig position as a [`GenericArg::Infer`][generic_arg_infer] +5. In an ambig position as a `GenericArg::Infer` Note that places 3 and 4 would never actually be possible to encounter as we always lower to `GenericArg::Infer` in generic arg position. This has a few failure modes: - People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident. -- People may write visitors which check for `hir::TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident. +- People may write visitors which check for `TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident. - People may write visitors which check for `GenericArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenericArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`. - People may write visitors which check for *only* `TyKind::Infer` and not `ConstArgKind::Infer` forgetting that there are also inferred const arguments (and vice versa). To make writing HIR visitors less error prone when caring about inferred types/consts we have a relatively complex system: -1. We have different types in the compiler for when a type or const is in an unambig or ambig position, `hir::Ty` and `hir::Ty<()>`. [`AmbigArg`][ambig_arg] is an uninhabited type which we use in the `Infer` variant of `TyKind` and `ConstArgKind` to selectively "disable" it if we are in an ambig position. +1. We have different types in the compiler for when a type or const is in an unambig or ambig position, `Ty` and `Ty<()>`. [`AmbigArg`][ambig_arg] is an uninhabited type which we use in the `Infer` variant of `TyKind` and `ConstArgKind` to selectively "disable" it if we are in an ambig position. 2. The [`visit_ty`][visit_ty] and [`visit_const_arg`][visit_const_arg] methods on HIR visitors only accept the ambig position versions of types/consts. Unambig types/consts are implicitly converted to ambig types/consts during the visiting process, with the `Infer` variant handled by a dedicated [`visit_infer`][visit_infer] method. @@ -61,3 +101,11 @@ This has a number of benefits: [visit_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_ty [visit_const_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_const_arg [visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer +[`LateResolutionVisitor::visit_generic_arg`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.LateResolutionVisitor.html#method.visit_generic_arg +[`LoweringContext::lower_generic_arg`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/struct.LoweringContext.html#method.lower_generic_arg +[`ast::GenericArg::Ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.GenericArg.html#variant.Type +[`ast::Ty::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.TyKind.html#variant.Infer +[`ast::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.AnonConst.html +[`hir::GenericArg::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Infer +[`ast::ExprKind::Underscore`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.ExprKind.html#variant.Underscore +[`ast::Ty::Path(N)`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.TyKind.html#variant.Path \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/solve/invariants.md b/src/doc/rustc-dev-guide/src/solve/invariants.md index 8ec15f339e51..efdd97fd1418 100644 --- a/src/doc/rustc-dev-guide/src/solve/invariants.md +++ b/src/doc/rustc-dev-guide/src/solve/invariants.md @@ -168,5 +168,10 @@ We lookup types using structural equality during codegen, but this shouldn't nec Semantically different `'static` types need different `TypeId`s to avoid transmutes, for example `for<'a> fn(&'a str)` vs `fn(&'static str)` must have a different `TypeId`. +## Evaluation of const items is deterministic ✅ + +As the values of const items can feed into the type system, it is important that the value of a const item is always the same in every crate. If this isn't the case then we can wind up with associated types with "equal" const arguments and so are "equal" associated types, and yet when normalized during codegen in different crates actually wind up as different types. + +Notably this does *not* extend to const *functions*, as the type system only works with the results of const *items* it's actually fine for const functions to be non deterministic so long as that doesn't affect the final value of a const item. [coherence chapter]: ../coherence.md From 29ad85c116b40f8c72305074d52087831af02485 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Fri, 31 Oct 2025 15:36:41 +0100 Subject: [PATCH 0556/3801] Do not propogate unnecessary closure constraints + tests. --- .../rustc_borrowck/src/region_infer/mod.rs | 20 ++++++++++++++ .../closure-prop-issue-104477-case1.rs | 14 ++++++++++ tests/ui/regions/closure-prop-issue-148289.rs | 26 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 tests/ui/regions/closure-prop-issue-104477-case1.rs create mode 100644 tests/ui/regions/closure-prop-issue-148289.rs diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index e98c60e63380..61a6d6d5b79d 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1292,6 +1292,26 @@ impl<'tcx> RegionInferenceContext<'tcx> { // so slightly larger than `shorter_fr`. let shorter_fr_plus = self.universal_region_relations.non_local_upper_bounds(shorter_fr); + + // If any of the `shorter_fr+` regions are already outlived by `fr-`, we propagate only those. + // Otherwise, we might incorrectly reject valid code. + // + // Consider this example (`'b: 'a` == `a -> b`), where we try to propagate `'d: 'a`: + // a --> b --> d + // \ + // \-> c + // Here, `shorter_fr+` of `'a` == `['b, 'c]`. + // Propagating `'d: 'b` is correct and should occur; `'d: 'c` is redundant because of `'d: 'b` + // and could reject valid code. + // + // So we filter `shorter_fr+` to regions already outlived by `fr-`, but if the filter yields an empty set, + // we fall back to the original one. + let subset: Vec<_> = shorter_fr_plus + .iter() + .filter(|&&fr_plus| self.eval_outlives(fr_minus, fr_plus)) + .copied() + .collect(); + let shorter_fr_plus = if subset.is_empty() { shorter_fr_plus } else { subset }; debug!("try_propagate_universal_region_error: shorter_fr_plus={:?}", shorter_fr_plus); for fr in shorter_fr_plus { // Push the constraint `fr-: shorter_fr+` diff --git a/tests/ui/regions/closure-prop-issue-104477-case1.rs b/tests/ui/regions/closure-prop-issue-104477-case1.rs new file mode 100644 index 000000000000..307ca930baea --- /dev/null +++ b/tests/ui/regions/closure-prop-issue-104477-case1.rs @@ -0,0 +1,14 @@ +//@ check-pass +// This checks that the compiler does not require that 'a: 'b. '_ has 'a and 'b as non-local +// upper bounds, but the compiler should not propagate 'a: 'b OR 'b: 'a when checking +// the closures. If it did, this would fail to compile, eventhough it's a valid program. +// PR #148329 explains this in detail. + +struct MyTy<'x, 'a, 'b>(std::cell::Cell<(&'x &'a u8, &'x &'b u8)>); +fn wf(_: T) {} +fn test<'a, 'b>() { + |_: &'a u8, x: MyTy<'_, 'a, 'b>| wf(x); + |x: MyTy<'_, 'a, 'b>, _: &'a u8| wf(x); +} + +fn main(){} diff --git a/tests/ui/regions/closure-prop-issue-148289.rs b/tests/ui/regions/closure-prop-issue-148289.rs new file mode 100644 index 000000000000..7f89927a76e0 --- /dev/null +++ b/tests/ui/regions/closure-prop-issue-148289.rs @@ -0,0 +1,26 @@ +//@ check-pass +// This test checks that the compiler does not propagate 'd: 'c when propagating region errors +// for the closure argument. If it did, this would fail to compile, eventhough it's a valid program. +// It should only propagate 'd: 'b. +// PR #148329 explains this in detail. + +#[derive(Clone, Copy)] +struct Inv<'a>(*mut &'a ()); +impl<'a> Inv<'a> { + fn outlived_by<'b: 'a>(self, _: Inv<'b>) {} +} +struct OutlivedBy<'a, 'b: 'a>(Inv<'a>, Inv<'b>); + +fn closure_arg<'b, 'c, 'd>( + _: impl for<'a> FnOnce(Inv<'a>, OutlivedBy<'a, 'b>, OutlivedBy<'a, 'c>, Inv<'d>), +) { +} +fn foo<'b, 'c, 'd: 'b>() { + closure_arg::<'b, 'c, 'd>(|a, b, c, d| { + a.outlived_by(b.1); + a.outlived_by(c.1); + b.1.outlived_by(d); + }); +} + +fn main() {} From c17a0f425685a9b386e408b9ef50789b251d36a4 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 10 Dec 2025 16:08:39 +0000 Subject: [PATCH 0557/3801] move docs about ambig ty and consts --- src/doc/rustc-dev-guide/src/SUMMARY.md | 2 +- .../src/{hir => }/ambig-unambig-ty-and-consts.md | 0 src/doc/rustc-dev-guide/src/const-generics.md | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/doc/rustc-dev-guide/src/{hir => }/ambig-unambig-ty-and-consts.md (100%) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index cdf61390baf0..1678d4f62dc4 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -126,8 +126,8 @@ - [Lang Items](./lang-items.md) - [The HIR (High-level IR)](./hir.md) - [Lowering AST to HIR](./hir/lowering.md) - - [Ambig/Unambig Types and Consts](./hir/ambig-unambig-ty-and-consts.md) - [Debugging](./hir/debugging.md) +- [Ambig/Unambig Types and Consts](./ambig-unambig-ty-and-consts.md) - [The THIR (Typed High-level IR)](./thir.md) - [The MIR (Mid-level IR)](./mir/index.md) - [MIR construction](./mir/construction.md) diff --git a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md b/src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md similarity index 100% rename from src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md rename to src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md diff --git a/src/doc/rustc-dev-guide/src/const-generics.md b/src/doc/rustc-dev-guide/src/const-generics.md index ffde2051e07d..cb8c7adc07f4 100644 --- a/src/doc/rustc-dev-guide/src/const-generics.md +++ b/src/doc/rustc-dev-guide/src/const-generics.md @@ -206,7 +206,7 @@ By feeding the type of an anon const with the type of the Const Parameter we gua Looking at the above example, this corresponds to `[u8; ANON]` being a well formed type because `ANON` has type `usize`, but the *body* of `ANON` being illformed and resulting in a type checking error because `true` can't be returned from a const item of type `usize`. -[ambig-unambig-ty-and-consts]: ./hir/ambig-unambig-ty-and-consts.md +[ambig-unambig-ty-and-consts]: ./ambig-unambig-ty-and-consts.md [`ConstKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html [`ConstKind::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Infer [`ConstKind::Param`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Param From fb9d3a5db4c3358f8ca22302f0e078675bc1a596 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Dec 2025 17:34:08 +0100 Subject: [PATCH 0558/3801] Simplify the sorting of impls and use CSS classes instead of plain JS to show/hide implementors --- src/librustdoc/html/render/print_item.rs | 10 +++---- src/librustdoc/html/render/write_shared.rs | 33 +++++---------------- src/librustdoc/html/static/css/noscript.css | 2 +- src/librustdoc/html/static/css/rustdoc.css | 2 +- src/librustdoc/html/static/js/main.js | 4 +-- 5 files changed, 17 insertions(+), 34 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 47e587626352..f88a5b8974fb 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -650,18 +650,18 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp /// /// This marker appears once in all trait impl lists to divide negative impls from positive impls. struct NegativeMarker { - inserted_negative_marker: bool, + inserted: bool, } impl NegativeMarker { fn new() -> Self { - Self { inserted_negative_marker: false } + Self { inserted: false } } fn insert_if_needed(&mut self, w: &mut fmt::Formatter<'_>, implementor: &Impl) -> fmt::Result { - if !self.inserted_negative_marker && !implementor.is_negative_trait_impl() { - write!(w, "
")?; - self.inserted_negative_marker = true; + if !self.inserted && !implementor.is_negative_trait_impl() { + w.write_str("
")?; + self.inserted = true; } Ok(()) } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index ca33531174b1..e0a37c95257c 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -747,7 +747,14 @@ impl TraitAliasPart { path.push(format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1])); let mut implementors = implementors.collect::>(); - implementors.sort_unstable(); + implementors.sort_unstable_by(|a, b| { + // We sort negative impls first. + match (a.is_negative, b.is_negative) { + (false, true) => Ordering::Greater, + (true, false) => Ordering::Less, + _ => compare_names(&a.text, &b.text), + } + }); let part = OrderedJson::array_unsorted( implementors @@ -762,7 +769,6 @@ impl TraitAliasPart { } } -#[derive(Eq)] struct Implementor { text: String, synthetic: bool, @@ -786,29 +792,6 @@ impl Serialize for Implementor { } } -impl PartialEq for Implementor { - fn eq(&self, other: &Self) -> bool { - self.cmp(other) == Ordering::Equal - } -} - -impl PartialOrd for Implementor { - fn partial_cmp(&self, other: &Self) -> Option { - Some(Ord::cmp(self, other)) - } -} - -impl Ord for Implementor { - fn cmp(&self, other: &Self) -> Ordering { - // We sort negative impls first. - match (self.is_negative, other.is_negative) { - (false, true) => Ordering::Greater, - (true, false) => Ordering::Less, - _ => compare_names(&self.text, &other.text), - } - } -} - /// Collect the list of aliased types and their aliases. /// /// diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index 6b80d3e7bbee..6f44854b6914 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -29,7 +29,7 @@ nav.sub { display: none; } -#synthetic-implementors-list, #implementors-list { +#synthetic-implementors-list:not(.loaded), #implementors-list:not(.loaded) { display: block; } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index a5e43e1d7d19..69a79f2736e7 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1158,7 +1158,7 @@ div.where { margin-left: calc(var(--docblock-indent) + var(--impl-items-indent)); } -#synthetic-implementors-list, #implementors-list { +#synthetic-implementors-list:not(.loaded), #implementors-list:not(.loaded) { /* To prevent layout shift when loading the page with extra implementors being loaded from JS, we hide the list until it's complete. */ display: none; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 72d7e6131814..476ecd42d6f9 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -911,10 +911,10 @@ function preLoadCss(cssUrl) { } } if (implementors[0]) { - implementors[0].style.display = "block"; + implementors[0].classList.add("loaded"); } if (syntheticImplementors[0]) { - syntheticImplementors[0].style.display = "block"; + syntheticImplementors[0].classList.add("loaded"); } }; if (window.pending_implementors) { From 40891c79e67bd4e83f98c5866e62d24e2f2e06eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 9 Dec 2025 11:31:24 +0100 Subject: [PATCH 0559/3801] Use ubuntu:24.04 for the `x86_64-gnu-miri` and `x86_64-gnu-aux` jobs --- src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile | 2 +- src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile index a74db2250fc6..d4113736b544 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM ghcr.io/rust-lang/ubuntu:24.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile index ad2ee85c7bb5..db4fca71d637 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/rust-lang/ubuntu:22.04 +FROM ghcr.io/rust-lang/ubuntu:24.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ From 0627df9151ec49426de114873309521c89f95da7 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Tue, 11 Nov 2025 22:16:13 +0100 Subject: [PATCH 0560/3801] Propagate region error for every non-local lower bound --- .../rustc_borrowck/src/region_infer/mod.rs | 76 ++++++++++++------ .../src/type_check/free_region_relations.rs | 24 +----- ...opagate-approximated-both-lower-bounds.rs} | 14 ++-- ...gate-approximated-both-lower-bounds.stderr | 79 +++++++++++++++++++ ...pagate-approximated-fail-no-postdom.stderr | 42 ---------- .../closure-prop-issue-104477-case2.rs | 12 +++ 6 files changed, 155 insertions(+), 92 deletions(-) rename tests/ui/nll/closure-requirements/{propagate-approximated-fail-no-postdom.rs => propagate-approximated-both-lower-bounds.rs} (66%) create mode 100644 tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.stderr delete mode 100644 tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr create mode 100644 tests/ui/regions/closure-prop-issue-104477-case2.rs diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 61a6d6d5b79d..2fec58ef3bc4 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1275,49 +1275,81 @@ impl<'tcx> RegionInferenceContext<'tcx> { shorter_fr: RegionVid, propagated_outlives_requirements: &mut Option<&mut Vec>>, ) -> RegionRelationCheckResult { - if let Some(propagated_outlives_requirements) = propagated_outlives_requirements - // Shrink `longer_fr` until we find a non-local region (if we do). - // We'll call it `fr-` -- it's ever so slightly smaller than + if let Some(propagated_outlives_requirements) = propagated_outlives_requirements { + // Shrink `longer_fr` until we find some non-local regions. + // We'll call them `longer_fr-` -- they are ever so slightly smaller than // `longer_fr`. - && let Some(fr_minus) = self.universal_region_relations.non_local_lower_bound(longer_fr) - { - debug!("try_propagate_universal_region_error: fr_minus={:?}", fr_minus); + let longer_fr_minus = self.universal_region_relations.non_local_lower_bounds(longer_fr); + + debug!("try_propagate_universal_region_error: fr_minus={:?}", longer_fr_minus); + + // If we don't find a any non-local regions, we should error out as there is nothing + // to propagate. + if longer_fr_minus.is_empty() { + return RegionRelationCheckResult::Error; + } let blame_constraint = self .best_blame_constraint(longer_fr, NllRegionVariableOrigin::FreeRegion, shorter_fr) .0; - // Grow `shorter_fr` until we find some non-local regions. (We - // always will.) We'll call them `shorter_fr+` -- they're ever - // so slightly larger than `shorter_fr`. + // Grow `shorter_fr` until we find some non-local regions. + // We will always find at least one: `'static`. We'll call + // them `shorter_fr+` -- they're ever so slightly larger + // than `shorter_fr`. let shorter_fr_plus = self.universal_region_relations.non_local_upper_bounds(shorter_fr); + debug!("try_propagate_universal_region_error: shorter_fr_plus={:?}", shorter_fr_plus); - // If any of the `shorter_fr+` regions are already outlived by `fr-`, we propagate only those. - // Otherwise, we might incorrectly reject valid code. + // We then create constraints `longer_fr-: shorter_fr+` that may or may not + // be propagated (see below). + let mut constraints = vec![]; + for fr_minus in longer_fr_minus { + for shorter_fr_plus in &shorter_fr_plus { + constraints.push((fr_minus, *shorter_fr_plus)); + } + } + + // We only need to propagate at least one of the constraints for + // soundness. However, we want to avoid arbitrary choices here + // and currently don't support returning OR constraints. + // + // If any of the `shorter_fr+` regions are already outlived by `longer_fr-`, + // we propagate only those. // // Consider this example (`'b: 'a` == `a -> b`), where we try to propagate `'d: 'a`: // a --> b --> d // \ // \-> c // Here, `shorter_fr+` of `'a` == `['b, 'c]`. - // Propagating `'d: 'b` is correct and should occur; `'d: 'c` is redundant because of `'d: 'b` - // and could reject valid code. + // Propagating `'d: 'b` is correct and should occur; `'d: 'c` is redundant because of + // `'d: 'b` and could reject valid code. // - // So we filter `shorter_fr+` to regions already outlived by `fr-`, but if the filter yields an empty set, - // we fall back to the original one. - let subset: Vec<_> = shorter_fr_plus + // So we filter the constraints to regions already outlived by `longer_fr-`, but if + // the filter yields an empty set, we fall back to the original one. + let subset: Vec<_> = constraints .iter() - .filter(|&&fr_plus| self.eval_outlives(fr_minus, fr_plus)) + .filter(|&&(fr_minus, shorter_fr_plus)| { + self.eval_outlives(fr_minus, shorter_fr_plus) + }) .copied() .collect(); - let shorter_fr_plus = if subset.is_empty() { shorter_fr_plus } else { subset }; - debug!("try_propagate_universal_region_error: shorter_fr_plus={:?}", shorter_fr_plus); - for fr in shorter_fr_plus { - // Push the constraint `fr-: shorter_fr+` + let propagated_constraints = if subset.is_empty() { constraints } else { subset }; + debug!( + "try_propagate_universal_region_error: constraints={:?}", + propagated_constraints + ); + + assert!( + !propagated_constraints.is_empty(), + "Expected at least one constraint to propagate here" + ); + + for (fr_minus, fr_plus) in propagated_constraints { + // Push the constraint `long_fr-: shorter_fr+` propagated_outlives_requirements.push(ClosureOutlivesRequirement { subject: ClosureOutlivesSubject::Region(fr_minus), - outlived_free_region: fr, + outlived_free_region: fr_plus, blame_span: blame_constraint.cause.span, category: blame_constraint.category, }); diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index d27a73535bab..279625cb87c9 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -94,28 +94,10 @@ impl UniversalRegionRelations<'_> { /// words, returns the largest (*) known region `fr1` that (a) is /// outlived by `fr` and (b) is not local. /// - /// (*) If there are multiple competing choices, we pick the "postdominating" - /// one. See `TransitiveRelation::postdom_upper_bound` for details. - pub(crate) fn non_local_lower_bound(&self, fr: RegionVid) -> Option { + /// (*) If there are multiple competing choices, we return all of them. + pub(crate) fn non_local_lower_bounds(&self, fr: RegionVid) -> Vec { debug!("non_local_lower_bound(fr={:?})", fr); - let lower_bounds = self.non_local_bounds(&self.outlives, fr); - - // In case we find more than one, reduce to one for - // convenience. This is to prevent us from generating more - // complex constraints, but it will cause spurious errors. - let post_dom = self.outlives.mutual_immediate_postdominator(lower_bounds); - - debug!("non_local_bound: post_dom={:?}", post_dom); - - post_dom.and_then(|post_dom| { - // If the mutual immediate postdom is not local, then - // there is no non-local result we can return. - if !self.universal_regions.is_local_free_region(post_dom) { - Some(post_dom) - } else { - None - } - }) + self.non_local_bounds(&self.outlives, fr) } /// Helper for `non_local_upper_bounds` and `non_local_lower_bounds`. diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs b/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.rs similarity index 66% rename from tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs rename to tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.rs index 5d21fa100a43..addfc7b91391 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs +++ b/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.rs @@ -1,6 +1,5 @@ -// Test where we fail to approximate due to demanding a postdom -// relationship between our upper bounds. - +// Test that we can propagate multiple region errors for closure constraints +// where the longer region has multiple non-local lower bounds without any postdominating one. //@ compile-flags:-Zverbose-internals #![feature(rustc_attrs)] @@ -13,9 +12,8 @@ use std::cell::Cell; // 'x: 'b // 'c: 'y // -// we have to prove that `'x: 'y`. We currently can only approximate -// via a postdominator -- hence we fail to choose between `'a` and -// `'b` here and report the error in the closure. +// we have to prove that `'x: 'y`. We find non-local lower bounds of 'x to be 'a and 'b and +// non-local upper bound of 'y to be 'c. So we propagate `'b: 'c` and `'a: 'c`. fn establish_relationships<'a, 'b, 'c, F>( _cell_a: Cell<&'a u32>, _cell_b: Cell<&'b u32>, @@ -36,6 +34,8 @@ fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) #[rustc_regions] fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { + //~vv ERROR lifetime may not live long enough + //~v ERROR lifetime may not live long enough establish_relationships( cell_a, cell_b, @@ -43,7 +43,7 @@ fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell |_outlives1, _outlives2, _outlives3, x, y| { // Only works if 'x: 'y: let p = x.get(); - demand_y(x, y, p) //~ ERROR + demand_y(x, y, p) }, ); } diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.stderr new file mode 100644 index 000000000000..af7ea253cc52 --- /dev/null +++ b/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.stderr @@ -0,0 +1,79 @@ +note: external requirements + --> $DIR/propagate-approximated-both-lower-bounds.rs:43:9 + | +LL | |_outlives1, _outlives2, _outlives3, x, y| { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: supply::{closure#0} with closure args [ + i16, + for extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'?2 &'^0 u32>, std::cell::Cell<&'^1 &'?3 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)), + (), + ] + = note: late-bound region is '?7 + = note: late-bound region is '?8 + = note: late-bound region is '?4 + = note: late-bound region is '?5 + = note: late-bound region is '?6 + = note: number of external vids: 7 + = note: where '?2: '?3 + = note: where '?1: '?3 + +note: no external requirements + --> $DIR/propagate-approximated-both-lower-bounds.rs:36:1 + | +LL | fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: supply + +error: lifetime may not live long enough + --> $DIR/propagate-approximated-both-lower-bounds.rs:39:5 + | +LL | fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { + | -- -- lifetime `'c` defined here + | | + | lifetime `'a` defined here +... +LL | / establish_relationships( +LL | | cell_a, +LL | | cell_b, +LL | | cell_c, +... | +LL | | }, +LL | | ); + | |_____^ argument requires that `'a` must outlive `'c` + | + = help: consider adding the following bound: `'a: 'c` + = note: requirement occurs because of the type `Cell<&'?10 u32>`, which makes the generic argument `&'?10 u32` invariant + = note: the struct `Cell` is invariant over the parameter `T` + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/propagate-approximated-both-lower-bounds.rs:39:5 + | +LL | fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { + | -- -- lifetime `'c` defined here + | | + | lifetime `'b` defined here +... +LL | / establish_relationships( +LL | | cell_a, +LL | | cell_b, +LL | | cell_c, +... | +LL | | }, +LL | | ); + | |_____^ argument requires that `'b` must outlive `'c` + | + = help: consider adding the following bound: `'b: 'c` + = note: requirement occurs because of the type `Cell<&'?10 u32>`, which makes the generic argument `&'?10 u32` invariant + = note: the struct `Cell` is invariant over the parameter `T` + = help: see for more information about variance + +help: the following changes may resolve your lifetime errors + | + = help: add bound `'a: 'c` + = help: add bound `'b: 'c` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr deleted file mode 100644 index 134ce99014d8..000000000000 --- a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ /dev/null @@ -1,42 +0,0 @@ -note: no external requirements - --> $DIR/propagate-approximated-fail-no-postdom.rs:43:9 - | -LL | |_outlives1, _outlives2, _outlives3, x, y| { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: supply::{closure#0} with closure args [ - i16, - for extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'?2 &'^0 u32>, std::cell::Cell<&'^1 &'?3 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)), - (), - ] - = note: late-bound region is '?7 - = note: late-bound region is '?8 - = note: late-bound region is '?4 - = note: late-bound region is '?5 - = note: late-bound region is '?6 - -error: lifetime may not live long enough - --> $DIR/propagate-approximated-fail-no-postdom.rs:46:13 - | -LL | |_outlives1, _outlives2, _outlives3, x, y| { - | ---------- ---------- has type `Cell<&'2 &'?3 u32>` - | | - | has type `Cell<&'?1 &'1 u32>` -... -LL | demand_y(x, y, p) - | ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` - | - = note: requirement occurs because of the type `Cell<&'?34 u32>`, which makes the generic argument `&'?34 u32` invariant - = note: the struct `Cell` is invariant over the parameter `T` - = help: see for more information about variance - -note: no external requirements - --> $DIR/propagate-approximated-fail-no-postdom.rs:38:1 - | -LL | fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: supply - -error: aborting due to 1 previous error - diff --git a/tests/ui/regions/closure-prop-issue-104477-case2.rs b/tests/ui/regions/closure-prop-issue-104477-case2.rs new file mode 100644 index 000000000000..a77a11d0eceb --- /dev/null +++ b/tests/ui/regions/closure-prop-issue-104477-case2.rs @@ -0,0 +1,12 @@ +//@ check-pass +// This test checks that the compiler propagates outlives requirements for both +// non-local lower bounds ['a, 'b] of '_, instead of conservatively finding a post-dominiting one +// from those 2. + +struct MyTy<'a, 'b, 'x>(std::cell::Cell<(&'a &'x str, &'b &'x str)>); +fn wf(_: T) {} +fn test<'a, 'b, 'x>() { + |x: MyTy<'a, 'b, '_>| wf(x); +} + +fn main() {} From c0bf494d24ad7fe8aed76320286b105cf90be4c0 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Wed, 10 Dec 2025 18:42:22 +0200 Subject: [PATCH 0561/3801] Support the new lowering of format_args!() --- .../crates/hir-def/src/expr_store/lower.rs | 32 +- .../src/expr_store/lower/format_args.rs | 461 +++++++++++++++--- .../hir-def/src/expr_store/tests/body.rs | 84 +++- .../crates/test-utils/src/minicore.rs | 51 +- 4 files changed, 523 insertions(+), 105 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 3448b734ff10..0b25812f261b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -432,6 +432,8 @@ pub struct ExprCollector<'db> { awaitable_context: Option, krate: base_db::Crate, + + name_generator_index: usize, } #[derive(Clone, Debug)] @@ -537,9 +539,16 @@ impl<'db> ExprCollector<'db> { current_block_legacy_macro_defs_count: FxHashMap::default(), outer_impl_trait: false, krate, + name_generator_index: 0, } } + fn generate_new_name(&mut self) -> Name { + let index = self.name_generator_index; + self.name_generator_index += 1; + Name::generate_new_name(index) + } + #[inline] pub(crate) fn lang_items(&self) -> &'db LangItems { self.lang_items.get_or_init(|| crate::lang_item::lang_items(self.db, self.def_map.krate())) @@ -1638,9 +1647,8 @@ impl<'db> ExprCollector<'db> { /// and save the `` to use it as a break target for desugaring of the `?` operator. fn desugar_try_block(&mut self, e: BlockExpr) -> ExprId { let try_from_output = self.lang_path(self.lang_items().TryTraitFromOutput); - let label = self.alloc_label_desugared(Label { - name: Name::generate_new_name(self.store.labels.len()), - }); + let label = self.generate_new_name(); + let label = self.alloc_label_desugared(Label { name: label }); let old_label = self.current_try_block_label.replace(label); let ptr = AstPtr::new(&e).upcast(); @@ -1768,7 +1776,7 @@ impl<'db> ExprCollector<'db> { this.collect_expr_opt(e.loop_body().map(|it| it.into())) }), }; - let iter_name = Name::generate_new_name(self.store.exprs.len()); + let iter_name = self.generate_new_name(); let iter_expr = self.alloc_expr(Expr::Path(Path::from(iter_name.clone())), syntax_ptr); let iter_expr_mut = self.alloc_expr( Expr::Ref { expr: iter_expr, rawness: Rawness::Ref, mutability: Mutability::Mut }, @@ -1829,7 +1837,7 @@ impl<'db> ExprCollector<'db> { let try_branch = self.alloc_expr(try_branch.map_or(Expr::Missing, Expr::Path), syntax_ptr); let expr = self .alloc_expr(Expr::Call { callee: try_branch, args: Box::new([operand]) }, syntax_ptr); - let continue_name = Name::generate_new_name(self.store.bindings.len()); + let continue_name = self.generate_new_name(); let continue_binding = self.alloc_binding( continue_name.clone(), BindingAnnotation::Unannotated, @@ -1847,7 +1855,7 @@ impl<'db> ExprCollector<'db> { guard: None, expr: self.alloc_expr(Expr::Path(Path::from(continue_name)), syntax_ptr), }; - let break_name = Name::generate_new_name(self.store.bindings.len()); + let break_name = self.generate_new_name(); let break_binding = self.alloc_binding(break_name.clone(), BindingAnnotation::Unannotated, HygieneId::ROOT); let break_bpat = self.alloc_pat_desugared(Pat::Bind { id: break_binding, subpat: None }); @@ -2628,9 +2636,17 @@ impl<'db> ExprCollector<'db> { fn ty_rel_lang_path( &self, lang: Option>, - relative_name: Name, + relative_name: Symbol, ) -> Option { - Some(Path::LangItem(lang?.into(), Some(relative_name))) + Some(Path::LangItem(lang?.into(), Some(Name::new_symbol_root(relative_name)))) + } + + fn ty_rel_lang_path_expr( + &self, + lang: Option>, + relative_name: Symbol, + ) -> Expr { + self.ty_rel_lang_path(lang, relative_name).map_or(Expr::Missing, Expr::Path) } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs index aa7bf0e4e244..7efc9a956c1c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs @@ -19,6 +19,7 @@ use crate::{ FormatPlaceholder, FormatSign, FormatTrait, }, }, + lang_item::LangItemTarget, type_ref::{Mutability, Rawness}, }; @@ -94,6 +95,347 @@ impl<'db> ExprCollector<'db> { ), }; + let idx = if self.lang_items().FormatCount.is_none() { + self.collect_format_args_after_1_93_0_impl(syntax_ptr, fmt) + } else { + self.collect_format_args_before_1_93_0_impl(syntax_ptr, fmt) + }; + + self.store + .template_map + .get_or_insert_with(Default::default) + .format_args_to_captures + .insert(idx, (hygiene, mappings)); + idx + } + + fn collect_format_args_after_1_93_0_impl( + &mut self, + syntax_ptr: AstPtr, + fmt: FormatArgs, + ) -> ExprId { + let lang_items = self.lang_items(); + + // Create a list of all _unique_ (argument, format trait) combinations. + // E.g. "{0} {0:x} {0} {1}" -> [(0, Display), (0, LowerHex), (1, Display)] + // + // We use usize::MAX for arguments that don't exist, because that can never be a valid index + // into the arguments array. + let mut argmap = FxIndexSet::default(); + + let mut incomplete_lit = String::new(); + + let mut implicit_arg_index = 0; + + let mut bytecode = Vec::new(); + + let template = if fmt.template.is_empty() { + // Treat empty templates as a single literal piece (with an empty string), + // so we produce `from_str("")` for those. + &[FormatArgsPiece::Literal(sym::__empty)][..] + } else { + &fmt.template[..] + }; + + // See library/core/src/fmt/mod.rs for the format string encoding format. + + for (i, piece) in template.iter().enumerate() { + match piece { + FormatArgsPiece::Literal(sym) => { + // Coalesce adjacent literal pieces. + if let Some(FormatArgsPiece::Literal(_)) = template.get(i + 1) { + incomplete_lit.push_str(sym.as_str()); + continue; + } + let mut s = if incomplete_lit.is_empty() { + sym.as_str() + } else { + incomplete_lit.push_str(sym.as_str()); + &incomplete_lit + }; + + // If this is the last piece and was the only piece, that means + // there are no placeholders and the entire format string is just a literal. + // + // In that case, we can just use `from_str`. + if i + 1 == template.len() && bytecode.is_empty() { + // Generate: + // ::from_str("meow") + let from_str = self.ty_rel_lang_path_desugared_expr( + lang_items.FormatArguments, + sym::from_str, + ); + let sym = + if incomplete_lit.is_empty() { sym.clone() } else { Symbol::intern(s) }; + let s = self.alloc_expr_desugared(Expr::Literal(Literal::String(sym))); + let from_str = self.alloc_expr( + Expr::Call { callee: from_str, args: Box::new([s]) }, + syntax_ptr, + ); + return if !fmt.arguments.arguments.is_empty() { + // With an incomplete format string (e.g. only an opening `{`), it's possible for `arguments` + // to be non-empty when reaching this code path. + self.alloc_expr( + Expr::Block { + id: None, + statements: fmt + .arguments + .arguments + .iter() + .map(|arg| Statement::Expr { + expr: arg.expr, + has_semi: true, + }) + .collect(), + tail: Some(from_str), + label: None, + }, + syntax_ptr, + ) + } else { + from_str + }; + } + + // Encode the literal in chunks of up to u16::MAX bytes, split at utf-8 boundaries. + while !s.is_empty() { + let len = s.floor_char_boundary(usize::from(u16::MAX)); + if len < 0x80 { + bytecode.push(len as u8); + } else { + bytecode.push(0x80); + bytecode.extend_from_slice(&(len as u16).to_le_bytes()); + } + bytecode.extend(&s.as_bytes()[..len]); + s = &s[len..]; + } + + incomplete_lit.clear(); + } + FormatArgsPiece::Placeholder(p) => { + // Push the start byte and remember its index so we can set the option bits later. + let i = bytecode.len(); + bytecode.push(0xC0); + + let position = match &p.argument.index { + &Ok(it) => it, + Err(_) => usize::MAX, + }; + let position = argmap + .insert_full((position, ArgumentType::Format(p.format_trait))) + .0 as u64; + + // This needs to match the constants in library/core/src/fmt/mod.rs. + let o = &p.format_options; + let align = match o.alignment { + Some(FormatAlignment::Left) => 0, + Some(FormatAlignment::Right) => 1, + Some(FormatAlignment::Center) => 2, + None => 3, + }; + let default_flags = 0x6000_0020; + let flags: u32 = o.fill.unwrap_or(' ') as u32 + | ((o.sign == Some(FormatSign::Plus)) as u32) << 21 + | ((o.sign == Some(FormatSign::Minus)) as u32) << 22 + | (o.alternate as u32) << 23 + | (o.zero_pad as u32) << 24 + | ((o.debug_hex == Some(FormatDebugHex::Lower)) as u32) << 25 + | ((o.debug_hex == Some(FormatDebugHex::Upper)) as u32) << 26 + | (o.width.is_some() as u32) << 27 + | (o.precision.is_some() as u32) << 28 + | align << 29; + if flags != default_flags { + bytecode[i] |= 1; + bytecode.extend_from_slice(&flags.to_le_bytes()); + if let Some(val) = &o.width { + let (indirect, val) = self.make_count_after_1_93_0(val, &mut argmap); + // Only encode if nonzero; zero is the default. + if indirect || val != 0 { + bytecode[i] |= 1 << 1 | (indirect as u8) << 4; + bytecode.extend_from_slice(&val.to_le_bytes()); + } + } + if let Some(val) = &o.precision { + let (indirect, val) = self.make_count_after_1_93_0(val, &mut argmap); + // Only encode if nonzero; zero is the default. + if indirect || val != 0 { + bytecode[i] |= 1 << 2 | (indirect as u8) << 5; + bytecode.extend_from_slice(&val.to_le_bytes()); + } + } + } + if implicit_arg_index != position { + bytecode[i] |= 1 << 3; + bytecode.extend_from_slice(&(position as u16).to_le_bytes()); + } + implicit_arg_index = position + 1; + } + } + } + + assert!(incomplete_lit.is_empty()); + + // Zero terminator. + bytecode.push(0); + + // Ensure all argument indexes actually fit in 16 bits, as we truncated them to 16 bits before. + if argmap.len() > u16::MAX as usize { + // FIXME: Emit an error. + // ctx.dcx().span_err(macsp, "too many format arguments"); + } + + let arguments = &fmt.arguments.arguments[..]; + + let (mut statements, args) = if arguments.is_empty() { + // Generate: + // [] + ( + Vec::new(), + self.alloc_expr_desugared(Expr::Array(Array::ElementList { + elements: Box::new([]), + })), + ) + } else { + // Generate: + // super let args = (&arg0, &arg1, &…); + let args_name = self.generate_new_name(); + let args_path = Path::from(args_name.clone()); + let args_binding = self.alloc_binding( + args_name.clone(), + BindingAnnotation::Unannotated, + HygieneId::ROOT, + ); + let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None }); + self.add_definition_to_binding(args_binding, args_pat); + let elements = arguments + .iter() + .map(|arg| { + self.alloc_expr_desugared(Expr::Ref { + expr: arg.expr, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }) + }) + .collect(); + let args_tuple = self.alloc_expr_desugared(Expr::Tuple { exprs: elements }); + // FIXME: Make this a `super let` when we have this statement. + let let_statement_1 = Statement::Let { + pat: args_pat, + type_ref: None, + initializer: Some(args_tuple), + else_branch: None, + }; + + // Generate: + // super let args = [ + // ::new_display(args.0), + // ::new_lower_hex(args.1), + // ::new_debug(args.0), + // … + // ]; + let args = argmap + .iter() + .map(|&(arg_index, ty)| { + let args_ident_expr = self.alloc_expr_desugared(Expr::Path(args_path.clone())); + let arg = self.alloc_expr_desugared(Expr::Field { + expr: args_ident_expr, + name: Name::new_tuple_field(arg_index), + }); + self.make_argument(arg, ty) + }) + .collect(); + let args = + self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args })); + let args_binding = + self.alloc_binding(args_name, BindingAnnotation::Unannotated, HygieneId::ROOT); + let args_pat = self.alloc_pat_desugared(Pat::Bind { id: args_binding, subpat: None }); + self.add_definition_to_binding(args_binding, args_pat); + // FIXME: Make this a `super let` when we have this statement. + let let_statement_2 = Statement::Let { + pat: args_pat, + type_ref: None, + initializer: Some(args), + else_branch: None, + }; + ( + vec![let_statement_1, let_statement_2], + self.alloc_expr_desugared(Expr::Path(args_path)), + ) + }; + + // Generate: + // unsafe { + // ::new(b"…", &args) + // } + let template = self + .alloc_expr_desugared(Expr::Literal(Literal::ByteString(bytecode.into_boxed_slice()))); + let call = { + let new = self.ty_rel_lang_path_desugared_expr(lang_items.FormatArguments, sym::new); + let args = self.alloc_expr_desugared(Expr::Ref { + expr: args, + rawness: Rawness::Ref, + mutability: Mutability::Shared, + }); + self.alloc_expr_desugared(Expr::Call { callee: new, args: Box::new([template, args]) }) + }; + let call = self.alloc_expr( + Expr::Unsafe { id: None, statements: Box::new([]), tail: Some(call) }, + syntax_ptr, + ); + + // We collect the unused expressions here so that we still infer them instead of + // dropping them out of the expression tree. We cannot store them in the `Unsafe` + // block because then unsafe blocks within them will get a false "unused unsafe" + // diagnostic (rustc has a notion of builtin unsafe blocks, but we don't). + statements + .extend(fmt.orphans.into_iter().map(|expr| Statement::Expr { expr, has_semi: true })); + + if !statements.is_empty() { + // Generate: + // { + // super let … + // super let … + // ::new(…) + // } + self.alloc_expr( + Expr::Block { + id: None, + statements: statements.into_boxed_slice(), + tail: Some(call), + label: None, + }, + syntax_ptr, + ) + } else { + call + } + } + + /// Get the value for a `width` or `precision` field. + /// + /// Returns the value and whether it is indirect (an indexed argument) or not. + fn make_count_after_1_93_0( + &self, + count: &FormatCount, + argmap: &mut FxIndexSet<(usize, ArgumentType)>, + ) -> (bool, u16) { + match count { + FormatCount::Literal(n) => (false, *n), + FormatCount::Argument(arg) => { + let index = match &arg.index { + &Ok(it) => it, + Err(_) => usize::MAX, + }; + (true, argmap.insert_full((index, ArgumentType::Usize)).0 as u16) + } + } + } + + fn collect_format_args_before_1_93_0_impl( + &mut self, + syntax_ptr: AstPtr, + fmt: FormatArgs, + ) -> ExprId { // Create a list of all _unique_ (argument, format trait) combinations. // E.g. "{0} {0:x} {0} {1}" -> [(0, Display), (0, LowerHex), (1, Display)] let mut argmap = FxIndexSet::default(); @@ -160,8 +502,14 @@ impl<'db> ExprCollector<'db> { let fmt_unsafe_arg = lang_items.FormatUnsafeArg; let use_format_args_since_1_89_0 = fmt_args.is_some() && fmt_unsafe_arg.is_none(); - let idx = if use_format_args_since_1_89_0 { - self.collect_format_args_impl(syntax_ptr, fmt, argmap, lit_pieces, format_options) + if use_format_args_since_1_89_0 { + self.collect_format_args_after_1_89_0_impl( + syntax_ptr, + fmt, + argmap, + lit_pieces, + format_options, + ) } else { self.collect_format_args_before_1_89_0_impl( syntax_ptr, @@ -170,14 +518,7 @@ impl<'db> ExprCollector<'db> { lit_pieces, format_options, ) - }; - - self.store - .template_map - .get_or_insert_with(Default::default) - .format_args_to_captures - .insert(idx, (hygiene, mappings)); - idx + } } /// `format_args!` expansion implementation for rustc versions < `1.89.0` @@ -238,17 +579,10 @@ impl<'db> ExprCollector<'db> { // ) let lang_items = self.lang_items(); - let new_v1_formatted = self.ty_rel_lang_path( - lang_items.FormatArguments, - Name::new_symbol_root(sym::new_v1_formatted), - ); - let unsafe_arg_new = - self.ty_rel_lang_path(lang_items.FormatUnsafeArg, Name::new_symbol_root(sym::new)); let new_v1_formatted = - self.alloc_expr_desugared(new_v1_formatted.map_or(Expr::Missing, Expr::Path)); - + self.ty_rel_lang_path_desugared_expr(lang_items.FormatArguments, sym::new_v1_formatted); let unsafe_arg_new = - self.alloc_expr_desugared(unsafe_arg_new.map_or(Expr::Missing, Expr::Path)); + self.ty_rel_lang_path_desugared_expr(lang_items.FormatUnsafeArg, sym::new); let unsafe_arg_new = self.alloc_expr_desugared(Expr::Call { callee: unsafe_arg_new, args: Box::default() }); let mut unsafe_arg_new = self.alloc_expr_desugared(Expr::Unsafe { @@ -284,7 +618,7 @@ impl<'db> ExprCollector<'db> { /// `format_args!` expansion implementation for rustc versions >= `1.89.0`, /// especially since [this PR](https://github.com/rust-lang/rust/pull/140748) - fn collect_format_args_impl( + fn collect_format_args_after_1_89_0_impl( &mut self, syntax_ptr: AstPtr, fmt: FormatArgs, @@ -422,12 +756,10 @@ impl<'db> ExprCollector<'db> { // ) // } - let new_v1_formatted = self.ty_rel_lang_path( + let new_v1_formatted = self.ty_rel_lang_path_desugared_expr( self.lang_items().FormatArguments, - Name::new_symbol_root(sym::new_v1_formatted), + sym::new_v1_formatted, ); - let new_v1_formatted = - self.alloc_expr_desugared(new_v1_formatted.map_or(Expr::Missing, Expr::Path)); let args = [lit_pieces, args, format_options]; let call = self .alloc_expr_desugared(Expr::Call { callee: new_v1_formatted, args: args.into() }); @@ -499,8 +831,8 @@ impl<'db> ExprCollector<'db> { debug_hex, } = &placeholder.format_options; - let precision_expr = self.make_count(precision, argmap); - let width_expr = self.make_count(width, argmap); + let precision_expr = self.make_count_before_1_93_0(precision, argmap); + let width_expr = self.make_count_before_1_93_0(width, argmap); if self.krate.workspace_data(self.db).is_atleast_187() { // These need to match the constants in library/core/src/fmt/rt.rs. @@ -542,16 +874,8 @@ impl<'db> ExprCollector<'db> { spread: None, }) } else { - let format_placeholder_new = { - let format_placeholder_new = self.ty_rel_lang_path( - lang_items.FormatPlaceholder, - Name::new_symbol_root(sym::new), - ); - match format_placeholder_new { - Some(path) => self.alloc_expr_desugared(Expr::Path(path)), - None => self.missing_expr(), - } - }; + let format_placeholder_new = + self.ty_rel_lang_path_desugared_expr(lang_items.FormatPlaceholder, sym::new); // This needs to match `Flag` in library/core/src/fmt/rt.rs. let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32) | (((sign == Some(FormatSign::Minus)) as u32) << 1) @@ -564,21 +888,15 @@ impl<'db> ExprCollector<'db> { Some(BuiltinUint::U32), ))); let fill = self.alloc_expr_desugared(Expr::Literal(Literal::Char(fill.unwrap_or(' ')))); - let align = { - let align = self.ty_rel_lang_path( - lang_items.FormatAlignment, - match alignment { - Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left), - Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right), - Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center), - None => Name::new_symbol_root(sym::Unknown), - }, - ); - match align { - Some(path) => self.alloc_expr_desugared(Expr::Path(path)), - None => self.missing_expr(), - } - }; + let align = self.ty_rel_lang_path_desugared_expr( + lang_items.FormatAlignment, + match alignment { + Some(FormatAlignment::Left) => sym::Left, + Some(FormatAlignment::Right) => sym::Right, + Some(FormatAlignment::Center) => sym::Center, + None => sym::Unknown, + }, + ); self.alloc_expr_desugared(Expr::Call { callee: format_placeholder_new, args: Box::new([position, fill, align, flags, precision_expr, width_expr]), @@ -605,7 +923,7 @@ impl<'db> ExprCollector<'db> { /// ```text /// ::Implied /// ``` - fn make_count( + fn make_count_before_1_93_0( &mut self, count: &Option, argmap: &mut FxIndexSet<(usize, ArgumentType)>, @@ -618,12 +936,8 @@ impl<'db> ExprCollector<'db> { // FIXME: Change this to Some(BuiltinUint::U16) once we drop support for toolchains < 1.88 None, ))); - let count_is = match self - .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Is)) - { - Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)), - None => self.missing_expr(), - }; + let count_is = + self.ty_rel_lang_path_desugared_expr(lang_items.FormatCount, sym::Is); self.alloc_expr_desugared(Expr::Call { callee: count_is, args: Box::new([args]) }) } Some(FormatCount::Argument(arg)) => { @@ -634,12 +948,8 @@ impl<'db> ExprCollector<'db> { i as u128, Some(BuiltinUint::Usize), ))); - let count_param = match self - .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Param)) - { - Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), - None => self.missing_expr(), - }; + let count_param = + self.ty_rel_lang_path_desugared_expr(lang_items.FormatCount, sym::Param); self.alloc_expr_desugared(Expr::Call { callee: count_param, args: Box::new([args]), @@ -650,9 +960,7 @@ impl<'db> ExprCollector<'db> { self.missing_expr() } } - None => match self - .ty_rel_lang_path(lang_items.FormatCount, Name::new_symbol_root(sym::Implied)) - { + None => match self.ty_rel_lang_path(lang_items.FormatCount, sym::Implied) { Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)), None => self.missing_expr(), }, @@ -670,9 +978,9 @@ impl<'db> ExprCollector<'db> { use ArgumentType::*; use FormatTrait::*; - let new_fn = match self.ty_rel_lang_path( + let new_fn = self.ty_rel_lang_path_desugared_expr( self.lang_items().FormatArgument, - Name::new_symbol_root(match ty { + match ty { Format(Display) => sym::new_display, Format(Debug) => sym::new_debug, Format(LowerExp) => sym::new_lower_exp, @@ -683,13 +991,18 @@ impl<'db> ExprCollector<'db> { Format(LowerHex) => sym::new_lower_hex, Format(UpperHex) => sym::new_upper_hex, Usize => sym::from_usize, - }), - ) { - Some(new_fn) => self.alloc_expr_desugared(Expr::Path(new_fn)), - None => self.missing_expr(), - }; + }, + ); self.alloc_expr_desugared(Expr::Call { callee: new_fn, args: Box::new([arg]) }) } + + fn ty_rel_lang_path_desugared_expr( + &mut self, + lang: Option>, + relative_name: Symbol, + ) -> ExprId { + self.alloc_expr_desugared(self.ty_rel_lang_path_expr(lang, relative_name)) + } } #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs index 22ade4387582..7e48ca8f4558 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs @@ -161,9 +161,9 @@ fn main() { match builtin#lang(into_iter)( 0..10, ) { - mut 11 => loop { + mut 0 => loop { match builtin#lang(next)( - &mut 11, + &mut 0, ) { builtin#lang(None) => break, builtin#lang(Some)(ident) => { @@ -261,10 +261,10 @@ fn main() { } #[test] -fn desugar_builtin_format_args() { +fn desugar_builtin_format_args_before_1_93_0() { let (db, body, def) = lower( r#" -//- minicore: fmt +//- minicore: fmt_before_1_93_0 fn main() { let are = "are"; let count = 10; @@ -343,6 +343,59 @@ fn main() { .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) } +#[test] +fn desugar_builtin_format_args() { + let (db, body, def) = lower( + r#" +//- minicore: fmt +fn main() { + let are = "are"; + let count = 10; + builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", orphan = (), last = "!"); + builtin#format_args("hello world"); + builtin#format_args("hello world", orphan = ()); +} +"#, + ); + + expect![[r#" + fn main() { + let are = "are"; + let count = 10; + { + let 0 = (&"fancy", &(), &"!", &count, &are, ); + let 0 = [ + builtin#lang(Argument::new_display)( + 0.3, + ), builtin#lang(Argument::new_display)( + 0.0, + ), builtin#lang(Argument::new_debug)( + 0.4, + ), builtin#lang(Argument::new_display)( + 0.2, + ), + ]; + (); + unsafe { + builtin#lang(Arguments::new)( + "\x07\x1bhello \xc3 \x00\x00i\x02\x00\x01 \xc0\r friends, we \xc0\x01 \xc8\x01\x00\xc8\x03\x00\x00", + &0, + ) + } + }; + builtin#lang(Arguments::from_str)( + "hello world", + ); + { + (); + builtin#lang(Arguments::from_str)( + "hello world", + ) + }; + }"#]] + .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) +} + #[test] fn test_macro_hygiene() { let (db, body, def) = lower( @@ -382,27 +435,16 @@ impl SsrError { fn main() { _ = ra_test_fixture::error::SsrError::new( { - let args = [ + let 0 = (&node.text(), ); + let 0 = [ builtin#lang(Argument::new_display)( - &node.text(), + 0.0, ), ]; unsafe { - builtin#lang(Arguments::new_v1_formatted)( - &[ - "Failed to resolve path `", "`", - ], - &args, - &[ - builtin#lang(Placeholder::new)( - 0usize, - ' ', - builtin#lang(Alignment::Unknown), - 0u32, - builtin#lang(Count::Implied), - builtin#lang(Count::Implied), - ), - ], + builtin#lang(Arguments::new)( + "\x18Failed to resolve path `\xc0\x01`\x00", + &0, ) } }, diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index 0fe17e3075de..b7c09391ec37 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs @@ -34,7 +34,8 @@ //! eq: sized //! error: fmt //! fmt: option, result, transmute, coerce_unsized, copy, clone, derive -//! fmt_before_1_89_0: fmt +//! fmt_before_1_93_0: fmt +//! fmt_before_1_89_0: fmt_before_1_93_0 //! fn: sized, tuple //! from: sized, result //! future: pin @@ -1259,6 +1260,7 @@ pub mod fmt { Unknown, } + // region:fmt_before_1_93_0 #[lang = "format_count"] pub enum Count { Is(usize), @@ -1288,6 +1290,7 @@ pub mod fmt { Placeholder { position, fill, align, flags, precision, width } } } + // endregion:fmt_before_1_93_0 // region:fmt_before_1_89_0 #[lang = "format_unsafe_arg"] @@ -1303,6 +1306,7 @@ pub mod fmt { // endregion:fmt_before_1_89_0 } + // region:fmt_before_1_93_0 #[derive(Copy, Clone)] #[lang = "format_arguments"] pub struct Arguments<'a> { @@ -1341,6 +1345,14 @@ pub mod fmt { } // endregion:!fmt_before_1_89_0 + pub fn from_str_nonconst(s: &'static str) -> Arguments<'a> { + Self::from_str(s) + } + + pub const fn from_str(s: &'static str) -> Arguments<'a> { + Arguments { pieces: &[s], fmt: None, args: &[] } + } + pub const fn as_str(&self) -> Option<&'static str> { match (self.pieces, self.args) { ([], []) => Some(""), @@ -1349,6 +1361,41 @@ pub mod fmt { } } } + // endregion:fmt_before_1_93_0 + + // region:!fmt_before_1_93_0 + #[lang = "format_arguments"] + #[derive(Copy, Clone)] + pub struct Arguments<'a> { + // This is a non-faithful representation of `core::fmt::Arguments`, because the real one + // is too complex for minicore. + message: Option<&'a str>, + } + + impl<'a> Arguments<'a> { + pub unsafe fn new( + _template: &'a [u8; N], + _args: &'a [rt::Argument<'a>; M], + ) -> Arguments<'a> { + Arguments { message: None } + } + + pub fn from_str_nonconst(s: &'static str) -> Arguments<'a> { + Arguments { message: Some(s) } + } + + pub const fn from_str(s: &'static str) -> Arguments<'a> { + Arguments { message: Some(s) } + } + + pub fn as_str(&self) -> Option<&'static str> { + match self.message { + Some(s) => unsafe { Some(&*(s as *const str)) }, + None => None, + } + } + } + // endregion:!fmt_before_1_93_0 // region:derive pub(crate) mod derive { @@ -1817,7 +1864,7 @@ mod panicking { #[lang = "panic"] pub const fn panic(expr: &'static str) -> ! { - panic_fmt(crate::fmt::Arguments::new_const(&[expr])) + panic_fmt(crate::fmt::Arguments::from_str(expr)) } } // endregion:panic From 96a700010103799b6988ab9800f72f2f2b43b696 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 8 Dec 2025 16:25:43 +0300 Subject: [PATCH 0562/3801] Rename some issue-* tests --- src/tools/tidy/src/issues.txt | 4 ---- .../const-item-no-type/dont-suggest-type-error.rs} | 0 .../const-item-no-type/dont-suggest-type-error.stderr} | 4 ++-- .../const-item-no-type/empty-array.rs} | 0 .../const-item-no-type/empty-array.stderr} | 4 ++-- .../const-item-no-type/in-macro.rs} | 0 .../const-item-no-type/in-macro.stderr} | 6 +++--- .../const-item-no-type/with-colon.fixed} | 0 .../const-item-no-type/with-colon.rs} | 0 .../const-item-no-type/with-colon.stderr} | 4 ++-- 10 files changed, 9 insertions(+), 13 deletions(-) rename tests/ui/{typeck/issue-79040.rs => consts/const-item-no-type/dont-suggest-type-error.rs} (100%) rename tests/ui/{typeck/issue-79040.stderr => consts/const-item-no-type/dont-suggest-type-error.stderr} (85%) rename tests/ui/{parser/issues/issue-89574.rs => consts/const-item-no-type/empty-array.rs} (100%) rename tests/ui/{parser/issues/issue-89574.stderr => consts/const-item-no-type/empty-array.stderr} (88%) rename tests/ui/{macros/issue-69396-const-no-type-in-macro.rs => consts/const-item-no-type/in-macro.rs} (100%) rename tests/ui/{macros/issue-69396-const-no-type-in-macro.stderr => consts/const-item-no-type/in-macro.stderr} (89%) rename tests/ui/{typeck/issue-100164.fixed => consts/const-item-no-type/with-colon.fixed} (100%) rename tests/ui/{typeck/issue-100164.rs => consts/const-item-no-type/with-colon.rs} (100%) rename tests/ui/{typeck/issue-100164.stderr => consts/const-item-no-type/with-colon.stderr} (82%) diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 1500c82c411a..45187a0b6450 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -1583,7 +1583,6 @@ ui/macros/issue-6596-1.rs ui/macros/issue-6596-2.rs ui/macros/issue-68058.rs ui/macros/issue-68060.rs -ui/macros/issue-69396-const-no-type-in-macro.rs ui/macros/issue-69838-mods-relative-to-included-path.rs ui/macros/issue-70446.rs ui/macros/issue-75982-foreign-macro-weird-mod.rs @@ -2100,7 +2099,6 @@ ui/parser/issues/issue-88770.rs ui/parser/issues/issue-88818.rs ui/parser/issues/issue-89388.rs ui/parser/issues/issue-89396.rs -ui/parser/issues/issue-89574.rs ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs ui/parser/issues/issue-90728.rs ui/parser/issues/issue-90993.rs @@ -2880,7 +2878,6 @@ ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs ui/typeck/auxiliary/issue-29181.rs ui/typeck/auxiliary/issue-36708.rs ui/typeck/auxiliary/issue-81943-lib.rs -ui/typeck/issue-100164.rs ui/typeck/issue-100246.rs ui/typeck/issue-100285.rs ui/typeck/issue-103899.rs @@ -2937,7 +2934,6 @@ ui/typeck/issue-74933.rs ui/typeck/issue-75883.rs ui/typeck/issue-75889.rs ui/typeck/issue-7813.rs -ui/typeck/issue-79040.rs ui/typeck/issue-80207-unsized-return.rs ui/typeck/issue-80779.rs ui/typeck/issue-81293.rs diff --git a/tests/ui/typeck/issue-79040.rs b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs similarity index 100% rename from tests/ui/typeck/issue-79040.rs rename to tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs diff --git a/tests/ui/typeck/issue-79040.stderr b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr similarity index 85% rename from tests/ui/typeck/issue-79040.stderr rename to tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr index 4ab8df8f6c93..8f1fcc645b9c 100644 --- a/tests/ui/typeck/issue-79040.stderr +++ b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr @@ -1,5 +1,5 @@ error[E0369]: cannot add `{integer}` to `&str` - --> $DIR/issue-79040.rs:2:25 + --> $DIR/dont-suggest-type-error.rs:2:25 | LL | const FOO = "hello" + 1; | ------- ^ - {integer} @@ -7,7 +7,7 @@ LL | const FOO = "hello" + 1; | &str error: missing type for `const` item - --> $DIR/issue-79040.rs:2:14 + --> $DIR/dont-suggest-type-error.rs:2:14 | LL | const FOO = "hello" + 1; | ^ diff --git a/tests/ui/parser/issues/issue-89574.rs b/tests/ui/consts/const-item-no-type/empty-array.rs similarity index 100% rename from tests/ui/parser/issues/issue-89574.rs rename to tests/ui/consts/const-item-no-type/empty-array.rs diff --git a/tests/ui/parser/issues/issue-89574.stderr b/tests/ui/consts/const-item-no-type/empty-array.stderr similarity index 88% rename from tests/ui/parser/issues/issue-89574.stderr rename to tests/ui/consts/const-item-no-type/empty-array.stderr index f40f5aded8ef..fe307d50353e 100644 --- a/tests/ui/parser/issues/issue-89574.stderr +++ b/tests/ui/consts/const-item-no-type/empty-array.stderr @@ -1,11 +1,11 @@ error[E0282]: type annotations needed - --> $DIR/issue-89574.rs:2:25 + --> $DIR/empty-array.rs:2:25 | LL | const EMPTY_ARRAY = []; | ^^ cannot infer type error: missing type for `const` item - --> $DIR/issue-89574.rs:2:22 + --> $DIR/empty-array.rs:2:22 | LL | const EMPTY_ARRAY = []; | ^ diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.rs b/tests/ui/consts/const-item-no-type/in-macro.rs similarity index 100% rename from tests/ui/macros/issue-69396-const-no-type-in-macro.rs rename to tests/ui/consts/const-item-no-type/in-macro.rs diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr b/tests/ui/consts/const-item-no-type/in-macro.stderr similarity index 89% rename from tests/ui/macros/issue-69396-const-no-type-in-macro.stderr rename to tests/ui/consts/const-item-no-type/in-macro.stderr index 4342d7d88f54..d6182aa11427 100644 --- a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr +++ b/tests/ui/consts/const-item-no-type/in-macro.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `A` is defined multiple times - --> $DIR/issue-69396-const-no-type-in-macro.rs:4:13 + --> $DIR/in-macro.rs:4:13 | LL | const A = "A".$fn(); | ^^^^^^^^^^^^^^^^^^^^ `A` redefined here @@ -14,7 +14,7 @@ LL | | } = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) error: missing type for `const` item - --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20 + --> $DIR/in-macro.rs:4:20 | LL | const A = "A".$fn(); | ^ help: provide a type for the constant: `: usize` @@ -28,7 +28,7 @@ LL | | } = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0121]: missing type for item - --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20 + --> $DIR/in-macro.rs:4:20 | LL | const A = "A".$fn(); | ^ not allowed in type signatures diff --git a/tests/ui/typeck/issue-100164.fixed b/tests/ui/consts/const-item-no-type/with-colon.fixed similarity index 100% rename from tests/ui/typeck/issue-100164.fixed rename to tests/ui/consts/const-item-no-type/with-colon.fixed diff --git a/tests/ui/typeck/issue-100164.rs b/tests/ui/consts/const-item-no-type/with-colon.rs similarity index 100% rename from tests/ui/typeck/issue-100164.rs rename to tests/ui/consts/const-item-no-type/with-colon.rs diff --git a/tests/ui/typeck/issue-100164.stderr b/tests/ui/consts/const-item-no-type/with-colon.stderr similarity index 82% rename from tests/ui/typeck/issue-100164.stderr rename to tests/ui/consts/const-item-no-type/with-colon.stderr index 06a132d65142..adbea1f355a0 100644 --- a/tests/ui/typeck/issue-100164.stderr +++ b/tests/ui/consts/const-item-no-type/with-colon.stderr @@ -1,11 +1,11 @@ error: missing type for `const` item - --> $DIR/issue-100164.rs:3:10 + --> $DIR/with-colon.rs:3:10 | LL | const _A: = 123; | ^ help: provide a type for the constant: `i32` error: missing type for `const` item - --> $DIR/issue-100164.rs:7:14 + --> $DIR/with-colon.rs:7:14 | LL | const _B: = 123; | ^ help: provide a type for the constant: `i32` From dc0bf26dd4aa7641644204a3cd9b42d20017582c Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sun, 2 Nov 2025 23:28:02 +0000 Subject: [PATCH 0563/3801] fix: `match_like_matches_macro` wrongly unmangled macros --- .../src/matches/match_like_matches.rs | 18 +++--- tests/ui/match_like_matches_macro.fixed | 22 +++++++ tests/ui/match_like_matches_macro.rs | 25 ++++++++ tests/ui/match_like_matches_macro.stderr | 62 ++++++++++++++----- 4 files changed, 100 insertions(+), 27 deletions(-) diff --git a/clippy_lints/src/matches/match_like_matches.rs b/clippy_lints/src/matches/match_like_matches.rs index 89411115f730..c26b2dbde7fc 100644 --- a/clippy_lints/src/matches/match_like_matches.rs +++ b/clippy_lints/src/matches/match_like_matches.rs @@ -3,7 +3,7 @@ use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::has_let_expr; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment}; use rustc_ast::LitKind; use rustc_errors::Applicability; @@ -44,6 +44,8 @@ pub(crate) fn check_if_let<'tcx>( { ex_new = ex_inner; } + + let (snippet, _) = snippet_with_context(cx, ex_new.span, expr.span.ctxt(), "..", &mut applicability); span_lint_and_then( cx, MATCH_LIKE_MATCHES_MACRO, @@ -53,11 +55,7 @@ pub(crate) fn check_if_let<'tcx>( diag.span_suggestion_verbose( expr.span, "use `matches!` directly", - format!( - "{}matches!({}, {pat})", - if b0 { "" } else { "!" }, - snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), - ), + format!("{}matches!({snippet}, {pat})", if b0 { "" } else { "!" }), applicability, ); }, @@ -178,6 +176,8 @@ pub(super) fn check_match<'tcx>( { ex_new = ex_inner; } + + let (snippet, _) = snippet_with_context(cx, ex_new.span, e.span.ctxt(), "..", &mut applicability); span_lint_and_then( cx, MATCH_LIKE_MATCHES_MACRO, @@ -187,11 +187,7 @@ pub(super) fn check_match<'tcx>( diag.span_suggestion_verbose( e.span, "use `matches!` directly", - format!( - "{}matches!({}, {pat_and_guard})", - if b0 { "" } else { "!" }, - snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), - ), + format!("{}matches!({snippet}, {pat_and_guard})", if b0 { "" } else { "!" },), applicability, ); }, diff --git a/tests/ui/match_like_matches_macro.fixed b/tests/ui/match_like_matches_macro.fixed index dad59c1ce6e4..045ee32bd8bb 100644 --- a/tests/ui/match_like_matches_macro.fixed +++ b/tests/ui/match_like_matches_macro.fixed @@ -1,6 +1,7 @@ #![warn(clippy::match_like_matches_macro)] #![allow( unreachable_patterns, + irrefutable_let_patterns, clippy::equatable_if_let, clippy::needless_borrowed_reference, clippy::redundant_guards @@ -230,3 +231,24 @@ fn issue15841(opt: Option>>, value: i32) { let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() })); //~^^^^ match_like_matches_macro } + +fn issue16015() -> bool { + use std::any::{TypeId, type_name}; + pub struct GetTypeId(T); + + impl GetTypeId { + pub const VALUE: TypeId = TypeId::of::(); + } + + macro_rules! typeid { + ($t:ty) => { + GetTypeId::<$t>::VALUE + }; + } + + matches!(typeid!(T), _); + //~^^^^ match_like_matches_macro + + matches!(typeid!(U), _) + //~^ match_like_matches_macro +} diff --git a/tests/ui/match_like_matches_macro.rs b/tests/ui/match_like_matches_macro.rs index 94bc6433e5cb..231e1ae98f86 100644 --- a/tests/ui/match_like_matches_macro.rs +++ b/tests/ui/match_like_matches_macro.rs @@ -1,6 +1,7 @@ #![warn(clippy::match_like_matches_macro)] #![allow( unreachable_patterns, + irrefutable_let_patterns, clippy::equatable_if_let, clippy::needless_borrowed_reference, clippy::redundant_guards @@ -277,3 +278,27 @@ fn issue15841(opt: Option>>, value: i32) { }; //~^^^^ match_like_matches_macro } + +fn issue16015() -> bool { + use std::any::{TypeId, type_name}; + pub struct GetTypeId(T); + + impl GetTypeId { + pub const VALUE: TypeId = TypeId::of::(); + } + + macro_rules! typeid { + ($t:ty) => { + GetTypeId::<$t>::VALUE + }; + } + + match typeid!(T) { + _ => true, + _ => false, + }; + //~^^^^ match_like_matches_macro + + if let _ = typeid!(U) { true } else { false } + //~^ match_like_matches_macro +} diff --git a/tests/ui/match_like_matches_macro.stderr b/tests/ui/match_like_matches_macro.stderr index a8e352461dbb..bc3e3584938e 100644 --- a/tests/ui/match_like_matches_macro.stderr +++ b/tests/ui/match_like_matches_macro.stderr @@ -1,5 +1,5 @@ error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:13:14 + --> tests/ui/match_like_matches_macro.rs:14:14 | LL | let _y = match x { | ______________^ @@ -20,7 +20,7 @@ LL + let _y = matches!(x, Some(0)); | error: redundant pattern matching, consider using `is_some()` - --> tests/ui/match_like_matches_macro.rs:20:14 + --> tests/ui/match_like_matches_macro.rs:21:14 | LL | let _w = match x { | ______________^ @@ -33,7 +33,7 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/match_like_matches_macro.rs:27:14 + --> tests/ui/match_like_matches_macro.rs:28:14 | LL | let _z = match x { | ______________^ @@ -43,7 +43,7 @@ LL | | }; | |_____^ help: try: `x.is_none()` error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:34:15 + --> tests/ui/match_like_matches_macro.rs:35:15 | LL | let _zz = match x { | _______________^ @@ -62,7 +62,7 @@ LL + let _zz = !matches!(x, Some(r) if r == 0); | error: `if let .. else` expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:41:16 + --> tests/ui/match_like_matches_macro.rs:42:16 | LL | let _zzz = if let Some(5) = x { true } else { false }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL + let _zzz = matches!(x, Some(5)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:66:20 + --> tests/ui/match_like_matches_macro.rs:67:20 | LL | let _ans = match x { | ____________________^ @@ -95,7 +95,7 @@ LL + let _ans = matches!(x, E::A(_) | E::B(_)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:77:20 + --> tests/ui/match_like_matches_macro.rs:78:20 | LL | let _ans = match x { | ____________________^ @@ -119,7 +119,7 @@ LL + let _ans = matches!(x, E::A(_) | E::B(_)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:88:20 + --> tests/ui/match_like_matches_macro.rs:89:20 | LL | let _ans = match x { | ____________________^ @@ -140,7 +140,7 @@ LL + let _ans = !matches!(x, E::B(_) | E::C); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:149:18 + --> tests/ui/match_like_matches_macro.rs:150:18 | LL | let _z = match &z { | __________________^ @@ -159,7 +159,7 @@ LL + let _z = matches!(z, Some(3)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:159:18 + --> tests/ui/match_like_matches_macro.rs:160:18 | LL | let _z = match &z { | __________________^ @@ -178,7 +178,7 @@ LL + let _z = matches!(&z, Some(3)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:177:21 + --> tests/ui/match_like_matches_macro.rs:178:21 | LL | let _ = match &z { | _____________________^ @@ -197,7 +197,7 @@ LL + let _ = matches!(&z, AnEnum::X); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:192:20 + --> tests/ui/match_like_matches_macro.rs:193:20 | LL | let _res = match &val { | ____________________^ @@ -216,7 +216,7 @@ LL + let _res = matches!(&val, &Some(ref _a)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:205:20 + --> tests/ui/match_like_matches_macro.rs:206:20 | LL | let _res = match &val { | ____________________^ @@ -235,7 +235,7 @@ LL + let _res = matches!(&val, &Some(ref _a)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:264:14 + --> tests/ui/match_like_matches_macro.rs:265:14 | LL | let _y = match Some(5) { | ______________^ @@ -254,7 +254,7 @@ LL + let _y = matches!(Some(5), Some(0)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:274:13 + --> tests/ui/match_like_matches_macro.rs:275:13 | LL | let _ = match opt { | _____________^ @@ -272,5 +272,35 @@ LL - }; LL + let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() })); | -error: aborting due to 15 previous errors +error: match expression looks like `matches!` macro + --> tests/ui/match_like_matches_macro.rs:296:5 + | +LL | / match typeid!(T) { +LL | | _ => true, +LL | | _ => false, +LL | | }; + | |_____^ + | +help: use `matches!` directly + | +LL - match typeid!(T) { +LL - _ => true, +LL - _ => false, +LL - }; +LL + matches!(typeid!(T), _); + | + +error: `if let .. else` expression looks like `matches!` macro + --> tests/ui/match_like_matches_macro.rs:302:5 + | +LL | if let _ = typeid!(U) { true } else { false } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `matches!` directly + | +LL - if let _ = typeid!(U) { true } else { false } +LL + matches!(typeid!(U), _) + | + +error: aborting due to 17 previous errors From 4ce7628869af3def2902a55b0c682d56d498c7f3 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 27 Nov 2025 21:19:53 +0100 Subject: [PATCH 0564/3801] clean-up --- clippy_utils/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index ed164fcf371b..10220a3da180 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -2490,7 +2490,7 @@ pub enum DefinedTy<'tcx> { /// in the context of its definition site. We also track the `def_id` of its /// definition site. /// - /// WARNING: As the `ty` in in the scope of the definition, not of the function + /// WARNING: As the `ty` is in the scope of the definition, not of the function /// using it, you must be very careful with how you use it. Using it in the wrong /// scope easily results in ICEs. Mir { @@ -2719,7 +2719,6 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'tcx>) -> ExprUseCtx moved_before_use, same_ctxt, }, - Some(ControlFlow::Break(_)) => unreachable!("type of node is ControlFlow"), None => ExprUseCtxt { node: Node::Crate(cx.tcx.hir_root_module()), child_id: HirId::INVALID, From 2bc2a0db6956f960a5218cea19f07ff8dd4c04cd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Dec 2025 20:18:42 +0100 Subject: [PATCH 0565/3801] For now, ignore target checking for doc attributes in attr_parsing --- .../rustc_attr_parsing/src/attributes/doc.rs | 66 ++++++++++--------- .../ui/attributes/issue-115264-expr-field.rs | 2 - .../attributes/issue-115264-expr-field.stderr | 12 ---- tests/ui/attributes/issue-115264-pat-field.rs | 2 - .../attributes/issue-115264-pat-field.stderr | 12 ---- tests/ui/lint/unused/useless-comment.rs | 6 -- tests/ui/lint/unused/useless-comment.stderr | 62 +++++------------ .../rustdoc/check-doc-alias-attr-location.rs | 8 --- .../check-doc-alias-attr-location.stderr | 45 ++----------- 9 files changed, 53 insertions(+), 162 deletions(-) delete mode 100644 tests/ui/attributes/issue-115264-expr-field.stderr delete mode 100644 tests/ui/attributes/issue-115264-pat-field.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index ccb6a873fb12..2fe1b4ad174c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -7,7 +7,7 @@ use rustc_hir::lints::AttributeLintKind; use rustc_span::{Span, Symbol, edition, sym}; use thin_vec::ThinVec; -use super::prelude::{Allow, AllowedTargets, Error, MethodKind, Target}; +use super::prelude::{ALL_TARGETS, AllowedTargets}; use super::{AcceptMapping, AttributeParser}; use crate::context::{AcceptContext, FinalizeContext, Stage}; use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, PathParser}; @@ -583,37 +583,39 @@ impl AttributeParser for DocParser { this.accept_single_doc_attr(cx, args); }, )]; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ - Allow(Target::ExternCrate), - Allow(Target::Use), - Allow(Target::Static), - Allow(Target::Const), - Allow(Target::Fn), - Allow(Target::Mod), - Allow(Target::ForeignMod), - Allow(Target::TyAlias), - Allow(Target::Enum), - Allow(Target::Variant), - Allow(Target::Struct), - Allow(Target::Field), - Allow(Target::Union), - Allow(Target::Trait), - Allow(Target::TraitAlias), - Allow(Target::Impl { of_trait: true }), - Allow(Target::Impl { of_trait: false }), - Allow(Target::AssocConst), - Allow(Target::Method(MethodKind::Inherent)), - Allow(Target::Method(MethodKind::Trait { body: true })), - Allow(Target::Method(MethodKind::Trait { body: false })), - Allow(Target::Method(MethodKind::TraitImpl)), - Allow(Target::AssocTy), - Allow(Target::ForeignFn), - Allow(Target::ForeignStatic), - Allow(Target::ForeignTy), - Allow(Target::MacroDef), - Allow(Target::Crate), - Error(Target::WherePredicate), - ]); + // FIXME: Currently emitted from 2 different places, generating duplicated warnings. + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + // const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + // Allow(Target::ExternCrate), + // Allow(Target::Use), + // Allow(Target::Static), + // Allow(Target::Const), + // Allow(Target::Fn), + // Allow(Target::Mod), + // Allow(Target::ForeignMod), + // Allow(Target::TyAlias), + // Allow(Target::Enum), + // Allow(Target::Variant), + // Allow(Target::Struct), + // Allow(Target::Field), + // Allow(Target::Union), + // Allow(Target::Trait), + // Allow(Target::TraitAlias), + // Allow(Target::Impl { of_trait: true }), + // Allow(Target::Impl { of_trait: false }), + // Allow(Target::AssocConst), + // Allow(Target::Method(MethodKind::Inherent)), + // Allow(Target::Method(MethodKind::Trait { body: true })), + // Allow(Target::Method(MethodKind::Trait { body: false })), + // Allow(Target::Method(MethodKind::TraitImpl)), + // Allow(Target::AssocTy), + // Allow(Target::ForeignFn), + // Allow(Target::ForeignStatic), + // Allow(Target::ForeignTy), + // Allow(Target::MacroDef), + // Allow(Target::Crate), + // Error(Target::WherePredicate), + // ]); fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { if self.nb_doc_attrs != 0 { diff --git a/tests/ui/attributes/issue-115264-expr-field.rs b/tests/ui/attributes/issue-115264-expr-field.rs index d8189626fb0f..8adb68deb5b4 100644 --- a/tests/ui/attributes/issue-115264-expr-field.rs +++ b/tests/ui/attributes/issue-115264-expr-field.rs @@ -12,8 +12,6 @@ struct X { fn main() { let _ = X { #[doc(alias = "StructItem")] - //~^ WARN: attribute cannot be used on struct fields - //~| WARN: this was previously accepted by the compiler but is being phased out foo: 123, }; } diff --git a/tests/ui/attributes/issue-115264-expr-field.stderr b/tests/ui/attributes/issue-115264-expr-field.stderr deleted file mode 100644 index 6bb9dfc90c93..000000000000 --- a/tests/ui/attributes/issue-115264-expr-field.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: `#[doc]` attribute cannot be used on struct fields - --> $DIR/issue-115264-expr-field.rs:14:9 - | -LL | #[doc(alias = "StructItem")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements - = note: requested on the command line with `-W unused-attributes` - -warning: 1 warning emitted - diff --git a/tests/ui/attributes/issue-115264-pat-field.rs b/tests/ui/attributes/issue-115264-pat-field.rs index 0c8966b5893f..53e3b4524d60 100644 --- a/tests/ui/attributes/issue-115264-pat-field.rs +++ b/tests/ui/attributes/issue-115264-pat-field.rs @@ -12,8 +12,6 @@ struct X { fn main() { let X { #[doc(alias = "StructItem")] - //~^ WARN: attribute cannot be used on pattern fields - //~| WARN: this was previously accepted by the compiler but is being phased out foo } = X { foo: 123 diff --git a/tests/ui/attributes/issue-115264-pat-field.stderr b/tests/ui/attributes/issue-115264-pat-field.stderr deleted file mode 100644 index a5b221110789..000000000000 --- a/tests/ui/attributes/issue-115264-pat-field.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: `#[doc]` attribute cannot be used on pattern fields - --> $DIR/issue-115264-pat-field.rs:14:9 - | -LL | #[doc(alias = "StructItem")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements - = note: requested on the command line with `-W unused-attributes` - -warning: 1 warning emitted - diff --git a/tests/ui/lint/unused/useless-comment.rs b/tests/ui/lint/unused/useless-comment.rs index fee6cff640f6..24ff91752081 100644 --- a/tests/ui/lint/unused/useless-comment.rs +++ b/tests/ui/lint/unused/useless-comment.rs @@ -18,8 +18,6 @@ fn foo() { /// a //~ ERROR unused doc comment #[doc(test(attr(allow(dead_code))))] //~^ ERROR unused doc comment - //~| ERROR `#[doc]` attribute cannot be used on statements - //~| WARN this was previously accepted by the compiler let x = 12; /// multi-line //~ ERROR unused doc comment @@ -30,8 +28,6 @@ fn foo() { 1 => {}, #[doc(test(attr(allow(dead_code))))] //~^ ERROR unused doc comment - //~| ERROR `#[doc]` attribute cannot be used on match arms [unused_attributes] - //~| WARN this was previously accepted by the compiler _ => {} } @@ -47,8 +43,6 @@ fn foo() { #[doc(test(attr(allow(dead_code))))] //~^ ERROR unused doc comment - //~| ERROR `#[doc]` attribute cannot be used on statements - //~| WARN this was previously accepted by the compiler let x = /** comment */ 47; //~ ERROR unused doc comment /// dox //~ ERROR unused doc comment diff --git a/tests/ui/lint/unused/useless-comment.stderr b/tests/ui/lint/unused/useless-comment.stderr index 3d3937e7a402..22e63caf607a 100644 --- a/tests/ui/lint/unused/useless-comment.stderr +++ b/tests/ui/lint/unused/useless-comment.stderr @@ -33,7 +33,7 @@ LL | unsafe extern "C" { } = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:45:5 + --> $DIR/useless-comment.rs:41:5 | LL | /// bar | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations @@ -56,14 +56,14 @@ error: unused doc comment | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... +LL | LL | let x = 12; | ----------- rustdoc does not generate documentation for statements | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:25:5 + --> $DIR/useless-comment.rs:23:5 | LL | / /// multi-line LL | | /// doc comment @@ -73,7 +73,7 @@ LL | / match x { LL | | /// c LL | | 1 => {}, LL | | #[doc(test(attr(allow(dead_code))))] -... | +LL | | LL | | _ => {} LL | | } | |_____- rustdoc does not generate documentation for expressions @@ -81,7 +81,7 @@ LL | | } = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:29:9 + --> $DIR/useless-comment.rs:27:9 | LL | /// c | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -91,18 +91,18 @@ LL | 1 => {}, = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:31:9 + --> $DIR/useless-comment.rs:29:9 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... +LL | LL | _ => {} | ------- rustdoc does not generate documentation for match arms | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:38:5 + --> $DIR/useless-comment.rs:34:5 | LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +112,7 @@ LL | unsafe {} = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:41:5 + --> $DIR/useless-comment.rs:37:5 | LL | #[doc = "foo"] | ^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ LL | 3; = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:42:5 + --> $DIR/useless-comment.rs:38:5 | LL | #[doc = "bar"] | ^^^^^^^^^^^^^^ @@ -133,18 +133,18 @@ LL | 3; = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:48:5 + --> $DIR/useless-comment.rs:44:5 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... +LL | LL | let x = /** comment */ 47; | -------------------------- rustdoc does not generate documentation for statements | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:52:13 + --> $DIR/useless-comment.rs:46:13 | LL | let x = /** comment */ 47; | ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions @@ -152,7 +152,7 @@ LL | let x = /** comment */ 47; = help: use `/* */` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:54:5 + --> $DIR/useless-comment.rs:48:5 | LL | /// dox | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,37 +163,5 @@ LL | | } | = help: use `//` for a plain comment -error: `#[doc]` attribute cannot be used on statements - --> $DIR/useless-comment.rs:19:5 - | -LL | #[doc(test(attr(allow(dead_code))))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements -note: the lint level is defined here - --> $DIR/useless-comment.rs:4:9 - | -LL | #![deny(unused_attributes)] - | ^^^^^^^^^^^^^^^^^ - -error: `#[doc]` attribute cannot be used on match arms - --> $DIR/useless-comment.rs:31:9 - | -LL | #[doc(test(attr(allow(dead_code))))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements - -error: `#[doc]` attribute cannot be used on statements - --> $DIR/useless-comment.rs:48:5 - | -LL | #[doc(test(attr(allow(dead_code))))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements - -error: aborting due to 18 previous errors +error: aborting due to 15 previous errors diff --git a/tests/ui/rustdoc/check-doc-alias-attr-location.rs b/tests/ui/rustdoc/check-doc-alias-attr-location.rs index 8ba6cfde2d6d..45777c5edf4d 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr-location.rs +++ b/tests/ui/rustdoc/check-doc-alias-attr-location.rs @@ -21,22 +21,14 @@ impl Foo for Bar { type X = i32; fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X { //~^ ERROR - //~| WARN `#[doc]` attribute cannot be used on function params - //~| WARN: this was previously accepted by the compiler #[doc(alias = "stmt")] //~^ ERROR - //~| WARN `#[doc]` attribute cannot be used on statements - //~| WARN: this was previously accepted by the compiler let x = 0; #[doc(alias = "expr")] //~^ ERROR - //~| WARN `#[doc]` attribute cannot be used on expressions - //~| WARN: this was previously accepted by the compiler match x { #[doc(alias = "arm")] //~^ ERROR - //~| WARN `#[doc]` attribute cannot be used on match arms - //~| WARN: this was previously accepted by the compiler _ => 0 } } diff --git a/tests/ui/rustdoc/check-doc-alias-attr-location.stderr b/tests/ui/rustdoc/check-doc-alias-attr-location.stderr index 24be42036f6f..f587c17c1f3e 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr-location.stderr +++ b/tests/ui/rustdoc/check-doc-alias-attr-location.stderr @@ -29,59 +29,22 @@ LL | #[doc(alias = "assoc")] | ^^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on statement - --> $DIR/check-doc-alias-attr-location.rs:26:23 + --> $DIR/check-doc-alias-attr-location.rs:24:23 | LL | #[doc(alias = "stmt")] | ^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on expression - --> $DIR/check-doc-alias-attr-location.rs:31:23 + --> $DIR/check-doc-alias-attr-location.rs:27:23 | LL | #[doc(alias = "expr")] | ^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on match arm - --> $DIR/check-doc-alias-attr-location.rs:36:27 + --> $DIR/check-doc-alias-attr-location.rs:30:27 | LL | #[doc(alias = "arm")] | ^^^^^ -warning: `#[doc]` attribute cannot be used on function params - --> $DIR/check-doc-alias-attr-location.rs:22:12 - | -LL | fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X { - | ^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements - = note: requested on the command line with `-W unused-attributes` - -warning: `#[doc]` attribute cannot be used on statements - --> $DIR/check-doc-alias-attr-location.rs:26:9 - | -LL | #[doc(alias = "stmt")] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements - -warning: `#[doc]` attribute cannot be used on expressions - --> $DIR/check-doc-alias-attr-location.rs:31:9 - | -LL | #[doc(alias = "expr")] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements - -warning: `#[doc]` attribute cannot be used on match arms - --> $DIR/check-doc-alias-attr-location.rs:36:13 - | -LL | #[doc(alias = "arm")] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[doc]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, functions, impl blocks, macro defs, modules, statics, struct fields, trait aliases, traits, type aliases, unions, and use statements - -error: aborting due to 8 previous errors; 4 warnings emitted +error: aborting due to 8 previous errors From 507b67f45745194e151e373325e7ec2154589484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 8 Nov 2025 22:26:43 +0000 Subject: [PATCH 0566/3801] Add test for incorrect macro span replacement --- .../ui/span/macro-span-caller-replacement.rs | 16 ++++++++++ .../span/macro-span-caller-replacement.stderr | 29 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 tests/ui/span/macro-span-caller-replacement.rs create mode 100644 tests/ui/span/macro-span-caller-replacement.stderr diff --git a/tests/ui/span/macro-span-caller-replacement.rs b/tests/ui/span/macro-span-caller-replacement.rs new file mode 100644 index 000000000000..45af729beb1a --- /dev/null +++ b/tests/ui/span/macro-span-caller-replacement.rs @@ -0,0 +1,16 @@ +macro_rules! macro_with_format { () => { + fn check_5(arg : usize) -> String { + let s : &str; + if arg < 5 { + s = format!("{arg}"); + } else { + s = String::new(); //~ ERROR mismatched types + } + String::from(s) + } +}} + +fn main() { + macro_with_format!(); //~ ERROR mismatched types + println!( "{}", check_5(6) ); +} diff --git a/tests/ui/span/macro-span-caller-replacement.stderr b/tests/ui/span/macro-span-caller-replacement.stderr new file mode 100644 index 000000000000..1c831f96ec0c --- /dev/null +++ b/tests/ui/span/macro-span-caller-replacement.stderr @@ -0,0 +1,29 @@ +error[E0308]: mismatched types + --> $DIR/macro-span-caller-replacement.rs:5:17 + | +LL | macro_with_format!(); + | ^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `String` + | + = note: this error originates in the macro `format` which comes from the expansion of the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/macro-span-caller-replacement.rs:7:17 + | +LL | let s : &str; + | ---- expected due to this type +... +LL | s = String::new(); + | ^^^^^^^^^^^^^ expected `&str`, found `String` +... +LL | macro_with_format!(); + | -------------------- in this macro invocation + | + = note: this error originates in the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider borrowing here + | +LL | s = &String::new(); + | + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 1bd7934d891cee73664367cfff8f914edda3d9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 8 Nov 2025 23:35:55 +0000 Subject: [PATCH 0567/3801] Point at span within local macros even when error happens in nested external macro ``` error[E0308]: mismatched types --> $DIR/macro-span-caller-replacement.rs:5:17 | LL | s = format!("{arg}"); | ^^^^^^^^^^^^^^^^ expected `&str`, found `String` ... LL | macro_with_format!(); | -------------------- in this macro invocation | = note: this error originates in the macro `format` which comes from the expansion of the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) ``` --- compiler/rustc_errors/src/emitter.rs | 9 +- .../tests/fail/panic/tls_macro_drop_panic.rs | 2 +- .../rustc-dev-remap.only-remap.stderr | 3 + .../rustc-dev-remap.remap-unremap.stderr | 5 +- ...diagnostic-derive-doc-comment-field.stderr | 6 + .../diagnostic-derive.stderr | 3 + tests/ui/binop/binary-op-suggest-deref.stderr | 12 +- tests/ui/binop/binop-mul-i32-f32.stderr | 12 +- .../const_param_ty_bad.stderr | 6 + .../const-eval/const-eval-overflow-3b.stderr | 12 +- .../const-eval/const-eval-overflow-4b.stderr | 12 +- tests/ui/consts/const-eval/issue-85155.stderr | 7 +- tests/ui/consts/const-eval/parse_ints.stderr | 12 ++ tests/ui/consts/const-ptr-is-null.stderr | 7 + .../ui/consts/const_transmute_type_id2.stderr | 4 + .../ui/consts/const_transmute_type_id3.stderr | 4 + .../ui/consts/const_transmute_type_id4.stderr | 4 + .../ui/consts/const_transmute_type_id5.stderr | 4 + .../ui/consts/const_transmute_type_id6.stderr | 4 + tests/ui/consts/timeout.stderr | 5 + .../hygiene/cross-crate-name-hiding-2.stderr | 6 +- tests/ui/impl-trait/equality.stderr | 12 +- .../ambiguous-glob-vs-expanded-extern.stderr | 14 +- .../issue-41731-infinite-macro-print.stderr | 14 +- .../issue-41731-infinite-macro-println.stderr | 14 +- .../invalid-iterator-chain-fixable.stderr | 24 +++- ...valid-iterator-chain-with-int-infer.stderr | 8 +- .../iterators/invalid-iterator-chain.stderr | 40 ++++-- tests/ui/mismatched_types/binops.stderr | 12 +- ...oat-integer-subtraction-error-24352.stderr | 12 +- tests/ui/never_type/issue-13352.stderr | 12 +- .../not-suggest-float-literal.stderr | 132 +++++++++++++----- .../suggest-float-literal.stderr | 96 +++++++++---- tests/ui/on-unimplemented/slice-index.stderr | 3 + tests/ui/on-unimplemented/sum.stderr | 16 ++- tests/ui/proc-macro/mixed-site-span.stderr | 28 ++-- .../ui/span/macro-span-caller-replacement.rs | 6 +- .../span/macro-span-caller-replacement.stderr | 5 +- tests/ui/span/multiline-span-simple.stderr | 12 +- ...ut-not-available.alignment_mismatch.stderr | 3 + ...gest-deref-inside-macro-issue-58298.stderr | 7 +- .../invalid-suggest-deref-issue-127590.stderr | 16 +++ tests/ui/try-trait/bad-interconversion.stderr | 6 + .../self-referential-2.current.stderr | 3 + .../self-referential-3.stderr | 3 + .../self-referential-4.stderr | 9 ++ .../self-referential.stderr | 9 ++ tests/ui/type/type-check-defaults.stderr | 12 +- ...0017-format-into-help-deletes-macro.stderr | 21 ++- ...2007-leaked-writeln-macro-internals.stderr | 7 +- tests/ui/typeck/issue-81293.stderr | 12 +- tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr | 24 +++- 52 files changed, 569 insertions(+), 162 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d08d5a5a1ea2..78feb60261bd 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -474,9 +474,12 @@ pub trait Emitter { .chain(span.span_labels().iter().map(|sp_label| sp_label.span)) .filter_map(|sp| { if !sp.is_dummy() && source_map.is_imported(sp) { - let maybe_callsite = sp.source_callsite(); - if sp != maybe_callsite { - return Some((sp, maybe_callsite)); + let mut span = sp; + while let Some(callsite) = span.parent_callsite() { + span = callsite; + if !source_map.is_imported(span) { + return Some((sp, span)); + } } } None diff --git a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs index 107d70a3b3c7..a207d3923124 100644 --- a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs +++ b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs @@ -1,7 +1,7 @@ //@error-in-other-file: aborted execution // Backtraces vary wildly between platforms, we have to normalize away almost the entire thing //@normalize-stderr-test: "'main'|''" -> "$$NAME" -//@normalize-stderr-test: ".*(note|-->|\|).*\n" -> "" +//@normalize-stderr-test: ".*(note|-->|:::|\|).*\n" -> "" pub struct NoisyDrop {} diff --git a/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr b/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr index 15e2cf66f8f8..d2303ef4bbb5 100644 --- a/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr +++ b/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr @@ -18,6 +18,9 @@ help: the following other types implement trait `VisitorResult` = note: `ControlFlow` note: required by a bound in `rustc_ast::visit::Visitor::Result` --> /rustc-dev/xyz/compiler/rustc_ast/src/visit.rs:LL:COL + ::: /rustc-dev/xyz/compiler/rustc_ast/src/visit.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `common_visitor_and_walkers` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr b/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr index b9276974c465..50bb60e78d68 100644 --- a/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr +++ b/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr @@ -20,8 +20,11 @@ LL | impl VisitorResult for ControlFlow { note: required by a bound in `rustc_ast::visit::Visitor::Result` --> $COMPILER_DIR_REAL/rustc_ast/src/visit.rs:LL:COL | +LL | type Result: VisitorResult = (); + | ^^^^^^^^^^^^^ required by this bound in `Visitor::Result` +... LL | common_visitor_and_walkers!(Visitor<'a>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Visitor::Result` + | ---------------------------------------- in this macro invocation = note: this error originates in the macro `common_visitor_and_walkers` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr index 8b6c4b181c0f..72e150dd5178 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr @@ -15,6 +15,9 @@ LL | struct NotIntoDiagArg; = help: normalized in stderr note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + | + = note: in this macro invocation = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `NotIntoDiagArg: IntoDiagArg` is not satisfied @@ -34,6 +37,9 @@ LL | struct NotIntoDiagArg; = help: normalized in stderr note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + | + = note: in this macro invocation = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 8a0e753a9c52..f2244a968769 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -665,6 +665,9 @@ LL | struct Hello {} = help: normalized in stderr note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + | + = note: in this macro invocation = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 85 previous errors diff --git a/tests/ui/binop/binary-op-suggest-deref.stderr b/tests/ui/binop/binary-op-suggest-deref.stderr index 0c9b1d9bd938..eb17c6cbbc66 100644 --- a/tests/ui/binop/binary-op-suggest-deref.stderr +++ b/tests/ui/binop/binary-op-suggest-deref.stderr @@ -305,13 +305,19 @@ LL | let _ = FOO & (*"Sized".to_string().into_boxed_str()); help: the following other types implement trait `BitAnd` --> $SRC_DIR/core/src/ops/bit.rs:LL:COL | - = note: `&i32` implements `BitAnd` + = note: `i32` implements `BitAnd` + ::: $SRC_DIR/core/src/ops/bit.rs:LL:COL | - = note: `&i32` implements `BitAnd` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `BitAnd` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `BitAnd<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `BitAnd` + = note: `&i32` implements `BitAnd` = note: this error originates in the macro `bitand_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `str` cannot be known at compilation time diff --git a/tests/ui/binop/binop-mul-i32-f32.stderr b/tests/ui/binop/binop-mul-i32-f32.stderr index dc4e7fdf6c14..a8893700b1be 100644 --- a/tests/ui/binop/binop-mul-i32-f32.stderr +++ b/tests/ui/binop/binop-mul-i32-f32.stderr @@ -8,13 +8,19 @@ LL | x * y help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Mul` + = note: `i32` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Mul<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Mul` + = note: `&i32` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr index 75718fbbba0a..5109dccd96a1 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr @@ -84,6 +84,9 @@ LL | check(&mut () as *mut ()); | help: the trait `ConstParamTy_` is implemented for `()` --> $SRC_DIR/core/src/marker.rs:LL:COL + ::: $SRC_DIR/core/src/marker.rs:LL:COL + | + = note: in this macro invocation note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | @@ -101,6 +104,9 @@ LL | check(&() as *const ()); | help: the trait `ConstParamTy_` is implemented for `()` --> $SRC_DIR/core/src/marker.rs:LL:COL + ::: $SRC_DIR/core/src/marker.rs:LL:COL + | + = note: in this macro invocation note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr index 4209e4bcee52..54d77b1bf3e9 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr @@ -14,13 +14,19 @@ LL | = [0; (i8::MAX + 1u8) as usize]; help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: `i8` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i8` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i8` implements `Add<&i8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i8` implements `Add` + = note: `&i8` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr index 2677d7956cc9..6c6472610b72 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr @@ -14,13 +14,19 @@ LL | : [u32; (i8::MAX as i8 + 1u8) as usize] help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: `i8` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i8` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i8` implements `Add<&i8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i8` implements `Add` + = note: `&i8` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0604]: only `u8` can be cast as `char`, not `i8` diff --git a/tests/ui/consts/const-eval/issue-85155.stderr b/tests/ui/consts/const-eval/issue-85155.stderr index 486d2adaf8cd..dfc784bc7a4f 100644 --- a/tests/ui/consts/const-eval/issue-85155.stderr +++ b/tests/ui/consts/const-eval/issue-85155.stderr @@ -5,10 +5,13 @@ LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `post_monomorphization_error::ValidateConstImm::<2, 0, 1>::VALID` failed here note: erroneous constant encountered - --> $DIR/auxiliary/post_monomorphization_error.rs:19:5 + --> $DIR/auxiliary/post_monomorphization_error.rs:13:17 | +LL | let _ = $crate::ValidateConstImm::<$imm, 0, { (1 << 1) - 1 }>::VALID; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | static_assert_imm1!(IMM1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------------------------- in this macro invocation | = note: this note originates in the macro `static_assert_imm1` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-eval/parse_ints.stderr b/tests/ui/consts/const-eval/parse_ints.stderr index 9c9d083e7ca2..7f42e20cf8e8 100644 --- a/tests/ui/consts/const-eval/parse_ints.stderr +++ b/tests/ui/consts/const-eval/parse_ints.stderr @@ -6,8 +6,14 @@ LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); }; | note: inside `core::num::::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation note: inside `core::num::::from_ascii_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: from_ascii_radix: radix must lie in the range `[2, 36]` @@ -18,8 +24,14 @@ LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); }; | note: inside `core::num::::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation note: inside `core::num::::from_ascii_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-ptr-is-null.stderr b/tests/ui/consts/const-ptr-is-null.stderr index be0a1346c647..b532ed9d4c5f 100644 --- a/tests/ui/consts/const-ptr-is-null.stderr +++ b/tests/ui/consts/const-ptr-is-null.stderr @@ -5,9 +5,16 @@ LL | assert!(!ptr.wrapping_sub(512).is_null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MAYBE_NULL` failed inside this call | note: inside `std::ptr::const_ptr::::is_null` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | + = note: in this macro invocation note: inside `std::ptr::const_ptr::::is_null::compiletime` + --> $SRC_DIR/core/src/panic.rs:LL:COL --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | + = note: in this macro invocation error: aborting due to 1 previous error diff --git a/tests/ui/consts/const_transmute_type_id2.stderr b/tests/ui/consts/const_transmute_type_id2.stderr index 5646eb1257d1..b420deaa49ce 100644 --- a/tests/ui/consts/const_transmute_type_id2.stderr +++ b/tests/ui/consts/const_transmute_type_id2.stderr @@ -5,7 +5,11 @@ LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id3.stderr b/tests/ui/consts/const_transmute_type_id3.stderr index e731f496652e..9f796cda6145 100644 --- a/tests/ui/consts/const_transmute_type_id3.stderr +++ b/tests/ui/consts/const_transmute_type_id3.stderr @@ -5,7 +5,11 @@ LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id4.stderr b/tests/ui/consts/const_transmute_type_id4.stderr index b224227cf352..c844b10d78cf 100644 --- a/tests/ui/consts/const_transmute_type_id4.stderr +++ b/tests/ui/consts/const_transmute_type_id4.stderr @@ -5,7 +5,11 @@ LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id5.stderr b/tests/ui/consts/const_transmute_type_id5.stderr index 6205679ebb64..9a7384eb95b4 100644 --- a/tests/ui/consts/const_transmute_type_id5.stderr +++ b/tests/ui/consts/const_transmute_type_id5.stderr @@ -5,7 +5,11 @@ LL | assert!(b == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id6.stderr b/tests/ui/consts/const_transmute_type_id6.stderr index f5d90256e7c6..c0b35f3d1081 100644 --- a/tests/ui/consts/const_transmute_type_id6.stderr +++ b/tests/ui/consts/const_transmute_type_id6.stderr @@ -5,7 +5,11 @@ LL | id == id | ^^^^^^^^ evaluation of `X` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/timeout.stderr b/tests/ui/consts/timeout.stderr index ecefeff76e96..6afb317c3aff 100644 --- a/tests/ui/consts/timeout.stderr +++ b/tests/ui/consts/timeout.stderr @@ -1,5 +1,10 @@ error: constant evaluation is taking a long time + --> $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + | --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. If your compilation actually takes a long time, you can safely allow the lint. diff --git a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr index fe3a12e93a7e..336d35099c80 100644 --- a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr +++ b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr @@ -4,10 +4,10 @@ error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope LL | let x = MyStruct {}; | ^^^^^^^^ not found in this scope | - ::: $DIR/auxiliary/use_by_macro.rs:15:1 + ::: $DIR/auxiliary/use_by_macro.rs:7:24 | -LL | x!(my_struct); - | ------------- you might have meant to refer to this struct +LL | pub struct MyStruct; + | -------- you might have meant to refer to this struct error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index c2b889138c89..7f965b9609a9 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -33,13 +33,19 @@ LL | n + sum_to(n - 1) help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: `u32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u32` implements `Add<&u32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u32` implements `Add` + = note: `&u32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr index c2e775e6c862..4a9a6c99819b 100644 --- a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr +++ b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr @@ -8,10 +8,13 @@ LL | glob_vs_expanded::mac!(); = note: for more information, see issue #114095 = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution note: `mac` could refer to the macro defined here - --> $DIR/auxiliary/glob-vs-expanded.rs:11:1 + --> $DIR/auxiliary/glob-vs-expanded.rs:9:13 | +LL | () => { pub macro mac() {} } + | ^^^^^^^^^^^^^ +LL | } LL | define_mac!(); - | ^^^^^^^^^^^^^ + | ------------- in this macro invocation note: `mac` could also refer to the macro defined here --> $DIR/auxiliary/glob-vs-expanded.rs:5:9 | @@ -33,10 +36,13 @@ LL | glob_vs_expanded::mac!(); = note: for more information, see issue #114095 = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution note: `mac` could refer to the macro defined here - --> $DIR/auxiliary/glob-vs-expanded.rs:11:1 + --> $DIR/auxiliary/glob-vs-expanded.rs:9:13 | +LL | () => { pub macro mac() {} } + | ^^^^^^^^^^^^^ +LL | } LL | define_mac!(); - | ^^^^^^^^^^^^^ + | ------------- in this macro invocation note: `mac` could also refer to the macro defined here --> $DIR/auxiliary/glob-vs-expanded.rs:5:9 | diff --git a/tests/ui/infinite/issue-41731-infinite-macro-print.stderr b/tests/ui/infinite/issue-41731-infinite-macro-print.stderr index 84436de9aa37..5f5d2c75525d 100644 --- a/tests/ui/infinite/issue-41731-infinite-macro-print.stderr +++ b/tests/ui/infinite/issue-41731-infinite-macro-print.stderr @@ -1,8 +1,11 @@ error: recursion limit reached while expanding `$crate::format_args!` - --> $DIR/issue-41731-infinite-macro-print.rs:14:5 + --> $DIR/issue-41731-infinite-macro-print.rs:8:13 | +LL | print!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "10"]` attribute to your crate (`issue_41731_infinite_macro_print`) = note: this error originates in the macro `print` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -23,10 +26,13 @@ LL | stack!("overflow"); = note: to `{ $crate :: io :: _print($crate :: format_args! (stack! ("overflow"))); }` error: format argument must be a string literal - --> $DIR/issue-41731-infinite-macro-print.rs:14:5 + --> $DIR/issue-41731-infinite-macro-print.rs:8:13 | +LL | print!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = note: this error originates in the macro `print` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might be missing a string literal to format with diff --git a/tests/ui/infinite/issue-41731-infinite-macro-println.stderr b/tests/ui/infinite/issue-41731-infinite-macro-println.stderr index 6d0432abe4c5..c19039e305e2 100644 --- a/tests/ui/infinite/issue-41731-infinite-macro-println.stderr +++ b/tests/ui/infinite/issue-41731-infinite-macro-println.stderr @@ -1,8 +1,11 @@ error: recursion limit reached while expanding `$crate::format_args_nl!` - --> $DIR/issue-41731-infinite-macro-println.rs:14:5 + --> $DIR/issue-41731-infinite-macro-println.rs:8:13 | +LL | println!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "10"]` attribute to your crate (`issue_41731_infinite_macro_println`) = note: this error originates in the macro `println` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -23,10 +26,13 @@ LL | stack!("overflow"); = note: to `{ $crate :: io :: _print($crate :: format_args_nl! (stack! ("overflow"))); }` error: format argument must be a string literal - --> $DIR/issue-41731-infinite-macro-println.rs:14:5 + --> $DIR/issue-41731-infinite-macro-println.rs:8:13 | +LL | println!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = note: this error originates in the macro `println` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might be missing a string literal to format with diff --git a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr index bef4cb6b0a1b..99bff6b450b5 100644 --- a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr @@ -35,10 +35,14 @@ LL | println!("{}", scores.sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum
` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:14:10 | @@ -72,10 +76,14 @@ LL | .sum::(), = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:23:14 | @@ -109,10 +117,14 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:27:38 | diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr index 638287ed1c64..c94b716e3131 100644 --- a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr @@ -9,10 +9,14 @@ LL | let x = Some(()).iter().map(|()| 1).sum::(); = help: the trait `Sum<{integer}>` is not implemented for `f32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `f32` implements `Sum<&f32>` | = note: `f32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `f32` implements `Sum<&f32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:29 | diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index 0fd9d3999966..7f0c154e255a 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -35,10 +35,14 @@ LL | println!("{}", scores.sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:12:10 | @@ -71,10 +75,14 @@ LL | .sum::(), = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:25:14 | @@ -114,10 +122,14 @@ LL | .sum::(), = help: the trait `Sum` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:33:14 | @@ -148,10 +160,14 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:38:38 | @@ -180,10 +196,14 @@ LL | println!("{}", vec![(), ()].iter().sum::()); = help: the trait `Sum<&()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:39:33 | diff --git a/tests/ui/mismatched_types/binops.stderr b/tests/ui/mismatched_types/binops.stderr index 504b44dfb7f6..ec2a951aac9a 100644 --- a/tests/ui/mismatched_types/binops.stderr +++ b/tests/ui/mismatched_types/binops.stderr @@ -26,13 +26,19 @@ LL | 2 as usize - Some(1); help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Sub` + = note: `usize` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&usize` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `usize` implements `Sub<&usize>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `usize` implements `Sub` + = note: `&usize` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `{integer}` by `()` diff --git a/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr index b2d0ffc4710e..54b536744f75 100644 --- a/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr +++ b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr @@ -8,13 +8,19 @@ LL | 1.0f64 - 1 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | diff --git a/tests/ui/never_type/issue-13352.stderr b/tests/ui/never_type/issue-13352.stderr index 344625af683a..5fcbb4aab993 100644 --- a/tests/ui/never_type/issue-13352.stderr +++ b/tests/ui/never_type/issue-13352.stderr @@ -8,13 +8,19 @@ LL | 2_usize + (loop {}); help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: `usize` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&usize` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `usize` implements `Add<&usize>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `usize` implements `Add` + = note: `&usize` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr index 3f5297be3719..a62bf5b6a04d 100644 --- a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr +++ b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr @@ -8,13 +8,19 @@ LL | x + 100.0 help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Add` + = note: `u8` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u8` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u8` implements `Add<&u8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u8` implements `Add` + = note: `&u8` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot add `&str` to `f64` @@ -27,13 +33,19 @@ LL | x + "foo" help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: `f64` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Add<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Add` + = note: `&f64` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot add `{integer}` to `f64` @@ -46,13 +58,19 @@ LL | x + y help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: `f64` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Add<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Add` + = note: `&f64` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot subtract `{float}` from `u8` @@ -65,13 +83,19 @@ LL | x - 100.0 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Sub` + = note: `u8` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u8` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u8` implements `Sub<&u8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u8` implements `Sub` + = note: `&u8` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot subtract `&str` from `f64` @@ -84,13 +108,19 @@ LL | x - "foo" help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot subtract `{integer}` from `f64` @@ -103,13 +133,19 @@ LL | x - y help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `u8` by `{float}` @@ -122,13 +158,19 @@ LL | x * 100.0 help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Mul` + = note: `u8` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u8` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u8` implements `Mul<&u8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u8` implements `Mul` + = note: `&u8` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `f64` by `&str` @@ -141,13 +183,19 @@ LL | x * "foo" help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: `f64` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Mul<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Mul` + = note: `&f64` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `f64` by `{integer}` @@ -160,13 +208,19 @@ LL | x * y help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: `f64` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Mul<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Mul` + = note: `&f64` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot divide `u8` by `{float}` @@ -193,13 +247,19 @@ LL | x / "foo" help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: `f64` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Div<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Div` + = note: `&f64` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot divide `f64` by `{integer}` @@ -212,13 +272,19 @@ LL | x / y help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: `f64` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Div<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Div` + = note: `&f64` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 12 previous errors diff --git a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr index a31ed6154746..65881ca7a82f 100644 --- a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr +++ b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr @@ -8,13 +8,19 @@ LL | x + 100 help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Add` + = note: `f32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Add<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Add` + = note: `&f32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -31,13 +37,19 @@ LL | x + 100 help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: `f64` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Add<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Add` + = note: `&f64` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -54,13 +66,19 @@ LL | x - 100 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Sub` + = note: `f32` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Sub<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Sub` + = note: `&f32` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -77,13 +95,19 @@ LL | x - 100 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -100,13 +124,19 @@ LL | x * 100 help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Mul` + = note: `f32` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Mul<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Mul` + = note: `&f32` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -123,13 +153,19 @@ LL | x * 100 help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: `f64` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Mul<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Mul` + = note: `&f64` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -146,13 +182,19 @@ LL | x / 100 help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Div` + = note: `f32` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Div<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Div` + = note: `&f32` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -169,13 +211,19 @@ LL | x / 100 help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: `f64` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Div<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Div` + = note: `&f64` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index baf821c45c5e..67b72bd038d8 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -28,6 +28,9 @@ help: the following other types implement trait `SliceIndex` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | = note: `RangeTo` implements `SliceIndex` + ::: $SRC_DIR/core/src/bstr/traits.rs:LL:COL + | + = note: in this macro invocation --> $SRC_DIR/core/src/str/traits.rs:LL:COL | = note: `RangeTo` implements `SliceIndex` diff --git a/tests/ui/on-unimplemented/sum.stderr b/tests/ui/on-unimplemented/sum.stderr index c4650e9f5278..5e82948352f7 100644 --- a/tests/ui/on-unimplemented/sum.stderr +++ b/tests/ui/on-unimplemented/sum.stderr @@ -9,10 +9,14 @@ LL | vec![(), ()].iter().sum::(); = help: the trait `Sum<&()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/sum.rs:4:18 | @@ -35,10 +39,14 @@ LL | vec![(), ()].iter().product::(); = help: the trait `Product<&()>` is not implemented for `i32` help: the following other types implement trait `Product` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Product<&i32>` | = note: `i32` implements `Product` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Product<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/sum.rs:7:18 | diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr index 2cc7ff8a8867..fd941f65b788 100644 --- a/tests/ui/proc-macro/mixed-site-span.stderr +++ b/tests/ui/proc-macro/mixed-site-span.stderr @@ -112,10 +112,13 @@ LL | test!(); = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:69:5 + --> $DIR/mixed-site-span.rs:67:9 | +LL | invoke_with_ident!{$crate call proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root +LL | }} LL | test!(); - | ^^^^^^^ no `proc_macro_item` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -262,10 +265,13 @@ LL + token_site_span::TokenItem as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:110:5 + --> $DIR/mixed-site-span.rs:106:9 | +LL | invoke_with_ident!{$crate mixed TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root +... LL | test!(); - | ^^^^^^^ no `TokenItem` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead @@ -417,10 +423,13 @@ LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:150:5 + --> $DIR/mixed-site-span.rs:145:9 | +LL | invoke_with_ident!{$crate mixed ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root +... LL | test!(); - | ^^^^^^^ no `ItemUse` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead @@ -447,10 +456,13 @@ LL + ItemUse as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:150:5 + --> $DIR/mixed-site-span.rs:148:9 | +LL | invoke_with_ident!{$crate call ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root +LL | }} LL | test!(); - | ^^^^^^^ no `ItemUse` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead diff --git a/tests/ui/span/macro-span-caller-replacement.rs b/tests/ui/span/macro-span-caller-replacement.rs index 45af729beb1a..8e7239699cd1 100644 --- a/tests/ui/span/macro-span-caller-replacement.rs +++ b/tests/ui/span/macro-span-caller-replacement.rs @@ -2,7 +2,7 @@ macro_rules! macro_with_format { () => { fn check_5(arg : usize) -> String { let s : &str; if arg < 5 { - s = format!("{arg}"); + s = format!("{arg}"); //~ ERROR mismatched types } else { s = String::new(); //~ ERROR mismatched types } @@ -11,6 +11,6 @@ macro_rules! macro_with_format { () => { }} fn main() { - macro_with_format!(); //~ ERROR mismatched types - println!( "{}", check_5(6) ); + macro_with_format!(); + println!( "{}", check_5(6) ); } diff --git a/tests/ui/span/macro-span-caller-replacement.stderr b/tests/ui/span/macro-span-caller-replacement.stderr index 1c831f96ec0c..43be48a9e362 100644 --- a/tests/ui/span/macro-span-caller-replacement.stderr +++ b/tests/ui/span/macro-span-caller-replacement.stderr @@ -1,8 +1,11 @@ error[E0308]: mismatched types --> $DIR/macro-span-caller-replacement.rs:5:17 | +LL | s = format!("{arg}"); + | ^^^^^^^^^^^^^^^^ expected `&str`, found `String` +... LL | macro_with_format!(); - | ^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `String` + | -------------------- in this macro invocation | = note: this error originates in the macro `format` which comes from the expansion of the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/span/multiline-span-simple.stderr b/tests/ui/span/multiline-span-simple.stderr index af04ceaf8097..e013b3c06bc1 100644 --- a/tests/ui/span/multiline-span-simple.stderr +++ b/tests/ui/span/multiline-span-simple.stderr @@ -8,13 +8,19 @@ LL | foo(1 as u32 + help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: `u32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u32` implements `Add<&u32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u32` implements `Add` + = note: `&u32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr index 6a8a7b152c54..93e189ffa0d3 100644 --- a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr +++ b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr @@ -6,6 +6,9 @@ LL | core::sync::atomic::AtomicU64::from_mut(&mut 0u64); | note: if you're trying to build a new `AtomicU64`, consider using `AtomicU64::new` which returns `AtomicU64` --> $SRC_DIR/core/src/sync/atomic.rs:LL:COL + ::: $SRC_DIR/core/src/sync/atomic.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `atomic_int` (in Nightly builds, run with -Z macro-backtrace for more info) help: there is an associated function `from` with a similar name | diff --git a/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr b/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr index 46613e8e1b48..0ed657c7fa99 100644 --- a/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr +++ b/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr @@ -1,10 +1,13 @@ error[E0308]: mismatched types - --> $DIR/dont-suggest-deref-inside-macro-issue-58298.rs:11:5 + --> $DIR/dont-suggest-deref-inside-macro-issue-58298.rs:5:14 | +LL | warn(format!("unsupported intrinsic {}", $intrinsic)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `String` +... LL | / intrinsic_match! { LL | | "abc" LL | | }; - | |_____^ expected `&str`, found `String` + | |_____- in this macro invocation | = note: this error originates in the macro `format` which comes from the expansion of the macro `intrinsic_match` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr index 07a54d574df4..3bae5798d047 100644 --- a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr @@ -24,7 +24,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `Iterator` = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -55,7 +59,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone( | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `Iterator` = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -68,7 +76,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -80,7 +92,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone( | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index da5c4d03dccb..61fecaf89917 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -13,9 +13,15 @@ help: the following other types implement trait `From` --> $SRC_DIR/core/src/convert/num.rs:LL:COL | = note: `u8` implements `From` + ::: $SRC_DIR/core/src/convert/num.rs:LL:COL + | + = note: in this macro invocation --> $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL | = note: `u8` implements `From` + ::: $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `impl_from` which comes from the expansion of the macro `into_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr index 2855c90234d2..ca26e3dd03f3 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr @@ -9,6 +9,9 @@ LL | 42_i32 help: the trait `PartialEq` is not implemented for `i32` but trait `PartialEq` is implemented for it --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index 83fed16c0a17..8592de243ada 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -10,6 +10,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/self-referential-4.stderr b/tests/ui/type-alias-impl-trait/self-referential-4.stderr index 4176bf780294..c6bf1973fcbb 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-4.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-4.stderr @@ -9,6 +9,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `Foo<'static, 'b>` @@ -22,6 +25,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `Moo<'static, 'a>` @@ -35,6 +41,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr index dc5b9ba7b442..7b4e6e9cac52 100644 --- a/tests/ui/type-alias-impl-trait/self-referential.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential.stderr @@ -10,6 +10,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)` @@ -24,6 +27,9 @@ LL | (42, i) = help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)` @@ -38,6 +44,9 @@ LL | (42, i) = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/type/type-check-defaults.stderr b/tests/ui/type/type-check-defaults.stderr index 4eab611244a6..a3a2ed5aa725 100644 --- a/tests/ui/type/type-check-defaults.stderr +++ b/tests/ui/type/type-check-defaults.stderr @@ -86,13 +86,19 @@ LL | trait ProjectionPred> where T::Item : Add {} help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: `i32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Add<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Add` + = note: `&i32` implements `Add` note: required by a bound in `ProjectionPred` --> $DIR/type-check-defaults.rs:24:66 | diff --git a/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr b/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr index e4834c0308bc..bc722cdd57a5 100644 --- a/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr +++ b/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr @@ -13,10 +13,13 @@ LL | Err(format!("error: {x}").into()) | +++++++ error[E0308]: mismatched types - --> $DIR/issue-110017-format-into-help-deletes-macro.rs:23:10 + --> $DIR/issue-110017-format-into-help-deletes-macro.rs:17:10 | +LL | format!("error: {}", $x) + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` +... LL | Err(outer!(x)) - | ^^^^^^^^^ expected `Box`, found `String` + | --------- in this macro invocation | = note: expected struct `Box` found struct `String` @@ -27,10 +30,13 @@ LL | format!("error: {}", $x).into() | +++++++ error[E0308]: mismatched types - --> $DIR/issue-110017-format-into-help-deletes-macro.rs:41:2 + --> $DIR/issue-110017-format-into-help-deletes-macro.rs:35:18 | +LL | Err(format!("error: {x}")) + | ^^^^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` +... LL | entire_fn_outer!(); - | ^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` + | ------------------ in this macro invocation | = note: expected struct `Box` found struct `String` @@ -41,10 +47,13 @@ LL | Err(format!("error: {x}").into()) | +++++++ error[E0308]: mismatched types - --> $DIR/issue-110017-format-into-help-deletes-macro.rs:51:5 + --> $DIR/issue-110017-format-into-help-deletes-macro.rs:45:13 | +LL | Err(format!("error: {}", $x)) + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` +... LL | nontrivial!(x) - | ^^^^^^^^^^^^^^ expected `Box`, found `String` + | -------------- in this macro invocation | = note: expected struct `Box` found struct `String` diff --git a/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr b/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr index 889d2c94d0cf..30d51420b7cb 100644 --- a/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr +++ b/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr @@ -27,13 +27,16 @@ LL | writeln!(w, "but not here")? | + error[E0308]: mismatched types - --> $DIR/issue-112007-leaked-writeln-macro-internals.rs:40:9 + --> $DIR/issue-112007-leaked-writeln-macro-internals.rs:31:9 | +LL | writeln!($w, "but not here") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Result<(), Error>` +... LL | / if true { LL | | writeln!(w, "`;?` here ->")?; LL | | } else { LL | | baz!(w) - | | ^^^^^^^ expected `()`, found `Result<(), Error>` + | | ------- in this macro invocation LL | | } | |_____- expected this to be `()` | diff --git a/tests/ui/typeck/issue-81293.stderr b/tests/ui/typeck/issue-81293.stderr index 8318d31f0946..604f3cca5486 100644 --- a/tests/ui/typeck/issue-81293.stderr +++ b/tests/ui/typeck/issue-81293.stderr @@ -23,13 +23,19 @@ LL | a = c + b * 5; help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: `usize` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&usize` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `usize` implements `Add<&usize>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `usize` implements `Add` + = note: `&usize` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr index 352638dd0118..dbbee54c185b 100644 --- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -8,13 +8,19 @@ LL | >::add(1, 2); help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: `i32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Add<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Add` + = note: `&i32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types @@ -73,13 +79,19 @@ LL | >::add(1, 2); help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: `i32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Add<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Add` + = note: `&i32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors From 8f9d86226dd67c6ff486b4220f26c65234c323fa Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Wed, 10 Dec 2025 22:27:21 +0200 Subject: [PATCH 0568/3801] Support `#[feature(associated_type_defaults)]` --- .../crates/hir-ty/src/next_solver/interner.rs | 9 +- .../crates/hir-ty/src/next_solver/solver.rs | 85 ++++++++++--------- .../crates/hir-ty/src/tests/traits.rs | 20 +++++ 3 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 2edf442a8cc6..8b24a20a5bed 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -1104,14 +1104,7 @@ impl<'db> Interner for DbInterner<'db> { fn type_of(self, def_id: Self::DefId) -> EarlyBinder { match def_id { - SolverDefId::TypeAliasId(id) => { - use hir_def::Lookup; - match id.lookup(self.db()).container { - ItemContainerId::ImplId(it) => it, - _ => panic!("assoc ty value should be in impl"), - }; - self.db().ty(id.into()) - } + SolverDefId::TypeAliasId(id) => self.db().ty(id.into()), SolverDefId::AdtId(id) => self.db().ty(id.into()), // FIXME(next-solver): This uses the types of `query mir_borrowck` in rustc. // diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs index 859e26e37641..40a3f17cf169 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs @@ -177,45 +177,52 @@ impl<'db> SolverDelegate for SolverContext<'db> { impl_id: ImplIdWrapper, ) -> Result, ErrorGuaranteed> { let impl_items = impl_id.0.impl_items(self.0.interner.db()); - let id = match trait_assoc_def_id { - SolverDefId::TypeAliasId(trait_assoc_id) => { - let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id); - impl_items - .items - .iter() - .find_map(|(impl_assoc_name, impl_assoc_id)| { - if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id - && *impl_assoc_name == trait_assoc_data.name - { - Some(impl_assoc_id) - } else { - None - } - }) - .map(SolverDefId::TypeAliasId) - } - SolverDefId::ConstId(trait_assoc_id) => { - let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id); - let trait_assoc_name = trait_assoc_data - .name - .as_ref() - .expect("unnamed consts should not get passed to the solver"); - impl_items - .items - .iter() - .find_map(|(impl_assoc_name, impl_assoc_id)| { - if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id - && impl_assoc_name == trait_assoc_name - { - Some(impl_assoc_id) - } else { - None - } - }) - .map(SolverDefId::ConstId) - } - _ => panic!("Unexpected SolverDefId"), - }; + let id = + match trait_assoc_def_id { + SolverDefId::TypeAliasId(trait_assoc_id) => { + let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id); + impl_items + .items + .iter() + .find_map(|(impl_assoc_name, impl_assoc_id)| { + if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id + && *impl_assoc_name == trait_assoc_data.name + { + Some(impl_assoc_id) + } else { + None + } + }) + .or_else(|| { + if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None } + }) + .map(SolverDefId::TypeAliasId) + } + SolverDefId::ConstId(trait_assoc_id) => { + let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id); + let trait_assoc_name = trait_assoc_data + .name + .as_ref() + .expect("unnamed consts should not get passed to the solver"); + impl_items + .items + .iter() + .find_map(|(impl_assoc_name, impl_assoc_id)| { + if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id + && impl_assoc_name == trait_assoc_name + { + Some(impl_assoc_id) + } else { + None + } + }) + .or_else(|| { + if trait_assoc_data.has_body() { Some(trait_assoc_id) } else { None } + }) + .map(SolverDefId::ConstId) + } + _ => panic!("Unexpected SolverDefId"), + }; Ok(id) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index 677e35775dd7..a54c0a799dfc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -5079,3 +5079,23 @@ fn foo(base_layer_two: &dyn BaseLayerOne) { "#, ); } + +#[test] +fn default_assoc_types() { + check_types( + r#" +trait Trait { + type Assoc = (T, U); + fn method(self) -> Self::Assoc { loop {} } +} + +struct Struct(T); +impl Trait<((), T)> for Struct {} + +fn foo(v: Struct) { + v.method(); + // ^^^^^^^^^^ (((), f32), i32) +} + "#, + ); +} From 71d7ae2f208ca3d16db7faef93f11e694693e3a9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 10 Dec 2025 12:35:04 -0800 Subject: [PATCH 0569/3801] std: Don't use `linkat` on the `wasm32-wasi*` targets This commit is a follow-up to 147572 and the issue reported at the end of that PR where the `std::fs::hard_link` function is broken after that PR landed. The true culprit and bug here is fixed in WebAssembly/wasi-libc/690 but until that's released in a wasi-sdk version it should be reasonable, on WASI, to skip the `linkat` function. --- library/std/src/sys/fs/unix.rs | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 507d093d2b2f..74206405bfe7 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -2077,12 +2077,25 @@ pub fn symlink(original: &CStr, link: &CStr) -> io::Result<()> { pub fn link(original: &CStr, link: &CStr) -> io::Result<()> { cfg_select! { - any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon", target_os = "vita", target_env = "nto70") => { - // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves - // it implementation-defined whether `link` follows symlinks, so rely on the - // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior. - // Android has `linkat` on newer versions, but we happen to know `link` - // always has the correct behavior, so it's here as well. + any( + // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. + // POSIX leaves it implementation-defined whether `link` follows + // symlinks, so rely on the `symlink_hard_link` test in + // library/std/src/fs/tests.rs to check the behavior. + target_os = "vxworks", + target_os = "redox", + target_os = "espidf", + // Android has `linkat` on newer versions, but we happen to know + // `link` always has the correct behavior, so it's here as well. + target_os = "android", + // wasi-sdk-29-and-prior have a buggy `linkat` so use `link` instead + // until wasi-sdk is updated (see WebAssembly/wasi-libc#690) + target_os = "wasi", + // Other misc platforms + target_os = "horizon", + target_os = "vita", + target_env = "nto70", + ) => { cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?; } _ => { From 6d512195a9b00cbf6a00d1b18863f7ed5a5fe89a Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Wed, 10 Dec 2025 22:45:20 +0200 Subject: [PATCH 0570/3801] `#[rustc_deprecated_safe_2024]` can also come as `#[rustc_deprecated_safe_2024(audit_that = "reason")]` --- src/tools/rust-analyzer/crates/hir-def/src/attrs.rs | 3 +++ .../crates/ide-diagnostics/src/handlers/missing_unsafe.rs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs index 607638f32b4e..febc794b5a05 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs @@ -155,6 +155,9 @@ fn match_attr_flags(attr_flags: &mut AttrFlags, attr: Meta) -> ControlFlow { extract_rustc_skip_during_method_dispatch(attr_flags, tt) } + "rustc_deprecated_safe_2024" => { + attr_flags.insert(AttrFlags::RUSTC_DEPRECATED_SAFE_2024) + } _ => {} }, 2 => match path.segments[0].text() { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs index 59215f34a581..1abb50144d34 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs @@ -296,8 +296,12 @@ fn main() { #[rustc_deprecated_safe_2024] fn set_var() {} +#[rustc_deprecated_safe_2024(audit_that = "something")] +fn set_var2() {} + fn main() { set_var(); + set_var2(); } "#, ); From c27bcef6f8ca820f9b22a707149485388281a8a8 Mon Sep 17 00:00:00 2001 From: 21aslade Date: Wed, 3 Dec 2025 20:43:27 -0700 Subject: [PATCH 0571/3801] don't resolve main in lib crates --- compiler/rustc_resolve/src/lib.rs | 7 +++++++ tests/ui/entry-point/imported_main_conflict_lib.rs | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/entry-point/imported_main_conflict_lib.rs diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 8132bf577d88..0b4ec6956bd1 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -73,6 +73,7 @@ use rustc_middle::ty::{ ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, }; use rustc_query_system::ich::StableHashingContext; +use rustc_session::config::CrateType; use rustc_session::lint::builtin::PRIVATE_MACRO_USE; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym}; @@ -2430,6 +2431,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn resolve_main(&mut self) { + let any_exe = self.tcx.crate_types().contains(&CrateType::Executable); + // Don't try to resolve main unless it's an executable + if !any_exe { + return; + } + let module = self.graph_root; let ident = Ident::with_dummy_span(sym::main); let parent_scope = &ParentScope::module(module, self.arenas); diff --git a/tests/ui/entry-point/imported_main_conflict_lib.rs b/tests/ui/entry-point/imported_main_conflict_lib.rs new file mode 100644 index 000000000000..b50e37951ede --- /dev/null +++ b/tests/ui/entry-point/imported_main_conflict_lib.rs @@ -0,0 +1,10 @@ +// Tests that ambiguously glob importing main doesn't fail to compile in non-executable crates +// Regression test for #149412 +//@ check-pass +#![crate_type = "lib"] + +mod m1 { pub(crate) fn main() {} } +mod m2 { pub(crate) fn main() {} } + +use m1::*; +use m2::*; From 4e51a8dbc0dfe25791375fe94a395d7cb200ef8a Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Fri, 28 Nov 2025 11:47:27 +0000 Subject: [PATCH 0572/3801] tidy: Detect outdated workspaces in workspace list --- src/tools/tidy/src/deps.rs | 42 ++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 592ba9c5c794..5dbb7a4e71b0 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -1,6 +1,7 @@ //! Checks the licenses of third-party dependencies. use std::collections::{HashMap, HashSet}; +use std::fmt::{Display, Formatter}; use std::fs::{File, read_dir}; use std::io::Write; use std::path::Path; @@ -14,6 +15,25 @@ use crate::diagnostics::{RunningCheck, TidyCtx}; #[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"] mod proc_macro_deps; +#[derive(Clone, Copy)] +struct ListLocation { + path: &'static str, + line: u32, +} + +impl Display for ListLocation { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}:{}", self.path, self.line) + } +} + +/// Creates a [`ListLocation`] for the current location (with an additional offset to the actual list start); +macro_rules! location { + (+ $offset:literal) => { + ListLocation { path: file!(), line: line!() + $offset } + }; +} + /// These are licenses that are allowed for all crates, including the runtime, /// rustc, tools, etc. #[rustfmt::skip] @@ -87,6 +107,8 @@ pub(crate) struct WorkspaceInfo<'a> { pub(crate) submodules: &'a [&'a str], } +const WORKSPACE_LOCATION: ListLocation = location!(+4); + /// The workspaces to check for licensing and optionally permitted dependencies. // FIXME auto detect all cargo workspaces pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ @@ -242,19 +264,6 @@ const EXCEPTIONS_BOOTSTRAP: ExceptionList = &[]; const EXCEPTIONS_UEFI_QEMU_TEST: ExceptionList = &[]; -#[derive(Clone, Copy)] -struct ListLocation { - path: &'static str, - line: u32, -} - -/// Creates a [`ListLocation`] for the current location (with an additional offset to the actual list start); -macro_rules! location { - (+ $offset:literal) => { - ListLocation { path: file!(), line: line!() + $offset } - }; -} - const PERMITTED_RUSTC_DEPS_LOCATION: ListLocation = location!(+6); /// Crates rustc is allowed to depend on. Avoid adding to the list if possible. @@ -641,6 +650,13 @@ pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { .other_options(vec!["--locked".to_owned()]); let metadata = t!(cmd.exec()); + // Check for packages which have been moved into a different workspace and not updated + let absolute_root = + if path == "." { root.to_path_buf() } else { t!(std::path::absolute(root.join(path))) }; + let absolute_root_real = t!(std::path::absolute(&metadata.workspace_root)); + if absolute_root_real != absolute_root { + check.error(format!("{path} is part of another workspace ({} != {}), remove from `WORKSPACES` ({WORKSPACE_LOCATION})", absolute_root.display(), absolute_root_real.display())); + } check_license_exceptions(&metadata, path, exceptions, &mut check); if let Some((crates, permitted_deps, location)) = crates_and_deps { let descr = crates.get(0).unwrap_or(&path); From c96ff2d42944a2df715115ddeaa6b260695dcca9 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Wed, 10 Dec 2025 23:41:19 +0000 Subject: [PATCH 0573/3801] Remove uses of `cfg(any()/all())` --- compiler/rustc_codegen_cranelift/src/base.rs | 2 +- library/core/src/primitive_docs.rs | 2 +- tests/ui/asm/naked-functions-inline.rs | 2 +- tests/ui/asm/naked-functions-inline.stderr | 6 +- .../unsafe/cfg-unsafe-attributes.rs | 2 +- .../unsafe/extraneous-unsafe-attributes.rs | 4 +- .../extraneous-unsafe-attributes.stderr | 4 +- .../ui/attributes/unsafe/unsafe-attributes.rs | 2 +- .../conditional-compilation-struct-11085.rs | 2 +- tests/ui/cfg/conditional-compile.rs | 2 +- ...nested-cfg-attr-conditional-compilation.rs | 6 +- ...ed-cfg-attr-conditional-compilation.stderr | 4 +- tests/ui/coherence/coherence-cow.rs | 2 +- .../cfg-attr-multi-false.rs | 2 +- .../cfg-attr-multi-true.rs | 2 +- .../conditional-compilation/cfg-attr-parse.rs | 22 +-- .../cfg-attr-parse.stderr | 90 ++++++------ ...-attr-unknown-attribute-macro-expansion.rs | 2 +- ...r-unknown-attribute-macro-expansion.stderr | 6 +- .../cfg-empty-any-all.rs | 12 ++ .../cfg-empty-any-all.stderr | 21 +++ .../conditional-compilation/cfg_attr_path.rs | 4 +- .../ui/conditional-compilation/issue-34028.rs | 2 +- .../module_with_cfg.rs | 2 +- .../ui/coroutine/static-closure-unexpanded.rs | 2 +- .../feature-gate-pin_ergonomics.rs | 2 +- .../feature-gates/feature-gate-super-let.rs | 2 +- .../feature-gate-unsafe-binders.rs | 2 +- .../feature-gate-unsafe_fields.rs | 6 +- .../feature-gate-where_clause_attrs.a.stderr | 132 +++++++++--------- .../feature-gate-where_clause_attrs.b.stderr | 132 +++++++++--------- .../feature-gate-where_clause_attrs.rs | 96 ++++++------- tests/ui/issues/issue-24434.rs | 2 +- tests/ui/lint/issue-97094.rs | 18 +-- tests/ui/lint/issue-97094.stderr | 36 ++--- tests/ui/macros/issue-34171.rs | 2 +- tests/ui/parser/attribute-on-empty.rs | 2 +- tests/ui/parser/attribute-on-empty.stderr | 2 +- tests/ui/parser/attribute-on-type.rs | 6 +- tests/ui/parser/attribute-on-type.stderr | 6 +- .../parser/attribute/attr-pat-struct-rest.rs | 2 +- .../attribute/attr-pat-struct-rest.stderr | 2 +- tests/ui/parser/cfg-keyword-lifetime.rs | 2 +- tests/ui/parser/issue-116781.rs | 2 +- tests/ui/parser/raw/raw-idents.rs | 2 +- .../ty-path-followed-by-single-colon.rs | 2 +- .../ui/proc-macro/ambiguous-builtin-attrs.rs | 2 +- .../proc-macro/ambiguous-builtin-attrs.stderr | 6 +- .../proc-macro/auxiliary/derive-attr-cfg.rs | 2 +- tests/ui/proc-macro/cfg-eval.rs | 8 +- tests/ui/proc-macro/cfg-eval.stderr | 4 +- tests/ui/proc-macro/cfg-eval.stdout | 44 +++--- tests/ui/proc-macro/derive-attr-cfg.rs | 2 +- tests/ui/proc-macro/derive-b.rs | 2 +- .../ui/proc-macro/derive-helper-configured.rs | 4 +- ...gest-import-without-clobbering-attrs.fixed | 2 +- ...suggest-import-without-clobbering-attrs.rs | 2 +- .../unsafe-attributes-fix.fixed | 2 +- .../unsafe-attributes-fix.rs | 2 +- .../unsafe-attributes-fix.stderr | 10 +- tests/ui/static/static-align.rs | 2 +- tests/ui/structs/struct-field-cfg.rs | 16 +-- tests/ui/structs/struct-field-cfg.stderr | 22 +-- tests/ui/test-attrs/issue-34932.rs | 2 +- .../ui/typeck/issue-86721-return-expr-ice.rs | 2 +- 65 files changed, 412 insertions(+), 389 deletions(-) create mode 100644 tests/ui/conditional-compilation/cfg-empty-any-all.rs create mode 100644 tests/ui/conditional-compilation/cfg-empty-any-all.stderr diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index a0bee4e18214..ac5b3c240785 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -167,7 +167,7 @@ pub(crate) fn compile_fn( context.clear(); context.func = codegened_func.func; - #[cfg(any())] // This is never true + #[cfg(false)] let _clif_guard = { use std::fmt::Write; diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 15ba72bccaa9..3a4e1e657a3d 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -591,7 +591,7 @@ impl () {} /// # pub unsafe fn malloc(_size: usize) -> *mut core::ffi::c_void { core::ptr::NonNull::dangling().as_ptr() } /// # pub unsafe fn free(_ptr: *mut core::ffi::c_void) {} /// # } -/// # #[cfg(any())] +/// # #[cfg(false)] /// #[allow(unused_extern_crates)] /// extern crate libc; /// diff --git a/tests/ui/asm/naked-functions-inline.rs b/tests/ui/asm/naked-functions-inline.rs index 93741f26275b..b6fddc88e19b 100644 --- a/tests/ui/asm/naked-functions-inline.rs +++ b/tests/ui/asm/naked-functions-inline.rs @@ -30,7 +30,7 @@ pub extern "C" fn inline_never() { } #[unsafe(naked)] -#[cfg_attr(all(), inline(never))] +#[cfg_attr(true, inline(never))] //~^ ERROR [E0736] pub extern "C" fn conditional_inline_never() { naked_asm!(""); diff --git a/tests/ui/asm/naked-functions-inline.stderr b/tests/ui/asm/naked-functions-inline.stderr index 91140a301edc..785ecf734b9d 100644 --- a/tests/ui/asm/naked-functions-inline.stderr +++ b/tests/ui/asm/naked-functions-inline.stderr @@ -23,12 +23,12 @@ LL | #[inline(never)] | ^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` error[E0736]: attribute incompatible with `#[unsafe(naked)]` - --> $DIR/naked-functions-inline.rs:33:19 + --> $DIR/naked-functions-inline.rs:33:18 | LL | #[unsafe(naked)] | ---------------- function marked with `#[unsafe(naked)]` here -LL | #[cfg_attr(all(), inline(never))] - | ^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` +LL | #[cfg_attr(true, inline(never))] + | ^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` error: aborting due to 4 previous errors diff --git a/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs b/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs index 6a9853b2f6fc..7d05e08b2623 100644 --- a/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs @@ -1,6 +1,6 @@ //@ build-pass -#[cfg_attr(all(), unsafe(no_mangle))] +#[cfg_attr(true, unsafe(no_mangle))] fn a() {} fn main() {} diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs index 19046c08ca8b..a034b7246a34 100644 --- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs @@ -1,9 +1,9 @@ //@ edition: 2024 -#[unsafe(cfg(any()))] //~ ERROR: is not an unsafe attribute +#[unsafe(cfg(false))] //~ ERROR: is not an unsafe attribute fn a() {} -#[unsafe(cfg_attr(any(), allow(dead_code)))] //~ ERROR: is not an unsafe attribute +#[unsafe(cfg_attr(false, allow(dead_code)))] //~ ERROR: is not an unsafe attribute fn b() {} #[unsafe(test)] //~ ERROR: is not an unsafe attribute diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr index b549a638d5ea..dec8c4d3542b 100644 --- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr @@ -1,7 +1,7 @@ error: `cfg` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:3:3 | -LL | #[unsafe(cfg(any()))] +LL | #[unsafe(cfg(false))] | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -9,7 +9,7 @@ LL | #[unsafe(cfg(any()))] error: `cfg_attr` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:6:3 | -LL | #[unsafe(cfg_attr(any(), allow(dead_code)))] +LL | #[unsafe(cfg_attr(false, allow(dead_code)))] | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes diff --git a/tests/ui/attributes/unsafe/unsafe-attributes.rs b/tests/ui/attributes/unsafe/unsafe-attributes.rs index 5c57767b3b96..c08b0ed995e5 100644 --- a/tests/ui/attributes/unsafe/unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/unsafe-attributes.rs @@ -6,7 +6,7 @@ fn a() {} #[unsafe(export_name = "foo")] fn b() {} -#[cfg_attr(any(), unsafe(no_mangle))] +#[cfg_attr(false, unsafe(no_mangle))] static VAR2: u32 = 1; fn main() {} diff --git a/tests/ui/cfg/conditional-compilation-struct-11085.rs b/tests/ui/cfg/conditional-compilation-struct-11085.rs index cd6dded54d30..8fdc88be37d2 100644 --- a/tests/ui/cfg/conditional-compilation-struct-11085.rs +++ b/tests/ui/cfg/conditional-compilation-struct-11085.rs @@ -11,7 +11,7 @@ struct Foo { } struct Foo2 { - #[cfg(all())] + #[cfg(true)] foo: isize, } diff --git a/tests/ui/cfg/conditional-compile.rs b/tests/ui/cfg/conditional-compile.rs index 0739e877bfd1..8761197891f5 100644 --- a/tests/ui/cfg/conditional-compile.rs +++ b/tests/ui/cfg/conditional-compile.rs @@ -151,5 +151,5 @@ mod test_methods { } } -#[cfg(any())] +#[cfg(false)] mod nonexistent_file; // Check that unconfigured non-inline modules are not loaded or parsed. diff --git a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs index c5d86a27d522..8e79ce8d1546 100644 --- a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs +++ b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs @@ -3,14 +3,14 @@ //! expansion works from outside to inside, eventually applying the innermost //! conditional compilation directive. //! -//! In this test, `cfg_attr(all(), cfg_attr(all(), cfg(false)))` should expand to: -//! 1. `cfg_attr(all(), cfg(false))` (outer cfg_attr applied) +//! In this test, `cfg_attr(true, cfg_attr(true, cfg(false)))` should expand to: +//! 1. `cfg_attr(true, cfg(false))` (outer cfg_attr applied) //! 2. `cfg(false)` (inner cfg_attr applied) //! 3. Function `f` is excluded from compilation //! //! Added in . -#[cfg_attr(all(), cfg_attr(all(), cfg(false)))] //~ NOTE the item is gated here +#[cfg_attr(true, cfg_attr(true, cfg(false)))] //~ NOTE the item is gated here fn f() {} //~ NOTE found an item that was configured out fn main() { diff --git a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr index 3f833bd558b8..e93a5433d979 100644 --- a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr +++ b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr @@ -7,8 +7,8 @@ LL | f() note: found an item that was configured out --> $DIR/nested-cfg-attr-conditional-compilation.rs:14:4 | -LL | #[cfg_attr(all(), cfg_attr(all(), cfg(false)))] - | ----- the item is gated here +LL | #[cfg_attr(true, cfg_attr(true, cfg(false)))] + | ----- the item is gated here LL | fn f() {} | ^ diff --git a/tests/ui/coherence/coherence-cow.rs b/tests/ui/coherence/coherence-cow.rs index af94964762a9..2fc33e3a3e8f 100644 --- a/tests/ui/coherence/coherence-cow.rs +++ b/tests/ui/coherence/coherence-cow.rs @@ -1,6 +1,6 @@ //@ revisions: re_a re_b re_c -#![cfg_attr(any(), re_a, re_b, re_c)] +#![cfg_attr(false, re_a, re_b, re_c)] //@ aux-build:coherence_lib.rs diff --git a/tests/ui/conditional-compilation/cfg-attr-multi-false.rs b/tests/ui/conditional-compilation/cfg-attr-multi-false.rs index cfb430ec5b23..871c1b81acd2 100644 --- a/tests/ui/conditional-compilation/cfg-attr-multi-false.rs +++ b/tests/ui/conditional-compilation/cfg-attr-multi-false.rs @@ -5,7 +5,7 @@ #![warn(unused_must_use)] -#[cfg_attr(any(), deprecated, must_use)] +#[cfg_attr(false, deprecated, must_use)] struct Struct {} impl Struct { diff --git a/tests/ui/conditional-compilation/cfg-attr-multi-true.rs b/tests/ui/conditional-compilation/cfg-attr-multi-true.rs index 424760c2e663..24950c8d4234 100644 --- a/tests/ui/conditional-compilation/cfg-attr-multi-true.rs +++ b/tests/ui/conditional-compilation/cfg-attr-multi-true.rs @@ -6,7 +6,7 @@ #![warn(unused_must_use)] -#[cfg_attr(all(), deprecated, must_use)] +#[cfg_attr(true, deprecated, must_use)] struct MustUseDeprecated {} impl MustUseDeprecated { //~ warning: use of deprecated diff --git a/tests/ui/conditional-compilation/cfg-attr-parse.rs b/tests/ui/conditional-compilation/cfg-attr-parse.rs index b8aaad2685ef..21df51264e2d 100644 --- a/tests/ui/conditional-compilation/cfg-attr-parse.rs +++ b/tests/ui/conditional-compilation/cfg-attr-parse.rs @@ -5,50 +5,50 @@ struct NoConfigurationPredicate; // Zero attributes, zero trailing comma (comma manatory here) -#[cfg_attr(all())] //~ error: expected `,`, found end of `cfg_attr` +#[cfg_attr(true)] //~ error: expected `,`, found end of `cfg_attr` struct A0C0; // Zero attributes, one trailing comma -#[cfg_attr(all(),)] +#[cfg_attr(true,)] //~^ WARN `#[cfg_attr]` does not expand to any attributes struct A0C1; // Zero attributes, two trailing commas -#[cfg_attr(all(),,)] //~ ERROR expected identifier +#[cfg_attr(true,,)] //~ ERROR expected identifier struct A0C2; // One attribute, no trailing comma -#[cfg_attr(all(), must_use)] // Ok +#[cfg_attr(true, must_use)] // Ok struct A1C0; // One attribute, one trailing comma -#[cfg_attr(all(), must_use,)] // Ok +#[cfg_attr(true, must_use,)] // Ok struct A1C1; // One attribute, two trailing commas -#[cfg_attr(all(), must_use,,)] //~ ERROR expected identifier +#[cfg_attr(true, must_use,,)] //~ ERROR expected identifier struct A1C2; // Two attributes, no trailing comma -#[cfg_attr(all(), must_use, deprecated)] // Ok +#[cfg_attr(true, must_use, deprecated)] // Ok struct A2C0; // Two attributes, one trailing comma -#[cfg_attr(all(), must_use, deprecated,)] // Ok +#[cfg_attr(true, must_use, deprecated,)] // Ok struct A2C1; // Two attributes, two trailing commas -#[cfg_attr(all(), must_use, deprecated,,)] //~ ERROR expected identifier +#[cfg_attr(true, must_use, deprecated,,)] //~ ERROR expected identifier struct A2C2; // Wrong delimiter `[` -#[cfg_attr[all(),,]] +#[cfg_attr[true,,]] //~^ ERROR wrong `cfg_attr` delimiters //~| ERROR expected identifier, found `,` struct BracketZero; // Wrong delimiter `{` -#[cfg_attr{all(),,}] +#[cfg_attr{true,,}] //~^ ERROR wrong `cfg_attr` delimiters //~| ERROR expected identifier, found `,` struct BraceZero; diff --git a/tests/ui/conditional-compilation/cfg-attr-parse.stderr b/tests/ui/conditional-compilation/cfg-attr-parse.stderr index 4d4769b05cda..8dbe8969fd1c 100644 --- a/tests/ui/conditional-compilation/cfg-attr-parse.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-parse.stderr @@ -10,45 +10,45 @@ LL | #[cfg_attr()] = note: for more information, visit error: expected `,`, found end of `cfg_attr` input - --> $DIR/cfg-attr-parse.rs:8:17 + --> $DIR/cfg-attr-parse.rs:8:16 | -LL | #[cfg_attr(all())] - | ----------------^- +LL | #[cfg_attr(true)] + | ---------------^- + | | | + | | expected `,` + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` + | + = note: for more information, visit + +error: expected identifier, found `,` + --> $DIR/cfg-attr-parse.rs:17:17 + | +LL | #[cfg_attr(true,,)] + | ----------------^-- | | | - | | expected `,` + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:17:18 + --> $DIR/cfg-attr-parse.rs:29:27 | -LL | #[cfg_attr(all(),,)] - | -----------------^-- - | | | - | | expected identifier +LL | #[cfg_attr(true, must_use,,)] + | --------------------------^-- + | | | + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:29:28 + --> $DIR/cfg-attr-parse.rs:41:39 | -LL | #[cfg_attr(all(), must_use,,)] - | ---------------------------^-- - | | | - | | expected identifier - | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` - | - = note: for more information, visit - -error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:41:40 - | -LL | #[cfg_attr(all(), must_use, deprecated,,)] - | ---------------------------------------^-- - | | | - | | expected identifier +LL | #[cfg_attr(true, must_use, deprecated,,)] + | --------------------------------------^-- + | | | + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit @@ -56,22 +56,22 @@ LL | #[cfg_attr(all(), must_use, deprecated,,)] error: wrong `cfg_attr` delimiters --> $DIR/cfg-attr-parse.rs:45:11 | -LL | #[cfg_attr[all(),,]] - | ^^^^^^^^^ +LL | #[cfg_attr[true,,]] + | ^^^^^^^^ | help: the delimiters should be `(` and `)` | -LL - #[cfg_attr[all(),,]] -LL + #[cfg_attr(all(),,)] +LL - #[cfg_attr[true,,]] +LL + #[cfg_attr(true,,)] | error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:45:18 + --> $DIR/cfg-attr-parse.rs:45:17 | -LL | #[cfg_attr[all(),,]] - | -----------------^-- - | | | - | | expected identifier +LL | #[cfg_attr[true,,]] + | ----------------^-- + | | | + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit @@ -79,22 +79,22 @@ LL | #[cfg_attr[all(),,]] error: wrong `cfg_attr` delimiters --> $DIR/cfg-attr-parse.rs:51:11 | -LL | #[cfg_attr{all(),,}] - | ^^^^^^^^^ +LL | #[cfg_attr{true,,}] + | ^^^^^^^^ | help: the delimiters should be `(` and `)` | -LL - #[cfg_attr{all(),,}] -LL + #[cfg_attr(all(),,)] +LL - #[cfg_attr{true,,}] +LL + #[cfg_attr(true,,)] | error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:51:18 + --> $DIR/cfg-attr-parse.rs:51:17 | -LL | #[cfg_attr{all(),,}] - | -----------------^-- - | | | - | | expected identifier +LL | #[cfg_attr{true,,}] + | ----------------^-- + | | | + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit @@ -102,8 +102,8 @@ LL | #[cfg_attr{all(),,}] warning: `#[cfg_attr]` does not expand to any attributes --> $DIR/cfg-attr-parse.rs:12:1 | -LL | #[cfg_attr(all(),)] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true,)] + | ^^^^^^^^^^^^^^^^^^ | = note: requested on the command line with `-W unused-attributes` diff --git a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs index 45b757e92830..0305be5d24e6 100644 --- a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs +++ b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs @@ -1,6 +1,6 @@ macro_rules! foo { () => { - #[cfg_attr(all(), unknown)] + #[cfg_attr(true, unknown)] //~^ ERROR cannot find attribute `unknown` in this scope fn foo() {} } diff --git a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr index c91ad128d6e5..bdddbd68cdaf 100644 --- a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr @@ -1,8 +1,8 @@ error: cannot find attribute `unknown` in this scope - --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:27 + --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:26 | -LL | #[cfg_attr(all(), unknown)] - | ^^^^^^^ +LL | #[cfg_attr(true, unknown)] + | ^^^^^^^ ... LL | foo!(); | ------ in this macro invocation diff --git a/tests/ui/conditional-compilation/cfg-empty-any-all.rs b/tests/ui/conditional-compilation/cfg-empty-any-all.rs new file mode 100644 index 000000000000..48ed4342235c --- /dev/null +++ b/tests/ui/conditional-compilation/cfg-empty-any-all.rs @@ -0,0 +1,12 @@ +//! Test the behaviour of `cfg(any())` and `cfg(all())` + +#[cfg(any())] // Equivalent to cfg(false) +struct Disabled; + +#[cfg(all())] // Equivalent to cfg(true) +struct Enabled; + +fn main() { + let _ = Disabled; //~ ERROR: cannot find value `Disabled` + let _ = Enabled; // ok +} diff --git a/tests/ui/conditional-compilation/cfg-empty-any-all.stderr b/tests/ui/conditional-compilation/cfg-empty-any-all.stderr new file mode 100644 index 000000000000..1674f2def23a --- /dev/null +++ b/tests/ui/conditional-compilation/cfg-empty-any-all.stderr @@ -0,0 +1,21 @@ +error[E0425]: cannot find value `Disabled` in this scope + --> $DIR/cfg-empty-any-all.rs:10:13 + | +LL | let _ = Disabled; + | ^^^^^^^^ not found in this scope + | +note: found an item that was configured out + --> $DIR/cfg-empty-any-all.rs:4:8 + | +LL | #[cfg(any())] // Equivalent to cfg(false) + | -- the item is gated here +LL | struct Disabled; + | ^^^^^^^^ +help: consider importing this unit variant + | +LL + use std::backtrace::BacktraceStatus::Disabled; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/conditional-compilation/cfg_attr_path.rs b/tests/ui/conditional-compilation/cfg_attr_path.rs index 00e07761977a..f300e02932b7 100644 --- a/tests/ui/conditional-compilation/cfg_attr_path.rs +++ b/tests/ui/conditional-compilation/cfg_attr_path.rs @@ -3,8 +3,8 @@ #![deny(unused_attributes)] // c.f #35584 mod auxiliary { - #[cfg_attr(any(), path = "nonexistent_file.rs")] pub mod namespaced_enums; - #[cfg_attr(all(), path = "namespaced_enums.rs")] pub mod nonexistent_file; + #[cfg_attr(false, path = "nonexistent_file.rs")] pub mod namespaced_enums; + #[cfg_attr(true, path = "namespaced_enums.rs")] pub mod nonexistent_file; } fn main() { diff --git a/tests/ui/conditional-compilation/issue-34028.rs b/tests/ui/conditional-compilation/issue-34028.rs index 3ee43cb4b322..d6f3f7a9abce 100644 --- a/tests/ui/conditional-compilation/issue-34028.rs +++ b/tests/ui/conditional-compilation/issue-34028.rs @@ -1,7 +1,7 @@ //@ check-pass macro_rules! m { - () => { #[cfg(any())] fn f() {} } + () => { #[cfg(false)] fn f() {} } } trait T {} diff --git a/tests/ui/conditional-compilation/module_with_cfg.rs b/tests/ui/conditional-compilation/module_with_cfg.rs index a96f8a3e6e96..32486bdb43d6 100644 --- a/tests/ui/conditional-compilation/module_with_cfg.rs +++ b/tests/ui/conditional-compilation/module_with_cfg.rs @@ -1,3 +1,3 @@ //@ ignore-auxiliary (used by `./inner-cfg-non-inline-mod.rs`) -#![cfg_attr(all(), cfg(false))] +#![cfg_attr(true, cfg(false))] diff --git a/tests/ui/coroutine/static-closure-unexpanded.rs b/tests/ui/coroutine/static-closure-unexpanded.rs index 7cf24774deda..ac7c251c8348 100644 --- a/tests/ui/coroutine/static-closure-unexpanded.rs +++ b/tests/ui/coroutine/static-closure-unexpanded.rs @@ -1,7 +1,7 @@ // Tests that static closures are not stable in the parser grammar unless the // coroutine feature is enabled. -#[cfg(any())] +#[cfg(false)] fn foo() { let _ = static || {}; //~^ ERROR coroutine syntax is experimental diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs index 7f669d0b93e5..6cb4492c3754 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs @@ -58,7 +58,7 @@ fn patterns<'a>( ref pin const w: i32, //~ ERROR pinned reference syntax is experimental ) {} -#[cfg(any())] +#[cfg(false)] mod not_compiled { use std::pin::Pin; diff --git a/tests/ui/feature-gates/feature-gate-super-let.rs b/tests/ui/feature-gates/feature-gate-super-let.rs index 7be080039133..19da1c4aa39b 100644 --- a/tests/ui/feature-gates/feature-gate-super-let.rs +++ b/tests/ui/feature-gates/feature-gate-super-let.rs @@ -4,7 +4,7 @@ fn main() { } // Check that it also isn't accepted in cfg'd out code. -#[cfg(any())] +#[cfg(false)] fn a() { super let a = 1; //~^ ERROR `super let` is experimental diff --git a/tests/ui/feature-gates/feature-gate-unsafe-binders.rs b/tests/ui/feature-gates/feature-gate-unsafe-binders.rs index a2997ced4fa1..e1eda7def482 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe-binders.rs +++ b/tests/ui/feature-gates/feature-gate-unsafe-binders.rs @@ -1,4 +1,4 @@ -#[cfg(any())] +#[cfg(false)] fn test() { let x: unsafe<> (); //~^ ERROR unsafe binder types are experimental diff --git a/tests/ui/feature-gates/feature-gate-unsafe_fields.rs b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs index 8f9b411df469..2b0bbaa08357 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe_fields.rs +++ b/tests/ui/feature-gates/feature-gate-unsafe_fields.rs @@ -4,7 +4,7 @@ #![cfg_attr(with_gate, feature(unsafe_fields))] //[with_gate]~ WARNING -#[cfg(any())] +#[cfg(false)] struct Foo { unsafe field: (), //[without_gate]~ ERROR } @@ -12,14 +12,14 @@ struct Foo { // This should not parse as an unsafe field definition. struct FooTuple(unsafe fn()); -#[cfg(any())] +#[cfg(false)] enum Bar { Variant { unsafe field: () }, //[without_gate]~ ERROR // This should not parse as an unsafe field definition. VariantTuple(unsafe fn()), } -#[cfg(any())] +#[cfg(false)] union Baz { unsafe field: (), //[without_gate]~ ERROR } diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr b/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr index 6a8f01bbcce1..970763157d18 100644 --- a/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr +++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr @@ -21,8 +21,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:35:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -31,7 +31,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:36:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -61,8 +61,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:39:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -71,7 +71,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:40:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -101,8 +101,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:46:9 | -LL | #[cfg(all())] U: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] U: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -111,7 +111,7 @@ LL | #[cfg(all())] U: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:47:9 | -LL | #[cfg(any())] U: TraitAny, +LL | #[cfg(false)] U: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -141,8 +141,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:50:9 | -LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -151,7 +151,7 @@ LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:51:9 | -LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; +LL | #[cfg_attr(false, cfg(false))] U: TraitAnyAny; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -181,8 +181,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:57:9 | -LL | #[cfg(all())] U: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] U: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -191,7 +191,7 @@ LL | #[cfg(all())] U: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:58:9 | -LL | #[cfg(any())] U: TraitAny, +LL | #[cfg(false)] U: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -221,8 +221,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:61:9 | -LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -231,7 +231,7 @@ LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:62:9 | -LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; +LL | #[cfg_attr(false, cfg(false))] U: TraitAnyAny; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -261,8 +261,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:69:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -271,7 +271,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:70:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -301,8 +301,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:73:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -311,7 +311,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:74:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -341,8 +341,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:79:9 | -LL | #[cfg(all())] U: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] U: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -351,7 +351,7 @@ LL | #[cfg(all())] U: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:80:9 | -LL | #[cfg(any())] U: TraitAny, +LL | #[cfg(false)] U: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -381,8 +381,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:83:9 | -LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -391,7 +391,7 @@ LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:84:9 | -LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; +LL | #[cfg_attr(false, cfg(false))] U: TraitAnyAny; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -421,8 +421,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:90:9 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -431,7 +431,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:91:9 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -461,8 +461,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:94:9 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -471,7 +471,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:95:9 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -501,8 +501,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:103:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -511,7 +511,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:104:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -541,8 +541,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:107:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -551,7 +551,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:108:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -581,8 +581,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:117:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -591,7 +591,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:118:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -621,8 +621,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:121:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -631,7 +631,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:122:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -661,8 +661,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:132:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -671,7 +671,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:133:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -701,8 +701,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:136:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -711,7 +711,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:137:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -741,8 +741,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:145:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -751,7 +751,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:146:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -781,8 +781,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:149:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -791,7 +791,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:150:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -821,8 +821,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:155:9 | -LL | #[cfg(all())] U: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] U: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -831,7 +831,7 @@ LL | #[cfg(all())] U: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:156:9 | -LL | #[cfg(any())] U: TraitAny, +LL | #[cfg(false)] U: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -861,8 +861,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:159:9 | -LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -871,7 +871,7 @@ LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:160:9 | -LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] U: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr b/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr index 6a8f01bbcce1..970763157d18 100644 --- a/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr +++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr @@ -21,8 +21,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:35:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -31,7 +31,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:36:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -61,8 +61,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:39:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -71,7 +71,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:40:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -101,8 +101,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:46:9 | -LL | #[cfg(all())] U: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] U: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -111,7 +111,7 @@ LL | #[cfg(all())] U: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:47:9 | -LL | #[cfg(any())] U: TraitAny, +LL | #[cfg(false)] U: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -141,8 +141,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:50:9 | -LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -151,7 +151,7 @@ LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:51:9 | -LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; +LL | #[cfg_attr(false, cfg(false))] U: TraitAnyAny; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -181,8 +181,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:57:9 | -LL | #[cfg(all())] U: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] U: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -191,7 +191,7 @@ LL | #[cfg(all())] U: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:58:9 | -LL | #[cfg(any())] U: TraitAny, +LL | #[cfg(false)] U: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -221,8 +221,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:61:9 | -LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -231,7 +231,7 @@ LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:62:9 | -LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; +LL | #[cfg_attr(false, cfg(false))] U: TraitAnyAny; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -261,8 +261,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:69:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -271,7 +271,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:70:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -301,8 +301,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:73:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -311,7 +311,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:74:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -341,8 +341,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:79:9 | -LL | #[cfg(all())] U: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] U: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -351,7 +351,7 @@ LL | #[cfg(all())] U: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:80:9 | -LL | #[cfg(any())] U: TraitAny, +LL | #[cfg(false)] U: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -381,8 +381,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:83:9 | -LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -391,7 +391,7 @@ LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:84:9 | -LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; +LL | #[cfg_attr(false, cfg(false))] U: TraitAnyAny; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -421,8 +421,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:90:9 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -431,7 +431,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:91:9 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -461,8 +461,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:94:9 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -471,7 +471,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:95:9 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -501,8 +501,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:103:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -511,7 +511,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:104:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -541,8 +541,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:107:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -551,7 +551,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:108:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -581,8 +581,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:117:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -591,7 +591,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:118:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -621,8 +621,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:121:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -631,7 +631,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:122:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -661,8 +661,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:132:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -671,7 +671,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:133:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -701,8 +701,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:136:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -711,7 +711,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:137:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -741,8 +741,8 @@ LL | #[cfg(b)] T: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:145:5 | -LL | #[cfg(all())] T: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] T: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -751,7 +751,7 @@ LL | #[cfg(all())] T: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:146:5 | -LL | #[cfg(any())] T: TraitAny, +LL | #[cfg(false)] T: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -781,8 +781,8 @@ LL | #[cfg_attr(b, cfg(b))] T: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:149:5 | -LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] T: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -791,7 +791,7 @@ LL | #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:150:5 | -LL | #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] T: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -821,8 +821,8 @@ LL | #[cfg(b)] U: TraitB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:155:9 | -LL | #[cfg(all())] U: TraitAll, - | ^^^^^^^^^^^^^ +LL | #[cfg(true)] U: TraitAll, + | ^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -831,7 +831,7 @@ LL | #[cfg(all())] U: TraitAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:156:9 | -LL | #[cfg(any())] U: TraitAny, +LL | #[cfg(false)] U: TraitAny, | ^^^^^^^^^^^^^ | = note: see issue #115590 for more information @@ -861,8 +861,8 @@ LL | #[cfg_attr(b, cfg(b))] U: TraitBB, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:159:9 | -LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, cfg(true))] U: TraitAllAll, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable @@ -871,7 +871,7 @@ LL | #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, error[E0658]: attributes in `where` clause are unstable --> $DIR/feature-gate-where_clause_attrs.rs:160:9 | -LL | #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny, +LL | #[cfg_attr(false, cfg(false))] U: TraitAnyAny, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #115590 for more information diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs b/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs index 09c734a52de0..b87a1d56ea06 100644 --- a/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs +++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs @@ -15,16 +15,16 @@ trait TraitAA {} #[cfg_attr(b, cfg(b))] trait TraitBB {} -#[cfg(all())] +#[cfg(true)] trait TraitAll {} -#[cfg(any())] +#[cfg(false)] trait TraitAny {} -#[cfg_attr(all(), cfg(all()))] +#[cfg_attr(true, cfg(true))] trait TraitAllAll {} -#[cfg_attr(any(), cfg(any()))] +#[cfg_attr(false, cfg(false))] trait TraitAnyAny {} @@ -32,67 +32,67 @@ trait A where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { type B where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] U: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable fn foo(&self) where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] U: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable } impl A for T where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { type B = () where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] U: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable fn foo(&self) where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable {} } @@ -100,12 +100,12 @@ struct C where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { _t: PhantomData, } @@ -114,12 +114,12 @@ union D where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { _t: PhantomData, @@ -129,12 +129,12 @@ enum E where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { E(PhantomData), } @@ -142,21 +142,21 @@ where impl C where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { fn new() where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] U: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] U: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable {} } diff --git a/tests/ui/issues/issue-24434.rs b/tests/ui/issues/issue-24434.rs index 991084c27409..429bcf4a8d87 100644 --- a/tests/ui/issues/issue-24434.rs +++ b/tests/ui/issues/issue-24434.rs @@ -1,6 +1,6 @@ //@ check-pass -#![cfg_attr(all(), feature(rustc_attrs))] +#![cfg_attr(true, feature(rustc_attrs))] #![rustc_dummy] fn main() {} diff --git a/tests/ui/lint/issue-97094.rs b/tests/ui/lint/issue-97094.rs index 22525ca11ae0..737f2827b67a 100644 --- a/tests/ui/lint/issue-97094.rs +++ b/tests/ui/lint/issue-97094.rs @@ -2,19 +2,19 @@ // Ensure that unknown lints inside cfg-attr's are linted for -#![cfg_attr(all(), allow(nonex_lint_top_level))] +#![cfg_attr(true, allow(nonex_lint_top_level))] //~^ ERROR unknown lint -#![cfg_attr(all(), allow(bare_trait_object))] +#![cfg_attr(true, allow(bare_trait_object))] //~^ ERROR has been renamed -#[cfg_attr(all(), allow(nonex_lint_mod))] +#[cfg_attr(true, allow(nonex_lint_mod))] //~^ ERROR unknown lint mod baz { - #![cfg_attr(all(), allow(nonex_lint_mod_inner))] + #![cfg_attr(true, allow(nonex_lint_mod_inner))] //~^ ERROR unknown lint } -#[cfg_attr(all(), allow(nonex_lint_fn))] +#[cfg_attr(true, allow(nonex_lint_fn))] //~^ ERROR unknown lint pub fn main() {} @@ -25,24 +25,24 @@ macro_rules! bar { } bar!( - #[cfg_attr(all(), allow(nonex_lint_in_macro))] + #[cfg_attr(true, allow(nonex_lint_in_macro))] //~^ ERROR unknown lint pub fn _bar() {} ); // No warning for non-applying cfg -#[cfg_attr(any(), allow(nonex_lint_fn))] +#[cfg_attr(false, allow(nonex_lint_fn))] pub fn _foo() {} // Allowing unknown lints works if inside cfg_attr -#[cfg_attr(all(), allow(unknown_lints))] +#[cfg_attr(true, allow(unknown_lints))] mod bar_allowed { #[allow(nonex_lint_fn)] fn _foo() {} } // ... but not if the cfg_attr doesn't evaluate -#[cfg_attr(any(), allow(unknown_lints))] +#[cfg_attr(false, allow(unknown_lints))] mod bar_not_allowed { #[allow(nonex_lint_fn)] //~^ ERROR unknown lint diff --git a/tests/ui/lint/issue-97094.stderr b/tests/ui/lint/issue-97094.stderr index 1a0a3eaf2507..e12250aa7542 100644 --- a/tests/ui/lint/issue-97094.stderr +++ b/tests/ui/lint/issue-97094.stderr @@ -1,8 +1,8 @@ error: unknown lint: `nonex_lint_top_level` - --> $DIR/issue-97094.rs:5:26 + --> $DIR/issue-97094.rs:5:25 | -LL | #![cfg_attr(all(), allow(nonex_lint_top_level))] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![cfg_attr(true, allow(nonex_lint_top_level))] + | ^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/issue-97094.rs:1:9 @@ -12,36 +12,36 @@ LL | #![deny(warnings)] = note: `#[deny(unknown_lints)]` implied by `#[deny(warnings)]` error: lint `bare_trait_object` has been renamed to `bare_trait_objects` - --> $DIR/issue-97094.rs:7:26 + --> $DIR/issue-97094.rs:7:25 | -LL | #![cfg_attr(all(), allow(bare_trait_object))] - | ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects` +LL | #![cfg_attr(true, allow(bare_trait_object))] + | ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects` | = note: `#[deny(renamed_and_removed_lints)]` implied by `#[deny(warnings)]` error: unknown lint: `nonex_lint_mod` - --> $DIR/issue-97094.rs:10:25 + --> $DIR/issue-97094.rs:10:24 | -LL | #[cfg_attr(all(), allow(nonex_lint_mod))] - | ^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, allow(nonex_lint_mod))] + | ^^^^^^^^^^^^^^ error: unknown lint: `nonex_lint_mod_inner` - --> $DIR/issue-97094.rs:13:30 + --> $DIR/issue-97094.rs:13:29 | -LL | #![cfg_attr(all(), allow(nonex_lint_mod_inner))] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![cfg_attr(true, allow(nonex_lint_mod_inner))] + | ^^^^^^^^^^^^^^^^^^^^ error: unknown lint: `nonex_lint_fn` - --> $DIR/issue-97094.rs:17:25 + --> $DIR/issue-97094.rs:17:24 | -LL | #[cfg_attr(all(), allow(nonex_lint_fn))] - | ^^^^^^^^^^^^^ +LL | #[cfg_attr(true, allow(nonex_lint_fn))] + | ^^^^^^^^^^^^^ error: unknown lint: `nonex_lint_in_macro` - --> $DIR/issue-97094.rs:28:29 + --> $DIR/issue-97094.rs:28:28 | -LL | #[cfg_attr(all(), allow(nonex_lint_in_macro))] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, allow(nonex_lint_in_macro))] + | ^^^^^^^^^^^^^^^^^^^ error: unknown lint: `nonex_lint_fn` --> $DIR/issue-97094.rs:47:13 diff --git a/tests/ui/macros/issue-34171.rs b/tests/ui/macros/issue-34171.rs index fbc2ea50097d..3f13341230fa 100644 --- a/tests/ui/macros/issue-34171.rs +++ b/tests/ui/macros/issue-34171.rs @@ -6,5 +6,5 @@ macro_rules! apply_null { } fn main() { - apply_null!(#[cfg(all())] fn f() {}); + apply_null!(#[cfg(true)] fn f() {}); } diff --git a/tests/ui/parser/attribute-on-empty.rs b/tests/ui/parser/attribute-on-empty.rs index 5932377f73ec..0177e6c1b59d 100644 --- a/tests/ui/parser/attribute-on-empty.rs +++ b/tests/ui/parser/attribute-on-empty.rs @@ -4,7 +4,7 @@ struct Baz(i32); fn main() { - let _: Baz<#[cfg(any())]> = todo!(); + let _: Baz<#[cfg(false)]> = todo!(); //~^ ERROR attributes cannot be applied here } diff --git a/tests/ui/parser/attribute-on-empty.stderr b/tests/ui/parser/attribute-on-empty.stderr index 7c4806c8704a..6bcbf1ceb8d1 100644 --- a/tests/ui/parser/attribute-on-empty.stderr +++ b/tests/ui/parser/attribute-on-empty.stderr @@ -1,7 +1,7 @@ error: attributes cannot be applied here --> $DIR/attribute-on-empty.rs:7:16 | -LL | let _: Baz<#[cfg(any())]> = todo!(); +LL | let _: Baz<#[cfg(false)]> = todo!(); | - ^^^^^^^^^^^^^ attributes are not allowed here | | | while parsing the type for `_` diff --git a/tests/ui/parser/attribute-on-type.rs b/tests/ui/parser/attribute-on-type.rs index 196d322bdf8f..b400bd1c173f 100644 --- a/tests/ui/parser/attribute-on-type.rs +++ b/tests/ui/parser/attribute-on-type.rs @@ -16,16 +16,16 @@ fn main() { let _: #[attr] &'static str = "123"; //~^ ERROR attributes cannot be applied to types - let _: Bar<#[cfg(any())] 'static> = Bar(&123); + let _: Bar<#[cfg(false)] 'static> = Bar(&123); //~^ ERROR attributes cannot be applied to generic arguments - let _: Baz<#[cfg(any())] 42> = Baz(42); + let _: Baz<#[cfg(false)] 42> = Baz(42); //~^ ERROR attributes cannot be applied to generic arguments let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); //~^ ERROR attributes cannot be applied to generic arguments - let _: Bar<#[cfg(any())] 'static> = Bar(&456); + let _: Bar<#[cfg(false)] 'static> = Bar(&456); //~^ ERROR attributes cannot be applied to generic arguments let _generic: Box<#[attr] i32> = Box::new(1); diff --git a/tests/ui/parser/attribute-on-type.stderr b/tests/ui/parser/attribute-on-type.stderr index 603c7e2be51a..316620325c04 100644 --- a/tests/ui/parser/attribute-on-type.stderr +++ b/tests/ui/parser/attribute-on-type.stderr @@ -13,13 +13,13 @@ LL | let _: #[attr] &'static str = "123"; error: attributes cannot be applied to generic arguments --> $DIR/attribute-on-type.rs:19:16 | -LL | let _: Bar<#[cfg(any())] 'static> = Bar(&123); +LL | let _: Bar<#[cfg(false)] 'static> = Bar(&123); | ^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments --> $DIR/attribute-on-type.rs:22:16 | -LL | let _: Baz<#[cfg(any())] 42> = Baz(42); +LL | let _: Baz<#[cfg(false)] 42> = Baz(42); | ^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments @@ -31,7 +31,7 @@ LL | let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); error: attributes cannot be applied to generic arguments --> $DIR/attribute-on-type.rs:28:16 | -LL | let _: Bar<#[cfg(any())] 'static> = Bar(&456); +LL | let _: Bar<#[cfg(false)] 'static> = Bar(&456); | ^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments diff --git a/tests/ui/parser/attribute/attr-pat-struct-rest.rs b/tests/ui/parser/attribute/attr-pat-struct-rest.rs index b2bfcf82df8d..8f0e4cd827e0 100644 --- a/tests/ui/parser/attribute/attr-pat-struct-rest.rs +++ b/tests/ui/parser/attribute/attr-pat-struct-rest.rs @@ -3,6 +3,6 @@ struct S {} fn main() { - let S { #[cfg(any())] .. } = S {}; + let S { #[cfg(false)] .. } = S {}; //~^ ERROR expected identifier, found `..` } diff --git a/tests/ui/parser/attribute/attr-pat-struct-rest.stderr b/tests/ui/parser/attribute/attr-pat-struct-rest.stderr index f72c54973fce..94ad7d571101 100644 --- a/tests/ui/parser/attribute/attr-pat-struct-rest.stderr +++ b/tests/ui/parser/attribute/attr-pat-struct-rest.stderr @@ -1,7 +1,7 @@ error: expected identifier, found `..` --> $DIR/attr-pat-struct-rest.rs:6:27 | -LL | let S { #[cfg(any())] .. } = S {}; +LL | let S { #[cfg(false)] .. } = S {}; | - ^^ expected identifier | | | while parsing the fields for this pattern diff --git a/tests/ui/parser/cfg-keyword-lifetime.rs b/tests/ui/parser/cfg-keyword-lifetime.rs index a1588eddc074..c61b69175c88 100644 --- a/tests/ui/parser/cfg-keyword-lifetime.rs +++ b/tests/ui/parser/cfg-keyword-lifetime.rs @@ -1,6 +1,6 @@ // Disallow `'keyword` even in cfg'd code. -#[cfg(any())] +#[cfg(false)] fn hello() -> &'ref () {} //~^ ERROR lifetimes cannot use keyword names diff --git a/tests/ui/parser/issue-116781.rs b/tests/ui/parser/issue-116781.rs index 0e951d2eaa44..176350fe2eec 100644 --- a/tests/ui/parser/issue-116781.rs +++ b/tests/ui/parser/issue-116781.rs @@ -1,6 +1,6 @@ #[derive(Debug)] struct Foo { - #[cfg(all())] + #[cfg(true)] field: fn(($),), //~ ERROR expected pattern, found `$` //~^ ERROR expected pattern, found `$` } diff --git a/tests/ui/parser/raw/raw-idents.rs b/tests/ui/parser/raw/raw-idents.rs index 93015ee6c494..4e1e6b124c31 100644 --- a/tests/ui/parser/raw/raw-idents.rs +++ b/tests/ui/parser/raw/raw-idents.rs @@ -62,7 +62,7 @@ macro_rules! tests { impl<$kw> B<$kw> {} } mod extern_crate { - #[cfg(any())] + #[cfg(false)] extern crate $kw; } mod body { diff --git a/tests/ui/parser/ty-path-followed-by-single-colon.rs b/tests/ui/parser/ty-path-followed-by-single-colon.rs index a9082ea317a7..588fec3f2fc8 100644 --- a/tests/ui/parser/ty-path-followed-by-single-colon.rs +++ b/tests/ui/parser/ty-path-followed-by-single-colon.rs @@ -12,7 +12,7 @@ mod garden { fn g(_: impl Take) {} // OK! - #[cfg(any())] fn h() where a::path:to::nowhere {} // OK! + #[cfg(false)] fn h() where a::path:to::nowhere {} // OK! fn i(_: impl Take:to::somewhere>) {} // OK! diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs index 63d3c79055ca..e36a12beb818 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs @@ -9,7 +9,7 @@ use builtin_attrs::{bench, test}; #[repr(C)] //~ ERROR `repr` is ambiguous struct S; -#[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous +#[cfg_attr(true, repr(C))] //~ ERROR `repr` is ambiguous struct SCond; #[test] // OK, shadowed diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr index ff7894a41eab..d05701986260 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr @@ -20,10 +20,10 @@ LL | use builtin_attrs::*; = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:12:19 + --> $DIR/ambiguous-builtin-attrs.rs:12:18 | -LL | #[cfg_attr(all(), repr(C))] - | ^^^^ ambiguous name +LL | #[cfg_attr(true, repr(C))] + | ^^^^ ambiguous name | = note: ambiguous because of a name conflict with a builtin attribute = note: `repr` could refer to a built-in attribute diff --git a/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs b/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs index cb60c182a43c..b1da93de2a6e 100644 --- a/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs +++ b/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs @@ -4,6 +4,6 @@ use proc_macro::TokenStream; #[proc_macro_derive(Foo, attributes(foo))] pub fn derive(input: TokenStream) -> TokenStream { - assert!(!input.to_string().contains("#[cfg(any())]")); + assert!(!input.to_string().contains("#[cfg(false)]")); "".parse().unwrap() } diff --git a/tests/ui/proc-macro/cfg-eval.rs b/tests/ui/proc-macro/cfg-eval.rs index 9e9e46912588..60c94ad2a752 100644 --- a/tests/ui/proc-macro/cfg-eval.rs +++ b/tests/ui/proc-macro/cfg-eval.rs @@ -17,9 +17,9 @@ extern crate test_macros; struct S1 { #[cfg(false)] field_false: u8, - #[cfg(all(/*true*/))] + #[cfg(true)] #[cfg_attr(FALSE, unknown_attr)] - #[cfg_attr(all(/*true*/), allow())] //~ WARN unused attribute + #[cfg_attr(true, allow())] //~ WARN unused attribute field_true: u8, } @@ -29,9 +29,9 @@ struct S2 {} fn main() { // Subtle - we need a trailing comma after the '1' - otherwise, `#[cfg_eval]` will - // turn this into `(#[cfg(all())] 1)`, which is a parenthesized expression, not a tuple + // turn this into `(#[cfg(true)] 1)`, which is a parenthesized expression, not a tuple // expression. `#[cfg]` is not supported inside parenthesized expressions, so this will // produce an error when attribute collection runs. let _ = #[cfg_eval] #[print_attr] #[cfg_attr(not(FALSE), rustc_dummy)] - (#[cfg(false)] 0, #[cfg(all(/*true*/))] 1,); + (#[cfg(false)] 0, #[cfg(true)] 1,); } diff --git a/tests/ui/proc-macro/cfg-eval.stderr b/tests/ui/proc-macro/cfg-eval.stderr index 1429dbde7bfc..72c452c7a08a 100644 --- a/tests/ui/proc-macro/cfg-eval.stderr +++ b/tests/ui/proc-macro/cfg-eval.stderr @@ -1,8 +1,8 @@ warning: unused attribute --> $DIR/cfg-eval.rs:22:5 | -LL | #[cfg_attr(all(/*true*/), allow())] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute +LL | #[cfg_attr(true, allow())] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | = note: attribute `allow` with an empty list has no effect = note: requested on the command line with `-W unused-attributes` diff --git a/tests/ui/proc-macro/cfg-eval.stdout b/tests/ui/proc-macro/cfg-eval.stdout index 5d88297ad688..6493eee46547 100644 --- a/tests/ui/proc-macro/cfg-eval.stdout +++ b/tests/ui/proc-macro/cfg-eval.stdout @@ -1,5 +1,5 @@ -PRINT-ATTR INPUT (DISPLAY): struct S1 { #[cfg(all())] #[allow()] field_true: u8, } -PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): struct S1 { #[cfg(all())] #[allow()] field_true : u8, } +PRINT-ATTR INPUT (DISPLAY): struct S1 { #[cfg(true)] #[allow()] field_true: u8, } +PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): struct S1 { #[cfg(true)] #[allow()] field_true : u8, } PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -28,19 +28,14 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ delimiter: Parenthesis, stream: TokenStream [ Ident { - ident: "all", - span: $DIR/cfg-eval.rs:20:11: 20:14 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [], - span: $DIR/cfg-eval.rs:20:14: 20:24 (#0), + ident: "true", + span: $DIR/cfg-eval.rs:20:11: 20:15 (#0), }, ], - span: $DIR/cfg-eval.rs:20:10: 20:25 (#0), + span: $DIR/cfg-eval.rs:20:10: 20:16 (#0), }, ], - span: $DIR/cfg-eval.rs:20:6: 20:26 (#0), + span: $DIR/cfg-eval.rs:20:6: 20:17 (#0), }, Punct { ch: '#', @@ -52,15 +47,15 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "allow", - span: $DIR/cfg-eval.rs:22:31: 22:36 (#0), + span: $DIR/cfg-eval.rs:22:22: 22:27 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: $DIR/cfg-eval.rs:22:36: 22:38 (#0), + span: $DIR/cfg-eval.rs:22:27: 22:29 (#0), }, ], - span: $DIR/cfg-eval.rs:22:6: 22:40 (#0), + span: $DIR/cfg-eval.rs:22:6: 22:31 (#0), }, Ident { ident: "field_true", @@ -84,7 +79,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ span: $DIR/cfg-eval.rs:17:11: 24:2 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] (#[cfg(all())] 1,) +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] (#[cfg(true)] 1,) PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', @@ -120,32 +115,27 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ delimiter: Parenthesis, stream: TokenStream [ Ident { - ident: "all", - span: $DIR/cfg-eval.rs:36:29: 36:32 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [], - span: $DIR/cfg-eval.rs:36:32: 36:42 (#0), + ident: "true", + span: $DIR/cfg-eval.rs:36:29: 36:33 (#0), }, ], - span: $DIR/cfg-eval.rs:36:28: 36:43 (#0), + span: $DIR/cfg-eval.rs:36:28: 36:34 (#0), }, ], - span: $DIR/cfg-eval.rs:36:24: 36:44 (#0), + span: $DIR/cfg-eval.rs:36:24: 36:35 (#0), }, Literal { kind: Integer, symbol: "1", suffix: None, - span: $DIR/cfg-eval.rs:36:45: 36:46 (#0), + span: $DIR/cfg-eval.rs:36:36: 36:37 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/cfg-eval.rs:36:46: 36:47 (#0), + span: $DIR/cfg-eval.rs:36:37: 36:38 (#0), }, ], - span: $DIR/cfg-eval.rs:36:5: 36:48 (#0), + span: $DIR/cfg-eval.rs:36:5: 36:39 (#0), }, ] diff --git a/tests/ui/proc-macro/derive-attr-cfg.rs b/tests/ui/proc-macro/derive-attr-cfg.rs index 2f3516cabae9..21d3a93ffa6c 100644 --- a/tests/ui/proc-macro/derive-attr-cfg.rs +++ b/tests/ui/proc-macro/derive-attr-cfg.rs @@ -9,7 +9,7 @@ use derive_attr_cfg::Foo; #[derive(Foo)] #[foo] struct S { - #[cfg(any())] + #[cfg(false)] x: i32 } diff --git a/tests/ui/proc-macro/derive-b.rs b/tests/ui/proc-macro/derive-b.rs index 68d341478f18..c04152f629ca 100644 --- a/tests/ui/proc-macro/derive-b.rs +++ b/tests/ui/proc-macro/derive-b.rs @@ -4,7 +4,7 @@ extern crate derive_b_rpass as derive_b; #[derive(Debug, PartialEq, derive_b::B, Eq, Copy, Clone)] -#[cfg_attr(all(), B[arbitrary tokens])] +#[cfg_attr(true, B[arbitrary tokens])] struct B { #[C] a: u64 diff --git a/tests/ui/proc-macro/derive-helper-configured.rs b/tests/ui/proc-macro/derive-helper-configured.rs index b753e29b8bf3..b96ebdebaebb 100644 --- a/tests/ui/proc-macro/derive-helper-configured.rs +++ b/tests/ui/proc-macro/derive-helper-configured.rs @@ -7,9 +7,9 @@ extern crate test_macros; #[derive(Empty)] -#[cfg_attr(all(), empty_helper)] +#[cfg_attr(true, empty_helper)] struct S { - #[cfg_attr(all(), empty_helper)] + #[cfg_attr(true, empty_helper)] field: u8, } diff --git a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed index cfbf9ef38684..f6fbff175a99 100644 --- a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed +++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed @@ -3,7 +3,7 @@ //@ compile-flags: -Aunused use y::z; -#[cfg(all())] +#[cfg(true)] use y::Whatever; mod y { diff --git a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs index 98be104d8fde..73f263e19aa4 100644 --- a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs +++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs @@ -2,7 +2,7 @@ //@ run-rustfix //@ compile-flags: -Aunused -#[cfg(all())] +#[cfg(true)] use y::Whatever; mod y { diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed index a2f04daa4b85..c1adc90161a4 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed @@ -43,7 +43,7 @@ macro_rules! meta2 { macro_rules! with_cfg_attr { () => { - #[cfg_attr(all(), unsafe(link_section = ".custom_section"))] + #[cfg_attr(true, unsafe(link_section = ".custom_section"))] //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition pub extern "C" fn abc() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs index 88c9328fd9cd..9fdf37904634 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs @@ -43,7 +43,7 @@ macro_rules! meta2 { macro_rules! with_cfg_attr { () => { - #[cfg_attr(all(), link_section = ".custom_section")] + #[cfg_attr(true, link_section = ".custom_section")] //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition pub extern "C" fn abc() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr index 55df60c51d9c..279e61a9cb67 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr @@ -77,10 +77,10 @@ LL | #[unsafe($e = $l)] | +++++++ + error: unsafe attribute used without unsafe - --> $DIR/unsafe-attributes-fix.rs:46:27 + --> $DIR/unsafe-attributes-fix.rs:46:26 | -LL | #[cfg_attr(all(), link_section = ".custom_section")] - | ^^^^^^^^^^^^ usage of unsafe attribute +LL | #[cfg_attr(true, link_section = ".custom_section")] + | ^^^^^^^^^^^^ usage of unsafe attribute ... LL | with_cfg_attr!(); | ---------------- in this macro invocation @@ -90,8 +90,8 @@ LL | with_cfg_attr!(); = note: this error originates in the macro `with_cfg_attr` (in Nightly builds, run with -Z macro-backtrace for more info) help: wrap the attribute in `unsafe(...)` | -LL | #[cfg_attr(all(), unsafe(link_section = ".custom_section"))] - | +++++++ + +LL | #[cfg_attr(true, unsafe(link_section = ".custom_section"))] + | +++++++ + error: unsafe attribute used without unsafe --> $DIR/unsafe-attributes-fix.rs:67:3 diff --git a/tests/ui/static/static-align.rs b/tests/ui/static/static-align.rs index e2db7c01adf2..c1c9f79996ed 100644 --- a/tests/ui/static/static-align.rs +++ b/tests/ui/static/static-align.rs @@ -53,7 +53,7 @@ thread_local! { #[allow(unused_mut, reason = "test attribute handling")] #[cfg_attr(TRUE, cfg_attr(FOURTY_TWO = "42", - cfg_attr(all(), + cfg_attr(true, cfg_attr(any(true), cfg_attr(true, rustc_align_static(4096))))))] #[allow(unused_mut, reason = "test attribute handling")] diff --git a/tests/ui/structs/struct-field-cfg.rs b/tests/ui/structs/struct-field-cfg.rs index 42cab8ab916b..84f913927dab 100644 --- a/tests/ui/structs/struct-field-cfg.rs +++ b/tests/ui/structs/struct-field-cfg.rs @@ -3,16 +3,16 @@ struct Foo { } fn main() { - let foo = Foo { #[cfg(all())] present: () }; - let _ = Foo { #[cfg(any())] present: () }; + let foo = Foo { #[cfg(true)] present: () }; + let _ = Foo { #[cfg(false)] present: () }; //~^ ERROR missing field `present` in initializer of `Foo` - let _ = Foo { present: (), #[cfg(any())] absent: () }; - let _ = Foo { present: (), #[cfg(all())] absent: () }; + let _ = Foo { present: (), #[cfg(false)] absent: () }; + let _ = Foo { present: (), #[cfg(true)] absent: () }; //~^ ERROR struct `Foo` has no field named `absent` - let Foo { #[cfg(all())] present: () } = foo; - let Foo { #[cfg(any())] present: () } = foo; + let Foo { #[cfg(true)] present: () } = foo; + let Foo { #[cfg(false)] present: () } = foo; //~^ ERROR pattern does not mention field `present` - let Foo { present: (), #[cfg(any())] absent: () } = foo; - let Foo { present: (), #[cfg(all())] absent: () } = foo; + let Foo { present: (), #[cfg(false)] absent: () } = foo; + let Foo { present: (), #[cfg(true)] absent: () } = foo; //~^ ERROR struct `Foo` does not have a field named `absent` } diff --git a/tests/ui/structs/struct-field-cfg.stderr b/tests/ui/structs/struct-field-cfg.stderr index 2bca6f302db7..db280a632d63 100644 --- a/tests/ui/structs/struct-field-cfg.stderr +++ b/tests/ui/structs/struct-field-cfg.stderr @@ -1,44 +1,44 @@ error[E0063]: missing field `present` in initializer of `Foo` --> $DIR/struct-field-cfg.rs:7:13 | -LL | let _ = Foo { #[cfg(any())] present: () }; +LL | let _ = Foo { #[cfg(false)] present: () }; | ^^^ missing `present` error[E0560]: struct `Foo` has no field named `absent` - --> $DIR/struct-field-cfg.rs:10:46 + --> $DIR/struct-field-cfg.rs:10:45 | -LL | let _ = Foo { present: (), #[cfg(all())] absent: () }; - | ^^^^^^ `Foo` does not have this field +LL | let _ = Foo { present: (), #[cfg(true)] absent: () }; + | ^^^^^^ `Foo` does not have this field | = note: all struct fields are already assigned error[E0027]: pattern does not mention field `present` --> $DIR/struct-field-cfg.rs:13:9 | -LL | let Foo { #[cfg(any())] present: () } = foo; +LL | let Foo { #[cfg(false)] present: () } = foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `present` | help: include the missing field in the pattern | -LL - let Foo { #[cfg(any())] present: () } = foo; +LL - let Foo { #[cfg(false)] present: () } = foo; LL + let Foo { present } = foo; | help: if you don't care about this missing field, you can explicitly ignore it | -LL - let Foo { #[cfg(any())] present: () } = foo; +LL - let Foo { #[cfg(false)] present: () } = foo; LL + let Foo { present: _ } = foo; | help: or always ignore missing fields here | -LL - let Foo { #[cfg(any())] present: () } = foo; +LL - let Foo { #[cfg(false)] present: () } = foo; LL + let Foo { .. } = foo; | error[E0026]: struct `Foo` does not have a field named `absent` - --> $DIR/struct-field-cfg.rs:16:42 + --> $DIR/struct-field-cfg.rs:16:41 | -LL | let Foo { present: (), #[cfg(all())] absent: () } = foo; - | ^^^^^^ struct `Foo` does not have this field +LL | let Foo { present: (), #[cfg(true)] absent: () } = foo; + | ^^^^^^ struct `Foo` does not have this field error: aborting due to 4 previous errors diff --git a/tests/ui/test-attrs/issue-34932.rs b/tests/ui/test-attrs/issue-34932.rs index feb6556b60a1..f0cbdd07df84 100644 --- a/tests/ui/test-attrs/issue-34932.rs +++ b/tests/ui/test-attrs/issue-34932.rs @@ -1,6 +1,6 @@ //@ run-pass //@ compile-flags:--test -#![cfg(any())] // This test should be configured away +#![cfg(false)] // This test should be configured away #![feature(rustc_attrs)] // Test that this is allowed on stable/beta #![feature(iter_arith_traits)] // Test that this is not unused #![deny(unused_features)] diff --git a/tests/ui/typeck/issue-86721-return-expr-ice.rs b/tests/ui/typeck/issue-86721-return-expr-ice.rs index ea3a2f2fbfe6..ed36164aea60 100644 --- a/tests/ui/typeck/issue-86721-return-expr-ice.rs +++ b/tests/ui/typeck/issue-86721-return-expr-ice.rs @@ -1,7 +1,7 @@ // Regression test for the ICE described in #86721. //@ revisions: rev1 rev2 -#![cfg_attr(any(), rev1, rev2)] +#![cfg_attr(false, rev1, rev2)] #![crate_type = "lib"] #[cfg(any(rev1))] From 932c939c9fa2c72c313172be4ea18b1fb1afcc7a Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Wed, 10 Dec 2025 23:41:19 +0000 Subject: [PATCH 0574/3801] Remove uses of `cfg(any()/all())` --- src/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index a0bee4e18214..ac5b3c240785 100644 --- a/src/base.rs +++ b/src/base.rs @@ -167,7 +167,7 @@ pub(crate) fn compile_fn( context.clear(); context.func = codegened_func.func; - #[cfg(any())] // This is never true + #[cfg(false)] let _clif_guard = { use std::fmt::Write; From 51806323f9288e9cdab756a6b528823bcadcaa7a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 11 Dec 2025 01:35:28 +0100 Subject: [PATCH 0575/3801] Do not error if there are duplicated doc attributes --- compiler/rustc_attr_parsing/src/attributes/doc.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 2fe1b4ad174c..547f00d14041 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -358,10 +358,14 @@ impl DocParser { return; } - if self.attribute.$ident.is_some() { - cx.duplicate_key(path.span(), path.word_sym().unwrap()); - return; - } + // FIXME: It's errorring when the attribute is passed multiple times on the command + // line. + // The right fix for this would be to only check this rule if the attribute is + // not set on the command line but directly in the code. + // if self.attribute.$ident.is_some() { + // cx.duplicate_key(path.span(), path.word_sym().unwrap()); + // return; + // } self.attribute.$ident = Some(path.span()); }}; From c17b4a2ec78e9d726e471feba169572ec33ea230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Fischer?= Date: Thu, 18 Sep 2025 23:10:59 -0300 Subject: [PATCH 0576/3801] Clarify `strlen_on_c_strings` documentation --- clippy_lints/src/strlen_on_c_strings.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/strlen_on_c_strings.rs b/clippy_lints/src/strlen_on_c_strings.rs index 33856c750d7e..2e7affb8d07f 100644 --- a/clippy_lints/src/strlen_on_c_strings.rs +++ b/clippy_lints/src/strlen_on_c_strings.rs @@ -14,8 +14,8 @@ declare_clippy_lint! { /// and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead. /// /// ### Why is this bad? - /// This avoids calling an unsafe `libc` function. - /// Currently, it also avoids calculating the length. + /// libc::strlen is an unsafe function, which we don't need to call + /// if all we want to know is the length of the c-string. /// /// ### Example /// ```rust, ignore From f9b830c10239f5ff2c3a6b2b7f8183a4a855e9fe Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 10 Dec 2025 18:59:52 -0800 Subject: [PATCH 0577/3801] Add more basic shift examples --- library/core/src/num/uint_macros.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 89f330a063ac..9e69dec9547f 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2611,6 +2611,10 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("assert_eq!(1_", stringify!($SelfT), ".wrapping_shl(7), 128);")] + #[doc = concat!("assert_eq!(0b101_", stringify!($SelfT), ".wrapping_shl(0), 0b101);")] + #[doc = concat!("assert_eq!(0b101_", stringify!($SelfT), ".wrapping_shl(1), 0b1010);")] + #[doc = concat!("assert_eq!(0b101_", stringify!($SelfT), ".wrapping_shl(2), 0b10100);")] + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.wrapping_shl(2), ", stringify!($SelfT), "::MAX - 3);")] #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(", stringify!($BITS), "), 42);")] #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shl(1).wrapping_shl(", stringify!($BITS_MINUS_ONE), "), 0);")] #[doc = concat!("assert_eq!(1_", stringify!($SelfT), ".wrapping_shl(128), 1);")] @@ -2651,6 +2655,10 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("assert_eq!(128_", stringify!($SelfT), ".wrapping_shr(7), 1);")] + #[doc = concat!("assert_eq!(0b1010_", stringify!($SelfT), ".wrapping_shr(0), 0b1010);")] + #[doc = concat!("assert_eq!(0b1010_", stringify!($SelfT), ".wrapping_shr(1), 0b101);")] + #[doc = concat!("assert_eq!(0b1010_", stringify!($SelfT), ".wrapping_shr(2), 0b10);")] + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.wrapping_shr(1), ", stringify!($SignedT), "::MAX.cast_unsigned());")] #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(", stringify!($BITS), "), 42);")] #[doc = concat!("assert_eq!(42_", stringify!($SelfT), ".wrapping_shr(1).wrapping_shr(", stringify!($BITS_MINUS_ONE), "), 0);")] #[doc = concat!("assert_eq!(128_", stringify!($SelfT), ".wrapping_shr(128), 128);")] From 0b11cdfa417ff1bc19f6bfe880307188674b147f Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 11 Dec 2025 04:59:05 +0000 Subject: [PATCH 0578/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to f5209000832c9d3bc29c91f4daef4ca9f28dc797. --- 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 b6a1415f1834..2e81ccbba184 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -36b2369c91d32c2659887ed6fe3d570640f44fd2 +f5209000832c9d3bc29c91f4daef4ca9f28dc797 From 254e0cb3bcb48d07914ddb5f94449278f0ef0382 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 20 Nov 2025 19:06:00 +0100 Subject: [PATCH 0579/3801] feat(unnecessary_fold): lint on `fold`s with `Add::add`/`Mul::mul` --- clippy_lints/src/methods/unnecessary_fold.rs | 179 +++++++++++-------- tests/ui/unnecessary_fold.fixed | 85 +++++++++ tests/ui/unnecessary_fold.rs | 85 +++++++++ tests/ui/unnecessary_fold.stderr | 130 ++++++++++++-- 4 files changed, 384 insertions(+), 95 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index bd471e0b18e3..9dae6fbb48dd 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -1,44 +1,52 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes}; +use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath, MaybeTypeckRes}; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{peel_blocks, strip_pat_refs}; +use clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_blocks, strip_pat_refs}; use rustc_ast::ast; use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::PatKind; +use rustc_hir::def::{DefKind, Res}; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_span::{Span, sym}; +use rustc_middle::ty::{self, Ty}; +use rustc_span::{Span, Symbol, sym}; use super::UNNECESSARY_FOLD; /// Do we need to suggest turbofish when suggesting a replacement method? /// Changing `fold` to `sum` needs it sometimes when the return type can't be /// inferred. This checks for some common cases where it can be safely omitted -fn needs_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { - let parent = cx.tcx.parent_hir_node(expr.hir_id); - - // some common cases where turbofish isn't needed: - // - assigned to a local variable with a type annotation - if let hir::Node::LetStmt(local) = parent - && local.ty.is_some() +fn needs_turbofish<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) -> bool { + let use_cx = expr_use_ctxt(cx, expr); + if use_cx.same_ctxt + && let use_node = use_cx.use_node(cx) + && let Some(ty) = use_node.defined_ty(cx) { - return false; - } + // some common cases where turbofish isn't needed: + match (use_node, ty) { + // - assigned to a local variable with a type annotation + (ExprUseNode::LetStmt(_), _) => return false, - // - part of a function call argument, can be inferred from the function signature (provided that - // the parameter is not a generic type parameter) - if let hir::Node::Expr(parent_expr) = parent - && let hir::ExprKind::Call(recv, args) = parent_expr.kind - && let hir::ExprKind::Path(ref qpath) = recv.kind - && let Some(fn_def_id) = cx.qpath_res(qpath, recv.hir_id).opt_def_id() - && let fn_sig = cx.tcx.fn_sig(fn_def_id).skip_binder().skip_binder() - && let Some(arg_pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id) - && let Some(ty) = fn_sig.inputs().get(arg_pos) - && !matches!(ty.kind(), ty::Param(_)) - { - return false; + // - part of a function call argument, can be inferred from the function signature (provided that the + // parameter is not a generic type parameter) + (ExprUseNode::FnArg(..), DefinedTy::Mir { ty: arg_ty, .. }) + if !matches!(arg_ty.skip_binder().kind(), ty::Param(_)) => + { + return false; + }, + + // - the final expression in the body of a function with a simple return type + (ExprUseNode::Return(_), DefinedTy::Mir { ty: fn_return_ty, .. }) + if !fn_return_ty + .skip_binder() + .walk() + .any(|generic| generic.as_type().is_some_and(Ty::is_impl_trait)) => + { + return false; + }, + _ => {}, + } } // if it's neither of those, stay on the safe side and suggest turbofish, @@ -60,7 +68,7 @@ fn check_fold_with_op( fold_span: Span, op: hir::BinOpKind, replacement: Replacement, -) { +) -> bool { if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = acc.kind // Extract the body of the closure passed to fold && let closure_body = cx.tcx.hir_body(body) @@ -93,7 +101,7 @@ fn check_fold_with_op( r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), ) } else { - format!("{method}{turbofish}()", method = replacement.method_name,) + format!("{method}{turbofish}()", method = replacement.method_name) }; span_lint_and_sugg( @@ -105,12 +113,47 @@ fn check_fold_with_op( sugg, applicability, ); + return true; + } + false +} + +fn check_fold_with_method( + cx: &LateContext<'_>, + expr: &hir::Expr<'_>, + acc: &hir::Expr<'_>, + fold_span: Span, + method: Symbol, + replacement: Replacement, +) { + // Extract the name of the function passed to `fold` + if let Res::Def(DefKind::AssocFn, fn_did) = acc.res_if_named(cx, method) + // Check if the function belongs to the operator + && cx.tcx.is_diagnostic_item(method, fn_did) + { + let applicability = Applicability::MachineApplicable; + + let turbofish = if replacement.has_generic_return { + format!("::<{}>", cx.typeck_results().expr_ty(expr)) + } else { + String::new() + }; + + span_lint_and_sugg( + cx, + UNNECESSARY_FOLD, + fold_span.with_hi(expr.span.hi()), + "this `.fold` can be written more succinctly using another method", + "try", + format!("{method}{turbofish}()", method = replacement.method_name), + applicability, + ); } } -pub(super) fn check( - cx: &LateContext<'_>, - expr: &hir::Expr<'_>, +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &hir::Expr<'tcx>, init: &hir::Expr<'_>, acc: &hir::Expr<'_>, fold_span: Span, @@ -124,60 +167,40 @@ pub(super) fn check( if let hir::ExprKind::Lit(lit) = init.kind { match lit.node { ast::LitKind::Bool(false) => { - check_fold_with_op( - cx, - expr, - acc, - fold_span, - hir::BinOpKind::Or, - Replacement { - method_name: "any", - has_args: true, - has_generic_return: false, - }, - ); + let replacement = Replacement { + method_name: "any", + has_args: true, + has_generic_return: false, + }; + check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Or, replacement); }, ast::LitKind::Bool(true) => { - check_fold_with_op( - cx, - expr, - acc, - fold_span, - hir::BinOpKind::And, - Replacement { - method_name: "all", - has_args: true, - has_generic_return: false, - }, - ); + let replacement = Replacement { + method_name: "all", + has_args: true, + has_generic_return: false, + }; + check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, replacement); }, ast::LitKind::Int(Pu128(0), _) => { - check_fold_with_op( - cx, - expr, - acc, - fold_span, - hir::BinOpKind::Add, - Replacement { - method_name: "sum", - has_args: false, - has_generic_return: needs_turbofish(cx, expr), - }, - ); + let replacement = Replacement { + method_name: "sum", + has_args: false, + has_generic_return: needs_turbofish(cx, expr), + }; + if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Add, replacement) { + check_fold_with_method(cx, expr, acc, fold_span, sym::add, replacement); + } }, ast::LitKind::Int(Pu128(1), _) => { - check_fold_with_op( - cx, - expr, - acc, - fold_span, - hir::BinOpKind::Mul, - Replacement { - method_name: "product", - has_args: false, - has_generic_return: needs_turbofish(cx, expr), - }, - ); + let replacement = Replacement { + method_name: "product", + has_args: false, + has_generic_return: needs_turbofish(cx, expr), + }; + if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, replacement) { + check_fold_with_method(cx, expr, acc, fold_span, sym::mul, replacement); + } }, _ => (), } diff --git a/tests/ui/unnecessary_fold.fixed b/tests/ui/unnecessary_fold.fixed index 1c331be75094..c3eeafbc39cd 100644 --- a/tests/ui/unnecessary_fold.fixed +++ b/tests/ui/unnecessary_fold.fixed @@ -6,21 +6,35 @@ fn is_any(acc: bool, x: usize) -> bool { /// Calls which should trigger the `UNNECESSARY_FOLD` lint fn unnecessary_fold() { + use std::ops::{Add, Mul}; + // Can be replaced by .any let _ = (0..3).any(|x| x > 2); //~^ unnecessary_fold + // Can be replaced by .any (checking suggestion) let _ = (0..3).fold(false, is_any); //~^ redundant_closure + // Can be replaced by .all let _ = (0..3).all(|x| x > 2); //~^ unnecessary_fold + // Can be replaced by .sum let _: i32 = (0..3).sum(); //~^ unnecessary_fold + let _: i32 = (0..3).sum(); + //~^ unnecessary_fold + let _: i32 = (0..3).sum(); + //~^ unnecessary_fold + // Can be replaced by .product let _: i32 = (0..3).product(); //~^ unnecessary_fold + let _: i32 = (0..3).product(); + //~^ unnecessary_fold + let _: i32 = (0..3).product(); + //~^ unnecessary_fold } /// Should trigger the `UNNECESSARY_FOLD` lint, with an error span including exactly `.fold(...)` @@ -37,6 +51,43 @@ fn unnecessary_fold_should_ignore() { let _ = (0..3).fold(0, |acc, x| acc * x); let _ = (0..3).fold(0, |acc, x| 1 + acc + x); + struct Adder; + impl Adder { + fn add(lhs: i32, rhs: i32) -> i32 { + unimplemented!() + } + fn mul(lhs: i32, rhs: i32) -> i32 { + unimplemented!() + } + } + // `add`/`mul` are inherent methods + let _: i32 = (0..3).fold(0, Adder::add); + let _: i32 = (0..3).fold(1, Adder::mul); + + trait FakeAdd { + type Output; + fn add(self, other: Rhs) -> Self::Output; + } + impl FakeAdd for i32 { + type Output = Self; + fn add(self, other: i32) -> Self::Output { + self + other + } + } + trait FakeMul { + type Output; + fn mul(self, other: Rhs) -> Self::Output; + } + impl FakeMul for i32 { + type Output = Self; + fn mul(self, other: i32) -> Self::Output { + self * other + } + } + // `add`/`mul` come from an unrelated trait + let _: i32 = (0..3).fold(0, FakeAdd::add); + let _: i32 = (0..3).fold(1, FakeMul::mul); + // We only match against an accumulator on the left // hand side. We could lint for .sum and .product when // it's on the right, but don't for now (and this wouldn't @@ -63,6 +114,7 @@ fn unnecessary_fold_over_multiple_lines() { fn issue10000() { use std::collections::HashMap; use std::hash::BuildHasher; + use std::ops::{Add, Mul}; fn anything(_: T) {} fn num(_: i32) {} @@ -74,23 +126,56 @@ fn issue10000() { // more cases: let _ = map.values().sum::(); //~^ unnecessary_fold + let _ = map.values().sum::(); + //~^ unnecessary_fold let _ = map.values().product::(); //~^ unnecessary_fold + let _ = map.values().product::(); + //~^ unnecessary_fold + let _: i32 = map.values().sum(); + //~^ unnecessary_fold let _: i32 = map.values().sum(); //~^ unnecessary_fold let _: i32 = map.values().product(); //~^ unnecessary_fold + let _: i32 = map.values().product(); + //~^ unnecessary_fold + anything(map.values().sum::()); + //~^ unnecessary_fold anything(map.values().sum::()); //~^ unnecessary_fold anything(map.values().product::()); //~^ unnecessary_fold + anything(map.values().product::()); + //~^ unnecessary_fold num(map.values().sum()); //~^ unnecessary_fold + num(map.values().sum()); + //~^ unnecessary_fold + num(map.values().product()); + //~^ unnecessary_fold num(map.values().product()); //~^ unnecessary_fold } smoketest_map(HashMap::new()); + + fn add_turbofish_not_necessary() -> i32 { + (0..3).sum() + //~^ unnecessary_fold + } + fn mul_turbofish_not_necessary() -> i32 { + (0..3).product() + //~^ unnecessary_fold + } + fn add_turbofish_necessary() -> impl Add { + (0..3).sum::() + //~^ unnecessary_fold + } + fn mul_turbofish_necessary() -> impl Mul { + (0..3).product::() + //~^ unnecessary_fold + } } fn main() {} diff --git a/tests/ui/unnecessary_fold.rs b/tests/ui/unnecessary_fold.rs index e2050e37e3b1..6ab41a942625 100644 --- a/tests/ui/unnecessary_fold.rs +++ b/tests/ui/unnecessary_fold.rs @@ -6,21 +6,35 @@ fn is_any(acc: bool, x: usize) -> bool { /// Calls which should trigger the `UNNECESSARY_FOLD` lint fn unnecessary_fold() { + use std::ops::{Add, Mul}; + // Can be replaced by .any let _ = (0..3).fold(false, |acc, x| acc || x > 2); //~^ unnecessary_fold + // Can be replaced by .any (checking suggestion) let _ = (0..3).fold(false, |acc, x| is_any(acc, x)); //~^ redundant_closure + // Can be replaced by .all let _ = (0..3).fold(true, |acc, x| acc && x > 2); //~^ unnecessary_fold + // Can be replaced by .sum let _: i32 = (0..3).fold(0, |acc, x| acc + x); //~^ unnecessary_fold + let _: i32 = (0..3).fold(0, Add::add); + //~^ unnecessary_fold + let _: i32 = (0..3).fold(0, i32::add); + //~^ unnecessary_fold + // Can be replaced by .product let _: i32 = (0..3).fold(1, |acc, x| acc * x); //~^ unnecessary_fold + let _: i32 = (0..3).fold(1, Mul::mul); + //~^ unnecessary_fold + let _: i32 = (0..3).fold(1, i32::mul); + //~^ unnecessary_fold } /// Should trigger the `UNNECESSARY_FOLD` lint, with an error span including exactly `.fold(...)` @@ -37,6 +51,43 @@ fn unnecessary_fold_should_ignore() { let _ = (0..3).fold(0, |acc, x| acc * x); let _ = (0..3).fold(0, |acc, x| 1 + acc + x); + struct Adder; + impl Adder { + fn add(lhs: i32, rhs: i32) -> i32 { + unimplemented!() + } + fn mul(lhs: i32, rhs: i32) -> i32 { + unimplemented!() + } + } + // `add`/`mul` are inherent methods + let _: i32 = (0..3).fold(0, Adder::add); + let _: i32 = (0..3).fold(1, Adder::mul); + + trait FakeAdd { + type Output; + fn add(self, other: Rhs) -> Self::Output; + } + impl FakeAdd for i32 { + type Output = Self; + fn add(self, other: i32) -> Self::Output { + self + other + } + } + trait FakeMul { + type Output; + fn mul(self, other: Rhs) -> Self::Output; + } + impl FakeMul for i32 { + type Output = Self; + fn mul(self, other: i32) -> Self::Output { + self * other + } + } + // `add`/`mul` come from an unrelated trait + let _: i32 = (0..3).fold(0, FakeAdd::add); + let _: i32 = (0..3).fold(1, FakeMul::mul); + // We only match against an accumulator on the left // hand side. We could lint for .sum and .product when // it's on the right, but don't for now (and this wouldn't @@ -63,6 +114,7 @@ fn unnecessary_fold_over_multiple_lines() { fn issue10000() { use std::collections::HashMap; use std::hash::BuildHasher; + use std::ops::{Add, Mul}; fn anything(_: T) {} fn num(_: i32) {} @@ -74,23 +126,56 @@ fn issue10000() { // more cases: let _ = map.values().fold(0, |x, y| x + y); //~^ unnecessary_fold + let _ = map.values().fold(0, Add::add); + //~^ unnecessary_fold let _ = map.values().fold(1, |x, y| x * y); //~^ unnecessary_fold + let _ = map.values().fold(1, Mul::mul); + //~^ unnecessary_fold let _: i32 = map.values().fold(0, |x, y| x + y); //~^ unnecessary_fold + let _: i32 = map.values().fold(0, Add::add); + //~^ unnecessary_fold let _: i32 = map.values().fold(1, |x, y| x * y); //~^ unnecessary_fold + let _: i32 = map.values().fold(1, Mul::mul); + //~^ unnecessary_fold anything(map.values().fold(0, |x, y| x + y)); //~^ unnecessary_fold + anything(map.values().fold(0, Add::add)); + //~^ unnecessary_fold anything(map.values().fold(1, |x, y| x * y)); //~^ unnecessary_fold + anything(map.values().fold(1, Mul::mul)); + //~^ unnecessary_fold num(map.values().fold(0, |x, y| x + y)); //~^ unnecessary_fold + num(map.values().fold(0, Add::add)); + //~^ unnecessary_fold num(map.values().fold(1, |x, y| x * y)); //~^ unnecessary_fold + num(map.values().fold(1, Mul::mul)); + //~^ unnecessary_fold } smoketest_map(HashMap::new()); + + fn add_turbofish_not_necessary() -> i32 { + (0..3).fold(0, |acc, x| acc + x) + //~^ unnecessary_fold + } + fn mul_turbofish_not_necessary() -> i32 { + (0..3).fold(1, |acc, x| acc * x) + //~^ unnecessary_fold + } + fn add_turbofish_necessary() -> impl Add { + (0..3).fold(0, |acc, x| acc + x) + //~^ unnecessary_fold + } + fn mul_turbofish_necessary() -> impl Mul { + (0..3).fold(1, |acc, x| acc * x) + //~^ unnecessary_fold + } } fn main() {} diff --git a/tests/ui/unnecessary_fold.stderr b/tests/ui/unnecessary_fold.stderr index d82b1f39b48b..bb8aa7e18d34 100644 --- a/tests/ui/unnecessary_fold.stderr +++ b/tests/ui/unnecessary_fold.stderr @@ -1,5 +1,5 @@ error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:10:20 + --> tests/ui/unnecessary_fold.rs:12:20 | LL | let _ = (0..3).fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` @@ -8,7 +8,7 @@ LL | let _ = (0..3).fold(false, |acc, x| acc || x > 2); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fold)]` error: redundant closure - --> tests/ui/unnecessary_fold.rs:13:32 + --> tests/ui/unnecessary_fold.rs:16:32 | LL | let _ = (0..3).fold(false, |acc, x| is_any(acc, x)); | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `is_any` @@ -17,88 +17,184 @@ LL | let _ = (0..3).fold(false, |acc, x| is_any(acc, x)); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:16:20 + --> tests/ui/unnecessary_fold.rs:20:20 | LL | let _ = (0..3).fold(true, |acc, x| acc && x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `all(|x| x > 2)` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:19:25 + --> tests/ui/unnecessary_fold.rs:24:25 | LL | let _: i32 = (0..3).fold(0, |acc, x| acc + x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:22:25 + --> tests/ui/unnecessary_fold.rs:26:25 + | +LL | let _: i32 = (0..3).fold(0, Add::add); + | ^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:28:25 + | +LL | let _: i32 = (0..3).fold(0, i32::add); + | ^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:32:25 | LL | let _: i32 = (0..3).fold(1, |acc, x| acc * x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:28:41 + --> tests/ui/unnecessary_fold.rs:34:25 + | +LL | let _: i32 = (0..3).fold(1, Mul::mul); + | ^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:36:25 + | +LL | let _: i32 = (0..3).fold(1, i32::mul); + | ^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:42:41 | LL | let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:59:10 + --> tests/ui/unnecessary_fold.rs:110:10 | LL | .fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:71:33 + --> tests/ui/unnecessary_fold.rs:123:33 | LL | assert_eq!(map.values().fold(0, |x, y| x + y), 0); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:75:30 + --> tests/ui/unnecessary_fold.rs:127:30 | LL | let _ = map.values().fold(0, |x, y| x + y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:77:30 + --> tests/ui/unnecessary_fold.rs:129:30 + | +LL | let _ = map.values().fold(0, Add::add); + | ^^^^^^^^^^^^^^^^^ help: try: `sum::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:131:30 | LL | let _ = map.values().fold(1, |x, y| x * y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:79:35 + --> tests/ui/unnecessary_fold.rs:133:30 + | +LL | let _ = map.values().fold(1, Mul::mul); + | ^^^^^^^^^^^^^^^^^ help: try: `product::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:135:35 | LL | let _: i32 = map.values().fold(0, |x, y| x + y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:81:35 + --> tests/ui/unnecessary_fold.rs:137:35 + | +LL | let _: i32 = map.values().fold(0, Add::add); + | ^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:139:35 | LL | let _: i32 = map.values().fold(1, |x, y| x * y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:83:31 + --> tests/ui/unnecessary_fold.rs:141:35 + | +LL | let _: i32 = map.values().fold(1, Mul::mul); + | ^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:143:31 | LL | anything(map.values().fold(0, |x, y| x + y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:85:31 + --> tests/ui/unnecessary_fold.rs:145:31 + | +LL | anything(map.values().fold(0, Add::add)); + | ^^^^^^^^^^^^^^^^^ help: try: `sum::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:147:31 | LL | anything(map.values().fold(1, |x, y| x * y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:87:26 + --> tests/ui/unnecessary_fold.rs:149:31 + | +LL | anything(map.values().fold(1, Mul::mul)); + | ^^^^^^^^^^^^^^^^^ help: try: `product::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:151:26 | LL | num(map.values().fold(0, |x, y| x + y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:89:26 + --> tests/ui/unnecessary_fold.rs:153:26 + | +LL | num(map.values().fold(0, Add::add)); + | ^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:155:26 | LL | num(map.values().fold(1, |x, y| x * y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` -error: aborting due to 16 previous errors +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:157:26 + | +LL | num(map.values().fold(1, Mul::mul)); + | ^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:164:16 + | +LL | (0..3).fold(0, |acc, x| acc + x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:168:16 + | +LL | (0..3).fold(1, |acc, x| acc * x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:172:16 + | +LL | (0..3).fold(0, |acc, x| acc + x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:176:16 + | +LL | (0..3).fold(1, |acc, x| acc * x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` + +error: aborting due to 32 previous errors From 1b790cdcac1d0f156f312b59b318ae42eb84797c Mon Sep 17 00:00:00 2001 From: Andrew Zhogin Date: Thu, 11 Dec 2025 16:46:32 +0700 Subject: [PATCH 0580/3801] Weak for Arc pointer is marked as DynSend/DynSync --- compiler/rustc_data_structures/src/marker.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 0ef3bb319ff8..72d5f004194a 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -75,6 +75,7 @@ impl_dyn_send!( [std::sync::Mutex where T: ?Sized+ DynSend] [std::sync::mpsc::Sender where T: DynSend] [std::sync::Arc where T: ?Sized + DynSync + DynSend] + [std::sync::Weak where T: ?Sized + DynSync + DynSend] [std::sync::LazyLock where T: DynSend, F: DynSend] [std::collections::HashSet where K: DynSend, S: DynSend] [std::collections::HashMap where K: DynSend, V: DynSend, S: DynSend] @@ -157,6 +158,7 @@ impl_dyn_sync!( [std::sync::OnceLock where T: DynSend + DynSync] [std::sync::Mutex where T: ?Sized + DynSend] [std::sync::Arc where T: ?Sized + DynSync + DynSend] + [std::sync::Weak where T: ?Sized + DynSync + DynSend] [std::sync::LazyLock where T: DynSend + DynSync, F: DynSend] [std::collections::HashSet where K: DynSync, S: DynSync] [std::collections::HashMap where K: DynSync, V: DynSync, S: DynSync] From 2a224f3e793da8da1c470dc58959fd81a34796e8 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Sat, 4 Oct 2025 12:33:55 +0200 Subject: [PATCH 0581/3801] clean-up --- clippy_lints/src/format_push_string.rs | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/format_push_string.rs b/clippy_lints/src/format_push_string.rs index a23ba9ab837a..069f8f7d75ab 100644 --- a/clippy_lints/src/format_push_string.rs +++ b/clippy_lints/src/format_push_string.rs @@ -1,5 +1,4 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::higher; use clippy_utils::res::MaybeDef; use rustc_hir::{AssignOpKind, Expr, ExprKind, LangItem, MatchSource}; use rustc_lint::{LateContext, LateLintPass}; @@ -49,22 +48,15 @@ fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { let e = e.peel_blocks().peel_borrows(); - if e.span.from_expansion() - && let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id - { - cx.tcx.get_diagnostic_name(macro_def_id) == Some(sym::format_macro) - } else if let Some(higher::If { then, r#else, .. }) = higher::If::hir(e) { - is_format(cx, then) || r#else.is_some_and(|e| is_format(cx, e)) - } else { - match higher::IfLetOrMatch::parse(cx, e) { - Some(higher::IfLetOrMatch::Match(_, arms, MatchSource::Normal)) => { - arms.iter().any(|arm| is_format(cx, arm.body)) - }, - Some(higher::IfLetOrMatch::IfLet(_, _, then, r#else, _)) => { - is_format(cx, then) || r#else.is_some_and(|e| is_format(cx, e)) - }, - _ => false, - } + match e.kind { + _ if e.span.from_expansion() + && let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id => + { + cx.tcx.is_diagnostic_item(sym::format_macro, macro_def_id) + }, + ExprKind::Match(_, arms, MatchSource::Normal) => arms.iter().any(|arm| is_format(cx, arm.body)), + ExprKind::If(_, then, els) => is_format(cx, then) || els.is_some_and(|e| is_format(cx, e)), + _ => false, } } From 34551be259d4b14af3103d0b61d2ef9d310b9f36 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Sat, 4 Oct 2025 12:05:56 +0200 Subject: [PATCH 0582/3801] feat(format_push_string): add a suggestion --- clippy_lints/src/format_push_string.rs | 201 +++++++++++---- clippy_lints/src/lib.rs | 5 +- tests/ui/format_push_string.fixed | 132 ++++++++++ tests/ui/format_push_string.rs | 140 +++++++++-- tests/ui/format_push_string.stderr | 205 ++++++++++++--- tests/ui/format_push_string_no_core.rs | 15 ++ tests/ui/format_push_string_no_std.fixed | 15 ++ tests/ui/format_push_string_no_std.rs | 15 ++ tests/ui/format_push_string_no_std.stderr | 17 ++ .../ui/format_push_string_no_std_unfixable.rs | 13 + ...format_push_string_no_std_unfixable.stderr | 17 ++ tests/ui/format_push_string_unfixable.rs | 144 +++++++++++ tests/ui/format_push_string_unfixable.stderr | 233 ++++++++++++++++++ 13 files changed, 1044 insertions(+), 108 deletions(-) create mode 100644 tests/ui/format_push_string.fixed create mode 100644 tests/ui/format_push_string_no_core.rs create mode 100644 tests/ui/format_push_string_no_std.fixed create mode 100644 tests/ui/format_push_string_no_std.rs create mode 100644 tests/ui/format_push_string_no_std.stderr create mode 100644 tests/ui/format_push_string_no_std_unfixable.rs create mode 100644 tests/ui/format_push_string_no_std_unfixable.stderr create mode 100644 tests/ui/format_push_string_unfixable.rs create mode 100644 tests/ui/format_push_string_unfixable.stderr diff --git a/clippy_lints/src/format_push_string.rs b/clippy_lints/src/format_push_string.rs index 069f8f7d75ab..fea55f91bce7 100644 --- a/clippy_lints/src/format_push_string.rs +++ b/clippy_lints/src/format_push_string.rs @@ -1,9 +1,13 @@ use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span, root_macro_call_first_node}; use clippy_utils::res::MaybeDef; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; +use clippy_utils::std_or_core; +use rustc_errors::Applicability; use rustc_hir::{AssignOpKind, Expr, ExprKind, LangItem, MatchSource}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::declare_lint_pass; -use rustc_span::sym; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_session::impl_lint_pass; +use rustc_span::{Span, sym}; declare_clippy_lint! { /// ### What it does @@ -37,7 +41,152 @@ declare_clippy_lint! { pedantic, "`format!(..)` appended to existing `String`" } -declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]); +impl_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]); + +pub(crate) struct FormatPushString { + format_args: FormatArgsStorage, +} + +enum FormatSearchResults { + /// The expression is itself a `format!()` invocation -- we can make a suggestion to replace it + Direct(Span), + /// The expression contains zero or more `format!()`s, e.g.: + /// ```ignore + /// if true { + /// format!("hello") + /// } else { + /// format!("world") + /// } + /// ``` + /// or + /// ```ignore + /// match true { + /// true => format!("hello"), + /// false => format!("world"), + /// } + Nested(Vec), +} + +impl FormatPushString { + pub(crate) fn new(format_args: FormatArgsStorage) -> Self { + Self { format_args } + } + + fn find_formats<'tcx>(&self, cx: &LateContext<'_>, e: &'tcx Expr<'tcx>) -> FormatSearchResults { + let expr_as_format = |e| { + if let Some(macro_call) = root_macro_call_first_node(cx, e) + && cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) + && let Some(format_args) = self.format_args.get(cx, e, macro_call.expn) + { + Some(format_args_inputs_span(format_args)) + } else { + None + } + }; + + let e = e.peel_blocks().peel_borrows(); + if let Some(fmt) = expr_as_format(e) { + FormatSearchResults::Direct(fmt) + } else { + fn inner<'tcx>( + e: &'tcx Expr<'tcx>, + expr_as_format: &impl Fn(&'tcx Expr<'tcx>) -> Option, + out: &mut Vec, + ) { + let e = e.peel_blocks().peel_borrows(); + + match e.kind { + _ if expr_as_format(e).is_some() => out.push(e.span), + ExprKind::Match(_, arms, MatchSource::Normal) => { + for arm in arms { + inner(arm.body, expr_as_format, out); + } + }, + ExprKind::If(_, then, els) => { + inner(then, expr_as_format, out); + if let Some(els) = els { + inner(els, expr_as_format, out); + } + }, + _ => {}, + } + } + let mut spans = vec![]; + inner(e, &expr_as_format, &mut spans); + FormatSearchResults::Nested(spans) + } + } +} + +impl<'tcx> LateLintPass<'tcx> for FormatPushString { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + let (recv, arg) = match expr.kind { + ExprKind::MethodCall(_, recv, [arg], _) => { + if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) + && cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id) + { + (recv, arg) + } else { + return; + } + }, + ExprKind::AssignOp(op, recv, arg) if op.node == AssignOpKind::AddAssign && is_string(cx, recv) => { + (recv, arg) + }, + _ => return, + }; + let Some(std_or_core) = std_or_core(cx) else { + // not even `core` is available, so can't suggest `write!` + return; + }; + match self.find_formats(cx, arg) { + FormatSearchResults::Direct(format_args) => { + span_lint_and_then( + cx, + FORMAT_PUSH_STRING, + expr.span, + "`format!(..)` appended to existing `String`", + |diag| { + let mut app = Applicability::MaybeIncorrect; + let msg = "consider using `write!` to avoid the extra allocation"; + + let sugg = format!( + "let _ = write!({recv}, {format_args})", + recv = snippet_with_context(cx.sess(), recv.span, expr.span.ctxt(), "_", &mut app).0, + format_args = snippet_with_applicability(cx.sess(), format_args, "..", &mut app), + ); + diag.span_suggestion_verbose(expr.span, msg, sugg, app); + + // TODO: omit the note if the `Write` trait is imported at point + // Tip: `TyCtxt::in_scope_traits` isn't it -- it returns a non-empty list only when called on + // the `HirId` of a `ExprKind::MethodCall` that is a call of a _trait_ method. + diag.note(format!("you may need to import the `{std_or_core}::fmt::Write` trait")); + }, + ); + }, + FormatSearchResults::Nested(spans) => { + if !spans.is_empty() { + span_lint_and_then( + cx, + FORMAT_PUSH_STRING, + expr.span, + "`format!(..)` appended to existing `String`", + |diag| { + diag.help("consider using `write!` to avoid the extra allocation"); + diag.span_labels(spans, "`format!` used here"); + + // TODO: omit the note if the `Write` trait is imported at point + // Tip: `TyCtxt::in_scope_traits` isn't it -- it returns a non-empty list only when called + // on the `HirId` of a `ExprKind::MethodCall` that is a call of + // a _trait_ method. + diag.note(format!("you may need to import the `{std_or_core}::fmt::Write` trait")); + }, + ); + } + }, + } + } +} fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { cx.typeck_results() @@ -45,47 +194,3 @@ fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { .peel_refs() .is_lang_item(cx, LangItem::String) } -fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - let e = e.peel_blocks().peel_borrows(); - - match e.kind { - _ if e.span.from_expansion() - && let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id => - { - cx.tcx.is_diagnostic_item(sym::format_macro, macro_def_id) - }, - ExprKind::Match(_, arms, MatchSource::Normal) => arms.iter().any(|arm| is_format(cx, arm.body)), - ExprKind::If(_, then, els) => is_format(cx, then) || els.is_some_and(|e| is_format(cx, e)), - _ => false, - } -} - -impl<'tcx> LateLintPass<'tcx> for FormatPushString { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - let arg = match expr.kind { - ExprKind::MethodCall(_, _, [arg], _) => { - if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) - && cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id) - { - arg - } else { - return; - } - }, - ExprKind::AssignOp(op, left, arg) if op.node == AssignOpKind::AddAssign && is_string(cx, left) => arg, - _ => return, - }; - if is_format(cx, arg) { - #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] - span_lint_and_then( - cx, - FORMAT_PUSH_STRING, - expr.span, - "`format!(..)` appended to existing `String`", - |diag| { - diag.help("consider using `write!` to avoid the extra allocation"); - }, - ); - } - } -} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 5b39d8844797..3b18f51c3323 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -739,7 +739,10 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(move |_| Box::new(cargo::Cargo::new(conf))), Box::new(|_| Box::new(empty_with_brackets::EmptyWithBrackets::default())), Box::new(|_| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings)), - Box::new(|_| Box::new(format_push_string::FormatPushString)), + { + let format_args = format_args_storage.clone(); + Box::new(move |_| Box::new(format_push_string::FormatPushString::new(format_args.clone()))) + }, Box::new(move |_| Box::new(large_include_file::LargeIncludeFile::new(conf))), Box::new(|_| Box::new(strings::TrimSplitWhitespace)), Box::new(|_| Box::new(rc_clone_in_vec_init::RcCloneInVecInit)), diff --git a/tests/ui/format_push_string.fixed b/tests/ui/format_push_string.fixed new file mode 100644 index 000000000000..f6396d9982a3 --- /dev/null +++ b/tests/ui/format_push_string.fixed @@ -0,0 +1,132 @@ +#![warn(clippy::format_push_string)] + +fn main() { + use std::fmt::Write; + + let mut string = String::new(); + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + + let _ = write!(string, "{:?}", 5678); + //~^ format_push_string + + macro_rules! string { + () => { + String::new() + }; + } + let _ = write!(string!(), "{:?}", 5678); + //~^ format_push_string +} + +// TODO: recognize the already imported `fmt::Write`, and don't add a note suggesting to import it +// again +mod import_write { + mod push_str { + mod imported_anonymously { + fn main(string: &mut String) { + use std::fmt::Write as _; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported { + fn main(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_anonymously_in_module { + use std::fmt::Write as _; + + fn main(string: &mut String) { + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_in_module { + use std::fmt::Write; + + fn main(string: &mut String) { + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_and_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + } + + mod add_assign { + mod imported_anonymously { + fn main(string: &mut String) { + use std::fmt::Write as _; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported { + fn main(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_anonymously_in_module { + use std::fmt::Write as _; + + fn main(string: &mut String) { + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_in_module { + use std::fmt::Write; + + fn main(string: &mut String) { + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_and_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + } +} diff --git a/tests/ui/format_push_string.rs b/tests/ui/format_push_string.rs index 056ef59ff0e2..1ed0f5b3ac59 100644 --- a/tests/ui/format_push_string.rs +++ b/tests/ui/format_push_string.rs @@ -1,44 +1,132 @@ #![warn(clippy::format_push_string)] fn main() { + use std::fmt::Write; + let mut string = String::new(); string += &format!("{:?}", 1234); //~^ format_push_string string.push_str(&format!("{:?}", 5678)); //~^ format_push_string + + macro_rules! string { + () => { + String::new() + }; + } + string!().push_str(&format!("{:?}", 5678)); + //~^ format_push_string } -mod issue9493 { - pub fn u8vec_to_hex(vector: &Vec, upper: bool) -> String { - let mut hex = String::with_capacity(vector.len() * 2); - for byte in vector { - hex += &(if upper { +// TODO: recognize the already imported `fmt::Write`, and don't add a note suggesting to import it +// again +mod import_write { + mod push_str { + mod imported_anonymously { + fn main(string: &mut String) { + use std::fmt::Write as _; + + string.push_str(&format!("{:?}", 1234)); //~^ format_push_string - - format!("{byte:02X}") - } else { - format!("{byte:02x}") - }); + } + } + + mod imported { + fn main(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_anonymously_in_module { + use std::fmt::Write as _; + + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_in_module { + use std::fmt::Write; + + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_and_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } } - hex } - pub fn other_cases() { - let mut s = String::new(); - // if let - s += &(if let Some(_a) = Some(1234) { - //~^ format_push_string + mod add_assign { + mod imported_anonymously { + fn main(string: &mut String) { + use std::fmt::Write as _; - format!("{}", 1234) - } else { - format!("{}", 1234) - }); - // match - s += &(match Some(1234) { - //~^ format_push_string - Some(_) => format!("{}", 1234), - None => format!("{}", 1234), - }); + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported { + fn main(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_anonymously_in_module { + use std::fmt::Write as _; + + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_in_module { + use std::fmt::Write; + + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_and_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } } } diff --git a/tests/ui/format_push_string.stderr b/tests/ui/format_push_string.stderr index bba2a8947c43..05e26fcbfc2b 100644 --- a/tests/ui/format_push_string.stderr +++ b/tests/ui/format_push_string.stderr @@ -1,60 +1,199 @@ error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:5:5 + --> tests/ui/format_push_string.rs:7:5 | LL | string += &format!("{:?}", 1234); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait = note: `-D clippy::format-push-string` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]` +help: consider using `write!` to avoid the extra allocation + | +LL - string += &format!("{:?}", 1234); +LL + let _ = write!(string, "{:?}", 1234); + | error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:8:5 + --> tests/ui/format_push_string.rs:10:5 | LL | string.push_str(&format!("{:?}", 5678)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 5678)); +LL + let _ = write!(string, "{:?}", 5678); + | error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:16:13 + --> tests/ui/format_push_string.rs:18:5 | -LL | / hex += &(if upper { -LL | | -LL | | -LL | | format!("{byte:02X}") -LL | | } else { -LL | | format!("{byte:02x}") -LL | | }); - | |______________^ +LL | string!().push_str(&format!("{:?}", 5678)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string!().push_str(&format!("{:?}", 5678)); +LL + let _ = write!(string!(), "{:?}", 5678); | - = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:30:9 + --> tests/ui/format_push_string.rs:30:17 | -LL | / s += &(if let Some(_a) = Some(1234) { -LL | | -LL | | -LL | | format!("{}", 1234) -LL | | } else { -LL | | format!("{}", 1234) -LL | | }); - | |__________^ +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); | - = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:38:9 + --> tests/ui/format_push_string.rs:39:17 | -LL | / s += &(match Some(1234) { -LL | | -LL | | Some(_) => format!("{}", 1234), -LL | | None => format!("{}", 1234), -LL | | }); - | |__________^ +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); | - = help: consider using `write!` to avoid the extra allocation -error: aborting due to 5 previous errors +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:48:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:57:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:66:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:73:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:84:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:93:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:102:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:111:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:120:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:127:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: aborting due to 15 previous errors diff --git a/tests/ui/format_push_string_no_core.rs b/tests/ui/format_push_string_no_core.rs new file mode 100644 index 000000000000..4bc45906fa78 --- /dev/null +++ b/tests/ui/format_push_string_no_core.rs @@ -0,0 +1,15 @@ +//@check-pass +#![warn(clippy::format_push_string)] +#![no_std] +#![feature(no_core)] +#![no_core] + +extern crate alloc; + +use alloc::format; +use alloc::string::String; + +fn foo(string: &mut String) { + // can't suggest even `core::fmt::Write` because of `#![no_core]` + string.push_str(&format!("{:?}", 1234)); +} diff --git a/tests/ui/format_push_string_no_std.fixed b/tests/ui/format_push_string_no_std.fixed new file mode 100644 index 000000000000..32d8659dcbd5 --- /dev/null +++ b/tests/ui/format_push_string_no_std.fixed @@ -0,0 +1,15 @@ +#![warn(clippy::format_push_string)] +#![no_std] + +extern crate alloc; + +use alloc::format; +use alloc::string::String; + +fn foo(string: &mut String) { + use core::fmt::Write; + + // TODO: recognize the already imported `fmt::Write`, and don't suggest importing it again + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string +} diff --git a/tests/ui/format_push_string_no_std.rs b/tests/ui/format_push_string_no_std.rs new file mode 100644 index 000000000000..a74189abe528 --- /dev/null +++ b/tests/ui/format_push_string_no_std.rs @@ -0,0 +1,15 @@ +#![warn(clippy::format_push_string)] +#![no_std] + +extern crate alloc; + +use alloc::format; +use alloc::string::String; + +fn foo(string: &mut String) { + use core::fmt::Write; + + // TODO: recognize the already imported `fmt::Write`, and don't suggest importing it again + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string +} diff --git a/tests/ui/format_push_string_no_std.stderr b/tests/ui/format_push_string_no_std.stderr new file mode 100644 index 000000000000..30fd42ac71b2 --- /dev/null +++ b/tests/ui/format_push_string_no_std.stderr @@ -0,0 +1,17 @@ +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_no_std.rs:13:5 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `core::fmt::Write` trait + = note: `-D clippy::format-push-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]` +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/format_push_string_no_std_unfixable.rs b/tests/ui/format_push_string_no_std_unfixable.rs new file mode 100644 index 000000000000..f5ed5e435b5a --- /dev/null +++ b/tests/ui/format_push_string_no_std_unfixable.rs @@ -0,0 +1,13 @@ +//@no-rustfix +#![warn(clippy::format_push_string)] +#![no_std] + +extern crate alloc; + +use alloc::format; +use alloc::string::String; + +fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string +} diff --git a/tests/ui/format_push_string_no_std_unfixable.stderr b/tests/ui/format_push_string_no_std_unfixable.stderr new file mode 100644 index 000000000000..cc716c84efe2 --- /dev/null +++ b/tests/ui/format_push_string_no_std_unfixable.stderr @@ -0,0 +1,17 @@ +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_no_std_unfixable.rs:11:5 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `core::fmt::Write` trait + = note: `-D clippy::format-push-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]` +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/format_push_string_unfixable.rs b/tests/ui/format_push_string_unfixable.rs new file mode 100644 index 000000000000..ff6c13fe4a49 --- /dev/null +++ b/tests/ui/format_push_string_unfixable.rs @@ -0,0 +1,144 @@ +//@no-rustfix +#![warn(clippy::format_push_string)] + +mod issue9493 { + pub fn u8vec_to_hex(vector: &Vec, upper: bool) -> String { + let mut hex = String::with_capacity(vector.len() * 2); + for byte in vector { + hex += &(if upper { + format!("{byte:02X}") + //~^ format_push_string + } else { + format!("{byte:02x}") + }); + } + hex + } + + pub fn other_cases() { + let mut s = String::new(); + // if let + s += &(if let Some(_a) = Some(1234) { + format!("{}", 1234) + //~^ format_push_string + } else { + format!("{}", 1234) + }); + // match + s += &(match Some(1234) { + Some(_) => format!("{}", 1234), + //~^ format_push_string + None => format!("{}", 1234), + }); + } +} + +mod import_write { + mod push_str { + // TODO: suggest importing `std::fmt::Write`; + mod not_imported { + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing the first time, but not again + mod not_imported_and_not_imported { + fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing the first time, but not again + mod not_imported_and_imported { + fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing, but only for `bar` + mod imported_and_not_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + } + + mod add_assign { + // TODO: suggest importing `std::fmt::Write`; + mod not_imported { + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing the first time, but not again + mod not_imported_and_not_imported { + fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing the first time, but not again + mod not_imported_and_imported { + fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing, but only for `bar` + mod imported_and_not_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + } +} + +fn main() {} diff --git a/tests/ui/format_push_string_unfixable.stderr b/tests/ui/format_push_string_unfixable.stderr new file mode 100644 index 000000000000..145e7fcc440d --- /dev/null +++ b/tests/ui/format_push_string_unfixable.stderr @@ -0,0 +1,233 @@ +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:8:13 + | +LL | / hex += &(if upper { +LL | | format!("{byte:02X}") + | | --------------------- `format!` used here +LL | | +LL | | } else { +LL | | format!("{byte:02x}") + | | --------------------- `format!` used here +LL | | }); + | |______________^ + | + = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait + = note: `-D clippy::format-push-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]` + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:21:9 + | +LL | / s += &(if let Some(_a) = Some(1234) { +LL | | format!("{}", 1234) + | | ------------------- `format!` used here +LL | | +LL | | } else { +LL | | format!("{}", 1234) + | | ------------------- `format!` used here +LL | | }); + | |__________^ + | + = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:28:9 + | +LL | / s += &(match Some(1234) { +LL | | Some(_) => format!("{}", 1234), + | | ------------------- `format!` used here +LL | | +LL | | None => format!("{}", 1234), + | | ------------------- `format!` used here +LL | | }); + | |__________^ + | + = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:41:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:49:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:54:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:62:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:69:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:79:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:84:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:94:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:102:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:107:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:115:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:122:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:132:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:137:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: aborting due to 17 previous errors + From b01a2fb652a382b20f9243403297b32569450d6c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 27 Nov 2025 13:58:24 +0000 Subject: [PATCH 0583/3801] Add a test for not resolving ambiguity for multiple --extern with same name --- .../foo-v1.rs | 1 + .../foo-v2.rs | 1 + .../main.rs | 10 ++++ .../main.stderr | 12 +++++ .../rmake.rs | 54 +++++++++++++++++++ .../use-foo.rs | 1 + 6 files changed, 79 insertions(+) create mode 100644 tests/run-make/duplicate-dependency-no-disambiguate/foo-v1.rs create mode 100644 tests/run-make/duplicate-dependency-no-disambiguate/foo-v2.rs create mode 100644 tests/run-make/duplicate-dependency-no-disambiguate/main.rs create mode 100644 tests/run-make/duplicate-dependency-no-disambiguate/main.stderr create mode 100644 tests/run-make/duplicate-dependency-no-disambiguate/rmake.rs create mode 100644 tests/run-make/duplicate-dependency-no-disambiguate/use-foo.rs diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/foo-v1.rs b/tests/run-make/duplicate-dependency-no-disambiguate/foo-v1.rs new file mode 100644 index 000000000000..4a835673a596 --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/foo-v1.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/foo-v2.rs b/tests/run-make/duplicate-dependency-no-disambiguate/foo-v2.rs new file mode 100644 index 000000000000..4a835673a596 --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/foo-v2.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/main.rs b/tests/run-make/duplicate-dependency-no-disambiguate/main.rs new file mode 100644 index 000000000000..eae6b8b4527d --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/main.rs @@ -0,0 +1,10 @@ +#![feature(custom_inner_attributes)] +#![rustfmt::skip] // use_foo must be referenced before foo + +// Load foo-v2 through use-foo +use use_foo as _; + +// Make sure we don't disambiguate this as foo-v2. +use foo as _; + +fn main() {} diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/main.stderr b/tests/run-make/duplicate-dependency-no-disambiguate/main.stderr new file mode 100644 index 000000000000..23caa2caaef6 --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/main.stderr @@ -0,0 +1,12 @@ +error[E0464]: multiple candidates for `rlib` dependency `foo` found + --> main.rs:8:5 + | +LL | use foo as _; + | ^^^ + | + = note: candidate #1: /build-root/test/run-make/duplicate-dependency-no-disambiguate/rmake_out/libfoo-v1.rlib + = note: candidate #2: /build-root/test/run-make/duplicate-dependency-no-disambiguate/rmake_out/libfoo-v2.rlib + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0464`. diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/rmake.rs b/tests/run-make/duplicate-dependency-no-disambiguate/rmake.rs new file mode 100644 index 000000000000..7dd6f3840dfa --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/rmake.rs @@ -0,0 +1,54 @@ +//@ needs-target-std + +use run_make_support::{Rustc, cwd, diff, regex, rust_lib_name, rustc}; + +fn rustc_with_common_args() -> Rustc { + let mut rustc = rustc(); + rustc.remap_path_prefix(cwd(), "$DIR"); + rustc.edition("2018"); // Don't require `extern crate` + rustc +} + +fn main() { + rustc_with_common_args() + .input("foo-v1.rs") + .crate_type("rlib") + .crate_name("foo") + .extra_filename("-v1") + .metadata("-v1") + .run(); + + rustc_with_common_args() + .input("foo-v2.rs") + .crate_type("rlib") + .crate_name("foo") + .extra_filename("-v2") + .metadata("-v2") + .run(); + + rustc_with_common_args() + .input("use-foo.rs") + .crate_type("rlib") + .extern_("foo", rust_lib_name("foo-v2")) + .run(); + + let stderr = rustc_with_common_args() + .input("main.rs") + .extern_("foo", rust_lib_name("foo-v1")) + .extern_("foo", rust_lib_name("foo-v2")) + .extern_("use_foo", rust_lib_name("use_foo")) + .library_search_path(cwd()) + .ui_testing() + .run_fail() + .stderr_utf8(); + + diff() + .expected_file("main.stderr") + .normalize( + regex::escape(run_make_support::build_root().canonicalize().unwrap().to_str().unwrap()), + "/build-root", + ) + .normalize(r"\\", "/") + .actual_text("(rustc)", &stderr) + .run(); +} diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/use-foo.rs b/tests/run-make/duplicate-dependency-no-disambiguate/use-foo.rs new file mode 100644 index 000000000000..15c1d27f1b95 --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/use-foo.rs @@ -0,0 +1 @@ +use foo as _; From 8fec0f495e44db4f2b3b23807f2247e238480c72 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 27 Nov 2025 13:58:49 +0000 Subject: [PATCH 0584/3801] Only check for already loaded indirect dependencies in existing_match For direct dependencies it is a lot harder to not accidentally resolve an ambiguity through an indirect dependency edge and as it turns out this check was actually more expensive than the work it skipped. For indirect dependencies existing_match is still necessary due to an assert in load, but at the same time it also can't accidentally resolve an ambiguity given that we already know exactly which crate to look for based on the crate hash. --- compiler/rustc_metadata/src/creader.rs | 51 ++++---------------------- 1 file changed, 8 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 250aa0769024..4400f9f68180 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -514,55 +514,20 @@ impl CStore { } } - fn existing_match( - &self, - externs: &Externs, - name: Symbol, - hash: Option, - ) -> Option { + fn existing_match(&self, name: Symbol, hash: Option) -> Option { + let hash = hash?; + for (cnum, data) in self.iter_crate_data() { if data.name() != name { trace!("{} did not match {}", data.name(), name); continue; } - match hash { - Some(hash) if hash == data.hash() => return Some(cnum), - Some(hash) => { - debug!("actual hash {} did not match expected {}", hash, data.hash()); - continue; - } - None => {} + if hash == data.hash() { + return Some(cnum); + } else { + debug!("actual hash {} did not match expected {}", hash, data.hash()); } - - // When the hash is None we're dealing with a top-level dependency - // in which case we may have a specification on the command line for - // this library. Even though an upstream library may have loaded - // something of the same name, we have to make sure it was loaded - // from the exact same location as well. - // - // We're also sure to compare *paths*, not actual byte slices. The - // `source` stores paths which are normalized which may be different - // from the strings on the command line. - let source = data.source(); - if let Some(entry) = externs.get(name.as_str()) { - // Only use `--extern crate_name=path` here, not `--extern crate_name`. - if let Some(mut files) = entry.files() { - if files.any(|l| { - let l = l.canonicalized(); - source.dylib.as_ref() == Some(l) - || source.rlib.as_ref() == Some(l) - || source.rmeta.as_ref() == Some(l) - }) { - return Some(cnum); - } - } - continue; - } - - // While the crate name matched, no --extern crate_name=path matched. It is possible - // that we have already loaded the target crate, but if that happens CStore::load will - // indicate so and we gracefully handle this, just potentially wasting a bit of time. } None @@ -799,7 +764,7 @@ impl CStore { let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate }; let private_dep = origin.private_dep(); - let result = if let Some(cnum) = self.existing_match(&tcx.sess.opts.externs, name, hash) { + let result = if let Some(cnum) = self.existing_match(name, hash) { (LoadResult::Previous(cnum), None) } else { info!("falling back to a load"); From 7f1828c5926e67cec899d73ebe1af64a610d49c2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 25 Nov 2025 11:26:09 +0000 Subject: [PATCH 0585/3801] Avoid multiple copies of proc macros ending up in the sysroot --- src/bootstrap/src/core/build_steps/compile.rs | 57 +++++++++++++++++-- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 01b757bae246..7ef170c5e8e1 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -7,7 +7,7 @@ //! goes along from the output of the previous stage. use std::borrow::Cow; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::ffi::OsStr; use std::io::BufReader; use std::io::prelude::*; @@ -1558,7 +1558,7 @@ impl Step for RustcLink { run.never() } - /// Same as `std_link`, only for librustc + /// Same as `StdLink`, only for librustc fn run(self, builder: &Builder<'_>) { let build_compiler = self.build_compiler; let sysroot_compiler = self.sysroot_compiler; @@ -2418,13 +2418,52 @@ pub fn add_to_sysroot( t!(fs::create_dir_all(sysroot_dst)); t!(fs::create_dir_all(sysroot_host_dst)); t!(fs::create_dir_all(self_contained_dst)); + + let mut crates = HashMap::new(); for (path, dependency_type) in builder.read_stamp_file(stamp) { + let filename = path.file_name().unwrap().to_str().unwrap(); let dst = match dependency_type { - DependencyType::Host => sysroot_host_dst, - DependencyType::Target => sysroot_dst, + DependencyType::Host => { + if sysroot_dst == sysroot_host_dst { + // Only insert the part before the . to deduplicate different files for the same crate. + // For example foo-1234.dll and foo-1234.dll.lib. + crates.insert(filename.split_once('.').unwrap().0.to_owned(), path.clone()); + } + + sysroot_host_dst + } + DependencyType::Target => { + // Only insert the part before the . to deduplicate different files for the same crate. + // For example foo-1234.dll and foo-1234.dll.lib. + crates.insert(filename.split_once('.').unwrap().0.to_owned(), path.clone()); + + sysroot_dst + } DependencyType::TargetSelfContained => self_contained_dst, }; - builder.copy_link(&path, &dst.join(path.file_name().unwrap()), FileType::Regular); + builder.copy_link(&path, &dst.join(filename), FileType::Regular); + } + + // Check that none of the rustc_* crates have multiple versions. Otherwise using them from + // the sysroot would cause ambiguity errors. We do allow rustc_hash however as it is an + // external dependency that we build multiple copies of. It is re-exported by + // rustc_data_structures, so not being able to use extern crate rustc_hash; is not a big + // issue. + let mut seen_crates = HashMap::new(); + for (filestem, path) in crates { + if !filestem.contains("rustc_") || filestem.contains("rustc_hash") { + continue; + } + if let Some(other_path) = + seen_crates.insert(filestem.split_once('-').unwrap().0.to_owned(), path.clone()) + { + panic!( + "duplicate rustc crate {}\n- first copy at {}\n- second copy at {}", + filestem.split_once('-').unwrap().0.to_owned(), + other_path.display(), + path.display(), + ); + } } } @@ -2511,7 +2550,13 @@ pub fn run_cargo( if filename.starts_with(&host_root_dir) { // Unless it's a proc macro used in the compiler if crate_types.iter().any(|t| t == "proc-macro") { - deps.push((filename.to_path_buf(), DependencyType::Host)); + // Cargo will compile proc-macros that are part of the rustc workspace twice. + // Once as libmacro-hash.so as build dependency and once as libmacro.so as + // output artifact. Only keep the former to avoid ambiguity when trying to use + // the proc macro from the sysroot. + if filename.file_name().unwrap().to_str().unwrap().contains("-") { + deps.push((filename.to_path_buf(), DependencyType::Host)); + } } continue; } From 3d3b96e3ec120d5074fb2ef9fa8b8506e524f8f3 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 5 Oct 2025 17:28:56 +0800 Subject: [PATCH 0586/3801] rust-analyzer: prep crates for testing against in-tree `rustc_private` --- src/tools/rust-analyzer/crates/base-db/Cargo.toml | 4 ++++ src/tools/rust-analyzer/crates/base-db/src/lib.rs | 5 +++++ src/tools/rust-analyzer/crates/cfg/Cargo.toml | 4 ++++ src/tools/rust-analyzer/crates/cfg/src/lib.rs | 5 +++++ .../rust-analyzer/crates/ide-completion/Cargo.toml | 4 ++++ .../rust-analyzer/crates/ide-completion/src/lib.rs | 5 +++++ src/tools/rust-analyzer/crates/ide-db/Cargo.toml | 4 ++++ src/tools/rust-analyzer/crates/ide-db/src/lib.rs | 5 +++++ .../rust-analyzer/crates/ide-diagnostics/Cargo.toml | 4 ++++ .../rust-analyzer/crates/ide-diagnostics/src/lib.rs | 5 +++++ src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml | 4 ++++ src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs | 5 +++++ src/tools/rust-analyzer/crates/load-cargo/src/lib.rs | 6 ++++++ src/tools/rust-analyzer/crates/parser/src/lib.rs | 2 ++ .../rust-analyzer/crates/proc-macro-api/Cargo.toml | 2 ++ .../rust-analyzer/crates/proc-macro-api/src/lib.rs | 5 +++++ .../rust-analyzer/crates/project-model/Cargo.toml | 4 ++++ .../rust-analyzer/crates/project-model/src/lib.rs | 5 +++++ .../rust-analyzer/crates/rust-analyzer/Cargo.toml | 10 +++++++--- .../rust-analyzer/crates/rust-analyzer/src/lib.rs | 5 +++++ .../crates/rust-analyzer/tests/slow-tests/main.rs | 4 ++++ src/tools/rust-analyzer/crates/span/Cargo.toml | 1 + src/tools/rust-analyzer/crates/span/src/lib.rs | 6 ++++++ .../rust-analyzer/crates/syntax-bridge/src/lib.rs | 5 +++++ src/tools/rust-analyzer/crates/syntax/Cargo.toml | 1 + src/tools/rust-analyzer/crates/syntax/src/lib.rs | 5 +++++ src/tools/rust-analyzer/crates/test-fixture/Cargo.toml | 4 ++++ src/tools/rust-analyzer/crates/test-fixture/src/lib.rs | 6 ++++++ src/tools/rust-analyzer/crates/tt/Cargo.toml | 1 + src/tools/rust-analyzer/crates/tt/src/lib.rs | 3 +++ 30 files changed, 126 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml index ea06fd9c48fc..55dfcbc7e508 100644 --- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml @@ -31,5 +31,9 @@ vfs.workspace = true span.workspace = true intern.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 97938924100b..b6e346521187 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -1,5 +1,10 @@ //! base_db defines basic database traits. The concrete DB is defined by ide. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + pub use salsa; pub use salsa_macros; diff --git a/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml index 9e2a95dbf32c..7207cfcf7dba 100644 --- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml +++ b/src/tools/rust-analyzer/crates/cfg/Cargo.toml @@ -33,5 +33,9 @@ syntax.workspace = true # tt is needed for testing cfg = { path = ".", default-features = false, features = ["tt"] } +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/cfg/src/lib.rs b/src/tools/rust-analyzer/crates/cfg/src/lib.rs index b1ec4c273a85..3e3d67cb4aaf 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/lib.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/lib.rs @@ -1,5 +1,10 @@ //! cfg defines conditional compiling options, `cfg` attribute parser and evaluator +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + mod cfg_expr; mod dnf; #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml index 277d5dfa495c..6abc009241cf 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml @@ -37,5 +37,9 @@ expect-test = "1.5.1" test-utils.workspace = true test-fixture.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index 31e33db104c7..c9d5971cd0e3 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -3,6 +3,11 @@ // It's useful to refer to code that is private in doc comments. #![allow(rustdoc::private_intra_doc_links)] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + mod completions; mod config; mod context; diff --git a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml index f1f9d85cf964..fca06b69d1bb 100644 --- a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml @@ -52,5 +52,9 @@ line-index.workspace = true [dev-dependencies] expect-test = "1.5.1" +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 0301b5020862..338c42325457 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -2,6 +2,11 @@ //! //! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + extern crate self as ide_db; mod apply_change; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml index 6f1e66948f42..ddf5999036d2 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml @@ -34,5 +34,9 @@ expect-test = "1.5.1" test-utils.workspace = true test-fixture.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index fe04bd175c96..e001f4b3e438 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -23,6 +23,11 @@ //! There are also a couple of ad-hoc diagnostics implemented directly here, we //! don't yet have a great pattern for how to do them properly. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + mod handlers { pub(crate) mod await_outside_of_async; pub(crate) mod bad_rtn; diff --git a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml index 0620bd26fefd..1900b069e00f 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml @@ -30,5 +30,9 @@ triomphe.workspace = true test-utils.workspace = true test-fixture.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs index 977dfb7466e4..958a26324fff 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs @@ -63,6 +63,11 @@ // // foo($a, $b) ==>> ($a).foo($b) // ``` +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + mod fragments; mod from_comment; mod matching; diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index a486219efa20..28fbfecfde80 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -2,6 +2,12 @@ //! for incorporating changes. // Note, don't remove any public api from this. This API is consumed by external tools // to run rust-analyzer as a library. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + use std::{any::Any, collections::hash_map::Entry, mem, path::Path, sync}; use crossbeam_channel::{Receiver, unbounded}; diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs index b15bf0cd0105..81cdc188012c 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lib.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs @@ -25,6 +25,8 @@ extern crate ra_ap_rustc_lexer as rustc_lexer; #[cfg(feature = "in-rust-tree")] extern crate rustc_lexer; +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; mod event; mod frontmatter; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml index 18a2408c4035..4de1a3e5dd7d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml @@ -34,6 +34,8 @@ semver.workspace = true [features] sysroot-abi = ["proc-macro-srv", "proc-macro-srv/sysroot-abi"] +default = [] +in-rust-tree = [] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index f0c7ce7efd1c..8e1faca00a1b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -12,6 +12,11 @@ )] #![allow(internal_features)] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + mod codec; mod framing; pub mod legacy_protocol; diff --git a/src/tools/rust-analyzer/crates/project-model/Cargo.toml b/src/tools/rust-analyzer/crates/project-model/Cargo.toml index 7e0b1f75f72c..f825a456dea7 100644 --- a/src/tools/rust-analyzer/crates/project-model/Cargo.toml +++ b/src/tools/rust-analyzer/crates/project-model/Cargo.toml @@ -39,5 +39,9 @@ toolchain.workspace = true [dev-dependencies] expect-test = "1.5.1" +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs index 8eee3d1455c1..0d89e13ed374 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs @@ -18,6 +18,11 @@ // It's useful to refer to code that is private in doc comments. #![allow(rustdoc::private_intra_doc_links)] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + pub mod project_json; pub mod toolchain_info { pub mod rustc_cfg; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index 2e48c5a5a66c..d1283ca59e8c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -98,12 +98,16 @@ syntax-bridge.workspace = true jemalloc = ["jemallocator", "profile/jemalloc"] force-always-assert = ["stdx/force-always-assert"] in-rust-tree = [ - "syntax/in-rust-tree", - "parser/in-rust-tree", - "hir/in-rust-tree", + "cfg/in-rust-tree", "hir-def/in-rust-tree", "hir-ty/in-rust-tree", + "hir/in-rust-tree", + "ide-ssr/in-rust-tree", + "ide/in-rust-tree", "load-cargo/in-rust-tree", + "parser/in-rust-tree", + "proc-macro-api/in-rust-tree", + "syntax/in-rust-tree", ] dhat = ["dep:dhat"] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 3dea21e56485..a6cd43139229 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -9,6 +9,11 @@ //! The `cli` submodule implements some batch-processing analysis, primarily as //! a debugging aid. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + extern crate ra_ap_rustc_type_ir as rustc_type_ir; /// Any toolchain less than this version will likely not work with rust-analyzer built from this revision. diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 5a4ad6f380f9..48433342d51d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -9,6 +9,10 @@ //! be sure without a real client anyway. #![allow(clippy::disallowed_types)] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; mod cli; mod ratoml; diff --git a/src/tools/rust-analyzer/crates/span/Cargo.toml b/src/tools/rust-analyzer/crates/span/Cargo.toml index 966962bab381..cfb319d688b6 100644 --- a/src/tools/rust-analyzer/crates/span/Cargo.toml +++ b/src/tools/rust-analyzer/crates/span/Cargo.toml @@ -27,6 +27,7 @@ syntax.workspace = true [features] default = ["salsa"] +in-rust-tree = [] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs index cb91f4924944..c44b0198b72c 100644 --- a/src/tools/rust-analyzer/crates/span/src/lib.rs +++ b/src/tools/rust-analyzer/crates/span/src/lib.rs @@ -1,4 +1,10 @@ //! File and span related types. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + use std::fmt::{self, Write}; mod ast_id; diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs index 1ded2b411319..815b4f279900 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs @@ -1,5 +1,10 @@ //! Conversions between [`SyntaxNode`] and [`tt::TokenTree`]. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + use std::{collections::VecDeque, fmt, hash::Hash}; use intern::Symbol; diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml index 1ee93013e3e8..8909fb423c4d 100644 --- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml +++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml @@ -33,6 +33,7 @@ rustc_apfloat = "0.2.3" test-utils.workspace = true [features] +default = [] in-rust-tree = [] [lints] diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs index de341f05538e..9e3083066c94 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs @@ -19,6 +19,11 @@ //! [RFC]: //! [Swift]: +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + mod parsing; mod ptr; mod syntax_error; diff --git a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml index 353d4c312dba..7760ae7aa045 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml +++ b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml @@ -21,5 +21,9 @@ intern.workspace = true triomphe.workspace = true paths.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 457cd3ac854a..5e8b250c24a0 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -1,4 +1,10 @@ //! A set of high-level utility fixture methods to use in tests. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + use std::{any::TypeId, mem, str::FromStr, sync}; use base_db::target::TargetData; diff --git a/src/tools/rust-analyzer/crates/tt/Cargo.toml b/src/tools/rust-analyzer/crates/tt/Cargo.toml index 82e7c24668fe..3183b72a6629 100644 --- a/src/tools/rust-analyzer/crates/tt/Cargo.toml +++ b/src/tools/rust-analyzer/crates/tt/Cargo.toml @@ -21,6 +21,7 @@ intern.workspace = true ra-ap-rustc_lexer.workspace = true [features] +default = [] in-rust-tree = [] [lints] diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index ea0752250db1..d6a743c695e8 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -5,6 +5,9 @@ #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_lexer as rustc_lexer; #[cfg(feature = "in-rust-tree")] From 24f00b63ef31c260e0e5a8393bc495dee9d7ad89 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Mon, 15 Sep 2025 20:37:24 +0800 Subject: [PATCH 0587/3801] bootstrap: run full `rust-analyzer` tests --- src/bootstrap/src/core/build_steps/test.rs | 55 ++++++++++++++++------ 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index a699cd23fb60..59fcf761d9fc 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -465,35 +465,60 @@ impl Step for RustAnalyzer { /// Runs `cargo test` for rust-analyzer fn run(self, builder: &Builder<'_>) { - let host = self.compilers.target(); + let build_compiler = self.compilers.build_compiler(); + let target = self.compilers.target(); - let workspace_path = "src/tools/rust-analyzer"; - // until the whole RA test suite runs on `i686`, we only run - // `proc-macro-srv` tests - let crate_path = "src/tools/rust-analyzer/crates/proc-macro-srv"; let mut cargo = tool::prepare_tool_cargo( builder, - self.compilers.build_compiler(), + build_compiler, Mode::ToolRustcPrivate, - host, + target, Kind::Test, - crate_path, + "src/tools/rust-analyzer", SourceType::InTree, &["in-rust-tree".to_owned()], ); cargo.allow_features(tool::RustAnalyzer::ALLOW_FEATURES); - let dir = builder.src.join(workspace_path); - // needed by rust-analyzer to find its own text fixtures, cf. - // https://github.com/rust-analyzer/expect-test/issues/33 - cargo.env("CARGO_WORKSPACE_DIR", &dir); + // N.B. it turns out _setting_ `CARGO_WORKSPACE_DIR` actually somehow breaks `expect-test`, + // even though previously we actually needed to set that hack to allow `expect-test` to + // correctly discover the r-a workspace instead of the outer r-l/r workspace. - // RA's test suite tries to write to the source directory, that can't - // work in Rust CI + // FIXME: RA's test suite tries to write to the source directory, that can't work in Rust CI + // without properly wiring up the writable test dir. cargo.env("SKIP_SLOW_TESTS", "1"); + // NOTE: we need to skip `src/tools/rust-analyzer/xtask` as they seem to exercise rustup / + // stable rustfmt. + // + // NOTE: you can only skip a specific workspace package via `--exclude=...` if you *also* + // specify `--workspace`. + cargo.arg("--workspace"); + cargo.arg("--exclude=xtask"); + + let mut skip_tests = vec![]; + + // NOTE: the following test skips is a bit cheeky in that it assumes there are no + // identically named tests across different r-a packages, where we want to run the + // identically named test in one package but not another. If we want to support that use + // case, we'd have to run the r-a tests in two batches (with one excluding the package that + // we *don't* want to run the test for, and the other batch including). + + // Across all platforms. + skip_tests.extend_from_slice(&[ + // FIXME: this test wants to find a `rustc`. We need to provide it with a path to staged + // in-tree `rustc`, but setting `RUSTC` env var requires some reworking of bootstrap. + "tests::smoke_test_real_sysroot_cargo", + // NOTE: part of `smol-str` test suite; this tries to access a stable rustfmt from the + // environment, which is not something we want to do. + "check_code_formatting", + ]); + + let skip_tests = skip_tests.iter().map(|name| format!("--skip={name}")).collect::>(); + let skip_tests = skip_tests.iter().map(|s| s.as_str()).collect::>(); + cargo.add_rustc_lib_path(builder); - run_cargo_test(cargo, &[], &[], "rust-analyzer", host, builder); + run_cargo_test(cargo, skip_tests.as_slice(), &[], "rust-analyzer", target, builder); } fn metadata(&self) -> Option { From 15e49699cab6d00fe626bff14c32e90860b99d21 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 11 Dec 2025 20:57:34 +0800 Subject: [PATCH 0588/3801] bootstrap: skip r-a main tests against 32-bit targets We don't really have a good way to get the target pointer width in bootstrap (yet), so I had to resort to hacky target tuple substring matches. This commit currently only gates on `i686-*` targets, which are 32-bits, and does not try to gate on `i586-*` targets (I need to run try jobs to check if r-a tests actually get run.) --- src/bootstrap/src/core/build_steps/test.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 59fcf761d9fc..6e2718f9f835 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -468,6 +468,19 @@ impl Step for RustAnalyzer { let build_compiler = self.compilers.build_compiler(); let target = self.compilers.target(); + // NOTE: rust-analyzer repo currently (as of 2025-12-11) does not run tests against 32-bit + // targets, so we also don't run them in rust-lang/rust CI (because that will just mean that + // subtree syncs will keep getting 32-bit-specific failures that are not observed in + // rust-analyzer repo CI). + // + // Some 32-bit specific failures include e.g. target pointer width specific hashes. + + // FIXME: eventually, we should probably reduce the amount of target tuple substring + // matching in bootstrap. + if target.starts_with("i686") { + return; + } + let mut cargo = tool::prepare_tool_cargo( builder, build_compiler, From a96d486cbd96c5f6819bec25e1f23a71b23233a7 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 11 Dec 2025 14:01:00 +0100 Subject: [PATCH 0589/3801] Update snapshot --- src/bootstrap/src/core/builder/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index b8ba1b4c2c34..28659f4c6fa5 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2912,6 +2912,7 @@ mod snapshot { [build] rustc 1 -> rust-analyzer-proc-macro-srv 2 [build] rustc 0 -> GenerateCopyright 1 [dist] rustc + [dist] rustc 1 -> rustc-dev 2 [build] rustc 1 -> cargo 2 [dist] rustc 1 -> cargo 2 [build] rustc 1 -> rust-analyzer 2 From 4215b7228d28cb84016e8f0e41c0a5e0935a222f Mon Sep 17 00:00:00 2001 From: Andrew Cherry Date: Thu, 11 Dec 2025 13:58:40 +0000 Subject: [PATCH 0590/3801] removal of aarch64 special-casing (#497) --- crates/std_float/src/lib.rs | 98 ++++++++++++++----------------------- 1 file changed, 37 insertions(+), 61 deletions(-) diff --git a/crates/std_float/src/lib.rs b/crates/std_float/src/lib.rs index c3c9b76e50b8..b269efc9b1d7 100644 --- a/crates/std_float/src/lib.rs +++ b/crates/std_float/src/lib.rs @@ -66,28 +66,43 @@ pub trait StdFloat: Sealed + Sized { /// Produces a vector where every element has the sine of the value /// in the equivalently-indexed element in `self`. + #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn sin(self) -> Self; + fn sin(self) -> Self { + unsafe { intrinsics::simd_fsin(self) } + } /// Produces a vector where every element has the cosine of the value /// in the equivalently-indexed element in `self`. + #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn cos(self) -> Self; + fn cos(self) -> Self { + unsafe { intrinsics::simd_fcos(self) } + } /// Produces a vector where every element has the exponential (base e) of the value /// in the equivalently-indexed element in `self`. + #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn exp(self) -> Self; + fn exp(self) -> Self { + unsafe { intrinsics::simd_fexp(self) } + } /// Produces a vector where every element has the exponential (base 2) of the value /// in the equivalently-indexed element in `self`. + #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn exp2(self) -> Self; + fn exp2(self) -> Self { + unsafe { intrinsics::simd_fexp2(self) } + } /// Produces a vector where every element has the natural logarithm of the value /// in the equivalently-indexed element in `self`. + #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn ln(self) -> Self; + fn ln(self) -> Self { + unsafe { intrinsics::simd_flog(self) } + } /// Produces a vector where every element has the logarithm with respect to an arbitrary /// in the equivalently-indexed elements in `self` and `base`. @@ -99,13 +114,19 @@ pub trait StdFloat: Sealed + Sized { /// Produces a vector where every element has the base-2 logarithm of the value /// in the equivalently-indexed element in `self`. + #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn log2(self) -> Self; + fn log2(self) -> Self { + unsafe { intrinsics::simd_flog2(self) } + } /// Produces a vector where every element has the base-10 logarithm of the value /// in the equivalently-indexed element in `self`. + #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn log10(self) -> Self; + fn log10(self) -> Self { + unsafe { intrinsics::simd_flog10(self) } + } /// Returns the smallest integer greater than or equal to each element. #[must_use = "method returns a new vector and does not mutate the original value"] @@ -143,61 +164,16 @@ pub trait StdFloat: Sealed + Sized { impl Sealed for Simd {} impl Sealed for Simd {} -macro_rules! impl_float { - { - $($fn:ident: $intrinsic:ident,)* - } => { - impl StdFloat for Simd - { - #[inline] - fn fract(self) -> Self { - self - self.trunc() - } - - $( - #[inline] - fn $fn(self) -> Self { - unsafe { intrinsics::$intrinsic(self) } - } - )* - } - - impl StdFloat for Simd - { - #[inline] - fn fract(self) -> Self { - self - self.trunc() - } - - $( - #[inline] - fn $fn(self) -> Self { - // https://github.com/llvm/llvm-project/issues/83729 - #[cfg(target_arch = "aarch64")] - { - let mut ln = Self::splat(0f64); - for i in 0..N { - ln[i] = self[i].$fn() - } - ln - } - - #[cfg(not(target_arch = "aarch64"))] - { - unsafe { intrinsics::$intrinsic(self) } - } - } - )* - } +impl StdFloat for Simd { + #[inline] + fn fract(self) -> Self { + self - self.trunc() } } -impl_float! { - sin: simd_fsin, - cos: simd_fcos, - exp: simd_fexp, - exp2: simd_fexp2, - ln: simd_flog, - log2: simd_flog2, - log10: simd_flog10, +impl StdFloat for Simd { + #[inline] + fn fract(self) -> Self { + self - self.trunc() + } } From 6672a89f98c3018967af44be7dafba14953ddafd Mon Sep 17 00:00:00 2001 From: Redddy Date: Thu, 11 Dec 2025 23:47:25 +0900 Subject: [PATCH 0591/3801] Fix broken link for 'Uniqueness and Reference Immutability' --- src/doc/rustc-dev-guide/src/appendix/bibliography.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index 3729194f5fa1..e862ac368475 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/src/appendix/bibliography.md @@ -15,7 +15,7 @@ Rust, as well as publications about Rust. * [Safe manual memory management in Cyclone](https://www.cs.umd.edu/projects/PL/cyclone/scp.pdf) * [Skolem Normal Form](https://en.wikipedia.org/wiki/Skolem_normal_form) * [Traits: composable units of behavior](http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf) -* [Uniqueness and Reference Immutability for Safe Parallelism](https://research.microsoft.com/pubs/170528/msr-tr-2012-79.pdf) +* [Uniqueness and Reference Immutability for Safe Parallelism](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/msr-tr-2012-79.pdf) ## Concurrency From c60ed211d1a7216fd422f99da158e853e3eca2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 10 Dec 2025 20:20:22 +0000 Subject: [PATCH 0592/3801] Do not suggest moving expression out of for loop when hitting `break` from desugaring --- .../src/diagnostics/conflict_errors.rs | 4 +- .../closure/spawn-thread.edition2018.stderr | 10 ----- .../moves/arc-consumed-in-looped-closure.rs | 37 +++++++++++++++++++ .../arc-consumed-in-looped-closure.stderr | 27 ++++++++++++++ .../nested-loop-moved-value-wrong-continue.rs | 6 +-- ...ted-loop-moved-value-wrong-continue.stderr | 30 +++------------ 6 files changed, 74 insertions(+), 40 deletions(-) create mode 100644 tests/ui/moves/arc-consumed-in-looped-closure.rs create mode 100644 tests/ui/moves/arc-consumed-in-looped-closure.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index f8a6fafbe78a..2999d1f2926c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -4521,7 +4521,9 @@ struct BreakFinder { impl<'hir> Visitor<'hir> for BreakFinder { fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { match ex.kind { - hir::ExprKind::Break(destination, _) => { + hir::ExprKind::Break(destination, _) + if !ex.span.is_desugaring(DesugaringKind::ForLoop) => + { self.found_breaks.push((destination, ex.span)); } hir::ExprKind::Continue(destination) => { diff --git a/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr index ac8e1c5fa858..4ac5dfb8d228 100644 --- a/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr +++ b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr @@ -12,16 +12,6 @@ LL | | drop((x.0, x.1, x.2)); | | --- use occurs due to use in closure LL | | }); | |_________- value moved here, in previous iteration of loop - | -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ let mut value = std::thread::spawn(use || { -LL + -LL + drop((x.0, x.1, x.2)); -LL + }); -LL ~ for _ in 0..10 { -LL ~ let handler = value; - | error: aborting due to 1 previous error diff --git a/tests/ui/moves/arc-consumed-in-looped-closure.rs b/tests/ui/moves/arc-consumed-in-looped-closure.rs new file mode 100644 index 000000000000..8700c7850847 --- /dev/null +++ b/tests/ui/moves/arc-consumed-in-looped-closure.rs @@ -0,0 +1,37 @@ +use std::thread; +use std::sync::{Arc, Mutex, Condvar}; +use std::collections::VecDeque; + +type Job = Box; + +struct ThreadPool { + workers: Vec>, + queue: Arc<()>, +} + +impl ThreadPool { + fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + panic!() + } +} + +fn main() { + let results = Arc::new(Mutex::new(Vec::new())); //~ NOTE move occurs because + let pool = ThreadPool { + workers: vec![], + queue: Arc::new(()), + }; + + for i in 0..20 { //~ NOTE inside of this loop + // let results = Arc::clone(&results); // Forgot this. + pool.execute(move || { //~ ERROR E0382 + //~^ NOTE value moved into closure here, in previous iteration of loop + //~| HELP consider cloning the value before moving it into the closure + let mut r = results.lock().unwrap(); //~ NOTE use occurs due to use in closure + r.push(i); + }); + } +} diff --git a/tests/ui/moves/arc-consumed-in-looped-closure.stderr b/tests/ui/moves/arc-consumed-in-looped-closure.stderr new file mode 100644 index 000000000000..47d6fd6cbad3 --- /dev/null +++ b/tests/ui/moves/arc-consumed-in-looped-closure.stderr @@ -0,0 +1,27 @@ +error[E0382]: use of moved value: `results` + --> $DIR/arc-consumed-in-looped-closure.rs:30:22 + | +LL | let results = Arc::new(Mutex::new(Vec::new())); + | ------- move occurs because `results` has type `Arc>>`, which does not implement the `Copy` trait +... +LL | for i in 0..20 { + | -------------- inside of this loop +LL | // let results = Arc::clone(&results); // Forgot this. +LL | pool.execute(move || { + | ^^^^^^^ value moved into closure here, in previous iteration of loop +... +LL | let mut r = results.lock().unwrap(); + | ------- use occurs due to use in closure + | +help: consider cloning the value before moving it into the closure + | +LL ~ let value = results.clone(); +LL ~ pool.execute(move || { +LL | +LL | +LL ~ let mut r = value.lock().unwrap(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs b/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs index 87800d314ed5..0cbb501a5764 100644 --- a/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs +++ b/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs @@ -7,8 +7,6 @@ fn foo() { //~^ NOTE this reinitialization might get skipped //~| NOTE move occurs because `foo` has type `String` //~| NOTE inside of this loop - //~| HELP consider moving the expression out of the loop - //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE //~| NOTE baz.push(foo); @@ -35,8 +33,6 @@ fn main() { //~| NOTE for bar in &bars { //~^ NOTE inside of this loop - //~| HELP consider moving the expression out of the loop - //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE if foo == *bar { baz.push(foo); @@ -44,7 +40,7 @@ fn main() { //~| HELP consider cloning the value continue; //~^ NOTE verify that your loop breaking logic is correct - //~| NOTE this `continue` advances the loop at line 36 + //~| NOTE this `continue` advances the loop at line 34 } } qux.push(foo); diff --git a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr index 6ef1a4193b1a..60be70007fbe 100644 --- a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr +++ b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `foo` - --> $DIR/nested-loop-moved-value-wrong-continue.rs:21:14 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:19:14 | LL | for foo in foos { for bar in &bars { if foo == *bar { | --- ---------------- inside of this loop @@ -14,29 +14,20 @@ LL | qux.push(foo); | ^^^ value used here after move | note: verify that your loop breaking logic is correct - --> $DIR/nested-loop-moved-value-wrong-continue.rs:17:9 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:15:9 | LL | for foo in foos { for bar in &bars { if foo == *bar { | --------------- ---------------- ... LL | continue; - | ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 20:8 -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ for foo in foos { let mut value = baz.push(foo); -LL ~ for bar in &bars { if foo == *bar { -LL | -... -LL | -LL ~ value; - | + | ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 18:8 help: consider cloning the value if the performance cost is acceptable | LL | baz.push(foo.clone()); | ++++++++ error[E0382]: use of moved value: `foo` - --> $DIR/nested-loop-moved-value-wrong-continue.rs:50:18 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:46:18 | LL | for foo in foos { | --- @@ -54,7 +45,7 @@ LL | qux.push(foo); | ^^^ value used here after move | note: verify that your loop breaking logic is correct - --> $DIR/nested-loop-moved-value-wrong-continue.rs:45:17 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:41:17 | LL | for foo in foos { | --------------- @@ -63,16 +54,7 @@ LL | for bar in &bars { | ---------------- ... LL | continue; - | ^^^^^^^^ this `continue` advances the loop at line 36 -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ let mut value = baz.push(foo); -LL ~ for bar in &bars { -LL | -... -LL | if foo == *bar { -LL ~ value; - | + | ^^^^^^^^ this `continue` advances the loop at line 34 help: consider cloning the value if the performance cost is acceptable | LL | baz.push(foo.clone()); From 82118ff316c67710f1677ae6e36660f7fed91d3a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 11 Dec 2025 17:03:49 +0100 Subject: [PATCH 0593/3801] gitconfig is not a toml file --- src/tools/miri/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md index 073ad267476c..1995300c5bcb 100644 --- a/src/tools/miri/CONTRIBUTING.md +++ b/src/tools/miri/CONTRIBUTING.md @@ -351,7 +351,7 @@ you need to pull rustc changes into Miri first, and then re-do the rustc push. If this fails due to authentication problems, it can help to make josh push via ssh instead of https. Add the following to your `.gitconfig`: -```toml +```text [url "git@github.com:"] pushInsteadOf = https://github.com/ ``` From 2422c1d9dabda5bca06d9488ff421198aee7a18e Mon Sep 17 00:00:00 2001 From: Urgau <3616612+Urgau@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:51:47 +0100 Subject: [PATCH 0594/3801] Remove `[no-mentions]` handler in our triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- library/compiler-builtins/triagebot.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/compiler-builtins/triagebot.toml b/library/compiler-builtins/triagebot.toml index 57f9a0849839..b210a5fb5256 100644 --- a/library/compiler-builtins/triagebot.toml +++ b/library/compiler-builtins/triagebot.toml @@ -12,10 +12,6 @@ exclude_titles = ["Rustc pull update"] [issue-links] check-commits = false -# Prevents mentions in commits to avoid users being spammed -# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html -[no-mentions] - # Enable issue transfers within the org # Documentation at: https://forge.rust-lang.org/triagebot/transfer.html [transfer] From 42c8b68ee9b591b79cbdfd68f5656a172815aa21 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 11 Dec 2025 18:48:10 +0100 Subject: [PATCH 0595/3801] Bump nightly version -> 2025-12-11 --- clippy_utils/README.md | 2 +- rust-toolchain.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 4b1a10a3d9cf..dc8695fef9f5 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-11-28 +nightly-2025-12-11 ``` diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5157b79832a3..1384f4078ebe 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-11-28" +channel = "nightly-2025-12-11" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" From 1ff46825908de84aa401b5be0ef7b70a89d8e8da Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 11 Dec 2025 18:48:15 +0100 Subject: [PATCH 0596/3801] Bump Clippy version -> 0.1.94 --- Cargo.toml | 2 +- clippy_config/Cargo.toml | 2 +- clippy_lints/Cargo.toml | 2 +- clippy_utils/Cargo.toml | 2 +- declare_clippy_lint/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fee885d8fa7e..67078adea2b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.93" +version = "0.1.94" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 3f6b26d3334e..a65fe7bcbda5 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.93" +version = "0.1.94" edition = "2024" publish = false diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index bc97746a1cba..7a78ef32bf3c 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.93" +version = "0.1.94" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index f2e276b27a98..503d581d6c7f 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.93" +version = "0.1.94" edition = "2024" description = "Helpful tools for writing lints, provided as they are used in Clippy" repository = "https://github.com/rust-lang/rust-clippy" diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml index b73a7c7bb4d9..ee6d6cdbc34e 100644 --- a/declare_clippy_lint/Cargo.toml +++ b/declare_clippy_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "declare_clippy_lint" -version = "0.1.93" +version = "0.1.94" edition = "2024" repository = "https://github.com/rust-lang/rust-clippy" license = "MIT OR Apache-2.0" From 0428dd5586f3c90d7e7229ffbeb505d3b33dce34 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 11 Dec 2025 18:51:58 +0100 Subject: [PATCH 0597/3801] miri: add -Zbinary-dep-depinfo to dependency builds --- src/tools/clippy/tests/compile-test.rs | 4 ++++ src/tools/miri/tests/ui.rs | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index 1ac688935278..fa2b6cf26806 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -173,6 +173,10 @@ impl TestContext { p.envs.push(("RUSTC_SNAPSHOT".into(), Some(rustc.into()))); p.envs.push(("RUSTC_SNAPSHOT_LIBDIR".into(), Some(libdir.into()))); p.envs.push(("RUSTC_SYSROOT".into(), Some(sysroot.into()))); + // Ensure we rebuild the dependencies when the sysroot changes. + // (Bootstrap usually sets this automatically, but since we invoke cargo + // ourselves we have to do it.) + p.args.push("-Zbinary-dep-depinfo".into()); } p }, diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index c2cbdd548078..338d55b9d773 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -133,7 +133,11 @@ fn miri_config( program: miri_path() .with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)), // There is no `cargo miri build` so we just use `cargo miri run`. - args: ["miri", "run"].into_iter().map(Into::into).collect(), + // Add `-Zbinary-dep-depinfo` since it is needed for bootstrap builds (and doesn't harm otherwise). + args: ["miri", "run", "--quiet", "-Zbinary-dep-depinfo"] + .into_iter() + .map(Into::into) + .collect(), // Reset `RUSTFLAGS` to work around . envs: vec![("RUSTFLAGS".into(), None)], ..CommandBuilder::cargo() From 13d9d6559fb6458c36bef03f146c930982cc69af Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 11 Dec 2025 18:51:58 +0100 Subject: [PATCH 0598/3801] miri: add -Zbinary-dep-depinfo to dependency builds --- tests/compile-test.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 1ac688935278..fa2b6cf26806 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -173,6 +173,10 @@ impl TestContext { p.envs.push(("RUSTC_SNAPSHOT".into(), Some(rustc.into()))); p.envs.push(("RUSTC_SNAPSHOT_LIBDIR".into(), Some(libdir.into()))); p.envs.push(("RUSTC_SYSROOT".into(), Some(sysroot.into()))); + // Ensure we rebuild the dependencies when the sysroot changes. + // (Bootstrap usually sets this automatically, but since we invoke cargo + // ourselves we have to do it.) + p.args.push("-Zbinary-dep-depinfo".into()); } p }, From 19f0c81b3f674c5cfd76e3491ad146b033ddfa96 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 11 Dec 2025 19:13:34 +0100 Subject: [PATCH 0599/3801] Merge commit '9e3e9649cbae7ed33ba62ca436f43081eaaedeb5' into clippy-subtree-update --- CHANGELOG.md | 83 ++++- Cargo.toml | 2 +- README.md | 2 +- book/src/README.md | 2 +- book/src/lint_configuration.md | 10 + clippy_config/Cargo.toml | 2 +- clippy_config/src/conf.rs | 3 + clippy_lints/Cargo.toml | 2 +- clippy_lints/src/casts/mod.rs | 32 ++ clippy_lints/src/casts/needless_type_cast.rs | 289 ++++++++++++++ clippy_lints/src/declared_lints.rs | 6 +- clippy_lints/src/deprecated_lints.rs | 2 +- clippy_lints/src/entry.rs | 48 ++- clippy_lints/src/large_stack_frames.rs | 152 +++++--- clippy_lints/src/len_without_is_empty.rs | 342 +++++++++++++++++ clippy_lints/src/len_zero.rs | 345 +---------------- clippy_lints/src/lib.rs | 4 + .../src/loops/while_let_on_iterator.rs | 31 +- clippy_lints/src/manual_ilog2.rs | 115 ++++++ .../src/matches/match_like_matches.rs | 52 ++- .../methods/manual_saturating_arithmetic.rs | 107 +++++- clippy_lints/src/methods/mod.rs | 53 ++- .../src/methods/ptr_offset_by_literal.rs | 138 +++++++ .../src/missing_asserts_for_indexing.rs | 94 ++--- clippy_lints/src/nonstandard_macro_braces.rs | 38 +- .../src/operators/decimal_bitwise_operands.rs | 76 ++++ clippy_lints/src/operators/mod.rs | 28 ++ clippy_lints/src/transmute/mod.rs | 36 +- .../src/transmute/transmute_ptr_to_ptr.rs | 10 +- .../src/transmute/transmute_ptr_to_ref.rs | 3 +- clippy_lints/src/tuple_array_conversions.rs | 41 +- clippy_lints/src/unwrap.rs | 9 +- clippy_lints/src/useless_conversion.rs | 5 +- clippy_lints/src/zero_repeat_side_effects.rs | 72 +++- clippy_utils/Cargo.toml | 6 +- clippy_utils/README.md | 2 +- clippy_utils/src/msrvs.rs | 1 + clippy_utils/src/sym.rs | 2 + declare_clippy_lint/Cargo.toml | 2 +- rust-toolchain.toml | 2 +- .../large_stack_frames_for_macros/clippy.toml | 1 + .../large_stack_frames.rs | 42 +++ .../large_stack_frames.stderr | 89 +++++ .../clippy.toml | 2 + .../large_stack_frames.rs | 13 + .../conf_nonstandard_macro_braces.fixed | 14 + .../conf_nonstandard_macro_braces.rs | 14 + .../conf_nonstandard_macro_braces.stderr | 44 ++- .../toml_unknown_key/conf_unknown_key.stderr | 3 + tests/ui/borrow_as_ptr.fixed | 2 +- tests/ui/borrow_as_ptr.rs | 2 +- .../ui/checked_unwrap/simple_conditionals.rs | 19 + tests/ui/crashes/ice-4579.rs | 2 +- tests/ui/decimal_bitwise_operands.rs | 133 +++++++ tests/ui/decimal_bitwise_operands.stderr | 204 ++++++++++ tests/ui/deprecated.stderr | 2 +- tests/ui/entry.fixed | 24 ++ tests/ui/entry.rs | 24 ++ tests/ui/len_without_is_empty.rs | 12 + tests/ui/manual_ilog2.fixed | 32 ++ tests/ui/manual_ilog2.rs | 32 ++ tests/ui/manual_ilog2.stderr | 23 ++ tests/ui/manual_saturating_arithmetic.fixed | 10 + tests/ui/manual_saturating_arithmetic.rs | 10 + tests/ui/manual_saturating_arithmetic.stderr | 8 +- tests/ui/match_like_matches_macro.fixed | 7 + tests/ui/match_like_matches_macro.rs | 10 + tests/ui/match_like_matches_macro.stderr | 156 +++++++- .../match_like_matches_macro_if_let_guard.rs | 51 +++ tests/ui/missing_asserts_for_indexing.stderr | 352 ++++-------------- ...sing_asserts_for_indexing_unfixable.stderr | 162 +------- tests/ui/needless_type_cast.fixed | 182 +++++++++ tests/ui/needless_type_cast.rs | 182 +++++++++ tests/ui/needless_type_cast.stderr | 71 ++++ tests/ui/ptr_offset_by_literal.fixed | 50 +++ tests/ui/ptr_offset_by_literal.rs | 50 +++ tests/ui/ptr_offset_by_literal.stderr | 141 +++++++ tests/ui/transmute_ptr_to_ptr.fixed | 23 ++ tests/ui/transmute_ptr_to_ptr.rs | 23 ++ tests/ui/transmute_ptr_to_ptr.stderr | 82 +++- tests/ui/transmute_ptr_to_ref.fixed | 56 ++- tests/ui/transmute_ptr_to_ref.rs | 56 ++- tests/ui/transmute_ptr_to_ref.stderr | 110 ++++-- tests/ui/tuple_array_conversions.rs | 23 ++ tests/ui/tuple_array_conversions.stderr | 10 +- tests/ui/useless_conversion.fixed | 11 + tests/ui/useless_conversion.rs | 11 + tests/ui/useless_conversion.stderr | 8 +- tests/ui/while_let_on_iterator.fixed | 104 ++++++ tests/ui/while_let_on_iterator.rs | 104 ++++++ tests/ui/while_let_on_iterator.stderr | 34 +- tests/ui/zero_offset.rs | 2 +- tests/ui/zero_repeat_side_effects.fixed | 32 +- tests/ui/zero_repeat_side_effects.rs | 26 +- tests/ui/zero_repeat_side_effects.stderr | 52 ++- triagebot.toml | 5 +- util/gh-pages/style.css | 4 +- 97 files changed, 4089 insertions(+), 1111 deletions(-) create mode 100644 clippy_lints/src/casts/needless_type_cast.rs create mode 100644 clippy_lints/src/len_without_is_empty.rs create mode 100644 clippy_lints/src/manual_ilog2.rs create mode 100644 clippy_lints/src/methods/ptr_offset_by_literal.rs create mode 100644 clippy_lints/src/operators/decimal_bitwise_operands.rs create mode 100644 tests/ui-toml/large_stack_frames_for_macros/clippy.toml create mode 100644 tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs create mode 100644 tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.stderr create mode 100644 tests/ui-toml/large_stack_frames_for_special_targets/clippy.toml create mode 100644 tests/ui-toml/large_stack_frames_for_special_targets/large_stack_frames.rs create mode 100644 tests/ui/decimal_bitwise_operands.rs create mode 100644 tests/ui/decimal_bitwise_operands.stderr create mode 100644 tests/ui/manual_ilog2.fixed create mode 100644 tests/ui/manual_ilog2.rs create mode 100644 tests/ui/manual_ilog2.stderr create mode 100644 tests/ui/match_like_matches_macro_if_let_guard.rs create mode 100644 tests/ui/needless_type_cast.fixed create mode 100644 tests/ui/needless_type_cast.rs create mode 100644 tests/ui/needless_type_cast.stderr create mode 100644 tests/ui/ptr_offset_by_literal.fixed create mode 100644 tests/ui/ptr_offset_by_literal.rs create mode 100644 tests/ui/ptr_offset_by_literal.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 78b81b5b74d6..6f666caf306f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,83 @@ document. ## Unreleased / Beta / In Rust Nightly -[e9b7045...master](https://github.com/rust-lang/rust-clippy/compare/e9b7045...master) +[d9fb15c...master](https://github.com/rust-lang/rust-clippy/compare/d9fb15c...master) + +## Rust 1.92 + +Current stable, released 2025-12-11 + +[View all 124 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-09-05T18%3A24%3A03Z..2025-10-16T14%3A13%3A43Z+base%3Amaster) + +### New Lints + +* Added [`unnecessary_option_map_or_else`] to `suspicious` + [#14662](https://github.com/rust-lang/rust-clippy/pull/14662) +* Added [`replace_box`] to `perf` + [#14953](https://github.com/rust-lang/rust-clippy/pull/14953) +* Added [`volatile_composites`] to `nursery` + [#15686](https://github.com/rust-lang/rust-clippy/pull/15686) +* Added [`self_only_used_in_recursion`] to `pedantic` + [#14787](https://github.com/rust-lang/rust-clippy/pull/14787) +* Added [`redundant_iter_cloned`] to `perf` + [#15277](https://github.com/rust-lang/rust-clippy/pull/15277) + +### Moves and Deprecations + +* Renamed [`unchecked_duration_subtraction`] to [`unchecked_time_subtraction`] + [#13800](https://github.com/rust-lang/rust-clippy/pull/13800) + +### Enhancements + +* [`mutex_atomic`] and [`mutex_integer`] overhauled to only lint definitions, not uses; added suggestions + and better help messages + [#15632](https://github.com/rust-lang/rust-clippy/pull/15632) +* [`manual_rotate`] now recognizes non-const rotation amounts + [#15402](https://github.com/rust-lang/rust-clippy/pull/15402) +* [`multiple_inherent_impl`] added `inherent-impl-lint-scope` config option (`module`, `file`, + or `crate`) + [#15843](https://github.com/rust-lang/rust-clippy/pull/15843) +* [`use_self`] now checks structs and enums + [#15566](https://github.com/rust-lang/rust-clippy/pull/15566) +* [`while_let_loop`] extended to lint on `loop { let else }` + [#15701](https://github.com/rust-lang/rust-clippy/pull/15701) +* [`mut_mut`] overhauled with structured suggestions and improved documentation + [#15417](https://github.com/rust-lang/rust-clippy/pull/15417) +* [`nonstandard_macro_braces`] now suggests trailing semicolon when needed + [#15593](https://github.com/rust-lang/rust-clippy/pull/15593) +* [`ptr_offset_with_cast`] now respects MSRV when suggesting fix, and lints more cases + [#15613](https://github.com/rust-lang/rust-clippy/pull/15613) +* [`cast_sign_loss`] and [`cast_possible_wrap`] added suggestions using `cast_{un,}signed()` methods + (MSRV 1.87+) + [#15384](https://github.com/rust-lang/rust-clippy/pull/15384) +* [`unchecked_time_subtraction`] extended to include `Duration - Duration` operations + [#13800](https://github.com/rust-lang/rust-clippy/pull/13800) +* [`filter_next`] now suggests replacing `filter().next_back()` with `rfind()` for + `DoubleEndedIterator` + [#15748](https://github.com/rust-lang/rust-clippy/pull/15748) + +### False Positive Fixes + +* [`unnecessary_safety_comment`] fixed FPs with comments above attributes + [#15678](https://github.com/rust-lang/rust-clippy/pull/15678) +* [`manual_unwrap_or`] fixed FP edge case + [#15812](https://github.com/rust-lang/rust-clippy/pull/15812) +* [`needless_continue`] fixed FP when match type is not unit or never + [#15547](https://github.com/rust-lang/rust-clippy/pull/15547) +* [`if_then_some_else_none`] fixed FP when return exists in block expr + [#15783](https://github.com/rust-lang/rust-clippy/pull/15783) +* [`new_without_default`] fixed to copy `#[cfg]` onto `impl Default` and fixed FP on private type + with trait impl + [#15720](https://github.com/rust-lang/rust-clippy/pull/15720) + [#15782](https://github.com/rust-lang/rust-clippy/pull/15782) +* [`question_mark`] fixed FP on variables used after + [#15644](https://github.com/rust-lang/rust-clippy/pull/15644) +* [`needless_return`] fixed FP with `cfg`d code after `return` + [#15669](https://github.com/rust-lang/rust-clippy/pull/15669) +* [`useless_attribute`] fixed FP on `deprecated_in_future` + [#15645](https://github.com/rust-lang/rust-clippy/pull/15645) +* [`double_parens`] fixed FP when macros are involved + [#15420](https://github.com/rust-lang/rust-clippy/pull/15420) ## Rust 1.91 @@ -6280,6 +6356,7 @@ Released 2018-09-13 [`cyclomatic_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#cyclomatic_complexity [`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro [`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call +[`decimal_bitwise_operands`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_bitwise_operands [`decimal_literal_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation [`declare_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const [`default_constructed_unit_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs @@ -6541,6 +6618,7 @@ Released 2018-09-13 [`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten [`manual_hash_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one [`manual_ignore_case_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ignore_case_cmp +[`manual_ilog2`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ilog2 [`manual_inspect`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_inspect [`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed [`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check @@ -6686,6 +6764,7 @@ Released 2018-09-13 [`needless_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return [`needless_return_with_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return_with_question_mark [`needless_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_splitn +[`needless_type_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_type_cast [`needless_update`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_update [`neg_cmp_op_on_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_cmp_op_on_partial_ord [`neg_multiply`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_multiply @@ -6765,6 +6844,7 @@ Released 2018-09-13 [`ptr_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr [`ptr_cast_constness`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_cast_constness [`ptr_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq +[`ptr_offset_by_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_by_literal [`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast [`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names [`pub_underscore_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields @@ -7081,6 +7161,7 @@ Released 2018-09-13 [`allow-expect-in-consts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-consts [`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests [`allow-indexing-slicing-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-indexing-slicing-in-tests +[`allow-large-stack-frames-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-large-stack-frames-in-tests [`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args [`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings [`allow-panic-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-panic-in-tests diff --git a/Cargo.toml b/Cargo.toml index fee885d8fa7e..67078adea2b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.93" +version = "0.1.94" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/README.md b/README.md index 20a5e997e629..78498c73ae78 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are over 800 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category. diff --git a/book/src/README.md b/book/src/README.md index 5d2c3972b060..c5b264c9f703 100644 --- a/book/src/README.md +++ b/book/src/README.md @@ -5,7 +5,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are over 800 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 2e185fb3a086..a1c079898594 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -111,6 +111,16 @@ Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]` * [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing) +## `allow-large-stack-frames-in-tests` +Whether functions inside `#[cfg(test)]` modules or test functions should be checked. + +**Default Value:** `true` + +--- +**Affected lints:** +* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames) + + ## `allow-mixed-uninlined-format-args` Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)` diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 3f6b26d3334e..a65fe7bcbda5 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.93" +version = "0.1.94" edition = "2024" publish = false diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 2e9cf8e91f7d..e1d7c1d88eb9 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -373,6 +373,9 @@ define_Conf! { /// Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]` #[lints(indexing_slicing)] allow_indexing_slicing_in_tests: bool = false, + /// Whether functions inside `#[cfg(test)]` modules or test functions should be checked. + #[lints(large_stack_frames)] + allow_large_stack_frames_in_tests: bool = true, /// Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)` #[lints(uninlined_format_args)] allow_mixed_uninlined_format_args: bool = true, diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index bc97746a1cba..7a78ef32bf3c 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.93" +version = "0.1.94" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 47cc1da0a6e9..494d6180d3cb 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -19,6 +19,7 @@ mod fn_to_numeric_cast; mod fn_to_numeric_cast_any; mod fn_to_numeric_cast_with_truncation; mod manual_dangling_ptr; +mod needless_type_cast; mod ptr_as_ptr; mod ptr_cast_constness; mod ref_as_ptr; @@ -813,6 +814,32 @@ declare_clippy_lint! { "casting a primitive method pointer to any integer type" } +declare_clippy_lint! { + /// ### What it does + /// Checks for bindings (constants, statics, or let bindings) that are defined + /// with one numeric type but are consistently cast to a different type in all usages. + /// + /// ### Why is this bad? + /// If a binding is always cast to a different type when used, it would be clearer + /// and more efficient to define it with the target type from the start. + /// + /// ### Example + /// ```no_run + /// const SIZE: u16 = 15; + /// let arr: [u8; SIZE as usize] = [0; SIZE as usize]; + /// ``` + /// + /// Use instead: + /// ```no_run + /// const SIZE: usize = 15; + /// let arr: [u8; SIZE] = [0; SIZE]; + /// ``` + #[clippy::version = "1.93.0"] + pub NEEDLESS_TYPE_CAST, + pedantic, + "binding defined with one type but always cast to another" +} + pub struct Casts { msrv: Msrv, } @@ -851,6 +878,7 @@ impl_lint_pass!(Casts => [ AS_POINTER_UNDERSCORE, MANUAL_DANGLING_PTR, CONFUSING_METHOD_TO_NUMERIC_CAST, + NEEDLESS_TYPE_CAST, ]); impl<'tcx> LateLintPass<'tcx> for Casts { @@ -920,4 +948,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts { cast_slice_different_sizes::check(cx, expr, self.msrv); ptr_cast_constness::check_null_ptr_cast_method(cx, expr); } + + fn check_body(&mut self, cx: &LateContext<'tcx>, body: &rustc_hir::Body<'tcx>) { + needless_type_cast::check(cx, body); + } } diff --git a/clippy_lints/src/casts/needless_type_cast.rs b/clippy_lints/src/casts/needless_type_cast.rs new file mode 100644 index 000000000000..ca6aa0f87bbf --- /dev/null +++ b/clippy_lints/src/casts/needless_type_cast.rs @@ -0,0 +1,289 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::visitors::{Descend, for_each_expr, for_each_expr_without_closures}; +use core::ops::ControlFlow; +use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{BlockCheckMode, Body, Expr, ExprKind, HirId, LetStmt, PatKind, StmtKind, UnsafeSource}; +use rustc_lint::LateContext; +use rustc_middle::ty::{Ty, TypeVisitableExt}; +use rustc_span::Span; + +use super::NEEDLESS_TYPE_CAST; + +struct BindingInfo<'a> { + source_ty: Ty<'a>, + ty_span: Span, +} + +struct UsageInfo<'a> { + cast_to: Option>, + in_generic_context: bool, +} + +pub(super) fn check<'a>(cx: &LateContext<'a>, body: &Body<'a>) { + let mut bindings: FxHashMap> = FxHashMap::default(); + + for_each_expr_without_closures(body.value, |expr| { + match expr.kind { + ExprKind::Block(block, _) => { + for stmt in block.stmts { + if let StmtKind::Let(let_stmt) = stmt.kind { + collect_binding_from_local(cx, let_stmt, &mut bindings); + } + } + }, + ExprKind::Let(let_expr) => { + collect_binding_from_let(cx, let_expr, &mut bindings); + }, + _ => {}, + } + ControlFlow::<()>::Continue(()) + }); + + #[allow(rustc::potential_query_instability)] + let mut binding_vec: Vec<_> = bindings.into_iter().collect(); + binding_vec.sort_by_key(|(_, info)| info.ty_span.lo()); + + for (hir_id, binding_info) in binding_vec { + check_binding_usages(cx, body, hir_id, &binding_info); + } +} + +fn collect_binding_from_let<'a>( + cx: &LateContext<'a>, + let_expr: &rustc_hir::LetExpr<'a>, + bindings: &mut FxHashMap>, +) { + if let_expr.ty.is_none() + || let_expr.span.from_expansion() + || has_generic_return_type(cx, let_expr.init) + || contains_unsafe(let_expr.init) + { + return; + } + + if let PatKind::Binding(_, hir_id, _, _) = let_expr.pat.kind + && let Some(ty_hir) = let_expr.ty + { + let ty = cx.typeck_results().pat_ty(let_expr.pat); + if ty.is_numeric() { + bindings.insert( + hir_id, + BindingInfo { + source_ty: ty, + ty_span: ty_hir.span, + }, + ); + } + } +} + +fn collect_binding_from_local<'a>( + cx: &LateContext<'a>, + let_stmt: &LetStmt<'a>, + bindings: &mut FxHashMap>, +) { + if let_stmt.ty.is_none() + || let_stmt.span.from_expansion() + || let_stmt + .init + .is_some_and(|init| has_generic_return_type(cx, init) || contains_unsafe(init)) + { + return; + } + + if let PatKind::Binding(_, hir_id, _, _) = let_stmt.pat.kind + && let Some(ty_hir) = let_stmt.ty + { + let ty = cx.typeck_results().pat_ty(let_stmt.pat); + if ty.is_numeric() { + bindings.insert( + hir_id, + BindingInfo { + source_ty: ty, + ty_span: ty_hir.span, + }, + ); + } + } +} + +fn contains_unsafe(expr: &Expr<'_>) -> bool { + for_each_expr_without_closures(expr, |e| { + if let ExprKind::Block(block, _) = e.kind + && let BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) = block.rules + { + return ControlFlow::Break(()); + } + ControlFlow::Continue(()) + }) + .is_some() +} + +fn has_generic_return_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + match &expr.kind { + ExprKind::Block(block, _) => { + if let Some(tail_expr) = block.expr { + return has_generic_return_type(cx, tail_expr); + } + false + }, + ExprKind::If(_, then_block, else_expr) => { + has_generic_return_type(cx, then_block) || else_expr.is_some_and(|e| has_generic_return_type(cx, e)) + }, + ExprKind::Match(_, arms, _) => arms.iter().any(|arm| has_generic_return_type(cx, arm.body)), + ExprKind::Loop(block, label, ..) => for_each_expr_without_closures(*block, |e| { + match e.kind { + ExprKind::Loop(..) => { + // Unlabeled breaks inside nested loops target the inner loop, not ours + return ControlFlow::Continue(Descend::No); + }, + ExprKind::Break(dest, Some(break_expr)) => { + let targets_this_loop = + dest.label.is_none() || dest.label.map(|l| l.ident) == label.map(|l| l.ident); + if targets_this_loop && has_generic_return_type(cx, break_expr) { + return ControlFlow::Break(()); + } + }, + _ => {}, + } + ControlFlow::Continue(Descend::Yes) + }) + .is_some(), + ExprKind::MethodCall(..) => { + if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { + let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let ret_ty = sig.output().skip_binder(); + return ret_ty.has_param(); + } + false + }, + ExprKind::Call(callee, _) => { + if let ExprKind::Path(qpath) = &callee.kind { + let res = cx.qpath_res(qpath, callee.hir_id); + if let Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) = res { + let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let ret_ty = sig.output().skip_binder(); + return ret_ty.has_param(); + } + } + false + }, + _ => false, + } +} + +fn is_generic_res(cx: &LateContext<'_>, res: Res) -> bool { + let has_type_params = |def_id| { + cx.tcx + .generics_of(def_id) + .own_params + .iter() + .any(|p| p.kind.is_ty_or_const()) + }; + match res { + Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => has_type_params(def_id), + // Ctor → Variant → ADT: constructor's parent is variant, variant's parent is the ADT + Res::Def(DefKind::Ctor(..), def_id) => has_type_params(cx.tcx.parent(cx.tcx.parent(def_id))), + _ => false, + } +} + +fn is_cast_in_generic_context<'a>(cx: &LateContext<'a>, cast_expr: &Expr<'a>) -> bool { + let mut current_id = cast_expr.hir_id; + + loop { + let parent_id = cx.tcx.parent_hir_id(current_id); + if parent_id == current_id { + return false; + } + + let parent = cx.tcx.hir_node(parent_id); + + match parent { + rustc_hir::Node::Expr(parent_expr) => { + match &parent_expr.kind { + ExprKind::Closure(_) => return false, + ExprKind::Call(callee, _) => { + if let ExprKind::Path(qpath) = &callee.kind { + let res = cx.qpath_res(qpath, callee.hir_id); + if is_generic_res(cx, res) { + return true; + } + } + }, + ExprKind::MethodCall(..) => { + if let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent_expr.hir_id) + && cx + .tcx + .generics_of(def_id) + .own_params + .iter() + .any(|p| p.kind.is_ty_or_const()) + { + return true; + } + }, + _ => {}, + } + current_id = parent_id; + }, + _ => return false, + } + } +} + +fn check_binding_usages<'a>(cx: &LateContext<'a>, body: &Body<'a>, hir_id: HirId, binding_info: &BindingInfo<'a>) { + let mut usages = Vec::new(); + + for_each_expr(cx, body.value, |expr| { + if let ExprKind::Path(ref qpath) = expr.kind + && !expr.span.from_expansion() + && let Res::Local(id) = cx.qpath_res(qpath, expr.hir_id) + && id == hir_id + { + let parent_id = cx.tcx.parent_hir_id(expr.hir_id); + let parent = cx.tcx.hir_node(parent_id); + + let usage = if let rustc_hir::Node::Expr(parent_expr) = parent + && let ExprKind::Cast(..) = parent_expr.kind + && !parent_expr.span.from_expansion() + { + UsageInfo { + cast_to: Some(cx.typeck_results().expr_ty(parent_expr)), + in_generic_context: is_cast_in_generic_context(cx, parent_expr), + } + } else { + UsageInfo { + cast_to: None, + in_generic_context: false, + } + }; + usages.push(usage); + } + ControlFlow::<()>::Continue(()) + }); + + let Some(first_target) = usages + .first() + .and_then(|u| u.cast_to) + .filter(|&t| t != binding_info.source_ty) + .filter(|&t| usages.iter().all(|u| u.cast_to == Some(t) && !u.in_generic_context)) + else { + return; + }; + + span_lint_and_sugg( + cx, + NEEDLESS_TYPE_CAST, + binding_info.ty_span, + format!( + "this binding is defined as `{}` but is always cast to `{}`", + binding_info.source_ty, first_target + ), + "consider defining it as", + first_target.to_string(), + Applicability::MaybeIncorrect, + ); +} diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 4a350dca2993..87d75234ebc0 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -70,6 +70,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO, crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO, crate::casts::MANUAL_DANGLING_PTR_INFO, + crate::casts::NEEDLESS_TYPE_CAST_INFO, crate::casts::PTR_AS_PTR_INFO, crate::casts::PTR_CAST_CONSTNESS_INFO, crate::casts::REF_AS_PTR_INFO, @@ -245,8 +246,8 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::large_stack_arrays::LARGE_STACK_ARRAYS_INFO, crate::large_stack_frames::LARGE_STACK_FRAMES_INFO, crate::legacy_numeric_constants::LEGACY_NUMERIC_CONSTANTS_INFO, + crate::len_without_is_empty::LEN_WITHOUT_IS_EMPTY_INFO, crate::len_zero::COMPARISON_TO_EMPTY_INFO, - crate::len_zero::LEN_WITHOUT_IS_EMPTY_INFO, crate::len_zero::LEN_ZERO_INFO, crate::let_if_seq::USELESS_LET_IF_SEQ_INFO, crate::let_underscore::LET_UNDERSCORE_FUTURE_INFO, @@ -300,6 +301,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::manual_float_methods::MANUAL_IS_INFINITE_INFO, crate::manual_hash_one::MANUAL_HASH_ONE_INFO, crate::manual_ignore_case_cmp::MANUAL_IGNORE_CASE_CMP_INFO, + crate::manual_ilog2::MANUAL_ILOG2_INFO, crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO, crate::manual_is_power_of_two::MANUAL_IS_POWER_OF_TWO_INFO, crate::manual_let_else::MANUAL_LET_ELSE_INFO, @@ -444,6 +446,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::methods::OR_THEN_UNWRAP_INFO, crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO, crate::methods::PATH_ENDS_WITH_EXT_INFO, + crate::methods::PTR_OFFSET_BY_LITERAL_INFO, crate::methods::PTR_OFFSET_WITH_CAST_INFO, crate::methods::RANGE_ZIP_WITH_LEN_INFO, crate::methods::READONLY_WRITE_LOCK_INFO, @@ -578,6 +581,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::operators::ASSIGN_OP_PATTERN_INFO, crate::operators::BAD_BIT_MASK_INFO, crate::operators::CMP_OWNED_INFO, + crate::operators::DECIMAL_BITWISE_OPERANDS_INFO, crate::operators::DOUBLE_COMPARISONS_INFO, crate::operators::DURATION_SUBSEC_INFO, crate::operators::EQ_OP_INFO, diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs index f010d17917f9..6e62e983d2f3 100644 --- a/clippy_lints/src/deprecated_lints.rs +++ b/clippy_lints/src/deprecated_lints.rs @@ -34,7 +34,7 @@ declare_with_version! { DEPRECATED(DEPRECATED_VERSION) = [ #[clippy::version = "pre 1.29.0"] ("clippy::should_assert_eq", "`assert!(a == b)` can now print the values the same way `assert_eq!(a, b) can"), #[clippy::version = "1.91.0"] - ("clippy::string_to_string", "`clippy:implicit_clone` covers those cases"), + ("clippy::string_to_string", "`clippy::implicit_clone` covers those cases"), #[clippy::version = "pre 1.29.0"] ("clippy::unsafe_vector_initialization", "the suggested alternative could be substantially slower"), #[clippy::version = "pre 1.29.0"] diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index a5ec6777b434..bdfe2e49e66e 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -3,11 +3,12 @@ use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_appl use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_expr; use clippy_utils::{ - SpanlessEq, can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified, - peel_hir_expr_while, + SpanlessEq, can_move_expr_to_closure_no_visit, desugar_await, higher, is_expr_final_block_expr, + is_expr_used_or_unified, paths, peel_hir_expr_while, }; use core::fmt::{self, Write}; use rustc_errors::Applicability; +use rustc_hir::def_id::DefId; use rustc_hir::hir_id::HirIdSet; use rustc_hir::intravisit::{Visitor, walk_body, walk_expr}; use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp}; @@ -382,6 +383,8 @@ struct InsertSearcher<'cx, 'tcx> { loops: Vec, /// Local variables created in the expression. These don't need to be captured. locals: HirIdSet, + /// Whether the map is a non-async-aware `MutexGuard`. + map_is_mutex_guard: bool, } impl<'tcx> InsertSearcher<'_, 'tcx> { /// Visit the expression as a branch in control flow. Multiple insert calls can be used, but @@ -524,15 +527,22 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> { ExprKind::If(cond_expr, then_expr, Some(else_expr)) => { self.is_single_insert = false; self.visit_non_tail_expr(cond_expr); - // Each branch may contain it's own insert expression. + // Each branch may contain its own insert expression. let mut is_map_used = self.visit_cond_arm(then_expr); is_map_used |= self.visit_cond_arm(else_expr); self.is_map_used = is_map_used; }, ExprKind::Match(scrutinee_expr, arms, _) => { + // If the map is a non-async-aware `MutexGuard` and + // `.await` expression appears alongside map insertion in the same `then` or `else` block, + // we cannot suggest using `entry()` because it would hold the lock across the await point, + // triggering `await_holding_lock` and risking deadlock. + if self.map_is_mutex_guard && desugar_await(expr).is_some() { + self.can_use_entry = false; + } self.is_single_insert = false; self.visit_non_tail_expr(scrutinee_expr); - // Each branch may contain it's own insert expression. + // Each branch may contain its own insert expression. let mut is_map_used = self.is_map_used; for arm in arms { self.visit_pat(arm.pat); @@ -725,16 +735,32 @@ fn find_insert_calls<'tcx>( edits: Vec::new(), loops: Vec::new(), locals: HirIdSet::default(), + map_is_mutex_guard: false, }; + // Check if the map is a non-async-aware `MutexGuard` + if let rustc_middle::ty::Adt(adt, _) = cx.typeck_results().expr_ty(contains_expr.map).kind() + && is_mutex_guard(cx, adt.did()) + { + s.map_is_mutex_guard = true; + } + s.visit_expr(expr); - let allow_insert_closure = s.allow_insert_closure; - let is_single_insert = s.is_single_insert; + if !s.can_use_entry { + return None; + } + let is_key_used_and_no_copy = s.is_key_used && !is_copy(cx, cx.typeck_results().expr_ty(contains_expr.key)); - let edits = s.edits; - s.can_use_entry.then_some(InsertSearchResults { - edits, - allow_insert_closure, - is_single_insert, + Some(InsertSearchResults { + edits: s.edits, + allow_insert_closure: s.allow_insert_closure, + is_single_insert: s.is_single_insert, is_key_used_and_no_copy, }) } + +fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool { + match cx.tcx.get_diagnostic_name(def_id) { + Some(name) => matches!(name, sym::MutexGuard | sym::RwLockReadGuard | sym::RwLockWriteGuard), + None => paths::PARKING_LOT_GUARDS.iter().any(|guard| guard.matches(cx, def_id)), + } +} diff --git a/clippy_lints/src/large_stack_frames.rs b/clippy_lints/src/large_stack_frames.rs index 5ed948c02bbc..6b0080d04c44 100644 --- a/clippy_lints/src/large_stack_frames.rs +++ b/clippy_lints/src/large_stack_frames.rs @@ -2,15 +2,16 @@ use std::{fmt, ops}; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::fn_has_unsatisfiable_preds; -use clippy_utils::source::SpanRangeExt; +use clippy_utils::source::{HasSession, SpanRangeExt}; +use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_in_test}; +use rustc_errors::Diag; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::FnKind; use rustc_hir::{Body, FnDecl}; use rustc_lexer::is_ident; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::Span; +use rustc_span::{Span, SyntaxContext}; declare_clippy_lint! { /// ### What it does @@ -83,12 +84,14 @@ declare_clippy_lint! { pub struct LargeStackFrames { maximum_allowed_size: u64, + allow_large_stack_frames_in_tests: bool, } impl LargeStackFrames { pub fn new(conf: &'static Conf) -> Self { Self { maximum_allowed_size: conf.stack_size_threshold, + allow_large_stack_frames_in_tests: conf.allow_large_stack_frames_in_tests, } } } @@ -152,67 +155,122 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackFrames { let mir = cx.tcx.optimized_mir(def_id); let typing_env = mir.typing_env(cx.tcx); - let sizes_of_locals = || { - mir.local_decls.iter().filter_map(|local| { + let sizes_of_locals = mir + .local_decls + .iter() + .filter_map(|local| { let layout = cx.tcx.layout_of(typing_env.as_query_input(local.ty)).ok()?; Some((local, layout.size.bytes())) }) - }; + .collect::>(); - let frame_size = sizes_of_locals().fold(Space::Used(0), |sum, (_, size)| sum + size); + let frame_size = sizes_of_locals + .iter() + .fold(Space::Used(0), |sum, (_, size)| sum + *size); let limit = self.maximum_allowed_size; if frame_size.exceeds_limit(limit) { // Point at just the function name if possible, because lints that span // the entire body and don't have to are less legible. - let fn_span = match fn_kind { - FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span, - FnKind::Closure => entire_fn_span, + let (fn_span, fn_name) = match fn_kind { + FnKind::ItemFn(ident, _, _) => (ident.span, format!("function `{}`", ident.name)), + FnKind::Method(ident, _) => (ident.span, format!("method `{}`", ident.name)), + FnKind::Closure => (entire_fn_span, "closure".to_string()), }; + // Don't lint inside tests if configured to not do so. + if self.allow_large_stack_frames_in_tests && is_in_test(cx.tcx, cx.tcx.local_def_id_to_hir_id(local_def_id)) + { + return; + } + + let explain_lint = |diag: &mut Diag<'_, ()>, ctxt: SyntaxContext| { + // Point out the largest individual contribution to this size, because + // it is the most likely to be unintentionally large. + if let Some((local, size)) = sizes_of_locals.iter().max_by_key(|&(_, size)| size) + && let local_span = local.source_info.span + && local_span.ctxt() == ctxt + { + let size = Space::Used(*size); // pluralizes for us + let ty = local.ty; + + // TODO: Is there a cleaner, robust way to ask this question? + // The obvious `LocalDecl::is_user_variable()` panics on "unwrapping cross-crate data", + // and that doesn't get us the true name in scope rather than the span text either. + if let Some(name) = local_span.get_source_text(cx) + && is_ident(&name) + { + // If the local is an ordinary named variable, + // print its name rather than relying solely on the span. + diag.span_label( + local_span, + format!("`{name}` is the largest part, at {size} for type `{ty}`"), + ); + } else { + diag.span_label( + local_span, + format!("this is the largest part, at {size} for type `{ty}`"), + ); + } + } + + // Explain why we are linting this and not other functions. + diag.note(format!( + "{frame_size} is larger than Clippy's configured `stack-size-threshold` of {limit}" + )); + + // Explain why the user should care, briefly. + diag.note_once( + "allocating large amounts of stack space can overflow the stack \ + and cause the program to abort", + ); + }; + + if fn_span.from_expansion() { + // Don't lint on the main function generated by `--test` target + if cx.sess().is_test_crate() && is_entrypoint_fn(cx, local_def_id.to_def_id()) { + return; + } + + let is_from_external_macro = fn_span.in_external_macro(cx.sess().source_map()); + span_lint_and_then( + cx, + LARGE_STACK_FRAMES, + fn_span.source_callsite(), + format!( + "{} generated by this macro may allocate a lot of stack space", + if is_from_external_macro { + cx.tcx.def_descr(local_def_id.into()) + } else { + fn_name.as_str() + } + ), + |diag| { + if is_from_external_macro { + return; + } + + diag.span_label( + fn_span, + format!( + "this {} has a stack frame size of {frame_size}", + cx.tcx.def_descr(local_def_id.into()) + ), + ); + + explain_lint(diag, fn_span.ctxt()); + }, + ); + return; + } + span_lint_and_then( cx, LARGE_STACK_FRAMES, fn_span, format!("this function may allocate {frame_size} on the stack"), |diag| { - // Point out the largest individual contribution to this size, because - // it is the most likely to be unintentionally large. - if let Some((local, size)) = sizes_of_locals().max_by_key(|&(_, size)| size) { - let local_span: Span = local.source_info.span; - let size = Space::Used(size); // pluralizes for us - let ty = local.ty; - - // TODO: Is there a cleaner, robust way to ask this question? - // The obvious `LocalDecl::is_user_variable()` panics on "unwrapping cross-crate data", - // and that doesn't get us the true name in scope rather than the span text either. - if let Some(name) = local_span.get_source_text(cx) - && is_ident(&name) - { - // If the local is an ordinary named variable, - // print its name rather than relying solely on the span. - diag.span_label( - local_span, - format!("`{name}` is the largest part, at {size} for type `{ty}`"), - ); - } else { - diag.span_label( - local_span, - format!("this is the largest part, at {size} for type `{ty}`"), - ); - } - } - - // Explain why we are linting this and not other functions. - diag.note(format!( - "{frame_size} is larger than Clippy's configured `stack-size-threshold` of {limit}" - )); - - // Explain why the user should care, briefly. - diag.note_once( - "allocating large amounts of stack space can overflow the stack \ - and cause the program to abort", - ); + explain_lint(diag, SyntaxContext::root()); }, ); } diff --git a/clippy_lints/src/len_without_is_empty.rs b/clippy_lints/src/len_without_is_empty.rs new file mode 100644 index 000000000000..1d219d7c3b74 --- /dev/null +++ b/clippy_lints/src/len_without_is_empty.rs @@ -0,0 +1,342 @@ +use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; +use clippy_utils::res::MaybeDef; +use clippy_utils::{fulfill_or_allowed, get_parent_as_impl, sym}; +use rustc_hir::def::Res; +use rustc_hir::def_id::{DefId, DefIdSet}; +use rustc_hir::{ + FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind, ImplicitSelfKind, Item, ItemKind, Mutability, + Node, OpaqueTyOrigin, PathSegment, PrimTy, QPath, TraitItemId, TyKind, +}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::{self, FnSig, Ty}; +use rustc_session::declare_lint_pass; +use rustc_span::symbol::kw; +use rustc_span::{Ident, Span, Symbol}; +use rustc_trait_selection::traits::supertrait_def_ids; + +declare_clippy_lint! { + /// ### What it does + /// Checks for items that implement `.len()` but not + /// `.is_empty()`. + /// + /// ### Why is this bad? + /// It is good custom to have both methods, because for + /// some data structures, asking about the length will be a costly operation, + /// whereas `.is_empty()` can usually answer in constant time. Also it used to + /// lead to false positives on the [`len_zero`](#len_zero) lint – currently that + /// lint will ignore such entities. + /// + /// ### Example + /// ```ignore + /// impl X { + /// pub fn len(&self) -> usize { + /// .. + /// } + /// } + /// ``` + #[clippy::version = "pre 1.29.0"] + pub LEN_WITHOUT_IS_EMPTY, + style, + "traits or impls with a public `len` method but no corresponding `is_empty` method" +} + +declare_lint_pass!(LenWithoutIsEmpty => [LEN_WITHOUT_IS_EMPTY]); + +impl<'tcx> LateLintPass<'tcx> for LenWithoutIsEmpty { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { + if let ItemKind::Trait(_, _, _, ident, _, _, trait_items) = item.kind + && !item.span.from_expansion() + { + check_trait_items(cx, item, ident, trait_items); + } + } + + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { + if item.ident.name == sym::len + && let ImplItemKind::Fn(sig, _) = &item.kind + && sig.decl.implicit_self.has_implicit_self() + && sig.decl.inputs.len() == 1 + && cx.effective_visibilities.is_exported(item.owner_id.def_id) + && matches!(sig.decl.output, FnRetTy::Return(_)) + && let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id()) + && imp.of_trait.is_none() + && let TyKind::Path(ty_path) = &imp.self_ty.kind + && let Some(ty_id) = cx.qpath_res(ty_path, imp.self_ty.hir_id).opt_def_id() + && let Some(local_id) = ty_id.as_local() + && let ty_hir_id = cx.tcx.local_def_id_to_hir_id(local_id) + && let Some(output) = LenOutput::new(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()) + { + let (name, kind) = match cx.tcx.hir_node(ty_hir_id) { + Node::ForeignItem(x) => (x.ident.name, "extern type"), + Node::Item(x) => match x.kind { + ItemKind::Struct(ident, ..) => (ident.name, "struct"), + ItemKind::Enum(ident, ..) => (ident.name, "enum"), + ItemKind::Union(ident, ..) => (ident.name, "union"), + _ => (x.kind.ident().unwrap().name, "type"), + }, + _ => return, + }; + check_for_is_empty( + cx, + sig.span, + sig.decl.implicit_self, + output, + ty_id, + name, + kind, + item.hir_id(), + ty_hir_id, + ); + } + } +} + +fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemId]) { + fn is_named_self(cx: &LateContext<'_>, item: TraitItemId, name: Symbol) -> bool { + cx.tcx.item_name(item.owner_id) == name + && matches!( + cx.tcx.fn_arg_idents(item.owner_id), + [Some(Ident { + name: kw::SelfLower, + .. + })], + ) + } + + // fill the set with current and super traits + fn fill_trait_set(traitt: DefId, set: &mut DefIdSet, cx: &LateContext<'_>) { + if set.insert(traitt) { + for supertrait in supertrait_def_ids(cx.tcx, traitt) { + fill_trait_set(supertrait, set, cx); + } + } + } + + if cx.effective_visibilities.is_exported(visited_trait.owner_id.def_id) + && trait_items.iter().any(|&i| is_named_self(cx, i, sym::len)) + { + let mut current_and_super_traits = DefIdSet::default(); + fill_trait_set(visited_trait.owner_id.to_def_id(), &mut current_and_super_traits, cx); + let is_empty_method_found = current_and_super_traits + .items() + .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(sym::is_empty)) + .any(|i| i.is_method() && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1); + + if !is_empty_method_found { + span_lint( + cx, + LEN_WITHOUT_IS_EMPTY, + visited_trait.span, + format!( + "trait `{}` has a `len` method but no (possibly inherited) `is_empty` method", + ident.name + ), + ); + } + } +} + +fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { + if let ty::Alias(_, alias_ty) = ty.kind() + && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(alias_ty.def_id) + && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin + && let [GenericBound::Trait(trait_ref)] = &opaque.bounds + && let Some(segment) = trait_ref.trait_ref.path.segments.last() + && let Some(generic_args) = segment.args + && let [constraint] = generic_args.constraints + && let Some(ty) = constraint.ty() + && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind + && let [segment] = path.segments + { + return Some(segment); + } + + None +} + +fn is_first_generic_integral<'tcx>(segment: &'tcx PathSegment<'tcx>) -> bool { + if let Some(generic_args) = segment.args + && let [GenericArg::Type(ty), ..] = &generic_args.args + && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind + && let [segment, ..] = &path.segments + && matches!(segment.res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) + { + true + } else { + false + } +} + +#[derive(Debug, Clone, Copy)] +enum LenOutput { + Integral, + Option(DefId), + Result(DefId), +} + +impl LenOutput { + fn new<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option { + if let Some(segment) = extract_future_output(cx, sig.output()) { + let res = segment.res; + + if matches!(res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) { + return Some(Self::Integral); + } + + if let Res::Def(_, def_id) = res + && let Some(res) = match cx.tcx.get_diagnostic_name(def_id) { + Some(sym::Option) => Some(Self::Option(def_id)), + Some(sym::Result) => Some(Self::Result(def_id)), + _ => None, + } + && is_first_generic_integral(segment) + { + return Some(res); + } + + return None; + } + + match *sig.output().kind() { + ty::Int(_) | ty::Uint(_) => Some(Self::Integral), + ty::Adt(adt, subs) => match cx.tcx.get_diagnostic_name(adt.did()) { + Some(sym::Option) => subs.type_at(0).is_integral().then(|| Self::Option(adt.did())), + Some(sym::Result) => subs.type_at(0).is_integral().then(|| Self::Result(adt.did())), + _ => None, + }, + _ => None, + } + } + + fn matches_is_empty_output<'tcx>(self, cx: &LateContext<'tcx>, is_empty_output: Ty<'tcx>) -> bool { + if let Some(segment) = extract_future_output(cx, is_empty_output) { + return match (self, segment.res) { + (_, Res::PrimTy(PrimTy::Bool)) => true, + (Self::Option(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Option, def_id) => true, + (Self::Result(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Result, def_id) => true, + _ => false, + }; + } + + match (self, is_empty_output.kind()) { + (_, &ty::Bool) => true, + (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), + (Self::Result(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), + _ => false, + } + } +} + +/// The expected signature of `is_empty`, based on that of `len` +fn expected_is_empty_sig(len_output: LenOutput, len_self_kind: ImplicitSelfKind) -> String { + let self_ref = match len_self_kind { + ImplicitSelfKind::RefImm => "&", + ImplicitSelfKind::RefMut => "&(mut) ", + _ => "", + }; + match len_output { + LenOutput::Integral => format!("expected signature: `({self_ref}self) -> bool`"), + LenOutput::Option(_) => { + format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Option") + }, + LenOutput::Result(..) => { + format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Result") + }, + } +} + +/// Checks if the given signature matches the expectations for `is_empty` +fn check_is_empty_sig<'tcx>( + cx: &LateContext<'tcx>, + is_empty_sig: FnSig<'tcx>, + len_self_kind: ImplicitSelfKind, + len_output: LenOutput, +) -> bool { + if let [is_empty_self_arg, is_empty_output] = &**is_empty_sig.inputs_and_output + && len_output.matches_is_empty_output(cx, *is_empty_output) + { + match (is_empty_self_arg.kind(), len_self_kind) { + // if `len` takes `&self`, `is_empty` should do so as well + (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::RefImm) + // if `len` takes `&mut self`, `is_empty` may take that _or_ `&self` (#16190) + | (ty::Ref(_, _, Mutability::Mut | Mutability::Not), ImplicitSelfKind::RefMut) => true, + // if len takes `self`, `is_empty` should do so as well + // XXX: we might want to relax this to allow `&self` and `&mut self` + (_, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut) if !is_empty_self_arg.is_ref() => true, + _ => false, + } + } else { + false + } +} + +/// Checks if the given type has an `is_empty` method with the appropriate signature. +#[expect(clippy::too_many_arguments)] +fn check_for_is_empty( + cx: &LateContext<'_>, + len_span: Span, + len_self_kind: ImplicitSelfKind, + len_output: LenOutput, + impl_ty: DefId, + item_name: Symbol, + item_kind: &str, + len_method_hir_id: HirId, + ty_decl_hir_id: HirId, +) { + // Implementor may be a type alias, in which case we need to get the `DefId` of the aliased type to + // find the correct inherent impls. + let impl_ty = if let Some(adt) = cx.tcx.type_of(impl_ty).skip_binder().ty_adt_def() { + adt.did() + } else { + return; + }; + + let is_empty = cx + .tcx + .inherent_impls(impl_ty) + .iter() + .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(sym::is_empty)) + .find(|item| item.is_fn()); + + let (msg, is_empty_span, is_empty_expected_sig) = match is_empty { + None => ( + format!("{item_kind} `{item_name}` has a public `len` method, but no `is_empty` method"), + None, + None, + ), + Some(is_empty) if !cx.effective_visibilities.is_exported(is_empty.def_id.expect_local()) => ( + format!("{item_kind} `{item_name}` has a public `len` method, but a private `is_empty` method"), + Some(cx.tcx.def_span(is_empty.def_id)), + None, + ), + Some(is_empty) + if !(is_empty.is_method() + && check_is_empty_sig( + cx, + cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(), + len_self_kind, + len_output, + )) => + { + ( + format!( + "{item_kind} `{item_name}` has a public `len` method, but the `is_empty` method has an unexpected signature", + ), + Some(cx.tcx.def_span(is_empty.def_id)), + Some(expected_is_empty_sig(len_output, len_self_kind)), + ) + }, + Some(_) => return, + }; + + if !fulfill_or_allowed(cx, LEN_WITHOUT_IS_EMPTY, [len_method_hir_id, ty_decl_hir_id]) { + span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, len_span, msg, |db| { + if let Some(span) = is_empty_span { + db.span_note(span, "`is_empty` defined here"); + } + if let Some(expected_sig) = is_empty_expected_sig { + db.note(expected_sig); + } + }); + } +} diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 877bd34a732b..2e576da38b89 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -1,27 +1,20 @@ use clippy_config::Conf; -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::Msrv; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; use clippy_utils::source::{SpanRangeExt, snippet_with_context}; use clippy_utils::sugg::{Sugg, has_enclosing_paren}; use clippy_utils::ty::implements_trait; -use clippy_utils::{fulfill_or_allowed, get_parent_as_impl, parent_item_name, peel_ref_operators, sym}; +use clippy_utils::{parent_item_name, peel_ref_operators, sym}; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; -use rustc_hir::def::Res; -use rustc_hir::def_id::{DefId, DefIdSet}; -use rustc_hir::{ - BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind, ImplicitSelfKind, - Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatExprKind, PatKind, PathSegment, PrimTy, QPath, RustcVersion, - StabilityLevel, StableSince, TraitItemId, TyKind, -}; +use rustc_hir::def_id::DefId; +use rustc_hir::{BinOpKind, Expr, ExprKind, PatExprKind, PatKind, RustcVersion, StabilityLevel, StableSince}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, FnSig, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use rustc_span::source_map::Spanned; -use rustc_span::symbol::kw; -use rustc_span::{Ident, Span, Symbol}; -use rustc_trait_selection::traits::supertrait_def_ids; +use rustc_span::{Span, Symbol}; declare_clippy_lint! { /// ### What it does @@ -58,32 +51,6 @@ declare_clippy_lint! { "checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` could be used instead" } -declare_clippy_lint! { - /// ### What it does - /// Checks for items that implement `.len()` but not - /// `.is_empty()`. - /// - /// ### Why is this bad? - /// It is good custom to have both methods, because for - /// some data structures, asking about the length will be a costly operation, - /// whereas `.is_empty()` can usually answer in constant time. Also it used to - /// lead to false positives on the [`len_zero`](#len_zero) lint – currently that - /// lint will ignore such entities. - /// - /// ### Example - /// ```ignore - /// impl X { - /// pub fn len(&self) -> usize { - /// .. - /// } - /// } - /// ``` - #[clippy::version = "pre 1.29.0"] - pub LEN_WITHOUT_IS_EMPTY, - style, - "traits or impls with a public `len` method but no corresponding `is_empty` method" -} - declare_clippy_lint! { /// ### What it does /// Checks for comparing to an empty slice such as `""` or `[]`, @@ -126,7 +93,7 @@ pub struct LenZero { msrv: Msrv, } -impl_lint_pass!(LenZero => [LEN_ZERO, LEN_WITHOUT_IS_EMPTY, COMPARISON_TO_EMPTY]); +impl_lint_pass!(LenZero => [LEN_ZERO, COMPARISON_TO_EMPTY]); impl LenZero { pub fn new(conf: &'static Conf) -> Self { @@ -135,54 +102,6 @@ impl LenZero { } impl<'tcx> LateLintPass<'tcx> for LenZero { - fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Trait(_, _, _, ident, _, _, trait_items) = item.kind - && !item.span.from_expansion() - { - check_trait_items(cx, item, ident, trait_items); - } - } - - fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { - if item.ident.name == sym::len - && let ImplItemKind::Fn(sig, _) = &item.kind - && sig.decl.implicit_self.has_implicit_self() - && sig.decl.inputs.len() == 1 - && cx.effective_visibilities.is_exported(item.owner_id.def_id) - && matches!(sig.decl.output, FnRetTy::Return(_)) - && let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id()) - && imp.of_trait.is_none() - && let TyKind::Path(ty_path) = &imp.self_ty.kind - && let Some(ty_id) = cx.qpath_res(ty_path, imp.self_ty.hir_id).opt_def_id() - && let Some(local_id) = ty_id.as_local() - && let ty_hir_id = cx.tcx.local_def_id_to_hir_id(local_id) - && let Some(output) = - parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()) - { - let (name, kind) = match cx.tcx.hir_node(ty_hir_id) { - Node::ForeignItem(x) => (x.ident.name, "extern type"), - Node::Item(x) => match x.kind { - ItemKind::Struct(ident, ..) => (ident.name, "struct"), - ItemKind::Enum(ident, ..) => (ident.name, "enum"), - ItemKind::Union(ident, ..) => (ident.name, "union"), - _ => (x.kind.ident().unwrap().name, "type"), - }, - _ => return, - }; - check_for_is_empty( - cx, - sig.span, - sig.decl.implicit_self, - output, - ty_id, - name, - kind, - item.hir_id(), - ty_hir_id, - ); - } - } - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Let(lt) = expr.kind && match lt.pat.kind { @@ -356,256 +275,6 @@ fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span { } } -fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemId]) { - fn is_named_self(cx: &LateContext<'_>, item: TraitItemId, name: Symbol) -> bool { - cx.tcx.item_name(item.owner_id) == name - && matches!( - cx.tcx.fn_arg_idents(item.owner_id), - [Some(Ident { - name: kw::SelfLower, - .. - })], - ) - } - - // fill the set with current and super traits - fn fill_trait_set(traitt: DefId, set: &mut DefIdSet, cx: &LateContext<'_>) { - if set.insert(traitt) { - for supertrait in supertrait_def_ids(cx.tcx, traitt) { - fill_trait_set(supertrait, set, cx); - } - } - } - - if cx.effective_visibilities.is_exported(visited_trait.owner_id.def_id) - && trait_items.iter().any(|&i| is_named_self(cx, i, sym::len)) - { - let mut current_and_super_traits = DefIdSet::default(); - fill_trait_set(visited_trait.owner_id.to_def_id(), &mut current_and_super_traits, cx); - let is_empty_method_found = current_and_super_traits - .items() - .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(sym::is_empty)) - .any(|i| i.is_method() && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1); - - if !is_empty_method_found { - span_lint( - cx, - LEN_WITHOUT_IS_EMPTY, - visited_trait.span, - format!( - "trait `{}` has a `len` method but no (possibly inherited) `is_empty` method", - ident.name - ), - ); - } - } -} - -#[derive(Debug, Clone, Copy)] -enum LenOutput { - Integral, - Option(DefId), - Result(DefId), -} - -fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { - if let ty::Alias(_, alias_ty) = ty.kind() - && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(alias_ty.def_id) - && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin - && let [GenericBound::Trait(trait_ref)] = &opaque.bounds - && let Some(segment) = trait_ref.trait_ref.path.segments.last() - && let Some(generic_args) = segment.args - && let [constraint] = generic_args.constraints - && let Some(ty) = constraint.ty() - && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind - && let [segment] = path.segments - { - return Some(segment); - } - - None -} - -fn is_first_generic_integral<'tcx>(segment: &'tcx PathSegment<'tcx>) -> bool { - if let Some(generic_args) = segment.args - && let [GenericArg::Type(ty), ..] = &generic_args.args - && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind - && let [segment, ..] = &path.segments - && matches!(segment.res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) - { - true - } else { - false - } -} - -fn parse_len_output<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option { - if let Some(segment) = extract_future_output(cx, sig.output()) { - let res = segment.res; - - if matches!(res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) { - return Some(LenOutput::Integral); - } - - if let Res::Def(_, def_id) = res - && let Some(res) = match cx.tcx.get_diagnostic_name(def_id) { - Some(sym::Option) => Some(LenOutput::Option(def_id)), - Some(sym::Result) => Some(LenOutput::Result(def_id)), - _ => None, - } - && is_first_generic_integral(segment) - { - return Some(res); - } - - return None; - } - - match *sig.output().kind() { - ty::Int(_) | ty::Uint(_) => Some(LenOutput::Integral), - ty::Adt(adt, subs) => match cx.tcx.get_diagnostic_name(adt.did()) { - Some(sym::Option) => subs.type_at(0).is_integral().then(|| LenOutput::Option(adt.did())), - Some(sym::Result) => subs.type_at(0).is_integral().then(|| LenOutput::Result(adt.did())), - _ => None, - }, - _ => None, - } -} - -impl LenOutput { - fn matches_is_empty_output<'tcx>(self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - if let Some(segment) = extract_future_output(cx, ty) { - return match (self, segment.res) { - (_, Res::PrimTy(PrimTy::Bool)) => true, - (Self::Option(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Option, def_id) => true, - (Self::Result(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Result, def_id) => true, - _ => false, - }; - } - - match (self, ty.kind()) { - (_, &ty::Bool) => true, - (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), - (Self::Result(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), - _ => false, - } - } - - fn expected_sig(self, self_kind: ImplicitSelfKind) -> String { - let self_ref = match self_kind { - ImplicitSelfKind::RefImm => "&", - ImplicitSelfKind::RefMut => "&mut ", - _ => "", - }; - match self { - Self::Integral => format!("expected signature: `({self_ref}self) -> bool`"), - Self::Option(_) => { - format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Option") - }, - Self::Result(..) => { - format!("expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Result") - }, - } - } -} - -/// Checks if the given signature matches the expectations for `is_empty` -fn check_is_empty_sig<'tcx>( - cx: &LateContext<'tcx>, - sig: FnSig<'tcx>, - self_kind: ImplicitSelfKind, - len_output: LenOutput, -) -> bool { - match &**sig.inputs_and_output { - [arg, res] if len_output.matches_is_empty_output(cx, *res) => { - matches!( - (arg.kind(), self_kind), - (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::RefImm) - | (ty::Ref(_, _, Mutability::Mut), ImplicitSelfKind::RefMut) - ) || (!arg.is_ref() && matches!(self_kind, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut)) - }, - _ => false, - } -} - -/// Checks if the given type has an `is_empty` method with the appropriate signature. -#[expect(clippy::too_many_arguments)] -fn check_for_is_empty( - cx: &LateContext<'_>, - span: Span, - self_kind: ImplicitSelfKind, - output: LenOutput, - impl_ty: DefId, - item_name: Symbol, - item_kind: &str, - len_method_hir_id: HirId, - ty_decl_hir_id: HirId, -) { - // Implementor may be a type alias, in which case we need to get the `DefId` of the aliased type to - // find the correct inherent impls. - let impl_ty = if let Some(adt) = cx.tcx.type_of(impl_ty).skip_binder().ty_adt_def() { - adt.did() - } else { - return; - }; - - let is_empty = cx - .tcx - .inherent_impls(impl_ty) - .iter() - .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(sym::is_empty)) - .find(|item| item.is_fn()); - - let (msg, is_empty_span, self_kind) = match is_empty { - None => ( - format!( - "{item_kind} `{}` has a public `len` method, but no `is_empty` method", - item_name.as_str(), - ), - None, - None, - ), - Some(is_empty) if !cx.effective_visibilities.is_exported(is_empty.def_id.expect_local()) => ( - format!( - "{item_kind} `{}` has a public `len` method, but a private `is_empty` method", - item_name.as_str(), - ), - Some(cx.tcx.def_span(is_empty.def_id)), - None, - ), - Some(is_empty) - if !(is_empty.is_method() - && check_is_empty_sig( - cx, - cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(), - self_kind, - output, - )) => - { - ( - format!( - "{item_kind} `{}` has a public `len` method, but the `is_empty` method has an unexpected signature", - item_name.as_str(), - ), - Some(cx.tcx.def_span(is_empty.def_id)), - Some(self_kind), - ) - }, - Some(_) => return, - }; - - if !fulfill_or_allowed(cx, LEN_WITHOUT_IS_EMPTY, [len_method_hir_id, ty_decl_hir_id]) { - span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, span, msg, |db| { - if let Some(span) = is_empty_span { - db.span_note(span, "`is_empty` defined here"); - } - if let Some(self_kind) = self_kind { - db.note(output.expected_sig(self_kind)); - } - }); - } -} - fn is_empty_string(expr: &Expr<'_>) -> bool { if let ExprKind::Lit(lit) = expr.kind && let LitKind::Str(lit, _) = lit.node diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index bc62d9b8450c..40487fe48f22 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -182,6 +182,7 @@ mod large_include_file; mod large_stack_arrays; mod large_stack_frames; mod legacy_numeric_constants; +mod len_without_is_empty; mod len_zero; mod let_if_seq; mod let_underscore; @@ -201,6 +202,7 @@ mod manual_clamp; mod manual_float_methods; mod manual_hash_one; mod manual_ignore_case_cmp; +mod manual_ilog2; mod manual_is_ascii_check; mod manual_is_power_of_two; mod manual_let_else; @@ -538,6 +540,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(|_| Box::new(unnecessary_mut_passed::UnnecessaryMutPassed)), Box::new(|_| Box::>::default()), Box::new(move |_| Box::new(len_zero::LenZero::new(conf))), + Box::new(|_| Box::new(len_without_is_empty::LenWithoutIsEmpty)), Box::new(move |_| Box::new(attrs::Attributes::new(conf))), Box::new(|_| Box::new(blocks_in_conditions::BlocksInConditions)), Box::new(|_| Box::new(unicode::Unicode)), @@ -848,6 +851,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(|_| Box::new(toplevel_ref_arg::ToplevelRefArg)), Box::new(|_| Box::new(volatile_composites::VolatileComposites)), Box::new(|_| Box::::default()), + Box::new(move |_| Box::new(manual_ilog2::ManualIlog2::new(conf))), // add late passes here, used by `cargo dev new_lint` ]; store.late_passes.extend(late_lints); diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs index 2545f81f1afa..6c95c7b54c50 100644 --- a/clippy_lints/src/loops/while_let_on_iterator.rs +++ b/clippy_lints/src/loops/while_let_on_iterator.rs @@ -43,26 +43,26 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { }; // If the iterator is a field or the iterator is accessed after the loop is complete it needs to be - // borrowed mutably. TODO: If the struct can be partially moved from and the struct isn't used + // passed by reference. TODO: If the struct can be partially moved from and the struct isn't used // afterwards a mutable borrow of a field isn't necessary. - let by_ref = if cx.typeck_results().expr_ty(iter_expr).ref_mutability() == Some(Mutability::Mut) + let iterator = snippet_with_applicability(cx, iter_expr.span, "_", &mut applicability); + let iterator_by_ref = if cx.typeck_results().expr_ty(iter_expr).ref_mutability() == Some(Mutability::Mut) || !iter_expr_struct.can_move || !iter_expr_struct.fields.is_empty() || needs_mutable_borrow(cx, &iter_expr_struct, expr) { - ".by_ref()" + make_iterator_snippet(cx, iter_expr, &iterator) } else { - "" + iterator.into_owned() }; - let iterator = snippet_with_applicability(cx, iter_expr.span, "_", &mut applicability); span_lint_and_sugg( cx, WHILE_LET_ON_ITERATOR, expr.span.with_hi(let_expr.span.hi()), "this loop could be written as a `for` loop", "try", - format!("{loop_label}for {loop_var} in {iterator}{by_ref}"), + format!("{loop_label}for {loop_var} in {iterator_by_ref}"), applicability, ); } @@ -355,3 +355,22 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: & .is_break() } } + +/// Constructs the transformed iterator expression for the suggestion. +/// Returns `iterator.by_ref()` unless the last deref adjustment targets an unsized type, +/// in which case it applies all derefs (e.g., `&mut **iterator` or `&mut ***iterator`). +fn make_iterator_snippet<'tcx>(cx: &LateContext<'tcx>, iter_expr: &Expr<'tcx>, iterator: &str) -> String { + if let Some((n, adjust)) = cx + .typeck_results() + .expr_adjustments(iter_expr) + .iter() + .take_while(|x| matches!(x.kind, Adjust::Deref(_))) + .enumerate() + .last() + && !adjust.target.is_sized(cx.tcx, cx.typing_env()) + { + format!("&mut {:* Self { + Self { msrv: conf.msrv } + } +} + +impl_lint_pass!(ManualIlog2 => [MANUAL_ILOG2]); + +impl LateLintPass<'_> for ManualIlog2 { + fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + if expr.span.in_external_macro(cx.sess().source_map()) { + return; + } + + match expr.kind { + // `BIT_WIDTH - 1 - n.leading_zeros()` + ExprKind::Binary(op, left, right) + if left.span.eq_ctxt(right.span) + && op.node == BinOpKind::Sub + && let ExprKind::Lit(lit) = left.kind + && let LitKind::Int(Pu128(val), _) = lit.node + && let ExprKind::MethodCall(leading_zeros, recv, [], _) = right.kind + && leading_zeros.ident.name == sym::leading_zeros + && let ty = cx.typeck_results().expr_ty(recv) + && let Some(bit_width) = match ty.kind() { + ty::Uint(uint_ty) => uint_ty.bit_width(), + ty::Int(_) => { + // On non-positive integers, `ilog2` would panic, which might be a sign that the author does + // in fact want to calculate something different, so stay on the safer side and don't + // suggest anything. + return; + }, + _ => return, + } + && val == u128::from(bit_width) - 1 + && self.msrv.meets(cx, msrvs::ILOG2) + && !is_from_proc_macro(cx, expr) => + { + emit(cx, recv, expr); + }, + + // `n.ilog(2)` + ExprKind::MethodCall(ilog, recv, [two], _) + if expr.span.eq_ctxt(two.span) + && ilog.ident.name == sym::ilog + && let ExprKind::Lit(lit) = two.kind + && let LitKind::Int(Pu128(2), _) = lit.node + && cx.typeck_results().expr_ty_adjusted(recv).is_integral() + /* no need to check MSRV here, as `ilog` and `ilog2` were introduced simultaneously */ + && !is_from_proc_macro(cx, expr) => + { + emit(cx, recv, expr); + }, + + _ => {}, + } + } +} + +fn emit(cx: &LateContext<'_>, recv: &Expr<'_>, full_expr: &Expr<'_>) { + let mut app = Applicability::MachineApplicable; + let recv = snippet_with_applicability(cx, recv.span, "_", &mut app); + span_lint_and_sugg( + cx, + MANUAL_ILOG2, + full_expr.span, + "manually reimplementing `ilog2`", + "try", + format!("{recv}.ilog2()"), + app, + ); +} diff --git a/clippy_lints/src/matches/match_like_matches.rs b/clippy_lints/src/matches/match_like_matches.rs index b5f631e8fea3..89411115f730 100644 --- a/clippy_lints/src/matches/match_like_matches.rs +++ b/clippy_lints/src/matches/match_like_matches.rs @@ -1,7 +1,8 @@ //! Lint a `match` or `if let .. { .. } else { .. }` expr that could be replaced by `matches!` use super::REDUNDANT_PATTERN_MATCHING; -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::higher::has_let_expr; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment}; use rustc_ast::LitKind; @@ -43,18 +44,23 @@ pub(crate) fn check_if_let<'tcx>( { ex_new = ex_inner; } - span_lint_and_sugg( + span_lint_and_then( cx, MATCH_LIKE_MATCHES_MACRO, expr.span, - "if let .. else expression looks like `matches!` macro", - "try", - format!( - "{}matches!({}, {pat})", - if b0 { "" } else { "!" }, - snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), - ), - applicability, + "`if let .. else` expression looks like `matches!` macro", + |diag| { + diag.span_suggestion_verbose( + expr.span, + "use `matches!` directly", + format!( + "{}matches!({}, {pat})", + if b0 { "" } else { "!" }, + snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), + ), + applicability, + ); + }, ); } } @@ -87,7 +93,10 @@ pub(super) fn check_match<'tcx>( // ```rs // matches!(e, Either::Left $(if $guard)|+) // ``` - middle_arms.is_empty() + // + // But if the guard _is_ present, it may not be an `if-let` guard, as `matches!` doesn't + // support these (currently?) + (middle_arms.is_empty() && first_arm.guard.is_none_or(|g| !has_let_expr(g))) // - (added in #6216) There are middle arms // @@ -169,18 +178,23 @@ pub(super) fn check_match<'tcx>( { ex_new = ex_inner; } - span_lint_and_sugg( + span_lint_and_then( cx, MATCH_LIKE_MATCHES_MACRO, e.span, "match expression looks like `matches!` macro", - "try", - format!( - "{}matches!({}, {pat_and_guard})", - if b0 { "" } else { "!" }, - snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), - ), - applicability, + |diag| { + diag.span_suggestion_verbose( + e.span, + "use `matches!` directly", + format!( + "{}matches!({}, {pat_and_guard})", + if b0 { "" } else { "!" }, + snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), + ), + applicability, + ); + }, ); true } else { diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs index 2196ce92b0ab..a3dd967bd77a 100644 --- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -4,18 +4,20 @@ use clippy_utils::source::snippet_with_applicability; use clippy_utils::sym; use rustc_ast::ast; use rustc_errors::Applicability; -use rustc_hir as hir; use rustc_hir::def::Res; +use rustc_hir::{self as hir, Expr}; use rustc_lint::LateContext; +use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; +use rustc_span::Symbol; -pub fn check( +pub fn check_unwrap_or( cx: &LateContext<'_>, - expr: &hir::Expr<'_>, - arith_lhs: &hir::Expr<'_>, - arith_rhs: &hir::Expr<'_>, - unwrap_arg: &hir::Expr<'_>, - arith: &str, + expr: &Expr<'_>, + arith_lhs: &Expr<'_>, + arith_rhs: &Expr<'_>, + unwrap_arg: &Expr<'_>, + arith: Symbol, ) { let ty = cx.typeck_results().expr_ty(arith_lhs); if !ty.is_integral() { @@ -26,35 +28,75 @@ pub fn check( return; }; - if ty.is_signed() { - use self::MinMax::{Max, Min}; - use self::Sign::{Neg, Pos}; + let Some(checked_arith) = CheckedArith::new(arith) else { + return; + }; + check(cx, expr, arith_lhs, arith_rhs, ty, mm, checked_arith); +} + +pub(super) fn check_sub_unwrap_or_default( + cx: &LateContext<'_>, + expr: &Expr<'_>, + arith_lhs: &Expr<'_>, + arith_rhs: &Expr<'_>, +) { + let ty = cx.typeck_results().expr_ty(arith_lhs); + if !ty.is_integral() { + return; + } + + let mm = if ty.is_signed() { + return; // iN::default() is 0, which is neither MIN nor MAX + } else { + MinMax::Min // uN::default() is 0, which is also the MIN + }; + + let checked_arith = CheckedArith::Sub; + + check(cx, expr, arith_lhs, arith_rhs, ty, mm, checked_arith); +} + +fn check( + cx: &LateContext<'_>, + expr: &Expr<'_>, + arith_lhs: &Expr<'_>, + arith_rhs: &Expr<'_>, + ty: Ty<'_>, + mm: MinMax, + checked_arith: CheckedArith, +) { + use self::MinMax::{Max, Min}; + use self::Sign::{Neg, Pos}; + use CheckedArith::{Add, Mul, Sub}; + + if ty.is_signed() { let Some(sign) = lit_sign(arith_rhs) else { return; }; - match (arith, sign, mm) { - ("add", Pos, Max) | ("add", Neg, Min) | ("sub", Neg, Max) | ("sub", Pos, Min) => (), + match (checked_arith, sign, mm) { + (Add, Pos, Max) | (Add, Neg, Min) | (Sub, Neg, Max) | (Sub, Pos, Min) => (), // "mul" is omitted because lhs can be negative. _ => return, } } else { - match (mm, arith) { - (MinMax::Max, "add" | "mul") | (MinMax::Min, "sub") => (), + match (mm, checked_arith) { + (Max, Add | Mul) | (Min, Sub) => (), _ => return, } } let mut applicability = Applicability::MachineApplicable; + let saturating_arith = checked_arith.as_saturating(); span_lint_and_sugg( cx, super::MANUAL_SATURATING_ARITHMETIC, expr.span, "manual saturating arithmetic", - format!("consider using `saturating_{arith}`"), + format!("consider using `{saturating_arith}`"), format!( - "{}.saturating_{arith}({})", + "{}.{saturating_arith}({})", snippet_with_applicability(cx, arith_lhs.span, "..", &mut applicability), snippet_with_applicability(cx, arith_rhs.span, "..", &mut applicability), ), @@ -62,13 +104,40 @@ pub fn check( ); } +#[derive(Clone, Copy)] +enum CheckedArith { + Add, + Sub, + Mul, +} + +impl CheckedArith { + fn new(sym: Symbol) -> Option { + let res = match sym { + sym::checked_add => Self::Add, + sym::checked_sub => Self::Sub, + sym::checked_mul => Self::Mul, + _ => return None, + }; + Some(res) + } + + fn as_saturating(self) -> &'static str { + match self { + Self::Add => "saturating_add", + Self::Sub => "saturating_sub", + Self::Mul => "saturating_mul", + } + } +} + #[derive(PartialEq, Eq)] enum MinMax { Min, Max, } -fn is_min_or_max(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option { +fn is_min_or_max(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { // `T::max_value()` `T::min_value()` inherent methods if let hir::ExprKind::Call(func, []) = &expr.kind && let hir::ExprKind::Path(hir::QPath::TypeRelative(_, segment)) = &func.kind @@ -106,7 +175,7 @@ fn is_min_or_max(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option { (0, if bits == 128 { !0 } else { (1 << bits) - 1 }) }; - let check_lit = |expr: &hir::Expr<'_>, check_min: bool| { + let check_lit = |expr: &Expr<'_>, check_min: bool| { if let hir::ExprKind::Lit(lit) = &expr.kind && let ast::LitKind::Int(value, _) = lit.node { @@ -141,7 +210,7 @@ enum Sign { Neg, } -fn lit_sign(expr: &hir::Expr<'_>) -> Option { +fn lit_sign(expr: &Expr<'_>) -> Option { if let hir::ExprKind::Unary(hir::UnOp::Neg, inner) = &expr.kind { if let hir::ExprKind::Lit(..) = &inner.kind { return Some(Sign::Neg); diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index c22b0a548e3d..48842c8739c0 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -94,6 +94,7 @@ mod or_fun_call; mod or_then_unwrap; mod path_buf_push_overwrite; mod path_ends_with_ext; +mod ptr_offset_by_literal; mod ptr_offset_with_cast; mod range_zip_with_len; mod read_line_without_trim; @@ -1728,6 +1729,40 @@ declare_clippy_lint! { "Check for offset calculations on raw pointers to zero-sized types" } +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of the `offset` pointer method with an integer + /// literal. + /// + /// ### Why is this bad? + /// The `add` and `sub` methods more accurately express the intent. + /// + /// ### Example + /// ```no_run + /// let vec = vec![b'a', b'b', b'c']; + /// let ptr = vec.as_ptr(); + /// + /// unsafe { + /// ptr.offset(-8); + /// } + /// ``` + /// + /// Could be written: + /// + /// ```no_run + /// let vec = vec![b'a', b'b', b'c']; + /// let ptr = vec.as_ptr(); + /// + /// unsafe { + /// ptr.sub(8); + /// } + /// ``` + #[clippy::version = "1.92.0"] + pub PTR_OFFSET_BY_LITERAL, + pedantic, + "unneeded pointer offset" +} + declare_clippy_lint! { /// ### What it does /// Checks for usage of the `offset` pointer method with a `usize` casted to an @@ -4635,7 +4670,7 @@ declare_clippy_lint! { /// let x = vec![String::new()]; /// let _ = x.iter().map(|x| x.len()); /// ``` - #[clippy::version = "1.90.0"] + #[clippy::version = "1.92.0"] pub REDUNDANT_ITER_CLONED, perf, "detects redundant calls to `Iterator::cloned`" @@ -4659,7 +4694,7 @@ declare_clippy_lint! { /// let x: Option = Some(4); /// let y = x.unwrap_or_else(|| 2 * k); /// ``` - #[clippy::version = "1.88.0"] + #[clippy::version = "1.92.0"] pub UNNECESSARY_OPTION_MAP_OR_ELSE, suspicious, "making no use of the \"map closure\" when calling `.map_or_else(|| 2 * k, |n| n)`" @@ -4803,6 +4838,7 @@ impl_lint_pass!(Methods => [ UNINIT_ASSUMED_INIT, MANUAL_SATURATING_ARITHMETIC, ZST_OFFSET, + PTR_OFFSET_BY_LITERAL, PTR_OFFSET_WITH_CAST, FILETYPE_IS_FILE, OPTION_AS_REF_DEREF, @@ -5426,6 +5462,7 @@ impl Methods { zst_offset::check(cx, expr, recv); ptr_offset_with_cast::check(cx, name, expr, recv, arg, self.msrv); + ptr_offset_by_literal::check(cx, expr, self.msrv); }, (sym::ok_or_else, [arg]) => { unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"); @@ -5567,14 +5604,7 @@ impl Methods { (sym::unwrap_or, [u_arg]) => { match method_call(recv) { Some((arith @ (sym::checked_add | sym::checked_sub | sym::checked_mul), lhs, [rhs], _, _)) => { - manual_saturating_arithmetic::check( - cx, - expr, - lhs, - rhs, - u_arg, - &arith.as_str()[const { "checked_".len() }..], - ); + manual_saturating_arithmetic::check_unwrap_or(cx, expr, lhs, rhs, u_arg, arith); }, Some((sym::map, m_recv, [m_arg], span, _)) => { option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv); @@ -5595,6 +5625,9 @@ impl Methods { }, (sym::unwrap_or_default, []) => { match method_call(recv) { + Some((sym::checked_sub, lhs, [rhs], _, _)) => { + manual_saturating_arithmetic::check_sub_unwrap_or_default(cx, expr, lhs, rhs); + }, Some((sym::map, m_recv, [arg], span, _)) => { manual_is_variant_and::check(cx, expr, m_recv, arg, span, self.msrv); }, diff --git a/clippy_lints/src/methods/ptr_offset_by_literal.rs b/clippy_lints/src/methods/ptr_offset_by_literal.rs new file mode 100644 index 000000000000..b5d2add65cf1 --- /dev/null +++ b/clippy_lints/src/methods/ptr_offset_by_literal.rs @@ -0,0 +1,138 @@ +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::source::SpanRangeExt; +use clippy_utils::sym; +use rustc_ast::LitKind; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, Lit, UnOp}; +use rustc_lint::LateContext; +use std::cmp::Ordering; +use std::fmt; + +use super::PTR_OFFSET_BY_LITERAL; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Msrv) { + // `pointer::add` and `pointer::wrapping_add` are only stable since 1.26.0. These functions + // became const-stable in 1.61.0, the same version that `pointer::offset` became const-stable. + if !msrv.meets(cx, msrvs::POINTER_ADD_SUB_METHODS) { + return; + } + + let ExprKind::MethodCall(method_name, recv, [arg_expr], _) = expr.kind else { + return; + }; + + let method = match method_name.ident.name { + sym::offset => Method::Offset, + sym::wrapping_offset => Method::WrappingOffset, + _ => return, + }; + + if !cx.typeck_results().expr_ty_adjusted(recv).is_raw_ptr() { + return; + } + + // Check if the argument to the method call is a (negated) literal. + let Some((literal, literal_text)) = expr_as_literal(cx, arg_expr) else { + return; + }; + + match method.suggestion(literal) { + None => { + let msg = format!("use of `{method}` with zero"); + span_lint_and_then(cx, PTR_OFFSET_BY_LITERAL, expr.span, msg, |diag| { + diag.span_suggestion( + expr.span.with_lo(recv.span.hi()), + format!("remove the call to `{method}`"), + String::new(), + Applicability::MachineApplicable, + ); + }); + }, + Some(method_suggestion) => { + let msg = format!("use of `{method}` with a literal"); + span_lint_and_then(cx, PTR_OFFSET_BY_LITERAL, expr.span, msg, |diag| { + diag.multipart_suggestion( + format!("use `{method_suggestion}` instead"), + vec![ + (method_name.ident.span, method_suggestion.to_string()), + (arg_expr.span, literal_text), + ], + Applicability::MachineApplicable, + ); + }); + }, + } +} + +fn get_literal_bits<'tcx>(expr: &'tcx Expr<'tcx>) -> Option { + match expr.kind { + ExprKind::Lit(Lit { + node: LitKind::Int(packed_u128, _), + .. + }) => Some(packed_u128.get()), + _ => None, + } +} + +// If the given expression is a (negated) literal, return its value. +fn expr_as_literal<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<(i128, String)> { + if let Some(literal_bits) = get_literal_bits(expr) { + // The value must fit in a isize, so we can't have overflow here. + return Some((literal_bits.cast_signed(), format_isize_literal(cx, expr)?)); + } + + if let ExprKind::Unary(UnOp::Neg, inner) = expr.kind + && let Some(literal_bits) = get_literal_bits(inner) + { + return Some((-(literal_bits.cast_signed()), format_isize_literal(cx, inner)?)); + } + + None +} + +fn format_isize_literal<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option { + let text = expr.span.get_source_text(cx)?; + let text = peel_parens_str(&text); + Some(text.trim_end_matches("isize").trim_end_matches('_').to_string()) +} + +fn peel_parens_str(snippet: &str) -> &str { + let mut s = snippet.trim(); + while let Some(next) = s.strip_prefix("(").and_then(|suf| suf.strip_suffix(")")) { + s = next.trim(); + } + s +} + +#[derive(Copy, Clone)] +enum Method { + Offset, + WrappingOffset, +} + +impl Method { + fn suggestion(self, literal: i128) -> Option<&'static str> { + match Ord::cmp(&literal, &0) { + Ordering::Greater => match self { + Method::Offset => Some("add"), + Method::WrappingOffset => Some("wrapping_add"), + }, + // `ptr.offset(0)` is equivalent to `ptr`, so no adjustment is needed + Ordering::Equal => None, + Ordering::Less => match self { + Method::Offset => Some("sub"), + Method::WrappingOffset => Some("wrapping_sub"), + }, + } + } +} + +impl fmt::Display for Method { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Offset => write!(f, "offset"), + Self::WrappingOffset => write!(f, "wrapping_offset"), + } + } +} diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index 808adb7e71ce..87ee164a1760 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -5,7 +5,7 @@ use clippy_utils::comparisons::{Rel, normalize_comparison}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::{If, Range}; use clippy_utils::macros::{find_assert_eq_args, first_node_macro_backtrace, root_macro_call}; -use clippy_utils::source::snippet; +use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{eq_expr_value, hash_expr}; use rustc_ast::{BinOpKind, LitKind, RangeLimits}; @@ -67,16 +67,13 @@ declare_clippy_lint! { } declare_lint_pass!(MissingAssertsForIndexing => [MISSING_ASSERTS_FOR_INDEXING]); -fn report_lint(cx: &LateContext<'_>, full_span: Span, msg: &'static str, indexes: &[Span], f: F) +fn report_lint(cx: &LateContext<'_>, index_spans: Vec, msg: &'static str, f: F) where F: FnOnce(&mut Diag<'_, ()>), { - span_lint_and_then(cx, MISSING_ASSERTS_FOR_INDEXING, full_span, msg, |diag| { + span_lint_and_then(cx, MISSING_ASSERTS_FOR_INDEXING, index_spans, msg, |diag| { f(diag); - for span in indexes { - diag.span_note(*span, "slice indexed here"); - } - diag.note("asserting the length before indexing will elide bounds checks"); + diag.note_once("asserting the length before indexing will elide bounds checks"); }); } @@ -213,15 +210,6 @@ impl<'hir> IndexEntry<'hir> { | IndexEntry::IndexWithoutAssert { slice, .. } => slice, } } - - pub fn index_spans(&self) -> Option<&[Span]> { - match self { - IndexEntry::StrayAssert { .. } => None, - IndexEntry::AssertWithIndex { indexes, .. } | IndexEntry::IndexWithoutAssert { indexes, .. } => { - Some(indexes) - }, - } - } } /// Extracts the upper index of a slice indexing expression. @@ -354,63 +342,47 @@ fn check_assert<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Un /// Inspects indexes and reports lints. /// /// Called at the end of this lint after all indexing and `assert!` expressions have been collected. -fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap>>) { - for bucket in map.values() { +fn report_indexes(cx: &LateContext<'_>, map: UnindexMap>>) { + for bucket in map.into_values() { for entry in bucket { - let Some(full_span) = entry - .index_spans() - .and_then(|spans| spans.first().zip(spans.last())) - .map(|(low, &high)| low.to(high)) - else { - continue; - }; - - match *entry { + match entry { IndexEntry::AssertWithIndex { highest_index, is_first_highest, asserted_len, - ref indexes, + indexes, comparison, assert_span, slice, macro_call, } if indexes.len() > 1 && !is_first_highest => { + let mut app = Applicability::MachineApplicable; + let slice_str = snippet_with_applicability(cx, slice.span, "_", &mut app); // if we have found an `assert!`, let's also check that it's actually right // and if it covers the highest index and if not, suggest the correct length let sugg = match comparison { // `v.len() < 5` and `v.len() <= 5` does nothing in terms of bounds checks. // The user probably meant `v.len() > 5` - LengthComparison::LengthLessThanInt | LengthComparison::LengthLessThanOrEqualInt => Some( - format!("assert!({}.len() > {highest_index})", snippet(cx, slice.span, "..")), - ), + LengthComparison::LengthLessThanInt | LengthComparison::LengthLessThanOrEqualInt => { + Some(format!("assert!({slice_str}.len() > {highest_index})",)) + }, // `5 < v.len()` == `v.len() > 5` - LengthComparison::IntLessThanLength if asserted_len < highest_index => Some(format!( - "assert!({}.len() > {highest_index})", - snippet(cx, slice.span, "..") - )), + LengthComparison::IntLessThanLength if asserted_len < highest_index => { + Some(format!("assert!({slice_str}.len() > {highest_index})",)) + }, // `5 <= v.len() == `v.len() >= 5` - LengthComparison::IntLessThanOrEqualLength if asserted_len <= highest_index => Some(format!( - "assert!({}.len() > {highest_index})", - snippet(cx, slice.span, "..") - )), + LengthComparison::IntLessThanOrEqualLength if asserted_len <= highest_index => { + Some(format!("assert!({slice_str}.len() > {highest_index})",)) + }, // `highest_index` here is rather a length, so we need to add 1 to it LengthComparison::LengthEqualInt if asserted_len < highest_index + 1 => match macro_call { - sym::assert_eq_macro => Some(format!( - "assert_eq!({}.len(), {})", - snippet(cx, slice.span, ".."), - highest_index + 1 - )), - sym::debug_assert_eq_macro => Some(format!( - "debug_assert_eq!({}.len(), {})", - snippet(cx, slice.span, ".."), - highest_index + 1 - )), - _ => Some(format!( - "assert!({}.len() == {})", - snippet(cx, slice.span, ".."), - highest_index + 1 - )), + sym::assert_eq_macro => { + Some(format!("assert_eq!({slice_str}.len(), {})", highest_index + 1)) + }, + sym::debug_assert_eq_macro => { + Some(format!("debug_assert_eq!({slice_str}.len(), {})", highest_index + 1)) + }, + _ => Some(format!("assert!({slice_str}.len() == {})", highest_index + 1)), }, _ => None, }; @@ -418,22 +390,21 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap if let Some(sugg) = sugg { report_lint( cx, - full_span, - "indexing into a slice multiple times with an `assert` that does not cover the highest index", indexes, + "indexing into a slice multiple times with an `assert` that does not cover the highest index", |diag| { - diag.span_suggestion( + diag.span_suggestion_verbose( assert_span, "provide the highest index that is indexed with", sugg, - Applicability::MachineApplicable, + app, ); }, ); } }, IndexEntry::IndexWithoutAssert { - ref indexes, + indexes, highest_index, is_first_highest, slice, @@ -442,9 +413,8 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap // adding an `assert!` that covers the highest index report_lint( cx, - full_span, - "indexing into a slice multiple times without an `assert`", indexes, + "indexing into a slice multiple times without an `assert`", |diag| { diag.help(format!( "consider asserting the length before indexing: `assert!({}.len() > {highest_index});`", @@ -469,6 +439,6 @@ impl LateLintPass<'_> for MissingAssertsForIndexing { ControlFlow::::Continue(()) }); - report_indexes(cx, &map); + report_indexes(cx, map); } } diff --git a/clippy_lints/src/nonstandard_macro_braces.rs b/clippy_lints/src/nonstandard_macro_braces.rs index 3a8a4dd0c713..8970970f4b47 100644 --- a/clippy_lints/src/nonstandard_macro_braces.rs +++ b/clippy_lints/src/nonstandard_macro_braces.rs @@ -115,35 +115,41 @@ impl EarlyLintPass for MacroBraces { } fn is_offending_macro(cx: &EarlyContext<'_>, span: Span, mac_braces: &MacroBraces) -> Option { - let unnested_or_local = || { - !span.ctxt().outer_expn_data().call_site.from_expansion() + let unnested_or_local = |span: Span| { + !span.from_expansion() || span .macro_backtrace() .last() .is_some_and(|e| e.macro_def_id.is_some_and(DefId::is_local)) }; - let callsite_span = span.ctxt().outer_expn_data().call_site; - if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span.ctxt().outer_expn_data().kind + + let mut ctxt = span.ctxt(); + while !ctxt.is_root() { + let expn_data = ctxt.outer_expn_data(); + if let ExpnKind::Macro(MacroKind::Bang, mac_name) = expn_data.kind && let name = mac_name.as_str() && let Some(&braces) = mac_braces.macro_braces.get(name) - && let Some(snip) = callsite_span.get_source_text(cx) + && let Some(snip) = expn_data.call_site.get_source_text(cx) // we must check only invocation sites // https://github.com/rust-lang/rust-clippy/issues/7422 && let Some(macro_args_str) = snip.strip_prefix(name).and_then(|snip| snip.strip_prefix('!')) && let Some(old_open_brace @ ('{' | '(' | '[')) = macro_args_str.trim_start().chars().next() && old_open_brace != braces.0 - && unnested_or_local() - && !mac_braces.done.contains(&callsite_span) - { - Some(MacroInfo { - callsite_span, - callsite_snippet: snip, - old_open_brace, - braces, - }) - } else { - None + && unnested_or_local(expn_data.call_site) + && !mac_braces.done.contains(&expn_data.call_site) + { + return Some(MacroInfo { + callsite_span: expn_data.call_site, + callsite_snippet: snip, + old_open_brace, + braces, + }); + } + + ctxt = expn_data.call_site.ctxt(); } + + None } fn emit_help(cx: &EarlyContext<'_>, snip: &str, (open, close): (char, char), span: Span, add_semi: bool) { diff --git a/clippy_lints/src/operators/decimal_bitwise_operands.rs b/clippy_lints/src/operators/decimal_bitwise_operands.rs new file mode 100644 index 000000000000..8511f2151342 --- /dev/null +++ b/clippy_lints/src/operators/decimal_bitwise_operands.rs @@ -0,0 +1,76 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::numeric_literal; +use clippy_utils::numeric_literal::NumericLiteral; +use clippy_utils::source::SpanRangeExt; +use rustc_ast::LitKind; +use rustc_data_structures::packed::Pu128; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_span::Span; + +use super::DECIMAL_BITWISE_OPERANDS; + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, op: BinOpKind, left: &'tcx Expr<'_>, right: &'tcx Expr<'_>) { + if !matches!(op, BinOpKind::BitAnd | BinOpKind::BitOr | BinOpKind::BitXor) { + return; + } + + for expr in [left, right] { + check_expr(cx, expr); + } +} + +fn check_expr(cx: &LateContext<'_>, expr: &Expr<'_>) { + match &expr.kind { + ExprKind::Block(block, _) => { + if let Some(block_expr) = block.expr { + check_expr(cx, block_expr); + } + }, + ExprKind::Cast(cast_expr, _) => { + check_expr(cx, cast_expr); + }, + ExprKind::Unary(_, unary_expr) => { + check_expr(cx, unary_expr); + }, + ExprKind::AddrOf(_, _, addr_of_expr) => { + check_expr(cx, addr_of_expr); + }, + ExprKind::Lit(lit) => { + if let LitKind::Int(Pu128(val), _) = lit.node + && !is_single_digit(val) + && !is_power_of_twoish(val) + && let Some(src) = lit.span.get_source_text(cx) + && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node) + && num_lit.is_decimal() + { + emit_lint(cx, lit.span, num_lit.suffix, val); + } + }, + _ => (), + } +} + +fn is_power_of_twoish(val: u128) -> bool { + val.is_power_of_two() || val.wrapping_add(1).is_power_of_two() +} + +fn is_single_digit(val: u128) -> bool { + val <= 9 +} + +fn emit_lint(cx: &LateContext<'_>, span: Span, suffix: Option<&str>, val: u128) { + span_lint_and_help( + cx, + DECIMAL_BITWISE_OPERANDS, + span, + "using decimal literal for bitwise operation", + None, + format!( + "use binary ({}), hex ({}), or octal ({}) notation for better readability", + numeric_literal::format(&format!("{val:#b}"), suffix, false), + numeric_literal::format(&format!("{val:#x}"), suffix, false), + numeric_literal::format(&format!("{val:#o}"), suffix, false), + ), + ); +} diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 8db2cc1d3f57..53b8e9e5d5ae 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -3,6 +3,7 @@ mod assign_op_pattern; mod bit_mask; mod cmp_owned; mod const_comparisons; +mod decimal_bitwise_operands; mod double_comparison; mod duration_subsec; mod eq_op; @@ -935,6 +936,28 @@ declare_clippy_lint! { "use of disallowed default division and remainder operations" } +declare_clippy_lint! { + /// ### What it does + /// Checks for decimal literals used as bit masks in bitwise operations. + /// + /// ### Why is this bad? + /// Using decimal literals for bit masks can make the code less readable and obscure the intended bit pattern. + /// Binary, hexadecimal, or octal literals make the bit pattern more explicit and easier to understand at a glance. + /// + /// ### Example + /// ```rust,no_run + /// let a = 14 & 6; // Bit pattern is not immediately clear + /// ``` + /// Use instead: + /// ```rust,no_run + /// let a = 0b1110 & 0b0110; + /// ``` + #[clippy::version = "1.93.0"] + pub DECIMAL_BITWISE_OPERANDS, + pedantic, + "use binary, hex, or octal literals for bitwise operations" +} + pub struct Operators { arithmetic_context: numeric_arithmetic::Context, verbose_bit_mask_threshold: u64, @@ -984,6 +1007,7 @@ impl_lint_pass!(Operators => [ MANUAL_IS_MULTIPLE_OF, MANUAL_DIV_CEIL, INVALID_UPCAST_COMPARISONS, + DECIMAL_BITWISE_OPERANDS ]); impl<'tcx> LateLintPass<'tcx> for Operators { @@ -1003,6 +1027,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators { needless_bitwise_bool::check(cx, e, op.node, lhs, rhs); manual_midpoint::check(cx, e, op.node, lhs, rhs, self.msrv); manual_is_multiple_of::check(cx, e, op.node, lhs, rhs, self.msrv); + decimal_bitwise_operands::check(cx, op.node, lhs, rhs); } self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs); bit_mask::check(cx, e, op.node, lhs, rhs); @@ -1028,6 +1053,9 @@ impl<'tcx> LateLintPass<'tcx> for Operators { }, ExprKind::AssignOp(op, lhs, rhs) => { let bin_op = op.node.into(); + if !e.span.from_expansion() { + decimal_bitwise_operands::check(cx, bin_op, lhs, rhs); + } self.arithmetic_context.check_binary(cx, e, bin_op, lhs, rhs); misrefactored_assign_op::check(cx, e, bin_op, lhs, rhs); modulo_arithmetic::check(cx, e, bin_op, lhs, rhs, false); diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index d643f7aea497..435cd7bcba4e 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -18,8 +18,11 @@ mod wrong_transmute; use clippy_config::Conf; use clippy_utils::is_in_const_context; use clippy_utils::msrvs::Msrv; +use clippy_utils::sugg::Sugg; +use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use rustc_span::symbol::sym; @@ -490,6 +493,32 @@ impl Transmute { pub fn new(conf: &'static Conf) -> Self { Self { msrv: conf.msrv } } + + /// When transmuting, a struct containing a single field works like the field. + /// This function extracts the field type and the expression to get the field. + fn extract_struct_field<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'_>, + outer_type: Ty<'tcx>, + outer: &'tcx Expr<'tcx>, + ) -> (Ty<'tcx>, Sugg<'tcx>) { + let mut applicability = Applicability::MachineApplicable; + let outer_sugg = Sugg::hir_with_context(cx, outer, e.span.ctxt(), "..", &mut applicability); + if let ty::Adt(struct_def, struct_args) = *outer_type.kind() + && struct_def.is_struct() + && let mut fields = struct_def.all_fields() + && let Some(first) = fields.next() + && fields.next().is_none() + && first.vis.is_accessible_from(cx.tcx.parent_module(outer.hir_id), cx.tcx) + { + ( + first.ty(cx.tcx, struct_args), + Sugg::NonParen(format!("{}.{}", outer_sugg.maybe_paren(), first.name).into()), + ) + } else { + (outer_type, outer_sugg) + } + } } impl<'tcx> LateLintPass<'tcx> for Transmute { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { @@ -516,14 +545,17 @@ impl<'tcx> LateLintPass<'tcx> for Transmute { return; } + // A struct having a single pointer can be treated like a pointer. + let (from_field_ty, from_field_expr) = Self::extract_struct_field(cx, e, from_ty, arg); + let linted = wrong_transmute::check(cx, e, from_ty, to_ty) | crosspointer_transmute::check(cx, e, from_ty, to_ty) | transmuting_null::check(cx, e, arg, to_ty) | transmute_null_to_fn::check(cx, e, arg, to_ty) - | transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, self.msrv) + | transmute_ptr_to_ref::check(cx, e, from_field_ty, to_ty, from_field_expr.clone(), path, self.msrv) | missing_transmute_annotations::check(cx, path, arg, from_ty, to_ty, e.hir_id) | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context) - | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, self.msrv) + | transmute_ptr_to_ptr::check(cx, e, from_field_ty, to_ty, from_field_expr, self.msrv) | transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg) | transmute_int_to_non_zero::check(cx, e, from_ty, to_ty, arg) | (unsound_collection_transmute::check(cx, e, from_ty, to_ty) diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs index 91fce5d5bd68..036b16e3dc3d 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs @@ -14,11 +14,9 @@ pub(super) fn check<'tcx>( e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>, - arg: &'tcx Expr<'_>, + arg: sugg::Sugg<'_>, msrv: Msrv, ) -> bool { - let mut applicability = Applicability::MachineApplicable; - let arg_sugg = sugg::Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut applicability); match (from_ty.kind(), to_ty.kind()) { (ty::RawPtr(from_pointee_ty, from_mutbl), ty::RawPtr(to_pointee_ty, to_mutbl)) => { span_lint_and_then( @@ -34,7 +32,7 @@ pub(super) fn check<'tcx>( diag.span_suggestion_verbose( e.span, "use `pointer::cast` instead", - format!("{}.cast::<{to_pointee_ty}>()", arg_sugg.maybe_paren()), + format!("{}.cast::<{to_pointee_ty}>()", arg.maybe_paren()), Applicability::MaybeIncorrect, ); } else if from_pointee_ty == to_pointee_ty @@ -49,14 +47,14 @@ pub(super) fn check<'tcx>( diag.span_suggestion_verbose( e.span, format!("use `pointer::{method}` instead"), - format!("{}.{method}()", arg_sugg.maybe_paren()), + format!("{}.{method}()", arg.maybe_paren()), Applicability::MaybeIncorrect, ); } else { diag.span_suggestion_verbose( e.span, "use an `as` cast instead", - arg_sugg.as_ty(to_ty), + arg.as_ty(to_ty), Applicability::MaybeIncorrect, ); } diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index e67ab6a73d26..ba107eed6b14 100644 --- a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -15,7 +15,7 @@ pub(super) fn check<'tcx>( e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>, - arg: &'tcx Expr<'_>, + arg: sugg::Sugg<'_>, path: &'tcx Path<'_>, msrv: Msrv, ) -> bool { @@ -27,7 +27,6 @@ pub(super) fn check<'tcx>( e.span, format!("transmute from a pointer type (`{from_ty}`) to a reference type (`{to_ty}`)"), |diag| { - let arg = sugg::Sugg::hir(cx, arg, ".."); let (deref, cast) = match mutbl { Mutability::Mut => ("&mut *", "*mut"), Mutability::Not => ("&*", "*const"), diff --git a/clippy_lints/src/tuple_array_conversions.rs b/clippy_lints/src/tuple_array_conversions.rs index 5d0945bece55..98bf9f9fea58 100644 --- a/clippy_lints/src/tuple_array_conversions.rs +++ b/clippy_lints/src/tuple_array_conversions.rs @@ -1,9 +1,9 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::is_from_proc_macro; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeResPath; -use clippy_utils::visitors::for_each_local_use_after_expr; +use clippy_utils::visitors::local_used_once; +use clippy_utils::{get_enclosing_block, is_from_proc_macro}; use itertools::Itertools; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind, Node, PatKind}; @@ -11,7 +11,6 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use std::iter::once; -use std::ops::ControlFlow; declare_clippy_lint! { /// ### What it does @@ -86,7 +85,7 @@ fn check_array<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: & ExprKind::Path(_) => Some(elements.iter().collect()), _ => None, }) - && all_bindings_are_for_conv(cx, &[ty], expr, elements, &locals, ToType::Array) + && all_bindings_are_for_conv(cx, &[ty], elements, &locals, ToType::Array) && !is_from_proc_macro(cx, expr) { span_lint_and_help( @@ -123,7 +122,7 @@ fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: & ExprKind::Path(_) => Some(elements.iter().collect()), _ => None, }) - && all_bindings_are_for_conv(cx, tys, expr, elements, &locals, ToType::Tuple) + && all_bindings_are_for_conv(cx, tys, elements, &locals, ToType::Tuple) && !is_from_proc_macro(cx, expr) { span_lint_and_help( @@ -148,7 +147,6 @@ fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: & fn all_bindings_are_for_conv<'tcx>( cx: &LateContext<'tcx>, final_tys: &[Ty<'tcx>], - expr: &Expr<'_>, elements: &[Expr<'_>], locals: &[&Expr<'_>], kind: ToType, @@ -166,13 +164,30 @@ fn all_bindings_are_for_conv<'tcx>( _ => None, }) .all_equal() - // Fix #11124, very convenient utils function! ❤️ - && locals - .iter() - .all(|&l| for_each_local_use_after_expr(cx, l, expr.hir_id, |_| ControlFlow::Break::<()>(())).is_continue()) + && locals.iter().zip(local_parents.iter()).all(|(&l, &parent)| { + if let Node::LetStmt(_) = parent { + return true; + } + + let Some(b) = get_enclosing_block(cx, l) else { + return true; + }; + local_used_once(cx, b, l).is_some() + }) && local_parents.first().is_some_and(|node| { let Some(ty) = match node { - Node::Pat(pat) => Some(pat.hir_id), + Node::Pat(pat) + if let PatKind::Tuple(pats, _) | PatKind::Slice(pats, None, []) = &pat.kind + && pats.iter().zip(locals.iter()).all(|(p, l)| { + if let PatKind::Binding(_, id, _, _) = p.kind { + id == *l + } else { + true + } + }) => + { + Some(pat.hir_id) + }, Node::LetStmt(l) => Some(l.hir_id), _ => None, } @@ -186,7 +201,9 @@ fn all_bindings_are_for_conv<'tcx>( tys.len() == elements.len() && tys.iter().chain(final_tys.iter().copied()).all_equal() }, (ToType::Tuple, ty::Array(ty, len)) => { - let Some(len) = len.try_to_target_usize(cx.tcx) else { return false }; + let Some(len) = len.try_to_target_usize(cx.tcx) else { + return false; + }; len as usize == elements.len() && final_tys.iter().chain(once(ty)).all_equal() }, _ => false, diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index 8ed3df8731b3..a95f2b681add 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -180,14 +180,19 @@ impl Local { field_indices, .. } => { + let field_projections = place + .projections + .iter() + .filter(|proj| matches!(proj.kind, ProjectionKind::Field(_, _))) + .collect::>(); is_potentially_local_place(*local_id, place) // If there were projections other than field projections, err on the side of caution and say that they // _might_ be mutating something. // // The reason we use `<=` and not `==` is that a mutation of `struct` or `struct.field1` should count as // mutation of the child fields such as `struct.field1.field2` - && place.projections.len() <= field_indices.len() - && iter::zip(&place.projections, field_indices.iter().copied().rev()).all(|(proj, field_idx)| { + && field_projections.len() <= field_indices.len() + && iter::zip(&field_projections, field_indices.iter().copied().rev()).all(|(proj, field_idx)| { match proj.kind { ProjectionKind::Field(f_idx, _) => f_idx == field_idx, // If this is a projection we don't expect, it _might_ be mutating something diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index 0cf5b9431a34..c06313d1a4c4 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -354,7 +354,10 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { return; } - let sugg = snippet(cx, recv.span, "").into_owned(); + let mut applicability = Applicability::MachineApplicable; + let sugg = snippet_with_context(cx, recv.span, e.span.ctxt(), "", &mut applicability) + .0 + .into_owned(); span_lint_and_sugg( cx, USELESS_CONVERSION, diff --git a/clippy_lints/src/zero_repeat_side_effects.rs b/clippy_lints/src/zero_repeat_side_effects.rs index a8351690068d..95085161c09c 100644 --- a/clippy_lints/src/zero_repeat_side_effects.rs +++ b/clippy_lints/src/zero_repeat_side_effects.rs @@ -4,10 +4,11 @@ use clippy_utils::source::{snippet, snippet_indent}; use rustc_ast::LitKind; use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; -use rustc_hir::{ConstArgKind, ExprKind, Node}; +use rustc_hir::{ConstArgKind, Expr, ExprKind, LetStmt, LocalSource, Node}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::IsSuggestable; +use rustc_middle::ty::{IsSuggestable, Ty}; use rustc_session::declare_lint_pass; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does @@ -44,7 +45,7 @@ declare_clippy_lint! { declare_lint_pass!(ZeroRepeatSideEffects => [ZERO_REPEAT_SIDE_EFFECTS]); impl LateLintPass<'_> for ZeroRepeatSideEffects { - fn check_expr(&mut self, cx: &LateContext<'_>, expr: &rustc_hir::Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if let Some(args) = VecArgs::hir(cx, expr) && let VecArgs::Repeat(inner_expr, len) = args && let ExprKind::Lit(l) = len.kind @@ -69,7 +70,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects { } } -fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr: &'_ rustc_hir::Expr<'_>, is_vec: bool) { +fn inner_check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, inner_expr: &'_ Expr<'_>, is_vec: bool) { // check if expr is a call or has a call inside it if inner_expr.can_have_side_effects() { let parent_hir_node = cx.tcx.parent_hir_node(expr.hir_id); @@ -81,19 +82,22 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr: let vec = if is_vec { "vec!" } else { "" }; let (span, sugg) = match parent_hir_node { - Node::LetStmt(l) => ( - l.span, - format!( - "{inner_expr};\n{indent}let {var_name}: {return_type} = {vec}[];", - var_name = snippet(cx, l.pat.span.source_callsite(), "..") - ), - ), + Node::LetStmt(l) + if matches!(l.source, LocalSource::AssignDesugar) + && let mut parent_iter = cx.tcx.hir_parent_iter(l.hir_id) + && let Some((_, Node::Stmt(_))) = parent_iter.next() + && let Some((_, Node::Block(_))) = parent_iter.next() + && let Some((_, Node::Expr(x))) = parent_iter.next() => + { + ( + x.span, + assign_expr_suggestion(cx, x, l.pat.span, &inner_expr, return_type, vec), + ) + }, + Node::LetStmt(l) => (l.span, let_stmt_suggestion(cx, l, &inner_expr, return_type, vec)), Node::Expr(x) if let ExprKind::Assign(l, _, _) = x.kind => ( x.span, - format!( - "{inner_expr};\n{indent}{var_name} = {vec}[] as {return_type}", - var_name = snippet(cx, l.span.source_callsite(), "..") - ), + assign_expr_suggestion(cx, x, l.span, &inner_expr, return_type, vec), ), // NOTE: don't use the stmt span to avoid touching the trailing semicolon Node::Stmt(_) => (expr.span, format!("{inner_expr};\n{indent}{vec}[] as {return_type}")), @@ -131,3 +135,41 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr: ); } } + +fn let_stmt_suggestion( + cx: &LateContext<'_>, + let_stmt: &LetStmt<'_>, + inner_expr: &str, + return_type: Ty<'_>, + vec_str: &str, +) -> String { + let indent = snippet_indent(cx, let_stmt.span).unwrap_or_default(); + format!( + "{inner_expr};\n{}let {var_name}: {return_type} = {vec_str}[];", + indent, + var_name = snippet(cx, let_stmt.pat.span.source_callsite(), "..") + ) +} + +fn assign_expr_suggestion( + cx: &LateContext<'_>, + outer_expr: &Expr<'_>, + assign_expr_span: Span, + inner_expr: &str, + return_type: Ty<'_>, + vec_str: &str, +) -> String { + let mut parent_hir_node = cx.tcx.parent_hir_node(outer_expr.hir_id); + if let Node::Stmt(stmt) = parent_hir_node { + parent_hir_node = cx.tcx.parent_hir_node(stmt.hir_id); + } + let needs_curly = !matches!(parent_hir_node, Node::Block(_)); + + let indent = snippet_indent(cx, outer_expr.span).unwrap_or_default(); + let var_name = snippet(cx, assign_expr_span.source_callsite(), ".."); + if needs_curly { + format!("{{\n {indent}{inner_expr};\n {indent}{var_name} = {vec_str}[] as {return_type}\n{indent}}}",) + } else { + format!("{inner_expr};\n{indent}{var_name} = {vec_str}[] as {return_type}") + } +} diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index a1e1b763dccb..503d581d6c7f 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.93" +version = "0.1.94" edition = "2024" description = "Helpful tools for writing lints, provided as they are used in Clippy" repository = "https://github.com/rust-lang/rust-clippy" @@ -16,6 +16,10 @@ itertools = "0.12" rustc_apfloat = "0.2.0" serde = { version = "1.0", features = ["derive"] } +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ['cfg(bootstrap)'] + [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] rustc_private = true diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 4b1a10a3d9cf..dc8695fef9f5 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-11-28 +nightly-2025-12-11 ``` diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 86d17a8231d5..4a7fa3472cae 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -40,6 +40,7 @@ msrv_aliases! { 1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE } 1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN } 1,68,0 { PATH_MAIN_SEPARATOR_STR } + 1,67,0 { ILOG2 } 1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS } 1,63,0 { CLONE_INTO, CONST_SLICE_FROM_REF } 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_C_FN } diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 1d1537dd0e91..00f4a9c7e586 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -180,6 +180,7 @@ generate! { has_significant_drop, hidden_glob_reexports, hygiene, + ilog, insert, insert_str, inspect, @@ -207,6 +208,7 @@ generate! { join, kw, lazy_static, + leading_zeros, lint_vec, ln, lock, diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml index b73a7c7bb4d9..ee6d6cdbc34e 100644 --- a/declare_clippy_lint/Cargo.toml +++ b/declare_clippy_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "declare_clippy_lint" -version = "0.1.93" +version = "0.1.94" edition = "2024" repository = "https://github.com/rust-lang/rust-clippy" license = "MIT OR Apache-2.0" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5157b79832a3..1384f4078ebe 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-11-28" +channel = "nightly-2025-12-11" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" diff --git a/tests/ui-toml/large_stack_frames_for_macros/clippy.toml b/tests/ui-toml/large_stack_frames_for_macros/clippy.toml new file mode 100644 index 000000000000..b6fd0e8a0483 --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_macros/clippy.toml @@ -0,0 +1 @@ +stack-size-threshold = 0 diff --git a/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs b/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs new file mode 100644 index 000000000000..1f6265590f93 --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs @@ -0,0 +1,42 @@ +//@ignore-target: i686 +//@normalize-stderr-test: "\b10000(08|16|32)\b" -> "100$$PTR" +//@normalize-stderr-test: "\b2500(060|120)\b" -> "250$$PTR" + +#![warn(clippy::large_stack_frames)] + +extern crate serde; +use serde::{Deserialize, Serialize}; + +struct ArrayDefault([u8; N]); + +macro_rules! mac { + ($name:ident) => { + fn foo() { + let $name = 1; + println!("macro_name called"); + } + + fn bar() { + let $name = ArrayDefault([0; 1000]); + } + }; +} + +mac!(something); +//~^ large_stack_frames +//~| large_stack_frames + +#[derive(Deserialize, Serialize)] +//~^ large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +//~| large_stack_frames +struct S { + a: [u128; 31], +} + +fn main() {} diff --git a/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.stderr b/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.stderr new file mode 100644 index 000000000000..bc222f6b1039 --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.stderr @@ -0,0 +1,89 @@ +error: function `foo` generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:25:1 + | +LL | fn foo() { + | --- this function has a stack frame size of 20 bytes +... +LL | mac!(something); + | ^^^^^^^^^^^^^^^ + | + = note: 20 bytes is larger than Clippy's configured `stack-size-threshold` of 0 + = note: allocating large amounts of stack space can overflow the stack and cause the program to abort + = note: `-D clippy::large-stack-frames` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]` + +error: function `bar` generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:25:1 + | +LL | fn bar() { + | --- this function has a stack frame size of 2000 bytes +LL | let $name = ArrayDefault([0; 1000]); + | --------- this is the largest part, at 1000 bytes for type `[u8; 1000]` +... +LL | mac!(something); + | ^^^^^^^^^^^^^^^ + | + = note: 2000 bytes is larger than Clippy's configured `stack-size-threshold` of 0 + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: method generated by this macro may allocate a lot of stack space + --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:23 + | +LL | #[derive(Deserialize, Serialize)] + | ^^^^^^^^^ + +error: aborting due to 10 previous errors + diff --git a/tests/ui-toml/large_stack_frames_for_special_targets/clippy.toml b/tests/ui-toml/large_stack_frames_for_special_targets/clippy.toml new file mode 100644 index 000000000000..02f3bc02dc4b --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_special_targets/clippy.toml @@ -0,0 +1,2 @@ +stack-size-threshold = 0 +allow-large-stack-frames-in-tests = false diff --git a/tests/ui-toml/large_stack_frames_for_special_targets/large_stack_frames.rs b/tests/ui-toml/large_stack_frames_for_special_targets/large_stack_frames.rs new file mode 100644 index 000000000000..cc01232ca408 --- /dev/null +++ b/tests/ui-toml/large_stack_frames_for_special_targets/large_stack_frames.rs @@ -0,0 +1,13 @@ +// This test checks if `clippy::large_stack_frames` is working correctly when encountering functions +// generated by special compiling targets like `--test`. +//@compile-flags: --test +//@check-pass + +#![warn(clippy::large_stack_frames)] + +#[cfg(test)] +#[expect(clippy::large_stack_frames)] +mod test { + #[test] + fn main_test() {} +} diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed index 419e62f92f46..3683e826aa92 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed @@ -1,6 +1,7 @@ //@aux-build:proc_macro_derive.rs #![warn(clippy::nonstandard_macro_braces)] +#![allow(clippy::println_empty_string)] extern crate proc_macro_derive; extern crate quote; @@ -75,3 +76,16 @@ fn issue9913() { [0]; // separate statement, not indexing into the result of println. //~^^ nonstandard_macro_braces } + +fn issue15594() { + println!(); + println!(""); + println!(); + //~^ nonstandard_macro_braces + println!(""); + //~^ nonstandard_macro_braces + println!(); + //~^ nonstandard_macro_braces + println!(""); + //~^ nonstandard_macro_braces +} diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs index b0bbced4ea3c..c1779dceff17 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs @@ -1,6 +1,7 @@ //@aux-build:proc_macro_derive.rs #![warn(clippy::nonstandard_macro_braces)] +#![allow(clippy::println_empty_string)] extern crate proc_macro_derive; extern crate quote; @@ -75,3 +76,16 @@ fn issue9913() { [0]; // separate statement, not indexing into the result of println. //~^^ nonstandard_macro_braces } + +fn issue15594() { + println!(); + println!(""); + println![]; + //~^ nonstandard_macro_braces + println![""]; + //~^ nonstandard_macro_braces + println! {}; + //~^ nonstandard_macro_braces + println! {""}; + //~^ nonstandard_macro_braces +} diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr index 87325f05c9bc..2488f7fa01e5 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr @@ -1,5 +1,5 @@ error: use of irregular braces for `vec!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:44:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:45:13 | LL | let _ = vec! {1, 2, 3}; | ^^^^^^^^^^^^^^ help: consider writing: `vec![1, 2, 3]` @@ -8,31 +8,31 @@ LL | let _ = vec! {1, 2, 3}; = help: to override `-D warnings` add `#[allow(clippy::nonstandard_macro_braces)]` error: use of irregular braces for `format!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:46:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:47:13 | LL | let _ = format!["ugh {} stop being such a good compiler", "hello"]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `format!("ugh {} stop being such a good compiler", "hello")` error: use of irregular braces for `matches!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:48:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:49:13 | LL | let _ = matches!{{}, ()}; | ^^^^^^^^^^^^^^^^ help: consider writing: `matches!({}, ())` error: use of irregular braces for `quote!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:50:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:51:13 | LL | let _ = quote!(let x = 1;); | ^^^^^^^^^^^^^^^^^^ help: consider writing: `quote!{let x = 1;}` error: use of irregular braces for `quote::quote!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:52:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:53:13 | LL | let _ = quote::quote!(match match match); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `quote::quote!{match match match}` error: use of irregular braces for `vec!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:18:9 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:19:9 | LL | vec!{0, 0, 0} | ^^^^^^^^^^^^^ help: consider writing: `vec![0, 0, 0]` @@ -43,22 +43,46 @@ LL | let _ = test!(); // trigger when macro def is inside our own crate = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error: use of irregular braces for `type_pos!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:62:12 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:63:12 | LL | let _: type_pos!(usize) = vec![]; | ^^^^^^^^^^^^^^^^ help: consider writing: `type_pos![usize]` error: use of irregular braces for `eprint!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:65:5 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:66:5 | LL | eprint!("test if user config overrides defaults"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `eprint!["test if user config overrides defaults"]` error: use of irregular braces for `println!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:74:5 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:75:5 | LL | println! {"hello world"} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `println!("hello world");` -error: aborting due to 9 previous errors +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:83:5 + | +LL | println![]; + | ^^^^^^^^^^ help: consider writing: `println!()` + +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:85:5 + | +LL | println![""]; + | ^^^^^^^^^^^^ help: consider writing: `println!("")` + +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:87:5 + | +LL | println! {}; + | ^^^^^^^^^^^ help: consider writing: `println!()` + +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:89:5 + | +LL | println! {""}; + | ^^^^^^^^^^^^^ help: consider writing: `println!("")` + +error: aborting due to 13 previous errors diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index d5040f4a39bf..e208bd510657 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -9,6 +9,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect allow-expect-in-consts allow-expect-in-tests allow-indexing-slicing-in-tests + allow-large-stack-frames-in-tests allow-mixed-uninlined-format-args allow-one-hash-in-raw-strings allow-panic-in-tests @@ -107,6 +108,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect allow-expect-in-consts allow-expect-in-tests allow-indexing-slicing-in-tests + allow-large-stack-frames-in-tests allow-mixed-uninlined-format-args allow-one-hash-in-raw-strings allow-panic-in-tests @@ -205,6 +207,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni allow-expect-in-consts allow-expect-in-tests allow-indexing-slicing-in-tests + allow-large-stack-frames-in-tests allow-mixed-uninlined-format-args allow-one-hash-in-raw-strings allow-panic-in-tests diff --git a/tests/ui/borrow_as_ptr.fixed b/tests/ui/borrow_as_ptr.fixed index bfe826508f36..a4689a7840ce 100644 --- a/tests/ui/borrow_as_ptr.fixed +++ b/tests/ui/borrow_as_ptr.fixed @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs #![warn(clippy::borrow_as_ptr)] -#![allow(clippy::useless_vec)] +#![allow(clippy::useless_vec, clippy::ptr_offset_by_literal)] extern crate proc_macros; diff --git a/tests/ui/borrow_as_ptr.rs b/tests/ui/borrow_as_ptr.rs index ce248f157c6e..d7468f37a3a4 100644 --- a/tests/ui/borrow_as_ptr.rs +++ b/tests/ui/borrow_as_ptr.rs @@ -1,6 +1,6 @@ //@aux-build:proc_macros.rs #![warn(clippy::borrow_as_ptr)] -#![allow(clippy::useless_vec)] +#![allow(clippy::useless_vec, clippy::ptr_offset_by_literal)] extern crate proc_macros; diff --git a/tests/ui/checked_unwrap/simple_conditionals.rs b/tests/ui/checked_unwrap/simple_conditionals.rs index c6476a7507a1..bab20b091d38 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.rs +++ b/tests/ui/checked_unwrap/simple_conditionals.rs @@ -472,3 +472,22 @@ fn issue15321() { //~^ unnecessary_unwrap } } + +mod issue16188 { + struct Foo { + value: Option, + } + + impl Foo { + pub fn bar(&mut self) { + let print_value = |v: i32| { + println!("{}", v); + }; + + if self.value.is_none() { + self.value = Some(10); + print_value(self.value.unwrap()); + } + } + } +} diff --git a/tests/ui/crashes/ice-4579.rs b/tests/ui/crashes/ice-4579.rs index 14c8113e315b..a2592e74c66d 100644 --- a/tests/ui/crashes/ice-4579.rs +++ b/tests/ui/crashes/ice-4579.rs @@ -1,6 +1,6 @@ //@ check-pass -#![allow(clippy::single_match)] +#![allow(clippy::single_match, clippy::ptr_offset_by_literal)] use std::ptr; diff --git a/tests/ui/decimal_bitwise_operands.rs b/tests/ui/decimal_bitwise_operands.rs new file mode 100644 index 000000000000..f1c053bb4358 --- /dev/null +++ b/tests/ui/decimal_bitwise_operands.rs @@ -0,0 +1,133 @@ +#![allow( + clippy::erasing_op, + clippy::no_effect, + clippy::unnecessary_operation, + clippy::unnecessary_cast, + clippy::op_ref +)] +#![warn(clippy::decimal_bitwise_operands)] + +macro_rules! bitwise_op { + ($x:expr, $y:expr) => { + $x & $y; + }; +} + +pub const SOME_CONST: i32 = 12345; + +fn main() { + let mut x = 0; + // BAD: Bitwise operation, decimal literal, one literal + x & 9_8765_4321; //~ decimal_bitwise_operands + x & 100_i32; //~ decimal_bitwise_operands + x | (/* comment */99); //~ decimal_bitwise_operands + x ^ (99); //~ decimal_bitwise_operands + x &= 99; //~ decimal_bitwise_operands + x |= { 99 }; //~ decimal_bitwise_operands + x |= { { 99 } }; //~ decimal_bitwise_operands + x |= { + 0b1000; + 99 //~ decimal_bitwise_operands + }; + x ^= (99); //~ decimal_bitwise_operands + + // BAD: Bitwise operation, decimal literal, two literals + 0b1010 & 99; //~ decimal_bitwise_operands + 0b1010 | (99); //~ decimal_bitwise_operands + 0b1010 ^ (/* comment */99); //~ decimal_bitwise_operands + 99 & 0b1010; //~ decimal_bitwise_operands + (99) | 0b1010; //~ decimal_bitwise_operands + (/* comment */99) ^ 0b1010; //~ decimal_bitwise_operands + 0xD | { 99 }; //~ decimal_bitwise_operands + 88 & 99; + //~^ decimal_bitwise_operands + //~| decimal_bitwise_operands + 37 & 38 & 39; + //~^ decimal_bitwise_operands + //~| decimal_bitwise_operands + //~| decimal_bitwise_operands + + // GOOD: Bitwise operation, binary/hex/octal literal, one literal + x & 0b1010; + x | 0b1010; + x ^ 0b1010; + x &= 0b1010; + x |= 0b1010; + x ^= 0b1010; + x & 0xD; + x & 0o77; + x | 0o123; + x ^ 0o377; + x &= 0o777; + x |= 0o7; + x ^= 0o70; + + // GOOD: Bitwise operation, binary/hex/octal literal, two literals + 0b1010 & 0b1101; + 0xD ^ 0xF; + 0o377 ^ 0o77; + 0b1101 ^ 0xFF; + + // GOOD: Numeric operation, any literal + x += 99; + x -= 0b1010; + x *= 0xD; + 99 + 99; + 0b1010 - 0b1101; + 0xD * 0xD; + + // BAD: Unary, cast and reference, decimal literal + x & !100; //~ decimal_bitwise_operands + x & -100; //~ decimal_bitwise_operands + x & (100 as i32); //~ decimal_bitwise_operands + x & &100; //~ decimal_bitwise_operands + + // GOOD: Unary, cast and reference, non-decimal literal + x & !0b1101; + x & -0xD; + x & (0o333 as i32); + x & &0b1010; + + // GOOD: Bitwise operation, variables only + let y = 0; + x & y; + x &= y; + x + y; + x += y; + + // GOOD: Macro expansion (should be ignored) + bitwise_op!(x, 123); + bitwise_op!(0b1010, 123); + + // GOOD: Using const (should be ignored) + x & SOME_CONST; + x |= SOME_CONST; + + // GOOD: Parenthesized binary/hex literal (should not trigger lint) + x & (0b1111); + x |= (0b1010); + x ^ (/* comment */0b1100); + (0xFF) & x; + + // GOOD: Power of two and power of two minus one + x & 16; // 2^4 + x | (31); // 2^5 - 1 + x ^ 0x40; // 2^6 (hex) + x ^= 7; // 2^3 - 1 + + // GOOD: Bitwise operation, single digit decimal literal + 5 & 9; + x ^ 6; + x ^= 7; + + // GOOD: More complex expressions + (x + 1) & 0xFF; + (x * 2) | (y & 0xF); + (x ^ y) & 0b11110000; + x | (1 << 9); + + // GOOD: Special cases + x & 0; // All bits off + x | !0; // All bits on + x ^ 1; // Toggle LSB +} diff --git a/tests/ui/decimal_bitwise_operands.stderr b/tests/ui/decimal_bitwise_operands.stderr new file mode 100644 index 000000000000..1b2b7bb71b69 --- /dev/null +++ b/tests/ui/decimal_bitwise_operands.stderr @@ -0,0 +1,204 @@ +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:21:9 + | +LL | x & 9_8765_4321; + | ^^^^^^^^^^^ + | + = help: use binary (0b11_1010_1101_1110_0110_1000_1011_0001), hex (0x3ade_68b1), or octal (0o7_267_464_261) notation for better readability + = note: `-D clippy::decimal-bitwise-operands` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::decimal_bitwise_operands)]` + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:22:9 + | +LL | x & 100_i32; + | ^^^^^^^ + | + = help: use binary (0b110_0100_i32), hex (0x0064_i32), or octal (0o144_i32) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:23:23 + | +LL | x | (/* comment */99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:24:10 + | +LL | x ^ (99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:25:10 + | +LL | x &= 99; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:26:12 + | +LL | x |= { 99 }; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:27:14 + | +LL | x |= { { 99 } }; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:30:9 + | +LL | 99 + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:32:11 + | +LL | x ^= (99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:35:14 + | +LL | 0b1010 & 99; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:36:15 + | +LL | 0b1010 | (99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:37:28 + | +LL | 0b1010 ^ (/* comment */99); + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:38:5 + | +LL | 99 & 0b1010; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:39:6 + | +LL | (99) | 0b1010; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:40:19 + | +LL | (/* comment */99) ^ 0b1010; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:41:13 + | +LL | 0xD | { 99 }; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:42:5 + | +LL | 88 & 99; + | ^^ + | + = help: use binary (0b101_1000), hex (0x0058), or octal (0o130) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:42:10 + | +LL | 88 & 99; + | ^^ + | + = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:45:15 + | +LL | 37 & 38 & 39; + | ^^ + | + = help: use binary (0b10_0111), hex (0x0027), or octal (0o47) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:45:5 + | +LL | 37 & 38 & 39; + | ^^ + | + = help: use binary (0b10_0101), hex (0x0025), or octal (0o45) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:45:10 + | +LL | 37 & 38 & 39; + | ^^ + | + = help: use binary (0b10_0110), hex (0x0026), or octal (0o46) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:80:10 + | +LL | x & !100; + | ^^^ + | + = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:81:10 + | +LL | x & -100; + | ^^^ + | + = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:82:10 + | +LL | x & (100 as i32); + | ^^^ + | + = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability + +error: using decimal literal for bitwise operation + --> tests/ui/decimal_bitwise_operands.rs:83:10 + | +LL | x & &100; + | ^^^ + | + = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability + +error: aborting due to 25 previous errors + diff --git a/tests/ui/deprecated.stderr b/tests/ui/deprecated.stderr index cd225da611c4..fa70371b926f 100644 --- a/tests/ui/deprecated.stderr +++ b/tests/ui/deprecated.stderr @@ -61,7 +61,7 @@ error: lint `clippy::should_assert_eq` has been removed: `assert!(a == b)` can n LL | #![warn(clippy::should_assert_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: lint `clippy::string_to_string` has been removed: `clippy:implicit_clone` covers those cases +error: lint `clippy::string_to_string` has been removed: `clippy::implicit_clone` covers those cases --> tests/ui/deprecated.rs:15:9 | LL | #![warn(clippy::string_to_string)] diff --git a/tests/ui/entry.fixed b/tests/ui/entry.fixed index f2df9f0204ea..1e36ca4f1f09 100644 --- a/tests/ui/entry.fixed +++ b/tests/ui/entry.fixed @@ -248,4 +248,28 @@ mod issue14449 { } } +// Don't suggest when it would cause `MutexGuard` to be held across an await point. +mod issue_16173 { + use std::collections::HashMap; + use std::sync::Mutex; + + async fn f() {} + + async fn foo() { + let mu_map = Mutex::new(HashMap::new()); + if !mu_map.lock().unwrap().contains_key(&0) { + f().await; + mu_map.lock().unwrap().insert(0, 0); + } + + if mu_map.lock().unwrap().contains_key(&1) { + todo!(); + } else { + mu_map.lock().unwrap().insert(1, 42); + todo!(); + f().await; + } + } +} + fn main() {} diff --git a/tests/ui/entry.rs b/tests/ui/entry.rs index 166eea417ac2..b3da0ef3ffd6 100644 --- a/tests/ui/entry.rs +++ b/tests/ui/entry.rs @@ -254,4 +254,28 @@ mod issue14449 { } } +// Don't suggest when it would cause `MutexGuard` to be held across an await point. +mod issue_16173 { + use std::collections::HashMap; + use std::sync::Mutex; + + async fn f() {} + + async fn foo() { + let mu_map = Mutex::new(HashMap::new()); + if !mu_map.lock().unwrap().contains_key(&0) { + f().await; + mu_map.lock().unwrap().insert(0, 0); + } + + if mu_map.lock().unwrap().contains_key(&1) { + todo!(); + } else { + mu_map.lock().unwrap().insert(1, 42); + todo!(); + f().await; + } + } +} + fn main() {} diff --git a/tests/ui/len_without_is_empty.rs b/tests/ui/len_without_is_empty.rs index 011833072d76..509348628dd6 100644 --- a/tests/ui/len_without_is_empty.rs +++ b/tests/ui/len_without_is_empty.rs @@ -473,4 +473,16 @@ impl Alias2 { } } +// Issue #16190 +pub struct RefMutLenButRefIsEmpty; +impl RefMutLenButRefIsEmpty { + pub fn len(&mut self) -> usize { + todo!() + } + + pub fn is_empty(&self) -> bool { + todo!() + } +} + fn main() {} diff --git a/tests/ui/manual_ilog2.fixed b/tests/ui/manual_ilog2.fixed new file mode 100644 index 000000000000..a0f6d9392c30 --- /dev/null +++ b/tests/ui/manual_ilog2.fixed @@ -0,0 +1,32 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::manual_ilog2)] +#![allow(clippy::unnecessary_operation)] + +use proc_macros::{external, with_span}; + +fn foo(a: u32, b: u64) { + a.ilog2(); //~ manual_ilog2 + a.ilog2(); //~ manual_ilog2 + + b.ilog2(); //~ manual_ilog2 + 64 - b.leading_zeros(); // No lint because manual ilog2 is `BIT_WIDTH - 1 - x.leading_zeros()` + + // don't lint when macros are involved + macro_rules! two { + () => { + 2 + }; + }; + + macro_rules! thirty_one { + () => { + 31 + }; + }; + + a.ilog(two!()); + thirty_one!() - a.leading_zeros(); + + external!($a.ilog(2)); + with_span!(span; a.ilog(2)); +} diff --git a/tests/ui/manual_ilog2.rs b/tests/ui/manual_ilog2.rs new file mode 100644 index 000000000000..bd4b5d9d3c0d --- /dev/null +++ b/tests/ui/manual_ilog2.rs @@ -0,0 +1,32 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::manual_ilog2)] +#![allow(clippy::unnecessary_operation)] + +use proc_macros::{external, with_span}; + +fn foo(a: u32, b: u64) { + 31 - a.leading_zeros(); //~ manual_ilog2 + a.ilog(2); //~ manual_ilog2 + + 63 - b.leading_zeros(); //~ manual_ilog2 + 64 - b.leading_zeros(); // No lint because manual ilog2 is `BIT_WIDTH - 1 - x.leading_zeros()` + + // don't lint when macros are involved + macro_rules! two { + () => { + 2 + }; + }; + + macro_rules! thirty_one { + () => { + 31 + }; + }; + + a.ilog(two!()); + thirty_one!() - a.leading_zeros(); + + external!($a.ilog(2)); + with_span!(span; a.ilog(2)); +} diff --git a/tests/ui/manual_ilog2.stderr b/tests/ui/manual_ilog2.stderr new file mode 100644 index 000000000000..7c9694f35330 --- /dev/null +++ b/tests/ui/manual_ilog2.stderr @@ -0,0 +1,23 @@ +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:8:5 + | +LL | 31 - a.leading_zeros(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.ilog2()` + | + = note: `-D clippy::manual-ilog2` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_ilog2)]` + +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:9:5 + | +LL | a.ilog(2); + | ^^^^^^^^^ help: try: `a.ilog2()` + +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:11:5 + | +LL | 63 - b.leading_zeros(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `b.ilog2()` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/manual_saturating_arithmetic.fixed b/tests/ui/manual_saturating_arithmetic.fixed index 304be05f6c4c..8dd142b2c79a 100644 --- a/tests/ui/manual_saturating_arithmetic.fixed +++ b/tests/ui/manual_saturating_arithmetic.fixed @@ -58,3 +58,13 @@ fn main() { let _ = 1i8.checked_sub(1).unwrap_or(127); // ok let _ = 1i8.checked_sub(-1).unwrap_or(-128); // ok } + +fn issue15655() { + let _ = 5u32.saturating_sub(1u32); //~ manual_saturating_arithmetic + let _ = 5u32.checked_add(1u32).unwrap_or_default(); // ok + let _ = 5u32.checked_mul(1u32).unwrap_or_default(); // ok + + let _ = 5i32.checked_sub(1i32).unwrap_or_default(); // ok + let _ = 5i32.checked_add(1i32).unwrap_or_default(); // ok + let _ = 5i32.checked_mul(1i32).unwrap_or_default(); // ok +} diff --git a/tests/ui/manual_saturating_arithmetic.rs b/tests/ui/manual_saturating_arithmetic.rs index c2b570e974ac..9cc8bc42410d 100644 --- a/tests/ui/manual_saturating_arithmetic.rs +++ b/tests/ui/manual_saturating_arithmetic.rs @@ -73,3 +73,13 @@ fn main() { let _ = 1i8.checked_sub(1).unwrap_or(127); // ok let _ = 1i8.checked_sub(-1).unwrap_or(-128); // ok } + +fn issue15655() { + let _ = 5u32.checked_sub(1u32).unwrap_or_default(); //~ manual_saturating_arithmetic + let _ = 5u32.checked_add(1u32).unwrap_or_default(); // ok + let _ = 5u32.checked_mul(1u32).unwrap_or_default(); // ok + + let _ = 5i32.checked_sub(1i32).unwrap_or_default(); // ok + let _ = 5i32.checked_add(1i32).unwrap_or_default(); // ok + let _ = 5i32.checked_mul(1i32).unwrap_or_default(); // ok +} diff --git a/tests/ui/manual_saturating_arithmetic.stderr b/tests/ui/manual_saturating_arithmetic.stderr index 2f006a3ae170..aec0f0a16419 100644 --- a/tests/ui/manual_saturating_arithmetic.stderr +++ b/tests/ui/manual_saturating_arithmetic.stderr @@ -165,5 +165,11 @@ LL | | .checked_sub(-1) LL | | .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727); | |_______________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(-1)` -error: aborting due to 24 previous errors +error: manual saturating arithmetic + --> tests/ui/manual_saturating_arithmetic.rs:78:13 + | +LL | let _ = 5u32.checked_sub(1u32).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `5u32.saturating_sub(1u32)` + +error: aborting due to 25 previous errors diff --git a/tests/ui/match_like_matches_macro.fixed b/tests/ui/match_like_matches_macro.fixed index a1c95e8a94f1..dad59c1ce6e4 100644 --- a/tests/ui/match_like_matches_macro.fixed +++ b/tests/ui/match_like_matches_macro.fixed @@ -223,3 +223,10 @@ fn msrv_1_42() { let _y = matches!(Some(5), Some(0)); //~^^^^ match_like_matches_macro } + +#[expect(clippy::option_option)] +fn issue15841(opt: Option>>, value: i32) { + // Lint: no if-let _in the guard_ + let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() })); + //~^^^^ match_like_matches_macro +} diff --git a/tests/ui/match_like_matches_macro.rs b/tests/ui/match_like_matches_macro.rs index eb419ba5bf8d..94bc6433e5cb 100644 --- a/tests/ui/match_like_matches_macro.rs +++ b/tests/ui/match_like_matches_macro.rs @@ -267,3 +267,13 @@ fn msrv_1_42() { }; //~^^^^ match_like_matches_macro } + +#[expect(clippy::option_option)] +fn issue15841(opt: Option>>, value: i32) { + // Lint: no if-let _in the guard_ + let _ = match opt { + Some(first) if (if let Some(second) = first { true } else { todo!() }) => true, + _ => false, + }; + //~^^^^ match_like_matches_macro +} diff --git a/tests/ui/match_like_matches_macro.stderr b/tests/ui/match_like_matches_macro.stderr index ae277ce4dca6..a8e352461dbb 100644 --- a/tests/ui/match_like_matches_macro.stderr +++ b/tests/ui/match_like_matches_macro.stderr @@ -6,10 +6,18 @@ LL | let _y = match x { LL | | Some(0) => true, LL | | _ => false, LL | | }; - | |_____^ help: try: `matches!(x, Some(0))` + | |_____^ | = note: `-D clippy::match-like-matches-macro` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::match_like_matches_macro)]` +help: use `matches!` directly + | +LL - let _y = match x { +LL - Some(0) => true, +LL - _ => false, +LL - }; +LL + let _y = matches!(x, Some(0)); + | error: redundant pattern matching, consider using `is_some()` --> tests/ui/match_like_matches_macro.rs:20:14 @@ -42,13 +50,28 @@ LL | let _zz = match x { LL | | Some(r) if r == 0 => false, LL | | _ => true, LL | | }; - | |_____^ help: try: `!matches!(x, Some(r) if r == 0)` + | |_____^ + | +help: use `matches!` directly + | +LL - let _zz = match x { +LL - Some(r) if r == 0 => false, +LL - _ => true, +LL - }; +LL + let _zz = !matches!(x, Some(r) if r == 0); + | -error: if let .. else expression looks like `matches!` macro +error: `if let .. else` expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:41:16 | LL | let _zzz = if let Some(5) = x { true } else { false }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(x, Some(5))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `matches!` directly + | +LL - let _zzz = if let Some(5) = x { true } else { false }; +LL + let _zzz = matches!(x, Some(5)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:66:20 @@ -59,7 +82,17 @@ LL | | E::A(_) => true, LL | | E::B(_) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(x, E::A(_) | E::B(_))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _ans = match x { +LL - E::A(_) => true, +LL - E::B(_) => true, +LL - _ => false, +LL - }; +LL + let _ans = matches!(x, E::A(_) | E::B(_)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:77:20 @@ -71,7 +104,19 @@ LL | | true ... | LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(x, E::A(_) | E::B(_))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _ans = match x { +LL - E::A(_) => { +LL - true +LL - } +LL - E::B(_) => true, +LL - _ => false, +LL - }; +LL + let _ans = matches!(x, E::A(_) | E::B(_)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:88:20 @@ -82,7 +127,17 @@ LL | | E::B(_) => false, LL | | E::C => false, LL | | _ => true, LL | | }; - | |_________^ help: try: `!matches!(x, E::B(_) | E::C)` + | |_________^ + | +help: use `matches!` directly + | +LL - let _ans = match x { +LL - E::B(_) => false, +LL - E::C => false, +LL - _ => true, +LL - }; +LL + let _ans = !matches!(x, E::B(_) | E::C); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:149:18 @@ -92,7 +147,16 @@ LL | let _z = match &z { LL | | Some(3) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(z, Some(3))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _z = match &z { +LL - Some(3) => true, +LL - _ => false, +LL - }; +LL + let _z = matches!(z, Some(3)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:159:18 @@ -102,7 +166,16 @@ LL | let _z = match &z { LL | | Some(3) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(&z, Some(3))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _z = match &z { +LL - Some(3) => true, +LL - _ => false, +LL - }; +LL + let _z = matches!(&z, Some(3)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:177:21 @@ -112,7 +185,16 @@ LL | let _ = match &z { LL | | AnEnum::X => true, LL | | _ => false, LL | | }; - | |_____________^ help: try: `matches!(&z, AnEnum::X)` + | |_____________^ + | +help: use `matches!` directly + | +LL - let _ = match &z { +LL - AnEnum::X => true, +LL - _ => false, +LL - }; +LL + let _ = matches!(&z, AnEnum::X); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:192:20 @@ -122,7 +204,16 @@ LL | let _res = match &val { LL | | &Some(ref _a) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(&val, &Some(ref _a))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _res = match &val { +LL - &Some(ref _a) => true, +LL - _ => false, +LL - }; +LL + let _res = matches!(&val, &Some(ref _a)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:205:20 @@ -132,7 +223,16 @@ LL | let _res = match &val { LL | | &Some(ref _a) => true, LL | | _ => false, LL | | }; - | |_________^ help: try: `matches!(&val, &Some(ref _a))` + | |_________^ + | +help: use `matches!` directly + | +LL - let _res = match &val { +LL - &Some(ref _a) => true, +LL - _ => false, +LL - }; +LL + let _res = matches!(&val, &Some(ref _a)); + | error: match expression looks like `matches!` macro --> tests/ui/match_like_matches_macro.rs:264:14 @@ -142,7 +242,35 @@ LL | let _y = match Some(5) { LL | | Some(0) => true, LL | | _ => false, LL | | }; - | |_____^ help: try: `matches!(Some(5), Some(0))` + | |_____^ + | +help: use `matches!` directly + | +LL - let _y = match Some(5) { +LL - Some(0) => true, +LL - _ => false, +LL - }; +LL + let _y = matches!(Some(5), Some(0)); + | -error: aborting due to 14 previous errors +error: match expression looks like `matches!` macro + --> tests/ui/match_like_matches_macro.rs:274:13 + | +LL | let _ = match opt { + | _____________^ +LL | | Some(first) if (if let Some(second) = first { true } else { todo!() }) => true, +LL | | _ => false, +LL | | }; + | |_____^ + | +help: use `matches!` directly + | +LL - let _ = match opt { +LL - Some(first) if (if let Some(second) = first { true } else { todo!() }) => true, +LL - _ => false, +LL - }; +LL + let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() })); + | + +error: aborting due to 15 previous errors diff --git a/tests/ui/match_like_matches_macro_if_let_guard.rs b/tests/ui/match_like_matches_macro_if_let_guard.rs new file mode 100644 index 000000000000..b596d36072e5 --- /dev/null +++ b/tests/ui/match_like_matches_macro_if_let_guard.rs @@ -0,0 +1,51 @@ +//@check-pass +#![warn(clippy::match_like_matches_macro)] +#![feature(if_let_guard)] + +#[expect(clippy::option_option)] +fn issue15841(opt: Option>>, value: i32) { + let _ = match opt { + Some(first) + if let Some(second) = first + && let Some(third) = second + && third == value => + { + true + }, + _ => false, + }; + + // if-let is the second if + let _ = match opt { + Some(first) + if first.is_some() + && let Some(second) = first => + { + true + }, + _ => false, + }; + + // if-let is the third if + let _ = match opt { + Some(first) + if first.is_some() + && first.is_none() + && let Some(second) = first => + { + true + }, + _ => false, + }; + + // don't get confused by `or`s + let _ = match opt { + Some(first) + if (first.is_some() || first.is_none()) + && let Some(second) = first => + { + true + }, + _ => false, + }; +} diff --git a/tests/ui/missing_asserts_for_indexing.stderr b/tests/ui/missing_asserts_for_indexing.stderr index b686eda7530a..d5b5455343e4 100644 --- a/tests/ui/missing_asserts_for_indexing.stderr +++ b/tests/ui/missing_asserts_for_indexing.stderr @@ -1,407 +1,191 @@ error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:30:5 | -LL | assert!(v.len() < 5); - | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:5 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:12 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:30:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ = note: asserting the length before indexing will elide bounds checks = note: `-D clippy::missing-asserts-for-indexing` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]` +help: provide the highest index that is indexed with + | +LL - assert!(v.len() < 5); +LL + assert!(v.len() > 4); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:36:5 | -LL | assert!(v.len() <= 5); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:5 +help: provide the highest index that is indexed with | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:12 +LL - assert!(v.len() <= 5); +LL + assert!(v.len() > 4); | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:36:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:42:5 | -LL | assert!(v.len() > 3); - | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:5 +help: provide the highest index that is indexed with | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:12 +LL - assert!(v.len() > 3); +LL + assert!(v.len() > 4); | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:42:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:48:5 | -LL | assert!(v.len() >= 4); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:5 +help: provide the highest index that is indexed with | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:12 +LL - assert!(v.len() >= 4); +LL + assert!(v.len() > 4); | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:48:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:66:13 | -LL | assert!(v.len() >= 3); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 3)` -LL | let _ = v[0]; - | _____________^ -... | -LL | | let _ = v[1..4]; - | |___________________^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:66:13 - | LL | let _ = v[0]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:69:13 - | +... LL | let _ = v[1..4]; | ^^^^^^^ - = note: asserting the length before indexing will elide bounds checks + | +help: provide the highest index that is indexed with + | +LL - assert!(v.len() >= 3); +LL + assert!(v.len() > 3); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:81:13 | -LL | assert!(v.len() >= 4); - | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)` -LL | let _ = v[0]; - | _____________^ -... | -LL | | let _ = v[1..=4]; - | |____________________^ - | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:81:13 - | LL | let _ = v[0]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:84:13 - | +... LL | let _ = v[1..=4]; | ^^^^^^^^ - = note: asserting the length before indexing will elide bounds checks + | +help: provide the highest index that is indexed with + | +LL - assert!(v.len() >= 4); +LL + assert!(v.len() > 4); + | error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:97:13 | -LL | assert!(v1.len() >= 12); - | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` -LL | assert!(v2.len() >= 15); LL | let _ = v1[0] + v1[12]; - | ^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:97:13 +help: provide the highest index that is indexed with | -LL | let _ = v1[0] + v1[12]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:97:21 +LL - assert!(v1.len() >= 12); +LL + assert!(v1.len() > 12); | -LL | let _ = v1[0] + v1[12]; - | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:100:13 | -LL | assert!(v2.len() >= 15); - | ----------------------- help: provide the highest index that is indexed with: `assert!(v2.len() > 15)` -... LL | let _ = v2[5] + v2[15]; - | ^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:100:13 +help: provide the highest index that is indexed with | -LL | let _ = v2[5] + v2[15]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:100:21 +LL - assert!(v2.len() >= 15); +LL + assert!(v2.len() > 15); | -LL | let _ = v2[5] + v2[15]; - | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:106:13 | -LL | assert!(v1.len() >= 12); - | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)` -LL | assert!(v2.len() > 15); LL | let _ = v1[0] + v1[12]; - | ^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:106:13 +help: provide the highest index that is indexed with | -LL | let _ = v1[0] + v1[12]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:106:21 +LL - assert!(v1.len() >= 12); +LL + assert!(v1.len() > 12); | -LL | let _ = v1[0] + v1[12]; - | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:131:13 | -LL | assert!(v1.len() == 2); - | ---------------------- help: provide the highest index that is indexed with: `assert!(v1.len() == 3)` -... LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^ ^^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:131:13 +help: provide the highest index that is indexed with | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:131:21 +LL - assert!(v1.len() == 2); +LL + assert!(v1.len() == 3); | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:131:29 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:136:13 | -LL | assert!(2 == v3.len()); - | ---------------------- help: provide the highest index that is indexed with: `assert!(v3.len() == 3)` -... LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^ ^^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:136:13 +help: provide the highest index that is indexed with | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:136:21 +LL - assert!(2 == v3.len()); +LL + assert!(v3.len() == 3); | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:136:29 - | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:158:13 | -LL | assert_eq!(v1.len(), 2); - | ----------------------- help: provide the highest index that is indexed with: `assert_eq!(v1.len(), 3)` -... LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^ ^^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:158:13 +help: provide the highest index that is indexed with | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:158:21 +LL - assert_eq!(v1.len(), 2); +LL + assert_eq!(v1.len(), 3); | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:158:29 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:163:13 | -LL | assert_eq!(2, v3.len()); - | ----------------------- help: provide the highest index that is indexed with: `assert_eq!(v3.len(), 3)` -... LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^ ^^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:163:13 +help: provide the highest index that is indexed with | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:163:21 +LL - assert_eq!(2, v3.len()); +LL + assert_eq!(v3.len(), 3); | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:163:29 - | -LL | let _ = v3[0] + v3[1] + v3[2]; - | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:172:17 | -LL | assert_eq!(v.len(), 2); - | ---------------------- help: provide the highest index that is indexed with: `assert_eq!(v.len(), 3)` LL | let _ = v[0] + v[1] + v[2]; - | ^^^^^^^^^^^^^^^^^^ + | ^^^^ ^^^^ ^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:172:17 +help: provide the highest index that is indexed with | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:172:24 +LL - assert_eq!(v.len(), 2); +LL + assert_eq!(v.len(), 3); | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:172:31 - | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times with an `assert` that does not cover the highest index --> tests/ui/missing_asserts_for_indexing.rs:178:17 | -LL | debug_assert_eq!(v.len(), 2); - | ---------------------------- help: provide the highest index that is indexed with: `debug_assert_eq!(v.len(), 3)` LL | let _ = v[0] + v[1] + v[2]; - | ^^^^^^^^^^^^^^^^^^ + | ^^^^ ^^^^ ^^^^ | -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:178:17 +help: provide the highest index that is indexed with | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:178:24 +LL - debug_assert_eq!(v.len(), 2); +LL + debug_assert_eq!(v.len(), 3); | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing.rs:178:31 - | -LL | let _ = v[0] + v[1] + v[2]; - | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: aborting due to 15 previous errors diff --git a/tests/ui/missing_asserts_for_indexing_unfixable.stderr b/tests/ui/missing_asserts_for_indexing_unfixable.stderr index a17ad0232138..2929646494a4 100644 --- a/tests/ui/missing_asserts_for_indexing_unfixable.stderr +++ b/tests/ui/missing_asserts_for_indexing_unfixable.stderr @@ -2,34 +2,9 @@ error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:5 | LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ | = help: consider asserting the length before indexing: `assert!(v.len() > 4);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:5 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:12 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:19 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:26 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:33 - | -LL | v[0] + v[1] + v[2] + v[3] + v[4] - | ^^^^ = note: asserting the length before indexing will elide bounds checks = note: `-D clippy::missing-asserts-for-indexing` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]` @@ -37,191 +12,82 @@ LL | v[0] + v[1] + v[2] + v[3] + v[4] error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:10:13 | -LL | let _ = v[0]; - | _____________^ -... | -LL | | let _ = v[1..4]; - | |___________________^ - | - = help: consider asserting the length before indexing: `assert!(v.len() > 3);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:10:13 - | LL | let _ = v[0]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:13:13 - | +... LL | let _ = v[1..4]; | ^^^^^^^ - = note: asserting the length before indexing will elide bounds checks + | + = help: consider asserting the length before indexing: `assert!(v.len() > 3);` error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:17:13 | -LL | let a = v[0]; - | _____________^ -LL | | -LL | | -LL | | let b = v[1]; -LL | | let c = v[2]; - | |________________^ - | - = help: consider asserting the length before indexing: `assert!(v.len() > 2);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:17:13 - | LL | let a = v[0]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:20:13 - | +... LL | let b = v[1]; | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:21:13 - | LL | let c = v[2]; | ^^^^ - = note: asserting the length before indexing will elide bounds checks + | + = help: consider asserting the length before indexing: `assert!(v.len() > 2);` error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:13 | LL | let _ = v1[0] + v1[12]; - | ^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^^ | = help: consider asserting the length before indexing: `assert!(v1.len() > 12);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:13 - | -LL | let _ = v1[0] + v1[12]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:21 - | -LL | let _ = v1[0] + v1[12]; - | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:13 | LL | let _ = v2[5] + v2[15]; - | ^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^^ | = help: consider asserting the length before indexing: `assert!(v2.len() > 15);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:13 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:21 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:13 | LL | let _ = v2[5] + v2[15]; - | ^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^^ | = help: consider asserting the length before indexing: `assert!(v2.len() > 15);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:13 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:21 - | -LL | let _ = v2[5] + v2[15]; - | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:13 | LL | let _ = f.v[0] + f.v[1]; - | ^^^^^^^^^^^^^^^ + | ^^^^^^ ^^^^^^ | = help: consider asserting the length before indexing: `assert!(f.v.len() > 1);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:13 - | -LL | let _ = f.v[0] + f.v[1]; - | ^^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:22 - | -LL | let _ = f.v[0] + f.v[1]; - | ^^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:13 | LL | let _ = x[0] + x[1]; - | ^^^^^^^^^^^ + | ^^^^ ^^^^ | = help: consider asserting the length before indexing: `assert!(x.len() > 1);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:13 - | -LL | let _ = x[0] + x[1]; - | ^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:20 - | -LL | let _ = x[0] + x[1]; - | ^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:77:13 | LL | let _ = v1[1] + v1[2]; - | ^^^^^^^^^^^^^ + | ^^^^^ ^^^^^ | = help: consider asserting the length before indexing: `assert!(v1.len() > 2);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:77:13 - | -LL | let _ = v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:77:21 - | -LL | let _ = v1[1] + v1[2]; - | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: indexing into a slice multiple times without an `assert` --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:13 | LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ ^^^^^ ^^^^^ | = help: consider asserting the length before indexing: `assert!(v1.len() > 2);` -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:13 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:21 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ -note: slice indexed here - --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:29 - | -LL | let _ = v1[0] + v1[1] + v1[2]; - | ^^^^^ - = note: asserting the length before indexing will elide bounds checks error: aborting due to 10 previous errors diff --git a/tests/ui/needless_type_cast.fixed b/tests/ui/needless_type_cast.fixed new file mode 100644 index 000000000000..32c348d3ca3a --- /dev/null +++ b/tests/ui/needless_type_cast.fixed @@ -0,0 +1,182 @@ +#![warn(clippy::needless_type_cast)] +#![allow(clippy::no_effect, clippy::unnecessary_cast, unused)] + +fn takes_i32(x: i32) -> i32 { + x +} + +fn generic(x: T) -> T { + x +} + +fn main() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = a as i32 + 5; + let _ = a as i32 * 2; + + let b: u16 = 20; + let _ = b; + let _ = b as u32; + + let c: u8 = 5; + let _ = c as u16; + let _ = c as u32; + + let d: i32 = 100; + let _ = d + 1; + + let e = 42u8; + let _ = e as i64; + let _ = e as i64 + 10; + + let f: usize = 1; + //~^ needless_type_cast + let _ = f as usize; +} + +fn test_function_call() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = takes_i32(a as i32); + let _ = takes_i32(a as i32); +} + +fn test_generic_call() { + let a: u8 = 10; + let _ = generic(a as i32); + let _ = generic(a as i32); +} + +fn test_method_on_cast() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = (a as i32).checked_add(5); + let _ = (a as i32).saturating_mul(2); +} + +fn test_iterator_sum() { + let a: i32 = 10; + //~^ needless_type_cast + let arr = [a as i32, a as i32]; + let _: i32 = arr.iter().copied().sum(); +} + +fn test_closure() { + let a: i32 = 10; + //~^ needless_type_cast + let _: i32 = [1i32, 2].iter().map(|x| x + a as i32).sum(); +} + +fn test_struct_field() { + struct S { + x: i32, + y: i32, + } + + let a: i32 = 10; + //~^ needless_type_cast + let _ = S { + x: a as i32, + y: a as i32, + }; +} + +fn test_option() { + let a: u8 = 10; + let _: Option = Some(a as i32); + let _: Option = Some(a as i32); +} + +fn test_mixed_context() { + let a: u8 = 10; + let _ = takes_i32(a as i32); + let _ = generic(a as i32); +} + +fn test_nested_block() { + if true { + let a: i32 = 10; + //~^ needless_type_cast + let _ = a as i32 + 1; + let _ = a as i32 * 2; + } +} + +fn test_match_expr() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = match 1 { + 1 => a as i32, + _ => a as i32, + }; +} + +fn test_return_expr() -> i32 { + let a: i32 = 10; + //~^ needless_type_cast + a as i32 +} + +fn test_closure_always_cast() { + let a: i32 = 10; + //~^ needless_type_cast + let _ = [1, 2].iter().map(|_| a as i32).sum::(); + let _ = a as i32; +} + +fn test_closure_mixed_usage() { + let a: u8 = 10; + let _ = [1, 2].iter().map(|_| a as i32).sum::(); + let _ = a + 1; +} + +fn test_nested_generic_call() { + let a: u8 = 10; + let _ = generic(takes_i32(a as i32)); + let _ = generic(takes_i32(a as i32)); +} + +fn test_generic_initializer() { + // Should not lint: changing type would affect what generic() returns + let a: u8 = generic(10u8); + let _ = a as i32; + let _ = a as i32; +} + +fn test_unsafe_transmute() { + // Should not lint: initializer contains unsafe block + #[allow(clippy::useless_transmute)] + let x: u32 = unsafe { std::mem::transmute(0u32) }; + let _ = x as u64; +} + +fn test_if_with_generic() { + // Should not lint: one branch has generic return type + let x: u8 = if true { generic(1) } else { 2 }; + let _ = x as i32; +} + +fn test_match_with_generic() { + // Should not lint: one branch has generic return type + let x: u8 = match 1 { + 1 => generic(1), + _ => 2, + }; + let _ = x as i32; +} + +fn test_default() { + // Should not lint: Default::default() has generic return type + let x: u8 = Default::default(); + let _ = x as i32; +} + +fn test_loop_with_generic() { + // Should not lint: loop break has generic return type + #[allow(clippy::never_loop)] + let x: u8 = loop { + break generic(1); + }; + let _ = x as i32; +} diff --git a/tests/ui/needless_type_cast.rs b/tests/ui/needless_type_cast.rs new file mode 100644 index 000000000000..e28f620e035f --- /dev/null +++ b/tests/ui/needless_type_cast.rs @@ -0,0 +1,182 @@ +#![warn(clippy::needless_type_cast)] +#![allow(clippy::no_effect, clippy::unnecessary_cast, unused)] + +fn takes_i32(x: i32) -> i32 { + x +} + +fn generic(x: T) -> T { + x +} + +fn main() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = a as i32 + 5; + let _ = a as i32 * 2; + + let b: u16 = 20; + let _ = b; + let _ = b as u32; + + let c: u8 = 5; + let _ = c as u16; + let _ = c as u32; + + let d: i32 = 100; + let _ = d + 1; + + let e = 42u8; + let _ = e as i64; + let _ = e as i64 + 10; + + let f: u8 = 1; + //~^ needless_type_cast + let _ = f as usize; +} + +fn test_function_call() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = takes_i32(a as i32); + let _ = takes_i32(a as i32); +} + +fn test_generic_call() { + let a: u8 = 10; + let _ = generic(a as i32); + let _ = generic(a as i32); +} + +fn test_method_on_cast() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = (a as i32).checked_add(5); + let _ = (a as i32).saturating_mul(2); +} + +fn test_iterator_sum() { + let a: u8 = 10; + //~^ needless_type_cast + let arr = [a as i32, a as i32]; + let _: i32 = arr.iter().copied().sum(); +} + +fn test_closure() { + let a: u8 = 10; + //~^ needless_type_cast + let _: i32 = [1i32, 2].iter().map(|x| x + a as i32).sum(); +} + +fn test_struct_field() { + struct S { + x: i32, + y: i32, + } + + let a: u8 = 10; + //~^ needless_type_cast + let _ = S { + x: a as i32, + y: a as i32, + }; +} + +fn test_option() { + let a: u8 = 10; + let _: Option = Some(a as i32); + let _: Option = Some(a as i32); +} + +fn test_mixed_context() { + let a: u8 = 10; + let _ = takes_i32(a as i32); + let _ = generic(a as i32); +} + +fn test_nested_block() { + if true { + let a: u8 = 10; + //~^ needless_type_cast + let _ = a as i32 + 1; + let _ = a as i32 * 2; + } +} + +fn test_match_expr() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = match 1 { + 1 => a as i32, + _ => a as i32, + }; +} + +fn test_return_expr() -> i32 { + let a: u8 = 10; + //~^ needless_type_cast + a as i32 +} + +fn test_closure_always_cast() { + let a: u8 = 10; + //~^ needless_type_cast + let _ = [1, 2].iter().map(|_| a as i32).sum::(); + let _ = a as i32; +} + +fn test_closure_mixed_usage() { + let a: u8 = 10; + let _ = [1, 2].iter().map(|_| a as i32).sum::(); + let _ = a + 1; +} + +fn test_nested_generic_call() { + let a: u8 = 10; + let _ = generic(takes_i32(a as i32)); + let _ = generic(takes_i32(a as i32)); +} + +fn test_generic_initializer() { + // Should not lint: changing type would affect what generic() returns + let a: u8 = generic(10u8); + let _ = a as i32; + let _ = a as i32; +} + +fn test_unsafe_transmute() { + // Should not lint: initializer contains unsafe block + #[allow(clippy::useless_transmute)] + let x: u32 = unsafe { std::mem::transmute(0u32) }; + let _ = x as u64; +} + +fn test_if_with_generic() { + // Should not lint: one branch has generic return type + let x: u8 = if true { generic(1) } else { 2 }; + let _ = x as i32; +} + +fn test_match_with_generic() { + // Should not lint: one branch has generic return type + let x: u8 = match 1 { + 1 => generic(1), + _ => 2, + }; + let _ = x as i32; +} + +fn test_default() { + // Should not lint: Default::default() has generic return type + let x: u8 = Default::default(); + let _ = x as i32; +} + +fn test_loop_with_generic() { + // Should not lint: loop break has generic return type + #[allow(clippy::never_loop)] + let x: u8 = loop { + break generic(1); + }; + let _ = x as i32; +} diff --git a/tests/ui/needless_type_cast.stderr b/tests/ui/needless_type_cast.stderr new file mode 100644 index 000000000000..3ee9df1043e7 --- /dev/null +++ b/tests/ui/needless_type_cast.stderr @@ -0,0 +1,71 @@ +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:13:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + | + = note: `-D clippy::needless-type-cast` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_type_cast)]` + +error: this binding is defined as `u8` but is always cast to `usize` + --> tests/ui/needless_type_cast.rs:33:12 + | +LL | let f: u8 = 1; + | ^^ help: consider defining it as: `usize` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:39:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:52:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:59:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:66:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:77:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:99:16 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:107:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:116:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:122:12 + | +LL | let a: u8 = 10; + | ^^ help: consider defining it as: `i32` + +error: aborting due to 11 previous errors + diff --git a/tests/ui/ptr_offset_by_literal.fixed b/tests/ui/ptr_offset_by_literal.fixed new file mode 100644 index 000000000000..bd9e41def938 --- /dev/null +++ b/tests/ui/ptr_offset_by_literal.fixed @@ -0,0 +1,50 @@ +#![warn(clippy::ptr_offset_by_literal)] +#![allow(clippy::inconsistent_digit_grouping)] + +fn main() { + let arr = [b'a', b'b', b'c']; + let ptr = arr.as_ptr(); + + let var = 32; + const CONST: isize = 42; + + unsafe { + let _ = ptr; + //~^ ptr_offset_by_literal + let _ = ptr; + //~^ ptr_offset_by_literal + + let _ = ptr.add(5); + //~^ ptr_offset_by_literal + let _ = ptr.sub(5); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(var); + let _ = ptr.offset(CONST); + + let _ = ptr.wrapping_add(5); + //~^ ptr_offset_by_literal + let _ = ptr.wrapping_sub(5); + //~^ ptr_offset_by_literal + + let _ = ptr.sub(5); + //~^ ptr_offset_by_literal + let _ = ptr.wrapping_sub(5); + //~^ ptr_offset_by_literal + + // isize::MAX and isize::MIN on 32-bit systems. + let _ = ptr.add(2_147_483_647); + //~^ ptr_offset_by_literal + let _ = ptr.sub(2_147_483_648); + //~^ ptr_offset_by_literal + + let _ = ptr.add(5_0); + //~^ ptr_offset_by_literal + let _ = ptr.sub(5_0); + //~^ ptr_offset_by_literal + + macro_rules! offs { { $e:expr, $offs:expr } => { $e.offset($offs) }; } + offs!(ptr, 6); + offs!(ptr, var); + } +} diff --git a/tests/ui/ptr_offset_by_literal.rs b/tests/ui/ptr_offset_by_literal.rs new file mode 100644 index 000000000000..b8e3f9b26c68 --- /dev/null +++ b/tests/ui/ptr_offset_by_literal.rs @@ -0,0 +1,50 @@ +#![warn(clippy::ptr_offset_by_literal)] +#![allow(clippy::inconsistent_digit_grouping)] + +fn main() { + let arr = [b'a', b'b', b'c']; + let ptr = arr.as_ptr(); + + let var = 32; + const CONST: isize = 42; + + unsafe { + let _ = ptr.offset(0); + //~^ ptr_offset_by_literal + let _ = ptr.offset(-0); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(5); + //~^ ptr_offset_by_literal + let _ = ptr.offset(-5); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(var); + let _ = ptr.offset(CONST); + + let _ = ptr.wrapping_offset(5isize); + //~^ ptr_offset_by_literal + let _ = ptr.wrapping_offset(-5isize); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(-(5)); + //~^ ptr_offset_by_literal + let _ = ptr.wrapping_offset(-(5)); + //~^ ptr_offset_by_literal + + // isize::MAX and isize::MIN on 32-bit systems. + let _ = ptr.offset(2_147_483_647isize); + //~^ ptr_offset_by_literal + let _ = ptr.offset(-2_147_483_648isize); + //~^ ptr_offset_by_literal + + let _ = ptr.offset(5_0__isize); + //~^ ptr_offset_by_literal + let _ = ptr.offset(-5_0__isize); + //~^ ptr_offset_by_literal + + macro_rules! offs { { $e:expr, $offs:expr } => { $e.offset($offs) }; } + offs!(ptr, 6); + offs!(ptr, var); + } +} diff --git a/tests/ui/ptr_offset_by_literal.stderr b/tests/ui/ptr_offset_by_literal.stderr new file mode 100644 index 000000000000..f85fef87d55f --- /dev/null +++ b/tests/ui/ptr_offset_by_literal.stderr @@ -0,0 +1,141 @@ +error: use of `offset` with zero + --> tests/ui/ptr_offset_by_literal.rs:12:17 + | +LL | let _ = ptr.offset(0); + | ^^^---------- + | | + | help: remove the call to `offset` + | + = note: `-D clippy::ptr-offset-by-literal` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::ptr_offset_by_literal)]` + +error: use of `offset` with zero + --> tests/ui/ptr_offset_by_literal.rs:14:17 + | +LL | let _ = ptr.offset(-0); + | ^^^----------- + | | + | help: remove the call to `offset` + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:17:17 + | +LL | let _ = ptr.offset(5); + | ^^^^^^^^^^^^^ + | +help: use `add` instead + | +LL - let _ = ptr.offset(5); +LL + let _ = ptr.add(5); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:19:17 + | +LL | let _ = ptr.offset(-5); + | ^^^^^^^^^^^^^^ + | +help: use `sub` instead + | +LL - let _ = ptr.offset(-5); +LL + let _ = ptr.sub(5); + | + +error: use of `wrapping_offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:25:17 + | +LL | let _ = ptr.wrapping_offset(5isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `wrapping_add` instead + | +LL - let _ = ptr.wrapping_offset(5isize); +LL + let _ = ptr.wrapping_add(5); + | + +error: use of `wrapping_offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:27:17 + | +LL | let _ = ptr.wrapping_offset(-5isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `wrapping_sub` instead + | +LL - let _ = ptr.wrapping_offset(-5isize); +LL + let _ = ptr.wrapping_sub(5); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:30:17 + | +LL | let _ = ptr.offset(-(5)); + | ^^^^^^^^^^^^^^^^ + | +help: use `sub` instead + | +LL - let _ = ptr.offset(-(5)); +LL + let _ = ptr.sub(5); + | + +error: use of `wrapping_offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:32:17 + | +LL | let _ = ptr.wrapping_offset(-(5)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `wrapping_sub` instead + | +LL - let _ = ptr.wrapping_offset(-(5)); +LL + let _ = ptr.wrapping_sub(5); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:36:17 + | +LL | let _ = ptr.offset(2_147_483_647isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `add` instead + | +LL - let _ = ptr.offset(2_147_483_647isize); +LL + let _ = ptr.add(2_147_483_647); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:38:17 + | +LL | let _ = ptr.offset(-2_147_483_648isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `sub` instead + | +LL - let _ = ptr.offset(-2_147_483_648isize); +LL + let _ = ptr.sub(2_147_483_648); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:41:17 + | +LL | let _ = ptr.offset(5_0__isize); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `add` instead + | +LL - let _ = ptr.offset(5_0__isize); +LL + let _ = ptr.add(5_0); + | + +error: use of `offset` with a literal + --> tests/ui/ptr_offset_by_literal.rs:43:17 + | +LL | let _ = ptr.offset(-5_0__isize); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `sub` instead + | +LL - let _ = ptr.offset(-5_0__isize); +LL + let _ = ptr.sub(5_0); + | + +error: aborting due to 12 previous errors + diff --git a/tests/ui/transmute_ptr_to_ptr.fixed b/tests/ui/transmute_ptr_to_ptr.fixed index 476e7e35a1f6..caba277db754 100644 --- a/tests/ui/transmute_ptr_to_ptr.fixed +++ b/tests/ui/transmute_ptr_to_ptr.fixed @@ -24,6 +24,13 @@ struct GenericParam { t: T, } +#[derive(Clone, Copy)] +struct PtrNamed { + ptr: *const u32, +} +#[derive(Clone, Copy)] +struct Ptr(*const u32); + fn transmute_ptr_to_ptr() { let ptr = &1u32 as *const u32; let mut_ptr = &mut 1u32 as *mut u32; @@ -68,6 +75,18 @@ fn transmute_ptr_to_ptr() { let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) }; } +fn issue1966() { + let ptr = &1u32 as *const u32; + unsafe { + let _: *const f32 = Ptr(ptr).0.cast::(); + //~^ transmute_ptr_to_ptr + let _: *const f32 = PtrNamed { ptr }.ptr.cast::(); + //~^ transmute_ptr_to_ptr + let _: *mut u32 = Ptr(ptr).0.cast_mut(); + //~^ transmute_ptr_to_ptr + } +} + fn lifetime_to_static(v: *mut &()) -> *const &'static () { unsafe { v as *const &() } //~^ transmute_ptr_to_ptr @@ -81,11 +100,15 @@ const _: &() = { unsafe { transmute::<&'static Zst, &'static ()>(zst) } }; +#[derive(Clone, Copy)] +struct Ptr8(*const u8); #[clippy::msrv = "1.37"] fn msrv_1_37(ptr: *const u8) { unsafe { let _: *const i8 = ptr as *const i8; //~^ transmute_ptr_to_ptr + let _: *const i8 = Ptr8(ptr).0 as *const i8; + //~^ transmute_ptr_to_ptr } } diff --git a/tests/ui/transmute_ptr_to_ptr.rs b/tests/ui/transmute_ptr_to_ptr.rs index 7356668bcab5..b3c2baf29c36 100644 --- a/tests/ui/transmute_ptr_to_ptr.rs +++ b/tests/ui/transmute_ptr_to_ptr.rs @@ -24,6 +24,13 @@ struct GenericParam { t: T, } +#[derive(Clone, Copy)] +struct PtrNamed { + ptr: *const u32, +} +#[derive(Clone, Copy)] +struct Ptr(*const u32); + fn transmute_ptr_to_ptr() { let ptr = &1u32 as *const u32; let mut_ptr = &mut 1u32 as *mut u32; @@ -68,6 +75,18 @@ fn transmute_ptr_to_ptr() { let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) }; } +fn issue1966() { + let ptr = &1u32 as *const u32; + unsafe { + let _: *const f32 = transmute(Ptr(ptr)); + //~^ transmute_ptr_to_ptr + let _: *const f32 = transmute(PtrNamed { ptr }); + //~^ transmute_ptr_to_ptr + let _: *mut u32 = transmute(Ptr(ptr)); + //~^ transmute_ptr_to_ptr + } +} + fn lifetime_to_static(v: *mut &()) -> *const &'static () { unsafe { transmute(v) } //~^ transmute_ptr_to_ptr @@ -81,11 +100,15 @@ const _: &() = { unsafe { transmute::<&'static Zst, &'static ()>(zst) } }; +#[derive(Clone, Copy)] +struct Ptr8(*const u8); #[clippy::msrv = "1.37"] fn msrv_1_37(ptr: *const u8) { unsafe { let _: *const i8 = transmute(ptr); //~^ transmute_ptr_to_ptr + let _: *const i8 = transmute(Ptr8(ptr)); + //~^ transmute_ptr_to_ptr } } diff --git a/tests/ui/transmute_ptr_to_ptr.stderr b/tests/ui/transmute_ptr_to_ptr.stderr index c8db4fe214fd..ba9e6df6c2d7 100644 --- a/tests/ui/transmute_ptr_to_ptr.stderr +++ b/tests/ui/transmute_ptr_to_ptr.stderr @@ -1,5 +1,5 @@ error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:32:29 + --> tests/ui/transmute_ptr_to_ptr.rs:39:29 | LL | let _: *const f32 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let _: *const f32 = ptr.cast::(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:35:27 + --> tests/ui/transmute_ptr_to_ptr.rs:42:27 | LL | let _: *mut f32 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -25,37 +25,37 @@ LL + let _: *mut f32 = mut_ptr.cast::(); | error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:39:23 + --> tests/ui/transmute_ptr_to_ptr.rs:46:23 | LL | let _: &f32 = transmute(&1u32); | ^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:42:23 + --> tests/ui/transmute_ptr_to_ptr.rs:49:23 | LL | let _: &f32 = transmute(&1f64); | ^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:47:27 + --> tests/ui/transmute_ptr_to_ptr.rs:54:27 | LL | let _: &mut f32 = transmute(&mut 1u32); | ^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:50:37 + --> tests/ui/transmute_ptr_to_ptr.rs:57:37 | LL | let _: &GenericParam = transmute(&GenericParam { t: 1u32 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam as *const GenericParam)` error: transmute from a reference to a reference - --> tests/ui/transmute_ptr_to_ptr.rs:54:27 + --> tests/ui/transmute_ptr_to_ptr.rs:61:27 | LL | let u8_ref: &u8 = transmute(u64_ref); | ^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)` error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:57:29 + --> tests/ui/transmute_ptr_to_ptr.rs:64:29 | LL | let _: *const u32 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL + let _: *const u32 = mut_ptr.cast_const(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:60:27 + --> tests/ui/transmute_ptr_to_ptr.rs:67:27 | LL | let _: *mut u32 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -79,7 +79,43 @@ LL + let _: *mut u32 = ptr.cast_mut(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:72:14 + --> tests/ui/transmute_ptr_to_ptr.rs:81:29 + | +LL | let _: *const f32 = transmute(Ptr(ptr)); + | ^^^^^^^^^^^^^^^^^^^ + | +help: use `pointer::cast` instead + | +LL - let _: *const f32 = transmute(Ptr(ptr)); +LL + let _: *const f32 = Ptr(ptr).0.cast::(); + | + +error: transmute from a pointer to a pointer + --> tests/ui/transmute_ptr_to_ptr.rs:83:29 + | +LL | let _: *const f32 = transmute(PtrNamed { ptr }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `pointer::cast` instead + | +LL - let _: *const f32 = transmute(PtrNamed { ptr }); +LL + let _: *const f32 = PtrNamed { ptr }.ptr.cast::(); + | + +error: transmute from a pointer to a pointer + --> tests/ui/transmute_ptr_to_ptr.rs:85:27 + | +LL | let _: *mut u32 = transmute(Ptr(ptr)); + | ^^^^^^^^^^^^^^^^^^^ + | +help: use `pointer::cast_mut` instead + | +LL - let _: *mut u32 = transmute(Ptr(ptr)); +LL + let _: *mut u32 = Ptr(ptr).0.cast_mut(); + | + +error: transmute from a pointer to a pointer + --> tests/ui/transmute_ptr_to_ptr.rs:91:14 | LL | unsafe { transmute(v) } | ^^^^^^^^^^^^ @@ -91,7 +127,7 @@ LL + unsafe { v as *const &() } | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:87:28 + --> tests/ui/transmute_ptr_to_ptr.rs:108:28 | LL | let _: *const i8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -103,7 +139,19 @@ LL + let _: *const i8 = ptr as *const i8; | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:95:28 + --> tests/ui/transmute_ptr_to_ptr.rs:110:28 + | +LL | let _: *const i8 = transmute(Ptr8(ptr)); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: use an `as` cast instead + | +LL - let _: *const i8 = transmute(Ptr8(ptr)); +LL + let _: *const i8 = Ptr8(ptr).0 as *const i8; + | + +error: transmute from a pointer to a pointer + --> tests/ui/transmute_ptr_to_ptr.rs:118:28 | LL | let _: *const i8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -115,7 +163,7 @@ LL + let _: *const i8 = ptr.cast::(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:103:26 + --> tests/ui/transmute_ptr_to_ptr.rs:126:26 | LL | let _: *mut u8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -127,7 +175,7 @@ LL + let _: *mut u8 = ptr as *mut u8; | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:105:28 + --> tests/ui/transmute_ptr_to_ptr.rs:128:28 | LL | let _: *const u8 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -139,7 +187,7 @@ LL + let _: *const u8 = mut_ptr as *const u8; | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:113:26 + --> tests/ui/transmute_ptr_to_ptr.rs:136:26 | LL | let _: *mut u8 = transmute(ptr); | ^^^^^^^^^^^^^^ @@ -151,7 +199,7 @@ LL + let _: *mut u8 = ptr.cast_mut(); | error: transmute from a pointer to a pointer - --> tests/ui/transmute_ptr_to_ptr.rs:115:28 + --> tests/ui/transmute_ptr_to_ptr.rs:138:28 | LL | let _: *const u8 = transmute(mut_ptr); | ^^^^^^^^^^^^^^^^^^ @@ -162,5 +210,5 @@ LL - let _: *const u8 = transmute(mut_ptr); LL + let _: *const u8 = mut_ptr.cast_const(); | -error: aborting due to 16 previous errors +error: aborting due to 20 previous errors diff --git a/tests/ui/transmute_ptr_to_ref.fixed b/tests/ui/transmute_ptr_to_ref.fixed index c130575df960..8de47031a400 100644 --- a/tests/ui/transmute_ptr_to_ref.fixed +++ b/tests/ui/transmute_ptr_to_ref.fixed @@ -55,6 +55,52 @@ fn issue1231() { //~^ transmute_ptr_to_ref } +#[derive(Clone, Copy)] +struct PtrRefNamed<'a> { + ptr: *const &'a u32, +} +#[derive(Clone, Copy)] +struct PtrRef<'a>(*const &'a u32); +#[derive(Clone, Copy)] +struct PtrSliceRef<'a>(*const [&'a str]); +#[derive(Clone, Copy)] +struct PtrSlice(*const [i32]); +#[derive(Clone, Copy)] +struct Ptr(*const u32); +impl std::ops::Add for Ptr { + type Output = Self; + fn add(self, _: Self) -> Self { + self + } +} +mod ptr_mod { + #[derive(Clone, Copy)] + pub struct Ptr(*const u32); +} +fn issue1966(u: PtrSlice, v: PtrSliceRef, w: Ptr, x: PtrRefNamed, y: PtrRef, z: ptr_mod::Ptr) { + unsafe { + let _: &i32 = &*(w.0 as *const i32); + //~^ transmute_ptr_to_ref + let _: &u32 = &*w.0; + //~^ transmute_ptr_to_ref + let _: &&u32 = &*x.ptr.cast::<&u32>(); + //~^ transmute_ptr_to_ref + // The field is not accessible. The program should not generate code + // that accesses the field. + let _: &u32 = std::mem::transmute(z); + let _ = &*w.0.cast::(); + //~^ transmute_ptr_to_ref + let _: &[&str] = &*(v.0 as *const [&str]); + //~^ transmute_ptr_to_ref + let _ = &*(u.0 as *const [i32]); + //~^ transmute_ptr_to_ref + let _: &&u32 = &*y.0.cast::<&u32>(); + //~^ transmute_ptr_to_ref + let _: &u32 = &*(w + w).0; + //~^ transmute_ptr_to_ref + } +} + fn issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 { unsafe { match 0 { @@ -89,7 +135,7 @@ fn meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { } #[clippy::msrv = "1.37"] -fn under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { +fn under_msrv<'a, 'b, 'c>(x: *const &'a u32, y: PtrRef) -> &'c &'b u32 { unsafe { let a = 0u32; let a = &a as *const u32; @@ -97,10 +143,16 @@ fn under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { //~^ transmute_ptr_to_ref let _: &u32 = &*(a as *const u32); //~^ transmute_ptr_to_ref + let _ = &*(Ptr(a).0 as *const u32); + //~^ transmute_ptr_to_ref match 0 { 0 => &*(x as *const () as *const &u32), //~^ transmute_ptr_to_ref - _ => &*(x as *const () as *const &'b u32), + 1 => &*(x as *const () as *const &'b u32), + //~^ transmute_ptr_to_ref + 2 => &*(y.0 as *const () as *const &u32), + //~^ transmute_ptr_to_ref + _ => &*(y.0 as *const () as *const &'b u32), //~^ transmute_ptr_to_ref } } diff --git a/tests/ui/transmute_ptr_to_ref.rs b/tests/ui/transmute_ptr_to_ref.rs index f79d54234a2c..52fe669de935 100644 --- a/tests/ui/transmute_ptr_to_ref.rs +++ b/tests/ui/transmute_ptr_to_ref.rs @@ -55,6 +55,52 @@ fn issue1231() { //~^ transmute_ptr_to_ref } +#[derive(Clone, Copy)] +struct PtrRefNamed<'a> { + ptr: *const &'a u32, +} +#[derive(Clone, Copy)] +struct PtrRef<'a>(*const &'a u32); +#[derive(Clone, Copy)] +struct PtrSliceRef<'a>(*const [&'a str]); +#[derive(Clone, Copy)] +struct PtrSlice(*const [i32]); +#[derive(Clone, Copy)] +struct Ptr(*const u32); +impl std::ops::Add for Ptr { + type Output = Self; + fn add(self, _: Self) -> Self { + self + } +} +mod ptr_mod { + #[derive(Clone, Copy)] + pub struct Ptr(*const u32); +} +fn issue1966(u: PtrSlice, v: PtrSliceRef, w: Ptr, x: PtrRefNamed, y: PtrRef, z: ptr_mod::Ptr) { + unsafe { + let _: &i32 = std::mem::transmute(w); + //~^ transmute_ptr_to_ref + let _: &u32 = std::mem::transmute(w); + //~^ transmute_ptr_to_ref + let _: &&u32 = core::mem::transmute(x); + //~^ transmute_ptr_to_ref + // The field is not accessible. The program should not generate code + // that accesses the field. + let _: &u32 = std::mem::transmute(z); + let _ = std::mem::transmute::<_, &u32>(w); + //~^ transmute_ptr_to_ref + let _: &[&str] = core::mem::transmute(v); + //~^ transmute_ptr_to_ref + let _ = std::mem::transmute::<_, &[i32]>(u); + //~^ transmute_ptr_to_ref + let _: &&u32 = std::mem::transmute(y); + //~^ transmute_ptr_to_ref + let _: &u32 = std::mem::transmute(w + w); + //~^ transmute_ptr_to_ref + } +} + fn issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 { unsafe { match 0 { @@ -89,7 +135,7 @@ fn meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { } #[clippy::msrv = "1.37"] -fn under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { +fn under_msrv<'a, 'b, 'c>(x: *const &'a u32, y: PtrRef) -> &'c &'b u32 { unsafe { let a = 0u32; let a = &a as *const u32; @@ -97,10 +143,16 @@ fn under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 { //~^ transmute_ptr_to_ref let _: &u32 = std::mem::transmute::<_, &u32>(a); //~^ transmute_ptr_to_ref + let _ = std::mem::transmute::<_, &u32>(Ptr(a)); + //~^ transmute_ptr_to_ref match 0 { 0 => std::mem::transmute(x), //~^ transmute_ptr_to_ref - _ => std::mem::transmute::<_, &&'b u32>(x), + 1 => std::mem::transmute::<_, &&'b u32>(x), + //~^ transmute_ptr_to_ref + 2 => std::mem::transmute(y), + //~^ transmute_ptr_to_ref + _ => std::mem::transmute::<_, &&'b u32>(y), //~^ transmute_ptr_to_ref } } diff --git a/tests/ui/transmute_ptr_to_ref.stderr b/tests/ui/transmute_ptr_to_ref.stderr index 3f404d295fef..c0f0ca916761 100644 --- a/tests/ui/transmute_ptr_to_ref.stderr +++ b/tests/ui/transmute_ptr_to_ref.stderr @@ -61,125 +61,191 @@ error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`) LL | unsafe { std::mem::transmute::<_, Bar>(raw) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const u8)` +error: transmute from a pointer type (`*const u32`) to a reference type (`&i32`) + --> tests/ui/transmute_ptr_to_ref.rs:82:23 + | +LL | let _: &i32 = std::mem::transmute(w); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(w.0 as *const i32)` + +error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:84:23 + | +LL | let _: &u32 = std::mem::transmute(w); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*w.0` + error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:61:18 + --> tests/ui/transmute_ptr_to_ref.rs:86:24 + | +LL | let _: &&u32 = core::mem::transmute(x); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.ptr.cast::<&u32>()` + +error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:91:17 + | +LL | let _ = std::mem::transmute::<_, &u32>(w); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*w.0.cast::()` + +error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&str]`) + --> tests/ui/transmute_ptr_to_ref.rs:93:26 + | +LL | let _: &[&str] = core::mem::transmute(v); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(v.0 as *const [&str])` + +error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[i32]`) + --> tests/ui/transmute_ptr_to_ref.rs:95:17 + | +LL | let _ = std::mem::transmute::<_, &[i32]>(u); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(u.0 as *const [i32])` + +error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:97:24 + | +LL | let _: &&u32 = std::mem::transmute(y); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.0.cast::<&u32>()` + +error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:99:23 + | +LL | let _: &u32 = std::mem::transmute(w + w); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(w + w).0` + +error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:107:18 | LL | 0 => std::mem::transmute(x), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:63:18 + --> tests/ui/transmute_ptr_to_ref.rs:109:18 | LL | 1 => std::mem::transmute(y), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:65:18 + --> tests/ui/transmute_ptr_to_ref.rs:111:18 | LL | 2 => std::mem::transmute::<_, &&'b u32>(x), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:67:18 + --> tests/ui/transmute_ptr_to_ref.rs:113:18 | LL | _ => std::mem::transmute::<_, &&'b u32>(y), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&'b u32>()` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:78:23 + --> tests/ui/transmute_ptr_to_ref.rs:124:23 | LL | let _: &u32 = std::mem::transmute(a); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:80:23 + --> tests/ui/transmute_ptr_to_ref.rs:126:23 | LL | let _: &u32 = std::mem::transmute::<_, &u32>(a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a.cast::()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:83:18 + --> tests/ui/transmute_ptr_to_ref.rs:129:18 | LL | 0 => std::mem::transmute(x), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:85:18 + --> tests/ui/transmute_ptr_to_ref.rs:131:18 | LL | _ => std::mem::transmute::<_, &&'b u32>(x), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:96:23 + --> tests/ui/transmute_ptr_to_ref.rs:142:23 | LL | let _: &u32 = std::mem::transmute(a); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a` error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:98:23 + --> tests/ui/transmute_ptr_to_ref.rs:144:23 | LL | let _: &u32 = std::mem::transmute::<_, &u32>(a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const u32)` +error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:146:17 + | +LL | let _ = std::mem::transmute::<_, &u32>(Ptr(a)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(Ptr(a).0 as *const u32)` + error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:101:18 + --> tests/ui/transmute_ptr_to_ref.rs:149:18 | LL | 0 => std::mem::transmute(x), | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &u32)` error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) - --> tests/ui/transmute_ptr_to_ref.rs:103:18 + --> tests/ui/transmute_ptr_to_ref.rs:151:18 | -LL | _ => std::mem::transmute::<_, &&'b u32>(x), +LL | 1 => std::mem::transmute::<_, &&'b u32>(x), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &'b u32)` +error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:153:18 + | +LL | 2 => std::mem::transmute(y), + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(y.0 as *const () as *const &u32)` + +error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`) + --> tests/ui/transmute_ptr_to_ref.rs:155:18 + | +LL | _ => std::mem::transmute::<_, &&'b u32>(y), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(y.0 as *const () as *const &'b u32)` + error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[u32]`) - --> tests/ui/transmute_ptr_to_ref.rs:113:17 + --> tests/ui/transmute_ptr_to_ref.rs:165:17 | LL | let _ = core::mem::transmute::<_, &[u32]>(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(ptr as *const [u32])` error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[u32]`) - --> tests/ui/transmute_ptr_to_ref.rs:115:25 + --> tests/ui/transmute_ptr_to_ref.rs:167:25 | LL | let _: &[u32] = core::mem::transmute(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(ptr as *const [u32])` error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&[u8]]`) - --> tests/ui/transmute_ptr_to_ref.rs:119:17 + --> tests/ui/transmute_ptr_to_ref.rs:171:17 | LL | let _ = core::mem::transmute::<_, &[&[u8]]>(a_s_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&[u8]])` error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&[u8]]`) - --> tests/ui/transmute_ptr_to_ref.rs:121:27 + --> tests/ui/transmute_ptr_to_ref.rs:173:27 | LL | let _: &[&[u8]] = core::mem::transmute(a_s_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&[u8]])` error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[i32]`) - --> tests/ui/transmute_ptr_to_ref.rs:125:17 + --> tests/ui/transmute_ptr_to_ref.rs:177:17 | LL | let _ = core::mem::transmute::<_, &[i32]>(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(ptr as *const [i32])` error: transmute from a pointer type (`*const [i32]`) to a reference type (`&[i32]`) - --> tests/ui/transmute_ptr_to_ref.rs:127:25 + --> tests/ui/transmute_ptr_to_ref.rs:179:25 | LL | let _: &[i32] = core::mem::transmute(ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*ptr` error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&str]`) - --> tests/ui/transmute_ptr_to_ref.rs:131:17 + --> tests/ui/transmute_ptr_to_ref.rs:183:17 | LL | let _ = core::mem::transmute::<_, &[&str]>(a_s_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&str])` error: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&str]`) - --> tests/ui/transmute_ptr_to_ref.rs:133:26 + --> tests/ui/transmute_ptr_to_ref.rs:185:26 | LL | let _: &[&str] = core::mem::transmute(a_s_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&str])` -error: aborting due to 30 previous errors +error: aborting due to 41 previous errors diff --git a/tests/ui/tuple_array_conversions.rs b/tests/ui/tuple_array_conversions.rs index 772c41df090e..17e6a252b266 100644 --- a/tests/ui/tuple_array_conversions.rs +++ b/tests/ui/tuple_array_conversions.rs @@ -116,3 +116,26 @@ fn msrv_juust_right() { let x = &[1, 2]; let x = (x[0], x[1]); } + +fn issue16192() { + fn do_something(tuple: (u32, u32)) {} + fn produce_array() -> [u32; 2] { + [1, 2] + } + + let [a, b] = produce_array(); + for tuple in [(a, b), (b, a)] { + do_something(tuple); + } + + let [a, b] = produce_array(); + let x = b; + do_something((a, b)); + + let [a, b] = produce_array(); + do_something((b, a)); + + let [a, b] = produce_array(); + do_something((a, b)); + //~^ tuple_array_conversions +} diff --git a/tests/ui/tuple_array_conversions.stderr b/tests/ui/tuple_array_conversions.stderr index 6dafb8d285d4..4c15769b7487 100644 --- a/tests/ui/tuple_array_conversions.stderr +++ b/tests/ui/tuple_array_conversions.stderr @@ -80,5 +80,13 @@ LL | let x = [x.0, x.1]; | = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed -error: aborting due to 10 previous errors +error: it looks like you're trying to convert an array to a tuple + --> tests/ui/tuple_array_conversions.rs:139:18 + | +LL | do_something((a, b)); + | ^^^^^^ + | + = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed + +error: aborting due to 11 previous errors diff --git a/tests/ui/useless_conversion.fixed b/tests/ui/useless_conversion.fixed index 9de7d2c67149..adf5e58d9a1a 100644 --- a/tests/ui/useless_conversion.fixed +++ b/tests/ui/useless_conversion.fixed @@ -442,3 +442,14 @@ fn issue14739() { let _ = R.map(|_x| 0); //~^ useless_conversion } + +fn issue16165() { + macro_rules! mac { + (iter $e:expr) => { + $e.iter() + }; + } + + for _ in mac!(iter [1, 2]) {} + //~^ useless_conversion +} diff --git a/tests/ui/useless_conversion.rs b/tests/ui/useless_conversion.rs index 38cd1175aa48..d95fe49e2e2b 100644 --- a/tests/ui/useless_conversion.rs +++ b/tests/ui/useless_conversion.rs @@ -442,3 +442,14 @@ fn issue14739() { let _ = R.into_iter().map(|_x| 0); //~^ useless_conversion } + +fn issue16165() { + macro_rules! mac { + (iter $e:expr) => { + $e.iter() + }; + } + + for _ in mac!(iter [1, 2]).into_iter() {} + //~^ useless_conversion +} diff --git a/tests/ui/useless_conversion.stderr b/tests/ui/useless_conversion.stderr index 3bfaf1411c2c..052c664f6f2e 100644 --- a/tests/ui/useless_conversion.stderr +++ b/tests/ui/useless_conversion.stderr @@ -389,5 +389,11 @@ error: useless conversion to the same type: `std::ops::Range` LL | let _ = R.into_iter().map(|_x| 0); | ^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `R` -error: aborting due to 43 previous errors +error: useless conversion to the same type: `std::slice::Iter<'_, i32>` + --> tests/ui/useless_conversion.rs:453:14 + | +LL | for _ in mac!(iter [1, 2]).into_iter() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `mac!(iter [1, 2])` + +error: aborting due to 44 previous errors diff --git a/tests/ui/while_let_on_iterator.fixed b/tests/ui/while_let_on_iterator.fixed index f9ccefab5898..0d3b446af43f 100644 --- a/tests/ui/while_let_on_iterator.fixed +++ b/tests/ui/while_let_on_iterator.fixed @@ -492,6 +492,110 @@ fn issue13123() { } } +fn issue16089() { + trait CertainTrait: Iterator { + fn iter_over_self(&mut self) { + let mut a = 0; + for r in &mut *self { + //~^ while_let_on_iterator + a = r; + } + self.use_after_iter() + } + + fn use_after_iter(&mut self) {} + } +} + +fn issue16089_sized_trait_not_reborrowed() { + trait CertainTrait: Iterator + Sized { + fn iter_over_self(&mut self) { + let mut a = 0; + // Check that the suggestion is just "self", since the trait is sized. + for r in self.by_ref() { + //~^ while_let_on_iterator + a = r; + } + self.use_after_iter() + } + + fn use_after_iter(&mut self) {} + } +} + +fn issue16089_nested_derefs() { + struct S(T); + impl core::ops::Deref for S { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for S { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + fn f(mut x: S>>) { + for _ in &mut ***x {} + //~^ while_let_on_iterator + } +} + +fn issue16089_nested_derefs_last_not_sized() { + struct WithSize(T); + impl core::ops::Deref for WithSize { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for WithSize { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + // The suggestion must use `&mut **x`. Using `x.by_ref()` doesn't work in this + // case, since the last type adjustment for `x` in the expression `x.next()` is + // to dereference a `?Sized` trait. + fn f(mut x: WithSize<&mut dyn Iterator>) { + for _ in &mut **x {} + //~^ while_let_on_iterator + } +} + +fn issue16089_nested_derefs_last_sized() { + struct NoSize(T); + impl core::ops::Deref for NoSize { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for NoSize { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + struct SizedIter {} + + impl Iterator for SizedIter { + type Item = u32; + fn next(&mut self) -> Option { + Some(0) + } + } + + // We want the suggestion to be `x.by_ref()`. It works in this case since the last type + // adjustment for `x` in the expression `x.next()` is to dereference a Sized type. + fn f(mut x: NoSize>) { + for _ in x.by_ref() {} + //~^ while_let_on_iterator + } +} + fn main() { let mut it = 0..20; for _ in it { diff --git a/tests/ui/while_let_on_iterator.rs b/tests/ui/while_let_on_iterator.rs index f957f2e5a523..e1d9e9081e45 100644 --- a/tests/ui/while_let_on_iterator.rs +++ b/tests/ui/while_let_on_iterator.rs @@ -492,6 +492,110 @@ fn issue13123() { } } +fn issue16089() { + trait CertainTrait: Iterator { + fn iter_over_self(&mut self) { + let mut a = 0; + while let Some(r) = self.next() { + //~^ while_let_on_iterator + a = r; + } + self.use_after_iter() + } + + fn use_after_iter(&mut self) {} + } +} + +fn issue16089_sized_trait_not_reborrowed() { + trait CertainTrait: Iterator + Sized { + fn iter_over_self(&mut self) { + let mut a = 0; + // Check that the suggestion is just "self", since the trait is sized. + while let Some(r) = self.next() { + //~^ while_let_on_iterator + a = r; + } + self.use_after_iter() + } + + fn use_after_iter(&mut self) {} + } +} + +fn issue16089_nested_derefs() { + struct S(T); + impl core::ops::Deref for S { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for S { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + fn f(mut x: S>>) { + while let Some(_) = x.next() {} + //~^ while_let_on_iterator + } +} + +fn issue16089_nested_derefs_last_not_sized() { + struct WithSize(T); + impl core::ops::Deref for WithSize { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for WithSize { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + // The suggestion must use `&mut **x`. Using `x.by_ref()` doesn't work in this + // case, since the last type adjustment for `x` in the expression `x.next()` is + // to dereference a `?Sized` trait. + fn f(mut x: WithSize<&mut dyn Iterator>) { + while let Some(_) = x.next() {} + //~^ while_let_on_iterator + } +} + +fn issue16089_nested_derefs_last_sized() { + struct NoSize(T); + impl core::ops::Deref for NoSize { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl core::ops::DerefMut for NoSize { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + + struct SizedIter {} + + impl Iterator for SizedIter { + type Item = u32; + fn next(&mut self) -> Option { + Some(0) + } + } + + // We want the suggestion to be `x.by_ref()`. It works in this case since the last type + // adjustment for `x` in the expression `x.next()` is to dereference a Sized type. + fn f(mut x: NoSize>) { + while let Some(_) = x.next() {} + //~^ while_let_on_iterator + } +} + fn main() { let mut it = 0..20; while let Some(..) = it.next() { diff --git a/tests/ui/while_let_on_iterator.stderr b/tests/ui/while_let_on_iterator.stderr index 50f20227b90f..cd43d3c17800 100644 --- a/tests/ui/while_let_on_iterator.stderr +++ b/tests/ui/while_let_on_iterator.stderr @@ -164,10 +164,40 @@ LL | 'label: while let Some(n) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'label: for n in it` error: this loop could be written as a `for` loop - --> tests/ui/while_let_on_iterator.rs:497:5 + --> tests/ui/while_let_on_iterator.rs:499:13 + | +LL | while let Some(r) = self.next() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for r in &mut *self` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:515:13 + | +LL | while let Some(r) = self.next() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for r in self.by_ref()` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:541:9 + | +LL | while let Some(_) = x.next() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in &mut ***x` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:563:9 + | +LL | while let Some(_) = x.next() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in &mut **x` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:594:9 + | +LL | while let Some(_) = x.next() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in x.by_ref()` + +error: this loop could be written as a `for` loop + --> tests/ui/while_let_on_iterator.rs:601:5 | LL | while let Some(..) = it.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it` -error: aborting due to 28 previous errors +error: aborting due to 33 previous errors diff --git a/tests/ui/zero_offset.rs b/tests/ui/zero_offset.rs index bedb09536c53..5a9c3ac9248f 100644 --- a/tests/ui/zero_offset.rs +++ b/tests/ui/zero_offset.rs @@ -1,4 +1,4 @@ -#[allow(clippy::borrow_as_ptr)] +#[allow(clippy::borrow_as_ptr, clippy::ptr_offset_by_literal)] fn main() { unsafe { let m = &mut () as *mut (); diff --git a/tests/ui/zero_repeat_side_effects.fixed b/tests/ui/zero_repeat_side_effects.fixed index b5fca36f3f08..4bdff6fd0f6c 100644 --- a/tests/ui/zero_repeat_side_effects.fixed +++ b/tests/ui/zero_repeat_side_effects.fixed @@ -1,6 +1,11 @@ #![warn(clippy::zero_repeat_side_effects)] -#![expect(clippy::unnecessary_operation, clippy::useless_vec, clippy::needless_late_init)] -#![allow(clippy::no_effect)] // only fires _after_ the fix +#![allow( + clippy::unnecessary_operation, + clippy::useless_vec, + clippy::needless_late_init, + clippy::single_match, + clippy::no_effect // only fires _after_ the fix +)] fn f() -> i32 { println!("side effect"); @@ -119,3 +124,26 @@ fn issue_14681() { }); //~^ zero_repeat_side_effects } + +fn issue_15824() { + fn f() {} + + match 0 { + 0 => { + f(); + _ = [] as [(); 0] + }, + //~^ zero_repeat_side_effects + _ => {}, + } + + let mut a = [(); 0]; + match 0 { + 0 => { + f(); + a = [] as [(); 0] + }, + //~^ zero_repeat_side_effects + _ => {}, + } +} diff --git a/tests/ui/zero_repeat_side_effects.rs b/tests/ui/zero_repeat_side_effects.rs index ea043d21638c..a1454d724c87 100644 --- a/tests/ui/zero_repeat_side_effects.rs +++ b/tests/ui/zero_repeat_side_effects.rs @@ -1,6 +1,11 @@ #![warn(clippy::zero_repeat_side_effects)] -#![expect(clippy::unnecessary_operation, clippy::useless_vec, clippy::needless_late_init)] -#![allow(clippy::no_effect)] // only fires _after_ the fix +#![allow( + clippy::unnecessary_operation, + clippy::useless_vec, + clippy::needless_late_init, + clippy::single_match, + clippy::no_effect // only fires _after_ the fix +)] fn f() -> i32 { println!("side effect"); @@ -102,3 +107,20 @@ fn issue_14681() { foo(&[Some(Some(S::new())); 0]); //~^ zero_repeat_side_effects } + +fn issue_15824() { + fn f() {} + + match 0 { + 0 => _ = [f(); 0], + //~^ zero_repeat_side_effects + _ => {}, + } + + let mut a = [(); 0]; + match 0 { + 0 => a = [f(); 0], + //~^ zero_repeat_side_effects + _ => {}, + } +} diff --git a/tests/ui/zero_repeat_side_effects.stderr b/tests/ui/zero_repeat_side_effects.stderr index 49e850d03534..f376a1501b00 100644 --- a/tests/ui/zero_repeat_side_effects.stderr +++ b/tests/ui/zero_repeat_side_effects.stderr @@ -1,5 +1,5 @@ error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:17:5 + --> tests/ui/zero_repeat_side_effects.rs:22:5 | LL | let a = [f(); 0]; | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + let a: [i32; 0] = []; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:20:5 + --> tests/ui/zero_repeat_side_effects.rs:25:5 | LL | b = [f(); 0]; | ^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL ~ b = [] as [i32; 0]; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:25:5 + --> tests/ui/zero_repeat_side_effects.rs:30:5 | LL | let c = vec![f(); 0]; | ^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + let c: std::vec::Vec = vec![]; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:28:5 + --> tests/ui/zero_repeat_side_effects.rs:33:5 | LL | d = vec![f(); 0]; | ^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL ~ d = vec![] as std::vec::Vec; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:32:5 + --> tests/ui/zero_repeat_side_effects.rs:37:5 | LL | let e = [println!("side effect"); 0]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + let e: [(); 0] = []; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:36:5 + --> tests/ui/zero_repeat_side_effects.rs:41:5 | LL | let g = [{ f() }; 0]; | ^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + let g: [i32; 0] = []; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:40:10 + --> tests/ui/zero_repeat_side_effects.rs:45:10 | LL | drop(vec![f(); 0]); | ^^^^^^^^^^^^ @@ -87,7 +87,7 @@ LL ~ }); | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:44:5 + --> tests/ui/zero_repeat_side_effects.rs:49:5 | LL | vec![f(); 0]; | ^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL ~ vec![] as std::vec::Vec; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:46:5 + --> tests/ui/zero_repeat_side_effects.rs:51:5 | LL | [f(); 0]; | ^^^^^^^^ @@ -111,7 +111,7 @@ LL ~ [] as [i32; 0]; | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:100:10 + --> tests/ui/zero_repeat_side_effects.rs:105:10 | LL | foo(&[Some(f()); 0]); | ^^^^^^^^^^^^^^ @@ -125,7 +125,7 @@ LL ~ }); | error: expression with side effects as the initial value in a zero-sized array initializer - --> tests/ui/zero_repeat_side_effects.rs:102:10 + --> tests/ui/zero_repeat_side_effects.rs:107:10 | LL | foo(&[Some(Some(S::new())); 0]); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -138,5 +138,33 @@ LL + [] as [std::option::Option>; 0] LL ~ }); | -error: aborting due to 11 previous errors +error: expression with side effects as the initial value in a zero-sized array initializer + --> tests/ui/zero_repeat_side_effects.rs:115:14 + | +LL | 0 => _ = [f(); 0], + | ^^^^^^^^^^^^ + | +help: consider performing the side effect separately + | +LL ~ 0 => { +LL + f(); +LL + _ = [] as [(); 0] +LL ~ }, + | + +error: expression with side effects as the initial value in a zero-sized array initializer + --> tests/ui/zero_repeat_side_effects.rs:122:14 + | +LL | 0 => a = [f(); 0], + | ^^^^^^^^^^^^ + | +help: consider performing the side effect separately + | +LL ~ 0 => { +LL + f(); +LL + a = [] as [(); 0] +LL ~ }, + | + +error: aborting due to 13 previous errors diff --git a/triagebot.toml b/triagebot.toml index 3bf62b6b3bba..09dec7675e7e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -22,9 +22,6 @@ allow-unauthenticated = [ [mentions."clippy_lints/src/doc"] cc = ["@notriddle"] -# Prevents mentions in commits to avoid users being spammed -[no-mentions] - # Have rustbot inform users about the *No Merge Policy* [no-merges] exclude_titles = ["Rustup"] # exclude syncs from rust-lang/rust @@ -65,6 +62,7 @@ users_on_vacation = [ "Manishearth", "Alexendoo", "y21", + "blyxyas", ] [assign.owners] @@ -77,7 +75,6 @@ users_on_vacation = [ "@Alexendoo", "@dswij", "@Jarcho", - "@blyxyas", "@y21", "@samueltardieu", ] diff --git a/util/gh-pages/style.css b/util/gh-pages/style.css index 242e2227ed94..ce478a3e18d0 100644 --- a/util/gh-pages/style.css +++ b/util/gh-pages/style.css @@ -637,14 +637,14 @@ pre, hr { display: flex; } -ul.dropdown-menu li.checkbox > button { +#menu-filters ul.dropdown-menu li.checkbox > button { border: 0; width: 100%; background: var(--theme-popup-bg); color: var(--fg); } -ul.dropdown-menu li.checkbox > button:hover { +#menu-filters ul.dropdown-menu li.checkbox > button:hover { background: var(--theme-hover); box-shadow: none; } From 43fa2a95c90d7ac4bb98d87e62630e9f549d00c2 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 11 Dec 2025 18:15:15 +0000 Subject: [PATCH 0600/3801] add regression test for `proc_macro` error subdiagnostics --- tests/ui/proc-macro/auxiliary/sub-error-diag.rs | 17 +++++++++++++++++ tests/ui/proc-macro/sub-error-diag.rs | 13 +++++++++++++ tests/ui/proc-macro/sub-error-diag.stderr | 11 +++++++++++ 3 files changed, 41 insertions(+) create mode 100644 tests/ui/proc-macro/auxiliary/sub-error-diag.rs create mode 100644 tests/ui/proc-macro/sub-error-diag.rs create mode 100644 tests/ui/proc-macro/sub-error-diag.stderr diff --git a/tests/ui/proc-macro/auxiliary/sub-error-diag.rs b/tests/ui/proc-macro/auxiliary/sub-error-diag.rs new file mode 100644 index 000000000000..5ce8c5d90304 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/sub-error-diag.rs @@ -0,0 +1,17 @@ +#![feature(proc_macro_diagnostic)] + +extern crate proc_macro; + +use proc_macro::{Diagnostic, Level, Span}; + +#[proc_macro_attribute] +pub fn proc_emit_err( + _: proc_macro::TokenStream, + input: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + Diagnostic::new(Level::Error, "Parent message") + .span_error(Span::call_site(), "Child message") + .emit(); + + input +} diff --git a/tests/ui/proc-macro/sub-error-diag.rs b/tests/ui/proc-macro/sub-error-diag.rs new file mode 100644 index 000000000000..11218fc66a37 --- /dev/null +++ b/tests/ui/proc-macro/sub-error-diag.rs @@ -0,0 +1,13 @@ +//@ proc-macro: sub-error-diag.rs + +// Regression test for issue https://github.com/rust-lang/rust/issues/145305, which used to cause an ICE +// due to an assertion in the compiler that errors could not be subdiagnostics. + +extern crate sub_error_diag; + +//~? ERROR: Parent message +#[sub_error_diag::proc_emit_err] +//~^ ERROR: Child message +fn foo() {} + +fn main() {} diff --git a/tests/ui/proc-macro/sub-error-diag.stderr b/tests/ui/proc-macro/sub-error-diag.stderr new file mode 100644 index 000000000000..b5d83e4d52ae --- /dev/null +++ b/tests/ui/proc-macro/sub-error-diag.stderr @@ -0,0 +1,11 @@ +error: Parent message + | +error: Child message + --> $DIR/sub-error-diag.rs:9:1 + | +LL | #[sub_error_diag::proc_emit_err] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the attribute macro `sub_error_diag::proc_emit_err` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + From 26c164f60cf6491146c5000cfda5c6602ac22088 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 11 Dec 2025 19:16:53 +0100 Subject: [PATCH 0601/3801] Update Cargo.lock --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03a4d71f67c3..0be6de0a2871 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -621,7 +621,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "clippy" -version = "0.1.93" +version = "0.1.94" dependencies = [ "anstream", "askama", @@ -648,7 +648,7 @@ dependencies = [ [[package]] name = "clippy_config" -version = "0.1.93" +version = "0.1.94" dependencies = [ "clippy_utils", "itertools", @@ -671,7 +671,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.1.93" +version = "0.1.94" dependencies = [ "arrayvec", "cargo_metadata 0.18.1", @@ -703,7 +703,7 @@ dependencies = [ [[package]] name = "clippy_utils" -version = "0.1.93" +version = "0.1.94" dependencies = [ "arrayvec", "itertools", @@ -1107,7 +1107,7 @@ dependencies = [ [[package]] name = "declare_clippy_lint" -version = "0.1.93" +version = "0.1.94" [[package]] name = "derive-where" From 03493597922f6d1527955b1d7558dd369126f1d9 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Mon, 8 Dec 2025 21:39:59 +0000 Subject: [PATCH 0602/3801] Suggest `cfg(false)` instead of `cfg(FALSE)` --- compiler/rustc_lint/messages.ftl | 1 + .../src/early/diagnostics/check_cfg.rs | 25 +++++ compiler/rustc_lint/src/lints.rs | 11 +++ tests/ui/check-cfg/false.rs | 61 ++++++++++++ tests/ui/check-cfg/false.stderr | 95 +++++++++++++++++++ 5 files changed, 193 insertions(+) create mode 100644 tests/ui/check-cfg/false.rs create mode 100644 tests/ui/check-cfg/false.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index bc1c246b8f03..846c83aff2d3 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -829,6 +829,7 @@ lint_unexpected_cfg_add_build_rs_println = or consider adding `{$build_rs_printl lint_unexpected_cfg_add_cargo_feature = consider using a Cargo feature instead lint_unexpected_cfg_add_cargo_toml_lint_cfg = or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:{$cargo_toml_lint_cfg} lint_unexpected_cfg_add_cmdline_arg = to expect this configuration use `{$cmdline_arg}` +lint_unexpected_cfg_boolean = you may have meant to use `{$literal}` (notice the capitalization). Doing so makes this predicate evaluate to `{$literal}` unconditionally lint_unexpected_cfg_cargo_update = the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}` lint_unexpected_cfg_define_features = consider defining some features in `Cargo.toml` diff --git a/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs index e2f5dd315d57..0c8d7523a9dc 100644 --- a/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs +++ b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs @@ -138,6 +138,16 @@ pub(super) fn unexpected_cfg_name( let is_from_external_macro = name_span.in_external_macro(sess.source_map()); let mut is_feature_cfg = name == sym::feature; + fn miscapitalized_boolean(name: Symbol) -> Option { + if name.as_str().eq_ignore_ascii_case("false") { + Some(false) + } else if name.as_str().eq_ignore_ascii_case("true") { + Some(true) + } else { + None + } + } + let code_sugg = if is_feature_cfg && is_from_cargo { lints::unexpected_cfg_name::CodeSuggestion::DefineFeatures // Suggest correct `version("..")` predicate syntax @@ -148,6 +158,21 @@ pub(super) fn unexpected_cfg_name( between_name_and_value: name_span.between(value_span), after_value: value_span.shrink_to_hi(), } + // Suggest a literal `false` instead + // Detect miscapitalized `False`/`FALSE` etc, ensuring that this isn't `r#false` + } else if value.is_none() + // If this is a miscapitalized False/FALSE, suggest the boolean literal instead + && let Some(boolean) = miscapitalized_boolean(name) + // Check this isn't a raw identifier + && sess + .source_map() + .span_to_snippet(name_span) + .map_or(true, |snippet| !snippet.contains("r#")) + { + lints::unexpected_cfg_name::CodeSuggestion::BooleanLiteral { + span: name_span, + literal: boolean, + } // Suggest the most probable if we found one } else if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) { is_feature_cfg |= best_match == sym::feature; diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 1bec316ce45a..3f853e09c72d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2401,6 +2401,17 @@ pub(crate) mod unexpected_cfg_name { #[subdiagnostic] expected_names: Option, }, + #[suggestion( + lint_unexpected_cfg_boolean, + applicability = "machine-applicable", + style = "verbose", + code = "{literal}" + )] + BooleanLiteral { + #[primary_span] + span: Span, + literal: bool, + }, } #[derive(Subdiagnostic)] diff --git a/tests/ui/check-cfg/false.rs b/tests/ui/check-cfg/false.rs new file mode 100644 index 000000000000..f7ed43ccfa95 --- /dev/null +++ b/tests/ui/check-cfg/false.rs @@ -0,0 +1,61 @@ +//! Check that `cfg(false)` is suggested instead of cfg(FALSE) +// +//@ check-pass +//@ no-auto-check-cfg +//@ compile-flags: --check-cfg=cfg() + +#[cfg(FALSE)] +//~^ WARNING unexpected `cfg` condition name: `FALSE` +//~| HELP: to expect this configuration use +//~| HELP: you may have meant to use `false` (notice the capitalization). +pub fn a() {} + +#[cfg(False)] +//~^ WARNING unexpected `cfg` condition name: `False` +//~| HELP: to expect this configuration use +//~| HELP: you may have meant to use `false` (notice the capitalization). +pub fn b() {} + +#[cfg(r#false)] +//~^ WARNING unexpected `cfg` condition name: `r#false` +//~| HELP: to expect this configuration use +// No capitalization help for r#false +pub fn c() {} + +#[cfg(r#False)] +//~^ WARNING unexpected `cfg` condition name: `False` +//~| HELP: to expect this configuration use +// No capitalization help for r#False +pub fn d() {} + +#[cfg(false)] +pub fn e() {} + +#[cfg(TRUE)] +//~^ WARNING unexpected `cfg` condition name: `TRUE` +//~| HELP: to expect this configuration use +//~| HELP: you may have meant to use `true` (notice the capitalization). +pub fn f() {} + +#[cfg(True)] +//~^ WARNING unexpected `cfg` condition name: `True` +//~| HELP: to expect this configuration use +//~| HELP: you may have meant to use `true` (notice the capitalization). +pub fn g() {} + +#[cfg(r#true)] +//~^ WARNING unexpected `cfg` condition name: `r#true` +//~| HELP: to expect this configuration use +// No capitalization help for r#true +pub fn h() {} + +#[cfg(r#True)] +//~^ WARNING unexpected `cfg` condition name: `True` +//~| HELP: to expect this configuration use +// No capitalization help for r#True +pub fn i() {} + +#[cfg(true)] +pub fn j() {} + +pub fn main() {} diff --git a/tests/ui/check-cfg/false.stderr b/tests/ui/check-cfg/false.stderr new file mode 100644 index 000000000000..f4480a3dc67e --- /dev/null +++ b/tests/ui/check-cfg/false.stderr @@ -0,0 +1,95 @@ +warning: unexpected `cfg` condition name: `FALSE` + --> $DIR/false.rs:7:7 + | +LL | #[cfg(FALSE)] + | ^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(FALSE)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default +help: you may have meant to use `false` (notice the capitalization). Doing so makes this predicate evaluate to `false` unconditionally + | +LL - #[cfg(FALSE)] +LL + #[cfg(false)] + | + +warning: unexpected `cfg` condition name: `False` + --> $DIR/false.rs:13:7 + | +LL | #[cfg(False)] + | ^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(False)` + = note: see for more information about checking conditional configuration +help: you may have meant to use `false` (notice the capitalization). Doing so makes this predicate evaluate to `false` unconditionally (notice the capitalization) + | +LL - #[cfg(False)] +LL + #[cfg(false)] + | + +warning: unexpected `cfg` condition name: `r#false` + --> $DIR/false.rs:19:7 + | +LL | #[cfg(r#false)] + | ^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(r#false)` + = note: see for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `False` + --> $DIR/false.rs:25:7 + | +LL | #[cfg(r#False)] + | ^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(False)` + = note: see for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `TRUE` + --> $DIR/false.rs:34:7 + | +LL | #[cfg(TRUE)] + | ^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(TRUE)` + = note: see for more information about checking conditional configuration +help: you may have meant to use `true` (notice the capitalization). Doing so makes this predicate evaluate to `true` unconditionally + | +LL - #[cfg(TRUE)] +LL + #[cfg(true)] + | + +warning: unexpected `cfg` condition name: `True` + --> $DIR/false.rs:40:7 + | +LL | #[cfg(True)] + | ^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(True)` + = note: see for more information about checking conditional configuration +help: you may have meant to use `true` (notice the capitalization). Doing so makes this predicate evaluate to `true` unconditionally + | +LL - #[cfg(True)] +LL + #[cfg(true)] + | + +warning: unexpected `cfg` condition name: `r#true` + --> $DIR/false.rs:46:7 + | +LL | #[cfg(r#true)] + | ^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(r#true)` + = note: see for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `True` + --> $DIR/false.rs:52:7 + | +LL | #[cfg(r#True)] + | ^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(True)` + = note: see for more information about checking conditional configuration + +warning: 8 warnings emitted + From 30eb6adf41e2105fd92213d8a129347cde200ded Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 11 Dec 2025 20:18:57 +0000 Subject: [PATCH 0603/3801] say "certain" --- src/doc/rustc-dev-guide/src/tests/compiletest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index cda5c1bcec71..c885bce75dd6 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -90,7 +90,7 @@ The following test suites are available, with links for more information: | `rustdoc-ui` | Check terminal output of `rustdoc` ([see also](ui.md)) | Some rustdoc-specific tests can also be found in `ui/rustdoc/`. -These tests ensure that lints that are emitted as part of executing rustdoc +These tests ensure that certain lints that are emitted as part of executing rustdoc are also run when executing rustc. Run-make tests pertaining to rustdoc are typically named `run-make/rustdoc-*/`. From 31ce232fda9790c5025d6f89a23b8fd67e8b9369 Mon Sep 17 00:00:00 2001 From: Paul Murphy Date: Tue, 21 Oct 2025 15:02:52 -0500 Subject: [PATCH 0604/3801] Stabilize ppc inline assembly --- compiler/rustc_ast_lowering/src/asm.rs | 2 + .../asm-experimental-arch.md | 41 +------------------ 2 files changed, 4 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index d44faad017ee..afcbae9c51b4 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -51,6 +51,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | asm::InlineAsmArch::LoongArch32 | asm::InlineAsmArch::LoongArch64 | asm::InlineAsmArch::S390x + | asm::InlineAsmArch::PowerPC + | asm::InlineAsmArch::PowerPC64 ); if !is_stable && !self.tcx.features().asm_experimental_arch() { feature_err( diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index 77d43315a6d4..23ac46b72ea7 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -8,7 +8,6 @@ The tracking issue for this feature is: [#93335] This feature tracks `asm!` and `global_asm!` support for the following architectures: - NVPTX -- PowerPC - Hexagon - MIPS32r2 and MIPS64r2 - wasm32 @@ -31,16 +30,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg64` | None\* | `l` | | Hexagon | `reg` | `r[0-28]` | `r` | | Hexagon | `preg` | `p[0-3]` | Only clobbers | -| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-29]`\* | `r` | -| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-29]`\* | `b` | -| PowerPC | `freg` | `f[0-31]` | `f` | -| PowerPC | `vreg` | `v[0-31]` | `v` | -| PowerPC | `vsreg | `vs[0-63]` | `wa` | -| PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers | -| PowerPC | `ctr` | `ctr` | Only clobbers | -| PowerPC | `lr` | `lr` | Only clobbers | -| PowerPC | `xer` | `xer` | Only clobbers | -| PowerPC | `spe_acc` | `spe_acc` | Only clobbers | | wasm32 | `local` | None\* | `r` | | BPF | `reg` | `r[0-10]` | `r` | | BPF | `wreg` | `w[0-10]` | `w` | @@ -62,10 +51,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect > - NVPTX doesn't have a fixed register set, so named registers are not supported. > > - WebAssembly doesn't have registers, so named registers are not supported. -> -> - r29 is reserved only on 32 bit PowerPC targets. -> -> - spe_acc is only available on PowerPC SPE targets. # Register class supported types @@ -80,17 +65,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | | Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` | | Hexagon | `preg` | N/A | Only clobbers | -| PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | -| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | -| PowerPC | `freg` | None | `f32`, `f64` | -| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` | -| PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` | -| PowerPC | `vsreg` | `vsx` | The union of vsx and altivec vreg types | -| PowerPC | `cr` | N/A | Only clobbers | -| PowerPC | `ctr` | N/A | Only clobbers | -| PowerPC | `lr` | N/A | Only clobbers | -| PowerPC | `xer` | N/A | Only clobbers | -| PowerPC | `spe_acc` | N/A | Only clobbers | | wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` | | BPF | `reg` | None | `i8` `i16` `i32` `i64` | | BPF | `wreg` | `alu32` | `i8` `i16` `i32` | @@ -111,10 +85,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Hexagon | `r29` | `sp` | | Hexagon | `r30` | `fr` | | Hexagon | `r31` | `lr` | -| PowerPC | `r1` | `sp` | -| PowerPC | `r31` | `fp` | -| PowerPC | `r[0-31]` | `[0-31]` | -| PowerPC | `f[0-31]` | `fr[0-31]`| | BPF | `r[0-10]` | `w[0-10]` | | AVR | `XH` | `r27` | | AVR | `XL` | `r26` | @@ -153,16 +123,14 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Architecture | Unsupported register | Reason | | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | All | `sp`, `r14`/`o6` (SPARC) | The stack pointer must be restored to its original value at the end of an asm code block. | -| All | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output. | -| All | `r19` (Hexagon), `r29` (PowerPC 32 bit only), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. | +| All | `fr` (Hexagon) `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output. | +| All | `r19` (Hexagon) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. | | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | | MIPS | `$1` or `$at` | Reserved for assembler. | | MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. | | MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. | | MIPS | `$ra` | Return address cannot be used as inputs or outputs. | | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | -| PowerPC | `r2`, `r13` | These are system reserved registers. | -| PowerPC | `vrsave` | The vrsave register cannot be used as an input or output. | | AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | |MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. | | M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer. | @@ -189,11 +157,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None | `r0` | None | | NVPTX | `reg64` | None | `rd0` | None | | Hexagon | `reg` | None | `r0` | None | -| PowerPC | `reg` | None | `0` | None | -| PowerPC | `reg_nonzero` | None | `3` | None | -| PowerPC | `freg` | None | `0` | None | -| PowerPC | `vreg` | None | `0` | None | -| PowerPC | `vsreg` | None | `0` | None | | SPARC | `reg` | None | `%o0` | None | | CSKY | `reg` | None | `r0` | None | | CSKY | `freg` | None | `f0` | None | From 0e81edcc67dc6148cc2b3da4f4bedcfed19b0fbf Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 11 Dec 2025 21:14:14 +0000 Subject: [PATCH 0605/3801] fix help wanted search --- src/doc/rustc-dev-guide/src/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 34bc5b59dd03..061f6966f4b7 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -96,7 +96,7 @@ For example: Not all important or beginner work has issue labels. See below for how to find work that isn't labelled. -[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+-linked%3Apr+ +[help-wanted-search]: https://github.com/issues?q=is%3Aopen%20is%3Aissue%20org%3Arust-lang%20no%3Aassignee%20label%3AE-easy%2CE-medium%2CE-help-wanted%2CE-mentor%20-label%3AS-blocked%20-linked%3Apr [Triage]: ./contributing.md#issue-triage ### Recurring work From e58de3a54c0d019f0725d2e33d23833894cfd52c Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 11 Dec 2025 21:18:21 +0000 Subject: [PATCH 0606/3801] clarify why define_opaque isnt needed --- .../rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md index 0f0e8e87c321..9f20bfc708dc 100644 --- a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md +++ b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md @@ -85,7 +85,7 @@ impl Baz for Quux { ``` For this you would also need to use `nightly` and the (different) `#![feature(impl_trait_in_assoc_type)]` annotation. -Note that you don't need a `#[define_opaque(Foo)]` on the method anymore. +Note that you don't need a `#[define_opaque(Foo)]` on the method anymore as the opaque type is mentioned in the function signature (behind the associated type). Complete example: ``` From ad25b20bdbc7a4aa301f20090519873d34f219a1 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 12 Dec 2025 00:09:31 +0200 Subject: [PATCH 0607/3801] Fix Clippy Needed because there is a new Clippy - Rust 1.92.0 was released. --- .../rust-analyzer/crates/hir-ty/src/infer.rs | 23 ++++++++----------- .../hir-ty/src/next_solver/infer/traits.rs | 4 ---- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index cafe0329692c..70868e4b95aa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -653,19 +653,16 @@ impl<'db> InferenceResult<'db> { } pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option> { match self.expr_adjustments.get(&id).and_then(|adjustments| { - adjustments - .iter() - .filter(|adj| { - // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140 - !matches!( - adj, - Adjustment { - kind: Adjust::NeverToAny, - target, - } if target.is_never() - ) - }) - .next_back() + adjustments.iter().rfind(|adj| { + // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140 + !matches!( + adj, + Adjustment { + kind: Adjust::NeverToAny, + target, + } if target.is_never() + ) + }) }) { Some(adjustment) => Some(adjustment.target), None => self.type_of_expr.get(id).copied(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs index 4f000c24cc73..3409de17a122 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs @@ -36,10 +36,6 @@ pub struct ObligationCause { } impl ObligationCause { - #[expect( - clippy::new_without_default, - reason = "`new` is temporary, eventually we will provide span etc. here" - )] #[inline] pub fn new() -> ObligationCause { ObligationCause { _private: () } From 901ab2b4a8a90114c471e553b91bd40bdb20d231 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 11 Dec 2025 23:54:54 +0200 Subject: [PATCH 0608/3801] Fix a panic in `ast::TypeBound::kind()` --- .../crates/hir-def/src/expr_store/lower.rs | 3 ++- .../hir-def/src/expr_store/tests/signatures.rs | 12 ++++++++++++ .../rust-analyzer/crates/syntax/src/ast/node_ext.rs | 11 +++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 0b2af134c8ca..e72de6d68297 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -949,7 +949,8 @@ impl<'db> ExprCollector<'db> { node: ast::TypeBound, impl_trait_lower_fn: ImplTraitLowerFn<'_>, ) -> TypeBound { - match node.kind() { + let Some(kind) = node.kind() else { return TypeBound::Error }; + match kind { ast::TypeBoundKind::PathType(binder, path_type) => { let binder = match binder.and_then(|it| it.generic_param_list()) { Some(gpl) => gpl diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/signatures.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/signatures.rs index 2dac4e7fc84b..f1db00cf6a67 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/signatures.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/signatures.rs @@ -197,3 +197,15 @@ fn allowed3(baz: impl Baz>) {} "#]], ); } + +#[test] +fn regression_21138() { + lower_and_print( + r#" +fn foo(v: for<'a> Trait1 + Trait2) {} + "#, + expect![[r#" + fn foo(dyn for<'a> Trait1 + Trait2) {...} + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index 901d17bb1491..b872221bf711 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -813,13 +813,16 @@ pub enum TypeBoundKind { } impl ast::TypeBound { - pub fn kind(&self) -> TypeBoundKind { + pub fn kind(&self) -> Option { if let Some(path_type) = support::children(self.syntax()).next() { - TypeBoundKind::PathType(self.for_binder(), path_type) + Some(TypeBoundKind::PathType(self.for_binder(), path_type)) + } else if let Some(for_binder) = support::children::(&self.syntax).next() { + let Some(ast::Type::PathType(path_type)) = for_binder.ty() else { return None }; + Some(TypeBoundKind::PathType(for_binder.for_binder(), path_type)) } else if let Some(args) = self.use_bound_generic_args() { - TypeBoundKind::Use(args) + Some(TypeBoundKind::Use(args)) } else if let Some(lifetime) = self.lifetime() { - TypeBoundKind::Lifetime(lifetime) + Some(TypeBoundKind::Lifetime(lifetime)) } else { unreachable!() } From 8e77f362c7da14a0e25edaa93c7bb1864455ab4e Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 11 Dec 2025 23:37:10 +0000 Subject: [PATCH 0609/3801] make more clear code snippet is supposed to error --- .../rustc-dev-guide/src/ty_module/instantiating_binders.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md b/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md index 0d1108c72e0e..7e29b9543714 100644 --- a/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md +++ b/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md @@ -1,6 +1,6 @@ # Instantiating `Binder`s -Much like [`EarlyBinder`], when accessing the inside of a [`Binder`] we must first discharge it by replacing the bound vars with some other value. This is for much the same reason as with `EarlyBinder`, types referencing parameters introduced by the `Binder` do not make any sense outside of that binder, for example: +Much like [`EarlyBinder`], when accessing the inside of a [`Binder`] we must first discharge it by replacing the bound vars with some other value. This is for much the same reason as with `EarlyBinder`, types referencing parameters introduced by the `Binder` do not make any sense outside of that binder. See the following erroring example: ```rust,ignore fn foo<'a>(a: &'a u32) -> &'a u32 { a @@ -11,10 +11,11 @@ fn bar(a: fn(&u32) -> T) -> T { fn main() { let higher_ranked_fn_ptr = foo as for<'a> fn(&'a u32) -> &'a u32; + // Attempt to infer `T=for<'a> &'a u32` which is not satsifiable let references_bound_vars = bar(higher_ranked_fn_ptr); } ``` -In this example we are providing an argument of type `for<'a> fn(&'^0 u32) -> &'^0 u32` to `bar`, we do not want to allow `T` to be inferred to the type `&'^0 u32` as it would be rather nonsensical (and likely unsound if we did not happen to ICE, `main` has no idea what `'a` is so how would the borrow checker handle a borrow with lifetime `'a`). +In this example we are providing an argument of type `for<'a> fn(&'^0 u32) -> &'^0 u32` to `bar`, we do not want to allow `T` to be inferred to the type `&'^0 u32` as it would be rather nonsensical (and likely unsound if we did not happen to ICE). `main` doesn't know about `'a` so the borrow checker would not be able to handle a borrow with lifetime `'a`. Unlike `EarlyBinder` we typically do not instantiate `Binder` with some concrete set of arguments from the user, i.e. `['b, 'static]` as arguments to a `for<'a1, 'a2> fn(&'a1 u32, &'a2 u32)`. Instead we usually instantiate the binder with inference variables or placeholders. From 31f801ef4038bf5024a199835ec15dbb17f01c8a Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 11 Dec 2025 23:43:59 +0000 Subject: [PATCH 0610/3801] clarify test suite is not formatted --- src/doc/rustc-dev-guide/src/conventions.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index cce1d1850694..31028f1b9414 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -21,6 +21,9 @@ Instead, formatting should be done using `./x fmt`. It's a good habit to run Formatting is checked by the `tidy` script. It runs automatically when you do `./x test` and can be run in isolation with `./x fmt --check`. +We do not check that tests under the `tests/` directory are formatted, and +similarly the `./x fmt` command will not format any files under that directory. + If you want to use format-on-save in your editor, the pinned version of `rustfmt` is built under `build//stage0/bin/rustfmt`. From 3662b4ca36a63a37bf36ebc8ed56889912551111 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Thu, 11 Dec 2025 08:07:02 +0800 Subject: [PATCH 0611/3801] Add LoongArch notification group instructions --- src/doc/rustc-dev-guide/src/SUMMARY.md | 1 + .../src/notification-groups/about.md | 2 ++ .../src/notification-groups/loongarch.md | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 src/doc/rustc-dev-guide/src/notification-groups/loongarch.md diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 826a2955e60a..e80ee6a5137d 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -66,6 +66,7 @@ - [ARM](notification-groups/arm.md) - [Emscripten](notification-groups/emscripten.md) - [Fuchsia](notification-groups/fuchsia.md) + - [LoongArch](notification-groups/loongarch.md) - [RISC-V](notification-groups/risc-v.md) - [Rust for Linux](notification-groups/rust-for-linux.md) - [WASI](notification-groups/wasi.md) diff --git a/src/doc/rustc-dev-guide/src/notification-groups/about.md b/src/doc/rustc-dev-guide/src/notification-groups/about.md index c649b930fe9f..917a0f8a1020 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/about.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/about.md @@ -22,6 +22,7 @@ Here's the list of the notification groups: - [Apple](./apple.md) - [ARM](./arm.md) - [Emscripten](./emscripten.md) +- [LoongArch](./loongarch.md) - [RISC-V](./risc-v.md) - [WASI](./wasi.md) - [WebAssembly](./wasm.md) @@ -63,6 +64,7 @@ Example PRs: * [Example of adding yourself to the Apple group.](https://github.com/rust-lang/team/pull/1434) * [Example of adding yourself to the ARM group.](https://github.com/rust-lang/team/pull/358) * [Example of adding yourself to the Emscripten group.](https://github.com/rust-lang/team/pull/1579) +* [Example of adding yourself to the LoongArch group.](https://github.com/rust-lang/team/pull/2176) * [Example of adding yourself to the RISC-V group.](https://github.com/rust-lang/team/pull/394) * [Example of adding yourself to the WASI group.](https://github.com/rust-lang/team/pull/1580) * [Example of adding yourself to the WebAssembly group.](https://github.com/rust-lang/team/pull/1581) diff --git a/src/doc/rustc-dev-guide/src/notification-groups/loongarch.md b/src/doc/rustc-dev-guide/src/notification-groups/loongarch.md new file mode 100644 index 000000000000..0a3707a9ad99 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/notification-groups/loongarch.md @@ -0,0 +1,22 @@ +# LoongArch notification group + +**Github Label:** [O-loongarch]
+**Ping command:** `@rustbot ping loongarch` + +[O-loongarch]: https://github.com/rust-lang/rust/labels/O-loongarch + +This list will be used to ask for help both in diagnosing and testing +LoongArch-related issues as well as suggestions on how to resolve +interesting questions regarding our LoongArch support. + +The group also has an associated Zulip channel ([`#t-compiler/loong-arch`]) +where people can go to pose questions and discuss LoongArch-specific topics. + +So, if you are interested in participating, please sign up for the +LoongArch group! To do so, open a PR against the [rust-lang/team] +repository. Just [follow this example][eg], but change the username to +your own! + +[`#t-compiler/loong-arch`]: https://rust-lang.zulipchat.com/#narrow/channel/551512-t-compiler.2Floong-arch +[rust-lang/team]: https://github.com/rust-lang/team +[eg]: https://github.com/rust-lang/team/pull/2176 From ce822cd6f2b6012d2e44d696c915ea7634eb8f04 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 11 Dec 2025 23:53:21 +0000 Subject: [PATCH 0612/3801] remove dashboard :( --- src/doc/rustc-dev-guide/src/tests/ci.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index a30af309a54e..e132946ae83e 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -447,23 +447,6 @@ More information is available in the [toolstate documentation]. [rust-toolstate]: https://rust-lang-nursery.github.io/rust-toolstate [toolstate documentation]: https://forge.rust-lang.org/infra/toolstate.html -## Public CI dashboard - -To monitor the Rust CI, you can have a look at the [public dashboard] maintained by the infra team. - -These are some useful panels from the dashboard: - -- Pipeline duration: check how long the auto builds take to run. -- Top slowest jobs: check which jobs are taking the longest to run. -- Change in median job duration: check what jobs are slowest than before. Useful - to detect regressions. -- Top failed jobs: check which jobs are failing the most. - -To learn more about the dashboard, see the [Datadog CI docs]. - -[Datadog CI docs]: https://docs.datadoghq.com/continuous_integration/ -[public dashboard]: https://p.datadoghq.com/sb/3a172e20-e9e1-11ed-80e3-da7ad0900002-b5f7bb7e08b664a06b08527da85f7e30 - ## Determining the CI configuration If you want to determine which `bootstrap.toml` settings are used in CI for a From bceccc2eb361685ca6e073979a9080a49599fff9 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Fri, 12 Dec 2025 00:02:33 +0000 Subject: [PATCH 0613/3801] link to forge policy --- src/doc/rustc-dev-guide/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index fee7cf042e1f..8f0fa462a8c5 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -38,6 +38,11 @@ In general, when writing about a particular part of the compiler's code, we recommend that you link to the relevant parts of the [rustc rustdocs][rustdocs]. +The guide has a much lower bar for what it takes for a PR to be merged. Check out +the forge documentation for [our policy][forge_policy]. + +[forge_policy]: https://forge.rust-lang.org/rustc-dev-guide/index.html#review-policy + ### Build Instructions To build a local static HTML site, install [`mdbook`](https://github.com/rust-lang/mdBook) with: From 7897102fde1c930c4c059b38dea0c4d1b611d7d8 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 12 Dec 2025 09:17:18 +0800 Subject: [PATCH 0614/3801] Make test suite formatting remark more precise --- src/doc/rustc-dev-guide/src/conventions.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 31028f1b9414..92ed0825c8c3 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -21,8 +21,15 @@ Instead, formatting should be done using `./x fmt`. It's a good habit to run Formatting is checked by the `tidy` script. It runs automatically when you do `./x test` and can be run in isolation with `./x fmt --check`. -We do not check that tests under the `tests/` directory are formatted, and -similarly the `./x fmt` command will not format any files under that directory. +> **Note: Formatting and test suites** +> +> Most Rust source files under `tests/` directory are not formatted for reasons +> such as whitespace sensitivity, nature of snapshot tests, location-sensitive +> comments and more. +> +> Consult the `ignore` entries in +> for which test +> files are not formatted. If you want to use format-on-save in your editor, the pinned version of `rustfmt` is built under `build//stage0/bin/rustfmt`. From de0d961eb3cf26c73b2d03464845ab465a5484e5 Mon Sep 17 00:00:00 2001 From: Makai Date: Fri, 12 Dec 2025 10:25:23 +0800 Subject: [PATCH 0615/3801] triagebot: ping makai410 for rustc_public --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 397e6875eef9..00e2d4c787ab 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1154,7 +1154,7 @@ cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] [mentions."compiler/rustc_public"] message = "This PR changes rustc_public" -cc = ["@oli-obk", "@celinval", "@ouz-a"] +cc = ["@oli-obk", "@celinval", "@ouz-a", "@makai410"] [mentions."compiler/rustc_target/src/spec"] message = """ From 24302fd95f026197304b4814cab668553b4b345c Mon Sep 17 00:00:00 2001 From: Makai Date: Fri, 12 Dec 2025 10:26:03 +0800 Subject: [PATCH 0616/3801] triagebot: add myself(makai410) to the review rotation --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 00e2d4c787ab..3182122bdeb0 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1542,6 +1542,7 @@ project-stable-mir = [ "@celinval", "@oli-obk", "@scottmcm", + "@makai410", ] project-exploit-mitigations = [ "@cuviper", From 36201bdf3e72c286d7c209f780d3c5944e5491a1 Mon Sep 17 00:00:00 2001 From: Cuong Le Date: Tue, 9 Dec 2025 21:47:17 +0700 Subject: [PATCH 0617/3801] Add iterator reduction coverage to never_loop --- clippy_lints/src/loops/mod.rs | 18 ++++++- clippy_lints/src/loops/never_loop.rs | 52 ++++++++++++++++++- clippy_utils/src/sym.rs | 3 ++ tests/ui/never_loop_iterator_reduction.rs | 17 ++++++ tests/ui/never_loop_iterator_reduction.stderr | 27 ++++++++++ 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 tests/ui/never_loop_iterator_reduction.rs create mode 100644 tests/ui/never_loop_iterator_reduction.stderr diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 21198c3c8bc2..15993b832218 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -26,7 +26,7 @@ mod while_let_on_iterator; use clippy_config::Conf; use clippy_utils::msrvs::Msrv; -use clippy_utils::{higher, sym}; +use clippy_utils::{higher, sym, ty}; use rustc_ast::Label; use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; use rustc_lint::{LateContext, LateLintPass}; @@ -889,6 +889,22 @@ impl<'tcx> LateLintPass<'tcx> for Loops { { unused_enumerate_index::check_method(cx, expr, recv, arg); } + + if let ExprKind::MethodCall(path, recv, args, _) = expr.kind + && matches!( + path.ident.name, + sym::for_each + | sym::try_for_each + | sym::fold + | sym::try_fold + | sym::reduce + | sym::all + | sym::any + ) + && ty::get_iterator_item_ty(cx, cx.typeck_results().expr_ty(recv)).is_some() + { + never_loop::check_iterator_reduction(cx, expr, recv, args); + } } } diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index 0d37be17689a..b80e10b3d3c9 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -4,13 +4,14 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::ForLoop; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::snippet; +use clippy_utils::sym; use clippy_utils::visitors::{Descend, for_each_expr_without_closures}; use rustc_errors::Applicability; use rustc_hir::{ Block, Destination, Expr, ExprKind, HirId, InlineAsm, InlineAsmOperand, Node, Pat, Stmt, StmtKind, StructTailExpr, }; use rustc_lint::LateContext; -use rustc_span::{BytePos, Span, sym}; +use rustc_span::{BytePos, Span}; use std::iter::once; use std::ops::ControlFlow; @@ -72,6 +73,55 @@ pub(super) fn check<'tcx>( } } +pub(super) fn check_iterator_reduction<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'tcx>, + recv: &'tcx Expr<'tcx>, + args: &'tcx [Expr<'tcx>], +) { + // identify which argument is the closure based on the method kind + let Some(method_name) = (match expr.kind { + ExprKind::MethodCall(path, ..) => Some(path.ident.name), + _ => None, + }) else { + return; + }; + + let closure_arg = match method_name { + sym::for_each | sym::try_for_each | sym::reduce | sym::all | sym::any => args.get(0), + sym::fold | sym::try_fold => args.get(1), + _ => None, + }; + + let Some(closure_arg) = closure_arg else { + return; + }; + + // extract the closure body + let closure_body = match closure_arg.kind { + ExprKind::Closure(closure) => cx.tcx.hir_body(closure.body).value, + _ => return, + }; + + let body_ty = cx.typeck_results().expr_ty(closure_body); + if body_ty.is_never() { + span_lint_and_then( + cx, + NEVER_LOOP, + expr.span, + "this iterator reduction never loops (closure always diverges)", + |diag| { + let mut app = Applicability::Unspecified; + let recv_snip = make_iterator_snippet(cx, recv, &mut app); + diag.note("if you only need one element, `if let Some(x) = iter.next()` is clearer"); + let sugg = format!("if let Some(x) = {recv_snip}.next() {{ ... }}"); + diag.span_suggestion_verbose(expr.span, "consider this pattern", sugg, app); + }, + ); + return; + } +} + fn contains_any_break_or_continue(block: &Block<'_>) -> bool { for_each_expr_without_closures(block, |e| match e.kind { ExprKind::Break(..) | ExprKind::Continue(..) => ControlFlow::Break(()), diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 00f4a9c7e586..7372ff6cb9aa 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -66,6 +66,7 @@ generate! { Regex, RegexBuilder, RegexSet, + reduce, Start, Symbol, SyntaxContext, @@ -364,7 +365,9 @@ generate! { trim_start, trim_start_matches, truncate, + try_fold, try_for_each, + try_reduce, unreachable_pub, unsafe_removed_from_name, unused, diff --git a/tests/ui/never_loop_iterator_reduction.rs b/tests/ui/never_loop_iterator_reduction.rs new file mode 100644 index 000000000000..6b07b91db29a --- /dev/null +++ b/tests/ui/never_loop_iterator_reduction.rs @@ -0,0 +1,17 @@ +//@no-rustfix +#![warn(clippy::never_loop)] + +fn main() { + // diverging closure: should trigger + [0, 1].into_iter().for_each(|x| { + //~^ never_loop + + let _ = x; + panic!("boom"); + }); + + // benign closure: should NOT trigger + [0, 1].into_iter().for_each(|x| { + let _ = x + 1; + }); +} diff --git a/tests/ui/never_loop_iterator_reduction.stderr b/tests/ui/never_loop_iterator_reduction.stderr new file mode 100644 index 000000000000..b76ee283146c --- /dev/null +++ b/tests/ui/never_loop_iterator_reduction.stderr @@ -0,0 +1,27 @@ +error: this iterator reduction never loops (closure always diverges) + --> tests/ui/never_loop_iterator_reduction.rs:6:5 + | +LL | / [0, 1].into_iter().for_each(|x| { +LL | | +LL | | +LL | | let _ = x; +LL | | panic!("boom"); +LL | | }); + | |______^ + | + = note: if you only need one element, `if let Some(x) = iter.next()` is clearer + = note: `-D clippy::never-loop` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::never_loop)]` +help: consider this pattern + | +LL - [0, 1].into_iter().for_each(|x| { +LL - +LL - +LL - let _ = x; +LL - panic!("boom"); +LL - }); +LL + if let Some(x) = [0, 1].into_iter().next() { ... }; + | + +error: aborting due to 1 previous error + From 5aa2c14aebc731f54e737231e6f57cc7fc47a659 Mon Sep 17 00:00:00 2001 From: Makai Date: Fri, 12 Dec 2025 10:35:13 +0800 Subject: [PATCH 0618/3801] mailmap: add makai410 --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index a586e7047769..4c254b396b53 100644 --- a/.mailmap +++ b/.mailmap @@ -431,6 +431,7 @@ Lzu Tao Maik Klein Maja Kądziołka Maja Kądziołka +Makai Malo Jaffré Manish Goregaokar Mara Bos From 89a848c4399db85036e0b22f06f6f137801a79fe Mon Sep 17 00:00:00 2001 From: Cuong Le Date: Fri, 12 Dec 2025 10:24:49 +0700 Subject: [PATCH 0619/3801] Fix fmt and dogfood lints for never_loop iterator reduction --- clippy_lints/src/loops/mod.rs | 8 +------- clippy_lints/src/loops/never_loop.rs | 3 +-- clippy_utils/src/sym.rs | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 15993b832218..1070f568eddd 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -893,13 +893,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops { if let ExprKind::MethodCall(path, recv, args, _) = expr.kind && matches!( path.ident.name, - sym::for_each - | sym::try_for_each - | sym::fold - | sym::try_fold - | sym::reduce - | sym::all - | sym::any + sym::for_each | sym::try_for_each | sym::fold | sym::try_fold | sym::reduce | sym::all | sym::any ) && ty::get_iterator_item_ty(cx, cx.typeck_results().expr_ty(recv)).is_some() { diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index b80e10b3d3c9..b57d800ff37c 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -88,7 +88,7 @@ pub(super) fn check_iterator_reduction<'tcx>( }; let closure_arg = match method_name { - sym::for_each | sym::try_for_each | sym::reduce | sym::all | sym::any => args.get(0), + sym::for_each | sym::try_for_each | sym::reduce | sym::all | sym::any => args.first(), sym::fold | sym::try_fold => args.get(1), _ => None, }; @@ -118,7 +118,6 @@ pub(super) fn check_iterator_reduction<'tcx>( diag.span_suggestion_verbose(expr.span, "consider this pattern", sugg, app); }, ); - return; } } diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 7372ff6cb9aa..b66ef36c483e 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -66,7 +66,6 @@ generate! { Regex, RegexBuilder, RegexSet, - reduce, Start, Symbol, SyntaxContext, @@ -276,6 +275,7 @@ generate! { read_to_string, read_unaligned, read_volatile, + reduce, redundant_imports, redundant_pub_crate, regex, From fefd58b32b1bdc0bfb02cfa6c0c87e0c6a53d554 Mon Sep 17 00:00:00 2001 From: Cuong Le Date: Fri, 12 Dec 2025 10:37:34 +0700 Subject: [PATCH 0620/3801] Clean up unused try_reduce entry in sym --- clippy_utils/src/sym.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index b66ef36c483e..9e7f6e4ee308 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -367,7 +367,6 @@ generate! { truncate, try_fold, try_for_each, - try_reduce, unreachable_pub, unsafe_removed_from_name, unused, From c1472c573ae83c45a11bb61b10f205c65322485f Mon Sep 17 00:00:00 2001 From: Evgenii Zheltonozhskii Date: Fri, 12 Dec 2025 06:31:00 +0200 Subject: [PATCH 0621/3801] Add const cloning of slices and tests --- library/core/src/slice/mod.rs | 30 +++++++++----- library/coretests/tests/clone.rs | 71 ++++++++++++++++++++++++++++++++ library/coretests/tests/lib.rs | 3 ++ 3 files changed, 94 insertions(+), 10 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index dc34d2a21ee9..3202a330b7a4 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -9,6 +9,7 @@ use crate::clone::TrivialClone; use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics::{exact_div, unchecked_sub}; +use crate::marker::Destruct; use crate::mem::{self, MaybeUninit, SizedTypeProperties}; use crate::num::NonZero; use crate::ops::{OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeInclusive}; @@ -3823,9 +3824,10 @@ impl [T] { /// [`split_at_mut`]: slice::split_at_mut #[stable(feature = "clone_from_slice", since = "1.7.0")] #[track_caller] - pub fn clone_from_slice(&mut self, src: &[T]) + #[rustc_const_unstable(feature = "const_clone", issue = "142757")] + pub const fn clone_from_slice(&mut self, src: &[T]) where - T: Clone, + T: [const] Clone + [const] Destruct, { self.spec_clone_from(src); } @@ -5136,13 +5138,17 @@ const unsafe fn copy_from_slice_impl(dest: &mut [T], src: &[T]) { } } -trait CloneFromSpec { - fn spec_clone_from(&mut self, src: &[T]); +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +const trait CloneFromSpec { + fn spec_clone_from(&mut self, src: &[T]) + where + T: [const] Destruct; } -impl CloneFromSpec for [T] +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +impl const CloneFromSpec for [T] where - T: Clone, + T: [const] Clone + [const] Destruct, { #[track_caller] default fn spec_clone_from(&mut self, src: &[T]) { @@ -5152,15 +5158,19 @@ where // But since it can't be relied on we also have an explicit specialization for T: Copy. let len = self.len(); let src = &src[..len]; - for i in 0..len { - self[i].clone_from(&src[i]); + // FIXME(const_hack): make this a `for idx in 0..self.len()` loop. + let mut idx = 0; + while idx < self.len() { + self[idx].clone_from(&src[idx]); + idx += 1; } } } -impl CloneFromSpec for [T] +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +impl const CloneFromSpec for [T] where - T: TrivialClone, + T: [const] TrivialClone + [const] Destruct, { #[track_caller] fn spec_clone_from(&mut self, src: &[T]) { diff --git a/library/coretests/tests/clone.rs b/library/coretests/tests/clone.rs index 054b1d3d4986..68871dbccf07 100644 --- a/library/coretests/tests/clone.rs +++ b/library/coretests/tests/clone.rs @@ -121,3 +121,74 @@ fn cstr_metadata_is_length_with_nul() { let bytes: *const [u8] = p as *const [u8]; assert_eq!(s.to_bytes_with_nul().len(), bytes.len()); } + +#[test] +fn test_const_clone() { + const { + let bool: bool = Default::default(); + let char: char = Default::default(); + let ascii_char: std::ascii::Char = Default::default(); + let usize: usize = Default::default(); + let u8: u8 = Default::default(); + let u16: u16 = Default::default(); + let u32: u32 = Default::default(); + let u64: u64 = Default::default(); + let u128: u128 = Default::default(); + let i8: i8 = Default::default(); + let i16: i16 = Default::default(); + let i32: i32 = Default::default(); + let i64: i64 = Default::default(); + let i128: i128 = Default::default(); + let f16: f16 = Default::default(); + let f32: f32 = Default::default(); + let f64: f64 = Default::default(); + let f128: f128 = Default::default(); + + let bool_clone: bool = bool.clone(); + let char_clone: char = char.clone(); + let ascii_char_clone: std::ascii::Char = ascii_char.clone(); + + let usize_clone: usize = usize.clone(); + let u8_clone: u8 = u8.clone(); + let u16_clone: u16 = u16.clone(); + let u32_clone: u32 = u32.clone(); + let u64_clone: u64 = u64.clone(); + let u128_clone: u128 = u128.clone(); + let i8_clone: i8 = i8.clone(); + let i16_clone: i16 = i16.clone(); + let i32_clone: i32 = i32.clone(); + let i64_clone: i64 = i64.clone(); + let i128_clone: i128 = i128.clone(); + let f16_clone: f16 = f16.clone(); + let f32_clone: f32 = f32.clone(); + let f64_clone: f64 = f64.clone(); + let f128_clone: f128 = f128.clone(); + + assert!(bool == bool_clone); + assert!(char == char_clone); + assert!(ascii_char == ascii_char_clone); + assert!(usize == usize_clone); + assert!(u8 == u8_clone); + assert!(u16 == u16_clone); + assert!(u32 == u32_clone); + assert!(u64 == u64_clone); + assert!(u128 == u128_clone); + assert!(i8 == i8_clone); + assert!(i16 == i16_clone); + assert!(i32 == i32_clone); + assert!(i64 == i64_clone); + assert!(i128 == i128_clone); + assert!(f16 == f16_clone); + assert!(f32 == f32_clone); + assert!(f64 == f64_clone); + assert!(f128 == f128_clone); + + let src: [i32; 4] = [1, 2, 3, 4]; + let mut dst: [i32; 2] = [0, 0]; + + dst.clone_from_slice(&src[2..]); + + assert!(src == [1, 2, 3, 4]); + assert!(dst == [3, 4]); + } +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 0387b442562d..a8421f333155 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -19,11 +19,14 @@ #![feature(clone_to_uninit)] #![feature(const_array)] #![feature(const_cell_traits)] +#![feature(const_clone)] #![feature(const_cmp)] #![feature(const_convert)] +#![feature(const_default)] #![feature(const_destruct)] #![feature(const_drop_in_place)] #![feature(const_eval_select)] +#![feature(const_index)] #![feature(const_ops)] #![feature(const_option_ops)] #![feature(const_ref_cell)] From b7b0007bf05320cbfe046c1e67f54b5d92b4685e Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 5 Dec 2025 20:38:22 +0100 Subject: [PATCH 0622/3801] Add current working to source map and `FileLoader` This is preparation for the filename handling overhaul where having access to the working directory is mandatory. --- compiler/rustc_span/src/source_map.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 17de34c8436f..090442bf64bd 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -105,6 +105,9 @@ pub trait FileLoader { /// Read the contents of a potentially non-UTF-8 file into memory. /// We don't normalize binary files, so we can start in an Arc. fn read_binary_file(&self, path: &Path) -> io::Result>; + + /// Current working directory + fn current_directory(&self) -> io::Result; } /// A FileLoader that uses std::fs to load real files. @@ -170,6 +173,10 @@ impl FileLoader for RealFileLoader { file.read_to_end(&mut bytes)?; Ok(bytes.into()) } + + fn current_directory(&self) -> io::Result { + std::env::current_dir() + } } // _____________________________________________________________________________ @@ -198,6 +205,9 @@ pub struct SourceMap { // `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`. path_mapping: FilePathMapping, + /// Current working directory + working_dir: RealFileName, + /// The algorithm used for hashing the contents of each source file. hash_kind: SourceFileHashAlgorithm, @@ -221,8 +231,14 @@ impl SourceMap { pub fn with_inputs( SourceMapInputs { file_loader, path_mapping, hash_kind, checksum_hash_kind }: SourceMapInputs, ) -> SourceMap { + let cwd = file_loader + .current_directory() + .expect("expecting a current working directory to exist"); + let working_dir = cwd.to_path_buf().into(); + debug!(?working_dir); SourceMap { files: Default::default(), + working_dir, file_loader: IntoDynSyncSend(file_loader), path_mapping, hash_kind, @@ -234,6 +250,10 @@ impl SourceMap { &self.path_mapping } + pub fn working_dir(&self) -> &RealFileName { + &self.working_dir + } + pub fn file_exists(&self, path: &Path) -> bool { self.file_loader.file_exists(path) } From 5da3de7527d79c63cb6f0554037bffef376a5669 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 5 Dec 2025 21:00:04 +0100 Subject: [PATCH 0623/3801] Move users of `span_to_embeddable_string` to `span_to_diagnostic_string` This is done in order to simplify the filename overhaul and those places don't need to the embeddable path anyway. --- compiler/rustc_borrowck/src/region_infer/dump_mir.rs | 2 +- compiler/rustc_expand/src/stats.rs | 5 +---- compiler/rustc_middle/src/mir/pretty.rs | 8 ++++---- compiler/rustc_monomorphize/src/util.rs | 11 ++--------- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs index a9ab30fd8fa3..68f822aac403 100644 --- a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs +++ b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs @@ -80,7 +80,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let OutlivesConstraint { sup, sub, locations, category, span, .. } = constraint; let (name, arg) = match locations { Locations::All(span) => { - ("All", tcx.sess.source_map().span_to_embeddable_string(*span)) + ("All", tcx.sess.source_map().span_to_diagnostic_string(*span)) } Locations::Single(loc) => ("Single", format!("{loc:?}")), }; diff --git a/compiler/rustc_expand/src/stats.rs b/compiler/rustc_expand/src/stats.rs index 3e40632275b6..00f1c11044e0 100644 --- a/compiler/rustc_expand/src/stats.rs +++ b/compiler/rustc_expand/src/stats.rs @@ -138,10 +138,7 @@ pub(crate) fn update_macro_stats( if false { let name = ExpnKind::Macro(macro_kind, name).descr(); let crate_name = &ecx.ecfg.crate_name; - let span = ecx - .sess - .source_map() - .span_to_string(span, rustc_span::FileNameDisplayPreference::Local); + let span = ecx.sess.source_map().span_to_diagnostic_string(span); eprint!( "\ -------------------------------\n\ diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 3bdc5fdb420c..b225dd4ef60a 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -504,7 +504,7 @@ fn write_scope_tree( "{0:1$} // at {2}", indented_header, ALIGN, - tcx.sess.source_map().span_to_embeddable_string(span), + tcx.sess.source_map().span_to_diagnostic_string(span), )?; } else { writeln!(w, "{indented_header}")?; @@ -688,7 +688,7 @@ fn write_user_type_annotations( "| {:?}: user_ty: {}, span: {}, inferred_ty: {}", index.index(), annotation.user_ty, - tcx.sess.source_map().span_to_embeddable_string(annotation.span), + tcx.sess.source_map().span_to_diagnostic_string(annotation.span), with_no_trimmed_paths!(format!("{}", annotation.inferred_ty)), )?; } @@ -1420,7 +1420,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { self.push("mir::ConstOperand"); self.push(&format!( "+ span: {}", - self.tcx.sess.source_map().span_to_embeddable_string(*span) + self.tcx.sess.source_map().span_to_diagnostic_string(*span) )); if let Some(user_ty) = user_ty { self.push(&format!("+ user_ty: {user_ty:?}")); @@ -1503,7 +1503,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { } fn comment(tcx: TyCtxt<'_>, SourceInfo { span, scope }: SourceInfo) -> String { - let location = tcx.sess.source_map().span_to_embeddable_string(span); + let location = tcx.sess.source_map().span_to_diagnostic_string(span); format!("scope {} at {}", scope.index(), location,) } diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs index deb4ab433bfe..6fcb18177a14 100644 --- a/compiler/rustc_monomorphize/src/util.rs +++ b/compiler/rustc_monomorphize/src/util.rs @@ -49,7 +49,7 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In .unwrap_or_else(|e| format!("Failed {e:?}")); let closure_span = tcx.def_span(closure_def_id); - let src_file = tcx.sess.source_map().span_to_filename(closure_span); + let src_file = tcx.sess.source_map().span_to_diagnostic_string(closure_span); let line_nos = tcx .sess .source_map() @@ -57,14 +57,7 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In .map(|l| format!("{:?} {:?}", l.lines.first(), l.lines.last())) .unwrap_or_else(|e| format!("{e:?}")); - if let Err(e) = writeln!( - file, - "{}, {}, {}, {:?}", - old_size, - new_size, - src_file.prefer_local(), - line_nos - ) { + if let Err(e) = writeln!(file, "{}, {}, {}, {:?}", old_size, new_size, src_file, line_nos) { eprintln!("Error writing to file {e}") } } From 8cbfb26383347cf4970a488177acfdc35c30984b Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 28 Nov 2025 00:01:51 +0100 Subject: [PATCH 0624/3801] Overhaul filename handling for cross-compiler consistency This commit refactors `SourceMap` and most importantly `RealFileName` to make it self-contained in order to achieve cross-compiler consistency. This is achieved: - by making `RealFileName` immutable - by only having `SourceMap::to_real_filename` create `RealFileName` - by also making `RealFileName` holds it's working directory, it's embeddable name and the remapped scopes - by making most `FileName` and `RealFileName` methods take a scope as an argument In order for `SourceMap::to_real_filename` to know which scopes to apply `FilePathMapping` now takes the current remapping scopes to apply, which makes `FileNameDisplayPreference` and company useless and are removed. The scopes type `RemapPathScopeComponents` was moved from `rustc_session::config` to `rustc_span`. The previous system for scoping the local/remapped filenames `RemapFileNameExt::for_scope` is no longer useful as it's replaced by methods on `FileName` and `RealFileName`. --- Cargo.lock | 2 +- .../rustc_builtin_macros/src/source_util.rs | 7 +- compiler/rustc_builtin_macros/src/test.rs | 4 +- compiler/rustc_codegen_llvm/src/back/write.rs | 15 +- .../src/coverageinfo/mapgen.rs | 16 +- .../src/debuginfo/metadata.rs | 109 ++-- .../src/const_eval/machine.rs | 9 +- compiler/rustc_driver_impl/src/pretty.rs | 2 +- compiler/rustc_errors/src/json.rs | 14 +- compiler/rustc_errors/src/json/tests.rs | 6 +- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_interface/src/passes.rs | 10 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 52 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 +- compiler/rustc_middle/src/mir/consts.rs | 10 +- compiler/rustc_middle/src/ty/print/pretty.rs | 38 +- compiler/rustc_parse/src/lib.rs | 8 +- compiler/rustc_parse/src/parser/tests.rs | 20 +- compiler/rustc_passes/src/entry.rs | 7 +- .../rustc_public_bridge/src/context/impls.rs | 9 +- compiler/rustc_resolve/src/rustdoc/tests.rs | 10 +- compiler/rustc_session/Cargo.toml | 1 - compiler/rustc_session/src/config.rs | 58 +-- compiler/rustc_session/src/options.rs | 2 +- compiler/rustc_session/src/session.rs | 71 +-- compiler/rustc_span/Cargo.toml | 1 + compiler/rustc_span/src/lib.rs | 339 +++++++++---- compiler/rustc_span/src/profiling.rs | 3 +- compiler/rustc_span/src/source_map.rs | 256 ++++------ compiler/rustc_span/src/source_map/tests.rs | 472 ++++++++++++------ tests/run-make/duplicate-dependency/rmake.rs | 6 +- ...refix-diagnostics.only-diag-in-deps.stderr | 2 +- 32 files changed, 805 insertions(+), 764 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d818d87e0804..b7cca34528f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4630,7 +4630,6 @@ dependencies = [ name = "rustc_session" version = "0.0.0" dependencies = [ - "bitflags", "getopts", "libc", "rand 0.9.2", @@ -4657,6 +4656,7 @@ dependencies = [ name = "rustc_span" version = "0.0.0" dependencies = [ + "bitflags", "blake3", "derive-where", "indexmap", diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 16adaab15c52..d49f4ded010b 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -68,13 +68,10 @@ pub(crate) fn expand_file( let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.source_map().lookup_char_pos(topmost.lo()); - use rustc_session::RemapFileNameExt; - use rustc_session::config::RemapPathScopeComponents; + use rustc_span::RemapPathScopeComponents; ExpandResult::Ready(MacEager::expr(cx.expr_str( topmost, - Symbol::intern( - &loc.file.name.for_scope(cx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(), - ), + Symbol::intern(&loc.file.name.display(RemapPathScopeComponents::MACRO).to_string_lossy()), ))) } diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index f31ad4f591b1..6f14385d5d30 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -11,7 +11,7 @@ use rustc_errors::{Applicability, Diag, Level}; use rustc_expand::base::*; use rustc_hir::Attribute; use rustc_hir::attrs::AttributeKind; -use rustc_span::{ErrorGuaranteed, FileNameDisplayPreference, Ident, Span, Symbol, sym}; +use rustc_span::{ErrorGuaranteed, Ident, RemapPathScopeComponents, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; use tracing::debug; @@ -445,7 +445,7 @@ fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize, cx.sess.source_map().span_to_location_info(span); let file_name = match source_file { - Some(sf) => sf.name.display(FileNameDisplayPreference::Remapped).to_string(), + Some(sf) => sf.name.display(RemapPathScopeComponents::MACRO).to_string(), None => "no-location".to_string(), }; diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index b131de1df8ba..2c4943e835a6 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -21,10 +21,8 @@ use rustc_errors::{DiagCtxtHandle, Level}; use rustc_fs_util::{link_or_copy, path_to_c_string}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_session::config::{ - self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath, -}; -use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext, sym}; +use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath}; +use rustc_span::{BytePos, InnerSpan, Pos, RemapPathScopeComponents, SpanData, SyntaxContext, sym}; use rustc_target::spec::{ Arch, CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel, }; @@ -248,6 +246,7 @@ pub(crate) fn target_machine_factory( !sess.opts.unstable_opts.use_ctors_section.unwrap_or(sess.target.use_ctors_section); let path_mapping = sess.source_map().path_mapping().clone(); + let working_dir = sess.source_map().working_dir().clone(); let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated); @@ -271,9 +270,6 @@ pub(crate) fn target_machine_factory( } }; - let file_name_display_preference = - sess.filename_display_preference(RemapPathScopeComponents::DEBUGINFO); - let use_wasm_eh = wants_wasm_eh(sess); let prof = SelfProfilerRef::clone(&sess.prof); @@ -284,8 +280,9 @@ pub(crate) fn target_machine_factory( let path_to_cstring_helper = |path: Option| -> CString { let path = path.unwrap_or_default(); let path = path_mapping - .to_real_filename(path) - .to_string_lossy(file_name_display_preference) + .to_real_filename(&working_dir, path) + .path(RemapPathScopeComponents::DEBUGINFO) + .to_string_lossy() .into_owned(); CString::new(path).unwrap() }; diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index b3a11f8b12bf..bc54657a380a 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -7,9 +7,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods}; use rustc_data_structures::fx::FxIndexMap; use rustc_index::IndexVec; use rustc_middle::ty::TyCtxt; -use rustc_session::RemapFileNameExt; -use rustc_session::config::RemapPathScopeComponents; -use rustc_span::{SourceFile, StableSourceFileId}; +use rustc_span::{RemapPathScopeComponents, SourceFile, StableSourceFileId}; use tracing::debug; use crate::common::CodegenCx; @@ -127,10 +125,7 @@ impl GlobalFileTable { for file in all_files { raw_file_table.entry(file.stable_id).or_insert_with(|| { - file.name - .for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE) - .to_string_lossy() - .into_owned() + file.name.display(RemapPathScopeComponents::COVERAGE).to_string_lossy().into_owned() }); } @@ -145,9 +140,10 @@ impl GlobalFileTable { // resolve any other entries that are stored as relative paths. let base_dir = tcx .sess - .opts - .working_dir - .for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE) + .psess + .source_map() + .working_dir() + .path(RemapPathScopeComponents::COVERAGE) .to_string_lossy(); table.push(base_dir.as_ref()); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 5535ebe65859..dc941cb41c56 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::Arc; use std::{iter, ptr}; @@ -19,9 +19,7 @@ use rustc_middle::ty::{ self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility, }; use rustc_session::config::{self, DebugInfo, Lto}; -use rustc_span::{ - DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Span, Symbol, hygiene, -}; +use rustc_span::{DUMMY_SP, FileName, RemapPathScopeComponents, SourceFile, Span, Symbol, hygiene}; use rustc_symbol_mangling::typeid_for_trait_ref; use rustc_target::spec::DebuginfoKind; use smallvec::smallvec; @@ -555,79 +553,38 @@ pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFi ) -> &'ll DIFile { debug!(?source_file.name); - let filename_display_preference = - cx.sess().filename_display_preference(RemapPathScopeComponents::DEBUGINFO); - - use rustc_session::config::RemapPathScopeComponents; let (directory, file_name) = match &source_file.name { FileName::Real(filename) => { - let working_directory = &cx.sess().opts.working_dir; - debug!(?working_directory); + let (working_directory, embeddable_name) = + filename.embeddable_name(RemapPathScopeComponents::DEBUGINFO); - if filename_display_preference == FileNameDisplayPreference::Remapped { - let filename = cx - .sess() - .source_map() - .path_mapping() - .to_embeddable_absolute_path(filename.clone(), working_directory); + debug!(?working_directory, ?embeddable_name); - // Construct the absolute path of the file - let abs_path = filename.remapped_path_if_available(); - debug!(?abs_path); - - if let Ok(rel_path) = - abs_path.strip_prefix(working_directory.remapped_path_if_available()) - { - // If the compiler's working directory (which also is the DW_AT_comp_dir of - // the compilation unit) is a prefix of the path we are about to emit, then - // only emit the part relative to the working directory. Because of path - // remapping we sometimes see strange things here: `abs_path` might - // actually look like a relative path (e.g. - // `/src/lib.rs`), so if we emit it without taking - // the working directory into account, downstream tooling will interpret it - // as `//src/lib.rs`, which - // makes no sense. Usually in such cases the working directory will also be - // remapped to `` or some other prefix of the path - // we are remapping, so we end up with - // `//src/lib.rs`. - // By moving the working directory portion into the `directory` part of the - // DIFile, we allow LLVM to emit just the relative path for DWARF, while - // still emitting the correct absolute path for CodeView. - ( - working_directory.to_string_lossy(FileNameDisplayPreference::Remapped), - rel_path.to_string_lossy().into_owned(), - ) - } else { - ("".into(), abs_path.to_string_lossy().into_owned()) - } + if let Ok(rel_path) = embeddable_name.strip_prefix(working_directory) { + // If the compiler's working directory (which also is the DW_AT_comp_dir of + // the compilation unit) is a prefix of the path we are about to emit, then + // only emit the part relative to the working directory. Because of path + // remapping we sometimes see strange things here: `abs_path` might + // actually look like a relative path (e.g. + // `/src/lib.rs`), so if we emit it without taking + // the working directory into account, downstream tooling will interpret it + // as `//src/lib.rs`, which + // makes no sense. Usually in such cases the working directory will also be + // remapped to `` or some other prefix of the path + // we are remapping, so we end up with + // `//src/lib.rs`. + // + // By moving the working directory portion into the `directory` part of the + // DIFile, we allow LLVM to emit just the relative path for DWARF, while + // still emitting the correct absolute path for CodeView. + (working_directory.to_string_lossy(), rel_path.to_string_lossy().into_owned()) } else { - let working_directory = working_directory.local_path_if_available(); - let filename = filename.local_path_if_available(); - - debug!(?working_directory, ?filename); - - let abs_path: Cow<'_, Path> = if filename.is_absolute() { - filename.into() - } else { - let mut p = PathBuf::new(); - p.push(working_directory); - p.push(filename); - p.into() - }; - - if let Ok(rel_path) = abs_path.strip_prefix(working_directory) { - ( - working_directory.to_string_lossy(), - rel_path.to_string_lossy().into_owned(), - ) - } else { - ("".into(), abs_path.to_string_lossy().into_owned()) - } + ("".into(), embeddable_name.to_string_lossy().into_owned()) } } other => { debug!(?other); - ("".into(), other.display(filename_display_preference).to_string()) + ("".into(), other.display(RemapPathScopeComponents::DEBUGINFO).to_string()) } }; @@ -889,12 +846,10 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( codegen_unit_name: &str, debug_context: &CodegenUnitDebugContext<'ll, 'tcx>, ) -> &'ll DIDescriptor { - use rustc_session::RemapFileNameExt; - use rustc_session::config::RemapPathScopeComponents; let mut name_in_debuginfo = tcx .sess .local_crate_source_file() - .map(|src| src.for_scope(&tcx.sess, RemapPathScopeComponents::DEBUGINFO).to_path_buf()) + .map(|src| src.path(RemapPathScopeComponents::DEBUGINFO).to_path_buf()) .unwrap_or_else(|| PathBuf::from(tcx.crate_name(LOCAL_CRATE).as_str())); // To avoid breaking split DWARF, we need to ensure that each codegen unit @@ -923,12 +878,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( let producer = format!("clang LLVM ({rustc_producer})"); let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); - let work_dir = tcx - .sess - .opts - .working_dir - .for_scope(tcx.sess, RemapPathScopeComponents::DEBUGINFO) - .to_string_lossy(); + let work_dir = tcx.sess.psess.source_map().working_dir(); let output_filenames = tcx.output_filenames(()); let split_name = if tcx.sess.target_can_use_split_dwarf() && let Some(f) = output_filenames.split_dwarf_path( @@ -938,14 +888,15 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( tcx.sess.invocation_temp.as_deref(), ) { // We get a path relative to the working directory from split_dwarf_path - Some(tcx.sess.source_map().path_mapping().to_real_filename(f)) + Some(tcx.sess.source_map().path_mapping().to_real_filename(work_dir, f)) } else { None }; let split_name = split_name .as_ref() - .map(|f| f.for_scope(tcx.sess, RemapPathScopeComponents::DEBUGINFO).to_string_lossy()) + .map(|f| f.path(RemapPathScopeComponents::DEBUGINFO).to_string_lossy()) .unwrap_or_default(); + let work_dir = work_dir.path(RemapPathScopeComponents::DEBUGINFO).to_string_lossy(); let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo); let dwarf_version = tcx.sess.dwarf_version(); diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index fccb6b171b1c..0c677b34df7b 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -208,15 +208,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo()); - use rustc_session::RemapFileNameExt; - use rustc_session::config::RemapPathScopeComponents; + use rustc_span::RemapPathScopeComponents; ( Symbol::intern( - &caller - .file - .name - .for_scope(self.tcx.sess, RemapPathScopeComponents::DIAGNOSTICS) - .to_string_lossy(), + &caller.file.name.display(RemapPathScopeComponents::DIAGNOSTICS).to_string_lossy(), ), u32::try_from(caller.line).unwrap(), u32::try_from(caller.col_display).unwrap().checked_add(1).unwrap(), diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 1604b704033b..962d035db862 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -181,7 +181,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> { } fn get_source(sess: &Session) -> (String, FileName) { - let src_name = sess.io.input.source_name(); + let src_name = sess.io.input.file_name(&sess); let src = String::clone( sess.source_map() .get_source_file(&src_name) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index ce5c830bbfcd..3b8c8baa5eff 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -11,7 +11,7 @@ use std::error::Report; use std::io::{self, Write}; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use std::vec; @@ -20,9 +20,9 @@ use derive_setters::Setters; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_error_messages::FluentArgs; use rustc_lint_defs::Applicability; -use rustc_span::Span; use rustc_span::hygiene::ExpnData; use rustc_span::source_map::{FilePathMapping, SourceMap}; +use rustc_span::{FileName, RealFileName, Span}; use serde::Serialize; use crate::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; @@ -490,8 +490,14 @@ impl DiagnosticSpan { None => { span = rustc_span::DUMMY_SP; empty_source_map = Arc::new(SourceMap::new(FilePathMapping::empty())); - empty_source_map - .new_source_file(std::path::PathBuf::from("empty.rs").into(), String::new()); + empty_source_map.new_source_file( + FileName::Real( + empty_source_map + .path_mapping() + .to_real_filename(&RealFileName::empty(), PathBuf::from("empty.rs")), + ), + String::new(), + ); &empty_source_map } }; diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 79bb5054dfef..30be06ae0bd3 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -36,11 +36,15 @@ impl Write for Shared { } } +fn filename(sm: &SourceMap, path: &str) -> FileName { + FileName::Real(sm.path_mapping().to_real_filename(sm.working_dir(), PathBuf::from(path))) +} + /// Test the span yields correct positions in JSON. fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { rustc_span::create_default_session_globals_then(|| { let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); - sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned()); + sm.new_source_file(filename(&sm, "test.rs"), code.to_owned()); let translator = Translator::with_fallback_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false); diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 33431556c76c..6422779e13c9 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -470,7 +470,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { FileName::Real(name) => name .into_local_path() .expect("attempting to resolve a file path in an external file"), - other => PathBuf::from(other.prefer_local().to_string()), + other => PathBuf::from(other.prefer_local_unconditionally().to_string()), }; let dir_path = file_path.parent().unwrap_or(&file_path).to_owned(); self.cx.root_path = dir_path.clone(); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ddfec9f886a6..9acb69f5940d 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -40,8 +40,7 @@ use rustc_session::output::{collect_crate_types, filename_for_input}; use rustc_session::parse::feature_err; use rustc_session::search_paths::PathKind; use rustc_span::{ - DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, SourceFileHash, SourceFileHashAlgorithm, Span, - Symbol, sym, + DUMMY_SP, ErrorGuaranteed, ExpnKind, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym, }; use rustc_trait_selection::{solve, traits}; use tracing::{info, instrument}; @@ -595,7 +594,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P .filter(|fmap| !fmap.is_imported()) .map(|fmap| { ( - escape_dep_filename(&fmap.name.prefer_local().to_string()), + escape_dep_filename(&fmap.name.prefer_local_unconditionally().to_string()), // This needs to be unnormalized, // as external tools wouldn't know how rustc normalizes them fmap.unnormalized_source_len as u64, @@ -610,10 +609,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P // (e.g. accessed in proc macros). let file_depinfo = sess.psess.file_depinfo.borrow(); - let normalize_path = |path: PathBuf| { - let file = FileName::from(path); - escape_dep_filename(&file.prefer_local().to_string()) - }; + let normalize_path = |path: PathBuf| escape_dep_filename(&path.to_string_lossy()); // The entries will be used to declare dependencies between files in a // Makefile-like output, so the iteration order does not matter. diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 65cbdc675962..0a6e5f153dde 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -33,8 +33,8 @@ use rustc_session::config::TargetModifier; use rustc_session::cstore::{CrateSource, ExternCrate}; use rustc_span::hygiene::HygieneDecodeContext; use rustc_span::{ - BlobDecoder, BytePos, ByteSymbol, DUMMY_SP, Pos, SpanData, SpanDecoder, Symbol, SyntaxContext, - kw, + BlobDecoder, BytePos, ByteSymbol, DUMMY_SP, Pos, RemapPathScopeComponents, SpanData, + SpanDecoder, Symbol, SyntaxContext, kw, }; use tracing::debug; @@ -1669,15 +1669,15 @@ impl<'a> CrateMetadataRef<'a> { for virtual_dir in virtual_source_base_dir.iter().flatten() { if let Some(real_dir) = &real_source_base_dir && let rustc_span::FileName::Real(old_name) = name - && let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } = - old_name - && let Ok(rest) = virtual_name.strip_prefix(virtual_dir) + && let (_working_dir, embeddable_name) = + old_name.embeddable_name(RemapPathScopeComponents::MACRO) + && let Ok(rest) = embeddable_name.strip_prefix(virtual_dir) { let new_path = real_dir.join(rest); debug!( "try_to_translate_virtual_to_real: `{}` -> `{}`", - virtual_name.display(), + embeddable_name.display(), new_path.display(), ); @@ -1686,17 +1686,12 @@ impl<'a> CrateMetadataRef<'a> { // Note that this is a special case for imported rust-src paths specified by // https://rust-lang.github.io/rfcs/3127-trim-paths.html#handling-sysroot-paths. // Other imported paths are not currently remapped (see #66251). - let (user_remapped, applied) = - tcx.sess.source_map().path_mapping().map_prefix(&new_path); - let new_name = if applied { - rustc_span::RealFileName::Remapped { - local_path: Some(new_path.clone()), - virtual_name: user_remapped.to_path_buf(), - } - } else { - rustc_span::RealFileName::LocalPath(new_path) - }; - *old_name = new_name; + *name = rustc_span::FileName::Real( + tcx.sess + .source_map() + .path_mapping() + .to_real_filename(&rustc_span::RealFileName::empty(), new_path), + ); } } }; @@ -1711,15 +1706,12 @@ impl<'a> CrateMetadataRef<'a> { && let Some(real_dir) = real_source_base_dir && let rustc_span::FileName::Real(old_name) = name { - let relative_path = match old_name { - rustc_span::RealFileName::LocalPath(local) => { - local.strip_prefix(real_dir).ok() - } - rustc_span::RealFileName::Remapped { virtual_name, .. } => { - virtual_source_base_dir - .and_then(|virtual_dir| virtual_name.strip_prefix(virtual_dir).ok()) - } - }; + let (_working_dir, embeddable_path) = + old_name.embeddable_name(RemapPathScopeComponents::MACRO); + let relative_path = embeddable_path.strip_prefix(real_dir).ok().or_else(|| { + virtual_source_base_dir + .and_then(|virtual_dir| embeddable_path.strip_prefix(virtual_dir).ok()) + }); debug!( ?relative_path, ?virtual_dir, @@ -1727,10 +1719,10 @@ impl<'a> CrateMetadataRef<'a> { "simulate_remapped_rust_src_base" ); if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok()) { - *old_name = rustc_span::RealFileName::Remapped { - local_path: None, - virtual_name: virtual_dir.join(subdir).join(rest), - }; + *name = + rustc_span::FileName::Real(rustc_span::RealFileName::from_virtual_path( + &virtual_dir.join(subdir).join(rest), + )) } } }; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 2069c06c3f77..b583c73b5a6b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -541,8 +541,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // is done. let required_source_files = self.required_source_files.take().unwrap(); - let working_directory = &self.tcx.sess.opts.working_dir; - let mut adapted = TableBuilder::default(); let local_crate_stable_id = self.tcx.stable_crate_id(LOCAL_CRATE); @@ -567,10 +565,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { match source_file.name { FileName::Real(ref original_file_name) => { - let adapted_file_name = source_map - .path_mapping() - .to_embeddable_absolute_path(original_file_name.clone(), working_directory); - + let mut adapted_file_name = original_file_name.clone(); + adapted_file_name.update_for_crate_metadata(); adapted_source_file.name = FileName::Real(adapted_file_name); } _ => { diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 6985cc7ddcfa..fe352df3b9f0 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -3,9 +3,7 @@ use std::fmt::{self, Debug, Display, Formatter}; use rustc_abi::{HasDataLayout, Size}; use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; -use rustc_session::RemapFileNameExt; -use rustc_session::config::RemapPathScopeComponents; -use rustc_span::{DUMMY_SP, Span, Symbol}; +use rustc_span::{DUMMY_SP, RemapPathScopeComponents, Span, Symbol}; use rustc_type_ir::TypeVisitableExt; use super::interpret::ReportedErrorInfo; @@ -587,11 +585,7 @@ impl<'tcx> TyCtxt<'tcx> { let caller = self.sess.source_map().lookup_char_pos(topmost.lo()); self.const_caller_location( Symbol::intern( - &caller - .file - .name - .for_scope(self.sess, RemapPathScopeComponents::MACRO) - .to_string_lossy(), + &caller.file.name.display(RemapPathScopeComponents::MACRO).to_string_lossy(), ), caller.line as u32, caller.col_display as u32 + 1, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 798e14c6f378..c4f2917ad9e5 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -16,7 +16,7 @@ use rustc_hir::definitions::{DefKey, DefPathDataName}; use rustc_hir::limit::Limit; use rustc_macros::{Lift, extension}; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; -use rustc_span::{FileNameDisplayPreference, Ident, Symbol, kw, sym}; +use rustc_span::{Ident, RemapPathScopeComponents, Symbol, kw, sym}; use rustc_type_ir::{Upcast as _, elaborate}; use smallvec::SmallVec; @@ -890,7 +890,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { "@{}", // This may end up in stderr diagnostics but it may also be emitted // into MIR. Hence we use the remapped path if available - self.tcx().sess.source_map().span_to_embeddable_string(span) + self.tcx().sess.source_map().span_to_diagnostic_string(span) )?; } else { write!(self, "@")?; @@ -921,7 +921,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { "@{}", // This may end up in stderr diagnostics but it may also be emitted // into MIR. Hence we use the remapped path if available - self.tcx().sess.source_map().span_to_embeddable_string(span) + self.tcx().sess.source_map().span_to_diagnostic_string(span) )?; } else { write!(self, "@")?; @@ -947,10 +947,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { self.print_def_path(did.to_def_id(), args)?; } else { let span = self.tcx().def_span(did); - let preference = if with_forced_trimmed_paths() { - FileNameDisplayPreference::Short + let loc = if with_forced_trimmed_paths() { + self.tcx().sess.source_map().span_to_short_string( + span, + RemapPathScopeComponents::DIAGNOSTICS, + ) } else { - FileNameDisplayPreference::Remapped + self.tcx().sess.source_map().span_to_diagnostic_string(span) }; write!( self, @@ -958,7 +961,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { // This may end up in stderr diagnostics but it may also be // emitted into MIR. Hence we use the remapped path if // available - self.tcx().sess.source_map().span_to_string(span, preference) + loc )?; } } else { @@ -1004,18 +1007,17 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { self.print_def_path(did.to_def_id(), args)?; } else { let span = self.tcx().def_span(did); - let preference = if with_forced_trimmed_paths() { - FileNameDisplayPreference::Short + // This may end up in stderr diagnostics but it may also be emitted + // into MIR. Hence we use the remapped path if available + let loc = if with_forced_trimmed_paths() { + self.tcx().sess.source_map().span_to_short_string( + span, + RemapPathScopeComponents::DIAGNOSTICS, + ) } else { - FileNameDisplayPreference::Remapped + self.tcx().sess.source_map().span_to_diagnostic_string(span) }; - write!( - self, - "@{}", - // This may end up in stderr diagnostics but it may also be emitted - // into MIR. Hence we use the remapped path if available - self.tcx().sess.source_map().span_to_string(span, preference) - )?; + write!(self, "@{loc}")?; } } else { write!(self, "@")?; @@ -2258,7 +2260,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { "", // This may end up in stderr diagnostics but it may also be emitted // into MIR. Hence we use the remapped path if available - self.tcx.sess.source_map().span_to_embeddable_string(span) + self.tcx.sess.source_map().span_to_diagnostic_string(span) )?; self.empty_path = false; diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 0992bee32f32..df8f970e0599 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -129,7 +129,13 @@ pub fn utf8_error( note.clone() }; let contents = String::from_utf8_lossy(contents).to_string(); - let source = sm.new_source_file(PathBuf::from(path).into(), contents); + + // We only emit this error for files in the current session + // so the working directory can only be the current working directory + let filename = FileName::Real( + sm.path_mapping().to_real_filename(sm.working_dir(), PathBuf::from(path).as_path()), + ); + let source = sm.new_source_file(filename, contents); // Avoid out-of-bounds span from lossy UTF-8 conversion. if start as u32 > source.normalized_source_len.0 { diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 9b157cb6c7bf..a46fcd30fef4 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -2,7 +2,7 @@ use std::assert_matches::assert_matches; use std::io::prelude::*; use std::iter::Peekable; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::{Arc, Mutex}; use std::{io, str}; @@ -29,11 +29,15 @@ fn psess() -> ParseSess { ParseSess::new(vec![crate::DEFAULT_LOCALE_RESOURCE]) } +fn filename(sm: &SourceMap, path: &str) -> FileName { + FileName::Real(sm.path_mapping().to_real_filename(sm.working_dir(), PathBuf::from(path))) +} + /// Map string to parser (via tts). fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> { unwrap_or_emit_fatal(new_parser_from_source_str( psess, - PathBuf::from("bogofile").into(), + filename(psess.source_map(), "bogofile"), source_str, StripTokens::Nothing, )) @@ -100,7 +104,7 @@ pub(crate) fn string_to_stream(source_str: String) -> TokenStream { let psess = psess(); unwrap_or_emit_fatal(source_str_to_stream( &psess, - PathBuf::from("bogofile").into(), + filename(psess.source_map(), "bogofile"), source_str, None, )) @@ -194,8 +198,7 @@ fn test_harness( (OutputTheme::Unicode, expected_output_unicode), ] { let (dcx, source_map, output) = create_test_handler(theme); - source_map - .new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned()); + source_map.new_source_file(filename(&source_map, "test.rs"), file_text.to_owned()); let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end); let mut msp = MultiSpan::from_span(primary_span); @@ -2525,7 +2528,7 @@ fn ttdelim_span() { create_default_session_globals_then(|| { let psess = psess(); let expr = parse_expr_from_source_str( - PathBuf::from("foo").into(), + filename(psess.source_map(), "foo"), "foo!( fn main() { body } )".to_string(), &psess, ) @@ -2888,10 +2891,11 @@ fn debug_lookahead() { #[test] fn out_of_line_mod() { create_default_session_globals_then(|| { + let psess = psess(); let item = parse_item_from_source_str( - PathBuf::from("foo").into(), + filename(psess.source_map(), "foo"), "mod foo { struct S; mod this_does_not_exist; }".to_owned(), - &psess(), + &psess, ) .unwrap() .unwrap(); diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 8ed2c2a89266..c02a01c1b823 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -6,9 +6,8 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{CRATE_HIR_ID, ItemId, Node, find_attr}; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_session::RemapFileNameExt; -use rustc_session::config::{CrateType, EntryFnType, RemapPathScopeComponents, sigpipe}; -use rustc_span::{Span, sym}; +use rustc_session::config::{CrateType, EntryFnType, sigpipe}; +use rustc_span::{RemapPathScopeComponents, Span, sym}; use crate::errors::{ExternMain, MultipleRustcMain, NoMainErr}; @@ -115,7 +114,7 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) { let filename = tcx .sess .local_crate_source_file() - .map(|src| src.for_scope(&tcx.sess, RemapPathScopeComponents::DIAGNOSTICS).to_path_buf()) + .map(|src| src.path(RemapPathScopeComponents::DIAGNOSTICS).to_path_buf()) .unwrap_or_else(|| { has_filename = false; Default::default() diff --git a/compiler/rustc_public_bridge/src/context/impls.rs b/compiler/rustc_public_bridge/src/context/impls.rs index 26728a34b84a..56aa22378072 100644 --- a/compiler/rustc_public_bridge/src/context/impls.rs +++ b/compiler/rustc_public_bridge/src/context/impls.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::{ use rustc_middle::{mir, ty}; use rustc_session::cstore::ForeignModule; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use rustc_span::{FileNameDisplayPreference, Span, Symbol}; +use rustc_span::{Span, Symbol}; use rustc_target::callconv::FnAbi; use super::{AllocRangeHelpers, CompilerCtxt, TyHelpers, TypingEnvHelpers}; @@ -324,12 +324,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { /// Return filename from given `Span`, for diagnostic purposes. pub fn get_filename(&self, span: Span) -> String { - self.tcx - .sess - .source_map() - .span_to_filename(span) - .display(FileNameDisplayPreference::Local) - .to_string() + self.tcx.sess.source_map().span_to_filename(span).prefer_local_unconditionally().to_string() } /// Return lines corresponding to this `Span`. diff --git a/compiler/rustc_resolve/src/rustdoc/tests.rs b/compiler/rustc_resolve/src/rustdoc/tests.rs index 9fea6f6807e4..7ad0a5003e4b 100644 --- a/compiler/rustc_resolve/src/rustdoc/tests.rs +++ b/compiler/rustc_resolve/src/rustdoc/tests.rs @@ -2,14 +2,18 @@ use std::path::PathBuf; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::symbol::sym; -use rustc_span::{BytePos, DUMMY_SP, Span}; +use rustc_span::{BytePos, DUMMY_SP, FileName, Span}; use super::{DocFragment, DocFragmentKind, source_span_for_markdown_range_inner}; +fn filename(sm: &SourceMap, path: &str) -> FileName { + FileName::Real(sm.path_mapping().to_real_filename(sm.working_dir(), PathBuf::from(path))) +} + #[test] fn single_backtick() { let sm = SourceMap::new(FilePathMapping::empty()); - sm.new_source_file(PathBuf::from("foo.rs").into(), r#"#[doc = "`"] fn foo() {}"#.to_string()); + sm.new_source_file(filename(&sm, "foo.rs"), r#"#[doc = "`"] fn foo() {}"#.to_string()); let (span, _) = source_span_for_markdown_range_inner( &sm, "`", @@ -32,7 +36,7 @@ fn single_backtick() { fn utf8() { // regression test for https://github.com/rust-lang/rust/issues/141665 let sm = SourceMap::new(FilePathMapping::empty()); - sm.new_source_file(PathBuf::from("foo.rs").into(), r#"#[doc = "⚠"] fn foo() {}"#.to_string()); + sm.new_source_file(filename(&sm, "foo.rs"), r#"#[doc = "⚠"] fn foo() {}"#.to_string()); let (span, _) = source_span_for_markdown_range_inner( &sm, "⚠", diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 0516982aeabb..aebac3880d2f 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -5,7 +5,6 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -bitflags = "2.4.1" getopts = "0.2" rand = "0.9.0" rustc_abi = { path = "../rustc_abi" } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 35d9b77f2ea8..b5b19c64951b 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -24,10 +24,7 @@ use rustc_hashes::Hash64; use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; -use rustc_span::{ - FileName, FileNameDisplayPreference, FileNameEmbeddablePreference, RealFileName, - SourceFileHashAlgorithm, Symbol, sym, -}; +use rustc_span::{FileName, SourceFileHashAlgorithm, Symbol, sym}; use rustc_target::spec::{ FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo, Target, TargetTuple, @@ -1022,9 +1019,15 @@ impl Input { "rust_out" } - pub fn source_name(&self) -> FileName { + pub fn file_name(&self, session: &Session) -> FileName { match *self { - Input::File(ref ifile) => ifile.clone().into(), + Input::File(ref ifile) => FileName::Real( + session + .psess + .source_map() + .path_mapping() + .to_real_filename(session.psess.source_map().working_dir(), ifile.as_path()), + ), Input::Str { ref name, .. } => name.clone(), } } @@ -1312,25 +1315,6 @@ impl OutputFilenames { } } -bitflags::bitflags! { - /// Scopes used to determined if it need to apply to --remap-path-prefix - #[derive(Clone, Copy, PartialEq, Eq, Hash)] - pub struct RemapPathScopeComponents: u8 { - /// Apply remappings to the expansion of std::file!() macro - const MACRO = 1 << 0; - /// Apply remappings to printed compiler diagnostics - const DIAGNOSTICS = 1 << 1; - /// Apply remappings to debug information - const DEBUGINFO = 1 << 3; - /// Apply remappings to coverage information - const COVERAGE = 1 << 4; - - /// An alias for `macro`, `debuginfo` and `coverage`. This ensures all paths in compiled - /// executables, libraries and objects are remapped but not elsewhere. - const OBJECT = Self::MACRO.bits() | Self::DEBUGINFO.bits() | Self::COVERAGE.bits(); - } -} - #[derive(Clone, Debug)] pub struct Sysroot { pub explicit: Option, @@ -1369,21 +1353,7 @@ fn file_path_mapping( remap_path_prefix: Vec<(PathBuf, PathBuf)>, unstable_opts: &UnstableOptions, ) -> FilePathMapping { - FilePathMapping::new( - remap_path_prefix.clone(), - if unstable_opts.remap_path_scope.contains(RemapPathScopeComponents::DIAGNOSTICS) - && !remap_path_prefix.is_empty() - { - FileNameDisplayPreference::Remapped - } else { - FileNameDisplayPreference::Local - }, - if unstable_opts.remap_path_scope.is_all() { - FileNameEmbeddablePreference::RemappedOnly - } else { - FileNameEmbeddablePreference::LocalAndRemapped - }, - ) + FilePathMapping::new(remap_path_prefix.clone(), unstable_opts.remap_path_scope) } impl Default for Options { @@ -3115,8 +3085,8 @@ pub(crate) mod dep_tracking { use rustc_errors::LanguageIdentifier; use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; - use rustc_span::RealFileName; use rustc_span::edition::Edition; + use rustc_span::{RealFileName, RemapPathScopeComponents}; use rustc_target::spec::{ CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple, @@ -3128,9 +3098,9 @@ pub(crate) mod dep_tracking { CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, - OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, - RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, - SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, + OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, + SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, + WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 92dd4a23125c..d7ac39ecc9e8 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -12,7 +12,7 @@ use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; use rustc_macros::{BlobDecodable, Encodable}; use rustc_span::edition::Edition; -use rustc_span::{RealFileName, SourceFileHashAlgorithm}; +use rustc_span::{RemapPathScopeComponents, SourceFileHashAlgorithm}; use rustc_target::spec::{ CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index acc65fc11a2a..14b80099bafe 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,5 +1,5 @@ use std::any::Any; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::str::FromStr; use std::sync::Arc; use std::sync::atomic::AtomicBool; @@ -28,7 +28,7 @@ use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; use rustc_span::edition::Edition; use rustc_span::source_map::{FilePathMapping, SourceMap}; -use rustc_span::{FileNameDisplayPreference, RealFileName, Span, Symbol}; +use rustc_span::{RealFileName, Span, Symbol}; use rustc_target::asm::InlineAsmArch; use rustc_target::spec::{ Arch, CodeModel, DebuginfoKind, Os, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, @@ -40,8 +40,7 @@ use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::{ self, CoverageLevel, CoverageOptions, CrateType, DebugInfo, ErrorOutputType, FunctionReturn, - Input, InstrumentCoverage, OptLevel, OutFileName, OutputType, RemapPathScopeComponents, - SwitchWithOptPath, + Input, InstrumentCoverage, OptLevel, OutFileName, OutputType, SwitchWithOptPath, }; use crate::filesearch::FileSearch; use crate::lint::LintId; @@ -192,7 +191,11 @@ impl Session { } pub fn local_crate_source_file(&self) -> Option { - Some(self.source_map().path_mapping().to_real_filename(self.io.input.opt_path()?)) + Some( + self.source_map() + .path_mapping() + .to_real_filename(self.source_map().working_dir(), self.io.input.opt_path()?), + ) } fn check_miri_unleashed_features(&self) -> Option { @@ -846,21 +849,6 @@ impl Session { self.opts.cg.link_dead_code.unwrap_or(false) } - pub fn filename_display_preference( - &self, - scope: RemapPathScopeComponents, - ) -> FileNameDisplayPreference { - assert!( - scope.bits().count_ones() == 1, - "one and only one scope should be passed to `Session::filename_display_preference`" - ); - if self.opts.unstable_opts.remap_path_scope.contains(scope) { - FileNameDisplayPreference::Remapped - } else { - FileNameDisplayPreference::Local - } - } - /// Get the deployment target on Apple platforms based on the standard environment variables, /// or fall back to the minimum version supported by `rustc`. /// @@ -1496,46 +1484,3 @@ fn mk_emitter(output: ErrorOutputType) -> Box { }; emitter } - -pub trait RemapFileNameExt { - type Output<'a> - where - Self: 'a; - - /// Returns a possibly remapped filename based on the passed scope and remap cli options. - /// - /// One and only one scope should be passed to this method, it will panic otherwise. - fn for_scope(&self, sess: &Session, scope: RemapPathScopeComponents) -> Self::Output<'_>; -} - -impl RemapFileNameExt for rustc_span::FileName { - type Output<'a> = rustc_span::FileNameDisplay<'a>; - - fn for_scope(&self, sess: &Session, scope: RemapPathScopeComponents) -> Self::Output<'_> { - assert!( - scope.bits().count_ones() == 1, - "one and only one scope should be passed to for_scope" - ); - if sess.opts.unstable_opts.remap_path_scope.contains(scope) { - self.prefer_remapped_unconditionally() - } else { - self.prefer_local() - } - } -} - -impl RemapFileNameExt for rustc_span::RealFileName { - type Output<'a> = &'a Path; - - fn for_scope(&self, sess: &Session, scope: RemapPathScopeComponents) -> Self::Output<'_> { - assert!( - scope.bits().count_ones() == 1, - "one and only one scope should be passed to for_scope" - ); - if sess.opts.unstable_opts.remap_path_scope.contains(scope) { - self.remapped_path_if_available() - } else { - self.local_path_if_available() - } - } -} diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index 43a2d692577e..bf0cad63e543 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start +bitflags = "2.4.1" blake3 = "1.5.2" derive-where = "1.2.7" indexmap = { version = "2.0.0" } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 6a359c5f4656..49b2e0c1ff1a 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -221,99 +221,227 @@ pub fn with_metavar_spans(f: impl FnOnce(&MetavarSpansMap) -> R) -> R { with_session_globals(|session_globals| f(&session_globals.metavar_spans)) } -// FIXME: We should use this enum or something like it to get rid of the -// use of magic `/rust/1.x/...` paths across the board. +bitflags::bitflags! { + /// Scopes used to determined if it need to apply to `--remap-path-prefix` + #[derive(Debug, Eq, PartialEq, Clone, Copy, Ord, PartialOrd, Hash)] + pub struct RemapPathScopeComponents: u8 { + /// Apply remappings to the expansion of `std::file!()` macro + const MACRO = 1 << 0; + /// Apply remappings to printed compiler diagnostics + const DIAGNOSTICS = 1 << 1; + /// Apply remappings to debug information + const DEBUGINFO = 1 << 3; + /// Apply remappings to coverage information + const COVERAGE = 1 << 4; + + /// An alias for `macro`, `debuginfo` and `coverage`. This ensures all paths in compiled + /// executables, libraries and objects are remapped but not elsewhere. + const OBJECT = Self::MACRO.bits() | Self::DEBUGINFO.bits() | Self::COVERAGE.bits(); + } +} + +impl Encodable for RemapPathScopeComponents { + fn encode(&self, s: &mut E) { + s.emit_u8(self.bits()); + } +} + +impl Decodable for RemapPathScopeComponents { + fn decode(s: &mut D) -> RemapPathScopeComponents { + RemapPathScopeComponents::from_bits(s.read_u8()) + .expect("invalid bits for RemapPathScopeComponents") + } +} + +/// A self-contained "real" filename. +/// +/// It is produced by `SourceMap::to_real_filename`. +/// +/// `RealFileName` represents a filename that may have been (partly) remapped +/// by `--remap-path-prefix` and `-Zremap-path-scope`. +/// +/// It also contains an embedabble component which gives a working directory +/// and a maybe-remapped maybe-aboslote name. This is useful for debuginfo where +/// some formats and tools highly prefer absolute paths. +/// +/// ## Consistency across compiler sessions +/// +/// The type-system, const-eval and other parts of the compiler rely on `FileName` +/// and by extension `RealFileName` to be consistent across compiler sessions. +/// +/// Otherwise unsoudness (like rust-lang/rust#148328) may occur. +/// +/// As such this type is self-sufficient and consistent in it's output. +/// +/// The [`RealFileName::path`] and [`RealFileName::embeddable_name`] methods +/// are guaranteed to always return the same output across compiler sessions. +/// +/// ## Usage +/// +/// Creation of a [`RealFileName`] should be done using +/// [`FilePathMapping::to_real_filename`][rustc_span::source_map::FilePathMapping::to_real_filename]. +/// +/// Retrieving a path can be done in two main ways: +/// - by using [`RealFileName::path`] with a given scope (should be preferred) +/// - or by using [`RealFileName::embeddable_name`] with a given scope #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable, Encodable)] -pub enum RealFileName { - LocalPath(PathBuf), - /// For remapped paths (namely paths into libstd that have been mapped - /// to the appropriate spot on the local host's file system, and local file - /// system paths that have been remapped with `FilePathMapping`), - Remapped { - /// `local_path` is the (host-dependent) local path to the file. This is - /// None if the file was imported from another crate - local_path: Option, - /// `virtual_name` is the stable path rustc will store internally within - /// build artifacts. - virtual_name: PathBuf, - }, +pub struct RealFileName { + /// The local name (always present in the original crate) + local: Option, + /// The maybe remapped part. Correspond to `local` when no remapped happened. + maybe_remapped: InnerRealFileName, + /// The remapped scopes. Any active scope MUST use `maybe_virtual` + scopes: RemapPathScopeComponents, +} + +/// The inner workings of `RealFileName`. +/// +/// It contains the `name`, `working_directory` and `embeddable_name` components. +#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable, Encodable, Hash)] +struct InnerRealFileName { + /// The name. + name: PathBuf, + /// The working directory associated with the embeddable name. + working_directory: PathBuf, + /// The embeddable name. + embeddable_name: PathBuf, } impl Hash for RealFileName { fn hash(&self, state: &mut H) { // To prevent #70924 from happening again we should only hash the - // remapped (virtualized) path if that exists. This is because - // virtualized paths to sysroot crates (/rust/$hash or /rust/$version) - // remain stable even if the corresponding local_path changes - self.remapped_path_if_available().hash(state) + // remapped path if that exists. This is because remapped paths to + // sysroot crates (/rust/$hash or /rust/$version) remain stable even + // if the corresponding local path changes. + if !self.scopes.is_all() { + self.local.hash(state); + } + self.maybe_remapped.hash(state); + self.scopes.bits().hash(state); } } impl RealFileName { - /// Returns the path suitable for reading from the file system on the local host, - /// if this information exists. - /// Avoid embedding this in build artifacts; see `remapped_path_if_available()` for that. - pub fn local_path(&self) -> Option<&Path> { - match self { - RealFileName::LocalPath(p) => Some(p), - RealFileName::Remapped { local_path, virtual_name: _ } => local_path.as_deref(), - } - } - - /// Returns the path suitable for reading from the file system on the local host, - /// if this information exists. - /// Avoid embedding this in build artifacts; see `remapped_path_if_available()` for that. - pub fn into_local_path(self) -> Option { - match self { - RealFileName::LocalPath(p) => Some(p), - RealFileName::Remapped { local_path: p, virtual_name: _ } => p, - } - } - - /// Returns the path suitable for embedding into build artifacts. This would still - /// be a local path if it has not been remapped. A remapped path will not correspond - /// to a valid file system path: see `local_path_if_available()` for something that - /// is more likely to return paths into the local host file system. - pub fn remapped_path_if_available(&self) -> &Path { - match self { - RealFileName::LocalPath(p) - | RealFileName::Remapped { local_path: _, virtual_name: p } => p, - } - } - - /// Returns the path suitable for reading from the file system on the local host, - /// if this information exists. Otherwise returns the remapped name. - /// Avoid embedding this in build artifacts; see `remapped_path_if_available()` for that. - pub fn local_path_if_available(&self) -> &Path { - match self { - RealFileName::LocalPath(path) - | RealFileName::Remapped { local_path: None, virtual_name: path } - | RealFileName::Remapped { local_path: Some(path), virtual_name: _ } => path, - } - } - - /// Return the path remapped or not depending on the [`FileNameDisplayPreference`]. + /// Returns the associated path for the given remapping scope. /// - /// For the purpose of this function, local and short preference are equal. - pub fn to_path(&self, display_pref: FileNameDisplayPreference) -> &Path { - match display_pref { - FileNameDisplayPreference::Local | FileNameDisplayPreference::Short => { - self.local_path_if_available() - } - FileNameDisplayPreference::Remapped => self.remapped_path_if_available(), + /// ## Panic + /// + /// Only one scope components can be given to this function. + pub fn path(&self, scope: RemapPathScopeComponents) -> &Path { + assert!( + scope.bits().count_ones() == 1, + "one and only one scope should be passed to `RealFileName::path`: {scope:?}" + ); + if !self.scopes.contains(scope) + && let Some(local_name) = &self.local + { + local_name.name.as_path() + } else { + self.maybe_remapped.name.as_path() } } - pub fn to_string_lossy(&self, display_pref: FileNameDisplayPreference) -> Cow<'_, str> { + /// Returns the working directory and embeddable path for the given remapping scope. + /// + /// Useful for embedding a mostly abosolute path (modulo remapping) in the compiler outputs. + /// + /// The embedabble path is not guaranteed to be an absolute path, nor is it garuenteed + /// that the working directory part is always a prefix of embeddable path. + /// + /// ## Panic + /// + /// Only one scope components can be given to this function. + pub fn embeddable_name(&self, scope: RemapPathScopeComponents) -> (&Path, &Path) { + assert!( + scope.bits().count_ones() == 1, + "one and only one scope should be passed to `RealFileName::embeddable_path`: {scope:?}" + ); + if !self.scopes.contains(scope) + && let Some(local_name) = &self.local + { + (&local_name.working_directory, &local_name.embeddable_name) + } else { + (&self.maybe_remapped.working_directory, &self.maybe_remapped.embeddable_name) + } + } + + /// Returns the path suitable for reading from the file system on the local host, + /// if this information exists. + /// + /// May not exists if the filename was imported from another crate. + pub fn local_path(&self) -> Option<&Path> { + self.local.as_ref().map(|lp| lp.name.as_ref()) + } + + /// Returns the path suitable for reading from the file system on the local host, + /// if this information exists. + /// + /// May not exists if the filename was imported from another crate. + pub fn into_local_path(self) -> Option { + self.local.map(|lp| lp.name) + } + + /// Returns whenever the filename was remapped. + pub(crate) fn was_remapped(&self) -> bool { + !self.scopes.is_empty() + } + + /// Returns an empty `RealFileName` + /// + /// Useful as the working directory input to `SourceMap::to_real_filename`. + pub fn empty() -> RealFileName { + RealFileName { + local: Some(InnerRealFileName { + name: PathBuf::new(), + working_directory: PathBuf::new(), + embeddable_name: PathBuf::new(), + }), + maybe_remapped: InnerRealFileName { + name: PathBuf::new(), + working_directory: PathBuf::new(), + embeddable_name: PathBuf::new(), + }, + scopes: RemapPathScopeComponents::empty(), + } + } + + /// Returns a `RealFileName` that is completely remapped without any local components. + /// + /// Only exposed for the purpose of `-Zsimulate-remapped-rust-src-base`. + pub fn from_virtual_path(path: &Path) -> RealFileName { + let name = InnerRealFileName { + name: path.to_owned(), + embeddable_name: path.to_owned(), + working_directory: PathBuf::new(), + }; + RealFileName { local: None, maybe_remapped: name, scopes: RemapPathScopeComponents::all() } + } + + /// Update the filename for encoding in the crate metadata. + /// + /// Currently it's about removing the local part when the filename + /// is fully remapped. + pub fn update_for_crate_metadata(&mut self) { + if self.scopes.is_all() { + self.local = None; + } + } + + /// Internal routine to display the filename. + /// + /// Users should always use the `RealFileName::path` method or `FileName` methods instead. + fn to_string_lossy<'a>(&'a self, display_pref: FileNameDisplayPreference) -> Cow<'a, str> { match display_pref { - FileNameDisplayPreference::Local => self.local_path_if_available().to_string_lossy(), - FileNameDisplayPreference::Remapped => { - self.remapped_path_if_available().to_string_lossy() + FileNameDisplayPreference::Remapped => self.maybe_remapped.name.to_string_lossy(), + FileNameDisplayPreference::Local => { + self.local.as_ref().unwrap_or(&self.maybe_remapped).name.to_string_lossy() } FileNameDisplayPreference::Short => self - .local_path_if_available() + .maybe_remapped + .name .file_name() .map_or_else(|| "".into(), |f| f.to_string_lossy()), + FileNameDisplayPreference::Scope(scope) => self.path(scope).to_string_lossy(), } } } @@ -339,40 +467,20 @@ pub enum FileName { InlineAsm(Hash64), } -impl From for FileName { - fn from(p: PathBuf) -> Self { - FileName::Real(RealFileName::LocalPath(p)) - } -} - -#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] -pub enum FileNameEmbeddablePreference { - /// If a remapped path is available, only embed the `virtual_path` and omit the `local_path`. - /// - /// Otherwise embed the local-path into the `virtual_path`. - RemappedOnly, - /// Embed the original path as well as its remapped `virtual_path` component if available. - LocalAndRemapped, -} - -#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] -pub enum FileNameDisplayPreference { - /// Display the path after the application of rewrite rules provided via `--remap-path-prefix`. - /// This is appropriate for paths that get embedded into files produced by the compiler. - Remapped, - /// Display the path before the application of rewrite rules provided via `--remap-path-prefix`. - /// This is appropriate for use in user-facing output (such as diagnostics). - Local, - /// Display only the filename, as a way to reduce the verbosity of the output. - /// This is appropriate for use in user-facing output (such as diagnostics). - Short, -} - pub struct FileNameDisplay<'a> { inner: &'a FileName, display_pref: FileNameDisplayPreference, } +// Internal enum. Should not be exposed. +#[derive(Clone, Copy)] +enum FileNameDisplayPreference { + Remapped, + Local, + Short, + Scope(RemapPathScopeComponents), +} + impl fmt::Display for FileNameDisplay<'_> { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use FileName::*; @@ -417,18 +525,30 @@ impl FileName { } } + /// Returns the path suitable for reading from the file system on the local host, + /// if this information exists. + /// + /// Avoid embedding this in build artifacts. Prefer using the `display` method. pub fn prefer_remapped_unconditionally(&self) -> FileNameDisplay<'_> { FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Remapped } } - /// This may include transient local filesystem information. - /// Must not be embedded in build outputs. - pub fn prefer_local(&self) -> FileNameDisplay<'_> { + /// Returns the path suitable for reading from the file system on the local host, + /// if this information exists. + /// + /// Avoid embedding this in build artifacts. Prefer using the `display` method. + pub fn prefer_local_unconditionally(&self) -> FileNameDisplay<'_> { FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Local } } - pub fn display(&self, display_pref: FileNameDisplayPreference) -> FileNameDisplay<'_> { - FileNameDisplay { inner: self, display_pref } + /// Returns a short (either the filename or an empty string). + pub fn short(&self) -> FileNameDisplay<'_> { + FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Short } + } + + /// Returns a `Display`-able path for the given scope. + pub fn display(&self, scope: RemapPathScopeComponents) -> FileNameDisplay<'_> { + FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Scope(scope) } } pub fn macro_expansion_source_code(src: &str) -> FileName { @@ -473,7 +593,8 @@ impl FileName { /// Returns the path suitable for reading from the file system on the local host, /// if this information exists. - /// Avoid embedding this in build artifacts; see `remapped_path_if_available()` for that. + /// + /// Avoid embedding this in build artifacts. pub fn into_local_path(self) -> Option { match self { FileName::Real(path) => path.into_local_path(), diff --git a/compiler/rustc_span/src/profiling.rs b/compiler/rustc_span/src/profiling.rs index c5a8bd3b15be..ab47e441cc35 100644 --- a/compiler/rustc_span/src/profiling.rs +++ b/compiler/rustc_span/src/profiling.rs @@ -2,6 +2,7 @@ use std::borrow::Borrow; use rustc_data_structures::profiling::EventArgRecorder; +use crate::RemapPathScopeComponents; use crate::source_map::SourceMap; /// Extension trait for self-profiling purposes: allows to record spans within a generic activity's @@ -24,6 +25,6 @@ impl SpannedEventArgRecorder for EventArgRecorder<'_> { A: Borrow + Into, { self.record_arg(event_arg); - self.record_arg(source_map.span_to_embeddable_string(span)); + self.record_arg(source_map.span_to_string(span, RemapPathScopeComponents::DEBUGINFO)); } } diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 090442bf64bd..35694be9e492 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -234,7 +234,7 @@ impl SourceMap { let cwd = file_loader .current_directory() .expect("expecting a current working directory to exist"); - let working_dir = cwd.to_path_buf().into(); + let working_dir = path_mapping.to_real_filename(&RealFileName::empty(), &cwd); debug!(?working_dir); SourceMap { files: Default::default(), @@ -260,7 +260,7 @@ impl SourceMap { pub fn load_file(&self, path: &Path) -> io::Result> { let src = self.file_loader.read_file(path)?; - let filename = path.to_owned().into(); + let filename = FileName::Real(self.path_mapping.to_real_filename(&self.working_dir, path)); Ok(self.new_source_file(filename, src)) } @@ -277,7 +277,8 @@ impl SourceMap { // via `mod`, so we try to use real file contents and not just an // empty string. let text = std::str::from_utf8(&bytes).unwrap_or("").to_string(); - let file = self.new_source_file(path.to_owned().into(), text); + let filename = FileName::Real(self.path_mapping.to_real_filename(&self.working_dir, path)); + let file = self.new_source_file(filename, text); Ok(( bytes, Span::new( @@ -345,7 +346,6 @@ impl SourceMap { // Note that filename may not be a valid path, eg it may be `` etc, // but this is okay because the directory determined by `path.pop()` will // be empty, so the working directory will be used. - let (filename, _) = self.path_mapping.map_filename_prefix(&filename); let stable_id = StableSourceFileId::from_filename_in_current_crate(&filename); match self.source_file_by_stable_id(stable_id) { @@ -444,25 +444,36 @@ impl SourceMap { } } - pub fn span_to_string( + pub fn span_to_string(&self, sp: Span, display_scope: RemapPathScopeComponents) -> String { + self.span_to_string_ext(sp, display_scope, false) + } + + pub fn span_to_short_string( &self, sp: Span, - filename_display_pref: FileNameDisplayPreference, + display_scope: RemapPathScopeComponents, + ) -> String { + self.span_to_string_ext(sp, display_scope, true) + } + + fn span_to_string_ext( + &self, + sp: Span, + display_scope: RemapPathScopeComponents, + short: bool, ) -> String { let (source_file, lo_line, lo_col, hi_line, hi_col) = self.span_to_location_info(sp); let file_name = match source_file { - Some(sf) => sf.name.display(filename_display_pref).to_string(), + Some(sf) => { + if short { sf.name.short() } else { sf.name.display(display_scope) }.to_string() + } None => return "no-location".to_string(), }; format!( "{file_name}:{lo_line}:{lo_col}{}", - if let FileNameDisplayPreference::Short = filename_display_pref { - String::new() - } else { - format!(": {hi_line}:{hi_col}") - } + if short { String::new() } else { format!(": {hi_line}:{hi_col}") } ) } @@ -479,16 +490,11 @@ impl SourceMap { (Some(lo.file), lo.line, lo.col.to_usize() + 1, hi.line, hi.col.to_usize() + 1) } - /// Format the span location suitable for embedding in build artifacts - pub fn span_to_embeddable_string(&self, sp: Span) -> String { - self.span_to_string(sp, FileNameDisplayPreference::Remapped) - } - /// Format the span location to be printed in diagnostics. Must not be emitted /// to build artifacts as this may leak local file paths. Use span_to_embeddable_string /// for string suitable for embedding. pub fn span_to_diagnostic_string(&self, sp: Span) -> String { - self.span_to_string(sp, self.path_mapping.filename_display_for_diagnostics) + self.span_to_string(sp, RemapPathScopeComponents::DIAGNOSTICS) } pub fn span_to_filename(&self, sp: Span) -> FileName { @@ -496,7 +502,7 @@ impl SourceMap { } pub fn filename_for_diagnostics<'a>(&self, filename: &'a FileName) -> FileNameDisplay<'a> { - filename.display(self.path_mapping.filename_display_for_diagnostics) + filename.display(RemapPathScopeComponents::DIAGNOSTICS) } pub fn is_multiline(&self, sp: Span) -> bool { @@ -1045,10 +1051,8 @@ impl SourceMap { } pub fn get_source_file(&self, filename: &FileName) -> Option> { - // Remap filename before lookup - let filename = self.path_mapping().map_filename_prefix(filename).0; for sf in self.files.borrow().source_files.iter() { - if filename == sf.name { + if *filename == sf.name { return Some(Arc::clone(&sf)); } } @@ -1080,16 +1084,20 @@ impl SourceMap { return None; }; - let local_path: Cow<'_, Path> = match name { - RealFileName::LocalPath(local_path) => local_path.into(), - RealFileName::Remapped { local_path: Some(local_path), .. } => local_path.into(), - RealFileName::Remapped { local_path: None, virtual_name } => { + let local_path: Cow<'_, Path> = match name.local_path() { + Some(local) => local.into(), + None => { // The compiler produces better error messages if the sources of dependencies // are available. Attempt to undo any path mapping so we can find remapped // dependencies. + // // We can only use the heuristic because `add_external_src` checks the file // content hash. - self.path_mapping.reverse_map_prefix_heuristically(virtual_name)?.into() + let maybe_remapped_path = name.path(RemapPathScopeComponents::DIAGNOSTICS); + self.path_mapping + .reverse_map_prefix_heuristically(maybe_remapped_path) + .map(Cow::from) + .unwrap_or(maybe_remapped_path.into()) } }; @@ -1135,35 +1143,25 @@ pub fn get_source_map() -> Option> { #[derive(Clone)] pub struct FilePathMapping { mapping: Vec<(PathBuf, PathBuf)>, - filename_display_for_diagnostics: FileNameDisplayPreference, - filename_embeddable_preference: FileNameEmbeddablePreference, + filename_remapping_scopes: RemapPathScopeComponents, } impl FilePathMapping { pub fn empty() -> FilePathMapping { - FilePathMapping::new( - Vec::new(), - FileNameDisplayPreference::Local, - FileNameEmbeddablePreference::RemappedOnly, - ) + FilePathMapping::new(Vec::new(), RemapPathScopeComponents::empty()) } pub fn new( mapping: Vec<(PathBuf, PathBuf)>, - filename_display_for_diagnostics: FileNameDisplayPreference, - filename_embeddable_preference: FileNameEmbeddablePreference, + filename_remapping_scopes: RemapPathScopeComponents, ) -> FilePathMapping { - FilePathMapping { - mapping, - filename_display_for_diagnostics, - filename_embeddable_preference, - } + FilePathMapping { mapping, filename_remapping_scopes } } /// Applies any path prefix substitution as defined by the mapping. /// The return value is the remapped path and a boolean indicating whether /// the path was affected by the mapping. - pub fn map_prefix<'a>(&'a self, path: impl Into>) -> (Cow<'a, Path>, bool) { + fn map_prefix<'a>(&'a self, path: impl Into>) -> (Cow<'a, Path>, bool) { let path = path.into(); if path.as_os_str().is_empty() { // Exit early if the path is empty and therefore there's nothing to remap. @@ -1209,138 +1207,68 @@ impl FilePathMapping { } } - fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) { - match file { - FileName::Real(realfile) if let RealFileName::LocalPath(local_path) = realfile => { - let (mapped_path, mapped) = self.map_prefix(local_path); - let realfile = if mapped { - RealFileName::Remapped { - local_path: Some(local_path.clone()), - virtual_name: mapped_path.into_owned(), - } - } else { - realfile.clone() - }; - (FileName::Real(realfile), mapped) - } - FileName::Real(_) => unreachable!("attempted to remap an already remapped filename"), - other => (other.clone(), false), - } - } - /// Applies any path prefix substitution as defined by the mapping. - /// The return value is the local path with a "virtual path" representing the remapped - /// part if any remapping was performed. - pub fn to_real_filename<'a>(&self, local_path: impl Into>) -> RealFileName { - let local_path = local_path.into(); - if let (remapped_path, true) = self.map_prefix(&*local_path) { - RealFileName::Remapped { - virtual_name: remapped_path.into_owned(), - local_path: Some(local_path.into_owned()), - } - } else { - RealFileName::LocalPath(local_path.into_owned()) - } - } - - /// Expand a relative path to an absolute path with remapping taken into account. - /// Use this when absolute paths are required (e.g. debuginfo or crate metadata). /// - /// The resulting `RealFileName` will have its `local_path` portion erased if - /// possible (i.e. if there's also a remapped path). - pub fn to_embeddable_absolute_path( + /// The returned filename contains the a remapped path representing the remapped + /// part if any remapping was performed. + pub fn to_real_filename<'a>( &self, - file_path: RealFileName, working_directory: &RealFileName, + local_path: impl Into>, ) -> RealFileName { - match file_path { - // Anything that's already remapped we don't modify, except for erasing - // the `local_path` portion (if desired). - RealFileName::Remapped { local_path, virtual_name } => { - RealFileName::Remapped { - local_path: match self.filename_embeddable_preference { - FileNameEmbeddablePreference::RemappedOnly => None, - FileNameEmbeddablePreference::LocalAndRemapped => local_path, - }, - // We use the remapped name verbatim, even if it looks like a relative - // path. The assumption is that the user doesn't want us to further - // process paths that have gone through remapping. - virtual_name, - } - } + let local_path = local_path.into(); - RealFileName::LocalPath(unmapped_file_path) => { - // If no remapping has been applied yet, try to do so - let (new_path, was_remapped) = self.map_prefix(&unmapped_file_path); - if was_remapped { - // It was remapped, so don't modify further - return RealFileName::Remapped { - virtual_name: new_path.into_owned(), - // But still provide the local path if desired - local_path: match self.filename_embeddable_preference { - FileNameEmbeddablePreference::RemappedOnly => None, - FileNameEmbeddablePreference::LocalAndRemapped => { - Some(unmapped_file_path) - } - }, - }; - } + let (remapped_path, mut was_remapped) = self.map_prefix(&*local_path); + debug!(?local_path, ?remapped_path, ?was_remapped, ?self.filename_remapping_scopes); - if new_path.is_absolute() { - // No remapping has applied to this path and it is absolute, - // so the working directory cannot influence it either, so - // we are done. - return RealFileName::LocalPath(new_path.into_owned()); - } + // Always populate the local part, even if we just remapped it and the scopes are + // total, so that places that load the file from disk still have access to it. + let local = InnerRealFileName { + name: local_path.to_path_buf(), + working_directory: working_directory + .local_path() + .expect("working directory should be local") + .to_path_buf(), + embeddable_name: if local_path.is_absolute() { + local_path.to_path_buf() + } else { + working_directory + .local_path() + .expect("working directory should be local") + .to_path_buf() + .join(&local_path) + }, + }; - debug_assert!(new_path.is_relative()); - let unmapped_file_path_rel = new_path; + RealFileName { + maybe_remapped: InnerRealFileName { + working_directory: working_directory.maybe_remapped.name.clone(), + embeddable_name: if remapped_path.is_absolute() || was_remapped { + // The current directory may have been remapped so we take that + // into account, otherwise we'll forget to include the scopes + was_remapped = was_remapped || working_directory.was_remapped(); - match working_directory { - RealFileName::LocalPath(unmapped_working_dir_abs) => { - let unmapped_file_path_abs = - unmapped_working_dir_abs.join(unmapped_file_path_rel); + remapped_path.to_path_buf() + } else { + // Create an absolute path and remap it as well. + let (abs_path, abs_was_remapped) = self.map_prefix( + working_directory.maybe_remapped.name.clone().join(&remapped_path), + ); - // Although neither `working_directory` nor the file name were subject - // to path remapping, the concatenation between the two may be. Hence - // we need to do a remapping here. - let (file_path_abs, was_remapped) = - self.map_prefix(&unmapped_file_path_abs); - if was_remapped { - RealFileName::Remapped { - virtual_name: file_path_abs.into_owned(), - local_path: match self.filename_embeddable_preference { - FileNameEmbeddablePreference::RemappedOnly => None, - FileNameEmbeddablePreference::LocalAndRemapped => { - Some(unmapped_file_path_abs) - } - }, - } - } else { - // No kind of remapping applied to this path, so - // we leave it as it is. - RealFileName::LocalPath(file_path_abs.into_owned()) - } - } - RealFileName::Remapped { - local_path, - virtual_name: remapped_working_dir_abs, - } => { - // If working_directory has been remapped, then we emit - // Remapped variant as the expanded path won't be valid - RealFileName::Remapped { - virtual_name: Path::new(remapped_working_dir_abs) - .join(&unmapped_file_path_rel), - local_path: match self.filename_embeddable_preference { - FileNameEmbeddablePreference::RemappedOnly => None, - FileNameEmbeddablePreference::LocalAndRemapped => local_path - .as_ref() - .map(|local_path| local_path.join(unmapped_file_path_rel)), - }, - } - } - } - } + // If either the embeddable name or the working directory was + // remapped, then the filename was remapped + was_remapped = abs_was_remapped || working_directory.was_remapped(); + + abs_path.to_path_buf() + }, + name: remapped_path.to_path_buf(), + }, + local: Some(local), + scopes: if was_remapped { + self.filename_remapping_scopes + } else { + RemapPathScopeComponents::empty() + }, } } diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index c919aacf6b5f..16d28f393d7f 100644 --- a/compiler/rustc_span/src/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs @@ -1,10 +1,14 @@ use super::*; +fn filename(sm: &SourceMap, path: &str) -> FileName { + FileName::Real(sm.path_mapping().to_real_filename(sm.working_dir(), PathBuf::from(path))) +} + fn init_source_map() -> SourceMap { let sm = SourceMap::new(FilePathMapping::empty()); - sm.new_source_file(PathBuf::from("blork.rs").into(), "first line.\nsecond line".to_string()); - sm.new_source_file(PathBuf::from("empty.rs").into(), String::new()); - sm.new_source_file(PathBuf::from("blork2.rs").into(), "first line.\nsecond line".to_string()); + sm.new_source_file(filename(&sm, "blork.rs"), "first line.\nsecond line".to_string()); + sm.new_source_file(filename(&sm, "empty.rs"), String::new()); + sm.new_source_file(filename(&sm, "blork2.rs"), "first line.\nsecond line".to_string()); sm } @@ -59,15 +63,15 @@ fn t3() { let sm = init_source_map(); let srcfbp1 = sm.lookup_byte_offset(BytePos(23)); - assert_eq!(srcfbp1.sf.name, PathBuf::from("blork.rs").into()); + assert_eq!(srcfbp1.sf.name, filename(&sm, "blork.rs")); assert_eq!(srcfbp1.pos, BytePos(23)); let srcfbp1 = sm.lookup_byte_offset(BytePos(24)); - assert_eq!(srcfbp1.sf.name, PathBuf::from("empty.rs").into()); + assert_eq!(srcfbp1.sf.name, filename(&sm, "empty.rs")); assert_eq!(srcfbp1.pos, BytePos(0)); let srcfbp2 = sm.lookup_byte_offset(BytePos(25)); - assert_eq!(srcfbp2.sf.name, PathBuf::from("blork2.rs").into()); + assert_eq!(srcfbp2.sf.name, filename(&sm, "blork2.rs")); assert_eq!(srcfbp2.pos, BytePos(0)); } @@ -89,12 +93,12 @@ fn t5() { let sm = init_source_map(); let loc1 = sm.lookup_char_pos(BytePos(22)); - assert_eq!(loc1.file.name, PathBuf::from("blork.rs").into()); + assert_eq!(loc1.file.name, filename(&sm, "blork.rs")); assert_eq!(loc1.line, 2); assert_eq!(loc1.col, CharPos(10)); let loc2 = sm.lookup_char_pos(BytePos(25)); - assert_eq!(loc2.file.name, PathBuf::from("blork2.rs").into()); + assert_eq!(loc2.file.name, filename(&sm, "blork2.rs")); assert_eq!(loc2.line, 1); assert_eq!(loc2.col, CharPos(0)); } @@ -102,14 +106,8 @@ fn t5() { fn init_source_map_mbc() -> SourceMap { let sm = SourceMap::new(FilePathMapping::empty()); // "€" is a three-byte UTF8 char. - sm.new_source_file( - PathBuf::from("blork.rs").into(), - "fir€st €€€€ line.\nsecond line".to_string(), - ); - sm.new_source_file( - PathBuf::from("blork2.rs").into(), - "first line€€.\n€ second line".to_string(), - ); + sm.new_source_file(filename(&sm, "blork.rs"), "fir€st €€€€ line.\nsecond line".to_string()); + sm.new_source_file(filename(&sm, "blork2.rs"), "first line€€.\n€ second line".to_string()); sm } @@ -138,7 +136,7 @@ fn t7() { let span = Span::with_root_ctxt(BytePos(12), BytePos(23)); let file_lines = sm.span_to_lines(span).unwrap(); - assert_eq!(file_lines.file.name, PathBuf::from("blork.rs").into()); + assert_eq!(file_lines.file.name, filename(&sm, "blork.rs")); assert_eq!(file_lines.lines.len(), 1); assert_eq!(file_lines.lines[0].line_index, 1); } @@ -161,7 +159,7 @@ fn span_to_snippet_and_lines_spanning_multiple_lines() { let sm = SourceMap::new(FilePathMapping::empty()); let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n"; let selection = " \n ~~\n~~~\n~~~~~ \n \n"; - sm.new_source_file(Path::new("blork.rs").to_owned().into(), inputtext.to_string()); + sm.new_source_file(filename(&sm, "blork.rs"), inputtext.to_string()); let span = span_from_selection(inputtext, selection); // Check that we are extracting the text we thought we were extracting. @@ -204,7 +202,7 @@ fn span_merging_fail() { let inputtext = "bbbb BB\ncc CCC\n"; let selection1 = " ~~\n \n"; let selection2 = " \n ~~~\n"; - sm.new_source_file(Path::new("blork.rs").to_owned().into(), inputtext.to_owned()); + sm.new_source_file(filename(&sm, "blork.rs"), inputtext.to_owned()); let span1 = span_from_selection(inputtext, selection1); let span2 = span_from_selection(inputtext, selection2); @@ -218,7 +216,7 @@ fn t10() { let unnormalized = "first line.\r\nsecond line"; let normalized = "first line.\nsecond line"; - let src_file = sm.new_source_file(PathBuf::from("blork.rs").into(), unnormalized.to_string()); + let src_file = sm.new_source_file(filename(&sm, "blork.rs"), unnormalized.to_string()); assert_eq!(src_file.src.as_ref().unwrap().as_ref(), normalized); assert!( @@ -306,8 +304,7 @@ fn path_prefix_remapping() { { let mapping = &FilePathMapping::new( vec![(path("abc/def"), path("foo"))], - FileNameDisplayPreference::Remapped, - FileNameEmbeddablePreference::RemappedOnly, + RemapPathScopeComponents::all(), ); assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("foo/src/main.rs")); @@ -318,8 +315,7 @@ fn path_prefix_remapping() { { let mapping = &FilePathMapping::new( vec![(path("abc/def"), path("/foo"))], - FileNameDisplayPreference::Remapped, - FileNameEmbeddablePreference::RemappedOnly, + RemapPathScopeComponents::all(), ); assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("/foo/src/main.rs")); @@ -330,8 +326,7 @@ fn path_prefix_remapping() { { let mapping = &FilePathMapping::new( vec![(path("/abc/def"), path("foo"))], - FileNameDisplayPreference::Remapped, - FileNameEmbeddablePreference::RemappedOnly, + RemapPathScopeComponents::all(), ); assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("foo/src/main.rs")); @@ -342,8 +337,7 @@ fn path_prefix_remapping() { { let mapping = &FilePathMapping::new( vec![(path("/abc/def"), path("/foo"))], - FileNameDisplayPreference::Remapped, - FileNameEmbeddablePreference::RemappedOnly, + RemapPathScopeComponents::all(), ); assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("/foo/src/main.rs")); @@ -352,171 +346,322 @@ fn path_prefix_remapping() { } #[test] -fn path_prefix_remapping_expand_to_absolute() { +fn to_real_filename_with_full_scopes() { // "virtual" working directory is relative path let mapping = &FilePathMapping::new( vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))], - FileNameDisplayPreference::Remapped, - FileNameEmbeddablePreference::RemappedOnly, + RemapPathScopeComponents::all(), ); let working_directory = path("/foo"); - let working_directory = RealFileName::Remapped { - local_path: Some(working_directory.clone()), - virtual_name: mapping.map_prefix(working_directory).0.into_owned(), - }; + let working_directory = mapping.to_real_filename(&RealFileName::empty(), working_directory); - assert_eq!(working_directory.remapped_path_if_available(), path("FOO")); + assert_eq!(working_directory.path(RemapPathScopeComponents::DIAGNOSTICS), path("FOO")); + assert_eq!(working_directory.path(RemapPathScopeComponents::MACRO), path("FOO")); + assert_eq!(working_directory.path(RemapPathScopeComponents::DEBUGINFO), path("FOO")); - // Unmapped absolute path + // Absolute path assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::LocalPath(path("/foo/src/main.rs")), - &working_directory - ), - RealFileName::Remapped { local_path: None, virtual_name: path("FOO/src/main.rs") } - ); - - // Unmapped absolute path with unrelated working directory - assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::LocalPath(path("/bar/src/main.rs")), - &working_directory - ), - RealFileName::Remapped { local_path: None, virtual_name: path("BAR/src/main.rs") } - ); - - // Unmapped absolute path that does not match any prefix - assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::LocalPath(path("/quux/src/main.rs")), - &working_directory - ), - RealFileName::LocalPath(path("/quux/src/main.rs")), - ); - - // Unmapped relative path - assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::LocalPath(path("src/main.rs")), - &working_directory - ), - RealFileName::Remapped { local_path: None, virtual_name: path("FOO/src/main.rs") } - ); - - // Unmapped relative path with `./` - assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::LocalPath(path("./src/main.rs")), - &working_directory - ), - RealFileName::Remapped { local_path: None, virtual_name: path("FOO/src/main.rs") } - ); - - // Unmapped relative path that does not match any prefix - assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::LocalPath(path("quux/src/main.rs")), - &RealFileName::LocalPath(path("/abc")), - ), - RealFileName::LocalPath(path("/abc/quux/src/main.rs")), - ); - - // Already remapped absolute path - assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::Remapped { - local_path: Some(path("/foo/src/main.rs")), - virtual_name: path("FOO/src/main.rs"), + mapping.to_real_filename(&working_directory, path("/foo/src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("/foo/src/main.rs"), + working_directory: path("/foo"), + embeddable_name: path("/foo/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("FOO/src/main.rs"), + working_directory: path("FOO"), + embeddable_name: path("FOO/src/main.rs") }, - &working_directory - ), - RealFileName::Remapped { local_path: None, virtual_name: path("FOO/src/main.rs") } + scopes: RemapPathScopeComponents::all() + } ); - // Already remapped absolute path, with unrelated working directory + // Absolute path with unrelated working directory assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::Remapped { - local_path: Some(path("/bar/src/main.rs")), - virtual_name: path("BAR/src/main.rs"), + mapping.to_real_filename(&working_directory, path("/bar/src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("/bar/src/main.rs"), + working_directory: path("/foo"), + embeddable_name: path("/bar/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("BAR/src/main.rs"), + working_directory: path("FOO"), + embeddable_name: path("BAR/src/main.rs") }, - &working_directory - ), - RealFileName::Remapped { local_path: None, virtual_name: path("BAR/src/main.rs") } + scopes: RemapPathScopeComponents::all() + } ); - // Already remapped relative path + // Absolute path that does not match any prefix assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") }, - &working_directory + mapping.to_real_filename(&working_directory, path("/quux/src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("/quux/src/main.rs"), + working_directory: path("/foo"), + embeddable_name: path("/quux/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("/quux/src/main.rs"), + working_directory: path("FOO"), + embeddable_name: path("/quux/src/main.rs") + }, + scopes: RemapPathScopeComponents::all() + } + ); + + // Relative path + assert_eq!( + mapping.to_real_filename(&working_directory, path("src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("src/main.rs"), + working_directory: path("/foo"), + embeddable_name: path("/foo/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("src/main.rs"), + working_directory: path("FOO"), + embeddable_name: path("FOO/src/main.rs") + }, + scopes: RemapPathScopeComponents::all() + } + ); + + // Relative path with `./` + assert_eq!( + mapping.to_real_filename(&working_directory, path("./src/main.rs"),), + RealFileName { + local: Some(InnerRealFileName { + name: path("./src/main.rs"), + working_directory: path("/foo"), + embeddable_name: path("/foo/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("./src/main.rs"), + working_directory: path("FOO"), + embeddable_name: path("FOO/src/main.rs") + }, + scopes: RemapPathScopeComponents::all() + } + ); + + // Relative path that does not match any prefix + assert_eq!( + mapping.to_real_filename( + &mapping.to_real_filename(&RealFileName::empty(), path("/abc")), + path("quux/src/main.rs"), ), - RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") } + RealFileName { + local: Some(InnerRealFileName { + name: path("quux/src/main.rs"), + working_directory: path("/abc"), + embeddable_name: path("/abc/quux/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("quux/src/main.rs"), + working_directory: path("/abc"), + embeddable_name: path("/abc/quux/src/main.rs") + }, + scopes: RemapPathScopeComponents::empty() + } ); } #[test] -fn path_prefix_remapping_expand_to_absolute_and_local() { +fn to_real_filename_with_mixed_scopes() { // "virtual" working directory is relative path let mapping = &FilePathMapping::new( vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))], - FileNameDisplayPreference::Remapped, - FileNameEmbeddablePreference::LocalAndRemapped, + RemapPathScopeComponents::OBJECT, ); let working_directory = path("/foo"); - let working_directory = RealFileName::Remapped { - local_path: Some(working_directory.clone()), - virtual_name: mapping.map_prefix(working_directory).0.into_owned(), - }; + let working_directory = mapping.to_real_filename(&RealFileName::empty(), working_directory); - assert_eq!(working_directory.remapped_path_if_available(), path("FOO")); + assert_eq!(working_directory.path(RemapPathScopeComponents::DIAGNOSTICS), path("/foo")); + assert_eq!(working_directory.path(RemapPathScopeComponents::MACRO), path("FOO")); + assert_eq!(working_directory.path(RemapPathScopeComponents::DEBUGINFO), path("FOO")); - // Unmapped absolute path + // Absolute path assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::LocalPath(path("/foo/src/main.rs")), - &working_directory - ), - RealFileName::Remapped { - local_path: Some(path("/foo/src/main.rs")), - virtual_name: path("FOO/src/main.rs") - } - ); - - // Unmapped absolute path with unrelated working directory - assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::LocalPath(path("/bar/src/main.rs")), - &working_directory - ), - RealFileName::Remapped { - local_path: Some(path("/bar/src/main.rs")), - virtual_name: path("BAR/src/main.rs") - } - ); - - // Already remapped absolute path, with unrelated working directory - assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::Remapped { - local_path: Some(path("/bar/src/main.rs")), - virtual_name: path("BAR/src/main.rs"), + mapping.to_real_filename(&working_directory, path("/foo/src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("/foo/src/main.rs"), + working_directory: path("/foo"), + embeddable_name: path("/foo/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("FOO/src/main.rs"), + working_directory: path("FOO"), + embeddable_name: path("FOO/src/main.rs") }, - &working_directory - ), - RealFileName::Remapped { - local_path: Some(path("/bar/src/main.rs")), - virtual_name: path("BAR/src/main.rs") + scopes: RemapPathScopeComponents::OBJECT } ); - // Already remapped relative path + // Absolute path with unrelated working directory assert_eq!( - mapping.to_embeddable_absolute_path( - RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") }, - &working_directory + mapping.to_real_filename(&working_directory, path("/bar/src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("/bar/src/main.rs"), + working_directory: path("/foo"), + embeddable_name: path("/bar/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("BAR/src/main.rs"), + working_directory: path("FOO"), + embeddable_name: path("BAR/src/main.rs") + }, + scopes: RemapPathScopeComponents::OBJECT + } + ); + + // Absolute path without remapping + assert_eq!( + mapping.to_real_filename(&working_directory, path("/quux/src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("/quux/src/main.rs"), + working_directory: path("/foo"), + embeddable_name: path("/quux/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("/quux/src/main.rs"), + working_directory: path("FOO"), + embeddable_name: path("/quux/src/main.rs") + }, + scopes: RemapPathScopeComponents::OBJECT + } + ); + + // Relative path + assert_eq!( + mapping.to_real_filename(&working_directory, path("src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("src/main.rs"), + working_directory: path("/foo"), + embeddable_name: path("/foo/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("src/main.rs"), + working_directory: path("FOO"), + embeddable_name: path("FOO/src/main.rs") + }, + scopes: RemapPathScopeComponents::OBJECT + } + ); + + // Relative path that does not match any prefix + assert_eq!( + mapping.to_real_filename( + &mapping.to_real_filename(&RealFileName::empty(), path("/abc")), + path("quux/src/main.rs"), ), - RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") } + RealFileName { + local: Some(InnerRealFileName { + name: path("quux/src/main.rs"), + working_directory: path("/abc"), + embeddable_name: path("/abc/quux/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("quux/src/main.rs"), + working_directory: path("/abc"), + embeddable_name: path("/abc/quux/src/main.rs") + }, + scopes: RemapPathScopeComponents::empty() + } + ); +} +#[test] +fn to_real_filename_without_remapped_cwd() { + // "virtual" working directory is relative path + let mapping = &FilePathMapping::new( + vec![(path("/foo"), path("FOO")), (path("/cwd/bar"), path("CWDBAR"))], + RemapPathScopeComponents::OBJECT, + ); + let working_directory = path("/cwd"); + let working_directory = mapping.to_real_filename(&RealFileName::empty(), working_directory); + + assert_eq!(working_directory.path(RemapPathScopeComponents::DIAGNOSTICS), path("/cwd")); + assert_eq!(working_directory.path(RemapPathScopeComponents::MACRO), path("/cwd")); + assert_eq!(working_directory.path(RemapPathScopeComponents::DEBUGINFO), path("/cwd")); + + // Absolute path + assert_eq!( + mapping.to_real_filename(&working_directory, path("/foo/src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("/foo/src/main.rs"), + working_directory: path("/cwd"), + embeddable_name: path("/foo/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("FOO/src/main.rs"), + working_directory: path("/cwd"), + embeddable_name: path("FOO/src/main.rs") + }, + scopes: RemapPathScopeComponents::OBJECT + } + ); + + // Absolute path with unrelated root + assert_eq!( + mapping.to_real_filename(&working_directory, path("/bar/src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("/bar/src/main.rs"), + working_directory: path("/cwd"), + embeddable_name: path("/bar/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("/bar/src/main.rs"), + working_directory: path("/cwd"), + embeddable_name: path("/bar/src/main.rs") + }, + scopes: RemapPathScopeComponents::empty() + } + ); + + // Absolute path with cwd + assert_eq!( + mapping.to_real_filename(&working_directory, path("/cwd/bar/src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("/cwd/bar/src/main.rs"), + working_directory: path("/cwd"), + embeddable_name: path("/cwd/bar/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("CWDBAR/src/main.rs"), + working_directory: path("/cwd"), + embeddable_name: path("CWDBAR/src/main.rs") + }, + scopes: RemapPathScopeComponents::OBJECT + } + ); + + // Relative path + assert_eq!( + mapping.to_real_filename(&working_directory, path("src/main.rs")), + RealFileName { + local: Some(InnerRealFileName { + name: path("src/main.rs"), + working_directory: path("/cwd"), + embeddable_name: path("/cwd/src/main.rs") + }), + maybe_remapped: InnerRealFileName { + name: path("src/main.rs"), + working_directory: path("/cwd"), + embeddable_name: path("/cwd/src/main.rs") + }, + scopes: RemapPathScopeComponents::empty() + } ); } @@ -526,8 +671,7 @@ fn path_prefix_remapping_reverse() { { let mapping = &FilePathMapping::new( vec![(path("abc"), path("/")), (path("def"), path("."))], - FileNameDisplayPreference::Remapped, - FileNameEmbeddablePreference::RemappedOnly, + RemapPathScopeComponents::all(), ); assert_eq!(reverse_map_prefix(mapping, "/hello.rs"), None); @@ -538,8 +682,7 @@ fn path_prefix_remapping_reverse() { { let mapping = &FilePathMapping::new( vec![(path("abc"), path("/redacted")), (path("def"), path("/redacted"))], - FileNameDisplayPreference::Remapped, - FileNameEmbeddablePreference::RemappedOnly, + RemapPathScopeComponents::all(), ); assert_eq!(reverse_map_prefix(mapping, "/redacted/hello.rs"), None); @@ -549,8 +692,7 @@ fn path_prefix_remapping_reverse() { { let mapping = &FilePathMapping::new( vec![(path("abc"), path("/redacted")), (path("def/ghi"), path("/fake/dir"))], - FileNameDisplayPreference::Remapped, - FileNameEmbeddablePreference::RemappedOnly, + RemapPathScopeComponents::all(), ); assert_eq!( @@ -567,7 +709,7 @@ fn path_prefix_remapping_reverse() { #[test] fn test_next_point() { let sm = SourceMap::new(FilePathMapping::empty()); - sm.new_source_file(PathBuf::from("example.rs").into(), "a…b".to_string()); + sm.new_source_file(filename(&sm, "example.rs"), "a…b".to_string()); // Dummy spans don't advance. let span = DUMMY_SP; diff --git a/tests/run-make/duplicate-dependency/rmake.rs b/tests/run-make/duplicate-dependency/rmake.rs index 762d97e4311f..274db933feb8 100644 --- a/tests/run-make/duplicate-dependency/rmake.rs +++ b/tests/run-make/duplicate-dependency/rmake.rs @@ -11,7 +11,7 @@ fn rustc_with_common_args() -> Rustc { fn main() { rustc_with_common_args() - .input("foo-v1.rs") + .input(cwd().join("foo-v1.rs")) .crate_type("rlib") .crate_name("foo") .extra_filename("-v1") @@ -19,7 +19,7 @@ fn main() { .run(); rustc_with_common_args() - .input("foo-v2.rs") + .input(cwd().join("foo-v2.rs")) .crate_type("rlib") .crate_name("foo") .extra_filename("-v2") @@ -27,7 +27,7 @@ fn main() { .run(); rustc_with_common_args() - .input("re-export-foo.rs") + .input(cwd().join("re-export-foo.rs")) .crate_type("rlib") .extern_("foo", rust_lib_name("foo-v2")) .run(); diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr index e77c0e5f68d6..86c1140573e3 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr +++ b/tests/ui/errors/remap-path-prefix-diagnostics.only-diag-in-deps.stderr @@ -10,7 +10,7 @@ help: the trait `std::fmt::Display` is not implemented for `A` LL | struct A; | ^^^^^^^^ note: required by a bound in `Trait` - --> $DIR/auxiliary/trait-diag.rs:LL:COL + --> remapped/errors/auxiliary/trait-diag.rs:LL:COL | LL | pub trait Trait: std::fmt::Display {} | ^^^^^^^^^^^^^^^^^ required by this bound in `Trait` From fb7ab6de1619128cc1708332b2ccc97987bda24d Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 5 Dec 2025 20:44:34 +0100 Subject: [PATCH 0625/3801] Adapt rustdoc to the overhauled filename handling --- src/librustdoc/clean/types.rs | 17 ++++++++++++----- src/librustdoc/doctest.rs | 13 +++---------- src/librustdoc/doctest/markdown.rs | 11 ++++++++--- src/librustdoc/doctest/rust.rs | 10 ---------- src/librustdoc/html/render/context.rs | 4 ++-- src/librustdoc/html/render/mod.rs | 4 ++-- src/librustdoc/html/sources.rs | 12 ++++++------ src/librustdoc/passes/calculate_doc_coverage.rs | 10 +++++++--- 8 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 7a4650feac1c..a390a03ff114 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -25,7 +25,7 @@ use rustc_resolve::rustdoc::{ use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Symbol, kw, sym}; -use rustc_span::{DUMMY_SP, FileName, Loc}; +use rustc_span::{DUMMY_SP, FileName, Loc, RemapPathScopeComponents}; use tracing::{debug, trace}; use {rustc_ast as ast, rustc_hir as hir}; @@ -148,10 +148,17 @@ impl ExternalCrate { pub(crate) fn src_root(&self, tcx: TyCtxt<'_>) -> PathBuf { match self.src(tcx) { - FileName::Real(ref p) => match p.local_path_if_available().parent() { - Some(p) => p.to_path_buf(), - None => PathBuf::new(), - }, + FileName::Real(ref p) => { + match p + .local_path() + .or(Some(p.path(RemapPathScopeComponents::MACRO))) + .unwrap() + .parent() + { + Some(p) => p.to_path_buf(), + None => PathBuf::new(), + } + } _ => PathBuf::new(), } } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 19e8fe3e3ed2..92b4a01409dd 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -29,7 +29,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::config::{self, CrateType, ErrorOutputType, Input}; use rustc_session::lint; use rustc_span::edition::Edition; -use rustc_span::{FileName, Span}; +use rustc_span::{FileName, RemapPathScopeComponents, Span}; use rustc_target::spec::{Target, TargetTuple}; use tempfile::{Builder as TempFileBuilder, TempDir}; use tracing::debug; @@ -952,14 +952,7 @@ impl ScrapedDocTest { } fn path(&self) -> PathBuf { match &self.filename { - FileName::Real(path) => { - if let Some(local_path) = path.local_path() { - local_path.to_path_buf() - } else { - // Somehow we got the filename from the metadata of another crate, should never happen - unreachable!("doctest from a different crate"); - } - } + FileName::Real(name) => name.path(RemapPathScopeComponents::DIAGNOSTICS).to_path_buf(), _ => PathBuf::from(r"doctest.rs"), } } @@ -1007,7 +1000,7 @@ impl CreateRunnableDocTests { // For example `module/file.rs` would become `module_file_rs` let file = scraped_test .filename - .prefer_local() + .prefer_local_unconditionally() .to_string_lossy() .chars() .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' }) diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs index 7f26605f2562..eba2b0adae5c 100644 --- a/src/librustdoc/doctest/markdown.rs +++ b/src/librustdoc/doctest/markdown.rs @@ -4,7 +4,8 @@ use std::fs::read_to_string; use std::sync::{Arc, Mutex}; use rustc_session::config::Input; -use rustc_span::{DUMMY_SP, FileName}; +use rustc_span::source_map::FilePathMapping; +use rustc_span::{DUMMY_SP, FileName, RealFileName}; use tempfile::tempdir; use super::{ @@ -105,8 +106,12 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> { cur_path: vec![], filename: input .opt_path() - .map(ToOwned::to_owned) - .map(FileName::from) + .map(|f| { + // We don't have access to a rustc Session so let's just use a dummy + // filepath mapping to create a real filename. + let file_mapping = FilePathMapping::empty(); + FileName::Real(file_mapping.to_real_filename(&RealFileName::empty(), f)) + }) .unwrap_or(FileName::Custom("input".to_owned())), }; let codes = ErrorCodes::from(options.unstable_features.is_nightly_build()); diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index ee1419d17d6e..b4397b1f01ff 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -1,7 +1,6 @@ //! Doctest functionality used only for doctests in `.rs` source files. use std::cell::Cell; -use std::env; use std::str::FromStr; use std::sync::Arc; @@ -31,15 +30,6 @@ struct RustCollector { impl RustCollector { fn get_filename(&self) -> FileName { let filename = self.source_map.span_to_filename(self.position); - if let FileName::Real(ref filename) = filename { - let path = filename.remapped_path_if_available(); - // Strip the cwd prefix from the path. This will likely exist if - // the path was not remapped. - let path = env::current_dir() - .map(|cur_dir| path.strip_prefix(&cur_dir).unwrap_or(path)) - .unwrap_or(path); - return path.to_owned().into(); - } filename } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 3d4dff4a17d2..ee71564a1417 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -365,7 +365,7 @@ impl<'tcx> Context<'tcx> { // We can safely ignore synthetic `SourceFile`s. let file = match span.filename(self.sess()) { - FileName::Real(ref path) => path.local_path_if_available().to_path_buf(), + FileName::Real(ref path) => path.local_path()?.to_path_buf(), _ => return None, }; let file = &file; @@ -499,7 +499,7 @@ impl<'tcx> Context<'tcx> { } = options; let src_root = match krate.src(tcx) { - FileName::Real(ref p) => match p.local_path_if_available().parent() { + FileName::Real(ref p) => match p.local_path().map(|p| p.parent()).flatten() { Some(p) => p.to_path_buf(), None => PathBuf::new(), }, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 8740b5935973..4529f5a8c016 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -60,7 +60,7 @@ use rustc_hir::{ConstStability, Mutability, RustcVersion, StabilityLevel, Stable use rustc_middle::ty::print::PrintTraitRefExt; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{Symbol, sym}; -use rustc_span::{BytePos, DUMMY_SP, FileName, RealFileName}; +use rustc_span::{BytePos, DUMMY_SP, FileName}; use tracing::{debug, info}; pub(crate) use self::context::*; @@ -2772,7 +2772,7 @@ fn render_call_locations( files .iter() .find(|file| match &file.name { - FileName::Real(RealFileName::LocalPath(other_path)) => rel_path == other_path, + FileName::Real(real) => real.local_path().map_or(false, |p| p == rel_path), _ => false, }) .map(|file| file.start_pos) diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 55f8ddab25b1..89fd78979839 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_span::{FileName, FileNameDisplayPreference, RealFileName}; +use rustc_span::{FileName, RealFileName, RemapPathScopeComponents}; use tracing::info; use super::render::Context; @@ -148,7 +148,10 @@ impl DocVisitor<'_> for SourceCollector<'_, '_> { span, format!( "failed to render source code for `{filename}`: {e}", - filename = filename.to_string_lossy(FileNameDisplayPreference::Local), + filename = filename + .path(RemapPathScopeComponents::DIAGNOSTICS) + .to_string_lossy() + .into_owned(), ), ); false @@ -224,10 +227,7 @@ impl SourceCollector<'_, '_> { cur.push(&fname); let title = format!("{} - source", src_fname.to_string_lossy()); - let desc = format!( - "Source of the Rust file `{}`.", - file.to_string_lossy(FileNameDisplayPreference::Remapped) - ); + let desc = format!("Source of the Rust file `{}`.", p.to_string_lossy()); let page = layout::Page { title: &title, short_title: &src_fname.to_string_lossy(), diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 66d8b667a4ca..2782baae5e20 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -7,7 +7,7 @@ use rustc_hir as hir; use rustc_lint::builtin::MISSING_DOCS; use rustc_middle::lint::{LevelAndSource, LintLevelSource}; use rustc_session::lint; -use rustc_span::FileName; +use rustc_span::{FileName, RemapPathScopeComponents}; use serde::Serialize; use tracing::debug; @@ -124,7 +124,7 @@ impl CoverageCalculator<'_, '_> { &self .items .iter() - .map(|(k, v)| (k.prefer_local().to_string(), v)) + .map(|(k, v)| (k.prefer_local_unconditionally().to_string(), v)) .collect::>(), ) .expect("failed to convert JSON data to string") @@ -167,7 +167,11 @@ impl CoverageCalculator<'_, '_> { for (file, &count) in &self.items { if let Some(percentage) = count.percentage() { print_table_record( - &limit_filename_len(file.prefer_local().to_string_lossy().into()), + &limit_filename_len( + file.display(RemapPathScopeComponents::DIAGNOSTICS) + .to_string_lossy() + .into(), + ), count, percentage, count.examples_percentage().unwrap_or(0.), From 799eecf1eb622704a602fed39b3733b96394560e Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 5 Dec 2025 21:46:29 +0100 Subject: [PATCH 0626/3801] Adapt Clippy to the overhaul filename handling --- src/tools/clippy/clippy_lints/src/module_style.rs | 2 +- src/tools/clippy/clippy_utils/src/source.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/module_style.rs b/src/tools/clippy/clippy_lints/src/module_style.rs index 9096d6f1c7b3..befd50a5c85f 100644 --- a/src/tools/clippy/clippy_lints/src/module_style.rs +++ b/src/tools/clippy/clippy_lints/src/module_style.rs @@ -81,7 +81,7 @@ pub struct ModStyle { impl EarlyLintPass for ModStyle { fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { - self.working_dir = cx.sess().opts.working_dir.local_path().map(Path::to_path_buf); + self.working_dir = cx.sess().source_map().working_dir().local_path().map(Path::to_path_buf); } fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs index e29d45551d1b..b48d17863aa3 100644 --- a/src/tools/clippy/clippy_utils/src/source.rs +++ b/src/tools/clippy/clippy_utils/src/source.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::source_map::{SourceMap, original_sp}; use rustc_span::{ - BytePos, DUMMY_SP, DesugaringKind, FileNameDisplayPreference, Pos, RelativeBytePos, SourceFile, SourceFileAndLine, + BytePos, DUMMY_SP, DesugaringKind, Pos, RelativeBytePos, SourceFile, SourceFileAndLine, Span, SpanData, SyntaxContext, hygiene, }; use std::borrow::Cow; @@ -268,7 +268,7 @@ fn map_range( debug_assert!( range.start <= text.len() && range.end <= text.len(), "Range `{range:?}` is outside the source file (file `{}`, length `{}`)", - src.sf.name.display(FileNameDisplayPreference::Local), + src.sf.name.prefer_local_unconditionally(), text.len(), ); debug_assert!(range.start <= range.end, "Range `{range:?}` has overlapping bounds"); From d5b1a0cfc6c0a170719d4eb84741c76ef072ce74 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 5 Dec 2025 22:04:55 +0100 Subject: [PATCH 0627/3801] Adapt Miri to the overhauled filename handling And use the diagnostic method for diagnostic paths. --- src/tools/miri/src/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 01f77f261d70..0c7ce472556b 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -627,7 +627,7 @@ pub fn report_msg<'tcx>( err.subdiagnostic(frame_info.as_note(machine.tcx)); } else { let sm = sess.source_map(); - let span = sm.span_to_embeddable_string(frame_info.span); + let span = sm.span_to_diagnostic_string(frame_info.span); err.note(format!("{frame_info} at {span}")); } } From b30c7c2554e995f0803d11ccfc163a57f1b0c079 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 5 Dec 2025 21:46:29 +0100 Subject: [PATCH 0628/3801] Adapt Clippy to the overhaul filename handling --- clippy_lints/src/module_style.rs | 2 +- clippy_utils/src/source.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/module_style.rs b/clippy_lints/src/module_style.rs index 9096d6f1c7b3..befd50a5c85f 100644 --- a/clippy_lints/src/module_style.rs +++ b/clippy_lints/src/module_style.rs @@ -81,7 +81,7 @@ pub struct ModStyle { impl EarlyLintPass for ModStyle { fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { - self.working_dir = cx.sess().opts.working_dir.local_path().map(Path::to_path_buf); + self.working_dir = cx.sess().source_map().working_dir().local_path().map(Path::to_path_buf); } fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index e29d45551d1b..b48d17863aa3 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::source_map::{SourceMap, original_sp}; use rustc_span::{ - BytePos, DUMMY_SP, DesugaringKind, FileNameDisplayPreference, Pos, RelativeBytePos, SourceFile, SourceFileAndLine, + BytePos, DUMMY_SP, DesugaringKind, Pos, RelativeBytePos, SourceFile, SourceFileAndLine, Span, SpanData, SyntaxContext, hygiene, }; use std::borrow::Cow; @@ -268,7 +268,7 @@ fn map_range( debug_assert!( range.start <= text.len() && range.end <= text.len(), "Range `{range:?}` is outside the source file (file `{}`, length `{}`)", - src.sf.name.display(FileNameDisplayPreference::Local), + src.sf.name.prefer_local_unconditionally(), text.len(), ); debug_assert!(range.start <= range.end, "Range `{range:?}` has overlapping bounds"); From cc4cdea3fac026bae72849032bbc5d7770b009ac Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 6 Dec 2025 13:02:03 +0100 Subject: [PATCH 0629/3801] Adapt rustfmt to the overhaul filename handling --- src/tools/rustfmt/src/config/file_lines.rs | 10 ++- src/tools/rustfmt/src/parse/session.rs | 80 +++++++++++----------- src/tools/rustfmt/src/source_file.rs | 12 ---- 3 files changed, 50 insertions(+), 52 deletions(-) diff --git a/src/tools/rustfmt/src/config/file_lines.rs b/src/tools/rustfmt/src/config/file_lines.rs index 2f2a6c8d5520..f9ae0d16e298 100644 --- a/src/tools/rustfmt/src/config/file_lines.rs +++ b/src/tools/rustfmt/src/config/file_lines.rs @@ -28,7 +28,15 @@ pub enum FileName { impl From for FileName { fn from(name: rustc_span::FileName) -> FileName { match name { - rustc_span::FileName::Real(rustc_span::RealFileName::LocalPath(p)) => FileName::Real(p), + rustc_span::FileName::Real(real) => { + if let Some(p) = real.into_local_path() { + FileName::Real(p) + } else { + // rustfmt does not remap filenames; the local path should always + // remain accessible. + unreachable!() + } + } rustc_span::FileName::Custom(ref f) if f == "stdin" => FileName::Stdin, _ => unreachable!(), } diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 10e2809e58bf..2fd8bfdaf3e1 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -58,19 +58,19 @@ impl Emitter for SilentOnIgnoredFilesEmitter { } if let Some(primary_span) = &diag.span.primary_span() { let file_name = self.source_map.span_to_filename(*primary_span); - if let rustc_span::FileName::Real(rustc_span::RealFileName::LocalPath(ref path)) = - file_name - { - if self - .ignore_path_set - .is_match(&FileName::Real(path.to_path_buf())) - { - if !self.has_non_ignorable_parser_errors { - self.can_reset.store(true, Ordering::Release); + if let rustc_span::FileName::Real(real) = file_name { + if let Some(path) = real.local_path() { + if self + .ignore_path_set + .is_match(&FileName::Real(path.to_path_buf())) + { + if !self.has_non_ignorable_parser_errors { + self.can_reset.store(true, Ordering::Release); + } + return; } - return; } - }; + } } self.handle_non_ignoreable_error(diag, registry); } @@ -181,7 +181,10 @@ impl ParseSess { self.raw_psess .source_map() .get_source_file(&rustc_span::FileName::Real( - rustc_span::RealFileName::LocalPath(path.to_path_buf()), + self.raw_psess + .source_map() + .path_mapping() + .to_real_filename(self.raw_psess.source_map().working_dir(), path), )) .is_some() } @@ -246,10 +249,20 @@ impl ParseSess { ) } - pub(crate) fn get_original_snippet(&self, file_name: &FileName) -> Option> { + pub(crate) fn get_original_snippet(&self, filename: &FileName) -> Option> { + let rustc_filename = match filename { + FileName::Real(path) => rustc_span::FileName::Real( + self.raw_psess + .source_map() + .path_mapping() + .to_real_filename(self.raw_psess.source_map().working_dir(), path), + ), + FileName::Stdin => rustc_span::FileName::Custom("stdin".to_owned()), + }; + self.raw_psess .source_map() - .get_source_file(&file_name.into()) + .get_source_file(&rustc_filename) .and_then(|source_file| source_file.src.clone()) } } @@ -313,7 +326,7 @@ mod tests { use crate::config::IgnoreList; use crate::utils::mk_sp; use rustc_errors::MultiSpan; - use rustc_span::{FileName as SourceMapFileName, RealFileName}; + use rustc_span::FileName as SourceMapFileName; use std::path::PathBuf; use std::sync::atomic::AtomicU32; @@ -372,6 +385,13 @@ mod tests { .ignore() } + fn filename(sm: &SourceMap, path: &str) -> SourceMapFileName { + SourceMapFileName::Real( + sm.path_mapping() + .to_real_filename(sm.working_dir(), PathBuf::from(path)), + ) + } + #[test] fn handles_fatal_parse_error_in_ignored_file() { let num_emitted_errors = Arc::new(AtomicU32::new(0)); @@ -380,10 +400,7 @@ mod tests { let source_map = Arc::new(SourceMap::new(FilePathMapping::empty())); let source = String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), - source, - ); + source_map.new_source_file(filename(&source_map, "foo.rs"), source); let registry = Registry::new(&[]); let mut emitter = build_emitter( Arc::clone(&num_emitted_errors), @@ -406,10 +423,7 @@ mod tests { let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#); let source_map = Arc::new(SourceMap::new(FilePathMapping::empty())); let source = String::from(r#"pub fn bar() { 1x; }"#); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), - source, - ); + source_map.new_source_file(filename(&source_map, "foo.rs"), source); let registry = Registry::new(&[]); let mut emitter = build_emitter( Arc::clone(&num_emitted_errors), @@ -431,10 +445,7 @@ mod tests { let can_reset_errors = Arc::new(AtomicBool::new(false)); let source_map = Arc::new(SourceMap::new(FilePathMapping::empty())); let source = String::from(r#"pub fn bar() { 1x; }"#); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), - source, - ); + source_map.new_source_file(filename(&source_map, "foo.rs"), source); let registry = Registry::new(&[]); let mut emitter = build_emitter( Arc::clone(&num_emitted_errors), @@ -460,18 +471,9 @@ mod tests { let foo_source = String::from(r#"pub fn foo() { 1x; }"#); let fatal_source = String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("bar.rs"))), - bar_source, - ); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), - foo_source, - ); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("fatal.rs"))), - fatal_source, - ); + source_map.new_source_file(filename(&source_map, "bar.rs"), bar_source); + source_map.new_source_file(filename(&source_map, "foo.rs"), foo_source); + source_map.new_source_file(filename(&source_map, "fatal.rs"), fatal_source); let registry = Registry::new(&[]); let mut emitter = build_emitter( Arc::clone(&num_emitted_errors), diff --git a/src/tools/rustfmt/src/source_file.rs b/src/tools/rustfmt/src/source_file.rs index e942058a0a83..b0ec24f3db66 100644 --- a/src/tools/rustfmt/src/source_file.rs +++ b/src/tools/rustfmt/src/source_file.rs @@ -65,18 +65,6 @@ where } } - #[allow(non_local_definitions)] - impl From<&FileName> for rustc_span::FileName { - fn from(filename: &FileName) -> rustc_span::FileName { - match filename { - FileName::Real(path) => { - rustc_span::FileName::Real(rustc_span::RealFileName::LocalPath(path.to_owned())) - } - FileName::Stdin => rustc_span::FileName::Custom("stdin".to_owned()), - } - } - } - // SourceFile's in the SourceMap will always have Unix-style line endings // See: https://github.com/rust-lang/rustfmt/issues/3850 // So if the user has explicitly overridden the rustfmt `newline_style` From d59c4d903fbd58718aa6aebba9a88fb15378de8c Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 6 Dec 2025 11:31:46 +0100 Subject: [PATCH 0630/3801] Adapt `cg_cranelift` to the overhauled filename handling --- .../src/debuginfo/line_info.rs | 7 ++++-- .../src/debuginfo/mod.rs | 22 +++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs index db58ee890911..12b0d5ec4963 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs @@ -6,7 +6,10 @@ use std::path::{Component, Path}; use cranelift_codegen::MachSrcLoc; use cranelift_codegen::binemit::CodeOffset; use gimli::write::{FileId, FileInfo, LineProgram, LineString, LineStringTable}; -use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene}; +use rustc_span::{ + FileName, Pos, RemapPathScopeComponents, SourceFile, SourceFileAndLine, + SourceFileHashAlgorithm, hygiene, +}; use crate::debuginfo::FunctionDebugContext; use crate::debuginfo::emit::address_for_func; @@ -95,7 +98,7 @@ impl DebugContext { match &source_file.name { FileName::Real(path) => { let (dir_path, file_name) = - split_path_dir_and_file(path.to_path(self.filename_display_preference)); + split_path_dir_and_file(path.path(RemapPathScopeComponents::DEBUGINFO)); let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str()); let file_name = osstr_as_utf8_bytes(file_name); diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index 8c43db92fe05..0cd510037293 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -21,7 +21,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; use rustc_session::config::DebugInfo; -use rustc_span::{FileNameDisplayPreference, SourceFileHash, StableSourceFileId}; +use rustc_span::{RemapPathScopeComponents, SourceFileHash, StableSourceFileId}; use rustc_target::callconv::FnAbi; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; @@ -44,7 +44,6 @@ pub(crate) struct DebugContext { namespace_map: DefIdMap, array_size_type: Option, - filename_display_preference: FileNameDisplayPreference, embed_source: bool, } @@ -102,18 +101,18 @@ impl DebugContext { let mut dwarf = DwarfUnit::new(encoding); - use rustc_session::config::RemapPathScopeComponents; - - let filename_display_preference = - tcx.sess.filename_display_preference(RemapPathScopeComponents::DEBUGINFO); - let producer = producer(tcx.sess); - let comp_dir = - tcx.sess.opts.working_dir.to_string_lossy(filename_display_preference).to_string(); + let comp_dir = tcx + .sess + .source_map() + .working_dir() + .path(RemapPathScopeComponents::DEBUGINFO) + .to_string_lossy(); let (name, file_info) = match tcx.sess.local_crate_source_file() { Some(path) => { - let name = path.to_string_lossy(filename_display_preference).to_string(); + let name = + path.path(RemapPathScopeComponents::DEBUGINFO).to_string_lossy().into_owned(); (name, None) } None => (tcx.crate_name(LOCAL_CRATE).to_string(), None), @@ -137,7 +136,7 @@ impl DebugContext { { let name = dwarf.strings.add(format!("{name}/@/{cgu_name}")); - let comp_dir = dwarf.strings.add(comp_dir); + let comp_dir = dwarf.strings.add(&*comp_dir); let root = dwarf.unit.root(); let root = dwarf.unit.get_mut(root); @@ -180,7 +179,6 @@ impl DebugContext { stack_pointer_register, namespace_map: DefIdMap::default(), array_size_type, - filename_display_preference, embed_source, }) } From b1eb21bb851db6089bc77e9321401cd0c13cd909 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 6 Dec 2025 11:54:06 +0100 Subject: [PATCH 0631/3801] Adapt and fix `cg_gcc` to the overhauled filename remapping --- compiler/rustc_codegen_gcc/src/debuginfo.rs | 28 ++++----------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index 3979f62987f2..53d3670c1524 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -297,29 +297,11 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let pos = span.lo(); let DebugLoc { file, line, col } = self.lookup_debug_loc(pos); match file.name { - rustc_span::FileName::Real(ref name) => match *name { - rustc_span::RealFileName::LocalPath(ref name) => { - if let Some(name) = name.to_str() { - self.context.new_location(name, line as i32, col as i32) - } else { - Location::null() - } - } - rustc_span::RealFileName::Remapped { - ref local_path, - virtual_name: ref _unused, - } => { - if let Some(name) = local_path.as_ref() { - if let Some(name) = name.to_str() { - self.context.new_location(name, line as i32, col as i32) - } else { - Location::null() - } - } else { - Location::null() - } - } - }, + rustc_span::FileName::Real(ref name) => self.context.new_location( + name.path(rustc_span::RemapPathScopeComponents::DEBUGINFO).to_string_lossy(), + line as i32, + col as i32, + ), _ => Location::null(), } } From 8b035e473a080a33525ee33524cb2ef57ec3d94d Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 22 Nov 2025 00:30:23 +0100 Subject: [PATCH 0632/3801] Add regression test for `Location::caller()` in consts across crates --- .../location-caller.rs | 21 ++++ .../remap-path-prefix-consts/rmake.rs | 114 ++++++++++++++++++ .../remap-path-prefix-consts/runner.rs | 19 +++ 3 files changed, 154 insertions(+) create mode 100644 tests/run-make/remap-path-prefix-consts/location-caller.rs create mode 100644 tests/run-make/remap-path-prefix-consts/rmake.rs create mode 100644 tests/run-make/remap-path-prefix-consts/runner.rs diff --git a/tests/run-make/remap-path-prefix-consts/location-caller.rs b/tests/run-make/remap-path-prefix-consts/location-caller.rs new file mode 100644 index 000000000000..70685e032e4a --- /dev/null +++ b/tests/run-make/remap-path-prefix-consts/location-caller.rs @@ -0,0 +1,21 @@ +// Reproducer from https://github.com/rust-lang/rust/issues/148328#issuecomment-3473688412 +#[inline(always)] +pub const fn the_path() -> &'static str { + std::panic::Location::caller().file() +} + +#[inline(never)] +pub fn the_path2() -> &'static str { + const { std::panic::Location::caller().file() } +} + +// Reproducer from https://github.com/rust-lang/rust/issues/148328#issuecomment-3473761194 +pub const fn the_path_len() -> usize { + std::panic::Location::caller().file().len() +} + +pub type Array = [u8; the_path_len()]; + +pub fn the_zeroed_path_len_array() -> Array { + [0; _] +} diff --git a/tests/run-make/remap-path-prefix-consts/rmake.rs b/tests/run-make/remap-path-prefix-consts/rmake.rs new file mode 100644 index 000000000000..02a75aa02278 --- /dev/null +++ b/tests/run-make/remap-path-prefix-consts/rmake.rs @@ -0,0 +1,114 @@ +//@ needs-target-std + +use run_make_support::{bin_name, cwd, run, rustc}; + +fn main() { + // No remapping - relative paths + { + let runner_bin = bin_name("runner-no-remap-rel-paths"); + + let mut location_caller = rustc(); + location_caller.crate_type("lib").input("location-caller.rs"); + location_caller.run(); + + let mut runner = rustc(); + runner.crate_type("bin").input("runner.rs").output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // No remapping - absolute paths + { + let runner_bin = bin_name("runner-no-remap-abs-paths"); + + let mut location_caller = rustc(); + location_caller.crate_type("lib").input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner.crate_type("bin").input(cwd().join("runner.rs")).output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // No remapping - mixed paths + { + let runner_bin = bin_name("runner-no-remap-mixed-paths"); + + let mut location_caller = rustc(); + location_caller.crate_type("lib").input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner.crate_type("bin").input("runner.rs").output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // Remapping current working directory + { + let runner_bin = bin_name("runner-remap-cwd"); + + let mut location_caller = rustc(); + location_caller + .crate_type("lib") + .remap_path_prefix(cwd(), "/remapped") + .input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner + .crate_type("bin") + .remap_path_prefix(cwd(), "/remapped") + .input(cwd().join("runner.rs")) + .output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // Remapping current working directory - only in the dependency + { + let runner_bin = bin_name("runner-remap-cwd-only-dep"); + + let mut location_caller = rustc(); + location_caller + .crate_type("lib") + .remap_path_prefix(cwd(), "/remapped") + .input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner.crate_type("bin").input(cwd().join("runner.rs")).output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // Remapping current working directory - different scopes + { + let runner_bin = bin_name("runner-remap-cwd-diff-scope"); + + let mut location_caller = rustc(); + location_caller + .crate_type("lib") + .remap_path_prefix(cwd(), "/remapped") + .arg("-Zremap-path-scope=object") + .input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner + .crate_type("bin") + .remap_path_prefix(cwd(), "/remapped") + .arg("-Zremap-path-scope=diagnostics") + .input(cwd().join("runner.rs")) + .output(&runner_bin); + runner.run(); + + run(&runner_bin); + } +} diff --git a/tests/run-make/remap-path-prefix-consts/runner.rs b/tests/run-make/remap-path-prefix-consts/runner.rs new file mode 100644 index 000000000000..d67dbe3b398a --- /dev/null +++ b/tests/run-make/remap-path-prefix-consts/runner.rs @@ -0,0 +1,19 @@ +// Verifies that the paths are the same and consistent between this crate and location_caller crate. +// +// https://github.com/rust-lang/rust/issues/148328 + +extern crate location_caller; + +fn main() { + { + // Assert both paths are the same + let the_path = location_caller::the_path(); + let the_path2 = location_caller::the_path2(); + assert_eq!(the_path, the_path2); + } + + { + // Let's make sure we don't read OOB memory + println!("{:?}", location_caller::the_zeroed_path_len_array()); + } +} From 0be1a9b59ae9f8d6caeb3c58a3e112443c9a5b6c Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 5 Dec 2025 20:52:14 +0100 Subject: [PATCH 0633/3801] Somewhat retire `Options::working_dir` in favor `SourceMap::working_dir` We can't completely remove it as it's needed for incr comp but direct consumers towards `SourceMap::working_dir` instead. --- compiler/rustc_session/src/config.rs | 31 ++++++++++++++++++++------- compiler/rustc_session/src/options.rs | 4 +++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b5b19c64951b..be4b36e3b926 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -24,7 +24,7 @@ use rustc_hashes::Hash64; use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; -use rustc_span::{FileName, SourceFileHashAlgorithm, Symbol, sym}; +use rustc_span::{FileName, RealFileName, SourceFileHashAlgorithm, Symbol, sym}; use rustc_target::spec::{ FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo, Target, TargetTuple, @@ -1358,6 +1358,17 @@ fn file_path_mapping( impl Default for Options { fn default() -> Options { + let unstable_opts = UnstableOptions::default(); + + // FIXME(Urgau): This is a hack that ideally shouldn't exist, but rustdoc + // currently uses this `Default` implementation, so we have no choice but + // to create a default working directory. + let working_dir = { + let working_dir = std::env::current_dir().unwrap(); + let file_mapping = file_path_mapping(Vec::new(), &unstable_opts); + file_mapping.to_real_filename(&RealFileName::empty(), &working_dir) + }; + Options { assert_incr_state: None, crate_types: Vec::new(), @@ -1374,7 +1385,7 @@ impl Default for Options { test: false, incremental: None, untracked_state_hash: Default::default(), - unstable_opts: Default::default(), + unstable_opts, prints: Vec::new(), cg: Default::default(), error_format: ErrorOutputType::default(), @@ -1398,7 +1409,7 @@ impl Default for Options { json_unused_externs: JsonUnusedExterns::No, json_future_incompat: false, pretty: None, - working_dir: RealFileName::LocalPath(std::env::current_dir().unwrap()), + working_dir, color: ColorConfig::Auto, logical_env: FxIndexMap::default(), verbose: false, @@ -2752,12 +2763,16 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M .collect() }; - let working_dir = std::env::current_dir().unwrap_or_else(|e| { - early_dcx.early_fatal(format!("Current directory is invalid: {e}")); - }); + // Ideally we would use `SourceMap::working_dir` instead, but we don't have access to it + // so we manually create the potentially-remapped working directory + let working_dir = { + let working_dir = std::env::current_dir().unwrap_or_else(|e| { + early_dcx.early_fatal(format!("Current directory is invalid: {e}")); + }); - let file_mapping = file_path_mapping(remap_path_prefix.clone(), &unstable_opts); - let working_dir = file_mapping.to_real_filename(&working_dir); + let file_mapping = file_path_mapping(remap_path_prefix.clone(), &unstable_opts); + file_mapping.to_real_filename(&RealFileName::empty(), &working_dir) + }; let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d7ac39ecc9e8..aea0b73ee927 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -12,7 +12,7 @@ use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; use rustc_macros::{BlobDecodable, Encodable}; use rustc_span::edition::Edition; -use rustc_span::{RemapPathScopeComponents, SourceFileHashAlgorithm}; +use rustc_span::{RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm}; use rustc_target::spec::{ CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, @@ -492,7 +492,9 @@ top_level_options!( pretty: Option [UNTRACKED], /// The (potentially remapped) working directory + #[rustc_lint_opt_deny_field_access("use `SourceMap::working_dir` instead of this field")] working_dir: RealFileName [TRACKED], + color: ColorConfig [UNTRACKED], verbose: bool [TRACKED_NO_CRATE_HASH], From 0afd21d646d5a6e43541cc1ffedff36dca44eb08 Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 9 Dec 2025 18:48:03 +0100 Subject: [PATCH 0634/3801] Add `ignore-cross-compile` to `remap-path-prefix-consts` run-make test --- tests/run-make/remap-path-prefix-consts/rmake.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/run-make/remap-path-prefix-consts/rmake.rs b/tests/run-make/remap-path-prefix-consts/rmake.rs index 02a75aa02278..d07a5e00768a 100644 --- a/tests/run-make/remap-path-prefix-consts/rmake.rs +++ b/tests/run-make/remap-path-prefix-consts/rmake.rs @@ -1,3 +1,4 @@ +//@ ignore-cross-compile (relocations in generic ELF against `arm-unknown-linux-gnueabihf`) //@ needs-target-std use run_make_support::{bin_name, cwd, run, rustc}; From a95aaca24965ff3661fd11a8b45883ea990a29a0 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 6 Dec 2025 11:54:06 +0100 Subject: [PATCH 0635/3801] Adapt and fix `cg_gcc` to the overhauled filename remapping --- src/debuginfo.rs | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 3979f62987f2..53d3670c1524 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -297,29 +297,11 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let pos = span.lo(); let DebugLoc { file, line, col } = self.lookup_debug_loc(pos); match file.name { - rustc_span::FileName::Real(ref name) => match *name { - rustc_span::RealFileName::LocalPath(ref name) => { - if let Some(name) = name.to_str() { - self.context.new_location(name, line as i32, col as i32) - } else { - Location::null() - } - } - rustc_span::RealFileName::Remapped { - ref local_path, - virtual_name: ref _unused, - } => { - if let Some(name) = local_path.as_ref() { - if let Some(name) = name.to_str() { - self.context.new_location(name, line as i32, col as i32) - } else { - Location::null() - } - } else { - Location::null() - } - } - }, + rustc_span::FileName::Real(ref name) => self.context.new_location( + name.path(rustc_span::RemapPathScopeComponents::DEBUGINFO).to_string_lossy(), + line as i32, + col as i32, + ), _ => Location::null(), } } From d55b61a684a8dd525883091f7ddbeb433e6cc30b Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 6 Dec 2025 11:31:46 +0100 Subject: [PATCH 0636/3801] Adapt `cg_cranelift` to the overhauled filename handling --- src/debuginfo/line_info.rs | 7 +++++-- src/debuginfo/mod.rs | 22 ++++++++++------------ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index db58ee890911..12b0d5ec4963 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -6,7 +6,10 @@ use std::path::{Component, Path}; use cranelift_codegen::MachSrcLoc; use cranelift_codegen::binemit::CodeOffset; use gimli::write::{FileId, FileInfo, LineProgram, LineString, LineStringTable}; -use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene}; +use rustc_span::{ + FileName, Pos, RemapPathScopeComponents, SourceFile, SourceFileAndLine, + SourceFileHashAlgorithm, hygiene, +}; use crate::debuginfo::FunctionDebugContext; use crate::debuginfo::emit::address_for_func; @@ -95,7 +98,7 @@ impl DebugContext { match &source_file.name { FileName::Real(path) => { let (dir_path, file_name) = - split_path_dir_and_file(path.to_path(self.filename_display_preference)); + split_path_dir_and_file(path.path(RemapPathScopeComponents::DEBUGINFO)); let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str()); let file_name = osstr_as_utf8_bytes(file_name); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 8c43db92fe05..0cd510037293 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -21,7 +21,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; use rustc_session::config::DebugInfo; -use rustc_span::{FileNameDisplayPreference, SourceFileHash, StableSourceFileId}; +use rustc_span::{RemapPathScopeComponents, SourceFileHash, StableSourceFileId}; use rustc_target::callconv::FnAbi; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; @@ -44,7 +44,6 @@ pub(crate) struct DebugContext { namespace_map: DefIdMap, array_size_type: Option, - filename_display_preference: FileNameDisplayPreference, embed_source: bool, } @@ -102,18 +101,18 @@ impl DebugContext { let mut dwarf = DwarfUnit::new(encoding); - use rustc_session::config::RemapPathScopeComponents; - - let filename_display_preference = - tcx.sess.filename_display_preference(RemapPathScopeComponents::DEBUGINFO); - let producer = producer(tcx.sess); - let comp_dir = - tcx.sess.opts.working_dir.to_string_lossy(filename_display_preference).to_string(); + let comp_dir = tcx + .sess + .source_map() + .working_dir() + .path(RemapPathScopeComponents::DEBUGINFO) + .to_string_lossy(); let (name, file_info) = match tcx.sess.local_crate_source_file() { Some(path) => { - let name = path.to_string_lossy(filename_display_preference).to_string(); + let name = + path.path(RemapPathScopeComponents::DEBUGINFO).to_string_lossy().into_owned(); (name, None) } None => (tcx.crate_name(LOCAL_CRATE).to_string(), None), @@ -137,7 +136,7 @@ impl DebugContext { { let name = dwarf.strings.add(format!("{name}/@/{cgu_name}")); - let comp_dir = dwarf.strings.add(comp_dir); + let comp_dir = dwarf.strings.add(&*comp_dir); let root = dwarf.unit.root(); let root = dwarf.unit.get_mut(root); @@ -180,7 +179,6 @@ impl DebugContext { stack_pointer_register, namespace_map: DefIdMap::default(), array_size_type, - filename_display_preference, embed_source, }) } From cefcd99c1779a1e46aa7950fb65fa5b5f77d56e1 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 10 Dec 2025 19:42:18 +0100 Subject: [PATCH 0637/3801] Fix normalization logic of the rustdoc extract doctests tests on Windows --- tests/rustdoc-ui/extract-doctests-result.rs | 1 + tests/rustdoc-ui/extract-doctests-result.stdout | 2 +- tests/rustdoc-ui/extract-doctests.rs | 1 + tests/rustdoc-ui/extract-doctests.stdout | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/rustdoc-ui/extract-doctests-result.rs b/tests/rustdoc-ui/extract-doctests-result.rs index 88affb6d3331..4869fcd0259b 100644 --- a/tests/rustdoc-ui/extract-doctests-result.rs +++ b/tests/rustdoc-ui/extract-doctests-result.rs @@ -3,6 +3,7 @@ //@ compile-flags:-Z unstable-options --output-format=doctest //@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "[A-Z]:[\\/](?:[^\\/]+[\\/])*?\$DIR" -> "$$DIR" //@ check-pass //! ``` diff --git a/tests/rustdoc-ui/extract-doctests-result.stdout b/tests/rustdoc-ui/extract-doctests-result.stdout index 44e6d33c6626..bb5d2c3e68c6 100644 --- a/tests/rustdoc-ui/extract-doctests-result.stdout +++ b/tests/rustdoc-ui/extract-doctests-result.stdout @@ -1 +1 @@ -{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests-result.rs","line":8,"doctest_attributes":{"original":"","should_panic":false,"no_run":false,"ignore":"None","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nOk(())","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nOk(())","wrapper":{"before":"fn main() { fn _inner() -> core::result::Result<(), impl core::fmt::Debug> {\n","after":"\n} _inner().unwrap() }","returns_result":true}},"name":"$DIR/extract-doctests-result.rs - (line 8)"}]} \ No newline at end of file +{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests-result.rs","line":9,"doctest_attributes":{"original":"","should_panic":false,"no_run":false,"ignore":"None","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nOk(())","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nOk(())","wrapper":{"before":"fn main() { fn _inner() -> core::result::Result<(), impl core::fmt::Debug> {\n","after":"\n} _inner().unwrap() }","returns_result":true}},"name":"$DIR/extract-doctests-result.rs - (line 9)"}]} \ No newline at end of file diff --git a/tests/rustdoc-ui/extract-doctests.rs b/tests/rustdoc-ui/extract-doctests.rs index 06bd35969d0c..e2071f4ec10c 100644 --- a/tests/rustdoc-ui/extract-doctests.rs +++ b/tests/rustdoc-ui/extract-doctests.rs @@ -3,6 +3,7 @@ //@ compile-flags:-Z unstable-options --output-format=doctest //@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "[A-Z]:[\\/](?:[^\\/]+[\\/])*?\$DIR" -> "$$DIR" //@ check-pass //! ```ignore (checking attributes) diff --git a/tests/rustdoc-ui/extract-doctests.stdout b/tests/rustdoc-ui/extract-doctests.stdout index 796ecd82f1c9..4e2acc91f498 100644 --- a/tests/rustdoc-ui/extract-doctests.stdout +++ b/tests/rustdoc-ui/extract-doctests.stdout @@ -1 +1 @@ -{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests.rs","line":8,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nlet y = 14;","wrapper":{"before":"fn main() {\n","after":"\n}","returns_result":false}},"name":"$DIR/extract-doctests.rs - (line 8)"},{"file":"$DIR/extract-doctests.rs","line":13,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":null,"name":"$DIR/extract-doctests.rs - (line 13)"}]} \ No newline at end of file +{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests.rs","line":9,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nlet y = 14;","wrapper":{"before":"fn main() {\n","after":"\n}","returns_result":false}},"name":"$DIR/extract-doctests.rs - (line 9)"},{"file":"$DIR/extract-doctests.rs","line":14,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":null,"name":"$DIR/extract-doctests.rs - (line 14)"}]} \ No newline at end of file From 73c682a1fd8e94417fdc7ab5683c7d22b563ceee Mon Sep 17 00:00:00 2001 From: Redddy Date: Fri, 12 Dec 2025 16:00:26 +0900 Subject: [PATCH 0638/3801] Add link to needs test issues in getting-started.md --- src/doc/rustc-dev-guide/src/getting-started.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 061f6966f4b7..36d19e6c570e 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -151,6 +151,9 @@ Issues that have been resolved but do not have a regression test are marked with Writing unit tests is a low-risk, lower-priority task that offers new contributors a great opportunity to familiarize themselves with the testing infrastructure and contribution workflow. +You can see a list of needs test issues [here][needs-test-issues]. + +[needs-test-issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue%20is%3Aopen%20label%3AE-needs-test%20no%3Aassignee ### Contributing to std (standard library) From 31258db8e224654244cad95c557bd76d8e71d4f9 Mon Sep 17 00:00:00 2001 From: tris203 Date: Thu, 11 Dec 2025 22:33:58 +0000 Subject: [PATCH 0639/3801] fix(lsp): handle dynamic registration for didSave Update server capabilities to set `save` to `None` when the client supports dynamic registration for `didSaveTextDocument`. This prevents redundant static registration and aligns with LSP specification. --- .../crates/rust-analyzer/src/lsp/capabilities.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs index f94e7486ff8f..d6a694be9121 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs @@ -37,7 +37,11 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { change: Some(TextDocumentSyncKind::INCREMENTAL), will_save: None, will_save_wait_until: None, - save: Some(SaveOptions::default().into()), + save: if config.caps().did_save_text_document_dynamic_registration() { + None + } else { + Some(SaveOptions::default().into()) + }, })), hover_provider: Some(HoverProviderCapability::Simple(true)), completion_provider: Some(CompletionOptions { From 97252d3747161635253ec7fefa413c2843be5321 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Mon, 8 Dec 2025 22:31:55 +0100 Subject: [PATCH 0640/3801] Remove from `MetaItemParser::from_attr` --- compiler/rustc_attr_parsing/src/interface.rs | 21 ++++++++++---------- compiler/rustc_attr_parsing/src/parser.rs | 18 +---------------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 5eefce75ace2..45b46803419d 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::convert::identity; use rustc_ast as ast; use rustc_ast::token::DocFragmentKind; @@ -13,7 +14,7 @@ use rustc_session::lint::BuiltinLintDiag; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage}; -use crate::parser::{ArgParser, MetaItemParser, PathParser}; +use crate::parser::{ArgParser, PathParser}; use crate::session_diagnostics::ParsedDescription; use crate::{Early, Late, OmitDoc, ShouldEmit}; @@ -144,22 +145,23 @@ impl<'sess> AttributeParser<'sess, Early> { }; let parts = normal_attr.item.path.segments.iter().map(|seg| seg.ident.name).collect::>(); - let meta_parser = MetaItemParser::from_attr(normal_attr, &parts, &sess.psess, emit_errors)?; - let path = meta_parser.path(); - let args = meta_parser.args(); + + let path = AttrPath::from_ast(&normal_attr.item.path, identity); + let args = + ArgParser::from_attr_args(&normal_attr.item.args, &parts, &sess.psess, emit_errors)?; Self::parse_single_args( sess, attr.span, normal_attr.item.span(), attr.style, - path.get_attribute_path(), + path, Some(normal_attr.item.unsafety), ParsedDescription::Attribute, target_span, target_node_id, features, emit_errors, - args, + &args, parse_fn, template, ) @@ -316,15 +318,14 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { n.item.path.segments.iter().map(|seg| seg.ident.name).collect::>(); if let Some(accepts) = S::parsers().accepters.get(parts.as_slice()) { - let Some(parser) = MetaItemParser::from_attr( - n, + let Some(args) = ArgParser::from_attr_args( + &n.item.args, &parts, &self.sess.psess, self.stage.should_emit(), ) else { continue; }; - let args = parser.args(); // Special-case handling for `#[doc = "..."]`: if we go through with // `DocParser`, the order of doc comments will be messed up because `///` @@ -373,7 +374,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attr_path: attr_path.clone(), }; - (accept.accept_fn)(&mut cx, args); + (accept.accept_fn)(&mut cx, &args); if !matches!(cx.stage.should_emit(), ShouldEmit::Nothing) { Self::check_target(&accept.allowed_targets, target, &mut cx); } diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 819e5630561d..2304fb0ca63c 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -8,7 +8,7 @@ use std::fmt::{Debug, Display}; use rustc_ast::token::{self, Delimiter, MetaVarKind}; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path, StmtKind, UnOp}; +use rustc_ast::{AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, Path, StmtKind, UnOp}; use rustc_ast_pretty::pprust; use rustc_errors::{Diag, PResult}; use rustc_hir::{self as hir, AttrPath}; @@ -252,22 +252,6 @@ impl<'a> Debug for MetaItemParser<'a> { } } -impl<'a> MetaItemParser<'a> { - /// Create a new parser from a [`NormalAttr`], which is stored inside of any - /// [`ast::Attribute`](rustc_ast::Attribute) - pub fn from_attr<'sess>( - attr: &'a NormalAttr, - parts: &[Symbol], - psess: &'sess ParseSess, - should_emit: ShouldEmit, - ) -> Option { - Some(Self { - path: PathParser(Cow::Borrowed(&attr.item.path)), - args: ArgParser::from_attr_args(&attr.item.args, parts, psess, should_emit)?, - }) - } -} - impl<'a> MetaItemParser<'a> { pub fn span(&self) -> Span { if let Some(other) = self.args.span() { From 86a97c41cbfae596cad6e6e9191c414e7a77a520 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Mon, 8 Dec 2025 22:48:13 +0100 Subject: [PATCH 0641/3801] Remove lifetime param from parser types --- .../src/attributes/allow_unstable.rs | 8 +- .../rustc_attr_parsing/src/attributes/cfg.rs | 8 +- .../src/attributes/codegen_attrs.rs | 18 ++-- .../src/attributes/crate_level.rs | 12 +-- .../src/attributes/debugger.rs | 2 +- .../src/attributes/deprecation.rs | 4 +- .../src/attributes/dummy.rs | 2 +- .../src/attributes/inline.rs | 4 +- .../src/attributes/link_attrs.rs | 22 ++--- .../src/attributes/macro_attrs.rs | 2 +- .../rustc_attr_parsing/src/attributes/mod.rs | 8 +- .../src/attributes/must_use.rs | 2 +- .../rustc_attr_parsing/src/attributes/path.rs | 2 +- .../src/attributes/proc_macro_attrs.rs | 6 +- .../src/attributes/prototype.rs | 4 +- .../rustc_attr_parsing/src/attributes/repr.rs | 21 ++--- .../src/attributes/rustc_internal.rs | 8 +- .../src/attributes/stability.rs | 6 +- .../src/attributes/test_attrs.rs | 4 +- .../src/attributes/traits.rs | 2 +- .../src/attributes/transparency.rs | 2 +- .../rustc_attr_parsing/src/attributes/util.rs | 2 +- compiler/rustc_attr_parsing/src/context.rs | 6 +- compiler/rustc_attr_parsing/src/interface.rs | 9 +- compiler/rustc_attr_parsing/src/parser.rs | 83 ++++++++++--------- 25 files changed, 119 insertions(+), 128 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index 088fa73d7427..faa366a62831 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -19,7 +19,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser { fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator { parse_unstable(cx, args, >::PATH[0]) .into_iter() @@ -41,7 +41,7 @@ impl CombineAttributeParser for UnstableFeatureBoundParser { fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator { if !cx.features().staged_api() { cx.emit_err(session_diagnostics::StabilityOutsideStd { span: cx.attr_span }); @@ -69,7 +69,7 @@ impl CombineAttributeParser for AllowConstFnUnstableParser { fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator + 'c { parse_unstable(cx, args, >::PATH[0]) } @@ -77,7 +77,7 @@ impl CombineAttributeParser for AllowConstFnUnstableParser { fn parse_unstable( cx: &AcceptContext<'_, '_, S>, - args: &ArgParser<'_>, + args: &ArgParser, symbol: Symbol, ) -> impl IntoIterator { let mut res = Vec::new(); diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 6ffe25098308..61c314b41b65 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -37,7 +37,7 @@ const CFG_ATTR_TEMPLATE: AttributeTemplate = template!( pub fn parse_cfg<'c, S: Stage>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> Option { let ArgParser::List(list) = args else { cx.expected_list(cx.attr_span); @@ -52,7 +52,7 @@ pub fn parse_cfg<'c, S: Stage>( pub fn parse_cfg_entry( cx: &mut AcceptContext<'_, '_, S>, - item: &MetaItemOrLitParser<'_>, + item: &MetaItemOrLitParser, ) -> Result { Ok(match item { MetaItemOrLitParser::MetaItemParser(meta) => match meta.args() { @@ -98,7 +98,7 @@ pub fn parse_cfg_entry( fn parse_cfg_entry_version( cx: &mut AcceptContext<'_, '_, S>, - list: &MetaItemListParser<'_>, + list: &MetaItemListParser, meta_span: Span, ) -> Result { try_gate_cfg(sym::version, meta_span, cx.sess(), cx.features_option()); @@ -130,7 +130,7 @@ fn parse_cfg_entry_version( fn parse_cfg_entry_target( cx: &mut AcceptContext<'_, '_, S>, - list: &MetaItemListParser<'_>, + list: &MetaItemListParser, meta_span: Span, ) -> Result { if let Some(features) = cx.features_option() diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index b4ecbe6e4de6..ce208203ec5e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -23,7 +23,7 @@ impl SingleAttributeParser for OptimizeParser { ]); const TEMPLATE: AttributeTemplate = template!(List: &["size", "speed", "none"]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(list) = args.list() else { cx.expected_list(cx.attr_span); return None; @@ -84,7 +84,7 @@ impl SingleAttributeParser for CoverageParser { ]); const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::off, sym::on]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(args) = args.list() else { cx.expected_specific_argument_and_list(cx.attr_span, &[sym::on, sym::off]); return None; @@ -135,7 +135,7 @@ impl SingleAttributeParser for ExportNameParser { ]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(nv) = args.name_value() else { cx.expected_name_value(cx.attr_span, None); return None; @@ -164,7 +164,7 @@ impl SingleAttributeParser for ObjcClassParser { AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName"); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(nv) = args.name_value() else { cx.expected_name_value(cx.attr_span, None); return None; @@ -196,7 +196,7 @@ impl SingleAttributeParser for ObjcSelectorParser { AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName"); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(nv) = args.name_value() else { cx.expected_name_value(cx.attr_span, None); return None; @@ -474,7 +474,7 @@ impl AttributeParser for UsedParser { fn parse_tf_attribute<'c, S: Stage>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator + 'c { let mut features = Vec::new(); let ArgParser::List(list) = args else { @@ -531,7 +531,7 @@ impl CombineAttributeParser for TargetFeatureParser { fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator + 'c { parse_tf_attribute(cx, args) } @@ -569,7 +569,7 @@ impl CombineAttributeParser for ForceTargetFeatureParser { fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator + 'c { parse_tf_attribute(cx, args) } @@ -599,7 +599,7 @@ impl SingleAttributeParser for SanitizeParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(list) = args.list() else { cx.expected_list(cx.attr_span); return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 480a32658bc5..01c503357fc7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -11,7 +11,7 @@ impl SingleAttributeParser for CrateNameParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(n) = args else { cx.expected_name_value(cx.attr_span, None); return None; @@ -35,7 +35,7 @@ impl SingleAttributeParser for RecursionLimitParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(nv) = args else { cx.expected_name_value(cx.attr_span, None); return None; @@ -58,7 +58,7 @@ impl SingleAttributeParser for MoveSizeLimitParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(nv) = args else { cx.expected_name_value(cx.attr_span, None); return None; @@ -81,7 +81,7 @@ impl SingleAttributeParser for TypeLengthLimitParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(nv) = args else { cx.expected_name_value(cx.attr_span, None); return None; @@ -104,7 +104,7 @@ impl SingleAttributeParser for PatternComplexityLimitParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(nv) = args else { cx.expected_name_value(cx.attr_span, None); return None; @@ -154,7 +154,7 @@ impl SingleAttributeParser for WindowsSubsystemParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute"); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(nv) = args.name_value() else { cx.expected_name_value( args.span().unwrap_or(cx.inner_span), diff --git a/compiler/rustc_attr_parsing/src/attributes/debugger.rs b/compiler/rustc_attr_parsing/src/attributes/debugger.rs index 56ff10be4264..dfb3b914e189 100644 --- a/compiler/rustc_attr_parsing/src/attributes/debugger.rs +++ b/compiler/rustc_attr_parsing/src/attributes/debugger.rs @@ -18,7 +18,7 @@ impl CombineAttributeParser for DebuggerViualizerParser { fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator + 'c { let Some(l) = args.list() else { cx.expected_list(args.span().unwrap_or(cx.attr_span)); diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs index f96477e28cd0..ad3e2ced60c7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs +++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs @@ -12,7 +12,7 @@ fn get( cx: &AcceptContext<'_, '_, S>, name: Symbol, param_span: Span, - arg: &ArgParser<'_>, + arg: &ArgParser, item: &Option, ) -> Option { if item.is_some() { @@ -68,7 +68,7 @@ impl SingleAttributeParser for DeprecationParser { NameValueStr: "reason" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let features = cx.features(); let mut since = None; diff --git a/compiler/rustc_attr_parsing/src/attributes/dummy.rs b/compiler/rustc_attr_parsing/src/attributes/dummy.rs index 7293cee842c2..0a7d95f31799 100644 --- a/compiler/rustc_attr_parsing/src/attributes/dummy.rs +++ b/compiler/rustc_attr_parsing/src/attributes/dummy.rs @@ -15,7 +15,7 @@ impl SingleAttributeParser for DummyParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really - fn convert(_: &mut AcceptContext<'_, '_, S>, _: &ArgParser<'_>) -> Option { + fn convert(_: &mut AcceptContext<'_, '_, S>, _: &ArgParser) -> Option { Some(AttributeKind::Dummy) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index fba1a663c057..f6aab9ea0ee2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -34,7 +34,7 @@ impl SingleAttributeParser for InlineParser { "https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { match args { ArgParser::NoArgs => Some(AttributeKind::Inline(InlineAttr::Hint, cx.attr_span)), ArgParser::List(list) => { @@ -77,7 +77,7 @@ impl SingleAttributeParser for RustcForceInlineParser { const TEMPLATE: AttributeTemplate = template!(Word, List: &["reason"], NameValueStr: "reason"); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let reason = match args { ArgParser::NoArgs => None, ArgParser::List(list) => { diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 46fa8ee71343..67471e31b105 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -33,7 +33,7 @@ impl SingleAttributeParser for LinkNameParser { "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_name-attribute" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(nv) = args.name_value() else { cx.expected_name_value(cx.attr_span, None); return None; @@ -64,7 +64,7 @@ impl CombineAttributeParser for LinkParser { fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator + 'c { let items = match args { ArgParser::List(list) => list, @@ -242,7 +242,7 @@ impl CombineAttributeParser for LinkParser { impl LinkParser { fn parse_link_name( - item: &MetaItemParser<'_>, + item: &MetaItemParser, name: &mut Option<(Symbol, Span)>, cx: &mut AcceptContext<'_, '_, S>, ) -> bool { @@ -267,7 +267,7 @@ impl LinkParser { } fn parse_link_kind( - item: &MetaItemParser<'_>, + item: &MetaItemParser, kind: &mut Option, cx: &mut AcceptContext<'_, '_, S>, sess: &Session, @@ -347,7 +347,7 @@ impl LinkParser { } fn parse_link_modifiers( - item: &MetaItemParser<'_>, + item: &MetaItemParser, modifiers: &mut Option<(Symbol, Span)>, cx: &mut AcceptContext<'_, '_, S>, ) -> bool { @@ -368,7 +368,7 @@ impl LinkParser { } fn parse_link_cfg( - item: &MetaItemParser<'_>, + item: &MetaItemParser, cfg: &mut Option, cx: &mut AcceptContext<'_, '_, S>, sess: &Session, @@ -400,7 +400,7 @@ impl LinkParser { } fn parse_link_wasm_import_module( - item: &MetaItemParser<'_>, + item: &MetaItemParser, wasm_import_module: &mut Option<(Symbol, Span)>, cx: &mut AcceptContext<'_, '_, S>, ) -> bool { @@ -421,7 +421,7 @@ impl LinkParser { } fn parse_link_import_name_type( - item: &MetaItemParser<'_>, + item: &MetaItemParser, import_name_type: &mut Option<(PeImportNameType, Span)>, cx: &mut AcceptContext<'_, '_, S>, ) -> bool { @@ -478,7 +478,7 @@ impl SingleAttributeParser for LinkSectionParser { "https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(nv) = args.name_value() else { cx.expected_name_value(cx.attr_span, None); return None; @@ -551,7 +551,7 @@ impl SingleAttributeParser for LinkOrdinalParser { "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_ordinal-attribute" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ordinal = parse_single_integer(cx, args)?; // According to the table at @@ -607,7 +607,7 @@ impl SingleAttributeParser for LinkageParser { "weak_odr", ]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(name_value) = args.name_value() else { cx.expected_name_value(cx.attr_span, Some(sym::linkage)); return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index d2fa1d440f40..e4209c3edd85 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -148,7 +148,7 @@ impl SingleAttributeParser for MacroExportParser { Error(Target::Crate), ]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let local_inner_macros = match args { ArgParser::NoArgs => false, ArgParser::List(list) => { diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 64bcb02b0b74..a26159cb09e7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -62,7 +62,7 @@ pub(crate) mod traits; pub(crate) mod transparency; pub(crate) mod util; -type AcceptFn = for<'sess> fn(&mut T, &mut AcceptContext<'_, 'sess, S>, &ArgParser<'_>); +type AcceptFn = for<'sess> fn(&mut T, &mut AcceptContext<'_, 'sess, S>, &ArgParser); type AcceptMapping = &'static [(&'static [Symbol], AttributeTemplate, AcceptFn)]; /// An [`AttributeParser`] is a type which searches for syntactic attributes. @@ -133,7 +133,7 @@ pub(crate) trait SingleAttributeParser: 'static { const TEMPLATE: AttributeTemplate; /// Converts a single syntactical attribute to a single semantic attribute, or [`AttributeKind`] - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option; + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option; } /// Use in combination with [`SingleAttributeParser`]. @@ -282,7 +282,7 @@ impl, S: Stage> SingleAttributeParser for Without const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; const TEMPLATE: AttributeTemplate = template!(Word); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { if let Err(span) = args.no_args() { cx.expected_no_args(span); } @@ -317,7 +317,7 @@ pub(crate) trait CombineAttributeParser: 'static { /// Converts a single syntactical attribute to a number of elements of the semantic attribute, or [`AttributeKind`] fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator + 'c; } diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index 51b43e96adf9..a27e1ecb707e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs @@ -29,7 +29,7 @@ impl SingleAttributeParser for MustUseParser { "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { Some(AttributeKind::MustUse { span: cx.attr_span, reason: match args { diff --git a/compiler/rustc_attr_parsing/src/attributes/path.rs b/compiler/rustc_attr_parsing/src/attributes/path.rs index e4cb806bb427..b60f8e315e5e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/path.rs +++ b/compiler/rustc_attr_parsing/src/attributes/path.rs @@ -13,7 +13,7 @@ impl SingleAttributeParser for PathParser { "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(nv) = args.name_value() else { cx.expected_name_value(cx.attr_span, None); return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs index b9929d6f1f8e..e1762005d4c4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs @@ -30,7 +30,7 @@ impl SingleAttributeParser for ProcMacroDeriveParser { "https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let (trait_name, helper_attrs) = parse_derive_like(cx, args, true)?; Some(AttributeKind::ProcMacroDerive { trait_name: trait_name.expect("Trait name is mandatory, so it is present"), @@ -49,7 +49,7 @@ impl SingleAttributeParser for RustcBuiltinMacroParser { const TEMPLATE: AttributeTemplate = template!(List: &["TraitName", "TraitName, attributes(name1, name2, ...)"]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let (builtin_name, helper_attrs) = parse_derive_like(cx, args, false)?; Some(AttributeKind::RustcBuiltinMacro { builtin_name, helper_attrs, span: cx.attr_span }) } @@ -57,7 +57,7 @@ impl SingleAttributeParser for RustcBuiltinMacroParser { fn parse_derive_like( cx: &mut AcceptContext<'_, '_, S>, - args: &ArgParser<'_>, + args: &ArgParser, trait_name_mandatory: bool, ) -> Option<(Option, ThinVec)> { let Some(list) = args.list() else { diff --git a/compiler/rustc_attr_parsing/src/attributes/prototype.rs b/compiler/rustc_attr_parsing/src/attributes/prototype.rs index 80fe82bf5429..cd7c84f45fe5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prototype.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prototype.rs @@ -25,7 +25,7 @@ impl SingleAttributeParser for CustomMirParser { const TEMPLATE: AttributeTemplate = template!(List: &[r#"dialect = "...", phase = "...""#]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(list) = args.list() else { cx.expected_list(cx.attr_span); return None; @@ -70,7 +70,7 @@ impl SingleAttributeParser for CustomMirParser { fn extract_value( cx: &mut AcceptContext<'_, '_, S>, key: Symbol, - arg: &ArgParser<'_>, + arg: &ArgParser, span: Span, out_val: &mut Option<(Symbol, Span)>, failed: &mut bool, diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 0330e2515c7d..c7320bf5d96f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -28,7 +28,7 @@ impl CombineAttributeParser for ReprParser { fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + args: &'c ArgParser, ) -> impl IntoIterator + 'c { let mut reprs = Vec::new(); @@ -98,10 +98,7 @@ fn int_type_of_word(s: Symbol) -> Option { } } -fn parse_repr( - cx: &AcceptContext<'_, '_, S>, - param: &MetaItemParser<'_>, -) -> Option { +fn parse_repr(cx: &AcceptContext<'_, '_, S>, param: &MetaItemParser) -> Option { use ReprAttr::*; // FIXME(jdonszelmann): invert the parsing here to match on the word first and then the @@ -192,7 +189,7 @@ enum AlignKind { fn parse_repr_align( cx: &AcceptContext<'_, '_, S>, - list: &MetaItemListParser<'_>, + list: &MetaItemListParser, param_span: Span, align_kind: AlignKind, ) -> Option { @@ -278,11 +275,7 @@ impl AlignParser { const PATH: &'static [Symbol] = &[sym::rustc_align]; const TEMPLATE: AttributeTemplate = template!(List: &[""]); - fn parse<'c, S: Stage>( - &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, - ) { + fn parse<'c, S: Stage>(&mut self, cx: &'c mut AcceptContext<'_, '_, S>, args: &'c ArgParser) { match args { ArgParser::NoArgs | ArgParser::NameValue(_) => { cx.expected_list(cx.attr_span); @@ -339,11 +332,7 @@ impl AlignStaticParser { const PATH: &'static [Symbol] = &[sym::rustc_align_static]; const TEMPLATE: AttributeTemplate = AlignParser::TEMPLATE; - fn parse<'c, S: Stage>( - &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, - ) { + fn parse<'c, S: Stage>(&mut self, cx: &'c mut AcceptContext<'_, '_, S>, args: &'c ArgParser) { self.0.parse(cx, args) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 455c61097d78..d51fa2510b93 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -19,7 +19,7 @@ impl SingleAttributeParser for RustcLayoutScalarValidRangeStartPars const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(List: &["start"]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { parse_single_integer(cx, args) .map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(Box::new(n), cx.attr_span)) } @@ -34,7 +34,7 @@ impl SingleAttributeParser for RustcLayoutScalarValidRangeEndParser const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(List: &["end"]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { parse_single_integer(cx, args) .map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(Box::new(n), cx.attr_span)) } @@ -49,7 +49,7 @@ impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(Word); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { if let Err(span) = args.no_args() { cx.expected_no_args(span); return None; @@ -68,7 +68,7 @@ impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(nv) = args else { cx.expected_name_value(cx.attr_span, None); return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index b94e23477ffe..b3ebb0f4fec1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -267,7 +267,7 @@ impl AttributeParser for ConstStabilityParser { /// `name = value` fn insert_value_into_option_or_error( cx: &AcceptContext<'_, '_, S>, - param: &MetaItemParser<'_>, + param: &MetaItemParser, item: &mut Option, name: Ident, ) -> Option<()> { @@ -289,7 +289,7 @@ fn insert_value_into_option_or_error( /// its stability information. pub(crate) fn parse_stability( cx: &AcceptContext<'_, '_, S>, - args: &ArgParser<'_>, + args: &ArgParser, ) -> Option<(Symbol, StabilityLevel)> { let mut feature = None; let mut since = None; @@ -365,7 +365,7 @@ pub(crate) fn parse_stability( /// attribute, and return the feature name and its stability information. pub(crate) fn parse_unstability( cx: &AcceptContext<'_, '_, S>, - args: &ArgParser<'_>, + args: &ArgParser, ) -> Option<(Symbol, StabilityLevel)> { let mut feature = None; let mut reason = None; diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index e0b006030758..7f25641b948e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -15,7 +15,7 @@ impl SingleAttributeParser for IgnoreParser { "https://doc.rust-lang.org/reference/attributes/testing.html#the-ignore-attribute" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { Some(AttributeKind::Ignore { span: cx.attr_span, reason: match args { @@ -49,7 +49,7 @@ impl SingleAttributeParser for ShouldPanicParser { "https://doc.rust-lang.org/reference/attributes/testing.html#the-should_panic-attribute" ); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { Some(AttributeKind::ShouldPanic { span: cx.attr_span, reason: match args { diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index 753892d1e997..a9b76021a989 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -18,7 +18,7 @@ impl SingleAttributeParser for SkipDuringMethodDispatchParser { const TEMPLATE: AttributeTemplate = template!(List: &["array, boxed_slice"]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let mut array = false; let mut boxed_slice = false; let Some(args) = args.list() else { diff --git a/compiler/rustc_attr_parsing/src/attributes/transparency.rs b/compiler/rustc_attr_parsing/src/attributes/transparency.rs index ea1f5549c4ec..52aa42b1085a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/transparency.rs +++ b/compiler/rustc_attr_parsing/src/attributes/transparency.rs @@ -17,7 +17,7 @@ impl SingleAttributeParser for TransparencyParser { const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["transparent", "semitransparent", "opaque"]); - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(nv) = args.name_value() else { cx.expected_name_value(cx.attr_span, None); return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs index 105f7164bf3b..4e3478abbf4f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/util.rs +++ b/compiler/rustc_attr_parsing/src/attributes/util.rs @@ -40,7 +40,7 @@ pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { /// `args` is the parser for the attribute arguments. pub(crate) fn parse_single_integer( cx: &mut AcceptContext<'_, '_, S>, - args: &ArgParser<'_>, + args: &ArgParser, ) -> Option { let Some(list) = args.list() else { cx.expected_list(cx.attr_span); diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index f41ea3708788..074f3b4194ae 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -75,7 +75,7 @@ use crate::attributes::traits::{ }; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; -use crate::parser::{ArgParser, PathParser}; +use crate::parser::{ArgParser, RefPathParser}; use crate::session_diagnostics::{ AttributeParseError, AttributeParseErrorReason, ParsedDescription, UnknownMetaItem, }; @@ -95,7 +95,7 @@ pub(super) struct GroupTypeInnerAccept { } type AcceptFn = - Box Fn(&mut AcceptContext<'_, 'sess, S>, &ArgParser<'a>) + Send + Sync>; + Box Fn(&mut AcceptContext<'_, 'sess, S>, &ArgParser) + Send + Sync>; type FinalizeFn = Box) -> Option>; @@ -713,7 +713,7 @@ pub(crate) struct FinalizeContext<'p, 'sess, S: Stage> { /// /// Usually, you should use normal attribute parsing logic instead, /// especially when making a *denylist* of other attributes. - pub(crate) all_attrs: &'p [PathParser<'p>], + pub(crate) all_attrs: &'p [RefPathParser<'p>], } impl<'p, 'sess: 'p, S: Stage> Deref for FinalizeContext<'p, 'sess, S> { diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 45b46803419d..732f8d6e3a2a 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -1,4 +1,3 @@ -use std::borrow::Cow; use std::convert::identity; use rustc_ast as ast; @@ -14,7 +13,7 @@ use rustc_session::lint::BuiltinLintDiag; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage}; -use crate::parser::{ArgParser, PathParser}; +use crate::parser::{ArgParser, PathParser, RefPathParser}; use crate::session_diagnostics::ParsedDescription; use crate::{Early, Late, OmitDoc, ShouldEmit}; @@ -137,7 +136,7 @@ impl<'sess> AttributeParser<'sess, Early> { target_node_id: NodeId, features: Option<&'sess Features>, emit_errors: ShouldEmit, - parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser<'_>) -> Option, + parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser) -> Option, template: &AttributeTemplate, ) -> Option { let ast::AttrKind::Normal(normal_attr) = &attr.kind else { @@ -269,7 +268,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { mut emit_lint: impl FnMut(AttributeLint), ) -> Vec { let mut attributes = Vec::new(); - let mut attr_paths = Vec::new(); + let mut attr_paths: Vec> = Vec::new(); for attr in attrs { // If we're only looking for a single attribute, skip all the ones we don't care about. @@ -303,7 +302,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { })) } ast::AttrKind::Normal(n) => { - attr_paths.push(PathParser(Cow::Borrowed(&n.item.path))); + attr_paths.push(PathParser(&n.item.path)); let attr_path = AttrPath::from_ast(&n.item.path, lower_span); self.check_attribute_safety( diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 2304fb0ca63c..09ecfaedb5ed 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -3,7 +3,7 @@ //! //! FIXME(jdonszelmann): delete `rustc_ast/attr/mod.rs` -use std::borrow::Cow; +use std::borrow::Borrow; use std::fmt::{Debug, Display}; use rustc_ast::token::{self, Delimiter, MetaVarKind}; @@ -26,9 +26,12 @@ use crate::session_diagnostics::{ }; #[derive(Clone, Debug)] -pub struct PathParser<'a>(pub Cow<'a, Path>); +pub struct PathParser>(pub P); -impl<'a> PathParser<'a> { +pub type OwnedPathParser = PathParser; +pub type RefPathParser<'p> = PathParser<&'p Path>; + +impl> PathParser

{ pub fn get_attribute_path(&self) -> hir::AttrPath { AttrPath { segments: self.segments().copied().collect::>().into_boxed_slice(), @@ -36,16 +39,16 @@ impl<'a> PathParser<'a> { } } - pub fn segments(&'a self) -> impl Iterator { - self.0.segments.iter().map(|seg| &seg.ident) + pub fn segments(&self) -> impl Iterator { + self.0.borrow().segments.iter().map(|seg| &seg.ident) } pub fn span(&self) -> Span { - self.0.span + self.0.borrow().span } pub fn len(&self) -> usize { - self.0.segments.len() + self.0.borrow().segments.len() } pub fn segments_is(&self, segments: &[Symbol]) -> bool { @@ -76,21 +79,21 @@ impl<'a> PathParser<'a> { } } -impl Display for PathParser<'_> { +impl> Display for PathParser

+/// This type is not properly implemented yet, and the documentation below is thus not accurate. +///
+/// +/// That is, if a reference (or a `Box`) is wrapped in `MaybeDangling` (including when in a +/// (nested) field of a compound type wrapped in `MaybeDangling`), it does not have to follow +/// pointer aliasing rules or be dereferenceable. +/// +/// This can be useful when the value can become dangling while the function holding it is still +/// executing (particularly in concurrent code). As a somewhat absurd example, consider this code: +/// +/// ```rust,no_run +/// #![feature(box_as_ptr)] +/// # use std::alloc::{dealloc, Layout}; +/// # use std::mem; +/// +/// let mut boxed = Box::new(0_u32); +/// let ptr = Box::as_mut_ptr(&mut boxed); +/// +/// // Safety: the pointer comes from a box and thus was allocated before; `box` is not used afterwards +/// unsafe { dealloc(ptr.cast(), Layout::new::()) }; +/// +/// mem::forget(boxed); // <-- this is UB! +/// ``` +/// +/// Even though the `Box`e's destructor is not run (and thus we don't have a double free bug), this +/// code is still UB. This is because when moving `boxed` into `forget`, its validity invariants +/// are asserted, causing UB since the `Box` is dangling. The safety comment is as such wrong, as +/// moving the `boxed` variable as part of the `forget` call *is* a use. +/// +/// To fix this we could use `MaybeDangling`: +/// +/// ```rust +/// #![feature(maybe_dangling, box_as_ptr)] +/// # use std::alloc::{dealloc, Layout}; +/// # use std::mem::{self, MaybeDangling}; +/// +/// let mut boxed = MaybeDangling::new(Box::new(0_u32)); +/// let ptr = Box::as_mut_ptr(boxed.as_mut()); +/// +/// // Safety: the pointer comes from a box and thus was allocated before; `box` is not used afterwards +/// unsafe { dealloc(ptr.cast(), Layout::new::()) }; +/// +/// mem::forget(boxed); // <-- this is OK! +/// ``` +/// +/// Note that the bit pattern must still be valid for the wrapped type. That is, [references] +/// (and [boxes]) still must be aligned and non-null. +/// +/// Additionally note that safe code can still assume that the inner value in a `MaybeDangling` is +/// **not** dangling -- functions like [`as_ref`] and [`into_inner`] are safe. It is not sound to +/// return a dangling reference in a `MaybeDangling` to safe code. However, it *is* sound +/// to hold such values internally inside your code -- and there's no way to do that without +/// this type. Note that other types can use this type and thus get the same effect; in particular, +/// [`ManuallyDrop`] will use `MaybeDangling`. +/// +/// Note that `MaybeDangling` doesn't prevent drops from being run, which can lead to UB if the +/// drop observes a dangling value. If you need to prevent drops from being run use [`ManuallyDrop`] +/// instead. +/// +/// [references]: prim@reference +/// [boxes]: ../../std/boxed/struct.Box.html +/// [`into_inner`]: MaybeDangling::into_inner +/// [`as_ref`]: MaybeDangling::as_ref +/// [`ManuallyDrop`]: crate::mem::ManuallyDrop +#[repr(transparent)] +#[rustc_pub_transparent] +#[derive(Debug, Copy, Clone, Default)] +pub struct MaybeDangling(P); + +impl MaybeDangling

{ + /// Wraps a value in a `MaybeDangling`, allowing it to dangle. + pub const fn new(x: P) -> Self + where + P: Sized, + { + MaybeDangling(x) + } + + /// Returns a reference to the inner value. + /// + /// Note that this is UB if the inner value is currently dangling. + pub const fn as_ref(&self) -> &P { + &self.0 + } + + /// Returns a mutable reference to the inner value. + /// + /// Note that this is UB if the inner value is currently dangling. + pub const fn as_mut(&mut self) -> &mut P { + &mut self.0 + } + + /// Extracts the value from the `MaybeDangling` container. + /// + /// Note that this is UB if the inner value is currently dangling. + pub const fn into_inner(self) -> P + where + P: Sized, + { + // FIXME: replace this with `self.0` when const checker can figure out that `self` isn't actually dropped + // SAFETY: this is equivalent to `self.0` + let x = unsafe { ptr::read(&self.0) }; + mem::forget(self); + x + } +} diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index ad5fda0cfe4d..4f7edce1e977 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -19,6 +19,10 @@ mod maybe_uninit; #[stable(feature = "maybe_uninit", since = "1.36.0")] pub use maybe_uninit::MaybeUninit; +mod maybe_dangling; +#[unstable(feature = "maybe_dangling", issue = "118166")] +pub use maybe_dangling::MaybeDangling; + mod transmutability; #[unstable(feature = "transmutability", issue = "99571")] pub use transmutability::{Assume, TransmuteFrom}; From 722e3102a22c529bade40c61f63bb3d88845360a Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Wed, 29 Oct 2025 19:26:26 +0100 Subject: [PATCH 0967/3801] use `MaybeDangling` in `ManuallyDrop` --- library/core/src/mem/manually_drop.rs | 55 ++++++++++++++++--- .../future-sizes/async-awaiting-fut.stdout | 8 +++ .../async-await/future-sizes/large-arg.stdout | 6 ++ tests/ui/print_type_sizes/async.stdout | 4 ++ .../coroutine_discr_placement.stdout | 2 + tests/ui/thir-print/offset_of.stdout | 18 +++--- 6 files changed, 75 insertions(+), 18 deletions(-) diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 7d49da850957..74f917bcf1cc 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -1,4 +1,7 @@ -use crate::marker::Destruct; +use crate::cmp::Ordering; +use crate::hash::{Hash, Hasher}; +use crate::marker::{Destruct, StructuralPartialEq}; +use crate::mem::MaybeDangling; use crate::ops::{Deref, DerefMut, DerefPure}; use crate::ptr; @@ -152,11 +155,11 @@ use crate::ptr; /// [`MaybeUninit`]: crate::mem::MaybeUninit #[stable(feature = "manually_drop", since = "1.20.0")] #[lang = "manually_drop"] -#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, Debug, Default)] #[repr(transparent)] #[rustc_pub_transparent] pub struct ManuallyDrop { - value: T, + value: MaybeDangling, } impl ManuallyDrop { @@ -179,7 +182,7 @@ impl ManuallyDrop { #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")] #[inline(always)] pub const fn new(value: T) -> ManuallyDrop { - ManuallyDrop { value } + ManuallyDrop { value: MaybeDangling::new(value) } } /// Extracts the value from the `ManuallyDrop` container. @@ -197,7 +200,7 @@ impl ManuallyDrop { #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")] #[inline(always)] pub const fn into_inner(slot: ManuallyDrop) -> T { - slot.value + slot.value.into_inner() } /// Takes the value from the `ManuallyDrop` container out. @@ -222,7 +225,7 @@ impl ManuallyDrop { pub const unsafe fn take(slot: &mut ManuallyDrop) -> T { // SAFETY: we are reading from a reference, which is guaranteed // to be valid for reads. - unsafe { ptr::read(&slot.value) } + unsafe { ptr::read(slot.value.as_ref()) } } } @@ -259,7 +262,7 @@ impl ManuallyDrop { // SAFETY: we are dropping the value pointed to by a mutable reference // which is guaranteed to be valid for writes. // It is up to the caller to make sure that `slot` isn't dropped again. - unsafe { ptr::drop_in_place(&mut slot.value) } + unsafe { ptr::drop_in_place(slot.value.as_mut()) } } } @@ -269,7 +272,7 @@ impl const Deref for ManuallyDrop { type Target = T; #[inline(always)] fn deref(&self) -> &T { - &self.value + self.value.as_ref() } } @@ -278,9 +281,43 @@ impl const Deref for ManuallyDrop { impl const DerefMut for ManuallyDrop { #[inline(always)] fn deref_mut(&mut self) -> &mut T { - &mut self.value + self.value.as_mut() } } #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Eq for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl PartialEq for ManuallyDrop { + fn eq(&self, other: &Self) -> bool { + self.value.as_ref().eq(other.value.as_ref()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl StructuralPartialEq for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Ord for ManuallyDrop { + fn cmp(&self, other: &Self) -> Ordering { + self.value.as_ref().cmp(other.value.as_ref()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl PartialOrd for ManuallyDrop { + fn partial_cmp(&self, other: &Self) -> Option { + self.value.as_ref().partial_cmp(other.value.as_ref()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Hash for ManuallyDrop { + fn hash(&self, state: &mut H) { + self.value.as_ref().hash(state); + } +} diff --git a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout index b30c15bcbe6e..13f03ffa65b5 100644 --- a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout +++ b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout @@ -7,6 +7,8 @@ print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes print-type-size field `.value`: 3077 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes +print-type-size field `.0`: 3077 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 3077 bytes print-type-size field `.uninit`: 0 bytes @@ -36,6 +38,8 @@ print-type-size variant `Panicked`: 1025 bytes print-type-size upvar `.fut`: 1025 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes print-type-size field `.value`: 1025 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes +print-type-size field `.0`: 1025 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1025 bytes print-type-size field `.uninit`: 0 bytes @@ -85,6 +89,10 @@ print-type-size type: `std::mem::ManuallyDrop`: 1 bytes, alignment: 1 byte print-type-size field `.value`: 1 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes +print-type-size type: `std::mem::MaybeDangling`: 1 bytes, alignment: 1 bytes +print-type-size field `.0`: 1 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes +print-type-size field `.0`: 1 bytes print-type-size type: `std::mem::MaybeUninit`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/async-await/future-sizes/large-arg.stdout b/tests/ui/async-await/future-sizes/large-arg.stdout index e00420d1493f..d51afa33595c 100644 --- a/tests/ui/async-await/future-sizes/large-arg.stdout +++ b/tests/ui/async-await/future-sizes/large-arg.stdout @@ -7,6 +7,8 @@ print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes print-type-size field `.value`: 3075 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes +print-type-size field `.0`: 3075 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 3075 bytes print-type-size field `.uninit`: 0 bytes @@ -24,6 +26,8 @@ print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes print-type-size field `.value`: 2050 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes +print-type-size field `.0`: 2050 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 2050 bytes print-type-size field `.uninit`: 0 bytes @@ -41,6 +45,8 @@ print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes print-type-size field `.value`: 1025 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes +print-type-size field `.0`: 1025 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1025 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout index d3d6b6471c6e..d2adff80e3c9 100644 --- a/tests/ui/print_type_sizes/async.stdout +++ b/tests/ui/print_type_sizes/async.stdout @@ -12,6 +12,8 @@ print-type-size variant `Panicked`: 8192 bytes print-type-size upvar `.arg`: 8192 bytes print-type-size type: `std::mem::ManuallyDrop<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes print-type-size field `.value`: 8192 bytes +print-type-size type: `std::mem::MaybeDangling<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes +print-type-size field `.0`: 8192 bytes print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 8192 bytes print-type-size field `.uninit`: 0 bytes @@ -47,6 +49,8 @@ print-type-size type: `std::ptr::NonNull`: 8 bytes, print-type-size field `.pointer`: 8 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes +print-type-size field `.0`: 1 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout index 4ce1ce46f6e8..b51beb514ba8 100644 --- a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout +++ b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout @@ -11,6 +11,8 @@ print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes print-type-size type: `std::mem::ManuallyDrop`: 4 bytes, alignment: 4 bytes print-type-size field `.value`: 4 bytes +print-type-size type: `std::mem::MaybeDangling`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `std::mem::MaybeUninit`: 4 bytes, alignment: 4 bytes print-type-size variant `MaybeUninit`: 4 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index 846817f47528..ab924091ba7a 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -68,7 +68,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).10)) - span: $DIR/offset_of.rs:37:5: 1433:57 (#0) + span: $DIR/offset_of.rs:37:5: 1437:57 (#0) } } Stmt { @@ -117,7 +117,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).20)) - span: $DIR/offset_of.rs:38:5: 1433:57 (#0) + span: $DIR/offset_of.rs:38:5: 1437:57 (#0) } } Stmt { @@ -166,7 +166,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).30)) - span: $DIR/offset_of.rs:39:5: 1433:57 (#0) + span: $DIR/offset_of.rs:39:5: 1437:57 (#0) } } Stmt { @@ -215,7 +215,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).40)) - span: $DIR/offset_of.rs:40:5: 1433:57 (#0) + span: $DIR/offset_of.rs:40:5: 1437:57 (#0) } } Stmt { @@ -264,7 +264,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).50)) - span: $DIR/offset_of.rs:41:5: 1433:57 (#0) + span: $DIR/offset_of.rs:41:5: 1437:57 (#0) } } ] @@ -864,7 +864,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).12)) - span: $DIR/offset_of.rs:45:5: 1433:57 (#0) + span: $DIR/offset_of.rs:45:5: 1437:57 (#0) } } Stmt { @@ -913,7 +913,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).24)) - span: $DIR/offset_of.rs:46:5: 1433:57 (#0) + span: $DIR/offset_of.rs:46:5: 1437:57 (#0) } } Stmt { @@ -962,7 +962,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).36)) - span: $DIR/offset_of.rs:47:5: 1433:57 (#0) + span: $DIR/offset_of.rs:47:5: 1437:57 (#0) } } Stmt { @@ -1011,7 +1011,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).48)) - span: $DIR/offset_of.rs:48:5: 1433:57 (#0) + span: $DIR/offset_of.rs:48:5: 1437:57 (#0) } } ] From 64c1e97f32cacc482ccb35cfe20813169ef8f913 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 17 Dec 2025 23:40:38 +0200 Subject: [PATCH 0968/3801] place it all in just 2 unit tests --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 49 ++++++-------------- 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index c19f19541846..aa34fbbb53f2 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -196,6 +196,9 @@ some code. block sentence with *italics* should not be ignored. truly. git log main.. compiler foo. bar. baz +o? whatever +r? @reviewer + r? @reviewer "; let expected = " # some. heading @@ -221,6 +224,10 @@ git log main.. compiler foo. bar. baz +o? +whatever +r? @reviewer + r? @reviewer "; assert_eq!(expected, comply(original)); } @@ -247,6 +254,12 @@ do not mess with code block chars leave the text alone ``` + + handle the + indented well + +[a target]: https://example.com +[another target]: https://example.com "; let expected = "\ do not split short sentences @@ -267,43 +280,11 @@ do not mess with code block chars leave the text alone ``` -"; - assert_eq!(expected, lengthen_lines(original, 50)); -} -#[test] -fn test_prettify_prefix_spaces() { - let original = "\ - do not split - short sentences -"; - let expected = "\ - do not split short sentences -"; - assert_eq!(expected, lengthen_lines(original, 50)); -} + handle the indented well -#[test] -fn test_prettify_ignore_link_targets() { - let original = "\ [a target]: https://example.com [another target]: https://example.com "; - assert_eq!(original, lengthen_lines(original, 100)); -} - -#[test] -fn test_sembr_question_mark() { - let original = " -o? whatever -r? @reviewer - r? @reviewer -"; - let expected = " -o? -whatever -r? @reviewer - r? @reviewer -"; - assert_eq!(expected, comply(original)); + assert_eq!(expected, lengthen_lines(original, 50)); } From 82ee8b21cb66364792f4103616a2368847fb5421 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 12 Dec 2025 17:37:39 +0100 Subject: [PATCH 0969/3801] `cfg_select!`: emit parse errors in unused branches --- .../src/attributes/cfg_select.rs | 27 ++++++ .../rustc_builtin_macros/src/cfg_select.rs | 80 ++++++++++++++---- tests/ui/macros/cfg_select.rs | 83 +++++++++++++++++++ tests/ui/macros/cfg_select.stderr | 24 +++--- tests/ui/macros/cfg_select_parse_error.rs | 18 ++++ tests/ui/macros/cfg_select_parse_error.stderr | 26 ++++++ 6 files changed, 229 insertions(+), 29 deletions(-) create mode 100644 tests/ui/macros/cfg_select_parse_error.rs create mode 100644 tests/ui/macros/cfg_select_parse_error.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs index 0c0915558089..00a2d12106e7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs @@ -28,6 +28,33 @@ pub struct CfgSelectBranches { pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>, } +impl CfgSelectBranches { + /// Removes the top-most branch for which `predicate` returns `true`, + /// or the wildcard if none of the reachable branches satisfied the predicate. + pub fn pop_first_match(&mut self, predicate: F) -> Option<(TokenStream, Span)> + where + F: Fn(&CfgEntry) -> bool, + { + for (index, (cfg, _, _)) in self.reachable.iter().enumerate() { + if predicate(cfg) { + let matched = self.reachable.remove(index); + return Some((matched.1, matched.2)); + } + } + + self.wildcard.take().map(|(_, tts, span)| (tts, span)) + } + + /// Consume this value and iterate over all the `TokenStream`s that it stores. + pub fn into_iter_tts(self) -> impl Iterator { + let it1 = self.reachable.into_iter().map(|(_, tts, span)| (tts, span)); + let it2 = self.wildcard.into_iter().map(|(_, tts, span)| (tts, span)); + let it3 = self.unreachable.into_iter().map(|(_, tts, span)| (tts, span)); + + it1.chain(it2).chain(it3) + } +} + pub fn parse_cfg_select( p: &mut Parser<'_>, sess: &Session, diff --git a/compiler/rustc_builtin_macros/src/cfg_select.rs b/compiler/rustc_builtin_macros/src/cfg_select.rs index dc8077b2a1ff..f11190b28105 100644 --- a/compiler/rustc_builtin_macros/src/cfg_select.rs +++ b/compiler/rustc_builtin_macros/src/cfg_select.rs @@ -1,22 +1,65 @@ use rustc_ast::tokenstream::TokenStream; +use rustc_ast::{Expr, ast}; use rustc_attr_parsing as attr; use rustc_attr_parsing::{ CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, parse_cfg_select, }; -use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; +use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacResult, MacroExpanderResult}; use rustc_span::{Ident, Span, sym}; +use smallvec::SmallVec; use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable}; -/// Selects the first arm whose predicate evaluates to true. -fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> { - for (cfg, tt, arm_span) in branches.reachable { - if let EvalConfigResult::True = attr::eval_config_entry(&ecx.sess, &cfg) { - return Some((tt, arm_span)); - } - } +/// This intermediate structure is used to emit parse errors for the branches that are not chosen. +/// The `MacResult` instance below parses all branches, emitting any errors it encounters, but only +/// keeps the parse result for the selected branch. +struct CfgSelectResult<'cx, 'sess> { + ecx: &'cx mut ExtCtxt<'sess>, + site_span: Span, + selected_tts: TokenStream, + selected_span: Span, + other_branches: CfgSelectBranches, +} - branches.wildcard.map(|(_, tt, span)| (tt, span)) +fn tts_to_mac_result<'cx, 'sess>( + ecx: &'cx mut ExtCtxt<'sess>, + site_span: Span, + tts: TokenStream, + span: Span, +) -> Box { + match ExpandResult::from_tts(ecx, tts, site_span, span, Ident::with_dummy_span(sym::cfg_select)) + { + ExpandResult::Ready(x) => x, + _ => unreachable!("from_tts always returns Ready"), + } +} + +macro_rules! forward_to_parser_any_macro { + ($method_name:ident, $ret_ty:ty) => { + fn $method_name(self: Box) -> Option<$ret_ty> { + let CfgSelectResult { ecx, site_span, selected_tts, selected_span, .. } = *self; + + for (tts, span) in self.other_branches.into_iter_tts() { + let _ = tts_to_mac_result(ecx, site_span, tts, span).$method_name(); + } + + tts_to_mac_result(ecx, site_span, selected_tts, selected_span).$method_name() + } + }; +} + +impl<'cx, 'sess> MacResult for CfgSelectResult<'cx, 'sess> { + forward_to_parser_any_macro!(make_expr, Box); + forward_to_parser_any_macro!(make_stmts, SmallVec<[ast::Stmt; 1]>); + forward_to_parser_any_macro!(make_items, SmallVec<[Box; 1]>); + + forward_to_parser_any_macro!(make_impl_items, SmallVec<[Box; 1]>); + forward_to_parser_any_macro!(make_trait_impl_items, SmallVec<[Box; 1]>); + forward_to_parser_any_macro!(make_trait_items, SmallVec<[Box; 1]>); + forward_to_parser_any_macro!(make_foreign_items, SmallVec<[Box; 1]>); + + forward_to_parser_any_macro!(make_ty, Box); + forward_to_parser_any_macro!(make_pat, Box); } pub(super) fn expand_cfg_select<'cx>( @@ -31,7 +74,7 @@ pub(super) fn expand_cfg_select<'cx>( Some(ecx.ecfg.features), ecx.current_expansion.lint_node_id, ) { - Ok(branches) => { + Ok(mut branches) => { if let Some((underscore, _, _)) = branches.wildcard { // Warn for every unreachable predicate. We store the fully parsed branch for rustfmt. for (predicate, _, _) in &branches.unreachable { @@ -44,14 +87,17 @@ pub(super) fn expand_cfg_select<'cx>( } } - if let Some((tts, arm_span)) = select_arm(ecx, branches) { - return ExpandResult::from_tts( + if let Some((selected_tts, selected_span)) = branches.pop_first_match(|cfg| { + matches!(attr::eval_config_entry(&ecx.sess, cfg), EvalConfigResult::True) + }) { + let mac = CfgSelectResult { ecx, - tts, - sp, - arm_span, - Ident::with_dummy_span(sym::cfg_select), - ); + selected_tts, + selected_span, + other_branches: branches, + site_span: sp, + }; + return ExpandResult::Ready(Box::new(mac)); } else { // Emit a compiler error when none of the predicates matched. let guar = ecx.dcx().emit_err(CfgSelectNoMatches { span: sp }); diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index 9fc680307025..2369158ba82a 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -47,6 +47,89 @@ fn arm_rhs_expr_3() -> i32 { } } +fn expand_to_statements() -> i32 { + cfg_select! { + true => { + let a = 1; + a + 1 + } + false => { + let b = 2; + b + 1 + } + } +} + +type ExpandToType = cfg_select! { + unix => u32, + _ => i32, +}; + +fn expand_to_pattern(x: Option) -> bool { + match x { + (cfg_select! { + unix => Some(n), + _ => None, + }) => true, + _ => false, + } +} + +cfg_select! { + true => { + fn foo() {} + } + _ => { + fn bar() {} + } +} + +struct S; + +impl S { + cfg_select! { + true => { + fn foo() {} + } + _ => { + fn bar() {} + } + } +} + +trait T { + cfg_select! { + true => { + fn a(); + } + _ => { + fn b(); + } + } +} + +impl T for S { + cfg_select! { + true => { + fn a() {} + } + _ => { + fn b() {} + } + } +} + +extern "C" { + cfg_select! { + true => { + fn puts(s: *const i8) -> i32; + } + _ => { + fn printf(fmt: *const i8, ...) -> i32; + } + } +} + cfg_select! { _ => {} true => {} diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 510fc33d6d11..ffd8540425ab 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -1,5 +1,5 @@ warning: unreachable predicate - --> $DIR/cfg_select.rs:52:5 + --> $DIR/cfg_select.rs:135:5 | LL | _ => {} | - always matches @@ -7,7 +7,7 @@ LL | true => {} | ^^^^ this predicate is never reached error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:56:1 + --> $DIR/cfg_select.rs:139:1 | LL | / cfg_select! { LL | | @@ -16,55 +16,55 @@ LL | | } | |_^ error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:61:1 + --> $DIR/cfg_select.rs:144:1 | LL | cfg_select! {} | ^^^^^^^^^^^^^^ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `=>` - --> $DIR/cfg_select.rs:65:5 + --> $DIR/cfg_select.rs:148:5 | LL | => {} | ^^ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression - --> $DIR/cfg_select.rs:70:5 + --> $DIR/cfg_select.rs:153:5 | LL | () => {} | ^^ expressions are not allowed here error[E0539]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:75:5 + --> $DIR/cfg_select.rs:158:5 | LL | "str" => {} | ^^^^^ expected a valid identifier here error[E0539]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:80:5 + --> $DIR/cfg_select.rs:163:5 | LL | a::b => {} | ^^^^ expected a valid identifier here error[E0537]: invalid predicate `a` - --> $DIR/cfg_select.rs:85:5 + --> $DIR/cfg_select.rs:168:5 | LL | a() => {} | ^^^ error: expected one of `(`, `::`, `=>`, or `=`, found `+` - --> $DIR/cfg_select.rs:90:7 + --> $DIR/cfg_select.rs:173:7 | LL | a + 1 => {} | ^ expected one of `(`, `::`, `=>`, or `=` error: expected one of `(`, `::`, `=>`, or `=`, found `!` - --> $DIR/cfg_select.rs:96:8 + --> $DIR/cfg_select.rs:179:8 | LL | cfg!() => {} | ^ expected one of `(`, `::`, `=>`, or `=` warning: unexpected `cfg` condition name: `a` - --> $DIR/cfg_select.rs:90:5 + --> $DIR/cfg_select.rs:173:5 | LL | a + 1 => {} | ^ help: found config with similar value: `target_feature = "a"` @@ -75,7 +75,7 @@ LL | a + 1 => {} = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `cfg` - --> $DIR/cfg_select.rs:96:5 + --> $DIR/cfg_select.rs:179:5 | LL | cfg!() => {} | ^^^ diff --git a/tests/ui/macros/cfg_select_parse_error.rs b/tests/ui/macros/cfg_select_parse_error.rs new file mode 100644 index 000000000000..90fcb2309b34 --- /dev/null +++ b/tests/ui/macros/cfg_select_parse_error.rs @@ -0,0 +1,18 @@ +#![feature(cfg_select)] +#![crate_type = "lib"] + +// Check that parse errors in arms that are not selected are still reported. + +fn print() { + println!(cfg_select! { + false => { 1 ++ 2 } + //~^ ERROR Rust has no postfix increment operator + _ => { "not unix" } + }); +} + +cfg_select! { + false => { fn foo() { 1 +++ 2 } } + //~^ ERROR Rust has no postfix increment operator + _ => {} +} diff --git a/tests/ui/macros/cfg_select_parse_error.stderr b/tests/ui/macros/cfg_select_parse_error.stderr new file mode 100644 index 000000000000..d4c86c3ceade --- /dev/null +++ b/tests/ui/macros/cfg_select_parse_error.stderr @@ -0,0 +1,26 @@ +error: Rust has no postfix increment operator + --> $DIR/cfg_select_parse_error.rs:8:22 + | +LL | false => { 1 ++ 2 } + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL - false => { 1 ++ 2 } +LL + false => { { let tmp = 1 ; 1 += 1; tmp } 2 } + | + +error: Rust has no postfix increment operator + --> $DIR/cfg_select_parse_error.rs:15:29 + | +LL | false => { fn foo() { 1 +++ 2 } } + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL - false => { fn foo() { 1 +++ 2 } } +LL + false => { fn foo() { { let tmp = 1 ; 1 += 1; tmp }+ 2 } } + | + +error: aborting due to 2 previous errors + From e254e7ef2d54ee546f75db6c1a75aa6bb1b83514 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 17 Dec 2025 23:47:04 +0200 Subject: [PATCH 0970/3801] match fn name --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index aa34fbbb53f2..8e963627066a 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -233,7 +233,7 @@ r? @reviewer } #[test] -fn test_prettify() { +fn test_lengthen_lines() { let original = "\ do not split short sentences From 8b2c9d8189ab55595f3a636b9e1cfe41b0748217 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 17 Dec 2025 23:49:54 +0200 Subject: [PATCH 0971/3801] sembr src/about-this-guide.md --- src/doc/rustc-dev-guide/src/about-this-guide.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md index 841691d859f9..2082481a200e 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -77,8 +77,7 @@ You might also find the following sites useful: - [std-dev-guide] -- a similar guide for developing the standard library. - [rust-analyzer book] -- documentation for the rust-analyzer. - [The t-compiler Zulip][z] -- The [Rust Internals forum][rif], a place to ask questions and - discuss Rust's internals +- The [Rust Internals forum][rif], a place to ask questions and discuss Rust's internals - The [Rust reference][rr], even though it doesn't specifically talk about Rust's internals, is a great resource nonetheless - Although out of date, [Tom Lee's great blog article][tlgba] is very helpful @@ -89,11 +88,10 @@ You might also find the following sites useful: the compiler, the books, the references, and the guides) to quickly find information about the language and compiler. - You can also use Rustdoc's built-in search feature to find documentation on - types and functions within the crates you're looking at. You can also search - by type signature! For example, searching for `* -> vec` should find all - functions that return a `Vec`. - _Hint:_ Find more tips and keyboard shortcuts by typing `?` on any Rustdoc - page! + types and functions within the crates you're looking at. + You can also search by type signature! + For example, searching for `* -> vec` should find all functions that return a `Vec`. + _Hint:_ Find more tips and keyboard shortcuts by typing `?` on any Rustdoc page! [rustc dev guide]: about-this-guide.md From 6a911741048a5a585c92533677b62ee65aaa8dcb Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 17 Dec 2025 23:53:15 +0200 Subject: [PATCH 0972/3801] sembr src/appendix/bibliography.md --- .../src/appendix/bibliography.md | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index 13a9c3a0b40b..c161bba5b34f 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/src/appendix/bibliography.md @@ -1,7 +1,7 @@ # Rust Bibliography -This is a reading list of material relevant to Rust. It includes prior -research that has - at one time or another - influenced the design of +This is a reading list of material relevant to Rust. +It includes prior research that has - at one time or another - influenced the design of Rust, as well as publications about Rust. ## Type system @@ -44,8 +44,7 @@ Rust, as well as publications about Rust. ## Papers *about* Rust -* [GPU Programming in Rust: Implementing High Level Abstractions in a Systems - Level +* [GPU Programming in Rust: Implementing High Level Abstractions in a Systems Level Language](https://ieeexplore.ieee.org/document/6650903). Early GPU work by Eric Holk. * [Parallel closures: a new twist on an old @@ -55,38 +54,47 @@ Rust, as well as publications about Rust. Language](https://dada.cs.washington.edu/research/tr/2015/03/UW-CSE-15-03-02.pdf). Early formalization of a subset of the type system, by Eric Reed. * [Experience Report: Developing the Servo Web Browser Engine using - Rust](https://arxiv.org/abs/1505.07383). By Lars Bergstrom. + Rust](https://arxiv.org/abs/1505.07383). + By Lars Bergstrom. * [Implementing a Generic Radix Trie in - Rust](https://michaelsproul.github.io/rust_radix_paper/rust-radix-sproul.pdf). Undergrad - paper by Michael Sproul. + Rust](https://michaelsproul.github.io/rust_radix_paper/rust-radix-sproul.pdf). + Undergrad paper by Michael Sproul. * [Reenix: Implementing a Unix-Like Operating System in - Rust](https://scialex.github.io/reenix.pdf). Undergrad paper by Alex - Light. + Rust](https://scialex.github.io/reenix.pdf). + Undergrad paper by Alex Light. * [Evaluation of performance and productivity metrics of potential programming languages in the HPC environment](https://github.com/1wilkens/thesis-ba). - Bachelor's thesis by Florian Wilkens. Compares C, Go and Rust. + Bachelor's thesis by Florian Wilkens. + Compares C, Go and Rust. * [Nom, a byte oriented, streaming, zero copy, parser combinators library - in Rust](http://spw15.langsec.org/papers/couprie-nom.pdf). By - Geoffroy Couprie, research for VLC. + in Rust](http://spw15.langsec.org/papers/couprie-nom.pdf). + By Geoffroy Couprie, research for VLC. * [Graph-Based Higher-Order Intermediate - Representation](https://compilers.cs.uni-saarland.de/papers/lkh15_cgo.pdf). An - experimental IR implemented in Impala, a Rust-like language. -* [Code Refinement of Stencil - Codes](https://compilers.cs.uni-saarland.de/papers/ppl14_web.pdf). Another - paper using Impala. + Representation](https://compilers.cs.uni-saarland.de/papers/lkh15_cgo.pdf). + An experimental IR implemented in Impala, a Rust-like language. +* [Code Refinement of Stencil Codes](https://compilers.cs.uni-saarland.de/papers/ppl14_web.pdf). + Another paper using Impala. * [Parallelization in Rust with fork-join and - friends](http://publications.lib.chalmers.se/records/fulltext/219016/219016.pdf). Linus - Farnstrand's master's thesis. -* [Session Types for - Rust](https://munksgaard.me/papers/laumann-munksgaard-larsen.pdf). Philip - Munksgaard's master's thesis. Research for Servo. -* [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. al.](https://amitlevy.com/papers/tock-plos2015.pdf) -* [You can't spell trust without Rust](https://faultlore.com/blah/papers/thesis.pdf). Aria Beingessner's master's thesis. -* [Rust-Bio: a fast and safe bioinformatics library](https://rust-bio.github.io/). Johannes Köster -* [Safe, Correct, and Fast Low-Level Networking](https://csperkins.org/research/thesis-msci-clipsham.pdf). Robert Clipsham's master's thesis. -* [Formalizing Rust traits](https://open.library.ubc.ca/cIRcle/collections/ubctheses/24/items/1.0220521). Jonatan Milewski's master's thesis. + friends](http://publications.lib.chalmers.se/records/fulltext/219016/219016.pdf). + Linus Farnstrand's master's thesis. +* [Session Types for Rust](https://munksgaard.me/papers/laumann-munksgaard-larsen.pdf). + Philip Munksgaard's master's thesis. + Research for Servo. +* [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. + al.](https://amitlevy.com/papers/tock-plos2015.pdf) +* [You can't spell trust without Rust](https://faultlore.com/blah/papers/thesis.pdf). + Aria Beingessner's master's thesis. +* [Rust-Bio: a fast and safe bioinformatics library](https://rust-bio.github.io/). + Johannes Köster +* [Safe, Correct, and Fast Low-Level Networking](https://csperkins.org/research/thesis-msci-clipsham.pdf). + Robert Clipsham's master's thesis. +* [Formalizing Rust traits](https://open.library.ubc.ca/cIRcle/collections/ubctheses/24/items/1.0220521). + Jonatan Milewski's master's thesis. * [Rust as a Language for High Performance GC Implementation](https://dl.acm.org/doi/pdf/10.1145/3241624.2926707) -* [Simple Verification of Rust Programs via Functional Purification](https://github.com/Kha/electrolysis). Sebastian Ullrich's master's thesis. +* [Simple Verification of Rust Programs via Functional Purification](https://github.com/Kha/electrolysis). + Sebastian Ullrich's master's thesis. * [Writing parsers like it is 2017](http://spw17.langsec.org/papers/chifflier-parsing-in-2017.pdf) Pierre Chifflier and Geoffroy Couprie for the Langsec Workshop * [The Case for Writing a Kernel in Rust](https://www.tockos.org/assets/papers/rust-kernel-apsys2017.pdf) * [RustBelt: Securing the Foundations of the Rust Programming Language](https://plv.mpi-sws.org/rustbelt/popl18/) -* [Oxide: The Essence of Rust](https://arxiv.org/abs/1903.00982). By Aaron Weiss, Olek Gierczak, Daniel Patterson, Nicholas D. Matsakis, and Amal Ahmed. +* [Oxide: The Essence of Rust](https://arxiv.org/abs/1903.00982). + By Aaron Weiss, Olek Gierczak, Daniel Patterson, Nicholas D. + Matsakis, and Amal Ahmed. From f685b240d8169cd0be8b21312cec07241f7fae08 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 18 Dec 2025 00:09:33 +0200 Subject: [PATCH 0973/3801] fix corner case --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 8e963627066a..2eb32491e3aa 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -80,6 +80,7 @@ fn ignore(line: &str, in_code_block: bool) -> bool { in_code_block || line.to_lowercase().contains("e.g.") || line.contains("i.e.") + || line.contains("et. al") || line.contains('|') || line.trim_start().starts_with('>') || line.starts_with('#') From e1fe9c64624a1040b88da91eef5044e3d810a537 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 18 Dec 2025 00:11:34 +0200 Subject: [PATCH 0974/3801] sembr src/appendix/bibliography.md (after fix from parent commit) Please enter the commit message for your changes. Lines starting --- src/doc/rustc-dev-guide/src/appendix/bibliography.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index c161bba5b34f..4f87e4d2fa00 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/src/appendix/bibliography.md @@ -79,8 +79,7 @@ Rust, as well as publications about Rust. * [Session Types for Rust](https://munksgaard.me/papers/laumann-munksgaard-larsen.pdf). Philip Munksgaard's master's thesis. Research for Servo. -* [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. - al.](https://amitlevy.com/papers/tock-plos2015.pdf) +* [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. al.](https://amitlevy.com/papers/tock-plos2015.pdf) * [You can't spell trust without Rust](https://faultlore.com/blah/papers/thesis.pdf). Aria Beingessner's master's thesis. * [Rust-Bio: a fast and safe bioinformatics library](https://rust-bio.github.io/). From 2dac444b7e2b7a87157b46b6a708c6fa6bce4c27 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 18 Dec 2025 00:18:45 +0200 Subject: [PATCH 0975/3801] sembr src/diagnostics/error-codes.md --- .../src/diagnostics/error-codes.md | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md index c7bb6669dce4..9a302f9100f1 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md @@ -1,24 +1,24 @@ # Error codes -We generally try to assign each error message a unique code like `E0123`. These -codes are defined in the compiler in the `diagnostics.rs` files found in each -crate, which basically consist of macros. All error codes have an associated -explanation: new error codes must include them. Note that not all _historical_ -(no longer emitted) error codes have explanations. +We generally try to assign each error message a unique code like `E0123`. +These codes are defined in the compiler in the `diagnostics.rs` files found in each +crate, which basically consist of macros. +All error codes have an associated explanation: new error codes must include them. +Note that not all _historical_ (no longer emitted) error codes have explanations. ## Error explanations The explanations are written in Markdown (see the [CommonMark Spec] for -specifics around syntax), and all of them are linked in the [`rustc_error_codes`] -crate. Please read [RFC 1567] for details on how to format and write long error -codes. As of February 2023, there is an -effort[^new-explanations] to replace this largely outdated RFC with a new more -flexible standard. +specifics around syntax), and all of them are linked in the [`rustc_error_codes`] crate. +Please read [RFC 1567] for details on how to format and write long error codes. +As of February 2023, there is an +effort[^new-explanations] to replace this largely outdated RFC with a new more flexible standard. Error explanations should expand on the error message and provide details about -_why_ the error occurs. It is not helpful for users to copy-paste a quick fix; -explanations should help users understand why their code cannot be accepted by -the compiler. Rust prides itself on helpful error messages and long-form -explanations are no exception. However, before error explanations are +_why_ the error occurs. +It is not helpful for users to copy-paste a quick fix; +explanations should help users understand why their code cannot be accepted by the compiler. +Rust prides itself on helpful error messages and long-form explanations are no exception. +However, before error explanations are overhauled[^new-explanations] it is a bit open as to how exactly they should be written, as always: ask your reviewer or ask around on the Rust Zulip. @@ -33,12 +33,12 @@ written, as always: ask your reviewer or ask around on the Rust Zulip. Error codes are stored in `compiler/rustc_error_codes`. -To create a new error, you first need to find the next available code. +To create a new error, you first need to find the next available code. You can find it by opening `rustc_error_codes/src/lib.rs` and scrolling down to the end of the `error_codes!` macro declaration. -Here we might see the highest error code in use is `E0805`, so we _probably_ want -`E0806`. To be sure, run `rg E0806` and check, you should see no references. +Here we might see the highest error code in use is `E0805`, so we _probably_ want `E0806`. +To be sure, run `rg E0806` and check, you should see no references. You will have to write an extended description for your error, which will go in `rustc_error_codes/src/error_codes/E0806.md`. @@ -62,8 +62,7 @@ struct_span_code_err!(self.dcx(), // some path to the `DiagCtxt` here .emit() // actually issue the error ``` -If you want to add notes or other snippets, you can invoke methods before you -call `.emit()`: +If you want to add notes or other snippets, you can invoke methods before you call `.emit()`: ```rust struct_span_code_err!(...) From 5e1352b6318d1e10560546c831f682debf0e43f4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 18 Dec 2025 00:25:13 +0200 Subject: [PATCH 0976/3801] sembr src/query.md --- src/doc/rustc-dev-guide/src/query.md | 104 ++++++++++++++------------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 5df9de762038..28e421acb207 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -2,11 +2,13 @@ As described in [Overview of the compiler], the Rust compiler is still (as of July 2021) transitioning from a -traditional "pass-based" setup to a "demand-driven" system. The compiler query -system is the key to rustc's demand-driven organization. -The idea is pretty simple. Instead of entirely independent passes +traditional "pass-based" setup to a "demand-driven" system. +The compiler query system is the key to rustc's demand-driven organization. +The idea is pretty simple. +Instead of entirely independent passes (parsing, type-checking, etc.), a set of function-like *queries* -compute information about the input source. For example, +compute information about the input source. +For example, there is a query called `type_of` that, given the [`DefId`] of some item, will compute the type of that item and return it to you. @@ -14,25 +16,21 @@ some item, will compute the type of that item and return it to you. [Overview of the compiler]: overview.md#queries Query execution is *memoized*. The first time you invoke a -query, it will go do the computation, but the next time, the result is -returned from a hashtable. Moreover, query execution fits nicely into +query, it will go do the computation, but the next time, the result is returned from a hashtable. +Moreover, query execution fits nicely into *incremental computation*; the idea is roughly that, when you invoke a -query, the result *may* be returned to you by loading stored data -from disk.[^incr-comp-detail] +query, the result *may* be returned to you by loading stored data from disk.[^incr-comp-detail] -Eventually, we want the entire compiler -control-flow to be query driven. There will effectively be one -top-level query (`compile`) that will run compilation on a crate; this -will in turn demand information about that crate, starting from the -*end*. For example: +Eventually, we want the entire compiler control-flow to be query driven. +There will effectively be one top-level query (`compile`) that will run compilation on a crate; this +will in turn demand information about that crate, starting from the *end*. For example: - The `compile` query might demand to get a list of codegen-units (i.e. modules that need to be compiled by LLVM). - But computing the list of codegen-units would invoke some subquery that returns the list of all modules defined in the Rust source. - That query in turn would invoke something asking for the HIR. -- This keeps going further and further back until we wind up doing the - actual parsing. +- This keeps going further and further back until we wind up doing the actual parsing. Although this vision is not fully realized, large sections of the compiler (for example, generating [MIR]) currently work exactly like this. @@ -46,9 +44,9 @@ If you intend to write a query of your own, this is a good read. ## Invoking queries -Invoking a query is simple. The [`TyCtxt`] ("type context") struct offers a method -for each defined query. For example, to invoke the `type_of` -query, you would just do this: +Invoking a query is simple. +The [`TyCtxt`] ("type context") struct offers a method for each defined query. +For example, to invoke the `type_of` query, you would just do this: ```rust,ignore let ty = tcx.type_of(some_def_id); @@ -58,8 +56,8 @@ let ty = tcx.type_of(some_def_id); ## How the compiler executes a query -So you may be wondering what happens when you invoke a query -method. The answer is that, for each query, the compiler maintains a +So you may be wondering what happens when you invoke a query method. +The answer is that, for each query, the compiler maintains a cache – if your query has already been executed, then, the answer is simple: we clone the return value out of the cache and return it (therefore, you should try to ensure that the return types of queries @@ -68,11 +66,12 @@ are cheaply cloneable; insert an `Rc` if necessary). ### Providers If, however, the query is *not* in the cache, then the compiler will -call the corresponding **provider** function. A provider is a function -implemented in a specific module and **manually registered** into either +call the corresponding **provider** function. +A provider is a function implemented in a specific module and **manually registered** into either the [`Providers`][providers_struct] struct (for local crate queries) or the [`ExternProviders`][extern_providers_struct] struct (for external crate queries) -during compiler initialization. The macro system generates both structs, +during compiler initialization. +The macro system generates both structs, which act as function tables for all query implementations, where each field is a function pointer to the actual provider. @@ -80,8 +79,8 @@ field is a function pointer to the actual provider. They are **not** Rust traits, but plain structs with function pointer fields. **Providers are defined per-crate.** The compiler maintains, -internally, a table of providers for every crate, at least -conceptually. There are two sets of providers: +internally, a table of providers for every crate, at least conceptually. +There are two sets of providers: - The `Providers` struct for queries about the **local crate** (that is, the one being compiled) - The `ExternProviders` struct for queries about **external crates** (that is, dependencies of the local crate) @@ -89,8 +88,7 @@ dependencies of the local crate) Note that what determines the crate that a query is targeting is not the *kind* of query, but the *key*. For example, when you invoke `tcx.type_of(def_id)`, that could be a local query or an external query, depending on what crate the `def_id` -is referring to (see the [`self::keys::Key`][Key] trait for more -information on how that works). +is referring to (see the [`self::keys::Key`][Key] trait for more information on how that works). Providers always have the same signature: @@ -106,10 +104,11 @@ fn provider<'tcx>( Providers take two arguments: the `tcx` and the query key. They return the result of the query. -N.B. Most of the `rustc_*` crates only provide **local +N.B. +Most of the `rustc_*` crates only provide **local providers**. Almost all **extern providers** wind up going through the -[`rustc_metadata` crate][rustc_metadata], which loads the information -from the crate metadata. But in some cases there are crates that +[`rustc_metadata` crate][rustc_metadata], which loads the information from the crate metadata. +But in some cases there are crates that provide queries for *both* local and external crates, in which case they define both a `provide` and a `provide_extern` function, through [`wasm_import_module_map`][wasm_import_module_map], that `rustc_driver` can invoke. @@ -120,7 +119,8 @@ they define both a `provide` and a `provide_extern` function, through ### How providers are set up When the tcx is created, it is given both the local and external providers by its creator using -the `Providers` struct from `rustc_middle::util`. This struct contains both the local and external providers: +the `Providers` struct from `rustc_middle::util`. +This struct contains both the local and external providers: ```rust,ignore pub struct Providers { @@ -134,7 +134,7 @@ Each of these provider structs is generated by the macros and contains function #### How are providers registered? -The `util::Providers` struct is filled in during compiler initialization, by the `rustc_interface` crate from the `DEFAULT_QUERY_PROVIDERS` static. +The `util::Providers` struct is filled in during compiler initialization, by the `rustc_interface` crate from the `DEFAULT_QUERY_PROVIDERS` static. The actual provider functions are defined across various `rustc_*` crates (like `rustc_middle`, `rustc_hir_analysis`, etc). To register providers, each crate exposes a [`provide`][provide_fn] function that looks like this: @@ -151,7 +151,9 @@ pub fn provide(providers: &mut query::Providers) { } ``` -Note that this function accepts `query::Providers` not `util::Providers`. It is exceedingly rare to need a `provide` function that doesn't just accept `query::Providers`. If more than the `queries` field of `util::Providers` is being updated then `util::Providers` can be accepted instead: +Note that this function accepts `query::Providers` not `util::Providers`. +It is exceedingly rare to need a `provide` function that doesn't just accept `query::Providers`. +If more than the `queries` field of `util::Providers` is being updated then `util::Providers` can be accepted instead: ```rust,ignore pub fn provide(providers: &mut rustc_middle::util::Providers) { providers.queries.type_of = type_of; @@ -173,7 +175,8 @@ Note that `util::Providers` implements `DerefMut` to `query::Providers` so calle #### Adding a new provider -Suppose you want to add a new query called `fubar`. This section focuses on wiring up the providers; for how to declare the query itself in the big `rustc_queries!` macro, see [Adding a new query](#adding-a-new-query) below. +Suppose you want to add a new query called `fubar`. +This section focuses on wiring up the providers; for how to declare the query itself in the big `rustc_queries!` macro, see [Adding a new query](#adding-a-new-query) below. In practice you usually: @@ -184,7 +187,8 @@ In practice you usually: // existing assignments } ``` - If it exists, you will extend it to set the field for your new query. If the crate does not yet have a `provide` function, add one and make sure it is included in `DEFAULT_QUERY_PROVIDERS` in the `rustc_interface` crate so that it actually gets called during initialization (see the discussion above). + If it exists, you will extend it to set the field for your new query. + If the crate does not yet have a `provide` function, add one and make sure it is included in `DEFAULT_QUERY_PROVIDERS` in the `rustc_interface` crate so that it actually gets called during initialization (see the discussion above). 3. Implement the provider function itself: ```rust,ignore fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: LocalDefId) -> Fubar<'tcx> { ... } @@ -210,7 +214,8 @@ The process works like this: This determines whether to use the local provider from [`Providers`][providers_struct] or the external provider from [`ExternProviders`][extern_providers_struct]. 2. For external crates, the query system will look for a provider in the [`ExternProviders`][extern_providers_struct] struct. - The `rustc_metadata` crate registers these external providers through the `provide_extern` function in `rustc_metadata/src/rmeta/decoder/cstore_impl.rs`. Just like: + The `rustc_metadata` crate registers these external providers through the `provide_extern` function in `rustc_metadata/src/rmeta/decoder/cstore_impl.rs`. + Just like: ```rust pub fn provide_extern(providers: &mut ExternProviders) { providers.foo = |tcx, def_id| { @@ -222,7 +227,8 @@ The process works like this: } ``` -3. The metadata is stored in a binary format in `.rmeta` files that contains pre-computed information about the external crate, such as types, function signatures, trait implementations, and other information needed by the compiler. When an external query is made, the `rustc_metadata` crate: +3. The metadata is stored in a binary format in `.rmeta` files that contains pre-computed information about the external crate, such as types, function signatures, trait implementations, and other information needed by the compiler. + When an external query is made, the `rustc_metadata` crate: - Loads the `.rmeta` file for the external crate - Decodes the metadata using the `Decodable` trait - Returns the decoded information to the query system @@ -234,10 +240,11 @@ Here is a simplified example, when you call `tcx.type_of(def_id)` for a type def 3. The provider will load and decode the type information from the external crate's metadata 4. Return the decoded type to the caller -This is why most `rustc_*` crates only need to provide local providers - the external providers are handled by the metadata system. +This is why most `rustc_*` crates only need to provide local providers - the external providers are handled by the metadata system. The only exception is when a crate needs to provide special handling for external queries, in which case it would implement both local and external providers. -When we define a new query that should work across crates, it does not automatically become cross-crate just because it is listed in `rustc_queries!`. You will typically need to: +When we define a new query that should work across crates, it does not automatically become cross-crate just because it is listed in `rustc_queries!`. +You will typically need to: - Add the query to `rustc_queries!` with appropriate modifiers (for example whether it is cached on disk). - Implement a local provider in the owning crate and register it via that crate's `provide` function. @@ -296,17 +303,16 @@ query keyword Let's go over these elements one by one: - **Query keyword:** indicates a start of a query definition. -- **Name of query:** the name of the query method - (`tcx.type_of(..)`). Also used as the name of a struct - (`ty::queries::type_of`) that will be generated to represent +- **Name of query:** the name of the query method (`tcx.type_of(..)`). + Also used as the name of a struct (`ty::queries::type_of`) that will be generated to represent this query. - **Query key type:** the type of the argument to this query. This type must implement the [`ty::query::keys::Key`][Key] trait, which defines (for example) how to map it to a crate, and so forth. -- **Result type of query:** the type produced by this query. This type - should (a) not use `RefCell` or other interior mutability and (b) be - cheaply cloneable. Interning or using `Rc` or `Arc` is recommended for - non-trivial data types.[^steal] +- **Result type of query:** the type produced by this query. + This type should (a) not use `RefCell` or other interior mutability and (b) be + cheaply cloneable. + Interning or using `Rc` or `Arc` is recommended for non-trivial data types.[^steal] - **Query modifiers:** various flags and options that customize how the query is processed (mostly with respect to [incremental compilation][incrcomp]). @@ -320,9 +326,9 @@ So, to add a query: or add a new one if needed and ensure that `rustc_driver` is invoking it. [^steal]: The one exception to those rules is the `ty::steal::Steal` type, -which is used to cheaply modify MIR in place. See the definition -of `Steal` for more details. New uses of `Steal` should **not** be -added without alerting `@rust-lang/compiler`. +which is used to cheaply modify MIR in place. +See the definition of `Steal` for more details. +New uses of `Steal` should **not** be added without alerting `@rust-lang/compiler`. ## External links From 2114b2107068617b0303f9d0e91ad12ad00a296c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 17 Dec 2025 23:27:38 +0100 Subject: [PATCH 0977/3801] Improve code by using `iterator::sum` instead of looping --- src/librustdoc/html/highlight.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index bc268d9495f8..f70b350de283 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -921,12 +921,10 @@ fn classify<'src>( && let Some(nb_items) = classifier.get_full_ident_path() { let start = classifier.byte_pos as usize; - let mut len = 0; - for _ in 0..nb_items { - if let Some((_, text, _)) = classifier.next() { - len += text.len(); - } - } + let len: usize = iter::from_fn(|| classifier.next()) + .take(nb_items) + .map(|(_, text, _)| text.len()) + .sum(); let text = &classifier.src[start..start + len]; classifier.advance(TokenKind::Ident, text, sink, start as u32); } else if let Some((token, text, before)) = classifier.next() { From 40d05f8108b551e435445a86977d7d8e8b2e2cfa Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 18 Dec 2025 00:36:27 +0200 Subject: [PATCH 0978/3801] corner case --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 1 + src/doc/rustc-dev-guide/src/query.md | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 2eb32491e3aa..d41a57d6f747 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -79,6 +79,7 @@ fn display(header: &str, paths: &[PathBuf]) { fn ignore(line: &str, in_code_block: bool) -> bool { in_code_block || line.to_lowercase().contains("e.g.") + || line.to_lowercase().contains("n.b.") || line.contains("i.e.") || line.contains("et. al") || line.contains('|') diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 28e421acb207..90bb08d8abcd 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -104,8 +104,7 @@ fn provider<'tcx>( Providers take two arguments: the `tcx` and the query key. They return the result of the query. -N.B. -Most of the `rustc_*` crates only provide **local +N.B. Most of the `rustc_*` crates only provide **local providers**. Almost all **extern providers** wind up going through the [`rustc_metadata` crate][rustc_metadata], which loads the information from the crate metadata. But in some cases there are crates that @@ -158,10 +157,10 @@ If more than the `queries` field of `util::Providers` is being updated then `ut pub fn provide(providers: &mut rustc_middle::util::Providers) { providers.queries.type_of = type_of; // ... add more local providers here - + providers.extern_queries.type_of = extern_type_of; // ... add more external providers here - + providers.hooks.some_hook = some_hook; // ... add more hooks here } @@ -205,7 +204,7 @@ In practice you usually: ### How queries interact with external crate metadata -When a query is made for an external crate (i.e., a dependency), the query system needs to load the information from that crate's metadata. +When a query is made for an external crate (i.e., a dependency), the query system needs to load the information from that crate's metadata. This is handled by the [`rustc_metadata` crate][rustc_metadata], which is responsible for decoding and providing the information stored in the `.rmeta` files. The process works like this: From 2fe2052bbec7bab1951712ddde3f3c0863575c4d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 18 Dec 2025 00:40:03 +0200 Subject: [PATCH 0979/3801] manual sembr --- src/doc/rustc-dev-guide/src/query.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 90bb08d8abcd..1961d68509f9 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -23,7 +23,9 @@ query, the result *may* be returned to you by loading stored data from disk.[^in Eventually, we want the entire compiler control-flow to be query driven. There will effectively be one top-level query (`compile`) that will run compilation on a crate; this -will in turn demand information about that crate, starting from the *end*. For example: +will in turn demand information about that crate, starting from the *end*. + +For example: - The `compile` query might demand to get a list of codegen-units (i.e. modules that need to be compiled by LLVM). From 4673d56b4178fbbccb428784f9a1c706bdcc8f3f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 18 Dec 2025 00:41:31 +0200 Subject: [PATCH 0980/3801] sembr src/conventions.md --- src/doc/rustc-dev-guide/src/conventions.md | 64 ++++++++++------------ 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 92ed0825c8c3..36ea0c584240 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -1,9 +1,8 @@ # Coding conventions -This file offers some tips on the coding conventions for rustc. This -chapter covers [formatting](#formatting), [coding for correctness](#cc), -[using crates from crates.io](#cio), and some tips on -[structuring your PR for easy review](#er). +This file offers some tips on the coding conventions for rustc. +This chapter covers [formatting](#formatting), [coding for correctness](#cc), +[using crates from crates.io](#cio), and some tips on [structuring your PR for easy review](#er). @@ -15,11 +14,11 @@ However, for now we don't use stable `rustfmt`; we use a pinned version with a special config, so this may result in different style from normal [`rustfmt`]. Therefore, formatting this repository using `cargo fmt` is not recommended. -Instead, formatting should be done using `./x fmt`. It's a good habit to run -`./x fmt` before every commit, as this reduces conflicts later. +Instead, formatting should be done using `./x fmt`. +It's a good habit to run `./x fmt` before every commit, as this reduces conflicts later. -Formatting is checked by the `tidy` script. It runs automatically when you do -`./x test` and can be run in isolation with `./x fmt --check`. +Formatting is checked by the `tidy` script. +It runs automatically when you do `./x test` and can be run in isolation with `./x fmt --check`. > **Note: Formatting and test suites** > @@ -47,13 +46,12 @@ When modifying that code, use this command to format it: ./x test tidy --extra-checks cpp:fmt --bless ``` -This uses a pinned version of `clang-format`, to avoid relying on the local -environment. +This uses a pinned version of `clang-format`, to avoid relying on the local environment. ### Formatting and linting Python code -The Rust repository contains quite a lot of Python code. We try to keep -it both linted and formatted by the [ruff] tool. +The Rust repository contains quite a lot of Python code. +We try to keep it both linted and formatted by the [ruff] tool. When modifying Python code, use this command to format it: @@ -78,8 +76,8 @@ These use a pinned version of `ruff`, to avoid relying on the local environment. ### Copyright notice -In the past, files began with a copyright and license notice. Please **omit** -this notice for new files licensed under the standard terms (dual +In the past, files began with a copyright and license notice. +Please **omit** this notice for new files licensed under the standard terms (dual MIT/Apache-2.0). All of the copyright notices should be gone by now, but if you come across one @@ -87,8 +85,8 @@ in the rust-lang/rust repo, feel free to open a PR to remove it. ### Line length -Lines should be at most 100 characters. It's even better if you can -keep things to 80. +Lines should be at most 100 characters. +It's even better if you can keep things to 80. Sometimes, and particularly for tests, it can be necessary to exempt yourself from this limit. In that case, you can add a comment towards the top of the file like so: @@ -105,17 +103,15 @@ Prefer 4-space indents. ## Coding for correctness -Beyond formatting, there are a few other tips that are worth -following. +Beyond formatting, there are a few other tips that are worth following. ### Prefer exhaustive matches Using `_` in a match is convenient, but it means that when new variants are added to the enum, they may not get handled correctly. Ask yourself: if a new variant were added to this enum, what's the -chance that it would want to use the `_` code, versus having some -other treatment? Unless the answer is "low", then prefer an -exhaustive match. +chance that it would want to use the `_` code, versus having some other treatment? +Unless the answer is "low", then prefer an exhaustive match. The same advice applies to `if let` and `while let`, which are effectively tests for a single variant. @@ -155,41 +151,39 @@ See the [crates.io dependencies][crates] section. ## How to structure your PR -How you prepare the commits in your PR can make a big difference for the -reviewer. Here are some tips. +How you prepare the commits in your PR can make a big difference for the reviewer. +Here are some tips. **Isolate "pure refactorings" into their own commit.** For example, if you rename a method, then put that rename into its own commit, along with the renames of all the uses. **More commits is usually better.** If you are doing a large change, -it's almost always better to break it up into smaller steps that can -be independently understood. The one thing to be aware of is that if +it's almost always better to break it up into smaller steps that can be independently understood. +The one thing to be aware of is that if you introduce some code following one strategy, then change it -dramatically (versus adding to it) in a later commit, that -'back-and-forth' can be confusing. +dramatically (versus adding to it) in a later commit, that 'back-and-forth' can be confusing. **Format liberally.** While only the final commit of a PR must be correctly formatted, it is both easier to review and less noisy to format each commit individually using `./x fmt`. -**No merges.** We do not allow merge commits into our history, other -than those by bors. If you get a merge conflict, rebase instead via a +**No merges.** We do not allow merge commits into our history, other than those by bors. +If you get a merge conflict, rebase instead via a command like `git rebase --interactive rust-lang/main` (presuming you use the name `rust-lang` for your remote). **Individual commits do not have to build (but it's nice).** We do not require that every intermediate commit successfully builds – we only -expect to be able to bisect at a PR level. However, if you *can* make -individual commits build, that is always helpful. +expect to be able to bisect at a PR level. +However, if you *can* make individual commits build, that is always helpful. ## Naming conventions -Apart from normal Rust style/naming conventions, there are also some specific -to the compiler. +Apart from normal Rust style/naming conventions, there are also some specific to the compiler. -- `cx` tends to be short for "context" and is often used as a suffix. For - example, `tcx` is a common name for the [Typing Context][tcx]. +- `cx` tends to be short for "context" and is often used as a suffix. + For example, `tcx` is a common name for the [Typing Context][tcx]. - [`'tcx`][tcx] is used as the lifetime name for the Typing Context. From 3aa4a794a7e76fd0977dcd9d020bfd59aa9a43be Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 18 Dec 2025 00:48:43 +0200 Subject: [PATCH 0981/3801] that basically repeats the title --- src/doc/rustc-dev-guide/src/conventions.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 36ea0c584240..5153f2c5711a 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -1,6 +1,5 @@ # Coding conventions -This file offers some tips on the coding conventions for rustc. This chapter covers [formatting](#formatting), [coding for correctness](#cc), [using crates from crates.io](#cio), and some tips on [structuring your PR for easy review](#er). From 2daccc92e18d60ea4ada94367d8f693702d0eb97 Mon Sep 17 00:00:00 2001 From: Niko Kajula Date: Thu, 18 Dec 2025 01:00:29 +0200 Subject: [PATCH 0982/3801] Fix intel manual links --- library/stdarch/crates/core_arch/src/x86/abm.rs | 2 +- library/stdarch/crates/core_arch/src/x86/aes.rs | 2 +- library/stdarch/crates/core_arch/src/x86/avx.rs | 2 +- library/stdarch/crates/core_arch/src/x86/avx2.rs | 2 +- library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs | 2 +- library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs | 2 +- library/stdarch/crates/core_arch/src/x86/bmi1.rs | 2 +- library/stdarch/crates/core_arch/src/x86/bmi2.rs | 2 +- library/stdarch/crates/core_arch/src/x86/fma.rs | 2 +- library/stdarch/crates/core_arch/src/x86/gfni.rs | 2 +- library/stdarch/crates/core_arch/src/x86/pclmulqdq.rs | 2 +- library/stdarch/crates/core_arch/src/x86/rtm.rs | 2 +- library/stdarch/crates/core_arch/src/x86/vaes.rs | 2 +- library/stdarch/crates/core_arch/src/x86_64/abm.rs | 2 +- library/stdarch/crates/core_arch/src/x86_64/avx.rs | 2 +- library/stdarch/crates/core_arch/src/x86_64/bmi.rs | 2 +- library/stdarch/crates/core_arch/src/x86_64/bmi2.rs | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/abm.rs b/library/stdarch/crates/core_arch/src/x86/abm.rs index 7f46e1a8d06e..b73076361d86 100644 --- a/library/stdarch/crates/core_arch/src/x86/abm.rs +++ b/library/stdarch/crates/core_arch/src/x86/abm.rs @@ -12,7 +12,7 @@ //! [Wikipedia][wikipedia_bmi] provides a quick overview of the instructions //! available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wikipedia_bmi]: //! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 diff --git a/library/stdarch/crates/core_arch/src/x86/aes.rs b/library/stdarch/crates/core_arch/src/x86/aes.rs index 7db743b2ccd3..be01d6ddd8d0 100644 --- a/library/stdarch/crates/core_arch/src/x86/aes.rs +++ b/library/stdarch/crates/core_arch/src/x86/aes.rs @@ -5,7 +5,7 @@ //! The reference is [Intel 64 and IA-32 Architectures Software Developer's //! Manual Volume 2: Instruction Set Reference, A-Z][intel64_ref]. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf use crate::core_arch::x86::__m128i; diff --git a/library/stdarch/crates/core_arch/src/x86/avx.rs b/library/stdarch/crates/core_arch/src/x86/avx.rs index bda0b8ac5047..6d4f79fc7cfe 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx.rs @@ -9,7 +9,7 @@ //! //! [Wikipedia][wiki] provides a quick overview of the instructions available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wiki]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index e7fd19fa2e97..a297544e9e9b 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -13,7 +13,7 @@ //! Wikipedia's [AVX][wiki_avx] and [FMA][wiki_fma] pages provide a quick //! overview of the instructions available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wiki_avx]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions //! [wiki_fma]: https://en.wikipedia.org/wiki/Fused_multiply-accumulate diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs b/library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs index 832a58432208..497fa21c4fe1 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs @@ -5,7 +5,7 @@ //! The reference is [Intel 64 and IA-32 Architectures Software Developer's //! Manual Volume 2: Instruction Set Reference, A-Z][intel64_ref]. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf use crate::core_arch::simd::i8x16; use crate::core_arch::simd::i8x32; diff --git a/library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs b/library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs index 42bff33a286d..38ef54b550fd 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs @@ -5,7 +5,7 @@ //! The reference is [Intel 64 and IA-32 Architectures Software Developer's //! Manual Volume 2: Instruction Set Reference, A-Z][intel64_ref]. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf use crate::core_arch::simd::*; use crate::core_arch::x86::__m128i; diff --git a/library/stdarch/crates/core_arch/src/x86/bmi1.rs b/library/stdarch/crates/core_arch/src/x86/bmi1.rs index 08444aaaeddd..11d66f699a12 100644 --- a/library/stdarch/crates/core_arch/src/x86/bmi1.rs +++ b/library/stdarch/crates/core_arch/src/x86/bmi1.rs @@ -6,7 +6,7 @@ //! [Wikipedia][wikipedia_bmi] provides a quick overview of the instructions //! available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [wikipedia_bmi]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 #[cfg(test)] diff --git a/library/stdarch/crates/core_arch/src/x86/bmi2.rs b/library/stdarch/crates/core_arch/src/x86/bmi2.rs index b5b7d0f34073..54d3b5387ec7 100644 --- a/library/stdarch/crates/core_arch/src/x86/bmi2.rs +++ b/library/stdarch/crates/core_arch/src/x86/bmi2.rs @@ -6,7 +6,7 @@ //! [Wikipedia][wikipedia_bmi] provides a quick overview of the instructions //! available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [wikipedia_bmi]: //! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 diff --git a/library/stdarch/crates/core_arch/src/x86/fma.rs b/library/stdarch/crates/core_arch/src/x86/fma.rs index a8439935660f..c0900e61d92d 100644 --- a/library/stdarch/crates/core_arch/src/x86/fma.rs +++ b/library/stdarch/crates/core_arch/src/x86/fma.rs @@ -14,7 +14,7 @@ //! Wikipedia's [FMA][wiki_fma] page provides a quick overview of the //! instructions available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wiki_fma]: https://en.wikipedia.org/wiki/Fused_multiply-accumulate diff --git a/library/stdarch/crates/core_arch/src/x86/gfni.rs b/library/stdarch/crates/core_arch/src/x86/gfni.rs index 8c4d097fee9e..681b8ae330d4 100644 --- a/library/stdarch/crates/core_arch/src/x86/gfni.rs +++ b/library/stdarch/crates/core_arch/src/x86/gfni.rs @@ -5,7 +5,7 @@ //! The reference is [Intel 64 and IA-32 Architectures Software Developer's //! Manual Volume 2: Instruction Set Reference, A-Z][intel64_ref]. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf use crate::core_arch::simd::i8x16; use crate::core_arch::simd::i8x32; diff --git a/library/stdarch/crates/core_arch/src/x86/pclmulqdq.rs b/library/stdarch/crates/core_arch/src/x86/pclmulqdq.rs index cce6a51e2cd6..efc01190305e 100644 --- a/library/stdarch/crates/core_arch/src/x86/pclmulqdq.rs +++ b/library/stdarch/crates/core_arch/src/x86/pclmulqdq.rs @@ -3,7 +3,7 @@ //! The reference is [Intel 64 and IA-32 Architectures Software Developer's //! Manual Volume 2: Instruction Set Reference, A-Z][intel64_ref] (p. 4-241). //! -//! [intel64_ref]: http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf use crate::core_arch::x86::__m128i; diff --git a/library/stdarch/crates/core_arch/src/x86/rtm.rs b/library/stdarch/crates/core_arch/src/x86/rtm.rs index b807305d6aa8..b37e7571eb8f 100644 --- a/library/stdarch/crates/core_arch/src/x86/rtm.rs +++ b/library/stdarch/crates/core_arch/src/x86/rtm.rs @@ -9,7 +9,7 @@ //! Intel's [programming considerations][intel_consid] details what sorts of instructions within a //! transaction are likely to cause an abort. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [wikipedia_rtm]: https://en.wikipedia.org/wiki/Transactional_Synchronization_Extensions#Restricted_Transactional_Memory //! [intel_consid]: https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-intel-transactional-synchronization-extensions-intel-tsx-programming-considerations diff --git a/library/stdarch/crates/core_arch/src/x86/vaes.rs b/library/stdarch/crates/core_arch/src/x86/vaes.rs index b1fe193e3f5d..561b8b4b308c 100644 --- a/library/stdarch/crates/core_arch/src/x86/vaes.rs +++ b/library/stdarch/crates/core_arch/src/x86/vaes.rs @@ -5,7 +5,7 @@ //! The reference is [Intel 64 and IA-32 Architectures Software Developer's //! Manual Volume 2: Instruction Set Reference, A-Z][intel64_ref]. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf use crate::core_arch::x86::__m256i; use crate::core_arch::x86::__m512i; diff --git a/library/stdarch/crates/core_arch/src/x86_64/abm.rs b/library/stdarch/crates/core_arch/src/x86_64/abm.rs index 2b63cb5dc763..9fb76be4ba89 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/abm.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/abm.rs @@ -12,7 +12,7 @@ //! [Wikipedia][wikipedia_bmi] provides a quick overview of the instructions //! available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wikipedia_bmi]: //! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 diff --git a/library/stdarch/crates/core_arch/src/x86_64/avx.rs b/library/stdarch/crates/core_arch/src/x86_64/avx.rs index 80ef7fbd60a6..aae3c981d6fe 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/avx.rs @@ -9,7 +9,7 @@ //! //! [Wikipedia][wiki] provides a quick overview of the instructions available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wiki]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions diff --git a/library/stdarch/crates/core_arch/src/x86_64/bmi.rs b/library/stdarch/crates/core_arch/src/x86_64/bmi.rs index ee41d4137591..d5fd97583fb1 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/bmi.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/bmi.rs @@ -6,7 +6,7 @@ //! [Wikipedia][wikipedia_bmi] provides a quick overview of the instructions //! available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [wikipedia_bmi]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 #[cfg(test)] diff --git a/library/stdarch/crates/core_arch/src/x86_64/bmi2.rs b/library/stdarch/crates/core_arch/src/x86_64/bmi2.rs index 4eb53ed5ea4a..be12465c8147 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/bmi2.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/bmi2.rs @@ -6,7 +6,7 @@ //! [Wikipedia][wikipedia_bmi] provides a quick overview of the instructions //! available. //! -//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf +//! [intel64_ref]: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf //! [wikipedia_bmi]: //! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 From 97927aa4702e729ac4f36604d2e517a0f3166d90 Mon Sep 17 00:00:00 2001 From: Jesung Yang Date: Thu, 18 Dec 2025 00:03:05 +0000 Subject: [PATCH 0983/3801] feat: pretty print attributes up to `cfg(false)` Extend ItemTree pretty-printing to include attributes even when a cfg expression evaluates to false, emitting explicit `cfg(cfg_expr)` marker after the attributes. This improves testability of ItemTree attribute handling by exposing more information in pretty-printed output. --- .../rust-analyzer/crates/cfg/src/cfg_expr.rs | 30 +++++++++++++++++++ .../crates/hir-def/src/item_tree/pretty.rs | 9 ++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs index 76e0aba859e6..a0e0dc5ff090 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs @@ -56,6 +56,36 @@ pub enum CfgExpr { Not(Box), } +impl fmt::Display for CfgExpr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + CfgExpr::Atom(atom) => atom.fmt(f), + CfgExpr::All(exprs) => { + write!(f, "all(")?; + for (i, expr) in exprs.iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + expr.fmt(f)?; + } + write!(f, ")") + } + CfgExpr::Any(exprs) => { + write!(f, "any(")?; + for (i, expr) in exprs.iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + expr.fmt(f)?; + } + write!(f, ")") + } + CfgExpr::Not(expr) => write!(f, "not({})", expr), + CfgExpr::Invalid => write!(f, "invalid"), + } + } +} + impl From for CfgExpr { fn from(atom: CfgAtom) -> Self { CfgExpr::Atom(atom) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs index 66a2d14a734f..c89299e6d863 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs @@ -86,9 +86,9 @@ impl Printer<'_> { } fn print_attrs(&mut self, attrs: &AttrsOrCfg, inner: bool, separated_by: &str) { - let AttrsOrCfg::Enabled { attrs } = attrs else { - w!(self, "#[cfg(false)]{separated_by}"); - return; + let (cfg_disabled_expr, attrs) = match attrs { + AttrsOrCfg::Enabled { attrs } => (None, attrs), + AttrsOrCfg::CfgDisabled(inner_box) => (Some(&inner_box.0), &inner_box.1), }; let inner = if inner { "!" } else { "" }; for attr in &*attrs.as_ref() { @@ -101,6 +101,9 @@ impl Printer<'_> { separated_by, ); } + if let Some(expr) = cfg_disabled_expr { + w!(self, "#{inner}[cfg({expr})]{separated_by}"); + } } fn print_attrs_of(&mut self, of: ModItemId, separated_by: &str) { From 23d056329518bc0e98b4a4a1838bd4536ab08fd3 Mon Sep 17 00:00:00 2001 From: Jesung Yang Date: Tue, 16 Dec 2025 05:49:37 +0000 Subject: [PATCH 0984/3801] feat: introduce `crate_attrs` field in `rust-project.json` Since the commit 50384460c68f ("Rewrite method resolution to follow rustc more closely"), the method resolution logic has changed: rust-analyzer only looks up inherent methods for primitive types in sysroot crates. Unfortunately, this change broke at least one project that relies on `rust-project.json`: Rust-for-Linux. Its auto-generated `rust-project.json` directly embeds `core`, `alloc`, and `std` in the `crates` list without defining `sysroot_src`. Consequently, rust-analyzer fails to identify them as sysroot crates, breaking IDE support for primitive methods (e.g., `0_i32.rotate_left(0)`). However, specifying `sysroot_src` creates a new issue: it implicitly adds `std` as a dependency to all kernel module crates, which are actually compiled with `-Zcrate-attr=no_std`. Since rust-analyzer cannot see compiler flags passed outside of the project definition, we need a method to explicitly specify `#![no_std]` or, more generally, crate-level attributes through the project configuration. To resolve this, extend the `rust-project.json` format with a new `crate_attrs` field. This allows users to specify crate-level attributes such as `#![no_std]` directly into the configuration, enabling rust-analyzer to respect them when analyzing crates. References: - The original Zulip discussion: https://rust-lang.zulipchat.com/#narrow/channel/185405-t-compiler.2Frust-analyzer/topic/Primitive.20type.20inherent.20method.20lookup.20fails/with/562983853 --- .../rust-analyzer/crates/base-db/src/input.rs | 19 ++++ .../rust-analyzer/crates/hir-def/src/attrs.rs | 92 +++++++++++++++---- .../crates/hir-def/src/item_tree.rs | 52 ++++++++++- .../crates/hir-def/src/item_tree/attrs.rs | 59 ++++++++++-- .../crates/hir-def/src/item_tree/tests.rs | 42 +++++++++ .../crates/hir-def/src/nameres/collector.rs | 13 +++ .../hir-def/src/nameres/tests/incremental.rs | 2 + .../rust-analyzer/crates/hir/src/semantics.rs | 16 +++- .../src/handlers/unused_variables.rs | 40 ++++++++ .../crates/ide-diagnostics/src/lib.rs | 23 +++-- .../crates/ide/src/doc_links/tests.rs | 15 +++ src/tools/rust-analyzer/crates/ide/src/lib.rs | 2 + .../rust-analyzer/crates/ide/src/status.rs | 2 + .../crates/project-model/src/project_json.rs | 5 + .../crates/project-model/src/tests.rs | 9 ++ .../crates/project-model/src/workspace.rs | 5 + .../project-model/test_data/crate-attrs.json | 13 +++ .../cargo_hello_world_project_model.txt | 5 + ...project_model_with_selective_overrides.txt | 5 + ..._project_model_with_wildcard_overrides.txt | 5 + .../output/rust_project_cfg_groups.txt | 2 + .../output/rust_project_crate_attrs.txt | 54 +++++++++++ ...rust_project_hello_world_project_model.txt | 1 + .../crates/test-fixture/src/lib.rs | 6 ++ .../crates/test-utils/src/fixture.rs | 18 +++- .../docs/book/src/non_cargo_based_projects.md | 9 ++ 26 files changed, 473 insertions(+), 41 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/project-model/test_data/crate-attrs.json create mode 100644 src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_crate_attrs.txt diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index 14649dde648f..240f1264917a 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -351,6 +351,8 @@ pub struct CrateData { /// declared in source via `extern crate test`. pub dependencies: Vec>, pub origin: CrateOrigin, + /// Extra crate-level attributes, including the surrounding `#![]`. + pub crate_attrs: Box<[Box]>, pub is_proc_macro: bool, /// The working directory to run proc-macros in invoked in the context of this crate. /// This is the workspace root of the cargo workspace for workspace members, the crate manifest @@ -530,6 +532,7 @@ impl CrateGraphBuilder { mut potential_cfg_options: Option, mut env: Env, origin: CrateOrigin, + crate_attrs: Vec, is_proc_macro: bool, proc_macro_cwd: Arc, ws_data: Arc, @@ -539,12 +542,17 @@ impl CrateGraphBuilder { if let Some(potential_cfg_options) = &mut potential_cfg_options { potential_cfg_options.shrink_to_fit(); } + let crate_attrs: Vec<_> = crate_attrs + .into_iter() + .map(|raw_attr| format!("#![{raw_attr}]").into_boxed_str()) + .collect(); self.arena.alloc(CrateBuilder { basic: CrateData { root_file_id, edition, dependencies: Vec::new(), origin, + crate_attrs: crate_attrs.into_boxed_slice(), is_proc_macro, proc_macro_cwd, }, @@ -648,6 +656,7 @@ impl CrateGraphBuilder { edition: krate.basic.edition, is_proc_macro: krate.basic.is_proc_macro, origin: krate.basic.origin.clone(), + crate_attrs: krate.basic.crate_attrs.clone(), root_file_id: krate.basic.root_file_id, proc_macro_cwd: krate.basic.proc_macro_cwd.clone(), }; @@ -975,6 +984,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), @@ -988,6 +998,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), @@ -1001,6 +1012,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), @@ -1034,6 +1046,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), @@ -1047,6 +1060,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), @@ -1075,6 +1089,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), @@ -1088,6 +1103,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), @@ -1101,6 +1117,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), @@ -1129,6 +1146,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), @@ -1142,6 +1160,7 @@ mod tests { Default::default(), Env::default(), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), empty_ws_data(), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs index febc794b5a05..34a9230794d1 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs @@ -39,7 +39,7 @@ use rustc_abi::ReprOptions; use rustc_hash::FxHashSet; use smallvec::SmallVec; use syntax::{ - AstNode, AstToken, NodeOrToken, SmolStr, SyntaxNode, SyntaxToken, T, + AstNode, AstToken, NodeOrToken, SmolStr, SourceFile, SyntaxNode, SyntaxToken, T, ast::{self, AttrDocCommentIter, HasAttrs, IsString, TokenTreeChildren}, }; use tt::{TextRange, TextSize}; @@ -292,35 +292,69 @@ bitflags::bitflags! { } } +pub fn parse_extra_crate_attrs(db: &dyn DefDatabase, krate: Crate) -> Option { + let crate_data = krate.data(db); + let crate_attrs = &crate_data.crate_attrs; + if crate_attrs.is_empty() { + return None; + } + // All attributes are already enclosed in `#![]`. + let combined = crate_attrs.concat(); + let p = SourceFile::parse(&combined, crate_data.edition); + + let errs = p.errors(); + if !errs.is_empty() { + let base_msg = "Failed to parse extra crate-level attribute"; + let crate_name = + krate.extra_data(db).display_name.as_ref().map_or("{unknown}", |name| name.as_str()); + let mut errs = errs.iter().peekable(); + let mut offset = TextSize::from(0); + for raw_attr in crate_attrs { + let attr_end = offset + TextSize::of(&**raw_attr); + if errs.peeking_take_while(|e| e.range().start() < attr_end).count() > 0 { + tracing::error!("{base_msg} {raw_attr} for crate {crate_name}"); + } + offset = attr_end + } + return None; + } + + Some(p.tree()) +} + fn attrs_source( db: &dyn DefDatabase, owner: AttrDefId, -) -> (InFile, Option>, Crate) { +) -> (InFile, Option>, Option, Crate) { let (owner, krate) = match owner { AttrDefId::ModuleId(id) => { let def_map = id.def_map(db); - let (definition, declaration) = match def_map[id].origin { + let krate = def_map.krate(); + let (definition, declaration, extra_crate_attrs) = match def_map[id].origin { ModuleOrigin::CrateRoot { definition } => { - let file = db.parse(definition).tree(); - (InFile::new(definition.into(), ast::AnyHasAttrs::from(file)), None) + let definition_source = db.parse(definition).tree(); + let definition = InFile::new(definition.into(), definition_source.into()); + let extra_crate_attrs = parse_extra_crate_attrs(db, krate); + (definition, None, extra_crate_attrs) } ModuleOrigin::File { declaration, declaration_tree_id, definition, .. } => { + let definition_source = db.parse(definition).tree(); + let definition = InFile::new(definition.into(), definition_source.into()); let declaration = InFile::new(declaration_tree_id.file_id(), declaration); let declaration = declaration.with_value(declaration.to_node(db)); - let definition_source = db.parse(definition).tree(); - (InFile::new(definition.into(), definition_source.into()), Some(declaration)) + (definition, Some(declaration), None) } ModuleOrigin::Inline { definition_tree_id, definition } => { let definition = InFile::new(definition_tree_id.file_id(), definition); let definition = definition.with_value(definition.to_node(db).into()); - (definition, None) + (definition, None, None) } ModuleOrigin::BlockExpr { block, .. } => { let definition = block.to_node(db); - (block.with_value(definition.into()), None) + (block.with_value(definition.into()), None, None) } }; - return (definition, declaration, def_map.krate()); + return (definition, declaration, extra_crate_attrs, krate); } AttrDefId::AdtId(AdtId::StructId(it)) => attrs_from_ast_id_loc(db, it), AttrDefId::AdtId(AdtId::UnionId(it)) => attrs_from_ast_id_loc(db, it), @@ -339,7 +373,7 @@ fn attrs_source( AttrDefId::ExternCrateId(it) => attrs_from_ast_id_loc(db, it), AttrDefId::UseId(it) => attrs_from_ast_id_loc(db, it), }; - (owner, None, krate) + (owner, None, None, krate) } fn collect_attrs( @@ -347,14 +381,15 @@ fn collect_attrs( owner: AttrDefId, mut callback: impl FnMut(Meta) -> ControlFlow, ) -> Option { - let (source, outer_mod_decl, krate) = attrs_source(db, owner); + let (source, outer_mod_decl, extra_crate_attrs, krate) = attrs_source(db, owner); + let extra_attrs = extra_crate_attrs + .into_iter() + .flat_map(|src| src.attrs()) + .chain(outer_mod_decl.into_iter().flat_map(|it| it.value.attrs())); let mut cfg_options = None; expand_cfg_attr( - outer_mod_decl - .into_iter() - .flat_map(|it| it.value.attrs()) - .chain(ast::attrs_including_inner(&source.value)), + extra_attrs.chain(ast::attrs_including_inner(&source.value)), || cfg_options.get_or_insert_with(|| krate.cfg_options(db)), move |meta, _, _, _| callback(meta), ) @@ -1013,10 +1048,12 @@ impl AttrFlags { pub fn doc_html_root_url(db: &dyn DefDatabase, krate: Crate) -> Option { let root_file_id = krate.root_file_id(db); let syntax = db.parse(root_file_id).tree(); + let extra_crate_attrs = + parse_extra_crate_attrs(db, krate).into_iter().flat_map(|src| src.attrs()); let mut cfg_options = None; expand_cfg_attr( - syntax.attrs(), + extra_crate_attrs.chain(syntax.attrs()), || cfg_options.get_or_insert(krate.cfg_options(db)), |attr, _, _, _| { if let Meta::TokenTree { path, tt } = attr @@ -1231,8 +1268,11 @@ impl AttrFlags { // We LRU this query because it is only used by IDE. #[salsa::tracked(returns(ref), lru = 250)] pub fn docs(db: &dyn DefDatabase, owner: AttrDefId) -> Option> { - let (source, outer_mod_decl, krate) = attrs_source(db, owner); + let (source, outer_mod_decl, _extra_crate_attrs, krate) = attrs_source(db, owner); let inner_attrs_node = source.value.inner_attributes_node(); + // Note: we don't have to pass down `_extra_crate_attrs` here, since `extract_docs` + // does not handle crate-level attributes related to docs. + // See: https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html#at-the-crate-level extract_docs(&|| krate.cfg_options(db), source, outer_mod_decl, inner_attrs_node) } @@ -1480,8 +1520,9 @@ mod tests { use test_fixture::WithFixture; use tt::{TextRange, TextSize}; - use crate::attrs::IsInnerDoc; - use crate::{attrs::Docs, test_db::TestDB}; + use crate::AttrDefId; + use crate::attrs::{AttrFlags, Docs, IsInnerDoc}; + use crate::test_db::TestDB; #[test] fn docs() { @@ -1617,4 +1658,15 @@ mod tests { Some((in_file(range(263, 265)), IsInnerDoc::Yes)) ); } + + #[test] + fn crate_attrs() { + let fixture = r#" +//- /lib.rs crate:foo crate-attr:no_std crate-attr:cfg(target_arch="x86") + "#; + let (db, file_id) = TestDB::with_single_file(fixture); + let module = db.module_for_file(file_id.file_id(&db)); + let attrs = AttrFlags::query(&db, AttrDefId::ModuleId(module)); + assert!(attrs.contains(AttrFlags::IS_NO_STD | AttrFlags::HAS_CFG)); + } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 2a104fff2b92..6eab8888d92d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -44,6 +44,7 @@ use std::{ }; use ast::{AstNode, StructKind}; +use cfg::CfgOptions; use hir_expand::{ ExpandTo, HirFileId, mod_path::{ModPath, PathKind}, @@ -52,13 +53,17 @@ use hir_expand::{ use intern::Interned; use la_arena::{Idx, RawIdx}; use rustc_hash::FxHashMap; -use span::{AstIdNode, Edition, FileAstId, SyntaxContext}; +use span::{ + AstIdNode, Edition, FileAstId, NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER, Span, SpanAnchor, + SyntaxContext, +}; use stdx::never; -use syntax::{SyntaxKind, ast, match_ast}; +use syntax::{SourceFile, SyntaxKind, ast, match_ast}; use thin_vec::ThinVec; use triomphe::Arc; +use tt::TextRange; -use crate::{BlockId, Lookup, db::DefDatabase}; +use crate::{BlockId, Lookup, attrs::parse_extra_crate_attrs, db::DefDatabase}; pub(crate) use crate::item_tree::{ attrs::*, @@ -88,6 +93,33 @@ impl fmt::Debug for RawVisibilityId { } } +fn lower_extra_crate_attrs<'a>( + db: &dyn DefDatabase, + crate_attrs_as_src: SourceFile, + file_id: span::EditionedFileId, + cfg_options: &dyn Fn() -> &'a CfgOptions, +) -> AttrsOrCfg { + #[derive(Copy, Clone)] + struct FakeSpanMap { + file_id: span::EditionedFileId, + } + impl syntax_bridge::SpanMapper for FakeSpanMap { + fn span_for(&self, range: TextRange) -> Span { + Span { + range, + anchor: SpanAnchor { + file_id: self.file_id, + ast_id: NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER, + }, + ctx: SyntaxContext::root(self.file_id.edition()), + } + } + } + + let span_map = FakeSpanMap { file_id }; + AttrsOrCfg::lower(db, &crate_attrs_as_src, cfg_options, span_map) +} + #[salsa_macros::tracked(returns(deref))] pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc { let _p = tracing::info_span!("file_item_tree_query", ?file_id).entered(); @@ -98,7 +130,19 @@ pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> let mut item_tree = match_ast! { match syntax { ast::SourceFile(file) => { - let top_attrs = ctx.lower_attrs(&file); + let krate = file_id.krate(db); + let root_file_id = krate.root_file_id(db); + let extra_top_attrs = (file_id == root_file_id).then(|| { + parse_extra_crate_attrs(db, krate).map(|crate_attrs| { + let file_id = root_file_id.editioned_file_id(db); + lower_extra_crate_attrs(db, crate_attrs, file_id, &|| ctx.cfg_options()) + }) + }).flatten(); + let top_attrs = match extra_top_attrs { + Some(attrs @ AttrsOrCfg::Enabled { .. }) => attrs.merge(ctx.lower_attrs(&file)), + Some(attrs @ AttrsOrCfg::CfgDisabled(_)) => attrs, + None => ctx.lower_attrs(&file) + }; let mut item_tree = ctx.lower_module_items(&file); item_tree.top_attrs = top_attrs; item_tree diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs index 5c635a4b3831..81a9b28b628e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs @@ -16,9 +16,9 @@ use hir_expand::{ attrs::{Attr, AttrId, AttrInput, Meta, collect_item_tree_attrs}, mod_path::ModPath, name::Name, - span_map::SpanMapRef, }; use intern::{Interned, Symbol, sym}; +use span::Span; use syntax::{AstNode, T, ast}; use syntax_bridge::DocCommentDesugarMode; use tt::token_to_literal; @@ -42,12 +42,15 @@ impl Default for AttrsOrCfg { } impl AttrsOrCfg { - pub(crate) fn lower<'a>( + pub(crate) fn lower<'a, S>( db: &dyn DefDatabase, owner: &dyn ast::HasAttrs, cfg_options: &dyn Fn() -> &'a CfgOptions, - span_map: SpanMapRef<'_>, - ) -> AttrsOrCfg { + span_map: S, + ) -> AttrsOrCfg + where + S: syntax_bridge::SpanMapper + Copy, + { let mut attrs = Vec::new(); let result = collect_item_tree_attrs::(owner, cfg_options, |meta, container, _, _| { @@ -55,17 +58,17 @@ impl AttrsOrCfg { // tracking. let (span, path_range, input) = match meta { Meta::NamedKeyValue { path_range, name: _, value } => { - let span = span_map.span_for_range(path_range); + let span = span_map.span_for(path_range); let input = value.map(|value| { Box::new(AttrInput::Literal(token_to_literal( value.text(), - span_map.span_for_range(value.text_range()), + span_map.span_for(value.text_range()), ))) }); (span, path_range, input) } Meta::TokenTree { path, tt } => { - let span = span_map.span_for_range(path.range); + let span = span_map.span_for(path.range); let tt = syntax_bridge::syntax_node_to_token_tree( tt.syntax(), span_map, @@ -76,7 +79,7 @@ impl AttrsOrCfg { (span, path.range, input) } Meta::Path { path } => { - let span = span_map.span_for_range(path.range); + let span = span_map.span_for(path.range); (span, path.range, None) } }; @@ -90,7 +93,7 @@ impl AttrsOrCfg { .filter(|it| it.kind().is_any_identifier()); ModPath::from_tokens( db, - &mut |range| span_map.span_for_range(range).ctx, + &mut |range| span_map.span_for(range).ctx, is_abs, segments, ) @@ -107,6 +110,44 @@ impl AttrsOrCfg { None => AttrsOrCfg::Enabled { attrs }, } } + + // Merges two `AttrsOrCfg`s, assuming `self` is placed before `other` in the source code. + // The operation follows these rules: + // + // - If `self` and `other` are both `AttrsOrCfg::Enabled`, the result is a new + // `AttrsOrCfg::Enabled`. It contains the concatenation of `self`'s attributes followed by + // `other`'s. + // - If `self` is `AttrsOrCfg::Enabled` but `other` is `AttrsOrCfg::CfgDisabled`, the result + // is a new `AttrsOrCfg::CfgDisabled`. It contains the concatenation of `self`'s attributes + // followed by `other`'s. + // - If `self` is `AttrsOrCfg::CfgDisabled`, return `self` as-is. + // + // The rationale is that attribute collection is sequential and order-sensitive. This operation + // preserves those semantics when combining attributes from two different sources. + // `AttrsOrCfg::CfgDisabled` marks a point where collection stops due to a false `#![cfg(...)]` + // condition. It acts as a "breakpoint": attributes beyond it are not collected. Therefore, + // when merging, an `AttrsOrCfg::CfgDisabled` on the left-hand side short-circuits the + // operation, while an `AttrsOrCfg::CfgDisabled` on the right-hand side preserves all + // attributes collected up to that point. + // + // Note that this operation is neither commutative nor associative. + pub(crate) fn merge(self, other: AttrsOrCfg) -> AttrsOrCfg { + match (self, other) { + (AttrsOrCfg::Enabled { attrs }, AttrsOrCfg::Enabled { attrs: other_attrs }) => { + let mut v = attrs.0.into_vec(); + v.extend(other_attrs.0); + AttrsOrCfg::Enabled { attrs: AttrsOwned(v.into_boxed_slice()) } + } + (AttrsOrCfg::Enabled { attrs }, AttrsOrCfg::CfgDisabled(mut other)) => { + let other_attrs = &mut other.1; + let mut v = attrs.0.into_vec(); + v.extend(std::mem::take(&mut other_attrs.0)); + other_attrs.0 = v.into_boxed_slice(); + AttrsOrCfg::CfgDisabled(other) + } + (this @ AttrsOrCfg::CfgDisabled(_), _) => this, + } + } } #[derive(Debug, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs index a57432f33c3d..1926ed74e869 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs @@ -244,3 +244,45 @@ pub(self) struct S; "#]], ) } + +#[test] +fn crate_attrs_should_preserve_order() { + check( + r#" +//- /main.rs crate:foo crate-attr:no_std crate-attr:features(f16) crate-attr:crate_type="bin" + "#, + expect![[r##" + #![no_std] + #![features(f16)] + #![crate_type = "bin"] + "##]], + ); +} + +#[test] +fn crate_attrs_with_disabled_cfg_injected() { + check( + r#" +//- /main.rs crate:foo crate-attr:no_std crate-attr:cfg(false) crate-attr:features(f16,f128) crate-attr:crate_type="bin" + "#, + expect![[r#" + #![no_std] + #![cfg(false)] + "#]], + ); +} + +#[test] +fn crate_attrs_with_disabled_cfg_in_source() { + check( + r#" +//- /lib.rs crate:foo crate-attr:no_std +#![cfg(false)] +#![no_core] + "#, + expect![[r#" + #![no_std] + #![cfg(false)] + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 08edf41c5694..10581378bef9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -2608,4 +2608,17 @@ foo!(KABOOM); "#, ); } + + #[test] + fn crate_attrs() { + let fixture = r#" +//- /lib.rs crate:foo crate-attr:recursion_limit="4" crate-attr:no_core crate-attr:no_std crate-attr:feature(register_tool) + "#; + let (db, file_id) = TestDB::with_single_file(fixture); + let def_map = crate_def_map(&db, file_id.krate(&db)); + assert_eq!(def_map.recursion_limit(), 4); + assert!(def_map.is_no_core()); + assert!(def_map.is_no_std()); + assert!(def_map.is_unstable_feature_enabled(&sym::register_tool)); + } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs index 57243346019f..225ba958634e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs @@ -76,6 +76,7 @@ pub const BAZ: u32 = 0; None, Env::default(), CrateOrigin::Local { repo: None, name: Some(Symbol::intern(crate_name)) }, + Vec::new(), false, Arc::new( // FIXME: This is less than ideal @@ -117,6 +118,7 @@ pub const BAZ: u32 = 0; expect![[r#" [ "crate_local_def_map", + "file_item_tree_query", "crate_local_def_map", ] "#]], diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 80fac3512ece..b65a24d61c6e 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -14,6 +14,7 @@ use base_db::FxIndexSet; use either::Either; use hir_def::{ DefWithBodyId, FunctionId, MacroId, StructId, TraitId, VariantId, + attrs::parse_extra_crate_attrs, expr_store::{Body, ExprOrPatSource, HygieneId, path::Path}, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, nameres::{ModuleOrigin, crate_def_map}, @@ -266,14 +267,27 @@ impl Semantics<'_, DB> { pub fn lint_attrs( &self, + file_id: FileId, krate: Crate, item: ast::AnyHasAttrs, ) -> impl DoubleEndedIterator { let mut cfg_options = None; let cfg_options = || *cfg_options.get_or_insert_with(|| krate.id.cfg_options(self.db)); + + let is_crate_root = file_id == krate.root_file(self.imp.db); + let is_source_file = ast::SourceFile::can_cast(item.syntax().kind()); + let extra_crate_attrs = (is_crate_root && is_source_file) + .then(|| { + parse_extra_crate_attrs(self.imp.db, krate.id) + .into_iter() + .flat_map(|src| src.attrs()) + }) + .into_iter() + .flatten(); + let mut result = Vec::new(); hir_expand::attrs::expand_cfg_attr::( - ast::attrs_including_inner(&item), + extra_crate_attrs.chain(ast::attrs_including_inner(&item)), cfg_options, |attr, _, _, _| { let hir_expand::attrs::Meta::TokenTree { path, tt } = attr else { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs index b7ec8fa53fa7..52a2f44fd0f8 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs @@ -387,6 +387,46 @@ struct S { field : u32 } fn f(S { field }: error) { // ^^^^^ 💡 warn: unused variable } +"#, + ); + } + + #[test] + fn crate_attrs_lint_smoke_test() { + check_diagnostics( + r#" +//- /lib.rs crate:foo crate-attr:deny(unused_variables) +fn main() { + let x = 2; + //^ 💡 error: unused variable +} +"#, + ); + } + + #[test] + fn crate_attrs_should_not_override_lints_in_source() { + check_diagnostics( + r#" +//- /lib.rs crate:foo crate-attr:allow(unused_variables) +#![deny(unused_variables)] +fn main() { + let x = 2; + //^ 💡 error: unused variable +} +"#, + ); + } + + #[test] + fn crate_attrs_should_preserve_lint_order() { + check_diagnostics( + r#" +//- /lib.rs crate:foo crate-attr:allow(unused_variables) crate-attr:warn(unused_variables) +fn main() { + let x = 2; + //^ 💡 warn: unused variable +} "#, ); } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index 2b8474c3163b..0b321442497b 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -485,7 +485,7 @@ pub fn semantic_diagnostics( // The edition isn't accurate (each diagnostics may have its own edition due to macros), // but it's okay as it's only being used for error recovery. - handle_lints(&ctx.sema, krate, &mut lints, editioned_file_id.edition(db)); + handle_lints(&ctx.sema, file_id, krate, &mut lints, editioned_file_id.edition(db)); res.retain(|d| d.severity != Severity::Allow); @@ -593,6 +593,7 @@ fn build_lints_map( fn handle_lints( sema: &Semantics<'_, RootDatabase>, + file_id: FileId, krate: hir::Crate, diagnostics: &mut [(InFile, &mut Diagnostic)], edition: Edition, @@ -609,10 +610,10 @@ fn handle_lints( } let mut diag_severity = - lint_severity_at(sema, krate, node, &lint_groups(&diag.code, edition)); + lint_severity_at(sema, file_id, krate, node, &lint_groups(&diag.code, edition)); if let outline_diag_severity @ Some(_) = - find_outline_mod_lint_severity(sema, krate, node, diag, edition) + find_outline_mod_lint_severity(sema, file_id, krate, node, diag, edition) { diag_severity = outline_diag_severity; } @@ -635,6 +636,7 @@ fn default_lint_severity(lint: &Lint, edition: Edition) -> Severity { fn find_outline_mod_lint_severity( sema: &Semantics<'_, RootDatabase>, + file_id: FileId, krate: hir::Crate, node: &InFile, diag: &Diagnostic, @@ -651,6 +653,7 @@ fn find_outline_mod_lint_severity( let lint_groups = lint_groups(&diag.code, edition); lint_attrs( sema, + file_id, krate, ast::AnyHasAttrs::cast(module_source_file.value).expect("SourceFile always has attrs"), ) @@ -659,6 +662,7 @@ fn find_outline_mod_lint_severity( fn lint_severity_at( sema: &Semantics<'_, RootDatabase>, + file_id: FileId, krate: hir::Crate, node: &InFile, lint_groups: &LintGroups, @@ -667,21 +671,28 @@ fn lint_severity_at( .ancestors() .filter_map(ast::AnyHasAttrs::cast) .find_map(|ancestor| { - lint_attrs(sema, krate, ancestor) + lint_attrs(sema, file_id, krate, ancestor) .find_map(|(lint, severity)| lint_groups.contains(&lint).then_some(severity)) }) .or_else(|| { - lint_severity_at(sema, krate, &sema.find_parent_file(node.file_id)?, lint_groups) + lint_severity_at( + sema, + file_id, + krate, + &sema.find_parent_file(node.file_id)?, + lint_groups, + ) }) } // FIXME: Switch this to analysis' `expand_cfg_attr`. fn lint_attrs( sema: &Semantics<'_, RootDatabase>, + file_id: FileId, krate: hir::Crate, ancestor: ast::AnyHasAttrs, ) -> impl Iterator { - sema.lint_attrs(krate, ancestor).rev().map(|(lint_attr, lint)| { + sema.lint_attrs(file_id, krate, ancestor).rev().map(|(lint_attr, lint)| { let severity = match lint_attr { hir::LintAttr::Allow | hir::LintAttr::Expect => Severity::Allow, hir::LintAttr::Warn => Severity::Warning, diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs index 8594a0a22475..a61a6c677f65 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs @@ -658,6 +658,21 @@ pub struct B$0ar ); } +#[test] +fn rewrite_html_root_url_using_crate_attr() { + check_rewrite( + r#" +//- /main.rs crate:foo crate-attr:doc(arbitrary_attribute="test",html_root_url="https:/example.com",arbitrary_attribute2) +pub mod foo { + pub struct Foo; +} +/// [Foo](foo::Foo) +pub struct B$0ar +"#, + expect![[r#"[Foo](https://example.com/foo/foo/struct.Foo.html)"#]], + ); +} + #[test] fn rewrite_on_field() { check_rewrite( diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index 94362649043d..0066ceed21ed 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -254,6 +254,7 @@ impl Analysis { TryFrom::try_from(&*std::env::current_dir().unwrap().as_path().to_string_lossy()) .unwrap(), ); + let crate_attrs = Vec::new(); cfg_options.insert_atom(sym::test); crate_graph.add_crate_root( file_id, @@ -264,6 +265,7 @@ impl Analysis { None, Env::default(), CrateOrigin::Local { repo: None, name: None }, + crate_attrs, false, proc_macro_cwd, Arc::new(CrateWorkspaceData { diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs index cfcd76d2aa3b..7f377e416b32 100644 --- a/src/tools/rust-analyzer/crates/ide/src/status.rs +++ b/src/tools/rust-analyzer/crates/ide/src/status.rs @@ -40,6 +40,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { edition, dependencies, origin, + crate_attrs, is_proc_macro, proc_macro_cwd, } = crate_id.data(db); @@ -62,6 +63,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { format_to!(buf, " Potential cfgs: {:?}\n", potential_cfg_options); format_to!(buf, " Env: {:?}\n", env); format_to!(buf, " Origin: {:?}\n", origin); + format_to!(buf, " Extra crate-level attrs: {:?}\n", crate_attrs); format_to!(buf, " Is a proc macro crate: {}\n", is_proc_macro); format_to!(buf, " Proc macro cwd: {:?}\n", proc_macro_cwd); let deps = dependencies diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index 041b9accf41d..b3478d2cfe03 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -163,6 +163,7 @@ impl ProjectJson { cfg, target: crate_data.target, env: crate_data.env, + crate_attrs: crate_data.crate_attrs, proc_macro_dylib_path: crate_data .proc_macro_dylib_path .map(absolutize_on_base), @@ -244,6 +245,8 @@ pub struct Crate { pub(crate) cfg: Vec, pub(crate) target: Option, pub(crate) env: FxHashMap, + // Extra crate-level attributes, without the surrounding `#![]`. + pub(crate) crate_attrs: Vec, pub(crate) proc_macro_dylib_path: Option, pub(crate) is_workspace_member: bool, pub(crate) include: Vec, @@ -365,6 +368,8 @@ struct CrateData { target: Option, #[serde(default)] env: FxHashMap, + #[serde(default)] + crate_attrs: Vec, proc_macro_dylib_path: Option, is_workspace_member: Option, source: Option, diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index 1908fc02904a..a03ed562e1be 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -198,6 +198,15 @@ fn rust_project_cfg_groups() { check_crate_graph(crate_graph, expect_file!["../test_data/output/rust_project_cfg_groups.txt"]); } +#[test] +fn rust_project_crate_attrs() { + let (crate_graph, _proc_macros) = load_rust_project("crate-attrs.json"); + check_crate_graph( + crate_graph, + expect_file!["../test_data/output/rust_project_crate_attrs.txt"], + ); +} + #[test] fn crate_graph_dedup_identical() { let (mut crate_graph, proc_macros) = load_cargo("regex-metadata.json"); diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 747aa68f082d..fa3a79e041e0 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -1093,6 +1093,7 @@ fn project_json_to_crate_graph( cfg, target, env, + crate_attrs, proc_macro_dylib_path, is_proc_macro, repository, @@ -1163,6 +1164,7 @@ fn project_json_to_crate_graph( } else { CrateOrigin::Local { repo: None, name: None } }, + crate_attrs.clone(), *is_proc_macro, match proc_macro_cwd { Some(path) => Arc::new(path.clone()), @@ -1467,6 +1469,7 @@ fn detached_file_to_crate_graph( repo: None, name: display_name.map(|n| n.canonical_name().to_owned()), }, + Vec::new(), false, Arc::new(detached_file.parent().to_path_buf()), crate_ws_data, @@ -1647,6 +1650,7 @@ fn add_target_crate_root( potential_cfg_options, env, origin, + Vec::new(), matches!(kind, TargetKind::Lib { is_proc_macro: true }), proc_macro_cwd, crate_ws_data, @@ -1830,6 +1834,7 @@ fn sysroot_to_crate_graph( None, Env::default(), CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)), + Vec::new(), false, Arc::new(stitched[krate].root.parent().to_path_buf()), crate_ws_data.clone(), diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/crate-attrs.json b/src/tools/rust-analyzer/crates/project-model/test_data/crate-attrs.json new file mode 100644 index 000000000000..b2a7e3715017 --- /dev/null +++ b/src/tools/rust-analyzer/crates/project-model/test_data/crate-attrs.json @@ -0,0 +1,13 @@ +{ + "sysroot_src": null, + "crates": [ + { + "display_name": "foo", + "root_module": "$ROOT$src/lib.rs", + "edition": "2024", + "deps": [], + "crate_attrs": ["no_std", "feature(f16,f128)", "crate_type = \"lib\""], + "is_workspace_member": true + } + ] +} diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt index 4f6ce4dc9537..a895ef53afa0 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt @@ -21,6 +21,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -106,6 +107,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -191,6 +193,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -276,6 +279,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -344,6 +348,7 @@ ), name: "libc", }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt index 4f6ce4dc9537..a895ef53afa0 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt @@ -21,6 +21,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -106,6 +107,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -191,6 +193,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -276,6 +279,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -344,6 +348,7 @@ ), name: "libc", }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt index 6862918e09ae..9eb47947b6fd 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt @@ -21,6 +21,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -105,6 +106,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -189,6 +191,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -273,6 +276,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -340,6 +344,7 @@ ), name: "libc", }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt index 28ad3236ae81..32f9206a3e16 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt @@ -12,6 +12,7 @@ "hello_world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$", @@ -62,6 +63,7 @@ "other_crate", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$", diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_crate_attrs.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_crate_attrs.txt new file mode 100644 index 000000000000..21b484bc0c42 --- /dev/null +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_crate_attrs.txt @@ -0,0 +1,54 @@ +{ + 0: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2024, + dependencies: [], + origin: Local { + repo: None, + name: Some( + "foo", + ), + }, + crate_attrs: [ + "#![no_std]", + "#![feature(f16,f128)]", + "#![crate_type = \"lib\"]", + ], + is_proc_macro: false, + proc_macro_cwd: AbsPathBuf( + "$ROOT$", + ), + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "foo", + ), + canonical_name: "foo", + }, + ), + potential_cfg_options: None, + }, + cfg_options: CfgOptions( + [ + "rust_analyzer", + "test", + "true", + ], + ), + env: Env { + entries: {}, + }, + ws_data: CrateWorkspaceData { + target: Err( + "test has no target data", + ), + toolchain: None, + }, + }, +} \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt index dabb3aa67441..de793115b9d5 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt @@ -12,6 +12,7 @@ "hello_world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$", diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 5e8b250c24a0..01e4215cfb86 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -239,6 +239,7 @@ impl ChangeFixture { Some(meta.cfg), meta.env, origin, + meta.crate_attrs, false, proc_macro_cwd.clone(), crate_ws_data.clone(), @@ -292,6 +293,7 @@ impl ChangeFixture { String::from("__ra_is_test_fixture"), )]), CrateOrigin::Lang(LangCrateOrigin::Core), + Vec::new(), false, proc_macro_cwd.clone(), crate_ws_data.clone(), @@ -322,6 +324,7 @@ impl ChangeFixture { Some(default_cfg), default_env, CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, proc_macro_cwd.clone(), crate_ws_data.clone(), @@ -385,6 +388,7 @@ impl ChangeFixture { String::from("__ra_is_test_fixture"), )]), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), true, proc_macro_cwd, crate_ws_data, @@ -635,6 +639,7 @@ struct FileMeta { cfg: CfgOptions, edition: Edition, env: Env, + crate_attrs: Vec, introduce_new_source_root: Option, } @@ -666,6 +671,7 @@ impl FileMeta { cfg, edition: f.edition.map_or(Edition::CURRENT, |v| Edition::from_str(&v).unwrap()), env: f.env.into_iter().collect(), + crate_attrs: f.crate_attrs, introduce_new_source_root, } } diff --git a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs index 831d2b30c1b6..1f6262c897c7 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs @@ -107,6 +107,11 @@ pub struct Fixture { /// /// Syntax: `env:PATH=/bin,RUST_LOG=debug` pub env: FxHashMap, + /// Specifies extra crate-level attributes injected at the top of the crate root file. + /// This must be used with `crate` meta. + /// + /// Syntax: `crate-attr:no_std crate-attr:features(f16,f128) crate-attr:cfg(target_arch="x86")` + pub crate_attrs: Vec, /// Introduces a new source root. This file **and the following /// files** will belong the new source root. This must be used /// with `crate` meta. @@ -275,6 +280,7 @@ impl FixtureWithProjectMeta { let mut krate = None; let mut deps = Vec::new(); + let mut crate_attrs = Vec::new(); let mut extern_prelude = None; let mut edition = None; let mut cfgs = Vec::new(); @@ -292,6 +298,7 @@ impl FixtureWithProjectMeta { match key { "crate" => krate = Some(value.to_owned()), "deps" => deps = value.split(',').map(|it| it.to_owned()).collect(), + "crate-attr" => crate_attrs.push(value.to_owned()), "extern-prelude" => { if value.is_empty() { extern_prelude = Some(Vec::new()); @@ -334,6 +341,7 @@ impl FixtureWithProjectMeta { line, krate, deps, + crate_attrs, extern_prelude, cfgs, edition, @@ -548,7 +556,7 @@ fn parse_fixture_gets_full_meta() { //- toolchain: nightly //- proc_macros: identity //- minicore: coerce_unsized -//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo +//- /lib.rs crate:foo deps:bar,baz crate-attr:no_std crate-attr:features(f16,f128) crate-attr:cfg(target_arch="x86") cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo mod m; "#, ); @@ -561,6 +569,14 @@ mod m; assert_eq!("mod m;\n", meta.text); assert_eq!("foo", meta.krate.as_ref().unwrap()); + assert_eq!( + vec![ + "no_std".to_owned(), + "features(f16,f128)".to_owned(), + "cfg(target_arch=\"x86\")".to_owned() + ], + meta.crate_attrs + ); assert_eq!("/lib.rs", meta.path); assert_eq!(2, meta.env.len()); } diff --git a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md index 74489a9046ba..e7df4a5d7668 100644 --- a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md +++ b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md @@ -144,6 +144,15 @@ interface Crate { /// Environment variables, used for /// the `env!` macro env: { [key: string]: string; }; + /// Extra crate-level attributes applied to this crate. + /// + /// rust-analyzer will behave as if these attributes + /// were present before the first source line of the + /// crate root. + /// + /// Each string should contain the contents of a `#![...]` + /// crate-level attribute, without the surrounding `#![]`. + crate_attrs?: string[]; /// Whether the crate is a proc-macro crate. is_proc_macro: boolean; From 186fc3c0003c70f73e7cdeddd51d2531c033d82a Mon Sep 17 00:00:00 2001 From: Redddy Date: Thu, 18 Dec 2025 12:00:12 +0900 Subject: [PATCH 0985/3801] Clarify serialization macros documentation remove `MetadataDecodable` and add `BlobDecodable` and `LazyDecodable`. --- src/doc/rustc-dev-guide/src/serialization.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/serialization.md b/src/doc/rustc-dev-guide/src/serialization.md index a6c2ee17a667..fcea4f3e605b 100644 --- a/src/doc/rustc-dev-guide/src/serialization.md +++ b/src/doc/rustc-dev-guide/src/serialization.md @@ -126,20 +126,21 @@ and `Encodable`. all `Encoders` and `Decoders`. These should be used in crates that don't depend on [`rustc_middle`], or that have to be serialized by a type that does not implement `TyEncoder`. -- [`MetadataEncodable`] and [`MetadataDecodable`] generate implementations that - only allow decoding by [`rustc_metadata::rmeta::encoder::EncodeContext`] and - [`rustc_metadata::rmeta::decoder::DecodeContext`]. These are used for types - that contain [`rustc_metadata::rmeta::`]`Lazy*`. +- [`MetadataEncodable`] generate implementations that + only allow decoding by [`rustc_metadata::rmeta::encoder::EncodeContext`]. +- [`BlobDecodable`] and [`LazyDecodable`] generate implementations that decode + with the metadata blob decoders in [`rustc_metadata::rmeta`]; use `BlobDecodable` + when the type has no lazy metadata handles, and `LazyDecodable` when it does. - `TyEncodable` and `TyDecodable` generate implementation that apply to any `TyEncoder` or `TyDecoder`. These should be used for types that are only serialized in crate metadata and/or the incremental cache, which is most serializable types in `rustc_middle`. -[`MetadataDecodable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/derive.MetadataDecodable.html +[`BlobDecodable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/derive.BlobDecodable.html +[`LazyDecodable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/derive.LazyDecodable.html [`MetadataEncodable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/derive.MetadataEncodable.html [`rustc_macros`]: https://github.com/rust-lang/rust/tree/HEAD/compiler/rustc_macros -[`rustc_metadata::rmeta::`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/index.html -[`rustc_metadata::rmeta::decoder::DecodeContext`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/decoder/struct.DecodeContext.html +[`rustc_metadata::rmeta`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/index.html [`rustc_metadata::rmeta::encoder::EncodeContext`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/encoder/struct.EncodeContext.html [`rustc_middle`]: https://github.com/rust-lang/rust/tree/HEAD/compiler/rustc_middle From 92890996a32ec2bd310ddfc43c6ccc51e59b3edd Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 18 Dec 2025 10:10:23 +0530 Subject: [PATCH 0986/3801] add request id to requests --- .../src/bidirectional_protocol.rs | 50 ++++++------------- .../crates/proc-macro-api/src/process.rs | 11 +++- .../src/server_impl/rust_analyzer_span.rs | 9 ++-- 3 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index 246f70a10196..728f0f707d71 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -30,7 +30,7 @@ use crate::{ pub mod msg; pub trait ClientCallbacks { - fn handle_sub_request(&mut self, id: u64, req: SubRequest) -> Result; + fn handle_sub_request(&mut self, req: SubRequest) -> Result; } pub fn run_conversation( @@ -65,7 +65,7 @@ pub fn run_conversation( match (msg.kind, msg.payload) { (Kind::SubRequest, Payload::SubRequest(sr)) => { - let resp = callbacks.handle_sub_request(id, sr)?; + let resp = callbacks.handle_sub_request(sr)?; let reply = Envelope { id, kind: Kind::SubResponse, payload: Payload::SubResponse(resp) }; let encoded = C::encode(&reply).map_err(wrap_encode)?; @@ -104,19 +104,14 @@ pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result Result { + fn handle_sub_request(&mut self, _req: SubRequest) -> Result { Err(ServerError { message: "sub-request not supported here".into(), io: None }) } } let mut callbacks = NoCallbacks; - let response_payload = - run_bidirectional(srv, (0, Kind::Request, request).into(), &mut callbacks)?; + let response_payload = run_request(srv, request, &mut callbacks)?; match response_payload { Payload::Response(Response::ApiVersionCheck(version)) => Ok(version), @@ -135,19 +130,14 @@ pub(crate) fn enable_rust_analyzer_spans( struct NoCallbacks; impl ClientCallbacks for NoCallbacks { - fn handle_sub_request( - &mut self, - _id: u64, - _req: SubRequest, - ) -> Result { + fn handle_sub_request(&mut self, _req: SubRequest) -> Result { Err(ServerError { message: "sub-request not supported here".into(), io: None }) } } let mut callbacks = NoCallbacks; - let response_payload = - run_bidirectional(srv, (0, Kind::Request, request).into(), &mut callbacks)?; + let response_payload = run_request(srv, request, &mut callbacks)?; match response_payload { Payload::Response(Response::SetConfig(ServerConfig { span_mode })) => Ok(span_mode), @@ -165,19 +155,14 @@ pub(crate) fn find_proc_macros( struct NoCallbacks; impl ClientCallbacks for NoCallbacks { - fn handle_sub_request( - &mut self, - _id: u64, - _req: SubRequest, - ) -> Result { + fn handle_sub_request(&mut self, _req: SubRequest) -> Result { Err(ServerError { message: "sub-request not supported here".into(), io: None }) } } let mut callbacks = NoCallbacks; - let response_payload = - run_bidirectional(srv, (0, Kind::Request, request).into(), &mut callbacks)?; + let response_payload = run_request(srv, request, &mut callbacks)?; match response_payload { Payload::Response(Response::ListMacros(it)) => Ok(it), @@ -229,11 +214,7 @@ pub(crate) fn expand( db: &'de dyn SourceDatabase, } impl<'db> ClientCallbacks for Callbacks<'db> { - fn handle_sub_request( - &mut self, - _id: u64, - req: SubRequest, - ) -> Result { + fn handle_sub_request(&mut self, req: SubRequest) -> Result { match req { SubRequest::SourceText { file_id, start, end } => { let file = FileId::from_raw(file_id); @@ -249,8 +230,7 @@ pub(crate) fn expand( let mut callbacks = Callbacks { db }; - let response_payload = - run_bidirectional(&proc_macro.process, (0, Kind::Request, task).into(), &mut callbacks)?; + let response_payload = run_request(&proc_macro.process, task, &mut callbacks)?; match response_payload { Payload::Response(Response::ExpandMacro(it)) => Ok(it @@ -279,18 +259,20 @@ pub(crate) fn expand( } } -fn run_bidirectional( +fn run_request( srv: &ProcMacroServerProcess, - msg: Envelope, + msg: Payload, callbacks: &mut dyn ClientCallbacks, ) -> Result { if let Some(server_error) = srv.exited() { return Err(server_error.clone()); } + let id = srv.request_id(); + if srv.use_postcard() { - srv.run_bidirectional::(msg.id, msg.payload, callbacks) + srv.run_bidirectional::(id, msg, callbacks) } else { - srv.run_bidirectional::(msg.id, msg.payload, callbacks) + srv.run_bidirectional::(id, msg, callbacks) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index 39d954855187..723fc928ff66 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -4,7 +4,10 @@ use std::{ io::{self, BufRead, BufReader, Read, Write}, panic::AssertUnwindSafe, process::{Child, ChildStdin, ChildStdout, Command, Stdio}, - sync::{Arc, Mutex, OnceLock}, + sync::{ + Arc, Mutex, OnceLock, + atomic::{AtomicU64, Ordering}, + }, }; use base_db::SourceDatabase; @@ -33,6 +36,7 @@ pub(crate) struct ProcMacroServerProcess { protocol: Protocol, /// Populated when the server exits. exited: OnceLock>, + next_request_id: AtomicU64, } #[derive(Debug, Clone)] @@ -90,6 +94,7 @@ impl ProcMacroServerProcess { version: 0, protocol: protocol.clone(), exited: OnceLock::new(), + next_request_id: AtomicU64::new(1), }) }; let mut srv = create_srv()?; @@ -312,6 +317,10 @@ impl ProcMacroServerProcess { ) }) } + + pub(crate) fn request_id(&self) -> RequestId { + self.next_request_id.fetch_add(1, Ordering::Relaxed) + } } /// Manages the execution of the proc-macro server process. diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 1a8f6d6730f7..cccb74429dd6 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -163,12 +163,9 @@ impl server::Span for RaSpanServer { start, end, }); - self.cli_to_server - .clone() - .unwrap() - .recv() - .and_then(|SubResponse::SourceTextResult { text }| Ok(text)) - .expect("REASON") + match self.cli_to_server.as_ref()?.recv().ok()? { + SubResponse::SourceTextResult { text } => text, + } } else { None } From c92d39e454c407bc78820fa610bf9576ee995a4d Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 18 Dec 2025 04:58:27 +0000 Subject: [PATCH 0987/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 686f9cefc37c5bdec069a75357f0277b390657ca. --- 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 dcf82c94aaee..11c138c28c24 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -0208ee09be465f69005a7a12c28d5eccac7d5f34 +686f9cefc37c5bdec069a75357f0277b390657ca From b48defae19f25b821fbd4236e2abf44823160f27 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 12 Dec 2025 11:53:05 -0800 Subject: [PATCH 0988/3801] Implement FlushFileBuffers --- .../miri/src/shims/windows/foreign_items.rs | 5 +++ src/tools/miri/src/shims/windows/fs.rs | 33 +++++++++++++++++++ src/tools/miri/tests/pass/shims/fs.rs | 14 +++++--- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 7d30582c582c..3bc52dddfe8b 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -313,6 +313,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = this.SetFileInformationByHandle(handle, class, info, size)?; this.write_scalar(res, dest)?; } + "FlushFileBuffers" => { + let [handle] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let res = this.FlushFileBuffers(handle)?; + this.write_scalar(res, dest)?; + } "DeleteFileW" => { let [file_name] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; let res = this.DeleteFileW(file_name)?; diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs index 967164cb250d..e5a98e86d645 100644 --- a/src/tools/miri/src/shims/windows/fs.rs +++ b/src/tools/miri/src/shims/windows/fs.rs @@ -457,6 +457,39 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } + fn FlushFileBuffers( + &mut self, + file: &OpTy<'tcx>, // HANDLE + ) -> InterpResult<'tcx, Scalar> { + // ^ returns BOOL (i32 on Windows) + let this = self.eval_context_mut(); + this.assert_target_os(Os::Windows, "FlushFileBuffers"); + + let file = this.read_handle(file, "FlushFileBuffers")?; + let Handle::File(fd_num) = file else { this.invalid_handle("FlushFileBuffers")? }; + let Some(desc) = this.machine.fds.get(fd_num) else { + this.invalid_handle("FlushFileBuffers")? + }; + let file = desc.downcast::().ok_or_else(|| { + err_unsup_format!( + "`FlushFileBuffers` is only supported on file-backed file descriptors" + ) + })?; + + if !file.writable { + this.set_last_error(IoError::WindowsError("ERROR_ACCESS_DENIED"))?; + return interp_ok(this.eval_windows("c", "FALSE")); + } + + match file.file.sync_all() { + Ok(_) => interp_ok(this.eval_windows("c", "TRUE")), + Err(e) => { + this.set_last_error(e)?; + interp_ok(this.eval_windows("c", "FALSE")) + } + } + } + fn DeleteFileW( &mut self, file_name: &OpTy<'tcx>, // LPCWSTR diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 70bca703cc2f..648c90b5dd97 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -29,9 +29,9 @@ fn main() { test_from_raw_os_error(); test_file_clone(); test_file_set_len(); + test_file_sync(); // Windows file handling is very incomplete. if cfg!(not(windows)) { - test_file_sync(); test_rename(); test_directory(); test_canonicalize(); @@ -231,10 +231,16 @@ fn test_file_sync() { file.sync_data().unwrap(); file.sync_all().unwrap(); - // Test that we can call sync_data and sync_all on a file opened for reading. + // Test that we can call sync_data and sync_all on a file opened for reading on unix, but not + // on Windows let file = File::open(&path).unwrap(); - file.sync_data().unwrap(); - file.sync_all().unwrap(); + if cfg!(unix) { + file.sync_data().unwrap(); + file.sync_all().unwrap(); + } else { + file.sync_data().unwrap_err(); + file.sync_all().unwrap_err(); + } remove_file(&path).unwrap(); } From b63e6fb7d238ec986cb89454a8fe93bfa3611604 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 12 Dec 2025 11:56:35 -0800 Subject: [PATCH 0989/3801] Implement direct shim test --- .../miri/tests/pass-dep/shims/windows-fs.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs index 0037f34d3c9a..91639c502325 100644 --- a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs +++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs @@ -22,8 +22,8 @@ use windows_sys::Win32::Storage::FileSystem::{ FILE_ALLOCATION_INFO, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, FILE_BEGIN, FILE_CURRENT, FILE_END_OF_FILE_INFO, FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, FileAllocationInfo, FileEndOfFileInfo, - GetFileInformationByHandle, OPEN_ALWAYS, OPEN_EXISTING, SetFileInformationByHandle, - SetFilePointerEx, + FlushFileBuffers, GetFileInformationByHandle, OPEN_ALWAYS, OPEN_EXISTING, + SetFileInformationByHandle, SetFilePointerEx, }; use windows_sys::Win32::System::IO::IO_STATUS_BLOCK; use windows_sys::Win32::System::Threading::GetCurrentProcess; @@ -41,6 +41,7 @@ fn main() { test_file_seek(); test_set_file_info(); test_dup_handle(); + test_flush_buffers(); } } @@ -362,6 +363,19 @@ unsafe fn test_file_seek() { assert_eq!(pos, 5); } +unsafe fn test_flush_buffers() { + let temp = utils::tmp().join("test_flush_buffers.txt"); + let file = fs::File::options().create(true).write(true).read(true).open(&temp).unwrap(); + if FlushFileBuffers(file.as_raw_handle()) == 0 { + panic!("Failed to flush buffers"); + } + + let file = fs::File::options().read(true).open(&temp).unwrap(); + if FlushFileBuffers(file.as_raw_handle()) != 0 { + panic!("Successfully flushed buffers on read-only file"); + } +} + fn to_wide_cstr(path: &Path) -> Vec { let mut raw_path = path.as_os_str().encode_wide().collect::>(); raw_path.extend([0, 0]); From 0383197fbe1d293c1b10e05f463b00075e7f1320 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 17 Dec 2025 21:10:03 +1100 Subject: [PATCH 0990/3801] Don't use `thir::PatKind::DerefPattern` for implicit pin-patterns --- .../src/builder/matches/match_pair.rs | 3 ++- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 13 ++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index dc1545c9278a..e08ef0d26748 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -287,8 +287,9 @@ impl<'tcx> MatchPairTree<'tcx> { None } + // FIXME: Pin-patterns should probably have their own pattern kind, + // instead of overloading `PatKind::Deref` via the pattern type. PatKind::Deref { ref subpattern } - | PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) } if let Some(ref_ty) = pattern.ty.pinned_ty() && ref_ty.is_ref() => { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 02e6f8d6ce71..a13536559527 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -11,7 +11,7 @@ use rustc_abi::{FieldIdx, Integer}; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::{self as hir, ByRef, LangItem, Mutability, Pinnedness, RangeEnd}; +use rustc_hir::{self as hir, LangItem, RangeEnd}; use rustc_index::Idx; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::LitToConstInput; @@ -114,16 +114,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let borrow = self.typeck_results.deref_pat_borrow_mode(adjust.source, pat); PatKind::DerefPattern { subpattern: thir_pat, borrow } } - PatAdjust::PinDeref => { - let mutable = self.typeck_results.pat_has_ref_mut_binding(pat); - PatKind::DerefPattern { - subpattern: thir_pat, - borrow: ByRef::Yes( - Pinnedness::Pinned, - if mutable { Mutability::Mut } else { Mutability::Not }, - ), - } - } + PatAdjust::PinDeref => PatKind::Deref { subpattern: thir_pat }, }; Box::new(Pat { span, ty: adjust.source, kind }) }); From 1ae96045d255ebda6ae9bb4a3b578f47ec24f6e7 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 17 Dec 2025 21:24:26 +1100 Subject: [PATCH 0991/3801] Don't use `ByRef` for the `thir::PatKind::DerefPattern` borrow mode This avoids having to awkwardly ignore the `Pinnedness` field. --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 7 ++++--- compiler/rustc_middle/src/thir.rs | 12 +++++++++--- compiler/rustc_middle/src/ty/typeck_results.rs | 17 +++++++++++------ .../src/builder/matches/match_pair.rs | 11 +++-------- .../rustc_mir_build/src/builder/matches/mod.rs | 8 ++------ .../rustc_mir_build/src/thir/pattern/mod.rs | 4 ++-- 6 files changed, 31 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 27b66d07f98e..be4fdb5240c7 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -23,6 +23,7 @@ use rustc_middle::hir::place::ProjectionKind; // Export these here so that Clippy can use them. pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection}; use rustc_middle::mir::FakeReadCause; +use rustc_middle::thir::DerefPatBorrowMode; use rustc_middle::ty::{ self, BorrowKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, adjustment, }; @@ -1004,7 +1005,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // Deref patterns on boxes don't borrow, so we ignore them here. // HACK: this could be a fake pattern corresponding to a deref inserted by match // ergonomics, in which case `pat.hir_id` will be the id of the subpattern. - if let hir::ByRef::Yes(_, mutability) = + if let DerefPatBorrowMode::Borrow(mutability) = self.cx.typeck_results().deref_pat_borrow_mode(place.place.ty(), subpattern) { let bk = ty::BorrowKind::from_mutbl(mutability); @@ -1891,9 +1892,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ) -> Result, Cx::Error> { match self.cx.typeck_results().deref_pat_borrow_mode(base_place.place.ty(), inner) { // Deref patterns on boxes are lowered using a built-in deref. - hir::ByRef::No => self.cat_deref(hir_id, base_place), + DerefPatBorrowMode::Box => self.cat_deref(hir_id, base_place), // For other types, we create a temporary to match on. - hir::ByRef::Yes(_, mutability) => { + DerefPatBorrowMode::Borrow(mutability) => { let re_erased = self.cx.tcx().lifetimes.re_erased; let ty = Ty::new_ref(self.cx.tcx(), re_erased, target_ty, mutability); // A deref pattern stores the result of `Deref::deref` or `DerefMut::deref_mut` ... diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index edbb736128cf..3d893bf75e0b 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -14,7 +14,7 @@ use std::ops::Index; use std::sync::Arc; use rustc_abi::{FieldIdx, Integer, Size, VariantIdx}; -use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece, Mutability}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd}; @@ -811,11 +811,11 @@ pub enum PatKind<'tcx> { DerefPattern { subpattern: Box>, /// Whether the pattern scrutinee needs to be borrowed in order to call `Deref::deref` or - /// `DerefMut::deref_mut`, and if so, which. This is `ByRef::No` for deref patterns on + /// `DerefMut::deref_mut`, and if so, which. This is `DerefPatBorrowMode::Box` for deref patterns on /// boxes; they are lowered using a built-in deref rather than a method call, thus they /// don't borrow the scrutinee. #[type_visitable(ignore)] - borrow: ByRef, + borrow: DerefPatBorrowMode, }, /// One of the following: @@ -879,6 +879,12 @@ pub enum PatKind<'tcx> { Error(ErrorGuaranteed), } +#[derive(Copy, Clone, Debug, HashStable)] +pub enum DerefPatBorrowMode { + Borrow(Mutability), + Box, +} + /// A range pattern. /// The boundaries must be of the same type and that type must be numeric. #[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)] diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index a3353661d9dd..2c5e4957d0ae 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -11,7 +11,6 @@ use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap}; use rustc_hir::hir_id::OwnerId; use rustc_hir::{ self as hir, BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability, - Pinnedness, }; use rustc_index::IndexVec; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; @@ -21,6 +20,7 @@ use rustc_span::Span; use crate::hir::place::Place as HirPlace; use crate::infer::canonical::Canonical; use crate::mir::FakeReadCause; +use crate::thir::DerefPatBorrowMode; use crate::traits::ObligationCause; use crate::ty::{ self, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData, GenericArgKind, GenericArgs, @@ -491,13 +491,18 @@ impl<'tcx> TypeckResults<'tcx> { /// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner /// pattern's scrutinee by calling `DerefMut::deref_mut`, and otherwise we call `Deref::deref`. /// However, for boxes we can use a built-in deref instead, which doesn't borrow the scrutinee; - /// in this case, we return `ByRef::No`. - pub fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: &hir::Pat<'_>) -> ByRef { + /// in this case, we return `DerefPatBorrowMode::Box`. + pub fn deref_pat_borrow_mode( + &self, + pointer_ty: Ty<'_>, + inner: &hir::Pat<'_>, + ) -> DerefPatBorrowMode { if pointer_ty.is_box() { - ByRef::No + DerefPatBorrowMode::Box } else { - let mutable = self.pat_has_ref_mut_binding(inner); - ByRef::Yes(Pinnedness::Not, if mutable { Mutability::Mut } else { Mutability::Not }) + let mutability = + if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not }; + DerefPatBorrowMode::Borrow(mutability) } } diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index e08ef0d26748..8d612b8c5efe 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -1,10 +1,9 @@ use std::sync::Arc; use rustc_abi::FieldIdx; -use rustc_hir::ByRef; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use crate::builder::Builder; use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder}; @@ -303,12 +302,8 @@ impl<'tcx> MatchPairTree<'tcx> { None } - PatKind::DerefPattern { borrow: ByRef::Yes(Pinnedness::Pinned, _), .. } => { - rustc_middle::bug!("RefPin pattern on non-`Pin` type {:?}", pattern.ty) - } - PatKind::Deref { ref subpattern } - | PatKind::DerefPattern { ref subpattern, borrow: ByRef::No } => { + | PatKind::DerefPattern { ref subpattern, borrow: DerefPatBorrowMode::Box } => { MatchPairTree::for_pattern( place_builder.deref(), subpattern, @@ -321,7 +316,7 @@ impl<'tcx> MatchPairTree<'tcx> { PatKind::DerefPattern { ref subpattern, - borrow: ByRef::Yes(Pinnedness::Not, mutability), + borrow: DerefPatBorrowMode::Borrow(mutability), } => { // Create a new temporary for each deref pattern. // FIXME(deref_patterns): dedup temporaries to avoid multiple `deref()` calls? diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index ecdc3842a9b8..66e36a99d3c4 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -11,10 +11,10 @@ use std::mem; use std::sync::Arc; use itertools::{Itertools, Position}; -use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; +use rustc_abi::{FIRST_VARIANT, VariantIdx}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_hir::{BindingMode, ByRef, LangItem, LetStmt, LocalSource, Node, Pinnedness}; +use rustc_hir::{BindingMode, ByRef, LangItem, LetStmt, LocalSource, Node}; use rustc_middle::middle::region::{self, TempLifetime}; use rustc_middle::mir::*; use rustc_middle::thir::{self, *}; @@ -920,10 +920,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { visit_subpat(self, subpattern, &user_tys.deref(), f); } - PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) } => { - visit_subpat(self, subpattern, &user_tys.leaf(FieldIdx::ZERO).deref(), f); - } - PatKind::DerefPattern { ref subpattern, .. } => { visit_subpat(self, subpattern, &ProjectedUserTypesNode::None, f); } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index a13536559527..891a7df7d235 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -16,7 +16,7 @@ use rustc_index::Idx; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::LitToConstInput; use rustc_middle::thir::{ - Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary, + Ascription, DerefPatBorrowMode, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary, }; use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment}; use rustc_middle::ty::layout::IntegerExt; @@ -325,7 +325,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } hir::PatKind::Box(subpattern) => PatKind::DerefPattern { subpattern: self.lower_pattern(subpattern), - borrow: hir::ByRef::No, + borrow: DerefPatBorrowMode::Box, }, hir::PatKind::Slice(prefix, slice, suffix) => { From c820f461228ba5d8d6bc6879e5a311a45673fb84 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 15 Dec 2025 14:42:01 +0100 Subject: [PATCH 0992/3801] Generate macro expansion for rust compiler crates docs --- src/bootstrap/src/core/build_steps/doc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index b86582807f72..fa36a6471cae 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -932,6 +932,7 @@ impl Step for Rustc { // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222 // If there is any bug, please comment out the next line. cargo.rustdocflag("--generate-link-to-definition"); + cargo.rustdocflag("--generate-macro-expansion"); compile::rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates); cargo.arg("-Zskip-rustdoc-fingerprint"); From 3fd2d64dc4e47b9a4ae9e9ac7fa430ffe6a24d19 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 18 Dec 2025 08:09:56 +0100 Subject: [PATCH 0993/3801] remove spin_loop hint intrinsics we no longer need --- src/tools/miri/src/shims/aarch64.rs | 14 -------------- src/tools/miri/src/shims/foreign_items.rs | 16 ---------------- 2 files changed, 30 deletions(-) diff --git a/src/tools/miri/src/shims/aarch64.rs b/src/tools/miri/src/shims/aarch64.rs index 6e422b4ab716..595a6595b531 100644 --- a/src/tools/miri/src/shims/aarch64.rs +++ b/src/tools/miri/src/shims/aarch64.rs @@ -19,20 +19,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Prefix should have already been checked. let unprefixed_name = link_name.as_str().strip_prefix("llvm.aarch64.").unwrap(); match unprefixed_name { - "isb" => { - let [arg] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let arg = this.read_scalar(arg)?.to_i32()?; - match arg { - // SY ("full system scope") - 15 => { - this.yield_active_thread(); - } - _ => { - throw_unsup_format!("unsupported llvm.aarch64.isb argument {}", arg); - } - } - } - // Used to implement the vpmaxq_u8 function. // Computes the maximum of adjacent pairs; the first half of the output is produced from the // `left` input, the second half of the output from the `right` input. diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 48f4ca53cdca..74ae93348d58 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -813,22 +813,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this, link_name, abi, args, dest, ); } - // FIXME: Move this to an `arm` submodule. - "llvm.arm.hint" if this.tcx.sess.target.arch == Arch::Arm => { - let [arg] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let arg = this.read_scalar(arg)?.to_i32()?; - // Note that different arguments might have different target feature requirements. - match arg { - // YIELD - 1 => { - this.expect_target_feature_for_intrinsic(link_name, "v6")?; - this.yield_active_thread(); - } - _ => { - throw_unsup_format!("unsupported llvm.arm.hint argument {}", arg); - } - } - } // Fallback to shims in submodules. _ => { From ae5e0d5492b1106f8843ee2e00f6017bb0bf75b7 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Thu, 18 Dec 2025 10:42:47 +0300 Subject: [PATCH 0994/3801] Support recursive delegation --- compiler/rustc_ast_lowering/messages.ftl | 2 + compiler/rustc_ast_lowering/src/delegation.rs | 68 +++++++++---- compiler/rustc_ast_lowering/src/errors.rs | 14 +++ compiler/rustc_ast_lowering/src/item.rs | 6 +- compiler/rustc_hir_analysis/src/delegation.rs | 6 -- compiler/rustc_middle/src/ty/mod.rs | 3 + compiler/rustc_resolve/src/late.rs | 22 ++++- compiler/rustc_resolve/src/lib.rs | 3 + .../auxiliary/recursive-delegation-aux.rs | 7 ++ tests/ui/delegation/ice-issue-124347.rs | 4 +- tests/ui/delegation/ice-issue-124347.stderr | 19 ++-- .../delegation/recursive-delegation-errors.rs | 54 ++++++++++ .../recursive-delegation-errors.stderr | 98 +++++++++++++++++++ .../delegation/recursive-delegation-pass.rs | 68 +++++++++++++ .../ui/delegation/unsupported.current.stderr | 13 +-- tests/ui/delegation/unsupported.next.stderr | 13 +-- tests/ui/delegation/unsupported.rs | 1 - 17 files changed, 331 insertions(+), 70 deletions(-) create mode 100644 tests/ui/delegation/auxiliary/recursive-delegation-aux.rs create mode 100644 tests/ui/delegation/recursive-delegation-errors.rs create mode 100644 tests/ui/delegation/recursive-delegation-errors.stderr create mode 100644 tests/ui/delegation/recursive-delegation-pass.rs diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 370b15d2871a..e1fccead4d21 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -56,6 +56,8 @@ ast_lowering_coroutine_too_many_parameters = ast_lowering_default_field_in_tuple = default fields are not supported in tuple structs .label = default fields are only supported on structs +ast_lowering_delegation_cycle_in_signature_resolution = encountered a cycle during delegation signature resolution +ast_lowering_delegation_unresolved_callee = failed to resolve delegation callee ast_lowering_does_not_support_modifiers = the `{$class_name}` register class does not support template modifiers diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 82bade8829a2..532a0ce520cd 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -44,6 +44,7 @@ use hir::{BodyId, HirId}; use rustc_abi::ExternAbi; use rustc_ast::*; use rustc_attr_parsing::{AttributeParser, ShouldEmit}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::ErrorGuaranteed; use rustc_hir::Target; use rustc_hir::attrs::{AttributeKind, InlineAttr}; @@ -55,6 +56,7 @@ use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; use {rustc_ast as ast, rustc_hir as hir}; use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode}; +use crate::errors::{CycleInDelegationSignatureResolution, UnresolvedDelegationCallee}; use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt}; pub(crate) struct DelegationResults<'hir> { @@ -119,10 +121,14 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, delegation: &Delegation, item_id: NodeId, - is_in_trait_impl: bool, ) -> DelegationResults<'hir> { let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span); - let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl); + + let sig_id = self.get_delegation_sig_id( + self.resolver.delegation_sig_resolution_nodes[&self.local_def_id(item_id)], + span, + ); + match sig_id { Ok(sig_id) => { self.add_attributes_if_needed(span, sig_id); @@ -238,24 +244,48 @@ impl<'hir> LoweringContext<'_, 'hir> { fn get_delegation_sig_id( &self, - item_id: NodeId, - path_id: NodeId, + mut node_id: NodeId, span: Span, - is_in_trait_impl: bool, ) -> Result { - let sig_id = if is_in_trait_impl { item_id } else { path_id }; - self.get_resolution_id(sig_id, span) + let mut visited: FxHashSet = Default::default(); + + loop { + visited.insert(node_id); + + let Some(def_id) = self.get_resolution_id(node_id) else { + return Err(self.tcx.dcx().span_delayed_bug( + span, + format!( + "LoweringContext: couldn't resolve node {:?} in delegation item", + node_id + ), + )); + }; + + // If def_id is in local crate and it corresponds to another delegation + // it means that we refer to another delegation as a callee, so in order to obtain + // a signature DefId we obtain NodeId of the callee delegation and try to get signature from it. + if let Some(local_id) = def_id.as_local() + && let Some(next_node_id) = + self.resolver.delegation_sig_resolution_nodes.get(&local_id) + { + node_id = *next_node_id; + if visited.contains(&node_id) { + // We encountered a cycle in the resolution, or delegation callee refers to non-existent + // entity, in this case emit an error. + return Err(match visited.len() { + 1 => self.dcx().emit_err(UnresolvedDelegationCallee { span }), + _ => self.dcx().emit_err(CycleInDelegationSignatureResolution { span }), + }); + } + } else { + return Ok(def_id); + } + } } - fn get_resolution_id(&self, node_id: NodeId, span: Span) -> Result { - let def_id = - self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id()); - def_id.ok_or_else(|| { - self.tcx.dcx().span_delayed_bug( - span, - format!("LoweringContext: couldn't resolve node {:?} in delegation item", node_id), - ) - }) + fn get_resolution_id(&self, node_id: NodeId) -> Option { + self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id()) } fn lower_delegation_generics(&mut self, span: Span) -> &'hir hir::Generics<'hir> { @@ -271,8 +301,6 @@ impl<'hir> LoweringContext<'_, 'hir> { // Function parameter count, including C variadic `...` if present. fn param_count(&self, sig_id: DefId) -> (usize, bool /*c_variadic*/) { if let Some(local_sig_id) = sig_id.as_local() { - // Map may be filled incorrectly due to recursive delegation. - // Error will be emitted later during HIR ty lowering. match self.resolver.delegation_fn_sigs.get(&local_sig_id) { Some(sig) => (sig.param_count, sig.c_variadic), None => (0, false), @@ -489,8 +517,8 @@ impl<'hir> LoweringContext<'_, 'hir> { delegation.path.segments.iter().rev().skip(1).any(|segment| segment.args.is_some()); let call = if self - .get_resolution_id(delegation.id, span) - .and_then(|def_id| Ok(self.is_method(def_id, span))) + .get_resolution_id(delegation.id) + .map(|def_id| self.is_method(def_id, span)) .unwrap_or_default() && delegation.qself.is_none() && !has_generic_args diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 83f3a976e83f..35c37fe91d49 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -475,3 +475,17 @@ pub(crate) struct UnionWithDefault { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(ast_lowering_delegation_unresolved_callee)] +pub(crate) struct UnresolvedDelegationCallee { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_lowering_delegation_cycle_in_signature_resolution)] +pub(crate) struct CycleInDelegationSignatureResolution { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index a68d63bf1464..bfce7c25b75d 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -541,7 +541,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ItemKind::Macro(ident, macro_def, macro_kinds) } ItemKind::Delegation(box delegation) => { - let delegation_results = self.lower_delegation(delegation, id, false); + let delegation_results = self.lower_delegation(delegation, id); hir::ItemKind::Fn { sig: delegation_results.sig, ident: delegation_results.ident, @@ -1026,7 +1026,7 @@ impl<'hir> LoweringContext<'_, 'hir> { (*ident, generics, kind, ty.is_some()) } AssocItemKind::Delegation(box delegation) => { - let delegation_results = self.lower_delegation(delegation, i.id, false); + let delegation_results = self.lower_delegation(delegation, i.id); let item_kind = hir::TraitItemKind::Fn( delegation_results.sig, hir::TraitFn::Provided(delegation_results.body_id), @@ -1196,7 +1196,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } AssocItemKind::Delegation(box delegation) => { - let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl); + let delegation_results = self.lower_delegation(delegation, i.id); ( delegation.ident, ( diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 125fc21a5cc1..4ab13140bf9c 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -401,12 +401,6 @@ fn check_constraints<'tcx>( })); }; - if let Some(local_sig_id) = sig_id.as_local() - && tcx.hir_opt_delegation_sig_id(local_sig_id).is_some() - { - emit("recursive delegation is not supported yet"); - } - if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic { // See issue #127443 for explanation. emit("delegation to C-variadic functions is not allowed"); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b91176e3d486..e918f7ba362d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -220,6 +220,9 @@ pub struct ResolverAstLowering { /// Information about functions signatures for delegation items expansion pub delegation_fn_sigs: LocalDefIdMap, + // NodeIds (either delegation.id or item_id in case of a trait impl) for signature resolution, + // for details see https://github.com/rust-lang/rust/issues/118212#issuecomment-2160686914 + pub delegation_sig_resolution_nodes: LocalDefIdMap, } bitflags::bitflags! { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 5a4fbad6aaf8..d3428a4af348 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2928,7 +2928,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { item.id, LifetimeBinderKind::Function, span, - |this| this.resolve_delegation(delegation), + |this| this.resolve_delegation(delegation, item.id, false), ); } @@ -3257,7 +3257,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { item.id, LifetimeBinderKind::Function, delegation.path.segments.last().unwrap().ident.span, - |this| this.resolve_delegation(delegation), + |this| this.resolve_delegation(delegation, item.id, false), ); } AssocItemKind::Type(box TyAlias { generics, .. }) => self @@ -3550,7 +3550,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |i, s, c| MethodNotMemberOfTrait(i, s, c), ); - this.resolve_delegation(delegation) + this.resolve_delegation(delegation, item.id, trait_id.is_some()); }, ); } @@ -3699,17 +3699,30 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }) } - fn resolve_delegation(&mut self, delegation: &'ast Delegation) { + fn resolve_delegation( + &mut self, + delegation: &'ast Delegation, + item_id: NodeId, + is_in_trait_impl: bool, + ) { self.smart_resolve_path( delegation.id, &delegation.qself, &delegation.path, PathSource::Delegation, ); + if let Some(qself) = &delegation.qself { self.visit_ty(&qself.ty); } + self.visit_path(&delegation.path); + + self.r.delegation_sig_resolution_nodes.insert( + self.r.local_def_id(item_id), + if is_in_trait_impl { item_id } else { delegation.id }, + ); + let Some(body) = &delegation.body else { return }; self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| { let span = delegation.path.segments.last().unwrap().ident.span; @@ -4294,7 +4307,6 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); } - #[instrument(level = "debug", skip(self))] fn smart_resolve_path_fragment( &mut self, qself: &Option>, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b3141406e467..646a1b891413 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1276,6 +1276,7 @@ pub struct Resolver<'ra, 'tcx> { /// Amount of lifetime parameters for each item in the crate. item_generics_num_lifetimes: FxHashMap, delegation_fn_sigs: LocalDefIdMap, + delegation_sig_resolution_nodes: LocalDefIdMap, main_def: Option = None, trait_impls: FxIndexMap>, @@ -1694,6 +1695,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { current_crate_outer_attr_insert_span, mods_with_parse_errors: Default::default(), impl_trait_names: Default::default(), + delegation_sig_resolution_nodes: Default::default(), .. }; @@ -1822,6 +1824,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), delegation_fn_sigs: self.delegation_fn_sigs, + delegation_sig_resolution_nodes: self.delegation_sig_resolution_nodes, }; ResolverOutputs { global_ctxt, ast_lowering } } diff --git a/tests/ui/delegation/auxiliary/recursive-delegation-aux.rs b/tests/ui/delegation/auxiliary/recursive-delegation-aux.rs new file mode 100644 index 000000000000..5df644974f3e --- /dev/null +++ b/tests/ui/delegation/auxiliary/recursive-delegation-aux.rs @@ -0,0 +1,7 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +fn foo() {} + +reuse foo as bar; +pub reuse bar as goo; diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs index 3e0a5b36ddcf..6bf3a08ba5b4 100644 --- a/tests/ui/delegation/ice-issue-124347.rs +++ b/tests/ui/delegation/ice-issue-124347.rs @@ -1,12 +1,12 @@ #![feature(fn_delegation)] #![allow(incomplete_features)] -// FIXME(fn_delegation): `recursive delegation` error should be emitted here trait Trait { reuse Trait::foo { &self.0 } + //~^ ERROR failed to resolve delegation callee } reuse foo; -//~^ ERROR cycle detected when computing generics of `foo` +//~^ ERROR failed to resolve delegation callee fn main() {} diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr index 2955c0442034..40be6be4abfa 100644 --- a/tests/ui/delegation/ice-issue-124347.stderr +++ b/tests/ui/delegation/ice-issue-124347.stderr @@ -1,17 +1,14 @@ -error[E0391]: cycle detected when computing generics of `foo` +error: failed to resolve delegation callee + --> $DIR/ice-issue-124347.rs:5:18 + | +LL | reuse Trait::foo { &self.0 } + | ^^^ + +error: failed to resolve delegation callee --> $DIR/ice-issue-124347.rs:9:7 | LL | reuse foo; | ^^^ - | - = note: ...which immediately requires computing generics of `foo` again -note: cycle used when checking that `foo` is well-formed - --> $DIR/ice-issue-124347.rs:9:7 - | -LL | reuse foo; - | ^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/delegation/recursive-delegation-errors.rs b/tests/ui/delegation/recursive-delegation-errors.rs new file mode 100644 index 000000000000..194182e20ed0 --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-errors.rs @@ -0,0 +1,54 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + + +mod first_mod { + reuse foo; + //~^ ERROR failed to resolve delegation callee +} + +mod second_mod { + reuse foo as bar; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse bar as foo; + //~^ ERROR encountered a cycle during delegation signature resolution +} + +mod third_mod { + reuse foo as foo1; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo1 as foo2; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo2 as foo3; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo3 as foo4; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo4 as foo5; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo5 as foo; + //~^ ERROR encountered a cycle during delegation signature resolution +} + +mod fourth_mod { + trait Trait { + reuse Trait::foo as bar; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse Trait::bar as foo; + //~^ ERROR encountered a cycle during delegation signature resolution + } +} + +mod fifth_mod { + reuse super::fifth_mod::{bar as foo, foo as bar}; + //~^ ERROR encountered a cycle during delegation signature resolution + //~| ERROR encountered a cycle during delegation signature resolution + + trait GlobReuse { + reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + //~^ ERROR encountered a cycle during delegation signature resolution + //~| ERROR encountered a cycle during delegation signature resolution + //~| ERROR encountered a cycle during delegation signature resolution + } +} + +fn main() {} diff --git a/tests/ui/delegation/recursive-delegation-errors.stderr b/tests/ui/delegation/recursive-delegation-errors.stderr new file mode 100644 index 000000000000..9c4e316745ae --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-errors.stderr @@ -0,0 +1,98 @@ +error: failed to resolve delegation callee + --> $DIR/recursive-delegation-errors.rs:6:11 + | +LL | reuse foo; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:11:11 + | +LL | reuse foo as bar; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:13:11 + | +LL | reuse bar as foo; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:18:11 + | +LL | reuse foo as foo1; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:20:11 + | +LL | reuse foo1 as foo2; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:22:11 + | +LL | reuse foo2 as foo3; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:24:11 + | +LL | reuse foo3 as foo4; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:26:11 + | +LL | reuse foo4 as foo5; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:28:11 + | +LL | reuse foo5 as foo; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:34:22 + | +LL | reuse Trait::foo as bar; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:36:22 + | +LL | reuse Trait::bar as foo; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:42:30 + | +LL | reuse super::fifth_mod::{bar as foo, foo as bar}; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:42:42 + | +LL | reuse super::fifth_mod::{bar as foo, foo as bar}; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:47:27 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:47:39 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:47:51 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ + +error: aborting due to 16 previous errors + diff --git a/tests/ui/delegation/recursive-delegation-pass.rs b/tests/ui/delegation/recursive-delegation-pass.rs new file mode 100644 index 000000000000..93f8fa401b55 --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-pass.rs @@ -0,0 +1,68 @@ +//@ check-pass +//@ edition:2018 +//@ aux-crate:recursive_delegation_aux=recursive-delegation-aux.rs + +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod first_mod { + pub mod to_reuse { + pub fn foo(x: usize) -> usize { + x + 1 + } + } + + mod single_reuse { + reuse crate::first_mod::to_reuse::foo; + reuse foo as bar; + reuse foo as bar1; + reuse bar as goo; + reuse goo as koo; + reuse koo as too; + } + + mod glob_reuse { + reuse super::to_reuse::{foo as bar, foo as bar1} { self } + reuse super::glob_reuse::{bar as goo, goo as koo, koo as too} { self } + } +} + +mod second_mod { + trait T { + fn foo(&self); + reuse T::foo as bar; + reuse T::bar as goo; + reuse T::goo as poo; + } + + trait TGlob { + fn xd(&self) -> &Self; + fn foo1(&self); + fn foo2(&self); + fn foo3(&self); + fn foo4(&self); + + reuse TGlob::{foo1 as bar1, foo3 as bar3, bar1 as bar11, bar11 as bar111} { self.xd() } + } +} + +mod third_mod { + reuse crate::first_mod::to_reuse::foo { + reuse foo as bar { + reuse bar as goo { + bar(123) + } + + goo(123) + } + + bar(123) + } +} + +mod fourth_mod { + reuse recursive_delegation_aux::goo as bar; + reuse bar as foo; +} + +fn main() {} diff --git a/tests/ui/delegation/unsupported.current.stderr b/tests/ui/delegation/unsupported.current.stderr index 5c4115630c00..2bb0633621f2 100644 --- a/tests/ui/delegation/unsupported.current.stderr +++ b/tests/ui/delegation/unsupported.current.stderr @@ -36,24 +36,15 @@ LL | reuse ToReuse::opaque_ret; | ^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: recursive delegation is not supported yet - --> $DIR/unsupported.rs:46:22 - | -LL | pub reuse to_reuse2::foo; - | --- callee defined here -... -LL | reuse to_reuse1::foo; - | ^^^ - error[E0283]: type annotations needed - --> $DIR/unsupported.rs:55:18 + --> $DIR/unsupported.rs:54:18 | LL | reuse Trait::foo; | ^^^ cannot infer type | = note: cannot satisfy `_: effects::Trait` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0283, E0391. For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/delegation/unsupported.next.stderr b/tests/ui/delegation/unsupported.next.stderr index a626da9a1442..1665d1f39d6d 100644 --- a/tests/ui/delegation/unsupported.next.stderr +++ b/tests/ui/delegation/unsupported.next.stderr @@ -28,24 +28,15 @@ LL | reuse ToReuse::opaque_ret; = note: cycle used when computing implied outlives bounds for `::opaque_ret::{anon_assoc#0}` (hack disabled = false) = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: recursive delegation is not supported yet - --> $DIR/unsupported.rs:46:22 - | -LL | pub reuse to_reuse2::foo; - | --- callee defined here -... -LL | reuse to_reuse1::foo; - | ^^^ - error[E0283]: type annotations needed - --> $DIR/unsupported.rs:55:18 + --> $DIR/unsupported.rs:54:18 | LL | reuse Trait::foo; | ^^^ cannot infer type | = note: cannot satisfy `_: effects::Trait` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0283, E0391. For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs index 5e2bd832a4d8..1681888e34ea 100644 --- a/tests/ui/delegation/unsupported.rs +++ b/tests/ui/delegation/unsupported.rs @@ -44,7 +44,6 @@ mod recursive { } reuse to_reuse1::foo; - //~^ ERROR recursive delegation is not supported yet } mod effects { From 49f42ea517783031e766bc0e94b27a62c92930c4 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Wed, 10 Dec 2025 06:35:11 +0200 Subject: [PATCH 0995/3801] Lay the basics for non-`Copy` solver types with GC That means stop using Salsa for interning solver types. --- src/tools/rust-analyzer/Cargo.lock | 1 + .../hir-def/src/nameres/attr_resolution.rs | 4 +- .../crates/hir-def/src/nameres/collector.rs | 2 +- .../crates/hir-ty/src/consteval.rs | 149 ++-- .../crates/hir-ty/src/consteval/tests.rs | 10 +- .../rust-analyzer/crates/hir-ty/src/db.rs | 130 ++-- .../crates/hir-ty/src/diagnostics/expr.rs | 12 +- .../hir-ty/src/diagnostics/match_check.rs | 17 +- .../diagnostics/match_check/pat_analysis.rs | 4 +- .../hir-ty/src/diagnostics/unsafe_check.rs | 22 +- .../crates/hir-ty/src/display.rs | 50 +- .../rust-analyzer/crates/hir-ty/src/drop.rs | 6 +- .../crates/hir-ty/src/dyn_compatibility.rs | 3 +- .../rust-analyzer/crates/hir-ty/src/infer.rs | 335 ++++----- .../crates/hir-ty/src/infer/autoderef.rs | 7 +- .../crates/hir-ty/src/infer/cast.rs | 20 +- .../hir-ty/src/infer/closure/analysis.rs | 88 +-- .../crates/hir-ty/src/infer/coerce.rs | 64 +- .../crates/hir-ty/src/infer/diagnostics.rs | 16 +- .../crates/hir-ty/src/infer/expr.rs | 88 +-- .../crates/hir-ty/src/infer/mutability.rs | 4 +- .../crates/hir-ty/src/infer/op.rs | 4 +- .../crates/hir-ty/src/infer/opaques.rs | 4 +- .../crates/hir-ty/src/infer/pat.rs | 35 +- .../crates/hir-ty/src/infer/path.rs | 2 +- .../crates/hir-ty/src/infer/place_op.rs | 15 +- .../crates/hir-ty/src/infer/unify.rs | 3 +- .../crates/hir-ty/src/inhabitedness.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/layout.rs | 68 +- .../crates/hir-ty/src/layout/adt.rs | 24 +- .../crates/hir-ty/src/layout/tests.rs | 6 +- .../rust-analyzer/crates/hir-ty/src/lib.rs | 19 +- .../rust-analyzer/crates/hir-ty/src/lower.rs | 692 ++++++++++-------- .../crates/hir-ty/src/lower/path.rs | 14 +- .../crates/hir-ty/src/method_resolution.rs | 2 +- .../hir-ty/src/method_resolution/confirm.rs | 22 +- .../hir-ty/src/method_resolution/probe.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/mir.rs | 261 ++++--- .../crates/hir-ty/src/mir/borrowck.rs | 123 ++-- .../crates/hir-ty/src/mir/eval.rs | 301 ++++---- .../crates/hir-ty/src/mir/eval/shim.rs | 31 +- .../crates/hir-ty/src/mir/eval/shim/simd.rs | 3 +- .../crates/hir-ty/src/mir/eval/tests.rs | 9 +- .../crates/hir-ty/src/mir/lower.rs | 327 ++++----- .../crates/hir-ty/src/mir/lower/as_place.rs | 54 +- .../hir-ty/src/mir/lower/pattern_matching.rs | 115 +-- .../crates/hir-ty/src/mir/monomorphization.rs | 106 +-- .../crates/hir-ty/src/mir/pretty.rs | 48 +- .../crates/hir-ty/src/next_solver.rs | 2 + .../crates/hir-ty/src/next_solver/binder.rs | 83 +++ .../crates/hir-ty/src/next_solver/consts.rs | 115 ++- .../crates/hir-ty/src/next_solver/fulfill.rs | 2 +- .../hir-ty/src/next_solver/fulfill/errors.rs | 2 +- .../hir-ty/src/next_solver/generic_arg.rs | 357 +++++++-- .../crates/hir-ty/src/next_solver/infer/at.rs | 2 +- .../infer/canonical/canonicalizer.rs | 4 +- .../infer/canonical/instantiate.rs | 2 +- .../next_solver/infer/outlives/obligations.rs | 10 +- .../crates/hir-ty/src/next_solver/interner.rs | 510 +++++++------ .../crates/hir-ty/src/next_solver/ir_print.rs | 1 - .../crates/hir-ty/src/next_solver/opaques.rs | 59 +- .../hir-ty/src/next_solver/predicate.rs | 295 ++++---- .../crates/hir-ty/src/next_solver/region.rs | 66 +- .../crates/hir-ty/src/next_solver/solver.rs | 2 +- .../crates/hir-ty/src/next_solver/ty.rs | 88 ++- .../crates/hir-ty/src/opaques.rs | 44 +- .../crates/hir-ty/src/specialization.rs | 1 - .../rust-analyzer/crates/hir-ty/src/tests.rs | 26 +- .../hir-ty/src/tests/closure_captures.rs | 1 + .../crates/hir-ty/src/tests/incremental.rs | 100 +-- .../rust-analyzer/crates/hir-ty/src/traits.rs | 29 +- .../crates/hir-ty/src/variance.rs | 58 +- .../crates/hir/src/diagnostics.rs | 21 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 86 ++- .../rust-analyzer/crates/hir/src/semantics.rs | 7 +- .../crates/hir/src/source_analyzer.rs | 101 ++- .../ide/src/inlay_hints/implicit_drop.rs | 2 +- .../rust-analyzer/crates/ide/src/interpret.rs | 2 +- .../rust-analyzer/crates/intern/Cargo.toml | 1 + .../rust-analyzer/crates/intern/src/intern.rs | 331 +++++++++ .../crates/intern/src/intern_slice.rs | 351 +++++++++ .../rust-analyzer/crates/intern/src/lib.rs | 221 +----- .../rust-analyzer/crates/macros/src/lib.rs | 30 + .../crates/query-group-macro/src/queries.rs | 3 +- .../rust-analyzer/src/cli/analysis_stats.rs | 33 +- 85 files changed, 3818 insertions(+), 2554 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/hir-ty/src/next_solver/binder.rs create mode 100644 src/tools/rust-analyzer/crates/intern/src/intern.rs create mode 100644 src/tools/rust-analyzer/crates/intern/src/intern_slice.rs diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 70611dd1311b..081c7d66f1d8 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1215,6 +1215,7 @@ dependencies = [ "dashmap", "hashbrown 0.14.5", "rustc-hash 2.1.1", + "smallvec", "triomphe", ] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs index ec05c02bd635..1cbd2c10b5a1 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs @@ -63,7 +63,7 @@ impl DefMap { return Ok(ResolvedAttr::Other); } } - None => return Err(UnresolvedMacro { path: ast_id.path.as_ref().clone() }), + None => return Err(UnresolvedMacro { path: (*ast_id.path).clone() }), }; Ok(ResolvedAttr::Macro(attr_macro_as_call_id( @@ -145,7 +145,7 @@ pub(super) fn derive_macro_as_call_id( ) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> { let (macro_id, def_id) = resolver(&item_attr.path) .filter(|(_, def_id)| def_id.is_derive()) - .ok_or_else(|| UnresolvedMacro { path: item_attr.path.as_ref().clone() })?; + .ok_or_else(|| UnresolvedMacro { path: (*item_attr.path).clone() })?; let call_id = def_id.make_call( db, krate, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 10581378bef9..7e1ec526a7bc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -1675,7 +1675,7 @@ impl<'db> DefCollector<'db> { derive_index: *derive_pos as u32, derive_macro_id: *derive_macro_id, }, - ast_id.path.as_ref().clone(), + (*ast_id.path).clone(), )); } // These are diagnosed by `reseed_with_unresolved_attribute`, as that function consumes them diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index 32c207b189f0..f11240e0f78c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -23,8 +23,9 @@ use crate::{ mir::{MirEvalError, MirLowerError}, next_solver::{ Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, - ParamEnv, Ty, ValueConst, + ParamEnv, StoredConst, StoredGenericArgs, Ty, ValueConst, }, + traits::StoredParamEnvAndCrate, }; use super::mir::{interpret_mir, lower_to_mir, pad16}; @@ -38,12 +39,12 @@ pub fn unknown_const_as_generic<'db>(ty: Ty<'db>) -> GenericArg<'db> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum ConstEvalError<'db> { - MirLowerError(MirLowerError<'db>), - MirEvalError(MirEvalError<'db>), +pub enum ConstEvalError { + MirLowerError(MirLowerError), + MirEvalError(MirEvalError), } -impl ConstEvalError<'_> { +impl ConstEvalError { pub fn pretty_print( &self, f: &mut String, @@ -62,8 +63,8 @@ impl ConstEvalError<'_> { } } -impl<'db> From> for ConstEvalError<'db> { - fn from(value: MirLowerError<'db>) -> Self { +impl From for ConstEvalError { + fn from(value: MirLowerError) -> Self { match value { MirLowerError::ConstEvalError(_, e) => *e, _ => ConstEvalError::MirLowerError(value), @@ -71,8 +72,8 @@ impl<'db> From> for ConstEvalError<'db> { } } -impl<'db> From> for ConstEvalError<'db> { - fn from(value: MirEvalError<'db>) -> Self { +impl From for ConstEvalError { + fn from(value: MirEvalError) -> Self { ConstEvalError::MirEvalError(value) } } @@ -85,7 +86,8 @@ pub fn intern_const_ref<'a>( krate: Crate, ) -> Const<'a> { let interner = DbInterner::new_no_crate(db); - let layout = db.layout_of_ty(ty, ParamEnvAndCrate { param_env: ParamEnv::empty(), krate }); + let layout = db + .layout_of_ty(ty.store(), ParamEnvAndCrate { param_env: ParamEnv::empty(), krate }.store()); let kind = match value { LiteralConstRef::Int(i) => { // FIXME: We should handle failure of layout better. @@ -180,10 +182,10 @@ pub fn try_const_isize<'db>(db: &'db dyn HirDatabase, c: &Const<'db>) -> Option< } } -pub(crate) fn const_eval_discriminant_variant<'db>( - db: &'db dyn HirDatabase, +pub(crate) fn const_eval_discriminant_variant( + db: &dyn HirDatabase, variant_id: EnumVariantId, -) -> Result> { +) -> Result { let interner = DbInterner::new_no_crate(db); let def = variant_id.into(); let body = db.body(def); @@ -206,8 +208,9 @@ pub(crate) fn const_eval_discriminant_variant<'db>( let mir_body = db.monomorphized_mir_body( def, - GenericArgs::new_from_iter(interner, []), - ParamEnvAndCrate { param_env: db.trait_environment_for_body(def), krate: def.krate(db) }, + GenericArgs::empty(interner).store(), + ParamEnvAndCrate { param_env: db.trait_environment_for_body(def), krate: def.krate(db) } + .store(), )?; let c = interpret_mir(db, mir_body, false, None)?.0?; let c = if is_signed { @@ -233,7 +236,7 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd } if has_closure(ctx.body, expr) { // Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic. - return unknown_const(infer[expr]); + return Const::error(ctx.interner()); } if let Expr::Path(p) = &ctx.body[expr] { let mut ctx = TyLoweringContext::new( @@ -252,63 +255,89 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd { return result; } - unknown_const(infer[expr]) + Const::error(ctx.interner()) } -pub(crate) fn const_eval_cycle_result<'db>( - _: &'db dyn HirDatabase, - _: salsa::Id, - _: ConstId, - _: GenericArgs<'db>, - _: Option>, -) -> Result, ConstEvalError<'db>> { - Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) -} - -pub(crate) fn const_eval_static_cycle_result<'db>( - _: &'db dyn HirDatabase, - _: salsa::Id, - _: StaticId, -) -> Result, ConstEvalError<'db>> { - Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) -} - -pub(crate) fn const_eval_discriminant_cycle_result<'db>( - _: &'db dyn HirDatabase, +pub(crate) fn const_eval_discriminant_cycle_result( + _: &dyn HirDatabase, _: salsa::Id, _: EnumVariantId, -) -> Result> { +) -> Result { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) } -pub(crate) fn const_eval_query<'db>( +pub(crate) fn const_eval<'db>( db: &'db dyn HirDatabase, def: ConstId, subst: GenericArgs<'db>, trait_env: Option>, -) -> Result, ConstEvalError<'db>> { - let body = db.monomorphized_mir_body( - def.into(), - subst, - ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) }, - )?; - let c = interpret_mir(db, body, false, trait_env)?.0?; - Ok(c) +) -> Result, ConstEvalError> { + return match const_eval_query(db, def, subst.store(), trait_env.map(|env| env.store())) { + Ok(konst) => Ok(konst.as_ref()), + Err(err) => Err(err.clone()), + }; + + #[salsa::tracked(returns(ref), cycle_result = const_eval_cycle_result)] + pub(crate) fn const_eval_query<'db>( + db: &'db dyn HirDatabase, + def: ConstId, + subst: StoredGenericArgs, + trait_env: Option, + ) -> Result { + let body = db.monomorphized_mir_body( + def.into(), + subst, + ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) } + .store(), + )?; + let c = interpret_mir(db, body, false, trait_env.as_ref().map(|env| env.as_ref()))?.0?; + Ok(c.store()) + } + + pub(crate) fn const_eval_cycle_result( + _: &dyn HirDatabase, + _: salsa::Id, + _: ConstId, + _: StoredGenericArgs, + _: Option, + ) -> Result { + Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) + } } -pub(crate) fn const_eval_static_query<'db>( +pub(crate) fn const_eval_static<'db>( db: &'db dyn HirDatabase, def: StaticId, -) -> Result, ConstEvalError<'db>> { - let interner = DbInterner::new_no_crate(db); - let body = db.monomorphized_mir_body( - def.into(), - GenericArgs::new_from_iter(interner, []), - ParamEnvAndCrate { - param_env: db.trait_environment_for_body(def.into()), - krate: def.krate(db), - }, - )?; - let c = interpret_mir(db, body, false, None)?.0?; - Ok(c) +) -> Result, ConstEvalError> { + return match const_eval_static_query(db, def) { + Ok(konst) => Ok(konst.as_ref()), + Err(err) => Err(err.clone()), + }; + + #[salsa::tracked(returns(ref), cycle_result = const_eval_static_cycle_result)] + pub(crate) fn const_eval_static_query<'db>( + db: &'db dyn HirDatabase, + def: StaticId, + ) -> Result { + let interner = DbInterner::new_no_crate(db); + let body = db.monomorphized_mir_body( + def.into(), + GenericArgs::empty(interner).store(), + ParamEnvAndCrate { + param_env: db.trait_environment_for_body(def.into()), + krate: def.krate(db), + } + .store(), + )?; + let c = interpret_mir(db, body, false, None)?.0?; + Ok(c.store()) + } + + pub(crate) fn const_eval_static_cycle_result( + _: &dyn HirDatabase, + _: salsa::Id, + _: StaticId, + ) -> Result { + Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) + } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index 2dc937d76031..8816e13ba7b6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -27,7 +27,7 @@ use super::{ mod intrinsics; -fn simplify(e: ConstEvalError<'_>) -> ConstEvalError<'_> { +fn simplify(e: ConstEvalError) -> ConstEvalError { match e { ConstEvalError::MirEvalError(MirEvalError::InFunction(e, _)) => { simplify(ConstEvalError::MirEvalError(*e)) @@ -39,7 +39,7 @@ fn simplify(e: ConstEvalError<'_>) -> ConstEvalError<'_> { #[track_caller] fn check_fail( #[rust_analyzer::rust_fixture] ra_fixture: &str, - error: impl FnOnce(ConstEvalError<'_>) -> bool, + error: impl FnOnce(ConstEvalError) -> bool, ) { let (db, file_id) = TestDB::with_single_file(ra_fixture); crate::attach_db(&db, || match eval_goal(&db, file_id) { @@ -104,7 +104,7 @@ fn check_answer( }); } -fn pretty_print_err(e: ConstEvalError<'_>, db: &TestDB) -> String { +fn pretty_print_err(e: ConstEvalError, db: &TestDB) -> String { let mut err = String::new(); let span_formatter = |file, range| format!("{file:?} {range:?}"); let display_target = @@ -121,7 +121,7 @@ fn pretty_print_err(e: ConstEvalError<'_>, db: &TestDB) -> String { err } -fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result, ConstEvalError<'_>> { +fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result, ConstEvalError> { let _tracing = setup_tracing(); let interner = DbInterner::new_no_crate(db); let module_id = db.module_for_file(file_id.file_id(db)); @@ -142,7 +142,7 @@ fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result, ConstEv _ => None, }) .expect("No const named GOAL found in the test"); - db.const_eval(const_id, GenericArgs::new_from_iter(interner, []), None) + db.const_eval(const_id, GenericArgs::empty(interner), None) } #[test] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index 47bb6675ea48..f0f65eedbce9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -19,9 +19,10 @@ use crate::{ lower::{Diagnostics, GenericDefaults}, mir::{BorrowckResult, MirBody, MirLowerError}, next_solver::{ - Const, EarlyBinder, GenericArgs, ParamEnv, PolyFnSig, TraitRef, Ty, VariancesOf, + Const, EarlyBinder, GenericArgs, ParamEnv, PolyFnSig, StoredEarlyBinder, StoredGenericArgs, + StoredTy, TraitRef, Ty, VariancesOf, }, - traits::ParamEnvAndCrate, + traits::{ParamEnvAndCrate, StoredParamEnvAndCrate}, }; #[query_group::query_group] @@ -32,60 +33,48 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { // and `monomorphized_mir_body_for_closure` into `monomorphized_mir_body` #[salsa::invoke(crate::mir::mir_body_query)] #[salsa::cycle(cycle_result = crate::mir::mir_body_cycle_result)] - fn mir_body<'db>( - &'db self, - def: DefWithBodyId, - ) -> Result>, MirLowerError<'db>>; + fn mir_body(&self, def: DefWithBodyId) -> Result, MirLowerError>; #[salsa::invoke(crate::mir::mir_body_for_closure_query)] - fn mir_body_for_closure<'db>( - &'db self, - def: InternedClosureId, - ) -> Result>, MirLowerError<'db>>; + fn mir_body_for_closure(&self, def: InternedClosureId) -> Result, MirLowerError>; #[salsa::invoke(crate::mir::monomorphized_mir_body_query)] #[salsa::cycle(cycle_result = crate::mir::monomorphized_mir_body_cycle_result)] - fn monomorphized_mir_body<'db>( - &'db self, + fn monomorphized_mir_body( + &self, def: DefWithBodyId, - subst: GenericArgs<'db>, - env: ParamEnvAndCrate<'db>, - ) -> Result>, MirLowerError<'db>>; + subst: StoredGenericArgs, + env: StoredParamEnvAndCrate, + ) -> Result, MirLowerError>; #[salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)] - fn monomorphized_mir_body_for_closure<'db>( - &'db self, + fn monomorphized_mir_body_for_closure( + &self, def: InternedClosureId, - subst: GenericArgs<'db>, - env: ParamEnvAndCrate<'db>, - ) -> Result>, MirLowerError<'db>>; + subst: StoredGenericArgs, + env: StoredParamEnvAndCrate, + ) -> Result, MirLowerError>; #[salsa::invoke(crate::mir::borrowck_query)] #[salsa::lru(2024)] - fn borrowck<'db>( - &'db self, - def: DefWithBodyId, - ) -> Result]>, MirLowerError<'db>>; + fn borrowck(&self, def: DefWithBodyId) -> Result, MirLowerError>; - #[salsa::invoke(crate::consteval::const_eval_query)] - #[salsa::cycle(cycle_result = crate::consteval::const_eval_cycle_result)] + #[salsa::invoke(crate::consteval::const_eval)] + #[salsa::transparent] fn const_eval<'db>( &'db self, def: ConstId, subst: GenericArgs<'db>, trait_env: Option>, - ) -> Result, ConstEvalError<'db>>; + ) -> Result, ConstEvalError>; - #[salsa::invoke(crate::consteval::const_eval_static_query)] - #[salsa::cycle(cycle_result = crate::consteval::const_eval_static_cycle_result)] - fn const_eval_static<'db>(&'db self, def: StaticId) -> Result, ConstEvalError<'db>>; + #[salsa::invoke(crate::consteval::const_eval_static)] + #[salsa::transparent] + fn const_eval_static<'db>(&'db self, def: StaticId) -> Result, ConstEvalError>; #[salsa::invoke(crate::consteval::const_eval_discriminant_variant)] #[salsa::cycle(cycle_result = crate::consteval::const_eval_discriminant_cycle_result)] - fn const_eval_discriminant<'db>( - &'db self, - def: EnumVariantId, - ) -> Result>; + fn const_eval_discriminant(&self, def: EnumVariantId) -> Result; #[salsa::invoke(crate::method_resolution::lookup_impl_method_query)] #[salsa::transparent] @@ -100,19 +89,19 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { #[salsa::invoke(crate::layout::layout_of_adt_query)] #[salsa::cycle(cycle_result = crate::layout::layout_of_adt_cycle_result)] - fn layout_of_adt<'db>( - &'db self, + fn layout_of_adt( + &self, def: AdtId, - args: GenericArgs<'db>, - trait_env: ParamEnvAndCrate<'db>, + args: StoredGenericArgs, + trait_env: StoredParamEnvAndCrate, ) -> Result, LayoutError>; #[salsa::invoke(crate::layout::layout_of_ty_query)] #[salsa::cycle(cycle_result = crate::layout::layout_of_ty_cycle_result)] - fn layout_of_ty<'db>( - &'db self, - ty: Ty<'db>, - env: ParamEnvAndCrate<'db>, + fn layout_of_ty( + &self, + ty: StoredTy, + env: StoredParamEnvAndCrate, ) -> Result, LayoutError>; #[salsa::invoke(crate::layout::target_data_layout_query)] @@ -125,8 +114,8 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { #[salsa::transparent] fn ty<'db>(&'db self, def: TyDefId) -> EarlyBinder<'db, Ty<'db>>; - #[salsa::invoke(crate::lower::type_for_type_alias_with_diagnostics_query)] - #[salsa::cycle(cycle_result = crate::lower::type_for_type_alias_with_diagnostics_cycle_result)] + #[salsa::invoke(crate::lower::type_for_type_alias_with_diagnostics)] + #[salsa::transparent] fn type_for_type_alias_with_diagnostics<'db>( &'db self, def: TypeAliasId, @@ -134,11 +123,12 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { /// Returns the type of the value of the given constant, or `None` if the `ValueTyDefId` is /// a `StructId` or `EnumVariantId` with a record constructor. - #[salsa::invoke(crate::lower::value_ty_query)] + #[salsa::invoke(crate::lower::value_ty)] + #[salsa::transparent] fn value_ty<'db>(&'db self, def: ValueTyDefId) -> Option>>; - #[salsa::invoke(crate::lower::impl_self_ty_with_diagnostics_query)] - #[salsa::cycle(cycle_result = crate::lower::impl_self_ty_with_diagnostics_cycle_result)] + #[salsa::invoke(crate::lower::impl_self_ty_with_diagnostics)] + #[salsa::transparent] fn impl_self_ty_with_diagnostics<'db>( &'db self, def: ImplId, @@ -148,9 +138,8 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { #[salsa::transparent] fn impl_self_ty<'db>(&'db self, def: ImplId) -> EarlyBinder<'db, Ty<'db>>; - // FIXME: Make this a non-interned query. - #[salsa::invoke_interned(crate::lower::const_param_ty_with_diagnostics_query)] - #[salsa::cycle(cycle_result = crate::lower::const_param_ty_with_diagnostics_cycle_result)] + #[salsa::invoke(crate::lower::const_param_ty_with_diagnostics)] + #[salsa::transparent] fn const_param_ty_with_diagnostics<'db>(&'db self, def: ConstParamId) -> (Ty<'db>, Diagnostics); @@ -158,7 +147,8 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { #[salsa::transparent] fn const_param_ty_ns<'db>(&'db self, def: ConstParamId) -> Ty<'db>; - #[salsa::invoke(crate::lower::impl_trait_with_diagnostics_query)] + #[salsa::invoke(crate::lower::impl_trait_with_diagnostics)] + #[salsa::transparent] fn impl_trait_with_diagnostics<'db>( &'db self, def: ImplId, @@ -169,19 +159,18 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { fn impl_trait<'db>(&'db self, def: ImplId) -> Option>>; #[salsa::invoke(crate::lower::field_types_with_diagnostics_query)] - fn field_types_with_diagnostics<'db>( - &'db self, + #[salsa::transparent] + fn field_types_with_diagnostics( + &self, var: VariantId, - ) -> (Arc>>>, Diagnostics); + ) -> &(ArenaMap>, Diagnostics); #[salsa::invoke(crate::lower::field_types_query)] #[salsa::transparent] - fn field_types<'db>( - &'db self, - var: VariantId, - ) -> Arc>>>; + fn field_types(&self, var: VariantId) -> &ArenaMap>; - #[salsa::invoke(crate::lower::callable_item_signature_query)] + #[salsa::invoke(crate::lower::callable_item_signature)] + #[salsa::transparent] fn callable_item_signature<'db>( &'db self, def: CallableDefId, @@ -191,26 +180,27 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { #[salsa::transparent] fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId) -> ParamEnv<'db>; - #[salsa::invoke(crate::lower::trait_environment_query)] + #[salsa::invoke(crate::lower::trait_environment)] + #[salsa::transparent] fn trait_environment<'db>(&'db self, def: GenericDefId) -> ParamEnv<'db>; #[salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)] #[salsa::cycle(cycle_result = crate::lower::generic_defaults_with_diagnostics_cycle_result)] - fn generic_defaults_with_diagnostics<'db>( - &'db self, + fn generic_defaults_with_diagnostics( + &self, def: GenericDefId, - ) -> (GenericDefaults<'db>, Diagnostics); + ) -> (GenericDefaults, Diagnostics); /// This returns an empty list if no parameter has default. /// /// The binders of the returned defaults are only up to (not including) this parameter. #[salsa::invoke(crate::lower::generic_defaults_query)] #[salsa::transparent] - fn generic_defaults<'db>(&'db self, def: GenericDefId) -> GenericDefaults<'db>; + fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults; // Interned IDs for solver integration #[salsa::interned] - fn intern_impl_trait_id(&self, id: ImplTraitId<'_>) -> InternedOpaqueTyId; + fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId; #[salsa::interned] fn intern_closure(&self, id: InternedClosure) -> InternedClosureId; @@ -219,11 +209,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { fn intern_coroutine(&self, id: InternedCoroutine) -> InternedCoroutineId; #[salsa::invoke(crate::variance::variances_of)] - #[salsa::cycle( - // cycle_fn = crate::variance::variances_of_cycle_fn, - // cycle_initial = crate::variance::variances_of_cycle_initial, - cycle_result = crate::variance::variances_of_cycle_initial, - )] + #[salsa::transparent] fn variances_of<'db>(&'db self, def: GenericDefId) -> VariancesOf<'db>; } @@ -245,10 +231,10 @@ pub struct InternedConstParamId { pub loc: ConstParamId, } -#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX, unsafe(non_update_types))] +#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)] #[derive(PartialOrd, Ord)] pub struct InternedOpaqueTyId { - pub loc: ImplTraitId<'db>, + pub loc: ImplTraitId, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs index 0de7fab8d1b2..dd1fc3b36ef8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs @@ -99,7 +99,7 @@ impl BodyValidationDiagnostic { struct ExprValidator<'db> { owner: DefWithBodyId, body: Arc, - infer: &'db InferenceResult<'db>, + infer: &'db InferenceResult, env: ParamEnv<'db>, diagnostics: Vec, validate_lints: bool, @@ -313,7 +313,7 @@ impl<'db> ExprValidator<'db> { ); value_or_partial.is_none_or(|v| !matches!(v, ValueNs::StaticId(_))) } - Expr::Field { expr, .. } => match self.infer.type_of_expr[*expr].kind() { + Expr::Field { expr, .. } => match self.infer.expr_ty(*expr).kind() { TyKind::Adt(adt, ..) if matches!(adt.def_id().0, AdtId::UnionId(_)) => false, _ => self.is_known_valid_scrutinee(*expr), }, @@ -554,7 +554,7 @@ impl<'db> FilterMapNextChecker<'db> { pub fn record_literal_missing_fields( db: &dyn HirDatabase, - infer: &InferenceResult<'_>, + infer: &InferenceResult, id: ExprId, expr: &Expr, ) -> Option<(VariantId, Vec, /*exhaustive*/ bool)> { @@ -584,7 +584,7 @@ pub fn record_literal_missing_fields( pub fn record_pattern_missing_fields( db: &dyn HirDatabase, - infer: &InferenceResult<'_>, + infer: &InferenceResult, id: PatId, pat: &Pat, ) -> Option<(VariantId, Vec, /*exhaustive*/ bool)> { @@ -612,8 +612,8 @@ pub fn record_pattern_missing_fields( Some((variant_def, missed_fields, exhaustive)) } -fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResult<'_>) -> bool { - fn walk(pat: PatId, body: &Body, infer: &InferenceResult<'_>, has_type_mismatches: &mut bool) { +fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResult) -> bool { + fn walk(pat: PatId, body: &Body, infer: &InferenceResult, has_type_mismatches: &mut bool) { match infer.type_mismatch_for_pat(pat) { Some(_) => *has_type_mismatches = true, None if *has_type_mismatches => (), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs index 80b65ace77cd..8e6101e6a0e3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs @@ -16,7 +16,7 @@ use hir_def::{ item_tree::FieldsShape, }; use hir_expand::name::Name; -use rustc_type_ir::inherent::{IntoKind, SliceLike}; +use rustc_type_ir::inherent::IntoKind; use span::Edition; use stdx::{always, never, variance::PhantomCovariantLifetime}; @@ -96,7 +96,7 @@ pub(crate) enum PatKind<'db> { pub(crate) struct PatCtxt<'a, 'db> { db: &'db dyn HirDatabase, - infer: &'a InferenceResult<'db>, + infer: &'db InferenceResult, body: &'a Body, pub(crate) errors: Vec, } @@ -104,7 +104,7 @@ pub(crate) struct PatCtxt<'a, 'db> { impl<'a, 'db> PatCtxt<'a, 'db> { pub(crate) fn new( db: &'db dyn HirDatabase, - infer: &'a InferenceResult<'db>, + infer: &'db InferenceResult, body: &'a Body, ) -> Self { Self { db, infer, body, errors: Vec::new() } @@ -119,12 +119,15 @@ impl<'a, 'db> PatCtxt<'a, 'db> { let unadjusted_pat = self.lower_pattern_unadjusted(pat); self.infer.pat_adjustments.get(&pat).map(|it| &**it).unwrap_or_default().iter().rev().fold( unadjusted_pat, - |subpattern, ref_ty| Pat { ty: *ref_ty, kind: Box::new(PatKind::Deref { subpattern }) }, + |subpattern, ref_ty| Pat { + ty: ref_ty.as_ref(), + kind: Box::new(PatKind::Deref { subpattern }), + }, ) } fn lower_pattern_unadjusted(&mut self, pat: PatId) -> Pat<'db> { - let mut ty = self.infer[pat]; + let mut ty = self.infer.pat_ty(pat); let variant = self.infer.variant_resolution_for_pat(pat); let kind = match self.body[pat] { @@ -151,7 +154,7 @@ impl<'a, 'db> PatCtxt<'a, 'db> { hir_def::hir::Pat::Bind { id, subpat, .. } => { let bm = self.infer.binding_modes[pat]; - ty = self.infer[id]; + ty = self.infer.binding_ty(id); let name = &self.body[id].name; match (bm, ty.kind()) { (BindingMode::Ref(_), TyKind::Ref(_, rty, _)) => ty = rty, @@ -273,7 +276,7 @@ impl<'a, 'db> PatCtxt<'a, 'db> { } fn lower_path(&mut self, pat: PatId, _path: &Path) -> Pat<'db> { - let ty = self.infer[pat]; + let ty = self.infer.pat_ty(pat); let pat_from_kind = |kind| Pat { ty, kind: Box::new(kind) }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 91448d5806f9..eda7e7e249b3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -11,7 +11,7 @@ use rustc_pattern_analysis::{ constructor::{Constructor, ConstructorSet, VariantVisibility}, usefulness::{PlaceValidity, UsefulnessReport, compute_match_usefulness}, }; -use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike}; +use rustc_type_ir::inherent::{AdtDef, IntoKind}; use smallvec::{SmallVec, smallvec}; use stdx::never; @@ -150,7 +150,7 @@ impl<'a, 'db> MatchCheckCtx<'a, 'db> { let fields_len = variant.fields(self.db).fields().len() as u32; (0..fields_len).map(|idx| LocalFieldId::from_raw(idx.into())).map(move |fid| { - let ty = field_tys[fid].instantiate(self.infcx.interner, substs); + let ty = field_tys[fid].get().instantiate(self.infcx.interner, substs); let ty = self .infcx .at(&ObligationCause::dummy(), self.env) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs index bbc381ba5d51..50d4517d0125 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -97,9 +97,9 @@ enum UnsafeDiagnostic { DeprecatedSafe2024 { node: ExprId, inside_unsafe_block: InsideUnsafeBlock }, } -pub fn unsafe_operations_for_body<'db>( - db: &'db dyn HirDatabase, - infer: &InferenceResult<'db>, +pub fn unsafe_operations_for_body( + db: &dyn HirDatabase, + infer: &InferenceResult, def: DefWithBodyId, body: &Body, callback: &mut dyn FnMut(ExprOrPatId), @@ -116,9 +116,9 @@ pub fn unsafe_operations_for_body<'db>( } } -pub fn unsafe_operations<'db>( - db: &'db dyn HirDatabase, - infer: &InferenceResult<'db>, +pub fn unsafe_operations( + db: &dyn HirDatabase, + infer: &InferenceResult, def: DefWithBodyId, body: &Body, current: ExprId, @@ -136,7 +136,7 @@ pub fn unsafe_operations<'db>( struct UnsafeVisitor<'db> { db: &'db dyn HirDatabase, - infer: &'db InferenceResult<'db>, + infer: &'db InferenceResult, body: &'db Body, resolver: Resolver<'db>, def: DefWithBodyId, @@ -155,7 +155,7 @@ struct UnsafeVisitor<'db> { impl<'db> UnsafeVisitor<'db> { fn new( db: &'db dyn HirDatabase, - infer: &'db InferenceResult<'db>, + infer: &'db InferenceResult, body: &'db Body, def: DefWithBodyId, unsafe_expr_cb: &'db mut dyn FnMut(UnsafeDiagnostic), @@ -260,7 +260,7 @@ impl<'db> UnsafeVisitor<'db> { match pat { Pat::Record { .. } => { - if let Some((AdtId::UnionId(_), _)) = self.infer[current].as_adt() { + if let Some((AdtId::UnionId(_), _)) = self.infer.pat_ty(current).as_adt() { let old_inside_union_destructure = mem::replace(&mut self.inside_union_destructure, true); self.body.walk_pats_shallow(current, |pat| self.walk_pat(pat)); @@ -286,7 +286,7 @@ impl<'db> UnsafeVisitor<'db> { let inside_assignment = mem::replace(&mut self.inside_assignment, false); match expr { &Expr::Call { callee, .. } => { - let callee = self.infer[callee]; + let callee = self.infer.expr_ty(callee); if let TyKind::FnDef(CallableIdWrapper(CallableDefId::FunctionId(func)), _) = callee.kind() { @@ -341,7 +341,7 @@ impl<'db> UnsafeVisitor<'db> { } } Expr::UnaryOp { expr, op: UnaryOp::Deref } => { - if let TyKind::RawPtr(..) = self.infer[*expr].kind() { + if let TyKind::RawPtr(..) = self.infer.expr_ty(*expr).kind() { self.on_unsafe_op(current.into(), UnsafetyReason::RawPtrDeref); } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index e1d62a9c7a3e..8e44c14abe23 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -38,7 +38,7 @@ use rustc_hash::FxHashSet; use rustc_type_ir::{ AliasTyKind, BoundVarIndexKind, CoroutineArgsParts, CoroutineClosureArgsParts, RegionKind, Upcast, - inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _, Tys as _}, + inherent::{AdtDef, GenericArgs as _, IntoKind, Term as _, Ty as _, Tys as _}, }; use smallvec::SmallVec; use span::Edition; @@ -52,9 +52,9 @@ use crate::{ lower::GenericPredicates, mir::pad16, next_solver::{ - AliasTy, Clause, ClauseKind, Const, ConstKind, DbInterner, EarlyBinder, - ExistentialPredicate, FnSig, GenericArg, GenericArgs, ParamEnv, PolyFnSig, Region, - SolverDefId, Term, TraitRef, Ty, TyKind, TypingMode, + AliasTy, Clause, ClauseKind, Const, ConstKind, DbInterner, ExistentialPredicate, FnSig, + GenericArg, GenericArgKind, GenericArgs, ParamEnv, PolyFnSig, Region, SolverDefId, + StoredEarlyBinder, StoredTy, Term, TermKind, TraitRef, Ty, TyKind, TypingMode, abi::Safety, infer::{DbInternerInferExt, traits::ObligationCause}, }, @@ -602,7 +602,7 @@ impl<'db, T: HirDisplay<'db>> HirDisplay<'db> for &T { impl<'db, T: HirDisplay<'db> + Internable> HirDisplay<'db> for Interned { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { - HirDisplay::hir_fmt(self.as_ref(), f) + HirDisplay::hir_fmt(&**self, f) } } @@ -664,10 +664,10 @@ fn write_projection<'db>(f: &mut HirFormatter<'_, 'db>, alias: &AliasTy<'db>) -> impl<'db> HirDisplay<'db> for GenericArg<'db> { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { - match self { - GenericArg::Ty(ty) => ty.hir_fmt(f), - GenericArg::Lifetime(lt) => lt.hir_fmt(f), - GenericArg::Const(c) => c.hir_fmt(f), + match self.kind() { + GenericArgKind::Type(ty) => ty.hir_fmt(f), + GenericArgKind::Lifetime(lt) => lt.hir_fmt(f), + GenericArgKind::Const(c) => c.hir_fmt(f), } } } @@ -790,7 +790,7 @@ fn render_const_scalar_inner<'db>( TyKind::Slice(ty) => { let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap()); let count = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap()); - let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { + let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else { return f.write_str(""); }; let size_one = layout.size.bytes_usize(); @@ -824,7 +824,7 @@ fn render_const_scalar_inner<'db>( let Ok(t) = memory_map.vtable_ty(ty_id) else { return f.write_str(""); }; - let Ok(layout) = f.db.layout_of_ty(t, param_env) else { + let Ok(layout) = f.db.layout_of_ty(t.store(), param_env.store()) else { return f.write_str(""); }; let size = layout.size.bytes_usize(); @@ -854,7 +854,7 @@ fn render_const_scalar_inner<'db>( return f.write_str(""); } }); - let Ok(layout) = f.db.layout_of_ty(t, param_env) else { + let Ok(layout) = f.db.layout_of_ty(t.store(), param_env.store()) else { return f.write_str(""); }; let size = layout.size.bytes_usize(); @@ -866,7 +866,7 @@ fn render_const_scalar_inner<'db>( } }, TyKind::Tuple(tys) => { - let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { + let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else { return f.write_str(""); }; f.write_str("(")?; @@ -878,7 +878,7 @@ fn render_const_scalar_inner<'db>( f.write_str(", ")?; } let offset = layout.fields.offset(id).bytes_usize(); - let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { + let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else { f.write_str("")?; continue; }; @@ -889,7 +889,7 @@ fn render_const_scalar_inner<'db>( } TyKind::Adt(def, args) => { let def = def.def_id().0; - let Ok(layout) = f.db.layout_of_adt(def, args, param_env) else { + let Ok(layout) = f.db.layout_of_adt(def, args.store(), param_env.store()) else { return f.write_str(""); }; match def { @@ -900,7 +900,7 @@ fn render_const_scalar_inner<'db>( render_variant_after_name( s.fields(f.db), f, - &field_types, + field_types, f.db.trait_environment(def.into()), &layout, args, @@ -932,7 +932,7 @@ fn render_const_scalar_inner<'db>( render_variant_after_name( var_id.fields(f.db), f, - &field_types, + field_types, f.db.trait_environment(def.into()), var_layout, args, @@ -952,7 +952,7 @@ fn render_const_scalar_inner<'db>( let Some(len) = consteval::try_const_usize(f.db, len) else { return f.write_str(""); }; - let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { + let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else { return f.write_str(""); }; let size_one = layout.size.bytes_usize(); @@ -992,7 +992,7 @@ fn render_const_scalar_inner<'db>( fn render_variant_after_name<'db>( data: &VariantFields, f: &mut HirFormatter<'_, 'db>, - field_types: &ArenaMap>>, + field_types: &'db ArenaMap>, param_env: ParamEnv<'db>, layout: &Layout, args: GenericArgs<'db>, @@ -1004,8 +1004,8 @@ fn render_variant_after_name<'db>( FieldsShape::Record | FieldsShape::Tuple => { let render_field = |f: &mut HirFormatter<'_, 'db>, id: LocalFieldId| { let offset = layout.fields.offset(u32::from(id.into_raw()) as usize).bytes_usize(); - let ty = field_types[id].instantiate(f.interner, args); - let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { + let ty = field_types[id].get().instantiate(f.interner, args); + let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else { return f.write_str(""); }; let size = layout.size.bytes_usize(); @@ -1223,7 +1223,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> { }; f.end_location_link(); - if args.len() > 0 { + if !args.is_empty() { let generic_def_id = GenericDefId::from_callable(db, def); let generics = generics(db, generic_def_id); let (parent_len, self_param, type_, const_, impl_, lifetime) = @@ -1787,9 +1787,9 @@ impl<'db> HirDisplay<'db> for PolyFnSig<'db> { impl<'db> HirDisplay<'db> for Term<'db> { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { - match self { - Term::Ty(it) => it.hir_fmt(f), - Term::Const(it) => it.hir_fmt(f), + match self.kind() { + TermKind::Ty(it) => it.hir_fmt(f), + TermKind::Const(it) => it.hir_fmt(f), } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs index 3ae6451d6952..66692143bc1a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs @@ -2,7 +2,7 @@ use hir_def::{AdtId, signatures::StructFlags}; use rustc_hash::FxHashSet; -use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike}; +use rustc_type_ir::inherent::{AdtDef, IntoKind}; use stdx::never; use crate::{ @@ -85,7 +85,7 @@ fn has_drop_glue_impl<'db>( .map(|(_, field_ty)| { has_drop_glue_impl( infcx, - field_ty.instantiate(infcx.interner, subst), + field_ty.get().instantiate(infcx.interner, subst), env, visited, ) @@ -105,7 +105,7 @@ fn has_drop_glue_impl<'db>( .map(|(_, field_ty)| { has_drop_glue_impl( infcx, - field_ty.instantiate(infcx.interner, subst), + field_ty.get().instantiate(infcx.interner, subst), env, visited, ) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index 64b15eb017a6..ffdc9ca0f85a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs @@ -10,8 +10,7 @@ use hir_def::{ use rustc_hash::FxHashSet; use rustc_type_ir::{ AliasTyKind, ClauseKind, PredicatePolarity, TypeSuperVisitable as _, TypeVisitable as _, - Upcast, elaborate, - inherent::{IntoKind, SliceLike}, + Upcast, elaborate, inherent::IntoKind, }; use smallvec::SmallVec; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index d6682c0cf2fe..bd5fffc4cc65 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -28,7 +28,7 @@ mod path; mod place_op; pub(crate) mod unify; -use std::{cell::OnceCell, convert::identity, iter, ops::Index}; +use std::{cell::OnceCell, convert::identity, iter}; use base_db::Crate; use either::Either; @@ -47,14 +47,12 @@ use hir_expand::{mod_path::ModPath, name::Name}; use indexmap::IndexSet; use intern::sym; use la_arena::ArenaMap; -use macros::{TypeFoldable, TypeVisitable}; use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; use rustc_type_ir::{ AliasTyKind, TypeFoldable, - inherent::{AdtDef, IntoKind, Region as _, SliceLike, Ty as _}, + inherent::{AdtDef, IntoKind, Region as _, Ty as _}, }; -use salsa::Update; use span::Edition; use stdx::never; use thin_vec::ThinVec; @@ -74,8 +72,8 @@ use crate::{ method_resolution::{CandidateId, MethodResolutionUnstableFeatures}, mir::MirSpan, next_solver::{ - AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Region, Ty, TyKind, - Tys, + AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Region, + StoredGenericArgs, StoredTy, StoredTys, Ty, TyKind, Tys, abi::Safety, infer::{InferCtxt, traits::ObligationCause}, }, @@ -95,7 +93,7 @@ use cast::{CastCheck, CastError}; pub(crate) use closure::analysis::{CaptureKind, CapturedItem, CapturedItemWithoutTy}; /// The entry point of type inference. -fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> { +fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult { let _p = tracing::info_span!("infer_query").entered(); let resolver = def.resolver(db); let body = db.body(def); @@ -162,7 +160,7 @@ fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> ctx.resolve_all() } -fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> InferenceResult<'_> { +fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> InferenceResult { InferenceResult { has_errors: true, ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)) @@ -196,8 +194,8 @@ pub enum InferenceTyDiagnosticSource { Signature, } -#[derive(Debug, PartialEq, Eq, Clone, Update)] -pub enum InferenceDiagnostic<'db> { +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum InferenceDiagnostic { NoSuchField { field: ExprOrPatId, private: Option, @@ -213,16 +211,16 @@ pub enum InferenceDiagnostic<'db> { }, UnresolvedField { expr: ExprId, - receiver: Ty<'db>, + receiver: StoredTy, name: Name, method_with_same_name_exists: bool, }, UnresolvedMethodCall { expr: ExprId, - receiver: Ty<'db>, + receiver: StoredTy, name: Name, /// Contains the type the field resolves to - field_with_same_name: Option>, + field_with_same_name: Option, assoc_func_with_same_name: Option, }, UnresolvedAssocItem { @@ -249,21 +247,21 @@ pub enum InferenceDiagnostic<'db> { }, ExpectedFunction { call_expr: ExprId, - found: Ty<'db>, + found: StoredTy, }, TypedHole { expr: ExprId, - expected: Ty<'db>, + expected: StoredTy, }, CastToUnsized { expr: ExprId, - cast_ty: Ty<'db>, + cast_ty: StoredTy, }, InvalidCast { expr: ExprId, error: CastError, - expr_ty: Ty<'db>, - cast_ty: Ty<'db>, + expr_ty: StoredTy, + cast_ty: StoredTy, }, TyDiagnostic { source: InferenceTyDiagnosticSource, @@ -290,10 +288,10 @@ pub enum InferenceDiagnostic<'db> { } /// A mismatch between an expected and an inferred type. -#[derive(Clone, PartialEq, Eq, Debug, Hash, Update)] -pub struct TypeMismatch<'db> { - pub expected: Ty<'db>, - pub actual: Ty<'db>, +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub struct TypeMismatch { + pub expected: StoredTy, + pub actual: StoredTy, } /// Represents coercing a value to a different type of value. @@ -336,20 +334,23 @@ pub struct TypeMismatch<'db> { /// At some point, of course, `Box` should move out of the compiler, in which /// case this is analogous to transforming a struct. E.g., Box<[i32; 4]> -> /// Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`. -#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable, Update)] -pub struct Adjustment<'db> { - #[type_visitable(ignore)] - #[type_foldable(identity)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Adjustment { pub kind: Adjust, - pub target: Ty<'db>, + pub target: StoredTy, } -impl<'db> Adjustment<'db> { - pub fn borrow(interner: DbInterner<'db>, m: Mutability, ty: Ty<'db>, lt: Region<'db>) -> Self { +impl Adjustment { + pub fn borrow<'db>( + interner: DbInterner<'db>, + m: Mutability, + ty: Ty<'db>, + lt: Region<'db>, + ) -> Self { let ty = Ty::new_ref(interner, lt, ty, m); Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::new(m, AllowTwoPhase::No))), - target: ty, + target: ty.store(), } } } @@ -473,56 +474,47 @@ pub enum PointerCast { /// When you add a field that stores types (including `Substitution` and the like), don't forget /// `resolve_completely()`'ing them in `InferenceContext::resolve_all()`. Inference variables must /// not appear in the final inference result. -#[derive(Clone, PartialEq, Eq, Debug, Update)] -pub struct InferenceResult<'db> { +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct InferenceResult { /// For each method call expr, records the function it resolves to. - #[update(unsafe(with(crate::utils::unsafe_update_eq /* expr id is technically update */)))] - method_resolutions: FxHashMap)>, + method_resolutions: FxHashMap, /// For each field access expr, records the field it resolves to. field_resolutions: FxHashMap>, /// For each struct literal or pattern, records the variant it resolves to. variant_resolutions: FxHashMap, /// For each associated item record what it resolves to - assoc_resolutions: FxHashMap)>, + assoc_resolutions: FxHashMap, /// Whenever a tuple field expression access a tuple field, we allocate a tuple id in /// [`InferenceContext`] and store the tuples substitution there. This map is the reverse of /// that which allows us to resolve a [`TupleFieldId`]s type. - #[update(unsafe(with(crate::utils::unsafe_update_eq /* thinvec is technically update */)))] - tuple_field_access_types: ThinVec>, + tuple_field_access_types: ThinVec, - #[update(unsafe(with(crate::utils::unsafe_update_eq /* expr id is technically update */)))] - pub(crate) type_of_expr: ArenaMap>, + pub(crate) type_of_expr: ArenaMap, /// For each pattern record the type it resolves to. /// /// **Note**: When a pattern type is resolved it may still contain /// unresolved or missing subpatterns or subpatterns of mismatched types. - #[update(unsafe(with(crate::utils::unsafe_update_eq /* pat id is technically update */)))] - pub(crate) type_of_pat: ArenaMap>, - #[update(unsafe(with(crate::utils::unsafe_update_eq /* binding id is technically update */)))] - pub(crate) type_of_binding: ArenaMap>, - #[update(unsafe(with(crate::utils::unsafe_update_eq /* type ref id is technically update */)))] - pub(crate) type_of_type_placeholder: FxHashMap>, - pub(crate) type_of_opaque: FxHashMap>, + pub(crate) type_of_pat: ArenaMap, + pub(crate) type_of_binding: ArenaMap, + pub(crate) type_of_type_placeholder: FxHashMap, + pub(crate) type_of_opaque: FxHashMap, - pub(crate) type_mismatches: Option>>>, + pub(crate) type_mismatches: Option>>, /// Whether there are any type-mismatching errors in the result. // FIXME: This isn't as useful as initially thought due to us falling back placeholders to // `TyKind::Error`. // Which will then mark this field. pub(crate) has_errors: bool, /// During inference this field is empty and [`InferenceContext::diagnostics`] is filled instead. - #[update(unsafe(with(crate::utils::unsafe_update_eq /* thinvec is technically update */)))] - diagnostics: ThinVec>, + diagnostics: ThinVec, /// Interned `Error` type to return references to. // FIXME: Remove this. - error_ty: Ty<'db>, + error_ty: StoredTy, - #[update(unsafe(with(crate::utils::unsafe_update_eq /* expr id is technically update */)))] - pub(crate) expr_adjustments: FxHashMap]>>, + pub(crate) expr_adjustments: FxHashMap>, /// Stores the types which were implicitly dereferenced in pattern binding modes. - #[update(unsafe(with(crate::utils::unsafe_update_eq /* pat id is technically update */)))] - pub(crate) pat_adjustments: FxHashMap>>, + pub(crate) pat_adjustments: FxHashMap>, /// Stores the binding mode (`ref` in `let ref x = 2`) of bindings. /// /// This one is tied to the `PatId` instead of `BindingId`, because in some rare cases, a binding in an @@ -538,7 +530,7 @@ pub struct InferenceResult<'db> { /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`. pub(crate) binding_modes: ArenaMap, - pub(crate) closure_info: FxHashMap>, FnTrait)>, + pub(crate) closure_info: FxHashMap, FnTrait)>, // FIXME: remove this field pub mutated_bindings_in_closure: FxHashSet, @@ -546,15 +538,15 @@ pub struct InferenceResult<'db> { } #[salsa::tracked] -impl<'db> InferenceResult<'db> { - #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result, unsafe(non_update_types))] - pub fn for_body(db: &'db dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'db> { +impl InferenceResult { + #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)] + pub fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult { infer_query(db, def) } } -impl<'db> InferenceResult<'db> { - fn new(error_ty: Ty<'db>) -> Self { +impl InferenceResult { + fn new(error_ty: Ty<'_>) -> Self { Self { method_resolutions: Default::default(), field_resolutions: Default::default(), @@ -569,7 +561,7 @@ impl<'db> InferenceResult<'db> { type_of_opaque: Default::default(), type_mismatches: Default::default(), has_errors: Default::default(), - error_ty, + error_ty: error_ty.store(), pat_adjustments: Default::default(), binding_modes: Default::default(), expr_adjustments: Default::default(), @@ -579,8 +571,8 @@ impl<'db> InferenceResult<'db> { } } - pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> { - self.method_resolutions.get(&expr).copied() + pub fn method_resolution<'db>(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> { + self.method_resolutions.get(&expr).map(|(func, args)| (*func, args.as_ref())) } pub fn field_resolution(&self, expr: ExprId) -> Option> { self.field_resolutions.get(&expr).copied() @@ -597,16 +589,19 @@ impl<'db> InferenceResult<'db> { ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id), } } - pub fn assoc_resolutions_for_expr( + pub fn assoc_resolutions_for_expr<'db>( &self, id: ExprId, ) -> Option<(CandidateId, GenericArgs<'db>)> { - self.assoc_resolutions.get(&id.into()).copied() + self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref())) } - pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<(CandidateId, GenericArgs<'db>)> { - self.assoc_resolutions.get(&id.into()).copied() + pub fn assoc_resolutions_for_pat<'db>( + &self, + id: PatId, + ) -> Option<(CandidateId, GenericArgs<'db>)> { + self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref())) } - pub fn assoc_resolutions_for_expr_or_pat( + pub fn assoc_resolutions_for_expr_or_pat<'db>( &self, id: ExprOrPatId, ) -> Option<(CandidateId, GenericArgs<'db>)> { @@ -615,20 +610,20 @@ impl<'db> InferenceResult<'db> { ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id), } } - pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch<'db>> { + pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { self.type_mismatches.as_deref()?.get(&expr.into()) } - pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch<'db>> { + pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch> { self.type_mismatches.as_deref()?.get(&pat.into()) } - pub fn type_mismatches(&self) -> impl Iterator)> { + pub fn type_mismatches(&self) -> impl Iterator { self.type_mismatches .as_deref() .into_iter() .flatten() .map(|(expr_or_pat, mismatch)| (*expr_or_pat, mismatch)) } - pub fn expr_type_mismatches(&self) -> impl Iterator)> { + pub fn expr_type_mismatches(&self) -> impl Iterator { self.type_mismatches.as_deref().into_iter().flatten().filter_map( |(expr_or_pat, mismatch)| match *expr_or_pat { ExprOrPatId::ExprId(expr) => Some((expr, mismatch)), @@ -636,22 +631,22 @@ impl<'db> InferenceResult<'db> { }, ) } - pub fn placeholder_types(&self) -> impl Iterator)> { - self.type_of_type_placeholder.iter().map(|(&type_ref, ty)| (type_ref, ty)) + pub fn placeholder_types<'db>(&self) -> impl Iterator)> { + self.type_of_type_placeholder.iter().map(|(&type_ref, ty)| (type_ref, ty.as_ref())) } - pub fn type_of_type_placeholder(&self, type_ref: TypeRefId) -> Option> { - self.type_of_type_placeholder.get(&type_ref).copied() + pub fn type_of_type_placeholder<'db>(&self, type_ref: TypeRefId) -> Option> { + self.type_of_type_placeholder.get(&type_ref).map(|ty| ty.as_ref()) } - pub fn closure_info(&self, closure: InternedClosureId) -> &(Vec>, FnTrait) { + pub fn closure_info(&self, closure: InternedClosureId) -> &(Vec, FnTrait) { self.closure_info.get(&closure).unwrap() } - pub fn type_of_expr_or_pat(&self, id: ExprOrPatId) -> Option> { + pub fn type_of_expr_or_pat<'db>(&self, id: ExprOrPatId) -> Option> { match id { - ExprOrPatId::ExprId(id) => self.type_of_expr.get(id).copied(), - ExprOrPatId::PatId(id) => self.type_of_pat.get(id).copied(), + ExprOrPatId::ExprId(id) => self.type_of_expr.get(id).map(|it| it.as_ref()), + ExprOrPatId::PatId(id) => self.type_of_pat.get(id).map(|it| it.as_ref()), } } - pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option> { + pub fn type_of_expr_with_adjust<'db>(&self, id: ExprId) -> Option> { match self.expr_adjustments.get(&id).and_then(|adjustments| { adjustments.iter().rfind(|adj| { // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140 @@ -660,37 +655,37 @@ impl<'db> InferenceResult<'db> { Adjustment { kind: Adjust::NeverToAny, target, - } if target.is_never() + } if target.as_ref().is_never() ) }) }) { - Some(adjustment) => Some(adjustment.target), - None => self.type_of_expr.get(id).copied(), + Some(adjustment) => Some(adjustment.target.as_ref()), + None => self.type_of_expr.get(id).map(|it| it.as_ref()), } } - pub fn type_of_pat_with_adjust(&self, id: PatId) -> Option> { + pub fn type_of_pat_with_adjust<'db>(&self, id: PatId) -> Option> { match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) { - Some(adjusted) => Some(*adjusted), - None => self.type_of_pat.get(id).copied(), + Some(adjusted) => Some(adjusted.as_ref()), + None => self.type_of_pat.get(id).map(|it| it.as_ref()), } } pub fn is_erroneous(&self) -> bool { self.has_errors && self.type_of_expr.iter().count() == 0 } - pub fn diagnostics(&self) -> &[InferenceDiagnostic<'db>] { + pub fn diagnostics(&self) -> &[InferenceDiagnostic] { &self.diagnostics } - pub fn tuple_field_access_type(&self, id: TupleId) -> Tys<'db> { - self.tuple_field_access_types[id.0 as usize] + pub fn tuple_field_access_type<'db>(&self, id: TupleId) -> Tys<'db> { + self.tuple_field_access_types[id.0 as usize].as_ref() } - pub fn pat_adjustment(&self, id: PatId) -> Option<&[Ty<'db>]> { + pub fn pat_adjustment(&self, id: PatId) -> Option<&[StoredTy]> { self.pat_adjustments.get(&id).map(|it| &**it) } - pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment<'db>]> { + pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment]> { self.expr_adjustments.get(&id).map(|it| &**it) } @@ -699,66 +694,47 @@ impl<'db> InferenceResult<'db> { } // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please. - pub fn expression_types(&self) -> impl Iterator)> { - self.type_of_expr.iter().map(|(k, v)| (k, *v)) + pub fn expression_types<'db>(&self) -> impl Iterator)> { + self.type_of_expr.iter().map(|(k, v)| (k, v.as_ref())) } // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please. - pub fn pattern_types(&self) -> impl Iterator)> { - self.type_of_pat.iter().map(|(k, v)| (k, *v)) + pub fn pattern_types<'db>(&self) -> impl Iterator)> { + self.type_of_pat.iter().map(|(k, v)| (k, v.as_ref())) } // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please. - pub fn binding_types(&self) -> impl Iterator)> { - self.type_of_binding.iter().map(|(k, v)| (k, *v)) + pub fn binding_types<'db>(&self) -> impl Iterator)> { + self.type_of_binding.iter().map(|(k, v)| (k, v.as_ref())) } // This method is consumed by external tools to run rust-analyzer as a library. Don't remove, please. - pub fn return_position_impl_trait_types( - &self, + pub fn return_position_impl_trait_types<'db>( + &'db self, db: &'db dyn HirDatabase, - ) -> impl Iterator, Ty<'db>)> { - self.type_of_opaque.iter().filter_map(move |(&id, &ty)| { + ) -> impl Iterator)> { + self.type_of_opaque.iter().filter_map(move |(&id, ty)| { let ImplTraitId::ReturnTypeImplTrait(_, rpit_idx) = id.loc(db) else { return None; }; - Some((rpit_idx, ty)) + Some((rpit_idx, ty.as_ref())) }) } -} -impl<'db> Index for InferenceResult<'db> { - type Output = Ty<'db>; - - fn index(&self, expr: ExprId) -> &Ty<'db> { - self.type_of_expr.get(expr).unwrap_or(&self.error_ty) + pub fn expr_ty<'db>(&self, id: ExprId) -> Ty<'db> { + self.type_of_expr.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref()) } -} -impl<'db> Index for InferenceResult<'db> { - type Output = Ty<'db>; - - fn index(&self, pat: PatId) -> &Ty<'db> { - self.type_of_pat.get(pat).unwrap_or(&self.error_ty) + pub fn pat_ty<'db>(&self, id: PatId) -> Ty<'db> { + self.type_of_pat.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref()) } -} -impl<'db> Index for InferenceResult<'db> { - type Output = Ty<'db>; - - fn index(&self, id: ExprOrPatId) -> &Ty<'db> { - match id { - ExprOrPatId::ExprId(id) => &self[id], - ExprOrPatId::PatId(id) => &self[id], - } + pub fn expr_or_pat_ty<'db>(&self, id: ExprOrPatId) -> Ty<'db> { + self.type_of_expr_or_pat(id).unwrap_or(self.error_ty.as_ref()) } -} -impl<'db> Index for InferenceResult<'db> { - type Output = Ty<'db>; - - fn index(&self, b: BindingId) -> &Ty<'db> { - self.type_of_binding.get(b).unwrap_or(&self.error_ty) + pub fn binding_ty<'db>(&self, id: BindingId) -> Ty<'db> { + self.type_of_binding.get(id).map_or(self.error_ty.as_ref(), |it| it.as_ref()) } } @@ -826,7 +802,7 @@ impl<'db> InternedStandardTypes<'db> { re_error: Region::error(interner), re_erased: Region::new_erased(interner), - empty_args: GenericArgs::new_from_iter(interner, []), + empty_args: GenericArgs::empty(interner), } } } @@ -848,7 +824,7 @@ pub(crate) struct InferenceContext<'body, 'db> { pub(crate) lang_items: &'db LangItems, /// The traits in scope, disregarding block modules. This is used for caching purposes. traits_in_scope: FxHashSet, - pub(crate) result: InferenceResult<'db>, + pub(crate) result: InferenceResult, tuple_field_accesses_rev: IndexSet, std::hash::BuildHasherDefault>, /// The return type of the function being inferred, the closure or async block if we're @@ -873,7 +849,7 @@ pub(crate) struct InferenceContext<'body, 'db> { deferred_cast_checks: Vec>, // fields related to closure capture - current_captures: Vec>, + current_captures: Vec, /// A stack that has an entry for each projection in the current capture. /// /// For example, in `a.b.c`, we capture the spans of `a`, `a.b`, and `a.b.c`. @@ -886,7 +862,7 @@ pub(crate) struct InferenceContext<'body, 'db> { closure_dependencies: FxHashMap>, deferred_closures: FxHashMap, Ty<'db>, Vec>, ExprId)>>, - diagnostics: Diagnostics<'db>, + diagnostics: Diagnostics, } #[derive(Clone, Debug)] @@ -1008,7 +984,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { /// Clones `self` and calls `resolve_all()` on it. // FIXME: Remove this. - pub(crate) fn fixme_resolve_all_clone(&self) -> InferenceResult<'db> { + pub(crate) fn fixme_resolve_all_clone(&self) -> InferenceResult { let mut ctx = self.clone(); ctx.type_inference_fallback(); @@ -1032,7 +1008,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { // `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you // used this function for another workaround, mention it here. If you really need this function and believe that // there is no problem in it being `pub(crate)`, remove this comment. - fn resolve_all(self) -> InferenceResult<'db> { + fn resolve_all(self) -> InferenceResult { let InferenceContext { mut table, mut result, tuple_field_accesses_rev, diagnostics, .. } = self; @@ -1066,23 +1042,23 @@ impl<'body, 'db> InferenceContext<'body, 'db> { } = &mut result; for ty in type_of_expr.values_mut() { - *ty = table.resolve_completely(*ty); - *has_errors = *has_errors || ty.references_non_lt_error(); + *ty = table.resolve_completely(ty.as_ref()).store(); + *has_errors = *has_errors || ty.as_ref().references_non_lt_error(); } type_of_expr.shrink_to_fit(); for ty in type_of_pat.values_mut() { - *ty = table.resolve_completely(*ty); - *has_errors = *has_errors || ty.references_non_lt_error(); + *ty = table.resolve_completely(ty.as_ref()).store(); + *has_errors = *has_errors || ty.as_ref().references_non_lt_error(); } type_of_pat.shrink_to_fit(); for ty in type_of_binding.values_mut() { - *ty = table.resolve_completely(*ty); - *has_errors = *has_errors || ty.references_non_lt_error(); + *ty = table.resolve_completely(ty.as_ref()).store(); + *has_errors = *has_errors || ty.as_ref().references_non_lt_error(); } type_of_binding.shrink_to_fit(); for ty in type_of_type_placeholder.values_mut() { - *ty = table.resolve_completely(*ty); - *has_errors = *has_errors || ty.references_non_lt_error(); + *ty = table.resolve_completely(ty.as_ref()).store(); + *has_errors = *has_errors || ty.as_ref().references_non_lt_error(); } type_of_type_placeholder.shrink_to_fit(); type_of_opaque.shrink_to_fit(); @@ -1090,8 +1066,8 @@ impl<'body, 'db> InferenceContext<'body, 'db> { if let Some(type_mismatches) = type_mismatches { *has_errors = true; for mismatch in type_mismatches.values_mut() { - mismatch.expected = table.resolve_completely(mismatch.expected); - mismatch.actual = table.resolve_completely(mismatch.actual); + mismatch.expected = table.resolve_completely(mismatch.expected.as_ref()).store(); + mismatch.actual = table.resolve_completely(mismatch.actual.as_ref()).store(); } type_mismatches.shrink_to_fit(); } @@ -1101,23 +1077,23 @@ impl<'body, 'db> InferenceContext<'body, 'db> { ExpectedFunction { found: ty, .. } | UnresolvedField { receiver: ty, .. } | UnresolvedMethodCall { receiver: ty, .. } => { - *ty = table.resolve_completely(*ty); + *ty = table.resolve_completely(ty.as_ref()).store(); // FIXME: Remove this when we are on par with rustc in terms of inference - if ty.references_non_lt_error() { + if ty.as_ref().references_non_lt_error() { return false; } if let UnresolvedMethodCall { field_with_same_name, .. } = diagnostic && let Some(ty) = field_with_same_name { - *ty = table.resolve_completely(*ty); - if ty.references_non_lt_error() { + *ty = table.resolve_completely(ty.as_ref()).store(); + if ty.as_ref().references_non_lt_error() { *field_with_same_name = None; } } } TypedHole { expected: ty, .. } => { - *ty = table.resolve_completely(*ty); + *ty = table.resolve_completely(ty.as_ref()).store(); } _ => (), } @@ -1125,30 +1101,33 @@ impl<'body, 'db> InferenceContext<'body, 'db> { }); diagnostics.shrink_to_fit(); for (_, subst) in method_resolutions.values_mut() { - *subst = table.resolve_completely(*subst); - *has_errors = *has_errors || subst.types().any(|ty| ty.references_non_lt_error()); + *subst = table.resolve_completely(subst.as_ref()).store(); + *has_errors = + *has_errors || subst.as_ref().types().any(|ty| ty.references_non_lt_error()); } method_resolutions.shrink_to_fit(); for (_, subst) in assoc_resolutions.values_mut() { - *subst = table.resolve_completely(*subst); - *has_errors = *has_errors || subst.types().any(|ty| ty.references_non_lt_error()); + *subst = table.resolve_completely(subst.as_ref()).store(); + *has_errors = + *has_errors || subst.as_ref().types().any(|ty| ty.references_non_lt_error()); } assoc_resolutions.shrink_to_fit(); for adjustment in expr_adjustments.values_mut().flatten() { - adjustment.target = table.resolve_completely(adjustment.target); - *has_errors = *has_errors || adjustment.target.references_non_lt_error(); + adjustment.target = table.resolve_completely(adjustment.target.as_ref()).store(); + *has_errors = *has_errors || adjustment.target.as_ref().references_non_lt_error(); } expr_adjustments.shrink_to_fit(); for adjustment in pat_adjustments.values_mut().flatten() { - *adjustment = table.resolve_completely(*adjustment); - *has_errors = *has_errors || adjustment.references_non_lt_error(); + *adjustment = table.resolve_completely(adjustment.as_ref()).store(); + *has_errors = *has_errors || adjustment.as_ref().references_non_lt_error(); } pat_adjustments.shrink_to_fit(); result.tuple_field_access_types = tuple_field_accesses_rev .into_iter() - .map(|subst| table.resolve_completely(subst)) + .map(|subst| table.resolve_completely(subst).store()) .inspect(|subst| { - *has_errors = *has_errors || subst.iter().any(|ty| ty.references_non_lt_error()); + *has_errors = + *has_errors || subst.as_ref().iter().any(|ty| ty.references_non_lt_error()); }) .collect(); result.tuple_field_access_types.shrink_to_fit(); @@ -1262,10 +1241,10 @@ impl<'body, 'db> InferenceContext<'body, 'db> { } fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>) { - self.result.type_of_expr.insert(expr, ty); + self.result.type_of_expr.insert(expr, ty.store()); } - pub(crate) fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment<'db>]>) { + pub(crate) fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) { if adjustments.is_empty() { return; } @@ -1278,7 +1257,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { ) => { // NeverToAny coercion can target any type, so instead of adding a new // adjustment on top we can change the target. - *target = *new_target; + *target = new_target.clone(); } _ => { *entry.get_mut() = adjustments; @@ -1291,7 +1270,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { } } - fn write_pat_adj(&mut self, pat: PatId, adjustments: Box<[Ty<'db>]>) { + fn write_pat_adj(&mut self, pat: PatId, adjustments: Box<[StoredTy]>) { if adjustments.is_empty() { return; } @@ -1304,7 +1283,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { func: FunctionId, subst: GenericArgs<'db>, ) { - self.result.method_resolutions.insert(expr, (func, subst)); + self.result.method_resolutions.insert(expr, (func, subst.store())); } fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) { @@ -1317,22 +1296,22 @@ impl<'body, 'db> InferenceContext<'body, 'db> { item: CandidateId, subs: GenericArgs<'db>, ) { - self.result.assoc_resolutions.insert(id, (item, subs)); + self.result.assoc_resolutions.insert(id, (item, subs.store())); } fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>) { - self.result.type_of_pat.insert(pat, ty); + self.result.type_of_pat.insert(pat, ty.store()); } fn write_type_placeholder_ty(&mut self, type_ref: TypeRefId, ty: Ty<'db>) { - self.result.type_of_type_placeholder.insert(type_ref, ty); + self.result.type_of_type_placeholder.insert(type_ref, ty.store()); } fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>) { - self.result.type_of_binding.insert(id, ty); + self.result.type_of_binding.insert(id, ty.store()); } - pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic<'db>) { + pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) { self.diagnostics.push(diagnostic); } @@ -1486,7 +1465,13 @@ impl<'body, 'db> InferenceContext<'body, 'db> { match ty.kind() { TyKind::Adt(adt_def, substs) => match adt_def.def_id().0 { AdtId::StructId(struct_id) => { - match self.db.field_types(struct_id.into()).values().next_back().copied() { + match self + .db + .field_types(struct_id.into()) + .values() + .next_back() + .map(|it| it.get()) + { Some(field) => { ty = field.instantiate(self.interner(), substs); } @@ -1547,7 +1532,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { self.result .type_mismatches .get_or_insert_default() - .insert(id, TypeMismatch { expected, actual }); + .insert(id, TypeMismatch { expected: expected.store(), actual: actual.store() }); } result } @@ -1592,7 +1577,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { } fn expr_ty(&self, expr: ExprId) -> Ty<'db> { - self.result[expr] + self.result.expr_ty(expr) } fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty<'db> { @@ -1600,7 +1585,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { if let Some(it) = self.result.expr_adjustments.get(&e) && let Some(it) = it.last() { - ty = Some(it.target); + ty = Some(it.target.as_ref()); } ty.unwrap_or_else(|| self.expr_ty(e)) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/autoderef.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/autoderef.rs index b54a6cdee2d4..d748c89e6775 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/autoderef.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/autoderef.rs @@ -25,7 +25,7 @@ impl<'db> InferenceTable<'db> { } impl<'db, Ctx: AutoderefCtx<'db>> GeneralAutoderef<'db, Ctx> { - pub(crate) fn adjust_steps_as_infer_ok(&mut self) -> InferOk<'db, Vec>> { + pub(crate) fn adjust_steps_as_infer_ok(&mut self) -> InferOk<'db, Vec> { let steps = self.steps(); if steps.is_empty() { return InferOk { obligations: PredicateObligations::new(), value: vec![] }; @@ -42,7 +42,10 @@ impl<'db, Ctx: AutoderefCtx<'db>> GeneralAutoderef<'db, Ctx> { } }) .zip(targets) - .map(|(autoderef, target)| Adjustment { kind: Adjust::Deref(autoderef), target }) + .map(|(autoderef, target)| Adjustment { + kind: Adjust::Deref(autoderef), + target: target.store(), + }) .collect(); InferOk { obligations: self.take_obligations(), value: steps } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs index 00a1dfff6d95..d073b06ccc8a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs @@ -4,7 +4,7 @@ use hir_def::{AdtId, hir::ExprId, signatures::TraitFlags}; use rustc_ast_ir::Mutability; use rustc_type_ir::{ Flags, InferTy, TypeFlags, UintTy, - inherent::{AdtDef, BoundExistentialPredicates as _, IntoKind, SliceLike, Ty as _}, + inherent::{AdtDef, BoundExistentialPredicates as _, IntoKind, Ty as _}, }; use stdx::never; @@ -83,8 +83,13 @@ impl CastError { expr: ExprId, expr_ty: Ty<'db>, cast_ty: Ty<'db>, - ) -> InferenceDiagnostic<'db> { - InferenceDiagnostic::InvalidCast { expr, error: self, expr_ty, cast_ty } + ) -> InferenceDiagnostic { + InferenceDiagnostic::InvalidCast { + expr, + error: self, + expr_ty: expr_ty.store(), + cast_ty: cast_ty.store(), + } } } @@ -109,7 +114,7 @@ impl<'db> CastCheck<'db> { pub(super) fn check( &mut self, ctx: &mut InferenceContext<'_, 'db>, - ) -> Result<(), InferenceDiagnostic<'db>> { + ) -> Result<(), InferenceDiagnostic> { self.expr_ty = ctx.table.try_structurally_resolve_type(self.expr_ty); self.cast_ty = ctx.table.try_structurally_resolve_type(self.cast_ty); @@ -137,7 +142,7 @@ impl<'db> CastCheck<'db> { { return Err(InferenceDiagnostic::CastToUnsized { expr: self.expr, - cast_ty: self.cast_ty, + cast_ty: self.cast_ty.store(), }); } @@ -393,8 +398,9 @@ fn pointer_kind<'db>( let struct_data = id.fields(ctx.db); if let Some((last_field, _)) = struct_data.fields().iter().last() { - let last_field_ty = - ctx.db.field_types(id.into())[last_field].instantiate(ctx.interner(), subst); + let last_field_ty = ctx.db.field_types(id.into())[last_field] + .get() + .instantiate(ctx.interner(), subst); pointer_kind(last_field_ty, ctx) } else { Ok(Some(PointerKind::Thin)) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs index 308c01865ae3..a7369d606da4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs @@ -15,7 +15,7 @@ use hir_def::{ }; use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; -use rustc_type_ir::inherent::{IntoKind, SliceLike, Ty as _}; +use rustc_type_ir::inherent::{IntoKind, Ty as _}; use smallvec::{SmallVec, smallvec}; use stdx::{format_to, never}; use syntax::utils::is_raw_identifier; @@ -25,21 +25,21 @@ use crate::{ db::{HirDatabase, InternedClosure, InternedClosureId}, infer::InferenceContext, mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem}, - next_solver::{DbInterner, EarlyBinder, GenericArgs, Ty, TyKind}, + next_solver::{DbInterner, GenericArgs, StoredEarlyBinder, StoredTy, Ty, TyKind}, traits::FnTrait, }; // The below functions handle capture and closure kind (Fn, FnMut, ..) #[derive(Debug, Clone, PartialEq, Eq, Hash, salsa::Update)] -pub(crate) struct HirPlace<'db> { +pub(crate) struct HirPlace { pub(crate) local: BindingId, - pub(crate) projections: Vec>, + pub(crate) projections: Vec>, } -impl<'db> HirPlace<'db> { - fn ty(&self, ctx: &mut InferenceContext<'_, 'db>) -> Ty<'db> { - let mut ty = ctx.table.resolve_completely(ctx.result[self.local]); +impl HirPlace { + fn ty<'db>(&self, ctx: &mut InferenceContext<'_, 'db>) -> Ty<'db> { + let mut ty = ctx.table.resolve_completely(ctx.result.binding_ty(self.local)); for p in &self.projections { ty = p.projected_ty( &ctx.table.infer_ctxt, @@ -78,8 +78,8 @@ pub enum CaptureKind { } #[derive(Debug, Clone, PartialEq, Eq, salsa::Update)] -pub struct CapturedItem<'db> { - pub(crate) place: HirPlace<'db>, +pub struct CapturedItem { + pub(crate) place: HirPlace, pub(crate) kind: CaptureKind, /// The inner vec is the stacks; the outer vec is for each capture reference. /// @@ -88,11 +88,10 @@ pub struct CapturedItem<'db> { /// copy all captures of the inner closure to the outer closure, and then we may /// truncate them, and we want the correct span to be reported. span_stacks: SmallVec<[SmallVec<[MirSpan; 3]>; 3]>, - #[update(unsafe(with(crate::utils::unsafe_update_eq)))] - pub(crate) ty: EarlyBinder<'db, Ty<'db>>, + pub(crate) ty: StoredEarlyBinder, } -impl<'db> CapturedItem<'db> { +impl CapturedItem { pub fn local(&self) -> BindingId { self.place.local } @@ -102,9 +101,9 @@ impl<'db> CapturedItem<'db> { self.place.projections.iter().any(|it| !matches!(it, ProjectionElem::Deref)) } - pub fn ty(&self, db: &'db dyn HirDatabase, subst: GenericArgs<'db>) -> Ty<'db> { + pub fn ty<'db>(&self, db: &'db dyn HirDatabase, subst: GenericArgs<'db>) -> Ty<'db> { let interner = DbInterner::new_no_crate(db); - self.ty.instantiate(interner, subst.split_closure_args_untupled().parent_args) + self.ty.get().instantiate(interner, subst.split_closure_args_untupled().parent_args) } pub fn kind(&self) -> CaptureKind { @@ -273,15 +272,15 @@ impl<'db> CapturedItem<'db> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct CapturedItemWithoutTy<'db> { - pub(crate) place: HirPlace<'db>, +pub(crate) struct CapturedItemWithoutTy { + pub(crate) place: HirPlace, pub(crate) kind: CaptureKind, /// The inner vec is the stacks; the outer vec is for each capture reference. pub(crate) span_stacks: SmallVec<[SmallVec<[MirSpan; 3]>; 3]>, } -impl<'db> CapturedItemWithoutTy<'db> { - fn with_ty(self, ctx: &mut InferenceContext<'_, 'db>) -> CapturedItem<'db> { +impl CapturedItemWithoutTy { + fn with_ty(self, ctx: &mut InferenceContext<'_, '_>) -> CapturedItem { let ty = self.place.ty(ctx); let ty = match &self.kind { CaptureKind::ByValue => ty, @@ -297,13 +296,13 @@ impl<'db> CapturedItemWithoutTy<'db> { place: self.place, kind: self.kind, span_stacks: self.span_stacks, - ty: EarlyBinder::bind(ty), + ty: StoredEarlyBinder::bind(ty.store()), } } } impl<'db> InferenceContext<'_, 'db> { - fn place_of_expr(&mut self, tgt_expr: ExprId) -> Option> { + fn place_of_expr(&mut self, tgt_expr: ExprId) -> Option { let r = self.place_of_expr_without_adjust(tgt_expr)?; let adjustments = self.result.expr_adjustments.get(&tgt_expr).map(|it| &**it).unwrap_or_default(); @@ -311,7 +310,7 @@ impl<'db> InferenceContext<'_, 'db> { } /// Pushes the span into `current_capture_span_stack`, *without clearing it first*. - fn path_place(&mut self, path: &Path, id: ExprOrPatId) -> Option> { + fn path_place(&mut self, path: &Path, id: ExprOrPatId) -> Option { if path.type_anchor().is_some() { return None; } @@ -332,7 +331,7 @@ impl<'db> InferenceContext<'_, 'db> { } /// Changes `current_capture_span_stack` to contain the stack of spans for this expr. - fn place_of_expr_without_adjust(&mut self, tgt_expr: ExprId) -> Option> { + fn place_of_expr_without_adjust(&mut self, tgt_expr: ExprId) -> Option { self.current_capture_span_stack.clear(); match &self.body[tgt_expr] { Expr::Path(p) => { @@ -367,7 +366,7 @@ impl<'db> InferenceContext<'_, 'db> { None } - fn push_capture(&mut self, place: HirPlace<'db>, kind: CaptureKind) { + fn push_capture(&mut self, place: HirPlace, kind: CaptureKind) { self.current_captures.push(CapturedItemWithoutTy { place, kind, @@ -375,11 +374,7 @@ impl<'db> InferenceContext<'_, 'db> { }); } - fn truncate_capture_spans( - &self, - capture: &mut CapturedItemWithoutTy<'db>, - mut truncate_to: usize, - ) { + fn truncate_capture_spans(&self, capture: &mut CapturedItemWithoutTy, mut truncate_to: usize) { // The first span is the identifier, and it must always remain. truncate_to += 1; for span_stack in &mut capture.span_stacks { @@ -404,14 +399,14 @@ impl<'db> InferenceContext<'_, 'db> { } } - fn ref_expr(&mut self, expr: ExprId, place: Option>) { + fn ref_expr(&mut self, expr: ExprId, place: Option) { if let Some(place) = place { self.add_capture(place, CaptureKind::ByRef(BorrowKind::Shared)); } self.walk_expr(expr); } - fn add_capture(&mut self, place: HirPlace<'db>, kind: CaptureKind) { + fn add_capture(&mut self, place: HirPlace, kind: CaptureKind) { if self.is_upvar(&place) { self.push_capture(place, kind); } @@ -427,7 +422,7 @@ impl<'db> InferenceContext<'_, 'db> { } } - fn mutate_expr(&mut self, expr: ExprId, place: Option>) { + fn mutate_expr(&mut self, expr: ExprId, place: Option) { if let Some(place) = place { self.add_capture( place, @@ -444,7 +439,7 @@ impl<'db> InferenceContext<'_, 'db> { self.walk_expr(expr); } - fn consume_place(&mut self, place: HirPlace<'db>) { + fn consume_place(&mut self, place: HirPlace) { if self.is_upvar(&place) { let ty = place.ty(self); let kind = if self.is_ty_copy(ty) { @@ -456,7 +451,7 @@ impl<'db> InferenceContext<'_, 'db> { } } - fn walk_expr_with_adjust(&mut self, tgt_expr: ExprId, adjustment: &[Adjustment<'db>]) { + fn walk_expr_with_adjust(&mut self, tgt_expr: ExprId, adjustment: &[Adjustment]) { if let Some((last, rest)) = adjustment.split_last() { match &last.kind { Adjust::NeverToAny | Adjust::Deref(None) | Adjust::Pointer(_) => { @@ -477,12 +472,7 @@ impl<'db> InferenceContext<'_, 'db> { } } - fn ref_capture_with_adjusts( - &mut self, - m: Mutability, - tgt_expr: ExprId, - rest: &[Adjustment<'db>], - ) { + fn ref_capture_with_adjusts(&mut self, m: Mutability, tgt_expr: ExprId, rest: &[Adjustment]) { let capture_kind = match m { Mutability::Mut => CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::Default }), Mutability::Not => CaptureKind::ByRef(BorrowKind::Shared), @@ -780,7 +770,7 @@ impl<'db> InferenceContext<'_, 'db> { } Pat::Bind { id, .. } => match self.result.binding_modes[p] { crate::BindingMode::Move => { - if self.is_ty_copy(self.result.type_of_binding[*id]) { + if self.is_ty_copy(self.result.binding_ty(*id)) { update_result(CaptureKind::ByRef(BorrowKind::Shared)); } else { update_result(CaptureKind::ByValue); @@ -798,7 +788,7 @@ impl<'db> InferenceContext<'_, 'db> { self.body.walk_pats_shallow(p, |p| self.walk_pat_inner(p, update_result, for_mut)); } - fn is_upvar(&self, place: &HirPlace<'db>) -> bool { + fn is_upvar(&self, place: &HirPlace) -> bool { if let Some(c) = self.current_closure { let InternedClosure(_, root) = self.db.lookup_intern_closure(c); return self.body.is_binding_upvar(place.local, root); @@ -830,7 +820,7 @@ impl<'db> InferenceContext<'_, 'db> { // FIXME: Borrow checker problems without this. let mut current_captures = std::mem::take(&mut self.current_captures); for capture in &mut current_captures { - let mut ty = self.table.resolve_completely(self.result[capture.place.local]); + let mut ty = self.table.resolve_completely(self.result.binding_ty(capture.place.local)); if ty.is_raw_ptr() || ty.is_union() { capture.kind = CaptureKind::ByRef(BorrowKind::Shared); self.truncate_capture_spans(capture, 0); @@ -875,7 +865,7 @@ impl<'db> InferenceContext<'_, 'db> { fn minimize_captures(&mut self) { self.current_captures.sort_unstable_by_key(|it| it.place.projections.len()); - let mut hash_map = FxHashMap::, usize>::default(); + let mut hash_map = FxHashMap::::default(); let result = mem::take(&mut self.current_captures); for mut item in result { let mut lookup_place = HirPlace { local: item.place.local, projections: vec![] }; @@ -910,7 +900,7 @@ impl<'db> InferenceContext<'_, 'db> { } } - fn consume_with_pat(&mut self, mut place: HirPlace<'db>, tgt_pat: PatId) { + fn consume_with_pat(&mut self, mut place: HirPlace, tgt_pat: PatId) { let adjustments_count = self.result.pat_adjustments.get(&tgt_pat).map(|it| it.len()).unwrap_or_default(); place.projections.extend((0..adjustments_count).map(|_| ProjectionElem::Deref)); @@ -921,7 +911,7 @@ impl<'db> InferenceContext<'_, 'db> { Pat::Missing | Pat::Wild => (), Pat::Tuple { args, ellipsis } => { let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize)); - let field_count = match self.result[tgt_pat].kind() { + let field_count = match self.result.pat_ty(tgt_pat).kind() { TyKind::Tuple(s) => s.len(), _ => break 'reset_span_stack, }; @@ -1221,11 +1211,11 @@ impl<'db> InferenceContext<'_, 'db> { } /// Call this only when the last span in the stack isn't a split. -fn apply_adjusts_to_place<'db>( +fn apply_adjusts_to_place( current_capture_span_stack: &mut Vec, - mut r: HirPlace<'db>, - adjustments: &[Adjustment<'db>], -) -> Option> { + mut r: HirPlace, + adjustments: &[Adjustment], +) -> Option { let span = *current_capture_span_stack.last().expect("empty capture span stack"); for adj in adjustments { match &adj.kind { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs index 77c7155550da..1233543c40f5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs @@ -104,7 +104,7 @@ struct Coerce { cause: ObligationCause, } -type CoerceResult<'db> = InferResult<'db, (Vec>, Ty<'db>)>; +type CoerceResult<'db> = InferResult<'db, (Vec, Ty<'db>)>; /// Coercing a mutable reference to an immutable works, while /// coercing `&T` to `&mut T` should be forbidden. @@ -114,7 +114,7 @@ fn coerce_mutbls<'db>(from_mutbl: Mutability, to_mutbl: Mutability) -> RelateRes /// This always returns `Ok(...)`. fn success<'db>( - adj: Vec>, + adj: Vec, target: Ty<'db>, obligations: PredicateObligations<'db>, ) -> CoerceResult<'db> { @@ -206,14 +206,17 @@ where &mut self, a: Ty<'db>, b: Ty<'db>, - adjustments: impl IntoIterator>, + adjustments: impl IntoIterator, final_adjustment: Adjust, ) -> CoerceResult<'db> { self.unify_raw(a, b).and_then(|InferOk { value: ty, obligations }| { success( adjustments .into_iter() - .chain(std::iter::once(Adjustment { target: ty, kind: final_adjustment })) + .chain(std::iter::once(Adjustment { + target: ty.store(), + kind: final_adjustment, + })) .collect(), ty, obligations, @@ -237,7 +240,7 @@ where if self.coerce_never { return success( - vec![Adjustment { kind: Adjust::NeverToAny, target: b }], + vec![Adjustment { kind: Adjust::NeverToAny, target: b.store() }], b, PredicateObligations::new(), ); @@ -532,7 +535,8 @@ where // Now apply the autoref. let mutbl = AutoBorrowMutability::new(mutbl_b, self.allow_two_phase); - adjustments.push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target: ty }); + adjustments + .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target: ty.store() }); debug!("coerce_borrowed_pointer: succeeded ty={:?} adjustments={:?}", ty, adjustments); @@ -635,10 +639,10 @@ where let mutbl = AutoBorrowMutability::new(mutbl_b, AllowTwoPhase::No); Some(( - Adjustment { kind: Adjust::Deref(None), target: ty_a }, + Adjustment { kind: Adjust::Deref(None), target: ty_a.store() }, Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), - target: Ty::new_ref(self.interner(), r_borrow, ty_a, mutbl_b), + target: Ty::new_ref(self.interner(), r_borrow, ty_a, mutbl_b).store(), }, )) } @@ -646,16 +650,16 @@ where coerce_mutbls(mt_a, mt_b)?; Some(( - Adjustment { kind: Adjust::Deref(None), target: ty_a }, + Adjustment { kind: Adjust::Deref(None), target: ty_a.store() }, Adjustment { kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b)), - target: Ty::new_ptr(self.interner(), ty_a, mt_b), + target: Ty::new_ptr(self.interner(), ty_a, mt_b).store(), }, )) } _ => None, }; - let coerce_source = reborrow.as_ref().map_or(source, |(_, r)| r.target); + let coerce_source = reborrow.as_ref().map_or(source, |(_, r)| r.target.as_ref()); // Setup either a subtyping or a LUB relationship between // the `CoerceUnsized` target type and the expected type. @@ -726,7 +730,7 @@ where Ok(None) => { if trait_pred.def_id().0 == unsize_did { let self_ty = trait_pred.self_ty(); - let unsize_ty = trait_pred.trait_ref.args.inner()[1].expect_ty(); + let unsize_ty = trait_pred.trait_ref.args[1].expect_ty(); debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_pred); match (self_ty.kind(), unsize_ty.kind()) { (TyKind::Infer(rustc_type_ir::TyVar(v)), TyKind::Dynamic(..)) @@ -815,7 +819,7 @@ where b, adjustment.map(|kind| Adjustment { kind, - target: Ty::new_fn_ptr(this.interner(), fn_ty_a), + target: Ty::new_fn_ptr(this.interner(), fn_ty_a).store(), }), Adjust::Pointer(PointerCast::UnsafeFnPointer), ) @@ -955,7 +959,7 @@ where self.unify_and( a_raw, b, - [Adjustment { kind: Adjust::Deref(None), target: mt_a.ty }], + [Adjustment { kind: Adjust::Deref(None), target: mt_a.ty.store() }], Adjust::Borrow(AutoBorrow::RawPtr(mutbl_b)), ) } else if mt_a.mutbl != mutbl_b { @@ -1170,12 +1174,15 @@ impl<'db> InferenceContext<'_, 'db> { for &expr in exprs { self.write_expr_adj( expr, - Box::new([Adjustment { kind: prev_adjustment.clone(), target: fn_ptr }]), + Box::new([Adjustment { + kind: prev_adjustment.clone(), + target: fn_ptr.store(), + }]), ); } self.write_expr_adj( new, - Box::new([Adjustment { kind: next_adjustment, target: fn_ptr }]), + Box::new([Adjustment { kind: next_adjustment, target: fn_ptr.store() }]), ); return Ok(fn_ptr); } @@ -1510,9 +1517,9 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> { icx.result.type_mismatches.get_or_insert_default().insert( expression.into(), if label_expression_as_expected { - TypeMismatch { expected: found, actual: expected } + TypeMismatch { expected: found.store(), actual: expected.store() } } else { - TypeMismatch { expected, actual: found } + TypeMismatch { expected: expected.store(), actual: found.store() } }, ); } @@ -1570,7 +1577,7 @@ fn coerce<'db>( db: &'db dyn HirDatabase, env: ParamEnvAndCrate<'db>, tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>, -) -> Result<(Vec>, Ty<'db>), TypeError>> { +) -> Result<(Vec, Ty<'db>), TypeError>> { let interner = DbInterner::new_with(db, env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let ((ty1_with_vars, ty2_with_vars), vars) = infcx.instantiate_canonical(tys); @@ -1593,7 +1600,6 @@ fn coerce<'db>( let mut ocx = ObligationCtxt::new(&infcx); let (adjustments, ty) = ocx.register_infer_ok_obligations(infer_ok); _ = ocx.try_evaluate_obligations(); - let (adjustments, ty) = infcx.resolve_vars_if_possible((adjustments, ty)); // default any type vars that weren't unified back to their original bound vars // (kind of hacky) @@ -1701,10 +1707,18 @@ fn coerce<'db>( } // FIXME: We don't fallback correctly since this is done on `InferenceContext` and we only have `InferCtxt`. - let (adjustments, ty) = (adjustments, ty).fold_with(&mut Resolver { - interner, - debruijn: DebruijnIndex::ZERO, - var_values: vars.var_values, - }); + let mut resolver = + Resolver { interner, debruijn: DebruijnIndex::ZERO, var_values: vars.var_values }; + let ty = infcx.resolve_vars_if_possible(ty).fold_with(&mut resolver); + let adjustments = adjustments + .into_iter() + .map(|adjustment| Adjustment { + kind: adjustment.kind, + target: infcx + .resolve_vars_if_possible(adjustment.target.as_ref()) + .fold_with(&mut resolver) + .store(), + }) + .collect(); Ok((adjustments, ty)) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs index 0eb7a2f4740f..2bdc6f9491dc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/diagnostics.rs @@ -25,10 +25,10 @@ use crate::{ // to our resolver and so we cannot have mutable reference, but we really want to have // ability to dispatch diagnostics during this work otherwise the code becomes a complete mess. #[derive(Debug, Default, Clone)] -pub(super) struct Diagnostics<'db>(RefCell>>); +pub(super) struct Diagnostics(RefCell>); -impl<'db> Diagnostics<'db> { - pub(super) fn push(&self, diagnostic: InferenceDiagnostic<'db>) { +impl Diagnostics { + pub(super) fn push(&self, diagnostic: InferenceDiagnostic) { self.0.borrow_mut().push(diagnostic); } @@ -42,19 +42,19 @@ impl<'db> Diagnostics<'db> { ); } - pub(super) fn finish(self) -> ThinVec> { + pub(super) fn finish(self) -> ThinVec { self.0.into_inner() } } -pub(crate) struct PathDiagnosticCallbackData<'a, 'db> { +pub(crate) struct PathDiagnosticCallbackData<'a> { node: ExprOrPatId, - diagnostics: &'a Diagnostics<'db>, + diagnostics: &'a Diagnostics, } pub(super) struct InferenceTyLoweringContext<'db, 'a> { ctx: TyLoweringContext<'db, 'a>, - diagnostics: &'a Diagnostics<'db>, + diagnostics: &'a Diagnostics, source: InferenceTyDiagnosticSource, } @@ -64,7 +64,7 @@ impl<'db, 'a> InferenceTyLoweringContext<'db, 'a> { db: &'db dyn HirDatabase, resolver: &'a Resolver<'db>, store: &'a ExpressionStore, - diagnostics: &'a Diagnostics<'db>, + diagnostics: &'a Diagnostics, source: InferenceTyDiagnosticSource, generic_def: GenericDefId, lifetime_elision: LifetimeElisionKind<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 4e1711e48ec4..5eeaeef9d9f6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -17,7 +17,7 @@ use hir_expand::name::Name; use rustc_ast_ir::Mutability; use rustc_type_ir::{ CoroutineArgs, CoroutineArgsParts, InferTy, Interner, - inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Ty as _}, + inherent::{AdtDef, GenericArgs as _, IntoKind, Ty as _}, }; use syntax::ast::RangeOp; use tracing::debug; @@ -35,7 +35,7 @@ use crate::{ lower::{GenericPredicates, lower_mutability}, method_resolution::{self, CandidateId, MethodCallee, MethodError}, next_solver::{ - ErrorGuaranteed, FnSig, GenericArgs, TraitRef, Ty, TyKind, TypeError, + ErrorGuaranteed, FnSig, GenericArg, GenericArgs, TraitRef, Ty, TyKind, TypeError, infer::{ BoundRegionConversionTime, InferOk, traits::{Obligation, ObligationCause}, @@ -68,10 +68,10 @@ impl<'db> InferenceContext<'_, 'db> { if let Some(expected_ty) = expected.only_has_type(&mut self.table) { let could_unify = self.unify(ty, expected_ty); if !could_unify { - self.result - .type_mismatches - .get_or_insert_default() - .insert(tgt_expr.into(), TypeMismatch { expected: expected_ty, actual: ty }); + self.result.type_mismatches.get_or_insert_default().insert( + tgt_expr.into(), + TypeMismatch { expected: expected_ty.store(), actual: ty.store() }, + ); } } ty @@ -98,10 +98,10 @@ impl<'db> InferenceContext<'_, 'db> { match self.coerce(expr.into(), ty, target, AllowTwoPhase::No, is_read) { Ok(res) => res, Err(_) => { - self.result - .type_mismatches - .get_or_insert_default() - .insert(expr.into(), TypeMismatch { expected: target, actual: ty }); + self.result.type_mismatches.get_or_insert_default().insert( + expr.into(), + TypeMismatch { expected: target.store(), actual: ty.store() }, + ); target } } @@ -276,7 +276,7 @@ impl<'db> InferenceContext<'_, 'db> { if ty.is_never() { if let Some(adjustments) = self.result.expr_adjustments.get(&expr) { return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &**adjustments { - *target + target.as_ref() } else { self.err_ty() }; @@ -292,10 +292,10 @@ impl<'db> InferenceContext<'_, 'db> { if let Some(expected_ty) = expected.only_has_type(&mut self.table) { let could_unify = self.unify(ty, expected_ty); if !could_unify { - self.result - .type_mismatches - .get_or_insert_default() - .insert(expr.into(), TypeMismatch { expected: expected_ty, actual: ty }); + self.result.type_mismatches.get_or_insert_default().insert( + expr.into(), + TypeMismatch { expected: expected_ty.store(), actual: ty.store() }, + ); } } ty @@ -637,7 +637,7 @@ impl<'db> InferenceContext<'_, 'db> { } }; let field_ty = field_def.map_or(self.err_ty(), |it| { - field_types[it].instantiate(self.interner(), &substs) + field_types[it].get().instantiate(self.interner(), &substs) }); // Field type might have some unknown types @@ -780,7 +780,7 @@ impl<'db> InferenceContext<'_, 'db> { Ty::new_adt( self.interner(), adt, - GenericArgs::new_from_iter(self.interner(), [ty.into()]), + GenericArgs::new_from_iter(self.interner(), [GenericArg::from(ty)]), ) }; match (range_type, lhs_ty, rhs_ty) { @@ -947,7 +947,10 @@ impl<'db> InferenceContext<'_, 'db> { // Underscore expression is an error, we render a specialized diagnostic // to let the user know what type is expected though. let expected = expected.to_option(&mut self.table).unwrap_or_else(|| self.err_ty()); - self.push_diagnostic(InferenceDiagnostic::TypedHole { expr: tgt_expr, expected }); + self.push_diagnostic(InferenceDiagnostic::TypedHole { + expr: tgt_expr, + expected: expected.store(), + }); expected } Expr::OffsetOf(_) => self.types.usize, @@ -1183,10 +1186,10 @@ impl<'db> InferenceContext<'_, 'db> { match this.coerce(tgt_expr.into(), ty, target, AllowTwoPhase::No, ExprIsRead::Yes) { Ok(res) => res, Err(_) => { - this.result - .type_mismatches - .get_or_insert_default() - .insert(tgt_expr.into(), TypeMismatch { expected: target, actual: ty }); + this.result.type_mismatches.get_or_insert_default().insert( + tgt_expr.into(), + TypeMismatch { expected: target.store(), actual: ty.store() }, + ); target } } @@ -1234,7 +1237,7 @@ impl<'db> InferenceContext<'_, 'db> { &mut self, fn_x: FnTrait, derefed_callee: Ty<'db>, - adjustments: &mut Vec>, + adjustments: &mut Vec, callee_ty: Ty<'db>, params: &[Ty<'db>], tgt_expr: ExprId, @@ -1249,7 +1252,8 @@ impl<'db> InferenceContext<'_, 'db> { .unwrap_or(true) { // prefer reborrow to move - adjustments.push(Adjustment { kind: Adjust::Deref(None), target: inner }); + adjustments + .push(Adjustment { kind: Adjust::Deref(None), target: inner.store() }); adjustments.push(Adjustment::borrow( self.interner(), Mutability::Mut, @@ -1282,13 +1286,10 @@ impl<'db> InferenceContext<'_, 'db> { }; let trait_data = trait_.trait_items(self.db); if let Some(func) = trait_data.method_by_name(&fn_x.method_name()) { - let subst = GenericArgs::new_from_iter( - self.interner(), - [ - callee_ty.into(), - Ty::new_tup_from_iter(self.interner(), params.iter().copied()).into(), - ], - ); + let subst = GenericArgs::new_from_slice(&[ + callee_ty.into(), + Ty::new_tup(self.interner(), params).into(), + ]); self.write_method_resolution(tgt_expr, func, subst); } } @@ -1549,7 +1550,10 @@ impl<'db> InferenceContext<'_, 'db> { { this.result.type_mismatches.get_or_insert_default().insert( expr.into(), - TypeMismatch { expected: t, actual: this.types.unit }, + TypeMismatch { + expected: t.store(), + actual: this.types.unit.store(), + }, ); } t @@ -1567,7 +1571,7 @@ impl<'db> InferenceContext<'_, 'db> { &mut self, receiver_ty: Ty<'db>, name: &Name, - ) -> Option<(Ty<'db>, Either, Vec>, bool)> { + ) -> Option<(Ty<'db>, Either, Vec, bool)> { let interner = self.interner(); let mut autoderef = self.table.autoderef_with_tracking(receiver_ty); let mut private_field = None; @@ -1612,6 +1616,7 @@ impl<'db> InferenceContext<'_, 'db> { return None; } let ty = self.db.field_types(field_id.parent)[field_id.local_id] + .get() .instantiate(interner, parameters); Some((Either::Left(field_id), ty)) }); @@ -1629,6 +1634,7 @@ impl<'db> InferenceContext<'_, 'db> { let adjustments = self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok()); let ty = self.db.field_types(field_id.parent)[field_id.local_id] + .get() .instantiate(self.interner(), subst); let ty = self.process_remote_user_written_ty(ty); @@ -1679,7 +1685,7 @@ impl<'db> InferenceContext<'_, 'db> { ); self.push_diagnostic(InferenceDiagnostic::UnresolvedField { expr: tgt_expr, - receiver: receiver_ty, + receiver: receiver_ty.store(), name: name.clone(), method_with_same_name_exists: resolved.is_ok(), }); @@ -1755,7 +1761,7 @@ impl<'db> InferenceContext<'_, 'db> { None => { self.push_diagnostic(InferenceDiagnostic::ExpectedFunction { call_expr: tgt_expr, - found: callee_ty, + found: callee_ty.store(), }); (Vec::new(), Ty::new_error(interner, ErrorGuaranteed)) } @@ -1867,9 +1873,9 @@ impl<'db> InferenceContext<'_, 'db> { self.push_diagnostic(InferenceDiagnostic::UnresolvedMethodCall { expr: tgt_expr, - receiver: receiver_ty, + receiver: receiver_ty.store(), name: method_name.clone(), - field_with_same_name: field_with_same_name_exists, + field_with_same_name: field_with_same_name_exists.map(|it| it.store()), assoc_func_with_same_name: assoc_func_with_same_name.map(|it| it.def_id), }); @@ -2115,10 +2121,10 @@ impl<'db> InferenceContext<'_, 'db> { && args_count_matches { // Don't report type mismatches if there is a mismatch in args count. - self.result - .type_mismatches - .get_or_insert_default() - .insert((*arg).into(), TypeMismatch { expected, actual: found }); + self.result.type_mismatches.get_or_insert_default().insert( + (*arg).into(), + TypeMismatch { expected: expected.store(), actual: found.store() }, + ); } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs index 87dcaa8a4ea8..729ed214daea 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs @@ -26,8 +26,8 @@ impl<'db> InferenceContext<'_, 'db> { Adjust::Deref(Some(d)) => { if mutability == Mutability::Mut { let source_ty = match adjustments.peek() { - Some(prev_adj) => prev_adj.target, - None => self.result.type_of_expr[tgt_expr], + Some(prev_adj) => prev_adj.target.as_ref(), + None => self.result.type_of_expr[tgt_expr].as_ref(), }; if let Some(infer_ok) = Self::try_mutable_overloaded_place_op( &self.table, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/op.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/op.rs index 8236de167f73..c61b6c9ae53d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/op.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/op.rs @@ -213,7 +213,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { let mutbl = AutoBorrowMutability::new(mutbl, AllowTwoPhase::Yes); let autoref = Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), - target: method.sig.inputs_and_output.inputs()[0], + target: method.sig.inputs_and_output.inputs()[0].store(), }; self.write_expr_adj(lhs_expr, Box::new([autoref])); } @@ -227,7 +227,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { let autoref = Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), - target: method.sig.inputs_and_output.inputs()[1], + target: method.sig.inputs_and_output.inputs()[1].store(), }; // HACK(eddyb) Bypass checks due to reborrows being in // some cases applied on the RHS, on top of which we need diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/opaques.rs index ce4597f83d55..1c722897f47b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/opaques.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/opaques.rs @@ -112,12 +112,12 @@ impl<'db> InferenceContext<'_, 'db> { _ = self.demand_eqtype_fixme_no_diag(expected, hidden_type.ty); } - self.result.type_of_opaque.insert(def_id, ty.ty); + self.result.type_of_opaque.insert(def_id, ty.ty.store()); continue; } - self.result.type_of_opaque.insert(def_id, self.types.error); + self.result.type_of_opaque.insert(def_id, self.types.error.store()); } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs index a02e280ac637..5eddd4102ba7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs @@ -9,7 +9,7 @@ use hir_def::{ }; use hir_expand::name::Name; use rustc_ast_ir::Mutability; -use rustc_type_ir::inherent::{GenericArg as _, GenericArgs as _, IntoKind, SliceLike, Ty as _}; +use rustc_type_ir::inherent::{GenericArg as _, GenericArgs as _, IntoKind, Ty as _}; use stdx::TupleExt; use crate::{ @@ -82,7 +82,7 @@ impl<'db> InferenceContext<'_, 'db> { { // FIXME(DIAGNOSE): private tuple field } - let f = field_types[local_id]; + let f = field_types[local_id].get(); let expected_ty = match substs { Some(substs) => f.instantiate(self.interner(), substs), None => f.instantiate(self.interner(), &[]), @@ -146,7 +146,7 @@ impl<'db> InferenceContext<'_, 'db> { variant: def, }); } - let f = field_types[local_id]; + let f = field_types[local_id].get(); let expected_ty = match substs { Some(substs) => f.instantiate(self.interner(), substs), None => f.instantiate(self.interner(), &[]), @@ -270,7 +270,7 @@ impl<'db> InferenceContext<'_, 'db> { } else if self.is_non_ref_pat(self.body, pat) { let mut pat_adjustments = Vec::new(); while let TyKind::Ref(_lifetime, inner, mutability) = expected.kind() { - pat_adjustments.push(expected); + pat_adjustments.push(expected.store()); expected = self.table.try_structurally_resolve_type(inner); default_bm = match default_bm { BindingMode::Move => BindingMode::Ref(mutability), @@ -333,7 +333,10 @@ impl<'db> InferenceContext<'_, 'db> { Err(_) => { self.result.type_mismatches.get_or_insert_default().insert( pat.into(), - TypeMismatch { expected, actual: ty_inserted_vars }, + TypeMismatch { + expected: expected.store(), + actual: ty_inserted_vars.store(), + }, ); self.write_pat_ty(pat, ty); // We return `expected` to prevent cascading errors. I guess an alternative is to @@ -413,10 +416,10 @@ impl<'db> InferenceContext<'_, 'db> { ) { Ok(ty) => ty, Err(_) => { - self.result - .type_mismatches - .get_or_insert_default() - .insert(pat.into(), TypeMismatch { expected, actual: lhs_ty }); + self.result.type_mismatches.get_or_insert_default().insert( + pat.into(), + TypeMismatch { expected: expected.store(), actual: lhs_ty.store() }, + ); // `rhs_ty` is returned so no further type mismatches are // reported because of this mismatch. expected @@ -432,22 +435,22 @@ impl<'db> InferenceContext<'_, 'db> { let ty = self.insert_type_vars_shallow(ty); // FIXME: This never check is odd, but required with out we do inference right now if !expected.is_never() && !self.unify(ty, expected) { - self.result - .type_mismatches - .get_or_insert_default() - .insert(pat.into(), TypeMismatch { expected, actual: ty }); + self.result.type_mismatches.get_or_insert_default().insert( + pat.into(), + TypeMismatch { expected: expected.store(), actual: ty.store() }, + ); } self.write_pat_ty(pat, ty); self.pat_ty_after_adjustment(pat) } fn pat_ty_after_adjustment(&self, pat: PatId) -> Ty<'db> { - *self - .result + self.result .pat_adjustments .get(&pat) .and_then(|it| it.last()) - .unwrap_or(&self.result.type_of_pat[pat]) + .unwrap_or_else(|| &self.result.type_of_pat[pat]) + .as_ref() } fn infer_ref_pat( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 301cbf462ce0..a323952494c0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -64,7 +64,7 @@ impl<'db> InferenceContext<'_, 'db> { } ValueNs::LocalBinding(pat) => { return match self.result.type_of_binding.get(pat) { - Some(ty) => Some(ValuePathResolution::NonGeneric(*ty)), + Some(ty) => Some(ValuePathResolution::NonGeneric(ty.as_ref())), None => { never!("uninferred pattern?"); None diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/place_op.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/place_op.rs index 3ef5e5870a58..5bcae21aa11b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/place_op.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/place_op.rs @@ -65,7 +65,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { oprnd_expr, Box::new([Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)), - target: method.sig.inputs_and_output.inputs()[0], + target: method.sig.inputs_and_output.inputs()[0].store(), }]), ); } else { @@ -151,7 +151,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> { { adjustments.push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)), - target: Ty::new_imm_ref(autoderef.ctx().interner(), region, adjusted_ty), + target: Ty::new_imm_ref(autoderef.ctx().interner(), region, adjusted_ty) + .store(), }); } else { panic!("input to index is not a ref?"); @@ -159,7 +160,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { if unsize { adjustments.push(Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), - target: method.sig.inputs_and_output.inputs()[0], + target: method.sig.inputs_and_output.inputs()[0].store(), }); } autoderef.ctx().write_expr_adj(base_expr, adjustments.into_boxed_slice()); @@ -283,7 +284,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { None => return, }; debug!("convert_place_op_to_mutable: method={:?}", method); - self.result.method_resolutions.insert(expr, (method.def_id, method.args)); + self.result.method_resolutions.insert(expr, (method.def_id, method.args.store())); let TyKind::Ref(region, _, Mutability::Mut) = method.sig.inputs_and_output.inputs()[0].kind() @@ -308,9 +309,9 @@ impl<'a, 'db> InferenceContext<'a, 'db> { allow_two_phase_borrow: AllowTwoPhase::No, }; adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(mutbl)); - adjustment.target = Ty::new_ref(interner, region, source, mutbl.into()); + adjustment.target = Ty::new_ref(interner, region, source, mutbl.into()).store(); } - source = adjustment.target; + source = adjustment.target.as_ref(); } // If we have an autoref followed by unsizing at the end, fix the unsize target. @@ -320,7 +321,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), ref mut target }, ] = adjustments[..] { - *target = method.sig.inputs_and_output.inputs()[0]; + *target = method.sig.inputs_and_output.inputs()[0].store(); } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index a5060416a16e..ac84797f37a9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -9,7 +9,7 @@ use intern::sym; use rustc_hash::FxHashSet; use rustc_type_ir::{ TyVid, TypeFoldable, TypeVisitableExt, UpcastFrom, - inherent::{Const as _, GenericArg as _, IntoKind, SliceLike, Ty as _}, + inherent::{Const as _, GenericArg as _, IntoKind, Ty as _}, solve::Certainty, }; use smallvec::SmallVec; @@ -640,6 +640,7 @@ impl<'db> InferenceTable<'db> { let struct_data = id.fields(self.db); if let Some((last_field, _)) = struct_data.fields().iter().next_back() { let last_field_ty = self.db.field_types(id.into())[last_field] + .get() .instantiate(self.interner(), subst); if structs.contains(&ty) { // A struct recursively contains itself as a tail field somewhere. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs index 075a7066db78..402e9ce96971 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs @@ -154,7 +154,7 @@ impl<'a, 'db> UninhabitedFrom<'a, 'db> { let field_vis = if is_enum { None } else { Some(self.db().field_visibilities(variant)) }; for (fid, _) in fields.iter() { - self.visit_field(field_vis.as_ref().map(|it| it[fid]), &field_tys[fid], subst)?; + self.visit_field(field_vis.as_ref().map(|it| it[fid]), &field_tys[fid].get(), subst)?; } CONTINUE_OPAQUELY_INHABITED } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 1ed604865b00..b6ad3624ae28 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -14,10 +14,7 @@ use rustc_abi::{ TargetDataLayout, WrappingRange, }; use rustc_index::IndexVec; -use rustc_type_ir::{ - FloatTy, IntTy, UintTy, - inherent::{IntoKind, SliceLike}, -}; +use rustc_type_ir::{FloatTy, IntTy, UintTy, inherent::IntoKind}; use triomphe::Arc; use crate::{ @@ -25,9 +22,10 @@ use crate::{ consteval::try_const_usize, db::HirDatabase, next_solver::{ - DbInterner, GenericArgs, Ty, TyKind, TypingMode, + DbInterner, GenericArgs, StoredTy, Ty, TyKind, TypingMode, infer::{DbInternerInferExt, traits::ObligationCause}, }, + traits::StoredParamEnvAndCrate, }; pub(crate) use self::adt::layout_of_adt_cycle_result; @@ -144,22 +142,22 @@ fn layout_of_simd_ty<'db>( let Some(TyKind::Array(e_ty, e_len)) = fields .next() .filter(|_| fields.next().is_none()) - .map(|f| (*f.1).instantiate(DbInterner::new_no_crate(db), args).kind()) + .map(|f| (*f.1).get().instantiate(DbInterner::new_no_crate(db), args).kind()) else { return Err(LayoutError::InvalidSimdType); }; let e_len = try_const_usize(db, e_len).ok_or(LayoutError::HasErrorConst)? as u64; - let e_ly = db.layout_of_ty(e_ty, env)?; + let e_ly = db.layout_of_ty(e_ty.store(), env.store())?; let cx = LayoutCx::new(dl); Ok(Arc::new(cx.calc.simd_type(e_ly, e_len, repr_packed)?)) } -pub fn layout_of_ty_query<'db>( - db: &'db dyn HirDatabase, - ty: Ty<'db>, - trait_env: ParamEnvAndCrate<'db>, +pub fn layout_of_ty_query( + db: &dyn HirDatabase, + ty: StoredTy, + trait_env: StoredParamEnvAndCrate, ) -> Result, LayoutError> { let krate = trait_env.krate; let interner = DbInterner::new_with(db, krate); @@ -170,19 +168,29 @@ pub fn layout_of_ty_query<'db>( let cx = LayoutCx::new(dl); let infer_ctxt = interner.infer_ctxt().build(TypingMode::PostAnalysis); let cause = ObligationCause::dummy(); - let ty = infer_ctxt.at(&cause, trait_env.param_env).deeply_normalize(ty).unwrap_or(ty); + let ty = infer_ctxt + .at(&cause, trait_env.param_env()) + .deeply_normalize(ty.as_ref()) + .unwrap_or(ty.as_ref()); let result = match ty.kind() { TyKind::Adt(def, args) => { match def.inner().id { hir_def::AdtId::StructId(s) => { let repr = AttrFlags::repr(db, s.into()).unwrap_or_default(); if repr.simd() { - return layout_of_simd_ty(db, s, repr.packed(), &args, trait_env, &target); + return layout_of_simd_ty( + db, + s, + repr.packed(), + &args, + trait_env.as_ref(), + &target, + ); } } _ => {} } - return db.layout_of_adt(def.inner().id, args, trait_env); + return db.layout_of_adt(def.inner().id, args.store(), trait_env); } TyKind::Bool => Layout::scalar( dl, @@ -246,21 +254,23 @@ pub fn layout_of_ty_query<'db>( ), TyKind::Tuple(tys) => { let kind = - if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; + if tys.is_empty() { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; - let fields = - tys.iter().map(|k| db.layout_of_ty(k, trait_env)).collect::, _>>()?; + let fields = tys + .iter() + .map(|k| db.layout_of_ty(k.store(), trait_env.clone())) + .collect::, _>>()?; let fields = fields.iter().map(|it| &**it).collect::>(); let fields = fields.iter().collect::>(); cx.calc.univariant(&fields, &ReprOptions::default(), kind)? } TyKind::Array(element, count) => { let count = try_const_usize(db, count).ok_or(LayoutError::HasErrorConst)? as u64; - let element = db.layout_of_ty(element, trait_env)?; + let element = db.layout_of_ty(element.store(), trait_env)?; cx.calc.array_like::<_, _, ()>(&element, Some(count))? } TyKind::Slice(element) => { - let element = db.layout_of_ty(element, trait_env)?; + let element = db.layout_of_ty(element.store(), trait_env)?; cx.calc.array_like::<_, _, ()>(&element, None)? } TyKind::Str => { @@ -325,9 +335,11 @@ pub fn layout_of_ty_query<'db>( let fields = captures .iter() .map(|it| { - let ty = - it.ty.instantiate(interner, args.split_closure_args_untupled().parent_args); - db.layout_of_ty(ty, trait_env) + let ty = it + .ty + .get() + .instantiate(interner, args.split_closure_args_untupled().parent_args); + db.layout_of_ty(ty.store(), trait_env.clone()) }) .collect::, _>>()?; let fields = fields.iter().map(|it| &**it).collect::>(); @@ -357,11 +369,11 @@ pub fn layout_of_ty_query<'db>( Ok(Arc::new(result)) } -pub(crate) fn layout_of_ty_cycle_result<'db>( +pub(crate) fn layout_of_ty_cycle_result( _: &dyn HirDatabase, _: salsa::Id, - _: Ty<'db>, - _: ParamEnvAndCrate<'db>, + _: StoredTy, + _: StoredParamEnvAndCrate, ) -> Result, LayoutError> { Err(LayoutError::RecursiveTypeWithoutIndirection) } @@ -377,7 +389,7 @@ fn struct_tail_erasing_lifetimes<'a>(db: &'a dyn HirDatabase, pointee: Ty<'a>) - let mut it = data.fields().iter().rev(); match it.next() { Some((f, _)) => { - let last_field_ty = field_ty(db, struct_id.into(), f, &args); + let last_field_ty = field_ty(db, struct_id.into(), f, args); struct_tail_erasing_lifetimes(db, last_field_ty) } None => pointee, @@ -398,9 +410,9 @@ fn field_ty<'a>( db: &'a dyn HirDatabase, def: hir_def::VariantId, fd: LocalFieldId, - args: &GenericArgs<'a>, + args: GenericArgs<'a>, ) -> Ty<'a> { - db.field_types(def)[fd].instantiate(DbInterner::new_no_crate(db), args) + db.field_types(def)[fd].get().instantiate(DbInterner::new_no_crate(db), args) } fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs index 1e2c3aa31b8d..d2495917187e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs @@ -13,17 +13,17 @@ use smallvec::SmallVec; use triomphe::Arc; use crate::{ - ParamEnvAndCrate, db::HirDatabase, layout::{Layout, LayoutCx, LayoutError, field_ty}, - next_solver::GenericArgs, + next_solver::StoredGenericArgs, + traits::StoredParamEnvAndCrate, }; -pub fn layout_of_adt_query<'db>( - db: &'db dyn HirDatabase, +pub fn layout_of_adt_query( + db: &dyn HirDatabase, def: AdtId, - args: GenericArgs<'db>, - trait_env: ParamEnvAndCrate<'db>, + args: StoredGenericArgs, + trait_env: StoredParamEnvAndCrate, ) -> Result, LayoutError> { let krate = trait_env.krate; let Ok(target) = db.target_data_layout(krate) else { @@ -34,7 +34,9 @@ pub fn layout_of_adt_query<'db>( let handle_variant = |def: VariantId, var: &VariantFields| { var.fields() .iter() - .map(|(fd, _)| db.layout_of_ty(field_ty(db, def, fd, &args), trait_env)) + .map(|(fd, _)| { + db.layout_of_ty(field_ty(db, def, fd, args.as_ref()).store(), trait_env.clone()) + }) .collect::, _>>() }; let (variants, repr, is_special_no_niche) = match def { @@ -95,12 +97,12 @@ pub fn layout_of_adt_query<'db>( Ok(Arc::new(result)) } -pub(crate) fn layout_of_adt_cycle_result<'db>( - _: &'db dyn HirDatabase, +pub(crate) fn layout_of_adt_cycle_result( + _: &dyn HirDatabase, _: salsa::Id, _def: AdtId, - _args: GenericArgs<'db>, - _trait_env: ParamEnvAndCrate<'db>, + _args: StoredGenericArgs, + _trait_env: StoredParamEnvAndCrate, ) -> Result, LayoutError> { Err(LayoutError::RecursiveTypeWithoutIndirection) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index be6a76478a11..8c91be1d7811 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs @@ -98,7 +98,7 @@ fn eval_goal( Either::Left(it) => it.krate(&db), Either::Right(it) => it.krate(&db), }; - db.layout_of_ty(goal_ty, ParamEnvAndCrate { param_env, krate }) + db.layout_of_ty(goal_ty.store(), ParamEnvAndCrate { param_env, krate }.store()) }) } @@ -140,10 +140,10 @@ fn eval_expr( .unwrap() .0; let infer = InferenceResult::for_body(&db, function_id.into()); - let goal_ty = infer.type_of_binding[b]; + let goal_ty = infer.type_of_binding[b].clone(); let param_env = db.trait_environment(function_id.into()); let krate = function_id.krate(&db); - db.layout_of_ty(goal_ty, ParamEnvAndCrate { param_env, krate }) + db.layout_of_ty(goal_ty, ParamEnvAndCrate { param_env, krate }.store()) }) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 5ebe87c5d5d6..012fd8a10abd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -61,11 +61,12 @@ use hir_def::{CallableDefId, TypeOrConstParamId, type_ref::Rawness}; use hir_expand::name::Name; use indexmap::{IndexMap, map::Entry}; use intern::{Symbol, sym}; +use macros::GenericTypeVisitable; use mir::{MirEvalError, VTableMap}; use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet}; use rustc_type_ir::{ BoundVarIndexKind, TypeSuperVisitable, TypeVisitableExt, UpcastFrom, - inherent::{IntoKind, SliceLike, Ty as _}, + inherent::{IntoKind, Ty as _}, }; use syntax::ast::{ConstArg, make}; use traits::FnTrait; @@ -104,7 +105,7 @@ pub use utils::{ /// A constant can have reference to other things. Memory map job is holding /// the necessary bits of memory of the const eval session to keep the constant /// meaningful. -#[derive(Debug, Default, Clone, PartialEq, Eq)] +#[derive(Debug, Default, Clone, PartialEq, Eq, GenericTypeVisitable)] pub enum MemoryMap<'db> { #[default] Empty, @@ -112,7 +113,7 @@ pub enum MemoryMap<'db> { Complex(Box>), } -#[derive(Debug, Default, Clone, PartialEq, Eq)] +#[derive(Debug, Default, Clone, PartialEq, Eq, GenericTypeVisitable)] pub struct ComplexMemoryMap<'db> { memory: IndexMap, FxBuildHasher>, vtable: VTableMap<'db>, @@ -134,7 +135,7 @@ impl ComplexMemoryMap<'_> { } impl<'db> MemoryMap<'db> { - pub fn vtable_ty(&self, id: usize) -> Result, MirEvalError<'db>> { + pub fn vtable_ty(&self, id: usize) -> Result, MirEvalError> { match self { MemoryMap::Empty | MemoryMap::Simple(_) => Err(MirEvalError::InvalidVTableId(id)), MemoryMap::Complex(cm) => cm.vtable.ty(id), @@ -150,8 +151,8 @@ impl<'db> MemoryMap<'db> { /// allocator function as `f` and it will return a mapping of old addresses to new addresses. fn transform_addresses( &self, - mut f: impl FnMut(&[u8], usize) -> Result>, - ) -> Result, MirEvalError<'db>> { + mut f: impl FnMut(&[u8], usize) -> Result, + ) -> Result, MirEvalError> { let mut transform = |(addr, val): (&usize, &[u8])| { let addr = *addr; let align = if addr == 0 { 64 } else { (addr - (addr & (addr - 1))).min(64) }; @@ -333,9 +334,9 @@ impl FnAbi { } #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] -pub enum ImplTraitId<'db> { - ReturnTypeImplTrait(hir_def::FunctionId, next_solver::ImplTraitIdx<'db>), - TypeAliasImplTrait(hir_def::TypeAliasId, next_solver::ImplTraitIdx<'db>), +pub enum ImplTraitId { + ReturnTypeImplTrait(hir_def::FunctionId, next_solver::ImplTraitIdx), + TypeAliasImplTrait(hir_def::TypeAliasId, next_solver::ImplTraitIdx), } /// 'Canonicalizes' the `t` by replacing any errors with new variables. Also diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 3f901ad69285..50f808affa99 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -15,8 +15,8 @@ use either::Either; use hir_def::{ AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, - LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId, - TypeParamId, UnionId, VariantId, + LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, + TypeOrConstParamId, TypeParamId, UnionId, VariantId, builtin_type::BuiltinType, expr_store::{ExpressionStore, HygieneId, path::Path}, hir::generics::{ @@ -61,36 +61,38 @@ use crate::{ AliasTy, Binder, BoundExistentialPredicates, Clause, ClauseKind, Clauses, Const, DbInterner, EarlyBinder, EarlyParamRegion, ErrorGuaranteed, FxIndexMap, GenericArg, GenericArgs, ParamConst, ParamEnv, PolyFnSig, Predicate, Region, SolverDefId, - TraitPredicate, TraitRef, Ty, Tys, UnevaluatedConst, abi::Safety, util::BottomUpFolder, + StoredClauses, StoredEarlyBinder, StoredGenericArg, StoredGenericArgs, StoredPolyFnSig, + StoredTy, TraitPredicate, TraitRef, Ty, Tys, UnevaluatedConst, abi::Safety, + util::BottomUpFolder, }, }; pub(crate) struct PathDiagnosticCallbackData(pub(crate) TypeRefId); #[derive(PartialEq, Eq, Debug, Hash)] -pub struct ImplTraits<'db> { - pub(crate) impl_traits: Arena>, +pub struct ImplTraits { + pub(crate) impl_traits: Arena, } #[derive(PartialEq, Eq, Debug, Hash)] -pub struct ImplTrait<'db> { - pub(crate) predicates: Box<[Clause<'db>]>, +pub struct ImplTrait { + pub(crate) predicates: StoredClauses, } -pub type ImplTraitIdx<'db> = Idx>; +pub type ImplTraitIdx = Idx; #[derive(Debug, Default)] -struct ImplTraitLoweringState<'db> { +struct ImplTraitLoweringState { /// When turning `impl Trait` into opaque types, we have to collect the /// bounds at the same time to get the IDs correct (without becoming too /// complicated). mode: ImplTraitLoweringMode, // This is structured as a struct with fields and not as an enum because it helps with the borrow checker. - opaque_type_data: Arena>, + opaque_type_data: Arena, } -impl<'db> ImplTraitLoweringState<'db> { - fn new(mode: ImplTraitLoweringMode) -> ImplTraitLoweringState<'db> { +impl ImplTraitLoweringState { + fn new(mode: ImplTraitLoweringMode) -> ImplTraitLoweringState { Self { mode, opaque_type_data: Arena::new() } } } @@ -174,7 +176,7 @@ pub struct TyLoweringContext<'db, 'a> { def: GenericDefId, generics: OnceCell, in_binders: DebruijnIndex, - impl_trait_mode: ImplTraitLoweringState<'db>, + impl_trait_mode: ImplTraitLoweringState, /// Tracks types with explicit `?Sized` bounds. pub(crate) unsized_types: FxHashSet>, pub(crate) diagnostics: Vec, @@ -337,7 +339,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { } } Some(ValueNs::ConstId(c)) => { - let args = GenericArgs::new_from_iter(self.interner, []); + let args = GenericArgs::empty(self.interner); Some(Const::new( self.interner, rustc_type_ir::ConstKind::Unevaluated(UnevaluatedConst::new( @@ -476,7 +478,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { let idx = self .impl_trait_mode .opaque_type_data - .alloc(ImplTrait { predicates: Box::default() }); + .alloc(ImplTrait { predicates: Clauses::empty(interner).store() }); let impl_trait_id = origin.either( |f| ImplTraitId::ReturnTypeImplTrait(f, idx), @@ -989,7 +991,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { } } - fn lower_impl_trait(&mut self, def_id: SolverDefId, bounds: &[TypeBound]) -> ImplTrait<'db> { + fn lower_impl_trait(&mut self, def_id: SolverDefId, bounds: &[TypeBound]) -> ImplTrait { let interner = self.interner; cov_mark::hit!(lower_rpit); let args = GenericArgs::identity_for_item(interner, def_id); @@ -1010,7 +1012,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { let trait_ref = TraitRef::new_from_args( interner, trait_id.into(), - GenericArgs::new_from_iter(interner, [self_ty.into()]), + GenericArgs::new_from_slice(&[self_ty.into()]), ); Clause(Predicate::new( interner, @@ -1024,9 +1026,9 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { }); predicates.extend(sized_clause); } - predicates.into_boxed_slice() + predicates }); - ImplTrait { predicates } + ImplTrait { predicates: Clauses::new_from_slice(&predicates).store() } } pub(crate) fn lower_lifetime(&mut self, lifetime: LifetimeRefId) -> Region<'db> { @@ -1090,28 +1092,50 @@ pub(crate) fn impl_trait_query<'db>( db.impl_trait_with_diagnostics(impl_id).map(|it| it.0) } -pub(crate) fn impl_trait_with_diagnostics_query<'db>( +pub(crate) fn impl_trait_with_diagnostics<'db>( db: &'db dyn HirDatabase, impl_id: ImplId, ) -> Option<(EarlyBinder<'db, TraitRef<'db>>, Diagnostics)> { - let impl_data = db.impl_signature(impl_id); - let resolver = impl_id.resolver(db); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &impl_data.store, - impl_id.into(), - LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, - ); - let self_ty = db.impl_self_ty(impl_id).skip_binder(); - let target_trait = impl_data.target_trait.as_ref()?; - let trait_ref = EarlyBinder::bind(ctx.lower_trait_ref(target_trait, self_ty)?); - Some((trait_ref, create_diagnostics(ctx.diagnostics))) + return impl_trait_with_diagnostics_query(db, impl_id).as_ref().map(|(binder, diags)| { + ( + binder.get_with(|(trait_id, args)| { + TraitRef::new_from_args( + DbInterner::new_no_crate(db), + (*trait_id).into(), + args.as_ref(), + ) + }), + diags.clone(), + ) + }); + + #[salsa::tracked(returns(ref))] + pub(crate) fn impl_trait_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + impl_id: ImplId, + ) -> Option<(StoredEarlyBinder<(TraitId, StoredGenericArgs)>, Diagnostics)> { + let impl_data = db.impl_signature(impl_id); + let resolver = impl_id.resolver(db); + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &impl_data.store, + impl_id.into(), + LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, + ); + let self_ty = db.impl_self_ty(impl_id).skip_binder(); + let target_trait = impl_data.target_trait.as_ref()?; + let trait_ref = ctx.lower_trait_ref(target_trait, self_ty)?; + Some(( + StoredEarlyBinder::bind((trait_ref.def_id.0, trait_ref.args.store())), + create_diagnostics(ctx.diagnostics), + )) + } } -impl<'db> ImplTraitId<'db> { +impl ImplTraitId { #[inline] - pub fn predicates(self, db: &'db dyn HirDatabase) -> EarlyBinder<'db, &'db [Clause<'db>]> { + pub fn predicates<'db>(self, db: &'db dyn HirDatabase) -> EarlyBinder<'db, &'db [Clause<'db>]> { let (impl_traits, idx) = match self { ImplTraitId::ReturnTypeImplTrait(owner, idx) => { (ImplTraits::return_type_impl_traits(db, owner), idx) @@ -1123,8 +1147,7 @@ impl<'db> ImplTraitId<'db> { impl_traits .as_deref() .expect("owner should have opaque type") - .as_ref() - .map_bound(|it| &*it.impl_traits[idx].predicates) + .get_with(|it| it.impl_traits[idx].predicates.as_ref().as_slice()) } } @@ -1136,12 +1159,12 @@ impl InternedOpaqueTyId { } #[salsa::tracked] -impl<'db> ImplTraits<'db> { - #[salsa::tracked(returns(ref), unsafe(non_update_types))] +impl ImplTraits { + #[salsa::tracked(returns(ref))] pub(crate) fn return_type_impl_traits( - db: &'db dyn HirDatabase, + db: &dyn HirDatabase, def: hir_def::FunctionId, - ) -> Option>>> { + ) -> Option>> { // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe let data = db.function_signature(def); let resolver = def.resolver(db); @@ -1162,15 +1185,15 @@ impl<'db> ImplTraits<'db> { None } else { return_type_impl_traits.impl_traits.shrink_to_fit(); - Some(Box::new(EarlyBinder::bind(return_type_impl_traits))) + Some(Box::new(StoredEarlyBinder::bind(return_type_impl_traits))) } } - #[salsa::tracked(returns(ref), unsafe(non_update_types))] + #[salsa::tracked(returns(ref))] pub(crate) fn type_alias_impl_traits( - db: &'db dyn HirDatabase, + db: &dyn HirDatabase, def: hir_def::TypeAliasId, - ) -> Option>>> { + ) -> Option>> { let data = db.type_alias_signature(def); let resolver = def.resolver(db); let mut ctx = TyLoweringContext::new( @@ -1190,7 +1213,7 @@ impl<'db> ImplTraits<'db> { None } else { type_alias_impl_traits.impl_traits.shrink_to_fit(); - Some(Box::new(EarlyBinder::bind(type_alias_impl_traits))) + Some(Box::new(StoredEarlyBinder::bind(type_alias_impl_traits))) } } } @@ -1246,17 +1269,20 @@ pub(crate) fn ty_query<'db>(db: &'db dyn HirDatabase, def: TyDefId) -> EarlyBind /// Build the declared type of a function. This should not need to look at the /// function body. -fn type_for_fn<'db>(db: &'db dyn HirDatabase, def: FunctionId) -> EarlyBinder<'db, Ty<'db>> { +fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder { let interner = DbInterner::new_no_crate(db); - EarlyBinder::bind(Ty::new_fn_def( - interner, - CallableDefId::FunctionId(def).into(), - GenericArgs::identity_for_item(interner, def.into()), - )) + StoredEarlyBinder::bind( + Ty::new_fn_def( + interner, + CallableDefId::FunctionId(def).into(), + GenericArgs::identity_for_item(interner, def.into()), + ) + .store(), + ) } /// Build the declared type of a const. -fn type_for_const<'db>(db: &'db dyn HirDatabase, def: ConstId) -> EarlyBinder<'db, Ty<'db>> { +fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> StoredEarlyBinder { let resolver = def.resolver(db); let data = db.const_signature(def); let parent = def.loc(db).container; @@ -1268,11 +1294,11 @@ fn type_for_const<'db>(db: &'db dyn HirDatabase, def: ConstId) -> EarlyBinder<'d LifetimeElisionKind::AnonymousReportError, ); ctx.set_lifetime_elision(LifetimeElisionKind::for_const(ctx.interner, parent)); - EarlyBinder::bind(ctx.lower_ty(data.type_ref)) + StoredEarlyBinder::bind(ctx.lower_ty(data.type_ref).store()) } /// Build the declared type of a static. -fn type_for_static<'db>(db: &'db dyn HirDatabase, def: StaticId) -> EarlyBinder<'db, Ty<'db>> { +fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> StoredEarlyBinder { let resolver = def.resolver(db); let data = db.static_signature(def); let mut ctx = TyLoweringContext::new( @@ -1283,100 +1309,129 @@ fn type_for_static<'db>(db: &'db dyn HirDatabase, def: StaticId) -> EarlyBinder< LifetimeElisionKind::AnonymousReportError, ); ctx.set_lifetime_elision(LifetimeElisionKind::Elided(Region::new_static(ctx.interner))); - EarlyBinder::bind(ctx.lower_ty(data.type_ref)) + StoredEarlyBinder::bind(ctx.lower_ty(data.type_ref).store()) } /// Build the type of a tuple struct constructor. -fn type_for_struct_constructor<'db>( - db: &'db dyn HirDatabase, +fn type_for_struct_constructor( + db: &dyn HirDatabase, def: StructId, -) -> Option>> { +) -> Option> { let struct_data = def.fields(db); match struct_data.shape { FieldsShape::Record => None, FieldsShape::Unit => Some(type_for_adt(db, def.into())), FieldsShape::Tuple => { let interner = DbInterner::new_no_crate(db); - Some(EarlyBinder::bind(Ty::new_fn_def( - interner, - CallableDefId::StructId(def).into(), - GenericArgs::identity_for_item(interner, def.into()), - ))) + Some(StoredEarlyBinder::bind( + Ty::new_fn_def( + interner, + CallableDefId::StructId(def).into(), + GenericArgs::identity_for_item(interner, def.into()), + ) + .store(), + )) } } } /// Build the type of a tuple enum variant constructor. -fn type_for_enum_variant_constructor<'db>( - db: &'db dyn HirDatabase, +fn type_for_enum_variant_constructor( + db: &dyn HirDatabase, def: EnumVariantId, -) -> Option>> { +) -> Option> { let struct_data = def.fields(db); match struct_data.shape { FieldsShape::Record => None, FieldsShape::Unit => Some(type_for_adt(db, def.loc(db).parent.into())), FieldsShape::Tuple => { let interner = DbInterner::new_no_crate(db); - Some(EarlyBinder::bind(Ty::new_fn_def( - interner, - CallableDefId::EnumVariantId(def).into(), - GenericArgs::identity_for_item(interner, def.loc(db).parent.into()), - ))) + Some(StoredEarlyBinder::bind( + Ty::new_fn_def( + interner, + CallableDefId::EnumVariantId(def).into(), + GenericArgs::identity_for_item(interner, def.loc(db).parent.into()), + ) + .store(), + )) } } } -pub(crate) fn value_ty_query<'db>( +pub(crate) fn value_ty<'db>( db: &'db dyn HirDatabase, def: ValueTyDefId, ) -> Option>> { - match def { - ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)), - ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), - ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())), - ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it), - ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)), - ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)), + return value_ty_query(db, def).as_ref().map(|it| it.get()); + + #[salsa::tracked(returns(ref))] + pub(crate) fn value_ty_query<'db>( + db: &'db dyn HirDatabase, + def: ValueTyDefId, + ) -> Option> { + match def { + ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)), + ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), + ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())), + ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it), + ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)), + ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)), + } } } -pub(crate) fn type_for_type_alias_with_diagnostics_query<'db>( +pub(crate) fn type_for_type_alias_with_diagnostics<'db>( db: &'db dyn HirDatabase, t: TypeAliasId, ) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) { - let type_alias_data = db.type_alias_signature(t); - let mut diags = None; - let resolver = t.resolver(db); - let interner = DbInterner::new_no_crate(db); - let inner = if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) { - EarlyBinder::bind(Ty::new_foreign(interner, t.into())) - } else { - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &type_alias_data.store, - t.into(), - LifetimeElisionKind::AnonymousReportError, - ) - .with_impl_trait_mode(ImplTraitLoweringMode::Opaque); - let res = EarlyBinder::bind( - type_alias_data - .ty - .map(|type_ref| ctx.lower_ty(type_ref)) - .unwrap_or_else(|| Ty::new_error(interner, ErrorGuaranteed)), - ); - diags = create_diagnostics(ctx.diagnostics); - res - }; - (inner, diags) -} + let (ty, diags) = type_for_type_alias_with_diagnostics_query(db, t); + return (ty.get(), diags.clone()); -pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result<'db>( - db: &'db dyn HirDatabase, - _: salsa::Id, - _adt: TypeAliasId, -) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) { - (EarlyBinder::bind(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)), None) + #[salsa::tracked(returns(ref), cycle_result = type_for_type_alias_with_diagnostics_cycle_result)] + pub(crate) fn type_for_type_alias_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + t: TypeAliasId, + ) -> (StoredEarlyBinder, Diagnostics) { + let type_alias_data = db.type_alias_signature(t); + let mut diags = None; + let resolver = t.resolver(db); + let interner = DbInterner::new_no_crate(db); + let inner = if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) { + StoredEarlyBinder::bind(Ty::new_foreign(interner, t.into()).store()) + } else { + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &type_alias_data.store, + t.into(), + LifetimeElisionKind::AnonymousReportError, + ) + .with_impl_trait_mode(ImplTraitLoweringMode::Opaque); + let res = StoredEarlyBinder::bind( + type_alias_data + .ty + .map(|type_ref| ctx.lower_ty(type_ref)) + .unwrap_or_else(|| Ty::new_error(interner, ErrorGuaranteed)) + .store(), + ); + diags = create_diagnostics(ctx.diagnostics); + res + }; + (inner, diags) + } + + pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, + _adt: TypeAliasId, + ) -> (StoredEarlyBinder, Diagnostics) { + ( + StoredEarlyBinder::bind( + Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed).store(), + ), + None, + ) + } } pub(crate) fn impl_self_ty_query<'db>( @@ -1386,31 +1441,45 @@ pub(crate) fn impl_self_ty_query<'db>( db.impl_self_ty_with_diagnostics(impl_id).0 } -pub(crate) fn impl_self_ty_with_diagnostics_query<'db>( +pub(crate) fn impl_self_ty_with_diagnostics<'db>( db: &'db dyn HirDatabase, impl_id: ImplId, ) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) { - let resolver = impl_id.resolver(db); + let (ty, diags) = impl_self_ty_with_diagnostics_query(db, impl_id); + return (ty.get(), diags.clone()); - let impl_data = db.impl_signature(impl_id); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &impl_data.store, - impl_id.into(), - LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, - ); - let ty = ctx.lower_ty(impl_data.self_ty); - assert!(!ty.has_escaping_bound_vars()); - (EarlyBinder::bind(ty), create_diagnostics(ctx.diagnostics)) -} + #[salsa::tracked(returns(ref), cycle_result = impl_self_ty_with_diagnostics_cycle_result)] + pub(crate) fn impl_self_ty_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + impl_id: ImplId, + ) -> (StoredEarlyBinder, Diagnostics) { + let resolver = impl_id.resolver(db); -pub(crate) fn impl_self_ty_with_diagnostics_cycle_result( - db: &dyn HirDatabase, - _: salsa::Id, - _impl_id: ImplId, -) -> (EarlyBinder<'_, Ty<'_>>, Diagnostics) { - (EarlyBinder::bind(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)), None) + let impl_data = db.impl_signature(impl_id); + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &impl_data.store, + impl_id.into(), + LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, + ); + let ty = ctx.lower_ty(impl_data.self_ty); + assert!(!ty.has_escaping_bound_vars()); + (StoredEarlyBinder::bind(ty.store()), create_diagnostics(ctx.diagnostics)) + } + + pub(crate) fn impl_self_ty_with_diagnostics_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, + _impl_id: ImplId, + ) -> (StoredEarlyBinder, Diagnostics) { + ( + StoredEarlyBinder::bind( + Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed).store(), + ), + None, + ) + } } pub(crate) fn const_param_ty_query<'db>(db: &'db dyn HirDatabase, def: ConstParamId) -> Ty<'db> { @@ -1418,57 +1487,69 @@ pub(crate) fn const_param_ty_query<'db>(db: &'db dyn HirDatabase, def: ConstPara } // returns None if def is a type arg -pub(crate) fn const_param_ty_with_diagnostics_query<'db>( +pub(crate) fn const_param_ty_with_diagnostics<'db>( db: &'db dyn HirDatabase, def: ConstParamId, ) -> (Ty<'db>, Diagnostics) { - let (parent_data, store) = db.generic_params_and_store(def.parent()); - let data = &parent_data[def.local_id()]; - let resolver = def.parent().resolver(db); - let interner = DbInterner::new_no_crate(db); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &store, - def.parent(), - LifetimeElisionKind::AnonymousReportError, - ); - let ty = match data { - TypeOrConstParamData::TypeParamData(_) => { - never!(); - Ty::new_error(interner, ErrorGuaranteed) - } - TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(d.ty), - }; - (ty, create_diagnostics(ctx.diagnostics)) + let (ty, diags) = const_param_ty_with_diagnostics_query(db, (), def); + return (ty.as_ref(), diags.clone()); + + // FIXME: Make this query non-interned. + #[salsa::tracked(returns(ref), cycle_result = const_param_ty_with_diagnostics_cycle_result)] + pub(crate) fn const_param_ty_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + _: (), + def: ConstParamId, + ) -> (StoredTy, Diagnostics) { + let (parent_data, store) = db.generic_params_and_store(def.parent()); + let data = &parent_data[def.local_id()]; + let resolver = def.parent().resolver(db); + let interner = DbInterner::new_no_crate(db); + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &store, + def.parent(), + LifetimeElisionKind::AnonymousReportError, + ); + let ty = match data { + TypeOrConstParamData::TypeParamData(_) => { + never!(); + Ty::new_error(interner, ErrorGuaranteed) + } + TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(d.ty), + }; + (ty.store(), create_diagnostics(ctx.diagnostics)) + } + + pub(crate) fn const_param_ty_with_diagnostics_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, + _: (), + _def: ConstParamId, + ) -> (StoredTy, Diagnostics) { + let interner = DbInterner::new_no_crate(db); + (Ty::new_error(interner, ErrorGuaranteed).store(), None) + } } -pub(crate) fn const_param_ty_with_diagnostics_cycle_result<'db>( - db: &'db dyn HirDatabase, - _: salsa::Id, - _: crate::db::HirDatabaseData, - _def: ConstParamId, -) -> (Ty<'db>, Diagnostics) { - let interner = DbInterner::new_no_crate(db); - (Ty::new_error(interner, ErrorGuaranteed), None) -} - -pub(crate) fn field_types_query<'db>( - db: &'db dyn HirDatabase, +pub(crate) fn field_types_query( + db: &dyn HirDatabase, variant_id: VariantId, -) -> Arc>>> { - db.field_types_with_diagnostics(variant_id).0 +) -> &ArenaMap> { + &db.field_types_with_diagnostics(variant_id).0 } /// Build the type of all specific fields of a struct or enum variant. +#[salsa::tracked(returns(ref))] pub(crate) fn field_types_with_diagnostics_query<'db>( db: &'db dyn HirDatabase, variant_id: VariantId, -) -> (Arc>>>, Diagnostics) { +) -> (ArenaMap>, Diagnostics) { let var_data = variant_id.fields(db); let fields = var_data.fields(); if fields.is_empty() { - return (Arc::new(ArenaMap::default()), None); + return (ArenaMap::default(), None); } let (resolver, def): (_, GenericDefId) = match variant_id { @@ -1485,9 +1566,9 @@ pub(crate) fn field_types_with_diagnostics_query<'db>( LifetimeElisionKind::AnonymousReportError, ); for (field_id, field_data) in var_data.fields().iter() { - res.insert(field_id, EarlyBinder::bind(ctx.lower_ty(field_data.type_ref))); + res.insert(field_id, StoredEarlyBinder::bind(ctx.lower_ty(field_data.type_ref).store())); } - (Arc::new(res), create_diagnostics(ctx.diagnostics)) + (res, create_diagnostics(ctx.diagnostics)) } /// This query exists only to be used when resolving short-hand associated types @@ -1499,13 +1580,13 @@ pub(crate) fn field_types_with_diagnostics_query<'db>( /// following bounds are disallowed: `T: Foo, U: Foo`, but /// these are fine: `T: Foo, U: Foo<()>`. #[tracing::instrument(skip(db), ret)] -#[salsa::tracked(returns(ref), unsafe(non_update_types), cycle_result = generic_predicates_for_param_cycle_result)] +#[salsa::tracked(returns(ref), cycle_result = generic_predicates_for_param_cycle_result)] pub(crate) fn generic_predicates_for_param<'db>( db: &'db dyn HirDatabase, def: GenericDefId, param_id: TypeOrConstParamId, assoc_name: Option, -) -> EarlyBinder<'db, Box<[Clause<'db>]>> { +) -> StoredEarlyBinder { let generics = generics(db, def); let interner = DbInterner::new_no_crate(db); let resolver = def.resolver(db); @@ -1607,17 +1688,17 @@ pub(crate) fn generic_predicates_for_param<'db>( predicates.extend(implicitly_sized_predicates); }; } - EarlyBinder::bind(predicates.into_boxed_slice()) + StoredEarlyBinder::bind(Clauses::new_from_slice(&predicates).store()) } -pub(crate) fn generic_predicates_for_param_cycle_result<'db>( - _db: &'db dyn HirDatabase, +pub(crate) fn generic_predicates_for_param_cycle_result( + db: &dyn HirDatabase, _: salsa::Id, _def: GenericDefId, _param_id: TypeOrConstParamId, _assoc_name: Option, -) -> EarlyBinder<'db, Box<[Clause<'db>]>> { - EarlyBinder::bind(Box::new([])) +) -> StoredEarlyBinder { + StoredEarlyBinder::bind(Clauses::empty(DbInterner::new_no_crate(db)).store()) } #[inline] @@ -1625,84 +1706,95 @@ pub(crate) fn type_alias_bounds<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, ) -> EarlyBinder<'db, &'db [Clause<'db>]> { - type_alias_bounds_with_diagnostics(db, type_alias).0.as_ref().map_bound(|it| &**it) + type_alias_bounds_with_diagnostics(db, type_alias).0.map_bound(|it| it.as_slice()) } -#[salsa::tracked(returns(ref), unsafe(non_update_types))] -pub fn type_alias_bounds_with_diagnostics<'db>( +pub(crate) fn type_alias_bounds_with_diagnostics<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, -) -> (EarlyBinder<'db, Box<[Clause<'db>]>>, Diagnostics) { - let type_alias_data = db.type_alias_signature(type_alias); - let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &type_alias_data.store, - type_alias.into(), - LifetimeElisionKind::AnonymousReportError, - ); - let interner = ctx.interner; - let def_id = type_alias.into(); +) -> (EarlyBinder<'db, Clauses<'db>>, Diagnostics) { + let (bounds, diags) = type_alias_bounds_with_diagnostics_query(db, type_alias); + return (bounds.get(), diags.clone()); - let item_args = GenericArgs::identity_for_item(interner, def_id); - let interner_ty = Ty::new_projection_from_args(interner, def_id, item_args); + #[salsa::tracked(returns(ref))] + pub fn type_alias_bounds_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + type_alias: TypeAliasId, + ) -> (StoredEarlyBinder, Diagnostics) { + let type_alias_data = db.type_alias_signature(type_alias); + let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &type_alias_data.store, + type_alias.into(), + LifetimeElisionKind::AnonymousReportError, + ); + let interner = ctx.interner; + let def_id = type_alias.into(); - let mut bounds = Vec::new(); - for bound in &type_alias_data.bounds { - ctx.lower_type_bound(bound, interner_ty, false).for_each(|pred| { - bounds.push(pred); - }); + let item_args = GenericArgs::identity_for_item(interner, def_id); + let interner_ty = Ty::new_projection_from_args(interner, def_id, item_args); + + let mut bounds = Vec::new(); + for bound in &type_alias_data.bounds { + ctx.lower_type_bound(bound, interner_ty, false).for_each(|pred| { + bounds.push(pred); + }); + } + + if !ctx.unsized_types.contains(&interner_ty) { + let sized_trait = ctx.lang_items.Sized; + if let Some(sized_trait) = sized_trait { + let trait_ref = TraitRef::new_from_args( + interner, + sized_trait.into(), + GenericArgs::new_from_slice(&[interner_ty.into()]), + ); + bounds.push(trait_ref.upcast(interner)); + }; + } + + ( + StoredEarlyBinder::bind(Clauses::new_from_slice(&bounds).store()), + create_diagnostics(ctx.diagnostics), + ) } - - if !ctx.unsized_types.contains(&interner_ty) { - let sized_trait = ctx.lang_items.Sized; - if let Some(sized_trait) = sized_trait { - let trait_ref = TraitRef::new_from_args( - interner, - sized_trait.into(), - GenericArgs::new_from_iter(interner, [interner_ty.into()]), - ); - bounds.push(trait_ref.upcast(interner)); - }; - } - - (EarlyBinder::bind(bounds.into_boxed_slice()), create_diagnostics(ctx.diagnostics)) } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct GenericPredicates<'db> { +pub struct GenericPredicates { // The order is the following: first, if `parent_is_trait == true`, comes the implicit trait predicate for the // parent. Then come the explicit predicates for the parent, then the explicit trait predicate for the child, // then the implicit trait predicate for the child, if `is_trait` is `true`. - predicates: EarlyBinder<'db, Box<[Clause<'db>]>>, + predicates: StoredEarlyBinder, own_predicates_start: u32, is_trait: bool, parent_is_trait: bool, } #[salsa::tracked] -impl<'db> GenericPredicates<'db> { +impl<'db> GenericPredicates { /// Resolve the where clause(s) of an item with generics. /// /// Diagnostics are computed only for this item's predicates, not for parents. - #[salsa::tracked(returns(ref), unsafe(non_update_types))] + #[salsa::tracked(returns(ref))] pub fn query_with_diagnostics( db: &'db dyn HirDatabase, def: GenericDefId, - ) -> (GenericPredicates<'db>, Diagnostics) { + ) -> (GenericPredicates, Diagnostics) { generic_predicates_filtered_by(db, def, PredicateFilter::All, |_| true) } } -impl<'db> GenericPredicates<'db> { +impl GenericPredicates { #[inline] - pub fn query(db: &'db dyn HirDatabase, def: GenericDefId) -> &'db GenericPredicates<'db> { + pub fn query(db: &dyn HirDatabase, def: GenericDefId) -> &GenericPredicates { &Self::query_with_diagnostics(db, def).0 } #[inline] - pub fn query_all( + pub fn query_all<'db>( db: &'db dyn HirDatabase, def: GenericDefId, ) -> EarlyBinder<'db, &'db [Clause<'db>]> { @@ -1710,7 +1802,7 @@ impl<'db> GenericPredicates<'db> { } #[inline] - pub fn query_own( + pub fn query_own<'db>( db: &'db dyn HirDatabase, def: GenericDefId, ) -> EarlyBinder<'db, &'db [Clause<'db>]> { @@ -1718,7 +1810,7 @@ impl<'db> GenericPredicates<'db> { } #[inline] - pub fn query_explicit( + pub fn query_explicit<'db>( db: &'db dyn HirDatabase, def: GenericDefId, ) -> EarlyBinder<'db, &'db [Clause<'db>]> { @@ -1726,20 +1818,20 @@ impl<'db> GenericPredicates<'db> { } #[inline] - pub fn all_predicates(&self) -> EarlyBinder<'db, &[Clause<'db>]> { - self.predicates.as_ref().map_bound(|it| &**it) + pub fn all_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { + self.predicates.get().map_bound(|it| it.as_slice()) } #[inline] - pub fn own_predicates(&self) -> EarlyBinder<'db, &[Clause<'db>]> { - self.predicates.as_ref().map_bound(|it| &it[self.own_predicates_start as usize..]) + pub fn own_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { + self.predicates.get().map_bound(|it| &it.as_slice()[self.own_predicates_start as usize..]) } /// Returns the predicates, minus the implicit `Self: Trait` predicate for a trait. #[inline] - pub fn explicit_predicates(&self) -> EarlyBinder<'db, &[Clause<'db>]> { - self.predicates.as_ref().map_bound(|it| { - &it[usize::from(self.parent_is_trait)..it.len() - usize::from(self.is_trait)] + pub fn explicit_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { + self.predicates.get().map_bound(|it| { + &it.as_slice()[usize::from(self.parent_is_trait)..it.len() - usize::from(self.is_trait)] }) } } @@ -1754,18 +1846,24 @@ pub(crate) fn trait_environment_for_body_query( db.trait_environment(def) } -pub(crate) fn trait_environment_query<'db>( - db: &'db dyn HirDatabase, - def: GenericDefId, -) -> ParamEnv<'db> { - let module = def.module(db); - let interner = DbInterner::new_with(db, module.krate(db)); - let predicates = GenericPredicates::query_all(db, def); - let clauses = rustc_type_ir::elaborate::elaborate(interner, predicates.iter_identity_copied()); - let clauses = Clauses::new_from_iter(interner, clauses); +pub(crate) fn trait_environment<'db>(db: &'db dyn HirDatabase, def: GenericDefId) -> ParamEnv<'db> { + return ParamEnv { clauses: trait_environment_query(db, def).as_ref() }; - // FIXME: We should normalize projections here, like rustc does. - ParamEnv { clauses } + #[salsa::tracked(returns(ref))] + pub(crate) fn trait_environment_query<'db>( + db: &'db dyn HirDatabase, + def: GenericDefId, + ) -> StoredClauses { + let module = def.module(db); + let interner = DbInterner::new_with(db, module.krate(db)); + let predicates = GenericPredicates::query_all(db, def); + let clauses = + rustc_type_ir::elaborate::elaborate(interner, predicates.iter_identity_copied()); + let clauses = Clauses::new_from_iter(interner, clauses); + + // FIXME: We should normalize projections here, like rustc does. + clauses.store() + } } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -1777,12 +1875,12 @@ pub(crate) enum PredicateFilter { /// Resolve the where clause(s) of an item with generics, /// with a given filter #[tracing::instrument(skip(db, filter), ret)] -pub(crate) fn generic_predicates_filtered_by<'db, F>( - db: &'db dyn HirDatabase, +pub(crate) fn generic_predicates_filtered_by( + db: &dyn HirDatabase, def: GenericDefId, predicate_filter: PredicateFilter, filter: F, -) -> (GenericPredicates<'db>, Diagnostics) +) -> (GenericPredicates, Diagnostics) where F: Fn(GenericDefId) -> bool, { @@ -1856,7 +1954,7 @@ where let trait_ref = TraitRef::new_from_args( interner, sized_trait.into(), - GenericArgs::new_from_iter(interner, [param_ty.into()]), + GenericArgs::new_from_slice(&[param_ty.into()]), ); let clause = Clause(Predicate::new( interner, @@ -1899,7 +1997,7 @@ where own_predicates_start, is_trait, parent_is_trait, - predicates: EarlyBinder::bind(predicates.into_boxed_slice()), + predicates: StoredEarlyBinder::bind(Clauses::new_from_slice(&predicates).store()), }; return (predicates, diagnostics); @@ -1988,7 +2086,7 @@ fn implicitly_sized_clauses<'a, 'subst, 'db>( let trait_ref = TraitRef::new_from_args( interner, sized_trait.into(), - GenericArgs::new_from_iter(interner, [self_ty.into()]), + GenericArgs::new_from_slice(&[self_ty.into()]), ); Clause(Predicate::new( interner, @@ -2004,19 +2102,16 @@ fn implicitly_sized_clauses<'a, 'subst, 'db>( } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct GenericDefaults<'db>(Option>>]>>); +pub struct GenericDefaults(Option>]>>); -impl<'db> GenericDefaults<'db> { +impl GenericDefaults { #[inline] - pub fn get(&self, idx: usize) -> Option>> { - self.0.as_ref()?[idx] + pub fn get<'db>(&self, idx: usize) -> Option>> { + Some(self.0.as_ref()?[idx].as_ref()?.get_with(|it| it.as_ref())) } } -pub(crate) fn generic_defaults_query( - db: &dyn HirDatabase, - def: GenericDefId, -) -> GenericDefaults<'_> { +pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) -> GenericDefaults { db.generic_defaults_with_diagnostics(def).0 } @@ -2026,7 +2121,7 @@ pub(crate) fn generic_defaults_query( pub(crate) fn generic_defaults_with_diagnostics_query( db: &dyn HirDatabase, def: GenericDefId, -) -> (GenericDefaults<'_>, Diagnostics) { +) -> (GenericDefaults, Diagnostics) { let generic_params = generics(db, def); if generic_params.is_empty() { return (GenericDefaults(None), None); @@ -2072,20 +2167,23 @@ pub(crate) fn generic_defaults_with_diagnostics_query( ctx: &mut TyLoweringContext<'db, '_>, idx: usize, p: GenericParamDataRef<'_>, - ) -> (Option>>, bool) { + ) -> (Option>, bool) { ctx.lowering_param_default(idx as u32); match p { GenericParamDataRef::TypeParamData(p) => { let ty = p.default.map(|ty| ctx.lower_ty(ty)); - (ty.map(|ty| EarlyBinder::bind(ty.into())), p.default.is_some()) + ( + ty.map(|ty| StoredEarlyBinder::bind(GenericArg::from(ty).store())), + p.default.is_some(), + ) } GenericParamDataRef::ConstParamData(p) => { let val = p.default.map(|c| { let param_ty = ctx.lower_ty(p.ty); let c = ctx.lower_const(c, param_ty); - c.into() + GenericArg::from(c).store() }); - (val.map(EarlyBinder::bind), p.default.is_some()) + (val.map(StoredEarlyBinder::bind), p.default.is_some()) } GenericParamDataRef::LifetimeParamData(_) => (None, false), } @@ -2096,26 +2194,31 @@ pub(crate) fn generic_defaults_with_diagnostics_cycle_result( _db: &dyn HirDatabase, _: salsa::Id, _def: GenericDefId, -) -> (GenericDefaults<'_>, Diagnostics) { +) -> (GenericDefaults, Diagnostics) { (GenericDefaults(None), None) } /// Build the signature of a callable item (function, struct or enum variant). -pub(crate) fn callable_item_signature_query<'db>( +pub(crate) fn callable_item_signature<'db>( db: &'db dyn HirDatabase, def: CallableDefId, ) -> EarlyBinder<'db, PolyFnSig<'db>> { - match def { - CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f), - CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s), - CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e), + return callable_item_signature_query(db, def).get_with(|sig| sig.get()); + + #[salsa::tracked(returns(ref))] + pub(crate) fn callable_item_signature_query<'db>( + db: &'db dyn HirDatabase, + def: CallableDefId, + ) -> StoredEarlyBinder { + match def { + CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f), + CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s), + CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e), + } } } -fn fn_sig_for_fn<'db>( - db: &'db dyn HirDatabase, - def: FunctionId, -) -> EarlyBinder<'db, PolyFnSig<'db>> { +fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder { let data = db.function_signature(def); let resolver = def.resolver(db); let interner = DbInterner::new_no_crate(db); @@ -2145,56 +2248,56 @@ fn fn_sig_for_fn<'db>( let inputs_and_output = Tys::new_from_iter(interner, params.chain(Some(ret))); // If/when we track late bound vars, we need to switch this to not be `dummy` - EarlyBinder::bind(rustc_type_ir::Binder::dummy(FnSig { + StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig { abi: data.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol), c_variadic: data.is_varargs(), safety: if data.is_unsafe() { Safety::Unsafe } else { Safety::Safe }, inputs_and_output, - })) + }))) } -fn type_for_adt<'db>(db: &'db dyn HirDatabase, adt: AdtId) -> EarlyBinder<'db, Ty<'db>> { +fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> StoredEarlyBinder { let interner = DbInterner::new_no_crate(db); let args = GenericArgs::identity_for_item(interner, adt.into()); let ty = Ty::new_adt(interner, adt, args); - EarlyBinder::bind(ty) + StoredEarlyBinder::bind(ty.store()) } -fn fn_sig_for_struct_constructor<'db>( - db: &'db dyn HirDatabase, +fn fn_sig_for_struct_constructor( + db: &dyn HirDatabase, def: StructId, -) -> EarlyBinder<'db, PolyFnSig<'db>> { +) -> StoredEarlyBinder { let field_tys = db.field_types(def.into()); - let params = field_tys.iter().map(|(_, ty)| ty.skip_binder()); + let params = field_tys.iter().map(|(_, ty)| ty.get().skip_binder()); let ret = type_for_adt(db, def.into()).skip_binder(); let inputs_and_output = - Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret))); - EarlyBinder::bind(Binder::dummy(FnSig { + Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret.as_ref()))); + StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig { abi: FnAbi::RustCall, c_variadic: false, safety: Safety::Safe, inputs_and_output, - })) + }))) } -fn fn_sig_for_enum_variant_constructor<'db>( - db: &'db dyn HirDatabase, +fn fn_sig_for_enum_variant_constructor( + db: &dyn HirDatabase, def: EnumVariantId, -) -> EarlyBinder<'db, PolyFnSig<'db>> { +) -> StoredEarlyBinder { let field_tys = db.field_types(def.into()); - let params = field_tys.iter().map(|(_, ty)| ty.skip_binder()); + let params = field_tys.iter().map(|(_, ty)| ty.get().skip_binder()); let parent = def.lookup(db).parent; let ret = type_for_adt(db, parent.into()).skip_binder(); let inputs_and_output = - Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret))); - EarlyBinder::bind(Binder::dummy(FnSig { + Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret.as_ref()))); + StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig { abi: FnAbi::RustCall, c_variadic: false, safety: Safety::Safe, inputs_and_output, - })) + }))) } // FIXME(next-solver): should merge this with `explicit_item_bounds` in some way @@ -2341,7 +2444,7 @@ fn named_associated_type_shorthand_candidates<'db, R>( if let Some(alias) = check_trait(trait_ref) { return Some(alias); } - for pred in generic_predicates_filtered_by( + let predicates = generic_predicates_filtered_by( db, GenericDefId::TraitId(trait_ref.def_id.0), PredicateFilter::SelfTrait, @@ -2352,9 +2455,8 @@ fn named_associated_type_shorthand_candidates<'db, R>( |pred| pred != def && pred == GenericDefId::TraitId(trait_ref.def_id.0), ) .0 - .predicates - .instantiate_identity() - { + .predicates; + for pred in predicates.get().instantiate_identity() { tracing::debug!(?pred); let sup_trait_ref = match pred.kind().skip_binder() { rustc_type_ir::ClauseKind::Trait(pred) => pred.trait_ref, @@ -2401,8 +2503,8 @@ fn named_associated_type_shorthand_candidates<'db, R>( let predicates = generic_predicates_for_param(db, def, param_id.into(), assoc_name.clone()); predicates - .as_ref() - .iter_identity_copied() + .get() + .iter_identity() .find_map(|pred| match pred.kind().skip_binder() { rustc_type_ir::ClauseKind::Trait(trait_predicate) => Some(trait_predicate), _ => None, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index fe96b6832e08..fba176bcb1ab 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs @@ -20,7 +20,7 @@ use hir_def::{ use hir_expand::name::Name; use rustc_type_ir::{ AliasTerm, AliasTy, AliasTyKind, - inherent::{GenericArgs as _, Region as _, SliceLike, Ty as _}, + inherent::{GenericArgs as _, Region as _, Ty as _}, }; use smallvec::SmallVec; use stdx::never; @@ -45,17 +45,15 @@ use super::{ const_param_ty_query, ty_query, }; -type CallbackData<'a, 'db> = Either< - PathDiagnosticCallbackData, - crate::infer::diagnostics::PathDiagnosticCallbackData<'a, 'db>, ->; +type CallbackData<'a> = + Either>; // We cannot use `&mut dyn FnMut()` because of lifetime issues, and we don't want to use `Box` // because of the allocation, so we create a lifetime-less callback, tailored for our needs. pub(crate) struct PathDiagnosticCallback<'a, 'db> { - pub(crate) data: CallbackData<'a, 'db>, + pub(crate) data: CallbackData<'a>, pub(crate) callback: - fn(&CallbackData<'_, 'db>, &mut TyLoweringContext<'db, '_>, PathLoweringDiagnostic), + fn(&CallbackData<'_>, &mut TyLoweringContext<'db, '_>, PathLoweringDiagnostic), } pub(crate) struct PathLoweringContext<'a, 'b, 'db> { @@ -555,7 +553,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { ValueTyDefId::UnionId(it) => it.into(), ValueTyDefId::ConstId(it) => it.into(), ValueTyDefId::StaticId(_) => { - return GenericArgs::new_from_iter(interner, []); + return GenericArgs::empty(interner); } ValueTyDefId::EnumVariantId(var) => { // the generic args for an enum variant may be either specified diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index d66a386bcdeb..aaa3cce4fad9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -26,7 +26,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use rustc_type_ir::{ TypeVisitableExt, fast_reject::{TreatParams, simplify_type}, - inherent::{BoundExistentialPredicates, IntoKind, SliceLike}, + inherent::{BoundExistentialPredicates, IntoKind}, }; use stdx::impl_from; use triomphe::Arc; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/confirm.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/confirm.rs index 6d6515a45782..9292928f99fc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/confirm.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/confirm.rs @@ -9,7 +9,7 @@ use hir_def::{ use rustc_type_ir::{ TypeFoldable, elaborate::elaborate, - inherent::{BoundExistentialPredicates, IntoKind, SliceLike, Ty as _}, + inherent::{BoundExistentialPredicates, IntoKind, Ty as _}, }; use tracing::debug; @@ -45,7 +45,7 @@ struct ConfirmContext<'a, 'b, 'db> { pub(crate) struct ConfirmResult<'db> { pub(crate) callee: MethodCallee<'db>, pub(crate) illegal_sized_bound: bool, - pub(crate) adjustments: Box<[Adjustment<'db>]>, + pub(crate) adjustments: Box<[Adjustment]>, } impl<'a, 'db> InferenceContext<'a, 'db> { @@ -177,7 +177,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { &mut self, unadjusted_self_ty: Ty<'db>, pick: &probe::Pick<'db>, - ) -> (Ty<'db>, Box<[Adjustment<'db>]>) { + ) -> (Ty<'db>, Box<[Adjustment]>) { // Commit the autoderefs by calling `autoderef` again, but this // time writing the results into the various typeck results. let mut autoderef = self.ctx.table.autoderef_with_tracking(unadjusted_self_ty); @@ -200,8 +200,10 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { // for two-phase borrows. let mutbl = AutoBorrowMutability::new(mutbl, AllowTwoPhase::Yes); - adjustments - .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target }); + adjustments.push(Adjustment { + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), + target: target.store(), + }); if unsize { let unsized_ty = if let TyKind::Array(elem_ty, _) = base_ty.kind() { @@ -213,8 +215,10 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { ) }; target = Ty::new_ref(self.interner(), region, unsized_ty, mutbl.into()); - adjustments - .push(Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target }); + adjustments.push(Adjustment { + kind: Adjust::Pointer(PointerCast::Unsize), + target: target.store(), + }); } } Some(probe::AutorefOrPtrAdjustment::ToConstPtr) => { @@ -228,7 +232,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { adjustments.push(Adjustment { kind: Adjust::Pointer(PointerCast::MutToConstPointer), - target, + target: target.store(), }); } None => {} @@ -482,7 +486,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { if self.ctx.unstable_features.arbitrary_self_types { self.ctx.result.type_mismatches.get_or_insert_default().insert( self.expr.into(), - TypeMismatch { expected: method_self_ty, actual: self_ty }, + TypeMismatch { expected: method_self_ty.store(), actual: self_ty.store() }, ); } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs index 9ea0d500a5f4..cdffcd9383ca 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs @@ -14,7 +14,7 @@ use rustc_type_ir::{ InferTy, TypeVisitableExt, Upcast, Variance, elaborate::{self, supertrait_def_ids}, fast_reject::{DeepRejectCtxt, TreatParams, simplify_type}, - inherent::{AdtDef as _, BoundExistentialPredicates as _, IntoKind, SliceLike, Ty as _}, + inherent::{AdtDef as _, BoundExistentialPredicates as _, IntoKind, Ty as _}, }; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs index 836c20a43348..664238601108 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs @@ -12,7 +12,7 @@ use hir_def::{ use la_arena::{Arena, ArenaMap, Idx, RawIdx}; use rustc_ast_ir::Mutability; use rustc_hash::FxHashMap; -use rustc_type_ir::inherent::{GenericArgs as _, IntoKind, SliceLike, Ty as _}; +use rustc_type_ir::inherent::{GenericArgs as _, IntoKind, Ty as _}; use smallvec::{SmallVec, smallvec}; use stdx::{impl_from, never}; @@ -23,7 +23,8 @@ use crate::{ display::{DisplayTarget, HirDisplay}, infer::PointerCast, next_solver::{ - Const, DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, Ty, TyKind, + Const, DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, StoredConst, StoredGenericArgs, + StoredTy, Ty, TyKind, infer::{InferCtxt, traits::ObligationCause}, obligation_ctxt::ObligationCtxt, }, @@ -49,16 +50,16 @@ pub(crate) use monomorphization::monomorphized_mir_body_cycle_result; use super::consteval::try_const_usize; -pub type BasicBlockId<'db> = Idx>; -pub type LocalId<'db> = Idx>; +pub type BasicBlockId = Idx; +pub type LocalId = Idx; -fn return_slot<'db>() -> LocalId<'db> { +fn return_slot() -> LocalId { LocalId::from_raw(RawIdx::from(0)) } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Local<'db> { - pub ty: Ty<'db>, +pub struct Local { + pub ty: StoredTy, } /// An operand in MIR represents a "value" in Rust, the definition of which is undecided and part of @@ -80,19 +81,19 @@ pub struct Local<'db> { /// currently implements it, but it seems like this may be something to check against in the /// validator. #[derive(Debug, PartialEq, Eq, Clone)] -pub struct Operand<'db> { - kind: OperandKind<'db>, +pub struct Operand { + kind: OperandKind, // FIXME : This should actually just be of type `MirSpan`. span: Option, } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum OperandKind<'db> { +pub enum OperandKind { /// Creates a value by loading the given place. /// /// Before drop elaboration, the type of the place must be `Copy`. After drop elaboration there /// is no such requirement. - Copy(Place<'db>), + Copy(Place), /// Creates a value by performing loading the place, just like the `Copy` operand. /// @@ -101,21 +102,21 @@ pub enum OperandKind<'db> { /// place without first re-initializing it. /// /// [UCG#188]: https://github.com/rust-lang/unsafe-code-guidelines/issues/188 - Move(Place<'db>), + Move(Place), /// Constants are already semantically values, and remain unchanged. - Constant { konst: Const<'db>, ty: Ty<'db> }, + Constant { konst: StoredConst, ty: StoredTy }, /// NON STANDARD: This kind of operand returns an immutable reference to that static memory. Rustc /// handles it with the `Constant` variant somehow. Static(StaticId), } -impl<'db> Operand<'db> { +impl<'db> Operand { fn from_concrete_const(data: Box<[u8]>, memory_map: MemoryMap<'db>, ty: Ty<'db>) -> Self { let interner = DbInterner::conjure(); Operand { kind: OperandKind::Constant { - konst: Const::new_valtree(interner, ty, data, memory_map), - ty, + konst: Const::new_valtree(interner, ty, data, memory_map).store(), + ty: ty.store(), }, span: None, } @@ -125,7 +126,7 @@ impl<'db> Operand<'db> { Operand::from_concrete_const(data, MemoryMap::default(), ty) } - fn const_zst(ty: Ty<'db>) -> Operand<'db> { + fn const_zst(ty: Ty<'db>) -> Operand { Self::from_bytes(Box::default(), ty) } @@ -133,28 +134,28 @@ impl<'db> Operand<'db> { db: &'db dyn HirDatabase, func_id: hir_def::FunctionId, generic_args: GenericArgs<'db>, - ) -> Operand<'db> { + ) -> Operand { let interner = DbInterner::new_no_crate(db); let ty = Ty::new_fn_def(interner, CallableDefId::FunctionId(func_id).into(), generic_args); Operand::from_bytes(Box::default(), ty) } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, salsa::Update)] -pub enum ProjectionElem<'db, V: PartialEq> { +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum ProjectionElem { Deref, Field(Either), // FIXME: get rid of this, and use FieldId for tuples and closures ClosureField(usize), - Index(#[update(unsafe(with(crate::utils::unsafe_update_eq)))] V), + Index(V), ConstantIndex { offset: u64, from_end: bool }, Subslice { from: u64, to: u64 }, //Downcast(Option, VariantIdx), - OpaqueCast(Ty<'db>), + OpaqueCast(StoredTy), } -impl<'db, V: PartialEq> ProjectionElem<'db, V> { - pub fn projected_ty( +impl ProjectionElem { + pub fn projected_ty<'db>( &self, infcx: &InferCtxt<'db>, env: ParamEnv<'db>, @@ -194,7 +195,7 @@ impl<'db, V: PartialEq> ProjectionElem<'db, V> { }, ProjectionElem::Field(Either::Left(f)) => match base.kind() { TyKind::Adt(_, subst) => { - db.field_types(f.parent)[f.local_id].instantiate(interner, subst) + db.field_types(f.parent)[f.local_id].get().instantiate(interner, subst) } ty => { never!("Only adt has field, found {:?}", ty); @@ -253,18 +254,18 @@ impl<'db, V: PartialEq> ProjectionElem<'db, V> { } } -type PlaceElem<'db> = ProjectionElem<'db, LocalId<'db>>; +type PlaceElem = ProjectionElem; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ProjectionId(u32); #[derive(Debug, Clone, PartialEq, Eq)] -pub struct ProjectionStore<'db> { - id_to_proj: FxHashMap]>>, - proj_to_id: FxHashMap]>, ProjectionId>, +pub struct ProjectionStore { + id_to_proj: FxHashMap>, + proj_to_id: FxHashMap, ProjectionId>, } -impl Default for ProjectionStore<'_> { +impl Default for ProjectionStore { fn default() -> Self { let mut this = Self { id_to_proj: Default::default(), proj_to_id: Default::default() }; // Ensure that [] will get the id 0 which is used in `ProjectionId::Empty` @@ -273,17 +274,17 @@ impl Default for ProjectionStore<'_> { } } -impl<'db> ProjectionStore<'db> { +impl ProjectionStore { pub fn shrink_to_fit(&mut self) { self.id_to_proj.shrink_to_fit(); self.proj_to_id.shrink_to_fit(); } - pub fn intern_if_exist(&self, projection: &[PlaceElem<'db>]) -> Option { + pub fn intern_if_exist(&self, projection: &[PlaceElem]) -> Option { self.proj_to_id.get(projection).copied() } - pub fn intern(&mut self, projection: Box<[PlaceElem<'db>]>) -> ProjectionId { + pub fn intern(&mut self, projection: Box<[PlaceElem]>) -> ProjectionId { let new_id = ProjectionId(self.proj_to_id.len() as u32); match self.proj_to_id.entry(projection) { Entry::Occupied(id) => *id.get(), @@ -304,15 +305,11 @@ impl ProjectionId { self == ProjectionId::EMPTY } - pub fn lookup<'a, 'db>(self, store: &'a ProjectionStore<'db>) -> &'a [PlaceElem<'db>] { + pub fn lookup(self, store: &ProjectionStore) -> &[PlaceElem] { store.id_to_proj.get(&self).unwrap() } - pub fn project<'db>( - self, - projection: PlaceElem<'db>, - store: &mut ProjectionStore<'db>, - ) -> ProjectionId { + pub fn project(self, projection: PlaceElem, store: &mut ProjectionStore) -> ProjectionId { let mut current = self.lookup(store).to_vec(); current.push(projection); store.intern(current.into()) @@ -320,13 +317,13 @@ impl ProjectionId { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Place<'db> { - pub local: LocalId<'db>, +pub struct Place { + pub local: LocalId, pub projection: ProjectionId, } -impl<'db> Place<'db> { - fn is_parent(&self, child: &Place<'db>, store: &ProjectionStore<'db>) -> bool { +impl Place { + fn is_parent(&self, child: &Place, store: &ProjectionStore) -> bool { self.local == child.local && child.projection.lookup(store).starts_with(self.projection.lookup(store)) } @@ -334,39 +331,39 @@ impl<'db> Place<'db> { /// The place itself is not included fn iterate_over_parents<'a>( &'a self, - store: &'a ProjectionStore<'db>, - ) -> impl Iterator> + 'a { + store: &'a ProjectionStore, + ) -> impl Iterator + 'a { let projection = self.projection.lookup(store); (0..projection.len()).map(|x| &projection[0..x]).filter_map(move |x| { Some(Place { local: self.local, projection: store.intern_if_exist(x)? }) }) } - fn project(&self, projection: PlaceElem<'db>, store: &mut ProjectionStore<'db>) -> Place<'db> { + fn project(&self, projection: PlaceElem, store: &mut ProjectionStore) -> Place { Place { local: self.local, projection: self.projection.project(projection, store) } } } -impl<'db> From> for Place<'db> { - fn from(local: LocalId<'db>) -> Self { +impl From for Place { + fn from(local: LocalId) -> Self { Self { local, projection: ProjectionId::EMPTY } } } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum AggregateKind<'db> { +pub enum AggregateKind { /// The type is of the element - Array(Ty<'db>), + Array(StoredTy), /// The type is of the tuple - Tuple(Ty<'db>), - Adt(VariantId, GenericArgs<'db>), + Tuple(StoredTy), + Adt(VariantId, StoredGenericArgs), Union(UnionId, FieldId), - Closure(Ty<'db>), + Closure(StoredTy), //Coroutine(LocalDefId, SubstsRef, Movability), } #[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct SwitchTargets<'db> { +pub struct SwitchTargets { /// Possible values. The locations to branch to in each case /// are found in the corresponding indices from the `targets` vector. values: SmallVec<[u128; 1]>, @@ -383,17 +380,17 @@ pub struct SwitchTargets<'db> { // // However we’ve decided to keep this as-is until we figure a case // where some other approach seems to be strictly better than other. - targets: SmallVec<[BasicBlockId<'db>; 2]>, + targets: SmallVec<[BasicBlockId; 2]>, } -impl<'db> SwitchTargets<'db> { +impl SwitchTargets { /// Creates switch targets from an iterator of values and target blocks. /// /// The iterator may be empty, in which case the `SwitchInt` instruction is equivalent to /// `goto otherwise;`. pub fn new( - targets: impl Iterator)>, - otherwise: BasicBlockId<'db>, + targets: impl Iterator, + otherwise: BasicBlockId, ) -> Self { let (values, mut targets): (SmallVec<_>, SmallVec<_>) = targets.unzip(); targets.push(otherwise); @@ -402,12 +399,12 @@ impl<'db> SwitchTargets<'db> { /// Builds a switch targets definition that jumps to `then` if the tested value equals `value`, /// and to `else_` if not. - pub fn static_if(value: u128, then: BasicBlockId<'db>, else_: BasicBlockId<'db>) -> Self { + pub fn static_if(value: u128, then: BasicBlockId, else_: BasicBlockId) -> Self { Self { values: smallvec![value], targets: smallvec![then, else_] } } /// Returns the fallback target that is jumped to when none of the values match the operand. - pub fn otherwise(&self) -> BasicBlockId<'db> { + pub fn otherwise(&self) -> BasicBlockId { *self.targets.last().unwrap() } @@ -417,33 +414,33 @@ impl<'db> SwitchTargets<'db> { /// including the `otherwise` fallback target. /// /// Note that this may yield 0 elements. Only the `otherwise` branch is mandatory. - pub fn iter(&self) -> impl Iterator)> + '_ { + pub fn iter(&self) -> impl Iterator + '_ { iter::zip(&self.values, &self.targets).map(|(x, y)| (*x, *y)) } /// Returns a slice with all possible jump targets (including the fallback target). - pub fn all_targets(&self) -> &[BasicBlockId<'db>] { + pub fn all_targets(&self) -> &[BasicBlockId] { &self.targets } /// Finds the `BasicBlock` to which this `SwitchInt` will branch given the /// specific value. This cannot fail, as it'll return the `otherwise` /// branch if there's not a specific match for the value. - pub fn target_for_value(&self, value: u128) -> BasicBlockId<'db> { + pub fn target_for_value(&self, value: u128) -> BasicBlockId { self.iter().find_map(|(v, t)| (v == value).then_some(t)).unwrap_or_else(|| self.otherwise()) } } #[derive(Debug, PartialEq, Eq, Clone)] -pub struct Terminator<'db> { +pub struct Terminator { pub span: MirSpan, - pub kind: TerminatorKind<'db>, + pub kind: TerminatorKind, } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum TerminatorKind<'db> { +pub enum TerminatorKind { /// Block has one successor; we continue execution there. - Goto { target: BasicBlockId<'db> }, + Goto { target: BasicBlockId }, /// Switches based on the computed value. /// @@ -455,9 +452,9 @@ pub enum TerminatorKind<'db> { /// Target values may not appear more than once. SwitchInt { /// The discriminant value being tested. - discr: Operand<'db>, + discr: Operand, - targets: SwitchTargets<'db>, + targets: SwitchTargets, }, /// Indicates that the landing pad is finished and that the process should continue unwinding. @@ -508,7 +505,7 @@ pub enum TerminatorKind<'db> { /// > The drop glue is executed if, among all statements executed within this `Body`, an assignment to /// > the place or one of its "parents" occurred more recently than a move out of it. This does not /// > consider indirect assignments. - Drop { place: Place<'db>, target: BasicBlockId<'db>, unwind: Option> }, + Drop { place: Place, target: BasicBlockId, unwind: Option }, /// Drops the place and assigns a new value to it. /// @@ -541,10 +538,10 @@ pub enum TerminatorKind<'db> { /// /// Disallowed after drop elaboration. DropAndReplace { - place: Place<'db>, - value: Operand<'db>, - target: BasicBlockId<'db>, - unwind: Option>, + place: Place, + value: Operand, + target: BasicBlockId, + unwind: Option, }, /// Roughly speaking, evaluates the `func` operand and the arguments, and starts execution of @@ -559,18 +556,18 @@ pub enum TerminatorKind<'db> { /// [#71117]: https://github.com/rust-lang/rust/issues/71117 Call { /// The function that’s being called. - func: Operand<'db>, + func: Operand, /// Arguments the function is called with. /// These are owned by the callee, which is free to modify them. /// This allows the memory occupied by "by-value" arguments to be /// reused across function calls without duplicating the contents. - args: Box<[Operand<'db>]>, + args: Box<[Operand]>, /// Where the returned value will be written - destination: Place<'db>, + destination: Place, /// Where to go after this call returns. If none, the call necessarily diverges. - target: Option>, + target: Option, /// Cleanups to be done if the call unwinds. - cleanup: Option>, + cleanup: Option, /// `true` if this is from a call in HIR rather than from an overloaded /// operator. True for overloaded function call. from_hir_call: bool, @@ -586,11 +583,11 @@ pub enum TerminatorKind<'db> { /// necessarily executed even in the case of a panic, for example in `-C panic=abort`. If the /// assertion does not fail, execution continues at the specified basic block. Assert { - cond: Operand<'db>, + cond: Operand, expected: bool, //msg: AssertMessage, - target: BasicBlockId<'db>, - cleanup: Option>, + target: BasicBlockId, + cleanup: Option, }, /// Marks a suspend point. @@ -607,13 +604,13 @@ pub enum TerminatorKind<'db> { /// **Needs clarification**: What about the evaluation order of the `resume_arg` and `value`? Yield { /// The value to return. - value: Operand<'db>, + value: Operand, /// Where to resume to. - resume: BasicBlockId<'db>, + resume: BasicBlockId, /// The place to store the resume argument in. - resume_arg: Place<'db>, + resume_arg: Place, /// Cleanup to be done if the coroutine is dropped at this suspend point. - drop: Option>, + drop: Option, }, /// Indicates the end of dropping a coroutine. @@ -636,10 +633,10 @@ pub enum TerminatorKind<'db> { /// Disallowed after drop elaboration. FalseEdge { /// The target normal control flow will take. - real_target: BasicBlockId<'db>, + real_target: BasicBlockId, /// A block control flow could conceptually jump to, but won't in /// practice. - imaginary_target: BasicBlockId<'db>, + imaginary_target: BasicBlockId, }, /// A terminator for blocks that only take one path in reality, but where we reserve the right @@ -651,14 +648,14 @@ pub enum TerminatorKind<'db> { /// Disallowed after drop elaboration. FalseUnwind { /// The target normal control flow will take. - real_target: BasicBlockId<'db>, + real_target: BasicBlockId, /// The imaginary cleanup block link. This particular path will never be taken /// in practice, but in order to avoid fragility we want to always /// consider it in borrowck. We don't want to accept programs which /// pass borrowck only when `panic=abort` or some assertions are disabled /// due to release vs. debug mode builds. This needs to be an `Option` because /// of the `remove_noop_landing_pads` and `abort_unwinding_calls` passes. - unwind: Option>, + unwind: Option, }, } @@ -845,8 +842,8 @@ impl From for BinOp { } } -impl<'db> From> for Rvalue<'db> { - fn from(x: Operand<'db>) -> Self { +impl From for Rvalue { + fn from(x: Operand) -> Self { Self::Use(x) } } @@ -875,14 +872,14 @@ pub enum CastKind { } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum Rvalue<'db> { +pub enum Rvalue { /// Yields the operand unchanged - Use(Operand<'db>), + Use(Operand), /// Creates an array where each element is the value of the operand. /// /// Corresponds to source code like `[x; 32]`. - Repeat(Operand<'db>, Const<'db>), + Repeat(Operand, StoredConst), /// Creates a reference of the indicated kind to the place. /// @@ -891,7 +888,7 @@ pub enum Rvalue<'db> { /// exactly what the behavior of this operation should be. /// /// `Shallow` borrows are disallowed after drop lowering. - Ref(BorrowKind, Place<'db>), + Ref(BorrowKind, Place), /// Creates a pointer/reference to the given thread local. /// @@ -922,7 +919,7 @@ pub enum Rvalue<'db> { /// If the type of the place is an array, this is the array length. For slices (`[T]`, not /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is /// ill-formed for places of other types. - Len(Place<'db>), + Len(Place), /// Performs essentially all of the casts that can be performed via `as`. /// @@ -930,7 +927,7 @@ pub enum Rvalue<'db> { /// /// **FIXME**: Document exactly which `CastKind`s allow which types of casts. Figure out why /// `ArrayToPointer` and `MutToConstPointer` are special. - Cast(CastKind, Operand<'db>, Ty<'db>), + Cast(CastKind, Operand, StoredTy), // FIXME link to `pointer::offset` when it hits stable. /// * `Offset` has the same semantics as `pointer::offset`, except that the second @@ -962,7 +959,7 @@ pub enum Rvalue<'db> { /// when the value of right-hand side is negative. /// /// Other combinations of types and operators are unsupported. - CheckedBinaryOp(BinOp, Operand<'db>, Operand<'db>), + CheckedBinaryOp(BinOp, Operand, Operand), /// Computes a value as described by the operation. //NullaryOp(NullOp, Ty), @@ -973,7 +970,7 @@ pub enum Rvalue<'db> { /// Also does two's-complement arithmetic. Negation requires a signed integer or a float; /// bitwise not requires a signed integer, unsigned integer, or bool. Both operation kinds /// return a value with the same type as their operand. - UnaryOp(UnOp, Operand<'db>), + UnaryOp(UnOp, Operand), /// Computes the discriminant of the place, returning it as an integer of type /// `discriminant_ty`. Returns zero for types without discriminant. @@ -983,7 +980,7 @@ pub enum Rvalue<'db> { /// variant index; use `discriminant_for_variant` to convert. /// /// [#91095]: https://github.com/rust-lang/rust/issues/91095 - Discriminant(Place<'db>), + Discriminant(Place), /// Creates an aggregate value, like a tuple or struct. /// @@ -993,17 +990,17 @@ pub enum Rvalue<'db> { /// /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Coroutine`. After /// coroutine lowering, `Coroutine` aggregate kinds are disallowed too. - Aggregate(AggregateKind<'db>, Box<[Operand<'db>]>), + Aggregate(AggregateKind, Box<[Operand]>), /// Transmutes a `*mut u8` into shallow-initialized `Box`. /// /// This is different from a normal transmute because dataflow analysis will treat the box as /// initialized but its content as uninitialized. Like other pointer casts, this in general /// affects alias analysis. - ShallowInitBox(Operand<'db>, Ty<'db>), + ShallowInitBox(Operand, StoredTy), /// NON STANDARD: allocates memory with the type's layout, and shallow init the box with the resulting pointer. - ShallowInitBoxWithAlloc(Ty<'db>), + ShallowInitBoxWithAlloc(StoredTy), /// A CopyForDeref is equivalent to a read from a place at the /// codegen level, but is treated specially by drop elaboration. When such a read happens, it @@ -1013,41 +1010,41 @@ pub enum Rvalue<'db> { /// read never happened and just projects further. This allows simplifying various MIR /// optimizations and codegen backends that previously had to handle deref operations anywhere /// in a place. - CopyForDeref(Place<'db>), + CopyForDeref(Place), } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum StatementKind<'db> { - Assign(Place<'db>, Rvalue<'db>), - FakeRead(Place<'db>), +pub enum StatementKind { + Assign(Place, Rvalue), + FakeRead(Place), //SetDiscriminant { // place: Box, // variant_index: VariantIdx, //}, - Deinit(Place<'db>), - StorageLive(LocalId<'db>), - StorageDead(LocalId<'db>), + Deinit(Place), + StorageLive(LocalId), + StorageDead(LocalId), //Retag(RetagKind, Box), //AscribeUserType(Place, UserTypeProjection, Variance), //Intrinsic(Box), Nop, } -impl<'db> StatementKind<'db> { - fn with_span(self, span: MirSpan) -> Statement<'db> { +impl StatementKind { + fn with_span(self, span: MirSpan) -> Statement { Statement { kind: self, span } } } #[derive(Debug, PartialEq, Eq, Clone)] -pub struct Statement<'db> { - pub kind: StatementKind<'db>, +pub struct Statement { + pub kind: StatementKind, pub span: MirSpan, } #[derive(Debug, Default, Clone, PartialEq, Eq)] -pub struct BasicBlock<'db> { +pub struct BasicBlock { /// List of statements in this block. - pub statements: Vec>, + pub statements: Vec, /// Terminator for this block. /// @@ -1057,7 +1054,7 @@ pub struct BasicBlock<'db> { /// exception is that certain passes, such as `simplify_cfg`, swap /// out the terminator temporarily with `None` while they continue /// to recurse over the set of basic blocks. - pub terminator: Option>, + pub terminator: Option, /// If true, this block lies on an unwind path. This is used /// during codegen where distinct kinds of basic blocks may be @@ -1067,29 +1064,29 @@ pub struct BasicBlock<'db> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct MirBody<'db> { - pub projection_store: ProjectionStore<'db>, - pub basic_blocks: Arena>, - pub locals: Arena>, - pub start_block: BasicBlockId<'db>, +pub struct MirBody { + pub projection_store: ProjectionStore, + pub basic_blocks: Arena, + pub locals: Arena, + pub start_block: BasicBlockId, pub owner: DefWithBodyId, - pub binding_locals: ArenaMap>, - pub param_locals: Vec>, + pub binding_locals: ArenaMap, + pub param_locals: Vec, /// This field stores the closures directly owned by this body. It is used /// in traversing every mir body. pub closures: Vec, } -impl<'db> MirBody<'db> { - pub fn local_to_binding_map(&self) -> ArenaMap, BindingId> { +impl MirBody { + pub fn local_to_binding_map(&self) -> ArenaMap { self.binding_locals.iter().map(|(it, y)| (*y, it)).collect() } - fn walk_places(&mut self, mut f: impl FnMut(&mut Place<'db>, &mut ProjectionStore<'db>)) { - fn for_operand<'db>( - op: &mut Operand<'db>, - f: &mut impl FnMut(&mut Place<'db>, &mut ProjectionStore<'db>), - store: &mut ProjectionStore<'db>, + fn walk_places(&mut self, mut f: impl FnMut(&mut Place, &mut ProjectionStore)) { + fn for_operand( + op: &mut Operand, + f: &mut impl FnMut(&mut Place, &mut ProjectionStore), + store: &mut ProjectionStore, ) { match &mut op.kind { OperandKind::Copy(p) | OperandKind::Move(p) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index b39c9bc06559..941b6c75bfe7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs @@ -17,7 +17,7 @@ use crate::{ display::DisplayTarget, mir::OperandKind, next_solver::{ - DbInterner, GenericArgs, ParamEnv, Ty, TypingMode, + DbInterner, GenericArgs, ParamEnv, StoredTy, Ty, TypingMode, infer::{DbInternerInferExt, InferCtxt}, }, }; @@ -36,44 +36,44 @@ pub enum MutabilityReason { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct MovedOutOfRef<'db> { - pub ty: Ty<'db>, +pub struct MovedOutOfRef { + pub ty: StoredTy, pub span: MirSpan, } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct PartiallyMoved<'db> { - pub ty: Ty<'db>, +pub struct PartiallyMoved { + pub ty: StoredTy, pub span: MirSpan, - pub local: LocalId<'db>, + pub local: LocalId, } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct BorrowRegion<'db> { - pub local: LocalId<'db>, +pub struct BorrowRegion { + pub local: LocalId, pub kind: BorrowKind, pub places: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct BorrowckResult<'db> { - pub mir_body: Arc>, - pub mutability_of_locals: ArenaMap, MutabilityReason>, - pub moved_out_of_ref: Vec>, - pub partially_moved: Vec>, - pub borrow_regions: Vec>, +pub struct BorrowckResult { + pub mir_body: Arc, + pub mutability_of_locals: ArenaMap, + pub moved_out_of_ref: Vec, + pub partially_moved: Vec, + pub borrow_regions: Vec, } -fn all_mir_bodies<'db>( - db: &'db dyn HirDatabase, +fn all_mir_bodies( + db: &dyn HirDatabase, def: DefWithBodyId, - mut cb: impl FnMut(Arc>), -) -> Result<(), MirLowerError<'db>> { - fn for_closure<'db>( - db: &'db dyn HirDatabase, + mut cb: impl FnMut(Arc), +) -> Result<(), MirLowerError> { + fn for_closure( + db: &dyn HirDatabase, c: InternedClosureId, - cb: &mut impl FnMut(Arc>), - ) -> Result<(), MirLowerError<'db>> { + cb: &mut impl FnMut(Arc), + ) -> Result<(), MirLowerError> { match db.mir_body_for_closure(c) { Ok(body) => { cb(body.clone()); @@ -91,10 +91,10 @@ fn all_mir_bodies<'db>( } } -pub fn borrowck_query<'db>( - db: &'db dyn HirDatabase, +pub fn borrowck_query( + db: &dyn HirDatabase, def: DefWithBodyId, -) -> Result]>, MirLowerError<'db>> { +) -> Result, MirLowerError> { let _p = tracing::info_span!("borrowck_query").entered(); let module = def.module(db); let interner = DbInterner::new_with(db, module.krate(db)); @@ -125,20 +125,20 @@ fn make_fetch_closure_field<'db>( let (captures, _) = infer.closure_info(c); let parent_subst = subst.split_closure_args_untupled().parent_args; let interner = DbInterner::new_no_crate(db); - captures.get(f).expect("broken closure field").ty.instantiate(interner, parent_subst) + captures.get(f).expect("broken closure field").ty.get().instantiate(interner, parent_subst) } } fn moved_out_of_ref<'db>( infcx: &InferCtxt<'db>, env: ParamEnv<'db>, - body: &MirBody<'db>, -) -> Vec> { + body: &MirBody, +) -> Vec { let db = infcx.interner.db; let mut result = vec![]; - let mut for_operand = |op: &Operand<'db>, span: MirSpan| match op.kind { + let mut for_operand = |op: &Operand, span: MirSpan| match op.kind { OperandKind::Copy(p) | OperandKind::Move(p) => { - let mut ty: Ty<'db> = body.locals[p.local].ty; + let mut ty: Ty<'db> = body.locals[p.local].ty.as_ref(); let mut is_dereference_of_ref = false; for proj in p.projection.lookup(&body.projection_store) { if *proj == ProjectionElem::Deref && ty.as_reference().is_some() { @@ -156,7 +156,7 @@ fn moved_out_of_ref<'db>( && !infcx.type_is_copy_modulo_regions(env, ty) && !ty.references_non_lt_error() { - result.push(MovedOutOfRef { span: op.span.unwrap_or(span), ty }); + result.push(MovedOutOfRef { span: op.span.unwrap_or(span), ty: ty.store() }); } } OperandKind::Constant { .. } | OperandKind::Static(_) => (), @@ -233,13 +233,13 @@ fn moved_out_of_ref<'db>( fn partially_moved<'db>( infcx: &InferCtxt<'db>, env: ParamEnv<'db>, - body: &MirBody<'db>, -) -> Vec> { + body: &MirBody, +) -> Vec { let db = infcx.interner.db; let mut result = vec![]; - let mut for_operand = |op: &Operand<'db>, span: MirSpan| match op.kind { + let mut for_operand = |op: &Operand, span: MirSpan| match op.kind { OperandKind::Copy(p) | OperandKind::Move(p) => { - let mut ty: Ty<'db> = body.locals[p.local].ty; + let mut ty: Ty<'db> = body.locals[p.local].ty.as_ref(); for proj in p.projection.lookup(&body.projection_store) { ty = proj.projected_ty( infcx, @@ -250,7 +250,7 @@ fn partially_moved<'db>( ); } if !infcx.type_is_copy_modulo_regions(env, ty) && !ty.references_non_lt_error() { - result.push(PartiallyMoved { span, ty, local: p.local }); + result.push(PartiallyMoved { span, ty: ty.store(), local: p.local }); } } OperandKind::Constant { .. } | OperandKind::Static(_) => (), @@ -324,7 +324,7 @@ fn partially_moved<'db>( result } -fn borrow_regions<'db>(db: &'db dyn HirDatabase, body: &MirBody<'db>) -> Vec> { +fn borrow_regions(db: &dyn HirDatabase, body: &MirBody) -> Vec { let mut borrows = FxHashMap::default(); for (_, block) in body.basic_blocks.iter() { db.unwind_if_revision_cancelled(); @@ -332,7 +332,7 @@ fn borrow_regions<'db>(db: &'db dyn HirDatabase, body: &MirBody<'db>) -> Vec| { + .and_modify(|it: &mut BorrowRegion| { it.places.push(statement.span); }) .or_insert_with(|| BorrowRegion { @@ -377,12 +377,12 @@ enum ProjectionCase { fn place_case<'db>( infcx: &InferCtxt<'db>, env: ParamEnv<'db>, - body: &MirBody<'db>, - lvalue: &Place<'db>, + body: &MirBody, + lvalue: &Place, ) -> ProjectionCase { let db = infcx.interner.db; let mut is_part_of = false; - let mut ty = body.locals[lvalue.local].ty; + let mut ty = body.locals[lvalue.local].ty.as_ref(); for proj in lvalue.projection.lookup(&body.projection_store).iter() { match proj { ProjectionElem::Deref if ty.as_adt().is_none() => return ProjectionCase::Indirect, // It's indirect in case of reference and raw @@ -410,18 +410,18 @@ fn place_case<'db>( /// Returns a map from basic blocks to the set of locals that might be ever initialized before /// the start of the block. Only `StorageDead` can remove something from this map, and we ignore /// `Uninit` and `drop` and similar after initialization. -fn ever_initialized_map<'db>( - db: &'db dyn HirDatabase, - body: &MirBody<'db>, -) -> ArenaMap, ArenaMap, bool>> { - let mut result: ArenaMap, ArenaMap, bool>> = +fn ever_initialized_map( + db: &dyn HirDatabase, + body: &MirBody, +) -> ArenaMap> { + let mut result: ArenaMap> = body.basic_blocks.iter().map(|it| (it.0, ArenaMap::default())).collect(); - fn dfs<'db>( - db: &'db dyn HirDatabase, - body: &MirBody<'db>, - l: LocalId<'db>, - stack: &mut Vec>, - result: &mut ArenaMap, ArenaMap, bool>>, + fn dfs( + db: &dyn HirDatabase, + body: &MirBody, + l: LocalId, + stack: &mut Vec, + result: &mut ArenaMap>, ) { while let Some(b) = stack.pop() { let mut is_ever_initialized = result[b][l]; // It must be filled, as we use it as mark for dfs @@ -509,11 +509,7 @@ fn ever_initialized_map<'db>( result } -fn push_mut_span<'db>( - local: LocalId<'db>, - span: MirSpan, - result: &mut ArenaMap, MutabilityReason>, -) { +fn push_mut_span(local: LocalId, span: MirSpan, result: &mut ArenaMap) { match &mut result[local] { MutabilityReason::Mut { spans } => spans.push(span), it @ (MutabilityReason::Not | MutabilityReason::Unused) => { @@ -522,16 +518,13 @@ fn push_mut_span<'db>( }; } -fn record_usage<'db>(local: LocalId<'db>, result: &mut ArenaMap, MutabilityReason>) { +fn record_usage(local: LocalId, result: &mut ArenaMap) { if let it @ MutabilityReason::Unused = &mut result[local] { *it = MutabilityReason::Not; }; } -fn record_usage_for_operand<'db>( - arg: &Operand<'db>, - result: &mut ArenaMap, MutabilityReason>, -) { +fn record_usage_for_operand(arg: &Operand, result: &mut ArenaMap) { if let OperandKind::Copy(p) | OperandKind::Move(p) = arg.kind { record_usage(p.local, result); } @@ -540,10 +533,10 @@ fn record_usage_for_operand<'db>( fn mutability_of_locals<'db>( infcx: &InferCtxt<'db>, env: ParamEnv<'db>, - body: &MirBody<'db>, -) -> ArenaMap, MutabilityReason> { + body: &MirBody, +) -> ArenaMap { let db = infcx.interner.db; - let mut result: ArenaMap, MutabilityReason> = + let mut result: ArenaMap = body.locals.iter().map(|it| (it.0, MutabilityReason::Unused)).collect(); let ever_init_maps = ever_initialized_map(db, body); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 3b4913cae3fb..b78e610b49e8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -17,6 +17,7 @@ use hir_def::{ use hir_expand::{InFile, mod_path::path, name::Name}; use intern::sym; use la_arena::ArenaMap; +use macros::GenericTypeVisitable; use rustc_abi::TargetDataLayout; use rustc_apfloat::{ Float, @@ -42,8 +43,8 @@ use crate::{ layout::{Layout, LayoutError, RustcEnumVariantIdx}, method_resolution::{is_dyn_method, lookup_impl_const}, next_solver::{ - Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region, Ty, TyKind, - TypingMode, UnevaluatedConst, ValueConst, + Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region, + StoredConst, StoredTy, Ty, TyKind, TypingMode, UnevaluatedConst, ValueConst, infer::{DbInternerInferExt, InferCtxt, traits::ObligationCause}, obligation_ctxt::ObligationCtxt, }, @@ -83,7 +84,7 @@ macro_rules! not_supported { }; } -#[derive(Debug, Default, Clone, PartialEq, Eq)] +#[derive(Debug, Default, Clone, PartialEq, Eq, GenericTypeVisitable)] pub struct VTableMap<'db> { ty_to_id: FxHashMap, usize>, id_to_ty: Vec>, @@ -150,16 +151,16 @@ impl TlsData { } } -struct StackFrame<'db> { - locals: Locals<'db>, - destination: Option>, +struct StackFrame { + locals: Locals, + destination: Option, prev_stack_ptr: usize, span: (MirSpan, DefWithBodyId), } #[derive(Clone)] -enum MirOrDynIndex<'db> { - Mir(Arc>), +enum MirOrDynIndex { + Mir(Arc), Dyn(usize), } @@ -169,7 +170,7 @@ pub struct Evaluator<'db> { target_data_layout: Arc, stack: Vec, heap: Vec, - code_stack: Vec>, + code_stack: Vec, /// Stores the global location of the statics. We const evaluate every static first time we need it /// and see it's missing, then we add it to this to reuse. static_locations: FxHashMap, @@ -182,13 +183,13 @@ pub struct Evaluator<'db> { stdout: Vec, stderr: Vec, layout_cache: RefCell, Arc>>, - projected_ty_cache: RefCell, PlaceElem<'db>), Ty<'db>>>, + projected_ty_cache: RefCell, PlaceElem), Ty<'db>>>, not_special_fn_cache: RefCell>, - mir_or_dyn_index_cache: RefCell), MirOrDynIndex<'db>>>, - /// Constantly dropping and creating `Locals<'db>` is very costly. We store + mir_or_dyn_index_cache: RefCell), MirOrDynIndex>>, + /// Constantly dropping and creating `Locals` is very costly. We store /// old locals that we normally want to drop here, to reuse their allocations /// later. - unused_locals_store: RefCell>>>, + unused_locals_store: RefCell>>, cached_ptr_size: usize, cached_fn_trait_func: Option, cached_fn_mut_trait_func: Option, @@ -261,7 +262,7 @@ impl<'db> IntervalAndTy<'db> { addr: Address, ty: Ty<'db>, evaluator: &Evaluator<'db>, - locals: &Locals<'db>, + locals: &Locals, ) -> Result<'db, IntervalAndTy<'db>> { let size = evaluator.size_of_sized(ty, locals, "type of interval")?; Ok(IntervalAndTy { interval: Interval { addr, size }, ty }) @@ -340,22 +341,22 @@ impl Address { } #[derive(Clone, PartialEq, Eq)] -pub enum MirEvalError<'db> { - ConstEvalError(String, Box>), - LayoutError(LayoutError, Ty<'db>), +pub enum MirEvalError { + ConstEvalError(String, Box), + LayoutError(LayoutError, StoredTy), TargetDataLayoutNotAvailable(TargetLoadError), /// Means that code had undefined behavior. We don't try to actively detect UB, but if it was detected /// then use this type of error. UndefinedBehavior(String), Panic(String), // FIXME: This should be folded into ConstEvalError? - MirLowerError(FunctionId, MirLowerError<'db>), - MirLowerErrorForClosure(InternedClosureId, MirLowerError<'db>), - TypeIsUnsized(Ty<'db>, &'static str), + MirLowerError(FunctionId, MirLowerError), + MirLowerErrorForClosure(InternedClosureId, MirLowerError), + TypeIsUnsized(StoredTy, &'static str), NotSupported(String), - InvalidConst(Const<'db>), + InvalidConst(StoredConst), InFunction( - Box>, + Box, Vec<(Either, MirSpan, DefWithBodyId)>, ), ExecutionLimitExceeded, @@ -363,12 +364,12 @@ pub enum MirEvalError<'db> { /// FIXME: Fold this into InternalError InvalidVTableId(usize), /// ? - CoerceUnsizedError(Ty<'db>), + CoerceUnsizedError(StoredTy), /// These should not occur, usually indicates a bug in mir lowering. InternalError(Box), } -impl MirEvalError<'_> { +impl MirEvalError { pub fn pretty_print( &self, f: &mut String, @@ -432,7 +433,9 @@ impl MirEvalError<'_> { write!( f, "Layout for type `{}` is not available due {err:?}", - ty.display(db, display_target).with_closure_style(ClosureStyle::ClosureWithId) + ty.as_ref() + .display(db, display_target) + .with_closure_style(ClosureStyle::ClosureWithId) )?; } MirEvalError::MirLowerError(func, err) => { @@ -495,7 +498,7 @@ impl MirEvalError<'_> { } } -impl std::fmt::Debug for MirEvalError<'_> { +impl std::fmt::Debug for MirEvalError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::ConstEvalError(arg0, arg1) => { @@ -534,15 +537,15 @@ impl std::fmt::Debug for MirEvalError<'_> { } } -type Result<'db, T> = std::result::Result>; +type Result<'db, T> = std::result::Result; #[derive(Debug, Default)] -struct DropFlags<'db> { - need_drop: FxHashSet>, +struct DropFlags { + need_drop: FxHashSet, } -impl<'db> DropFlags<'db> { - fn add_place(&mut self, p: Place<'db>, store: &ProjectionStore<'db>) { +impl DropFlags { + fn add_place(&mut self, p: Place, store: &ProjectionStore) { if p.iterate_over_parents(store).any(|it| self.need_drop.contains(&it)) { return; } @@ -550,7 +553,7 @@ impl<'db> DropFlags<'db> { self.need_drop.insert(p); } - fn remove_place(&mut self, p: &Place<'db>, store: &ProjectionStore<'db>) -> bool { + fn remove_place(&mut self, p: &Place, store: &ProjectionStore) -> bool { // FIXME: replace parents with parts if let Some(parent) = p.iterate_over_parents(store).find(|it| self.need_drop.contains(it)) { self.need_drop.remove(&parent); @@ -565,10 +568,10 @@ impl<'db> DropFlags<'db> { } #[derive(Debug)] -struct Locals<'db> { - ptr: ArenaMap, Interval>, - body: Arc>, - drop_flags: DropFlags<'db>, +struct Locals { + ptr: ArenaMap, + body: Arc, + drop_flags: DropFlags, } pub struct MirOutput { @@ -587,7 +590,7 @@ impl MirOutput { pub fn interpret_mir<'db>( db: &'db dyn HirDatabase, - body: Arc>, + body: Arc, // FIXME: This is workaround. Ideally, const generics should have a separate body (issue #7434), but now // they share their body with their parent, so in MIR lowering we have locals of the parent body, which // might have placeholders. With this argument, we (wrongly) assume that every placeholder type has @@ -596,7 +599,7 @@ pub fn interpret_mir<'db>( assert_placeholder_ty_is_unused: bool, trait_env: Option>, ) -> Result<'db, (Result<'db, Const<'db>>, MirOutput)> { - let ty = body.locals[return_slot()].ty; + let ty = body.locals[return_slot()].ty.as_ref(); let mut evaluator = Evaluator::new(db, body.owner, assert_placeholder_ty_is_unused, trait_env)?; let it: Result<'db, Const<'db>> = (|| { if evaluator.ptr_size() != size_of::() { @@ -694,11 +697,11 @@ impl<'db> Evaluator<'db> { self.infcx.interner.lang_items() } - fn place_addr(&self, p: &Place<'db>, locals: &Locals<'db>) -> Result<'db, Address> { + fn place_addr(&self, p: &Place, locals: &Locals) -> Result<'db, Address> { Ok(self.place_addr_and_ty_and_metadata(p, locals)?.0) } - fn place_interval(&self, p: &Place<'db>, locals: &Locals<'db>) -> Result<'db, Interval> { + fn place_interval(&self, p: &Place, locals: &Locals) -> Result<'db, Interval> { let place_addr_and_ty = self.place_addr_and_ty_and_metadata(p, locals)?; Ok(Interval { addr: place_addr_and_ty.0, @@ -714,7 +717,7 @@ impl<'db> Evaluator<'db> { self.cached_ptr_size } - fn projected_ty(&self, ty: Ty<'db>, proj: PlaceElem<'db>) -> Ty<'db> { + fn projected_ty(&self, ty: Ty<'db>, proj: PlaceElem) -> Ty<'db> { let pair = (ty, proj); if let Some(r) = self.projected_ty_cache.borrow().get(&pair) { return *r; @@ -733,6 +736,7 @@ impl<'db> Evaluator<'db> { .get(f) .expect("broken closure field") .ty + .get() .instantiate(self.interner(), parent_subst) }, self.crate_id, @@ -743,11 +747,11 @@ impl<'db> Evaluator<'db> { fn place_addr_and_ty_and_metadata<'a>( &'a self, - p: &Place<'db>, - locals: &'a Locals<'db>, + p: &Place, + locals: &'a Locals, ) -> Result<'db, (Address, Ty<'db>, Option)> { let mut addr = locals.ptr[p.local].addr; - let mut ty: Ty<'db> = locals.body.locals[p.local].ty; + let mut ty: Ty<'db> = locals.body.locals[p.local].ty.as_ref(); let mut metadata: Option = None; // locals are always sized for proj in p.projection.lookup(&locals.body.projection_store) { let prev_ty = ty; @@ -868,8 +872,8 @@ impl<'db> Evaluator<'db> { } let r = self .db - .layout_of_ty(ty, self.param_env) - .map_err(|e| MirEvalError::LayoutError(e, ty))?; + .layout_of_ty(ty.store(), self.param_env.store()) + .map_err(|e| MirEvalError::LayoutError(e, ty.store()))?; self.layout_cache.borrow_mut().insert(ty, r.clone()); Ok(r) } @@ -878,17 +882,17 @@ impl<'db> Evaluator<'db> { self.layout(Ty::new_adt(self.interner(), adt, subst)) } - fn place_ty<'a>(&'a self, p: &Place<'db>, locals: &'a Locals<'db>) -> Result<'db, Ty<'db>> { + fn place_ty<'a>(&'a self, p: &Place, locals: &'a Locals) -> Result<'db, Ty<'db>> { Ok(self.place_addr_and_ty_and_metadata(p, locals)?.1) } - fn operand_ty(&self, o: &Operand<'db>, locals: &Locals<'db>) -> Result<'db, Ty<'db>> { + fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<'db, Ty<'db>> { Ok(match &o.kind { OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?, - OperandKind::Constant { konst: _, ty } => *ty, + OperandKind::Constant { konst: _, ty } => ty.as_ref(), &OperandKind::Static(s) => { - let ty = - InferenceResult::for_body(self.db, s.into())[self.db.body(s.into()).body_expr]; + let ty = InferenceResult::for_body(self.db, s.into()) + .expr_ty(self.db.body(s.into()).body_expr); Ty::new_ref( self.interner(), Region::new_static(self.interner()), @@ -901,8 +905,8 @@ impl<'db> Evaluator<'db> { fn operand_ty_and_eval( &mut self, - o: &Operand<'db>, - locals: &mut Locals<'db>, + o: &Operand, + locals: &mut Locals, ) -> Result<'db, IntervalAndTy<'db>> { Ok(IntervalAndTy { interval: self.eval_operand(o, locals)?, @@ -912,7 +916,7 @@ impl<'db> Evaluator<'db> { fn interpret_mir( &mut self, - body: Arc>, + body: Arc, args: impl Iterator, ) -> Result<'db, Interval> { if let Some(it) = self.stack_depth_limit.checked_sub(1) { @@ -1076,8 +1080,8 @@ impl<'db> Evaluator<'db> { fn fill_locals_for_body( &mut self, - body: &MirBody<'db>, - locals: &mut Locals<'db>, + body: &MirBody, + locals: &mut Locals, args: impl Iterator, ) -> Result<'db, ()> { let mut remain_args = body.param_locals.len(); @@ -1100,9 +1104,9 @@ impl<'db> Evaluator<'db> { fn create_locals_for_body( &mut self, - body: &Arc>, + body: &Arc, destination: Option, - ) -> Result<'db, (Locals<'db>, usize)> { + ) -> Result<'db, (Locals, usize)> { let mut locals = match self.unused_locals_store.borrow_mut().entry(body.owner).or_default().pop() { None => Locals { @@ -1126,7 +1130,7 @@ impl<'db> Evaluator<'db> { continue; } let (size, align) = self.size_align_of_sized( - it.ty, + it.ty.as_ref(), &locals, "no unsized local in extending stack", )?; @@ -1149,11 +1153,7 @@ impl<'db> Evaluator<'db> { Ok((locals, prev_stack_pointer)) } - fn eval_rvalue( - &mut self, - r: &Rvalue<'db>, - locals: &mut Locals<'db>, - ) -> Result<'db, IntervalOrOwned> { + fn eval_rvalue(&mut self, r: &Rvalue, locals: &mut Locals) -> Result<'db, IntervalOrOwned> { use IntervalOrOwned::*; Ok(match r { Rvalue::Use(it) => Borrowed(self.eval_operand(it, locals)?), @@ -1445,7 +1445,7 @@ impl<'db> Evaluator<'db> { Owned(result.to_le_bytes().to_vec()) } Rvalue::Repeat(it, len) => { - let len = match try_const_usize(self.db, *len) { + let len = match try_const_usize(self.db, len.as_ref()) { Some(it) => it as usize, None => not_supported!("non evaluatable array len in repeat Rvalue"), }; @@ -1455,7 +1455,7 @@ impl<'db> Evaluator<'db> { } Rvalue::ShallowInitBox(_, _) => not_supported!("shallow init box"), Rvalue::ShallowInitBoxWithAlloc(ty) => { - let Some((size, align)) = self.size_align_of(*ty, locals)? else { + let Some((size, align)) = self.size_align_of(ty.as_ref(), locals)? else { not_supported!("unsized box initialization"); }; let addr = self.heap_allocate(size, align)?; @@ -1477,7 +1477,7 @@ impl<'db> Evaluator<'db> { Owned(r) } AggregateKind::Tuple(ty) => { - let layout = self.layout(*ty)?; + let layout = self.layout(ty.as_ref())?; Owned(self.construct_with_layout( layout.size.bytes_usize(), &layout, @@ -1486,10 +1486,8 @@ impl<'db> Evaluator<'db> { )?) } AggregateKind::Union(it, f) => { - let layout = self.layout_adt( - (*it).into(), - GenericArgs::new_from_iter(self.interner(), []), - )?; + let layout = + self.layout_adt((*it).into(), GenericArgs::empty(self.interner()))?; let offset = layout .fields .offset(u32::from(f.local_id.into_raw()) as usize) @@ -1501,7 +1499,7 @@ impl<'db> Evaluator<'db> { } AggregateKind::Adt(it, subst) => { let (size, variant_layout, tag) = - self.layout_of_variant(*it, *subst, locals)?; + self.layout_of_variant(*it, subst.as_ref(), locals)?; Owned(self.construct_with_layout( size, &variant_layout, @@ -1510,7 +1508,7 @@ impl<'db> Evaluator<'db> { )?) } AggregateKind::Closure(ty) => { - let layout = self.layout(*ty)?; + let layout = self.layout(ty.as_ref())?; Owned(self.construct_with_layout( layout.size.bytes_usize(), &layout, @@ -1537,7 +1535,7 @@ impl<'db> Evaluator<'db> { PointerCast::Unsize => { let current_ty = self.operand_ty(operand, locals)?; let addr = self.eval_operand(operand, locals)?; - self.coerce_unsized(addr, current_ty, *target_ty)? + self.coerce_unsized(addr, current_ty, target_ty.as_ref())? } PointerCast::MutToConstPointer | PointerCast::UnsafeFnPointer => { // This is no-op @@ -1556,8 +1554,11 @@ impl<'db> Evaluator<'db> { let current_ty = self.operand_ty(operand, locals)?; let is_signed = matches!(current_ty.kind(), TyKind::Int(_)); let current = pad16(self.eval_operand(operand, locals)?.get(self)?, is_signed); - let dest_size = - self.size_of_sized(*target_ty, locals, "destination of int to int cast")?; + let dest_size = self.size_of_sized( + target_ty.as_ref(), + locals, + "destination of int to int cast", + )?; Owned(current[0..dest_size].to_vec()) } CastKind::FloatToInt => { @@ -1579,9 +1580,12 @@ impl<'db> Evaluator<'db> { not_supported!("unstable floating point type f16 and f128"); } }; - let is_signed = matches!(target_ty.kind(), TyKind::Int(_)); - let dest_size = - self.size_of_sized(*target_ty, locals, "destination of float to int cast")?; + let is_signed = matches!(target_ty.as_ref().kind(), TyKind::Int(_)); + let dest_size = self.size_of_sized( + target_ty.as_ref(), + locals, + "destination of float to int cast", + )?; let dest_bits = dest_size * 8; let (max, min) = if dest_bits == 128 { (i128::MAX, i128::MIN) @@ -1614,7 +1618,7 @@ impl<'db> Evaluator<'db> { not_supported!("unstable floating point type f16 and f128"); } }; - let TyKind::Float(target_ty) = target_ty.kind() else { + let TyKind::Float(target_ty) = target_ty.as_ref().kind() else { not_supported!("invalid float to float cast"); }; match target_ty { @@ -1630,7 +1634,7 @@ impl<'db> Evaluator<'db> { let is_signed = matches!(current_ty.kind(), TyKind::Int(_)); let value = pad16(self.eval_operand(operand, locals)?.get(self)?, is_signed); let value = i128::from_le_bytes(value); - let TyKind::Float(target_ty) = target_ty.kind() else { + let TyKind::Float(target_ty) = target_ty.as_ref().kind() else { not_supported!("invalid int to float cast"); }; match target_ty { @@ -1709,12 +1713,12 @@ impl<'db> Evaluator<'db> { { let field_types = self.db.field_types(struct_id.into()); if let Some(ty) = - field_types.iter().last().map(|it| it.1.instantiate(self.interner(), subst)) + field_types.iter().last().map(|it| it.1.get().instantiate(self.interner(), subst)) { return self.coerce_unsized_look_through_fields(ty, goal); } } - Err(MirEvalError::CoerceUnsizedError(ty)) + Err(MirEvalError::CoerceUnsizedError(ty.store())) } fn coerce_unsized( @@ -1787,8 +1791,10 @@ impl<'db> Evaluator<'db> { not_supported!("unsizing struct without field"); }; let target_last_field = self.db.field_types(id.into())[last_field] + .get() .instantiate(self.interner(), target_subst); let current_last_field = self.db.field_types(id.into())[last_field] + .get() .instantiate(self.interner(), current_subst); return self.unsizing_ptr_from_addr( target_last_field, @@ -1806,7 +1812,7 @@ impl<'db> Evaluator<'db> { &mut self, it: VariantId, subst: GenericArgs<'db>, - locals: &Locals<'db>, + locals: &Locals, ) -> Result<'db, (usize, Arc, Option<(usize, usize, i128)>)> { let adt = it.adt_id(self.db); if let DefWithBodyId::VariantId(f) = locals.body.owner @@ -1900,11 +1906,7 @@ impl<'db> Evaluator<'db> { Ok(result) } - fn eval_operand( - &mut self, - it: &Operand<'db>, - locals: &mut Locals<'db>, - ) -> Result<'db, Interval> { + fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<'db, Interval> { Ok(match &it.kind { OperandKind::Copy(p) | OperandKind::Move(p) => { locals.drop_flags.remove_place(p, &locals.body.projection_store); @@ -1914,14 +1916,16 @@ impl<'db> Evaluator<'db> { let addr = self.eval_static(*st, locals)?; Interval::new(addr, self.ptr_size()) } - OperandKind::Constant { konst, .. } => self.allocate_const_in_heap(locals, *konst)?, + OperandKind::Constant { konst, .. } => { + self.allocate_const_in_heap(locals, konst.as_ref())? + } }) } #[allow(clippy::double_parens)] fn allocate_const_in_heap( &mut self, - locals: &Locals<'db>, + locals: &Locals, konst: Const<'db>, ) -> Result<'db, Interval> { let result_owner; @@ -1971,7 +1975,7 @@ impl<'db> Evaluator<'db> { } else if size < 16 && v.len() == 16 { Cow::Borrowed(&v[0..size]) } else { - return Err(MirEvalError::InvalidConst(konst)); + return Err(MirEvalError::InvalidConst(konst.store())); } } else { Cow::Borrowed(v) @@ -1993,7 +1997,7 @@ impl<'db> Evaluator<'db> { Ok(Interval::new(addr, size)) } - fn eval_place(&mut self, p: &Place<'db>, locals: &Locals<'db>) -> Result<'db, Interval> { + fn eval_place(&mut self, p: &Place, locals: &Locals) -> Result<'db, Interval> { let addr = self.place_addr(p, locals)?; Ok(Interval::new( addr, @@ -2093,11 +2097,7 @@ impl<'db> Evaluator<'db> { Ok(()) } - fn size_align_of( - &self, - ty: Ty<'db>, - locals: &Locals<'db>, - ) -> Result<'db, Option<(usize, usize)>> { + fn size_align_of(&self, ty: Ty<'db>, locals: &Locals) -> Result<'db, Option<(usize, usize)>> { if let Some(layout) = self.layout_cache.borrow().get(&ty) { return Ok(layout .is_sized() @@ -2126,12 +2126,12 @@ impl<'db> Evaluator<'db> { fn size_of_sized( &self, ty: Ty<'db>, - locals: &Locals<'db>, + locals: &Locals, what: &'static str, ) -> Result<'db, usize> { match self.size_align_of(ty, locals)? { Some(it) => Ok(it.0), - None => Err(MirEvalError::TypeIsUnsized(ty, what)), + None => Err(MirEvalError::TypeIsUnsized(ty.store(), what)), } } @@ -2140,12 +2140,12 @@ impl<'db> Evaluator<'db> { fn size_align_of_sized( &self, ty: Ty<'db>, - locals: &Locals<'db>, + locals: &Locals, what: &'static str, ) -> Result<'db, (usize, usize)> { match self.size_align_of(ty, locals)? { Some(it) => Ok(it), - None => Err(MirEvalError::TypeIsUnsized(ty, what)), + None => Err(MirEvalError::TypeIsUnsized(ty.store(), what)), } } @@ -2181,13 +2181,13 @@ impl<'db> Evaluator<'db> { &self, bytes: &[u8], ty: Ty<'db>, - locals: &Locals<'db>, + locals: &Locals, ) -> Result<'db, ComplexMemoryMap<'db>> { fn rec<'db>( this: &Evaluator<'db>, bytes: &[u8], ty: Ty<'db>, - locals: &Locals<'db>, + locals: &Locals, mm: &mut ComplexMemoryMap<'db>, stack_depth_limit: usize, ) -> Result<'db, ()> { @@ -2288,7 +2288,7 @@ impl<'db> Evaluator<'db> { .fields .offset(u32::from(f.into_raw()) as usize) .bytes_usize(); - let ty = field_types[f].instantiate(this.interner(), subst); + let ty = field_types[f].get().instantiate(this.interner(), subst); let size = this.layout(ty)?.size.bytes_usize(); rec( this, @@ -2314,7 +2314,7 @@ impl<'db> Evaluator<'db> { for (f, _) in data.fields().iter() { let offset = l.fields.offset(u32::from(f.into_raw()) as usize).bytes_usize(); - let ty = field_types[f].instantiate(this.interner(), subst); + let ty = field_types[f].get().instantiate(this.interner(), subst); let size = this.layout(ty)?.size.bytes_usize(); rec( this, @@ -2356,7 +2356,7 @@ impl<'db> Evaluator<'db> { ty_of_bytes: impl Fn(&[u8]) -> Result<'db, Ty<'db>> + Copy, addr: Address, ty: Ty<'db>, - locals: &Locals<'db>, + locals: &Locals, ) -> Result<'db, ()> { // FIXME: support indirect references let layout = self.layout(ty)?; @@ -2389,7 +2389,7 @@ impl<'db> Evaluator<'db> { AdtId::StructId(s) => { for (i, (_, ty)) in self.db.field_types(s.into()).iter().enumerate() { let offset = layout.fields.offset(i).bytes_usize(); - let ty = ty.instantiate(self.interner(), args); + let ty = ty.get().instantiate(self.interner(), args); self.patch_addresses( patch_map, ty_of_bytes, @@ -2410,7 +2410,7 @@ impl<'db> Evaluator<'db> { ) { for (i, (_, ty)) in self.db.field_types(ev.into()).iter().enumerate() { let offset = layout.fields.offset(i).bytes_usize(); - let ty = ty.instantiate(self.interner(), args); + let ty = ty.get().instantiate(self.interner(), args); self.patch_addresses( patch_map, ty_of_bytes, @@ -2477,10 +2477,10 @@ impl<'db> Evaluator<'db> { bytes: Interval, destination: Interval, args: &[IntervalAndTy<'db>], - locals: &Locals<'db>, - target_bb: Option>, + locals: &Locals, + target_bb: Option, span: MirSpan, - ) -> Result<'db, Option>> { + ) -> Result<'db, Option> { let id = from_bytes!(usize, bytes.get(self)?); let next_ty = self.vtable_map.ty(id)?; use rustc_type_ir::TyKind; @@ -2508,19 +2508,23 @@ impl<'db> Evaluator<'db> { generic_args: GenericArgs<'db>, destination: Interval, args: &[IntervalAndTy<'db>], - locals: &Locals<'db>, + locals: &Locals, span: MirSpan, - ) -> Result<'db, Option>> { + ) -> Result<'db, Option> { let mir_body = self .db - .monomorphized_mir_body_for_closure(closure, generic_args, self.param_env) + .monomorphized_mir_body_for_closure( + closure, + generic_args.store(), + self.param_env.store(), + ) .map_err(|it| MirEvalError::MirLowerErrorForClosure(closure, it))?; - let closure_data = if mir_body.locals[mir_body.param_locals[0]].ty.as_reference().is_some() - { - closure_data.addr.to_bytes().to_vec() - } else { - closure_data.get(self)?.to_owned() - }; + let closure_data = + if mir_body.locals[mir_body.param_locals[0]].ty.as_ref().as_reference().is_some() { + closure_data.addr.to_bytes().to_vec() + } else { + closure_data.get(self)?.to_owned() + }; let arg_bytes = iter::once(Ok(closure_data)) .chain(args.iter().map(|it| Ok(it.get(self)?.to_owned()))) .collect::>>()?; @@ -2542,10 +2546,10 @@ impl<'db> Evaluator<'db> { generic_args: GenericArgs<'db>, destination: Interval, args: &[IntervalAndTy<'db>], - locals: &Locals<'db>, - target_bb: Option>, + locals: &Locals, + target_bb: Option, span: MirSpan, - ) -> Result<'db, Option>> { + ) -> Result<'db, Option> { match def { CallableDefId::FunctionId(def) => { if self.detect_fn_trait(def).is_some() { @@ -2600,9 +2604,9 @@ impl<'db> Evaluator<'db> { &self, def: FunctionId, generic_args: GenericArgs<'db>, - locals: &Locals<'db>, + locals: &Locals, span: MirSpan, - ) -> Result<'db, MirOrDynIndex<'db>> { + ) -> Result<'db, MirOrDynIndex> { let pair = (def, generic_args); if let Some(r) = self.mir_or_dyn_index_cache.borrow().get(&pair) { return Ok(r.clone()); @@ -2621,7 +2625,7 @@ impl<'db> Evaluator<'db> { let mir_body = self .db - .monomorphized_mir_body(imp.into(), generic_args, self.param_env) + .monomorphized_mir_body(imp.into(), generic_args.store(), self.param_env.store()) .map_err(|e| { MirEvalError::InFunction( Box::new(MirEvalError::MirLowerError(imp, e)), @@ -2639,11 +2643,11 @@ impl<'db> Evaluator<'db> { mut def: FunctionId, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, - locals: &Locals<'db>, + locals: &Locals, destination: Interval, - target_bb: Option>, + target_bb: Option, span: MirSpan, - ) -> Result<'db, Option>> { + ) -> Result<'db, Option> { if self.detect_and_exec_special_function( def, args, @@ -2705,14 +2709,14 @@ impl<'db> Evaluator<'db> { fn exec_looked_up_function( &mut self, - mir_body: Arc>, - locals: &Locals<'db>, + mir_body: Arc, + locals: &Locals, def: FunctionId, arg_bytes: impl Iterator, span: MirSpan, destination: Interval, - target_bb: Option>, - ) -> Result<'db, Option>> { + target_bb: Option, + ) -> Result<'db, Option> { Ok(if let Some(target_bb) = target_bb { let (mut locals, prev_stack_ptr) = self.create_locals_for_body(&mir_body, Some(destination))?; @@ -2736,11 +2740,11 @@ impl<'db> Evaluator<'db> { def: FunctionId, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, - locals: &Locals<'db>, + locals: &Locals, destination: Interval, - target_bb: Option>, + target_bb: Option, span: MirSpan, - ) -> Result<'db, Option>> { + ) -> Result<'db, Option> { let func = args .first() .ok_or_else(|| MirEvalError::InternalError("fn trait with no arg".into()))?; @@ -2805,7 +2809,7 @@ impl<'db> Evaluator<'db> { } } - fn eval_static(&mut self, st: StaticId, locals: &Locals<'db>) -> Result<'db, Address> { + fn eval_static(&mut self, st: StaticId, locals: &Locals) -> Result<'db, Address> { if let Some(o) = self.static_locations.get(&st) { return Ok(*o); }; @@ -2816,8 +2820,8 @@ impl<'db> Evaluator<'db> { })?; self.allocate_const_in_heap(locals, konst)? } else { - let ty = - InferenceResult::for_body(self.db, st.into())[self.db.body(st.into()).body_expr]; + let ty = InferenceResult::for_body(self.db, st.into()) + .expr_ty(self.db.body(st.into()).body_expr); let Some((size, align)) = self.size_align_of(ty, locals)? else { not_supported!("unsized extern static"); }; @@ -2852,12 +2856,7 @@ impl<'db> Evaluator<'db> { } } - fn drop_place( - &mut self, - place: &Place<'db>, - locals: &mut Locals<'db>, - span: MirSpan, - ) -> Result<'db, ()> { + fn drop_place(&mut self, place: &Place, locals: &mut Locals, span: MirSpan) -> Result<'db, ()> { let (addr, ty, metadata) = self.place_addr_and_ty_and_metadata(place, locals)?; if !locals.drop_flags.remove_place(place, &locals.body.projection_store) { return Ok(()); @@ -2872,7 +2871,7 @@ impl<'db> Evaluator<'db> { fn run_drop_glue_deep( &mut self, ty: Ty<'db>, - locals: &Locals<'db>, + locals: &Locals, addr: Address, _metadata: &[u8], span: MirSpan, @@ -2886,7 +2885,7 @@ impl<'db> Evaluator<'db> { return Ok(()); }; - let generic_args = GenericArgs::new_from_iter(self.interner(), [ty.into()]); + let generic_args = GenericArgs::new_from_slice(&[ty.into()]); if let Ok(MirOrDynIndex::Mir(body)) = self.get_mir_or_dyn_index(drop_fn, generic_args, locals, span) { @@ -2920,7 +2919,9 @@ impl<'db> Evaluator<'db> { .offset(u32::from(field.into_raw()) as usize) .bytes_usize(); let addr = addr.offset(offset); - let ty = field_types[field].instantiate(self.interner(), subst); + let ty = field_types[field] + .get() + .instantiate(self.interner(), subst); self.run_drop_glue_deep(ty, locals, addr, &[], span)?; } } @@ -3011,7 +3012,7 @@ pub fn render_const_using_debug_impl<'db>( let debug_fmt_fn_ptr = evaluator.vtable_map.id(Ty::new_fn_def( evaluator.interner(), CallableDefId::FunctionId(debug_fmt_fn).into(), - GenericArgs::new_from_iter(evaluator.interner(), [ty.into()]), + GenericArgs::new_from_slice(&[ty.into()]), )); evaluator.write_memory(a2.offset(evaluator.ptr_size()), &debug_fmt_fn_ptr.to_le_bytes())?; // a3 = ::core::fmt::Arguments::new_v1(a1, a2) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index 42c11113ee30..a47a8c440007 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -52,7 +52,7 @@ impl<'db> Evaluator<'db> { def: FunctionId, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, - locals: &Locals<'db>, + locals: &Locals, destination: Interval, span: MirSpan, ) -> Result<'db, bool> { @@ -149,7 +149,7 @@ impl<'db> Evaluator<'db> { def: FunctionId, args: &[IntervalAndTy<'db>], self_ty: Ty<'db>, - locals: &Locals<'db>, + locals: &Locals, destination: Interval, span: MirSpan, ) -> Result<'db, ()> { @@ -195,7 +195,7 @@ impl<'db> Evaluator<'db> { self.exec_fn_with_args( def, args, - GenericArgs::new_from_iter(self.interner(), [self_ty.into()]), + GenericArgs::new_from_slice(&[self_ty.into()]), locals, destination, None, @@ -212,7 +212,7 @@ impl<'db> Evaluator<'db> { layout: Arc, addr: Address, def: FunctionId, - locals: &Locals<'db>, + locals: &Locals, destination: Interval, span: MirSpan, ) -> Result<'db, ()> { @@ -318,7 +318,7 @@ impl<'db> Evaluator<'db> { it: EvalLangItem, generic_args: GenericArgs<'db>, args: &[IntervalAndTy<'db>], - locals: &Locals<'db>, + locals: &Locals, span: MirSpan, ) -> Result<'db, Vec> { use EvalLangItem::*; @@ -390,7 +390,7 @@ impl<'db> Evaluator<'db> { id: i64, args: &[IntervalAndTy<'db>], destination: Interval, - _locals: &Locals<'db>, + _locals: &Locals, _span: MirSpan, ) -> Result<'db, ()> { match id { @@ -421,7 +421,7 @@ impl<'db> Evaluator<'db> { args: &[IntervalAndTy<'db>], _generic_args: GenericArgs<'db>, destination: Interval, - locals: &Locals<'db>, + locals: &Locals, span: MirSpan, ) -> Result<'db, ()> { match as_str { @@ -587,7 +587,7 @@ impl<'db> Evaluator<'db> { args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, destination: Interval, - locals: &Locals<'db>, + locals: &Locals, span: MirSpan, needs_override: bool, ) -> Result<'db, bool> { @@ -1235,7 +1235,7 @@ impl<'db> Evaluator<'db> { def, &args, // FIXME: wrong for manual impls of `FnOnce` - GenericArgs::new_from_iter(self.interner(), []), + GenericArgs::empty(self.interner()), locals, destination, None, @@ -1369,7 +1369,7 @@ impl<'db> Evaluator<'db> { &mut self, ty: Ty<'db>, metadata: Interval, - locals: &Locals<'db>, + locals: &Locals, ) -> Result<'db, (usize, usize)> { Ok(match ty.kind() { TyKind::Str => (from_bytes!(usize, metadata.get(self)?), 1), @@ -1391,8 +1391,13 @@ impl<'db> Evaluator<'db> { _ => not_supported!("unsized enum or union"), }; let field_types = self.db.field_types(id.into()); - let last_field_ty = - field_types.iter().next_back().unwrap().1.instantiate(self.interner(), subst); + let last_field_ty = field_types + .iter() + .next_back() + .unwrap() + .1 + .get() + .instantiate(self.interner(), subst); let sized_part_size = layout.fields.offset(field_types.iter().count() - 1).bytes_usize(); let sized_part_align = layout.align.bytes() as usize; @@ -1423,7 +1428,7 @@ impl<'db> Evaluator<'db> { args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, destination: Interval, - locals: &Locals<'db>, + locals: &Locals, _span: MirSpan, ) -> Result<'db, ()> { // We are a single threaded runtime with no UB checking and no optimization, so diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs index 4c64a70a7a62..3896917cab1a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs @@ -35,6 +35,7 @@ impl<'db> Evaluator<'db> { not_supported!("simd type with no field"); }; let field_ty = self.db.field_types(id.into())[first_field] + .get() .instantiate(self.interner(), subst); return Ok((fields.len(), field_ty)); } @@ -67,7 +68,7 @@ impl<'db> Evaluator<'db> { args: &[IntervalAndTy<'db>], _generic_args: GenericArgs<'db>, destination: Interval, - _locals: &Locals<'db>, + _locals: &Locals, _span: MirSpan, ) -> Result<'db, ()> { match name { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs index c13b76c12579..61dd7757c90b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs @@ -15,7 +15,7 @@ use crate::{ use super::{MirEvalError, interpret_mir}; -fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), MirEvalError<'_>> { +fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), MirEvalError> { crate::attach_db(db, || { let interner = DbInterner::new_no_crate(db); let module_id = db.module_for_file(file_id.file_id(db)); @@ -39,11 +39,12 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), let body = db .monomorphized_mir_body( func_id.into(), - GenericArgs::new_from_iter(interner, []), + GenericArgs::empty(interner).store(), crate::ParamEnvAndCrate { param_env: db.trait_environment(func_id.into()), krate: func_id.krate(db), - }, + } + .store(), ) .map_err(|e| MirEvalError::MirLowerError(func_id, e))?; @@ -122,7 +123,7 @@ fn check_panic(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected_panic: fn check_error_with( #[rust_analyzer::rust_fixture] ra_fixture: &str, - expect_err: impl FnOnce(MirEvalError<'_>) -> bool, + expect_err: impl FnOnce(MirEvalError) -> bool, ) { let (db, file_ids) = TestDB::with_many_files(ra_fixture); crate::attach_db(&db, || { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index d7a8c18614a4..ef2a13848ca6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -19,7 +19,7 @@ use hir_expand::name::Name; use la_arena::ArenaMap; use rustc_apfloat::Float; use rustc_hash::FxHashMap; -use rustc_type_ir::inherent::{Const as _, IntoKind, SliceLike, Ty as _}; +use rustc_type_ir::inherent::{Const as _, IntoKind, Ty as _}; use span::{Edition, FileId}; use syntax::TextRange; use triomphe::Arc; @@ -42,7 +42,8 @@ use crate::{ TupleFieldId, Ty, UnOp, VariantId, return_slot, }, next_solver::{ - Const, DbInterner, ParamConst, ParamEnv, Region, TyKind, TypingMode, UnevaluatedConst, + Const, DbInterner, ParamConst, ParamEnv, Region, StoredGenericArgs, StoredTy, TyKind, + TypingMode, UnevaluatedConst, infer::{DbInternerInferExt, InferCtxt}, }, traits::FnTrait, @@ -56,39 +57,39 @@ mod pattern_matching; mod tests; #[derive(Debug, Clone)] -struct LoopBlocks<'db> { - begin: BasicBlockId<'db>, +struct LoopBlocks { + begin: BasicBlockId, /// `None` for loops that are not terminating - end: Option>, - place: Place<'db>, + end: Option, + place: Place, drop_scope_index: usize, } #[derive(Debug, Clone, Default)] -struct DropScope<'db> { +struct DropScope { /// locals, in order of definition (so we should run drop glues in reverse order) - locals: Vec>, + locals: Vec, } struct MirLowerCtx<'a, 'db> { - result: MirBody<'db>, + result: MirBody, owner: DefWithBodyId, - current_loop_blocks: Option>, - labeled_loop_blocks: FxHashMap>, - discr_temp: Option>, + current_loop_blocks: Option, + labeled_loop_blocks: FxHashMap, + discr_temp: Option, db: &'db dyn HirDatabase, body: &'a Body, - infer: &'a InferenceResult<'db>, + infer: &'a InferenceResult, resolver: Resolver<'db>, - drop_scopes: Vec>, + drop_scopes: Vec, env: ParamEnv<'db>, infcx: InferCtxt<'db>, } // FIXME: Make this smaller, its stored in database queries #[derive(Debug, Clone, PartialEq, Eq)] -pub enum MirLowerError<'db> { - ConstEvalError(Box, Box>), +pub enum MirLowerError { + ConstEvalError(Box, Box), LayoutError(LayoutError), IncompleteExpr, IncompletePattern, @@ -98,9 +99,9 @@ pub enum MirLowerError<'db> { RecordLiteralWithoutPath, UnresolvedMethod(String), UnresolvedField, - UnsizedTemporary(Ty<'db>), + UnsizedTemporary(StoredTy), MissingFunctionDefinition(DefWithBodyId, ExprId), - TypeMismatch(TypeMismatch<'db>), + TypeMismatch(TypeMismatch), HasErrors, /// This should never happen. Type mismatch should catch everything. TypeError(&'static str), @@ -113,11 +114,11 @@ pub enum MirLowerError<'db> { LangItemNotFound, MutatingRvalue, UnresolvedLabel, - UnresolvedUpvar(Place<'db>), + UnresolvedUpvar(Place), InaccessibleLocal, // monomorphization errors: - GenericArgNotProvided(GenericParamId, GenericArgs<'db>), + GenericArgNotProvided(GenericParamId, StoredGenericArgs), } /// A token to ensuring that each drop scope is popped at most once, thanks to the compiler that checks moves. @@ -126,9 +127,9 @@ impl DropScopeToken { fn pop_and_drop<'db>( self, ctx: &mut MirLowerCtx<'_, 'db>, - current: BasicBlockId<'db>, + current: BasicBlockId, span: MirSpan, - ) -> BasicBlockId<'db> { + ) -> BasicBlockId { std::mem::forget(self); ctx.pop_drop_scope_internal(current, span) } @@ -158,7 +159,7 @@ impl Drop for DropScopeToken { // } // } -impl MirLowerError<'_> { +impl MirLowerError { pub fn pretty_print( &self, f: &mut String, @@ -190,8 +191,8 @@ impl MirLowerError<'_> { MirLowerError::TypeMismatch(e) => writeln!( f, "Type mismatch: Expected {}, found {}", - e.expected.display(db, display_target), - e.actual.display(db, display_target), + e.expected.as_ref().display(db, display_target), + e.actual.as_ref().display(db, display_target), )?, MirLowerError::GenericArgNotProvided(id, subst) => { let param_name = match *id { @@ -211,7 +212,7 @@ impl MirLowerError<'_> { param_name.unwrap_or(Name::missing()).display(db, display_target.edition) )?; writeln!(f, "Provided args: [")?; - for g in subst.iter() { + for g in subst.as_ref() { write!(f, " {},", g.display(db, display_target))?; } writeln!(f, "]")?; @@ -254,13 +255,13 @@ macro_rules! implementation_error { }}; } -impl From for MirLowerError<'_> { +impl From for MirLowerError { fn from(value: LayoutError) -> Self { MirLowerError::LayoutError(value) } } -impl MirLowerError<'_> { +impl MirLowerError { fn unresolved_path( db: &dyn HirDatabase, p: &Path, @@ -273,14 +274,14 @@ impl MirLowerError<'_> { } } -type Result<'db, T> = std::result::Result>; +type Result<'db, T> = std::result::Result; impl<'a, 'db> MirLowerCtx<'a, 'db> { fn new( db: &'db dyn HirDatabase, owner: DefWithBodyId, body: &'a Body, - infer: &'a InferenceResult<'db>, + infer: &'a InferenceResult, ) -> Self { let mut basic_blocks = Arena::new(); let start_block = basic_blocks.alloc(BasicBlock { @@ -289,7 +290,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { is_cleanup: false, }); let locals = Arena::new(); - let binding_locals: ArenaMap> = ArenaMap::new(); + let binding_locals: ArenaMap = ArenaMap::new(); let mir = MirBody { projection_store: ProjectionStore::default(), basic_blocks, @@ -332,16 +333,11 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { self.infcx.interner.lang_items() } - fn temp( - &mut self, - ty: Ty<'db>, - current: BasicBlockId<'db>, - span: MirSpan, - ) -> Result<'db, LocalId<'db>> { + fn temp(&mut self, ty: Ty<'db>, current: BasicBlockId, span: MirSpan) -> Result<'db, LocalId> { if matches!(ty.kind(), TyKind::Slice(_) | TyKind::Dynamic(..)) { - return Err(MirLowerError::UnsizedTemporary(ty)); + return Err(MirLowerError::UnsizedTemporary(ty.store())); } - let l = self.result.locals.alloc(Local { ty }); + let l = self.result.locals.alloc(Local { ty: ty.store() }); self.push_storage_live_for_local(l, current, span)?; Ok(l) } @@ -349,8 +345,8 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_expr_to_some_operand( &mut self, expr_id: ExprId, - current: BasicBlockId<'db>, - ) -> Result<'db, Option<(Operand<'db>, BasicBlockId<'db>)>> { + current: BasicBlockId, + ) -> Result<'db, Option<(Operand, BasicBlockId)>> { if !self.has_adjustments(expr_id) && let Expr::Literal(l) = &self.body[expr_id] { @@ -366,10 +362,10 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_expr_to_place_with_adjust( &mut self, expr_id: ExprId, - place: Place<'db>, - current: BasicBlockId<'db>, - adjustments: &[Adjustment<'db>], - ) -> Result<'db, Option>> { + place: Place, + current: BasicBlockId, + adjustments: &[Adjustment], + ) -> Result<'db, Option> { match adjustments.split_last() { Some((last, rest)) => match &last.kind { Adjust::NeverToAny => { @@ -416,7 +412,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { Rvalue::Cast( CastKind::PointerCoercion(*cast), Operand { kind: OperandKind::Copy(p), span: None }, - last.target, + last.target.clone(), ), expr_id.into(), ); @@ -430,11 +426,11 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_expr_to_place_with_borrow_adjust( &mut self, expr_id: ExprId, - place: Place<'db>, - current: BasicBlockId<'db>, - rest: &[Adjustment<'db>], + place: Place, + current: BasicBlockId, + rest: &[Adjustment], m: Mutability, - ) -> Result<'db, Option>> { + ) -> Result<'db, Option> { let Some((p, current)) = self.lower_expr_as_place_with_adjust(current, expr_id, true, rest)? else { @@ -448,9 +444,9 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_expr_to_place( &mut self, expr_id: ExprId, - place: Place<'db>, - prev_block: BasicBlockId<'db>, - ) -> Result<'db, Option>> { + place: Place, + prev_block: BasicBlockId, + ) -> Result<'db, Option> { if let Some(adjustments) = self.infer.expr_adjustments.get(&expr_id) { return self.lower_expr_to_place_with_adjust(expr_id, place, prev_block, adjustments); } @@ -460,9 +456,9 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_expr_to_place_without_adjust( &mut self, expr_id: ExprId, - place: Place<'db>, - mut current: BasicBlockId<'db>, - ) -> Result<'db, Option>> { + place: Place, + mut current: BasicBlockId, + ) -> Result<'db, Option> { match &self.body[expr_id] { Expr::OffsetOf(_) => { not_supported!("builtin#offset_of") @@ -537,7 +533,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { const_id.into(), current, place, - GenericArgs::new_from_iter(self.interner(), []), + GenericArgs::empty(self.interner()), expr_id.into(), )?; Ok(Some(current)) @@ -545,7 +541,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { ValueNs::EnumVariantId(variant_id) => { let variant_fields = variant_id.fields(self.db); if variant_fields.shape == FieldsShape::Unit { - let ty = self.infer.type_of_expr[expr_id]; + let ty = self.infer.expr_ty(expr_id); current = self.lower_enum_variant( variant_id, current, @@ -575,8 +571,9 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { konst: Const::new_param( self.interner(), ParamConst { id: p, index }, - ), - ty: self.db.const_param_ty_ns(p), + ) + .store(), + ty: self.db.const_param_ty_ns(p).store(), }, span: None, }), @@ -907,7 +904,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { operands[u32::from(field_id.into_raw()) as usize] = Some(op); } let rvalue = Rvalue::Aggregate( - AggregateKind::Adt(variant_id, subst), + AggregateKind::Adt(variant_id, subst.store()), match spread_place { Some(sp) => operands .into_iter() @@ -978,15 +975,15 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { let rvalue = if self.infer.coercion_casts.contains(expr) { Rvalue::Use(it) } else { - let source_ty = self.infer[*expr]; - let target_ty = self.infer[expr_id]; + let source_ty = self.infer.expr_ty(*expr); + let target_ty = self.infer.expr_ty(expr_id); let cast_kind = if source_ty.as_reference().is_some() { CastKind::PointerCoercion(PointerCast::ArrayToPointer) } else { cast_kind(self.db, source_ty, target_ty)? }; - Rvalue::Cast(cast_kind, it, target_ty) + Rvalue::Cast(cast_kind, it, target_ty.store()) }; self.push_assignment(current, place, rvalue, expr_id.into()); Ok(Some(current)) @@ -1004,7 +1001,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { self.push_assignment( current, place, - Rvalue::ShallowInitBoxWithAlloc(ty), + Rvalue::ShallowInitBoxWithAlloc(ty.store()), expr_id.into(), ); let Some((operand, current)) = self.lower_expr_to_some_operand(*expr, current)? @@ -1222,7 +1219,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { current, place, Rvalue::Aggregate( - AggregateKind::Adt(st.into(), subst), + AggregateKind::Adt(st.into(), subst.store()), st.fields(self.db) .fields() .iter() @@ -1284,11 +1281,10 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { }; match &capture.kind { CaptureKind::ByRef(bk) => { - let tmp_ty = capture.ty.instantiate_identity(); + let tmp_ty = capture.ty.get().instantiate_identity(); // FIXME: Handle more than one span. let capture_spans = capture.spans(); - let tmp: Place<'db> = - self.temp(tmp_ty, current, capture_spans[0])?.into(); + let tmp: Place = self.temp(tmp_ty, current, capture_spans[0])?.into(); self.push_assignment( current, tmp, @@ -1305,7 +1301,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { self.push_assignment( current, place, - Rvalue::Aggregate(AggregateKind::Closure(ty), operands.into()), + Rvalue::Aggregate(AggregateKind::Closure(ty.store()), operands.into()), expr_id.into(), ); Ok(Some(current)) @@ -1325,7 +1321,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { return Ok(None); }; let r = Rvalue::Aggregate( - AggregateKind::Tuple(self.expr_ty_without_adjust(expr_id)), + AggregateKind::Tuple(self.expr_ty_without_adjust(expr_id).store()), values, ); self.push_assignment(current, place, r, expr_id.into()); @@ -1355,7 +1351,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { else { return Ok(None); }; - let r = Rvalue::Aggregate(AggregateKind::Array(elem_ty), values); + let r = Rvalue::Aggregate(AggregateKind::Array(elem_ty.store()), values); self.push_assignment(current, place, r, expr_id.into()); Ok(Some(current)) } @@ -1373,7 +1369,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { )); } }; - let r = Rvalue::Repeat(init, len); + let r = Rvalue::Repeat(init, len.store()); self.push_assignment(current, place, r, expr_id.into()); Ok(Some(current)) } @@ -1388,11 +1384,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { } } - fn push_field_projection( - &mut self, - place: &mut Place<'db>, - expr_id: ExprId, - ) -> Result<'db, ()> { + fn push_field_projection(&mut self, place: &mut Place, expr_id: ExprId) -> Result<'db, ()> { if let Expr::Field { expr, name } = &self.body[expr_id] { if let TyKind::Tuple(..) = self.expr_ty_after_adjustments(*expr).kind() { let index = @@ -1421,7 +1413,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { &mut self, ty: Ty<'db>, loc: &ExprId, - ) -> Result<'db, Operand<'db>> { + ) -> Result<'db, Operand> { match &self.body[*loc] { Expr::Literal(l) => self.lower_literal_to_operand(ty, l), Expr::Path(c) => { @@ -1443,7 +1435,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { ResolveValueResult::ValueNs(v, _) => { if let ValueNs::ConstId(c) = v { self.lower_const_to_operand( - GenericArgs::new_from_iter(self.interner(), []), + GenericArgs::empty(self.interner()), c.into(), ) } else { @@ -1461,10 +1453,13 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { } } - fn lower_literal_to_operand(&mut self, ty: Ty<'db>, l: &Literal) -> Result<'db, Operand<'db>> { + fn lower_literal_to_operand(&mut self, ty: Ty<'db>, l: &Literal) -> Result<'db, Operand> { let size = || { self.db - .layout_of_ty(ty, ParamEnvAndCrate { param_env: self.env, krate: self.krate() }) + .layout_of_ty( + ty.store(), + ParamEnvAndCrate { param_env: self.env, krate: self.krate() }.store(), + ) .map(|it| it.size.bytes_usize()) }; const USIZE_SIZE: usize = size_of::(); @@ -1512,15 +1507,15 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { Ok(Operand::from_concrete_const(bytes, MemoryMap::default(), ty)) } - fn new_basic_block(&mut self) -> BasicBlockId<'db> { + fn new_basic_block(&mut self) -> BasicBlockId { self.result.basic_blocks.alloc(BasicBlock::default()) } fn lower_const( &mut self, const_id: GeneralConstId, - prev_block: BasicBlockId<'db>, - place: Place<'db>, + prev_block: BasicBlockId, + place: Place, subst: GenericArgs<'db>, span: MirSpan, ) -> Result<'db, ()> { @@ -1533,8 +1528,8 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { &mut self, subst: GenericArgs<'db>, const_id: GeneralConstId, - ) -> Result<'db, Operand<'db>> { - let konst = if subst.len() != 0 { + ) -> Result<'db, Operand> { + let konst = if !subst.is_empty() { // We can't evaluate constant with substitution now, as generics are not monomorphized in lowering. Const::new_unevaluated( self.interner(), @@ -1564,13 +1559,16 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { }) .unwrap() .instantiate(self.interner(), subst); - Ok(Operand { kind: OperandKind::Constant { konst, ty }, span: None }) + Ok(Operand { + kind: OperandKind::Constant { konst: konst.store(), ty: ty.store() }, + span: None, + }) } fn write_bytes_to_place( &mut self, - prev_block: BasicBlockId<'db>, - place: Place<'db>, + prev_block: BasicBlockId, + place: Place, cv: Box<[u8]>, ty: Ty<'db>, span: MirSpan, @@ -1582,12 +1580,12 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_enum_variant( &mut self, variant_id: EnumVariantId, - prev_block: BasicBlockId<'db>, - place: Place<'db>, + prev_block: BasicBlockId, + place: Place, ty: Ty<'db>, - fields: Box<[Operand<'db>]>, + fields: Box<[Operand]>, span: MirSpan, - ) -> Result<'db, BasicBlockId<'db>> { + ) -> Result<'db, BasicBlockId> { let subst = match ty.kind() { TyKind::Adt(_, subst) => subst, _ => implementation_error!("Non ADT enum"), @@ -1595,7 +1593,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { self.push_assignment( prev_block, place, - Rvalue::Aggregate(AggregateKind::Adt(variant_id.into(), subst), fields), + Rvalue::Aggregate(AggregateKind::Adt(variant_id.into(), subst.store()), fields), span, ); Ok(prev_block) @@ -1603,13 +1601,13 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_call_and_args( &mut self, - func: Operand<'db>, + func: Operand, args: impl Iterator, - place: Place<'db>, - mut current: BasicBlockId<'db>, + place: Place, + mut current: BasicBlockId, is_uninhabited: bool, span: MirSpan, - ) -> Result<'db, Option>> { + ) -> Result<'db, Option> { let Some(args) = args .map(|arg| { if let Some((temp, c)) = self.lower_expr_to_some_operand(arg, current)? { @@ -1628,13 +1626,13 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_call( &mut self, - func: Operand<'db>, - args: Box<[Operand<'db>]>, - place: Place<'db>, - current: BasicBlockId<'db>, + func: Operand, + args: Box<[Operand]>, + place: Place, + current: BasicBlockId, is_uninhabited: bool, span: MirSpan, - ) -> Result<'db, Option>> { + ) -> Result<'db, Option> { let b = if is_uninhabited { None } else { Some(self.new_basic_block()) }; self.set_terminator( current, @@ -1651,25 +1649,20 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { Ok(b) } - fn is_unterminated(&mut self, source: BasicBlockId<'db>) -> bool { + fn is_unterminated(&mut self, source: BasicBlockId) -> bool { self.result.basic_blocks[source].terminator.is_none() } - fn set_terminator( - &mut self, - source: BasicBlockId<'db>, - terminator: TerminatorKind<'db>, - span: MirSpan, - ) { + fn set_terminator(&mut self, source: BasicBlockId, terminator: TerminatorKind, span: MirSpan) { self.result.basic_blocks[source].terminator = Some(Terminator { span, kind: terminator }); } - fn set_goto(&mut self, source: BasicBlockId<'db>, target: BasicBlockId<'db>, span: MirSpan) { + fn set_goto(&mut self, source: BasicBlockId, target: BasicBlockId, span: MirSpan) { self.set_terminator(source, TerminatorKind::Goto { target }, span); } fn expr_ty_without_adjust(&self, e: ExprId) -> Ty<'db> { - self.infer[e] + self.infer.expr_ty(e) } fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty<'db> { @@ -1677,36 +1670,36 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { if let Some(it) = self.infer.expr_adjustments.get(&e) && let Some(it) = it.last() { - ty = Some(it.target); + ty = Some(it.target.as_ref()); } ty.unwrap_or_else(|| self.expr_ty_without_adjust(e)) } - fn push_statement(&mut self, block: BasicBlockId<'db>, statement: Statement<'db>) { + fn push_statement(&mut self, block: BasicBlockId, statement: Statement) { self.result.basic_blocks[block].statements.push(statement); } - fn push_fake_read(&mut self, block: BasicBlockId<'db>, p: Place<'db>, span: MirSpan) { + fn push_fake_read(&mut self, block: BasicBlockId, p: Place, span: MirSpan) { self.push_statement(block, StatementKind::FakeRead(p).with_span(span)); } fn push_assignment( &mut self, - block: BasicBlockId<'db>, - place: Place<'db>, - rvalue: Rvalue<'db>, + block: BasicBlockId, + place: Place, + rvalue: Rvalue, span: MirSpan, ) { self.push_statement(block, StatementKind::Assign(place, rvalue).with_span(span)); } - fn discr_temp_place(&mut self, current: BasicBlockId<'db>) -> Place<'db> { + fn discr_temp_place(&mut self, current: BasicBlockId) -> Place { match &self.discr_temp { Some(it) => *it, None => { // FIXME: rustc's ty is dependent on the adt type, maybe we need to do that as well let discr_ty = Ty::new_int(self.interner(), rustc_type_ir::IntTy::I128); - let tmp: Place<'db> = self + let tmp: Place = self .temp(discr_ty, current, MirSpan::Unknown) .expect("discr_ty is never unsized") .into(); @@ -1718,12 +1711,12 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_loop( &mut self, - prev_block: BasicBlockId<'db>, - place: Place<'db>, + prev_block: BasicBlockId, + place: Place, label: Option, span: MirSpan, - f: impl FnOnce(&mut MirLowerCtx<'_, 'db>, BasicBlockId<'db>) -> Result<'db, ()>, - ) -> Result<'db, Option>> { + f: impl FnOnce(&mut MirLowerCtx<'_, 'db>, BasicBlockId) -> Result<'db, ()>, + ) -> Result<'db, Option> { let begin = self.new_basic_block(); let prev = self.current_loop_blocks.replace(LoopBlocks { begin, @@ -1758,10 +1751,10 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn merge_blocks( &mut self, - b1: Option>, - b2: Option>, + b1: Option, + b2: Option, span: MirSpan, - ) -> Option> { + ) -> Option { match (b1, b2) { (None, None) => None, (None, Some(b)) | (Some(b), None) => Some(b), @@ -1774,7 +1767,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { } } - fn current_loop_end(&mut self) -> Result<'db, BasicBlockId<'db>> { + fn current_loop_end(&mut self) -> Result<'db, BasicBlockId> { let r = match self .current_loop_blocks .as_mut() @@ -1801,7 +1794,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn is_uninhabited(&self, expr_id: ExprId) -> bool { is_ty_uninhabited_from( &self.infcx, - self.infer[expr_id], + self.infer.expr_ty(expr_id), self.owner.module(self.db), self.env, ) @@ -1809,15 +1802,15 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { /// This function push `StorageLive` statement for the binding, and applies changes to add `StorageDead` and /// `Drop` in the appropriated places. - fn push_storage_live(&mut self, b: BindingId, current: BasicBlockId<'db>) -> Result<'db, ()> { + fn push_storage_live(&mut self, b: BindingId, current: BasicBlockId) -> Result<'db, ()> { let l = self.binding_local(b)?; self.push_storage_live_for_local(l, current, MirSpan::BindingId(b)) } fn push_storage_live_for_local( &mut self, - l: LocalId<'db>, - current: BasicBlockId<'db>, + l: LocalId, + current: BasicBlockId, span: MirSpan, ) -> Result<'db, ()> { self.drop_scopes.last_mut().unwrap().locals.push(l); @@ -1828,11 +1821,11 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn lower_block_to_place( &mut self, statements: &[hir_def::hir::Statement], - mut current: BasicBlockId<'db>, + mut current: BasicBlockId, tail: Option, - place: Place<'db>, + place: Place, span: MirSpan, - ) -> Result<'db, Option>>> { + ) -> Result<'db, Option>> { let scope = self.push_drop_scope(); for statement in statements.iter() { match statement { @@ -1908,11 +1901,11 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { params: impl Iterator)> + Clone, self_binding: Option<(BindingId, Ty<'db>)>, pick_binding: impl Fn(BindingId) -> bool, - ) -> Result<'db, BasicBlockId<'db>> { + ) -> Result<'db, BasicBlockId> { let base_param_count = self.result.param_locals.len(); let self_binding = match self_binding { Some((self_binding, ty)) => { - let local_id = self.result.locals.alloc(Local { ty }); + let local_id = self.result.locals.alloc(Local { ty: ty.store() }); self.drop_scopes.last_mut().unwrap().locals.push(local_id); self.result.binding_locals.insert(self_binding, local_id); self.result.param_locals.push(local_id); @@ -1921,7 +1914,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { None => None, }; self.result.param_locals.extend(params.clone().map(|(it, ty)| { - let local_id = self.result.locals.alloc(Local { ty }); + let local_id = self.result.locals.alloc(Local { ty: ty.store() }); self.drop_scopes.last_mut().unwrap().locals.push(local_id); if let Pat::Bind { id, subpat: None } = self.body[it] && matches!( @@ -1939,9 +1932,10 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { continue; } if !self.result.binding_locals.contains_idx(id) { - self.result - .binding_locals - .insert(id, self.result.locals.alloc(Local { ty: self.infer[id] })); + self.result.binding_locals.insert( + id, + self.result.locals.alloc(Local { ty: self.infer.binding_ty(id).store() }), + ); } } let mut current = self.result.start_block; @@ -1976,7 +1970,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { Ok(current) } - fn binding_local(&self, b: BindingId) -> Result<'db, LocalId<'db>> { + fn binding_local(&self, b: BindingId) -> Result<'db, LocalId> { match self.result.binding_locals.get(b) { Some(it) => Ok(*it), None => { @@ -2025,9 +2019,9 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn drop_until_scope( &mut self, scope_index: usize, - mut current: BasicBlockId<'db>, + mut current: BasicBlockId, span: MirSpan, - ) -> BasicBlockId<'db> { + ) -> BasicBlockId { for scope in self.drop_scopes[scope_index..].to_vec().iter().rev() { self.emit_drop_and_storage_dead_for_scope(scope, &mut current, span); } @@ -2047,9 +2041,9 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { /// Don't call directly fn pop_drop_scope_internal( &mut self, - mut current: BasicBlockId<'db>, + mut current: BasicBlockId, span: MirSpan, - ) -> BasicBlockId<'db> { + ) -> BasicBlockId { let scope = self.drop_scopes.pop().unwrap(); self.emit_drop_and_storage_dead_for_scope(&scope, &mut current, span); current @@ -2057,9 +2051,9 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn pop_drop_scope_assert_finished( &mut self, - mut current: BasicBlockId<'db>, + mut current: BasicBlockId, span: MirSpan, - ) -> Result<'db, BasicBlockId<'db>> { + ) -> Result<'db, BasicBlockId> { current = self.pop_drop_scope_internal(current, span); if !self.drop_scopes.is_empty() { implementation_error!("Mismatched count between drop scope push and pops"); @@ -2069,12 +2063,13 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { fn emit_drop_and_storage_dead_for_scope( &mut self, - scope: &DropScope<'db>, - current: &mut Idx>, + scope: &DropScope, + current: &mut Idx, span: MirSpan, ) { for &l in scope.locals.iter().rev() { - if !self.infcx.type_is_copy_modulo_regions(self.env, self.result.locals[l].ty) { + if !self.infcx.type_is_copy_modulo_regions(self.env, self.result.locals[l].ty.as_ref()) + { let prev = std::mem::replace(current, self.new_basic_block()); self.set_terminator( prev, @@ -2112,36 +2107,37 @@ fn cast_kind<'db>( pub fn mir_body_for_closure_query<'db>( db: &'db dyn HirDatabase, closure: InternedClosureId, -) -> Result<'db, Arc>> { +) -> Result<'db, Arc> { let InternedClosure(owner, expr) = db.lookup_intern_closure(closure); let body = db.body(owner); let infer = InferenceResult::for_body(db, owner); let Expr::Closure { args, body: root, .. } = &body[expr] else { implementation_error!("closure expression is not closure"); }; - let crate::next_solver::TyKind::Closure(_, substs) = infer[expr].kind() else { + let crate::next_solver::TyKind::Closure(_, substs) = infer.expr_ty(expr).kind() else { implementation_error!("closure expression is not closure"); }; let (captures, kind) = infer.closure_info(closure); let mut ctx = MirLowerCtx::new(db, owner, &body, infer); // 0 is return local - ctx.result.locals.alloc(Local { ty: infer[*root] }); + ctx.result.locals.alloc(Local { ty: infer.expr_ty(*root).store() }); let closure_local = ctx.result.locals.alloc(Local { ty: match kind { - FnTrait::FnOnce | FnTrait::AsyncFnOnce => infer[expr], + FnTrait::FnOnce | FnTrait::AsyncFnOnce => infer.expr_ty(expr), FnTrait::FnMut | FnTrait::AsyncFnMut => Ty::new_ref( ctx.interner(), Region::error(ctx.interner()), - infer[expr], + infer.expr_ty(expr), Mutability::Mut, ), FnTrait::Fn | FnTrait::AsyncFn => Ty::new_ref( ctx.interner(), Region::error(ctx.interner()), - infer[expr], + infer.expr_ty(expr), Mutability::Not, ), - }, + } + .store(), }); ctx.result.param_locals.push(closure_local); let Some(sig) = @@ -2160,8 +2156,7 @@ pub fn mir_body_for_closure_query<'db>( let current = ctx.pop_drop_scope_assert_finished(current, root.into())?; ctx.set_terminator(current, TerminatorKind::Return, (*root).into()); } - let mut upvar_map: FxHashMap, Vec<(&CapturedItem<'_>, usize)>> = - FxHashMap::default(); + let mut upvar_map: FxHashMap> = FxHashMap::default(); for (i, capture) in captures.iter().enumerate() { let local = ctx.binding_local(capture.place.local)?; upvar_map.entry(local).or_default().push((capture, i)); @@ -2226,7 +2221,7 @@ pub fn mir_body_for_closure_query<'db>( pub fn mir_body_query<'db>( db: &'db dyn HirDatabase, def: DefWithBodyId, -) -> Result<'db, Arc>> { +) -> Result<'db, Arc> { let krate = def.krate(db); let edition = krate.data(db).edition; let detail = match def { @@ -2263,7 +2258,7 @@ pub(crate) fn mir_body_cycle_result<'db>( _db: &'db dyn HirDatabase, _: salsa::Id, _def: DefWithBodyId, -) -> Result<'db, Arc>> { +) -> Result<'db, Arc> { Err(MirLowerError::Loop) } @@ -2271,17 +2266,17 @@ pub fn lower_to_mir<'db>( db: &'db dyn HirDatabase, owner: DefWithBodyId, body: &Body, - infer: &InferenceResult<'db>, + infer: &InferenceResult, // FIXME: root_expr should always be the body.body_expr, but since `X` in `[(); X]` doesn't have its own specific body yet, we // need to take this input explicitly. root_expr: ExprId, -) -> Result<'db, MirBody<'db>> { +) -> Result<'db, MirBody> { if infer.type_mismatches().next().is_some() || infer.is_erroneous() { return Err(MirLowerError::HasErrors); } let mut ctx = MirLowerCtx::new(db, owner, body, infer); // 0 is return local - ctx.result.locals.alloc(Local { ty: ctx.expr_ty_after_adjustments(root_expr) }); + ctx.result.locals.alloc(Local { ty: ctx.expr_ty_after_adjustments(root_expr).store() }); let binding_picker = |b: BindingId| { let owner = ctx.body.binding_owner(b); if root_expr == body.body_expr { owner.is_none() } else { owner == Some(root_expr) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs index 40c6c5de795a..cf05ec27ac37 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs @@ -20,8 +20,8 @@ impl<'db> MirLowerCtx<'_, 'db> { fn lower_expr_to_some_place_without_adjust( &mut self, expr_id: ExprId, - prev_block: BasicBlockId<'db>, - ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> { + prev_block: BasicBlockId, + ) -> Result<'db, Option<(Place, BasicBlockId)>> { let ty = self.expr_ty_without_adjust(expr_id); let place = self.temp(ty, prev_block, expr_id.into())?; let Some(current) = @@ -35,12 +35,12 @@ impl<'db> MirLowerCtx<'_, 'db> { fn lower_expr_to_some_place_with_adjust( &mut self, expr_id: ExprId, - prev_block: BasicBlockId<'db>, - adjustments: &[Adjustment<'db>], - ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> { + prev_block: BasicBlockId, + adjustments: &[Adjustment], + ) -> Result<'db, Option<(Place, BasicBlockId)>> { let ty = adjustments .last() - .map(|it| it.target) + .map(|it| it.target.as_ref()) .unwrap_or_else(|| self.expr_ty_without_adjust(expr_id)); let place = self.temp(ty, prev_block, expr_id.into())?; let Some(current) = @@ -53,11 +53,11 @@ impl<'db> MirLowerCtx<'_, 'db> { pub(super) fn lower_expr_as_place_with_adjust( &mut self, - current: BasicBlockId<'db>, + current: BasicBlockId, expr_id: ExprId, upgrade_rvalue: bool, - adjustments: &[Adjustment<'db>], - ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> { + adjustments: &[Adjustment], + ) -> Result<'db, Option<(Place, BasicBlockId)>> { let try_rvalue = |this: &mut MirLowerCtx<'_, 'db>| { if !upgrade_rvalue { return Err(MirLowerError::MutatingRvalue); @@ -93,9 +93,9 @@ impl<'db> MirLowerCtx<'_, 'db> { current, r, rest.last() - .map(|it| it.target) + .map(|it| it.target.as_ref()) .unwrap_or_else(|| self.expr_ty_without_adjust(expr_id)), - last.target, + last.target.as_ref(), expr_id.into(), match od.0 { Some(Mutability::Mut) => true, @@ -115,10 +115,10 @@ impl<'db> MirLowerCtx<'_, 'db> { pub(super) fn lower_expr_as_place( &mut self, - current: BasicBlockId<'db>, + current: BasicBlockId, expr_id: ExprId, upgrade_rvalue: bool, - ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> { + ) -> Result<'db, Option<(Place, BasicBlockId)>> { match self.infer.expr_adjustments.get(&expr_id) { Some(a) => self.lower_expr_as_place_with_adjust(current, expr_id, upgrade_rvalue, a), None => self.lower_expr_as_place_without_adjust(current, expr_id, upgrade_rvalue), @@ -127,10 +127,10 @@ impl<'db> MirLowerCtx<'_, 'db> { pub(super) fn lower_expr_as_place_without_adjust( &mut self, - current: BasicBlockId<'db>, + current: BasicBlockId, expr_id: ExprId, upgrade_rvalue: bool, - ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> { + ) -> Result<'db, Option<(Place, BasicBlockId)>> { let try_rvalue = |this: &mut MirLowerCtx<'_, 'db>| { if !upgrade_rvalue { return Err(MirLowerError::MutatingRvalue); @@ -159,7 +159,7 @@ impl<'db> MirLowerCtx<'_, 'db> { ty, Mutability::Not, ); - let temp: Place<'db> = self.temp(ref_ty, current, expr_id.into())?.into(); + let temp: Place = self.temp(ref_ty, current, expr_id.into())?.into(); self.push_assignment( current, temp, @@ -279,21 +279,21 @@ impl<'db> MirLowerCtx<'_, 'db> { fn lower_overloaded_index( &mut self, - current: BasicBlockId<'db>, - place: Place<'db>, + current: BasicBlockId, + place: Place, base_ty: Ty<'db>, result_ty: Ty<'db>, - index_operand: Operand<'db>, + index_operand: Operand, span: MirSpan, index_fn: (FunctionId, GenericArgs<'db>), - ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> { + ) -> Result<'db, Option<(Place, BasicBlockId)>> { let mutability = match base_ty.as_reference() { Some((_, _, mutability)) => mutability, None => Mutability::Not, }; let result_ref = Ty::new_ref(self.interner(), Region::error(self.interner()), result_ty, mutability); - let mut result: Place<'db> = self.temp(result_ref, current, span)?.into(); + let mut result: Place = self.temp(result_ref, current, span)?.into(); let index_fn_op = Operand::const_zst(Ty::new_fn_def( self.interner(), CallableDefId::FunctionId(index_fn.0).into(), @@ -316,13 +316,13 @@ impl<'db> MirLowerCtx<'_, 'db> { fn lower_overloaded_deref( &mut self, - current: BasicBlockId<'db>, - place: Place<'db>, + current: BasicBlockId, + place: Place, source_ty: Ty<'db>, target_ty: Ty<'db>, span: MirSpan, mutability: bool, - ) -> Result<'db, Option<(Place<'db>, BasicBlockId<'db>)>> { + ) -> Result<'db, Option<(Place, BasicBlockId)>> { let lang_items = self.lang_items(); let (mutability, trait_lang_item, trait_method_name, borrow_kind) = if !mutability { ( @@ -342,7 +342,7 @@ impl<'db> MirLowerCtx<'_, 'db> { let error_region = Region::error(self.interner()); let ty_ref = Ty::new_ref(self.interner(), error_region, source_ty, mutability); let target_ty_ref = Ty::new_ref(self.interner(), error_region, target_ty, mutability); - let ref_place: Place<'db> = self.temp(ty_ref, current, span)?.into(); + let ref_place: Place = self.temp(ty_ref, current, span)?.into(); self.push_assignment(current, ref_place, Rvalue::Ref(borrow_kind, place), span); let deref_trait = trait_lang_item.ok_or(MirLowerError::LangItemNotFound)?; let deref_fn = deref_trait @@ -352,9 +352,9 @@ impl<'db> MirLowerCtx<'_, 'db> { let deref_fn_op = Operand::const_zst(Ty::new_fn_def( self.interner(), CallableDefId::FunctionId(deref_fn).into(), - GenericArgs::new_from_iter(self.interner(), [source_ty.into()]), + GenericArgs::new_from_slice(&[source_ty.into()]), )); - let mut result: Place<'db> = self.temp(target_ty_ref, current, span)?.into(); + let mut result: Place = self.temp(target_ty_ref, current, span)?.into(); let Some(current) = self.lower_call( deref_fn_op, Box::new([Operand { kind: OperandKind::Copy(ref_place), span: None }]), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs index c3a4814a3ab4..a8aacbff16fa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -1,7 +1,7 @@ //! MIR lowering for patterns use hir_def::{hir::ExprId, signatures::VariantFields}; -use rustc_type_ir::inherent::{IntoKind, SliceLike, Ty as _}; +use rustc_type_ir::inherent::{IntoKind, Ty as _}; use crate::{ BindingMode, @@ -63,11 +63,11 @@ impl<'db> MirLowerCtx<'_, 'db> { /// so it should be an empty block. pub(super) fn pattern_match( &mut self, - current: BasicBlockId<'db>, - current_else: Option>, - cond_place: Place<'db>, + current: BasicBlockId, + current_else: Option, + cond_place: Place, pattern: PatId, - ) -> Result<'db, (BasicBlockId<'db>, Option>)> { + ) -> Result<'db, (BasicBlockId, Option)> { let (current, current_else) = self.pattern_match_inner( current, current_else, @@ -87,10 +87,10 @@ impl<'db> MirLowerCtx<'_, 'db> { pub(super) fn pattern_match_assignment( &mut self, - current: BasicBlockId<'db>, - value: Place<'db>, + current: BasicBlockId, + value: Place, pattern: PatId, - ) -> Result<'db, BasicBlockId<'db>> { + ) -> Result<'db, BasicBlockId> { let (current, _) = self.pattern_match_inner(current, None, value, pattern, MatchingMode::Assign)?; Ok(current) @@ -99,9 +99,9 @@ impl<'db> MirLowerCtx<'_, 'db> { pub(super) fn match_self_param( &mut self, id: BindingId, - current: BasicBlockId<'db>, - local: LocalId<'db>, - ) -> Result<'db, (BasicBlockId<'db>, Option>)> { + current: BasicBlockId, + local: LocalId, + ) -> Result<'db, (BasicBlockId, Option)> { self.pattern_match_binding( id, BindingMode::Move, @@ -114,12 +114,12 @@ impl<'db> MirLowerCtx<'_, 'db> { fn pattern_match_inner( &mut self, - mut current: BasicBlockId<'db>, - mut current_else: Option>, - mut cond_place: Place<'db>, + mut current: BasicBlockId, + mut current_else: Option, + mut cond_place: Place, pattern: PatId, mode: MatchingMode, - ) -> Result<'db, (BasicBlockId<'db>, Option>)> { + ) -> Result<'db, (BasicBlockId, Option)> { let cnt = self.infer.pat_adjustments.get(&pattern).map(|x| x.len()).unwrap_or_default(); cond_place.projection = self.result.projection_store.intern( cond_place @@ -135,7 +135,7 @@ impl<'db> MirLowerCtx<'_, 'db> { Pat::Missing => return Err(MirLowerError::IncompletePattern), Pat::Wild => (current, current_else), Pat::Tuple { args, ellipsis } => { - let subst = match self.infer[pattern].kind() { + let subst = match self.infer.pat_ty(pattern).kind() { TyKind::Tuple(s) => s, _ => { return Err(MirLowerError::TypeError( @@ -209,10 +209,11 @@ impl<'db> MirLowerCtx<'_, 'db> { } Pat::Range { start, end, range_type: _ } => { let mut add_check = |l: &ExprId, binop| -> Result<'db, ()> { - let lv = self.lower_literal_or_const_to_operand(self.infer[pattern], l)?; + let lv = + self.lower_literal_or_const_to_operand(self.infer.pat_ty(pattern), l)?; let else_target = *current_else.get_or_insert_with(|| self.new_basic_block()); let next = self.new_basic_block(); - let discr: Place<'db> = + let discr: Place = self.temp(Ty::new_bool(self.interner()), current, pattern.into())?.into(); self.push_assignment( current, @@ -249,9 +250,9 @@ impl<'db> MirLowerCtx<'_, 'db> { Pat::Slice { prefix, slice, suffix } => { if mode == MatchingMode::Check { // emit runtime length check for slice - if let TyKind::Slice(_) = self.infer[pattern].kind() { + if let TyKind::Slice(_) = self.infer.pat_ty(pattern).kind() { let pattern_len = prefix.len() + suffix.len(); - let place_len: Place<'db> = self + let place_len: Place = self .temp(Ty::new_usize(self.interner()), current, pattern.into())? .into(); self.push_assignment( @@ -285,7 +286,7 @@ impl<'db> MirLowerCtx<'_, 'db> { MemoryMap::default(), Ty::new_usize(self.interner()), ); - let discr: Place<'db> = self + let discr: Place = self .temp(Ty::new_bool(self.interner()), current, pattern.into())? .into(); self.push_assignment( @@ -398,15 +399,15 @@ impl<'db> MirLowerCtx<'_, 'db> { break 'b (c, x.1); } if let ResolveValueResult::ValueNs(ValueNs::ConstId(c), _) = pr { - break 'b (c, GenericArgs::new_from_iter(self.interner(), [])); + break 'b (c, GenericArgs::empty(self.interner())); } not_supported!("path in pattern position that is not const or variant") }; - let tmp: Place<'db> = - self.temp(self.infer[pattern], current, pattern.into())?.into(); + let tmp: Place = + self.temp(self.infer.pat_ty(pattern), current, pattern.into())?.into(); let span = pattern.into(); self.lower_const(c.into(), current, tmp, subst, span)?; - let tmp2: Place<'db> = + let tmp2: Place = self.temp(Ty::new_bool(self.interner()), current, pattern.into())?.into(); self.push_assignment( current, @@ -434,7 +435,7 @@ impl<'db> MirLowerCtx<'_, 'db> { Pat::Lit(l) => match &self.body[*l] { Expr::Literal(l) => { if mode == MatchingMode::Check { - let c = self.lower_literal_to_operand(self.infer[pattern], l)?; + let c = self.lower_literal_to_operand(self.infer.pat_ty(pattern), l)?; self.pattern_match_const(current_else, current, c, cond_place, pattern)? } else { (current, current_else) @@ -506,11 +507,11 @@ impl<'db> MirLowerCtx<'_, 'db> { &mut self, id: BindingId, mode: BindingMode, - cond_place: Place<'db>, + cond_place: Place, span: MirSpan, - current: BasicBlockId<'db>, - current_else: Option>, - ) -> Result<'db, (BasicBlockId<'db>, Option>)> { + current: BasicBlockId, + current_else: Option, + ) -> Result<'db, (BasicBlockId, Option)> { let target_place = self.binding_local(id)?; self.push_storage_live(id, current)?; self.push_match_assignment(current, target_place, mode, cond_place, span); @@ -519,10 +520,10 @@ impl<'db> MirLowerCtx<'_, 'db> { fn push_match_assignment( &mut self, - current: BasicBlockId<'db>, - target_place: LocalId<'db>, + current: BasicBlockId, + target_place: LocalId, mode: BindingMode, - cond_place: Place<'db>, + cond_place: Place, span: MirSpan, ) { self.push_assignment( @@ -545,15 +546,15 @@ impl<'db> MirLowerCtx<'_, 'db> { fn pattern_match_const( &mut self, - current_else: Option>, - current: BasicBlockId<'db>, - c: Operand<'db>, - cond_place: Place<'db>, + current_else: Option, + current: BasicBlockId, + c: Operand, + cond_place: Place, pattern: Idx, - ) -> Result<'db, (BasicBlockId<'db>, Option>)> { + ) -> Result<'db, (BasicBlockId, Option)> { let then_target = self.new_basic_block(); let else_target = current_else.unwrap_or_else(|| self.new_basic_block()); - let discr: Place<'db> = + let discr: Place = self.temp(Ty::new_bool(self.interner()), current, pattern.into())?.into(); self.push_assignment( current, @@ -579,14 +580,14 @@ impl<'db> MirLowerCtx<'_, 'db> { fn pattern_matching_variant( &mut self, - cond_place: Place<'db>, + cond_place: Place, variant: VariantId, - mut current: BasicBlockId<'db>, + mut current: BasicBlockId, span: MirSpan, - mut current_else: Option>, + mut current_else: Option, shape: AdtPatternShape<'_>, mode: MatchingMode, - ) -> Result<'db, (BasicBlockId<'db>, Option>)> { + ) -> Result<'db, (BasicBlockId, Option)> { Ok(match variant { VariantId::EnumVariantId(v) => { if mode == MatchingMode::Check { @@ -635,11 +636,11 @@ impl<'db> MirLowerCtx<'_, 'db> { shape: AdtPatternShape<'_>, variant_data: &VariantFields, v: VariantId, - current: BasicBlockId<'db>, - current_else: Option>, - cond_place: &Place<'db>, + current: BasicBlockId, + current_else: Option, + cond_place: &Place, mode: MatchingMode, - ) -> Result<'db, (BasicBlockId<'db>, Option>)> { + ) -> Result<'db, (BasicBlockId, Option)> { Ok(match shape { AdtPatternShape::Record { args } => { let it = args @@ -678,12 +679,12 @@ impl<'db> MirLowerCtx<'_, 'db> { fn pattern_match_adt( &mut self, - mut current: BasicBlockId<'db>, - mut current_else: Option>, - args: impl Iterator, PatId)>, - cond_place: &Place<'db>, + mut current: BasicBlockId, + mut current_else: Option, + args: impl Iterator, + cond_place: &Place, mode: MatchingMode, - ) -> Result<'db, (BasicBlockId<'db>, Option>)> { + ) -> Result<'db, (BasicBlockId, Option)> { for (proj, arg) in args { let cond_place = cond_place.project(proj, &mut self.result.projection_store); (current, current_else) = @@ -694,14 +695,14 @@ impl<'db> MirLowerCtx<'_, 'db> { fn pattern_match_tuple_like( &mut self, - current: BasicBlockId<'db>, - current_else: Option>, + current: BasicBlockId, + current_else: Option, args: &[PatId], ellipsis: Option, - fields: impl DoubleEndedIterator> + Clone, - cond_place: &Place<'db>, + fields: impl DoubleEndedIterator + Clone, + cond_place: &Place, mode: MatchingMode, - ) -> Result<'db, (BasicBlockId<'db>, Option>)> { + ) -> Result<'db, (BasicBlockId, Option)> { let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize)); let it = al .iter() diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs index beb0003c31ca..5752a3d7fae4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs @@ -8,7 +8,7 @@ //! So the monomorphization should be called even if the substitution is empty. use hir_def::DefWithBodyId; -use rustc_type_ir::inherent::{IntoKind, SliceLike}; +use rustc_type_ir::inherent::IntoKind; use rustc_type_ir::{ FallibleTypeFolder, TypeFlags, TypeFoldable, TypeSuperFoldable, TypeVisitableExt, }; @@ -16,7 +16,8 @@ use triomphe::Arc; use crate::{ ParamEnvAndCrate, - next_solver::{Const, ConstKind, Region, RegionKind}, + next_solver::{Const, ConstKind, Region, RegionKind, StoredConst, StoredGenericArgs, StoredTy}, + traits::StoredParamEnvAndCrate, }; use crate::{ db::{HirDatabase, InternedClosureId}, @@ -37,7 +38,7 @@ struct Filler<'db> { } impl<'db> FallibleTypeFolder> for Filler<'db> { - type Error = MirLowerError<'db>; + type Error = MirLowerError; fn cx(&self) -> DbInterner<'db> { self.infcx.interner @@ -69,7 +70,7 @@ impl<'db> FallibleTypeFolder> for Filler<'db> { .get(param.index as usize) .and_then(|arg| arg.ty()) .ok_or_else(|| { - MirLowerError::GenericArgNotProvided(param.id.into(), self.subst) + MirLowerError::GenericArgNotProvided(param.id.into(), self.subst.store()) })?), _ => ty.try_super_fold_with(self), } @@ -79,22 +80,18 @@ impl<'db> FallibleTypeFolder> for Filler<'db> { let ConstKind::Param(param) = ct.kind() else { return ct.try_super_fold_with(self); }; - self.subst - .as_slice() - .get(param.index as usize) - .and_then(|arg| arg.konst()) - .ok_or_else(|| MirLowerError::GenericArgNotProvided(param.id.into(), self.subst)) + self.subst.as_slice().get(param.index as usize).and_then(|arg| arg.konst()).ok_or_else( + || MirLowerError::GenericArgNotProvided(param.id.into(), self.subst.store()), + ) } fn try_fold_region(&mut self, region: Region<'db>) -> Result, Self::Error> { let RegionKind::ReEarlyParam(param) = region.kind() else { return Ok(region); }; - self.subst - .as_slice() - .get(param.index as usize) - .and_then(|arg| arg.region()) - .ok_or_else(|| MirLowerError::GenericArgNotProvided(param.id.into(), self.subst)) + self.subst.as_slice().get(param.index as usize).and_then(|arg| arg.region()).ok_or_else( + || MirLowerError::GenericArgNotProvided(param.id.into(), self.subst.store()), + ) } } @@ -105,33 +102,50 @@ impl<'db> Filler<'db> { Self { infcx, trait_env: env, subst } } - fn fill> + Copy>( - &mut self, - t: &mut T, - ) -> Result<(), MirLowerError<'db>> { + fn fill_ty(&mut self, t: &mut StoredTy) -> Result<(), MirLowerError> { // Can't deep normalized as that'll try to normalize consts and fail. - *t = t.try_fold_with(self)?; - if references_non_lt_error(t) { + *t = t.as_ref().try_fold_with(self)?.store(); + if references_non_lt_error(&t.as_ref()) { Err(MirLowerError::NotSupported("monomorphization resulted in errors".to_owned())) } else { Ok(()) } } - fn fill_operand(&mut self, op: &mut Operand<'db>) -> Result<(), MirLowerError<'db>> { + fn fill_const(&mut self, t: &mut StoredConst) -> Result<(), MirLowerError> { + // Can't deep normalized as that'll try to normalize consts and fail. + *t = t.as_ref().try_fold_with(self)?.store(); + if references_non_lt_error(&t.as_ref()) { + Err(MirLowerError::NotSupported("monomorphization resulted in errors".to_owned())) + } else { + Ok(()) + } + } + + fn fill_args(&mut self, t: &mut StoredGenericArgs) -> Result<(), MirLowerError> { + // Can't deep normalized as that'll try to normalize consts and fail. + *t = t.as_ref().try_fold_with(self)?.store(); + if references_non_lt_error(&t.as_ref()) { + Err(MirLowerError::NotSupported("monomorphization resulted in errors".to_owned())) + } else { + Ok(()) + } + } + + fn fill_operand(&mut self, op: &mut Operand) -> Result<(), MirLowerError> { match &mut op.kind { OperandKind::Constant { konst, ty } => { - self.fill(konst)?; - self.fill(ty)?; + self.fill_const(konst)?; + self.fill_ty(ty)?; } OperandKind::Copy(_) | OperandKind::Move(_) | OperandKind::Static(_) => (), } Ok(()) } - fn fill_body(&mut self, body: &mut MirBody<'db>) -> Result<(), MirLowerError<'db>> { + fn fill_body(&mut self, body: &mut MirBody) -> Result<(), MirLowerError> { for (_, l) in body.locals.iter_mut() { - self.fill(&mut l.ty)?; + self.fill_ty(&mut l.ty)?; } for (_, bb) in body.basic_blocks.iter_mut() { for statement in &mut bb.statements { @@ -144,20 +158,20 @@ impl<'db> Filler<'db> { match ak { super::AggregateKind::Array(ty) | super::AggregateKind::Tuple(ty) - | super::AggregateKind::Closure(ty) => self.fill(ty)?, - super::AggregateKind::Adt(_, subst) => self.fill(subst)?, + | super::AggregateKind::Closure(ty) => self.fill_ty(ty)?, + super::AggregateKind::Adt(_, subst) => self.fill_args(subst)?, super::AggregateKind::Union(_, _) => (), } } Rvalue::ShallowInitBox(_, ty) | Rvalue::ShallowInitBoxWithAlloc(ty) => { - self.fill(ty)?; + self.fill_ty(ty)?; } Rvalue::Use(op) => { self.fill_operand(op)?; } Rvalue::Repeat(op, len) => { self.fill_operand(op)?; - self.fill(len)?; + self.fill_const(len)?; } Rvalue::Ref(_, _) | Rvalue::Len(_) @@ -208,36 +222,36 @@ impl<'db> Filler<'db> { } } -pub fn monomorphized_mir_body_query<'db>( - db: &'db dyn HirDatabase, +pub fn monomorphized_mir_body_query( + db: &dyn HirDatabase, owner: DefWithBodyId, - subst: GenericArgs<'db>, - trait_env: ParamEnvAndCrate<'db>, -) -> Result>, MirLowerError<'db>> { - let mut filler = Filler::new(db, trait_env, subst); + subst: StoredGenericArgs, + trait_env: StoredParamEnvAndCrate, +) -> Result, MirLowerError> { + let mut filler = Filler::new(db, trait_env.as_ref(), subst.as_ref()); let body = db.mir_body(owner)?; let mut body = (*body).clone(); filler.fill_body(&mut body)?; Ok(Arc::new(body)) } -pub(crate) fn monomorphized_mir_body_cycle_result<'db>( - _db: &'db dyn HirDatabase, +pub(crate) fn monomorphized_mir_body_cycle_result( + _db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId, - _: GenericArgs<'db>, - _: ParamEnvAndCrate<'db>, -) -> Result>, MirLowerError<'db>> { + _: StoredGenericArgs, + _: StoredParamEnvAndCrate, +) -> Result, MirLowerError> { Err(MirLowerError::Loop) } -pub fn monomorphized_mir_body_for_closure_query<'db>( - db: &'db dyn HirDatabase, +pub fn monomorphized_mir_body_for_closure_query( + db: &dyn HirDatabase, closure: InternedClosureId, - subst: GenericArgs<'db>, - trait_env: ParamEnvAndCrate<'db>, -) -> Result>, MirLowerError<'db>> { - let mut filler = Filler::new(db, trait_env, subst); + subst: StoredGenericArgs, + trait_env: StoredParamEnvAndCrate, +) -> Result, MirLowerError> { + let mut filler = Filler::new(db, trait_env.as_ref(), subst.as_ref()); let body = db.mir_body_for_closure(closure)?; let mut body = (*body).clone(); filler.fill_body(&mut body)?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs index 0c5a64935e49..96b90a3f4074 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs @@ -36,8 +36,8 @@ macro_rules! wln { }; } -impl<'db> MirBody<'db> { - pub fn pretty_print(&self, db: &'db dyn HirDatabase, display_target: DisplayTarget) -> String { +impl MirBody { + pub fn pretty_print(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String { let hir_body = db.body(self.owner); let mut ctx = MirPrettyCtx::new(self, &hir_body, db, display_target); ctx.for_body(|this| match ctx.body.owner { @@ -80,7 +80,7 @@ impl<'db> MirBody<'db> { // String with lines is rendered poorly in `dbg` macros, which I use very much, so this // function exists to solve that. - pub fn dbg(&self, db: &'db dyn HirDatabase, display_target: DisplayTarget) -> impl Debug { + pub fn dbg(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> impl Debug { struct StringDbg(String); impl Debug for StringDbg { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -92,12 +92,12 @@ impl<'db> MirBody<'db> { } struct MirPrettyCtx<'a, 'db> { - body: &'a MirBody<'db>, + body: &'a MirBody, hir_body: &'a Body, db: &'db dyn HirDatabase, result: String, indent: String, - local_to_binding: ArenaMap, BindingId>, + local_to_binding: ArenaMap, display_target: DisplayTarget, } @@ -113,12 +113,12 @@ impl Write for MirPrettyCtx<'_, '_> { } } -enum LocalName<'db> { - Unknown(LocalId<'db>), - Binding(Name, LocalId<'db>), +enum LocalName { + Unknown(LocalId), + Binding(Name, LocalId), } -impl<'db> HirDisplay<'db> for LocalName<'db> { +impl<'db> HirDisplay<'db> for LocalName { fn hir_fmt( &self, f: &mut crate::display::HirFormatter<'_, 'db>, @@ -179,7 +179,7 @@ impl<'a, 'db> MirPrettyCtx<'a, 'db> { } fn new( - body: &'a MirBody<'db>, + body: &'a MirBody, hir_body: &'a Body, db: &'db dyn HirDatabase, display_target: DisplayTarget, @@ -211,19 +211,19 @@ impl<'a, 'db> MirPrettyCtx<'a, 'db> { self, "let {}: {};", self.local_name(id).display_test(self.db, self.display_target), - self.hir_display(&local.ty) + self.hir_display(&local.ty.as_ref()) ); } } - fn local_name(&self, local: LocalId<'db>) -> LocalName<'db> { + fn local_name(&self, local: LocalId) -> LocalName { match self.local_to_binding.get(local) { Some(b) => LocalName::Binding(self.hir_body[*b].name.clone(), local), None => LocalName::Unknown(local), } } - fn basic_block_id(&self, basic_block_id: BasicBlockId<'db>) -> String { + fn basic_block_id(&self, basic_block_id: BasicBlockId) -> String { format!("'bb{}", u32::from(basic_block_id.into_raw())) } @@ -311,12 +311,8 @@ impl<'a, 'db> MirPrettyCtx<'a, 'db> { } } - fn place(&mut self, p: &Place<'db>) { - fn f<'db>( - this: &mut MirPrettyCtx<'_, 'db>, - local: LocalId<'db>, - projections: &[PlaceElem<'db>], - ) { + fn place(&mut self, p: &Place) { + fn f<'db>(this: &mut MirPrettyCtx<'_, 'db>, local: LocalId, projections: &[PlaceElem]) { let Some((last, head)) = projections.split_last() else { // no projection w!(this, "{}", this.local_name(local).display_test(this.db, this.display_target)); @@ -376,19 +372,21 @@ impl<'a, 'db> MirPrettyCtx<'a, 'db> { f(self, p.local, p.projection.lookup(&self.body.projection_store)); } - fn operand(&mut self, r: &Operand<'db>) { + fn operand(&mut self, r: &Operand) { match &r.kind { OperandKind::Copy(p) | OperandKind::Move(p) => { // MIR at the time of writing doesn't have difference between move and copy, so we show them // equally. Feel free to change it. self.place(p); } - OperandKind::Constant { konst, .. } => w!(self, "Const({})", self.hir_display(konst)), + OperandKind::Constant { konst, .. } => { + w!(self, "Const({})", self.hir_display(&konst.as_ref())) + } OperandKind::Static(s) => w!(self, "Static({:?})", s), } } - fn rvalue(&mut self, r: &Rvalue<'db>) { + fn rvalue(&mut self, r: &Rvalue) { match r { Rvalue::Use(op) => self.operand(op), Rvalue::Ref(r, p) => { @@ -415,7 +413,7 @@ impl<'a, 'db> MirPrettyCtx<'a, 'db> { Rvalue::Repeat(op, len) => { w!(self, "["); self.operand(op); - w!(self, "; {}]", len.display_test(self.db, self.display_target)); + w!(self, "; {}]", len.as_ref().display_test(self.db, self.display_target)); } Rvalue::Aggregate(AggregateKind::Adt(_, _), it) => { w!(self, "Adt("); @@ -440,7 +438,7 @@ impl<'a, 'db> MirPrettyCtx<'a, 'db> { Rvalue::Cast(ck, op, ty) => { w!(self, "Cast({ck:?}, "); self.operand(op); - w!(self, ", {})", self.hir_display(ty)); + w!(self, ", {})", self.hir_display(&ty.as_ref())); } Rvalue::CheckedBinaryOp(b, o1, o2) => { self.operand(o1); @@ -478,7 +476,7 @@ impl<'a, 'db> MirPrettyCtx<'a, 'db> { } } - fn operand_list(&mut self, it: &[Operand<'db>]) { + fn operand_list(&mut self, it: &[Operand]) { let mut it = it.iter(); if let Some(first) = it.next() { self.operand(first); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs index 8c52a847d1e9..539d09a8f5df 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs @@ -1,6 +1,7 @@ //! Things relevant to the next trait solver. pub mod abi; +mod binder; mod consts; mod def_id; pub mod fold; @@ -21,6 +22,7 @@ mod structural_normalize; mod ty; pub mod util; +pub use binder::*; pub use consts::*; pub use def_id::*; pub use generic_arg::*; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/binder.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/binder.rs new file mode 100644 index 000000000000..3645f8096cfd --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/binder.rs @@ -0,0 +1,83 @@ +use crate::{ + FnAbi, + next_solver::{ + Binder, Clauses, EarlyBinder, FnSig, PolyFnSig, StoredBoundVarKinds, StoredClauses, + StoredTy, StoredTys, Ty, abi::Safety, + }, +}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct StoredEarlyBinder(T); + +impl StoredEarlyBinder { + #[inline] + pub fn bind(value: T) -> Self { + Self(value) + } + + #[inline] + pub fn skip_binder(self) -> T { + self.0 + } + + #[inline] + pub fn as_ref(&self) -> StoredEarlyBinder<&T> { + StoredEarlyBinder(&self.0) + } + + #[inline] + pub fn get_with<'db, 'a, R>(&'a self, f: impl FnOnce(&'a T) -> R) -> EarlyBinder<'db, R> { + EarlyBinder::bind(f(&self.0)) + } +} + +impl StoredEarlyBinder { + #[inline] + pub fn get<'db>(&self) -> EarlyBinder<'db, Ty<'db>> { + self.get_with(|it| it.as_ref()) + } +} + +impl StoredEarlyBinder { + #[inline] + pub fn get<'db>(&self) -> EarlyBinder<'db, Clauses<'db>> { + self.get_with(|it| it.as_ref()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct StoredPolyFnSig { + bound_vars: StoredBoundVarKinds, + inputs_and_output: StoredTys, + c_variadic: bool, + safety: Safety, + abi: FnAbi, +} + +impl StoredPolyFnSig { + #[inline] + pub fn new(sig: PolyFnSig<'_>) -> Self { + let bound_vars = sig.bound_vars().store(); + let sig = sig.skip_binder(); + Self { + bound_vars, + inputs_and_output: sig.inputs_and_output.store(), + c_variadic: sig.c_variadic, + safety: sig.safety, + abi: sig.abi, + } + } + + #[inline] + pub fn get(&self) -> PolyFnSig<'_> { + Binder::bind_with_vars( + FnSig { + inputs_and_output: self.inputs_and_output.as_ref(), + c_variadic: self.c_variadic, + safety: self.safety, + abi: self.abi, + }, + self.bound_vars.as_ref(), + ) + } +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs index 3a32cf8b1fef..8417e145a46d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs @@ -3,19 +3,20 @@ use std::hash::Hash; use hir_def::ConstParamId; -use macros::{TypeFoldable, TypeVisitable}; +use intern::{Interned, InternedRef, impl_internable}; +use macros::{GenericTypeVisitable, TypeFoldable, TypeVisitable}; use rustc_ast_ir::visit::VisitorResult; use rustc_type_ir::{ - BoundVar, BoundVarIndexKind, ConstVid, DebruijnIndex, FlagComputation, Flags, InferConst, - TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, - WithCachedTypeInfo, + BoundVar, BoundVarIndexKind, ConstVid, DebruijnIndex, FlagComputation, Flags, + GenericTypeVisitable, InferConst, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, WithCachedTypeInfo, inherent::{IntoKind, ParamEnv as _, PlaceholderLike, SliceLike}, relate::Relate, }; use crate::{ MemoryMap, - next_solver::{ClauseKind, ParamEnv, interner::InternedWrapperNoDebug}, + next_solver::{ClauseKind, ParamEnv, impl_stored_interned}, }; use super::{BoundVarKind, DbInterner, ErrorGuaranteed, GenericArgs, Placeholder, Ty}; @@ -23,30 +24,43 @@ use super::{BoundVarKind, DbInterner, ErrorGuaranteed, GenericArgs, Placeholder, pub type ConstKind<'db> = rustc_type_ir::ConstKind>; pub type UnevaluatedConst<'db> = rustc_type_ir::UnevaluatedConst>; -#[salsa::interned(constructor = new_, unsafe(non_update_types))] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Const<'db> { - #[returns(ref)] - kind_: InternedWrapperNoDebug>>, + pub(super) interned: InternedRef<'db, ConstInterned>, } +#[derive(PartialEq, Eq, Hash)] +#[repr(align(4))] // Required for `GenericArg` bit-tagging. +pub(super) struct ConstInterned(WithCachedTypeInfo>); + +impl_internable!(gc; ConstInterned); +impl_stored_interned!(ConstInterned, Const, StoredConst); + +const _: () = { + const fn is_copy() {} + is_copy::>(); +}; + impl<'db> Const<'db> { - pub fn new(interner: DbInterner<'db>, kind: ConstKind<'db>) -> Self { + pub fn new(_interner: DbInterner<'db>, kind: ConstKind<'db>) -> Self { + let kind = unsafe { std::mem::transmute::, ConstKind<'static>>(kind) }; let flags = FlagComputation::for_const_kind(&kind); let cached = WithCachedTypeInfo { internee: kind, flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, }; - Const::new_(interner.db(), InternedWrapperNoDebug(cached)) + Self { interned: Interned::new_gc(ConstInterned(cached)) } } pub fn inner(&self) -> &WithCachedTypeInfo> { - crate::with_attached_db(|db| { - let inner = &self.kind_(db).0; - // SAFETY: The caller already has access to a `Const<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute(inner) } - }) + let inner = &self.interned.0; + unsafe { + std::mem::transmute::< + &WithCachedTypeInfo>, + &WithCachedTypeInfo>, + >(inner) + } } pub fn error(interner: DbInterner<'db>) -> Self { @@ -106,12 +120,6 @@ impl<'db> std::fmt::Debug for Const<'db> { } } -impl<'db> std::fmt::Debug for InternedWrapperNoDebug>> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.internee.fmt(f) - } -} - pub type PlaceholderConst = Placeholder; #[derive(Copy, Clone, Hash, Eq, PartialEq)] @@ -164,7 +172,9 @@ impl ParamConst { /// A type-level constant value. /// /// Represents a typed, fully evaluated constant. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, TypeFoldable, TypeVisitable)] +#[derive( + Debug, Copy, Clone, Eq, PartialEq, Hash, TypeFoldable, TypeVisitable, GenericTypeVisitable, +)] pub struct ValueConst<'db> { pub ty: Ty<'db>, // FIXME: Should we ignore this for TypeVisitable, TypeFoldable? @@ -190,7 +200,7 @@ impl<'db> rustc_type_ir::inherent::ValueConst> for ValueConst<'d } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, GenericTypeVisitable)] pub struct ConstBytes<'db> { pub memory: Box<[u8]>, pub memory_map: MemoryMap<'db>, @@ -202,31 +212,53 @@ impl Hash for ConstBytes<'_> { } } -#[salsa::interned(constructor = new_, debug, unsafe(non_update_types))] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Valtree<'db> { - #[returns(ref)] - bytes_: ConstBytes<'db>, + interned: InternedRef<'db, ValtreeInterned>, } +impl<'db, V: super::WorldExposer> GenericTypeVisitable for Valtree<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + visitor.on_interned(self.interned); + self.inner().generic_visit_with(visitor); + } +} + +#[derive(Debug, PartialEq, Eq, Hash)] +struct ValtreeInterned { + bytes: ConstBytes<'static>, +} + +impl_internable!(gc; ValtreeInterned); + +const _: () = { + const fn is_copy() {} + is_copy::>(); +}; + impl<'db> Valtree<'db> { + #[inline] pub fn new(bytes: ConstBytes<'db>) -> Self { - crate::with_attached_db(|db| unsafe { - // SAFETY: ¯\_(ツ)_/¯ - std::mem::transmute(Valtree::new_(db, bytes)) - }) + let bytes = unsafe { std::mem::transmute::, ConstBytes<'static>>(bytes) }; + Self { interned: Interned::new_gc(ValtreeInterned { bytes }) } } + #[inline] pub fn inner(&self) -> &ConstBytes<'db> { - crate::with_attached_db(|db| { - let inner = self.bytes_(db); - // SAFETY: The caller already has access to a `Valtree<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute(inner) } - }) + let inner = &self.interned.bytes; + unsafe { std::mem::transmute::<&ConstBytes<'static>, &ConstBytes<'db>>(inner) } } } -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable)] +impl std::fmt::Debug for Valtree<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.interned.fmt(f) + } +} + +#[derive( + Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable, GenericTypeVisitable, +)] pub struct ExprConst; impl rustc_type_ir::inherent::ParamLike for ParamConst { @@ -243,6 +275,13 @@ impl<'db> IntoKind for Const<'db> { } } +impl<'db, V: super::WorldExposer> GenericTypeVisitable for Const<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + visitor.on_interned(self.interned); + self.kind().generic_visit_with(visitor); + } +} + impl<'db> TypeVisitable> for Const<'db> { fn visit_with>>( &self, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs index 40cc84e0c0ed..4a19e30c64f7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs @@ -249,7 +249,7 @@ impl<'db> FulfillmentCtxt<'db> { | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } | TypingMode::PostAnalysis => return Default::default(), }; - let stalled_coroutines = stalled_coroutines.inner(); + let stalled_coroutines = stalled_coroutines.as_slice(); if stalled_coroutines.is_empty() { return Default::default(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill/errors.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill/errors.rs index 8495af4b755e..8f798b4ade24 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill/errors.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill/errors.rs @@ -9,7 +9,7 @@ use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt}; use rustc_type_ir::{ AliasRelationDirection, AliasTermKind, HostEffectPredicate, Interner, PredicatePolarity, error::ExpectedFound, - inherent::{IntoKind, SliceLike, Span as _}, + inherent::{IntoKind, Span as _}, lang_items::SolverTraitLangItem, solve::{Certainty, GoalSource, MaybeCause, NoSolution}, }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs index 10f2ba2b119b..f31b487eaed5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs @@ -1,41 +1,209 @@ //! Things related to generic args in the next-trait-solver. +use std::{hint::unreachable_unchecked, marker::PhantomData, ptr::NonNull}; + use hir_def::{GenericDefId, GenericParamId}; -use macros::{TypeFoldable, TypeVisitable}; +use intern::InternedRef; use rustc_type_ir::{ - ClosureArgs, CollectAndApply, ConstVid, CoroutineArgs, CoroutineClosureArgs, FnSigTys, - GenericArgKind, Interner, TermKind, TyKind, TyVid, Variance, + ClosureArgs, ConstVid, CoroutineArgs, CoroutineClosureArgs, FallibleTypeFolder, FnSigTys, + GenericTypeVisitable, Interner, TyKind, TyVid, TypeFoldable, TypeFolder, TypeVisitable, + TypeVisitor, Variance, inherent::{GenericArg as _, GenericsOf, IntoKind, SliceLike, Term as _, Ty as _}, relate::{Relate, VarianceDiagInfo}, walk::TypeWalker, }; use smallvec::SmallVec; -use crate::next_solver::{PolyFnSig, interned_vec_db}; +use crate::next_solver::{ + ConstInterned, PolyFnSig, RegionInterned, TyInterned, impl_foldable_for_interned_slice, + impl_stored_interned_slice, interned_slice, +}; use super::{ Const, DbInterner, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, SolverDefId, Ty, Tys, generics::Generics, }; -#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable, salsa::Supertype)] -pub enum GenericArg<'db> { - Ty(Ty<'db>), - Lifetime(Region<'db>), - Const(Const<'db>), +pub type GenericArgKind<'db> = rustc_type_ir::GenericArgKind>; +pub type TermKind<'db> = rustc_type_ir::TermKind>; + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +struct GenericArgImpl<'db> { + ptr: NonNull<()>, + _marker: PhantomData<(Ty<'db>, Const<'db>, Region<'db>)>, +} + +unsafe impl Send for GenericArgImpl<'_> {} +unsafe impl Sync for GenericArgImpl<'_> {} + +impl<'db> GenericArgImpl<'db> { + const KIND_MASK: usize = 0b11; + const PTR_MASK: usize = !Self::KIND_MASK; + const TY_TAG: usize = 0b00; + const CONST_TAG: usize = 0b01; + const REGION_TAG: usize = 0b10; + + #[inline] + fn new_ty(ty: Ty<'db>) -> Self { + Self { + ptr: unsafe { + NonNull::new_unchecked( + ty.interned + .as_raw() + .cast::<()>() + .cast_mut() + .map_addr(|addr| addr | Self::TY_TAG), + ) + }, + _marker: PhantomData, + } + } + + #[inline] + fn new_const(ty: Const<'db>) -> Self { + Self { + ptr: unsafe { + NonNull::new_unchecked( + ty.interned + .as_raw() + .cast::<()>() + .cast_mut() + .map_addr(|addr| addr | Self::CONST_TAG), + ) + }, + _marker: PhantomData, + } + } + + #[inline] + fn new_region(ty: Region<'db>) -> Self { + Self { + ptr: unsafe { + NonNull::new_unchecked( + ty.interned + .as_raw() + .cast::<()>() + .cast_mut() + .map_addr(|addr| addr | Self::REGION_TAG), + ) + }, + _marker: PhantomData, + } + } + + #[inline] + fn kind(self) -> GenericArgKind<'db> { + let ptr = self.ptr.as_ptr().map_addr(|addr| addr & Self::PTR_MASK); + unsafe { + match self.ptr.addr().get() & Self::KIND_MASK { + Self::TY_TAG => GenericArgKind::Type(Ty { + interned: InternedRef::from_raw(ptr.cast::()), + }), + Self::CONST_TAG => GenericArgKind::Const(Const { + interned: InternedRef::from_raw(ptr.cast::()), + }), + Self::REGION_TAG => GenericArgKind::Lifetime(Region { + interned: InternedRef::from_raw(ptr.cast::()), + }), + _ => unreachable_unchecked(), + } + } + } + + #[inline] + fn term_kind(self) -> TermKind<'db> { + let ptr = self.ptr.as_ptr().map_addr(|addr| addr & Self::PTR_MASK); + unsafe { + match self.ptr.addr().get() & Self::KIND_MASK { + Self::TY_TAG => { + TermKind::Ty(Ty { interned: InternedRef::from_raw(ptr.cast::()) }) + } + Self::CONST_TAG => TermKind::Const(Const { + interned: InternedRef::from_raw(ptr.cast::()), + }), + _ => unreachable_unchecked(), + } + } + } +} + +#[derive(PartialEq, Eq, Hash)] +pub struct StoredGenericArg { + ptr: GenericArgImpl<'static>, +} + +impl Clone for StoredGenericArg { + #[inline] + fn clone(&self) -> Self { + match self.ptr.kind() { + GenericArgKind::Lifetime(it) => std::mem::forget(it.interned.to_owned()), + GenericArgKind::Type(it) => std::mem::forget(it.interned.to_owned()), + GenericArgKind::Const(it) => std::mem::forget(it.interned.to_owned()), + } + Self { ptr: self.ptr } + } +} + +impl Drop for StoredGenericArg { + #[inline] + fn drop(&mut self) { + unsafe { + match self.ptr.kind() { + GenericArgKind::Lifetime(it) => it.interned.decrement_refcount(), + GenericArgKind::Type(it) => it.interned.decrement_refcount(), + GenericArgKind::Const(it) => it.interned.decrement_refcount(), + } + } + } +} + +impl StoredGenericArg { + #[inline] + fn new(value: GenericArg<'_>) -> Self { + let result = Self { ptr: GenericArgImpl { ptr: value.ptr.ptr, _marker: PhantomData } }; + // Increase refcount. + std::mem::forget(result.clone()); + result + } + + #[inline] + pub fn as_ref<'db>(&self) -> GenericArg<'db> { + GenericArg { ptr: self.ptr } + } +} + +impl std::fmt::Debug for StoredGenericArg { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.as_ref().fmt(f) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct GenericArg<'db> { + ptr: GenericArgImpl<'db>, } impl<'db> std::fmt::Debug for GenericArg<'db> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Ty(t) => std::fmt::Debug::fmt(t, f), - Self::Lifetime(r) => std::fmt::Debug::fmt(r, f), - Self::Const(c) => std::fmt::Debug::fmt(c, f), + match self.kind() { + GenericArgKind::Type(t) => std::fmt::Debug::fmt(&t, f), + GenericArgKind::Lifetime(r) => std::fmt::Debug::fmt(&r, f), + GenericArgKind::Const(c) => std::fmt::Debug::fmt(&c, f), } } } impl<'db> GenericArg<'db> { + #[inline] + pub fn store(self) -> StoredGenericArg { + StoredGenericArg::new(self) + } + + #[inline] + pub fn kind(self) -> GenericArgKind<'db> { + self.ptr.kind() + } + pub fn ty(self) -> Option> { match self.kind() { GenericArgKind::Type(ty) => Some(ty), @@ -66,8 +234,8 @@ impl<'db> GenericArg<'db> { #[inline] pub(crate) fn expect_region(self) -> Region<'db> { - match self { - GenericArg::Lifetime(region) => region, + match self.kind() { + GenericArgKind::Lifetime(region) => region, _ => panic!("expected a region, got {self:?}"), } } @@ -87,30 +255,32 @@ impl<'db> GenericArg<'db> { } impl<'db> From> for GenericArg<'db> { + #[inline] fn from(value: Term<'db>) -> Self { - match value { - Term::Ty(ty) => GenericArg::Ty(ty), - Term::Const(c) => GenericArg::Const(c), - } + GenericArg { ptr: value.ptr } } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)] -pub enum Term<'db> { - Ty(Ty<'db>), - Const(Const<'db>), +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct Term<'db> { + ptr: GenericArgImpl<'db>, } impl<'db> std::fmt::Debug for Term<'db> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Ty(t) => std::fmt::Debug::fmt(t, f), - Self::Const(c) => std::fmt::Debug::fmt(c, f), + match self.kind() { + TermKind::Ty(t) => std::fmt::Debug::fmt(&t, f), + TermKind::Const(c) => std::fmt::Debug::fmt(&c, f), } } } impl<'db> Term<'db> { + #[inline] + pub fn kind(self) -> TermKind<'db> { + self.ptr.term_kind() + } + pub fn expect_type(&self) -> Ty<'db> { self.as_type().expect("expected a type, but found a const") } @@ -124,31 +294,108 @@ impl<'db> Term<'db> { } impl<'db> From> for GenericArg<'db> { + #[inline] fn from(value: Ty<'db>) -> Self { - Self::Ty(value) + GenericArg { ptr: GenericArgImpl::new_ty(value) } } } impl<'db> From> for GenericArg<'db> { + #[inline] fn from(value: Region<'db>) -> Self { - Self::Lifetime(value) + GenericArg { ptr: GenericArgImpl::new_region(value) } } } impl<'db> From> for GenericArg<'db> { + #[inline] fn from(value: Const<'db>) -> Self { - Self::Const(value) + GenericArg { ptr: GenericArgImpl::new_const(value) } } } impl<'db> IntoKind for GenericArg<'db> { - type Kind = GenericArgKind>; + type Kind = GenericArgKind<'db>; + #[inline] fn kind(self) -> Self::Kind { - match self { - GenericArg::Ty(ty) => GenericArgKind::Type(ty), - GenericArg::Lifetime(region) => GenericArgKind::Lifetime(region), - GenericArg::Const(c) => GenericArgKind::Const(c), + self.ptr.kind() + } +} + +impl<'db, V> GenericTypeVisitable for GenericArg<'db> +where + GenericArgKind<'db>: GenericTypeVisitable, +{ + fn generic_visit_with(&self, visitor: &mut V) { + self.kind().generic_visit_with(visitor); + } +} + +impl<'db, V> GenericTypeVisitable for Term<'db> +where + TermKind<'db>: GenericTypeVisitable, +{ + fn generic_visit_with(&self, visitor: &mut V) { + self.kind().generic_visit_with(visitor); + } +} + +impl<'db> TypeVisitable> for GenericArg<'db> { + fn visit_with>>(&self, visitor: &mut V) -> V::Result { + match self.kind() { + GenericArgKind::Lifetime(it) => it.visit_with(visitor), + GenericArgKind::Type(it) => it.visit_with(visitor), + GenericArgKind::Const(it) => it.visit_with(visitor), + } + } +} + +impl<'db> TypeVisitable> for Term<'db> { + fn visit_with>>(&self, visitor: &mut V) -> V::Result { + match self.kind() { + TermKind::Ty(it) => it.visit_with(visitor), + TermKind::Const(it) => it.visit_with(visitor), + } + } +} + +impl<'db> TypeFoldable> for GenericArg<'db> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { + Ok(match self.kind() { + GenericArgKind::Lifetime(it) => it.try_fold_with(folder)?.into(), + GenericArgKind::Type(it) => it.try_fold_with(folder)?.into(), + GenericArgKind::Const(it) => it.try_fold_with(folder)?.into(), + }) + } + + fn fold_with>>(self, folder: &mut F) -> Self { + match self.kind() { + GenericArgKind::Lifetime(it) => it.fold_with(folder).into(), + GenericArgKind::Type(it) => it.fold_with(folder).into(), + GenericArgKind::Const(it) => it.fold_with(folder).into(), + } + } +} + +impl<'db> TypeFoldable> for Term<'db> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { + Ok(match self.kind() { + TermKind::Ty(it) => it.try_fold_with(folder)?.into(), + TermKind::Const(it) => it.try_fold_with(folder)?.into(), + }) + } + + fn fold_with>>(self, folder: &mut F) -> Self { + match self.kind() { + TermKind::Ty(it) => it.fold_with(folder).into(), + TermKind::Const(it) => it.fold_with(folder).into(), } } } @@ -182,7 +429,9 @@ impl<'db> Relate> for GenericArg<'db> { } } -interned_vec_db!(GenericArgs, GenericArg); +interned_slice!(GenericArgsStorage, GenericArgs, GenericArg<'db>, GenericArg<'static>,); +impl_foldable_for_interned_slice!(GenericArgs); +impl_stored_interned_slice!(GenericArgsStorage, GenericArgs, StoredGenericArgs); impl<'db> rustc_type_ir::inherent::GenericArg> for GenericArg<'db> {} @@ -306,7 +555,7 @@ impl<'db> GenericArgs<'db> { /// A "sensible" `.split_closure_args()`, where the arguments are not in a tuple. pub fn split_closure_args_untupled(self) -> rustc_type_ir::ClosureArgsParts> { // FIXME: should use `ClosureSubst` when possible - match self.inner().as_slice() { + match self.as_slice() { [parent_args @ .., closure_kind_ty, sig_ty, tupled_upvars_ty] => { let interner = DbInterner::conjure(); rustc_type_ir::ClosureArgsParts { @@ -341,8 +590,8 @@ impl<'db> rustc_type_ir::relate::Relate> for GenericArgs<'db> { a: Self, b: Self, ) -> rustc_type_ir::relate::RelateResult, Self> { - let interner = relation.cx(); - CollectAndApply::collect_and_apply( + GenericArgs::new_from_iter( + relation.cx(), std::iter::zip(a.iter(), b.iter()).map(|(a, b)| { relation.relate_with_variance( Variance::Invariant, @@ -351,7 +600,6 @@ impl<'db> rustc_type_ir::relate::Relate> for GenericArgs<'db> { b, ) }), - |g| GenericArgs::new_from_iter(interner, g.iter().cloned()), ) } } @@ -397,29 +645,26 @@ impl<'db> rustc_type_ir::inherent::GenericArgs> for GenericArgs< }) } fn type_at(self, i: usize) -> as rustc_type_ir::Interner>::Ty { - self.inner() - .get(i) + self.get(i) .and_then(|g| g.as_type()) .unwrap_or_else(|| Ty::new_error(DbInterner::conjure(), ErrorGuaranteed)) } fn region_at(self, i: usize) -> as rustc_type_ir::Interner>::Region { - self.inner() - .get(i) + self.get(i) .and_then(|g| g.as_region()) .unwrap_or_else(|| Region::error(DbInterner::conjure())) } fn const_at(self, i: usize) -> as rustc_type_ir::Interner>::Const { - self.inner() - .get(i) + self.get(i) .and_then(|g| g.as_const()) .unwrap_or_else(|| Const::error(DbInterner::conjure())) } fn split_closure_args(self) -> rustc_type_ir::ClosureArgsParts> { // FIXME: should use `ClosureSubst` when possible - match self.inner().as_slice() { + match self.as_slice() { [parent_args @ .., closure_kind_ty, sig_ty, tupled_upvars_ty] => { let interner = DbInterner::conjure(); // This is stupid, but the next solver expects the first input to actually be a tuple @@ -458,7 +703,7 @@ impl<'db> rustc_type_ir::inherent::GenericArgs> for GenericArgs< fn split_coroutine_closure_args( self, ) -> rustc_type_ir::CoroutineClosureArgsParts> { - match self.inner().as_slice() { + match self.as_slice() { [ parent_args @ .., closure_kind_ty, @@ -481,7 +726,7 @@ impl<'db> rustc_type_ir::inherent::GenericArgs> for GenericArgs< fn split_coroutine_args(self) -> rustc_type_ir::CoroutineArgsParts> { let interner = DbInterner::conjure(); - match self.inner().as_slice() { + match self.as_slice() { [parent_args @ .., kind_ty, resume_ty, yield_ty, return_ty, tupled_upvars_ty] => { rustc_type_ir::CoroutineArgsParts { parent_args: GenericArgs::new_from_iter(interner, parent_args.iter().cloned()), @@ -518,25 +763,25 @@ pub fn error_for_param_kind<'db>(id: GenericParamId, interner: DbInterner<'db>) } impl<'db> IntoKind for Term<'db> { - type Kind = TermKind>; + type Kind = TermKind<'db>; + #[inline] fn kind(self) -> Self::Kind { - match self { - Term::Ty(ty) => TermKind::Ty(ty), - Term::Const(c) => TermKind::Const(c), - } + self.ptr.term_kind() } } impl<'db> From> for Term<'db> { + #[inline] fn from(value: Ty<'db>) -> Self { - Self::Ty(value) + Term { ptr: GenericArgImpl::new_ty(value) } } } impl<'db> From> for Term<'db> { + #[inline] fn from(value: Const<'db>) -> Self { - Self::Const(value) + Term { ptr: GenericArgImpl::new_const(value) } } } @@ -583,7 +828,7 @@ impl From for TermVid { impl<'db> DbInterner<'db> { pub(super) fn mk_args(self, args: &[GenericArg<'db>]) -> GenericArgs<'db> { - GenericArgs::new_from_iter(self, args.iter().cloned()) + GenericArgs::new_from_slice(args) } pub(super) fn mk_args_from_iter(self, iter: I) -> T::Output diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/at.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/at.rs index 70b659406f86..6ba1aae2d486 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/at.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/at.rs @@ -28,7 +28,7 @@ use rustc_type_ir::{ FnSig, GenericArgKind, TypeFoldable, TypingMode, Variance, error::ExpectedFound, - inherent::{IntoKind, Span as _}, + inherent::Span as _, relate::{Relate, TypeRelation, solver_relating::RelateExt}, }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs index 1029a7ff39e8..4422eeaa9a4b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs @@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; use rustc_index::Idx; use rustc_type_ir::InferTy::{self, FloatVar, IntVar, TyVar}; -use rustc_type_ir::inherent::{Const as _, IntoKind as _, Region as _, SliceLike, Ty as _}; +use rustc_type_ir::inherent::{Const as _, IntoKind as _, Region as _, Ty as _}; use rustc_type_ir::{ BoundVar, BoundVarIndexKind, DebruijnIndex, Flags, InferConst, RegionKind, TyVid, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UniverseIndex, @@ -498,7 +498,7 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> { { let base = Canonical { max_universe: UniverseIndex::ROOT, - variables: CanonicalVars::new_from_iter(tcx, []), + variables: CanonicalVars::empty(tcx), value: (), }; Canonicalizer::canonicalize_with_base( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs index 13c620cfdbc9..b758042e85b0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs @@ -23,7 +23,7 @@ use rustc_index::{Idx as _, IndexVec}; use rustc_type_ir::{ BoundVar, BoundVarIndexKind, GenericArgKind, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UniverseIndex, - inherent::{GenericArg as _, IntoKind, SliceLike}, + inherent::{GenericArg as _, IntoKind}, }; use tracing::{debug, instrument}; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/outlives/obligations.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/outlives/obligations.rs index befb2001b1b9..617dbda1338b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/outlives/obligations.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/outlives/obligations.rs @@ -3,7 +3,7 @@ use rustc_type_ir::{OutlivesPredicate, TypeVisitableExt}; use tracing::{debug, instrument}; use crate::next_solver::{ - ArgOutlivesPredicate, GenericArg, Region, RegionOutlivesPredicate, Ty, + ArgOutlivesPredicate, GenericArgKind, Region, RegionOutlivesPredicate, Ty, infer::{InferCtxt, TypeOutlivesConstraint, snapshot::undo_log::UndoLog}, }; @@ -12,14 +12,14 @@ impl<'db> InferCtxt<'db> { &self, OutlivesPredicate(arg, r2): ArgOutlivesPredicate<'db>, ) { - match arg { - GenericArg::Lifetime(r1) => { + match arg.kind() { + GenericArgKind::Lifetime(r1) => { self.register_region_outlives_constraint(OutlivesPredicate(r1, r2)); } - GenericArg::Ty(ty1) => { + GenericArgKind::Type(ty1) => { self.register_type_outlives_constraint(ty1, r2); } - GenericArg::Const(_) => unreachable!(), + GenericArgKind::Const(_) => unreachable!(), } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 4d3c028879a1..1a946cb90817 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -2,6 +2,7 @@ use std::fmt; +use intern::{Interned, InternedRef, InternedSliceRef, impl_internable}; use rustc_ast_ir::{FloatTy, IntTy, UintTy}; pub use tls_cache::clear_tls_solver_cache; pub use tls_db::{attach_db, attach_db_allow_change, with_attached_db}; @@ -57,155 +58,18 @@ use super::{ util::sizedness_constraint_for_ty, }; -#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Clone)] -pub struct InternedWrapperNoDebug(pub(crate) T); +macro_rules! interned_slice { + ($storage:ident, $name:ident, $ty_db:ty, $ty_static:ty $(,)?) => { + const _: () = { + #[allow(unused_lifetimes)] + fn _ensure_correct_types<'db: 'static>(v: $ty_db) -> $ty_static { v } + }; -#[macro_export] -#[doc(hidden)] -macro_rules! _interned_vec_nolifetime_salsa { - ($name:ident, $ty:ty) => { - interned_vec_nolifetime_salsa!($name, $ty, nofold); + ::intern::impl_slice_internable!(gc; $storage, (), $ty_static); - impl<'db> rustc_type_ir::TypeFoldable> for $name<'db> { - fn try_fold_with>>( - self, - folder: &mut F, - ) -> Result { - use rustc_type_ir::inherent::SliceLike as _; - let inner: smallvec::SmallVec<[_; 2]> = - self.iter().map(|v| v.try_fold_with(folder)).collect::>()?; - Ok($name::new_(folder.cx().db(), inner)) - } - fn fold_with>>( - self, - folder: &mut F, - ) -> Self { - use rustc_type_ir::inherent::SliceLike as _; - let inner: smallvec::SmallVec<[_; 2]> = - self.iter().map(|v| v.fold_with(folder)).collect(); - $name::new_(folder.cx().db(), inner) - } - } - - impl<'db> rustc_type_ir::TypeVisitable> for $name<'db> { - fn visit_with>>( - &self, - visitor: &mut V, - ) -> V::Result { - use rustc_ast_ir::visit::VisitorResult; - use rustc_type_ir::inherent::SliceLike as _; - rustc_ast_ir::walk_visitable_list!(visitor, self.as_slice().iter()); - V::Result::output() - } - } - }; - ($name:ident, $ty:ty, nofold) => { - #[salsa::interned(constructor = new_)] - pub struct $name { - #[returns(ref)] - inner_: smallvec::SmallVec<[$ty; 2]>, - } - - impl<'db> $name<'db> { - pub fn new_from_iter( - interner: DbInterner<'db>, - data: impl IntoIterator, - ) -> Self { - $name::new_(interner.db(), data.into_iter().collect::>()) - } - - pub fn inner(&self) -> &smallvec::SmallVec<[$ty; 2]> { - // SAFETY: ¯\_(ツ)_/¯ - $crate::with_attached_db(|db| { - let inner = self.inner_(db); - unsafe { std::mem::transmute(inner) } - }) - } - } - - impl<'db> std::fmt::Debug for $name<'db> { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.as_slice().fmt(fmt) - } - } - - impl<'db> rustc_type_ir::inherent::SliceLike for $name<'db> { - type Item = $ty; - - type IntoIter = as IntoIterator>::IntoIter; - - fn iter(self) -> Self::IntoIter { - self.inner().clone().into_iter() - } - - fn as_slice(&self) -> &[Self::Item] { - self.inner().as_slice() - } - } - - impl<'db> IntoIterator for $name<'db> { - type Item = $ty; - type IntoIter = ::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - rustc_type_ir::inherent::SliceLike::iter(self) - } - } - - impl<'db> Default for $name<'db> { - fn default() -> Self { - $name::new_from_iter(DbInterner::conjure(), []) - } - } - }; -} - -pub use crate::_interned_vec_nolifetime_salsa as interned_vec_nolifetime_salsa; - -#[macro_export] -#[doc(hidden)] -macro_rules! _interned_vec_db { - ($name:ident, $ty:ident) => { - interned_vec_db!($name, $ty, nofold); - - impl<'db> rustc_type_ir::TypeFoldable> for $name<'db> { - fn try_fold_with>>( - self, - folder: &mut F, - ) -> Result { - use rustc_type_ir::inherent::SliceLike as _; - let inner: smallvec::SmallVec<[_; 2]> = - self.iter().map(|v| v.try_fold_with(folder)).collect::>()?; - Ok($name::new_(folder.cx().db(), inner)) - } - fn fold_with>>( - self, - folder: &mut F, - ) -> Self { - use rustc_type_ir::inherent::SliceLike as _; - let inner: smallvec::SmallVec<[_; 2]> = - self.iter().map(|v| v.fold_with(folder)).collect(); - $name::new_(folder.cx().db(), inner) - } - } - - impl<'db> rustc_type_ir::TypeVisitable> for $name<'db> { - fn visit_with>>( - &self, - visitor: &mut V, - ) -> V::Result { - use rustc_ast_ir::visit::VisitorResult; - use rustc_type_ir::inherent::SliceLike as _; - rustc_ast_ir::walk_visitable_list!(visitor, self.as_slice().iter()); - V::Result::output() - } - } - }; - ($name:ident, $ty:ident, nofold) => { - #[salsa::interned(constructor = new_, unsafe(non_update_types))] + #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct $name<'db> { - #[returns(ref)] - inner_: smallvec::SmallVec<[$ty<'db>; 2]>, + interned: ::intern::InternedSliceRef<'db, $storage>, } impl<'db> std::fmt::Debug for $name<'db> { @@ -215,58 +79,223 @@ macro_rules! _interned_vec_db { } impl<'db> $name<'db> { - pub fn empty(interner: DbInterner<'db>) -> Self { - $name::new_(interner.db(), smallvec::SmallVec::new()) + #[inline] + pub fn empty(_interner: DbInterner<'db>) -> Self { + // FIXME: Get from a static. + Self::new_from_slice(&[]) } - pub fn new_from_iter( - interner: DbInterner<'db>, - data: impl IntoIterator>, - ) -> Self { - $name::new_(interner.db(), data.into_iter().collect::>()) + #[inline] + pub fn new_from_slice(slice: &[$ty_db]) -> Self { + let slice = unsafe { ::std::mem::transmute::<&[$ty_db], &[$ty_static]>(slice) }; + Self { interned: ::intern::InternedSlice::from_header_and_slice((), slice) } } - pub fn inner(&self) -> &smallvec::SmallVec<[$ty<'db>; 2]> { - // SAFETY: ¯\_(ツ)_/¯ - $crate::with_attached_db(|db| { - let inner = self.inner_(db); - unsafe { std::mem::transmute(inner) } + #[inline] + pub fn new_from_iter(_interner: DbInterner<'db>, args: I) -> T::Output + where + I: IntoIterator, + T: ::rustc_type_ir::CollectAndApply<$ty_db, Self>, + { + ::rustc_type_ir::CollectAndApply::collect_and_apply(args.into_iter(), |g| { + Self::new_from_slice(g) }) } - } - impl<'db> rustc_type_ir::inherent::SliceLike for $name<'db> { - type Item = $ty<'db>; - - type IntoIter = ; 2]> as IntoIterator>::IntoIter; - - fn iter(self) -> Self::IntoIter { - self.inner().clone().into_iter() + #[inline] + pub fn as_slice(self) -> &'db [$ty_db] { + let slice = &self.interned.get().slice; + unsafe { ::std::mem::transmute::<&[$ty_static], &[$ty_db]>(slice) } } - fn as_slice(&self) -> &[Self::Item] { - self.inner().as_slice() + #[inline] + pub fn iter(self) -> ::std::iter::Copied<::std::slice::Iter<'db, $ty_db>> { + self.as_slice().iter().copied() + } + + #[inline] + pub fn len(self) -> usize { + self.as_slice().len() + } + + #[inline] + pub fn is_empty(self) -> bool { + self.as_slice().is_empty() } } impl<'db> IntoIterator for $name<'db> { - type Item = $ty<'db>; - type IntoIter = ::IntoIter; + type IntoIter = ::std::iter::Copied<::std::slice::Iter<'db, $ty_db>>; + type Item = $ty_db; + #[inline] + fn into_iter(self) -> Self::IntoIter { self.iter() } + } - fn into_iter(self) -> Self::IntoIter { - rustc_type_ir::inherent::SliceLike::iter(self) + impl<'db> ::std::ops::Deref for $name<'db> { + type Target = [$ty_db]; + + #[inline] + fn deref(&self) -> &Self::Target { + (*self).as_slice() + } + } + + impl<'db> rustc_type_ir::inherent::SliceLike for $name<'db> { + type Item = $ty_db; + + type IntoIter = ::std::iter::Copied<::std::slice::Iter<'db, $ty_db>>; + + #[inline] + fn iter(self) -> Self::IntoIter { + self.iter() + } + + #[inline] + fn as_slice(&self) -> &[Self::Item] { + (*self).as_slice() } } impl<'db> Default for $name<'db> { + #[inline] fn default() -> Self { - $name::new_from_iter(DbInterner::conjure(), []) + $name::empty(DbInterner::conjure()) + } + } + + + impl<'db, V: $crate::next_solver::interner::WorldExposer> + rustc_type_ir::GenericTypeVisitable for $name<'db> + { + #[inline] + fn generic_visit_with(&self, visitor: &mut V) { + visitor.on_interned_slice(self.interned); + self.as_slice().iter().for_each(|it| it.generic_visit_with(visitor)); } } }; } +pub(crate) use interned_slice; -pub use crate::_interned_vec_db as interned_vec_db; +macro_rules! impl_foldable_for_interned_slice { + ($name:ident) => { + impl<'db> ::rustc_type_ir::TypeVisitable> for $name<'db> { + fn visit_with>>( + &self, + visitor: &mut V, + ) -> V::Result { + use rustc_ast_ir::visit::VisitorResult; + rustc_ast_ir::walk_visitable_list!(visitor, (*self).iter()); + V::Result::output() + } + } + + impl<'db> rustc_type_ir::TypeFoldable> for $name<'db> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { + Self::new_from_iter(folder.cx(), self.iter().map(|it| it.try_fold_with(folder))) + } + fn fold_with>>( + self, + folder: &mut F, + ) -> Self { + Self::new_from_iter(folder.cx(), self.iter().map(|it| it.fold_with(folder))) + } + } + }; +} +pub(crate) use impl_foldable_for_interned_slice; + +macro_rules! impl_stored_interned_slice { + ( $storage:ident, $name:ident, $stored_name:ident $(,)? ) => { + #[derive(Clone, PartialEq, Eq, Hash)] + pub struct $stored_name { + interned: ::intern::InternedSlice<$storage>, + } + + impl $stored_name { + #[inline] + fn new(it: $name<'_>) -> Self { + Self { interned: it.interned.to_owned() } + } + + #[inline] + pub fn as_ref<'a, 'db>(&'a self) -> $name<'db> { + let it = $name { interned: self.interned.as_ref() }; + unsafe { std::mem::transmute::<$name<'a>, $name<'db>>(it) } + } + } + + unsafe impl salsa::Update for $stored_name { + unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool { + unsafe { crate::utils::unsafe_update_eq(old_pointer, new_value) } + } + } + + impl std::fmt::Debug for $stored_name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.as_ref().fmt(f) + } + } + + impl $name<'_> { + #[inline] + pub fn store(self) -> $stored_name { + $stored_name::new(self) + } + } + }; +} +pub(crate) use impl_stored_interned_slice; + +macro_rules! impl_stored_interned { + ( $storage:ident, $name:ident, $stored_name:ident $(,)? ) => { + #[derive(Clone, PartialEq, Eq, Hash)] + pub struct $stored_name { + interned: ::intern::Interned<$storage>, + } + + impl $stored_name { + #[inline] + fn new(it: $name<'_>) -> Self { + Self { interned: it.interned.to_owned() } + } + + #[inline] + pub fn as_ref<'a, 'db>(&'a self) -> $name<'db> { + let it = $name { interned: self.interned.as_ref() }; + unsafe { std::mem::transmute::<$name<'a>, $name<'db>>(it) } + } + } + + unsafe impl salsa::Update for $stored_name { + unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool { + unsafe { crate::utils::unsafe_update_eq(old_pointer, new_value) } + } + } + + impl std::fmt::Debug for $stored_name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.as_ref().fmt(f) + } + } + + impl $name<'_> { + #[inline] + pub fn store(self) -> $stored_name { + $stored_name::new(self) + } + } + }; +} +pub(crate) use impl_stored_interned; + +pub trait WorldExposer { + fn on_interned(&mut self, interned: InternedRef<'_, T>); + fn on_interned_slice(&mut self, interned: InternedSliceRef<'_, T>); +} #[derive(Debug, Copy, Clone)] pub struct DbInterner<'db> { @@ -333,7 +362,8 @@ impl<'db> inherent::Span> for Span { } } -interned_vec_nolifetime_salsa!(BoundVarKinds, BoundVarKind, nofold); +interned_slice!(BoundVarKindsStorage, BoundVarKinds, BoundVarKind, BoundVarKind); +impl_stored_interned_slice!(BoundVarKindsStorage, BoundVarKinds, StoredBoundVarKinds); #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum BoundVarKind { @@ -365,7 +395,12 @@ impl BoundVarKind { } } -interned_vec_db!(CanonicalVars, CanonicalVarKind, nofold); +interned_slice!( + CanonicalVarsStorage, + CanonicalVars, + CanonicalVarKind<'db>, + CanonicalVarKind<'static> +); pub struct DepNodeIndex; @@ -391,7 +426,8 @@ impl std::fmt::Debug for Placeholder { #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct AllocId; -interned_vec_nolifetime_salsa!(VariancesOf, Variance, nofold); +interned_slice!(VariancesOfStorage, VariancesOf, Variance, Variance); +impl_stored_interned_slice!(VariancesOfStorage, VariancesOf, StoredVariancesOf); #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct VariantIdx(usize); @@ -658,7 +694,7 @@ impl<'db> inherent::AdtDef> for AdtDef { let id: VariantId = struct_id.into(); let field_types = interner.db().field_types(id); - field_types.iter().last().map(|f| *f.1) + field_types.iter().last().map(|f| f.1.get()) } fn all_field_tys( @@ -668,7 +704,7 @@ impl<'db> inherent::AdtDef> for AdtDef { let db = interner.db(); // FIXME: this is disabled just to match the behavior with chalk right now let _field_tys = |id: VariantId| { - db.field_types(id).iter().map(|(_, ty)| ty.skip_binder()).collect::>() + db.field_types(id).iter().map(|(_, ty)| ty.get().skip_binder()).collect::>() }; let field_tys = |_id: VariantId| vec![]; let tys: Vec<_> = match self.inner().id { @@ -762,30 +798,36 @@ impl std::ops::Deref for UnsizingParams { pub type PatternKind<'db> = rustc_type_ir::PatternKind>; -#[salsa::interned(constructor = new_, debug, unsafe(non_update_types))] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Pattern<'db> { - #[returns(ref)] - kind_: InternedWrapperNoDebug>, + interned: InternedRef<'db, PatternInterned>, } -impl<'db> std::fmt::Debug for InternedWrapperNoDebug> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} +#[derive(PartialEq, Eq, Hash)] +struct PatternInterned(PatternKind<'static>); + +impl_internable!(gc; PatternInterned); + +const _: () = { + const fn is_copy() {} + is_copy::>(); +}; impl<'db> Pattern<'db> { - pub fn new(interner: DbInterner<'db>, kind: PatternKind<'db>) -> Self { - Pattern::new_(interner.db(), InternedWrapperNoDebug(kind)) + pub fn new(_interner: DbInterner<'db>, kind: PatternKind<'db>) -> Self { + let kind = unsafe { std::mem::transmute::, PatternKind<'static>>(kind) }; + Self { interned: Interned::new_gc(PatternInterned(kind)) } } pub fn inner(&self) -> &PatternKind<'db> { - crate::with_attached_db(|db| { - let inner = &self.kind_(db).0; - // SAFETY: The caller already has access to a `Ty<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute(inner) } - }) + let inner = &self.interned.0; + unsafe { std::mem::transmute::<&PatternKind<'static>, &PatternKind<'db>>(inner) } + } +} + +impl<'db> std::fmt::Debug for Pattern<'db> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.kind().fmt(f) } } @@ -831,6 +873,35 @@ impl<'db> rustc_type_ir::inherent::IntoKind for Pattern<'db> { } } +impl<'db> rustc_type_ir::TypeVisitable> for Pattern<'db> { + fn visit_with>>( + &self, + visitor: &mut V, + ) -> V::Result { + self.kind().visit_with(visitor) + } +} + +impl<'db, V: WorldExposer> rustc_type_ir::GenericTypeVisitable for Pattern<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + visitor.on_interned(self.interned); + self.kind().generic_visit_with(visitor); + } +} + +impl<'db> rustc_type_ir::TypeFoldable> for Pattern<'db> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { + Ok(Pattern::new(folder.cx(), self.kind().try_fold_with(folder)?)) + } + + fn fold_with>>(self, folder: &mut F) -> Self { + Pattern::new(folder.cx(), self.kind().fold_with(folder)) + } +} + impl<'db> rustc_type_ir::relate::Relate> for Pattern<'db> { fn relate>>( relation: &mut R, @@ -851,9 +922,9 @@ impl<'db> rustc_type_ir::relate::Relate> for Pattern<'db> { if a.len() != b.len() { return Err(TypeError::Mismatch); } - let pats = CollectAndApply::collect_and_apply( + let pats = PatList::new_from_iter( + relation.cx(), std::iter::zip(a.iter(), b.iter()).map(|(a, b)| relation.relate(a, b)), - |g| PatList::new_from_iter(tcx, g.iter().cloned()), )?; Ok(Pattern::new(tcx, PatternKind::Or(pats))) } @@ -865,7 +936,8 @@ impl<'db> rustc_type_ir::relate::Relate> for Pattern<'db> { } } -interned_vec_db!(PatList, Pattern); +interned_slice!(PatListStorage, PatList, Pattern<'db>, Pattern<'static>); +impl_foldable_for_interned_slice!(PatList); macro_rules! as_lang_item { ( @@ -941,7 +1013,7 @@ impl<'db> Interner for DbInterner<'db> { self, data: &[(OpaqueTypeKey<'db>, Self::Ty)], ) -> Self::PredefinedOpaques { - PredefinedOpaques::new_from_iter(self, data.iter().cloned()) + PredefinedOpaques::new_from_slice(data) } type CanonicalVarKinds = CanonicalVars<'db>; @@ -950,7 +1022,7 @@ impl<'db> Interner for DbInterner<'db> { self, kinds: &[rustc_type_ir::CanonicalVarKind], ) -> Self::CanonicalVarKinds { - CanonicalVars::new_from_iter(self, kinds.iter().cloned()) + CanonicalVars::new_from_slice(kinds) } type ExternalConstraints = ExternalConstraints<'db>; @@ -1012,7 +1084,7 @@ impl<'db> Interner for DbInterner<'db> { type Features = Features; fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs { - GenericArgs::new_from_iter(self, args.iter().cloned()) + GenericArgs::new_from_slice(args) } fn mk_args_from_iter(self, args: I) -> T::Output @@ -1020,9 +1092,7 @@ impl<'db> Interner for DbInterner<'db> { I: Iterator, T: rustc_type_ir::CollectAndApply, { - CollectAndApply::collect_and_apply(args, |g| { - GenericArgs::new_from_iter(self, g.iter().cloned()) - }) + GenericArgs::new_from_iter(self, args) } type UnsizingParams = UnsizingParams; @@ -1096,7 +1166,7 @@ impl<'db> Interner for DbInterner<'db> { | SolverDefId::ImplId(_) | SolverDefId::InternedClosureId(_) | SolverDefId::InternedCoroutineId(_) => { - return VariancesOf::new_from_iter(self, []); + return VariancesOf::empty(self); } }; self.db.variances_of(generic_def) @@ -1202,7 +1272,7 @@ impl<'db> Interner for DbInterner<'db> { I: Iterator, T: rustc_type_ir::CollectAndApply, { - CollectAndApply::collect_and_apply(args, |g| Tys::new_from_iter(self, g.iter().cloned())) + Tys::new_from_iter(self, args) } fn parent(self, def_id: Self::DefId) -> Self::DefId { @@ -1338,7 +1408,7 @@ impl<'db> Interner for DbInterner<'db> { let own_bounds: FxHashSet<_> = self.item_self_bounds(def_id).skip_binder().into_iter().collect(); if all_bounds.len() == own_bounds.len() { - EarlyBinder::bind(Clauses::new_from_iter(self, [])) + EarlyBinder::bind(Clauses::empty(self)) } else { EarlyBinder::bind(Clauses::new_from_iter( self, @@ -1952,7 +2022,7 @@ impl<'db> Interner for DbInterner<'db> { let field_types = self.db().field_types(variant.id()); let mut unsizing_params = DenseBitSet::new_empty(num_params); - let ty = field_types[tail_field.0]; + let ty = field_types[tail_field.0].get(); for arg in ty.instantiate_identity().walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.insert(i); @@ -1962,7 +2032,7 @@ impl<'db> Interner for DbInterner<'db> { // Ensure none of the other fields mention the parameters used // in unsizing. for field in prefix_fields { - for arg in field_types[field.0].instantiate_identity().walk() { + for arg in field_types[field.0].get().instantiate_identity().walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.remove(i); } @@ -2022,7 +2092,7 @@ impl<'db> Interner for DbInterner<'db> { }; let mut result = Vec::new(); crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result); - SolverDefIds::new_from_iter(self, result) + SolverDefIds::new_from_slice(&result) } fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds { @@ -2051,7 +2121,7 @@ impl<'db> Interner for DbInterner<'db> { } }); - SolverDefIds::new_from_iter(self, result) + SolverDefIds::new_from_slice(&result) } fn alias_has_const_conditions(self, _def_id: Self::DefId) -> bool { @@ -2096,10 +2166,10 @@ impl<'db> Interner for DbInterner<'db> { let impl_trait_id = self.db().lookup_intern_impl_trait_id(opaque); match impl_trait_id { crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => { - crate::opaques::rpit_hidden_types(self.db, func)[idx] + crate::opaques::rpit_hidden_types(self.db, func)[idx].get() } crate::ImplTraitId::TypeAliasImplTrait(type_alias, idx) => { - crate::opaques::tait_hidden_types(self.db, type_alias)[idx] + crate::opaques::tait_hidden_types(self.db, type_alias)[idx].get() } } } @@ -2288,6 +2358,11 @@ macro_rules! TrivialTypeTraversalImpls { ::output() } } + + impl rustc_type_ir::GenericTypeVisitable for $ty { + #[inline] + fn generic_visit_with(&self, _visitor: &mut V) {} + } )+ }; } @@ -2302,17 +2377,22 @@ TrivialTypeTraversalImpls! { AdtIdWrapper, ImplIdWrapper, GeneralConstIdWrapper, - Pattern<'db>, Safety, FnAbi, Span, ParamConst, ParamTy, BoundRegion, - BoundVar, Placeholder, Placeholder, Placeholder, + Placeholder, + BoundVarKind, + EarlyParamRegion, + LateParamRegion, + AdtDef, + BoundTy, + BoundConst, } mod tls_db { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ir_print.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ir_print.rs index dab0fe9e4a90..998aab5a3fff 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ir_print.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ir_print.rs @@ -2,7 +2,6 @@ use std::any::type_name_of_val; -use rustc_type_ir::inherent::SliceLike; use rustc_type_ir::{self as ty, ir_print::IrPrint}; use super::SolverDefId; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs index 4fbeb76adaad..7e1d6b7328cd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs @@ -1,37 +1,64 @@ //! Things related to opaques in the next-trait-solver. +use intern::{Interned, InternedRef, impl_internable}; use rustc_ast_ir::try_visit; use rustc_type_ir::inherent::SliceLike; -use super::{DbInterner, SolverDefId, Ty, interned_vec_db, interned_vec_nolifetime_salsa}; +use crate::next_solver::{impl_foldable_for_interned_slice, interned_slice}; + +use super::{DbInterner, SolverDefId, Ty}; pub type OpaqueTypeKey<'db> = rustc_type_ir::OpaqueTypeKey>; type PredefinedOpaque<'db> = (OpaqueTypeKey<'db>, Ty<'db>); -interned_vec_db!(PredefinedOpaques, PredefinedOpaque); +interned_slice!( + PredefinedOpaquesStorage, + PredefinedOpaques, + PredefinedOpaque<'db>, + PredefinedOpaque<'static>, +); +impl_foldable_for_interned_slice!(PredefinedOpaques); pub type ExternalConstraintsData<'db> = rustc_type_ir::solve::ExternalConstraintsData>; -interned_vec_nolifetime_salsa!(SolverDefIds, SolverDefId); +interned_slice!(SolverDefIdsStorage, SolverDefIds, SolverDefId, SolverDefId); +impl_foldable_for_interned_slice!(SolverDefIds); -#[salsa::interned(constructor = new_, debug, unsafe(non_update_types))] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct ExternalConstraints<'db> { - #[returns(ref)] - kind_: rustc_type_ir::solve::ExternalConstraintsData>, + interned: InternedRef<'db, ExternalConstraintsInterned>, } +#[derive(PartialEq, Eq, Hash)] +struct ExternalConstraintsInterned(ExternalConstraintsData<'static>); + +impl_internable!(gc; ExternalConstraintsInterned); + +const _: () = { + const fn is_copy() {} + is_copy::>(); +}; + impl<'db> ExternalConstraints<'db> { - pub fn new(interner: DbInterner<'db>, data: ExternalConstraintsData<'db>) -> Self { - ExternalConstraints::new_(interner.db(), data) + #[inline] + pub fn new(_interner: DbInterner<'db>, data: ExternalConstraintsData<'db>) -> Self { + let data = unsafe { + std::mem::transmute::, ExternalConstraintsData<'static>>( + data, + ) + }; + Self { interned: Interned::new_gc(ExternalConstraintsInterned(data)) } } + #[inline] pub fn inner(&self) -> &ExternalConstraintsData<'db> { - crate::with_attached_db(|db| { - let inner = self.kind_(db); - // SAFETY: ¯\_(ツ)_/¯ - unsafe { std::mem::transmute(inner) } - }) + let inner = &self.interned.0; + unsafe { + std::mem::transmute::<&ExternalConstraintsData<'static>, &ExternalConstraintsData<'db>>( + inner, + ) + } } } @@ -43,6 +70,12 @@ impl<'db> std::ops::Deref for ExternalConstraints<'db> { } } +impl std::fmt::Debug for ExternalConstraints<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.inner().fmt(f) + } +} + impl<'db> rustc_type_ir::TypeVisitable> for ExternalConstraints<'db> { fn visit_with>>( &self, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs index 71d9b0b55a30..95b48c73c12f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs @@ -2,20 +2,25 @@ use std::cmp::Ordering; -use macros::{TypeFoldable, TypeVisitable}; +use intern::{ + Interned, InternedRef, InternedSlice, InternedSliceRef, impl_internable, impl_slice_internable, +}; +use macros::{GenericTypeVisitable, TypeFoldable, TypeVisitable}; use rustc_type_ir::{ - self as ty, CollectAndApply, DebruijnIndex, EarlyBinder, FlagComputation, Flags, - PredicatePolarity, TypeFlags, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, - TypeVisitable, Upcast, UpcastFrom, WithCachedTypeInfo, + self as ty, CollectAndApply, EarlyBinder, FlagComputation, Flags, GenericTypeVisitable, + PredicatePolarity, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, Upcast, + UpcastFrom, WithCachedTypeInfo, elaborate::Elaboratable, error::{ExpectedFound, TypeError}, inherent::{IntoKind, SliceLike}, }; -use smallvec::SmallVec; -use crate::next_solver::{GenericArg, InternedWrapperNoDebug, TraitIdWrapper}; +use crate::next_solver::{ + GenericArg, TraitIdWrapper, impl_foldable_for_interned_slice, impl_stored_interned_slice, + interned_slice, +}; -use super::{Binder, BoundVarKinds, DbInterner, Region, Ty, interned_vec_db}; +use super::{Binder, BoundVarKinds, DbInterner, Region, Ty}; pub type BoundExistentialPredicate<'db> = Binder<'db, ExistentialPredicate<'db>>; @@ -68,7 +73,13 @@ fn stable_cmp_existential_predicate<'db>( (ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater, } } -interned_vec_db!(BoundExistentialPredicates, BoundExistentialPredicate); +interned_slice!( + BoundExistentialPredicatesStorage, + BoundExistentialPredicates, + BoundExistentialPredicate<'db>, + BoundExistentialPredicate<'static>, +); +impl_foldable_for_interned_slice!(BoundExistentialPredicates); impl<'db> rustc_type_ir::inherent::BoundExistentialPredicates> for BoundExistentialPredicates<'db> @@ -82,7 +93,7 @@ impl<'db> rustc_type_ir::inherent::BoundExistentialPredicates> ) -> Option< rustc_type_ir::Binder, rustc_type_ir::ExistentialTraitRef>>, > { - self.inner()[0] + self[0] .map_bound(|this| match this { ExistentialPredicate::Trait(tr) => Some(tr), _ => None, @@ -166,74 +177,50 @@ impl<'db> rustc_type_ir::relate::Relate> for BoundExistentialPre }, ); - CollectAndApply::collect_and_apply(v, |g| { - BoundExistentialPredicates::new_from_iter(interner, g.iter().cloned()) - }) + BoundExistentialPredicates::new_from_iter(interner, v) } } -#[salsa::interned(constructor = new_, unsafe(non_update_types))] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Predicate<'db> { - #[returns(ref)] - kind_: InternedWrapperNoDebug>>>, + interned: InternedRef<'db, PredicateInterned>, } -impl<'db> std::fmt::Debug for Predicate<'db> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.inner().internee.fmt(f) - } -} +#[derive(PartialEq, Eq, Hash)] +struct PredicateInterned(WithCachedTypeInfo>>); -impl<'db> std::fmt::Debug - for InternedWrapperNoDebug>>> -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Binder<")?; - match self.0.internee.skip_binder() { - rustc_type_ir::PredicateKind::Clause(clause_kind) => { - write!(f, "{clause_kind:?}") - } - rustc_type_ir::PredicateKind::DynCompatible(trait_def_id) => { - write!(f, "the trait `{trait_def_id:?}` is dyn-compatible") - } - rustc_type_ir::PredicateKind::Subtype(subtype_predicate) => { - write!(f, "{subtype_predicate:?}") - } - rustc_type_ir::PredicateKind::Coerce(coerce_predicate) => { - write!(f, "{coerce_predicate:?}") - } - rustc_type_ir::PredicateKind::ConstEquate(c1, c2) => { - write!(f, "the constant `{c1:?}` equals `{c2:?}`") - } - rustc_type_ir::PredicateKind::Ambiguous => write!(f, "ambiguous"), - rustc_type_ir::PredicateKind::NormalizesTo(data) => write!(f, "{data:?}"), - rustc_type_ir::PredicateKind::AliasRelate(t1, t2, dir) => { - write!(f, "{t1:?} {dir:?} {t2:?}") - } - }?; - write!(f, ", [{:?}]>", self.0.internee.bound_vars())?; - Ok(()) - } -} +impl_internable!(gc; PredicateInterned); + +const _: () = { + const fn is_copy() {} + is_copy::>(); +}; impl<'db> Predicate<'db> { - pub fn new(interner: DbInterner<'db>, kind: Binder<'db, PredicateKind<'db>>) -> Self { + pub fn new(_interner: DbInterner<'db>, kind: Binder<'db, PredicateKind<'db>>) -> Self { + let kind = unsafe { + std::mem::transmute::< + Binder<'db, PredicateKind<'db>>, + Binder<'static, PredicateKind<'static>>, + >(kind) + }; let flags = FlagComputation::for_predicate(kind); let cached = WithCachedTypeInfo { internee: kind, flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, }; - Predicate::new_(interner.db(), InternedWrapperNoDebug(cached)) + Self { interned: Interned::new_gc(PredicateInterned(cached)) } } pub fn inner(&self) -> &WithCachedTypeInfo>> { - crate::with_attached_db(|db| { - let inner = &self.kind_(db).0; - // SAFETY: The caller already has access to a `Predicate<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute(inner) } - }) + let inner = &self.interned.0; + unsafe { + std::mem::transmute::< + &WithCachedTypeInfo>>, + &WithCachedTypeInfo>>, + >(inner) + } } /// Flips the polarity of a Predicate. @@ -259,110 +246,132 @@ impl<'db> Predicate<'db> { } } -// FIXME: should make a "header" in interned_vec - -#[derive(Debug, Clone)] -pub struct InternedClausesWrapper<'db>(SmallVec<[Clause<'db>; 2]>, TypeFlags, DebruijnIndex); - -impl<'db> PartialEq for InternedClausesWrapper<'db> { - fn eq(&self, other: &Self) -> bool { - self.0.eq(&other.0) +impl<'db> std::fmt::Debug for Predicate<'db> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.kind().fmt(f) } } -impl<'db> Eq for InternedClausesWrapper<'db> {} +impl_slice_internable!(gc; ClausesStorage, WithCachedTypeInfo<()>, Clause<'static>); +impl_stored_interned_slice!(ClausesStorage, Clauses, StoredClauses); -impl<'db> std::hash::Hash for InternedClausesWrapper<'db> { - fn hash(&self, state: &mut H) { - self.0.hash(state) - } -} - -#[salsa::interned(constructor = new_, unsafe(non_update_types))] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Clauses<'db> { - #[returns(ref)] - inner_: InternedClausesWrapper<'db>, -} - -impl<'db> Clauses<'db> { - pub fn new_from_iter( - interner: DbInterner<'db>, - data: impl IntoIterator>, - ) -> Self { - let clauses: SmallVec<_> = data.into_iter().collect(); - let flags = FlagComputation::>::for_clauses(&clauses); - let wrapper = InternedClausesWrapper(clauses, flags.flags, flags.outer_exclusive_binder); - Clauses::new_(interner.db(), wrapper) - } - - pub fn inner(&self) -> &InternedClausesWrapper<'db> { - crate::with_attached_db(|db| { - let inner = self.inner_(db); - // SAFETY: The caller already has access to a `Clauses<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute(inner) } - }) - } + interned: InternedSliceRef<'db, ClausesStorage>, } impl<'db> std::fmt::Debug for Clauses<'db> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.inner().0.fmt(f) + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.as_slice().fmt(fmt) } } -impl<'db> rustc_type_ir::inherent::Clauses> for Clauses<'db> {} - -impl<'db> rustc_type_ir::inherent::SliceLike for Clauses<'db> { - type Item = Clause<'db>; - - type IntoIter = ; 2]> as IntoIterator>::IntoIter; - - fn iter(self) -> Self::IntoIter { - self.inner().0.clone().into_iter() +impl<'db> Clauses<'db> { + #[inline] + pub fn empty(_interner: DbInterner<'db>) -> Self { + // FIXME: Get from a static. + Self::new_from_slice(&[]) } - fn as_slice(&self) -> &[Self::Item] { - self.inner().0.as_slice() + #[inline] + pub fn new_from_slice(slice: &[Clause<'db>]) -> Self { + let slice = unsafe { ::std::mem::transmute::<&[Clause<'db>], &[Clause<'static>]>(slice) }; + let flags = FlagComputation::>::for_clauses(slice); + let flags = WithCachedTypeInfo { + internee: (), + flags: flags.flags, + outer_exclusive_binder: flags.outer_exclusive_binder, + }; + Self { interned: InternedSlice::from_header_and_slice(flags, slice) } + } + + #[inline] + pub fn new_from_iter(_interner: DbInterner<'db>, args: I) -> T::Output + where + I: IntoIterator, + T: CollectAndApply, Self>, + { + CollectAndApply::collect_and_apply(args.into_iter(), Self::new_from_slice) + } + + #[inline] + pub fn as_slice(self) -> &'db [Clause<'db>] { + let slice = &self.interned.get().slice; + unsafe { ::std::mem::transmute::<&[Clause<'static>], &[Clause<'db>]>(slice) } + } + + #[inline] + pub fn iter(self) -> ::std::iter::Copied<::std::slice::Iter<'db, Clause<'db>>> { + self.as_slice().iter().copied() + } + + #[inline] + pub fn len(self) -> usize { + self.as_slice().len() + } + + #[inline] + pub fn is_empty(self) -> bool { + self.as_slice().is_empty() } } impl<'db> IntoIterator for Clauses<'db> { + type IntoIter = ::std::iter::Copied<::std::slice::Iter<'db, Clause<'db>>>; type Item = Clause<'db>; - type IntoIter = ::IntoIter; - + #[inline] fn into_iter(self) -> Self::IntoIter { - rustc_type_ir::inherent::SliceLike::iter(self) + self.iter() + } +} + +impl<'db> std::ops::Deref for Clauses<'db> { + type Target = [Clause<'db>]; + + #[inline] + fn deref(&self) -> &Self::Target { + (*self).as_slice() + } +} + +impl<'db> rustc_type_ir::inherent::SliceLike for Clauses<'db> { + type Item = Clause<'db>; + + type IntoIter = ::std::iter::Copied<::std::slice::Iter<'db, Clause<'db>>>; + + #[inline] + fn iter(self) -> Self::IntoIter { + self.iter() + } + + #[inline] + fn as_slice(&self) -> &[Self::Item] { + (*self).as_slice() } } impl<'db> Default for Clauses<'db> { + #[inline] fn default() -> Self { - Clauses::new_from_iter(DbInterner::conjure(), []) + Clauses::empty(DbInterner::conjure()) } } +impl<'db> rustc_type_ir::inherent::Clauses> for Clauses<'db> {} + impl<'db> rustc_type_ir::TypeSuperFoldable> for Clauses<'db> { fn try_super_fold_with>>( self, folder: &mut F, ) -> Result { - let mut clauses: SmallVec<[_; 2]> = SmallVec::with_capacity(self.inner().0.len()); - for c in self { - clauses.push(c.try_fold_with(folder)?); - } - Ok(Clauses::new_from_iter(folder.cx(), clauses)) + Clauses::new_from_iter(folder.cx(), self.iter().map(|clause| clause.try_fold_with(folder))) } fn super_fold_with>>( self, folder: &mut F, ) -> Self { - let mut clauses: SmallVec<[_; 2]> = SmallVec::with_capacity(self.inner().0.len()); - for c in self { - clauses.push(c.fold_with(folder)); - } - Clauses::new_from_iter(folder.cx(), clauses) + Clauses::new_from_iter(folder.cx(), self.iter().map(|clause| clause.fold_with(folder))) } } @@ -371,15 +380,10 @@ impl<'db> rustc_type_ir::TypeFoldable> for Clauses<'db> { self, folder: &mut F, ) -> Result { - use rustc_type_ir::inherent::SliceLike as _; - let inner: smallvec::SmallVec<[_; 2]> = - self.iter().map(|v| v.try_fold_with(folder)).collect::>()?; - Ok(Clauses::new_from_iter(folder.cx(), inner)) + self.try_super_fold_with(folder) } fn fold_with>>(self, folder: &mut F) -> Self { - use rustc_type_ir::inherent::SliceLike as _; - let inner: smallvec::SmallVec<[_; 2]> = self.iter().map(|v| v.fold_with(folder)).collect(); - Clauses::new_from_iter(folder.cx(), inner) + self.super_fold_with(folder) } } @@ -389,19 +393,27 @@ impl<'db> rustc_type_ir::TypeVisitable> for Clauses<'db> { visitor: &mut V, ) -> V::Result { use rustc_ast_ir::visit::VisitorResult; - use rustc_type_ir::inherent::SliceLike as _; - rustc_ast_ir::walk_visitable_list!(visitor, self.as_slice().iter()); + rustc_ast_ir::walk_visitable_list!(visitor, self.iter()); V::Result::output() } } +impl<'db, V: super::WorldExposer> rustc_type_ir::GenericTypeVisitable for Clauses<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + visitor.on_interned_slice(self.interned); + self.as_slice().iter().for_each(|it| it.generic_visit_with(visitor)); + } +} + impl<'db> rustc_type_ir::Flags for Clauses<'db> { + #[inline] fn flags(&self) -> rustc_type_ir::TypeFlags { - self.inner().1 + self.interned.header.header.flags } + #[inline] fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex { - self.inner().2 + self.interned.header.header.outer_exclusive_binder } } @@ -414,7 +426,7 @@ impl<'db> rustc_type_ir::TypeSuperVisitable> for Clauses<'db> { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] // TODO implement Debug by hand +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, GenericTypeVisitable)] // TODO implement Debug by hand pub struct Clause<'db>(pub(crate) Predicate<'db>); // We could cram the reveal into the clauses like rustc does, probably @@ -425,7 +437,7 @@ pub struct ParamEnv<'db> { impl<'db> ParamEnv<'db> { pub fn empty() -> Self { - ParamEnv { clauses: Clauses::new_from_iter(DbInterner::conjure(), []) } + ParamEnv { clauses: Clauses::empty(DbInterner::conjure()) } } pub fn clauses(self) -> Clauses<'db> { @@ -460,6 +472,13 @@ impl<'db> TypeVisitable> for Predicate<'db> { } } +impl<'db, V: super::WorldExposer> GenericTypeVisitable for Predicate<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + visitor.on_interned(self.interned); + self.kind().generic_visit_with(visitor); + } +} + impl<'db> TypeSuperVisitable> for Predicate<'db> { fn super_visit_with>>( &self, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs index 3be715ab07d3..dee7953ae36c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs @@ -1,47 +1,50 @@ //! Things related to regions. use hir_def::LifetimeParamId; -use intern::Symbol; +use intern::{Interned, InternedRef, Symbol, impl_internable}; use rustc_type_ir::{ - BoundVar, BoundVarIndexKind, DebruijnIndex, Flags, INNERMOST, RegionVid, TypeFlags, - TypeFoldable, TypeVisitable, + BoundVar, BoundVarIndexKind, DebruijnIndex, Flags, GenericTypeVisitable, INNERMOST, RegionVid, + TypeFlags, TypeFoldable, TypeVisitable, inherent::{IntoKind, PlaceholderLike, SliceLike}, relate::Relate, }; -use crate::next_solver::{GenericArg, OutlivesPredicate}; +use crate::next_solver::{ + GenericArg, OutlivesPredicate, impl_foldable_for_interned_slice, interned_slice, +}; use super::{ - ErrorGuaranteed, SolverDefId, interned_vec_db, + ErrorGuaranteed, SolverDefId, interner::{BoundVarKind, DbInterner, Placeholder}, }; pub type RegionKind<'db> = rustc_type_ir::RegionKind>; -#[salsa::interned(constructor = new_, unsafe(non_update_types))] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Region<'db> { - #[returns(ref)] - kind_: RegionKind<'db>, + pub(super) interned: InternedRef<'db, RegionInterned>, } -impl std::fmt::Debug for Region<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.kind().fmt(f) - } -} +#[derive(PartialEq, Eq, Hash)] +#[repr(align(4))] // Required for `GenericArg` bit-tagging. +pub(super) struct RegionInterned(RegionKind<'static>); + +impl_internable!(gc; RegionInterned); + +const _: () = { + const fn is_copy() {} + is_copy::>(); +}; impl<'db> Region<'db> { - pub fn new(interner: DbInterner<'db>, kind: RegionKind<'db>) -> Self { - Region::new_(interner.db(), kind) + pub fn new(_interner: DbInterner<'db>, kind: RegionKind<'db>) -> Self { + let kind = unsafe { std::mem::transmute::, RegionKind<'static>>(kind) }; + Self { interned: Interned::new_gc(RegionInterned(kind)) } } pub fn inner(&self) -> &RegionKind<'db> { - crate::with_attached_db(|db| { - let inner = self.kind_(db); - // SAFETY: The caller already has access to a `Region<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute::<&RegionKind<'_>, &RegionKind<'db>>(inner) } - }) + let inner = &self.interned.0; + unsafe { std::mem::transmute::<&RegionKind<'static>, &RegionKind<'db>>(inner) } } pub fn new_early_param( @@ -256,6 +259,12 @@ impl BoundRegionKind { } } +impl std::fmt::Debug for Region<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.kind().fmt(f) + } +} + impl<'db> IntoKind for Region<'db> { type Kind = RegionKind<'db>; @@ -377,6 +386,19 @@ impl<'db> PlaceholderLike> for PlaceholderRegion { } } +impl<'db, V: super::WorldExposer> GenericTypeVisitable for Region<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + visitor.on_interned(self.interned); + self.kind().generic_visit_with(visitor); + } +} + type GenericArgOutlivesPredicate<'db> = OutlivesPredicate<'db, GenericArg<'db>>; -interned_vec_db!(RegionAssumptions, GenericArgOutlivesPredicate); +interned_slice!( + RegionAssumptionsStorage, + RegionAssumptions, + GenericArgOutlivesPredicate<'db>, + GenericArgOutlivesPredicate<'static>, +); +impl_foldable_for_interned_slice!(RegionAssumptions); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs index 40a3f17cf169..d800925ba4e9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs @@ -5,7 +5,7 @@ use rustc_next_trait_solver::delegate::SolverDelegate; use rustc_type_ir::{ AliasTyKind, GenericArgKind, InferCtxtLike, Interner, PredicatePolarity, TypeFlags, TypeVisitableExt, - inherent::{IntoKind, SliceLike, Term as _, Ty as _}, + inherent::{IntoKind, Term as _, Ty as _}, lang_items::SolverTraitLangItem, solve::{Certainty, NoSolution}, }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs index 7dcb8567c2e4..305da50b6d9f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs @@ -7,13 +7,14 @@ use hir_def::{ hir::generics::{TypeOrConstParamData, TypeParamProvenance}, }; use hir_def::{TraitId, type_ref::Rawness}; +use intern::{Interned, InternedRef, impl_internable}; use rustc_abi::{Float, Integer, Size}; use rustc_ast_ir::{Mutability, try_visit, visit::VisitorResult}; use rustc_type_ir::{ AliasTyKind, BoundVar, BoundVarIndexKind, ClosureKind, CoroutineArgs, CoroutineArgsParts, - DebruijnIndex, FlagComputation, Flags, FloatTy, FloatVid, InferTy, IntTy, IntVid, Interner, - TyVid, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, - TypeVisitor, UintTy, Upcast, WithCachedTypeInfo, + DebruijnIndex, FlagComputation, Flags, FloatTy, FloatVid, GenericTypeVisitable, InferTy, IntTy, + IntVid, Interner, TyVid, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, UintTy, Upcast, WithCachedTypeInfo, inherent::{ AdtDef as _, BoundExistentialPredicates, BoundVarLike, Const as _, GenericArgs as _, IntoKind, ParamLike, PlaceholderLike, Safety as _, SliceLike, Ty as _, @@ -28,15 +29,16 @@ use crate::{ lower::GenericPredicates, next_solver::{ AdtDef, AliasTy, Binder, CallableIdWrapper, Clause, ClauseKind, ClosureIdWrapper, Const, - CoroutineIdWrapper, FnSig, GenericArg, PolyFnSig, Region, TraitRef, TypeAliasIdWrapper, + CoroutineIdWrapper, FnSig, GenericArgKind, PolyFnSig, Region, TraitRef, TypeAliasIdWrapper, abi::Safety, - interner::InternedWrapperNoDebug, + impl_foldable_for_interned_slice, impl_stored_interned, impl_stored_interned_slice, + interned_slice, util::{CoroutineArgsExt, IntegerTypeExt}, }, }; use super::{ - BoundVarKind, DbInterner, GenericArgs, Placeholder, SolverDefId, interned_vec_db, + BoundVarKind, DbInterner, GenericArgs, Placeholder, SolverDefId, util::{FloatExt, IntegerExt}, }; @@ -44,35 +46,45 @@ pub type SimplifiedType = rustc_type_ir::fast_reject::SimplifiedType = rustc_type_ir::TyKind>; pub type FnHeader<'db> = rustc_type_ir::FnHeader>; -#[salsa::interned(constructor = new_, unsafe(non_update_types))] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Ty<'db> { - #[returns(ref)] - kind_: InternedWrapperNoDebug>>, + pub(super) interned: InternedRef<'db, TyInterned>, } +#[derive(PartialEq, Eq, Hash)] +#[repr(align(4))] // Required for `GenericArg` bit-tagging. +pub(super) struct TyInterned(WithCachedTypeInfo>); + +impl_internable!(gc; TyInterned); +impl_stored_interned!(TyInterned, Ty, StoredTy); + const _: () = { const fn is_copy() {} is_copy::>(); }; impl<'db> Ty<'db> { - pub fn new(interner: DbInterner<'db>, kind: TyKind<'db>) -> Self { + #[inline] + pub fn new(_interner: DbInterner<'db>, kind: TyKind<'db>) -> Self { + let kind = unsafe { std::mem::transmute::, TyKind<'static>>(kind) }; let flags = FlagComputation::for_kind(&kind); let cached = WithCachedTypeInfo { internee: kind, flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, }; - Ty::new_(interner.db(), InternedWrapperNoDebug(cached)) + Self { interned: Interned::new_gc(TyInterned(cached)) } } + #[inline] pub fn inner(&self) -> &WithCachedTypeInfo> { - crate::with_attached_db(|db| { - let inner = &self.kind_(db).0; - // SAFETY: The caller already has access to a `Ty<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute(inner) } - }) + let inner = &self.interned.0; + unsafe { + std::mem::transmute::< + &WithCachedTypeInfo>, + &WithCachedTypeInfo>, + >(inner) + } } pub fn new_adt(interner: DbInterner<'db>, adt_id: AdtId, args: GenericArgs<'db>) -> Self { @@ -383,7 +395,7 @@ impl<'db> Ty<'db> { #[inline] pub fn is_unit(self) -> bool { - matches!(self.kind(), TyKind::Tuple(tys) if tys.inner().is_empty()) + matches!(self.kind(), TyKind::Tuple(tys) if tys.is_empty()) } #[inline] @@ -661,12 +673,9 @@ impl<'db> Ty<'db> { // This is only used by type walking. // Parameters will be walked outside, and projection predicate is not used. // So just provide the Future trait. - let impl_bound = TraitRef::new( - interner, - future_trait.into(), - GenericArgs::new_from_iter(interner, []), - ) - .upcast(interner); + let impl_bound = + TraitRef::new(interner, future_trait.into(), GenericArgs::empty(interner)) + .upcast(interner); Some(vec![impl_bound]) } else { None @@ -730,20 +739,22 @@ impl<'db> std::fmt::Debug for Ty<'db> { } } -impl<'db> std::fmt::Debug for InternedWrapperNoDebug>> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.internee.fmt(f) - } -} - impl<'db> IntoKind for Ty<'db> { type Kind = TyKind<'db>; + #[inline] fn kind(self) -> Self::Kind { self.inner().internee } } +impl<'db, V: super::WorldExposer> GenericTypeVisitable for Ty<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + visitor.on_interned(self.interned); + self.kind().generic_visit_with(visitor); + } +} + impl<'db> TypeVisitable> for Ty<'db> { fn visit_with>>( &self, @@ -1068,9 +1079,9 @@ impl<'db> rustc_type_ir::inherent::Ty> for Ty<'db> { // to unnecessary overflows in async code. See the issue: // . let coroutine_args = interner.mk_args_from_iter(coroutine_args.iter().map(|arg| { - match arg { - GenericArg::Ty(_) | GenericArg::Const(_) => arg, - GenericArg::Lifetime(_) => { + match arg.kind() { + GenericArgKind::Type(_) | GenericArgKind::Const(_) => arg, + GenericArgKind::Lifetime(_) => { crate::next_solver::Region::new(interner, rustc_type_ir::RegionKind::ReErased) .into() } @@ -1254,10 +1265,13 @@ impl<'db> rustc_type_ir::inherent::Ty> for Ty<'db> { } } -interned_vec_db!(Tys, Ty); +interned_slice!(TysStorage, Tys, Ty<'db>, Ty<'static>); +impl_foldable_for_interned_slice!(Tys); +impl_stored_interned_slice!(TysStorage, Tys, StoredTys); impl<'db> Tys<'db> { - pub fn inputs(&self) -> &[Ty<'db>] { + #[inline] + pub fn inputs(self) -> &'db [Ty<'db>] { self.as_slice().split_last().unwrap().1 } } @@ -1323,6 +1337,10 @@ pub enum BoundTyKind { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub struct ErrorGuaranteed; +impl GenericTypeVisitable for ErrorGuaranteed { + fn generic_visit_with(&self, _visitor: &mut V) {} +} + impl<'db> TypeVisitable> for ErrorGuaranteed { fn visit_with>>( &self, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs index 76a6207e2338..27ae5e39d55b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs @@ -13,7 +13,7 @@ use crate::{ db::{HirDatabase, InternedOpaqueTyId}, lower::{ImplTraitIdx, ImplTraits}, next_solver::{ - DbInterner, EarlyBinder, ErrorGuaranteed, SolverDefId, Ty, TypingMode, + DbInterner, ErrorGuaranteed, SolverDefId, StoredEarlyBinder, StoredTy, Ty, TypingMode, infer::{DbInternerInferExt, traits::ObligationCause}, obligation_ctxt::ObligationCtxt, }, @@ -72,10 +72,10 @@ pub(crate) fn opaque_types_defined_by( // FIXME: Collect opaques from `#[define_opaque]`. - fn extend_with_opaques<'db>( - db: &'db dyn HirDatabase, - opaques: &Option>>>, - mut make_impl_trait: impl FnMut(ImplTraitIdx<'db>) -> ImplTraitId<'db>, + fn extend_with_opaques( + db: &dyn HirDatabase, + opaques: &Option>>, + mut make_impl_trait: impl FnMut(ImplTraitIdx) -> ImplTraitId, result: &mut Vec, ) { if let Some(opaques) = opaques { @@ -89,25 +89,25 @@ pub(crate) fn opaque_types_defined_by( // These are firewall queries to prevent drawing dependencies between infers: -#[salsa::tracked(returns(ref), unsafe(non_update_types))] +#[salsa::tracked(returns(ref))] pub(crate) fn rpit_hidden_types<'db>( db: &'db dyn HirDatabase, function: FunctionId, -) -> ArenaMap, EarlyBinder<'db, Ty<'db>>> { +) -> ArenaMap> { let infer = InferenceResult::for_body(db, function.into()); let mut result = ArenaMap::new(); for (opaque, hidden_type) in infer.return_position_impl_trait_types(db) { - result.insert(opaque, EarlyBinder::bind(hidden_type)); + result.insert(opaque, StoredEarlyBinder::bind(hidden_type.store())); } result.shrink_to_fit(); result } -#[salsa::tracked(returns(ref), unsafe(non_update_types))] +#[salsa::tracked(returns(ref))] pub(crate) fn tait_hidden_types<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, -) -> ArenaMap, EarlyBinder<'db, Ty<'db>>> { +) -> ArenaMap> { // Call this first, to not perform redundant work if there are no TAITs. let Some(taits_count) = ImplTraits::type_alias_impl_traits(db, type_alias) .as_deref() @@ -129,7 +129,7 @@ pub(crate) fn tait_hidden_types<'db>( let mut result = ArenaMap::with_capacity(taits_count); for defining_body in defining_bodies { let infer = InferenceResult::for_body(db, defining_body); - for (&opaque, &hidden_type) in &infer.type_of_opaque { + for (&opaque, hidden_type) in &infer.type_of_opaque { let ImplTraitId::TypeAliasImplTrait(opaque_owner, opaque_idx) = opaque.loc(db) else { continue; }; @@ -138,13 +138,18 @@ pub(crate) fn tait_hidden_types<'db>( } // In the presence of errors, we attempt to create a unified type from all // types. rustc doesn't do that, but this should improve the experience. - let hidden_type = infcx.insert_type_vars(hidden_type); + let hidden_type = infcx.insert_type_vars(hidden_type.as_ref()); match result.entry(opaque_idx) { la_arena::Entry::Vacant(entry) => { - entry.insert(EarlyBinder::bind(hidden_type)); + entry.insert(StoredEarlyBinder::bind(hidden_type.store())); } la_arena::Entry::Occupied(entry) => { - _ = ocx.eq(&cause, param_env, entry.get().instantiate_identity(), hidden_type); + _ = ocx.eq( + &cause, + param_env, + entry.get().get().instantiate_identity(), + hidden_type, + ); } } } @@ -157,12 +162,15 @@ pub(crate) fn tait_hidden_types<'db>( let idx = la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(idx as u32)); match result.entry(idx) { la_arena::Entry::Vacant(entry) => { - entry.insert(EarlyBinder::bind(Ty::new_error(interner, ErrorGuaranteed))); + entry.insert(StoredEarlyBinder::bind( + Ty::new_error(interner, ErrorGuaranteed).store(), + )); } la_arena::Entry::Occupied(mut entry) => { - *entry.get_mut() = entry.get().map_bound(|hidden_type| { - infcx.resolve_vars_if_possible(hidden_type).replace_infer_with_error(interner) - }); + let hidden_type = entry.get().get().skip_binder(); + let hidden_type = + infcx.resolve_vars_if_possible(hidden_type).replace_infer_with_error(interner); + *entry.get_mut() = StoredEarlyBinder::bind(hidden_type.store()); } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs index 4164e39e6592..d97a35549ca4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs @@ -2,7 +2,6 @@ use hir_def::{HasModule, ImplId, nameres::crate_def_map}; use intern::sym; -use rustc_type_ir::inherent::SliceLike; use tracing::debug; use crate::{ diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs index a31353f1e336..67ab89f5ec8f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs @@ -149,9 +149,10 @@ fn check_impl( let (body, body_source_map) = db.body_with_source_map(def); let inference_result = InferenceResult::for_body(&db, def); - for (pat, mut ty) in inference_result.type_of_pat.iter() { + for (pat, ty) in inference_result.type_of_pat.iter() { + let mut ty = ty.as_ref(); if let Pat::Bind { id, .. } = body[pat] { - ty = &inference_result.type_of_binding[id]; + ty = inference_result.type_of_binding[id].as_ref(); } let node = match pat_node(&body_source_map, pat, &db) { Some(value) => value, @@ -169,6 +170,7 @@ fn check_impl( } for (expr, ty) in inference_result.type_of_expr.iter() { + let ty = ty.as_ref(); let node = match expr_node(&body_source_map, expr, &db) { Some(value) => value, None => continue, @@ -209,8 +211,8 @@ fn check_impl( let range = node.as_ref().original_file_range_rooted(&db); let actual = format!( "expected {}, got {}", - mismatch.expected.display_test(&db, display_target), - mismatch.actual.display_test(&db, display_target) + mismatch.expected.as_ref().display_test(&db, display_target), + mismatch.actual.as_ref().display_test(&db, display_target) ); match mismatches.remove(&range) { Some(annotation) => assert_eq!(actual, annotation), @@ -318,20 +320,20 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { crate::attach_db(&db, || { let mut buf = String::new(); - let mut infer_def = |inference_result: &InferenceResult<'_>, + let mut infer_def = |inference_result: &InferenceResult, body: Arc, body_source_map: Arc, krate: Crate| { let display_target = DisplayTarget::from_crate(&db, krate); - let mut types: Vec<(InFile, &Ty<'_>)> = Vec::new(); - let mut mismatches: Vec<(InFile, &TypeMismatch<'_>)> = Vec::new(); + let mut types: Vec<(InFile, Ty<'_>)> = Vec::new(); + let mut mismatches: Vec<(InFile, &TypeMismatch)> = Vec::new(); if let Some(self_param) = body.self_param { let ty = &inference_result.type_of_binding[self_param]; if let Some(syntax_ptr) = body_source_map.self_param_syntax() { let root = db.parse_or_expand(syntax_ptr.file_id); let node = syntax_ptr.map(|ptr| ptr.to_node(&root).syntax().clone()); - types.push((node, ty)); + types.push((node, ty.as_ref())); } } @@ -346,7 +348,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { } Err(SyntheticSyntax) => continue, }; - types.push((node.clone(), ty)); + types.push((node.clone(), ty.as_ref())); if let Some(mismatch) = inference_result.type_mismatch_for_pat(pat) { mismatches.push((node, mismatch)); } @@ -360,7 +362,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { } Err(SyntheticSyntax) => continue, }; - types.push((node.clone(), ty)); + types.push((node.clone(), ty.as_ref())); if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr) { mismatches.push((node, mismatch)); } @@ -401,8 +403,8 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { "{}{:?}: expected {}, got {}\n", macro_prefix, range, - mismatch.expected.display_test(&db, display_target), - mismatch.actual.display_test(&db, display_target), + mismatch.expected.as_ref().display_test(&db, display_target), + mismatch.actual.as_ref().display_test(&db, display_target), ); } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs index ff55ff54cefb..3bdc72d01500 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/closure_captures.rs @@ -74,6 +74,7 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec let place = capture.display_place(closure.0, db); let capture_ty = capture .ty + .get() .skip_binder() .display_test(db, DisplayTarget::from_crate(db, module.krate(db))) .to_string(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index 7b0c1d35442e..6558d2179fba 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -28,7 +28,7 @@ fn foo() -> i32 { } }); }, - &[("InferenceResult < 'db >::for_body_", 1)], + &[("InferenceResult::for_body_", 1)], expect_test::expect![[r#" [ "crate_local_def_map", @@ -36,17 +36,17 @@ fn foo() -> i32 { "ast_id_map_shim", "parse_shim", "real_span_map_shim", - "InferenceResult < 'db >::for_body_", + "InferenceResult::for_body_", "function_signature_shim", "function_signature_with_source_map_shim", "AttrFlags::query_", "body_shim", "body_with_source_map_shim", - "trait_environment_shim", + "trait_environment_query", "lang_items", "crate_lang_items", - "GenericPredicates < 'db >::query_with_diagnostics_", - "ImplTraits < 'db >::return_type_impl_traits_", + "GenericPredicates::query_with_diagnostics_", + "ImplTraits::return_type_impl_traits_", "expr_scopes_shim", ] "#]], @@ -72,7 +72,7 @@ fn foo() -> i32 { } }); }, - &[("InferenceResult < 'db >::for_body_", 0)], + &[("InferenceResult::for_body_", 0)], expect_test::expect![[r#" [ "parse_shim", @@ -115,7 +115,7 @@ fn baz() -> i32 { } }); }, - &[("InferenceResult < 'db >::for_body_", 3)], + &[("InferenceResult::for_body_", 3)], expect_test::expect![[r#" [ "crate_local_def_map", @@ -123,37 +123,37 @@ fn baz() -> i32 { "ast_id_map_shim", "parse_shim", "real_span_map_shim", - "InferenceResult < 'db >::for_body_", + "InferenceResult::for_body_", "function_signature_shim", "function_signature_with_source_map_shim", "AttrFlags::query_", "body_shim", "body_with_source_map_shim", - "trait_environment_shim", + "trait_environment_query", "lang_items", "crate_lang_items", "AttrFlags::query_", "AttrFlags::query_", - "GenericPredicates < 'db >::query_with_diagnostics_", - "ImplTraits < 'db >::return_type_impl_traits_", + "GenericPredicates::query_with_diagnostics_", + "ImplTraits::return_type_impl_traits_", "expr_scopes_shim", - "InferenceResult < 'db >::for_body_", + "InferenceResult::for_body_", "function_signature_shim", "function_signature_with_source_map_shim", "body_shim", "body_with_source_map_shim", - "trait_environment_shim", - "GenericPredicates < 'db >::query_with_diagnostics_", - "ImplTraits < 'db >::return_type_impl_traits_", + "trait_environment_query", + "GenericPredicates::query_with_diagnostics_", + "ImplTraits::return_type_impl_traits_", "expr_scopes_shim", - "InferenceResult < 'db >::for_body_", + "InferenceResult::for_body_", "function_signature_shim", "function_signature_with_source_map_shim", "body_shim", "body_with_source_map_shim", - "trait_environment_shim", - "GenericPredicates < 'db >::query_with_diagnostics_", - "ImplTraits < 'db >::return_type_impl_traits_", + "trait_environment_query", + "GenericPredicates::query_with_diagnostics_", + "ImplTraits::return_type_impl_traits_", "expr_scopes_shim", ] "#]], @@ -184,7 +184,7 @@ fn baz() -> i32 { } }); }, - &[("InferenceResult < 'db >::for_body_", 1)], + &[("InferenceResult::for_body_", 1)], expect_test::expect![[r#" [ "parse_shim", @@ -202,7 +202,7 @@ fn baz() -> i32 { "function_signature_shim", "body_with_source_map_shim", "body_shim", - "InferenceResult < 'db >::for_body_", + "InferenceResult::for_body_", "expr_scopes_shim", "function_signature_with_source_map_shim", "function_signature_shim", @@ -502,7 +502,7 @@ impl SomeStruct { "crate_local_def_map", "TraitImpls::for_crate_", "AttrFlags::query_", - "impl_trait_with_diagnostics_shim", + "impl_trait_with_diagnostics_query", "impl_signature_shim", "impl_signature_with_source_map_shim", "lang_items", @@ -512,7 +512,7 @@ impl SomeStruct { "AttrFlags::query_", "AttrFlags::query_", "AttrFlags::query_", - "impl_self_ty_with_diagnostics_shim", + "impl_self_ty_with_diagnostics_query", "struct_signature_shim", "struct_signature_with_source_map_shim", ] @@ -574,7 +574,7 @@ fn main() { "body_with_source_map_shim", "AttrFlags::query_", "ImplItems::of_", - "InferenceResult < 'db >::for_body_", + "InferenceResult::for_body_", "trait_signature_shim", "trait_signature_with_source_map_shim", "AttrFlags::query_", @@ -583,36 +583,36 @@ fn main() { "AttrFlags::query_", "body_shim", "body_with_source_map_shim", - "trait_environment_shim", + "trait_environment_query", "lang_items", "crate_lang_items", "AttrFlags::query_", "AttrFlags::query_", - "GenericPredicates < 'db >::query_with_diagnostics_", - "GenericPredicates < 'db >::query_with_diagnostics_", - "ImplTraits < 'db >::return_type_impl_traits_", - "InferenceResult < 'db >::for_body_", + "GenericPredicates::query_with_diagnostics_", + "GenericPredicates::query_with_diagnostics_", + "ImplTraits::return_type_impl_traits_", + "InferenceResult::for_body_", "function_signature_shim", "function_signature_with_source_map_shim", - "trait_environment_shim", - "GenericPredicates < 'db >::query_with_diagnostics_", - "ImplTraits < 'db >::return_type_impl_traits_", + "trait_environment_query", + "GenericPredicates::query_with_diagnostics_", + "ImplTraits::return_type_impl_traits_", "expr_scopes_shim", "struct_signature_shim", "struct_signature_with_source_map_shim", - "GenericPredicates < 'db >::query_with_diagnostics_", - "value_ty_shim", + "GenericPredicates::query_with_diagnostics_", + "value_ty_query", "VariantFields::firewall_", "VariantFields::query_", "InherentImpls::for_crate_", "impl_signature_shim", "impl_signature_with_source_map_shim", - "callable_item_signature_shim", + "callable_item_signature_query", "TraitImpls::for_crate_and_deps_", "TraitImpls::for_crate_", - "impl_trait_with_diagnostics_shim", - "impl_self_ty_with_diagnostics_shim", - "GenericPredicates < 'db >::query_with_diagnostics_", + "impl_trait_with_diagnostics_query", + "impl_self_ty_with_diagnostics_query", + "GenericPredicates::query_with_diagnostics_", ] "#]], ); @@ -671,7 +671,7 @@ fn main() { "AttrFlags::query_", "body_shim", "ImplItems::of_", - "InferenceResult < 'db >::for_body_", + "InferenceResult::for_body_", "AttrFlags::query_", "trait_signature_with_source_map_shim", "AttrFlags::query_", @@ -683,25 +683,25 @@ fn main() { "AttrFlags::query_", "AttrFlags::query_", "AttrFlags::query_", - "GenericPredicates < 'db >::query_with_diagnostics_", - "GenericPredicates < 'db >::query_with_diagnostics_", - "ImplTraits < 'db >::return_type_impl_traits_", - "InferenceResult < 'db >::for_body_", + "GenericPredicates::query_with_diagnostics_", + "GenericPredicates::query_with_diagnostics_", + "ImplTraits::return_type_impl_traits_", + "InferenceResult::for_body_", "function_signature_with_source_map_shim", - "GenericPredicates < 'db >::query_with_diagnostics_", - "ImplTraits < 'db >::return_type_impl_traits_", + "GenericPredicates::query_with_diagnostics_", + "ImplTraits::return_type_impl_traits_", "expr_scopes_shim", "struct_signature_with_source_map_shim", - "GenericPredicates < 'db >::query_with_diagnostics_", + "GenericPredicates::query_with_diagnostics_", "VariantFields::query_", "InherentImpls::for_crate_", "impl_signature_with_source_map_shim", "impl_signature_shim", - "callable_item_signature_shim", + "callable_item_signature_query", "TraitImpls::for_crate_", - "impl_trait_with_diagnostics_shim", - "impl_self_ty_with_diagnostics_shim", - "GenericPredicates < 'db >::query_with_diagnostics_", + "impl_trait_with_diagnostics_query", + "impl_self_ty_with_diagnostics_query", + "GenericPredicates::query_with_diagnostics_", ] "#]], ); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index 2f8c31ec6074..ad8de293d5a5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -21,8 +21,8 @@ use rustc_type_ir::{ use crate::{ db::HirDatabase, next_solver::{ - Canonical, DbInterner, GenericArgs, Goal, ParamEnv, Predicate, SolverContext, Span, Ty, - TyKind, + Canonical, DbInterner, GenericArgs, Goal, ParamEnv, Predicate, SolverContext, Span, + StoredClauses, Ty, TyKind, infer::{DbInternerInferExt, InferCtxt, traits::ObligationCause}, obligation_ctxt::ObligationCtxt, }, @@ -35,6 +35,31 @@ pub struct ParamEnvAndCrate<'db> { pub krate: Crate, } +impl<'db> ParamEnvAndCrate<'db> { + #[inline] + pub fn store(self) -> StoredParamEnvAndCrate { + StoredParamEnvAndCrate { param_env: self.param_env.clauses.store(), krate: self.krate } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct StoredParamEnvAndCrate { + param_env: StoredClauses, + pub krate: Crate, +} + +impl StoredParamEnvAndCrate { + #[inline] + pub fn param_env(&self) -> ParamEnv<'_> { + ParamEnv { clauses: self.param_env.as_ref() } + } + + #[inline] + pub fn as_ref(&self) -> ParamEnvAndCrate<'_> { + ParamEnvAndCrate { param_env: self.param_env(), krate: self.krate } + } +} + /// This should be used in `hir` only. pub fn structurally_normalize_ty<'db>( infcx: &InferCtxt<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index b32180d41247..bfb9a3f77e94 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs @@ -17,7 +17,7 @@ use hir_def::{AdtId, GenericDefId, GenericParamId, VariantId, signatures::Struct use rustc_ast_ir::Mutability; use rustc_type_ir::{ Variance, - inherent::{AdtDef, IntoKind, SliceLike}, + inherent::{AdtDef, IntoKind}, }; use stdx::never; @@ -25,12 +25,22 @@ use crate::{ db::HirDatabase, generics::{Generics, generics}, next_solver::{ - Const, ConstKind, DbInterner, ExistentialPredicate, GenericArg, GenericArgs, Region, - RegionKind, Term, Ty, TyKind, VariancesOf, + Const, ConstKind, DbInterner, ExistentialPredicate, GenericArgKind, GenericArgs, Region, + RegionKind, StoredVariancesOf, TermKind, Ty, TyKind, VariancesOf, }, }; pub(crate) fn variances_of(db: &dyn HirDatabase, def: GenericDefId) -> VariancesOf<'_> { + variances_of_query(db, def).as_ref() +} + +#[salsa::tracked( + returns(ref), + // cycle_fn = crate::variance::variances_of_cycle_fn, + // cycle_initial = crate::variance::variances_of_cycle_initial, + cycle_result = crate::variance::variances_of_cycle_initial, +)] +fn variances_of_query(db: &dyn HirDatabase, def: GenericDefId) -> StoredVariancesOf { tracing::debug!("variances_of(def={:?})", def); let interner = DbInterner::new_no_crate(db); match def { @@ -39,19 +49,19 @@ pub(crate) fn variances_of(db: &dyn HirDatabase, def: GenericDefId) -> Variances if let AdtId::StructId(id) = adt { let flags = &db.struct_signature(id).flags; if flags.contains(StructFlags::IS_UNSAFE_CELL) { - return VariancesOf::new_from_iter(interner, [Variance::Invariant]); + return VariancesOf::new_from_iter(interner, [Variance::Invariant]).store(); } else if flags.contains(StructFlags::IS_PHANTOM_DATA) { - return VariancesOf::new_from_iter(interner, [Variance::Covariant]); + return VariancesOf::new_from_iter(interner, [Variance::Covariant]).store(); } } } - _ => return VariancesOf::new_from_iter(interner, []), + _ => return VariancesOf::empty(interner).store(), } let generics = generics(db, def); let count = generics.len(); if count == 0 { - return VariancesOf::new_from_iter(interner, []); + return VariancesOf::empty(interner).store(); } let mut variances = Context { generics, variances: vec![Variance::Bivariant; count], db }.solve(); @@ -71,7 +81,7 @@ pub(crate) fn variances_of(db: &dyn HirDatabase, def: GenericDefId) -> Variances } } - VariancesOf::new_from_iter(interner, variances) + VariancesOf::new_from_iter(interner, variances).store() } // pub(crate) fn variances_of_cycle_fn( @@ -107,13 +117,13 @@ pub(crate) fn variances_of_cycle_initial( db: &dyn HirDatabase, _: salsa::Id, def: GenericDefId, -) -> VariancesOf<'_> { +) -> StoredVariancesOf { let interner = DbInterner::new_no_crate(db); let generics = generics(db, def); let count = generics.len(); // FIXME(next-solver): Returns `Invariance` and not `Bivariance` here, see the comment in the main query. - VariancesOf::new_from_iter(interner, std::iter::repeat_n(Variance::Invariant, count)) + VariancesOf::new_from_iter(interner, std::iter::repeat_n(Variance::Invariant, count)).store() } struct Context<'db> { @@ -131,7 +141,7 @@ impl<'db> Context<'db> { let mut add_constraints_from_variant = |variant| { for (_, field) in db.field_types(variant).iter() { self.add_constraints_from_ty( - field.instantiate_identity(), + field.get().instantiate_identity(), Variance::Covariant, ); } @@ -233,11 +243,11 @@ impl<'db> Context<'db> { } ExistentialPredicate::Projection(projection) => { self.add_constraints_from_invariant_args(projection.args); - match projection.term { - Term::Ty(ty) => { + match projection.term.kind() { + TermKind::Ty(ty) => { self.add_constraints_from_ty(ty, Variance::Invariant) } - Term::Const(konst) => self.add_constraints_from_const(konst), + TermKind::Const(konst) => self.add_constraints_from_const(konst), } } ExistentialPredicate::AutoTrait(_) => {} @@ -267,12 +277,12 @@ impl<'db> Context<'db> { fn add_constraints_from_invariant_args(&mut self, args: GenericArgs<'db>) { for k in args.iter() { - match k { - GenericArg::Lifetime(lt) => { + match k.kind() { + GenericArgKind::Lifetime(lt) => { self.add_constraints_from_region(lt, Variance::Invariant) } - GenericArg::Ty(ty) => self.add_constraints_from_ty(ty, Variance::Invariant), - GenericArg::Const(val) => self.add_constraints_from_const(val), + GenericArgKind::Type(ty) => self.add_constraints_from_ty(ty, Variance::Invariant), + GenericArgKind::Const(val) => self.add_constraints_from_const(val), } } } @@ -291,10 +301,12 @@ impl<'db> Context<'db> { let variances = self.db.variances_of(def_id); for (k, v) in args.iter().zip(variances) { - match k { - GenericArg::Lifetime(lt) => self.add_constraints_from_region(lt, variance.xform(v)), - GenericArg::Ty(ty) => self.add_constraints_from_ty(ty, variance.xform(v)), - GenericArg::Const(val) => self.add_constraints_from_const(val), + match k.kind() { + GenericArgKind::Lifetime(lt) => { + self.add_constraints_from_region(lt, variance.xform(v)) + } + GenericArgKind::Type(ty) => self.add_constraints_from_ty(ty, variance.xform(v)), + GenericArgKind::Const(val) => self.add_constraints_from_const(val), } } } @@ -388,7 +400,7 @@ mod tests { AdtId, GenericDefId, ModuleDefId, hir::generics::GenericParamDataRef, src::HasSource, }; use itertools::Itertools; - use rustc_type_ir::{Variance, inherent::SliceLike}; + use rustc_type_ir::Variance; use stdx::format_to; use syntax::{AstNode, ast::HasName}; use test_fixture::WithFixture; diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs index 6ef6ea272e58..050777a4806d 100644 --- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs @@ -617,7 +617,7 @@ impl<'db> AnyDiagnostic<'db> { pub(crate) fn inference_diagnostic( db: &'db dyn HirDatabase, def: DefWithBodyId, - d: &InferenceDiagnostic<'db>, + d: &InferenceDiagnostic, source_map: &hir_def::expr_store::BodySourceMap, sig_map: &hir_def::expr_store::ExpressionStoreSourceMap, ) -> Option> { @@ -663,7 +663,8 @@ impl<'db> AnyDiagnostic<'db> { } InferenceDiagnostic::ExpectedFunction { call_expr, found } => { let call_expr = expr_syntax(*call_expr)?; - ExpectedFunction { call: call_expr, found: Type::new(db, def, *found) }.into() + ExpectedFunction { call: call_expr, found: Type::new(db, def, found.as_ref()) } + .into() } InferenceDiagnostic::UnresolvedField { expr, @@ -675,7 +676,7 @@ impl<'db> AnyDiagnostic<'db> { UnresolvedField { expr, name: name.clone(), - receiver: Type::new(db, def, *receiver), + receiver: Type::new(db, def, receiver.as_ref()), method_with_same_name_exists: *method_with_same_name_exists, } .into() @@ -691,8 +692,10 @@ impl<'db> AnyDiagnostic<'db> { UnresolvedMethodCall { expr, name: name.clone(), - receiver: Type::new(db, def, *receiver), - field_with_same_name: (*field_with_same_name).map(|ty| Type::new(db, def, ty)), + receiver: Type::new(db, def, receiver.as_ref()), + field_with_same_name: field_with_same_name + .as_ref() + .map(|ty| Type::new(db, def, ty.as_ref())), assoc_func_with_same_name: assoc_func_with_same_name.map(Into::into), } .into() @@ -719,7 +722,7 @@ impl<'db> AnyDiagnostic<'db> { } InferenceDiagnostic::TypedHole { expr, expected } => { let expr = expr_syntax(*expr)?; - TypedHole { expr, expected: Type::new(db, def, *expected) }.into() + TypedHole { expr, expected: Type::new(db, def, expected.as_ref()) }.into() } &InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => { let expr_or_pat = match pat { @@ -736,12 +739,12 @@ impl<'db> AnyDiagnostic<'db> { } InferenceDiagnostic::CastToUnsized { expr, cast_ty } => { let expr = expr_syntax(*expr)?; - CastToUnsized { expr, cast_ty: Type::new(db, def, *cast_ty) }.into() + CastToUnsized { expr, cast_ty: Type::new(db, def, cast_ty.as_ref()) }.into() } InferenceDiagnostic::InvalidCast { expr, error, expr_ty, cast_ty } => { let expr = expr_syntax(*expr)?; - let expr_ty = Type::new(db, def, *expr_ty); - let cast_ty = Type::new(db, def, *cast_ty); + let expr_ty = Type::new(db, def, expr_ty.as_ref()); + let cast_ty = Type::new(db, def, cast_ty.as_ref()); InvalidCast { expr, error: *error, expr_ty, cast_ty }.into() } InferenceDiagnostic::TyDiagnostic { source, diag } => { diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index ae7e4aa6c8ac..3532220b72ae 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -102,7 +102,7 @@ use rustc_type_ir::{ }; use smallvec::SmallVec; use span::{AstIdNode, Edition, FileId}; -use stdx::{format_to, impl_from, never}; +use stdx::{format_to, impl_from, never, variance::PhantomCovariantLifetime}; use syntax::{ AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, ast::{self, HasName, HasVisibility as _}, @@ -697,7 +697,7 @@ impl Module { push_ty_diagnostics( db, acc, - db.field_types_with_diagnostics(s.id.into()).1, + db.field_types_with_diagnostics(s.id.into()).1.clone(), source_map, ); } @@ -709,7 +709,7 @@ impl Module { push_ty_diagnostics( db, acc, - db.field_types_with_diagnostics(u.id.into()).1, + db.field_types_with_diagnostics(u.id.into()).1.clone(), source_map, ); } @@ -739,7 +739,7 @@ impl Module { push_ty_diagnostics( db, acc, - db.field_types_with_diagnostics(v.into()).1, + db.field_types_with_diagnostics(v.into()).1.clone(), source_map, ); expr_store_diagnostics(db, acc, source_map); @@ -1219,7 +1219,7 @@ impl<'db> InstantiatedField<'db> { let interner = DbInterner::new_no_crate(db); let var_id = self.inner.parent.into(); - let field = db.field_types(var_id)[self.inner.id]; + let field = db.field_types(var_id)[self.inner.id].get(); let ty = field.instantiate(interner, self.args); TypeNs::new(db, var_id, ty) } @@ -1297,7 +1297,7 @@ impl Field { /// context of the field definition. pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> TypeNs<'db> { let var_id = self.parent.into(); - let ty = db.field_types(var_id)[self.id].skip_binder(); + let ty = db.field_types(var_id)[self.id].get().skip_binder(); TypeNs::new(db, var_id, ty) } @@ -1315,13 +1315,13 @@ impl Field { }; let interner = DbInterner::new_no_crate(db); let args = generic_args_from_tys(interner, def_id.into(), generics.map(|ty| ty.ty)); - let ty = db.field_types(var_id)[self.id].instantiate(interner, args); + let ty = db.field_types(var_id)[self.id].get().instantiate(interner, args); Type::new(db, var_id, ty) } pub fn layout(&self, db: &dyn HirDatabase) -> Result { db.layout_of_ty( - self.ty(db).ty, + self.ty(db).ty.store(), param_env_from_has_crate( db, match hir_def::VariantId::from(self.parent) { @@ -1331,7 +1331,8 @@ impl Field { hir_def::VariantId::StructId(id) => GenericDefId::AdtId(id.into()), hir_def::VariantId::UnionId(id) => GenericDefId::AdtId(id.into()), }, - ), + ) + .store(), ) .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).into()).unwrap())) } @@ -1662,7 +1663,7 @@ impl Variant { self.source(db)?.value.expr() } - pub fn eval(self, db: &dyn HirDatabase) -> Result> { + pub fn eval(self, db: &dyn HirDatabase) -> Result { db.const_eval_discriminant(self.into()) } @@ -1753,7 +1754,7 @@ impl Adt { let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, id, _| { GenericArg::error_from_id(interner, id) }); - db.layout_of_adt(adt_id, args, param_env_from_has_crate(db, adt_id)) + db.layout_of_adt(adt_id, args.store(), param_env_from_has_crate(db, adt_id).store()) .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).id).unwrap())) } @@ -1988,8 +1989,8 @@ impl DefWithBody { acc.push( TypeMismatch { expr_or_pat, - expected: Type::new(db, DefWithBodyId::from(self), mismatch.expected), - actual: Type::new(db, DefWithBodyId::from(self), mismatch.actual), + expected: Type::new(db, DefWithBodyId::from(self), mismatch.expected.as_ref()), + actual: Type::new(db, DefWithBodyId::from(self), mismatch.actual.as_ref()), } .into(), ); @@ -2059,7 +2060,10 @@ impl DefWithBody { } mir::MirSpan::Unknown => continue, }; - acc.push(MovedOutOfRef { ty: Type::new_for_crate(krate, moof.ty), span }.into()) + acc.push( + MovedOutOfRef { ty: Type::new_for_crate(krate, moof.ty.as_ref()), span } + .into(), + ) } let mol = &borrowck_result.mutability_of_locals; for (binding_id, binding_data) in body.bindings() { @@ -2468,15 +2472,16 @@ impl Function { self, db: &dyn HirDatabase, span_formatter: impl Fn(FileId, TextRange) -> String, - ) -> Result> { + ) -> Result { let interner = DbInterner::new_no_crate(db); let body = db.monomorphized_mir_body( self.id.into(), - GenericArgs::new_from_iter(interner, []), + GenericArgs::empty(interner).store(), ParamEnvAndCrate { param_env: db.trait_environment(self.id.into()), krate: self.id.module(db).krate(db), - }, + } + .store(), )?; let (result, output) = interpret_mir(db, body, false, None)?; let mut text = match result { @@ -2728,11 +2733,14 @@ impl Const { } /// Evaluate the constant. - pub fn eval(self, db: &dyn HirDatabase) -> Result, ConstEvalError<'_>> { + pub fn eval(self, db: &dyn HirDatabase) -> Result, ConstEvalError> { let interner = DbInterner::new_no_crate(db); let ty = db.value_ty(self.id.into()).unwrap().instantiate_identity(); - db.const_eval(self.id, GenericArgs::new_from_iter(interner, []), None) - .map(|it| EvaluatedConst { const_: it, def: self.id.into(), ty }) + db.const_eval(self.id, GenericArgs::empty(interner), None).map(|it| EvaluatedConst { + const_: it, + def: self.id.into(), + ty, + }) } } @@ -2753,7 +2761,7 @@ impl<'db> EvaluatedConst<'db> { format!("{}", self.const_.display(db, display_target)) } - pub fn render_debug(&self, db: &'db dyn HirDatabase) -> Result> { + pub fn render_debug(&self, db: &'db dyn HirDatabase) -> Result { let kind = self.const_.kind(); if let ConstKind::Value(c) = kind && let ty = c.ty.kind() @@ -2809,7 +2817,7 @@ impl Static { } /// Evaluate the static initializer. - pub fn eval(self, db: &dyn HirDatabase) -> Result, ConstEvalError<'_>> { + pub fn eval(self, db: &dyn HirDatabase) -> Result, ConstEvalError> { let ty = db.value_ty(self.id.into()).unwrap().instantiate_identity(); db.const_eval_static(self.id).map(|it| EvaluatedConst { const_: it, @@ -3847,7 +3855,7 @@ impl Local { pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { let def = self.parent; let infer = InferenceResult::for_body(db, def); - let ty = infer[self.binding_id]; + let ty = infer.binding_ty(self.binding_id); Type::new(db, def, ty) } @@ -4152,8 +4160,8 @@ impl TypeParam { pub fn default(self, db: &dyn HirDatabase) -> Option> { let ty = generic_arg_from_param(db, self.id.into())?; let resolver = self.id.parent().resolver(db); - match ty { - GenericArg::Ty(it) if !it.is_ty_error() => { + match ty.kind() { + rustc_type_ir::GenericArgKind::Type(it) if !it.is_ty_error() => { Some(Type::new_with_resolver_inner(db, &resolver, it)) } _ => None, @@ -4545,7 +4553,12 @@ impl<'db> Closure<'db> { info.0 .iter() .cloned() - .map(|capture| ClosureCapture { owner, closure: id, capture }) + .map(|capture| ClosureCapture { + owner, + closure: id, + capture, + _marker: PhantomCovariantLifetime::new(), + }) .collect() } @@ -4650,7 +4663,8 @@ impl FnTrait { pub struct ClosureCapture<'db> { owner: DefWithBodyId, closure: InternedClosureId, - capture: hir_ty::CapturedItem<'db>, + capture: hir_ty::CapturedItem, + _marker: PhantomCovariantLifetime<'db>, } impl<'db> ClosureCapture<'db> { @@ -4917,7 +4931,7 @@ impl<'db> Type<'db> { .fields() .iter() .map(|(idx, _)| { - field_types[idx].instantiate(self.interner, args) + field_types[idx].get().instantiate(self.interner, args) }) .filter(|it| !it.references_non_lt_error()) .collect() @@ -5241,7 +5255,7 @@ impl<'db> Type<'db> { .iter() .map(|(local_id, ty)| { let def = Field { parent: variant_id.into(), id: local_id }; - let ty = ty.instantiate(interner, substs); + let ty = ty.get().instantiate(interner, substs); (def, self.derived(ty)) }) .collect() @@ -5399,12 +5413,14 @@ impl<'db> Type<'db> { .as_adt() .into_iter() .flat_map(|(_, substs)| substs.iter()) - .filter_map(move |arg| match arg { - GenericArg::Ty(ty) => Some(format_smolstr!("{}", ty.display(db, display_target))), - GenericArg::Const(const_) => { + .filter_map(move |arg| match arg.kind() { + rustc_type_ir::GenericArgKind::Type(ty) => { + Some(format_smolstr!("{}", ty.display(db, display_target))) + } + rustc_type_ir::GenericArgKind::Const(const_) => { Some(format_smolstr!("{}", const_.display(db, display_target))) } - GenericArg::Lifetime(_) => None, + rustc_type_ir::GenericArgKind::Lifetime(_) => None, }) } @@ -5808,7 +5824,7 @@ impl<'db> Type<'db> { } pub fn layout(&self, db: &'db dyn HirDatabase) -> Result { - db.layout_of_ty(self.ty, self.env) + db.layout_of_ty(self.ty.store(), self.env.store()) .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap())) } @@ -5840,7 +5856,7 @@ impl<'db> TypeNs<'db> { pub fn impls_trait(&self, infcx: InferCtxt<'db>, trait_: Trait, args: &[TypeNs<'db>]) -> bool { let args = GenericArgs::new_from_iter( infcx.interner, - [self.ty].into_iter().chain(args.iter().map(|t| t.ty)).map(|t| t.into()), + [self.ty].into_iter().chain(args.iter().map(|t| t.ty)).map(GenericArg::from), ); let trait_ref = hir_ty::next_solver::TraitRef::new(infcx.interner, trait_.id.into(), args); diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index b65a24d61c6e..fd08528e86ab 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -1653,8 +1653,11 @@ impl<'db> SemanticsImpl<'db> { analyzer.expr_adjustments(expr).map(|it| { it.iter() .map(|adjust| { - let target = - Type::new_with_resolver(self.db, &analyzer.resolver, adjust.target); + let target = Type::new_with_resolver( + self.db, + &analyzer.resolver, + adjust.target.as_ref(), + ); let kind = match adjust.kind { hir_ty::Adjust::NeverToAny => Adjust::NeverToAny, hir_ty::Adjust::Deref(Some(hir_ty::OverloadedDeref(m))) => { diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index b90eb97d8791..848ad3380133 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -79,7 +79,7 @@ pub(crate) enum BodyOrSig<'db> { def: DefWithBodyId, body: Arc, source_map: Arc, - infer: Option<&'db InferenceResult<'db>>, + infer: Option<&'db InferenceResult>, }, // To be folded into body once it is considered one VariantFields { @@ -119,7 +119,7 @@ impl<'db> SourceAnalyzer<'db> { def: DefWithBodyId, node @ InFile { file_id, .. }: InFile<&SyntaxNode>, offset: Option, - infer: Option<&'db InferenceResult<'db>>, + infer: Option<&'db InferenceResult>, ) -> SourceAnalyzer<'db> { let (body, source_map) = db.body_with_source_map(def); let scopes = db.expr_scopes(def); @@ -185,9 +185,7 @@ impl<'db> SourceAnalyzer<'db> { } // FIXME: Remove this - fn body_( - &self, - ) -> Option<(DefWithBodyId, &Body, &BodySourceMap, Option<&InferenceResult<'db>>)> { + fn body_(&self) -> Option<(DefWithBodyId, &Body, &BodySourceMap, Option<&InferenceResult>)> { self.body_or_sig.as_ref().and_then(|it| match it { BodyOrSig::Body { def, body, source_map, infer } => { Some((*def, &**body, &**source_map, infer.as_deref())) @@ -196,7 +194,7 @@ impl<'db> SourceAnalyzer<'db> { }) } - fn infer(&self) -> Option<&InferenceResult<'db>> { + fn infer(&self) -> Option<&InferenceResult> { self.body_or_sig.as_ref().and_then(|it| match it { BodyOrSig::Sig { .. } => None, BodyOrSig::VariantFields { .. } => None, @@ -260,7 +258,7 @@ impl<'db> SourceAnalyzer<'db> { if let Pat::Bind { id, .. } = self.store()?[pat_id.as_pat()?] { Some(id) } else { None } } - pub(crate) fn expr_adjustments(&self, expr: &ast::Expr) -> Option<&[Adjustment<'db>]> { + pub(crate) fn expr_adjustments(&self, expr: &ast::Expr) -> Option<&[Adjustment]> { // It is safe to omit destructuring assignments here because they have no adjustments (neither // expressions nor patterns). let expr_id = self.expr_id(expr.clone())?.as_expr()?; @@ -326,8 +324,8 @@ impl<'db> SourceAnalyzer<'db> { let coerced = expr_id .as_expr() .and_then(|expr_id| infer.expr_adjustment(expr_id)) - .and_then(|adjusts| adjusts.last().map(|adjust| adjust.target)); - let ty = infer[expr_id]; + .and_then(|adjusts| adjusts.last().map(|adjust| adjust.target.as_ref())); + let ty = infer.expr_or_pat_ty(expr_id); let mk_ty = |ty: Ty<'db>| Type::new_with_resolver(db, &self.resolver, ty); Some((mk_ty(ty), coerced.map(mk_ty))) } @@ -342,14 +340,15 @@ impl<'db> SourceAnalyzer<'db> { let coerced = match expr_or_pat_id { ExprOrPatId::ExprId(idx) => infer .expr_adjustment(idx) - .and_then(|adjusts| adjusts.last().cloned()) - .map(|adjust| adjust.target), - ExprOrPatId::PatId(idx) => { - infer.pat_adjustment(idx).and_then(|adjusts| adjusts.last().cloned()) - } + .and_then(|adjusts| adjusts.last()) + .map(|adjust| adjust.target.as_ref()), + ExprOrPatId::PatId(idx) => infer + .pat_adjustment(idx) + .and_then(|adjusts| adjusts.last()) + .map(|adjust| adjust.as_ref()), }; - let ty = infer[expr_or_pat_id]; + let ty = infer.expr_or_pat_ty(expr_or_pat_id); let mk_ty = |ty: Ty<'db>| Type::new_with_resolver(db, &self.resolver, ty); Some((mk_ty(ty), coerced.map(mk_ty))) } @@ -361,7 +360,7 @@ impl<'db> SourceAnalyzer<'db> { ) -> Option> { let binding_id = self.binding_id_of_pat(pat)?; let infer = self.infer()?; - let ty = infer[binding_id]; + let ty = infer.binding_ty(binding_id); let mk_ty = |ty: Ty<'db>| Type::new_with_resolver(db, &self.resolver, ty); Some(mk_ty(ty)) } @@ -372,7 +371,7 @@ impl<'db> SourceAnalyzer<'db> { _param: &ast::SelfParam, ) -> Option> { let binding = self.body()?.self_param?; - let ty = self.infer()?[binding]; + let ty = self.infer()?.binding_ty(binding); Some(Type::new_with_resolver(db, &self.resolver, ty)) } @@ -404,7 +403,7 @@ impl<'db> SourceAnalyzer<'db> { infer .pat_adjustment(pat_id.as_pat()?)? .iter() - .map(|ty| Type::new_with_resolver(db, &self.resolver, *ty)) + .map(|ty| Type::new_with_resolver(db, &self.resolver, ty.as_ref())) .collect(), ) } @@ -482,7 +481,7 @@ impl<'db> SourceAnalyzer<'db> { fn field_subst( &self, field_expr: ExprId, - infer: &InferenceResult<'db>, + infer: &InferenceResult, db: &'db dyn HirDatabase, ) -> Option> { let body = self.store()?; @@ -598,8 +597,7 @@ impl<'db> SourceAnalyzer<'db> { let poll_fn = self.lang_items(db).FuturePoll?; // HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself // doesn't have any generic parameters, so we skip building another subst for `poll()`. - let interner = DbInterner::new_no_crate(db); - let substs = GenericArgs::new_from_iter(interner, [ty.into()]); + let substs = GenericArgs::new_from_slice(&[ty.into()]); Some(self.resolve_impl_method_or_trait_def(db, poll_fn, substs)) } @@ -641,10 +639,9 @@ impl<'db> SourceAnalyzer<'db> { let ty = self.ty_of_expr(prefix_expr.expr()?)?; - let interner = DbInterner::new_no_crate(db); // HACK: subst for all methods coincides with that for their trait because the methods // don't have any generic parameters, so we skip building another subst for the methods. - let substs = GenericArgs::new_from_iter(interner, [ty.into()]); + let substs = GenericArgs::new_from_slice(&[ty.into()]); Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) } @@ -674,8 +671,7 @@ impl<'db> SourceAnalyzer<'db> { .unwrap_or(index_fn); // HACK: subst for all methods coincides with that for their trait because the methods // don't have any generic parameters, so we skip building another subst for the methods. - let interner = DbInterner::new_no_crate(db); - let substs = GenericArgs::new_from_iter(interner, [base_ty.into(), index_ty.into()]); + let substs = GenericArgs::new_from_slice(&[base_ty.into(), index_ty.into()]); Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) } @@ -694,8 +690,7 @@ impl<'db> SourceAnalyzer<'db> { })?; // HACK: subst for `index()` coincides with that for `Index` because `index()` itself // doesn't have any generic parameters, so we skip building another subst for `index()`. - let interner = DbInterner::new_no_crate(db); - let substs = GenericArgs::new_from_iter(interner, [lhs.into(), rhs.into()]); + let substs = GenericArgs::new_from_slice(&[lhs.into(), rhs.into()]); Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) } @@ -710,8 +705,7 @@ impl<'db> SourceAnalyzer<'db> { let op_fn = self.lang_items(db).TryTraitBranch?; // HACK: subst for `branch()` coincides with that for `Try` because `branch()` itself // doesn't have any generic parameters, so we skip building another subst for `branch()`. - let interner = DbInterner::new_no_crate(db); - let substs = GenericArgs::new_from_iter(interner, [ty.into()]); + let substs = GenericArgs::new_from_slice(&[ty.into()]); Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) } @@ -751,7 +745,8 @@ impl<'db> SourceAnalyzer<'db> { let variant = self.infer()?.variant_resolution_for_expr_or_pat(expr_id)?; let variant_data = variant.fields(db); let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? }; - let field_ty = (*db.field_types(variant).get(field.local_id)?).instantiate(interner, subst); + let field_ty = + (*db.field_types(variant).get(field.local_id)?).get().instantiate(interner, subst); Some(( field.into(), local, @@ -772,8 +767,9 @@ impl<'db> SourceAnalyzer<'db> { let variant = self.infer()?.variant_resolution_for_pat(pat_id.as_pat()?)?; let variant_data = variant.fields(db); let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? }; - let (adt, subst) = self.infer()?[pat_id.as_pat()?].as_adt()?; - let field_ty = (*db.field_types(variant).get(field.local_id)?).instantiate(interner, subst); + let (adt, subst) = self.infer()?.pat_ty(pat_id.as_pat()?).as_adt()?; + let field_ty = + (*db.field_types(variant).get(field.local_id)?).get().instantiate(interner, subst); Some(( field.into(), Type::new_with_resolver(db, &self.resolver, field_ty), @@ -835,23 +831,24 @@ impl<'db> SourceAnalyzer<'db> { if let Either::Right(container) = &mut container { *container = structurally_normalize_ty(&infcx, *container, trait_env.param_env); } - let handle_variants = - |variant: VariantId, subst: GenericArgs<'db>, container: &mut _| { - let fields = variant.fields(db); - let field = fields.field(&field_name.as_name())?; - let field_types = db.field_types(variant); - *container = Either::Right(field_types[field].instantiate(interner, subst)); - let generic_def = match variant { - VariantId::EnumVariantId(it) => it.loc(db).parent.into(), - VariantId::StructId(it) => it.into(), - VariantId::UnionId(it) => it.into(), - }; - Some(( - Either::Right(Field { parent: variant.into(), id: field }), - generic_def, - subst, - )) + let handle_variants = |variant: VariantId, + subst: GenericArgs<'db>, + container: &mut _| { + let fields = variant.fields(db); + let field = fields.field(&field_name.as_name())?; + let field_types = db.field_types(variant); + *container = Either::Right(field_types[field].get().instantiate(interner, subst)); + let generic_def = match variant { + VariantId::EnumVariantId(it) => it.loc(db).parent.into(), + VariantId::StructId(it) => it.into(), + VariantId::UnionId(it) => it.into(), }; + Some(( + Either::Right(Field { parent: variant.into(), id: field }), + generic_def, + subst, + )) + }; let temp_ty = Ty::new_error(interner, ErrorGuaranteed); let (field_def, generic_def, subst) = match std::mem::replace(&mut container, Either::Right(temp_ty)) { @@ -1173,7 +1170,7 @@ impl<'db> SourceAnalyzer<'db> { self.infer()?.type_of_expr_or_pat(expr_id)? } else if let Some(pat) = ast::Pat::cast(parent) { let pat_id = self.pat_id(&pat)?; - self.infer()?[pat_id] + self.infer()?.expr_or_pat_ty(pat_id) } else { return None; }; @@ -1245,7 +1242,7 @@ impl<'db> SourceAnalyzer<'db> { let infer = self.infer()?; let expr_id = self.expr_id(literal.clone().into())?; - let substs = infer[expr_id].as_adt()?.1; + let substs = infer.expr_or_pat_ty(expr_id).as_adt()?.1; let (variant, missing_fields, _exhaustive) = match expr_id { ExprOrPatId::ExprId(expr_id) => { @@ -1268,7 +1265,7 @@ impl<'db> SourceAnalyzer<'db> { let infer = self.infer()?; let pat_id = self.pat_id(&pattern.clone().into())?.as_pat()?; - let substs = infer[pat_id].as_adt()?.1; + let substs = infer.pat_ty(pat_id).as_adt()?.1; let (variant, missing_fields, _exhaustive) = record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?; @@ -1290,7 +1287,7 @@ impl<'db> SourceAnalyzer<'db> { .into_iter() .map(|local_id| { let field = FieldId { parent: variant, local_id }; - let ty = field_types[local_id].instantiate(interner, substs); + let ty = field_types[local_id].get().instantiate(interner, substs); (field.into(), Type::new_with_resolver_inner(db, &self.resolver, ty)) }) .collect() diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs index 951a672d4b79..1317684a0877 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs @@ -46,7 +46,7 @@ pub(super) fn hints( if !place.projection.is_empty() { continue; // Ignore complex cases for now } - if mir.locals[place.local].ty.as_adt().is_none() { + if mir.locals[place.local].ty.as_ref().as_adt().is_none() { continue; // Arguably only ADTs have significant drop impls } let Some(&binding_idx) = local_to_binding.get(place.local) else { diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs index 791da00bb695..3741822547e4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/interpret.rs +++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs @@ -60,7 +60,7 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Dura pub(crate) fn render_const_eval_error( db: &RootDatabase, - e: ConstEvalError<'_>, + e: ConstEvalError, display_target: DisplayTarget, ) -> String { let span_formatter = |file_id, text_range: TextRange| { diff --git a/src/tools/rust-analyzer/crates/intern/Cargo.toml b/src/tools/rust-analyzer/crates/intern/Cargo.toml index 81b6703deef5..44621031ab8e 100644 --- a/src/tools/rust-analyzer/crates/intern/Cargo.toml +++ b/src/tools/rust-analyzer/crates/intern/Cargo.toml @@ -18,6 +18,7 @@ dashmap.workspace = true hashbrown.workspace = true rustc-hash.workspace = true triomphe.workspace = true +smallvec.workspace = true [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/intern/src/intern.rs b/src/tools/rust-analyzer/crates/intern/src/intern.rs new file mode 100644 index 000000000000..fdefb936560e --- /dev/null +++ b/src/tools/rust-analyzer/crates/intern/src/intern.rs @@ -0,0 +1,331 @@ +//! Interning of single values. + +use std::{ + fmt::{self, Debug, Display}, + hash::{BuildHasher, BuildHasherDefault, Hash, Hasher}, + ops::Deref, + ptr, + sync::OnceLock, +}; + +use dashmap::{DashMap, SharedValue}; +use hashbrown::raw::RawTable; +use rustc_hash::FxHasher; +use triomphe::{Arc, ArcBorrow}; + +type InternMap = DashMap, (), BuildHasherDefault>; +type Guard = dashmap::RwLockWriteGuard<'static, RawTable<(Arc, SharedValue<()>)>>; + +pub struct Interned { + arc: Arc, +} + +unsafe impl Send for Interned {} +unsafe impl Sync for Interned {} + +impl Interned { + #[inline] + pub fn new(obj: T) -> Self { + let storage = T::storage().get(); + let (mut shard, hash) = Self::select(storage, &obj); + // Atomically, + // - check if `obj` is already in the map + // - if so, clone its `Arc` and return it + // - if not, box it up, insert it, and return a clone + // This needs to be atomic (locking the shard) to avoid races with other thread, which could + // insert the same object between us looking it up and inserting it. + let bucket = match shard.find_or_find_insert_slot( + hash, + |(other, _)| **other == obj, + |(x, _)| Self::hash(storage, x), + ) { + Ok(bucket) => bucket, + // SAFETY: The slot came from `find_or_find_insert_slot()`, and the table wasn't modified since then. + Err(insert_slot) => unsafe { + shard.insert_in_slot(hash, insert_slot, (Arc::new(obj), SharedValue::new(()))) + }, + }; + // SAFETY: We just retrieved/inserted this bucket. + unsafe { Self { arc: bucket.as_ref().0.clone() } } + } + + #[inline] + pub fn new_gc<'a>(obj: T) -> InternedRef<'a, T> { + const { assert!(T::USE_GC) }; + + let storage = T::storage().get(); + let (mut shard, hash) = Self::select(storage, &obj); + // Atomically, + // - check if `obj` is already in the map + // - if so, clone its `Arc` and return it + // - if not, box it up, insert it, and return a clone + // This needs to be atomic (locking the shard) to avoid races with other thread, which could + // insert the same object between us looking it up and inserting it. + let bucket = match shard.find_or_find_insert_slot( + hash, + |(other, _)| **other == obj, + |(x, _)| Self::hash(storage, x), + ) { + Ok(bucket) => bucket, + // SAFETY: The slot came from `find_or_find_insert_slot()`, and the table wasn't modified since then. + Err(insert_slot) => unsafe { + shard.insert_in_slot(hash, insert_slot, (Arc::new(obj), SharedValue::new(()))) + }, + }; + // SAFETY: We just retrieved/inserted this bucket. + unsafe { InternedRef { arc: Arc::borrow_arc(&bucket.as_ref().0) } } + } + + #[inline] + fn select(storage: &'static InternMap, obj: &T) -> (Guard, u64) { + let hash = Self::hash(storage, obj); + let shard_idx = storage.determine_shard(hash as usize); + let shard = &storage.shards()[shard_idx]; + (shard.write(), hash) + } + + #[inline] + fn hash(storage: &'static InternMap, obj: &T) -> u64 { + storage.hasher().hash_one(obj) + } + + /// # Safety + /// + /// The pointer should originate from an `Interned` or an `InternedRef`. + #[inline] + pub unsafe fn from_raw(ptr: *const T) -> Self { + Self { arc: unsafe { Arc::from_raw(ptr) } } + } + + #[inline] + pub fn as_ref(&self) -> InternedRef<'_, T> { + InternedRef { arc: self.arc.borrow_arc() } + } +} + +impl Drop for Interned { + #[inline] + fn drop(&mut self) { + // When the last `Ref` is dropped, remove the object from the global map. + if !T::USE_GC && Arc::count(&self.arc) == 2 { + // Only `self` and the global map point to the object. + + self.drop_slow(); + } + } +} + +impl Interned { + #[cold] + fn drop_slow(&mut self) { + let storage = T::storage().get(); + let (mut shard, hash) = Self::select(storage, &self.arc); + + if Arc::count(&self.arc) != 2 { + // Another thread has interned another copy + return; + } + + shard.remove_entry(hash, |(other, _)| **other == **self); + + // Shrink the backing storage if the shard is less than 50% occupied. + if shard.len() * 2 < shard.capacity() { + let len = shard.len(); + shard.shrink_to(len, |(x, _)| Self::hash(storage, x)); + } + } +} + +/// Compares interned `Ref`s using pointer equality. +impl PartialEq for Interned { + // NOTE: No `?Sized` because `ptr_eq` doesn't work right with trait objects. + + #[inline] + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.arc, &other.arc) + } +} + +impl Eq for Interned {} + +impl Hash for Interned { + #[inline] + fn hash(&self, state: &mut H) { + state.write_usize(self.arc.as_ptr().addr()) + } +} + +impl AsRef for Interned { + #[inline] + fn as_ref(&self) -> &T { + self + } +} + +impl Deref for Interned { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.arc + } +} + +impl Clone for Interned { + #[inline] + fn clone(&self) -> Self { + Self { arc: self.arc.clone() } + } +} + +impl Debug for Interned { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ::fmt(&**self, f) + } +} + +impl Display for Interned { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ::fmt(&**self, f) + } +} + +#[repr(transparent)] +pub struct InternedRef<'a, T> { + arc: ArcBorrow<'a, T>, +} + +impl<'a, T: Internable> InternedRef<'a, T> { + #[inline] + pub fn as_raw(self) -> *const T { + // Not `ptr::from_ref(&*self.arc)`, because we need to keep the provenance. + self.arc.with_arc(|arc| Arc::as_ptr(arc)) + } + + /// # Safety + /// + /// The pointer needs to originate from `Interned` or `InternedRef`. + #[inline] + pub unsafe fn from_raw(ptr: *const T) -> Self { + Self { arc: unsafe { ArcBorrow::from_ptr(ptr) } } + } + + #[inline] + pub fn to_owned(self) -> Interned { + Interned { arc: self.arc.clone_arc() } + } + + #[inline] + pub fn get(self) -> &'a T { + self.arc.get() + } + + /// # Safety + /// + /// You have to make sure the data is not referenced after the refcount reaches zero; beware the interning + /// map also keeps a reference to the value. + #[inline] + pub unsafe fn decrement_refcount(self) { + unsafe { drop(Arc::from_raw(self.as_raw())) } + } +} + +impl Clone for InternedRef<'_, T> { + #[inline] + fn clone(&self) -> Self { + *self + } +} + +impl Copy for InternedRef<'_, T> {} + +impl Hash for InternedRef<'_, T> { + #[inline] + fn hash(&self, state: &mut H) { + let ptr = ptr::from_ref::(&*self.arc); + state.write_usize(ptr.addr()); + } +} + +impl PartialEq for InternedRef<'_, T> { + #[inline] + fn eq(&self, other: &Self) -> bool { + ArcBorrow::ptr_eq(&self.arc, &other.arc) + } +} + +impl Eq for InternedRef<'_, T> {} + +impl Deref for InternedRef<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.arc + } +} + +impl Debug for InternedRef<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (*self.arc).fmt(f) + } +} + +impl Display for InternedRef<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (*self.arc).fmt(f) + } +} + +pub struct InternStorage { + map: OnceLock>, +} + +#[allow( + clippy::new_without_default, + reason = "this a const fn, so it can't be default yet. See " +)] +impl InternStorage { + pub const fn new() -> Self { + Self { map: OnceLock::new() } + } +} + +impl InternStorage { + fn get(&self) -> &InternMap { + self.map.get_or_init(DashMap::default) + } +} + +pub trait Internable: Hash + Eq + 'static { + const USE_GC: bool; + + fn storage() -> &'static InternStorage; +} + +/// Implements `Internable` for a given list of types, making them usable with `Interned`. +#[macro_export] +#[doc(hidden)] +macro_rules! _impl_internable { + ( gc; $($t:ty),+ $(,)? ) => { $( + impl $crate::Internable for $t { + const USE_GC: bool = true; + + fn storage() -> &'static $crate::InternStorage { + static STORAGE: $crate::InternStorage<$t> = $crate::InternStorage::new(); + &STORAGE + } + } + )+ }; + ( $($t:ty),+ $(,)? ) => { $( + impl $crate::Internable for $t { + const USE_GC: bool = false; + + fn storage() -> &'static $crate::InternStorage { + static STORAGE: $crate::InternStorage<$t> = $crate::InternStorage::new(); + &STORAGE + } + } + )+ }; +} +pub use crate::_impl_internable as impl_internable; diff --git a/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs new file mode 100644 index 000000000000..989a21e70cf0 --- /dev/null +++ b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs @@ -0,0 +1,351 @@ +//! Interning of slices, potentially with a header. + +use std::{ + borrow::Borrow, + ffi::c_void, + fmt::{self, Debug}, + hash::{BuildHasher, BuildHasherDefault, Hash, Hasher}, + marker::PhantomData, + mem::ManuallyDrop, + ops::Deref, + ptr::{self, NonNull}, + sync::OnceLock, +}; + +use dashmap::{DashMap, SharedValue}; +use hashbrown::raw::RawTable; +use rustc_hash::FxHasher; +use triomphe::{HeaderSlice, HeaderWithLength, ThinArc}; + +type InternMap = DashMap< + ThinArc<::Header, ::SliceType>, + (), + BuildHasherDefault, +>; +type Guard = dashmap::RwLockWriteGuard< + 'static, + RawTable<( + ThinArc<::Header, ::SliceType>, + SharedValue<()>, + )>, +>; +type Pointee = HeaderSlice< + HeaderWithLength<::Header>, + [::SliceType], +>; + +pub struct InternedSlice { + arc: ThinArc, +} + +impl InternedSlice { + #[inline] + fn new<'a>( + header: T::Header, + slice: impl Borrow<[T::SliceType]> + + IntoIterator, + ) -> InternedSliceRef<'a, T> { + const { assert!(T::USE_GC) }; + let storage = T::storage().get(); + let (mut shard, hash) = Self::select(storage, &header, slice.borrow()); + // Atomically, + // - check if `obj` is already in the map + // - if so, clone its `Arc` and return it + // - if not, box it up, insert it, and return a clone + // This needs to be atomic (locking the shard) to avoid races with other thread, which could + // insert the same object between us looking it up and inserting it. + let bucket = match shard.find_or_find_insert_slot( + hash, + |(other, _)| other.header.header == header && other.slice == *slice.borrow(), + |(x, _)| storage.hasher().hash_one(x), + ) { + Ok(bucket) => bucket, + // SAFETY: The slot came from `find_or_find_insert_slot()`, and the table wasn't modified since then. + Err(insert_slot) => unsafe { + shard.insert_in_slot( + hash, + insert_slot, + ( + ThinArc::from_header_and_iter(header, slice.into_iter()), + SharedValue::new(()), + ), + ) + }, + }; + // SAFETY: We just retrieved/inserted this bucket. + unsafe { + InternedSliceRef { + ptr: NonNull::new_unchecked(ThinArc::as_ptr(&bucket.as_ref().0).cast_mut()), + _marker: PhantomData, + } + } + } + + #[inline] + pub fn from_header_and_slice<'a>( + header: T::Header, + slice: &[T::SliceType], + ) -> InternedSliceRef<'a, T> + where + T::SliceType: Clone, + { + return Self::new(header, Iter(slice)); + + struct Iter<'a, T>(&'a [T]); + + impl<'a, T: Clone> IntoIterator for Iter<'a, T> { + type IntoIter = std::iter::Cloned>; + type Item = T; + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.0.iter().cloned() + } + } + + impl Borrow<[T]> for Iter<'_, T> { + #[inline] + fn borrow(&self) -> &[T] { + self.0 + } + } + } + + #[inline] + fn select( + storage: &'static InternMap, + header: &T::Header, + slice: &[T::SliceType], + ) -> (Guard, u64) { + let hash = Self::hash(storage, header, slice); + let shard_idx = storage.determine_shard(hash as usize); + let shard = &storage.shards()[shard_idx]; + (shard.write(), hash) + } + + #[inline] + fn hash(storage: &'static InternMap, header: &T::Header, slice: &[T::SliceType]) -> u64 { + storage.hasher().hash_one(HeaderSlice { + header: HeaderWithLength { header, length: slice.len() }, + slice, + }) + } + + #[inline(always)] + fn ptr(&self) -> *const c_void { + unsafe { ptr::from_ref(&self.arc).read().into_raw() } + } + + #[inline] + pub fn as_ref(&self) -> InternedSliceRef<'_, T> { + InternedSliceRef { + ptr: unsafe { NonNull::new_unchecked(self.ptr().cast_mut()) }, + _marker: PhantomData, + } + } +} + +impl Drop for InternedSlice { + #[inline] + fn drop(&mut self) { + // When the last `Ref` is dropped, remove the object from the global map. + if !T::USE_GC && ThinArc::strong_count(&self.arc) == 2 { + // Only `self` and the global map point to the object. + + self.drop_slow(); + } + } +} + +impl InternedSlice { + #[cold] + fn drop_slow(&mut self) { + let storage = T::storage().get(); + let (mut shard, hash) = Self::select(storage, &self.arc.header.header, &self.arc.slice); + + if ThinArc::strong_count(&self.arc) != 2 { + // Another thread has interned another copy + return; + } + + shard.remove_entry(hash, |(other, _)| **other == *self.arc); + + // Shrink the backing storage if the shard is less than 50% occupied. + if shard.len() * 2 < shard.capacity() { + let len = shard.len(); + shard.shrink_to(len, |(x, _)| storage.hasher().hash_one(x)); + } + } +} + +/// Compares interned `Ref`s using pointer equality. +impl PartialEq for InternedSlice { + // NOTE: No `?Sized` because `ptr_eq` doesn't work right with trait objects. + + #[inline] + fn eq(&self, other: &Self) -> bool { + self.arc.as_ptr() == other.arc.as_ptr() + } +} + +impl Eq for InternedSlice {} + +impl Hash for InternedSlice { + #[inline] + fn hash(&self, state: &mut H) { + state.write_usize(self.ptr().addr()) + } +} + +impl Deref for InternedSlice { + type Target = Pointee; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.arc + } +} + +impl Clone for InternedSlice { + #[inline] + fn clone(&self) -> Self { + Self { arc: self.arc.clone() } + } +} + +impl Debug for InternedSlice +where + T: SliceInternable, + T::SliceType: Debug, + T::Header: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (*self.arc).fmt(f) + } +} + +#[repr(transparent)] +pub struct InternedSliceRef<'a, T> { + ptr: NonNull, + _marker: PhantomData<&'a T>, +} + +unsafe impl Send for InternedSliceRef<'_, T> {} +unsafe impl Sync for InternedSliceRef<'_, T> {} + +impl<'a, T: SliceInternable> InternedSliceRef<'a, T> { + #[inline(always)] + fn arc(self) -> ManuallyDrop> { + unsafe { ManuallyDrop::new(ThinArc::from_raw(self.ptr.as_ptr())) } + } + + #[inline] + pub fn to_owned(self) -> InternedSlice { + InternedSlice { arc: (*self.arc()).clone() } + } + + #[inline] + pub fn get(self) -> &'a Pointee { + unsafe { &*ptr::from_ref::>(&*self.arc()) } + } + + /// # Safety + /// + /// You have to make sure the data is not referenced after the refcount reaches zero; beware the interning + /// map also keeps a reference to the value. + #[inline] + pub unsafe fn decrement_refcount(self) { + drop(ManuallyDrop::into_inner(self.arc())); + } +} + +impl Clone for InternedSliceRef<'_, T> { + #[inline] + fn clone(&self) -> Self { + *self + } +} + +impl Copy for InternedSliceRef<'_, T> {} + +impl Hash for InternedSliceRef<'_, T> { + #[inline] + fn hash(&self, state: &mut H) { + state.write_usize(self.ptr.as_ptr().addr()); + } +} + +impl PartialEq for InternedSliceRef<'_, T> { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.ptr == other.ptr + } +} + +impl Eq for InternedSliceRef<'_, T> {} + +impl Deref for InternedSliceRef<'_, T> { + type Target = Pointee; + + #[inline] + fn deref(&self) -> &Self::Target { + self.get() + } +} + +impl Debug for InternedSliceRef<'_, T> +where + T: SliceInternable, + T::SliceType: Debug, + T::Header: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (**self).fmt(f) + } +} + +pub struct InternSliceStorage { + map: OnceLock>, +} + +#[allow( + clippy::new_without_default, + reason = "this a const fn, so it can't be default yet. See " +)] +impl InternSliceStorage { + pub const fn new() -> Self { + Self { map: OnceLock::new() } + } +} + +impl InternSliceStorage { + fn get(&self) -> &InternMap { + self.map.get_or_init(DashMap::default) + } +} + +pub trait SliceInternable: Sized + 'static { + const USE_GC: bool; + type Header: Eq + Hash; + type SliceType: Eq + Hash + 'static; + fn storage() -> &'static InternSliceStorage; +} + +/// Implements `SliceInternable` for a given list of types, making them usable with `InternedSlice`. +#[macro_export] +#[doc(hidden)] +macro_rules! _impl_slice_internable { + ( gc; $tag:ident, $h:ty, $t:ty $(,)? ) => { + pub struct $tag; + impl $crate::SliceInternable for $tag { + const USE_GC: bool = true; + type Header = $h; + type SliceType = $t; + fn storage() -> &'static $crate::InternSliceStorage { + static STORAGE: $crate::InternSliceStorage<$tag> = + $crate::InternSliceStorage::new(); + &STORAGE + } + } + }; +} +pub use crate::_impl_slice_internable as impl_slice_internable; diff --git a/src/tools/rust-analyzer/crates/intern/src/lib.rs b/src/tools/rust-analyzer/crates/intern/src/lib.rs index 398d224c07ad..c5b42a860ac4 100644 --- a/src/tools/rust-analyzer/crates/intern/src/lib.rs +++ b/src/tools/rust-analyzer/crates/intern/src/lib.rs @@ -2,219 +2,12 @@ //! //! Eventually this should probably be replaced with salsa-based interning. -use std::{ - borrow::Borrow, - fmt::{self, Debug, Display}, - hash::{BuildHasher, BuildHasherDefault, Hash, Hasher}, - ops::Deref, - sync::OnceLock, -}; - -use dashmap::{DashMap, SharedValue}; -use hashbrown::raw::RawTable; -use rustc_hash::FxHasher; -use triomphe::Arc; - -type InternMap = DashMap, (), BuildHasherDefault>; -type Guard = dashmap::RwLockWriteGuard<'static, RawTable<(Arc, SharedValue<()>)>>; - +mod intern; +mod intern_slice; mod symbol; + +pub use self::intern::{InternStorage, Internable, Interned, InternedRef, impl_internable}; +pub use self::intern_slice::{ + InternSliceStorage, InternedSlice, InternedSliceRef, SliceInternable, impl_slice_internable, +}; pub use self::symbol::{Symbol, symbols as sym}; - -pub struct Interned { - arc: Arc, -} - -impl Interned { - #[inline] - pub fn new(obj: T) -> Self { - Self::new_generic(obj) - } -} - -impl Interned { - #[inline] - pub fn new_str(s: &str) -> Self { - Self::new_generic(s) - } -} - -impl Interned { - #[inline] - pub fn new_generic(obj: U) -> Self - where - U: Borrow, - Arc: From, - { - let storage = T::storage().get(); - let (mut shard, hash) = Self::select(storage, obj.borrow()); - // Atomically, - // - check if `obj` is already in the map - // - if so, clone its `Arc` and return it - // - if not, box it up, insert it, and return a clone - // This needs to be atomic (locking the shard) to avoid races with other thread, which could - // insert the same object between us looking it up and inserting it. - let bucket = match shard.find_or_find_insert_slot( - hash, - |(other, _)| **other == *obj.borrow(), - |(x, _)| Self::hash(storage, x), - ) { - Ok(bucket) => bucket, - // SAFETY: The slot came from `find_or_find_insert_slot()`, and the table wasn't modified since then. - Err(insert_slot) => unsafe { - shard.insert_in_slot(hash, insert_slot, (Arc::from(obj), SharedValue::new(()))) - }, - }; - // SAFETY: We just retrieved/inserted this bucket. - unsafe { Self { arc: bucket.as_ref().0.clone() } } - } - - #[inline] - fn select(storage: &'static InternMap, obj: &T) -> (Guard, u64) { - let hash = Self::hash(storage, obj); - let shard_idx = storage.determine_shard(hash as usize); - let shard = &storage.shards()[shard_idx]; - (shard.write(), hash) - } - - #[inline] - fn hash(storage: &'static InternMap, obj: &T) -> u64 { - storage.hasher().hash_one(obj) - } -} - -impl Drop for Interned { - #[inline] - fn drop(&mut self) { - // When the last `Ref` is dropped, remove the object from the global map. - if Arc::count(&self.arc) == 2 { - // Only `self` and the global map point to the object. - - self.drop_slow(); - } - } -} - -impl Interned { - #[cold] - fn drop_slow(&mut self) { - let storage = T::storage().get(); - let (mut shard, hash) = Self::select(storage, &self.arc); - - if Arc::count(&self.arc) != 2 { - // Another thread has interned another copy - return; - } - - shard.remove_entry(hash, |(other, _)| **other == *self.arc); - - // Shrink the backing storage if the shard is less than 50% occupied. - if shard.len() * 2 < shard.capacity() { - let len = shard.len(); - shard.shrink_to(len, |(x, _)| Self::hash(storage, x)); - } - } -} - -/// Compares interned `Ref`s using pointer equality. -impl PartialEq for Interned { - // NOTE: No `?Sized` because `ptr_eq` doesn't work right with trait objects. - - #[inline] - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.arc, &other.arc) - } -} - -impl Eq for Interned {} - -impl PartialEq for Interned { - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.arc, &other.arc) - } -} - -impl Eq for Interned {} - -impl Hash for Interned { - fn hash(&self, state: &mut H) { - // NOTE: Cast disposes vtable pointer / slice/str length. - state.write_usize(Arc::as_ptr(&self.arc) as *const () as usize) - } -} - -impl AsRef for Interned { - #[inline] - fn as_ref(&self) -> &T { - &self.arc - } -} - -impl Deref for Interned { - type Target = T; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.arc - } -} - -impl Clone for Interned { - fn clone(&self) -> Self { - Self { arc: self.arc.clone() } - } -} - -impl Debug for Interned { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (*self.arc).fmt(f) - } -} - -impl Display for Interned { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (*self.arc).fmt(f) - } -} - -pub struct InternStorage { - map: OnceLock>, -} - -#[allow( - clippy::new_without_default, - reason = "this a const fn, so it can't be default yet. See " -)] -impl InternStorage { - pub const fn new() -> Self { - Self { map: OnceLock::new() } - } -} - -impl InternStorage { - fn get(&self) -> &InternMap { - self.map.get_or_init(DashMap::default) - } -} - -pub trait Internable: Hash + Eq + 'static { - fn storage() -> &'static InternStorage; -} - -/// Implements `Internable` for a given list of types, making them usable with `Interned`. -#[macro_export] -#[doc(hidden)] -macro_rules! _impl_internable { - ( $($t:path),+ $(,)? ) => { $( - impl $crate::Internable for $t { - fn storage() -> &'static $crate::InternStorage { - static STORAGE: $crate::InternStorage<$t> = $crate::InternStorage::new(); - &STORAGE - } - } - )+ }; -} - -pub use crate::_impl_internable as impl_internable; - -impl_internable!(str,); diff --git a/src/tools/rust-analyzer/crates/macros/src/lib.rs b/src/tools/rust-analyzer/crates/macros/src/lib.rs index 3f90ecc8f902..de8c3f2e55f1 100644 --- a/src/tools/rust-analyzer/crates/macros/src/lib.rs +++ b/src/tools/rust-analyzer/crates/macros/src/lib.rs @@ -25,6 +25,9 @@ decl_derive!( /// visited (and its type is not required to implement `TypeVisitable`). type_visitable_derive ); +decl_derive!( + [GenericTypeVisitable] => generic_type_visitable_derive +); fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { if let syn::Data::Union(_) = s.ast().data { @@ -163,6 +166,33 @@ fn has_ignore_attr(attrs: &[syn::Attribute], name: &'static str, meta: &'static ignored } +fn generic_type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + s.add_bounds(synstructure::AddBounds::Fields); + s.bind_with(|_| synstructure::BindStyle::Move); + s.add_impl_generic(parse_quote!(__V: hir_ty::next_solver::interner::WorldExposer)); + let body_visit = s.each(|bind| { + quote! { + ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(#bind, __visitor); + } + }); + + s.bound_impl( + quote!(::rustc_type_ir::GenericTypeVisitable<__V>), + quote! { + fn generic_visit_with( + &self, + __visitor: &mut __V + ) { + match self { #body_visit } + } + }, + ) +} + decl_derive!( [UpmapFromRaFixture] => upmap_from_ra_fixture ); diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs index fe932ac133a0..83ce8902d0c9 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs @@ -48,8 +48,7 @@ impl ToTokens for TrackedQuery { quote!(#(#options),*) }) .into_iter() - .chain(self.lru.map(|lru| quote!(lru = #lru))) - .chain(Some(quote!(unsafe(non_update_types)))); + .chain(self.lru.map(|lru| quote!(lru = #lru))); let annotation = quote!(#[salsa_macros::tracked( #(#options),* )]); let pat_and_tys = &self.pat_and_tys; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 1a6cd784cf2f..f863a7ee8d04 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -390,11 +390,12 @@ impl flags::AnalysisStats { all += 1; let Err(e) = db.layout_of_adt( hir_def::AdtId::from(a), - GenericArgs::new_from_iter(interner, []), + GenericArgs::empty(interner).store(), hir_ty::ParamEnvAndCrate { param_env: db.trait_environment(a.into()), krate: a.krate(db).into(), - }, + } + .store(), ) else { continue; }; @@ -830,7 +831,7 @@ impl flags::AnalysisStats { let (previous_exprs, previous_unknown, previous_partially_unknown) = (num_exprs, num_exprs_unknown, num_exprs_partially_unknown); for (expr_id, _) in body.exprs() { - let ty = &inference_result[expr_id]; + let ty = inference_result.expr_ty(expr_id); num_exprs += 1; let unknown_or_partial = if ty.is_ty_error() { num_exprs_unknown += 1; @@ -897,15 +898,15 @@ impl flags::AnalysisStats { start.col, end.line + 1, end.col, - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) )); } else { bar.println(format!( "{}: Expected {}, got {}", name.display(db, Edition::LATEST), - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) )); } } @@ -913,8 +914,8 @@ impl flags::AnalysisStats { println!( r#"{},mismatch,"{}","{}""#, location_csv_expr(db, vfs, &sm(), expr_id), - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) ); } } @@ -934,7 +935,7 @@ impl flags::AnalysisStats { let (previous_pats, previous_unknown, previous_partially_unknown) = (num_pats, num_pats_unknown, num_pats_partially_unknown); for (pat_id, _) in body.pats() { - let ty = &inference_result[pat_id]; + let ty = inference_result.pat_ty(pat_id); num_pats += 1; let unknown_or_partial = if ty.is_ty_error() { num_pats_unknown += 1; @@ -999,15 +1000,15 @@ impl flags::AnalysisStats { start.col, end.line + 1, end.col, - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) )); } else { bar.println(format!( "{}: Expected {}, got {}", name.display(db, Edition::LATEST), - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) )); } } @@ -1015,8 +1016,8 @@ impl flags::AnalysisStats { println!( r#"{},mismatch,"{}","{}""#, location_csv_pat(db, vfs, &sm(), pat_id), - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) ); } } From b9ed61fea1d176edb5f594c7947cd11020f0e261 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Wed, 10 Dec 2025 08:44:05 +0200 Subject: [PATCH 0996/3801] GC support for solver types A GC is triggered every X revisions, and is synchronous, unfortunately. --- src/tools/rust-analyzer/Cargo.lock | 1 + .../crates/hir-ty/src/next_solver/consts.rs | 24 +- .../crates/hir-ty/src/next_solver/interner.rs | 132 ++++++- .../crates/hir-ty/src/next_solver/opaques.rs | 5 +- .../hir-ty/src/next_solver/predicate.rs | 31 +- .../crates/hir-ty/src/next_solver/region.rs | 8 +- .../crates/hir-ty/src/next_solver/ty.rs | 8 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 2 +- .../rust-analyzer/crates/intern/Cargo.toml | 1 + .../rust-analyzer/crates/intern/src/gc.rs | 325 ++++++++++++++++++ .../rust-analyzer/crates/intern/src/intern.rs | 11 +- .../crates/intern/src/intern_slice.rs | 17 +- .../rust-analyzer/crates/intern/src/lib.rs | 2 + .../rust-analyzer/src/cli/analysis_stats.rs | 1 + .../crates/rust-analyzer/src/config.rs | 13 +- .../crates/rust-analyzer/src/global_state.rs | 13 + .../docs/book/src/configuration_generated.md | 11 + .../rust-analyzer/editors/code/package.json | 11 + 18 files changed, 566 insertions(+), 50 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/intern/src/gc.rs diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 081c7d66f1d8..7ada91d2b65b 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1214,6 +1214,7 @@ version = "0.0.0" dependencies = [ "dashmap", "hashbrown 0.14.5", + "rayon", "rustc-hash 2.1.1", "smallvec", "triomphe", diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs index 8417e145a46d..c2fc4d18bbae 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs @@ -29,9 +29,9 @@ pub struct Const<'db> { pub(super) interned: InternedRef<'db, ConstInterned>, } -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)] #[repr(align(4))] // Required for `GenericArg` bit-tagging. -pub(super) struct ConstInterned(WithCachedTypeInfo>); +pub(super) struct ConstInterned(pub(super) WithCachedTypeInfo>); impl_internable!(gc; ConstInterned); impl_stored_interned!(ConstInterned, Const, StoredConst); @@ -219,15 +219,14 @@ pub struct Valtree<'db> { impl<'db, V: super::WorldExposer> GenericTypeVisitable for Valtree<'db> { fn generic_visit_with(&self, visitor: &mut V) { - visitor.on_interned(self.interned); - self.inner().generic_visit_with(visitor); + if visitor.on_interned(self.interned).is_continue() { + self.inner().generic_visit_with(visitor); + } } } -#[derive(Debug, PartialEq, Eq, Hash)] -struct ValtreeInterned { - bytes: ConstBytes<'static>, -} +#[derive(Debug, PartialEq, Eq, Hash, GenericTypeVisitable)] +pub(super) struct ValtreeInterned(ConstBytes<'static>); impl_internable!(gc; ValtreeInterned); @@ -240,12 +239,12 @@ impl<'db> Valtree<'db> { #[inline] pub fn new(bytes: ConstBytes<'db>) -> Self { let bytes = unsafe { std::mem::transmute::, ConstBytes<'static>>(bytes) }; - Self { interned: Interned::new_gc(ValtreeInterned { bytes }) } + Self { interned: Interned::new_gc(ValtreeInterned(bytes)) } } #[inline] pub fn inner(&self) -> &ConstBytes<'db> { - let inner = &self.interned.bytes; + let inner = &self.interned.0; unsafe { std::mem::transmute::<&ConstBytes<'static>, &ConstBytes<'db>>(inner) } } } @@ -277,8 +276,9 @@ impl<'db> IntoKind for Const<'db> { impl<'db, V: super::WorldExposer> GenericTypeVisitable for Const<'db> { fn generic_visit_with(&self, visitor: &mut V) { - visitor.on_interned(self.interned); - self.kind().generic_visit_with(visitor); + if visitor.on_interned(self.interned).is_continue() { + self.kind().generic_visit_with(visitor); + } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 1a946cb90817..f2dacd16dbf9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -1,8 +1,9 @@ //! Things related to the Interner in the next-trait-solver. -use std::fmt; +use std::{fmt, ops::ControlFlow}; use intern::{Interned, InternedRef, InternedSliceRef, impl_internable}; +use macros::GenericTypeVisitable; use rustc_ast_ir::{FloatTy, IntTy, UintTy}; pub use tls_cache::clear_tls_solver_cache; pub use tls_db::{attach_db, attach_db_allow_change, with_attached_db}; @@ -21,8 +22,8 @@ use rustc_hash::FxHashSet; use rustc_index::bit_set::DenseBitSet; use rustc_type_ir::{ AliasTermKind, AliasTyKind, BoundVar, CollectAndApply, CoroutineWitnessTypes, DebruijnIndex, - EarlyBinder, FlagComputation, Flags, GenericArgKind, ImplPolarity, InferTy, Interner, TraitRef, - TypeFlags, TypeVisitableExt, UniverseIndex, Upcast, Variance, + EarlyBinder, FlagComputation, Flags, GenericArgKind, GenericTypeVisitable, ImplPolarity, + InferTy, Interner, TraitRef, TypeFlags, TypeVisitableExt, UniverseIndex, Upcast, Variance, elaborate::elaborate, error::TypeError, fast_reject, @@ -169,8 +170,9 @@ macro_rules! interned_slice { { #[inline] fn generic_visit_with(&self, visitor: &mut V) { - visitor.on_interned_slice(self.interned); - self.as_slice().iter().for_each(|it| it.generic_visit_with(visitor)); + if visitor.on_interned_slice(self.interned).is_continue() { + self.as_slice().iter().for_each(|it| it.generic_visit_with(visitor)); + } } } }; @@ -293,8 +295,14 @@ macro_rules! impl_stored_interned { pub(crate) use impl_stored_interned; pub trait WorldExposer { - fn on_interned(&mut self, interned: InternedRef<'_, T>); - fn on_interned_slice(&mut self, interned: InternedSliceRef<'_, T>); + fn on_interned( + &mut self, + interned: InternedRef<'_, T>, + ) -> ControlFlow<()>; + fn on_interned_slice( + &mut self, + interned: InternedSliceRef<'_, T>, + ) -> ControlFlow<()>; } #[derive(Debug, Copy, Clone)] @@ -803,7 +811,7 @@ pub struct Pattern<'db> { interned: InternedRef<'db, PatternInterned>, } -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)] struct PatternInterned(PatternKind<'static>); impl_internable!(gc; PatternInterned); @@ -884,8 +892,9 @@ impl<'db> rustc_type_ir::TypeVisitable> for Pattern<'db> { impl<'db, V: WorldExposer> rustc_type_ir::GenericTypeVisitable for Pattern<'db> { fn generic_visit_with(&self, visitor: &mut V) { - visitor.on_interned(self.interned); - self.kind().generic_visit_with(visitor); + if visitor.on_interned(self.interned).is_continue() { + self.kind().generic_visit_with(visitor); + } } } @@ -2559,3 +2568,106 @@ mod tls_cache { GLOBAL_CACHE.with_borrow_mut(|handle| *handle = None); } } + +impl WorldExposer for intern::GarbageCollector { + fn on_interned( + &mut self, + interned: InternedRef<'_, T>, + ) -> ControlFlow<()> { + self.mark_interned_alive(interned) + } + + fn on_interned_slice( + &mut self, + interned: InternedSliceRef<'_, T>, + ) -> ControlFlow<()> { + self.mark_interned_slice_alive(interned) + } +} + +/// # Safety +/// +/// This cannot be called if there are some not-yet-recorded type values. Generally, if you have a mutable +/// reference to the database, and there are no other database - then you can call this safely, but you +/// also need to make sure to maintain the mutable reference while this is running. +pub unsafe fn collect_ty_garbage() { + let mut gc = intern::GarbageCollector::default(); + + gc.add_storage::(); + gc.add_storage::(); + gc.add_storage::(); + gc.add_storage::(); + gc.add_storage::(); + gc.add_storage::(); + gc.add_storage::(); + + gc.add_slice_storage::(); + gc.add_slice_storage::(); + gc.add_slice_storage::(); + gc.add_slice_storage::(); + gc.add_slice_storage::(); + gc.add_slice_storage::(); + gc.add_slice_storage::(); + gc.add_slice_storage::(); + gc.add_slice_storage::(); + gc.add_slice_storage::(); + gc.add_slice_storage::(); + + unsafe { gc.collect() }; +} + +macro_rules! impl_gc_visit { + ( $($ty:ty),* $(,)? ) => { + $( + impl ::intern::GcInternedVisit for $ty { + #[inline] + fn visit_with(&self, gc: &mut ::intern::GarbageCollector) { + self.generic_visit_with(gc); + } + } + )* + }; +} + +impl_gc_visit!( + super::consts::ConstInterned, + super::consts::ValtreeInterned, + PatternInterned, + super::opaques::ExternalConstraintsInterned, + super::predicate::PredicateInterned, + super::region::RegionInterned, + super::ty::TyInterned, + super::predicate::ClausesCachedTypeInfo, +); + +macro_rules! impl_gc_visit_slice { + ( $($ty:ty),* $(,)? ) => { + $( + impl ::intern::GcInternedSliceVisit for $ty { + #[inline] + fn visit_header(header: &::Header, gc: &mut ::intern::GarbageCollector) { + header.generic_visit_with(gc); + } + + #[inline] + fn visit_slice(header: &[::SliceType], gc: &mut ::intern::GarbageCollector) { + header.generic_visit_with(gc); + } + } + )* + }; +} + +impl_gc_visit_slice!( + super::predicate::ClausesStorage, + super::generic_arg::GenericArgsStorage, + BoundVarKindsStorage, + VariancesOfStorage, + CanonicalVarsStorage, + PatListStorage, + super::opaques::PredefinedOpaquesStorage, + super::opaques::SolverDefIdsStorage, + super::predicate::BoundExistentialPredicatesStorage, + super::region::RegionAssumptionsStorage, + super::ty::TysStorage, +); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs index 7e1d6b7328cd..230469c21ab8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs @@ -1,6 +1,7 @@ //! Things related to opaques in the next-trait-solver. use intern::{Interned, InternedRef, impl_internable}; +use macros::GenericTypeVisitable; use rustc_ast_ir::try_visit; use rustc_type_ir::inherent::SliceLike; @@ -30,8 +31,8 @@ pub struct ExternalConstraints<'db> { interned: InternedRef<'db, ExternalConstraintsInterned>, } -#[derive(PartialEq, Eq, Hash)] -struct ExternalConstraintsInterned(ExternalConstraintsData<'static>); +#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)] +pub(super) struct ExternalConstraintsInterned(ExternalConstraintsData<'static>); impl_internable!(gc; ExternalConstraintsInterned); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs index 95b48c73c12f..6d7539575fbc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs @@ -186,8 +186,8 @@ pub struct Predicate<'db> { interned: InternedRef<'db, PredicateInterned>, } -#[derive(PartialEq, Eq, Hash)] -struct PredicateInterned(WithCachedTypeInfo>>); +#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)] +pub(super) struct PredicateInterned(WithCachedTypeInfo>>); impl_internable!(gc; PredicateInterned); @@ -252,7 +252,10 @@ impl<'db> std::fmt::Debug for Predicate<'db> { } } -impl_slice_internable!(gc; ClausesStorage, WithCachedTypeInfo<()>, Clause<'static>); +#[derive(Clone, Copy, PartialEq, Eq, Hash, GenericTypeVisitable)] +pub struct ClausesCachedTypeInfo(WithCachedTypeInfo<()>); + +impl_slice_internable!(gc; ClausesStorage, ClausesCachedTypeInfo, Clause<'static>); impl_stored_interned_slice!(ClausesStorage, Clauses, StoredClauses); #[derive(Clone, Copy, PartialEq, Eq, Hash)] @@ -277,11 +280,11 @@ impl<'db> Clauses<'db> { pub fn new_from_slice(slice: &[Clause<'db>]) -> Self { let slice = unsafe { ::std::mem::transmute::<&[Clause<'db>], &[Clause<'static>]>(slice) }; let flags = FlagComputation::>::for_clauses(slice); - let flags = WithCachedTypeInfo { + let flags = ClausesCachedTypeInfo(WithCachedTypeInfo { internee: (), flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, - }; + }); Self { interned: InternedSlice::from_header_and_slice(flags, slice) } } @@ -400,20 +403,21 @@ impl<'db> rustc_type_ir::TypeVisitable> for Clauses<'db> { impl<'db, V: super::WorldExposer> rustc_type_ir::GenericTypeVisitable for Clauses<'db> { fn generic_visit_with(&self, visitor: &mut V) { - visitor.on_interned_slice(self.interned); - self.as_slice().iter().for_each(|it| it.generic_visit_with(visitor)); + if visitor.on_interned_slice(self.interned).is_continue() { + self.as_slice().iter().for_each(|it| it.generic_visit_with(visitor)); + } } } impl<'db> rustc_type_ir::Flags for Clauses<'db> { #[inline] fn flags(&self) -> rustc_type_ir::TypeFlags { - self.interned.header.header.flags + self.interned.header.header.0.flags } #[inline] fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex { - self.interned.header.header.outer_exclusive_binder + self.interned.header.header.0.outer_exclusive_binder } } @@ -430,7 +434,9 @@ impl<'db> rustc_type_ir::TypeSuperVisitable> for Clauses<'db> { pub struct Clause<'db>(pub(crate) Predicate<'db>); // We could cram the reveal into the clauses like rustc does, probably -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable)] +#[derive( + Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable, GenericTypeVisitable, +)] pub struct ParamEnv<'db> { pub(crate) clauses: Clauses<'db>, } @@ -474,8 +480,9 @@ impl<'db> TypeVisitable> for Predicate<'db> { impl<'db, V: super::WorldExposer> GenericTypeVisitable for Predicate<'db> { fn generic_visit_with(&self, visitor: &mut V) { - visitor.on_interned(self.interned); - self.kind().generic_visit_with(visitor); + if visitor.on_interned(self.interned).is_continue() { + self.kind().generic_visit_with(visitor); + } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs index dee7953ae36c..e34e87601fd7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs @@ -2,6 +2,7 @@ use hir_def::LifetimeParamId; use intern::{Interned, InternedRef, Symbol, impl_internable}; +use macros::GenericTypeVisitable; use rustc_type_ir::{ BoundVar, BoundVarIndexKind, DebruijnIndex, Flags, GenericTypeVisitable, INNERMOST, RegionVid, TypeFlags, TypeFoldable, TypeVisitable, @@ -25,7 +26,7 @@ pub struct Region<'db> { pub(super) interned: InternedRef<'db, RegionInterned>, } -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)] #[repr(align(4))] // Required for `GenericArg` bit-tagging. pub(super) struct RegionInterned(RegionKind<'static>); @@ -388,8 +389,9 @@ impl<'db> PlaceholderLike> for PlaceholderRegion { impl<'db, V: super::WorldExposer> GenericTypeVisitable for Region<'db> { fn generic_visit_with(&self, visitor: &mut V) { - visitor.on_interned(self.interned); - self.kind().generic_visit_with(visitor); + if visitor.on_interned(self.interned).is_continue() { + self.kind().generic_visit_with(visitor); + } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs index 305da50b6d9f..85534e42a823 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs @@ -8,6 +8,7 @@ use hir_def::{ }; use hir_def::{TraitId, type_ref::Rawness}; use intern::{Interned, InternedRef, impl_internable}; +use macros::GenericTypeVisitable; use rustc_abi::{Float, Integer, Size}; use rustc_ast_ir::{Mutability, try_visit, visit::VisitorResult}; use rustc_type_ir::{ @@ -51,7 +52,7 @@ pub struct Ty<'db> { pub(super) interned: InternedRef<'db, TyInterned>, } -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)] #[repr(align(4))] // Required for `GenericArg` bit-tagging. pub(super) struct TyInterned(WithCachedTypeInfo>); @@ -750,8 +751,9 @@ impl<'db> IntoKind for Ty<'db> { impl<'db, V: super::WorldExposer> GenericTypeVisitable for Ty<'db> { fn generic_visit_with(&self, visitor: &mut V) { - visitor.on_interned(self.interned); - self.kind().generic_visit_with(visitor); + if visitor.on_interned(self.interned).is_continue() { + self.kind().generic_visit_with(visitor); + } } } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 3532220b72ae..933dd6af1d52 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -175,7 +175,7 @@ pub use { layout::LayoutError, mir::{MirEvalError, MirLowerError}, next_solver::abi::Safety, - next_solver::clear_tls_solver_cache, + next_solver::{clear_tls_solver_cache, collect_ty_garbage}, }, // FIXME: These are needed for import assets, properly encapsulate them. hir_ty::{method_resolution::TraitImpls, next_solver::SimplifiedType}, diff --git a/src/tools/rust-analyzer/crates/intern/Cargo.toml b/src/tools/rust-analyzer/crates/intern/Cargo.toml index 44621031ab8e..6414f091783c 100644 --- a/src/tools/rust-analyzer/crates/intern/Cargo.toml +++ b/src/tools/rust-analyzer/crates/intern/Cargo.toml @@ -19,6 +19,7 @@ hashbrown.workspace = true rustc-hash.workspace = true triomphe.workspace = true smallvec.workspace = true +rayon.workspace = true [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/intern/src/gc.rs b/src/tools/rust-analyzer/crates/intern/src/gc.rs new file mode 100644 index 000000000000..e559d1dc5710 --- /dev/null +++ b/src/tools/rust-analyzer/crates/intern/src/gc.rs @@ -0,0 +1,325 @@ +//! Garbage collection of interned values. + +use std::{marker::PhantomData, ops::ControlFlow}; + +use hashbrown::raw::RawTable; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; +use rustc_hash::{FxBuildHasher, FxHashSet}; +use triomphe::{Arc, ThinArc}; + +use crate::{Internable, InternedRef, InternedSliceRef, SliceInternable}; + +trait Storage { + fn len(&self) -> usize; + + fn mark(&self, gc: &mut GarbageCollector); + + fn sweep(&self, gc: &GarbageCollector); +} + +struct InternedStorage(PhantomData T>); + +impl Storage for InternedStorage { + fn len(&self) -> usize { + T::storage().get().len() + } + + fn mark(&self, gc: &mut GarbageCollector) { + let storage = T::storage().get(); + for item in storage { + let item = item.key(); + let addr = Arc::as_ptr(item).addr(); + if Arc::strong_count(item) > 1 { + // The item is referenced from the outside. + gc.alive.insert(addr); + item.visit_with(gc); + } + } + } + + fn sweep(&self, gc: &GarbageCollector) { + let storage = T::storage().get(); + if cfg!(miri) { + storage.shards().iter().for_each(|shard| { + gc.retain_only_alive(&mut *shard.write(), |item| item.0.as_ptr().addr()) + }); + } else { + storage.shards().par_iter().for_each(|shard| { + gc.retain_only_alive(&mut *shard.write(), |item| item.0.as_ptr().addr()) + }); + } + } +} + +struct InternedSliceStorage(PhantomData T>); + +impl Storage for InternedSliceStorage { + fn len(&self) -> usize { + T::storage().get().len() + } + + fn mark(&self, gc: &mut GarbageCollector) { + let storage = T::storage().get(); + for item in storage { + let item = item.key(); + let addr = ThinArc::as_ptr(item).addr(); + if ThinArc::strong_count(item) > 1 { + // The item is referenced from the outside. + gc.alive.insert(addr); + T::visit_header(&item.header.header, gc); + T::visit_slice(&item.slice, gc); + } + } + } + + fn sweep(&self, gc: &GarbageCollector) { + let storage = T::storage().get(); + if cfg!(miri) { + storage.shards().iter().for_each(|shard| { + gc.retain_only_alive(&mut *shard.write(), |item| item.0.as_ptr().addr()) + }); + } else { + storage.shards().par_iter().for_each(|shard| { + gc.retain_only_alive(&mut *shard.write(), |item| item.0.as_ptr().addr()) + }); + } + } +} + +pub trait GcInternedVisit { + fn visit_with(&self, gc: &mut GarbageCollector); +} + +pub trait GcInternedSliceVisit: SliceInternable { + fn visit_header(header: &Self::Header, gc: &mut GarbageCollector); + fn visit_slice(header: &[Self::SliceType], gc: &mut GarbageCollector); +} + +#[derive(Default)] +pub struct GarbageCollector { + alive: FxHashSet, + storages: Vec>, +} + +impl GarbageCollector { + pub fn add_storage(&mut self) { + const { assert!(T::USE_GC) }; + + self.storages.push(Box::new(InternedStorage::(PhantomData))); + } + + pub fn add_slice_storage(&mut self) { + const { assert!(T::USE_GC) }; + + self.storages.push(Box::new(InternedSliceStorage::(PhantomData))); + } + + /// # Safety + /// + /// This cannot be called if there are some not-yet-recorded type values. + pub unsafe fn collect(mut self) { + let total_nodes = self.storages.iter().map(|storage| storage.len()).sum(); + self.alive = FxHashSet::with_capacity_and_hasher(total_nodes, FxBuildHasher); + + let storages = std::mem::take(&mut self.storages); + + for storage in &storages { + storage.mark(&mut self); + } + + if cfg!(miri) { + storages.iter().for_each(|storage| storage.sweep(&self)); + } else { + storages.par_iter().for_each(|storage| storage.sweep(&self)); + } + } + + pub fn mark_interned_alive( + &mut self, + interned: InternedRef<'_, T>, + ) -> ControlFlow<()> { + if interned.strong_count() > 1 { + // It will be visited anyway, so short-circuit + return ControlFlow::Break(()); + } + let addr = interned.as_raw().addr(); + if !self.alive.insert(addr) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } + } + + pub fn mark_interned_slice_alive( + &mut self, + interned: InternedSliceRef<'_, T>, + ) -> ControlFlow<()> { + if interned.strong_count() > 1 { + // It will be visited anyway, so short-circuit + return ControlFlow::Break(()); + } + let addr = interned.as_raw().addr(); + if !self.alive.insert(addr) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } + } + + #[inline] + fn retain_only_alive(&self, map: &mut RawTable, mut get_addr: impl FnMut(&T) -> usize) { + unsafe { + // Here we only use `iter` as a temporary, preventing use-after-free + for bucket in map.iter() { + let item = bucket.as_mut(); + let addr = get_addr(item); + if !self.alive.contains(&addr) { + map.erase(bucket); + } + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::{ + GarbageCollector, GcInternedSliceVisit, GcInternedVisit, Interned, InternedSliceRef, + }; + + crate::impl_internable!(String); + + #[test] + fn simple_interned() { + let a = Interned::new("abc".to_owned()); + let b = Interned::new("abc".to_owned()); + assert_eq!(a, b); + assert_eq!(a.as_ref(), b.as_ref()); + assert_eq!(a.as_ref(), a.as_ref()); + assert_eq!(a, a.clone()); + assert_eq!(a, a.clone().clone()); + assert_eq!(b.clone(), a.clone().clone()); + assert_eq!(*a, "abc"); + assert_eq!(*b, "abc"); + assert_eq!(b.as_ref().to_owned(), a); + let c = Interned::new("def".to_owned()); + assert_ne!(a, c); + assert_ne!(b, c); + assert_ne!(b.as_ref(), c.as_ref()); + assert_eq!(*c.as_ref(), "def"); + drop(c); + assert_eq!(*a, "abc"); + assert_eq!(*b, "abc"); + drop(a); + assert_eq!(*b, "abc"); + drop(b); + } + + #[test] + fn simple_gc() { + #[derive(Debug, PartialEq, Eq, Hash)] + struct GcString(String); + + crate::impl_internable!(gc; GcString); + + impl GcInternedVisit for GcString { + fn visit_with(&self, _gc: &mut GarbageCollector) {} + } + + crate::impl_slice_internable!(gc; StringSlice, String, String); + type InternedSlice = crate::InternedSlice; + + impl GcInternedSliceVisit for StringSlice { + fn visit_header(_header: &Self::Header, _gc: &mut GarbageCollector) {} + + fn visit_slice(_header: &[Self::SliceType], _gc: &mut GarbageCollector) {} + } + + let (a, d) = { + let a = Interned::new_gc(GcString("abc".to_owned())).to_owned(); + let b = Interned::new_gc(GcString("abc".to_owned())).to_owned(); + assert_eq!(a, b); + assert_eq!(a.as_ref(), b.as_ref()); + assert_eq!(a.as_ref(), a.as_ref()); + assert_eq!(a, a.clone()); + assert_eq!(a, a.clone().clone()); + assert_eq!(b.clone(), a.clone().clone()); + assert_eq!(a.0, "abc"); + assert_eq!(b.0, "abc"); + assert_eq!(b.as_ref().to_owned(), a); + let c = Interned::new_gc(GcString("def".to_owned())).to_owned(); + assert_ne!(a, c); + assert_ne!(b, c); + assert_ne!(b.as_ref(), c.as_ref()); + assert_eq!(c.as_ref().0, "def"); + + let d = InternedSlice::from_header_and_slice( + "abc".to_owned(), + &["def".to_owned(), "123".to_owned()], + ); + let e = InternedSlice::from_header_and_slice( + "abc".to_owned(), + &["def".to_owned(), "123".to_owned()], + ); + assert_eq!(d, e); + assert_eq!(d.to_owned(), e.to_owned()); + assert_eq!(d.header.length, 2); + assert_eq!(d.header.header, "abc"); + assert_eq!(d.slice, ["def", "123"]); + (a, d.to_owned()) + }; + + let mut gc = GarbageCollector::default(); + gc.add_slice_storage::(); + gc.add_storage::(); + unsafe { gc.collect() }; + + assert_eq!(a.0, "abc"); + assert_eq!(d.header.length, 2); + assert_eq!(d.header.header, "abc"); + assert_eq!(d.slice, ["def", "123"]); + + drop(a); + drop(d); + + let mut gc = GarbageCollector::default(); + gc.add_slice_storage::(); + gc.add_storage::(); + unsafe { gc.collect() }; + } + + #[test] + fn gc_visit() { + #[derive(PartialEq, Eq, Hash)] + struct GcInterned(InternedSliceRef<'static, StringSlice>); + + crate::impl_internable!(gc; GcInterned); + + impl GcInternedVisit for GcInterned { + fn visit_with(&self, gc: &mut GarbageCollector) { + _ = gc.mark_interned_slice_alive(self.0); + } + } + + crate::impl_slice_internable!(gc; StringSlice, String, i32); + type InternedSlice = crate::InternedSlice; + + impl GcInternedSliceVisit for StringSlice { + fn visit_header(_header: &Self::Header, _gc: &mut GarbageCollector) {} + + fn visit_slice(_header: &[Self::SliceType], _gc: &mut GarbageCollector) {} + } + + let outer = { + let inner = InternedSlice::from_header_and_slice("abc".to_owned(), &[123, 456, 789]); + Interned::new_gc(GcInterned(inner)).to_owned() + }; + + let mut gc = GarbageCollector::default(); + gc.add_slice_storage::(); + gc.add_storage::(); + unsafe { gc.collect() }; + + assert_eq!(outer.0.header.header, "abc"); + assert_eq!(outer.0.slice, [123, 456, 789]); + + drop(outer); + + let mut gc = GarbageCollector::default(); + gc.add_slice_storage::(); + gc.add_storage::(); + unsafe { gc.collect() }; + } +} diff --git a/src/tools/rust-analyzer/crates/intern/src/intern.rs b/src/tools/rust-analyzer/crates/intern/src/intern.rs index fdefb936560e..5d4d00118512 100644 --- a/src/tools/rust-analyzer/crates/intern/src/intern.rs +++ b/src/tools/rust-analyzer/crates/intern/src/intern.rs @@ -26,6 +26,8 @@ unsafe impl Sync for Interned {} impl Interned { #[inline] pub fn new(obj: T) -> Self { + const { assert!(!T::USE_GC) }; + let storage = T::storage().get(); let (mut shard, hash) = Self::select(storage, &obj); // Atomically, @@ -228,6 +230,11 @@ impl<'a, T: Internable> InternedRef<'a, T> { pub unsafe fn decrement_refcount(self) { unsafe { drop(Arc::from_raw(self.as_raw())) } } + + #[inline] + pub(crate) fn strong_count(self) -> usize { + ArcBorrow::strong_count(&self.arc) + } } impl Clone for InternedRef<'_, T> { @@ -292,12 +299,12 @@ impl InternStorage { } impl InternStorage { - fn get(&self) -> &InternMap { + pub(crate) fn get(&self) -> &InternMap { self.map.get_or_init(DashMap::default) } } -pub trait Internable: Hash + Eq + 'static { +pub trait Internable: Hash + Eq + Send + Sync + 'static { const USE_GC: bool; fn storage() -> &'static InternStorage; diff --git a/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs index 989a21e70cf0..7f2159ee664e 100644 --- a/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs +++ b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs @@ -256,6 +256,16 @@ impl<'a, T: SliceInternable> InternedSliceRef<'a, T> { pub unsafe fn decrement_refcount(self) { drop(ManuallyDrop::into_inner(self.arc())); } + + #[inline] + pub(crate) fn strong_count(self) -> usize { + ThinArc::strong_count(&self.arc()) + } + + #[inline] + pub(crate) fn as_raw(self) -> *const c_void { + self.arc().as_ptr() + } } impl Clone for InternedSliceRef<'_, T> { @@ -318,15 +328,15 @@ impl InternSliceStorage { } impl InternSliceStorage { - fn get(&self) -> &InternMap { + pub(crate) fn get(&self) -> &InternMap { self.map.get_or_init(DashMap::default) } } pub trait SliceInternable: Sized + 'static { const USE_GC: bool; - type Header: Eq + Hash; - type SliceType: Eq + Hash + 'static; + type Header: Eq + Hash + Send + Sync; + type SliceType: Eq + Hash + Send + Sync + 'static; fn storage() -> &'static InternSliceStorage; } @@ -335,6 +345,7 @@ pub trait SliceInternable: Sized + 'static { #[doc(hidden)] macro_rules! _impl_slice_internable { ( gc; $tag:ident, $h:ty, $t:ty $(,)? ) => { + #[allow(unreachable_pub)] pub struct $tag; impl $crate::SliceInternable for $tag { const USE_GC: bool = true; diff --git a/src/tools/rust-analyzer/crates/intern/src/lib.rs b/src/tools/rust-analyzer/crates/intern/src/lib.rs index c5b42a860ac4..0c0b12427d21 100644 --- a/src/tools/rust-analyzer/crates/intern/src/lib.rs +++ b/src/tools/rust-analyzer/crates/intern/src/lib.rs @@ -2,10 +2,12 @@ //! //! Eventually this should probably be replaced with salsa-based interning. +mod gc; mod intern; mod intern_slice; mod symbol; +pub use self::gc::{GarbageCollector, GcInternedSliceVisit, GcInternedVisit}; pub use self::intern::{InternStorage, Internable, Interned, InternedRef, impl_internable}; pub use self::intern_slice::{ InternSliceStorage, InternedSlice, InternedSliceRef, SliceInternable, impl_slice_internable, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index f863a7ee8d04..76256b0a2253 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -355,6 +355,7 @@ impl flags::AnalysisStats { } hir::clear_tls_solver_cache(); + unsafe { hir::collect_ty_garbage() }; let db = host.raw_database_mut(); db.trigger_lru_eviction(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 007725be7406..2371f7a65649 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -98,6 +98,13 @@ config_data! { /// Code's `files.watcherExclude`. files_exclude | files_excludeDirs: Vec = vec![], + /// This config controls the frequency in which rust-analyzer will perform its internal Garbage + /// Collection. It is specified in revisions, roughly equivalent to number of changes. The default + /// is 1000. + /// + /// Setting a smaller value may help limit peak memory usage at the expense of speed. + gc_frequency: usize = 1000, + /// If this is `true`, when "Goto Implementations" and in "Implementations" lens, are triggered on a `struct` or `enum` or `union`, we filter out trait implementations that originate from `derive`s above the type. gotoImplementations_filterAdjacentDerives: bool = false, @@ -1701,9 +1708,11 @@ impl Config { pub fn caps(&self) -> &ClientCapabilities { &self.caps } -} -impl Config { + pub fn gc_freq(&self) -> usize { + *self.gc_frequency() + } + pub fn assist(&self, source_root: Option) -> AssistConfig { AssistConfig { snippet_cap: self.snippet_cap(), diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 7828f5084433..41783584a9ba 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -193,6 +193,8 @@ pub(crate) struct GlobalState { /// which will usually end up causing a bunch of incorrect diagnostics on startup. pub(crate) incomplete_crate_graph: bool, + pub(crate) revisions_until_next_gc: usize, + pub(crate) minicore: MiniCoreRustAnalyzerInternalOnly, } @@ -319,6 +321,8 @@ impl GlobalState { incomplete_crate_graph: false, minicore: MiniCoreRustAnalyzerInternalOnly::default(), + + revisions_until_next_gc: config.gc_freq(), }; // Apply any required database inputs from the config. this.update_configuration(config); @@ -435,6 +439,15 @@ impl GlobalState { }); self.analysis_host.apply_change(change); + + if self.revisions_until_next_gc == 0 { + // SAFETY: Just changed some database inputs, all queries were canceled. + unsafe { hir::collect_ty_garbage() }; + self.revisions_until_next_gc = self.config.gc_freq(); + } else { + self.revisions_until_next_gc -= 1; + } + if !modified_ratoml_files.is_empty() || !self.config.same_source_root_parent_map(&self.local_roots_parent_map) { diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index 1f5c672233ae..6b7ef049645c 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -635,6 +635,17 @@ Default: `"client"` Controls file watching implementation. +## rust-analyzer.gc.frequency {#gc.frequency} + +Default: `1000` + +This config controls the frequency in which rust-analyzer will perform its internal Garbage +Collection. It is specified in revisions, roughly equivalent to number of changes. The default +is 1000. + +Setting a smaller value may help limit peak memory usage at the expense of speed. + + ## rust-analyzer.gotoImplementations.filterAdjacentDerives {#gotoImplementations.filterAdjacentDerives} Default: `false` diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 98fe6a558b80..97db1322dd71 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -1627,6 +1627,17 @@ } } }, + { + "title": "Gc", + "properties": { + "rust-analyzer.gc.frequency": { + "markdownDescription": "This config controls the frequency in which rust-analyzer will perform its internal Garbage\nCollection. It is specified in revisions, roughly equivalent to number of changes. The default\nis 1000.\n\nSetting a smaller value may help limit peak memory usage at the expense of speed.", + "default": 1000, + "type": "integer", + "minimum": 0 + } + } + }, { "title": "Goto Implementations", "properties": { From abaf959d871a1d873f51e1fe9483f0f9efd285b0 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 18 Dec 2025 14:05:45 +0530 Subject: [PATCH 0997/3801] refactor the main loop in proc_macro-srv-cli --- .../proc-macro-srv-cli/src/main_loop.rs | 466 ++++++++++-------- 1 file changed, 251 insertions(+), 215 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index e543260964fb..aec971c776e2 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -80,239 +80,257 @@ fn run_new() -> io::Result<()> { .collect() }); - let resp_env = Envelope { - id: req.id, - kind: Kind::Response, - payload: Payload::Response( - proc_macro_api::bidirectional_protocol::msg::Response::ListMacros(res), - ), - }; - - resp_env.write::<_, C>(&mut stdout)?; + send_response::<_, C>( + &mut stdout, + req.id, + proc_macro_api::bidirectional_protocol::msg::Response::ListMacros(res), + )?; } Request::ApiVersionCheck {} => { - let resp_env = Envelope { - id: req.id, - kind: Kind::Response, - payload: Payload::Response( - proc_macro_api::bidirectional_protocol::msg::Response::ApiVersionCheck( - CURRENT_API_VERSION, - ), + send_response::<_, C>( + &mut stdout, + req.id, + proc_macro_api::bidirectional_protocol::msg::Response::ApiVersionCheck( + CURRENT_API_VERSION, ), - }; - resp_env.write::<_, C>(&mut stdout)?; + )?; } Request::SetConfig(config) => { span_mode = config.span_mode; - let resp_env = Envelope { - id: req.id, - kind: Kind::Response, - payload: Payload::Response( - proc_macro_api::bidirectional_protocol::msg::Response::SetConfig( - config, - ), - ), - }; - resp_env.write::<_, C>(&mut stdout)?; + send_response::<_, C>( + &mut stdout, + req.id, + proc_macro_api::bidirectional_protocol::msg::Response::SetConfig(config), + )?; } - Request::ExpandMacro(task) => { - let proc_macro_api::bidirectional_protocol::msg::ExpandMacro { - lib, - env, - current_dir, - data: - proc_macro_api::bidirectional_protocol::msg::ExpandMacroData { - macro_body, - macro_name, - attributes, - has_global_spans: - proc_macro_api::bidirectional_protocol::msg::ExpnGlobals { - serialize: _, - def_site, - call_site, - mixed_site, - }, - span_data_table, - }, - } = *task; - - match span_mode { - SpanMode::Id => { - let def_site = SpanId(def_site as u32); - let call_site = SpanId(call_site as u32); - let mixed_site = SpanId(mixed_site as u32); - - let macro_body = macro_body.to_tokenstream_unresolved::( - CURRENT_API_VERSION, - |_, b| b, - ); - let attributes = attributes.map(|it| { - it.to_tokenstream_unresolved::( - CURRENT_API_VERSION, - |_, b| b, - ) - }); - - let res = srv - .expand( - lib, - &env, - current_dir, - ¯o_name, - macro_body, - attributes, - def_site, - call_site, - mixed_site, - ) - .map(|it| { - msg::FlatTree::from_tokenstream_raw::( - it, - call_site, - CURRENT_API_VERSION, - ) - }) - .map_err(|e| e.into_string().unwrap_or_default()) - .map_err(msg::PanicMessage); - - let resp_env = Envelope { - id: req.id, - kind: Kind::Response, - payload: Payload::Response(proc_macro_api::bidirectional_protocol::msg::Response::ExpandMacro(res)), - }; - - resp_env.write::<_, C>(&mut stdout)?; - } - - SpanMode::RustAnalyzer => { - let mut span_data_table = - deserialize_span_data_index_map(&span_data_table); - - let def_site_span = span_data_table[def_site]; - let call_site_span = span_data_table[call_site]; - let mixed_site_span = span_data_table[mixed_site]; - - let macro_body_ts = macro_body.to_tokenstream_resolved( - CURRENT_API_VERSION, - &span_data_table, - |a, b| srv.join_spans(a, b).unwrap_or(b), - ); - let attributes_ts = attributes.map(|it| { - it.to_tokenstream_resolved( - CURRENT_API_VERSION, - &span_data_table, - |a, b| srv.join_spans(a, b).unwrap_or(b), - ) - }); - - let (subreq_tx, subreq_rx) = unbounded::(); - let (subresp_tx, subresp_rx) = - unbounded::(); - let (result_tx, result_rx) = crossbeam_channel::bounded(1); - - std::thread::scope(|scope| { - let srv_ref = &srv; - - scope.spawn({ - let lib = lib.clone(); - let env = env.clone(); - let current_dir = current_dir.clone(); - let macro_name = macro_name.clone(); - move || { - let res = srv_ref - .expand_with_channels( - lib, - &env, - current_dir, - ¯o_name, - macro_body_ts, - attributes_ts, - def_site_span, - call_site_span, - mixed_site_span, - subresp_rx, - subreq_tx, - ) - .map(|it| { - ( - msg::FlatTree::from_tokenstream( - it, - CURRENT_API_VERSION, - call_site_span, - &mut span_data_table, - ), - serialize_span_data_index_map(&span_data_table), - ) - }) - .map(|(tree, span_data_table)| { - proc_macro_api::bidirectional_protocol::msg::ExpandMacroExtended { tree, span_data_table } - }) - .map_err(|e| e.into_string().unwrap_or_default()) - .map_err(msg::PanicMessage); - let _ = result_tx.send(res); - } - }); - - loop { - if let Ok(res) = result_rx.try_recv() { - let resp_env = Envelope { - id: req.id, - kind: Kind::Response, - payload: Payload::Response( - proc_macro_api::bidirectional_protocol::msg::Response::ExpandMacroExtended(res), - ), - }; - resp_env.write::<_, C>(&mut stdout).unwrap(); - break; - } - - let subreq = match subreq_rx.recv() { - Ok(r) => r, - Err(_) => { - break; - } - }; - - let sub_env = Envelope { - id: req.id, - kind: Kind::SubRequest, - payload: Payload::SubRequest(from_srv_req(subreq)), - }; - sub_env.write::<_, C>(&mut stdout).unwrap(); - - let resp_opt = - Envelope::read::<_, C>(&mut stdin, &mut buf).unwrap(); - let resp = match resp_opt { - Some(env) => env, - None => { - break; - } - }; - - match (resp.kind, resp.payload) { - (Kind::SubResponse, Payload::SubResponse(subresp)) => { - let _ = subresp_tx.send(from_client_res(subresp)); - } - _ => { - break; - } - } - } - }); - } - } + handle_expand::<_, _, C>( + &srv, + &mut stdin, + &mut stdout, + &mut buf, + req.id, + span_mode, + *task, + )?; } }, - _ => {} + _ => continue, } } Ok(()) } +fn handle_expand( + srv: &proc_macro_srv::ProcMacroSrv<'_>, + stdin: &mut R, + stdout: &mut W, + buf: &mut C::Buf, + req_id: u64, + span_mode: SpanMode, + task: proc_macro_api::bidirectional_protocol::msg::ExpandMacro, +) -> io::Result<()> { + match span_mode { + SpanMode::Id => handle_expand_id::<_, C>(srv, stdout, req_id, task), + SpanMode::RustAnalyzer => { + handle_expand_ra::<_, _, C>(srv, stdin, stdout, buf, req_id, task) + } + } +} + +fn handle_expand_id( + srv: &proc_macro_srv::ProcMacroSrv<'_>, + stdout: &mut W, + req_id: u64, + task: proc_macro_api::bidirectional_protocol::msg::ExpandMacro, +) -> io::Result<()> { + let proc_macro_api::bidirectional_protocol::msg::ExpandMacro { lib, env, current_dir, data } = + task; + let proc_macro_api::bidirectional_protocol::msg::ExpandMacroData { + macro_body, + macro_name, + attributes, + has_global_spans: + proc_macro_api::bidirectional_protocol::msg::ExpnGlobals { + def_site, + call_site, + mixed_site, + .. + }, + .. + } = data; + + let def_site = SpanId(def_site as u32); + let call_site = SpanId(call_site as u32); + let mixed_site = SpanId(mixed_site as u32); + + let macro_body = + macro_body.to_tokenstream_unresolved::(CURRENT_API_VERSION, |_, b| b); + let attributes = attributes + .map(|it| it.to_tokenstream_unresolved::(CURRENT_API_VERSION, |_, b| b)); + + let res = srv + .expand( + lib, + &env, + current_dir, + ¯o_name, + macro_body, + attributes, + def_site, + call_site, + mixed_site, + ) + .map(|it| { + msg::FlatTree::from_tokenstream_raw::(it, call_site, CURRENT_API_VERSION) + }) + .map_err(|e| msg::PanicMessage(e.into_string().unwrap_or_default())); + + send_response::<_, C>( + stdout, + req_id, + proc_macro_api::bidirectional_protocol::msg::Response::ExpandMacro(res), + ) +} + +fn handle_expand_ra( + srv: &proc_macro_srv::ProcMacroSrv<'_>, + stdin: &mut R, + stdout: &mut W, + buf: &mut C::Buf, + req_id: u64, + task: proc_macro_api::bidirectional_protocol::msg::ExpandMacro, +) -> io::Result<()> { + let proc_macro_api::bidirectional_protocol::msg::ExpandMacro { + lib, + env, + current_dir, + data: + proc_macro_api::bidirectional_protocol::msg::ExpandMacroData { + macro_body, + macro_name, + attributes, + has_global_spans: + proc_macro_api::bidirectional_protocol::msg::ExpnGlobals { + serialize: _, + def_site, + call_site, + mixed_site, + }, + span_data_table, + }, + } = task; + + let mut span_data_table = deserialize_span_data_index_map(&span_data_table); + + let def_site_span = span_data_table[def_site]; + let call_site_span = span_data_table[call_site]; + let mixed_site_span = span_data_table[mixed_site]; + + let macro_body_ts = + macro_body.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| { + srv.join_spans(a, b).unwrap_or(b) + }); + let attributes_ts = attributes.map(|it| { + it.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| { + srv.join_spans(a, b).unwrap_or(b) + }) + }); + + let (subreq_tx, subreq_rx) = unbounded::(); + let (subresp_tx, subresp_rx) = unbounded::(); + let (result_tx, result_rx) = crossbeam_channel::bounded(1); + + std::thread::scope(|scope| { + let srv_ref = &srv; + + scope.spawn({ + let lib = lib.clone(); + let env = env.clone(); + let current_dir = current_dir.clone(); + let macro_name = macro_name.clone(); + move || { + let res = srv_ref + .expand_with_channels( + lib, + &env, + current_dir, + ¯o_name, + macro_body_ts, + attributes_ts, + def_site_span, + call_site_span, + mixed_site_span, + subresp_rx, + subreq_tx, + ) + .map(|it| { + ( + msg::FlatTree::from_tokenstream( + it, + CURRENT_API_VERSION, + call_site_span, + &mut span_data_table, + ), + serialize_span_data_index_map(&span_data_table), + ) + }) + .map(|(tree, span_data_table)| { + proc_macro_api::bidirectional_protocol::msg::ExpandMacroExtended { + tree, + span_data_table, + } + }) + .map_err(|e| e.into_string().unwrap_or_default()) + .map_err(msg::PanicMessage); + let _ = result_tx.send(res); + } + }); + + loop { + if let Ok(res) = result_rx.try_recv() { + send_response::<_, C>( + stdout, + req_id, + proc_macro_api::bidirectional_protocol::msg::Response::ExpandMacroExtended(res), + ) + .unwrap(); + break; + } + + let subreq = match subreq_rx.recv() { + Ok(r) => r, + Err(_) => { + break; + } + }; + + send_subrequest::<_, C>(stdout, req_id, from_srv_req(subreq)).unwrap(); + + let resp_opt = Envelope::read::<_, C>(stdin, buf).unwrap(); + let resp = match resp_opt { + Some(env) => env, + None => { + break; + } + }; + + match (resp.kind, resp.payload) { + (Kind::SubResponse, Payload::SubResponse(subresp)) => { + let _ = subresp_tx.send(from_client_res(subresp)); + } + _ => { + break; + } + } + } + }); + Ok(()) +} + fn run_() -> io::Result<()> { fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind { match kind { @@ -473,3 +491,21 @@ fn from_client_res( } } } + +fn send_response( + stdout: &mut W, + id: u64, + resp: proc_macro_api::bidirectional_protocol::msg::Response, +) -> io::Result<()> { + let resp = Envelope { id, kind: Kind::Response, payload: Payload::Response(resp) }; + resp.write::(stdout) +} + +fn send_subrequest( + stdout: &mut W, + id: u64, + resp: proc_macro_api::bidirectional_protocol::msg::SubRequest, +) -> io::Result<()> { + let resp = Envelope { id, kind: Kind::SubRequest, payload: Payload::SubRequest(resp) }; + resp.write::(stdout) +} From 5cdad62e1d86212de9900e6eec13615ddab07d6e Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 18 Dec 2025 14:25:15 +0530 Subject: [PATCH 0998/3801] make imports proper --- .../proc-macro-srv-cli/src/main_loop.rs | 249 +++++++++--------- 1 file changed, 118 insertions(+), 131 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index aec971c776e2..1ad73d4daac2 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -2,23 +2,22 @@ use std::io; use crossbeam_channel::unbounded; -use proc_macro_api::bidirectional_protocol::msg::Request; use proc_macro_api::{ Codec, - bidirectional_protocol::msg::{Envelope, Kind, Payload}, - legacy_protocol::msg::{ - self, ExpandMacroData, ExpnGlobals, Message, SpanMode, SpanTransformer, - deserialize_span_data_index_map, serialize_span_data_index_map, - }, + bidirectional_protocol::msg as bidirectional, + legacy_protocol::msg as legacy, transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; + +use legacy::Message; + use proc_macro_srv::{EnvSnapshot, SpanId}; use crate::ProtocolFormat; struct SpanTrans; -impl SpanTransformer for SpanTrans { +impl legacy::SpanTransformer for SpanTrans { type Table = (); type Span = SpanId; fn token_id_of( @@ -62,61 +61,61 @@ fn run_new() -> io::Result<()> { let env_snapshot = EnvSnapshot::default(); let srv = proc_macro_srv::ProcMacroSrv::new(&env_snapshot); - let mut span_mode = SpanMode::Id; + let mut span_mode = legacy::SpanMode::Id; 'outer: loop { - let req_opt = Envelope::read::<_, C>(&mut stdin, &mut buf)?; + let req_opt = bidirectional::Envelope::read::<_, C>(&mut stdin, &mut buf)?; let Some(req) = req_opt else { break 'outer; }; match (req.kind, req.payload) { - (Kind::Request, Payload::Request(request)) => match request { - Request::ListMacros { dylib_path } => { - let res = srv.list_macros(&dylib_path).map(|macros| { - macros - .into_iter() - .map(|(name, kind)| (name, macro_kind_to_api(kind))) - .collect() - }); + (bidirectional::Kind::Request, bidirectional::Payload::Request(request)) => { + match request { + bidirectional::Request::ListMacros { dylib_path } => { + let res = srv.list_macros(&dylib_path).map(|macros| { + macros + .into_iter() + .map(|(name, kind)| (name, macro_kind_to_api(kind))) + .collect() + }); - send_response::<_, C>( - &mut stdout, - req.id, - proc_macro_api::bidirectional_protocol::msg::Response::ListMacros(res), - )?; - } + send_response::<_, C>( + &mut stdout, + req.id, + bidirectional::Response::ListMacros(res), + )?; + } - Request::ApiVersionCheck {} => { - send_response::<_, C>( - &mut stdout, - req.id, - proc_macro_api::bidirectional_protocol::msg::Response::ApiVersionCheck( - CURRENT_API_VERSION, - ), - )?; - } + bidirectional::Request::ApiVersionCheck {} => { + send_response::<_, C>( + &mut stdout, + req.id, + bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), + )?; + } - Request::SetConfig(config) => { - span_mode = config.span_mode; - send_response::<_, C>( - &mut stdout, - req.id, - proc_macro_api::bidirectional_protocol::msg::Response::SetConfig(config), - )?; + bidirectional::Request::SetConfig(config) => { + span_mode = config.span_mode; + send_response::<_, C>( + &mut stdout, + req.id, + bidirectional::Response::SetConfig(config), + )?; + } + bidirectional::Request::ExpandMacro(task) => { + handle_expand::<_, _, C>( + &srv, + &mut stdin, + &mut stdout, + &mut buf, + req.id, + span_mode, + *task, + )?; + } } - Request::ExpandMacro(task) => { - handle_expand::<_, _, C>( - &srv, - &mut stdin, - &mut stdout, - &mut buf, - req.id, - span_mode, - *task, - )?; - } - }, + } _ => continue, } } @@ -130,12 +129,12 @@ fn handle_expand( stdout: &mut W, buf: &mut C::Buf, req_id: u64, - span_mode: SpanMode, - task: proc_macro_api::bidirectional_protocol::msg::ExpandMacro, + span_mode: legacy::SpanMode, + task: bidirectional::ExpandMacro, ) -> io::Result<()> { match span_mode { - SpanMode::Id => handle_expand_id::<_, C>(srv, stdout, req_id, task), - SpanMode::RustAnalyzer => { + legacy::SpanMode::Id => handle_expand_id::<_, C>(srv, stdout, req_id, task), + legacy::SpanMode::RustAnalyzer => { handle_expand_ra::<_, _, C>(srv, stdin, stdout, buf, req_id, task) } } @@ -145,21 +144,14 @@ fn handle_expand_id( srv: &proc_macro_srv::ProcMacroSrv<'_>, stdout: &mut W, req_id: u64, - task: proc_macro_api::bidirectional_protocol::msg::ExpandMacro, + task: bidirectional::ExpandMacro, ) -> io::Result<()> { - let proc_macro_api::bidirectional_protocol::msg::ExpandMacro { lib, env, current_dir, data } = - task; - let proc_macro_api::bidirectional_protocol::msg::ExpandMacroData { + let bidirectional::ExpandMacro { lib, env, current_dir, data } = task; + let bidirectional::ExpandMacroData { macro_body, macro_name, attributes, - has_global_spans: - proc_macro_api::bidirectional_protocol::msg::ExpnGlobals { - def_site, - call_site, - mixed_site, - .. - }, + has_global_spans: bidirectional::ExpnGlobals { def_site, call_site, mixed_site, .. }, .. } = data; @@ -185,15 +177,11 @@ fn handle_expand_id( mixed_site, ) .map(|it| { - msg::FlatTree::from_tokenstream_raw::(it, call_site, CURRENT_API_VERSION) + legacy::FlatTree::from_tokenstream_raw::(it, call_site, CURRENT_API_VERSION) }) - .map_err(|e| msg::PanicMessage(e.into_string().unwrap_or_default())); + .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); - send_response::<_, C>( - stdout, - req_id, - proc_macro_api::bidirectional_protocol::msg::Response::ExpandMacro(res), - ) + send_response::<_, C>(stdout, req_id, bidirectional::Response::ExpandMacro(res)) } fn handle_expand_ra( @@ -202,29 +190,24 @@ fn handle_expand_ra( stdout: &mut W, buf: &mut C::Buf, req_id: u64, - task: proc_macro_api::bidirectional_protocol::msg::ExpandMacro, + task: bidirectional::ExpandMacro, ) -> io::Result<()> { - let proc_macro_api::bidirectional_protocol::msg::ExpandMacro { + let bidirectional::ExpandMacro { lib, env, current_dir, data: - proc_macro_api::bidirectional_protocol::msg::ExpandMacroData { + bidirectional::ExpandMacroData { macro_body, macro_name, attributes, has_global_spans: - proc_macro_api::bidirectional_protocol::msg::ExpnGlobals { - serialize: _, - def_site, - call_site, - mixed_site, - }, + bidirectional::ExpnGlobals { serialize: _, def_site, call_site, mixed_site }, span_data_table, }, } = task; - let mut span_data_table = deserialize_span_data_index_map(&span_data_table); + let mut span_data_table = legacy::deserialize_span_data_index_map(&span_data_table); let def_site_span = span_data_table[def_site]; let call_site_span = span_data_table[call_site]; @@ -269,23 +252,21 @@ fn handle_expand_ra( ) .map(|it| { ( - msg::FlatTree::from_tokenstream( + legacy::FlatTree::from_tokenstream( it, CURRENT_API_VERSION, call_site_span, &mut span_data_table, ), - serialize_span_data_index_map(&span_data_table), + legacy::serialize_span_data_index_map(&span_data_table), ) }) - .map(|(tree, span_data_table)| { - proc_macro_api::bidirectional_protocol::msg::ExpandMacroExtended { - tree, - span_data_table, - } + .map(|(tree, span_data_table)| bidirectional::ExpandMacroExtended { + tree, + span_data_table, }) .map_err(|e| e.into_string().unwrap_or_default()) - .map_err(msg::PanicMessage); + .map_err(legacy::PanicMessage); let _ = result_tx.send(res); } }); @@ -295,7 +276,7 @@ fn handle_expand_ra( send_response::<_, C>( stdout, req_id, - proc_macro_api::bidirectional_protocol::msg::Response::ExpandMacroExtended(res), + bidirectional::Response::ExpandMacroExtended(res), ) .unwrap(); break; @@ -310,7 +291,7 @@ fn handle_expand_ra( send_subrequest::<_, C>(stdout, req_id, from_srv_req(subreq)).unwrap(); - let resp_opt = Envelope::read::<_, C>(stdin, buf).unwrap(); + let resp_opt = bidirectional::Envelope::read::<_, C>(stdin, buf).unwrap(); let resp = match resp_opt { Some(env) => env, None => { @@ -319,7 +300,10 @@ fn handle_expand_ra( }; match (resp.kind, resp.payload) { - (Kind::SubResponse, Payload::SubResponse(subresp)) => { + ( + bidirectional::Kind::SubResponse, + bidirectional::Payload::SubResponse(subresp), + ) => { let _ = subresp_tx.send(from_client_res(subresp)); } _ => { @@ -343,38 +327,38 @@ fn run_() -> io::Result<()> { } let mut buf = C::Buf::default(); - let mut read_request = || msg::Request::read::<_, C>(&mut io::stdin().lock(), &mut buf); - let write_response = |msg: msg::Response| msg.write::<_, C>(&mut io::stdout().lock()); + let mut read_request = || legacy::Request::read::<_, C>(&mut io::stdin().lock(), &mut buf); + let write_response = |msg: legacy::Response| msg.write::<_, C>(&mut io::stdout().lock()); let env = EnvSnapshot::default(); let srv = proc_macro_srv::ProcMacroSrv::new(&env); - let mut span_mode = SpanMode::Id; + let mut span_mode = legacy::SpanMode::Id; while let Some(req) = read_request()? { let res = match req { - msg::Request::ListMacros { dylib_path } => { - msg::Response::ListMacros(srv.list_macros(&dylib_path).map(|macros| { + legacy::Request::ListMacros { dylib_path } => { + legacy::Response::ListMacros(srv.list_macros(&dylib_path).map(|macros| { macros.into_iter().map(|(name, kind)| (name, macro_kind_to_api(kind))).collect() })) } - msg::Request::ExpandMacro(task) => { - let msg::ExpandMacro { + legacy::Request::ExpandMacro(task) => { + let legacy::ExpandMacro { lib, env, current_dir, data: - ExpandMacroData { + legacy::ExpandMacroData { macro_body, macro_name, attributes, has_global_spans: - ExpnGlobals { serialize: _, def_site, call_site, mixed_site }, + legacy::ExpnGlobals { serialize: _, def_site, call_site, mixed_site }, span_data_table, }, } = *task; match span_mode { - SpanMode::Id => msg::Response::ExpandMacro({ + legacy::SpanMode::Id => legacy::Response::ExpandMacro({ let def_site = SpanId(def_site as u32); let call_site = SpanId(call_site as u32); let mixed_site = SpanId(mixed_site as u32); @@ -397,17 +381,18 @@ fn run_() -> io::Result<()> { mixed_site, ) .map(|it| { - msg::FlatTree::from_tokenstream_raw::( + legacy::FlatTree::from_tokenstream_raw::( it, call_site, CURRENT_API_VERSION, ) }) .map_err(|e| e.into_string().unwrap_or_default()) - .map_err(msg::PanicMessage) + .map_err(legacy::PanicMessage) }), - SpanMode::RustAnalyzer => msg::Response::ExpandMacroExtended({ - let mut span_data_table = deserialize_span_data_index_map(&span_data_table); + legacy::SpanMode::RustAnalyzer => legacy::Response::ExpandMacroExtended({ + let mut span_data_table = + legacy::deserialize_span_data_index_map(&span_data_table); let def_site = span_data_table[def_site]; let call_site = span_data_table[call_site]; @@ -438,28 +423,30 @@ fn run_() -> io::Result<()> { ) .map(|it| { ( - msg::FlatTree::from_tokenstream( + legacy::FlatTree::from_tokenstream( it, CURRENT_API_VERSION, call_site, &mut span_data_table, ), - serialize_span_data_index_map(&span_data_table), + legacy::serialize_span_data_index_map(&span_data_table), ) }) - .map(|(tree, span_data_table)| msg::ExpandMacroExtended { + .map(|(tree, span_data_table)| legacy::ExpandMacroExtended { tree, span_data_table, }) .map_err(|e| e.into_string().unwrap_or_default()) - .map_err(msg::PanicMessage) + .map_err(legacy::PanicMessage) }), } } - msg::Request::ApiVersionCheck {} => msg::Response::ApiVersionCheck(CURRENT_API_VERSION), - msg::Request::SetConfig(config) => { + legacy::Request::ApiVersionCheck {} => { + legacy::Response::ApiVersionCheck(CURRENT_API_VERSION) + } + legacy::Request::SetConfig(config) => { span_mode = config.span_mode; - msg::Response::SetConfig(config) + legacy::Response::SetConfig(config) } }; write_response(res)? @@ -468,25 +455,17 @@ fn run_() -> io::Result<()> { Ok(()) } -fn from_srv_req( - value: proc_macro_srv::SubRequest, -) -> proc_macro_api::bidirectional_protocol::msg::SubRequest { +fn from_srv_req(value: proc_macro_srv::SubRequest) -> bidirectional::SubRequest { match value { proc_macro_srv::SubRequest::SourceText { file_id, start, end } => { - proc_macro_api::bidirectional_protocol::msg::SubRequest::SourceText { - file_id: file_id.file_id().index(), - start, - end, - } + bidirectional::SubRequest::SourceText { file_id: file_id.file_id().index(), start, end } } } } -fn from_client_res( - value: proc_macro_api::bidirectional_protocol::msg::SubResponse, -) -> proc_macro_srv::SubResponse { +fn from_client_res(value: bidirectional::SubResponse) -> proc_macro_srv::SubResponse { match value { - proc_macro_api::bidirectional_protocol::msg::SubResponse::SourceTextResult { text } => { + bidirectional::SubResponse::SourceTextResult { text } => { proc_macro_srv::SubResponse::SourceTextResult { text } } } @@ -495,17 +474,25 @@ fn from_client_res( fn send_response( stdout: &mut W, id: u64, - resp: proc_macro_api::bidirectional_protocol::msg::Response, + resp: bidirectional::Response, ) -> io::Result<()> { - let resp = Envelope { id, kind: Kind::Response, payload: Payload::Response(resp) }; + let resp = bidirectional::Envelope { + id, + kind: bidirectional::Kind::Response, + payload: bidirectional::Payload::Response(resp), + }; resp.write::(stdout) } fn send_subrequest( stdout: &mut W, id: u64, - resp: proc_macro_api::bidirectional_protocol::msg::SubRequest, + resp: bidirectional::SubRequest, ) -> io::Result<()> { - let resp = Envelope { id, kind: Kind::SubRequest, payload: Payload::SubRequest(resp) }; + let resp = bidirectional::Envelope { + id, + kind: bidirectional::Kind::SubRequest, + payload: bidirectional::Payload::SubRequest(resp), + }; resp.write::(stdout) } From b65078edce5cfb09a1870fb2df4fefd530f135b4 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 18 Dec 2025 14:34:57 +0530 Subject: [PATCH 0999/3801] change request id to u32 to make powerpc happy --- .../proc-macro-api/src/bidirectional_protocol/msg.rs | 2 +- .../crates/proc-macro-api/src/process.rs | 6 +++--- .../crates/proc-macro-srv-cli/src/main_loop.rs | 11 ++++++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 7aed3ae1e607..796573385c3c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -8,7 +8,7 @@ use crate::{ legacy_protocol::msg::{FlatTree, Message, PanicMessage, ServerConfig}, }; -pub type RequestId = u64; +pub type RequestId = u32; #[derive(Debug, Serialize, Deserialize)] pub struct Envelope { diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index 723fc928ff66..bb4599c53272 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -6,7 +6,7 @@ use std::{ process::{Child, ChildStdin, ChildStdout, Command, Stdio}, sync::{ Arc, Mutex, OnceLock, - atomic::{AtomicU64, Ordering}, + atomic::{AtomicU32, Ordering}, }, }; @@ -36,7 +36,7 @@ pub(crate) struct ProcMacroServerProcess { protocol: Protocol, /// Populated when the server exits. exited: OnceLock>, - next_request_id: AtomicU64, + next_request_id: AtomicU32, } #[derive(Debug, Clone)] @@ -94,7 +94,7 @@ impl ProcMacroServerProcess { version: 0, protocol: protocol.clone(), exited: OnceLock::new(), - next_request_id: AtomicU64::new(1), + next_request_id: AtomicU32::new(1), }) }; let mut srv = create_srv()?; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 1ad73d4daac2..dc828a87de13 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -10,6 +10,7 @@ use proc_macro_api::{ version::CURRENT_API_VERSION, }; +use bidirectional::RequestId; use legacy::Message; use proc_macro_srv::{EnvSnapshot, SpanId}; @@ -128,7 +129,7 @@ fn handle_expand( stdin: &mut R, stdout: &mut W, buf: &mut C::Buf, - req_id: u64, + req_id: RequestId, span_mode: legacy::SpanMode, task: bidirectional::ExpandMacro, ) -> io::Result<()> { @@ -143,7 +144,7 @@ fn handle_expand( fn handle_expand_id( srv: &proc_macro_srv::ProcMacroSrv<'_>, stdout: &mut W, - req_id: u64, + req_id: RequestId, task: bidirectional::ExpandMacro, ) -> io::Result<()> { let bidirectional::ExpandMacro { lib, env, current_dir, data } = task; @@ -189,7 +190,7 @@ fn handle_expand_ra( stdin: &mut R, stdout: &mut W, buf: &mut C::Buf, - req_id: u64, + req_id: RequestId, task: bidirectional::ExpandMacro, ) -> io::Result<()> { let bidirectional::ExpandMacro { @@ -473,7 +474,7 @@ fn from_client_res(value: bidirectional::SubResponse) -> proc_macro_srv::SubResp fn send_response( stdout: &mut W, - id: u64, + id: u32, resp: bidirectional::Response, ) -> io::Result<()> { let resp = bidirectional::Envelope { @@ -486,7 +487,7 @@ fn send_response( fn send_subrequest( stdout: &mut W, - id: u64, + id: u32, resp: bidirectional::SubRequest, ) -> io::Result<()> { let resp = bidirectional::Envelope { From 1dff3e71a46c4bdde01ba52c37c07902ed089c6e Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Thu, 18 Dec 2025 01:25:57 -0800 Subject: [PATCH 1000/3801] stabilization_guide: add missing `)` in prose --- src/doc/rustc-dev-guide/src/stabilization_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/stabilization_guide.md b/src/doc/rustc-dev-guide/src/stabilization_guide.md index 19296b22cecf..6167546a2bc8 100644 --- a/src/doc/rustc-dev-guide/src/stabilization_guide.md +++ b/src/doc/rustc-dev-guide/src/stabilization_guide.md @@ -64,7 +64,7 @@ Before the stabilization will be considered by the lang team, there must be a co There is a central listing of unstable feature-gates in [`compiler/rustc_feature/src/unstable.rs`]. Search for the `declare_features!` macro. There should be an entry for the feature you are aiming to stabilize, -something like the following (taken from [rust-lang/rust#32409]: +something like the following (taken from [rust-lang/rust#32409]): ```rust,ignore // pub(restricted) visibilities (RFC 1422) From 957169399012bd3474b6b9b4c90048996f7c53b3 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Thu, 18 Dec 2025 01:32:49 -0800 Subject: [PATCH 1001/3801] unstable.rs: fix typos in comments (implementatble -> implementable) --- compiler/rustc_feature/src/unstable.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index fe053935f9e6..f0a1f1416859 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -221,7 +221,7 @@ declare_features! ( (internal, compiler_builtins, "1.13.0", None), /// Allows writing custom MIR (internal, custom_mir, "1.65.0", None), - /// Implementation details of externally implementatble items + /// Implementation details of externally implementable items (internal, eii_internals, "CURRENT_RUSTC_VERSION", None), /// Outputs useful `assert!` messages (unstable, generic_assert, "1.63.0", None), @@ -503,7 +503,7 @@ declare_features! ( (incomplete, explicit_tail_calls, "1.72.0", Some(112788)), /// Allows using `#[export_stable]` which indicates that an item is exportable. (incomplete, export_stable, "1.88.0", Some(139939)), - /// Externally implementatble items + /// Externally implementable items (unstable, extern_item_impls, "CURRENT_RUSTC_VERSION", Some(125418)), /// Allows defining `extern type`s. (unstable, extern_types, "1.23.0", Some(43467)), From 6396521fdbcda3c9e79dd7c6f698d6589eeaf5ce Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 18 Dec 2025 10:52:32 +0000 Subject: [PATCH 1002/3801] Rustup to rustc 1.94.0-nightly (f794a0873 2025-12-17) --- rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 4d3fe30e7d47..6ce49eb4ccf0 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-12-16" +channel = "nightly-2025-12-18" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal" From 8de4afd39ba48f25be98684cdb7a96ec6da89d10 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:09:12 +0000 Subject: [PATCH 1003/3801] Fix rustc testsuite --- scripts/test_rustc_tests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 69c6099c3ab8..b25269d1430a 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -35,6 +35,7 @@ git checkout -- tests/ui/entry-point/auxiliary/bad_main_functions.rs rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic rm tests/ui/simd/dont-invalid-bitcast-x86_64.rs # unimplemented llvm.x86.sse41.round.ps rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # unimplemented simd_funnel_{shl,shr} +rm -r tests/ui/scalable-vectors # scalable vectors are unsupported # exotic linkages rm tests/incremental/hashes/function_interfaces.rs @@ -159,6 +160,7 @@ rm tests/ui/lint/use-redundant/use-redundant-issue-71450.rs # same rm tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs # same rm tests/ui/specialization/const_trait_impl.rs # same rm tests/ui/thir-print/offset_of.rs # same +rm tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs # same # genuine bugs # ============ From fe34b17c2a626df957d26b6c2e0bbcf6e0565311 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Thu, 18 Dec 2025 11:39:40 +0100 Subject: [PATCH 1004/3801] Port `#[rustc_lint_opt_deny_field_access]` to attribute parser --- .../src/attributes/rustc_internal.rs | 24 +++++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 7 +++--- .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/internal.rs | 9 ++----- compiler/rustc_passes/messages.ftl | 3 --- compiler/rustc_passes/src/check_attr.rs | 16 +------------ compiler/rustc_passes/src/errors.rs | 9 ------- 8 files changed, 35 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 7910443787b4..72c6d9e9851f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -117,6 +117,30 @@ impl SingleAttributeParser for RustcLegacyConstGenericsParser { } } +pub(crate) struct RustcLintOptDenyFieldAccessParser; + +impl SingleAttributeParser for RustcLintOptDenyFieldAccessParser { + const PATH: &[Symbol] = &[sym::rustc_lint_opt_deny_field_access]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]); + const TEMPLATE: AttributeTemplate = template!(Word); + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(arg) = args.list().and_then(MetaItemListParser::single) else { + cx.expected_single_argument(cx.attr_span); + return None; + }; + + let MetaItemOrLitParser::Lit(MetaItemLit { kind: LitKind::Str(lint_message, _), .. }) = arg + else { + cx.expected_string_literal(arg.span(), arg.lit()); + return None; + }; + + Some(AttributeKind::RustcLintOptDenyFieldAccess { lint_message: *lint_message }) + } +} + pub(crate) struct RustcLintOptTyParser; impl NoArgsAttributeParser for RustcLintOptTyParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index b4854c430cae..e5448e7792a8 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,9 +61,9 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser, - RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, - RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, + RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, + RustcLintQueryInstabilityParser, RustcMainParser, RustcNeverReturnsNullPointerParser, + RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; @@ -213,6 +213,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 5e650fbb9bd0..5991fb5ab24e 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -931,6 +931,9 @@ pub enum AttributeKind { /// Represents `#[rustc_legacy_const_generics]` RustcLegacyConstGenerics { fn_indexes: ThinVec<(usize, Span)>, attr_span: Span }, + /// Represents `#[rustc_lint_opt_deny_field_access]` + RustcLintOptDenyFieldAccess { lint_message: Symbol }, + /// Represents `#[rustc_lint_opt_ty]` RustcLintOptTy, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index f99069e416bd..64aa9c2a45bc 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -94,6 +94,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, + RustcLintOptDenyFieldAccess { .. } => Yes, RustcLintOptTy => Yes, RustcLintQueryInstability => Yes, RustcMain => No, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index c32fed3674fc..d6f20a4c85a4 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -668,17 +668,12 @@ impl LateLintPass<'_> for BadOptAccess { for field in adt_def.all_fields() { if field.name == target.name - && let Some(attr) = - cx.tcx.get_attr(field.did, sym::rustc_lint_opt_deny_field_access) - && let Some(items) = attr.meta_item_list() - && let Some(item) = items.first() - && let Some(lit) = item.lit() - && let ast::LitKind::Str(val, _) = lit.kind + && let Some(lint_message) = find_attr!(cx.tcx.get_all_attrs(field.did), AttributeKind::RustcLintOptDenyFieldAccess { lint_message, } => lint_message) { cx.emit_span_lint( BAD_OPT_ACCESS, expr.span, - BadOptAccessDiag { msg: val.as_str() }, + BadOptAccessDiag { msg: lint_message.as_str() }, ); } } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 5a9b75957517..7ebfca91d499 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -473,9 +473,6 @@ passes_rustc_legacy_const_generics_only = #[rustc_legacy_const_generics] functions must only have const generics .label = non-const generic parameter -passes_rustc_lint_opt_deny_field_access = - `#[rustc_lint_opt_deny_field_access]` should be applied to a field - .label = not a field passes_rustc_pub_transparent = attribute should be applied to `#[repr(transparent)]` types diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d03da2e06cf1..33a3477bcf69 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -258,6 +258,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) + | AttributeKind::RustcLintOptDenyFieldAccess { .. } | AttributeKind::RustcLintOptTy | AttributeKind::RustcLintQueryInstability | AttributeKind::RustcNeverReturnsNullPointer @@ -314,9 +315,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_lint_diagnostics, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } - [sym::rustc_lint_opt_deny_field_access, ..] => { - self.check_rustc_lint_opt_deny_field_access(attr, span, target) - } [sym::rustc_clean, ..] | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] @@ -1251,18 +1249,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks that the `#[rustc_lint_opt_deny_field_access]` attribute is only applied to a field. - fn check_rustc_lint_opt_deny_field_access(&self, attr: &Attribute, span: Span, target: Target) { - match target { - Target::Field => {} - _ => { - self.tcx - .dcx() - .emit_err(errors::RustcLintOptDenyFieldAccess { attr_span: attr.span(), span }); - } - } - } - /// Checks that the dep-graph debugging attributes are only present when the query-dep-graph /// option is passed to the compiler. fn check_rustc_dirty_clean(&self, attr: &Attribute) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index f2b7d3740cb6..895cefe672ba 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -412,15 +412,6 @@ pub(crate) struct UnusedMultiple { pub name: Symbol, } -#[derive(Diagnostic)] -#[diag(passes_rustc_lint_opt_deny_field_access)] -pub(crate) struct RustcLintOptDenyFieldAccess { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(passes_collapse_debuginfo)] pub(crate) struct CollapseDebuginfo { From cd4d899862bf23ce325c55310537b326d349bcd4 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Thu, 18 Dec 2025 12:30:05 +0100 Subject: [PATCH 1005/3801] make all parsed rustc attributes error on duplicate --- compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 72c6d9e9851f..8005dd76b2a3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -145,7 +145,7 @@ pub(crate) struct RustcLintOptTyParser; impl NoArgsAttributeParser for RustcLintOptTyParser { const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy; } @@ -154,7 +154,7 @@ pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { const PATH: &[Symbol] = &[sym::rustc_lint_query_instability]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), From 45671b42e6b951c065d73b9f7ccaa0ff576cf9cb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:50:08 +0000 Subject: [PATCH 1006/3801] Merge commit '8de4afd39ba48f25be98684cdb7a96ec6da89d10' into sync_cg_clif-2025-12-18 --- .github/workflows/main.yml | 8 ++++---- .github/workflows/rustc.yml | 4 ++-- example/std_example.rs | 18 ++++++++++++++++++ rust-toolchain | 4 ---- rust-toolchain.toml | 4 ++++ scripts/rustup.sh | 5 ++--- scripts/test_rustc_tests.sh | 29 ++++++++++++++++++++++++----- src/driver/jit.rs | 2 +- src/intrinsics/llvm_x86.rs | 29 +++++++++++++++++++++++++++++ triagebot.toml | 3 --- 10 files changed, 84 insertions(+), 22 deletions(-) delete mode 100644 rust-toolchain create mode 100644 rust-toolchain.toml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0930b924d177..07d9af4a9b54 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: - name: Avoid installing rustc-dev run: | - sed -i 's/components.*/components = ["rustfmt"]/' rust-toolchain + sed -i 's/components.*/components = ["rustfmt"]/' rust-toolchain.toml rustfmt -v - name: Rustfmt @@ -88,7 +88,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} - name: Set MinGW as the default toolchain if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' @@ -158,7 +158,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} - name: Install hyperfine run: | @@ -207,7 +207,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-dist-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-dist-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} - name: Set MinGW as the default toolchain if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' diff --git a/.github/workflows/rustc.yml b/.github/workflows/rustc.yml index 9253ab96353c..b22725fdc9d4 100644 --- a/.github/workflows/rustc.yml +++ b/.github/workflows/rustc.yml @@ -20,7 +20,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }} - name: Test run: ./scripts/test_bootstrap.sh @@ -40,7 +40,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }} - name: Install ripgrep run: | diff --git a/example/std_example.rs b/example/std_example.rs index c569ef0ef829..33db75f0943a 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -259,6 +259,9 @@ unsafe fn test_simd() { test_mm_cvttps_epi32(); test_mm_cvtsi128_si64(); + #[cfg(not(jit))] + test_mm_cvtps_ph(); + test_mm_extract_epi8(); test_mm_insert_epi16(); test_mm_shuffle_epi8(); @@ -558,6 +561,21 @@ unsafe fn test_mm_cvttps_epi32() { } } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "f16c")] +#[cfg(not(jit))] +unsafe fn test_mm_cvtps_ph() { + const F16_ONE: i16 = 0x3c00; + const F16_TWO: i16 = 0x4000; + const F16_THREE: i16 = 0x4200; + const F16_FOUR: i16 = 0x4400; + + let a = _mm_set_ps(1.0, 2.0, 3.0, 4.0); + let r = _mm_cvtps_ph::<_MM_FROUND_CUR_DIRECTION>(a); + let e = _mm_set_epi16(0, 0, 0, 0, F16_ONE, F16_TWO, F16_THREE, F16_FOUR); + assert_eq_m128i(r, e); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); diff --git a/rust-toolchain b/rust-toolchain deleted file mode 100644 index 461dbcdb0fb5..000000000000 --- a/rust-toolchain +++ /dev/null @@ -1,4 +0,0 @@ -[toolchain] -channel = "nightly-2025-12-08" -components = ["rust-src", "rustc-dev", "llvm-tools"] -profile = "minimal" diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000000..6ce49eb4ccf0 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "nightly-2025-12-18" +components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] +profile = "minimal" diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 1a82193303e2..e26be307328f 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -22,8 +22,7 @@ case $1 in "prepare") echo "=> Installing new nightly" rustup toolchain install --profile minimal "nightly-${TOOLCHAIN}" # Sanity check to see if the nightly exists - sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain - rustup component add rustfmt || true + sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain.toml echo "=> Uninstalling all old nightlies" for nightly in $(rustup toolchain list | grep nightly | grep -v "$TOOLCHAIN" | grep -v nightly-x86_64); do @@ -35,7 +34,7 @@ case $1 in ./y.sh prepare ;; "commit") - git add rust-toolchain + git add rust-toolchain.toml git commit -m "Rustup to $(rustc -V)" ;; "push") diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index b5af585a732e..b25269d1430a 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -35,6 +35,7 @@ git checkout -- tests/ui/entry-point/auxiliary/bad_main_functions.rs rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic rm tests/ui/simd/dont-invalid-bitcast-x86_64.rs # unimplemented llvm.x86.sse41.round.ps rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # unimplemented simd_funnel_{shl,shr} +rm -r tests/ui/scalable-vectors # scalable vectors are unsupported # exotic linkages rm tests/incremental/hashes/function_interfaces.rs @@ -53,23 +54,29 @@ rm tests/ui/sanitizer/kcfi-c-variadic.rs # same rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported rm tests/ui/delegation/fn-header.rs +# inline assembly features +rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly +rm tests/ui/asm/global-asm-mono-sym-fn.rs # same +rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same +rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported +rm tests/ui/asm/label-operand.rs # same +rm tests/ui/asm/may_unwind.rs # asm unwinding not supported +rm tests/ui/asm/aarch64/may_unwind.rs # same + # misc unimplemented things rm tests/ui/target-feature/missing-plusminus.rs # error not implemented rm -r tests/run-make/repr128-dwarf # debuginfo test rm -r tests/run-make/split-debuginfo # same rm -r tests/run-make/target-specs # i686 not supported by Cranelift rm -r tests/run-make/mismatching-target-triples # same -rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly -rm tests/ui/asm/global-asm-mono-sym-fn.rs # same -rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same -rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported -rm tests/ui/asm/label-operand.rs # same rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported rm -r tests/ui/explicit-tail-calls # tail calls rm -r tests/run-make/pointer-auth-link-with-c # pointer auth +rm -r tests/ui/eii # EII not yet implemented +rm -r tests/run-make/forced-unwind-terminate-pof # forced unwinding doesn't take precedence # requires LTO rm -r tests/run-make/cdylib @@ -78,6 +85,7 @@ rm -r tests/run-make/lto-* rm -r tests/run-make/reproducible-build-2 rm -r tests/run-make/no-builtins-lto rm -r tests/run-make/reachable-extern-fn-available-lto +rm -r tests/run-make/no-builtins-linker-plugin-lto # coverage instrumentation rm tests/ui/consts/precise-drop-with-coverage.rs @@ -87,6 +95,7 @@ rm -r tests/ui/instrument-coverage/ # ================== rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations rm tests/ui/codegen/init-large-type.rs # same +rm tests/ui/codegen/StackColoring-not-blowup-stack-issue-40883.rs # same rm tests/ui/statics/const_generics.rs # tests an optimization rm tests/ui/linking/executable-no-mangle-strip.rs # requires --gc-sections to work for statics @@ -143,6 +152,15 @@ rm tests/ui/errors/remap-path-prefix-sysroot.rs # different sysroot source path rm -r tests/run-make/export/extern-opt # something about rustc version mismatches rm -r tests/run-make/export # same rm -r tests/ui/compiletest-self-test/compile-flags-incremental.rs # needs compiletest compiled with panic=unwind +rm tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs # something going wrong with stdlib source remapping +rm tests/ui/consts/miri_unleashed/drop.rs # same +rm tests/ui/error-emitter/multiline-removal-suggestion.rs # same +rm tests/ui/lint/lint-const-item-mutation.rs # same +rm tests/ui/lint/use-redundant/use-redundant-issue-71450.rs # same +rm tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs # same +rm tests/ui/specialization/const_trait_impl.rs # same +rm tests/ui/thir-print/offset_of.rs # same +rm tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs # same # genuine bugs # ============ @@ -157,6 +175,7 @@ rm tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs # same rm tests/ui/async-await/async-drop/async-drop-initial.rs # same (rust-lang/rust#140493) rm -r tests/ui/codegen/equal-pointers-unequal # make incorrect assumptions about the location of stack variables rm -r tests/run-make-cargo/rustdoc-scrape-examples-paths # FIXME(rust-lang/rust#145580) incr comp bug +rm -r tests/incremental/extern_static/issue-49153.rs # assumes reference to undefined static gets optimized away rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # really slow with unoptimized libstd rm tests/ui/process/process-panic-after-fork.rs # same diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 9dba46363936..3a8ca25a5fc0 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -190,7 +190,7 @@ fn dep_symbol_lookup_fn( diag.emit(); } Linkage::Dynamic => { - dylib_paths.push(src.dylib.as_ref().unwrap().0.clone()); + dylib_paths.push(src.dylib.as_ref().unwrap().clone()); } } } diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 37fbe4be1b0f..61f48fa97743 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -1313,6 +1313,35 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>( ret.write_cvalue_transmute(fx, res); } + "llvm.x86.vcvtps2ph.128" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtps_ph + intrinsic_args!(fx, args => (a, _imm8); intrinsic); + let a = a.load_scalar(fx); + + let imm8 = + if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[1].node) { + imm8 + } else { + fx.tcx + .dcx() + .span_fatal(span, "Index argument for `_mm_cvtps_ph` is not a constant"); + }; + + let imm8 = imm8.to_u32(); + + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String(format!("vcvtps2ph xmm0, xmm0, {imm8}").into())], + &[CInlineAsmOperand::InOut { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)), + _late: true, + in_value: a, + out_place: Some(ret), + }], + InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, + ); + } + _ => { fx.tcx .dcx() diff --git a/triagebot.toml b/triagebot.toml index 13da0a87def3..eb0c7b011f60 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -2,6 +2,3 @@ # Prevents un-canonicalized issue links (to avoid wrong issues being linked in r-l/rust) [issue-links] - -# Prevents mentions in commits to avoid users being spammed -[no-mentions] From e1e8e0648cebb900fd0a1c44057caa1513bba126 Mon Sep 17 00:00:00 2001 From: Redddy Date: Thu, 18 Dec 2025 21:13:17 +0900 Subject: [PATCH 1007/3801] fix typo Co-authored-by: Tshepang Mbambo --- src/doc/rustc-dev-guide/src/serialization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/serialization.md b/src/doc/rustc-dev-guide/src/serialization.md index fcea4f3e605b..0fb7870c3a5f 100644 --- a/src/doc/rustc-dev-guide/src/serialization.md +++ b/src/doc/rustc-dev-guide/src/serialization.md @@ -126,9 +126,9 @@ and `Encodable`. all `Encoders` and `Decoders`. These should be used in crates that don't depend on [`rustc_middle`], or that have to be serialized by a type that does not implement `TyEncoder`. -- [`MetadataEncodable`] generate implementations that +- [`MetadataEncodable`] generates implementations that only allow decoding by [`rustc_metadata::rmeta::encoder::EncodeContext`]. -- [`BlobDecodable`] and [`LazyDecodable`] generate implementations that decode +- [`BlobDecodable`] and [`LazyDecodable`] generates implementations that decode with the metadata blob decoders in [`rustc_metadata::rmeta`]; use `BlobDecodable` when the type has no lazy metadata handles, and `LazyDecodable` when it does. - `TyEncodable` and `TyDecodable` generate implementation that apply to any From 54a25b152642d5e72b367a45e1080d255b5a6314 Mon Sep 17 00:00:00 2001 From: Redddy Date: Thu, 18 Dec 2025 23:54:18 +0900 Subject: [PATCH 1008/3801] Clarify descriptions for BlobDecodable and LazyDecodable --- src/doc/rustc-dev-guide/src/serialization.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/serialization.md b/src/doc/rustc-dev-guide/src/serialization.md index 0fb7870c3a5f..91b2cc92125e 100644 --- a/src/doc/rustc-dev-guide/src/serialization.md +++ b/src/doc/rustc-dev-guide/src/serialization.md @@ -128,9 +128,10 @@ and `Encodable`. not implement `TyEncoder`. - [`MetadataEncodable`] generates implementations that only allow decoding by [`rustc_metadata::rmeta::encoder::EncodeContext`]. -- [`BlobDecodable`] and [`LazyDecodable`] generates implementations that decode - with the metadata blob decoders in [`rustc_metadata::rmeta`]; use `BlobDecodable` - when the type has no lazy metadata handles, and `LazyDecodable` when it does. +- [`BlobDecodable`] and [`LazyDecodable`] serve as the decoding counterparts to + `MetadataEncodable`. They generate implementations that decode with the + metadata blob decoders in `rustc_metadata::rmeta`; use `BlobDecodable` when + the type has no lazy metadata handles, and `LazyDecodable` when it does. - `TyEncodable` and `TyDecodable` generate implementation that apply to any `TyEncoder` or `TyDecoder`. These should be used for types that are only serialized in crate metadata and/or the incremental cache, which is most From e337275d0667dc6d61af6d99d74b1df89198a521 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Sun, 14 Sep 2025 04:37:45 +0000 Subject: [PATCH 1009/3801] RISC-V: Add virtual target feature: `zkne_or_zknd` Because some AES key scheduling instructions require *either* Zkne or Zknd extension, we must have a target feature to represent `(Zkne || Zknd)`. This commit adds (perma-unstable) target feature to the RISC-V architecture: `zkne_or_zknd` for this purpose. Helped-by: sayantn --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 5 +++++ compiler/rustc_target/src/target_features.rs | 5 +++-- tests/ui/check-cfg/target_feature.stderr | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 682484595a89..14ef9ce68c9b 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -262,6 +262,11 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Some(LLVMFeature::new("crypto")), s => Some(LLVMFeature::new(s)), }, + Arch::RiscV32 | Arch::RiscV64 => match s { + // Filter out Rust-specific *virtual* target feature + "zkne_or_zknd" => None, + s => Some(LLVMFeature::new(s)), + }, Arch::Sparc | Arch::Sparc64 => match s { "leoncasa" => Some(LLVMFeature::new("hasleoncasa")), s => Some(LLVMFeature::new(s)), diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index e516a31d1e66..2c2e3c7caad7 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -690,8 +690,9 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zimop", Unstable(sym::riscv_target_feature), &[]), ("zk", Stable, &["zkn", "zkr", "zkt"]), ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]), - ("zknd", Stable, &[]), - ("zkne", Stable, &[]), + ("zknd", Stable, &["zkne_or_zknd"]), + ("zkne", Stable, &["zkne_or_zknd"]), + ("zkne_or_zknd", Unstable(sym::riscv_target_feature), &[]), // Not an extension ("zknh", Stable, &[]), ("zkr", Stable, &[]), ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]), diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index d25e7f094964..ea7c2efddc6e 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -423,6 +423,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `zkn` `zknd` `zkne` +`zkne_or_zknd` `zknh` `zkr` `zks` From 288c372b7a039cb05803ebc6ed04254fec535cf0 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Fri, 19 Sep 2025 21:36:50 +0000 Subject: [PATCH 1010/3801] RISC-V: Use inline assembly and `zkne_or_zknd` on (Zkne or Zknd) intrinsics Using the inline assembly and `zkne_or_zknd` target feature could avoid current issues regarding intrinsics available when either Zkne or Zknd is available. Before this commit, intrinsics `aes64ks1i` and `aes64ks2` required both Zkne and Zknd extensions, not either Zkne or Zknd. Closes: https://github.com/rust-lang/stdarch/issues/1765 --- .../crates/core_arch/src/riscv64/zk.rs | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/riscv64/zk.rs b/library/stdarch/crates/core_arch/src/riscv64/zk.rs index a30653cbe088..3aa1ca39b3c9 100644 --- a/library/stdarch/crates/core_arch/src/riscv64/zk.rs +++ b/library/stdarch/crates/core_arch/src/riscv64/zk.rs @@ -1,6 +1,8 @@ #[cfg(test)] use stdarch_test::assert_instr; +use crate::arch::asm; + unsafe extern "unadjusted" { #[link_name = "llvm.riscv.aes64es"] fn _aes64es(rs1: i64, rs2: i64) -> i64; @@ -14,12 +16,6 @@ unsafe extern "unadjusted" { #[link_name = "llvm.riscv.aes64dsm"] fn _aes64dsm(rs1: i64, rs2: i64) -> i64; - #[link_name = "llvm.riscv.aes64ks1i"] - fn _aes64ks1i(rs1: i64, rnum: i32) -> i64; - - #[link_name = "llvm.riscv.aes64ks2"] - fn _aes64ks2(rs1: i64, rs2: i64) -> i64; - #[link_name = "llvm.riscv.aes64im"] fn _aes64im(rs1: i64) -> i64; @@ -133,15 +129,26 @@ pub fn aes64dsm(rs1: u64, rs2: u64) -> u64 { /// # Note /// /// The `RNUM` parameter is expected to be a constant value inside the range of `0..=10`. -#[target_feature(enable = "zkne", enable = "zknd")] +#[target_feature(enable = "zkne_or_zknd")] #[rustc_legacy_const_generics(1)] -#[cfg_attr(test, assert_instr(aes64ks1i, RNUM = 0))] #[inline] #[unstable(feature = "riscv_ext_intrinsics", issue = "114544")] pub fn aes64ks1i(rs1: u64) -> u64 { static_assert!(RNUM <= 10); - - unsafe { _aes64ks1i(rs1 as i64, RNUM as i32) as u64 } + unsafe { + let rd: u64; + asm!( + ".option push", + ".option arch, +zkne", + "aes64ks1i {}, {}, {}", + ".option pop", + lateout(reg) rd, + in(reg) rs1, + const RNUM, + options(pure, nomem, nostack, preserves_flags) + ); + rd + } } /// This instruction implements part of the KeySchedule operation for the AES Block cipher. @@ -155,12 +162,24 @@ pub fn aes64ks1i(rs1: u64) -> u64 { /// Version: v1.0.1 /// /// Section: 3.11 -#[target_feature(enable = "zkne", enable = "zknd")] -#[cfg_attr(test, assert_instr(aes64ks2))] +#[target_feature(enable = "zkne_or_zknd")] #[inline] #[unstable(feature = "riscv_ext_intrinsics", issue = "114544")] pub fn aes64ks2(rs1: u64, rs2: u64) -> u64 { - unsafe { _aes64ks2(rs1 as i64, rs2 as i64) as u64 } + unsafe { + let rd: u64; + asm!( + ".option push", + ".option arch, +zkne", + "aes64ks2 {}, {}, {}", + ".option pop", + lateout(reg) rd, + in(reg) rs1, + in(reg) rs2, + options(pure, nomem, nostack, preserves_flags) + ); + rd + } } /// This instruction accelerates the inverse MixColumns step of the AES Block Cipher, and is used to aid creation of From 83d8750aead21f4acd494d9889e131dde499d348 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 18 Dec 2025 17:28:03 +0200 Subject: [PATCH 1011/3801] Add extensive docs for the unsafe operations --- .../crates/hir-ty/src/next_solver.rs | 4 + .../hir-ty/src/next_solver/generic_arg.rs | 19 ++- .../crates/hir-ty/src/next_solver/interner.rs | 8 ++ .../rust-analyzer/crates/intern/src/gc.rs | 67 +++++----- .../rust-analyzer/crates/intern/src/intern.rs | 46 ++++++- .../crates/intern/src/intern_slice.rs | 117 ++++++------------ 6 files changed, 146 insertions(+), 115 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs index 539d09a8f5df..e91864bd8759 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs @@ -1,5 +1,9 @@ //! Things relevant to the next trait solver. +// Note: in interned types defined in this module, we generally treat the lifetime as advisory +// and transmute it as needed. This is because no real memory unsafety can be caused from an +// incorrect lifetime here. + pub mod abi; mod binder; mod consts; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs index f31b487eaed5..b600f6000d9e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs @@ -1,4 +1,10 @@ -//! Things related to generic args in the next-trait-solver. +//! Things related to generic args in the next-trait-solver (`GenericArg`, `GenericArgs`, `Term`). +//! +//! Implementations of `GenericArg` and `Term` are pointer-tagged instead of an enum (rustc does +//! the same). This is done to save memory (which also helps speed) - one `GenericArg` is a machine +//! word instead of two, while matching on it is basically as cheap. The implementation for both +//! `GenericArg` and `Term` is shared in [`GenericArgImpl`]. This both simplifies the implementation, +//! as well as enables a noop conversion from `Term` to `GenericArg`. use std::{hint::unreachable_unchecked, marker::PhantomData, ptr::NonNull}; @@ -29,10 +35,14 @@ pub type TermKind<'db> = rustc_type_ir::TermKind>; #[derive(Clone, Copy, PartialEq, Eq, Hash)] struct GenericArgImpl<'db> { + /// # Invariant + /// + /// Contains an [`InternedRef`] of a [`Ty`], [`Const`] or [`Region`], bit-tagged as per the consts below. ptr: NonNull<()>, _marker: PhantomData<(Ty<'db>, Const<'db>, Region<'db>)>, } +// SAFETY: We essentially own the `Ty`, `Const` or `Region`, and they are `Send + Sync`. unsafe impl Send for GenericArgImpl<'_> {} unsafe impl Sync for GenericArgImpl<'_> {} @@ -46,6 +56,7 @@ impl<'db> GenericArgImpl<'db> { #[inline] fn new_ty(ty: Ty<'db>) -> Self { Self { + // SAFETY: We create it from an `InternedRef`, and it's never null. ptr: unsafe { NonNull::new_unchecked( ty.interned @@ -62,6 +73,7 @@ impl<'db> GenericArgImpl<'db> { #[inline] fn new_const(ty: Const<'db>) -> Self { Self { + // SAFETY: We create it from an `InternedRef`, and it's never null. ptr: unsafe { NonNull::new_unchecked( ty.interned @@ -78,6 +90,7 @@ impl<'db> GenericArgImpl<'db> { #[inline] fn new_region(ty: Region<'db>) -> Self { Self { + // SAFETY: We create it from an `InternedRef`, and it's never null. ptr: unsafe { NonNull::new_unchecked( ty.interned @@ -94,6 +107,7 @@ impl<'db> GenericArgImpl<'db> { #[inline] fn kind(self) -> GenericArgKind<'db> { let ptr = self.ptr.as_ptr().map_addr(|addr| addr & Self::PTR_MASK); + // SAFETY: We can only be created from a `Ty`, a `Const` or a `Region`, and the tag will match. unsafe { match self.ptr.addr().get() & Self::KIND_MASK { Self::TY_TAG => GenericArgKind::Type(Ty { @@ -113,6 +127,9 @@ impl<'db> GenericArgImpl<'db> { #[inline] fn term_kind(self) -> TermKind<'db> { let ptr = self.ptr.as_ptr().map_addr(|addr| addr & Self::PTR_MASK); + // SAFETY: We can only be created from a `Ty`, a `Const` or a `Region`, and the tag will match. + // It is the caller's responsibility (encapsulated within this module) to only call this with + // `Term`, which cannot be constructed from a `Region`. unsafe { match self.ptr.addr().get() & Self::KIND_MASK { Self::TY_TAG => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index f2dacd16dbf9..6b97d110ee3e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -230,8 +230,10 @@ macro_rules! impl_stored_interned_slice { } } + // SAFETY: It is safe to store this type in queries (but not `$name`). unsafe impl salsa::Update for $stored_name { unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool { + // SAFETY: Comparing by (pointer) equality is safe. unsafe { crate::utils::unsafe_update_eq(old_pointer, new_value) } } } @@ -294,6 +296,8 @@ macro_rules! impl_stored_interned { } pub(crate) use impl_stored_interned; +/// This is a visitor trait that treats any interned thing specifically. Visitables are expected to call +/// the trait's methods when encountering an interned. This is used to implement marking in GC. pub trait WorldExposer { fn on_interned( &mut self, @@ -2613,6 +2617,10 @@ pub unsafe fn collect_ty_garbage() { gc.add_slice_storage::(); gc.add_slice_storage::(); + // SAFETY: + // - By our precondition, there are no unrecorded types. + // - We implement `GcInternedVisit` and `GcInternedSliceVisit` correctly for all types. + // - We added all storages (FIXME: it's too easy to forget to add a new storage here). unsafe { gc.collect() }; } diff --git a/src/tools/rust-analyzer/crates/intern/src/gc.rs b/src/tools/rust-analyzer/crates/intern/src/gc.rs index e559d1dc5710..0d500a9714e4 100644 --- a/src/tools/rust-analyzer/crates/intern/src/gc.rs +++ b/src/tools/rust-analyzer/crates/intern/src/gc.rs @@ -1,7 +1,12 @@ //! Garbage collection of interned values. +//! +//! The GC is a simple mark-and-sweep GC: you first mark all storages, then the +//! GC visits them, and each live value they refer, recursively, then removes +//! those not marked. The sweep phase is done in parallel. -use std::{marker::PhantomData, ops::ControlFlow}; +use std::{hash::Hash, marker::PhantomData, ops::ControlFlow}; +use dashmap::DashMap; use hashbrown::raw::RawTable; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use rustc_hash::{FxBuildHasher, FxHashSet}; @@ -39,15 +44,7 @@ impl Storage for InternedStorage { fn sweep(&self, gc: &GarbageCollector) { let storage = T::storage().get(); - if cfg!(miri) { - storage.shards().iter().for_each(|shard| { - gc.retain_only_alive(&mut *shard.write(), |item| item.0.as_ptr().addr()) - }); - } else { - storage.shards().par_iter().for_each(|shard| { - gc.retain_only_alive(&mut *shard.write(), |item| item.0.as_ptr().addr()) - }); - } + gc.sweep_storage(storage, |item| item.as_ptr().addr()); } } @@ -74,15 +71,7 @@ impl Storage for InternedSliceStorage fn sweep(&self, gc: &GarbageCollector) { let storage = T::storage().get(); - if cfg!(miri) { - storage.shards().iter().for_each(|shard| { - gc.retain_only_alive(&mut *shard.write(), |item| item.0.as_ptr().addr()) - }); - } else { - storage.shards().par_iter().for_each(|shard| { - gc.retain_only_alive(&mut *shard.write(), |item| item.0.as_ptr().addr()) - }); - } + gc.sweep_storage(storage, |item| item.as_ptr().addr()); } } @@ -116,7 +105,10 @@ impl GarbageCollector { /// # Safety /// - /// This cannot be called if there are some not-yet-recorded type values. + /// - This cannot be called if there are some not-yet-recorded type values. + /// - All relevant storages must have been added; that is, within the full graph of values, + /// the added storages must form a DAG. + /// - [`GcInternedVisit`] and [`GcInternedSliceVisit`] must mark all values reachable from the node. pub unsafe fn collect(mut self) { let total_nodes = self.storages.iter().map(|storage| storage.len()).sum(); self.alive = FxHashSet::with_capacity_and_hasher(total_nodes, FxBuildHasher); @@ -127,6 +119,7 @@ impl GarbageCollector { storage.mark(&mut self); } + // Miri doesn't support rayon. if cfg!(miri) { storages.iter().for_each(|storage| storage.sweep(&self)); } else { @@ -158,8 +151,26 @@ impl GarbageCollector { if !self.alive.insert(addr) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } } + fn sweep_storage( + &self, + storage: &DashMap, + get_addr: impl Fn(&T) -> usize + Send + Sync, + ) { + // Miri doesn't support rayon. + if cfg!(miri) { + storage.shards().iter().for_each(|shard| { + self.retain_only_alive(&mut *shard.write(), |item| get_addr(&item.0)) + }); + } else { + storage.shards().par_iter().for_each(|shard| { + self.retain_only_alive(&mut *shard.write(), |item| get_addr(&item.0)) + }); + } + } + #[inline] fn retain_only_alive(&self, map: &mut RawTable, mut get_addr: impl FnMut(&T) -> usize) { + // This code was copied from DashMap's retain() - which we can't use because we want to run in parallel. unsafe { // Here we only use `iter` as a temporary, preventing use-after-free for bucket in map.iter() { @@ -218,7 +229,7 @@ mod tests { fn visit_with(&self, _gc: &mut GarbageCollector) {} } - crate::impl_slice_internable!(gc; StringSlice, String, String); + crate::impl_slice_internable!(gc; StringSlice, String, u32); type InternedSlice = crate::InternedSlice; impl GcInternedSliceVisit for StringSlice { @@ -245,19 +256,13 @@ mod tests { assert_ne!(b.as_ref(), c.as_ref()); assert_eq!(c.as_ref().0, "def"); - let d = InternedSlice::from_header_and_slice( - "abc".to_owned(), - &["def".to_owned(), "123".to_owned()], - ); - let e = InternedSlice::from_header_and_slice( - "abc".to_owned(), - &["def".to_owned(), "123".to_owned()], - ); + let d = InternedSlice::from_header_and_slice("abc".to_owned(), &[123, 456]); + let e = InternedSlice::from_header_and_slice("abc".to_owned(), &[123, 456]); assert_eq!(d, e); assert_eq!(d.to_owned(), e.to_owned()); assert_eq!(d.header.length, 2); assert_eq!(d.header.header, "abc"); - assert_eq!(d.slice, ["def", "123"]); + assert_eq!(d.slice, [123, 456]); (a, d.to_owned()) }; @@ -269,7 +274,7 @@ mod tests { assert_eq!(a.0, "abc"); assert_eq!(d.header.length, 2); assert_eq!(d.header.header, "abc"); - assert_eq!(d.slice, ["def", "123"]); + assert_eq!(d.slice, [123, 456]); drop(a); drop(d); diff --git a/src/tools/rust-analyzer/crates/intern/src/intern.rs b/src/tools/rust-analyzer/crates/intern/src/intern.rs index 5d4d00118512..b7acd6624b99 100644 --- a/src/tools/rust-analyzer/crates/intern/src/intern.rs +++ b/src/tools/rust-analyzer/crates/intern/src/intern.rs @@ -1,8 +1,31 @@ //! Interning of single values. +//! +//! Interning supports two modes: GC and non-GC. +//! +//! In non-GC mode, you create [`Interned`]s, and can create `Copy` handles to them +//! that can still be upgraded back to [`Interned`] ([`InternedRef`]) via [`Interned::as_ref`]. +//! Generally, letting the [`InternedRef`] to outlive the [`Interned`] is a soundness bug and can +//! lead to UB. When all [`Interned`]s of some value are dropped, the value is freed (newer interns +//! may re-create it, not necessarily in the same place). +//! +//! In GC mode, you generally operate on [`InternedRef`]s. They are `Copy` and comfortable. To intern +//! a value you call [`Interned::new_gc`], which returns an [`InternedRef`]. Having all [`Interned`]s +//! of some value be dropped will *not* immediately free the value. Instead, a mark-and-sweep GC can +//! be initiated, which will free all values which have no live [`Interned`]s. +//! +//! Generally, in GC mode, you operate on [`InternedRef`], but when you need to store some long-term +//! value (e.g. a Salsa query output), you convert it to an [`Interned`]. This ensures that an eventual +//! GC will not free it as long as it is alive. +//! +//! Making mistakes is hard due to GC [`InternedRef`] wrappers not implementing `salsa::Update`, meaning +//! Salsa will ensure you do not store them in queries or Salsa-interneds. However it's still *possible* +//! without unsafe code (for example, by storing them in a `static`), which is why triggering GC is unsafe. +//! +//! For more information about GC see [`crate::gc`]. use std::{ fmt::{self, Debug, Display}, - hash::{BuildHasher, BuildHasherDefault, Hash, Hasher}, + hash::{BuildHasher, Hash, Hasher}, ops::Deref, ptr, sync::OnceLock, @@ -10,19 +33,16 @@ use std::{ use dashmap::{DashMap, SharedValue}; use hashbrown::raw::RawTable; -use rustc_hash::FxHasher; +use rustc_hash::FxBuildHasher; use triomphe::{Arc, ArcBorrow}; -type InternMap = DashMap, (), BuildHasherDefault>; +type InternMap = DashMap, (), FxBuildHasher>; type Guard = dashmap::RwLockWriteGuard<'static, RawTable<(Arc, SharedValue<()>)>>; pub struct Interned { arc: Arc, } -unsafe impl Send for Interned {} -unsafe impl Sync for Interned {} - impl Interned { #[inline] pub fn new(obj: T) -> Self { @@ -96,6 +116,7 @@ impl Interned { /// The pointer should originate from an `Interned` or an `InternedRef`. #[inline] pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Our precondition. Self { arc: unsafe { Arc::from_raw(ptr) } } } @@ -209,6 +230,7 @@ impl<'a, T: Internable> InternedRef<'a, T> { /// The pointer needs to originate from `Interned` or `InternedRef`. #[inline] pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Our precondition. Self { arc: unsafe { ArcBorrow::from_ptr(ptr) } } } @@ -228,6 +250,7 @@ impl<'a, T: Internable> InternedRef<'a, T> { /// map also keeps a reference to the value. #[inline] pub unsafe fn decrement_refcount(self) { + // SAFETY: Our precondition. unsafe { drop(Arc::from_raw(self.as_raw())) } } @@ -235,6 +258,17 @@ impl<'a, T: Internable> InternedRef<'a, T> { pub(crate) fn strong_count(self) -> usize { ArcBorrow::strong_count(&self.arc) } + + /// **Available only on GC mode**. + /// + /// Changes the attached lifetime, as in GC mode, the lifetime is more kind of a lint to prevent misuse + /// than actual soundness check. + #[inline] + pub fn change_lifetime<'b>(self) -> InternedRef<'b, T> { + const { assert!(T::USE_GC) }; + // SAFETY: The lifetime on `InternedRef` is essentially advisory only for GCed types. + unsafe { std::mem::transmute::, InternedRef<'b, T>>(self) } + } } impl Clone for InternedRef<'_, T> { diff --git a/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs index 7f2159ee664e..58de6e17bdff 100644 --- a/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs +++ b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs @@ -1,10 +1,16 @@ //! Interning of slices, potentially with a header. +//! +//! See [`crate::intern`] for an explanation of interning modes. Note that slice interning is currently +//! available only in GC mode (there is no other need). +//! +//! [`InternedSlice`] and [`InternedSliceRef`] are essentially [`Interned<(Header, Box<[SliceType]>)>`][crate::Interned] +//! and [`InternedRef`][crate::InternedRef] with the same types, but more optimized. There is only one +//! allocation and the pointer is thin. use std::{ - borrow::Borrow, ffi::c_void, fmt::{self, Debug}, - hash::{BuildHasher, BuildHasherDefault, Hash, Hasher}, + hash::{BuildHasher, Hash, Hasher}, marker::PhantomData, mem::ManuallyDrop, ops::Deref, @@ -14,13 +20,13 @@ use std::{ use dashmap::{DashMap, SharedValue}; use hashbrown::raw::RawTable; -use rustc_hash::FxHasher; +use rustc_hash::FxBuildHasher; use triomphe::{HeaderSlice, HeaderWithLength, ThinArc}; type InternMap = DashMap< ThinArc<::Header, ::SliceType>, (), - BuildHasherDefault, + FxBuildHasher, >; type Guard = dashmap::RwLockWriteGuard< 'static, @@ -40,14 +46,14 @@ pub struct InternedSlice { impl InternedSlice { #[inline] - fn new<'a>( + pub fn from_header_and_slice<'a>( header: T::Header, - slice: impl Borrow<[T::SliceType]> - + IntoIterator, + slice: &[T::SliceType], ) -> InternedSliceRef<'a, T> { const { assert!(T::USE_GC) }; + let storage = T::storage().get(); - let (mut shard, hash) = Self::select(storage, &header, slice.borrow()); + let (mut shard, hash) = Self::select(storage, &header, slice); // Atomically, // - check if `obj` is already in the map // - if so, clone its `Arc` and return it @@ -56,7 +62,7 @@ impl InternedSlice { // insert the same object between us looking it up and inserting it. let bucket = match shard.find_or_find_insert_slot( hash, - |(other, _)| other.header.header == header && other.slice == *slice.borrow(), + |(other, _)| other.header.header == header && other.slice == *slice, |(x, _)| storage.hasher().hash_one(x), ) { Ok(bucket) => bucket, @@ -65,51 +71,21 @@ impl InternedSlice { shard.insert_in_slot( hash, insert_slot, - ( - ThinArc::from_header_and_iter(header, slice.into_iter()), - SharedValue::new(()), - ), + (ThinArc::from_header_and_slice(header, slice), SharedValue::new(())), ) }, }; // SAFETY: We just retrieved/inserted this bucket. + // `NonNull::new_unchecked()` is safe because the pointer originates from a `ThinArc`. unsafe { InternedSliceRef { + // INVARIANT: We create it from a `ThinArc`. ptr: NonNull::new_unchecked(ThinArc::as_ptr(&bucket.as_ref().0).cast_mut()), _marker: PhantomData, } } } - #[inline] - pub fn from_header_and_slice<'a>( - header: T::Header, - slice: &[T::SliceType], - ) -> InternedSliceRef<'a, T> - where - T::SliceType: Clone, - { - return Self::new(header, Iter(slice)); - - struct Iter<'a, T>(&'a [T]); - - impl<'a, T: Clone> IntoIterator for Iter<'a, T> { - type IntoIter = std::iter::Cloned>; - type Item = T; - #[inline] - fn into_iter(self) -> Self::IntoIter { - self.0.iter().cloned() - } - } - - impl Borrow<[T]> for Iter<'_, T> { - #[inline] - fn borrow(&self) -> &[T] { - self.0 - } - } - } - #[inline] fn select( storage: &'static InternMap, @@ -132,51 +108,20 @@ impl InternedSlice { #[inline(always)] fn ptr(&self) -> *const c_void { - unsafe { ptr::from_ref(&self.arc).read().into_raw() } + self.arc.as_ptr() } #[inline] pub fn as_ref(&self) -> InternedSliceRef<'_, T> { InternedSliceRef { + // SAFETY: `self.ptr` comes from a valid `ThinArc`, so non null. + // INVARIANT: We create it from a `ThinArc`. ptr: unsafe { NonNull::new_unchecked(self.ptr().cast_mut()) }, _marker: PhantomData, } } } -impl Drop for InternedSlice { - #[inline] - fn drop(&mut self) { - // When the last `Ref` is dropped, remove the object from the global map. - if !T::USE_GC && ThinArc::strong_count(&self.arc) == 2 { - // Only `self` and the global map point to the object. - - self.drop_slow(); - } - } -} - -impl InternedSlice { - #[cold] - fn drop_slow(&mut self) { - let storage = T::storage().get(); - let (mut shard, hash) = Self::select(storage, &self.arc.header.header, &self.arc.slice); - - if ThinArc::strong_count(&self.arc) != 2 { - // Another thread has interned another copy - return; - } - - shard.remove_entry(hash, |(other, _)| **other == *self.arc); - - // Shrink the backing storage if the shard is less than 50% occupied. - if shard.len() * 2 < shard.capacity() { - let len = shard.len(); - shard.shrink_to(len, |(x, _)| storage.hasher().hash_one(x)); - } - } -} - /// Compares interned `Ref`s using pointer equality. impl PartialEq for InternedSlice { // NOTE: No `?Sized` because `ptr_eq` doesn't work right with trait objects. @@ -225,16 +170,22 @@ where #[repr(transparent)] pub struct InternedSliceRef<'a, T> { + /// # Invariant + /// + /// There is no `ThinArcBorrow` unfortunately, so this is basically a `ManuallyDrop`, + /// except that can't be `Copy`, so we store a raw pointer instead. ptr: NonNull, _marker: PhantomData<&'a T>, } +// SAFETY: This is essentially a `ThinArc`, implemented as a raw pointer because there is no `ThinArcBorrowed`. unsafe impl Send for InternedSliceRef<'_, T> {} unsafe impl Sync for InternedSliceRef<'_, T> {} impl<'a, T: SliceInternable> InternedSliceRef<'a, T> { #[inline(always)] fn arc(self) -> ManuallyDrop> { + // SAFETY: `self.ptr`'s invariant. unsafe { ManuallyDrop::new(ThinArc::from_raw(self.ptr.as_ptr())) } } @@ -245,6 +196,7 @@ impl<'a, T: SliceInternable> InternedSliceRef<'a, T> { #[inline] pub fn get(self) -> &'a Pointee { + // SAFETY: This is a lifetime extension, valid because we live for `'a`. unsafe { &*ptr::from_ref::>(&*self.arc()) } } @@ -266,6 +218,17 @@ impl<'a, T: SliceInternable> InternedSliceRef<'a, T> { pub(crate) fn as_raw(self) -> *const c_void { self.arc().as_ptr() } + + /// **Available only on GC mode**. + /// + /// Changes the attached lifetime, as in GC mode, the lifetime is more kind of a lint to prevent misuse + /// than actual soundness check. + #[inline] + pub fn change_lifetime<'b>(self) -> InternedSliceRef<'b, T> { + const { assert!(T::USE_GC) }; + // SAFETY: The lifetime on `InternedSliceRef` is essentially advisory only for GCed types. + unsafe { std::mem::transmute::, InternedSliceRef<'b, T>>(self) } + } } impl Clone for InternedSliceRef<'_, T> { @@ -336,7 +299,7 @@ impl InternSliceStorage { pub trait SliceInternable: Sized + 'static { const USE_GC: bool; type Header: Eq + Hash + Send + Sync; - type SliceType: Eq + Hash + Send + Sync + 'static; + type SliceType: Eq + Hash + Send + Sync + Copy + 'static; fn storage() -> &'static InternSliceStorage; } From 3566b6775c45169ffc9c5ede434ad0500ba0476e Mon Sep 17 00:00:00 2001 From: delta17920 Date: Mon, 15 Dec 2025 15:28:57 +0000 Subject: [PATCH 1012/3801] Fix macro_metavar_expr_concat behavior with nested repetitions --- compiler/rustc_expand/src/mbe/transcribe.rs | 29 +++++++-------- tests/ui/macros/concat-nested-repetition.rs | 35 +++++++++++++++++++ .../in-repetition.rs | 2 +- .../in-repetition.stderr | 6 ++-- .../metavar-expressions/concat-repetitions.rs | 7 ++-- .../concat-repetitions.stderr | 18 +++++----- 6 files changed, 63 insertions(+), 34 deletions(-) create mode 100644 tests/ui/macros/concat-nested-repetition.rs diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index dddd62a4945a..d53d180a4ab9 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -558,25 +558,20 @@ fn metavar_expr_concat<'tx>( MetaVarExprConcatElem::Ident(elem) => elem.name, MetaVarExprConcatElem::Literal(elem) => *elem, MetaVarExprConcatElem::Var(ident) => { - match matched_from_ident(dcx, *ident, tscx.interp)? { - NamedMatch::MatchedSeq(named_matches) => { - let Some((curr_idx, _)) = tscx.repeats.last() else { - return Err(dcx.struct_span_err(dspan.entire(), "invalid syntax")); - }; - match &named_matches[*curr_idx] { - // FIXME(c410-f3r) Nested repetitions are unimplemented - MatchedSeq(_) => { - return Err(dcx.struct_span_err( - ident.span, - "nested repetitions with `${concat(...)}` metavariable expressions are not yet supported", - )); - } - MatchedSingle(pnr) => extract_symbol_from_pnr(dcx, pnr, ident.span)?, - } - } - NamedMatch::MatchedSingle(pnr) => { + let key = MacroRulesNormalizedIdent::new(*ident); + match lookup_cur_matched(key, tscx.interp, &tscx.repeats) { + Some(NamedMatch::MatchedSingle(pnr)) => { extract_symbol_from_pnr(dcx, pnr, ident.span)? } + Some(NamedMatch::MatchedSeq(..)) => { + return Err(dcx.struct_span_err( + ident.span, + "`${concat(...)}` variable is still repeating at this depth", + )); + } + None => { + return Err(dcx.create_err(MveUnrecognizedVar { span: ident.span, key })); + } } } }; diff --git a/tests/ui/macros/concat-nested-repetition.rs b/tests/ui/macros/concat-nested-repetition.rs new file mode 100644 index 000000000000..ac5394ef8dcc --- /dev/null +++ b/tests/ui/macros/concat-nested-repetition.rs @@ -0,0 +1,35 @@ +//@ check-pass +#![feature(macro_metavar_expr_concat)] + +struct A; +struct B; +const AA: A = A; +const BB: B = B; + +macro_rules! define_ioctl_data { + (struct $s:ident { + $($field:ident: $ty:ident $([$opt:ident])?,)* + }) => { + pub struct $s { + $($field: $ty,)* + } + + impl $s { + $($( + fn ${concat(get_, $field)}(&self) -> $ty { + let _ = $opt; + todo!() + } + )?)* + } + }; +} + +define_ioctl_data! { + struct Foo { + a: A [AA], + b: B [BB], + } +} + +fn main() {} diff --git a/tests/ui/macros/macro-metavar-expr-concat/in-repetition.rs b/tests/ui/macros/macro-metavar-expr-concat/in-repetition.rs index d2bd31b06d60..3ee11d373e05 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/in-repetition.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/in-repetition.rs @@ -11,7 +11,7 @@ macro_rules! InRepetition { ) => { $( $( - ${concat(_, $arg)} //~ ERROR nested repetitions with `${concat(...)}` metavariable expressions are not yet supported + ${concat(_, $arg)} //~ ERROR macro expansion ends with an incomplete expression: expected one of `!` or `::` )* )* }; diff --git a/tests/ui/macros/macro-metavar-expr-concat/in-repetition.stderr b/tests/ui/macros/macro-metavar-expr-concat/in-repetition.stderr index ec39ca799e19..b84d98874931 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/in-repetition.stderr +++ b/tests/ui/macros/macro-metavar-expr-concat/in-repetition.stderr @@ -1,8 +1,8 @@ -error: nested repetitions with `${concat(...)}` metavariable expressions are not yet supported - --> $DIR/in-repetition.rs:14:30 +error: macro expansion ends with an incomplete expression: expected one of `!` or `::` + --> $DIR/in-repetition.rs:14:35 | LL | ${concat(_, $arg)} - | ^^^ + | ^ expected one of `!` or `::` error: aborting due to 1 previous error diff --git a/tests/ui/macros/metavar-expressions/concat-repetitions.rs b/tests/ui/macros/metavar-expressions/concat-repetitions.rs index 52a7d5cd8a7e..133a969b1248 100644 --- a/tests/ui/macros/metavar-expressions/concat-repetitions.rs +++ b/tests/ui/macros/metavar-expressions/concat-repetitions.rs @@ -11,8 +11,7 @@ macro_rules! one_rep { macro_rules! issue_128346 { ( $($a:ident)* ) => { A( - const ${concat($a, Z)}: i32 = 3; - //~^ ERROR invalid syntax + const ${concat($a, Z)}: i32 = 3; //~ ERROR `${concat(...)}` variable is still repeating at this depth )* }; } @@ -20,8 +19,8 @@ macro_rules! issue_128346 { macro_rules! issue_131393 { ($t:ident $($en:ident)?) => { read::<${concat($t, $en)}>() - //~^ ERROR invalid syntax - //~| ERROR invalid syntax + //~^ ERROR `${concat(...)}` variable is still repeating at this depth + //~| ERROR `${concat(...)}` variable is still repeating at this depth } } diff --git a/tests/ui/macros/metavar-expressions/concat-repetitions.stderr b/tests/ui/macros/metavar-expressions/concat-repetitions.stderr index 18b0a90c1c8a..0ef20c65a284 100644 --- a/tests/ui/macros/metavar-expressions/concat-repetitions.stderr +++ b/tests/ui/macros/metavar-expressions/concat-repetitions.stderr @@ -1,20 +1,20 @@ -error: invalid syntax - --> $DIR/concat-repetitions.rs:14:20 +error: `${concat(...)}` variable is still repeating at this depth + --> $DIR/concat-repetitions.rs:14:29 | LL | const ${concat($a, Z)}: i32 = 3; - | ^^^^^^^^^^^^^^^ + | ^ -error: invalid syntax - --> $DIR/concat-repetitions.rs:22:17 +error: `${concat(...)}` variable is still repeating at this depth + --> $DIR/concat-repetitions.rs:21:30 | LL | read::<${concat($t, $en)}>() - | ^^^^^^^^^^^^^^^^^ + | ^^ -error: invalid syntax - --> $DIR/concat-repetitions.rs:22:17 +error: `${concat(...)}` variable is still repeating at this depth + --> $DIR/concat-repetitions.rs:21:30 | LL | read::<${concat($t, $en)}>() - | ^^^^^^^^^^^^^^^^^ + | ^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` From a079cb98cd4dfd2839b45cecd72f5c1a6c3297ab Mon Sep 17 00:00:00 2001 From: jackh726 Date: Wed, 17 Dec 2025 17:27:17 +0000 Subject: [PATCH 1013/3801] Remove Expressions (and just use a Vec) --- compiler/rustc_hir_typeck/src/_match.rs | 13 +- compiler/rustc_hir_typeck/src/coercion.rs | 123 ++++-------------- compiler/rustc_hir_typeck/src/expr.rs | 6 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 6 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 6 +- compiler/rustc_hir_typeck/src/lib.rs | 4 +- 6 files changed, 38 insertions(+), 120 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 6467adb54dab..ded03c88a16e 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -10,7 +10,7 @@ use rustc_trait_selection::traits::{ }; use tracing::{debug, instrument}; -use crate::coercion::{AsCoercionSite, CoerceMany}; +use crate::coercion::CoerceMany; use crate::{Diverges, Expectation, FnCtxt, GatherLocalsVisitor, Needs}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -73,7 +73,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Expectation::ExpectHasType(ety) if ety != tcx.types.unit => ety, _ => self.next_ty_var(expr.span), }; - CoerceMany::with_coercion_sites(coerce_first, arms) + CoerceMany::with_capacity(coerce_first, arms.len()) }; let mut prior_non_diverging_arms = vec![]; // Used only for diagnostics. @@ -269,16 +269,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Handle the fallback arm of a desugared if(-let) like a missing else. /// /// Returns `true` if there was an error forcing the coercion to the `()` type. - pub(super) fn if_fallback_coercion( + pub(super) fn if_fallback_coercion( &self, if_span: Span, cond_expr: &'tcx hir::Expr<'tcx>, then_expr: &'tcx hir::Expr<'tcx>, - coercion: &mut CoerceMany<'tcx, '_, T>, - ) -> bool - where - T: AsCoercionSite, - { + coercion: &mut CoerceMany<'tcx>, + ) -> bool { // If this `if` expr is the parent's function return expr, // the cause of the type coercion is the return type, point at it. (#25228) let hir_id = self.tcx.parent_hir_id(self.tcx.parent_hir_id(then_expr.hir_id)); diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 127965cb4b30..b4a43548dcda 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1165,17 +1165,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// This is really an internal helper. From outside the coercion /// module, you should instantiate a `CoerceMany` instance. - fn try_find_coercion_lub( + fn try_find_coercion_lub( &self, cause: &ObligationCause<'tcx>, - exprs: &[E], + exprs: &[&'tcx hir::Expr<'tcx>], prev_ty: Ty<'tcx>, new: &hir::Expr<'_>, new_ty: Ty<'tcx>, - ) -> RelateResult<'tcx, Ty<'tcx>> - where - E: AsCoercionSite, - { + ) -> RelateResult<'tcx, Ty<'tcx>> { let prev_ty = self.try_structurally_resolve_type(cause.span, prev_ty); let new_ty = self.try_structurally_resolve_type(new.span, new_ty); debug!( @@ -1269,7 +1266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer(sig.safety())), _ => span_bug!(new.span, "should not try to coerce a {new_ty} to a fn pointer"), }; - for expr in exprs.iter().map(|e| e.as_coercion_site()) { + for expr in exprs.iter() { self.apply_adjustments( expr, vec![Adjustment { kind: prev_adjustment.clone(), target: fn_ptr }], @@ -1316,7 +1313,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (adjustments, target) = self.register_infer_ok_obligations(ok); for expr in exprs { - let expr = expr.as_coercion_site(); self.apply_adjustments(expr, adjustments.clone()); } debug!( @@ -1382,41 +1378,23 @@ pub fn can_coerce<'tcx>( /// } /// let final_ty = coerce.complete(fcx); /// ``` -pub(crate) struct CoerceMany<'tcx, 'exprs, E: AsCoercionSite> { +pub(crate) struct CoerceMany<'tcx> { expected_ty: Ty<'tcx>, final_ty: Option>, - expressions: Expressions<'tcx, 'exprs, E>, - pushed: usize, + expressions: Vec<&'tcx hir::Expr<'tcx>>, } -/// The type of a `CoerceMany` that is storing up the expressions into -/// a buffer. We use this in `check/mod.rs` for things like `break`. -pub(crate) type DynamicCoerceMany<'tcx> = CoerceMany<'tcx, 'tcx, &'tcx hir::Expr<'tcx>>; - -enum Expressions<'tcx, 'exprs, E: AsCoercionSite> { - Dynamic(Vec<&'tcx hir::Expr<'tcx>>), - UpFront(&'exprs [E]), -} - -impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { - /// The usual case; collect the set of expressions dynamically. - /// If the full set of coercion sites is known before hand, - /// consider `with_coercion_sites()` instead to avoid allocation. +impl<'tcx> CoerceMany<'tcx> { + /// Creates a `CoerceMany` with a default capacity of 1. If the full set of + /// coercion sites is known before hand, consider `with_capacity()` instead + /// to avoid allocation. pub(crate) fn new(expected_ty: Ty<'tcx>) -> Self { - Self::make(expected_ty, Expressions::Dynamic(vec![])) + Self::with_capacity(expected_ty, 1) } - /// As an optimization, you can create a `CoerceMany` with a - /// preexisting slice of expressions. In this case, you are - /// expected to pass each element in the slice to `coerce(...)` in - /// order. This is used with arrays in particular to avoid - /// needlessly cloning the slice. - pub(crate) fn with_coercion_sites(expected_ty: Ty<'tcx>, coercion_sites: &'exprs [E]) -> Self { - Self::make(expected_ty, Expressions::UpFront(coercion_sites)) - } - - fn make(expected_ty: Ty<'tcx>, expressions: Expressions<'tcx, 'exprs, E>) -> Self { - CoerceMany { expected_ty, final_ty: None, expressions, pushed: 0 } + /// Creates a `CoerceMany` with a given capacity. + pub(crate) fn with_capacity(expected_ty: Ty<'tcx>, capacity: usize) -> Self { + CoerceMany { expected_ty, final_ty: None, expressions: Vec::with_capacity(capacity) } } /// Returns the "expected type" with which this coercion was @@ -1529,7 +1507,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // Handle the actual type unification etc. let result = if let Some(expression) = expression { - if self.pushed == 0 { + if self.expressions.is_empty() { // Special-case the first expression we are coercing. // To be honest, I'm not entirely sure why we do this. // We don't allow two-phase borrows, see comment in try_find_coercion_lub for why @@ -1541,22 +1519,13 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { Some(cause.clone()), ) } else { - match self.expressions { - Expressions::Dynamic(ref exprs) => fcx.try_find_coercion_lub( - cause, - exprs, - self.merged_ty(), - expression, - expression_ty, - ), - Expressions::UpFront(coercion_sites) => fcx.try_find_coercion_lub( - cause, - &coercion_sites[0..self.pushed], - self.merged_ty(), - expression, - expression_ty, - ), - } + fcx.try_find_coercion_lub( + cause, + &self.expressions, + self.merged_ty(), + expression, + expression_ty, + ) } } else { // this is a hack for cases where we default to `()` because @@ -1591,18 +1560,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { Ok(v) => { self.final_ty = Some(v); if let Some(e) = expression { - match self.expressions { - Expressions::Dynamic(ref mut buffer) => buffer.push(e), - Expressions::UpFront(coercion_sites) => { - // if the user gave us an array to validate, check that we got - // the next expression in the list, as expected - assert_eq!( - coercion_sites[self.pushed].as_coercion_site().hir_id, - e.hir_id - ); - } - } - self.pushed += 1; + self.expressions.push(e); } } Err(coercion_error) => { @@ -1955,45 +1913,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } else { // If we only had inputs that were of type `!` (or no // inputs at all), then the final type is `!`. - assert_eq!(self.pushed, 0); + assert!(self.expressions.is_empty()); fcx.tcx.types.never } } } -/// Something that can be converted into an expression to which we can -/// apply a coercion. -pub(crate) trait AsCoercionSite { - fn as_coercion_site(&self) -> &hir::Expr<'_>; -} - -impl AsCoercionSite for hir::Expr<'_> { - fn as_coercion_site(&self) -> &hir::Expr<'_> { - self - } -} - -impl<'a, T> AsCoercionSite for &'a T -where - T: AsCoercionSite, -{ - fn as_coercion_site(&self) -> &hir::Expr<'_> { - (**self).as_coercion_site() - } -} - -impl AsCoercionSite for ! { - fn as_coercion_site(&self) -> &hir::Expr<'_> { - *self - } -} - -impl AsCoercionSite for hir::Arm<'_> { - fn as_coercion_site(&self) -> &hir::Expr<'_> { - self.body - } -} - /// Recursively visit goals to decide whether an unsizing is possible. /// `Break`s when it isn't, and an error should be raised. /// `Continue`s when an unsizing ok based on an implementation of the `Unsize` trait / lang item. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 48082560bb83..c4fa39c6c2c8 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -40,7 +40,7 @@ use tracing::{debug, instrument, trace}; use {rustc_ast as ast, rustc_hir as hir}; use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation}; -use crate::coercion::{CoerceMany, DynamicCoerceMany}; +use crate::coercion::CoerceMany; use crate::errors::{ AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr, BaseExpressionDoubleDotRemove, CantDereference, FieldMultiplySpecifiedInInitializer, @@ -1227,7 +1227,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // (`only_has_type`); otherwise, we just go with a // fresh type variable. let coerce_to_ty = expected.coercion_target_type(self, sp); - let mut coerce: DynamicCoerceMany<'_> = CoerceMany::new(coerce_to_ty); + let mut coerce = CoerceMany::with_capacity(coerce_to_ty, 2); coerce.coerce(self, &self.misc(sp), then_expr, then_ty); @@ -1681,7 +1681,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .to_option(self) .and_then(|uty| self.try_structurally_resolve_type(expr.span, uty).builtin_index()) .unwrap_or_else(|| self.next_ty_var(expr.span)); - let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args); + let mut coerce = CoerceMany::with_capacity(coerce_to, args.len()); for e in args { let e_ty = self.check_expr_with_hint(e, coerce_to); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index d04133ccee97..c07cbfae256d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1033,11 +1033,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // break 'a 22; }` would not force the type of the block // to be `()`). let coerce_to_ty = expected.coercion_target_type(self, blk.span); - let coerce = if blk.targeted_by_break { - CoerceMany::new(coerce_to_ty) - } else { - CoerceMany::with_coercion_sites(coerce_to_ty, blk.expr.as_slice()) - }; + let coerce = CoerceMany::new(coerce_to_ty); let prev_diverges = self.diverges.get(); let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false }; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 998c5e6cd25a..c875e2e50d70 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -25,7 +25,7 @@ use rustc_trait_selection::traits::{ self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, }; -use crate::coercion::DynamicCoerceMany; +use crate::coercion::CoerceMany; use crate::fallback::DivergingFallbackBehavior; use crate::fn_ctxt::checks::DivergingBlockBehavior; use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt}; @@ -56,13 +56,13 @@ pub(crate) struct FnCtxt<'a, 'tcx> { /// expressions. If `None`, this is in a context where return is /// inappropriate, such as a const expression. /// - /// This is a `RefCell`, which means that we + /// This is a `RefCell`, which means that we /// can track all the return expressions and then use them to /// compute a useful coercion from the set, similar to a match /// expression or other branching context. You can use methods /// like `expected_ty` to access the declared return type (if /// any). - pub(super) ret_coercion: Option>>, + pub(super) ret_coercion: Option>>, /// First span of a return site that we find. Used in error messages. pub(super) ret_coercion_span: Cell>, diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 9ca5ddd494ae..6f9e91bca45a 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -62,7 +62,7 @@ use tracing::{debug, instrument}; use typeck_root_ctxt::TypeckRootCtxt; use crate::check::check_fn; -use crate::coercion::DynamicCoerceMany; +use crate::coercion::CoerceMany; use crate::diverges::Diverges; use crate::expectation::Expectation; use crate::fn_ctxt::LoweredTy; @@ -350,7 +350,7 @@ pub struct BreakableCtxt<'tcx> { // this is `null` for loops where break with a value is illegal, // such as `while`, `for`, and `while let` - coerce: Option>, + coerce: Option>, } pub struct EnclosingBreakables<'tcx> { From 558ff51722a7944e37c60ea73525bb9090955f90 Mon Sep 17 00:00:00 2001 From: Coca Date: Thu, 18 Dec 2025 17:13:55 +0000 Subject: [PATCH 1014/3801] `transmuting_null`: Check single expression const blocks and blocks changelog: [`transmuting_null`]: now checks single expression const blocks and blocks --- .../src/transmute/transmuting_null.rs | 20 ++++++++++++++++++- tests/ui/transmuting_null.rs | 11 ++++++++++ tests/ui/transmuting_null.stderr | 14 ++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/transmute/transmuting_null.rs b/clippy_lints/src/transmute/transmuting_null.rs index 31e770f421e1..3f435f255d91 100644 --- a/clippy_lints/src/transmute/transmuting_null.rs +++ b/clippy_lints/src/transmute/transmuting_null.rs @@ -2,7 +2,7 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_integer_const; use clippy_utils::res::{MaybeDef, MaybeResPath}; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::{ConstBlock, Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty::Ty; use rustc_span::symbol::sym; @@ -42,5 +42,23 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t return true; } + // Catching: + // `std::mem::transmute({ 0 as *const u64 })` and similar const blocks + if let ExprKind::Block(block, _) = arg.kind + && block.stmts.is_empty() + && let Some(inner) = block.expr + { + // Run again with the inner expression + return check(cx, expr, inner, to_ty); + } + + // Catching: + // `std::mem::transmute(const { u64::MIN as *const u64 });` + if let ExprKind::ConstBlock(ConstBlock { body, .. }) = arg.kind { + // Strip out the const and run again + let block = cx.tcx.hir_body(body).value; + return check(cx, expr, block, to_ty); + } + false } diff --git a/tests/ui/transmuting_null.rs b/tests/ui/transmuting_null.rs index 0d3b26673452..00aa35dff803 100644 --- a/tests/ui/transmuting_null.rs +++ b/tests/ui/transmuting_null.rs @@ -37,8 +37,19 @@ fn transmute_const_int() { } } +fn transumute_single_expr_blocks() { + unsafe { + let _: &u64 = std::mem::transmute({ 0 as *const u64 }); + //~^ transmuting_null + + let _: &u64 = std::mem::transmute(const { u64::MIN as *const u64 }); + //~^ transmuting_null + } +} + fn main() { one_liners(); transmute_const(); transmute_const_int(); + transumute_single_expr_blocks(); } diff --git a/tests/ui/transmuting_null.stderr b/tests/ui/transmuting_null.stderr index ed7c3396a243..e1de391813bd 100644 --- a/tests/ui/transmuting_null.stderr +++ b/tests/ui/transmuting_null.stderr @@ -25,5 +25,17 @@ error: transmuting a known null pointer into a reference LL | let _: &u64 = std::mem::transmute(u64::MIN as *const u64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: transmuting a known null pointer into a reference + --> tests/ui/transmuting_null.rs:42:23 + | +LL | let _: &u64 = std::mem::transmute({ 0 as *const u64 }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmuting a known null pointer into a reference + --> tests/ui/transmuting_null.rs:45:23 + | +LL | let _: &u64 = std::mem::transmute(const { u64::MIN as *const u64 }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors From f2283e2ef54539e51d47335fc3ab0435f6efd495 Mon Sep 17 00:00:00 2001 From: yanglsh Date: Fri, 19 Sep 2025 23:51:46 +0800 Subject: [PATCH 1015/3801] fix: `map_unwrap_or` fail to cover `Result::unwrap_or` --- clippy_lints/src/methods/map_unwrap_or.rs | 208 ++++++++++++++---- .../src/methods/map_unwrap_or_else.rs | 71 ++++++ clippy_lints/src/methods/mod.rs | 6 +- .../src/methods/option_map_unwrap_or.rs | 180 --------------- clippy_utils/src/msrvs.rs | 2 +- lintcheck/src/input.rs | 3 +- tests/ui/map_unwrap_or_fixable.fixed | 16 ++ tests/ui/map_unwrap_or_fixable.rs | 16 ++ tests/ui/map_unwrap_or_fixable.stderr | 50 ++++- 9 files changed, 325 insertions(+), 227 deletions(-) create mode 100644 clippy_lints/src/methods/map_unwrap_or_else.rs delete mode 100644 clippy_lints/src/methods/option_map_unwrap_or.rs diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs index 8eb26fb50747..b29be88fb520 100644 --- a/clippy_lints/src/methods/map_unwrap_or.rs +++ b/clippy_lints/src/methods/map_unwrap_or.rs @@ -1,71 +1,199 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeDef; -use clippy_utils::source::snippet; -use clippy_utils::usage::mutated_variables; +use clippy_utils::source::snippet_with_applicability; +use clippy_utils::ty::is_copy; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir as hir; +use rustc_hir::def::Res; +use rustc_hir::intravisit::{Visitor, walk_path}; +use rustc_hir::{ExprKind, HirId, Node, PatKind, Path, QPath}; use rustc_lint::LateContext; -use rustc_span::symbol::sym; +use rustc_middle::hir::nested_filter; +use rustc_span::{Span, sym}; +use std::ops::ControlFlow; use super::MAP_UNWRAP_OR; -/// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s -/// -/// Returns true if the lint was emitted +/// lint use of `map().unwrap_or()` for `Option`s and `Result`s +#[expect(clippy::too_many_arguments)] pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, - expr: &'tcx hir::Expr<'_>, - recv: &'tcx hir::Expr<'_>, - map_arg: &'tcx hir::Expr<'_>, - unwrap_arg: &'tcx hir::Expr<'_>, + expr: &rustc_hir::Expr<'_>, + recv: &rustc_hir::Expr<'_>, + map_arg: &'tcx rustc_hir::Expr<'_>, + unwrap_recv: &rustc_hir::Expr<'_>, + unwrap_arg: &'tcx rustc_hir::Expr<'_>, + map_span: Span, msrv: Msrv, ) -> bool { // lint if the caller of `map()` is an `Option` or a `Result`. let is_option = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Option); let is_result = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result); - if is_result && !msrv.meets(cx, msrvs::RESULT_MAP_OR_ELSE) { + if is_result && !msrv.meets(cx, msrvs::RESULT_MAP_OR) { return false; } + // lint if the caller of `map()` is an `Option` if is_option || is_result { - // Don't make a suggestion that may fail to compile due to mutably borrowing - // the same variable twice. - let map_mutated_vars = mutated_variables(recv, cx); - let unwrap_mutated_vars = mutated_variables(unwrap_arg, cx); - if let (Some(map_mutated_vars), Some(unwrap_mutated_vars)) = (map_mutated_vars, unwrap_mutated_vars) { - if map_mutated_vars.intersection(&unwrap_mutated_vars).next().is_some() { + if !is_copy(cx, cx.typeck_results().expr_ty(unwrap_arg)) { + // Replacing `.map().unwrap_or()` with `.map_or(, )` can sometimes lead to + // borrowck errors, see #10579 for one such instance. + // In particular, if `a` causes a move and `f` references that moved binding, then we cannot lint: + // ``` + // let x = vec![1, 2]; + // x.get(0..1).map(|s| s.to_vec()).unwrap_or(x); + // ``` + // This compiles, but changing it to `map_or` will produce a compile error: + // ``` + // let x = vec![1, 2]; + // x.get(0..1).map_or(x, |s| s.to_vec()) + // ^ moving `x` here + // ^^^^^^^^^^^ while it is borrowed here (and later used in the closure) + // ``` + // So, we have to check that `a` is not referenced anywhere (even outside of the `.map` closure!) + // before the call to `unwrap_or`. + + let mut unwrap_visitor = UnwrapVisitor { + cx, + identifiers: FxHashSet::default(), + }; + unwrap_visitor.visit_expr(unwrap_arg); + + let mut reference_visitor = ReferenceVisitor { + cx, + identifiers: unwrap_visitor.identifiers, + unwrap_or_span: unwrap_arg.span, + }; + + let body = cx.tcx.hir_body_owned_by(cx.tcx.hir_enclosing_body_owner(expr.hir_id)); + + // Visit the body, and return if we've found a reference + if reference_visitor.visit_body(body).is_break() { return false; } - } else { + } + + if !unwrap_arg.span.eq_ctxt(map_span) { return false; } + // is_some_and is stabilised && `unwrap_or` argument is false; suggest `is_some_and` instead + let suggest_is_some_and = matches!(&unwrap_arg.kind, ExprKind::Lit(lit) + if matches!(lit.node, rustc_ast::LitKind::Bool(false))) + && msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND); + + let mut applicability = Applicability::MachineApplicable; + // get snippet for unwrap_or() + let unwrap_snippet = snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability); // lint message - let msg = if is_option { - "called `map().unwrap_or_else()` on an `Option` value" + // comparing the snippet from source to raw text ("None") below is safe + // because we already have checked the type. + let unwrap_snippet_none = is_option && unwrap_snippet == "None"; + let arg = if unwrap_snippet_none { + "None" + } else if suggest_is_some_and { + "false" } else { - "called `map().unwrap_or_else()` on a `Result` value" + "" }; - // get snippets for args to map() and unwrap_or_else() - let map_snippet = snippet(cx, map_arg.span, ".."); - let unwrap_snippet = snippet(cx, unwrap_arg.span, ".."); - // lint, with note if both map() and unwrap_or_else() have the same span - if map_arg.span.eq_ctxt(unwrap_arg.span) { - let var_snippet = snippet(cx, recv.span, ".."); - span_lint_and_sugg( - cx, - MAP_UNWRAP_OR, - expr.span, - msg, - "try", - format!("{var_snippet}.map_or_else({unwrap_snippet}, {map_snippet})"), - Applicability::MachineApplicable, - ); - return true; - } + let suggest = if unwrap_snippet_none { + "and_then()" + } else if suggest_is_some_and { + if is_result { + "is_ok_and()" + } else { + "is_some_and()" + } + } else { + "map_or(, )" + }; + let msg = format!( + "called `map().unwrap_or({arg})` on an `{}` value", + if is_option { "Option" } else { "Result" } + ); + + span_lint_and_then(cx, MAP_UNWRAP_OR, expr.span, msg, |diag| { + let map_arg_span = map_arg.span; + + let mut suggestion = vec![ + ( + map_span, + String::from(if unwrap_snippet_none { + "and_then" + } else if suggest_is_some_and { + if is_result { "is_ok_and" } else { "is_some_and" } + } else { + "map_or" + }), + ), + (expr.span.with_lo(unwrap_recv.span.hi()), String::new()), + ]; + + if !unwrap_snippet_none && !suggest_is_some_and { + suggestion.push((map_arg_span.with_hi(map_arg_span.lo()), format!("{unwrap_snippet}, "))); + } + + diag.multipart_suggestion(format!("use `{suggest}` instead"), suggestion, applicability); + }); + + return true; } false } + +struct UnwrapVisitor<'a, 'tcx> { + cx: &'a LateContext<'tcx>, + identifiers: FxHashSet, +} + +impl<'tcx> Visitor<'tcx> for UnwrapVisitor<'_, 'tcx> { + type NestedFilter = nested_filter::All; + + fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) { + if let Res::Local(local_id) = path.res + && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id) + && let PatKind::Binding(_, local_id, ..) = pat.kind + { + self.identifiers.insert(local_id); + } + walk_path(self, path); + } + + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx + } +} + +struct ReferenceVisitor<'a, 'tcx> { + cx: &'a LateContext<'tcx>, + identifiers: FxHashSet, + unwrap_or_span: Span, +} + +impl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> { + type NestedFilter = nested_filter::All; + type Result = ControlFlow<()>; + fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) -> ControlFlow<()> { + // If we haven't found a reference yet, check if this references + // one of the locals that was moved in the `unwrap_or` argument. + // We are only interested in exprs that appear before the `unwrap_or` call. + if expr.span < self.unwrap_or_span + && let ExprKind::Path(ref path) = expr.kind + && let QPath::Resolved(_, path) = path + && let Res::Local(local_id) = path.res + && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id) + && let PatKind::Binding(_, local_id, ..) = pat.kind + && self.identifiers.contains(&local_id) + { + return ControlFlow::Break(()); + } + rustc_hir::intravisit::walk_expr(self, expr) + } + + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + self.cx.tcx + } +} diff --git a/clippy_lints/src/methods/map_unwrap_or_else.rs b/clippy_lints/src/methods/map_unwrap_or_else.rs new file mode 100644 index 000000000000..8eb26fb50747 --- /dev/null +++ b/clippy_lints/src/methods/map_unwrap_or_else.rs @@ -0,0 +1,71 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::res::MaybeDef; +use clippy_utils::source::snippet; +use clippy_utils::usage::mutated_variables; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_span::symbol::sym; + +use super::MAP_UNWRAP_OR; + +/// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s +/// +/// Returns true if the lint was emitted +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, + recv: &'tcx hir::Expr<'_>, + map_arg: &'tcx hir::Expr<'_>, + unwrap_arg: &'tcx hir::Expr<'_>, + msrv: Msrv, +) -> bool { + // lint if the caller of `map()` is an `Option` or a `Result`. + let is_option = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Option); + let is_result = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result); + + if is_result && !msrv.meets(cx, msrvs::RESULT_MAP_OR_ELSE) { + return false; + } + + if is_option || is_result { + // Don't make a suggestion that may fail to compile due to mutably borrowing + // the same variable twice. + let map_mutated_vars = mutated_variables(recv, cx); + let unwrap_mutated_vars = mutated_variables(unwrap_arg, cx); + if let (Some(map_mutated_vars), Some(unwrap_mutated_vars)) = (map_mutated_vars, unwrap_mutated_vars) { + if map_mutated_vars.intersection(&unwrap_mutated_vars).next().is_some() { + return false; + } + } else { + return false; + } + + // lint message + let msg = if is_option { + "called `map().unwrap_or_else()` on an `Option` value" + } else { + "called `map().unwrap_or_else()` on a `Result` value" + }; + // get snippets for args to map() and unwrap_or_else() + let map_snippet = snippet(cx, map_arg.span, ".."); + let unwrap_snippet = snippet(cx, unwrap_arg.span, ".."); + // lint, with note if both map() and unwrap_or_else() have the same span + if map_arg.span.eq_ctxt(unwrap_arg.span) { + let var_snippet = snippet(cx, recv.span, ".."); + span_lint_and_sugg( + cx, + MAP_UNWRAP_OR, + expr.span, + msg, + "try", + format!("{var_snippet}.map_or_else({unwrap_snippet}, {map_snippet})"), + Applicability::MachineApplicable, + ); + return true; + } + } + + false +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 48842c8739c0..163205ea87be 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -74,6 +74,7 @@ mod map_err_ignore; mod map_flatten; mod map_identity; mod map_unwrap_or; +mod map_unwrap_or_else; mod map_with_unused_argument_over_ranges; mod mut_mutex_lock; mod needless_as_bytes; @@ -89,7 +90,6 @@ mod open_options; mod option_as_ref_cloned; mod option_as_ref_deref; mod option_map_or_none; -mod option_map_unwrap_or; mod or_fun_call; mod or_then_unwrap; mod path_buf_push_overwrite; @@ -5607,7 +5607,7 @@ impl Methods { manual_saturating_arithmetic::check_unwrap_or(cx, expr, lhs, rhs, u_arg, arith); }, Some((sym::map, m_recv, [m_arg], span, _)) => { - option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv); + map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv); }, Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => { obfuscated_if_else::check( @@ -5648,7 +5648,7 @@ impl Methods { (sym::unwrap_or_else, [u_arg]) => { match method_call(recv) { Some((sym::map, recv, [map_arg], _, _)) - if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {}, + if map_unwrap_or_else::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {}, Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => { obfuscated_if_else::check( cx, diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs deleted file mode 100644 index 32a9b4fe7c58..000000000000 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ /dev/null @@ -1,180 +0,0 @@ -use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::res::MaybeDef; -use clippy_utils::source::snippet_with_applicability; -use clippy_utils::ty::is_copy; -use rustc_data_structures::fx::FxHashSet; -use rustc_errors::Applicability; -use rustc_hir::def::Res; -use rustc_hir::intravisit::{Visitor, walk_path}; -use rustc_hir::{ExprKind, HirId, Node, PatKind, Path, QPath}; -use rustc_lint::LateContext; -use rustc_middle::hir::nested_filter; -use rustc_span::{Span, sym}; -use std::ops::ControlFlow; - -use super::MAP_UNWRAP_OR; - -/// lint use of `map().unwrap_or()` for `Option`s -#[expect(clippy::too_many_arguments)] -pub(super) fn check<'tcx>( - cx: &LateContext<'tcx>, - expr: &rustc_hir::Expr<'_>, - recv: &rustc_hir::Expr<'_>, - map_arg: &'tcx rustc_hir::Expr<'_>, - unwrap_recv: &rustc_hir::Expr<'_>, - unwrap_arg: &'tcx rustc_hir::Expr<'_>, - map_span: Span, - msrv: Msrv, -) { - // lint if the caller of `map()` is an `Option` - if cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Option) { - if !is_copy(cx, cx.typeck_results().expr_ty(unwrap_arg)) { - // Replacing `.map().unwrap_or()` with `.map_or(, )` can sometimes lead to - // borrowck errors, see #10579 for one such instance. - // In particular, if `a` causes a move and `f` references that moved binding, then we cannot lint: - // ``` - // let x = vec![1, 2]; - // x.get(0..1).map(|s| s.to_vec()).unwrap_or(x); - // ``` - // This compiles, but changing it to `map_or` will produce a compile error: - // ``` - // let x = vec![1, 2]; - // x.get(0..1).map_or(x, |s| s.to_vec()) - // ^ moving `x` here - // ^^^^^^^^^^^ while it is borrowed here (and later used in the closure) - // ``` - // So, we have to check that `a` is not referenced anywhere (even outside of the `.map` closure!) - // before the call to `unwrap_or`. - - let mut unwrap_visitor = UnwrapVisitor { - cx, - identifiers: FxHashSet::default(), - }; - unwrap_visitor.visit_expr(unwrap_arg); - - let mut reference_visitor = ReferenceVisitor { - cx, - identifiers: unwrap_visitor.identifiers, - unwrap_or_span: unwrap_arg.span, - }; - - let body = cx.tcx.hir_body_owned_by(cx.tcx.hir_enclosing_body_owner(expr.hir_id)); - - // Visit the body, and return if we've found a reference - if reference_visitor.visit_body(body).is_break() { - return; - } - } - - if !unwrap_arg.span.eq_ctxt(map_span) { - return; - } - - // is_some_and is stabilised && `unwrap_or` argument is false; suggest `is_some_and` instead - let suggest_is_some_and = matches!(&unwrap_arg.kind, ExprKind::Lit(lit) - if matches!(lit.node, rustc_ast::LitKind::Bool(false))) - && msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND); - - let mut applicability = Applicability::MachineApplicable; - // get snippet for unwrap_or() - let unwrap_snippet = snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability); - // lint message - // comparing the snippet from source to raw text ("None") below is safe - // because we already have checked the type. - let arg = if unwrap_snippet == "None" { - "None" - } else if suggest_is_some_and { - "false" - } else { - "" - }; - let unwrap_snippet_none = unwrap_snippet == "None"; - let suggest = if unwrap_snippet_none { - "and_then()" - } else if suggest_is_some_and { - "is_some_and()" - } else { - "map_or(, )" - }; - let msg = format!("called `map().unwrap_or({arg})` on an `Option` value"); - - span_lint_and_then(cx, MAP_UNWRAP_OR, expr.span, msg, |diag| { - let map_arg_span = map_arg.span; - - let mut suggestion = vec![ - ( - map_span, - String::from(if unwrap_snippet_none { - "and_then" - } else if suggest_is_some_and { - "is_some_and" - } else { - "map_or" - }), - ), - (expr.span.with_lo(unwrap_recv.span.hi()), String::new()), - ]; - - if !unwrap_snippet_none && !suggest_is_some_and { - suggestion.push((map_arg_span.with_hi(map_arg_span.lo()), format!("{unwrap_snippet}, "))); - } - - diag.multipart_suggestion(format!("use `{suggest}` instead"), suggestion, applicability); - }); - } -} - -struct UnwrapVisitor<'a, 'tcx> { - cx: &'a LateContext<'tcx>, - identifiers: FxHashSet, -} - -impl<'tcx> Visitor<'tcx> for UnwrapVisitor<'_, 'tcx> { - type NestedFilter = nested_filter::All; - - fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) { - if let Res::Local(local_id) = path.res - && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id) - && let PatKind::Binding(_, local_id, ..) = pat.kind - { - self.identifiers.insert(local_id); - } - walk_path(self, path); - } - - fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { - self.cx.tcx - } -} - -struct ReferenceVisitor<'a, 'tcx> { - cx: &'a LateContext<'tcx>, - identifiers: FxHashSet, - unwrap_or_span: Span, -} - -impl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> { - type NestedFilter = nested_filter::All; - type Result = ControlFlow<()>; - fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) -> ControlFlow<()> { - // If we haven't found a reference yet, check if this references - // one of the locals that was moved in the `unwrap_or` argument. - // We are only interested in exprs that appear before the `unwrap_or` call. - if expr.span < self.unwrap_or_span - && let ExprKind::Path(ref path) = expr.kind - && let QPath::Resolved(_, path) = path - && let Res::Local(local_id) = path.res - && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id) - && let PatKind::Binding(_, local_id, ..) = pat.kind - && self.identifiers.contains(&local_id) - { - return ControlFlow::Break(()); - } - rustc_hir::intravisit::walk_expr(self, expr) - } - - fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { - self.cx.tcx - } -} diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 4a7fa3472cae..144ed3dec7d0 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -61,7 +61,7 @@ msrv_aliases! { 1,45,0 { STR_STRIP_PREFIX } 1,43,0 { LOG2_10, LOG10_2, NUMERIC_ASSOCIATED_CONSTANTS } 1,42,0 { MATCHES_MACRO, SLICE_PATTERNS, PTR_SLICE_RAW_PARTS } - 1,41,0 { RE_REBALANCING_COHERENCE, RESULT_MAP_OR_ELSE } + 1,41,0 { RE_REBALANCING_COHERENCE, RESULT_MAP_OR, RESULT_MAP_OR_ELSE } 1,40,0 { MEM_TAKE, NON_EXHAUSTIVE, OPTION_AS_DEREF } 1,38,0 { POINTER_CAST, REM_EUCLID } 1,37,0 { TYPE_ALIAS_ENUM_VARIANTS } diff --git a/lintcheck/src/input.rs b/lintcheck/src/input.rs index 7dda2b7b25f8..ee3fcaa0a84a 100644 --- a/lintcheck/src/input.rs +++ b/lintcheck/src/input.rs @@ -281,8 +281,7 @@ impl CrateWithSource { CrateSource::Path { path } => { fn is_cache_dir(entry: &DirEntry) -> bool { fs::read(entry.path().join("CACHEDIR.TAG")) - .map(|x| x.starts_with(b"Signature: 8a477f597d28d172789f06886806bc55")) - .unwrap_or(false) + .is_ok_and(|x| x.starts_with(b"Signature: 8a477f597d28d172789f06886806bc55")) } // copy path into the dest_crate_root but skip directories that contain a CACHEDIR.TAG file. diff --git a/tests/ui/map_unwrap_or_fixable.fixed b/tests/ui/map_unwrap_or_fixable.fixed index 90f3cf8bab04..a7a2f0693210 100644 --- a/tests/ui/map_unwrap_or_fixable.fixed +++ b/tests/ui/map_unwrap_or_fixable.fixed @@ -51,3 +51,19 @@ fn main() { option_methods(); result_methods(); } + +fn issue15714() { + let o: Option = Some(3); + let r: Result = Ok(3); + println!("{}", o.map_or(3, |y| y + 1)); + //~^ map_unwrap_or + println!("{}", o.map_or_else(|| 3, |y| y + 1)); + //~^ map_unwrap_or + println!("{}", r.map_or(3, |y| y + 1)); + //~^ map_unwrap_or + println!("{}", r.map_or_else(|()| 3, |y| y + 1)); + //~^ map_unwrap_or + + println!("{}", r.is_ok_and(|y| y == 1)); + //~^ map_unwrap_or +} diff --git a/tests/ui/map_unwrap_or_fixable.rs b/tests/ui/map_unwrap_or_fixable.rs index 1078c7a3cf34..f12f058c1c4b 100644 --- a/tests/ui/map_unwrap_or_fixable.rs +++ b/tests/ui/map_unwrap_or_fixable.rs @@ -57,3 +57,19 @@ fn main() { option_methods(); result_methods(); } + +fn issue15714() { + let o: Option = Some(3); + let r: Result = Ok(3); + println!("{}", o.map(|y| y + 1).unwrap_or(3)); + //~^ map_unwrap_or + println!("{}", o.map(|y| y + 1).unwrap_or_else(|| 3)); + //~^ map_unwrap_or + println!("{}", r.map(|y| y + 1).unwrap_or(3)); + //~^ map_unwrap_or + println!("{}", r.map(|y| y + 1).unwrap_or_else(|()| 3)); + //~^ map_unwrap_or + + println!("{}", r.map(|y| y == 1).unwrap_or(false)); + //~^ map_unwrap_or +} diff --git a/tests/ui/map_unwrap_or_fixable.stderr b/tests/ui/map_unwrap_or_fixable.stderr index 99e660f8dbd1..083a2510bdf2 100644 --- a/tests/ui/map_unwrap_or_fixable.stderr +++ b/tests/ui/map_unwrap_or_fixable.stderr @@ -19,5 +19,53 @@ LL | let _ = res.map(|x| x + 1) LL | | .unwrap_or_else(|_e| 0); | |_______________________________^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)` -error: aborting due to 2 previous errors +error: called `map().unwrap_or()` on an `Option` value + --> tests/ui/map_unwrap_or_fixable.rs:64:20 + | +LL | println!("{}", o.map(|y| y + 1).unwrap_or(3)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `map_or(, )` instead + | +LL - println!("{}", o.map(|y| y + 1).unwrap_or(3)); +LL + println!("{}", o.map_or(3, |y| y + 1)); + | + +error: called `map().unwrap_or_else()` on an `Option` value + --> tests/ui/map_unwrap_or_fixable.rs:66:20 + | +LL | println!("{}", o.map(|y| y + 1).unwrap_or_else(|| 3)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `o.map_or_else(|| 3, |y| y + 1)` + +error: called `map().unwrap_or()` on an `Result` value + --> tests/ui/map_unwrap_or_fixable.rs:68:20 + | +LL | println!("{}", r.map(|y| y + 1).unwrap_or(3)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `map_or(, )` instead + | +LL - println!("{}", r.map(|y| y + 1).unwrap_or(3)); +LL + println!("{}", r.map_or(3, |y| y + 1)); + | + +error: called `map().unwrap_or_else()` on a `Result` value + --> tests/ui/map_unwrap_or_fixable.rs:70:20 + | +LL | println!("{}", r.map(|y| y + 1).unwrap_or_else(|()| 3)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `r.map_or_else(|()| 3, |y| y + 1)` + +error: called `map().unwrap_or(false)` on an `Result` value + --> tests/ui/map_unwrap_or_fixable.rs:73:20 + | +LL | println!("{}", r.map(|y| y == 1).unwrap_or(false)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `is_ok_and()` instead + | +LL - println!("{}", r.map(|y| y == 1).unwrap_or(false)); +LL + println!("{}", r.is_ok_and(|y| y == 1)); + | + +error: aborting due to 7 previous errors From 9565b28598976f62305ea3fb9a877b2628bb1c14 Mon Sep 17 00:00:00 2001 From: yanglsh Date: Wed, 24 Sep 2025 00:04:49 +0800 Subject: [PATCH 1016/3801] fix: `map_unwrap_or` FN on references --- clippy_lints/src/methods/map_unwrap_or.rs | 18 +++---- .../src/methods/map_unwrap_or_else.rs | 6 +-- tests/ui/map_unwrap_or_fixable.fixed | 19 +++++++ tests/ui/map_unwrap_or_fixable.rs | 19 +++++++ tests/ui/map_unwrap_or_fixable.stderr | 52 ++++++++++++++++--- 5 files changed, 92 insertions(+), 22 deletions(-) diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs index b29be88fb520..f2e3cc5c0091 100644 --- a/clippy_lints/src/methods/map_unwrap_or.rs +++ b/clippy_lints/src/methods/map_unwrap_or.rs @@ -26,13 +26,13 @@ pub(super) fn check<'tcx>( unwrap_arg: &'tcx rustc_hir::Expr<'_>, map_span: Span, msrv: Msrv, -) -> bool { - // lint if the caller of `map()` is an `Option` or a `Result`. - let is_option = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Option); - let is_result = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result); +) { + let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs(); + let is_option = recv_ty.is_diag_item(cx, sym::Option); + let is_result = recv_ty.is_diag_item(cx, sym::Result); if is_result && !msrv.meets(cx, msrvs::RESULT_MAP_OR) { - return false; + return; } // lint if the caller of `map()` is an `Option` @@ -71,12 +71,12 @@ pub(super) fn check<'tcx>( // Visit the body, and return if we've found a reference if reference_visitor.visit_body(body).is_break() { - return false; + return; } } if !unwrap_arg.span.eq_ctxt(map_span) { - return false; + return; } // is_some_and is stabilised && `unwrap_or` argument is false; suggest `is_some_and` instead @@ -137,11 +137,7 @@ pub(super) fn check<'tcx>( diag.multipart_suggestion(format!("use `{suggest}` instead"), suggestion, applicability); }); - - return true; } - - false } struct UnwrapVisitor<'a, 'tcx> { diff --git a/clippy_lints/src/methods/map_unwrap_or_else.rs b/clippy_lints/src/methods/map_unwrap_or_else.rs index 8eb26fb50747..a2f157c0cb8a 100644 --- a/clippy_lints/src/methods/map_unwrap_or_else.rs +++ b/clippy_lints/src/methods/map_unwrap_or_else.rs @@ -21,9 +21,9 @@ pub(super) fn check<'tcx>( unwrap_arg: &'tcx hir::Expr<'_>, msrv: Msrv, ) -> bool { - // lint if the caller of `map()` is an `Option` or a `Result`. - let is_option = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Option); - let is_result = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result); + let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs(); + let is_option = recv_ty.is_diag_item(cx, sym::Option); + let is_result = recv_ty.is_diag_item(cx, sym::Result); if is_result && !msrv.meets(cx, msrvs::RESULT_MAP_OR_ELSE) { return false; diff --git a/tests/ui/map_unwrap_or_fixable.fixed b/tests/ui/map_unwrap_or_fixable.fixed index a7a2f0693210..1789c7f4d487 100644 --- a/tests/ui/map_unwrap_or_fixable.fixed +++ b/tests/ui/map_unwrap_or_fixable.fixed @@ -1,6 +1,7 @@ //@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] +#![allow(clippy::unnecessary_lazy_evaluations)] #[macro_use] extern crate option_helpers; @@ -67,3 +68,21 @@ fn issue15714() { println!("{}", r.is_ok_and(|y| y == 1)); //~^ map_unwrap_or } + +fn issue15713() { + let x = &Some(3); + println!("{}", x.map_or(3, |y| y + 1)); + //~^ map_unwrap_or + + let x: &Result = &Ok(3); + println!("{}", x.map_or(3, |y| y + 1)); + //~^ map_unwrap_or + + let x = &Some(3); + println!("{}", x.map_or_else(|| 3, |y| y + 1)); + //~^ map_unwrap_or + + let x: &Result = &Ok(3); + println!("{}", x.map_or_else(|_| 3, |y| y + 1)); + //~^ map_unwrap_or +} diff --git a/tests/ui/map_unwrap_or_fixable.rs b/tests/ui/map_unwrap_or_fixable.rs index f12f058c1c4b..309067edce4d 100644 --- a/tests/ui/map_unwrap_or_fixable.rs +++ b/tests/ui/map_unwrap_or_fixable.rs @@ -1,6 +1,7 @@ //@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] +#![allow(clippy::unnecessary_lazy_evaluations)] #[macro_use] extern crate option_helpers; @@ -73,3 +74,21 @@ fn issue15714() { println!("{}", r.map(|y| y == 1).unwrap_or(false)); //~^ map_unwrap_or } + +fn issue15713() { + let x = &Some(3); + println!("{}", x.map(|y| y + 1).unwrap_or(3)); + //~^ map_unwrap_or + + let x: &Result = &Ok(3); + println!("{}", x.map(|y| y + 1).unwrap_or(3)); + //~^ map_unwrap_or + + let x = &Some(3); + println!("{}", x.map(|y| y + 1).unwrap_or_else(|| 3)); + //~^ map_unwrap_or + + let x: &Result = &Ok(3); + println!("{}", x.map(|y| y + 1).unwrap_or_else(|_| 3)); + //~^ map_unwrap_or +} diff --git a/tests/ui/map_unwrap_or_fixable.stderr b/tests/ui/map_unwrap_or_fixable.stderr index 083a2510bdf2..696f516ee055 100644 --- a/tests/ui/map_unwrap_or_fixable.stderr +++ b/tests/ui/map_unwrap_or_fixable.stderr @@ -1,5 +1,5 @@ error: called `map().unwrap_or_else()` on an `Option` value - --> tests/ui/map_unwrap_or_fixable.rs:16:13 + --> tests/ui/map_unwrap_or_fixable.rs:17:13 | LL | let _ = opt.map(|x| x + 1) | _____________^ @@ -11,7 +11,7 @@ LL | | .unwrap_or_else(|| 0); = help: to override `-D warnings` add `#[allow(clippy::map_unwrap_or)]` error: called `map().unwrap_or_else()` on a `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:47:13 + --> tests/ui/map_unwrap_or_fixable.rs:48:13 | LL | let _ = res.map(|x| x + 1) | _____________^ @@ -20,7 +20,7 @@ LL | | .unwrap_or_else(|_e| 0); | |_______________________________^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)` error: called `map().unwrap_or()` on an `Option` value - --> tests/ui/map_unwrap_or_fixable.rs:64:20 + --> tests/ui/map_unwrap_or_fixable.rs:65:20 | LL | println!("{}", o.map(|y| y + 1).unwrap_or(3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,13 +32,13 @@ LL + println!("{}", o.map_or(3, |y| y + 1)); | error: called `map().unwrap_or_else()` on an `Option` value - --> tests/ui/map_unwrap_or_fixable.rs:66:20 + --> tests/ui/map_unwrap_or_fixable.rs:67:20 | LL | println!("{}", o.map(|y| y + 1).unwrap_or_else(|| 3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `o.map_or_else(|| 3, |y| y + 1)` error: called `map().unwrap_or()` on an `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:68:20 + --> tests/ui/map_unwrap_or_fixable.rs:69:20 | LL | println!("{}", r.map(|y| y + 1).unwrap_or(3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,13 +50,13 @@ LL + println!("{}", r.map_or(3, |y| y + 1)); | error: called `map().unwrap_or_else()` on a `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:70:20 + --> tests/ui/map_unwrap_or_fixable.rs:71:20 | LL | println!("{}", r.map(|y| y + 1).unwrap_or_else(|()| 3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `r.map_or_else(|()| 3, |y| y + 1)` error: called `map().unwrap_or(false)` on an `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:73:20 + --> tests/ui/map_unwrap_or_fixable.rs:74:20 | LL | println!("{}", r.map(|y| y == 1).unwrap_or(false)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,5 +67,41 @@ LL - println!("{}", r.map(|y| y == 1).unwrap_or(false)); LL + println!("{}", r.is_ok_and(|y| y == 1)); | -error: aborting due to 7 previous errors +error: called `map().unwrap_or()` on an `Option` value + --> tests/ui/map_unwrap_or_fixable.rs:80:20 + | +LL | println!("{}", x.map(|y| y + 1).unwrap_or(3)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `map_or(, )` instead + | +LL - println!("{}", x.map(|y| y + 1).unwrap_or(3)); +LL + println!("{}", x.map_or(3, |y| y + 1)); + | + +error: called `map().unwrap_or()` on an `Result` value + --> tests/ui/map_unwrap_or_fixable.rs:84:20 + | +LL | println!("{}", x.map(|y| y + 1).unwrap_or(3)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `map_or(, )` instead + | +LL - println!("{}", x.map(|y| y + 1).unwrap_or(3)); +LL + println!("{}", x.map_or(3, |y| y + 1)); + | + +error: called `map().unwrap_or_else()` on an `Option` value + --> tests/ui/map_unwrap_or_fixable.rs:88:20 + | +LL | println!("{}", x.map(|y| y + 1).unwrap_or_else(|| 3)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map_or_else(|| 3, |y| y + 1)` + +error: called `map().unwrap_or_else()` on a `Result` value + --> tests/ui/map_unwrap_or_fixable.rs:92:20 + | +LL | println!("{}", x.map(|y| y + 1).unwrap_or_else(|_| 3)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map_or_else(|_| 3, |y| y + 1)` + +error: aborting due to 11 previous errors From 0acc8463874c665c42d5659ef10e44b58e74cb68 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 18 Dec 2025 21:18:05 +0100 Subject: [PATCH 1017/3801] Normalize away the maybe remapped paths to the compiler and std --- tests/ui/extern/extern-types-field-offset.rs | 1 + tests/ui/hygiene/panic-location.rs | 1 + tests/ui/mir/lint/storage-live.rs | 1 + tests/ui/mir/lint/storage-live.stderr | 4 ++-- tests/ui/panics/panic-in-cleanup.rs | 1 + tests/ui/panics/panic-in-cleanup.run.stderr | 4 ++-- tests/ui/panics/panic-in-ffi.rs | 1 + tests/ui/panics/panic-in-ffi.run.stderr | 2 +- tests/ui/process/println-with-broken-pipe.rs | 1 + .../ui/resolve/multiple_definitions_attribute_merging.rs | 1 + .../resolve/multiple_definitions_attribute_merging.stderr | 8 ++++---- tests/ui/resolve/proc_macro_generated_packed.rs | 1 + tests/ui/resolve/proc_macro_generated_packed.stderr | 6 +++--- tests/ui/track-diagnostics/track.rs | 1 + tests/ui/track-diagnostics/track2.rs | 1 + tests/ui/track-diagnostics/track3.rs | 1 + tests/ui/track-diagnostics/track4.rs | 1 + tests/ui/track-diagnostics/track5.rs | 1 + tests/ui/track-diagnostics/track6.rs | 4 ++-- .../bad_const_generics_args_on_const_param.rs | 1 + .../bad_const_generics_args_on_const_param.stderr | 4 ++-- 21 files changed, 30 insertions(+), 16 deletions(-) diff --git a/tests/ui/extern/extern-types-field-offset.rs b/tests/ui/extern/extern-types-field-offset.rs index 470ae07a0b55..9fe1cdf3bc47 100644 --- a/tests/ui/extern/extern-types-field-offset.rs +++ b/tests/ui/extern/extern-types-field-offset.rs @@ -2,6 +2,7 @@ //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 //@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ ignore-backends: gcc #![feature(extern_types)] diff --git a/tests/ui/hygiene/panic-location.rs b/tests/ui/hygiene/panic-location.rs index 4731d8e1d538..27850f3e4c3a 100644 --- a/tests/ui/hygiene/panic-location.rs +++ b/tests/ui/hygiene/panic-location.rs @@ -2,6 +2,7 @@ //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" // // Regression test for issue #70963 // The reported panic location should not be `<::core::macros::panic macros>`. diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs index 32bd32754ddd..047ceaaf82c6 100644 --- a/tests/ui/mir/lint/storage-live.rs +++ b/tests/ui/mir/lint/storage-live.rs @@ -4,6 +4,7 @@ //@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" //@ normalize-stderr: "storage_live\[....\]" -> "storage_live[HASH]" //@ normalize-stderr: "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - " +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![feature(custom_mir, core_intrinsics)] diff --git a/tests/ui/mir/lint/storage-live.stderr b/tests/ui/mir/lint/storage-live.stderr index 50df9ae061fc..ef0d253b15a8 100644 --- a/tests/ui/mir/lint/storage-live.stderr +++ b/tests/ui/mir/lint/storage-live.stderr @@ -1,12 +1,12 @@ error: internal compiler error: broken MIR in Item(DefId(0:8 ~ storage_live[HASH]::multiple_storage)) (after pass CheckForceInline) at bb0[1]: StorageLive(_1) which already has storage here - --> $DIR/storage-live.rs:21:13 + --> $DIR/storage-live.rs:22:13 | LL | StorageLive(a); | ^^^^^^^^^^^^^^ | note: delayed at compiler/rustc_mir_transform/src/lint.rs:LL:CC - disabled backtrace - --> $DIR/storage-live.rs:21:13 + --> $DIR/storage-live.rs:22:13 | LL | StorageLive(a); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/panics/panic-in-cleanup.rs b/tests/ui/panics/panic-in-cleanup.rs index 2e307de43939..23430d1f496e 100644 --- a/tests/ui/panics/panic-in-cleanup.rs +++ b/tests/ui/panics/panic-in-cleanup.rs @@ -5,6 +5,7 @@ //@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" //@ normalize-stderr: "\n +at [^\n]+" -> "" //@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ needs-unwind //@ ignore-emscripten "RuntimeError" junk in output //@ ignore-msvc SEH doesn't do panic-during-cleanup the same way as everyone else diff --git a/tests/ui/panics/panic-in-cleanup.run.stderr b/tests/ui/panics/panic-in-cleanup.run.stderr index bfe3dc8c9d73..b6b396d8617d 100644 --- a/tests/ui/panics/panic-in-cleanup.run.stderr +++ b/tests/ui/panics/panic-in-cleanup.run.stderr @@ -1,9 +1,9 @@ -thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:22:5: +thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:23:5: explicit panic note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:16:9: +thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:17:9: BOOM stack backtrace: diff --git a/tests/ui/panics/panic-in-ffi.rs b/tests/ui/panics/panic-in-ffi.rs index b926d0fa7761..ef40a3b6f7d6 100644 --- a/tests/ui/panics/panic-in-ffi.rs +++ b/tests/ui/panics/panic-in-ffi.rs @@ -6,6 +6,7 @@ //@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" //@ normalize-stderr: "\n +at [^\n]+" -> "" //@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ needs-unwind //@ ignore-emscripten "RuntimeError" junk in output diff --git a/tests/ui/panics/panic-in-ffi.run.stderr b/tests/ui/panics/panic-in-ffi.run.stderr index ce907d64358f..49eb92ef7c91 100644 --- a/tests/ui/panics/panic-in-ffi.run.stderr +++ b/tests/ui/panics/panic-in-ffi.run.stderr @@ -1,5 +1,5 @@ -thread 'main' ($TID) panicked at $DIR/panic-in-ffi.rs:21:5: +thread 'main' ($TID) panicked at $DIR/panic-in-ffi.rs:22:5: Test note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace Noisy Drop diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs index e87e20773702..51521f1dcf42 100644 --- a/tests/ui/process/println-with-broken-pipe.rs +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -11,6 +11,7 @@ //@ ignore-visionos no 'head' //@ ignore-backends: gcc //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ compile-flags: -Zon-broken-pipe=error // Test what the error message looks like when `println!()` panics because of diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.rs b/tests/ui/resolve/multiple_definitions_attribute_merging.rs index 519b989fbe87..9f1bff51a3d4 100644 --- a/tests/ui/resolve/multiple_definitions_attribute_merging.rs +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.rs @@ -7,6 +7,7 @@ //@ normalize-stderr: "note: .*\n\n" -> "" //@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" //@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ rustc-env:RUST_BACKTRACE=0 #[repr(packed)] diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr index 10ce68e506e6..b8b33e3417bf 100644 --- a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `Dealigned` is defined multiple times - --> $DIR/multiple_definitions_attribute_merging.rs:17:1 + --> $DIR/multiple_definitions_attribute_merging.rs:18:1 | LL | struct Dealigned(u8, T); | --------------------------- previous definition of the type `Dealigned` here @@ -8,7 +8,7 @@ LL | struct Dealigned(u8, T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Dealigned` redefined here | = error: internal compiler error: compiler/rustc_mir_transform/src/check_packed_ref.rs:LL:CC: builtin derive created an unaligned reference - --> $DIR/multiple_definitions_attribute_merging.rs:17:25 + --> $DIR/multiple_definitions_attribute_merging.rs:18:25 | LL | #[derive(PartialEq)] | --------- in this derive macro expansion @@ -19,8 +19,8 @@ LL | struct Dealigned(u8, T); Box query stack during panic: -#0 [mir_built] building MIR for `::eq` -#1 [check_unsafety] unsafety-checking `::eq` +#0 [mir_built] building MIR for `::eq` +#1 [check_unsafety] unsafety-checking `::eq` ... and 1 other queries... use `env RUST_BACKTRACE=1` to see the full query stack error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/proc_macro_generated_packed.rs b/tests/ui/resolve/proc_macro_generated_packed.rs index 41236c732bbd..a8175895af04 100644 --- a/tests/ui/resolve/proc_macro_generated_packed.rs +++ b/tests/ui/resolve/proc_macro_generated_packed.rs @@ -7,6 +7,7 @@ //@ normalize-stderr: "note: .*\n\n" -> "" //@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" //@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ rustc-env:RUST_BACKTRACE=0 extern crate proc_macro_generate_packed; diff --git a/tests/ui/resolve/proc_macro_generated_packed.stderr b/tests/ui/resolve/proc_macro_generated_packed.stderr index 47de5be82ddf..d8e160d0c6a0 100644 --- a/tests/ui/resolve/proc_macro_generated_packed.stderr +++ b/tests/ui/resolve/proc_macro_generated_packed.stderr @@ -1,5 +1,5 @@ error: internal compiler error: compiler/rustc_mir_transform/src/check_packed_ref.rs:LL:CC: builtin derive created an unaligned reference - --> $DIR/proc_macro_generated_packed.rs:18:25 + --> $DIR/proc_macro_generated_packed.rs:19:25 | LL | #[derive(PartialEq)] | --------- in this derive macro expansion @@ -10,8 +10,8 @@ LL | struct Dealigned(u8, T); Box query stack during panic: -#0 [mir_built] building MIR for `::eq` -#1 [check_unsafety] unsafety-checking `::eq` +#0 [mir_built] building MIR for `::eq` +#1 [check_unsafety] unsafety-checking `::eq` ... and 1 other queries... use `env RUST_BACKTRACE=1` to see the full query stack error: aborting due to 1 previous error diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs index 2d6d6170fe0b..09864a6e3090 100644 --- a/tests/ui/track-diagnostics/track.rs +++ b/tests/ui/track-diagnostics/track.rs @@ -7,6 +7,7 @@ // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" //@ normalize-stderr: "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" // The test becomes too flaky if we care about exact args. If `-Z ui-testing` // from compiletest and `-Z track-diagnostics` from `// compile-flags` at the diff --git a/tests/ui/track-diagnostics/track2.rs b/tests/ui/track-diagnostics/track2.rs index 591b84f330b7..145b2a3e5d57 100644 --- a/tests/ui/track-diagnostics/track2.rs +++ b/tests/ui/track-diagnostics/track2.rs @@ -4,6 +4,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" fn main() { let _moved @ _from = String::from("foo"); diff --git a/tests/ui/track-diagnostics/track3.rs b/tests/ui/track-diagnostics/track3.rs index a39e71915d90..144f2794e910 100644 --- a/tests/ui/track-diagnostics/track3.rs +++ b/tests/ui/track-diagnostics/track3.rs @@ -4,6 +4,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" fn main() { let _unimported = Blah { field: u8 }; diff --git a/tests/ui/track-diagnostics/track4.rs b/tests/ui/track-diagnostics/track4.rs index 0038c616aa55..2ab7d5423303 100644 --- a/tests/ui/track-diagnostics/track4.rs +++ b/tests/ui/track-diagnostics/track4.rs @@ -4,6 +4,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" pub onion { //~^ ERROR missing `enum` for enum definition diff --git a/tests/ui/track-diagnostics/track5.rs b/tests/ui/track-diagnostics/track5.rs index 09fda4eb5273..4d47f56e5806 100644 --- a/tests/ui/track-diagnostics/track5.rs +++ b/tests/ui/track-diagnostics/track5.rs @@ -4,6 +4,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" } //~^ ERROR unexpected closing delimiter: `}` diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs index 11d3b7e9764b..aa75c5691e5f 100644 --- a/tests/ui/track-diagnostics/track6.rs +++ b/tests/ui/track-diagnostics/track6.rs @@ -4,13 +4,13 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" - +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" pub trait Foo { fn bar(); } -impl Foo for T { +impl Foo for T { default fn bar() {} //~^ ERROR specialization is unstable //~| NOTE created at diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs index ff99ac98926c..29f193a4d7f3 100644 --- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs +++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs @@ -3,6 +3,7 @@ //@ normalize-stderr: "note: .*\n\n" -> "" //@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" //@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![feature(pattern_types, pattern_type_macro, generic_const_exprs)] diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr index ffc6068eb17e..d053d8aed062 100644 --- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr +++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr @@ -1,12 +1,12 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad_const_generics_args_on_const_param.rs:8:47 + --> $DIR/bad_const_generics_args_on_const_param.rs:9:47 | LL | #![feature(pattern_types, pattern_type_macro, generic_const_exprs)] | ^^^^^^^^^^^^^^^^^^^ | = note: see issue #76560 for more information = error: internal compiler error: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs:LL:CC: try_lower_anon_const_lit: received const param which shouldn't be possible - --> $DIR/bad_const_generics_args_on_const_param.rs:12:36 + --> $DIR/bad_const_generics_args_on_const_param.rs:13:36 | LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>); | ^^^^^^^^^^^^^^^^^^^ From b31ee3af9c67c777143c0b6707a4439c78391b69 Mon Sep 17 00:00:00 2001 From: Moulins Date: Thu, 18 Dec 2025 00:27:02 +0100 Subject: [PATCH 1018/3801] layout: Store inverse memory index in `FieldsShape::Arbitrary` All usages of `memory_index` start by calling `invert_bijective_mapping`, so storing the inverted mapping directly saves some work and simplifies the code. --- compiler/rustc_abi/src/layout.rs | 46 ++++++++---------- compiler/rustc_abi/src/layout/coroutine.rs | 46 +++++++++--------- compiler/rustc_abi/src/layout/simple.rs | 6 +-- compiler/rustc_abi/src/lib.rs | 47 ++----------------- .../src/pretty_clif.rs | 4 +- .../rustc_const_eval/src/interpret/visitor.rs | 18 +++---- compiler/rustc_index/src/slice.rs | 3 -- compiler/rustc_transmute/src/layout/tree.rs | 5 +- compiler/rustc_ty_utils/src/layout.rs | 4 +- src/tools/miri/src/helpers.rs | 7 ++- tests/ui/abi/c-zst.aarch64-darwin.stderr | 4 +- tests/ui/abi/c-zst.powerpc-linux.stderr | 4 +- tests/ui/abi/c-zst.s390x-linux.stderr | 4 +- tests/ui/abi/c-zst.sparc64-linux.stderr | 4 +- tests/ui/abi/c-zst.x86_64-linux.stderr | 4 +- .../ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 4 +- tests/ui/abi/debug.generic.stderr | 20 ++++---- tests/ui/abi/debug.loongarch64.stderr | 20 ++++---- tests/ui/abi/debug.riscv64.stderr | 20 ++++---- tests/ui/abi/pass-indirectly-attr.stderr | 8 ++-- tests/ui/abi/sysv64-zst.stderr | 4 +- .../pass-by-value-abi.aarch64.stderr | 4 +- tests/ui/c-variadic/pass-by-value-abi.rs | 2 +- .../c-variadic/pass-by-value-abi.win.stderr | 4 +- .../pass-by-value-abi.x86_64.stderr | 12 ++--- .../enum-discriminant/wrapping_niche.stderr | 16 +++---- tests/ui/layout/debug.stderr | 14 +++--- tests/ui/layout/hexagon-enum.stderr | 20 ++++---- ...-scalarpair-payload-might-be-uninit.stderr | 34 +++++++------- .../issue-96185-overaligned-enum.stderr | 12 ++--- tests/ui/layout/thumb-enum.stderr | 20 ++++---- .../layout/zero-sized-array-enum-niche.stderr | 26 +++++----- ...-variants.aarch64-unknown-linux-gnu.stderr | 16 +++---- ...-c-dead-variants.armebv7r-none-eabi.stderr | 16 +++---- ...-dead-variants.i686-pc-windows-msvc.stderr | 16 +++---- ...d-variants.x86_64-unknown-linux-gnu.stderr | 16 +++---- tests/ui/repr/repr-c-int-dead-variants.stderr | 16 +++---- tests/ui/type/pattern_types/non_null.stderr | 10 ++-- .../ui/type/pattern_types/or_patterns.stderr | 4 +- .../type/pattern_types/range_patterns.stderr | 22 ++++----- 40 files changed, 254 insertions(+), 308 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index b852d71b8008..4f1594d02a82 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -714,7 +714,7 @@ impl LayoutCalculator { }, fields: FieldsShape::Arbitrary { offsets: [niche_offset].into(), - memory_index: [0].into(), + in_memory_order: [FieldIdx::new(0)].into(), }, backend_repr: abi, largest_niche, @@ -1008,8 +1008,8 @@ impl LayoutCalculator { let pair = LayoutData::::scalar_pair(&self.cx, tag, prim_scalar); let pair_offsets = match pair.fields { - FieldsShape::Arbitrary { ref offsets, ref memory_index } => { - assert_eq!(memory_index.raw, [0, 1]); + FieldsShape::Arbitrary { ref offsets, ref in_memory_order } => { + assert_eq!(in_memory_order.raw, [FieldIdx::new(0), FieldIdx::new(1)]); offsets } _ => panic!("encountered a non-arbitrary layout during enum layout"), @@ -1061,7 +1061,7 @@ impl LayoutCalculator { }, fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), - memory_index: [0].into(), + in_memory_order: [FieldIdx::new(0)].into(), }, largest_niche, uninhabited, @@ -1110,10 +1110,10 @@ impl LayoutCalculator { let pack = repr.pack; let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; let mut max_repr_align = repr.align; - let mut inverse_memory_index: IndexVec = fields.indices().collect(); + let mut in_memory_order: IndexVec = fields.indices().collect(); let optimize_field_order = !repr.inhibit_struct_field_reordering(); let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; - let optimizing = &mut inverse_memory_index.raw[..end]; + let optimizing = &mut in_memory_order.raw[..end]; let fields_excluding_tail = &fields.raw[..end]; // unsizable tail fields are excluded so that we use the same seed for the sized and unsized layouts. let field_seed = fields_excluding_tail @@ -1248,12 +1248,10 @@ impl LayoutCalculator { // regardless of the status of `-Z randomize-layout` } } - // inverse_memory_index holds field indices by increasing memory offset. - // That is, if field 5 has offset 0, the first element of inverse_memory_index is 5. + // in_memory_order holds field indices by increasing memory offset. + // That is, if field 5 has offset 0, the first element of in_memory_order is 5. // We now write field offsets to the corresponding offset slot; // field 5 with offset 0 puts 0 in offsets[5]. - // At the bottom of this function, we invert `inverse_memory_index` to - // produce `memory_index` (see `invert_mapping`). let mut unsized_field = None::<&F>; let mut offsets = IndexVec::from_elem(Size::ZERO, fields); let mut offset = Size::ZERO; @@ -1265,7 +1263,7 @@ impl LayoutCalculator { align = align.max(prefix_align); offset = prefix_size.align_to(prefix_align); } - for &i in &inverse_memory_index { + for &i in &in_memory_order { let field = &fields[i]; if let Some(unsized_field) = unsized_field { return Err(LayoutCalculatorError::UnexpectedUnsized(*unsized_field)); @@ -1322,18 +1320,6 @@ impl LayoutCalculator { debug!("univariant min_size: {:?}", offset); let min_size = offset; - // As stated above, inverse_memory_index holds field indices by increasing offset. - // This makes it an already-sorted view of the offsets vec. - // To invert it, consider: - // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0. - // Field 5 would be the first element, so memory_index is i: - // Note: if we didn't optimize, it's already right. - let memory_index = if optimize_field_order { - inverse_memory_index.invert_bijective_mapping() - } else { - debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices())); - inverse_memory_index.into_iter().map(|it| it.index() as u32).collect() - }; let size = min_size.align_to(align); // FIXME(oli-obk): deduplicate and harden these checks if size.bytes() >= dl.obj_size_bound() { @@ -1389,8 +1375,11 @@ impl LayoutCalculator { let pair = LayoutData::::scalar_pair(&self.cx, a, b); let pair_offsets = match pair.fields { - FieldsShape::Arbitrary { ref offsets, ref memory_index } => { - assert_eq!(memory_index.raw, [0, 1]); + FieldsShape::Arbitrary { ref offsets, ref in_memory_order } => { + assert_eq!( + in_memory_order.raw, + [FieldIdx::new(0), FieldIdx::new(1)] + ); offsets } FieldsShape::Primitive @@ -1434,7 +1423,7 @@ impl LayoutCalculator { Ok(LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Arbitrary { offsets, memory_index }, + fields: FieldsShape::Arbitrary { offsets, in_memory_order }, backend_repr: abi, largest_niche, uninhabited, @@ -1530,7 +1519,10 @@ where Ok(LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }, + fields: FieldsShape::Arbitrary { + offsets: [Size::ZERO].into(), + in_memory_order: [FieldIdx::new(0)].into(), + }, backend_repr: repr, largest_niche: elt.largest_niche, uninhabited: false, diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs index 2b22276d4aed..815cf1e28a08 100644 --- a/compiler/rustc_abi/src/layout/coroutine.rs +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -182,33 +182,29 @@ pub(super) fn layout< // CoroutineLayout. debug!("prefix = {:#?}", prefix); let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields { - FieldsShape::Arbitrary { mut offsets, memory_index } => { - let mut inverse_memory_index = memory_index.invert_bijective_mapping(); - + FieldsShape::Arbitrary { mut offsets, in_memory_order } => { // "a" (`0..b_start`) and "b" (`b_start..`) correspond to // "outer" and "promoted" fields respectively. let b_start = tag_index.plus(1); let offsets_b = IndexVec::from_raw(offsets.raw.split_off(b_start.index())); let offsets_a = offsets; - // Disentangle the "a" and "b" components of `inverse_memory_index` + // Disentangle the "a" and "b" components of `in_memory_order` // by preserving the order but keeping only one disjoint "half" each. // FIXME(eddyb) build a better abstraction for permutations, if possible. - let inverse_memory_index_b: IndexVec = inverse_memory_index - .iter() - .filter_map(|&i| i.index().checked_sub(b_start.index()).map(FieldIdx::new)) - .collect(); - inverse_memory_index.raw.retain(|&i| i.index() < b_start.index()); - let inverse_memory_index_a = inverse_memory_index; - - // Since `inverse_memory_index_{a,b}` each only refer to their - // respective fields, they can be safely inverted - let memory_index_a = inverse_memory_index_a.invert_bijective_mapping(); - let memory_index_b = inverse_memory_index_b.invert_bijective_mapping(); + let mut in_memory_order_a = IndexVec::::new(); + let mut in_memory_order_b = IndexVec::::new(); + for i in in_memory_order { + if let Some(j) = i.index().checked_sub(b_start.index()) { + in_memory_order_b.push(FieldIdx::new(j)); + } else { + in_memory_order_a.push(i); + } + } let outer_fields = - FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a }; - (outer_fields, offsets_b, memory_index_b) + FieldsShape::Arbitrary { offsets: offsets_a, in_memory_order: in_memory_order_a }; + (outer_fields, offsets_b, in_memory_order_b.invert_bijective_mapping()) } _ => unreachable!(), }; @@ -236,7 +232,7 @@ pub(super) fn layout< )?; variant.variants = Variants::Single { index }; - let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else { + let FieldsShape::Arbitrary { offsets, in_memory_order } = variant.fields else { unreachable!(); }; @@ -249,8 +245,9 @@ pub(super) fn layout< // promoted fields were being used, but leave the elements not in the // subset as `invalid_field_idx`, which we can filter out later to // obtain a valid (bijective) mapping. + let memory_index = in_memory_order.invert_bijective_mapping(); let invalid_field_idx = promoted_memory_index.len() + memory_index.len(); - let mut combined_inverse_memory_index = + let mut combined_in_memory_order = IndexVec::from_elem_n(FieldIdx::new(invalid_field_idx), invalid_field_idx); let mut offsets_and_memory_index = iter::zip(offsets, memory_index); @@ -268,19 +265,18 @@ pub(super) fn layout< (promoted_offsets[field_idx], promoted_memory_index[field_idx]) } }; - combined_inverse_memory_index[memory_index] = i; + combined_in_memory_order[memory_index] = i; offset }) .collect(); - // Remove the unused slots and invert the mapping to obtain the - // combined `memory_index` (also see previous comment). - combined_inverse_memory_index.raw.retain(|&i| i.index() != invalid_field_idx); - let combined_memory_index = combined_inverse_memory_index.invert_bijective_mapping(); + // Remove the unused slots to obtain the combined `in_memory_order` + // (also see previous comment). + combined_in_memory_order.raw.retain(|&i| i.index() != invalid_field_idx); variant.fields = FieldsShape::Arbitrary { offsets: combined_offsets, - memory_index: combined_memory_index, + in_memory_order: combined_in_memory_order, }; size = size.max(variant.size); diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index b3807c872739..3784611b157b 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -16,7 +16,7 @@ impl LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Arbitrary { offsets: IndexVec::new(), - memory_index: IndexVec::new(), + in_memory_order: IndexVec::new(), }, backend_repr: BackendRepr::Memory { sized }, largest_niche: None, @@ -108,7 +108,7 @@ impl LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Arbitrary { offsets: [Size::ZERO, b_offset].into(), - memory_index: [0, 1].into(), + in_memory_order: [FieldIdx::new(0), FieldIdx::new(1)].into(), }, backend_repr: BackendRepr::ScalarPair(a, b), largest_niche, @@ -133,7 +133,7 @@ impl LayoutData { Some(fields) => FieldsShape::Union(fields), None => FieldsShape::Arbitrary { offsets: IndexVec::new(), - memory_index: IndexVec::new(), + in_memory_order: IndexVec::new(), }, }, backend_repr: BackendRepr::Memory { sized: true }, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 53b2c3f36dfc..061ad8617893 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1636,19 +1636,14 @@ pub enum FieldsShape { // FIXME(eddyb) use small vector optimization for the common case. offsets: IndexVec, - /// Maps source order field indices to memory order indices, + /// Maps memory order field indices to source order indices, /// depending on how the fields were reordered (if at all). /// This is a permutation, with both the source order and the /// memory order using the same (0..n) index ranges. /// - /// Note that during computation of `memory_index`, sometimes - /// it is easier to operate on the inverse mapping (that is, - /// from memory order to source order), and that is usually - /// named `inverse_memory_index`. - /// // FIXME(eddyb) build a better abstraction for permutations, if possible. // FIXME(camlorn) also consider small vector optimization here. - memory_index: IndexVec, + in_memory_order: IndexVec, }, } @@ -1682,51 +1677,17 @@ impl FieldsShape { } } - #[inline] - pub fn memory_index(&self, i: usize) -> usize { - match *self { - FieldsShape::Primitive => { - unreachable!("FieldsShape::memory_index: `Primitive`s have no fields") - } - FieldsShape::Union(_) | FieldsShape::Array { .. } => i, - FieldsShape::Arbitrary { ref memory_index, .. } => { - memory_index[FieldIdx::new(i)].try_into().unwrap() - } - } - } - /// Gets source indices of the fields by increasing offsets. #[inline] pub fn index_by_increasing_offset(&self) -> impl ExactSizeIterator { - let mut inverse_small = [0u8; 64]; - let mut inverse_big = IndexVec::new(); - let use_small = self.count() <= inverse_small.len(); - - // We have to write this logic twice in order to keep the array small. - if let FieldsShape::Arbitrary { ref memory_index, .. } = *self { - if use_small { - for (field_idx, &mem_idx) in memory_index.iter_enumerated() { - inverse_small[mem_idx as usize] = field_idx.index() as u8; - } - } else { - inverse_big = memory_index.invert_bijective_mapping(); - } - } - // Primitives don't really have fields in the way that structs do, // but having this return an empty iterator for them is unhelpful // since that makes them look kinda like ZSTs, which they're not. let pseudofield_count = if let FieldsShape::Primitive = self { 1 } else { self.count() }; - (0..pseudofield_count).map(move |i| match *self { + (0..pseudofield_count).map(move |i| match self { FieldsShape::Primitive | FieldsShape::Union(_) | FieldsShape::Array { .. } => i, - FieldsShape::Arbitrary { .. } => { - if use_small { - inverse_small[i] as usize - } else { - inverse_big[i as u32].index() - } - } + FieldsShape::Arbitrary { in_memory_order, .. } => in_memory_order[i as u32].index(), }) } } diff --git a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs index 2878fa7aa298..65779b38ad1c 100644 --- a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs +++ b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs @@ -10,7 +10,7 @@ //! function u0:22(i64) -> i8, i8 system_v { //! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd361e9f5c3d1c4deE //! ; instance Instance { def: Item(DefId(0:42 ~ example[3895]::{impl#0}::call_once)), args: ['{erased}, '{erased}] } -//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: Memory { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 12266848898570219025 } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } +//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: Memory { sized: true }, fields: Arbitrary { offsets: [], in_memory_order: [] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 12266848898570219025 } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], in_memory_order: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } //! //! ; kind loc.idx param pass mode ty //! ; ssa _0 (u8, u8) 2b 1 var=(0, 1) @@ -41,7 +41,7 @@ //! ; //! ; _0 = >::call_mut(move _3, copy _2) //! v2 = stack_load.i64 ss0 -//! ; abi: FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: &mut IsNotEmpty, layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(1 bytes)) }) }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } +//! ; abi: FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: &mut IsNotEmpty, layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(1 bytes)) }) }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], in_memory_order: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } //! v3, v4 = call fn0(v1, v2) ; v1 = 1 //! v5 -> v3 //! v6 -> v4 diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index b5de10c7dcd1..95106c7c143b 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -4,7 +4,7 @@ use std::num::NonZero; use rustc_abi::{FieldIdx, FieldsShape, VariantIdx, Variants}; -use rustc_index::IndexVec; +use rustc_index::{Idx as _, IndexVec}; use rustc_middle::mir::interpret::InterpResult; use rustc_middle::ty::{self, Ty}; use tracing::trace; @@ -27,13 +27,15 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { /// This function provides the chance to reorder the order in which fields are visited for /// `FieldsShape::Aggregate`. /// - /// The default means we iterate in source declaration order; alternatively this can do some - /// work with `memory_index` to iterate in memory order. + /// The default means we iterate in source declaration order; alternatively this can use + /// `in_memory_order` to iterate in memory order. #[inline(always)] fn aggregate_field_iter( - memory_index: &IndexVec, - ) -> impl Iterator + 'static { - memory_index.indices() + in_memory_order: &IndexVec, + ) -> impl Iterator { + // Allow the optimizer to elide the bounds checking when creating each index. + let _ = FieldIdx::new(in_memory_order.len()); + (0..in_memory_order.len()).map(FieldIdx::new) } // Recursive actions, ready to be overloaded. @@ -168,8 +170,8 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { &FieldsShape::Union(fields) => { self.visit_union(v, fields)?; } - FieldsShape::Arbitrary { memory_index, .. } => { - for idx in Self::aggregate_field_iter(memory_index) { + FieldsShape::Arbitrary { in_memory_order, .. } => { + for idx in Self::aggregate_field_iter(in_memory_order) { let field = self.ecx().project_field(v, idx)?; self.visit_field(v, idx.as_usize(), &field)?; } diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index d2702bdb0571..415fe370b702 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -181,9 +181,6 @@ impl IndexSlice { /// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`, /// assuming the values in `self` are a permutation of `0..self.len()`. /// - /// This is used to go between `memory_index` (source field order to memory order) - /// and `inverse_memory_index` (memory order to source field order). - /// See also `FieldsShape::Arbitrary::memory_index` for more details. // FIXME(eddyb) build a better abstraction for permutations, if possible. pub fn invert_bijective_mapping(&self) -> IndexVec { debug_assert_eq!( diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index d9ebdadf3b79..1202ed238431 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -491,7 +491,7 @@ pub(crate) mod rustc { ) -> Result { // This constructor does not support non-`FieldsShape::Arbitrary` // layouts. - let FieldsShape::Arbitrary { offsets, memory_index } = layout.fields() else { + let FieldsShape::Arbitrary { offsets, in_memory_order } = layout.fields() else { return Err(Err::NotYetSupported); }; @@ -519,8 +519,7 @@ pub(crate) mod rustc { } // Append the fields, in memory order, to the layout. - let inverse_memory_index = memory_index.invert_bijective_mapping(); - for &field_idx in inverse_memory_index.iter() { + for &field_idx in in_memory_order.iter() { // Add interfield padding. let padding_needed = offsets[field_idx] - size; let padding = Self::padding(padding_needed.bytes_usize()); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 6962eeddf137..62f3667ad7f4 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -9,7 +9,7 @@ use rustc_abi::{ use rustc_hashes::Hash64; use rustc_hir::attrs::AttributeKind; use rustc_hir::find_attr; -use rustc_index::IndexVec; +use rustc_index::{Idx as _, IndexVec}; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; @@ -374,7 +374,7 @@ fn layout_of_uncached<'tcx>( // specifically care about pattern types will have to handle it. layout.fields = FieldsShape::Arbitrary { offsets: [Size::ZERO].into_iter().collect(), - memory_index: [0].into_iter().collect(), + in_memory_order: [FieldIdx::new(0)].into_iter().collect(), }; tcx.mk_layout(layout) } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index f11860f4a1ad..218e4ffe5e2f 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -584,10 +584,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } fn aggregate_field_iter( - memory_index: &IndexVec, - ) -> impl Iterator + 'static { - let inverse_memory_index = memory_index.invert_bijective_mapping(); - inverse_memory_index.into_iter() + in_memory_order: &IndexVec, + ) -> impl Iterator { + in_memory_order.iter().copied() } // Hook to detect `UnsafeCell`. diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index d050bfcbaa17..6d2ac90c0c97 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -41,7 +41,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index 816addd79576..f297aa984dd2 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index 816addd79576..f297aa984dd2 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index 816addd79576..f297aa984dd2 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index d050bfcbaa17..6d2ac90c0c97 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -41,7 +41,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index 816addd79576..f297aa984dd2 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/debug.generic.stderr b/tests/ui/abi/debug.generic.stderr index 04d6f50872a3..8a031b79780a 100644 --- a/tests/ui/abi/debug.generic.stderr +++ b/tests/ui/abi/debug.generic.stderr @@ -244,7 +244,7 @@ error: fn_abi_of(test_generic) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -328,7 +328,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -400,7 +400,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -479,7 +479,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -552,7 +552,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -629,7 +629,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -701,7 +701,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -779,7 +779,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -851,7 +851,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -962,7 +962,7 @@ error: fn_abi_of(assoc_test) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/debug.loongarch64.stderr b/tests/ui/abi/debug.loongarch64.stderr index 85c888c4fae0..00bd3febde4e 100644 --- a/tests/ui/abi/debug.loongarch64.stderr +++ b/tests/ui/abi/debug.loongarch64.stderr @@ -244,7 +244,7 @@ error: fn_abi_of(test_generic) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -328,7 +328,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -400,7 +400,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -479,7 +479,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -552,7 +552,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -629,7 +629,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -701,7 +701,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -779,7 +779,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -851,7 +851,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -962,7 +962,7 @@ error: fn_abi_of(assoc_test) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/debug.riscv64.stderr b/tests/ui/abi/debug.riscv64.stderr index 85c888c4fae0..00bd3febde4e 100644 --- a/tests/ui/abi/debug.riscv64.stderr +++ b/tests/ui/abi/debug.riscv64.stderr @@ -244,7 +244,7 @@ error: fn_abi_of(test_generic) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -328,7 +328,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -400,7 +400,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -479,7 +479,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -552,7 +552,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -629,7 +629,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -701,7 +701,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -779,7 +779,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -851,7 +851,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -962,7 +962,7 @@ error: fn_abi_of(assoc_test) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/pass-indirectly-attr.stderr b/tests/ui/abi/pass-indirectly-attr.stderr index a93982dacfa1..03fe9ea46a4b 100644 --- a/tests/ui/abi/pass-indirectly-attr.stderr +++ b/tests/ui/abi/pass-indirectly-attr.stderr @@ -24,7 +24,7 @@ error: fn_abi_of(extern_c) = FnAbi { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -65,7 +65,7 @@ error: fn_abi_of(extern_c) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -106,7 +106,7 @@ error: fn_abi_of(extern_rust) = FnAbi { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -165,7 +165,7 @@ error: fn_abi_of(extern_rust) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index 2233e8e4f623..82d3793c3532 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -41,7 +41,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr index a86b28d98ecc..584416f58f86 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(take_va_list) = FnAbi { }, fields: Arbitrary { offsets: $OFFSETS, - memory_index: $MEMORY_INDEX, + in_memory_order: $MEMORY_INDEX, }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(take_va_list) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/c-variadic/pass-by-value-abi.rs b/tests/ui/c-variadic/pass-by-value-abi.rs index 1e3935067cc2..a7cf37295a74 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.rs +++ b/tests/ui/c-variadic/pass-by-value-abi.rs @@ -1,7 +1,7 @@ //@ check-fail //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ normalize-stderr: "valid_range: 0\.\.=\d+" -> "valid_range: 0..=$$MAX" -//@ normalize-stderr: "memory_index: \[[^\]]+\]" -> "memory_index: $$MEMORY_INDEX" +//@ normalize-stderr: "in_memory_order: \[[^\]]+\]" -> "in_memory_order: $$MEMORY_INDEX" //@ normalize-stderr: "offsets: \[[^\]]+\]" -> "offsets: $$OFFSETS" //@ revisions: x86_64 aarch64 win //@ compile-flags: -O diff --git a/tests/ui/c-variadic/pass-by-value-abi.win.stderr b/tests/ui/c-variadic/pass-by-value-abi.win.stderr index 8ff93961f667..b8e3f699b30e 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.win.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.win.stderr @@ -20,7 +20,7 @@ error: fn_abi_of(take_va_list) = FnAbi { ), fields: Arbitrary { offsets: $OFFSETS, - memory_index: $MEMORY_INDEX, + in_memory_order: $MEMORY_INDEX, }, largest_niche: None, uninhabited: false, @@ -55,7 +55,7 @@ error: fn_abi_of(take_va_list) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr index aafe89d59e33..b5e0e8589af1 100644 --- a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr +++ b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(take_va_list) = FnAbi { }, fields: Arbitrary { offsets: $OFFSETS, - memory_index: $MEMORY_INDEX, + in_memory_order: $MEMORY_INDEX, }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(take_va_list) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -91,7 +91,7 @@ error: fn_abi_of(take_va_list_sysv64) = FnAbi { }, fields: Arbitrary { offsets: $OFFSETS, - memory_index: $MEMORY_INDEX, + in_memory_order: $MEMORY_INDEX, }, largest_niche: None, uninhabited: false, @@ -130,7 +130,7 @@ error: fn_abi_of(take_va_list_sysv64) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -171,7 +171,7 @@ error: fn_abi_of(take_va_list_win64) = FnAbi { }, fields: Arbitrary { offsets: $OFFSETS, - memory_index: $MEMORY_INDEX, + in_memory_order: $MEMORY_INDEX, }, largest_niche: None, uninhabited: false, @@ -210,7 +210,7 @@ error: fn_abi_of(take_va_list_win64) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index e3e1755e14dd..9b97ad4aeac7 100644 --- a/tests/ui/enum-discriminant/wrapping_niche.stderr +++ b/tests/ui/enum-discriminant/wrapping_niche.stderr @@ -16,7 +16,7 @@ error: layout_of(UnsignedAroundZero) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -52,7 +52,7 @@ error: layout_of(UnsignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -73,7 +73,7 @@ error: layout_of(UnsignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -94,7 +94,7 @@ error: layout_of(UnsignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -134,7 +134,7 @@ error: layout_of(SignedAroundZero) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -170,7 +170,7 @@ error: layout_of(SignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -191,7 +191,7 @@ error: layout_of(SignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -212,7 +212,7 @@ error: layout_of(SignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index b2ce6385ab65..79ce21eb532b 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -16,7 +16,7 @@ error: layout_of(E) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -52,7 +52,7 @@ error: layout_of(E) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -77,7 +77,7 @@ error: layout_of(E) = Layout { Size(4 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, 2, @@ -130,7 +130,7 @@ error: layout_of(S) = Layout { Size(8 bytes), Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, 2, 1, @@ -200,7 +200,7 @@ error: layout_of(Result) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -251,7 +251,7 @@ error: layout_of(Result) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -289,7 +289,7 @@ error: layout_of(Result) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 659013c8a6f1..20e0a8642a66 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -16,7 +16,7 @@ error: layout_of(A) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -52,7 +52,7 @@ error: layout_of(A) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -92,7 +92,7 @@ error: layout_of(B) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -128,7 +128,7 @@ error: layout_of(B) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -168,7 +168,7 @@ error: layout_of(C) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -204,7 +204,7 @@ error: layout_of(C) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -244,7 +244,7 @@ error: layout_of(P) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -280,7 +280,7 @@ error: layout_of(P) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -320,7 +320,7 @@ error: layout_of(T) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -356,7 +356,7 @@ error: layout_of(T) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index 2087fedeb19b..61cfcbdc07f7 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -22,7 +22,7 @@ error: layout_of(MissingPayloadField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -72,7 +72,7 @@ error: layout_of(MissingPayloadField) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -95,7 +95,7 @@ error: layout_of(MissingPayloadField) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -142,7 +142,7 @@ error: layout_of(CommonPayloadField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -193,7 +193,7 @@ error: layout_of(CommonPayloadField) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(CommonPayloadField) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -279,7 +279,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -329,7 +329,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -366,7 +366,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -414,7 +414,7 @@ error: layout_of(NicheFirst) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -470,7 +470,7 @@ error: layout_of(NicheFirst) = Layout { Size(0 bytes), Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -503,7 +503,7 @@ error: layout_of(NicheFirst) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -524,7 +524,7 @@ error: layout_of(NicheFirst) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -570,7 +570,7 @@ error: layout_of(NicheSecond) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -626,7 +626,7 @@ error: layout_of(NicheSecond) = Layout { Size(1 bytes), Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 1, 0, ], @@ -659,7 +659,7 @@ error: layout_of(NicheSecond) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -680,7 +680,7 @@ error: layout_of(NicheSecond) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 6bcc5b4906b5..64e2f42c042f 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -10,7 +10,7 @@ error: layout_of(Aligned1) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -46,7 +46,7 @@ error: layout_of(Aligned1) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -69,7 +69,7 @@ error: layout_of(Aligned1) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -113,7 +113,7 @@ error: layout_of(Aligned2) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -149,7 +149,7 @@ error: layout_of(Aligned2) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -172,7 +172,7 @@ error: layout_of(Aligned2) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 1ef22daf2a9d..a6e603652123 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -16,7 +16,7 @@ error: layout_of(A) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -52,7 +52,7 @@ error: layout_of(A) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -92,7 +92,7 @@ error: layout_of(B) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -128,7 +128,7 @@ error: layout_of(B) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -168,7 +168,7 @@ error: layout_of(C) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -204,7 +204,7 @@ error: layout_of(C) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -244,7 +244,7 @@ error: layout_of(P) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -280,7 +280,7 @@ error: layout_of(P) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -320,7 +320,7 @@ error: layout_of(T) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -356,7 +356,7 @@ error: layout_of(T) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index 1707b8aff81c..23f909277808 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -10,7 +10,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -48,7 +48,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -73,7 +73,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -118,7 +118,7 @@ error: layout_of(MultipleAlignments) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -156,7 +156,7 @@ error: layout_of(MultipleAlignments) = Layout { offsets: [ Size(2 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -181,7 +181,7 @@ error: layout_of(MultipleAlignments) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -206,7 +206,7 @@ error: layout_of(MultipleAlignments) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -251,7 +251,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -289,7 +289,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -314,7 +314,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -359,7 +359,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -401,7 +401,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -426,7 +426,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 1a1929c530ff..62f6ec92d493 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -16,7 +16,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 67729e9fcef9..3e0efad974cd 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -16,7 +16,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 1a1929c530ff..62f6ec92d493 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -16,7 +16,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 1a1929c530ff..62f6ec92d493 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -16,7 +16,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index d88a842f8848..b25e4a9b7b6f 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -16,7 +16,7 @@ error: layout_of(UnivariantU8) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(UnivariantU8) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariantsU8) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariantsU8) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariantsU8) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr index ad61e9a59147..0847af2d086f 100644 --- a/tests/ui/type/pattern_types/non_null.stderr +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -17,7 +17,7 @@ error: layout_of((*const T) is !null) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -64,7 +64,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -96,7 +96,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -126,7 +126,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -186,7 +186,7 @@ error: layout_of((*const [u8]) is !null) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/type/pattern_types/or_patterns.stderr b/tests/ui/type/pattern_types/or_patterns.stderr index adc7320829b9..7206c570187b 100644 --- a/tests/ui/type/pattern_types/or_patterns.stderr +++ b/tests/ui/type/pattern_types/or_patterns.stderr @@ -57,7 +57,7 @@ error: layout_of((i8) is (i8::MIN..=-1 | 1..)) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -102,7 +102,7 @@ error: layout_of((i8) is (i8::MIN..=-2 | 0..)) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index c9a846e22f58..6c9acac7eb7b 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -16,7 +16,7 @@ error: layout_of(NonZero) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -61,7 +61,7 @@ error: layout_of((u32) is 1..) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -106,7 +106,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -137,7 +137,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -166,7 +166,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -217,7 +217,7 @@ error: layout_of(Option>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -248,7 +248,7 @@ error: layout_of(Option>) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -277,7 +277,7 @@ error: layout_of(Option>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -328,7 +328,7 @@ error: layout_of(NonZeroU32New) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -401,7 +401,7 @@ error: layout_of((i8) is -10..=10) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -446,7 +446,7 @@ error: layout_of((i8) is i8::MIN..=0) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, From 005046ddd4f990f48dee63a24f49fb47de992646 Mon Sep 17 00:00:00 2001 From: Moulins Date: Thu, 18 Dec 2025 00:27:02 +0100 Subject: [PATCH 1019/3801] layout: Store inverse memory index in `FieldsShape::Arbitrary` All usages of `memory_index` start by calling `invert_bijective_mapping`, so storing the inverted mapping directly saves some work and simplifies the code. --- src/pretty_clif.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 2878fa7aa298..65779b38ad1c 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -10,7 +10,7 @@ //! function u0:22(i64) -> i8, i8 system_v { //! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd361e9f5c3d1c4deE //! ; instance Instance { def: Item(DefId(0:42 ~ example[3895]::{impl#0}::call_once)), args: ['{erased}, '{erased}] } -//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: Memory { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 12266848898570219025 } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } +//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: Memory { sized: true }, fields: Arbitrary { offsets: [], in_memory_order: [] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 12266848898570219025 } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], in_memory_order: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } //! //! ; kind loc.idx param pass mode ty //! ; ssa _0 (u8, u8) 2b 1 var=(0, 1) @@ -41,7 +41,7 @@ //! ; //! ; _0 = >::call_mut(move _3, copy _2) //! v2 = stack_load.i64 ss0 -//! ; abi: FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: &mut IsNotEmpty, layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(1 bytes)) }) }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } +//! ; abi: FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: &mut IsNotEmpty, layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(1 bytes)) }) }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], in_memory_order: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } //! v3, v4 = call fn0(v1, v2) ; v1 = 1 //! v5 -> v3 //! v6 -> v4 From 5277241d277e1cb5a577bb0ae297c63f23d5dd3d Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Thu, 18 Dec 2025 12:12:31 +0100 Subject: [PATCH 1020/3801] Port `#[rustc_lint_untracked_query_information]` to attribute parser --- .../src/attributes/rustc_internal.rs | 16 ++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 6 ++++-- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/internal.rs | 5 ++++- compiler/rustc_passes/src/check_attr.rs | 4 +--- 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 8005dd76b2a3..ea73b7ad60ef 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -165,6 +165,22 @@ impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintQueryInstability; } +pub(crate) struct RustcLintUntrackedQueryInformationParser; + +impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationParser { + const PATH: &[Symbol] = &[sym::rustc_lint_untracked_query_information]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintUntrackedQueryInformation; +} + pub(crate) struct RustcObjectLifetimeDefaultParser; impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index e5448e7792a8..9b9bd94e1143 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -62,8 +62,9 @@ use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, - RustcLintQueryInstabilityParser, RustcMainParser, RustcNeverReturnsNullPointerParser, - RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, + RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, + RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, + RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; @@ -259,6 +260,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 5991fb5ab24e..afc458e2775f 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -940,6 +940,9 @@ pub enum AttributeKind { /// Represents `#[rustc_lint_query_instability]` RustcLintQueryInstability, + /// Represents `#[rustc_lint_untracked_query_information]` + RustcLintUntrackedQueryInformation, + /// Represents `#[rustc_main]`. RustcMain, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 64aa9c2a45bc..1899fe12ecdc 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -97,6 +97,7 @@ impl AttributeKind { RustcLintOptDenyFieldAccess { .. } => Yes, RustcLintOptTy => Yes, RustcLintQueryInstability => Yes, + RustcLintUntrackedQueryInformation => Yes, RustcMain => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index d6f20a4c85a4..a2fcbd75f50f 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -106,7 +106,10 @@ impl<'tcx> LateLintPass<'tcx> for QueryStability { ); } - if cx.tcx.has_attr(def_id, sym::rustc_lint_untracked_query_information) { + if find_attr!( + cx.tcx.get_all_attrs(def_id), + AttributeKind::RustcLintUntrackedQueryInformation + ) { cx.emit_span_lint( UNTRACKED_QUERY_INFORMATION, span, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 33a3477bcf69..7c89982f8077 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -261,6 +261,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcLintOptDenyFieldAccess { .. } | AttributeKind::RustcLintOptTy | AttributeKind::RustcLintQueryInstability + | AttributeKind::RustcLintUntrackedQueryInformation | AttributeKind::RustcNeverReturnsNullPointer | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) @@ -309,9 +310,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::rustc_lint_untracked_query_information, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) - } [sym::rustc_lint_diagnostics, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } From 44cfed7465684c092d7a054bd4accdb8618cca3e Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Thu, 18 Dec 2025 14:20:26 +0100 Subject: [PATCH 1021/3801] Port `#[rustc_lint_diagnostics]` to attribute parser --- .../src/attributes/rustc_internal.rs | 15 ++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 9 ++++---- .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/internal.rs | 6 ++--- compiler/rustc_passes/messages.ftl | 7 ------ compiler/rustc_passes/src/check_attr.rs | 23 +------------------ compiler/rustc_passes/src/errors.rs | 10 -------- .../internal-lints/diagnostics_incorrect.rs | 2 +- .../diagnostics_incorrect.stderr | 23 +++++++++++-------- 10 files changed, 42 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index ea73b7ad60ef..be4e2210c5ee 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -117,6 +117,21 @@ impl SingleAttributeParser for RustcLegacyConstGenericsParser { } } +pub(crate) struct RustcLintDiagnosticsParser; + +impl NoArgsAttributeParser for RustcLintDiagnosticsParser { + const PATH: &[Symbol] = &[sym::rustc_lint_diagnostics]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintDiagnostics; +} + pub(crate) struct RustcLintOptDenyFieldAccessParser; impl SingleAttributeParser for RustcLintOptDenyFieldAccessParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9b9bd94e1143..a752869c2eb2 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,10 +61,10 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, - RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, - RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, - RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, + RustcLegacyConstGenericsParser, RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, + RustcLintOptTyParser, RustcLintQueryInstabilityParser, + RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcNeverReturnsNullPointerParser, + RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; @@ -258,6 +258,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index afc458e2775f..1a382d8f124b 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -931,6 +931,9 @@ pub enum AttributeKind { /// Represents `#[rustc_legacy_const_generics]` RustcLegacyConstGenerics { fn_indexes: ThinVec<(usize, Span)>, attr_span: Span }, + /// Represents `#[rustc_lint_diagnostics]` + RustcLintDiagnostics, + /// Represents `#[rustc_lint_opt_deny_field_access]` RustcLintOptDenyFieldAccess { lint_message: Symbol }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 1899fe12ecdc..7c1e71f258be 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -94,6 +94,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, + RustcLintDiagnostics => Yes, RustcLintOptDenyFieldAccess { .. } => Yes, RustcLintOptTy => Yes, RustcLintQueryInstability => Yes, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index a2fcbd75f50f..68885e14f40d 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -609,14 +609,14 @@ impl Diagnostics { else { return; }; - let has_attr = cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics); - if !has_attr { + + if !find_attr!(cx.tcx.get_all_attrs(inst.def_id()), AttributeKind::RustcLintDiagnostics) { return; }; for (hir_id, _parent) in cx.tcx.hir_parent_iter(current_id) { if let Some(owner_did) = hir_id.as_owner() - && cx.tcx.has_attr(owner_did, sym::rustc_lint_diagnostics) + && find_attr!(cx.tcx.get_all_attrs(owner_did), AttributeKind::RustcLintDiagnostics) { // The parent method is marked with `#[rustc_lint_diagnostics]` return; diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 7ebfca91d499..c0106ea0c627 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -484,13 +484,6 @@ passes_sanitize_attribute_not_allowed = .no_body = function has no body .help = sanitize attribute can be applied to a function (with body), impl block, or module -passes_should_be_applied_to_fn = - attribute should be applied to a function definition - .label = {$on_crate -> - [true] cannot be applied to crates - *[false] not a function definition - } - passes_should_be_applied_to_static = attribute should be applied to a static .label = not a static diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7c89982f8077..945dcec798e3 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -258,6 +258,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) + | AttributeKind::RustcLintDiagnostics | AttributeKind::RustcLintOptDenyFieldAccess { .. } | AttributeKind::RustcLintOptTy | AttributeKind::RustcLintQueryInstability @@ -310,9 +311,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::rustc_lint_diagnostics, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) - } [sym::rustc_clean, ..] | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] @@ -1228,25 +1226,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Helper function for checking that the provided attribute is only applied to a function or - /// method. - fn check_applied_to_fn_or_method( - &self, - hir_id: HirId, - attr_span: Span, - defn_span: Span, - target: Target, - ) { - let is_function = matches!(target, Target::Fn | Target::Method(..)); - if !is_function { - self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { - attr_span, - defn_span, - on_crate: hir_id == CRATE_HIR_ID, - }); - } - } - /// Checks that the dep-graph debugging attributes are only present when the query-dep-graph /// option is passed to the compiler. fn check_rustc_dirty_clean(&self, attr: &Attribute) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 895cefe672ba..4f97f74c7804 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -80,16 +80,6 @@ pub(crate) struct OuterCrateLevelAttrSuggestion { #[diag(passes_inner_crate_level_attr)] pub(crate) struct InnerCrateLevelAttr; -#[derive(Diagnostic)] -#[diag(passes_should_be_applied_to_fn)] -pub(crate) struct AttrShouldBeAppliedToFn { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, - pub on_crate: bool, -} - #[derive(Diagnostic)] #[diag(passes_non_exhaustive_with_default_field_values)] pub(crate) struct NonExhaustiveWithDefaultFieldValues { diff --git a/tests/ui/internal-lints/diagnostics_incorrect.rs b/tests/ui/internal-lints/diagnostics_incorrect.rs index c1532aa9d57e..787acdad3884 100644 --- a/tests/ui/internal-lints/diagnostics_incorrect.rs +++ b/tests/ui/internal-lints/diagnostics_incorrect.rs @@ -3,7 +3,7 @@ #![feature(rustc_attrs)] #[rustc_lint_diagnostics] -//~^ ERROR attribute should be applied to a function +//~^ ERROR `#[rustc_lint_diagnostics]` attribute cannot be used on structs struct Foo; impl Foo { diff --git a/tests/ui/internal-lints/diagnostics_incorrect.stderr b/tests/ui/internal-lints/diagnostics_incorrect.stderr index e849ca2829e4..4d509acec790 100644 --- a/tests/ui/internal-lints/diagnostics_incorrect.stderr +++ b/tests/ui/internal-lints/diagnostics_incorrect.stderr @@ -1,17 +1,20 @@ -error: malformed `rustc_lint_diagnostics` attribute input - --> $DIR/diagnostics_incorrect.rs:10:5 - | -LL | #[rustc_lint_diagnostics(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_diagnostics]` - -error: attribute should be applied to a function definition +error: `#[rustc_lint_diagnostics]` attribute cannot be used on structs --> $DIR/diagnostics_incorrect.rs:5:1 | LL | #[rustc_lint_diagnostics] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | struct Foo; - | ----------- not a function definition + | + = help: `#[rustc_lint_diagnostics]` can only be applied to functions + +error[E0565]: malformed `rustc_lint_diagnostics` attribute input + --> $DIR/diagnostics_incorrect.rs:10:5 + | +LL | #[rustc_lint_diagnostics(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[rustc_lint_diagnostics]` error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0565`. From 4ff2c5c9f54bb33702b76013a2464cb31f6efa4f Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 25 Oct 2023 17:33:43 -0400 Subject: [PATCH 1022/3801] Don't treat asserts as a call in cross-crate inlining --- .../src/cross_crate_inline.rs | 35 +++++++++++++++---- .../cross-crate-inlining/auxiliary/leaf.rs | 5 +++ .../cross-crate-inlining/leaf-inlining.rs | 9 +++++ .../item-collection/implicit-panic-call.rs | 1 + 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 69248cf91f24..71bdafa958ca 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -1,6 +1,7 @@ use rustc_hir::attrs::InlineAttr; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_middle::bug; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::query::Providers; @@ -110,6 +111,15 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { && checker.statements <= threshold } +// The threshold that CostChecker computes is balancing the desire to make more things +// inlinable cross crates against the growth in incremental CGU size that happens when too many +// things in the sysroot are made inlinable. +// Permitting calls causes the size of some incremental CGUs to grow, because more functions are +// made inlinable out of the sysroot or dependencies. +// Assert terminators are similar to calls, but do not have the same impact on compile time, so +// those are just treated as statements. +// A threshold exists at all because we don't want to blindly mark a huge function as inlinable. + struct CostChecker<'b, 'tcx> { tcx: TyCtxt<'tcx>, callee_body: &'b Body<'tcx>, @@ -129,9 +139,10 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { } fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, _: Location) { + self.statements += 1; let tcx = self.tcx; - match terminator.kind { - TerminatorKind::Drop { ref place, unwind, .. } => { + match &terminator.kind { + TerminatorKind::Drop { place, unwind, .. } => { let ty = place.ty(self.callee_body, tcx).ty; if !ty.is_trivially_pure_clone_copy() { self.calls += 1; @@ -140,7 +151,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { } } } - TerminatorKind::Call { ref func, unwind, .. } => { + TerminatorKind::Call { func, unwind, .. } => { // We track calls because they make our function not a leaf (and in theory, the // number of calls indicates how likely this function is to perturb other CGUs). // But intrinsics don't have a body that gets assigned to a CGU, so they are @@ -155,21 +166,31 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { self.landing_pads += 1; } } - TerminatorKind::Assert { unwind, .. } => { + TerminatorKind::TailCall { .. } => { self.calls += 1; + } + TerminatorKind::Assert { unwind, .. } => { if let UnwindAction::Cleanup(_) = unwind { self.landing_pads += 1; } } TerminatorKind::UnwindResume => self.resumes += 1, TerminatorKind::InlineAsm { unwind, .. } => { - self.statements += 1; if let UnwindAction::Cleanup(_) = unwind { self.landing_pads += 1; } } - TerminatorKind::Return => {} - _ => self.statements += 1, + TerminatorKind::Return + | TerminatorKind::Goto { .. } + | TerminatorKind::SwitchInt { .. } + | TerminatorKind::Unreachable + | TerminatorKind::UnwindTerminate(_) => {} + kind @ (TerminatorKind::FalseUnwind { .. } + | TerminatorKind::FalseEdge { .. } + | TerminatorKind::Yield { .. } + | TerminatorKind::CoroutineDrop) => { + bug!("{kind:?} should not be in runtime MIR"); + } } } } diff --git a/tests/codegen-llvm/cross-crate-inlining/auxiliary/leaf.rs b/tests/codegen-llvm/cross-crate-inlining/auxiliary/leaf.rs index 7b5679c3f4de..5b3cd34a7fa5 100644 --- a/tests/codegen-llvm/cross-crate-inlining/auxiliary/leaf.rs +++ b/tests/codegen-llvm/cross-crate-inlining/auxiliary/leaf.rs @@ -23,3 +23,8 @@ fn inner() -> String { pub fn leaf_with_intrinsic(a: &[u64; 2], b: &[u64; 2]) -> bool { a == b } + +// This function's optimized MIR contains assert terminators, not calls. +pub fn leaf_with_assert(a: i32, b: i32) -> i32 { + a / b +} diff --git a/tests/codegen-llvm/cross-crate-inlining/leaf-inlining.rs b/tests/codegen-llvm/cross-crate-inlining/leaf-inlining.rs index 5e7912791ad6..3173adbd03ee 100644 --- a/tests/codegen-llvm/cross-crate-inlining/leaf-inlining.rs +++ b/tests/codegen-llvm/cross-crate-inlining/leaf-inlining.rs @@ -25,3 +25,12 @@ pub fn leaf_with_intrinsic_outer(a: &[u64; 2], b: &[u64; 2]) -> bool { // CHECK-NOT: call {{.*}}leaf_with_intrinsic leaf::leaf_with_intrinsic(a, b) } + +// Check that we inline functions with assert terminators +#[no_mangle] +pub fn leaf_with_assert(a: i32, b: i32) -> i32 { + // CHECK-NOT: call {{.*}}leaf_with_assert + // CHECK: sdiv i32 %a, %b + // CHECK-NOT: call {{.*}}leaf_with_assert + leaf::leaf_with_assert(a, b) +} diff --git a/tests/codegen-units/item-collection/implicit-panic-call.rs b/tests/codegen-units/item-collection/implicit-panic-call.rs index 612132f056be..3b442942cc5c 100644 --- a/tests/codegen-units/item-collection/implicit-panic-call.rs +++ b/tests/codegen-units/item-collection/implicit-panic-call.rs @@ -1,5 +1,6 @@ // rust-lang/rust#90405 // Ensure implicit panic calls are collected +//@ compile-flags: -Zcross-crate-inline-threshold=never #![feature(lang_items)] #![feature(no_core)] From c2f8ee9bbab1f64cdbf0f3bb02ea09f201fdbc04 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 6 Oct 2025 13:38:00 +1100 Subject: [PATCH 1023/3801] Remove inherent methods from `llvm::TypeKind` --- .../src/llvm/conversions.rs | 40 ++++++++++++++++++- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 27 ------------- compiler/rustc_codegen_llvm/src/type_.rs | 2 +- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm/conversions.rs b/compiler/rustc_codegen_llvm/src/llvm/conversions.rs index 9e9f9339ade8..3bc790ca7cff 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/conversions.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/conversions.rs @@ -1,6 +1,6 @@ //! Conversions from backend-independent data types to/from LLVM FFI types. -use rustc_codegen_ssa::common::{AtomicRmwBinOp, IntPredicate, RealPredicate}; +use rustc_codegen_ssa::common::{AtomicRmwBinOp, IntPredicate, RealPredicate, TypeKind}; use rustc_middle::ty::AtomicOrdering; use rustc_session::config::DebugInfo; use rustc_target::spec::SymbolVisibility; @@ -9,10 +9,22 @@ use crate::llvm; /// Helper trait for converting backend-independent types to LLVM-specific /// types, for FFI purposes. +/// +/// FIXME(#147327): These trait/method names were chosen to avoid churn in +/// existing code, but are not great and could probably be made clearer. pub(crate) trait FromGeneric { fn from_generic(other: T) -> Self; } +/// Helper trait for converting LLVM-specific types to backend-independent +/// types, for FFI purposes. +/// +/// FIXME(#147327): These trait/method names were chosen to avoid churn in +/// existing code, but are not great and could probably be made clearer. +pub(crate) trait ToGeneric { + fn to_generic(&self) -> T; +} + impl FromGeneric for llvm::Visibility { fn from_generic(visibility: SymbolVisibility) -> Self { match visibility { @@ -113,3 +125,29 @@ impl FromGeneric for llvm::debuginfo::DebugEmissionKind { } } } + +impl ToGeneric for llvm::TypeKind { + fn to_generic(&self) -> TypeKind { + match self { + Self::Void => TypeKind::Void, + Self::Half => TypeKind::Half, + Self::Float => TypeKind::Float, + Self::Double => TypeKind::Double, + Self::X86_FP80 => TypeKind::X86_FP80, + Self::FP128 => TypeKind::FP128, + Self::PPC_FP128 => TypeKind::PPC_FP128, + Self::Label => TypeKind::Label, + Self::Integer => TypeKind::Integer, + Self::Function => TypeKind::Function, + Self::Struct => TypeKind::Struct, + Self::Array => TypeKind::Array, + Self::Pointer => TypeKind::Pointer, + Self::Vector => TypeKind::Vector, + Self::Metadata => TypeKind::Metadata, + Self::Token => TypeKind::Token, + Self::ScalableVector => TypeKind::ScalableVector, + Self::BFloat => TypeKind::BFloat, + Self::X86_AMX => TypeKind::X86_AMX, + } + } +} diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 2f53a1995248..10cb9390a764 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -363,33 +363,6 @@ pub(crate) enum TypeKind { X86_AMX = 19, } -impl TypeKind { - pub(crate) fn to_generic(self) -> rustc_codegen_ssa::common::TypeKind { - use rustc_codegen_ssa::common::TypeKind as Common; - match self { - Self::Void => Common::Void, - Self::Half => Common::Half, - Self::Float => Common::Float, - Self::Double => Common::Double, - Self::X86_FP80 => Common::X86_FP80, - Self::FP128 => Common::FP128, - Self::PPC_FP128 => Common::PPC_FP128, - Self::Label => Common::Label, - Self::Integer => Common::Integer, - Self::Function => Common::Function, - Self::Struct => Common::Struct, - Self::Array => Common::Array, - Self::Pointer => Common::Pointer, - Self::Vector => Common::Vector, - Self::Metadata => Common::Metadata, - Self::Token => Common::Token, - Self::ScalableVector => Common::ScalableVector, - Self::BFloat => Common::BFloat, - Self::X86_AMX => Common::X86_AMX, - } - } -} - /// LLVMAtomicRmwBinOp #[derive(Copy, Clone)] #[repr(C)] diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 83d7fa0c9153..d8b77369a34f 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -15,7 +15,7 @@ use rustc_target::callconv::{CastTarget, FnAbi}; use crate::abi::{FnAbiLlvmExt, LlvmType}; use crate::common; use crate::context::{CodegenCx, GenericCx, SCx}; -use crate::llvm::{self, FALSE, Metadata, TRUE, ToLlvmBool, Type, Value}; +use crate::llvm::{self, FALSE, Metadata, TRUE, ToGeneric, ToLlvmBool, Type, Value}; use crate::type_of::LayoutLlvmExt; impl PartialEq for Type { From 735a98069309e91b859a5e888ca3403733f2278a Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 6 Oct 2025 13:42:39 +1100 Subject: [PATCH 1024/3801] Move `DIBuilderBox` out of `ffi.rs` --- .../src/debuginfo/di_builder.rs | 31 ++++++++++++++++++- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 3 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 30 ------------------ 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs b/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs index 5d874631ca1a..0b5ef6c68740 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs @@ -1,8 +1,37 @@ +use std::ptr; + use libc::c_uint; use rustc_abi::Align; use crate::llvm::debuginfo::DIBuilder; -use crate::llvm::{self, ToLlvmBool}; +use crate::llvm::{self, Module, ToLlvmBool}; + +/// Owning pointer to a `DIBuilder<'ll>` that will dispose of the builder +/// when dropped. Use `.as_ref()` to get the underlying `&DIBuilder` +/// needed for debuginfo FFI calls. +pub(crate) struct DIBuilderBox<'ll> { + raw: ptr::NonNull>, +} + +impl<'ll> DIBuilderBox<'ll> { + pub(crate) fn new(llmod: &'ll Module) -> Self { + let raw = unsafe { llvm::LLVMCreateDIBuilder(llmod) }; + let raw = ptr::NonNull::new(raw).unwrap(); + Self { raw } + } + + pub(crate) fn as_ref(&self) -> &DIBuilder<'ll> { + // SAFETY: This is an owning pointer, so `&DIBuilder` is valid + // for as long as `&self` is. + unsafe { self.raw.as_ref() } + } +} + +impl<'ll> Drop for DIBuilderBox<'ll> { + fn drop(&mut self) { + unsafe { llvm::LLVMDisposeDIBuilder(self.raw) }; + } +} /// Extension trait for defining safe wrappers and helper methods on /// `&DIBuilder<'ll>`, without requiring it to be defined in the same crate. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index c2c55ee2b64f..1c63bbcd1710 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -38,8 +38,9 @@ use self::namespace::mangled_name_of_instance; use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; use crate::builder::Builder; use crate::common::{AsCCharPtr, CodegenCx}; +use crate::debuginfo::di_builder::DIBuilderBox; use crate::llvm::debuginfo::{ - DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, + DIArray, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DITemplateTypeParameter, DIType, DIVariable, }; use crate::llvm::{self, Value}; diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 10cb9390a764..a86b4cc38915 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -711,12 +711,9 @@ unsafe extern "C" { pub(crate) type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); pub(crate) mod debuginfo { - use std::ptr; - use bitflags::bitflags; use super::{InvariantOpaque, Metadata}; - use crate::llvm::{self, Module}; /// Opaque target type for references to an LLVM debuginfo builder. /// @@ -729,33 +726,6 @@ pub(crate) mod debuginfo { #[repr(C)] pub(crate) struct DIBuilder<'ll>(InvariantOpaque<'ll>); - /// Owning pointer to a `DIBuilder<'ll>` that will dispose of the builder - /// when dropped. Use `.as_ref()` to get the underlying `&DIBuilder` - /// needed for debuginfo FFI calls. - pub(crate) struct DIBuilderBox<'ll> { - raw: ptr::NonNull>, - } - - impl<'ll> DIBuilderBox<'ll> { - pub(crate) fn new(llmod: &'ll Module) -> Self { - let raw = unsafe { llvm::LLVMCreateDIBuilder(llmod) }; - let raw = ptr::NonNull::new(raw).unwrap(); - Self { raw } - } - - pub(crate) fn as_ref(&self) -> &DIBuilder<'ll> { - // SAFETY: This is an owning pointer, so `&DIBuilder` is valid - // for as long as `&self` is. - unsafe { self.raw.as_ref() } - } - } - - impl<'ll> Drop for DIBuilderBox<'ll> { - fn drop(&mut self) { - unsafe { llvm::LLVMDisposeDIBuilder(self.raw) }; - } - } - pub(crate) type DIDescriptor = Metadata; pub(crate) type DILocation = Metadata; pub(crate) type DIScope = DIDescriptor; From b00739765c89f9182a8284c1718de7c858217869 Mon Sep 17 00:00:00 2001 From: Jane Losare-Lusby Date: Tue, 16 Dec 2025 13:25:27 -0800 Subject: [PATCH 1025/3801] Update provider API docs --- library/core/src/error.rs | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 9ca91ee009ee..011d6ac4a1c7 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -205,6 +205,56 @@ pub trait Error: Debug + Display { /// assert!(request_ref::(dyn_error).is_none()); /// } /// ``` + /// + /// # Delegating Impls + /// + ///

+ /// + /// This method should expose context from the current piece of the source chain only, not from + /// sources that are exposed in the chain of sources. Delegating `provide` implementations cause + /// the same context to be provided by multiple errors in the chain of sources which can cause + /// unintended duplication of information in error reports or require heuristics to deduplicate. + /// + /// In other words, the following implementation pattern for `provide` is discouraged and should + /// not be used for [`Error`] types exposed in public APIs to third parties. + /// + /// ```rust + /// # #![feature(error_generic_member_access)] + /// # use core::fmt; + /// # use core::error::Request; + /// # #[derive(Debug)] + /// struct MyError { + /// source: Error, + /// } + /// # #[derive(Debug)] + /// # struct Error; + /// # impl fmt::Display for Error { + /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + /// # write!(f, "Example Source Error") + /// # } + /// # } + /// # impl fmt::Display for MyError { + /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + /// # write!(f, "Example Error") + /// # } + /// # } + /// # impl std::error::Error for Error { } + /// + /// impl std::error::Error for MyError { + /// fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + /// Some(&self.source) + /// } + /// + /// fn provide<'a>(&'a self, request: &mut Request<'a>) { + /// self.source.provide(request) // <--- Discouraged + /// } + /// } + /// ``` #[unstable(feature = "error_generic_member_access", issue = "99301")] #[allow(unused_variables)] fn provide<'a>(&'a self, request: &mut Request<'a>) {} From ef494feccca725d5e5148a721e64a2655763be6f Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 19 Dec 2025 04:58:34 +0000 Subject: [PATCH 1026/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 526a91cbcc4601b92b0587405015e07b9c0d79f6. --- 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 11c138c28c24..d4fbfacf4eda 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -686f9cefc37c5bdec069a75357f0277b390657ca +526a91cbcc4601b92b0587405015e07b9c0d79f6 From 8870bb8d9c07f0c2e110dfca17794eef0c474eae Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 19 Dec 2025 05:07:13 +0000 Subject: [PATCH 1027/3801] fmt --- src/tools/miri/tests/fail/closures/deref-in-pattern.rs | 7 ++++--- .../miri/tests/fail/closures/deref-in-pattern.stderr | 2 +- src/tools/miri/tests/fail/closures/partial-pattern.rs | 9 +++++---- .../miri/tests/fail/closures/partial-pattern.stderr | 2 +- .../miri/tests/fail/closures/uninhabited-variant.rs | 9 +++++---- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/tools/miri/tests/fail/closures/deref-in-pattern.rs b/src/tools/miri/tests/fail/closures/deref-in-pattern.rs index c729469c78b0..27915a9a489b 100644 --- a/src/tools/miri/tests/fail/closures/deref-in-pattern.rs +++ b/src/tools/miri/tests/fail/closures/deref-in-pattern.rs @@ -9,12 +9,13 @@ fn main() { // the inner reference is dangling let x: &&u32 = unsafe { let x: u32 = 42; - &&* &raw const x + &&*&raw const x }; - let _ = || { //~ ERROR: encountered a dangling reference + //~v ERROR: encountered a dangling reference + let _ = || { match x { - &&_y => {}, + &&_y => {} } }; } diff --git a/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr b/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr index 1264f4e3fb95..fae2d286c487 100644 --- a/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr +++ b/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr @@ -4,7 +4,7 @@ error: Undefined Behavior: constructing invalid value: encountered a dangling re LL | let _ = || { | _____________^ LL | | match x { -LL | | &&_y => {}, +LL | | &&_y => {} LL | | } LL | | }; | |_____^ Undefined Behavior occurred here diff --git a/src/tools/miri/tests/fail/closures/partial-pattern.rs b/src/tools/miri/tests/fail/closures/partial-pattern.rs index cb6446208180..f70fe096fd80 100644 --- a/src/tools/miri/tests/fail/closures/partial-pattern.rs +++ b/src/tools/miri/tests/fail/closures/partial-pattern.rs @@ -15,14 +15,15 @@ fn main() { let x: &(&u32, &u32) = unsafe { let a = 21; let b = 37; - let ra = &* &raw const a; - let rb = &* &raw const b; + let ra = &*&raw const a; + let rb = &*&raw const b; &(ra, rb) }; - let _ = || { //~ ERROR: encountered a dangling reference + //~v ERROR: encountered a dangling reference + let _ = || { match x { - (&_y, _) => {}, + (&_y, _) => {} } }; } diff --git a/src/tools/miri/tests/fail/closures/partial-pattern.stderr b/src/tools/miri/tests/fail/closures/partial-pattern.stderr index 5b7ee35ecc73..8dea4d4d8c64 100644 --- a/src/tools/miri/tests/fail/closures/partial-pattern.stderr +++ b/src/tools/miri/tests/fail/closures/partial-pattern.stderr @@ -4,7 +4,7 @@ error: Undefined Behavior: constructing invalid value: encountered a dangling re LL | let _ = || { | _____________^ LL | | match x { -LL | | (&_y, _) => {}, +LL | | (&_y, _) => {} LL | | } LL | | }; | |_____^ Undefined Behavior occurred here diff --git a/src/tools/miri/tests/fail/closures/uninhabited-variant.rs b/src/tools/miri/tests/fail/closures/uninhabited-variant.rs index 9c50fdc13a35..0a2dfe9a7f64 100644 --- a/src/tools/miri/tests/fail/closures/uninhabited-variant.rs +++ b/src/tools/miri/tests/fail/closures/uninhabited-variant.rs @@ -5,9 +5,9 @@ #[repr(C)] #[allow(dead_code)] enum E { - V0, // discriminant: 0 - V1, // 1 - V2(!), // 2 + V0, // discriminant: 0 + V1, // 1 + V2(!), // 2 } fn main() { @@ -20,7 +20,8 @@ fn main() { // After rust-lang/rust#138961, constructing the closure performs a reborrow of r. // Nevertheless, the discriminant is only actually inspected when the closure // is called. - match r { //~ ERROR: read discriminant of an uninhabited enum variant + match r { + //~^ ERROR: read discriminant of an uninhabited enum variant E::V0 => {} E::V1 => {} E::V2(_) => {} From 7e63bc07de1e638ceab5894f9163fdd8dc289359 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 19 Dec 2025 17:30:47 +1100 Subject: [PATCH 1028/3801] mir_build: Remove unnecessary lifetime from `PatCtxt` It turns out that lifetime `'a` is just `'tcx` in disguise. --- .../src/thir/pattern/const_to_pat.rs | 4 ++-- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 6316ccf1b8c5..c3c4c455b965 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -28,7 +28,7 @@ use crate::errors::{ PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, UnsizedPattern, }; -impl<'a, 'tcx> PatCtxt<'a, 'tcx> { +impl<'tcx> PatCtxt<'tcx> { /// Converts a constant to a pattern (if possible). /// This means aggregate values (like structs and enums) are converted /// to a pattern that matches the value (as if you'd compared via structural equality). @@ -64,7 +64,7 @@ struct ConstToPat<'tcx> { } impl<'tcx> ConstToPat<'tcx> { - fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self { + fn new(pat_ctxt: &PatCtxt<'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self { trace!(?pat_ctxt.typeck_results.hir_owner); ConstToPat { tcx: pat_ctxt.tcx, typing_env: pat_ctxt.typing_env, span, id, c } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 02e6f8d6ce71..ca43bd00185c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -30,19 +30,20 @@ pub(crate) use self::check_match::check_match; use self::migration::PatMigration; use crate::errors::*; -struct PatCtxt<'a, 'tcx> { +/// Context for lowering HIR patterns to THIR patterns. +struct PatCtxt<'tcx> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, - typeck_results: &'a ty::TypeckResults<'tcx>, + typeck_results: &'tcx ty::TypeckResults<'tcx>, /// Used by the Rust 2024 migration lint. - rust_2024_migration: Option>, + rust_2024_migration: Option>, } -pub(super) fn pat_from_hir<'a, 'tcx>( +pub(super) fn pat_from_hir<'tcx>( tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, - typeck_results: &'a ty::TypeckResults<'tcx>, + typeck_results: &'tcx ty::TypeckResults<'tcx>, pat: &'tcx hir::Pat<'tcx>, ) -> Box> { let mut pcx = PatCtxt { @@ -62,7 +63,7 @@ pub(super) fn pat_from_hir<'a, 'tcx>( result } -impl<'a, 'tcx> PatCtxt<'a, 'tcx> { +impl<'tcx> PatCtxt<'tcx> { fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box> { let adjustments: &[PatAdjustment<'tcx>] = self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v); From 7d88ed1f19f25b3e2abaa4515aaeee539983624d Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 19 Dec 2025 10:25:43 +0100 Subject: [PATCH 1029/3801] Use actions/checkout@v6 consistently Two places were not updated from v5 to v6. --- .github/workflows/clippy_dev.yml | 2 +- .github/workflows/clippy_pr.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/clippy_dev.yml b/.github/workflows/clippy_dev.yml index d530eb6c73a3..3a99d65233d3 100644 --- a/.github/workflows/clippy_dev.yml +++ b/.github/workflows/clippy_dev.yml @@ -16,7 +16,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: # Unsetting this would make so that any malicious package could get our Github Token persist-credentials: false diff --git a/.github/workflows/clippy_pr.yml b/.github/workflows/clippy_pr.yml index d91c638a8fb5..f9e882d9757c 100644 --- a/.github/workflows/clippy_pr.yml +++ b/.github/workflows/clippy_pr.yml @@ -24,7 +24,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: # Unsetting this would make so that any malicious package could get our Github Token persist-credentials: false From 76457e60d76612856d44674c1103a3af5372cae6 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 19 Dec 2025 10:38:46 +0100 Subject: [PATCH 1030/3801] Reenable some tests on "apple" targets Those tests appear to be passing on "apple" targets as well. --- tests/ui/crashes/ice-7410.rs | 2 +- tests/ui/def_id_nocore.rs | 2 -- tests/ui/def_id_nocore.stderr | 2 +- tests/ui/empty_loop_no_std.rs | 2 -- tests/ui/empty_loop_no_std.stderr | 2 +- 5 files changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/ui/crashes/ice-7410.rs b/tests/ui/crashes/ice-7410.rs index 71f00fb9aede..7b39f7ffc01a 100644 --- a/tests/ui/crashes/ice-7410.rs +++ b/tests/ui/crashes/ice-7410.rs @@ -1,6 +1,6 @@ //@ check-pass //@compile-flags: -Clink-arg=-nostartfiles -//@ignore-target: apple windows +//@ignore-target: windows #![crate_type = "lib"] #![no_std] diff --git a/tests/ui/def_id_nocore.rs b/tests/ui/def_id_nocore.rs index 5c13d8622767..6aa023a8d450 100644 --- a/tests/ui/def_id_nocore.rs +++ b/tests/ui/def_id_nocore.rs @@ -1,5 +1,3 @@ -//@ignore-target: apple - #![feature(no_core, lang_items)] #![no_core] #![allow(clippy::missing_safety_doc)] diff --git a/tests/ui/def_id_nocore.stderr b/tests/ui/def_id_nocore.stderr index 175dd0754081..bf022fb56a36 100644 --- a/tests/ui/def_id_nocore.stderr +++ b/tests/ui/def_id_nocore.stderr @@ -1,5 +1,5 @@ error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/def_id_nocore.rs:33:19 + --> tests/ui/def_id_nocore.rs:31:19 | LL | pub fn as_ref(self) -> &'static str { | ^^^^ diff --git a/tests/ui/empty_loop_no_std.rs b/tests/ui/empty_loop_no_std.rs index 6407bd678f9c..1ea96abbcd8b 100644 --- a/tests/ui/empty_loop_no_std.rs +++ b/tests/ui/empty_loop_no_std.rs @@ -1,6 +1,4 @@ //@compile-flags: -Clink-arg=-nostartfiles -//@ignore-target: apple - #![warn(clippy::empty_loop)] #![crate_type = "lib"] #![no_std] diff --git a/tests/ui/empty_loop_no_std.stderr b/tests/ui/empty_loop_no_std.stderr index f36fb9d9e3f2..e34b50ed1aef 100644 --- a/tests/ui/empty_loop_no_std.stderr +++ b/tests/ui/empty_loop_no_std.stderr @@ -1,5 +1,5 @@ error: empty `loop {}` wastes CPU cycles - --> tests/ui/empty_loop_no_std.rs:10:5 + --> tests/ui/empty_loop_no_std.rs:8:5 | LL | loop {} | ^^^^^^^ From bd0341471abbf02331061d76ca54fe801f95fb52 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 19 Dec 2025 11:20:38 +0100 Subject: [PATCH 1031/3801] Post `needless_continue` diagnostic on the right node --- clippy_lints/src/needless_continue.rs | 31 +++++++++++------------- tests/ui/needless_continue.rs | 35 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index 55208ae708b9..d1d0d31ed91a 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -1,9 +1,9 @@ -use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::higher; use clippy_utils::source::{indent_of, snippet_block, snippet_with_context}; use rustc_ast::Label; use rustc_errors::Applicability; -use rustc_hir::{Block, Expr, ExprKind, LoopSource, StmtKind}; +use rustc_hir::{Block, Expr, ExprKind, HirId, LoopSource, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::declare_lint_pass; use rustc_span::{ExpnKind, Span}; @@ -336,14 +336,9 @@ fn emit_warning(cx: &LateContext<'_>, data: &LintData<'_>, header: &str, typ: Li data.if_expr, ), }; - span_lint_and_help( - cx, - NEEDLESS_CONTINUE, - expr.span, - message, - None, - format!("{header}\n{snip}"), - ); + span_lint_hir_and_then(cx, NEEDLESS_CONTINUE, expr.hir_id, expr.span, message, |diag| { + diag.help(format!("{header}\n{snip}")); + }); } fn suggestion_snippet_for_continue_inside_if(cx: &LateContext<'_>, data: &LintData<'_>) -> String { @@ -424,11 +419,11 @@ fn suggestion_snippet_for_continue_inside_else(cx: &LateContext<'_>, data: &Lint fn check_last_stmt_in_expr(cx: &LateContext<'_>, inner_expr: &Expr<'_>, func: &F) where - F: Fn(Option<&Label>, Span), + F: Fn(HirId, Option<&Label>, Span), { match inner_expr.kind { ExprKind::Continue(continue_label) => { - func(continue_label.label.as_ref(), inner_expr.span); + func(inner_expr.hir_id, continue_label.label.as_ref(), inner_expr.span); }, ExprKind::If(_, then_block, else_block) if let ExprKind::Block(then_block, _) = then_block.kind => { check_last_stmt_in_block(cx, then_block, func); @@ -454,7 +449,7 @@ where fn check_last_stmt_in_block(cx: &LateContext<'_>, b: &Block<'_>, func: &F) where - F: Fn(Option<&Label>, Span), + F: Fn(HirId, Option<&Label>, Span), { if let Some(expr) = b.expr { check_last_stmt_in_expr(cx, expr, func); @@ -470,15 +465,17 @@ where fn check_and_warn(cx: &LateContext<'_>, expr: &Expr<'_>) { with_loop_block(expr, |loop_block, label| { - let p = |continue_label: Option<&Label>, span: Span| { + let p = |continue_hir_id, continue_label: Option<&Label>, span: Span| { if compare_labels(label, continue_label) { - span_lint_and_help( + span_lint_hir_and_then( cx, NEEDLESS_CONTINUE, + continue_hir_id, span, MSG_REDUNDANT_CONTINUE_EXPRESSION, - None, - DROP_CONTINUE_EXPRESSION_MSG, + |diag| { + diag.help(DROP_CONTINUE_EXPRESSION_MSG); + }, ); } }; diff --git a/tests/ui/needless_continue.rs b/tests/ui/needless_continue.rs index 88b7905e7fa8..3275dddf1a0f 100644 --- a/tests/ui/needless_continue.rs +++ b/tests/ui/needless_continue.rs @@ -342,3 +342,38 @@ fn issue15548() { } } } + +fn issue16256() { + fn some_condition() -> bool { + true + } + fn another_condition() -> bool { + true + } + + for _ in 0..5 { + if some_condition() { + // ... + continue; + } + + if another_condition() { + // ... + // "this `continue` expression is redundant" is posted on + // the `continue` node. + #[expect(clippy::needless_continue)] + continue; + } + } + + for _ in 0..5 { + // "This `else` block is redundant" is posted on the + // `else` node. + #[expect(clippy::needless_continue)] + if some_condition() { + // ... + } else { + continue; + } + } +} From c040bb1c7eeb21e5e9dfb2843eba75a8168e0791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 19 Dec 2025 12:36:26 +0100 Subject: [PATCH 1032/3801] move eii tests --- .../{wrong_target.rs => attribute_targets.rs} | 0 ...target.stderr => attribute_targets.stderr} | 36 +++++++++---------- tests/ui/eii/{ => type_checking}/subtype_1.rs | 0 .../eii/{ => type_checking}/subtype_1.stderr | 0 tests/ui/eii/{ => type_checking}/subtype_2.rs | 0 .../eii/{ => type_checking}/subtype_2.stderr | 0 tests/ui/eii/{ => type_checking}/subtype_3.rs | 0 tests/ui/eii/{ => type_checking}/subtype_4.rs | 0 .../eii/{ => type_checking}/wrong_ret_ty.rs | 0 .../{ => type_checking}/wrong_ret_ty.stderr | 0 tests/ui/eii/{ => type_checking}/wrong_ty.rs | 0 .../eii/{ => type_checking}/wrong_ty.stderr | 0 .../ui/eii/{ => type_checking}/wrong_ty_2.rs | 0 .../eii/{ => type_checking}/wrong_ty_2.stderr | 0 14 files changed, 18 insertions(+), 18 deletions(-) rename tests/ui/eii/{wrong_target.rs => attribute_targets.rs} (100%) rename tests/ui/eii/{wrong_target.stderr => attribute_targets.stderr} (67%) rename tests/ui/eii/{ => type_checking}/subtype_1.rs (100%) rename tests/ui/eii/{ => type_checking}/subtype_1.stderr (100%) rename tests/ui/eii/{ => type_checking}/subtype_2.rs (100%) rename tests/ui/eii/{ => type_checking}/subtype_2.stderr (100%) rename tests/ui/eii/{ => type_checking}/subtype_3.rs (100%) rename tests/ui/eii/{ => type_checking}/subtype_4.rs (100%) rename tests/ui/eii/{ => type_checking}/wrong_ret_ty.rs (100%) rename tests/ui/eii/{ => type_checking}/wrong_ret_ty.stderr (100%) rename tests/ui/eii/{ => type_checking}/wrong_ty.rs (100%) rename tests/ui/eii/{ => type_checking}/wrong_ty.stderr (100%) rename tests/ui/eii/{ => type_checking}/wrong_ty_2.rs (100%) rename tests/ui/eii/{ => type_checking}/wrong_ty_2.stderr (100%) diff --git a/tests/ui/eii/wrong_target.rs b/tests/ui/eii/attribute_targets.rs similarity index 100% rename from tests/ui/eii/wrong_target.rs rename to tests/ui/eii/attribute_targets.rs diff --git a/tests/ui/eii/wrong_target.stderr b/tests/ui/eii/attribute_targets.stderr similarity index 67% rename from tests/ui/eii/wrong_target.stderr rename to tests/ui/eii/attribute_targets.stderr index 9b27f49fb302..bf04c323c95c 100644 --- a/tests/ui/eii/wrong_target.stderr +++ b/tests/ui/eii/attribute_targets.stderr @@ -1,107 +1,107 @@ error: `#[foo]` is only valid on functions - --> $DIR/wrong_target.rs:7:1 + --> $DIR/attribute_targets.rs:7:1 | LL | #[foo] | ^^^^^^ error: `#[eii]` is only valid on functions - --> $DIR/wrong_target.rs:9:1 + --> $DIR/attribute_targets.rs:9:1 | LL | #[eii] | ^^^^^^ error: `#[foo]` is only valid on functions - --> $DIR/wrong_target.rs:13:1 + --> $DIR/attribute_targets.rs:13:1 | LL | #[foo] | ^^^^^^ error: `#[eii]` is only valid on functions - --> $DIR/wrong_target.rs:15:1 + --> $DIR/attribute_targets.rs:15:1 | LL | #[eii] | ^^^^^^ error: `#[foo]` is only valid on functions - --> $DIR/wrong_target.rs:21:1 + --> $DIR/attribute_targets.rs:21:1 | LL | #[foo] | ^^^^^^ error: `#[eii]` is only valid on functions - --> $DIR/wrong_target.rs:23:1 + --> $DIR/attribute_targets.rs:23:1 | LL | #[eii] | ^^^^^^ error: `#[foo]` is only valid on functions - --> $DIR/wrong_target.rs:27:1 + --> $DIR/attribute_targets.rs:27:1 | LL | #[foo] | ^^^^^^ error: `#[eii]` is only valid on functions - --> $DIR/wrong_target.rs:29:1 + --> $DIR/attribute_targets.rs:29:1 | LL | #[eii] | ^^^^^^ error: `#[foo]` is only valid on functions - --> $DIR/wrong_target.rs:32:5 + --> $DIR/attribute_targets.rs:32:5 | LL | #[foo] | ^^^^^^ error: `#[eii]` is only valid on functions - --> $DIR/wrong_target.rs:34:5 + --> $DIR/attribute_targets.rs:34:5 | LL | #[eii] | ^^^^^^ error: `#[foo]` is only valid on functions - --> $DIR/wrong_target.rs:39:1 + --> $DIR/attribute_targets.rs:39:1 | LL | #[foo] | ^^^^^^ error: `#[eii]` is only valid on functions - --> $DIR/wrong_target.rs:41:1 + --> $DIR/attribute_targets.rs:41:1 | LL | #[eii] | ^^^^^^ error: `#[foo]` is only valid on functions - --> $DIR/wrong_target.rs:44:5 + --> $DIR/attribute_targets.rs:44:5 | LL | #[foo] | ^^^^^^ error: `#[eii]` is only valid on functions - --> $DIR/wrong_target.rs:46:5 + --> $DIR/attribute_targets.rs:46:5 | LL | #[eii] | ^^^^^^ error: `#[foo]` is only valid on functions - --> $DIR/wrong_target.rs:51:1 + --> $DIR/attribute_targets.rs:51:1 | LL | #[foo] | ^^^^^^ error: `#[eii]` is only valid on functions - --> $DIR/wrong_target.rs:53:1 + --> $DIR/attribute_targets.rs:53:1 | LL | #[eii] | ^^^^^^ error: `#[foo]` is only valid on functions - --> $DIR/wrong_target.rs:56:5 + --> $DIR/attribute_targets.rs:56:5 | LL | #[foo] | ^^^^^^ error: `#[eii]` is only valid on functions - --> $DIR/wrong_target.rs:58:5 + --> $DIR/attribute_targets.rs:58:5 | LL | #[eii] | ^^^^^^ diff --git a/tests/ui/eii/subtype_1.rs b/tests/ui/eii/type_checking/subtype_1.rs similarity index 100% rename from tests/ui/eii/subtype_1.rs rename to tests/ui/eii/type_checking/subtype_1.rs diff --git a/tests/ui/eii/subtype_1.stderr b/tests/ui/eii/type_checking/subtype_1.stderr similarity index 100% rename from tests/ui/eii/subtype_1.stderr rename to tests/ui/eii/type_checking/subtype_1.stderr diff --git a/tests/ui/eii/subtype_2.rs b/tests/ui/eii/type_checking/subtype_2.rs similarity index 100% rename from tests/ui/eii/subtype_2.rs rename to tests/ui/eii/type_checking/subtype_2.rs diff --git a/tests/ui/eii/subtype_2.stderr b/tests/ui/eii/type_checking/subtype_2.stderr similarity index 100% rename from tests/ui/eii/subtype_2.stderr rename to tests/ui/eii/type_checking/subtype_2.stderr diff --git a/tests/ui/eii/subtype_3.rs b/tests/ui/eii/type_checking/subtype_3.rs similarity index 100% rename from tests/ui/eii/subtype_3.rs rename to tests/ui/eii/type_checking/subtype_3.rs diff --git a/tests/ui/eii/subtype_4.rs b/tests/ui/eii/type_checking/subtype_4.rs similarity index 100% rename from tests/ui/eii/subtype_4.rs rename to tests/ui/eii/type_checking/subtype_4.rs diff --git a/tests/ui/eii/wrong_ret_ty.rs b/tests/ui/eii/type_checking/wrong_ret_ty.rs similarity index 100% rename from tests/ui/eii/wrong_ret_ty.rs rename to tests/ui/eii/type_checking/wrong_ret_ty.rs diff --git a/tests/ui/eii/wrong_ret_ty.stderr b/tests/ui/eii/type_checking/wrong_ret_ty.stderr similarity index 100% rename from tests/ui/eii/wrong_ret_ty.stderr rename to tests/ui/eii/type_checking/wrong_ret_ty.stderr diff --git a/tests/ui/eii/wrong_ty.rs b/tests/ui/eii/type_checking/wrong_ty.rs similarity index 100% rename from tests/ui/eii/wrong_ty.rs rename to tests/ui/eii/type_checking/wrong_ty.rs diff --git a/tests/ui/eii/wrong_ty.stderr b/tests/ui/eii/type_checking/wrong_ty.stderr similarity index 100% rename from tests/ui/eii/wrong_ty.stderr rename to tests/ui/eii/type_checking/wrong_ty.stderr diff --git a/tests/ui/eii/wrong_ty_2.rs b/tests/ui/eii/type_checking/wrong_ty_2.rs similarity index 100% rename from tests/ui/eii/wrong_ty_2.rs rename to tests/ui/eii/type_checking/wrong_ty_2.rs diff --git a/tests/ui/eii/wrong_ty_2.stderr b/tests/ui/eii/type_checking/wrong_ty_2.stderr similarity index 100% rename from tests/ui/eii/wrong_ty_2.stderr rename to tests/ui/eii/type_checking/wrong_ty_2.stderr From 6c4c4384e8f66476214d56b82313c39472c8215e Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 19 Dec 2025 11:37:22 +0000 Subject: [PATCH 1033/3801] destabilise target-spec-json --- compiler/rustc_driver_impl/src/lib.rs | 3 ++- compiler/rustc_interface/src/interface.rs | 1 + compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_session/src/config.rs | 3 ++- compiler/rustc_session/src/session.rs | 7 +++++-- compiler/rustc_target/src/spec/mod.rs | 15 ++++++++++++--- tests/run-make/target-specs/rmake.rs | 16 +++++++++++++++- 7 files changed, 38 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 63fc9c96f450..5a30e7869f86 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1124,9 +1124,10 @@ fn get_backend_from_raw_matches( let backend_name = debug_flags .iter() .find_map(|x| x.strip_prefix("codegen-backend=").or(x.strip_prefix("codegen_backend="))); + let unstable_options = debug_flags.iter().find(|x| *x == "unstable-options").is_some(); let target = parse_target_triple(early_dcx, matches); let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from)); - let target = config::build_target_config(early_dcx, &target, sysroot.path()); + let target = config::build_target_config(early_dcx, &target, sysroot.path(), unstable_options); get_codegen_backend(early_dcx, &sysroot, backend_name, &target) } diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index c0f8f33692e8..863c56f1a54f 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -427,6 +427,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se &early_dcx, &config.opts.target_triple, config.opts.sysroot.path(), + config.opts.unstable_opts.unstable_options, ); let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); let path_mapping = config.opts.file_path_mapping(); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8dab3a7f37f5..0ea7232cb7a9 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -46,6 +46,7 @@ where &early_dcx, &sessopts.target_triple, sessopts.sysroot.path(), + sessopts.unstable_opts.unstable_options, ); let hash_kind = sessopts.unstable_opts.src_hash_algorithm(&target); let checksum_hash_kind = sessopts.unstable_opts.checksum_hash_algorithm(); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a3a97dfec61d..74826d053101 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1586,8 +1586,9 @@ pub fn build_target_config( early_dcx: &EarlyDiagCtxt, target: &TargetTuple, sysroot: &Path, + unstable_options: bool, ) -> Target { - match Target::search(target, sysroot) { + match Target::search(target, sysroot, unstable_options) { Ok((target, warnings)) => { for warning in warnings.warning_messages() { early_dcx.early_warn(warning) diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 1a0ec600af47..1d5b36fc61b8 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1002,8 +1002,11 @@ pub fn build_session( } let host_triple = TargetTuple::from_tuple(config::host_tuple()); - let (host, target_warnings) = Target::search(&host_triple, sopts.sysroot.path()) - .unwrap_or_else(|e| dcx.handle().fatal(format!("Error loading host specification: {e}"))); + let (host, target_warnings) = + Target::search(&host_triple, sopts.sysroot.path(), sopts.unstable_opts.unstable_options) + .unwrap_or_else(|e| { + dcx.handle().fatal(format!("Error loading host specification: {e}")) + }); for warning in target_warnings.warning_messages() { dcx.handle().warn(warning) } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 3d500694c978..d6d607fb18d6 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3299,10 +3299,19 @@ impl Target { pub fn search( target_tuple: &TargetTuple, sysroot: &Path, + unstable_options: bool, ) -> Result<(Target, TargetWarnings), String> { use std::{env, fs}; - fn load_file(path: &Path) -> Result<(Target, TargetWarnings), String> { + fn load_file( + path: &Path, + unstable_options: bool, + ) -> Result<(Target, TargetWarnings), String> { + if !unstable_options { + return Err( + "custom targets are unstable and require `-Zunstable-options`".to_string() + ); + } let contents = fs::read_to_string(path).map_err(|e| e.to_string())?; Target::from_json(&contents) } @@ -3326,7 +3335,7 @@ impl Target { for dir in env::split_paths(&target_path) { let p = dir.join(&path); if p.is_file() { - return load_file(&p); + return load_file(&p, unstable_options); } } @@ -3339,7 +3348,7 @@ impl Target { Path::new("target.json"), ]); if p.is_file() { - return load_file(&p); + return load_file(&p, unstable_options); } Err(format!("could not find specification for target {target_tuple:?}")) diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs index 7c30a5b21b33..69292af5fd69 100644 --- a/tests/run-make/target-specs/rmake.rs +++ b/tests/run-make/target-specs/rmake.rs @@ -15,11 +15,20 @@ fn main() { .run_fail() .assert_stderr_contains("error loading target specification"); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("my-incomplete-platform.json") .run_fail() .assert_stderr_contains("missing field `llvm-target`"); + let test_platform = rustc() + .input("foo.rs") + .target("my-x86_64-unknown-linux-gnu-platform") + .crate_type("lib") + .emit("asm") + .run_fail() + .assert_stderr_contains("custom targets are unstable and require `-Zunstable-options`"); rustc() + .arg("-Zunstable-options") .env("RUST_TARGET_PATH", ".") .input("foo.rs") .target("my-awesome-platform") @@ -27,6 +36,7 @@ fn main() { .emit("asm") .run(); rustc() + .arg("-Zunstable-options") .env("RUST_TARGET_PATH", ".") .input("foo.rs") .target("my-x86_64-unknown-linux-gnu-platform") @@ -52,27 +62,31 @@ fn main() { .actual_text("test-platform-2", test_platform_2) .run(); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("endianness-mismatch") .run_fail() .assert_stderr_contains(r#""data-layout" claims architecture is little-endian"#); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("mismatching-data-layout") .crate_type("lib") .run_fail() .assert_stderr_contains("data-layout for target"); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("require-explicit-cpu") .crate_type("lib") .run_fail() .assert_stderr_contains("target requires explicitly specifying a cpu"); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("require-explicit-cpu") .crate_type("lib") .arg("-Ctarget-cpu=generic") .run(); - rustc().target("require-explicit-cpu").arg("--print=target-cpus").run(); + rustc().arg("-Zunstable-options").target("require-explicit-cpu").print("target-cpus").run(); } From 3e4944d573af5bae3def57572fb0ed16e152ca88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= Date: Mon, 8 Dec 2025 20:47:53 +0100 Subject: [PATCH 1034/3801] Split runtime global logic and cache kernel specific one --- compiler/rustc_codegen_llvm/src/base.rs | 16 +- .../src/builder/gpu_offload.rs | 186 ++++++++++++------ compiler/rustc_codegen_llvm/src/context.rs | 9 + compiler/rustc_codegen_llvm/src/intrinsic.rs | 25 ++- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- tests/codegen-llvm/gpu_offload/gpu_host.rs | 18 +- 6 files changed, 171 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 6cbddfec4631..16455b4c79cd 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -23,13 +23,14 @@ use rustc_middle::dep_graph; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs}; use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::TyCtxt; -use rustc_session::config::DebugInfo; +use rustc_session::config::{DebugInfo, Offload}; use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; use super::ModuleLlvm; use crate::attributes; use crate::builder::Builder; +use crate::builder::gpu_offload::OffloadGlobals; use crate::context::CodegenCx; use crate::llvm::{self, Value}; @@ -85,6 +86,19 @@ pub(crate) fn compile_codegen_unit( let llvm_module = ModuleLlvm::new(tcx, cgu_name.as_str()); { let mut cx = CodegenCx::new(tcx, cgu, &llvm_module); + + // Declare and store globals shared by all offload kernels + // + // These globals are left in the LLVM-IR host module so all kernels can access them. + // They are necessary for correct offload execution. We do this here to simplify the + // `offload` intrinsic, avoiding the need for tracking whether it's the first + // intrinsic call or not. + if cx.sess().opts.unstable_opts.offload.contains(&Offload::Enable) + && !cx.sess().target.is_like_gpu + { + cx.offload_globals.replace(Some(OffloadGlobals::declare(&cx))); + } + let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx); for &(mono_item, data) in &mono_items { mono_item.predefine::>( diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index 5d1ddd057d88..f28037fb9cff 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -2,17 +2,76 @@ use std::ffi::CString; use llvm::Linkage::*; use rustc_abi::Align; -use rustc_codegen_ssa::traits::BaseTypeCodegenMethods; +use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods}; use rustc_middle::ty::offload_meta::OffloadMetadata; -use crate::builder::SBuilder; +use crate::builder::Builder; +use crate::common::CodegenCx; use crate::llvm::AttributePlace::Function; -use crate::llvm::{self, BasicBlock, Linkage, Type, Value}; +use crate::llvm::{self, Linkage, Type, Value}; use crate::{SimpleCx, attributes}; +// LLVM kernel-independent globals required for offloading +pub(crate) struct OffloadGlobals<'ll> { + pub launcher_fn: &'ll llvm::Value, + pub launcher_ty: &'ll llvm::Type, + + pub bin_desc: &'ll llvm::Type, + + pub kernel_args_ty: &'ll llvm::Type, + + pub offload_entry_ty: &'ll llvm::Type, + + pub begin_mapper: &'ll llvm::Value, + pub end_mapper: &'ll llvm::Value, + pub mapper_fn_ty: &'ll llvm::Type, + + pub ident_t_global: &'ll llvm::Value, + + pub register_lib: &'ll llvm::Value, + pub unregister_lib: &'ll llvm::Value, + pub init_rtls: &'ll llvm::Value, +} + +impl<'ll> OffloadGlobals<'ll> { + pub(crate) fn declare(cx: &CodegenCx<'ll, '_>) -> Self { + let (launcher_fn, launcher_ty) = generate_launcher(cx); + let kernel_args_ty = KernelArgsTy::new_decl(cx); + let offload_entry_ty = TgtOffloadEntry::new_decl(cx); + let (begin_mapper, _, end_mapper, mapper_fn_ty) = gen_tgt_data_mappers(cx); + let ident_t_global = generate_at_one(cx); + + let tptr = cx.type_ptr(); + let ti32 = cx.type_i32(); + let tgt_bin_desc_ty = vec![ti32, tptr, tptr, tptr]; + let bin_desc = cx.type_named_struct("struct.__tgt_bin_desc"); + cx.set_struct_body(bin_desc, &tgt_bin_desc_ty, false); + + let register_lib = declare_offload_fn(&cx, "__tgt_register_lib", mapper_fn_ty); + let unregister_lib = declare_offload_fn(&cx, "__tgt_unregister_lib", mapper_fn_ty); + let init_ty = cx.type_func(&[], cx.type_void()); + let init_rtls = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); + + OffloadGlobals { + launcher_fn, + launcher_ty, + bin_desc, + kernel_args_ty, + offload_entry_ty, + begin_mapper, + end_mapper, + mapper_fn_ty, + ident_t_global, + register_lib, + unregister_lib, + init_rtls, + } + } +} + // ; Function Attrs: nounwind // declare i32 @__tgt_target_kernel(ptr, i64, i32, i32, ptr, ptr) #2 -fn generate_launcher<'ll>(cx: &'ll SimpleCx<'_>) -> (&'ll llvm::Value, &'ll llvm::Type) { +fn generate_launcher<'ll>(cx: &CodegenCx<'ll, '_>) -> (&'ll llvm::Value, &'ll llvm::Type) { let tptr = cx.type_ptr(); let ti64 = cx.type_i64(); let ti32 = cx.type_i32(); @@ -30,7 +89,7 @@ fn generate_launcher<'ll>(cx: &'ll SimpleCx<'_>) -> (&'ll llvm::Value, &'ll llvm // @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @0 }, align 8 // FIXME(offload): @0 should include the file name (e.g. lib.rs) in which the function to be // offloaded was defined. -fn generate_at_one<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Value { +pub(crate) fn generate_at_one<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll llvm::Value { let unknown_txt = ";unknown;unknown;0;0;;"; let c_entry_name = CString::new(unknown_txt).unwrap(); let c_val = c_entry_name.as_bytes_with_nul(); @@ -68,7 +127,7 @@ pub(crate) struct TgtOffloadEntry { } impl TgtOffloadEntry { - pub(crate) fn new_decl<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Type { + pub(crate) fn new_decl<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll llvm::Type { let offload_entry_ty = cx.type_named_struct("struct.__tgt_offload_entry"); let tptr = cx.type_ptr(); let ti64 = cx.type_i64(); @@ -82,7 +141,7 @@ impl TgtOffloadEntry { } fn new<'ll>( - cx: &'ll SimpleCx<'_>, + cx: &CodegenCx<'ll, '_>, region_id: &'ll Value, llglobal: &'ll Value, ) -> [&'ll Value; 9] { @@ -126,7 +185,7 @@ impl KernelArgsTy { const OFFLOAD_VERSION: u64 = 3; const FLAGS: u64 = 0; const TRIPCOUNT: u64 = 0; - fn new_decl<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll Type { + fn new_decl<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Type { let kernel_arguments_ty = cx.type_named_struct("struct.__tgt_kernel_arguments"); let tptr = cx.type_ptr(); let ti64 = cx.type_i64(); @@ -140,8 +199,8 @@ impl KernelArgsTy { kernel_arguments_ty } - fn new<'ll>( - cx: &'ll SimpleCx<'_>, + fn new<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, num_args: u64, memtransfer_types: &'ll Value, geps: [&'ll Value; 3], @@ -171,7 +230,8 @@ impl KernelArgsTy { } // Contains LLVM values needed to manage offloading for a single kernel. -pub(crate) struct OffloadKernelData<'ll> { +#[derive(Copy, Clone)] +pub(crate) struct OffloadKernelGlobals<'ll> { pub offload_sizes: &'ll llvm::Value, pub memtransfer_types: &'ll llvm::Value, pub region_id: &'ll llvm::Value, @@ -179,7 +239,7 @@ pub(crate) struct OffloadKernelData<'ll> { } fn gen_tgt_data_mappers<'ll>( - cx: &'ll SimpleCx<'_>, + cx: &CodegenCx<'ll, '_>, ) -> (&'ll llvm::Value, &'ll llvm::Value, &'ll llvm::Value, &'ll llvm::Type) { let tptr = cx.type_ptr(); let ti64 = cx.type_i64(); @@ -241,12 +301,18 @@ pub(crate) fn add_global<'ll>( // mapped to/from the gpu. It also returns a region_id with the name of this kernel, to be // concatenated into the list of region_ids. pub(crate) fn gen_define_handling<'ll>( - cx: &SimpleCx<'ll>, - offload_entry_ty: &'ll llvm::Type, + cx: &CodegenCx<'ll, '_>, metadata: &[OffloadMetadata], - types: &[&Type], - symbol: &str, -) -> OffloadKernelData<'ll> { + types: &[&'ll Type], + symbol: String, + offload_globals: &OffloadGlobals<'ll>, +) -> OffloadKernelGlobals<'ll> { + if let Some(entry) = cx.offload_kernel_cache.borrow().get(&symbol) { + return *entry; + } + + let offload_entry_ty = offload_globals.offload_entry_ty; + // It seems like non-pointer values are automatically mapped. So here, we focus on pointer (or // reference) types. let ptr_meta = types.iter().zip(metadata).filter_map(|(&x, meta)| match cx.type_kind(x) { @@ -274,7 +340,7 @@ pub(crate) fn gen_define_handling<'ll>( let initializer = cx.get_const_i8(0); let region_id = add_unnamed_global(&cx, &name, initializer, WeakAnyLinkage); - let c_entry_name = CString::new(symbol).unwrap(); + let c_entry_name = CString::new(symbol.clone()).unwrap(); let c_val = c_entry_name.as_bytes_with_nul(); let offload_entry_name = format!(".offloading.entry_name.{symbol}"); @@ -298,11 +364,16 @@ pub(crate) fn gen_define_handling<'ll>( let c_section_name = CString::new("llvm_offload_entries").unwrap(); llvm::set_section(offload_entry, &c_section_name); - OffloadKernelData { offload_sizes, memtransfer_types, region_id, offload_entry } + let result = + OffloadKernelGlobals { offload_sizes, memtransfer_types, region_id, offload_entry }; + + cx.offload_kernel_cache.borrow_mut().insert(symbol, result); + + result } fn declare_offload_fn<'ll>( - cx: &'ll SimpleCx<'_>, + cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll llvm::Type, ) -> &'ll llvm::Value { @@ -335,28 +406,28 @@ fn declare_offload_fn<'ll>( // 4. set insert point after kernel call. // 5. generate all the GEPS and stores, to be used in 6) // 6. generate __tgt_target_data_end calls to move data from the GPU -pub(crate) fn gen_call_handling<'ll>( - cx: &SimpleCx<'ll>, - bb: &BasicBlock, - offload_data: &OffloadKernelData<'ll>, +pub(crate) fn gen_call_handling<'ll, 'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, + offload_data: &OffloadKernelGlobals<'ll>, args: &[&'ll Value], types: &[&Type], metadata: &[OffloadMetadata], + offload_globals: &OffloadGlobals<'ll>, ) { - let OffloadKernelData { offload_sizes, offload_entry, memtransfer_types, region_id } = + let cx = builder.cx; + let OffloadKernelGlobals { offload_sizes, offload_entry, memtransfer_types, region_id } = offload_data; - let (tgt_decl, tgt_target_kernel_ty) = generate_launcher(&cx); + + let tgt_decl = offload_globals.launcher_fn; + let tgt_target_kernel_ty = offload_globals.launcher_ty; + // %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } - let tptr = cx.type_ptr(); - let ti32 = cx.type_i32(); - let tgt_bin_desc_ty = vec![ti32, tptr, tptr, tptr]; - let tgt_bin_desc = cx.type_named_struct("struct.__tgt_bin_desc"); - cx.set_struct_body(tgt_bin_desc, &tgt_bin_desc_ty, false); + let tgt_bin_desc = offload_globals.bin_desc; - let tgt_kernel_decl = KernelArgsTy::new_decl(&cx); - let (begin_mapper_decl, _, end_mapper_decl, fn_ty) = gen_tgt_data_mappers(&cx); - - let mut builder = SBuilder::build(cx, bb); + let tgt_kernel_decl = offload_globals.kernel_args_ty; + let begin_mapper_decl = offload_globals.begin_mapper; + let end_mapper_decl = offload_globals.end_mapper; + let fn_ty = offload_globals.mapper_fn_ty; let num_args = types.len() as u64; let ip = unsafe { llvm::LLVMRustGetInsertPoint(&builder.llbuilder) }; @@ -378,9 +449,8 @@ pub(crate) fn gen_call_handling<'ll>( // Step 0) // %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } // %6 = alloca %struct.__tgt_bin_desc, align 8 - let llfn = unsafe { llvm::LLVMGetBasicBlockParent(bb) }; unsafe { - llvm::LLVMRustPositionBuilderPastAllocas(&builder.llbuilder, llfn); + llvm::LLVMRustPositionBuilderPastAllocas(&builder.llbuilder, builder.llfn()); } let tgt_bin_desc_alloca = builder.direct_alloca(tgt_bin_desc, Align::EIGHT, "EmptyDesc"); @@ -413,16 +483,16 @@ pub(crate) fn gen_call_handling<'ll>( } let mapper_fn_ty = cx.type_func(&[cx.type_ptr()], cx.type_void()); - let register_lib_decl = declare_offload_fn(&cx, "__tgt_register_lib", mapper_fn_ty); - let unregister_lib_decl = declare_offload_fn(&cx, "__tgt_unregister_lib", mapper_fn_ty); + let register_lib_decl = offload_globals.register_lib; + let unregister_lib_decl = offload_globals.unregister_lib; let init_ty = cx.type_func(&[], cx.type_void()); - let init_rtls_decl = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); + let init_rtls_decl = offload_globals.init_rtls; // FIXME(offload): Later we want to add them to the wrapper code, rather than our main function. // call void @__tgt_register_lib(ptr noundef %6) - builder.call(mapper_fn_ty, register_lib_decl, &[tgt_bin_desc_alloca], None); + builder.call(mapper_fn_ty, None, None, register_lib_decl, &[tgt_bin_desc_alloca], None, None); // call void @__tgt_init_all_rtls() - builder.call(init_ty, init_rtls_decl, &[], None); + builder.call(init_ty, None, None, init_rtls_decl, &[], None, None); for i in 0..num_args { let idx = cx.get_const_i32(i); @@ -437,15 +507,15 @@ pub(crate) fn gen_call_handling<'ll>( // For now we have a very simplistic indexing scheme into our // offload_{baseptrs,ptrs,sizes}. We will probably improve this along with our gpu frontend pr. - fn get_geps<'a, 'll>( - builder: &mut SBuilder<'a, 'll>, - cx: &'ll SimpleCx<'ll>, + fn get_geps<'ll, 'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, ty: &'ll Type, ty2: &'ll Type, a1: &'ll Value, a2: &'ll Value, a4: &'ll Value, ) -> [&'ll Value; 3] { + let cx = builder.cx; let i32_0 = cx.get_const_i32(0); let gep1 = builder.inbounds_gep(ty, a1, &[i32_0, i32_0]); @@ -454,9 +524,8 @@ pub(crate) fn gen_call_handling<'ll>( [gep1, gep2, gep3] } - fn generate_mapper_call<'a, 'll>( - builder: &mut SBuilder<'a, 'll>, - cx: &'ll SimpleCx<'ll>, + fn generate_mapper_call<'ll, 'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, geps: [&'ll Value; 3], o_type: &'ll Value, fn_to_call: &'ll Value, @@ -464,20 +533,20 @@ pub(crate) fn gen_call_handling<'ll>( num_args: u64, s_ident_t: &'ll Value, ) { + let cx = builder.cx; let nullptr = cx.const_null(cx.type_ptr()); let i64_max = cx.get_const_i64(u64::MAX); let num_args = cx.get_const_i32(num_args); let args = vec![s_ident_t, i64_max, num_args, geps[0], geps[1], geps[2], o_type, nullptr, nullptr]; - builder.call(fn_ty, fn_to_call, &args, None); + builder.call(fn_ty, None, None, fn_to_call, &args, None, None); } // Step 2) - let s_ident_t = generate_at_one(&cx); - let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4); + let s_ident_t = offload_globals.ident_t_global; + let geps = get_geps(builder, ty, ty2, a1, a2, a4); generate_mapper_call( - &mut builder, - &cx, + builder, geps, memtransfer_types, begin_mapper_decl, @@ -504,14 +573,13 @@ pub(crate) fn gen_call_handling<'ll>( region_id, a5, ]; - builder.call(tgt_target_kernel_ty, tgt_decl, &args, None); + builder.call(tgt_target_kernel_ty, None, None, tgt_decl, &args, None, None); // %41 = call i32 @__tgt_target_kernel(ptr @1, i64 -1, i32 2097152, i32 256, ptr @.kernel_1.region_id, ptr %kernel_args) // Step 4) - let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4); + let geps = get_geps(builder, ty, ty2, a1, a2, a4); generate_mapper_call( - &mut builder, - &cx, + builder, geps, memtransfer_types, end_mapper_decl, @@ -520,7 +588,5 @@ pub(crate) fn gen_call_handling<'ll>( s_ident_t, ); - builder.call(mapper_fn_ty, unregister_lib_decl, &[tgt_bin_desc_alloca], None); - - drop(builder); + builder.call(mapper_fn_ty, None, None, unregister_lib_decl, &[tgt_bin_desc_alloca], None, None); } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 6caf60e3cc41..03da70d48f7d 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -35,6 +35,7 @@ use smallvec::SmallVec; use crate::abi::to_llvm_calling_convention; use crate::back::write::to_llvm_code_model; +use crate::builder::gpu_offload::{OffloadGlobals, OffloadKernelGlobals}; use crate::callee::get_fn; use crate::debuginfo::metadata::apply_vcall_visibility_metadata; use crate::llvm::{self, Metadata, MetadataKindId, Module, Type, Value}; @@ -156,6 +157,12 @@ pub(crate) struct FullCx<'ll, 'tcx> { /// Cache of Objective-C selector references pub objc_selrefs: RefCell>, + + /// Globals shared by the offloading runtime + pub offload_globals: RefCell>>, + + /// Cache of kernel-specific globals + pub offload_kernel_cache: RefCell>>, } fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode { @@ -639,6 +646,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { objc_class_t: Cell::new(None), objc_classrefs: Default::default(), objc_selrefs: Default::default(), + offload_globals: Default::default(), + offload_kernel_cache: Default::default(), }, PhantomData, ) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 33541f7b695f..46a7c55a7baa 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -26,7 +26,7 @@ use tracing::debug; use crate::abi::FnAbiLlvmExt; use crate::builder::Builder; use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call}; -use crate::builder::gpu_offload::TgtOffloadEntry; +use crate::builder::gpu_offload::{gen_call_handling, gen_define_handling}; use crate::context::CodegenCx; use crate::errors::{ AutoDiffWithoutEnable, AutoDiffWithoutLto, OffloadWithoutEnable, OffloadWithoutFatLTO, @@ -1287,8 +1287,6 @@ fn codegen_offload<'ll, 'tcx>( let args = get_args_from_tuple(bx, args[1], fn_target); let target_symbol = symbol_name_for_instance_in_crate(tcx, fn_target, LOCAL_CRATE); - let offload_entry_ty = TgtOffloadEntry::new_decl(&cx); - let sig = tcx.fn_sig(fn_target.def_id()).skip_binder().skip_binder(); let inputs = sig.inputs(); @@ -1296,17 +1294,16 @@ fn codegen_offload<'ll, 'tcx>( let types = inputs.iter().map(|ty| cx.layout_of(*ty).llvm_type(cx)).collect::>(); - let offload_data = crate::builder::gpu_offload::gen_define_handling( - cx, - offload_entry_ty, - &metadata, - &types, - &target_symbol, - ); - - // FIXME(Sa4dUs): pass the original builder once we separate kernel launch logic from globals - let bb = unsafe { llvm::LLVMGetInsertBlock(bx.llbuilder) }; - crate::builder::gpu_offload::gen_call_handling(cx, bb, &offload_data, &args, &types, &metadata); + let offload_globals_ref = cx.offload_globals.borrow(); + let offload_globals = match offload_globals_ref.as_ref() { + Some(globals) => globals, + None => { + // Offload is not initialized, cannot continue + return; + } + }; + let offload_data = gen_define_handling(&cx, &metadata, &types, target_symbol, offload_globals); + gen_call_handling(bx, &offload_data, &args, &types, &metadata, offload_globals); } fn get_args_from_tuple<'ll, 'tcx>( diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 6eefb2f48d12..c8245b0e43bd 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1118,7 +1118,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(Word, List: &[r#""...""#]), DuplicatesOk, EncodeCrossCrate::Yes, ), - rustc_attr!( + rustc_attr!( rustc_offload_kernel, Normal, template!(Word), DuplicatesOk, EncodeCrossCrate::Yes, diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index b0f83c825705..06bb2d92d8ba 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -11,6 +11,7 @@ // when inside of a function called main. This, too, is a temporary workaround for not having a // frontend. +#![feature(rustc_attrs)] #![feature(core_intrinsics)] #![no_main] @@ -21,29 +22,31 @@ fn main() { core::hint::black_box(&x); } -// CHECK: %struct.__tgt_offload_entry = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK: %struct.ident_t = type { i32, i32, i32, i32, ptr } +// CHECK: %struct.__tgt_offload_entry = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK: %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } // CHECK: %struct.__tgt_kernel_arguments = type { i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, i64, i64, [3 x i32], [3 x i32], i32 } +// CHECK: @anon.{{.*}}.0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 +// CHECK: @anon.{{.*}}.1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @anon.{{.*}}.0 }, align 8 + // CHECK: @.offload_sizes._kernel_1 = private unnamed_addr constant [1 x i64] [i64 1024] // CHECK: @.offload_maptypes._kernel_1 = private unnamed_addr constant [1 x i64] [i64 35] // CHECK: @._kernel_1.region_id = internal unnamed_addr constant i8 0 // CHECK: @.offloading.entry_name._kernel_1 = internal unnamed_addr constant [10 x i8] c"_kernel_1\00", section ".llvm.rodata.offloading", align 1 // CHECK: @.offloading.entry._kernel_1 = internal constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr @._kernel_1.region_id, ptr @.offloading.entry_name._kernel_1, i64 0, i64 0, ptr null }, section "llvm_offload_entries", align 8 -// CHECK: @anon.{{.*}}.0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 -// CHECK: @anon.{{.*}}.1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @anon.{{.*}}.0 }, align 8 +// CHECK: Function Attrs: nounwind +// CHECK: declare i32 @__tgt_target_kernel(ptr, i64, i32, i32, ptr, ptr) -// CHECK: Function Attrs: -// CHECK-NEXT: define{{( dso_local)?}} void @main() +// CHECK: define{{( dso_local)?}} void @main() // CHECK-NEXT: start: // CHECK-NEXT: %0 = alloca [8 x i8], align 8 // CHECK-NEXT: %x = alloca [1024 x i8], align 16 // CHECK: call void @kernel_1(ptr noalias noundef nonnull align 4 dereferenceable(1024) %x) // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %0) // CHECK-NEXT: store ptr %x, ptr %0, align 8 -// CHECK-NEXT: call void asm sideeffect "", "r,~{memory}"(ptr nonnull %0) #4, !srcloc !4 +// CHECK-NEXT: call void asm sideeffect "", "r,~{memory}"(ptr nonnull %0) // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %0) // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %x) // CHECK-NEXT: ret void @@ -92,9 +95,6 @@ fn main() { // CHECK-NEXT: ret void // CHECK-NEXT: } -// CHECK: Function Attrs: nounwind -// CHECK: declare i32 @__tgt_target_kernel(ptr, i64, i32, i32, ptr, ptr) - #[unsafe(no_mangle)] #[inline(never)] pub fn kernel_1(x: &mut [f32; 256]) { From 8bafb632026871b4e6849f80d63b3f4d8a5fb517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= Date: Mon, 8 Dec 2025 22:47:05 +0100 Subject: [PATCH 1035/3801] Remove outdated comment --- compiler/rustc_codegen_llvm/src/back/write.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index c0c01b80372f..c6a1440c86da 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -710,8 +710,7 @@ pub(crate) unsafe fn llvm_optimize( if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Enable) { let cx = SimpleCx::new(module.module_llvm.llmod(), module.module_llvm.llcx, cgcx.pointer_size); - // For now we only support up to 10 kernels named kernel_0 ... kernel_9, a follow-up PR is - // introducing a proper offload intrinsic to solve this limitation. + for func in cx.get_functions() { let offload_kernel = "offload-kernel"; if attributes::has_string_attr(func, offload_kernel) { From 04c2d2be1379cd67521d04d7142d3edd680d6b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= Date: Thu, 18 Dec 2025 13:14:41 +0100 Subject: [PATCH 1036/3801] Remove `region_id` unnamed attr --- compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs | 2 +- tests/codegen-llvm/gpu_offload/gpu_host.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index f28037fb9cff..046501d08c48 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -338,7 +338,7 @@ pub(crate) fn gen_define_handling<'ll>( let name = format!(".{symbol}.region_id"); let initializer = cx.get_const_i8(0); - let region_id = add_unnamed_global(&cx, &name, initializer, WeakAnyLinkage); + let region_id = add_global(&cx, &name, initializer, WeakAnyLinkage); let c_entry_name = CString::new(symbol.clone()).unwrap(); let c_val = c_entry_name.as_bytes_with_nul(); diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index 06bb2d92d8ba..ac179a65828d 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -32,7 +32,7 @@ fn main() { // CHECK: @.offload_sizes._kernel_1 = private unnamed_addr constant [1 x i64] [i64 1024] // CHECK: @.offload_maptypes._kernel_1 = private unnamed_addr constant [1 x i64] [i64 35] -// CHECK: @._kernel_1.region_id = internal unnamed_addr constant i8 0 +// CHECK: @._kernel_1.region_id = internal constant i8 0 // CHECK: @.offloading.entry_name._kernel_1 = internal unnamed_addr constant [10 x i8] c"_kernel_1\00", section ".llvm.rodata.offloading", align 1 // CHECK: @.offloading.entry._kernel_1 = internal constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr @._kernel_1.region_id, ptr @.offloading.entry_name._kernel_1, i64 0, i64 0, ptr null }, section "llvm_offload_entries", align 8 From 678f58151e36741d0588e150cc46cda14263bedb Mon Sep 17 00:00:00 2001 From: Aditya-PS-05 Date: Fri, 19 Dec 2025 18:05:11 +0530 Subject: [PATCH 1037/3801] fix ICE when {{root}} appears in import suggestions --- compiler/rustc_resolve/src/diagnostics.rs | 6 +++++- .../nested-import-root-symbol-150103.rs | 13 ++++++++++++ .../nested-import-root-symbol-150103.stderr | 20 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/ui/imports/nested-import-root-symbol-150103.rs create mode 100644 tests/ui/imports/nested-import-root-symbol-150103.stderr diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 3eccbd4682da..b0cdfe8ab87d 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2223,7 +2223,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match binding.kind { NameBindingKind::Import { import, .. } => { for segment in import.module_path.iter().skip(1) { - path.push(segment.ident); + // Don't include `{{root}}` in suggestions - it's an internal symbol + // that should never be shown to users. + if segment.ident.name != kw::PathRoot { + path.push(segment.ident); + } } sugg_paths.push(( path.iter().cloned().chain(std::iter::once(ident)).collect::>(), diff --git a/tests/ui/imports/nested-import-root-symbol-150103.rs b/tests/ui/imports/nested-import-root-symbol-150103.rs new file mode 100644 index 000000000000..066ed37d8bbb --- /dev/null +++ b/tests/ui/imports/nested-import-root-symbol-150103.rs @@ -0,0 +1,13 @@ +// Issue: https://github.com/rust-lang/rust/issues/150103 +// ICE when using `::` at start of nested imports +// caused by `{{root}}` appearing in diagnostic suggestions + +mod A { + use Iuse::{ ::Fish }; //~ ERROR failed to resolve: use of unresolved module or unlinked crate +} + +mod B { + use A::{::Fish}; //~ ERROR failed to resolve: crate root in paths can only be used in start position +} + +fn main() {} diff --git a/tests/ui/imports/nested-import-root-symbol-150103.stderr b/tests/ui/imports/nested-import-root-symbol-150103.stderr new file mode 100644 index 000000000000..be8b8c12d218 --- /dev/null +++ b/tests/ui/imports/nested-import-root-symbol-150103.stderr @@ -0,0 +1,20 @@ +error[E0433]: failed to resolve: use of unresolved module or unlinked crate `Iuse` + --> $DIR/nested-import-root-symbol-150103.rs:6:9 + | +LL | use Iuse::{ ::Fish }; + | ^^^^ use of unresolved module or unlinked crate `Iuse` + | +help: you might be missing a crate named `Iuse`, add it to your project and import it in your code + | +LL + extern crate Iuse; + | + +error[E0433]: failed to resolve: crate root in paths can only be used in start position + --> $DIR/nested-import-root-symbol-150103.rs:10:13 + | +LL | use A::{::Fish}; + | ^ crate root in paths can only be used in start position + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. From a45b2ba60be6e0f89aa05eb9c4b444477b3b15b6 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 19 Dec 2025 15:19:39 +0100 Subject: [PATCH 1038/3801] Set myself on vacation --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 09dec7675e7e..5f637205fa65 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -63,6 +63,7 @@ users_on_vacation = [ "Alexendoo", "y21", "blyxyas", + "samueltardieu", ] [assign.owners] From 9bfc9a4778d41831157e2af5063e38542960ece0 Mon Sep 17 00:00:00 2001 From: WaterWhisperer Date: Thu, 18 Dec 2025 23:29:54 +0800 Subject: [PATCH 1039/3801] fix: `main_recursion` enable lint in no_std crates and fix broken tests --- tests/ui/crate_level_checks/entrypoint_recursion.rs | 7 +++---- .../crate_level_checks/entrypoint_recursion.stderr | 12 ++++++++++++ .../ui/crate_level_checks/no_std_main_recursion.rs | 13 +++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 tests/ui/crate_level_checks/entrypoint_recursion.stderr create mode 100644 tests/ui/crate_level_checks/no_std_main_recursion.rs diff --git a/tests/ui/crate_level_checks/entrypoint_recursion.rs b/tests/ui/crate_level_checks/entrypoint_recursion.rs index 3ded902e36b1..84147d8e9c16 100644 --- a/tests/ui/crate_level_checks/entrypoint_recursion.rs +++ b/tests/ui/crate_level_checks/entrypoint_recursion.rs @@ -1,12 +1,11 @@ -//@check-pass //@ignore-target: apple - #![feature(rustc_attrs)] - #[warn(clippy::main_recursion)] #[allow(unconditional_recursion)] #[rustc_main] fn a() { - println!("Hello, World!"); a(); + //~^ main_recursion } + +fn main() {} diff --git a/tests/ui/crate_level_checks/entrypoint_recursion.stderr b/tests/ui/crate_level_checks/entrypoint_recursion.stderr new file mode 100644 index 000000000000..d9f50d2dfc4b --- /dev/null +++ b/tests/ui/crate_level_checks/entrypoint_recursion.stderr @@ -0,0 +1,12 @@ +error: recursing into entrypoint `a` + --> tests/ui/crate_level_checks/entrypoint_recursion.rs:7:5 + | +LL | a(); + | ^ + | + = help: consider using another function for this recursion + = note: `-D clippy::main-recursion` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::main_recursion)]` + +error: aborting due to 1 previous error + diff --git a/tests/ui/crate_level_checks/no_std_main_recursion.rs b/tests/ui/crate_level_checks/no_std_main_recursion.rs new file mode 100644 index 000000000000..74763d67dd78 --- /dev/null +++ b/tests/ui/crate_level_checks/no_std_main_recursion.rs @@ -0,0 +1,13 @@ +//@check-pass +//@compile-flags: -Cpanic=abort +#![no_std] +#[warn(clippy::main_recursion)] +#[allow(unconditional_recursion)] +fn main() { + main(); +} + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} From a287c66721cc088ee0fec6c93f94e94ee03ee11f Mon Sep 17 00:00:00 2001 From: Nelli Skogman Date: Sun, 12 Oct 2025 16:07:11 +0200 Subject: [PATCH 1040/3801] Fix an incorrect error message regarding the size of `isize` and `usize` --- clippy_lints/src/casts/cast_precision_loss.rs | 22 ++++++------------- tests/ui/cast.stderr | 12 +++++----- tests/ui/cast_size.r32bit.stderr | 12 +++++----- tests/ui/cast_size.r64bit.stderr | 12 +++++----- 4 files changed, 25 insertions(+), 33 deletions(-) diff --git a/clippy_lints/src/casts/cast_precision_loss.rs b/clippy_lints/src/casts/cast_precision_loss.rs index 712e38db499f..748ab3163496 100644 --- a/clippy_lints/src/casts/cast_precision_loss.rs +++ b/clippy_lints/src/casts/cast_precision_loss.rs @@ -23,15 +23,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, ca let cast_to_f64 = to_nbits == 64; let mantissa_nbits = if cast_to_f64 { 52 } else { 23 }; - let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64; - let arch_dependent_str = "on targets with 64-bit wide pointers "; - let from_nbits_str = if arch_dependent { - "64".to_owned() - } else if is_isize_or_usize(cast_from) { - // FIXME: handle 16 bits `usize` type - "32 or 64".to_owned() + + let has_width = if is_isize_or_usize(cast_from) { + "can be up to 64 bits wide depending on the target architecture".to_owned() } else { - from_nbits.to_string() + format!("is {from_nbits} bits wide") }; span_lint( @@ -39,13 +35,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, ca CAST_PRECISION_LOSS, expr.span, format!( - "casting `{0}` to `{1}` causes a loss of precision {2}(`{0}` is {3} bits wide, \ - but `{1}`'s mantissa is only {4} bits wide)", - cast_from, - if cast_to_f64 { "f64" } else { "f32" }, - if arch_dependent { arch_dependent_str } else { "" }, - from_nbits_str, - mantissa_nbits + "casting `{cast_from}` to `{cast_to}` may cause a loss of precision \ + (`{cast_from}` {has_width}, \ + but `{cast_to}`'s mantissa is only {mantissa_nbits} bits wide)", ), ); } diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 0ff1dc11c3ac..14b84b1ff1ef 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -1,4 +1,4 @@ -error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `i32` to `f32` may cause a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast.rs:23:5 | LL | x0 as f32; @@ -7,31 +7,31 @@ LL | x0 as f32; = note: `-D clippy::cast-precision-loss` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` -error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `i64` to `f32` may cause a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast.rs:27:5 | LL | x1 as f32; | ^^^^^^^^^ -error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `i64` to `f64` may cause a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast.rs:30:5 | LL | x1 as f64; | ^^^^^^^^^ -error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `u32` to `f32` may cause a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast.rs:34:5 | LL | x2 as f32; | ^^^^^^^^^ -error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `u64` to `f32` may cause a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast.rs:38:5 | LL | x3 as f32; | ^^^^^^^^^ -error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `u64` to `f64` may cause a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast.rs:41:5 | LL | x3 as f64; diff --git a/tests/ui/cast_size.r32bit.stderr b/tests/ui/cast_size.r32bit.stderr index 5811cb3607ba..2f7eeda385e5 100644 --- a/tests/ui/cast_size.r32bit.stderr +++ b/tests/ui/cast_size.r32bit.stderr @@ -13,7 +13,7 @@ LL - 1isize as i8; LL + i8::try_from(1isize); | -error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `isize` to `f32` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:24:5 | LL | x0 as f32; @@ -22,19 +22,19 @@ LL | x0 as f32; = note: `-D clippy::cast-precision-loss` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` -error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `usize` to `f32` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:26:5 | LL | x1 as f32; | ^^^^^^^^^ -error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `isize` to `f64` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:28:5 | LL | x0 as f64; | ^^^^^^^^^ -error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:30:5 | LL | x1 as f64; @@ -165,13 +165,13 @@ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit LL | 1u32 as isize; | ^^^^^^^^^^^^^ -error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `i32` to `f32` may cause a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:61:5 | LL | 999_999_999 as f32; | ^^^^^^^^^^^^^^^^^^ -error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:63:5 | LL | 9_999_999_999_999_999usize as f64; diff --git a/tests/ui/cast_size.r64bit.stderr b/tests/ui/cast_size.r64bit.stderr index ba1419583aeb..8e5f38137602 100644 --- a/tests/ui/cast_size.r64bit.stderr +++ b/tests/ui/cast_size.r64bit.stderr @@ -13,7 +13,7 @@ LL - 1isize as i8; LL + i8::try_from(1isize); | -error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `isize` to `f32` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:24:5 | LL | x0 as f32; @@ -22,19 +22,19 @@ LL | x0 as f32; = note: `-D clippy::cast-precision-loss` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` -error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `usize` to `f32` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:26:5 | LL | x1 as f32; | ^^^^^^^^^ -error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `isize` to `f64` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:28:5 | LL | x0 as f64; | ^^^^^^^^^ -error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:30:5 | LL | x1 as f64; @@ -165,13 +165,13 @@ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit LL | 1u32 as isize; | ^^^^^^^^^^^^^ -error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `i32` to `f32` may cause a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:61:5 | LL | 999_999_999 as f32; | ^^^^^^^^^^^^^^^^^^ -error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:63:5 | LL | 9_999_999_999_999_999usize as f64; From 5610d84ab12502922459ae5da17ac8e0774a8e44 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 19 Dec 2025 07:55:00 -0800 Subject: [PATCH 1041/3801] rustc: Fix `-Zexport-executable-symbols` on wasm This commit reorders some cases in `export_symbols` in the linker implementation for wasm to ensure that the `is_like_wasm` case is handled before the catch-all `CrateType::Executable` case. --- compiler/rustc_codegen_ssa/src/back/linker.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index c73e950bed40..b47652092ed5 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -839,6 +839,11 @@ impl<'a> Linker for GccLinker<'a> { self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error }); } self.link_arg(path); + } else if self.sess.target.is_like_wasm { + self.link_arg("--no-export-dynamic"); + for (sym, _) in symbols { + self.link_arg("--export").link_arg(sym); + } } else if crate_type == CrateType::Executable && !self.sess.target.is_like_solaris { let res: io::Result<()> = try { let mut f = File::create_buffered(&path)?; @@ -853,11 +858,6 @@ impl<'a> Linker for GccLinker<'a> { self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error }); } self.link_arg("--dynamic-list").link_arg(path); - } else if self.sess.target.is_like_wasm { - self.link_arg("--no-export-dynamic"); - for (sym, _) in symbols { - self.link_arg("--export").link_arg(sym); - } } else { // Write an LD version script let res: io::Result<()> = try { From 0bc29cec45412ee3cc68a1ef1556814885543d55 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 19 Dec 2025 17:55:19 +0100 Subject: [PATCH 1042/3801] Add regression test for `const_item_interior_mutations` deref FP --- ...nst-item-interior-mutations-const-deref.rs | 30 +++++++++++++++ ...item-interior-mutations-const-deref.stderr | 37 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/ui/lint/const-item-interior-mutations-const-deref.rs create mode 100644 tests/ui/lint/const-item-interior-mutations-const-deref.stderr diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.rs b/tests/ui/lint/const-item-interior-mutations-const-deref.rs new file mode 100644 index 000000000000..ce684abacccd --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-deref.rs @@ -0,0 +1,30 @@ +// Regression test for +// +// We shouldn't lint on user types, including through deref. + +//@ check-pass + +use std::cell::Cell; +use std::ops::Deref; + +// Cut down version of the issue reproducer without the thread local to just a Deref +pub struct LocalKey { + inner: T, +} + +impl Deref for LocalKey { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; + +fn main() { + let count = LOCAL_COUNT.get(); + //~^ WARN mutation of an interior mutable `const` + LOCAL_COUNT.set(count); + //~^ WARN mutation of an interior mutable `const` +} diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.stderr b/tests/ui/lint/const-item-interior-mutations-const-deref.stderr new file mode 100644 index 000000000000..35696d0ba100 --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-deref.stderr @@ -0,0 +1,37 @@ +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/const-item-interior-mutations-const-deref.rs:26:17 + | +LL | let count = LOCAL_COUNT.get(); + | -----------^^^^^^ + | | + | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified + = help: for more details on interior mutability see + = note: `#[warn(const_item_interior_mutations)]` on by default +help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead + | +LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; +LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/const-item-interior-mutations-const-deref.rs:28:5 + | +LL | LOCAL_COUNT.set(count); + | -----------^^^^^^^^^^^ + | | + | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead + | +LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; +LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; + | + +warning: 2 warnings emitted + From 7431c38ec9cae9b77b7554d62d9d7776bb0f587f Mon Sep 17 00:00:00 2001 From: Flakebi Date: Fri, 19 Dec 2025 17:58:08 +0100 Subject: [PATCH 1043/3801] Add amdgpu intrinsics Add intrinsics for the amdgpu architecture. --- library/stdarch/.github/workflows/main.yml | 15 +- .../ci/docker/amdgcn-amd-amdhsa/Dockerfile | 5 + library/stdarch/ci/dox.sh | 10 + library/stdarch/ci/run.sh | 3 + .../crates/core_arch/src/amdgpu/mod.rs | 1053 +++++++++++++++++ .../crates/core_arch/src/core_arch_docs.md | 2 + library/stdarch/crates/core_arch/src/mod.rs | 14 + 7 files changed, 1100 insertions(+), 2 deletions(-) create mode 100644 library/stdarch/ci/docker/amdgcn-amd-amdhsa/Dockerfile create mode 100644 library/stdarch/crates/core_arch/src/amdgpu/mod.rs diff --git a/library/stdarch/.github/workflows/main.yml b/library/stdarch/.github/workflows/main.yml index 28c15cf4734a..6c8a5694f332 100644 --- a/library/stdarch/.github/workflows/main.yml +++ b/library/stdarch/.github/workflows/main.yml @@ -84,6 +84,8 @@ jobs: os: ubuntu-latest - tuple: nvptx64-nvidia-cuda os: ubuntu-latest + - tuple: amdgcn-amd-amdhsa + os: ubuntu-latest - tuple: thumbv6m-none-eabi os: ubuntu-latest - tuple: thumbv7m-none-eabi @@ -201,6 +203,10 @@ jobs: tuple: aarch64-apple-ios-macabi os: macos-15 norun: true # https://github.com/rust-lang/stdarch/issues/1206 + - target: + tuple: amdgcn-amd-amdhsa + os: ubuntu-latest + norun: true steps: - uses: actions/checkout@v4 @@ -212,12 +218,17 @@ jobs: - run: rustup target add ${{ matrix.target.tuple }} shell: bash - if: matrix.build_std == '' + if: matrix.build_std == '' && matrix.target.tuple != 'amdgcn-amd-amdhsa' - run: | rustup component add rust-src echo "CARGO_UNSTABLE_BUILD_STD=std" >> $GITHUB_ENV shell: bash if: matrix.build_std != '' + - run: | + rustup component add rust-src + echo "CARGO_UNSTABLE_BUILD_STD=core,alloc" >> $GITHUB_ENV + shell: bash + if: matrix.target.tuple == 'amdgcn-amd-amdhsa' # Configure some env vars based on matrix configuration - run: echo "PROFILE=--profile=${{matrix.profile}}" >> $GITHUB_ENV @@ -233,7 +244,7 @@ jobs: if: matrix.disable_assert_instr != '' - run: echo "NOSTD=1" >> $GITHUB_ENV shell: bash - if: startsWith(matrix.target.tuple, 'thumb') || matrix.target.tuple == 'nvptx64-nvidia-cuda' + if: startsWith(matrix.target.tuple, 'thumb') || matrix.target.tuple == 'nvptx64-nvidia-cuda' || matrix.target.tuple == 'amdgcn-amd-amdhsa' # Windows & OSX go straight to `run.sh` ... - run: ./ci/run.sh diff --git a/library/stdarch/ci/docker/amdgcn-amd-amdhsa/Dockerfile b/library/stdarch/ci/docker/amdgcn-amd-amdhsa/Dockerfile new file mode 100644 index 000000000000..65cf281b1477 --- /dev/null +++ b/library/stdarch/ci/docker/amdgcn-amd-amdhsa/Dockerfile @@ -0,0 +1,5 @@ +FROM ubuntu:25.10 +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + libc6-dev \ + ca-certificates diff --git a/library/stdarch/ci/dox.sh b/library/stdarch/ci/dox.sh index 94d76d430472..9803f7e37111 100755 --- a/library/stdarch/ci/dox.sh +++ b/library/stdarch/ci/dox.sh @@ -15,6 +15,15 @@ dox() { cargo clean --target "${1}" + if [ "${1}" == "amdgcn-amd-amdhsa" ]; then + if [ "$CI" != "" ]; then + rustup component add rust-src + fi + export CARGO_UNSTABLE_BUILD_STD=core + # amdgpu needs a target-cpu, any is fine + export RUSTFLAGS="${RUSTFLAGS} -Ctarget-cpu=gfx900" + fi + cargo build --verbose --target "${1}" --manifest-path crates/core_arch/Cargo.toml cargo doc --verbose --target "${1}" --manifest-path crates/core_arch/Cargo.toml } @@ -33,6 +42,7 @@ if [ -z "$1" ]; then #dox mips64-unknown-linux-gnuabi64 dox wasm32-unknown-unknown dox nvptx64-nvidia-cuda + dox amdgcn-amd-amdhsa else dox "${1}" fi diff --git a/library/stdarch/ci/run.sh b/library/stdarch/ci/run.sh index 2bb77bae256f..22c6593132eb 100755 --- a/library/stdarch/ci/run.sh +++ b/library/stdarch/ci/run.sh @@ -42,6 +42,9 @@ case ${TARGET} in armv7-*eabihf | thumbv7-*eabihf) export RUSTFLAGS="${RUSTFLAGS} -Ctarget-feature=+neon" ;; + amdgcn-*) + export RUSTFLAGS="${RUSTFLAGS} -Ctarget-cpu=gfx1200" + ;; # Some of our test dependencies use the deprecated `gcc` crates which # doesn't detect RISC-V compilers automatically, so do it manually here. riscv*) diff --git a/library/stdarch/crates/core_arch/src/amdgpu/mod.rs b/library/stdarch/crates/core_arch/src/amdgpu/mod.rs new file mode 100644 index 000000000000..40274e4d794f --- /dev/null +++ b/library/stdarch/crates/core_arch/src/amdgpu/mod.rs @@ -0,0 +1,1053 @@ +//! amdgpu intrinsics +//! +//! The reference is the [LLVM amdgpu guide] and the [LLVM implementation]. +//! The order of intrinsics here follows the order in the [LLVM implementation]. +//! +//! [LLVM amdgpu guide]: https://llvm.org/docs/AMDGPUUsage.html#llvm-ir-intrinsics +//! [LLVM implementation]: https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/IntrinsicsAMDGPU.td + +#[allow(improper_ctypes)] +unsafe extern "unadjusted" { + #[link_name = "llvm.amdgcn.workitem.id.x"] + safe fn llvm_workitem_id_x() -> u32; + #[link_name = "llvm.amdgcn.workitem.id.y"] + safe fn llvm_workitem_id_y() -> u32; + #[link_name = "llvm.amdgcn.workitem.id.z"] + safe fn llvm_workitem_id_z() -> u32; + + #[link_name = "llvm.amdgcn.workgroup.id.x"] + safe fn llvm_workgroup_id_x() -> u32; + #[link_name = "llvm.amdgcn.workgroup.id.y"] + safe fn llvm_workgroup_id_y() -> u32; + #[link_name = "llvm.amdgcn.workgroup.id.z"] + safe fn llvm_workgroup_id_z() -> u32; + + #[link_name = "llvm.amdgcn.groupstaticsize"] + safe fn llvm_groupstaticsize() -> u32; + #[link_name = "llvm.amdgcn.dispatch.id"] + safe fn llvm_dispatch_id() -> u64; + + #[link_name = "llvm.amdgcn.wavefrontsize"] + safe fn llvm_wavefrontsize() -> u32; + + #[link_name = "llvm.amdgcn.s.barrier"] + safe fn llvm_s_barrier(); + #[link_name = "llvm.amdgcn.s.barrier.signal"] + fn llvm_s_barrier_signal(barrier_type: i32); + #[link_name = "llvm.amdgcn.s.barrier.signal.isfirst"] + fn llvm_s_barrier_signal_isfirst(barrier_type: i32) -> bool; + #[link_name = "llvm.amdgcn.s.barrier.wait"] + fn llvm_s_barrier_wait(barrier_type: i16); + #[link_name = "llvm.amdgcn.s.get.barrier.state"] + fn llvm_s_get_barrier_state(barrier_type: i32) -> u32; + #[link_name = "llvm.amdgcn.wave.barrier"] + safe fn llvm_wave_barrier(); + #[link_name = "llvm.amdgcn.sched.barrier"] + fn llvm_sched_barrier(mask: u32); + #[link_name = "llvm.amdgcn.sched.group.barrier"] + fn llvm_sched_group_barrier(mask: u32, size: u32, sync_id: u32); + + #[link_name = "llvm.amdgcn.s.sleep"] + safe fn llvm_s_sleep(count: u32); + + #[link_name = "llvm.amdgcn.s.sethalt"] + safe fn llvm_s_sethalt(value: u32) -> !; + + #[link_name = "llvm.amdgcn.s.getpc"] + safe fn llvm_s_getpc() -> i64; + + #[link_name = "llvm.amdgcn.mbcnt.lo"] + safe fn llvm_mbcnt_lo(value: u32, init: u32) -> u32; + #[link_name = "llvm.amdgcn.mbcnt.hi"] + safe fn llvm_mbcnt_hi(value: u32, init: u32) -> u32; + + #[link_name = "llvm.amdgcn.ballot"] + safe fn llvm_ballot(b: bool) -> u64; + + #[link_name = "llvm.amdgcn.inverse.ballot"] + safe fn llvm_inverse_ballot(value: u64) -> bool; + + #[link_name = "llvm.amdgcn.wave.reduce.umin"] + safe fn llvm_wave_reduce_umin(value: u32, strategy: u32) -> u32; + #[link_name = "llvm.amdgcn.wave.reduce.min"] + safe fn llvm_wave_reduce_min(value: i32, strategy: u32) -> i32; + #[link_name = "llvm.amdgcn.wave.reduce.umax"] + safe fn llvm_wave_reduce_umax(value: u32, strategy: u32) -> u32; + #[link_name = "llvm.amdgcn.wave.reduce.max"] + safe fn llvm_wave_reduce_max(value: i32, strategy: u32) -> i32; + #[link_name = "llvm.amdgcn.wave.reduce.add"] + safe fn llvm_wave_reduce_add(value: u32, strategy: u32) -> u32; + #[link_name = "llvm.amdgcn.wave.reduce.and"] + safe fn llvm_wave_reduce_and(value: u32, strategy: u32) -> u32; + #[link_name = "llvm.amdgcn.wave.reduce.or"] + safe fn llvm_wave_reduce_or(value: u32, strategy: u32) -> u32; + #[link_name = "llvm.amdgcn.wave.reduce.xor"] + safe fn llvm_wave_reduce_xor(value: u32, strategy: u32) -> u32; + + // The following intrinsics can have multiple sizes + + #[link_name = "llvm.amdgcn.readfirstlane.i32"] + safe fn llvm_readfirstlane_u32(value: u32) -> u32; + #[link_name = "llvm.amdgcn.readfirstlane.i64"] + safe fn llvm_readfirstlane_u64(value: u64) -> u64; + #[link_name = "llvm.amdgcn.readlane.i32"] + fn llvm_readlane_u32(value: u32, lane: u32) -> u32; + #[link_name = "llvm.amdgcn.readlane.i64"] + fn llvm_readlane_u64(value: u64, lane: u32) -> u64; + #[link_name = "llvm.amdgcn.writelane.i32"] + fn llvm_writelane_u32(value: u32, lane: u32, default: u32) -> u32; + #[link_name = "llvm.amdgcn.writelane.i64"] + fn llvm_writelane_u64(value: u64, lane: u32, default: u64) -> u64; + + #[link_name = "llvm.amdgcn.endpgm"] + safe fn llvm_endpgm() -> !; + + #[link_name = "llvm.amdgcn.update.dpp.i32"] + fn llvm_update_dpp( + old: u32, + src: u32, + dpp_ctrl: u32, + row_mask: u32, + bank_mask: u32, + bound_control: bool, + ) -> u32; + + #[link_name = "llvm.amdgcn.s.memrealtime"] + safe fn llvm_s_memrealtime() -> u64; + + #[link_name = "llvm.amdgcn.ds.permute"] + fn llvm_ds_permute(lane: u32, value: u32) -> u32; + #[link_name = "llvm.amdgcn.ds.bpermute"] + fn llvm_ds_bpermute(lane: u32, value: u32) -> u32; + #[link_name = "llvm.amdgcn.perm"] + fn llvm_perm(src0: u32, src1: u32, selector: u32) -> u32; + + // gfx10 + #[link_name = "llvm.amdgcn.permlane16.i32"] + fn llvm_permlane16_u32( + old: u32, + src0: u32, + src1: u32, + src2: u32, + fi: bool, + bound_control: bool, + ) -> u32; + + // gfx10 + #[link_name = "llvm.amdgcn.permlanex16.i32"] + fn llvm_permlanex16_u32( + old: u32, + src0: u32, + src1: u32, + src2: u32, + fi: bool, + bound_control: bool, + ) -> u32; + + #[link_name = "llvm.amdgcn.s.get.waveid.in.workgroup"] + safe fn llvm_s_get_waveid_in_workgroup() -> u32; + + // gfx11 + #[link_name = "llvm.amdgcn.permlane64.i32"] + fn llvm_permlane64_u32(value: u32) -> u32; + + // gfx12 + #[link_name = "llvm.amdgcn.permlane16.var"] + fn llvm_permlane16_var(old: u32, src0: u32, src1: u32, fi: bool, bound_control: bool) -> u32; + + // gfx12 + #[link_name = "llvm.amdgcn.permlanex16.var"] + fn llvm_permlanex16_var(old: u32, src0: u32, src1: u32, fi: bool, bound_control: bool) -> u32; + + #[link_name = "llvm.amdgcn.wave.id"] + safe fn llvm_wave_id() -> u32; + + // gfx950 + #[link_name = "llvm.amdgcn.permlane16.swap"] + fn llvm_permlane16_swap( + vdst_old: u32, + vsrc_src0: u32, + fi: bool, + bound_control: bool, + ) -> (u32, u32); + + // gfx950 + #[link_name = "llvm.amdgcn.permlane32.swap"] + fn llvm_permlane32_swap( + vdst_old: u32, + vsrc_src0: u32, + fi: bool, + bound_control: bool, + ) -> (u32, u32); +} + +/// Returns the x coordinate of the workitem index within the workgroup. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn workitem_id_x() -> u32 { + llvm_workitem_id_x() +} +/// Returns the y coordinate of the workitem index within the workgroup. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn workitem_id_y() -> u32 { + llvm_workitem_id_y() +} +/// Returns the z coordinate of the workitem index within the workgroup. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn workitem_id_z() -> u32 { + llvm_workitem_id_z() +} + +/// Returns the x coordinate of the workgroup index within the dispatch. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn workgroup_id_x() -> u32 { + llvm_workgroup_id_x() +} +/// Returns the y coordinate of the workgroup index within the dispatch. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn workgroup_id_y() -> u32 { + llvm_workgroup_id_y() +} +/// Returns the z coordinate of the workgroup index within the dispatch. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn workgroup_id_z() -> u32 { + llvm_workgroup_id_z() +} + +/// Returns the size of statically allocated shared memory for this program in bytes. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn groupstaticsize() -> u32 { + llvm_groupstaticsize() +} +/// Returns the id of the dispatch that is currently executed. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn dispatch_id() -> u64 { + llvm_dispatch_id() +} + +/// Returns the number of threads in a wavefront. +/// +/// Is always a power of 2. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wavefrontsize() -> u32 { + llvm_wavefrontsize() +} + +/// Synchronize all wavefronts in a workgroup. +/// +/// Each wavefronts in a workgroup waits at the barrier until all wavefronts in the workgroup arrive at a barrier. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn s_barrier() { + llvm_s_barrier() +} + +/// Signal a specific barrier type. +/// +/// Only for non-named barriers. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn s_barrier_signal() { + unsafe { llvm_s_barrier_signal(BARRIER_TYPE) } +} + +/// Signal a specific barrier type. +/// +/// Only for non-named barriers. +/// Provides access to the s_barrier_signal_first instruction; +/// additionally ensures that the result value is valid even when +/// the intrinsic is used from a wavefront that is not running in a workgroup. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn s_barrier_signal_isfirst() -> bool { + unsafe { llvm_s_barrier_signal_isfirst(BARRIER_TYPE) } +} + +/// Wait for a specific barrier type. +/// +/// Only for non-named barriers. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn s_barrier_wait() { + unsafe { llvm_s_barrier_wait(BARRIER_TYPE) } +} + +/// Get the state of a specific barrier type. +/// +/// The `barrier_type` argument must be uniform, otherwise behavior is undefined. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn s_get_barrier_state() -> u32 { + unsafe { llvm_s_get_barrier_state(BARRIER_TYPE) } +} + +/// A barrier for only the threads within the current wavefront. +/// +/// Does not result in an instruction but restricts the compiler. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_barrier() { + llvm_wave_barrier() +} + +/// Prevent movement of some instruction types. +/// +/// Controls the types of instructions that may be allowed to cross the intrinsic during instruction scheduling. +/// The parameter is a mask for the instruction types that can cross the intrinsic. +/// +/// - 0x0000: No instructions may be scheduled across `sched_barrier`. +/// - 0x0001: All, non-memory, non-side-effect producing instructions may be scheduled across `sched_barrier`, i.e. allow ALU instructions to pass. +/// - 0x0002: VALU instructions may be scheduled across `sched_barrier`. +/// - 0x0004: SALU instructions may be scheduled across `sched_barrier`. +/// - 0x0008: MFMA/WMMA instructions may be scheduled across `sched_barrier`. +/// - 0x0010: All VMEM instructions may be scheduled across `sched_barrier`. +/// - 0x0020: VMEM read instructions may be scheduled across `sched_barrier`. +/// - 0x0040: VMEM write instructions may be scheduled across `sched_barrier`. +/// - 0x0080: All DS instructions may be scheduled across `sched_barrier`. +/// - 0x0100: All DS read instructions may be scheduled across `sched_barrier`. +/// - 0x0200: All DS write instructions may be scheduled across `sched_barrier`. +/// - 0x0400: All Transcendental (e.g. V_EXP) instructions may be scheduled across `sched_barrier`. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn sched_barrier() { + static_assert_uimm_bits!(MASK, 11); + unsafe { llvm_sched_barrier(MASK) } +} + +/// Creates schedule groups with specific properties to create custom scheduling pipelines. +/// +/// The ordering between groups is enforced by the instruction scheduler. +/// The intrinsic applies to the code that precedes the intrinsic. +/// The intrinsic takes three values that control the behavior of the schedule groups. +/// +/// - `mask`: Classify instruction groups using the [`sched_barrier`] mask values. +/// - `size`: The number of instructions that are in the group. +/// - `sync_id`: Order is enforced between groups with matching values. +/// +/// The mask can include multiple instruction types. It is undefined behavior to set values beyond the range of valid masks. +/// +/// Combining multiple `sched_group_barrier` intrinsics enables an ordering of specific instruction types during instruction scheduling. +/// For example, the following enforces a sequence of 1 VMEM read, followed by 1 VALU instruction, followed by 5 MFMA instructions. +/// +/// ```rust +/// // 1 VMEM read +/// sched_group_barrier::<32, 1, 0>() +/// // 1 VALU +/// sched_group_barrier::<2, 1, 0>() +/// // 5 MFMA +/// sched_group_barrier::<8, 5, 0>() +/// ``` +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn sched_group_barrier() { + static_assert_uimm_bits!(MASK, 11); + unsafe { llvm_sched_group_barrier(MASK, SIZE, SYNC_ID) } +} + +/// Sleeps for approximately `COUNT * 64` cycles. +/// +/// `COUNT` must be a constant. +/// Only the lower 7 bits of `COUNT` are used. +/// If `COUNT == 0x8000`, sleep forever until woken up, or killed. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn s_sleep() { + llvm_s_sleep(COUNT) +} + +/// Stop execution of the kernel. +/// +/// This usually signals an error state. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn s_sethalt() -> ! { + static_assert_uimm_bits!(VALUE, 3); + llvm_s_sethalt(VALUE) +} + +/// Returns the current process counter. +/// +/// Provides access to the s_getpc_b64 instruction, but with the return value sign-extended +/// from the width of the underlying PC hardware register even on processors where the +/// s_getpc_b64 instruction returns a zero-extended value. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn s_getpc() -> i64 { + llvm_s_getpc() +} + +/// Masked bit count, low 32 lanes. +/// +/// Computes the number of bits set in `value`, masked with a thread mask +/// which contains 1 for all active threads less than the current thread within a wavefront. +/// `init` is added to the result. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn mbcnt_lo(value: u32, init: u32) -> u32 { + llvm_mbcnt_lo(value, init) +} +/// Masked bit count, high 32 lanes. +/// +/// Computes the number of bits set in `value`, masked with a thread mask +/// which contains 1 for all active threads less than the current thread within a wavefront. +/// `init` is added to the result. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn mbcnt_hi(value: u32, init: u32) -> u32 { + llvm_mbcnt_hi(value, init) +} + +/// Returns a bitfield (`u32` or `u64`) containing the result of its i1 argument +/// in all active lanes, and zero in all inactive lanes. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn ballot(b: bool) -> u64 { + llvm_ballot(b) +} + +/// Indexes into the `value` with the current lane id and returns for each lane +/// if the corresponding bit is set. +/// +/// While [`ballot`] converts a `bool` to a mask, `inverse_ballot` converts a mask back to a `bool`. +/// This means `inverse_ballot(ballot(b)) == b`. +/// The inverse of `ballot(inverse_ballot(value)) ~= value` is not always true as inactive lanes are set to zero by `ballot`. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn inverse_ballot(value: u64) -> bool { + llvm_inverse_ballot(value) +} + +/// Performs an arithmetic min reduction on the unsigned values provided by each lane in the wavefront. +/// +/// The `STRATEGY` argument is a hint for the reduction strategy. +/// - 0: Target default preference +/// - 1: Iterative strategy +/// - 2: DPP +/// +/// If target does not support the DPP operations (e.g. gfx6/7), reduction will be performed using default iterative strategy. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_reduce_umin(value: u32) -> u32 { + static_assert!(STRATEGY <= 2); + llvm_wave_reduce_umin(value, STRATEGY) +} +/// Performs an arithmetic min reduction on the signed values provided by each lane in the wavefront. +/// +/// The `STRATEGY` argument is a hint for the reduction strategy. +/// - 0: Target default preference +/// - 1: Iterative strategy +/// - 2: DPP +/// +/// If target does not support the DPP operations (e.g. gfx6/7), reduction will be performed using default iterative strategy. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_reduce_min(value: i32) -> i32 { + static_assert!(STRATEGY <= 2); + llvm_wave_reduce_min(value, STRATEGY) +} + +/// Performs an arithmetic max reduction on the unsigned values provided by each lane in the wavefront. +/// +/// The `STRATEGY` argument is a hint for the reduction strategy. +/// - 0: Target default preference +/// - 1: Iterative strategy +/// - 2: DPP +/// +/// If target does not support the DPP operations (e.g. gfx6/7), reduction will be performed using default iterative strategy. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_reduce_umax(value: u32) -> u32 { + static_assert!(STRATEGY <= 2); + llvm_wave_reduce_umax(value, STRATEGY) +} +/// Performs an arithmetic max reduction on the signed values provided by each lane in the wavefront. +/// +/// The `STRATEGY` argument is a hint for the reduction strategy. +/// - 0: Target default preference +/// - 1: Iterative strategy +/// - 2: DPP +/// +/// If target does not support the DPP operations (e.g. gfx6/7), reduction will be performed using default iterative strategy. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_reduce_max(value: i32) -> i32 { + static_assert!(STRATEGY <= 2); + llvm_wave_reduce_max(value, STRATEGY) +} + +/// Performs an arithmetic add reduction on the values provided by each lane in the wavefront. +/// +/// The `STRATEGY` argument is a hint for the reduction strategy. +/// - 0: Target default preference +/// - 1: Iterative strategy +/// - 2: DPP +/// +/// If target does not support the DPP operations (e.g. gfx6/7), reduction will be performed using default iterative strategy. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_reduce_add(value: u32) -> u32 { + static_assert!(STRATEGY <= 2); + llvm_wave_reduce_add(value, STRATEGY) +} + +/// Performs a logical and reduction on the unsigned values provided by each lane in the wavefront. +/// +/// The `STRATEGY` argument is a hint for the reduction strategy. +/// - 0: Target default preference +/// - 1: Iterative strategy +/// - 2: DPP +/// +/// If target does not support the DPP operations (e.g. gfx6/7), reduction will be performed using default iterative strategy. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_reduce_and(value: u32) -> u32 { + static_assert!(STRATEGY <= 2); + llvm_wave_reduce_and(value, STRATEGY) +} +/// Performs a logical or reduction on the unsigned values provided by each lane in the wavefront. +/// +/// The `STRATEGY` argument is a hint for the reduction strategy. +/// - 0: Target default preference +/// - 1: Iterative strategy +/// - 2: DPP +/// +/// If target does not support the DPP operations (e.g. gfx6/7), reduction will be performed using default iterative strategy. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_reduce_or(value: u32) -> u32 { + static_assert!(STRATEGY <= 2); + llvm_wave_reduce_or(value, STRATEGY) +} +/// Performs a logical xor reduction on the unsigned values provided by each lane in the wavefront. +/// +/// The `STRATEGY` argument is a hint for the reduction strategy. +/// - 0: Target default preference +/// - 1: Iterative strategy +/// - 2: DPP +/// +/// If target does not support the DPP operations (e.g. gfx6/7), reduction will be performed using default iterative strategy. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_reduce_xor(value: u32) -> u32 { + static_assert!(STRATEGY <= 2); + llvm_wave_reduce_xor(value, STRATEGY) +} + +// The following intrinsics can have multiple sizes + +/// Get `value` from the first active lane in the wavefront. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn readfirstlane_u32(value: u32) -> u32 { + llvm_readfirstlane_u32(value) +} +/// Get `value` from the first active lane in the wavefront. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn readfirstlane_u64(value: u64) -> u64 { + llvm_readfirstlane_u64(value) +} +/// Get `value` from the lane at index `lane` in the wavefront. +/// +/// The lane argument must be uniform across the currently active threads +/// of the current wavefront. Otherwise, the result is undefined. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn readlane_u32(value: u32, lane: u32) -> u32 { + unsafe { llvm_readlane_u32(value, lane) } +} +/// Get `value` from the lane at index `lane` in the wavefront. +/// +/// The lane argument must be uniform across the currently active threads +/// of the current wavefront. Otherwise, the result is undefined. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn readlane_u64(value: u64, lane: u32) -> u64 { + unsafe { llvm_readlane_u64(value, lane) } +} +/// Return `value` for the lane at index `lane` in the wavefront. +/// Return `default` for all other lanes. +/// +/// The value to write and lane select arguments must be uniform across the +/// currently active threads of the current wavefront. Otherwise, the result is +/// undefined. +/// +/// `value` is the value returned by `lane`. +/// `default` is the value returned by all lanes other than `lane`. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn writelane_u32(value: u32, lane: u32, default: u32) -> u32 { + unsafe { llvm_writelane_u32(value, lane, default) } +} +/// Return `value` for the lane at index `lane` in the wavefront. +/// Return `default` for all other lanes. +/// +/// The value to write and lane select arguments must be uniform across the +/// currently active threads of the current wavefront. Otherwise, the result is +/// undefined. +/// +/// `value` is the value returned by `lane`. +/// `default` is the value returned by all lanes other than `lane`. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn writelane_u64(value: u64, lane: u32, default: u64) -> u64 { + unsafe { llvm_writelane_u64(value, lane, default) } +} + +/// Stop execution of the wavefront. +/// +/// This usually signals the end of a successful execution. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn endpgm() -> ! { + llvm_endpgm() +} + +/// The `update_dpp` intrinsic represents the `update.dpp` operation in AMDGPU. +/// It takes an old value, a source operand, a DPP control operand, a row mask, a bank mask, and a bound control. +/// This operation is equivalent to a sequence of `v_mov_b32` operations. +/// +/// `llvm.amdgcn.update.dpp.i32 ` +/// Should be equivalent to: +/// ```asm +/// v_mov_b32 +/// v_mov_b32 +/// ``` +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn update_dpp< + const DPP_CTRL: u32, + const ROW_MASK: u32, + const BANK_MASK: u32, + const BOUND_CONTROL: bool, +>( + old: u32, + src: u32, +) -> u32 { + unsafe { llvm_update_dpp(old, src, DPP_CTRL, ROW_MASK, BANK_MASK, BOUND_CONTROL) } +} + +/// Measures time based on a fixed frequency. +/// +/// Provides a real-time clock counter that runs at constant speed (typically 100 MHz) independent of ALU clock speeds. +/// The clock is consistent across the chip, so can be used for measuring between different wavefronts. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn s_memrealtime() -> u64 { + llvm_s_memrealtime() +} + +/// Scatter data across all lanes in a wavefront. +/// +/// Writes `value` to the lane `lane`. +/// +/// Reading from inactive lanes returns `0`. +/// In case multiple values get written to the same `lane`, the value from the source lane with the higher index is taken. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn ds_permute(lane: u32, value: u32) -> u32 { + unsafe { llvm_ds_permute(lane, value) } +} +/// Gather data across all lanes in a wavefront. +/// +/// Returns the `value` given to `ds_permute` by lane `lane`. +/// +/// Reading from inactive lanes returns `0`. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn ds_bpermute(lane: u32, value: u32) -> u32 { + unsafe { llvm_ds_bpermute(lane, value) } +} +/// Permute a 64-bit value. +/// +/// `selector` selects between different patterns in which the 64-bit values represented by `src0` and `src1` are permuted. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn perm(src0: u32, src1: u32, selector: u32) -> u32 { + unsafe { llvm_perm(src0, src1, selector) } +} + +// gfx10 +/// Performs arbitrary gather-style operation within a row (16 contiguous lanes) of the second input operand. +/// +/// The third and fourth inputs must be uniform across the current wavefront. +/// These are combined into a single 64-bit value representing lane selects used to swizzle within each row. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn permlane16_u32( + old: u32, + src0: u32, + src1: u32, + src2: u32, +) -> u32 { + unsafe { llvm_permlane16_u32(old, src0, src1, src2, FI, BOUND_CONTROL) } +} + +// gfx10 +/// Performs arbitrary gather-style operation across two rows (16 contiguous lanes) of the second input operand. +/// +/// The third and fourth inputs must be uniform across the current wavefront. +/// These are combined into a single 64-bit value representing lane selects used to swizzle within each row. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn permlanex16_u32( + old: u32, + src0: u32, + src1: u32, + src2: u32, +) -> u32 { + unsafe { llvm_permlanex16_u32(old, src0, src1, src2, FI, BOUND_CONTROL) } +} + +/// Get the index of the current wavefront in the workgroup. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn s_get_waveid_in_workgroup() -> u32 { + llvm_s_get_waveid_in_workgroup() +} + +// gfx11 +/// Swap `value` between upper and lower 32 lanes in a wavefront. +/// +/// Does nothing for wave32. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn permlane64_u32(value: u32) -> u32 { + unsafe { llvm_permlane64_u32(value) } +} + +// gfx12 +/// Performs arbitrary gather-style operation within a row (16 contiguous lanes) of the second input operand. +/// +/// In contrast to [`permlane16_u32`], allows each lane to specify its own gather lane. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn permlane16_var( + old: u32, + src0: u32, + src1: u32, +) -> u32 { + unsafe { llvm_permlane16_var(old, src0, src1, FI, BOUND_CONTROL) } +} + +// gfx12 +/// Performs arbitrary gather-style operation across two rows (16 contiguous lanes) of the second input operand. +/// +/// In contrast to [`permlanex16_u32`], allows each lane to specify its own gather lane. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn permlanex16_var( + old: u32, + src0: u32, + src1: u32, +) -> u32 { + unsafe { llvm_permlanex16_var(old, src0, src1, FI, BOUND_CONTROL) } +} + +/// Get the index of the current wavefront in the workgroup. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub fn wave_id() -> u32 { + llvm_wave_id() +} + +// gfx950 +/// Provide direct access to `v_permlane16_swap_b32` instruction on supported targets. +/// +/// Swaps the values across lanes of first 2 operands. +/// Odd rows of the first operand are swapped with even rows of the second operand (one row is 16 lanes). +/// Returns a pair for the swapped registers. +/// The first element of the return corresponds to the swapped element of the first argument. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn permlane16_swap( + vdst_old: u32, + vsrc_src0: u32, +) -> (u32, u32) { + unsafe { llvm_permlane16_swap(vdst_old, vsrc_src0, FI, BOUND_CONTROL) } +} + +// gfx950 +/// Provide direct access to `v_permlane32_swap_b32` instruction on supported targets. +/// +/// Swaps the values across lanes of first 2 operands. +/// Rows 2 and 3 of the first operand are swapped with rows 0 and 1 of the second operand (one row is 16 lanes). +/// Returns a pair for the swapped registers. +/// The first element of the return corresponds to the swapped element of the first argument. +#[inline] +#[unstable(feature = "stdarch_amdgpu", issue = "149988")] +pub unsafe fn permlane32_swap( + vdst_old: u32, + vsrc_src0: u32, +) -> (u32, u32) { + unsafe { llvm_permlane32_swap(vdst_old, vsrc_src0, FI, BOUND_CONTROL) } +} + +// Functions to generate code, used to check that the intrinsics build. +// Marked as no_mangle, so the compiler does not remove the functions. +// To test, uncomment the `#[cfg(test)]` line below and run +// NORUN=1 NOSTD=1 TARGET=amdgcn-amd-amdhsa CARGO_UNSTABLE_BUILD_STD=core ci/run.sh +// +// Note that depending on the target-cpu set in run.sh, some of these intrinsics are not available +// and compilation fails with `Cannot select: intrinsic %llvm.amdgcn...`. +// Uncomment these intrinsics to check. +#[cfg(test)] +mod tests { + use super::*; + + #[unsafe(no_mangle)] + fn test_workitem_id_x() -> u32 { + workitem_id_x() + } + #[unsafe(no_mangle)] + fn test_workitem_id_y() -> u32 { + workitem_id_y() + } + #[unsafe(no_mangle)] + fn test_workitem_id_z() -> u32 { + workitem_id_z() + } + + #[unsafe(no_mangle)] + fn test_workgroup_id_x() -> u32 { + workgroup_id_x() + } + #[unsafe(no_mangle)] + fn test_workgroup_id_y() -> u32 { + workgroup_id_y() + } + #[unsafe(no_mangle)] + fn test_workgroup_id_z() -> u32 { + workgroup_id_z() + } + + #[unsafe(no_mangle)] + fn test_groupstaticsize() -> u32 { + groupstaticsize() + } + #[unsafe(no_mangle)] + fn test_dispatch_id() -> u64 { + dispatch_id() + } + + #[unsafe(no_mangle)] + fn test_wavefrontsize() -> u32 { + wavefrontsize() + } + + #[unsafe(no_mangle)] + fn test_s_barrier() { + s_barrier() + } + + #[unsafe(no_mangle)] + fn test_s_barrier_signal() { + unsafe { s_barrier_signal::<-1>() } + } + + #[unsafe(no_mangle)] + fn test_s_barrier_signal_isfirst() -> bool { + unsafe { s_barrier_signal_isfirst::<-1>() } + } + + #[unsafe(no_mangle)] + fn test_s_barrier_wait() { + unsafe { s_barrier_wait::<-1>() } + } + + #[unsafe(no_mangle)] + fn test_s_get_barrier_state() -> u32 { + unsafe { s_get_barrier_state::<-1>() } + } + + #[unsafe(no_mangle)] + fn test_wave_barrier() { + wave_barrier() + } + + #[unsafe(no_mangle)] + fn test_sched_barrier() { + unsafe { sched_barrier::<1>() } + } + + #[unsafe(no_mangle)] + fn test_sched_group_barrier() { + unsafe { sched_group_barrier::<1, 1, 0>() } + } + + #[unsafe(no_mangle)] + fn test_s_sleep() { + s_sleep::<1>() + } + + #[unsafe(no_mangle)] + fn test_s_sethalt() -> ! { + s_sethalt::<1>() + } + + #[unsafe(no_mangle)] + fn test_s_getpc() -> i64 { + s_getpc() + } + + #[unsafe(no_mangle)] + fn test_mbcnt_lo(value: u32, init: u32) -> u32 { + mbcnt_lo(value, init) + } + #[unsafe(no_mangle)] + fn test_mbcnt_hi(value: u32, init: u32) -> u32 { + mbcnt_hi(value, init) + } + + #[unsafe(no_mangle)] + fn test_ballot(b: bool) -> u64 { + ballot(b) + } + + #[unsafe(no_mangle)] + fn test_inverse_ballot(value: u64) -> bool { + inverse_ballot(value) + } + + #[unsafe(no_mangle)] + fn test_wave_reduce_umin(value: u32) -> u32 { + wave_reduce_umin::<0>(value) + } + #[unsafe(no_mangle)] + fn test_wave_reduce_min(value: i32) -> i32 { + wave_reduce_min::<0>(value) + } + + #[unsafe(no_mangle)] + fn test_wave_reduce_umax(value: u32) -> u32 { + wave_reduce_umax::<0>(value) + } + #[unsafe(no_mangle)] + fn test_wave_reduce_max(value: i32) -> i32 { + wave_reduce_max::<0>(value) + } + + #[unsafe(no_mangle)] + fn test_wave_reduce_add(value: u32) -> u32 { + wave_reduce_add::<0>(value) + } + + #[unsafe(no_mangle)] + fn test_wave_reduce_and(value: u32) -> u32 { + wave_reduce_and::<0>(value) + } + #[unsafe(no_mangle)] + fn test_wave_reduce_or(value: u32) -> u32 { + wave_reduce_or::<0>(value) + } + #[unsafe(no_mangle)] + fn test_wave_reduce_xor(value: u32) -> u32 { + wave_reduce_xor::<0>(value) + } + + #[unsafe(no_mangle)] + fn test_readfirstlane_u32(value: u32) -> u32 { + readfirstlane_u32(value) + } + #[unsafe(no_mangle)] + fn test_readfirstlane_u64(value: u64) -> u64 { + readfirstlane_u64(value) + } + #[unsafe(no_mangle)] + fn test_readlane_u32(value: u32, lane: u32) -> u32 { + unsafe { readlane_u32(value, lane) } + } + #[unsafe(no_mangle)] + fn test_readlane_u64(value: u64, lane: u32) -> u64 { + unsafe { readlane_u64(value, lane) } + } + #[unsafe(no_mangle)] + fn test_writelane_u32(value: u32, lane: u32, default: u32) -> u32 { + unsafe { writelane_u32(value, lane, default) } + } + #[unsafe(no_mangle)] + fn test_writelane_u64(value: u64, lane: u32, default: u64) -> u64 { + unsafe { writelane_u64(value, lane, default) } + } + + #[unsafe(no_mangle)] + fn test_endpgm() -> ! { + endpgm() + } + + #[unsafe(no_mangle)] + fn test_update_dpp(old: u32, src: u32) -> u32 { + unsafe { update_dpp::<0, 0, 0, true>(old, src) } + } + + #[unsafe(no_mangle)] + fn test_s_memrealtime() -> u64 { + s_memrealtime() + } + + #[unsafe(no_mangle)] + fn test_ds_permute(lane: u32, value: u32) -> u32 { + unsafe { ds_permute(lane, value) } + } + #[unsafe(no_mangle)] + fn test_ds_bpermute(lane: u32, value: u32) -> u32 { + unsafe { ds_bpermute(lane, value) } + } + #[unsafe(no_mangle)] + fn test_perm(src0: u32, src1: u32, selector: u32) -> u32 { + unsafe { perm(src0, src1, selector) } + } + + #[unsafe(no_mangle)] + fn test_permlane16_u32(old: u32, src0: u32, src1: u32, src2: u32) -> u32 { + unsafe { permlane16_u32::(old, src0, src1, src2) } + } + + #[unsafe(no_mangle)] + fn test_permlanex16_u32(old: u32, src0: u32, src1: u32, src2: u32) -> u32 { + unsafe { permlanex16_u32::(old, src0, src1, src2) } + } + + #[unsafe(no_mangle)] + fn test_s_get_waveid_in_workgroup() -> u32 { + s_get_waveid_in_workgroup() + } + + #[unsafe(no_mangle)] + fn test_permlane64_u32(value: u32) -> u32 { + unsafe { permlane64_u32(value) } + } + + #[unsafe(no_mangle)] + fn test_permlane16_var(old: u32, src0: u32, src1: u32) -> u32 { + unsafe { permlane16_var::(old, src0, src1) } + } + + #[unsafe(no_mangle)] + fn test_permlanex16_var(old: u32, src0: u32, src1: u32) -> u32 { + unsafe { permlanex16_var::(old, src0, src1) } + } + + #[unsafe(no_mangle)] + fn test_wave_id() -> u32 { + wave_id() + } + + #[unsafe(no_mangle)] + fn test_permlane16_swap(vdst_old: u32, vsrc_src0: u32) -> (u32, u32) { + unsafe { permlane16_swap::(vdst_old, vsrc_src0) } + } + + #[unsafe(no_mangle)] + fn test_permlane32_swap(vdst_old: u32, vsrc_src0: u32) -> (u32, u32) { + unsafe { permlane32_swap::(vdst_old, vsrc_src0) } + } +} diff --git a/library/stdarch/crates/core_arch/src/core_arch_docs.md b/library/stdarch/crates/core_arch/src/core_arch_docs.md index 6aea2b461846..707594575497 100644 --- a/library/stdarch/crates/core_arch/src/core_arch_docs.md +++ b/library/stdarch/crates/core_arch/src/core_arch_docs.md @@ -185,6 +185,7 @@ others at: * [`x86_64`] * [`arm`] * [`aarch64`] +* [`amdgpu`] * [`riscv32`] * [`riscv64`] * [`mips`] @@ -201,6 +202,7 @@ others at: [`x86_64`]: ../../core/arch/x86_64/index.html [`arm`]: ../../core/arch/arm/index.html [`aarch64`]: ../../core/arch/aarch64/index.html +[`amdgpu`]: ../../core/arch/amdgpu/index.html [`riscv32`]: ../../core/arch/riscv32/index.html [`riscv64`]: ../../core/arch/riscv64/index.html [`mips`]: ../../core/arch/mips/index.html diff --git a/library/stdarch/crates/core_arch/src/mod.rs b/library/stdarch/crates/core_arch/src/mod.rs index 2105cca1b438..fbb8562d318e 100644 --- a/library/stdarch/crates/core_arch/src/mod.rs +++ b/library/stdarch/crates/core_arch/src/mod.rs @@ -274,6 +274,16 @@ pub mod arch { pub use crate::core_arch::nvptx::*; } + /// Platform-specific intrinsics for the `amdgpu` platform. + /// + /// See the [module documentation](../index.html) for more details. + #[cfg(any(target_arch = "amdgpu", doc))] + #[doc(cfg(target_arch = "amdgpu"))] + #[unstable(feature = "stdarch_amdgpu", issue = "149988")] + pub mod amdgpu { + pub use crate::core_arch::amdgpu::*; + } + /// Platform-specific intrinsics for the `loongarch32` platform. /// /// See the [module documentation](../index.html) for more details. @@ -349,6 +359,10 @@ mod powerpc64; #[doc(cfg(target_arch = "nvptx64"))] mod nvptx; +#[cfg(any(target_arch = "amdgpu", doc))] +#[doc(cfg(target_arch = "amdgpu"))] +mod amdgpu; + #[cfg(any(target_arch = "loongarch32", doc))] #[doc(cfg(target_arch = "loongarch32"))] mod loongarch32; From ca91076898c59730efe3c615916fa0a589d4fe8a Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Wed, 13 Aug 2025 10:13:48 +0530 Subject: [PATCH 1044/3801] std: sys: net: uefi: tcp: Initial TcpListener support Add support for binding and accepting TCP4 connections. While testing, the following network options were used with QEMU + OVMF: -nic user,hostfwd=tcp::12345-:12345 The default localhost address on qemu seems to be 10.0.2.15. UEFI spec does not seem to state that the TCP Handle returned by the Accept method has a ServiceBinding Protocol. So have made the ServiceBinding Protocol optional. Signed-off-by: Ayush Singh --- .../std/src/sys/net/connection/uefi/mod.rs | 35 +++++---- .../std/src/sys/net/connection/uefi/tcp.rs | 19 ++++- .../std/src/sys/net/connection/uefi/tcp4.rs | 78 +++++++++++++++---- library/std/src/sys/pal/uefi/helpers.rs | 48 ++++++------ 4 files changed, 128 insertions(+), 52 deletions(-) diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs index db2d18646d02..107a3e23733d 100644 --- a/library/std/src/sys/net/connection/uefi/mod.rs +++ b/library/std/src/sys/net/connection/uefi/mod.rs @@ -16,26 +16,26 @@ pub struct TcpStream { } impl TcpStream { + fn new(inner: tcp::Tcp) -> Self { + Self { + inner, + read_timeout: Arc::new(Mutex::new(None)), + write_timeout: Arc::new(Mutex::new(None)), + } + } + pub fn connect(addr: A) -> io::Result { return each_addr(addr, inner); fn inner(addr: &SocketAddr) -> io::Result { let inner = tcp::Tcp::connect(addr, None)?; - Ok(TcpStream { - inner, - read_timeout: Arc::new(Mutex::new(None)), - write_timeout: Arc::new(Mutex::new(None)), - }) + Ok(TcpStream::new(inner)) } } pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result { let inner = tcp::Tcp::connect(addr, Some(timeout))?; - Ok(Self { - inner, - read_timeout: Arc::new(Mutex::new(None)), - write_timeout: Arc::new(Mutex::new(None)), - }) + Ok(Self::new(inner)) } pub fn set_read_timeout(&self, t: Option) -> io::Result<()> { @@ -148,16 +148,23 @@ pub struct TcpListener { } impl TcpListener { - pub fn bind(_: A) -> io::Result { - unsupported() + pub fn bind(addr: A) -> io::Result { + return each_addr(addr, inner); + + fn inner(addr: &SocketAddr) -> io::Result { + let inner = tcp::Tcp::bind(addr)?; + Ok(TcpListener { inner }) + } } pub fn socket_addr(&self) -> io::Result { - unsupported() + self.inner.socket_addr() } pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - unsupported() + let tcp = self.inner.accept()?; + let addr = tcp.peer_addr()?; + Ok((TcpStream::new(tcp), addr)) } pub fn duplicate(&self) -> io::Result { diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index 1e7e829c85f3..dc6765b125ea 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -18,7 +18,24 @@ impl Tcp { temp.connect(timeout)?; Ok(Tcp::V4(temp)) } - SocketAddr::V6(_) => todo!(), + SocketAddr::V6(_) => unsupported(), + } + } + + pub(crate) fn bind(addr: &SocketAddr) -> io::Result { + match addr { + SocketAddr::V4(x) => { + let temp = tcp4::Tcp4::new()?; + temp.configure(false, None, Some(x))?; + Ok(Tcp::V4(temp)) + } + SocketAddr::V6(_) => unsupported(), + } + } + + pub(crate) fn accept(&self) -> io::Result { + match self { + Self::V4(client) => client.accept().map(Tcp::V4), } } diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs index 0409997f0272..00c93384e5f6 100644 --- a/library/std/src/sys/net/connection/uefi/tcp4.rs +++ b/library/std/src/sys/net/connection/uefi/tcp4.rs @@ -3,7 +3,7 @@ use r_efi::protocols::tcp4; use crate::io::{self, IoSlice, IoSliceMut}; use crate::net::SocketAddrV4; -use crate::ptr::NonNull; +use crate::ptr::{self, NonNull}; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::pal::helpers; use crate::time::{Duration, Instant}; @@ -12,9 +12,9 @@ const TYPE_OF_SERVICE: u8 = 8; const TIME_TO_LIVE: u8 = 255; pub(crate) struct Tcp4 { + handle: NonNull, protocol: NonNull, flag: AtomicBool, - #[expect(dead_code)] service_binding: helpers::ServiceProtocol, } @@ -22,10 +22,11 @@ const DEFAULT_ADDR: efi::Ipv4Address = efi::Ipv4Address { addr: [0u8; 4] }; impl Tcp4 { pub(crate) fn new() -> io::Result { - let service_binding = helpers::ServiceProtocol::open(tcp4::SERVICE_BINDING_PROTOCOL_GUID)?; - let protocol = helpers::open_protocol(service_binding.child_handle(), tcp4::PROTOCOL_GUID)?; + let (service_binding, handle) = + helpers::ServiceProtocol::open(tcp4::SERVICE_BINDING_PROTOCOL_GUID)?; + let protocol = helpers::open_protocol(handle, tcp4::PROTOCOL_GUID)?; - Ok(Self { service_binding, protocol, flag: AtomicBool::new(false) }) + Ok(Self { service_binding, handle, protocol, flag: AtomicBool::new(false) }) } pub(crate) fn configure( @@ -42,11 +43,14 @@ impl Tcp4 { (DEFAULT_ADDR, 0) }; - // FIXME: Remove when passive connections with proper subnet handling are added - assert!(station_address.is_none()); - let use_default_address = efi::Boolean::TRUE; - let (station_address, station_port) = (DEFAULT_ADDR, 0); - let subnet_mask = helpers::ipv4_to_r_efi(crate::net::Ipv4Addr::new(0, 0, 0, 0)); + let use_default_address: r_efi::efi::Boolean = + station_address.is_none_or(|addr| addr.ip().is_unspecified()).into(); + let (station_address, station_port) = if let Some(x) = station_address { + (helpers::ipv4_to_r_efi(*x.ip()), x.port()) + } else { + (DEFAULT_ADDR, 0) + }; + let subnet_mask = helpers::ipv4_to_r_efi(crate::net::Ipv4Addr::new(255, 255, 255, 0)); let mut config_data = tcp4::ConfigData { type_of_service: TYPE_OF_SERVICE, @@ -60,7 +64,7 @@ impl Tcp4 { station_port, subnet_mask, }, - control_option: crate::ptr::null_mut(), + control_option: ptr::null_mut(), }; let r = unsafe { ((*protocol).configure)(protocol, &mut config_data) }; @@ -74,17 +78,55 @@ impl Tcp4 { let r = unsafe { ((*protocol).get_mode_data)( protocol, - crate::ptr::null_mut(), + ptr::null_mut(), &mut config_data, - crate::ptr::null_mut(), - crate::ptr::null_mut(), - crate::ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), ) }; if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(config_data) } } + pub(crate) fn accept(&self) -> io::Result { + let evt = unsafe { self.create_evt() }?; + let completion_token = + tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; + let mut listen_token = + tcp4::ListenToken { completion_token, new_child_handle: ptr::null_mut() }; + + let protocol = self.protocol.as_ptr(); + let r = unsafe { ((*protocol).accept)(protocol, &mut listen_token) }; + if r.is_error() { + return Err(io::Error::from_raw_os_error(r.as_usize())); + } + + unsafe { self.wait_or_cancel(None, &mut listen_token.completion_token) }?; + + if completion_token.status.is_error() { + Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) + } else { + // EDK2 internals seem to assume a single ServiceBinding Protocol for TCP4 and TCP6, and + // thus does not use any service binding protocol data in destroying child sockets. It + // does seem to suggest that we need to cleanup even the protocols created by accept. To + // be on the safe side with other implementations, we will be using the same service + // binding protocol as the parent TCP4 handle. + // + // https://github.com/tianocore/edk2/blob/f80580f56b267c96f16f985dbf707b2f96947da4/NetworkPkg/TcpDxe/TcpDriver.c#L938 + + let handle = NonNull::new(listen_token.new_child_handle).unwrap(); + let protocol = helpers::open_protocol(handle, tcp4::PROTOCOL_GUID)?; + + Ok(Self { + handle, + service_binding: self.service_binding, + protocol, + flag: AtomicBool::new(false), + }) + } + } + pub(crate) fn connect(&self, timeout: Option) -> io::Result<()> { let evt = unsafe { self.create_evt() }?; let completion_token = @@ -352,6 +394,12 @@ impl Tcp4 { } } +impl Drop for Tcp4 { + fn drop(&mut self) { + let _ = unsafe { self.service_binding.destroy_child(self.handle) }; + } +} + extern "efiapi" fn toggle_atomic_flag(_: r_efi::efi::Event, ctx: *mut crate::ffi::c_void) { let flag = unsafe { AtomicBool::from_ptr(ctx.cast()) }; flag.store(true, Ordering::Relaxed); diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index d059be010e98..8a3ed6c00c15 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -651,34 +651,38 @@ pub(crate) fn get_device_path_from_map(map: &Path) -> io::Result, - child_handle: NonNull, } impl ServiceProtocol { - pub(crate) fn open(service_guid: r_efi::efi::Guid) -> io::Result { + /// Open a child handle on a service_binding protocol. + pub(crate) fn open( + service_guid: r_efi::efi::Guid, + ) -> io::Result<(Self, NonNull)> { let handles = locate_handles(service_guid)?; for handle in handles { if let Ok(protocol) = open_protocol::(handle, service_guid) { - let Ok(child_handle) = Self::create_child(protocol) else { - continue; - }; - - return Ok(Self { service_guid, handle, child_handle }); + if let Ok(child_handle) = unsafe { Self::create_child(protocol) } { + return Ok((Self { service_guid, handle }, child_handle)); + } } } Err(io::const_error!(io::ErrorKind::NotFound, "no service binding protocol found")) } - pub(crate) fn child_handle(&self) -> NonNull { - self.child_handle - } - - fn create_child( + // SAFETY: sbp must be a valid service binding protocol pointer + unsafe fn create_child( sbp: NonNull, ) -> io::Result> { let mut child_handle: r_efi::efi::Handle = crate::ptr::null_mut(); @@ -692,17 +696,17 @@ impl ServiceProtocol { .ok_or(const_error!(io::ErrorKind::Other, "null child handle")) } } -} -impl Drop for ServiceProtocol { - fn drop(&mut self) { - if let Ok(sbp) = open_protocol::(self.handle, self.service_guid) - { - // SAFETY: Child handle must be allocated by the current service binding protocol. - let _ = unsafe { - ((*sbp.as_ptr()).destroy_child)(sbp.as_ptr(), self.child_handle.as_ptr()) - }; - } + // SAFETY: Child handle must be allocated by the current service binding protocol and must be + // valid. + pub(crate) unsafe fn destroy_child( + &self, + handle: NonNull, + ) -> io::Result<()> { + let sbp = open_protocol::(self.handle, self.service_guid)?; + + let r = unsafe { ((*sbp.as_ptr()).destroy_child)(sbp.as_ptr(), handle.as_ptr()) }; + if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } } From 675fd681aa19cc45d27051416db847438efd0f76 Mon Sep 17 00:00:00 2001 From: irelaxcn Date: Fri, 19 Dec 2025 01:17:16 +0800 Subject: [PATCH 1045/3801] Fix `println_empty_string` suggestion caused error when there is a `,` after arg. Make `writeln_empty_string` don't provide an auto-fix suggestion when there is a comment in the macro call span. --- clippy_lints/src/write/empty_string.rs | 42 +++++---- tests/ui/crashes/ice-10148.stderr | 2 +- tests/ui/println_empty_string.fixed | 20 +++++ tests/ui/println_empty_string.rs | 24 ++++++ tests/ui/println_empty_string.stderr | 39 ++++++++- tests/ui/println_empty_string_unfixable.rs | 30 +++++++ .../ui/println_empty_string_unfixable.stderr | 85 +++++++++++++++++++ tests/ui/writeln_empty_string_unfixable.rs | 26 ++++++ .../ui/writeln_empty_string_unfixable.stderr | 47 ++++++++++ 9 files changed, 295 insertions(+), 20 deletions(-) create mode 100644 tests/ui/println_empty_string_unfixable.rs create mode 100644 tests/ui/println_empty_string_unfixable.stderr create mode 100644 tests/ui/writeln_empty_string_unfixable.rs create mode 100644 tests/ui/writeln_empty_string_unfixable.stderr diff --git a/clippy_lints/src/write/empty_string.rs b/clippy_lints/src/write/empty_string.rs index e7eb99eb34ec..1291f2489a21 100644 --- a/clippy_lints/src/write/empty_string.rs +++ b/clippy_lints/src/write/empty_string.rs @@ -1,37 +1,43 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::MacroCall; use clippy_utils::source::expand_past_previous_comma; -use clippy_utils::sym; +use clippy_utils::{span_extract_comments, sym}; use rustc_ast::{FormatArgs, FormatArgsPiece}; use rustc_errors::Applicability; -use rustc_lint::LateContext; +use rustc_lint::{LateContext, LintContext}; use super::{PRINTLN_EMPTY_STRING, WRITELN_EMPTY_STRING}; pub(super) fn check(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &MacroCall, name: &str) { if let [FormatArgsPiece::Literal(sym::LF)] = &format_args.template[..] { - let mut span = format_args.span; - - let lint = if name == "writeln" { - span = expand_past_previous_comma(cx, span); - - WRITELN_EMPTY_STRING - } else { - PRINTLN_EMPTY_STRING - }; + let is_writeln = name == "writeln"; span_lint_and_then( cx, - lint, + if is_writeln { + WRITELN_EMPTY_STRING + } else { + PRINTLN_EMPTY_STRING + }, macro_call.span, format!("empty string literal in `{name}!`"), |diag| { - diag.span_suggestion( - span, - "remove the empty string", - String::new(), - Applicability::MachineApplicable, - ); + if span_extract_comments(cx.sess().source_map(), macro_call.span).is_empty() { + let closing_paren = cx.sess().source_map().span_extend_to_prev_char_before( + macro_call.span.shrink_to_hi(), + ')', + false, + ); + let mut span = format_args.span.with_hi(closing_paren.lo()); + if is_writeln { + span = expand_past_previous_comma(cx, span); + } + + diag.span_suggestion(span, "remove the empty string", "", Applicability::MachineApplicable); + } else { + // If there is a comment in the span of macro call, we don't provide an auto-fix suggestion. + diag.span_note(format_args.span, "remove the empty string"); + } }, ); } diff --git a/tests/ui/crashes/ice-10148.stderr b/tests/ui/crashes/ice-10148.stderr index 639cf2dd442b..e91fb3778a31 100644 --- a/tests/ui/crashes/ice-10148.stderr +++ b/tests/ui/crashes/ice-10148.stderr @@ -2,7 +2,7 @@ error: empty string literal in `println!` --> tests/ui/crashes/ice-10148.rs:8:5 | LL | println!(with_span!(""something "")); - | ^^^^^^^^^^^^^^^^^^^^-----------^^^^^ + | ^^^^^^^^^^^^^^^^^^^^---------------^ | | | help: remove the empty string | diff --git a/tests/ui/println_empty_string.fixed b/tests/ui/println_empty_string.fixed index 05e262ec7786..6b1039ee8020 100644 --- a/tests/ui/println_empty_string.fixed +++ b/tests/ui/println_empty_string.fixed @@ -19,3 +19,23 @@ fn main() { //~^ println_empty_string } } + +#[rustfmt::skip] +fn issue_16167() { + //~v println_empty_string + println!( + ); + + match "a" { + _ => println!(), // there is a space between "" and comma + //~^ println_empty_string + } + + eprintln!(); // there is a tab between "" and comma + //~^ println_empty_string + + match "a" { + _ => eprintln!(), // tab and space between "" and comma + //~^ println_empty_string + } +} diff --git a/tests/ui/println_empty_string.rs b/tests/ui/println_empty_string.rs index 028ddb60dbce..db3b8e1a0eac 100644 --- a/tests/ui/println_empty_string.rs +++ b/tests/ui/println_empty_string.rs @@ -19,3 +19,27 @@ fn main() { //~^ println_empty_string } } + +#[rustfmt::skip] +fn issue_16167() { + //~v println_empty_string + println!( + "\ + \ + " + , + ); + + match "a" { + _ => println!("" ,), // there is a space between "" and comma + //~^ println_empty_string + } + + eprintln!("" ,); // there is a tab between "" and comma + //~^ println_empty_string + + match "a" { + _ => eprintln!("" ,), // tab and space between "" and comma + //~^ println_empty_string + } +} diff --git a/tests/ui/println_empty_string.stderr b/tests/ui/println_empty_string.stderr index 8b997aef9069..bdac1bb3b8ef 100644 --- a/tests/ui/println_empty_string.stderr +++ b/tests/ui/println_empty_string.stderr @@ -33,5 +33,42 @@ LL | _ => eprintln!(""), | | | help: remove the empty string -error: aborting due to 4 previous errors +error: empty string literal in `println!` + --> tests/ui/println_empty_string.rs:26:5 + | +LL | / println!( +LL | |/ "\ +LL | || \ +LL | || " +LL | || , +LL | || ); + | ||____-^ + | |____| + | help: remove the empty string + +error: empty string literal in `println!` + --> tests/ui/println_empty_string.rs:34:14 + | +LL | _ => println!("" ,), // there is a space between "" and comma + | ^^^^^^^^^----^ + | | + | help: remove the empty string + +error: empty string literal in `eprintln!` + --> tests/ui/println_empty_string.rs:38:5 + | +LL | eprintln!("" ,); // there is a tab between "" and comma + | ^^^^^^^^^^-------^ + | | + | help: remove the empty string + +error: empty string literal in `eprintln!` + --> tests/ui/println_empty_string.rs:42:14 + | +LL | _ => eprintln!("" ,), // tab and space between "" and comma + | ^^^^^^^^^^--------^ + | | + | help: remove the empty string + +error: aborting due to 8 previous errors diff --git a/tests/ui/println_empty_string_unfixable.rs b/tests/ui/println_empty_string_unfixable.rs new file mode 100644 index 000000000000..d6c30f627a58 --- /dev/null +++ b/tests/ui/println_empty_string_unfixable.rs @@ -0,0 +1,30 @@ +#![allow(clippy::match_single_binding)] + +// If there is a comment in the span of macro call, we don't provide an auto-fix suggestion. +#[rustfmt::skip] +fn issue_16167() { + //~v println_empty_string + println!("" /* comment */); + //~v println_empty_string + eprintln!("" /* comment */); + + //~v println_empty_string + println!( // comment + ""); + //~v println_empty_string + eprintln!( // comment + ""); + + //~v println_empty_string + println!("", /* comment */); + + //~v println_empty_string + println!( + "\ + \ + ", + + // there is a comment in the macro span regardless of its position + + ); +} diff --git a/tests/ui/println_empty_string_unfixable.stderr b/tests/ui/println_empty_string_unfixable.stderr new file mode 100644 index 000000000000..648fd7cdbccd --- /dev/null +++ b/tests/ui/println_empty_string_unfixable.stderr @@ -0,0 +1,85 @@ +error: empty string literal in `println!` + --> tests/ui/println_empty_string_unfixable.rs:7:5 + | +LL | println!("" /* comment */); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:7:14 + | +LL | println!("" /* comment */); + | ^^ + = note: `-D clippy::println-empty-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::println_empty_string)]` + +error: empty string literal in `eprintln!` + --> tests/ui/println_empty_string_unfixable.rs:9:5 + | +LL | eprintln!("" /* comment */); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:9:15 + | +LL | eprintln!("" /* comment */); + | ^^ + +error: empty string literal in `println!` + --> tests/ui/println_empty_string_unfixable.rs:12:5 + | +LL | / println!( // comment +LL | | ""); + | |___________________^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:13:17 + | +LL | ""); + | ^^ + +error: empty string literal in `eprintln!` + --> tests/ui/println_empty_string_unfixable.rs:15:5 + | +LL | / eprintln!( // comment +LL | | ""); + | |___________________^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:16:17 + | +LL | ""); + | ^^ + +error: empty string literal in `println!` + --> tests/ui/println_empty_string_unfixable.rs:19:5 + | +LL | println!("", /* comment */); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:19:14 + | +LL | println!("", /* comment */); + | ^^ + +error: empty string literal in `println!` + --> tests/ui/println_empty_string_unfixable.rs:22:5 + | +LL | / println!( +LL | | "\ +LL | | \ +LL | | ", +... | +LL | | ); + | |_____^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:23:9 + | +LL | / "\ +LL | | \ +LL | | ", + | |_____________^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/writeln_empty_string_unfixable.rs b/tests/ui/writeln_empty_string_unfixable.rs new file mode 100644 index 000000000000..ca570fd1fc7b --- /dev/null +++ b/tests/ui/writeln_empty_string_unfixable.rs @@ -0,0 +1,26 @@ +#![allow(unused_must_use)] +#![warn(clippy::writeln_empty_string)] + +use std::io::Write; + +// If there is a comment in the span of macro call, we don't provide an auto-fix suggestion. +#[rustfmt::skip] +fn issue_16251() { + let mut v = Vec::new(); + + writeln!(v, /* comment */ ""); + //~^ writeln_empty_string + + writeln!(v, "" /* comment */); + //~^ writeln_empty_string + + //~v writeln_empty_string + writeln!(v, + "\ + \ + " + + // there is a comment in the macro span regardless of its position + + ); +} diff --git a/tests/ui/writeln_empty_string_unfixable.stderr b/tests/ui/writeln_empty_string_unfixable.stderr new file mode 100644 index 000000000000..0ed802ba84ba --- /dev/null +++ b/tests/ui/writeln_empty_string_unfixable.stderr @@ -0,0 +1,47 @@ +error: empty string literal in `writeln!` + --> tests/ui/writeln_empty_string_unfixable.rs:11:5 + | +LL | writeln!(v, /* comment */ ""); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/writeln_empty_string_unfixable.rs:11:31 + | +LL | writeln!(v, /* comment */ ""); + | ^^ + = note: `-D clippy::writeln-empty-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::writeln_empty_string)]` + +error: empty string literal in `writeln!` + --> tests/ui/writeln_empty_string_unfixable.rs:14:5 + | +LL | writeln!(v, "" /* comment */); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/writeln_empty_string_unfixable.rs:14:17 + | +LL | writeln!(v, "" /* comment */); + | ^^ + +error: empty string literal in `writeln!` + --> tests/ui/writeln_empty_string_unfixable.rs:18:5 + | +LL | / writeln!(v, +LL | | "\ +LL | | \ +LL | | " +... | +LL | | ); + | |_____^ + | +note: remove the empty string + --> tests/ui/writeln_empty_string_unfixable.rs:19:9 + | +LL | / "\ +LL | | \ +LL | | " + | |_____________^ + +error: aborting due to 3 previous errors + From 897e88c63ded83e8b6be47ea09c661f7bd8c0ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 19 Dec 2025 12:34:59 +0100 Subject: [PATCH 1046/3801] add test for 149980 --- tests/ui/eii/error_statement_position.rs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/ui/eii/error_statement_position.rs diff --git a/tests/ui/eii/error_statement_position.rs b/tests/ui/eii/error_statement_position.rs new file mode 100644 index 000000000000..a9c606991574 --- /dev/null +++ b/tests/ui/eii/error_statement_position.rs @@ -0,0 +1,6 @@ +#![feature(extern_item_impls)] + +fn main() { + #[eii] + impl Bar {} +} From 6608f6ace7a0267cff3920216f1b697cabc3ca67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 19 Dec 2025 13:57:34 +0100 Subject: [PATCH 1047/3801] split up expansion code of eii macro into functions --- compiler/rustc_builtin_macros/src/eii.rs | 416 +++++++++++++---------- 1 file changed, 244 insertions(+), 172 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index b97cb1daec53..e29b29fc6ccb 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -1,11 +1,12 @@ use rustc_ast::token::{Delimiter, TokenKind}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::{ - DUMMY_NODE_ID, EiiExternTarget, EiiImpl, ItemKind, Stmt, StmtKind, ast, token, tokenstream, + Attribute, DUMMY_NODE_ID, EiiExternTarget, EiiImpl, ItemKind, MetaItem, Path, Stmt, StmtKind, + Visibility, ast, }; use rustc_ast_pretty::pprust::path_to_string; use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_span::{Ident, Span, kw, sym}; +use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; use thin_vec::{ThinVec, thin_vec}; use crate::errors::{ @@ -52,12 +53,12 @@ pub(crate) fn unsafe_eii( fn eii_( ecx: &mut ExtCtxt<'_>, - span: Span, + eii_attr_span: Span, meta_item: &ast::MetaItem, item: Annotatable, impl_unsafe: bool, ) -> Vec { - let span = ecx.with_def_site_ctxt(span); + let eii_attr_span = ecx.with_def_site_ctxt(eii_attr_span); let (item, stmt) = if let Annotatable::Item(item) = item { (item, false) @@ -67,7 +68,7 @@ fn eii_( (item.clone(), true) } else { ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { - span, + span: eii_attr_span, name: path_to_string(&meta_item.path), }); return vec![item]; @@ -77,113 +78,218 @@ fn eii_( let item = *item; - let ast::Item { attrs, id: _, span: item_span, vis, kind: ItemKind::Fn(mut func), tokens: _ } = - item - else { + let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } = item else { ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { - span, + span: eii_attr_span, name: path_to_string(&meta_item.path), }); return vec![Annotatable::Item(Box::new(item))]; }; - // Detect when this is the *second* eii attribute on an item. - let mut new_attrs = ThinVec::new(); - for i in attrs { - if i.has_name(sym::eii) { - ecx.dcx().emit_err(EiiOnlyOnce { - span: i.span, - first_span: span, - name: path_to_string(&meta_item.path), - }); - } else { - new_attrs.push(i); - } - } - let attrs = new_attrs; + let attrs_from_decl = + filter_attrs_for_multiple_eii_attr(ecx, attrs, eii_attr_span, &meta_item.path); - let macro_name = if meta_item.is_word() { - func.ident - } else if let Some([first]) = meta_item.meta_item_list() - && let Some(m) = first.meta_item() - && m.path.segments.len() == 1 - { - m.path.segments[0].ident - } else { - ecx.dcx().emit_err(EiiMacroExpectedMaxOneArgument { - span: meta_item.span, - name: path_to_string(&meta_item.path), - }); + let Ok(macro_name) = name_for_impl_macro(ecx, &func, &meta_item) else { return vec![Annotatable::Item(orig_item)]; }; + // span of the declaring item without attributes + let item_span = func.sig.span; + // span of the eii attribute and the item below it, i.e. the full declaration + let decl_span = eii_attr_span.to(item_span); + let foreign_item_name = func.ident; + let mut return_items = Vec::new(); if func.body.is_some() { - let mut default_func = func.clone(); - func.body = None; - default_func.eii_impls.push(ast::EiiImpl { - node_id: DUMMY_NODE_ID, - eii_macro_path: ast::Path::from_ident(macro_name), - impl_safety: if impl_unsafe { ast::Safety::Unsafe(span) } else { ast::Safety::Default }, - span, - inner_span: macro_name.span, - is_default: true, // important! - }); - - return_items.push(Box::new(ast::Item { - attrs: ThinVec::new(), - id: ast::DUMMY_NODE_ID, - span, - vis: ast::Visibility { span, kind: ast::VisibilityKind::Inherited, tokens: None }, - kind: ast::ItemKind::Const(Box::new(ast::ConstItem { - ident: Ident { name: kw::Underscore, span }, - defaultness: ast::Defaultness::Final, - generics: ast::Generics::default(), - ty: Box::new(ast::Ty { - id: DUMMY_NODE_ID, - kind: ast::TyKind::Tup(ThinVec::new()), - span, - tokens: None, - }), - rhs: Some(ast::ConstItemRhs::Body(Box::new(ast::Expr { - id: DUMMY_NODE_ID, - kind: ast::ExprKind::Block( - Box::new(ast::Block { - stmts: thin_vec![ast::Stmt { - id: DUMMY_NODE_ID, - kind: ast::StmtKind::Item(Box::new(ast::Item { - attrs: thin_vec![], // FIXME: re-add some original attrs - id: DUMMY_NODE_ID, - span: item_span, - vis: ast::Visibility { - span, - kind: ast::VisibilityKind::Inherited, - tokens: None - }, - kind: ItemKind::Fn(default_func), - tokens: None, - })), - span - }], - id: DUMMY_NODE_ID, - rules: ast::BlockCheckMode::Default, - span, - tokens: None, - }), - None, - ), - span, - attrs: ThinVec::new(), - tokens: None, - }))), - define_opaque: None, - })), - tokens: None, - })) + return_items.push(Box::new(generate_default_impl( + &func, + impl_unsafe, + macro_name, + eii_attr_span, + item_span, + ))) } - let decl_span = span.to(func.sig.span); + return_items.push(Box::new(generate_foreign_item( + ecx, + eii_attr_span, + item_span, + *func, + vis, + &attrs_from_decl, + ))); + return_items.push(Box::new(generate_attribute_macro_to_implement( + ecx, + eii_attr_span, + macro_name, + foreign_item_name, + impl_unsafe, + decl_span, + ))); + + if stmt { + return_items + .into_iter() + .map(|i| { + Annotatable::Stmt(Box::new(Stmt { + id: DUMMY_NODE_ID, + kind: StmtKind::Item(i), + span: eii_attr_span, + })) + }) + .collect() + } else { + return_items.into_iter().map(|i| Annotatable::Item(i)).collect() + } +} + +/// Decide on the name of the macro that can be used to implement the EII. +/// This is either an explicitly given name, or the name of the item in the +/// declaration of the EII. +fn name_for_impl_macro( + ecx: &mut ExtCtxt<'_>, + func: &ast::Fn, + meta_item: &MetaItem, +) -> Result { + if meta_item.is_word() { + Ok(func.ident) + } else if let Some([first]) = meta_item.meta_item_list() + && let Some(m) = first.meta_item() + && m.path.segments.len() == 1 + { + Ok(m.path.segments[0].ident) + } else { + Err(ecx.dcx().emit_err(EiiMacroExpectedMaxOneArgument { + span: meta_item.span, + name: path_to_string(&meta_item.path), + })) + } +} + +/// Ensure that in the list of attrs, there's only a single `eii` attribute. +fn filter_attrs_for_multiple_eii_attr( + ecx: &mut ExtCtxt<'_>, + attrs: ThinVec, + eii_attr_span: Span, + eii_attr_path: &Path, +) -> ThinVec { + attrs + .into_iter() + .filter(|i| { + if i.has_name(sym::eii) { + ecx.dcx().emit_err(EiiOnlyOnce { + span: i.span, + first_span: eii_attr_span, + name: path_to_string(eii_attr_path), + }); + false + } else { + true + } + }) + .collect() +} + +fn generate_default_impl( + func: &ast::Fn, + impl_unsafe: bool, + macro_name: Ident, + eii_attr_span: Span, + item_span: Span, +) -> ast::Item { + // FIXME: re-add some original attrs + let attrs = ThinVec::new(); + + let mut default_func = func.clone(); + default_func.eii_impls.push(EiiImpl { + node_id: DUMMY_NODE_ID, + inner_span: macro_name.span, + eii_macro_path: ast::Path::from_ident(macro_name), + impl_safety: if impl_unsafe { + ast::Safety::Unsafe(eii_attr_span) + } else { + ast::Safety::Default + }, + span: eii_attr_span, + is_default: true, + }); + + ast::Item { + attrs: ThinVec::new(), + id: ast::DUMMY_NODE_ID, + span: eii_attr_span, + vis: ast::Visibility { + span: eii_attr_span, + kind: ast::VisibilityKind::Inherited, + tokens: None, + }, + kind: ast::ItemKind::Const(Box::new(ast::ConstItem { + ident: Ident { name: kw::Underscore, span: eii_attr_span }, + defaultness: ast::Defaultness::Final, + generics: ast::Generics::default(), + ty: Box::new(ast::Ty { + id: DUMMY_NODE_ID, + kind: ast::TyKind::Tup(ThinVec::new()), + span: eii_attr_span, + tokens: None, + }), + rhs: Some(ast::ConstItemRhs::Body(Box::new(ast::Expr { + id: DUMMY_NODE_ID, + kind: ast::ExprKind::Block( + Box::new(ast::Block { + stmts: thin_vec![ast::Stmt { + id: DUMMY_NODE_ID, + kind: ast::StmtKind::Item(Box::new(ast::Item { + attrs, + id: DUMMY_NODE_ID, + span: item_span, + vis: ast::Visibility { + span: eii_attr_span, + kind: ast::VisibilityKind::Inherited, + tokens: None + }, + kind: ItemKind::Fn(Box::new(default_func)), + tokens: None, + })), + span: eii_attr_span + }], + id: DUMMY_NODE_ID, + rules: ast::BlockCheckMode::Default, + span: eii_attr_span, + tokens: None, + }), + None, + ), + span: eii_attr_span, + attrs: ThinVec::new(), + tokens: None, + }))), + define_opaque: None, + })), + tokens: None, + } +} + +/// Generates a foreign item, like +/// +/// ```rust, ignore +/// extern "…" { safe fn item(); } +/// ``` +fn generate_foreign_item( + ecx: &mut ExtCtxt<'_>, + eii_attr_span: Span, + item_span: Span, + mut func: ast::Fn, + vis: Visibility, + attrs_from_decl: &[Attribute], +) -> ast::Item { + let mut foreign_item_attrs = ThinVec::new(); + foreign_item_attrs.extend_from_slice(attrs_from_decl); + + // Add the rustc_eii_extern_item on the foreign item. Usually, foreign items are mangled. + // This attribute makes sure that we later know that this foreign item's symbol should not be. + foreign_item_attrs.push(ecx.attr_word(sym::rustc_eii_extern_item, eii_attr_span)); let abi = match func.sig.header.ext { // extern "X" fn => extern "X" {} @@ -196,85 +302,69 @@ fn eii_( suffix: None, symbol_unescaped: sym::Rust, style: ast::StrStyle::Cooked, - span, + span: eii_attr_span, }), }; // ABI has been moved to the extern {} block, so we remove it from the fn item. func.sig.header.ext = ast::Extern::None; + func.body = None; // And mark safe functions explicitly as `safe fn`. if func.sig.header.safety == ast::Safety::Default { func.sig.header.safety = ast::Safety::Safe(func.sig.span); } - // extern "…" { safe fn item(); } - let mut extern_item_attrs = attrs.clone(); - extern_item_attrs.push(ast::Attribute { - kind: ast::AttrKind::Normal(Box::new(ast::NormalAttr { - item: ast::AttrItem { - unsafety: ast::Safety::Default, - // Add the rustc_eii_extern_item on the foreign item. Usually, foreign items are mangled. - // This attribute makes sure that we later know that this foreign item's symbol should not be. - path: ast::Path::from_ident(Ident::new(sym::rustc_eii_extern_item, span)), - args: ast::AttrArgs::Empty, - tokens: None, - }, - tokens: None, - })), - id: ecx.sess.psess.attr_id_generator.mk_attr_id(), - style: ast::AttrStyle::Outer, - span, - }); - - let extern_block = Box::new(ast::Item { + ast::Item { attrs: ast::AttrVec::default(), id: ast::DUMMY_NODE_ID, - span, - vis: ast::Visibility { span, kind: ast::VisibilityKind::Inherited, tokens: None }, + span: eii_attr_span, + vis: ast::Visibility { + span: eii_attr_span, + kind: ast::VisibilityKind::Inherited, + tokens: None, + }, kind: ast::ItemKind::ForeignMod(ast::ForeignMod { - extern_span: span, - safety: ast::Safety::Unsafe(span), + extern_span: eii_attr_span, + safety: ast::Safety::Unsafe(eii_attr_span), abi, items: From::from([Box::new(ast::ForeignItem { - attrs: extern_item_attrs, + attrs: foreign_item_attrs, id: ast::DUMMY_NODE_ID, span: item_span, vis, - kind: ast::ForeignItemKind::Fn(func.clone()), + kind: ast::ForeignItemKind::Fn(Box::new(func.clone())), tokens: None, })]), }), tokens: None, - }); + } +} - let mut macro_attrs = attrs.clone(); - macro_attrs.push( - // #[builtin_macro(eii_shared_macro)] - ast::Attribute { - kind: ast::AttrKind::Normal(Box::new(ast::NormalAttr { - item: ast::AttrItem { - unsafety: ast::Safety::Default, - path: ast::Path::from_ident(Ident::new(sym::rustc_builtin_macro, span)), - args: ast::AttrArgs::Delimited(ast::DelimArgs { - dspan: DelimSpan::from_single(span), - delim: Delimiter::Parenthesis, - tokens: TokenStream::new(vec![tokenstream::TokenTree::token_alone( - token::TokenKind::Ident(sym::eii_shared_macro, token::IdentIsRaw::No), - span, - )]), - }), - tokens: None, - }, - tokens: None, - })), - id: ecx.sess.psess.attr_id_generator.mk_attr_id(), - style: ast::AttrStyle::Outer, - span, - }, - ); +/// Generate a stub macro (a bit like in core) that will roughly look like: +/// +/// ```rust, ignore, example +/// // Since this a stub macro, the actual code that expands it lives in the compiler. +/// // This attribute tells the compiler that +/// #[builtin_macro(eii_shared_macro)] +/// // the metadata to link this macro to the generated foreign item. +/// #[eii_extern_target()] +/// macro macro_name { () => {} } +/// ``` +fn generate_attribute_macro_to_implement( + ecx: &mut ExtCtxt<'_>, + span: Span, + macro_name: Ident, + foreign_item_name: Ident, + impl_unsafe: bool, + decl_span: Span, +) -> ast::Item { + let mut macro_attrs = ThinVec::new(); - let macro_def = Box::new(ast::Item { + // #[builtin_macro(eii_shared_macro)] + macro_attrs.push(ecx.attr_nested_word(sym::rustc_builtin_macro, sym::eii_shared_macro, span)); + + ast::Item { attrs: macro_attrs, id: ast::DUMMY_NODE_ID, span, @@ -305,33 +395,15 @@ fn eii_( ]), }), macro_rules: false, - // #[eii_extern_target(func.ident)] + // #[eii_extern_target(foreign_item_ident)] eii_extern_target: Some(ast::EiiExternTarget { - extern_item_path: ast::Path::from_ident(func.ident), + extern_item_path: ast::Path::from_ident(foreign_item_name), impl_unsafe, span: decl_span, }), }, ), tokens: None, - }); - - return_items.push(extern_block); - return_items.push(macro_def); - - if stmt { - return_items - .into_iter() - .map(|i| { - Annotatable::Stmt(Box::new(Stmt { - id: DUMMY_NODE_ID, - kind: StmtKind::Item(i), - span, - })) - }) - .collect() - } else { - return_items.into_iter().map(|i| Annotatable::Item(i)).collect() } } @@ -436,10 +508,10 @@ pub(crate) fn eii_shared_macro( f.eii_impls.push(EiiImpl { node_id: DUMMY_NODE_ID, + inner_span: meta_item.path.span, eii_macro_path: meta_item.path.clone(), impl_safety: meta_item.unsafety, span, - inner_span: meta_item.path.span, is_default, }); From c316c05dc512bba366d461e1719f0a8620a07453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 19 Dec 2025 14:42:20 +0100 Subject: [PATCH 1048/3801] refactor how eii expansion is wrapped fixing 149980 --- compiler/rustc_builtin_macros/src/eii.rs | 45 +++++++++----------- tests/ui/eii/error_statement_position.rs | 10 +++++ tests/ui/eii/error_statement_position.stderr | 8 ++++ 3 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 tests/ui/eii/error_statement_position.stderr diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index e29b29fc6ccb..9049639925dd 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -60,12 +60,18 @@ fn eii_( ) -> Vec { let eii_attr_span = ecx.with_def_site_ctxt(eii_attr_span); - let (item, stmt) = if let Annotatable::Item(item) = item { - (item, false) + let (item, wrap_item): (_, &dyn Fn(_) -> _) = if let Annotatable::Item(item) = item { + (item, &Annotatable::Item) } else if let Annotatable::Stmt(ref stmt) = item && let StmtKind::Item(ref item) = stmt.kind { - (item.clone(), true) + (item.clone(), &|item| { + Annotatable::Stmt(Box::new(Stmt { + id: DUMMY_NODE_ID, + kind: StmtKind::Item(item), + span: eii_attr_span, + })) + }) } else { ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { span: eii_attr_span, @@ -74,23 +80,25 @@ fn eii_( return vec![item]; }; - let orig_item = item.clone(); - - let item = *item; - - let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } = item else { + let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } = + item.as_ref() + else { ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { span: eii_attr_span, name: path_to_string(&meta_item.path), }); - return vec![Annotatable::Item(Box::new(item))]; + return vec![wrap_item(item)]; }; + // only clone what we need + let attrs = attrs.clone(); + let func = (**func).clone(); + let vis = vis.clone(); let attrs_from_decl = filter_attrs_for_multiple_eii_attr(ecx, attrs, eii_attr_span, &meta_item.path); let Ok(macro_name) = name_for_impl_macro(ecx, &func, &meta_item) else { - return vec![Annotatable::Item(orig_item)]; + return vec![wrap_item(item)]; }; // span of the declaring item without attributes @@ -115,7 +123,7 @@ fn eii_( ecx, eii_attr_span, item_span, - *func, + func, vis, &attrs_from_decl, ))); @@ -128,20 +136,7 @@ fn eii_( decl_span, ))); - if stmt { - return_items - .into_iter() - .map(|i| { - Annotatable::Stmt(Box::new(Stmt { - id: DUMMY_NODE_ID, - kind: StmtKind::Item(i), - span: eii_attr_span, - })) - }) - .collect() - } else { - return_items.into_iter().map(|i| Annotatable::Item(i)).collect() - } + return_items.into_iter().map(wrap_item).collect() } /// Decide on the name of the macro that can be used to implement the EII. diff --git a/tests/ui/eii/error_statement_position.rs b/tests/ui/eii/error_statement_position.rs index a9c606991574..cf81e7e6a8b2 100644 --- a/tests/ui/eii/error_statement_position.rs +++ b/tests/ui/eii/error_statement_position.rs @@ -1,6 +1,16 @@ #![feature(extern_item_impls)] +// EIIs can, despite not being super useful, be declared in statement position +// nested inside items. Items in statement position, when expanded as part of a macro, +// need to be wrapped slightly differently (in an `ast::Statement`). +// We did this on the happy path (no errors), but when there was an error, we'd +// replace it with *just* an `ast::Item` not wrapped in an `ast::Statement`. +// This caused an ICE (https://github.com/rust-lang/rust/issues/149980). +// this test fails to build, but demonstrates that no ICE is produced. fn main() { + struct Bar; + #[eii] + //~^ ERROR `#[eii]` is only valid on functions impl Bar {} } diff --git a/tests/ui/eii/error_statement_position.stderr b/tests/ui/eii/error_statement_position.stderr new file mode 100644 index 000000000000..01b7394ef00f --- /dev/null +++ b/tests/ui/eii/error_statement_position.stderr @@ -0,0 +1,8 @@ +error: `#[eii]` is only valid on functions + --> $DIR/error_statement_position.rs:13:5 + | +LL | #[eii] + | ^^^^^^ + +error: aborting due to 1 previous error + From c34ea6e56dcea96bed3739c37580bd559c75c0e8 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 19 Dec 2025 11:02:57 -0800 Subject: [PATCH 1049/3801] remove llvm_enzyme and enzyme fallbacks from most places, enable the autodiff frontend on nightly --- compiler/rustc_builtin_macros/messages.ftl | 1 - compiler/rustc_builtin_macros/src/autodiff.rs | 5 - compiler/rustc_builtin_macros/src/errors.rs | 11 -- compiler/rustc_codegen_llvm/Cargo.toml | 4 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 1 - compiler/rustc_codegen_llvm/src/back/write.rs | 6 +- compiler/rustc_codegen_llvm/src/errors.rs | 1 - compiler/rustc_codegen_llvm/src/lib.rs | 4 +- .../rustc_codegen_llvm/src/llvm/enzyme_ffi.rs | 143 ------------------ compiler/rustc_codegen_llvm/src/typetree.rs | 36 ++--- tests/pretty/autodiff/autodiff_forward.pp | 2 +- tests/pretty/autodiff/autodiff_forward.rs | 2 +- tests/pretty/autodiff/autodiff_reverse.pp | 2 +- tests/pretty/autodiff/autodiff_reverse.rs | 2 +- tests/pretty/autodiff/inherent_impl.pp | 2 +- tests/pretty/autodiff/inherent_impl.rs | 2 +- tests/ui/autodiff/visibility.rs | 2 +- .../autodiff/visibility.std_autodiff.stderr | 10 +- ... feature-gate-autodiff-use.nightly.stderr} | 2 +- .../feature-gate-autodiff-use.rs | 21 ++- ...> feature-gate-autodiff-use.stable.stderr} | 10 +- 21 files changed, 46 insertions(+), 223 deletions(-) rename tests/ui/feature-gates/{feature-gate-autodiff-use.has_support.stderr => feature-gate-autodiff-use.nightly.stderr} (95%) rename tests/ui/feature-gates/{feature-gate-autodiff-use.no_support.stderr => feature-gate-autodiff-use.stable.stderr} (78%) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 542f34d9d831..f0f6f2dcf82c 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -55,7 +55,6 @@ builtin_macros_assert_requires_expression = macro requires an expression as an a builtin_macros_autodiff = autodiff must be applied to function builtin_macros_autodiff_missing_config = autodiff requires at least a name and mode builtin_macros_autodiff_mode_activity = {$act} can not be used in {$mode} Mode -builtin_macros_autodiff_not_build = this rustc version does not support autodiff builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found} builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode} Mode builtin_macros_autodiff_ty_activity = {$act} can not be used for this type diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 6bf985fcc9f0..39abb66df30c 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -209,11 +209,6 @@ mod llvm_enzyme { mut item: Annotatable, mode: DiffMode, ) -> Vec { - // FIXME(bjorn3) maybe have the backend directly tell if autodiff is supported? - if cfg!(not(feature = "llvm_enzyme")) { - ecx.sess.dcx().emit_err(errors::AutoDiffSupportNotBuild { span: meta_item.span }); - return vec![item]; - } let dcx = ecx.sess.dcx(); // first get information about the annotable item: visibility, signature, name and generic diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 2a4c499349ad..ad31eae10f60 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -216,17 +216,6 @@ mod autodiff { } } -pub(crate) use ad_fallback::*; -mod ad_fallback { - use super::*; - #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_not_build)] - pub(crate) struct AutoDiffSupportNotBuild { - #[primary_span] - pub(crate) span: Span, - } -} - #[derive(Diagnostic)] #[diag(builtin_macros_concat_bytes_invalid)] pub(crate) struct ConcatBytesInvalid { diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 076ec5e59eb6..b40962b759d8 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -14,7 +14,7 @@ bitflags = "2.4.1" gimli = "0.31" itertools = "0.12" libc = "0.2" -libloading = { version = "0.9.0", optional = true } +libloading = { version = "0.9.0" } measureme = "12.0.1" object = { version = "0.37.0", default-features = false, features = ["std", "read"] } rustc-demangle = "0.1.21" @@ -47,7 +47,7 @@ tracing = "0.1" [features] # tidy-alphabetical-start check_only = ["rustc_llvm/check_only"] -llvm_enzyme = ["dep:libloading"] +llvm_enzyme = [] llvm_offload = [] # tidy-alphabetical-end diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 314e64272ffe..52c2ca7b1696 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -528,7 +528,6 @@ fn thin_lto( } } -#[cfg(feature = "llvm_enzyme")] pub(crate) fn enable_autodiff_settings(ad: &[config::AutoDiff]) { let mut enzyme = llvm::EnzymeWrapper::get_instance(); diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 18da945f5a31..f5566cc84ce9 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -568,8 +568,7 @@ pub(crate) unsafe fn llvm_optimize( // FIXME(ZuseZ4): In a future update we could figure out how to only optimize individual functions getting // differentiated. - let consider_ad = - cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable); + let consider_ad = config.autodiff.contains(&config::AutoDiff::Enable); let run_enzyme = autodiff_stage == AutodiffStage::DuringAD; let print_before_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModBefore); let print_after_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModAfter); @@ -819,8 +818,7 @@ pub(crate) fn optimize( // If we know that we will later run AD, then we disable vectorization and loop unrolling. // Otherwise we pretend AD is already done and run the normal opt pipeline (=PostAD). - let consider_ad = - cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable); + let consider_ad = config.autodiff.contains(&config::AutoDiff::Enable); let autodiff_stage = if consider_ad { AutodiffStage::PreAD } else { AutodiffStage::PostAD }; // The embedded bitcode is used to run LTO/ThinLTO. // The bitcode obtained during the `codegen` phase is no longer suitable for performing LTO. diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index f2e147b1ee0a..b59067b9745b 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -32,7 +32,6 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { } } -#[cfg(feature = "llvm_enzyme")] #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_component_unavailable)] pub(crate) struct AutoDiffComponentUnavailable; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 4d0f8dbb9302..d96d7d13e7cc 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -242,7 +242,9 @@ impl CodegenBackend for LlvmCodegenBackend { fn init(&self, sess: &Session) { llvm_util::init(sess); // Make sure llvm is inited - #[cfg(feature = "llvm_enzyme")] + // autodiff is based on Enzyme, a library which we might not have available, when it was + // neither build, nor downloaded via rustup. If autodiff is used, but not available we emit + // an early error here and abort compilation. { use rustc_session::config::AutoDiff; diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 956a4e43a7de..b11310b970d0 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -86,10 +86,8 @@ pub(crate) enum LLVMRustVerifierFailureAction { LLVMReturnStatusAction = 2, } -#[cfg(feature = "llvm_enzyme")] pub(crate) use self::Enzyme_AD::*; -#[cfg(feature = "llvm_enzyme")] pub(crate) mod Enzyme_AD { use std::ffi::{c_char, c_void}; use std::sync::{Mutex, MutexGuard, OnceLock}; @@ -450,147 +448,6 @@ pub(crate) mod Enzyme_AD { } } -#[cfg(not(feature = "llvm_enzyme"))] -pub(crate) use self::Fallback_AD::*; - -#[cfg(not(feature = "llvm_enzyme"))] -pub(crate) mod Fallback_AD { - #![allow(unused_variables)] - - use std::ffi::c_void; - use std::sync::{Mutex, MutexGuard}; - - use libc::c_char; - use rustc_codegen_ssa::back::write::CodegenContext; - use rustc_codegen_ssa::traits::WriteBackendMethods; - - use super::{CConcreteType, CTypeTreeRef, Context, EnzymeTypeTree}; - - pub(crate) struct EnzymeWrapper { - pub registerEnzymeAndPassPipeline: *const c_void, - } - - impl EnzymeWrapper { - pub(crate) fn get_or_init( - _sysroot: &rustc_session::config::Sysroot, - ) -> Result, Box> { - unimplemented!("Enzyme not available: build with llvm_enzyme feature") - } - - pub(crate) fn init<'a, B: WriteBackendMethods>( - _cgcx: &'a CodegenContext, - ) -> &'static Mutex { - unimplemented!("Enzyme not available: build with llvm_enzyme feature") - } - - pub(crate) fn get_instance() -> MutexGuard<'static, Self> { - unimplemented!("Enzyme not available: build with llvm_enzyme feature") - } - - pub(crate) fn new_type_tree(&self) -> CTypeTreeRef { - unimplemented!() - } - - pub(crate) fn new_type_tree_ct( - &self, - t: CConcreteType, - ctx: &Context, - ) -> *mut EnzymeTypeTree { - unimplemented!() - } - - pub(crate) fn new_type_tree_tr(&self, tree: CTypeTreeRef) -> CTypeTreeRef { - unimplemented!() - } - - pub(crate) fn free_type_tree(&self, tree: CTypeTreeRef) { - unimplemented!() - } - - pub(crate) fn merge_type_tree(&self, tree1: CTypeTreeRef, tree2: CTypeTreeRef) -> bool { - unimplemented!() - } - - pub(crate) fn tree_only_eq(&self, tree: CTypeTreeRef, num: i64) { - unimplemented!() - } - - pub(crate) fn tree_data0_eq(&self, tree: CTypeTreeRef) { - unimplemented!() - } - - pub(crate) fn shift_indicies_eq( - &self, - tree: CTypeTreeRef, - data_layout: *const c_char, - offset: i64, - max_size: i64, - add_offset: u64, - ) { - unimplemented!() - } - - pub(crate) fn tree_insert_eq( - &self, - tree: CTypeTreeRef, - indices: *const i64, - len: usize, - ct: CConcreteType, - ctx: &Context, - ) { - unimplemented!() - } - - pub(crate) fn tree_to_string(&self, tree: *mut EnzymeTypeTree) -> *const c_char { - unimplemented!() - } - - pub(crate) fn tree_to_string_free(&self, ch: *const c_char) { - unimplemented!() - } - - pub(crate) fn get_max_type_depth(&self) -> usize { - unimplemented!() - } - - pub(crate) fn set_inline(&mut self, val: bool) { - unimplemented!() - } - - pub(crate) fn set_print_perf(&mut self, print: bool) { - unimplemented!() - } - - pub(crate) fn set_print_activity(&mut self, print: bool) { - unimplemented!() - } - - pub(crate) fn set_print_type(&mut self, print: bool) { - unimplemented!() - } - - pub(crate) fn set_print_type_fun(&mut self, fun_name: &str) { - unimplemented!() - } - - pub(crate) fn set_print(&mut self, print: bool) { - unimplemented!() - } - - pub(crate) fn set_strict_aliasing(&mut self, strict: bool) { - unimplemented!() - } - - pub(crate) fn set_loose_types(&mut self, loose: bool) { - unimplemented!() - } - - pub(crate) fn set_rust_rules(&mut self, val: bool) { - unimplemented!() - } - } -} - impl TypeTree { pub(crate) fn new() -> TypeTree { let wrapper = EnzymeWrapper::get_instance(); diff --git a/compiler/rustc_codegen_llvm/src/typetree.rs b/compiler/rustc_codegen_llvm/src/typetree.rs index 513a832e7fe8..4f433f273c8c 100644 --- a/compiler/rustc_codegen_llvm/src/typetree.rs +++ b/compiler/rustc_codegen_llvm/src/typetree.rs @@ -1,15 +1,10 @@ -use rustc_ast::expand::typetree::FncTree; -#[cfg(feature = "llvm_enzyme")] -use { - crate::attributes, - crate::llvm::EnzymeWrapper, - rustc_ast::expand::typetree::TypeTree as RustTypeTree, - std::ffi::{CString, c_char, c_uint}, -}; +use std::ffi::{CString, c_char, c_uint}; -use crate::llvm::{self, Value}; +use rustc_ast::expand::typetree::{FncTree, TypeTree as RustTypeTree}; + +use crate::attributes; +use crate::llvm::{self, EnzymeWrapper, Value}; -#[cfg(feature = "llvm_enzyme")] fn to_enzyme_typetree( rust_typetree: RustTypeTree, _data_layout: &str, @@ -19,7 +14,6 @@ fn to_enzyme_typetree( process_typetree_recursive(&mut enzyme_tt, &rust_typetree, &[], llcx); enzyme_tt } -#[cfg(feature = "llvm_enzyme")] fn process_typetree_recursive( enzyme_tt: &mut llvm::TypeTree, rust_typetree: &RustTypeTree, @@ -57,13 +51,21 @@ fn process_typetree_recursive( } } -#[cfg(feature = "llvm_enzyme")] +#[cfg_attr(not(feature = "llvm_enzyme"), allow(unused))] pub(crate) fn add_tt<'ll>( llmod: &'ll llvm::Module, llcx: &'ll llvm::Context, fn_def: &'ll Value, tt: FncTree, ) { + // TypeTree processing uses functions from Enzyme, which we might not have available if we did + // not build this compiler with `llvm_enzyme`. This feature is not strictly necessary, but + // skipping this function increases the chance that Enzyme fails to compile some code. + // FIXME(autodiff): In the future we should conditionally run this function even without the + // `llvm_enzyme` feature, in case that libEnzyme was provided via rustup. + #[cfg(not(feature = "llvm_enzyme"))] + return; + let inputs = tt.args; let ret_tt: RustTypeTree = tt.ret; @@ -113,13 +115,3 @@ pub(crate) fn add_tt<'ll>( enzyme_wrapper.tree_to_string_free(c_str.as_ptr()); } } - -#[cfg(not(feature = "llvm_enzyme"))] -pub(crate) fn add_tt<'ll>( - _llmod: &'ll llvm::Module, - _llcx: &'ll llvm::Context, - _fn_def: &'ll Value, - _tt: FncTree, -) { - unimplemented!() -} diff --git a/tests/pretty/autodiff/autodiff_forward.pp b/tests/pretty/autodiff/autodiff_forward.pp index 6eddb5669c7a..ea4e294f1ac3 100644 --- a/tests/pretty/autodiff/autodiff_forward.pp +++ b/tests/pretty/autodiff/autodiff_forward.pp @@ -1,6 +1,6 @@ #![feature(prelude_import)] #![no_std] -//@ needs-enzyme +//@ only-nightly #![feature(autodiff)] #[macro_use] diff --git a/tests/pretty/autodiff/autodiff_forward.rs b/tests/pretty/autodiff/autodiff_forward.rs index e23a1b3e241e..4fa02bc85e3e 100644 --- a/tests/pretty/autodiff/autodiff_forward.rs +++ b/tests/pretty/autodiff/autodiff_forward.rs @@ -1,4 +1,4 @@ -//@ needs-enzyme +//@ only-nightly #![feature(autodiff)] //@ pretty-mode:expanded diff --git a/tests/pretty/autodiff/autodiff_reverse.pp b/tests/pretty/autodiff/autodiff_reverse.pp index 8f598b865c7b..9202e0a76635 100644 --- a/tests/pretty/autodiff/autodiff_reverse.pp +++ b/tests/pretty/autodiff/autodiff_reverse.pp @@ -1,6 +1,6 @@ #![feature(prelude_import)] #![no_std] -//@ needs-enzyme +//@ only-nightly #![feature(autodiff)] #[macro_use] diff --git a/tests/pretty/autodiff/autodiff_reverse.rs b/tests/pretty/autodiff/autodiff_reverse.rs index c50b81d7780d..f1a8f9b50a77 100644 --- a/tests/pretty/autodiff/autodiff_reverse.rs +++ b/tests/pretty/autodiff/autodiff_reverse.rs @@ -1,4 +1,4 @@ -//@ needs-enzyme +//@ only-nightly #![feature(autodiff)] //@ pretty-mode:expanded diff --git a/tests/pretty/autodiff/inherent_impl.pp b/tests/pretty/autodiff/inherent_impl.pp index 36a9222640ae..bc70c4076121 100644 --- a/tests/pretty/autodiff/inherent_impl.pp +++ b/tests/pretty/autodiff/inherent_impl.pp @@ -1,6 +1,6 @@ #![feature(prelude_import)] #![no_std] -//@ needs-enzyme +//@ only-nightly #![feature(autodiff)] #[macro_use] diff --git a/tests/pretty/autodiff/inherent_impl.rs b/tests/pretty/autodiff/inherent_impl.rs index 11ff209f9d89..e2702b7e51f6 100644 --- a/tests/pretty/autodiff/inherent_impl.rs +++ b/tests/pretty/autodiff/inherent_impl.rs @@ -1,4 +1,4 @@ -//@ needs-enzyme +//@ only-nightly #![feature(autodiff)] //@ pretty-mode:expanded diff --git a/tests/ui/autodiff/visibility.rs b/tests/ui/autodiff/visibility.rs index a84df75e7996..3cf13b5b5dce 100644 --- a/tests/ui/autodiff/visibility.rs +++ b/tests/ui/autodiff/visibility.rs @@ -1,5 +1,6 @@ //@ ignore-enzyme //@ revisions: std_autodiff no_std_autodiff +//@ only-nightly //@[no_std_autodiff] check-pass //@ proc-macro: my_macro.rs #![crate_type = "lib"] @@ -12,5 +13,4 @@ use my_macro::autodiff_forward; // bring `autodiff_forward` in scope #[autodiff_forward(dfoo)] //[std_autodiff]~^^^ ERROR the name `autodiff_forward` is defined multiple times -//[std_autodiff]~^^ ERROR this rustc version does not support autodiff fn foo() {} diff --git a/tests/ui/autodiff/visibility.std_autodiff.stderr b/tests/ui/autodiff/visibility.std_autodiff.stderr index e45f1139012a..6a0cdd492e2d 100644 --- a/tests/ui/autodiff/visibility.std_autodiff.stderr +++ b/tests/ui/autodiff/visibility.std_autodiff.stderr @@ -1,5 +1,5 @@ error[E0252]: the name `autodiff_forward` is defined multiple times - --> $DIR/visibility.rs:11:5 + --> $DIR/visibility.rs:12:5 | LL | use std::autodiff::autodiff_forward; | ------------------------------- previous import of the macro `autodiff_forward` here @@ -13,12 +13,6 @@ help: you can use `as` to change the binding name of the import LL | use my_macro::autodiff_forward as other_autodiff_forward; // bring `autodiff_forward` in scope | +++++++++++++++++++++++++ -error: this rustc version does not support autodiff - --> $DIR/visibility.rs:13:1 - | -LL | #[autodiff_forward(dfoo)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0252`. diff --git a/tests/ui/feature-gates/feature-gate-autodiff-use.has_support.stderr b/tests/ui/feature-gates/feature-gate-autodiff-use.nightly.stderr similarity index 95% rename from tests/ui/feature-gates/feature-gate-autodiff-use.has_support.stderr rename to tests/ui/feature-gates/feature-gate-autodiff-use.nightly.stderr index e5edd8e45e6c..ca724632063d 100644 --- a/tests/ui/feature-gates/feature-gate-autodiff-use.has_support.stderr +++ b/tests/ui/feature-gates/feature-gate-autodiff-use.nightly.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature `autodiff` - --> $DIR/feature-gate-autodiff-use.rs:13:3 + --> $DIR/feature-gate-autodiff-use.rs:16:3 | LL | #[autodiff_reverse(dfoo)] | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-autodiff-use.rs b/tests/ui/feature-gates/feature-gate-autodiff-use.rs index 2864b786c121..d97c06de7de5 100644 --- a/tests/ui/feature-gates/feature-gate-autodiff-use.rs +++ b/tests/ui/feature-gates/feature-gate-autodiff-use.rs @@ -1,17 +1,22 @@ -//@ revisions: has_support no_support -//@[no_support] ignore-enzyme -//@[has_support] needs-enzyme +//@ revisions: nightly stable +//@[nightly] only-nightly +//@[stable] only-stable // This checks that without enabling the autodiff feature, we can't import std::autodiff::autodiff; #![crate_type = "lib"] use std::autodiff::autodiff_reverse; -//[has_support]~^ ERROR use of unstable library feature `autodiff` -//[no_support]~^^ ERROR use of unstable library feature `autodiff` +//[nightly]~^ ERROR use of unstable library feature `autodiff` +//[stable]~^^ ERROR use of unstable library feature `autodiff` +//[stable]~| NOTE see issue #124509 for more information +//[stable]~| HELP add `#![feature(autodiff)]` to the crate attributes to enable +//[stable]~| NOTE this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date #[autodiff_reverse(dfoo)] -//[has_support]~^ ERROR use of unstable library feature `autodiff` [E0658] -//[no_support]~^^ ERROR use of unstable library feature `autodiff` [E0658] -//[no_support]~| ERROR this rustc version does not support autodiff +//[nightly]~^ ERROR use of unstable library feature `autodiff` [E0658] +//[stable]~^^ ERROR use of unstable library feature `autodiff` [E0658] +//[stable]~| NOTE see issue #124509 for more information +//[stable]~| HELP add `#![feature(autodiff)]` to the crate attributes to enable +//[stable]~| NOTE this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date fn foo() {} diff --git a/tests/ui/feature-gates/feature-gate-autodiff-use.no_support.stderr b/tests/ui/feature-gates/feature-gate-autodiff-use.stable.stderr similarity index 78% rename from tests/ui/feature-gates/feature-gate-autodiff-use.no_support.stderr rename to tests/ui/feature-gates/feature-gate-autodiff-use.stable.stderr index 65ba033b3589..ca724632063d 100644 --- a/tests/ui/feature-gates/feature-gate-autodiff-use.no_support.stderr +++ b/tests/ui/feature-gates/feature-gate-autodiff-use.stable.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature `autodiff` - --> $DIR/feature-gate-autodiff-use.rs:13:3 + --> $DIR/feature-gate-autodiff-use.rs:16:3 | LL | #[autodiff_reverse(dfoo)] | ^^^^^^^^^^^^^^^^ @@ -8,12 +8,6 @@ LL | #[autodiff_reverse(dfoo)] = help: add `#![feature(autodiff)]` 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: this rustc version does not support autodiff - --> $DIR/feature-gate-autodiff-use.rs:13:1 - | -LL | #[autodiff_reverse(dfoo)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0658]: use of unstable library feature `autodiff` --> $DIR/feature-gate-autodiff-use.rs:9:5 | @@ -24,6 +18,6 @@ LL | use std::autodiff::autodiff_reverse; = help: add `#![feature(autodiff)]` 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 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. From 4ee01c4e4c9a8aea2ded93eca66785fbb0a5f014 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 19 Dec 2025 20:17:46 +0100 Subject: [PATCH 1050/3801] Add `target_feature = "gc"` for Wasm --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 4 ++++ compiler/rustc_target/src/target_features.rs | 1 + tests/ui/check-cfg/target_feature.stderr | 1 + 3 files changed, 6 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 682484595a89..2e1d0cfada5b 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -266,6 +266,10 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Some(LLVMFeature::new("hasleoncasa")), s => Some(LLVMFeature::new(s)), }, + Arch::Wasm32 | Arch::Wasm64 => match s { + "gc" if major < 22 => None, + s => Some(LLVMFeature::new(s)), + }, Arch::X86 | Arch::X86_64 => { match s { "sse4.2" => Some(LLVMFeature::with_dependencies( diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index e516a31d1e66..35cfeba2bffd 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -745,6 +745,7 @@ static WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("bulk-memory", Stable, &[]), ("exception-handling", Unstable(sym::wasm_target_feature), &[]), ("extended-const", Stable, &[]), + ("gc", Unstable(sym::wasm_target_feature), &["reference-types"]), ("multivalue", Stable, &[]), ("mutable-globals", Stable, &[]), ("nontrapping-fptoint", Stable, &[]), diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index d25e7f094964..72edc03e10a4 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -121,6 +121,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `frecipe` `frintts` `fxsr` +`gc` `gfni` `guarded-storage` `hard-float` From cbc05da116b9ebc7a35fb57fcda4c8079bdd4316 Mon Sep 17 00:00:00 2001 From: Asuka Minato Date: Sat, 20 Dec 2025 05:04:58 +0900 Subject: [PATCH 1051/3801] fix test case --- .../macro_expansion_tests/mbe/regression.rs | 36 +++++++++++++++++++ .../rust-analyzer/crates/mbe/src/expander.rs | 13 +++++-- .../crates/mbe/src/expander/matcher.rs | 27 ++++++++------ .../crates/mbe/src/expander/transcriber.rs | 11 ++++-- 4 files changed, 72 insertions(+), 15 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs index e2022c7967d8..ddabb50251a4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs @@ -108,6 +108,42 @@ fn main() { ); } +#[test] +fn ty_fragment_followed_by_expr() { + check( + r#" +macro_rules! a { + ($t:tt) => {}; +} + +macro_rules! b { + ($t:ty) => { + a!($t); + }; +} + +fn main() { + b!(&'static str); +} +"#, + expect![[r#" +macro_rules! a { + ($t:tt) => {}; +} + +macro_rules! b { + ($t:ty) => { + a!($t); + }; +} + +fn main() { + a!(&'static str);; +} +"#]], + ); +} + #[test] fn test_winapi_struct() { // from https://github.com/retep998/winapi-rs/blob/a7ef2bca086aae76cf6c4ce4c2552988ed9798ad/src/macros.rs#L366 diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander.rs b/src/tools/rust-analyzer/crates/mbe/src/expander.rs index 6510fefcb6ad..274b779c1b2e 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander.rs @@ -128,7 +128,10 @@ enum Fragment<'a> { #[default] Empty, /// token fragments are just copy-pasted into the output - Tokens(tt::TokenTreesView<'a, Span>), + Tokens { + tree: tt::TokenTreesView<'a, Span>, + origin: TokensOrigin, + }, /// Expr ast fragments are surrounded with `()` on transcription to preserve precedence. /// Note that this impl is different from the one currently in `rustc` -- /// `rustc` doesn't translate fragments into token trees at all. @@ -156,10 +159,16 @@ impl Fragment<'_> { fn is_empty(&self) -> bool { match self { Fragment::Empty => true, - Fragment::Tokens(it) => it.len() == 0, + Fragment::Tokens { tree, .. } => tree.len() == 0, Fragment::Expr(it) => it.len() == 0, Fragment::Path(it) => it.len() == 0, Fragment::TokensOwned(it) => it.0.is_empty(), } } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum TokensOrigin { + Raw, + Ast, +} diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs index 4da8b309f005..a21468fbb0d5 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs @@ -71,7 +71,7 @@ use tt::{ use crate::{ ExpandError, ExpandErrorKind, MetaTemplate, ValueResult, - expander::{Binding, Bindings, ExpandResult, Fragment}, + expander::{Binding, Bindings, ExpandResult, Fragment, TokensOrigin}, expect_fragment, parser::{ExprKind, MetaVarKind, Op, RepeatKind, Separator}, }; @@ -842,18 +842,23 @@ fn match_meta_var<'t>( } .err(); let tt_result = input.from_savepoint(savepoint); - return ValueResult { value: Fragment::Tokens(tt_result), err }; + return ValueResult { + value: Fragment::Tokens { tree: tt_result, origin: TokensOrigin::Raw }, + err, + }; } - MetaVarKind::Ty => parser::PrefixEntryPoint::Ty, - MetaVarKind::Pat => parser::PrefixEntryPoint::PatTop, - MetaVarKind::PatParam => parser::PrefixEntryPoint::Pat, - MetaVarKind::Stmt => parser::PrefixEntryPoint::Stmt, - MetaVarKind::Block => parser::PrefixEntryPoint::Block, - MetaVarKind::Meta => parser::PrefixEntryPoint::MetaItem, - MetaVarKind::Item => parser::PrefixEntryPoint::Item, - MetaVarKind::Vis => parser::PrefixEntryPoint::Vis, + MetaVarKind::Ty => (parser::PrefixEntryPoint::Ty, TokensOrigin::Ast), + MetaVarKind::Pat => (parser::PrefixEntryPoint::PatTop, TokensOrigin::Ast), + MetaVarKind::PatParam => (parser::PrefixEntryPoint::Pat, TokensOrigin::Ast), + MetaVarKind::Stmt => (parser::PrefixEntryPoint::Stmt, TokensOrigin::Ast), + MetaVarKind::Block => (parser::PrefixEntryPoint::Block, TokensOrigin::Ast), + MetaVarKind::Meta => (parser::PrefixEntryPoint::MetaItem, TokensOrigin::Ast), + MetaVarKind::Item => (parser::PrefixEntryPoint::Item, TokensOrigin::Ast), + MetaVarKind::Vis => (parser::PrefixEntryPoint::Vis, TokensOrigin::Ast), }; - expect_fragment(db, input, fragment, delim_span).map(Fragment::Tokens) + let (entry_point, origin) = fragment; + expect_fragment(db, input, entry_point, delim_span) + .map(|tree| Fragment::Tokens { tree, origin }) } fn collect_vars(collector_fun: &mut impl FnMut(Symbol), pattern: &MetaTemplate) { diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs index 3e4ab8bdc1d8..006ef1af806e 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs @@ -5,6 +5,7 @@ use intern::{Symbol, sym}; use span::{Edition, Span}; use tt::{Delimiter, TopSubtreeBuilder, iter::TtElement}; +use super::TokensOrigin; use crate::{ ExpandError, ExpandErrorKind, ExpandResult, MetaTemplate, expander::{Binding, Bindings, Fragment}, @@ -313,7 +314,7 @@ fn expand_subtree( } }; let values = match &var_value { - Fragment::Tokens(tokens) => { + Fragment::Tokens { tree: tokens, .. } => { let mut iter = tokens.iter(); (iter.next(), iter.next()) } @@ -393,7 +394,13 @@ fn expand_var( // rustc spacing is not like ours. Ours is like proc macros', it dictates how puncts will actually be joined. // rustc uses them mostly for pretty printing. So we have to deviate a bit from what rustc does here. // Basically, a metavariable can never be joined with whatever after it. - Fragment::Tokens(tt) => builder.extend_with_tt_alone(tt.strip_invisible()), + Fragment::Tokens { tree, origin } => { + let view = match origin { + TokensOrigin::Raw => tree.strip_invisible(), + TokensOrigin::Ast => tree, + }; + builder.extend_with_tt_alone(view); + } Fragment::TokensOwned(tt) => { builder.extend_with_tt_alone(tt.view().strip_invisible()) } From 746acc47a1d068792faebd5d3a1b8ed2ac9f9ae8 Mon Sep 17 00:00:00 2001 From: Kjetil Kjeka Date: Tue, 4 Nov 2025 18:22:56 +0100 Subject: [PATCH 1052/3801] Nvptx: Use llbc as default linker --- compiler/rustc_target/src/spec/mod.rs | 5 ----- .../rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs | 4 +--- src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md | 4 ++-- tests/assembly-llvm/nvptx-arch-default.rs | 2 +- tests/assembly-llvm/nvptx-arch-target-cpu.rs | 2 +- tests/assembly-llvm/nvptx-c-abi-arg-v7.rs | 2 +- tests/assembly-llvm/nvptx-c-abi-ret-v7.rs | 2 +- .../nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs | 2 +- tests/assembly-llvm/nvptx-safe-naming.rs | 2 +- 9 files changed, 9 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 3d500694c978..b06339f59425 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2956,11 +2956,6 @@ impl Target { matches!(self.linker_flavor, LinkerFlavor::Bpf), "`linker_flavor` must be `bpf` if and only if `arch` is `bpf`" ); - check_eq!( - self.arch == Arch::Nvptx64, - matches!(self.linker_flavor, LinkerFlavor::Ptx), - "`linker_flavor` must be `ptc` if and only if `arch` is `nvptx64`" - ); for args in [ &self.pre_link_args, diff --git a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs index 35003c4d4dd6..be09681b1f35 100644 --- a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs @@ -19,9 +19,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { os: Os::Cuda, vendor: "nvidia".into(), - linker_flavor: LinkerFlavor::Ptx, - // The linker can be installed from `crates.io`. - linker: Some("rust-ptx-linker".into()), + linker_flavor: LinkerFlavor::Llbc, // With `ptx-linker` approach, it can be later overridden via link flags. cpu: "sm_30".into(), diff --git a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md index 36598982481b..0eb7e1d84bd0 100644 --- a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md +++ b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md @@ -12,7 +12,7 @@ platform. ## Requirements -This target is `no_std` and will typically be built with crate-type `cdylib` and `-C linker-flavor=llbc`, which generates PTX. +This target is `no_std`, and uses the `llvm-bitcode-linker` by default. For PTX output, build with crate-type `cdylib`. The necessary components for this workflow are: - `rustup toolchain add nightly` @@ -38,7 +38,7 @@ While the compiler accepts `#[target_feature(enable = "ptx80", enable = "sm_89") A `no_std` crate containing one or more functions with `extern "ptx-kernel"` can be compiled to PTX using a command like the following. ```console -$ RUSTFLAGS='-Ctarget-cpu=sm_89' cargo +nightly rustc --target=nvptx64-nvidia-cuda -Zbuild-std=core --crate-type=cdylib -- -Clinker-flavor=llbc -Zunstable-options +$ RUSTFLAGS='-Ctarget-cpu=sm_89' cargo +nightly rustc --target=nvptx64-nvidia-cuda -Zbuild-std=core --crate-type=cdylib ``` Intrinsics in `core::arch::nvptx` may use `#[cfg(target_feature = "...")]`, thus it's necessary to use `-Zbuild-std=core` with appropriate `RUSTFLAGS`. The following components are needed for this workflow: diff --git a/tests/assembly-llvm/nvptx-arch-default.rs b/tests/assembly-llvm/nvptx-arch-default.rs index a621fd6dcb29..22b4a680e322 100644 --- a/tests/assembly-llvm/nvptx-arch-default.rs +++ b/tests/assembly-llvm/nvptx-arch-default.rs @@ -1,5 +1,5 @@ //@ assembly-output: ptx-linker -//@ compile-flags: --crate-type cdylib -Z unstable-options -Clinker-flavor=llbc +//@ compile-flags: --crate-type cdylib //@ only-nvptx64 #![no_std] diff --git a/tests/assembly-llvm/nvptx-arch-target-cpu.rs b/tests/assembly-llvm/nvptx-arch-target-cpu.rs index 609ab297e636..e02ad0d558a9 100644 --- a/tests/assembly-llvm/nvptx-arch-target-cpu.rs +++ b/tests/assembly-llvm/nvptx-arch-target-cpu.rs @@ -1,5 +1,5 @@ //@ assembly-output: ptx-linker -//@ compile-flags: --crate-type cdylib -C target-cpu=sm_50 -Z unstable-options -Clinker-flavor=llbc +//@ compile-flags: --crate-type cdylib -C target-cpu=sm_50 //@ only-nvptx64 #![no_std] diff --git a/tests/assembly-llvm/nvptx-c-abi-arg-v7.rs b/tests/assembly-llvm/nvptx-c-abi-arg-v7.rs index be98b167470a..6f5ef792e9b3 100644 --- a/tests/assembly-llvm/nvptx-c-abi-arg-v7.rs +++ b/tests/assembly-llvm/nvptx-c-abi-arg-v7.rs @@ -1,5 +1,5 @@ //@ assembly-output: ptx-linker -//@ compile-flags: --crate-type cdylib -C target-cpu=sm_86 -Z unstable-options -Clinker-flavor=llbc +//@ compile-flags: --crate-type cdylib -C target-cpu=sm_86 //@ only-nvptx64 // The PTX ABI stability is tied to major versions of the PTX ISA diff --git a/tests/assembly-llvm/nvptx-c-abi-ret-v7.rs b/tests/assembly-llvm/nvptx-c-abi-ret-v7.rs index c68c71c872c2..02ec9facee7a 100644 --- a/tests/assembly-llvm/nvptx-c-abi-ret-v7.rs +++ b/tests/assembly-llvm/nvptx-c-abi-ret-v7.rs @@ -1,5 +1,5 @@ //@ assembly-output: ptx-linker -//@ compile-flags: --crate-type cdylib -C target-cpu=sm_86 -Z unstable-options -Clinker-flavor=llbc +//@ compile-flags: --crate-type cdylib -C target-cpu=sm_86 //@ only-nvptx64 // The PTX ABI stability is tied to major versions of the PTX ISA diff --git a/tests/assembly-llvm/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs b/tests/assembly-llvm/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs index f245b4460f2b..00f6fe9332d9 100644 --- a/tests/assembly-llvm/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs +++ b/tests/assembly-llvm/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs @@ -1,5 +1,5 @@ //@ assembly-output: ptx-linker -//@ compile-flags: --crate-type cdylib -C target-cpu=sm_86 -Z unstable-options -Clinker-flavor=llbc +//@ compile-flags: --crate-type cdylib -C target-cpu=sm_86 //@ only-nvptx64 // The following ABI tests are made with nvcc 11.6 does. diff --git a/tests/assembly-llvm/nvptx-safe-naming.rs b/tests/assembly-llvm/nvptx-safe-naming.rs index c70c63b7ee7c..85415b6ca5b5 100644 --- a/tests/assembly-llvm/nvptx-safe-naming.rs +++ b/tests/assembly-llvm/nvptx-safe-naming.rs @@ -1,5 +1,5 @@ //@ assembly-output: ptx-linker -//@ compile-flags: --crate-type cdylib -Z unstable-options -Clinker-flavor=llbc +//@ compile-flags: --crate-type cdylib //@ only-nvptx64 //@ revisions: LLVM20 LLVM21 //@ [LLVM21] min-llvm-version: 21 From 81d86bf0ebe38897ba1c79cb9a340a1342e0f22a Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 19 Dec 2025 22:03:57 +0100 Subject: [PATCH 1053/3801] Add regression test for remap-path-prefix handling in rustdoc for deps --- tests/rustdoc/auxiliary/remapped-paths.rs | 11 +++++++++++ tests/rustdoc/import-remapped-paths.rs | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/rustdoc/auxiliary/remapped-paths.rs create mode 100644 tests/rustdoc/import-remapped-paths.rs diff --git a/tests/rustdoc/auxiliary/remapped-paths.rs b/tests/rustdoc/auxiliary/remapped-paths.rs new file mode 100644 index 000000000000..f31d2d316f3a --- /dev/null +++ b/tests/rustdoc/auxiliary/remapped-paths.rs @@ -0,0 +1,11 @@ +//@ compile-flags:-Zunstable-options --remap-path-prefix={{src-base}}= + +pub struct MyStruct { + field: u32, +} + +impl MyStruct { + pub fn new() -> MyStruct { + MyStruct { field: 3 } + } +} diff --git a/tests/rustdoc/import-remapped-paths.rs b/tests/rustdoc/import-remapped-paths.rs new file mode 100644 index 000000000000..c90ef4df1c0f --- /dev/null +++ b/tests/rustdoc/import-remapped-paths.rs @@ -0,0 +1,20 @@ +// This is a regression for `--remap-path-prefix` in an auxiliary dependency. +// +// We want to make sure that we can still have the "Source" links to the dependency +// even if it's paths are remapped. +// +// See also rust-lang/rust#150100 + +//@ aux-build:remapped-paths.rs +//@ build-aux-docs + +#![crate_name = "foo"] + +extern crate remapped_paths; + +//@ has foo/struct.MyStruct.html +// FIXME: Doesn't work! +//@ has - '//a[@href="../src/remapped_paths/remapped-paths.rs.html#3"]' 'Source' +//@ has - '//a[@href="../src/remapped_paths/remapped-paths.rs.html#8"]' 'Source' + +pub use remapped_paths::MyStruct; From 811c241b3d873880fe9bd4b9b36b37a3cdf3f70d Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 18 Dec 2025 23:37:51 +0100 Subject: [PATCH 1054/3801] Handle remapped paths correctly when generating "Source" links --- src/librustdoc/html/render/context.rs | 17 +++++++++++------ tests/rustdoc/import-remapped-paths.rs | 1 - 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index ee71564a1417..4d9e352595a1 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -14,7 +14,7 @@ use rustc_hir::def_id::{DefIdMap, LOCAL_CRATE}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::edition::Edition; -use rustc_span::{BytePos, FileName, Symbol}; +use rustc_span::{BytePos, FileName, RemapPathScopeComponents, Symbol}; use tracing::info; use super::print_item::{full_path, print_item, print_item_path}; @@ -365,7 +365,10 @@ impl<'tcx> Context<'tcx> { // We can safely ignore synthetic `SourceFile`s. let file = match span.filename(self.sess()) { - FileName::Real(ref path) => path.local_path()?.to_path_buf(), + FileName::Real(ref path) => path + .local_path() + .unwrap_or(path.path(RemapPathScopeComponents::MACRO)) + .to_path_buf(), _ => return None, }; let file = &file; @@ -499,10 +502,12 @@ impl<'tcx> Context<'tcx> { } = options; let src_root = match krate.src(tcx) { - FileName::Real(ref p) => match p.local_path().map(|p| p.parent()).flatten() { - Some(p) => p.to_path_buf(), - None => PathBuf::new(), - }, + FileName::Real(ref p) => { + match p.local_path().unwrap_or(p.path(RemapPathScopeComponents::MACRO)).parent() { + Some(p) => p.to_path_buf(), + None => PathBuf::new(), + } + } _ => PathBuf::new(), }; // If user passed in `--playground-url` arg, we fill in crate name here diff --git a/tests/rustdoc/import-remapped-paths.rs b/tests/rustdoc/import-remapped-paths.rs index c90ef4df1c0f..bce3d782b9c2 100644 --- a/tests/rustdoc/import-remapped-paths.rs +++ b/tests/rustdoc/import-remapped-paths.rs @@ -13,7 +13,6 @@ extern crate remapped_paths; //@ has foo/struct.MyStruct.html -// FIXME: Doesn't work! //@ has - '//a[@href="../src/remapped_paths/remapped-paths.rs.html#3"]' 'Source' //@ has - '//a[@href="../src/remapped_paths/remapped-paths.rs.html#8"]' 'Source' From 2581c2571c904c180ec8dc2b0242413a5b251358 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 19 Dec 2025 18:13:07 +0100 Subject: [PATCH 1055/3801] Don't lint on interior mutable `const` item coming from derefs --- .../rustc_lint/src/interior_mutable_consts.rs | 8 ++++ ...nst-item-interior-mutations-const-deref.rs | 2 - ...item-interior-mutations-const-deref.stderr | 37 ------------------- 3 files changed, 8 insertions(+), 39 deletions(-) delete mode 100644 tests/ui/lint/const-item-interior-mutations-const-deref.stderr diff --git a/compiler/rustc_lint/src/interior_mutable_consts.rs b/compiler/rustc_lint/src/interior_mutable_consts.rs index 8576698dec33..4c7d2c6af93b 100644 --- a/compiler/rustc_lint/src/interior_mutable_consts.rs +++ b/compiler/rustc_lint/src/interior_mutable_consts.rs @@ -1,6 +1,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Expr, ExprKind, ItemKind, Node, find_attr}; +use rustc_middle::ty::adjustment::Adjust; use rustc_session::{declare_lint, declare_lint_pass}; use crate::lints::{ConstItemInteriorMutationsDiag, ConstItemInteriorMutationsSuggestionStatic}; @@ -77,6 +78,13 @@ impl<'tcx> LateLintPass<'tcx> for InteriorMutableConsts { if let ExprKind::Path(qpath) = &receiver.kind && let Res::Def(DefKind::Const | DefKind::AssocConst, const_did) = typeck.qpath_res(qpath, receiver.hir_id) + // Don't consider derefs as those can do arbitrary things + // like using thread local (see rust-lang/rust#150157) + && !cx + .typeck_results() + .expr_adjustments(receiver) + .into_iter() + .any(|adj| matches!(adj.kind, Adjust::Deref(_))) // Let's do the attribute check after the other checks for perf reasons && find_attr!( cx.tcx.get_all_attrs(method_did), diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.rs b/tests/ui/lint/const-item-interior-mutations-const-deref.rs index ce684abacccd..021e0952da70 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-deref.rs +++ b/tests/ui/lint/const-item-interior-mutations-const-deref.rs @@ -24,7 +24,5 @@ const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; fn main() { let count = LOCAL_COUNT.get(); - //~^ WARN mutation of an interior mutable `const` LOCAL_COUNT.set(count); - //~^ WARN mutation of an interior mutable `const` } diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.stderr b/tests/ui/lint/const-item-interior-mutations-const-deref.stderr deleted file mode 100644 index 35696d0ba100..000000000000 --- a/tests/ui/lint/const-item-interior-mutations-const-deref.stderr +++ /dev/null @@ -1,37 +0,0 @@ -warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-deref.rs:26:17 - | -LL | let count = LOCAL_COUNT.get(); - | -----------^^^^^^ - | | - | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` - | - = note: each usage of a `const` item creates a new temporary - = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified - = help: for more details on interior mutability see - = note: `#[warn(const_item_interior_mutations)]` on by default -help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead - | -LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; -LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; - | - -warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const-deref.rs:28:5 - | -LL | LOCAL_COUNT.set(count); - | -----------^^^^^^^^^^^ - | | - | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` - | - = note: each usage of a `const` item creates a new temporary - = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified - = help: for more details on interior mutability see -help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead - | -LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; -LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; - | - -warning: 2 warnings emitted - From 90a33f69f4dce50ff60e5f8744f9174a31095edc Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Mon, 8 Dec 2025 10:08:32 +0000 Subject: [PATCH 1056/3801] replace version placeholder --- compiler/rustc_feature/src/accepted.rs | 6 ++--- compiler/rustc_feature/src/removed.rs | 2 +- compiler/rustc_feature/src/unstable.rs | 4 +-- .../alloc/src/collections/vec_deque/mod.rs | 4 +-- library/alloc/src/fmt.rs | 2 +- library/alloc/src/string.rs | 2 +- library/alloc/src/vec/mod.rs | 2 +- library/core/src/char/methods.rs | 4 +-- library/core/src/fmt/builders.rs | 8 +++--- library/core/src/fmt/mod.rs | 2 +- library/core/src/mem/maybe_uninit.rs | 16 ++++++------ library/core/src/num/int_macros.rs | 12 ++++----- library/core/src/num/uint_macros.rs | 8 +++--- library/core/src/ptr/const_ptr.rs | 4 +-- library/core/src/ptr/mut_ptr.rs | 4 +-- library/core/src/slice/mod.rs | 8 +++--- library/core/src/time.rs | 4 +-- library/std/src/lib.rs | 2 +- library/std_detect/src/detect/arch/mod.rs | 2 +- library/std_detect/src/detect/arch/s390x.rs | 26 +++++++++---------- 20 files changed, 61 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 7e765918d7b6..13c1f2219bed 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -61,7 +61,7 @@ declare_features! ( /// Allows explicit discriminants on non-unit enum variants. (accepted, arbitrary_enum_discriminant, "1.66.0", Some(60553)), /// Allows #[cfg(...)] on inline assembly templates and operands. - (accepted, asm_cfg, "CURRENT_RUSTC_VERSION", Some(140364)), + (accepted, asm_cfg, "1.93.0", Some(140364)), /// Allows using `const` operands in inline assembly. (accepted, asm_const, "1.82.0", Some(93332)), /// Allows using `label` operands in inline assembly. @@ -218,7 +218,7 @@ declare_features! ( /// Allows access to crate names passed via `--extern` through prelude. (accepted, extern_prelude, "1.30.0", Some(44660)), /// Allows using `system` as a calling convention with varargs. - (accepted, extern_system_varargs, "CURRENT_RUSTC_VERSION", Some(136946)), + (accepted, extern_system_varargs, "1.93.0", Some(136946)), /// Allows using F16C intrinsics from `core::arch::{x86, x86_64}`. (accepted, f16c_target_feature, "1.68.0", Some(44839)), /// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions. @@ -392,7 +392,7 @@ declare_features! ( /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414). (accepted, rvalue_static_promotion, "1.21.0", Some(38865)), /// Allows use of the `vector` and related s390x target features. - (accepted, s390x_target_feature_vector, "CURRENT_RUSTC_VERSION", Some(145649)), + (accepted, s390x_target_feature_vector, "1.93.0", Some(145649)), /// Allows `Self` in type definitions (RFC 2300). (accepted, self_in_typedefs, "1.32.0", Some(49303)), /// Allows `Self` struct constructor (RFC 2302). diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index cd61facb39bb..e5d66364c2a6 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -190,7 +190,7 @@ declare_features! ( /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8 (removed, negate_unsigned, "1.0.0", Some(29645), None), /// Allows diverging expressions to fall back to `!` rather than `()`. - (removed, never_type_fallback, "CURRENT_RUSTC_VERSION", Some(65992), Some("removed in favor of unconditional fallback"), 148871), + (removed, never_type_fallback, "1.93.0", Some(65992), Some("removed in favor of unconditional fallback"), 148871), /// Allows `#[no_coverage]` on functions. /// The feature was renamed to `coverage_attribute` and the attribute to `#[coverage(on|off)]` (removed, no_coverage, "1.74.0", Some(84605), Some("renamed to `coverage_attribute`"), 114656), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index f0a1f1416859..692cba8035c4 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -412,7 +412,7 @@ declare_features! ( (unstable, c_variadic, "1.34.0", Some(44930)), /// Allows defining c-variadic naked functions with any extern ABI that is allowed /// on c-variadic foreign functions. - (unstable, c_variadic_naked_functions, "CURRENT_RUSTC_VERSION", Some(148767)), + (unstable, c_variadic_naked_functions, "1.93.0", Some(148767)), /// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled. (unstable, cfg_contract_checks, "1.86.0", Some(128044)), /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. @@ -486,7 +486,7 @@ declare_features! ( /// Allows deriving the From trait on single-field structs. (unstable, derive_from, "1.91.0", Some(144889)), /// Allows giving non-const impls custom diagnostic messages if attempted to be used as const - (unstable, diagnostic_on_const, "CURRENT_RUSTC_VERSION", Some(143874)), + (unstable, diagnostic_on_const, "1.93.0", Some(143874)), /// Allows `#[doc(cfg(...))]`. (unstable, doc_cfg, "1.21.0", Some(43781)), /// Allows `#[doc(masked)]`. diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index ea9d5b128ebe..0e01d0d19e7a 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2053,7 +2053,7 @@ impl VecDeque { /// assert_eq!(deque, [1, 2, 3, 4]); /// assert_eq!(deque.pop_front_if(pred), None); /// ``` - #[stable(feature = "vec_deque_pop_if", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_deque_pop_if", since = "1.93.0")] pub fn pop_front_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option { let first = self.front_mut()?; if predicate(first) { self.pop_front() } else { None } @@ -2075,7 +2075,7 @@ impl VecDeque { /// assert_eq!(deque, [0, 1, 2, 3]); /// assert_eq!(deque.pop_back_if(pred), None); /// ``` - #[stable(feature = "vec_deque_pop_if", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_deque_pop_if", since = "1.93.0")] pub fn pop_back_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option { let last = self.back_mut()?; if predicate(last) { self.pop_back() } else { None } diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 4d6fe220a09a..3d7c580be8c9 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -602,7 +602,7 @@ pub use core::fmt::{DebugAsHex, FormattingOptions, Sign}; pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{Formatter, Result, Write}; -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] pub use core::fmt::{FromFn, from_fn}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{LowerExp, UpperExp}; diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 64abdca32d21..e400fc9e00ed 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -934,7 +934,7 @@ impl String { /// assert_eq!(rebuilt, "hello"); /// ``` #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "vec_into_raw_parts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_into_raw_parts", since = "1.93.0")] pub fn into_raw_parts(self) -> (*mut u8, usize, usize) { self.vec.into_raw_parts() } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index d2bc5d9bce39..f8a96e358d6d 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -834,7 +834,7 @@ impl Vec { /// assert_eq!(rebuilt, [4294967295, 0, 1]); /// ``` #[must_use = "losing the pointer will leak memory"] - #[stable(feature = "vec_into_raw_parts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_into_raw_parts", since = "1.93.0")] pub fn into_raw_parts(self) -> (*mut T, usize, usize) { let mut me = ManuallyDrop::new(self); (me.as_mut_ptr(), me.len(), me.capacity()) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index d1de2c560615..89cb06972392 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -74,12 +74,12 @@ impl char { /// The maximum number of bytes required to [encode](char::encode_utf8) a `char` to /// UTF-8 encoding. - #[stable(feature = "char_max_len_assoc", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "char_max_len_assoc", since = "1.93.0")] pub const MAX_LEN_UTF8: usize = 4; /// The maximum number of two-byte units required to [encode](char::encode_utf16) a `char` /// to UTF-16 encoding. - #[stable(feature = "char_max_len_assoc", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "char_max_len_assoc", since = "1.93.0")] pub const MAX_LEN_UTF16: usize = 2; /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index 4ea6c6ba8fb9..197cddd3fa9d 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -1226,7 +1226,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// assert_eq!(format!("{}", wrapped), "'a'"); /// assert_eq!(format!("{:?}", wrapped), "'a'"); /// ``` -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] #[must_use = "returns a type implementing Debug and Display, which do not have any effects unless they are used"] pub fn from_fn) -> fmt::Result>(f: F) -> FromFn { FromFn(f) @@ -1235,10 +1235,10 @@ pub fn from_fn) -> fmt::Result>(f: F) -> FromFn /// Implements [`fmt::Debug`] and [`fmt::Display`] via the provided closure. /// /// Created with [`from_fn`]. -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] pub struct FromFn(F); -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] impl fmt::Debug for FromFn where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, @@ -1248,7 +1248,7 @@ where } } -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] impl fmt::Display for FromFn where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 7a80023ce64e..e20109c3cc9a 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -41,7 +41,7 @@ pub use num_buffer::{NumBuffer, NumBufferTrait}; #[stable(feature = "debug_builders", since = "1.2.0")] pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; -#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "fmt_from_fn", since = "1.93.0")] pub use self::builders::{FromFn, from_fn}; /// The type returned by formatter methods. diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 1f066697fa48..e0001153a6e7 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -1139,8 +1139,8 @@ impl [MaybeUninit] { /// ``` /// /// [`write_clone_of_slice`]: slice::write_clone_of_slice - #[stable(feature = "maybe_uninit_write_slice", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "maybe_uninit_write_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_write_slice", since = "1.93.0")] + #[rustc_const_stable(feature = "maybe_uninit_write_slice", since = "1.93.0")] pub const fn write_copy_of_slice(&mut self, src: &[T]) -> &mut [T] where T: Copy, @@ -1200,7 +1200,7 @@ impl [MaybeUninit] { /// ``` /// /// [`write_copy_of_slice`]: slice::write_copy_of_slice - #[stable(feature = "maybe_uninit_write_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_write_slice", since = "1.93.0")] pub fn write_clone_of_slice(&mut self, src: &[T]) -> &mut [T] where T: Clone, @@ -1462,7 +1462,7 @@ impl [MaybeUninit] { /// requirement the compiler knows about it is that the data pointer must be /// non-null. Dropping such a `Vec` however will cause undefined /// behaviour. - #[stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_slice", since = "1.93.0")] #[inline(always)] #[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")] pub const unsafe fn assume_init_drop(&mut self) @@ -1484,8 +1484,8 @@ impl [MaybeUninit] { /// Calling this when the content is not yet fully initialized causes undefined /// behavior: it is up to the caller to guarantee that every `MaybeUninit` in /// the slice really is in an initialized state. - #[stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_slice", since = "1.93.0")] + #[rustc_const_stable(feature = "maybe_uninit_slice", since = "1.93.0")] #[inline(always)] pub const unsafe fn assume_init_ref(&self) -> &[T] { // SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that @@ -1503,8 +1503,8 @@ impl [MaybeUninit] { /// behavior: it is up to the caller to guarantee that every `MaybeUninit` in the /// slice really is in an initialized state. For instance, `.assume_init_mut()` cannot /// be used to initialize a `MaybeUninit` slice. - #[stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "maybe_uninit_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "maybe_uninit_slice", since = "1.93.0")] + #[rustc_const_stable(feature = "maybe_uninit_slice", since = "1.93.0")] #[inline(always)] pub const unsafe fn assume_init_mut(&mut self) -> &mut [T] { // SAFETY: similar to safety notes for `slice_get_ref`, but we have a diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index f5672f7106e5..f49f5f3c3afb 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1275,8 +1275,8 @@ macro_rules! int_impl { /// i.e. when [`checked_neg`] would return `None`. /// #[doc = concat!("[`checked_neg`]: ", stringify!($SelfT), "::checked_neg")] - #[stable(feature = "unchecked_neg", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_neg", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_neg", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_neg", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -1392,8 +1392,8 @@ macro_rules! int_impl { /// i.e. when [`checked_shl`] would return `None`. /// #[doc = concat!("[`checked_shl`]: ", stringify!($SelfT), "::checked_shl")] - #[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_shifts", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_shifts", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -1564,8 +1564,8 @@ macro_rules! int_impl { /// i.e. when [`checked_shr`] would return `None`. /// #[doc = concat!("[`checked_shr`]: ", stringify!($SelfT), "::checked_shr")] - #[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_shifts", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_shifts", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f129fc56a77c..bf901c9b4ad3 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1851,8 +1851,8 @@ macro_rules! uint_impl { /// i.e. when [`checked_shl`] would return `None`. /// #[doc = concat!("[`checked_shl`]: ", stringify!($SelfT), "::checked_shl")] - #[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_shifts", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_shifts", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -2020,8 +2020,8 @@ macro_rules! uint_impl { /// i.e. when [`checked_shr`] would return `None`. /// #[doc = concat!("[`checked_shr`]: ", stringify!($SelfT), "::checked_shr")] - #[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_shifts", since = "1.93.0")] + #[rustc_const_stable(feature = "unchecked_shifts", since = "1.93.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 2860bf0a6e69..00b71f9a997c 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1462,8 +1462,8 @@ impl *const [T] { /// Gets a raw pointer to the underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "core_slice_as_array", since = "1.93.0")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")] #[inline] #[must_use] pub const fn as_array(self) -> Option<*const [T; N]> { diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index f8dc6ef7ed71..8976154c61db 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1712,8 +1712,8 @@ impl *mut [T] { /// Gets a raw, mutable pointer to the underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "core_slice_as_array", since = "1.93.0")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")] #[inline] #[must_use] pub const fn as_mut_array(self) -> Option<*mut [T; N]> { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 256252f73e0b..889fd4cd65df 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -842,8 +842,8 @@ impl [T] { /// Gets a reference to the underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "core_slice_as_array", since = "1.93.0")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")] #[inline] #[must_use] pub const fn as_array(&self) -> Option<&[T; N]> { @@ -861,8 +861,8 @@ impl [T] { /// Gets a mutable reference to the slice's underlying array. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "core_slice_as_array", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "core_slice_as_array", since = "1.93.0")] + #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")] #[inline] #[must_use] pub const fn as_mut_array(&mut self) -> Option<&mut [T; N]> { diff --git a/library/core/src/time.rs b/library/core/src/time.rs index b85179e925d1..940129d68816 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -325,8 +325,8 @@ impl Duration { /// assert_eq!(10_u64.pow(15), duration.as_secs()); /// assert_eq!(321, duration.subsec_nanos()); /// ``` - #[stable(feature = "duration_from_nanos_u128", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "duration_from_nanos_u128", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "duration_from_nanos_u128", since = "1.93.0")] + #[rustc_const_stable(feature = "duration_from_nanos_u128", since = "1.93.0")] #[must_use] #[inline] #[track_caller] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 8fb1b1b05d20..508a6ed85261 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -667,7 +667,7 @@ pub mod arch { pub use std_detect::is_loongarch_feature_detected; #[unstable(feature = "is_riscv_feature_detected", issue = "111192")] pub use std_detect::is_riscv_feature_detected; - #[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "stdarch_s390x_feature_detection", since = "1.93.0")] pub use std_detect::is_s390x_feature_detected; #[stable(feature = "simd_x86", since = "1.27.0")] pub use std_detect::is_x86_feature_detected; diff --git a/library/std_detect/src/detect/arch/mod.rs b/library/std_detect/src/detect/arch/mod.rs index 23e7a30b985b..2be7f091c285 100644 --- a/library/std_detect/src/detect/arch/mod.rs +++ b/library/std_detect/src/detect/arch/mod.rs @@ -60,7 +60,7 @@ cfg_select! { pub use loongarch::*; } target_arch = "s390x" => { - #[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "stdarch_s390x_feature_detection", since = "1.93.0")] pub use s390x::*; } _ => { diff --git a/library/std_detect/src/detect/arch/s390x.rs b/library/std_detect/src/detect/arch/s390x.rs index 6122e8f5b837..a04283f90a02 100644 --- a/library/std_detect/src/detect/arch/s390x.rs +++ b/library/std_detect/src/detect/arch/s390x.rs @@ -9,7 +9,7 @@ features! { /// /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) /// the macro expands to `true`. - #[stable(feature = "stdarch_s390x_feature_detection", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "stdarch_s390x_feature_detection", since = "1.93.0")] @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] concurrent_functions: "concurrent-functions"; /// s390x concurrent-functions facility @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] deflate_conversion: "deflate-conversion"; @@ -32,30 +32,30 @@ features! { /// s390x message-security-assist-extension9 facility @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension12: "message-security-assist-extension12"; /// s390x message-security-assist-extension12 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; /// s390x miscellaneous-extensions-2 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] miscellaneous_extensions_3: "miscellaneous-extensions-3"; /// s390x miscellaneous-extensions-3 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] miscellaneous_extensions_4: "miscellaneous-extensions-4"; /// s390x miscellaneous-extensions-4 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] nnp_assist: "nnp-assist"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] nnp_assist: "nnp-assist"; /// s390x nnp-assist facility @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] transactional_execution: "transactional-execution"; /// s390x transactional-execution facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector: "vector"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector: "vector"; /// s390x vector facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_1: "vector-enhancements-1"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_enhancements_1: "vector-enhancements-1"; /// s390x vector-enhancements-1 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_2: "vector-enhancements-2"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_enhancements_2: "vector-enhancements-2"; /// s390x vector-enhancements-2 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_enhancements_3: "vector-enhancements-3"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_enhancements_3: "vector-enhancements-3"; /// s390x vector-enhancements-3 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal: "vector-packed-decimal"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_packed_decimal: "vector-packed-decimal"; /// s390x vector-packed-decimal facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_packed_decimal_enhancement: "vector-packed-decimal-enhancement"; /// s390x vector-packed-decimal-enhancement facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_packed_decimal_enhancement_2: "vector-packed-decimal-enhancement-2"; /// s390x vector-packed-decimal-enhancement-2 facility - @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "CURRENT_RUSTC_VERSION")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3"; + @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector_packed_decimal_enhancement_3: "vector-packed-decimal-enhancement-3"; /// s390x vector-packed-decimal-enhancement-3 facility } From 93fc20360622338bafa1d94184dfff7278e20e00 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 10 Dec 2025 05:41:49 +0000 Subject: [PATCH 1057/3801] bump stage0 --- src/stage0 | 1060 ++++++++++++++++++++++++++-------------------------- 1 file changed, 538 insertions(+), 522 deletions(-) diff --git a/src/stage0 b/src/stage0 index 0e4e9eb1c4b9..66b652a844f3 100644 --- a/src/stage0 +++ b/src/stage0 @@ -13,528 +13,544 @@ nightly_branch=main # All changes below this comment will be overridden the next time the # tool is executed. -compiler_channel_manifest_hash=d8adf7e1722d2dc8ebdb327ee661e58a58145464bfcd9bb3cab66d652cc7bb90 -compiler_git_commit_hash=3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f -compiler_date=2025-10-28 +compiler_channel_manifest_hash=936fefc9b8e88ef79db59e6dee693b757f35a98c87698b65206dca1118850996 +compiler_git_commit_hash=1b6e21e163baa0b20f119e17e3871910978a60b6 +compiler_date=2025-12-09 compiler_version=beta -rustfmt_channel_manifest_hash=108599f303463cabaef3b53ab5e0c0e560a6a5a97f606d75a802efb595141baf -rustfmt_git_commit_hash=adaa838976ff99a4f0661136322f64cb466b58a0 -rustfmt_date=2025-10-28 +rustfmt_channel_manifest_hash=8a4b2700918bd32bda5cbab3da25fc4ea1bee06bb24ef24d1df890997ef35a51 +rustfmt_git_commit_hash=c61a3a44d1a5bee35914cada6c788a05e0808f5b +rustfmt_date=2025-12-10 rustfmt_version=nightly -dist/2025-10-28/rustc-beta-aarch64-apple-darwin.tar.gz=5d971d3a1c127d314f94f41440f0717b51692176630fef7f05a70d9bcd3bae44 -dist/2025-10-28/rustc-beta-aarch64-apple-darwin.tar.xz=2cedfc3a96acc9ebe82c5cf5bcf5355902a5726e1c28e7d50b15cfa2ee343174 -dist/2025-10-28/rustc-beta-aarch64-pc-windows-gnullvm.tar.gz=1875833b43088879444902023cc76682fa58f39520a1135e438afaacf3605f88 -dist/2025-10-28/rustc-beta-aarch64-pc-windows-gnullvm.tar.xz=a925fb02b296b8ce753ff7b1fae583a27fb2ef6de582a80f1428678a2f61a466 -dist/2025-10-28/rustc-beta-aarch64-pc-windows-msvc.tar.gz=28f423bb7db80232b887bd0d47243341a50611eca913c17c305dd55fa6bd3f12 -dist/2025-10-28/rustc-beta-aarch64-pc-windows-msvc.tar.xz=3be7d39a956afd591ba4b22785b4851fd6c0c7afd23d045c54d6b603cc14bc2d -dist/2025-10-28/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=8b98b7e04ef03c3b2bc95e0d6e3a92ad7849bad8d5a8969d6c9eefe169673066 -dist/2025-10-28/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=1b35688d58c10fdd1f1d02325022ae9eb36ee139f76ae753e16a0f4524d0f6d4 -dist/2025-10-28/rustc-beta-aarch64-unknown-linux-musl.tar.gz=c1de08dbaff419f08f82aef49972965d87e02054822e83e6e7f73714afbc4155 -dist/2025-10-28/rustc-beta-aarch64-unknown-linux-musl.tar.xz=2755a71cee31227e4638499dc882347ed9ecf0698cc64a177ff8a94c6ff3be8c -dist/2025-10-28/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=dac50bed8e2bb5d65b5f6ea52963d2b268829c9f79800304a225e058152be0bd -dist/2025-10-28/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=f818783e566cebc2ac392f923efd0ae8f51ae77ce6ade284514a57c21d288b7e -dist/2025-10-28/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=922d9d3aba6c5ac4da95ab9310d0f33ec7da4830a7d424b83d6f0181af96bccb -dist/2025-10-28/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=746a200dab88eec922dc08ea244ae818c27a0ca91360278e578ab9fc433bd3be -dist/2025-10-28/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=ac45fe7547dc1064286de6704a9343e95fa760163247ac02ff88ebf2bf4d7d8c -dist/2025-10-28/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=35ab727f335242d588742f79f29fb94590ac0c3bef29d012538f2e925cb9f96f -dist/2025-10-28/rustc-beta-i686-pc-windows-gnu.tar.gz=42eab38b498e0b8efd7fae51facd7caaf253e1bc341f915f978b484065e4c812 -dist/2025-10-28/rustc-beta-i686-pc-windows-gnu.tar.xz=d663982b6293285fa1ffcc5987ded64569216c0133476243b5525768cd6123bb -dist/2025-10-28/rustc-beta-i686-pc-windows-msvc.tar.gz=571eeccc9c1f25c4b9c2c6f45d15dbd9730bf6c0ac0f75a5b49652b6d4e98f68 -dist/2025-10-28/rustc-beta-i686-pc-windows-msvc.tar.xz=595a8b6b74910fa53a947ddde81f5519152f8c773a41a2f5b0d663540bc913fa -dist/2025-10-28/rustc-beta-i686-unknown-linux-gnu.tar.gz=3f2261279e5c16b0a4b572e799e2d3079aa33192e7713803214011e14c5c6707 -dist/2025-10-28/rustc-beta-i686-unknown-linux-gnu.tar.xz=c49c0e84b4b43aa6b72dc355173b4b5dc41563f3f76e882c405a8625c00befbc -dist/2025-10-28/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=92cea4e2708fbd86b35bc798b25a69ab10b62f28e972ff0624709e6e8268db60 -dist/2025-10-28/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=224f6e9896d19e00e369da70bc0e0dbd545d04033ff6ecff12b3f2d2bfe73fc8 -dist/2025-10-28/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=74901d397d5f6695df197520d16851986df2a5c5d432b8f24da1a5c3a5c0474b -dist/2025-10-28/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=02d8962da7234bfd365147b4177497a99c8f1f12f6841160abede61332edd35f -dist/2025-10-28/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=b8d810c76102a325cdecb98e7d7fab480a8d349328ce8a275366018a627fa4bf -dist/2025-10-28/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=f09c4e8d4a4ae4cf490e55bcd29ab00b6f7c1aed09c93b63f10fc3f812f415e7 -dist/2025-10-28/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=6c71850444d597cdc07a7169bd5d2564cbd99d1a34ec806ac8b818b39c9fd529 -dist/2025-10-28/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=01f3537787f41c2fd2ed1f955520ff0852bb27d899141cf44de3ae126abf8808 -dist/2025-10-28/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=833dcfab6dc87d375154d593c8e53cd5c74b3029f8b94c753928de718185283c -dist/2025-10-28/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=cf99a56b49b3db107d33f5c6e668310317aaeb2b2ca3c80a0ea2b30a09b453dd -dist/2025-10-28/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=55b1db794a4bb0f535e46a2c4a85eb7ea0016482b7086b6deae033746a42a69d -dist/2025-10-28/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=a741b18a92f5fa35cab2ed93d90782175b70e3ef5a127e21fde7acabb6228b59 -dist/2025-10-28/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=97335caa2ace3f33cd959dc35f01ec8a3d2de5699518b93fd191766eda3fe318 -dist/2025-10-28/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=2127853b7b4e2b3cf906ef292e9c7e370ec3f3760ce5576b447ed7902048794f -dist/2025-10-28/rustc-beta-s390x-unknown-linux-gnu.tar.gz=eb3df84c1a840cc69799ef0649972e5312afe59144700ba3652bd6083f48074a -dist/2025-10-28/rustc-beta-s390x-unknown-linux-gnu.tar.xz=16942680ea11ead1ab4d9d46d31389a14f237637a6877b278cd30a608446b787 -dist/2025-10-28/rustc-beta-sparcv9-sun-solaris.tar.gz=5c7848ab2b2cb181bd7f64cdbdc3b5b659b61850c14604a7977c35b9807daa48 -dist/2025-10-28/rustc-beta-sparcv9-sun-solaris.tar.xz=0f12cb118e253206ea74e7b1dabdda6e95bb0b10d47657aa4c560fa9ca28cf83 -dist/2025-10-28/rustc-beta-x86_64-apple-darwin.tar.gz=3c34e03deee0445864c7f5ebc89883db051a3c69b874a2daff658fb5dd364aba -dist/2025-10-28/rustc-beta-x86_64-apple-darwin.tar.xz=292d40e5ea57295ecd921a07fa11796771953d38793edcea9841a95e79d94ac2 -dist/2025-10-28/rustc-beta-x86_64-pc-solaris.tar.gz=6ac79775ff166ba76e663e8760ddf9625e06a28e5033d4d8cc570dcca73ca725 -dist/2025-10-28/rustc-beta-x86_64-pc-solaris.tar.xz=46c214af2c11ccb17529a991201624bad044d59c171c6f872468acb8523b6f96 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-gnu.tar.gz=29067fc4a5e0f123c34a045a1b0d55f88170bc9f658584d50e32219cd5945854 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-gnu.tar.xz=30c20794d0c244bd04dbd4de304ef3aea5ba11e26882f2a004680281f21e05b0 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-gnullvm.tar.gz=6c6c7614b538d9bad498b3642321adf0b2b6cdd3b24706903a8eb2125c0c122a -dist/2025-10-28/rustc-beta-x86_64-pc-windows-gnullvm.tar.xz=09822c7d5bbf218d5113e902968b37719949997fd788523bf80400274f428986 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-msvc.tar.gz=fcf05b8150cf7199e100f560854f6acb6874985a5cfbb00ead36914dc3fb66e9 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-msvc.tar.xz=f5259f5b521ea10f093c522abd5bcec4e9dfb94ce3e384e3b53865a223e700d0 -dist/2025-10-28/rustc-beta-x86_64-unknown-freebsd.tar.gz=c3719366a9687d243483431231b86140e268bf2ce99e1ea1759a611524ea8ade -dist/2025-10-28/rustc-beta-x86_64-unknown-freebsd.tar.xz=015e02fb99098c31d502738e9e525d48ac6ca386e16f3ecb55235c7268d4abe7 -dist/2025-10-28/rustc-beta-x86_64-unknown-illumos.tar.gz=508acec5f2b092d09d55590e7fe921f7415aacc13c535532997776c4ebb86483 -dist/2025-10-28/rustc-beta-x86_64-unknown-illumos.tar.xz=f7437c9b0e747b0eccd7755a3ef551fa81194f23304ddb40ae44bca5782dda4b -dist/2025-10-28/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=cd985cf21af999dbb76e25cb6c9b5ac5723e8cda8625cf511e7df2c98e7e735a -dist/2025-10-28/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=d30acafe9f3ddfd25148abdd3078deaaafb6bb62f7979252e9e7880abc260b23 -dist/2025-10-28/rustc-beta-x86_64-unknown-linux-musl.tar.gz=1778c649d790e52b8462d5ea377339443e607b2434fa9b579236b465f63748c7 -dist/2025-10-28/rustc-beta-x86_64-unknown-linux-musl.tar.xz=909808e6e3a10cd3fc2c0927f47dbe4ac8de4653b4e771c9c44b8e58cbe5fe2d -dist/2025-10-28/rustc-beta-x86_64-unknown-netbsd.tar.gz=8584d5ad71c7cedcf6e64b0f83ed2cfa82346e88a1000acac677f464dbb0e6f6 -dist/2025-10-28/rustc-beta-x86_64-unknown-netbsd.tar.xz=7b85928ce5f6908ad82895097ba07fad70990b7810aa23c63725d7ecbbf54d54 -dist/2025-10-28/rust-std-beta-aarch64-apple-darwin.tar.gz=312c1121edf001f03ea169e8fff9668efd1925a45962b282b32d5f126bd6b010 -dist/2025-10-28/rust-std-beta-aarch64-apple-darwin.tar.xz=11e0fd642939358a892e66ebeea7f1737a009ad23692da486c7427cdce60c37d -dist/2025-10-28/rust-std-beta-aarch64-apple-ios.tar.gz=d7086698f3414ebf1410f79f8167ef2e4cf8e9143dc7e3704200d67e64252080 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios.tar.xz=a71fd039b0bfa2fa7a1abd13c622c89371f7af273fc44b3c210b1ead6a1f9156 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=52795cad4c58b32c3f36fb7b596c25a8e3277c85c165e161445d1fc81e0c4200 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=7db4e584f7890bd05d7cf8a991f539be249e0f04526e30743575129dada977c2 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios-sim.tar.gz=575b6d5185a71a4f4d29dc881f5dea5fe492d7b21a01c0bd9987cc212bb8ca25 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios-sim.tar.xz=ea1c7896e21d0a89da399405611a25ec447ff71495a4b5d48501c9f8129b2a20 -dist/2025-10-28/rust-std-beta-aarch64-linux-android.tar.gz=f7a85a478dd9d55491a2395dda9539ab7898385782ef5be479362ba35e8be837 -dist/2025-10-28/rust-std-beta-aarch64-linux-android.tar.xz=4fc53a2be557540332410446f6f43f5e6339d10d8010c153d99d707df64a5ef1 -dist/2025-10-28/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=99b3f95696883f18e3734d02c75a5dc91edac003b6d9627c5a32baac41f3c69c -dist/2025-10-28/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=375db4717baaac6a784d8f53f84035f99d5f76f9a3f7df7dd385ee2d93027368 -dist/2025-10-28/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=b650ca7708ae5b05fc82c7aa483f9aaa42be83d6bcc6c524690da745f32f6f60 -dist/2025-10-28/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=1683d5a33387dd546ff641222b501e90049241df0f52c2f1a5dc568b35594135 -dist/2025-10-28/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=3e2d64dd8d2fdedb30b25f899f8ed8deff653c4d3f3f7e16e534ab7e1eec8a66 -dist/2025-10-28/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=e83d63666e0372f27d404a4ddf48de7abc5b646d9f087ebf8856bcbfe6f86362 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=8a99f5fbaf869f68bced6435acf18127ac8880193fb23e44cb5791546bc795d7 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=53be5ecbcb4d47e6a1fb811a6e8b4ecec7fd6ae2b6efac7d9934dee4cfb19dce -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=f61af59bc40a53dddf0a85b5205bec90d287a41ee3ac32345a97d21861ae6546 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=9ed2894300f6ac917ac33d0724133ba2fada2ab2e42a0b21a9bd994d70c942f4 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=70ad473c7d4934bab123afb8cff98773993fdbb73b4941f6022a25ef2942a223 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=d0a06230a38c725ceed103c89e8031b541b7bc15a3646a1a3662d8147901b2fd -dist/2025-10-28/rust-std-beta-aarch64-unknown-none.tar.gz=90d4484a1e390e0d3edf25331d41f9b419730bd2e318e8927c4a891b2c035652 -dist/2025-10-28/rust-std-beta-aarch64-unknown-none.tar.xz=5b795b7378b6753fb2a8ea0ecef760009ffa05c9a4778815d2d2b4085baffe14 -dist/2025-10-28/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=52d0e13f1dc2083787d3294d5c3569b11227724ab4ced4ba9905ac0a5f25bde0 -dist/2025-10-28/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=981dca064b73d6617039bb35a32a17111445bc1ed9ba957525d227d3be9e8f6d -dist/2025-10-28/rust-std-beta-aarch64-unknown-uefi.tar.gz=fbb7066da0824513e4441bb59d4c6a6d4c8bc34f67ed79f67da3b8ec69ff3a4c -dist/2025-10-28/rust-std-beta-aarch64-unknown-uefi.tar.xz=c0bb51d8c513c0b5d597cbc00260bf2764595b12244906606c20ae6f98e0fc66 -dist/2025-10-28/rust-std-beta-arm-linux-androideabi.tar.gz=7cd5763f202c5679dc1bdc0e6551dc8093ee95a9b2d405ad8cbd31fcf232332c -dist/2025-10-28/rust-std-beta-arm-linux-androideabi.tar.xz=126b3a04432a3f6f5f1aef6f5e22deec98629da4a0809b0c7739911ae5e4b6cc -dist/2025-10-28/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=01bc31ad9812edeb11dc4b6c15d4bf80a325e286390829babd85176b91c38cfa -dist/2025-10-28/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=0b1c799856c8314afddfaa5109535535c36df31bb9188a319c1e45f4968a7079 -dist/2025-10-28/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=8792d0115ba1d9b0e3bfefbd7a9ddf7859f7bbf8431ef32530b05ec7cf9c68b8 -dist/2025-10-28/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=fc470db282fb0fab537e4b93a9498d4b4fc65cf014536905654cc2c14f82d245 -dist/2025-10-28/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=fe82493d2a7f4a9566916beefcd7fb26301bd13b8b838b5251398ecac0c867ef -dist/2025-10-28/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=b7cd0514db083e115d8aacceb3f7998da11f26e9f2be44137e8af2e2f9ac786e -dist/2025-10-28/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=0adc4e2e0f5bee4c28c81ba2cfd9796268e830d23b23b80c71121c30f08e3326 -dist/2025-10-28/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=8c98799e7b4c454cad130d0eb87e8ed59e0e7e64bb0513af8beb6d1d5f8e3ac7 -dist/2025-10-28/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=bb1da273578b508b9f397074438ecb2527a729e404d2820bd34d67dc8824106a -dist/2025-10-28/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=e004d91a9732284851d613a3c488909bc7d457b2053a1af45710aa4bbe3169e9 -dist/2025-10-28/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=7e6b5d4266306001366003cdc4fd4b60d700e86ec5dce01b58b0e73bd6a50c42 -dist/2025-10-28/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=170b32ea83d21436e744d11a56ea8e298278f8b9aa58fd82d6d788ff1e3258f3 -dist/2025-10-28/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=8ee71b71a8e90b21d580f9e64cc115f182db8582cd6238f946e24fc32de27e65 -dist/2025-10-28/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=9319475d974dce729182c3d99696bd5cf6a36257b1b80186f261d2885610ddb9 -dist/2025-10-28/rust-std-beta-armv7-linux-androideabi.tar.gz=71db2b02df33e229899f0dafc675572f2b4041400954f9145796edee7cd923d4 -dist/2025-10-28/rust-std-beta-armv7-linux-androideabi.tar.xz=0f331806b4523d61204f38f2d7ddd07e6f3dcda8a15806a9f01cb1747a587e8f -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=52f331579373b749fb1c7a6302a770a4be33008cdd9db4a5640208ba1ba7b540 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=1e8c5dcc4cb672c4e8ba2862549cd281ea6802fb73701c885eaf5423673ab233 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=2d0dded898f567cbfa5605dcc09b1e44970e345a030ef91c806eafcac4470258 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=3a63913c874f30c8a68d5cbb62dc654ec9c3bf2f4488e1098034f60c51824bb7 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=24c341427a9b5a4d883e7f322a9c7760446896e8c2eeb1f8654b80cef00db6ea -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=53c5607351479ad76c3450bcc81353633f2587aafda473487bb11e42f80d8523 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=beda2ede28453b81588d639c18b36fa6e935e586723159e39ab9b714291c680a -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=f175a55fc81159e9a40407b1d97ea658239014cf0f5191a3533318e53ee1ff7f -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=db1f0cfd65d795d23a60d29e44f24e6174a0a516b998e65bd1964230c9c6c03c -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=264efedfd340c095dfe08fc95a35c36392eda0d1c2c179e56c75b27685b90d7e -dist/2025-10-28/rust-std-beta-armv7a-none-eabi.tar.gz=578fe97f24afa73c155290bf7386594e8b18a4652f54477d7a4e3f6f3ada0b5a -dist/2025-10-28/rust-std-beta-armv7a-none-eabi.tar.xz=a373109143f701d266ba53b3fff32206d88f5dfabdd888ac988606fade0b4928 -dist/2025-10-28/rust-std-beta-armv7a-none-eabihf.tar.gz=b3d6ec33c14a034c621aaf7de6ec81f0a916e18f5acc933713cc479fc21af755 -dist/2025-10-28/rust-std-beta-armv7a-none-eabihf.tar.xz=6550b2a97ce84884aa0da9133b81703e08b6e57b65c2e93f310fad2559ea4a08 -dist/2025-10-28/rust-std-beta-armv7r-none-eabi.tar.gz=b50984f65ee8a9e8c1b62158d8e91cb976f7c36f6ebc3c70ccfcab2a3da26533 -dist/2025-10-28/rust-std-beta-armv7r-none-eabi.tar.xz=0227fe58cacca86a04d85860a1de852a29ab9ac1bfea7bc50c2f560b73951d8b -dist/2025-10-28/rust-std-beta-armv7r-none-eabihf.tar.gz=da5e26a7cb5b91d3b8ec4f1a02c81b0f538dbb416e10e9453f3fd9d5cfc08129 -dist/2025-10-28/rust-std-beta-armv7r-none-eabihf.tar.xz=9132e8a69bf5dbd144def8bc647c659304fa785612a0f68f2e1a2df5dc195e33 -dist/2025-10-28/rust-std-beta-armv8r-none-eabihf.tar.gz=a312253ad16ccffacd0d840cba85d290fb5d2580865de99887990eff96f58b45 -dist/2025-10-28/rust-std-beta-armv8r-none-eabihf.tar.xz=474813a75bd586e562cf76705bdabf37a915cda6edb45afe029cbcbe54be3cb5 -dist/2025-10-28/rust-std-beta-i586-unknown-linux-gnu.tar.gz=4be0898bb9da3e8d75cb9b4851d5119efdd3136eb10cf31a42109f188781b6ea -dist/2025-10-28/rust-std-beta-i586-unknown-linux-gnu.tar.xz=5a51fb1f2da0dd645c1eb6ce19f37f16f356042ba176ab109f8bcd4ad3514ad3 -dist/2025-10-28/rust-std-beta-i586-unknown-linux-musl.tar.gz=96f621043d426d00f6baec72f66db5d91940215ba3e6985bb823c7b02acbd7ff -dist/2025-10-28/rust-std-beta-i586-unknown-linux-musl.tar.xz=2e62b9a670e3ca1d892ab18da1cd4b2bd946395e35c3b7829dd4b03726a73e4c -dist/2025-10-28/rust-std-beta-i686-linux-android.tar.gz=6c3b0e8796cb87e1a0369b55a91e49d5129af929deb4b63a623cf68219679543 -dist/2025-10-28/rust-std-beta-i686-linux-android.tar.xz=682747e9ab2706e90b5071ce13e8bff21160987d42ed0565f8e0012acded5f40 -dist/2025-10-28/rust-std-beta-i686-pc-windows-gnu.tar.gz=e7afe1e6ccb84fcf03114a6a3fd7232b40d7b2005f31a00a02d9c8e092af8b5d -dist/2025-10-28/rust-std-beta-i686-pc-windows-gnu.tar.xz=99d64d295d7bc0befe84a1da5d888de3ee0daa67a027c8628f78c36ab53eb7b4 -dist/2025-10-28/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=1b36e3979b73348b46a01961a2515bc6ae19a54924e63272cb1bca709a07bcf0 -dist/2025-10-28/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=f579f144f9f653df8be318e4f5ba363116a538b840030d3cd5305f87e03b9e23 -dist/2025-10-28/rust-std-beta-i686-pc-windows-msvc.tar.gz=79de79f2ed569a93dcd57aba35c7995582dde8b633bafbf0fc43ab6a8fb9d152 -dist/2025-10-28/rust-std-beta-i686-pc-windows-msvc.tar.xz=8c3fdbeb815085aaa9d484f1b22d0adbcc829a88511df5930bb518b139d20801 -dist/2025-10-28/rust-std-beta-i686-unknown-freebsd.tar.gz=d25fbb684148778444743e9d651a6d36dc4527d42367bfa67eebc43200e6cc0f -dist/2025-10-28/rust-std-beta-i686-unknown-freebsd.tar.xz=32c6d84e419a72cb862294a110fc79a88b123c4180a3a64bd53c38b200c60f9a -dist/2025-10-28/rust-std-beta-i686-unknown-linux-gnu.tar.gz=577cec0f5fb83cd22a9256dcf7c74529d95572976f102a8a63eb1cb9550f0a6c -dist/2025-10-28/rust-std-beta-i686-unknown-linux-gnu.tar.xz=dc537d7c09efaeb054d2954689842c813b5e9d646fcad912005f4b10e137181d -dist/2025-10-28/rust-std-beta-i686-unknown-linux-musl.tar.gz=5713f1784a424f509f47f70e0bce2bf8ae82e1a16efab8cd771677988b37516b -dist/2025-10-28/rust-std-beta-i686-unknown-linux-musl.tar.xz=1a3dc46f4cb4e4c8e4f96e9835b1188242addcb7a5a8ebbe3ef614c3aef862c4 -dist/2025-10-28/rust-std-beta-i686-unknown-uefi.tar.gz=4c32dcb28c1fbaeb910c9c7c60ea7dfe50e6556663eb3f002b66ec3ed42bd7ed -dist/2025-10-28/rust-std-beta-i686-unknown-uefi.tar.xz=1683c1c2838a2693b2f08a9daf0626675623d6bccbc4c996fcda8489eac853a1 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=401945e68f2246d1f502d4ac63666d5443ca7fa2f81ce38e76fbb0647fed4643 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=9b8d7d2f8a4ebf1369718d8bd3ae6973c977cdcb7030ccea0542f9e28970c281 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=ae351e8f921f0c3b8bcccafa0c84402e15ced7591debf82287e63bac0965801b -dist/2025-10-28/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=7d64ee15508ebb610abe61e1aa03607140302fdbe41200e82070be85312d4a07 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-none.tar.gz=9f951f51a32a4f037f3548935a07208e14f3e67d29100954ae6fbf61a8e56c06 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-none.tar.xz=80494d9d9e02d7a6f56a638d93253d087a4edb83d4662b4771bd1d5c2cba97b3 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=f23fd6331ba600a3a4350565ad11f51129ad13a248f35c37b9d485fab725b4ac -dist/2025-10-28/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=03d765256191ab9fac9f37102fa4252f7efb05261c8d2464745826232351dcd7 -dist/2025-10-28/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=509bcbeb245d69fcb828bf9f3fa4413d1d4d59a0e85ed28c4f412929c734aacf -dist/2025-10-28/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=543aa41bd2ae544c0114cca0e5a50c15eb7ed78d3d132bf5b48f93f2f92b502d -dist/2025-10-28/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=d67670d0b9385f4433635a473548031d083fe14e1a407766fb1ae5c4762da93e -dist/2025-10-28/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=e2f403936d191b38347bbad4e9b9bd66270b23e9df238ba9b5d52f81aaebfdb8 -dist/2025-10-28/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=15ef51a8fc10b2298db444d68130ef350414722133097d670b8106e8de68609b -dist/2025-10-28/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=515151364a93fc458ab5f11831797d2d708b22d9a71c78f717cf89e4e593417a -dist/2025-10-28/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=8ea0204c3ac93828c5a72f671c12167d0b5120cde99bb797c8d839caeb3ba3d8 -dist/2025-10-28/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=138969d2a43b6c4d736a950f8ba5bc0ed5fc7868c7044623d389d8278727e759 -dist/2025-10-28/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=a3423e7917b59232faaf855ad9b9cd3b23e5d2188aeb8636e2cef324d405beb4 -dist/2025-10-28/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=36914d3ce6a2e5a56a2a394d2c5a461a7c8a40fc235b3552a658ab1ed7d786f6 -dist/2025-10-28/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=dbc0b69f7eba79726bc08a0a6b357f9d818623d3cbe153dff5f2fcb31aeea61b -dist/2025-10-28/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=39def1e42a80080159347b5e85bc666830a3a346c9b0e83eea8207e94659ed94 -dist/2025-10-28/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=7aebf847c08b0eee42c77da8defc6b30439f4b6d29e4122802f02d029518a31e -dist/2025-10-28/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=35c49b2df4b3e18e0ec8ac20ec8b9a4a81b69f026921d85a666e0a97a671045b -dist/2025-10-28/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=b10e9e0a0457db1441a9bfeb3c4b9a8b2af4d33518bc58a8ee1d3fa7546c0bb5 -dist/2025-10-28/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=8e210b59b95b3c8db109d978ea73a540478315fb49d4515ccf248aafa7517617 -dist/2025-10-28/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=e2bfdac9e858f144db5e9ae79b494f1e09b2a012b18f0eaac96ce684a6a43e25 -dist/2025-10-28/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=6d2f5e60af9f6824fe2078a58a6cb804e61116e4848e1502289e08b0b9a5196c -dist/2025-10-28/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=382f448ea95627ee9fbb3d42c32ab9ecffe21ea12c00810e4eb8e94553d463a9 -dist/2025-10-28/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=ad7f534565c1b97495bf29054c202d8fada0a0ddfa0cca110c14a8221c654cb9 -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=7c8cf6afaa4edb589259dcc61ec5e1e667a5deeace8e277f752a433f20bcbf8d -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=8a396e9db63f1352bfde7a0d51446dabe6873c9a0a46e3c74f59ee775092e2af -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=551d398055ee522ec4a67a9173daca7a1f0f537ab006383ed2ada6b00cc81cbc -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=cf08dcb74f961bff041ad52efcae0c8e239e6439ecdcb32f869eb57b1a3aea1d -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=fd4e49a23ea0d512ed32bbaaefc1e5ea32c837e9a371513b94643966afabc521 -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=10700fa42e00a3b58ddcd664c0179016b837b43a31476fe4c56e8124619e4a22 -dist/2025-10-28/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=ea2f2873255dcc73185490b2c396abb4bcd5f1623f7749f77885426f753ce29f -dist/2025-10-28/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=7c02315d003cf65ac1246e3ac21b6da39cb1d99e61078ba9941647ae48bf9aa5 -dist/2025-10-28/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=008321f0ccd9b96e77829b709c2683c0053acbb19ae86f2fccef49c2cb964531 -dist/2025-10-28/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=047db35903bec7fee6c1d9deee5b4dc21db546a06e11c30d8372ffaf09814c59 -dist/2025-10-28/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=19677dc6495a139eac6c5827cb765e54e3b099d64f83e92273190f09ead7dab7 -dist/2025-10-28/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=d5815d1eb4906a442da0a0b56fe61cf94767dda29479da447d94a23803f9cf0e -dist/2025-10-28/rust-std-beta-sparcv9-sun-solaris.tar.gz=184424d0d18c2c49ce1c819e49804d7667edf2bce34fafedd4eeb6d4f427ae5e -dist/2025-10-28/rust-std-beta-sparcv9-sun-solaris.tar.xz=30ad3f9e3eaf48af0eb700d528b330118ad39f221a7beaab1a42e52b1ffa8531 -dist/2025-10-28/rust-std-beta-thumbv6m-none-eabi.tar.gz=c9a72ea7a13651f1b9bc6e509d9d6d32e56a4659d541e20f571ef9f6dd858480 -dist/2025-10-28/rust-std-beta-thumbv6m-none-eabi.tar.xz=6dd3a25ee5060cdf4631d8b0b7f16aa569bf611ef392d93826e88846053779e5 -dist/2025-10-28/rust-std-beta-thumbv7em-none-eabi.tar.gz=ccf8d09ba0bed60fecc775689649f2de31bab68cff273d796378d213c9d1e44a -dist/2025-10-28/rust-std-beta-thumbv7em-none-eabi.tar.xz=b7a972a9b972a2e0665387cd825491bf0ee9581ff26a586806c986014f0ae742 -dist/2025-10-28/rust-std-beta-thumbv7em-none-eabihf.tar.gz=26baa00580268fb5b7aba63a069c187dcca43dcf29161a0c1b849ef3765bbbda -dist/2025-10-28/rust-std-beta-thumbv7em-none-eabihf.tar.xz=dcd67a3ad1f2c553fb90009c630a8edcd8f571e28e5fcef0ade63c624fa11037 -dist/2025-10-28/rust-std-beta-thumbv7m-none-eabi.tar.gz=cef72caa89fcd3d48c070b1aae2fe85f29547c9b615446af2d51767ef42b5045 -dist/2025-10-28/rust-std-beta-thumbv7m-none-eabi.tar.xz=70ad20d0016c6c81b4526ccf89bbd96f4bc0a97b904b2c06487fd0a0368d7a17 -dist/2025-10-28/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=f22aeb9cdd40a4a465525fca7e6520aaa74b5fbfb41f45777e1376742f711c59 -dist/2025-10-28/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=48410a5a2f05c80f3d76b9f0b3e0eb89521495b273a854b40386048f27b553c2 -dist/2025-10-28/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=a791f5442467819c154f943c3126de1dd8f5fdd6b62527aadd88260ecb8c380b -dist/2025-10-28/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=cf43ec766a353cad48150d47d108d8df4b1561101b2c95241b909d4a5ec47bce -dist/2025-10-28/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=3699e5b727abc016ab9fa78f40655ef7d88ff157e46759297cd80e5c169136f8 -dist/2025-10-28/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=a6942c04a569f68cf1c5126e520400c51dfccd9e18a1d3941e28d7a8e63ae648 -dist/2025-10-28/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=eb27f46d3ee51e4f71316a75087d4ca2493f55ed5e0b720f0dfa3564c8f19a67 -dist/2025-10-28/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=f50b7fa2830844fd27041ced4c96eaa68ae6595b370eef1c958e3542c718d5aa -dist/2025-10-28/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=398556eca8a50c1d905ef7e2bf3f25d75f8dcf1d9b679af87b565f5f58af5c2b -dist/2025-10-28/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=8dc4a5036cfda5725120a8d7e7d0cd05151230ed967ff77fa028c4b73dde6885 -dist/2025-10-28/rust-std-beta-wasm32-unknown-emscripten.tar.gz=212f761263b9a4c72a53aba0b76986f70b3d624557f34d36af2e7d935702359d -dist/2025-10-28/rust-std-beta-wasm32-unknown-emscripten.tar.xz=89c0dae14955afab89b8fa2892944325ff154987c863fd36f93089f29ef993b6 -dist/2025-10-28/rust-std-beta-wasm32-unknown-unknown.tar.gz=92159d52588bb1ca6346025f894dce5520b42d89cb54a78a3ff42ee119c1e90b -dist/2025-10-28/rust-std-beta-wasm32-unknown-unknown.tar.xz=a187e36833f587ad5f117b012a5d9ddacb3122b39b902bc2a9d9d03b5aba27a2 -dist/2025-10-28/rust-std-beta-wasm32-wasip1.tar.gz=fa8971fcd7c22f5d382f4239fa8742238ec967f70fa40180ac9d8a39bffc28b3 -dist/2025-10-28/rust-std-beta-wasm32-wasip1.tar.xz=0603acb7e6fa5540fb458cf363fe473889b0abba91ec0c124ce380ffb1869cbf -dist/2025-10-28/rust-std-beta-wasm32-wasip1-threads.tar.gz=7651d409d4a89dab576cabf51cdd2947f877b77f09f668c6f9b8826dccd5c322 -dist/2025-10-28/rust-std-beta-wasm32-wasip1-threads.tar.xz=a6c3bc7f7f2e6a4cee6db2aa16f74af80cdd17ca92dcfcb1ab1e0c06bbaddd79 -dist/2025-10-28/rust-std-beta-wasm32-wasip2.tar.gz=77537c7a4518e62cb592e5e9d41df02d1ec8a3038b87cdfe082c98ae578973d5 -dist/2025-10-28/rust-std-beta-wasm32-wasip2.tar.xz=794a3c2e08edd74b7a004489017172c30a3242f7f0c5538c3b033937787da332 -dist/2025-10-28/rust-std-beta-wasm32v1-none.tar.gz=746ac6eb726ea2d2996b68be881d5c5fbeeba2bec1fbe57e6c315d4953cccba1 -dist/2025-10-28/rust-std-beta-wasm32v1-none.tar.xz=8bdbcf0cc2b598cbb2098f113128e6f94085dfdaea3ed3d5e15cfd0a82262b56 -dist/2025-10-28/rust-std-beta-x86_64-apple-darwin.tar.gz=2082bcdfd0e837163aec012cba1ae674825f52f5891c8cf3d4d00c619d5bd27b -dist/2025-10-28/rust-std-beta-x86_64-apple-darwin.tar.xz=b2267e0df76f21bcfbb55ab323c58015501d3a3060c4127a005e29fa0e628a7b -dist/2025-10-28/rust-std-beta-x86_64-apple-ios.tar.gz=6a48b60d0aa883ffad612a657d9de232ad1df92f937a5166532a7ee4e655fcc7 -dist/2025-10-28/rust-std-beta-x86_64-apple-ios.tar.xz=81ee2cdad7fd25b56be24d919268d0dc61c1d44d50bccb4c1811e30e85b97869 -dist/2025-10-28/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=01d5952f0970508064fa24196e126cb09aca5085ad6258c53397c3b23b006217 -dist/2025-10-28/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=3c10717be0087060ffb0e5b83c86ce69bff8b0dee9dee95b1be6a44f4238b5c5 -dist/2025-10-28/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=ce87a282ea73eb83015a321b208abfa9d4afdf4a797c799d9efeb1a246e4a64d -dist/2025-10-28/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=5c8866ec1cb4ec7826a94510c00f5cbc7f31822dd7e01ec2fe6b781b25e2afa8 -dist/2025-10-28/rust-std-beta-x86_64-linux-android.tar.gz=19538e0dd74d638b3ac1ac9ed679b8ebc6c058f661d7f167f957eb0866f7cb65 -dist/2025-10-28/rust-std-beta-x86_64-linux-android.tar.xz=15554ba8cc8d1d1c4c46e0438503170aff5a5519eb8bedef07a32d187ca32915 -dist/2025-10-28/rust-std-beta-x86_64-pc-solaris.tar.gz=41a6db659dff188414e33595448dc9c2b99103dbbdedab53d74c6aeccbb76458 -dist/2025-10-28/rust-std-beta-x86_64-pc-solaris.tar.xz=2bbcb13b8271c39a48ac2774e7444fdce883a283622400085623c161f8be405d -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=e2390bf5da8a91f056df7133020d053d5d90c84c81763738efe8a862864318ae -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=5d6fb692f2a1d2bad7b550b79e1288223ec598a46975848d07f2a5105b36cb4d -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=30c66f64c7343388f3205e172e64e51dc2930214fae46eb3b21648285092c944 -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=25788901f6fc13a4963bba4e985d619e0739b1239a5679406229a2bd5eaafbaa -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=9fab4a6cc38c2f06113ae9f0620e40ff5e9134f83562c32576c1e82048ad3bc8 -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=1b7007f9bc3619cfba09bfa92c3b1e5460316501fee4ae7c8492703a79517f4a -dist/2025-10-28/rust-std-beta-x86_64-unknown-freebsd.tar.gz=461036ed77e332851e88fb6f0f5c64068aef0b177b27662f326d157c06c7115a -dist/2025-10-28/rust-std-beta-x86_64-unknown-freebsd.tar.xz=fd7c7b75a50833650f131a6a676df90dcd57c4784654aee12ce594846da1c219 -dist/2025-10-28/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=882fe895b376384d9b1b1d9c01d9b641ab56b1405d63d7a83266f228b4b759d7 -dist/2025-10-28/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=e9d1fdbd0ba327b6d4e618622c0336eb6895e0e188005423710d514e145baac7 -dist/2025-10-28/rust-std-beta-x86_64-unknown-illumos.tar.gz=aade9f95b362cf13ee48e1d7608eb8487229cf86cc72082afe21fef533e45f5d -dist/2025-10-28/rust-std-beta-x86_64-unknown-illumos.tar.xz=de92c9cf00a2413d5481e96e1db5157c5cb3814851951076e4881b9269651cb9 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=04f6feb37de8305d17e7aacc6174395bd55447340963303767c5a66a63200149 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=2838910a0ef0084245a69fefdc67845ea579f49629cd24fa051b4db0bdc76d98 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=d2f88d608fdccd0aecbcd83cc184d157d93159e29ad525583188013f327572d1 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=b5e7ae18377727f93fece51d9ee5704ffd5a9ccd00c540b38ebbf3b9155cf20a -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=40a52cf3527090a12095b0ed4ad8d35fa5e3cef39146a9a8bff9009cf5772dc1 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=28be865d06f9bd744aaad2e82ab8bdb87045e6e2d7ee6fceef2024fa620ba920 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=e0afdd5422adac97fe8c6943470a8561847a614d3e367cb983f28250c0e2e34c -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=3007d13a0640d915eca622260c6b8b6a8936788a1228011b90df817b6888155c -dist/2025-10-28/rust-std-beta-x86_64-unknown-netbsd.tar.gz=1744c2485854792601518dcf7855d4223db63e9f3693e2d06c1ac285b92ba33b -dist/2025-10-28/rust-std-beta-x86_64-unknown-netbsd.tar.xz=757803d3cfb8db12dd7c9528852c1e28fb3a9ba97e4230d1e29dbf1834cf3f84 -dist/2025-10-28/rust-std-beta-x86_64-unknown-none.tar.gz=21d5de489cc22d849f246225909278f123483a446e1a3c68b14b8b992c104082 -dist/2025-10-28/rust-std-beta-x86_64-unknown-none.tar.xz=62755ecf24c0a2423b4d05c09ec8e8d38737e6762312d1ba993e1a9417083ba9 -dist/2025-10-28/rust-std-beta-x86_64-unknown-redox.tar.gz=0339d37d857f7f5ecb1607e8c53c499623f0c3563e3b68f2b939ee960d31b270 -dist/2025-10-28/rust-std-beta-x86_64-unknown-redox.tar.xz=613b5ca94e5c33c46d9f29cb557d1e512abd1104c5d81f1897915f6153175cc5 -dist/2025-10-28/rust-std-beta-x86_64-unknown-uefi.tar.gz=1da6167f0a2652b1622cae5ac815d55e307dbd639e4901005a3b225150dcafa7 -dist/2025-10-28/rust-std-beta-x86_64-unknown-uefi.tar.xz=6fca79a15c1ef9f8a3974f84af805106ab453099bdb6f652f584abcd7c8174be -dist/2025-10-28/cargo-beta-aarch64-apple-darwin.tar.gz=e66d076303fe8010c27fdbf8a9e31f47223508a280cd2ffcfea698aede848986 -dist/2025-10-28/cargo-beta-aarch64-apple-darwin.tar.xz=f4e87741a4070fe5bc4ad59ecfd324785cd9a477c539543d6a4fc1675afa8111 -dist/2025-10-28/cargo-beta-aarch64-pc-windows-gnullvm.tar.gz=5e9213968960bab07ad28408563b46d01c1d881c26ccd07651bdb527440461cb -dist/2025-10-28/cargo-beta-aarch64-pc-windows-gnullvm.tar.xz=ec01099da59fab595f8ed8a2f6fb308fbaaabf563cf50c103d47fad4595d72ec -dist/2025-10-28/cargo-beta-aarch64-pc-windows-msvc.tar.gz=ed3cd99db73648bb87c5a25556da30993346f1acc665f9dc906094639370282a -dist/2025-10-28/cargo-beta-aarch64-pc-windows-msvc.tar.xz=c5f89cae65188a7d1b5b5a93f8645774f878db6a14032abb8fd960fa9f4cdb06 -dist/2025-10-28/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=2c85f1c5b1a8bb9532194a16ceb8b04f1586d0ade14442f45e740f3e85022924 -dist/2025-10-28/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=a675601cf6552783625b79c33c1d42715c3918a08078e6eed01236910bafc4b4 -dist/2025-10-28/cargo-beta-aarch64-unknown-linux-musl.tar.gz=e5f2cc9f31b927e2e02117c38a5822c39993242459a057c48e7e11695dabe5a5 -dist/2025-10-28/cargo-beta-aarch64-unknown-linux-musl.tar.xz=1830b8b7e43fc03f0348503ae036b30d0e906cb024bc2257e717a58df95ac222 -dist/2025-10-28/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=eef6f553184a8177525a1ee932d6e293f42eaed6986c1c83f7d76d579f02b867 -dist/2025-10-28/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=13c81e5874532e490c987dbc46b19cf3a7eac14fefdffc30d0c5493a84f8a257 -dist/2025-10-28/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=56d7f1b41af4d72091c8a99b9a583f24d5aa3912f6dfcbfeeae4eb47bfbf158e -dist/2025-10-28/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=010292117dca5b10b71b7aabe38d1e8c2f0180ab54e9bf072a9ca8bab3f40ced -dist/2025-10-28/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=91671bdd6438df48e4c529e5897afe57b91e8575c12d40c3cb3280493599c0d9 -dist/2025-10-28/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=0da8474db35ef547b28f123e8c98ec84dcc4a4a5c4a487a222ac006e809ceb80 -dist/2025-10-28/cargo-beta-i686-pc-windows-gnu.tar.gz=5d9ce7ba82e8d694e53ac877214c0873b0dd78a60c8eabcfe9128433d199d12e -dist/2025-10-28/cargo-beta-i686-pc-windows-gnu.tar.xz=209100fad49e274457d8299360a4c2e83803411a69fec69898a03d9a2bdee955 -dist/2025-10-28/cargo-beta-i686-pc-windows-msvc.tar.gz=edca4ca03b055b40d0c4778e325b93e3759123f207a6d32d7ff42cfa0f323604 -dist/2025-10-28/cargo-beta-i686-pc-windows-msvc.tar.xz=5146440d030e04450de61bd6022cd7ad6364fd06f9cec28bbb7889bad171e579 -dist/2025-10-28/cargo-beta-i686-unknown-linux-gnu.tar.gz=d1045ab266d914060e24224b0e74ea865f4bf4cd527d9a09c5631441c40f48a3 -dist/2025-10-28/cargo-beta-i686-unknown-linux-gnu.tar.xz=caed7a0786cc9f476d1b9fb5367c67a02397ccb12ed18a357b5ed04fe77fb12f -dist/2025-10-28/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=017335d6ca97cbe4bf93e2ffb4def850b05a8efa0367b008de4cc8b55f1af3cf -dist/2025-10-28/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=f5671ec0dee9841d4a482183f56ccb986f358a80d043d1ec4b05bc8a356f8ad7 -dist/2025-10-28/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=0a280ebc1b5aab8452f1445fe858ad4808fd7035dd498510951d8b7caa13edc8 -dist/2025-10-28/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=8ab41df2264470d6ed0a6d82b665992f76f9065046a153bc8ee1eda9ca81eaae -dist/2025-10-28/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=7368d0d297fa06108271b03138a9dda0cfbdbe5463a614ebf6fb5b573dde08d7 -dist/2025-10-28/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=1ad0b7d4e3173150768db7105b1a691e8c85db3e9c6a391390e2f5df7844d420 -dist/2025-10-28/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=75740d0b1847f73777894f484e085f70f24d981b0ef69d00cb5b0c29d276c5b5 -dist/2025-10-28/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=1ca71e60a6fa9752dd27bfe4f354a1b732b67e55c9e645021e6041a2450b7994 -dist/2025-10-28/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=ab37e6d39ccb7fe33c55bf62836c2174f1a4197f02cbe9d88d118b81ec6d49e2 -dist/2025-10-28/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=77cc38c5b89fc65fb7453dcc3c3212e0a512923497420b7782ffbfd88f00b39f -dist/2025-10-28/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=29a2dd23fe30b2d1741e1d4032d4250b4f7f0e2af5ae718b309f2d271e13ef41 -dist/2025-10-28/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=bac42c5d4af02abbb4db1a9dd4664340d686e4c23f923f372d3b08e090bd105c -dist/2025-10-28/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=3b396bf0ddede9f4964bc9fb27b52e628db1d9ccc38dbc5d5e06c316ba8bef87 -dist/2025-10-28/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=e706521e4496c79bb677d7d06d79fc1ae2770cdba4a81d8c28ede81ab4ee7909 -dist/2025-10-28/cargo-beta-s390x-unknown-linux-gnu.tar.gz=2fa6ecf04d1cb20dde5f700a0e425ea186d628c5704885e84e197e4494af101f -dist/2025-10-28/cargo-beta-s390x-unknown-linux-gnu.tar.xz=e8810699e679fd0306d4e6c95608970ec5a1d1ccffcdd707fe4a4508518a0e6d -dist/2025-10-28/cargo-beta-sparcv9-sun-solaris.tar.gz=2fcae7eb2f538d84545944c744bbac39e28b3bd58e8d2bdc862d5f66df7068e7 -dist/2025-10-28/cargo-beta-sparcv9-sun-solaris.tar.xz=2fe42f27469fdc23a9e45ec025c60a09f00be07a239cd8c8df74ce52e94b4cab -dist/2025-10-28/cargo-beta-x86_64-apple-darwin.tar.gz=c92c1a580eb85d96f973df4dd9cf4440eb661f8fab9c632b5f0621cf0839badc -dist/2025-10-28/cargo-beta-x86_64-apple-darwin.tar.xz=6c2b13253e1066e49fc52f3cb1654776d5d38853a15e8022652b4a2cb6845daa -dist/2025-10-28/cargo-beta-x86_64-pc-solaris.tar.gz=ca98af5dcaae734ccc02fde2807dca8d95947918eb753d407c12dd05ae937568 -dist/2025-10-28/cargo-beta-x86_64-pc-solaris.tar.xz=864ed5842890359e9f767b4050b8a27ec9c27c88a8cef20993b8f775c213d394 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-gnu.tar.gz=ec8a9e8436f83388736f16f7ad9962a1d9b72673c3da56b8233a6b39dde54534 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-gnu.tar.xz=1f059aae8e6faedcc56663d833a07417e07eededdc2776b2762822987a010131 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-gnullvm.tar.gz=f364bf2f20f35c7ff0381cbd34c88a256849a1b9a27267436e14bc01b7bacfbd -dist/2025-10-28/cargo-beta-x86_64-pc-windows-gnullvm.tar.xz=451f18d049f1c47bfa0c010481e499afa1baaffb889de11534cf451578c62f76 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-msvc.tar.gz=96ca48b12b27b8e933cbb426e7123873a1120bd884a62d150aceb6a26bfc7694 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-msvc.tar.xz=dfe14d019f5c1744a312da8d926059147974de0b5bcdcd869526b5257a1112b3 -dist/2025-10-28/cargo-beta-x86_64-unknown-freebsd.tar.gz=7ef3d3edb6b536382f5063a5de5aaf036d6ba09bf7bd1ff770b87d8942110c2a -dist/2025-10-28/cargo-beta-x86_64-unknown-freebsd.tar.xz=beb5587235e8ff471a8eb9fd84ae5cf4380e7ec9b00ab03dc0c549be0e661dd0 -dist/2025-10-28/cargo-beta-x86_64-unknown-illumos.tar.gz=b97f511486ad044dae0c8b50df8430e489887ac36b770155f163d8e4216cd9c9 -dist/2025-10-28/cargo-beta-x86_64-unknown-illumos.tar.xz=21fc84a42fa988632fb9b0d9dccdf6ab2fbbd06a6780076282fc9bea56567559 -dist/2025-10-28/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=d5b05dc398716909df77415b4a68233b68a5d578855e0e91dcf423f2985fc1cd -dist/2025-10-28/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=21e79bba772e93a6fd910e9d6ee833b55a53b80088f8280525717a4cd800c21b -dist/2025-10-28/cargo-beta-x86_64-unknown-linux-musl.tar.gz=4d126f2591652ddea26884973c1ae1f1e25246cc5f60baeb3a52d6ff45a1aa15 -dist/2025-10-28/cargo-beta-x86_64-unknown-linux-musl.tar.xz=62113a7383f7ff8a9bee099155ca55c3c69d16bf135fc06046f672b2102deafa -dist/2025-10-28/cargo-beta-x86_64-unknown-netbsd.tar.gz=e9a07f035f308d4b9cf5f1b0ab4ef969cad1c41528adea2fca81d8dfe45ebff0 -dist/2025-10-28/cargo-beta-x86_64-unknown-netbsd.tar.xz=3f3d87269072d8e219e7213ca878a7fd441aaf74e4d052ca44ccc7ad75e83eee -dist/2025-10-28/clippy-beta-aarch64-apple-darwin.tar.gz=a44daddb30309be19856b9572679569ffc2ab2c30318706ad59aa2dc14887587 -dist/2025-10-28/clippy-beta-aarch64-apple-darwin.tar.xz=00576ad0f30db5be96e6434e22a2fcdd167067d65ab85199df06a6d11d1ef6c0 -dist/2025-10-28/clippy-beta-aarch64-pc-windows-gnullvm.tar.gz=24fb3dc6680e845c84e535f9c14be5e3d4052ef3ccc800e0fd81815edccb4836 -dist/2025-10-28/clippy-beta-aarch64-pc-windows-gnullvm.tar.xz=20d2ebdb6e2a902eb74ad502a14a2a66e6a9316d5f94513ec9781d146c323d9d -dist/2025-10-28/clippy-beta-aarch64-pc-windows-msvc.tar.gz=652e5bdffbb89ba281cbd5efe3a2cf103adea6af7ba56a21cb6bb538a2ea6536 -dist/2025-10-28/clippy-beta-aarch64-pc-windows-msvc.tar.xz=59d0fb72db77c484571ebab8c992303659225735d3f820ed7048122d8f96d764 -dist/2025-10-28/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=6bf6fb7279ecf5df6edca6014db5f8ba0427fd8cd32f073630b6b02e2e69feaf -dist/2025-10-28/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=0a8d19bca62dc38e64cf527b239106901fa2e0642ca5c2ef1cde070faaa901b0 -dist/2025-10-28/clippy-beta-aarch64-unknown-linux-musl.tar.gz=663581dbd93b22b3b20d281486c8dc0580e43ceca42d9455d78f2d2c341cc758 -dist/2025-10-28/clippy-beta-aarch64-unknown-linux-musl.tar.xz=49548d8ee0561ab96629e354ad055ed5f0c6f3f60c1559ca2a27352b441ff848 -dist/2025-10-28/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=b3d44866b1f909576e0e586aa34b480f1170aa3eba28209ac5bcb929f544d07c -dist/2025-10-28/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=717397166acd760e391c251b1c308657f45deadd928035d2860c772c8b377b91 -dist/2025-10-28/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=8911fa3347ca26a2afed6140bc4cafa629830740b8e4ff5e648c517f6ea43c6b -dist/2025-10-28/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=e7360c728068520ec7bd712d57357ce30bbfbb629ec69cfdcf6596002751d93b -dist/2025-10-28/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=6d94df05e43804f1054d17542db72cfd3f2df27eedc275c810b35362f9d581c1 -dist/2025-10-28/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=25c33744d9722aad4f9fc80674233d16eb653adb17d0deadcd3be8f16a79ecb7 -dist/2025-10-28/clippy-beta-i686-pc-windows-gnu.tar.gz=dfb9ba0cc842b7c92f1dda8bb88bd1db9beeac746c3ca3d144dd4d66d91ff6ff -dist/2025-10-28/clippy-beta-i686-pc-windows-gnu.tar.xz=20f3cf3fe6b52b8f54391be7edd11331a376313c37b674f4987589f50eac68d0 -dist/2025-10-28/clippy-beta-i686-pc-windows-msvc.tar.gz=bcabe1f7679e1ae416c7ed56afd74ad224ff47cd9b5413dececb0e6f503ce393 -dist/2025-10-28/clippy-beta-i686-pc-windows-msvc.tar.xz=f8ebfef39e7119b45a4f714e91b47964aeb6653fbdaf9b01786ef629cbaf3d31 -dist/2025-10-28/clippy-beta-i686-unknown-linux-gnu.tar.gz=f0fc318e90de4f45f6ca7d0d6ca3ed5d044db75f97254d792cdea9a7b196042e -dist/2025-10-28/clippy-beta-i686-unknown-linux-gnu.tar.xz=27c9adb19a7f84edb19ff4c8ce34dd836fb8d10e8786999591e41ec9c60e4602 -dist/2025-10-28/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=04673347c7e13eee9e301ffc1640ce7a5ed733915c29d90750706829d6b02884 -dist/2025-10-28/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=2484f24346fbbd2d48f69d86ab7710ef65a5952bb5ea0141f3388f616c7d6d0c -dist/2025-10-28/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=656eb1b94dd2324958e6ba0b1c7a37281abe24dac7d87b0e406fc10931ea0d29 -dist/2025-10-28/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=3349952da5d2693554d2e1ae60bb7ff9cd64451719cadf4227095b73377228c1 -dist/2025-10-28/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=40eeba3b2807a1d807ed25c3bc0482d5b91135a769d2281a894ec8cb8bb52a35 -dist/2025-10-28/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=0a6e79cea6655d6b3e1ff1218651c627886d8f06a5d36e9c3bd3c9c45b375f57 -dist/2025-10-28/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=b11f919fce34d70816a6dfa0884e37939c38336bad6261fccf5d67d25935852c -dist/2025-10-28/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=ead91ce4260d07d4e4f950092e94ae224f067ae3c711efe2ccedc9250b2f3dd7 -dist/2025-10-28/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=481a2e3b45751e2d86c30d4fb3897f0a7a18e9eadde2c9a3ad1a8b0259fa2066 -dist/2025-10-28/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=d5d6529cfc89c29443d9e87041a5f93b746e5bc5791016242e2f271be5bcb557 -dist/2025-10-28/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=a70d30948f5e95cdd454fa2b3284b97f29134f59e98e130fc2877781f3b62e89 -dist/2025-10-28/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=8dddfc0b1b2ca8e8866a11a1c95b8601c50150f1e52adbd3803cca2fabb386e9 -dist/2025-10-28/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=bd1b28dd79a52de657515ba5c25063b0b6015eb30ee3b0ee05511567b429c992 -dist/2025-10-28/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=5262011db6be068ef70905a28939b1838a2fd2b719d38d59e80754695049269b -dist/2025-10-28/clippy-beta-s390x-unknown-linux-gnu.tar.gz=6d3d83d03c46e1de2cc6b6f204e701acc9dddb6d4baef80fada9d868b7eb86cc -dist/2025-10-28/clippy-beta-s390x-unknown-linux-gnu.tar.xz=e57ac819f962d9b431b699b40a047d3e2530f76f2670c5a04747b7de11c3d5e2 -dist/2025-10-28/clippy-beta-sparcv9-sun-solaris.tar.gz=7a492d27b49facb9554248935728cba483eb7ecf3de317751a7445c3932932e6 -dist/2025-10-28/clippy-beta-sparcv9-sun-solaris.tar.xz=cc02f4f971b9e5eb63ca65ff6947cf3490101bfb40ea9fb2b310283bb6d10b27 -dist/2025-10-28/clippy-beta-x86_64-apple-darwin.tar.gz=56f11b8ca012467ef6aa8dc3458a5bf45950f1de062a616a01f6c0aae412d0fd -dist/2025-10-28/clippy-beta-x86_64-apple-darwin.tar.xz=01fe53ec63d71a8427fa3220d037313fc31f8d0fa33a64305b01109344aac21a -dist/2025-10-28/clippy-beta-x86_64-pc-solaris.tar.gz=d222cfda8613bba09b0ac1d02fad99c0d081d10733f0f9253d809221ffdda506 -dist/2025-10-28/clippy-beta-x86_64-pc-solaris.tar.xz=918706ee8ed38bf398cbf0dad85333e3082dc461fff2fb2399b96e840dc24766 -dist/2025-10-28/clippy-beta-x86_64-pc-windows-gnu.tar.gz=7764df051100b08b4b4e5c434d5ced1aaa84d9665f6a4401c9ed6350db983b70 -dist/2025-10-28/clippy-beta-x86_64-pc-windows-gnu.tar.xz=4a43dee6ce0279de929566f844fa4987d10fa5ca856bb2a2cbea4327eef3308e -dist/2025-10-28/clippy-beta-x86_64-pc-windows-gnullvm.tar.gz=add2532fe4e8afb8b53aee8a729fde0c0b36f83a8f6a859c39ae25f3d01e8dd6 -dist/2025-10-28/clippy-beta-x86_64-pc-windows-gnullvm.tar.xz=7117f0afc57ac09c277ba99be4a7de80d62ffaebe4174706910d5ab6501ec9f7 -dist/2025-10-28/clippy-beta-x86_64-pc-windows-msvc.tar.gz=e71d45b8bdb5346d89f769b4698b404b293884878a7f697680318c72829c1d6f -dist/2025-10-28/clippy-beta-x86_64-pc-windows-msvc.tar.xz=67be8cf6580a4a6e36eff94bfe19fdad290eae5db598d2a016dfcc7516178e14 -dist/2025-10-28/clippy-beta-x86_64-unknown-freebsd.tar.gz=03b78bad90efe98cab6416ecc641b7da0c9a2be5950edbb4c520c0758cdb90a8 -dist/2025-10-28/clippy-beta-x86_64-unknown-freebsd.tar.xz=056aecae34c8ae10a41516834809d983bd6126bd0374a7bf0857710492f0d0a5 -dist/2025-10-28/clippy-beta-x86_64-unknown-illumos.tar.gz=a67147c647da8a9b68a507087b66610ed19e65b94538b08326b000e66c170260 -dist/2025-10-28/clippy-beta-x86_64-unknown-illumos.tar.xz=09bd43034d7bc1e9ad1873610237f98543751809ebe63d8255813eadf4a00e70 -dist/2025-10-28/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=9397e5c3b1f45ce949b8e3420233e8b86f95a887667c917b8e7615218989820f -dist/2025-10-28/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=5b67e9eb803c180d101e799f6d7c2a6ea7ec07a93a6395b4f688bf2592bc30d5 -dist/2025-10-28/clippy-beta-x86_64-unknown-linux-musl.tar.gz=b255c33a89b0b1bd666ffb584c20554daa3a7c48123de75eae5e1b4cbc53e1aa -dist/2025-10-28/clippy-beta-x86_64-unknown-linux-musl.tar.xz=bc7f3f7d59f9c52370849092541a9368632f390ed9bc88f2566f1e3700f4da80 -dist/2025-10-28/clippy-beta-x86_64-unknown-netbsd.tar.gz=a8f366918520cc5a82c9bcfbb419570e6792712455ec5c04655e6557a657e949 -dist/2025-10-28/clippy-beta-x86_64-unknown-netbsd.tar.xz=dad3555be56e7c8d042f65dfced7915856f9f23cec13a7a633a4aad38c634247 -dist/2025-10-28/rust-beta-aarch64-pc-windows-msvc.msi=943683af0d464ecd36678e1c87b1207a67105820cb3d1516eeebaae450a2928b -dist/2025-10-28/rust-beta-i686-pc-windows-gnu.msi=8532743b3406fbf2926e5c6643300194eaace9de492e7f2ad0caa6f7d040f8db -dist/2025-10-28/rust-beta-i686-pc-windows-msvc.msi=1b3b15aa90c3dca73e9d72d53d214eb3c02b97386c83d8755a03f571cc09de4e -dist/2025-10-28/rust-beta-x86_64-pc-windows-gnu.msi=6249ad7cfcfe78b541e4935ed18dc4cfb10130252885668383a4c8f5046ecc2d -dist/2025-10-28/rust-beta-x86_64-pc-windows-msvc.msi=700f63a1baf0de2f0d1972454486f890af15b3700481698ffb0daf403778390a -dist/2025-10-28/rust-beta-aarch64-apple-darwin.pkg=1f2862fd5dbf8a9c7a765e75391cfffc5a3cd6837066b29f95778b5a346f0f59 -dist/2025-10-28/rust-beta-x86_64-apple-darwin.pkg=ffa2c6275b401c73575a5158911bc53edfece2edc03f6b3f6a140823cf870ee4 -dist/2025-10-28/rustc-beta-src.tar.gz=dbbae9e1c0b5e914b588ba5b659b7fb6af3d5b422831aba028d64b00c7161417 -dist/2025-10-28/rustc-beta-src.tar.xz=aa771d2b1ea8c933444c962c03c384bf2511bdeddf90edcaac8f45bd49f5232c -dist/2025-10-28/rustfmt-nightly-aarch64-apple-darwin.tar.gz=5a5e525f45010fd3e30503f408f21eef78cafa54e42adf9709cff50f6cb29720 -dist/2025-10-28/rustfmt-nightly-aarch64-apple-darwin.tar.xz=b6f92173abde0be1f4f3378c682e42016390e6e5e20df7e84cbd7804a6161114 -dist/2025-10-28/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.gz=430775c6856f4aea6a2b83e245904d5527f6ace134a9375dc7172f77ecd328f6 -dist/2025-10-28/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.xz=3d14ccf194d04ad5767a5fc3df6f9c1427cd0e282671887d2264b8314586e168 -dist/2025-10-28/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=251f7fa0b78fdad3be1977ffd6a2f563d1524b6423d2bab73d1741aec97b4717 -dist/2025-10-28/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=534cacc40024fec78c02916e7e2d46cde8b8153d303efc1b805af8789f25fb1e -dist/2025-10-28/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=5663e413cd9ae9f403a4b5c5e9a9862c00d57bcd68bde9161c91e852115e45cd -dist/2025-10-28/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=3625b287a83796cb71741b9a4b002eb4517950d386f97a91470c0acd5aed835c -dist/2025-10-28/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=657b0774a95a925eb38d039ef11bc23d15c4733d0b322f172f0b8236bc7410f6 -dist/2025-10-28/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=4e058f11346ec86801bc9cdb830c6dec2620b81fe2cd4b439b275a5145859dfa -dist/2025-10-28/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=820ece81e455d11f65ddf09093b6bf97359cc803959d951bd199c70a79ae117e -dist/2025-10-28/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=8a72a3e715ab2427fc120f8af20d67f722881ee9e13bf482e45ef07f5fb2bf86 -dist/2025-10-28/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=fb583c846e1a11663a1fc525f02c0146dc70e7b4da12c264c8b00cf7927ad9c9 -dist/2025-10-28/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=8a15430000d48b702142cc4569a5eef3aba59c07f33f69cfb6966250fae18178 -dist/2025-10-28/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=c470dd9f35b1b701e8475716e61cfadee5475fa29a2994f407d532a794c0ef82 -dist/2025-10-28/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=774898dd43893b99e4e11d004c52244d78d2fb08aaa6fa242cf1d7070d9ff8ac -dist/2025-10-28/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=31ef71bea5f5ce3668b903fabb1582dc256fe6e2f97e5c23ca468e05f3deb7c9 -dist/2025-10-28/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=232351f0a578f9973b536eb587b2e90cb01ca5f76ad376c09d7dd225c09810b0 -dist/2025-10-28/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=eb469e8475af339d36e1381474f931e326ef1f095a6f56f44730019c5f6422fb -dist/2025-10-28/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=42c5f2e88f81cdcc375d26c4ab6d9ec03b387b8de632af8a3fa75bcbfcbf56da -dist/2025-10-28/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=79e06c14b8f18927b1c24cc4ea97e55a805355137a9bdbe3ba616e334878d85a -dist/2025-10-28/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=3883c297de03da522a20b893f24970305fadaf726dd9388f89196e1f284115e9 -dist/2025-10-28/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=b3ddf283d7964a4c261668df7685bc47b469c7294325f975436d465cb7d44163 -dist/2025-10-28/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=9e63e1bd8b4c52943092e91942737be9b3ee9c128dfbeafdc01d3dc732058165 -dist/2025-10-28/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=83845c5809a9b525655565b3e3b4889e2a07562587c6f046280a44dcbb809094 -dist/2025-10-28/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=533113ead2985a36cf685cfbd6645d43f1a7e2e66b6eaadbde2ff5a72d10c5dd -dist/2025-10-28/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=82c6aa57adb0f03b96982f51edc65aebfac3811cd2845d280b7bf5fb81cbe92a -dist/2025-10-28/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=8f4b3c91072d56ba80ba4702e611dbc6fe66163666e6ee35d74602ef36fe9839 -dist/2025-10-28/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=4fe0b85296e2249b36a0b021d6b82e7c31c40a5f717a5f447b6bf9b9524069a2 -dist/2025-10-28/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=9257bb295a58a7df3fbbda809bafc74a8601618afd0fd41467439a8972278cae -dist/2025-10-28/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=d3a5851060a66a0e027ba142dbdb6e827f4f5f5116b5fdb0b8e86ee56616d682 -dist/2025-10-28/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=fe1e9e4e3a234ba8cb656b08b7bbf5349f5068906cb60a4c5c53f7fe3e214487 -dist/2025-10-28/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=2187f1ccbd4e638efaf9f05566998b579b32729fd9ee4332964a3c54556c3a20 -dist/2025-10-28/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=88526ca6af21bdbc6c46130012cb5fdde25fd44e6372187e66d273067efbc052 -dist/2025-10-28/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=9299c8d4dfc320cf331dc4005c36a0108961a6d5ad750a5b0a6be8c7cda77953 -dist/2025-10-28/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=7da58822a9ba4d65258ca0cd514b9abcc85070baa195ce65d40ed9d9de049049 -dist/2025-10-28/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=e07cc8f1166bb39aada202559c1e2ee9190cf85fc11b4d4abb921cab352748f8 -dist/2025-10-28/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=ebcb49b4ee1e8dded5e6569c7edea1578a369e92aac9030a51d11e95bd8bb8b1 -dist/2025-10-28/rustfmt-nightly-sparcv9-sun-solaris.tar.gz=247ce6a1fb10911b8f38bc8f88617d9a7dd2147e1f1896710b0b610f8bb4b86e -dist/2025-10-28/rustfmt-nightly-sparcv9-sun-solaris.tar.xz=020d64391c730a61f4c61d802b432a463d4909d0e4d5fe4756db4683df6e000c -dist/2025-10-28/rustfmt-nightly-x86_64-apple-darwin.tar.gz=547d7711acee55435e271fca1cebead82045375b0fb136404be7df379b0d404b -dist/2025-10-28/rustfmt-nightly-x86_64-apple-darwin.tar.xz=e8ef4fa56be91b642fd3a8c29afb9dfb3fb7601c8fbd24393be4f3dea1802163 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-solaris.tar.gz=0e41caa314927c9a8656d16b6623c95463a64f07a23941d03597a17582c224d6 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-solaris.tar.xz=d73dcd42d9110befbdf64c46b9e4e8bad07839302cec49e2d8cd99ab436d4bbf -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=8e821c45dc91d5df1b9f8487554cadc4deb86a9ef3db25f4e21b38eab3cc8ed2 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=f98ccfcc37b7412788a546cbafe5f09b90c26f823e3cad17e71432df4ba910ef -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.gz=762e15406bac23f0f41dae2b1b3370458b92e8be771868b4f8f536f53cb26fc3 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.xz=cd87b4a4c2af3edea8ba09ce9bb8704449d8f51c5dee8ba10161e0ce2ec2aa19 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=7de2ee69be5384656024a6d7c3481315fe90abc9ba9a26726f1eab09aae2c818 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=16377ae5474e30b6c11ba886579ef13db4039d0b9f43240db00aacf7366b37d7 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=d98fd17080ed5a4fda444719011540a80320001a0b0dc36148f2e3f78e5f5c33 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=c825c2b46f43fe71f4452494fb422cd9565ec6454857835a6c77081553081523 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=8844743cc05351b1f6ba8fb50ac1d86161a285775eb4c0e474308aec71b631c7 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=172dc660ceb00e7003e855a09f46d9f83096773495ed6d7b8b1ed6b9e770912f -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=2710450c26834b07a5eb80bf990dc67a6db89f87e26d6b613ed96116c28958d4 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=bbb8eac454e0ba3b23c9803d8201fa341d0f0af509aa9e8b530c9b98a1d9886c -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=e6bb6a67878c9cbbbbc96f1a1858500403ecc3b8c951366e18ace0f2601f41cb -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=f6509af9551e73ac16c425c53e667382bf7b6b48be65f4779485ee7843e68030 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=3915f1907939fbfcd82012efa4293e7ddf22bd5bf1484efffacb31c805e6cf68 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=cca6182ce9f2906a8b16971741a8435dbcf60d9ef6020cc7d6f7909525a73dc2 -dist/2025-10-28/rustc-nightly-aarch64-apple-darwin.tar.gz=876004fa16a6154ea8ea46cd1bb60a06fc14b24e72e26e20e42fde4e32882b46 -dist/2025-10-28/rustc-nightly-aarch64-apple-darwin.tar.xz=0a98f29bb6a2a1555f6ceaa161ecdd2e599ffe879b98bc98c6066e257fc12362 -dist/2025-10-28/rustc-nightly-aarch64-pc-windows-gnullvm.tar.gz=b07b2f7975b463970cbb4a8c92e51788ac63c3a46d3ae6c8cb54c7024161d899 -dist/2025-10-28/rustc-nightly-aarch64-pc-windows-gnullvm.tar.xz=5445b2e30804733fe2a7d07f66a77c2e3ec5e7c71bb55403541b8d365cf91870 -dist/2025-10-28/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=d2cff6b8cb52172f4bb394f8ca891897c774ece1b87f9d30729aa236dfa24900 -dist/2025-10-28/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=a6d0c00367b49654c91d4b71b33819854f628d51b7193c2475b9f737258a575a -dist/2025-10-28/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=c30649c2360aef41d97bdbf76d55bbfe674a1225161bc125a8215d3954656cda -dist/2025-10-28/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=3b204fb1461f47b4e2a79a67923abcf8610ab7ab006ee3f9a70cdc87458f81c5 -dist/2025-10-28/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=949f55697b50db7d70a6465b100ae4458d2f676b818ca7227014ddc9c5f707e5 -dist/2025-10-28/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=ff500cd8f318f0316936af462264254df2aa1bd5a2b368ad3c5758e9079eaf71 -dist/2025-10-28/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=231c4cfa37df03a0e0517843bd115a0f0b13ec259397d6e4dfb4014d3a0d4d9f -dist/2025-10-28/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=50f4d7060d02833949ffc970b88c5ad2183fabd3c498334bf63d87d0c9602720 -dist/2025-10-28/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=f89586ea5bac722a06c225a50d7d603b4895aea89297509f248a1cb51a5cf0ed -dist/2025-10-28/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=0de0552ae68cb9b61f2c5031cdbefae5ccde39c4003441e93c2e4e704d3751aa -dist/2025-10-28/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=019bbb267d1c0520a715287e0a1a680b58dd5e9ece2071f3ebd6f2b1d8eb2228 -dist/2025-10-28/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=069bcd46adfb5e14786fd8aced5ceb74af24cc05dfa2bd41ebd81ac146122598 -dist/2025-10-28/rustc-nightly-i686-pc-windows-gnu.tar.gz=911eb977b10aa4bb1f25124f08f3397fb3ac65f36666865be40bf44259b5d77a -dist/2025-10-28/rustc-nightly-i686-pc-windows-gnu.tar.xz=14ed0abc8708a90e8bbaf0c0de2aec1a4ed60c63b4db00fd4a732f3c808c125b -dist/2025-10-28/rustc-nightly-i686-pc-windows-msvc.tar.gz=8917e6dd4786f0f413908e9db4c92e060bce525f91b9cc0d43b453d26057435d -dist/2025-10-28/rustc-nightly-i686-pc-windows-msvc.tar.xz=86a8580a180de9224c176beb1ada2c69acc37fc73ae0e7c7780bbbded842365c -dist/2025-10-28/rustc-nightly-i686-unknown-linux-gnu.tar.gz=0d29e999ccbc46ff6b0c50a5648e0c5c8f767daa9a0d1fc86dff30c6e0078dd5 -dist/2025-10-28/rustc-nightly-i686-unknown-linux-gnu.tar.xz=bcafb54ca3f587d3cc9302c057da2fbdb4531e2279ef462fc8682e82e1046561 -dist/2025-10-28/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=0a5bfd49a7a2fb98fe06815a2a50d9dc859722da3cc107928e36596c7b8c7f8e -dist/2025-10-28/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=b8ec7898e087577b78ef1b716f8935c7023d740b389234f38075a09b2c7b494a -dist/2025-10-28/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=5cab6709c372feed484b5148ec642cf9767e7fe051146023459467012f2e0b64 -dist/2025-10-28/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=e42a3c007bdf7e8179c597daffc61d7a6bd8eac782b8d81d0b883267bc226f86 -dist/2025-10-28/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=a7cb220770ebd482ff9737d787d04e2e1274c46b7da0809041d06712e27f69ae -dist/2025-10-28/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=088b1d0898bc5b5d83d0fe20edfdadc2d1c0865c39108d11a5d078074aa37a1f -dist/2025-10-28/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=90a3b28ca667187fb18eee8b87f5aebdb2c2e457acbe5b7b088d9b9a39314a1a -dist/2025-10-28/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=4eb8f1d20b2eeb85a2b78d3e28a1d665e1171e1271540bdd8453833818d53c30 -dist/2025-10-28/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=e4fc106d7d4e098912b4dc0ac0211769ecc1f01731e118bf6c0bca33c7ceb9f5 -dist/2025-10-28/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=74bf23136731240e8dac7497d8b1a244fc35cd529d12f77fff308099354f3aef -dist/2025-10-28/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=85ada50366246530a0dcbd462aef31a6edac600d22074d97bfc07321569eafdf -dist/2025-10-28/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=f0cb51df2f6639fc65091608d569b9ac0730f5a8d88e27079d87bc8a8834b1e4 -dist/2025-10-28/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=c37432d8d8db7aaad9132e1301025dd5bf3671bad0ac1fea0f04e9aae238cae3 -dist/2025-10-28/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=57f72896f0309149a4b376a21d56ea28e65316db08065bfe32cdbd750bbc9657 -dist/2025-10-28/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=170776eefa09f01859af0b3694c013ebfab04e9fcf8fb44233593ef4a763bd38 -dist/2025-10-28/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=29335ffe7d88b758ec1a7a067056e35fe8f24430e8d899df3256b4e2d19ac16e -dist/2025-10-28/rustc-nightly-sparcv9-sun-solaris.tar.gz=14b5cfe710c92e8691aaad99de891695ef025638eca065587107c075a31215bf -dist/2025-10-28/rustc-nightly-sparcv9-sun-solaris.tar.xz=d21bb41b4abdaededefd199192bc257424295ec74d482693d032ca67f02dee15 -dist/2025-10-28/rustc-nightly-x86_64-apple-darwin.tar.gz=09c7d0777ea308ad552ea1e958f5c65fa3380c9cb93efa1e6edec3a29fc30b5c -dist/2025-10-28/rustc-nightly-x86_64-apple-darwin.tar.xz=923ef47f5bd9608d277b6636b8c798c5b2760460264fa6f0c0836f317746a89c -dist/2025-10-28/rustc-nightly-x86_64-pc-solaris.tar.gz=805643ab958df449ffd8dd5557e43c5e7060a10a3deab2238096b721ab451f08 -dist/2025-10-28/rustc-nightly-x86_64-pc-solaris.tar.xz=f2fb0c0643808bd9f483bf9bf66ead4444285f2e50bc1264b4861deddfaa9c62 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=05b7ee4041b2cdcee1739da7a22e4083acc24c043d11cb3f61d0c22237a9f42a -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=2f3b04d56dd929ab5997711bc52395fa700247ff38b9362cda375b685c740337 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-gnullvm.tar.gz=52575038868d91349b40434ec8faf9836a0aa0a4f77c2decc634a9ba02796c07 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-gnullvm.tar.xz=d2d1f2a0d26cc3dc86d88ae46a9dcaa5f0ce694ebac3f46b7466fb058a1a76e5 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=5469701cbe03939a82ce5ec50dc166342ab968d2f96cb372dee8f29dfd6e4362 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=e6d18f7b7fa3a3613f1aa129f4a14820d4fa1977550689cd99b7dad12054edab -dist/2025-10-28/rustc-nightly-x86_64-unknown-freebsd.tar.gz=e2a5ff9df2b07f8c939fdb885da717faf19a5b3e63ab780962dc288f832cba6f -dist/2025-10-28/rustc-nightly-x86_64-unknown-freebsd.tar.xz=b577558a8f1b42d6bbbc80804e3b72835a85979c98659696db32832595283d04 -dist/2025-10-28/rustc-nightly-x86_64-unknown-illumos.tar.gz=5535a693d5b8edf3fae7e1da97c20596a1f60135fefe22835109ed3648765a16 -dist/2025-10-28/rustc-nightly-x86_64-unknown-illumos.tar.xz=bfc15f0678099ea110135d4e7bcb1b9a545f041e5810f6528d49e0b5451a29bb -dist/2025-10-28/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=877bf56730551f851e2ce5279c105f231906959bcf904aa2fc29acaba5160cc5 -dist/2025-10-28/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=911bf7891d7687675f9200d3bd51946e21df3762b5320b7d31bd49d58526a8a7 -dist/2025-10-28/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=c0c26704d16d6612d0d99ad078bbcb2ac0ed86419a0404a9e08739990acc5ad9 -dist/2025-10-28/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=677f5c6126262b64126b5fc7c3c527cbc9e8ba62aaf4376c924149b6d05e16db -dist/2025-10-28/rustc-nightly-x86_64-unknown-netbsd.tar.gz=84c82523969ff1b987a09d5f7401e9a773b3110f51f00d708a4791ef6615272b -dist/2025-10-28/rustc-nightly-x86_64-unknown-netbsd.tar.xz=680eb70467d5695e986b013b3d16dbd0c0b0b7bc85cf8df4a3392c100f97eff9 -dist/2025-10-28/rust-nightly-aarch64-pc-windows-msvc.msi=a8f7ef71113d5ca8094d9433f23d5bab8ae910803e0cc23110d4fd0e04816bf3 -dist/2025-10-28/rust-nightly-i686-pc-windows-gnu.msi=6c4c49c2c2303f94a39d5c598c4f75b9d2c894b1c30aa6b49c8ab7ca674c8ca9 -dist/2025-10-28/rust-nightly-i686-pc-windows-msvc.msi=f7c80d8c614f5b53a596bfd8a263fc0e680b554ec47630e36e23354afb7fd426 -dist/2025-10-28/rust-nightly-x86_64-pc-windows-gnu.msi=2f830bf3391a7da78de14ba4ffd82de8a49652262fcc7a3ae377a3703fe7ab93 -dist/2025-10-28/rust-nightly-x86_64-pc-windows-msvc.msi=c9b61b50bace832fc504853a5ea5dacd869909946c04d1d9c95b15385e98fd47 -dist/2025-10-28/rust-nightly-aarch64-apple-darwin.pkg=8d7cb75018220eac497ffa180c94b210e2e53e8e8c36ab8a39d6c4c6234fe72b -dist/2025-10-28/rust-nightly-x86_64-apple-darwin.pkg=82e9979fe0cdbac0e008f46cd2d7da70e9fa2caa0d4f1df56654cf57114c993a -dist/2025-10-28/rustc-nightly-src.tar.gz=f6da3a086dd47e5ace7eec9f03879d4c3082503912fe631e54e38168dac60f22 -dist/2025-10-28/rustc-nightly-src.tar.xz=523289ae9e6a87f076decc1beb412897184e728302826882bf53dfde4df4ce15 +dist/2025-12-09/rustc-beta-aarch64-apple-darwin.tar.gz=a91d96a219d1c3a195b064ea786a693ddf3987afa20b4117352526e04d27a76e +dist/2025-12-09/rustc-beta-aarch64-apple-darwin.tar.xz=40e55dd62ba38d106cf6a53044d38ddeb41721a4f301a2dc54d8cc64b31e3ba7 +dist/2025-12-09/rustc-beta-aarch64-pc-windows-gnullvm.tar.gz=4747203b5f3387abea65d9076eb790c2d1cde3bcf1e058bf072149c4c08768be +dist/2025-12-09/rustc-beta-aarch64-pc-windows-gnullvm.tar.xz=07889f4d4a975817f64d3ca7fc3625159edcd58ed0f2121edc4be6c781318c8a +dist/2025-12-09/rustc-beta-aarch64-pc-windows-msvc.tar.gz=7c4a21a4a66b1a652a9f2ab7026f98d00b8bb792e9d35e43acbbb9e721e2fc1c +dist/2025-12-09/rustc-beta-aarch64-pc-windows-msvc.tar.xz=744d6df884551fc14c1284390378b6f133c8b971055d30f86c0f42d6864e958f +dist/2025-12-09/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=b13dcb3bb092ad1cbca6ff91e9ca3c92eb363fdecc6b9c16175b07ce32435c6c +dist/2025-12-09/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=36e6ca5ca171c09b3c5a4c36d877163674b9a4bb5562a1dc9a66c5af39d3f37f +dist/2025-12-09/rustc-beta-aarch64-unknown-linux-musl.tar.gz=047b25aca0b1d4f4d630db240f12c96433c25ee5d0a149499a715df120c73f10 +dist/2025-12-09/rustc-beta-aarch64-unknown-linux-musl.tar.xz=6a0332f6a824e8f25942178fb1eb562297a7dc31205d17b7dd11a2d9c64cc3f1 +dist/2025-12-09/rustc-beta-aarch64-unknown-linux-ohos.tar.gz=4f80108f65a8a05067972263acfc1756e06283ebb0bdac86974c96298dfb8ce6 +dist/2025-12-09/rustc-beta-aarch64-unknown-linux-ohos.tar.xz=71ac8ab1ef7624171a2d50c00577fa7a734146099e7d9e8bac10a784831a877d +dist/2025-12-09/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=4beca02231720f3de8c3f11d97a69962c3049c2812d98c043df03e50d97cfb4d +dist/2025-12-09/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=b1edced09ff9ea6a94cfd029578dc0b04e75713b25b7ba211907d398e4be4857 +dist/2025-12-09/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=bdeb895d3d69b7405c773af4c9e941e4c97d2e8916c5e381f2bfb9ee1e3d1533 +dist/2025-12-09/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=53f9efbc64431efed920f9f0ee5ced9ad18589237fe080983730d6536c0e94b9 +dist/2025-12-09/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=bd65ec758f8a0bfade3daa30a3478424e0e59d2f18890545453dae1cd0410107 +dist/2025-12-09/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=1180f684a647091ba857bf74a921933711f5dd3970995860ea7c12ecb4e25660 +dist/2025-12-09/rustc-beta-i686-pc-windows-gnu.tar.gz=386934445fce601578146f052dc042cf23292f6a9dbe22f1333ae93cf0872820 +dist/2025-12-09/rustc-beta-i686-pc-windows-gnu.tar.xz=64731c7e3c61ed0791c6a985d61207e3d687555f6d95abff73e9c051246c65bc +dist/2025-12-09/rustc-beta-i686-pc-windows-msvc.tar.gz=8b5df3cc0e53b36b32317461fe89ee7afc8333ee7e11184dc09ba2b96405e6ed +dist/2025-12-09/rustc-beta-i686-pc-windows-msvc.tar.xz=11273df779687a10be4c99e9175d8d4396580c1439d7a8ce27b6b4a674b3c401 +dist/2025-12-09/rustc-beta-i686-unknown-linux-gnu.tar.gz=e31368fbc85656ab864046539978da6b6635a6ee2cc15c48c617b988b84c0d8b +dist/2025-12-09/rustc-beta-i686-unknown-linux-gnu.tar.xz=de94f1f65cd3afc9c7caf554a50e3a1c7e8d730413c3dd4d9916618e7aabb3af +dist/2025-12-09/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=af6be7ca8e4b43b87a754bc63be169b392e4fdbccb9217fe19960bdd87278703 +dist/2025-12-09/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=caa7e16901ff848b2083ccf5b684c9e1975da3dad46bbbd72b127c9420508f57 +dist/2025-12-09/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=8652e6f5e68146d3483dd7baa8e215b7ec003a626547cf087a541c78ed98fd67 +dist/2025-12-09/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=d3853bfd0bfdbe96996764f27451154c0f0b4b135728c25a2be48b7ce069440d +dist/2025-12-09/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=828e8cc488d70fc966bcc1196b019b74a7610cbc4b0947b04eea684da8e77f35 +dist/2025-12-09/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=47bdc9313660ca1a29525155f3a7773ffa4021219dac5cfd309f5ec692ab1821 +dist/2025-12-09/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=f7b8dc496326a38d47f9769631b9893c803acb21cf7021e7ee200e81bffd0f2c +dist/2025-12-09/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=1d4ec35a9ee7cad99458db77f8787dee2c90556e56a21c8681984a09798f1e7f +dist/2025-12-09/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=8dad2a1f7f9667270fb7e8d0917c77b251f2079251e46bf012d640754a46e0a6 +dist/2025-12-09/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=259c2b9add30c03a6f91c4aaebfe4f052f0342bcc32df79af1121316ee5aafc8 +dist/2025-12-09/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=01b1b5bc19b82caa031c0ff2fe4d9d4ef27aa17a918ea15853c3680f3d1eea8a +dist/2025-12-09/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=4a410356d19e7e5b46a276c0ed015df3afa2af8aa5837feba11149212a4b4208 +dist/2025-12-09/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=a0530a7ca051e0fd0ae303f479f0962e0d3bd0065be3cc42bf29272322ce4893 +dist/2025-12-09/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=1e1ab9ce2619c6430e785c00cccf689fde5c20b4b81dd6281deba15615cdf9fe +dist/2025-12-09/rustc-beta-s390x-unknown-linux-gnu.tar.gz=bc0e4f9ba5f99fc9b849e95901140957d58cda12e980edf84a6a05544a32c80b +dist/2025-12-09/rustc-beta-s390x-unknown-linux-gnu.tar.xz=9ba83613dab2ffa00b581f5927abfb8398e3854fe21d2b685830ff57f609324f +dist/2025-12-09/rustc-beta-sparcv9-sun-solaris.tar.gz=8ed8158201b4f55d68bb5e89bcea83763803c5b592864495c5b614bea1cf717a +dist/2025-12-09/rustc-beta-sparcv9-sun-solaris.tar.xz=51e54052960f878e4e8d028917db9b02c0650350d50e537cd873c0c812a85957 +dist/2025-12-09/rustc-beta-x86_64-apple-darwin.tar.gz=ff615c109d69ff4beb505968210112b1307893824f410b3b461b9c3236b082b3 +dist/2025-12-09/rustc-beta-x86_64-apple-darwin.tar.xz=0a60addd526bd5964ae9710692a472edf6b9af88cbe6e671764dcd0fa7a785db +dist/2025-12-09/rustc-beta-x86_64-pc-solaris.tar.gz=e2c75e77f4f2582b2d3e7336daae2dd06a8d3a14de2ca954d8b65dc809cd774b +dist/2025-12-09/rustc-beta-x86_64-pc-solaris.tar.xz=2264bc2facde878befdddc8c47c7eb795ce5b2777a1d8fa48cbf5bb81e214475 +dist/2025-12-09/rustc-beta-x86_64-pc-windows-gnu.tar.gz=7e4a2a3cdfc7aa744b90a09dd6c0a98164898a7ff04c8a15ec61b91fe9efdcd7 +dist/2025-12-09/rustc-beta-x86_64-pc-windows-gnu.tar.xz=50b143dae27df2e923bf0d498e6ef155b95a89ad1548b6bb859e1c95fe1b9a92 +dist/2025-12-09/rustc-beta-x86_64-pc-windows-gnullvm.tar.gz=6e71c2b948b20319ef43242af469e241ce9567586fd6d872fd85751c8db1ca16 +dist/2025-12-09/rustc-beta-x86_64-pc-windows-gnullvm.tar.xz=a9b72e9897a93981b9c9f166f1f4072560c1eb4f9e0f5a5a6c2eb0ab742bd020 +dist/2025-12-09/rustc-beta-x86_64-pc-windows-msvc.tar.gz=e975eed4f35220c1cd0b7e19c2ad48ce9f57cb2d07b90a2331a16e2502d1289e +dist/2025-12-09/rustc-beta-x86_64-pc-windows-msvc.tar.xz=11a8f8d49f946bf4e1ebcf9e21ccc8d75de627c84776aba1041082f676cb029c +dist/2025-12-09/rustc-beta-x86_64-unknown-freebsd.tar.gz=94c7e7b64d00c24ffe18cd5b1c96ad9d55019acc98e9ad23d798974e7936780c +dist/2025-12-09/rustc-beta-x86_64-unknown-freebsd.tar.xz=ef33215967034bce1217f5587d9454dba543260ff38c2c80f8ecb1292f9c063b +dist/2025-12-09/rustc-beta-x86_64-unknown-illumos.tar.gz=45e2f150ac9a4aee63437d7621b5ad8782c4248f8dda30062b1a001a9f9c7a32 +dist/2025-12-09/rustc-beta-x86_64-unknown-illumos.tar.xz=e0196e2bccbad5d1e520f0e711a8d79ebc6296f8946421fc80c7c1b51115e9bd +dist/2025-12-09/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=2d14a960636bae79f0ace6ae5b91ba2a07f8897512a5e7ce9b72601d4c0aabc6 +dist/2025-12-09/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=d80990444597aeef8a956bb71ed468d874f1b47316e51afafe509442803ebae4 +dist/2025-12-09/rustc-beta-x86_64-unknown-linux-musl.tar.gz=e6bcc1ad145b9154560ef41d0e664dbf133980226983c334f5c3ffe1350892ae +dist/2025-12-09/rustc-beta-x86_64-unknown-linux-musl.tar.xz=1dbe4c0222aee37c45b8bb53dd563a56c4f7f198e97b25e22ea5590bb4bc47c2 +dist/2025-12-09/rustc-beta-x86_64-unknown-netbsd.tar.gz=618cbe2bd888669e7b0ee73b127f4a68bc1a30976ae41cfebbe806be794eb143 +dist/2025-12-09/rustc-beta-x86_64-unknown-netbsd.tar.xz=ecfde3d55928deeeabe49e31a5263ade8119897f9f82aafe594406d5ec2fc1a9 +dist/2025-12-09/rust-std-beta-aarch64-apple-darwin.tar.gz=71485c941dacf6a9f2acebfb7506eca5802aba23fc941208d1563fd0a6b74876 +dist/2025-12-09/rust-std-beta-aarch64-apple-darwin.tar.xz=2bec6cbb4c6249fa5a5384ef67dfed9c5b2149589efb086f18b675eca472c255 +dist/2025-12-09/rust-std-beta-aarch64-apple-ios.tar.gz=62701f83e7d374f318756720f6a7ca14a9dd94935df92bb635da718a724e91a9 +dist/2025-12-09/rust-std-beta-aarch64-apple-ios.tar.xz=b596278416039b70cdca751482255b16708bde9ad008b08a49362456231904d6 +dist/2025-12-09/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=38bea00e6057cd52d98b7a707f36d091877b8a8dc38c4aa3e8e08a57e95caa75 +dist/2025-12-09/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=45a01da54adc3c02e0e5837ca30a1e5d2f284958d6622d048c2b76442026ceae +dist/2025-12-09/rust-std-beta-aarch64-apple-ios-sim.tar.gz=40b32df24c2b916d829868fcf7694c9cc00a5853edf8addf586ed346ee29e2bc +dist/2025-12-09/rust-std-beta-aarch64-apple-ios-sim.tar.xz=7d9683d5614f0fa59641e299d169275f7e26d1ab8e4c1510216eb15307e6c63f +dist/2025-12-09/rust-std-beta-aarch64-linux-android.tar.gz=97ddf7807abbd7494c9c0053a6d1b6ef9b5a02329a572eb6ac56c58843d6e558 +dist/2025-12-09/rust-std-beta-aarch64-linux-android.tar.xz=b971a8c8a44a3fa048752e23232335e7896e3c4ef2cdf8636a3d3504e2a8ddaf +dist/2025-12-09/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=d3acb91f5bb97c0272c2d61b2abc6ba0a717808c89b201273f4b8a6a9aca08ff +dist/2025-12-09/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=3cc8c607b8289748cec9b3470ca37fab63be4f5a48cf3fb3dd48c5e7983b3682 +dist/2025-12-09/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=d65621d42ac27885ab47ae95cc5feae4aa6ededc61b7d3206f9ddf930da08d41 +dist/2025-12-09/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=8f96ad5facfb3f4b03bb84fb49b014505795764dbb49a66497c753bdbcea6fa1 +dist/2025-12-09/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=e5ae9120a770ee03254ea202031d11cc5d0f06260c3818334d4afd586ba619a0 +dist/2025-12-09/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=1fb8e830cf4dfa2df68b3d730cb709e4225fe13002e4bf768d875be7c330b892 +dist/2025-12-09/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=21d61a5e4e7a84d87b8d371900300b0a9bc4afbfd1b8fc6e6500be338a8f40cf +dist/2025-12-09/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=82783445c68a553bfe1cdb25161073c03deb2a9733e5811f29ff03d86879df56 +dist/2025-12-09/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=69855bba4ddd7e77fadf35cb2fb3e4c6ae9684a3ed68c7b6a949d03b3a2ba2dd +dist/2025-12-09/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=37ccb03697edc787ab7d07e7e77ee328b8dcae8ce5d9d328dcda28489bb4bf6e +dist/2025-12-09/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=81f3a854fb1af8271abbf4332993b755d3746ad3878066544a0187f80d0d2ab3 +dist/2025-12-09/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=054666e60b05826046760bce5a1f6b6aa8991205c912cf4faa6630e98808e3a7 +dist/2025-12-09/rust-std-beta-aarch64-unknown-none.tar.gz=e382fedc0bedfaea97ab7d8e2228fe3d437143812fffff224ae14fc434059157 +dist/2025-12-09/rust-std-beta-aarch64-unknown-none.tar.xz=72aec0eb4181535516597e859fd8f10b2216cedec0659b6d322ee353226e5623 +dist/2025-12-09/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=2e4e1fb234fe8734d884bc180790632be460cedb35fefabf453be6efaca39aff +dist/2025-12-09/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=f8aa1f77cbcb85def86b725263a70f4d714cbf8c838a563a4fc272aacc2f3ba6 +dist/2025-12-09/rust-std-beta-aarch64-unknown-uefi.tar.gz=65ff64a57050f3be4b64f49c630aca871b448db30ffad76e601cec5306cbef8f +dist/2025-12-09/rust-std-beta-aarch64-unknown-uefi.tar.xz=261f0af0b1b991f59235b0dc05745b51641d649b1b59af7f5f6469ba0a273b0e +dist/2025-12-09/rust-std-beta-arm-linux-androideabi.tar.gz=c8b5c64541286f0b0a9675083bf2c37fdd39577b362efac149cd261bc19fbdc6 +dist/2025-12-09/rust-std-beta-arm-linux-androideabi.tar.xz=4d43c454ea36de0dc391de15d6cc54f0e24982d5b6f6b0574775b68317003c03 +dist/2025-12-09/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=acdb7e966699acafa86b4873dfda34724fb53f2688ff3a76edf4c0f638443648 +dist/2025-12-09/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=fa2d71b3d23572172fcede867b6ffe95135576c696ad2b7f7642bc97d9cb59f7 +dist/2025-12-09/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=c07bb539390c033df181ece6cd12ff3e9495719d7ea24e8410815436c8d43d4b +dist/2025-12-09/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=d1bfaa712e3687f1a24e0733666e6f78593b2ec66e7edd4a90183e15afacc38f +dist/2025-12-09/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=19fc80ca30e77eace2e2c0d37ebe93efe5423ab08852832c18e5be5f9a49b994 +dist/2025-12-09/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=046322601ea0962b6ca9587731a1d3270fd229d18161f02c056bfe882c77481d +dist/2025-12-09/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=0689439e1518597b6ebb5e1c0e4bcb61a741c0e4f540c03fdc92a5abdb177608 +dist/2025-12-09/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=00c3dbc2f78f4e372557b59004139708347c543c61c485d8ef6f673840482b01 +dist/2025-12-09/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=597fb79132dcc86f20b52a7e3694e2aca4e0b1310f2936ec1eda102f0dbff0b4 +dist/2025-12-09/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=a2e4f7a5026ebd05fed1aa1a925347db043bb03afe5e16cac09cbca6c6ca88e0 +dist/2025-12-09/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=476a217d51c05c3b192bf668db05270e2ad48004635a29194eeb1268c6cf86fe +dist/2025-12-09/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=12a59c08179d0bdbf6811b90aee922b5744a1cc8110ef04db71eb8315e950208 +dist/2025-12-09/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=0acdd625672417f897e3381383e2e7982d4b1d29ac418bd4fd864a969532693f +dist/2025-12-09/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=515626a896f9d9bc1fcc6ec33adda205b609fe6a41c1462fec0e74bf3c50ff75 +dist/2025-12-09/rust-std-beta-armv7-linux-androideabi.tar.gz=167e74b6f5cb8283ecb53e596c1728d8f91846cbf1b30c7d640dee9b20d433b3 +dist/2025-12-09/rust-std-beta-armv7-linux-androideabi.tar.xz=c2e69b04d4cd86a83aa9b9c3ec37adf3cda2d06c1a4ec977068d216a48681d2a +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=91866669e8946c1949aa48781df52854b5fe537026f9a93c9adf67fd2189ae19 +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=95633a5ba9bc81093b56f5c318d97c50a27f0d553b7e878f039a3a12df4c7e4a +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=c9746beaf4896937c708143270278c0e6b4b40d7155cf5746443f0f03fee705f +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=defaafa063c1c57bb5f9ff0320a1f26e4dc7bc626ac31e2d028ef16c81fa3301 +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=630af0d305dc441dfa2c04ede30f5d11d154ee04be72f6507f321123ed6bc741 +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=b875e2f68624a8149115a1e86b66a279931305816efce81b005ef0479c898528 +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=6f751bf3da85ab19ace00fdac387a60ee6f2ce4b55f5b52efab2a7a7e0d679a7 +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=b10cf3d867407de5c93c2bd65c616d0d5dcba4997c25ad396b5814af86f09d73 +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=98a4971ed72aad245ca31a7409ec0e33b4304ed3fe470df12b35f83642022883 +dist/2025-12-09/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=f89afd1dab7a482e0d1984fe8852b1a78b2e708d348ddce3978687190e205e84 +dist/2025-12-09/rust-std-beta-armv7a-none-eabi.tar.gz=5801642b53256e015e216b98e1791d9d286e8da496d8a3d0b006f4328b73c814 +dist/2025-12-09/rust-std-beta-armv7a-none-eabi.tar.xz=eee727983344340eab73c430a9ca66763a743c59c2e34b84d2937979e9c02801 +dist/2025-12-09/rust-std-beta-armv7a-none-eabihf.tar.gz=b934350dc0ef04038d0c4cf7924f0d573f559e5925d476cee743a9a74301e953 +dist/2025-12-09/rust-std-beta-armv7a-none-eabihf.tar.xz=46fb1485ebdb726e33e4e2cdeb260578a19ade553caba9190beb3a1ca9d190fb +dist/2025-12-09/rust-std-beta-armv7r-none-eabi.tar.gz=5957cf630fbfb7e3758e151607f2b0d87736f90255822ddd37d8761582f28a58 +dist/2025-12-09/rust-std-beta-armv7r-none-eabi.tar.xz=63b92037e86a526c734461c02d8450c83136b05fef17e8d80e998d513bba9caa +dist/2025-12-09/rust-std-beta-armv7r-none-eabihf.tar.gz=35360bb54ca208dc4b819ec1151d99daf5a2bc7c7f31b81b24f06df1e994b644 +dist/2025-12-09/rust-std-beta-armv7r-none-eabihf.tar.xz=3bb49e862d38d34b5ac52eac27d65eb0c2913cc4d486c83004c485c1a93f36b4 +dist/2025-12-09/rust-std-beta-armv8r-none-eabihf.tar.gz=77c0a3b6a3d57c40012a1bc1818fafaf8b3591c6ac451ea4a05cc599da96e8b6 +dist/2025-12-09/rust-std-beta-armv8r-none-eabihf.tar.xz=add26a701346661f3b16d4ba1db9c8ec795c58427b5a8d1081c7a55faf3813a2 +dist/2025-12-09/rust-std-beta-i586-unknown-linux-gnu.tar.gz=525031f51d2c92301692c0798b48534d2b845eba44e01f7f8e7e7ce4fb6f9379 +dist/2025-12-09/rust-std-beta-i586-unknown-linux-gnu.tar.xz=a882f765539da05de5f8782a6bd6cccc34c5179b6b4ae845eb27a8e9a354fc82 +dist/2025-12-09/rust-std-beta-i586-unknown-linux-musl.tar.gz=0ba2fbbb2cb8aba07122bdeb8ed94e061b256d747c5ad679ddad701601d51211 +dist/2025-12-09/rust-std-beta-i586-unknown-linux-musl.tar.xz=5554b861765e43f530b23595622f399bc83ad04900123f366aeedad71c2e957d +dist/2025-12-09/rust-std-beta-i686-linux-android.tar.gz=039a001036cca4cd22fb42cc60777fac2e2cc9553d0987096c285efc87c53a3f +dist/2025-12-09/rust-std-beta-i686-linux-android.tar.xz=b9ce40f48e695b60a98debff5de341a7303bb8dead8d4f33ca9d9dd0cd5d692a +dist/2025-12-09/rust-std-beta-i686-pc-windows-gnu.tar.gz=34138dba519fe8d3c45326b22091e29d68c4df53c404f1ce90e8d50d9412b5c8 +dist/2025-12-09/rust-std-beta-i686-pc-windows-gnu.tar.xz=ea604b3b0204605f8973c7b257f95c0095a549a221b5166a4fab36fde21fb4ed +dist/2025-12-09/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=6ff8d19ce86de968e10e8449e87528f81979e3470e5ebdbf7c1a089f4896b01b +dist/2025-12-09/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=1659e5a260362e596f26bc55807e8ed407c2603203ddb8201bb6993873fb1cbb +dist/2025-12-09/rust-std-beta-i686-pc-windows-msvc.tar.gz=e2afe62459e655796c3a1c61d6342dbb43eec597a322be633bf4f6ebb3e60faf +dist/2025-12-09/rust-std-beta-i686-pc-windows-msvc.tar.xz=c6e8d9df8fc459d10e7382d4d324604ffbe0f4f18c595684e38c83df149eacb2 +dist/2025-12-09/rust-std-beta-i686-unknown-freebsd.tar.gz=12c3d52726261b7c714e69773d5eba430683f1b5daa5ebbfa728367f2073a9e3 +dist/2025-12-09/rust-std-beta-i686-unknown-freebsd.tar.xz=6e62b81aa735b8f99668fa15741a9b20201e51abc976143b894d867160c2b9a4 +dist/2025-12-09/rust-std-beta-i686-unknown-linux-gnu.tar.gz=f55362021acbf7ce28291f535210d21807caa63811aaa2206d5ceff0e0cb789e +dist/2025-12-09/rust-std-beta-i686-unknown-linux-gnu.tar.xz=c1c9b90c8586805b02d74465d5293ec3d286a07e646e51cfb91505a7d407cf90 +dist/2025-12-09/rust-std-beta-i686-unknown-linux-musl.tar.gz=5df73e6eb6ac56c1866d123852864ae5946be38e97131e0fc23cfbc0ca807a9e +dist/2025-12-09/rust-std-beta-i686-unknown-linux-musl.tar.xz=cb7a6d7060cc9fbc01e54546377d3ee5076ba36b46203acb0aa44fa75ea10c15 +dist/2025-12-09/rust-std-beta-i686-unknown-uefi.tar.gz=3616a3ed2eb921f2075b53c1b04134b1668e4b6d692d50c66ce2d37e7b96740b +dist/2025-12-09/rust-std-beta-i686-unknown-uefi.tar.xz=ac64b54721d8f6b218a9f8a50197b4a8d62d48bfbcd90c4bfca75117f2d359ce +dist/2025-12-09/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=219729c628f9729d415680c688704d7561e1550b8ecd1d508b103c204ce47f35 +dist/2025-12-09/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=73ecff3074ebc9abe9efec380c75c8c717df50a08b339dd0aece8538b58daa04 +dist/2025-12-09/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=481877f357877619d950d0826197843e47204d3b57aee11b7880ce4559da5dba +dist/2025-12-09/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=60674e9092592803e2bbb2a36d8793e3c88f56187f43f289d5a63ddb10cad23c +dist/2025-12-09/rust-std-beta-loongarch64-unknown-none.tar.gz=2651b85be9f606f7d769433f716e482921cbfd39c3318fcedc0a42b35eea5bd4 +dist/2025-12-09/rust-std-beta-loongarch64-unknown-none.tar.xz=b304b09ff87242b78ea524c3a3c8dcf5d30d4889f7d103318df9316bc65d051c +dist/2025-12-09/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=6a1735d9a1d6fed323a659ee39a88dcdcce72385b9b306135b7ec24c3e3f6cd0 +dist/2025-12-09/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=d0b1ec1cb5a97e60b3a805f60b75d06e8572d9f513310da72e7029e23449d457 +dist/2025-12-09/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=bcf45185cb5475a179c4402f787fd6780545512f3afa33dca71c6862e83240c3 +dist/2025-12-09/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=aee86a13753c9be073a18dce28384921f2a5519d272802791e1d5b96ed00cd2c +dist/2025-12-09/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=2da51021239ce4c3dcc36c02107f4abc70df7b157784e7c9dbb4aa9d83014e49 +dist/2025-12-09/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=3c54a7b9cf2318589f9d52109b0083df2eb7193f2c4d45d166c1912353ac0812 +dist/2025-12-09/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=49107f7d7290c8779161095c2f7218e929cf4498b04cb8717b2e04ef00d04139 +dist/2025-12-09/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=26539ea11b3838de5c530c0462c38f31aa5ae889abd65e5eb18a8817353207e0 +dist/2025-12-09/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=198b5e4b994c18e096a0c24a1ede2ef180183780f1456d3af3ef46d516fface0 +dist/2025-12-09/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=9c31f5d881ea898da452d628bc0a1e2e27434e8c6b3f5561e0e326024dd91d9a +dist/2025-12-09/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=e796cbfca385de190e7b56fe4c5e8b76a22410fc1e303c55dd22db03df5eb15e +dist/2025-12-09/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=056cbacb291248e2ff71e6d051119bc3b6f4157cb0e9349b4a69bc71165ee978 +dist/2025-12-09/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=f28ca9d74bbf52ab554f83f70e42e55f050610a49f1c57230ca65fa7088b1b48 +dist/2025-12-09/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=3a5637edd1179cf15143250ee5e152a1e21c0eb0aa725f05f4a0a7d902b04ddf +dist/2025-12-09/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=202251567a7cac42470061f4fbfe7e465d94838b492654256992960ba746b27e +dist/2025-12-09/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=faca8810a93a0c916f75643c60a6dfc873c4521647b4f2d3a288e510885f7e70 +dist/2025-12-09/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=226c5737b033bc3acec904593845f484d32451e2a1309250cfe6c1910013f9e7 +dist/2025-12-09/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=99f33be2da6e9da57ca13cc50cc2c27f769189cb0d28f8d4576c9d1cdd3784dd +dist/2025-12-09/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=8ff0b8eb19a4007dad61364ec7957d25fd7778c4c2801dc324ef0638cb874a81 +dist/2025-12-09/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=3f4d1f9cbd0db9de6cd0657bcd1844726dd268de71fba893194be76827a1c77d +dist/2025-12-09/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=f455e8855d37ccf35f86964d91a62ef3fd3ba167fd722e4ac5195b6516fa8c5c +dist/2025-12-09/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=e698357e974ba32256663c9c0c98209f5f7303f415acce2a6f821d5af4175a20 +dist/2025-12-09/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.gz=57af63ea6f6944a2f6a3311f2ccfbb1d77e2fcb1a8c7d2a3e0bc7db0f3c2b63f +dist/2025-12-09/rust-std-beta-riscv64a23-unknown-linux-gnu.tar.xz=e0779b0a0d2321967350831c1e32bb04abf555667c6666bf137f821bd1858792 +dist/2025-12-09/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=eb3a1f13c27c2d8e2f016385af36b4fe7ae6a879f3440328abcd85986287a190 +dist/2025-12-09/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=cc96484aed4fb6e0e6f5df5326ab9e6647e3d2367752d25f5717f007fcbba6a1 +dist/2025-12-09/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=ef8c620a7bd4aae0db5b4b6b97ccb03cb818362e782c845f191f6049e74fa222 +dist/2025-12-09/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=ff3405403beb6d794e0f7866c15664a8a8b927c924f99af3f03dbd2d7449eed9 +dist/2025-12-09/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=dcd2e20de8a9064e569f59092b81385fab67456ef86d5e4b25ee39a6fcdf52d1 +dist/2025-12-09/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=39f8802cc4106bfa67b6a0cad88534af350619d66718458dbc3912b0ec12f369 +dist/2025-12-09/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=a7453854d101abc9cb8ee0075c3575eabda972911def34919c5437be79326b32 +dist/2025-12-09/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=d00175adb49aabe0d6a76592df30558ac745f62fa2e9a62887141a2fbc7304f4 +dist/2025-12-09/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=1725461c9399c95aab95c7963d1f351c7b0d487a96a1d60043b3fd223cfa550c +dist/2025-12-09/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=5157be3919659a14beec82ab274b9fefcea8d7eb56d35de2c7278e21cf4e10f5 +dist/2025-12-09/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=5380c9bac880edaaf16de8e5fdfdd8deb2b645e4933c18b4928c96755ddbd604 +dist/2025-12-09/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=0700f10b4c8dce6bf86df94fa7413c95596aab6b70ca89437b226b33a1b5cf22 +dist/2025-12-09/rust-std-beta-sparcv9-sun-solaris.tar.gz=0b3e6a7b49dba2ed53a59ba733ac35094a06e2b1896b88442c72aba36f5c4038 +dist/2025-12-09/rust-std-beta-sparcv9-sun-solaris.tar.xz=18d6ca35ca291af5873d726db3494e3f64fd57f0ca7ed5a60003f7a769f29ce0 +dist/2025-12-09/rust-std-beta-thumbv6m-none-eabi.tar.gz=227f530497142eea0e3906b517c0d93bdba0a598ed469553b7928f094dbd5673 +dist/2025-12-09/rust-std-beta-thumbv6m-none-eabi.tar.xz=b68840c4e61887c593ced00dddb707f95538c72b70c1f5c729086f95604c3d89 +dist/2025-12-09/rust-std-beta-thumbv7em-none-eabi.tar.gz=ed01c5d7941e37e930e5689523a38aa1c8560b99ff90f20443a687e62cff4f51 +dist/2025-12-09/rust-std-beta-thumbv7em-none-eabi.tar.xz=c4170568ef0f5127c55544bd0ca32d5a0f8bd485218fad54129df1c9ca9d806d +dist/2025-12-09/rust-std-beta-thumbv7em-none-eabihf.tar.gz=1bab00737022c44c767ecce5e84f4f0d995ec0358ea50d813b8397e0a4ecb6a3 +dist/2025-12-09/rust-std-beta-thumbv7em-none-eabihf.tar.xz=ad3fd09b465f7a8420be64e43d7ca50f83aa0aaf38fcf30593be6a067593c438 +dist/2025-12-09/rust-std-beta-thumbv7m-none-eabi.tar.gz=fd5f2111dbaef4bee091d09df11f241e7d687fd4dbcbca87348302caef107cc5 +dist/2025-12-09/rust-std-beta-thumbv7m-none-eabi.tar.xz=ab409331b70f565143a34575745f8a25d2eceb1f878aab0c51453fd37cb3be33 +dist/2025-12-09/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=845ee997875c5a78f80d967894efaf3ebce89306756166513f2a291c9de9920e +dist/2025-12-09/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=d47c061768ed88a67755597a4c592213f9ab65c1899086d1f6932042d9c61cc3 +dist/2025-12-09/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=ebc31ccfd49f8583e3c8ea5c0dc0bd1574edbc486bf3b48f8941599ce37207a8 +dist/2025-12-09/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=79204e81dfd8a46122222ddaf24c9c0931876b8965b54523138764510d6516cf +dist/2025-12-09/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=8f55906a80c91d1e6836513826931185de79dd5c653b8bfeb1e48e37397face3 +dist/2025-12-09/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=2492a0f81dd79b0bf667ab068a36bd7223832ea91737c025d70da36677b74d22 +dist/2025-12-09/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=217d7f3d7b421cda819bd2723738caac2fac06c1b2e3aa3316e9a310f3ac913f +dist/2025-12-09/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=cca4be68e522ccfcd51b08d356d7a8e01d1a29b47a1f1ad224da08ca478fafb0 +dist/2025-12-09/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=8440d1030be1a5963bdb37c690c001046d369e43ce2fbba9a5823cacc17d16f2 +dist/2025-12-09/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=41836a990ab6fff97ca35e8b42e345179c475e87f684b166dfd1a40e65da773e +dist/2025-12-09/rust-std-beta-wasm32-unknown-emscripten.tar.gz=ec25fd98026b960e04ffb28b5a21bd9574dda359aa0f6f905f17cdcaa45c86d0 +dist/2025-12-09/rust-std-beta-wasm32-unknown-emscripten.tar.xz=ea4d554a967e035a5d03ab3098eed7d0d493ac46a75c5bdb4f8b294b98f6092c +dist/2025-12-09/rust-std-beta-wasm32-unknown-unknown.tar.gz=ecb7f66836e8745663c346d5de957fef96583e36053a94e3171813746edd79aa +dist/2025-12-09/rust-std-beta-wasm32-unknown-unknown.tar.xz=639c98dea1d0db49b827e96404d1126e604bcfa111ea4bf6519c67232f588600 +dist/2025-12-09/rust-std-beta-wasm32-wasip1.tar.gz=436dc6f6eb37ef3c956c8f020d5eecd51034e5cf4df5940b8295d6bfbe00202d +dist/2025-12-09/rust-std-beta-wasm32-wasip1.tar.xz=65e96ffd02b3735a2b84a00bc3872ea0f574096f56de6c77fb00b3e1d7a0e1fa +dist/2025-12-09/rust-std-beta-wasm32-wasip1-threads.tar.gz=71f8c5f5bdebd64ded342df43f98493d8ecd52434201cad2f6160e06eccf15fd +dist/2025-12-09/rust-std-beta-wasm32-wasip1-threads.tar.xz=81ccdab9aa05a1839fea2498ec7eac882b4c56ae3c573ca43132ac450c48738c +dist/2025-12-09/rust-std-beta-wasm32-wasip2.tar.gz=29b92754da126ee7e8bb1b71b7ee98255c52b53b842923ad29a97d4d54b06737 +dist/2025-12-09/rust-std-beta-wasm32-wasip2.tar.xz=c6fe278fbf360f03e5dc13a7e9de2b9eef4a8cb65e543e63c4e299df155a6018 +dist/2025-12-09/rust-std-beta-wasm32v1-none.tar.gz=a0645d157f59d1bf2e97f89e0453e13f02ec114ab28a07aa2d5746b15073f2e2 +dist/2025-12-09/rust-std-beta-wasm32v1-none.tar.xz=7120f968949be0ec4f89312135f36adda1b75db3d2070d6548a71324e57755b4 +dist/2025-12-09/rust-std-beta-x86_64-apple-darwin.tar.gz=07b68e518da8d290c26d8917f18f31c4c0b8c00f2aa83b4d70bd057e42264d1c +dist/2025-12-09/rust-std-beta-x86_64-apple-darwin.tar.xz=00785f17e51985fcf66185547c4996da73cfac13dfef10e3143491fa0a50bdf4 +dist/2025-12-09/rust-std-beta-x86_64-apple-ios.tar.gz=09aa4217e1fa44ca41f0711374b3dd194849f7eabe988275915c6a3cc9a5b34d +dist/2025-12-09/rust-std-beta-x86_64-apple-ios.tar.xz=cc7723d874929dc474643287905165b6ebc2d5b5d488b00a4239436f65bb0373 +dist/2025-12-09/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=7893661c4998ba8c53e25770d2ee63cc5c52583a7c3a65c8289697a9b3c734c5 +dist/2025-12-09/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=f07589b38e0f48d6d349c71b029347a006f52a9777e53779e933df296dd5fd41 +dist/2025-12-09/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=6bf1078f18c314bbda2e8e61c6d7bd821875d7cd6945fc00b25b7c1b951a734c +dist/2025-12-09/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=740bbd92e86c8c2809c8922e696c5cc8bce48454d40b486ded2f4b3922815b98 +dist/2025-12-09/rust-std-beta-x86_64-linux-android.tar.gz=752f3f17da55e9aa2fc810b01566828ca94cff8af422f8d85f82029c862f0a48 +dist/2025-12-09/rust-std-beta-x86_64-linux-android.tar.xz=c6f7d6d01c04a8370db9b28e0f1b7fcc20cde35dc1bcf668d667268129341f32 +dist/2025-12-09/rust-std-beta-x86_64-pc-solaris.tar.gz=96b14f03be37a8f94190fe9c78fe12e6423954499ddbe8f6a7375cd72ab345f2 +dist/2025-12-09/rust-std-beta-x86_64-pc-solaris.tar.xz=70d6a32f6b740bdb0aecdf7ef8811c94ec31905737ee144573e72a56fad93dba +dist/2025-12-09/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=6ccec82d1cc57a83afd857b7bfa02bfd0aba6908deaff8319322148cb11145a5 +dist/2025-12-09/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=932c90d8de3d8b1e1b705862e2d7570b5fa09c2fcc210aeb6d054c61980b61ca +dist/2025-12-09/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=454d9ebd2ae8baa0350d452023cef119dfc2a6ce2035d6caee2a6aaf51445e08 +dist/2025-12-09/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=b11035387f7bd20a12f249a3b527ef6e6bb21e55c8bfc17eb43fe8ed2aeb2d01 +dist/2025-12-09/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=5fa38e0b4568da60d8bacb77d667bca269a62a806245fa1b3c5154868ce8c0e9 +dist/2025-12-09/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=3afde6b9cadc0f0782b342cea124ec9b6196e85f99b317d5365bc8d6f0886f57 +dist/2025-12-09/rust-std-beta-x86_64-unknown-freebsd.tar.gz=6fce2224f59084e4e256a42437f49bbb01523827aad5b0c9406fd23c7117d62c +dist/2025-12-09/rust-std-beta-x86_64-unknown-freebsd.tar.xz=3ae24b5b8acc95e1a3659451bdf8c12c02a3c576b51311ca87636dee0fbe8162 +dist/2025-12-09/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=49f82f4a9b54861c304a89a32667d87ddaa5045920effd2f8a51d27495538f58 +dist/2025-12-09/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=7f5d52c6c6263a47a496a4d915be1b91418c3e16a06ccd0255d94577d71a1786 +dist/2025-12-09/rust-std-beta-x86_64-unknown-illumos.tar.gz=a1e12868fccdf88c54eced9793d8c4b292a4e2ab336b14ad3aef1529e6bbf427 +dist/2025-12-09/rust-std-beta-x86_64-unknown-illumos.tar.xz=2be5a86894132b2ddcde9127aca6ddd366e6a6b928d0bbefcfad155afd2c6a8f +dist/2025-12-09/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=552bcdb9041169ab431674f7536107af05ef4b9f85351757ec890c0779f5ef1d +dist/2025-12-09/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=393e345443c8c16e9b796ffd1d1867650702c75db3a1d541396ad7d035eba249 +dist/2025-12-09/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=91bf07d6ae7cc836aa4f5440a639a89cc0c706e11145a2dd9e1a46d87a85a8f3 +dist/2025-12-09/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=5acb8a3606a14d6ba23296d1dba83fbdc9e10d33c4a0859ae675a8910963661f +dist/2025-12-09/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=7d5307cdbc388a9635bad36081d067e3bb1ea6b30f53fddcb7a7b4a5046ad86e +dist/2025-12-09/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=33087e52b9683d0653e3c3315b03d39b7e7cf6b0f1d1a4a11a1ae21949a62765 +dist/2025-12-09/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=c4bd53291e41545a9e48c3951d591ffd3ef3c549b644a333913dd3770ce4020f +dist/2025-12-09/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=dc70e5c4e567962bc98a62a2f492828ee5f0420b9f44f6bd4279d2e59efe4433 +dist/2025-12-09/rust-std-beta-x86_64-unknown-netbsd.tar.gz=b08307db96fdc7777825ed9a2f09c1fe9b2bd3bcc8862a10ee31c8306ffd45ae +dist/2025-12-09/rust-std-beta-x86_64-unknown-netbsd.tar.xz=8e2fcfd80f0a678a91df324c198609bee2b02a76fdff6e861fa166be7964e03e +dist/2025-12-09/rust-std-beta-x86_64-unknown-none.tar.gz=c459a4cf0b0b38282bad8a80f42af8bd7567613432106396246f1751b3e1b187 +dist/2025-12-09/rust-std-beta-x86_64-unknown-none.tar.xz=da43d6038f9b0ea443c5a317e2d3414df076ae5f6e59433c4371289ed3852a46 +dist/2025-12-09/rust-std-beta-x86_64-unknown-redox.tar.gz=20cd456f8d9012aefe5ea5fc639ff18142614af45f00b101526587fedc735382 +dist/2025-12-09/rust-std-beta-x86_64-unknown-redox.tar.xz=7d31c1346facd16accb3a58dcae5fc62af5db3c99c26ba5915839a3118571208 +dist/2025-12-09/rust-std-beta-x86_64-unknown-uefi.tar.gz=7c738b0354a7d25b5d931d2e73b1207d452d027935f034a7ae106e4119ebcae8 +dist/2025-12-09/rust-std-beta-x86_64-unknown-uefi.tar.xz=e0640c8cfb01603576e58142829e96f06b650ad9131b8bfa8ecc76d26a49fbd1 +dist/2025-12-09/cargo-beta-aarch64-apple-darwin.tar.gz=9f75819749c4cc87f7435e765ac987f0816e8a17636828a152bba7dd02b46b6a +dist/2025-12-09/cargo-beta-aarch64-apple-darwin.tar.xz=38b8c3e43121c5a1f93e6b81d53598185d0c42c41933db4e09bb402aacf719d9 +dist/2025-12-09/cargo-beta-aarch64-pc-windows-gnullvm.tar.gz=5823f511f5e81e2b4cb72a9dc5955b311b31c7e07ac84be7c81a2ab537e20ec8 +dist/2025-12-09/cargo-beta-aarch64-pc-windows-gnullvm.tar.xz=e1cc29549af4fc472a1edc603de3ec9e575d4c18d67346b2b3b17ec1f3d4d140 +dist/2025-12-09/cargo-beta-aarch64-pc-windows-msvc.tar.gz=e7486bdbd06111ef8e0c328a0ba4e8a5a56d710054a17dc2b9ffbaf05c7c4e17 +dist/2025-12-09/cargo-beta-aarch64-pc-windows-msvc.tar.xz=18c81a2a41051362e1e0a040bb8615f4e3b3ed671147ad585ae9befd17e41c94 +dist/2025-12-09/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=5f846b7dbb282195160213f282e4746c874e60f6cff5ecef2083f0805765ec72 +dist/2025-12-09/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=c9eaf314667d3d0bb3da48857720be60c715a9fc3344bec15a7fb1b92c6214d6 +dist/2025-12-09/cargo-beta-aarch64-unknown-linux-musl.tar.gz=0394e35c668e58e9e6b2cf5eef24981ab97356f857546090a9af321b27fa9631 +dist/2025-12-09/cargo-beta-aarch64-unknown-linux-musl.tar.xz=cb3b9b54402f919244572eeee0cee0c16908fd80de7a07357eaa3fbde21852c5 +dist/2025-12-09/cargo-beta-aarch64-unknown-linux-ohos.tar.gz=9845a957510458b2fee44efbde72b71e7575a557687f07f76f71f343e746aef3 +dist/2025-12-09/cargo-beta-aarch64-unknown-linux-ohos.tar.xz=4ef90f7bc4c9eb87e259ba52f492ff100926ca0d5c874bf00f6e28f256dd9f32 +dist/2025-12-09/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=c5e609db1371ceeb9a9c817fffa90b59aa5d88a2931100e68e5e5fcc49f98f7a +dist/2025-12-09/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=aa454892dac6baaf4a51e6afaf41c9acb81e50bdd7a5de6c85045e2fad7d37c3 +dist/2025-12-09/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=5e8b574d1b758f045c7938439e44d173065525a1b99cdeb1f4ae822fd1dc7a31 +dist/2025-12-09/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=6eb4178b85a3c6e7eaf324c28496e8701af2268151590ccd361853e8f52078da +dist/2025-12-09/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=c4817681243ebeca687abc59fc0f1035d898ffc03b339634435fcdb6ac0563ba +dist/2025-12-09/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=74867e0de7d5eb96c10888c2aa536dbcf140e94190f42b3462a483fc3a17eea0 +dist/2025-12-09/cargo-beta-i686-pc-windows-gnu.tar.gz=4182caa439db0b6cb9ebed815d27de38d492904e9e4d05523b64de77657549f5 +dist/2025-12-09/cargo-beta-i686-pc-windows-gnu.tar.xz=12963ebddf340691ad70b4c1cb71ca1dbe9ea7b20e969ddaa1b01199519eed97 +dist/2025-12-09/cargo-beta-i686-pc-windows-msvc.tar.gz=5ad903382865f5e03659c8c128b33e8afb4288d52c515de1aee00ef119f1dc59 +dist/2025-12-09/cargo-beta-i686-pc-windows-msvc.tar.xz=4abf8df988ac23a7c2f3a974dc3f3ac2c5babf13c13a7089366813bb0e177d2b +dist/2025-12-09/cargo-beta-i686-unknown-linux-gnu.tar.gz=8e161351713a615e0625ea79e20915427c4daa006be76336c45f0fb90a2d2a1f +dist/2025-12-09/cargo-beta-i686-unknown-linux-gnu.tar.xz=3b550c261bd105fc5f3d027dcc90b37b343be3187ff2b1d84912b09faf0f976f +dist/2025-12-09/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=cc345ca12eb88366b95de1c40ca182ca14f260cca7cfb857e775f011bc9c3adc +dist/2025-12-09/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=b6a3a0ab898dcf2b35556642f812870ee15e62bed465e33ed4e8bf1094444b52 +dist/2025-12-09/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=a7ccd2f9f0dd4b7dfeacf06c42812471bdd24d2795f3533e41db872183157a14 +dist/2025-12-09/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=b2a75d4597b62f9d2fd3534b0972a8f0f6447d8da14e887d6207f3869d8df4dc +dist/2025-12-09/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=0b8db0062b3220806d215eab392bde104a4846f16b07b14130efa456352f0610 +dist/2025-12-09/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=51991f325aa8d01393c59af81d92d32fddb90a0e153178fa6d574f113a33376b +dist/2025-12-09/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=ae8d26626ff486f360f8b7d8178844024d4f458eca5997c9305825f3010f679c +dist/2025-12-09/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=b40b3f43472ab0bfc46f821c12a1df17dd41aa0ff6375522861abcb77aabd68b +dist/2025-12-09/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=362ca45ba28f18d3667416b2c81fc03d6b424d6d8d778f3d7a31dcb89f6f7fb8 +dist/2025-12-09/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=4513dafaf90abb9eba29f578b1ca1c57934ce78f0ad05ea0f45be5b6e39da7a9 +dist/2025-12-09/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=d77e406f0e0056a24db4afe70addff520059bfcf2e4441d4e3972dc20953ed0d +dist/2025-12-09/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=17e2a1f489fcd6920543e46fdf08c54a63e9bba1490d6daa800e225c6b753fd1 +dist/2025-12-09/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=469db45a320665a6a285bdfaf45791715a8c546c61cea3a35066b43b8d410c16 +dist/2025-12-09/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=0e2200fed953b69b4709ddc4df060e9718f09d062ae7184f51479ae684137e01 +dist/2025-12-09/cargo-beta-s390x-unknown-linux-gnu.tar.gz=dd3f998f36bf93541072e3c5a6d93ab7cca773e93ec436f2202d791e009ce6fd +dist/2025-12-09/cargo-beta-s390x-unknown-linux-gnu.tar.xz=f7c2707a6e855eb6ef6fa34da58c838db64a48ecf4baf84f62a3d676dc90a794 +dist/2025-12-09/cargo-beta-sparcv9-sun-solaris.tar.gz=646cc26a6cb13d404832ab6b10ba30c88ae232fdcf84ff2e524a61f6a8d3a3ad +dist/2025-12-09/cargo-beta-sparcv9-sun-solaris.tar.xz=833dfe8175a28e9ba9997dddcdff73c17ca54a685805a00fa8d6b3e2b688b532 +dist/2025-12-09/cargo-beta-x86_64-apple-darwin.tar.gz=4c73238ea769c53061b56937baad41e724669159a83b29b2ad71fd61a3e9b83c +dist/2025-12-09/cargo-beta-x86_64-apple-darwin.tar.xz=6eba917c9c319e082437bd402c933f27a0cd855619ccd7bc0eecef0745008714 +dist/2025-12-09/cargo-beta-x86_64-pc-solaris.tar.gz=dbe7b52b7f4e5bacfd465918eae271981eb01d40906152da88fd65ac4aa915e9 +dist/2025-12-09/cargo-beta-x86_64-pc-solaris.tar.xz=1a7addf40be3044cb9cc78574936ea3479466f573dca89c188a0e4fc367e70b8 +dist/2025-12-09/cargo-beta-x86_64-pc-windows-gnu.tar.gz=7a4c5d11c78f79dbd83ea36b8d9f50b8dcc70345d4ded5c25727540d49f8c317 +dist/2025-12-09/cargo-beta-x86_64-pc-windows-gnu.tar.xz=ea5c2c141cf5977cd230a28e7e64eb573090f9df58e694f9587cabbb24630b6a +dist/2025-12-09/cargo-beta-x86_64-pc-windows-gnullvm.tar.gz=6cf2d9cb061376f636ff23c42d4f70f6a7506f2d52a80995a4c0eb9e7011ca0f +dist/2025-12-09/cargo-beta-x86_64-pc-windows-gnullvm.tar.xz=854904ff28e8138e5d6b4a07698aa762a199f18692666962172b70d3f98085ef +dist/2025-12-09/cargo-beta-x86_64-pc-windows-msvc.tar.gz=ffcf63ab2b6a5ab9291e79a7c0bb4b0404a6b0f662c8fee5400871e57030ba86 +dist/2025-12-09/cargo-beta-x86_64-pc-windows-msvc.tar.xz=be6a9ebc401ba2e57dda2c278ac0fb04f07af05bae279df12a6db6cd92dd5fc8 +dist/2025-12-09/cargo-beta-x86_64-unknown-freebsd.tar.gz=194e7c211473bf17a00924a60e87edf95e50c29610ad66b01e03d7a57192bbac +dist/2025-12-09/cargo-beta-x86_64-unknown-freebsd.tar.xz=ecf5f9e48deac7b3bb4207b24607904f084f78e1cbe099b6bf49623361bc2399 +dist/2025-12-09/cargo-beta-x86_64-unknown-illumos.tar.gz=e3b16e0e31260123c60e8061b72b10d5e655f778f6f852feec9ea87816d677b4 +dist/2025-12-09/cargo-beta-x86_64-unknown-illumos.tar.xz=6d1065cc19ae1d09f72740e53640502c3337613f210733fec561ba977dda28a4 +dist/2025-12-09/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=2e1b3cf1ff6d6ebd72f309046c7a764fc3d689ab2cf3f66340a42c98cda06a9c +dist/2025-12-09/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=54f2e54197e4340aab81e4d81d9dff836473d098a0bc12b5f944581cca90567f +dist/2025-12-09/cargo-beta-x86_64-unknown-linux-musl.tar.gz=f34964cfe1432e2af127d62824bcb6be68ee40e41c190774efc56347bb72164f +dist/2025-12-09/cargo-beta-x86_64-unknown-linux-musl.tar.xz=40434b0a6609149823262f2a788a3f15c0343769286b8fd1addc9662fbd26825 +dist/2025-12-09/cargo-beta-x86_64-unknown-netbsd.tar.gz=3c2356d84ecee2197db0963bc67b3c896a90175c1a33c1f0c7df98354a1c17a0 +dist/2025-12-09/cargo-beta-x86_64-unknown-netbsd.tar.xz=bf5fc50b555ed8b1dfa1d06b811c5d0bed790cc0d6ab159fb59ca65604f08a73 +dist/2025-12-09/clippy-beta-aarch64-apple-darwin.tar.gz=07d985d4094b51973607b4857c32cca8371f2c9ea219309e25a8bbc09e7b6f19 +dist/2025-12-09/clippy-beta-aarch64-apple-darwin.tar.xz=022457737252bc7ae1293c523cdaaae68a1952ecd43546c642f0bbf5721bb327 +dist/2025-12-09/clippy-beta-aarch64-pc-windows-gnullvm.tar.gz=77d9f6e425be1a19e684b609971f30373eba3d57f7afec837d41041318acf942 +dist/2025-12-09/clippy-beta-aarch64-pc-windows-gnullvm.tar.xz=2e785a6dd171a22c5e7d57e4692d396256c286e429646f12c5b9ea883ad29c59 +dist/2025-12-09/clippy-beta-aarch64-pc-windows-msvc.tar.gz=df3230490829d3f85e9089c0270436b64984c5c83009e4b7be856cc1533ac697 +dist/2025-12-09/clippy-beta-aarch64-pc-windows-msvc.tar.xz=69d8f5ba926d82d71084ed00be6088bb1537d77a90b24af8218b8995547d1214 +dist/2025-12-09/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=9f23282495c4c598c21795c5938c3b072367d27c56f1ef6c5e9c81e0116a6736 +dist/2025-12-09/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=edca9027570949403f14f0e719249095ccd4b8d59296a41b4a72af54c020ef17 +dist/2025-12-09/clippy-beta-aarch64-unknown-linux-musl.tar.gz=651b5d61d641cf146799a747d4cfd35e18a43638f65765104bbfca1a61f89b60 +dist/2025-12-09/clippy-beta-aarch64-unknown-linux-musl.tar.xz=afee1d8d0b1c2b0a395ad5522e935e2d03c6bb88f2d0a496d8c453b2aaf65838 +dist/2025-12-09/clippy-beta-aarch64-unknown-linux-ohos.tar.gz=871a039f625ae3e2fcd69249b4fbe7211bc57ffa460dbdba95f433731aed00ee +dist/2025-12-09/clippy-beta-aarch64-unknown-linux-ohos.tar.xz=3a6413eac375103258fda9ecaeb79276144e96b1a7526932ff372b39676bf4e8 +dist/2025-12-09/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=c4143ceb6c644d73c7bdf36dc12184ee0545e56c17762e310163f32d171142e3 +dist/2025-12-09/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=ea1d55e762194001dd67ecb9f36b6e88023174d2afc11c270560133122127004 +dist/2025-12-09/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=84619076b88d498a9db44f9b1a4e18646412becf406a9c0e3ca53266e1cc63e0 +dist/2025-12-09/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=518f0d5578fa1a3be13da7c74a4388db0a1e30a212e07e005f54a964af9e3b6e +dist/2025-12-09/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=71f1b0fa2d6353bd15a3e71e37705cfc05b32f1a995ceed6661860846156b6bb +dist/2025-12-09/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=071d5f6a7726c049e8779ff0348a82e617faa2f0271d6a48785a829511f2ccd9 +dist/2025-12-09/clippy-beta-i686-pc-windows-gnu.tar.gz=1b0b74ad7374811536e8dee6276d95c00e93d5ff8582f47904311a801a4a457b +dist/2025-12-09/clippy-beta-i686-pc-windows-gnu.tar.xz=3909a6759b946bd26db078785ce2816d8e7ecc6b91f0a93da8e1215101315ec2 +dist/2025-12-09/clippy-beta-i686-pc-windows-msvc.tar.gz=20daed7b47df1a6edc52f4e513a9d8a3fd9adcbb57193584967908062e0b5f5a +dist/2025-12-09/clippy-beta-i686-pc-windows-msvc.tar.xz=726cc91501ad1618b960bfa8ef2fb48aedae7b6bce2e579ee97c2feaf731e63f +dist/2025-12-09/clippy-beta-i686-unknown-linux-gnu.tar.gz=76f33f847f9ca954ab4728d0ba59fc51eb45a19fb75162c37363a31d9cc81fbd +dist/2025-12-09/clippy-beta-i686-unknown-linux-gnu.tar.xz=fb2e996550d4c50d2e932b947b730c1be9a237de5b30bf88d51f02d4fb3aace4 +dist/2025-12-09/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=23bdfce50ecf66d373a029b97fb5ada2bf302b39245a7f2c2673b21d13889cec +dist/2025-12-09/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=e3d80cd58be9c50fd9316b1e19fac0b27246bf32264db5c765a04bfe11acdfe0 +dist/2025-12-09/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=c531fe17d77ae42393b7fd556ce8508f9450f393dd612085977707bec106f402 +dist/2025-12-09/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=805b2c4321e59d1d0d2f4dd6eb12920a472fa1422517bf506d41a09f887eb981 +dist/2025-12-09/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=8b82b14f74241aba3f65b80d726c3c43ff5d3452ea0268905eaa8247efd2e75c +dist/2025-12-09/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=5868780ae5c0cf07a613c3247b8339e6e5d0fb209ca279211061c20520a1916d +dist/2025-12-09/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=f40011b8c9868f0f20e55d0be4600c277e1391ab5fdc832c0ba3261299680d4c +dist/2025-12-09/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=09ad15c8d179d38424c64a697af9d256b3905fa27aa21fffe0dcf60e18821376 +dist/2025-12-09/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=5dccee69021050129a301aed0e2a092768aba58c0922f8265fc42172e55ef930 +dist/2025-12-09/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=3961d80cea94e31f8f571e962478fcc842a22163ed6e853b08b19063a56fb601 +dist/2025-12-09/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=d814ee9c7af0889b37ea08e4b2d059bc54d3bf3919b5d445d8a812ecd6bc122a +dist/2025-12-09/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=0ddea2966b675892b6f2f3161590af8adf4d9c278c4b50ac1d51bc82473a898a +dist/2025-12-09/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=e31bbd06adf63ab0b0abb357f3362d4398f7e6550aed91d7f5578e3a03cd55a7 +dist/2025-12-09/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=25affee87f7ec9b8b91368a64d9f5ce17f22a0c40f6bf1f6b51fadb43dec05b2 +dist/2025-12-09/clippy-beta-s390x-unknown-linux-gnu.tar.gz=001b23bb4d8e88f96d3fc1fbaab7e8b6a64de4d8d5767334ac3e9db9d79e56b5 +dist/2025-12-09/clippy-beta-s390x-unknown-linux-gnu.tar.xz=5f137aa245a5a168e71abef128e2181c4df0675666abad895d28df917ca9f0ff +dist/2025-12-09/clippy-beta-sparcv9-sun-solaris.tar.gz=1db02f7429b6594a0c5e33fdf273a827429ce928d37a48f06d1f9908be04bd8a +dist/2025-12-09/clippy-beta-sparcv9-sun-solaris.tar.xz=802755153ad5af276df68592784206cbf49f49a8b678ec6dd621e46699e391c8 +dist/2025-12-09/clippy-beta-x86_64-apple-darwin.tar.gz=3e5cf614a5dcc33b7a570f3b58d89bc930c84aacd05c8df00b40d1d813d13a9a +dist/2025-12-09/clippy-beta-x86_64-apple-darwin.tar.xz=aef870bd83eeb4b26ea3754a4ac3b11d81acfc74f9af97a006079445fb068069 +dist/2025-12-09/clippy-beta-x86_64-pc-solaris.tar.gz=6d1f58fcc6ebbfcec039a06375c09fdbad426e1bc4ed68881a63a19ea4edcc6d +dist/2025-12-09/clippy-beta-x86_64-pc-solaris.tar.xz=7309a240bca719dddc7d9c2e04906e765256407c397a759ee22ba6c6034beb28 +dist/2025-12-09/clippy-beta-x86_64-pc-windows-gnu.tar.gz=ebd0d50c7ad0f975be1862f8b025f1c577bf0b969fc50da679165041fdff5de2 +dist/2025-12-09/clippy-beta-x86_64-pc-windows-gnu.tar.xz=dd9fecb16743aa7584ac6c2e36e202194b51517cb86cd4a454a97dd63a83cf12 +dist/2025-12-09/clippy-beta-x86_64-pc-windows-gnullvm.tar.gz=50eec7195970f99f0ba0f493e3c12b0cb8dfa9fbe60fef436c64a318bad0a6f4 +dist/2025-12-09/clippy-beta-x86_64-pc-windows-gnullvm.tar.xz=e6090190aa83a26b4d71c66422e6332d873580fe807be6a3f2aa9dd56cf53e7d +dist/2025-12-09/clippy-beta-x86_64-pc-windows-msvc.tar.gz=e187f226606301670326e70f4f616d784d89fbe40be755f14a29e6df03e3fafd +dist/2025-12-09/clippy-beta-x86_64-pc-windows-msvc.tar.xz=0f69c54b1c112a276f5f538dcb007e34070e9a75681875d926d6f8f446692cae +dist/2025-12-09/clippy-beta-x86_64-unknown-freebsd.tar.gz=c107ed25ed5a09deb390b175e16a5102dafb21b12405cd227328f2e199a656e7 +dist/2025-12-09/clippy-beta-x86_64-unknown-freebsd.tar.xz=8d8927b64fec353a5cf987457f059995f16e1b36e96ca8b1f8be8e016f49962c +dist/2025-12-09/clippy-beta-x86_64-unknown-illumos.tar.gz=697d12dd34cb0176a839a1d08834fede0b39209f9b5ce102e40b3a41b4bab363 +dist/2025-12-09/clippy-beta-x86_64-unknown-illumos.tar.xz=c31578a3ebb692541cab846d81662ae554169d95018a4697c39fe1249c4e5154 +dist/2025-12-09/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=58b7c72e976dabeb431b897eaa921557b3460c5dc6c12a5ad908f2fcdaf697b8 +dist/2025-12-09/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=649b10e076d03f2428b3284391c67a2a1f7daf3b58185a797973121fc5b4c337 +dist/2025-12-09/clippy-beta-x86_64-unknown-linux-musl.tar.gz=c8f5c1c9990714c20ee85ff6d449caa0519e291b8068e6a5d27c6be1701c6a10 +dist/2025-12-09/clippy-beta-x86_64-unknown-linux-musl.tar.xz=2ff9d03902202060d6059f78872f9606c67357a839dc1d84d0dabc9b0dc79e61 +dist/2025-12-09/clippy-beta-x86_64-unknown-netbsd.tar.gz=95f9c12acabbeca6eb1fe6abee785909009b39d2119c45e8c54f0aa4aee09ab9 +dist/2025-12-09/clippy-beta-x86_64-unknown-netbsd.tar.xz=a8fc86de0d51cbe8ffc9622c539de5ec958948e8d510d113d4d86da0ff512a45 +dist/2025-12-09/rust-beta-aarch64-pc-windows-gnullvm.msi=0decc8436fecf2946138123ba94002507c4e9e0883db90aec5639dadd2fe0fa6 +dist/2025-12-09/rust-beta-aarch64-pc-windows-msvc.msi=d094d7636cc4ab90b00539cf2fd63339dea88e2cce4ed1e6079d925c5102bbb2 +dist/2025-12-09/rust-beta-i686-pc-windows-gnu.msi=546214c69cdb5ebcc1b30a0919e13ce15ee5bab0a6a3f5b2ba09506a7f1ccba8 +dist/2025-12-09/rust-beta-i686-pc-windows-msvc.msi=9f93d409def886c556de52c35dae811e6d5d59cb88c4447bef80f126b08af64b +dist/2025-12-09/rust-beta-x86_64-pc-windows-gnu.msi=a348502a2cbd16752b792f69c24e49cdc1b241aabfb629e25d4136d34e1d7403 +dist/2025-12-09/rust-beta-x86_64-pc-windows-gnullvm.msi=04b4c3d704d742b840bd1bc60aae178a87b6d04eeb970dbe5d84dcbe503cdd8c +dist/2025-12-09/rust-beta-x86_64-pc-windows-msvc.msi=660b04aeef50fac72ab4e53a524af5632ba5d43bcd37fe95c1a2a6e7704e8789 +dist/2025-12-09/rust-beta-aarch64-apple-darwin.pkg=fc4889fa5dabb9e2a54535e33bb82aa658dadf2b53061b0cd5a47ad58e42cdf3 +dist/2025-12-09/rust-beta-x86_64-apple-darwin.pkg=5224a904cef4284950d8c193c89e4f826ed5a5fb77a9b05fba3fcf6b8a107dfb +dist/2025-12-09/rustc-beta-src.tar.gz=2ba3a82da54f472c3eb8253c0eee35f9d121f8027d34869455e9b10635a7b648 +dist/2025-12-09/rustc-beta-src.tar.xz=af3e7fe0843ecfff1168dba08615b7e500a8f9aa82926c422d01754156ca38f6 +dist/2025-12-10/rustfmt-nightly-aarch64-apple-darwin.tar.gz=24ec825bd10f04ebef571174b08cd6f4041cba5da0255811b1eba58771f8ee84 +dist/2025-12-10/rustfmt-nightly-aarch64-apple-darwin.tar.xz=4a80862cc5f685c325650b364361cb7d4b80faab1688988fc6d3e585cb37b133 +dist/2025-12-10/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.gz=2322573bee75a407302fd18cea373975dad8d3bc77ae52fb4a65ab89a85ad8d1 +dist/2025-12-10/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.xz=cefab5e313a8e184a243ecb7429acf2c9338396279467e4eb74b42dd0d74d588 +dist/2025-12-10/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=9c61e4763b7d5a378684cbf323522b18721be552f19b61303b0fcc257aad94fd +dist/2025-12-10/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=960c96b8b5d5b1ae2b01103c59bd761b7ead18470795fac7d9de5b8ed635abd3 +dist/2025-12-10/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=c7ab92e0faba8c29ac42aec6be553f2a98b6eb552a2327e7eea27fa90d324287 +dist/2025-12-10/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=8245467e46eaf068f560c63e43e14de233be6481fa47a663dfc03e0343a21a24 +dist/2025-12-10/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=4f73b7d59a7f43f9732bb37779224d289dd9bfedd98963387e968283dd09959c +dist/2025-12-10/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=4deeab8e28f00f7dfb11fc9fcffef9bfc866ec7a67e6da4cf0c2a68ced8eea7b +dist/2025-12-10/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.gz=d7cfae90e1d3ee3c7e30a39e2cc789b045498e282eab5831a538910ae4c878fe +dist/2025-12-10/rustfmt-nightly-aarch64-unknown-linux-ohos.tar.xz=674460a55e04a6d1e505957bc1bbc560351f4143bcacdd93f86e301c0a7415b6 +dist/2025-12-10/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=c745ef65f257d48dbaabb5aefa2ac0b2a51a3f2185f542f0e6017fd5378c1bc6 +dist/2025-12-10/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=0765fe91b4ff940575c819259c2b2e328c81a7ff02a1a283ec2e6844bd026e85 +dist/2025-12-10/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=7b01938f5c56be23e682b7cbdbefe0da87e41a136029f09a38362aac4df05bc2 +dist/2025-12-10/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=f90fa659f11e39ce6145689cd3284fec95d7e4219e4e8c5b14876357b3892e4c +dist/2025-12-10/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=c168b4f52d9e4f17234a824e49e257577f3a2f2643cf5cfac8e28395d3c6a7c8 +dist/2025-12-10/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=0a9cd71999664d67f83bb9c3f87415656329086f0e3503953992b1cbe34d9a5e +dist/2025-12-10/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=207f1343fd0a348344b9866e99b80ff7112a9b48a2ff63168e133913fe161425 +dist/2025-12-10/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=83147ebb6c01438b55d2973759821178a6e109eb91146d96386c504070248769 +dist/2025-12-10/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=a59c45a3ab6601db73a1628266ff6dec37cc04bb964096116df21595aa53d358 +dist/2025-12-10/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=b1da98ed515858fe2659e42a31c9b9cd4adb60c3080ec154f3829859855c324e +dist/2025-12-10/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=59fd2ab17d3215a6bd6e34ec2e61146a48cb273754003d561df7ac2a7a3d131e +dist/2025-12-10/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=1b3aae40df398d2456ac82fd9ff86e83870b9ce46247a164eba82365c5624569 +dist/2025-12-10/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=f9f43f82d73e136a2f40dcdc41bd3c7e106a94a0a4e5edac661ba7a72a883a09 +dist/2025-12-10/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=bd4912cd32a56cffcf4b019a08b4b751d4a5006c754fa349cc5f38c396fc2e88 +dist/2025-12-10/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=cc65c029ab8d0a5efbadf00b40b5bc8e4e737ce0eaa3f2bd24ff145725384038 +dist/2025-12-10/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=0bc6580c37977c55c259e0da12732f0a3ff072fe629615ec3602c510129db20f +dist/2025-12-10/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=9837287d443e9519759e541f7d60128f535eb0990ca49cf107a6d7f8e13fb33c +dist/2025-12-10/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=55b0b24b2e33b6ed5eb8eaab1e6ef9b0cb7c64280d8f4a46fb8c644291bc72cb +dist/2025-12-10/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=29510416f023edabd18ebb9a5f6fd96e55a07dc968a33922b68749d17a51df71 +dist/2025-12-10/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=aa9a16c99748912c2d9aa17ea1fd3d34afa87f352b922ebf5939e41ec4b2bc7f +dist/2025-12-10/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=9a0642853b345aa058dd7ed7bb3777fcb1bb6d8d15893bedf40595c7513beb67 +dist/2025-12-10/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=5b4f5226d11cc8811d92a7ddd601fc6e0a7f1cafb973def40efa5c5a3b29fff1 +dist/2025-12-10/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=e6ed9a58e3d8b3e215d9e24cd47c363b5659cf32e9cb4c104a35cfaeeee1a6c0 +dist/2025-12-10/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=760ab76dfa17332f1c3b3330fec0774ae5a07599aaad838c946df4f588993f71 +dist/2025-12-10/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=8f0bc4bd2bc633afff10982328f5a2b6d0a37faadadc7cbbf761a106a3a9ba71 +dist/2025-12-10/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=9e0e069e0c57c2c07768b3fa4a9c38cc6f914a23b84e8efe6fabb250d6e99e34 +dist/2025-12-10/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=4a23ff6f2d3f2df2afa21ceaccf118c1711e4553090cac6caf116b567080f396 +dist/2025-12-10/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=98c672887a5d8ef1a9d356e5a53acb21ff9771b122f67e6fde8c1c362dfdfd21 +dist/2025-12-10/rustfmt-nightly-sparcv9-sun-solaris.tar.gz=92dd3c460488e73cfa5a4162b910a9db64b3fb3952c32039fa1bb24dabbebec5 +dist/2025-12-10/rustfmt-nightly-sparcv9-sun-solaris.tar.xz=231d454a308af3a1deafca579bbf82fd630bd42df903e47c3e48f84be588bf3c +dist/2025-12-10/rustfmt-nightly-x86_64-apple-darwin.tar.gz=e57059b13d749c0b671fd5bc4bf03b1162afe5d258304f80bd67b75a7dba7361 +dist/2025-12-10/rustfmt-nightly-x86_64-apple-darwin.tar.xz=f837b268e872681f2cfad6c485a0e28647ac826ebe9d0ce2d01520f294ad0037 +dist/2025-12-10/rustfmt-nightly-x86_64-pc-solaris.tar.gz=d5890236f6963d2a9a16a4edb3e6515216ea9f96f2996da298ed9756c75bbed8 +dist/2025-12-10/rustfmt-nightly-x86_64-pc-solaris.tar.xz=789e877ca7a2fba536a62bc27d1034399a75c5df0c0fb677ee6aad8dfc8c0e1e +dist/2025-12-10/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=eefadcc6be10ba4b41c21c60cd1fdb818389b17bfe09b97d41be64fba9643f35 +dist/2025-12-10/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=d9904734a9ba86930c4680f167c4c6d3b3c5c49d6274a47c1e25f3557a19e672 +dist/2025-12-10/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.gz=b9d556aa1f760b6acfa6257a77fc489b4efaff3627a80ea25b1cb759786b9182 +dist/2025-12-10/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.xz=3230a9ab8bfea6e9d90a444aedb546040fc743b6ae9f3e7830ecad35eb343896 +dist/2025-12-10/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=9cdb560c8941551b371f898f8d385a4952794aad27d27786d263b3ff02069cd7 +dist/2025-12-10/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=ec4b17c6c8aedc5bec3afdcda9a5f85b932e94c8711d03f06171c36ea9349b1c +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=bf5a2486465ee6848b2a145c6a16bb5116b893e8d22d3897c78c2930617e8e65 +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=c71effbcbb3e1b2b90384799b1079658118e24a60408c482d75aaedc3628a6ef +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=867a4ba29283c658f6a3db55e0edace19cd0102f17409338c75827d3dbceeed8 +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=ea07fe1ecc5480b246387a228a8ea342616385bf9ec25e40d3de9806e06e1e07 +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=8457f82703b5dd5cf1c8ec74011b666239268f1151b0800209a5312274b99151 +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=31f203fc0623c23d41cd64ec4928f0a8d330aeba0f28d0f451683e94da873f28 +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=5d752c9879b464b385c14c38ce2b6dad2542d3e4932337ce76d5fcf77b2d3d39 +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=797ed8b8c2f2f5764ab2965b7701d73dac4f3ea01a431b1b337dece0e718c940 +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=a4eed85109f7d76a11e9bcfcb27550636c47c09a10e12f92d76778f6989ffff9 +dist/2025-12-10/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=fdb91ee8d9edc3824426268654efa77a7366ee436b5969366b7f924e1efc8082 +dist/2025-12-10/rustc-nightly-aarch64-apple-darwin.tar.gz=1debf4ac8bcc013d4a4a6f000a308bf69b1b99609e841f4eb5f63fb22edb68c4 +dist/2025-12-10/rustc-nightly-aarch64-apple-darwin.tar.xz=460eb2dc63c9b2da77a9e12eeaacf3302fa0b2276cf6fab1b1875465fed221cf +dist/2025-12-10/rustc-nightly-aarch64-pc-windows-gnullvm.tar.gz=b9dfa64737763a506ba08a1485c7ba1cf985c1b3e68c282b0515cc646bcd7852 +dist/2025-12-10/rustc-nightly-aarch64-pc-windows-gnullvm.tar.xz=f7aaf99ffb316c72fe1121344ae55f65e94448f6ae324ec00f6f73960360bcef +dist/2025-12-10/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=832410daf93d83d489586bd9823b06c53cfd284072274b43e6db4514dc2c5c2c +dist/2025-12-10/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=4e1a2e537f0daf6c000bfaedba3a306d3e9017574dba0ff53c08ad208f5a3326 +dist/2025-12-10/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=f520d2e5ea92519c99ad80fd61af4621c5f6a3ecd1dcd6bcf797aff679ccc403 +dist/2025-12-10/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=73120c237a0a19f6b5ca52fe02ea1c2300d5204861a6f7f5a5d059925a780a9e +dist/2025-12-10/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=5121387c446ff2e3f766ed1f117526d21768e84dc07512cc738ef19870bddfed +dist/2025-12-10/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=3deae487826308f70a7855adf612c4c87121ca2df8f890b744e738f667696883 +dist/2025-12-10/rustc-nightly-aarch64-unknown-linux-ohos.tar.gz=ed6c93be35e43f787ab6838c468d984b6f3ccaf561a48bf6b4928e4d5bb17b75 +dist/2025-12-10/rustc-nightly-aarch64-unknown-linux-ohos.tar.xz=76b40a2678643983781508a6fda99de7a3dd7b6269b410bf5f3638fd2db596e4 +dist/2025-12-10/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=a0e75393de8ace2e7c40ed54a127e5dc25242914a31313f2520fc634f3e400e8 +dist/2025-12-10/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=03ed745c4940c088893ceb36f563f43ecab1c6f17d3983e28ceb4e89d8234331 +dist/2025-12-10/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=4d473526c3e46f04550f2623542568fad0c397dfdb6194e2528cc21975bcb64e +dist/2025-12-10/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=6dc10f3407d80a7ecb9594620ca070291e192275434daa6e49888484f0c1b9c7 +dist/2025-12-10/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=3929d09ab864e5669b38f5b5a308fe637b22e88ad25e339bdd3e2df15e77a18a +dist/2025-12-10/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=2d674373dfbb2ac0caeab3e5fe053073f8313aa3d3c5937b982abcc5d467af22 +dist/2025-12-10/rustc-nightly-i686-pc-windows-gnu.tar.gz=e7abc330e9f8554f29fce9c984ab624498c55b4f66aea12836564e097569a753 +dist/2025-12-10/rustc-nightly-i686-pc-windows-gnu.tar.xz=887d766a9996d9b956e5d61bcb3166a5f5923ca37d114814e3a85db83bff30d7 +dist/2025-12-10/rustc-nightly-i686-pc-windows-msvc.tar.gz=00854c8dfcd94264a88483241cfe79e9357f97ad5fd9ca1a59f49a54806e1b1f +dist/2025-12-10/rustc-nightly-i686-pc-windows-msvc.tar.xz=cbcf96dbb3250cd9d54e66858fa2af4c2506fe81ec2239b2ebbbeba1ef1b4911 +dist/2025-12-10/rustc-nightly-i686-unknown-linux-gnu.tar.gz=42f92a1d712bfca3b365b8627d5a5266e0b35f8a6af67cd77ad7a78bd6dcc4db +dist/2025-12-10/rustc-nightly-i686-unknown-linux-gnu.tar.xz=a762070fe4c322916daccacca0e14793bd91339f5803d981fd83e8f2511d9eaf +dist/2025-12-10/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=a621f4811d670ae885d63dbce5ced336cb26662527e5ad16a020bd31e0ffc4df +dist/2025-12-10/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=b20f98c90930205966d88771dbf3ffed04f701be0d7dbe074791f63ae9d563ab +dist/2025-12-10/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=a8be28df240832939d2988af21a15b06dcd550ef6de9a468e8d1241f96a9d548 +dist/2025-12-10/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=b4d883ddd22480c6adf1a9f448124532b50f8bc3d1da54e17ce30e1e07bdeac7 +dist/2025-12-10/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=f15a8266370bbf23e5c33afd1dbde578eed56ef1d8b0dfd0f4a689cc90a55890 +dist/2025-12-10/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=c4f63b2adebf61896681df4d8e4015bc510dfe83a7d99ffd0df996ceb56333d4 +dist/2025-12-10/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=864210b8ed936a21532ba16ed2c12538ab802bb1f678f4175738957949090515 +dist/2025-12-10/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=4dfa49bbc7e9bdc4edb33e8b21a4fde9dac6f178845bc0f86baec1cf0cccc661 +dist/2025-12-10/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=4234e6dfc10b54510d4caa7266ddd2776cb6ac4a463f5fc0e105b56f90fe25a0 +dist/2025-12-10/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=707e947a1a6afb285918f5116a7a821fcbfb5448e9dde4f93aecfd49d0ec206a +dist/2025-12-10/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=9f2968856d329a2a87f3d6e035b75d78036941f30c7e5b9b99a8f2e18329d135 +dist/2025-12-10/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=138635257545931c183a5c6c41345391190c3bc5b64caf3192f05053f1243f87 +dist/2025-12-10/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=31edf819c4374e2d56a9a3fb125e2879e78067695c05bb165f0246846968fc09 +dist/2025-12-10/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=84c92f5bc6ebd0904db0e91a17163e4aadf93478b09681d7f659b2733e7ec7dd +dist/2025-12-10/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=dd5bb23c59ef383fa51bc59e4dd869d8c195a02512306fa0010c00b0f13c0ad1 +dist/2025-12-10/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=48d041d57df47c4d99fc0ebc0a10b7cb374f664303ea8b4ffca4c08aab20289e +dist/2025-12-10/rustc-nightly-sparcv9-sun-solaris.tar.gz=006f8d00e4bf719a84f3f8244bf7587f6b7fa141d0659941fb1c0bef7e1c0f5c +dist/2025-12-10/rustc-nightly-sparcv9-sun-solaris.tar.xz=dc9b5086fb6f00164fd676baacccfe030af279e75c339162cb666ebba0f76692 +dist/2025-12-10/rustc-nightly-x86_64-apple-darwin.tar.gz=71604d26e35b1d8d47edfa5744e1f56d99ae780ff39780f2e6f91dcd744881e7 +dist/2025-12-10/rustc-nightly-x86_64-apple-darwin.tar.xz=67d9b818da84cae669f13e24e3be2e16036286f4ad3ba82965dbfc6a9cc0bd21 +dist/2025-12-10/rustc-nightly-x86_64-pc-solaris.tar.gz=5b7eb8e65fc1c3f173e640487dce7778167710dfa403bb877905bdfda1f3e6c9 +dist/2025-12-10/rustc-nightly-x86_64-pc-solaris.tar.xz=fdf2bd54e7278c1f601a894fd8e10a22bfef06aac7bd062e08ed08fdffc9d1a4 +dist/2025-12-10/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=4165469f2326441c64874ddddaec7897386e8f7808dbe48762f4e394319c33dd +dist/2025-12-10/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=d60b8e47a871874a1e21b3b3e79255d818596364295b4fc7ab31ebd45576f66a +dist/2025-12-10/rustc-nightly-x86_64-pc-windows-gnullvm.tar.gz=2f6de03a3af0fb2c66eb7a2a01a425435dd3f6025aa9d83073798f37a0311c77 +dist/2025-12-10/rustc-nightly-x86_64-pc-windows-gnullvm.tar.xz=0a4b940cfadddf0c1dd3c6ac44e1db9a48e71578803a1690d92ff35bf062eac0 +dist/2025-12-10/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=08b6ea3a88f0ed773edb97f02995a05afa142f08054a4c076dcfe07d6d95d406 +dist/2025-12-10/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=ed07457a628abfb45c5e1e290cd3df284d7aad4caa2fa72e1042b9c0fd0e8375 +dist/2025-12-10/rustc-nightly-x86_64-unknown-freebsd.tar.gz=2dd8158c9a0f5715c20bc325100f89a8bf73703d426ae7222d86ffc4fc4b1f4f +dist/2025-12-10/rustc-nightly-x86_64-unknown-freebsd.tar.xz=35eca84b519cad4bcbd46cc40bde94ac22bf7e62af32bc802a8a3f05c82ab35d +dist/2025-12-10/rustc-nightly-x86_64-unknown-illumos.tar.gz=f41e19ee9031fd636b8b6ccac51949b0f52a884e866f75a04645f57a24f13216 +dist/2025-12-10/rustc-nightly-x86_64-unknown-illumos.tar.xz=63a3c093db358866ec31c38a872f6024a02a611c5729127d5bff91b394f2b5ab +dist/2025-12-10/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=056872dae473bc6e843a5272698ab2de04a8d08aa1a510753f4dd46058601b1d +dist/2025-12-10/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=5342e6efe17f2ffbd2625f758e7389f201c15eff59288c3a929743ae9eb33d95 +dist/2025-12-10/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=9076cb3c1aeacd2e11bb6a2790b6b83234aae46cc956ae615eac171471f2c94f +dist/2025-12-10/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=23ac96d176e79490597c80205c51b51682e7bb0f24e1020367958ec737614722 +dist/2025-12-10/rustc-nightly-x86_64-unknown-netbsd.tar.gz=03c1c5fe68c45392a93774a228ff18abcc1b29fc1e83c3a901604594ef2e78fd +dist/2025-12-10/rustc-nightly-x86_64-unknown-netbsd.tar.xz=274cbef82373e1687534e81c53d2dc909ad8200c21062363bd2c892b528209d8 +dist/2025-12-10/rust-nightly-aarch64-pc-windows-gnullvm.msi=0ad2a86241f5a786e7afeacbed7225f904748c62b0c2a91cc72123392834a234 +dist/2025-12-10/rust-nightly-aarch64-pc-windows-msvc.msi=21b3530f3615448adfe61ce4e28c47fbf0b2f15e674d73b5a11e966476a9473e +dist/2025-12-10/rust-nightly-i686-pc-windows-gnu.msi=93d58d311e7bb3a75903e8539dd34bc65b85b951bf9eff5594f539f79bc65c72 +dist/2025-12-10/rust-nightly-i686-pc-windows-msvc.msi=22ba8e3dfd93267d0c4660cf889951208c17ef0050538206a5fe7f799e24a2fd +dist/2025-12-10/rust-nightly-x86_64-pc-windows-gnu.msi=d8e6963725b2b8fb1c92cec90830a1cd73968450b676ddcd4ccd90b9006281a7 +dist/2025-12-10/rust-nightly-x86_64-pc-windows-gnullvm.msi=d4c1af5399e97ec877d06ad0ef978ba08fb9994b2588b3195316a36c58915151 +dist/2025-12-10/rust-nightly-x86_64-pc-windows-msvc.msi=c738f27b64f63b8702646effaddb4af8398bd2d2ef810ef6b2ac1cee4997c692 +dist/2025-12-10/rust-nightly-aarch64-apple-darwin.pkg=6d35933519ae62d24b8c772aa43483d9e40138f7bb5894fe42fbe6e48299efe8 +dist/2025-12-10/rust-nightly-x86_64-apple-darwin.pkg=388c57b33f3fb46bbf1f194e5bd899316eddf6a067103792e0df64861bbb193e +dist/2025-12-10/rustc-nightly-src.tar.gz=1cb5229e21c945bf992fc9e0eb8c5cbf3516fd7d4caea9969e8515971c45483a +dist/2025-12-10/rustc-nightly-src.tar.xz=96ce631d5b33858d220d686bb2c1388e3f055680366f94833ba4c2a026cfc796 From 2ffb1d55efd648145b069a51fd4bbbc22c2db55f Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 10 Dec 2025 05:55:31 +0000 Subject: [PATCH 1058/3801] Handle bootstrap cfgs --- compiler/rustc_arena/src/lib.rs | 1 - compiler/rustc_codegen_llvm/src/lib.rs | 1 - compiler/rustc_hir/src/lib.rs | 1 - compiler/rustc_hir_analysis/src/lib.rs | 1 - compiler/rustc_lint/src/builtin.rs | 1 - compiler/rustc_lint_defs/src/builtin.rs | 18 ++++++------------ compiler/rustc_target/src/lib.rs | 1 - library/proc_macro/src/lib.rs | 1 - src/librustdoc/lib.rs | 1 - src/tools/miri/src/lib.rs | 1 - 10 files changed, 6 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 5151c358774e..a0350dd6ff31 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -10,7 +10,6 @@ // tidy-alphabetical-start #![allow(clippy::mut_from_ref)] // Arena allocators are one place where this pattern is fine. #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(maybe_uninit_slice))] #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] #![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 4d0f8dbb9302..65e1bc5c8434 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(slice_as_array))] #![feature(assert_matches)] #![feature(extern_types)] #![feature(file_buffered)] diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 7a5776f0d5a9..7c9c15c16df4 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -3,7 +3,6 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(debug_closure_helpers))] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] #![feature(const_default)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 538fb8c7df1e..65f6a11e8e9b 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -58,7 +58,6 @@ This API is completely unstable and subject to change. // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(bootstrap, feature(debug_closure_helpers))] #![feature(assert_matches)] #![feature(gen_blocks)] #![feature(if_let_guard)] diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 810760e9f53e..e2a061cab680 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2683,7 +2683,6 @@ declare_lint! { /// /// ```rust,compile_fail /// # #![allow(unused)] - /// # #![cfg_attr(bootstrap, deny(deref_nullptr))] /// use std::ptr; /// unsafe { /// let x = &*ptr::null::(); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 99cce0c44b86..6bd0efd5d751 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2346,8 +2346,7 @@ declare_lint! { /// [sanitize]: https://doc.rust-lang.org/nightly/unstable-book/language-features/no-sanitize.html /// ### Example /// - #[cfg_attr(bootstrap, doc = "```ignore")] - #[cfg_attr(not(bootstrap), doc = "```rust,no_run")] + /// ```rust,no_run /// #![feature(sanitize)] /// /// #[sanitize(realtime = "nonblocking")] @@ -2356,8 +2355,7 @@ declare_lint! { /// fn main() { /// x(); /// } - #[cfg_attr(bootstrap, doc = "```")] - #[cfg_attr(not(bootstrap), doc = "```")] + /// ``` /// /// {{produces}} /// @@ -4907,8 +4905,7 @@ declare_lint! { /// /// ### Example /// - #[cfg_attr(bootstrap, doc = "```ignore")] - #[cfg_attr(not(bootstrap), doc = "```rust,compile_fail")] + /// ```rust,compile_fail /// #![feature(supertrait_item_shadowing)] /// #![deny(resolving_to_items_shadowing_supertrait_items)] /// @@ -4924,8 +4921,7 @@ declare_lint! { /// /// struct MyType; /// MyType.hello(); - #[cfg_attr(bootstrap, doc = "```")] - #[cfg_attr(not(bootstrap), doc = "```")] + /// ``` /// /// {{produces}} /// @@ -4951,8 +4947,7 @@ declare_lint! { /// /// ### Example /// - #[cfg_attr(bootstrap, doc = "```ignore")] - #[cfg_attr(not(bootstrap), doc = "```rust,compile_fail")] + /// ```rust,compile_fail" /// #![feature(supertrait_item_shadowing)] /// #![deny(shadowing_supertrait_items)] /// @@ -4965,8 +4960,7 @@ declare_lint! { /// fn hello(&self) {} /// } /// impl Downstream for T {} - #[cfg_attr(bootstrap, doc = "```")] - #[cfg_attr(not(bootstrap), doc = "```")] + /// ``` /// /// {{produces}} /// diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 1210169b3a5c..dfa1b2320718 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -8,7 +8,6 @@ //! LLVM. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(debug_closure_helpers))] #![expect(internal_features)] #![feature(iter_intersperse)] #![feature(rustc_attrs)] diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 9287807c43e3..a0b6656c8ded 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -22,7 +22,6 @@ #![feature(staged_api)] #![feature(allow_internal_unstable)] #![feature(decl_macro)] -#![cfg_attr(bootstrap, feature(maybe_uninit_write_slice))] #![feature(negative_impls)] #![feature(panic_can_unwind)] #![feature(restricted_std)] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c74c556b6210..137319ae0c06 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(debug_closure_helpers))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/", html_playground_url = "https://play.rust-lang.org/" diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 743caed6dbb6..7ce2ab3b3a43 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -17,7 +17,6 @@ #![feature(derive_coerce_pointee)] #![feature(arbitrary_self_types)] #![feature(iter_advance_by)] -#![cfg_attr(bootstrap, feature(duration_from_nanos_u128))] // Configure clippy and other lints #![allow( clippy::collapsible_else_if, From 8321ad2369fc23fc64d8e63cce938d646bbe3808 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 10 Dec 2025 05:56:40 +0000 Subject: [PATCH 1059/3801] update missing targets list --- src/bootstrap/src/core/sanity.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index d1f706fd9c3e..932a58c954df 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -34,15 +34,8 @@ pub struct Finder { // // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ - "aarch64-unknown-helenos", - "i686-unknown-helenos", - "x86_64-unknown-helenos", - "powerpc-unknown-helenos", - "sparc64-unknown-helenos", // just a dummy comment so the list doesn't get onelined - "riscv64gc-unknown-redox", "riscv64im-unknown-none-elf", - "hexagon-unknown-qurt", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM From df780f87c733f115f394279eb0a6a058e8815a4e Mon Sep 17 00:00:00 2001 From: Boxy Date: Wed, 10 Dec 2025 07:50:44 +0000 Subject: [PATCH 1060/3801] Update compiler/rustc_lint_defs/src/builtin.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: León Orell Valerian Liehr --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 6bd0efd5d751..8c69cc089caf 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4947,7 +4947,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail" + /// ```rust,compile_fail /// #![feature(supertrait_item_shadowing)] /// #![deny(shadowing_supertrait_items)] /// From b22b343fafaf0540797b0099ff6e06ed85c184bc Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 19 Dec 2025 15:06:11 -0800 Subject: [PATCH 1061/3801] Revert "Generate macro expansion for rust compiler crates docs" This reverts commit c820f461228ba5d8d6bc6879e5a311a45673fb84 due to an ICE encountered while bumping the bootstrap compiler to 1.93-beta. --- src/bootstrap/src/core/build_steps/doc.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index fa36a6471cae..b86582807f72 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -932,7 +932,6 @@ impl Step for Rustc { // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222 // If there is any bug, please comment out the next line. cargo.rustdocflag("--generate-link-to-definition"); - cargo.rustdocflag("--generate-macro-expansion"); compile::rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates); cargo.arg("-Zskip-rustdoc-fingerprint"); From c039edd41416c209b6bcdfa02d152a8db64102ba Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 20 Dec 2025 00:32:56 +0100 Subject: [PATCH 1062/3801] Fix typo --- tests/rustdoc/import-remapped-paths.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rustdoc/import-remapped-paths.rs b/tests/rustdoc/import-remapped-paths.rs index bce3d782b9c2..9e7518f7c017 100644 --- a/tests/rustdoc/import-remapped-paths.rs +++ b/tests/rustdoc/import-remapped-paths.rs @@ -1,7 +1,7 @@ // This is a regression for `--remap-path-prefix` in an auxiliary dependency. // // We want to make sure that we can still have the "Source" links to the dependency -// even if it's paths are remapped. +// even if its paths are remapped. // // See also rust-lang/rust#150100 From fb6dd1700a24349d2470165c5ce6702158bcbe9a Mon Sep 17 00:00:00 2001 From: "U. Lasiotus" Date: Thu, 18 Dec 2025 21:41:41 -0800 Subject: [PATCH 1063/3801] std: switch to moto-rt v0.16.0 --- library/Cargo.lock | 4 +- library/std/Cargo.toml | 2 +- library/std/src/os/motor/mod.rs | 4 ++ library/std/src/sys/net/connection/motor.rs | 23 ++++----- library/std/src/sys/pal/motor/mod.rs | 54 +++++++++++---------- library/std/src/sys/pal/motor/os.rs | 15 +++--- library/std/src/sys/process/motor.rs | 7 +-- library/std/src/sys/thread/motor.rs | 2 +- 8 files changed, 58 insertions(+), 53 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index 513d3f136698..5e49843dae06 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -175,9 +175,9 @@ dependencies = [ [[package]] name = "moto-rt" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf4bc387d3b3502cb92c09ec980cca909b94978e144c61da8319ecf4bc8d031" +checksum = "29aea9f7dfeb258e030a84e0ec38a9c2ec2063d4f45eb2db31445cfc40b3dba1" dependencies = [ "rustc-std-workspace-alloc", "rustc-std-workspace-core", diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 83a0826ac425..43caf7734fdb 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -71,7 +71,7 @@ fortanix-sgx-abi = { version = "0.6.1", features = [ ], public = true } [target.'cfg(target_os = "motor")'.dependencies] -moto-rt = { version = "0.15", features = ['rustc-dep-of-std'], public = true } +moto-rt = { version = "0.16", features = ['rustc-dep-of-std'], public = true } [target.'cfg(target_os = "hermit")'.dependencies] hermit-abi = { version = "0.5.0", features = [ diff --git a/library/std/src/os/motor/mod.rs b/library/std/src/os/motor/mod.rs index 18da079c74a1..e8812f48a120 100644 --- a/library/std/src/os/motor/mod.rs +++ b/library/std/src/os/motor/mod.rs @@ -2,3 +2,7 @@ pub mod ffi; pub mod process; + +pub fn rt_version() -> u64 { + moto_rt::RT_VERSION +} diff --git a/library/std/src/sys/net/connection/motor.rs b/library/std/src/sys/net/connection/motor.rs index 9beed0779752..79a528792106 100644 --- a/library/std/src/sys/net/connection/motor.rs +++ b/library/std/src/sys/net/connection/motor.rs @@ -144,8 +144,9 @@ impl TcpStream { } pub fn take_error(&self) -> io::Result> { - let e = moto_rt::net::take_error(self.inner.as_raw_fd()).map_err(map_motor_error)?; - if e == moto_rt::E_OK { Ok(None) } else { Ok(Some(map_motor_error(e))) } + moto_rt::net::take_error(self.inner.as_raw_fd()) + .map(|e| e.map(map_motor_error)) + .map_err(map_motor_error) } pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { @@ -212,8 +213,9 @@ impl TcpListener { } pub fn take_error(&self) -> io::Result> { - let e = moto_rt::net::take_error(self.inner.as_raw_fd()).map_err(map_motor_error)?; - if e == moto_rt::E_OK { Ok(None) } else { Ok(Some(map_motor_error(e))) } + moto_rt::net::take_error(self.inner.as_raw_fd()) + .map(|e| e.map(map_motor_error)) + .map_err(map_motor_error) } pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { @@ -363,10 +365,7 @@ impl UdpSocket { pub fn take_error(&self) -> io::Result> { moto_rt::net::take_error(self.inner.as_raw_fd()) - .map(|e| match e { - moto_rt::E_OK => None, - e => Some(map_motor_error(e)), - }) + .map(|e| e.map(map_motor_error)) .map_err(map_motor_error) } @@ -414,10 +413,12 @@ impl TryFrom<&str> for LookupHost { fn try_from(host_port: &str) -> io::Result { let (host, port_str) = host_port .rsplit_once(':') - .ok_or(moto_rt::E_INVALID_ARGUMENT) + .ok_or(moto_rt::Error::InvalidArgument) + .map_err(map_motor_error)?; + let port: u16 = port_str + .parse() + .map_err(|_| moto_rt::Error::InvalidArgument) .map_err(map_motor_error)?; - let port: u16 = - port_str.parse().map_err(|_| moto_rt::E_INVALID_ARGUMENT).map_err(map_motor_error)?; (host, port).try_into() } } diff --git a/library/std/src/sys/pal/motor/mod.rs b/library/std/src/sys/pal/motor/mod.rs index 9bca264d78ea..e4860b1542f0 100644 --- a/library/std/src/sys/pal/motor/mod.rs +++ b/library/std/src/sys/pal/motor/mod.rs @@ -6,10 +6,11 @@ pub mod time; pub use moto_rt::futex; use crate::io as std_io; -use crate::sys::RawOsError; +use crate::sys::io::RawOsError; -pub(crate) fn map_motor_error(err: moto_rt::ErrorCode) -> crate::io::Error { - crate::io::Error::from_raw_os_error(err.into()) +pub(crate) fn map_motor_error(err: moto_rt::Error) -> crate::io::Error { + let error_code: moto_rt::ErrorCode = err.into(); + crate::io::Error::from_raw_os_error(error_code.into()) } #[cfg(not(test))] @@ -49,35 +50,36 @@ pub fn is_interrupted(_code: RawOsError) -> bool { } pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind { - use moto_rt::error::*; use std_io::ErrorKind; if code < 0 || code > u16::MAX.into() { return std_io::ErrorKind::Uncategorized; } - match code as moto_rt::ErrorCode /* u16 */ { - E_UNSPECIFIED => ErrorKind::Uncategorized, - E_UNKNOWN => ErrorKind::Uncategorized, - E_NOT_READY => ErrorKind::WouldBlock, - E_NOT_IMPLEMENTED => ErrorKind::Unsupported, - E_VERSION_TOO_HIGH => ErrorKind::Unsupported, - E_VERSION_TOO_LOW => ErrorKind::Unsupported, - E_INVALID_ARGUMENT => ErrorKind::InvalidInput, - E_OUT_OF_MEMORY => ErrorKind::OutOfMemory, - E_NOT_ALLOWED => ErrorKind::PermissionDenied, - E_NOT_FOUND => ErrorKind::NotFound, - E_INTERNAL_ERROR => ErrorKind::Other, - E_TIMED_OUT => ErrorKind::TimedOut, - E_ALREADY_IN_USE => ErrorKind::AlreadyExists, - E_UNEXPECTED_EOF => ErrorKind::UnexpectedEof, - E_INVALID_FILENAME => ErrorKind::InvalidFilename, - E_NOT_A_DIRECTORY => ErrorKind::NotADirectory, - E_BAD_HANDLE => ErrorKind::InvalidInput, - E_FILE_TOO_LARGE => ErrorKind::FileTooLarge, - E_NOT_CONNECTED => ErrorKind::NotConnected, - E_STORAGE_FULL => ErrorKind::StorageFull, - E_INVALID_DATA => ErrorKind::InvalidData, + let error = moto_rt::Error::from(code as moto_rt::ErrorCode); + + match error { + moto_rt::Error::Unspecified => ErrorKind::Uncategorized, + moto_rt::Error::Unknown => ErrorKind::Uncategorized, + moto_rt::Error::NotReady => ErrorKind::WouldBlock, + moto_rt::Error::NotImplemented => ErrorKind::Unsupported, + moto_rt::Error::VersionTooHigh => ErrorKind::Unsupported, + moto_rt::Error::VersionTooLow => ErrorKind::Unsupported, + moto_rt::Error::InvalidArgument => ErrorKind::InvalidInput, + moto_rt::Error::OutOfMemory => ErrorKind::OutOfMemory, + moto_rt::Error::NotAllowed => ErrorKind::PermissionDenied, + moto_rt::Error::NotFound => ErrorKind::NotFound, + moto_rt::Error::InternalError => ErrorKind::Other, + moto_rt::Error::TimedOut => ErrorKind::TimedOut, + moto_rt::Error::AlreadyInUse => ErrorKind::AlreadyExists, + moto_rt::Error::UnexpectedEof => ErrorKind::UnexpectedEof, + moto_rt::Error::InvalidFilename => ErrorKind::InvalidFilename, + moto_rt::Error::NotADirectory => ErrorKind::NotADirectory, + moto_rt::Error::BadHandle => ErrorKind::InvalidInput, + moto_rt::Error::FileTooLarge => ErrorKind::FileTooLarge, + moto_rt::Error::NotConnected => ErrorKind::NotConnected, + moto_rt::Error::StorageFull => ErrorKind::StorageFull, + moto_rt::Error::InvalidData => ErrorKind::InvalidData, _ => crate::io::ErrorKind::Uncategorized, } } diff --git a/library/std/src/sys/pal/motor/os.rs b/library/std/src/sys/pal/motor/os.rs index 052e3b238b6a..0367c905b453 100644 --- a/library/std/src/sys/pal/motor/os.rs +++ b/library/std/src/sys/pal/motor/os.rs @@ -4,7 +4,7 @@ use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; use crate::os::motor::ffi::OsStrExt; use crate::path::{self, PathBuf}; -use crate::sys::RawOsError; +use crate::sys::io::RawOsError; use crate::{fmt, io}; pub fn errno() -> RawOsError { @@ -22,16 +22,17 @@ pub fn errno() -> RawOsError { // separate runtime background/I/O thread, so it is really hard // to define what "last system error in the current thread" // actually means. - moto_rt::E_UNKNOWN.into() + let error_code: moto_rt::ErrorCode = moto_rt::Error::Unknown.into(); + error_code.into() } pub fn error_string(errno: RawOsError) -> String { - let error_code: moto_rt::ErrorCode = match errno { - x if x < 0 => moto_rt::E_UNKNOWN, - x if x > u16::MAX.into() => moto_rt::E_UNKNOWN, - x => x as moto_rt::ErrorCode, /* u16 */ + let error: moto_rt::Error = match errno { + x if x < 0 => moto_rt::Error::Unknown, + x if x > u16::MAX.into() => moto_rt::Error::Unknown, + x => (x as moto_rt::ErrorCode).into(), /* u16 */ }; - format!("{}", moto_rt::Error::from(error_code)) + format!("{}", error) } pub fn getcwd() -> io::Result { diff --git a/library/std/src/sys/process/motor.rs b/library/std/src/sys/process/motor.rs index 97b5a0fce2e4..a5d018447890 100644 --- a/library/std/src/sys/process/motor.rs +++ b/library/std/src/sys/process/motor.rs @@ -265,10 +265,7 @@ impl Process { } pub fn kill(&mut self) -> io::Result<()> { - match moto_rt::process::kill(self.handle) { - moto_rt::E_OK => Ok(()), - err => Err(map_motor_error(err)), - } + moto_rt::process::kill(self.handle).map_err(map_motor_error) } pub fn wait(&mut self) -> io::Result { @@ -279,7 +276,7 @@ impl Process { match moto_rt::process::try_wait(self.handle) { Ok(s) => Ok(Some(ExitStatus(s))), Err(err) => match err { - moto_rt::E_NOT_READY => Ok(None), + moto_rt::Error::NotReady => Ok(None), err => Err(map_motor_error(err)), }, } diff --git a/library/std/src/sys/thread/motor.rs b/library/std/src/sys/thread/motor.rs index 4c6d3ccb84ec..3c6df936b0ae 100644 --- a/library/std/src/sys/thread/motor.rs +++ b/library/std/src/sys/thread/motor.rs @@ -36,7 +36,7 @@ impl Thread { } pub fn join(self) { - assert!(moto_rt::thread::join(self.sys_thread) == moto_rt::E_OK) + assert!(moto_rt::thread::join(self.sys_thread).is_ok()) } } From 361888f763b707f982e02419684c716771d2146c Mon Sep 17 00:00:00 2001 From: dianqk Date: Sat, 20 Dec 2025 09:53:08 +0800 Subject: [PATCH 1064/3801] Update LLVM submodule --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 85a90d119deb..00d23d10dc48 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 85a90d119deb25b518867cd37d62c7b93b575a6f +Subproject commit 00d23d10dc48c6bb9d57ba96d4a748d85d77d0c7 From 3e5b12ed9a7d175a07c72fe7fa56c022264988bb Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 19 Dec 2025 15:22:28 -0500 Subject: [PATCH 1065/3801] Update cargo submodule --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index e91b2baa632c..3861f60f6b58 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit e91b2baa632c0c7e84216c91ecfe107c37d887c1 +Subproject commit 3861f60f6b58f57524c0e7aab1f5c1ad83e35409 From c3bd76b7afc20bb46c503d1a4edab9da82484f13 Mon Sep 17 00:00:00 2001 From: Redddy Date: Sat, 20 Dec 2025 15:22:41 +0900 Subject: [PATCH 1066/3801] Add Rustc Explore video link --- src/doc/rustc-dev-guide/src/appendix/compiler-lecture.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/appendix/compiler-lecture.md b/src/doc/rustc-dev-guide/src/appendix/compiler-lecture.md index 90c4097cc3e6..0bd4c6eb1339 100644 --- a/src/doc/rustc-dev-guide/src/appendix/compiler-lecture.md +++ b/src/doc/rustc-dev-guide/src/appendix/compiler-lecture.md @@ -6,6 +6,7 @@ These are videos where various experts explain different parts of the compiler: - [January 2019: Tom Tromey discusses debugging support in rustc](https://www.youtube.com/watch?v=elBxMRSNYr4) - [June 2019: Responsive compilers - Nicholas Matsakis - PLISS 2019](https://www.youtube.com/watch?v=N6b44kMS6OM) - [June 2019: Things I Learned (TIL) - Nicholas Matsakis - PLISS 2019](https://www.youtube.com/watch?v=LIYkT3p5gTs) +- [October 2022: Rustc Explore](https://www.youtube.com/playlist?list=PL85XCvVPmGQj3-MujOJ0jcoSqQ6Yi6Rkk) ## Rust Analyzer - [January 2019: How Salsa Works](https://www.youtube.com/watch?v=_muY4HjSqVw) @@ -46,4 +47,4 @@ These are videos where various experts explain different parts of the compiler: ## Code Generation - [January 2019: Cranelift](https://www.youtube.com/watch?v=9OIA7DTFQWU) -- [December 2024: LLVM Developers' Meeting - Rust ❤️ LLVM](https://www.youtube.com/watch?v=Kqz-umsAnk8) \ No newline at end of file +- [December 2024: LLVM Developers' Meeting - Rust ❤️ LLVM](https://www.youtube.com/watch?v=Kqz-umsAnk8) From 69c43e838df4d097c63079513edf3404f9541f0b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 20 Dec 2025 08:12:48 +0100 Subject: [PATCH 1067/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to f51d1bcdc69f9bba47cc1656260ff76e6ff5fba3. --- 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 d4fbfacf4eda..de0270f31fe5 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -526a91cbcc4601b92b0587405015e07b9c0d79f6 +f51d1bcdc69f9bba47cc1656260ff76e6ff5fba3 From 572ca1eb748f14b29b240a5028d72908fc4517f9 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Fri, 19 Sep 2025 04:58:26 +0000 Subject: [PATCH 1068/3801] rustc_codegen_llvm: Split "Fixed in LLVM 20" cases ... in `update_target_reliable_float_cfg`, based on the actual changes. The AArch64 issue is fixed on LLVM 20.1.1 while the MIPS issue is fixed on LLVM 20.1.0 (the first LLVM 20 release). This commit distinguishes two separate cases. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 2e1d0cfada5b..adb1ac09a633 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -364,11 +364,12 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { let target_abi = &sess.target.options.abi; let target_pointer_width = sess.target.pointer_width; let version = get_version(); + let lt_20_1_0 = version < (20, 1, 0); let lt_20_1_1 = version < (20, 1, 1); let lt_21_0_0 = version < (21, 0, 0); cfg.has_reliable_f16 = match (target_arch, target_os) { - // LLVM crash without neon (fixed in llvm20) + // LLVM crash without neon (fixed in LLVM 20.1.1) (Arch::AArch64, _) if !cfg.target_features.iter().any(|f| f.as_str() == "neon") && lt_20_1_1 => { @@ -395,8 +396,8 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { cfg.has_reliable_f128 = match (target_arch, target_os) { // Unsupported (Arch::Arm64EC, _) => false, - // Selection bug (fixed in llvm20) - (Arch::Mips64 | Arch::Mips64r6, _) if lt_20_1_1 => false, + // Selection bug (fixed in LLVM 20.1.0) + (Arch::Mips64 | Arch::Mips64r6, _) if lt_20_1_0 => false, // Selection bug . This issue is closed // but basic math still does not work. (Arch::Nvptx64, _) => false, From 28203e182f0d74577fee90d4fccd52fa98f72f07 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Fri, 19 Sep 2025 04:14:10 +0000 Subject: [PATCH 1069/3801] rustc_codegen_llvm: Simplify `update_target_reliable_float_cfg` This commit simplifies floating type handling through `update_target_reliable_float_cfg` based on several facts: 1. Major changes in behavior normally occurs only on the major LLVM upgrade. 2. The first release of LLVM 20.x.x is 20.1.0. Due to the first fact, we can normally ignore minor and patch releases of LLVM and we can remove obscure variables like `lt_xx_x_x` (still, there is a case where checking for patch version is required). The second fact is missed when the minimum LLVM version is raised to LLVM 20 and one "fixed in LLVM 20" case can be safely removed. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index adb1ac09a633..a3b1de9c3878 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -364,26 +364,25 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { let target_abi = &sess.target.options.abi; let target_pointer_width = sess.target.pointer_width; let version = get_version(); - let lt_20_1_0 = version < (20, 1, 0); - let lt_20_1_1 = version < (20, 1, 1); - let lt_21_0_0 = version < (21, 0, 0); + let (major, _, _) = version; cfg.has_reliable_f16 = match (target_arch, target_os) { // LLVM crash without neon (fixed in LLVM 20.1.1) (Arch::AArch64, _) - if !cfg.target_features.iter().any(|f| f.as_str() == "neon") && lt_20_1_1 => + if !cfg.target_features.iter().any(|f| f.as_str() == "neon") + && version < (20, 1, 1) => { false } // Unsupported (Arch::Arm64EC, _) => false, // Selection failure (fixed in llvm21) - (Arch::S390x, _) if lt_21_0_0 => false, + (Arch::S390x, _) if major < 21 => false, // MinGW ABI bugs (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, // Infinite recursion (Arch::CSky, _) => false, - (Arch::Hexagon, _) if lt_21_0_0 => false, // (fixed in llvm21) + (Arch::Hexagon, _) if major < 21 => false, // (fixed in llvm21) (Arch::PowerPC | Arch::PowerPC64, _) => false, (Arch::Sparc | Arch::Sparc64, _) => false, (Arch::Wasm32 | Arch::Wasm64, _) => false, @@ -397,7 +396,7 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // Unsupported (Arch::Arm64EC, _) => false, // Selection bug (fixed in LLVM 20.1.0) - (Arch::Mips64 | Arch::Mips64r6, _) if lt_20_1_0 => false, + (Arch::Mips64 | Arch::Mips64r6, _) if version < (20, 1, 0) => false, // Selection bug . This issue is closed // but basic math still does not work. (Arch::Nvptx64, _) => false, @@ -410,7 +409,7 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { (Arch::Sparc, _) => false, // Stack alignment bug . NB: tests may // not fail if our compiler-builtins is linked. (fixed in llvm21) - (Arch::X86, _) if lt_21_0_0 => false, + (Arch::X86, _) if major < 21 => false, // MinGW ABI bugs (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, // There are no known problems on other platforms, so the only requirement is that symbols From 42d9f099e0f703bf681ab5e5fa502193bab7ad9e Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Fri, 19 Sep 2025 04:14:10 +0000 Subject: [PATCH 1070/3801] rustc_codegen_llvm: Reorder by arch in `update_target_reliable_float_cfg` This commit reorders certain match clauses in `update_target_reliable_float_cfg` by the architecture when there's no problems reordering it. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index a3b1de9c3878..a5a8f8e6a25e 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -393,6 +393,8 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { }; cfg.has_reliable_f128 = match (target_arch, target_os) { + // Unsupported https://github.com/llvm/llvm-project/issues/121122 + (Arch::AmdGpu, _) => false, // Unsupported (Arch::Arm64EC, _) => false, // Selection bug (fixed in LLVM 20.1.0) @@ -400,8 +402,6 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // Selection bug . This issue is closed // but basic math still does not work. (Arch::Nvptx64, _) => false, - // Unsupported https://github.com/llvm/llvm-project/issues/121122 - (Arch::AmdGpu, _) => false, // ABI bugs et al. (full // list at ) (Arch::PowerPC | Arch::PowerPC64, _) => false, From d11ac79eeffab870de09ab62de1ef1383f38b429 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 20 Dec 2025 08:22:15 +0100 Subject: [PATCH 1071/3801] normalize file name changes away --- src/tools/miri/tests/panic/mir-validation.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/miri/tests/panic/mir-validation.rs b/src/tools/miri/tests/panic/mir-validation.rs index 11c4e395920c..4c863c5a9de8 100644 --- a/src/tools/miri/tests/panic/mir-validation.rs +++ b/src/tools/miri/tests/panic/mir-validation.rs @@ -5,6 +5,8 @@ //@normalize-stderr-test: "\n +\[\.\.\. omitted [0-9]+ frames? \.\.\.\].*" -> "" //@normalize-stderr-test: "\n[ =]*note:.*" -> "" //@normalize-stderr-test: "DefId\([^()]*\)" -> "DefId" +// Paths differ between bootstrap and stand-alone Miri runs, normalize them to be the same +//@normalize-stderr-test: "/rustc-dev/[^/]*/" -> "" // Somehow on rustc Windows CI, the "Miri caused an ICE" message is not shown // and we don't even get a regular panic; rustc aborts with a different exit code instead. //@ignore-host: windows From 19f74f46f999fda8910a596746dd595337be7139 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 20 Dec 2025 18:26:02 +1100 Subject: [PATCH 1072/3801] Use the same length type for `TestableCase::Slice` and `TestKind::Len` If we convert the minimum length to `u64` up-front when creating `TestableCase::Slice`, we can avoid more conversions to `u64` later. --- compiler/rustc_mir_build/src/builder/matches/buckets.rs | 4 ++-- compiler/rustc_mir_build/src/builder/matches/match_pair.rs | 2 +- compiler/rustc_mir_build/src/builder/matches/mod.rs | 2 +- compiler/rustc_mir_build/src/builder/matches/test.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs index 6c5f0ed28a82..8cbbb8e14095 100644 --- a/compiler/rustc_mir_build/src/builder/matches/buckets.rs +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -218,7 +218,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &TestKind::Len { len: test_len, op: BinOp::Eq }, &TestableCase::Slice { len, variable_length }, ) => { - match (test_len.cmp(&(len as u64)), variable_length) { + match (test_len.cmp(&len), variable_length) { (Ordering::Equal, false) => { // on true, min_len = len = $actual_length, // on false, len != $actual_length @@ -251,7 +251,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &TestableCase::Slice { len, variable_length }, ) => { // the test is `$actual_len >= test_len` - match (test_len.cmp(&(len as u64)), variable_length) { + match (test_len.cmp(&len), variable_length) { (Ordering::Equal, true) => { // $actual_len >= test_len = pat_len, // so we can match. diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 6b4ba9243479..9b9ee1836956 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -256,7 +256,7 @@ impl<'tcx> MatchPairTree<'tcx> { None } else { Some(TestableCase::Slice { - len: prefix.len() + suffix.len(), + len: u64::try_from(prefix.len() + suffix.len()).unwrap(), variable_length: slice.is_some(), }) } diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 66e36a99d3c4..8897ca7c7210 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1264,7 +1264,7 @@ enum TestableCase<'tcx> { Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx }, Constant { value: ty::Value<'tcx> }, Range(Arc>), - Slice { len: usize, variable_length: bool }, + Slice { len: u64, variable_length: bool }, Deref { temp: Place<'tcx>, mutability: Mutability }, Never, Or { pats: Box<[FlatPat<'tcx>]> }, diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 55e21ff18aae..402587bff7e8 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -47,7 +47,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TestableCase::Slice { len, variable_length } => { let op = if variable_length { BinOp::Ge } else { BinOp::Eq }; - TestKind::Len { len: len as u64, op } + TestKind::Len { len, op } } TestableCase::Deref { temp, mutability } => TestKind::Deref { temp, mutability }, From 354adbce4463b460e77d3bcb45789b1a5688af63 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sat, 20 Dec 2025 09:14:50 +0100 Subject: [PATCH 1073/3801] Do not attempt to use `nth` with non-usize argument --- clippy_lints/src/methods/needless_collect.rs | 4 +++- tests/ui/needless_collect.fixed | 5 +++++ tests/ui/needless_collect.rs | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 055fdcabdd21..0e2012319147 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -81,7 +81,9 @@ pub(super) fn check<'tcx>( }, _ => return, }; - } else if let ExprKind::Index(_, index, _) = parent.kind { + } else if let ExprKind::Index(_, index, _) = parent.kind + && cx.typeck_results().expr_ty(index).is_usize() + { app = Applicability::MaybeIncorrect; let snip = snippet_with_applicability(cx, index.span, "_", &mut app); sugg = format!("nth({snip}).unwrap()"); diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index ba1451bf9704..99027e79b664 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -214,3 +214,8 @@ mod issue8055_regression { .len(); } } + +fn issue16270() { + // Do not lint, `..` implements `Index` but is not `usize` + _ = &(1..3).collect::>()[..]; +} diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index e054cd01e6f5..683cc49c9af3 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -214,3 +214,8 @@ mod issue8055_regression { .len(); } } + +fn issue16270() { + // Do not lint, `..` implements `Index` but is not `usize` + _ = &(1..3).collect::>()[..]; +} From c97d202d20c641b32c051e1ccbb37d45ee2702c5 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sat, 20 Dec 2025 09:41:52 +0100 Subject: [PATCH 1074/3801] Preserve explicit lifetime information when removing `mut` Rather than trying to reconstruct the reference type without the `mut`, remove the `mut` itself so that user-inserted lifetime information is preserved. The message has been changed from "consider changing to [NON-MUT REF]" to "remove this `mut`" --- clippy_lints/src/needless_pass_by_ref_mut.rs | 19 ++- .../needless_pass_by_ref_mut.stderr | 4 +- tests/ui/needless_pass_by_ref_mut.stderr | 136 +++++++++++++----- tests/ui/needless_pass_by_ref_mut2.fixed | 6 + tests/ui/needless_pass_by_ref_mut2.rs | 6 + tests/ui/needless_pass_by_ref_mut2.stderr | 18 ++- 6 files changed, 146 insertions(+), 43 deletions(-) diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 3d2285efbe18..904ff538ba36 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -1,7 +1,7 @@ use super::needless_pass_by_value::requires_exact_signature; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_hir_and_then; -use clippy_utils::source::snippet; +use clippy_utils::source::HasSession as _; use clippy_utils::visitors::for_each_expr; use clippy_utils::{inherits_cfg, is_from_proc_macro, is_self}; use core::ops::ControlFlow; @@ -18,9 +18,9 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath}; use rustc_session::impl_lint_pass; -use rustc_span::Span; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does @@ -269,6 +269,15 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { // If the argument is never used mutably, we emit the warning. let sp = input.span; if let rustc_hir::TyKind::Ref(_, inner_ty) = input.kind { + let Some(after_mut_span) = cx.sess().source_map().span_extend_to_prev_str( + inner_ty.ty.span.shrink_to_lo(), + "mut", + true, + true, + ) else { + return; + }; + let mut_span = after_mut_span.with_lo(after_mut_span.lo() - BytePos(3)); let is_cfged = is_cfged.get_or_insert_with(|| inherits_cfg(cx.tcx, *fn_def_id)); span_lint_hir_and_then( cx, @@ -278,9 +287,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { "this argument is a mutable reference, but not used mutably", |diag| { diag.span_suggestion( - sp, - "consider changing to".to_string(), - format!("&{}", snippet(cx, cx.tcx.hir_span(inner_ty.ty.hir_id), "_"),), + mut_span, + "consider removing this `mut`", + "", Applicability::Unspecified, ); if cx.effective_visibilities.is_exported(*fn_def_id) { diff --git a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr index c10607bf4bab..f79b20ec69fc 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr @@ -2,7 +2,9 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs:5:19 | LL | pub fn pub_foo(s: &mut Vec, b: &u32, x: &mut u32) { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` | = warning: changing this function will impact semver compatibility = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr index 94d98f0e9b12..90d99b9f0cf6 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -2,7 +2,9 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:12:11 | LL | fn foo(s: &mut Vec, b: &u32, x: &mut u32) { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` | = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` @@ -11,79 +13,105 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:38:12 | LL | fn foo6(s: &mut Vec) { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:49:12 | LL | fn bar(&mut self) {} - | ^^^^^^^^^ help: consider changing to: `&self` + | ^----^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:52:29 | LL | fn mushroom(&self, vec: &mut Vec) -> usize { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:130:16 | LL | async fn a1(x: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:135:16 | LL | async fn a2(x: &mut i32, y: String) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:140:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:145:16 | LL | async fn a4(x: &mut i32, y: i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:150:24 | LL | async fn a5(x: i32, y: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:155:24 | LL | async fn a6(x: i32, y: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:160:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:165:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:165:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:201:16 | LL | fn cfg_warn(s: &mut u32) {} - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` | = note: this is cfg-gated and may require further changes @@ -91,7 +119,9 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:206:20 | LL | fn cfg_warn(s: &mut u32) {} - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` | = note: this is cfg-gated and may require further changes @@ -99,115 +129,153 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:219:39 | LL | async fn inner_async2(x: &mut i32, y: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:228:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:248:30 | LL | async fn call_in_closure1(n: &mut str) { - | ^^^^^^^^ help: consider changing to: `&str` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:268:16 | LL | fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { - | ^^^^^^^^^^ help: consider changing to: `&usize` + | ^----^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:280:22 | LL | async fn closure4(n: &mut usize) { - | ^^^^^^^^^^ help: consider changing to: `&usize` + | ^----^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:335:12 | LL | fn bar(&mut self) {} - | ^^^^^^^^^ help: consider changing to: `&self` + | ^----^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:338:18 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { - | ^^^^^^^^^ help: consider changing to: `&self` + | ^----^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:338:45 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:347:46 | LL | async fn foo2(&mut self, u: &mut i32, v: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:364:18 | LL | fn _empty_tup(x: &mut (())) {} - | ^^^^^^^^^ help: consider changing to: `&()` + | ^^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:366:19 | LL | fn _single_tup(x: &mut ((i32,))) {} - | ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)` + | ^^----^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:368:18 | LL | fn _multi_tup(x: &mut ((i32, u32))) {} - | ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)` + | ^^----^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:370:11 | LL | fn _fn(x: &mut (fn())) {} - | ^^^^^^^^^^^ help: consider changing to: `&fn()` + | ^^----^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:373:23 | LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()` + | ^----^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:375:20 | LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} - | ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()` + | ^----^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:377:18 | LL | fn _unsafe_fn(x: &mut unsafe fn()) {} - | ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()` + | ^----^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:379:25 | LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()` + | ^----^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:381:20 | LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)` + | ^----^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:383:20 | LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)` + | ^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: aborting due to 34 previous errors diff --git a/tests/ui/needless_pass_by_ref_mut2.fixed b/tests/ui/needless_pass_by_ref_mut2.fixed index 0e2ac0202364..c462f1cc8d87 100644 --- a/tests/ui/needless_pass_by_ref_mut2.fixed +++ b/tests/ui/needless_pass_by_ref_mut2.fixed @@ -24,3 +24,9 @@ async fn inner_async4(u: &mut i32, v: &u32) { } fn main() {} + +//~v needless_pass_by_ref_mut +fn issue16267<'a>(msg: &str, slice: &'a [i32]) -> &'a [i32] { + println!("{msg}"); + &slice[0..5] +} diff --git a/tests/ui/needless_pass_by_ref_mut2.rs b/tests/ui/needless_pass_by_ref_mut2.rs index 9201d9a27298..b00f294c57f0 100644 --- a/tests/ui/needless_pass_by_ref_mut2.rs +++ b/tests/ui/needless_pass_by_ref_mut2.rs @@ -24,3 +24,9 @@ async fn inner_async4(u: &mut i32, v: &mut u32) { } fn main() {} + +//~v needless_pass_by_ref_mut +fn issue16267<'a>(msg: &str, slice: &'a mut [i32]) -> &'a [i32] { + println!("{msg}"); + &slice[0..5] +} diff --git a/tests/ui/needless_pass_by_ref_mut2.stderr b/tests/ui/needless_pass_by_ref_mut2.stderr index 9876a6b50718..6af8a4d4a2b5 100644 --- a/tests/ui/needless_pass_by_ref_mut2.stderr +++ b/tests/ui/needless_pass_by_ref_mut2.stderr @@ -2,7 +2,9 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut2.rs:8:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` | = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` @@ -11,7 +13,17 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut2.rs:17:39 | LL | async fn inner_async4(u: &mut i32, v: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: aborting due to 2 previous errors +error: this argument is a mutable reference, but not used mutably + --> tests/ui/needless_pass_by_ref_mut2.rs:29:37 + | +LL | fn issue16267<'a>(msg: &str, slice: &'a mut [i32]) -> &'a [i32] { + | ^^^^----^^^^^ + | | + | help: consider removing this `mut` + +error: aborting due to 3 previous errors From 889ad15b62c46ed81187d27df8cc762226ae4520 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 20 Dec 2025 11:02:37 +0100 Subject: [PATCH 1075/3801] interpreter/visitor: always iterate in in-memory order --- .../rustc_const_eval/src/interpret/visitor.rs | 17 +---------------- src/tools/miri/src/helpers.rs | 7 ------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 95106c7c143b..a8d472bc2ea2 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -4,7 +4,6 @@ use std::num::NonZero; use rustc_abi::{FieldIdx, FieldsShape, VariantIdx, Variants}; -use rustc_index::{Idx as _, IndexVec}; use rustc_middle::mir::interpret::InterpResult; use rustc_middle::ty::{self, Ty}; use tracing::trace; @@ -24,20 +23,6 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { self.ecx().read_discriminant(&v.to_op(self.ecx())?) } - /// This function provides the chance to reorder the order in which fields are visited for - /// `FieldsShape::Aggregate`. - /// - /// The default means we iterate in source declaration order; alternatively this can use - /// `in_memory_order` to iterate in memory order. - #[inline(always)] - fn aggregate_field_iter( - in_memory_order: &IndexVec, - ) -> impl Iterator { - // Allow the optimizer to elide the bounds checking when creating each index. - let _ = FieldIdx::new(in_memory_order.len()); - (0..in_memory_order.len()).map(FieldIdx::new) - } - // Recursive actions, ready to be overloaded. /// Visits the given value, dispatching as appropriate to more specialized visitors. #[inline(always)] @@ -171,7 +156,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { self.visit_union(v, fields)?; } FieldsShape::Arbitrary { in_memory_order, .. } => { - for idx in Self::aggregate_field_iter(in_memory_order) { + for idx in in_memory_order.iter().copied() { let field = self.ecx().project_field(v, idx)?; self.visit_field(v, idx.as_usize(), &field)?; } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 218e4ffe5e2f..f4fc478481a7 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -10,7 +10,6 @@ use rustc_data_structures::fx::{FxBuildHasher, FxHashSet}; use rustc_hir::Safety; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefId, LOCAL_CRATE}; -use rustc_index::IndexVec; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::ExportedSymbol; @@ -583,12 +582,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { self.ecx } - fn aggregate_field_iter( - in_memory_order: &IndexVec, - ) -> impl Iterator { - in_memory_order.iter().copied() - } - // Hook to detect `UnsafeCell`. fn visit_value(&mut self, v: &MPlaceTy<'tcx>) -> InterpResult<'tcx> { trace!("UnsafeCellVisitor: {:?} {:?}", *v, v.layout.ty); From 462a8b34104a9b58932654937e55ed82e492b4f2 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Mon, 3 Nov 2025 07:45:02 +0200 Subject: [PATCH 1076/3801] Dogfood `strip_circumfix` --- compiler/rustc_metadata/src/errors.rs | 4 +--- compiler/rustc_metadata/src/lib.rs | 1 + .../rustc_trait_selection/src/error_reporting/infer/mod.rs | 5 ++--- compiler/rustc_trait_selection/src/lib.rs | 1 + 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index abfd078f7462..af8ff5643f2c 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -251,9 +251,7 @@ impl<'a> MissingNativeLibrary<'a> { // if it looks like the user has provided a complete filename rather just the bare lib name, // then provide a note that they might want to try trimming the name let suggested_name = if !verbatim { - if let Some(libname) = libname.strip_prefix("lib") - && let Some(libname) = libname.strip_suffix(".a") - { + if let Some(libname) = libname.strip_circumfix("lib", ".a") { // this is a unix style filename so trim prefix & suffix Some(libname) } else if let Some(libname) = libname.strip_suffix(".lib") { diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index f31c4938e118..f3b738f93d2d 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -10,6 +10,7 @@ #![feature(never_type)] #![feature(proc_macro_internals)] #![feature(result_option_map_or_default)] +#![feature(strip_circumfix)] #![feature(trusted_len)] // tidy-alphabetical-end diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 32be23eed765..4de3ba3e2781 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1758,8 +1758,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // specify a byte literal (ty::Uint(ty::UintTy::U8), ty::Char) => { if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) - && let Some(code) = - code.strip_prefix('\'').and_then(|s| s.strip_suffix('\'')) + && let Some(code) = code.strip_circumfix('\'', '\'') // forbid all Unicode escapes && !code.starts_with("\\u") // forbids literal Unicode characters beyond ASCII @@ -1776,7 +1775,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // specify a character literal (issue #92479) (ty::Char, ty::Ref(_, r, _)) if r.is_str() => { if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) - && let Some(code) = code.strip_prefix('"').and_then(|s| s.strip_suffix('"')) + && let Some(code) = code.strip_circumfix('"', '"') && code.chars().count() == 1 { suggestions.push(TypeErrorAdditionalDiags::MeantCharLiteral { diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 0184b2ccde78..6705d271bc7d 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -22,6 +22,7 @@ #![feature(iter_intersperse)] #![feature(iterator_try_reduce)] #![feature(never_type)] +#![feature(strip_circumfix)] #![feature(try_blocks)] #![feature(unwrap_infallible)] #![feature(yeet_expr)] From 5d8a096afeb4cd9b7ef7693aa6692afe71fbf5bc Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 19 Dec 2025 14:46:18 +0000 Subject: [PATCH 1077/3801] change non-canonical clone impl to {*self}, fix some doc comments --- compiler/rustc_graphviz/src/lib.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_pattern_analysis/src/lib.rs | 2 +- compiler/rustc_pattern_analysis/src/pat.rs | 5 +---- compiler/rustc_pattern_analysis/src/usefulness.rs | 2 +- compiler/rustc_thread_pool/src/registry.rs | 14 ++++++-------- 6 files changed, 11 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 9f75578aa636..cd1e573ea28d 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -416,7 +416,7 @@ impl<'a> Id<'a> { /// it in the generated .dot file. They can also provide more /// elaborate (and non-unique) label text that is used in the graphviz /// rendered output. - +/// /// The graph instance is responsible for providing the DOT compatible /// identifiers for the nodes and (optionally) rendered labels for the nodes and /// edges, as well as an identifier for the graph itself. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 471bd1d937e9..9e4692b96418 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2654,7 +2654,7 @@ struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T); impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> { fn clone(&self) -> Self { - InternedInSet(self.0) + *self } } diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index d9bb93a829b5..f3308086ddc6 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -141,7 +141,7 @@ pub struct MatchArm<'p, Cx: PatCx> { impl<'p, Cx: PatCx> Clone for MatchArm<'p, Cx> { fn clone(&self) -> Self { - Self { pat: self.pat, has_guard: self.has_guard, arm_data: self.arm_data } + *self } } diff --git a/compiler/rustc_pattern_analysis/src/pat.rs b/compiler/rustc_pattern_analysis/src/pat.rs index 901b72e53995..51d0703f9c5c 100644 --- a/compiler/rustc_pattern_analysis/src/pat.rs +++ b/compiler/rustc_pattern_analysis/src/pat.rs @@ -174,10 +174,7 @@ pub(crate) enum PatOrWild<'p, Cx: PatCx> { impl<'p, Cx: PatCx> Clone for PatOrWild<'p, Cx> { fn clone(&self) -> Self { - match self { - PatOrWild::Wild => PatOrWild::Wild, - PatOrWild::Pat(pat) => PatOrWild::Pat(pat), - } + *self } } diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 19446a1efe9c..971616b18914 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -824,7 +824,7 @@ struct PlaceCtxt<'a, Cx: PatCx> { impl<'a, Cx: PatCx> Copy for PlaceCtxt<'a, Cx> {} impl<'a, Cx: PatCx> Clone for PlaceCtxt<'a, Cx> { fn clone(&self) -> Self { - Self { cx: self.cx, ty: self.ty } + *self } } diff --git a/compiler/rustc_thread_pool/src/registry.rs b/compiler/rustc_thread_pool/src/registry.rs index 4a018ea743ae..92bb8961e7df 100644 --- a/compiler/rustc_thread_pool/src/registry.rs +++ b/compiler/rustc_thread_pool/src/registry.rs @@ -153,8 +153,8 @@ pub struct Registry { terminate_count: AtomicUsize, } -/// //////////////////////////////////////////////////////////////////////// -/// Initialization +/////////////////////////////////////////////////////////////////////////// +// Initialization static mut THE_REGISTRY: Option> = None; static THE_REGISTRY_SET: Once = Once::new(); @@ -407,12 +407,12 @@ impl Registry { } } - /// //////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// /// MAIN LOOP /// /// So long as all of the worker threads are hanging out in their /// top-level loop, there is no work to be done. - + /// /// Push a job into the given `registry`. If we are running on a /// worker thread for the registry, this will push onto the /// deque. Else, it will inject from the outside (which is slower). @@ -668,8 +668,8 @@ impl ThreadInfo { } } -/// //////////////////////////////////////////////////////////////////////// -/// WorkerThread identifiers +/////////////////////////////////////////////////////////////////////////// +// WorkerThread identifiers pub(super) struct WorkerThread { /// the "worker" half of our local deque @@ -1019,8 +1019,6 @@ impl WorkerThread { } } -/// //////////////////////////////////////////////////////////////////////// - unsafe fn main_loop(thread: ThreadBuilder) { let worker_thread = &WorkerThread::from(thread); unsafe { WorkerThread::set_current(worker_thread) }; From 120f0d4f07ef21a615ac40362e0acb4d803fcb37 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sat, 20 Dec 2025 15:35:52 +0100 Subject: [PATCH 1078/3801] Port `#[thread_local]` to attribute parser --- .../src/attributes/codegen_attrs.rs | 10 ++++++ compiler/rustc_attr_parsing/src/context.rs | 3 +- .../rustc_codegen_ssa/src/codegen_attrs.rs | 4 ++- .../rustc_hir/src/attrs/data_structures.rs | 3 ++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/messages.ftl | 4 --- compiler/rustc_passes/src/check_attr.rs | 15 +------- compiler/rustc_passes/src/errors.rs | 9 ----- tests/ui/attributes/malformed-attrs.stderr | 15 ++++---- tests/ui/thread-local/non-static.rs | 8 ++--- tests/ui/thread-local/non-static.stderr | 34 ++++++++----------- 11 files changed, 48 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index e59f70877c94..c68c66b27185 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -690,6 +690,16 @@ impl SingleAttributeParser for SanitizeParser { } } +pub(crate) struct ThreadLocalParser; + +impl NoArgsAttributeParser for ThreadLocalParser { + const PATH: &[Symbol] = &[sym::thread_local]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ThreadLocal; +} + pub(crate) struct RustcPassIndirectlyInNonRusticAbisParser; impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index a752869c2eb2..df4970d8aa90 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -23,7 +23,7 @@ use crate::attributes::codegen_attrs::{ ColdParser, CoverageParser, EiiExternItemParser, ExportNameParser, ForceTargetFeatureParser, NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser, RustcPassIndirectlyInNonRusticAbisParser, SanitizeParser, TargetFeatureParser, - TrackCallerParser, UsedParser, + ThreadLocalParser, TrackCallerParser, UsedParser, }; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::crate_level::{ @@ -269,6 +269,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 473598bad394..8135fd43dd93 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -350,6 +350,9 @@ fn process_builtin_attrs( codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM; } } + AttributeKind::ThreadLocal => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL + } _ => {} } } @@ -366,7 +369,6 @@ fn process_builtin_attrs( sym::rustc_allocator_zeroed => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } - sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL, sym::instruction_set => { codegen_fn_attrs.instruction_set = parse_instruction_set_attr(tcx, attr) } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 1a382d8f124b..e9f9b2445deb 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1010,6 +1010,9 @@ pub enum AttributeKind { /// `#[unsafe(force_target_feature(enable = "...")]`. TargetFeature { features: ThinVec<(Symbol, Span)>, attr_span: Span, was_forced: bool }, + /// Represents `#[thread_local]` + ThreadLocal, + /// Represents `#[track_caller]` TrackCaller(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 7c1e71f258be..68456dfe4c29 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -114,6 +114,7 @@ impl AttributeKind { Stability { .. } => Yes, StdInternalSymbol(..) => No, TargetFeature { .. } => No, + ThreadLocal => No, TrackCaller(..) => Yes, TypeConst(..) => Yes, TypeLengthLimit { .. } => No, diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index c0106ea0c627..cf069b364be8 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -484,10 +484,6 @@ passes_sanitize_attribute_not_allowed = .no_body = function has no body .help = sanitize attribute can be applied to a function (with body), impl block, or module -passes_should_be_applied_to_static = - attribute should be applied to a static - .label = not a static - passes_should_be_applied_to_trait = attribute should be applied to a trait .label = not a trait diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 945dcec798e3..7822614a05cb 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -297,6 +297,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) | AttributeKind::PinV2(..) | AttributeKind::WindowsSubsystem(..) + | AttributeKind::ThreadLocal ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -310,7 +311,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::diagnostic, sym::on_const, ..] => { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } - [sym::thread_local, ..] => self.check_thread_local(attr, span, target), [sym::rustc_clean, ..] | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] @@ -768,19 +768,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks if the `#[thread_local]` attribute on `item` is valid. - fn check_thread_local(&self, attr: &Attribute, span: Span, target: Target) { - match target { - Target::ForeignStatic | Target::Static => {} - _ => { - self.dcx().emit_err(errors::AttrShouldBeAppliedToStatic { - attr_span: attr.span(), - defn_span: span, - }); - } - } - } - fn check_doc_alias_value(&self, span: Span, hir_id: HirId, target: Target, alias: Symbol) { if let Some(location) = match target { Target::AssocTy => { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 4f97f74c7804..2b817c6dd106 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -98,15 +98,6 @@ pub(crate) struct AttrShouldBeAppliedToTrait { pub defn_span: Span, } -#[derive(Diagnostic)] -#[diag(passes_should_be_applied_to_static)] -pub(crate) struct AttrShouldBeAppliedToStatic { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - #[derive(Diagnostic)] #[diag(passes_doc_alias_bad_location)] pub(crate) struct DocAliasBadLocation<'a> { diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 228ea12cba8b..d0e5cb631c1e 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -141,12 +141,6 @@ LL | #[forbid(lint1, lint2, ...)] LL | #[forbid(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ -error: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:210:1 - | -LL | #[thread_local()] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` - error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type --> $DIR/malformed-attrs.rs:105:1 | @@ -618,6 +612,15 @@ LL | #[non_exhaustive = 1] | | didn't expect any arguments here | help: must be of the form: `#[non_exhaustive]` +error[E0565]: malformed `thread_local` attribute input + --> $DIR/malformed-attrs.rs:210:1 + | +LL | #[thread_local()] + | ^^^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[thread_local]` + error[E0565]: malformed `no_link` attribute input --> $DIR/malformed-attrs.rs:214:1 | diff --git a/tests/ui/thread-local/non-static.rs b/tests/ui/thread-local/non-static.rs index f1c4273870bf..f14ff20f449b 100644 --- a/tests/ui/thread-local/non-static.rs +++ b/tests/ui/thread-local/non-static.rs @@ -2,19 +2,19 @@ #![feature(thread_local)] #[thread_local] -//~^ ERROR attribute should be applied to a static +//~^ ERROR `#[thread_local]` attribute cannot be used on constants const A: u32 = 0; #[thread_local] -//~^ ERROR attribute should be applied to a static +//~^ ERROR `#[thread_local]` attribute cannot be used on functions fn main() { #[thread_local] || {}; - //~^ ERROR attribute should be applied to a static + //~^ ERROR `#[thread_local]` attribute cannot be used on closures } struct S { #[thread_local] - //~^ ERROR attribute should be applied to a static + //~^ ERROR `#[thread_local]` attribute cannot be used on struct fields a: String, b: String, } diff --git a/tests/ui/thread-local/non-static.stderr b/tests/ui/thread-local/non-static.stderr index 09a1618d6e71..c83a6beb4c6a 100644 --- a/tests/ui/thread-local/non-static.stderr +++ b/tests/ui/thread-local/non-static.stderr @@ -1,38 +1,34 @@ -error: attribute should be applied to a static +error: `#[thread_local]` attribute cannot be used on constants --> $DIR/non-static.rs:4:1 | LL | #[thread_local] | ^^^^^^^^^^^^^^^ -LL | -LL | const A: u32 = 0; - | ----------------- not a static + | + = help: `#[thread_local]` can be applied to foreign statics and statics -error: attribute should be applied to a static +error: `#[thread_local]` attribute cannot be used on functions --> $DIR/non-static.rs:8:1 | -LL | #[thread_local] - | ^^^^^^^^^^^^^^^ -LL | -LL | / fn main() { -LL | | #[thread_local] || {}; -LL | | -LL | | } - | |_- not a static +LL | #[thread_local] + | ^^^^^^^^^^^^^^^ + | + = help: `#[thread_local]` can be applied to foreign statics and statics -error: attribute should be applied to a static +error: `#[thread_local]` attribute cannot be used on closures --> $DIR/non-static.rs:11:5 | LL | #[thread_local] || {}; - | ^^^^^^^^^^^^^^^ ----- not a static + | ^^^^^^^^^^^^^^^ + | + = help: `#[thread_local]` can be applied to foreign statics and statics -error: attribute should be applied to a static +error: `#[thread_local]` attribute cannot be used on struct fields --> $DIR/non-static.rs:16:5 | LL | #[thread_local] | ^^^^^^^^^^^^^^^ -LL | -LL | a: String, - | --------- not a static + | + = help: `#[thread_local]` can be applied to foreign statics and statics error: aborting due to 4 previous errors From 7b7ee8463f0b21e7cf2c6dc57ea8c026bc2f5829 Mon Sep 17 00:00:00 2001 From: Redddy Date: Sun, 21 Dec 2025 00:26:51 +0900 Subject: [PATCH 1079/3801] Add title field to ICE issue template --- .github/ISSUE_TEMPLATE/ice.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/ice.md b/.github/ISSUE_TEMPLATE/ice.md index 2afcd210a6eb..1ab1ddf46016 100644 --- a/.github/ISSUE_TEMPLATE/ice.md +++ b/.github/ISSUE_TEMPLATE/ice.md @@ -2,6 +2,7 @@ name: Internal Compiler Error about: Create a report for an internal compiler error in rustc. labels: C-bug, I-ICE, T-compiler +title: "[ICE]: " --- tests/ui/new_without_default.rs:340:9 + | +LL | / pub fn new() -> Self +LL | | +LL | | where +LL | | T: Clone, +LL | | { +LL | | Self { marker: PhantomData } +LL | | } + | |_________^ + | +help: try adding this + | +LL ~ impl Default for Foo +LL + where +LL + T: Display, +LL + T: Clone, +LL + { +LL + fn default() -> Self { +LL + Self::new() +LL + } +LL + } +LL + +LL ~ impl Foo + | + +error: you should consider adding a `Default` implementation for `Bar` + --> tests/ui/new_without_default.rs:354:9 + | +LL | / pub fn new() -> Self +LL | | +LL | | where +LL | | T: Clone, +LL | | { +LL | | Self { marker: PhantomData } +LL | | } + | |_________^ + | +help: try adding this + | +LL ~ impl Default for Bar +LL + where +LL + T: Clone, +LL + { +LL + fn default() -> Self { +LL + Self::new() +LL + } +LL + } +LL + +LL ~ impl Bar { + | + +error: aborting due to 15 previous errors From 4c4b2a1dbe8692196df6f4f117c2f074b410fa81 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 20 Dec 2025 18:53:58 +0000 Subject: [PATCH 1089/3801] fix: `str_to_string` wrongly unmangled macros --- clippy_lints/src/strings.rs | 5 +++-- tests/ui/str_to_string.fixed | 14 ++++++++++++++ tests/ui/str_to_string.rs | 14 ++++++++++++++ tests/ui/str_to_string.stderr | 8 +++++++- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 1d0efa46a14c..609504ffc233 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::res::{MaybeDef, MaybeQPath}; -use clippy_utils::source::{snippet, snippet_with_applicability}; +use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context}; use clippy_utils::{ SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, method_calls, peel_blocks, sym, }; @@ -404,7 +404,8 @@ impl<'tcx> LateLintPass<'tcx> for StrToString { "`to_string()` called on a `&str`", |diag| { let mut applicability = Applicability::MachineApplicable; - let snippet = snippet_with_applicability(cx, self_arg.span, "..", &mut applicability); + let (snippet, _) = + snippet_with_context(cx, self_arg.span, expr.span.ctxt(), "..", &mut applicability); diag.span_suggestion(expr.span, "try", format!("{snippet}.to_owned()"), applicability); }, ); diff --git a/tests/ui/str_to_string.fixed b/tests/ui/str_to_string.fixed index 2941c4dbd33d..8713c4f9bc86 100644 --- a/tests/ui/str_to_string.fixed +++ b/tests/ui/str_to_string.fixed @@ -8,3 +8,17 @@ fn main() { msg.to_owned(); //~^ str_to_string } + +fn issue16271(key: &[u8]) { + macro_rules! t { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + } + }; + } + + let _value = t!(str::from_utf8(key)).to_owned(); + //~^ str_to_string +} diff --git a/tests/ui/str_to_string.rs b/tests/ui/str_to_string.rs index 4c4d2bb18062..b81759e1037b 100644 --- a/tests/ui/str_to_string.rs +++ b/tests/ui/str_to_string.rs @@ -8,3 +8,17 @@ fn main() { msg.to_string(); //~^ str_to_string } + +fn issue16271(key: &[u8]) { + macro_rules! t { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + } + }; + } + + let _value = t!(str::from_utf8(key)).to_string(); + //~^ str_to_string +} diff --git a/tests/ui/str_to_string.stderr b/tests/ui/str_to_string.stderr index cb7b6b48843a..c0a38c8ebe46 100644 --- a/tests/ui/str_to_string.stderr +++ b/tests/ui/str_to_string.stderr @@ -13,5 +13,11 @@ error: `to_string()` called on a `&str` LL | msg.to_string(); | ^^^^^^^^^^^^^^^ help: try: `msg.to_owned()` -error: aborting due to 2 previous errors +error: `to_string()` called on a `&str` + --> tests/ui/str_to_string.rs:22:18 + | +LL | let _value = t!(str::from_utf8(key)).to_string(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t!(str::from_utf8(key)).to_owned()` + +error: aborting due to 3 previous errors From b7a0f84a5aef6b097636c29408c8bddf89a711bf Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 20 Dec 2025 20:35:30 +0100 Subject: [PATCH 1090/3801] tests/debuginfo/function-arg-initialization.rs: Stop disabling SingleUseConsts MIR pass --- tests/debuginfo/function-arg-initialization.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/debuginfo/function-arg-initialization.rs b/tests/debuginfo/function-arg-initialization.rs index c3b7ed81d026..78fecd8a4bfe 100644 --- a/tests/debuginfo/function-arg-initialization.rs +++ b/tests/debuginfo/function-arg-initialization.rs @@ -6,8 +6,7 @@ // function name. //@ min-lldb-version: 1800 -//@ compile-flags:-g -Zmir-enable-passes=-SingleUseConsts -// SingleUseConsts shouldn't need to be disabled, see #128945 +//@ compile-flags:-g //@ disable-gdb-pretty-printers //@ ignore-backends: gcc From 8825e1fe5d3a142228277f0df36dae19310a723f Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 17 Dec 2025 10:32:13 +0100 Subject: [PATCH 1091/3801] library/coretests/tests/fmt/mod.rs: Add HRTB fn pointer case --- library/coretests/tests/fmt/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index d0ae7124f474..0fb099ef4191 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -30,6 +30,12 @@ fn test_format_flags() { assert_eq!(format!("{:p} {:x}", p, 16), format!("{p:p} 10")); assert_eq!(format!("{: >3}", 'a'), " a"); + + /// Regression test for . + fn show(a: fn() -> f32, b: fn(&Vec) -> f32) { + println!("the two pointers: {:p} {:p}", a, b); + } + show(|| 1.0, |_| 2.0); } #[test] From cd8cc6ff3840825681e1971f8557ddae1baa1559 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 20 Dec 2025 16:43:54 -0500 Subject: [PATCH 1092/3801] Update to nightly-2025-12-20 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index f9645451e964..86ae738d4483 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-11-24" +channel = "nightly-2025-12-20" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 3f4f07f0b9ebbb08cb7ef1702d6f79b553eb33bc Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Thu, 4 Dec 2025 21:53:11 +0000 Subject: [PATCH 1093/3801] add check for uninhabited types along side never (cherry picked from commit 2a2da782d32f25d69b66880b5dca640e2be8fe3e) --- compiler/rustc_mir_build/src/builder/mod.rs | 21 ++++++++++++++++++- .../uninhabited-unreachable-warning-149571.rs | 10 +++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/ui/uninhabited/uninhabited-unreachable-warning-149571.rs diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 206eb9126f54..14a24265a8f4 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -839,6 +839,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.infcx.typing_env(self.param_env), ); + // check if the function's return type is inhabited + // this was added here because of this regression + // https://github.com/rust-lang/rust/issues/149571 + let output_is_inhabited = + if matches!(self.tcx.def_kind(self.def_id), DefKind::Fn | DefKind::AssocFn) { + self.tcx + .fn_sig(self.def_id) + .instantiate_identity() + .skip_binder() + .output() + .is_inhabited_from( + self.tcx, + self.parent_module, + self.infcx.typing_env(self.param_env), + ) + } else { + true + }; + if !ty_is_inhabited { // Unreachable code warnings are already emitted during type checking. // However, during type checking, full type information is being @@ -849,7 +868,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // uninhabited types (e.g. empty enums). The check above is used so // that we do not emit the same warning twice if the uninhabited type // is indeed `!`. - if !ty.is_never() { + if !ty.is_never() && output_is_inhabited { lints.push((target_bb, ty, term.source_info.span)); } diff --git a/tests/ui/uninhabited/uninhabited-unreachable-warning-149571.rs b/tests/ui/uninhabited/uninhabited-unreachable-warning-149571.rs new file mode 100644 index 000000000000..a389562d649e --- /dev/null +++ b/tests/ui/uninhabited/uninhabited-unreachable-warning-149571.rs @@ -0,0 +1,10 @@ +#![deny(unreachable_code)] +//@ run-pass + +use std::convert::Infallible; + +pub fn foo(f: impl FnOnce() -> Infallible) -> Infallible { + f() +} + +fn main() {} From 834ced45a471742e8e3fb0bcece4f575c07bfeb2 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 16 Dec 2025 12:32:00 +0100 Subject: [PATCH 1094/3801] Update to LLVM 21.1.8 (cherry picked from commit f33abb17db4045a629e0ef4e9755dc145e3fdaec) --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 16b5ac8b0a54..85a90d119deb 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 16b5ac8b0a5456eb23c72e1bff3fc9bd6e824f84 +Subproject commit 85a90d119deb25b518867cd37d62c7b93b575a6f From 4bc6d7559250e95aecada1067b03058b32c62492 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 17 Dec 2025 14:33:52 +0000 Subject: [PATCH 1095/3801] Revert #148937 (Remove initialized-bytes tracking from `BorrowedBuf` and `BorrowedCursor`) This caused several performance regressions because of existing code which uses `Read::read` and therefore requires full buffer initialization. This is particularly a problem when the same buffer is re-used for multiple read calls since this means it needs to be fully re-initialized each time. There is still some benefit to landing the API changes, but we will have to add private APIs so that the existing infrastructure can track and avoid redundant initialization. (cherry picked from commit 4b07875505bdd5c4b635fbf821401fcd4573dffd) --- library/core/src/io/borrowed_buf.rs | 162 +++++++++++++++--- library/coretests/tests/io/borrowed_buf.rs | 90 ++++++++-- library/std/src/fs/tests.rs | 2 + library/std/src/io/buffered/bufreader.rs | 9 + .../std/src/io/buffered/bufreader/buffer.rs | 27 ++- library/std/src/io/buffered/tests.rs | 24 +++ library/std/src/io/copy.rs | 13 ++ library/std/src/io/mod.rs | 53 +++++- library/std/src/io/tests.rs | 9 + library/std/src/io/util.rs | 2 +- library/std/src/io/util/tests.rs | 8 + library/std/src/net/tcp/tests.rs | 2 + library/std/src/process/tests.rs | 2 + library/std/src/sys/fd/hermit.rs | 2 +- library/std/src/sys/fd/unix.rs | 4 +- library/std/src/sys/fd/wasi.rs | 2 +- library/std/src/sys/fs/solid.rs | 2 +- .../src/sys/net/connection/socket/hermit.rs | 2 +- .../src/sys/net/connection/socket/solid.rs | 2 +- .../std/src/sys/net/connection/socket/unix.rs | 2 +- .../src/sys/net/connection/socket/wasip2.rs | 2 +- .../src/sys/net/connection/socket/windows.rs | 2 +- .../std/src/sys/pal/sgx/abi/usercalls/mod.rs | 2 +- library/std/src/sys/pal/windows/handle.rs | 4 +- library/std/src/sys/pal/windows/pipe.rs | 2 +- library/std/src/sys/stdio/zkvm.rs | 2 +- 26 files changed, 368 insertions(+), 65 deletions(-) diff --git a/library/core/src/io/borrowed_buf.rs b/library/core/src/io/borrowed_buf.rs index b765b96fd00a..088dea781294 100644 --- a/library/core/src/io/borrowed_buf.rs +++ b/library/core/src/io/borrowed_buf.rs @@ -2,26 +2,27 @@ use crate::fmt::{self, Debug, Formatter}; use crate::mem::{self, MaybeUninit}; +use crate::{cmp, ptr}; -/// A borrowed buffer of initially uninitialized bytes, which is incrementally filled. +/// A borrowed byte buffer which is incrementally filled and initialized. /// -/// This type makes it safer to work with `MaybeUninit` buffers, such as to read into a buffer -/// without having to initialize it first. It tracks the region of bytes that have been filled and -/// the region that remains uninitialized. +/// This type is a sort of "double cursor". It tracks three regions in the buffer: a region at the beginning of the +/// buffer that has been logically filled with data, a region that has been initialized at some point but not yet +/// logically filled, and a region at the end that is fully uninitialized. The filled region is guaranteed to be a +/// subset of the initialized region. /// -/// The contents of the buffer can be visualized as: +/// In summary, the contents of the buffer can be visualized as: /// ```not_rust -/// [ capacity ] -/// [ len: filled and initialized | capacity - len: uninitialized ] +/// [ capacity ] +/// [ filled | unfilled ] +/// [ initialized | uninitialized ] /// ``` /// -/// Note that `BorrowedBuf` does not distinguish between uninitialized data and data that was -/// previously initialized but no longer contains valid data. -/// -/// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique -/// reference (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_len`), but -/// cannot be directly written. To write into the buffer, use `unfilled` to create a -/// `BorrowedCursor`. The cursor has write-only access to the unfilled portion of the buffer. +/// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique reference +/// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but cannot be +/// directly written. To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor +/// has write-only access to the unfilled portion of the buffer (you can think of it as a +/// write-only iterator). /// /// The lifetime `'data` is a bound on the lifetime of the underlying data. pub struct BorrowedBuf<'data> { @@ -29,11 +30,14 @@ pub struct BorrowedBuf<'data> { buf: &'data mut [MaybeUninit], /// The length of `self.buf` which is known to be filled. filled: usize, + /// The length of `self.buf` which is known to be initialized. + init: usize, } impl Debug for BorrowedBuf<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("BorrowedBuf") + .field("init", &self.init) .field("filled", &self.filled) .field("capacity", &self.capacity()) .finish() @@ -44,22 +48,24 @@ impl Debug for BorrowedBuf<'_> { impl<'data> From<&'data mut [u8]> for BorrowedBuf<'data> { #[inline] fn from(slice: &'data mut [u8]) -> BorrowedBuf<'data> { + let len = slice.len(); + BorrowedBuf { - // SAFETY: Always in bounds. We treat the buffer as uninitialized, even though it's - // already initialized. + // SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf buf: unsafe { (slice as *mut [u8]).as_uninit_slice_mut().unwrap() }, filled: 0, + init: len, } } } /// Creates a new `BorrowedBuf` from an uninitialized buffer. /// -/// Use `set_filled` if part of the buffer is known to be already filled. +/// Use `set_init` if part of the buffer is known to be already initialized. impl<'data> From<&'data mut [MaybeUninit]> for BorrowedBuf<'data> { #[inline] fn from(buf: &'data mut [MaybeUninit]) -> BorrowedBuf<'data> { - BorrowedBuf { buf, filled: 0 } + BorrowedBuf { buf, filled: 0, init: 0 } } } @@ -68,11 +74,14 @@ impl<'data> From<&'data mut [MaybeUninit]> for BorrowedBuf<'data> { /// Use `BorrowedCursor::with_unfilled_buf` instead for a safer alternative. impl<'data> From> for BorrowedBuf<'data> { #[inline] - fn from(buf: BorrowedCursor<'data>) -> BorrowedBuf<'data> { + fn from(mut buf: BorrowedCursor<'data>) -> BorrowedBuf<'data> { + let init = buf.init_mut().len(); BorrowedBuf { - // SAFETY: Always in bounds. We treat the buffer as uninitialized. + // SAFETY: no initialized byte is ever uninitialized as per + // `BorrowedBuf`'s invariant buf: unsafe { buf.buf.buf.get_unchecked_mut(buf.buf.filled..) }, filled: 0, + init, } } } @@ -90,6 +99,12 @@ impl<'data> BorrowedBuf<'data> { self.filled } + /// Returns the length of the initialized part of the buffer. + #[inline] + pub fn init_len(&self) -> usize { + self.init + } + /// Returns a shared reference to the filled portion of the buffer. #[inline] pub fn filled(&self) -> &[u8] { @@ -144,16 +159,33 @@ impl<'data> BorrowedBuf<'data> { /// Clears the buffer, resetting the filled region to empty. /// - /// The contents of the buffer are not modified. + /// The number of initialized bytes is not changed, and the contents of the buffer are not modified. #[inline] pub fn clear(&mut self) -> &mut Self { self.filled = 0; self } + + /// Asserts that the first `n` bytes of the buffer are initialized. + /// + /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer + /// bytes than are already known to be initialized. + /// + /// # Safety + /// + /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized. + #[inline] + pub unsafe fn set_init(&mut self, n: usize) -> &mut Self { + self.init = cmp::max(self.init, n); + self + } } /// A writeable view of the unfilled portion of a [`BorrowedBuf`]. /// +/// The unfilled portion consists of an initialized and an uninitialized part; see [`BorrowedBuf`] +/// for details. +/// /// Data can be written directly to the cursor by using [`append`](BorrowedCursor::append) or /// indirectly by getting a slice of part or all of the cursor and writing into the slice. In the /// indirect case, the caller must call [`advance`](BorrowedCursor::advance) after writing to inform @@ -206,17 +238,48 @@ impl<'a> BorrowedCursor<'a> { self.buf.filled } + /// Returns a mutable reference to the initialized portion of the cursor. + #[inline] + pub fn init_mut(&mut self) -> &mut [u8] { + // SAFETY: We only slice the initialized part of the buffer, which is always valid + unsafe { + let buf = self.buf.buf.get_unchecked_mut(self.buf.filled..self.buf.init); + buf.assume_init_mut() + } + } + /// Returns a mutable reference to the whole cursor. /// /// # Safety /// - /// The caller must not uninitialize any previously initialized bytes. + /// The caller must not uninitialize any bytes in the initialized portion of the cursor. #[inline] pub unsafe fn as_mut(&mut self) -> &mut [MaybeUninit] { // SAFETY: always in bounds unsafe { self.buf.buf.get_unchecked_mut(self.buf.filled..) } } + /// Advances the cursor by asserting that `n` bytes have been filled. + /// + /// After advancing, the `n` bytes are no longer accessible via the cursor and can only be + /// accessed via the underlying buffer. I.e., the buffer's filled portion grows by `n` elements + /// and its unfilled portion (and the capacity of this cursor) shrinks by `n` elements. + /// + /// If less than `n` bytes initialized (by the cursor's point of view), `set_init` should be + /// called first. + /// + /// # Panics + /// + /// Panics if there are less than `n` bytes initialized. + #[inline] + pub fn advance(&mut self, n: usize) -> &mut Self { + // The subtraction cannot underflow by invariant of this type. + assert!(n <= self.buf.init - self.buf.filled); + + self.buf.filled += n; + self + } + /// Advances the cursor by asserting that `n` bytes have been filled. /// /// After advancing, the `n` bytes are no longer accessible via the cursor and can only be @@ -225,11 +288,42 @@ impl<'a> BorrowedCursor<'a> { /// /// # Safety /// - /// The caller must ensure that the first `n` bytes of the cursor have been initialized. `n` - /// must not exceed the remaining capacity of this cursor. + /// The caller must ensure that the first `n` bytes of the cursor have been properly + /// initialised. #[inline] - pub unsafe fn advance(&mut self, n: usize) -> &mut Self { + pub unsafe fn advance_unchecked(&mut self, n: usize) -> &mut Self { self.buf.filled += n; + self.buf.init = cmp::max(self.buf.init, self.buf.filled); + self + } + + /// Initializes all bytes in the cursor. + #[inline] + pub fn ensure_init(&mut self) -> &mut Self { + // SAFETY: always in bounds and we never uninitialize these bytes. + let uninit = unsafe { self.buf.buf.get_unchecked_mut(self.buf.init..) }; + + // SAFETY: 0 is a valid value for MaybeUninit and the length matches the allocation + // since it is comes from a slice reference. + unsafe { + ptr::write_bytes(uninit.as_mut_ptr(), 0, uninit.len()); + } + self.buf.init = self.buf.capacity(); + + self + } + + /// Asserts that the first `n` unfilled bytes of the cursor are initialized. + /// + /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when + /// called with fewer bytes than are already known to be initialized. + /// + /// # Safety + /// + /// The caller must ensure that the first `n` bytes of the buffer have already been initialized. + #[inline] + pub unsafe fn set_init(&mut self, n: usize) -> &mut Self { + self.buf.init = cmp::max(self.buf.init, self.buf.filled + n); self } @@ -247,6 +341,10 @@ impl<'a> BorrowedCursor<'a> { self.as_mut()[..buf.len()].write_copy_of_slice(buf); } + // SAFETY: We just added the entire contents of buf to the filled section. + unsafe { + self.set_init(buf.len()); + } self.buf.filled += buf.len(); } @@ -269,9 +367,17 @@ impl<'a> BorrowedCursor<'a> { // there, one could mark some bytes as initialized even though there aren't. assert!(core::ptr::addr_eq(prev_ptr, buf.buf)); - // SAFETY: These bytes were filled in the `BorrowedBuf`, so they're filled in the cursor - // too, because the buffer wasn't replaced. - self.buf.filled += buf.filled; + let filled = buf.filled; + let init = buf.init; + + // Update `init` and `filled` fields with what was written to the buffer. + // `self.buf.filled` was the starting length of the `BorrowedBuf`. + // + // SAFETY: These amounts of bytes were initialized/filled in the `BorrowedBuf`, + // and therefore they are initialized/filled in the cursor too, because the + // buffer wasn't replaced. + self.buf.init = self.buf.filled + init; + self.buf.filled += filled; res } diff --git a/library/coretests/tests/io/borrowed_buf.rs b/library/coretests/tests/io/borrowed_buf.rs index 730ba04465a1..aaa98d26ff8b 100644 --- a/library/coretests/tests/io/borrowed_buf.rs +++ b/library/coretests/tests/io/borrowed_buf.rs @@ -8,6 +8,7 @@ fn new() { let mut rbuf: BorrowedBuf<'_> = buf.into(); assert_eq!(rbuf.filled().len(), 0); + assert_eq!(rbuf.init_len(), 16); assert_eq!(rbuf.capacity(), 16); assert_eq!(rbuf.unfilled().capacity(), 16); } @@ -19,16 +20,27 @@ fn uninit() { let mut rbuf: BorrowedBuf<'_> = buf.into(); assert_eq!(rbuf.filled().len(), 0); + assert_eq!(rbuf.init_len(), 0); assert_eq!(rbuf.capacity(), 16); assert_eq!(rbuf.unfilled().capacity(), 16); } +#[test] +fn initialize_unfilled() { + let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16]; + let mut rbuf: BorrowedBuf<'_> = buf.into(); + + rbuf.unfilled().ensure_init(); + + assert_eq!(rbuf.init_len(), 16); +} + #[test] fn advance_filled() { let buf: &mut [_] = &mut [0; 16]; let mut rbuf: BorrowedBuf<'_> = buf.into(); - unsafe { rbuf.unfilled().advance(1) }; + rbuf.unfilled().advance(1); assert_eq!(rbuf.filled().len(), 1); assert_eq!(rbuf.unfilled().capacity(), 15); @@ -39,7 +51,7 @@ fn clear() { let buf: &mut [_] = &mut [255; 16]; let mut rbuf: BorrowedBuf<'_> = buf.into(); - unsafe { rbuf.unfilled().advance(16) }; + rbuf.unfilled().advance(16); assert_eq!(rbuf.filled().len(), 16); assert_eq!(rbuf.unfilled().capacity(), 0); @@ -49,9 +61,33 @@ fn clear() { assert_eq!(rbuf.filled().len(), 0); assert_eq!(rbuf.unfilled().capacity(), 16); - unsafe { rbuf.unfilled().advance(16) }; + assert_eq!(rbuf.unfilled().init_mut(), [255; 16]); +} - assert_eq!(rbuf.filled(), [255; 16]); +#[test] +fn set_init() { + let buf: &mut [_] = &mut [MaybeUninit::zeroed(); 16]; + let mut rbuf: BorrowedBuf<'_> = buf.into(); + + unsafe { + rbuf.set_init(8); + } + + assert_eq!(rbuf.init_len(), 8); + + rbuf.unfilled().advance(4); + + unsafe { + rbuf.set_init(2); + } + + assert_eq!(rbuf.init_len(), 8); + + unsafe { + rbuf.set_init(8); + } + + assert_eq!(rbuf.init_len(), 8); } #[test] @@ -61,6 +97,7 @@ fn append() { rbuf.unfilled().append(&[0; 8]); + assert_eq!(rbuf.init_len(), 8); assert_eq!(rbuf.filled().len(), 8); assert_eq!(rbuf.filled(), [0; 8]); @@ -68,6 +105,7 @@ fn append() { rbuf.unfilled().append(&[1; 16]); + assert_eq!(rbuf.init_len(), 16); assert_eq!(rbuf.filled().len(), 16); assert_eq!(rbuf.filled(), [1; 16]); } @@ -87,12 +125,43 @@ fn reborrow_written() { assert_eq!(cursor.written(), 32); assert_eq!(buf.unfilled().written(), 32); + assert_eq!(buf.init_len(), 32); assert_eq!(buf.filled().len(), 32); let filled = buf.filled(); assert_eq!(&filled[..16], [1; 16]); assert_eq!(&filled[16..], [2; 16]); } +#[test] +fn cursor_set_init() { + let buf: &mut [_] = &mut [MaybeUninit::zeroed(); 16]; + let mut rbuf: BorrowedBuf<'_> = buf.into(); + + unsafe { + rbuf.unfilled().set_init(8); + } + + assert_eq!(rbuf.init_len(), 8); + assert_eq!(rbuf.unfilled().init_mut().len(), 8); + assert_eq!(unsafe { rbuf.unfilled().as_mut().len() }, 16); + + rbuf.unfilled().advance(4); + + unsafe { + rbuf.unfilled().set_init(2); + } + + assert_eq!(rbuf.init_len(), 8); + + unsafe { + rbuf.unfilled().set_init(8); + } + + assert_eq!(rbuf.init_len(), 12); + assert_eq!(rbuf.unfilled().init_mut().len(), 8); + assert_eq!(unsafe { rbuf.unfilled().as_mut().len() }, 12); +} + #[test] fn cursor_with_unfilled_buf() { let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16]; @@ -100,30 +169,31 @@ fn cursor_with_unfilled_buf() { let mut cursor = rbuf.unfilled(); cursor.with_unfilled_buf(|buf| { - assert_eq!(buf.capacity(), 16); buf.unfilled().append(&[1, 2, 3]); assert_eq!(buf.filled(), &[1, 2, 3]); }); + assert_eq!(cursor.init_mut().len(), 0); assert_eq!(cursor.written(), 3); cursor.with_unfilled_buf(|buf| { assert_eq!(buf.capacity(), 13); + assert_eq!(buf.init_len(), 0); - unsafe { - buf.unfilled().as_mut().write_filled(0); - buf.unfilled().advance(4) - }; + buf.unfilled().ensure_init(); + buf.unfilled().advance(4); }); + assert_eq!(cursor.init_mut().len(), 9); assert_eq!(cursor.written(), 7); cursor.with_unfilled_buf(|buf| { assert_eq!(buf.capacity(), 9); + assert_eq!(buf.init_len(), 9); }); + assert_eq!(cursor.init_mut().len(), 9); assert_eq!(cursor.written(), 7); - assert_eq!(rbuf.len(), 7); assert_eq!(rbuf.filled(), &[1, 2, 3, 0, 0, 0, 0]); } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index bcaafcfee787..0a5d1153d860 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -709,6 +709,8 @@ fn file_test_read_buf() { let mut file = check!(File::open(filename)); check!(file.read_buf(buf.unfilled())); assert_eq!(buf.filled(), &[1, 2, 3, 4]); + // File::read_buf should omit buffer initialization. + assert_eq!(buf.init_len(), 4); check!(fs::remove_file(filename)); } diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 69c260b5410a..40441dc057d0 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -284,6 +284,15 @@ impl BufReader { } } +// This is only used by a test which asserts that the initialization-tracking is correct. +#[cfg(test)] +impl BufReader { + #[allow(missing_docs)] + pub fn initialized(&self) -> usize { + self.buf.initialized() + } +} + impl BufReader { /// Seeks relative to the current position. If the new position lies within the buffer, /// the buffer will not be flushed, allowing for more efficient seeks. diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 2694726b3f44..9b600cd55758 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -21,19 +21,25 @@ pub struct Buffer { // Each call to `fill_buf` sets `filled` to indicate how many bytes at the start of `buf` are // initialized with bytes from a read. filled: usize, + // This is the max number of bytes returned across all `fill_buf` calls. We track this so that we + // can accurately tell `read_buf` how many bytes of buf are initialized, to bypass as much of its + // defensive initialization as possible. Note that while this often the same as `filled`, it + // doesn't need to be. Calls to `fill_buf` are not required to actually fill the buffer, and + // omitting this is a huge perf regression for `Read` impls that do not. + initialized: usize, } impl Buffer { #[inline] pub fn with_capacity(capacity: usize) -> Self { let buf = Box::new_uninit_slice(capacity); - Self { buf, pos: 0, filled: 0 } + Self { buf, pos: 0, filled: 0, initialized: 0 } } #[inline] pub fn try_with_capacity(capacity: usize) -> io::Result { match Box::try_new_uninit_slice(capacity) { - Ok(buf) => Ok(Self { buf, pos: 0, filled: 0 }), + Ok(buf) => Ok(Self { buf, pos: 0, filled: 0, initialized: 0 }), Err(_) => { Err(io::const_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer")) } @@ -62,6 +68,12 @@ impl Buffer { self.pos } + // This is only used by a test which asserts that the initialization-tracking is correct. + #[cfg(test)] + pub fn initialized(&self) -> usize { + self.initialized + } + #[inline] pub fn discard_buffer(&mut self) { self.pos = 0; @@ -98,8 +110,13 @@ impl Buffer { /// Read more bytes into the buffer without discarding any of its contents pub fn read_more(&mut self, mut reader: impl Read) -> io::Result { let mut buf = BorrowedBuf::from(&mut self.buf[self.filled..]); + let old_init = self.initialized - self.filled; + unsafe { + buf.set_init(old_init); + } reader.read_buf(buf.unfilled())?; self.filled += buf.len(); + self.initialized += buf.init_len() - old_init; Ok(buf.len()) } @@ -120,10 +137,16 @@ impl Buffer { debug_assert!(self.pos == self.filled); let mut buf = BorrowedBuf::from(&mut *self.buf); + // SAFETY: `self.filled` bytes will always have been initialized. + unsafe { + buf.set_init(self.initialized); + } + let result = reader.read_buf(buf.unfilled()); self.pos = 0; self.filled = buf.len(); + self.initialized = buf.init_len(); result?; } diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs index 068dca819775..17f6107aa030 100644 --- a/library/std/src/io/buffered/tests.rs +++ b/library/std/src/io/buffered/tests.rs @@ -1052,6 +1052,30 @@ fn single_formatted_write() { assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]); } +#[test] +fn bufreader_full_initialize() { + struct OneByteReader; + impl Read for OneByteReader { + fn read(&mut self, buf: &mut [u8]) -> crate::io::Result { + if buf.len() > 0 { + buf[0] = 0; + Ok(1) + } else { + Ok(0) + } + } + } + let mut reader = BufReader::new(OneByteReader); + // Nothing is initialized yet. + assert_eq!(reader.initialized(), 0); + + let buf = reader.fill_buf().unwrap(); + // We read one byte... + assert_eq!(buf.len(), 1); + // But we initialized the whole buffer! + assert_eq!(reader.initialized(), reader.capacity()); +} + /// This is a regression test for https://github.com/rust-lang/rust/issues/127584. #[test] fn bufwriter_aliasing() { diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs index 8b5e7c4df4e0..2b558efb8885 100644 --- a/library/std/src/io/copy.rs +++ b/library/std/src/io/copy.rs @@ -214,19 +214,28 @@ impl BufferedWriterSpec for BufWriter { } let mut len = 0; + let mut init = 0; loop { let buf = self.buffer_mut(); let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into(); + unsafe { + // SAFETY: init is either 0 or the init_len from the previous iteration. + read_buf.set_init(init); + } + if read_buf.capacity() >= DEFAULT_BUF_SIZE { let mut cursor = read_buf.unfilled(); match reader.read_buf(cursor.reborrow()) { Ok(()) => { let bytes_read = cursor.written(); + if bytes_read == 0 { return Ok(len); } + + init = read_buf.init_len() - bytes_read; len += bytes_read as u64; // SAFETY: BorrowedBuf guarantees all of its filled bytes are init @@ -239,6 +248,10 @@ impl BufferedWriterSpec for BufWriter { Err(e) => return Err(e), } } else { + // All the bytes that were already in the buffer are initialized, + // treat them as such when the buffer is flushed. + init += buf.len(); + self.flush_buf()?; } } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 4c064c435e5b..b7756befa11e 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -419,6 +419,8 @@ pub(crate) fn default_read_to_end( .and_then(|s| s.checked_add(1024)?.checked_next_multiple_of(DEFAULT_BUF_SIZE)) .unwrap_or(DEFAULT_BUF_SIZE); + let mut initialized = 0; // Extra initialized bytes from previous loop iteration + const PROBE_SIZE: usize = 32; fn small_probe_read(r: &mut R, buf: &mut Vec) -> Result { @@ -447,6 +449,8 @@ pub(crate) fn default_read_to_end( } } + let mut consecutive_short_reads = 0; + loop { if buf.len() == buf.capacity() && buf.capacity() == start_cap { // The buffer might be an exact fit. Let's read into a probe buffer @@ -470,6 +474,11 @@ pub(crate) fn default_read_to_end( spare = &mut spare[..buf_len]; let mut read_buf: BorrowedBuf<'_> = spare.into(); + // SAFETY: These bytes were initialized but not filled in the previous loop + unsafe { + read_buf.set_init(initialized); + } + let mut cursor = read_buf.unfilled(); let result = loop { match r.read_buf(cursor.reborrow()) { @@ -480,7 +489,9 @@ pub(crate) fn default_read_to_end( } }; + let unfilled_but_initialized = cursor.init_mut().len(); let bytes_read = cursor.written(); + let was_fully_initialized = read_buf.init_len() == buf_len; // SAFETY: BorrowedBuf's invariants mean this much memory is initialized. unsafe { @@ -495,8 +506,27 @@ pub(crate) fn default_read_to_end( return Ok(buf.len() - start_len); } + if bytes_read < buf_len { + consecutive_short_reads += 1; + } else { + consecutive_short_reads = 0; + } + + // store how much was initialized but not filled + initialized = unfilled_but_initialized; + // Use heuristics to determine the max read size if no initial size hint was provided if size_hint.is_none() { + // The reader is returning short reads but it doesn't call ensure_init(). + // In that case we no longer need to restrict read sizes to avoid + // initialization costs. + // When reading from disk we usually don't get any short reads except at EOF. + // So we wait for at least 2 short reads before uncapping the read buffer; + // this helps with the Windows issue. + if !was_fully_initialized && consecutive_short_reads > 1 { + max_read_size = usize::MAX; + } + // we have passed a larger buffer than previously and the // reader still hasn't returned a short read if buf_len >= max_read_size && bytes_read == buf_len { @@ -557,13 +587,8 @@ pub(crate) fn default_read_buf(read: F, mut cursor: BorrowedCursor<'_>) -> Re where F: FnOnce(&mut [u8]) -> Result, { - // SAFETY: We do not uninitialize any part of the buffer. - let n = read(unsafe { cursor.as_mut().write_filled(0) })?; - assert!(n <= cursor.capacity()); - // SAFETY: We've initialized the entire buffer, and `read` can't make it uninitialized. - unsafe { - cursor.advance(n); - } + let n = read(cursor.ensure_init().init_mut())?; + cursor.advance(n); Ok(()) } @@ -3073,21 +3098,31 @@ impl Read for Take { // The condition above guarantees that `self.limit` fits in `usize`. let limit = self.limit as usize; + let extra_init = cmp::min(limit, buf.init_mut().len()); + // SAFETY: no uninit data is written to ibuf let ibuf = unsafe { &mut buf.as_mut()[..limit] }; let mut sliced_buf: BorrowedBuf<'_> = ibuf.into(); + // SAFETY: extra_init bytes of ibuf are known to be initialized + unsafe { + sliced_buf.set_init(extra_init); + } + let mut cursor = sliced_buf.unfilled(); let result = self.inner.read_buf(cursor.reborrow()); + let new_init = cursor.init_mut().len(); let filled = sliced_buf.len(); // cursor / sliced_buf / ibuf must drop here - // SAFETY: filled bytes have been filled and therefore initialized unsafe { - buf.advance(filled); + // SAFETY: filled bytes have been filled and therefore initialized + buf.advance_unchecked(filled); + // SAFETY: new_init bytes of buf's unfilled buffer have been initialized + buf.set_init(new_init); } self.limit -= filled as u64; diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index e14e6432eafa..b22988d4a8a9 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -209,6 +209,15 @@ fn read_buf_exact() { assert_eq!(c.read_buf_exact(buf.unfilled()).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); } +#[test] +#[should_panic] +fn borrowed_cursor_advance_overflow() { + let mut buf = [0; 512]; + let mut buf = BorrowedBuf::from(&mut buf[..]); + buf.unfilled().advance(1); + buf.unfilled().advance(usize::MAX); +} + #[test] fn take_eof() { struct R; diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index a09c8bc06930..0410df3ef1a3 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -283,7 +283,7 @@ impl Read for Repeat { // SAFETY: No uninit bytes are being written. unsafe { buf.as_mut() }.write_filled(self.byte); // SAFETY: the entire unfilled portion of buf has been initialized. - unsafe { buf.advance(buf.capacity()) }; + unsafe { buf.advance_unchecked(buf.capacity()) }; Ok(()) } diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs index 92dbc3919bea..d0f106d7af41 100644 --- a/library/std/src/io/util/tests.rs +++ b/library/std/src/io/util/tests.rs @@ -75,36 +75,43 @@ fn empty_reads() { let mut buf: BorrowedBuf<'_> = buf.into(); e.read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit()]; let mut buf: BorrowedBuf<'_> = buf.into(); e.read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; let mut buf: BorrowedBuf<'_> = buf.into(); e.read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; let mut buf: BorrowedBuf<'_> = buf.into(); Read::by_ref(&mut e).read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [MaybeUninit<_>] = &mut []; let mut buf: BorrowedBuf<'_> = buf.into(); e.read_buf_exact(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit()]; let mut buf: BorrowedBuf<'_> = buf.into(); assert_eq!(e.read_buf_exact(buf.unfilled()).unwrap_err().kind(), ErrorKind::UnexpectedEof); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; let mut buf: BorrowedBuf<'_> = buf.into(); assert_eq!(e.read_buf_exact(buf.unfilled()).unwrap_err().kind(), ErrorKind::UnexpectedEof); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; let mut buf: BorrowedBuf<'_> = buf.into(); @@ -113,6 +120,7 @@ fn empty_reads() { ErrorKind::UnexpectedEof, ); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let mut buf = Vec::new(); assert_eq!(e.read_to_end(&mut buf).unwrap(), 0); diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs index 4787f8a1040b..7c7ef7b2f701 100644 --- a/library/std/src/net/tcp/tests.rs +++ b/library/std/src/net/tcp/tests.rs @@ -315,6 +315,8 @@ fn read_buf() { let mut buf = BorrowedBuf::from(buf.as_mut_slice()); t!(s.read_buf(buf.unfilled())); assert_eq!(buf.filled(), &[1, 2, 3, 4]); + // TcpStream::read_buf should omit buffer initialization. + assert_eq!(buf.init_len(), 4); t.join().ok().expect("thread panicked"); }) diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs index c8a83edffe42..12c5130defe5 100644 --- a/library/std/src/process/tests.rs +++ b/library/std/src/process/tests.rs @@ -188,8 +188,10 @@ fn child_stdout_read_buf() { // ChildStdout::read_buf should omit buffer initialization. if cfg!(target_os = "windows") { assert_eq!(buf.filled(), b"abc\r\n"); + assert_eq!(buf.init_len(), 5); } else { assert_eq!(buf.filled(), b"abc\n"); + assert_eq!(buf.init_len(), 4); }; } diff --git a/library/std/src/sys/fd/hermit.rs b/library/std/src/sys/fd/hermit.rs index afcd8c635541..7e8ba065f1b9 100644 --- a/library/std/src/sys/fd/hermit.rs +++ b/library/std/src/sys/fd/hermit.rs @@ -34,7 +34,7 @@ impl FileDesc { ) })?; // SAFETY: Exactly `result` bytes have been filled. - unsafe { buf.advance(result as usize) }; + unsafe { buf.advance_unchecked(result as usize) }; Ok(()) } diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index a631e1d91393..2b2dfe48e89e 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -185,7 +185,7 @@ impl FileDesc { // SAFETY: `ret` bytes were written to the initialized portion of the buffer unsafe { - cursor.advance(ret as usize); + cursor.advance_unchecked(ret as usize); } Ok(()) } @@ -203,7 +203,7 @@ impl FileDesc { // SAFETY: `ret` bytes were written to the initialized portion of the buffer unsafe { - cursor.advance(ret as usize); + cursor.advance_unchecked(ret as usize); } Ok(()) } diff --git a/library/std/src/sys/fd/wasi.rs b/library/std/src/sys/fd/wasi.rs index a468b31168af..80a5143ff0b0 100644 --- a/library/std/src/sys/fd/wasi.rs +++ b/library/std/src/sys/fd/wasi.rs @@ -59,7 +59,7 @@ impl WasiFd { }]; match wasi::fd_read(self.as_raw_fd() as wasi::Fd, &bufs) { Ok(n) => { - buf.advance(n); + buf.advance_unchecked(n); Ok(()) } Err(e) => Err(err2io(e)), diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index ec1db262855a..f6d5d3b784d3 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -401,7 +401,7 @@ impl File { // Safety: `num_bytes_read` bytes were written to the unfilled // portion of the buffer - cursor.advance(num_bytes_read); + cursor.advance_unchecked(num_bytes_read); Ok(()) } diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs index f044bf8dfae0..2f5c6fa31d40 100644 --- a/library/std/src/sys/net/connection/socket/hermit.rs +++ b/library/std/src/sys/net/connection/socket/hermit.rs @@ -143,7 +143,7 @@ impl Socket { ) })?; unsafe { - buf.advance(ret as usize); + buf.advance_unchecked(ret as usize); } Ok(()) } diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs index 731157ec319c..14cf75adcc06 100644 --- a/library/std/src/sys/net/connection/socket/solid.rs +++ b/library/std/src/sys/net/connection/socket/solid.rs @@ -191,7 +191,7 @@ impl Socket { netc::recv(self.as_raw_fd(), buf.as_mut().as_mut_ptr().cast(), buf.capacity(), flags) })?; unsafe { - buf.advance(ret as usize); + buf.advance_unchecked(ret as usize); } Ok(()) } diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index c892daf0d39c..559e27604a9d 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -293,7 +293,7 @@ impl Socket { ) })?; unsafe { - buf.advance(ret as usize); + buf.advance_unchecked(ret as usize); } Ok(()) } diff --git a/library/std/src/sys/net/connection/socket/wasip2.rs b/library/std/src/sys/net/connection/socket/wasip2.rs index f86034266c26..a1b08609eb02 100644 --- a/library/std/src/sys/net/connection/socket/wasip2.rs +++ b/library/std/src/sys/net/connection/socket/wasip2.rs @@ -167,7 +167,7 @@ impl Socket { ) })?; unsafe { - buf.advance(ret as usize); + buf.advance_unchecked(ret as usize); } Ok(()) } diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index 08196d61aa30..6dbebc5e276e 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs @@ -244,7 +244,7 @@ impl Socket { } } _ => { - unsafe { buf.advance(result as usize) }; + unsafe { buf.advance_unchecked(result as usize) }; Ok(()) } } diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs index f1e4a5a42577..5041770faf66 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs @@ -46,7 +46,7 @@ pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_>) -> IoResult<()> { let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.capacity()); let len = raw::read(fd, userbuf.as_mut_ptr().cast(), userbuf.len()).from_sgx_result()?; userbuf[..len].copy_to_enclave(&mut buf.as_mut()[..len]); - buf.advance(len); + buf.advance_unchecked(len); Ok(()) } } diff --git a/library/std/src/sys/pal/windows/handle.rs b/library/std/src/sys/pal/windows/handle.rs index 712f41ba8030..76c8aa939d3b 100644 --- a/library/std/src/sys/pal/windows/handle.rs +++ b/library/std/src/sys/pal/windows/handle.rs @@ -121,7 +121,7 @@ impl Handle { Ok(read) => { // Safety: `read` bytes were written to the initialized portion of the buffer unsafe { - cursor.advance(read); + cursor.advance_unchecked(read); } Ok(()) } @@ -144,7 +144,7 @@ impl Handle { // SAFETY: `read` bytes were written to the initialized portion of the buffer unsafe { - cursor.advance(read); + cursor.advance_unchecked(read); } Ok(()) } diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index d8e306068d73..b5ccf037a4f2 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -259,7 +259,7 @@ impl AnonPipe { Err(e) => Err(e), Ok(n) => { unsafe { - buf.advance(n); + buf.advance_unchecked(n); } Ok(()) } diff --git a/library/std/src/sys/stdio/zkvm.rs b/library/std/src/sys/stdio/zkvm.rs index 84496ac93736..f31c6c26e87c 100644 --- a/library/std/src/sys/stdio/zkvm.rs +++ b/library/std/src/sys/stdio/zkvm.rs @@ -19,7 +19,7 @@ impl io::Read for Stdin { fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> io::Result<()> { unsafe { let n = abi::sys_read(fileno::STDIN, buf.as_mut().as_mut_ptr().cast(), buf.capacity()); - buf.advance(n); + buf.advance_unchecked(n); } Ok(()) } From 93cf63b7899e98df3353f0b119a04f6ae18c7850 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 20 Dec 2025 16:50:34 -0500 Subject: [PATCH 1096/3801] Move libgccjit.so to the new location within the sysroot --- build_system/src/build.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 27476465d740..9b7ee8380ca5 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -111,14 +111,20 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu // Symlink libgccjit.so to sysroot. let lib_path = start_dir.join("sysroot").join("lib"); + let rustlib_target_path = lib_path + .join("rustlib") + .join(&config.host_triple) + .join("codegen-backends") + .join("lib") + .join(&config.target_triple); let libgccjit_path = PathBuf::from(config.gcc_path.as_ref().expect("libgccjit should be set by this point")) .join("libgccjit.so"); - let libgccjit_in_sysroot_path = lib_path.join("libgccjit.so"); + let libgccjit_in_sysroot_path = rustlib_target_path.join("libgccjit.so"); // First remove the file to be able to create the symlink even when the file already exists. let _ = fs::remove_file(&libgccjit_in_sysroot_path); - create_dir(&lib_path)?; - symlink(libgccjit_path, libgccjit_in_sysroot_path) + create_dir(&rustlib_target_path)?; + symlink(libgccjit_path, &libgccjit_in_sysroot_path) .map_err(|error| format!("Cannot create symlink for libgccjit.so: {}", error))?; let library_dir = start_dir.join("sysroot_src").join("library"); From 1ac26a7b1c757f55c3a5d86691c9a7b105d5d86f Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 20 Dec 2025 17:31:53 -0500 Subject: [PATCH 1097/3801] Add new failing tests --- tests/failing-ui-tests.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 2380bd0fc137..99a80fa7e4f4 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -88,3 +88,12 @@ tests/ui/test-attrs/test-panic-while-printing.rs tests/ui/thir-print/offset_of.rs tests/ui/iterators/rangefrom-overflow-debug.rs tests/ui/iterators/rangefrom-overflow-overflow-checks.rs +tests/ui/iterators/iter-filter-count-debug-check.rs +tests/ui/eii/codegen_single_crate.rs +tests/ui/eii/codegen_cross_crate.rs +tests/ui/eii/default/local_crate.rs +tests/ui/eii/multiple_impls.rs +tests/ui/eii/default/call_default.rs +tests/ui/eii/same-symbol.rs +tests/ui/eii/privacy1.rs +tests/ui/eii/default/call_impl.rs From 7ba8b145e8e0e93d87e641e5b50a09fc013bf1ad Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 20 Dec 2025 22:43:35 +0000 Subject: [PATCH 1098/3801] fix: `if_then_some_else_none` suggests wrongly when then ends with comment --- clippy_lints/src/if_then_some_else_none.rs | 16 +++-- tests/ui/if_then_some_else_none.fixed | 42 ++++++++++-- tests/ui/if_then_some_else_none.rs | 13 ++++ tests/ui/if_then_some_else_none.stderr | 78 ++++++++++++++++++++-- 4 files changed, 133 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs index 314c8e1dd54c..9e5e4fa58d2f 100644 --- a/clippy_lints/src/if_then_some_else_none.rs +++ b/clippy_lints/src/if_then_some_else_none.rs @@ -109,13 +109,19 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { .maybe_paren() .to_string(); let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0; - let method_body = if let Some(first_stmt) = then_block.stmts.first() - && let Some(first_stmt_span) = walk_span_to_context(first_stmt.span, ctxt) + let method_body = if let Some(_) = then_block.stmts.first() + && let Some(then_span) = walk_span_to_context(then.span, ctxt) { - let block_snippet = - snippet_with_applicability(cx, first_stmt_span.until(then_expr.span), "..", &mut app); + let block_before_snippet = + snippet_with_applicability(cx, then_span.until(then_expr.span), "..", &mut app); + let block_after_snippet = snippet_with_applicability( + cx, + then_expr.span.shrink_to_hi().until(then_span.shrink_to_hi()), + "..", + &mut app, + ); let closure = if method_name == sym::then { "|| " } else { "" }; - format!("{closure} {{ {} {arg_snip} }}", block_snippet.trim_end()) + format!("{closure}{block_before_snippet}{arg_snip}{block_after_snippet}") } else if method_name == sym::then { (std::borrow::Cow::Borrowed("|| ") + arg_snip).into_owned() } else { diff --git a/tests/ui/if_then_some_else_none.fixed b/tests/ui/if_then_some_else_none.fixed index 9d4cbe6baf07..ce122ac69b12 100644 --- a/tests/ui/if_then_some_else_none.fixed +++ b/tests/ui/if_then_some_else_none.fixed @@ -3,10 +3,20 @@ fn main() { // Should issue an error. - let _ = foo().then(|| { println!("true!"); "foo" }); + let _ = foo().then(|| { + //~^ if_then_some_else_none + + println!("true!"); + "foo" + }); // Should issue an error when macros are used. - let _ = matches!(true, true).then(|| { println!("true!"); matches!(true, false) }); + let _ = matches!(true, true).then(|| { + //~^ if_then_some_else_none + + println!("true!"); + matches!(true, false) + }); // Should issue an error. Binary expression `o < 32` should be parenthesized. let x = Some(5); @@ -71,7 +81,12 @@ fn _msrv_1_49() { #[clippy::msrv = "1.50"] fn _msrv_1_50() { - let _ = foo().then(|| { println!("true!"); 150 }); + let _ = foo().then(|| { + //~^ if_then_some_else_none + + println!("true!"); + 150 + }); } fn foo() -> bool { @@ -182,7 +197,10 @@ fn issue15005() { fn next(&mut self) -> Option { //~v if_then_some_else_none - (self.count < 5).then(|| { self.count += 1; self.count }) + (self.count < 5).then(|| { + self.count += 1; + self.count + }) } } } @@ -195,7 +213,10 @@ fn statements_from_macro() { }; } //~v if_then_some_else_none - let _ = true.then(|| { mac!(); 42 }); + let _ = true.then(|| { + mac!(); + 42 + }); } fn dont_lint_inside_macros() { @@ -228,3 +249,14 @@ mod issue16176 { if cond { Some(foo().await) } else { None } // OK } } + +fn issue16269() -> Option { + use std::cell::UnsafeCell; + + //~v if_then_some_else_none + (1 <= 3).then(|| { + let a = UnsafeCell::new(1); + // SAFETY: `bytes` bytes starting at `new_end` were just reserved. + unsafe { *a.get() } + }) +} diff --git a/tests/ui/if_then_some_else_none.rs b/tests/ui/if_then_some_else_none.rs index 6b1ece61e775..1d6c86d94492 100644 --- a/tests/ui/if_then_some_else_none.rs +++ b/tests/ui/if_then_some_else_none.rs @@ -284,3 +284,16 @@ mod issue16176 { if cond { Some(foo().await) } else { None } // OK } } + +fn issue16269() -> Option { + use std::cell::UnsafeCell; + + //~v if_then_some_else_none + if 1 <= 3 { + let a = UnsafeCell::new(1); + // SAFETY: `bytes` bytes starting at `new_end` were just reserved. + Some(unsafe { *a.get() }) + } else { + None + } +} diff --git a/tests/ui/if_then_some_else_none.stderr b/tests/ui/if_then_some_else_none.stderr index 58651a055942..eff5f8c82dcb 100644 --- a/tests/ui/if_then_some_else_none.stderr +++ b/tests/ui/if_then_some_else_none.stderr @@ -9,10 +9,19 @@ LL | | println!("true!"); ... | LL | | None LL | | }; - | |_____^ help: try: `foo().then(|| { println!("true!"); "foo" })` + | |_____^ | = note: `-D clippy::if-then-some-else-none` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::if_then_some_else_none)]` +help: try + | +LL ~ let _ = foo().then(|| { +LL + +LL + +LL + println!("true!"); +LL + "foo" +LL ~ }); + | error: this could be simplified with `bool::then` --> tests/ui/if_then_some_else_none.rs:16:13 @@ -25,7 +34,17 @@ LL | | println!("true!"); ... | LL | | None LL | | }; - | |_____^ help: try: `matches!(true, true).then(|| { println!("true!"); matches!(true, false) })` + | |_____^ + | +help: try + | +LL ~ let _ = matches!(true, true).then(|| { +LL + +LL + +LL + println!("true!"); +LL + matches!(true, false) +LL ~ }); + | error: this could be simplified with `bool::then_some` --> tests/ui/if_then_some_else_none.rs:27:28 @@ -50,7 +69,17 @@ LL | | println!("true!"); ... | LL | | None LL | | }; - | |_____^ help: try: `foo().then(|| { println!("true!"); 150 })` + | |_____^ + | +help: try + | +LL ~ let _ = foo().then(|| { +LL + +LL + +LL + println!("true!"); +LL + 150 +LL ~ }); + | error: this could be simplified with `bool::then` --> tests/ui/if_then_some_else_none.rs:138:5 @@ -125,7 +154,15 @@ LL | | Some(self.count) LL | | } else { LL | | None LL | | } - | |_____________^ help: try: `(self.count < 5).then(|| { self.count += 1; self.count })` + | |_____________^ + | +help: try + | +LL ~ (self.count < 5).then(|| { +LL + self.count += 1; +LL + self.count +LL + }) + | error: this could be simplified with `bool::then` --> tests/ui/if_then_some_else_none.rs:249:13 @@ -137,7 +174,36 @@ LL | | Some(42) LL | | } else { LL | | None LL | | }; - | |_____^ help: try: `true.then(|| { mac!(); 42 })` + | |_____^ + | +help: try + | +LL ~ let _ = true.then(|| { +LL + mac!(); +LL + 42 +LL ~ }); + | -error: aborting due to 13 previous errors +error: this could be simplified with `bool::then` + --> tests/ui/if_then_some_else_none.rs:292:5 + | +LL | / if 1 <= 3 { +LL | | let a = UnsafeCell::new(1); +LL | | // SAFETY: `bytes` bytes starting at `new_end` were just reserved. +LL | | Some(unsafe { *a.get() }) +LL | | } else { +LL | | None +LL | | } + | |_____^ + | +help: try + | +LL ~ (1 <= 3).then(|| { +LL + let a = UnsafeCell::new(1); +LL + // SAFETY: `bytes` bytes starting at `new_end` were just reserved. +LL + unsafe { *a.get() } +LL + }) + | + +error: aborting due to 14 previous errors From 86d3abf374ac49960b8669301195f57b634e54da Mon Sep 17 00:00:00 2001 From: jackh726 Date: Sat, 6 Dec 2025 18:54:02 +0000 Subject: [PATCH 1099/3801] Add lsp extension to get failed trait obligations for a given function --- src/tools/rust-analyzer/Cargo.lock | 2 + .../rust-analyzer/crates/hir-ty/Cargo.toml | 1 + .../rust-analyzer/crates/hir-ty/src/infer.rs | 14 ++- .../rust-analyzer/crates/hir-ty/src/lib.rs | 2 +- .../crates/hir-ty/src/next_solver.rs | 1 + .../src/next_solver/format_proof_tree.rs | 93 +++++++++++++++++++ .../crates/hir-ty/src/next_solver/fulfill.rs | 3 + .../crates/hir-ty/src/next_solver/infer/at.rs | 2 + .../hir-ty/src/next_solver/infer/mod.rs | 31 ++++++- .../hir-ty/src/next_solver/infer/traits.rs | 14 ++- .../crates/hir-ty/src/next_solver/inspect.rs | 9 +- .../rust-analyzer/crates/hir-ty/src/traits.rs | 25 ++++- src/tools/rust-analyzer/crates/hir/Cargo.toml | 1 + .../rust-analyzer/crates/hir/src/semantics.rs | 34 ++++++- src/tools/rust-analyzer/crates/ide/src/lib.rs | 14 ++- .../rust-analyzer/src/handlers/request.rs | 16 +++- .../crates/rust-analyzer/src/lsp/ext.rs | 15 +++ .../crates/rust-analyzer/src/main_loop.rs | 1 + .../rust-analyzer/tests/slow-tests/main.rs | 37 ++++++++ .../book/src/contributing/lsp-extensions.md | 13 ++- .../rust-analyzer/editors/code/package.json | 9 ++ .../editors/code/src/commands.ts | 12 +++ .../rust-analyzer/editors/code/src/lsp_ext.ts | 3 + .../rust-analyzer/editors/code/src/main.ts | 1 + 24 files changed, 337 insertions(+), 16 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/hir-ty/src/next_solver/format_proof_tree.rs diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 7ada91d2b65b..92a6c3e9764d 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -788,6 +788,7 @@ dependencies = [ "itertools 0.14.0", "ra-ap-rustc_type_ir", "rustc-hash 2.1.1", + "serde_json", "smallvec", "span", "stdx", @@ -901,6 +902,7 @@ dependencies = [ "rustc_apfloat", "salsa", "salsa-macros", + "serde", "smallvec", "span", "stdx", diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml index c60ecef58eaf..e54a6190b44d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml @@ -18,6 +18,7 @@ itertools.workspace = true arrayvec.workspace = true smallvec.workspace = true ena = "0.14.3" +serde.workspace = true either.workspace = true oorandom = "11.1.5" tracing = { workspace = true, features = ["attributes"] } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 4f739dc8eee0..d527a4ae29c2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -75,7 +75,7 @@ use crate::{ AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Region, StoredGenericArgs, StoredTy, StoredTys, Ty, TyKind, Tys, abi::Safety, - infer::{InferCtxt, traits::ObligationCause}, + infer::{InferCtxt, ObligationInspector, traits::ObligationCause}, }, traits::FnTrait, utils::TargetFeatureIsSafeInTarget, @@ -94,11 +94,23 @@ pub(crate) use closure::analysis::{CaptureKind, CapturedItem, CapturedItemWithou /// The entry point of type inference. fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult { + infer_query_with_inspect(db, def, None) +} + +pub fn infer_query_with_inspect<'db>( + db: &'db dyn HirDatabase, + def: DefWithBodyId, + inspect: Option>, +) -> InferenceResult { let _p = tracing::info_span!("infer_query").entered(); let resolver = def.resolver(db); let body = db.body(def); let mut ctx = InferenceContext::new(db, def, &body, resolver); + if let Some(inspect) = inspect { + ctx.table.infer_ctxt.attach_obligation_inspector(inspect); + } + match def { DefWithBodyId::FunctionId(f) => { ctx.collect_fn(f); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 6081196bacc2..1674771413f2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -88,7 +88,7 @@ pub use infer::{ InferenceTyDiagnosticSource, OverloadedDeref, PointerCast, cast::CastError, closure::analysis::{CaptureKind, CapturedItem}, - could_coerce, could_unify, could_unify_deeply, + could_coerce, could_unify, could_unify_deeply, infer_query_with_inspect, }; pub use lower::{ GenericPredicates, ImplTraits, LifetimeElisionKind, TyDefId, TyLoweringContext, ValueTyDefId, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs index 298af7d12411..605e31404c57 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver.rs @@ -9,6 +9,7 @@ mod binder; mod consts; mod def_id; pub mod fold; +pub mod format_proof_tree; pub mod fulfill; mod generic_arg; pub mod generics; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/format_proof_tree.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/format_proof_tree.rs new file mode 100644 index 000000000000..fa09cda234c1 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/format_proof_tree.rs @@ -0,0 +1,93 @@ +use rustc_type_ir::{solve::GoalSource, solve::inspect::GoalEvaluation}; +use serde::{Deserialize, Serialize}; + +use crate::next_solver::infer::InferCtxt; +use crate::next_solver::inspect::{InspectCandidate, InspectGoal}; +use crate::next_solver::{DbInterner, Span}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ProofTreeData { + pub goal: String, + pub result: String, + pub depth: usize, + pub candidates: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CandidateData { + pub kind: String, + pub result: String, + pub impl_header: Option, + pub nested_goals: Vec, +} + +pub fn dump_proof_tree_structured<'db>( + proof_tree: GoalEvaluation>, + _span: Span, + infcx: &InferCtxt<'db>, +) -> ProofTreeData { + let goal_eval = InspectGoal::new(infcx, 0, proof_tree, None, GoalSource::Misc); + let mut serializer = ProofTreeSerializer::new(infcx); + serializer.serialize_goal(&goal_eval) +} + +struct ProofTreeSerializer<'a, 'db> { + infcx: &'a InferCtxt<'db>, +} + +impl<'a, 'db> ProofTreeSerializer<'a, 'db> { + fn new(infcx: &'a InferCtxt<'db>) -> Self { + Self { infcx } + } + + fn serialize_goal(&mut self, goal: &InspectGoal<'_, 'db>) -> ProofTreeData { + let candidates = goal.candidates(); + let candidates_data: Vec = + candidates.iter().map(|c| self.serialize_candidate(c)).collect(); + + ProofTreeData { + goal: format!("{:?}", goal.goal()), + result: format!("{:?}", goal.result()), + depth: goal.depth(), + candidates: candidates_data, + } + } + + fn serialize_candidate(&mut self, candidate: &InspectCandidate<'_, 'db>) -> CandidateData { + let kind = candidate.kind(); + let impl_header = self.get_impl_header(candidate); + + let mut nested = Vec::new(); + self.infcx.probe(|_| { + for nested_goal in candidate.instantiate_nested_goals() { + nested.push(self.serialize_goal(&nested_goal)); + } + }); + + CandidateData { + kind: format!("{:?}", kind), + result: format!("{:?}", candidate.result()), + impl_header, + nested_goals: nested, + } + } + + fn get_impl_header(&self, candidate: &InspectCandidate<'_, 'db>) -> Option { + use rustc_type_ir::solve::inspect::ProbeKind; + match candidate.kind() { + ProbeKind::TraitCandidate { source, .. } => { + use rustc_type_ir::solve::CandidateSource; + match source { + CandidateSource::Impl(impl_def_id) => { + use hir_def::{Lookup, src::HasSource}; + let db = self.infcx.interner.db; + let impl_src = impl_def_id.0.lookup(db).source(db); + Some(impl_src.value.to_string()) + } + _ => None, + } + } + _ => None, + } + } +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs index 4a19e30c64f7..0fe073297279 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs @@ -187,6 +187,9 @@ impl<'db> FulfillmentCtxt<'db> { } let result = delegate.evaluate_root_goal(goal, Span::dummy(), stalled_on); + infcx.inspect_evaluated_obligation(&obligation, &result, || { + Some(delegate.evaluate_root_goal_for_proof_tree(goal, Span::dummy()).1) + }); let GoalEvaluation { goal: _, certainty, has_changed, stalled_on } = match result { Ok(result) => result, Err(NoSolution) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/at.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/at.rs index 6ba1aae2d486..dc0b584084e8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/at.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/at.rs @@ -68,6 +68,7 @@ impl<'db> InferCtxt<'db> { inner: self.inner.clone(), tainted_by_errors: self.tainted_by_errors.clone(), universe: self.universe.clone(), + obligation_inspector: self.obligation_inspector.clone(), } } @@ -84,6 +85,7 @@ impl<'db> InferCtxt<'db> { inner: self.inner.clone(), tainted_by_errors: self.tainted_by_errors.clone(), universe: self.universe.clone(), + obligation_inspector: self.obligation_inspector.clone(), } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs index 14b8a61088d8..2926dc30def7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs @@ -10,8 +10,9 @@ use ena::unify as ut; use hir_def::GenericParamId; use opaque_types::{OpaqueHiddenType, OpaqueTypeStorage}; use region_constraints::{RegionConstraintCollector, RegionConstraintStorage}; -use rustc_next_trait_solver::solve::SolverDelegateEvalExt; +use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt}; use rustc_pattern_analysis::Captures; +use rustc_type_ir::solve::{NoSolution, inspect}; use rustc_type_ir::{ ClosureKind, ConstVid, FloatVarValue, FloatVid, GenericArgKind, InferConst, InferTy, IntVarValue, IntVid, OutlivesPredicate, RegionVid, TermKind, TyVid, TypeFoldable, TypeFolder, @@ -27,6 +28,7 @@ use traits::{ObligationCause, PredicateObligations}; use type_variable::TypeVariableOrigin; use unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey}; +pub use crate::next_solver::infer::traits::ObligationInspector; use crate::next_solver::{ ArgOutlivesPredicate, BoundConst, BoundRegion, BoundTy, BoundVarKind, Goal, Predicate, SolverContext, @@ -250,6 +252,8 @@ pub struct InferCtxt<'db> { /// when we enter into a higher-ranked (`for<..>`) type or trait /// bound. universe: Cell, + + obligation_inspector: Cell>>, } /// See the `error_reporting` module for more details. @@ -375,6 +379,7 @@ impl<'db> InferCtxtBuilder<'db> { inner: RefCell::new(InferCtxtInner::new()), tainted_by_errors: Cell::new(None), universe: Cell::new(UniverseIndex::ROOT), + obligation_inspector: Cell::new(None), } } } @@ -1223,6 +1228,30 @@ impl<'db> InferCtxt<'db> { fn sub_unify_ty_vids_raw(&self, a: rustc_type_ir::TyVid, b: rustc_type_ir::TyVid) { self.inner.borrow_mut().type_variables().sub_unify(a, b); } + + /// Attach a callback to be invoked on each root obligation evaluated in the new trait solver. + pub fn attach_obligation_inspector(&self, inspector: ObligationInspector<'db>) { + debug_assert!( + self.obligation_inspector.get().is_none(), + "shouldn't override a set obligation inspector" + ); + self.obligation_inspector.set(Some(inspector)); + } + + pub fn inspect_evaluated_obligation( + &self, + obligation: &PredicateObligation<'db>, + result: &Result>, NoSolution>, + get_proof_tree: impl FnOnce() -> Option>>, + ) { + if let Some(inspector) = self.obligation_inspector.get() { + let result = match result { + Ok(GoalEvaluation { certainty, .. }) => Ok(*certainty), + Err(_) => Err(NoSolution), + }; + (inspector)(self, obligation, result, get_proof_tree()); + } + } } /// Helper for [InferCtxt::ty_or_const_infer_var_changed] (see comment on that), currently diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs index 3409de17a122..14df42dc2aeb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs @@ -9,8 +9,11 @@ use std::{ use hir_def::TraitId; use macros::{TypeFoldable, TypeVisitable}; -use rustc_type_ir::Upcast; use rustc_type_ir::elaborate::Elaboratable; +use rustc_type_ir::{ + Upcast, + solve::{Certainty, NoSolution, inspect}, +}; use tracing::debug; use crate::next_solver::{ @@ -79,6 +82,15 @@ pub struct Obligation<'db, T> { pub recursion_depth: usize, } +/// A callback that can be provided to `inspect_typeck`. Invoked on evaluation +/// of root obligations. +pub type ObligationInspector<'db> = fn( + &InferCtxt<'db>, + &PredicateObligation<'db>, + Result, + Option>>, +); + /// For [`Obligation`], a sub-obligation is combined with the current obligation's /// param-env and cause code. impl<'db> Elaboratable> for PredicateObligation<'db> { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/inspect.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/inspect.rs index d66aa9f277c7..528697754959 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/inspect.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/inspect.rs @@ -74,7 +74,7 @@ impl<'a, 'db> std::fmt::Debug for InspectCandidate<'a, 'db> { /// treat `NormalizesTo` goals as if they apply the expected /// type at the end of each candidate. #[derive(Debug, Copy, Clone)] -struct NormalizesToTermHack<'db> { +pub(crate) struct NormalizesToTermHack<'db> { term: Term<'db>, unconstrained_term: Term<'db>, } @@ -311,10 +311,7 @@ impl<'a, 'db> InspectCandidate<'a, 'db> { /// Visit all nested goals of this candidate, rolling back /// all inference constraints. #[expect(dead_code, reason = "used in rustc")] - pub(crate) fn visit_nested_in_probe>( - &self, - visitor: &mut V, - ) -> V::Result { + fn visit_nested_in_probe>(&self, visitor: &mut V) -> V::Result { self.goal.infcx.probe(|_| self.visit_nested_no_probe(visitor)) } } @@ -430,7 +427,7 @@ impl<'a, 'db> InspectGoal<'a, 'db> { candidates.pop().filter(|_| candidates.is_empty()) } - fn new( + pub(crate) fn new( infcx: &'a InferCtxt<'db>, depth: usize, root: inspect::GoalEvaluation>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index ad8de293d5a5..fb598fe5acb0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -23,7 +23,10 @@ use crate::{ next_solver::{ Canonical, DbInterner, GenericArgs, Goal, ParamEnv, Predicate, SolverContext, Span, StoredClauses, Ty, TyKind, - infer::{DbInternerInferExt, InferCtxt, traits::ObligationCause}, + infer::{ + DbInternerInferExt, InferCtxt, + traits::{Obligation, ObligationCause}, + }, obligation_ctxt::ObligationCtxt, }, }; @@ -107,6 +110,16 @@ pub fn next_trait_solve_canonical_in_ctxt<'db>( let res = context.evaluate_root_goal(goal, Span::dummy(), None); + let obligation = Obligation { + cause: ObligationCause::dummy(), + param_env: goal.param_env, + recursion_depth: 0, + predicate: goal.predicate, + }; + infer_ctxt.inspect_evaluated_obligation(&obligation, &res, || { + Some(context.evaluate_root_goal_for_proof_tree(goal, Span::dummy()).1) + }); + let res = res.map(|r| (r.has_changed, r.certainty)); tracing::debug!("solve_nextsolver({:?}) => {:?}", goal, res); @@ -130,6 +143,16 @@ pub fn next_trait_solve_in_ctxt<'db, 'a>( let res = context.evaluate_root_goal(goal, Span::dummy(), None); + let obligation = Obligation { + cause: ObligationCause::dummy(), + param_env: goal.param_env, + recursion_depth: 0, + predicate: goal.predicate, + }; + infer_ctxt.inspect_evaluated_obligation(&obligation, &res, || { + Some(context.evaluate_root_goal_for_proof_tree(goal, Span::dummy()).1) + }); + let res = res.map(|r| (r.has_changed, r.certainty)); tracing::debug!("solve_nextsolver({:?}) => {:?}", goal, res); diff --git a/src/tools/rust-analyzer/crates/hir/Cargo.toml b/src/tools/rust-analyzer/crates/hir/Cargo.toml index 24b2bd9150ee..d20ee1546fa4 100644 --- a/src/tools/rust-analyzer/crates/hir/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir/Cargo.toml @@ -17,6 +17,7 @@ rustc-hash.workspace = true either.workspace = true arrayvec.workspace = true itertools.workspace = true +serde_json.workspace = true smallvec.workspace = true tracing = { workspace = true, features = ["attributes"] } triomphe.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index fd08528e86ab..60418b1dad49 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -8,6 +8,7 @@ use std::{ convert::Infallible, fmt, iter, mem, ops::{self, ControlFlow, Not}, + sync::Mutex, }; use base_db::FxIndexSet; @@ -32,11 +33,13 @@ use hir_expand::{ use hir_ty::{ InferenceResult, diagnostics::{unsafe_operations, unsafe_operations_for_body}, - next_solver::DbInterner, + infer_query_with_inspect, + next_solver::{DbInterner, Span, format_proof_tree::dump_proof_tree_structured}, }; use intern::{Interned, Symbol, sym}; use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_type_ir::inherent::Span as _; use smallvec::{SmallVec, smallvec}; use span::{FileId, SyntaxContext}; use stdx::{TupleExt, always}; @@ -2310,6 +2313,35 @@ impl<'db> SemanticsImpl<'db> { Some(locals) } + + pub fn get_failed_obligations(&self, token: SyntaxToken) -> Option { + let node = token.parent()?; + let node = self.find_file(&node); + + let container = self.with_ctx(|ctx| ctx.find_container(node))?; + + match container { + ChildContainer::DefWithBodyId(def) => { + static RESULT: Mutex = Mutex::new(String::new()); + infer_query_with_inspect( + self.db, + def, + Some(|infer_ctxt, _obligation, result, proof_tree| { + if result.is_err() + && let Some(tree) = proof_tree + { + let data = dump_proof_tree_structured(tree, Span::dummy(), infer_ctxt); + let data = serde_json::to_string_pretty(&data) + .unwrap_or_else(|_| "{}".to_string()); + *RESULT.lock().unwrap() = data; + } + }), + ); + RESULT.lock().ok().map(|s| (*s).clone()) + } + _ => None, + } + } } // FIXME This can't be the best way to do this diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index 0066ceed21ed..5e4d930393af 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -73,7 +73,7 @@ use ide_db::{ }; use ide_db::{MiniCore, ra_fixture::RaFixtureAnalysis}; use macros::UpmapFromRaFixture; -use syntax::{SourceFile, ast}; +use syntax::{AstNode, SourceFile, ast}; use triomphe::Arc; use view_memory_layout::{RecursiveMemoryLayout, view_memory_layout}; @@ -905,6 +905,18 @@ impl Analysis { self.with_db(|db| view_memory_layout(db, position)) } + pub fn get_failed_obligations(&self, offset: TextSize, file_id: FileId) -> Cancellable { + self.with_db(|db| { + let sema = Semantics::new(db); + let source_file = sema.parse_guess_edition(file_id); + + let Some(token) = source_file.syntax().token_at_offset(offset).next() else { + return String::new(); + }; + sema.get_failed_obligations(token).unwrap_or_default() + }) + } + pub fn editioned_file_id_to_vfs(&self, file_id: hir::EditionedFileId) -> FileId { file_id.file_id(&self.db) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index d15b519d6983..4d97505768a2 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -42,8 +42,8 @@ use crate::{ lsp::{ LspError, completion_item_hash, ext::{ - InternalTestingFetchConfigOption, InternalTestingFetchConfigParams, - InternalTestingFetchConfigResponse, + GetFailedObligationsParams, InternalTestingFetchConfigOption, + InternalTestingFetchConfigParams, InternalTestingFetchConfigResponse, }, from_proto, to_proto, utils::{all_edits_are_disjoint, invalid_params_error}, @@ -2575,6 +2575,18 @@ pub(crate) fn internal_testing_fetch_config( })) } +pub(crate) fn get_failed_obligations( + snap: GlobalStateSnapshot, + params: GetFailedObligationsParams, +) -> anyhow::Result { + let _p = tracing::info_span!("get_failed_obligations").entered(); + let file_id = try_default!(from_proto::file_id(&snap, ¶ms.text_document.uri)?); + let line_index = snap.file_line_index(file_id)?; + let offset = from_proto::offset(&line_index, params.position)?; + + Ok(snap.analysis.get_failed_obligations(offset, file_id)?) +} + /// Searches for the directory of a Rust crate given this crate's root file path. /// /// # Arguments diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs index b132323bec5b..e6493eefef17 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs @@ -864,3 +864,18 @@ pub struct CompletionImport { pub struct ClientCommandOptions { pub commands: Vec, } + +pub enum GetFailedObligations {} + +#[derive(Deserialize, Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GetFailedObligationsParams { + pub text_document: TextDocumentIdentifier, + pub position: Position, +} + +impl Request for GetFailedObligations { + type Params = GetFailedObligationsParams; + type Result = String; + const METHOD: &'static str = "rust-analyzer/getFailedObligations"; +} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index 1a1c0182f87a..6e08b7bb88d4 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -1328,6 +1328,7 @@ impl GlobalState { .on::(handlers::handle_move_item) // .on::(handlers::internal_testing_fetch_config) + .on::(handlers::get_failed_obligations) .finish(); } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 48433342d51d..0754e80b1560 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -1488,3 +1488,40 @@ version = "0.0.0" server.request::(Default::default(), json!([])); } + +#[test] +fn test_get_failed_obligations() { + use expect_test::expect; + if skip_slow_tests() { + return; + } + + let server = Project::with_fixture( + r#" +//- /Cargo.toml +[package] +name = "foo" +version = "0.0.0" + +//- /src/lib.rs +trait Trait {} +fn requires_trait(x: T) {} + +fn test() { + requires_trait(0usize); +} +"#, + ) + .server() + .wait_until_workspace_is_loaded(); + + let res = server.send_request::( + rust_analyzer::lsp::ext::GetFailedObligationsParams { + text_document: server.doc_id("src/lib.rs"), + position: Position::new(4, 19), + }, + ); + + expect![[r#""{\n \"goal\": \"Goal { param_env: ParamEnv { clauses: [] }, predicate: Binder { value: TraitPredicate(usize: Trait, polarity:Positive), bound_vars: [] } }\",\n \"result\": \"Err(NoSolution)\",\n \"depth\": 0,\n \"candidates\": []\n}""#]] + .assert_eq(&res.to_string()); +} diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md b/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md index 5922f0b551d6..5d21c37806dd 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md @@ -1,5 +1,5 @@ RUSTLIB/std/src/thread/mod.rs:LL:CC - | -LL | match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside `std::thread::ThreadId::new` at RUSTLIB/std/src/thread/mod.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::thread::current::id::get_or_init` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::thread::current_id` at RUSTLIB/std/src/thread/current.rs:LL:CC - = note: inside `std::rt::init` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC -note: inside `main` - --> tests/genmc/fail/shims/exit.rs:LL:CC - | -LL | / std::thread::spawn(|| { -LL | | unsafe { std::hint::unreachable_unchecked() }; -LL | | }); - | |______^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - | -LL | || self - | ________________^ -LL | | .state -LL | | .compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed) - | |____________________________________________________________________________________^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside `std::sys::sync::PLATFORM::futex::RwLock::read` at RUSTLIB/std/src/sys/sync/PLATFORM/futex.rs:LL:CC - = note: inside `std::sync::RwLock::<()>::read` at RUSTLIB/std/src/sync/poison/rwlock.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::env_read_lock` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::>` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::env::PLATFORM::getenv` at RUSTLIB/std/src/sys/env/PLATFORM.rs:LL:CC - = note: inside `std::env::_var_os` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside `std::env::var_os::<&str>` at RUSTLIB/std/src/env.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/thread/mod.rs:LL:CC -note: inside `main` - --> tests/genmc/fail/shims/exit.rs:LL:CC - | -LL | / std::thread::spawn(|| { -LL | | unsafe { std::hint::unreachable_unchecked() }; -LL | | }); - | |______^ - -warning: GenMC currently does not model spurious failures of `compare_exchange_weak`. Miri with GenMC might miss bugs related to spurious failures. - --> RUSTLIB/std/src/rt.rs:LL:CC - | -LL | / CLEANUP.call_once(|| unsafe { -LL | | // Flush stdout and disable buffering. -LL | | crate::io::cleanup(); -... | -LL | | }); - | |______^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside `std::rt::cleanup` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::process::exit` at RUSTLIB/std/src/process.rs:LL:CC -note: inside `main` - --> tests/genmc/fail/shims/exit.rs:LL:CC - | -LL | std::process::exit(0); - | ^^^^^^^^^^^^^^^^^^^^^ - -warning: GenMC currently does not model the failure ordering for `compare_exchange`. Due to success ordering 'Acquire', the failure ordering 'Relaxed' is treated like 'Acquire'. Miri with GenMC might miss bugs related to this memory access. - --> RUSTLIB/std/src/sys/exit_guard.rs:LL:CC - | -LL | match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code - | - = note: BACKTRACE: - = note: inside `std::sys::exit_guard::unique_thread_exit` at RUSTLIB/std/src/sys/exit_guard.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::os::exit` at RUSTLIB/std/src/sys/pal/PLATFORM/os.rs:LL:CC - = note: inside `std::process::exit` at RUSTLIB/std/src/process.rs:LL:CC -note: inside `main` - --> tests/genmc/fail/shims/exit.rs:LL:CC - | -LL | std::process::exit(0); - | ^^^^^^^^^^^^^^^^^^^^^ - error: Undefined Behavior: entering unreachable code --> tests/genmc/fail/shims/exit.rs:LL:CC | @@ -122,5 +12,5 @@ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report -error: aborting due to 1 previous error; 5 warnings emitted +error: aborting due to 1 previous error From e1f7a22e50bdf640ecbdc522ec38e8dc8fc436e3 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 21 Dec 2025 14:11:48 +0100 Subject: [PATCH 1114/3801] Call out feature freeze on IDE assists --- src/tools/rust-analyzer/CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/rust-analyzer/CONTRIBUTING.md b/src/tools/rust-analyzer/CONTRIBUTING.md index cac352feb180..35d03780c1d5 100644 --- a/src/tools/rust-analyzer/CONTRIBUTING.md +++ b/src/tools/rust-analyzer/CONTRIBUTING.md @@ -1,3 +1,8 @@ +> [!IMPORTANT] +> We have enacted a feature freeze for IDE assists to cope with the PR backlog as well as allowing us to prepare for the rowan transition! +> If you submit a PR that **adds** new ide-assists, chances are very high that we will just close it on this basis alone until we have the capacity to deal with them again. + + # Contributing to rust-analyzer Thank you for your interest in contributing to rust-analyzer! There are many ways to contribute From 37af3f647b4f7e464577d8cc3cd5fb080a827ed9 Mon Sep 17 00:00:00 2001 From: dianqk Date: Sun, 21 Dec 2025 21:32:06 +0800 Subject: [PATCH 1115/3801] GVN: Adds the `insert_unique` method --- compiler/rustc_mir_transform/src/gvn.rs | 43 ++++++++++++------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 526d0e96a36d..0d458402c951 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -420,6 +420,19 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { self.ecx.typing_env() } + fn insert_unique( + &mut self, + ty: Ty<'tcx>, + value: impl FnOnce(VnOpaque) -> Value<'a, 'tcx>, + ) -> VnIndex { + let index = self.values.insert_unique(ty, value); + let _index = self.evaluated.push(None); + debug_assert_eq!(index, _index); + let _index = self.rev_locals.push(SmallVec::new()); + debug_assert_eq!(index, _index); + index + } + #[instrument(level = "trace", skip(self), ret)] fn insert(&mut self, ty: Ty<'tcx>, value: Value<'a, 'tcx>) -> VnIndex { let (index, new) = self.values.insert(ty, value); @@ -437,11 +450,8 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { /// from all the others. #[instrument(level = "trace", skip(self), ret)] fn new_opaque(&mut self, ty: Ty<'tcx>) -> VnIndex { - let index = self.values.insert_unique(ty, Value::Opaque); - let _index = self.evaluated.push(Some(None)); - debug_assert_eq!(index, _index); - let _index = self.rev_locals.push(SmallVec::new()); - debug_assert_eq!(index, _index); + let index = self.insert_unique(ty, Value::Opaque); + self.evaluated[index] = Some(None); index } @@ -470,42 +480,29 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { projection.map(|proj| proj.try_map(|index| self.locals[index], |ty| ty).ok_or(())); let projection = self.arena.try_alloc_from_iter(projection).ok()?; - let index = self.values.insert_unique(ty, |provenance| Value::Address { + let index = self.insert_unique(ty, |provenance| Value::Address { base, projection, kind, provenance, }); - let _index = self.evaluated.push(None); - debug_assert_eq!(index, _index); - let _index = self.rev_locals.push(SmallVec::new()); - debug_assert_eq!(index, _index); - Some(index) } #[instrument(level = "trace", skip(self), ret)] fn insert_constant(&mut self, value: Const<'tcx>) -> VnIndex { - let (index, new) = if value.is_deterministic() { + if value.is_deterministic() { // The constant is deterministic, no need to disambiguate. let constant = Value::Constant { value, disambiguator: None }; - self.values.insert(value.ty(), constant) + self.insert(value.ty(), constant) } else { // Multiple mentions of this constant will yield different values, // so assign a different `disambiguator` to ensure they do not get the same `VnIndex`. - let index = self.values.insert_unique(value.ty(), |disambiguator| Value::Constant { + self.insert_unique(value.ty(), |disambiguator| Value::Constant { value, disambiguator: Some(disambiguator), - }); - (index, true) - }; - if new { - let _index = self.evaluated.push(None); - debug_assert_eq!(index, _index); - let _index = self.rev_locals.push(SmallVec::new()); - debug_assert_eq!(index, _index); + }) } - index } #[inline] From 74af408790acb796ece9aee438b87408ee15a240 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Sun, 21 Dec 2025 18:24:44 +0800 Subject: [PATCH 1116/3801] rustdoc: handle macro expansions in types --- compiler/rustc_ast_pretty/src/pprust/mod.rs | 3 +++ src/librustdoc/html/macro_expansion.rs | 12 +++++++-- .../macro-expansion/type-macro-expansion.rs | 27 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 tests/rustdoc/macro-expansion/type-macro-expansion.rs diff --git a/compiler/rustc_ast_pretty/src/pprust/mod.rs b/compiler/rustc_ast_pretty/src/pprust/mod.rs index a766e2006e59..74ed0405498d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/mod.rs +++ b/compiler/rustc_ast_pretty/src/pprust/mod.rs @@ -33,6 +33,9 @@ pub fn where_bound_predicate_to_string(where_bound_predicate: &ast::WhereBoundPr State::new().where_bound_predicate_to_string(where_bound_predicate) } +/// # Panics +/// +/// Panics if `pat.kind` is `PatKind::Missing`. pub fn pat_to_string(pat: &ast::Pat) -> String { State::new().pat_to_string(pat) } diff --git a/src/librustdoc/html/macro_expansion.rs b/src/librustdoc/html/macro_expansion.rs index 9098e92a5cd4..d3c91be3a280 100644 --- a/src/librustdoc/html/macro_expansion.rs +++ b/src/librustdoc/html/macro_expansion.rs @@ -1,5 +1,5 @@ -use rustc_ast::visit::{Visitor, walk_crate, walk_expr, walk_item, walk_pat, walk_stmt}; -use rustc_ast::{Crate, Expr, Item, Pat, Stmt}; +use rustc_ast::visit::{Visitor, walk_crate, walk_expr, walk_item, walk_pat, walk_stmt, walk_ty}; +use rustc_ast::{Crate, Expr, Item, Pat, Stmt, Ty}; use rustc_data_structures::fx::FxHashMap; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, Span}; @@ -153,4 +153,12 @@ impl<'ast> Visitor<'ast> for ExpandedCodeVisitor<'ast> { walk_pat(self, pat); } } + + fn visit_ty(&mut self, ty: &'ast Ty) { + if ty.span.from_expansion() { + self.handle_new_span(ty.span, || rustc_ast_pretty::pprust::ty_to_string(ty)); + } else { + walk_ty(self, ty); + } + } } diff --git a/tests/rustdoc/macro-expansion/type-macro-expansion.rs b/tests/rustdoc/macro-expansion/type-macro-expansion.rs new file mode 100644 index 000000000000..d7d28fdac666 --- /dev/null +++ b/tests/rustdoc/macro-expansion/type-macro-expansion.rs @@ -0,0 +1,27 @@ +// Ensure macro invocations at type position are expanded correctly + +//@ compile-flags: -Zunstable-options --generate-macro-expansion + +#![crate_name = "foo"] + +//@ has 'src/foo/type-macro-expansion.rs.html' + +macro_rules! foo { + () => { + fn(()) + }; + ($_arg:expr) => { + [(); 1] + }; +} + +fn bar() { + //@ has - '//*[@class="expansion"]/*[@class="original"]/*[@class="macro"]' 'foo!' + //@ has - '//*[@class="expansion"]/*[@class="original"]' 'foo!()' + //@ has - '//*[@class="expansion"]/*[@class="expanded"]' 'fn(())' + let _: foo!(); + //@ has - '//*[@class="expansion"]/*[@class="original"]/*[@class="macro"]' 'foo!' + //@ has - '//*[@class="expansion"]/*[@class="original"]' 'foo!(42)' + //@ has - '//*[@class="expansion"]/*[@class="expanded"]' '[(); 1]' + let _: foo!(42); +} From d2eaec9e258f4e02989b23cfecda681e05101307 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 21 Dec 2025 08:46:13 -0700 Subject: [PATCH 1117/3801] Clean up needlessly complex math and conditions Co-authored-by: Guillaume Gomez --- src/librustdoc/html/static/js/stringdex.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/static/js/stringdex.js b/src/librustdoc/html/static/js/stringdex.js index d04fd6c0e451..e45c8bcd653b 100644 --- a/src/librustdoc/html/static/js/stringdex.js +++ b/src/librustdoc/html/static/js/stringdex.js @@ -57,7 +57,7 @@ class RoaringBitmap { } else if (u8array[i] > 0xe0) { // Special representation of tiny sets that are runs const lspecial = u8array[i] & 0x0f; - this.keysAndCardinalities = new Uint8Array(lspecial * 4); + this.keysAndCardinalities = new Uint8Array(lspecial << 2); i += 1; const key = u8array[i + 2] | (u8array[i + 3] << 8); const value = u8array[i] | (u8array[i + 1] << 8); @@ -74,7 +74,7 @@ class RoaringBitmap { } else if (u8array[i] > 0xd0) { // Special representation of tiny sets that are close together const lspecial = u8array[i] & 0x0f; - this.keysAndCardinalities = new Uint8Array(lspecial * 4); + this.keysAndCardinalities = new Uint8Array(lspecial << 2); let pspecial = i + 1; let key = u8array[pspecial + 2] | (u8array[pspecial + 3] << 8); let value = u8array[pspecial] | (u8array[pspecial + 1] << 8); @@ -93,8 +93,8 @@ class RoaringBitmap { key = entry >> 16; container = this.addToArrayAt(key); const cardinalityOld = container.cardinality; - container.array[cardinalityOld * 2] = value & 0xFF; - container.array[(cardinalityOld * 2) + 1] = (value >> 8) & 0xFF; + container.array[cardinalityOld << 1] = value & 0xFF; + container.array[(cardinalityOld << 1) + 1] = (value >> 8) & 0xFF; container.cardinality = cardinalityOld + 1; pspecial += 1; } @@ -2409,7 +2409,7 @@ function loadDatabase(hooks) { encoded.subarray(i, i + (branch_leaves_count * 2)), ), ]; - i += branch_leaves_count * 2; + i += branch_leaves_count << 1; } branch_nodes.push(Promise.resolve( is_suffixes_only ? @@ -2465,7 +2465,7 @@ function loadDatabase(hooks) { encoded.subarray(i, i + (leaves_count * 2)), ), ]; - i += leaves_count * 2; + i += leaves_count << 1; } } return is_suffixes_only ? @@ -3054,8 +3054,7 @@ function loadDatabase(hooks) { const leaves_count = no_leaves_flag !== 0 ? 0 : ((compression_tag >> 4) & 0x07) + 1; - const leaves_is_run = no_leaves_flag !== 0 ? - false : + const leaves_is_run = no_leaves_flag === 0 && ((compression_tag >> 4) & 0x08) !== 0; const branch_count = is_long_compressed ? ((compression_tag >> 8) & 0xff) + 1 : @@ -3086,7 +3085,7 @@ function loadDatabase(hooks) { if (branch_leaves_is_run) { i += 2; } else { - i += branch_leaves_count * 2; + i += branch_leaves_count << 1; } } // branch keys @@ -3095,7 +3094,7 @@ function loadDatabase(hooks) { if (leaves_is_run) { i += 2; } else { - i += leaves_count * 2; + i += leaves_count << 1; } if (is_data_compressed) { const clen = ( From 38c667265b18caa3b0d0ac2b281c4ea928ee3459 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sun, 21 Dec 2025 21:35:10 +0100 Subject: [PATCH 1118/3801] add `expected_non_empty_string_literal` to attribute parser Signed-off-by: Edvin Bryntesson --- compiler/rustc_attr_parsing/src/context.rs | 4 ++++ compiler/rustc_attr_parsing/src/session_diagnostics.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index df4970d8aa90..9aa0729c5790 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -498,6 +498,10 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNameValueOrNoArgs) } + pub(crate) fn expected_non_empty_string_literal(&self, span: Span) -> ErrorGuaranteed { + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNonEmptyStringLiteral) + } + pub(crate) fn expected_no_args(&self, span: Span) -> ErrorGuaranteed { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNoArgs) } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 73b65193fd34..d9998a15f233 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -521,6 +521,7 @@ pub(crate) enum AttributeParseErrorReason<'a> { ExpectedList, ExpectedListOrNoArgs, ExpectedNameValueOrNoArgs, + ExpectedNonEmptyStringLiteral, UnexpectedLiteral, ExpectedNameValue(Option), DuplicateKey(Symbol), @@ -599,6 +600,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { AttributeParseErrorReason::ExpectedNameValueOrNoArgs => { diag.span_label(self.span, "didn't expect a list here"); } + AttributeParseErrorReason::ExpectedNonEmptyStringLiteral => { + diag.span_label(self.span, "string is not allowed to be empty"); + } AttributeParseErrorReason::DuplicateKey(key) => { diag.span_label(self.span, format!("found `{key}` used as a key more than once")); diag.code(E0538); From d719a49b28a0da4d91c4fd0fd8ccd71cbfa0d491 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sun, 21 Dec 2025 21:45:15 +0100 Subject: [PATCH 1119/3801] Port `#[cfi_encoding]` to attribute parser --- .../src/attributes/cfi_encoding.rs | 33 +++++++++ .../rustc_attr_parsing/src/attributes/mod.rs | 1 + compiler/rustc_attr_parsing/src/context.rs | 2 + .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 68 ++++++------------- .../cfi/typeid/itanium_cxx_abi/transform.rs | 11 +-- tests/ui/attributes/malformed-attrs.rs | 2 +- tests/ui/attributes/malformed-attrs.stderr | 15 ++-- .../cfi/invalid-attr-encoding.stderr | 8 ++- 11 files changed, 83 insertions(+), 63 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs diff --git a/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs b/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs new file mode 100644 index 000000000000..df1e569743c0 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs @@ -0,0 +1,33 @@ +use super::prelude::*; +pub(crate) struct CfiEncodingParser; +impl SingleAttributeParser for CfiEncodingParser { + const PATH: &[Symbol] = &[sym::cfi_encoding]; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + Allow(Target::Struct), + Allow(Target::ForeignTy), + Allow(Target::Enum), + Allow(Target::Union), + ]); + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(name_value) = args.name_value() else { + cx.expected_name_value(cx.attr_span, Some(sym::cfi_encoding)); + return None; + }; + + let Some(value_str) = name_value.value_as_str() else { + cx.expected_string_literal(name_value.value_span, None); + return None; + }; + + if value_str.as_str().trim().is_empty() { + cx.expected_non_empty_string_literal(name_value.value_span); + return None; + } + + Some(AttributeKind::CfiEncoding { encoding: value_str }) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index f7290bd7e6f2..c39c60ea7e39 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -33,6 +33,7 @@ pub(crate) mod allow_unstable; pub(crate) mod body; pub(crate) mod cfg; pub(crate) mod cfg_select; +pub(crate) mod cfi_encoding; pub(crate) mod codegen_attrs; pub(crate) mod confusables; pub(crate) mod crate_level; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9aa0729c5790..9a443dfbb842 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -19,6 +19,7 @@ use crate::attributes::allow_unstable::{ AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser, }; use crate::attributes::body::CoroutineParser; +use crate::attributes::cfi_encoding::CfiEncodingParser; use crate::attributes::codegen_attrs::{ ColdParser, CoverageParser, EiiExternItemParser, ExportNameParser, ForceTargetFeatureParser, NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser, @@ -187,6 +188,7 @@ attribute_parsers!( // tidy-alphabetical-end // tidy-alphabetical-start + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index e9f9b2445deb..39530f5c3f8b 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -703,6 +703,9 @@ pub enum AttributeKind { span: Span, }, + /// Represents `#[cfi_encoding]` + CfiEncoding { encoding: Symbol }, + /// Represents `#[rustc_coinductive]`. Coinductive(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 68456dfe4c29..6d159a6ee68a 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -26,6 +26,7 @@ impl AttributeKind { AsPtr(..) => Yes, AutomaticallyDerived(..) => Yes, BodyStability { .. } => No, + CfiEncoding { .. } => Yes, Coinductive(..) => No, Cold(..) => No, Confusables { .. } => Yes, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7822614a05cb..fae269bfdcf1 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -298,6 +298,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::PinV2(..) | AttributeKind::WindowsSubsystem(..) | AttributeKind::ThreadLocal + | AttributeKind::CfiEncoding { .. } ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -336,7 +337,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::cfg_trace | sym::cfg_attr_trace // need to be fixed - | sym::cfi_encoding // FIXME(cfi_encoding) | sym::instruction_set // broken on stable!!! | sym::patchable_function_entry // FIXME(patchable_function_entry) | sym::deprecated_safe // FIXME(deprecated_safe) 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 60b3b42989b7..5505fe82cea6 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 @@ -11,6 +11,8 @@ use rustc_abi::{ExternAbi, Integer}; use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; use rustc_middle::bug; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ @@ -18,7 +20,6 @@ use rustc_middle::ty::{ IntTy, List, Region, RegionKind, TermKind, Ty, TyCtxt, TypeFoldable, UintTy, }; use rustc_span::def_id::DefId; -use rustc_span::sym; use tracing::instrument; use crate::cfi::typeid::TypeIdOptions; @@ -446,36 +447,20 @@ pub(crate) fn encode_ty<'tcx>( ty::Adt(adt_def, args) => { let mut s = String::new(); let def_id = adt_def.did(); - if let Some(cfi_encoding) = tcx.get_attr(def_id, sym::cfi_encoding) { + if let Some(encoding) = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::CfiEncoding { encoding } => encoding) + { + let encoding = encoding.as_str().trim(); // Use user-defined CFI encoding for type - if let Some(value_str) = cfi_encoding.value_str() { - let value_str = value_str.as_str().trim(); - if !value_str.is_empty() { - s.push_str(value_str); - // Don't compress user-defined builtin types (see - // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-builtin and - // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression). - let builtin_types = [ - "v", "w", "b", "c", "a", "h", "s", "t", "i", "j", "l", "m", "x", "y", - "n", "o", "f", "d", "e", "g", "z", "Dh", - ]; - if !builtin_types.contains(&value_str) { - compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); - } - } else { - #[allow( - rustc::diagnostic_outside_of_impl, - rustc::untranslatable_diagnostic - )] - tcx.dcx() - .struct_span_err( - cfi_encoding.span(), - format!("invalid `cfi_encoding` for `{:?}`", ty.kind()), - ) - .emit(); - } - } else { - bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind()); + s.push_str(&encoding); + // Don't compress user-defined builtin types (see + // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-builtin and + // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression). + let builtin_types = [ + "v", "w", "b", "c", "a", "h", "s", "t", "i", "j", "l", "m", "x", "y", "n", "o", + "f", "d", "e", "g", "z", "Dh", + ]; + if !builtin_types.contains(&encoding) { + compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); } } else if options.contains(EncodeTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() { // For cross-language LLVM CFI support, the encoding must be compatible at the FFI @@ -508,26 +493,11 @@ pub(crate) fn encode_ty<'tcx>( ty::Foreign(def_id) => { // , where is let mut s = String::new(); - if let Some(cfi_encoding) = tcx.get_attr(*def_id, sym::cfi_encoding) { + + if let Some(encoding) = find_attr!(tcx.get_all_attrs(*def_id), AttributeKind::CfiEncoding {encoding} => encoding) + { // Use user-defined CFI encoding for type - if let Some(value_str) = cfi_encoding.value_str() { - if !value_str.to_string().trim().is_empty() { - s.push_str(value_str.to_string().trim()); - } else { - #[allow( - rustc::diagnostic_outside_of_impl, - rustc::untranslatable_diagnostic - )] - tcx.dcx() - .struct_span_err( - cfi_encoding.span(), - format!("invalid `cfi_encoding` for `{:?}`", ty.kind()), - ) - .emit(); - } - } else { - bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind()); - } + s.push_str(encoding.as_str().trim()); } else { let name = tcx.item_name(*def_id).to_string(); let _ = write!(s, "{}{}", name.len(), name); diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 28481f3dcdb3..9cea681fcb57 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -6,15 +6,15 @@ use std::iter; -use rustc_hir as hir; -use rustc_hir::LangItem; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{self as hir, LangItem, find_attr}; use rustc_middle::bug; use rustc_middle::ty::{ self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy, }; +use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; -use rustc_span::{DUMMY_SP, sym}; use rustc_trait_selection::traits; use tracing::{debug, instrument}; @@ -138,7 +138,10 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { { // Don't transform repr(transparent) types with an user-defined CFI encoding to // preserve the user-defined CFI encoding. - if let Some(_) = self.tcx.get_attr(adt_def.did(), sym::cfi_encoding) { + if find_attr!( + self.tcx.get_all_attrs(adt_def.did()), + AttributeKind::CfiEncoding { .. } + ) { return t; } let variant = adt_def.non_enum_variant(); diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 37ccf9faa1a3..b0d8fd774f74 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -137,7 +137,7 @@ pub fn test3() {} //~^ ERROR malformed #[must_not_suspend()] //~^ ERROR malformed -#[cfi_encoding] +#[cfi_encoding = ""] //~^ ERROR malformed struct Test; diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index d0e5cb631c1e..860dcdb349bf 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -55,12 +55,6 @@ LL - #[must_not_suspend()] LL + #[must_not_suspend] | -error: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:140:1 - | -LL | #[cfi_encoding] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` - error: malformed `allow` attribute input --> $DIR/malformed-attrs.rs:184:1 | @@ -530,6 +524,15 @@ LL | #[rustc_layout_scalar_valid_range_end] | expected this to be a list | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` +error[E0539]: malformed `cfi_encoding` attribute input + --> $DIR/malformed-attrs.rs:140:1 + | +LL | #[cfi_encoding = ""] + | ^^^^^^^^^^^^^^^^^--^ + | | | + | | string is not allowed to be empty + | help: must be of the form: `#[cfi_encoding = "encoding"]` + error[E0565]: malformed `marker` attribute input --> $DIR/malformed-attrs.rs:161:1 | diff --git a/tests/ui/sanitizer/cfi/invalid-attr-encoding.stderr b/tests/ui/sanitizer/cfi/invalid-attr-encoding.stderr index 1aa6bef17b1e..e95006c0ef61 100644 --- a/tests/ui/sanitizer/cfi/invalid-attr-encoding.stderr +++ b/tests/ui/sanitizer/cfi/invalid-attr-encoding.stderr @@ -1,8 +1,12 @@ -error: malformed `cfi_encoding` attribute input +error[E0539]: malformed `cfi_encoding` attribute input --> $DIR/invalid-attr-encoding.rs:10:1 | LL | #[cfi_encoding] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` + | ^^^^^^^^^^^^^^^ + | | + | expected this to be of the form `cfi_encoding = "..."` + | help: must be of the form: `#[cfi_encoding = "encoding"]` error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. From dcb19a0a1e74d4c8a9f6df825d555ff761314d16 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 21 Dec 2025 22:31:25 +0100 Subject: [PATCH 1120/3801] Use "parameter" instead of "argument" in the lint message --- clippy_lints/src/needless_pass_by_ref_mut.rs | 2 +- .../needless_pass_by_ref_mut.fixed | 2 +- .../needless_pass_by_ref_mut.rs | 2 +- .../needless_pass_by_ref_mut.stderr | 2 +- tests/ui/needless_pass_by_ref_mut.stderr | 68 +++++++++---------- tests/ui/needless_pass_by_ref_mut2.stderr | 6 +- 6 files changed, 41 insertions(+), 41 deletions(-) diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 904ff538ba36..f3e42b1c58f8 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -284,7 +284,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { NEEDLESS_PASS_BY_REF_MUT, cx.tcx.local_def_id_to_hir_id(*fn_def_id), sp, - "this argument is a mutable reference, but not used mutably", + "this parameter is a mutable reference but is not used mutably", |diag| { diag.span_suggestion( mut_span, diff --git a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed index 40556ca5410f..962a4e00d86e 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed @@ -3,7 +3,7 @@ // Should warn pub fn pub_foo(s: &Vec, b: &u32, x: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut *x += *b + s.len() as u32; } diff --git a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs index bbc63ceb15a3..5f584c6704f2 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs @@ -3,7 +3,7 @@ // Should warn pub fn pub_foo(s: &mut Vec, b: &u32, x: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut *x += *b + s.len() as u32; } diff --git a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr index f79b20ec69fc..57137ab08d1e 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr @@ -1,4 +1,4 @@ -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs:5:19 | LL | pub fn pub_foo(s: &mut Vec, b: &u32, x: &mut u32) { diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr index 90d99b9f0cf6..c427f4c3e42c 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -1,4 +1,4 @@ -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:12:11 | LL | fn foo(s: &mut Vec, b: &u32, x: &mut u32) { @@ -9,7 +9,7 @@ LL | fn foo(s: &mut Vec, b: &u32, x: &mut u32) { = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:38:12 | LL | fn foo6(s: &mut Vec) { @@ -17,7 +17,7 @@ LL | fn foo6(s: &mut Vec) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:49:12 | LL | fn bar(&mut self) {} @@ -25,7 +25,7 @@ LL | fn bar(&mut self) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:52:29 | LL | fn mushroom(&self, vec: &mut Vec) -> usize { @@ -33,7 +33,7 @@ LL | fn mushroom(&self, vec: &mut Vec) -> usize { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:130:16 | LL | async fn a1(x: &mut i32) { @@ -41,7 +41,7 @@ LL | async fn a1(x: &mut i32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:135:16 | LL | async fn a2(x: &mut i32, y: String) { @@ -49,7 +49,7 @@ LL | async fn a2(x: &mut i32, y: String) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:140:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { @@ -57,7 +57,7 @@ LL | async fn a3(x: &mut i32, y: String, z: String) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:145:16 | LL | async fn a4(x: &mut i32, y: i32) { @@ -65,7 +65,7 @@ LL | async fn a4(x: &mut i32, y: i32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:150:24 | LL | async fn a5(x: i32, y: &mut i32) { @@ -73,7 +73,7 @@ LL | async fn a5(x: i32, y: &mut i32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:155:24 | LL | async fn a6(x: i32, y: &mut i32) { @@ -81,7 +81,7 @@ LL | async fn a6(x: i32, y: &mut i32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:160:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { @@ -89,7 +89,7 @@ LL | async fn a7(x: i32, y: i32, z: &mut i32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:165:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { @@ -97,7 +97,7 @@ LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:165:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { @@ -105,7 +105,7 @@ LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:201:16 | LL | fn cfg_warn(s: &mut u32) {} @@ -115,7 +115,7 @@ LL | fn cfg_warn(s: &mut u32) {} | = note: this is cfg-gated and may require further changes -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:206:20 | LL | fn cfg_warn(s: &mut u32) {} @@ -125,7 +125,7 @@ LL | fn cfg_warn(s: &mut u32) {} | = note: this is cfg-gated and may require further changes -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:219:39 | LL | async fn inner_async2(x: &mut i32, y: &mut u32) { @@ -133,7 +133,7 @@ LL | async fn inner_async2(x: &mut i32, y: &mut u32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:228:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { @@ -141,7 +141,7 @@ LL | async fn inner_async3(x: &mut i32, y: &mut u32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:248:30 | LL | async fn call_in_closure1(n: &mut str) { @@ -149,7 +149,7 @@ LL | async fn call_in_closure1(n: &mut str) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:268:16 | LL | fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { @@ -157,7 +157,7 @@ LL | fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:280:22 | LL | async fn closure4(n: &mut usize) { @@ -165,7 +165,7 @@ LL | async fn closure4(n: &mut usize) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:335:12 | LL | fn bar(&mut self) {} @@ -173,7 +173,7 @@ LL | fn bar(&mut self) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:338:18 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { @@ -181,7 +181,7 @@ LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:338:45 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { @@ -189,7 +189,7 @@ LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:347:46 | LL | async fn foo2(&mut self, u: &mut i32, v: &mut u32) { @@ -197,7 +197,7 @@ LL | async fn foo2(&mut self, u: &mut i32, v: &mut u32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:364:18 | LL | fn _empty_tup(x: &mut (())) {} @@ -205,7 +205,7 @@ LL | fn _empty_tup(x: &mut (())) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:366:19 | LL | fn _single_tup(x: &mut ((i32,))) {} @@ -213,7 +213,7 @@ LL | fn _single_tup(x: &mut ((i32,))) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:368:18 | LL | fn _multi_tup(x: &mut ((i32, u32))) {} @@ -221,7 +221,7 @@ LL | fn _multi_tup(x: &mut ((i32, u32))) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:370:11 | LL | fn _fn(x: &mut (fn())) {} @@ -229,7 +229,7 @@ LL | fn _fn(x: &mut (fn())) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:373:23 | LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} @@ -237,7 +237,7 @@ LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:375:20 | LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} @@ -245,7 +245,7 @@ LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:377:18 | LL | fn _unsafe_fn(x: &mut unsafe fn()) {} @@ -253,7 +253,7 @@ LL | fn _unsafe_fn(x: &mut unsafe fn()) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:379:25 | LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} @@ -261,7 +261,7 @@ LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:381:20 | LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} @@ -269,7 +269,7 @@ LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:383:20 | LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} diff --git a/tests/ui/needless_pass_by_ref_mut2.stderr b/tests/ui/needless_pass_by_ref_mut2.stderr index 6af8a4d4a2b5..aa5c412adb4d 100644 --- a/tests/ui/needless_pass_by_ref_mut2.stderr +++ b/tests/ui/needless_pass_by_ref_mut2.stderr @@ -1,4 +1,4 @@ -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut2.rs:8:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { @@ -9,7 +9,7 @@ LL | async fn inner_async3(x: &mut i32, y: &mut u32) { = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut2.rs:17:39 | LL | async fn inner_async4(u: &mut i32, v: &mut u32) { @@ -17,7 +17,7 @@ LL | async fn inner_async4(u: &mut i32, v: &mut u32) { | | | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut2.rs:29:37 | LL | fn issue16267<'a>(msg: &str, slice: &'a mut [i32]) -> &'a [i32] { From 1377de0f0e7e25ee4c4869853456694fc8639363 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sun, 21 Dec 2025 21:20:42 +0000 Subject: [PATCH 1121/3801] fix: `bool_assert_comparison` suggests wrongly for macros --- clippy_lints/src/bool_assert_comparison.rs | 33 ++++++++++++---------- tests/ui/bool_assert_comparison.fixed | 13 +++++++++ tests/ui/bool_assert_comparison.rs | 13 +++++++++ tests/ui/bool_assert_comparison.stderr | 26 ++++++++++++++++- 4 files changed, 69 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/bool_assert_comparison.rs b/clippy_lints/src/bool_assert_comparison.rs index f31b67f470f9..165941a859f7 100644 --- a/clippy_lints/src/bool_assert_comparison.rs +++ b/clippy_lints/src/bool_assert_comparison.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::{find_assert_eq_args, root_macro_call_first_node}; +use clippy_utils::source::walk_span_to_context; use clippy_utils::sugg::Sugg; use clippy_utils::sym; use clippy_utils::ty::{implements_trait, is_copy}; @@ -130,22 +131,24 @@ impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison { let mut suggestions = vec![(name_span, non_eq_mac.to_string()), (lit_span, String::new())]; - if let Some(sugg) = Sugg::hir_opt(cx, non_lit_expr) { - let sugg = if bool_value ^ eq_macro { - !sugg.maybe_paren() - } else if ty::Bool == *non_lit_ty.kind() { - sugg - } else { - !!sugg.maybe_paren() - }; - suggestions.push((non_lit_expr.span, sugg.to_string())); + let mut applicability = Applicability::MachineApplicable; + let sugg = Sugg::hir_with_context(cx, non_lit_expr, macro_call.span.ctxt(), "..", &mut applicability); + let sugg = if bool_value ^ eq_macro { + !sugg.maybe_paren() + } else if ty::Bool == *non_lit_ty.kind() { + sugg + } else { + !!sugg.maybe_paren() + }; + let non_lit_expr_span = + walk_span_to_context(non_lit_expr.span, macro_call.span.ctxt()).unwrap_or(non_lit_expr.span); + suggestions.push((non_lit_expr_span, sugg.to_string())); - diag.multipart_suggestion( - format!("replace it with `{non_eq_mac}!(..)`"), - suggestions, - Applicability::MachineApplicable, - ); - } + diag.multipart_suggestion( + format!("replace it with `{non_eq_mac}!(..)`"), + suggestions, + applicability, + ); }, ); } diff --git a/tests/ui/bool_assert_comparison.fixed b/tests/ui/bool_assert_comparison.fixed index ec76abbef05a..cd390ce0db9d 100644 --- a/tests/ui/bool_assert_comparison.fixed +++ b/tests/ui/bool_assert_comparison.fixed @@ -216,3 +216,16 @@ fn main() { assert!(!(b + b)); //~^ bool_assert_comparison } + +fn issue16279() { + macro_rules! is_empty { + ($x:expr) => { + $x.is_empty() + }; + } + + assert!(!is_empty!("a")); + //~^ bool_assert_comparison + assert!(is_empty!("")); + //~^ bool_assert_comparison +} diff --git a/tests/ui/bool_assert_comparison.rs b/tests/ui/bool_assert_comparison.rs index 40824a23c82e..b2ea5b6ea540 100644 --- a/tests/ui/bool_assert_comparison.rs +++ b/tests/ui/bool_assert_comparison.rs @@ -216,3 +216,16 @@ fn main() { assert_eq!(b + b, false); //~^ bool_assert_comparison } + +fn issue16279() { + macro_rules! is_empty { + ($x:expr) => { + $x.is_empty() + }; + } + + assert_eq!(is_empty!("a"), false); + //~^ bool_assert_comparison + assert_eq!(is_empty!(""), true); + //~^ bool_assert_comparison +} diff --git a/tests/ui/bool_assert_comparison.stderr b/tests/ui/bool_assert_comparison.stderr index 72aa6303a202..b4e8fcf09bb6 100644 --- a/tests/ui/bool_assert_comparison.stderr +++ b/tests/ui/bool_assert_comparison.stderr @@ -444,5 +444,29 @@ LL - assert_eq!(b + b, false); LL + assert!(!(b + b)); | -error: aborting due to 37 previous errors +error: used `assert_eq!` with a literal bool + --> tests/ui/bool_assert_comparison.rs:227:5 + | +LL | assert_eq!(is_empty!("a"), false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(is_empty!("a"), false); +LL + assert!(!is_empty!("a")); + | + +error: used `assert_eq!` with a literal bool + --> tests/ui/bool_assert_comparison.rs:229:5 + | +LL | assert_eq!(is_empty!(""), true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(is_empty!(""), true); +LL + assert!(is_empty!("")); + | + +error: aborting due to 39 previous errors From 85998185db03565dd0dcf523220f513f6f0d8d77 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sun, 21 Dec 2025 21:57:03 +0000 Subject: [PATCH 1122/3801] `cmp_null`: add missing parens and mention of `ptr::null_mut` in its docs --- clippy_lints/src/ptr/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/ptr/mod.rs b/clippy_lints/src/ptr/mod.rs index 6b2647e7b0a2..c4f40a7ffcaa 100644 --- a/clippy_lints/src/ptr/mod.rs +++ b/clippy_lints/src/ptr/mod.rs @@ -45,7 +45,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// This lint checks for equality comparisons with `ptr::null` + /// This lint checks for equality comparisons with `ptr::null` or `ptr::null_mut` /// /// ### Why is this bad? /// It's easier and more readable to use the inherent @@ -56,7 +56,7 @@ declare_clippy_lint! { /// ```rust,ignore /// use std::ptr; /// - /// if x == ptr::null { + /// if x == ptr::null() { /// // .. /// } /// ``` From a4e8d41802d65afa3c814f53482d08b4d077c71f Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sun, 21 Dec 2025 22:01:46 +0000 Subject: [PATCH 1123/3801] fix: `cmp_null` wrongly unmangled macros --- clippy_lints/src/ptr/cmp_null.rs | 7 ++++--- tests/ui/cmp_null.fixed | 20 ++++++++++++++++++++ tests/ui/cmp_null.rs | 20 ++++++++++++++++++++ tests/ui/cmp_null.stderr | 8 +++++++- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/ptr/cmp_null.rs b/clippy_lints/src/ptr/cmp_null.rs index 905b48e6d1d4..f2d1c855eddd 100644 --- a/clippy_lints/src/ptr/cmp_null.rs +++ b/clippy_lints/src/ptr/cmp_null.rs @@ -14,13 +14,14 @@ pub(super) fn check<'tcx>( l: &Expr<'_>, r: &Expr<'_>, ) -> bool { + let mut applicability = Applicability::MachineApplicable; let non_null_path_snippet = match ( is_lint_allowed(cx, CMP_NULL, expr.hir_id), is_null_path(cx, l), is_null_path(cx, r), ) { - (false, true, false) if let Some(sugg) = Sugg::hir_opt(cx, r) => sugg.maybe_paren(), - (false, false, true) if let Some(sugg) = Sugg::hir_opt(cx, l) => sugg.maybe_paren(), + (false, true, false) => Sugg::hir_with_context(cx, r, expr.span.ctxt(), "..", &mut applicability).maybe_paren(), + (false, false, true) => Sugg::hir_with_context(cx, l, expr.span.ctxt(), "..", &mut applicability).maybe_paren(), _ => return false, }; let invert = if op == BinOpKind::Eq { "" } else { "!" }; @@ -32,7 +33,7 @@ pub(super) fn check<'tcx>( "comparing with null is better expressed by the `.is_null()` method", "try", format!("{invert}{non_null_path_snippet}.is_null()",), - Applicability::MachineApplicable, + applicability, ); true } diff --git a/tests/ui/cmp_null.fixed b/tests/ui/cmp_null.fixed index c12279cf12e6..4a0ee439e94a 100644 --- a/tests/ui/cmp_null.fixed +++ b/tests/ui/cmp_null.fixed @@ -38,3 +38,23 @@ fn issue15010() { debug_assert!(!f.is_null()); //~^ cmp_null } + +fn issue16281() { + use std::ptr; + + struct Container { + value: *const i32, + } + let x = Container { value: ptr::null() }; + + macro_rules! dot_value { + ($obj:expr) => { + $obj.value + }; + } + + if dot_value!(x).is_null() { + //~^ cmp_null + todo!() + } +} diff --git a/tests/ui/cmp_null.rs b/tests/ui/cmp_null.rs index 2771a16e00c5..26ea8960e5fb 100644 --- a/tests/ui/cmp_null.rs +++ b/tests/ui/cmp_null.rs @@ -38,3 +38,23 @@ fn issue15010() { debug_assert!(f != std::ptr::null_mut()); //~^ cmp_null } + +fn issue16281() { + use std::ptr; + + struct Container { + value: *const i32, + } + let x = Container { value: ptr::null() }; + + macro_rules! dot_value { + ($obj:expr) => { + $obj.value + }; + } + + if dot_value!(x) == ptr::null() { + //~^ cmp_null + todo!() + } +} diff --git a/tests/ui/cmp_null.stderr b/tests/ui/cmp_null.stderr index 381747cb3c65..51b98d2a2320 100644 --- a/tests/ui/cmp_null.stderr +++ b/tests/ui/cmp_null.stderr @@ -37,5 +37,11 @@ error: comparing with null is better expressed by the `.is_null()` method LL | debug_assert!(f != std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!f.is_null()` -error: aborting due to 6 previous errors +error: comparing with null is better expressed by the `.is_null()` method + --> tests/ui/cmp_null.rs:56:8 + | +LL | if dot_value!(x) == ptr::null() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dot_value!(x).is_null()` + +error: aborting due to 7 previous errors From 3cf9fa54968778d37950ba187b833ef030a693c3 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 20 Dec 2025 22:03:16 +0000 Subject: [PATCH 1124/3801] fix: `result_large_err` FN on closures --- clippy_lints/src/functions/mod.rs | 4 +++ clippy_lints/src/functions/result.rs | 43 ++++++++++++++++++++++++---- tests/ui/result_large_err.rs | 9 ++++++ tests/ui/result_large_err.stderr | 18 +++++++++++- 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/functions/mod.rs b/clippy_lints/src/functions/mod.rs index bdc366f6878a..9a7427ea1447 100644 --- a/clippy_lints/src/functions/mod.rs +++ b/clippy_lints/src/functions/mod.rs @@ -596,4 +596,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions { impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api); ref_option::check_trait_item(cx, item, self.avoid_breaking_exported_api); } + + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + result::check_expr(cx, expr, self.large_error_threshold, &self.large_error_ignored); + } } diff --git a/clippy_lints/src/functions/result.rs b/clippy_lints/src/functions/result.rs index 04e15a1d8a0e..77fec9371425 100644 --- a/clippy_lints/src/functions/result.rs +++ b/clippy_lints/src/functions/result.rs @@ -50,7 +50,7 @@ pub(super) fn check_item<'tcx>( let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); check_result_unit_err(cx, err_ty, fn_header_span, msrv); } - check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored); + check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false); } } @@ -70,7 +70,7 @@ pub(super) fn check_impl_item<'tcx>( let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); check_result_unit_err(cx, err_ty, fn_header_span, msrv); } - check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored); + check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false); } } @@ -87,7 +87,7 @@ pub(super) fn check_trait_item<'tcx>( if cx.effective_visibilities.is_exported(item.owner_id.def_id) { check_result_unit_err(cx, err_ty, fn_header_span, msrv); } - check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored); + check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false); } } } @@ -111,12 +111,15 @@ fn check_result_large_err<'tcx>( hir_ty_span: Span, large_err_threshold: u64, large_err_ignored: &DefIdSet, + is_closure: bool, ) { if let ty::Adt(adt, _) = err_ty.kind() && large_err_ignored.contains(&adt.did()) { return; } + + let subject = if is_closure { "closure" } else { "function" }; if let ty::Adt(adt, subst) = err_ty.kind() && let Some(local_def_id) = adt.did().as_local() && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_def_id) @@ -130,7 +133,7 @@ fn check_result_large_err<'tcx>( cx, RESULT_LARGE_ERR, hir_ty_span, - "the `Err`-variant returned from this function is very large", + format!("the `Err`-variant returned from this {subject} is very large"), |diag| { diag.span_label( def.variants[first_variant.ind].span, @@ -161,7 +164,7 @@ fn check_result_large_err<'tcx>( cx, RESULT_LARGE_ERR, hir_ty_span, - "the `Err`-variant returned from this function is very large", + format!("the `Err`-variant returned from this {subject} is very large"), |diag: &mut Diag<'_, ()>| { diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes")); diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`")); @@ -170,3 +173,33 @@ fn check_result_large_err<'tcx>( } } } + +pub(super) fn check_expr<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'tcx>, + large_err_threshold: u64, + large_err_ignored: &DefIdSet, +) { + if let hir::ExprKind::Closure(closure) = expr.kind + && let ty::Closure(_, args) = cx.typeck_results().expr_ty(expr).kind() + && let closure_sig = args.as_closure().sig() + && let Ok(err_binder) = closure_sig.output().try_map_bound(|output_ty| { + if let ty::Adt(adt, args) = output_ty.kind() + && let [_, err_arg] = args.as_slice() + && let Some(err_ty) = err_arg.as_type() + && adt.is_diag_item(cx, sym::Result) + { + return Ok(err_ty); + } + + Err(()) + }) + { + let err_ty = cx.tcx.instantiate_bound_regions_with_erased(err_binder); + let hir_ty_span = match closure.fn_decl.output { + hir::FnRetTy::Return(hir_ty) => hir_ty.span, + hir::FnRetTy::DefaultReturn(_) => expr.span, + }; + check_result_large_err(cx, err_ty, hir_ty_span, large_err_threshold, large_err_ignored, true); + } +} diff --git a/tests/ui/result_large_err.rs b/tests/ui/result_large_err.rs index fa57b3f553fc..b4ad050df3b7 100644 --- a/tests/ui/result_large_err.rs +++ b/tests/ui/result_large_err.rs @@ -141,3 +141,12 @@ fn _empty_error() -> Result<(), Empty> { } fn main() {} + +fn issue16249() { + type Large = [u8; 1024]; + + let closure = || -> Result<(), Large> { Ok(()) }; + //~^ result_large_err + let closure = || Ok::<(), Large>(()); + //~^ result_large_err +} diff --git a/tests/ui/result_large_err.stderr b/tests/ui/result_large_err.stderr index 72fbc3f58961..fd39179c61cb 100644 --- a/tests/ui/result_large_err.stderr +++ b/tests/ui/result_large_err.stderr @@ -104,5 +104,21 @@ LL | pub fn array_error() -> Result<(), ArrayError<(i32, T), U>> { | = help: try reducing the size of `ArrayError<(i32, T), U>`, for example by boxing large elements or replacing it with `Box>` -error: aborting due to 12 previous errors +error: the `Err`-variant returned from this closure is very large + --> tests/ui/result_large_err.rs:148:25 + | +LL | let closure = || -> Result<(), Large> { Ok(()) }; + | ^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 1024 bytes + | + = help: try reducing the size of `[u8; 1024]`, for example by boxing large elements or replacing it with `Box<[u8; 1024]>` + +error: the `Err`-variant returned from this closure is very large + --> tests/ui/result_large_err.rs:150:19 + | +LL | let closure = || Ok::<(), Large>(()); + | ^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 1024 bytes + | + = help: try reducing the size of `[u8; 1024]`, for example by boxing large elements or replacing it with `Box<[u8; 1024]>` + +error: aborting due to 14 previous errors From 91dec8008c130254efec7e43931e826b01baf2c3 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Mon, 22 Dec 2025 00:15:50 +0100 Subject: [PATCH 1125/3801] add `expected_list_with_num_args_or_more` attribute parsing error --- compiler/rustc_attr_parsing/src/context.rs | 4 ++++ compiler/rustc_attr_parsing/src/session_diagnostics.rs | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index df4970d8aa90..af0aee0b1e0b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -490,6 +490,10 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedList) } + pub(crate) fn expected_list_with_num_args_or_more(&self, args: usize, span: Span) -> ErrorGuaranteed { + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedListWithNumArgsOrMore { args}) + } + pub(crate) fn expected_list_or_no_args(&self, span: Span) -> ErrorGuaranteed { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedListOrNoArgs) } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 73b65193fd34..dfa72effa689 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -520,6 +520,9 @@ pub(crate) enum AttributeParseErrorReason<'a> { ExpectedSingleArgument, ExpectedList, ExpectedListOrNoArgs, + ExpectedListWithNumArgsOrMore { + args: usize, + }, ExpectedNameValueOrNoArgs, UnexpectedLiteral, ExpectedNameValue(Option), @@ -596,6 +599,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { AttributeParseErrorReason::ExpectedListOrNoArgs => { diag.span_label(self.span, "expected a list or no arguments here"); } + AttributeParseErrorReason::ExpectedListWithNumArgsOrMore { args } => { + diag.span_label(self.span, format!("expected {args} or more items")); + } AttributeParseErrorReason::ExpectedNameValueOrNoArgs => { diag.span_label(self.span, "didn't expect a list here"); } From bdc8894004031b063d9201f5297292211c6df791 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 13 Dec 2025 16:41:26 -0500 Subject: [PATCH 1126/3801] Write file with channel to S3 This will let rustup-toolchain-install-master gain support for installing stable artifacts, which is currently only possible when explicitly overriding the channel. That in turn will unblock letting Crater kick off a beta run as soon as both a new beta and a new stable artifact are ready, rather than waiting until the actual release. --- src/bootstrap/src/lib.rs | 18 ++++++------------ src/ci/scripts/upload-artifacts.sh | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index adae9a1b8b08..c9358599012c 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1624,26 +1624,20 @@ impl Build { self.release(&self.version) } - /// Returns the "package version" for a component given the `num` release - /// number. + /// Returns the "package version" for a component. /// /// The package version is typically what shows up in the names of tarballs. - /// For channels like beta/nightly it's just the channel name, otherwise - /// it's the `num` provided. - fn package_vers(&self, num: &str) -> String { + /// For channels like beta/nightly it's just the channel name, otherwise it's the release + /// version. + fn rust_package_vers(&self) -> String { match &self.config.channel[..] { - "stable" => num.to_string(), + "stable" => self.version.to_string(), "beta" => "beta".to_string(), "nightly" => "nightly".to_string(), - _ => format!("{num}-dev"), + _ => format!("{}-dev", self.version), } } - /// Returns the value of `package_vers` above for Rust itself. - fn rust_package_vers(&self) -> String { - self.package_vers(&self.version) - } - /// Returns the `version` string associated with this compiler for Rust /// itself. /// diff --git a/src/ci/scripts/upload-artifacts.sh b/src/ci/scripts/upload-artifacts.sh index 975b4c527267..6c916eb90cbe 100755 --- a/src/ci/scripts/upload-artifacts.sh +++ b/src/ci/scripts/upload-artifacts.sh @@ -6,6 +6,7 @@ set -euo pipefail IFS=$'\n\t' +ci_dir=`cd $(dirname $0)/.. && pwd` source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" upload_dir="$(mktemp -d)" @@ -22,6 +23,22 @@ if [[ "${DEPLOY-0}" -eq "1" ]] || [[ "${DEPLOY_ALT-0}" -eq "1" ]]; then mv "${dist_dir}"/* "${upload_dir}" fi +# We write the release channel into the output so that +# `rustup-toolchain-install-master` or other, similar, tools can automatically +# detect the appropriate name to use for downloading artifacts. +# +# For nightly and beta this isn't strictly necessary as just trying both is +# enough, but stable builds produce artifacts with a version (e.g., +# rust-src-1.92.0.tar.xz) which can't be easily guessed otherwise. +channel=$(releaseChannel) +if [[ "$channel" = "stable" ]]; then + # On stable, artifacts use the version number. See rust_package_vers in + # src/bootstrap/src/lib.rs. + cat "$ci_dir/../version" > "${upload_dir}/package-version" +else + echo "$channel" > "${upload_dir}/package-version" +fi + # CPU usage statistics. cp build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv" From 5fc00306a8ed6eb40b470773988c57d494b2596d Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Mon, 22 Dec 2025 09:40:21 +0800 Subject: [PATCH 1127/3801] tidy: skip target-specific check for run-make-cargo too I forgot to change this when implementing the run-make fission. --- src/tools/tidy/src/target_specific_tests.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index 159d7278bb62..11138de5de76 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -52,8 +52,12 @@ pub fn check(tests_path: &Path, tidy_ctx: TidyCtx) { } }); - // Skip run-make tests as revisions are not supported. - if entry.path().strip_prefix(tests_path).is_ok_and(|rest| rest.starts_with("run-make")) { + // Skip run-make/run-make-cargo tests as revisions are not supported. + if entry + .path() + .strip_prefix(tests_path) + .is_ok_and(|rest| rest.starts_with("run-make") || rest.starts_with("run-make-cargo")) + { return; } From 059655298692949f33754ce62c339b84418ed9ff Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 21 Dec 2025 19:35:57 -0700 Subject: [PATCH 1128/3801] Use arithmetic instead of bitshifts Co-authored-by: Yotam Ofek --- src/librustdoc/html/static/js/stringdex.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/js/stringdex.js b/src/librustdoc/html/static/js/stringdex.js index e45c8bcd653b..720ac58e76e0 100644 --- a/src/librustdoc/html/static/js/stringdex.js +++ b/src/librustdoc/html/static/js/stringdex.js @@ -57,7 +57,7 @@ class RoaringBitmap { } else if (u8array[i] > 0xe0) { // Special representation of tiny sets that are runs const lspecial = u8array[i] & 0x0f; - this.keysAndCardinalities = new Uint8Array(lspecial << 2); + this.keysAndCardinalities = new Uint8Array(lspecial * 4); i += 1; const key = u8array[i + 2] | (u8array[i + 3] << 8); const value = u8array[i] | (u8array[i + 1] << 8); @@ -74,7 +74,7 @@ class RoaringBitmap { } else if (u8array[i] > 0xd0) { // Special representation of tiny sets that are close together const lspecial = u8array[i] & 0x0f; - this.keysAndCardinalities = new Uint8Array(lspecial << 2); + this.keysAndCardinalities = new Uint8Array(lspecial * 4); let pspecial = i + 1; let key = u8array[pspecial + 2] | (u8array[pspecial + 3] << 8); let value = u8array[pspecial] | (u8array[pspecial + 1] << 8); @@ -93,8 +93,8 @@ class RoaringBitmap { key = entry >> 16; container = this.addToArrayAt(key); const cardinalityOld = container.cardinality; - container.array[cardinalityOld << 1] = value & 0xFF; - container.array[(cardinalityOld << 1) + 1] = (value >> 8) & 0xFF; + container.array[cardinalityOld * 2] = value & 0xFF; + container.array[(cardinalityOld * 2) + 1] = (value >> 8) & 0xFF; container.cardinality = cardinalityOld + 1; pspecial += 1; } @@ -2409,7 +2409,7 @@ function loadDatabase(hooks) { encoded.subarray(i, i + (branch_leaves_count * 2)), ), ]; - i += branch_leaves_count << 1; + i += branch_leaves_count * 2; } branch_nodes.push(Promise.resolve( is_suffixes_only ? @@ -2465,7 +2465,7 @@ function loadDatabase(hooks) { encoded.subarray(i, i + (leaves_count * 2)), ), ]; - i += leaves_count << 1; + i += leaves_count * 2; } } return is_suffixes_only ? @@ -3085,7 +3085,7 @@ function loadDatabase(hooks) { if (branch_leaves_is_run) { i += 2; } else { - i += branch_leaves_count << 1; + i += branch_leaves_count * 2; } } // branch keys @@ -3094,7 +3094,7 @@ function loadDatabase(hooks) { if (leaves_is_run) { i += 2; } else { - i += leaves_count << 1; + i += leaves_count * 2; } if (is_data_compressed) { const clen = ( From de0945b2a714673a94e068d0cfad72dc40a0e6c8 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Wed, 10 Dec 2025 17:16:36 +0800 Subject: [PATCH 1129/3801] bootstrap: update comment for `STAGE0_MISSING_TARGETS` --- src/bootstrap/src/core/sanity.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 932a58c954df..67f4eb37b2c1 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -28,11 +28,13 @@ pub struct Finder { path: OsString, } -// During sanity checks, we search for target names to determine if they exist in the compiler's built-in -// target list (`rustc --print target-list`). While a target name may be present in the stage2 compiler, -// it might not yet be included in stage0. In such cases, we handle the targets missing from stage0 in this list. -// -// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). +/// During sanity checks, we search for target tuples to determine if they exist in the compiler's +/// built-in target list (`rustc --print target-list`). While a target tuple may be present in the +/// in-tree compiler, the stage 0 compiler might not yet know about it (assuming not operating with +/// local-rebuild). In such cases, we handle the targets missing from stage 0 in this list. +/// +/// Targets can be removed from this list during the usual release process bootstrap compiler bumps, +/// when the newly-bumped stage 0 compiler now knows about the formerly-missing targets. const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined "riscv64im-unknown-none-elf", From ba9cc48c7a093a95554ab7c38b0f7f6db0fe49dd Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 22 Dec 2025 04:21:46 +0000 Subject: [PATCH 1130/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to f41f40408d719aa9ae0c6bfa17619d8f3f9e5b99. --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index dcf82c94aaee..95e1cd0db37c 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -0208ee09be465f69005a7a12c28d5eccac7d5f34 +f41f40408d719aa9ae0c6bfa17619d8f3f9e5b99 From 4652295a3e60b569536dcf703ed5081c6d36787a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 22 Dec 2025 14:51:02 +1100 Subject: [PATCH 1131/3801] Simplify `TypeFreshener` methods. `freshen_{ty,const}` take a `Result` and just do a fold if the input is `Ok`. It's simpler to do those folds at the call site, and only call `freshen_{ty,const}` in the `Err` case. That way we can also avoid useless fold operations on the results of `new_{int,uint,float}`. Also, make some `bug!` calls more concise. --- compiler/rustc_infer/src/infer/freshen.rs | 122 ++++++++++------------ 1 file changed, 54 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index ddc0b1168062..d614fac40831 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -60,45 +60,35 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { } } - fn freshen_ty(&mut self, input: Result, ty::InferTy>, mk_fresh: F) -> Ty<'tcx> + fn freshen_ty(&mut self, input: ty::InferTy, mk_fresh: F) -> Ty<'tcx> where F: FnOnce(u32) -> Ty<'tcx>, { - match input { - Ok(ty) => ty.fold_with(self), - Err(key) => match self.ty_freshen_map.entry(key) { - Entry::Occupied(entry) => *entry.get(), - Entry::Vacant(entry) => { - let index = self.ty_freshen_count; - self.ty_freshen_count += 1; - let t = mk_fresh(index); - entry.insert(t); - t - } - }, + match self.ty_freshen_map.entry(input) { + Entry::Occupied(entry) => *entry.get(), + Entry::Vacant(entry) => { + let index = self.ty_freshen_count; + self.ty_freshen_count += 1; + let t = mk_fresh(index); + entry.insert(t); + t + } } } - fn freshen_const( - &mut self, - input: Result, ty::InferConst>, - freshener: F, - ) -> ty::Const<'tcx> + fn freshen_const(&mut self, input: ty::InferConst, freshener: F) -> ty::Const<'tcx> where F: FnOnce(u32) -> ty::InferConst, { - match input { - Ok(ct) => ct.fold_with(self), - Err(key) => match self.const_freshen_map.entry(key) { - Entry::Occupied(entry) => *entry.get(), - Entry::Vacant(entry) => { - let index = self.const_freshen_count; - self.const_freshen_count += 1; - let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index)); - entry.insert(ct); - ct - } - }, + match self.const_freshen_map.entry(input) { + Entry::Occupied(entry) => *entry.get(), + Entry::Vacant(entry) => { + let index = self.const_freshen_count; + self.const_freshen_count += 1; + let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index)); + entry.insert(ct); + ct + } } } } @@ -146,21 +136,21 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { match ct.kind() { ty::ConstKind::Infer(ty::InferConst::Var(v)) => { let mut inner = self.infcx.inner.borrow_mut(); - let input = - inner.const_unification_table().probe_value(v).known().ok_or_else(|| { - ty::InferConst::Var(inner.const_unification_table().find(v).vid) - }); - drop(inner); - self.freshen_const(input, ty::InferConst::Fresh) + match inner.const_unification_table().probe_value(v).known() { + Some(const_) => { + drop(inner); + const_.fold_with(self) + } + None => { + let input = + ty::InferConst::Var(inner.const_unification_table().find(v).vid); + self.freshen_const(input, ty::InferConst::Fresh) + } + } } ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => { if i >= self.const_freshen_count { - bug!( - "Encountered a freshend const with id {} \ - but our counter is only at {}", - i, - self.const_freshen_count, - ); + bug!("freshened const id {} exceeds counter {}", i, self.const_freshen_count); } ct } @@ -185,50 +175,46 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { match v { ty::TyVar(v) => { let mut inner = self.infcx.inner.borrow_mut(); - let input = inner - .type_variables() - .probe(v) - .known() - .ok_or_else(|| ty::TyVar(inner.type_variables().root_var(v))); - drop(inner); - Some(self.freshen_ty(input, |n| Ty::new_fresh(self.infcx.tcx, n))) + match inner.type_variables().probe(v).known() { + Some(ty) => { + drop(inner); + Some(ty.fold_with(self)) + } + None => { + let input = ty::TyVar(inner.type_variables().root_var(v)); + Some(self.freshen_ty(input, |n| Ty::new_fresh(self.infcx.tcx, n))) + } + } } ty::IntVar(v) => { let mut inner = self.infcx.inner.borrow_mut(); let value = inner.int_unification_table().probe_value(v); - let input = match value { - ty::IntVarValue::IntType(ty) => Ok(Ty::new_int(self.infcx.tcx, ty)), - ty::IntVarValue::UintType(ty) => Ok(Ty::new_uint(self.infcx.tcx, ty)), + match value { + ty::IntVarValue::IntType(ty) => Some(Ty::new_int(self.infcx.tcx, ty)), + ty::IntVarValue::UintType(ty) => Some(Ty::new_uint(self.infcx.tcx, ty)), ty::IntVarValue::Unknown => { - Err(ty::IntVar(inner.int_unification_table().find(v))) + let input = ty::IntVar(inner.int_unification_table().find(v)); + Some(self.freshen_ty(input, |n| Ty::new_fresh_int(self.infcx.tcx, n))) } - }; - drop(inner); - Some(self.freshen_ty(input, |n| Ty::new_fresh_int(self.infcx.tcx, n))) + } } ty::FloatVar(v) => { let mut inner = self.infcx.inner.borrow_mut(); let value = inner.float_unification_table().probe_value(v); - let input = match value { - ty::FloatVarValue::Known(ty) => Ok(Ty::new_float(self.infcx.tcx, ty)), + match value { + ty::FloatVarValue::Known(ty) => Some(Ty::new_float(self.infcx.tcx, ty)), ty::FloatVarValue::Unknown => { - Err(ty::FloatVar(inner.float_unification_table().find(v))) + let input = ty::FloatVar(inner.float_unification_table().find(v)); + Some(self.freshen_ty(input, |n| Ty::new_fresh_float(self.infcx.tcx, n))) } - }; - drop(inner); - Some(self.freshen_ty(input, |n| Ty::new_fresh_float(self.infcx.tcx, n))) + } } ty::FreshTy(ct) | ty::FreshIntTy(ct) | ty::FreshFloatTy(ct) => { if ct >= self.ty_freshen_count { - bug!( - "Encountered a freshend type with id {} \ - but our counter is only at {}", - ct, - self.ty_freshen_count - ); + bug!("freshened type id {} exceeds counter {}", ct, self.ty_freshen_count); } None } From 1c26670e64367672f01b02608c0257d518f6a4a5 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 3 Sep 2025 08:04:14 +0800 Subject: [PATCH 1132/3801] Fix indent for convert_iter_for_each_to_for Example --- ```rust fn main() { { let it = core::iter::repeat(92); it.$0for_each(|param| match param { (x, y) => println!("x: {}, y: {}", x, y), }); } } ``` **Before this PR**: ```rust fn main() { { let it = core::iter::repeat(92); for param in it { match param { (x, y) => println!("x: {}, y: {}", x, y), } } } } ``` **After this PR**: ```rust fn main() { { let it = core::iter::repeat(92); for param in it { match param { (x, y) => println!("x: {}, y: {}", x, y), } } } } ``` --- .../handlers/convert_iter_for_each_to_for.rs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs index 2eea4f71ed34..63b1a0193bd6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs @@ -3,7 +3,7 @@ use ide_db::famous_defs::FamousDefs; use stdx::format_to; use syntax::{ AstNode, - ast::{self, HasArgList, HasLoopBody, edit_in_place::Indent, syntax_factory::SyntaxFactory}, + ast::{self, HasArgList, HasLoopBody, edit::AstNodeEdit, syntax_factory::SyntaxFactory}, }; use crate::{AssistContext, AssistId, Assists}; @@ -62,10 +62,10 @@ pub(crate) fn convert_iter_for_each_to_for( stmt.as_ref().map_or_else(|| method.indent_level(), ast::ExprStmt::indent_level); let block = match body { - ast::Expr::BlockExpr(block) => block.clone_for_update(), - _ => make.block_expr(Vec::new(), Some(body)), - }; - block.reindent_to(indent); + ast::Expr::BlockExpr(block) => block.reset_indent(), + _ => make.block_expr(Vec::new(), Some(body.reset_indent().indent(1.into()))), + } + .indent(indent); let expr_for_loop = make.expr_for_loop(param, receiver, block); @@ -285,15 +285,23 @@ fn main() { r#" //- minicore: iterators fn main() { - let it = core::iter::repeat(92); - it.$0for_each(|(x, y)| println!("x: {}, y: {}", x, y)); + { + let it = core::iter::repeat(92); + it.$0for_each(|param| match param { + (x, y) => println!("x: {}, y: {}", x, y), + }); + } } "#, r#" fn main() { - let it = core::iter::repeat(92); - for (x, y) in it { - println!("x: {}, y: {}", x, y) + { + let it = core::iter::repeat(92); + for param in it { + match param { + (x, y) => println!("x: {}, y: {}", x, y), + } + } } } "#, From 1bb9ff05c077756e77bcce2d34cab5b079bb4012 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 22 Dec 2025 17:48:37 +1100 Subject: [PATCH 1133/3801] Remove `InferCtxt::freshener`. I have always found this confusingly named, because it creates a new freshener rather than returning an existing one. We can remove it and just use `TypeFreshener::new()` at the two call sites, avoiding this confusion. --- compiler/rustc_infer/src/infer/mod.rs | 6 +----- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 53567c6071e3..571d5117bc91 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -638,7 +638,7 @@ impl<'tcx> InferCtxt<'tcx> { } pub fn freshen>>(&self, t: T) -> T { - t.fold_with(&mut self.freshener()) + t.fold_with(&mut TypeFreshener::new(self)) } /// Returns the origin of the type variable identified by `vid`. @@ -658,10 +658,6 @@ impl<'tcx> InferCtxt<'tcx> { } } - pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> { - freshen::TypeFreshener::new(self) - } - pub fn unresolved_variables(&self) -> Vec> { let mut inner = self.inner.borrow_mut(); let mut vars: Vec> = inner diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ea903bac9d61..43f9d6249771 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -195,7 +195,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { pub fn new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx, - freshener: infcx.freshener(), + freshener: TypeFreshener::new(infcx), intercrate_ambiguity_causes: None, query_mode: TraitQueryMode::Standard, } From 646f583b3aa9f4ea1209be8da5e280a1d47d4685 Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Mon, 22 Dec 2025 19:06:46 +1030 Subject: [PATCH 1134/3801] fix: remove else-if collapse suggestion when all branches contain only an `if {..} else {..}` expression If two `if` arms contain only a single `if {..} else {..}` statement, don't suggest a collapse as this can lead to less readable code. --- clippy_lints/src/collapsible_if.rs | 16 ++++++++++++++++ tests/ui/collapsible_else_if.fixed | 26 ++++++++++++++++++++++++++ tests/ui/collapsible_else_if.rs | 28 ++++++++++++++++++++++++++++ tests/ui/collapsible_else_if.stderr | 24 +++++++++++++++++++++--- 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 0efcb3c77ff6..be07ce1272bd 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -267,6 +267,9 @@ impl LateLintPass<'_> for CollapsibleIf { && !expr.span.from_expansion() { if let Some(else_) = else_ + // Short circuit if both `if` branches contain only a single `if {..} else {}`, as + // collapsing such blocks can lead to less readable code (#4971) + && !(single_inner_if_else(then) && single_inner_if_else(else_)) && let ExprKind::Block(else_, None) = else_.kind { self.check_collapsible_else_if(cx, then.span, else_); @@ -280,6 +283,19 @@ impl LateLintPass<'_> for CollapsibleIf { } } +/// Returns true if `expr` is a block that contains only one `if {..} else {}` statement +fn single_inner_if_else(expr: &Expr<'_>) -> bool { + if let ExprKind::Block(block, None) = expr.kind + && let Some(inner_expr) = expr_block(block) + && let ExprKind::If(_, _, else_) = inner_expr.kind + && else_.is_some() + { + true + } else { + false + } +} + /// If `block` is a block with either one expression or a statement containing an expression, /// return the expression. We don't peel blocks recursively, as extra blocks might be intentional. fn expr_block<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> { diff --git a/tests/ui/collapsible_else_if.fixed b/tests/ui/collapsible_else_if.fixed index d85bbf189075..cd2d9be9f433 100644 --- a/tests/ui/collapsible_else_if.fixed +++ b/tests/ui/collapsible_else_if.fixed @@ -70,6 +70,17 @@ fn main() { } //~^^^^^^^^ collapsible_else_if + if x == "hello" { + if y == "world" { + print!("Hello "); + } else { + println!("world"); + } + } else if let Some(42) = Some(42) { + println!("42"); + } + //~^^^^^ collapsible_else_if + if x == "hello" { print!("Hello "); } else { @@ -78,6 +89,21 @@ fn main() { println!("world!") } } + + if x == "hello" { + if y == "world" { + print!("Hello "); + } else { + println!("world"); + } + } else { + if let Some(42) = Some(42) { + println!("42"); + } else { + println!("!"); + } + } + } #[rustfmt::skip] diff --git a/tests/ui/collapsible_else_if.rs b/tests/ui/collapsible_else_if.rs index 10aef2792adb..75f204328538 100644 --- a/tests/ui/collapsible_else_if.rs +++ b/tests/ui/collapsible_else_if.rs @@ -84,6 +84,19 @@ fn main() { } //~^^^^^^^^ collapsible_else_if + if x == "hello" { + if y == "world" { + print!("Hello "); + } else { + println!("world"); + } + } else { + if let Some(42) = Some(42) { + println!("42"); + } + } + //~^^^^^ collapsible_else_if + if x == "hello" { print!("Hello "); } else { @@ -92,6 +105,21 @@ fn main() { println!("world!") } } + + if x == "hello" { + if y == "world" { + print!("Hello "); + } else { + println!("world"); + } + } else { + if let Some(42) = Some(42) { + println!("42"); + } else { + println!("!"); + } + } + } #[rustfmt::skip] diff --git a/tests/ui/collapsible_else_if.stderr b/tests/ui/collapsible_else_if.stderr index 98109099bae6..ebd78d2b1ffe 100644 --- a/tests/ui/collapsible_else_if.stderr +++ b/tests/ui/collapsible_else_if.stderr @@ -142,7 +142,25 @@ LL + } | error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:100:10 + --> tests/ui/collapsible_else_if.rs:93:12 + | +LL | } else { + | ____________^ +LL | | if let Some(42) = Some(42) { +LL | | println!("42"); +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else if let Some(42) = Some(42) { +LL + println!("42"); +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:128:10 | LL | }else{ | __________^ @@ -151,7 +169,7 @@ LL | | } | |_____^ help: collapse nested if block: `if false {}` error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:139:12 + --> tests/ui/collapsible_else_if.rs:167:12 | LL | } else { | ____________^ @@ -159,5 +177,5 @@ LL | | (if y == "world" { println!("world") } else { println!("!") }) LL | | } | |_____^ help: collapse nested if block: `if y == "world" { println!("world") } else { println!("!") }` -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors From 7b427ce4741d19cbd283635ec1301653937fc230 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 24 Aug 2025 12:02:25 +0800 Subject: [PATCH 1135/3801] Add BreakExpr completion suggest - Move `ide::goto_definition::find_loops` into `ide_db::syntax_helpers::node_ext::find_loops` --- .../ide-completion/src/context/analysis.rs | 13 +- .../ide-completion/src/context/tests.rs | 119 ++++++++++++++++++ .../ide-db/src/syntax_helpers/node_ext.rs | 42 +++++++ .../crates/ide/src/goto_definition.rs | 53 +------- .../crates/ide/src/highlight_related.rs | 6 +- 5 files changed, 177 insertions(+), 56 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index ce26d3806cc4..49fb36ad04f8 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -2,7 +2,9 @@ use std::iter; use hir::{ExpandResult, InFile, Semantics, Type, TypeInfo, Variant}; -use ide_db::{RootDatabase, active_parameter::ActiveParameter}; +use ide_db::{ + RootDatabase, active_parameter::ActiveParameter, syntax_helpers::node_ext::find_loops, +}; use itertools::Either; use stdx::always; use syntax::{ @@ -779,6 +781,12 @@ fn expected_type_and_name<'db>( }); (ty, None) }, + ast::BreakExpr(it) => { + let ty = it.break_token() + .and_then(|it| find_loops(sema, &it)?.next()) + .and_then(|expr| sema.type_of_expr(&expr)); + (ty.map(TypeInfo::original), None) + }, ast::ClosureExpr(it) => { let ty = sema.type_of_expr(&it.into()); ty.and_then(|ty| ty.original.as_callable(sema.db)) @@ -2059,7 +2067,8 @@ fn prev_special_biased_token_at_trivia(mut token: SyntaxToken) -> SyntaxToken { | T![|] | T![return] | T![break] - | T![continue] = prev.kind() + | T![continue] + | T![lifetime_ident] = prev.kind() { token = prev } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs index 09a9b6f112f0..e97d9720e3f3 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs @@ -635,6 +635,125 @@ fn foo() { ); } +#[test] +fn expected_type_break_expr_in_loop() { + check_expected_type_and_name( + r#" +enum State { Stop } +fn foo() { + let _x: State = loop { + { + break State::Stop; + break $0; + } + }; +} +"#, + expect![[r#"ty: State, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +enum State { Stop } +fn foo() { + let _x: State = 'a: loop { + { + break State::Stop; + break $0; + } + }; +} +"#, + expect![[r#"ty: State, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +enum State { Stop } +fn foo() { + let _x: State = 'a: loop { + while true { + break $0; + } + }; +} +"#, + expect![[r#"ty: (), name: ?"#]], + ); +} + +#[test] +fn expected_type_break_expr_in_labeled_loop() { + check_expected_type_and_name( + r#" +enum State { Stop } +fn foo() { + let _x: State = 'a: loop { + let _y: i32 = loop { + { + break 'a State::Stop; + break 'a $0; + } + }; + }; +} +"#, + expect![[r#"ty: State, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +enum State { Stop } +fn foo() { + let _x: State = 'a: loop { + let _y: i32 = loop { + while true { + break 'a State::Stop; + break 'a $0; + } + }; + }; +} +"#, + expect![[r#"ty: State, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +enum State { Stop } +fn foo() { + 'a: while true { + let _x: State = loop { + break State::Stop; + break 'a $0; + }; + } +} +"#, + expect![[r#"ty: (), name: ?"#]], + ); +} + +#[test] +fn expected_type_break_expr_in_labeled_block() { + check_expected_type_and_name( + r#" +enum State { Stop } +fn foo() { + let _x: State = 'a: { + let _y: i32 = 'b: { + { + break 'a State::Stop; + break 'a $0; + }; + }; + }; +} +"#, + expect![[r#"ty: State, name: ?"#]], + ); +} + #[test] fn expected_type_logic_op() { check_expected_type_and_name( diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs index e1d140730edc..acce066b8323 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs @@ -419,6 +419,48 @@ pub fn eq_label_lt(lt1: &Option, lt2: &Option) -> lt1.as_ref().zip(lt2.as_ref()).is_some_and(|(lt, lbl)| lt.text() == lbl.text()) } +/// Find the loop or block to break or continue, multiple results may be caused by macros. +pub fn find_loops( + sema: &hir::Semantics<'_, crate::RootDatabase>, + token: &syntax::SyntaxToken, +) -> Option> { + let parent = token.parent()?; + let lbl = syntax::match_ast! { + match parent { + ast::BreakExpr(break_) => break_.lifetime(), + ast::ContinueExpr(continue_) => continue_.lifetime(), + _ => None, + } + }; + let label_matches = + move |it: Option| match (lbl.as_ref(), it.and_then(|it| it.lifetime())) { + (Some(lbl), Some(it)) => lbl.text() == it.text(), + (None, _) => true, + (Some(_), None) => false, + }; + + let find_ancestors = move |token| { + for anc in sema.token_ancestors_with_macros(token).filter_map(ast::Expr::cast) { + let node = match &anc { + ast::Expr::LoopExpr(loop_) if label_matches(loop_.label()) => anc, + ast::Expr::WhileExpr(while_) if label_matches(while_.label()) => anc, + ast::Expr::ForExpr(for_) if label_matches(for_.label()) => anc, + ast::Expr::BlockExpr(blk) + if blk.label().is_some() && label_matches(blk.label()) => + { + anc + } + _ => continue, + }; + + return Some(node); + } + None + }; + + sema.descend_into_macros(token.clone()).into_iter().filter_map(find_ancestors).into() +} + struct TreeWithDepthIterator { preorder: Preorder, depth: u32, diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs index b00aa4d0ca67..c0a74380810b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs +++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs @@ -16,15 +16,12 @@ use ide_db::{ defs::{Definition, IdentClass}, famous_defs::FamousDefs, helpers::pick_best_token, + syntax_helpers::node_ext::find_loops, }; use itertools::Itertools; use span::FileId; use syntax::{ - AstNode, AstToken, - SyntaxKind::*, - SyntaxNode, SyntaxToken, T, TextRange, - ast::{self, HasLoopBody}, - match_ast, + AstNode, AstToken, SyntaxKind::*, SyntaxNode, SyntaxToken, T, TextRange, ast, match_ast, }; #[derive(Debug)] @@ -510,51 +507,6 @@ fn nav_for_branch_exit_points( Some(navs) } -pub(crate) fn find_loops( - sema: &Semantics<'_, RootDatabase>, - token: &SyntaxToken, -) -> Option> { - let parent = token.parent()?; - let lbl = match_ast! { - match parent { - ast::BreakExpr(break_) => break_.lifetime(), - ast::ContinueExpr(continue_) => continue_.lifetime(), - _ => None, - } - }; - let label_matches = - |it: Option| match (lbl.as_ref(), it.and_then(|it| it.lifetime())) { - (Some(lbl), Some(it)) => lbl.text() == it.text(), - (None, _) => true, - (Some(_), None) => false, - }; - - let find_ancestors = |token: SyntaxToken| { - for anc in sema.token_ancestors_with_macros(token).filter_map(ast::Expr::cast) { - let node = match &anc { - ast::Expr::LoopExpr(loop_) if label_matches(loop_.label()) => anc, - ast::Expr::WhileExpr(while_) if label_matches(while_.label()) => anc, - ast::Expr::ForExpr(for_) if label_matches(for_.label()) => anc, - ast::Expr::BlockExpr(blk) - if blk.label().is_some() && label_matches(blk.label()) => - { - anc - } - _ => continue, - }; - - return Some(node); - } - None - }; - - sema.descend_into_macros(token.clone()) - .into_iter() - .filter_map(find_ancestors) - .collect_vec() - .into() -} - fn nav_for_break_points( sema: &Semantics<'_, RootDatabase>, token: &SyntaxToken, @@ -562,7 +514,6 @@ fn nav_for_break_points( let db = sema.db; let navs = find_loops(sema, token)? - .into_iter() .filter_map(|expr| { let file_id = sema.hir_file_for(expr.syntax()); let expr_in_file = InFile::new(file_id, expr.clone()); diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs index acba573cc00e..fce033382b4b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs +++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs @@ -7,8 +7,8 @@ use ide_db::{ helpers::pick_best_token, search::{FileReference, ReferenceCategory, SearchScope}, syntax_helpers::node_ext::{ - eq_label_lt, for_each_tail_expr, full_path_of_name_ref, is_closure_or_blk_with_modif, - preorder_expr_with_ctx_checker, + eq_label_lt, find_loops, for_each_tail_expr, full_path_of_name_ref, + is_closure_or_blk_with_modif, preorder_expr_with_ctx_checker, }, }; use syntax::{ @@ -562,7 +562,7 @@ pub(crate) fn highlight_break_points( Some(highlights) } - let Some(loops) = goto_definition::find_loops(sema, &token) else { + let Some(loops) = find_loops(sema, &token) else { return FxHashMap::default(); }; From a8e5693797b42df429929d372179567035d5e1a0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 22 Dec 2025 13:29:11 +0100 Subject: [PATCH 1136/3801] split up tracking issue for target feature feature gates --- compiler/rustc_feature/src/unstable.rs | 81 +++++++++++---------- library/std_detect/src/detect/arch/s390x.rs | 24 +++--- tests/ui/target-feature/gate.stderr | 2 +- 3 files changed, 57 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 692cba8035c4..072543871e31 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -319,47 +319,14 @@ declare_features! ( // feature-group-end: internal feature gates // ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- - // feature-group-start: actual feature gates (target features) - // ------------------------------------------------------------------------- - - // FIXME: Document these and merge with the list below. - - // Unstable `#[target_feature]` directives. - (unstable, aarch64_unstable_target_feature, "1.82.0", Some(44839)), - (unstable, aarch64_ver_target_feature, "1.27.0", Some(44839)), - (unstable, apx_target_feature, "1.88.0", Some(139284)), - (unstable, arm_target_feature, "1.27.0", Some(44839)), - (unstable, bpf_target_feature, "1.54.0", Some(44839)), - (unstable, csky_target_feature, "1.73.0", Some(44839)), - (unstable, ermsb_target_feature, "1.49.0", Some(44839)), - (unstable, hexagon_target_feature, "1.27.0", Some(44839)), - (unstable, lahfsahf_target_feature, "1.78.0", Some(44839)), - (unstable, loongarch_target_feature, "1.73.0", Some(44839)), - (unstable, m68k_target_feature, "1.85.0", Some(134328)), - (unstable, mips_target_feature, "1.27.0", Some(44839)), - (unstable, movrs_target_feature, "1.88.0", Some(137976)), - (unstable, nvptx_target_feature, "1.91.0", Some(44839)), - (unstable, powerpc_target_feature, "1.27.0", Some(44839)), - (unstable, prfchw_target_feature, "1.78.0", Some(44839)), - (unstable, riscv_target_feature, "1.45.0", Some(44839)), - (unstable, rtm_target_feature, "1.35.0", Some(44839)), - (unstable, s390x_target_feature, "1.82.0", Some(44839)), - (unstable, sparc_target_feature, "1.84.0", Some(132783)), - (unstable, wasm_target_feature, "1.30.0", Some(44839)), - (unstable, x87_target_feature, "1.85.0", Some(44839)), - // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! - // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. - // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! - - // ------------------------------------------------------------------------- - // feature-group-end: actual feature gates (target features) - // ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- // feature-group-start: actual feature gates // ------------------------------------------------------------------------- + /// The remaining unstable target features on aarch64. + (unstable, aarch64_unstable_target_feature, "1.82.0", Some(150244)), + /// Instruction set "version" target features on aarch64. + (unstable, aarch64_ver_target_feature, "1.27.0", Some(150245)), /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`. (unstable, abi_avr_interrupt, "1.45.0", Some(69664)), /// Allows `extern "cmse-nonsecure-call" fn()`. @@ -380,10 +347,14 @@ declare_features! ( (unstable, adt_const_params, "1.56.0", Some(95174)), /// Allows defining an `#[alloc_error_handler]`. (unstable, alloc_error_handler, "1.29.0", Some(51540)), + /// The `apxf` target feature on x86 + (unstable, apx_target_feature, "1.88.0", Some(139284)), /// Allows inherent and trait methods with arbitrary self types. (unstable, arbitrary_self_types, "1.23.0", Some(44874)), /// Allows inherent and trait methods with arbitrary self types that are raw pointers. (unstable, arbitrary_self_types_pointers, "1.83.0", Some(44874)), + /// Target features on arm. + (unstable, arm_target_feature, "1.27.0", Some(150246)), /// Enables experimental inline assembly support for additional architectures. (unstable, asm_experimental_arch, "1.58.0", Some(93335)), /// Enables experimental register support in inline assembly. @@ -408,6 +379,8 @@ declare_features! ( (unstable, async_trait_bounds, "1.85.0", Some(62290)), /// Allows using Intel AVX10 target features and intrinsics (unstable, avx10_target_feature, "1.88.0", Some(138843)), + /// Target features on bpf. + (unstable, bpf_target_feature, "1.54.0", Some(150247)), /// Allows using C-variadics. (unstable, c_variadic, "1.34.0", Some(44930)), /// Allows defining c-variadic naked functions with any extern ABI that is allowed @@ -468,6 +441,8 @@ declare_features! ( /// Allows function attribute `#[coverage(on/off)]`, to control coverage /// instrumentation of that function. (unstable, coverage_attribute, "1.74.0", Some(84605)), + /// Target features on csky. + (unstable, csky_target_feature, "1.73.0", Some(150248)), /// Allows non-builtin attributes in inner attribute position. (unstable, custom_inner_attributes, "1.30.0", Some(54726)), /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. @@ -495,6 +470,8 @@ declare_features! ( (incomplete, effective_target_features, "1.91.0", Some(143352)), /// Allows the .use postfix syntax `x.use` and use closures `use |x| { ... }` (incomplete, ergonomic_clones, "1.87.0", Some(132290)), + /// ermsb target feature on x86. + (unstable, ermsb_target_feature, "1.49.0", Some(150249)), /// Allows exhaustive pattern matching on types that contain uninhabited types. (unstable, exhaustive_patterns, "1.13.0", Some(51085)), /// Disallows `extern` without an explicit ABI. @@ -541,6 +518,8 @@ declare_features! ( (incomplete, guard_patterns, "1.85.0", Some(129967)), /// Allows using `..=X` as a patterns in slices. (unstable, half_open_range_patterns_in_slices, "1.66.0", Some(67264)), + /// Target features on hexagon. + (unstable, hexagon_target_feature, "1.27.0", Some(150250)), /// Allows `if let` guard in match arms. (unstable, if_let_guard, "1.47.0", Some(51114)), /// Allows `impl Trait` to be used inside associated types (RFC 2515). @@ -555,6 +534,8 @@ declare_features! ( (incomplete, inherent_associated_types, "1.52.0", Some(8995)), /// Allows using `pointer` and `reference` in intra-doc links (unstable, intra_doc_pointers, "1.51.0", Some(80896)), + /// lahfsahf target feature on x86. + (unstable, lahfsahf_target_feature, "1.78.0", Some(150251)), /// Allows setting the threshold for the `large_assignments` lint. (unstable, large_assignments, "1.52.0", Some(83518)), /// Allow to have type alias types for inter-crate use. @@ -562,8 +543,12 @@ declare_features! ( /// Allows using `#[link(kind = "link-arg", name = "...")]` /// to pass custom arguments to the linker. (unstable, link_arg_attribute, "1.76.0", Some(99427)), + /// Target features on loongarch. + (unstable, loongarch_target_feature, "1.73.0", Some(150252)), /// Allows fused `loop`/`match` for direct intraprocedural jumps. (incomplete, loop_match, "1.90.0", Some(132306)), + /// Target features on m68k. + (unstable, m68k_target_feature, "1.85.0", Some(134328)), /// Allow `macro_rules!` attribute rules (unstable, macro_attr, "1.91.0", Some(143547)), /// Allow `macro_rules!` derive rules @@ -580,8 +565,12 @@ declare_features! ( /// standard library until the soundness issues with specialization /// are fixed. (unstable, min_specialization, "1.7.0", Some(31844)), + /// Target features on mips. + (unstable, mips_target_feature, "1.27.0", Some(150253)), /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns. (unstable, more_qualified_paths, "1.54.0", Some(86935)), + /// The `movrs` target feature on x86. + (unstable, movrs_target_feature, "1.88.0", Some(137976)), /// Allows the `#[must_not_suspend]` attribute. (unstable, must_not_suspend, "1.57.0", Some(83310)), /// Allows `mut ref` and `mut ref mut` identifier patterns. @@ -606,6 +595,8 @@ declare_features! ( (unstable, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554)), /// Allows `for` binders in where-clauses (incomplete, non_lifetime_binders, "1.69.0", Some(108185)), + /// Target feaures on nvptx. + (unstable, nvptx_target_feature, "1.91.0", Some(150254)), /// Allows using enums in offset_of! (unstable, offset_of_enum, "1.75.0", Some(120141)), /// Allows using fields with slice type in offset_of! @@ -618,6 +609,10 @@ declare_features! ( (incomplete, pin_ergonomics, "1.83.0", Some(130494)), /// Allows postfix match `expr.match { ... }` (unstable, postfix_match, "1.79.0", Some(121618)), + /// Target features on powerpc. + (unstable, powerpc_target_feature, "1.27.0", Some(150255)), + /// The prfchw target feature on x86. + (unstable, prfchw_target_feature, "1.78.0", Some(150256)), /// Allows macro attributes on expressions, statements and non-inline modules. (unstable, proc_macro_hygiene, "1.30.0", Some(54727)), /// Allows the use of raw-dylibs on ELF platforms @@ -633,12 +628,20 @@ declare_features! ( (unstable, repr_simd, "1.4.0", Some(27731)), /// Allows bounding the return type of AFIT/RPITIT. (unstable, return_type_notation, "1.70.0", Some(109417)), + /// Target features on riscv. + (unstable, riscv_target_feature, "1.45.0", Some(150257)), + /// The rtm target feature on x86. + (unstable, rtm_target_feature, "1.35.0", Some(150258)), /// Allows `extern "rust-cold"`. (unstable, rust_cold_cc, "1.63.0", Some(97544)), + /// Target features on s390x. + (unstable, s390x_target_feature, "1.82.0", Some(150259)), /// Allows the use of the `sanitize` attribute. (unstable, sanitize, "1.91.0", Some(39699)), /// Allows the use of SIMD types in functions declared in `extern` blocks. (unstable, simd_ffi, "1.0.0", Some(27731)), + /// Target features on sparc. + (unstable, sparc_target_feature, "1.84.0", Some(132783)), /// Allows specialization of implementations (RFC 1210). (incomplete, specialization, "1.7.0", Some(31844)), /// Allows using `#[rustc_align_static(...)]` on static items. @@ -685,10 +688,14 @@ declare_features! ( (internal, unsized_fn_params, "1.49.0", Some(48055)), /// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute. (unstable, used_with_arg, "1.60.0", Some(93798)), + /// Target features on wasm. + (unstable, wasm_target_feature, "1.30.0", Some(150260)), /// Allows use of attributes in `where` clauses. (unstable, where_clause_attrs, "1.87.0", Some(115590)), /// Allows use of x86 `AMX` target-feature attributes and intrinsics (unstable, x86_amx_intrinsics, "1.81.0", Some(126622)), + /// The x87 target feature on x86. + (unstable, x87_target_feature, "1.85.0", Some(150261)), /// Allows use of the `xop` target-feature (unstable, xop_target_feature, "1.81.0", Some(127208)), /// Allows `do yeet` expressions diff --git a/library/std_detect/src/detect/arch/s390x.rs b/library/std_detect/src/detect/arch/s390x.rs index a04283f90a02..63f7390d5ae3 100644 --- a/library/std_detect/src/detect/arch/s390x.rs +++ b/library/std_detect/src/detect/arch/s390x.rs @@ -10,27 +10,27 @@ features! { /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) /// the macro expands to `true`. #[stable(feature = "stdarch_s390x_feature_detection", since = "1.93.0")] - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] concurrent_functions: "concurrent-functions"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] concurrent_functions: "concurrent-functions"; /// s390x concurrent-functions facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] deflate_conversion: "deflate-conversion"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] deflate_conversion: "deflate-conversion"; /// s390x deflate-conversion facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] enhanced_sort: "enhanced-sort"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] enhanced_sort: "enhanced-sort"; /// s390x enhanced-sort facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] guarded_storage: "guarded-storage"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] guarded_storage: "guarded-storage"; /// s390x guarded-storage facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] high_word: "high-word"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] high_word: "high-word"; /// s390x high-word facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension3: "message-security-assist-extension3"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] message_security_assist_extension3: "message-security-assist-extension3"; /// s390x message-security-assist-extension3 facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension4: "message-security-assist-extension4"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] message_security_assist_extension4: "message-security-assist-extension4"; /// s390x message-security-assist-extension4 facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension5: "message-security-assist-extension5"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] message_security_assist_extension5: "message-security-assist-extension5"; /// s390x message-security-assist-extension5 facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension8: "message-security-assist-extension8"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] message_security_assist_extension8: "message-security-assist-extension8"; /// s390x message-security-assist-extension8 facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension9: "message-security-assist-extension9"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] message_security_assist_extension9: "message-security-assist-extension9"; /// s390x message-security-assist-extension9 facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] message_security_assist_extension12: "message-security-assist-extension12"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] message_security_assist_extension12: "message-security-assist-extension12"; /// s390x message-security-assist-extension12 facility @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] miscellaneous_extensions_2: "miscellaneous-extensions-2"; /// s390x miscellaneous-extensions-2 facility @@ -40,7 +40,7 @@ features! { /// s390x miscellaneous-extensions-4 facility @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] nnp_assist: "nnp-assist"; /// s390x nnp-assist facility - @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "44839")] transactional_execution: "transactional-execution"; + @FEATURE: #[unstable(feature = "s390x_target_feature", issue = "150259")] transactional_execution: "transactional-execution"; /// s390x transactional-execution facility @FEATURE: #[stable(feature = "s390x_target_feature_vector", since = "1.93.0")] vector: "vector"; /// s390x vector facility diff --git a/tests/ui/target-feature/gate.stderr b/tests/ui/target-feature/gate.stderr index 345dc2006d0b..67df09fd369e 100644 --- a/tests/ui/target-feature/gate.stderr +++ b/tests/ui/target-feature/gate.stderr @@ -4,7 +4,7 @@ error[E0658]: the target feature `x87` is currently unstable LL | #[target_feature(enable = "x87")] | ^^^^^^^^^^^^^^ | - = note: see issue #44839 for more information + = note: see issue #150261 for more information = help: add `#![feature(x87_target_feature)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date From 5c49aee9ec94ab4e6d64560e973c47b22141a1e1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 22 Dec 2025 17:56:49 +1100 Subject: [PATCH 1137/3801] Remove `InferCtxt::freshen`. Sometimes we freshen using a new `TypeFreshener`, and sometimes we freshen with an existing `TypeFreshener`. For the former we have the method `InferCtxt::freshen`. For the latter we just call `fold_with`. This asymmetry has been confusing to me. This commit removes `InferCtxt::freshen` so that all the freshening sites consistently use `fold_with` and it's obvious if each one is using a new or existing `TypeFreshener`. --- compiler/rustc_infer/src/infer/mod.rs | 4 ---- compiler/rustc_trait_selection/src/traits/auto_trait.rs | 3 ++- compiler/rustc_trait_selection/src/traits/select/mod.rs | 3 ++- compiler/rustc_type_ir/src/const_kind.rs | 2 +- compiler/rustc_type_ir/src/ty_kind.rs | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 571d5117bc91..c9ea420944e2 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -637,10 +637,6 @@ impl<'tcx> InferCtxt<'tcx> { self.typing_mode } - pub fn freshen>>(&self, t: T) -> T { - t.fold_with(&mut TypeFreshener::new(self)) - } - /// Returns the origin of the type variable identified by `vid`. /// /// No attempt is made to resolve `vid` to its root variable. diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 09709291a4b9..2da7c4448ce5 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -13,6 +13,7 @@ use tracing::debug; use super::*; use crate::errors::UnableToConstructConstantValue; +use crate::infer::TypeFreshener; use crate::infer::region_constraints::{ConstraintKind, RegionConstraintData}; use crate::regions::OutlivesEnvironmentBuildExt; use crate::traits::project::ProjectAndUnifyResult; @@ -817,6 +818,6 @@ impl<'tcx> AutoTraitFinder<'tcx> { infcx: &InferCtxt<'tcx>, p: ty::Predicate<'tcx>, ) -> ty::Predicate<'tcx> { - infcx.freshen(p) + p.fold_with(&mut TypeFreshener::new(infcx)) } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 43f9d6249771..0a1542c1d16d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -324,7 +324,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // separately rather than using `stack.fresh_trait_ref` -- // this is because we want the unbound variables to be // replaced with fresh types starting from index 0. - let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate); + let cache_fresh_trait_pred = + stack.obligation.predicate.fold_with(&mut TypeFreshener::new(self.infcx)); debug!(?cache_fresh_trait_pred); debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars()); diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index f315e8b3e11c..9a83055d06c4 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -103,7 +103,7 @@ rustc_index::newtype_index! { pub enum InferConst { /// Infer the value of the const. Var(ConstVid), - /// A fresh const variable. See `infer::freshen` for more details. + /// A fresh const variable. See `TypeFreshener` for more details. Fresh(u32), } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 34bb3cd8a6c3..498797bef653 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -594,7 +594,7 @@ pub enum InferTy { /// A [`FreshTy`][Self::FreshTy] is one that is generated as a replacement /// for an unbound type variable. This is convenient for caching etc. See - /// `rustc_infer::infer::freshen` for more details. + /// `TypeFreshener` for more details. /// /// Compare with [`TyVar`][Self::TyVar]. FreshTy(u32), From 63d30f1a0ad12ba12b5de4e5e77b15b30dc91e8b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 22 Dec 2025 23:33:09 +1100 Subject: [PATCH 1138/3801] `s/fresh_trait_ref/fresh_trait_pred`. Because `fresh_trait_pred` is the name of the field/argument. The `_ref` suffix appears to be a typo, or left over from earlier versions of the code. --- .../rustc_trait_selection/src/traits/select/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0a1542c1d16d..13f3a76824f5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -321,7 +321,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.check_recursion_limit(stack.obligation, stack.obligation)?; // Check the cache. Note that we freshen the trait-ref - // separately rather than using `stack.fresh_trait_ref` -- + // separately rather than using `stack.fresh_trait_pred` -- // this is because we want the unbound variables to be // replaced with fresh types starting from index 0. let cache_fresh_trait_pred = @@ -1136,7 +1136,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// `Option>>` is `Send` if `Box>` is /// `Send`. /// - /// Note that we do this comparison using the `fresh_trait_ref` + /// Note that we do this comparison using the `fresh_trait_pred` /// fields. Because these have all been freshened using /// `self.freshener`, we can be sure that (a) this will not /// affect the inferencer state and (b) that if we see two @@ -1220,7 +1220,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if unbound_input_types && stack.iter().skip(1).any(|prev| { stack.obligation.param_env == prev.obligation.param_env - && self.match_fresh_trait_refs(stack.fresh_trait_pred, prev.fresh_trait_pred) + && self.match_fresh_trait_preds(stack.fresh_trait_pred, prev.fresh_trait_pred) }) { debug!("evaluate_stack --> unbound argument, recursive --> giving up",); @@ -2743,7 +2743,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { /////////////////////////////////////////////////////////////////////////// // Miscellany - fn match_fresh_trait_refs( + fn match_fresh_trait_preds( &self, previous: ty::PolyTraitPredicate<'tcx>, current: ty::PolyTraitPredicate<'tcx>, @@ -3032,7 +3032,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> { } /// Check the provisional cache for any result for - /// `fresh_trait_ref`. If there is a hit, then you must consider + /// `fresh_trait_pred`. If there is a hit, then you must consider /// it an access to the stack slots at depth /// `reached_depth` (from the returned value). fn get_provisional( From 2d10f476938faf3993a7fb746ccf4d371601c5ca Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 22 Dec 2025 23:45:38 +1100 Subject: [PATCH 1139/3801] Disallow freshening an already-freshened type/const. It never happens in practice. --- compiler/rustc_infer/src/infer/freshen.rs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index d614fac40831..1a2e5e93c864 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -148,15 +148,12 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { } } } - ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => { - if i >= self.const_freshen_count { - bug!("freshened const id {} exceeds counter {}", i, self.const_freshen_count); - } - ct + ty::ConstKind::Infer(ty::InferConst::Fresh(_)) => { + bug!("trying to freshen already-freshened const {ct:?}"); } ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { - bug!("unexpected const {:?}", ct) + bug!("unexpected const {ct:?}") } ty::ConstKind::Param(_) @@ -171,8 +168,8 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { // This is separate from `fold_ty` to keep that method small and inlinable. #[inline(never)] - fn fold_infer_ty(&mut self, v: ty::InferTy) -> Option> { - match v { + fn fold_infer_ty(&mut self, ty: ty::InferTy) -> Option> { + match ty { ty::TyVar(v) => { let mut inner = self.infcx.inner.borrow_mut(); match inner.type_variables().probe(v).known() { @@ -212,11 +209,8 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { } } - ty::FreshTy(ct) | ty::FreshIntTy(ct) | ty::FreshFloatTy(ct) => { - if ct >= self.ty_freshen_count { - bug!("freshened type id {} exceeds counter {}", ct, self.ty_freshen_count); - } - None + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { + bug!("trying to freshen already-freshened type {ty:?}"); } } } From 23278232ac3748c80bac01642b0a3bbe056c498a Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 22 Dec 2025 19:21:05 +0530 Subject: [PATCH 1140/3801] remove request_id, rename postcardNew to BidirectionalPostcardPrototype and remove JsonNew --- .../src/bidirectional_protocol.rs | 20 +++--------- .../src/bidirectional_protocol/msg.rs | 9 ------ .../crates/proc-macro-api/src/process.rs | 32 ++++++------------- .../crates/proc-macro-srv-cli/src/main.rs | 6 +--- .../proc-macro-srv-cli/src/main_loop.rs | 22 +++---------- 5 files changed, 20 insertions(+), 69 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index 728f0f707d71..c7caccb96ff1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -12,7 +12,7 @@ use span::{FileId, Span}; use crate::{ Codec, ProcMacro, ProcMacroKind, ServerError, bidirectional_protocol::msg::{ - Envelope, ExpandMacro, ExpandMacroData, ExpnGlobals, Kind, Payload, Request, RequestId, + Envelope, ExpandMacro, ExpandMacroData, ExpnGlobals, Kind, Payload, Request, Response, SubRequest, SubResponse, }, legacy_protocol::{ @@ -37,11 +37,10 @@ pub fn run_conversation( writer: &mut dyn Write, reader: &mut dyn BufRead, buf: &mut C::Buf, - id: RequestId, initial: Payload, callbacks: &mut dyn ClientCallbacks, ) -> Result { - let msg = Envelope { id, kind: Kind::Request, payload: initial }; + let msg = Envelope { kind: Kind::Request, payload: initial }; let encoded = C::encode(&msg).map_err(wrap_encode)?; C::write(writer, &encoded).map_err(wrap_io("failed to write initial request"))?; @@ -56,18 +55,11 @@ pub fn run_conversation( let msg: Envelope = C::decode(b).map_err(wrap_decode)?; - if msg.id != id { - return Err(ServerError { - message: format!("unexpected message id {}, expected {}", msg.id, id), - io: None, - }); - } - match (msg.kind, msg.payload) { (Kind::SubRequest, Payload::SubRequest(sr)) => { let resp = callbacks.handle_sub_request(sr)?; let reply = - Envelope { id, kind: Kind::SubResponse, payload: Payload::SubResponse(resp) }; + Envelope { kind: Kind::SubResponse, payload: Payload::SubResponse(resp) }; let encoded = C::encode(&reply).map_err(wrap_encode)?; C::write(writer, &encoded).map_err(wrap_io("failed to write sub-response"))?; } @@ -268,11 +260,9 @@ fn run_request( return Err(server_error.clone()); } - let id = srv.request_id(); - if srv.use_postcard() { - srv.run_bidirectional::(id, msg, callbacks) + srv.run_bidirectional::(msg, callbacks) } else { - srv.run_bidirectional::(id, msg, callbacks) + srv.run_bidirectional::(msg, callbacks) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 796573385c3c..4f81ef4ae6bd 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -8,21 +8,12 @@ use crate::{ legacy_protocol::msg::{FlatTree, Message, PanicMessage, ServerConfig}, }; -pub type RequestId = u32; - #[derive(Debug, Serialize, Deserialize)] pub struct Envelope { - pub id: RequestId, pub kind: Kind, pub payload: Payload, } -impl From<(RequestId, Kind, Payload)> for Envelope { - fn from(value: (RequestId, Kind, Payload)) -> Self { - Envelope { id: value.0, kind: value.1, payload: value.2 } - } -} - #[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] pub enum Kind { Request, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index bb4599c53272..1c1709e5fa64 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -6,7 +6,6 @@ use std::{ process::{Child, ChildStdin, ChildStdout, Command, Stdio}, sync::{ Arc, Mutex, OnceLock, - atomic::{AtomicU32, Ordering}, }, }; @@ -20,7 +19,7 @@ use crate::{ Codec, ProcMacro, ProcMacroKind, ServerError, bidirectional_protocol::{ self, ClientCallbacks, - msg::{Payload, RequestId}, + msg::Payload, }, legacy_protocol::{self, SpanMode}, version, @@ -36,15 +35,13 @@ pub(crate) struct ProcMacroServerProcess { protocol: Protocol, /// Populated when the server exits. exited: OnceLock>, - next_request_id: AtomicU32, } #[derive(Debug, Clone)] pub(crate) enum Protocol { LegacyJson { mode: SpanMode }, LegacyPostcard { mode: SpanMode }, - NewPostcard { mode: SpanMode }, - NewJson { mode: SpanMode }, + BidirectionalPostcardPrototype { mode: SpanMode }, } /// Maintains the state of the proc-macro server process. @@ -74,8 +71,7 @@ impl ProcMacroServerProcess { && has_working_format_flag { &[ - (Some("postcard-new"), Protocol::NewPostcard { mode: SpanMode::Id }), - (Some("json-new"), Protocol::NewJson { mode: SpanMode::Id }), + (Some("postcard-new"), Protocol::BidirectionalPostcardPrototype { mode: SpanMode::Id }), (Some("postcard-legacy"), Protocol::LegacyPostcard { mode: SpanMode::Id }), (Some("json-legacy"), Protocol::LegacyJson { mode: SpanMode::Id }), ] @@ -94,7 +90,6 @@ impl ProcMacroServerProcess { version: 0, protocol: protocol.clone(), exited: OnceLock::new(), - next_request_id: AtomicU32::new(1), }) }; let mut srv = create_srv()?; @@ -122,8 +117,7 @@ impl ProcMacroServerProcess { match &mut srv.protocol { Protocol::LegacyJson { mode } | Protocol::LegacyPostcard { mode } - | Protocol::NewJson { mode } - | Protocol::NewPostcard { mode } => *mode = new_mode, + | Protocol::BidirectionalPostcardPrototype { mode } => *mode = new_mode, } } tracing::info!("Proc-macro server protocol: {:?}", srv.protocol); @@ -159,8 +153,7 @@ impl ProcMacroServerProcess { match self.protocol { Protocol::LegacyJson { mode } => mode == SpanMode::RustAnalyzer, Protocol::LegacyPostcard { mode } => mode == SpanMode::RustAnalyzer, - Protocol::NewJson { mode } => mode == SpanMode::RustAnalyzer, - Protocol::NewPostcard { mode } => mode == SpanMode::RustAnalyzer, + Protocol::BidirectionalPostcardPrototype { mode } => mode == SpanMode::RustAnalyzer, } } @@ -170,7 +163,7 @@ impl ProcMacroServerProcess { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::version_check(self) } - Protocol::NewJson { .. } | Protocol::NewPostcard { .. } => { + Protocol::BidirectionalPostcardPrototype { .. } => { bidirectional_protocol::version_check(self) } } @@ -182,7 +175,7 @@ impl ProcMacroServerProcess { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::enable_rust_analyzer_spans(self) } - Protocol::NewJson { .. } | Protocol::NewPostcard { .. } => { + Protocol::BidirectionalPostcardPrototype { .. } => { bidirectional_protocol::enable_rust_analyzer_spans(self) } } @@ -197,7 +190,7 @@ impl ProcMacroServerProcess { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::find_proc_macros(self, dylib_path) } - Protocol::NewJson { .. } | Protocol::NewPostcard { .. } => { + Protocol::BidirectionalPostcardPrototype { .. } => { bidirectional_protocol::find_proc_macros(self, dylib_path) } } @@ -229,7 +222,7 @@ impl ProcMacroServerProcess { current_dir, ) } - Protocol::NewJson { .. } | Protocol::NewPostcard { .. } => { + Protocol::BidirectionalPostcardPrototype { .. } => { bidirectional_protocol::expand( proc_macro, db, @@ -307,20 +300,15 @@ impl ProcMacroServerProcess { pub(crate) fn run_bidirectional( &self, - id: RequestId, initial: Payload, callbacks: &mut dyn ClientCallbacks, ) -> Result { self.with_locked_io::(|writer, reader, buf| { bidirectional_protocol::run_conversation::( - writer, reader, buf, id, initial, callbacks, + writer, reader, buf, initial, callbacks, ) }) } - - pub(crate) fn request_id(&self) -> RequestId { - self.next_request_id.fetch_add(1, Ordering::Relaxed) - } } /// Manages the execution of the proc-macro server process. diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index c9134b402dfa..53302dd5798c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -31,7 +31,7 @@ fn main() -> std::io::Result<()> { clap::Arg::new("format") .long("format") .action(clap::ArgAction::Set) - .default_value("json-new") + .default_value("postcard-new") .value_parser(clap::builder::EnumValueParser::::new()), clap::Arg::new("version") .long("version") @@ -52,7 +52,6 @@ fn main() -> std::io::Result<()> { enum ProtocolFormat { JsonLegacy, PostcardLegacy, - JsonNew, PostcardNew, } @@ -61,7 +60,6 @@ impl ValueEnum for ProtocolFormat { &[ ProtocolFormat::JsonLegacy, ProtocolFormat::PostcardLegacy, - ProtocolFormat::JsonNew, ProtocolFormat::PostcardNew, ] } @@ -72,7 +70,6 @@ impl ValueEnum for ProtocolFormat { ProtocolFormat::PostcardLegacy => { Some(clap::builder::PossibleValue::new("postcard-legacy")) } - ProtocolFormat::JsonNew => Some(clap::builder::PossibleValue::new("json-new")), ProtocolFormat::PostcardNew => Some(clap::builder::PossibleValue::new("postcard-new")), } } @@ -81,7 +78,6 @@ impl ValueEnum for ProtocolFormat { "json-legacy" => Ok(ProtocolFormat::JsonLegacy), "postcard-legacy" => Ok(ProtocolFormat::PostcardLegacy), "postcard-new" => Ok(ProtocolFormat::PostcardNew), - "json-new" => Ok(ProtocolFormat::JsonNew), _ => Err(format!("unknown protocol format: {input}")), } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index dc828a87de13..ee9b2088117d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -10,7 +10,6 @@ use proc_macro_api::{ version::CURRENT_API_VERSION, }; -use bidirectional::RequestId; use legacy::Message; use proc_macro_srv::{EnvSnapshot, SpanId}; @@ -39,7 +38,6 @@ pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> { match format { ProtocolFormat::JsonLegacy => run_::(), ProtocolFormat::PostcardLegacy => run_::(), - ProtocolFormat::JsonNew => run_new::(), ProtocolFormat::PostcardNew => run_new::(), } } @@ -83,7 +81,6 @@ fn run_new() -> io::Result<()> { send_response::<_, C>( &mut stdout, - req.id, bidirectional::Response::ListMacros(res), )?; } @@ -91,7 +88,6 @@ fn run_new() -> io::Result<()> { bidirectional::Request::ApiVersionCheck {} => { send_response::<_, C>( &mut stdout, - req.id, bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), )?; } @@ -100,7 +96,6 @@ fn run_new() -> io::Result<()> { span_mode = config.span_mode; send_response::<_, C>( &mut stdout, - req.id, bidirectional::Response::SetConfig(config), )?; } @@ -110,7 +105,6 @@ fn run_new() -> io::Result<()> { &mut stdin, &mut stdout, &mut buf, - req.id, span_mode, *task, )?; @@ -129,14 +123,13 @@ fn handle_expand( stdin: &mut R, stdout: &mut W, buf: &mut C::Buf, - req_id: RequestId, span_mode: legacy::SpanMode, task: bidirectional::ExpandMacro, ) -> io::Result<()> { match span_mode { - legacy::SpanMode::Id => handle_expand_id::<_, C>(srv, stdout, req_id, task), + legacy::SpanMode::Id => handle_expand_id::<_, C>(srv, stdout, task), legacy::SpanMode::RustAnalyzer => { - handle_expand_ra::<_, _, C>(srv, stdin, stdout, buf, req_id, task) + handle_expand_ra::<_, _, C>(srv, stdin, stdout, buf, task) } } } @@ -144,7 +137,6 @@ fn handle_expand( fn handle_expand_id( srv: &proc_macro_srv::ProcMacroSrv<'_>, stdout: &mut W, - req_id: RequestId, task: bidirectional::ExpandMacro, ) -> io::Result<()> { let bidirectional::ExpandMacro { lib, env, current_dir, data } = task; @@ -182,7 +174,7 @@ fn handle_expand_id( }) .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); - send_response::<_, C>(stdout, req_id, bidirectional::Response::ExpandMacro(res)) + send_response::<_, C>(stdout, bidirectional::Response::ExpandMacro(res)) } fn handle_expand_ra( @@ -190,7 +182,6 @@ fn handle_expand_ra( stdin: &mut R, stdout: &mut W, buf: &mut C::Buf, - req_id: RequestId, task: bidirectional::ExpandMacro, ) -> io::Result<()> { let bidirectional::ExpandMacro { @@ -276,7 +267,6 @@ fn handle_expand_ra( if let Ok(res) = result_rx.try_recv() { send_response::<_, C>( stdout, - req_id, bidirectional::Response::ExpandMacroExtended(res), ) .unwrap(); @@ -290,7 +280,7 @@ fn handle_expand_ra( } }; - send_subrequest::<_, C>(stdout, req_id, from_srv_req(subreq)).unwrap(); + send_subrequest::<_, C>(stdout, from_srv_req(subreq)).unwrap(); let resp_opt = bidirectional::Envelope::read::<_, C>(stdin, buf).unwrap(); let resp = match resp_opt { @@ -474,11 +464,9 @@ fn from_client_res(value: bidirectional::SubResponse) -> proc_macro_srv::SubResp fn send_response( stdout: &mut W, - id: u32, resp: bidirectional::Response, ) -> io::Result<()> { let resp = bidirectional::Envelope { - id, kind: bidirectional::Kind::Response, payload: bidirectional::Payload::Response(resp), }; @@ -487,11 +475,9 @@ fn send_response( fn send_subrequest( stdout: &mut W, - id: u32, resp: bidirectional::SubRequest, ) -> io::Result<()> { let resp = bidirectional::Envelope { - id, kind: bidirectional::Kind::SubRequest, payload: bidirectional::Payload::SubRequest(resp), }; From 3db62cf30798a2c390c4b568495e150b19e661dd Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 22 Dec 2025 19:21:22 +0530 Subject: [PATCH 1141/3801] comment out disabled workflow --- src/tools/rust-analyzer/.github/workflows/ci.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index 623200aea032..81ca0254982d 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -70,6 +70,10 @@ jobs: - name: Test run: cargo test --features sysroot-abi -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api -- --quiet + + # FIXME: This is temporarily disable, more info: https://rust-lang.zulipchat.com/#narrow/channel/185405-t-compiler.2Frust-analyzer/topic/Non-generic.20spans/with/564604549 + # - name: Check salsa dependency + # run: "! (cargo tree -p proc-macro-srv-cli | grep -q salsa)" rust: if: github.repository == 'rust-lang/rust-analyzer' From 22996d69599b39f5bbad9f1b85aaa7e9d1f3990f Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Mon, 22 Dec 2025 14:55:44 +0100 Subject: [PATCH 1142/3801] Remove inactive nvptx maintainer --- src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md index 36598982481b..56caf531a92e 100644 --- a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md +++ b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md @@ -7,7 +7,6 @@ platform. ## Target maintainers -[@RDambrosio016](https://github.com/RDambrosio016) [@kjetilkjeka](https://github.com/kjetilkjeka) ## Requirements From 42ec5c7b324f2754453691d93561c2738407db2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 12 Dec 2025 19:52:23 +0000 Subject: [PATCH 1143/3801] Detail expectation on non-`()` block tail in `if` then condition with no `else` When encountering an `if` expression with no `else` where the then block has a tail expression, we emit an E0308 type error. We now explain why `()` was expected. --- compiler/rustc_hir_typeck/src/coercion.rs | 15 ++++++++++++++- ...e-for-type-mismatch-in-closure-in-async.stderr | 2 +- .../missing-return-in-async-block.stderr | 4 ++-- .../unused/unused-doc-comments-edge-cases.stderr | 2 +- .../ui/loops/dont-suggest-break-thru-item.stderr | 8 ++++---- .../struct-literals-in-invalid-places.stderr | 2 +- .../issue-82612-return-mutable-reference.stderr | 2 +- .../return/tail-expr-as-potential-return.stderr | 6 +++--- tests/ui/return/tail-expr-if-as-return.stderr | 2 +- .../try-operator-dont-suggest-semicolon.rs | 2 +- .../try-operator-dont-suggest-semicolon.stderr | 2 +- 11 files changed, 30 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index b4a43548dcda..5e1e567d103e 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1838,7 +1838,20 @@ impl<'tcx> CoerceMany<'tcx> { hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) ) { - err.span_label(cond_expr.span, "expected this to be `()`"); + if let ObligationCauseCode::BlockTailExpression(hir_id, hir::MatchSource::Normal) = + cause.code() + && let hir::Node::Block(block) = fcx.tcx.hir_node(*hir_id) + && let hir::Node::Expr(expr) = fcx.tcx.parent_hir_node(block.hir_id) + && let hir::Node::Expr(if_expr) = fcx.tcx.parent_hir_node(expr.hir_id) + && let hir::ExprKind::If(_cond, _then, None) = if_expr.kind + { + err.span_label( + cond_expr.span, + "`if` expressions without `else` arms expect their inner expression to be `()`", + ); + } else { + err.span_label(cond_expr.span, "expected this to be `()`"); + } if expr.can_have_side_effects() { fcx.suggest_semicolon_at_end(cond_expr.span, &mut err); } diff --git a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr index ce023397db90..928e1fcaa578 100644 --- a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr +++ b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr @@ -6,7 +6,7 @@ LL | | false | | ^^^^^ expected `()`, found `bool` LL | | LL | | } - | |_________- expected this to be `()` + | |_________- `if` expressions without `else` arms expect their inner expression to be `()` error[E0308]: mismatched types --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:12:9 diff --git a/tests/ui/async-await/missing-return-in-async-block.stderr b/tests/ui/async-await/missing-return-in-async-block.stderr index 5ea76e5f7bf9..a7d72ab5f33c 100644 --- a/tests/ui/async-await/missing-return-in-async-block.stderr +++ b/tests/ui/async-await/missing-return-in-async-block.stderr @@ -5,7 +5,7 @@ LL | / if true { LL | | Ok(S) | | ^^^^^ expected `()`, found `Result` LL | | } - | |_________- expected this to be `()` + | |_________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result` @@ -21,7 +21,7 @@ LL | / if true { LL | | Ok(S) | | ^^^^^ expected `()`, found `Result` LL | | } - | |_________- expected this to be `()` + | |_________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result` diff --git a/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr index c07411745549..0f0288c6def6 100644 --- a/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr +++ b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr @@ -105,7 +105,7 @@ LL | / if num == 3 { LL | | true | | ^^^^ expected `()`, found `bool` LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | help: you might have meant to return this value | diff --git a/tests/ui/loops/dont-suggest-break-thru-item.stderr b/tests/ui/loops/dont-suggest-break-thru-item.stderr index e7ed7ae15015..576bd353520f 100644 --- a/tests/ui/loops/dont-suggest-break-thru-item.stderr +++ b/tests/ui/loops/dont-suggest-break-thru-item.stderr @@ -6,7 +6,7 @@ LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` ... | LL | | } - | |_____________- expected this to be `()` + | |_____________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` @@ -23,7 +23,7 @@ LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` ... | LL | | } - | |_____________- expected this to be `()` + | |_____________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` @@ -40,7 +40,7 @@ LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` LL | | LL | | } - | |_____________- expected this to be `()` + | |_____________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` @@ -53,7 +53,7 @@ LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` LL | | LL | | } - | |_____________- expected this to be `()` + | |_____________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` diff --git a/tests/ui/parser/struct-literals-in-invalid-places.stderr b/tests/ui/parser/struct-literals-in-invalid-places.stderr index 39dc2d2efb75..380ecf94d824 100644 --- a/tests/ui/parser/struct-literals-in-invalid-places.stderr +++ b/tests/ui/parser/struct-literals-in-invalid-places.stderr @@ -200,7 +200,7 @@ LL | if x == E::V { field } {} | ---------------^^^^^-- | | | | | expected `()`, found `bool` - | expected this to be `()` + | `if` expressions without `else` arms expect their inner expression to be `()` | help: you might have meant to return this value | diff --git a/tests/ui/return/issue-82612-return-mutable-reference.stderr b/tests/ui/return/issue-82612-return-mutable-reference.stderr index 59a6bb85d0fd..632f366c7551 100644 --- a/tests/ui/return/issue-82612-return-mutable-reference.stderr +++ b/tests/ui/return/issue-82612-return-mutable-reference.stderr @@ -6,7 +6,7 @@ LL | | let value = unsafe { self.values.get_unchecked_mut(index) }; LL | | value.get_or_insert_with(func) | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&mut V` LL | | } - | |_________- expected this to be `()` + | |_________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found mutable reference `&mut V` diff --git a/tests/ui/return/tail-expr-as-potential-return.stderr b/tests/ui/return/tail-expr-as-potential-return.stderr index 8105b2df3fea..be3d4b5116f2 100644 --- a/tests/ui/return/tail-expr-as-potential-return.stderr +++ b/tests/ui/return/tail-expr-as-potential-return.stderr @@ -6,7 +6,7 @@ LL | | Err(42) | | ^^^^^^^ expected `()`, found `Result<_, {integer}>` ... | LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` @@ -23,7 +23,7 @@ LL | | 1i32 | | ^^^^ expected `()`, found `i32` ... | LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | help: you might have meant to return this value | @@ -38,7 +38,7 @@ LL | | Err(42) | | ^^^^^^^ expected `()`, found `Result<_, {integer}>` ... | LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` diff --git a/tests/ui/return/tail-expr-if-as-return.stderr b/tests/ui/return/tail-expr-if-as-return.stderr index 2631f1e426de..68acde416bc7 100644 --- a/tests/ui/return/tail-expr-if-as-return.stderr +++ b/tests/ui/return/tail-expr-if-as-return.stderr @@ -5,7 +5,7 @@ LL | / if true { LL | | "" | | ^^ expected `()`, found `&str` LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/try-operator-dont-suggest-semicolon.rs b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.rs index f882a159f983..fdd5dfc8307a 100644 --- a/tests/ui/suggestions/try-operator-dont-suggest-semicolon.rs +++ b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.rs @@ -12,7 +12,7 @@ fn main() -> Result<(), ()> { // Here, we do want to suggest a semicolon: let x = Ok(42); if true { - //~^ NOTE: expected this to be `()` + //~^ NOTE: `if` expressions without `else` arms expect their inner expression to be `()` x? //~^ ERROR: mismatched types [E0308] //~| NOTE: expected `()`, found integer diff --git a/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr index a275f0c2fa89..25cd27488c8c 100644 --- a/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr +++ b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr @@ -15,7 +15,7 @@ LL | | x? | | ^^ expected `()`, found integer ... | LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | help: consider using a semicolon here | From f5aec79668a1c37bd75575eda5755e049f4e6f1b Mon Sep 17 00:00:00 2001 From: Josh Kaplan Date: Wed, 8 Oct 2025 17:53:52 -0400 Subject: [PATCH 1144/3801] Implement round-ties-to-even for Duration Debug for consistency with f64 --- library/core/src/time.rs | 28 +++++++++++++++++++++++++++- library/coretests/tests/time.rs | 10 +++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 940129d68816..0f2160338db5 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1316,7 +1316,33 @@ impl fmt::Debug for Duration { // normal floating point numbers. However, we only need to do work // when rounding up. This happens if the first digit of the // remaining ones is >= 5. - let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 { + let integer_part = if fractional_part > 0 && fractional_part == divisor * 5 { + let last_digit_is_odd = if pos > 0 { + (buf[pos - 1] - b'0') % 2 == 1 + } else { + // No fractional digits - check the integer part + (integer_part % 2) == 1 + }; + + if last_digit_is_odd { + let mut rev_pos = pos; + let mut carry = true; + while carry && rev_pos > 0 { + rev_pos -= 1; + + if buf[rev_pos] < b'9' { + buf[rev_pos] += 1; + carry = false; + } else { + buf[rev_pos] = b'0'; + } + } + + if carry { integer_part.checked_add(1) } else { Some(integer_part) } + } else { + Some(integer_part) + } + } else if fractional_part > 0 && fractional_part > divisor * 5 { // Round up the number contained in the buffer. We go through // the buffer backwards and keep track of the carry. let mut rev_pos = pos; diff --git a/library/coretests/tests/time.rs b/library/coretests/tests/time.rs index fb3c50f9bde9..ff80ff680943 100644 --- a/library/coretests/tests/time.rs +++ b/library/coretests/tests/time.rs @@ -439,7 +439,6 @@ fn debug_formatting_precision_two() { assert_eq!(format!("{:.2?}", Duration::new(4, 001_000_000)), "4.00s"); assert_eq!(format!("{:.2?}", Duration::new(2, 100_000_000)), "2.10s"); assert_eq!(format!("{:.2?}", Duration::new(2, 104_990_000)), "2.10s"); - assert_eq!(format!("{:.2?}", Duration::new(2, 105_000_000)), "2.11s"); assert_eq!(format!("{:.2?}", Duration::new(8, 999_999_999)), "9.00s"); } @@ -480,6 +479,15 @@ fn debug_formatting_precision_high() { assert_eq!(format!("{:.20?}", Duration::new(4, 001_000_000)), "4.00100000000000000000s"); } +#[test] +fn debug_formatting_round_to_even() { + assert_eq!(format!("{:.0?}", Duration::new(1, 500_000_000)), "2s"); + assert_eq!(format!("{:.0?}", Duration::new(2, 500_000_000)), "2s"); + assert_eq!(format!("{:.0?}", Duration::new(0, 1_500_000)), "2ms"); + assert_eq!(format!("{:.0?}", Duration::new(0, 2_500_000)), "2ms"); + assert_eq!(format!("{:.2?}", Duration::new(2, 105_000_000)), "2.10s"); +} + #[test] fn duration_const() { // test that the methods of `Duration` are usable in a const context From 95302b25377bf678d8db964eff20f7acd2044991 Mon Sep 17 00:00:00 2001 From: Josh Kaplan Date: Sun, 12 Oct 2025 19:09:32 -0400 Subject: [PATCH 1145/3801] Update comment on duration rounding behavior --- library/core/src/time.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 0f2160338db5..8266a2a63bc0 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1315,7 +1315,8 @@ impl fmt::Debug for Duration { // need to perform rounding to match the semantics of printing // normal floating point numbers. However, we only need to do work // when rounding up. This happens if the first digit of the - // remaining ones is >= 5. + // remaining ones is > 5. When the first digit is exactly 5, rounding + // follows IEEE-754 round-ties-to-even semantics. let integer_part = if fractional_part > 0 && fractional_part == divisor * 5 { let last_digit_is_odd = if pos > 0 { (buf[pos - 1] - b'0') % 2 == 1 From c74aa910ca9ab0f4b6662600a031d57689f11fae Mon Sep 17 00:00:00 2001 From: Josh Kaplan Date: Mon, 22 Dec 2025 09:20:56 -0500 Subject: [PATCH 1146/3801] Merged Duration Debug tie rounding with existing rounding logic --- library/core/src/time.rs | 64 ++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 8266a2a63bc0..18792659d974 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1315,9 +1315,12 @@ impl fmt::Debug for Duration { // need to perform rounding to match the semantics of printing // normal floating point numbers. However, we only need to do work // when rounding up. This happens if the first digit of the - // remaining ones is > 5. When the first digit is exactly 5, rounding - // follows IEEE-754 round-ties-to-even semantics. - let integer_part = if fractional_part > 0 && fractional_part == divisor * 5 { + // remaining ones is >= 5. When the first digit is exactly 5, rounding + // follows IEEE-754 round-ties-to-even semantics: we only round up + // if the last written digit is odd. + let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 { + // For ties (fractional_part == divisor * 5), only round up if last digit is odd + let is_tie = fractional_part == divisor * 5; let last_digit_is_odd = if pos > 0 { (buf[pos - 1] - b'0') % 2 == 1 } else { @@ -1325,12 +1328,20 @@ impl fmt::Debug for Duration { (integer_part % 2) == 1 }; - if last_digit_is_odd { + if is_tie && !last_digit_is_odd { + Some(integer_part) + } else { + // Round up the number contained in the buffer. We go through + // the buffer backwards and keep track of the carry. let mut rev_pos = pos; let mut carry = true; while carry && rev_pos > 0 { rev_pos -= 1; + // If the digit in the buffer is not '9', we just need to + // increment it and can stop then (since we don't have a + // carry anymore). Otherwise, we set it to '0' (overflow) + // and continue. if buf[rev_pos] < b'9' { buf[rev_pos] += 1; carry = false; @@ -1339,43 +1350,20 @@ impl fmt::Debug for Duration { } } - if carry { integer_part.checked_add(1) } else { Some(integer_part) } - } else { - Some(integer_part) - } - } else if fractional_part > 0 && fractional_part > divisor * 5 { - // Round up the number contained in the buffer. We go through - // the buffer backwards and keep track of the carry. - let mut rev_pos = pos; - let mut carry = true; - while carry && rev_pos > 0 { - rev_pos -= 1; - - // If the digit in the buffer is not '9', we just need to - // increment it and can stop then (since we don't have a - // carry anymore). Otherwise, we set it to '0' (overflow) - // and continue. - if buf[rev_pos] < b'9' { - buf[rev_pos] += 1; - carry = false; + // If we still have the carry bit set, that means that we set + // the whole buffer to '0's and need to increment the integer + // part. + if carry { + // If `integer_part == u64::MAX` and precision < 9, any + // carry of the overflow during rounding of the + // `fractional_part` into the `integer_part` will cause the + // `integer_part` itself to overflow. Avoid this by using an + // `Option`, with `None` representing `u64::MAX + 1`. + integer_part.checked_add(1) } else { - buf[rev_pos] = b'0'; + Some(integer_part) } } - - // If we still have the carry bit set, that means that we set - // the whole buffer to '0's and need to increment the integer - // part. - if carry { - // If `integer_part == u64::MAX` and precision < 9, any - // carry of the overflow during rounding of the - // `fractional_part` into the `integer_part` will cause the - // `integer_part` itself to overflow. Avoid this by using an - // `Option`, with `None` representing `u64::MAX + 1`. - integer_part.checked_add(1) - } else { - Some(integer_part) - } } else { Some(integer_part) }; From 8e21457edd104f9a82c57dc0cb59f0a283d01e3f Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 22 Dec 2025 20:04:35 +0530 Subject: [PATCH 1147/3801] remove envelop and keep it simple --- .../src/bidirectional_protocol.rs | 61 ++++++----- .../src/bidirectional_protocol/msg.rs | 18 +--- .../crates/proc-macro-api/src/process.rs | 46 ++++---- .../crates/proc-macro-srv-cli/src/main.rs | 6 +- .../proc-macro-srv-cli/src/main_loop.rs | 102 +++++++----------- 5 files changed, 94 insertions(+), 139 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index c7caccb96ff1..4cb6a1d90f19 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -12,8 +12,8 @@ use span::{FileId, Span}; use crate::{ Codec, ProcMacro, ProcMacroKind, ServerError, bidirectional_protocol::msg::{ - Envelope, ExpandMacro, ExpandMacroData, ExpnGlobals, Kind, Payload, Request, - Response, SubRequest, SubResponse, + BidirectionalMessage, ExpandMacro, ExpandMacroData, ExpnGlobals, Request, Response, + SubRequest, SubResponse, }, legacy_protocol::{ SpanMode, @@ -37,10 +37,9 @@ pub fn run_conversation( writer: &mut dyn Write, reader: &mut dyn BufRead, buf: &mut C::Buf, - initial: Payload, + msg: BidirectionalMessage, callbacks: &mut dyn ClientCallbacks, -) -> Result { - let msg = Envelope { kind: Kind::Request, payload: initial }; +) -> Result { let encoded = C::encode(&msg).map_err(wrap_encode)?; C::write(writer, &encoded).map_err(wrap_io("failed to write initial request"))?; @@ -53,25 +52,21 @@ pub fn run_conversation( }); }; - let msg: Envelope = C::decode(b).map_err(wrap_decode)?; + let msg: BidirectionalMessage = C::decode(b).map_err(wrap_decode)?; - match (msg.kind, msg.payload) { - (Kind::SubRequest, Payload::SubRequest(sr)) => { + match msg { + BidirectionalMessage::Response(response) => { + return Ok(BidirectionalMessage::Response(response)); + } + BidirectionalMessage::SubRequest(sr) => { let resp = callbacks.handle_sub_request(sr)?; - let reply = - Envelope { kind: Kind::SubResponse, payload: Payload::SubResponse(resp) }; + let reply = BidirectionalMessage::SubResponse(resp); let encoded = C::encode(&reply).map_err(wrap_encode)?; C::write(writer, &encoded).map_err(wrap_io("failed to write sub-response"))?; } - (Kind::Response, payload) => { - return Ok(payload); - } - (kind, payload) => { + _ => { return Err(ServerError { - message: format!( - "unexpected message kind {:?} with payload {:?}", - kind, payload - ), + message: format!("unexpected message {:?}", msg), io: None, }); } @@ -92,7 +87,7 @@ fn wrap_decode(err: io::Error) -> ServerError { } pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result { - let request = Payload::Request(Request::ApiVersionCheck {}); + let request = BidirectionalMessage::Request(Request::ApiVersionCheck {}); struct NoCallbacks; impl ClientCallbacks for NoCallbacks { @@ -106,7 +101,7 @@ pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result Ok(version), + BidirectionalMessage::Response(Response::ApiVersionCheck(version)) => Ok(version), other => { Err(ServerError { message: format!("unexpected response: {:?}", other), io: None }) } @@ -117,8 +112,9 @@ pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result Result { - let request = - Payload::Request(Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer })); + let request = BidirectionalMessage::Request(Request::SetConfig(ServerConfig { + span_mode: SpanMode::RustAnalyzer, + })); struct NoCallbacks; impl ClientCallbacks for NoCallbacks { @@ -132,7 +128,9 @@ pub(crate) fn enable_rust_analyzer_spans( let response_payload = run_request(srv, request, &mut callbacks)?; match response_payload { - Payload::Response(Response::SetConfig(ServerConfig { span_mode })) => Ok(span_mode), + BidirectionalMessage::Response(Response::SetConfig(ServerConfig { span_mode })) => { + Ok(span_mode) + } _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }), } } @@ -142,8 +140,9 @@ pub(crate) fn find_proc_macros( srv: &ProcMacroServerProcess, dylib_path: &AbsPath, ) -> Result, String>, ServerError> { - let request = - Payload::Request(Request::ListMacros { dylib_path: dylib_path.to_path_buf().into() }); + let request = BidirectionalMessage::Request(Request::ListMacros { + dylib_path: dylib_path.to_path_buf().into(), + }); struct NoCallbacks; impl ClientCallbacks for NoCallbacks { @@ -157,7 +156,7 @@ pub(crate) fn find_proc_macros( let response_payload = run_request(srv, request, &mut callbacks)?; match response_payload { - Payload::Response(Response::ListMacros(it)) => Ok(it), + BidirectionalMessage::Response(Response::ListMacros(it)) => Ok(it), _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }), } } @@ -179,7 +178,7 @@ pub(crate) fn expand( let def_site = span_data_table.insert_full(def_site).0; let call_site = span_data_table.insert_full(call_site).0; let mixed_site = span_data_table.insert_full(mixed_site).0; - let task = Payload::Request(Request::ExpandMacro(Box::new(ExpandMacro { + let task = BidirectionalMessage::Request(Request::ExpandMacro(Box::new(ExpandMacro { data: ExpandMacroData { macro_body: FlatTree::from_subtree(subtree, version, &mut span_data_table), macro_name: proc_macro.name.to_string(), @@ -225,7 +224,7 @@ pub(crate) fn expand( let response_payload = run_request(&proc_macro.process, task, &mut callbacks)?; match response_payload { - Payload::Response(Response::ExpandMacro(it)) => Ok(it + BidirectionalMessage::Response(Response::ExpandMacro(it)) => Ok(it .map(|tree| { let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table); if proc_macro.needs_fixup_change() { @@ -234,7 +233,7 @@ pub(crate) fn expand( expanded }) .map_err(|msg| msg.0)), - Payload::Response(Response::ExpandMacroExtended(it)) => Ok(it + BidirectionalMessage::Response(Response::ExpandMacroExtended(it)) => Ok(it .map(|resp| { let mut expanded = FlatTree::to_subtree_resolved( resp.tree, @@ -253,9 +252,9 @@ pub(crate) fn expand( fn run_request( srv: &ProcMacroServerProcess, - msg: Payload, + msg: BidirectionalMessage, callbacks: &mut dyn ClientCallbacks, -) -> Result { +) -> Result { if let Some(server_error) = srv.exited() { return Err(server_error.clone()); } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 4f81ef4ae6bd..cf8becd922de 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -8,20 +8,6 @@ use crate::{ legacy_protocol::msg::{FlatTree, Message, PanicMessage, ServerConfig}, }; -#[derive(Debug, Serialize, Deserialize)] -pub struct Envelope { - pub kind: Kind, - pub payload: Payload, -} - -#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] -pub enum Kind { - Request, - Response, - SubRequest, - SubResponse, -} - #[derive(Debug, Serialize, Deserialize)] pub enum SubRequest { SourceText { file_id: u32, start: u32, end: u32 }, @@ -33,7 +19,7 @@ pub enum SubResponse { } #[derive(Debug, Serialize, Deserialize)] -pub enum Payload { +pub enum BidirectionalMessage { Request(Request), Response(Response), SubRequest(SubRequest), @@ -102,4 +88,4 @@ impl ExpnGlobals { } } -impl Message for Envelope {} +impl Message for BidirectionalMessage {} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index 1c1709e5fa64..6d4025001212 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -4,9 +4,7 @@ use std::{ io::{self, BufRead, BufReader, Read, Write}, panic::AssertUnwindSafe, process::{Child, ChildStdin, ChildStdout, Command, Stdio}, - sync::{ - Arc, Mutex, OnceLock, - }, + sync::{Arc, Mutex, OnceLock}, }; use base_db::SourceDatabase; @@ -17,10 +15,7 @@ use stdx::JodChild; use crate::{ Codec, ProcMacro, ProcMacroKind, ServerError, - bidirectional_protocol::{ - self, ClientCallbacks, - msg::Payload, - }, + bidirectional_protocol::{self, ClientCallbacks, msg::BidirectionalMessage}, legacy_protocol::{self, SpanMode}, version, }; @@ -71,7 +66,10 @@ impl ProcMacroServerProcess { && has_working_format_flag { &[ - (Some("postcard-new"), Protocol::BidirectionalPostcardPrototype { mode: SpanMode::Id }), + ( + Some("postcard-new"), + Protocol::BidirectionalPostcardPrototype { mode: SpanMode::Id }, + ), (Some("postcard-legacy"), Protocol::LegacyPostcard { mode: SpanMode::Id }), (Some("json-legacy"), Protocol::LegacyJson { mode: SpanMode::Id }), ] @@ -222,19 +220,17 @@ impl ProcMacroServerProcess { current_dir, ) } - Protocol::BidirectionalPostcardPrototype { .. } => { - bidirectional_protocol::expand( - proc_macro, - db, - subtree, - attr, - env, - def_site, - call_site, - mixed_site, - current_dir, - ) - } + Protocol::BidirectionalPostcardPrototype { .. } => bidirectional_protocol::expand( + proc_macro, + db, + subtree, + attr, + env, + def_site, + call_site, + mixed_site, + current_dir, + ), } } @@ -300,13 +296,11 @@ impl ProcMacroServerProcess { pub(crate) fn run_bidirectional( &self, - initial: Payload, + initial: BidirectionalMessage, callbacks: &mut dyn ClientCallbacks, - ) -> Result { + ) -> Result { self.with_locked_io::(|writer, reader, buf| { - bidirectional_protocol::run_conversation::( - writer, reader, buf, initial, callbacks, - ) + bidirectional_protocol::run_conversation::(writer, reader, buf, initial, callbacks) }) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index 53302dd5798c..01b261dab748 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -57,11 +57,7 @@ enum ProtocolFormat { impl ValueEnum for ProtocolFormat { fn value_variants<'a>() -> &'a [Self] { - &[ - ProtocolFormat::JsonLegacy, - ProtocolFormat::PostcardLegacy, - ProtocolFormat::PostcardNew, - ] + &[ProtocolFormat::JsonLegacy, ProtocolFormat::PostcardLegacy, ProtocolFormat::PostcardNew] } fn to_possible_value(&self) -> Option { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index ee9b2088117d..9c66a308b18e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -63,54 +63,46 @@ fn run_new() -> io::Result<()> { let mut span_mode = legacy::SpanMode::Id; 'outer: loop { - let req_opt = bidirectional::Envelope::read::<_, C>(&mut stdin, &mut buf)?; + let req_opt = bidirectional::BidirectionalMessage::read::<_, C>(&mut stdin, &mut buf)?; let Some(req) = req_opt else { break 'outer; }; - match (req.kind, req.payload) { - (bidirectional::Kind::Request, bidirectional::Payload::Request(request)) => { - match request { - bidirectional::Request::ListMacros { dylib_path } => { - let res = srv.list_macros(&dylib_path).map(|macros| { - macros - .into_iter() - .map(|(name, kind)| (name, macro_kind_to_api(kind))) - .collect() - }); + match req { + bidirectional::BidirectionalMessage::Request(request) => match request { + bidirectional::Request::ListMacros { dylib_path } => { + let res = srv.list_macros(&dylib_path).map(|macros| { + macros + .into_iter() + .map(|(name, kind)| (name, macro_kind_to_api(kind))) + .collect() + }); - send_response::<_, C>( - &mut stdout, - bidirectional::Response::ListMacros(res), - )?; - } - - bidirectional::Request::ApiVersionCheck {} => { - send_response::<_, C>( - &mut stdout, - bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), - )?; - } - - bidirectional::Request::SetConfig(config) => { - span_mode = config.span_mode; - send_response::<_, C>( - &mut stdout, - bidirectional::Response::SetConfig(config), - )?; - } - bidirectional::Request::ExpandMacro(task) => { - handle_expand::<_, _, C>( - &srv, - &mut stdin, - &mut stdout, - &mut buf, - span_mode, - *task, - )?; - } + send_response::<_, C>(&mut stdout, bidirectional::Response::ListMacros(res))?; } - } + + bidirectional::Request::ApiVersionCheck {} => { + send_response::<_, C>( + &mut stdout, + bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), + )?; + } + + bidirectional::Request::SetConfig(config) => { + span_mode = config.span_mode; + send_response::<_, C>(&mut stdout, bidirectional::Response::SetConfig(config))?; + } + bidirectional::Request::ExpandMacro(task) => { + handle_expand::<_, _, C>( + &srv, + &mut stdin, + &mut stdout, + &mut buf, + span_mode, + *task, + )?; + } + }, _ => continue, } } @@ -265,11 +257,8 @@ fn handle_expand_ra( loop { if let Ok(res) = result_rx.try_recv() { - send_response::<_, C>( - stdout, - bidirectional::Response::ExpandMacroExtended(res), - ) - .unwrap(); + send_response::<_, C>(stdout, bidirectional::Response::ExpandMacroExtended(res)) + .unwrap(); break; } @@ -282,7 +271,7 @@ fn handle_expand_ra( send_subrequest::<_, C>(stdout, from_srv_req(subreq)).unwrap(); - let resp_opt = bidirectional::Envelope::read::<_, C>(stdin, buf).unwrap(); + let resp_opt = bidirectional::BidirectionalMessage::read::<_, C>(stdin, buf).unwrap(); let resp = match resp_opt { Some(env) => env, None => { @@ -290,11 +279,8 @@ fn handle_expand_ra( } }; - match (resp.kind, resp.payload) { - ( - bidirectional::Kind::SubResponse, - bidirectional::Payload::SubResponse(subresp), - ) => { + match resp { + bidirectional::BidirectionalMessage::SubResponse(subresp) => { let _ = subresp_tx.send(from_client_res(subresp)); } _ => { @@ -466,10 +452,7 @@ fn send_response( stdout: &mut W, resp: bidirectional::Response, ) -> io::Result<()> { - let resp = bidirectional::Envelope { - kind: bidirectional::Kind::Response, - payload: bidirectional::Payload::Response(resp), - }; + let resp = bidirectional::BidirectionalMessage::Response(resp); resp.write::(stdout) } @@ -477,9 +460,6 @@ fn send_subrequest( stdout: &mut W, resp: bidirectional::SubRequest, ) -> io::Result<()> { - let resp = bidirectional::Envelope { - kind: bidirectional::Kind::SubRequest, - payload: bidirectional::Payload::SubRequest(resp), - }; + let resp = bidirectional::BidirectionalMessage::SubRequest(resp); resp.write::(stdout) } From 7eeaa7ad4841b8e0e63bfd2dff5e2fba7d1fadf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 22 Dec 2025 16:31:05 +0200 Subject: [PATCH 1148/3801] Fix name collision warning --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 90a0c2b402c0..9fc29de4a11c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -2624,7 +2624,7 @@ impl SelfParam { let callable_sig = db.callable_item_signature(self.func.into()).instantiate_identity().skip_binder(); let environment = param_env_from_has_crate(db, self.func); - let ty = callable_sig.inputs().as_slice()[0]; + let ty = rustc_type_ir::inherent::SliceLike::as_slice(&callable_sig.inputs())[0]; Type { env: environment, ty } } @@ -2639,7 +2639,7 @@ impl SelfParam { let callable_sig = db.callable_item_signature(self.func.into()).instantiate(interner, args).skip_binder(); let environment = param_env_from_has_crate(db, self.func); - let ty = callable_sig.inputs().as_slice()[0]; + let ty = rustc_type_ir::inherent::SliceLike::as_slice(&callable_sig.inputs())[0]; Type { env: environment, ty } } } From 27be5c2f682567a8825d6b50a04feda8f74ccf39 Mon Sep 17 00:00:00 2001 From: Soroush Mirzaei Date: Mon, 22 Dec 2025 10:14:57 -0500 Subject: [PATCH 1149/3801] docs(core): update `find()` and `rfind()` examples `find()` has a missing example. In the docs there was a mention of an example with double reference but it didn't exist. `rfind()` is also very similar to `find()`, however it had the double reference example and no owned value example like `find()` did. This commit adds the missing examples and making them look consistent. --- library/core/src/iter/traits/double_ended.rs | 12 +++++++++++- library/core/src/iter/traits/iterator.rs | 11 +++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 7dabaece9556..da0b05063657 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -334,8 +334,18 @@ pub trait DoubleEndedIterator: Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// assert_eq!(a.iter().rfind(|&&x| x == 2), Some(&2)); + /// assert_eq!(a.into_iter().rfind(|&x| x == 2), Some(2)); + /// assert_eq!(a.into_iter().rfind(|&x| x == 5), None); + /// ``` /// + /// Iterating over references: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// // `iter()` yields references i.e. `&i32` and `rfind()` takes a + /// // reference to each element. + /// assert_eq!(a.iter().rfind(|&&x| x == 2), Some(&2)); /// assert_eq!(a.iter().rfind(|&&x| x == 5), None); /// ``` /// diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 29230b166538..d99afbc6036d 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2858,6 +2858,17 @@ pub trait Iterator { /// assert_eq!(a.into_iter().find(|&x| x == 5), None); /// ``` /// + /// Iterating over references: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// // `iter()` yields references i.e. `&i32` and `find()` takes a + /// // reference to each element. + /// assert_eq!(a.iter().find(|&&x| x == 2), Some(&2)); + /// assert_eq!(a.iter().find(|&&x| x == 5), None); + /// ``` + /// /// Stopping at the first `true`: /// /// ``` From 7afba2977d0d8a2a2148cbdc244a86258bb5d328 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 9 Dec 2025 09:49:50 +0100 Subject: [PATCH 1150/3801] Make attr path symbols rather than idents --- compiler/rustc_ast/src/attr/mod.rs | 42 +++++++++---------- compiler/rustc_ast_passes/src/feature_gate.rs | 2 +- .../rustc_attr_parsing/src/attributes/cfg.rs | 8 +--- .../src/attributes/cfg_select.rs | 7 +--- .../rustc_attr_parsing/src/attributes/util.rs | 3 +- compiler/rustc_attr_parsing/src/parser.rs | 2 +- compiler/rustc_attr_parsing/src/safety.rs | 2 +- .../rustc_attr_parsing/src/target_checking.rs | 2 +- .../rustc_attr_parsing/src/validate_attr.rs | 2 +- compiler/rustc_builtin_macros/src/cfg.rs | 4 +- compiler/rustc_builtin_macros/src/cfg_eval.rs | 5 +-- .../rustc_codegen_ssa/src/codegen_attrs.rs | 4 +- compiler/rustc_expand/src/expand.rs | 4 +- compiler/rustc_hir/src/hir.rs | 33 ++++++++------- compiler/rustc_hir_pretty/src/lib.rs | 8 +++- .../rustc_parse/src/parser/attr_wrapper.rs | 12 +++--- compiler/rustc_passes/src/check_attr.rs | 4 +- .../src/ich/impls_syntax.rs | 2 +- src/librustdoc/clean/cfg.rs | 4 +- src/librustdoc/clean/mod.rs | 4 +- src/librustdoc/passes/propagate_doc_cfg.rs | 4 +- .../src/attrs/allow_attributes.rs | 7 ++-- .../clippy/clippy_lints/src/attrs/mod.rs | 12 +++--- .../src/attrs/useless_attribute.rs | 2 +- .../clippy_lints/src/incompatible_msrv.rs | 2 +- .../clippy/clippy_lints/src/missing_doc.rs | 4 +- src/tools/clippy/clippy_utils/src/attrs.rs | 17 ++++---- .../clippy_utils/src/check_proc_macro.rs | 4 +- .../tests/ui/renamed_builtin_attr.stderr | 4 +- .../clippy/tests/ui/unknown_attribute.stderr | 4 +- src/tools/rustfmt/src/attr.rs | 4 +- 31 files changed, 103 insertions(+), 115 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index c53188a22aed..c0ed6e24e222 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -96,11 +96,11 @@ impl AttributeExt for Attribute { } /// For a single-segment attribute, returns its name; otherwise, returns `None`. - fn ident(&self) -> Option { + fn name(&self) -> Option { match &self.kind { AttrKind::Normal(normal) => { if let [ident] = &*normal.item.path.segments { - Some(ident.ident) + Some(ident.ident.name) } else { None } @@ -109,9 +109,18 @@ impl AttributeExt for Attribute { } } - fn ident_path(&self) -> Option> { + fn symbol_path(&self) -> Option> { match &self.kind { - AttrKind::Normal(p) => Some(p.item.path.segments.iter().map(|i| i.ident).collect()), + AttrKind::Normal(p) => { + Some(p.item.path.segments.iter().map(|i| i.ident.name).collect()) + } + AttrKind::DocComment(_, _) => None, + } + } + + fn path_span(&self) -> Option { + match &self.kind { + AttrKind::Normal(attr) => Some(attr.item.path.span), AttrKind::DocComment(_, _) => None, } } @@ -794,9 +803,7 @@ pub trait AttributeExt: Debug { /// For a single-segment attribute (i.e., `#[attr]` and not `#[path::atrr]`), /// return the name of the attribute; otherwise, returns `None`. - fn name(&self) -> Option { - self.ident().map(|ident| ident.name) - } + fn name(&self) -> Option; /// Get the meta item list, `#[attr(meta item list)]` fn meta_item_list(&self) -> Option>; @@ -807,9 +814,6 @@ pub trait AttributeExt: Debug { /// Gets the span of the value literal, as string, when using `#[attr = value]` fn value_span(&self) -> Option; - /// For a single-segment attribute, returns its ident; otherwise, returns `None`. - fn ident(&self) -> Option; - /// Checks whether the path of this attribute matches the name. /// /// Matches one segment of the path to each element in `name` @@ -822,7 +826,7 @@ pub trait AttributeExt: Debug { #[inline] fn has_name(&self, name: Symbol) -> bool { - self.ident().map(|x| x.name == name).unwrap_or(false) + self.name().map(|x| x == name).unwrap_or(false) } #[inline] @@ -836,13 +840,13 @@ pub trait AttributeExt: Debug { fn is_word(&self) -> bool; fn path(&self) -> SmallVec<[Symbol; 1]> { - self.ident_path() - .map(|i| i.into_iter().map(|i| i.name).collect()) - .unwrap_or(smallvec![sym::doc]) + self.symbol_path().unwrap_or(smallvec![sym::doc]) } + fn path_span(&self) -> Option; + /// Returns None for doc comments - fn ident_path(&self) -> Option>; + fn symbol_path(&self) -> Option>; /// Returns the documentation if this is a doc comment or a sugared doc comment. /// * `///doc` returns `Some("doc")`. @@ -903,10 +907,6 @@ impl Attribute { AttributeExt::value_span(self) } - pub fn ident(&self) -> Option { - AttributeExt::ident(self) - } - pub fn path_matches(&self, name: &[Symbol]) -> bool { AttributeExt::path_matches(self, name) } @@ -938,10 +938,6 @@ impl Attribute { AttributeExt::path(self) } - pub fn ident_path(&self) -> Option> { - AttributeExt::ident_path(self) - } - pub fn doc_str(&self) -> Option { AttributeExt::doc_str(self) } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index dbbd3906b525..26eb8051df37 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -160,7 +160,7 @@ impl<'a> PostExpansionVisitor<'a> { impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_attribute(&mut self, attr: &ast::Attribute) { - let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); + let attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)); // Check feature gates for built-in attributes. if let Some(BuiltinAttribute { gate: AttributeGate::Gated { feature, message, check, notes, .. }, diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 798cc1076541..66f0f8d391f6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -371,13 +371,7 @@ fn parse_cfg_attr_internal<'a>( attribute.span, attribute.get_normal_item().span(), attribute.style, - AttrPath { - segments: attribute - .ident_path() - .expect("cfg_attr is not a doc comment") - .into_boxed_slice(), - span: attribute.span, - }, + AttrPath { segments: attribute.path().into_boxed_slice(), span: attribute.span }, Some(attribute.get_normal_item().unsafety), ParsedDescription::Attribute, pred_span, diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs index 00a2d12106e7..24b989e22a2b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs @@ -7,7 +7,7 @@ use rustc_hir::attrs::CfgEntry; use rustc_parse::exp; use rustc_parse::parser::Parser; use rustc_session::Session; -use rustc_span::{ErrorGuaranteed, Ident, Span}; +use rustc_span::{ErrorGuaranteed, Span, sym}; use crate::parser::MetaItemOrLitParser; use crate::{AttributeParser, ParsedDescription, ShouldEmit, parse_cfg_entry}; @@ -86,10 +86,7 @@ pub fn parse_cfg_select( cfg_span, cfg_span, AttrStyle::Inner, - AttrPath { - segments: vec![Ident::from_str("cfg_select")].into_boxed_slice(), - span: cfg_span, - }, + AttrPath { segments: vec![sym::cfg_select].into_boxed_slice(), span: cfg_span }, None, ParsedDescription::Macro, cfg_span, diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs index 431ba539b2ba..ebec8e8443fc 100644 --- a/compiler/rustc_attr_parsing/src/attributes/util.rs +++ b/compiler/rustc_attr_parsing/src/attributes/util.rs @@ -28,8 +28,7 @@ pub fn parse_version(s: Symbol) -> Option { } pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { - attr.is_doc_comment().is_some() - || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) + attr.is_doc_comment().is_some() || attr.name().is_some_and(|name| is_builtin_attr_name(name)) } /// Parse a single integer. diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 9551744d5ec5..9c0fbe92d71b 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -34,7 +34,7 @@ pub type RefPathParser<'p> = PathParser<&'p Path>; impl> PathParser
"; const REEXPORTS_TABLE_OPEN: &str = "
"; const ITEM_TABLE_CLOSE: &str = "
"; @@ -300,10 +216,6 @@ fn toggle_close(mut w: impl fmt::Write) { w.write_str("").unwrap(); } -trait ItemTemplate<'a, 'cx: 'a>: askama::Template + Display { - fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>); -} - fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> impl fmt::Display { fmt::from_fn(|w| { write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?; @@ -1482,20 +1394,32 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> }) } -item_template!( - #[template(path = "item_union.html")] - struct ItemUnion<'a, 'cx> { - cx: &'a Context<'cx>, - it: &'a clean::Item, - fields: &'a [clean::Item], - generics: &'a clean::Generics, - is_type_alias: bool, - def_id: DefId, - }, - methods = [document, document_type_layout, render_assoc_items] -); +#[derive(Template)] +#[template(path = "item_union.html")] +struct ItemUnion<'a, 'cx> { + cx: &'a Context<'cx>, + it: &'a clean::Item, + fields: &'a [clean::Item], + generics: &'a clean::Generics, + is_type_alias: bool, + def_id: DefId, +} impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { + fn document(&self) -> impl fmt::Display { + document(self.cx, self.it, None, HeadingOffset::H2) + } + + fn document_type_layout(&self) -> impl fmt::Display { + let def_id = self.it.item_id.expect_def_id(); + document_type_layout(self.cx, def_id) + } + + fn render_assoc_items(&self) -> impl fmt::Display { + let def_id = self.it.item_id.expect_def_id(); + render_assoc_items(self.cx, self.it, def_id, AssocItemRender::All) + } + fn render_union(&self) -> impl Display { render_union( self.it, diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index df9e8631bbdd..a4535792ac3c 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -128,10 +128,12 @@ pub(crate) mod filters { use askama::filters::Safe; use crate::html::escape::EscapeBodyTextWithWbr; - pub(crate) fn wrapped(v: T, _: V) -> askama::Result> - where - T: Display, - { + + #[askama::filter_fn] + pub(crate) fn wrapped( + v: impl Display, + _: &dyn askama::Values, + ) -> askama::Result> { let string = v.to_string(); Ok(Safe(fmt::from_fn(move |f| EscapeBodyTextWithWbr(&string).fmt(f)))) } From 5c1df0d0fafb244905644885540ea8945a8af07a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 24 Dec 2025 15:51:53 +0100 Subject: [PATCH 1361/3801] Update askama version to `0.15` in citool --- src/ci/citool/Cargo.lock | 28 +++++++++++++++-------- src/ci/citool/Cargo.toml | 2 +- src/ci/citool/templates/test_group.askama | 4 ++-- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index ab5d2adc9dc5..9e1ded4d3f7c 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -66,11 +66,11 @@ checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "askama" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4" +checksum = "bb7125972258312e79827b60c9eb93938334100245081cf701a2dee981b17427" dependencies = [ - "askama_derive", + "askama_macros", "itoa", "percent-encoding", "serde", @@ -79,9 +79,9 @@ dependencies = [ [[package]] name = "askama_derive" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f" +checksum = "8ba5e7259a1580c61571e3116ebaaa01e3c001b2132b17c4cc5c70780ca3e994" dependencies = [ "askama_parser", "basic-toml", @@ -95,14 +95,24 @@ dependencies = [ ] [[package]] -name = "askama_parser" -version = "0.14.0" +name = "askama_macros" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358" +checksum = "236ce20b77cb13506eaf5024899f4af6e12e8825f390bd943c4c37fd8f322e46" dependencies = [ - "memchr", + "askama_derive", +] + +[[package]] +name = "askama_parser" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c63392767bb2df6aa65a6e1e3b80fd89bb7af6d58359b924c0695620f1512e" +dependencies = [ + "rustc-hash", "serde", "serde_derive", + "unicode-ident", "winnow", ] diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index 078b877e44b1..468d8c8a02aa 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] anyhow = "1" -askama = "0.14" +askama = "0.15.1" clap = { version = "4.5", features = ["derive"] } csv = "1" diff = "0.1" diff --git a/src/ci/citool/templates/test_group.askama b/src/ci/citool/templates/test_group.askama index 95731103f3b9..1a72c47d3788 100644 --- a/src/ci/citool/templates/test_group.askama +++ b/src/ci/citool/templates/test_group.askama @@ -24,12 +24,12 @@ passed: {{ r.passed.len() }}, ignored: {{ r.ignored.len() }} {% for (name, test) in root_tests %}
  • {% if let Some(result) = test.single_test() %} - {{ name }} ({% call test_result(result) %}) + {{ name }} ({% call test_result(result) %}{% endcall %}) {% else %} {{ name }} ({{ test.revisions.len() }} revision{{ test.revisions.len() | pluralize }})
      {% for (revision, result) in test.revisions %} -
    • #{{ revision }} ({% call test_result(result) %})
    • +
    • #{{ revision }} ({% call test_result(result) %}{% endcall %})
    • {% endfor %}
    {% endif %} From 45592688cf37aa8c9cd8ff30fc6009e722636ec4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 24 Dec 2025 15:55:17 +0100 Subject: [PATCH 1362/3801] Update askama version to `0.15` in `generate-copyright` --- Cargo.lock | 2 +- src/tools/generate-copyright/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca0853c110d5..9d29f4498de2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1567,7 +1567,7 @@ name = "generate-copyright" version = "0.1.0" dependencies = [ "anyhow", - "askama 0.14.0", + "askama 0.15.1", "cargo_metadata 0.21.0", "serde", "serde_json", diff --git a/src/tools/generate-copyright/Cargo.toml b/src/tools/generate-copyright/Cargo.toml index bcb3165de458..66b9f394409b 100644 --- a/src/tools/generate-copyright/Cargo.toml +++ b/src/tools/generate-copyright/Cargo.toml @@ -8,7 +8,7 @@ description = "Produces a manifest of all the copyrighted materials in the Rust [dependencies] anyhow = "1.0.65" -askama = "0.14.0" +askama = "0.15.1" cargo_metadata = "0.21" serde = { version = "1.0.147", features = ["derive"] } serde_json = "1.0.85" From aede29f9ed0b85b305c0bfe6064f7e9126982145 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sun, 28 Dec 2025 21:23:33 +0000 Subject: [PATCH 1363/3801] Enhance `needless_collect` to cover vec `push` --- clippy_lints/src/methods/needless_collect.rs | 113 ++++++++++++++++--- clippy_utils/src/sym.rs | 1 + tests/ui/needless_collect.fixed | 45 ++++++++ tests/ui/needless_collect.rs | 45 ++++++++ tests/ui/needless_collect.stderr | 54 ++++++++- 5 files changed, 242 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 0e2012319147..312133689900 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -16,8 +16,8 @@ use rustc_hir::{ use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, AssocTag, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty}; -use rustc_span::Span; use rustc_span::symbol::Ident; +use rustc_span::{Span, Symbol}; const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed"; @@ -104,16 +104,19 @@ pub(super) fn check<'tcx>( Node::LetStmt(l) => { if let PatKind::Binding(BindingMode::NONE | BindingMode::MUT, id, _, None) = l.pat.kind && let ty = cx.typeck_results().expr_ty(collect_expr) - && matches!( - ty.opt_diag_name(cx), - Some(sym::Vec | sym::VecDeque | sym::BinaryHeap | sym::LinkedList) - ) + && let Some(extra_spec) = ty.opt_diag_name(cx).and_then(ExtraFunctionSpec::new) && let iter_ty = cx.typeck_results().expr_ty(iter_expr) && let Some(block) = get_enclosing_block(cx, l.hir_id) - && let Some(iter_calls) = detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty)) + && let Some((iter_calls, extra_calls)) = + detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty), extra_spec) && let [iter_call] = &*iter_calls { - let mut used_count_visitor = UsedCountVisitor { cx, id, count: 0 }; + let mut used_count_visitor = UsedCountVisitor { + cx, + id, + extra_spec, + count: 0, + }; walk_block(&mut used_count_visitor, block); if used_count_visitor.count > 1 { return; @@ -135,11 +138,18 @@ pub(super) fn check<'tcx>( span, NEEDLESS_COLLECT_MSG, |diag| { - let iter_replacement = - format!("{}{}", Sugg::hir(cx, iter_expr, ".."), iter_call.get_iter_method(cx)); + let iter_snippet = Sugg::hir(cx, iter_expr, ".."); + let mut iter_replacement = iter_snippet.to_string(); + iter_replacement.extend(extra_calls.iter().map(|extra| extra.get_iter_method(cx))); + iter_replacement.push_str(&iter_call.get_iter_method(cx)); + + let mut remove_suggestions = vec![(l.span, String::new())]; + remove_suggestions.extend(extra_calls.iter().map(|extra| (extra.span, String::new()))); + remove_suggestions.push((iter_call.span, iter_replacement)); + diag.multipart_suggestion( iter_call.get_suggestion_text(), - vec![(l.span, String::new()), (iter_call.span, iter_replacement)], + remove_suggestions, Applicability::MaybeIncorrect, ); }, @@ -272,6 +282,7 @@ struct IterFunction { func: IterFunctionKind, span: Span, } + impl IterFunction { fn get_iter_method(&self, cx: &LateContext<'_>) -> String { match &self.func { @@ -288,6 +299,7 @@ impl IterFunction { }, } } + fn get_suggestion_text(&self) -> &'static str { match &self.func { IterFunctionKind::IntoIter(_) => { @@ -305,6 +317,7 @@ impl IterFunction { } } } + enum IterFunctionKind { IntoIter(HirId), Len, @@ -312,16 +325,59 @@ enum IterFunctionKind { Contains(Span), } +struct ExtraFunction { + kind: ExtraFunctionKind, + span: Span, +} + +impl ExtraFunction { + fn get_iter_method(&self, cx: &LateContext<'_>) -> String { + match &self.kind { + ExtraFunctionKind::Push(span) => { + let s = snippet(cx, *span, ".."); + format!(".chain([{s}])") + }, + } + } +} + +enum ExtraFunctionKind { + Push(Span), +} + +#[derive(Clone, Copy)] +struct ExtraFunctionSpec { + push_symbol: Option, +} + +impl ExtraFunctionSpec { + fn new(target: Symbol) -> Option { + match target { + sym::Vec => Some(ExtraFunctionSpec { + push_symbol: Some(sym::push), + }), + sym::VecDeque | sym::LinkedList => Some(ExtraFunctionSpec { + push_symbol: Some(sym::push_back), + }), + sym::BinaryHeap => Some(ExtraFunctionSpec { push_symbol: None }), + _ => None, + } + } +} + struct IterFunctionVisitor<'a, 'tcx> { illegal_mutable_capture_ids: HirIdSet, current_mutably_captured_ids: HirIdSet, cx: &'a LateContext<'tcx>, uses: Vec>, + extras: Vec, + extra_spec: ExtraFunctionSpec, hir_id_uses_map: FxHashMap, current_statement_hir_id: Option, seen_other: bool, target: HirId, } + impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> { fn visit_block(&mut self, block: &'tcx Block<'tcx>) { for (expr, hir_id) in block.stmts.iter().filter_map(get_expr_and_hir_id_from_stmt) { @@ -384,6 +440,17 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> { func: IterFunctionKind::Contains(args[0].span), span: expr.span, })), + name if Some(name) == self.extra_spec.push_symbol && self.uses.is_empty() => { + let mut span = expr.span; + // Remove the statement span if possible + if let Node::Stmt(stmt) = self.cx.tcx.parent_hir_node(expr.hir_id) { + span = stmt.span; + } + self.extras.push(ExtraFunction { + kind: ExtraFunctionKind::Push(args[0].span), + span, + }); + }, _ => { self.seen_other = true; if let Some(hir_id) = self.current_statement_hir_id { @@ -468,6 +535,7 @@ fn get_expr_and_hir_id_from_stmt<'v>(stmt: &'v Stmt<'v>) -> Option<(&'v Expr<'v> struct UsedCountVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, id: HirId, + extra_spec: ExtraFunctionSpec, count: usize, } @@ -475,11 +543,23 @@ impl<'tcx> Visitor<'tcx> for UsedCountVisitor<'_, 'tcx> { type NestedFilter = nested_filter::OnlyBodies; fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if expr.res_local_id() == Some(self.id) { - self.count += 1; - } else { + if expr.res_local_id() != Some(self.id) { walk_expr(self, expr); + return; } + + let parent = self.cx.tcx.parent_hir_node(expr.hir_id); + if let Node::Expr(expr) = parent + && let ExprKind::MethodCall(method_name, _, _, _) = &expr.kind + && self + .extra_spec + .push_symbol + .is_some_and(|sym| method_name.ident.name == sym) + { + return; + } + + self.count += 1; } fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { @@ -494,12 +574,15 @@ fn detect_iter_and_into_iters<'tcx: 'a, 'a>( id: HirId, cx: &'a LateContext<'tcx>, captured_ids: HirIdSet, -) -> Option> { + extra_spec: ExtraFunctionSpec, +) -> Option<(Vec, Vec)> { let mut visitor = IterFunctionVisitor { illegal_mutable_capture_ids: captured_ids, current_mutably_captured_ids: HirIdSet::default(), cx, uses: Vec::new(), + extras: Vec::new(), + extra_spec, hir_id_uses_map: FxHashMap::default(), current_statement_hir_id: None, seen_other: false, @@ -509,7 +592,7 @@ fn detect_iter_and_into_iters<'tcx: 'a, 'a>( if visitor.seen_other { None } else { - Some(visitor.uses.into_iter().flatten().collect()) + Some((visitor.uses.into_iter().flatten().collect(), visitor.extras)) } } diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index a0d2e8673fe6..a36f4954a06a 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -271,6 +271,7 @@ generate! { powi, product, push, + push_back, push_str, read, read_exact, diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index 99027e79b664..fff383fb1328 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -219,3 +219,48 @@ fn issue16270() { // Do not lint, `..` implements `Index` but is not `usize` _ = &(1..3).collect::>()[..]; } + +#[warn(clippy::needless_collect)] +mod collect_push_then_iter { + use std::collections::{BinaryHeap, LinkedList}; + + fn vec_push(iter: impl Iterator) -> Vec { + + //~^ needless_collect + + iter.chain([1]).map(|x| x + 1).collect() + } + + fn vec_push_no_iter(iter: impl Iterator) { + let mut v = iter.collect::>(); + v.push(1); + } + + fn vec_push_multiple(iter: impl Iterator) -> Vec { + + //~^ needless_collect + + + iter.chain([1]).chain([2]).map(|x| x + 1).collect() + } + + fn linked_list_push(iter: impl Iterator) -> LinkedList { + + //~^ needless_collect + + iter.chain([1]).map(|x| x + 1).collect() + } + + fn binary_heap_push(iter: impl Iterator) -> BinaryHeap { + let mut v = iter.collect::>(); + v.push(1); + v.into_iter().map(|x| x + 1).collect() + } + + fn vec_push_mixed(iter: impl Iterator) -> bool { + let mut v = iter.collect::>(); + let ok = v.contains(&1); + v.push(1); + ok + } +} diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index 683cc49c9af3..f6e966b09ea5 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -219,3 +219,48 @@ fn issue16270() { // Do not lint, `..` implements `Index` but is not `usize` _ = &(1..3).collect::>()[..]; } + +#[warn(clippy::needless_collect)] +mod collect_push_then_iter { + use std::collections::{BinaryHeap, LinkedList}; + + fn vec_push(iter: impl Iterator) -> Vec { + let mut v = iter.collect::>(); + //~^ needless_collect + v.push(1); + v.into_iter().map(|x| x + 1).collect() + } + + fn vec_push_no_iter(iter: impl Iterator) { + let mut v = iter.collect::>(); + v.push(1); + } + + fn vec_push_multiple(iter: impl Iterator) -> Vec { + let mut v = iter.collect::>(); + //~^ needless_collect + v.push(1); + v.push(2); + v.into_iter().map(|x| x + 1).collect() + } + + fn linked_list_push(iter: impl Iterator) -> LinkedList { + let mut v = iter.collect::>(); + //~^ needless_collect + v.push_back(1); + v.into_iter().map(|x| x + 1).collect() + } + + fn binary_heap_push(iter: impl Iterator) -> BinaryHeap { + let mut v = iter.collect::>(); + v.push(1); + v.into_iter().map(|x| x + 1).collect() + } + + fn vec_push_mixed(iter: impl Iterator) -> bool { + let mut v = iter.collect::>(); + let ok = v.contains(&1); + v.push(1); + ok + } +} diff --git a/tests/ui/needless_collect.stderr b/tests/ui/needless_collect.stderr index c77674dc55d4..93ca32a68d6a 100644 --- a/tests/ui/needless_collect.stderr +++ b/tests/ui/needless_collect.stderr @@ -121,5 +121,57 @@ error: avoid using `collect()` when not needed LL | baz((0..10), (), ('a'..='z').collect::>()) | ^^^^^^^^^^^^^^^^^^^^ help: remove this call -error: aborting due to 20 previous errors +error: avoid using `collect()` when not needed + --> tests/ui/needless_collect.rs:228:26 + | +LL | let mut v = iter.collect::>(); + | ^^^^^^^ +... +LL | v.into_iter().map(|x| x + 1).collect() + | ------------- the iterator could be used here instead + | +help: use the original Iterator instead of collecting it and then producing a new one + | +LL ~ +LL | +LL ~ +LL ~ iter.chain([1]).map(|x| x + 1).collect() + | + +error: avoid using `collect()` when not needed + --> tests/ui/needless_collect.rs:240:26 + | +LL | let mut v = iter.collect::>(); + | ^^^^^^^ +... +LL | v.into_iter().map(|x| x + 1).collect() + | ------------- the iterator could be used here instead + | +help: use the original Iterator instead of collecting it and then producing a new one + | +LL ~ +LL | +LL ~ +LL ~ +LL ~ iter.chain([1]).chain([2]).map(|x| x + 1).collect() + | + +error: avoid using `collect()` when not needed + --> tests/ui/needless_collect.rs:248:26 + | +LL | let mut v = iter.collect::>(); + | ^^^^^^^ +... +LL | v.into_iter().map(|x| x + 1).collect() + | ------------- the iterator could be used here instead + | +help: use the original Iterator instead of collecting it and then producing a new one + | +LL ~ +LL | +LL ~ +LL ~ iter.chain([1]).map(|x| x + 1).collect() + | + +error: aborting due to 23 previous errors From c516c284755130dac7d3232b7c40567a57cfb936 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Mon, 29 Dec 2025 06:45:17 +0800 Subject: [PATCH 1364/3801] Add useless prefix `try_into_` for suggest_name Example --- ```rust enum Foo { Num(i32) } impl Foo { fn try_into_num(self) -> Result { if let Self::Num(v) = self { Ok(v) } else { Err(self) } } } fn handle(foo: Foo) { foo.try_into_num().$0 } ``` **Before this PR** ```rust fn handle(foo: Foo) { if let Ok(${1:try_into_num}) = foo.try_into_num() { $0 } } ``` **After this PR** ```rust fn handle(foo: Foo) { if let Ok(${1:num}) = foo.try_into_num() { $0 } } ``` --- .../crates/ide-db/src/syntax_helpers/suggest_name.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs index 273328a8d270..b8b9a7a76816 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs @@ -44,7 +44,7 @@ const SEQUENCE_TYPES: &[&str] = &["Vec", "VecDeque", "LinkedList"]; /// `vec.as_slice()` -> `slice` /// `args.into_config()` -> `config` /// `bytes.to_vec()` -> `vec` -const USELESS_METHOD_PREFIXES: &[&str] = &["into_", "as_", "to_"]; +const USELESS_METHOD_PREFIXES: &[&str] = &["try_into_", "into_", "as_", "to_"]; /// Useless methods that are stripped from expression /// From 998a0df610eff8c262106c3dc567358d241ef026 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 28 Dec 2025 15:18:30 -0500 Subject: [PATCH 1365/3801] more sophisticated checking --- .../src/error_reporting/traits/suggestions.rs | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index c5b014293f98..511e9e85b5f6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4069,24 +4069,45 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )) && expr.span.hi() != rcvr.span.hi() { - match tcx.hir_node(call_hir_id) { - // Do not suggest removing a method call if the argument is the receiver of the parent call: - // `x.a().b()`, suggesting removing `.a()` would change the type and could make `.b()` unavailable. + let should_sugg = match tcx.hir_node(call_hir_id) { Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(_, call_receiver, _, _), .. - }) if call_receiver.hir_id == arg_hir_id => {} - _ => { - err.span_suggestion_verbose( - expr.span.with_lo(rcvr.span.hi()), - format!( - "consider removing this method call, as the receiver has type `{ty}` and \ - `{pred}` trivially holds", - ), - "", - Applicability::MaybeIncorrect, - ); + }) if let Some((DefKind::AssocFn, did)) = + typeck_results.type_dependent_def(call_hir_id) + && call_receiver.hir_id == arg_hir_id => + { + // Avoid suggesting removing a method call if the argument is the receiver of the parent call and + // removing the receiver would make the method inaccessible. i.e. `x.a().b()`, suggesting removing + // `.a()` could change the type and make `.b()` unavailable. + if tcx.inherent_impl_of_assoc(did).is_some() { + // if we're calling an inherent impl method, just try to make sure that the receiver type stays the same. + Some(ty) == typeck_results.node_type_opt(arg_hir_id) + } else { + // we're calling a trait method, so we just check removing the method call still satisfies the trait. + let trait_id = tcx + .trait_of_assoc(did) + .unwrap_or_else(|| tcx.impl_trait_id(tcx.parent(did))); + let args = typeck_results.node_args(call_hir_id); + let tr = ty::TraitRef::from_assoc(tcx, trait_id, args) + .with_replaced_self_ty(tcx, ty); + self.type_implements_trait(tr.def_id, tr.args, param_env) + .must_apply_modulo_regions() + } } + _ => true, + }; + + if should_sugg { + err.span_suggestion_verbose( + expr.span.with_lo(rcvr.span.hi()), + format!( + "consider removing this method call, as the receiver has type `{ty}` and \ + `{pred}` trivially holds", + ), + "", + Applicability::MaybeIncorrect, + ); } } if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr { From 49b6f677a50ac57051806eef1727b6a40bb2a196 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 29 Dec 2025 04:14:12 +0200 Subject: [PATCH 1366/3801] Separate the public `tt` API from how they're stored And don't provide any insight into the actual storage (no references, no "cheat" methods like `flat_tokens()`), as we're going to rewrite it to be more memory efficient. --- .../rust-analyzer/crates/cfg/src/cfg_expr.rs | 11 +- .../hir-def/src/nameres/attr_resolution.rs | 2 +- .../crates/hir-def/src/nameres/collector.rs | 4 +- .../crates/hir-def/src/nameres/proc_macro.rs | 51 ++--- .../crates/hir-expand/src/attrs.rs | 19 +- .../crates/hir-expand/src/builtin/fn_macro.rs | 65 +++--- .../crates/hir-expand/src/builtin/quote.rs | 9 +- .../rust-analyzer/crates/hir-expand/src/db.rs | 14 +- .../crates/hir-expand/src/eager.rs | 2 +- .../crates/hir-expand/src/fixup.rs | 95 ++------- .../crates/hir-expand/src/mod_path.rs | 10 +- .../rust-analyzer/crates/mbe/src/benchmark.rs | 2 +- .../rust-analyzer/crates/mbe/src/expander.rs | 2 +- .../crates/mbe/src/expander/matcher.rs | 10 +- .../crates/mbe/src/expander/transcriber.rs | 22 ++- .../rust-analyzer/crates/mbe/src/parser.rs | 8 +- .../src/legacy_protocol/msg/flat.rs | 20 +- .../crates/proc-macro-api/src/lib.rs | 18 +- .../crates/syntax-bridge/src/lib.rs | 14 +- .../crates/syntax-bridge/src/tests.rs | 2 +- .../crates/test-fixture/src/lib.rs | 42 ++-- .../rust-analyzer/crates/tt/src/buffer.rs | 4 +- src/tools/rust-analyzer/crates/tt/src/iter.rs | 32 +-- src/tools/rust-analyzer/crates/tt/src/lib.rs | 185 +++++++++++++++--- 24 files changed, 350 insertions(+), 293 deletions(-) diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs index 2f1fc8ae49e9..c5da8443a68f 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs @@ -197,17 +197,18 @@ fn next_cfg_expr(it: &mut tt::iter::TtIter<'_>) -> Option { Some(_) => return Some(CfgExpr::Invalid), }; - let ret = match it.peek() { + let mut it_clone = it.clone(); + let ret = match it_clone.next() { Some(TtElement::Leaf(tt::Leaf::Punct(punct))) // Don't consume on e.g. `=>`. if punct.char == '=' && (punct.spacing == tt::Spacing::Alone - || it.remaining().flat_tokens().get(1).is_none_or(|peek2| { - !matches!(peek2, tt::TokenTree::Leaf(tt::Leaf::Punct(_))) + || it_clone.peek().is_none_or(|peek2| { + !matches!(peek2, tt::TtElement::Leaf(tt::Leaf::Punct(_))) })) => { - match it.remaining().flat_tokens().get(1) { - Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => { + match it_clone.next() { + Some(tt::TtElement::Leaf(tt::Leaf::Literal(literal))) => { it.next(); it.next(); CfgAtom::KeyValue { key: name, value: literal.symbol.clone() }.into() diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs index 1cbd2c10b5a1..062b55fcefdf 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs @@ -114,7 +114,7 @@ pub(super) fn attr_macro_as_call_id( let arg = match macro_attr.input.as_deref() { Some(AttrInput::TokenTree(tt)) => { let mut tt = tt.clone(); - tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Invisible; + tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); Some(tt) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index a7f687a3168b..822da678d797 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -2466,8 +2466,8 @@ impl ModCollector<'_, '_> { None => { let explicit_name = attrs.by_key(sym::rustc_builtin_macro).tt_values().next().and_then(|tt| { - match tt.token_trees().flat_tokens().first() { - Some(tt::TokenTree::Leaf(tt::Leaf::Ident(name))) => Some(name), + match tt.token_trees().iter().next() { + Some(tt::TtElement::Leaf(tt::Leaf::Ident(name))) => Some(name), _ => None, } }); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs index cd45afe57d7c..91d664938bf2 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/proc_macro.rs @@ -2,10 +2,11 @@ use hir_expand::name::{AsName, Name}; use intern::sym; +use itertools::Itertools; use crate::{ item_tree::Attrs, - tt::{Leaf, TokenTree, TopSubtree, TtElement}, + tt::{Leaf, TopSubtree, TtElement}, }; #[derive(Debug, PartialEq, Eq)] @@ -61,35 +62,35 @@ impl Attrs<'_> { // This fn is intended for `#[proc_macro_derive(..)]` and `#[rustc_builtin_macro(..)]`, which have // the same structure. -#[rustfmt::skip] pub(crate) fn parse_macro_name_and_helper_attrs(tt: &TopSubtree) -> Option<(Name, Box<[Name]>)> { - match tt.token_trees().flat_tokens() { + if let Some([TtElement::Leaf(Leaf::Ident(trait_name))]) = + tt.token_trees().iter().collect_array() + { // `#[proc_macro_derive(Trait)]` // `#[rustc_builtin_macro(Trait)]` - [TokenTree::Leaf(Leaf::Ident(trait_name))] => Some((trait_name.as_name(), Box::new([]))), - + Some((trait_name.as_name(), Box::new([]))) + } else if let Some( + [ + TtElement::Leaf(Leaf::Ident(trait_name)), + TtElement::Leaf(Leaf::Punct(comma)), + TtElement::Leaf(Leaf::Ident(attributes)), + TtElement::Subtree(_, helpers), + ], + ) = tt.token_trees().iter().collect_array() + && comma.char == ',' + && attributes.sym == sym::attributes + { // `#[proc_macro_derive(Trait, attributes(helper1, helper2, ...))]` // `#[rustc_builtin_macro(Trait, attributes(helper1, helper2, ...))]` - [ - TokenTree::Leaf(Leaf::Ident(trait_name)), - TokenTree::Leaf(Leaf::Punct(comma)), - TokenTree::Leaf(Leaf::Ident(attributes)), - TokenTree::Subtree(_), - .. - ] if comma.char == ',' && attributes.sym == sym::attributes => - { - let helpers = tt::TokenTreesView::new(&tt.token_trees().flat_tokens()[3..]).try_into_subtree()?; - let helpers = helpers - .iter() - .filter_map(|tt| match tt { - TtElement::Leaf(Leaf::Ident(helper)) => Some(helper.as_name()), - _ => None, - }) - .collect::>(); + let helpers = helpers + .filter_map(|tt| match tt { + TtElement::Leaf(Leaf::Ident(helper)) => Some(helper.as_name()), + _ => None, + }) + .collect::>(); - Some((trait_name.as_name(), helpers)) - } - - _ => None, + Some((trait_name.as_name(), helpers)) + } else { + None } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index e1807cd2e1e9..5a440187203c 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -36,6 +36,7 @@ use base_db::Crate; use cfg::{CfgExpr, CfgOptions}; use either::Either; use intern::{Interned, Symbol}; +use itertools::Itertools; use mbe::{DelimiterKind, Punct}; use parser::T; use smallvec::SmallVec; @@ -453,10 +454,10 @@ impl Attr { } /// #[path(ident)] - pub fn single_ident_value(&self) -> Option<&tt::Ident> { + pub fn single_ident_value(&self) -> Option { match self.input.as_deref()? { - AttrInput::TokenTree(tt) => match tt.token_trees().flat_tokens() { - [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] => Some(ident), + AttrInput::TokenTree(tt) => match tt.token_trees().iter().collect_array() { + Some([tt::TtElement::Leaf(tt::Leaf::Ident(ident))]) => Some(ident), _ => None, }, _ => None, @@ -492,7 +493,7 @@ fn parse_path_comma_token_tree<'a>( args.token_trees() .split(|tt| matches!(tt, tt::TtElement::Leaf(tt::Leaf::Punct(Punct { char: ',', .. })))) .filter_map(move |tts| { - let span = tts.flat_tokens().first()?.first_span(); + let span = tts.first_span()?; Some((ModPath::from_tt(db, tts)?, span, tts)) }) } @@ -611,16 +612,12 @@ impl AttrId { else { return derive_attr_range; }; - let (Some(first_tt), Some(last_tt)) = - (derive_tts.flat_tokens().first(), derive_tts.flat_tokens().last()) + let (Some(first_span), Some(last_span)) = (derive_tts.first_span(), derive_tts.last_span()) else { return derive_attr_range; }; - let start = first_tt.first_span().range.start(); - let end = match last_tt { - tt::TokenTree::Leaf(it) => it.span().range.end(), - tt::TokenTree::Subtree(it) => it.delimiter.close.range.end(), - }; + let start = first_span.range.start(); + let end = last_span.range.end(); TextRange::new(start, end) } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 3d630cfc1c8e..011a9530c4d3 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -210,7 +210,7 @@ fn stringify_expand( tt: &tt::TopSubtree, span: Span, ) -> ExpandResult { - let pretty = ::tt::pretty(tt.token_trees().flat_tokens()); + let pretty = ::tt::pretty(tt.token_trees()); let expanded = quote! {span => #pretty @@ -283,7 +283,7 @@ fn format_args_expand( ) -> ExpandResult { let pound = mk_pound(span); let mut tt = tt.clone(); - tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Parenthesis; + tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Parenthesis); ExpandResult::ok(quote! {span => builtin #pound format_args #tt }) @@ -297,14 +297,14 @@ fn format_args_nl_expand( ) -> ExpandResult { let pound = mk_pound(span); let mut tt = tt.clone(); - tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Parenthesis; - if let Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, - kind: tt::LitKind::Str, - .. - }))) = tt.0.get_mut(1) + tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Parenthesis); + let lit = tt.as_token_trees().iter_flat_tokens().nth(1); + if let Some(tt::TokenTree::Leaf(tt::Leaf::Literal( + mut lit @ tt::Literal { kind: tt::LitKind::Str, .. }, + ))) = lit { - *text = Symbol::intern(&format_smolstr!("{}\\n", text.as_str())); + lit.symbol = Symbol::intern(&format_smolstr!("{}\\n", lit.symbol.as_str())); + tt.set_token(1, lit.into()); } ExpandResult::ok(quote! {span => builtin #pound format_args #tt @@ -318,7 +318,7 @@ fn asm_expand( span: Span, ) -> ExpandResult { let mut tt = tt.clone(); - tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Parenthesis; + tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Parenthesis); let pound = mk_pound(span); let expanded = quote! {span => builtin #pound asm #tt @@ -333,7 +333,7 @@ fn global_asm_expand( span: Span, ) -> ExpandResult { let mut tt = tt.clone(); - tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Parenthesis; + tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Parenthesis); let pound = mk_pound(span); let expanded = quote! {span => builtin #pound global_asm #tt @@ -348,7 +348,7 @@ fn naked_asm_expand( span: Span, ) -> ExpandResult { let mut tt = tt.clone(); - tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Parenthesis; + tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Parenthesis); let pound = mk_pound(span); let expanded = quote! {span => builtin #pound naked_asm #tt @@ -478,11 +478,11 @@ fn unreachable_expand( // Pass the original arguments let mut subtree = tt.clone(); - *subtree.top_subtree_delimiter_mut() = tt::Delimiter { + subtree.set_top_subtree_delimiter_kind(tt::DelimiterKind::Parenthesis); + subtree.set_top_subtree_delimiter_span(tt::DelimSpan { open: call_site_span, close: call_site_span, - kind: tt::DelimiterKind::Parenthesis, - }; + }); // Expand to a macro call `$crate::panic::panic_{edition}` let call = quote!(call_site_span =>#dollar_crate::panic::#mac! #subtree); @@ -518,16 +518,17 @@ fn compile_error_expand( tt: &tt::TopSubtree, span: Span, ) -> ExpandResult { - let err = match &*tt.0 { - [ - _, - tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, - span: _, - kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), - suffix: _, - })), - ] => ExpandError::other(span, Box::from(unescape_symbol(text).as_str())), + let err = match tt.iter().collect_array() { + Some( + [ + tt::TtElement::Leaf(tt::Leaf::Literal(tt::Literal { + symbol: text, + span: _, + kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), + suffix: _, + })), + ], + ) => ExpandError::other(span, Box::from(unescape_symbol(&text).as_str())), _ => ExpandError::other(span, "`compile_error!` argument must be a string"), }; @@ -556,7 +557,7 @@ fn concat_expand( // to ensure the right parsing order, so skip the parentheses here. Ideally we'd // implement rustc's model. cc https://github.com/rust-lang/rust-analyzer/pull/10623 if let TtElement::Subtree(subtree, subtree_iter) = &t - && let [tt::TokenTree::Leaf(tt)] = subtree_iter.remaining().flat_tokens() + && let Some([tt::TtElement::Leaf(tt)]) = subtree_iter.clone().collect_array() && subtree.delimiter.kind == tt::DelimiterKind::Parenthesis { t = TtElement::Leaf(tt); @@ -663,7 +664,7 @@ fn concat_bytes_expand( kind, suffix: _, })) => { - record_span(*span); + record_span(span); match kind { tt::LitKind::Byte => { if let Ok(b) = unescape_byte(text.as_str()) { @@ -679,7 +680,7 @@ fn concat_bytes_expand( bytes.extend(text.as_str().escape_debug()); } _ => { - err.get_or_insert(ExpandError::other(*span, "unexpected token")); + err.get_or_insert(ExpandError::other(span, "unexpected token")); break; } } @@ -733,7 +734,7 @@ fn concat_bytes_expand_subtree( if let Ok(b) = unescape_byte(text.as_str()) { bytes.extend(b.escape_ascii().filter_map(|it| char::from_u32(it as u32))); } - record_span(*span); + record_span(span); } TtElement::Leaf(tt::Leaf::Literal(tt::Literal { symbol: text, @@ -741,7 +742,7 @@ fn concat_bytes_expand_subtree( kind: tt::LitKind::Integer, suffix: _, })) => { - record_span(*span); + record_span(span); if let Ok(b) = text.as_str().parse::() { bytes.extend(b.escape_ascii().filter_map(|it| char::from_u32(it as u32))); } @@ -796,13 +797,13 @@ fn parse_string(tt: &tt::TopSubtree) -> Result<(Symbol, Span), ExpandError> { span, kind: tt::LitKind::Str, suffix: _, - })) => Ok((unescape_symbol(text), *span)), + })) => Ok((unescape_symbol(&text), span)), TtElement::Leaf(tt::Leaf::Literal(tt::Literal { symbol: text, span, kind: tt::LitKind::StrRaw(_), suffix: _, - })) => Ok((text.clone(), *span)), + })) => Ok((text.clone(), span)), TtElement::Leaf(l) => Err(*l.span()), TtElement::Subtree(tt, _) => Err(tt.delimiter.open.cover(tt.delimiter.close)), } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs index b1d46f5c4e76..4039b6c334ec 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs @@ -163,7 +163,7 @@ impl ToTokenTree for crate::tt::SubtreeView<'_> { impl ToTokenTree for crate::tt::TopSubtree { fn to_tokens(self, _: Span, builder: &mut TopSubtreeBuilder) { - builder.extend_tt_dangerous(self.0); + builder.extend_with_tt(self.as_token_trees()); } } @@ -172,10 +172,9 @@ impl ToTokenTree for crate::tt::TtElement<'_> { match self { crate::tt::TtElement::Leaf(leaf) => builder.push(leaf.clone()), crate::tt::TtElement::Subtree(subtree, subtree_iter) => { - builder.extend_tt_dangerous( - std::iter::once(crate::tt::TokenTree::Subtree(subtree.clone())) - .chain(subtree_iter.remaining().flat_tokens().iter().cloned()), - ); + builder.open(subtree.delimiter.kind, subtree.delimiter.open); + builder.extend_with_tt(subtree_iter.remaining()); + builder.close(subtree.delimiter.close); } } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 5c517e671be4..40d44cd1dba2 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -237,7 +237,8 @@ pub fn expand_speculative( span, DocCommentDesugarMode::ProcMacro, ); - *tree.top_subtree_delimiter_mut() = tt::Delimiter::invisible_spanned(span); + tree.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); + tree.set_top_subtree_delimiter_span(tt::DelimSpan::from_single(span)); tree }, ) @@ -255,7 +256,7 @@ pub fn expand_speculative( span, DocCommentDesugarMode::ProcMacro, ); - attr_arg.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Invisible; + attr_arg.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); Some(attr_arg) } _ => None, @@ -270,7 +271,8 @@ pub fn expand_speculative( let mut speculative_expansion = match loc.def.kind { MacroDefKind::ProcMacro(ast, expander, _) => { let span = db.proc_macro_span(ast); - *tt.top_subtree_delimiter_mut() = tt::Delimiter::invisible_spanned(span); + tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); + tt.set_top_subtree_delimiter_span(tt::DelimSpan::from_single(span)); expander.expand( db, loc.def.krate, @@ -430,7 +432,7 @@ fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult { ( Arc::new(tt::TopSubtree::from_token_trees( tt::Delimiter { open: span, close: span, kind }, - tt::TokenTreesView::new(&[]), + tt::TokenTreesView::empty(), )), SyntaxFixupUndoInfo::default(), span, @@ -478,7 +480,7 @@ fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult { ); if loc.def.is_proc_macro() { // proc macros expect their inputs without parentheses, MBEs expect it with them included - tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Invisible; + tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); } return (Arc::new(tt), SyntaxFixupUndoInfo::NONE, span); } @@ -512,7 +514,7 @@ fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult { if loc.def.is_proc_macro() { // proc macros expect their inputs without parentheses, MBEs expect it with them included - tt.top_subtree_delimiter_mut().kind = tt::DelimiterKind::Invisible; + tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); } (Arc::new(tt), undo_info, span) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs index 9b65bdac65c0..0b6124ebf359 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs @@ -96,7 +96,7 @@ pub fn expand_eager_macro_input( DocCommentDesugarMode::Mbe, ); - subtree.top_subtree_delimiter_mut().kind = crate::tt::DelimiterKind::Invisible; + subtree.set_top_subtree_delimiter_kind(crate::tt::DelimiterKind::Invisible); let loc = MacroCallLoc { def, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs index 876d87093663..6afc6e5d5e7f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs @@ -15,7 +15,7 @@ use syntax::{ }; use syntax_bridge::DocCommentDesugarMode; use triomphe::Arc; -use tt::Spacing; +use tt::{Spacing, TransformTtAction, transform_tt}; use crate::{ span_map::SpanMapRef, @@ -343,93 +343,29 @@ fn has_error_to_handle(node: &SyntaxNode) -> bool { pub(crate) fn reverse_fixups(tt: &mut TopSubtree, undo_info: &SyntaxFixupUndoInfo) { let Some(undo_info) = undo_info.original.as_deref() else { return }; let undo_info = &**undo_info; - let delimiter = tt.top_subtree_delimiter_mut(); + let top_subtree = tt.top_subtree(); + let open_span = top_subtree.delimiter.open; + let close_span = top_subtree.delimiter.close; #[allow(deprecated)] if never!( - delimiter.close.anchor.ast_id == FIXUP_DUMMY_AST_ID - || delimiter.open.anchor.ast_id == FIXUP_DUMMY_AST_ID + close_span.anchor.ast_id == FIXUP_DUMMY_AST_ID + || open_span.anchor.ast_id == FIXUP_DUMMY_AST_ID ) { let span = |file_id| Span { range: TextRange::empty(TextSize::new(0)), anchor: SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID }, ctx: SyntaxContext::root(span::Edition::Edition2015), }; - delimiter.open = span(delimiter.open.anchor.file_id); - delimiter.close = span(delimiter.close.anchor.file_id); + tt.set_top_subtree_delimiter_span(tt::DelimSpan { + open: span(open_span.anchor.file_id), + close: span(close_span.anchor.file_id), + }); } reverse_fixups_(tt, undo_info); } -#[derive(Debug)] -enum TransformTtAction<'a> { - Keep, - ReplaceWith(tt::TokenTreesView<'a>), -} - -impl TransformTtAction<'_> { - fn remove() -> Self { - Self::ReplaceWith(tt::TokenTreesView::new(&[])) - } -} - -/// This function takes a token tree, and calls `callback` with each token tree in it. -/// Then it does what the callback says: keeps the tt or replaces it with a (possibly empty) -/// tts view. -fn transform_tt<'a, 'b>( - tt: &'a mut Vec, - mut callback: impl FnMut(&mut tt::TokenTree) -> TransformTtAction<'b>, -) { - // We need to keep a stack of the currently open subtrees, because we need to update - // them if we change the number of items in them. - let mut subtrees_stack = Vec::new(); - let mut i = 0; - while i < tt.len() { - 'pop_finished_subtrees: while let Some(&subtree_idx) = subtrees_stack.last() { - let tt::TokenTree::Subtree(subtree) = &tt[subtree_idx] else { - unreachable!("non-subtree on subtrees stack"); - }; - if i >= subtree_idx + 1 + subtree.usize_len() { - subtrees_stack.pop(); - } else { - break 'pop_finished_subtrees; - } - } - - let action = callback(&mut tt[i]); - match action { - TransformTtAction::Keep => { - // This cannot be shared with the replaced case, because then we may push the same subtree - // twice, and will update it twice which will lead to errors. - if let tt::TokenTree::Subtree(_) = &tt[i] { - subtrees_stack.push(i); - } - - i += 1; - } - TransformTtAction::ReplaceWith(replacement) => { - let old_len = 1 + match &tt[i] { - tt::TokenTree::Leaf(_) => 0, - tt::TokenTree::Subtree(subtree) => subtree.usize_len(), - }; - let len_diff = replacement.len() as i64 - old_len as i64; - tt.splice(i..i + old_len, replacement.flat_tokens().iter().cloned()); - // Skip the newly inserted replacement, we don't want to visit it. - i += replacement.len(); - - for &subtree_idx in &subtrees_stack { - let tt::TokenTree::Subtree(subtree) = &mut tt[subtree_idx] else { - unreachable!("non-subtree on subtrees stack"); - }; - subtree.len = (i64::from(subtree.len) + len_diff).try_into().unwrap(); - } - } - } - } -} - fn reverse_fixups_(tt: &mut TopSubtree, undo_info: &[TopSubtree]) { - let mut tts = std::mem::take(&mut tt.0).into_vec(); - transform_tt(&mut tts, |tt| match tt { + transform_tt(tt, |tt| match tt { tt::TokenTree::Leaf(leaf) => { let span = leaf.span(); let is_real_leaf = span.anchor.ast_id != FIXUP_DUMMY_AST_ID; @@ -459,7 +395,6 @@ fn reverse_fixups_(tt: &mut TopSubtree, undo_info: &[TopSubtree]) { TransformTtAction::Keep } }); - tt.0 = tts.into_boxed_slice(); } #[cfg(test)] @@ -488,9 +423,9 @@ mod tests { } fn check_subtree_eq(a: &tt::TopSubtree, b: &tt::TopSubtree) -> bool { - let a = a.view().as_token_trees().flat_tokens(); - let b = b.view().as_token_trees().flat_tokens(); - a.len() == b.len() && std::iter::zip(a, b).all(|(a, b)| check_tt_eq(a, b)) + let a = a.view().as_token_trees().iter_flat_tokens(); + let b = b.view().as_token_trees().iter_flat_tokens(); + a.len() == b.len() && std::iter::zip(a, b).all(|(a, b)| check_tt_eq(&a, &b)) } fn check_tt_eq(a: &tt::TokenTree, b: &tt::TokenTree) -> bool { @@ -545,7 +480,7 @@ mod tests { // the fixed-up tree should not contain braces as punct // FIXME: should probably instead check that it's a valid punctuation character - for x in tt.token_trees().flat_tokens() { + for x in tt.token_trees().iter_flat_tokens() { match x { ::tt::TokenTree::Leaf(::tt::Leaf::Punct(punct)) => { assert!(!matches!(punct.char, '{' | '}' | '(' | ')' | '[' | ']')) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index e9805e3f86b8..51e449fe5085 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -355,16 +355,16 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: tt::TokenTreesView<'_>) -> Optio tt::Leaf::Punct(tt::Punct { char: ':', .. }) => PathKind::Abs, _ => return None, }, - tt::Leaf::Ident(tt::Ident { sym: text, span, .. }) if *text == sym::dollar_crate => { + tt::Leaf::Ident(tt::Ident { sym: text, span, .. }) if text == sym::dollar_crate => { resolve_crate_root(db, span.ctx).map(PathKind::DollarCrate).unwrap_or(PathKind::Crate) } - tt::Leaf::Ident(tt::Ident { sym: text, .. }) if *text == sym::self_ => PathKind::SELF, - tt::Leaf::Ident(tt::Ident { sym: text, .. }) if *text == sym::super_ => { + tt::Leaf::Ident(tt::Ident { sym: text, .. }) if text == sym::self_ => PathKind::SELF, + tt::Leaf::Ident(tt::Ident { sym: text, .. }) if text == sym::super_ => { let mut deg = 1; while let Some(tt::Leaf::Ident(tt::Ident { sym: text, span, is_raw: _ })) = leaves.next() { - if *text != sym::super_ { + if text != sym::super_ { segments.push(Name::new_symbol(text.clone(), span.ctx)); break; } @@ -372,7 +372,7 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: tt::TokenTreesView<'_>) -> Optio } PathKind::Super(deg) } - tt::Leaf::Ident(tt::Ident { sym: text, .. }) if *text == sym::crate_ => PathKind::Crate, + tt::Leaf::Ident(tt::Ident { sym: text, .. }) if text == sym::crate_ => PathKind::Crate, tt::Leaf::Ident(ident) => { segments.push(Name::new_symbol(ident.sym.clone(), ident.span.ctx)); PathKind::Plain diff --git a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs index e0f1e616d851..6b018510be14 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs @@ -54,7 +54,7 @@ fn benchmark_expand_macro_rules() { .map(|(id, tt)| { let res = rules[&id].expand(&db, &tt, |_| (), MacroCallStyle::FnLike, DUMMY); assert!(res.err.is_none()); - res.value.0.0.len() + res.value.0.as_token_trees().len() }) .sum() }; diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander.rs b/src/tools/rust-analyzer/crates/mbe/src/expander.rs index 36c7871519aa..25e05df7b710 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander.rs @@ -162,7 +162,7 @@ impl Fragment<'_> { Fragment::Tokens { tree, .. } => tree.len() == 0, Fragment::Expr(it) => it.len() == 0, Fragment::Path(it) => it.len() == 0, - Fragment::TokensOwned(it) => it.0.is_empty(), + Fragment::TokensOwned(_) => false, // A `TopSubtree` is never empty } } } diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs index c4c1e1f5654f..e845b1ab8d1f 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs @@ -517,7 +517,7 @@ fn match_loop_inner<'t>( } OpDelimited::Op(Op::Literal(lhs)) => { if let Ok(rhs) = src.clone().expect_leaf() { - if matches!(rhs, tt::Leaf::Literal(it) if it.symbol == lhs.symbol) { + if matches!(&rhs, tt::Leaf::Literal(it) if it.symbol == lhs.symbol) { item.dot.next(); } else { res.add_err(ExpandError::new( @@ -537,7 +537,7 @@ fn match_loop_inner<'t>( } OpDelimited::Op(Op::Ident(lhs)) => { if let Ok(rhs) = src.clone().expect_leaf() { - if matches!(rhs, tt::Leaf::Ident(it) if it.sym == lhs.sym) { + if matches!(&rhs, tt::Leaf::Ident(it) if it.sym == lhs.sym) { item.dot.next(); } else { res.add_err(ExpandError::new( @@ -701,7 +701,7 @@ fn match_loop<'t>( || !(bb_items.is_empty() || next_items.is_empty()) || bb_items.len() > 1; if has_leftover_tokens { - res.unmatched_tts += src.remaining().flat_tokens().len(); + res.unmatched_tts += src.remaining().len(); res.add_err(ExpandError::new(span.open, ExpandErrorKind::LeftoverTokens)); if let Some(error_recover_item) = error_recover_item { @@ -991,7 +991,7 @@ fn expect_tt(iter: &mut TtIter<'_>) -> Result<(), ()> { Ok(()) } -fn expect_lifetime<'a>(iter: &mut TtIter<'a>) -> Result<&'a tt::Ident, ()> { +fn expect_lifetime<'a>(iter: &mut TtIter<'a>) -> Result { let punct = iter.expect_single_punct()?; if punct.char != '\'' { return Err(()); @@ -1000,7 +1000,7 @@ fn expect_lifetime<'a>(iter: &mut TtIter<'a>) -> Result<&'a tt::Ident, ()> { } fn eat_char(iter: &mut TtIter<'_>, c: char) { - if matches!(iter.peek(), Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char, .. }))) if *char == c) + if matches!(iter.peek(), Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char, .. }))) if char == c) { iter.next().expect("already peeked"); } diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs index a0fd4550ba8c..38098e2c84da 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs @@ -3,6 +3,7 @@ use intern::{Symbol, sym}; use span::{Edition, Span}; +use stdx::itertools::Itertools; use tt::{Delimiter, TopSubtreeBuilder, iter::TtElement}; use super::TokensOrigin; @@ -324,7 +325,7 @@ fn expand_subtree( } _ => (None, None), }; - let value = match values { + let value = match &values { (Some(TtElement::Leaf(tt::Leaf::Ident(ident))), None) => { ident.sym.as_str() } @@ -412,15 +413,15 @@ fn expand_var( // Check if this is a simple negative literal (MINUS + LITERAL) // that should not be wrapped in parentheses let is_negative_literal = matches!( - sub.flat_tokens(), - [ - tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '-', .. })), - tt::TokenTree::Leaf(tt::Leaf::Literal(_)) - ] + sub.iter().collect_array(), + Some([ + tt::TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char: '-', .. })), + tt::TtElement::Leaf(tt::Leaf::Literal(_)) + ]) ); let wrap_in_parens = !is_negative_literal - && !matches!(sub.flat_tokens(), [tt::TokenTree::Leaf(_)]) + && !matches!(sub.iter().collect_array(), Some([tt::TtElement::Leaf(_)])) && sub.try_into_subtree().is_none_or(|it| { it.top_subtree().delimiter.kind == tt::DelimiterKind::Invisible }); @@ -560,8 +561,8 @@ fn fix_up_and_push_path_tt( // argument list and thus needs `::` between it and `FnOnce`. However in // today's Rust this type of path *semantically* cannot appear as a // top-level expression-context path, so we can safely ignore it. - if let [tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '<', .. }))] = - tt.flat_tokens() + if let Some([tt::TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char: '<', .. }))]) = + tt.iter().collect_array() { builder.extend([ tt::Leaf::Punct(tt::Punct { @@ -577,7 +578,8 @@ fn fix_up_and_push_path_tt( ]); } } - prev_was_ident = matches!(tt.flat_tokens(), [tt::TokenTree::Leaf(tt::Leaf::Ident(_))]); + prev_was_ident = + matches!(tt.iter().collect_array(), Some([tt::TtElement::Leaf(tt::Leaf::Ident(_))])); builder.extend_with_tt(tt); } } diff --git a/src/tools/rust-analyzer/crates/mbe/src/parser.rs b/src/tools/rust-analyzer/crates/mbe/src/parser.rs index ddf9afbf98ab..cecdd43a42a1 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/parser.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/parser.rs @@ -224,7 +224,7 @@ fn next_op( None => { return Ok(Op::Punct({ let mut res = ArrayVec::new(); - res.push(*p); + res.push(p); Box::new(res) })); } @@ -268,7 +268,7 @@ fn next_op( let id = ident.span; Op::Var { name, kind, id } } - tt::Leaf::Literal(lit) if is_boolean_literal(lit) => { + tt::Leaf::Literal(lit) if is_boolean_literal(&lit) => { let kind = eat_fragment_kind(edition, src, mode)?; let name = lit.symbol.clone(); let id = lit.span; @@ -282,7 +282,7 @@ fn next_op( } Mode::Template => Op::Punct({ let mut res = ArrayVec::new(); - res.push(*punct); + res.push(punct); Box::new(res) }), }, @@ -400,7 +400,7 @@ fn parse_repeat(src: &mut TtIter<'_>) -> Result<(Option, RepeatKind), '?' => RepeatKind::ZeroOrOne, _ => match &mut separator { Separator::Puncts(puncts) if puncts.len() < 3 => { - puncts.push(*punct); + puncts.push(punct); continue; } _ => return Err(ParseError::InvalidRepeat), diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs index 8c96b06700a9..ed4b7aff76fc 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs @@ -489,7 +489,7 @@ struct Writer<'a, 'span, S: SpanTransformer, W> { impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIter<'a>> { fn write_subtree(&mut self, root: tt::SubtreeView<'a>) { let subtree = root.top_subtree(); - self.enqueue(subtree, root.iter()); + self.enqueue(&subtree, root.iter()); while let Some((idx, len, subtree)) = self.work.pop_front() { self.subtree(idx, len, subtree); } @@ -504,7 +504,7 @@ impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIt for child in subtree { let idx_tag = match child { tt::iter::TtElement::Subtree(subtree, subtree_iter) => { - let idx = self.enqueue(subtree, subtree_iter); + let idx = self.enqueue(&subtree, subtree_iter); idx << 2 } tt::iter::TtElement::Leaf(leaf) => match leaf { @@ -513,8 +513,11 @@ impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIt let id = self.token_id_of(lit.span); let (text, suffix) = if self.version >= EXTENDED_LEAF_DATA { ( - self.intern(lit.symbol.as_str()), - lit.suffix.as_ref().map(|s| self.intern(s.as_str())).unwrap_or(!0), + self.intern_owned(lit.symbol.as_str().to_owned()), + lit.suffix + .as_ref() + .map(|s| self.intern_owned(s.as_str().to_owned())) + .unwrap_or(!0), ) } else { (self.intern_owned(format!("{lit}")), !0) @@ -549,11 +552,11 @@ impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIt let idx = self.ident.len() as u32; let id = self.token_id_of(ident.span); let text = if self.version >= EXTENDED_LEAF_DATA { - self.intern(ident.sym.as_str()) + self.intern_owned(ident.sym.as_str().to_owned()) } else if ident.is_raw.yes() { self.intern_owned(format!("r#{}", ident.sym.as_str(),)) } else { - self.intern(ident.sym.as_str()) + self.intern_owned(ident.sym.as_str().to_owned()) }; self.ident.push(IdentRepr { id, text, is_raw: ident.is_raw.yes() }); (idx << 2) | 0b11 @@ -565,7 +568,7 @@ impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIt } } - fn enqueue(&mut self, subtree: &'a tt::Subtree, contents: tt::iter::TtIter<'a>) -> u32 { + fn enqueue(&mut self, subtree: &tt::Subtree, contents: tt::iter::TtIter<'a>) -> u32 { let idx = self.subtree.len(); let open = self.token_id_of(subtree.delimiter.open); let close = self.token_id_of(subtree.delimiter.close); @@ -582,6 +585,7 @@ impl<'a, T: SpanTransformer, U> Writer<'a, '_, T, U> { T::token_id_of(self.span_data_table, span) } + #[cfg(feature = "sysroot-abi")] pub(crate) fn intern(&mut self, text: &'a str) -> u32 { let table = &mut self.text; *self.string_table.entry(text.into()).or_insert_with(|| { @@ -840,7 +844,7 @@ impl> Reader<'_, T> { let (delimiter, mut res) = res[0].take().unwrap(); res.insert(0, tt::TokenTree::Subtree(tt::Subtree { delimiter, len: res.len() as u32 })); - tt::TopSubtree(res.into_boxed_slice()) + tt::TopSubtree::from_serialized(res) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index e0d20c82b9e2..f5fcc99f14a3 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -194,28 +194,14 @@ impl ProcMacro { /// On some server versions, the fixup ast id is different than ours. So change it to match. fn change_fixup_to_match_old_server(&self, tt: &mut tt::TopSubtree) { const OLD_FIXUP_AST_ID: ErasedFileAstId = ErasedFileAstId::from_raw(!0 - 1); - let change_ast_id = |ast_id: &mut ErasedFileAstId| { + tt.change_every_ast_id(|ast_id| { if *ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER { *ast_id = OLD_FIXUP_AST_ID; } else if *ast_id == OLD_FIXUP_AST_ID { // Swap between them, that means no collision plus the change can be reversed by doing itself. *ast_id = FIXUP_ERASED_FILE_AST_ID_MARKER; } - }; - - for tt in &mut tt.0 { - match tt { - tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { span, .. })) - | tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { span, .. })) - | tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { span, .. })) => { - change_ast_id(&mut span.anchor.ast_id); - } - tt::TokenTree::Subtree(subtree) => { - change_ast_id(&mut subtree.delimiter.open.anchor.ast_id); - change_ast_id(&mut subtree.delimiter.close.anchor.ast_id); - } - } - } + }); } /// Expands the procedural macro by sending an expansion request to the server. diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs index 82cf51f1627a..79b51a816ebe 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs @@ -223,7 +223,7 @@ where spacing: _, })) => { let found_expected_delimiter = - builder.expected_delimiters().enumerate().find(|(_, delim)| match delim.kind { + builder.expected_delimiters().enumerate().find(|(_, delim)| match delim { tt::DelimiterKind::Parenthesis => char == ')', tt::DelimiterKind::Brace => char == '}', tt::DelimiterKind::Bracket => char == ']', @@ -257,13 +257,11 @@ where } kind if kind.is_punct() && kind != UNDERSCORE => { let found_expected_delimiter = - builder.expected_delimiters().enumerate().find(|(_, delim)| { - match delim.kind { - tt::DelimiterKind::Parenthesis => kind == T![')'], - tt::DelimiterKind::Brace => kind == T!['}'], - tt::DelimiterKind::Bracket => kind == T![']'], - tt::DelimiterKind::Invisible => false, - } + builder.expected_delimiters().enumerate().find(|(_, delim)| match delim { + tt::DelimiterKind::Parenthesis => kind == T![')'], + tt::DelimiterKind::Brace => kind == T!['}'], + tt::DelimiterKind::Bracket => kind == T![']'], + tt::DelimiterKind::Invisible => false, }); // Current token is a closing delimiter that we expect, fix up the closing span diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs index c8dc3131b59c..8c28e1c5aaac 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs @@ -30,7 +30,7 @@ fn check_punct_spacing(fixture: &str) { }) .collect(); - let mut cursor = Cursor::new(&subtree.0); + let mut cursor = Cursor::new(subtree.as_token_trees()); while !cursor.eof() { while let Some(token_tree) = cursor.token_tree() { if let tt::TokenTree::Leaf(Leaf::Punct(Punct { diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 67f69d0fa98e..487171c3e3e8 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -770,7 +770,7 @@ impl ProcMacroExpander for Issue18089ProcMacroExpander { _: Span, _: String, ) -> Result { - let tt::TokenTree::Leaf(macro_name) = &subtree.0[2] else { + let Some(tt::TtElement::Leaf(macro_name)) = subtree.iter().nth(1) else { return Err(ProcMacroExpansionError::Panic("incorrect input".to_owned())); }; Ok(quote! { call_site => @@ -837,13 +837,14 @@ impl ProcMacroExpander for Issue18840ProcMacroExpander { // ``` // The span that was created by the fixup infra. - let fixed_up_span = fn_.token_trees().flat_tokens()[5].first_span(); + let mut iter = fn_.iter(); + iter.nth(2); + let (_, mut fn_body) = iter.expect_subtree().unwrap(); + let fixed_up_span = fn_body.nth(1).unwrap().first_span(); let mut result = quote! {fixed_up_span => ::core::compile_error! { "my cool compile_error!" } }; // Make it so we won't remove the top subtree when reversing fixups. - let top_subtree_delimiter_mut = result.top_subtree_delimiter_mut(); - top_subtree_delimiter_mut.open = def_site; - top_subtree_delimiter_mut.close = def_site; + result.set_top_subtree_delimiter_span(tt::DelimSpan::from_single(def_site)); Ok(result) } @@ -905,13 +906,14 @@ impl ProcMacroExpander for ShortenProcMacroExpander { _: Span, _: String, ) -> Result { - let mut result = input.0.clone(); - for it in &mut result { - if let TokenTree::Leaf(leaf) = it { - modify_leaf(leaf) + let mut result = input.clone(); + for (idx, it) in input.as_token_trees().iter_flat_tokens().enumerate() { + if let TokenTree::Leaf(mut leaf) = it { + modify_leaf(&mut leaf); + result.set_token(idx, leaf); } } - return Ok(tt::TopSubtree(result)); + return Ok(result); fn modify_leaf(leaf: &mut Leaf) { match leaf { @@ -948,7 +950,8 @@ impl ProcMacroExpander for Issue17479ProcMacroExpander { _: Span, _: String, ) -> Result { - let TokenTree::Leaf(Leaf::Literal(lit)) = &subtree.0[1] else { + let mut iter = subtree.iter(); + let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = iter.next() else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); }; let symbol = &lit.symbol; @@ -980,10 +983,8 @@ impl ProcMacroExpander for Issue18898ProcMacroExpander { ) -> Result { let span = subtree .token_trees() - .flat_tokens() - .last() - .ok_or_else(|| ProcMacroExpansionError::Panic("malformed input".to_owned()))? - .first_span(); + .last_span() + .ok_or_else(|| ProcMacroExpansionError::Panic("malformed input".to_owned()))?; let overly_long_subtree = quote! {span => { let a = 5; @@ -1034,7 +1035,7 @@ impl ProcMacroExpander for DisallowCfgProcMacroExpander { _: Span, _: String, ) -> Result { - for tt in subtree.token_trees().flat_tokens() { + for tt in subtree.token_trees().iter_flat_tokens() { if let tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) = tt && (ident.sym == sym::cfg || ident.sym == sym::cfg_attr) { @@ -1066,20 +1067,23 @@ impl ProcMacroExpander for GenerateSuffixedTypeProcMacroExpander { _mixed_site: Span, _current_dir: String, ) -> Result { - let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[1] else { + let mut iter = subtree.iter(); + let Some(TtElement::Leaf(tt::Leaf::Ident(ident))) = iter.next() else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); }; let ident = match ident.sym.as_str() { "struct" => { - let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[2] else { + let Some(TtElement::Leaf(tt::Leaf::Ident(ident))) = iter.next() else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); }; ident } "enum" => { - let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[4] else { + iter.next(); + let (_, mut iter) = iter.expect_subtree().unwrap(); + let Some(TtElement::Leaf(tt::Leaf::Ident(ident))) = iter.next() else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); }; ident diff --git a/src/tools/rust-analyzer/crates/tt/src/buffer.rs b/src/tools/rust-analyzer/crates/tt/src/buffer.rs index c464e5ece194..de6379b5cd14 100644 --- a/src/tools/rust-analyzer/crates/tt/src/buffer.rs +++ b/src/tools/rust-analyzer/crates/tt/src/buffer.rs @@ -10,8 +10,8 @@ pub struct Cursor<'a> { } impl<'a> Cursor<'a> { - pub fn new(buffer: &'a [TokenTree]) -> Self { - Self { buffer, index: 0, subtrees_stack: Vec::new() } + pub fn new(buffer: TokenTreesView<'a>) -> Self { + Self { buffer: buffer.0, index: 0, subtrees_stack: Vec::new() } } /// Check whether it is eof diff --git a/src/tools/rust-analyzer/crates/tt/src/iter.rs b/src/tools/rust-analyzer/crates/tt/src/iter.rs index 88c3c7f52e93..5ab9f94b63fd 100644 --- a/src/tools/rust-analyzer/crates/tt/src/iter.rs +++ b/src/tools/rust-analyzer/crates/tt/src/iter.rs @@ -36,28 +36,28 @@ impl<'a> TtIter<'a> { pub fn expect_char(&mut self, char: char) -> Result<(), ()> { match self.next() { - Some(TtElement::Leaf(&Leaf::Punct(Punct { char: c, .. }))) if c == char => Ok(()), + Some(TtElement::Leaf(Leaf::Punct(Punct { char: c, .. }))) if c == char => Ok(()), _ => Err(()), } } pub fn expect_any_char(&mut self, chars: &[char]) -> Result<(), ()> { match self.next() { - Some(TtElement::Leaf(Leaf::Punct(Punct { char: c, .. }))) if chars.contains(c) => { + Some(TtElement::Leaf(Leaf::Punct(Punct { char: c, .. }))) if chars.contains(&c) => { Ok(()) } _ => Err(()), } } - pub fn expect_subtree(&mut self) -> Result<(&'a Subtree, TtIter<'a>), ()> { + pub fn expect_subtree(&mut self) -> Result<(Subtree, TtIter<'a>), ()> { match self.next() { Some(TtElement::Subtree(subtree, iter)) => Ok((subtree, iter)), _ => Err(()), } } - pub fn expect_leaf(&mut self) -> Result<&'a Leaf, ()> { + pub fn expect_leaf(&mut self) -> Result { match self.next() { Some(TtElement::Leaf(it)) => Ok(it), _ => Err(()), @@ -78,30 +78,30 @@ impl<'a> TtIter<'a> { } } - pub fn expect_ident(&mut self) -> Result<&'a Ident, ()> { + pub fn expect_ident(&mut self) -> Result { match self.expect_leaf()? { Leaf::Ident(it) if it.sym != sym::underscore => Ok(it), _ => Err(()), } } - pub fn expect_ident_or_underscore(&mut self) -> Result<&'a Ident, ()> { + pub fn expect_ident_or_underscore(&mut self) -> Result { match self.expect_leaf()? { Leaf::Ident(it) => Ok(it), _ => Err(()), } } - pub fn expect_literal(&mut self) -> Result<&'a Leaf, ()> { + pub fn expect_literal(&mut self) -> Result { let it = self.expect_leaf()?; - match it { + match &it { Leaf::Literal(_) => Ok(it), Leaf::Ident(ident) if ident.sym == sym::true_ || ident.sym == sym::false_ => Ok(it), _ => Err(()), } } - pub fn expect_single_punct(&mut self) -> Result<&'a Punct, ()> { + pub fn expect_single_punct(&mut self) -> Result { match self.expect_leaf()? { Leaf::Punct(it) => Ok(it), _ => Err(()), @@ -113,7 +113,7 @@ impl<'a> TtIter<'a> { /// This method currently may return a single quotation, which is part of lifetime ident and /// conceptually not a punct in the context of mbe. Callers should handle this. pub fn expect_glued_punct(&mut self) -> Result, ()> { - let TtElement::Leaf(&Leaf::Punct(first)) = self.next().ok_or(())? else { + let TtElement::Leaf(Leaf::Punct(first)) = self.next().ok_or(())? else { return Err(()); }; @@ -168,11 +168,11 @@ impl<'a> TtIter<'a> { pub fn peek(&self) -> Option> { match self.inner.as_slice().first()? { - TokenTree::Leaf(leaf) => Some(TtElement::Leaf(leaf)), + TokenTree::Leaf(leaf) => Some(TtElement::Leaf(leaf.clone())), TokenTree::Subtree(subtree) => { let nested_iter = TtIter { inner: self.inner.as_slice()[1..][..subtree.usize_len()].iter() }; - Some(TtElement::Subtree(subtree, nested_iter)) + Some(TtElement::Subtree(*subtree, nested_iter)) } } } @@ -214,8 +214,8 @@ impl<'a> TtIter<'a> { #[derive(Clone)] pub enum TtElement<'a> { - Leaf(&'a Leaf), - Subtree(&'a Subtree, TtIter<'a>), + Leaf(Leaf), + Subtree(Subtree, TtIter<'a>), } impl fmt::Debug for TtElement<'_> { @@ -243,12 +243,12 @@ impl<'a> Iterator for TtIter<'a> { type Item = TtElement<'a>; fn next(&mut self) -> Option { match self.inner.next()? { - TokenTree::Leaf(leaf) => Some(TtElement::Leaf(leaf)), + TokenTree::Leaf(leaf) => Some(TtElement::Leaf(leaf.clone())), TokenTree::Subtree(subtree) => { let nested_iter = TtIter { inner: self.inner.as_slice()[..subtree.usize_len()].iter() }; self.inner = self.inner.as_slice()[subtree.usize_len()..].iter(); - Some(TtElement::Subtree(subtree, nested_iter)) + Some(TtElement::Subtree(*subtree, nested_iter)) } } } diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 636f567f1aa7..97e0b34ad7b7 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -111,7 +111,7 @@ impl Leaf { } impl_from!(Literal, Punct, Ident for Leaf); -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Subtree { pub delimiter: Delimiter, /// Number of following token trees that belong to this subtree, excluding this subtree. @@ -125,7 +125,7 @@ impl Subtree { } #[derive(Clone, PartialEq, Eq, Hash)] -pub struct TopSubtree(pub Box<[TokenTree]>); +pub struct TopSubtree(Box<[TokenTree]>); impl TopSubtree { pub fn empty(span: DelimSpan) -> Self { @@ -147,6 +147,10 @@ impl TopSubtree { builder.build() } + pub fn from_serialized(tt: Vec) -> Self { + Self(tt.into_boxed_slice()) + } + pub fn from_subtree(subtree: SubtreeView<'_>) -> Self { Self(subtree.0.into()) } @@ -159,20 +163,55 @@ impl TopSubtree { self.view().iter() } - pub fn top_subtree(&self) -> &Subtree { + pub fn top_subtree(&self) -> Subtree { self.view().top_subtree() } - pub fn top_subtree_delimiter_mut(&mut self) -> &mut Delimiter { + pub fn set_top_subtree_delimiter_kind(&mut self, kind: DelimiterKind) { + self.top_subtree_mut().delimiter.kind = kind; + } + + pub fn set_top_subtree_delimiter_span(&mut self, span: DelimSpan) { + let top_subtree = self.top_subtree_mut(); + top_subtree.delimiter.open = span.open; + top_subtree.delimiter.close = span.close; + } + + fn top_subtree_mut(&mut self) -> &mut Subtree { let TokenTree::Subtree(subtree) = &mut self.0[0] else { unreachable!("the first token tree is always the top subtree"); }; - &mut subtree.delimiter + subtree + } + + pub fn set_token(&mut self, idx: usize, leaf: Leaf) { + assert!(matches!(self.0[idx], TokenTree::Leaf(_)), "cannot replace a subtree by a leaf"); + self.0[idx] = leaf.into(); } pub fn token_trees(&self) -> TokenTreesView<'_> { self.view().token_trees() } + + pub fn as_token_trees(&self) -> TokenTreesView<'_> { + self.view().as_token_trees() + } + + pub fn change_every_ast_id(&mut self, mut callback: impl FnMut(&mut span::ErasedFileAstId)) { + for tt in &mut self.0 { + match tt { + TokenTree::Leaf(Leaf::Ident(Ident { span, .. })) + | TokenTree::Leaf(Leaf::Literal(Literal { span, .. })) + | TokenTree::Leaf(Leaf::Punct(Punct { span, .. })) => { + callback(&mut span.anchor.ast_id); + } + TokenTree::Subtree(subtree) => { + callback(&mut subtree.delimiter.open.anchor.ast_id); + callback(&mut subtree.delimiter.close.anchor.ast_id); + } + } + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -241,11 +280,6 @@ impl TopSubtreeBuilder { self.token_trees.extend(leaves.into_iter().map(TokenTree::Leaf)); } - /// This does not check the token trees are valid, beware! - pub fn extend_tt_dangerous(&mut self, tt: impl IntoIterator) { - self.token_trees.extend(tt); - } - pub fn extend_with_tt(&mut self, tt: TokenTreesView<'_>) { self.token_trees.extend(tt.0.iter().cloned()); } @@ -267,12 +301,12 @@ impl TopSubtreeBuilder { } } - pub fn expected_delimiters(&self) -> impl Iterator { + pub fn expected_delimiters(&self) -> impl Iterator { self.unclosed_subtree_indices.iter().rev().map(|&subtree_idx| { let TokenTree::Subtree(subtree) = &self.token_trees[subtree_idx] else { unreachable!("unclosed token tree is always a subtree") }; - &subtree.delimiter + subtree.delimiter.kind }) } @@ -330,7 +364,7 @@ pub struct SubtreeBuilderRestorePoint { pub struct TokenTreesView<'a>(&'a [TokenTree]); impl<'a> TokenTreesView<'a> { - pub fn new(tts: &'a [TokenTree]) -> Self { + fn new(tts: &'a [TokenTree]) -> Self { if cfg!(debug_assertions) { tts.iter().enumerate().for_each(|(idx, tt)| { if let TokenTree::Subtree(tt) = &tt { @@ -345,12 +379,16 @@ impl<'a> TokenTreesView<'a> { Self(tts) } + pub fn empty() -> Self { + Self(&[]) + } + pub fn iter(&self) -> TtIter<'a> { TtIter::new(self.0) } pub fn cursor(&self) -> Cursor<'a> { - Cursor::new(self.0) + Cursor::new(*self) } pub fn len(&self) -> usize { @@ -374,13 +412,6 @@ impl<'a> TokenTreesView<'a> { self.try_into_subtree().map(|subtree| subtree.strip_invisible()).unwrap_or(self) } - /// This returns a **flat** structure of tokens (subtrees will be represented by a single node - /// preceding their children), so it isn't suited for most use cases, only for matching leaves - /// at the beginning/end with no subtrees before them. If you need a structured pass, use [`TtIter`]. - pub fn flat_tokens(&self) -> &'a [TokenTree] { - self.0 - } - pub fn split( self, mut split_fn: impl FnMut(TtElement<'a>) -> bool, @@ -406,6 +437,21 @@ impl<'a> TokenTreesView<'a> { Some(result) }) } + + pub fn first_span(&self) -> Option { + Some(self.0.first()?.first_span()) + } + + pub fn last_span(&self) -> Option { + Some(match self.0.last()? { + TokenTree::Leaf(it) => *it.span(), + TokenTree::Subtree(it) => it.delimiter.close, + }) + } + + pub fn iter_flat_tokens(&self) -> impl ExactSizeIterator + use<'a> { + self.0.iter().cloned() + } } impl fmt::Debug for TokenTreesView<'_> { @@ -453,11 +499,11 @@ impl fmt::Display for TokenTreesView<'_> { match child { TtElement::Leaf(Leaf::Punct(p)) => { needs_space = p.spacing == Spacing::Alone; - fmt::Display::fmt(p, f)?; + fmt::Display::fmt(&p, f)?; } - TtElement::Leaf(leaf) => fmt::Display::fmt(leaf, f)?, + TtElement::Leaf(leaf) => fmt::Display::fmt(&leaf, f)?, TtElement::Subtree(subtree, subtree_iter) => { - subtree_display(subtree, f, subtree_iter)? + subtree_display(&subtree, f, subtree_iter)? } } } @@ -493,11 +539,11 @@ impl<'a> SubtreeView<'a> { TtIter::new(&self.0[1..]) } - pub fn top_subtree(&self) -> &'a Subtree { + pub fn top_subtree(&self) -> Subtree { let TokenTree::Subtree(subtree) = &self.0[0] else { unreachable!("the first token tree is always the top subtree"); }; - subtree + *subtree } pub fn strip_invisible(&self) -> TokenTreesView<'a> { @@ -791,7 +837,7 @@ fn print_debug_token(f: &mut fmt::Formatter<'_>, level: usize, tt: TtElement<'_> } }, TtElement::Subtree(subtree, subtree_iter) => { - print_debug_subtree(f, subtree, level, subtree_iter)?; + print_debug_subtree(f, &subtree, level, subtree_iter)?; } } @@ -956,7 +1002,7 @@ impl TopSubtree { } } -pub fn pretty(mut tkns: &[TokenTree]) -> String { +pub fn pretty(tkns: TokenTreesView<'_>) -> String { fn tokentree_to_text(tkn: &TokenTree, tkns: &mut &[TokenTree]) -> String { match tkn { TokenTree::Leaf(Leaf::Ident(ident)) => { @@ -966,7 +1012,7 @@ pub fn pretty(mut tkns: &[TokenTree]) -> String { TokenTree::Leaf(Leaf::Punct(punct)) => format!("{}", punct.char), TokenTree::Subtree(subtree) => { let (subtree_content, rest) = tkns.split_at(subtree.usize_len()); - let content = pretty(subtree_content); + let content = pretty(TokenTreesView(subtree_content)); *tkns = rest; let (open, close) = match subtree.delimiter.kind { DelimiterKind::Brace => ("{", "}"), @@ -979,6 +1025,7 @@ pub fn pretty(mut tkns: &[TokenTree]) -> String { } } + let mut tkns = tkns.0; let mut last = String::new(); let mut last_to_joint = true; @@ -994,3 +1041,83 @@ pub fn pretty(mut tkns: &[TokenTree]) -> String { } last } + +#[derive(Debug)] +pub enum TransformTtAction<'a> { + Keep, + ReplaceWith(TokenTreesView<'a>), +} + +impl TransformTtAction<'_> { + #[inline] + pub fn remove() -> Self { + Self::ReplaceWith(TokenTreesView::empty()) + } +} + +/// This function takes a token tree, and calls `callback` with each token tree in it. +/// Then it does what the callback says: keeps the tt or replaces it with a (possibly empty) +/// tts view. +pub fn transform_tt<'b>( + tt: &mut TopSubtree, + mut callback: impl FnMut(TokenTree) -> TransformTtAction<'b>, +) { + let mut tt_vec = std::mem::take(&mut tt.0).into_vec(); + + // We need to keep a stack of the currently open subtrees, because we need to update + // them if we change the number of items in them. + let mut subtrees_stack = Vec::new(); + let mut i = 0; + while i < tt_vec.len() { + 'pop_finished_subtrees: while let Some(&subtree_idx) = subtrees_stack.last() { + let TokenTree::Subtree(subtree) = &tt_vec[subtree_idx] else { + unreachable!("non-subtree on subtrees stack"); + }; + if i >= subtree_idx + 1 + subtree.usize_len() { + subtrees_stack.pop(); + } else { + break 'pop_finished_subtrees; + } + } + + let current = match &tt_vec[i] { + TokenTree::Leaf(leaf) => TokenTree::Leaf(match leaf { + Leaf::Literal(leaf) => Leaf::Literal(leaf.clone()), + Leaf::Punct(leaf) => Leaf::Punct(*leaf), + Leaf::Ident(leaf) => Leaf::Ident(leaf.clone()), + }), + TokenTree::Subtree(subtree) => TokenTree::Subtree(*subtree), + }; + let action = callback(current); + match action { + TransformTtAction::Keep => { + // This cannot be shared with the replaced case, because then we may push the same subtree + // twice, and will update it twice which will lead to errors. + if let TokenTree::Subtree(_) = &tt_vec[i] { + subtrees_stack.push(i); + } + + i += 1; + } + TransformTtAction::ReplaceWith(replacement) => { + let old_len = 1 + match &tt_vec[i] { + TokenTree::Leaf(_) => 0, + TokenTree::Subtree(subtree) => subtree.usize_len(), + }; + let len_diff = replacement.len() as i64 - old_len as i64; + tt_vec.splice(i..i + old_len, replacement.0.iter().cloned()); + // Skip the newly inserted replacement, we don't want to visit it. + i += replacement.len(); + + for &subtree_idx in &subtrees_stack { + let TokenTree::Subtree(subtree) = &mut tt_vec[subtree_idx] else { + unreachable!("non-subtree on subtrees stack"); + }; + subtree.len = (i64::from(subtree.len) + len_diff).try_into().unwrap(); + } + } + } + } + + tt.0 = tt_vec.into_boxed_slice(); +} From 175e297e58198883cc181ad01805c6f3280f2e61 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 29 Dec 2025 05:05:47 +0200 Subject: [PATCH 1367/3801] Make `tt::Literal` use one `Symbol` for the text and the suffix That shrinks it, which is useless now (it's not the dominant factor), but will become important when we'll implement span compression. --- .../rust-analyzer/crates/cfg/src/cfg_expr.rs | 5 +- .../crates/hir-def/src/item_tree/attrs.rs | 2 +- .../crates/hir-def/src/nameres/collector.rs | 8 +- .../crates/hir-expand/src/attrs.rs | 33 ++--- .../crates/hir-expand/src/builtin/fn_macro.rs | 107 ++++++--------- .../crates/hir-expand/src/builtin/quote.rs | 10 +- .../crates/hir-expand/src/fixup.rs | 2 +- .../rust-analyzer/crates/mbe/src/benchmark.rs | 7 +- .../crates/mbe/src/expander/matcher.rs | 7 +- .../crates/mbe/src/expander/transcriber.rs | 18 ++- .../rust-analyzer/crates/mbe/src/parser.rs | 13 +- .../proc-macro-api/src/legacy_protocol/msg.rs | 25 ++-- .../src/legacy_protocol/msg/flat.rs | 28 ++-- .../crates/syntax-bridge/src/lib.rs | 11 +- .../syntax-bridge/src/to_parser_input.rs | 2 +- .../crates/test-fixture/src/lib.rs | 5 +- src/tools/rust-analyzer/crates/tt/src/lib.rs | 125 +++++++++--------- 17 files changed, 190 insertions(+), 218 deletions(-) diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs index c5da8443a68f..d253f6f492c7 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs @@ -157,7 +157,8 @@ fn next_cfg_expr_from_ast( }, ctx: span::SyntaxContext::root(span::Edition::Edition2015), }; - let literal = tt::token_to_literal(literal.text(), dummy_span).symbol; + let literal = + Symbol::intern(tt::token_to_literal(literal.text(), dummy_span).text()); it.next(); CfgAtom::KeyValue { key: name, value: literal.clone() }.into() } else { @@ -211,7 +212,7 @@ fn next_cfg_expr(it: &mut tt::iter::TtIter<'_>) -> Option { Some(tt::TtElement::Leaf(tt::Leaf::Literal(literal))) => { it.next(); it.next(); - CfgAtom::KeyValue { key: name, value: literal.symbol.clone() }.into() + CfgAtom::KeyValue { key: name, value: Symbol::intern(literal.text()) }.into() } _ => return Some(CfgExpr::Invalid), } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs index bfebce001375..79076112847b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs @@ -226,7 +226,7 @@ impl<'attr> AttrQuery<'attr> { } #[inline] - pub(crate) fn string_value_with_span(self) -> Option<(&'attr Symbol, span::Span)> { + pub(crate) fn string_value_with_span(self) -> Option<(&'attr str, span::Span)> { self.attrs().find_map(|attr| attr.string_value_with_span()) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 822da678d797..4740e3b99e3d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -17,7 +17,7 @@ use hir_expand::{ name::{AsName, Name}, proc_macro::CustomProcMacroExpander, }; -use intern::{Interned, sym}; +use intern::{Interned, Symbol, sym}; use itertools::izip; use la_arena::Idx; use rustc_hash::{FxHashMap, FxHashSet}; @@ -292,13 +292,13 @@ impl<'db> DefCollector<'db> { match () { () if *attr_name == sym::recursion_limit => { if let Some(limit) = attr.string_value() - && let Ok(limit) = limit.as_str().parse() + && let Ok(limit) = limit.parse() { crate_data.recursion_limit = Some(limit); } } () if *attr_name == sym::crate_type => { - if attr.string_value() == Some(&sym::proc_dash_macro) { + if attr.string_value() == Some("proc-macro") { self.is_proc_macro = true; } } @@ -2460,7 +2460,7 @@ impl ModCollector<'_, '_> { let name; let name = match attrs.by_key(sym::rustc_builtin_macro).string_value_with_span() { Some((it, span)) => { - name = Name::new_symbol(it.clone(), span.ctx); + name = Name::new_symbol(Symbol::intern(it), span.ctx); &name } None => { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index 5a440187203c..e3f10b212904 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs @@ -35,7 +35,7 @@ use arrayvec::ArrayVec; use base_db::Crate; use cfg::{CfgExpr, CfgOptions}; use either::Either; -use intern::{Interned, Symbol}; +use intern::Interned; use itertools::Itertools; use mbe::{DelimiterKind, Punct}; use parser::T; @@ -417,37 +417,32 @@ impl fmt::Display for AttrInput { impl Attr { /// #[path = "string"] - pub fn string_value(&self) -> Option<&Symbol> { + pub fn string_value(&self) -> Option<&str> { match self.input.as_deref()? { - AttrInput::Literal(tt::Literal { - symbol: text, - kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), - .. - }) => Some(text), + AttrInput::Literal( + lit @ tt::Literal { kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), .. }, + ) => Some(lit.text()), _ => None, } } /// #[path = "string"] - pub fn string_value_with_span(&self) -> Option<(&Symbol, span::Span)> { + pub fn string_value_with_span(&self) -> Option<(&str, span::Span)> { match self.input.as_deref()? { - AttrInput::Literal(tt::Literal { - symbol: text, - kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), - span, - suffix: _, - }) => Some((text, *span)), + AttrInput::Literal( + lit @ tt::Literal { kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), span, .. }, + ) => Some((lit.text(), *span)), _ => None, } } pub fn string_value_unescape(&self) -> Option> { match self.input.as_deref()? { - AttrInput::Literal(tt::Literal { - symbol: text, kind: tt::LitKind::StrRaw(_), .. - }) => Some(Cow::Borrowed(text.as_str())), - AttrInput::Literal(tt::Literal { symbol: text, kind: tt::LitKind::Str, .. }) => { - unescape(text.as_str()) + AttrInput::Literal(lit @ tt::Literal { kind: tt::LitKind::StrRaw(_), .. }) => { + Some(Cow::Borrowed(lit.text())) + } + AttrInput::Literal(lit @ tt::Literal { kind: tt::LitKind::Str, .. }) => { + unescape(lit.text()) } _ => None, } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 011a9530c4d3..6e4b96b05088 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -1,5 +1,7 @@ //! Builtin macro +use std::borrow::Cow; + use base_db::AnchoredPath; use cfg::CfgExpr; use either::Either; @@ -13,7 +15,7 @@ use span::{Edition, FileId, Span}; use stdx::format_to; use syntax::{ format_smolstr, - unescape::{unescape_byte, unescape_char, unescape_str}, + unescape::{unescape_byte, unescape_char}, }; use syntax_bridge::syntax_node_to_token_tree; @@ -177,12 +179,7 @@ fn line_expand( // not incremental ExpandResult::ok(tt::TopSubtree::invisible_from_leaves( span, - [tt::Leaf::Literal(tt::Literal { - symbol: sym::INTEGER_0, - span, - kind: tt::LitKind::Integer, - suffix: Some(sym::u32), - })], + [tt::Leaf::Literal(tt::Literal::new("0", span, tt::LitKind::Integer, "u32"))], )) } @@ -303,7 +300,8 @@ fn format_args_nl_expand( mut lit @ tt::Literal { kind: tt::LitKind::Str, .. }, ))) = lit { - lit.symbol = Symbol::intern(&format_smolstr!("{}\\n", lit.symbol.as_str())); + let (text, suffix) = lit.text_and_suffix(); + lit.text_and_suffix = Symbol::intern(&format_smolstr!("{text}\\n{suffix}")); tt.set_token(1, lit.into()); } ExpandResult::ok(quote! {span => @@ -521,14 +519,11 @@ fn compile_error_expand( let err = match tt.iter().collect_array() { Some( [ - tt::TtElement::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, - span: _, - kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), - suffix: _, - })), + tt::TtElement::Leaf(tt::Leaf::Literal( + lit @ tt::Literal { kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), .. }, + )), ], - ) => ExpandError::other(span, Box::from(unescape_symbol(&text).as_str())), + ) => ExpandError::other(span, Box::from(unescape_str(lit.text()))), _ => ExpandError::other(span, "`compile_error!` argument must be a string"), }; @@ -569,20 +564,20 @@ fn concat_expand( // as-is. match it.kind { tt::LitKind::Char => { - if let Ok(c) = unescape_char(it.symbol.as_str()) { + if let Ok(c) = unescape_char(it.text()) { text.push(c); } record_span(it.span); } tt::LitKind::Integer | tt::LitKind::Float => { - format_to!(text, "{}", it.symbol.as_str()) + format_to!(text, "{}", it.text()) } tt::LitKind::Str => { - text.push_str(unescape_symbol(&it.symbol).as_str()); + text.push_str(&unescape_str(it.text())); record_span(it.span); } tt::LitKind::StrRaw(_) => { - format_to!(text, "{}", it.symbol.as_str()); + format_to!(text, "{}", it.text()); record_span(it.span); } tt::LitKind::Byte @@ -620,7 +615,7 @@ fn concat_expand( TtElement::Leaf(tt::Leaf::Literal(it)) if matches!(it.kind, tt::LitKind::Integer | tt::LitKind::Float) => { - format_to!(text, "-{}", it.symbol.as_str()); + format_to!(text, "-{}", it.text()); record_span(punct.span.cover(it.span)); } _ => { @@ -658,26 +653,22 @@ fn concat_bytes_expand( }; for (i, t) in tt.iter().enumerate() { match t { - TtElement::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, - span, - kind, - suffix: _, - })) => { + TtElement::Leaf(tt::Leaf::Literal(lit @ tt::Literal { span, kind, .. })) => { + let text = lit.text(); record_span(span); match kind { tt::LitKind::Byte => { - if let Ok(b) = unescape_byte(text.as_str()) { + if let Ok(b) = unescape_byte(text) { bytes.extend( b.escape_ascii().filter_map(|it| char::from_u32(it as u32)), ); } } tt::LitKind::ByteStr => { - bytes.push_str(text.as_str()); + bytes.push_str(text); } tt::LitKind::ByteStrRaw(_) => { - bytes.extend(text.as_str().escape_debug()); + bytes.extend(text.escape_debug()); } _ => { err.get_or_insert(ExpandError::other(span, "unexpected token")); @@ -706,12 +697,7 @@ fn concat_bytes_expand( ExpandResult { value: tt::TopSubtree::invisible_from_leaves( span, - [tt::Leaf::Literal(tt::Literal { - symbol: Symbol::intern(&bytes), - span, - kind: tt::LitKind::ByteStr, - suffix: None, - })], + [tt::Leaf::Literal(tt::Literal::new_no_suffix(&bytes, span, tt::LitKind::ByteStr))], ), err, } @@ -725,25 +711,19 @@ fn concat_bytes_expand_subtree( ) -> Result<(), ExpandError> { for (ti, tt) in tree_iter.enumerate() { match tt { - TtElement::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, - span, - kind: tt::LitKind::Byte, - suffix: _, - })) => { - if let Ok(b) = unescape_byte(text.as_str()) { + TtElement::Leaf(tt::Leaf::Literal( + lit @ tt::Literal { span, kind: tt::LitKind::Byte, .. }, + )) => { + if let Ok(b) = unescape_byte(lit.text()) { bytes.extend(b.escape_ascii().filter_map(|it| char::from_u32(it as u32))); } record_span(span); } - TtElement::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, - span, - kind: tt::LitKind::Integer, - suffix: _, - })) => { + TtElement::Leaf(tt::Leaf::Literal( + lit @ tt::Literal { span, kind: tt::LitKind::Integer, .. }, + )) => { record_span(span); - if let Ok(b) = text.as_str().parse::() { + if let Ok(b) = lit.text().parse::() { bytes.extend(b.escape_ascii().filter_map(|it| char::from_u32(it as u32))); } } @@ -792,18 +772,16 @@ fn parse_string(tt: &tt::TopSubtree) -> Result<(Symbol, Span), ExpandError> { } match tt { - TtElement::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, + TtElement::Leaf(tt::Leaf::Literal(lit @ tt::Literal { span, kind: tt::LitKind::Str, - suffix: _, - })) => Ok((unescape_symbol(&text), span)), - TtElement::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, + .. + })) => Ok((Symbol::intern(&unescape_str(lit.text())), span)), + TtElement::Leaf(tt::Leaf::Literal(lit @ tt::Literal { span, kind: tt::LitKind::StrRaw(_), - suffix: _, - })) => Ok((text.clone(), span)), + .. + })) => Ok((Symbol::intern(lit.text()), span)), TtElement::Leaf(l) => Err(*l.span()), TtElement::Subtree(tt, _) => Err(tt.delimiter.open.cover(tt.delimiter.close)), } @@ -855,10 +833,10 @@ fn include_bytes_expand( let res = tt::TopSubtree::invisible_from_leaves( span, [tt::Leaf::Literal(tt::Literal { - symbol: Symbol::empty(), + text_and_suffix: Symbol::empty(), span, kind: tt::LitKind::ByteStrRaw(1), - suffix: None, + suffix_len: 0, })], ); ExpandResult::ok(res) @@ -979,17 +957,16 @@ fn quote_expand( ) } -fn unescape_symbol(s: &Symbol) -> Symbol { - if s.as_str().contains('\\') { - let s = s.as_str(); +fn unescape_str(s: &str) -> Cow<'_, str> { + if s.contains('\\') { let mut buf = String::with_capacity(s.len()); - unescape_str(s, |_, c| { + syntax::unescape::unescape_str(s, |_, c| { if let Ok(c) = c { buf.push(c) } }); - Symbol::intern(&buf) + Cow::Owned(buf) } else { - s.clone() + Cow::Borrowed(s) } } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs index 4039b6c334ec..51c4e225168f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs @@ -199,16 +199,16 @@ impl ToTokenTree for &T { } impl_to_to_tokentrees! { - span: u32 => self { crate::tt::Literal{symbol: Symbol::integer(self as _), span, kind: tt::LitKind::Integer, suffix: None } }; - span: usize => self { crate::tt::Literal{symbol: Symbol::integer(self as _), span, kind: tt::LitKind::Integer, suffix: None } }; - span: i32 => self { crate::tt::Literal{symbol: Symbol::integer(self as _), span, kind: tt::LitKind::Integer, suffix: None } }; + span: u32 => self { crate::tt::Literal{text_and_suffix: Symbol::integer(self as _), span, kind: tt::LitKind::Integer, suffix_len: 0 } }; + span: usize => self { crate::tt::Literal{text_and_suffix: Symbol::integer(self as _), span, kind: tt::LitKind::Integer, suffix_len: 0 } }; + span: i32 => self { crate::tt::Literal{text_and_suffix: Symbol::integer(self as _), span, kind: tt::LitKind::Integer, suffix_len: 0 } }; span: bool => self { crate::tt::Ident{sym: if self { sym::true_ } else { sym::false_ }, span, is_raw: tt::IdentIsRaw::No } }; _span: crate::tt::Leaf => self { self }; _span: crate::tt::Literal => self { self }; _span: crate::tt::Ident => self { self }; _span: crate::tt::Punct => self { self }; - span: &str => self { crate::tt::Literal{symbol: Symbol::intern(&self.escape_default().to_smolstr()), span, kind: tt::LitKind::Str, suffix: None }}; - span: String => self { crate::tt::Literal{symbol: Symbol::intern(&self.escape_default().to_smolstr()), span, kind: tt::LitKind::Str, suffix: None }}; + span: &str => self { crate::tt::Literal{text_and_suffix: Symbol::intern(&self.escape_default().to_smolstr()), span, kind: tt::LitKind::Str, suffix_len: 0 }}; + span: String => self { crate::tt::Literal{text_and_suffix: Symbol::intern(&self.escape_default().to_smolstr()), span, kind: tt::LitKind::Str, suffix_len: 0 }}; span: Name => self { let (is_raw, s) = IdentIsRaw::split_from_symbol(self.as_str()); crate::tt::Ident{sym: Symbol::intern(s), span, is_raw } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs index 6afc6e5d5e7f..92ddd7fa8b07 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs @@ -415,7 +415,7 @@ mod tests { // `TokenTree`s, see the last assertion in `check()`. fn check_leaf_eq(a: &tt::Leaf, b: &tt::Leaf) -> bool { match (a, b) { - (tt::Leaf::Literal(a), tt::Leaf::Literal(b)) => a.symbol == b.symbol, + (tt::Leaf::Literal(a), tt::Leaf::Literal(b)) => a.text_and_suffix == b.text_and_suffix, (tt::Leaf::Punct(a), tt::Leaf::Punct(b)) => a.char == b.char, (tt::Leaf::Ident(a), tt::Leaf::Ident(b)) => a.sym == b.sym, _ => false, diff --git a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs index 6b018510be14..603fee73064e 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs @@ -236,12 +236,7 @@ fn invocation_fixtures( tt::Leaf::Punct(tt::Punct { span: DUMMY, char, spacing: tt::Spacing::Alone }) } fn make_literal(lit: &str) -> tt::Leaf { - tt::Leaf::Literal(tt::Literal { - span: DUMMY, - symbol: Symbol::intern(lit), - kind: tt::LitKind::Str, - suffix: None, - }) + tt::Leaf::Literal(tt::Literal::new_no_suffix(lit, DUMMY, tt::LitKind::Str)) } fn make_subtree(kind: tt::DelimiterKind, builder: &mut tt::TopSubtreeBuilder) { builder.open(kind, DUMMY); diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs index e845b1ab8d1f..8f6627a60fe6 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs @@ -517,7 +517,8 @@ fn match_loop_inner<'t>( } OpDelimited::Op(Op::Literal(lhs)) => { if let Ok(rhs) = src.clone().expect_leaf() { - if matches!(&rhs, tt::Leaf::Literal(it) if it.symbol == lhs.symbol) { + if matches!(&rhs, tt::Leaf::Literal(it) if it.text_and_suffix == lhs.text_and_suffix) + { item.dot.next(); } else { res.add_err(ExpandError::new( @@ -953,8 +954,8 @@ fn expect_separator(iter: &mut TtIter<'_>, separator: &Separator) -> bool { }, Separator::Literal(lhs) => match fork.expect_literal() { Ok(rhs) => match rhs { - tt::Leaf::Literal(rhs) => rhs.symbol == lhs.symbol, - tt::Leaf::Ident(rhs) => rhs.sym == lhs.symbol, + tt::Leaf::Literal(rhs) => rhs.text_and_suffix == lhs.text_and_suffix, + tt::Leaf::Ident(rhs) => rhs.sym == lhs.text_and_suffix, tt::Leaf::Punct(_) => false, }, Err(_) => false, diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs index 38098e2c84da..e8e7928c263f 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs @@ -222,10 +222,10 @@ fn expand_subtree( let index = ctx.nesting.get(ctx.nesting.len() - 1 - depth).map_or(0, |nest| nest.idx); builder.push(tt::Leaf::Literal(tt::Literal { - symbol: Symbol::integer(index), + text_and_suffix: Symbol::integer(index), span: ctx.call_site, kind: tt::LitKind::Integer, - suffix: None, + suffix_len: 0, })); } Op::Len { depth } => { @@ -234,10 +234,10 @@ fn expand_subtree( 0 }); builder.push(tt::Leaf::Literal(tt::Literal { - symbol: Symbol::integer(length), + text_and_suffix: Symbol::integer(length), span: ctx.call_site, kind: tt::LitKind::Integer, - suffix: None, + suffix_len: 0, })); } Op::Count { name, depth } => { @@ -278,9 +278,9 @@ fn expand_subtree( let res = count(binding, 0, depth.unwrap_or(0)); builder.push(tt::Leaf::Literal(tt::Literal { - symbol: Symbol::integer(res), + text_and_suffix: Symbol::integer(res), span: ctx.call_site, - suffix: None, + suffix_len: 0, kind: tt::LitKind::Integer, })); } @@ -294,7 +294,7 @@ fn expand_subtree( ConcatMetaVarExprElem::Literal(lit) => { // FIXME: This isn't really correct wrt. escaping, but that's what rustc does and anyway // escaping is used most of the times for characters that are invalid in identifiers. - concatenated.push_str(lit.symbol.as_str()) + concatenated.push_str(lit.text()) } ConcatMetaVarExprElem::Var(var) => { // Handling of repetitions in `${concat}` isn't fleshed out in rustc, so we currently @@ -329,9 +329,7 @@ fn expand_subtree( (Some(TtElement::Leaf(tt::Leaf::Ident(ident))), None) => { ident.sym.as_str() } - (Some(TtElement::Leaf(tt::Leaf::Literal(lit))), None) => { - lit.symbol.as_str() - } + (Some(TtElement::Leaf(tt::Leaf::Literal(lit))), None) => lit.text(), _ => { if err.is_none() { err = Some(ExpandError::binding_error( diff --git a/src/tools/rust-analyzer/crates/mbe/src/parser.rs b/src/tools/rust-analyzer/crates/mbe/src/parser.rs index cecdd43a42a1..796ee62d48e3 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/parser.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/parser.rs @@ -192,7 +192,7 @@ impl PartialEq for Separator { match (self, other) { (Ident(a), Ident(b)) => a.sym == b.sym, - (Literal(a), Literal(b)) => a.symbol == b.symbol, + (Literal(a), Literal(b)) => a.text_and_suffix == b.text_and_suffix, (Puncts(a), Puncts(b)) if a.len() == b.len() => { let a_iter = a.iter().map(|a| a.char); let b_iter = b.iter().map(|b| b.char); @@ -270,7 +270,7 @@ fn next_op( } tt::Leaf::Literal(lit) if is_boolean_literal(&lit) => { let kind = eat_fragment_kind(edition, src, mode)?; - let name = lit.symbol.clone(); + let name = lit.text_and_suffix.clone(); let id = lit.span; Op::Var { name, kind, id } } @@ -364,7 +364,7 @@ fn eat_fragment_kind( } fn is_boolean_literal(lit: &tt::Literal) -> bool { - matches!(lit.symbol.as_str(), "true" | "false") + lit.text_and_suffix == sym::true_ || lit.text_and_suffix == sym::false_ } fn parse_repeat(src: &mut TtIter<'_>) -> Result<(Option, RepeatKind), ParseError> { @@ -478,11 +478,12 @@ fn parse_metavar_expr(src: &mut TtIter<'_>) -> Result { fn parse_depth(src: &mut TtIter<'_>) -> Result { if src.is_empty() { Ok(0) - } else if let tt::Leaf::Literal(tt::Literal { symbol: text, suffix: None, .. }) = - src.expect_literal()? + } else if let tt::Leaf::Literal(lit) = src.expect_literal()? + && let (text, suffix) = lit.text_and_suffix() + && suffix.is_empty() { // Suffixes are not allowed. - text.as_str().parse().map_err(|_| ()) + text.parse().map_err(|_| ()) } else { Err(()) } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs index ac627b9232a0..4146b619ec0c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs @@ -172,7 +172,7 @@ impl Message for Response {} #[cfg(test)] mod tests { - use intern::{Symbol, sym}; + use intern::Symbol; use span::{ Edition, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext, TextRange, TextSize, }; @@ -232,16 +232,15 @@ mod tests { } .into(), ); - builder.push(Leaf::Literal(Literal { - symbol: Symbol::intern("Foo"), - span: Span { + builder.push(Leaf::Literal(Literal::new_no_suffix( + "Foo", + Span { range: TextRange::at(TextSize::new(10), TextSize::of("\"Foo\"")), anchor, ctx: SyntaxContext::root(Edition::CURRENT), }, - kind: tt::LitKind::Str, - suffix: None, - })); + tt::LitKind::Str, + ))); builder.push(Leaf::Punct(Punct { char: '@', span: Span { @@ -267,16 +266,16 @@ mod tests { ctx: SyntaxContext::root(Edition::CURRENT), }, ); - builder.push(Leaf::Literal(Literal { - symbol: sym::INTEGER_0, - span: Span { + builder.push(Leaf::Literal(Literal::new( + "0", + Span { range: TextRange::at(TextSize::new(16), TextSize::of("0u32")), anchor, ctx: SyntaxContext::root(Edition::CURRENT), }, - kind: tt::LitKind::Integer, - suffix: Some(sym::u32), - })); + tt::LitKind::Integer, + "u32", + ))); builder.close(Span { range: TextRange::at(TextSize::new(20), TextSize::of(']')), anchor, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs index ed4b7aff76fc..cd8944aa6170 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs @@ -512,12 +512,14 @@ impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIt let idx = self.literal.len() as u32; let id = self.token_id_of(lit.span); let (text, suffix) = if self.version >= EXTENDED_LEAF_DATA { + let (text, suffix) = lit.text_and_suffix(); ( - self.intern_owned(lit.symbol.as_str().to_owned()), - lit.suffix - .as_ref() - .map(|s| self.intern_owned(s.as_str().to_owned())) - .unwrap_or(!0), + self.intern_owned(text.to_owned()), + if suffix.is_empty() { + !0 + } else { + self.intern_owned(suffix.to_owned()) + }, ) } else { (self.intern_owned(format!("{lit}")), !0) @@ -774,10 +776,10 @@ impl> Reader<'_, T> { let span = read_span(repr.id); s.push( tt::Leaf::Literal(if self.version >= EXTENDED_LEAF_DATA { - tt::Literal { - symbol: Symbol::intern(text), + tt::Literal::new( + text, span, - kind: match u16::to_le_bytes(repr.kind) { + match u16::to_le_bytes(repr.kind) { [0, _] => Err(()), [1, _] => Byte, [2, _] => Char, @@ -791,14 +793,12 @@ impl> Reader<'_, T> { [10, r] => CStrRaw(r), _ => unreachable!(), }, - suffix: if repr.suffix != !0 { - Some(Symbol::intern( - self.text[repr.suffix as usize].as_str(), - )) + if repr.suffix != !0 { + self.text[repr.suffix as usize].as_str() } else { - None + "" }, - } + ) } else { tt::token_to_literal(text, span) }) diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs index 79b51a816ebe..ce238eb932ae 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs @@ -442,7 +442,7 @@ fn convert_doc_comment( text = &text[0..text.len() - 2]; } let (text, kind) = desugar_doc_comment_text(text, mode); - let lit = tt::Literal { symbol: text, span, kind, suffix: None }; + let lit = tt::Literal { text_and_suffix: text, span, kind, suffix_len: 0 }; tt::Leaf::from(lit) }; @@ -867,12 +867,9 @@ impl TtTreeSink<'_> { /// This occurs when a float literal is used as a field access. fn float_split(&mut self, has_pseudo_dot: bool) { let (text, span) = match self.cursor.token_tree() { - Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, - span, - kind: tt::LitKind::Float, - suffix: _, - }))) => (text.as_str(), *span), + Some(tt::TokenTree::Leaf(tt::Leaf::Literal( + lit @ tt::Literal { span, kind: tt::LitKind::Float, .. }, + ))) => (lit.text(), *span), tt => unreachable!("{tt:?}"), }; // FIXME: Span splitting diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs index 6883f71307c8..851a4af86439 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs @@ -52,7 +52,7 @@ pub fn to_parser_input( }; res.push(kind, ctx_edition(lit.span.ctx)); - if kind == FLOAT_NUMBER && !lit.symbol.as_str().ends_with('.') { + if kind == FLOAT_NUMBER && !lit.text().ends_with('.') { // Tag the token as joint if it is float with a fractional part // we use this jointness to inform the parser about what token split // event to emit when we encounter a float literal in a field access diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 487171c3e3e8..b9c389c7694e 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -920,7 +920,8 @@ impl ProcMacroExpander for ShortenProcMacroExpander { Leaf::Literal(it) => { // XXX Currently replaces any literals with an empty string, but supporting // "shortening" other literals would be nice. - it.symbol = Symbol::empty(); + it.text_and_suffix = Symbol::empty(); + it.suffix_len = 0; } Leaf::Punct(_) => {} Leaf::Ident(it) => { @@ -954,7 +955,7 @@ impl ProcMacroExpander for Issue17479ProcMacroExpander { let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = iter.next() else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); }; - let symbol = &lit.symbol; + let symbol = Symbol::intern(lit.text()); let span = lit.span; Ok(quote! { span => #symbol() diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 97e0b34ad7b7..91fcec9327c3 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -18,6 +18,7 @@ pub mod iter; use std::fmt; +use arrayvec::ArrayString; use buffer::Cursor; use intern::Symbol; use stdx::{impl_from, itertools::Itertools as _}; @@ -617,17 +618,56 @@ pub enum DelimiterKind { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Literal { - // escaped - pub symbol: Symbol, + /// Escaped, text then suffix concatenated. + pub text_and_suffix: Symbol, pub span: Span, pub kind: LitKind, - pub suffix: Option, + pub suffix_len: u8, } -pub fn token_to_literal(text: &str, span: Span) -> Literal -where - Span: Copy, -{ +impl Literal { + #[inline] + pub fn text_and_suffix(&self) -> (&str, &str) { + let text_and_suffix = self.text_and_suffix.as_str(); + text_and_suffix.split_at(text_and_suffix.len() - usize::from(self.suffix_len)) + } + + #[inline] + pub fn text(&self) -> &str { + self.text_and_suffix().0 + } + + #[inline] + pub fn suffix(&self) -> &str { + self.text_and_suffix().1 + } + + pub fn new(text: &str, span: Span, kind: LitKind, suffix: &str) -> Self { + const MAX_INLINE_CAPACITY: usize = 30; + let text_and_suffix = if suffix.is_empty() { + Symbol::intern(text) + } else if (text.len() + suffix.len()) < MAX_INLINE_CAPACITY { + let mut text_and_suffix = ArrayString::::new(); + text_and_suffix.push_str(text); + text_and_suffix.push_str(suffix); + Symbol::intern(&text_and_suffix) + } else { + let mut text_and_suffix = String::with_capacity(text.len() + suffix.len()); + text_and_suffix.push_str(text); + text_and_suffix.push_str(suffix); + Symbol::intern(&text_and_suffix) + }; + + Self { text_and_suffix, span, kind, suffix_len: suffix.len().try_into().unwrap() } + } + + #[inline] + pub fn new_no_suffix(text: &str, span: Span, kind: LitKind) -> Self { + Self { text_and_suffix: Symbol::intern(text), span, kind, suffix_len: 0 } + } +} + +pub fn token_to_literal(text: &str, span: Span) -> Literal { use rustc_lexer::LiteralKind; let token = rustc_lexer::tokenize(text, rustc_lexer::FrontmatterAllowed::No).next_tuple(); @@ -636,12 +676,7 @@ where .. },)) = token else { - return Literal { - span, - symbol: Symbol::intern(text), - kind: LitKind::Err(()), - suffix: None, - }; + return Literal::new_no_suffix(text, span, LitKind::Err(())); }; let (kind, start_offset, end_offset) = match kind { @@ -672,20 +707,15 @@ where let (lit, suffix) = text.split_at(suffix_start as usize); let lit = &lit[start_offset..lit.len() - end_offset]; let suffix = match suffix { - "" | "_" => None, + "" | "_" => "", // ill-suffixed literals _ if !matches!(kind, LitKind::Integer | LitKind::Float | LitKind::Err(_)) => { - return Literal { - span, - symbol: Symbol::intern(text), - kind: LitKind::Err(()), - suffix: None, - }; + return Literal::new_no_suffix(text, span, LitKind::Err(())); } - suffix => Some(Symbol::intern(suffix)), + suffix => suffix, }; - Literal { span, symbol: Symbol::intern(lit), kind, suffix } + Literal::new(lit, span, kind, suffix) } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -805,15 +835,8 @@ fn print_debug_token(f: &mut fmt::Formatter<'_>, level: usize, tt: TtElement<'_> match tt { TtElement::Leaf(leaf) => match leaf { Leaf::Literal(lit) => { - write!( - f, - "{}LITERAL {:?} {}{} {:#?}", - align, - lit.kind, - lit.symbol, - lit.suffix.as_ref().map(|it| it.as_str()).unwrap_or(""), - lit.span - )?; + let (text, suffix) = lit.text_and_suffix(); + write!(f, "{}LITERAL {:?} {}{} {:#?}", align, lit.kind, text, suffix, lit.span)?; } Leaf::Punct(punct) => { write!( @@ -875,44 +898,28 @@ impl fmt::Display for Ident { impl fmt::Display for Literal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (text, suffix) = self.text_and_suffix(); match self.kind { - LitKind::Byte => write!(f, "b'{}'", self.symbol), - LitKind::Char => write!(f, "'{}'", self.symbol), - LitKind::Integer | LitKind::Float | LitKind::Err(_) => write!(f, "{}", self.symbol), - LitKind::Str => write!(f, "\"{}\"", self.symbol), - LitKind::ByteStr => write!(f, "b\"{}\"", self.symbol), - LitKind::CStr => write!(f, "c\"{}\"", self.symbol), + LitKind::Byte => write!(f, "b'{}'", text), + LitKind::Char => write!(f, "'{}'", text), + LitKind::Integer | LitKind::Float | LitKind::Err(_) => write!(f, "{}", text), + LitKind::Str => write!(f, "\"{}\"", text), + LitKind::ByteStr => write!(f, "b\"{}\"", text), + LitKind::CStr => write!(f, "c\"{}\"", text), LitKind::StrRaw(num_of_hashes) => { let num_of_hashes = num_of_hashes as usize; - write!( - f, - r#"r{0:# { let num_of_hashes = num_of_hashes as usize; - write!( - f, - r#"br{0:# { let num_of_hashes = num_of_hashes as usize; - write!( - f, - r#"cr{0:# { let s = match it { - Leaf::Literal(it) => it.symbol.to_string(), + Leaf::Literal(it) => it.text().to_owned(), Leaf::Punct(it) => it.char.to_string(), Leaf::Ident(it) => format!("{}{}", it.is_raw.as_str(), it.sym), }; From cfd4d099f2644b12803dd469d6228a77d9a005e2 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 29 Dec 2025 04:27:59 +0000 Subject: [PATCH 1368/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 7fefa09b90ca57b8a0e0e4717d672d38a0ae58b5. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 7345c25066a8..d32b6d0d2fc7 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -2dc30247c5d8293aaa31e1d7dae2ed2fde908ada +7fefa09b90ca57b8a0e0e4717d672d38a0ae58b5 From 2d35541eb5e04b018f7859600ea7a01c575ba3ac Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 29 Dec 2025 05:04:35 +0000 Subject: [PATCH 1369/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 7fefa09b90ca57b8a0e0e4717d672d38a0ae58b5. --- 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 6a2835bc2d9e..d32b6d0d2fc7 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -23d01cd2412583491621ab1ca4f1b01e37d11e39 +7fefa09b90ca57b8a0e0e4717d672d38a0ae58b5 From 2ac2b18910fcfca41d90b80f866b84ff23f0a2e2 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Wed, 19 Nov 2025 11:17:00 +0530 Subject: [PATCH 1370/3801] std: sys: fs: uefi: Implement initial File - Implement basic opening and creating files. - Also implement debug. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 153 ++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 58 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 1c65e3e2b155..41d35c01252a 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -11,7 +11,7 @@ use crate::sys::{helpers, unsupported}; const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY; -pub struct File(!); +pub struct File(uefi_fs::File); #[derive(Clone)] pub struct FileAttr { @@ -235,9 +235,11 @@ impl OpenOptions { pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; + if create_new { + self.create(true); + } } - #[expect(dead_code)] const fn is_mode_valid(&self) -> bool { // Valid Combinations: Read, Read/Write, Read/Write/Create self.mode == file::MODE_READ @@ -247,100 +249,125 @@ impl OpenOptions { } impl File { - pub fn open(_path: &Path, _opts: &OpenOptions) -> io::Result { - unsupported() + pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { + if !opts.is_mode_valid() { + return Err(io::const_error!(io::ErrorKind::InvalidInput, "Invalid open options")); + } + + if opts.create_new && exists(path)? { + return Err(io::const_error!(io::ErrorKind::AlreadyExists, "File already exists")); + } + + let f = uefi_fs::File::from_path(path, opts.mode, 0).map(Self)?; + + if opts.truncate { + f.truncate(0)?; + } + + if opts.append { + f.seek(io::SeekFrom::End(0))?; + } + + Ok(f) } pub fn file_attr(&self) -> io::Result { - self.0 + self.0.file_info().map(FileAttr::from_uefi) } pub fn fsync(&self) -> io::Result<()> { - self.0 + unsupported() } pub fn datasync(&self) -> io::Result<()> { - self.0 + unsupported() } pub fn lock(&self) -> io::Result<()> { - self.0 + unsupported() } pub fn lock_shared(&self) -> io::Result<()> { - self.0 + unsupported() } pub fn try_lock(&self) -> Result<(), TryLockError> { - self.0 + unsupported().map_err(TryLockError::Error) } pub fn try_lock_shared(&self) -> Result<(), TryLockError> { - self.0 + unsupported().map_err(TryLockError::Error) } pub fn unlock(&self) -> io::Result<()> { - self.0 + unsupported() } - pub fn truncate(&self, _size: u64) -> io::Result<()> { - self.0 + pub fn truncate(&self, size: u64) -> io::Result<()> { + let mut file_info = self.0.file_info()?; + + unsafe { (*file_info.as_mut_ptr()).file_size = size }; + + self.0.set_file_info(file_info) } pub fn read(&self, _buf: &mut [u8]) -> io::Result { - self.0 + unsupported() } - pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.0 + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + crate::io::default_read_vectored(|b| self.read(b), bufs) } pub fn is_read_vectored(&self) -> bool { - self.0 + false } - pub fn read_buf(&self, _cursor: BorrowedCursor<'_>) -> io::Result<()> { - self.0 + pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + crate::io::default_read_buf(|buf| self.read(buf), cursor) } pub fn write(&self, _buf: &[u8]) -> io::Result { - self.0 + unsupported() } - pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result { - self.0 + pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + crate::io::default_write_vectored(|b| self.write(b), bufs) } pub fn is_write_vectored(&self) -> bool { - self.0 + false } pub fn flush(&self) -> io::Result<()> { - self.0 + unsupported() } pub fn seek(&self, _pos: SeekFrom) -> io::Result { - self.0 + unsupported() } pub fn size(&self) -> Option> { - self.0 + match self.file_attr() { + Ok(x) => Some(Ok(x.size())), + Err(e) => Some(Err(e)), + } } pub fn tell(&self) -> io::Result { - self.0 + unsupported() } pub fn duplicate(&self) -> io::Result { - self.0 + unsupported() } - pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { - self.0 + pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> { + set_perm_inner(&self.0, perm) } - pub fn set_times(&self, _times: FileTimes) -> io::Result<()> { - self.0 + pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + set_times_inner(&self.0, times) } } @@ -355,8 +382,10 @@ impl DirBuilder { } impl fmt::Debug for File { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut b = f.debug_struct("File"); + b.field("path", &self.0.path()); + b.finish() } } @@ -391,14 +420,7 @@ pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> { pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { let f = uefi_fs::File::from_path(p, file::MODE_READ | file::MODE_WRITE, 0)?; - let mut file_info = f.file_info()?; - - unsafe { - (*file_info.as_mut_ptr()).attribute = - ((*file_info.as_ptr()).attribute & !FILE_PERMISSIONS_MASK) | perm.to_attr() - }; - - f.set_file_info(file_info) + set_perm_inner(&f, perm) } pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> { @@ -408,21 +430,7 @@ pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> { pub fn set_times_nofollow(p: &Path, times: FileTimes) -> io::Result<()> { let f = uefi_fs::File::from_path(p, file::MODE_READ | file::MODE_WRITE, 0)?; - let mut file_info = f.file_info()?; - - if let Some(x) = times.accessed { - unsafe { - (*file_info.as_mut_ptr()).last_access_time = uefi_fs::systemtime_to_uefi(x); - } - } - - if let Some(x) = times.modified { - unsafe { - (*file_info.as_mut_ptr()).modification_time = uefi_fs::systemtime_to_uefi(x); - } - } - - f.set_file_info(file_info) + set_times_inner(&f, times) } pub fn rmdir(p: &Path) -> io::Result<()> { @@ -480,6 +488,35 @@ pub fn copy(_from: &Path, _to: &Path) -> io::Result { unsupported() } +fn set_perm_inner(f: &uefi_fs::File, perm: FilePermissions) -> io::Result<()> { + let mut file_info = f.file_info()?; + + unsafe { + (*file_info.as_mut_ptr()).attribute = + ((*file_info.as_ptr()).attribute & !FILE_PERMISSIONS_MASK) | perm.to_attr() + }; + + f.set_file_info(file_info) +} + +fn set_times_inner(f: &uefi_fs::File, times: FileTimes) -> io::Result<()> { + let mut file_info = f.file_info()?; + + if let Some(x) = times.accessed { + unsafe { + (*file_info.as_mut_ptr()).last_access_time = uefi_fs::systemtime_to_uefi(x); + } + } + + if let Some(x) = times.modified { + unsafe { + (*file_info.as_mut_ptr()).modification_time = uefi_fs::systemtime_to_uefi(x); + } + } + + f.set_file_info(file_info) +} + mod uefi_fs { use r_efi::protocols::{device_path, file, simple_file_system}; From 29f9397ad4277c127c7cb4e317cd95f623a27e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=9D=E5=80=89=E6=B0=B4=E5=B8=8C?= Date: Wed, 24 Dec 2025 17:51:39 +0800 Subject: [PATCH 1371/3801] docs: fix typo in std::io::buffered --- library/std/src/io/buffered/bufreader/buffer.rs | 2 +- library/std/src/io/buffered/linewritershim.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 9b600cd55758..ad8608bf6190 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -48,7 +48,7 @@ impl Buffer { #[inline] pub fn buffer(&self) -> &[u8] { - // SAFETY: self.pos and self.cap are valid, and self.cap => self.pos, and + // SAFETY: self.pos and self.filled are valid, and self.filled >= self.pos, and // that region is initialized because those are all invariants of this type. unsafe { self.buf.get_unchecked(self.pos..self.filled).assume_init_ref() } } diff --git a/library/std/src/io/buffered/linewritershim.rs b/library/std/src/io/buffered/linewritershim.rs index 5ebeada59bb5..967e24812b9f 100644 --- a/library/std/src/io/buffered/linewritershim.rs +++ b/library/std/src/io/buffered/linewritershim.rs @@ -52,7 +52,7 @@ impl<'a, W: ?Sized + Write> LineWriterShim<'a, W> { } impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> { - /// Writes some data into this BufReader with line buffering. + /// Writes some data into this BufWriter with line buffering. /// /// This means that, if any newlines are present in the data, the data up to /// the last newline is sent directly to the underlying writer, and data @@ -146,7 +146,7 @@ impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> { self.buffer.flush() } - /// Writes some vectored data into this BufReader with line buffering. + /// Writes some vectored data into this BufWriter with line buffering. /// /// This means that, if any newlines are present in the data, the data up to /// and including the buffer containing the last newline is sent directly to @@ -256,7 +256,7 @@ impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> { self.inner().is_write_vectored() } - /// Writes some data into this BufReader with line buffering. + /// Writes some data into this BufWriter with line buffering. /// /// This means that, if any newlines are present in the data, the data up to /// the last newline is sent directly to the underlying writer, and data From a3c816ad7d0e670467f864179a0f5cfd88f0a21e Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Mon, 29 Dec 2025 14:59:11 +0800 Subject: [PATCH 1372/3801] Fix enum variant suggestion consuming trailing parenthesis --- .../rustc_hir_typeck/src/method/suggest.rs | 13 ++-- tests/ui/suggestions/suggest-variants.rs | 23 +++++++ tests/ui/suggestions/suggest-variants.stderr | 60 ++++++++++++++++++- 3 files changed, 89 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 18bc00d65351..331fb91becad 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1384,13 +1384,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::Node::Stmt(&hir::Stmt { kind: hir::StmtKind::Semi(parent), .. }) | hir::Node::Expr(parent) = tcx.parent_hir_node(path_expr.hir_id) { - let replacement_span = - if let hir::ExprKind::Call(..) | hir::ExprKind::Struct(..) = parent.kind { - // We want to replace the parts that need to go, like `()` and `{}`. + // We want to replace the parts that need to go, like `()` and `{}`. + let replacement_span = match parent.kind { + hir::ExprKind::Call(callee, _) if callee.hir_id == path_expr.hir_id => { span.with_hi(parent.span.hi()) - } else { - span - }; + } + hir::ExprKind::Struct(..) => span.with_hi(parent.span.hi()), + _ => span, + }; match (variant.ctor, parent.kind) { (None, hir::ExprKind::Struct(..)) => { // We want a struct and we have a struct. We won't suggest changing diff --git a/tests/ui/suggestions/suggest-variants.rs b/tests/ui/suggestions/suggest-variants.rs index dd05d0f04abe..d3bd3c2c8e87 100644 --- a/tests/ui/suggestions/suggest-variants.rs +++ b/tests/ui/suggestions/suggest-variants.rs @@ -16,3 +16,26 @@ fn main() { Shape::Circl; //~ ERROR no variant Shape::Rombus; //~ ERROR no variant } + +enum Color { + Red, + Green(()), + Blue, + Alpha{ a: u8 }, +} + +fn red() -> Result { + Ok(Color::Redd) //~ ERROR no variant +} + +fn green() -> Result { + Ok(Color::Greenn(())) //~ ERROR no variant +} + +fn blue() -> Result { + Ok(Color::Blu) //~ ERROR no variant +} + +fn alpha() -> Result { + Ok(Color::Alph{ a: 255 }) //~ ERROR no variant +} diff --git a/tests/ui/suggestions/suggest-variants.stderr b/tests/ui/suggestions/suggest-variants.stderr index 50286a968759..13518a9d5842 100644 --- a/tests/ui/suggestions/suggest-variants.stderr +++ b/tests/ui/suggestions/suggest-variants.stderr @@ -74,6 +74,64 @@ LL | enum Shape { LL | Shape::Rombus; | ^^^^^^ variant or associated item not found in `Shape` -error: aborting due to 6 previous errors +error[E0599]: no variant or associated item named `Redd` found for enum `Color` in the current scope + --> $DIR/suggest-variants.rs:28:13 + | +LL | enum Color { + | ---------- variant or associated item `Redd` not found for this enum +... +LL | Ok(Color::Redd) + | ^^^^ variant or associated item not found in `Color` + | +help: there is a variant with a similar name + | +LL - Ok(Color::Redd) +LL + Ok(Color::Red) + | + +error[E0599]: no variant or associated item named `Greenn` found for enum `Color` in the current scope + --> $DIR/suggest-variants.rs:32:13 + | +LL | enum Color { + | ---------- variant or associated item `Greenn` not found for this enum +... +LL | Ok(Color::Greenn(())) + | ^^^^^^ variant or associated item not found in `Color` + | +help: there is a variant with a similar name + | +LL - Ok(Color::Greenn(())) +LL + Ok(Color::Green(())) + | + +error[E0599]: no variant or associated item named `Blu` found for enum `Color` in the current scope + --> $DIR/suggest-variants.rs:36:13 + | +LL | enum Color { + | ---------- variant or associated item `Blu` not found for this enum +... +LL | Ok(Color::Blu) + | ^^^ variant or associated item not found in `Color` + | +help: there is a variant with a similar name + | +LL | Ok(Color::Blue) + | + + +error[E0599]: no variant named `Alph` found for enum `Color` + --> $DIR/suggest-variants.rs:40:13 + | +LL | enum Color { + | ---------- variant `Alph` not found here +... +LL | Ok(Color::Alph{ a: 255 }) + | ^^^^ + | +help: there is a variant with a similar name + | +LL | Ok(Color::Alpha{ a: 255 }) + | + + +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0599`. From dc85816f912581d8114978d86e29ff5d31fcb6af Mon Sep 17 00:00:00 2001 From: Redddy Date: Mon, 29 Dec 2025 16:53:16 +0900 Subject: [PATCH 1373/3801] Add link for perf run Zulip channel --- src/doc/rustc-dev-guide/src/tests/perf.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/perf.md b/src/doc/rustc-dev-guide/src/tests/perf.md index e460ed8187eb..18762556137e 100644 --- a/src/doc/rustc-dev-guide/src/tests/perf.md +++ b/src/doc/rustc-dev-guide/src/tests/perf.md @@ -41,7 +41,9 @@ To evaluate the performance impact of a PR, write this comment on the PR: > repository](https://github.com/rust-lang/team) with the `perf = true` value in > the `[permissions]` section (and bors permissions are also required). If you > are not on one of those teams, feel free to ask for someone to post it for you -> (either on Zulip or ask the assigned reviewer). +> (either on [Zulip][perf run] or ask the assigned reviewer). + +[perf run]: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/perf.20run This will first tell bors to do a "try" build which do a full release build for `x86_64-unknown-linux-gnu`. After the build finishes, it will place it in the From 19c8ea4629ec22c0301bf4d5c36c7b9919c964d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 29 Dec 2025 09:56:12 +0100 Subject: [PATCH 1374/3801] Fix new bors config --- rust-bors.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rust-bors.toml b/rust-bors.toml index 996b50b2ea27..384343e431dc 100644 --- a/rust-bors.toml +++ b/rust-bors.toml @@ -29,6 +29,10 @@ labels_blocking_approval = [ # If CI runs quicker than this duration, consider it to be a failure min_ci_time = 600 +# Flip this once new bors is used for actual merges on this repository +merge_queue_enabled = false +report_merge_conflicts = true + [labels] approved = [ "+S-waiting-on-bors", @@ -60,7 +64,3 @@ auto_build_failed = [ "-S-waiting-on-crater", "-S-waiting-on-team" ] - -# Flip this two once new bors is used for actual merges on this repository -merge_queue_enabled = false -report_merge_conflicts = true From cb5f95c1013e7defd8a4504d03274a4b142248bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Fri, 19 Sep 2025 20:36:54 +0200 Subject: [PATCH 1375/3801] Implement 'TryFrom' for 'usize'; --- library/core/src/char/convert.rs | 55 ++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 6380f42d320c..7c1a329e7011 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -45,6 +45,7 @@ impl const From for u32 { /// ``` /// let c = 'c'; /// let u = u32::from(c); + /// /// assert!(4 == size_of_val(&u)) /// ``` #[inline] @@ -63,6 +64,7 @@ impl const From for u64 { /// ``` /// let c = '👤'; /// let u = u64::from(c); + /// /// assert!(8 == size_of_val(&u)) /// ``` #[inline] @@ -83,6 +85,7 @@ impl const From for u128 { /// ``` /// let c = '⚙'; /// let u = u128::from(c); + /// /// assert!(16 == size_of_val(&u)) /// ``` #[inline] @@ -93,8 +96,8 @@ impl const From for u128 { } } -/// Maps a `char` with code point in U+0000..=U+00FF to a byte in 0x00..=0xFF with same value, -/// failing if the code point is greater than U+00FF. +/// Maps a `char` with a code point from U+0000 to U+00FF (inclusive) to a byte in `0x00..=0xFF` with +/// the same value, failing if the code point is greater than U+00FF. /// /// See [`impl From for char`](char#impl-From-for-char) for details on the encoding. #[stable(feature = "u8_from_char", since = "1.59.0")] @@ -109,6 +112,7 @@ impl const TryFrom for u8 { /// ``` /// let a = 'ÿ'; // U+00FF /// let b = 'Ā'; // U+0100 + /// /// assert_eq!(u8::try_from(a), Ok(0xFF_u8)); /// assert!(u8::try_from(b).is_err()); /// ``` @@ -122,8 +126,8 @@ impl const TryFrom for u8 { } } -/// Maps a `char` with code point in U+0000..=U+FFFF to a `u16` in 0x0000..=0xFFFF with same value, -/// failing if the code point is greater than U+FFFF. +/// Maps a `char` with a code point from U+0000 to U+FFFF (inclusive) to a `u16` in `0x0000..=0xFFFF` +/// with the same value, failing if the code point is greater than U+FFFF. /// /// This corresponds to the UCS-2 encoding, as specified in ISO/IEC 10646:2003. #[stable(feature = "u16_from_char", since = "1.74.0")] @@ -138,6 +142,7 @@ impl const TryFrom for u16 { /// ``` /// let trans_rights = '⚧'; // U+26A7 /// let ninjas = '🥷'; // U+1F977 + /// /// assert_eq!(u16::try_from(trans_rights), Ok(0x26A7_u16)); /// assert!(u16::try_from(ninjas).is_err()); /// ``` @@ -151,7 +156,45 @@ impl const TryFrom for u16 { } } -/// Maps a byte in 0x00..=0xFF to a `char` whose code point has the same value, in U+0000..=U+00FF. +/// Maps a `char` with a code point from U+0000 to U+10FFFF (inclusive) to a `usize` in +/// `0x0000..=0x10FFFF` with the same value, failing if the final value is unrepresentable by +/// `usize`. +/// +/// Generally speaking, this conversion can be seen as obtaining the character's corresponding +/// UTF-32 code point to the extent representable by pointer addresses. +#[stable(feature = "usize_try_from_char", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_convert", issue = "143773")] +impl const TryFrom for usize { + type Error = TryFromCharError; + + /// Tries to convert a [`char`] into a [`usize`]. + /// + /// # Examples + /// + /// ``` + /// let a = '\u{FFFF}'; // Always succeeds. + /// let b = '\u{10FFFF}'; // Conditionally succeeds. + /// + /// assert_eq!(usize::try_from(a), Ok(0xFFFF)); + /// + /// if size_of::() >= size_of::() { + /// assert_eq!(usize::try_from(b), Ok(0x10FFFF)); + /// } else { + /// assert!(matches!(usize::try_from(b), Err(_))); + /// } + /// ``` + #[inline] + fn try_from(c: char) -> Result { + // FIXME(const-hack): this should use map_err instead + match usize::try_from(u32::from(c)) { + Ok(x) => Ok(x), + Err(_) => Err(TryFromCharError(())), + } + } +} + +/// Maps a byte in `0x00..=0xFF` to a `char` whose code point has the same value from U+0000 to U+00FF +/// (inclusive). /// /// Unicode is designed such that this effectively decodes bytes /// with the character encoding that IANA calls ISO-8859-1. @@ -179,6 +222,7 @@ impl const From for char { /// ``` /// let u = 32 as u8; /// let c = char::from(u); + /// /// assert!(4 == size_of_val(&c)) /// ``` #[inline] @@ -246,7 +290,6 @@ const fn char_try_from_u32(i: u32) -> Result { // Subtracting 0x800 causes 0x0000..0x0800 to wrap, meaning that a single // unsigned comparison against 0x110000 - 0x800 will detect both the wrapped // surrogate range as well as the numbers originally larger than 0x110000. - // if (i ^ 0xD800).wrapping_sub(0x800) >= 0x110000 - 0x800 { Err(CharTryFromError(())) } else { From 7ee7d446bf8205c196a4a5a42edef23938ede5c9 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Mon, 29 Dec 2025 02:47:53 -0800 Subject: [PATCH 1376/3801] add has_offload/needs-offload to the test infra --- src/bootstrap/src/core/build_steps/test.rs | 4 ++++ src/doc/rustc-dev-guide/src/tests/directives.md | 1 + src/tools/compiletest/src/common.rs | 3 +++ src/tools/compiletest/src/directives/cfg.rs | 1 + src/tools/compiletest/src/directives/directive_names.rs | 1 + src/tools/compiletest/src/directives/needs.rs | 5 +++++ src/tools/compiletest/src/lib.rs | 3 +++ src/tools/compiletest/src/rustdoc_gui_test.rs | 1 + 8 files changed, 19 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index a58739c9e65c..a3c13fc4b095 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2064,6 +2064,10 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--has-enzyme"); } + if builder.build.config.llvm_offload { + cmd.arg("--has-offload"); + } + if builder.config.cmd.bless() { cmd.arg("--bless"); } diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index c8b0072dc101..6cecf7f47fd6 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -213,6 +213,7 @@ settings: that this directive can be overriden with the `--bypass-ignore-backends=[BACKEND]` command line flag. - `needs-backends` — only runs the test if current codegen backend is listed. +- `needs-offload` — ignores if our LLVM backend was not built with offload support. The following directives will check LLVM support: diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 9473e51688cb..5563abe92a80 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -625,6 +625,9 @@ pub struct Config { /// Whether to run `enzyme` autodiff tests. pub has_enzyme: bool, + /// Whether to run `offload` autodiff tests. + pub has_offload: bool, + /// The current Rust channel info. /// /// FIXME: treat this more carefully; "stable", "beta" and "nightly" are definitely valid, but diff --git a/src/tools/compiletest/src/directives/cfg.rs b/src/tools/compiletest/src/directives/cfg.rs index e89c1330f467..6431eb6b090b 100644 --- a/src/tools/compiletest/src/directives/cfg.rs +++ b/src/tools/compiletest/src/directives/cfg.rs @@ -164,6 +164,7 @@ pub(crate) fn prepare_conditions(config: &Config) -> PreparedConditions { // FIXME(Zalathar): Support all known binary formats, not just ELF? builder.cond("elf", current.binary_format == "elf", "when the target binary format is ELF"); builder.cond("enzyme", config.has_enzyme, "when rustc is built with LLVM Enzyme"); + builder.cond("offload", config.has_offload, "when rustc is built with LLVM Offload"); // Technically the locally built compiler uses the "dev" channel rather than the "nightly" // channel, even though most people don't know or won't care about it. To avoid confusion, we diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index 282e2a131d93..9813ac7ff500 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -165,6 +165,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-git-hash", "needs-llvm-components", "needs-llvm-zstd", + "needs-offload", "needs-profiler-runtime", "needs-relocation-model-pic", "needs-run-enabled", diff --git a/src/tools/compiletest/src/directives/needs.rs b/src/tools/compiletest/src/directives/needs.rs index 36c2ca62cd87..32ce6cf7b989 100644 --- a/src/tools/compiletest/src/directives/needs.rs +++ b/src/tools/compiletest/src/directives/needs.rs @@ -91,6 +91,11 @@ pub(super) fn handle_needs( condition: config.has_enzyme && config.default_codegen_backend.is_llvm(), ignore_reason: "ignored when LLVM Enzyme is disabled or LLVM is not the default codegen backend", }, + Need { + name: "needs-offload", + condition: config.has_offload && config.default_codegen_backend.is_llvm(), + ignore_reason: "ignored when LLVM Offload is disabled or LLVM is not the default codegen backend", + }, Need { name: "needs-run-enabled", condition: config.run_enabled(), diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 83aee865e010..a64c7850aad4 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -104,6 +104,7 @@ fn parse_config(args: Vec) -> Config { .optopt("", "run", "whether to execute run-* tests", "auto | always | never") .optflag("", "ignored", "run tests marked as ignored") .optflag("", "has-enzyme", "run tests that require enzyme") + .optflag("", "has-offload", "run tests that require offload") .optflag("", "with-rustc-debug-assertions", "whether rustc was built with debug assertions") .optflag("", "with-std-debug-assertions", "whether std was built with debug assertions") .optflag("", "with-std-remap-debuginfo", "whether std was built with remapping") @@ -299,6 +300,7 @@ fn parse_config(args: Vec) -> Config { let with_std_remap_debuginfo = matches.opt_present("with-std-remap-debuginfo"); let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode"); let has_enzyme = matches.opt_present("has-enzyme"); + let has_offload = matches.opt_present("has-offload"); let filters = if mode == TestMode::RunMake { matches .free @@ -444,6 +446,7 @@ fn parse_config(args: Vec) -> Config { compare_mode, rustfix_coverage: matches.opt_present("rustfix-coverage"), has_enzyme, + has_offload, channel: matches.opt_str("channel").unwrap(), git_hash: matches.opt_present("git-hash"), edition: matches.opt_str("edition").as_deref().map(parse_edition), diff --git a/src/tools/compiletest/src/rustdoc_gui_test.rs b/src/tools/compiletest/src/rustdoc_gui_test.rs index 2b057bb35519..4454ffb1f59e 100644 --- a/src/tools/compiletest/src/rustdoc_gui_test.rs +++ b/src/tools/compiletest/src/rustdoc_gui_test.rs @@ -113,6 +113,7 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { compare_mode: Default::default(), rustfix_coverage: Default::default(), has_enzyme: Default::default(), + has_offload: Default::default(), channel: Default::default(), git_hash: Default::default(), cc: Default::default(), From 6e0b610049fb9e78f8d319d0aea45394a1f8654b Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Mon, 29 Dec 2025 02:48:36 -0800 Subject: [PATCH 1377/3801] document the needs-enzyme flag --- src/doc/rustc-dev-guide/src/tests/directives.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 6cecf7f47fd6..4852c3623b05 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -214,6 +214,7 @@ settings: flag. - `needs-backends` — only runs the test if current codegen backend is listed. - `needs-offload` — ignores if our LLVM backend was not built with offload support. +- `needs-enzyme` — ignores if our Enzyme submodule was not built. The following directives will check LLVM support: From a6c2e50e8241d9e86fb428f163f03f8e8ea4feb6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 29 Dec 2025 12:58:15 +0100 Subject: [PATCH 1378/3801] fix ICE for particular data race situations --- src/tools/miri/src/concurrency/data_race.rs | 7 +++-- .../miri/src/concurrency/vector_clock.rs | 12 ++++++++- .../data_race/mixed_size_read_write_read.rs | 27 +++++++++++++++++++ .../mixed_size_read_write_read.stderr | 26 ++++++++++++++++++ 4 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.rs create mode 100644 src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 75c1d0f6a798..c18b78099860 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -1116,6 +1116,7 @@ impl VClockAlloc { { (AccessType::AtomicStore, idx, &atomic.write_vector) } else if !access.is_atomic() && + !access.is_read() && let Some(atomic) = mem_clocks.atomic() && let Some(idx) = Self::find_gt_index(&atomic.read_vector, &active_clocks.clock) { @@ -1124,7 +1125,7 @@ impl VClockAlloc { } else if mem_clocks.write.1 > active_clocks.clock[mem_clocks.write.0] { write_clock = mem_clocks.write(); (AccessType::NaWrite(mem_clocks.write_type), mem_clocks.write.0, &write_clock) - } else if let Some(idx) = Self::find_gt_index(&mem_clocks.read, &active_clocks.clock) { + } else if !access.is_read() && let Some(idx) = Self::find_gt_index(&mem_clocks.read, &active_clocks.clock) { (AccessType::NaRead(mem_clocks.read[idx].read_type()), idx, &mem_clocks.read) // Finally, mixed-size races. } else if access.is_atomic() && let Some(atomic) = mem_clocks.atomic() && atomic.size != Some(access_size) { @@ -1157,7 +1158,9 @@ impl VClockAlloc { assert!(!involves_non_atomic); Some("overlapping unsynchronized atomic accesses must use the same access size") } else if access.is_read() && other_access.is_read() { - panic!("there should be no same-size read-read races") + panic!( + "there should be no same-size read-read races\naccess: {access:?}\nother_access: {other_access:?}" + ) } else { None }; diff --git a/src/tools/miri/src/concurrency/vector_clock.rs b/src/tools/miri/src/concurrency/vector_clock.rs index 494e7922d2b2..d7ea3b0c6ce3 100644 --- a/src/tools/miri/src/concurrency/vector_clock.rs +++ b/src/tools/miri/src/concurrency/vector_clock.rs @@ -48,7 +48,7 @@ const SMALL_VECTOR: usize = 4; /// The time-stamps recorded in the data-race detector consist of both /// a 32-bit unsigned integer which is the actual timestamp, and a `Span` /// so that diagnostics can report what code was responsible for an operation. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy)] pub(super) struct VTimestamp { /// The lowest bit indicates read type, the rest is the time. /// `1` indicates a retag read, `0` a regular read. @@ -56,6 +56,16 @@ pub(super) struct VTimestamp { pub span: Span, } +impl Debug for VTimestamp { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("VTimestamp") + .field("time", &self.time()) + .field("read_type", &self.read_type()) + .field("span", &self.span) + .finish() + } +} + impl VTimestamp { pub const ZERO: VTimestamp = VTimestamp::new(0, NaReadType::Read, DUMMY_SP); diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.rs b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.rs new file mode 100644 index 000000000000..c84895799b69 --- /dev/null +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.rs @@ -0,0 +1,27 @@ +//@compile-flags: -Zmiri-deterministic-concurrency +// A case that is not covered by `mixed_size_read_write`. +#![feature(ptr_as_ref_unchecked)] + +use std::sync::atomic::*; +use std::thread; + +fn main() { + let data = AtomicI32::new(0); + + thread::scope(|s| { + s.spawn(|| unsafe { + let _val = (&raw const data).read(); + let _val = (&raw const data).cast::().as_ref_unchecked().compare_exchange( + 0, + 1, + Ordering::Relaxed, + Ordering::Relaxed, + ); + thread::yield_now(); + unreachable!(); + }); + s.spawn(|| { + let _val = data.load(Ordering::Relaxed); //~ERROR: /Race condition detected between \(1\) 1-byte atomic store .* and \(2\) 4-byte atomic load/ + }); + }); +} diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr new file mode 100644 index 000000000000..f1884bf404f1 --- /dev/null +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr @@ -0,0 +1,26 @@ +error: Undefined Behavior: Race condition detected between (1) 1-byte atomic store on thread `unnamed-ID` and (2) 4-byte atomic load on thread `unnamed-ID` at ALLOC + --> tests/fail/data_race/mixed_size_read_write_read.rs:LL:CC + | +LL | ... let _val = data.load(Ordering::Relaxed); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (2) just happened here + | +help: and (1) occurred earlier here + --> tests/fail/data_race/mixed_size_read_write_read.rs:LL:CC + | +LL | let _val = (&raw const data).cast::().as_ref_unchecked().compare_exchange( + | ________________________^ +LL | | 0, +LL | | 1, +LL | | Ordering::Relaxed, +LL | | Ordering::Relaxed, +LL | | ); + | |_____________^ + = help: overlapping unsynchronized atomic accesses must use the same access size + = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model + = 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 + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From cfd859a99fa7a0879922bc4af05ba478ed1d8728 Mon Sep 17 00:00:00 2001 From: Jan Sommer Date: Mon, 29 Dec 2025 12:48:53 +0100 Subject: [PATCH 1379/3801] Mark set_times as unavailable for RTEMS target --- library/std/src/sys/fs/unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index de80f2ed053f..f1b976c61b5b 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -2166,7 +2166,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> fn set_times_impl(p: &CStr, times: FileTimes, follow_symlinks: bool) -> io::Result<()> { cfg_select! { - any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "vita") => { + any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "vita", target_os = "rtems") => { let _ = (p, times, follow_symlinks); Err(io::const_error!( io::ErrorKind::Unsupported, From 440bf4ded9c7bcc9e597d914c5883ac04edb9b5e Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Mon, 8 Dec 2025 18:24:51 +0100 Subject: [PATCH 1380/3801] =?UTF-8?q?`crate::io::Result`=20=E2=86=92=20`io?= =?UTF-8?q?::Result`=20in=20most=20places?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I don't know why many places refer to the type as `crate::io::Result` when `crate::io` is already imported. --- library/std/src/os/fd/owned.rs | 12 ++-- library/std/src/os/solid/io.rs | 8 +-- library/std/src/os/unix/net/addr.rs | 2 +- library/std/src/os/windows/io/handle.rs | 18 ++--- library/std/src/sys/pal/hermit/mod.rs | 51 +++++++-------- library/std/src/sys/pal/itron/error.rs | 35 +++++----- library/std/src/sys/pal/motor/mod.rs | 65 +++++++++---------- .../std/src/sys/pal/sgx/abi/usercalls/mod.rs | 42 ++++++------ library/std/src/sys/pal/sgx/mod.rs | 54 +++++++-------- library/std/src/sys/pal/sgx/thread_parking.rs | 4 +- library/std/src/sys/pal/solid/error.rs | 20 +++--- library/std/src/sys/pal/solid/mod.rs | 10 +-- library/std/src/sys/pal/teeos/mod.rs | 25 ++++--- library/std/src/sys/pal/uefi/mod.rs | 60 ++++++++--------- library/std/src/sys/pal/uefi/os.rs | 6 +- library/std/src/sys/pal/unix/mod.rs | 16 ++--- library/std/src/sys/pal/unix/os.rs | 15 ++--- library/std/src/sys/pal/wasi/os.rs | 2 +- library/std/src/sys/pal/windows/handle.rs | 6 +- library/std/src/sys/pal/windows/mod.rs | 34 +++++----- library/std/src/thread/builder.rs | 4 -- library/std/src/thread/scoped.rs | 2 - 22 files changed, 237 insertions(+), 254 deletions(-) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 846ad37aad22..2acac6f086e4 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -91,7 +91,7 @@ impl OwnedFd { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `OwnedFd` instance. #[stable(feature = "io_safety", since = "1.63.0")] - pub fn try_clone(&self) -> crate::io::Result { + pub fn try_clone(&self) -> io::Result { self.as_fd().try_clone_to_owned() } } @@ -106,7 +106,7 @@ impl BorrowedFd<'_> { target_os = "motor" )))] #[stable(feature = "io_safety", since = "1.63.0")] - pub fn try_clone_to_owned(&self) -> crate::io::Result { + pub fn try_clone_to_owned(&self) -> io::Result { // We want to atomically duplicate this file descriptor and set the // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This // is a POSIX flag that was added to Linux in 2.6.24. @@ -129,15 +129,15 @@ impl BorrowedFd<'_> { /// description as the existing `BorrowedFd` instance. #[cfg(any(target_arch = "wasm32", target_os = "hermit", target_os = "trusty"))] #[stable(feature = "io_safety", since = "1.63.0")] - pub fn try_clone_to_owned(&self) -> crate::io::Result { - Err(crate::io::Error::UNSUPPORTED_PLATFORM) + pub fn try_clone_to_owned(&self) -> io::Result { + Err(io::Error::UNSUPPORTED_PLATFORM) } /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `BorrowedFd` instance. #[cfg(target_os = "motor")] #[stable(feature = "io_safety", since = "1.63.0")] - pub fn try_clone_to_owned(&self) -> crate::io::Result { + pub fn try_clone_to_owned(&self) -> io::Result { let fd = moto_rt::fs::duplicate(self.as_raw_fd()).map_err(crate::sys::map_motor_error)?; Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } @@ -233,7 +233,7 @@ macro_rules! impl_is_terminal { impl crate::sealed::Sealed for $t {} #[stable(feature = "is_terminal", since = "1.70.0")] - impl crate::io::IsTerminal for $t { + impl io::IsTerminal for $t { #[inline] fn is_terminal(&self) -> bool { crate::sys::io::is_terminal(self) diff --git a/library/std/src/os/solid/io.rs b/library/std/src/os/solid/io.rs index a1c8a86c9861..ac112e739170 100644 --- a/library/std/src/os/solid/io.rs +++ b/library/std/src/os/solid/io.rs @@ -49,7 +49,7 @@ use crate::marker::PhantomData; use crate::mem::ManuallyDrop; use crate::sys::{AsInner, FromInner, IntoInner}; -use crate::{fmt, net, sys}; +use crate::{fmt, io, net, sys}; /// Raw file descriptors. pub type RawFd = i32; @@ -110,7 +110,7 @@ impl BorrowedFd<'_> { impl OwnedFd { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `OwnedFd` instance. - pub fn try_clone(&self) -> crate::io::Result { + pub fn try_clone(&self) -> io::Result { self.as_fd().try_clone_to_owned() } } @@ -118,7 +118,7 @@ impl OwnedFd { impl BorrowedFd<'_> { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `BorrowedFd` instance. - pub fn try_clone_to_owned(&self) -> crate::io::Result { + pub fn try_clone_to_owned(&self) -> io::Result { let fd = sys::net::cvt(unsafe { crate::sys::abi::sockets::dup(self.as_raw_fd()) })?; Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } @@ -184,7 +184,7 @@ macro_rules! impl_is_terminal { impl crate::sealed::Sealed for $t {} #[stable(feature = "is_terminal", since = "1.70.0")] - impl crate::io::IsTerminal for $t { + impl io::IsTerminal for $t { #[inline] fn is_terminal(&self) -> bool { crate::sys::io::is_terminal(self) diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 25b95014e08b..0748f6984a82 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -264,7 +264,7 @@ impl linux_ext::addr::SocketAddrExt for SocketAddr { if let AddressKind::Abstract(name) = self.address() { Some(name.as_bytes()) } else { None } } - fn from_abstract_name(name: N) -> crate::io::Result + fn from_abstract_name(name: N) -> io::Result where N: AsRef<[u8]>, { diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index afc58ca59cfa..13c0752b560b 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -184,7 +184,7 @@ impl OwnedHandle { /// Creates a new `OwnedHandle` instance that shares the same underlying /// object as the existing `OwnedHandle` instance. #[stable(feature = "io_safety", since = "1.63.0")] - pub fn try_clone(&self) -> crate::io::Result { + pub fn try_clone(&self) -> io::Result { self.as_handle().try_clone_to_owned() } } @@ -193,7 +193,7 @@ impl BorrowedHandle<'_> { /// Creates a new `OwnedHandle` instance that shares the same underlying /// object as the existing `BorrowedHandle` instance. #[stable(feature = "io_safety", since = "1.63.0")] - pub fn try_clone_to_owned(&self) -> crate::io::Result { + pub fn try_clone_to_owned(&self) -> io::Result { self.duplicate(0, false, sys::c::DUPLICATE_SAME_ACCESS) } @@ -409,7 +409,7 @@ macro_rules! impl_is_terminal { impl crate::sealed::Sealed for $t {} #[stable(feature = "is_terminal", since = "1.70.0")] - impl crate::io::IsTerminal for $t { + impl io::IsTerminal for $t { #[inline] fn is_terminal(&self) -> bool { crate::sys::io::is_terminal(self) @@ -546,7 +546,7 @@ impl From for fs::File { } #[stable(feature = "io_safety", since = "1.63.0")] -impl AsHandle for crate::io::Stdin { +impl AsHandle for io::Stdin { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } @@ -554,7 +554,7 @@ impl AsHandle for crate::io::Stdin { } #[stable(feature = "io_safety", since = "1.63.0")] -impl<'a> AsHandle for crate::io::StdinLock<'a> { +impl<'a> AsHandle for io::StdinLock<'a> { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } @@ -562,7 +562,7 @@ impl<'a> AsHandle for crate::io::StdinLock<'a> { } #[stable(feature = "io_safety", since = "1.63.0")] -impl AsHandle for crate::io::Stdout { +impl AsHandle for io::Stdout { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } @@ -570,7 +570,7 @@ impl AsHandle for crate::io::Stdout { } #[stable(feature = "io_safety", since = "1.63.0")] -impl<'a> AsHandle for crate::io::StdoutLock<'a> { +impl<'a> AsHandle for io::StdoutLock<'a> { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } @@ -578,7 +578,7 @@ impl<'a> AsHandle for crate::io::StdoutLock<'a> { } #[stable(feature = "io_safety", since = "1.63.0")] -impl AsHandle for crate::io::Stderr { +impl AsHandle for io::Stderr { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } @@ -586,7 +586,7 @@ impl AsHandle for crate::io::Stderr { } #[stable(feature = "io_safety", since = "1.63.0")] -impl<'a> AsHandle for crate::io::StderrLock<'a> { +impl<'a> AsHandle for io::StderrLock<'a> { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index 52bcd8da2420..0e1328a7972f 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -16,7 +16,7 @@ #![deny(unsafe_op_in_unsafe_fn)] #![allow(missing_docs, nonstandard_style)] -use crate::io::ErrorKind; +use crate::io; use crate::os::hermit::hermit_abi; use crate::os::raw::c_char; use crate::sys::env; @@ -25,15 +25,12 @@ pub mod futex; pub mod os; pub mod time; -pub fn unsupported() -> crate::io::Result { +pub fn unsupported() -> io::Result { Err(unsupported_err()) } -pub fn unsupported_err() -> crate::io::Error { - crate::io::const_error!( - crate::io::ErrorKind::Unsupported, - "operation not supported on HermitCore yet", - ) +pub fn unsupported_err() -> io::Error { + io::const_error!(io::ErrorKind::Unsupported, "operation not supported on HermitCore yet") } pub fn abort_internal() -> ! { @@ -83,24 +80,24 @@ pub(crate) fn is_interrupted(errno: i32) -> bool { errno == hermit_abi::errno::EINTR } -pub fn decode_error_kind(errno: i32) -> ErrorKind { +pub fn decode_error_kind(errno: i32) -> io::ErrorKind { match errno { - hermit_abi::errno::EACCES => ErrorKind::PermissionDenied, - hermit_abi::errno::EADDRINUSE => ErrorKind::AddrInUse, - hermit_abi::errno::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, - hermit_abi::errno::EAGAIN => ErrorKind::WouldBlock, - hermit_abi::errno::ECONNABORTED => ErrorKind::ConnectionAborted, - hermit_abi::errno::ECONNREFUSED => ErrorKind::ConnectionRefused, - hermit_abi::errno::ECONNRESET => ErrorKind::ConnectionReset, - hermit_abi::errno::EEXIST => ErrorKind::AlreadyExists, - hermit_abi::errno::EINTR => ErrorKind::Interrupted, - hermit_abi::errno::EINVAL => ErrorKind::InvalidInput, - hermit_abi::errno::ENOENT => ErrorKind::NotFound, - hermit_abi::errno::ENOTCONN => ErrorKind::NotConnected, - hermit_abi::errno::EPERM => ErrorKind::PermissionDenied, - hermit_abi::errno::EPIPE => ErrorKind::BrokenPipe, - hermit_abi::errno::ETIMEDOUT => ErrorKind::TimedOut, - _ => ErrorKind::Uncategorized, + hermit_abi::errno::EACCES => io::ErrorKind::PermissionDenied, + hermit_abi::errno::EADDRINUSE => io::ErrorKind::AddrInUse, + hermit_abi::errno::EADDRNOTAVAIL => io::ErrorKind::AddrNotAvailable, + hermit_abi::errno::EAGAIN => io::ErrorKind::WouldBlock, + hermit_abi::errno::ECONNABORTED => io::ErrorKind::ConnectionAborted, + hermit_abi::errno::ECONNREFUSED => io::ErrorKind::ConnectionRefused, + hermit_abi::errno::ECONNRESET => io::ErrorKind::ConnectionReset, + hermit_abi::errno::EEXIST => io::ErrorKind::AlreadyExists, + hermit_abi::errno::EINTR => io::ErrorKind::Interrupted, + hermit_abi::errno::EINVAL => io::ErrorKind::InvalidInput, + hermit_abi::errno::ENOENT => io::ErrorKind::NotFound, + hermit_abi::errno::ENOTCONN => io::ErrorKind::NotConnected, + hermit_abi::errno::EPERM => io::ErrorKind::PermissionDenied, + hermit_abi::errno::EPIPE => io::ErrorKind::BrokenPipe, + hermit_abi::errno::ETIMEDOUT => io::ErrorKind::TimedOut, + _ => io::ErrorKind::Uncategorized, } } @@ -133,16 +130,16 @@ impl IsNegative for i32 { } impl_is_negative! { i8 i16 i64 isize } -pub fn cvt(t: T) -> crate::io::Result { +pub fn cvt(t: T) -> io::Result { if t.is_negative() { let e = decode_error_kind(t.negate()); - Err(crate::io::Error::from(e)) + Err(io::Error::from(e)) } else { Ok(t) } } -pub fn cvt_r(mut f: F) -> crate::io::Result +pub fn cvt_r(mut f: F) -> io::Result where T: IsNegative, F: FnMut() -> T, diff --git a/library/std/src/sys/pal/itron/error.rs b/library/std/src/sys/pal/itron/error.rs index 8ff3017c6147..87be7d5b3546 100644 --- a/library/std/src/sys/pal/itron/error.rs +++ b/library/std/src/sys/pal/itron/error.rs @@ -1,6 +1,5 @@ use super::abi; -use crate::fmt; -use crate::io::ErrorKind; +use crate::{fmt, io}; /// Wraps a μITRON error code. #[derive(Debug, Copy, Clone)] @@ -84,39 +83,39 @@ pub fn is_interrupted(er: abi::ER) -> bool { er == abi::E_RLWAI } -pub fn decode_error_kind(er: abi::ER) -> ErrorKind { +pub fn decode_error_kind(er: abi::ER) -> io::ErrorKind { match er { // Success - er if er >= 0 => ErrorKind::Uncategorized, + er if er >= 0 => io::ErrorKind::Uncategorized, // μITRON 4.0 // abi::E_SYS - abi::E_NOSPT => ErrorKind::Unsupported, // Some("unsupported function"), - abi::E_RSFN => ErrorKind::InvalidInput, // Some("reserved function code"), - abi::E_RSATR => ErrorKind::InvalidInput, // Some("reserved attribute"), - abi::E_PAR => ErrorKind::InvalidInput, // Some("parameter error"), - abi::E_ID => ErrorKind::NotFound, // Some("invalid ID number"), + abi::E_NOSPT => io::ErrorKind::Unsupported, // Some("unsupported function"), + abi::E_RSFN => io::ErrorKind::InvalidInput, // Some("reserved function code"), + abi::E_RSATR => io::ErrorKind::InvalidInput, // Some("reserved attribute"), + abi::E_PAR => io::ErrorKind::InvalidInput, // Some("parameter error"), + abi::E_ID => io::ErrorKind::NotFound, // Some("invalid ID number"), // abi::E_CTX - abi::E_MACV => ErrorKind::PermissionDenied, // Some("memory access violation"), - abi::E_OACV => ErrorKind::PermissionDenied, // Some("object access violation"), + abi::E_MACV => io::ErrorKind::PermissionDenied, // Some("memory access violation"), + abi::E_OACV => io::ErrorKind::PermissionDenied, // Some("object access violation"), // abi::E_ILUSE - abi::E_NOMEM => ErrorKind::OutOfMemory, // Some("insufficient memory"), - abi::E_NOID => ErrorKind::OutOfMemory, // Some("no ID number available"), + abi::E_NOMEM => io::ErrorKind::OutOfMemory, // Some("insufficient memory"), + abi::E_NOID => io::ErrorKind::OutOfMemory, // Some("no ID number available"), // abi::E_OBJ - abi::E_NOEXS => ErrorKind::NotFound, // Some("non-existent object"), + abi::E_NOEXS => io::ErrorKind::NotFound, // Some("non-existent object"), // abi::E_QOVR - abi::E_RLWAI => ErrorKind::Interrupted, // Some("forced release from waiting"), - abi::E_TMOUT => ErrorKind::TimedOut, // Some("polling failure or timeout"), + abi::E_RLWAI => io::ErrorKind::Interrupted, // Some("forced release from waiting"), + abi::E_TMOUT => io::ErrorKind::TimedOut, // Some("polling failure or timeout"), // abi::E_DLT // abi::E_CLS // abi::E_WBLK // abi::E_BOVR // The TOPPERS third generation kernels - abi::E_NORES => ErrorKind::OutOfMemory, // Some("insufficient system resources"), + abi::E_NORES => io::ErrorKind::OutOfMemory, // Some("insufficient system resources"), // abi::E_RASTER // abi::E_COMM - _ => ErrorKind::Uncategorized, + _ => io::ErrorKind::Uncategorized, } } diff --git a/library/std/src/sys/pal/motor/mod.rs b/library/std/src/sys/pal/motor/mod.rs index e4860b1542f0..016fbe5c154c 100644 --- a/library/std/src/sys/pal/motor/mod.rs +++ b/library/std/src/sys/pal/motor/mod.rs @@ -5,12 +5,11 @@ pub mod time; pub use moto_rt::futex; -use crate::io as std_io; -use crate::sys::io::RawOsError; +use crate::io; -pub(crate) fn map_motor_error(err: moto_rt::Error) -> crate::io::Error { +pub(crate) fn map_motor_error(err: moto_rt::Error) -> io::Error { let error_code: moto_rt::ErrorCode = err.into(); - crate::io::Error::from_raw_os_error(error_code.into()) + io::Error::from_raw_os_error(error_code.into()) } #[cfg(not(test))] @@ -37,50 +36,50 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {} // NOTE: this is not guaranteed to run, for example when the program aborts. pub unsafe fn cleanup() {} -pub fn unsupported() -> std_io::Result { +pub fn unsupported() -> io::Result { Err(unsupported_err()) } -pub fn unsupported_err() -> std_io::Error { - std_io::Error::UNSUPPORTED_PLATFORM +pub fn unsupported_err() -> io::Error { + io::Error::UNSUPPORTED_PLATFORM } -pub fn is_interrupted(_code: RawOsError) -> bool { +pub fn is_interrupted(_code: io::RawOsError) -> bool { false // Motor OS doesn't have signals. } -pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind { - use std_io::ErrorKind; +pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { + use moto_rt::error::*; if code < 0 || code > u16::MAX.into() { - return std_io::ErrorKind::Uncategorized; + return io::ErrorKind::Uncategorized; } let error = moto_rt::Error::from(code as moto_rt::ErrorCode); match error { - moto_rt::Error::Unspecified => ErrorKind::Uncategorized, - moto_rt::Error::Unknown => ErrorKind::Uncategorized, - moto_rt::Error::NotReady => ErrorKind::WouldBlock, - moto_rt::Error::NotImplemented => ErrorKind::Unsupported, - moto_rt::Error::VersionTooHigh => ErrorKind::Unsupported, - moto_rt::Error::VersionTooLow => ErrorKind::Unsupported, - moto_rt::Error::InvalidArgument => ErrorKind::InvalidInput, - moto_rt::Error::OutOfMemory => ErrorKind::OutOfMemory, - moto_rt::Error::NotAllowed => ErrorKind::PermissionDenied, - moto_rt::Error::NotFound => ErrorKind::NotFound, - moto_rt::Error::InternalError => ErrorKind::Other, - moto_rt::Error::TimedOut => ErrorKind::TimedOut, - moto_rt::Error::AlreadyInUse => ErrorKind::AlreadyExists, - moto_rt::Error::UnexpectedEof => ErrorKind::UnexpectedEof, - moto_rt::Error::InvalidFilename => ErrorKind::InvalidFilename, - moto_rt::Error::NotADirectory => ErrorKind::NotADirectory, - moto_rt::Error::BadHandle => ErrorKind::InvalidInput, - moto_rt::Error::FileTooLarge => ErrorKind::FileTooLarge, - moto_rt::Error::NotConnected => ErrorKind::NotConnected, - moto_rt::Error::StorageFull => ErrorKind::StorageFull, - moto_rt::Error::InvalidData => ErrorKind::InvalidData, - _ => crate::io::ErrorKind::Uncategorized, + moto_rt::Error::Unspecified => io::ErrorKind::Uncategorized, + moto_rt::Error::Unknown => io::ErrorKind::Uncategorized, + moto_rt::Error::NotReady => io::ErrorKind::WouldBlock, + moto_rt::Error::NotImplemented => io::ErrorKind::Unsupported, + moto_rt::Error::VersionTooHigh => io::ErrorKind::Unsupported, + moto_rt::Error::VersionTooLow => io::ErrorKind::Unsupported, + moto_rt::Error::InvalidArgument => io::ErrorKind::InvalidInput, + moto_rt::Error::OutOfMemory => io::ErrorKind::OutOfMemory, + moto_rt::Error::NotAllowed => io::ErrorKind::PermissionDenied, + moto_rt::Error::NotFound => io::ErrorKind::NotFound, + moto_rt::Error::InternalError => io::ErrorKind::Other, + moto_rt::Error::TimedOut => io::ErrorKind::TimedOut, + moto_rt::Error::AlreadyInUse => io::ErrorKind::AlreadyExists, + moto_rt::Error::UnexpectedEof => io::ErrorKind::UnexpectedEof, + moto_rt::Error::InvalidFilename => io::ErrorKind::InvalidFilename, + moto_rt::Error::NotADirectory => io::ErrorKind::NotADirectory, + moto_rt::Error::BadHandle => io::ErrorKind::InvalidInput, + moto_rt::Error::FileTooLarge => io::ErrorKind::FileTooLarge, + moto_rt::Error::NotConnected => io::ErrorKind::NotConnected, + moto_rt::Error::StorageFull => io::ErrorKind::StorageFull, + moto_rt::Error::InvalidData => io::ErrorKind::InvalidData, + _ => io::ErrorKind::Uncategorized, } } diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs index 5041770faf66..f49e940c5044 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs @@ -1,7 +1,5 @@ use crate::cmp; -use crate::io::{ - BorrowedCursor, Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult, -}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::random::random; use crate::time::{Duration, Instant}; @@ -18,7 +16,7 @@ use self::raw::*; /// This will do a single `read` usercall and scatter the read data among /// `bufs`. To read to a single buffer, just pass a slice of length one. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> IoResult { +pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> io::Result { unsafe { let total_len = bufs.iter().fold(0usize, |sum, buf| sum.saturating_add(buf.len())); let mut userbuf = alloc::User::<[u8]>::uninitialized(total_len); @@ -41,7 +39,7 @@ pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> IoResult { /// Usercall `read` with an uninitialized buffer. See the ABI documentation for /// more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_>) -> IoResult<()> { +pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_>) -> io::Result<()> { unsafe { let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.capacity()); let len = raw::read(fd, userbuf.as_mut_ptr().cast(), userbuf.len()).from_sgx_result()?; @@ -53,7 +51,7 @@ pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_>) -> IoResult<()> { /// Usercall `read_alloc`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn read_alloc(fd: Fd) -> IoResult> { +pub fn read_alloc(fd: Fd) -> io::Result> { unsafe { let userbuf = ByteBuffer { data: crate::ptr::null_mut(), len: 0 }; let mut userbuf = alloc::User::new_from_enclave(&userbuf); @@ -67,7 +65,7 @@ pub fn read_alloc(fd: Fd) -> IoResult> { /// This will do a single `write` usercall and gather the written data from /// `bufs`. To write from a single buffer, just pass a slice of length one. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn write(fd: Fd, bufs: &[IoSlice<'_>]) -> IoResult { +pub fn write(fd: Fd, bufs: &[IoSlice<'_>]) -> io::Result { unsafe { let total_len = bufs.iter().fold(0usize, |sum, buf| sum.saturating_add(buf.len())); let mut userbuf = alloc::User::<[u8]>::uninitialized(total_len); @@ -87,7 +85,7 @@ pub fn write(fd: Fd, bufs: &[IoSlice<'_>]) -> IoResult { /// Usercall `flush`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn flush(fd: Fd) -> IoResult<()> { +pub fn flush(fd: Fd) -> io::Result<()> { unsafe { raw::flush(fd).from_sgx_result() } } @@ -104,7 +102,7 @@ fn string_from_bytebuffer(buf: &alloc::UserRef, usercall: &str, arg: /// Usercall `bind_stream`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn bind_stream(addr: &str) -> IoResult<(Fd, String)> { +pub fn bind_stream(addr: &str) -> io::Result<(Fd, String)> { unsafe { let addr_user = alloc::User::new_from_enclave(addr.as_bytes()); let mut local = alloc::User::::uninitialized(); @@ -117,7 +115,7 @@ pub fn bind_stream(addr: &str) -> IoResult<(Fd, String)> { /// Usercall `accept_stream`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn accept_stream(fd: Fd) -> IoResult<(Fd, String, String)> { +pub fn accept_stream(fd: Fd) -> io::Result<(Fd, String, String)> { unsafe { let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized(); let mut buf_it = alloc::UserRef::iter_mut(&mut *bufs); // FIXME: can this be done @@ -133,7 +131,7 @@ pub fn accept_stream(fd: Fd) -> IoResult<(Fd, String, String)> { /// Usercall `connect_stream`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> { +pub fn connect_stream(addr: &str) -> io::Result<(Fd, String, String)> { unsafe { let addr_user = alloc::User::new_from_enclave(addr.as_bytes()); let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized(); @@ -155,7 +153,7 @@ pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> { /// Usercall `launch_thread`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub unsafe fn launch_thread() -> IoResult<()> { +pub unsafe fn launch_thread() -> io::Result<()> { // SAFETY: The caller must uphold the safety contract for `launch_thread`. unsafe { raw::launch_thread().from_sgx_result() } } @@ -168,7 +166,7 @@ pub fn exit(panic: bool) -> ! { /// Usercall `wait`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn wait(event_mask: u64, mut timeout: u64) -> IoResult { +pub fn wait(event_mask: u64, mut timeout: u64) -> io::Result { if timeout != WAIT_NO && timeout != WAIT_INDEFINITE { // We don't want people to rely on accuracy of timeouts to make // security decisions in an SGX enclave. That's why we add a random @@ -216,7 +214,9 @@ where true } Err(e) => { - rtassert!(e.kind() == ErrorKind::TimedOut || e.kind() == ErrorKind::WouldBlock); + rtassert!( + e.kind() == io::ErrorKind::TimedOut || e.kind() == io::ErrorKind::WouldBlock + ); false } } @@ -260,7 +260,7 @@ where /// Usercall `send`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn send(event_set: u64, tcs: Option) -> IoResult<()> { +pub fn send(event_set: u64, tcs: Option) -> io::Result<()> { unsafe { raw::send(event_set, tcs).from_sgx_result() } } @@ -273,7 +273,7 @@ pub fn insecure_time() -> Duration { /// Usercall `alloc`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] -pub fn alloc(size: usize, alignment: usize) -> IoResult<*mut u8> { +pub fn alloc(size: usize, alignment: usize) -> io::Result<*mut u8> { unsafe { raw::alloc(size, alignment).from_sgx_result() } } @@ -316,18 +316,18 @@ pub trait FromSgxResult { type Return; /// Translate the raw result of an SGX usercall. - fn from_sgx_result(self) -> IoResult; + fn from_sgx_result(self) -> io::Result; } #[unstable(feature = "sgx_platform", issue = "56975")] impl FromSgxResult for (Result, T) { type Return = T; - fn from_sgx_result(self) -> IoResult { + fn from_sgx_result(self) -> io::Result { if self.0 == RESULT_SUCCESS { Ok(self.1) } else { - Err(IoError::from_raw_os_error(check_os_error(self.0))) + Err(io::Error::from_raw_os_error(check_os_error(self.0))) } } } @@ -336,11 +336,11 @@ impl FromSgxResult for (Result, T) { impl FromSgxResult for Result { type Return = (); - fn from_sgx_result(self) -> IoResult { + fn from_sgx_result(self) -> io::Result { if self == RESULT_SUCCESS { Ok(()) } else { - Err(IoError::from_raw_os_error(check_os_error(self))) + Err(io::Error::from_raw_os_error(check_os_error(self))) } } } diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 7a207ceb329e..a067480508c7 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -5,7 +5,7 @@ #![deny(unsafe_op_in_unsafe_fn)] #![allow(fuzzy_provenance_casts)] // FIXME: this entire module systematically confuses pointers and integers -use crate::io::ErrorKind; +use crate::io; use crate::sync::atomic::{Atomic, AtomicBool, Ordering}; pub mod abi; @@ -29,12 +29,12 @@ pub unsafe fn cleanup() {} /// This function is used to implement functionality that simply doesn't exist. /// Programs relying on this functionality will need to deal with the error. -pub fn unsupported() -> crate::io::Result { +pub fn unsupported() -> io::Result { Err(unsupported_err()) } -pub fn unsupported_err() -> crate::io::Error { - crate::io::const_error!(ErrorKind::Unsupported, "operation not supported on SGX yet") +pub fn unsupported_err() -> io::Error { + io::const_error!(io::ErrorKind::Unsupported, "operation not supported on SGX yet") } /// This function is used to implement various functions that doesn't exist, @@ -42,11 +42,11 @@ pub fn unsupported_err() -> crate::io::Error { /// returned, the program might very well be able to function normally. This is /// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is /// `false`, the behavior is the same as `unsupported`. -pub fn sgx_ineffective(v: T) -> crate::io::Result { +pub fn sgx_ineffective(v: T) -> io::Result { static SGX_INEFFECTIVE_ERROR: Atomic = AtomicBool::new(false); if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) { - Err(crate::io::const_error!( - ErrorKind::Uncategorized, + Err(io::const_error!( + io::ErrorKind::Uncategorized, "operation can't be trusted to have any effect on SGX", )) } else { @@ -59,48 +59,48 @@ pub fn is_interrupted(code: i32) -> bool { code == fortanix_sgx_abi::Error::Interrupted as _ } -pub fn decode_error_kind(code: i32) -> ErrorKind { +pub fn decode_error_kind(code: i32) -> io::ErrorKind { use fortanix_sgx_abi::Error; // FIXME: not sure how to make sure all variants of Error are covered if code == Error::NotFound as _ { - ErrorKind::NotFound + io::ErrorKind::NotFound } else if code == Error::PermissionDenied as _ { - ErrorKind::PermissionDenied + io::ErrorKind::PermissionDenied } else if code == Error::ConnectionRefused as _ { - ErrorKind::ConnectionRefused + io::ErrorKind::ConnectionRefused } else if code == Error::ConnectionReset as _ { - ErrorKind::ConnectionReset + io::ErrorKind::ConnectionReset } else if code == Error::ConnectionAborted as _ { - ErrorKind::ConnectionAborted + io::ErrorKind::ConnectionAborted } else if code == Error::NotConnected as _ { - ErrorKind::NotConnected + io::ErrorKind::NotConnected } else if code == Error::AddrInUse as _ { - ErrorKind::AddrInUse + io::ErrorKind::AddrInUse } else if code == Error::AddrNotAvailable as _ { - ErrorKind::AddrNotAvailable + io::ErrorKind::AddrNotAvailable } else if code == Error::BrokenPipe as _ { - ErrorKind::BrokenPipe + io::ErrorKind::BrokenPipe } else if code == Error::AlreadyExists as _ { - ErrorKind::AlreadyExists + io::ErrorKind::AlreadyExists } else if code == Error::WouldBlock as _ { - ErrorKind::WouldBlock + io::ErrorKind::WouldBlock } else if code == Error::InvalidInput as _ { - ErrorKind::InvalidInput + io::ErrorKind::InvalidInput } else if code == Error::InvalidData as _ { - ErrorKind::InvalidData + io::ErrorKind::InvalidData } else if code == Error::TimedOut as _ { - ErrorKind::TimedOut + io::ErrorKind::TimedOut } else if code == Error::WriteZero as _ { - ErrorKind::WriteZero + io::ErrorKind::WriteZero } else if code == Error::Interrupted as _ { - ErrorKind::Interrupted + io::ErrorKind::Interrupted } else if code == Error::Other as _ { - ErrorKind::Uncategorized + io::ErrorKind::Uncategorized } else if code == Error::UnexpectedEof as _ { - ErrorKind::UnexpectedEof + io::ErrorKind::UnexpectedEof } else { - ErrorKind::Uncategorized + io::ErrorKind::Uncategorized } } diff --git a/library/std/src/sys/pal/sgx/thread_parking.rs b/library/std/src/sys/pal/sgx/thread_parking.rs index 660624ea9c3b..6510a3ab211f 100644 --- a/library/std/src/sys/pal/sgx/thread_parking.rs +++ b/library/std/src/sys/pal/sgx/thread_parking.rs @@ -1,7 +1,7 @@ use fortanix_sgx_abi::{EV_UNPARK, WAIT_INDEFINITE}; use super::abi::usercalls; -use crate::io::ErrorKind; +use crate::io; use crate::time::Duration; pub type ThreadId = fortanix_sgx_abi::Tcs; @@ -15,7 +15,7 @@ pub fn park(_hint: usize) { pub fn park_timeout(dur: Duration, _hint: usize) { let timeout = u128::min(dur.as_nanos(), WAIT_INDEFINITE as u128 - 1) as u64; if let Err(e) = usercalls::wait(EV_UNPARK, timeout) { - assert!(matches!(e.kind(), ErrorKind::TimedOut | ErrorKind::WouldBlock)) + assert!(matches!(e.kind(), io::ErrorKind::TimedOut | io::ErrorKind::WouldBlock)) } } diff --git a/library/std/src/sys/pal/solid/error.rs b/library/std/src/sys/pal/solid/error.rs index b399463c0c28..3e85cdb3c1d9 100644 --- a/library/std/src/sys/pal/solid/error.rs +++ b/library/std/src/sys/pal/solid/error.rs @@ -1,6 +1,6 @@ pub use self::itron::error::{ItronError as SolidError, expect_success}; use super::{abi, itron}; -use crate::io::ErrorKind; +use crate::io; use crate::sys::net; /// Describe the specified SOLID error code. Returns `None` if it's an @@ -31,23 +31,23 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> { } } -pub fn decode_error_kind(er: abi::ER) -> ErrorKind { +pub fn decode_error_kind(er: abi::ER) -> io::ErrorKind { match er { // Success - er if er >= 0 => ErrorKind::Uncategorized, + er if er >= 0 => io::ErrorKind::Uncategorized, er if er < abi::sockets::SOLID_NET_ERR_BASE => net::decode_error_kind(er), - abi::SOLID_ERR_NOTFOUND => ErrorKind::NotFound, - abi::SOLID_ERR_NOTSUPPORTED => ErrorKind::Unsupported, - abi::SOLID_ERR_EBADF => ErrorKind::InvalidInput, - abi::SOLID_ERR_INVALIDCONTENT => ErrorKind::InvalidData, + abi::SOLID_ERR_NOTFOUND => io::ErrorKind::NotFound, + abi::SOLID_ERR_NOTSUPPORTED => io::ErrorKind::Unsupported, + abi::SOLID_ERR_EBADF => io::ErrorKind::InvalidInput, + abi::SOLID_ERR_INVALIDCONTENT => io::ErrorKind::InvalidData, // abi::SOLID_ERR_NOTUSED // abi::SOLID_ERR_ALREADYUSED - abi::SOLID_ERR_OUTOFBOUND => ErrorKind::InvalidInput, + abi::SOLID_ERR_OUTOFBOUND => io::ErrorKind::InvalidInput, // abi::SOLID_ERR_BADSEQUENCE - abi::SOLID_ERR_UNKNOWNDEVICE => ErrorKind::NotFound, + abi::SOLID_ERR_UNKNOWNDEVICE => io::ErrorKind::NotFound, // abi::SOLID_ERR_BUSY - abi::SOLID_ERR_TIMEOUT => ErrorKind::TimedOut, + abi::SOLID_ERR_TIMEOUT => io::ErrorKind::TimedOut, // abi::SOLID_ERR_INVALIDACCESS // abi::SOLID_ERR_NOTREADY _ => itron::error::decode_error_kind(er), diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index 33df9116f5c2..01477c7dc5e9 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -2,6 +2,8 @@ #![allow(missing_docs, nonstandard_style)] #![forbid(unsafe_op_in_unsafe_fn)] +use crate::io; + pub mod abi; #[path = "../itron"] @@ -28,12 +30,12 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {} // SAFETY: must be called only once during runtime cleanup. pub unsafe fn cleanup() {} -pub fn unsupported() -> crate::io::Result { +pub fn unsupported() -> io::Result { Err(unsupported_err()) } -pub fn unsupported_err() -> crate::io::Error { - crate::io::Error::UNSUPPORTED_PLATFORM +pub fn unsupported_err() -> io::Error { + io::Error::UNSUPPORTED_PLATFORM } #[inline] @@ -41,7 +43,7 @@ pub fn is_interrupted(code: i32) -> bool { crate::sys::net::is_interrupted(code) } -pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind { +pub fn decode_error_kind(code: i32) -> io::ErrorKind { error::decode_error_kind(code) } diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index fe2dd9c6c493..627096b11c38 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -19,7 +19,7 @@ pub mod sync { pub use mutex::Mutex; } -use crate::io::ErrorKind; +use crate::io; pub fn abort_internal() -> ! { unsafe { libc::abort() } @@ -44,8 +44,8 @@ pub(crate) fn is_interrupted(errno: i32) -> bool { } // Note: code below is 1:1 copied from unix/mod.rs -pub fn decode_error_kind(errno: i32) -> ErrorKind { - use ErrorKind::*; +pub fn decode_error_kind(errno: i32) -> io::ErrorKind { + use io::ErrorKind::*; match errno as libc::c_int { libc::E2BIG => ArgumentListTooLong, libc::EADDRINUSE => AddrInUse, @@ -108,32 +108,31 @@ macro_rules! impl_is_minus_one { impl_is_minus_one! { i8 i16 i32 i64 isize } -pub fn cvt(t: T) -> crate::io::Result { - if t.is_minus_one() { Err(crate::io::Error::last_os_error()) } else { Ok(t) } +pub fn cvt(t: T) -> io::Result { + if t.is_minus_one() { Err(io::Error::last_os_error()) } else { Ok(t) } } -pub fn cvt_r(mut f: F) -> crate::io::Result +pub fn cvt_r(mut f: F) -> io::Result where T: IsMinusOne, F: FnMut() -> T, { loop { match cvt(f()) { - Err(ref e) if e.kind() == ErrorKind::Interrupted => {} + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} other => return other, } } } -pub fn cvt_nz(error: libc::c_int) -> crate::io::Result<()> { - if error == 0 { Ok(()) } else { Err(crate::io::Error::from_raw_os_error(error)) } +pub fn cvt_nz(error: libc::c_int) -> io::Result<()> { + if error == 0 { Ok(()) } else { Err(io::Error::from_raw_os_error(error)) } } -use crate::io as std_io; -pub fn unsupported() -> std_io::Result { +pub fn unsupported() -> io::Result { Err(unsupported_err()) } -pub fn unsupported_err() -> std_io::Error { - std_io::Error::UNSUPPORTED_PLATFORM +pub fn unsupported_err() -> io::Error { + io::Error::UNSUPPORTED_PLATFORM } diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index 61725b2ed048..e2f99d6751f5 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -13,8 +13,6 @@ //! [`OsString`]: crate::ffi::OsString #![forbid(unsafe_op_in_unsafe_fn)] -use crate::io::RawOsError; - pub mod helpers; pub mod os; pub mod time; @@ -22,7 +20,7 @@ pub mod time; #[cfg(test)] mod tests; -use crate::io as std_io; +use crate::io; use crate::os::uefi; use crate::ptr::NonNull; use crate::sync::atomic::{Atomic, AtomicPtr, Ordering}; @@ -76,20 +74,18 @@ pub unsafe fn cleanup() { } #[inline] -pub const fn unsupported() -> std_io::Result { +pub const fn unsupported() -> io::Result { Err(unsupported_err()) } #[inline] -pub const fn unsupported_err() -> std_io::Error { - std_io::const_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI") +pub const fn unsupported_err() -> io::Error { + io::const_error!(io::ErrorKind::Unsupported, "operation not supported on UEFI") } -pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind { +pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { use r_efi::efi::Status; - use crate::io::ErrorKind; - match r_efi::efi::Status::from_usize(code) { Status::ALREADY_STARTED | Status::COMPROMISED_DATA @@ -108,28 +104,28 @@ pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind { | Status::PROTOCOL_ERROR | Status::PROTOCOL_UNREACHABLE | Status::TFTP_ERROR - | Status::VOLUME_CORRUPTED => ErrorKind::Other, - Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => ErrorKind::InvalidData, - Status::ABORTED => ErrorKind::ConnectionAborted, - Status::ACCESS_DENIED => ErrorKind::PermissionDenied, - Status::BUFFER_TOO_SMALL => ErrorKind::FileTooLarge, - Status::CONNECTION_REFUSED => ErrorKind::ConnectionRefused, - Status::CONNECTION_RESET => ErrorKind::ConnectionReset, - Status::END_OF_FILE => ErrorKind::UnexpectedEof, - Status::HOST_UNREACHABLE => ErrorKind::HostUnreachable, - Status::INVALID_PARAMETER => ErrorKind::InvalidInput, - Status::IP_ADDRESS_CONFLICT => ErrorKind::AddrInUse, - Status::NETWORK_UNREACHABLE => ErrorKind::NetworkUnreachable, - Status::NO_RESPONSE => ErrorKind::HostUnreachable, - Status::NOT_FOUND => ErrorKind::NotFound, - Status::NOT_READY => ErrorKind::ResourceBusy, - Status::OUT_OF_RESOURCES => ErrorKind::OutOfMemory, - Status::SECURITY_VIOLATION => ErrorKind::PermissionDenied, - Status::TIMEOUT => ErrorKind::TimedOut, - Status::UNSUPPORTED => ErrorKind::Unsupported, - Status::VOLUME_FULL => ErrorKind::StorageFull, - Status::WRITE_PROTECTED => ErrorKind::ReadOnlyFilesystem, - _ => ErrorKind::Uncategorized, + | Status::VOLUME_CORRUPTED => io::ErrorKind::Other, + Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => io::ErrorKind::InvalidData, + Status::ABORTED => io::ErrorKind::ConnectionAborted, + Status::ACCESS_DENIED => io::ErrorKind::PermissionDenied, + Status::BUFFER_TOO_SMALL => io::ErrorKind::FileTooLarge, + Status::CONNECTION_REFUSED => io::ErrorKind::ConnectionRefused, + Status::CONNECTION_RESET => io::ErrorKind::ConnectionReset, + Status::END_OF_FILE => io::ErrorKind::UnexpectedEof, + Status::HOST_UNREACHABLE => io::ErrorKind::HostUnreachable, + Status::INVALID_PARAMETER => io::ErrorKind::InvalidInput, + Status::IP_ADDRESS_CONFLICT => io::ErrorKind::AddrInUse, + Status::NETWORK_UNREACHABLE => io::ErrorKind::NetworkUnreachable, + Status::NO_RESPONSE => io::ErrorKind::HostUnreachable, + Status::NOT_FOUND => io::ErrorKind::NotFound, + Status::NOT_READY => io::ErrorKind::ResourceBusy, + Status::OUT_OF_RESOURCES => io::ErrorKind::OutOfMemory, + Status::SECURITY_VIOLATION => io::ErrorKind::PermissionDenied, + Status::TIMEOUT => io::ErrorKind::TimedOut, + Status::UNSUPPORTED => io::ErrorKind::Unsupported, + Status::VOLUME_FULL => io::ErrorKind::StorageFull, + Status::WRITE_PROTECTED => io::ErrorKind::ReadOnlyFilesystem, + _ => io::ErrorKind::Uncategorized, } } @@ -163,6 +159,6 @@ extern "efiapi" fn exit_boot_service_handler(_e: r_efi::efi::Event, _ctx: *mut c uefi::env::disable_boot_services(); } -pub fn is_interrupted(_code: RawOsError) -> bool { +pub fn is_interrupted(_code: io::RawOsError) -> bool { false } diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs index aae6cb9e0646..5593e195178d 100644 --- a/library/std/src/sys/pal/uefi/os.rs +++ b/library/std/src/sys/pal/uefi/os.rs @@ -1,7 +1,7 @@ use r_efi::efi::Status; use r_efi::efi::protocols::{device_path, loaded_image_device_path}; -use super::{RawOsError, helpers, unsupported_err}; +use super::{helpers, unsupported_err}; use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; use crate::os::uefi; @@ -9,11 +9,11 @@ use crate::path::{self, PathBuf}; use crate::ptr::NonNull; use crate::{fmt, io}; -pub fn errno() -> RawOsError { +pub fn errno() -> io::RawOsError { 0 } -pub fn error_string(errno: RawOsError) -> String { +pub fn error_string(errno: io::RawOsError) -> String { // Keep the List in Alphabetical Order // The Messages are taken from UEFI Specification Appendix D - Status Codes #[rustfmt::skip] diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index a6c5decf2d34..f24898671af8 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -1,6 +1,6 @@ #![allow(missing_docs, nonstandard_style)] -use crate::io::ErrorKind; +use crate::io; #[cfg(target_os = "fuchsia")] pub mod fuchsia; @@ -229,8 +229,8 @@ pub(crate) fn is_interrupted(errno: i32) -> bool { errno == libc::EINTR } -pub fn decode_error_kind(errno: i32) -> ErrorKind { - use ErrorKind::*; +pub fn decode_error_kind(errno: i32) -> io::ErrorKind { + use io::ErrorKind::*; match errno as libc::c_int { libc::E2BIG => ArgumentListTooLong, libc::EADDRINUSE => AddrInUse, @@ -298,12 +298,12 @@ impl_is_minus_one! { i8 i16 i32 i64 isize } /// Converts native return values to Result using the *-1 means error is in `errno`* convention. /// Non-error values are `Ok`-wrapped. -pub fn cvt(t: T) -> crate::io::Result { - if t.is_minus_one() { Err(crate::io::Error::last_os_error()) } else { Ok(t) } +pub fn cvt(t: T) -> io::Result { + if t.is_minus_one() { Err(io::Error::last_os_error()) } else { Ok(t) } } /// `-1` → look at `errno` → retry on `EINTR`. Otherwise `Ok()`-wrap the closure return value. -pub fn cvt_r(mut f: F) -> crate::io::Result +pub fn cvt_r(mut f: F) -> io::Result where T: IsMinusOne, F: FnMut() -> T, @@ -318,8 +318,8 @@ where #[allow(dead_code)] // Not used on all platforms. /// Zero means `Ok()`, all other values are treated as raw OS errors. Does not look at `errno`. -pub fn cvt_nz(error: libc::c_int) -> crate::io::Result<()> { - if error == 0 { Ok(()) } else { Err(crate::io::Error::from_raw_os_error(error)) } +pub fn cvt_nz(error: libc::c_int) -> io::Result<()> { + if error == 0 { Ok(()) } else { Err(io::Error::from_raw_os_error(error)) } } // libc::abort() will run the SIGABRT handler. That's fine because anyone who diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 7c9f3b7992f7..edb7b604415b 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -244,10 +244,10 @@ pub fn current_exe() -> io::Result { #[cfg(not(test))] use crate::env; - use crate::io::ErrorKind; + use crate::io; let exe_path = env::args().next().ok_or(io::const_error!( - ErrorKind::NotFound, + io::ErrorKind::NotFound, "an executable path was not found because no arguments were provided through argv", ))?; let path = PathBuf::from(exe_path); @@ -272,7 +272,7 @@ pub fn current_exe() -> io::Result { } } } - Err(io::const_error!(ErrorKind::NotFound, "an executable path was not found")) + Err(io::const_error!(io::ErrorKind::NotFound, "an executable path was not found")) } #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] @@ -463,8 +463,7 @@ pub fn current_exe() -> io::Result { name.len(), ); if result != libc::B_OK { - use crate::io::ErrorKind; - Err(io::const_error!(ErrorKind::Uncategorized, "error getting executable path")) + Err(io::const_error!(io::ErrorKind::Uncategorized, "error getting executable path")) } else { // find_path adds the null terminator. let name = CStr::from_ptr(name.as_ptr()).to_bytes(); @@ -485,8 +484,7 @@ pub fn current_exe() -> io::Result { #[cfg(target_os = "l4re")] pub fn current_exe() -> io::Result { - use crate::io::ErrorKind; - Err(io::const_error!(ErrorKind::Unsupported, "not yet implemented!")) + Err(io::const_error!(io::ErrorKind::Unsupported, "not yet implemented!")) } #[cfg(target_os = "vxworks")] @@ -514,10 +512,9 @@ pub fn current_exe() -> io::Result { #[cfg(not(test))] use crate::env; - use crate::io::ErrorKind; let exe_path = env::args().next().ok_or(io::const_error!( - ErrorKind::Uncategorized, + io::ErrorKind::Uncategorized, "an executable path was not found because no arguments were provided through argv", ))?; let path = PathBuf::from(exe_path); diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs index 367c63dfc59e..a3bb329c2c4f 100644 --- a/library/std/src/sys/pal/wasi/os.rs +++ b/library/std/src/sys/pal/wasi/os.rs @@ -157,7 +157,7 @@ pub fn cvt(t: T) -> io::Result { if t.is_minus_one() { Err(io::Error::last_os_error()) } else { Ok(t) } } -pub fn cvt_r(mut f: F) -> crate::io::Result +pub fn cvt_r(mut f: F) -> io::Result where T: IsMinusOne, F: FnMut() -> T, diff --git a/library/std/src/sys/pal/windows/handle.rs b/library/std/src/sys/pal/windows/handle.rs index 90e243e1aa03..9b92cd79c06f 100644 --- a/library/std/src/sys/pal/windows/handle.rs +++ b/library/std/src/sys/pal/windows/handle.rs @@ -3,7 +3,7 @@ use core::ffi::c_void; use core::{cmp, mem, ptr}; -use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, Read}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read}; use crate::os::windows::io::{ AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle, }; @@ -83,7 +83,7 @@ impl Handle { // pipe semantics, which yields this error when *reading* from // a pipe after the other end has closed; we interpret that as // EOF on the pipe. - Err(ref e) if e.kind() == ErrorKind::BrokenPipe => Ok(0), + Err(ref e) if e.kind() == io::ErrorKind::BrokenPipe => Ok(0), Err(e) => Err(e), } @@ -126,7 +126,7 @@ impl Handle { // pipe semantics, which yields this error when *reading* from // a pipe after the other end has closed; we interpret that as // EOF on the pipe. - Err(ref e) if e.kind() == ErrorKind::BrokenPipe => Ok(()), + Err(ref e) if e.kind() == io::ErrorKind::BrokenPipe => Ok(()), Err(e) => Err(e), } diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 32bd6ea3a4f6..2db88d7e1fc3 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -2,7 +2,7 @@ #![forbid(unsafe_op_in_unsafe_fn)] use crate::ffi::{OsStr, OsString}; -use crate::io::ErrorKind; +use crate::io; use crate::mem::MaybeUninit; use crate::os::windows::ffi::{OsStrExt, OsStringExt}; use crate::path::PathBuf; @@ -32,13 +32,13 @@ cfg_select! { } pub mod winsock; -/// Map a [`Result`] to [`io::Result`](crate::io::Result). +/// Map a [`Result`] to [`io::Result`]. pub trait IoResult { - fn io_result(self) -> crate::io::Result; + fn io_result(self) -> io::Result; } impl IoResult for Result { - fn io_result(self) -> crate::io::Result { - self.map_err(|e| crate::io::Error::from_raw_os_error(e.code as i32)) + fn io_result(self) -> io::Result { + self.map_err(|e| io::Error::from_raw_os_error(e.code as i32)) } } @@ -65,8 +65,8 @@ pub fn is_interrupted(_errno: i32) -> bool { false } -pub fn decode_error_kind(errno: i32) -> ErrorKind { - use ErrorKind::*; +pub fn decode_error_kind(errno: i32) -> io::ErrorKind { + use io::ErrorKind::*; match errno as u32 { c::ERROR_ACCESS_DENIED => return PermissionDenied, @@ -167,8 +167,8 @@ pub fn unrolled_find_u16s(needle: u16, haystack: &[u16]) -> Option { None } -pub fn to_u16s>(s: S) -> crate::io::Result> { - fn inner(s: &OsStr) -> crate::io::Result> { +pub fn to_u16s>(s: S) -> io::Result> { + fn inner(s: &OsStr) -> io::Result> { // Most paths are ASCII, so reserve capacity for as much as there are bytes // in the OsStr plus one for the null-terminating character. We are not // wasting bytes here as paths created by this function are primarily used @@ -177,8 +177,8 @@ pub fn to_u16s>(s: S) -> crate::io::Result> { maybe_result.extend(s.encode_wide()); if unrolled_find_u16s(0, &maybe_result).is_some() { - return Err(crate::io::const_error!( - ErrorKind::InvalidInput, + return Err(io::const_error!( + io::ErrorKind::InvalidInput, "strings passed to WinAPI cannot contain NULs", )); } @@ -209,7 +209,7 @@ pub fn to_u16s>(s: S) -> crate::io::Result> { // Once the syscall has completed (errors bail out early) the second closure is // passed the data which has been read from the syscall. The return value // from this closure is then the return value of the function. -pub fn fill_utf16_buf(mut f1: F1, f2: F2) -> crate::io::Result +pub fn fill_utf16_buf(mut f1: F1, f2: F2) -> io::Result where F1: FnMut(*mut u16, u32) -> u32, F2: FnOnce(&[u16]) -> T, @@ -251,7 +251,7 @@ where c::SetLastError(0); let k = match f1(buf.as_mut_ptr().cast::(), n as u32) { 0 if api::get_last_error().code == 0 => 0, - 0 => return Err(crate::io::Error::last_os_error()), + 0 => return Err(io::Error::last_os_error()), n => n, } as usize; if k == n && api::get_last_error().code == c::ERROR_INSUFFICIENT_BUFFER { @@ -285,9 +285,9 @@ pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] { } } -pub fn ensure_no_nuls>(s: T) -> crate::io::Result { +pub fn ensure_no_nuls>(s: T) -> io::Result { if s.as_ref().encode_wide().any(|b| b == 0) { - Err(crate::io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data")) + Err(io::const_error!(io::ErrorKind::InvalidInput, "nul byte found in provided data")) } else { Ok(s) } @@ -307,8 +307,8 @@ macro_rules! impl_is_zero { impl_is_zero! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } -pub fn cvt(i: I) -> crate::io::Result { - if i.is_zero() { Err(crate::io::Error::last_os_error()) } else { Ok(i) } +pub fn cvt(i: I) -> io::Result { + if i.is_zero() { Err(io::Error::last_os_error()) } else { Ok(i) } } pub fn dur2timeout(dur: Duration) -> u32 { diff --git a/library/std/src/thread/builder.rs b/library/std/src/thread/builder.rs index f4abe074ab9d..baec8c905d80 100644 --- a/library/std/src/thread/builder.rs +++ b/library/std/src/thread/builder.rs @@ -40,7 +40,6 @@ use crate::io; /// [`name`]: Builder::name /// [`spawn`]: Builder::spawn /// [`thread::spawn`]: super::spawn -/// [`io::Result`]: crate::io::Result /// [`unwrap`]: crate::result::Result::unwrap /// [naming-threads]: ./index.html#naming-threads /// [stack-size]: ./index.html#stack-size @@ -161,8 +160,6 @@ impl Builder { /// [`io::Result`] to capture any failure to create the thread at /// the OS level. /// - /// [`io::Result`]: crate::io::Result - /// /// # Panics /// /// Panics if a thread name was set and it contained null bytes. @@ -250,7 +247,6 @@ impl Builder { /// handler.join().unwrap(); /// ``` /// - /// [`io::Result`]: crate::io::Result /// [`thread::spawn`]: super::spawn /// [`spawn`]: super::spawn #[stable(feature = "thread_spawn_unchecked", since = "1.82.0")] diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index 301f5e949cac..3ac9956336d7 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -210,8 +210,6 @@ impl Builder { /// Unlike [`Scope::spawn`], this method yields an [`io::Result`] to /// capture any failure to create the thread at the OS level. /// - /// [`io::Result`]: crate::io::Result - /// /// # Panics /// /// Panics if a thread name was set and it contained null bytes. From b0ff5733bb2e06ba967e54a4637b62475244063f Mon Sep 17 00:00:00 2001 From: dfireBird Date: Sat, 20 Dec 2025 23:27:00 +0530 Subject: [PATCH 1381/3801] feat: implement configuration to change subcommand for test and bench --- .../crates/rust-analyzer/src/config.rs | 37 ++++++++++ .../crates/rust-analyzer/src/lsp/to_proto.rs | 53 ++++++++++----- .../crates/rust-analyzer/src/target_spec.rs | 53 +++++++++++++-- .../docs/book/src/configuration_generated.md | 47 +++++++++++++ .../rust-analyzer/editors/code/package.json | 68 +++++++++++++++++++ 5 files changed, 236 insertions(+), 22 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 1b2d8c8d14fa..3ca2e0d300b7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -904,8 +904,22 @@ config_data! { /// This config takes a map of crate names with the exported proc-macro names to ignore as values. procMacro_ignored: FxHashMap, Box<[Box]>> = FxHashMap::default(), + /// Subcommand used for bench runnables instead of `bench`. + runnables_bench_command: String = "bench".to_owned(), + /// Override the command used for bench runnables. + /// The first element of the array should be the program to execute (for example, `cargo`). + /// + /// Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, + /// target option (such as `--bin` or `--example`), and the target name. + runnables_bench_overrideCommand: Option> = None, /// Command to be executed instead of 'cargo' for runnables. runnables_command: Option = None, + /// Override the command used for bench runnables. + /// The first element of the array should be the program to execute (for example, `cargo`). + /// + /// Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, + /// target option (such as `--bin` or `--example`), and the target name. + runnables_doctest_overrideCommand: Option> = None, /// Additional arguments to be passed to cargo for runnables such as /// tests or binaries. For example, it may be `--release`. runnables_extraArgs: Vec = vec![], @@ -917,6 +931,14 @@ config_data! { /// they will end up being interpreted as options to /// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments). runnables_extraTestBinaryArgs: Vec = vec!["--nocapture".to_owned()], + /// Subcommand used for test runnables instead of `test`. + runnables_test_command: String = "test".to_owned(), + /// Override the command used for test runnables. + /// The first element of the array should be the program to execute (for example, `cargo`). + /// + /// Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, + /// target option (such as `--bin` or `--example`), and the target name. + runnables_test_overrideCommand: Option> = None, /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private /// projects, or "discover" to try to automatically find it if the `rustc-dev` component @@ -1568,6 +1590,16 @@ pub struct RunnablesConfig { pub cargo_extra_args: Vec, /// Additional arguments for the binary being run, if it is a test or benchmark. pub extra_test_binary_args: Vec, + /// Subcommand used for doctest runnables instead of `test`. + pub test_command: String, + /// Override the command used for test runnables. + pub test_override_command: Option>, + /// Subcommand used for doctest runnables instead of `bench`. + pub bench_command: String, + /// Override the command used for bench runnables. + pub bench_override_command: Option>, + /// Override the command used for doctest runnables. + pub doc_test_override_command: Option>, } /// Configuration for workspace symbol search requests. @@ -2494,6 +2526,11 @@ impl Config { override_cargo: self.runnables_command(source_root).clone(), cargo_extra_args: self.runnables_extraArgs(source_root).clone(), extra_test_binary_args: self.runnables_extraTestBinaryArgs(source_root).clone(), + test_command: self.runnables_test_command(source_root).clone(), + test_override_command: self.runnables_test_overrideCommand(source_root).clone(), + bench_command: self.runnables_bench_command(source_root).clone(), + bench_override_command: self.runnables_bench_overrideCommand(source_root).clone(), + doc_test_override_command: self.runnables_doctest_overrideCommand(source_root).clone(), } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 86a35c7d116c..ae1861985e55 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1561,6 +1561,9 @@ pub(crate) fn runnable( let target = spec.target.clone(); + let override_command = + CargoTargetSpec::override_command(snap, Some(spec.clone()), &runnable.kind); + let (cargo_args, executable_args) = CargoTargetSpec::runnable_args( snap, Some(spec.clone()), @@ -1576,23 +1579,41 @@ pub(crate) fn runnable( let label = runnable.label(Some(&target)); let location = location_link(snap, None, runnable.nav)?; - Ok(Some(lsp_ext::Runnable { - label, - location: Some(location), - kind: lsp_ext::RunnableKind::Cargo, - args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs { - workspace_root: Some(workspace_root.into()), - override_cargo: config.override_cargo, - cargo_args, - cwd: cwd.into(), - executable_args, - environment: spec - .sysroot_root - .map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string())) - .into_iter() - .collect(), + let environment = spec + .sysroot_root + .map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string())) + .into_iter() + .collect(); + + Ok(match override_command { + Some(override_command) => match override_command.split_first() { + Some((program, args)) => Some(lsp_ext::Runnable { + label, + location: Some(location), + kind: lsp_ext::RunnableKind::Shell, + args: lsp_ext::RunnableArgs::Shell(lsp_ext::ShellRunnableArgs { + environment, + cwd: cwd.into(), + program: program.to_string(), + args: args.to_vec().into_iter().chain(executable_args).collect(), + }), + }), + _ => None, + }, + None => Some(lsp_ext::Runnable { + label, + location: Some(location), + kind: lsp_ext::RunnableKind::Cargo, + args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs { + workspace_root: Some(workspace_root.into()), + override_cargo: config.override_cargo, + cargo_args, + cwd: cwd.into(), + executable_args, + environment, + }), }), - })) + }) } Some(TargetSpec::ProjectJson(spec)) => { let label = runnable.label(Some(&spec.label)); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index e532d155536c..dbe48f313440 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -123,7 +123,7 @@ impl CargoTargetSpec { match kind { RunnableKind::Test { test_id, attr } => { - cargo_args.push("test".to_owned()); + cargo_args.push(config.test_command); executable_args.push(test_id.to_string()); if let TestId::Path(_) = test_id { executable_args.push("--exact".to_owned()); @@ -134,12 +134,12 @@ impl CargoTargetSpec { } } RunnableKind::TestMod { path } => { - cargo_args.push("test".to_owned()); + cargo_args.push(config.test_command); executable_args.push(path.clone()); executable_args.extend(extra_test_binary_args); } RunnableKind::Bench { test_id } => { - cargo_args.push("bench".to_owned()); + cargo_args.push(config.bench_command); executable_args.push(test_id.to_string()); if let TestId::Path(_) = test_id { executable_args.push("--exact".to_owned()); @@ -154,10 +154,12 @@ impl CargoTargetSpec { } RunnableKind::Bin => { let subcommand = match spec { - Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => "test", - _ => "run", + Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => { + config.test_command + } + _ => "run".to_owned(), }; - cargo_args.push(subcommand.to_owned()); + cargo_args.push(subcommand); } } @@ -206,6 +208,45 @@ impl CargoTargetSpec { (cargo_args, executable_args) } + pub(crate) fn override_command( + snap: &GlobalStateSnapshot, + spec: Option, + kind: &RunnableKind, + ) -> Option> { + let config = snap.config.runnables(None); + let args = match kind { + RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { + config.test_override_command + } + RunnableKind::Bench { .. } => config.bench_override_command, + RunnableKind::DocTest { .. } => config.doc_test_override_command, + RunnableKind::Bin => match spec { + Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => { + config.test_override_command + } + _ => None, + }, + }; + + let target_arg = |kind| match kind { + TargetKind::Bin => "--bin", + TargetKind::Test => "--test", + TargetKind::Bench => "--bench", + TargetKind::Example => "--example", + TargetKind::Lib { .. } => "--lib", + TargetKind::BuildScript | TargetKind::Other => "", + }; + + let replace_placeholders = |arg| match &spec { + Some(spec) if arg == "${package}" => spec.package.clone(), + Some(spec) if arg == "${target_arg}" => target_arg(spec.target_kind).to_string(), + Some(spec) if arg == "${target}" => spec.target.clone(), + _ => arg, + }; + + args.map(|args| args.into_iter().map(replace_placeholders).collect()) + } + pub(crate) fn push_to(self, buf: &mut Vec, kind: &RunnableKind) { buf.push("--package".to_owned()); buf.push(self.package); diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index e208dbadea2b..e824e18854ab 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1348,6 +1348,24 @@ Default: `true` Whether to warn when a rename will cause conflicts (change the meaning of the code). +## rust-analyzer.runnables.bench.command {#runnables.bench.command} + +Default: `"bench"` + +Subcommand used for bench runnables instead of `bench`. + + +## rust-analyzer.runnables.bench.overrideCommand {#runnables.bench.overrideCommand} + +Default: `null` + +Override the command used for bench runnables. +The first element of the array should be the program to execute (for example, `cargo`). + +Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, +target option (such as `--bin` or `--example`), and the target name. + + ## rust-analyzer.runnables.command {#runnables.command} Default: `null` @@ -1355,6 +1373,17 @@ Default: `null` Command to be executed instead of 'cargo' for runnables. +## rust-analyzer.runnables.doctest.overrideCommand {#runnables.doctest.overrideCommand} + +Default: `null` + +Override the command used for bench runnables. +The first element of the array should be the program to execute (for example, `cargo`). + +Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, +target option (such as `--bin` or `--example`), and the target name. + + ## rust-analyzer.runnables.extraArgs {#runnables.extraArgs} Default: `[]` @@ -1381,6 +1410,24 @@ they will end up being interpreted as options to [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments). +## rust-analyzer.runnables.test.command {#runnables.test.command} + +Default: `"test"` + +Subcommand used for test runnables instead of `test`. + + +## rust-analyzer.runnables.test.overrideCommand {#runnables.test.overrideCommand} + +Default: `null` + +Override the command used for test runnables. +The first element of the array should be the program to execute (for example, `cargo`). + +Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, +target option (such as `--bin` or `--example`), and the target name. + + ## rust-analyzer.rustc.source {#rustc.source} Default: `null` diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 481721896227..39404458095f 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -2826,6 +2826,32 @@ } } }, + { + "title": "Runnables", + "properties": { + "rust-analyzer.runnables.bench.command": { + "markdownDescription": "Subcommand used for bench runnables instead of `bench`.", + "default": "bench", + "type": "string" + } + } + }, + { + "title": "Runnables", + "properties": { + "rust-analyzer.runnables.bench.overrideCommand": { + "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name,\ntarget option (such as `--bin` or `--example`), and the target name.", + "default": null, + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + } + } + } + }, { "title": "Runnables", "properties": { @@ -2839,6 +2865,22 @@ } } }, + { + "title": "Runnables", + "properties": { + "rust-analyzer.runnables.doctest.overrideCommand": { + "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name,\ntarget option (such as `--bin` or `--example`), and the target name.", + "default": null, + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + } + } + } + }, { "title": "Runnables", "properties": { @@ -2867,6 +2909,32 @@ } } }, + { + "title": "Runnables", + "properties": { + "rust-analyzer.runnables.test.command": { + "markdownDescription": "Subcommand used for test runnables instead of `test`.", + "default": "test", + "type": "string" + } + } + }, + { + "title": "Runnables", + "properties": { + "rust-analyzer.runnables.test.overrideCommand": { + "markdownDescription": "Override the command used for test runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name,\ntarget option (such as `--bin` or `--example`), and the target name.", + "default": null, + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + } + } + } + }, { "title": "Rustc", "properties": { From bb4d75f123ffef443a65fbb26f65bd15e1d82895 Mon Sep 17 00:00:00 2001 From: dfireBird Date: Mon, 29 Dec 2025 20:24:24 +0530 Subject: [PATCH 1382/3801] fix clippy errors --- .../rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs | 2 +- src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index ae1861985e55..64476338b51e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1595,7 +1595,7 @@ pub(crate) fn runnable( environment, cwd: cwd.into(), program: program.to_string(), - args: args.to_vec().into_iter().chain(executable_args).collect(), + args: args.iter().cloned().chain(executable_args).collect(), }), }), _ => None, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index dbe48f313440..6d05efd75bea 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -239,7 +239,7 @@ impl CargoTargetSpec { let replace_placeholders = |arg| match &spec { Some(spec) if arg == "${package}" => spec.package.clone(), - Some(spec) if arg == "${target_arg}" => target_arg(spec.target_kind).to_string(), + Some(spec) if arg == "${target_arg}" => target_arg(spec.target_kind).to_owned(), Some(spec) if arg == "${target}" => spec.target.clone(), _ => arg, }; From 866598d912e032c7fe4c859ce217338ae530b086 Mon Sep 17 00:00:00 2001 From: Redddy Date: Tue, 30 Dec 2025 00:20:18 +0900 Subject: [PATCH 1383/3801] Add guidance on suppressing warnings in tests --- src/doc/rustc-dev-guide/src/tests/best-practices.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc-dev-guide/src/tests/best-practices.md b/src/doc/rustc-dev-guide/src/tests/best-practices.md index 10372c36ac99..ff4ea11bbc7a 100644 --- a/src/doc/rustc-dev-guide/src/tests/best-practices.md +++ b/src/doc/rustc-dev-guide/src/tests/best-practices.md @@ -153,6 +153,7 @@ This may include remarks on: - Try to make sure the test is as minimal as possible. - Minimize non-critical code and especially minimize unnecessary syntax and type errors which can clutter stderr snapshots. +- Use `#![allow(...)]` or `#![expect(...)]` to suppress unrelated warnings. - Where possible, use semantically meaningful names (e.g. `fn bare_coverage_attributes() {}`). From 315646a7a05062f1177789ffb1f43a74403a3a48 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Thu, 25 Dec 2025 16:07:32 -0500 Subject: [PATCH 1384/3801] Remove the explicit branch hint from const_panic --- library/core/src/intrinsics/mod.rs | 28 ++----------------- library/core/src/panic.rs | 7 ++--- .../codegen-llvm/intrinsics/likely_assert.rs | 18 ++++++++++-- 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 2179b451c375..d46d3ed9d513 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2402,8 +2402,7 @@ where /// The `@capture` block declares which surrounding variables / expressions can be /// used inside the `if const`. /// Note that the two arms of this `if` really each become their own function, which is why the -/// macro supports setting attributes for those functions. The runtime function is always -/// marked as `#[inline]`. +/// macro supports setting attributes for those functions. Both functions are marked as `#[inline]`. /// /// See [`const_eval_select()`] for the rules and requirements around that intrinsic. pub(crate) macro const_eval_select { @@ -2413,35 +2412,14 @@ pub(crate) macro const_eval_select { $(#[$compiletime_attr:meta])* $compiletime:block else $(#[$runtime_attr:meta])* $runtime:block - ) => { - // Use the `noinline` arm, after adding explicit `inline` attributes - $crate::intrinsics::const_eval_select!( - @capture$([$($binders)*])? { $($arg : $ty = $val),* } $(-> $ret)? : - #[noinline] - if const - #[inline] // prevent codegen on this function - $(#[$compiletime_attr])* - $compiletime - else - #[inline] // avoid the overhead of an extra fn call - $(#[$runtime_attr])* - $runtime - ) - }, - // With a leading #[noinline], we don't add inline attributes - ( - @capture$([$($binders:tt)*])? { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? : - #[noinline] - if const - $(#[$compiletime_attr:meta])* $compiletime:block - else - $(#[$runtime_attr:meta])* $runtime:block ) => {{ + #[inline] $(#[$runtime_attr])* fn runtime$(<$($binders)*>)?($($arg: $ty),*) $( -> $ret )? { $runtime } + #[inline] $(#[$compiletime_attr])* const fn compiletime$(<$($binders)*>)?($($arg: $ty),*) $( -> $ret )? { // Don't warn if one of the arguments is unused. diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 7a42b3d0fc78..81520c3ecd1b 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -166,10 +166,9 @@ pub macro const_panic { const fn do_panic($($arg: $ty),*) -> ! { $crate::intrinsics::const_eval_select!( @capture { $($arg: $ty = $arg),* } -> !: - #[noinline] - if const #[track_caller] #[inline] { // Inline this, to prevent codegen + if const #[track_caller] { $crate::panic!($const_msg) - } else #[track_caller] { // Do not inline this, it makes perf worse + } else #[track_caller] { $crate::panic!($runtime_msg) } ) @@ -195,7 +194,7 @@ pub macro const_panic { #[doc(hidden)] pub macro const_assert { ($condition: expr, $const_msg:literal, $runtime_msg:literal, $($arg:tt)*) => {{ - if !$crate::intrinsics::likely($condition) { + if !($condition) { $crate::panic::const_panic!($const_msg, $runtime_msg, $($arg)*) } }} diff --git a/tests/codegen-llvm/intrinsics/likely_assert.rs b/tests/codegen-llvm/intrinsics/likely_assert.rs index 87ffb4ee3fb6..59a40c750eab 100644 --- a/tests/codegen-llvm/intrinsics/likely_assert.rs +++ b/tests/codegen-llvm/intrinsics/likely_assert.rs @@ -1,17 +1,31 @@ //@ compile-flags: -Copt-level=3 +#![feature(panic_internals, const_eval_select, rustc_allow_const_fn_unstable, core_intrinsics)] #![crate_type = "lib"] +// check that assert! and const_assert! emit branch weights + #[no_mangle] pub fn test_assert(x: bool) { assert!(x); } -// check that assert! emits branch weights - // CHECK-LABEL: @test_assert( // CHECK: br i1 %x, label %bb2, label %bb1, !prof ![[NUM:[0-9]+]] // CHECK: bb1: // CHECK: panic // CHECK: bb2: // CHECK: ret void + +#[no_mangle] +pub fn test_const_assert(x: bool) { + core::panic::const_assert!(x, "", "",); +} + +// CHECK-LABEL: @test_const_assert( +// CHECK: br i1 %x, label %bb2, label %bb1, !prof ![[NUM:[0-9]+]] +// CHECK: bb1: +// CHECK: panic +// CHECK: bb2: +// CHECK: ret void + // CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 2000, i32 1} From 1313e958c84adfe9f7d62c90bced8ff16a60af7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 29 Dec 2025 17:49:45 +0100 Subject: [PATCH 1385/3801] Disable debuginfo when building GCC --- src/bootstrap/src/core/build_steps/gcc.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 648a2bea4181..6348e5705f3b 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -346,6 +346,9 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target_pair: GccTargetPair) .map_or_else(|| cxx.clone(), |ccache| format!("{ccache} {cxx}")); configure_cmd.env("CXX", cxx); } + // Disable debuginfo to reduce size of libgccjit.so 10x + configure_cmd.env("CXXFLAGS", "-O2 -g0"); + configure_cmd.env("CFLAGS", "-O2 -g0"); configure_cmd.run(builder); command("make") From cd2c209a1c158d37d1db840c3a00aa5bf57577be Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 29 Dec 2025 18:58:25 +0200 Subject: [PATCH 1386/3801] Fix Clippy --- src/tools/rust-analyzer/crates/span/src/ast_id.rs | 2 +- src/tools/rust-analyzer/crates/span/src/map.rs | 2 +- src/tools/rust-analyzer/crates/syntax/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/span/src/ast_id.rs b/src/tools/rust-analyzer/crates/span/src/ast_id.rs index da537ba9900c..599b3c717522 100644 --- a/src/tools/rust-analyzer/crates/span/src/ast_id.rs +++ b/src/tools/rust-analyzer/crates/span/src/ast_id.rs @@ -804,7 +804,7 @@ impl Drop for AstIdMap { // block on a receive _ = receiver.recv(); // then drain the entire channel - while let Ok(_) = receiver.try_recv() {} + while receiver.try_recv().is_ok() {} // and sleep for a bit std::thread::sleep(std::time::Duration::from_millis(100)); } diff --git a/src/tools/rust-analyzer/crates/span/src/map.rs b/src/tools/rust-analyzer/crates/span/src/map.rs index 75a1b0029cbc..dc7d471aa03a 100644 --- a/src/tools/rust-analyzer/crates/span/src/map.rs +++ b/src/tools/rust-analyzer/crates/span/src/map.rs @@ -168,7 +168,7 @@ impl Drop for SpanMap { // block on a receive _ = receiver.recv(); // then drain the entire channel - while let Ok(_) = receiver.try_recv() {} + while receiver.try_recv().is_ok() {} // and sleep for a bit std::thread::sleep(std::time::Duration::from_millis(100)); } diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs index d36019514016..c510b2831e12 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs @@ -223,7 +223,7 @@ impl Drop for Parse { // block on a receive _ = receiver.recv(); // then drain the entire channel - while let Ok(_) = receiver.try_recv() {} + while receiver.try_recv().is_ok() {} // and sleep for a bit std::thread::sleep(std::time::Duration::from_millis(100)); } From 7069629ee92c2aeb911f7db6a73c02b98882903d Mon Sep 17 00:00:00 2001 From: dfireBird Date: Mon, 29 Dec 2025 22:25:00 +0530 Subject: [PATCH 1387/3801] chore: add `test_name` placeholder in config --- .../crates/rust-analyzer/src/config.rs | 15 ++++++---- .../crates/rust-analyzer/src/lsp/to_proto.rs | 2 +- .../crates/rust-analyzer/src/target_spec.rs | 30 ++++++++++++------- .../docs/book/src/configuration_generated.md | 15 ++++++---- .../rust-analyzer/editors/code/package.json | 6 ++-- 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 3ca2e0d300b7..e39569e108de 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -909,16 +909,18 @@ config_data! { /// Override the command used for bench runnables. /// The first element of the array should be the program to execute (for example, `cargo`). /// - /// Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, - /// target option (such as `--bin` or `--example`), and the target name. + /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically + /// replace the package name, target option (such as `--bin` or `--example`), the target name and + /// the test name (name of test function or test mod path). runnables_bench_overrideCommand: Option> = None, /// Command to be executed instead of 'cargo' for runnables. runnables_command: Option = None, /// Override the command used for bench runnables. /// The first element of the array should be the program to execute (for example, `cargo`). /// - /// Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, - /// target option (such as `--bin` or `--example`), and the target name. + /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically + /// replace the package name, target option (such as `--bin` or `--example`), the target name and + /// the test name (name of test function or test mod path). runnables_doctest_overrideCommand: Option> = None, /// Additional arguments to be passed to cargo for runnables such as /// tests or binaries. For example, it may be `--release`. @@ -936,8 +938,9 @@ config_data! { /// Override the command used for test runnables. /// The first element of the array should be the program to execute (for example, `cargo`). /// - /// Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, - /// target option (such as `--bin` or `--example`), and the target name. + /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically + /// replace the package name, target option (such as `--bin` or `--example`), the target name and + /// the test name (name of test function or test mod path). runnables_test_overrideCommand: Option> = None, /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 64476338b51e..6f0f57725fc7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1595,7 +1595,7 @@ pub(crate) fn runnable( environment, cwd: cwd.into(), program: program.to_string(), - args: args.iter().cloned().chain(executable_args).collect(), + args: args.to_vec(), }), }), _ => None, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index 6d05efd75bea..e0f95a7830ea 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -214,19 +214,25 @@ impl CargoTargetSpec { kind: &RunnableKind, ) -> Option> { let config = snap.config.runnables(None); - let args = match kind { - RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { - config.test_override_command + let (args, test_name) = match kind { + RunnableKind::Test { test_id, .. } => { + (config.test_override_command, Some(test_id.to_string())) + } + RunnableKind::TestMod { path } => (config.test_override_command, Some(path.clone())), + RunnableKind::Bench { test_id } => { + (config.bench_override_command, Some(test_id.to_string())) + } + RunnableKind::DocTest { test_id } => { + (config.doc_test_override_command, Some(test_id.to_string())) } - RunnableKind::Bench { .. } => config.bench_override_command, - RunnableKind::DocTest { .. } => config.doc_test_override_command, RunnableKind::Bin => match spec { Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => { - config.test_override_command + (config.test_override_command, None) } - _ => None, + _ => (None, None), }, }; + let test_name = test_name.unwrap_or_default(); let target_arg = |kind| match kind { TargetKind::Bin => "--bin", @@ -237,10 +243,12 @@ impl CargoTargetSpec { TargetKind::BuildScript | TargetKind::Other => "", }; - let replace_placeholders = |arg| match &spec { - Some(spec) if arg == "${package}" => spec.package.clone(), - Some(spec) if arg == "${target_arg}" => target_arg(spec.target_kind).to_owned(), - Some(spec) if arg == "${target}" => spec.target.clone(), + let replace_placeholders = |arg: String| match &spec { + Some(spec) => arg + .replace("${package}", &spec.package) + .replace("${target_arg}", target_arg(spec.target_kind)) + .replace("${target}", &spec.target) + .replace("${test_name}", &test_name), _ => arg, }; diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index e824e18854ab..58b636334527 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1362,8 +1362,9 @@ Default: `null` Override the command used for bench runnables. The first element of the array should be the program to execute (for example, `cargo`). -Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, -target option (such as `--bin` or `--example`), and the target name. +Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically +replace the package name, target option (such as `--bin` or `--example`), the target name and +the test name (name of test function or test mod path). ## rust-analyzer.runnables.command {#runnables.command} @@ -1380,8 +1381,9 @@ Default: `null` Override the command used for bench runnables. The first element of the array should be the program to execute (for example, `cargo`). -Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, -target option (such as `--bin` or `--example`), and the target name. +Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically +replace the package name, target option (such as `--bin` or `--example`), the target name and +the test name (name of test function or test mod path). ## rust-analyzer.runnables.extraArgs {#runnables.extraArgs} @@ -1424,8 +1426,9 @@ Default: `null` Override the command used for test runnables. The first element of the array should be the program to execute (for example, `cargo`). -Use the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name, -target option (such as `--bin` or `--example`), and the target name. +Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically +replace the package name, target option (such as `--bin` or `--example`), the target name and +the test name (name of test function or test mod path). ## rust-analyzer.rustc.source {#rustc.source} diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 39404458095f..2157cbd48653 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -2840,7 +2840,7 @@ "title": "Runnables", "properties": { "rust-analyzer.runnables.bench.overrideCommand": { - "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name,\ntarget option (such as `--bin` or `--example`), and the target name.", + "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe test name (name of test function or test mod path).", "default": null, "type": [ "null", @@ -2869,7 +2869,7 @@ "title": "Runnables", "properties": { "rust-analyzer.runnables.doctest.overrideCommand": { - "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name,\ntarget option (such as `--bin` or `--example`), and the target name.", + "markdownDescription": "Override the command used for bench runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe test name (name of test function or test mod path).", "default": null, "type": [ "null", @@ -2923,7 +2923,7 @@ "title": "Runnables", "properties": { "rust-analyzer.runnables.test.overrideCommand": { - "markdownDescription": "Override the command used for test runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}` to dynamically replace the package name,\ntarget option (such as `--bin` or `--example`), and the target name.", + "markdownDescription": "Override the command used for test runnables.\nThe first element of the array should be the program to execute (for example, `cargo`).\n\nUse the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically\nreplace the package name, target option (such as `--bin` or `--example`), the target name and\nthe test name (name of test function or test mod path).", "default": null, "type": [ "null", From 0cc8608493266486b71ce848762c663cf47a6566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 29 Dec 2025 18:06:48 +0100 Subject: [PATCH 1388/3801] Specify bug URL when building GCC --- src/bootstrap/src/core/build_steps/gcc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 648a2bea4181..d9870f323cf7 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -325,6 +325,7 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target_pair: GccTargetPair) .arg("--enable-checking=release") .arg("--disable-bootstrap") .arg("--disable-multilib") + .arg("--with-bugurl=https://github.com/rust-lang/gcc/") .arg(format!("--prefix={}", install_dir.display())); let cc = builder.build.cc(host).display().to_string(); From 192bbd1d4ba14c9b0599d63938dcd11cd809d7d9 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 29 Dec 2025 18:56:07 +0200 Subject: [PATCH 1389/3801] Have an `upvars_mentioned()` query that only computes what upvars a closure captures It's required for coercion, where we now use it, as well as for other things. --- .../crates/hir-ty/src/infer/coerce.rs | 39 +-- .../rust-analyzer/crates/hir-ty/src/lib.rs | 1 + .../crates/hir-ty/src/tests/simple.rs | 23 ++ .../rust-analyzer/crates/hir-ty/src/upvars.rs | 319 ++++++++++++++++++ 4 files changed, 359 insertions(+), 23 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/hir-ty/src/upvars.rs diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs index ec7dad0fa08c..e79868f4ae6b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs @@ -56,7 +56,7 @@ use tracing::{debug, instrument}; use crate::{ Adjust, Adjustment, AutoBorrow, ParamEnvAndCrate, PointerCast, TargetFeatures, autoderef::Autoderef, - db::{HirDatabase, InternedClosureId}, + db::{HirDatabase, InternedClosure, InternedClosureId}, infer::{ AllowTwoPhase, AutoBorrowMutability, InferenceContext, TypeMismatch, expr::ExprIsRead, }, @@ -74,6 +74,7 @@ use crate::{ }, obligation_ctxt::ObligationCtxt, }, + upvars::upvars_mentioned, utils::TargetFeatureIsSafeInTarget, }; @@ -896,7 +897,7 @@ where fn coerce_closure_to_fn( &mut self, a: Ty<'db>, - _closure_def_id_a: InternedClosureId, + closure_def_id_a: InternedClosureId, args_a: GenericArgs<'db>, b: Ty<'db>, ) -> CoerceResult<'db> { @@ -904,19 +905,7 @@ where debug_assert!(self.infcx().shallow_resolve(b) == b); match b.kind() { - // FIXME: We need to have an `upvars_mentioned()` query: - // At this point we haven't done capture analysis, which means - // that the ClosureArgs just contains an inference variable instead - // of tuple of captured types. - // - // All we care here is if any variable is being captured and not the exact paths, - // so we check `upvars_mentioned` for root variables being captured. - TyKind::FnPtr(_, hdr) => - // if self - // .db - // .upvars_mentioned(closure_def_id_a.expect_local()) - // .is_none_or(|u| u.is_empty()) => - { + TyKind::FnPtr(_, hdr) if !is_capturing_closure(self.db(), closure_def_id_a) => { // We coerce the closure, which has fn type // `extern "rust-call" fn((arg0,arg1,...)) -> _` // to @@ -1089,14 +1078,12 @@ impl<'db> InferenceContext<'_, 'db> { // Special-case that coercion alone cannot handle: // Function items or non-capturing closures of differing IDs or GenericArgs. let (a_sig, b_sig) = { - let is_capturing_closure = |_ty: Ty<'db>| { - // FIXME: - // if let TyKind::Closure(closure_def_id, _args) = ty.kind() { - // self.db.upvars_mentioned(closure_def_id.expect_local()).is_some() - // } else { - // false - // } - false + let is_capturing_closure = |ty: Ty<'db>| { + if let TyKind::Closure(closure_def_id, _args) = ty.kind() { + is_capturing_closure(self.db, closure_def_id.0) + } else { + false + } }; if is_capturing_closure(prev_ty) || is_capturing_closure(new_ty) { (None, None) @@ -1728,3 +1715,9 @@ fn coerce<'db>( .collect(); Ok((adjustments, ty)) } + +fn is_capturing_closure(db: &dyn HirDatabase, closure: InternedClosureId) -> bool { + let InternedClosure(owner, expr) = closure.loc(db); + upvars_mentioned(db, owner) + .is_some_and(|upvars| upvars.get(&expr).is_some_and(|upvars| !upvars.is_empty())) +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 373862229bd1..41c381220cfd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -50,6 +50,7 @@ pub mod method_resolution; pub mod mir; pub mod primitive; pub mod traits; +pub mod upvars; #[cfg(test)] mod test_db; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index 2e107b2c5941..db557b75071f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs @@ -1,5 +1,7 @@ use expect_test::expect; +use crate::tests::check_infer_with_mismatches; + use super::{check, check_infer, check_no_mismatches, check_types}; #[test] @@ -3956,3 +3958,24 @@ fn bar() { "#, ); } + +#[test] +fn cannot_coerce_capturing_closure_to_fn_ptr() { + check_infer_with_mismatches( + r#" +fn foo() { + let a = 1; + let _: fn() -> i32 = || a; +} + "#, + expect![[r#" + 9..58 '{ ...| a; }': () + 19..20 'a': i32 + 23..24 '1': i32 + 34..35 '_': fn() -> i32 + 51..55 '|| a': impl Fn() -> i32 + 54..55 'a': i32 + 51..55: expected fn() -> i32, got impl Fn() -> i32 + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/upvars.rs b/src/tools/rust-analyzer/crates/hir-ty/src/upvars.rs new file mode 100644 index 000000000000..ee864ab068d2 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-ty/src/upvars.rs @@ -0,0 +1,319 @@ +//! A simple query to collect tall locals (upvars) a closure use. + +use hir_def::{ + DefWithBodyId, + expr_store::{Body, path::Path}, + hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, + resolver::{HasResolver, Resolver, ValueNs}, +}; +use hir_expand::mod_path::PathKind; +use rustc_hash::{FxHashMap, FxHashSet}; + +use crate::db::HirDatabase; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +// Kept sorted. +pub struct Upvars(Box<[BindingId]>); + +impl Upvars { + fn new(upvars: &FxHashSet) -> Upvars { + let mut upvars = upvars.iter().copied().collect::>(); + upvars.sort_unstable(); + Upvars(upvars) + } + + #[inline] + pub fn contains(&self, local: BindingId) -> bool { + self.0.binary_search(&local).is_ok() + } + + #[inline] + pub fn iter(&self) -> impl ExactSizeIterator { + self.0.iter().copied() + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +/// Returns a map from `Expr::Closure` to its upvars. +#[salsa::tracked(returns(as_deref))] +pub fn upvars_mentioned( + db: &dyn HirDatabase, + owner: DefWithBodyId, +) -> Option>> { + let body = db.body(owner); + let mut resolver = owner.resolver(db); + let mut result = FxHashMap::default(); + handle_expr_outside_closure(db, &mut resolver, owner, &body, body.body_expr, &mut result); + return if result.is_empty() { + None + } else { + result.shrink_to_fit(); + Some(Box::new(result)) + }; + + fn handle_expr_outside_closure<'db>( + db: &'db dyn HirDatabase, + resolver: &mut Resolver<'db>, + owner: DefWithBodyId, + body: &Body, + expr: ExprId, + closures_map: &mut FxHashMap, + ) { + match &body[expr] { + &Expr::Closure { body: body_expr, .. } => { + let mut upvars = FxHashSet::default(); + handle_expr_inside_closure( + db, + resolver, + owner, + body, + expr, + body_expr, + &mut upvars, + closures_map, + ); + if !upvars.is_empty() { + closures_map.insert(expr, Upvars::new(&upvars)); + } + } + _ => body.walk_child_exprs(expr, |expr| { + handle_expr_outside_closure(db, resolver, owner, body, expr, closures_map) + }), + } + } + + fn handle_expr_inside_closure<'db>( + db: &'db dyn HirDatabase, + resolver: &mut Resolver<'db>, + owner: DefWithBodyId, + body: &Body, + current_closure: ExprId, + expr: ExprId, + upvars: &mut FxHashSet, + closures_map: &mut FxHashMap, + ) { + match &body[expr] { + Expr::Path(path) => { + resolve_maybe_upvar( + db, + resolver, + owner, + body, + current_closure, + expr, + expr.into(), + upvars, + path, + ); + } + &Expr::Assignment { target, .. } => { + body.walk_pats(target, &mut |pat| { + let Pat::Path(path) = &body[pat] else { return }; + resolve_maybe_upvar( + db, + resolver, + owner, + body, + current_closure, + expr, + pat.into(), + upvars, + path, + ); + }); + } + &Expr::Closure { body: body_expr, .. } => { + let mut closure_upvars = FxHashSet::default(); + handle_expr_inside_closure( + db, + resolver, + owner, + body, + expr, + body_expr, + &mut closure_upvars, + closures_map, + ); + if !closure_upvars.is_empty() { + closures_map.insert(expr, Upvars::new(&closure_upvars)); + // All nested closure's upvars are also upvars of the parent closure. + upvars.extend( + closure_upvars + .iter() + .copied() + .filter(|local| body.binding_owner(*local) != Some(current_closure)), + ); + } + return; + } + _ => {} + } + body.walk_child_exprs(expr, |expr| { + handle_expr_inside_closure( + db, + resolver, + owner, + body, + current_closure, + expr, + upvars, + closures_map, + ) + }); + } +} + +fn resolve_maybe_upvar<'db>( + db: &'db dyn HirDatabase, + resolver: &mut Resolver<'db>, + owner: DefWithBodyId, + body: &Body, + current_closure: ExprId, + expr: ExprId, + id: ExprOrPatId, + upvars: &mut FxHashSet, + path: &Path, +) { + if let Path::BarePath(mod_path) = path + && matches!(mod_path.kind, PathKind::Plain) + && mod_path.segments().len() == 1 + { + // Could be a variable. + let guard = resolver.update_to_inner_scope(db, owner, expr); + let resolution = + resolver.resolve_path_in_value_ns_fully(db, path, body.expr_or_pat_path_hygiene(id)); + if let Some(ValueNs::LocalBinding(local)) = resolution + && body.binding_owner(local) != Some(current_closure) + { + upvars.insert(local); + } + resolver.reset_to_guard(guard); + } +} + +#[cfg(test)] +mod tests { + use expect_test::{Expect, expect}; + use hir_def::{ModuleDefId, db::DefDatabase, nameres::crate_def_map}; + use itertools::Itertools; + use span::Edition; + use test_fixture::WithFixture; + + use crate::{test_db::TestDB, upvars::upvars_mentioned}; + + #[track_caller] + fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expectation: Expect) { + let db = TestDB::with_files(ra_fixture); + crate::attach_db(&db, || { + let def_map = crate_def_map(&db, db.test_crate()); + let func = def_map + .modules() + .flat_map(|(_, module)| module.scope.declarations()) + .filter_map(|decl| match decl { + ModuleDefId::FunctionId(func) => Some(func), + _ => None, + }) + .exactly_one() + .unwrap_or_else(|_| panic!("expected one function")); + let (body, source_map) = db.body_with_source_map(func.into()); + let Some(upvars) = upvars_mentioned(&db, func.into()) else { + expectation.assert_eq(""); + return; + }; + let mut closures = Vec::new(); + for (&closure, upvars) in upvars { + let closure_range = source_map.expr_syntax(closure).unwrap().value.text_range(); + let upvars = upvars + .iter() + .map(|local| body[local].name.display(&db, Edition::CURRENT)) + .join(", "); + closures.push((closure_range, upvars)); + } + closures.sort_unstable_by_key(|(range, _)| (range.start(), range.end())); + let closures = closures + .into_iter() + .map(|(range, upvars)| format!("{range:?}: {upvars}")) + .join("\n"); + expectation.assert_eq(&closures); + }); + } + + #[test] + fn simple() { + check( + r#" +struct foo; +fn foo(param: i32) { + let local = "boo"; + || { param; foo }; + || local; + || { param; local; param; local; }; + || 0xDEAFBEAF; +} + "#, + expect![[r#" + 60..77: param + 83..91: local + 97..131: param, local"#]], + ); + } + + #[test] + fn nested() { + check( + r#" +fn foo() { + let (a, b); + || { + || a; + || b; + }; +} + "#, + expect![[r#" + 31..69: a, b + 44..48: a + 58..62: b"#]], + ); + } + + #[test] + fn closure_var() { + check( + r#" +fn foo() { + let upvar = 1; + |closure_param: i32| { + let closure_local = closure_param; + closure_local + upvar + }; +} + "#, + expect!["34..135: upvar"], + ); + } + + #[test] + fn closure_var_nested() { + check( + r#" +fn foo() { + let a = 1; + |b: i32| { + || { + let c = 123; + a + b + c + } + }; +} + "#, + expect![[r#" + 30..116: a + 49..110: a, b"#]], + ); + } +} From 0763954226fac65c3e2bb484856c86d38203bd4e Mon Sep 17 00:00:00 2001 From: Jeremy Smart Date: Wed, 1 Oct 2025 18:29:30 -0400 Subject: [PATCH 1390/3801] add VecDeque::splice --- .../alloc/src/collections/vec_deque/drain.rs | 23 ++- .../alloc/src/collections/vec_deque/mod.rs | 65 ++++++++ .../alloc/src/collections/vec_deque/splice.rs | 150 ++++++++++++++++++ library/alloc/src/vec/splice.rs | 1 + library/alloctests/tests/lib.rs | 2 +- library/alloctests/tests/vec_deque.rs | 71 +++++++++ 6 files changed, 299 insertions(+), 13 deletions(-) create mode 100644 library/alloc/src/collections/vec_deque/splice.rs diff --git a/library/alloc/src/collections/vec_deque/drain.rs b/library/alloc/src/collections/vec_deque/drain.rs index 321621d18be9..eee7be674c95 100644 --- a/library/alloc/src/collections/vec_deque/drain.rs +++ b/library/alloc/src/collections/vec_deque/drain.rs @@ -21,13 +21,13 @@ pub struct Drain< > { // We can't just use a &mut VecDeque, as that would make Drain invariant over T // and we want it to be covariant instead - deque: NonNull>, + pub(super) deque: NonNull>, // drain_start is stored in deque.len - drain_len: usize, + pub(super) drain_len: usize, // index into the logical array, not the physical one (always lies in [0..deque.len)) idx: usize, - // number of elements remaining after dropping the drain - new_len: usize, + // number of elements after the drained range + pub(super) tail_len: usize, remaining: usize, // Needed to make Drain covariant over T _marker: PhantomData<&'a T>, @@ -40,12 +40,12 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { drain_len: usize, ) -> Self { let orig_len = mem::replace(&mut deque.len, drain_start); - let new_len = orig_len - drain_len; + let tail_len = orig_len - drain_start - drain_len; Drain { deque: NonNull::from(deque), drain_len, idx: drain_start, - new_len, + tail_len, remaining: drain_len, _marker: PhantomData, } @@ -78,7 +78,7 @@ impl fmt::Debug for Drain<'_, T, A> { f.debug_tuple("Drain") .field(&self.drain_len) .field(&self.idx) - .field(&self.new_len) + .field(&self.tail_len) .field(&self.remaining) .finish() } @@ -125,7 +125,9 @@ impl Drop for Drain<'_, T, A> { let source_deque = unsafe { self.0.deque.as_mut() }; let drain_len = self.0.drain_len; - let new_len = self.0.new_len; + let head_len = source_deque.len; // #elements in front of the drain + let tail_len = self.0.tail_len; // #elements behind the drain + let new_len = head_len + tail_len; if T::IS_ZST { // no need to copy around any memory if T is a ZST @@ -133,9 +135,6 @@ impl Drop for Drain<'_, T, A> { return; } - let head_len = source_deque.len; // #elements in front of the drain - let tail_len = new_len - head_len; // #elements behind the drain - // Next, we will fill the hole left by the drain with as few writes as possible. // The code below handles the following control flow and reduces the amount of // branches under the assumption that `head_len == 0 || tail_len == 0`, i.e. @@ -219,7 +218,7 @@ impl Drop for Drain<'_, T, A> { } if new_len == 0 { - // Special case: If the entire dequeue was drained, reset the head back to 0, + // Special case: If the entire deque was drained, reset the head back to 0, // like `.clear()` does. source_deque.head = 0; } else if head_len < tail_len { diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 0e01d0d19e7a..c51317a1a68f 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -62,6 +62,13 @@ use self::spec_from_iter::SpecFromIter; mod spec_from_iter; +#[cfg(not(no_global_oom_handling))] +#[unstable(feature = "deque_extend_front", issue = "146975")] +pub use self::splice::Splice; + +#[cfg(not(no_global_oom_handling))] +mod splice; + #[cfg(test)] mod tests; @@ -1838,6 +1845,64 @@ impl VecDeque { unsafe { Drain::new(self, drain_start, drain_len) } } + /// Creates a splicing iterator that replaces the specified range in the deque with the given + /// `replace_with` iterator and yields the removed items. `replace_with` does not need to be the + /// same length as `range`. + /// + /// `range` is removed even if the `Splice` iterator is not consumed before it is dropped. + /// + /// It is unspecified how many elements are removed from the deque if the `Splice` value is + /// leaked. + /// + /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped. + /// + /// This is optimal if: + /// + /// * The tail (elements in the deque after `range`) is empty, + /// * or `replace_with` yields fewer or equal elements than `range`'s length + /// * or the lower bound of its `size_hint()` is exact. + /// + /// Otherwise, a temporary vector is allocated and the tail is moved twice. + /// + /// # Panics + /// + /// Panics if the range has `start_bound > end_bound`, or, if the range is + /// bounded on either end and past the length of the deque. + /// + /// # Examples + /// + /// ``` + /// # #![feature(deque_extend_front)] + /// # use std::collections::VecDeque; + /// + /// let mut v = VecDeque::from(vec![1, 2, 3, 4]); + /// let new = [7, 8, 9]; + /// let u: Vec<_> = v.splice(1..3, new).collect(); + /// assert_eq!(v, [1, 7, 8, 9, 4]); + /// assert_eq!(u, [2, 3]); + /// ``` + /// + /// Using `splice` to insert new items into a vector efficiently at a specific position + /// indicated by an empty range: + /// + /// ``` + /// # #![feature(deque_extend_front)] + /// # use std::collections::VecDeque; + /// + /// let mut v = VecDeque::from(vec![1, 5]); + /// let new = [2, 3, 4]; + /// v.splice(1..1, new); + /// assert_eq!(v, [1, 2, 3, 4, 5]); + /// ``` + #[unstable(feature = "deque_extend_front", issue = "146975")] + pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter, A> + where + R: RangeBounds, + I: IntoIterator, + { + Splice { drain: self.drain(range), replace_with: replace_with.into_iter() } + } + /// Clears the deque, removing all values. /// /// # Examples diff --git a/library/alloc/src/collections/vec_deque/splice.rs b/library/alloc/src/collections/vec_deque/splice.rs new file mode 100644 index 000000000000..cd98af7341de --- /dev/null +++ b/library/alloc/src/collections/vec_deque/splice.rs @@ -0,0 +1,150 @@ +use core::alloc::Allocator; + +use crate::alloc::Global; +use crate::collections::vec_deque::Drain; +use crate::vec::Vec; + +/// A splicing iterator for `VecDeque`. +/// +/// This struct is created by [`VecDeque::splice()`][super::VecDeque::splice]. +/// See its documentation for more. +/// +/// # Example +/// +/// ``` +/// # #![feature(deque_extend_front)] +/// # use std::collections::VecDeque; +/// +/// let mut v = VecDeque::from(vec![0, 1, 2]); +/// let new = [7, 8]; +/// let iter: std::collections::vec_deque::Splice<'_, _> = v.splice(1.., new); +/// ``` +#[unstable(feature = "deque_extend_front", issue = "146975")] +#[derive(Debug)] +pub struct Splice< + 'a, + I: Iterator + 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global, +> { + pub(super) drain: Drain<'a, I::Item, A>, + pub(super) replace_with: I, +} + +#[unstable(feature = "deque_extend_front", issue = "146975")] +impl Iterator for Splice<'_, I, A> { + type Item = I::Item; + + fn next(&mut self) -> Option { + self.drain.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.drain.size_hint() + } +} + +#[unstable(feature = "deque_extend_front", issue = "146975")] +impl DoubleEndedIterator for Splice<'_, I, A> { + fn next_back(&mut self) -> Option { + self.drain.next_back() + } +} + +#[unstable(feature = "deque_extend_front", issue = "146975")] +impl ExactSizeIterator for Splice<'_, I, A> {} + +// See also: [`crate::vec::Splice`]. +#[unstable(feature = "deque_extend_front", issue = "146975")] +impl Drop for Splice<'_, I, A> { + fn drop(&mut self) { + // This will set drain.remaining to 0, so its drop won't try to read deallocated memory on + // drop. + self.drain.by_ref().for_each(drop); + + // At this point draining is done and the only remaining tasks are splicing + // and moving things into the final place. + + unsafe { + let tail_len = self.drain.tail_len; // #elements behind the drain + + if tail_len == 0 { + self.drain.deque.as_mut().extend(self.replace_with.by_ref()); + return; + } + + // First fill the range left by drain(). + if !self.drain.fill(&mut self.replace_with) { + return; + } + + // There may be more elements. Use the lower bound as an estimate. + // FIXME: Is the upper bound a better guess? Or something else? + let (lower_bound, _upper_bound) = self.replace_with.size_hint(); + if lower_bound > 0 { + self.drain.move_tail(lower_bound); + if !self.drain.fill(&mut self.replace_with) { + return; + } + } + + // Collect any remaining elements. + // This is a zero-length vector which does not allocate if `lower_bound` was exact. + let mut collected = self.replace_with.by_ref().collect::>().into_iter(); + // Now we have an exact count. + if collected.len() > 0 { + self.drain.move_tail(collected.len()); + let filled = self.drain.fill(&mut collected); + debug_assert!(filled); + debug_assert_eq!(collected.len(), 0); + } + } + // Let `Drain::drop` move the tail back if necessary and restore `deque.len`. + } +} + +/// Private helper methods for `Splice::drop` +impl Drain<'_, T, A> { + /// The range from `self.deque.len` to `self.deque.len + self.drain_len` contains elements that + /// have been moved out. + /// Fill that range as much as possible with new elements from the `replace_with` iterator. + /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.) + /// + /// # Safety + /// + /// self.deque must be valid. self.deque.len and self.deque.len + self.drain_len must be less + /// than twice the deque's capacity. + unsafe fn fill>(&mut self, replace_with: &mut I) -> bool { + let deque = unsafe { self.deque.as_mut() }; + let range_start = deque.len; + let range_end = range_start + self.drain_len; + + for idx in range_start..range_end { + if let Some(new_item) = replace_with.next() { + let index = deque.to_physical_idx(idx); + unsafe { deque.buffer_write(index, new_item) }; + deque.len += 1; + self.drain_len -= 1; + } else { + return false; + } + } + true + } + + /// Makes room for inserting more elements before the tail. + /// + /// # Safety + /// + /// self.deque must be valid. + unsafe fn move_tail(&mut self, additional: usize) { + let deque = unsafe { self.deque.as_mut() }; + let tail_start = deque.len + self.drain_len; + deque.buf.reserve(tail_start + self.tail_len, additional); + + let new_tail_start = tail_start + additional; + unsafe { + deque.wrap_copy(tail_start, new_tail_start, self.tail_len); + } + self.drain_len += additional; + } +} diff --git a/library/alloc/src/vec/splice.rs b/library/alloc/src/vec/splice.rs index b08bb9cb6d19..46611f611dc2 100644 --- a/library/alloc/src/vec/splice.rs +++ b/library/alloc/src/vec/splice.rs @@ -50,6 +50,7 @@ impl DoubleEndedIterator for Splice<'_, I, A> { #[stable(feature = "vec_splice", since = "1.21.0")] impl ExactSizeIterator for Splice<'_, I, A> {} +// See also: [`crate::collections::vec_deque::Splice`]. #[stable(feature = "vec_splice", since = "1.21.0")] impl Drop for Splice<'_, I, A> { fn drop(&mut self) { diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index b4d3e75b0994..34c65bf787c8 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -1,11 +1,11 @@ #![feature(allocator_api)] #![feature(alloc_layout_extra)] +#![feature(deque_extend_front)] #![feature(iter_array_chunks)] #![feature(assert_matches)] #![feature(wtf8_internals)] #![feature(cow_is_borrowed)] #![feature(core_intrinsics)] -#![feature(deque_extend_front)] #![feature(downcast_unchecked)] #![feature(exact_size_is_empty)] #![feature(hashmap_internals)] diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs index cf31613577f7..82803c7a0dab 100644 --- a/library/alloctests/tests/vec_deque.rs +++ b/library/alloctests/tests/vec_deque.rs @@ -2155,3 +2155,74 @@ fn test_extend_front_specialization_copy_slice() { // check it really wrapped assert_eq!(v.as_slices(), ([5].as_slice(), [4, 3, 2].as_slice())); } + +#[test] +fn test_splice() { + let mut v = VecDeque::from(vec![1, 2, 3, 4, 5]); + let a = [10, 11, 12]; + v.splice(2..4, a); + assert_eq!(v, &[1, 2, 10, 11, 12, 5]); + v.splice(1..3, Some(20)); + assert_eq!(v, &[1, 20, 11, 12, 5]); +} + +#[test] +fn test_splice_inclusive_range() { + let mut v = VecDeque::from(vec![1, 2, 3, 4, 5]); + let a = [10, 11, 12]; + let t1: Vec<_> = v.splice(2..=3, a).collect(); + assert_eq!(v, &[1, 2, 10, 11, 12, 5]); + assert_eq!(t1, &[3, 4]); + let t2: Vec<_> = v.splice(1..=2, Some(20)).collect(); + assert_eq!(v, &[1, 20, 11, 12, 5]); + assert_eq!(t2, &[2, 10]); +} + +#[test] +fn test_splice_inclusive_range2() { + let mut v = VecDeque::from(vec![1, 2, 10, 11, 12, 5]); + let t2: Vec<_> = v.splice(1..=2, Some(20)).collect(); + assert_eq!(v, &[1, 20, 11, 12, 5]); + assert_eq!(t2, &[2, 10]); +} + +#[test] +#[should_panic] +fn test_splice_out_of_bounds() { + let mut v = VecDeque::from(vec![1, 2, 3, 4, 5]); + let a = [10, 11, 12]; + v.splice(5..6, a); +} + +#[test] +#[should_panic] +fn test_splice_inclusive_out_of_bounds() { + let mut v = VecDeque::from(vec![1, 2, 3, 4, 5]); + let a = [10, 11, 12]; + v.splice(5..=5, a); +} + +#[test] +fn test_splice_items_zero_sized() { + let mut vec = VecDeque::from(vec![(), (), ()]); + let vec2 = VecDeque::from(vec![]); + let t: Vec<_> = vec.splice(1..2, vec2.iter().cloned()).collect(); + assert_eq!(vec, &[(), ()]); + assert_eq!(t, &[()]); +} + +#[test] +fn test_splice_unbounded() { + let mut vec = VecDeque::from(vec![1, 2, 3, 4, 5]); + let t: Vec<_> = vec.splice(.., None).collect(); + assert_eq!(vec, &[]); + assert_eq!(t, &[1, 2, 3, 4, 5]); +} + +#[test] +fn test_splice_forget() { + let mut v = VecDeque::from(vec![1, 2, 3, 4, 5]); + let a = [10, 11, 12]; + std::mem::forget(v.splice(2..4, a)); + assert_eq!(v, &[1, 2]); +} From 67a76f9fb5893c87bee0360e72a74ed33e2b0741 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Mon, 29 Dec 2025 18:32:24 +0000 Subject: [PATCH 1391/3801] fix: `implicit_saturating_sub` suggests wrongly on untyped int literal --- clippy_lints/src/implicit_saturating_sub.rs | 27 ++++++++++++++++----- clippy_utils/src/lib.rs | 13 +++++++++- clippy_utils/src/sugg.rs | 2 +- tests/ui/implicit_saturating_sub.fixed | 8 ++++++ tests/ui/implicit_saturating_sub.rs | 8 ++++++ tests/ui/implicit_saturating_sub.stderr | 8 +++++- 6 files changed, 57 insertions(+), 9 deletions(-) diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs index 7b6f8729cb75..516f9e3aa60c 100644 --- a/clippy_lints/src/implicit_saturating_sub.rs +++ b/clippy_lints/src/implicit_saturating_sub.rs @@ -1,9 +1,13 @@ +use std::borrow::Cow; + use clippy_config::Conf; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::{Sugg, make_binop}; use clippy_utils::{ - SpanlessEq, eq_expr_value, higher, is_in_const_context, is_integer_literal, peel_blocks, peel_blocks_with_stmt, sym, + SpanlessEq, eq_expr_value, higher, is_in_const_context, is_integer_literal, is_integer_literal_untyped, + peel_blocks, peel_blocks_with_stmt, sym, }; use rustc_ast::ast::LitKind; use rustc_data_structures::packed::Pu128; @@ -238,10 +242,21 @@ fn check_subtraction( if eq_expr_value(cx, left, big_expr) && eq_expr_value(cx, right, little_expr) { // This part of the condition is voluntarily split from the one before to ensure that // if `snippet_opt` fails, it won't try the next conditions. - if (!is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST)) - && let Some(big_expr_sugg) = Sugg::hir_opt(cx, big_expr).map(Sugg::maybe_paren) - && let Some(little_expr_sugg) = Sugg::hir_opt(cx, little_expr) - { + if !is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST) { + let mut applicability = Applicability::MachineApplicable; + let big_expr_sugg = (if is_integer_literal_untyped(big_expr) { + let get_snippet = |span: Span| { + let snippet = snippet_with_applicability(cx, span, "..", &mut applicability); + let big_expr_ty = cx.typeck_results().expr_ty(big_expr); + Cow::Owned(format!("{snippet}_{big_expr_ty}")) + }; + Sugg::hir_from_snippet(cx, big_expr, get_snippet) + } else { + Sugg::hir_with_applicability(cx, big_expr, "..", &mut applicability) + }) + .maybe_paren(); + let little_expr_sugg = Sugg::hir_with_applicability(cx, little_expr, "..", &mut applicability); + let sugg = format!( "{}{big_expr_sugg}.saturating_sub({little_expr_sugg}){}", if is_composited { "{ " } else { "" }, @@ -254,7 +269,7 @@ fn check_subtraction( "manual arithmetic check found", "replace it with", sugg, - Applicability::MachineApplicable, + applicability, ); } } else if eq_expr_value(cx, left, little_expr) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 954c32687af6..2d079deb0ce4 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -90,7 +90,7 @@ use std::sync::{Mutex, MutexGuard, OnceLock}; use itertools::Itertools; use rustc_abi::Integer; use rustc_ast::ast::{self, LitKind, RangeLimits}; -use rustc_ast::join_path_syms; +use rustc_ast::{LitIntType, join_path_syms}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexmap; use rustc_data_structures::packed::Pu128; @@ -1385,6 +1385,17 @@ pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool { false } +/// Checks whether the given expression is an untyped integer literal. +pub fn is_integer_literal_untyped(expr: &Expr<'_>) -> bool { + if let ExprKind::Lit(spanned) = expr.kind + && let LitKind::Int(_, suffix) = spanned.node + { + return suffix == LitIntType::Unsuffixed; + } + + false +} + /// Checks whether the given expression is a constant literal of the given value. pub fn is_float_literal(expr: &Expr<'_>, value: f64) -> bool { if let ExprKind::Lit(spanned) = expr.kind diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 2ef2afb45071..3ade38bea8ed 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -127,7 +127,7 @@ impl<'a> Sugg<'a> { /// Generate a suggestion for an expression with the given snippet. This is used by the `hir_*` /// function variants of `Sugg`, since these use different snippet functions. - fn hir_from_snippet( + pub fn hir_from_snippet( cx: &LateContext<'_>, expr: &hir::Expr<'_>, mut get_snippet: impl FnMut(Span) -> Cow<'a, str>, diff --git a/tests/ui/implicit_saturating_sub.fixed b/tests/ui/implicit_saturating_sub.fixed index 1aab6c54407e..22e59bbd2705 100644 --- a/tests/ui/implicit_saturating_sub.fixed +++ b/tests/ui/implicit_saturating_sub.fixed @@ -252,3 +252,11 @@ fn arbitrary_expression() { 0 }; } + +fn issue16307() { + let x: u8 = 100; + let y = 100_u8.saturating_sub(x); + //~^ implicit_saturating_sub + + println!("{y}"); +} diff --git a/tests/ui/implicit_saturating_sub.rs b/tests/ui/implicit_saturating_sub.rs index 7ca57a2902db..7fa19f0c8ad2 100644 --- a/tests/ui/implicit_saturating_sub.rs +++ b/tests/ui/implicit_saturating_sub.rs @@ -326,3 +326,11 @@ fn arbitrary_expression() { 0 }; } + +fn issue16307() { + let x: u8 = 100; + let y = if x >= 100 { 0 } else { 100 - x }; + //~^ implicit_saturating_sub + + println!("{y}"); +} diff --git a/tests/ui/implicit_saturating_sub.stderr b/tests/ui/implicit_saturating_sub.stderr index 0c225856fd07..2f3d2ba787e8 100644 --- a/tests/ui/implicit_saturating_sub.stderr +++ b/tests/ui/implicit_saturating_sub.stderr @@ -238,5 +238,11 @@ error: manual arithmetic check found LL | let _ = if a < b * 2 { 0 } else { a - b * 2 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b * 2)` -error: aborting due to 27 previous errors +error: manual arithmetic check found + --> tests/ui/implicit_saturating_sub.rs:332:13 + | +LL | let y = if x >= 100 { 0 } else { 100 - x }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `100_u8.saturating_sub(x)` + +error: aborting due to 28 previous errors From eea3d794ff25055e7f544305d1b4996f8d3c5283 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Wed, 24 Dec 2025 13:24:34 +0000 Subject: [PATCH 1392/3801] LinkedList: use Box::into_non_null_with_allocator --- library/alloc/src/collections/linked_list.rs | 30 +++++++++++--------- library/alloc/src/lib.rs | 1 + library/alloctests/lib.rs | 1 + 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index c98aeb80628e..d5747d34f036 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -167,7 +167,7 @@ impl LinkedList { /// Adds the given node to the front of the list. /// /// # Safety - /// `node` must point to a valid node that was boxed and leaked using the list's allocator. + /// `node` must point to a valid node in the list's allocator. /// This method takes ownership of the node, so the pointer should not be used again. #[inline] unsafe fn push_front_node(&mut self, node: NonNull>) { @@ -212,7 +212,7 @@ impl LinkedList { /// Adds the given node to the back of the list. /// /// # Safety - /// `node` must point to a valid node that was boxed and leaked using the list's allocator. + /// `node` must point to a valid node in the list's allocator. /// This method takes ownership of the node, so the pointer should not be used again. #[inline] unsafe fn push_back_node(&mut self, node: NonNull>) { @@ -866,12 +866,12 @@ impl LinkedList { #[unstable(feature = "push_mut", issue = "135974")] #[must_use = "if you don't need a reference to the value, use `LinkedList::push_front` instead"] pub fn push_front_mut(&mut self, elt: T) -> &mut T { - let node = Box::new_in(Node::new(elt), &self.alloc); - let mut node_ptr = NonNull::from(Box::leak(node)); - // SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc and leaked + let mut node = + Box::into_non_null_with_allocator(Box::new_in(Node::new(elt), &self.alloc)).0; + // SAFETY: node is a unique pointer to a node in self.alloc unsafe { - self.push_front_node(node_ptr); - &mut node_ptr.as_mut().element + self.push_front_node(node); + &mut node.as_mut().element } } @@ -938,12 +938,12 @@ impl LinkedList { #[unstable(feature = "push_mut", issue = "135974")] #[must_use = "if you don't need a reference to the value, use `LinkedList::push_back` instead"] pub fn push_back_mut(&mut self, elt: T) -> &mut T { - let node = Box::new_in(Node::new(elt), &self.alloc); - let mut node_ptr = NonNull::from(Box::leak(node)); - // SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc and leaked + let mut node = + Box::into_non_null_with_allocator(Box::new_in(Node::new(elt), &self.alloc)).0; + // SAFETY: node is a unique pointer to a node in self.alloc unsafe { - self.push_back_node(node_ptr); - &mut node_ptr.as_mut().element + self.push_back_node(node); + &mut node.as_mut().element } } @@ -1690,7 +1690,8 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_after(&mut self, item: T) { unsafe { - let spliced_node = Box::leak(Box::new_in(Node::new(item), &self.list.alloc)).into(); + let spliced_node = + Box::into_non_null_with_allocator(Box::new_in(Node::new(item), &self.list.alloc)).0; let node_next = match self.current { None => self.list.head, Some(node) => node.as_ref().next, @@ -1710,7 +1711,8 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_before(&mut self, item: T) { unsafe { - let spliced_node = Box::leak(Box::new_in(Node::new(item), &self.list.alloc)).into(); + let spliced_node = + Box::into_non_null_with_allocator(Box::new_in(Node::new(item), &self.list.alloc)).0; let node_prev = match self.current { None => self.list.tail, Some(node) => node.as_ref().prev, diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 8097e43e03a2..b659e904c8a0 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -93,6 +93,7 @@ #![feature(assert_matches)] #![feature(async_fn_traits)] #![feature(async_iterator)] +#![feature(box_vec_non_null)] #![feature(bstr)] #![feature(bstr_internals)] #![feature(cast_maybe_uninit)] diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index f6c7105ea280..cd02c0a53857 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -18,6 +18,7 @@ #![feature(allocator_api)] #![feature(array_into_iter_constructors)] #![feature(assert_matches)] +#![feature(box_vec_non_null)] #![feature(char_internals)] #![feature(copied_into_inner)] #![feature(core_intrinsics)] From 1ff953d63e8d470892d13cb99abeadb42bc1d997 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Mon, 29 Dec 2025 19:23:26 +0000 Subject: [PATCH 1393/3801] Fix and expand direct-access-external-data test This test currently doesn't fulfill its purpose, as `external dso_local` can still match `external {{.*}}`. Fix this by using CHECK-NOT directives. Also, this test is expanded to all platforms where it makes sense, instead of restricting to loongarch. --- .../direct-access-external-data.rs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/codegen-llvm/direct-access-external-data.rs b/tests/codegen-llvm/direct-access-external-data.rs index 5b2ff41ef052..c2c32d17ff7e 100644 --- a/tests/codegen-llvm/direct-access-external-data.rs +++ b/tests/codegen-llvm/direct-access-external-data.rs @@ -1,21 +1,25 @@ -//@ only-loongarch64-unknown-linux-gnu +//@ ignore-powerpc64 (handles dso_local differently) +//@ ignore-apple (handles dso_local differently) -//@ revisions: DEFAULT DIRECT INDIRECT +//@ revisions: DEFAULT PIE DIRECT INDIRECT //@ [DEFAULT] compile-flags: -C relocation-model=static -//@ [DIRECT] compile-flags: -C relocation-model=static -Z direct-access-external-data=yes +//@ [PIE] compile-flags: -C relocation-model=pie +//@ [DIRECT] compile-flags: -C relocation-model=pie -Z direct-access-external-data=yes //@ [INDIRECT] compile-flags: -C relocation-model=static -Z direct-access-external-data=no #![crate_type = "rlib"] -// DEFAULT: @VAR = external {{.*}} global i32 -// DIRECT: @VAR = external dso_local {{.*}} global i32 -// INDIRECT: @VAR = external {{.*}} global i32 - -extern "C" { - static VAR: i32; +unsafe extern "C" { + // CHECK: @VAR = external + // DEFAULT-SAME: dso_local + // PIE-NOT: dso_local + // DIRECT-SAME: dso_local + // INDIRECT-NOT: dso_local + // CHECK-SAME: global i32 + safe static VAR: i32; } #[no_mangle] -pub fn get() -> i32 { - unsafe { VAR } +pub fn refer() { + core::hint::black_box(VAR); } From 5467a398c2a33c9a49db2117c2c6f9e12015dd16 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Mon, 29 Dec 2025 17:21:29 +0000 Subject: [PATCH 1394/3801] Fix dso_local for external statics with linkage The current code applies `dso_local` to the internal generated symbols instead of the actually-externally one. --- compiler/rustc_codegen_llvm/src/consts.rs | 4 ++++ .../direct-access-external-data.rs | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 08c53179bc14..2b04f81c267f 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -187,6 +187,10 @@ fn check_and_apply_linkage<'ll, 'tcx>( }; llvm::set_linkage(g1, base::linkage_to_llvm(linkage)); + // Normally this is done in `get_static_inner`, but when as we generate an internal global, + // it will apply the dso_local to the internal global instead, so do it here, too. + cx.assume_dso_local(g1, true); + // Declare an internal global `extern_with_linkage_foo` which // is initialized with the address of `foo`. If `foo` is // discarded during linking (for example, if `foo` has weak diff --git a/tests/codegen-llvm/direct-access-external-data.rs b/tests/codegen-llvm/direct-access-external-data.rs index c2c32d17ff7e..73dc08dc2b57 100644 --- a/tests/codegen-llvm/direct-access-external-data.rs +++ b/tests/codegen-llvm/direct-access-external-data.rs @@ -8,6 +8,7 @@ //@ [INDIRECT] compile-flags: -C relocation-model=static -Z direct-access-external-data=no #![crate_type = "rlib"] +#![feature(linkage)] unsafe extern "C" { // CHECK: @VAR = external @@ -17,9 +18,31 @@ unsafe extern "C" { // INDIRECT-NOT: dso_local // CHECK-SAME: global i32 safe static VAR: i32; + + // When "linkage" is used, we generate an indirection global. + // Check dso_local is still applied to the actual global. + // CHECK: @EXTERNAL = external + // DEFAULT-SAME: dso_local + // PIE-NOT: dso_local + // DIRECT-SAME: dso_local + // INDIRECT-NOT: dso_local + // CHECK-SAME: global i8 + #[linkage = "external"] + safe static EXTERNAL: *const u32; + + // CHECK: @WEAK = extern_weak + // DEFAULT-SAME: dso_local + // PIE-NOT: dso_local + // DIRECT-SAME: dso_local + // INDIRECT-NOT: dso_local + // CHECK-SAME: global i8 + #[linkage = "extern_weak"] + safe static WEAK: *const u32; } #[no_mangle] pub fn refer() { core::hint::black_box(VAR); + core::hint::black_box(EXTERNAL); + core::hint::black_box(WEAK); } From 36d8e77439b37c5bec246700d8778fce5a626119 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 29 Dec 2025 11:40:41 -0600 Subject: [PATCH 1395/3801] Correct hexagon "unwinder_private_data_size" Discovered while porting libstd to hexagon-unknown-qurt: the unwinder data size refers to the count of pointers in _Unwind_Exception but when I put the value "35" intiially for hexagon linux, I incorrectly considered the size of the exception context hexagon_thread_state_t data structure. Correct the value for hexagon linux and expand it to cover all hexagon architecture instead. --- library/unwind/src/libunwind.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 9ac9b54ed4a2..091efa9c5129 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -78,8 +78,8 @@ pub const unwinder_private_data_size: usize = 20; #[cfg(all(target_arch = "wasm32", target_os = "linux"))] pub const unwinder_private_data_size: usize = 2; -#[cfg(all(target_arch = "hexagon", target_os = "linux"))] -pub const unwinder_private_data_size: usize = 35; +#[cfg(target_arch = "hexagon")] +pub const unwinder_private_data_size: usize = 5; #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] pub const unwinder_private_data_size: usize = 2; From 8cd16cd18bf3259dd765e67456ee8c7095c85d98 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 7 Dec 2025 00:06:07 +0100 Subject: [PATCH 1396/3801] adjust how backtraces get rendered; always show thread name when there are multiple threads --- src/tools/miri/src/diagnostics.rs | 67 ++++++++++++------- ...pple_os_unfair_lock_move_with_queue.stderr | 1 + .../libc_pthread_cond_move.init.stderr | 5 +- ...thread_cond_move.static_initializer.stderr | 5 +- .../libc_pthread_join_detached.stderr | 1 + .../libc_pthread_join_joined.stderr | 1 + .../concurrency/libc_pthread_join_main.stderr | 1 + .../libc_pthread_join_multiple.stderr | 1 + .../concurrency/libc_pthread_join_self.stderr | 1 + .../libc_pthread_mutex_deadlock.stderr | 15 +++-- ...ibc_pthread_mutex_free_while_queued.stderr | 9 ++- .../libc_pthread_mutex_move.init.stderr | 5 +- ...hread_mutex_move.static_initializer.stderr | 5 +- ...libc_pthread_mutex_normal_reentrant.stderr | 2 +- ...ibc_pthread_mutex_read_while_queued.stderr | 1 + ...bc_pthread_mutex_write_while_queued.stderr | 1 + .../libc_pthread_mutex_wrong_owner.stderr | 1 + ...k_read_write_deadlock_single_thread.stderr | 2 +- ...ibc_pthread_rwlock_read_wrong_owner.stderr | 1 + ..._pthread_rwlock_write_read_deadlock.stderr | 15 +++-- ...k_write_read_deadlock_single_thread.stderr | 2 +- ...pthread_rwlock_write_write_deadlock.stderr | 15 +++-- ..._write_write_deadlock_single_thread.stderr | 2 +- ...bc_pthread_rwlock_write_wrong_owner.stderr | 1 + .../concurrency/windows_join_detached.stderr | 9 ++- .../concurrency/windows_join_main.stderr | 14 ++-- .../concurrency/windows_join_self.stderr | 15 +++-- .../libc/env-set_var-data-race.stderr | 1 + .../libc/eventfd_block_read_twice.stderr | 15 +++-- .../libc/eventfd_block_write_twice.stderr | 15 +++-- .../libc/fcntl_fsetfl_while_blocking.stderr | 4 +- .../libc/fs/mkstemp_immutable_arg.stderr | 5 +- .../fs/unix_open_missing_required_mode.stderr | 5 +- .../fail-dep/libc/libc-epoll-data-race.stderr | 1 + .../libc/libc_epoll_block_two_thread.stderr | 15 +++-- .../socketpair-close-while-blocked.stderr | 15 +++-- .../fail-dep/libc/socketpair-data-race.stderr | 1 + .../libc/socketpair_block_read_twice.stderr | 15 +++-- .../libc/socketpair_block_write_twice.stderr | 15 +++-- .../fail/alloc/alloc_error_handler.stderr | 15 ++--- .../alloc/alloc_error_handler_custom.stderr | 11 ++- .../alloc/alloc_error_handler_no_std.stderr | 11 ++- .../fail/alloc/global_system_mixup.stderr | 7 +- .../miri/tests/fail/alloc/stack_free.stderr | 9 ++- .../fail/async-shared-mutable.stack.stderr | 13 ++-- .../fail/async-shared-mutable.tree.stderr | 13 ++-- .../both_borrows/aliasing_mut1.stack.stderr | 9 ++- .../both_borrows/aliasing_mut1.tree.stderr | 9 ++- .../both_borrows/aliasing_mut2.stack.stderr | 9 ++- .../both_borrows/aliasing_mut2.tree.stderr | 9 ++- .../both_borrows/aliasing_mut3.stack.stderr | 9 ++- .../both_borrows/aliasing_mut3.tree.stderr | 9 ++- .../both_borrows/aliasing_mut4.stack.stderr | 9 ++- .../both_borrows/aliasing_mut4.tree.stderr | 15 +++-- .../box_exclusive_violation1.stack.stderr | 11 +-- .../box_exclusive_violation1.tree.stderr | 11 +-- .../box_noalias_violation.stack.stderr | 9 ++- .../box_noalias_violation.tree.stderr | 9 ++- .../buggy_split_at_mut.stack.stderr | 9 ++- .../both_borrows/illegal_write6.stack.stderr | 9 ++- .../both_borrows/illegal_write6.tree.stderr | 9 ++- ...invalidate_against_protector2.stack.stderr | 9 ++- .../invalidate_against_protector2.tree.stderr | 9 ++- ...invalidate_against_protector3.stack.stderr | 9 ++- .../invalidate_against_protector3.tree.stderr | 9 ++- .../issue-miri-1050-1.stack.stderr | 11 +-- .../issue-miri-1050-1.tree.stderr | 11 +-- .../issue-miri-1050-2.stack.stderr | 7 +- .../issue-miri-1050-2.tree.stderr | 7 +- .../mut_exclusive_violation1.stack.stderr | 11 +-- .../mut_exclusive_violation1.tree.stderr | 11 +-- .../newtype_pair_retagging.stack.stderr | 15 +++-- .../newtype_pair_retagging.tree.stderr | 17 +++-- .../newtype_retagging.stack.stderr | 15 +++-- .../newtype_retagging.tree.stderr | 17 +++-- .../retag_data_race_write.stack.stderr | 9 ++- .../retag_data_race_write.tree.stderr | 9 ++- .../return_invalid_shr.stack.stderr | 9 ++- .../return_invalid_shr.tree.stderr | 9 ++- .../return_invalid_shr_option.stack.stderr | 9 ++- .../return_invalid_shr_option.tree.stderr | 9 ++- .../return_invalid_shr_tuple.stack.stderr | 9 ++- .../return_invalid_shr_tuple.tree.stderr | 9 ++- .../shr_frozen_violation1.stack.stderr | 11 +-- .../shr_frozen_violation1.tree.stderr | 11 +-- .../miri/tests/fail/box-cell-alias.stderr | 9 ++- .../fail/closures/uninhabited-variant.stderr | 5 +- .../concurrency/mutex-leak-move-deadlock.rs | 2 +- .../mutex-leak-move-deadlock.stderr | 4 +- .../tests/fail/coroutine-pinned-moved.stderr | 13 ++-- .../dangling_pointer_to_raw_pointer.stderr | 5 +- .../storage_dead_dangling.stderr | 5 +- .../fail/data_race/alloc_read_race.stderr | 1 + .../fail/data_race/alloc_write_race.stderr | 1 + .../atomic_read_na_write_race1.stderr | 1 + .../atomic_read_na_write_race2.stderr | 1 + .../atomic_write_na_read_race1.stderr | 1 + .../atomic_write_na_read_race2.stderr | 1 + .../atomic_write_na_write_race1.stderr | 1 + .../atomic_write_na_write_race2.stderr | 1 + .../dangling_thread_async_race.stderr | 1 + .../data_race/dangling_thread_race.stderr | 1 + .../fail/data_race/dealloc_read_race1.stderr | 1 + .../fail/data_race/dealloc_read_race2.stderr | 1 + .../data_race/dealloc_read_race_stack.stderr | 1 + .../fail/data_race/dealloc_write_race1.stderr | 1 + .../fail/data_race/dealloc_write_race2.stderr | 1 + .../data_race/dealloc_write_race_stack.stderr | 1 + .../enable_after_join_to_main.stderr | 1 + .../fail/data_race/fence_after_load.stderr | 1 + .../local_variable_alloc_race.stderr | 1 + .../data_race/local_variable_read_race.stderr | 1 + .../local_variable_write_race.stderr | 1 + ...ze_read_read_write.match_first_load.stderr | 1 + ...e_read_read_write.match_second_load.stderr | 1 + .../mixed_size_read_write.read_write.stderr | 1 + .../mixed_size_read_write.write_read.stderr | 1 + .../mixed_size_read_write_read.stderr | 1 + .../mixed_size_write_write.fst.stderr | 1 + .../mixed_size_write_write.snd.stderr | 1 + .../fail/data_race/read_write_race.stderr | 1 + .../data_race/read_write_race_stack.stderr | 1 + .../fail/data_race/relax_acquire_race.stderr | 1 + .../fail/data_race/release_seq_race.stderr | 1 + .../release_seq_race_same_thread.stderr | 1 + .../miri/tests/fail/data_race/rmw_race.stderr | 1 + .../fail/data_race/stack_pop_race.stderr | 1 + .../fail/data_race/write_write_race.stderr | 1 + .../data_race/write_write_race_stack.stderr | 1 + ...et-discriminant-niche-variant-wrong.stderr | 5 +- .../arg_inplace_mutate.stack.stderr | 9 ++- .../arg_inplace_mutate.tree.stderr | 9 ++- .../arg_inplace_observe_during.none.stderr | 5 +- .../arg_inplace_observe_during.stack.stderr | 9 ++- .../arg_inplace_observe_during.tree.stderr | 9 ++- .../exported_symbol_bad_unwind2.both.stderr | 17 +++-- ...orted_symbol_bad_unwind2.definition.stderr | 17 +++-- .../return_pointer_aliasing_read.none.stderr | 5 +- .../return_pointer_aliasing_read.stack.stderr | 9 ++- .../return_pointer_aliasing_read.tree.stderr | 9 ++- ...return_pointer_aliasing_write.stack.stderr | 9 ++- .../return_pointer_aliasing_write.tree.stderr | 9 ++- ...nter_aliasing_write_tail_call.stack.stderr | 9 ++- ...inter_aliasing_write_tail_call.tree.stderr | 9 ++- .../simd_feature_flag_difference.stderr | 5 +- .../ptr_metadata_uninit_slice_data.stderr | 5 +- .../ptr_metadata_uninit_slice_len.stderr | 5 +- .../ptr_metadata_uninit_thin.stderr | 5 +- .../typed-swap-invalid-array.stderr | 5 +- .../typed-swap-invalid-scalar.left.stderr | 5 +- .../typed-swap-invalid-scalar.right.stderr | 5 +- .../miri/tests/fail/issue-miri-1112.stderr | 5 +- src/tools/miri/tests/fail/memleak_rc.stderr | 5 +- .../tests/fail/never_transmute_void.stderr | 5 +- .../tests/fail/overlapping_assignment.stderr | 5 +- .../miri/tests/fail/panic/abort_unwind.stderr | 17 +++-- .../miri/tests/fail/panic/bad_unwind.stderr | 11 ++- .../miri/tests/fail/panic/double_panic.stderr | 15 ++--- src/tools/miri/tests/fail/panic/no_std.stderr | 5 +- .../miri/tests/fail/panic/panic_abort1.stderr | 17 +++-- .../miri/tests/fail/panic/panic_abort2.stderr | 17 +++-- .../miri/tests/fail/panic/panic_abort3.stderr | 17 +++-- .../miri/tests/fail/panic/panic_abort4.stderr | 17 +++-- .../provenance/provenance_transmute.stderr | 5 +- .../tests/fail/ptr_swap_nonoverlapping.stderr | 11 ++- .../tests/fail/shims/fs/isolated_file.stderr | 25 ++++--- .../tests/fail/shims/isolated_stdin.stderr | 2 +- .../deallocate_against_protector1.stderr | 15 ++--- .../drop_in_place_protector.stderr | 13 ++-- .../drop_in_place_retag.stderr | 11 ++- .../invalidate_against_protector1.stderr | 9 ++- .../stacked_borrows/pointer_smuggling.stderr | 9 ++- .../retag_data_race_protected_read.stderr | 1 + .../retag_data_race_read.stderr | 9 ++- .../stacked_borrows/return_invalid_mut.stderr | 9 ++- .../return_invalid_mut_option.stderr | 9 ++- .../return_invalid_mut_tuple.stderr | 9 ++- .../tests/fail/tail_calls/cc-mismatch.stderr | 27 ++++---- .../fail/tail_calls/dangling-local-var.stderr | 9 ++- .../tests/fail/terminate-terminator.stderr | 19 +++--- .../tests/fail/tls/tls_static_dealloc.stderr | 1 + .../miri/tests/fail/tls_macro_leak.stderr | 9 ++- .../fail/tree_borrows/outside-range.stderr | 9 ++- .../fail/tree_borrows/pass_invalid_mut.stderr | 9 ++- ...peated_foreign_read_lazy_conflicted.stderr | 9 ++- .../reserved/cell-protected-write.stderr | 9 ++- .../reserved/int-protected-write.stderr | 9 ++- .../reservedim_spurious_write.with.stderr | 1 + .../reservedim_spurious_write.without.stderr | 1 + .../fail/tree_borrows/spurious_read.stderr | 9 ++- .../tree_borrows/strongly-protected.stderr | 19 +++--- ...tree_traversal_skipping_diagnostics.stderr | 9 ++- .../wildcard/protected_wildcard.stderr | 9 ++- .../wildcard/protector_conflicted.stderr | 5 +- .../strongly_protected_wildcard.stderr | 19 +++--- .../tree_borrows/write-during-2phase.stderr | 9 ++- .../unaligned_pointers/drop_in_place.stderr | 5 +- ...ld_requires_parent_struct_alignment.stderr | 5 +- ...d_requires_parent_struct_alignment2.stderr | 5 +- .../reference_to_packed.stderr | 5 +- .../uninit/uninit_alloc_diagnostic.stderr | 7 +- ...it_alloc_diagnostic_with_provenance.stderr | 7 +- .../tests/fail/unwind-action-terminate.stderr | 17 +++-- .../cast_fn_ptr_invalid_caller_arg.stderr | 5 +- .../fail/validity/invalid_char_cast.stderr | 5 +- .../fail/validity/invalid_char_match.stderr | 5 +- .../fail/validity/invalid_enum_cast.stderr | 5 +- .../tests/fail/weak_memory/weak_uninit.stderr | 1 + .../atomics/atomic_ptr_double_free.stderr | 13 ++-- .../atomic_ptr_alloc_race.dealloc.stderr | 7 +- .../atomic_ptr_alloc_race.write.stderr | 7 +- .../atomic_ptr_dealloc_write_race.stderr | 11 +-- .../atomic_ptr_write_dealloc_race.stderr | 7 +- .../genmc/fail/data_race/mpu2_rels_rlx.stderr | 7 +- .../data_race/weak_orderings.rel_rlx.stderr | 7 +- .../data_race/weak_orderings.rlx_acq.stderr | 7 +- .../data_race/weak_orderings.rlx_rlx.stderr | 7 +- .../tests/genmc/fail/loom/buggy_inc.stderr | 2 + .../fail/loom/store_buffering.genmc.stderr | 2 + .../loom/store_buffering.non_genmc.stderr | 2 + .../shims/mutex_diff_thread_unlock.stderr | 11 ++- .../fail/shims/mutex_double_unlock.stderr | 9 ++- .../fail/simple/2w2w_weak.relaxed4.stderr | 2 + .../fail/simple/2w2w_weak.release4.stderr | 2 + .../fail/simple/2w2w_weak.sc3_rel1.stderr | 2 + .../fail/simple/alloc_large.multiple.stderr | 13 ++-- .../fail/simple/alloc_large.single.stderr | 13 ++-- .../cas_failure_ord_racy_key_init.stderr | 9 ++- .../fail/tracing/partial_init.stderr | 10 ++- .../tracing/unexposed_reachable_alloc.stderr | 10 ++- .../pass/ptr_read_access.notrace.stderr | 10 ++- .../pass/ptr_read_access.trace.stderr | 10 ++- .../pass/ptr_write_access.notrace.stderr | 5 +- .../pass/ptr_write_access.trace.stderr | 5 +- .../tests/pass/alloc-access-tracking.stderr | 7 +- 235 files changed, 1000 insertions(+), 768 deletions(-) diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 10467fa79d9e..fb4029d10454 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -250,7 +250,7 @@ pub fn report_result<'tcx>( StackedBorrowsUb { .. } | TreeBorrowsUb { .. } | DataRace { .. } => Some("Undefined Behavior"), LocalDeadlock => { - labels.push(format!("this thread got stuck here")); + labels.push(format!("thread got stuck here")); None } GlobalDeadlock => { @@ -264,10 +264,7 @@ pub fn report_result<'tcx>( report_msg( DiagLevel::Error, format!("the evaluated program deadlocked"), - vec![format!( - "thread `{}` got stuck here", - ecx.machine.threads.get_thread_display_name(thread) - )], + vec![format!("thread got stuck here")], vec![], vec![], &stacktrace, @@ -563,6 +560,7 @@ fn report_msg<'tcx>( None => match thread { Some(thread_id) => machine.threads.thread_ref(thread_id).origin_span, + // This fallback is super rare, but can happen e.g. when `main` has the wrong ABI None => DUMMY_SP, }, }; @@ -608,36 +606,53 @@ fn report_msg<'tcx>( } // Add backtrace - if stacktrace.len() > 1 { - let mut backtrace_title = String::from("BACKTRACE"); - if extra_span { - write!(backtrace_title, " (of the first span)").unwrap(); + if let Some((first, rest)) = stacktrace.split_first() { + // Start with the function and thread that contain the first span. + let mut fn_and_thread = String::new(); + // Only print thread name if there are multiple threads. + if let Some(thread) = thread + && machine.threads.get_total_thread_count() > 1 + { + write!( + fn_and_thread, + "on thread `{}`", + machine.threads.get_thread_display_name(thread) + ) + .unwrap(); } - if let Some(thread) = thread { - let thread_name = machine.threads.get_thread_display_name(thread); - if thread_name != "main" { - // Only print thread name if it is not `main`. - write!(backtrace_title, " on thread `{thread_name}`").unwrap(); - }; + // Only print function name if we show a backtrace + if rest.len() > 0 { + if !fn_and_thread.is_empty() { + fn_and_thread.push_str(", "); + } + write!(fn_and_thread, "{first}").unwrap(); } - write!(backtrace_title, ":").unwrap(); - err.note(backtrace_title); - for (idx, frame_info) in stacktrace.iter().enumerate() { + if !fn_and_thread.is_empty() { + if extra_span && rest.len() > 0 { + // Print a `span_note` as otherwise the backtrace looks attached to the last + // `span_help`. We somewhat arbitrarily use the span of the surrounding function. + err.span_note( + machine.tcx.def_span(first.instance.def_id()), + format!("{level} occurred {fn_and_thread}"), + ); + } else { + err.note(format!("this is {fn_and_thread}")); + } + } + // Continue with where that function got called. + for frame_info in rest.iter() { let is_local = machine.is_local(frame_info.instance); // No span for non-local frames and the first frame (which is the error site). - if is_local && idx > 0 { - err.subdiagnostic(frame_info.as_note(machine.tcx)); + if is_local { + err.span_note(frame_info.span, format!("which got called {frame_info}")); } else { let sm = sess.source_map(); let span = sm.span_to_diagnostic_string(frame_info.span); - err.note(format!("{frame_info} at {span}")); + err.note(format!("which got called {frame_info} (at {span})")); } } - } else if stacktrace.len() == 0 && !span.is_dummy() { - err.note(format!( - "this {} occurred while pushing a call frame onto an empty stack", - level.to_str() - )); + } else if !span.is_dummy() { + err.note(format!("this {level} occurred while pushing a call frame onto an empty stack")); err.note("the span indicates which code caused the function to be called, but may not be the literal call site"); } diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr index 003ddb9b287d..e86395fae201 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr @@ -6,6 +6,7 @@ LL | let _val = atomic_ref.load(Ordering::Relaxed); | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr index f3f64a60a89b..4507c1bfa227 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr @@ -6,9 +6,8 @@ LL | libc::pthread_cond_destroy(cond2.as_mut_ptr()); | = 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 - = note: BACKTRACE: - = note: inside `check` at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC -note: inside `main` + = note: this is inside `check` +note: which got called inside `main` --> tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC | LL | check() diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr index 4056f7d9d41b..6132785b13dd 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr @@ -6,9 +6,8 @@ LL | libc::pthread_cond_destroy(&mut cond2 as *mut _); | = 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 - = note: BACKTRACE: - = note: inside `check` at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC -note: inside `main` + = note: this is inside `check` +note: which got called inside `main` --> tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC | LL | check() diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr index 618584a117e4..60c4bd7f0589 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr @@ -6,6 +6,7 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); | = 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 + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr index a9f16a96adc2..87eed26bcaa3 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr @@ -6,6 +6,7 @@ LL | ... assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); | = 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 + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr index 46c9c5d3d714..85d7fae892d1 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr @@ -6,6 +6,7 @@ LL | ... assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0); | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr index 8a16f82a9307..72c778fd0beb 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr @@ -6,6 +6,7 @@ LL | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 0); | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr index dec0139bd89a..250b9ef9dfa1 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr @@ -6,6 +6,7 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr index e3b0036c9aa9..db4811b52a3a 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC | LL | / thread::spawn(move || { @@ -21,7 +20,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC | LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); - | ^ thread `unnamed-ID` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr index 7b6e05828cea..cd6f6563469e 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr @@ -6,11 +6,10 @@ LL | self.1.deallocate(From::from(ptr.cast()), layout); | = 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 - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure + = note: this is on thread `unnamed-ID`, inside ` as std::ops::Drop>::drop` + = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) +note: which got called inside closure --> tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs:LL:CC | LL | drop(unsafe { Box::from_raw(m.get().cast::()) }); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr index a7cba0f00fe9..f9e06c75e06d 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr @@ -6,9 +6,8 @@ LL | libc::pthread_mutex_lock(&mut m2 as *mut _); | = 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 - = note: BACKTRACE: - = note: inside `check` at tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC -note: inside `main` + = note: this is inside `check` +note: which got called inside `main` --> tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC | LL | check(); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr index 71f71efa0d96..643518c60617 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr @@ -6,9 +6,8 @@ LL | libc::pthread_mutex_unlock(&mut m2 as *mut _); | = 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 - = note: BACKTRACE: - = note: inside `check` at tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC -note: inside `main` + = note: this is inside `check` +note: which got called inside `main` --> tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC | LL | check(); diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr index 782322d5c32b..d7c69e088461 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.stderr @@ -2,7 +2,7 @@ error: a thread deadlocked --> tests/fail-dep/concurrency/libc_pthread_mutex_normal_reentrant.rs:LL:CC | LL | libc::pthread_mutex_lock(&mut mutex as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this thread got stuck here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr index 42dbd5f02cb3..6b46b6f1a7f9 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr @@ -6,6 +6,7 @@ LL | ... let _val = atomic_ref.load(Ordering::Relaxed); | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr index 4705f9a1b5f0..641150a9d31e 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr @@ -6,6 +6,7 @@ LL | atomic_ref.store(0, Ordering::Relaxed); | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr index c7d858a444cc..39765c8ec830 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr @@ -6,6 +6,7 @@ LL | ... assert_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0 | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr index ea8cbcada970..57bd956dd3aa 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.rs:LL:CC | LL | libc::pthread_rwlock_wrlock(rw.get()); - | ^ thread `main` got stuck here + | ^ thread got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr index f1f5c50baf47..3b90bd446e54 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr @@ -6,6 +6,7 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr index 255632870efc..c1722e33b615 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC | LL | / thread::spawn(move || { @@ -21,7 +20,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC | LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); - | ^ thread `unnamed-ID` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr index 0208a5bae4f5..e6b692623590 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.rs:LL:CC | LL | libc::pthread_rwlock_rdlock(rw.get()); - | ^ thread `main` got stuck here + | ^ thread got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr index 6891b989d05f..ce1e0d83c772 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC | LL | / thread::spawn(move || { @@ -21,7 +20,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC | LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); - | ^ thread `unnamed-ID` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr index 314e60b02360..25435eadd735 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr @@ -2,7 +2,7 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.rs:LL:CC | LL | libc::pthread_rwlock_wrlock(rw.get()); - | ^ thread `main` got stuck here + | ^ thread got stuck here note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr index fdf4297c56ae..0a4037305c77 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr @@ -6,6 +6,7 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr index 52affb767db5..1765f0a18041 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr @@ -6,11 +6,10 @@ LL | let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle( | = 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 - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/concurrency/windows_join_detached.rs:LL:CC | LL | thread.join().unwrap(); diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr index d9cc93d0fc49..d07f16eb6a99 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/concurrency/windows_join_main.rs:LL:CC | LL | / thread::spawn(|| { @@ -22,8 +21,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/windows_join_main.rs:LL:CC | LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread `unnamed-ID` got stuck here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread got stuck here | + = note: this is on thread `unnamed-ID` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr index f5515983da2b..d82e273677e4 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/concurrency/windows_join_self.rs:LL:CC | LL | / thread::spawn(|| { @@ -24,7 +23,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/concurrency/windows_join_self.rs:LL:CC | LL | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0); - | ^ thread `unnamed-ID` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr index 2b10a322b0be..c326bb8c3c3f 100644 --- a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr +++ b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr @@ -11,6 +11,7 @@ LL | env::set_var("MY_RUST_VAR", "Ferris"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr index 53ae7ea82bd9..dc34f4748cd2 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC | LL | thread2.join().unwrap(); @@ -18,7 +17,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC | LL | let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; - | ^ thread `unnamed-ID` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr index 62810f17be88..3758484bb05e 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC | LL | thread2.join().unwrap(); @@ -18,7 +17,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC | LL | libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() - | ^ thread `unnamed-ID` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr b/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr index 307762fb12c6..f2f6f373a2a7 100644 --- a/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fcntl_fsetfl_while_blocking.stderr @@ -2,7 +2,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/fcntl_fsetfl_while_blocking.rs:LL:CC | LL | let _res = unsafe { libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr index 981f055e1294..ec7b681dfad4 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr @@ -6,9 +6,8 @@ LL | let _fd = unsafe { libc::mkstemp(s) }; | = 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 - = note: BACKTRACE: - = note: inside `test_mkstemp_immutable_arg` at tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs:LL:CC -note: inside `main` + = note: this is inside `test_mkstemp_immutable_arg` +note: which got called inside `main` --> tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs:LL:CC | LL | test_mkstemp_immutable_arg(); diff --git a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr index 298e67f1468b..9f5ea4ed021f 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr @@ -6,9 +6,8 @@ LL | let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; | = 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 - = note: BACKTRACE: - = note: inside `test_file_open_missing_needed_mode` at tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs:LL:CC -note: inside `main` + = note: this is inside `test_file_open_missing_needed_mode` +note: which got called inside `main` --> tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs:LL:CC | LL | test_file_open_missing_needed_mode(); diff --git a/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.stderr index a322de74b510..e606a03e46fa 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.stderr @@ -11,6 +11,7 @@ LL | unsafe { VAL_TWO = 51 }; | ^^^^^^^^^^^^ = 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 + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr index dba12d190317..e883bd9bd025 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC | LL | thread2.join().unwrap(); @@ -18,7 +17,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC | LL | check_epoll_wait::(epfd, &expected, -1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread `unnamed-ID` got stuck here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr index a7c660e1adcc..a7d0b60dfcb3 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/libc/socketpair-close-while-blocked.rs:LL:CC | LL | thread1.join().unwrap(); @@ -18,7 +17,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair-close-while-blocked.rs:LL:CC | LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - | ^ thread `unnamed-ID` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.stderr index 7cee4b83ba90..fa7e45bccdc5 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.stderr @@ -11,6 +11,7 @@ LL | unsafe { VAL = 1 }; | ^^^^^^^ = 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 + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr index faab75f7840b..a817f2867284 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC | LL | thread2.join().unwrap(); @@ -18,7 +17,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC | LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - | ^ thread `unnamed-ID` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr index 9f95d98beb6f..18e6222589f0 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr @@ -2,13 +2,12 @@ error: the evaluated program deadlocked --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC | LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; - | ^ thread `main` got stuck here + | ^ thread got stuck here | - = note: BACKTRACE: - = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC - = note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC -note: inside `main` + = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` + = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) + = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) +note: which got called inside `main` --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC | LL | thread2.join().unwrap(); @@ -18,7 +17,9 @@ error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC | LL | let res = unsafe { libc::write(fds[0], data.as_ptr() as *const libc::c_void, data.len()) }; - | ^ thread `unnamed-ID` got stuck here + | ^ thread got stuck here + | + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr index b85a23e3c7db..bd62bf148d7a 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr @@ -7,14 +7,13 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort() | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/alloc.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::alloc::rust_oom::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::alloc::rust_oom` at RUSTLIB/std/src/alloc.rs:LL:CC - = note: inside `std::alloc::_::__rust_alloc_error_handler` at RUSTLIB/std/src/alloc.rs:LL:CC - = note: inside `std::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `std::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC -note: inside `main` + = note: this is inside closure + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::alloc::rust_oom::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::alloc::rust_oom` (at RUSTLIB/std/src/alloc.rs:LL:CC) + = note: which got called inside `std::alloc::_::__rust_alloc_error_handler` (at RUSTLIB/std/src/alloc.rs:LL:CC) + = note: which got called inside `std::alloc::handle_alloc_error::rt_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) + = note: which got called inside `std::alloc::handle_alloc_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) +note: which got called inside `main` --> tests/fail/alloc/alloc_error_handler.rs:LL:CC | LL | handle_alloc_error(Layout::for_value(&0)); diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr index f8a96758aa2d..7e7871dc89bc 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr @@ -5,18 +5,17 @@ error: abnormal termination: the program aborted execution LL | core::intrinsics::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `alloc_error_handler` at tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC -note: inside `_::__rust_alloc_error_handler` + = note: this is inside `alloc_error_handler` +note: which got called inside `_::__rust_alloc_error_handler` --> tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC | LL | #[alloc_error_handler] | ---------------------- in this attribute macro expansion LL | fn alloc_error_handler(layout: Layout) -> ! { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `alloc::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC -note: inside `miri_start` + = note: which got called inside `alloc::alloc::handle_alloc_error::rt_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) + = note: which got called inside `alloc::alloc::handle_alloc_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) +note: which got called inside `miri_start` --> tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC | LL | handle_alloc_error(Layout::for_value(&0)); diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr index 488b1d879e87..b126cb042bee 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr @@ -7,12 +7,11 @@ error: abnormal termination: the program aborted execution LL | core::intrinsics::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `panic_handler` at tests/fail/alloc/alloc_error_handler_no_std.rs:LL:CC - = note: inside `alloc::alloc::__alloc_error_handler::__rdl_alloc_error_handler` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `alloc::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC -note: inside `miri_start` + = note: this is inside `panic_handler` + = note: which got called inside `alloc::alloc::__alloc_error_handler::__rdl_alloc_error_handler` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) + = note: which got called inside `alloc::alloc::handle_alloc_error::rt_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) + = note: which got called inside `alloc::alloc::handle_alloc_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) +note: which got called inside `miri_start` --> tests/fail/alloc/alloc_error_handler_no_std.rs:LL:CC | LL | handle_alloc_error(Layout::for_value(&0)); diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr index 5a5f7496237c..27464a5a29e8 100644 --- a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr +++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr @@ -6,10 +6,9 @@ LL | FREE(); | = 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 - = note: BACKTRACE: - = note: inside `std::sys::alloc::PLATFORM::::dealloc` at RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC - = note: inside `::deallocate` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` + = note: this is inside `std::sys::alloc::PLATFORM::::dealloc` + = note: which got called inside `::deallocate` (at RUSTLIB/std/src/alloc.rs:LL:CC) +note: which got called inside `main` --> tests/fail/alloc/global_system_mixup.rs:LL:CC | LL | unsafe { System.deallocate(ptr, l) }; diff --git a/src/tools/miri/tests/fail/alloc/stack_free.stderr b/src/tools/miri/tests/fail/alloc/stack_free.stderr index 6e98a7abc760..ec052fcb6b9a 100644 --- a/src/tools/miri/tests/fail/alloc/stack_free.stderr +++ b/src/tools/miri/tests/fail/alloc/stack_free.stderr @@ -6,11 +6,10 @@ LL | self.1.deallocate(From::from(ptr.cast()), layout); | = 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 - = note: BACKTRACE: - = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside `main` + = note: this is inside ` as std::ops::Drop>::drop` + = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) +note: which got called inside `main` --> tests/fail/alloc/stack_free.rs:LL:CC | LL | drop(bad_box); diff --git a/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr b/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr index bc3db8c6801b..9949dad12867 100644 --- a/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr +++ b/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr @@ -20,15 +20,18 @@ help: was later invalidated at offsets [OFFSET] by a SharedReadOnly retag | LL | let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`. | ^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside closure at tests/fail/async-shared-mutable.rs:LL:CC - = note: inside ` as std::future::Future>::poll` at RUSTLIB/core/src/future/poll_fn.rs:LL:CC -note: inside closure +note: error occurred inside closure + --> tests/fail/async-shared-mutable.rs:LL:CC + | +LL | core::future::poll_fn(move |_| { + | ^^^^^^^^ + = note: which got called inside ` as std::future::Future>::poll` (at RUSTLIB/core/src/future/poll_fn.rs:LL:CC) +note: which got called inside closure --> tests/fail/async-shared-mutable.rs:LL:CC | LL | .await | ^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/async-shared-mutable.rs:LL:CC | LL | assert_eq!(f.as_mut().poll(&mut cx), Poll::Pending); diff --git a/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr b/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr index dc8b4f6665a0..c204f75c4f21 100644 --- a/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr +++ b/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr @@ -28,15 +28,18 @@ help: the accessed tag later transitioned to Frozen due to a reborrow (act LL | let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`. | ^^^^^^^^^^ = help: this transition corresponds to a loss of write permissions - = note: BACKTRACE (of the first span): - = note: inside closure at tests/fail/async-shared-mutable.rs:LL:CC - = note: inside ` as std::future::Future>::poll` at RUSTLIB/core/src/future/poll_fn.rs:LL:CC -note: inside closure +note: error occurred inside closure + --> tests/fail/async-shared-mutable.rs:LL:CC + | +LL | core::future::poll_fn(move |_| { + | ^^^^^^^^ + = note: which got called inside ` as std::future::Future>::poll` (at RUSTLIB/core/src/future/poll_fn.rs:LL:CC) +note: which got called inside closure --> tests/fail/async-shared-mutable.rs:LL:CC | LL | .await | ^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/async-shared-mutable.rs:LL:CC | LL | assert_eq!(f.as_mut().poll(&mut cx), Poll::Pending); diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr index 196eaeb3fb6c..bb5e731545b7 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr @@ -16,9 +16,12 @@ help: is this argument | LL | fn safe(x: &mut i32, y: &mut i32) { | ^ - = note: BACKTRACE (of the first span): - = note: inside `safe` at tests/fail/both_borrows/aliasing_mut1.rs:LL:CC -note: inside `main` +note: error occurred inside `safe` + --> tests/fail/both_borrows/aliasing_mut1.rs:LL:CC + | +LL | fn safe(x: &mut i32, y: &mut i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/aliasing_mut1.rs:LL:CC | LL | safe_raw(xraw, xraw); diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr index b9e6e2547806..34f56696e000 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr @@ -18,9 +18,12 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | fn safe(x: &mut i32, y: &mut i32) { | ^ = help: this transition corresponds to a temporary loss of write permissions until function exit - = note: BACKTRACE (of the first span): - = note: inside `safe` at tests/fail/both_borrows/aliasing_mut1.rs:LL:CC -note: inside `main` +note: error occurred inside `safe` + --> tests/fail/both_borrows/aliasing_mut1.rs:LL:CC + | +LL | fn safe(x: &mut i32, y: &mut i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/aliasing_mut1.rs:LL:CC | LL | safe_raw(xraw, xraw); diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr index e70e5b10793c..5c574f13ff70 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr @@ -16,9 +16,12 @@ help: is this argument | LL | fn safe(x: &i32, y: &mut i32) { | ^ - = note: BACKTRACE (of the first span): - = note: inside `safe` at tests/fail/both_borrows/aliasing_mut2.rs:LL:CC -note: inside `main` +note: error occurred inside `safe` + --> tests/fail/both_borrows/aliasing_mut2.rs:LL:CC + | +LL | fn safe(x: &i32, y: &mut i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/aliasing_mut2.rs:LL:CC | LL | safe_raw(xshr, xraw); diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr index aed59b21f137..639a4ef57efe 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr @@ -18,9 +18,12 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | let _v = *x; | ^^ = help: this transition corresponds to a temporary loss of write permissions until function exit - = note: BACKTRACE (of the first span): - = note: inside `safe` at tests/fail/both_borrows/aliasing_mut2.rs:LL:CC -note: inside `main` +note: error occurred inside `safe` + --> tests/fail/both_borrows/aliasing_mut2.rs:LL:CC + | +LL | fn safe(x: &i32, y: &mut i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/aliasing_mut2.rs:LL:CC | LL | safe_raw(xshr, xraw); diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr index 9980d14e1054..4be06c65f191 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr @@ -16,9 +16,12 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique function-ent | LL | safe_raw(xraw, xshr); | ^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `safe` at tests/fail/both_borrows/aliasing_mut3.rs:LL:CC -note: inside `main` +note: error occurred inside `safe` + --> tests/fail/both_borrows/aliasing_mut3.rs:LL:CC + | +LL | fn safe(x: &mut i32, y: &i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/aliasing_mut3.rs:LL:CC | LL | safe_raw(xraw, xshr); diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr index 357d7d220192..09a54f8199c7 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr @@ -18,9 +18,12 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | fn safe(x: &mut i32, y: &i32) { | ^ = help: this transition corresponds to a temporary loss of write permissions until function exit - = note: BACKTRACE (of the first span): - = note: inside `safe` at tests/fail/both_borrows/aliasing_mut3.rs:LL:CC -note: inside `main` +note: error occurred inside `safe` + --> tests/fail/both_borrows/aliasing_mut3.rs:LL:CC + | +LL | fn safe(x: &mut i32, y: &i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/aliasing_mut3.rs:LL:CC | LL | safe_raw(xraw, xshr); diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr index eb2514df588a..e72996d43d7b 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr @@ -16,9 +16,12 @@ help: is this argument | LL | fn safe(x: &i32, y: &mut Cell) { | ^ - = note: BACKTRACE (of the first span): - = note: inside `safe` at tests/fail/both_borrows/aliasing_mut4.rs:LL:CC -note: inside `main` +note: error occurred inside `safe` + --> tests/fail/both_borrows/aliasing_mut4.rs:LL:CC + | +LL | fn safe(x: &i32, y: &mut Cell) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/aliasing_mut4.rs:LL:CC | LL | safe_raw(xshr, xraw as *mut _); diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr index c06ae0e92138..d2a533a3da8e 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr @@ -19,16 +19,19 @@ help: the protected tag was created here, in the initial state Frozen | LL | fn safe(x: &i32, y: &mut Cell) { | ^ - = note: BACKTRACE (of the first span): - = note: inside `std::mem::replace::` at RUSTLIB/core/src/mem/mod.rs:LL:CC - = note: inside `std::cell::Cell::::replace` at RUSTLIB/core/src/cell.rs:LL:CC - = note: inside `std::cell::Cell::::set` at RUSTLIB/core/src/cell.rs:LL:CC -note: inside `safe` +note: error occurred inside `std::mem::replace::` + --> RUSTLIB/core/src/mem/mod.rs:LL:CC + | +LL | pub const fn replace(dest: &mut T, src: T) -> T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::cell::Cell::::replace` (at RUSTLIB/core/src/cell.rs:LL:CC) + = note: which got called inside `std::cell::Cell::::set` (at RUSTLIB/core/src/cell.rs:LL:CC) +note: which got called inside `safe` --> tests/fail/both_borrows/aliasing_mut4.rs:LL:CC | LL | y.set(1); | ^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/aliasing_mut4.rs:LL:CC | LL | safe_raw(xshr, xraw as *mut _); diff --git a/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.stack.stderr index 009ec2dd4aaa..c9341ccdb037 100644 --- a/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.stack.stderr @@ -16,14 +16,17 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *our = 5; | ^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `unknown_code_2` at tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC -note: inside `demo_box_advanced_unique` +note: error occurred inside `unknown_code_2` + --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC + | +LL | fn unknown_code_2() { + | ^^^^^^^^^^^^^^^^^^^ +note: which got called inside `demo_box_advanced_unique` --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC | LL | unknown_code_2(); | ^^^^^^^^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC | LL | demo_box_advanced_unique(Box::new(0)); diff --git a/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.tree.stderr index d4cfab024bae..446d283694a1 100644 --- a/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.tree.stderr @@ -18,14 +18,17 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *our = 5; | ^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `unknown_code_2` at tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC -note: inside `demo_box_advanced_unique` +note: error occurred inside `unknown_code_2` + --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC + | +LL | fn unknown_code_2() { + | ^^^^^^^^^^^^^^^^^^^ +note: which got called inside `demo_box_advanced_unique` --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC | LL | unknown_code_2(); | ^^^^^^^^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC | LL | demo_box_advanced_unique(Box::new(0)); diff --git a/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr index cc6633eb24f9..1a5662b74693 100644 --- a/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr @@ -16,9 +16,12 @@ help: is this argument | LL | unsafe fn test(mut x: Box, y: *const i32) -> i32 { | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `test` at tests/fail/both_borrows/box_noalias_violation.rs:LL:CC -note: inside `main` +note: error occurred inside `test` + --> tests/fail/both_borrows/box_noalias_violation.rs:LL:CC + | +LL | unsafe fn test(mut x: Box, y: *const i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/box_noalias_violation.rs:LL:CC | LL | test(Box::from_raw(ptr), ptr); diff --git a/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr index 6a1f7761a410..6ec056828fd5 100644 --- a/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr @@ -25,9 +25,12 @@ help: the protected tag later transitioned to Unique due to a child write LL | *x = 5; | ^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference - = note: BACKTRACE (of the first span): - = note: inside `test` at tests/fail/both_borrows/box_noalias_violation.rs:LL:CC -note: inside `main` +note: error occurred inside `test` + --> tests/fail/both_borrows/box_noalias_violation.rs:LL:CC + | +LL | unsafe fn test(mut x: Box, y: *const i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/box_noalias_violation.rs:LL:CC | LL | test(Box::from_raw(ptr), ptr); diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr index c4cb2c7ae4d6..2b0d5f07994c 100644 --- a/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr @@ -22,9 +22,12 @@ help: was later invalidated at offsets [0x0..0x10] by a Unique retag | LL | from_raw_parts_mut(ptr.offset(mid as isize), len - mid), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `safe::split_at_mut::` at tests/fail/both_borrows/buggy_split_at_mut.rs:LL:CC -note: inside `main` +note: error occurred inside `safe::split_at_mut::` + --> tests/fail/both_borrows/buggy_split_at_mut.rs:LL:CC + | +LL | pub fn split_at_mut(self_: &mut [T], mid: usize) -> (&mut [T], &mut [T]) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/buggy_split_at_mut.rs:LL:CC | LL | let (a, b) = safe::split_at_mut(&mut array, 0); diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr index 40b44d77e3df..3c09bec03d6a 100644 --- a/src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr @@ -16,9 +16,12 @@ help: is this argument | LL | fn foo(a: &mut u32, y: *mut u32) -> u32 { | ^ - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/both_borrows/illegal_write6.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/both_borrows/illegal_write6.rs:LL:CC + | +LL | fn foo(a: &mut u32, y: *mut u32) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/illegal_write6.rs:LL:CC | LL | foo(x, p); diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr index 1547a6ca73a0..69bb914236da 100644 --- a/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr @@ -25,9 +25,12 @@ help: the protected tag later transitioned to Unique due to a child write LL | *a = 1; | ^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/both_borrows/illegal_write6.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/both_borrows/illegal_write6.rs:LL:CC + | +LL | fn foo(a: &mut u32, y: *mut u32) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/illegal_write6.rs:LL:CC | LL | foo(x, p); diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr index ef531be496af..d298d511d3e1 100644 --- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr @@ -16,9 +16,12 @@ help: is this argument | LL | fn inner(x: *mut i32, _y: &i32) { | ^^ - = note: BACKTRACE (of the first span): - = note: inside `inner` at tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC -note: inside `main` +note: error occurred inside `inner` + --> tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC + | +LL | fn inner(x: *mut i32, _y: &i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC | LL | inner(xraw, xref); diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr index 90a89e48e61b..b83217bce7e9 100644 --- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr @@ -19,9 +19,12 @@ help: the protected tag was created here, in the initial state Frozen | LL | fn inner(x: *mut i32, _y: &i32) { | ^^ - = note: BACKTRACE (of the first span): - = note: inside `inner` at tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC -note: inside `main` +note: error occurred inside `inner` + --> tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC + | +LL | fn inner(x: *mut i32, _y: &i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC | LL | inner(xraw, xref); diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr index caf2b702fec6..ebbc3a7ae8c0 100644 --- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr @@ -16,9 +16,12 @@ help: is this argument | LL | fn inner(x: *mut i32, _y: &i32) { | ^^ - = note: BACKTRACE (of the first span): - = note: inside `inner` at tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC -note: inside `main` +note: error occurred inside `inner` + --> tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC + | +LL | fn inner(x: *mut i32, _y: &i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC | LL | inner(ptr, &*ptr); diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr index 8bac71dcd468..1a1eb89d25f7 100644 --- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr @@ -19,9 +19,12 @@ help: the protected tag was created here, in the initial state Frozen | LL | fn inner(x: *mut i32, _y: &i32) { | ^^ - = note: BACKTRACE (of the first span): - = note: inside `inner` at tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC -note: inside `main` +note: error occurred inside `inner` + --> tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC + | +LL | fn inner(x: *mut i32, _y: &i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC | LL | inner(ptr, &*ptr); diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr index 9927d90c6469..2b2e16d1ecff 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr @@ -11,10 +11,13 @@ help: ALLOC was allocated here: | LL | let ptr = Box::into_raw(Box::new(0u16)); | ^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `std::boxed::Box::::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::boxed::Box::::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `main` +note: error occurred inside `std::boxed::Box::::from_raw_in` + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `main` --> tests/fail/both_borrows/issue-miri-1050-1.rs:LL:CC | LL | drop(Box::from_raw(ptr as *mut u32)); diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr index 9927d90c6469..2b2e16d1ecff 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr @@ -11,10 +11,13 @@ help: ALLOC was allocated here: | LL | let ptr = Box::into_raw(Box::new(0u16)); | ^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `std::boxed::Box::::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::boxed::Box::::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `main` +note: error occurred inside `std::boxed::Box::::from_raw_in` + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `main` --> tests/fail/both_borrows/issue-miri-1050-1.rs:LL:CC | LL | drop(Box::from_raw(ptr as *mut u32)); diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr index c704085f9583..f33b6cf77e4d 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr @@ -6,10 +6,9 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = 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 - = note: BACKTRACE: - = note: inside `std::boxed::Box::::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::boxed::Box::::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `main` + = note: this is inside `std::boxed::Box::::from_raw_in` + = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `main` --> tests/fail/both_borrows/issue-miri-1050-2.rs:LL:CC | LL | drop(Box::from_raw(ptr.as_ptr())); diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr index c704085f9583..f33b6cf77e4d 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr @@ -6,10 +6,9 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = 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 - = note: BACKTRACE: - = note: inside `std::boxed::Box::::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::boxed::Box::::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `main` + = note: this is inside `std::boxed::Box::::from_raw_in` + = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `main` --> tests/fail/both_borrows/issue-miri-1050-2.rs:LL:CC | LL | drop(Box::from_raw(ptr.as_ptr())); diff --git a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr index 3c8316ca5bc1..290f50f60c2b 100644 --- a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr @@ -16,14 +16,17 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *our = 5; | ^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `unknown_code_2` at tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC -note: inside `demo_mut_advanced_unique` +note: error occurred inside `unknown_code_2` + --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC + | +LL | fn unknown_code_2() { + | ^^^^^^^^^^^^^^^^^^^ +note: which got called inside `demo_mut_advanced_unique` --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC | LL | unknown_code_2(); | ^^^^^^^^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC | LL | demo_mut_advanced_unique(&mut 0); diff --git a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr index f5c1dea69f02..608e41341c3f 100644 --- a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr @@ -18,14 +18,17 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *our = 5; | ^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `unknown_code_2` at tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC -note: inside `demo_mut_advanced_unique` +note: error occurred inside `unknown_code_2` + --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC + | +LL | fn unknown_code_2() { + | ^^^^^^^^^^^^^^^^^^^ +note: which got called inside `demo_mut_advanced_unique` --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC | LL | unknown_code_2(); | ^^^^^^^^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC | LL | demo_mut_advanced_unique(&mut 0); diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr index 7cee5fb1369d..68fd20ba942a 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr @@ -16,20 +16,23 @@ help: is this argument | LL | fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { | ^^ - = note: BACKTRACE (of the first span): - = note: inside `std::boxed::Box::::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::boxed::Box::::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside closure +note: error occurred inside `std::boxed::Box::::from_raw_in` + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside closure --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC | LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ -note: inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC}>` +note: which got called inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC}>` --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC | LL | dealloc(); | ^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC | LL | / dealloc_while_running( diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr index aa07ef53b315..f0dffb8f14ad 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr @@ -25,21 +25,24 @@ help: the protected tag later transitioned to Reserved (conflicted) due to LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit - = note: BACKTRACE (of the first span): - = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure +note: error occurred inside ` as std::ops::Drop>::drop` + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | fn drop(&mut self) { + | ^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) +note: which got called inside closure --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC | LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC}>` +note: which got called inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC}>` --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC | LL | dealloc(); | ^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC | LL | / dealloc_while_running( diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr index 7bd42fc20ce7..8f1619bda403 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr @@ -16,20 +16,23 @@ help: is this argument | LL | fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { | ^^ - = note: BACKTRACE (of the first span): - = note: inside `std::boxed::Box::::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::boxed::Box::::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside closure +note: error occurred inside `std::boxed::Box::::from_raw_in` + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside closure --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC | LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ -note: inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_retagging.rs:LL:CC}>` +note: which got called inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_retagging.rs:LL:CC}>` --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC | LL | dealloc(); | ^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC | LL | / dealloc_while_running( diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr index c8a72c591762..f7a2d63dc8a9 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr @@ -25,21 +25,24 @@ help: the protected tag later transitioned to Reserved (conflicted) due to LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit - = note: BACKTRACE (of the first span): - = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure +note: error occurred inside ` as std::ops::Drop>::drop` + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | fn drop(&mut self) { + | ^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) +note: which got called inside closure --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC | LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_retagging.rs:LL:CC}>` +note: which got called inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_retagging.rs:LL:CC}>` --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC | LL | dealloc(); | ^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC | LL | / dealloc_while_running( diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr index d97850d7a444..8624205444bc 100644 --- a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr @@ -14,9 +14,12 @@ LL | let _r = &mut *p; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = 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 - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside `thread_2` at tests/fail/both_borrows/retag_data_race_write.rs:LL:CC -note: inside closure +note: error occurred on thread `unnamed-ID`, inside `thread_2` + --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC + | +LL | fn thread_2(p: SendPtr) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside closure --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC | LL | let t2 = std::thread::spawn(move || thread_2(p)); diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr index c1b37f8a9bfc..6d1dff0d5f53 100644 --- a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr @@ -14,9 +14,12 @@ LL | let _r = &mut *p; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = 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 - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside `thread_2` at tests/fail/both_borrows/retag_data_race_write.rs:LL:CC -note: inside closure +note: error occurred on thread `unnamed-ID`, inside `thread_2` + --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC + | +LL | fn thread_2(p: SendPtr) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside closure --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC | LL | let t2 = std::thread::spawn(move || thread_2(p)); diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr index 7c4fe7487012..ff9968802809 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr @@ -16,9 +16,12 @@ help: was later invalidated at offsets [0x4..0x8] by a write access | LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/both_borrows/return_invalid_shr.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC + | +LL | fn foo(x: &mut (i32, i32)) -> &i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC | LL | foo(&mut (1, 2)); diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr index a8e3553aae2c..598a95dd96c9 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr @@ -18,9 +18,12 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/both_borrows/return_invalid_shr.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC + | +LL | fn foo(x: &mut (i32, i32)) -> &i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC | LL | foo(&mut (1, 2)); diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr index 8411437ea4c9..d33782301180 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr @@ -19,9 +19,12 @@ help: was later invalidated at offsets [0x4..0x8] by a write access | LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC + | +LL | fn foo(x: &mut (i32, i32)) -> Option<&i32> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC | LL | match foo(&mut (1, 2)) { diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr index 39da45ad6db4..d303cc9b22e8 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr @@ -18,9 +18,12 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC + | +LL | fn foo(x: &mut (i32, i32)) -> Option<&i32> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC | LL | match foo(&mut (1, 2)) { diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr index a7c422aa73f2..d6063168d33d 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr @@ -19,9 +19,12 @@ help: was later invalidated at offsets [0x4..0x8] by a write access | LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC + | +LL | fn foo(x: &mut (i32, i32)) -> (&i32,) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC | LL | foo(&mut (1, 2)).0; diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr index 66b03e57905e..0c5b05ce1b94 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr @@ -18,9 +18,12 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC + | +LL | fn foo(x: &mut (i32, i32)) -> (&i32,) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC | LL | foo(&mut (1, 2)).0; diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr index eed8c0273ab1..3a05fb151cf1 100644 --- a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr @@ -11,14 +11,17 @@ help: was created by a SharedReadOnly retag at offsets [0x0..0x4] | LL | *(x as *const i32 as *mut i32) = 7; | ^ - = note: BACKTRACE (of the first span): - = note: inside `unknown_code` at tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC -note: inside `foo` +note: error occurred inside `unknown_code` + --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC + | +LL | fn unknown_code(x: &i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `foo` --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC | LL | unknown_code(&*x); | ^^^^^^^^^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC | LL | println!("{}", foo(&mut 0)); diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr index d9b75f65f752..8040cfa212a9 100644 --- a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr @@ -12,14 +12,17 @@ help: the accessed tag was created here, in the initial state Frozen | LL | fn unknown_code(x: &i32) { | ^ - = note: BACKTRACE (of the first span): - = note: inside `unknown_code` at tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC -note: inside `foo` +note: error occurred inside `unknown_code` + --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC + | +LL | fn unknown_code(x: &i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `foo` --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC | LL | unknown_code(&*x); | ^^^^^^^^^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC | LL | println!("{}", foo(&mut 0)); diff --git a/src/tools/miri/tests/fail/box-cell-alias.stderr b/src/tools/miri/tests/fail/box-cell-alias.stderr index 8e1e9370c707..c5ce263ff1c9 100644 --- a/src/tools/miri/tests/fail/box-cell-alias.stderr +++ b/src/tools/miri/tests/fail/box-cell-alias.stderr @@ -16,9 +16,12 @@ help: was later invalidated at offsets [0x0..0x1] by a Unique retag | LL | let res = helper(val, ptr); | ^^^ - = note: BACKTRACE (of the first span): - = note: inside `helper` at tests/fail/box-cell-alias.rs:LL:CC -note: inside `main` +note: error occurred inside `helper` + --> tests/fail/box-cell-alias.rs:LL:CC + | +LL | fn helper(val: Box>, ptr: *const Cell) -> u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/box-cell-alias.rs:LL:CC | LL | let res = helper(val, ptr); diff --git a/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr b/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr index 995a5e3eac14..f0f145fd1366 100644 --- a/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr +++ b/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr @@ -6,9 +6,8 @@ LL | match r { | = 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 - = note: BACKTRACE: - = note: inside closure at tests/fail/closures/uninhabited-variant.rs:LL:CC -note: inside `main` + = note: this is inside closure +note: which got called inside `main` --> tests/fail/closures/uninhabited-variant.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs index 9c73f6c03edd..5afa6c71700e 100644 --- a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs +++ b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs @@ -4,7 +4,7 @@ //@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "\n *= note:.*" -> "" // On macOS we use chekced pthread mutexes which changes the error -//@normalize-stderr-test: "this thread got stuck here" -> "thread `main` got stuck here" +//@normalize-stderr-test: "a thread got stuck here" -> "thread `main` got stuck here" //@normalize-stderr-test: "a thread deadlocked" -> "the evaluated program deadlocked" use std::mem; use std::sync::Mutex; diff --git a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr index 7784132a54ce..258f5a823fcd 100644 --- a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr +++ b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr @@ -2,9 +2,9 @@ error: the evaluated program deadlocked --> RUSTLIB/std/$FILE:LL:CC | LL | $CODE - | ^ thread `main` got stuck here + | ^ thread got stuck here | -note: inside `main` +note: which got called inside `main` --> tests/fail/concurrency/mutex-leak-move-deadlock.rs:LL:CC | LL | $CODE diff --git a/src/tools/miri/tests/fail/coroutine-pinned-moved.stderr b/src/tools/miri/tests/fail/coroutine-pinned-moved.stderr index 70ecfa9379a7..2cc3b845deba 100644 --- a/src/tools/miri/tests/fail/coroutine-pinned-moved.stderr +++ b/src/tools/miri/tests/fail/coroutine-pinned-moved.stderr @@ -16,15 +16,18 @@ help: ALLOC was deallocated here: | LL | }; // *deallocate* coroutine_iterator | ^ - = note: BACKTRACE (of the first span): - = note: inside closure at tests/fail/coroutine-pinned-moved.rs:LL:CC -note: inside ` as std::iter::Iterator>::next` +note: error occurred inside closure + --> tests/fail/coroutine-pinned-moved.rs:LL:CC + | +LL | static move || { + | ^^^^^^^^^^^^^^ +note: which got called inside ` as std::iter::Iterator>::next` --> tests/fail/coroutine-pinned-moved.rs:LL:CC | LL | match me.resume(()) { | ^^^^^^^^^^^^^ - = note: inside `std::boxed::iter::>>::next` at RUSTLIB/alloc/src/boxed/iter.rs:LL:CC -note: inside `main` + = note: which got called inside `std::boxed::iter::>>::next` (at RUSTLIB/alloc/src/boxed/iter.rs:LL:CC) +note: which got called inside `main` --> tests/fail/coroutine-pinned-moved.rs:LL:CC | LL | coroutine_iterator_2.next(); // and use moved value diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.stderr index df2b227c8097..e5471e094bc8 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.stderr @@ -6,9 +6,8 @@ LL | unsafe { &(*x).0 as *const i32 } | = 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 - = note: BACKTRACE: - = note: inside `via_ref` at tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs:LL:CC -note: inside `main` + = note: this is inside `via_ref` +note: which got called inside `main` --> tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs:LL:CC | LL | via_ref(ptr); // this is not diff --git a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr index 3a3133049b21..93bb9603ae5b 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr @@ -6,9 +6,8 @@ LL | let _ref = unsafe { &mut *(LEAK as *mut i32) }; | = 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 - = note: BACKTRACE: - = note: inside `evil` at tests/fail/dangling_pointers/storage_dead_dangling.rs:LL:CC -note: inside `main` + = note: this is inside `evil` +note: which got called inside `main` --> tests/fail/dangling_pointers/storage_dead_dangling.rs:LL:CC | LL | evil(); diff --git a/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr b/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr index d4933db2ed57..c9e9059ef085 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr +++ b/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr @@ -11,6 +11,7 @@ LL | pointer.store(Box::into_raw(Box::new_uninit()), Ordering::Relax | ^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr b/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr index da7f5ed869db..110c013ec0cc 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr @@ -11,6 +11,7 @@ LL | .store(Box::into_raw(Box::::new_uninit()) as *mut us | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr index 203e6a10e497..2d0317c7ffdf 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr @@ -11,6 +11,7 @@ LL | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr index 791dc71f9930..a5c1006e31f6 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr @@ -11,6 +11,7 @@ LL | atomic_ref.load(Ordering::SeqCst) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr index 73d963875fb1..bef2f1f6fa1a 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr @@ -11,6 +11,7 @@ LL | atomic_ref.store(32, Ordering::SeqCst) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr index 066fff5e3d36..56c669549106 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr @@ -11,6 +11,7 @@ LL | let _val = *(c.0 as *mut usize); | ^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr index 10b7d8398d9d..3b79801bfab8 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr @@ -11,6 +11,7 @@ LL | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr index bb854bc4235c..069dc9ac8de8 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr @@ -11,6 +11,7 @@ LL | atomic_ref.store(64, Ordering::SeqCst); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr index 8cecfbee9d95..a01f85ab6ce1 100644 --- a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr +++ b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr @@ -11,6 +11,7 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_race.stderr b/src/tools/miri/tests/fail/data_race/dangling_thread_race.stderr index 7260776043ea..67b254c265da 100644 --- a/src/tools/miri/tests/fail/data_race/dangling_thread_race.stderr +++ b/src/tools/miri/tests/fail/data_race/dangling_thread_race.stderr @@ -11,6 +11,7 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace 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 c4200ea96153..afe1125e7514 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 @@ -16,6 +16,7 @@ LL | let _val = *ptr.0; | ^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace 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 5ab5c9655d78..a741203dcf6d 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 @@ -20,6 +20,7 @@ LL | | std::mem::size_of::(), LL | | std::mem::align_of::(), LL | | ) | |_____________^ + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr index b52e48827b4b..4adf3f3d58d3 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr @@ -11,6 +11,7 @@ LL | *pointer.load(Ordering::Acquire) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace 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 0a574068d4e7..cfa4f06f9a9f 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 @@ -16,6 +16,7 @@ LL | *ptr.0 = 2; | ^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace 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 9fbae21eb891..3a843a4eba5d 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 @@ -20,6 +20,7 @@ LL | | std::mem::size_of::(), LL | | std::mem::align_of::(), LL | | ); | |_____________^ + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr index 0c853ccb8cc1..708fddb8f0be 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr @@ -11,6 +11,7 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr index a8eee1241b65..adcf00c8a88f 100644 --- a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr +++ b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr @@ -11,6 +11,7 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/fence_after_load.stderr b/src/tools/miri/tests/fail/data_race/fence_after_load.stderr index bf2ac30a1e3f..f2098e1d3e2d 100644 --- a/src/tools/miri/tests/fail/data_race/fence_after_load.stderr +++ b/src/tools/miri/tests/fail/data_race/fence_after_load.stderr @@ -11,6 +11,7 @@ LL | unsafe { V = 1 } | ^^^^^ = 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 + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr index 52bd7721ef22..676a62b8fefe 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr @@ -11,6 +11,7 @@ LL | StorageLive(val); | ^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr index 969b6faadbe1..269676caf5c7 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr @@ -11,6 +11,7 @@ LL | let _val = val; | ^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr index 0bf7dd28c0f9..5e26e88ce98c 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr @@ -11,6 +11,7 @@ LL | let mut val: u8 = 0; | ^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr index 087f326053b5..95b41a232b2c 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr @@ -13,6 +13,7 @@ LL | a16.load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr index 66aee703e4f3..96b0c00e08cc 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr @@ -13,6 +13,7 @@ LL | a16.load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr index 967fd45c5b36..e795f7ec8120 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr @@ -13,6 +13,7 @@ LL | a8[0].load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr index 7664c3f13e3d..ecdbb49e8b86 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr @@ -13,6 +13,7 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr index f1884bf404f1..be1bb4e507f6 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr @@ -19,6 +19,7 @@ LL | | ); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr index 7e30cf6856de..0b1eac5d5d03 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr @@ -13,6 +13,7 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr index 74bb72b986af..da62f537903a 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr @@ -13,6 +13,7 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/read_write_race.stderr b/src/tools/miri/tests/fail/data_race/read_write_race.stderr index ce063d8c532f..9163bff917e4 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/read_write_race.stderr @@ -11,6 +11,7 @@ LL | let _val = *c.0; | ^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr index 5ac78a2ecf6b..719a7162690a 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr @@ -11,6 +11,7 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr b/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr index fffde0370a2a..ea441ab36722 100644 --- a/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr +++ b/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr @@ -11,6 +11,7 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race.stderr b/src/tools/miri/tests/fail/data_race/release_seq_race.stderr index 61f5501434b8..8cb1fd7ce613 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race.stderr +++ b/src/tools/miri/tests/fail/data_race/release_seq_race.stderr @@ -11,6 +11,7 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr index 2c28ee03e786..d9a4b71ca21f 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr +++ b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr @@ -11,6 +11,7 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/rmw_race.stderr b/src/tools/miri/tests/fail/data_race/rmw_race.stderr index 04621ff07b81..c1eeef1dca76 100644 --- a/src/tools/miri/tests/fail/data_race/rmw_race.stderr +++ b/src/tools/miri/tests/fail/data_race/rmw_race.stderr @@ -11,6 +11,7 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr b/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr index 130a31ebeef0..c543bcf11150 100644 --- a/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr +++ b/src/tools/miri/tests/fail/data_race/stack_pop_race.stderr @@ -11,6 +11,7 @@ LL | let _val = unsafe { *ptr.0 }; | ^^^^^^ = 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 + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/write_write_race.stderr b/src/tools/miri/tests/fail/data_race/write_write_race.stderr index 03bee0060a4e..13f798e4da56 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/write_write_race.stderr @@ -11,6 +11,7 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr index cb2faf4ac274..eb8c2747b40e 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr @@ -11,6 +11,7 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr b/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr index f3ec20837d37..068d4b4f1329 100644 --- a/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr +++ b/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr @@ -6,9 +6,8 @@ LL | SetDiscriminant(*ptr, 1); | = 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 - = note: BACKTRACE: - = note: inside `set_discriminant` at tests/fail/enum-set-discriminant-niche-variant-wrong.rs:LL:CC -note: inside `main` + = note: this is inside `set_discriminant` +note: which got called inside `main` --> tests/fail/enum-set-discriminant-niche-variant-wrong.rs:LL:CC | LL | set_discriminant(&mut v); diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr index 8a454bedb281..f45f5c26bacb 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr @@ -21,9 +21,12 @@ help: is this argument | LL | unsafe { ptr.write(S(0)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `callee` at tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC -note: inside `main` +note: error occurred inside `callee` + --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC + | +LL | fn callee(x: S, ptr: *mut S) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC | LL | Call(_unit = callee(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr index 74706d6b9f6b..044026ee8ddc 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr @@ -30,9 +30,12 @@ help: the protected tag later transitioned to Unique due to a child write LL | unsafe { ptr.write(S(0)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference - = note: BACKTRACE (of the first span): - = note: inside `callee` at tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC -note: inside `main` +note: error occurred inside `callee` + --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC + | +LL | fn callee(x: S, ptr: *mut S) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC | LL | Call(_unit = callee(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr index 09a5b9a64961..b66d13cede1f 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr @@ -6,9 +6,8 @@ LL | unsafe { ptr.read() }; | = 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 - = note: BACKTRACE: - = note: inside `change_arg` at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC -note: inside `main` + = note: this is inside `change_arg` +note: which got called inside `main` --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC | LL | Call(_unit = change_arg(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr index 609599ef6ca8..9dc9adc13ae3 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr @@ -21,9 +21,12 @@ help: is this argument | LL | x.0 = 0; | ^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `change_arg` at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC -note: inside `main` +note: error occurred inside `change_arg` + --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC + | +LL | fn change_arg(mut x: S, ptr: *mut S) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC | LL | Call(_unit = change_arg(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr index c8c0e5c37efe..0a6c6e615a16 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr @@ -30,9 +30,12 @@ help: the protected tag later transitioned to Unique due to a child write LL | x.0 = 0; | ^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference - = note: BACKTRACE (of the first span): - = note: inside `change_arg` at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC -note: inside `main` +note: error occurred inside `change_arg` + --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC + | +LL | fn change_arg(mut x: S, ptr: *mut S) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC | LL | Call(_unit = change_arg(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr index 95f79aae6c17..dd7f52d03f20 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr @@ -14,21 +14,20 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC -note: inside `nounwind` + = note: this is inside `std::panicking::panic_with_hook` + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) +note: which got called inside `nounwind` --> tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC | LL | / extern "C-unwind" fn nounwind() { LL | | panic!(); LL | | } | |_^ -note: inside `main` +note: which got called inside `main` --> tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC | LL | unsafe { nounwind() } diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr index 95f79aae6c17..dd7f52d03f20 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr @@ -14,21 +14,20 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC -note: inside `nounwind` + = note: this is inside `std::panicking::panic_with_hook` + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) +note: which got called inside `nounwind` --> tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC | LL | / extern "C-unwind" fn nounwind() { LL | | panic!(); LL | | } | |_^ -note: inside `main` +note: which got called inside `main` --> tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC | LL | unsafe { nounwind() } diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr index d478568ceaeb..32e80ed0e61e 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr @@ -6,9 +6,8 @@ LL | unsafe { ptr.read() }; | = 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 - = note: BACKTRACE: - = note: inside `myfun` at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC -note: inside `main` + = note: this is inside `myfun` +note: which got called inside `main` --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr index 86adbab353b4..14c8e5cb8960 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr @@ -21,9 +21,12 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique in-place fun | LL | unsafe { ptr.read() }; | ^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `myfun` at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC -note: inside `main` +note: error occurred inside `myfun` + --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC + | +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr index b43e19c3905c..2e5b687f90ac 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr @@ -30,9 +30,12 @@ help: the protected tag later transitioned to Unique due to a child write LL | unsafe { ptr.read() }; | ^^^^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference - = note: BACKTRACE (of the first span): - = note: inside `myfun` at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC -note: inside `main` +note: error occurred inside `myfun` + --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC + | +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC | LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr index faae6172d751..63dee06563d1 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr @@ -21,9 +21,12 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique in-place fun | LL | unsafe { ptr.write(0) }; | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `myfun` at tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC -note: inside `main` +note: error occurred inside `myfun` + --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC + | +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC | LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr index deefb24b7850..80c111d4ddb4 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr @@ -30,9 +30,12 @@ help: the protected tag later transitioned to Unique due to a child write LL | unsafe { ptr.write(0) }; | ^^^^^^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference - = note: BACKTRACE (of the first span): - = note: inside `myfun` at tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC -note: inside `main` +note: error occurred inside `myfun` + --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC + | +LL | fn myfun(ptr: *mut i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC | LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr index 1a18857bb175..a6129451530a 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr @@ -21,9 +21,12 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique in-place fun | LL | become myfun2(ptr) | ^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `myfun2` at tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC -note: inside `main` +note: error occurred inside `myfun2` + --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC + | +LL | fn myfun2(ptr: *mut i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC | LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr index 76ccf39744d9..a6fff1c26683 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr @@ -30,9 +30,12 @@ help: the protected tag later transitioned to Unique due to a child write LL | unsafe { ptr.write(0) }; | ^^^^^^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference - = note: BACKTRACE (of the first span): - = note: inside `myfun2` at tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC -note: inside `main` +note: error occurred inside `myfun2` + --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC + | +LL | fn myfun2(ptr: *mut i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC | LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) diff --git a/src/tools/miri/tests/fail/function_calls/simd_feature_flag_difference.stderr b/src/tools/miri/tests/fail/function_calls/simd_feature_flag_difference.stderr index 755bc3e7c2c0..ef6decaece35 100644 --- a/src/tools/miri/tests/fail/function_calls/simd_feature_flag_difference.stderr +++ b/src/tools/miri/tests/fail/function_calls/simd_feature_flag_difference.stderr @@ -6,9 +6,8 @@ LL | unsafe { foo(0.0, x) } | = 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 - = note: BACKTRACE: - = note: inside `bar` at tests/fail/function_calls/simd_feature_flag_difference.rs:LL:CC -note: inside `main` + = note: this is inside `bar` +note: which got called inside `main` --> tests/fail/function_calls/simd_feature_flag_difference.rs:LL:CC | LL | let copy = bar(input); diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr index 1e7f500edb2d..697e35a660ca 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr @@ -6,9 +6,8 @@ LL | RET = PtrMetadata(*p); | = 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 - = note: BACKTRACE: - = note: inside `deref_meta` at tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs:LL:CC -note: inside `main` + = note: this is inside `deref_meta` +note: which got called inside `main` --> tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs:LL:CC | LL | let _meta = deref_meta(p.as_ptr().cast()); diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr index d284a6f6d019..ba711710b41e 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr @@ -18,9 +18,8 @@ LL | RET = PtrMetadata(*p); | = 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 - = note: BACKTRACE: - = note: inside `deref_meta` at tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs:LL:CC -note: inside `main` + = note: this is inside `deref_meta` +note: which got called inside `main` --> tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs:LL:CC | LL | let _meta = deref_meta(p.as_ptr().cast()); diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr index 7a1f3d6ea84f..104e281f2a8e 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr @@ -6,9 +6,8 @@ LL | RET = PtrMetadata(*p); | = 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 - = note: BACKTRACE: - = note: inside `deref_meta` at tests/fail/intrinsics/ptr_metadata_uninit_thin.rs:LL:CC -note: inside `main` + = note: this is inside `deref_meta` +note: which got called inside `main` --> tests/fail/intrinsics/ptr_metadata_uninit_thin.rs:LL:CC | LL | let _meta = deref_meta(p.as_ptr()); diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr index 7db795829925..619925f28968 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr @@ -6,9 +6,8 @@ LL | typed_swap_nonoverlapping(a, b); | = 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 - = note: BACKTRACE: - = note: inside `invalid_array` at tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC -note: inside `main` + = note: this is inside `invalid_array` +note: which got called inside `main` --> tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC | LL | invalid_array(); diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr index 7edf72205d9e..42bea7dd5e34 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr @@ -6,9 +6,8 @@ LL | typed_swap_nonoverlapping(a, b); | = 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 - = note: BACKTRACE: - = note: inside `invalid_scalar` at tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC -note: inside `main` + = note: this is inside `invalid_scalar` +note: which got called inside `main` --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC | LL | invalid_scalar(); diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr index aece0b6cb98a..13e8c7f9c5ae 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr @@ -6,9 +6,8 @@ LL | typed_swap_nonoverlapping(a, b); | = 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 - = note: BACKTRACE: - = note: inside `invalid_scalar` at tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC -note: inside `main` + = note: this is inside `invalid_scalar` +note: which got called inside `main` --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC | LL | invalid_scalar(); diff --git a/src/tools/miri/tests/fail/issue-miri-1112.stderr b/src/tools/miri/tests/fail/issue-miri-1112.stderr index 98f04ff1af65..0fc67c6d4fd9 100644 --- a/src/tools/miri/tests/fail/issue-miri-1112.stderr +++ b/src/tools/miri/tests/fail/issue-miri-1112.stderr @@ -6,9 +6,8 @@ LL | let obj = std::mem::transmute::(obj) | = 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 - = note: BACKTRACE: - = note: inside `FunnyPointer::from_data_ptr` at tests/fail/issue-miri-1112.rs:LL:CC -note: inside `main` + = note: this is inside `FunnyPointer::from_data_ptr` +note: which got called inside `main` --> tests/fail/issue-miri-1112.rs:LL:CC | LL | let _raw: &FunnyPointer = FunnyPointer::from_data_ptr(&hello, &meta as *const _); diff --git a/src/tools/miri/tests/fail/memleak_rc.stderr b/src/tools/miri/tests/fail/memleak_rc.stderr index df12eeed6ac6..f7b0950ef6ce 100644 --- a/src/tools/miri/tests/fail/memleak_rc.stderr +++ b/src/tools/miri/tests/fail/memleak_rc.stderr @@ -4,9 +4,8 @@ error: memory leaked: ALLOC (Rust heap, SIZE, ALIGN), allocated here: LL | Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value })) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: BACKTRACE: - = note: inside `std::rc::Rc::>>::new` at RUSTLIB/alloc/src/rc.rs:LL:CC -note: inside `main` + = note: this is inside `std::rc::Rc::>>::new` +note: which got called inside `main` --> tests/fail/memleak_rc.rs:LL:CC | LL | let x = Dummy(Rc::new(RefCell::new(None))); diff --git a/src/tools/miri/tests/fail/never_transmute_void.stderr b/src/tools/miri/tests/fail/never_transmute_void.stderr index 10ef783f2201..a236d17c49dd 100644 --- a/src/tools/miri/tests/fail/never_transmute_void.stderr +++ b/src/tools/miri/tests/fail/never_transmute_void.stderr @@ -6,9 +6,8 @@ LL | match v.0 {} | = 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 - = note: BACKTRACE: - = note: inside `m::f` at tests/fail/never_transmute_void.rs:LL:CC -note: inside `main` + = note: this is inside `m::f` +note: which got called inside `main` --> tests/fail/never_transmute_void.rs:LL:CC | LL | m::f(v); diff --git a/src/tools/miri/tests/fail/overlapping_assignment.stderr b/src/tools/miri/tests/fail/overlapping_assignment.stderr index a479e8be6481..6bf7fa446598 100644 --- a/src/tools/miri/tests/fail/overlapping_assignment.stderr +++ b/src/tools/miri/tests/fail/overlapping_assignment.stderr @@ -6,9 +6,8 @@ LL | *ptr1 = *ptr2; | = 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 - = note: BACKTRACE: - = note: inside `self_copy` at tests/fail/overlapping_assignment.rs:LL:CC -note: inside `main` + = note: this is inside `self_copy` +note: which got called inside `main` --> tests/fail/overlapping_assignment.rs:LL:CC | LL | self_copy(ptr, ptr); diff --git a/src/tools/miri/tests/fail/panic/abort_unwind.stderr b/src/tools/miri/tests/fail/panic/abort_unwind.stderr index 23dbc2fb8f39..1f45211c5ee4 100644 --- a/src/tools/miri/tests/fail/panic/abort_unwind.stderr +++ b/src/tools/miri/tests/fail/panic/abort_unwind.stderr @@ -14,15 +14,14 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC - = note: inside `std::panic::abort_unwind::<{closure@tests/fail/panic/abort_unwind.rs:LL:CC}, ()>` at RUSTLIB/core/src/panic.rs:LL:CC -note: inside `main` + = note: this is inside `std::panicking::panic_with_hook` + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) + = note: which got called inside `std::panic::abort_unwind::<{closure@tests/fail/panic/abort_unwind.rs:LL:CC}, ()>` (at RUSTLIB/core/src/panic.rs:LL:CC) +note: which got called inside `main` --> tests/fail/panic/abort_unwind.rs:LL:CC | LL | std::panic::abort_unwind(|| panic!("PANIC!!!")); diff --git a/src/tools/miri/tests/fail/panic/bad_unwind.stderr b/src/tools/miri/tests/fail/panic/bad_unwind.stderr index b0a8492b6a61..06e019bb6978 100644 --- a/src/tools/miri/tests/fail/panic/bad_unwind.stderr +++ b/src/tools/miri/tests/fail/panic/bad_unwind.stderr @@ -11,12 +11,11 @@ LL | std::panic::catch_unwind(|| unwind()).unwrap_err(); | = 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 - = note: BACKTRACE: - = note: inside closure at tests/fail/panic/bad_unwind.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@tests/fail/panic/bad_unwind.rs:LL:CC}, ()>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::<(), {closure@tests/fail/panic/bad_unwind.rs:LL:CC}>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@tests/fail/panic/bad_unwind.rs:LL:CC}, ()>` at RUSTLIB/std/src/panic.rs:LL:CC -note: inside `main` + = note: this is inside closure + = note: which got called inside `std::panicking::catch_unwind::do_call::<{closure@tests/fail/panic/bad_unwind.rs:LL:CC}, ()>` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panicking::catch_unwind::<(), {closure@tests/fail/panic/bad_unwind.rs:LL:CC}>` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panic::catch_unwind::<{closure@tests/fail/panic/bad_unwind.rs:LL:CC}, ()>` (at RUSTLIB/std/src/panic.rs:LL:CC) +note: which got called inside `main` --> tests/fail/panic/bad_unwind.rs:LL:CC | LL | std::panic::catch_unwind(|| unwind()).unwrap_err(); diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr index edbc0d8fc571..4beadb6aa647 100644 --- a/src/tools/miri/tests/fail/panic/double_panic.stderr +++ b/src/tools/miri/tests/fail/panic/double_panic.stderr @@ -17,14 +17,13 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind_nobacktrace` at RUSTLIB/core/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_in_cleanup` at RUSTLIB/core/src/panicking.rs:LL:CC -note: inside `main` + = note: this is inside `std::panicking::panic_with_hook` + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_nounwind_nobacktrace` (at RUSTLIB/core/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_in_cleanup` (at RUSTLIB/core/src/panicking.rs:LL:CC) +note: which got called inside `main` --> tests/fail/panic/double_panic.rs:LL:CC | LL | / fn main() { diff --git a/src/tools/miri/tests/fail/panic/no_std.stderr b/src/tools/miri/tests/fail/panic/no_std.stderr index dbd29e43069e..128dfddc215e 100644 --- a/src/tools/miri/tests/fail/panic/no_std.stderr +++ b/src/tools/miri/tests/fail/panic/no_std.stderr @@ -6,9 +6,8 @@ error: abnormal termination: the program aborted execution LL | core::intrinsics::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `panic_handler` at tests/fail/panic/no_std.rs:LL:CC -note: inside `miri_start` + = note: this is inside `panic_handler` +note: which got called inside `miri_start` --> tests/fail/panic/no_std.rs:LL:CC | LL | panic!("blarg I am dead") diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.stderr b/src/tools/miri/tests/fail/panic/panic_abort1.stderr index c389a9bc0750..57c8ee843b86 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort1.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort1.stderr @@ -9,15 +9,14 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::rt::__rust_abort` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `panic_abort::__rust_start_panic` at RUSTLIB/panic_abort/src/lib.rs:LL:CC - = note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC -note: inside `main` + = note: this is inside `std::rt::__rust_abort` + = note: which got called inside `panic_abort::__rust_start_panic` (at RUSTLIB/panic_abort/src/lib.rs:LL:CC) + = note: which got called inside `std::panicking::rust_panic` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panicking::panic_with_hook` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) +note: which got called inside `main` --> tests/fail/panic/panic_abort1.rs:LL:CC | LL | std::panic!("panicking from libstd"); diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.stderr b/src/tools/miri/tests/fail/panic/panic_abort2.stderr index 5fe2245cbe00..7c145634a102 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort2.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort2.stderr @@ -9,15 +9,14 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::rt::__rust_abort` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `panic_abort::__rust_start_panic` at RUSTLIB/panic_abort/src/lib.rs:LL:CC - = note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC -note: inside `main` + = note: this is inside `std::rt::__rust_abort` + = note: which got called inside `panic_abort::__rust_start_panic` (at RUSTLIB/panic_abort/src/lib.rs:LL:CC) + = note: which got called inside `std::panicking::rust_panic` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panicking::panic_with_hook` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) +note: which got called inside `main` --> tests/fail/panic/panic_abort2.rs:LL:CC | LL | std::panic!("{}-panicking from libstd", 42); diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.stderr b/src/tools/miri/tests/fail/panic/panic_abort3.stderr index cac24ca41c71..71877122b625 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort3.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort3.stderr @@ -9,15 +9,14 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::rt::__rust_abort` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `panic_abort::__rust_start_panic` at RUSTLIB/panic_abort/src/lib.rs:LL:CC - = note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC -note: inside `main` + = note: this is inside `std::rt::__rust_abort` + = note: which got called inside `panic_abort::__rust_start_panic` (at RUSTLIB/panic_abort/src/lib.rs:LL:CC) + = note: which got called inside `std::panicking::rust_panic` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panicking::panic_with_hook` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) +note: which got called inside `main` --> tests/fail/panic/panic_abort3.rs:LL:CC | LL | core::panic!("panicking from libcore"); diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.stderr b/src/tools/miri/tests/fail/panic/panic_abort4.stderr index 21195729ae82..2b4c6bea5605 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort4.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort4.stderr @@ -9,15 +9,14 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::rt::__rust_abort` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `panic_abort::__rust_start_panic` at RUSTLIB/panic_abort/src/lib.rs:LL:CC - = note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC -note: inside `main` + = note: this is inside `std::rt::__rust_abort` + = note: which got called inside `panic_abort::__rust_start_panic` (at RUSTLIB/panic_abort/src/lib.rs:LL:CC) + = note: which got called inside `std::panicking::rust_panic` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panicking::panic_with_hook` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) +note: which got called inside `main` --> tests/fail/panic/panic_abort4.rs:LL:CC | LL | core::panic!("{}-panicking from libcore", 42); diff --git a/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr b/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr index 013c39a22462..6af86ffdb2bd 100644 --- a/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr +++ b/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr @@ -6,9 +6,8 @@ LL | let _val = *left_ptr; | = 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 - = note: BACKTRACE: - = note: inside `deref` at tests/fail/provenance/provenance_transmute.rs:LL:CC -note: inside `main` + = note: this is inside `deref` +note: which got called inside `main` --> tests/fail/provenance/provenance_transmute.rs:LL:CC | LL | deref(ptr1, ptr2.with_addr(ptr1.addr())); diff --git a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr index c5f6e62b8690..7fc54636b552 100644 --- a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr +++ b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr @@ -12,12 +12,11 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC -note: inside `main` + = note: this is inside `std::panicking::panic_with_hook` + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) +note: which got called inside `main` --> tests/fail/ptr_swap_nonoverlapping.rs:LL:CC | LL | std::ptr::swap_nonoverlapping(ptr, ptr, 1); diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr index f08909d44276..eb7f70a351ad 100644 --- a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr +++ b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr @@ -6,19 +6,18 @@ LL | let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode a | = help: set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation; = help: or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning - = note: BACKTRACE: - = note: inside closure at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::cvt_r::` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - = note: inside `std::sys::fs::PLATFORM::File::open_c` at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::pal::PLATFORM::small_c_string::run_path_with_cstr::` at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - = note: inside `std::sys::fs::PLATFORM::File::open` at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC - = note: inside `std::fs::OpenOptions::_open` at RUSTLIB/std/src/fs.rs:LL:CC - = note: inside `std::fs::OpenOptions::open::<&std::path::Path>` at RUSTLIB/std/src/fs.rs:LL:CC - = note: inside `std::fs::File::open::<&str>` at RUSTLIB/std/src/fs.rs:LL:CC -note: inside `main` + = note: this is inside closure + = note: which got called inside `std::sys::pal::PLATFORM::cvt_r::` (at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC) + = note: which got called inside `std::sys::fs::PLATFORM::File::open_c` (at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC) + = note: which got called inside closure (at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC) + = note: which got called inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::` (at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC) + = note: which got called inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::` (at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC) + = note: which got called inside `std::sys::pal::PLATFORM::small_c_string::run_path_with_cstr::` (at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC) + = note: which got called inside `std::sys::fs::PLATFORM::File::open` (at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC) + = note: which got called inside `std::fs::OpenOptions::_open` (at RUSTLIB/std/src/fs.rs:LL:CC) + = note: which got called inside `std::fs::OpenOptions::open::<&std::path::Path>` (at RUSTLIB/std/src/fs.rs:LL:CC) + = note: which got called inside `std::fs::File::open::<&str>` (at RUSTLIB/std/src/fs.rs:LL:CC) +note: which got called inside `main` --> tests/fail/shims/fs/isolated_file.rs:LL:CC | LL | let _file = std::fs::File::open("file.txt").unwrap(); diff --git a/src/tools/miri/tests/fail/shims/isolated_stdin.stderr b/src/tools/miri/tests/fail/shims/isolated_stdin.stderr index 5fda90b46ef6..58f0957a668c 100644 --- a/src/tools/miri/tests/fail/shims/isolated_stdin.stderr +++ b/src/tools/miri/tests/fail/shims/isolated_stdin.stderr @@ -5,7 +5,7 @@ error: unsupported operation: `read` from stdin not available when isolation is | = help: set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation; = help: or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning -note: inside `main` +note: which got called inside `main` --> tests/fail/shims/isolated_stdin.rs:LL:CC | | ^ diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr index 8d18e5a7d605..84051e688aab 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr @@ -6,22 +6,21 @@ LL | self.1.deallocate(From::from(ptr.cast()), layout); | = 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 - = note: BACKTRACE: - = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure + = note: this is inside ` as std::ops::Drop>::drop` + = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) +note: which got called inside closure --> tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC | LL | drop(unsafe { Box::from_raw(raw) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: inside `<{closure@tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC} as std::ops::FnOnce<(&mut i32,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC -note: inside `inner` + = note: which got called inside `<{closure@tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC} as std::ops::FnOnce<(&mut i32,)>>::call_once - shim` (at RUSTLIB/core/src/ops/function.rs:LL:CC) +note: which got called inside `inner` --> tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC | LL | f(x) | ^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC | LL | / inner(Box::leak(Box::new(0)), |x| { diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr index 464c44802ec3..7f4899bb0d6f 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr @@ -16,11 +16,14 @@ help: is this argument | LL | core::ptr::drop_in_place(x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `::drop` at tests/fail/stacked_borrows/drop_in_place_protector.rs:LL:CC - = note: inside `std::ptr::drop_in_place:: - shim(Some(HasDrop))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::ptr::drop_in_place::<(HasDrop, u8)> - shim(Some((HasDrop, u8)))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC -note: inside `main` +note: error occurred inside `::drop` + --> tests/fail/stacked_borrows/drop_in_place_protector.rs:LL:CC + | +LL | fn drop(&mut self) { + | ^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::ptr::drop_in_place:: - shim(Some(HasDrop))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::ptr::drop_in_place::<(HasDrop, u8)> - shim(Some((HasDrop, u8)))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) +note: which got called inside `main` --> tests/fail/stacked_borrows/drop_in_place_protector.rs:LL:CC | LL | core::ptr::drop_in_place(x); diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr index e586d3f03994..11b3e49b852e 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr @@ -13,9 +13,14 @@ help: was created by a SharedReadOnly retag at offsets [0x0..0x1] | LL | let x = core::ptr::addr_of!(x); | ^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `std::ptr::drop_in_place:: - shim(None)` at RUSTLIB/core/src/ptr/mod.rs:LL:CC -note: inside `main` +note: error occurred inside `std::ptr::drop_in_place:: - shim(None)` + --> RUSTLIB/core/src/ptr/mod.rs:LL:CC + | +LL | / pub const unsafe fn drop_in_place(to_drop: *mut T) +LL | | where +LL | | T: [const] Destruct, + | |________________________^ +note: which got called inside `main` --> tests/fail/stacked_borrows/drop_in_place_retag.rs:LL:CC | LL | core::ptr::drop_in_place(x.cast_mut()); diff --git a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr index b082abe7b25b..17abcf0a4643 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr @@ -16,9 +16,12 @@ help: is this argument | LL | fn inner(x: *mut i32, _y: &mut i32) { | ^^ - = note: BACKTRACE (of the first span): - = note: inside `inner` at tests/fail/stacked_borrows/invalidate_against_protector1.rs:LL:CC -note: inside `main` +note: error occurred inside `inner` + --> tests/fail/stacked_borrows/invalidate_against_protector1.rs:LL:CC + | +LL | fn inner(x: *mut i32, _y: &mut i32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/stacked_borrows/invalidate_against_protector1.rs:LL:CC | LL | inner(xraw, xref); diff --git a/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr b/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr index b07599a500ee..a13ff30deda7 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr @@ -16,9 +16,12 @@ help: was later invalidated at offsets [0x0..0x1] by a write access | LL | *val = 2; // this invalidates any raw ptrs `fun1` might have created. | ^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `fun2` at tests/fail/stacked_borrows/pointer_smuggling.rs:LL:CC -note: inside `main` +note: error occurred inside `fun2` + --> tests/fail/stacked_borrows/pointer_smuggling.rs:LL:CC + | +LL | fn fun2() { + | ^^^^^^^^^ +note: which got called inside `main` --> tests/fail/stacked_borrows/pointer_smuggling.rs:LL:CC | LL | fun2(); // if they now use a raw ptr they break our reference diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr index 5b8f77600cd2..c8662628c033 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr @@ -14,6 +14,7 @@ LL | unsafe { ptr.0.read() }; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr index ee82bbbb1ed1..3a95e13f5bc0 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr @@ -14,9 +14,12 @@ LL | let _r = &*p; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = 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 - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside `thread_2` at tests/fail/stacked_borrows/retag_data_race_read.rs:LL:CC -note: inside closure +note: error occurred on thread `unnamed-ID`, inside `thread_2` + --> tests/fail/stacked_borrows/retag_data_race_read.rs:LL:CC + | +LL | fn thread_2(p: SendPtr) { + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside closure --> tests/fail/stacked_borrows/retag_data_race_read.rs:LL:CC | LL | let t2 = std::thread::spawn(move || thread_2(p)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr index 4ac82192a9fb..9148f5ae817c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr @@ -16,9 +16,12 @@ help: was later invalidated at offsets [0x0..0x8] by a read access | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/stacked_borrows/return_invalid_mut.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/stacked_borrows/return_invalid_mut.rs:LL:CC + | +LL | fn foo(x: &mut (i32, i32)) -> &mut i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/stacked_borrows/return_invalid_mut.rs:LL:CC | LL | foo(&mut (1, 2)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr index 7e7670e49f17..6cce7f9f246e 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr @@ -19,9 +19,12 @@ help: was later invalidated at offsets [0x0..0x8] by a read access | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/stacked_borrows/return_invalid_mut_option.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/stacked_borrows/return_invalid_mut_option.rs:LL:CC + | +LL | fn foo(x: &mut (i32, i32)) -> Option<&mut i32> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/stacked_borrows/return_invalid_mut_option.rs:LL:CC | LL | match foo(&mut (1, 2)) { diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr index aeaa694d2923..37d18f122b68 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr @@ -19,9 +19,12 @@ help: was later invalidated at offsets [0x0..0x8] by a read access | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/stacked_borrows/return_invalid_mut_tuple.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/stacked_borrows/return_invalid_mut_tuple.rs:LL:CC + | +LL | fn foo(x: &mut (i32, i32)) -> (&mut i32,) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/stacked_borrows/return_invalid_mut_tuple.rs:LL:CC | LL | foo(&mut (1, 2)).0; diff --git a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr index 61a57a64116b..00dd2999f540 100644 --- a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr +++ b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr @@ -6,20 +6,19 @@ LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | = 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 - = note: BACKTRACE: - = note: inside `>::call_once - shim(fn())` at RUSTLIB/core/src/ops/function.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_begin_short_backtrace::` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::ops::function::impls:: for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at RUSTLIB/core/src/ops/function.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind:: i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::catch_unwind::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC + = note: this is inside `>::call_once - shim(fn())` + = note: which got called inside `std::sys::backtrace::__rust_begin_short_backtrace::` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside closure (at RUSTLIB/std/src/rt.rs:LL:CC) + = note: which got called inside `std::ops::function::impls:: for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` (at RUSTLIB/core/src/ops/function.rs:LL:CC) + = note: which got called inside `std::panicking::catch_unwind::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panicking::catch_unwind:: i32 + std::marker::Sync + std::panic::RefUnwindSafe>` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` (at RUSTLIB/std/src/panic.rs:LL:CC) + = note: which got called inside closure (at RUSTLIB/std/src/rt.rs:LL:CC) + = note: which got called inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panicking::catch_unwind::` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` (at RUSTLIB/std/src/panic.rs:LL:CC) + = note: which got called inside `std::rt::lang_start_internal` (at RUSTLIB/std/src/rt.rs:LL:CC) + = note: which got called inside `std::rt::lang_start::<()>` (at RUSTLIB/std/src/rt.rs:LL:CC) error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr b/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr index 965dd5b399f7..a48673fb4b23 100644 --- a/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr +++ b/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr @@ -16,9 +16,12 @@ help: ALLOC was deallocated here: | LL | f(std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `g` at tests/fail/tail_calls/dangling-local-var.rs:LL:CC -note: inside `main` +note: error occurred inside `g` + --> tests/fail/tail_calls/dangling-local-var.rs:LL:CC + | +LL | fn g(x: *const i32) { + | ^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/tail_calls/dangling-local-var.rs:LL:CC | LL | f(std::ptr::null()); diff --git a/src/tools/miri/tests/fail/terminate-terminator.stderr b/src/tools/miri/tests/fail/terminate-terminator.stderr index 8ae649a392bd..7d8ae128b5d6 100644 --- a/src/tools/miri/tests/fail/terminate-terminator.stderr +++ b/src/tools/miri/tests/fail/terminate-terminator.stderr @@ -16,14 +16,13 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC -note: inside `has_cleanup` + = note: this is inside `std::panicking::panic_with_hook` + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) +note: which got called inside `has_cleanup` --> tests/fail/terminate-terminator.rs:LL:CC | LL | / fn has_cleanup() { @@ -31,12 +30,12 @@ LL | | let _f = Foo; LL | | panic!(); LL | | } | |_^ -note: inside `panic_abort` +note: which got called inside `panic_abort` --> tests/fail/terminate-terminator.rs:LL:CC | LL | has_cleanup(); | ^^^^^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/terminate-terminator.rs:LL:CC | LL | panic_abort(); diff --git a/src/tools/miri/tests/fail/tls/tls_static_dealloc.stderr b/src/tools/miri/tests/fail/tls/tls_static_dealloc.stderr index db113b6cf457..efc4bead418e 100644 --- a/src/tools/miri/tests/fail/tls/tls_static_dealloc.stderr +++ b/src/tools/miri/tests/fail/tls/tls_static_dealloc.stderr @@ -6,6 +6,7 @@ LL | let _val = *dangling_ptr.0; | = 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 + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tls_macro_leak.stderr b/src/tools/miri/tests/fail/tls_macro_leak.stderr index 512932b3cb8a..c3029bb5b4de 100644 --- a/src/tools/miri/tests/fail/tls_macro_leak.stderr +++ b/src/tools/miri/tests/fail/tls_macro_leak.stderr @@ -4,11 +4,10 @@ error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: LL | cell.set(Some(Box::leak(Box::new(123)))); | ^^^^^^^^^^^^^ | - = note: BACKTRACE: - = note: inside closure at tests/fail/tls_macro_leak.rs:LL:CC - = note: inside `std::thread::LocalKey::>>::try_with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC - = note: inside `std::thread::LocalKey::>>::with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC -note: inside closure + = note: this is inside closure + = note: which got called inside `std::thread::LocalKey::>>::try_with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` (at RUSTLIB/std/src/thread/local.rs:LL:CC) + = note: which got called inside `std::thread::LocalKey::>>::with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` (at RUSTLIB/std/src/thread/local.rs:LL:CC) +note: which got called inside closure --> tests/fail/tls_macro_leak.rs:LL:CC | LL | / TLS.with(|cell| { diff --git a/src/tools/miri/tests/fail/tree_borrows/outside-range.stderr b/src/tools/miri/tests/fail/tree_borrows/outside-range.stderr index 7960f42faa51..e504f8dde717 100644 --- a/src/tools/miri/tests/fail/tree_borrows/outside-range.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/outside-range.stderr @@ -19,9 +19,12 @@ help: the protected tag was created here, in the initial state Reserved | LL | unsafe fn stuff(x: &mut u8, y: *mut u8) { | ^ - = note: BACKTRACE (of the first span): - = note: inside `stuff` at tests/fail/tree_borrows/outside-range.rs:LL:CC -note: inside `main` +note: error occurred inside `stuff` + --> tests/fail/tree_borrows/outside-range.rs:LL:CC + | +LL | unsafe fn stuff(x: &mut u8, y: *mut u8) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/tree_borrows/outside-range.rs:LL:CC | LL | stuff(&mut *raw, raw); diff --git a/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr b/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr index 9a70d248aa0c..48527fedcc35 100644 --- a/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr @@ -30,9 +30,12 @@ help: the conflicting tag later transitioned to Frozen due to a foreign re LL | let _val = unsafe { *xraw }; // invalidate xref for writing | ^^^^^ = help: this transition corresponds to a loss of write permissions - = note: BACKTRACE (of the first span): - = note: inside `foo` at tests/fail/tree_borrows/pass_invalid_mut.rs:LL:CC -note: inside `main` +note: error occurred inside `foo` + --> tests/fail/tree_borrows/pass_invalid_mut.rs:LL:CC + | +LL | fn foo(nope: &mut i32) { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/tree_borrows/pass_invalid_mut.rs:LL:CC | LL | foo(xref); diff --git a/src/tools/miri/tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.stderr b/src/tools/miri/tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.stderr index 012d7caef501..40a3989c2dc4 100644 --- a/src/tools/miri/tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.stderr @@ -18,9 +18,12 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | do_something(*orig_ptr); | ^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit - = note: BACKTRACE (of the first span): - = note: inside `access_after_sub_1` at tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.rs:LL:CC -note: inside `main` +note: error occurred inside `access_after_sub_1` + --> tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.rs:LL:CC + | +LL | unsafe fn access_after_sub_1(x: &mut u8, orig_ptr: *mut u8) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.rs:LL:CC | LL | access_after_sub_1(&mut *(foo as *mut u8).byte_add(1), orig_ptr); diff --git a/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr index b1c3ffe86ef7..8effbe30dd6a 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr @@ -29,9 +29,12 @@ help: the protected tag was created here, in the initial state Reserved | LL | unsafe fn write_second(x: &mut UnsafeCell, y: *mut u8) { | ^ - = note: BACKTRACE (of the first span): - = note: inside `main::write_second` at tests/fail/tree_borrows/reserved/cell-protected-write.rs:LL:CC -note: inside `main` +note: error occurred inside `main::write_second` + --> tests/fail/tree_borrows/reserved/cell-protected-write.rs:LL:CC + | +LL | unsafe fn write_second(x: &mut UnsafeCell, y: *mut u8) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/tree_borrows/reserved/cell-protected-write.rs:LL:CC | LL | write_second(x, y); diff --git a/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr b/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr index 5f3129b9dc08..1bc337eb1e7a 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr @@ -29,9 +29,12 @@ help: the protected tag was created here, in the initial state Reserved | LL | unsafe fn write_second(x: &mut u8, y: *mut u8) { | ^ - = note: BACKTRACE (of the first span): - = note: inside `main::write_second` at tests/fail/tree_borrows/reserved/int-protected-write.rs:LL:CC -note: inside `main` +note: error occurred inside `main::write_second` + --> tests/fail/tree_borrows/reserved/int-protected-write.rs:LL:CC + | +LL | unsafe fn write_second(x: &mut u8, y: *mut u8) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/tree_borrows/reserved/int-protected-write.rs:LL:CC | LL | write_second(x, y); diff --git a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr index 15365e5c8bcc..c5a0b58c2185 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr @@ -32,6 +32,7 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *x = 64; | ^^^^^^^ = help: this transition corresponds to a loss of read and write permissions + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr index 4065c822866c..75c11f09ce52 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr @@ -32,6 +32,7 @@ help: the accessed tag later transitioned to Disabled due to a protector r LL | } | ^ = help: this transition corresponds to a loss of read and write permissions + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr b/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr index 8f2534d6b6e9..eef8766fd652 100644 --- a/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr @@ -31,9 +31,12 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | } | ^ = help: this transition corresponds to a temporary loss of write permissions until function exit - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside `retagx_retagy_retx_writey_rety::{closure#1}::as_mut` at tests/fail/tree_borrows/spurious_read.rs:LL:CC -note: inside closure +note: error occurred on thread `unnamed-ID`, inside `retagx_retagy_retx_writey_rety::{closure#1}::as_mut` + --> tests/fail/tree_borrows/spurious_read.rs:LL:CC + | +LL | fn as_mut(y: &mut u8, b: (usize, Arc)) -> *mut u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside closure --> tests/fail/tree_borrows/spurious_read.rs:LL:CC | LL | let _y = as_mut(unsafe { &mut *ptr.0 }, b.clone()); diff --git a/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr index 685abee3292f..9545ebf39a27 100644 --- a/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr @@ -18,22 +18,25 @@ help: the strongly protected tag was created here, in the initial state Re | LL | fn inner(x: &mut i32, f: fn(*mut i32)) { | ^ - = note: BACKTRACE (of the first span): - = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure +note: error occurred inside ` as std::ops::Drop>::drop` + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | fn drop(&mut self) { + | ^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) +note: which got called inside closure --> tests/fail/tree_borrows/strongly-protected.rs:LL:CC | LL | drop(unsafe { Box::from_raw(raw) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: inside `<{closure@tests/fail/tree_borrows/strongly-protected.rs:LL:CC} as std::ops::FnOnce<(*mut i32,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC -note: inside `inner` + = note: which got called inside `<{closure@tests/fail/tree_borrows/strongly-protected.rs:LL:CC} as std::ops::FnOnce<(*mut i32,)>>::call_once - shim` (at RUSTLIB/core/src/ops/function.rs:LL:CC) +note: which got called inside `inner` --> tests/fail/tree_borrows/strongly-protected.rs:LL:CC | LL | f(x) | ^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/tree_borrows/strongly-protected.rs:LL:CC | LL | / inner(Box::leak(Box::new(0)), |raw| { diff --git a/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr b/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr index b98d2fafcf4e..3db6dab3167b 100644 --- a/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr @@ -18,9 +18,12 @@ help: the conflicting tag was created here, in the initial state Frozen | LL | let intermediary = &root; | ^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `write_to_mut` at tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC -note: inside `main` +note: error occurred inside `write_to_mut` + --> tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC + | +LL | fn write_to_mut(m: &mut u8, other_ptr: *const u8) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC | LL | write_to_mut(data, core::ptr::addr_of!(root)); diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr index e257a3511f75..d61fe47a871b 100644 --- a/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr @@ -23,9 +23,12 @@ help: the protected tag was created here, in the initial state Reserved | LL | let mut protect = |_arg: &mut u32| { | ^^^^ - = note: BACKTRACE (of the first span): - = note: inside closure at tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC -note: inside `main` +note: error occurred inside closure + --> tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC + | +LL | let mut protect = |_arg: &mut u32| { + | ^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC | LL | protect(wild_ref); diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr index 5486eee4f063..cd797cdc0c79 100644 --- a/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr @@ -7,9 +7,8 @@ LL | unsafe { *wild = 4 }; = 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: there are no exposed tags which may perform this access here - = note: BACKTRACE: - = note: inside closure at tests/fail/tree_borrows/wildcard/protector_conflicted.rs:LL:CC -note: inside `main` + = note: this is inside closure +note: which got called inside `main` --> tests/fail/tree_borrows/wildcard/protector_conflicted.rs:LL:CC | LL | protect(ref1); diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr index 6e115b22feb1..bcc6b5f5b879 100644 --- a/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr @@ -18,22 +18,25 @@ help: the strongly protected tag was created here, in the initial state Re | LL | fn inner(x: &mut i32, f: fn(usize)) { | ^ - = note: BACKTRACE (of the first span): - = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure +note: error occurred inside ` as std::ops::Drop>::drop` + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | fn drop(&mut self) { + | ^^^^^^^^^^^^^^^^^^ + = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) +note: which got called inside closure --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC | LL | drop(unsafe { Box::from_raw(raw as *mut i32) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: inside `<{closure@tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC} as std::ops::FnOnce<(usize,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC -note: inside `inner` + = note: which got called inside `<{closure@tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC} as std::ops::FnOnce<(usize,)>>::call_once - shim` (at RUSTLIB/core/src/ops/function.rs:LL:CC) +note: which got called inside `inner` --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC | LL | f(x as *mut i32 as usize) | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: inside `main` +note: which got called inside `main` --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC | LL | / inner(Box::leak(Box::new(0)), |raw| { diff --git a/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr b/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr index 7f55e06a6bb7..11d148bc872e 100644 --- a/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr @@ -18,9 +18,12 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *alias = 42; | ^^^^^^^^^^^ = help: this transition corresponds to a loss of read and write permissions - = note: BACKTRACE (of the first span): - = note: inside `Foo::add` at tests/fail/tree_borrows/write-during-2phase.rs:LL:CC -note: inside `main` +note: error occurred inside `Foo::add` + --> tests/fail/tree_borrows/write-during-2phase.rs:LL:CC + | +LL | fn add(&mut self, n: u64) -> u64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside `main` --> tests/fail/tree_borrows/write-during-2phase.rs:LL:CC | LL | let res = f.add(unsafe { diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr index ea144f206643..6fb62b766440 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr @@ -8,9 +8,8 @@ LL | | T: [const] Destruct, | = 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 - = note: BACKTRACE: - = note: inside `std::ptr::drop_in_place:: - shim(Some(PartialDrop))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC -note: inside `main` + = note: this is inside `std::ptr::drop_in_place:: - shim(Some(PartialDrop))` +note: which got called inside `main` --> tests/fail/unaligned_pointers/drop_in_place.rs:LL:CC | LL | core::ptr::drop_in_place(p); diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr index d2a5f83a43da..61915490917e 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr @@ -6,9 +6,8 @@ LL | unsafe { (*x).x } | = 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 - = note: BACKTRACE: - = note: inside `foo` at tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs:LL:CC -note: inside `main` + = note: this is inside `foo` +note: which got called inside `main` --> tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs:LL:CC | LL | foo(odd_ptr.cast()); diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr index 39540fc8320d..58db5dda6a2e 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr @@ -6,9 +6,8 @@ LL | unsafe { (*x).packed.x } | = 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 - = note: BACKTRACE: - = note: inside `foo` at tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs:LL:CC -note: inside `main` + = note: this is inside `foo` +note: which got called inside `main` --> tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs:LL:CC | LL | foo(odd_ptr.cast()); diff --git a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr index a91be376bd16..56a3bf129ab2 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr @@ -6,9 +6,8 @@ LL | mem::transmute(x) | = 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 - = note: BACKTRACE: - = note: inside `raw_to_ref::<'_, i32>` at tests/fail/unaligned_pointers/reference_to_packed.rs:LL:CC -note: inside `main` + = note: this is inside `raw_to_ref::<'_, i32>` +note: which got called inside `main` --> tests/fail/unaligned_pointers/reference_to_packed.rs:LL:CC | LL | let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr index 25a9bddb42c7..6a2f038017c0 100644 --- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr @@ -6,10 +6,9 @@ LL | let mut order = unsafe { compare_bytes(left, right, len) as isize } | = 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 - = note: BACKTRACE: - = note: inside `::compare` at RUSTLIB/core/src/slice/cmp.rs:LL:CC - = note: inside `core::slice::cmp::::cmp` at RUSTLIB/core/src/slice/cmp.rs:LL:CC -note: inside `main` + = note: this is inside `::compare` + = note: which got called inside `core::slice::cmp::::cmp` (at RUSTLIB/core/src/slice/cmp.rs:LL:CC) +note: which got called inside `main` --> tests/fail/uninit/uninit_alloc_diagnostic.rs:LL:CC | LL | drop(slice1.cmp(slice2)); diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr index 305d8d4fbede..f40e796cca61 100644 --- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr @@ -6,10 +6,9 @@ LL | let mut order = unsafe { compare_bytes(left, right, len) as isize } | = 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 - = note: BACKTRACE: - = note: inside `::compare` at RUSTLIB/core/src/slice/cmp.rs:LL:CC - = note: inside `core::slice::cmp::::cmp` at RUSTLIB/core/src/slice/cmp.rs:LL:CC -note: inside `main` + = note: this is inside `::compare` + = note: which got called inside `core::slice::cmp::::cmp` (at RUSTLIB/core/src/slice/cmp.rs:LL:CC) +note: which got called inside `main` --> tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs:LL:CC | LL | drop(slice1.cmp(slice2)); diff --git a/src/tools/miri/tests/fail/unwind-action-terminate.stderr b/src/tools/miri/tests/fail/unwind-action-terminate.stderr index cf41c88ce377..c86d94a82025 100644 --- a/src/tools/miri/tests/fail/unwind-action-terminate.stderr +++ b/src/tools/miri/tests/fail/unwind-action-terminate.stderr @@ -14,21 +14,20 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: BACKTRACE: - = note: inside `std::panicking::panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC -note: inside `panic_abort` + = note: this is inside `std::panicking::panic_with_hook` + = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) + = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) + = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) +note: which got called inside `panic_abort` --> tests/fail/unwind-action-terminate.rs:LL:CC | LL | / extern "C" fn panic_abort() { LL | | panic!() LL | | } | |_^ -note: inside `main` +note: which got called inside `main` --> tests/fail/unwind-action-terminate.rs:LL:CC | LL | panic_abort(); diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr index c370e19ef313..5c7572c76a13 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr @@ -6,9 +6,8 @@ LL | Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue()) | = 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 - = note: BACKTRACE: - = note: inside `call` at tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC -note: inside `main` + = note: this is inside `call` +note: which got called inside `main` --> tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC | LL | call(f); diff --git a/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr index c435e51d6be8..6612bcd22394 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr @@ -6,9 +6,8 @@ LL | RET = *ptr as u32; | = 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 - = note: BACKTRACE: - = note: inside `cast` at tests/fail/validity/invalid_char_cast.rs:LL:CC -note: inside `main` + = note: this is inside `cast` +note: which got called inside `main` --> tests/fail/validity/invalid_char_cast.rs:LL:CC | LL | cast(&v as *const u32 as *const char); diff --git a/src/tools/miri/tests/fail/validity/invalid_char_match.stderr b/src/tools/miri/tests/fail/validity/invalid_char_match.stderr index 141305a00170..cda730172177 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char_match.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_char_match.stderr @@ -9,9 +9,8 @@ LL | | } | = 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 - = note: BACKTRACE: - = note: inside `switch_int` at tests/fail/validity/invalid_char_match.rs:LL:CC -note: inside `main` + = note: this is inside `switch_int` +note: which got called inside `main` --> tests/fail/validity/invalid_char_match.rs:LL:CC | LL | switch_int(&v as *const u32 as *const char); diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr index b2d876419034..6a4d0e0375af 100644 --- a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr @@ -6,9 +6,8 @@ LL | let _val = *ptr as u32; | = 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 - = note: BACKTRACE: - = note: inside `cast` at tests/fail/validity/invalid_enum_cast.rs:LL:CC -note: inside `main` + = note: this is inside `cast` +note: which got called inside `main` --> tests/fail/validity/invalid_enum_cast.rs:LL:CC | LL | cast(&v as *const u32 as *const E); diff --git a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr index 99e06e7febf5..605767db22b1 100644 --- a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr +++ b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr @@ -6,6 +6,7 @@ LL | let j2 = spawn(move || x.load(Ordering::Relaxed)); | = 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 + = note: this is on thread `unnamed-ID` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr index 7d03bd9a8eb8..333405a9172b 100644 --- a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr +++ b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr @@ -17,15 +17,18 @@ help: ALLOC was deallocated here: | LL | dealloc(ptr as *mut u8, Layout::new::()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside `free` at tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC -note: inside closure +note: error occurred on thread `unnamed-ID`, inside `free` + --> tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC + | +LL | unsafe fn free(ptr: *mut u64) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called inside closure --> tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC | LL | free(b); | ^^^^^^^ - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC}>` + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC}>` --> tests/genmc/fail/atomics/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr index bde793014bbf..6ec5843c3a0c 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr @@ -7,10 +7,9 @@ LL | dealloc(b as *mut u8, Layout::new::()); | = 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 - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC}>` + = note: this is on thread `unnamed-ID`, inside closure + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC}>` --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr index 7bfafe0ca086..fb29e326ba83 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr @@ -7,10 +7,9 @@ LL | *b = 42; | = 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 - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC}>` + = note: this is on thread `unnamed-ID`, inside closure + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC}>` --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr index 0facf6a5d177..e4af214bfb99 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr @@ -17,10 +17,13 @@ help: ALLOC was deallocated here: | LL | }), | ^ - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.rs:LL:CC - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.rs:LL:CC}>` +note: error occurred on thread `unnamed-ID`, inside closure + --> tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.rs:LL:CC + | +LL | spawn_pthread_closure(|| { + | ^^ + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.rs:LL:CC}>` --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr index 8e4ed1aba043..f5986d50bafc 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr @@ -7,10 +7,9 @@ LL | }), | = 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 - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.rs:LL:CC - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.rs:LL:CC}>` + = note: this is on thread `unnamed-ID`, inside closure + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.rs:LL:CC}>` --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr b/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr index 1ffb55f22e6e..b061b9029b3d 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr @@ -7,10 +7,9 @@ LL | X = 2; | = 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 - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/genmc/fail/data_race/mpu2_rels_rlx.rs:LL:CC - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/mpu2_rels_rlx.rs:LL:CC}>` + = note: this is on thread `unnamed-ID`, inside closure + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/mpu2_rels_rlx.rs:LL:CC}>` --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr index b0037c211c69..ad5047be60c1 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr @@ -7,10 +7,9 @@ LL | X = 2; | = 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 - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/genmc/fail/data_race/weak_orderings.rs:LL:CC - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/weak_orderings.rs:LL:CC}>` + = note: this is on thread `unnamed-ID`, inside closure + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/weak_orderings.rs:LL:CC}>` --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr index b0037c211c69..ad5047be60c1 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr @@ -7,10 +7,9 @@ LL | X = 2; | = 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 - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/genmc/fail/data_race/weak_orderings.rs:LL:CC - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/weak_orderings.rs:LL:CC}>` + = note: this is on thread `unnamed-ID`, inside closure + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/weak_orderings.rs:LL:CC}>` --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr index b0037c211c69..ad5047be60c1 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr @@ -7,10 +7,9 @@ LL | X = 2; | = 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 - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at tests/genmc/fail/data_race/weak_orderings.rs:LL:CC - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/weak_orderings.rs:LL:CC}>` + = note: this is on thread `unnamed-ID`, inside closure + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/weak_orderings.rs:LL:CC}>` --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/genmc/fail/loom/buggy_inc.stderr b/src/tools/miri/tests/genmc/fail/loom/buggy_inc.stderr index ad98ba6aeb9a..abda3e31189e 100644 --- a/src/tools/miri/tests/genmc/fail/loom/buggy_inc.stderr +++ b/src/tools/miri/tests/genmc/fail/loom/buggy_inc.stderr @@ -4,6 +4,8 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here + | + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/loom/store_buffering.genmc.stderr b/src/tools/miri/tests/genmc/fail/loom/store_buffering.genmc.stderr index 658914ba088d..176ab6a573c8 100644 --- a/src/tools/miri/tests/genmc/fail/loom/store_buffering.genmc.stderr +++ b/src/tools/miri/tests/genmc/fail/loom/store_buffering.genmc.stderr @@ -4,6 +4,8 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here + | + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/loom/store_buffering.non_genmc.stderr b/src/tools/miri/tests/genmc/fail/loom/store_buffering.non_genmc.stderr index d2036d464bb5..487ab21f28b3 100644 --- a/src/tools/miri/tests/genmc/fail/loom/store_buffering.non_genmc.stderr +++ b/src/tools/miri/tests/genmc/fail/loom/store_buffering.non_genmc.stderr @@ -3,6 +3,8 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here + | + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr index db465969cda8..5adfb066e6f1 100644 --- a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr +++ b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr @@ -7,12 +7,11 @@ LL | self.lock.inner.unlock(); | = 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 - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/std/src/sync/poison/mutex.rs:LL:CC - = note: inside `std::ptr::drop_in_place::> - shim(Some(std::sync::MutexGuard<'_, u64>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::ptr::drop_in_place::>> - shim(Some(EvilSend>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside closure + = note: this is on thread `unnamed-ID`, inside ` as std::ops::Drop>::drop` + = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::sync::MutexGuard<'_, u64>))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::ptr::drop_in_place::>> - shim(Some(EvilSend>))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::mem::drop::>>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) +note: which got called inside closure --> tests/genmc/fail/shims/mutex_diff_thread_unlock.rs:LL:CC | LL | drop(guard); diff --git a/src/tools/miri/tests/genmc/fail/shims/mutex_double_unlock.stderr b/src/tools/miri/tests/genmc/fail/shims/mutex_double_unlock.stderr index 3ba863668f1e..9fec95ae6770 100644 --- a/src/tools/miri/tests/genmc/fail/shims/mutex_double_unlock.stderr +++ b/src/tools/miri/tests/genmc/fail/shims/mutex_double_unlock.stderr @@ -7,11 +7,10 @@ LL | self.lock.inner.unlock(); | = 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 - = note: BACKTRACE: - = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/std/src/sync/poison/mutex.rs:LL:CC - = note: inside `std::ptr::drop_in_place::> - shim(Some(std::sync::MutexGuard<'_, u64>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC -note: inside `miri_start` + = note: this is inside ` as std::ops::Drop>::drop` + = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::sync::MutexGuard<'_, u64>))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) + = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) +note: which got called inside `miri_start` --> tests/genmc/fail/shims/mutex_double_unlock.rs:LL:CC | LL | drop(guard); diff --git a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.relaxed4.stderr b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.relaxed4.stderr index d6c66bf8f5c4..f7942d8ff749 100644 --- a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.relaxed4.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.relaxed4.stderr @@ -4,6 +4,8 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here + | + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.release4.stderr b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.release4.stderr index d6c66bf8f5c4..f7942d8ff749 100644 --- a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.release4.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.release4.stderr @@ -4,6 +4,8 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here + | + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.sc3_rel1.stderr b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.sc3_rel1.stderr index d6c66bf8f5c4..f7942d8ff749 100644 --- a/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.sc3_rel1.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/2w2w_weak.sc3_rel1.stderr @@ -4,6 +4,8 @@ error: abnormal termination: the program aborted execution | LL | std::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here + | + = note: this is on thread `main` note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/simple/alloc_large.multiple.stderr b/src/tools/miri/tests/genmc/fail/simple/alloc_large.multiple.stderr index 1d56614c7f03..2fc6e3d47229 100644 --- a/src/tools/miri/tests/genmc/fail/simple/alloc_large.multiple.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/alloc_large.multiple.stderr @@ -6,13 +6,12 @@ LL | AllocInit::Uninitialized => alloc.allocate(layout), | ^^^^^^^^^^^^^^^^^^^^^^ resource exhaustion occurred here | = help: in GenMC mode, the address space is limited to 4GB per thread, and addresses cannot be reused - = note: BACKTRACE: - = note: inside `alloc::raw_vec::RawVecInner::try_allocate_in` at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - = note: inside `alloc::raw_vec::RawVecInner::with_capacity_in` at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - = note: inside `alloc::raw_vec::RawVec::::with_capacity_in` at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - = note: inside `std::vec::Vec::::with_capacity_in` at RUSTLIB/alloc/src/vec/mod.rs:LL:CC - = note: inside `std::vec::Vec::::with_capacity` at RUSTLIB/alloc/src/vec/mod.rs:LL:CC -note: inside `miri_start` + = note: this is inside `alloc::raw_vec::RawVecInner::try_allocate_in` + = note: which got called inside `alloc::raw_vec::RawVecInner::with_capacity_in` (at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC) + = note: which got called inside `alloc::raw_vec::RawVec::::with_capacity_in` (at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC) + = note: which got called inside `std::vec::Vec::::with_capacity_in` (at RUSTLIB/alloc/src/vec/mod.rs:LL:CC) + = note: which got called inside `std::vec::Vec::::with_capacity` (at RUSTLIB/alloc/src/vec/mod.rs:LL:CC) +note: which got called inside `miri_start` --> tests/genmc/fail/simple/alloc_large.rs:LL:CC | LL | let _v = Vec::::with_capacity(1024 * 1024 * 1024); diff --git a/src/tools/miri/tests/genmc/fail/simple/alloc_large.single.stderr b/src/tools/miri/tests/genmc/fail/simple/alloc_large.single.stderr index 8595612811fd..dbd39e4727c2 100644 --- a/src/tools/miri/tests/genmc/fail/simple/alloc_large.single.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/alloc_large.single.stderr @@ -6,13 +6,12 @@ LL | AllocInit::Uninitialized => alloc.allocate(layout), | ^^^^^^^^^^^^^^^^^^^^^^ resource exhaustion occurred here | = help: in GenMC mode, the address space is limited to 4GB per thread, and addresses cannot be reused - = note: BACKTRACE: - = note: inside `alloc::raw_vec::RawVecInner::try_allocate_in` at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - = note: inside `alloc::raw_vec::RawVecInner::with_capacity_in` at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - = note: inside `alloc::raw_vec::RawVec::::with_capacity_in` at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC - = note: inside `std::vec::Vec::::with_capacity_in` at RUSTLIB/alloc/src/vec/mod.rs:LL:CC - = note: inside `std::vec::Vec::::with_capacity` at RUSTLIB/alloc/src/vec/mod.rs:LL:CC -note: inside `miri_start` + = note: this is inside `alloc::raw_vec::RawVecInner::try_allocate_in` + = note: which got called inside `alloc::raw_vec::RawVecInner::with_capacity_in` (at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC) + = note: which got called inside `alloc::raw_vec::RawVec::::with_capacity_in` (at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC) + = note: which got called inside `std::vec::Vec::::with_capacity_in` (at RUSTLIB/alloc/src/vec/mod.rs:LL:CC) + = note: which got called inside `std::vec::Vec::::with_capacity` (at RUSTLIB/alloc/src/vec/mod.rs:LL:CC) +note: which got called inside `miri_start` --> tests/genmc/fail/simple/alloc_large.rs:LL:CC | LL | let _v = Vec::::with_capacity(8 * 1024 * 1024 * 1024); diff --git a/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr b/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr index 31438f9352fe..71a01d8f754b 100644 --- a/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr +++ b/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr @@ -5,15 +5,14 @@ warning: GenMC currently does not model the failure ordering for `compare_exchan LL | match KEY.compare_exchange(KEY_SENTVAL, key, Release, Acquire) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside `get_or_init` at tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.rs:LL:CC -note: inside closure + = note: this is on thread `unnamed-ID`, inside `get_or_init` +note: which got called inside closure --> tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.rs:LL:CC | LL | let key = get_or_init(0); | ^^^^^^^^^^^^^^ - = note: inside ` as std::ops::FnOnce<()>>::call_once` at RUSTLIB/alloc/src/boxed.rs:LL:CC -note: inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.rs:LL:CC}>` + = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) +note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.rs:LL:CC}>` --> tests/genmc/pass/atomics/../../../utils/genmc.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/native-lib/fail/tracing/partial_init.stderr b/src/tools/miri/tests/native-lib/fail/tracing/partial_init.stderr index 1c0ad2f0dc91..4a7d24090641 100644 --- a/src/tools/miri/tests/native-lib/fail/tracing/partial_init.stderr +++ b/src/tools/miri/tests/native-lib/fail/tracing/partial_init.stderr @@ -9,9 +9,8 @@ LL | init_n(2, slice_ptr); = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free = help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here - = note: BACKTRACE: - = note: inside `partial_init` at tests/native-lib/fail/tracing/partial_init.rs:LL:CC -note: inside `main` + = note: this is inside `partial_init` +note: which got called inside `main` --> tests/native-lib/fail/tracing/partial_init.rs:LL:CC | LL | partial_init(); @@ -25,9 +24,8 @@ LL | let _val = *slice_ptr.offset(2); | = 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 - = note: BACKTRACE: - = note: inside `partial_init` at tests/native-lib/fail/tracing/partial_init.rs:LL:CC -note: inside `main` + = note: this is inside `partial_init` +note: which got called inside `main` --> tests/native-lib/fail/tracing/partial_init.rs:LL:CC | LL | partial_init(); diff --git a/src/tools/miri/tests/native-lib/fail/tracing/unexposed_reachable_alloc.stderr b/src/tools/miri/tests/native-lib/fail/tracing/unexposed_reachable_alloc.stderr index 2d34dac1b3ff..825c9666b749 100644 --- a/src/tools/miri/tests/native-lib/fail/tracing/unexposed_reachable_alloc.stderr +++ b/src/tools/miri/tests/native-lib/fail/tracing/unexposed_reachable_alloc.stderr @@ -9,9 +9,8 @@ LL | unsafe { do_one_deref(exposed) }; = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free = help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here - = note: BACKTRACE: - = note: inside `unexposed_reachable_alloc` at tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC -note: inside `main` + = note: this is inside `unexposed_reachable_alloc` +note: which got called inside `main` --> tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC | LL | unexposed_reachable_alloc(); @@ -25,9 +24,8 @@ LL | let _not_ok = *invalid; | = 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 - = note: BACKTRACE: - = note: inside `unexposed_reachable_alloc` at tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC -note: inside `main` + = note: this is inside `unexposed_reachable_alloc` +note: which got called inside `main` --> tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC | LL | unexposed_reachable_alloc(); diff --git a/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr index 200eba8050bb..cbccd8fb62f4 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr @@ -8,9 +8,8 @@ LL | unsafe { print_pointer(&x) }; = help: in particular, Miri assumes that the native call initializes all memory it has access to = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free - = note: BACKTRACE: - = note: inside `test_access_pointer` at tests/native-lib/pass/ptr_read_access.rs:LL:CC -note: inside `main` + = note: this is inside `test_access_pointer` +note: which got called inside `main` --> tests/native-lib/pass/ptr_read_access.rs:LL:CC | LL | test_access_pointer(); @@ -23,9 +22,8 @@ LL | pass_fn_ptr(Some(nop)); // this one is not | ^^^^^^^^^^^^^^^^^^^^^^ sharing a function pointer with a native function | = help: calling Rust functions from C is not supported and will, in the best case, crash the program - = note: BACKTRACE: - = note: inside `pass_fn_ptr` at tests/native-lib/pass/ptr_read_access.rs:LL:CC -note: inside `main` + = note: this is inside `pass_fn_ptr` +note: which got called inside `main` --> tests/native-lib/pass/ptr_read_access.rs:LL:CC | LL | pass_fn_ptr(); diff --git a/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr index 5c0e954deb9b..2697fb6d4353 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr @@ -9,9 +9,8 @@ LL | unsafe { print_pointer(&x) }; = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free = help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here - = note: BACKTRACE: - = note: inside `test_access_pointer` at tests/native-lib/pass/ptr_read_access.rs:LL:CC -note: inside `main` + = note: this is inside `test_access_pointer` +note: which got called inside `main` --> tests/native-lib/pass/ptr_read_access.rs:LL:CC | LL | test_access_pointer(); @@ -24,9 +23,8 @@ LL | pass_fn_ptr(Some(nop)); // this one is not | ^^^^^^^^^^^^^^^^^^^^^^ sharing a function pointer with a native function | = help: calling Rust functions from C is not supported and will, in the best case, crash the program - = note: BACKTRACE: - = note: inside `pass_fn_ptr` at tests/native-lib/pass/ptr_read_access.rs:LL:CC -note: inside `main` + = note: this is inside `pass_fn_ptr` +note: which got called inside `main` --> tests/native-lib/pass/ptr_read_access.rs:LL:CC | LL | pass_fn_ptr(); diff --git a/src/tools/miri/tests/native-lib/pass/ptr_write_access.notrace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_write_access.notrace.stderr index c893b0d9f656..c7edaa373167 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_write_access.notrace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_write_access.notrace.stderr @@ -8,9 +8,8 @@ LL | unsafe { increment_int(&mut x) }; = help: in particular, Miri assumes that the native call initializes all memory it has access to = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free - = note: BACKTRACE: - = note: inside `test_increment_int` at tests/native-lib/pass/ptr_write_access.rs:LL:CC -note: inside `main` + = note: this is inside `test_increment_int` +note: which got called inside `main` --> tests/native-lib/pass/ptr_write_access.rs:LL:CC | LL | test_increment_int(); diff --git a/src/tools/miri/tests/native-lib/pass/ptr_write_access.trace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_write_access.trace.stderr index dbf021b15bec..dacde45e17a1 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_write_access.trace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_write_access.trace.stderr @@ -9,9 +9,8 @@ LL | unsafe { increment_int(&mut x) }; = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free = help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here - = note: BACKTRACE: - = note: inside `test_increment_int` at tests/native-lib/pass/ptr_write_access.rs:LL:CC -note: inside `main` + = note: this is inside `test_increment_int` +note: which got called inside `main` --> tests/native-lib/pass/ptr_write_access.rs:LL:CC | LL | test_increment_int(); diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.stderr b/src/tools/miri/tests/pass/alloc-access-tracking.stderr index 745fd89f9f54..b5b1bc2a7bc2 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.stderr +++ b/src/tools/miri/tests/pass/alloc-access-tracking.stderr @@ -24,10 +24,9 @@ note: freed allocation ALLOC LL | self.1.deallocate(From::from(ptr.cast()), layout); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tracking was triggered here | - = note: BACKTRACE: - = note: inside `> as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::ptr::drop_in_place::>> - shim(Some(std::boxed::Box>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC -note: inside `main` + = note: this is inside `> as std::ops::Drop>::drop` + = note: which got called inside `std::ptr::drop_in_place::>> - shim(Some(std::boxed::Box>))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) +note: which got called inside `main` --> tests/pass/alloc-access-tracking.rs:LL:CC | LL | } From b49e56d5a887a2c4dd8d78e9f215a219bd03a1ac Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Mon, 29 Dec 2025 22:11:16 +0000 Subject: [PATCH 1397/3801] fix typo (this commit will be squashed after review) --- src/tools/tidy/src/extra_checks/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index d5b360cbe549..bedcd08ca13f 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -754,7 +754,7 @@ enum ExtraCheckParseError { /// `auto` specified without lang part. AutoRequiresLang, /// `if-installed` specified without lang part. - IfInsatlledRequiresLang, + IfInstalledRequiresLang, } struct ExtraCheckArg { @@ -874,7 +874,7 @@ impl FromStr for ExtraCheckArg { if !if_installed && first == "if-installed" { let Some(part) = parts.next() else { - return Err(ExtraCheckParseError::IfInsatlledRequiresLang); + return Err(ExtraCheckParseError::IfInstalledRequiresLang); }; if_installed = true; first = part; From 1514495151d4d2e0aa5a1d7157d1a4ce87e443ce Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 7 Dec 2025 10:20:33 +0100 Subject: [PATCH 1398/3801] always show the origin_span of the failing thread --- src/tools/miri/src/diagnostics.rs | 40 ++++++++----------- ...pple_os_unfair_lock_move_with_queue.stderr | 10 ++++- .../concurrency/libc_pthread_join_main.stderr | 12 +++++- .../libc_pthread_join_multiple.stderr | 10 ++++- .../concurrency/libc_pthread_join_self.stderr | 13 +++++- .../libc_pthread_mutex_deadlock.stderr | 9 ++++- ...ibc_pthread_mutex_free_while_queued.stderr | 9 +++++ ...ibc_pthread_mutex_read_while_queued.stderr | 10 ++++- ...bc_pthread_mutex_write_while_queued.stderr | 10 ++++- .../libc_pthread_mutex_wrong_owner.stderr | 9 ++++- ...ibc_pthread_rwlock_read_wrong_owner.stderr | 9 ++++- ..._pthread_rwlock_write_read_deadlock.stderr | 9 ++++- ...pthread_rwlock_write_write_deadlock.stderr | 9 ++++- ...bc_pthread_rwlock_write_wrong_owner.stderr | 9 ++++- .../concurrency/windows_join_main.stderr | 11 ++++- .../concurrency/windows_join_self.stderr | 12 +++++- .../libc/env-set_var-data-race.stderr | 12 +++++- .../libc/eventfd_block_read_twice.stderr | 12 +++++- .../libc/eventfd_block_write_twice.stderr | 14 ++++++- .../libc/libc_epoll_block_two_thread.stderr | 11 ++++- .../socketpair-close-while-blocked.stderr | 14 ++++++- .../libc/socketpair_block_read_twice.stderr | 14 ++++++- .../libc/socketpair_block_write_twice.stderr | 14 ++++++- .../retag_data_race_write.stack.stderr | 5 +++ .../retag_data_race_write.tree.stderr | 5 +++ .../fail/data_race/alloc_read_race.stderr | 13 +++++- .../fail/data_race/alloc_write_race.stderr | 12 +++++- .../atomic_read_na_write_race1.stderr | 11 ++++- .../atomic_read_na_write_race2.stderr | 12 +++++- .../atomic_write_na_read_race1.stderr | 12 +++++- .../atomic_write_na_read_race2.stderr | 11 ++++- .../atomic_write_na_write_race1.stderr | 11 ++++- .../atomic_write_na_write_race2.stderr | 12 +++++- .../dangling_thread_async_race.stderr | 10 ++++- .../fail/data_race/dealloc_read_race1.stderr | 13 +++++- .../fail/data_race/dealloc_read_race2.stderr | 11 ++++- .../data_race/dealloc_read_race_stack.stderr | 13 +++++- .../fail/data_race/dealloc_write_race1.stderr | 13 +++++- .../fail/data_race/dealloc_write_race2.stderr | 11 ++++- .../data_race/dealloc_write_race_stack.stderr | 13 +++++- .../enable_after_join_to_main.stderr | 11 ++++- .../local_variable_alloc_race.stderr | 11 ++++- .../data_race/local_variable_read_race.stderr | 12 +++++- .../local_variable_write_race.stderr | 12 +++++- ...ze_read_read_write.match_first_load.stderr | 12 +++++- ...e_read_read_write.match_second_load.stderr | 12 +++++- .../mixed_size_read_write.read_write.stderr | 12 +++++- .../mixed_size_read_write.write_read.stderr | 12 +++++- .../mixed_size_read_write_read.stderr | 9 ++++- .../mixed_size_write_write.fst.stderr | 11 ++++- .../mixed_size_write_write.snd.stderr | 11 ++++- .../fail/data_race/read_write_race.stderr | 11 ++++- .../data_race/read_write_race_stack.stderr | 12 +++++- .../fail/data_race/relax_acquire_race.stderr | 13 +++++- .../fail/data_race/release_seq_race.stderr | 13 +++++- .../release_seq_race_same_thread.stderr | 13 +++++- .../miri/tests/fail/data_race/rmw_race.stderr | 13 +++++- .../fail/data_race/write_write_race.stderr | 11 ++++- .../data_race/write_write_race_stack.stderr | 12 +++++- src/tools/miri/tests/fail/shims/ctor_ub.rs | 39 ++++++++++++++++++ .../miri/tests/fail/shims/ctor_ub.stderr | 23 +++++++++++ .../retag_data_race_protected_read.stderr | 13 +++++- .../retag_data_race_read.stderr | 5 +++ .../reservedim_spurious_write.with.stderr | 14 ++++++- .../reservedim_spurious_write.without.stderr | 14 ++++++- .../fail/tree_borrows/spurious_read.stderr | 12 ++++++ .../tests/fail/weak_memory/weak_uninit.stderr | 7 +++- .../atomics/atomic_ptr_double_free.stderr | 10 +++++ .../atomic_ptr_alloc_race.dealloc.stderr | 10 +++++ .../atomic_ptr_alloc_race.write.stderr | 10 +++++ .../atomic_ptr_dealloc_write_race.stderr | 10 +++++ .../atomic_ptr_write_dealloc_race.stderr | 10 +++++ .../genmc/fail/data_race/mpu2_rels_rlx.stderr | 10 +++++ .../data_race/weak_orderings.rel_rlx.stderr | 10 +++++ .../data_race/weak_orderings.rlx_acq.stderr | 10 +++++ .../data_race/weak_orderings.rlx_rlx.stderr | 10 +++++ .../miri/tests/genmc/fail/shims/exit.stderr | 8 ++++ .../shims/mutex_diff_thread_unlock.stderr | 9 +++++ .../cas_failure_ord_racy_key_init.stderr | 10 +++++ 79 files changed, 854 insertions(+), 83 deletions(-) create mode 100644 src/tools/miri/tests/fail/shims/ctor_ub.rs create mode 100644 src/tools/miri/tests/fail/shims/ctor_ub.stderr diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index fb4029d10454..8de30d870327 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -555,35 +555,24 @@ fn report_msg<'tcx>( thread: Option, machine: &MiriMachine<'tcx>, ) { - let span = match stacktrace.first() { - Some(fi) => fi.span, - None => - match thread { - Some(thread_id) => machine.threads.thread_ref(thread_id).origin_span, - // This fallback is super rare, but can happen e.g. when `main` has the wrong ABI - None => DUMMY_SP, - }, - }; - let sess = machine.tcx.sess; + let origin_span = thread.map(|t| machine.threads.thread_ref(t).origin_span).unwrap_or(DUMMY_SP); + let span = stacktrace.first().map(|fi| fi.span).unwrap_or(origin_span); + // The only time we do not have an origin span is for `main`, and there we check the signature + // upfront. So we should always have a span here. + assert!(!span.is_dummy()); + + let tcx = machine.tcx; let level = match diag_level { DiagLevel::Error => Level::Error, DiagLevel::Warning => Level::Warning, DiagLevel::Note => Level::Note, }; - let mut err = Diag::<()>::new(sess.dcx(), level, title); + let mut err = Diag::<()>::new(tcx.sess.dcx(), level, title); err.span(span); // Show main message. - if !span.is_dummy() { - for line in span_msg { - err.span_label(span, line); - } - } else { - // Make sure we show the message even when it is a dummy span. - for line in span_msg { - err.note(line); - } - err.note("(no span available)"); + for line in span_msg { + err.span_label(span, line); } // Show note and help messages. @@ -621,7 +610,7 @@ fn report_msg<'tcx>( .unwrap(); } // Only print function name if we show a backtrace - if rest.len() > 0 { + if rest.len() > 0 || !origin_span.is_dummy() { if !fn_and_thread.is_empty() { fn_and_thread.push_str(", "); } @@ -632,7 +621,7 @@ fn report_msg<'tcx>( // Print a `span_note` as otherwise the backtrace looks attached to the last // `span_help`. We somewhat arbitrarily use the span of the surrounding function. err.span_note( - machine.tcx.def_span(first.instance.def_id()), + tcx.def_span(first.instance.def_id()), format!("{level} occurred {fn_and_thread}"), ); } else { @@ -646,11 +635,14 @@ fn report_msg<'tcx>( if is_local { err.span_note(frame_info.span, format!("which got called {frame_info}")); } else { - let sm = sess.source_map(); + let sm = tcx.sess.source_map(); let span = sm.span_to_diagnostic_string(frame_info.span); err.note(format!("which got called {frame_info} (at {span})")); } } + if !origin_span.is_dummy() { + err.span_note(origin_span, format!("which got called indirectly due to this code")); + } } else if !span.is_dummy() { err.note(format!("this {level} occurred while pushing a call frame onto an empty stack")); err.note("the span indicates which code caused the function to be called, but may not be the literal call site"); diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr index e86395fae201..b943ac1f61ef 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr @@ -6,7 +6,15 @@ LL | let _val = atomic_ref.load(Ordering::Relaxed); | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs:LL:CC + | +LL | / ... s.spawn(|| { +LL | | ... let atomic_ref = unsafe { &*lock.get().cast::() }; +LL | | ... let _val = atomic_ref.load(Ordering::Relaxed); +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr index 85d7fae892d1..c364642fc629 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr @@ -6,7 +6,17 @@ LL | ... assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0); | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC + | +LL | let handle = thread::spawn(move || { + | __________________^ +LL | | unsafe { +LL | | assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0); +LL | | } +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr index 72c778fd0beb..b9bf801eaf61 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr @@ -6,7 +6,15 @@ LL | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 0); | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC + | +LL | ... let handle = thread::spawn(move || { + | ____________________^ +LL | | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 0); +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr index 250b9ef9dfa1..ddf3372a7277 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr @@ -6,7 +6,18 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC + | +LL | let handle = thread::spawn(|| { + | __________________^ +LL | | unsafe { +LL | | let native: libc::pthread_t = libc::pthread_self(); +LL | | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); +LL | | } +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr index db4811b52a3a..1e7b0abf341a 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr @@ -22,7 +22,14 @@ error: the evaluated program deadlocked LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); | ^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC + | +LL | / thread::spawn(move || { +LL | | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); +LL | | }) + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr index cd6f6563469e..765604ea0060 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr @@ -14,6 +14,15 @@ note: which got called inside closure | LL | drop(unsafe { Box::from_raw(m.get().cast::()) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs:LL:CC + | +LL | / s.spawn(|| { +LL | | // Ensure we happen-after the initialization write. +LL | | assert!(initialized.load(Ordering::Acquire)); +... | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr index 6b46b6f1a7f9..fd9cddebabc7 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr @@ -6,7 +6,15 @@ LL | ... let _val = atomic_ref.load(Ordering::Relaxed); | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs:LL:CC + | +LL | / ... s.spawn(|| { +LL | | ... let atomic_ref = unsafe { &*m.get().byte_add(OFFSET).cast::() }; +LL | | ... let _val = atomic_ref.load(Ordering::Relaxed); +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr index 641150a9d31e..02a0f25af492 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr @@ -6,7 +6,15 @@ LL | atomic_ref.store(0, Ordering::Relaxed); | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs:LL:CC + | +LL | / s.spawn(|| { +LL | | let atomic_ref = unsafe { &*m.get().byte_add(OFFSET).cast::() }; +LL | | atomic_ref.store(0, Ordering::Relaxed); +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr index 39765c8ec830..25dae98ef5d9 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr @@ -6,7 +6,14 @@ LL | ... assert_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0 | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs:LL:CC + | +LL | / ... thread::spawn(move || { +LL | | ... assert_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0); +LL | | ... }) + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr index 3b90bd446e54..37c7540afb27 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr @@ -6,7 +6,14 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC + | +LL | / ... thread::spawn(move || { +LL | | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); +LL | | ... }) + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr index c1722e33b615..0818f213f5e7 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr @@ -22,7 +22,14 @@ error: the evaluated program deadlocked LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); | ^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC + | +LL | / thread::spawn(move || { +LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); +LL | | }) + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr index ce1e0d83c772..4ee88c0059d2 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr @@ -22,7 +22,14 @@ error: the evaluated program deadlocked LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); | ^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC + | +LL | / thread::spawn(move || { +LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); +LL | | }) + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr index 0a4037305c77..94578338f40b 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr @@ -6,7 +6,14 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.rs:LL:CC + | +LL | / ... thread::spawn(move || { +LL | | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); +LL | | ... }) + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr index d07f16eb6a99..ee0aa254abaf 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr @@ -23,7 +23,16 @@ error: the evaluated program deadlocked LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/windows_join_main.rs:LL:CC + | +LL | / thread::spawn(|| { +LL | | unsafe { +LL | | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0); +LL | | } +LL | | }) + | |______^ = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr index d82e273677e4..561464d47179 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr @@ -25,7 +25,17 @@ error: the evaluated program deadlocked LL | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0); | ^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/concurrency/windows_join_self.rs:LL:CC + | +LL | / thread::spawn(|| { +LL | | unsafe { +LL | | let native = GetCurrentThread(); +LL | | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0); +LL | | } +LL | | }) + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr index c326bb8c3c3f..eed33569af11 100644 --- a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr +++ b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr @@ -11,7 +11,17 @@ LL | env::set_var("MY_RUST_VAR", "Ferris"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/libc/env-set_var-data-race.rs:LL:CC + | +LL | let t = thread::spawn(|| unsafe { + | _____________^ +LL | | // Access the environment in another thread without taking the env lock. +LL | | // This represents some C code that queries the environment. +LL | | libc::getenv(b"TZ/0".as_ptr().cast()); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr index dc34f4748cd2..d0c8169fe7d2 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr @@ -19,7 +19,17 @@ error: the evaluated program deadlocked LL | let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; | ^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC + | +LL | let thread2 = thread::spawn(move || { + | ___________________^ +LL | | let mut buf: [u8; 8] = [0; 8]; +... | +LL | | assert_eq!(counter, 1_u64); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr index 3758484bb05e..878059cb5ef2 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr @@ -19,7 +19,19 @@ error: the evaluated program deadlocked LL | libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() | ^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC + | +LL | let thread2 = thread::spawn(move || { + | ___________________^ +LL | | let sized_8_data = (u64::MAX - 1).to_ne_bytes(); +LL | | // Write u64::MAX - 1, so that all subsequent writes will block. +LL | | let res: i64 = unsafe { +... | +LL | | assert_eq!(res, 8); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr index e883bd9bd025..f7f77647acb5 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr @@ -19,7 +19,16 @@ error: the evaluated program deadlocked LL | check_epoll_wait::(epfd, &expected, -1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC + | +LL | let thread2 = thread::spawn(move || { + | ___________________^ +LL | | check_epoll_wait::(epfd, &expected, -1); +LL | | +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr index a7d0b60dfcb3..b1b1fddc6735 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr @@ -19,7 +19,19 @@ error: the evaluated program deadlocked LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) | ^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/libc/socketpair-close-while-blocked.rs:LL:CC + | +LL | let thread1 = thread::spawn(move || { + | ___________________^ +LL | | let mut buf: [u8; 1] = [0; 1]; +LL | | let _res: i32 = unsafe { +LL | | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) +... | +LL | | }; +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr index a817f2867284..a556ba592ec8 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr @@ -19,7 +19,19 @@ error: the evaluated program deadlocked LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) | ^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC + | +LL | let thread2 = thread::spawn(move || { + | ___________________^ +LL | | // Let this thread block on read. +LL | | let mut buf: [u8; 1] = [0; 1]; +LL | | let res = unsafe { +... | +LL | | assert_eq!(&buf, "a".as_bytes()); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr index 18e6222589f0..259ca6bd8347 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr @@ -19,7 +19,19 @@ error: the evaluated program deadlocked LL | let res = unsafe { libc::write(fds[0], data.as_ptr() as *const libc::c_void, data.len()) }; | ^ thread got stuck here | - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC + | +LL | let thread2 = thread::spawn(move || { + | ___________________^ +LL | | let data = "a".as_bytes(); +LL | | // The write below will be blocked because the buffer is already full. +LL | | let res = unsafe { libc::write(fds[0], data.as_ptr() as *const libc::c_void, data.len()) }; +LL | | +LL | | assert_eq!(res, data.len().cast_signed()); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr index 8624205444bc..d1dbdbc67f1b 100644 --- a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr @@ -24,6 +24,11 @@ note: which got called inside closure | LL | let t2 = std::thread::spawn(move || thread_2(p)); | ^^^^^^^^^^^ +note: which got called indirectly due to this code + --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC + | +LL | let t2 = std::thread::spawn(move || thread_2(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr index 6d1dff0d5f53..47abf74cb8a2 100644 --- a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr @@ -24,6 +24,11 @@ note: which got called inside closure | LL | let t2 = std::thread::spawn(move || thread_2(p)); | ^^^^^^^^^^^ +note: which got called indirectly due to this code + --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC + | +LL | let t2 = std::thread::spawn(move || thread_2(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr b/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr index c9e9059ef085..67edbfb4658e 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr +++ b/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr @@ -11,7 +11,18 @@ LL | pointer.store(Box::into_raw(Box::new_uninit()), Ordering::Relax | ^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/alloc_read_race.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let ptr = ptr; // avoid field capturing +LL | | ... let pointer = &*ptr.0; +... | +LL | | ... *pointer.load(Ordering::Relaxed) +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr b/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr index 110c013ec0cc..33c562958e20 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr @@ -11,7 +11,17 @@ LL | .store(Box::into_raw(Box::::new_uninit()) as *mut us | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/alloc_write_race.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let ptr = ptr; // avoid field capturing +LL | | ... let pointer = &*ptr.0; +LL | | ... *pointer.load(Ordering::Relaxed) = 2; +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr index 2d0317c7ffdf..6f0332e46fa3 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr @@ -11,7 +11,16 @@ LL | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/atomic_read_na_write_race1.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... (&*c.0).load(Ordering::SeqCst) +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr index a5c1006e31f6..13f95e85242a 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr @@ -11,7 +11,17 @@ LL | atomic_ref.load(Ordering::SeqCst) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/atomic_read_na_write_race2.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... let atomic_ref = &mut *c.0; +LL | | ... *atomic_ref.get_mut() = 32; +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr index bef2f1f6fa1a..0907ed3cd0a3 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr @@ -11,7 +11,17 @@ LL | atomic_ref.store(32, Ordering::SeqCst) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/atomic_write_na_read_race1.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... let atomic_ref = &mut *c.0; +LL | | ... *atomic_ref.get_mut() +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr index 56c669549106..dfc7ed012725 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr @@ -11,7 +11,16 @@ LL | let _val = *(c.0 as *mut usize); | ^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/atomic_write_na_read_race2.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... (&*c.0).store(32, Ordering::SeqCst); +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr index 3b79801bfab8..018db8364ed0 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr @@ -11,7 +11,16 @@ LL | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/atomic_write_na_write_race1.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... (&*c.0).store(64, Ordering::SeqCst); +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr index 069dc9ac8de8..ef5521448676 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr @@ -11,7 +11,17 @@ LL | atomic_ref.store(64, Ordering::SeqCst); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/atomic_write_na_write_race2.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... let atomic_ref = &mut *c.0; +LL | | ... *atomic_ref.get_mut() = 32; +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr index a01f85ab6ce1..da13b62b1cf0 100644 --- a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr +++ b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr @@ -11,7 +11,15 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/dangling_thread_async_race.rs:LL:CC + | +LL | / ... spawn(move || { +LL | | ... let c = c; // capture `c`, not just its field. +LL | | ... *c.0 = 64; +LL | | ... }) + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace 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 afe1125e7514..798c6c490b4c 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 @@ -16,7 +16,18 @@ LL | let _val = *ptr.0; | ^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/dealloc_read_race1.rs:LL:CC + | +LL | let j2 = spawn(move || { + | __________________^ +LL | | let ptr = ptr; // avoid field capturing +LL | | __rust_dealloc( +... | +LL | | ); +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace 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 a741203dcf6d..4a9e6e832b8e 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 @@ -20,7 +20,16 @@ LL | | std::mem::size_of::(), LL | | std::mem::align_of::(), LL | | ) | |_____________^ - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/dealloc_read_race2.rs:LL:CC + | +LL | let j2 = spawn(move || { + | __________________^ +LL | | let ptr = ptr; // avoid field capturing +... | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr index 4adf3f3d58d3..8b8cfaf9930c 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr @@ -11,7 +11,18 @@ LL | *pointer.load(Ordering::Acquire) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/dealloc_read_race_stack.rs:LL:CC + | +LL | ... let j1 = spawn(move || { + | ________________^ +LL | | ... let ptr = ptr; // avoid field capturing +LL | | ... let pointer = &*ptr.0; +... | +LL | | ... } +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace 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 cfa4f06f9a9f..18924d7d65ce 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 @@ -16,7 +16,18 @@ LL | *ptr.0 = 2; | ^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/dealloc_write_race1.rs:LL:CC + | +LL | let j2 = spawn(move || { + | __________________^ +LL | | let ptr = ptr; // avoid field capturing +LL | | __rust_dealloc( +... | +LL | | ); +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace 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 3a843a4eba5d..2029e0632141 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 @@ -20,7 +20,16 @@ LL | | std::mem::size_of::(), LL | | std::mem::align_of::(), LL | | ); | |_____________^ - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/dealloc_write_race2.rs:LL:CC + | +LL | let j2 = spawn(move || { + | __________________^ +LL | | let ptr = ptr; // avoid field capturing +... | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr index 708fddb8f0be..3ce6e6ce5661 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr @@ -11,7 +11,18 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/dealloc_write_race_stack.rs:LL:CC + | +LL | ... let j1 = spawn(move || { + | ________________^ +LL | | ... let ptr = ptr; // avoid field capturing +LL | | ... let pointer = &*ptr.0; +... | +LL | | ... } +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr index adcf00c8a88f..f9a18008ab75 100644 --- a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr +++ b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr @@ -11,7 +11,16 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/enable_after_join_to_main.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... *c.0 = 64; +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr index 676a62b8fefe..6caeacfb5e25 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr @@ -11,7 +11,16 @@ LL | StorageLive(val); | ^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/local_variable_alloc_race.rs:LL:CC + | +LL | / std::thread::spawn(|| { +LL | | while P.load(Relaxed).is_null() { +LL | | std::hint::spin_loop(); +... | +LL | | }) + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr index 269676caf5c7..5dfa6917e3ba 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr @@ -11,7 +11,17 @@ LL | let _val = val; | ^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/local_variable_read_race.rs:LL:CC + | +LL | let t1 = std::thread::spawn(|| { + | ______________^ +LL | | while P.load(Relaxed).is_null() { +LL | | std::hint::spin_loop(); +... | +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr index 5e26e88ce98c..2f9e22f66fff 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr @@ -11,7 +11,17 @@ LL | let mut val: u8 = 0; | ^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/local_variable_write_race.rs:LL:CC + | +LL | let t1 = std::thread::spawn(|| { + | ______________^ +LL | | while P.load(Relaxed).is_null() { +LL | | std::hint::spin_loop(); +... | +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr index 95b41a232b2c..10b5539a5b8c 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr @@ -13,7 +13,17 @@ LL | a16.load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/mixed_size_read_read_write.rs:LL:CC + | +LL | / s.spawn(|| { +LL | | thread::yield_now(); // make sure this happens last +LL | | if cfg!(match_first_load) { +LL | | a16.store(0, Ordering::SeqCst); +... | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr index 96b0c00e08cc..8e37e6161c31 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr @@ -13,7 +13,17 @@ LL | a16.load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/mixed_size_read_read_write.rs:LL:CC + | +LL | / s.spawn(|| { +LL | | thread::yield_now(); // make sure this happens last +LL | | if cfg!(match_first_load) { +LL | | a16.store(0, Ordering::SeqCst); +... | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr index e795f7ec8120..ec86c41cd160 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr @@ -13,7 +13,17 @@ LL | a8[0].load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/mixed_size_read_write.rs:LL:CC + | +LL | / s.spawn(|| { +LL | | if cfg!(read_write) { +LL | | // Let the other one go first. +LL | | thread::yield_now(); +... | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr index ecdbb49e8b86..d4d03b96a3e5 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr @@ -13,7 +13,17 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/mixed_size_read_write.rs:LL:CC + | +LL | / s.spawn(|| { +LL | | if cfg!(write_read) { +LL | | // Let the other one go first. +LL | | thread::yield_now(); +... | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr index be1bb4e507f6..98565708f881 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr @@ -19,7 +19,14 @@ LL | | ); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/mixed_size_read_write_read.rs:LL:CC + | +LL | / ... s.spawn(|| { +LL | | ... let _val = data.load(Ordering::Relaxed); +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr index 0b1eac5d5d03..9033bc2c922d 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr @@ -13,7 +13,16 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/mixed_size_write_write.rs:LL:CC + | +LL | / s.spawn(|| { +LL | | let idx = if cfg!(fst) { 0 } else { 1 }; +LL | | a8[idx].store(1, Ordering::SeqCst); +LL | | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr index da62f537903a..b0e771c40b91 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr @@ -13,7 +13,16 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/mixed_size_write_write.rs:LL:CC + | +LL | / s.spawn(|| { +LL | | let idx = if cfg!(fst) { 0 } else { 1 }; +LL | | a8[idx].store(1, Ordering::SeqCst); +LL | | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/read_write_race.stderr b/src/tools/miri/tests/fail/data_race/read_write_race.stderr index 9163bff917e4..1922ce949f6b 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/read_write_race.stderr @@ -11,7 +11,16 @@ LL | let _val = *c.0; | ^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/read_write_race.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... *c.0 = 64; +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr index 719a7162690a..a6bdac409d9d 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr @@ -11,7 +11,17 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/read_write_race_stack.rs:LL:CC + | +LL | ... let j1 = spawn(move || { + | ________________^ +LL | | ... let ptr = ptr; // avoid field capturing +... | +LL | | ... stack_var +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr b/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr index ea441ab36722..6c77bf6b3d8b 100644 --- a/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr +++ b/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr @@ -11,7 +11,18 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/relax_acquire_race.rs:LL:CC + | +LL | ... let j3 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... if SYNC.load(Ordering::Acquire) == 2 { +LL | | ... *c.0 +... | +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race.stderr b/src/tools/miri/tests/fail/data_race/release_seq_race.stderr index 8cb1fd7ce613..528db7ed2479 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race.stderr +++ b/src/tools/miri/tests/fail/data_race/release_seq_race.stderr @@ -11,7 +11,18 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/release_seq_race.rs:LL:CC + | +LL | let j3 = spawn(move || { + | __________________^ +LL | | let c = c; // avoid field capturing +LL | | sleep(Duration::from_millis(500)); +LL | | if SYNC.load(Ordering::Acquire) == 3 { +... | +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr index d9a4b71ca21f..1b2daf8b256b 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr +++ b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr @@ -11,7 +11,18 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/release_seq_race_same_thread.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... if SYNC.load(Ordering::Acquire) == 2 { +LL | | ... *c.0 +... | +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/rmw_race.stderr b/src/tools/miri/tests/fail/data_race/rmw_race.stderr index c1eeef1dca76..21f710e16b0d 100644 --- a/src/tools/miri/tests/fail/data_race/rmw_race.stderr +++ b/src/tools/miri/tests/fail/data_race/rmw_race.stderr @@ -11,7 +11,18 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/rmw_race.rs:LL:CC + | +LL | ... let j3 = spawn(move || { + | ________________^ +LL | | ... let c = c; // capture `c`, not just its field. +LL | | ... if SYNC.load(Ordering::Acquire) == 3 { +LL | | ... *c.0 +... | +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/write_write_race.stderr b/src/tools/miri/tests/fail/data_race/write_write_race.stderr index 13f798e4da56..112cdb278196 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/write_write_race.stderr @@ -11,7 +11,16 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/write_write_race.rs:LL:CC + | +LL | ... let j2 = spawn(move || { + | ________________^ +LL | | ... let c = c; // avoid field capturing +LL | | ... *c.0 = 64; +LL | | ... }); + | |________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr index eb8c2747b40e..c70dbb4e619f 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr @@ -11,7 +11,17 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/data_race/write_write_race_stack.rs:LL:CC + | +LL | let j1 = spawn(move || { + | __________________^ +LL | | let ptr = ptr; // avoid field capturing +... | +LL | | stack_var +LL | | }); + | |__________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/ctor_ub.rs b/src/tools/miri/tests/fail/shims/ctor_ub.rs new file mode 100644 index 000000000000..860f602e69d0 --- /dev/null +++ b/src/tools/miri/tests/fail/shims/ctor_ub.rs @@ -0,0 +1,39 @@ +unsafe extern "C" fn ctor() { + std::hint::unreachable_unchecked() + //~^ERROR: unreachable +} + +#[rustfmt::skip] +macro_rules! ctor { + ($ident:ident = $ctor:ident) => { + #[cfg_attr( + all(any( + target_os = "linux", + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "none", + target_family = "wasm", + )), + link_section = ".init_array" + )] + #[cfg_attr(windows, link_section = ".CRT$XCU")] + #[cfg_attr( + any(target_os = "macos", target_os = "ios"), + // We do not set the `mod_init_funcs` flag here since ctor/inventory also do not do + // that. See . + link_section = "__DATA,__mod_init_func" + )] + #[used] + static $ident: unsafe extern "C" fn() = $ctor; + }; +} + +ctor! { CTOR = ctor } + +fn main() {} diff --git a/src/tools/miri/tests/fail/shims/ctor_ub.stderr b/src/tools/miri/tests/fail/shims/ctor_ub.stderr new file mode 100644 index 000000000000..ab8a8f633638 --- /dev/null +++ b/src/tools/miri/tests/fail/shims/ctor_ub.stderr @@ -0,0 +1,23 @@ +error: Undefined Behavior: entering unreachable code + --> tests/fail/shims/ctor_ub.rs:LL:CC + | +LL | std::hint::unreachable_unchecked() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 + = note: this is inside `ctor` +note: which got called indirectly due to this code + --> tests/fail/shims/ctor_ub.rs:LL:CC + | +LL | static $ident: unsafe extern "C" fn() = $ctor; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | ctor! { CTOR = ctor } + | --------------------- in this macro invocation + = note: this error originates in the macro `ctor` (in Nightly builds, run with -Z macro-backtrace for more info) + +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/stacked_borrows/retag_data_race_protected_read.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr index c8662628c033..f50b05712ee2 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr @@ -14,7 +14,18 @@ LL | unsafe { ptr.0.read() }; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/stacked_borrows/retag_data_race_protected_read.rs:LL:CC + | +LL | let t = thread::spawn(move || { + | _____________^ +LL | | let ptr = ptr; +LL | | // We do a protected mutable retag (but no write!) in this thread. +LL | | fn retag(_x: &mut i32) {} +LL | | retag(unsafe { &mut *ptr.0 }); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr index 3a95e13f5bc0..67b1cdab911a 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr @@ -24,6 +24,11 @@ note: which got called inside closure | LL | let t2 = std::thread::spawn(move || thread_2(p)); | ^^^^^^^^^^^ +note: which got called indirectly due to this code + --> tests/fail/stacked_borrows/retag_data_race_read.rs:LL:CC + | +LL | let t2 = std::thread::spawn(move || thread_2(p)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr index c5a0b58c2185..3567340f2202 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr @@ -32,7 +32,19 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *x = 64; | ^^^^^^^ = help: this transition corresponds to a loss of read and write permissions - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/tree_borrows/reservedim_spurious_write.rs:LL:CC + | +LL | let thread_2 = thread::spawn(move || { + | ____________________^ +LL | | let b = (2, by); +LL | | synchronized!(b, "start"); +LL | | let ptr = ptr; +... | +LL | | synchronized!(b, "end"); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr index 75c11f09ce52..a28730abd953 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr @@ -32,7 +32,19 @@ help: the accessed tag later transitioned to Disabled due to a protector r LL | } | ^ = help: this transition corresponds to a loss of read and write permissions - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/tree_borrows/reservedim_spurious_write.rs:LL:CC + | +LL | let thread_2 = thread::spawn(move || { + | ____________________^ +LL | | let b = (2, by); +LL | | synchronized!(b, "start"); +LL | | let ptr = ptr; +... | +LL | | synchronized!(b, "end"); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr b/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr index eef8766fd652..9e20ec238ed8 100644 --- a/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr @@ -41,6 +41,18 @@ note: which got called inside closure | LL | let _y = as_mut(unsafe { &mut *ptr.0 }, b.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: which got called indirectly due to this code + --> tests/fail/tree_borrows/spurious_read.rs:LL:CC + | +LL | let thread_y = thread::spawn(move || { + | ____________________^ +LL | | let b = (2, by); +LL | | synchronized!(b, "start"); +LL | | let ptr = ptr; +... | +LL | | synchronized!(b, "end"); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr index 605767db22b1..9f3792e0e409 100644 --- a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr +++ b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr @@ -6,7 +6,12 @@ LL | let j2 = spawn(move || x.load(Ordering::Relaxed)); | = 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 - = note: this is on thread `unnamed-ID` + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/fail/weak_memory/weak_uninit.rs:LL:CC + | +LL | let j2 = spawn(move || x.load(Ordering::Relaxed)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr index 333405a9172b..85e2810f1f30 100644 --- a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr +++ b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr @@ -33,6 +33,16 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/atomics/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr index 6ec5843c3a0c..4bca53961f5f 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr @@ -14,6 +14,16 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr index fb29e326ba83..0a03363285b6 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr @@ -14,6 +14,16 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr index e4af214bfb99..29a2e371bb3c 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr @@ -28,6 +28,16 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr index f5986d50bafc..3f5d0bdf346e 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr @@ -14,6 +14,16 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr b/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr index b061b9029b3d..48b8a16c8b10 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr @@ -14,6 +14,16 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr index ad5047be60c1..2eb3791aaf08 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr @@ -14,6 +14,16 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr index ad5047be60c1..2eb3791aaf08 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr @@ -14,6 +14,16 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr index ad5047be60c1..2eb3791aaf08 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr @@ -14,6 +14,16 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/shims/exit.stderr b/src/tools/miri/tests/genmc/fail/shims/exit.stderr index f27860b82fe7..573c8b14fae3 100644 --- a/src/tools/miri/tests/genmc/fail/shims/exit.stderr +++ b/src/tools/miri/tests/genmc/fail/shims/exit.stderr @@ -7,6 +7,14 @@ LL | unsafe { std::hint::unreachable_unchecked() }; | = 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 + = note: this is on thread `unnamed-ID`, inside closure +note: which got called indirectly due to this code + --> tests/genmc/fail/shims/exit.rs:LL:CC + | +LL | / std::thread::spawn(|| { +LL | | unsafe { std::hint::unreachable_unchecked() }; +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr index 5adfb066e6f1..e32548c4b5d5 100644 --- a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr +++ b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr @@ -16,6 +16,15 @@ note: which got called inside closure | LL | drop(guard); | ^^^^^^^^^^^ +note: which got called indirectly due to this code + --> tests/genmc/fail/shims/mutex_diff_thread_unlock.rs:LL:CC + | +LL | let handle = std::thread::spawn(move || { + | __________________^ +LL | | let guard = guard; // avoid field capturing +LL | | drop(guard); +LL | | }); + | |______^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr b/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr index 71a01d8f754b..6d597aaa6342 100644 --- a/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr +++ b/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr @@ -17,5 +17,15 @@ note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{clos | LL | f(); | ^^^ +note: which got called indirectly due to this code + --> tests/genmc/pass/atomics/../../../utils/genmc.rs:LL:CC + | +LL | / libc::pthread_create( +LL | | &raw mut thread_id, +LL | | attr, +LL | | thread_func::, +LL | | Box::into_raw(f) as *mut c_void, +LL | | ) + | |_________^ Verification complete with 2 executions. No errors found. From b12b766cf33791020f453198f1545592c424c3c3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 7 Dec 2025 10:43:07 +0100 Subject: [PATCH 1399/3801] fix previously dead android tests and remove some dangling files --- src/tools/miri/ci/ci.sh | 2 +- .../libc/prctl-get-name-buffer-too-small.rs | 2 +- .../prctl-get-name-buffer-too-small.stderr | 10 +++---- .../libc/socketpair_read_blocking.stderr | 13 ---------- .../libc/socketpair_write_blocking.stderr | 13 ---------- .../data_race/mixed_size_write_write.stderr | 22 ---------------- .../retag_data_race_read.stack.stderr | 25 ------------------ .../retag_data_race_read.tree.stderr | 26 ------------------- 8 files changed, 6 insertions(+), 107 deletions(-) delete mode 100644 src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr delete mode 100644 src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr delete mode 100644 src/tools/miri/tests/fail/data_race/mixed_size_write_write.stderr delete mode 100644 src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stack.stderr delete mode 100644 src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.tree.stderr diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 2d27f0274999..2dd8fc77459a 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -152,7 +152,7 @@ case $HOST_TARGET in # Partially supported targets (tier 2) BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there - TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd + TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd prctl TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std ;; diff --git a/src/tools/miri/tests/fail-dep/libc/prctl-get-name-buffer-too-small.rs b/src/tools/miri/tests/fail-dep/libc/prctl-get-name-buffer-too-small.rs index 4b731866aca1..d923667d8741 100644 --- a/src/tools/miri/tests/fail-dep/libc/prctl-get-name-buffer-too-small.rs +++ b/src/tools/miri/tests/fail-dep/libc/prctl-get-name-buffer-too-small.rs @@ -5,6 +5,6 @@ fn main() { let mut buf = vec![0u8; 15]; unsafe { - libc::prctl(libc::PR_GET_NAME, buf.as_mut_ptr().cast::()); //~ ERROR: memory access failed: expected a pointer to 16 bytes of memory, but got alloc952 which is only 15 bytes from the end of the allocation + libc::prctl(libc::PR_GET_NAME, buf.as_mut_ptr().cast::()); //~ ERROR: memory access failed } } diff --git a/src/tools/miri/tests/fail-dep/libc/prctl-get-name-buffer-too-small.stderr b/src/tools/miri/tests/fail-dep/libc/prctl-get-name-buffer-too-small.stderr index 275a38e593c8..cc50564a43f5 100644 --- a/src/tools/miri/tests/fail-dep/libc/prctl-get-name-buffer-too-small.stderr +++ b/src/tools/miri/tests/fail-dep/libc/prctl-get-name-buffer-too-small.stderr @@ -1,18 +1,16 @@ -error: Undefined Behavior: memory access failed: expected a pointer to 16 bytes of memory, but got ALLOC which is only 15 bytes from the end of the allocation - --> tests/fail-dep/libc/prctl-threadname.rs:LL:CC +error: Undefined Behavior: memory access failed: attempting to access 16 bytes, but got ALLOC which is only 15 bytes from the end of the allocation + --> tests/fail-dep/libc/prctl-get-name-buffer-too-small.rs:LL:CC | LL | libc::prctl(libc::PR_GET_NAME, buf.as_mut_ptr().cast::()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 16 bytes of memory, but got ALLOC which is only 15 bytes from the end of the allocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 help: ALLOC was allocated here: - --> tests/fail-dep/libc/prctl-threadname.rs:LL:CC + --> tests/fail-dep/libc/prctl-get-name-buffer-too-small.rs:LL:CC | LL | let mut buf = vec![0u8; 15]; | ^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail-dep/libc/prctl-threadname.rs:LL:CC = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr deleted file mode 100644 index caf23da1150f..000000000000 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_read_blocking.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: deadlock: the evaluated program deadlocked - --> tests/fail-dep/libc/socketpair_read_blocking.rs:LL:CC - | -LL | let _res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - | ^ the evaluated program deadlocked - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/socketpair_read_blocking.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-dep/libc/socketpair_write_blocking.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr deleted file mode 100644 index 2dc420d5f1ef..000000000000 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_write_blocking.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: deadlock: the evaluated program deadlocked - --> tests/fail-dep/libc/socketpair_write_blocking.rs:LL:CC - | -LL | let _ = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; - | ^ the evaluated program deadlocked - | - = note: BACKTRACE: - = note: inside `main` at tests/fail-dep/libc/socketpair_write_blocking.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/data_race/mixed_size_write_write.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.stderr deleted file mode 100644 index 1f22413bc5f9..000000000000 --- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error: Undefined Behavior: Race condition detected between (1) 2-byte atomic store on thread `unnamed-ID` and (2) 1-byte atomic store on thread `unnamed-ID` at ALLOC. (2) just happened here - --> tests/fail/data_race/mixed_size_write_write.rs:LL:CC - | -LL | a8[0].store(1, Ordering::SeqCst); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Race condition detected between (1) 2-byte atomic store on thread `unnamed-ID` and (2) 1-byte atomic store on thread `unnamed-ID` at ALLOC. (2) just happened here - | -help: and (1) occurred earlier here - --> tests/fail/data_race/mixed_size_write_write.rs:LL:CC - | -LL | a16.store(1, Ordering::SeqCst); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: overlapping unsynchronized atomic accesses must use the same access size - = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model - = 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 - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/mixed_size_write_write.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/stacked_borrows/retag_data_race_read.stack.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stack.stderr deleted file mode 100644 index 1d7ea18982d1..000000000000 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stack.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error: Undefined Behavior: Data race detected between (1) Read on thread `unnamed-ID` and (2) Write on thread `unnamed-ID` at ALLOC. (2) just happened here - --> $DIR/retag_data_race_read.rs:LL:CC - | -LL | *p = 5; - | ^^^^^^ Data race detected between (1) Read on thread `unnamed-ID` and (2) Write on thread `unnamed-ID` at ALLOC. (2) just happened here - | -help: and (1) occurred earlier here - --> $DIR/retag_data_race_read.rs:LL:CC - | -LL | let _r = &*p; - | ^^^ - = 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 - = note: BACKTRACE (of the first span): - = note: inside `thread_2` at $DIR/retag_data_race_read.rs:LL:CC -note: inside closure - --> $DIR/retag_data_race_read.rs:LL:CC - | -LL | let t2 = std::thread::spawn(move || thread_2(p)); - | ^^^^^^^^^^^ - -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/stacked_borrows/retag_data_race_read.tree.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.tree.stderr deleted file mode 100644 index e6c1745d321c..000000000000 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.tree.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: Undefined Behavior: reborrow through (root of the allocation) is forbidden - --> RUSTLIB/std/src/rt.rs:LL:CC - | -LL | panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }).map_err(rt_abort)?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reborrow through (root of the allocation) is forbidden - | - = 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: the accessed tag (root of the allocation) is foreign to the protected tag (i.e., it is not a child) - = help: this reborrow (acting as a foreign read access) would cause the protected tag (currently Active) to become Disabled - = help: protected tags must never be Disabled -help: the accessed tag was created here - --> RUSTLIB/std/src/rt.rs:LL:CC - | -LL | panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }).map_err(rt_abort)?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: the protected tag was created here, in the initial state Active - --> RUSTLIB/std/src/panic.rs:LL:CC - | -LL | fn catch_unwind R + UnwindSafe, R>(f: F) -> Result { - | ^ - = note: BACKTRACE (of the first span): - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC - -error: aborting due to 1 previous error - From 065791ee0603a45fefd686fb13b1e55dbf831ab3 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 5 Nov 2025 13:01:12 -0800 Subject: [PATCH 1400/3801] Add allocator parameter to HashMap --- library/std/src/collections/hash/map.rs | 289 ++++++++++++++++++------ 1 file changed, 216 insertions(+), 73 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 251d62bd2033..ad6328f76ed6 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -4,6 +4,7 @@ mod tests; use hashbrown::hash_map as base; use self::Entry::*; +use crate::alloc::{Allocator, Global}; use crate::borrow::Borrow; use crate::collections::{TryReserveError, TryReserveErrorKind}; use crate::error::Error; @@ -243,8 +244,13 @@ use crate::ops::Index; #[cfg_attr(not(test), rustc_diagnostic_item = "HashMap")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] -pub struct HashMap { - base: base::HashMap, +pub struct HashMap< + K, + V, + S = RandomState, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::HashMap, } impl HashMap { @@ -286,6 +292,46 @@ impl HashMap { } } +impl HashMap { + /// Creates an empty `HashMap` using the given allocator. + /// + /// The hash map is initially created with a capacity of 0, so it will not allocate until it + /// is first inserted into. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// let mut map: HashMap<&str, i32> = HashMap::new(); + /// ``` + #[inline] + #[must_use] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn new_in(alloc: A) -> Self { + HashMap::with_hasher_in(Default::default(), alloc) + } + + /// Creates an empty `HashMap` with at least the specified capacity using + /// the given allocator. + /// + /// The hash map will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is zero, the hash map will not allocate. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10); + /// ``` + #[inline] + #[must_use] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { + HashMap::with_capacity_and_hasher_in(capacity, Default::default(), alloc) + } +} + impl HashMap { /// Creates an empty `HashMap` which will use the given hash builder to hash /// keys. @@ -347,6 +393,47 @@ impl HashMap { pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashMap { HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hasher) } } +} + +impl HashMap { + /// Creates an empty `HashMap` which will use the given hash builder and + /// allocator. + /// + /// The created map has the default initial capacity. + /// + /// Warning: `hash_builder` is normally randomly generated, and + /// is designed to allow HashMaps to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// the `HashMap` to be useful, see its documentation for details. + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_hasher_in(hash_builder: S, alloc: A) -> Self { + HashMap { base: base::HashMap::with_hasher_in(hash_builder, alloc) } + } + + /// Creates an empty `HashMap` with at least the specified capacity, using + /// `hasher` to hash the keys and `alloc` to allocate memory. + /// + /// The hash map will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is zero, the hash map will not allocate. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow HashMaps to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hasher` passed should implement the [`BuildHasher`] trait for + /// the `HashMap` to be useful, see its documentation for details. + /// + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_capacity_and_hasher_in(capacity: usize, hash_builder: S, alloc: A) -> Self { + HashMap { base: base::HashMap::with_capacity_and_hasher_in(capacity, hash_builder, alloc) } + } /// Returns the number of elements the map can hold without reallocating. /// @@ -424,7 +511,7 @@ impl HashMap { #[inline] #[rustc_lint_query_instability] #[stable(feature = "map_into_keys_values", since = "1.54.0")] - pub fn into_keys(self) -> IntoKeys { + pub fn into_keys(self) -> IntoKeys { IntoKeys { inner: self.into_iter() } } @@ -519,7 +606,7 @@ impl HashMap { #[inline] #[rustc_lint_query_instability] #[stable(feature = "map_into_keys_values", since = "1.54.0")] - pub fn into_values(self) -> IntoValues { + pub fn into_values(self) -> IntoValues { IntoValues { inner: self.into_iter() } } @@ -648,7 +735,7 @@ impl HashMap { #[inline] #[rustc_lint_query_instability] #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self) -> Drain<'_, K, V> { + pub fn drain(&mut self) -> Drain<'_, K, V, A> { Drain { base: self.base.drain() } } @@ -688,7 +775,7 @@ impl HashMap { #[inline] #[rustc_lint_query_instability] #[stable(feature = "hash_extract_if", since = "1.88.0")] - pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, K, V, F> + pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, K, V, F, A> where F: FnMut(&K, &mut V) -> bool, { @@ -762,10 +849,11 @@ impl HashMap { } } -impl HashMap +impl HashMap where K: Eq + Hash, S: BuildHasher, + A: Allocator, { /// Reserves capacity for at least `additional` more elements to be inserted /// in the `HashMap`. The collection may reserve more space to speculatively @@ -884,7 +972,7 @@ where /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn entry(&mut self, key: K) -> Entry<'_, K, V> { + pub fn entry(&mut self, key: K) -> Entry<'_, K, V, A> { map_entry(self.base.rustc_entry(key)) } @@ -1232,7 +1320,7 @@ where /// assert_eq!(err.value, "b"); /// ``` #[unstable(feature = "map_try_insert", issue = "82766")] - pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V>> { + pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V, A>> { match self.entry(key) { Occupied(entry) => Err(OccupiedError { entry, value }), Vacant(entry) => Ok(entry.insert(value)), @@ -1298,11 +1386,12 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for HashMap +impl Clone for HashMap where K: Clone, V: Clone, S: Clone, + A: Allocator + Clone, { #[inline] fn clone(&self) -> Self { @@ -1316,13 +1405,14 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for HashMap +impl PartialEq for HashMap where K: Eq + Hash, V: PartialEq, S: BuildHasher, + A: Allocator, { - fn eq(&self, other: &HashMap) -> bool { + fn eq(&self, other: &HashMap) -> bool { if self.len() != other.len() { return false; } @@ -1332,19 +1422,21 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for HashMap +impl Eq for HashMap where K: Eq + Hash, V: Eq, S: BuildHasher, + A: Allocator, { } #[stable(feature = "rust1", since = "1.0.0")] -impl Debug for HashMap +impl Debug for HashMap where K: Debug, V: Debug, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map().entries(self.iter()).finish() @@ -1364,11 +1456,12 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Index<&Q> for HashMap +impl Index<&Q> for HashMap where K: Eq + Hash + Borrow, Q: Eq + Hash, S: BuildHasher, + A: Allocator, { type Output = V; @@ -1523,11 +1616,15 @@ impl Default for IterMut<'_, K, V> { /// let iter = map.into_iter(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub struct IntoIter { - base: base::IntoIter, +pub struct IntoIter< + K, + V, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::IntoIter, } -impl IntoIter { +impl IntoIter { /// Returns an iterator of references over the remaining items. #[inline] pub(super) fn iter(&self) -> Iter<'_, K, V> { @@ -1656,11 +1753,16 @@ impl fmt::Debug for Values<'_, K, V> { /// ``` #[stable(feature = "drain", since = "1.6.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_drain_ty")] -pub struct Drain<'a, K: 'a, V: 'a> { - base: base::Drain<'a, K, V>, +pub struct Drain< + 'a, + K: 'a, + V: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::Drain<'a, K, V, A>, } -impl<'a, K, V> Drain<'a, K, V> { +impl<'a, K, V, A: Allocator> Drain<'a, K, V, A> { /// Returns an iterator of references over the remaining items. #[inline] pub(super) fn iter(&self) -> Iter<'_, K, V> { @@ -1687,8 +1789,14 @@ impl<'a, K, V> Drain<'a, K, V> { #[stable(feature = "hash_extract_if", since = "1.88.0")] #[must_use = "iterators are lazy and do nothing unless consumed; \ use `retain` to remove and discard elements"] -pub struct ExtractIf<'a, K, V, F> { - base: base::ExtractIf<'a, K, V, F>, +pub struct ExtractIf< + 'a, + K, + V, + F, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::ExtractIf<'a, K, V, F, A>, } /// A mutable iterator over the values of a `HashMap`. @@ -1740,8 +1848,12 @@ impl Default for ValuesMut<'_, K, V> { /// let iter_keys = map.into_keys(); /// ``` #[stable(feature = "map_into_keys_values", since = "1.54.0")] -pub struct IntoKeys { - inner: IntoIter, +pub struct IntoKeys< + K, + V, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + inner: IntoIter, } #[stable(feature = "default_iters_hash", since = "1.83.0")] @@ -1770,8 +1882,12 @@ impl Default for IntoKeys { /// let iter_keys = map.into_values(); /// ``` #[stable(feature = "map_into_keys_values", since = "1.54.0")] -pub struct IntoValues { - inner: IntoIter, +pub struct IntoValues< + K, + V, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + inner: IntoIter, } #[stable(feature = "default_iters_hash", since = "1.83.0")] @@ -1789,14 +1905,19 @@ impl Default for IntoValues { /// [`entry`]: HashMap::entry #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "HashMapEntry")] -pub enum Entry<'a, K: 'a, V: 'a> { +pub enum Entry< + 'a, + K: 'a, + V: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { /// An occupied entry. #[stable(feature = "rust1", since = "1.0.0")] - Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>), + Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V, A>), /// A vacant entry. #[stable(feature = "rust1", since = "1.0.0")] - Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>), + Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V, A>), } #[stable(feature = "debug_hash_map", since = "1.12.0")] @@ -1812,12 +1933,17 @@ impl Debug for Entry<'_, K, V> { /// A view into an occupied entry in a `HashMap`. /// It is part of the [`Entry`] enum. #[stable(feature = "rust1", since = "1.0.0")] -pub struct OccupiedEntry<'a, K: 'a, V: 'a> { - base: base::RustcOccupiedEntry<'a, K, V>, +pub struct OccupiedEntry< + 'a, + K: 'a, + V: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::RustcOccupiedEntry<'a, K, V, A>, } #[stable(feature = "debug_hash_map", since = "1.12.0")] -impl Debug for OccupiedEntry<'_, K, V> { +impl Debug for OccupiedEntry<'_, K, V, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OccupiedEntry") .field("key", self.key()) @@ -1829,12 +1955,17 @@ impl Debug for OccupiedEntry<'_, K, V> { /// A view into a vacant entry in a `HashMap`. /// It is part of the [`Entry`] enum. #[stable(feature = "rust1", since = "1.0.0")] -pub struct VacantEntry<'a, K: 'a, V: 'a> { - base: base::RustcVacantEntry<'a, K, V>, +pub struct VacantEntry< + 'a, + K: 'a, + V: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::RustcVacantEntry<'a, K, V, A>, } #[stable(feature = "debug_hash_map", since = "1.12.0")] -impl Debug for VacantEntry<'_, K, V> { +impl Debug for VacantEntry<'_, K, V, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("VacantEntry").field(self.key()).finish() } @@ -1844,15 +1975,20 @@ impl Debug for VacantEntry<'_, K, V> { /// /// Contains the occupied entry, and the value that was not inserted. #[unstable(feature = "map_try_insert", issue = "82766")] -pub struct OccupiedError<'a, K: 'a, V: 'a> { +pub struct OccupiedError< + 'a, + K: 'a, + V: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { /// The entry in the map that was already occupied. - pub entry: OccupiedEntry<'a, K, V>, + pub entry: OccupiedEntry<'a, K, V, A>, /// The value which was not inserted, because the entry was already occupied. pub value: V, } #[unstable(feature = "map_try_insert", issue = "82766")] -impl Debug for OccupiedError<'_, K, V> { +impl Debug for OccupiedError<'_, K, V, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OccupiedError") .field("key", self.entry.key()) @@ -1863,7 +1999,7 @@ impl Debug for OccupiedError<'_, K, V> { } #[unstable(feature = "map_try_insert", issue = "82766")] -impl<'a, K: Debug, V: Debug> fmt::Display for OccupiedError<'a, K, V> { +impl<'a, K: Debug, V: Debug, A: Allocator> fmt::Display for OccupiedError<'a, K, V, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, @@ -1876,10 +2012,10 @@ impl<'a, K: Debug, V: Debug> fmt::Display for OccupiedError<'a, K, V> { } #[unstable(feature = "map_try_insert", issue = "82766")] -impl<'a, K: Debug, V: Debug> Error for OccupiedError<'a, K, V> {} +impl<'a, K: Debug, V: Debug, A: Allocator> Error for OccupiedError<'a, K, V, A> {} #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K, V, S> IntoIterator for &'a HashMap { +impl<'a, K, V, S, A: Allocator> IntoIterator for &'a HashMap { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; @@ -1891,7 +2027,7 @@ impl<'a, K, V, S> IntoIterator for &'a HashMap { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K, V, S> IntoIterator for &'a mut HashMap { +impl<'a, K, V, S, A: Allocator> IntoIterator for &'a mut HashMap { type Item = (&'a K, &'a mut V); type IntoIter = IterMut<'a, K, V>; @@ -1903,9 +2039,9 @@ impl<'a, K, V, S> IntoIterator for &'a mut HashMap { } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for HashMap { +impl IntoIterator for HashMap { type Item = (K, V); - type IntoIter = IntoIter; + type IntoIter = IntoIter; /// Creates a consuming iterator, that is, one that moves each key-value /// pair out of the map in arbitrary order. The map cannot be used after @@ -1927,7 +2063,7 @@ impl IntoIterator for HashMap { /// ``` #[inline] #[rustc_lint_query_instability] - fn into_iter(self) -> IntoIter { + fn into_iter(self) -> IntoIter { IntoIter { base: self.base.into_iter() } } } @@ -2015,7 +2151,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = (K, V); #[inline] @@ -2040,17 +2176,17 @@ impl Iterator for IntoIter { } } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter { +impl ExactSizeIterator for IntoIter { #[inline] fn len(&self) -> usize { self.base.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for IntoIter {} +impl FusedIterator for IntoIter {} #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for IntoIter { +impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.iter()).finish() } @@ -2169,7 +2305,7 @@ impl fmt::Debug for ValuesMut<'_, K, V> { } #[stable(feature = "map_into_keys_values", since = "1.54.0")] -impl Iterator for IntoKeys { +impl Iterator for IntoKeys { type Item = K; #[inline] @@ -2194,24 +2330,24 @@ impl Iterator for IntoKeys { } } #[stable(feature = "map_into_keys_values", since = "1.54.0")] -impl ExactSizeIterator for IntoKeys { +impl ExactSizeIterator for IntoKeys { #[inline] fn len(&self) -> usize { self.inner.len() } } #[stable(feature = "map_into_keys_values", since = "1.54.0")] -impl FusedIterator for IntoKeys {} +impl FusedIterator for IntoKeys {} #[stable(feature = "map_into_keys_values", since = "1.54.0")] -impl fmt::Debug for IntoKeys { +impl fmt::Debug for IntoKeys { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.inner.iter().map(|(k, _)| k)).finish() } } #[stable(feature = "map_into_keys_values", since = "1.54.0")] -impl Iterator for IntoValues { +impl Iterator for IntoValues { type Item = V; #[inline] @@ -2236,24 +2372,24 @@ impl Iterator for IntoValues { } } #[stable(feature = "map_into_keys_values", since = "1.54.0")] -impl ExactSizeIterator for IntoValues { +impl ExactSizeIterator for IntoValues { #[inline] fn len(&self) -> usize { self.inner.len() } } #[stable(feature = "map_into_keys_values", since = "1.54.0")] -impl FusedIterator for IntoValues {} +impl FusedIterator for IntoValues {} #[stable(feature = "map_into_keys_values", since = "1.54.0")] -impl fmt::Debug for IntoValues { +impl fmt::Debug for IntoValues { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.inner.iter().map(|(_, v)| v)).finish() } } #[stable(feature = "drain", since = "1.6.0")] -impl<'a, K, V> Iterator for Drain<'a, K, V> { +impl<'a, K, V, A: Allocator> Iterator for Drain<'a, K, V, A> { type Item = (K, V); #[inline] @@ -2274,17 +2410,17 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> { } } #[stable(feature = "drain", since = "1.6.0")] -impl ExactSizeIterator for Drain<'_, K, V> { +impl ExactSizeIterator for Drain<'_, K, V, A> { #[inline] fn len(&self) -> usize { self.base.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Drain<'_, K, V> {} +impl FusedIterator for Drain<'_, K, V, A> {} #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Drain<'_, K, V> +impl fmt::Debug for Drain<'_, K, V, A> where K: fmt::Debug, V: fmt::Debug, @@ -2295,7 +2431,7 @@ where } #[stable(feature = "hash_extract_if", since = "1.88.0")] -impl Iterator for ExtractIf<'_, K, V, F> +impl Iterator for ExtractIf<'_, K, V, F, A> where F: FnMut(&K, &mut V) -> bool, { @@ -2312,10 +2448,13 @@ where } #[stable(feature = "hash_extract_if", since = "1.88.0")] -impl FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {} +impl FusedIterator for ExtractIf<'_, K, V, F, A> where + F: FnMut(&K, &mut V) -> bool +{ +} #[stable(feature = "hash_extract_if", since = "1.88.0")] -impl fmt::Debug for ExtractIf<'_, K, V, F> +impl fmt::Debug for ExtractIf<'_, K, V, F, A> where K: fmt::Debug, V: fmt::Debug, @@ -2325,7 +2464,7 @@ where } } -impl<'a, K, V> Entry<'a, K, V> { +impl<'a, K, V, A: Allocator> Entry<'a, K, V, A> { /// Ensures a value is in the entry by inserting the default if empty, and returns /// a mutable reference to the value in the entry. /// @@ -2473,7 +2612,7 @@ impl<'a, K, V> Entry<'a, K, V> { /// ``` #[inline] #[stable(feature = "entry_insert", since = "1.83.0")] - pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> { + pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, A> { match self { Occupied(mut entry) => { entry.insert(value); @@ -2510,7 +2649,7 @@ impl<'a, K, V: Default> Entry<'a, K, V> { } } -impl<'a, K, V> OccupiedEntry<'a, K, V> { +impl<'a, K, V, A: Allocator> OccupiedEntry<'a, K, V, A> { /// Gets a reference to the key in the entry. /// /// # Examples @@ -2682,7 +2821,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { } } -impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { +impl<'a, K: 'a, V: 'a, A: Allocator> VacantEntry<'a, K, V, A> { /// Gets a reference to the key that would be used when inserting a value /// through the `VacantEntry`. /// @@ -2760,7 +2899,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { /// ``` #[inline] #[stable(feature = "entry_insert", since = "1.83.0")] - pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> { + pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, A> { let base = self.base.insert_entry(value); OccupiedEntry { base } } @@ -2786,10 +2925,11 @@ where /// Inserts all new key-values from the iterator and replaces values with existing /// keys with new values returned from the iterator. #[stable(feature = "rust1", since = "1.0.0")] -impl Extend<(K, V)> for HashMap +impl Extend<(K, V)> for HashMap where K: Eq + Hash, S: BuildHasher, + A: Allocator, { #[inline] fn extend>(&mut self, iter: T) { @@ -2808,11 +2948,12 @@ where } #[stable(feature = "hash_extend_copy", since = "1.4.0")] -impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap +impl<'a, K, V, S, A> Extend<(&'a K, &'a V)> for HashMap where K: Eq + Hash + Copy, V: Copy, S: BuildHasher, + A: Allocator, { #[inline] fn extend>(&mut self, iter: T) { @@ -2831,7 +2972,9 @@ where } #[inline] -fn map_entry<'a, K: 'a, V: 'a>(raw: base::RustcEntry<'a, K, V>) -> Entry<'a, K, V> { +fn map_entry<'a, K: 'a, V: 'a, A: Allocator>( + raw: base::RustcEntry<'a, K, V, A>, +) -> Entry<'a, K, V, A> { match raw { base::RustcEntry::Occupied(base) => Entry::Occupied(OccupiedEntry { base }), base::RustcEntry::Vacant(base) => Entry::Vacant(VacantEntry { base }), From 0f516ec9294746eb781feb3c2787f0c9591e1c50 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 5 Nov 2025 15:05:58 -0800 Subject: [PATCH 1401/3801] Update UI tests for addition of HashMap allocator --- tests/ui/generics/wrong-number-of-args.rs | 4 --- tests/ui/generics/wrong-number-of-args.stderr | 24 ++++++------------ tests/ui/inference/issue-71732.stderr | 2 +- ...clone-when-some-obligation-is-unmet.stderr | 2 +- tests/ui/privacy/suggest-box-new.rs | 2 +- tests/ui/privacy/suggest-box-new.stderr | 21 +++++++++------- .../suggestions/multi-suggestion.ascii.stderr | 21 +++++++++------- tests/ui/suggestions/multi-suggestion.rs | 2 +- .../multi-suggestion.unicode.stderr | 25 +++++++++++-------- tests/ui/traits/issue-77982.stderr | 2 +- 10 files changed, 51 insertions(+), 54 deletions(-) diff --git a/tests/ui/generics/wrong-number-of-args.rs b/tests/ui/generics/wrong-number-of-args.rs index 6524bd538b6b..8bc384a3d817 100644 --- a/tests/ui/generics/wrong-number-of-args.rs +++ b/tests/ui/generics/wrong-number-of-args.rs @@ -321,10 +321,6 @@ mod stdlib { //~| ERROR struct takes at least 2 //~| HELP add missing - type D = HashMap; - //~^ ERROR struct takes at most 3 - //~| HELP remove the - type E = HashMap<>; //~^ ERROR struct takes at least 2 generic arguments but 0 generic arguments //~| HELP add missing diff --git a/tests/ui/generics/wrong-number-of-args.stderr b/tests/ui/generics/wrong-number-of-args.stderr index bac0d26b622d..bedeeb812fc9 100644 --- a/tests/ui/generics/wrong-number-of-args.stderr +++ b/tests/ui/generics/wrong-number-of-args.stderr @@ -926,16 +926,8 @@ help: add missing generic arguments LL | type C = HashMap<'static, K, V>; | ++++++ -error[E0107]: struct takes at most 3 generic arguments but 4 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:324:18 - | -LL | type D = HashMap; - | ^^^^^^^ ----- help: remove the unnecessary generic argument - | | - | expected at most 3 generic arguments - error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:328:18 + --> $DIR/wrong-number-of-args.rs:324:18 | LL | type E = HashMap<>; | ^^^^^^^ expected at least 2 generic arguments @@ -946,7 +938,7 @@ LL | type E = HashMap; | ++++ error[E0107]: missing generics for enum `Result` - --> $DIR/wrong-number-of-args.rs:334:18 + --> $DIR/wrong-number-of-args.rs:330:18 | LL | type A = Result; | ^^^^^^ expected 2 generic arguments @@ -957,7 +949,7 @@ LL | type A = Result; | ++++++ error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied - --> $DIR/wrong-number-of-args.rs:338:18 + --> $DIR/wrong-number-of-args.rs:334:18 | LL | type B = Result; | ^^^^^^ ------ supplied 1 generic argument @@ -970,7 +962,7 @@ LL | type B = Result; | +++ error[E0107]: enum takes 0 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/wrong-number-of-args.rs:342:18 + --> $DIR/wrong-number-of-args.rs:338:18 | LL | type C = Result<'static>; | ^^^^^^--------- help: remove the unnecessary generics @@ -978,7 +970,7 @@ LL | type C = Result<'static>; | expected 0 lifetime arguments error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:342:18 + --> $DIR/wrong-number-of-args.rs:338:18 | LL | type C = Result<'static>; | ^^^^^^ expected 2 generic arguments @@ -989,7 +981,7 @@ LL | type C = Result<'static, T, E>; | ++++++ error[E0107]: enum takes 2 generic arguments but 3 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:348:18 + --> $DIR/wrong-number-of-args.rs:344:18 | LL | type D = Result; | ^^^^^^ ------ help: remove the unnecessary generic argument @@ -997,7 +989,7 @@ LL | type D = Result; | expected 2 generic arguments error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:352:18 + --> $DIR/wrong-number-of-args.rs:348:18 | LL | type E = Result<>; | ^^^^^^ expected 2 generic arguments @@ -1007,7 +999,7 @@ help: add missing generic arguments LL | type E = Result; | ++++ -error: aborting due to 71 previous errors +error: aborting due to 70 previous errors Some errors have detailed explanations: E0106, E0107. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/inference/issue-71732.stderr b/tests/ui/inference/issue-71732.stderr index af8b310fd1d9..e79131694856 100644 --- a/tests/ui/inference/issue-71732.stderr +++ b/tests/ui/inference/issue-71732.stderr @@ -10,7 +10,7 @@ LL | .get(&"key".into()) - impl Borrow for String; - impl Borrow for T where T: ?Sized; -note: required by a bound in `HashMap::::get` +note: required by a bound in `HashMap::::get` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL help: consider specifying the generic argument | diff --git a/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr b/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr index 6272455cc57e..af0f67b7c1c0 100644 --- a/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr +++ b/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr @@ -6,7 +6,7 @@ LL | let mut copy: Vec = map.clone().into_values().collect(); | | | move occurs because value has type `HashMap`, which does not implement the `Copy` trait | -note: `HashMap::::into_values` takes ownership of the receiver `self`, which moves value +note: `HashMap::::into_values` takes ownership of the receiver `self`, which moves value --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL note: if `Hash128_1` implemented `Clone`, you could clone the value --> $DIR/suggest-clone-when-some-obligation-is-unmet.rs:8:1 diff --git a/tests/ui/privacy/suggest-box-new.rs b/tests/ui/privacy/suggest-box-new.rs index ff585387020e..87ee13d15edb 100644 --- a/tests/ui/privacy/suggest-box-new.rs +++ b/tests/ui/privacy/suggest-box-new.rs @@ -14,7 +14,7 @@ fn main() { let _ = std::collections::HashMap(); //~^ ERROR expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` let _ = std::collections::HashMap {}; - //~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + //~^ ERROR cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields let _ = Box {}; //~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields // test that we properly instantiate the parameter of `Box::::new` with an inference variable diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index e3a7e5f62017..7367672351d6 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -5,6 +5,7 @@ LL | let _ = std::collections::HashMap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + ::: $SRC_DIR/std/src/collections/hash/map.rs:LL:COL | = note: `std::collections::HashMap` defined here help: you might have meant to use an associated function to build this type @@ -12,14 +13,15 @@ help: you might have meant to use an associated function to build this type LL | let _ = std::collections::HashMap::new(); | +++++ LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::new_in(_); + | +LL - let _ = std::collections::HashMap(); LL + let _ = std::collections::HashMap::with_capacity(_); | LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_hasher(_); - | -LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); | + = and 4 other candidates help: consider using the `Default` trait | LL | let _ = ::default(); @@ -73,7 +75,7 @@ LL - })), LL + wtf: Some(::default()), | -error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields +error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields --> $DIR/suggest-box-new.rs:16:13 | LL | let _ = std::collections::HashMap {}; @@ -86,14 +88,15 @@ LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::new(); | LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new_in(_); + | +LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::with_capacity(_); | LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_hasher(_); - | -LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); | + = and 4 other candidates help: consider using the `Default` trait | LL - let _ = std::collections::HashMap {}; diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr index c2ae19b1ae9a..2da0f9bd12c2 100644 --- a/tests/ui/suggestions/multi-suggestion.ascii.stderr +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -5,6 +5,7 @@ LL | let _ = std::collections::HashMap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + ::: $SRC_DIR/std/src/collections/hash/map.rs:LL:COL | = note: `std::collections::HashMap` defined here help: you might have meant to use an associated function to build this type @@ -12,14 +13,15 @@ help: you might have meant to use an associated function to build this type LL | let _ = std::collections::HashMap::new(); | +++++ LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::new_in(_); + | +LL - let _ = std::collections::HashMap(); LL + let _ = std::collections::HashMap::with_capacity(_); | LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_hasher(_); - | -LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); | + = and 4 other candidates help: consider using the `Default` trait | LL | let _ = ::default(); @@ -73,7 +75,7 @@ LL - })), LL + wtf: Some(::default()), | -error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields +error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields --> $DIR/multi-suggestion.rs:19:13 | LL | let _ = std::collections::HashMap {}; @@ -86,14 +88,15 @@ LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::new(); | LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new_in(_); + | +LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::with_capacity(_); | LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_hasher(_); - | -LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); | + = and 4 other candidates help: consider using the `Default` trait | LL - let _ = std::collections::HashMap {}; diff --git a/tests/ui/suggestions/multi-suggestion.rs b/tests/ui/suggestions/multi-suggestion.rs index 99d2407aa212..6d822a8e5aff 100644 --- a/tests/ui/suggestions/multi-suggestion.rs +++ b/tests/ui/suggestions/multi-suggestion.rs @@ -17,6 +17,6 @@ fn main() { let _ = std::collections::HashMap(); //[ascii]~^ ERROR expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` let _ = std::collections::HashMap {}; - //[ascii]~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + //[ascii]~^ ERROR cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields let _ = Box {}; //[ascii]~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields } diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr index fc187cac91d1..69529b67b775 100644 --- a/tests/ui/suggestions/multi-suggestion.unicode.stderr +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -5,6 +5,7 @@ LL │ let _ = std::collections::HashMap(); │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━ ╰╴ ╭▸ $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + ⸬ $SRC_DIR/std/src/collections/hash/map.rs:LL:COL │ ╰ note: `std::collections::HashMap` defined here help: you might have meant to use an associated function to build this type @@ -12,14 +13,15 @@ help: you might have meant to use an associated function to build this type LL │ let _ = std::collections::HashMap::new(); ├╴ +++++ LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::new_in(_); + ├╴ +LL - let _ = std::collections::HashMap(); LL + let _ = std::collections::HashMap::with_capacity(_); ├╴ LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_hasher(_); - ├╴ -LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); - ╰╴ +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); + │ + ╰ and 4 other candidates help: consider using the `Default` trait ╭╴ LL │ let _ = ::default(); @@ -73,7 +75,7 @@ LL - })), LL + wtf: Some(::default()), ╰╴ -error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields +error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields ╭▸ $DIR/multi-suggestion.rs:19:13 │ LL │ let _ = std::collections::HashMap {}; @@ -86,14 +88,15 @@ LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::new(); ├╴ LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new_in(_); + ├╴ +LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::with_capacity(_); ├╴ LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_hasher(_); - ├╴ -LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); - ╰╴ +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); + │ + ╰ and 4 other candidates help: consider using the `Default` trait ╭╴ LL - let _ = std::collections::HashMap {}; diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index edc7f56ea467..4bc24e81215a 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -10,7 +10,7 @@ LL | opts.get(opt.as_ref()); - impl Borrow for String; - impl Borrow for T where T: ?Sized; -note: required by a bound in `HashMap::::get` +note: required by a bound in `HashMap::::get` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL help: consider specifying the generic argument | From ef7616dbaa9378ac8028f76f9ce74a9c4237565e Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 5 Nov 2025 14:44:14 -0800 Subject: [PATCH 1402/3801] Add allocator parameter to HashSet --- library/std/src/collections/hash/set.rs | 429 ++++++++++++++++-------- 1 file changed, 286 insertions(+), 143 deletions(-) diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 6795da80aacb..02a4a0d9c815 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -4,6 +4,7 @@ mod tests; use hashbrown::hash_set as base; use super::map::map_try_reserve_error; +use crate::alloc::{Allocator, Global}; use crate::borrow::Borrow; use crate::collections::TryReserveError; use crate::fmt; @@ -122,8 +123,12 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub}; /// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")] #[stable(feature = "rust1", since = "1.0.0")] -pub struct HashSet { - base: base::HashSet, +pub struct HashSet< + T, + S = RandomState, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::HashSet, } impl HashSet { @@ -166,7 +171,141 @@ impl HashSet { } } +impl HashSet { + /// Creates an empty `HashSet` in the provided allocator. + /// + /// The hash set is initially created with a capacity of 0, so it will not allocate until it + /// is first inserted into. + #[inline] + #[must_use] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn new_in(alloc: A) -> HashSet { + HashSet::with_hasher_in(Default::default(), alloc) + } + + /// Creates an empty `HashSet` with at least the specified capacity. + /// + /// The hash set will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is zero, the hash set will not allocate. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// let set: HashSet = HashSet::with_capacity(10); + /// assert!(set.capacity() >= 10); + /// ``` + #[inline] + #[must_use] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_capacity_in(capacity: usize, alloc: A) -> HashSet { + HashSet::with_capacity_and_hasher_in(capacity, Default::default(), alloc) + } +} + impl HashSet { + /// Creates a new empty hash set which will use the given hasher to hash + /// keys. + /// + /// The hash set is also created with the default initial capacity. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// the `HashSet` to be useful, see its documentation for details. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// use std::hash::RandomState; + /// + /// let s = RandomState::new(); + /// let mut set = HashSet::with_hasher(s); + /// set.insert(2); + /// ``` + #[inline] + #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] + #[rustc_const_stable(feature = "const_collections_with_hasher", since = "1.85.0")] + pub const fn with_hasher(hasher: S) -> HashSet { + HashSet { base: base::HashSet::with_hasher(hasher) } + } + + /// Creates an empty `HashSet` with at least the specified capacity, using + /// `hasher` to hash the keys. + /// + /// The hash set will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is zero, the hash set will not allocate. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// the `HashSet` to be useful, see its documentation for details. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// use std::hash::RandomState; + /// + /// let s = RandomState::new(); + /// let mut set = HashSet::with_capacity_and_hasher(10, s); + /// set.insert(1); + /// ``` + #[inline] + #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] + pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet { + HashSet { base: base::HashSet::with_capacity_and_hasher(capacity, hasher) } + } +} + +impl HashSet { + /// Creates a new empty hash set which will use the given hasher to hash + /// keys and will allocate memory using the provided allocator. + /// + /// The hash set is also created with the default initial capacity. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// the `HashSet` to be useful, see its documentation for details. + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_hasher_in(hasher: S, alloc: A) -> HashSet { + HashSet { base: base::HashSet::with_hasher_in(hasher, alloc) } + } + + /// Creates an empty `HashSet` with at least the specified capacity, using + /// `hasher` to hash the keys and `alloc` to allocate memory. + /// + /// The hash set will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is zero, the hash set will not allocate. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// the `HashSet` to be useful, see its documentation for details. + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> HashSet { + HashSet { base: base::HashSet::with_capacity_and_hasher_in(capacity, hasher, alloc) } + } + /// Returns the number of elements the set can hold without reallocating. /// /// # Examples @@ -272,7 +411,7 @@ impl HashSet { #[inline] #[rustc_lint_query_instability] #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self) -> Drain<'_, T> { + pub fn drain(&mut self) -> Drain<'_, T, A> { Drain { base: self.base.drain() } } @@ -309,7 +448,7 @@ impl HashSet { #[inline] #[rustc_lint_query_instability] #[stable(feature = "hash_extract_if", since = "1.88.0")] - pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, T, F> + pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, T, F, A> where F: FnMut(&T) -> bool, { @@ -362,67 +501,6 @@ impl HashSet { self.base.clear() } - /// Creates a new empty hash set which will use the given hasher to hash - /// keys. - /// - /// The hash set is also created with the default initial capacity. - /// - /// Warning: `hasher` is normally randomly generated, and - /// is designed to allow `HashSet`s to be resistant to attacks that - /// cause many collisions and very poor performance. Setting it - /// manually using this function can expose a DoS attack vector. - /// - /// The `hash_builder` passed should implement the [`BuildHasher`] trait for - /// the `HashSet` to be useful, see its documentation for details. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashSet; - /// use std::hash::RandomState; - /// - /// let s = RandomState::new(); - /// let mut set = HashSet::with_hasher(s); - /// set.insert(2); - /// ``` - #[inline] - #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_stable(feature = "const_collections_with_hasher", since = "1.85.0")] - pub const fn with_hasher(hasher: S) -> HashSet { - HashSet { base: base::HashSet::with_hasher(hasher) } - } - - /// Creates an empty `HashSet` with at least the specified capacity, using - /// `hasher` to hash the keys. - /// - /// The hash set will be able to hold at least `capacity` elements without - /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is zero, the hash set will not allocate. - /// - /// Warning: `hasher` is normally randomly generated, and - /// is designed to allow `HashSet`s to be resistant to attacks that - /// cause many collisions and very poor performance. Setting it - /// manually using this function can expose a DoS attack vector. - /// - /// The `hash_builder` passed should implement the [`BuildHasher`] trait for - /// the `HashSet` to be useful, see its documentation for details. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashSet; - /// use std::hash::RandomState; - /// - /// let s = RandomState::new(); - /// let mut set = HashSet::with_capacity_and_hasher(10, s); - /// set.insert(1); - /// ``` - #[inline] - #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet { - HashSet { base: base::HashSet::with_capacity_and_hasher(capacity, hasher) } - } - /// Returns a reference to the set's [`BuildHasher`]. /// /// # Examples @@ -442,10 +520,11 @@ impl HashSet { } } -impl HashSet +impl HashSet where T: Eq + Hash, S: BuildHasher, + A: Allocator, { /// Reserves capacity for at least `additional` more elements to be inserted /// in the `HashSet`. The collection may reserve more space to speculatively @@ -569,7 +648,7 @@ where #[inline] #[rustc_lint_query_instability] #[stable(feature = "rust1", since = "1.0.0")] - pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S> { + pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S, A> { Difference { iter: self.iter(), other } } @@ -599,8 +678,8 @@ where #[stable(feature = "rust1", since = "1.0.0")] pub fn symmetric_difference<'a>( &'a self, - other: &'a HashSet, - ) -> SymmetricDifference<'a, T, S> { + other: &'a HashSet, + ) -> SymmetricDifference<'a, T, S, A> { SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } } @@ -631,7 +710,7 @@ where #[inline] #[rustc_lint_query_instability] #[stable(feature = "rust1", since = "1.0.0")] - pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S> { + pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S, A> { if self.len() <= other.len() { Intersection { iter: self.iter(), other } } else { @@ -660,7 +739,7 @@ where #[inline] #[rustc_lint_query_instability] #[stable(feature = "rust1", since = "1.0.0")] - pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S> { + pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S, A> { if self.len() >= other.len() { Union { iter: self.iter().chain(other.difference(self)) } } else { @@ -812,7 +891,7 @@ where /// ``` #[inline] #[unstable(feature = "hash_set_entry", issue = "60896")] - pub fn entry(&mut self, value: T) -> Entry<'_, T, S> { + pub fn entry(&mut self, value: T) -> Entry<'_, T, S, A> { map_entry(self.base.entry(value)) } @@ -834,7 +913,7 @@ where /// assert_eq!(a.is_disjoint(&b), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_disjoint(&self, other: &HashSet) -> bool { + pub fn is_disjoint(&self, other: &HashSet) -> bool { if self.len() <= other.len() { self.iter().all(|v| !other.contains(v)) } else { @@ -860,7 +939,7 @@ where /// assert_eq!(set.is_subset(&sup), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_subset(&self, other: &HashSet) -> bool { + pub fn is_subset(&self, other: &HashSet) -> bool { if self.len() <= other.len() { self.iter().all(|v| other.contains(v)) } else { false } } @@ -886,7 +965,7 @@ where /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_superset(&self, other: &HashSet) -> bool { + pub fn is_superset(&self, other: &HashSet) -> bool { other.is_subset(self) } @@ -995,7 +1074,7 @@ where } #[inline] -fn map_entry<'a, K: 'a, V: 'a>(raw: base::Entry<'a, K, V>) -> Entry<'a, K, V> { +fn map_entry<'a, K: 'a, V: 'a, A: Allocator>(raw: base::Entry<'a, K, V, A>) -> Entry<'a, K, V, A> { match raw { base::Entry::Occupied(base) => Entry::Occupied(OccupiedEntry { base }), base::Entry::Vacant(base) => Entry::Vacant(VacantEntry { base }), @@ -1003,10 +1082,11 @@ fn map_entry<'a, K: 'a, V: 'a>(raw: base::Entry<'a, K, V>) -> Entry<'a, K, V> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for HashSet +impl Clone for HashSet where T: Clone, S: Clone, + A: Allocator + Clone, { #[inline] fn clone(&self) -> Self { @@ -1024,12 +1104,13 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for HashSet +impl PartialEq for HashSet where T: Eq + Hash, S: BuildHasher, + A: Allocator, { - fn eq(&self, other: &HashSet) -> bool { + fn eq(&self, other: &HashSet) -> bool { if self.len() != other.len() { return false; } @@ -1039,17 +1120,19 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for HashSet +impl Eq for HashSet where T: Eq + Hash, S: BuildHasher, + A: Allocator, { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for HashSet +impl fmt::Debug for HashSet where T: fmt::Debug, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_set().entries(self.iter()).finish() @@ -1107,10 +1190,11 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for HashSet +impl Extend for HashSet where T: Eq + Hash, S: BuildHasher, + A: Allocator, { #[inline] fn extend>(&mut self, iter: I) { @@ -1129,10 +1213,11 @@ where } #[stable(feature = "hash_extend_copy", since = "1.4.0")] -impl<'a, T, S> Extend<&'a T> for HashSet +impl<'a, T, S, A> Extend<&'a T> for HashSet where T: 'a + Eq + Hash + Copy, S: BuildHasher, + A: Allocator, { #[inline] fn extend>(&mut self, iter: I) { @@ -1341,8 +1426,11 @@ impl Default for Iter<'_, K> { /// let mut iter = a.into_iter(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub struct IntoIter { - base: base::IntoIter, +pub struct IntoIter< + K, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::IntoIter, } #[stable(feature = "default_iters_hash", since = "1.83.0")] @@ -1371,8 +1459,12 @@ impl Default for IntoIter { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "hashset_drain_ty")] -pub struct Drain<'a, K: 'a> { - base: base::Drain<'a, K>, +pub struct Drain< + 'a, + K: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::Drain<'a, K, A>, } /// A draining, filtering iterator over the items of a `HashSet`. @@ -1393,8 +1485,13 @@ pub struct Drain<'a, K: 'a> { #[stable(feature = "hash_extract_if", since = "1.88.0")] #[must_use = "iterators are lazy and do nothing unless consumed; \ use `retain` to remove and discard elements"] -pub struct ExtractIf<'a, K, F> { - base: base::ExtractIf<'a, K, F>, +pub struct ExtractIf< + 'a, + K, + F, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::ExtractIf<'a, K, F, A>, } /// A lazy iterator producing elements in the intersection of `HashSet`s. @@ -1417,11 +1514,16 @@ pub struct ExtractIf<'a, K, F> { #[must_use = "this returns the intersection as an iterator, \ without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Intersection<'a, T: 'a, S: 'a> { +pub struct Intersection< + 'a, + T: 'a, + S: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { // iterator of the first set iter: Iter<'a, T>, // the second set - other: &'a HashSet, + other: &'a HashSet, } /// A lazy iterator producing elements in the difference of `HashSet`s. @@ -1444,11 +1546,16 @@ pub struct Intersection<'a, T: 'a, S: 'a> { #[must_use = "this returns the difference as an iterator, \ without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Difference<'a, T: 'a, S: 'a> { +pub struct Difference< + 'a, + T: 'a, + S: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { // iterator of the first set iter: Iter<'a, T>, // the second set - other: &'a HashSet, + other: &'a HashSet, } /// A lazy iterator producing elements in the symmetric difference of `HashSet`s. @@ -1471,8 +1578,13 @@ pub struct Difference<'a, T: 'a, S: 'a> { #[must_use = "this returns the difference as an iterator, \ without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct SymmetricDifference<'a, T: 'a, S: 'a> { - iter: Chain, Difference<'a, T, S>>, +pub struct SymmetricDifference< + 'a, + T: 'a, + S: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + iter: Chain, Difference<'a, T, S, A>>, } /// A lazy iterator producing elements in the union of `HashSet`s. @@ -1495,12 +1607,17 @@ pub struct SymmetricDifference<'a, T: 'a, S: 'a> { #[must_use = "this returns the union as an iterator, \ without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Union<'a, T: 'a, S: 'a> { - iter: Chain, Difference<'a, T, S>>, +pub struct Union< + 'a, + T: 'a, + S: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + iter: Chain, Difference<'a, T, S, A>>, } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> IntoIterator for &'a HashSet { +impl<'a, T, S, A: Allocator> IntoIterator for &'a HashSet { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -1512,9 +1629,9 @@ impl<'a, T, S> IntoIterator for &'a HashSet { } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for HashSet { +impl IntoIterator for HashSet { type Item = T; - type IntoIter = IntoIter; + type IntoIter = IntoIter; /// Creates a consuming iterator, that is, one that moves each value out /// of the set in arbitrary order. The set cannot be used after calling @@ -1538,7 +1655,7 @@ impl IntoIterator for HashSet { /// ``` #[inline] #[rustc_lint_query_instability] - fn into_iter(self) -> IntoIter { + fn into_iter(self) -> IntoIter { IntoIter { base: self.base.into_iter() } } } @@ -1593,7 +1710,7 @@ impl fmt::Debug for Iter<'_, K> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = K; #[inline] @@ -1618,24 +1735,24 @@ impl Iterator for IntoIter { } } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter { +impl ExactSizeIterator for IntoIter { #[inline] fn len(&self) -> usize { self.base.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for IntoIter {} +impl FusedIterator for IntoIter {} #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for IntoIter { +impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.base, f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K> Iterator for Drain<'a, K> { +impl<'a, K, A: Allocator> Iterator for Drain<'a, K, A> { type Item = K; #[inline] @@ -1656,24 +1773,24 @@ impl<'a, K> Iterator for Drain<'a, K> { } } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Drain<'_, K> { +impl ExactSizeIterator for Drain<'_, K, A> { #[inline] fn len(&self) -> usize { self.base.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Drain<'_, K> {} +impl FusedIterator for Drain<'_, K, A> {} #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Drain<'_, K> { +impl fmt::Debug for Drain<'_, K, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.base, f) } } #[stable(feature = "hash_extract_if", since = "1.88.0")] -impl Iterator for ExtractIf<'_, K, F> +impl Iterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool, { @@ -1690,10 +1807,10 @@ where } #[stable(feature = "hash_extract_if", since = "1.88.0")] -impl FusedIterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool {} +impl FusedIterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool {} #[stable(feature = "hash_extract_if", since = "1.88.0")] -impl fmt::Debug for ExtractIf<'_, K, F> +impl fmt::Debug for ExtractIf<'_, K, F, A> where K: fmt::Debug, { @@ -1703,7 +1820,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Intersection<'_, T, S> { +impl Clone for Intersection<'_, T, S, A> { #[inline] fn clone(&self) -> Self { Intersection { iter: self.iter.clone(), ..*self } @@ -1711,10 +1828,11 @@ impl Clone for Intersection<'_, T, S> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> Iterator for Intersection<'a, T, S> +impl<'a, T, S, A> Iterator for Intersection<'a, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { type Item = &'a T; @@ -1745,10 +1863,11 @@ where } #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Intersection<'_, T, S> +impl fmt::Debug for Intersection<'_, T, S, A> where T: fmt::Debug + Eq + Hash, S: BuildHasher, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1756,15 +1875,16 @@ where } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Intersection<'_, T, S> +impl FusedIterator for Intersection<'_, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Difference<'_, T, S> { +impl Clone for Difference<'_, T, S, A> { #[inline] fn clone(&self) -> Self { Difference { iter: self.iter.clone(), ..*self } @@ -1772,10 +1892,11 @@ impl Clone for Difference<'_, T, S> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> Iterator for Difference<'a, T, S> +impl<'a, T, S, A> Iterator for Difference<'a, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { type Item = &'a T; @@ -1806,18 +1927,20 @@ where } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Difference<'_, T, S> +impl FusedIterator for Difference<'_, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { } #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Difference<'_, T, S> +impl fmt::Debug for Difference<'_, T, S, A> where T: fmt::Debug + Eq + Hash, S: BuildHasher, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1825,7 +1948,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for SymmetricDifference<'_, T, S> { +impl Clone for SymmetricDifference<'_, T, S, A> { #[inline] fn clone(&self) -> Self { SymmetricDifference { iter: self.iter.clone() } @@ -1833,10 +1956,11 @@ impl Clone for SymmetricDifference<'_, T, S> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S> +impl<'a, T, S, A> Iterator for SymmetricDifference<'a, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { type Item = &'a T; @@ -1859,18 +1983,20 @@ where } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for SymmetricDifference<'_, T, S> +impl FusedIterator for SymmetricDifference<'_, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { } #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for SymmetricDifference<'_, T, S> +impl fmt::Debug for SymmetricDifference<'_, T, S, A> where T: fmt::Debug + Eq + Hash, S: BuildHasher, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1878,7 +2004,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Union<'_, T, S> { +impl Clone for Union<'_, T, S, A> { #[inline] fn clone(&self) -> Self { Union { iter: self.iter.clone() } @@ -1886,7 +2012,7 @@ impl Clone for Union<'_, T, S> { } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Union<'_, T, S> +impl FusedIterator for Union<'_, T, S, A> where T: Eq + Hash, S: BuildHasher, @@ -1894,10 +2020,11 @@ where } #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Union<'_, T, S> +impl fmt::Debug for Union<'_, T, S, A> where T: fmt::Debug + Eq + Hash, S: BuildHasher, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1905,10 +2032,11 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> Iterator for Union<'a, T, S> +impl<'a, T, S, A> Iterator for Union<'a, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { type Item = &'a T; @@ -1973,7 +2101,12 @@ where /// assert_eq!(vec, ["a", "b", "c", "d", "e"]); /// ``` #[unstable(feature = "hash_set_entry", issue = "60896")] -pub enum Entry<'a, T, S> { +pub enum Entry< + 'a, + T, + S, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { /// An occupied entry. /// /// # Examples @@ -1990,7 +2123,7 @@ pub enum Entry<'a, T, S> { /// Entry::Occupied(_) => { } /// } /// ``` - Occupied(OccupiedEntry<'a, T, S>), + Occupied(OccupiedEntry<'a, T, S, A>), /// A vacant entry. /// @@ -2008,11 +2141,11 @@ pub enum Entry<'a, T, S> { /// Entry::Vacant(_) => { } /// } /// ``` - Vacant(VacantEntry<'a, T, S>), + Vacant(VacantEntry<'a, T, S, A>), } #[unstable(feature = "hash_set_entry", issue = "60896")] -impl fmt::Debug for Entry<'_, T, S> { +impl fmt::Debug for Entry<'_, T, S, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), @@ -2060,12 +2193,17 @@ impl fmt::Debug for Entry<'_, T, S> { /// assert_eq!(set.len(), 2); /// ``` #[unstable(feature = "hash_set_entry", issue = "60896")] -pub struct OccupiedEntry<'a, T, S> { - base: base::OccupiedEntry<'a, T, S>, +pub struct OccupiedEntry< + 'a, + T, + S, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::OccupiedEntry<'a, T, S, A>, } #[unstable(feature = "hash_set_entry", issue = "60896")] -impl fmt::Debug for OccupiedEntry<'_, T, S> { +impl fmt::Debug for OccupiedEntry<'_, T, S, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OccupiedEntry").field("value", self.get()).finish() } @@ -2100,18 +2238,23 @@ impl fmt::Debug for OccupiedEntry<'_, T, S> { /// assert!(set.contains("b") && set.len() == 2); /// ``` #[unstable(feature = "hash_set_entry", issue = "60896")] -pub struct VacantEntry<'a, T, S> { - base: base::VacantEntry<'a, T, S>, +pub struct VacantEntry< + 'a, + T, + S, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::VacantEntry<'a, T, S, A>, } #[unstable(feature = "hash_set_entry", issue = "60896")] -impl fmt::Debug for VacantEntry<'_, T, S> { +impl fmt::Debug for VacantEntry<'_, T, S, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("VacantEntry").field(self.get()).finish() } } -impl<'a, T, S> Entry<'a, T, S> { +impl<'a, T, S, A: Allocator> Entry<'a, T, S, A> { /// Sets the value of the entry, and returns an OccupiedEntry. /// /// # Examples @@ -2128,7 +2271,7 @@ impl<'a, T, S> Entry<'a, T, S> { /// ``` #[inline] #[unstable(feature = "hash_set_entry", issue = "60896")] - pub fn insert(self) -> OccupiedEntry<'a, T, S> + pub fn insert(self) -> OccupiedEntry<'a, T, S, A> where T: Hash, S: BuildHasher, @@ -2198,7 +2341,7 @@ impl<'a, T, S> Entry<'a, T, S> { } } -impl OccupiedEntry<'_, T, S> { +impl OccupiedEntry<'_, T, S, A> { /// Gets a reference to the value in the entry. /// /// # Examples @@ -2255,7 +2398,7 @@ impl OccupiedEntry<'_, T, S> { } } -impl<'a, T, S> VacantEntry<'a, T, S> { +impl<'a, T, S, A: Allocator> VacantEntry<'a, T, S, A> { /// Gets a reference to the value that would be used when inserting /// through the `VacantEntry`. /// @@ -2325,7 +2468,7 @@ impl<'a, T, S> VacantEntry<'a, T, S> { } #[inline] - fn insert_entry(self) -> OccupiedEntry<'a, T, S> + fn insert_entry(self) -> OccupiedEntry<'a, T, S, A> where T: Hash, S: BuildHasher, From 72c6b0714142f45b7c8989b2bc54de22c4a38c6d Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 30 Dec 2025 10:57:15 +0800 Subject: [PATCH 1403/3801] Migrate `move_arm_cond_to_match_guard` assist to use `SyntaxEditor` --- .../ide-assists/src/handlers/move_guard.rs | 74 ++++++++++--------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs index 8daf86923d92..1c0c6e43d53b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs @@ -1,6 +1,11 @@ +use itertools::Itertools; use syntax::{ SyntaxKind::WHITESPACE, - ast::{AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit, make}, + ast::{ + AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit, make, + syntax_factory::SyntaxFactory, + }, + syntax_editor::Element, }; use crate::{AssistContext, AssistId, Assists}; @@ -131,8 +136,10 @@ pub(crate) fn move_arm_cond_to_match_guard( AssistId::refactor_rewrite("move_arm_cond_to_match_guard"), "Move condition to match guard", replace_node.text_range(), - |edit| { - edit.delete(match_arm.syntax().text_range()); + |builder| { + let make = SyntaxFactory::without_mappings(); + let mut replace_arms = vec![]; + // Dedent if if_expr is in a BlockExpr let dedent = if needs_dedent { cov_mark::hit!(move_guard_ifelse_in_block); @@ -141,47 +148,30 @@ pub(crate) fn move_arm_cond_to_match_guard( cov_mark::hit!(move_guard_ifelse_else_block); 0 }; - let then_arm_end = match_arm.syntax().text_range().end(); let indent_level = match_arm.indent_level(); - let spaces = indent_level; - let mut first = true; for (cond, block) in conds_blocks { - if !first { - edit.insert(then_arm_end, format!("\n{spaces}")); - } else { - first = false; - } - let guard = format!("{match_pat} if {cond} => "); - edit.insert(then_arm_end, guard); let only_expr = block.statements().next().is_none(); - match &block.tail_expr() { - Some(then_expr) if only_expr => { - edit.insert(then_arm_end, then_expr.syntax().text()); - edit.insert(then_arm_end, ","); - } - _ => { - let to_insert = block.dedent(dedent.into()).syntax().text(); - edit.insert(then_arm_end, to_insert) - } - } + let expr = match block.tail_expr() { + Some(then_expr) if only_expr => then_expr, + _ => block.dedent(dedent.into()).into(), + }; + let guard = make.match_guard(cond); + let new_arm = make.match_arm(match_pat.clone(), Some(guard), expr); + replace_arms.push(new_arm); } - if let Some(e) = tail { + if let Some(block) = tail { cov_mark::hit!(move_guard_ifelse_else_tail); - let guard = format!("\n{spaces}{match_pat} => "); - edit.insert(then_arm_end, guard); - let only_expr = e.statements().next().is_none(); - match &e.tail_expr() { + let only_expr = block.statements().next().is_none(); + let expr = match block.tail_expr() { Some(expr) if only_expr => { cov_mark::hit!(move_guard_ifelse_expr_only); - edit.insert(then_arm_end, expr.syntax().text()); - edit.insert(then_arm_end, ","); + expr } - _ => { - let to_insert = e.dedent(dedent.into()).syntax().text(); - edit.insert(then_arm_end, to_insert) - } - } + _ => block.dedent(dedent.into()).into(), + }; + let new_arm = make.match_arm(match_pat, None, expr); + replace_arms.push(new_arm); } else { // There's no else branch. Add a pattern without guard, unless the following match // arm is `_ => ...` @@ -193,9 +183,21 @@ pub(crate) fn move_arm_cond_to_match_guard( { cov_mark::hit!(move_guard_ifelse_has_wildcard); } - _ => edit.insert(then_arm_end, format!("\n{spaces}{match_pat} => {{}}")), + _ => { + let block_expr = make.expr_empty_block().into(); + replace_arms.push(make.match_arm(match_pat, None, block_expr)); + } } } + + let mut edit = builder.make_editor(match_arm.syntax()); + + let newline = make.whitespace(&format!("\n{indent_level}")); + let replace_arms = replace_arms.iter().map(|it| it.syntax().syntax_element()); + let replace_arms = Itertools::intersperse(replace_arms, newline.syntax_element()); + edit.replace_with_many(match_arm.syntax(), replace_arms.collect()); + + builder.add_file_edits(ctx.vfs_file_id(), edit); }, ) } From b3c26f10c845eb06b0c73a67c9738a02e2857106 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 29 Dec 2025 17:23:03 +1100 Subject: [PATCH 1404/3801] Extract shared helper function `is_const_pat_that_looks_like_binding` --- .../src/thir/pattern/check_match.rs | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index c4479c402ab2..bf480cf601ee 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -5,7 +5,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, struct_span_code_err}; use rustc_hir::def::*; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, BindingMode, ByRef, HirId, MatchSource}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::Level; @@ -687,12 +687,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { unpeeled_pat = subpattern; } - if let PatKind::ExpandedConstant { def_id, .. } = unpeeled_pat.kind - && let DefKind::Const = self.tcx.def_kind(def_id) - && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span) - // We filter out paths with multiple path::segments. - && snippet.chars().all(|c| c.is_alphanumeric() || c == '_') - { + if let Some(def_id) = is_const_pat_that_looks_like_binding(self.tcx, unpeeled_pat) { let span = self.tcx.def_span(def_id); let variable = self.tcx.item_name(def_id).to_string(); // When we encounter a constant as the binding name, point at the `const` definition. @@ -1209,6 +1204,26 @@ fn pat_is_catchall(pat: &DeconstructedPat<'_, '_>) -> bool { } } +/// If the given pattern is a named constant that looks like it could have been +/// intended to be a binding, returns the `DefId` of the named constant. +/// +/// Diagnostics use this to give more detailed suggestions for non-exhaustive +/// matches. +fn is_const_pat_that_looks_like_binding<'tcx>(tcx: TyCtxt<'tcx>, pat: &Pat<'tcx>) -> Option { + // The pattern must be a named constant, and the name that appears in + // the pattern's source text must resemble a plain identifier without any + // `::` namespace separators or other non-identifier characters. + if let PatKind::ExpandedConstant { def_id, .. } = pat.kind + && matches!(tcx.def_kind(def_id), DefKind::Const) + && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(pat.span) + && snippet.chars().all(|c| c.is_alphanumeric() || c == '_') + { + Some(def_id) + } else { + None + } +} + /// Report that a match is not exhaustive. fn report_non_exhaustive_match<'p, 'tcx>( cx: &PatCtxt<'p, 'tcx>, @@ -1303,12 +1318,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( for &arm in arms { let arm = &thir.arms[arm]; - if let PatKind::ExpandedConstant { def_id, .. } = arm.pattern.kind - && !matches!(cx.tcx.def_kind(def_id), DefKind::InlineConst) - && let Ok(snippet) = cx.tcx.sess.source_map().span_to_snippet(arm.pattern.span) - // We filter out paths with multiple path::segments. - && snippet.chars().all(|c| c.is_alphanumeric() || c == '_') - { + if let Some(def_id) = is_const_pat_that_looks_like_binding(cx.tcx, &arm.pattern) { let const_name = cx.tcx.item_name(def_id); err.span_label( arm.pattern.span, From 89f7d70045ef6b3ede7cb5e7f7f59bdda7f16521 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 29 Dec 2025 13:30:18 +1100 Subject: [PATCH 1405/3801] Remove several remnants of `#![feature(inline_const_pat)]` --- compiler/rustc_middle/src/thir.rs | 16 ++++++------- .../rustc_mir_build/src/check_unsafety.rs | 8 ------- .../src/thir/pattern/const_to_pat.rs | 2 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 24 +++++++++---------- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 31745cae3c06..65bfc7d362b6 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -832,18 +832,18 @@ pub enum PatKind<'tcx> { value: ty::Value<'tcx>, }, - /// Pattern obtained by converting a constant (inline or named) to its pattern - /// representation using `const_to_pat`. This is used for unsafety checking. + /// Wrapper node representing a named constant that was lowered to a pattern + /// using `const_to_pat`. + /// + /// This is used by some diagnostics for non-exhaustive matches, to map + /// the pattern node back to the `DefId` of its original constant. + /// + /// FIXME(#150498): Can we make this an `Option` field on `Pat` + /// instead, so that non-diagnostic code can ignore it more easily? ExpandedConstant { /// [DefId] of the constant item. def_id: DefId, /// The pattern that the constant lowered to. - /// - /// HACK: we need to keep the `DefId` of inline constants around for unsafety checking; - /// therefore when a range pattern contains inline constants, we re-wrap the range pattern - /// with the `ExpandedConstant` nodes that correspond to the range endpoints. Hence - /// `subpattern` may actually be a range pattern, and `def_id` be the constant for one of - /// its endpoints. subpattern: Box>, }, diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index a06c030b103b..4f03e3d965c6 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -410,14 +410,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { visit::walk_pat(self, pat); self.inside_adt = old_inside_adt; } - PatKind::ExpandedConstant { def_id, .. } => { - if let Some(def) = def_id.as_local() - && matches!(self.tcx.def_kind(def_id), DefKind::InlineConst) - { - self.visit_inner_body(def); - } - visit::walk_pat(self, pat); - } _ => { visit::walk_pat(self, pat); } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index ce4c89a8eb2e..2da9a43f71d8 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -187,7 +187,7 @@ impl<'tcx> ConstToPat<'tcx> { } // Wrap the pattern in a marker node to indicate that it is the result of lowering a - // constant. This is used for diagnostics, and for unsafety checking of inline const blocks. + // constant. This is used for diagnostics. let kind = PatKind::ExpandedConstant { subpattern: inlined_const_as_pat, def_id: uv.def }; Box::new(Pat { kind, ty, span: self.span }) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index d62faae44d67..063bb4a3d461 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -21,7 +21,6 @@ use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment}; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; -use rustc_span::def_id::DefId; use rustc_span::{ErrorGuaranteed, Span}; use tracing::{debug, instrument}; @@ -131,9 +130,8 @@ impl<'tcx> PatCtxt<'tcx> { fn lower_pattern_range_endpoint( &mut self, expr: Option<&'tcx hir::PatExpr<'tcx>>, - // Out-parameters collecting extra data to be reapplied by the caller + // Out-parameter collecting extra data to be reapplied by the caller ascriptions: &mut Vec>, - expanded_consts: &mut Vec, ) -> Result>, ErrorGuaranteed> { let Some(expr) = expr else { return Ok(None) }; @@ -148,8 +146,10 @@ impl<'tcx> PatCtxt<'tcx> { ascriptions.push(ascription); kind = subpattern.kind; } - PatKind::ExpandedConstant { def_id, subpattern } => { - expanded_consts.push(def_id); + PatKind::ExpandedConstant { def_id: _, subpattern } => { + // Expanded-constant nodes are currently only needed by + // diagnostics that don't apply to range patterns, so we + // can just discard them here. kind = subpattern.kind; } _ => break, @@ -227,10 +227,7 @@ impl<'tcx> PatCtxt<'tcx> { // Collect extra data while lowering the endpoints, to be reapplied later. let mut ascriptions = vec![]; - let mut expanded_consts = vec![]; - - let mut lower_endpoint = - |expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions, &mut expanded_consts); + let mut lower_endpoint = |expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions); let lo = lower_endpoint(lo_expr)?.unwrap_or(PatRangeBoundary::NegInfinity); let hi = lower_endpoint(hi_expr)?.unwrap_or(PatRangeBoundary::PosInfinity); @@ -282,10 +279,11 @@ impl<'tcx> PatCtxt<'tcx> { let subpattern = Box::new(Pat { span, ty, kind }); kind = PatKind::AscribeUserType { ascription, subpattern }; } - for def_id in expanded_consts { - let subpattern = Box::new(Pat { span, ty, kind }); - kind = PatKind::ExpandedConstant { def_id, subpattern }; - } + // `PatKind::ExpandedConstant` wrappers from range endpoints used to + // also be preserved here, but that was only needed for unsafeck of + // inline `const { .. }` patterns, which were removed by + // . + Ok(kind) } From 8cc5dc374be1d6b87c487965b6fee736ad0b82c4 Mon Sep 17 00:00:00 2001 From: qb42 <42453758+qb42@users.noreply.github.com> Date: Tue, 30 Dec 2025 06:13:43 +0000 Subject: [PATCH 1406/3801] Add missing columns to demoted targets --- src/doc/rustc/src/platform-support.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 5164ab69d353..75ab2cb9db32 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -285,8 +285,8 @@ target | std | host | notes [`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS [`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS [`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | Arm BE8 the default Arm big-endian architecture since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). -[`armebv7r-none-eabi`](platform-support/armebv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian -[`armebv7r-none-eabihf`](platform-support/armebv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat +[`armebv7r-none-eabi`](platform-support/armebv7r-none-eabi.md) | * | | Bare Armv7-R, Big Endian +[`armebv7r-none-eabihf`](platform-support/armebv7r-none-eabi.md) | * | | Bare Armv7-R, Big Endian, hardfloat [`armv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Bare Armv4T `armv4t-unknown-linux-gnueabi` | ? | | Armv4T Linux [`armv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Bare Armv5TE @@ -423,7 +423,7 @@ target | std | host | notes [`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI) -[`wasm32-wasip3`](platform-support/wasm32-wasip3.md) | ✓ | WebAssembly with WASIp3 +[`wasm32-wasip3`](platform-support/wasm32-wasip3.md) | ✓ | | WebAssembly with WASIp3 [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator [`x86_64-lynx-lynxos178`](platform-support/lynxos178.md) | | | x86_64 LynxOS-178 From e330a3fab15e1ca2da03bd54de3a40a20485c59d Mon Sep 17 00:00:00 2001 From: qb42 <42453758+qb42@users.noreply.github.com> Date: Tue, 30 Dec 2025 06:26:01 +0000 Subject: [PATCH 1407/3801] Make empty columns consistent --- src/doc/rustc/src/platform-support.md | 48 +++++++++++++-------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 75ab2cb9db32..e09597062bdd 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -260,7 +260,7 @@ target | std | host | notes [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit [`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) -[`aarch64-unknown-managarm-mlibc`](platform-support/managarm.md) | ? | | ARM64 Managarm +[`aarch64-unknown-managarm-mlibc`](platform-support/managarm.md) | ? | | ARM64 Managarm [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD [`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | @@ -282,8 +282,8 @@ target | std | host | notes [`amdgcn-amd-amdhsa`](platform-support/amdgcn-amd-amdhsa.md) | * | | `-Ctarget-cpu=gfx...` to specify [the AMD GPU] to compile for [`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Arm Apple WatchOS 64-bit with 32-bit pointers [`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin -[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS -[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS +[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS +[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS [`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | Arm BE8 the default Arm big-endian architecture since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). [`armebv7r-none-eabi`](platform-support/armebv7r-none-eabi.md) | * | | Bare Armv7-R, Big Endian [`armebv7r-none-eabihf`](platform-support/armebv7r-none-eabi.md) | * | | Bare Armv7-R, Big Endian, hardfloat @@ -314,9 +314,9 @@ target | std | host | notes `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian) `csky-unknown-linux-gnuabiv2hf` | ✓ | | C-SKY abiv2 Linux, hardfloat (little endian) -[`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.5 -[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) -[`hexagon-unknown-qurt`](platform-support/hexagon-unknown-qurt.md)| * | | Hexagon QuRT +[`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.5 +[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) +[`hexagon-unknown-qurt`](platform-support/hexagon-unknown-qurt.md)| * | | Hexagon QuRT [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS (Penryn) [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86 (original Pentium) [^x86_32-floats-x87] [`i586-unknown-redox`](platform-support/redox.md) | ✓ | | 32-bit x86 Redox OS (PentiumPro) [^x86_32-floats-x87] @@ -329,12 +329,12 @@ target | std | host | notes [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD (Pentium 4) [^x86_32-floats-return-ABI] `i686-uwp-windows-gnu` | ✓ | | [^x86_32-floats-return-ABI] [`i686-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | | [^x86_32-floats-return-ABI] [^win32-msvc-alignment] -[`i686-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] -[`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] [^win32-msvc-alignment] +[`i686-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] +[`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] [^win32-msvc-alignment] [`i686-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [^x86_32-floats-return-ABI] -[`loongarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | LoongArch64 OpenHarmony -[`loongarch32-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch32 Bare-metal (ILP32D ABI) -[`loongarch32-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch32 Bare-metal (ILP32S ABI) +[`loongarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | LoongArch64 OpenHarmony +[`loongarch32-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch32 Bare-metal (ILP32D ABI) +[`loongarch32-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch32 Bare-metal (ILP32S ABI) [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux [`m68k-unknown-none-elf`](platform-support/m68k-unknown-none-elf.md) | | | Motorola 680x0 `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23) @@ -359,8 +359,8 @@ target | std | host | notes [`mipsisa64r6-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ? | | 64-bit MIPS Release 6 Big Endian [`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ✓ | ✓ | 64-bit MIPS Release 6 Little Endian `msp430-none-elf` | * | | 16-bit MSP430 microcontrollers -[`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD -[`powerpc-unknown-helenos`](platform-support/helenos.md) | ✓ | | PowerPC HelenOS +[`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD +[`powerpc-unknown-helenos`](platform-support/helenos.md) | ✓ | | PowerPC HelenOS [`powerpc-unknown-linux-gnuspe`](platform-support/powerpc-unknown-linux-gnuspe.md) | ✓ | | PowerPC SPE Linux `powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.5 [`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? | | PowerPC SPE Linux with musl 1.2.5 @@ -378,8 +378,8 @@ target | std | host | notes [`riscv32e-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA) [`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA) [`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA) -`riscv32gc-unknown-linux-gnu` | ✓ | | RISC-V Linux (kernel 5.4, glibc 2.33) -`riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.5) +`riscv32gc-unknown-linux-gnu` | ✓ | | RISC-V Linux (kernel 5.4, glibc 2.33) +`riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.5) [`riscv32im-risc0-zkvm-elf`](platform-support/riscv32im-risc0-zkvm-elf.md) | ? | | RISC Zero's zero-knowledge Virtual Machine (RV32IM ISA) [`riscv32ima-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IMA ISA) [`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF @@ -389,12 +389,12 @@ target | std | host | notes [`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 32bit with NuttX [`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF [`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 32bit with NuttX -[`riscv64-linux-android`](platform-support/android.md) | ? | | RISC-V 64-bit Android +[`riscv64-linux-android`](platform-support/android.md) | ? | | RISC-V 64-bit Android [`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | -`riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD -`riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia -[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit -[`riscv64gc-unknown-managarm-mlibc`](platform-support/managarm.md) | ? | | RISC-V Managarm +`riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD +`riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia +[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit +[`riscv64gc-unknown-managarm-mlibc`](platform-support/managarm.md) | ? | | RISC-V Managarm [`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD [`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 64bit with NuttX [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 @@ -426,12 +426,12 @@ target | std | host | notes [`wasm32-wasip3`](platform-support/wasm32-wasip3.md) | ✓ | | WebAssembly with WASIp3 [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator -[`x86_64-lynx-lynxos178`](platform-support/lynxos178.md) | | | x86_64 LynxOS-178 +[`x86_64-lynx-lynxos178`](platform-support/lynxos178.md) | | | x86_64 LynxOS-178 [`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ✓ | | 64-bit x86 Cygwin | [`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) | [`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS | -[`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.5 +[`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.5 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku [`x86_64-unknown-hermit`](platform-support/hermit.md) | ✓ | | x86_64 Hermit @@ -439,13 +439,13 @@ target | std | host | notes [`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd `x86_64-unknown-l4re-uclibc` | ? | | [`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc -[`x86_64-unknown-managarm-mlibc`](platform-support/managarm.md) | ? | | x86_64 Managarm +[`x86_64-unknown-managarm-mlibc`](platform-support/managarm.md) | ? | | x86_64 Managarm [`x86_64-unknown-motor`](platform-support/motor.md) | ✓ | | x86_64 Motor OS [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD [`x86_64-unknown-trusty`](platform-support/trusty.md) | ✓ | | `x86_64-uwp-windows-gnu` | ✓ | | [`x86_64-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | | -[`x86_64-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 64-bit Windows 7 support +[`x86_64-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 64-bit Windows 7 support [`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | ✓ | 64-bit Windows 7 support [`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) From 841091b8467535c2490e7cefffc3668f7693bd70 Mon Sep 17 00:00:00 2001 From: qb42 <42453758+qb42@users.noreply.github.com> Date: Tue, 30 Dec 2025 06:44:28 +0000 Subject: [PATCH 1408/3801] Remove extra columns from promoted targets --- src/doc/rustc/src/platform-support.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index e09597062bdd..754d0c975ec3 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -163,10 +163,10 @@ target | std | notes `armv7-unknown-linux-musleabi` | ✓ | Armv7-A Linux with musl 1.2.5 `armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.5, hardfloat [`armv7a-none-eabi`](platform-support/armv7a-none-eabi.md) | * | Bare Armv7-A -[`armv7a-none-eabihf`](platform-support/armv7a-none-eabi.md) | * | | Bare Armv7-A, hardfloat +[`armv7a-none-eabihf`](platform-support/armv7a-none-eabi.md) | * | Bare Armv7-A, hardfloat [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat -[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat +[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | Bare Armv8-R, hardfloat `i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2+, glibc 2.17, original Pentium) [^x86_32-floats-x87] `i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.5, original Pentium) [^x86_32-floats-x87] [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([Pentium 4 plus various extensions](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI] From b3c3604f624ec256da9a18cd25b9260dd6717d8c Mon Sep 17 00:00:00 2001 From: AprilNEA Date: Tue, 30 Dec 2025 17:51:49 +0800 Subject: [PATCH 1409/3801] Add regression test for issue 99173 Adds a test for nested proc-macro calls where the inner macro returns an empty TokenStream. This previously caused an ICE in rustc_resolve. --- .../auxiliary/nested-empty-proc-macro.rs | 18 ++++++++++++++++++ tests/ui/proc-macro/nested-empty-proc-macro.rs | 12 ++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/ui/proc-macro/auxiliary/nested-empty-proc-macro.rs create mode 100644 tests/ui/proc-macro/nested-empty-proc-macro.rs diff --git a/tests/ui/proc-macro/auxiliary/nested-empty-proc-macro.rs b/tests/ui/proc-macro/auxiliary/nested-empty-proc-macro.rs new file mode 100644 index 000000000000..a1cb4c1c7638 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/nested-empty-proc-macro.rs @@ -0,0 +1,18 @@ +// Auxiliary proc-macro for issue #99173 +// Tests that nested proc-macro calls with empty output don't cause ICE + +extern crate proc_macro; + +use proc_macro::TokenStream; + +// This macro returns an empty TokenStream +#[proc_macro] +pub fn ignore(_input: TokenStream) -> TokenStream { + TokenStream::new() +} + +// This macro generates code that calls the `ignore` macro +#[proc_macro] +pub fn outer_macro(_input: TokenStream) -> TokenStream { + "nested_empty_proc_macro::ignore!(42)".parse().unwrap() +} diff --git a/tests/ui/proc-macro/nested-empty-proc-macro.rs b/tests/ui/proc-macro/nested-empty-proc-macro.rs new file mode 100644 index 000000000000..d1c2c8a01412 --- /dev/null +++ b/tests/ui/proc-macro/nested-empty-proc-macro.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ proc-macro: nested-empty-proc-macro.rs + +// Regression test for issue #99173 +// Tests that nested proc-macro calls where the inner macro returns +// an empty TokenStream don't cause an ICE. + +extern crate nested_empty_proc_macro; + +fn main() { + nested_empty_proc_macro::outer_macro!(1 * 2 * 3 * 7); +} From 791fa37df5e91619afe0d0d7d4e0b04b167b3ddd Mon Sep 17 00:00:00 2001 From: tiif Date: Sun, 28 Dec 2025 05:51:01 +0000 Subject: [PATCH 1410/3801] Move c-variadic arguments handling into compute_inputs_and_output --- .../rustc_borrowck/src/universal_regions.rs | 66 ++++++++++--------- tests/ui/c-variadic/variadic-ffi-4.stderr | 8 +-- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index a0d5e1ce780d..fda4719fc3f5 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -543,38 +543,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { &indices, ); - let (unnormalized_output_ty, mut unnormalized_input_tys) = + let (unnormalized_output_ty, unnormalized_input_tys) = inputs_and_output.split_last().unwrap(); - // C-variadic fns also have a `VaList` input that's not listed in the signature - // (as it's created inside the body itself, not passed in from outside). - if let DefiningTy::FnDef(def_id, _) = defining_ty { - if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() { - let va_list_did = self - .infcx - .tcx - .require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def)); - - let reg_vid = self - .infcx - .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { - RegionCtxt::Free(sym::c_dash_variadic) - }) - .as_var(); - - let region = ty::Region::new_var(self.infcx.tcx, reg_vid); - let va_list_ty = self - .infcx - .tcx - .type_of(va_list_did) - .instantiate(self.infcx.tcx, &[region.into()]); - - unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter( - unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)), - ); - } - } - let fr_fn_body = self .infcx .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { @@ -816,7 +787,40 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::FnDef(def_id, _) => { let sig = tcx.fn_sig(def_id).instantiate_identity(); let sig = indices.fold_to_region_vids(tcx, sig); - sig.inputs_and_output() + let inputs_and_output = sig.inputs_and_output(); + + // C-variadic fns also have a `VaList` input that's not listed in the signature + // (as it's created inside the body itself, not passed in from outside). + if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() { + let va_list_did = self + .infcx + .tcx + .require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def)); + + let reg_vid = self + .infcx + .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::Free(sym::c_dash_variadic) + }) + .as_var(); + + let region = ty::Region::new_var(self.infcx.tcx, reg_vid); + let va_list_ty = self + .infcx + .tcx + .type_of(va_list_did) + .instantiate(self.infcx.tcx, &[region.into()]); + + // The signature needs to follow the order [input_tys, va_list_ty, output_ty] + return inputs_and_output.map_bound(|tys| { + let (output_ty, input_tys) = tys.split_last().unwrap(); + tcx.mk_type_list_from_iter( + input_tys.iter().copied().chain([va_list_ty, *output_ty]), + ) + }); + } + + inputs_and_output } DefiningTy::Const(def_id, _) => { diff --git a/tests/ui/c-variadic/variadic-ffi-4.stderr b/tests/ui/c-variadic/variadic-ffi-4.stderr index a230bb6f5861..01ace5c79680 100644 --- a/tests/ui/c-variadic/variadic-ffi-4.stderr +++ b/tests/ui/c-variadic/variadic-ffi-4.stderr @@ -30,9 +30,9 @@ error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:22:5 | LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { - | ------- ------- has type `VaList<'2>` + | ------- ------- has type `VaList<'1>` | | - | has type `&mut VaList<'1>` + | has type `&mut VaList<'2>` LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` | @@ -44,9 +44,9 @@ error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:22:5 | LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { - | ------- ------- has type `VaList<'2>` + | ------- ------- has type `VaList<'1>` | | - | has type `&mut VaList<'1>` + | has type `&mut VaList<'2>` LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1` | From 9508cd1cb7cc3f329e79da69839b144eabfe0d91 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 29 Dec 2025 10:54:10 +0200 Subject: [PATCH 1411/3801] Compress token trees for best memory usage --- src/tools/rust-analyzer/Cargo.lock | 2 + .../crates/syntax-bridge/src/lib.rs | 13 +- .../crates/syntax-bridge/src/tests.rs | 4 +- src/tools/rust-analyzer/crates/tt/Cargo.toml | 2 + .../rust-analyzer/crates/tt/src/buffer.rs | 37 +- src/tools/rust-analyzer/crates/tt/src/iter.rs | 94 +- src/tools/rust-analyzer/crates/tt/src/lib.rs | 552 +++------- .../rust-analyzer/crates/tt/src/storage.rs | 992 ++++++++++++++++++ 8 files changed, 1259 insertions(+), 437 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/tt/src/storage.rs diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 10927728a105..42eaeb01f1f2 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -3085,8 +3085,10 @@ name = "tt" version = "0.0.0" dependencies = [ "arrayvec", + "indexmap", "intern", "ra-ap-rustc_lexer", + "rustc-hash 2.1.1", "span", "stdx", "text-size 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs index ce238eb932ae..0dcf18a4ad97 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs @@ -866,7 +866,8 @@ impl TtTreeSink<'_> { /// Parses a float literal as if it was a one to two name ref nodes with a dot inbetween. /// This occurs when a float literal is used as a field access. fn float_split(&mut self, has_pseudo_dot: bool) { - let (text, span) = match self.cursor.token_tree() { + let token_tree = self.cursor.token_tree(); + let (text, span) = match &token_tree { Some(tt::TokenTree::Leaf(tt::Leaf::Literal( lit @ tt::Literal { span, kind: tt::LitKind::Float, .. }, ))) => (lit.text(), *span), @@ -928,9 +929,15 @@ impl TtTreeSink<'_> { self.buf.push_str("r#"); self.text_pos += TextSize::of("r#"); } - let r = (ident.sym.as_str(), ident.span); + let text = ident.sym.as_str(); + self.buf += text; + self.text_pos += TextSize::of(text); + combined_span = match combined_span { + None => Some(ident.span), + Some(prev_span) => Some(Self::merge_spans(prev_span, ident.span)), + }; self.cursor.bump(); - r + continue 'tokens; } tt::Leaf::Punct(punct) => { assert!(punct.char.is_ascii()); diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs index 8c28e1c5aaac..16f2498bf357 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs @@ -36,9 +36,9 @@ fn check_punct_spacing(fixture: &str) { if let tt::TokenTree::Leaf(Leaf::Punct(Punct { spacing, span: Span { range, .. }, .. })) = token_tree - && let Some(expected) = annotations.remove(range) + && let Some(expected) = annotations.remove(&range) { - assert_eq!(expected, *spacing); + assert_eq!(expected, spacing); } cursor.bump(); } diff --git a/src/tools/rust-analyzer/crates/tt/Cargo.toml b/src/tools/rust-analyzer/crates/tt/Cargo.toml index 4b38bfb1e536..6cfb76400e3c 100644 --- a/src/tools/rust-analyzer/crates/tt/Cargo.toml +++ b/src/tools/rust-analyzer/crates/tt/Cargo.toml @@ -15,6 +15,8 @@ doctest = false [dependencies] arrayvec.workspace = true text-size.workspace = true +rustc-hash.workspace = true +indexmap.workspace = true span = { path = "../span", version = "0.0", default-features = false } stdx.workspace = true diff --git a/src/tools/rust-analyzer/crates/tt/src/buffer.rs b/src/tools/rust-analyzer/crates/tt/src/buffer.rs index de6379b5cd14..78cf4b956d0c 100644 --- a/src/tools/rust-analyzer/crates/tt/src/buffer.rs +++ b/src/tools/rust-analyzer/crates/tt/src/buffer.rs @@ -1,17 +1,17 @@ //! Stateful iteration over token trees. //! //! We use this as the source of tokens for parser. -use crate::{Leaf, Subtree, TokenTree, TokenTreesView}; +use crate::{Leaf, Subtree, TokenTree, TokenTreesView, dispatch_ref}; pub struct Cursor<'a> { - buffer: &'a [TokenTree], + buffer: TokenTreesView<'a>, index: usize, subtrees_stack: Vec, } impl<'a> Cursor<'a> { pub fn new(buffer: TokenTreesView<'a>) -> Self { - Self { buffer: buffer.0, index: 0, subtrees_stack: Vec::new() } + Self { buffer, index: 0, subtrees_stack: Vec::new() } } /// Check whether it is eof @@ -23,16 +23,22 @@ impl<'a> Cursor<'a> { self.subtrees_stack.is_empty() } - fn last_subtree(&self) -> Option<(usize, &'a Subtree)> { + fn at(&self, idx: usize) -> Option { + dispatch_ref! { + match self.buffer.repr => tt => Some(tt.get(idx)?.to_api(self.buffer.span_parts)) + } + } + + fn last_subtree(&self) -> Option<(usize, Subtree)> { self.subtrees_stack.last().map(|&subtree_idx| { - let TokenTree::Subtree(subtree) = &self.buffer[subtree_idx] else { + let Some(TokenTree::Subtree(subtree)) = self.at(subtree_idx) else { panic!("subtree pointing to non-subtree"); }; (subtree_idx, subtree) }) } - pub fn end(&mut self) -> &'a Subtree { + pub fn end(&mut self) -> Subtree { let (last_subtree_idx, last_subtree) = self.last_subtree().expect("called `Cursor::end()` without an open subtree"); // +1 because `Subtree.len` excludes the subtree itself. @@ -46,14 +52,14 @@ impl<'a> Cursor<'a> { } /// Returns the `TokenTree` at the cursor if it is not at the end of a subtree. - pub fn token_tree(&self) -> Option<&'a TokenTree> { + pub fn token_tree(&self) -> Option { if let Some((last_subtree_idx, last_subtree)) = self.last_subtree() { // +1 because `Subtree.len` excludes the subtree itself. if last_subtree_idx + last_subtree.usize_len() + 1 == self.index { return None; } } - self.buffer.get(self.index) + self.at(self.index) } /// Bump the cursor, and enters a subtree if it is on one. @@ -66,7 +72,7 @@ impl<'a> Cursor<'a> { "called `Cursor::bump()` when at the end of a subtree" ); } - if let TokenTree::Subtree(_) = self.buffer[self.index] { + if let Some(TokenTree::Subtree(_)) = self.at(self.index) { self.subtrees_stack.push(self.index); } self.index += 1; @@ -81,13 +87,13 @@ impl<'a> Cursor<'a> { } } // +1 because `Subtree.len` excludes the subtree itself. - if let TokenTree::Subtree(_) = self.buffer[self.index] { + if let Some(TokenTree::Subtree(_)) = self.at(self.index) { self.subtrees_stack.push(self.index); } self.index += 1; } - pub fn peek_two_leaves(&self) -> Option<[&'a Leaf; 2]> { + pub fn peek_two_leaves(&self) -> Option<[Leaf; 2]> { if let Some((last_subtree_idx, last_subtree)) = self.last_subtree() { // +1 because `Subtree.len` excludes the subtree itself. let last_end = last_subtree_idx + last_subtree.usize_len() + 1; @@ -95,14 +101,17 @@ impl<'a> Cursor<'a> { return None; } } - self.buffer.get(self.index..self.index + 2).and_then(|it| match it { - [TokenTree::Leaf(a), TokenTree::Leaf(b)] => Some([a, b]), + self.at(self.index).zip(self.at(self.index + 1)).and_then(|it| match it { + (TokenTree::Leaf(a), TokenTree::Leaf(b)) => Some([a, b]), _ => None, }) } pub fn crossed(&self) -> TokenTreesView<'a> { assert!(self.is_root()); - TokenTreesView::new(&self.buffer[..self.index]) + TokenTreesView { + repr: self.buffer.repr.get(..self.index).unwrap(), + span_parts: self.buffer.span_parts, + } } } diff --git a/src/tools/rust-analyzer/crates/tt/src/iter.rs b/src/tools/rust-analyzer/crates/tt/src/iter.rs index 5ab9f94b63fd..7caacd40dd7e 100644 --- a/src/tools/rust-analyzer/crates/tt/src/iter.rs +++ b/src/tools/rust-analyzer/crates/tt/src/iter.rs @@ -7,11 +7,14 @@ use arrayvec::ArrayVec; use intern::sym; use span::Span; -use crate::{Ident, Leaf, MAX_GLUED_PUNCT_LEN, Punct, Spacing, Subtree, TokenTree, TokenTreesView}; +use crate::{ + Ident, Leaf, MAX_GLUED_PUNCT_LEN, Punct, Spacing, Subtree, TokenTree, TokenTreesReprRef, + TokenTreesView, dispatch_ref, +}; #[derive(Clone)] pub struct TtIter<'a> { - inner: std::slice::Iter<'a, TokenTree>, + inner: TokenTreesView<'a>, } impl fmt::Debug for TtIter<'_> { @@ -21,17 +24,17 @@ impl fmt::Debug for TtIter<'_> { } #[derive(Clone, Copy)] -pub struct TtIterSavepoint<'a>(&'a [TokenTree]); +pub struct TtIterSavepoint<'a>(TokenTreesView<'a>); impl<'a> TtIterSavepoint<'a> { pub fn remaining(self) -> TokenTreesView<'a> { - TokenTreesView::new(self.0) + self.0 } } impl<'a> TtIter<'a> { - pub(crate) fn new(tt: &'a [TokenTree]) -> TtIter<'a> { - TtIter { inner: tt.iter() } + pub(crate) fn new(tt: TokenTreesView<'a>) -> TtIter<'a> { + TtIter { inner: tt } } pub fn expect_char(&mut self, char: char) -> Result<(), ()> { @@ -141,8 +144,8 @@ impl<'a> TtIter<'a> { let _ = self.next().unwrap(); let _ = self.next().unwrap(); res.push(first); - res.push(*second); - res.push(*third.unwrap()); + res.push(second); + res.push(third.unwrap()); } ('-' | '!' | '*' | '/' | '&' | '%' | '^' | '+' | '<' | '=' | '>' | '|', '=', _) | ('-' | '=' | '>', '>', _) @@ -154,7 +157,7 @@ impl<'a> TtIter<'a> { | ('|', '|', _) => { let _ = self.next().unwrap(); res.push(first); - res.push(*second); + res.push(second); } _ => res.push(first), } @@ -162,17 +165,21 @@ impl<'a> TtIter<'a> { } /// This method won't check for subtrees, so the nth token tree may not be the nth sibling of the current tree. - fn peek_n(&self, n: usize) -> Option<&'a TokenTree> { - self.inner.as_slice().get(n) + fn peek_n(&self, n: usize) -> Option { + dispatch_ref! { + match self.inner.repr => tt => Some(tt.get(n)?.to_api(self.inner.span_parts)) + } } pub fn peek(&self) -> Option> { - match self.inner.as_slice().first()? { - TokenTree::Leaf(leaf) => Some(TtElement::Leaf(leaf.clone())), + match self.peek_n(0)? { + TokenTree::Leaf(leaf) => Some(TtElement::Leaf(leaf)), TokenTree::Subtree(subtree) => { - let nested_iter = - TtIter { inner: self.inner.as_slice()[1..][..subtree.usize_len()].iter() }; - Some(TtElement::Subtree(*subtree, nested_iter)) + let nested_repr = self.inner.repr.get(1..subtree.usize_len() + 1).unwrap(); + let nested_iter = TtIter { + inner: TokenTreesView { repr: nested_repr, span_parts: self.inner.span_parts }, + }; + Some(TtElement::Subtree(subtree, nested_iter)) } } } @@ -183,26 +190,51 @@ impl<'a> TtIter<'a> { } pub fn next_span(&self) -> Option { - Some(self.inner.as_slice().first()?.first_span()) + Some(self.peek()?.first_span()) } pub fn remaining(&self) -> TokenTreesView<'a> { - TokenTreesView::new(self.inner.as_slice()) + self.inner } /// **Warning**: This advances `skip` **flat** token trees, subtrees account for children+1! pub fn flat_advance(&mut self, skip: usize) { - self.inner = self.inner.as_slice()[skip..].iter(); + self.inner.repr = self.inner.repr.get(skip..).unwrap(); } pub fn savepoint(&self) -> TtIterSavepoint<'a> { - TtIterSavepoint(self.inner.as_slice()) + TtIterSavepoint(self.inner) } pub fn from_savepoint(&self, savepoint: TtIterSavepoint<'a>) -> TokenTreesView<'a> { - let len = (self.inner.as_slice().as_ptr() as usize - savepoint.0.as_ptr() as usize) - / size_of::(); - TokenTreesView::new(&savepoint.0[..len]) + let len = match (self.inner.repr, savepoint.0.repr) { + ( + TokenTreesReprRef::SpanStorage32(this), + TokenTreesReprRef::SpanStorage32(savepoint), + ) => { + (this.as_ptr() as usize - savepoint.as_ptr() as usize) + / size_of::>() + } + ( + TokenTreesReprRef::SpanStorage64(this), + TokenTreesReprRef::SpanStorage64(savepoint), + ) => { + (this.as_ptr() as usize - savepoint.as_ptr() as usize) + / size_of::>() + } + ( + TokenTreesReprRef::SpanStorage96(this), + TokenTreesReprRef::SpanStorage96(savepoint), + ) => { + (this.as_ptr() as usize - savepoint.as_ptr() as usize) + / size_of::>() + } + _ => panic!("savepoint did not originate from this TtIter"), + }; + TokenTreesView { + repr: savepoint.0.repr.get(..len).unwrap(), + span_parts: savepoint.0.span_parts, + } } pub fn next_as_view(&mut self) -> Option> { @@ -242,14 +274,12 @@ impl TtElement<'_> { impl<'a> Iterator for TtIter<'a> { type Item = TtElement<'a>; fn next(&mut self) -> Option { - match self.inner.next()? { - TokenTree::Leaf(leaf) => Some(TtElement::Leaf(leaf.clone())), - TokenTree::Subtree(subtree) => { - let nested_iter = - TtIter { inner: self.inner.as_slice()[..subtree.usize_len()].iter() }; - self.inner = self.inner.as_slice()[subtree.usize_len()..].iter(); - Some(TtElement::Subtree(*subtree, nested_iter)) - } - } + let result = self.peek()?; + let skip = match &result { + TtElement::Leaf(_) => 1, + TtElement::Subtree(subtree, _) => subtree.usize_len() + 1, + }; + self.inner.repr = self.inner.repr.get(skip..).unwrap(); + Some(result) } } diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 91fcec9327c3..a59fc2e08982 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -15,8 +15,9 @@ extern crate rustc_lexer; pub mod buffer; pub mod iter; +mod storage; -use std::fmt; +use std::{fmt, slice::SliceIndex}; use arrayvec::ArrayString; use buffer::Cursor; @@ -26,7 +27,10 @@ use stdx::{impl_from, itertools::Itertools as _}; pub use span::Span; pub use text_size::{TextRange, TextSize}; +use crate::storage::{CompressedSpanPart, SpanStorage}; + pub use self::iter::{TtElement, TtIter}; +pub use self::storage::{TopSubtree, TopSubtreeBuilder}; pub const MAX_GLUED_PUNCT_LEN: usize = 3; @@ -125,267 +129,71 @@ impl Subtree { } } -#[derive(Clone, PartialEq, Eq, Hash)] -pub struct TopSubtree(Box<[TokenTree]>); +/// `dispatch_ref! {}` +macro_rules! dispatch_ref { + ( + match $scrutinee:expr => $tt:ident => $body:expr + ) => { + match $scrutinee { + $crate::TokenTreesReprRef::SpanStorage32($tt) => $body, + $crate::TokenTreesReprRef::SpanStorage64($tt) => $body, + $crate::TokenTreesReprRef::SpanStorage96($tt) => $body, + } + }; +} +use dispatch_ref; -impl TopSubtree { - pub fn empty(span: DelimSpan) -> Self { - Self(Box::new([TokenTree::Subtree(Subtree { - delimiter: Delimiter::invisible_delim_spanned(span), - len: 0, - })])) - } +#[derive(Clone, Copy)] +enum TokenTreesReprRef<'a> { + SpanStorage32(&'a [crate::storage::TokenTree]), + SpanStorage64(&'a [crate::storage::TokenTree]), + SpanStorage96(&'a [crate::storage::TokenTree]), +} - pub fn invisible_from_leaves(delim_span: Span, leaves: [Leaf; N]) -> Self { - let mut builder = TopSubtreeBuilder::new(Delimiter::invisible_spanned(delim_span)); - builder.extend(leaves); - builder.build() - } - - pub fn from_token_trees(delimiter: Delimiter, token_trees: TokenTreesView<'_>) -> Self { - let mut builder = TopSubtreeBuilder::new(delimiter); - builder.extend_with_tt(token_trees); - builder.build() - } - - pub fn from_serialized(tt: Vec) -> Self { - Self(tt.into_boxed_slice()) - } - - pub fn from_subtree(subtree: SubtreeView<'_>) -> Self { - Self(subtree.0.into()) - } - - pub fn view(&self) -> SubtreeView<'_> { - SubtreeView::new(&self.0) - } - - pub fn iter(&self) -> TtIter<'_> { - self.view().iter() - } - - pub fn top_subtree(&self) -> Subtree { - self.view().top_subtree() - } - - pub fn set_top_subtree_delimiter_kind(&mut self, kind: DelimiterKind) { - self.top_subtree_mut().delimiter.kind = kind; - } - - pub fn set_top_subtree_delimiter_span(&mut self, span: DelimSpan) { - let top_subtree = self.top_subtree_mut(); - top_subtree.delimiter.open = span.open; - top_subtree.delimiter.close = span.close; - } - - fn top_subtree_mut(&mut self) -> &mut Subtree { - let TokenTree::Subtree(subtree) = &mut self.0[0] else { - unreachable!("the first token tree is always the top subtree"); - }; - subtree - } - - pub fn set_token(&mut self, idx: usize, leaf: Leaf) { - assert!(matches!(self.0[idx], TokenTree::Leaf(_)), "cannot replace a subtree by a leaf"); - self.0[idx] = leaf.into(); - } - - pub fn token_trees(&self) -> TokenTreesView<'_> { - self.view().token_trees() - } - - pub fn as_token_trees(&self) -> TokenTreesView<'_> { - self.view().as_token_trees() - } - - pub fn change_every_ast_id(&mut self, mut callback: impl FnMut(&mut span::ErasedFileAstId)) { - for tt in &mut self.0 { - match tt { - TokenTree::Leaf(Leaf::Ident(Ident { span, .. })) - | TokenTree::Leaf(Leaf::Literal(Literal { span, .. })) - | TokenTree::Leaf(Leaf::Punct(Punct { span, .. })) => { - callback(&mut span.anchor.ast_id); - } - TokenTree::Subtree(subtree) => { - callback(&mut subtree.delimiter.open.anchor.ast_id); - callback(&mut subtree.delimiter.close.anchor.ast_id); - } +impl<'a> TokenTreesReprRef<'a> { + #[inline] + fn get(&self, index: I) -> Option + where + I: SliceIndex< + [crate::storage::TokenTree], + Output = [crate::storage::TokenTree], + >, + I: SliceIndex< + [crate::storage::TokenTree], + Output = [crate::storage::TokenTree], + >, + I: SliceIndex< + [crate::storage::TokenTree], + Output = [crate::storage::TokenTree], + >, + { + Some(match self { + TokenTreesReprRef::SpanStorage32(tt) => { + TokenTreesReprRef::SpanStorage32(tt.get(index)?) + } + TokenTreesReprRef::SpanStorage64(tt) => { + TokenTreesReprRef::SpanStorage64(tt.get(index)?) + } + TokenTreesReprRef::SpanStorage96(tt) => { + TokenTreesReprRef::SpanStorage96(tt.get(index)?) } - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TopSubtreeBuilder { - unclosed_subtree_indices: Vec, - token_trees: Vec, - last_closed_subtree: Option, -} - -impl TopSubtreeBuilder { - pub fn new(top_delimiter: Delimiter) -> Self { - let mut result = Self { - unclosed_subtree_indices: Vec::new(), - token_trees: Vec::new(), - last_closed_subtree: None, - }; - let top_subtree = TokenTree::Subtree(Subtree { delimiter: top_delimiter, len: 0 }); - result.token_trees.push(top_subtree); - result - } - - pub fn open(&mut self, delimiter_kind: DelimiterKind, open_span: Span) { - self.unclosed_subtree_indices.push(self.token_trees.len()); - self.token_trees.push(TokenTree::Subtree(Subtree { - delimiter: Delimiter { - open: open_span, - close: open_span, // Will be overwritten on close. - kind: delimiter_kind, - }, - len: 0, - })); - } - - pub fn close(&mut self, close_span: Span) { - let last_unclosed_index = self - .unclosed_subtree_indices - .pop() - .expect("attempt to close a `tt::Subtree` when none is open"); - let subtree_len = (self.token_trees.len() - last_unclosed_index - 1) as u32; - let TokenTree::Subtree(subtree) = &mut self.token_trees[last_unclosed_index] else { - unreachable!("unclosed token tree is always a subtree"); - }; - subtree.len = subtree_len; - subtree.delimiter.close = close_span; - self.last_closed_subtree = Some(last_unclosed_index); - } - - /// You cannot call this consecutively, it will only work once after close. - pub fn remove_last_subtree_if_invisible(&mut self) { - let Some(last_subtree_idx) = self.last_closed_subtree else { return }; - if let TokenTree::Subtree(Subtree { - delimiter: Delimiter { kind: DelimiterKind::Invisible, .. }, - .. - }) = self.token_trees[last_subtree_idx] - { - self.token_trees.remove(last_subtree_idx); - self.last_closed_subtree = None; - } - } - - pub fn push(&mut self, leaf: Leaf) { - self.token_trees.push(TokenTree::Leaf(leaf)); - } - - pub fn extend(&mut self, leaves: impl IntoIterator) { - self.token_trees.extend(leaves.into_iter().map(TokenTree::Leaf)); - } - - pub fn extend_with_tt(&mut self, tt: TokenTreesView<'_>) { - self.token_trees.extend(tt.0.iter().cloned()); - } - - /// Like [`Self::extend_with_tt()`], but makes sure the new tokens will never be - /// joint with whatever comes after them. - pub fn extend_with_tt_alone(&mut self, tt: TokenTreesView<'_>) { - if let Some((last, before_last)) = tt.0.split_last() { - self.token_trees.reserve(tt.0.len()); - self.token_trees.extend(before_last.iter().cloned()); - let last = if let TokenTree::Leaf(Leaf::Punct(last)) = last { - let mut last = *last; - last.spacing = Spacing::Alone; - TokenTree::Leaf(Leaf::Punct(last)) - } else { - last.clone() - }; - self.token_trees.push(last); - } - } - - pub fn expected_delimiters(&self) -> impl Iterator { - self.unclosed_subtree_indices.iter().rev().map(|&subtree_idx| { - let TokenTree::Subtree(subtree) = &self.token_trees[subtree_idx] else { - unreachable!("unclosed token tree is always a subtree") - }; - subtree.delimiter.kind }) } - - /// Builds, and remove the top subtree if it has only one subtree child. - pub fn build_skip_top_subtree(mut self) -> TopSubtree { - let top_tts = TokenTreesView::new(&self.token_trees[1..]); - match top_tts.try_into_subtree() { - Some(_) => { - assert!( - self.unclosed_subtree_indices.is_empty(), - "attempt to build an unbalanced `TopSubtreeBuilder`" - ); - TopSubtree(self.token_trees.drain(1..).collect()) - } - None => self.build(), - } - } - - pub fn build(mut self) -> TopSubtree { - assert!( - self.unclosed_subtree_indices.is_empty(), - "attempt to build an unbalanced `TopSubtreeBuilder`" - ); - let total_len = self.token_trees.len() as u32; - let TokenTree::Subtree(top_subtree) = &mut self.token_trees[0] else { - unreachable!("first token tree is always a subtree"); - }; - top_subtree.len = total_len - 1; - TopSubtree(self.token_trees.into_boxed_slice()) - } - - pub fn restore_point(&self) -> SubtreeBuilderRestorePoint { - SubtreeBuilderRestorePoint { - unclosed_subtree_indices_len: self.unclosed_subtree_indices.len(), - token_trees_len: self.token_trees.len(), - last_closed_subtree: self.last_closed_subtree, - } - } - - pub fn restore(&mut self, restore_point: SubtreeBuilderRestorePoint) { - self.unclosed_subtree_indices.truncate(restore_point.unclosed_subtree_indices_len); - self.token_trees.truncate(restore_point.token_trees_len); - self.last_closed_subtree = restore_point.last_closed_subtree; - } } #[derive(Clone, Copy)] -pub struct SubtreeBuilderRestorePoint { - unclosed_subtree_indices_len: usize, - token_trees_len: usize, - last_closed_subtree: Option, +pub struct TokenTreesView<'a> { + repr: TokenTreesReprRef<'a>, + span_parts: &'a [CompressedSpanPart], } -#[derive(Clone, Copy)] -pub struct TokenTreesView<'a>(&'a [TokenTree]); - impl<'a> TokenTreesView<'a> { - fn new(tts: &'a [TokenTree]) -> Self { - if cfg!(debug_assertions) { - tts.iter().enumerate().for_each(|(idx, tt)| { - if let TokenTree::Subtree(tt) = &tt { - // `<` and not `<=` because `Subtree.len` does not include the subtree node itself. - debug_assert!( - idx + tt.usize_len() < tts.len(), - "`TokenTreeView::new()` was given a cut-in-half list" - ); - } - }); - } - Self(tts) - } - pub fn empty() -> Self { - Self(&[]) + Self { repr: TokenTreesReprRef::SpanStorage32(&[]), span_parts: &[] } } pub fn iter(&self) -> TtIter<'a> { - TtIter::new(self.0) + TtIter::new(*self) } pub fn cursor(&self) -> Cursor<'a> { @@ -393,20 +201,23 @@ impl<'a> TokenTreesView<'a> { } pub fn len(&self) -> usize { - self.0.len() + dispatch_ref! { + match self.repr => tt => tt.len() + } } pub fn is_empty(&self) -> bool { - self.0.is_empty() + self.len() == 0 } pub fn try_into_subtree(self) -> Option> { - if let Some(TokenTree::Subtree(subtree)) = self.0.first() - && subtree.usize_len() == (self.0.len() - 1) - { - return Some(SubtreeView::new(self.0)); - } - None + let is_subtree = dispatch_ref! { + match self.repr => tt => matches!( + tt.first(), + Some(crate::storage::TokenTree::Subtree { len, .. }) if (*len as usize) == (tt.len() - 1) + ) + }; + if is_subtree { Some(SubtreeView(self)) } else { None } } pub fn strip_invisible(self) -> TokenTreesView<'a> { @@ -440,18 +251,23 @@ impl<'a> TokenTreesView<'a> { } pub fn first_span(&self) -> Option { - Some(self.0.first()?.first_span()) - } - - pub fn last_span(&self) -> Option { - Some(match self.0.last()? { - TokenTree::Leaf(it) => *it.span(), - TokenTree::Subtree(it) => it.delimiter.close, + Some(dispatch_ref! { + match self.repr => tt => tt.first()?.first_span().span(self.span_parts) }) } - pub fn iter_flat_tokens(&self) -> impl ExactSizeIterator + use<'a> { - self.0.iter().cloned() + pub fn last_span(&self) -> Option { + Some(dispatch_ref! { + match self.repr => tt => tt.last()?.last_span().span(self.span_parts) + }) + } + + pub fn iter_flat_tokens(self) -> impl ExactSizeIterator + use<'a> { + (0..self.len()).map(move |idx| { + dispatch_ref! { + match self.repr => tt => tt[idx].to_api(self.span_parts) + } + }) } } @@ -515,60 +331,70 @@ impl fmt::Display for TokenTreesView<'_> { #[derive(Clone, Copy)] // Invariant: always starts with `Subtree` that covers the entire thing. -pub struct SubtreeView<'a>(&'a [TokenTree]); +pub struct SubtreeView<'a>(TokenTreesView<'a>); impl<'a> SubtreeView<'a> { - pub fn new(tts: &'a [TokenTree]) -> Self { - if cfg!(debug_assertions) { - let TokenTree::Subtree(subtree) = &tts[0] else { - panic!("first token tree must be a subtree in `SubtreeView`"); - }; - assert_eq!( - subtree.usize_len(), - tts.len() - 1, - "subtree must cover the entire `SubtreeView`" - ); - } - Self(tts) - } - pub fn as_token_trees(self) -> TokenTreesView<'a> { - TokenTreesView::new(self.0) + self.0 } pub fn iter(&self) -> TtIter<'a> { - TtIter::new(&self.0[1..]) + self.token_trees().iter() } pub fn top_subtree(&self) -> Subtree { - let TokenTree::Subtree(subtree) = &self.0[0] else { - unreachable!("the first token tree is always the top subtree"); - }; - *subtree + dispatch_ref! { + match self.0.repr => tt => { + let crate::storage::TokenTree::Subtree { len, delim_kind, open_span, close_span } = + &tt[0] + else { + unreachable!("the first token tree is always the top subtree"); + }; + Subtree { + delimiter: Delimiter { + open: open_span.span(self.0.span_parts), + close: close_span.span(self.0.span_parts), + kind: *delim_kind, + }, + len: *len, + } + } + } } pub fn strip_invisible(&self) -> TokenTreesView<'a> { if self.top_subtree().delimiter.kind == DelimiterKind::Invisible { - TokenTreesView::new(&self.0[1..]) + self.token_trees() } else { - TokenTreesView::new(self.0) + self.0 } } pub fn token_trees(&self) -> TokenTreesView<'a> { - TokenTreesView::new(&self.0[1..]) + let repr = match self.0.repr { + TokenTreesReprRef::SpanStorage32(token_trees) => { + TokenTreesReprRef::SpanStorage32(&token_trees[1..]) + } + TokenTreesReprRef::SpanStorage64(token_trees) => { + TokenTreesReprRef::SpanStorage64(&token_trees[1..]) + } + TokenTreesReprRef::SpanStorage96(token_trees) => { + TokenTreesReprRef::SpanStorage96(&token_trees[1..]) + } + }; + TokenTreesView { repr, ..self.0 } } } impl fmt::Debug for SubtreeView<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&TokenTreesView(self.0), f) + fmt::Debug::fmt(&self.0, f) } } impl fmt::Display for SubtreeView<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&TokenTreesView(self.0), f) + fmt::Display::fmt(&self.0, f) } } @@ -937,91 +763,40 @@ impl Subtree { } } -impl TopSubtree { - /// A simple line string used for debugging - pub fn subtree_as_debug_string(&self, subtree_idx: usize) -> String { - fn debug_subtree( - output: &mut String, - subtree: &Subtree, - iter: &mut std::slice::Iter<'_, TokenTree>, - ) { - let delim = match subtree.delimiter.kind { - DelimiterKind::Brace => ("{", "}"), - DelimiterKind::Bracket => ("[", "]"), - DelimiterKind::Parenthesis => ("(", ")"), - DelimiterKind::Invisible => ("$", "$"), - }; - - output.push_str(delim.0); - let mut last = None; - let mut idx = 0; - while idx < subtree.len { - let child = iter.next().unwrap(); - debug_token_tree(output, child, last, iter); - last = Some(child); - idx += 1; - } - - output.push_str(delim.1); - } - - fn debug_token_tree( - output: &mut String, - tt: &TokenTree, - last: Option<&TokenTree>, - iter: &mut std::slice::Iter<'_, TokenTree>, - ) { - match tt { - TokenTree::Leaf(it) => { - let s = match it { - Leaf::Literal(it) => it.text().to_owned(), - Leaf::Punct(it) => it.char.to_string(), - Leaf::Ident(it) => format!("{}{}", it.is_raw.as_str(), it.sym), - }; - match (it, last) { - (Leaf::Ident(_), Some(&TokenTree::Leaf(Leaf::Ident(_)))) => { - output.push(' '); - output.push_str(&s); - } - (Leaf::Punct(_), Some(TokenTree::Leaf(Leaf::Punct(punct)))) => { - if punct.spacing == Spacing::Alone { - output.push(' '); - output.push_str(&s); - } else { - output.push_str(&s); - } - } - _ => output.push_str(&s), - } - } - TokenTree::Subtree(it) => debug_subtree(output, it, iter), - } - } - - let mut res = String::new(); - debug_token_tree( - &mut res, - &self.0[subtree_idx], - None, - &mut self.0[subtree_idx + 1..].iter(), - ); - res - } -} - pub fn pretty(tkns: TokenTreesView<'_>) -> String { - fn tokentree_to_text(tkn: &TokenTree, tkns: &mut &[TokenTree]) -> String { + return dispatch_ref! { + match tkns.repr => tt => pretty_impl(tt) + }; + + use crate::storage::TokenTree; + + fn tokentree_to_text(tkn: &TokenTree, tkns: &mut &[TokenTree]) -> String { match tkn { - TokenTree::Leaf(Leaf::Ident(ident)) => { - format!("{}{}", ident.is_raw.as_str(), ident.sym) + TokenTree::Ident { sym, is_raw, .. } => format!("{}{}", is_raw.as_str(), sym), + &TokenTree::Literal { ref text_and_suffix, kind, suffix_len, span: _ } => { + format!( + "{}", + Literal { + text_and_suffix: text_and_suffix.clone(), + span: Span { + range: TextRange::empty(TextSize::new(0)), + anchor: span::SpanAnchor { + file_id: span::EditionedFileId::from_raw(0), + ast_id: span::FIXUP_ERASED_FILE_AST_ID_MARKER + }, + ctx: span::SyntaxContext::root(span::Edition::Edition2015) + }, + kind, + suffix_len + } + ) } - TokenTree::Leaf(Leaf::Literal(literal)) => format!("{literal}"), - TokenTree::Leaf(Leaf::Punct(punct)) => format!("{}", punct.char), - TokenTree::Subtree(subtree) => { - let (subtree_content, rest) = tkns.split_at(subtree.usize_len()); - let content = pretty(TokenTreesView(subtree_content)); + TokenTree::Punct { char, .. } => format!("{}", char), + TokenTree::Subtree { len, delim_kind, .. } => { + let (subtree_content, rest) = tkns.split_at(*len as usize); + let content = pretty_impl(subtree_content); *tkns = rest; - let (open, close) = match subtree.delimiter.kind { + let (open, close) = match *delim_kind { DelimiterKind::Brace => ("{", "}"), DelimiterKind::Bracket => ("[", "]"), DelimiterKind::Parenthesis => ("(", ")"), @@ -1032,21 +807,26 @@ pub fn pretty(tkns: TokenTreesView<'_>) -> String { } } - let mut tkns = tkns.0; - let mut last = String::new(); - let mut last_to_joint = true; + fn pretty_impl(mut tkns: &[TokenTree]) -> String { + let mut last = String::new(); + let mut last_to_joint = true; - while let Some((tkn, rest)) = tkns.split_first() { - tkns = rest; - last = [last, tokentree_to_text(tkn, &mut tkns)].join(if last_to_joint { "" } else { " " }); - last_to_joint = false; - if let TokenTree::Leaf(Leaf::Punct(punct)) = tkn - && punct.spacing == Spacing::Joint - { - last_to_joint = true; + while let Some((tkn, rest)) = tkns.split_first() { + tkns = rest; + last = [last, tokentree_to_text(tkn, &mut tkns)].join(if last_to_joint { + "" + } else { + " " + }); + last_to_joint = false; + if let TokenTree::Punct { spacing, .. } = tkn + && *spacing == Spacing::Joint + { + last_to_joint = true; + } } + last } - last } #[derive(Debug)] @@ -1069,7 +849,7 @@ pub fn transform_tt<'b>( tt: &mut TopSubtree, mut callback: impl FnMut(TokenTree) -> TransformTtAction<'b>, ) { - let mut tt_vec = std::mem::take(&mut tt.0).into_vec(); + let mut tt_vec = tt.as_token_trees().iter_flat_tokens().collect::>(); // We need to keep a stack of the currently open subtrees, because we need to update // them if we change the number of items in them. @@ -1112,7 +892,7 @@ pub fn transform_tt<'b>( TokenTree::Subtree(subtree) => subtree.usize_len(), }; let len_diff = replacement.len() as i64 - old_len as i64; - tt_vec.splice(i..i + old_len, replacement.0.iter().cloned()); + tt_vec.splice(i..i + old_len, replacement.iter_flat_tokens()); // Skip the newly inserted replacement, we don't want to visit it. i += replacement.len(); @@ -1126,5 +906,5 @@ pub fn transform_tt<'b>( } } - tt.0 = tt_vec.into_boxed_slice(); + *tt = TopSubtree::from_serialized(tt_vec); } diff --git a/src/tools/rust-analyzer/crates/tt/src/storage.rs b/src/tools/rust-analyzer/crates/tt/src/storage.rs new file mode 100644 index 000000000000..62d2e20016ac --- /dev/null +++ b/src/tools/rust-analyzer/crates/tt/src/storage.rs @@ -0,0 +1,992 @@ +//! Spans are memory heavy, and we have a lot of token trees. Storing them straight +//! will waste a lot of memory. So instead we implement a clever compression mechanism: +//! +//! A `TopSubtree` has a list of [`CompressedSpanPart`], which are the parts of a span +//! that tend to be shared between tokens - namely, without the range. The main list +//! of token trees is kept in one of three versions, where we use the smallest version +//! we can for this tree: +//! +//! 1. In the most common version a span is just a `u32`. The bits are divided as follows: +//! there are 4 bits that index into the [`CompressedSpanPart`] list. 20 bits +//! store the range start, and 8 bits store the range length. In experiments, +//! this accounts for 75%-85% of the spans. +//! 2. In the second version a span is 64 bits. 32 bits for the range start, 16 bits +//! for the range length, and 16 bits for the span parts index. This is used in +//! less than 2% of all `TopSubtree`s, but they account for 15%-25% of the spans: +//! those are mostly token tree munchers, that generate a lot of `SyntaxContext`s +//! (because they recurse a lot), which is why they can't fit in the first version, +//! and tend to generate a lot of code. +//! 3. The third version is practically unused; 65,535 bytes for a token and 65,535 +//! unique span parts is more than enough for everybody. However, someone may still +//! create a macro that requires more, therefore we have this version as a backup: +//! it uses 96 bits, 32 for each of the range start, length and span parts index. + +use std::fmt; + +use intern::Symbol; +use rustc_hash::FxBuildHasher; +use span::{Span, SpanAnchor, SyntaxContext, TextRange, TextSize}; + +use crate::{ + DelimSpan, DelimiterKind, IdentIsRaw, LitKind, Spacing, SubtreeView, TokenTreesReprRef, + TokenTreesView, TtIter, dispatch_ref, +}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct CompressedSpanPart { + pub(crate) anchor: SpanAnchor, + pub(crate) ctx: SyntaxContext, +} + +impl CompressedSpanPart { + #[inline] + fn from_span(span: &Span) -> Self { + Self { anchor: span.anchor, ctx: span.ctx } + } + + #[inline] + fn recombine(&self, range: TextRange) -> Span { + Span { range, anchor: self.anchor, ctx: self.ctx } + } +} + +pub(crate) trait SpanStorage: Copy { + fn can_hold(text_range: TextRange, span_parts_index: usize) -> bool; + + fn new(text_range: TextRange, span_parts_index: usize) -> Self; + + fn text_range(&self) -> TextRange; + + fn span_parts_index(&self) -> usize; + + #[inline] + fn span(&self, span_parts: &[CompressedSpanPart]) -> Span { + span_parts[self.span_parts_index()].recombine(self.text_range()) + } +} + +#[inline] +const fn n_bits_mask(n: u32) -> u32 { + (1 << n) - 1 +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct SpanStorage32(u32); + +impl SpanStorage32 { + const SPAN_PARTS_BIT: u32 = 4; + const LEN_BITS: u32 = 8; + const OFFSET_BITS: u32 = 20; +} + +const _: () = assert!( + (SpanStorage32::SPAN_PARTS_BIT + SpanStorage32::LEN_BITS + SpanStorage32::OFFSET_BITS) + == u32::BITS +); + +impl SpanStorage for SpanStorage32 { + #[inline] + fn can_hold(text_range: TextRange, span_parts_index: usize) -> bool { + let offset = u32::from(text_range.start()); + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + offset <= n_bits_mask(Self::OFFSET_BITS) + && len <= n_bits_mask(Self::LEN_BITS) + && span_parts_index <= n_bits_mask(Self::SPAN_PARTS_BIT) + } + + #[inline] + fn new(text_range: TextRange, span_parts_index: usize) -> Self { + let offset = u32::from(text_range.start()); + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + debug_assert!(offset <= n_bits_mask(Self::OFFSET_BITS)); + debug_assert!(len <= n_bits_mask(Self::LEN_BITS)); + debug_assert!(span_parts_index <= n_bits_mask(Self::SPAN_PARTS_BIT)); + + Self( + (offset << (Self::LEN_BITS + Self::SPAN_PARTS_BIT)) + | (len << Self::SPAN_PARTS_BIT) + | span_parts_index, + ) + } + + #[inline] + fn text_range(&self) -> TextRange { + let offset = TextSize::new(self.0 >> (Self::SPAN_PARTS_BIT + Self::LEN_BITS)); + let len = TextSize::new((self.0 >> Self::SPAN_PARTS_BIT) & n_bits_mask(Self::LEN_BITS)); + TextRange::at(offset, len) + } + + #[inline] + fn span_parts_index(&self) -> usize { + (self.0 & n_bits_mask(Self::SPAN_PARTS_BIT)) as usize + } +} + +impl fmt::Debug for SpanStorage32 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SpanStorage32") + .field("text_range", &self.text_range()) + .field("span_parts_index", &self.span_parts_index()) + .finish() + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct SpanStorage64 { + offset: u32, + len_and_parts: u32, +} + +impl SpanStorage64 { + const SPAN_PARTS_BIT: u32 = 16; + const LEN_BITS: u32 = 16; +} + +const _: () = assert!((SpanStorage64::SPAN_PARTS_BIT + SpanStorage64::LEN_BITS) == u32::BITS); + +impl SpanStorage for SpanStorage64 { + #[inline] + fn can_hold(text_range: TextRange, span_parts_index: usize) -> bool { + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + len <= n_bits_mask(Self::LEN_BITS) && span_parts_index <= n_bits_mask(Self::SPAN_PARTS_BIT) + } + + #[inline] + fn new(text_range: TextRange, span_parts_index: usize) -> Self { + let offset = u32::from(text_range.start()); + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + debug_assert!(len <= n_bits_mask(Self::LEN_BITS)); + debug_assert!(span_parts_index <= n_bits_mask(Self::SPAN_PARTS_BIT)); + + Self { offset, len_and_parts: (len << Self::SPAN_PARTS_BIT) | span_parts_index } + } + + #[inline] + fn text_range(&self) -> TextRange { + let offset = TextSize::new(self.offset); + let len = TextSize::new(self.len_and_parts >> Self::SPAN_PARTS_BIT); + TextRange::at(offset, len) + } + + #[inline] + fn span_parts_index(&self) -> usize { + (self.len_and_parts & n_bits_mask(Self::SPAN_PARTS_BIT)) as usize + } +} + +impl fmt::Debug for SpanStorage64 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SpanStorage64") + .field("text_range", &self.text_range()) + .field("span_parts_index", &self.span_parts_index()) + .finish() + } +} + +impl From for SpanStorage64 { + #[inline] + fn from(value: SpanStorage32) -> Self { + SpanStorage64::new(value.text_range(), value.span_parts_index()) + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct SpanStorage96 { + offset: u32, + len: u32, + parts: u32, +} + +impl SpanStorage for SpanStorage96 { + #[inline] + fn can_hold(_text_range: TextRange, _span_parts_index: usize) -> bool { + true + } + + #[inline] + fn new(text_range: TextRange, span_parts_index: usize) -> Self { + let offset = u32::from(text_range.start()); + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + Self { offset, len, parts: span_parts_index } + } + + #[inline] + fn text_range(&self) -> TextRange { + let offset = TextSize::new(self.offset); + let len = TextSize::new(self.len); + TextRange::at(offset, len) + } + + #[inline] + fn span_parts_index(&self) -> usize { + self.parts as usize + } +} + +impl fmt::Debug for SpanStorage96 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SpanStorage96") + .field("text_range", &self.text_range()) + .field("span_parts_index", &self.span_parts_index()) + .finish() + } +} + +impl From for SpanStorage96 { + #[inline] + fn from(value: SpanStorage32) -> Self { + SpanStorage96::new(value.text_range(), value.span_parts_index()) + } +} + +impl From for SpanStorage96 { + #[inline] + fn from(value: SpanStorage64) -> Self { + SpanStorage96::new(value.text_range(), value.span_parts_index()) + } +} + +// We don't use structs or enum nesting here to save padding. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) enum TokenTree { + Literal { text_and_suffix: Symbol, span: S, kind: LitKind, suffix_len: u8 }, + Punct { char: char, spacing: Spacing, span: S }, + Ident { sym: Symbol, span: S, is_raw: IdentIsRaw }, + Subtree { len: u32, delim_kind: DelimiterKind, open_span: S, close_span: S }, +} + +impl TokenTree { + #[inline] + pub(crate) fn first_span(&self) -> &S { + match self { + TokenTree::Literal { span, .. } => span, + TokenTree::Punct { span, .. } => span, + TokenTree::Ident { span, .. } => span, + TokenTree::Subtree { open_span, .. } => open_span, + } + } + + #[inline] + pub(crate) fn last_span(&self) -> &S { + match self { + TokenTree::Literal { span, .. } => span, + TokenTree::Punct { span, .. } => span, + TokenTree::Ident { span, .. } => span, + TokenTree::Subtree { close_span, .. } => close_span, + } + } + + #[inline] + pub(crate) fn to_api(&self, span_parts: &[CompressedSpanPart]) -> crate::TokenTree { + match self { + TokenTree::Literal { text_and_suffix, span, kind, suffix_len } => { + crate::TokenTree::Leaf(crate::Leaf::Literal(crate::Literal { + text_and_suffix: text_and_suffix.clone(), + span: span.span(span_parts), + kind: *kind, + suffix_len: *suffix_len, + })) + } + TokenTree::Punct { char, spacing, span } => { + crate::TokenTree::Leaf(crate::Leaf::Punct(crate::Punct { + char: *char, + spacing: *spacing, + span: span.span(span_parts), + })) + } + TokenTree::Ident { sym, span, is_raw } => { + crate::TokenTree::Leaf(crate::Leaf::Ident(crate::Ident { + sym: sym.clone(), + span: span.span(span_parts), + is_raw: *is_raw, + })) + } + TokenTree::Subtree { len, delim_kind, open_span, close_span } => { + crate::TokenTree::Subtree(crate::Subtree { + delimiter: crate::Delimiter { + open: open_span.span(span_parts), + close: close_span.span(span_parts), + kind: *delim_kind, + }, + len: *len, + }) + } + } + } + + #[inline] + fn convert>(self) -> TokenTree { + match self { + TokenTree::Literal { text_and_suffix, span, kind, suffix_len } => { + TokenTree::Literal { text_and_suffix, span: span.into(), kind, suffix_len } + } + TokenTree::Punct { char, spacing, span } => { + TokenTree::Punct { char, spacing, span: span.into() } + } + TokenTree::Ident { sym, span, is_raw } => { + TokenTree::Ident { sym, span: span.into(), is_raw } + } + TokenTree::Subtree { len, delim_kind, open_span, close_span } => TokenTree::Subtree { + len, + delim_kind, + open_span: open_span.into(), + close_span: close_span.into(), + }, + } + } +} + +// This is used a lot, make sure it doesn't grow unintentionally. +const _: () = { + assert!(size_of::>() == 16); + assert!(size_of::>() == 24); + assert!(size_of::>() == 32); +}; + +/// `dispatch! {}` +macro_rules! dispatch { + ( + match $scrutinee:expr => $tt:ident => $body:expr + ) => { + match $scrutinee { + TopSubtreeRepr::SpanStorage32($tt) => $body, + TopSubtreeRepr::SpanStorage64($tt) => $body, + TopSubtreeRepr::SpanStorage96($tt) => $body, + } + }; +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) enum TopSubtreeRepr { + SpanStorage32(Box<[TokenTree]>), + SpanStorage64(Box<[TokenTree]>), + SpanStorage96(Box<[TokenTree]>), +} + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct TopSubtree { + repr: TopSubtreeRepr, + span_parts: Box<[CompressedSpanPart]>, +} + +impl TopSubtree { + pub fn empty(span: DelimSpan) -> Self { + Self { + repr: TopSubtreeRepr::SpanStorage96(Box::new([TokenTree::Subtree { + len: 0, + delim_kind: DelimiterKind::Invisible, + open_span: SpanStorage96::new(span.open.range, 0), + close_span: SpanStorage96::new(span.close.range, 1), + }])), + span_parts: Box::new([ + CompressedSpanPart::from_span(&span.open), + CompressedSpanPart::from_span(&span.close), + ]), + } + } + + pub fn invisible_from_leaves( + delim_span: Span, + leaves: [crate::Leaf; N], + ) -> Self { + let mut builder = TopSubtreeBuilder::new(crate::Delimiter::invisible_spanned(delim_span)); + builder.extend(leaves); + builder.build() + } + + pub fn from_token_trees(delimiter: crate::Delimiter, token_trees: TokenTreesView<'_>) -> Self { + let mut builder = TopSubtreeBuilder::new(delimiter); + builder.extend_with_tt(token_trees); + builder.build() + } + + pub fn from_serialized(tt: Vec) -> Self { + let mut tt = tt.into_iter(); + let Some(crate::TokenTree::Subtree(top_subtree)) = tt.next() else { + panic!("first must always come the top subtree") + }; + let mut builder = TopSubtreeBuilder::new(top_subtree.delimiter); + for tt in tt { + builder.push_token_tree(tt); + } + builder.build() + } + + pub fn from_subtree(subtree: SubtreeView<'_>) -> Self { + let mut builder = TopSubtreeBuilder::new(subtree.top_subtree().delimiter); + builder.extend_with_tt(subtree.token_trees()); + builder.build() + } + + pub fn view(&self) -> SubtreeView<'_> { + let repr = match &self.repr { + TopSubtreeRepr::SpanStorage32(token_trees) => { + TokenTreesReprRef::SpanStorage32(token_trees) + } + TopSubtreeRepr::SpanStorage64(token_trees) => { + TokenTreesReprRef::SpanStorage64(token_trees) + } + TopSubtreeRepr::SpanStorage96(token_trees) => { + TokenTreesReprRef::SpanStorage96(token_trees) + } + }; + SubtreeView(TokenTreesView { repr, span_parts: &self.span_parts }) + } + + pub fn iter(&self) -> TtIter<'_> { + self.view().iter() + } + + pub fn top_subtree(&self) -> crate::Subtree { + self.view().top_subtree() + } + + pub fn set_top_subtree_delimiter_kind(&mut self, kind: DelimiterKind) { + dispatch! { + match &mut self.repr => tt => { + let TokenTree::Subtree { delim_kind, .. } = &mut tt[0] else { + unreachable!("the first token tree is always the top subtree"); + }; + *delim_kind = kind; + } + } + } + + fn ensure_can_hold(&mut self, range: TextRange) { + fn can_hold(_: &[TokenTree], range: TextRange) -> bool { + S::can_hold(range, 0) + } + let can_hold = dispatch! { + match &self.repr => tt => can_hold(tt, range) + }; + if can_hold { + return; + } + + // Otherwise, we do something very junky: recreate the entire tree. Hopefully this should be rare. + let mut builder = TopSubtreeBuilder::new(self.top_subtree().delimiter); + builder.extend_with_tt(self.token_trees()); + builder.ensure_can_hold(range, 0); + *self = builder.build(); + } + + pub fn set_top_subtree_delimiter_span(&mut self, span: DelimSpan) { + self.ensure_can_hold(span.open.range); + self.ensure_can_hold(span.close.range); + fn do_it(tt: &mut [TokenTree], span: DelimSpan) { + let TokenTree::Subtree { open_span, close_span, .. } = &mut tt[0] else { + unreachable!() + }; + *open_span = S::new(span.open.range, 0); + *close_span = S::new(span.close.range, 0); + } + dispatch! { + match &mut self.repr => tt => do_it(tt, span) + } + self.span_parts[0] = CompressedSpanPart::from_span(&span.open); + self.span_parts[1] = CompressedSpanPart::from_span(&span.close); + } + + /// Note: this cannot change spans. + pub fn set_token(&mut self, idx: usize, leaf: crate::Leaf) { + fn do_it( + tt: &mut [TokenTree], + idx: usize, + span_parts: &[CompressedSpanPart], + leaf: crate::Leaf, + ) { + assert!( + !matches!(tt[idx], TokenTree::Subtree { .. }), + "`TopSubtree::set_token()` must be called on a leaf" + ); + let existing_span_compressed = *tt[idx].first_span(); + let existing_span = existing_span_compressed.span(span_parts); + assert_eq!( + *leaf.span(), + existing_span, + "`TopSubtree::set_token()` cannot change spans" + ); + match leaf { + crate::Leaf::Literal(leaf) => { + tt[idx] = TokenTree::Literal { + text_and_suffix: leaf.text_and_suffix, + span: existing_span_compressed, + kind: leaf.kind, + suffix_len: leaf.suffix_len, + } + } + crate::Leaf::Punct(leaf) => { + tt[idx] = TokenTree::Punct { + char: leaf.char, + spacing: leaf.spacing, + span: existing_span_compressed, + } + } + crate::Leaf::Ident(leaf) => { + tt[idx] = TokenTree::Ident { + sym: leaf.sym, + span: existing_span_compressed, + is_raw: leaf.is_raw, + } + } + } + } + dispatch! { + match &mut self.repr => tt => do_it(tt, idx, &self.span_parts, leaf) + } + } + + pub fn token_trees(&self) -> TokenTreesView<'_> { + self.view().token_trees() + } + + pub fn as_token_trees(&self) -> TokenTreesView<'_> { + self.view().as_token_trees() + } + + pub fn change_every_ast_id(&mut self, mut callback: impl FnMut(&mut span::ErasedFileAstId)) { + for span_part in &mut self.span_parts { + callback(&mut span_part.anchor.ast_id); + } + } +} + +/// `dispatch_builder! {}` +macro_rules! dispatch_builder { + ( + match $scrutinee:expr => $tt:ident => $body:expr + ) => { + match $scrutinee { + TopSubtreeBuilderRepr::SpanStorage32($tt) => $body, + TopSubtreeBuilderRepr::SpanStorage64($tt) => $body, + TopSubtreeBuilderRepr::SpanStorage96($tt) => $body, + } + }; +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +enum TopSubtreeBuilderRepr { + SpanStorage32(Vec>), + SpanStorage64(Vec>), + SpanStorage96(Vec>), +} + +type FxIndexSet = indexmap::IndexSet; + +/// In any tree, the first two subtree parts are reserved for the top subtree. +/// +/// We do it because `TopSubtree` exposes an API to modify the top subtree, therefore it's more convenient +/// this way, and it's unlikely to affect memory usage. +const RESERVED_SPAN_PARTS_LEN: usize = 2; + +#[derive(Debug, Clone)] +pub struct TopSubtreeBuilder { + unclosed_subtree_indices: Vec, + token_trees: TopSubtreeBuilderRepr, + span_parts: FxIndexSet, + last_closed_subtree: Option, + /// We need to keep those because they are not inside `span_parts`, see [`RESERVED_SPAN_PARTS_LEN`]. + top_subtree_spans: DelimSpan, +} + +impl TopSubtreeBuilder { + pub fn new(top_delimiter: crate::Delimiter) -> Self { + let mut result = Self { + unclosed_subtree_indices: Vec::new(), + token_trees: TopSubtreeBuilderRepr::SpanStorage32(Vec::new()), + span_parts: FxIndexSet::default(), + last_closed_subtree: None, + top_subtree_spans: top_delimiter.delim_span(), + }; + result.ensure_can_hold(top_delimiter.open.range, 0); + result.ensure_can_hold(top_delimiter.close.range, 1); + fn push_first(tt: &mut Vec>, top_delimiter: crate::Delimiter) { + tt.push(TokenTree::Subtree { + len: 0, + delim_kind: top_delimiter.kind, + open_span: S::new(top_delimiter.open.range, 0), + close_span: S::new(top_delimiter.close.range, 1), + }); + } + dispatch_builder! { + match &mut result.token_trees => tt => push_first(tt, top_delimiter) + } + result + } + + fn span_part_index(&mut self, part: CompressedSpanPart) -> usize { + self.span_parts.insert_full(part).0 + RESERVED_SPAN_PARTS_LEN + } + + fn switch_repr>(repr: &mut Vec>) -> Vec> { + let repr = std::mem::take(repr); + repr.into_iter().map(|tt| tt.convert()).collect() + } + + /// Ensures we have a representation that can hold these values. + fn ensure_can_hold(&mut self, text_range: TextRange, span_parts_index: usize) { + match &mut self.token_trees { + TopSubtreeBuilderRepr::SpanStorage32(token_trees) => { + if SpanStorage32::can_hold(text_range, span_parts_index) { + // Can hold. + } else if SpanStorage64::can_hold(text_range, span_parts_index) { + self.token_trees = + TopSubtreeBuilderRepr::SpanStorage64(Self::switch_repr(token_trees)); + } else { + self.token_trees = + TopSubtreeBuilderRepr::SpanStorage96(Self::switch_repr(token_trees)); + } + } + TopSubtreeBuilderRepr::SpanStorage64(token_trees) => { + if SpanStorage64::can_hold(text_range, span_parts_index) { + // Can hold. + } else { + self.token_trees = + TopSubtreeBuilderRepr::SpanStorage96(Self::switch_repr(token_trees)); + } + } + TopSubtreeBuilderRepr::SpanStorage96(_) => { + // Can hold anything. + } + } + } + + /// Not to be exposed, this assumes the subtree's children will be filled in immediately. + fn push_subtree(&mut self, subtree: crate::Subtree) { + let open_span_parts_index = + self.span_part_index(CompressedSpanPart::from_span(&subtree.delimiter.open)); + self.ensure_can_hold(subtree.delimiter.open.range, open_span_parts_index); + let close_span_parts_index = + self.span_part_index(CompressedSpanPart::from_span(&subtree.delimiter.close)); + self.ensure_can_hold(subtree.delimiter.close.range, close_span_parts_index); + fn do_it( + tt: &mut Vec>, + open_span_parts_index: usize, + close_span_parts_index: usize, + subtree: crate::Subtree, + ) { + let open_span = S::new(subtree.delimiter.open.range, open_span_parts_index); + let close_span = S::new(subtree.delimiter.close.range, close_span_parts_index); + tt.push(TokenTree::Subtree { + len: subtree.len, + delim_kind: subtree.delimiter.kind, + open_span, + close_span, + }); + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, open_span_parts_index, close_span_parts_index, subtree) + } + } + + pub fn open(&mut self, delimiter_kind: DelimiterKind, open_span: Span) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&open_span)); + self.ensure_can_hold(open_span.range, span_parts_index); + fn do_it( + token_trees: &mut Vec>, + delimiter_kind: DelimiterKind, + range: TextRange, + span_parts_index: usize, + ) -> usize { + let open_span = S::new(range, span_parts_index); + token_trees.push(TokenTree::Subtree { + len: 0, + delim_kind: delimiter_kind, + open_span, + close_span: open_span, // Will be overwritten on close. + }); + token_trees.len() - 1 + } + let subtree_idx = dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, delimiter_kind, open_span.range, span_parts_index) + }; + self.unclosed_subtree_indices.push(subtree_idx); + } + + pub fn close(&mut self, close_span: Span) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&close_span)); + let range = close_span.range; + self.ensure_can_hold(range, span_parts_index); + + let last_unclosed_index = self + .unclosed_subtree_indices + .pop() + .expect("attempt to close a `tt::Subtree` when none is open"); + fn do_it( + token_trees: &mut [TokenTree], + last_unclosed_index: usize, + range: TextRange, + span_parts_index: usize, + ) { + let token_trees_len = token_trees.len(); + let TokenTree::Subtree { len, delim_kind: _, open_span: _, close_span } = + &mut token_trees[last_unclosed_index] + else { + unreachable!("unclosed token tree is always a subtree"); + }; + *len = (token_trees_len - last_unclosed_index - 1) as u32; + *close_span = S::new(range, span_parts_index); + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, last_unclosed_index, range, span_parts_index) + } + self.last_closed_subtree = Some(last_unclosed_index); + } + + /// You cannot call this consecutively, it will only work once after close. + pub fn remove_last_subtree_if_invisible(&mut self) { + let Some(last_subtree_idx) = self.last_closed_subtree else { return }; + fn do_it(tt: &mut Vec>, last_subtree_idx: usize) { + if let TokenTree::Subtree { delim_kind: DelimiterKind::Invisible, .. } = + tt[last_subtree_idx] + { + tt.remove(last_subtree_idx); + } + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, last_subtree_idx) + } + self.last_closed_subtree = None; + } + + fn push_literal(&mut self, leaf: crate::Literal) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&leaf.span)); + let range = leaf.span.range; + self.ensure_can_hold(range, span_parts_index); + fn do_it( + tt: &mut Vec>, + range: TextRange, + span_parts_index: usize, + leaf: crate::Literal, + ) { + tt.push(TokenTree::Literal { + text_and_suffix: leaf.text_and_suffix, + span: S::new(range, span_parts_index), + kind: leaf.kind, + suffix_len: leaf.suffix_len, + }) + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, range, span_parts_index, leaf) + } + } + + fn push_punct(&mut self, leaf: crate::Punct) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&leaf.span)); + let range = leaf.span.range; + self.ensure_can_hold(range, span_parts_index); + fn do_it( + tt: &mut Vec>, + range: TextRange, + span_parts_index: usize, + leaf: crate::Punct, + ) { + tt.push(TokenTree::Punct { + char: leaf.char, + spacing: leaf.spacing, + span: S::new(range, span_parts_index), + }) + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, range, span_parts_index, leaf) + } + } + + fn push_ident(&mut self, leaf: crate::Ident) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&leaf.span)); + let range = leaf.span.range; + self.ensure_can_hold(range, span_parts_index); + fn do_it( + tt: &mut Vec>, + range: TextRange, + span_parts_index: usize, + leaf: crate::Ident, + ) { + tt.push(TokenTree::Ident { + sym: leaf.sym, + span: S::new(range, span_parts_index), + is_raw: leaf.is_raw, + }) + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, range, span_parts_index, leaf) + } + } + + pub fn push(&mut self, leaf: crate::Leaf) { + match leaf { + crate::Leaf::Literal(leaf) => self.push_literal(leaf), + crate::Leaf::Punct(leaf) => self.push_punct(leaf), + crate::Leaf::Ident(leaf) => self.push_ident(leaf), + } + } + + fn push_token_tree(&mut self, tt: crate::TokenTree) { + match tt { + crate::TokenTree::Leaf(leaf) => self.push(leaf), + crate::TokenTree::Subtree(subtree) => self.push_subtree(subtree), + } + } + + pub fn extend(&mut self, leaves: impl IntoIterator) { + leaves.into_iter().for_each(|leaf| self.push(leaf)); + } + + pub fn extend_with_tt(&mut self, tt: TokenTreesView<'_>) { + fn do_it( + this: &mut TopSubtreeBuilder, + tt: &[TokenTree], + span_parts: &[CompressedSpanPart], + ) { + for tt in tt { + this.push_token_tree(tt.to_api(span_parts)); + } + } + dispatch_ref! { + match tt.repr => tt_repr => do_it(self, tt_repr, tt.span_parts) + } + } + + /// Like [`Self::extend_with_tt()`], but makes sure the new tokens will never be + /// joint with whatever comes after them. + pub fn extend_with_tt_alone(&mut self, tt: TokenTreesView<'_>) { + self.extend_with_tt(tt); + fn do_it(tt: &mut [TokenTree]) { + if let Some(TokenTree::Punct { spacing, .. }) = tt.last_mut() { + *spacing = Spacing::Alone; + } + } + if !tt.is_empty() { + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt) + } + } + } + + pub fn expected_delimiters(&self) -> impl Iterator { + self.unclosed_subtree_indices.iter().rev().map(|&subtree_idx| { + dispatch_builder! { + match &self.token_trees => tt => { + let TokenTree::Subtree { delim_kind, .. } = tt[subtree_idx] else { + unreachable!("unclosed token tree is always a subtree") + }; + delim_kind + } + } + }) + } + + /// Builds, and remove the top subtree if it has only one subtree child. + pub fn build_skip_top_subtree(mut self) -> TopSubtree { + fn remove_first_if_needed( + tt: &mut Vec>, + top_delim_span: &mut DelimSpan, + span_parts: &FxIndexSet, + ) { + let tt_len = tt.len(); + let Some(TokenTree::Subtree { len, open_span, close_span, .. }) = tt.get_mut(1) else { + return; + }; + if (*len as usize) != (tt_len - 2) { + // Subtree does not cover the whole tree (minus 2; itself, and the top span). + return; + } + + // Now we need to adjust the spans, because we assume that the first two spans are always reserved. + let top_open_span = span_parts + .get_index(open_span.span_parts_index() - RESERVED_SPAN_PARTS_LEN) + .unwrap() + .recombine(open_span.text_range()); + let top_close_span = span_parts + .get_index(close_span.span_parts_index() - RESERVED_SPAN_PARTS_LEN) + .unwrap() + .recombine(close_span.text_range()); + *top_delim_span = DelimSpan { open: top_open_span, close: top_close_span }; + // Can't remove the top spans from the map, as maybe they're used by other things as well. + // Now we need to reencode the spans, because their parts index changed: + *open_span = S::new(open_span.text_range(), 0); + *close_span = S::new(close_span.text_range(), 1); + + tt.remove(0); + } + dispatch_builder! { + match &mut self.token_trees => tt => remove_first_if_needed(tt, &mut self.top_subtree_spans, &self.span_parts) + } + self.build() + } + + pub fn build(mut self) -> TopSubtree { + assert!( + self.unclosed_subtree_indices.is_empty(), + "attempt to build an unbalanced `TopSubtreeBuilder`" + ); + fn finish_top_len(tt: &mut [TokenTree]) { + let total_len = tt.len() as u32; + let TokenTree::Subtree { len, .. } = &mut tt[0] else { + unreachable!("first token tree is always a subtree"); + }; + *len = total_len - 1; + } + dispatch_builder! { + match &mut self.token_trees => tt => finish_top_len(tt) + } + + let span_parts = [ + CompressedSpanPart::from_span(&self.top_subtree_spans.open), + CompressedSpanPart::from_span(&self.top_subtree_spans.close), + ] + .into_iter() + .chain(self.span_parts.iter().copied()) + .collect(); + + let repr = match self.token_trees { + TopSubtreeBuilderRepr::SpanStorage32(tt) => { + TopSubtreeRepr::SpanStorage32(tt.into_boxed_slice()) + } + TopSubtreeBuilderRepr::SpanStorage64(tt) => { + TopSubtreeRepr::SpanStorage64(tt.into_boxed_slice()) + } + TopSubtreeBuilderRepr::SpanStorage96(tt) => { + TopSubtreeRepr::SpanStorage96(tt.into_boxed_slice()) + } + }; + + TopSubtree { repr, span_parts } + } + + pub fn restore_point(&self) -> SubtreeBuilderRestorePoint { + let token_trees_len = dispatch_builder! { + match &self.token_trees => tt => tt.len() + }; + SubtreeBuilderRestorePoint { + unclosed_subtree_indices_len: self.unclosed_subtree_indices.len(), + token_trees_len, + last_closed_subtree: self.last_closed_subtree, + } + } + + pub fn restore(&mut self, restore_point: SubtreeBuilderRestorePoint) { + self.unclosed_subtree_indices.truncate(restore_point.unclosed_subtree_indices_len); + dispatch_builder! { + match &mut self.token_trees => tt => tt.truncate(restore_point.token_trees_len) + } + self.last_closed_subtree = restore_point.last_closed_subtree; + } +} + +#[derive(Clone, Copy)] +pub struct SubtreeBuilderRestorePoint { + unclosed_subtree_indices_len: usize, + token_trees_len: usize, + last_closed_subtree: Option, +} From 36f86f9e6ab0ed62ea3a8660deceacc4e1aa7ca1 Mon Sep 17 00:00:00 2001 From: AprilNEA Date: Tue, 30 Dec 2025 19:52:02 +0800 Subject: [PATCH 1412/3801] Adds a regression test for 137823 --- .../recursion-issue-137823.rs | 39 +++++++++++++++++++ .../recursion-issue-137823.stderr | 14 +++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/ui/codegen/normalization-overflow/recursion-issue-137823.rs create mode 100644 tests/ui/codegen/normalization-overflow/recursion-issue-137823.stderr diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-137823.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-137823.rs new file mode 100644 index 000000000000..4ae8d84eba11 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-137823.rs @@ -0,0 +1,39 @@ +//@ build-fail + +// Regression test for issue #137823 +// Tests that recursive monomorphization with associated types produces +// a proper "recursion limit" error instead of an ICE. + +fn convert() -> S::Out { + convert2::>() + //~^ ERROR: reached the recursion limit while instantiating +} + +fn convert2() -> S::Out { + convert::() +} + +fn main() { + convert::(); +} + +trait Converter { + type Out; +} + +struct Ser; + +impl Converter for Ser { + type Out = (); +} + +struct ConvertWrap { + _d: S, +} + +impl Converter for ConvertWrap +where + S: Converter, +{ + type Out = S::Out; +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-137823.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-137823.stderr new file mode 100644 index 000000000000..3d80c45685f5 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-137823.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `convert2::>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + --> $DIR/recursion-issue-137823.rs:8:5 + | +LL | convert2::>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `convert2` defined here + --> $DIR/recursion-issue-137823.rs:12:1 + | +LL | fn convert2() -> S::Out { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From ea3839ae18ff5850e35820017a583235722e8f7f Mon Sep 17 00:00:00 2001 From: Alejandra Gonzalez Date: Tue, 30 Dec 2025 14:15:00 +0100 Subject: [PATCH 1413/3801] Remove a single allocation on doc lints --- clippy_lints/src/doc/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 120da92da944..5ff66f10a3fe 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -869,10 +869,12 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ }), true, ); - let mut doc = fragments.iter().fold(String::new(), |mut acc, fragment| { - add_doc_fragment(&mut acc, fragment); - acc - }); + + let mut doc = String::with_capacity(fragments.iter().map(|frag| frag.doc.as_str().len() + 1).sum()); + + for fragment in &fragments { + add_doc_fragment(&mut doc, fragment); + } doc.pop(); if doc.trim().is_empty() { From a74de276d1e847ae8ecb8107d7b7f10dd7f4486f Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 30 Dec 2025 17:55:07 +0100 Subject: [PATCH 1414/3801] remove another single allocation --- clippy_lints/src/booleans.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index a04a56d72bc0..0bd459d8b021 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -15,6 +15,7 @@ use rustc_lint::{LateContext, LateLintPass, Level}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, Symbol, SyntaxContext}; +use std::fmt::Write as _; declare_clippy_lint! { /// ### What it does @@ -356,7 +357,7 @@ impl SuggestContext<'_, '_, '_> { if app != Applicability::MachineApplicable { return None; } - self.output.push_str(&(!snip).to_string()); + let _cannot_fail = write!(&mut self.output, "{}", &(!snip)); } }, True | False | Not(_) => { From c2fc43c7a2b54794cdbfe32f2e576b5b88d825b2 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 30 Dec 2025 23:05:36 +0530 Subject: [PATCH 1415/3801] std: sys: fs: uefi: Ignore "." and ".." when reading directory At least in Unix, "." and ".." are not returned as a directory entry. So ignore these in UEFI as well. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 1c65e3e2b155..8339d835dd1c 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -160,7 +160,15 @@ impl Iterator for ReadDir { fn next(&mut self) -> Option> { match self.0.read_dir_entry() { Ok(None) => None, - Ok(Some(x)) => Some(Ok(DirEntry::from_uefi(x, self.0.path()))), + Ok(Some(x)) => { + let temp = DirEntry::from_uefi(x, self.0.path()); + // Ignore "." and "..". This is how ReadDir behaves in Unix. + if temp.file_name == "." || temp.file_name == ".." { + self.next() + } else { + Some(Ok(temp)) + } + } Err(e) => Some(Err(e)), } } From 58715c3cceb1e644692f3d736a0b155509b8ab4b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 30 Dec 2025 19:28:01 +0100 Subject: [PATCH 1416/3801] make backtrace look a lot like panics --- src/tools/miri/src/diagnostics.rs | 71 +++++++------------ ...pple_os_unfair_lock_move_with_queue.stderr | 4 +- .../libc_pthread_cond_move.init.stderr | 11 ++- ...thread_cond_move.static_initializer.stderr | 11 ++- .../libc_pthread_create_too_few_args.stderr | 1 + .../libc_pthread_create_too_many_args.stderr | 1 + .../concurrency/libc_pthread_join_main.stderr | 4 +- .../libc_pthread_join_multiple.stderr | 4 +- .../concurrency/libc_pthread_join_self.stderr | 4 +- .../libc_pthread_mutex_deadlock.stderr | 25 ++++--- ...ibc_pthread_mutex_free_while_queued.stderr | 20 +++--- .../libc_pthread_mutex_move.init.stderr | 11 ++- ...hread_mutex_move.static_initializer.stderr | 11 ++- ...ibc_pthread_mutex_read_while_queued.stderr | 4 +- ...bc_pthread_mutex_write_while_queued.stderr | 4 +- .../libc_pthread_mutex_wrong_owner.stderr | 4 +- ...ibc_pthread_rwlock_read_wrong_owner.stderr | 4 +- ..._pthread_rwlock_write_read_deadlock.stderr | 25 ++++--- ...pthread_rwlock_write_write_deadlock.stderr | 25 ++++--- ...bc_pthread_rwlock_write_wrong_owner.stderr | 4 +- .../concurrency/windows_join_detached.stderr | 18 ++--- .../concurrency/windows_join_main.stderr | 26 ++++--- .../concurrency/windows_join_self.stderr | 28 ++++---- .../libc/env-set_var-data-race.stderr | 4 +- .../libc/eventfd_block_read_twice.stderr | 22 +++--- .../libc/eventfd_block_write_twice.stderr | 22 +++--- .../libc/fs/mkstemp_immutable_arg.stderr | 11 ++- .../fs/unix_open_missing_required_mode.stderr | 11 ++- .../libc/libc_epoll_block_two_thread.stderr | 22 +++--- .../socketpair-close-while-blocked.stderr | 22 +++--- .../libc/socketpair_block_read_twice.stderr | 22 +++--- .../libc/socketpair_block_write_twice.stderr | 22 +++--- .../fail/alloc/alloc_error_handler.stderr | 26 ++++--- .../alloc/alloc_error_handler_custom.stderr | 26 +++---- .../alloc/alloc_error_handler_no_std.stderr | 20 +++--- .../fail/alloc/global_system_mixup.stderr | 14 ++-- .../miri/tests/fail/alloc/stack_free.stderr | 17 ++--- .../fail/async-shared-mutable.stack.stderr | 25 +++---- .../fail/async-shared-mutable.tree.stderr | 25 +++---- .../both_borrows/aliasing_mut1.stack.stderr | 15 ++-- .../both_borrows/aliasing_mut1.tree.stderr | 15 ++-- .../both_borrows/aliasing_mut2.stack.stderr | 15 ++-- .../both_borrows/aliasing_mut2.tree.stderr | 15 ++-- .../both_borrows/aliasing_mut3.stack.stderr | 15 ++-- .../both_borrows/aliasing_mut3.tree.stderr | 15 ++-- .../both_borrows/aliasing_mut4.stack.stderr | 15 ++-- .../both_borrows/aliasing_mut4.tree.stderr | 28 +++----- .../box_exclusive_violation1.stack.stderr | 22 ++---- .../box_exclusive_violation1.tree.stderr | 22 ++---- .../box_noalias_violation.stack.stderr | 15 ++-- .../box_noalias_violation.tree.stderr | 15 ++-- .../buggy_split_at_mut.stack.stderr | 15 ++-- .../both_borrows/illegal_write6.stack.stderr | 15 ++-- .../both_borrows/illegal_write6.tree.stderr | 15 ++-- ...invalidate_against_protector2.stack.stderr | 15 ++-- .../invalidate_against_protector2.tree.stderr | 15 ++-- ...invalidate_against_protector3.stack.stderr | 15 ++-- .../invalidate_against_protector3.tree.stderr | 15 ++-- .../issue-miri-1050-1.stack.stderr | 18 ++--- .../issue-miri-1050-1.tree.stderr | 18 ++--- .../issue-miri-1050-2.stack.stderr | 14 ++-- .../issue-miri-1050-2.tree.stderr | 14 ++-- .../mut_exclusive_violation1.stack.stderr | 22 ++---- .../mut_exclusive_violation1.tree.stderr | 22 ++---- .../newtype_pair_retagging.stack.stderr | 35 +++------ .../newtype_pair_retagging.tree.stderr | 38 ++++------ .../newtype_retagging.stack.stderr | 35 +++------ .../newtype_retagging.tree.stderr | 38 ++++------ .../retag_data_race_write.stack.stderr | 18 ++--- .../retag_data_race_write.tree.stderr | 18 ++--- .../return_invalid_shr.stack.stderr | 15 ++-- .../return_invalid_shr.tree.stderr | 15 ++-- .../return_invalid_shr_option.stack.stderr | 15 ++-- .../return_invalid_shr_option.tree.stderr | 15 ++-- .../return_invalid_shr_tuple.stack.stderr | 15 ++-- .../return_invalid_shr_tuple.tree.stderr | 15 ++-- .../shr_frozen_violation1.stack.stderr | 22 ++---- .../shr_frozen_violation1.tree.stderr | 22 ++---- .../miri/tests/fail/box-cell-alias.stderr | 15 ++-- .../fail/closures/uninhabited-variant.stderr | 11 ++- .../concurrency/mutex-leak-move-deadlock.rs | 1 + .../mutex-leak-move-deadlock.stderr | 5 -- .../tests/fail/coroutine-pinned-moved.stderr | 25 +++---- .../dangling_pointer_to_raw_pointer.stderr | 11 ++- .../storage_dead_dangling.stderr | 11 ++- .../fail/data_race/alloc_read_race.stderr | 4 +- .../fail/data_race/alloc_write_race.stderr | 4 +- .../atomic_read_na_write_race1.stderr | 4 +- .../atomic_read_na_write_race2.stderr | 4 +- .../atomic_write_na_read_race1.stderr | 4 +- .../atomic_write_na_read_race2.stderr | 4 +- .../atomic_write_na_write_race1.stderr | 4 +- .../atomic_write_na_write_race2.stderr | 4 +- .../dangling_thread_async_race.stderr | 4 +- .../fail/data_race/dealloc_read_race1.stderr | 4 +- .../fail/data_race/dealloc_read_race2.stderr | 4 +- .../data_race/dealloc_read_race_stack.stderr | 4 +- .../fail/data_race/dealloc_write_race1.stderr | 4 +- .../fail/data_race/dealloc_write_race2.stderr | 4 +- .../data_race/dealloc_write_race_stack.stderr | 4 +- .../enable_after_join_to_main.stderr | 4 +- .../local_variable_alloc_race.stderr | 4 +- .../data_race/local_variable_read_race.stderr | 4 +- .../local_variable_write_race.stderr | 4 +- ...ze_read_read_write.match_first_load.stderr | 4 +- ...e_read_read_write.match_second_load.stderr | 4 +- .../mixed_size_read_write.read_write.stderr | 4 +- .../mixed_size_read_write.write_read.stderr | 4 +- .../mixed_size_read_write_read.stderr | 4 +- .../mixed_size_write_write.fst.stderr | 4 +- .../mixed_size_write_write.snd.stderr | 4 +- .../fail/data_race/read_write_race.stderr | 4 +- .../data_race/read_write_race_stack.stderr | 4 +- .../fail/data_race/relax_acquire_race.stderr | 4 +- .../fail/data_race/release_seq_race.stderr | 4 +- .../release_seq_race_same_thread.stderr | 4 +- .../miri/tests/fail/data_race/rmw_race.stderr | 4 +- .../fail/data_race/write_write_race.stderr | 4 +- .../data_race/write_write_race_stack.stderr | 4 +- ...et-discriminant-niche-variant-wrong.stderr | 11 ++- .../arg_inplace_mutate.stack.stderr | 15 ++-- .../arg_inplace_mutate.tree.stderr | 15 ++-- .../arg_inplace_observe_during.none.stderr | 11 ++- .../arg_inplace_observe_during.stack.stderr | 15 ++-- .../arg_inplace_observe_during.tree.stderr | 15 ++-- .../exported_symbol_bad_unwind2.both.stderr | 19 +---- ...orted_symbol_bad_unwind2.definition.stderr | 19 +---- .../return_pointer_aliasing_read.none.stderr | 11 ++- .../return_pointer_aliasing_read.stack.stderr | 15 ++-- .../return_pointer_aliasing_read.tree.stderr | 15 ++-- ...return_pointer_aliasing_write.stack.stderr | 15 ++-- .../return_pointer_aliasing_write.tree.stderr | 15 ++-- ...nter_aliasing_write_tail_call.stack.stderr | 15 ++-- ...inter_aliasing_write_tail_call.tree.stderr | 15 ++-- .../simd_feature_flag_difference.stderr | 11 ++- .../ptr_metadata_uninit_slice_data.stderr | 11 ++- .../ptr_metadata_uninit_slice_len.stderr | 11 ++- .../ptr_metadata_uninit_thin.stderr | 11 ++- .../typed-swap-invalid-array.stderr | 11 ++- .../typed-swap-invalid-scalar.left.stderr | 11 ++- .../typed-swap-invalid-scalar.right.stderr | 11 ++- .../miri/tests/fail/issue-miri-1112.stderr | 11 ++- src/tools/miri/tests/fail/memleak_rc.stderr | 11 ++- .../miri/tests/fail/never_transmute_void.rs | 2 - .../tests/fail/never_transmute_void.stderr | 11 ++- .../tests/fail/overlapping_assignment.stderr | 11 ++- .../miri/tests/fail/panic/abort_unwind.stderr | 13 +--- .../miri/tests/fail/panic/bad_unwind.stderr | 20 +++--- .../miri/tests/fail/panic/double_panic.stderr | 15 +--- src/tools/miri/tests/fail/panic/no_std.stderr | 11 ++- .../miri/tests/fail/panic/panic_abort1.stderr | 29 ++++---- .../miri/tests/fail/panic/panic_abort2.stderr | 29 ++++---- .../miri/tests/fail/panic/panic_abort3.stderr | 29 ++++---- .../miri/tests/fail/panic/panic_abort4.stderr | 29 ++++---- .../fail/panic/tls_macro_const_drop_panic.rs | 1 + .../tests/fail/panic/tls_macro_drop_panic.rs | 3 +- .../fail/panic/tls_macro_drop_panic.stderr | 1 + .../provenance/provenance_transmute.stderr | 11 ++- .../tests/fail/ptr_swap_nonoverlapping.stderr | 10 +-- .../miri/tests/fail/shims/ctor_ub.stderr | 3 +- .../tests/fail/shims/fs/isolated_file.stderr | 41 ++++++----- .../tests/fail/shims/isolated_stdin.stderr | 4 -- .../deallocate_against_protector1.stderr | 37 ++++------ .../drop_in_place_protector.stderr | 21 +++--- .../drop_in_place_retag.stderr | 17 ++--- .../invalidate_against_protector1.stderr | 15 ++-- .../stacked_borrows/pointer_smuggling.stderr | 15 ++-- .../retag_data_race_protected_read.stderr | 4 +- .../retag_data_race_read.stderr | 18 ++--- .../stacked_borrows/return_invalid_mut.stderr | 15 ++-- .../return_invalid_mut_option.stderr | 15 ++-- .../return_invalid_mut_tuple.stderr | 15 ++-- .../tests/fail/tail_calls/cc-mismatch.stderr | 40 +++++++---- .../fail/tail_calls/dangling-local-var.stderr | 15 ++-- .../tests/fail/terminate-terminator.stderr | 25 +------ .../miri/tests/fail/tls_macro_leak.stderr | 19 +++-- .../fail/tree_borrows/outside-range.stderr | 15 ++-- .../fail/tree_borrows/pass_invalid_mut.stderr | 15 ++-- ...peated_foreign_read_lazy_conflicted.stderr | 15 ++-- .../reserved/cell-protected-write.stderr | 15 ++-- .../reserved/int-protected-write.stderr | 15 ++-- .../reservedim_spurious_write.with.stderr | 4 +- .../reservedim_spurious_write.without.stderr | 4 +- .../fail/tree_borrows/spurious_read.stderr | 18 ++--- .../tree_borrows/strongly-protected.stderr | 40 ++++------- ...tree_traversal_skipping_diagnostics.stderr | 15 ++-- .../wildcard/protected_wildcard.stderr | 15 ++-- .../wildcard/protector_conflicted.stderr | 11 ++- .../strongly_protected_wildcard.stderr | 40 ++++------- .../tree_borrows/write-during-2phase.stderr | 21 ++---- .../unaligned_pointers/drop_in_place.stderr | 11 ++- ...ld_requires_parent_struct_alignment.stderr | 11 ++- ...d_requires_parent_struct_alignment2.stderr | 11 ++- .../reference_to_packed.stderr | 11 ++- .../uninit/uninit_alloc_diagnostic.stderr | 14 ++-- ...it_alloc_diagnostic_with_provenance.stderr | 14 ++-- .../tests/fail/unwind-action-terminate.stderr | 19 +---- .../cast_fn_ptr_invalid_caller_arg.stderr | 11 ++- .../fail/validity/invalid_char_cast.stderr | 11 ++- .../fail/validity/invalid_char_match.stderr | 11 ++- .../fail/validity/invalid_enum_cast.stderr | 11 ++- .../tests/fail/weak_memory/weak_uninit.stderr | 4 +- .../atomics/atomic_ptr_double_free.stderr | 28 +++----- .../atomic_ptr_alloc_race.dealloc.stderr | 17 ++--- .../atomic_ptr_alloc_race.write.stderr | 17 ++--- .../atomic_ptr_dealloc_write_race.stderr | 21 +++--- .../atomic_ptr_write_dealloc_race.stderr | 17 ++--- .../genmc/fail/data_race/mpu2_rels_rlx.stderr | 17 ++--- .../data_race/weak_orderings.rel_rlx.stderr | 17 ++--- .../data_race/weak_orderings.rlx_acq.stderr | 17 ++--- .../data_race/weak_orderings.rlx_rlx.stderr | 17 ++--- .../miri/tests/genmc/fail/shims/exit.stderr | 4 +- .../shims/mutex_diff_thread_unlock.stderr | 23 +++--- .../fail/shims/mutex_double_unlock.stderr | 17 ++--- .../fail/simple/alloc_large.multiple.stderr | 23 +++--- .../fail/simple/alloc_large.single.stderr | 23 +++--- .../cas_failure_ord_racy_key_init.stderr | 24 +++---- .../fail/tracing/partial_init.stderr | 22 +++--- .../tracing/unexposed_reachable_alloc.stderr | 22 +++--- .../pass/ptr_read_access.notrace.stderr | 22 +++--- .../pass/ptr_read_access.trace.stderr | 22 +++--- .../pass/ptr_write_access.notrace.stderr | 11 ++- .../pass/ptr_write_access.trace.stderr | 11 ++- src/tools/miri/tests/panic/panic1.stderr | 8 +-- .../tests/pass/alloc-access-tracking.stderr | 14 ++-- .../backtrace/backtrace-global-alloc.stderr | 28 ++++---- .../tests/pass/backtrace/backtrace-std.stderr | 36 +++++----- src/tools/miri/tests/ui.rs | 2 - 228 files changed, 1381 insertions(+), 1927 deletions(-) diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 8de30d870327..1f87ac60c17a 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -576,11 +576,9 @@ fn report_msg<'tcx>( } // Show note and help messages. - let mut extra_span = false; for (span_data, note) in notes { if let Some(span_data) = span_data { err.span_note(span_data.span(), note); - extra_span = true; } else { err.note(note); } @@ -588,60 +586,41 @@ fn report_msg<'tcx>( for (span_data, help) in helps { if let Some(span_data) = span_data { err.span_help(span_data.span(), help); - extra_span = true; } else { err.help(help); } } + // Only print thread name if there are multiple threads. + if let Some(thread) = thread + && machine.threads.get_total_thread_count() > 1 + { + err.note(format!( + "this is on thread `{}`", + machine.threads.get_thread_display_name(thread) + )); + } // Add backtrace - if let Some((first, rest)) = stacktrace.split_first() { - // Start with the function and thread that contain the first span. - let mut fn_and_thread = String::new(); - // Only print thread name if there are multiple threads. - if let Some(thread) = thread - && machine.threads.get_total_thread_count() > 1 - { - write!( - fn_and_thread, - "on thread `{}`", - machine.threads.get_thread_display_name(thread) - ) - .unwrap(); - } - // Only print function name if we show a backtrace - if rest.len() > 0 || !origin_span.is_dummy() { - if !fn_and_thread.is_empty() { - fn_and_thread.push_str(", "); - } - write!(fn_and_thread, "{first}").unwrap(); - } - if !fn_and_thread.is_empty() { - if extra_span && rest.len() > 0 { - // Print a `span_note` as otherwise the backtrace looks attached to the last - // `span_help`. We somewhat arbitrarily use the span of the surrounding function. - err.span_note( - tcx.def_span(first.instance.def_id()), - format!("{level} occurred {fn_and_thread}"), - ); - } else { - err.note(format!("this is {fn_and_thread}")); - } - } - // Continue with where that function got called. - for frame_info in rest.iter() { - let is_local = machine.is_local(frame_info.instance); - // No span for non-local frames and the first frame (which is the error site). - if is_local { - err.span_note(frame_info.span, format!("which got called {frame_info}")); - } else { - let sm = tcx.sess.source_map(); + if stacktrace.len() > 0 { + // Skip it if we'd only shpw the span we have already shown + if stacktrace.len() > 1 { + let sm = tcx.sess.source_map(); + let mut out = format!("stack backtrace:"); + for (idx, frame_info) in stacktrace.iter().enumerate() { let span = sm.span_to_diagnostic_string(frame_info.span); - err.note(format!("which got called {frame_info} (at {span})")); + write!(out, "\n{idx}: {}", frame_info.instance).unwrap(); + write!(out, "\n at {span}").unwrap(); } + err.note(out); } + // For TLS dtors and non-main threads, show the "origin" if !origin_span.is_dummy() { - err.span_note(origin_span, format!("which got called indirectly due to this code")); + let what = if stacktrace.len() > 1 { + "the last function in that backtrace" + } else { + "the current function" + }; + err.span_note(origin_span, format!("{what} got called indirectly due to this code")); } } else if !span.is_dummy() { err.note(format!("this {level} occurred while pushing a call frame onto an empty stack")); diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr index b943ac1f61ef..b4d2d2be6530 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.stderr @@ -6,8 +6,8 @@ LL | let _val = atomic_ref.load(Ordering::Relaxed); | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs:LL:CC | LL | / ... s.spawn(|| { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr index 4507c1bfa227..4e494e1d2a2c 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.init.stderr @@ -6,12 +6,11 @@ LL | libc::pthread_cond_destroy(cond2.as_mut_ptr()); | = 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 - = note: this is inside `check` -note: which got called inside `main` - --> tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC - | -LL | check() - | ^^^^^^^ + = note: stack backtrace: + 0: check + at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC + 1: main + at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr index 6132785b13dd..8b8ead3976f9 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_move.static_initializer.stderr @@ -6,12 +6,11 @@ LL | libc::pthread_cond_destroy(&mut cond2 as *mut _); | = 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 - = note: this is inside `check` -note: which got called inside `main` - --> tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC - | -LL | check() - | ^^^^^^^ + = note: stack backtrace: + 0: check + at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC + 1: main + at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr index fef91e85470d..979a1a8337b5 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr @@ -6,6 +6,7 @@ LL | libc::pthread_create(&mut native, ptr::null(), thread_start, pt | = 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 + = note: this is on thread `unnamed-ID` = note: this error occurred while pushing a call frame onto an empty stack = note: the span indicates which code caused the function to be called, but may not be the literal call site diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr index 4d70576d784c..e8ad65a74ac8 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr @@ -6,6 +6,7 @@ LL | libc::pthread_create(&mut native, ptr::null(), thread_start, pt | = 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 + = note: this is on thread `unnamed-ID` = note: this error occurred while pushing a call frame onto an empty stack = note: the span indicates which code caused the function to be called, but may not be the literal call site diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr index c364642fc629..0d07c2bfa351 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr @@ -6,8 +6,8 @@ LL | ... assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0); | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC | LL | let handle = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr index b9bf801eaf61..8754aaecef94 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr @@ -6,8 +6,8 @@ LL | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 0); | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC | LL | ... let handle = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr index ddf3372a7277..ffc7f2fe4cac 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr @@ -6,8 +6,8 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0); | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC | LL | let handle = thread::spawn(|| { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr index 1e7b0abf341a..468c0e63cc34 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr @@ -4,17 +4,16 @@ error: the evaluated program deadlocked LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC - | -LL | / thread::spawn(move || { -LL | | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); -LL | | }) -LL | | .join() - | |_______________^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC @@ -22,8 +21,8 @@ error: the evaluated program deadlocked LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); | ^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC | LL | / thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr index 765604ea0060..96be3f5764a3 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.stderr @@ -6,15 +6,17 @@ LL | self.1.deallocate(From::from(ptr.cast()), layout); | = 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 - = note: this is on thread `unnamed-ID`, inside ` as std::ops::Drop>::drop` - = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) -note: which got called inside closure - --> tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs:LL:CC - | -LL | drop(unsafe { Box::from_raw(m.get().cast::()) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: as std::ops::Drop>::drop + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::mem::drop + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 3: main::{closure#0}::{closure#2} + at tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs:LL:CC | LL | / s.spawn(|| { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr index f9e06c75e06d..389b014ed647 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.init.stderr @@ -6,12 +6,11 @@ LL | libc::pthread_mutex_lock(&mut m2 as *mut _); | = 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 - = note: this is inside `check` -note: which got called inside `main` - --> tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC - | -LL | check(); - | ^^^^^^^ + = note: stack backtrace: + 0: check + at tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC + 1: main + at tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr index 643518c60617..ba281a548c24 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_move.static_initializer.stderr @@ -6,12 +6,11 @@ LL | libc::pthread_mutex_unlock(&mut m2 as *mut _); | = 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 - = note: this is inside `check` -note: which got called inside `main` - --> tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC - | -LL | check(); - | ^^^^^^^ + = note: stack backtrace: + 0: check + at tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC + 1: main + at tests/fail-dep/concurrency/libc_pthread_mutex_move.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr index fd9cddebabc7..a8d9679eb959 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.stderr @@ -6,8 +6,8 @@ LL | ... let _val = atomic_ref.load(Ordering::Relaxed); | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_mutex_read_while_queued.rs:LL:CC | LL | / ... s.spawn(|| { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr index 02a0f25af492..9bc413fe8d53 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.stderr @@ -6,8 +6,8 @@ LL | atomic_ref.store(0, Ordering::Relaxed); | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_mutex_write_while_queued.rs:LL:CC | LL | / s.spawn(|| { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr index 25dae98ef5d9..0a1de6332562 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr @@ -6,8 +6,8 @@ LL | ... assert_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0 | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs:LL:CC | LL | / ... thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr index 37c7540afb27..d077c6a552ae 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr @@ -6,8 +6,8 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC | LL | / ... thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr index 0818f213f5e7..e00c297a9b29 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr @@ -4,17 +4,16 @@ error: the evaluated program deadlocked LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC - | -LL | / thread::spawn(move || { -LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); -LL | | }) -LL | | .join() - | |_______________^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC @@ -22,8 +21,8 @@ error: the evaluated program deadlocked LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); | ^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC | LL | / thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr index 4ee88c0059d2..21fa8dcbd18d 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr @@ -4,17 +4,16 @@ error: the evaluated program deadlocked LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC - | -LL | / thread::spawn(move || { -LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); -LL | | }) -LL | | .join() - | |_______________^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC @@ -22,8 +21,8 @@ error: the evaluated program deadlocked LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); | ^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC | LL | / thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr index 94578338f40b..ceba695ce5fb 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr @@ -6,8 +6,8 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.rs:LL:CC | LL | / ... thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr index 1765f0a18041..73e79852d63a 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr @@ -6,14 +6,16 @@ LL | let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle( | = 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 - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/concurrency/windows_join_detached.rs:LL:CC - | -LL | thread.join().unwrap(); - | ^^^^^^^^^^^^^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/concurrency/windows_join_detached.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr index ee0aa254abaf..3d324ad0bdef 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr @@ -4,18 +4,16 @@ error: the evaluated program deadlocked LL | let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/concurrency/windows_join_main.rs:LL:CC - | -LL | / thread::spawn(|| { -LL | | unsafe { -LL | | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0); -... | -LL | | .join() - | |___________^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/concurrency/windows_join_main.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/concurrency/windows_join_main.rs:LL:CC @@ -23,8 +21,8 @@ error: the evaluated program deadlocked LL | assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJECT_0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/windows_join_main.rs:LL:CC | LL | / thread::spawn(|| { diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr index 561464d47179..8f28324363b3 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr @@ -4,20 +4,16 @@ error: the evaluated program deadlocked LL | let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/concurrency/windows_join_self.rs:LL:CC - | -LL | / thread::spawn(|| { -LL | | unsafe { -LL | | let native = GetCurrentThread(); -LL | | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0); -LL | | } -LL | | }) -LL | | .join() - | |___________^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/concurrency/windows_join_self.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/concurrency/windows_join_self.rs:LL:CC @@ -25,8 +21,8 @@ error: the evaluated program deadlocked LL | assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0); | ^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/concurrency/windows_join_self.rs:LL:CC | LL | / thread::spawn(|| { diff --git a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr index eed33569af11..635091cc0173 100644 --- a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr +++ b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr @@ -11,8 +11,8 @@ LL | env::set_var("MY_RUST_VAR", "Ferris"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/libc/env-set_var-data-race.rs:LL:CC | LL | let t = thread::spawn(|| unsafe { diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr index d0c8169fe7d2..f5cfd35847af 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr @@ -4,14 +4,16 @@ error: the evaluated program deadlocked LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC - | -LL | thread2.join().unwrap(); - | ^^^^^^^^^^^^^^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC @@ -19,8 +21,8 @@ error: the evaluated program deadlocked LL | let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() }; | ^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/libc/eventfd_block_read_twice.rs:LL:CC | LL | let thread2 = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr index 878059cb5ef2..92c3fc47c4fd 100644 --- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr @@ -4,14 +4,16 @@ error: the evaluated program deadlocked LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC - | -LL | thread2.join().unwrap(); - | ^^^^^^^^^^^^^^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC @@ -19,8 +21,8 @@ error: the evaluated program deadlocked LL | libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() | ^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/libc/eventfd_block_write_twice.rs:LL:CC | LL | let thread2 = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr index ec7b681dfad4..edf428ae8dda 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr @@ -6,12 +6,11 @@ LL | let _fd = unsafe { libc::mkstemp(s) }; | = 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 - = note: this is inside `test_mkstemp_immutable_arg` -note: which got called inside `main` - --> tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs:LL:CC - | -LL | test_mkstemp_immutable_arg(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: test_mkstemp_immutable_arg + at tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs:LL:CC + 1: main + at tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr index 9f5ea4ed021f..a85fae9c7dd2 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr @@ -6,12 +6,11 @@ LL | let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; | = 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 - = note: this is inside `test_file_open_missing_needed_mode` -note: which got called inside `main` - --> tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs:LL:CC - | -LL | test_file_open_missing_needed_mode(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: test_file_open_missing_needed_mode + at tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs:LL:CC + 1: main + at tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr index f7f77647acb5..af6578357a59 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr @@ -4,14 +4,16 @@ error: the evaluated program deadlocked LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC - | -LL | thread2.join().unwrap(); - | ^^^^^^^^^^^^^^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC @@ -19,8 +21,8 @@ error: the evaluated program deadlocked LL | check_epoll_wait::(epfd, &expected, -1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC | LL | let thread2 = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr index b1b1fddc6735..b40c35d6d266 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr @@ -4,14 +4,16 @@ error: the evaluated program deadlocked LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/libc/socketpair-close-while-blocked.rs:LL:CC - | -LL | thread1.join().unwrap(); - | ^^^^^^^^^^^^^^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/libc/socketpair-close-while-blocked.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair-close-while-blocked.rs:LL:CC @@ -19,8 +21,8 @@ error: the evaluated program deadlocked LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) | ^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/libc/socketpair-close-while-blocked.rs:LL:CC | LL | let thread1 = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr index a556ba592ec8..d649076374f5 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr @@ -4,14 +4,16 @@ error: the evaluated program deadlocked LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC - | -LL | thread2.join().unwrap(); - | ^^^^^^^^^^^^^^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC @@ -19,8 +21,8 @@ error: the evaluated program deadlocked LL | libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) | ^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/libc/socketpair_block_read_twice.rs:LL:CC | LL | let thread2 = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr index 259ca6bd8347..66f3359a1292 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr +++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr @@ -4,14 +4,16 @@ error: the evaluated program deadlocked LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ^ thread got stuck here | - = note: this is on thread `main`, inside `std::sys::thread::PLATFORM::Thread::join` - = note: which got called inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` (at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC) - = note: which got called inside `std::thread::JoinHandle::<()>::join` (at RUSTLIB/std/src/thread/join_handle.rs:LL:CC) -note: which got called inside `main` - --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC - | -LL | thread2.join().unwrap(); - | ^^^^^^^^^^^^^^ + = note: this is on thread `main` + = note: stack backtrace: + 0: std::sys::thread::PLATFORM::Thread::join + at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC + 1: std::thread::lifecycle::JoinInner::join + at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC + 2: std::thread::JoinHandle::join + at RUSTLIB/std/src/thread/join_handle.rs:LL:CC + 3: main + at tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC error: the evaluated program deadlocked --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC @@ -19,8 +21,8 @@ error: the evaluated program deadlocked LL | let res = unsafe { libc::write(fds[0], data.as_ptr() as *const libc::c_void, data.len()) }; | ^ thread got stuck here | - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail-dep/libc/socketpair_block_write_twice.rs:LL:CC | LL | let thread2 = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr index bd62bf148d7a..ed9b7ad18b0f 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr @@ -7,17 +7,21 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort() | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside closure - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::alloc::rust_oom::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::alloc::rust_oom` (at RUSTLIB/std/src/alloc.rs:LL:CC) - = note: which got called inside `std::alloc::_::__rust_alloc_error_handler` (at RUSTLIB/std/src/alloc.rs:LL:CC) - = note: which got called inside `std::alloc::handle_alloc_error::rt_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) - = note: which got called inside `std::alloc::handle_alloc_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/alloc/alloc_error_handler.rs:LL:CC - | -LL | handle_alloc_error(Layout::for_value(&0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::alloc::rust_oom::{closure#0} + at RUSTLIB/std/src/alloc.rs:LL:CC + 1: std::sys::backtrace::__rust_end_short_backtrace + at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + 2: std::alloc::rust_oom + at RUSTLIB/std/src/alloc.rs:LL:CC + 3: std::alloc::_::__rust_alloc_error_handler + at RUSTLIB/std/src/alloc.rs:LL:CC + 4: std::alloc::handle_alloc_error::rt_error + at RUSTLIB/alloc/src/alloc.rs:LL:CC + 5: std::alloc::handle_alloc_error + at RUSTLIB/alloc/src/alloc.rs:LL:CC + 6: main + at tests/fail/alloc/alloc_error_handler.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr index 7e7871dc89bc..677fa1b1bb9c 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr @@ -5,21 +5,17 @@ error: abnormal termination: the program aborted execution LL | core::intrinsics::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `alloc_error_handler` -note: which got called inside `_::__rust_alloc_error_handler` - --> tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC - | -LL | #[alloc_error_handler] - | ---------------------- in this attribute macro expansion -LL | fn alloc_error_handler(layout: Layout) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: which got called inside `alloc::alloc::handle_alloc_error::rt_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) - = note: which got called inside `alloc::alloc::handle_alloc_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) -note: which got called inside `miri_start` - --> tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC - | -LL | handle_alloc_error(Layout::for_value(&0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: alloc_error_handler + at tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC + 1: _::__rust_alloc_error_handler + at tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC + 2: alloc::alloc::handle_alloc_error::rt_error + at RUSTLIB/alloc/src/alloc.rs:LL:CC + 3: alloc::alloc::handle_alloc_error + at RUSTLIB/alloc/src/alloc.rs:LL:CC + 4: miri_start + at tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr index b126cb042bee..386e7cdc2bd8 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr @@ -7,15 +7,17 @@ error: abnormal termination: the program aborted execution LL | core::intrinsics::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `panic_handler` - = note: which got called inside `alloc::alloc::__alloc_error_handler::__rdl_alloc_error_handler` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) - = note: which got called inside `alloc::alloc::handle_alloc_error::rt_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) - = note: which got called inside `alloc::alloc::handle_alloc_error` (at RUSTLIB/alloc/src/alloc.rs:LL:CC) -note: which got called inside `miri_start` - --> tests/fail/alloc/alloc_error_handler_no_std.rs:LL:CC - | -LL | handle_alloc_error(Layout::for_value(&0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: panic_handler + at tests/fail/alloc/alloc_error_handler_no_std.rs:LL:CC + 1: alloc::alloc::__alloc_error_handler::__rdl_alloc_error_handler + at RUSTLIB/alloc/src/alloc.rs:LL:CC + 2: alloc::alloc::handle_alloc_error::rt_error + at RUSTLIB/alloc/src/alloc.rs:LL:CC + 3: alloc::alloc::handle_alloc_error + at RUSTLIB/alloc/src/alloc.rs:LL:CC + 4: miri_start + at tests/fail/alloc/alloc_error_handler_no_std.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr index 27464a5a29e8..4214e3e7675b 100644 --- a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr +++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr @@ -6,13 +6,13 @@ LL | FREE(); | = 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 - = note: this is inside `std::sys::alloc::PLATFORM::::dealloc` - = note: which got called inside `::deallocate` (at RUSTLIB/std/src/alloc.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/alloc/global_system_mixup.rs:LL:CC - | -LL | unsafe { System.deallocate(ptr, l) }; - | ^ + = note: stack backtrace: + 0: std::sys::alloc::PLATFORM::dealloc + at RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC + 1: ::deallocate + at RUSTLIB/std/src/alloc.rs:LL:CC + 2: main + at tests/fail/alloc/global_system_mixup.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/stack_free.stderr b/src/tools/miri/tests/fail/alloc/stack_free.stderr index ec052fcb6b9a..deb42c098679 100644 --- a/src/tools/miri/tests/fail/alloc/stack_free.stderr +++ b/src/tools/miri/tests/fail/alloc/stack_free.stderr @@ -6,14 +6,15 @@ LL | self.1.deallocate(From::from(ptr.cast()), layout); | = 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 - = note: this is inside ` as std::ops::Drop>::drop` - = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/alloc/stack_free.rs:LL:CC - | -LL | drop(bad_box); - | ^^^^^^^^^^^^^ + = note: stack backtrace: + 0: as std::ops::Drop>::drop + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::mem::drop + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 3: main + at tests/fail/alloc/stack_free.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr b/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr index 9949dad12867..7cedb24a2564 100644 --- a/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr +++ b/src/tools/miri/tests/fail/async-shared-mutable.stack.stderr @@ -20,22 +20,15 @@ help: was later invalidated at offsets [OFFSET] by a SharedReadOnly retag | LL | let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`. | ^^^^^^^^^^ -note: error occurred inside closure - --> tests/fail/async-shared-mutable.rs:LL:CC - | -LL | core::future::poll_fn(move |_| { - | ^^^^^^^^ - = note: which got called inside ` as std::future::Future>::poll` (at RUSTLIB/core/src/future/poll_fn.rs:LL:CC) -note: which got called inside closure - --> tests/fail/async-shared-mutable.rs:LL:CC - | -LL | .await - | ^^^^^ -note: which got called inside `main` - --> tests/fail/async-shared-mutable.rs:LL:CC - | -LL | assert_eq!(f.as_mut().poll(&mut cx), Poll::Pending); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: main::{closure#0}::{closure#0} + at tests/fail/async-shared-mutable.rs:LL:CC + 1: as std::future::Future>::poll + at RUSTLIB/core/src/future/poll_fn.rs:LL:CC + 2: main::{closure#0} + at tests/fail/async-shared-mutable.rs:LL:CC + 3: main + at tests/fail/async-shared-mutable.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr b/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr index c204f75c4f21..fb6816183768 100644 --- a/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr +++ b/src/tools/miri/tests/fail/async-shared-mutable.tree.stderr @@ -28,22 +28,15 @@ help: the accessed tag later transitioned to Frozen due to a reborrow (act LL | let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`. | ^^^^^^^^^^ = help: this transition corresponds to a loss of write permissions -note: error occurred inside closure - --> tests/fail/async-shared-mutable.rs:LL:CC - | -LL | core::future::poll_fn(move |_| { - | ^^^^^^^^ - = note: which got called inside ` as std::future::Future>::poll` (at RUSTLIB/core/src/future/poll_fn.rs:LL:CC) -note: which got called inside closure - --> tests/fail/async-shared-mutable.rs:LL:CC - | -LL | .await - | ^^^^^ -note: which got called inside `main` - --> tests/fail/async-shared-mutable.rs:LL:CC - | -LL | assert_eq!(f.as_mut().poll(&mut cx), Poll::Pending); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: main::{closure#0}::{closure#0} + at tests/fail/async-shared-mutable.rs:LL:CC + 1: as std::future::Future>::poll + at RUSTLIB/core/src/future/poll_fn.rs:LL:CC + 2: main::{closure#0} + at tests/fail/async-shared-mutable.rs:LL:CC + 3: main + at tests/fail/async-shared-mutable.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr index bb5e731545b7..cdd668f1f633 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.stack.stderr @@ -16,16 +16,11 @@ help: is this argument | LL | fn safe(x: &mut i32, y: &mut i32) { | ^ -note: error occurred inside `safe` - --> tests/fail/both_borrows/aliasing_mut1.rs:LL:CC - | -LL | fn safe(x: &mut i32, y: &mut i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/aliasing_mut1.rs:LL:CC - | -LL | safe_raw(xraw, xraw); - | ^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: safe + at tests/fail/both_borrows/aliasing_mut1.rs:LL:CC + 1: main + at tests/fail/both_borrows/aliasing_mut1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr index 34f56696e000..d26a0fc0586e 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut1.tree.stderr @@ -18,16 +18,11 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | fn safe(x: &mut i32, y: &mut i32) { | ^ = help: this transition corresponds to a temporary loss of write permissions until function exit -note: error occurred inside `safe` - --> tests/fail/both_borrows/aliasing_mut1.rs:LL:CC - | -LL | fn safe(x: &mut i32, y: &mut i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/aliasing_mut1.rs:LL:CC - | -LL | safe_raw(xraw, xraw); - | ^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: safe + at tests/fail/both_borrows/aliasing_mut1.rs:LL:CC + 1: main + at tests/fail/both_borrows/aliasing_mut1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr index 5c574f13ff70..c050dbb792b5 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.stack.stderr @@ -16,16 +16,11 @@ help: is this argument | LL | fn safe(x: &i32, y: &mut i32) { | ^ -note: error occurred inside `safe` - --> tests/fail/both_borrows/aliasing_mut2.rs:LL:CC - | -LL | fn safe(x: &i32, y: &mut i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/aliasing_mut2.rs:LL:CC - | -LL | safe_raw(xshr, xraw); - | ^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: safe + at tests/fail/both_borrows/aliasing_mut2.rs:LL:CC + 1: main + at tests/fail/both_borrows/aliasing_mut2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr index 639a4ef57efe..77597e4aa831 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut2.tree.stderr @@ -18,16 +18,11 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | let _v = *x; | ^^ = help: this transition corresponds to a temporary loss of write permissions until function exit -note: error occurred inside `safe` - --> tests/fail/both_borrows/aliasing_mut2.rs:LL:CC - | -LL | fn safe(x: &i32, y: &mut i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/aliasing_mut2.rs:LL:CC - | -LL | safe_raw(xshr, xraw); - | ^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: safe + at tests/fail/both_borrows/aliasing_mut2.rs:LL:CC + 1: main + at tests/fail/both_borrows/aliasing_mut2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr index 4be06c65f191..49087d472255 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.stack.stderr @@ -16,16 +16,11 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique function-ent | LL | safe_raw(xraw, xshr); | ^^^^^^^^^^^^^^^^^^^^ -note: error occurred inside `safe` - --> tests/fail/both_borrows/aliasing_mut3.rs:LL:CC - | -LL | fn safe(x: &mut i32, y: &i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/aliasing_mut3.rs:LL:CC - | -LL | safe_raw(xraw, xshr); - | ^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: safe + at tests/fail/both_borrows/aliasing_mut3.rs:LL:CC + 1: main + at tests/fail/both_borrows/aliasing_mut3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr index 09a54f8199c7..32f980da6f7e 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut3.tree.stderr @@ -18,16 +18,11 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | fn safe(x: &mut i32, y: &i32) { | ^ = help: this transition corresponds to a temporary loss of write permissions until function exit -note: error occurred inside `safe` - --> tests/fail/both_borrows/aliasing_mut3.rs:LL:CC - | -LL | fn safe(x: &mut i32, y: &i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/aliasing_mut3.rs:LL:CC - | -LL | safe_raw(xraw, xshr); - | ^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: safe + at tests/fail/both_borrows/aliasing_mut3.rs:LL:CC + 1: main + at tests/fail/both_borrows/aliasing_mut3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr index e72996d43d7b..f56270f48bea 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.stack.stderr @@ -16,16 +16,11 @@ help: is this argument | LL | fn safe(x: &i32, y: &mut Cell) { | ^ -note: error occurred inside `safe` - --> tests/fail/both_borrows/aliasing_mut4.rs:LL:CC - | -LL | fn safe(x: &i32, y: &mut Cell) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/aliasing_mut4.rs:LL:CC - | -LL | safe_raw(xshr, xraw as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: safe + at tests/fail/both_borrows/aliasing_mut4.rs:LL:CC + 1: main + at tests/fail/both_borrows/aliasing_mut4.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr index d2a533a3da8e..11eb1ae7ddee 100644 --- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr @@ -19,23 +19,17 @@ help: the protected tag was created here, in the initial state Frozen | LL | fn safe(x: &i32, y: &mut Cell) { | ^ -note: error occurred inside `std::mem::replace::` - --> RUSTLIB/core/src/mem/mod.rs:LL:CC - | -LL | pub const fn replace(dest: &mut T, src: T) -> T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::cell::Cell::::replace` (at RUSTLIB/core/src/cell.rs:LL:CC) - = note: which got called inside `std::cell::Cell::::set` (at RUSTLIB/core/src/cell.rs:LL:CC) -note: which got called inside `safe` - --> tests/fail/both_borrows/aliasing_mut4.rs:LL:CC - | -LL | y.set(1); - | ^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/aliasing_mut4.rs:LL:CC - | -LL | safe_raw(xshr, xraw as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::mem::replace + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 1: std::cell::Cell::replace + at RUSTLIB/core/src/cell.rs:LL:CC + 2: std::cell::Cell::set + at RUSTLIB/core/src/cell.rs:LL:CC + 3: safe + at tests/fail/both_borrows/aliasing_mut4.rs:LL:CC + 4: main + at tests/fail/both_borrows/aliasing_mut4.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.stack.stderr index c9341ccdb037..69f7c908119f 100644 --- a/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.stack.stderr @@ -16,21 +16,13 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *our = 5; | ^^^^^^^^ -note: error occurred inside `unknown_code_2` - --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC - | -LL | fn unknown_code_2() { - | ^^^^^^^^^^^^^^^^^^^ -note: which got called inside `demo_box_advanced_unique` - --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC - | -LL | unknown_code_2(); - | ^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC - | -LL | demo_box_advanced_unique(Box::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: unknown_code_2 + at tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC + 1: demo_box_advanced_unique + at tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC + 2: main + at tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.tree.stderr index 446d283694a1..b4def1008f7d 100644 --- a/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/box_exclusive_violation1.tree.stderr @@ -18,21 +18,13 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *our = 5; | ^^^^^^^^ = help: this transition corresponds to a loss of read permissions -note: error occurred inside `unknown_code_2` - --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC - | -LL | fn unknown_code_2() { - | ^^^^^^^^^^^^^^^^^^^ -note: which got called inside `demo_box_advanced_unique` - --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC - | -LL | unknown_code_2(); - | ^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC - | -LL | demo_box_advanced_unique(Box::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: unknown_code_2 + at tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC + 1: demo_box_advanced_unique + at tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC + 2: main + at tests/fail/both_borrows/box_exclusive_violation1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr index 1a5662b74693..7bf29bfdcb58 100644 --- a/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.stack.stderr @@ -16,16 +16,11 @@ help: is this argument | LL | unsafe fn test(mut x: Box, y: *const i32) -> i32 { | ^^^^^ -note: error occurred inside `test` - --> tests/fail/both_borrows/box_noalias_violation.rs:LL:CC - | -LL | unsafe fn test(mut x: Box, y: *const i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/box_noalias_violation.rs:LL:CC - | -LL | test(Box::from_raw(ptr), ptr); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: test + at tests/fail/both_borrows/box_noalias_violation.rs:LL:CC + 1: main + at tests/fail/both_borrows/box_noalias_violation.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr index 6ec056828fd5..0744b0e9499b 100644 --- a/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/box_noalias_violation.tree.stderr @@ -25,16 +25,11 @@ help: the protected tag later transitioned to Unique due to a child write LL | *x = 5; | ^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference -note: error occurred inside `test` - --> tests/fail/both_borrows/box_noalias_violation.rs:LL:CC - | -LL | unsafe fn test(mut x: Box, y: *const i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/box_noalias_violation.rs:LL:CC - | -LL | test(Box::from_raw(ptr), ptr); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: test + at tests/fail/both_borrows/box_noalias_violation.rs:LL:CC + 1: main + at tests/fail/both_borrows/box_noalias_violation.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr index 2b0d5f07994c..ef7d54b0b19d 100644 --- a/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/buggy_split_at_mut.stack.stderr @@ -22,16 +22,11 @@ help: was later invalidated at offsets [0x0..0x10] by a Unique retag | LL | from_raw_parts_mut(ptr.offset(mid as isize), len - mid), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: error occurred inside `safe::split_at_mut::` - --> tests/fail/both_borrows/buggy_split_at_mut.rs:LL:CC - | -LL | pub fn split_at_mut(self_: &mut [T], mid: usize) -> (&mut [T], &mut [T]) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/buggy_split_at_mut.rs:LL:CC - | -LL | let (a, b) = safe::split_at_mut(&mut array, 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: safe::split_at_mut + at tests/fail/both_borrows/buggy_split_at_mut.rs:LL:CC + 1: main + at tests/fail/both_borrows/buggy_split_at_mut.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr index 3c09bec03d6a..21d1504b03b1 100644 --- a/src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write6.stack.stderr @@ -16,16 +16,11 @@ help: is this argument | LL | fn foo(a: &mut u32, y: *mut u32) -> u32 { | ^ -note: error occurred inside `foo` - --> tests/fail/both_borrows/illegal_write6.rs:LL:CC - | -LL | fn foo(a: &mut u32, y: *mut u32) -> u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/illegal_write6.rs:LL:CC - | -LL | foo(x, p); - | ^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/both_borrows/illegal_write6.rs:LL:CC + 1: main + at tests/fail/both_borrows/illegal_write6.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr b/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr index 69bb914236da..923dd33a0a17 100644 --- a/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/illegal_write6.tree.stderr @@ -25,16 +25,11 @@ help: the protected tag later transitioned to Unique due to a child write LL | *a = 1; | ^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference -note: error occurred inside `foo` - --> tests/fail/both_borrows/illegal_write6.rs:LL:CC - | -LL | fn foo(a: &mut u32, y: *mut u32) -> u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/illegal_write6.rs:LL:CC - | -LL | foo(x, p); - | ^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/both_borrows/illegal_write6.rs:LL:CC + 1: main + at tests/fail/both_borrows/illegal_write6.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr index d298d511d3e1..12de173519ac 100644 --- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.stack.stderr @@ -16,16 +16,11 @@ help: is this argument | LL | fn inner(x: *mut i32, _y: &i32) { | ^^ -note: error occurred inside `inner` - --> tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC - | -LL | fn inner(x: *mut i32, _y: &i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC - | -LL | inner(xraw, xref); - | ^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: inner + at tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC + 1: main + at tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr index b83217bce7e9..26882ae08024 100644 --- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector2.tree.stderr @@ -19,16 +19,11 @@ help: the protected tag was created here, in the initial state Frozen | LL | fn inner(x: *mut i32, _y: &i32) { | ^^ -note: error occurred inside `inner` - --> tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC - | -LL | fn inner(x: *mut i32, _y: &i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC - | -LL | inner(xraw, xref); - | ^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: inner + at tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC + 1: main + at tests/fail/both_borrows/invalidate_against_protector2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr index ebbc3a7ae8c0..b1215852a35f 100644 --- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr @@ -16,16 +16,11 @@ help: is this argument | LL | fn inner(x: *mut i32, _y: &i32) { | ^^ -note: error occurred inside `inner` - --> tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC - | -LL | fn inner(x: *mut i32, _y: &i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC - | -LL | inner(ptr, &*ptr); - | ^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: inner + at tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC + 1: main + at tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr index 1a1eb89d25f7..ae2dc93fd109 100644 --- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.tree.stderr @@ -19,16 +19,11 @@ help: the protected tag was created here, in the initial state Frozen | LL | fn inner(x: *mut i32, _y: &i32) { | ^^ -note: error occurred inside `inner` - --> tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC - | -LL | fn inner(x: *mut i32, _y: &i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC - | -LL | inner(ptr, &*ptr); - | ^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: inner + at tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC + 1: main + at tests/fail/both_borrows/invalidate_against_protector3.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr index 2b2e16d1ecff..14a4065c1f0a 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.stack.stderr @@ -11,17 +11,13 @@ help: ALLOC was allocated here: | LL | let ptr = Box::into_raw(Box::new(0u16)); | ^^^^^^^^^^^^^^ -note: error occurred inside `std::boxed::Box::::from_raw_in` - --> RUSTLIB/alloc/src/boxed.rs:LL:CC - | -LL | pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/both_borrows/issue-miri-1050-1.rs:LL:CC - | -LL | drop(Box::from_raw(ptr as *mut u32)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::boxed::Box::from_raw_in + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::boxed::Box::from_raw + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: main + at tests/fail/both_borrows/issue-miri-1050-1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr index 2b2e16d1ecff..14a4065c1f0a 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.tree.stderr @@ -11,17 +11,13 @@ help: ALLOC was allocated here: | LL | let ptr = Box::into_raw(Box::new(0u16)); | ^^^^^^^^^^^^^^ -note: error occurred inside `std::boxed::Box::::from_raw_in` - --> RUSTLIB/alloc/src/boxed.rs:LL:CC - | -LL | pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/both_borrows/issue-miri-1050-1.rs:LL:CC - | -LL | drop(Box::from_raw(ptr as *mut u32)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::boxed::Box::from_raw_in + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::boxed::Box::from_raw + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: main + at tests/fail/both_borrows/issue-miri-1050-1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr index f33b6cf77e4d..beb712388f91 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.stack.stderr @@ -6,13 +6,13 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = 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 - = note: this is inside `std::boxed::Box::::from_raw_in` - = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/both_borrows/issue-miri-1050-2.rs:LL:CC - | -LL | drop(Box::from_raw(ptr.as_ptr())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::boxed::Box::from_raw_in + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::boxed::Box::from_raw + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: main + at tests/fail/both_borrows/issue-miri-1050-2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr index f33b6cf77e4d..beb712388f91 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.tree.stderr @@ -6,13 +6,13 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = 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 - = note: this is inside `std::boxed::Box::::from_raw_in` - = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/both_borrows/issue-miri-1050-2.rs:LL:CC - | -LL | drop(Box::from_raw(ptr.as_ptr())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::boxed::Box::from_raw_in + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::boxed::Box::from_raw + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: main + at tests/fail/both_borrows/issue-miri-1050-2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr index 290f50f60c2b..772e7c03bf6e 100644 --- a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.stack.stderr @@ -16,21 +16,13 @@ help: was later invalidated at offsets [0x0..0x4] by a write access | LL | *our = 5; | ^^^^^^^^ -note: error occurred inside `unknown_code_2` - --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC - | -LL | fn unknown_code_2() { - | ^^^^^^^^^^^^^^^^^^^ -note: which got called inside `demo_mut_advanced_unique` - --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC - | -LL | unknown_code_2(); - | ^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC - | -LL | demo_mut_advanced_unique(&mut 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: unknown_code_2 + at tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC + 1: demo_mut_advanced_unique + at tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC + 2: main + at tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr index 608e41341c3f..97400d479d32 100644 --- a/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/mut_exclusive_violation1.tree.stderr @@ -18,21 +18,13 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *our = 5; | ^^^^^^^^ = help: this transition corresponds to a loss of read permissions -note: error occurred inside `unknown_code_2` - --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC - | -LL | fn unknown_code_2() { - | ^^^^^^^^^^^^^^^^^^^ -note: which got called inside `demo_mut_advanced_unique` - --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC - | -LL | unknown_code_2(); - | ^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC - | -LL | demo_mut_advanced_unique(&mut 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: unknown_code_2 + at tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC + 1: demo_mut_advanced_unique + at tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC + 2: main + at tests/fail/both_borrows/mut_exclusive_violation1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr index 68fd20ba942a..d7688680e7da 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr @@ -16,30 +16,17 @@ help: is this argument | LL | fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { | ^^ -note: error occurred inside `std::boxed::Box::::from_raw_in` - --> RUSTLIB/alloc/src/boxed.rs:LL:CC - | -LL | pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside closure - --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC - | -LL | || drop(Box::from_raw(ptr)), - | ^^^^^^^^^^^^^^^^^^ -note: which got called inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC}>` - --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC - | -LL | dealloc(); - | ^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC - | -LL | / dealloc_while_running( -LL | | Newtype(&mut *ptr, 0), -LL | | || drop(Box::from_raw(ptr)), -LL | | ) - | |_________^ + = note: stack backtrace: + 0: std::boxed::Box::from_raw_in + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::boxed::Box::from_raw + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: main::{closure#0} + at tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC + 3: dealloc_while_running + at tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC + 4: main + at tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr index f0dffb8f14ad..68b9d1c86d1a 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr @@ -25,31 +25,19 @@ help: the protected tag later transitioned to Reserved (conflicted) due to LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit -note: error occurred inside ` as std::ops::Drop>::drop` - --> RUSTLIB/alloc/src/boxed.rs:LL:CC - | -LL | fn drop(&mut self) { - | ^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) -note: which got called inside closure - --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC - | -LL | || drop(Box::from_raw(ptr)), - | ^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC}>` - --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC - | -LL | dealloc(); - | ^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC - | -LL | / dealloc_while_running( -LL | | Newtype(&mut *ptr, 0), -LL | | || drop(Box::from_raw(ptr)), -LL | | ) - | |_________^ + = note: stack backtrace: + 0: as std::ops::Drop>::drop + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::mem::drop + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 3: main::{closure#0} + at tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC + 4: dealloc_while_running + at tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC + 5: main + at tests/fail/both_borrows/newtype_pair_retagging.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr index 8f1619bda403..b7b0f2812669 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr @@ -16,30 +16,17 @@ help: is this argument | LL | fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { | ^^ -note: error occurred inside `std::boxed::Box::::from_raw_in` - --> RUSTLIB/alloc/src/boxed.rs:LL:CC - | -LL | pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::boxed::Box::::from_raw` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside closure - --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC - | -LL | || drop(Box::from_raw(ptr)), - | ^^^^^^^^^^^^^^^^^^ -note: which got called inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_retagging.rs:LL:CC}>` - --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC - | -LL | dealloc(); - | ^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC - | -LL | / dealloc_while_running( -LL | | Newtype(&mut *ptr), -LL | | || drop(Box::from_raw(ptr)), -LL | | ) - | |_________^ + = note: stack backtrace: + 0: std::boxed::Box::from_raw_in + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::boxed::Box::from_raw + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: main::{closure#0} + at tests/fail/both_borrows/newtype_retagging.rs:LL:CC + 3: dealloc_while_running + at tests/fail/both_borrows/newtype_retagging.rs:LL:CC + 4: main + at tests/fail/both_borrows/newtype_retagging.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr index f7a2d63dc8a9..5069b1d01cd2 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr @@ -25,31 +25,19 @@ help: the protected tag later transitioned to Reserved (conflicted) due to LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit -note: error occurred inside ` as std::ops::Drop>::drop` - --> RUSTLIB/alloc/src/boxed.rs:LL:CC - | -LL | fn drop(&mut self) { - | ^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) -note: which got called inside closure - --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC - | -LL | || drop(Box::from_raw(ptr)), - | ^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `dealloc_while_running::<{closure@tests/fail/both_borrows/newtype_retagging.rs:LL:CC}>` - --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC - | -LL | dealloc(); - | ^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/newtype_retagging.rs:LL:CC - | -LL | / dealloc_while_running( -LL | | Newtype(&mut *ptr), -LL | | || drop(Box::from_raw(ptr)), -LL | | ) - | |_________^ + = note: stack backtrace: + 0: as std::ops::Drop>::drop + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::mem::drop + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 3: main::{closure#0} + at tests/fail/both_borrows/newtype_retagging.rs:LL:CC + 4: dealloc_while_running + at tests/fail/both_borrows/newtype_retagging.rs:LL:CC + 5: main + at tests/fail/both_borrows/newtype_retagging.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr index d1dbdbc67f1b..f0d98ee6f20f 100644 --- a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr @@ -14,17 +14,13 @@ LL | let _r = &mut *p; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = 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 -note: error occurred on thread `unnamed-ID`, inside `thread_2` - --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC - | -LL | fn thread_2(p: SendPtr) { - | ^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside closure - --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC - | -LL | let t2 = std::thread::spawn(move || thread_2(p)); - | ^^^^^^^^^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: thread_2 + at tests/fail/both_borrows/retag_data_race_write.rs:LL:CC + 1: main::{closure#1} + at tests/fail/both_borrows/retag_data_race_write.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC | LL | let t2 = std::thread::spawn(move || thread_2(p)); diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr index 47abf74cb8a2..bf8b2f8690fe 100644 --- a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr @@ -14,17 +14,13 @@ LL | let _r = &mut *p; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = 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 -note: error occurred on thread `unnamed-ID`, inside `thread_2` - --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC - | -LL | fn thread_2(p: SendPtr) { - | ^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside closure - --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC - | -LL | let t2 = std::thread::spawn(move || thread_2(p)); - | ^^^^^^^^^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: thread_2 + at tests/fail/both_borrows/retag_data_race_write.rs:LL:CC + 1: main::{closure#1} + at tests/fail/both_borrows/retag_data_race_write.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/fail/both_borrows/retag_data_race_write.rs:LL:CC | LL | let t2 = std::thread::spawn(move || thread_2(p)); diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr index ff9968802809..8ca0cd4bda43 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr @@ -16,16 +16,11 @@ help: was later invalidated at offsets [0x4..0x8] by a write access | LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ -note: error occurred inside `foo` - --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC - | -LL | fn foo(x: &mut (i32, i32)) -> &i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC - | -LL | foo(&mut (1, 2)); - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/both_borrows/return_invalid_shr.rs:LL:CC + 1: main + at tests/fail/both_borrows/return_invalid_shr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr index 598a95dd96c9..0147769bb949 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr @@ -18,16 +18,11 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions -note: error occurred inside `foo` - --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC - | -LL | fn foo(x: &mut (i32, i32)) -> &i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC - | -LL | foo(&mut (1, 2)); - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/both_borrows/return_invalid_shr.rs:LL:CC + 1: main + at tests/fail/both_borrows/return_invalid_shr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr index d33782301180..94d538072ae0 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr @@ -19,16 +19,11 @@ help: was later invalidated at offsets [0x4..0x8] by a write access | LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ -note: error occurred inside `foo` - --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC - | -LL | fn foo(x: &mut (i32, i32)) -> Option<&i32> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC - | -LL | match foo(&mut (1, 2)) { - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC + 1: main + at tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr index d303cc9b22e8..f66798c43586 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr @@ -18,16 +18,11 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions -note: error occurred inside `foo` - --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC - | -LL | fn foo(x: &mut (i32, i32)) -> Option<&i32> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC - | -LL | match foo(&mut (1, 2)) { - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC + 1: main + at tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr index d6063168d33d..ffe673e1bcf9 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr @@ -19,16 +19,11 @@ help: was later invalidated at offsets [0x4..0x8] by a write access | LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ -note: error occurred inside `foo` - --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC - | -LL | fn foo(x: &mut (i32, i32)) -> (&i32,) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC - | -LL | foo(&mut (1, 2)).0; - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC + 1: main + at tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr index 0c5b05ce1b94..1eee9ed338ec 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr @@ -18,16 +18,11 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | unsafe { *xraw = (42, 23) }; // unfreeze | ^^^^^^^^^^^^^^^^ = help: this transition corresponds to a loss of read permissions -note: error occurred inside `foo` - --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC - | -LL | fn foo(x: &mut (i32, i32)) -> (&i32,) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC - | -LL | foo(&mut (1, 2)).0; - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC + 1: main + at tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr index 3a05fb151cf1..aae9f8efbe9f 100644 --- a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.stack.stderr @@ -11,21 +11,13 @@ help: was created by a SharedReadOnly retag at offsets [0x0..0x4] | LL | *(x as *const i32 as *mut i32) = 7; | ^ -note: error occurred inside `unknown_code` - --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC - | -LL | fn unknown_code(x: &i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `foo` - --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC - | -LL | unknown_code(&*x); - | ^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC - | -LL | println!("{}", foo(&mut 0)); - | ^^^^^^^^^^^ + = note: stack backtrace: + 0: unknown_code + at tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC + 1: foo + at tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC + 2: main + at tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr index 8040cfa212a9..274d5becddfd 100644 --- a/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/shr_frozen_violation1.tree.stderr @@ -12,21 +12,13 @@ help: the accessed tag was created here, in the initial state Frozen | LL | fn unknown_code(x: &i32) { | ^ -note: error occurred inside `unknown_code` - --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC - | -LL | fn unknown_code(x: &i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `foo` - --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC - | -LL | unknown_code(&*x); - | ^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC - | -LL | println!("{}", foo(&mut 0)); - | ^^^^^^^^^^^ + = note: stack backtrace: + 0: unknown_code + at tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC + 1: foo + at tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC + 2: main + at tests/fail/both_borrows/shr_frozen_violation1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/box-cell-alias.stderr b/src/tools/miri/tests/fail/box-cell-alias.stderr index c5ce263ff1c9..63cdc98d3054 100644 --- a/src/tools/miri/tests/fail/box-cell-alias.stderr +++ b/src/tools/miri/tests/fail/box-cell-alias.stderr @@ -16,16 +16,11 @@ help: was later invalidated at offsets [0x0..0x1] by a Unique retag | LL | let res = helper(val, ptr); | ^^^ -note: error occurred inside `helper` - --> tests/fail/box-cell-alias.rs:LL:CC - | -LL | fn helper(val: Box>, ptr: *const Cell) -> u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/box-cell-alias.rs:LL:CC - | -LL | let res = helper(val, ptr); - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: helper + at tests/fail/box-cell-alias.rs:LL:CC + 1: main + at tests/fail/box-cell-alias.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr b/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr index f0f145fd1366..aea878660115 100644 --- a/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr +++ b/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr @@ -6,12 +6,11 @@ LL | match r { | = 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 - = note: this is inside closure -note: which got called inside `main` - --> tests/fail/closures/uninhabited-variant.rs:LL:CC - | -LL | f(); - | ^^^ + = note: stack backtrace: + 0: main::{closure#0} + at tests/fail/closures/uninhabited-variant.rs:LL:CC + 1: main + at tests/fail/closures/uninhabited-variant.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs index 5afa6c71700e..6d8bd3d3f2a4 100644 --- a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs +++ b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.rs @@ -3,6 +3,7 @@ //@normalize-stderr-test: "LL \| .*" -> "LL | $$CODE" //@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "\n *= note:.*" -> "" +//@normalize-stderr-test: "\n *\d+:.*\n *at .*" -> "" // On macOS we use chekced pthread mutexes which changes the error //@normalize-stderr-test: "a thread got stuck here" -> "thread `main` got stuck here" //@normalize-stderr-test: "a thread deadlocked" -> "the evaluated program deadlocked" diff --git a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr index 258f5a823fcd..b036141bb267 100644 --- a/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr +++ b/src/tools/miri/tests/fail/concurrency/mutex-leak-move-deadlock.stderr @@ -4,11 +4,6 @@ error: the evaluated program deadlocked LL | $CODE | ^ thread got stuck here | -note: which got called inside `main` - --> tests/fail/concurrency/mutex-leak-move-deadlock.rs:LL:CC - | -LL | $CODE - | ^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/coroutine-pinned-moved.stderr b/src/tools/miri/tests/fail/coroutine-pinned-moved.stderr index 2cc3b845deba..0c57c6894a08 100644 --- a/src/tools/miri/tests/fail/coroutine-pinned-moved.stderr +++ b/src/tools/miri/tests/fail/coroutine-pinned-moved.stderr @@ -16,22 +16,15 @@ help: ALLOC was deallocated here: | LL | }; // *deallocate* coroutine_iterator | ^ -note: error occurred inside closure - --> tests/fail/coroutine-pinned-moved.rs:LL:CC - | -LL | static move || { - | ^^^^^^^^^^^^^^ -note: which got called inside ` as std::iter::Iterator>::next` - --> tests/fail/coroutine-pinned-moved.rs:LL:CC - | -LL | match me.resume(()) { - | ^^^^^^^^^^^^^ - = note: which got called inside `std::boxed::iter::>>::next` (at RUSTLIB/alloc/src/boxed/iter.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/coroutine-pinned-moved.rs:LL:CC - | -LL | coroutine_iterator_2.next(); // and use moved value - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: firstn::{closure#0} + at tests/fail/coroutine-pinned-moved.rs:LL:CC + 1: as std::iter::Iterator>::next + at tests/fail/coroutine-pinned-moved.rs:LL:CC + 2: std::boxed::iter::next + at RUSTLIB/alloc/src/boxed/iter.rs:LL:CC + 3: main + at tests/fail/coroutine-pinned-moved.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.stderr index e5471e094bc8..feff143cba66 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.stderr @@ -6,12 +6,11 @@ LL | unsafe { &(*x).0 as *const i32 } | = 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 - = note: this is inside `via_ref` -note: which got called inside `main` - --> tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs:LL:CC - | -LL | via_ref(ptr); // this is not - | ^^^^^^^^^^^^ + = note: stack backtrace: + 0: via_ref + at tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs:LL:CC + 1: main + at tests/fail/dangling_pointers/dangling_pointer_to_raw_pointer.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr index 93bb9603ae5b..67b60e6bca41 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.stderr @@ -6,12 +6,11 @@ LL | let _ref = unsafe { &mut *(LEAK as *mut i32) }; | = 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 - = note: this is inside `evil` -note: which got called inside `main` - --> tests/fail/dangling_pointers/storage_dead_dangling.rs:LL:CC - | -LL | evil(); - | ^^^^^^ + = note: stack backtrace: + 0: evil + at tests/fail/dangling_pointers/storage_dead_dangling.rs:LL:CC + 1: main + at tests/fail/dangling_pointers/storage_dead_dangling.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr b/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr index 67edbfb4658e..ddb2edc68d48 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr +++ b/src/tools/miri/tests/fail/data_race/alloc_read_race.stderr @@ -11,8 +11,8 @@ LL | pointer.store(Box::into_raw(Box::new_uninit()), Ordering::Relax | ^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/alloc_read_race.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr b/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr index 33c562958e20..93fe9ff5539a 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/alloc_write_race.stderr @@ -11,8 +11,8 @@ LL | .store(Box::into_raw(Box::::new_uninit()) as *mut us | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/alloc_write_race.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr index 6f0332e46fa3..aa8a48461208 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.stderr @@ -11,8 +11,8 @@ LL | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/atomic_read_na_write_race1.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr index 13f95e85242a..1d1dc68784d9 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.stderr @@ -11,8 +11,8 @@ LL | atomic_ref.load(Ordering::SeqCst) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/atomic_read_na_write_race2.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr index 0907ed3cd0a3..b65e4e3609e7 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.stderr @@ -11,8 +11,8 @@ LL | atomic_ref.store(32, Ordering::SeqCst) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/atomic_write_na_read_race1.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr index dfc7ed012725..444d73d46b3c 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.stderr @@ -11,8 +11,8 @@ LL | let _val = *(c.0 as *mut usize); | ^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/atomic_write_na_read_race2.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr index 018db8364ed0..ca67861b47ce 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.stderr @@ -11,8 +11,8 @@ LL | *(c.0 as *mut usize) = 32; | ^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/atomic_write_na_write_race1.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr index ef5521448676..b67a2bac102d 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.stderr @@ -11,8 +11,8 @@ LL | atomic_ref.store(64, Ordering::SeqCst); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/atomic_write_na_write_race2.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr index da13b62b1cf0..d90b8f528f3c 100644 --- a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr +++ b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.stderr @@ -11,8 +11,8 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/dangling_thread_async_race.rs:LL:CC | LL | / ... spawn(move || { 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 798c6c490b4c..feb35ddcd34c 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 @@ -16,8 +16,8 @@ LL | let _val = *ptr.0; | ^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/dealloc_read_race1.rs:LL:CC | LL | let j2 = spawn(move || { 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 4a9e6e832b8e..f1bd657cc5a8 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 @@ -20,8 +20,8 @@ LL | | std::mem::size_of::(), LL | | std::mem::align_of::(), LL | | ) | |_____________^ - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/dealloc_read_race2.rs:LL:CC | LL | let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr index 8b8cfaf9930c..a07dd0a1a1da 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.stderr @@ -11,8 +11,8 @@ LL | *pointer.load(Ordering::Acquire) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/dealloc_read_race_stack.rs:LL:CC | LL | ... let j1 = spawn(move || { 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 18924d7d65ce..f24830d73fb1 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 @@ -16,8 +16,8 @@ LL | *ptr.0 = 2; | ^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/dealloc_write_race1.rs:LL:CC | LL | let j2 = spawn(move || { 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 2029e0632141..a4712554a087 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 @@ -20,8 +20,8 @@ LL | | std::mem::size_of::(), LL | | std::mem::align_of::(), LL | | ); | |_____________^ - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/dealloc_write_race2.rs:LL:CC | LL | let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr index 3ce6e6ce5661..cc23bc0f611f 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.stderr @@ -11,8 +11,8 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/dealloc_write_race_stack.rs:LL:CC | LL | ... let j1 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr index f9a18008ab75..1cbca79e04a8 100644 --- a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr +++ b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.stderr @@ -11,8 +11,8 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/enable_after_join_to_main.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr index 6caeacfb5e25..7f97fc775ca9 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_alloc_race.stderr @@ -11,8 +11,8 @@ LL | StorageLive(val); | ^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/local_variable_alloc_race.rs:LL:CC | LL | / std::thread::spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr index 5dfa6917e3ba..e9173feb61dd 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_read_race.stderr @@ -11,8 +11,8 @@ LL | let _val = val; | ^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/local_variable_read_race.rs:LL:CC | LL | let t1 = std::thread::spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr b/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr index 2f9e22f66fff..859ade5fb65d 100644 --- a/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/local_variable_write_race.stderr @@ -11,8 +11,8 @@ LL | let mut val: u8 = 0; | ^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/local_variable_write_race.rs:LL:CC | LL | let t1 = std::thread::spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr index 10b5539a5b8c..b74351a5f296 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_first_load.stderr @@ -13,8 +13,8 @@ LL | a16.load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/mixed_size_read_read_write.rs:LL:CC | LL | / s.spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr index 8e37e6161c31..be78189a695d 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_read_write.match_second_load.stderr @@ -13,8 +13,8 @@ LL | a16.load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/mixed_size_read_read_write.rs:LL:CC | LL | / s.spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr index ec86c41cd160..736509cd3a9e 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.read_write.stderr @@ -13,8 +13,8 @@ LL | a8[0].load(Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/mixed_size_read_write.rs:LL:CC | LL | / s.spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr index d4d03b96a3e5..f4aa4cbd933f 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write.write_read.stderr @@ -13,8 +13,8 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/mixed_size_read_write.rs:LL:CC | LL | / s.spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr index 98565708f881..10356419dc1e 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_read_write_read.stderr @@ -19,8 +19,8 @@ LL | | ); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/mixed_size_read_write_read.rs:LL:CC | LL | / ... s.spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr index 9033bc2c922d..6c5ac0ca2118 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.fst.stderr @@ -13,8 +13,8 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/mixed_size_write_write.rs:LL:CC | LL | / s.spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr index b0e771c40b91..7e7461a7a4f6 100644 --- a/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr +++ b/src/tools/miri/tests/fail/data_race/mixed_size_write_write.snd.stderr @@ -13,8 +13,8 @@ LL | a16.store(1, Ordering::SeqCst); = help: see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/mixed_size_write_write.rs:LL:CC | LL | / s.spawn(|| { diff --git a/src/tools/miri/tests/fail/data_race/read_write_race.stderr b/src/tools/miri/tests/fail/data_race/read_write_race.stderr index 1922ce949f6b..f0eae9841bee 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/read_write_race.stderr @@ -11,8 +11,8 @@ LL | let _val = *c.0; | ^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/read_write_race.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr index a6bdac409d9d..703a02508727 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/read_write_race_stack.stderr @@ -11,8 +11,8 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/read_write_race_stack.rs:LL:CC | LL | ... let j1 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr b/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr index 6c77bf6b3d8b..1fb793912b72 100644 --- a/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr +++ b/src/tools/miri/tests/fail/data_race/relax_acquire_race.stderr @@ -11,8 +11,8 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/relax_acquire_race.rs:LL:CC | LL | ... let j3 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race.stderr b/src/tools/miri/tests/fail/data_race/release_seq_race.stderr index 528db7ed2479..8f01b7cdad51 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race.stderr +++ b/src/tools/miri/tests/fail/data_race/release_seq_race.stderr @@ -11,8 +11,8 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/release_seq_race.rs:LL:CC | LL | let j3 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr index 1b2daf8b256b..a7fdf8e219f5 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr +++ b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.stderr @@ -11,8 +11,8 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/release_seq_race_same_thread.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/rmw_race.stderr b/src/tools/miri/tests/fail/data_race/rmw_race.stderr index 21f710e16b0d..8bbd9929517e 100644 --- a/src/tools/miri/tests/fail/data_race/rmw_race.stderr +++ b/src/tools/miri/tests/fail/data_race/rmw_race.stderr @@ -11,8 +11,8 @@ LL | *c.0 = 1; | ^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/rmw_race.rs:LL:CC | LL | ... let j3 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/write_write_race.stderr b/src/tools/miri/tests/fail/data_race/write_write_race.stderr index 112cdb278196..33352a5ded58 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race.stderr +++ b/src/tools/miri/tests/fail/data_race/write_write_race.stderr @@ -11,8 +11,8 @@ LL | *c.0 = 32; | ^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/write_write_race.rs:LL:CC | LL | ... let j2 = spawn(move || { diff --git a/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr b/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr index c70dbb4e619f..a439be859015 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr +++ b/src/tools/miri/tests/fail/data_race/write_write_race_stack.stderr @@ -11,8 +11,8 @@ LL | *pointer.load(Ordering::Acquire) = 3; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/data_race/write_write_race_stack.rs:LL:CC | LL | let j1 = spawn(move || { diff --git a/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr b/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr index 068d4b4f1329..a9a8deb05aae 100644 --- a/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr +++ b/src/tools/miri/tests/fail/enum-set-discriminant-niche-variant-wrong.stderr @@ -6,12 +6,11 @@ LL | SetDiscriminant(*ptr, 1); | = 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 - = note: this is inside `set_discriminant` -note: which got called inside `main` - --> tests/fail/enum-set-discriminant-niche-variant-wrong.rs:LL:CC - | -LL | set_discriminant(&mut v); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: set_discriminant + at tests/fail/enum-set-discriminant-niche-variant-wrong.rs:LL:CC + 1: main + at tests/fail/enum-set-discriminant-niche-variant-wrong.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr index f45f5c26bacb..952f2272f3bf 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr @@ -21,16 +21,11 @@ help: is this argument | LL | unsafe { ptr.write(S(0)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: error occurred inside `callee` - --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC - | -LL | fn callee(x: S, ptr: *mut S) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC - | -LL | Call(_unit = callee(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: callee + at tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC + 1: main + at tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr index 044026ee8ddc..095dc7e1a1fb 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr @@ -30,16 +30,11 @@ help: the protected tag later transitioned to Unique due to a child write LL | unsafe { ptr.write(S(0)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference -note: error occurred inside `callee` - --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC - | -LL | fn callee(x: S, ptr: *mut S) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC - | -LL | Call(_unit = callee(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: callee + at tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC + 1: main + at tests/fail/function_calls/arg_inplace_mutate.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr index b66d13cede1f..22077345243f 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr @@ -6,12 +6,11 @@ LL | unsafe { ptr.read() }; | = 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 - = note: this is inside `change_arg` -note: which got called inside `main` - --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC - | -LL | Call(_unit = change_arg(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: change_arg + at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC + 1: main + at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC Uninitialized memory occurred at ALLOC[0x0..0x4], in this allocation: ALLOC (stack variable, size: 4, align: 4) { diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr index 9dc9adc13ae3..d625d1d1d034 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr @@ -21,16 +21,11 @@ help: is this argument | LL | x.0 = 0; | ^^^^^^^ -note: error occurred inside `change_arg` - --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC - | -LL | fn change_arg(mut x: S, ptr: *mut S) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC - | -LL | Call(_unit = change_arg(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: change_arg + at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC + 1: main + at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr index 0a6c6e615a16..a01c040fe6f8 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr @@ -30,16 +30,11 @@ help: the protected tag later transitioned to Unique due to a child write LL | x.0 = 0; | ^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference -note: error occurred inside `change_arg` - --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC - | -LL | fn change_arg(mut x: S, ptr: *mut S) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC - | -LL | Call(_unit = change_arg(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: change_arg + at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC + 1: main + at tests/fail/function_calls/arg_inplace_observe_during.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr index dd7f52d03f20..3c71934ac63e 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr @@ -14,24 +14,7 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::panicking::panic_with_hook` - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) -note: which got called inside `nounwind` - --> tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC - | -LL | / extern "C-unwind" fn nounwind() { -LL | | panic!(); -LL | | } - | |_^ -note: which got called inside `main` - --> tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC - | -LL | unsafe { nounwind() } - | ^^^^^^^^^^ + = note: stack backtrace: note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr index dd7f52d03f20..3c71934ac63e 100644 --- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr +++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr @@ -14,24 +14,7 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::panicking::panic_with_hook` - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) -note: which got called inside `nounwind` - --> tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC - | -LL | / extern "C-unwind" fn nounwind() { -LL | | panic!(); -LL | | } - | |_^ -note: which got called inside `main` - --> tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC - | -LL | unsafe { nounwind() } - | ^^^^^^^^^^ + = note: stack backtrace: note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr index 32e80ed0e61e..016849a6a336 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.none.stderr @@ -6,12 +6,11 @@ LL | unsafe { ptr.read() }; | = 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 - = note: this is inside `myfun` -note: which got called inside `main` - --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC - | -LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: myfun + at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC + 1: main + at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC Uninitialized memory occurred at ALLOC[0x0..0x4], in this allocation: ALLOC (stack variable, size: 4, align: 4) { diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr index 14c8e5cb8960..73c562c94e95 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.stack.stderr @@ -21,16 +21,11 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique in-place fun | LL | unsafe { ptr.read() }; | ^^^^^^^^^^^^^^^^^^^^^ -note: error occurred inside `myfun` - --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC - | -LL | fn myfun(ptr: *mut i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC - | -LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: myfun + at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC + 1: main + at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr index 2e5b687f90ac..0dc137843c91 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_read.tree.stderr @@ -30,16 +30,11 @@ help: the protected tag later transitioned to Unique due to a child write LL | unsafe { ptr.read() }; | ^^^^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference -note: error occurred inside `myfun` - --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC - | -LL | fn myfun(ptr: *mut i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC - | -LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: myfun + at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC + 1: main + at tests/fail/function_calls/return_pointer_aliasing_read.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr index 63dee06563d1..6654ddc12c29 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.stack.stderr @@ -21,16 +21,11 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique in-place fun | LL | unsafe { ptr.write(0) }; | ^^^^^^^^^^^^^^^^^^^^^^^ -note: error occurred inside `myfun` - --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC - | -LL | fn myfun(ptr: *mut i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC - | -LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: myfun + at tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC + 1: main + at tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr index 80c111d4ddb4..6472dfd4f995 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write.tree.stderr @@ -30,16 +30,11 @@ help: the protected tag later transitioned to Unique due to a child write LL | unsafe { ptr.write(0) }; | ^^^^^^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference -note: error occurred inside `myfun` - --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC - | -LL | fn myfun(ptr: *mut i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC - | -LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: myfun + at tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC + 1: main + at tests/fail/function_calls/return_pointer_aliasing_write.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr index a6129451530a..79f4d2c69f3c 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.stack.stderr @@ -21,16 +21,11 @@ help: was later invalidated at offsets [0x0..0x4] by a Unique in-place fun | LL | become myfun2(ptr) | ^^^^^^^^^^^^^^^^^^ -note: error occurred inside `myfun2` - --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC - | -LL | fn myfun2(ptr: *mut i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC - | -LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: myfun2 + at tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC + 1: main + at tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr index a6fff1c26683..82b898df45b2 100644 --- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr +++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing_write_tail_call.tree.stderr @@ -30,16 +30,11 @@ help: the protected tag later transitioned to Unique due to a child write LL | unsafe { ptr.write(0) }; | ^^^^^^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference -note: error occurred inside `myfun2` - --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC - | -LL | fn myfun2(ptr: *mut i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC - | -LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: myfun2 + at tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC + 1: main + at tests/fail/function_calls/return_pointer_aliasing_write_tail_call.rs:LL:CC = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/function_calls/simd_feature_flag_difference.stderr b/src/tools/miri/tests/fail/function_calls/simd_feature_flag_difference.stderr index ef6decaece35..db7fb1a68790 100644 --- a/src/tools/miri/tests/fail/function_calls/simd_feature_flag_difference.stderr +++ b/src/tools/miri/tests/fail/function_calls/simd_feature_flag_difference.stderr @@ -6,12 +6,11 @@ LL | unsafe { foo(0.0, x) } | = 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 - = note: this is inside `bar` -note: which got called inside `main` - --> tests/fail/function_calls/simd_feature_flag_difference.rs:LL:CC - | -LL | let copy = bar(input); - | ^^^^^^^^^^ + = note: stack backtrace: + 0: bar + at tests/fail/function_calls/simd_feature_flag_difference.rs:LL:CC + 1: main + at tests/fail/function_calls/simd_feature_flag_difference.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr index 697e35a660ca..249eba76c83d 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_data.stderr @@ -6,12 +6,11 @@ LL | RET = PtrMetadata(*p); | = 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 - = note: this is inside `deref_meta` -note: which got called inside `main` - --> tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs:LL:CC - | -LL | let _meta = deref_meta(p.as_ptr().cast()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: deref_meta + at tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs:LL:CC + 1: main + at tests/fail/intrinsics/ptr_metadata_uninit_slice_data.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr index ba711710b41e..371802a7bcf2 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr @@ -18,12 +18,11 @@ LL | RET = PtrMetadata(*p); | = 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 - = note: this is inside `deref_meta` -note: which got called inside `main` - --> tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs:LL:CC - | -LL | let _meta = deref_meta(p.as_ptr().cast()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: deref_meta + at tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs:LL:CC + 1: main + at tests/fail/intrinsics/ptr_metadata_uninit_slice_len.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr index 104e281f2a8e..207e7983aab4 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_thin.stderr @@ -6,12 +6,11 @@ LL | RET = PtrMetadata(*p); | = 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 - = note: this is inside `deref_meta` -note: which got called inside `main` - --> tests/fail/intrinsics/ptr_metadata_uninit_thin.rs:LL:CC - | -LL | let _meta = deref_meta(p.as_ptr()); - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: deref_meta + at tests/fail/intrinsics/ptr_metadata_uninit_thin.rs:LL:CC + 1: main + at tests/fail/intrinsics/ptr_metadata_uninit_thin.rs:LL:CC Uninitialized memory occurred at ALLOC[0xX..0xY], in this allocation: ALLOC DUMP diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr index 619925f28968..6cdcd114d5cf 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr @@ -6,12 +6,11 @@ LL | typed_swap_nonoverlapping(a, b); | = 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 - = note: this is inside `invalid_array` -note: which got called inside `main` - --> tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC - | -LL | invalid_array(); - | ^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: invalid_array + at tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC + 1: main + at tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr index 42bea7dd5e34..223f7430b60a 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr @@ -6,12 +6,11 @@ LL | typed_swap_nonoverlapping(a, b); | = 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 - = note: this is inside `invalid_scalar` -note: which got called inside `main` - --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC - | -LL | invalid_scalar(); - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: invalid_scalar + at tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC + 1: main + at tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr index 13e8c7f9c5ae..59e392085001 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr @@ -6,12 +6,11 @@ LL | typed_swap_nonoverlapping(a, b); | = 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 - = note: this is inside `invalid_scalar` -note: which got called inside `main` - --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC - | -LL | invalid_scalar(); - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: invalid_scalar + at tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC + 1: main + at tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/issue-miri-1112.stderr b/src/tools/miri/tests/fail/issue-miri-1112.stderr index 0fc67c6d4fd9..0c5c6a94baf2 100644 --- a/src/tools/miri/tests/fail/issue-miri-1112.stderr +++ b/src/tools/miri/tests/fail/issue-miri-1112.stderr @@ -6,12 +6,11 @@ LL | let obj = std::mem::transmute::(obj) | = 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 - = note: this is inside `FunnyPointer::from_data_ptr` -note: which got called inside `main` - --> tests/fail/issue-miri-1112.rs:LL:CC - | -LL | let _raw: &FunnyPointer = FunnyPointer::from_data_ptr(&hello, &meta as *const _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: FunnyPointer::from_data_ptr + at tests/fail/issue-miri-1112.rs:LL:CC + 1: main + at tests/fail/issue-miri-1112.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/memleak_rc.stderr b/src/tools/miri/tests/fail/memleak_rc.stderr index f7b0950ef6ce..91097a99117f 100644 --- a/src/tools/miri/tests/fail/memleak_rc.stderr +++ b/src/tools/miri/tests/fail/memleak_rc.stderr @@ -4,12 +4,11 @@ error: memory leaked: ALLOC (Rust heap, SIZE, ALIGN), allocated here: LL | Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value })) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this is inside `std::rc::Rc::>>::new` -note: which got called inside `main` - --> tests/fail/memleak_rc.rs:LL:CC - | -LL | let x = Dummy(Rc::new(RefCell::new(None))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::rc::Rc::new + at RUSTLIB/alloc/src/rc.rs:LL:CC + 1: main + at tests/fail/memleak_rc.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/never_transmute_void.rs b/src/tools/miri/tests/fail/never_transmute_void.rs index ad67b4446165..a2db2ca9db61 100644 --- a/src/tools/miri/tests/fail/never_transmute_void.rs +++ b/src/tools/miri/tests/fail/never_transmute_void.rs @@ -1,6 +1,5 @@ // This should fail even without validation //@compile-flags: -Zmiri-disable-validation -//@require-annotations-for-level: ERROR #![feature(never_type)] #![allow(unused, invalid_value)] @@ -18,5 +17,4 @@ mod m { fn main() { let v = unsafe { std::mem::transmute::<(), m::Void>(()) }; m::f(v); - //~^ NOTE: inside `main` } diff --git a/src/tools/miri/tests/fail/never_transmute_void.stderr b/src/tools/miri/tests/fail/never_transmute_void.stderr index a236d17c49dd..ce65be6ef1b4 100644 --- a/src/tools/miri/tests/fail/never_transmute_void.stderr +++ b/src/tools/miri/tests/fail/never_transmute_void.stderr @@ -6,12 +6,11 @@ LL | match v.0 {} | = 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 - = note: this is inside `m::f` -note: which got called inside `main` - --> tests/fail/never_transmute_void.rs:LL:CC - | -LL | m::f(v); - | ^^^^^^^ + = note: stack backtrace: + 0: m::f + at tests/fail/never_transmute_void.rs:LL:CC + 1: main + at tests/fail/never_transmute_void.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/overlapping_assignment.stderr b/src/tools/miri/tests/fail/overlapping_assignment.stderr index 6bf7fa446598..43e767e97555 100644 --- a/src/tools/miri/tests/fail/overlapping_assignment.stderr +++ b/src/tools/miri/tests/fail/overlapping_assignment.stderr @@ -6,12 +6,11 @@ LL | *ptr1 = *ptr2; | = 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 - = note: this is inside `self_copy` -note: which got called inside `main` - --> tests/fail/overlapping_assignment.rs:LL:CC - | -LL | self_copy(ptr, ptr); - | ^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: self_copy + at tests/fail/overlapping_assignment.rs:LL:CC + 1: main + at tests/fail/overlapping_assignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/abort_unwind.stderr b/src/tools/miri/tests/fail/panic/abort_unwind.stderr index 1f45211c5ee4..d5699fc41dfe 100644 --- a/src/tools/miri/tests/fail/panic/abort_unwind.stderr +++ b/src/tools/miri/tests/fail/panic/abort_unwind.stderr @@ -14,18 +14,7 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::panicking::panic_with_hook` - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) - = note: which got called inside `std::panic::abort_unwind::<{closure@tests/fail/panic/abort_unwind.rs:LL:CC}, ()>` (at RUSTLIB/core/src/panic.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/panic/abort_unwind.rs:LL:CC - | -LL | std::panic::abort_unwind(|| panic!("PANIC!!!")); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/bad_unwind.stderr b/src/tools/miri/tests/fail/panic/bad_unwind.stderr index 06e019bb6978..d47f7b5b10c1 100644 --- a/src/tools/miri/tests/fail/panic/bad_unwind.stderr +++ b/src/tools/miri/tests/fail/panic/bad_unwind.stderr @@ -11,15 +11,17 @@ LL | std::panic::catch_unwind(|| unwind()).unwrap_err(); | = 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 - = note: this is inside closure - = note: which got called inside `std::panicking::catch_unwind::do_call::<{closure@tests/fail/panic/bad_unwind.rs:LL:CC}, ()>` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panicking::catch_unwind::<(), {closure@tests/fail/panic/bad_unwind.rs:LL:CC}>` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panic::catch_unwind::<{closure@tests/fail/panic/bad_unwind.rs:LL:CC}, ()>` (at RUSTLIB/std/src/panic.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/panic/bad_unwind.rs:LL:CC - | -LL | std::panic::catch_unwind(|| unwind()).unwrap_err(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: main::{closure#0} + at tests/fail/panic/bad_unwind.rs:LL:CC + 1: std::panicking::catch_unwind::do_call + at RUSTLIB/std/src/panicking.rs:LL:CC + 2: std::panicking::catch_unwind + at RUSTLIB/std/src/panicking.rs:LL:CC + 3: std::panic::catch_unwind + at RUSTLIB/std/src/panic.rs:LL:CC + 4: main + at tests/fail/panic/bad_unwind.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr index 4beadb6aa647..34a62a09cc3e 100644 --- a/src/tools/miri/tests/fail/panic/double_panic.stderr +++ b/src/tools/miri/tests/fail/panic/double_panic.stderr @@ -17,20 +17,7 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::panicking::panic_with_hook` - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_nounwind_nobacktrace` (at RUSTLIB/core/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_in_cleanup` (at RUSTLIB/core/src/panicking.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/panic/double_panic.rs:LL:CC - | -LL | / fn main() { -LL | | let _foo = Foo; -LL | | panic!("first"); -LL | | } - | |_^ + = note: stack backtrace: note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/no_std.stderr b/src/tools/miri/tests/fail/panic/no_std.stderr index 128dfddc215e..87adb18a7ab9 100644 --- a/src/tools/miri/tests/fail/panic/no_std.stderr +++ b/src/tools/miri/tests/fail/panic/no_std.stderr @@ -6,12 +6,11 @@ error: abnormal termination: the program aborted execution LL | core::intrinsics::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `panic_handler` -note: which got called inside `miri_start` - --> tests/fail/panic/no_std.rs:LL:CC - | -LL | panic!("blarg I am dead") - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: panic_handler + at tests/fail/panic/no_std.rs:LL:CC + 1: miri_start + at RUSTLIB/core/src/panic.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.stderr b/src/tools/miri/tests/fail/panic/panic_abort1.stderr index 57c8ee843b86..4135ceadc539 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort1.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort1.stderr @@ -9,18 +9,23 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::rt::__rust_abort` - = note: which got called inside `panic_abort::__rust_start_panic` (at RUSTLIB/panic_abort/src/lib.rs:LL:CC) - = note: which got called inside `std::panicking::rust_panic` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panicking::panic_with_hook` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/panic/panic_abort1.rs:LL:CC - | -LL | std::panic!("panicking from libstd"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::rt::__rust_abort + at RUSTLIB/std/src/rt.rs:LL:CC + 1: panic_abort::__rust_start_panic + at RUSTLIB/panic_abort/src/lib.rs:LL:CC + 2: std::panicking::rust_panic + at RUSTLIB/std/src/panicking.rs:LL:CC + 3: std::panicking::panic_with_hook + at RUSTLIB/std/src/panicking.rs:LL:CC + 4: std::panicking::panic_handler::{closure#0} + at RUSTLIB/std/src/panicking.rs:LL:CC + 5: std::sys::backtrace::__rust_end_short_backtrace + at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + 6: std::panicking::panic_handler + at RUSTLIB/std/src/panicking.rs:LL:CC + 7: main + at RUSTLIB/core/src/panic.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.stderr b/src/tools/miri/tests/fail/panic/panic_abort2.stderr index 7c145634a102..5b485604037c 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort2.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort2.stderr @@ -9,18 +9,23 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::rt::__rust_abort` - = note: which got called inside `panic_abort::__rust_start_panic` (at RUSTLIB/panic_abort/src/lib.rs:LL:CC) - = note: which got called inside `std::panicking::rust_panic` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panicking::panic_with_hook` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/panic/panic_abort2.rs:LL:CC - | -LL | std::panic!("{}-panicking from libstd", 42); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::rt::__rust_abort + at RUSTLIB/std/src/rt.rs:LL:CC + 1: panic_abort::__rust_start_panic + at RUSTLIB/panic_abort/src/lib.rs:LL:CC + 2: std::panicking::rust_panic + at RUSTLIB/std/src/panicking.rs:LL:CC + 3: std::panicking::panic_with_hook + at RUSTLIB/std/src/panicking.rs:LL:CC + 4: std::panicking::panic_handler::{closure#0} + at RUSTLIB/std/src/panicking.rs:LL:CC + 5: std::sys::backtrace::__rust_end_short_backtrace + at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + 6: std::panicking::panic_handler + at RUSTLIB/std/src/panicking.rs:LL:CC + 7: main + at RUSTLIB/core/src/panic.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.stderr b/src/tools/miri/tests/fail/panic/panic_abort3.stderr index 71877122b625..e4179f93f931 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort3.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort3.stderr @@ -9,18 +9,23 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::rt::__rust_abort` - = note: which got called inside `panic_abort::__rust_start_panic` (at RUSTLIB/panic_abort/src/lib.rs:LL:CC) - = note: which got called inside `std::panicking::rust_panic` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panicking::panic_with_hook` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/panic/panic_abort3.rs:LL:CC - | -LL | core::panic!("panicking from libcore"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::rt::__rust_abort + at RUSTLIB/std/src/rt.rs:LL:CC + 1: panic_abort::__rust_start_panic + at RUSTLIB/panic_abort/src/lib.rs:LL:CC + 2: std::panicking::rust_panic + at RUSTLIB/std/src/panicking.rs:LL:CC + 3: std::panicking::panic_with_hook + at RUSTLIB/std/src/panicking.rs:LL:CC + 4: std::panicking::panic_handler::{closure#0} + at RUSTLIB/std/src/panicking.rs:LL:CC + 5: std::sys::backtrace::__rust_end_short_backtrace + at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + 6: std::panicking::panic_handler + at RUSTLIB/std/src/panicking.rs:LL:CC + 7: main + at RUSTLIB/core/src/panic.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.stderr b/src/tools/miri/tests/fail/panic/panic_abort4.stderr index 2b4c6bea5605..d2e50b87068f 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort4.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort4.stderr @@ -9,18 +9,23 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::rt::__rust_abort` - = note: which got called inside `panic_abort::__rust_start_panic` (at RUSTLIB/panic_abort/src/lib.rs:LL:CC) - = note: which got called inside `std::panicking::rust_panic` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panicking::panic_with_hook` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/panic/panic_abort4.rs:LL:CC - | -LL | core::panic!("{}-panicking from libcore", 42); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::rt::__rust_abort + at RUSTLIB/std/src/rt.rs:LL:CC + 1: panic_abort::__rust_start_panic + at RUSTLIB/panic_abort/src/lib.rs:LL:CC + 2: std::panicking::rust_panic + at RUSTLIB/std/src/panicking.rs:LL:CC + 3: std::panicking::panic_with_hook + at RUSTLIB/std/src/panicking.rs:LL:CC + 4: std::panicking::panic_handler::{closure#0} + at RUSTLIB/std/src/panicking.rs:LL:CC + 5: std::sys::backtrace::__rust_end_short_backtrace + at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + 6: std::panicking::panic_handler + at RUSTLIB/std/src/panicking.rs:LL:CC + 7: main + at RUSTLIB/core/src/panic.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.rs b/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.rs index 93ad42ea1cce..c25684af5090 100644 --- a/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.rs +++ b/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.rs @@ -4,6 +4,7 @@ //@compile-flags: -Zmiri-backtrace=full //@normalize-stderr-test: "'main'|''" -> "$$NAME" //@normalize-stderr-test: ".*(note|-->|\|).*\n" -> "" +//@normalize-stderr-test: "\n *\d+:.*\n *at .*" -> "" pub struct NoisyDrop {} diff --git a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs index a207d3923124..32fd8318f796 100644 --- a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs +++ b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs @@ -1,7 +1,8 @@ //@error-in-other-file: aborted execution // Backtraces vary wildly between platforms, we have to normalize away almost the entire thing //@normalize-stderr-test: "'main'|''" -> "$$NAME" -//@normalize-stderr-test: ".*(note|-->|:::|\|).*\n" -> "" +//@normalize-stderr-test: ".*(note|-->|\|).*\n" -> "" +//@normalize-stderr-test: "\n *\d+:.*\n *at .*" -> "" pub struct NoisyDrop {} diff --git a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr index 39263a8d61cc..ec243f114af0 100644 --- a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr +++ b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr @@ -3,6 +3,7 @@ thread $NAME ($TID) panicked at tests/fail/panic/tls_macro_drop_panic.rs:LL:CC: ow fatal runtime error: thread local panicked on drop, aborting error: abnormal termination: the program aborted execution + ::: RUSTLIB/std/src/sys/thread_local/PLATFORM.rs:LL:CC error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr b/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr index 6af86ffdb2bd..fc9f394a568c 100644 --- a/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr +++ b/src/tools/miri/tests/fail/provenance/provenance_transmute.stderr @@ -6,12 +6,11 @@ LL | let _val = *left_ptr; | = 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 - = note: this is inside `deref` -note: which got called inside `main` - --> tests/fail/provenance/provenance_transmute.rs:LL:CC - | -LL | deref(ptr1, ptr2.with_addr(ptr1.addr())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: deref + at tests/fail/provenance/provenance_transmute.rs:LL:CC + 1: main + at tests/fail/provenance/provenance_transmute.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr index 7fc54636b552..7275be1343ac 100644 --- a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr +++ b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr @@ -12,15 +12,7 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::panicking::panic_with_hook` - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/ptr_swap_nonoverlapping.rs:LL:CC - | -LL | std::ptr::swap_nonoverlapping(ptr, ptr, 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/ctor_ub.stderr b/src/tools/miri/tests/fail/shims/ctor_ub.stderr index ab8a8f633638..e89f3b3c9059 100644 --- a/src/tools/miri/tests/fail/shims/ctor_ub.stderr +++ b/src/tools/miri/tests/fail/shims/ctor_ub.stderr @@ -6,8 +6,7 @@ LL | std::hint::unreachable_unchecked() | = 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 - = note: this is inside `ctor` -note: which got called indirectly due to this code +note: the current function got called indirectly due to this code --> tests/fail/shims/ctor_ub.rs:LL:CC | LL | static $ident: unsafe extern "C" fn() = $ctor; diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr index eb7f70a351ad..af55ccfe5e67 100644 --- a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr +++ b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr @@ -6,22 +6,31 @@ LL | let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode a | = help: set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation; = help: or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning - = note: this is inside closure - = note: which got called inside `std::sys::pal::PLATFORM::cvt_r::` (at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC) - = note: which got called inside `std::sys::fs::PLATFORM::File::open_c` (at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC) - = note: which got called inside closure (at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC) - = note: which got called inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack::` (at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC) - = note: which got called inside `std::sys::pal::PLATFORM::small_c_string::run_with_cstr::` (at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC) - = note: which got called inside `std::sys::pal::PLATFORM::small_c_string::run_path_with_cstr::` (at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC) - = note: which got called inside `std::sys::fs::PLATFORM::File::open` (at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC) - = note: which got called inside `std::fs::OpenOptions::_open` (at RUSTLIB/std/src/fs.rs:LL:CC) - = note: which got called inside `std::fs::OpenOptions::open::<&std::path::Path>` (at RUSTLIB/std/src/fs.rs:LL:CC) - = note: which got called inside `std::fs::File::open::<&str>` (at RUSTLIB/std/src/fs.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/shims/fs/isolated_file.rs:LL:CC - | -LL | let _file = std::fs::File::open("file.txt").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::sys::fs::PLATFORM::File::open_c::{closure#0} + at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC + 1: std::sys::pal::PLATFORM::cvt_r + at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC + 2: std::sys::fs::PLATFORM::File::open_c + at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC + 3: std::sys::fs::PLATFORM::File::open::{closure#0} + at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC + 4: std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack + at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + 5: std::sys::pal::PLATFORM::small_c_string::run_with_cstr + at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + 6: std::sys::pal::PLATFORM::small_c_string::run_path_with_cstr + at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + 7: std::sys::fs::PLATFORM::File::open + at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC + 8: std::fs::OpenOptions::_open + at RUSTLIB/std/src/fs.rs:LL:CC + 9: std::fs::OpenOptions::open + at RUSTLIB/std/src/fs.rs:LL:CC + 10: std::fs::File::open + at RUSTLIB/std/src/fs.rs:LL:CC + 11: main + at tests/fail/shims/fs/isolated_file.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/isolated_stdin.stderr b/src/tools/miri/tests/fail/shims/isolated_stdin.stderr index 58f0957a668c..c478f1412bbf 100644 --- a/src/tools/miri/tests/fail/shims/isolated_stdin.stderr +++ b/src/tools/miri/tests/fail/shims/isolated_stdin.stderr @@ -5,10 +5,6 @@ error: unsupported operation: `read` from stdin not available when isolation is | = help: set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation; = help: or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning -note: which got called inside `main` - --> tests/fail/shims/isolated_stdin.rs:LL:CC - | - | ^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr index 84051e688aab..266f9247b98d 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr @@ -6,28 +6,21 @@ LL | self.1.deallocate(From::from(ptr.cast()), layout); | = 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 - = note: this is inside ` as std::ops::Drop>::drop` - = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) -note: which got called inside closure - --> tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC - | -LL | drop(unsafe { Box::from_raw(raw) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: which got called inside `<{closure@tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC} as std::ops::FnOnce<(&mut i32,)>>::call_once - shim` (at RUSTLIB/core/src/ops/function.rs:LL:CC) -note: which got called inside `inner` - --> tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC - | -LL | f(x) - | ^^^^ -note: which got called inside `main` - --> tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC - | -LL | / inner(Box::leak(Box::new(0)), |x| { -LL | | let raw = x as *mut _; -LL | | drop(unsafe { Box::from_raw(raw) }); -LL | | }); - | |______^ + = note: stack backtrace: + 0: as std::ops::Drop>::drop + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::mem::drop + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 3: main::{closure#0} + at tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC + 4: <{closure@tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC} as std::ops::FnOnce<(&mut i32,)>>::call_once - shim + at RUSTLIB/core/src/ops/function.rs:LL:CC + 5: inner + at tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC + 6: main + at tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr index 7f4899bb0d6f..027fe239319a 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr @@ -16,18 +16,15 @@ help: is this argument | LL | core::ptr::drop_in_place(x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: error occurred inside `::drop` - --> tests/fail/stacked_borrows/drop_in_place_protector.rs:LL:CC - | -LL | fn drop(&mut self) { - | ^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::ptr::drop_in_place:: - shim(Some(HasDrop))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::ptr::drop_in_place::<(HasDrop, u8)> - shim(Some((HasDrop, u8)))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/stacked_borrows/drop_in_place_protector.rs:LL:CC - | -LL | core::ptr::drop_in_place(x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: ::drop + at tests/fail/stacked_borrows/drop_in_place_protector.rs:LL:CC + 1: std::ptr::drop_in_place - shim(Some(HasDrop)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::ptr::drop_in_place - shim(Some((HasDrop, u8))) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 3: main + at tests/fail/stacked_borrows/drop_in_place_protector.rs:LL:CC = note: this error originates in the macro `core::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr index 11b3e49b852e..cffa17556950 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr @@ -13,18 +13,11 @@ help: was created by a SharedReadOnly retag at offsets [0x0..0x1] | LL | let x = core::ptr::addr_of!(x); | ^^^^^^^^^^^^^^^^^^^^^^ -note: error occurred inside `std::ptr::drop_in_place:: - shim(None)` - --> RUSTLIB/core/src/ptr/mod.rs:LL:CC - | -LL | / pub const unsafe fn drop_in_place(to_drop: *mut T) -LL | | where -LL | | T: [const] Destruct, - | |________________________^ -note: which got called inside `main` - --> tests/fail/stacked_borrows/drop_in_place_retag.rs:LL:CC - | -LL | core::ptr::drop_in_place(x.cast_mut()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::ptr::drop_in_place - shim(None) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 1: main + at tests/fail/stacked_borrows/drop_in_place_retag.rs:LL:CC = note: this error originates in the macro `core::ptr::addr_of` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr index 17abcf0a4643..336dff598b42 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/invalidate_against_protector1.stderr @@ -16,16 +16,11 @@ help: is this argument | LL | fn inner(x: *mut i32, _y: &mut i32) { | ^^ -note: error occurred inside `inner` - --> tests/fail/stacked_borrows/invalidate_against_protector1.rs:LL:CC - | -LL | fn inner(x: *mut i32, _y: &mut i32) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/stacked_borrows/invalidate_against_protector1.rs:LL:CC - | -LL | inner(xraw, xref); - | ^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: inner + at tests/fail/stacked_borrows/invalidate_against_protector1.rs:LL:CC + 1: main + at tests/fail/stacked_borrows/invalidate_against_protector1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr b/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr index a13ff30deda7..4f6045c7c16a 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/pointer_smuggling.stderr @@ -16,16 +16,11 @@ help: was later invalidated at offsets [0x0..0x1] by a write access | LL | *val = 2; // this invalidates any raw ptrs `fun1` might have created. | ^^^^^^^^ -note: error occurred inside `fun2` - --> tests/fail/stacked_borrows/pointer_smuggling.rs:LL:CC - | -LL | fn fun2() { - | ^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/stacked_borrows/pointer_smuggling.rs:LL:CC - | -LL | fun2(); // if they now use a raw ptr they break our reference - | ^^^^^^ + = note: stack backtrace: + 0: fun2 + at tests/fail/stacked_borrows/pointer_smuggling.rs:LL:CC + 1: main + at tests/fail/stacked_borrows/pointer_smuggling.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr index f50b05712ee2..7f112a2e85b6 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_protected_read.stderr @@ -14,8 +14,8 @@ LL | unsafe { ptr.0.read() }; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/stacked_borrows/retag_data_race_protected_read.rs:LL:CC | LL | let t = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr index 67b1cdab911a..c162bee0a672 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stderr @@ -14,17 +14,13 @@ LL | let _r = &*p; = help: therefore from the perspective of data races, a retag has the same implications as a read or write = 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 -note: error occurred on thread `unnamed-ID`, inside `thread_2` - --> tests/fail/stacked_borrows/retag_data_race_read.rs:LL:CC - | -LL | fn thread_2(p: SendPtr) { - | ^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside closure - --> tests/fail/stacked_borrows/retag_data_race_read.rs:LL:CC - | -LL | let t2 = std::thread::spawn(move || thread_2(p)); - | ^^^^^^^^^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: thread_2 + at tests/fail/stacked_borrows/retag_data_race_read.rs:LL:CC + 1: main::{closure#1} + at tests/fail/stacked_borrows/retag_data_race_read.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/fail/stacked_borrows/retag_data_race_read.rs:LL:CC | LL | let t2 = std::thread::spawn(move || thread_2(p)); diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr index 9148f5ae817c..88dfd1ec9db9 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut.stderr @@ -16,16 +16,11 @@ help: was later invalidated at offsets [0x0..0x8] by a read access | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ -note: error occurred inside `foo` - --> tests/fail/stacked_borrows/return_invalid_mut.rs:LL:CC - | -LL | fn foo(x: &mut (i32, i32)) -> &mut i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/stacked_borrows/return_invalid_mut.rs:LL:CC - | -LL | foo(&mut (1, 2)); - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/stacked_borrows/return_invalid_mut.rs:LL:CC + 1: main + at tests/fail/stacked_borrows/return_invalid_mut.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr index 6cce7f9f246e..5ccb09c7fd84 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_option.stderr @@ -19,16 +19,11 @@ help: was later invalidated at offsets [0x0..0x8] by a read access | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ -note: error occurred inside `foo` - --> tests/fail/stacked_borrows/return_invalid_mut_option.rs:LL:CC - | -LL | fn foo(x: &mut (i32, i32)) -> Option<&mut i32> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/stacked_borrows/return_invalid_mut_option.rs:LL:CC - | -LL | match foo(&mut (1, 2)) { - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/stacked_borrows/return_invalid_mut_option.rs:LL:CC + 1: main + at tests/fail/stacked_borrows/return_invalid_mut_option.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr index 37d18f122b68..eb68a637c229 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/return_invalid_mut_tuple.stderr @@ -19,16 +19,11 @@ help: was later invalidated at offsets [0x0..0x8] by a read access | LL | let _val = unsafe { *xraw }; // invalidate xref | ^^^^^ -note: error occurred inside `foo` - --> tests/fail/stacked_borrows/return_invalid_mut_tuple.rs:LL:CC - | -LL | fn foo(x: &mut (i32, i32)) -> (&mut i32,) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/stacked_borrows/return_invalid_mut_tuple.rs:LL:CC - | -LL | foo(&mut (1, 2)).0; - | ^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/stacked_borrows/return_invalid_mut_tuple.rs:LL:CC + 1: main + at tests/fail/stacked_borrows/return_invalid_mut_tuple.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr index 00dd2999f540..c7e471f570c8 100644 --- a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr +++ b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr @@ -6,19 +6,33 @@ LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | = 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 - = note: this is inside `>::call_once - shim(fn())` - = note: which got called inside `std::sys::backtrace::__rust_begin_short_backtrace::` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside closure (at RUSTLIB/std/src/rt.rs:LL:CC) - = note: which got called inside `std::ops::function::impls:: for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` (at RUSTLIB/core/src/ops/function.rs:LL:CC) - = note: which got called inside `std::panicking::catch_unwind::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panicking::catch_unwind:: i32 + std::marker::Sync + std::panic::RefUnwindSafe>` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` (at RUSTLIB/std/src/panic.rs:LL:CC) - = note: which got called inside closure (at RUSTLIB/std/src/rt.rs:LL:CC) - = note: which got called inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panicking::catch_unwind::` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` (at RUSTLIB/std/src/panic.rs:LL:CC) - = note: which got called inside `std::rt::lang_start_internal` (at RUSTLIB/std/src/rt.rs:LL:CC) - = note: which got called inside `std::rt::lang_start::<()>` (at RUSTLIB/std/src/rt.rs:LL:CC) + = note: stack backtrace: + 0: >::call_once - shim(fn()) + at RUSTLIB/core/src/ops/function.rs:LL:CC + 1: std::sys::backtrace::__rust_begin_short_backtrace + at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + 2: std::rt::lang_start::{closure#0} + at RUSTLIB/std/src/rt.rs:LL:CC + 3: std::ops::function::impls::call_once + at RUSTLIB/core/src/ops/function.rs:LL:CC + 4: std::panicking::catch_unwind::do_call + at RUSTLIB/std/src/panicking.rs:LL:CC + 5: std::panicking::catch_unwind + at RUSTLIB/std/src/panicking.rs:LL:CC + 6: std::panic::catch_unwind + at RUSTLIB/std/src/panic.rs:LL:CC + 7: std::rt::lang_start_internal::{closure#0} + at RUSTLIB/std/src/rt.rs:LL:CC + 8: std::panicking::catch_unwind::do_call + at RUSTLIB/std/src/panicking.rs:LL:CC + 9: std::panicking::catch_unwind + at RUSTLIB/std/src/panicking.rs:LL:CC + 10: std::panic::catch_unwind + at RUSTLIB/std/src/panic.rs:LL:CC + 11: std::rt::lang_start_internal + at RUSTLIB/std/src/rt.rs:LL:CC + 12: std::rt::lang_start + at RUSTLIB/std/src/rt.rs:LL:CC error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr b/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr index a48673fb4b23..1577cceae594 100644 --- a/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr +++ b/src/tools/miri/tests/fail/tail_calls/dangling-local-var.stderr @@ -16,16 +16,11 @@ help: ALLOC was deallocated here: | LL | f(std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^ -note: error occurred inside `g` - --> tests/fail/tail_calls/dangling-local-var.rs:LL:CC - | -LL | fn g(x: *const i32) { - | ^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tail_calls/dangling-local-var.rs:LL:CC - | -LL | f(std::ptr::null()); - | ^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: g + at tests/fail/tail_calls/dangling-local-var.rs:LL:CC + 1: main + at tests/fail/tail_calls/dangling-local-var.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/terminate-terminator.stderr b/src/tools/miri/tests/fail/terminate-terminator.stderr index 7d8ae128b5d6..6c38de9b0314 100644 --- a/src/tools/miri/tests/fail/terminate-terminator.stderr +++ b/src/tools/miri/tests/fail/terminate-terminator.stderr @@ -16,30 +16,7 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::panicking::panic_with_hook` - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) -note: which got called inside `has_cleanup` - --> tests/fail/terminate-terminator.rs:LL:CC - | -LL | / fn has_cleanup() { -LL | | let _f = Foo; -LL | | panic!(); -LL | | } - | |_^ -note: which got called inside `panic_abort` - --> tests/fail/terminate-terminator.rs:LL:CC - | -LL | has_cleanup(); - | ^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/terminate-terminator.rs:LL:CC - | -LL | panic_abort(); - | ^^^^^^^^^^^^^ + = note: stack backtrace: note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tls_macro_leak.stderr b/src/tools/miri/tests/fail/tls_macro_leak.stderr index c3029bb5b4de..3f8240f44547 100644 --- a/src/tools/miri/tests/fail/tls_macro_leak.stderr +++ b/src/tools/miri/tests/fail/tls_macro_leak.stderr @@ -4,16 +4,15 @@ error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: LL | cell.set(Some(Box::leak(Box::new(123)))); | ^^^^^^^^^^^^^ | - = note: this is inside closure - = note: which got called inside `std::thread::LocalKey::>>::try_with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` (at RUSTLIB/std/src/thread/local.rs:LL:CC) - = note: which got called inside `std::thread::LocalKey::>>::with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` (at RUSTLIB/std/src/thread/local.rs:LL:CC) -note: which got called inside closure - --> tests/fail/tls_macro_leak.rs:LL:CC - | -LL | / TLS.with(|cell| { -LL | | cell.set(Some(Box::leak(Box::new(123)))); -LL | | }); - | |__________^ + = note: stack backtrace: + 0: main::{closure#0}::{closure#0} + at tests/fail/tls_macro_leak.rs:LL:CC + 1: std::thread::LocalKey::>>::try_with + at RUSTLIB/std/src/thread/local.rs:LL:CC + 2: std::thread::LocalKey::>>::with + at RUSTLIB/std/src/thread/local.rs:LL:CC + 3: main::{closure#0} + at tests/fail/tls_macro_leak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/outside-range.stderr b/src/tools/miri/tests/fail/tree_borrows/outside-range.stderr index e504f8dde717..a51cf50640ba 100644 --- a/src/tools/miri/tests/fail/tree_borrows/outside-range.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/outside-range.stderr @@ -19,16 +19,11 @@ help: the protected tag was created here, in the initial state Reserved | LL | unsafe fn stuff(x: &mut u8, y: *mut u8) { | ^ -note: error occurred inside `stuff` - --> tests/fail/tree_borrows/outside-range.rs:LL:CC - | -LL | unsafe fn stuff(x: &mut u8, y: *mut u8) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/outside-range.rs:LL:CC - | -LL | stuff(&mut *raw, raw); - | ^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: stuff + at tests/fail/tree_borrows/outside-range.rs:LL:CC + 1: main + at tests/fail/tree_borrows/outside-range.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr b/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr index 48527fedcc35..029b0a56f305 100644 --- a/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/pass_invalid_mut.stderr @@ -30,16 +30,11 @@ help: the conflicting tag later transitioned to Frozen due to a foreign re LL | let _val = unsafe { *xraw }; // invalidate xref for writing | ^^^^^ = help: this transition corresponds to a loss of write permissions -note: error occurred inside `foo` - --> tests/fail/tree_borrows/pass_invalid_mut.rs:LL:CC - | -LL | fn foo(nope: &mut i32) { - | ^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/pass_invalid_mut.rs:LL:CC - | -LL | foo(xref); - | ^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/tree_borrows/pass_invalid_mut.rs:LL:CC + 1: main + at tests/fail/tree_borrows/pass_invalid_mut.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.stderr b/src/tools/miri/tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.stderr index 40a3989c2dc4..693afb133967 100644 --- a/src/tools/miri/tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.stderr @@ -18,16 +18,11 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | do_something(*orig_ptr); | ^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit -note: error occurred inside `access_after_sub_1` - --> tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.rs:LL:CC - | -LL | unsafe fn access_after_sub_1(x: &mut u8, orig_ptr: *mut u8) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.rs:LL:CC - | -LL | access_after_sub_1(&mut *(foo as *mut u8).byte_add(1), orig_ptr); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: access_after_sub_1 + at tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.rs:LL:CC + 1: main + at tests/fail/tree_borrows/repeated_foreign_read_lazy_conflicted.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr index 8effbe30dd6a..29397a8fd0bc 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr @@ -29,16 +29,11 @@ help: the protected tag was created here, in the initial state Reserved | LL | unsafe fn write_second(x: &mut UnsafeCell, y: *mut u8) { | ^ -note: error occurred inside `main::write_second` - --> tests/fail/tree_borrows/reserved/cell-protected-write.rs:LL:CC - | -LL | unsafe fn write_second(x: &mut UnsafeCell, y: *mut u8) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/reserved/cell-protected-write.rs:LL:CC - | -LL | write_second(x, y); - | ^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: main::write_second + at tests/fail/tree_borrows/reserved/cell-protected-write.rs:LL:CC + 1: main + at tests/fail/tree_borrows/reserved/cell-protected-write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr b/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr index 1bc337eb1e7a..3bddd2ce1de6 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.stderr @@ -29,16 +29,11 @@ help: the protected tag was created here, in the initial state Reserved | LL | unsafe fn write_second(x: &mut u8, y: *mut u8) { | ^ -note: error occurred inside `main::write_second` - --> tests/fail/tree_borrows/reserved/int-protected-write.rs:LL:CC - | -LL | unsafe fn write_second(x: &mut u8, y: *mut u8) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/reserved/int-protected-write.rs:LL:CC - | -LL | write_second(x, y); - | ^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: main::write_second + at tests/fail/tree_borrows/reserved/int-protected-write.rs:LL:CC + 1: main + at tests/fail/tree_borrows/reserved/int-protected-write.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr index 3567340f2202..619e707f36f7 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.with.stderr @@ -32,8 +32,8 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *x = 64; | ^^^^^^^ = help: this transition corresponds to a loss of read and write permissions - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/tree_borrows/reservedim_spurious_write.rs:LL:CC | LL | let thread_2 = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr index a28730abd953..2f14900e43e7 100644 --- a/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/reservedim_spurious_write.without.stderr @@ -32,8 +32,8 @@ help: the accessed tag later transitioned to Disabled due to a protector r LL | } | ^ = help: this transition corresponds to a loss of read and write permissions - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/tree_borrows/reservedim_spurious_write.rs:LL:CC | LL | let thread_2 = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr b/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr index 9e20ec238ed8..12c163aa8754 100644 --- a/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/spurious_read.stderr @@ -31,17 +31,13 @@ help: the accessed tag later transitioned to Reserved (conflicted) due to LL | } | ^ = help: this transition corresponds to a temporary loss of write permissions until function exit -note: error occurred on thread `unnamed-ID`, inside `retagx_retagy_retx_writey_rety::{closure#1}::as_mut` - --> tests/fail/tree_borrows/spurious_read.rs:LL:CC - | -LL | fn as_mut(y: &mut u8, b: (usize, Arc)) -> *mut u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside closure - --> tests/fail/tree_borrows/spurious_read.rs:LL:CC - | -LL | let _y = as_mut(unsafe { &mut *ptr.0 }, b.clone()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: retagx_retagy_retx_writey_rety::{closure#1}::as_mut + at tests/fail/tree_borrows/spurious_read.rs:LL:CC + 1: retagx_retagy_retx_writey_rety::{closure#1} + at tests/fail/tree_borrows/spurious_read.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/fail/tree_borrows/spurious_read.rs:LL:CC | LL | let thread_y = thread::spawn(move || { diff --git a/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr index 9545ebf39a27..4abaeb66e527 100644 --- a/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr @@ -18,31 +18,21 @@ help: the strongly protected tag was created here, in the initial state Re | LL | fn inner(x: &mut i32, f: fn(*mut i32)) { | ^ -note: error occurred inside ` as std::ops::Drop>::drop` - --> RUSTLIB/alloc/src/boxed.rs:LL:CC - | -LL | fn drop(&mut self) { - | ^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) -note: which got called inside closure - --> tests/fail/tree_borrows/strongly-protected.rs:LL:CC - | -LL | drop(unsafe { Box::from_raw(raw) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: which got called inside `<{closure@tests/fail/tree_borrows/strongly-protected.rs:LL:CC} as std::ops::FnOnce<(*mut i32,)>>::call_once - shim` (at RUSTLIB/core/src/ops/function.rs:LL:CC) -note: which got called inside `inner` - --> tests/fail/tree_borrows/strongly-protected.rs:LL:CC - | -LL | f(x) - | ^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/strongly-protected.rs:LL:CC - | -LL | / inner(Box::leak(Box::new(0)), |raw| { -LL | | drop(unsafe { Box::from_raw(raw) }); -LL | | }); - | |______^ + = note: stack backtrace: + 0: as std::ops::Drop>::drop + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::mem::drop + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 3: main::{closure#0} + at tests/fail/tree_borrows/strongly-protected.rs:LL:CC + 4: <{closure@tests/fail/tree_borrows/strongly-protected.rs:LL:CC} as std::ops::FnOnce<(*mut i32,)>>::call_once - shim + at RUSTLIB/core/src/ops/function.rs:LL:CC + 5: inner + at tests/fail/tree_borrows/strongly-protected.rs:LL:CC + 6: main + at tests/fail/tree_borrows/strongly-protected.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr b/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr index 3db6dab3167b..c27db19cd3e9 100644 --- a/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.stderr @@ -18,16 +18,11 @@ help: the conflicting tag was created here, in the initial state Frozen | LL | let intermediary = &root; | ^^^^^ -note: error occurred inside `write_to_mut` - --> tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC - | -LL | fn write_to_mut(m: &mut u8, other_ptr: *const u8) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC - | -LL | write_to_mut(data, core::ptr::addr_of!(root)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: write_to_mut + at tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC + 1: main + at tests/fail/tree_borrows/subtree_traversal_skipping_diagnostics.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr index d61fe47a871b..28deb09664c7 100644 --- a/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protected_wildcard.stderr @@ -23,16 +23,11 @@ help: the protected tag was created here, in the initial state Reserved | LL | let mut protect = |_arg: &mut u32| { | ^^^^ -note: error occurred inside closure - --> tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC - | -LL | let mut protect = |_arg: &mut u32| { - | ^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC - | -LL | protect(wild_ref); - | ^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: main::{closure#0} + at tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC + 1: main + at tests/fail/tree_borrows/wildcard/protected_wildcard.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr index cd797cdc0c79..dce29e63583e 100644 --- a/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr @@ -7,12 +7,11 @@ LL | unsafe { *wild = 4 }; = 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: there are no exposed tags which may perform this access here - = note: this is inside closure -note: which got called inside `main` - --> tests/fail/tree_borrows/wildcard/protector_conflicted.rs:LL:CC - | -LL | protect(ref1); - | ^^^^^^^^^^^^^ + = note: stack backtrace: + 0: main::{closure#0} + at tests/fail/tree_borrows/wildcard/protector_conflicted.rs:LL:CC + 1: main + at tests/fail/tree_borrows/wildcard/protector_conflicted.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr index bcc6b5f5b879..89d1f8ca556d 100644 --- a/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr @@ -18,31 +18,21 @@ help: the strongly protected tag was created here, in the initial state Re | LL | fn inner(x: &mut i32, f: fn(usize)) { | ^ -note: error occurred inside ` as std::ops::Drop>::drop` - --> RUSTLIB/alloc/src/boxed.rs:LL:CC - | -LL | fn drop(&mut self) { - | ^^^^^^^^^^^^^^^^^^ - = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) -note: which got called inside closure - --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC - | -LL | drop(unsafe { Box::from_raw(raw as *mut i32) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: which got called inside `<{closure@tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC} as std::ops::FnOnce<(usize,)>>::call_once - shim` (at RUSTLIB/core/src/ops/function.rs:LL:CC) -note: which got called inside `inner` - --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC - | -LL | f(x as *mut i32 as usize) - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC - | -LL | / inner(Box::leak(Box::new(0)), |raw| { -LL | | drop(unsafe { Box::from_raw(raw as *mut i32) }); -LL | | }); - | |______^ + = note: stack backtrace: + 0: as std::ops::Drop>::drop + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::mem::drop + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 3: main::{closure#0} + at tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC + 4: <{closure@tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC} as std::ops::FnOnce<(usize,)>>::call_once - shim + at RUSTLIB/core/src/ops/function.rs:LL:CC + 5: inner + at tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC + 6: main + at tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr b/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr index 11d148bc872e..e44f306f7fad 100644 --- a/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/write-during-2phase.stderr @@ -18,22 +18,11 @@ help: the accessed tag later transitioned to Disabled due to a foreign wri LL | *alias = 42; | ^^^^^^^^^^^ = help: this transition corresponds to a loss of read and write permissions -note: error occurred inside `Foo::add` - --> tests/fail/tree_borrows/write-during-2phase.rs:LL:CC - | -LL | fn add(&mut self, n: u64) -> u64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside `main` - --> tests/fail/tree_borrows/write-during-2phase.rs:LL:CC - | -LL | let res = f.add(unsafe { - | _______________^ -LL | | // This is the access at fault, but it's not immediately apparent because -LL | | // the reference that got invalidated is not under a Protector. -LL | | *alias = 42; -LL | | 0 -LL | | }); - | |______^ + = note: stack backtrace: + 0: Foo::add + at tests/fail/tree_borrows/write-during-2phase.rs:LL:CC + 1: main + at tests/fail/tree_borrows/write-during-2phase.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr index 6fb62b766440..2b98a2f99cf9 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr @@ -8,12 +8,11 @@ LL | | T: [const] Destruct, | = 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 - = note: this is inside `std::ptr::drop_in_place:: - shim(Some(PartialDrop))` -note: which got called inside `main` - --> tests/fail/unaligned_pointers/drop_in_place.rs:LL:CC - | -LL | core::ptr::drop_in_place(p); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: std::ptr::drop_in_place - shim(Some(PartialDrop)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 1: main + at tests/fail/unaligned_pointers/drop_in_place.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr index 61915490917e..ed5c724a2e2b 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr @@ -6,12 +6,11 @@ LL | unsafe { (*x).x } | = 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 - = note: this is inside `foo` -note: which got called inside `main` - --> tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs:LL:CC - | -LL | foo(odd_ptr.cast()); - | ^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs:LL:CC + 1: main + at tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr index 58db5dda6a2e..bd44ed1224ec 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr @@ -6,12 +6,11 @@ LL | unsafe { (*x).packed.x } | = 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 - = note: this is inside `foo` -note: which got called inside `main` - --> tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs:LL:CC - | -LL | foo(odd_ptr.cast()); - | ^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: foo + at tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs:LL:CC + 1: main + at tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr index 56a3bf129ab2..2f3079383d12 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.stderr @@ -6,12 +6,11 @@ LL | mem::transmute(x) | = 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 - = note: this is inside `raw_to_ref::<'_, i32>` -note: which got called inside `main` - --> tests/fail/unaligned_pointers/reference_to_packed.rs:LL:CC - | -LL | let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: raw_to_ref + at tests/fail/unaligned_pointers/reference_to_packed.rs:LL:CC + 1: main + at tests/fail/unaligned_pointers/reference_to_packed.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr index 6a2f038017c0..e0caff6a21a9 100644 --- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr @@ -6,13 +6,13 @@ LL | let mut order = unsafe { compare_bytes(left, right, len) as isize } | = 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 - = note: this is inside `::compare` - = note: which got called inside `core::slice::cmp::::cmp` (at RUSTLIB/core/src/slice/cmp.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/uninit/uninit_alloc_diagnostic.rs:LL:CC - | -LL | drop(slice1.cmp(slice2)); - | ^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: ::compare + at RUSTLIB/core/src/slice/cmp.rs:LL:CC + 1: core::slice::cmp::cmp + at RUSTLIB/core/src/slice/cmp.rs:LL:CC + 2: main + at tests/fail/uninit/uninit_alloc_diagnostic.rs:LL:CC Uninitialized memory occurred at ALLOC[0x4..0x10], in this allocation: ALLOC (Rust heap, size: 32, align: 8) { diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr index f40e796cca61..efad61c14fb8 100644 --- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr @@ -6,13 +6,13 @@ LL | let mut order = unsafe { compare_bytes(left, right, len) as isize } | = 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 - = note: this is inside `::compare` - = note: which got called inside `core::slice::cmp::::cmp` (at RUSTLIB/core/src/slice/cmp.rs:LL:CC) -note: which got called inside `main` - --> tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs:LL:CC - | -LL | drop(slice1.cmp(slice2)); - | ^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: ::compare + at RUSTLIB/core/src/slice/cmp.rs:LL:CC + 1: core::slice::cmp::cmp + at RUSTLIB/core/src/slice/cmp.rs:LL:CC + 2: main + at tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs:LL:CC Uninitialized memory occurred at ALLOC[0x4..0x8], in this allocation: ALLOC (Rust heap, size: 16, align: 8) { diff --git a/src/tools/miri/tests/fail/unwind-action-terminate.stderr b/src/tools/miri/tests/fail/unwind-action-terminate.stderr index c86d94a82025..2295d80f45e8 100644 --- a/src/tools/miri/tests/fail/unwind-action-terminate.stderr +++ b/src/tools/miri/tests/fail/unwind-action-terminate.stderr @@ -14,24 +14,7 @@ error: abnormal termination: the program aborted execution LL | crate::process::abort(); | ^^^^^^^^^^^^^^^^^^^^^^^ abnormal termination occurred here | - = note: this is inside `std::panicking::panic_with_hook` - = note: which got called inside closure (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::panic_handler::{closure#0}}, !>` (at RUSTLIB/std/src/sys/backtrace.rs:LL:CC) - = note: which got called inside `std::panicking::panic_handler` (at RUSTLIB/std/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_nounwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) - = note: which got called inside `core::panicking::panic_cannot_unwind` (at RUSTLIB/core/src/panicking.rs:LL:CC) -note: which got called inside `panic_abort` - --> tests/fail/unwind-action-terminate.rs:LL:CC - | -LL | / extern "C" fn panic_abort() { -LL | | panic!() -LL | | } - | |_^ -note: which got called inside `main` - --> tests/fail/unwind-action-terminate.rs:LL:CC - | -LL | panic_abort(); - | ^^^^^^^^^^^^^ + = note: stack backtrace: note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr index 5c7572c76a13..c2e647aa18fc 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr @@ -6,12 +6,11 @@ LL | Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue()) | = 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 - = note: this is inside `call` -note: which got called inside `main` - --> tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC - | -LL | call(f); - | ^^^^^^^ + = note: stack backtrace: + 0: call + at tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC + 1: main + at tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr index 6612bcd22394..ecccf204cf81 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr @@ -6,12 +6,11 @@ LL | RET = *ptr as u32; | = 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 - = note: this is inside `cast` -note: which got called inside `main` - --> tests/fail/validity/invalid_char_cast.rs:LL:CC - | -LL | cast(&v as *const u32 as *const char); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: cast + at tests/fail/validity/invalid_char_cast.rs:LL:CC + 1: main + at tests/fail/validity/invalid_char_cast.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_char_match.stderr b/src/tools/miri/tests/fail/validity/invalid_char_match.stderr index cda730172177..818b2e26f869 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char_match.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_char_match.stderr @@ -9,12 +9,11 @@ LL | | } | = 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 - = note: this is inside `switch_int` -note: which got called inside `main` - --> tests/fail/validity/invalid_char_match.rs:LL:CC - | -LL | switch_int(&v as *const u32 as *const char); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: switch_int + at tests/fail/validity/invalid_char_match.rs:LL:CC + 1: main + at tests/fail/validity/invalid_char_match.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr index 6a4d0e0375af..a02dc678f018 100644 --- a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr @@ -6,12 +6,11 @@ LL | let _val = *ptr as u32; | = 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 - = note: this is inside `cast` -note: which got called inside `main` - --> tests/fail/validity/invalid_enum_cast.rs:LL:CC - | -LL | cast(&v as *const u32 as *const E); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: cast + at tests/fail/validity/invalid_enum_cast.rs:LL:CC + 1: main + at tests/fail/validity/invalid_enum_cast.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr index 9f3792e0e409..d2d6da49fc1e 100644 --- a/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr +++ b/src/tools/miri/tests/fail/weak_memory/weak_uninit.stderr @@ -6,8 +6,8 @@ LL | let j2 = spawn(move || x.load(Ordering::Relaxed)); | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/fail/weak_memory/weak_uninit.rs:LL:CC | LL | let j2 = spawn(move || x.load(Ordering::Relaxed)); diff --git a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr index 85e2810f1f30..2ba64ac032a8 100644 --- a/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr +++ b/src/tools/miri/tests/genmc/fail/atomics/atomic_ptr_double_free.stderr @@ -17,23 +17,17 @@ help: ALLOC was deallocated here: | LL | dealloc(ptr as *mut u8, Layout::new::()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: error occurred on thread `unnamed-ID`, inside `free` - --> tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC - | -LL | unsafe fn free(ptr: *mut u64) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: which got called inside closure - --> tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC - | -LL | free(b); - | ^^^^^^^ - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC}>` - --> tests/genmc/fail/atomics/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: free + at tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC + 1: miri_start::{closure#1} + at tests/genmc/fail/atomics/atomic_ptr_double_free.rs:LL:CC + 2: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 3: genmc::spawn_pthread_closure::thread_func + at tests/genmc/fail/atomics/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/atomics/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr index 4bca53961f5f..7534eaf8f37e 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.dealloc.stderr @@ -7,14 +7,15 @@ LL | dealloc(b as *mut u8, Layout::new::()); | = 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 - = note: this is on thread `unnamed-ID`, inside closure - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC}>` - --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: miri_start::{closure#1} + at tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC + 1: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: genmc::spawn_pthread_closure::thread_func + at tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr index 0a03363285b6..77e9817a55c7 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_alloc_race.write.stderr @@ -7,14 +7,15 @@ LL | *b = 42; | = 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 - = note: this is on thread `unnamed-ID`, inside closure - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC}>` - --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: miri_start::{closure#1} + at tests/genmc/fail/data_race/atomic_ptr_alloc_race.rs:LL:CC + 1: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: genmc::spawn_pthread_closure::thread_func + at tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr index 29a2e371bb3c..47df94404efa 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.stderr @@ -17,18 +17,15 @@ help: ALLOC was deallocated here: | LL | }), | ^ -note: error occurred on thread `unnamed-ID`, inside closure - --> tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.rs:LL:CC - | -LL | spawn_pthread_closure(|| { - | ^^ - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.rs:LL:CC}>` - --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: miri_start::{closure#1} + at tests/genmc/fail/data_race/atomic_ptr_dealloc_write_race.rs:LL:CC + 1: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: genmc::spawn_pthread_closure::thread_func + at tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr index 3f5d0bdf346e..e2c87b2d25e1 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.stderr @@ -7,14 +7,15 @@ LL | }), | = 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 - = note: this is on thread `unnamed-ID`, inside closure - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.rs:LL:CC}>` - --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: miri_start::{closure#1} + at tests/genmc/fail/data_race/atomic_ptr_write_dealloc_race.rs:LL:CC + 1: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: genmc::spawn_pthread_closure::thread_func + at tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr b/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr index 48b8a16c8b10..a3a15a71ce15 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/mpu2_rels_rlx.stderr @@ -7,14 +7,15 @@ LL | X = 2; | = 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 - = note: this is on thread `unnamed-ID`, inside closure - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/mpu2_rels_rlx.rs:LL:CC}>` - --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: miri_start::{closure#1} + at tests/genmc/fail/data_race/mpu2_rels_rlx.rs:LL:CC + 1: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: genmc::spawn_pthread_closure::thread_func + at tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr index 2eb3791aaf08..1220c0c09cbe 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rel_rlx.stderr @@ -7,14 +7,15 @@ LL | X = 2; | = 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 - = note: this is on thread `unnamed-ID`, inside closure - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/weak_orderings.rs:LL:CC}>` - --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: miri_start::{closure#1} + at tests/genmc/fail/data_race/weak_orderings.rs:LL:CC + 1: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: genmc::spawn_pthread_closure::thread_func + at tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr index 2eb3791aaf08..1220c0c09cbe 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_acq.stderr @@ -7,14 +7,15 @@ LL | X = 2; | = 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 - = note: this is on thread `unnamed-ID`, inside closure - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/weak_orderings.rs:LL:CC}>` - --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: miri_start::{closure#1} + at tests/genmc/fail/data_race/weak_orderings.rs:LL:CC + 1: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: genmc::spawn_pthread_closure::thread_func + at tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr index 2eb3791aaf08..1220c0c09cbe 100644 --- a/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr +++ b/src/tools/miri/tests/genmc/fail/data_race/weak_orderings.rlx_rlx.stderr @@ -7,14 +7,15 @@ LL | X = 2; | = 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 - = note: this is on thread `unnamed-ID`, inside closure - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/fail/data_race/weak_orderings.rs:LL:CC}>` - --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: miri_start::{closure#1} + at tests/genmc/fail/data_race/weak_orderings.rs:LL:CC + 1: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 2: genmc::spawn_pthread_closure::thread_func + at tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/data_race/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/genmc/fail/shims/exit.stderr b/src/tools/miri/tests/genmc/fail/shims/exit.stderr index 573c8b14fae3..c0d0321defe1 100644 --- a/src/tools/miri/tests/genmc/fail/shims/exit.stderr +++ b/src/tools/miri/tests/genmc/fail/shims/exit.stderr @@ -7,8 +7,8 @@ LL | unsafe { std::hint::unreachable_unchecked() }; | = 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 - = note: this is on thread `unnamed-ID`, inside closure -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` +note: the current function got called indirectly due to this code --> tests/genmc/fail/shims/exit.rs:LL:CC | LL | / std::thread::spawn(|| { diff --git a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr index e32548c4b5d5..272a52ba7fef 100644 --- a/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr +++ b/src/tools/miri/tests/genmc/fail/shims/mutex_diff_thread_unlock.stderr @@ -7,16 +7,19 @@ LL | self.lock.inner.unlock(); | = 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 - = note: this is on thread `unnamed-ID`, inside ` as std::ops::Drop>::drop` - = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::sync::MutexGuard<'_, u64>))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::ptr::drop_in_place::>> - shim(Some(EvilSend>))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::mem::drop::>>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) -note: which got called inside closure - --> tests/genmc/fail/shims/mutex_diff_thread_unlock.rs:LL:CC - | -LL | drop(guard); - | ^^^^^^^^^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: as std::ops::Drop>::drop + at RUSTLIB/std/src/sync/poison/mutex.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 3: std::mem::drop + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 4: miri_start::{closure#0} + at tests/genmc/fail/shims/mutex_diff_thread_unlock.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/fail/shims/mutex_diff_thread_unlock.rs:LL:CC | LL | let handle = std::thread::spawn(move || { diff --git a/src/tools/miri/tests/genmc/fail/shims/mutex_double_unlock.stderr b/src/tools/miri/tests/genmc/fail/shims/mutex_double_unlock.stderr index 9fec95ae6770..d668706f7647 100644 --- a/src/tools/miri/tests/genmc/fail/shims/mutex_double_unlock.stderr +++ b/src/tools/miri/tests/genmc/fail/shims/mutex_double_unlock.stderr @@ -7,14 +7,15 @@ LL | self.lock.inner.unlock(); | = 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 - = note: this is inside ` as std::ops::Drop>::drop` - = note: which got called inside `std::ptr::drop_in_place::> - shim(Some(std::sync::MutexGuard<'_, u64>))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) - = note: which got called inside `std::mem::drop::>` (at RUSTLIB/core/src/mem/mod.rs:LL:CC) -note: which got called inside `miri_start` - --> tests/genmc/fail/shims/mutex_double_unlock.rs:LL:CC - | -LL | drop(guard); - | ^^^^^^^^^^^ + = note: stack backtrace: + 0: as std::ops::Drop>::drop + at RUSTLIB/std/src/sync/poison/mutex.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: std::mem::drop + at RUSTLIB/core/src/mem/mod.rs:LL:CC + 3: miri_start + at tests/genmc/fail/shims/mutex_double_unlock.rs:LL:CC note: add `-Zmiri-genmc-print-genmc-output` to MIRIFLAGS to see the detailed GenMC error report diff --git a/src/tools/miri/tests/genmc/fail/simple/alloc_large.multiple.stderr b/src/tools/miri/tests/genmc/fail/simple/alloc_large.multiple.stderr index 2fc6e3d47229..5ddcce1fa30c 100644 --- a/src/tools/miri/tests/genmc/fail/simple/alloc_large.multiple.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/alloc_large.multiple.stderr @@ -6,16 +6,19 @@ LL | AllocInit::Uninitialized => alloc.allocate(layout), | ^^^^^^^^^^^^^^^^^^^^^^ resource exhaustion occurred here | = help: in GenMC mode, the address space is limited to 4GB per thread, and addresses cannot be reused - = note: this is inside `alloc::raw_vec::RawVecInner::try_allocate_in` - = note: which got called inside `alloc::raw_vec::RawVecInner::with_capacity_in` (at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC) - = note: which got called inside `alloc::raw_vec::RawVec::::with_capacity_in` (at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC) - = note: which got called inside `std::vec::Vec::::with_capacity_in` (at RUSTLIB/alloc/src/vec/mod.rs:LL:CC) - = note: which got called inside `std::vec::Vec::::with_capacity` (at RUSTLIB/alloc/src/vec/mod.rs:LL:CC) -note: which got called inside `miri_start` - --> tests/genmc/fail/simple/alloc_large.rs:LL:CC - | -LL | let _v = Vec::::with_capacity(1024 * 1024 * 1024); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: alloc::raw_vec::RawVecInner::try_allocate_in + at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC + 1: alloc::raw_vec::RawVecInner::with_capacity_in + at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC + 2: alloc::raw_vec::RawVec::with_capacity_in + at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC + 3: std::vec::Vec::with_capacity_in + at RUSTLIB/alloc/src/vec/mod.rs:LL:CC + 4: std::vec::Vec::with_capacity + at RUSTLIB/alloc/src/vec/mod.rs:LL:CC + 5: miri_start + at tests/genmc/fail/simple/alloc_large.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/fail/simple/alloc_large.single.stderr b/src/tools/miri/tests/genmc/fail/simple/alloc_large.single.stderr index dbd39e4727c2..5ddcce1fa30c 100644 --- a/src/tools/miri/tests/genmc/fail/simple/alloc_large.single.stderr +++ b/src/tools/miri/tests/genmc/fail/simple/alloc_large.single.stderr @@ -6,16 +6,19 @@ LL | AllocInit::Uninitialized => alloc.allocate(layout), | ^^^^^^^^^^^^^^^^^^^^^^ resource exhaustion occurred here | = help: in GenMC mode, the address space is limited to 4GB per thread, and addresses cannot be reused - = note: this is inside `alloc::raw_vec::RawVecInner::try_allocate_in` - = note: which got called inside `alloc::raw_vec::RawVecInner::with_capacity_in` (at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC) - = note: which got called inside `alloc::raw_vec::RawVec::::with_capacity_in` (at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC) - = note: which got called inside `std::vec::Vec::::with_capacity_in` (at RUSTLIB/alloc/src/vec/mod.rs:LL:CC) - = note: which got called inside `std::vec::Vec::::with_capacity` (at RUSTLIB/alloc/src/vec/mod.rs:LL:CC) -note: which got called inside `miri_start` - --> tests/genmc/fail/simple/alloc_large.rs:LL:CC - | -LL | let _v = Vec::::with_capacity(8 * 1024 * 1024 * 1024); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: alloc::raw_vec::RawVecInner::try_allocate_in + at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC + 1: alloc::raw_vec::RawVecInner::with_capacity_in + at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC + 2: alloc::raw_vec::RawVec::with_capacity_in + at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC + 3: std::vec::Vec::with_capacity_in + at RUSTLIB/alloc/src/vec/mod.rs:LL:CC + 4: std::vec::Vec::with_capacity + at RUSTLIB/alloc/src/vec/mod.rs:LL:CC + 5: miri_start + at tests/genmc/fail/simple/alloc_large.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr b/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr index 6d597aaa6342..24bde07924d1 100644 --- a/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr +++ b/src/tools/miri/tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.stderr @@ -5,19 +5,17 @@ warning: GenMC currently does not model the failure ordering for `compare_exchan LL | match KEY.compare_exchange(KEY_SENTVAL, key, Release, Acquire) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GenMC might miss possible behaviors of this code | - = note: this is on thread `unnamed-ID`, inside `get_or_init` -note: which got called inside closure - --> tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.rs:LL:CC - | -LL | let key = get_or_init(0); - | ^^^^^^^^^^^^^^ - = note: which got called inside ` as std::ops::FnOnce<()>>::call_once` (at RUSTLIB/alloc/src/boxed.rs:LL:CC) -note: which got called inside `genmc::spawn_pthread_closure::thread_func::<{closure@tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.rs:LL:CC}>` - --> tests/genmc/pass/atomics/../../../utils/genmc.rs:LL:CC - | -LL | f(); - | ^^^ -note: which got called indirectly due to this code + = note: this is on thread `unnamed-ID` + = note: stack backtrace: + 0: get_or_init + at tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.rs:LL:CC + 1: miri_start::{closure#0} + at tests/genmc/pass/atomics/cas_failure_ord_racy_key_init.rs:LL:CC + 2: as std::ops::FnOnce<()>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 3: genmc::spawn_pthread_closure::thread_func + at tests/genmc/pass/atomics/../../../utils/genmc.rs:LL:CC +note: the last function in that backtrace got called indirectly due to this code --> tests/genmc/pass/atomics/../../../utils/genmc.rs:LL:CC | LL | / libc::pthread_create( diff --git a/src/tools/miri/tests/native-lib/fail/tracing/partial_init.stderr b/src/tools/miri/tests/native-lib/fail/tracing/partial_init.stderr index 4a7d24090641..032461b6ed3f 100644 --- a/src/tools/miri/tests/native-lib/fail/tracing/partial_init.stderr +++ b/src/tools/miri/tests/native-lib/fail/tracing/partial_init.stderr @@ -9,12 +9,11 @@ LL | init_n(2, slice_ptr); = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free = help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here - = note: this is inside `partial_init` -note: which got called inside `main` - --> tests/native-lib/fail/tracing/partial_init.rs:LL:CC - | -LL | partial_init(); - | ^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: partial_init + at tests/native-lib/fail/tracing/partial_init.rs:LL:CC + 1: main + at tests/native-lib/fail/tracing/partial_init.rs:LL:CC error: Undefined Behavior: reading memory at ALLOC[0x2..0x3], but memory is uninitialized at [0x2..0x3], and this operation requires initialized memory --> tests/native-lib/fail/tracing/partial_init.rs:LL:CC @@ -24,12 +23,11 @@ LL | let _val = *slice_ptr.offset(2); | = 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 - = note: this is inside `partial_init` -note: which got called inside `main` - --> tests/native-lib/fail/tracing/partial_init.rs:LL:CC - | -LL | partial_init(); - | ^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: partial_init + at tests/native-lib/fail/tracing/partial_init.rs:LL:CC + 1: main + at tests/native-lib/fail/tracing/partial_init.rs:LL:CC Uninitialized memory occurred at ALLOC[0x2..0x3], in this allocation: ALLOC (stack variable, size: 3, align: 1) { diff --git a/src/tools/miri/tests/native-lib/fail/tracing/unexposed_reachable_alloc.stderr b/src/tools/miri/tests/native-lib/fail/tracing/unexposed_reachable_alloc.stderr index 825c9666b749..773d2dd63c3e 100644 --- a/src/tools/miri/tests/native-lib/fail/tracing/unexposed_reachable_alloc.stderr +++ b/src/tools/miri/tests/native-lib/fail/tracing/unexposed_reachable_alloc.stderr @@ -9,12 +9,11 @@ LL | unsafe { do_one_deref(exposed) }; = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free = help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here - = note: this is inside `unexposed_reachable_alloc` -note: which got called inside `main` - --> tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC - | -LL | unexposed_reachable_alloc(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: unexposed_reachable_alloc + at tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC + 1: main + at tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC error: Undefined Behavior: memory access failed: attempting to access 4 bytes, but got $HEX[noalloc] which is a dangling pointer (it has no provenance) --> tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC @@ -24,12 +23,11 @@ LL | let _not_ok = *invalid; | = 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 - = note: this is inside `unexposed_reachable_alloc` -note: which got called inside `main` - --> tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC - | -LL | unexposed_reachable_alloc(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: unexposed_reachable_alloc + at tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC + 1: main + at tests/native-lib/fail/tracing/unexposed_reachable_alloc.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr index cbccd8fb62f4..b6bbb4342b77 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr @@ -8,12 +8,11 @@ LL | unsafe { print_pointer(&x) }; = help: in particular, Miri assumes that the native call initializes all memory it has access to = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free - = note: this is inside `test_access_pointer` -note: which got called inside `main` - --> tests/native-lib/pass/ptr_read_access.rs:LL:CC - | -LL | test_access_pointer(); - | ^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: test_access_pointer + at tests/native-lib/pass/ptr_read_access.rs:LL:CC + 1: main + at tests/native-lib/pass/ptr_read_access.rs:LL:CC warning: sharing a function pointer with a native function called via FFI --> tests/native-lib/pass/ptr_read_access.rs:LL:CC @@ -22,10 +21,9 @@ LL | pass_fn_ptr(Some(nop)); // this one is not | ^^^^^^^^^^^^^^^^^^^^^^ sharing a function pointer with a native function | = help: calling Rust functions from C is not supported and will, in the best case, crash the program - = note: this is inside `pass_fn_ptr` -note: which got called inside `main` - --> tests/native-lib/pass/ptr_read_access.rs:LL:CC - | -LL | pass_fn_ptr(); - | ^^^^^^^^^^^^^ + = note: stack backtrace: + 0: pass_fn_ptr + at tests/native-lib/pass/ptr_read_access.rs:LL:CC + 1: main + at tests/native-lib/pass/ptr_read_access.rs:LL:CC diff --git a/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr index 2697fb6d4353..0d86ea066099 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr @@ -9,12 +9,11 @@ LL | unsafe { print_pointer(&x) }; = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free = help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here - = note: this is inside `test_access_pointer` -note: which got called inside `main` - --> tests/native-lib/pass/ptr_read_access.rs:LL:CC - | -LL | test_access_pointer(); - | ^^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: test_access_pointer + at tests/native-lib/pass/ptr_read_access.rs:LL:CC + 1: main + at tests/native-lib/pass/ptr_read_access.rs:LL:CC warning: sharing a function pointer with a native function called via FFI --> tests/native-lib/pass/ptr_read_access.rs:LL:CC @@ -23,10 +22,9 @@ LL | pass_fn_ptr(Some(nop)); // this one is not | ^^^^^^^^^^^^^^^^^^^^^^ sharing a function pointer with a native function | = help: calling Rust functions from C is not supported and will, in the best case, crash the program - = note: this is inside `pass_fn_ptr` -note: which got called inside `main` - --> tests/native-lib/pass/ptr_read_access.rs:LL:CC - | -LL | pass_fn_ptr(); - | ^^^^^^^^^^^^^ + = note: stack backtrace: + 0: pass_fn_ptr + at tests/native-lib/pass/ptr_read_access.rs:LL:CC + 1: main + at tests/native-lib/pass/ptr_read_access.rs:LL:CC diff --git a/src/tools/miri/tests/native-lib/pass/ptr_write_access.notrace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_write_access.notrace.stderr index c7edaa373167..15b2bc6df63f 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_write_access.notrace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_write_access.notrace.stderr @@ -8,10 +8,9 @@ LL | unsafe { increment_int(&mut x) }; = help: in particular, Miri assumes that the native call initializes all memory it has access to = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free - = note: this is inside `test_increment_int` -note: which got called inside `main` - --> tests/native-lib/pass/ptr_write_access.rs:LL:CC - | -LL | test_increment_int(); - | ^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: test_increment_int + at tests/native-lib/pass/ptr_write_access.rs:LL:CC + 1: main + at tests/native-lib/pass/ptr_write_access.rs:LL:CC diff --git a/src/tools/miri/tests/native-lib/pass/ptr_write_access.trace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_write_access.trace.stderr index dacde45e17a1..d12a25f84b37 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_write_access.trace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_write_access.trace.stderr @@ -9,10 +9,9 @@ LL | unsafe { increment_int(&mut x) }; = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free = help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here - = note: this is inside `test_increment_int` -note: which got called inside `main` - --> tests/native-lib/pass/ptr_write_access.rs:LL:CC - | -LL | test_increment_int(); - | ^^^^^^^^^^^^^^^^^^^^ + = note: stack backtrace: + 0: test_increment_int + at tests/native-lib/pass/ptr_write_access.rs:LL:CC + 1: main + at tests/native-lib/pass/ptr_write_access.rs:LL:CC diff --git a/src/tools/miri/tests/panic/panic1.stderr b/src/tools/miri/tests/panic/panic1.stderr index ff7e287b5a58..d709428f3115 100644 --- a/src/tools/miri/tests/panic/panic1.stderr +++ b/src/tools/miri/tests/panic/panic1.stderr @@ -3,11 +3,11 @@ thread 'main' ($TID) panicked at tests/panic/panic1.rs:LL:CC: panicking from libstd stack backtrace: 0: std::panicking::panic_handler - at RUSTLIB/std/src/panicking.rs:LL:CC + at RUSTLIB/std/src/panicking.rs:LL:CC 1: std::rt::panic_fmt - at RUSTLIB/core/src/panicking.rs:LL:CC + at RUSTLIB/core/src/panicking.rs:LL:CC 2: main - at tests/panic/panic1.rs:LL:CC + at tests/panic/panic1.rs:LL:CC 3: >::call_once - shim(fn()) - at RUSTLIB/core/src/ops/function.rs:LL:CC + at RUSTLIB/core/src/ops/function.rs:LL:CC note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.stderr b/src/tools/miri/tests/pass/alloc-access-tracking.stderr index b5b1bc2a7bc2..5dfcd0180e4c 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.stderr +++ b/src/tools/miri/tests/pass/alloc-access-tracking.stderr @@ -24,11 +24,11 @@ note: freed allocation ALLOC LL | self.1.deallocate(From::from(ptr.cast()), layout); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tracking was triggered here | - = note: this is inside `> as std::ops::Drop>::drop` - = note: which got called inside `std::ptr::drop_in_place::>> - shim(Some(std::boxed::Box>))` (at RUSTLIB/core/src/ptr/mod.rs:LL:CC) -note: which got called inside `main` - --> tests/pass/alloc-access-tracking.rs:LL:CC - | -LL | } - | ^ + = note: stack backtrace: + 0: > as std::ops::Drop>::drop + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 1: std::ptr::drop_in_place)) + at RUSTLIB/core/src/ptr/mod.rs:LL:CC + 2: main + at tests/pass/alloc-access-tracking.rs:LL:CC diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr index 588bb85f35a4..b4ef3f76c20f 100644 --- a/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr +++ b/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr @@ -1,28 +1,28 @@ 0: main - at tests/pass/backtrace/backtrace-global-alloc.rs:LL:CC + at tests/pass/backtrace/backtrace-global-alloc.rs:LL:CC 1: >::call_once - shim(fn()) - at RUSTLIB/core/src/ops/function.rs:LL:CC + at RUSTLIB/core/src/ops/function.rs:LL:CC 2: std::sys::backtrace::__rust_begin_short_backtrace - at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + at RUSTLIB/std/src/sys/backtrace.rs:LL:CC 3: std::rt::lang_start::{closure#0} - at RUSTLIB/std/src/rt.rs:LL:CC + at RUSTLIB/std/src/rt.rs:LL:CC 4: std::ops::function::impls::call_once - at RUSTLIB/core/src/ops/function.rs:LL:CC + at RUSTLIB/core/src/ops/function.rs:LL:CC 5: std::panicking::catch_unwind::do_call - at RUSTLIB/std/src/panicking.rs:LL:CC + at RUSTLIB/std/src/panicking.rs:LL:CC 6: std::panicking::catch_unwind - at RUSTLIB/std/src/panicking.rs:LL:CC + at RUSTLIB/std/src/panicking.rs:LL:CC 7: std::panic::catch_unwind - at RUSTLIB/std/src/panic.rs:LL:CC + at RUSTLIB/std/src/panic.rs:LL:CC 8: std::rt::lang_start_internal::{closure#0} - at RUSTLIB/std/src/rt.rs:LL:CC + at RUSTLIB/std/src/rt.rs:LL:CC 9: std::panicking::catch_unwind::do_call - at RUSTLIB/std/src/panicking.rs:LL:CC + at RUSTLIB/std/src/panicking.rs:LL:CC 10: std::panicking::catch_unwind - at RUSTLIB/std/src/panicking.rs:LL:CC + at RUSTLIB/std/src/panicking.rs:LL:CC 11: std::panic::catch_unwind - at RUSTLIB/std/src/panic.rs:LL:CC + at RUSTLIB/std/src/panic.rs:LL:CC 12: std::rt::lang_start_internal - at RUSTLIB/std/src/rt.rs:LL:CC + at RUSTLIB/std/src/rt.rs:LL:CC 13: std::rt::lang_start - at RUSTLIB/std/src/rt.rs:LL:CC + at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr index 9c952755957b..706eacc70fd8 100644 --- a/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr +++ b/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr @@ -1,36 +1,36 @@ 0: func_d - at tests/pass/backtrace/backtrace-std.rs:LL:CC + at tests/pass/backtrace/backtrace-std.rs:LL:CC 1: func_c - at tests/pass/backtrace/backtrace-std.rs:LL:CC + at tests/pass/backtrace/backtrace-std.rs:LL:CC 2: func_b - at tests/pass/backtrace/backtrace-std.rs:LL:CC + at tests/pass/backtrace/backtrace-std.rs:LL:CC 3: func_a - at tests/pass/backtrace/backtrace-std.rs:LL:CC + at tests/pass/backtrace/backtrace-std.rs:LL:CC 4: main - at tests/pass/backtrace/backtrace-std.rs:LL:CC + at tests/pass/backtrace/backtrace-std.rs:LL:CC 5: >::call_once - shim(fn()) - at RUSTLIB/core/src/ops/function.rs:LL:CC + at RUSTLIB/core/src/ops/function.rs:LL:CC 6: std::sys::backtrace::__rust_begin_short_backtrace - at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + at RUSTLIB/std/src/sys/backtrace.rs:LL:CC 7: std::rt::lang_start::{closure#0} - at RUSTLIB/std/src/rt.rs:LL:CC + at RUSTLIB/std/src/rt.rs:LL:CC 8: std::ops::function::impls::call_once - at RUSTLIB/core/src/ops/function.rs:LL:CC + at RUSTLIB/core/src/ops/function.rs:LL:CC 9: std::panicking::catch_unwind::do_call - at RUSTLIB/std/src/panicking.rs:LL:CC + at RUSTLIB/std/src/panicking.rs:LL:CC 10: std::panicking::catch_unwind - at RUSTLIB/std/src/panicking.rs:LL:CC + at RUSTLIB/std/src/panicking.rs:LL:CC 11: std::panic::catch_unwind - at RUSTLIB/std/src/panic.rs:LL:CC + at RUSTLIB/std/src/panic.rs:LL:CC 12: std::rt::lang_start_internal::{closure#0} - at RUSTLIB/std/src/rt.rs:LL:CC + at RUSTLIB/std/src/rt.rs:LL:CC 13: std::panicking::catch_unwind::do_call - at RUSTLIB/std/src/panicking.rs:LL:CC + at RUSTLIB/std/src/panicking.rs:LL:CC 14: std::panicking::catch_unwind - at RUSTLIB/std/src/panicking.rs:LL:CC + at RUSTLIB/std/src/panicking.rs:LL:CC 15: std::panic::catch_unwind - at RUSTLIB/std/src/panic.rs:LL:CC + at RUSTLIB/std/src/panic.rs:LL:CC 16: std::rt::lang_start_internal - at RUSTLIB/std/src/rt.rs:LL:CC + at RUSTLIB/std/src/rt.rs:LL:CC 17: std::rt::lang_start - at RUSTLIB/std/src/rt.rs:LL:CC + at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index 8a3ab658b669..70739eef2883 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -255,8 +255,6 @@ regexes! { "<[0-9]+=" => " "$1", - // erase whitespace that differs between platforms - r" +at (.*\.rs)" => " at $1", // erase generics in backtraces "([0-9]+: .*)::<.*>" => "$1", // erase long hexadecimals From 262426d5354b69c658faeb54a4642a4a8121a1e0 Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Tue, 30 Dec 2025 16:05:53 -0300 Subject: [PATCH 1417/3801] Avoid index check in char::to_lowercase and char::to_uppercase --- library/core/src/unicode/unicode_data.rs | 6 ++++-- src/tools/unicode-table-generator/src/case_mapping.rs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index 3c38b44224f8..429b60a68f43 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -767,7 +767,8 @@ pub mod conversions { LOWERCASE_TABLE .binary_search_by(|&(key, _)| key.cmp(&c)) .map(|i| { - let u = LOWERCASE_TABLE[i].1; + // SAFETY: i is the result of the binary search + let u = unsafe { LOWERCASE_TABLE.get_unchecked(i) }.1; char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { // SAFETY: Index comes from statically generated table unsafe { *LOWERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } @@ -784,7 +785,8 @@ pub mod conversions { UPPERCASE_TABLE .binary_search_by(|&(key, _)| key.cmp(&c)) .map(|i| { - let u = UPPERCASE_TABLE[i].1; + // SAFETY: i is the result of the binary search + let u = unsafe { UPPERCASE_TABLE.get_unchecked(i) }.1; char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { // SAFETY: Index comes from statically generated table unsafe { *UPPERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index 49aef3ec33ec..437e1e47dd70 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -91,7 +91,8 @@ pub fn to_lower(c: char) -> [char; 3] { LOWERCASE_TABLE .binary_search_by(|&(key, _)| key.cmp(&c)) .map(|i| { - let u = LOWERCASE_TABLE[i].1; + // SAFETY: i is the result of the binary search + let u = unsafe { LOWERCASE_TABLE.get_unchecked(i) }.1; char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { // SAFETY: Index comes from statically generated table unsafe { *LOWERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } @@ -108,7 +109,8 @@ pub fn to_upper(c: char) -> [char; 3] { UPPERCASE_TABLE .binary_search_by(|&(key, _)| key.cmp(&c)) .map(|i| { - let u = UPPERCASE_TABLE[i].1; + // SAFETY: i is the result of the binary search + let u = unsafe { UPPERCASE_TABLE.get_unchecked(i) }.1; char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { // SAFETY: Index comes from statically generated table unsafe { *UPPERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } From 319735d8c9851db41a1fd0a1c435a72e5eec9df0 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 30 Dec 2025 10:35:05 -0800 Subject: [PATCH 1418/3801] Fix parsing of mgca const blocks in array repeat exprs There was an inconsistency where in the case of array repeat expressions, we forgot to eat the `const` keyword of mgca const blocks. Thus, we ended up parsing them as an anon const containing an inline const, instead of simply an anon const as they should be. This commit fixes that issue and also makes the parsing for mgca const blocks more consistent and simpler in general. For example, we avoid doing a lookahead check to ensure there's a curly brace coming. There should always be one after a `const` keyword in an expression context, and that's handled by the mgca const block parsing function. --- compiler/rustc_parse/src/parser/expr.rs | 6 ++--- compiler/rustc_parse/src/parser/mod.rs | 5 ++-- compiler/rustc_parse/src/parser/path.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 4 +--- .../assoc-const-eq-ambiguity.stderr | 4 ++-- ...soc-const-eq-bound-var-in-ty-not-wf.stderr | 8 +++---- .../const-block-is-poly.rs | 2 +- .../const-block-is-poly.stderr | 6 +++-- ...nbraced_const_block_const_arg_gated.stderr | 24 +++++++++---------- 9 files changed, 29 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 8bbf534294f4..8835fba1adcd 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1622,15 +1622,13 @@ impl<'a> Parser<'a> { let first_expr = self.parse_expr()?; if self.eat(exp!(Semi)) { // Repeating array syntax: `[ 0; 512 ]` - let count = if self.token.is_keyword(kw::Const) - && self.look_ahead(1, |t| *t == token::OpenBrace) - { + let count = if self.eat_keyword(exp!(Const)) { // While we could just disambiguate `Direct` from `AnonConst` by // treating all const block exprs as `AnonConst`, that would // complicate the DefCollector and likely all other visitors. // So we strip the const blockiness and just store it as a block // in the AST with the extra disambiguator on the AnonConst - self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)? + self.parse_mgca_const_block(false)? } else { self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))? }; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index b3df728e8198..4dade1d01282 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1303,9 +1303,8 @@ impl<'a> Parser<'a> { } fn parse_mgca_const_block(&mut self, gate_syntax: bool) -> PResult<'a, AnonConst> { - self.expect_keyword(exp!(Const))?; - let kw_span = self.token.span; - let value = self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)?; + let kw_span = self.prev_token.span; + let value = self.parse_expr_block(None, kw_span, BlockCheckMode::Default)?; if gate_syntax { self.psess.gated_spans.gate(sym::min_generic_const_args, kw_span.to(value.span)); } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index ce9e9c73669e..dd190707c42b 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -874,7 +874,7 @@ impl<'a> Parser<'a> { let (value, mgca_disambiguation) = if self.token.kind == token::OpenBrace { let value = self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)?; (value, MgcaDisambiguation::Direct) - } else if self.token.is_keyword(kw::Const) { + } else if self.eat_keyword(exp!(Const)) { // While we could just disambiguate `Direct` from `AnonConst` by // treating all const block exprs as `AnonConst`, that would // complicate the DefCollector and likely all other visitors. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 3ccaae868a65..0185c51c5c56 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -658,9 +658,7 @@ impl<'a> Parser<'a> { }; let ty = if self.eat(exp!(Semi)) { - let mut length = if self.token.is_keyword(kw::Const) - && self.look_ahead(1, |t| *t == token::OpenBrace) - { + let mut length = if self.eat_keyword(exp!(Const)) { // While we could just disambiguate `Direct` from `AnonConst` by // treating all const block exprs as `AnonConst`, that would // complicate the DefCollector and likely all other visitors. diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr index 9ab39e6b8a60..cf4805aaf592 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr @@ -13,8 +13,8 @@ LL | fn take0(_: impl Trait0) {} = help: consider introducing a new type parameter `T` and adding `where` constraints: where T: Trait0, - T: Parent0::K = { }, - T: Parent0::K = { } + T: Parent0::K = const { }, + T: Parent0::K = const { } error[E0222]: ambiguous associated constant `C` in bounds of `Trait1` --> $DIR/assoc-const-eq-ambiguity.rs:26:25 diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index 4a4c2b285829..76868715b861 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -1,14 +1,14 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:19 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 | LL | K = const { () } - | ^^^^^^ + | ^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:19 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 | LL | K = const { () } - | ^^^^^^ + | ^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs index f1305202ad45..a6988a492f61 100644 --- a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs +++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs @@ -2,7 +2,7 @@ //~^ WARN the feature `generic_const_exprs` is incomplete fn foo() { - let _ = [0u8; const { std::mem::size_of::() }]; + let _ = [0u8; { const { std::mem::size_of::() } }]; //~^ ERROR: overly complex generic constant } diff --git a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr index 03b0004bf0bd..db547e6a2481 100644 --- a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr +++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr @@ -10,8 +10,10 @@ LL | #![feature(generic_const_exprs)] error: overly complex generic constant --> $DIR/const-block-is-poly.rs:5:19 | -LL | let _ = [0u8; const { std::mem::size_of::() }]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ const blocks are not supported in generic constants +LL | let _ = [0u8; { const { std::mem::size_of::() } }]; + | ^^----------------------------------^^ + | | + | const blocks are not supported in generic constants | = help: consider moving this anonymous constant into a `const` function = note: this operation may be supported in the future diff --git a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr index 30509ddf9b46..00db630c27e9 100644 --- a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr +++ b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr @@ -1,58 +1,58 @@ error[E0658]: unbraced const blocks as const args are experimental - --> $DIR/unbraced_const_block_const_arg_gated.rs:7:33 + --> $DIR/unbraced_const_block_const_arg_gated.rs:7:27 | LL | const PARAM_TY: Inner, - | ^^^^^ + | ^^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental - --> $DIR/unbraced_const_block_const_arg_gated.rs:9:34 + --> $DIR/unbraced_const_block_const_arg_gated.rs:9:28 | LL | const DEFAULT: usize = const { 1 }, - | ^^^^^ + | ^^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental - --> $DIR/unbraced_const_block_const_arg_gated.rs:14:29 + --> $DIR/unbraced_const_block_const_arg_gated.rs:14:23 | LL | type NormalTy = Inner; - | ^^^^^ + | ^^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental - --> $DIR/unbraced_const_block_const_arg_gated.rs:22:24 + --> $DIR/unbraced_const_block_const_arg_gated.rs:22:18 | LL | let _: Inner; - | ^^^^^ + | ^^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental - --> $DIR/unbraced_const_block_const_arg_gated.rs:28:25 + --> $DIR/unbraced_const_block_const_arg_gated.rs:28:19 | LL | generic::(); - | ^^^^^ + | ^^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental - --> $DIR/unbraced_const_block_const_arg_gated.rs:37:33 + --> $DIR/unbraced_const_block_const_arg_gated.rs:37:27 | LL | const TYPE_CONST: usize = const { 1 }; - | ^^^^^ + | ^^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable From 975aa0dc8a535165a5415ca057a738626339be03 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 30 Dec 2025 19:39:13 +0200 Subject: [PATCH 1419/3801] Add `#[rust_analyzer::macro_style()]` attribute to control macro completion brace style --- .../rust-analyzer/crates/hir-def/src/attrs.rs | 19 ++++ src/tools/rust-analyzer/crates/hir/src/lib.rs | 44 ++++++++++ .../ide-completion/src/render/macro_.rs | 87 ++++++++++++++++--- .../ide-completion/src/tests/flyimport.rs | 1 + 4 files changed, 138 insertions(+), 13 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs index e91d72a701cf..83df11f2d2a4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs @@ -99,6 +99,20 @@ fn extract_ra_completions(attr_flags: &mut AttrFlags, tt: ast::TokenTree) { } } +fn extract_ra_macro_style(attr_flags: &mut AttrFlags, tt: ast::TokenTree) { + let tt = TokenTreeChildren::new(&tt); + if let Ok(NodeOrToken::Token(option)) = Itertools::exactly_one(tt) + && option.kind().is_any_identifier() + { + match option.text() { + "braces" => attr_flags.insert(AttrFlags::MACRO_STYLE_BRACES), + "brackets" => attr_flags.insert(AttrFlags::MACRO_STYLE_BRACKETS), + "parentheses" => attr_flags.insert(AttrFlags::MACRO_STYLE_PARENTHESES), + _ => {} + } + } +} + fn extract_rustc_skip_during_method_dispatch(attr_flags: &mut AttrFlags, tt: ast::TokenTree) { let iter = TokenTreeChildren::new(&tt); for kind in iter { @@ -163,6 +177,7 @@ fn match_attr_flags(attr_flags: &mut AttrFlags, attr: Meta) -> ControlFlow match path.segments[0].text() { "rust_analyzer" => match path.segments[1].text() { "completions" => extract_ra_completions(attr_flags, tt), + "macro_style" => extract_ra_macro_style(attr_flags, tt), _ => {} }, _ => {} @@ -291,6 +306,10 @@ bitflags::bitflags! { const RUSTC_COINDUCTIVE = 1 << 43; const RUSTC_FORCE_INLINE = 1 << 44; const IS_POINTEE = 1 << 45; + + const MACRO_STYLE_BRACES = 1 << 46; + const MACRO_STYLE_BRACKETS = 1 << 47; + const MACRO_STYLE_PARENTHESES = 1 << 48; } } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 6a19603923c3..1ab57c4489cf 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -3429,6 +3429,50 @@ impl Macro { pub fn is_derive(&self, db: &dyn HirDatabase) -> bool { matches!(self.kind(db), MacroKind::Derive | MacroKind::DeriveBuiltIn) } + + pub fn preferred_brace_style(&self, db: &dyn HirDatabase) -> Option { + let attrs = self.attrs(db); + MacroBraces::extract(attrs.attrs) + } +} + +// Feature: Macro Brace Style Attribute +// Crate authors can declare the preferred brace style for their macro. This will affect how completion +// insert calls to it. +// +// This is only supported on function-like macros. +// +// To do that, insert the `#[rust_analyzer::macro_style(style)]` attribute on the macro (for proc macros, +// insert it for the macro's function). `style` can be one of: +// +// - `braces` for `{...}` style. +// - `brackets` for `[...]` style. +// - `parentheses` for `(...)` style. +// +// Malformed attributes will be ignored without warnings. +// +// Note that users have no way to override this attribute, so be careful and only include things +// users definitely do not want to be completed! + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum MacroBraces { + Braces, + Brackets, + Parentheses, +} + +impl MacroBraces { + fn extract(attrs: AttrFlags) -> Option { + if attrs.contains(AttrFlags::MACRO_STYLE_BRACES) { + Some(Self::Braces) + } else if attrs.contains(AttrFlags::MACRO_STYLE_BRACKETS) { + Some(Self::Brackets) + } else if attrs.contains(AttrFlags::MACRO_STYLE_PARENTHESES) { + Some(Self::Parentheses) + } else { + None + } + } } #[derive(Clone, Copy, PartialEq, Eq, Hash)] diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs index 6efa8a84553e..8cdeb8abbff7 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs @@ -1,6 +1,6 @@ //! Renderer for macro invocations. -use hir::HirDisplay; +use hir::{HirDisplay, db::HirDatabase}; use ide_db::{SymbolKind, documentation::Documentation}; use syntax::{SmolStr, ToSmolStr, format_smolstr}; @@ -46,17 +46,15 @@ fn render( ctx.source_range() }; - let orig_name = macro_.name(ctx.db()); - let (name, orig_name, escaped_name) = ( - name.as_str(), - orig_name.as_str(), - name.display(ctx.db(), completion.edition).to_smolstr(), - ); + let (name, escaped_name) = + (name.as_str(), name.display(ctx.db(), completion.edition).to_smolstr()); let docs = ctx.docs(macro_); - let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default(); let is_fn_like = macro_.is_fn_like(completion.db); - let (bra, ket) = - if is_fn_like { guess_macro_braces(name, orig_name, docs_str) } else { ("", "") }; + let (bra, ket) = if is_fn_like { + guess_macro_braces(ctx.db(), macro_, name, docs.as_ref()) + } else { + ("", "") + }; let needs_bang = is_fn_like && !is_use_path && !has_macro_bang; @@ -115,12 +113,24 @@ fn banged_name(name: &str) -> SmolStr { } fn guess_macro_braces( + db: &dyn HirDatabase, + macro_: hir::Macro, macro_name: &str, - orig_name: &str, - docs: &str, + docs: Option<&Documentation<'_>>, ) -> (&'static str, &'static str) { + if let Some(style) = macro_.preferred_brace_style(db) { + return match style { + hir::MacroBraces::Braces => (" {", "}"), + hir::MacroBraces::Brackets => ("[", "]"), + hir::MacroBraces::Parentheses => ("(", ")"), + }; + } + + let orig_name = macro_.name(db); + let docs = docs.map(Documentation::as_str).unwrap_or_default(); + let mut votes = [0, 0, 0]; - for (idx, s) in docs.match_indices(macro_name).chain(docs.match_indices(orig_name)) { + for (idx, s) in docs.match_indices(macro_name).chain(docs.match_indices(orig_name.as_str())) { let (before, after) = (&docs[..idx], &docs[idx + s.len()..]); // Ensure to match the full word if after.starts_with('!') @@ -199,6 +209,57 @@ fn main() { ); } + #[test] + fn preferred_macro_braces() { + check_edit( + "vec!", + r#" +#[rust_analyzer::macro_style(brackets)] +macro_rules! vec { () => {} } + +fn main() { v$0 } +"#, + r#" +#[rust_analyzer::macro_style(brackets)] +macro_rules! vec { () => {} } + +fn main() { vec![$0] } +"#, + ); + + check_edit( + "foo!", + r#" +#[rust_analyzer::macro_style(braces)] +macro_rules! foo { () => {} } +fn main() { $0 } +"#, + r#" +#[rust_analyzer::macro_style(braces)] +macro_rules! foo { () => {} } +fn main() { foo! {$0} } +"#, + ); + + check_edit( + "bar!", + r#" +#[macro_export] +#[rust_analyzer::macro_style(brackets)] +macro_rules! foo { () => {} } +pub use crate::foo as bar; +fn main() { $0 } +"#, + r#" +#[macro_export] +#[rust_analyzer::macro_style(brackets)] +macro_rules! foo { () => {} } +pub use crate::foo as bar; +fn main() { bar![$0] } +"#, + ); + } + #[test] fn guesses_macro_braces() { check_edit( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index c9755525a5de..aad881f8ce4f 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -79,6 +79,7 @@ fn macro_fuzzy_completion() { r#" //- /lib.rs crate:dep /// Please call me as macro_with_curlies! {} +#[rust_analyzer::macro_style(braces)] #[macro_export] macro_rules! macro_with_curlies { () => {} From df998811cee1c2d0567a04020708c1534185a980 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 30 Dec 2025 19:48:04 +0200 Subject: [PATCH 1420/3801] Adapt macros in rust-analyzer to new attribute `match_ast!` cannot be ported because of a weird compiler bug: https://github.com/rust-lang/rust/issues/150518. --- src/tools/rust-analyzer/crates/tt/src/lib.rs | 2 +- src/tools/rust-analyzer/crates/tt/src/storage.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index a59fc2e08982..72b0d762ef62 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -129,7 +129,7 @@ impl Subtree { } } -/// `dispatch_ref! {}` +#[rust_analyzer::macro_style(braces)] macro_rules! dispatch_ref { ( match $scrutinee:expr => $tt:ident => $body:expr diff --git a/src/tools/rust-analyzer/crates/tt/src/storage.rs b/src/tools/rust-analyzer/crates/tt/src/storage.rs index 62d2e20016ac..4dd02d875a29 100644 --- a/src/tools/rust-analyzer/crates/tt/src/storage.rs +++ b/src/tools/rust-analyzer/crates/tt/src/storage.rs @@ -353,7 +353,7 @@ const _: () = { assert!(size_of::>() == 32); }; -/// `dispatch! {}` +#[rust_analyzer::macro_style(braces)] macro_rules! dispatch { ( match $scrutinee:expr => $tt:ident => $body:expr @@ -561,7 +561,7 @@ impl TopSubtree { } } -/// `dispatch_builder! {}` +#[rust_analyzer::macro_style(braces)] macro_rules! dispatch_builder { ( match $scrutinee:expr => $tt:ident => $body:expr From 62d19109c8af8bfcc5dc9ec4b99fb86fefc561ea Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 30 Dec 2025 17:05:56 -0500 Subject: [PATCH 1421/3801] Update cargo submodule --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 94c368ad2b9d..b54051b15052 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 94c368ad2b9db0f0da5bdd8421cea13786ce4412 +Subproject commit b54051b1505281ec7a45a250140a0ff25d33f319 From acd6ba4edbd847cb80ae140298701c13824852e8 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sat, 20 Dec 2025 14:50:13 +0100 Subject: [PATCH 1422/3801] Port `#[instruction_set]` to attribute parser --- compiler/rustc_attr_parsing/messages.ftl | 2 + .../src/attributes/instruction_set.rs | 73 ++++++++++++ .../rustc_attr_parsing/src/attributes/mod.rs | 1 + compiler/rustc_attr_parsing/src/context.rs | 2 + .../src/session_diagnostics.rs | 10 ++ compiler/rustc_codegen_ssa/messages.ftl | 8 -- .../rustc_codegen_ssa/src/codegen_attrs.rs | 41 +------ compiler/rustc_codegen_ssa/src/errors.rs | 28 ----- .../src/error_codes/E0778.md | 3 +- .../src/error_codes/E0779.md | 3 +- .../rustc_hir/src/attrs/data_structures.rs | 15 ++- .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 + tests/ui/attributes/instruction-set.rs | 111 ++++++++++++++++++ tests/ui/attributes/instruction-set.stderr | 31 +++++ .../invalid-instruction-set-target.rs | 6 + .../invalid-instruction-set-target.stderr | 8 ++ tests/ui/attributes/malformed-attrs.stderr | 19 +-- tests/ui/error-codes/E0778.rs | 4 - tests/ui/error-codes/E0778.stderr | 9 -- tests/ui/error-codes/E0779.rs | 2 - tests/ui/error-codes/E0779.stderr | 9 -- 23 files changed, 281 insertions(+), 109 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/instruction_set.rs create mode 100644 tests/ui/attributes/instruction-set.rs create mode 100644 tests/ui/attributes/instruction-set.stderr create mode 100644 tests/ui/attributes/invalid-instruction-set-target.rs create mode 100644 tests/ui/attributes/invalid-instruction-set-target.stderr delete mode 100644 tests/ui/error-codes/E0778.rs delete mode 100644 tests/ui/error-codes/E0778.stderr delete mode 100644 tests/ui/error-codes/E0779.rs delete mode 100644 tests/ui/error-codes/E0779.stderr diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 5caa98b05357..36213e68a52b 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -229,6 +229,8 @@ attr_parsing_unstable_cfg_target_compact = attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable .help = If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` +attr_parsing_unsupported_instruction_set = target `{$current_target}` does not support `#[instruction_set({$instruction_set}::*)]` + attr_parsing_unsupported_literal_suggestion = consider removing the prefix diff --git a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs new file mode 100644 index 000000000000..3be9b9ded9c1 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs @@ -0,0 +1,73 @@ +use rustc_hir::attrs::InstructionSetAttr; + +use super::prelude::*; +use crate::session_diagnostics; + +pub(crate) struct InstructionSetParser; + +impl SingleAttributeParser for InstructionSetParser { + const PATH: &[Symbol] = &[sym::instruction_set]; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + Allow(Target::Fn), + Allow(Target::Closure), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Method(MethodKind::Trait { body: true })), + ]); + const TEMPLATE: AttributeTemplate = template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute"); + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32]; + const POSSIBLE_ARM_SYMBOLS: &[Symbol] = &[sym::a32, sym::t32]; + let Some(maybe_meta_item) = args.list().and_then(MetaItemListParser::single) else { + cx.expected_specific_argument(cx.attr_span, POSSIBLE_SYMBOLS); + return None; + }; + + let Some(meta_item) = maybe_meta_item.meta_item() else { + cx.expected_specific_argument(maybe_meta_item.span(), POSSIBLE_SYMBOLS); + return None; + }; + + let mut segments = meta_item.path().segments(); + + let Some(architecture) = segments.next() else { + cx.expected_specific_argument(meta_item.span(), POSSIBLE_SYMBOLS); + return None; + }; + + let Some(instruction_set) = segments.next() else { + cx.expected_specific_argument(architecture.span, POSSIBLE_SYMBOLS); + return None; + }; + + let instruction_set = match architecture.name { + sym::arm => { + if !cx.sess.target.has_thumb_interworking { + cx.dcx().emit_err(session_diagnostics::UnsupportedInstructionSet { + span: cx.attr_span, + instruction_set: sym::arm, + current_target: &cx.sess.opts.target_triple, + }); + return None; + } + match instruction_set.name { + sym::a32 => InstructionSetAttr::ArmA32, + sym::t32 => InstructionSetAttr::ArmT32, + _ => { + cx.expected_specific_argument(instruction_set.span, POSSIBLE_ARM_SYMBOLS); + return None; + } + } + } + _ => { + cx.expected_specific_argument(architecture.span, POSSIBLE_SYMBOLS); + return None; + } + }; + + Some(AttributeKind::InstructionSet(instruction_set)) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index c39c60ea7e39..fafac7ea909d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -42,6 +42,7 @@ pub(crate) mod deprecation; pub(crate) mod doc; pub(crate) mod dummy; pub(crate) mod inline; +pub(crate) mod instruction_set; pub(crate) mod link_attrs; pub(crate) mod lint_helpers; pub(crate) mod loop_match; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9a443dfbb842..57962f0ce8b1 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -37,6 +37,7 @@ use crate::attributes::deprecation::DeprecationParser; use crate::attributes::doc::DocParser; use crate::attributes::dummy::DummyParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; +use crate::attributes::instruction_set::InstructionSetParser; use crate::attributes::link_attrs::{ ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser, LinkParser, LinkSectionParser, LinkageParser, StdInternalSymbolParser, @@ -197,6 +198,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index d9998a15f233..5b6aaf1d4f04 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -9,6 +9,7 @@ use rustc_feature::AttributeTemplate; use rustc_hir::AttrPath; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; +use rustc_target::spec::TargetTuple; use crate::fluent_generated as fluent; @@ -930,3 +931,12 @@ pub(crate) struct DocAliasMalformed { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(attr_parsing_unsupported_instruction_set)] +pub(crate) struct UnsupportedInstructionSet<'a> { + #[primary_span] + pub span: Span, + pub instruction_set: Symbol, + pub current_target: &'a TargetTuple, +} diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index ff78bea5b67c..1d87dc5da8d2 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -8,8 +8,6 @@ codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error} -codegen_ssa_bare_instruction_set = `#[instruction_set]` requires an argument - codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty codegen_ssa_cgu_not_recorded = @@ -90,8 +88,6 @@ codegen_ssa_incorrect_cgu_reuse_type = codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. -codegen_ssa_invalid_instruction_set = invalid instruction set specified - codegen_ssa_invalid_literal_value = invalid literal value .label = value must be an integer between `0` and `255` @@ -215,8 +211,6 @@ codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions -codegen_ssa_multiple_instruction_set = cannot specify more than one instruction set - codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times .help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point @@ -383,8 +377,6 @@ codegen_ssa_unstable_ctarget_feature = unstable feature specified for `-Ctarget-feature`: `{$feature}` .note = this feature is not stably supported; its behavior can change in the future -codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]` - codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 8135fd43dd93..6056b1582e42 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -3,9 +3,7 @@ use std::str::FromStr; use rustc_abi::{Align, ExternAbi}; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr}; -use rustc_hir::attrs::{ - AttributeKind, InlineAttr, InstructionSetAttr, Linkage, RtsanSetting, UsedBy, -}; +use rustc_hir::attrs::{AttributeKind, InlineAttr, Linkage, RtsanSetting, UsedBy}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items}; @@ -47,37 +45,6 @@ fn try_fn_sig<'tcx>( } } -// FIXME(jdonszelmann): remove when instruction_set becomes a parsed attr -fn parse_instruction_set_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> Option { - let list = attr.meta_item_list()?; - - match &list[..] { - [MetaItemInner::MetaItem(set)] => { - let segments = set.path.segments.iter().map(|x| x.ident.name).collect::>(); - match segments.as_slice() { - [sym::arm, sym::a32 | sym::t32] if !tcx.sess.target.has_thumb_interworking => { - tcx.dcx().emit_err(errors::UnsupportedInstructionSet { span: attr.span() }); - None - } - [sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32), - [sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32), - _ => { - tcx.dcx().emit_err(errors::InvalidInstructionSet { span: attr.span() }); - None - } - } - } - [] => { - tcx.dcx().emit_err(errors::BareInstructionSet { span: attr.span() }); - None - } - _ => { - tcx.dcx().emit_err(errors::MultipleInstructionSet { span: attr.span() }); - None - } - } -} - // FIXME(jdonszelmann): remove when patchable_function_entry becomes a parsed attr fn parse_patchable_function_entry( tcx: TyCtxt<'_>, @@ -353,6 +320,9 @@ fn process_builtin_attrs( AttributeKind::ThreadLocal => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL } + AttributeKind::InstructionSet(instruction_set) => { + codegen_fn_attrs.instruction_set = Some(*instruction_set) + } _ => {} } } @@ -369,9 +339,6 @@ fn process_builtin_attrs( sym::rustc_allocator_zeroed => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } - sym::instruction_set => { - codegen_fn_attrs.instruction_set = parse_instruction_set_attr(tcx, attr) - } sym::patchable_function_entry => { codegen_fn_attrs.patchable_function_entry = parse_patchable_function_entry(tcx, attr); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index c3d63e332989..95306c140895 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -136,34 +136,6 @@ pub(crate) struct RequiresRustAbi { pub span: Span, } -#[derive(Diagnostic)] -#[diag(codegen_ssa_unsupported_instruction_set, code = E0779)] -pub(crate) struct UnsupportedInstructionSet { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_invalid_instruction_set, code = E0779)] -pub(crate) struct InvalidInstructionSet { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_bare_instruction_set, code = E0778)] -pub(crate) struct BareInstructionSet { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_multiple_instruction_set, code = E0779)] -pub(crate) struct MultipleInstructionSet { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(codegen_ssa_expected_name_value_pair)] pub(crate) struct ExpectedNameValuePair { diff --git a/compiler/rustc_error_codes/src/error_codes/E0778.md b/compiler/rustc_error_codes/src/error_codes/E0778.md index 467362dca58f..4bdf85451c9b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0778.md +++ b/compiler/rustc_error_codes/src/error_codes/E0778.md @@ -1,8 +1,9 @@ +#### Note: this error code is no longer emitted by the compiler The `instruction_set` attribute was malformed. Erroneous code example: -```compile_fail,E0778 +```compile_fail #![feature(isa_attribute)] #[instruction_set()] // error: expected one argument diff --git a/compiler/rustc_error_codes/src/error_codes/E0779.md b/compiler/rustc_error_codes/src/error_codes/E0779.md index 146e20c26265..036931379a06 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0779.md +++ b/compiler/rustc_error_codes/src/error_codes/E0779.md @@ -1,8 +1,9 @@ +#### Note: this error code is no longer emitted by the compiler An unknown argument was given to the `instruction_set` attribute. Erroneous code example: -```compile_fail,E0779 +```compile_fail #![feature(isa_attribute)] #[instruction_set(intel::x64)] // error: invalid argument diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 39530f5c3f8b..55207a14ff51 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -60,7 +60,17 @@ impl InlineAttr { } } -#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)] +#[derive( + Copy, + Clone, + Encodable, + Decodable, + Debug, + PartialEq, + Eq, + HashStable_Generic, + PrintAttribute +)] pub enum InstructionSetAttr { ArmA32, ArmT32, @@ -807,6 +817,9 @@ pub enum AttributeKind { /// Represents `#[inline]` and `#[rustc_force_inline]`. Inline(InlineAttr, Span), + /// Represents `#[instruction_set]` + InstructionSet(InstructionSetAttr), + /// Represents `#[link]`. Link(ThinVec, Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 6d159a6ee68a..8d83efd48f26 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -54,6 +54,7 @@ impl AttributeKind { Fundamental { .. } => Yes, Ignore { .. } => No, Inline(..) => No, + InstructionSet(..) => No, Link(..) => No, LinkName { .. } => Yes, // Needed for rustdoc LinkOrdinal { .. } => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index fae269bfdcf1..7367879687fe 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -229,6 +229,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::Dummy | AttributeKind::RustcBuiltinMacro { .. } | AttributeKind::Ignore { .. } + | AttributeKind::InstructionSet(..) | AttributeKind::Path(..) | AttributeKind::NoImplicitPrelude(..) | AttributeKind::AutomaticallyDerived(..) @@ -337,7 +338,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::cfg_trace | sym::cfg_attr_trace // need to be fixed - | sym::instruction_set // broken on stable!!! | sym::patchable_function_entry // FIXME(patchable_function_entry) | sym::deprecated_safe // FIXME(deprecated_safe) // internal diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 0e30abccb62b..72709753b1df 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -472,6 +472,8 @@ symbols! { arith_offset, arm, arm64ec, + arm_a32: "arm::a32", + arm_t32: "arm::t32", arm_target_feature, array, as_dash_needed: "as-needed", diff --git a/tests/ui/attributes/instruction-set.rs b/tests/ui/attributes/instruction-set.rs new file mode 100644 index 000000000000..dafa907cb568 --- /dev/null +++ b/tests/ui/attributes/instruction-set.rs @@ -0,0 +1,111 @@ +//@ add-minicore +//@ compile-flags: --target armv5te-none-eabi +//@ needs-llvm-components: arm +//@ ignore-backends: gcc +//@ edition: 2024 + +#![crate_type = "lib"] +#![feature(no_core, lang_items,)] +#![no_core] + +extern crate minicore; +use minicore::*; + + + + +#[instruction_set(arm::a32)] +fn foo() { +} + +#[instruction_set(arm)] +//~^ ERROR malformed `instruction_set` attribute input [E0539] +fn bar() { +} + +#[instruction_set(arm::)] +//~^ ERROR expected identifier, found `` +fn bazz() { +} + +#[instruction_set(arm::magic)] +//~^ ERROR malformed `instruction_set` attribute input [E0539] +fn bazzer() { + +} + +fn all_instruction_set_cases() { + #[instruction_set(arm::a32)] + || { + 0 + }; + #[instruction_set(arm::t32)] + async || { + 0 + }; +} + +struct Fooer; + +impl Fooer { + #[instruction_set(arm::a32)] + fn fooest() { + + } +} + +trait Bazzest { + fn bazz(); + + #[instruction_set(arm::a32)] + fn bazziest() { + + } +} +impl Bazzest for Fooer { + #[instruction_set(arm::t32)] + fn bazz() {} +} + + +// The following lang items need to be defined for the async closure to work +#[lang = "ResumeTy"] +pub struct ResumeTy(NonNull>); + +#[lang = "future_trait"] +pub trait Future { + /// The type of value produced on completion. + #[lang = "future_output"] + type Output; + + // NOTE: misses the `poll` method. +} + +#[lang = "async_drop"] +pub trait AsyncDrop { + // NOTE: misses the `drop` method. +} + +#[lang = "Poll"] +pub enum Poll { + #[lang = "Ready"] + Ready(T), + + #[lang = "Pending"] + Pending, +} + +#[lang = "Context"] +pub struct Context<'a> { + // NOTE: misses a bunch of fields. + _marker: PhantomData &'a ()>, +} + +#[lang = "get_context"] +pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { + // NOTE: the actual implementation looks different. + unsafe {mem::transmute(cx.0)} +} + +#[lang = "pin"] +pub struct Pin(T); diff --git a/tests/ui/attributes/instruction-set.stderr b/tests/ui/attributes/instruction-set.stderr new file mode 100644 index 000000000000..c5aea396b53e --- /dev/null +++ b/tests/ui/attributes/instruction-set.stderr @@ -0,0 +1,31 @@ +error[E0539]: malformed `instruction_set` attribute input + --> $DIR/instruction-set.rs:21:1 + | +LL | #[instruction_set(arm)] + | ^^^^^^^^^^^^^^^^^^---^^ + | | | + | | valid arguments are `arm::a32` or `arm::t32` + | help: must be of the form: `#[instruction_set(set)]` + | + = note: for more information, visit + +error: expected identifier, found `` + --> $DIR/instruction-set.rs:26:22 + | +LL | #[instruction_set(arm::)] + | ^^ expected identifier + +error[E0539]: malformed `instruction_set` attribute input + --> $DIR/instruction-set.rs:31:1 + | +LL | #[instruction_set(arm::magic)] + | ^^^^^^^^^^^^^^^^^^^^^^^-----^^ + | | | + | | valid arguments are `a32` or `t32` + | help: must be of the form: `#[instruction_set(set)]` + | + = note: for more information, visit + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/invalid-instruction-set-target.rs b/tests/ui/attributes/invalid-instruction-set-target.rs new file mode 100644 index 000000000000..08b261c1b309 --- /dev/null +++ b/tests/ui/attributes/invalid-instruction-set-target.rs @@ -0,0 +1,6 @@ +//@ only-x86_64-unknown-linux-gnu + +#[instruction_set(arm::a32)] +//~^ ERROR target `x86_64-unknown-linux-gnu` does not support `#[instruction_set(arm::*)]` +fn main() { +} diff --git a/tests/ui/attributes/invalid-instruction-set-target.stderr b/tests/ui/attributes/invalid-instruction-set-target.stderr new file mode 100644 index 000000000000..d99fbd369a0e --- /dev/null +++ b/tests/ui/attributes/invalid-instruction-set-target.stderr @@ -0,0 +1,8 @@ +error: target `x86_64-unknown-linux-gnu` does not support `#[instruction_set(arm::*)]` + --> $DIR/invalid-instruction-set-target.rs:3:1 + | +LL | #[instruction_set(arm::a32)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 860dcdb349bf..7027328bc27b 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -26,14 +26,6 @@ error[E0463]: can't find crate for `wloop` LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate -error: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:112:1 - | -LL | #[instruction_set] - | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` - | - = note: for more information, visit - error: malformed `patchable_function_entry` attribute input --> $DIR/malformed-attrs.rs:114:1 | @@ -456,6 +448,17 @@ LL | #[proc_macro = 18] | | didn't expect any arguments here | help: must be of the form: `#[proc_macro]` +error[E0539]: malformed `instruction_set` attribute input + --> $DIR/malformed-attrs.rs:112:1 + | +LL | #[instruction_set] + | ^^^^^^^^^^^^^^^^^^ + | | + | valid arguments are `arm::a32` or `arm::t32` + | help: must be of the form: `#[instruction_set(set)]` + | + = note: for more information, visit + error[E0565]: malformed `coroutine` attribute input --> $DIR/malformed-attrs.rs:117:5 | diff --git a/tests/ui/error-codes/E0778.rs b/tests/ui/error-codes/E0778.rs deleted file mode 100644 index 74653886d415..000000000000 --- a/tests/ui/error-codes/E0778.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[instruction_set()] //~ ERROR -fn no_isa_defined() {} - -fn main() {} diff --git a/tests/ui/error-codes/E0778.stderr b/tests/ui/error-codes/E0778.stderr deleted file mode 100644 index 7eb24c493bf5..000000000000 --- a/tests/ui/error-codes/E0778.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0778]: `#[instruction_set]` requires an argument - --> $DIR/E0778.rs:1:1 - | -LL | #[instruction_set()] - | ^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0778`. diff --git a/tests/ui/error-codes/E0779.rs b/tests/ui/error-codes/E0779.rs deleted file mode 100644 index c32dae12c9cb..000000000000 --- a/tests/ui/error-codes/E0779.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[instruction_set(arm::magic)] //~ ERROR -fn main() {} diff --git a/tests/ui/error-codes/E0779.stderr b/tests/ui/error-codes/E0779.stderr deleted file mode 100644 index a01aa98b914c..000000000000 --- a/tests/ui/error-codes/E0779.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0779]: invalid instruction set specified - --> $DIR/E0779.rs:1:1 - | -LL | #[instruction_set(arm::magic)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0779`. From 74e0a9aa8147cc640120d73ec868507e37b29db1 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 4 Oct 2025 23:35:19 -0400 Subject: [PATCH 1423/3801] Make inliner cycle detection a fallible process --- compiler/rustc_middle/src/query/mod.rs | 5 ++-- compiler/rustc_mir_transform/src/inline.rs | 7 ++++-- .../rustc_mir_transform/src/inline/cycle.rs | 23 ++++++++++--------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b2473052b442..08db16ba8ecb 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1312,8 +1312,9 @@ rustc_queries! { return_result_from_ensure_ok } - /// Return the set of (transitive) callees that may result in a recursive call to `key`. - query mir_callgraph_cyclic(key: LocalDefId) -> &'tcx UnordSet { + /// Return the set of (transitive) callees that may result in a recursive call to `key`, + /// if we were able to walk all callees. + query mir_callgraph_cyclic(key: LocalDefId) -> &'tcx Option> { fatal_cycle arena_cache desc { |tcx| diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 9e3ca9b30d53..1e9665f4337d 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -775,8 +775,11 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( { // If we know for sure that the function we're calling will itself try to // call us, then we avoid inlining that function. - if inliner.tcx().mir_callgraph_cyclic(caller_def_id.expect_local()).contains(&callee_def_id) - { + let Some(cyclic_callees) = inliner.tcx().mir_callgraph_cyclic(caller_def_id.expect_local()) + else { + return Err("call graph cycle detection bailed due to recursion limit"); + }; + if cyclic_callees.contains(&callee_def_id) { debug!("query cycle avoidance"); return Err("caller might be reachable from callee"); } diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 25a9baffe582..9d031b654802 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -68,7 +68,7 @@ fn process<'tcx>( involved: &mut FxHashSet, recursion_limiter: &mut FxHashMap, recursion_limit: Limit, -) -> bool { +) -> Option { trace!(%caller); let mut reaches_root = false; @@ -127,10 +127,9 @@ fn process<'tcx>( recursion_limiter, recursion_limit, ) - }) + })? } else { - // Pessimistically assume that there could be recursion. - true + return None; }; seen.insert(callee, callee_reaches_root); callee_reaches_root @@ -144,14 +143,14 @@ fn process<'tcx>( } } - reaches_root + Some(reaches_root) } #[instrument(level = "debug", skip(tcx), ret)] pub(crate) fn mir_callgraph_cyclic<'tcx>( tcx: TyCtxt<'tcx>, root: LocalDefId, -) -> UnordSet { +) -> Option> { assert!( !tcx.is_constructor(root.to_def_id()), "you should not call `mir_callgraph_reachable` on enum/struct constructor functions" @@ -164,16 +163,16 @@ pub(crate) fn mir_callgraph_cyclic<'tcx>( // limit, we will hit the limit first and give up on looking for inlining. And in any case, // the default recursion limits are quite generous for us. If we need to recurse 64 times // into the call graph, we're probably not going to find any useful MIR inlining. - let recursion_limit = tcx.recursion_limit() / 2; + let recursion_limit = tcx.recursion_limit() / 8; let mut involved = FxHashSet::default(); let typing_env = ty::TypingEnv::post_analysis(tcx, root); let root_instance = ty::Instance::new_raw(root.to_def_id(), ty::GenericArgs::identity_for_item(tcx, root)); if !should_recurse(tcx, root_instance) { trace!("cannot walk, skipping"); - return involved.into(); + return Some(involved.into()); } - process( + match process( tcx, typing_env, root_instance, @@ -182,8 +181,10 @@ pub(crate) fn mir_callgraph_cyclic<'tcx>( &mut involved, &mut FxHashMap::default(), recursion_limit, - ); - involved.into() + ) { + Some(_) => Some(involved.into()), + _ => None, + } } pub(crate) fn mir_inliner_callees<'tcx>( From cee7f5ed318e0717e2d86d94c8d08bc0a69a3355 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 30 Dec 2025 22:21:03 -0500 Subject: [PATCH 1424/3801] Add a regression test --- tests/mir-opt/inline/auxiliary/wrapper.rs | 10 ++++ ...ecursion_limit_prevents_cycle_discovery.rs | 54 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 tests/mir-opt/inline/auxiliary/wrapper.rs create mode 100644 tests/mir-opt/inline/recursion_limit_prevents_cycle_discovery.rs diff --git a/tests/mir-opt/inline/auxiliary/wrapper.rs b/tests/mir-opt/inline/auxiliary/wrapper.rs new file mode 100644 index 000000000000..35d3ae788239 --- /dev/null +++ b/tests/mir-opt/inline/auxiliary/wrapper.rs @@ -0,0 +1,10 @@ +//@ no-prefer-dynamic +//@ compile-flags: -O + +pub trait Compare { + fn eq(self); +} + +pub fn wrap(a: A) { + Compare::eq(a); +} diff --git a/tests/mir-opt/inline/recursion_limit_prevents_cycle_discovery.rs b/tests/mir-opt/inline/recursion_limit_prevents_cycle_discovery.rs new file mode 100644 index 000000000000..866d6fbd9e97 --- /dev/null +++ b/tests/mir-opt/inline/recursion_limit_prevents_cycle_discovery.rs @@ -0,0 +1,54 @@ +//@ aux-build: wrapper.rs +//@ compile-flags: -Zmir-opt-level=2 -Zinline-mir +// skip-filecheck + +// This is a regression test for https://github.com/rust-lang/rust/issues/146998 + +extern crate wrapper; +use wrapper::{Compare, wrap}; + +pub struct BundleInner; + +impl Compare for BundleInner { + fn eq(self) { + lots_of_calls(); + wrap(Resource::ExtensionValue); + } +} + +pub enum Resource { + Bundle, + ExtensionValue, +} + +impl Compare for Resource { + fn eq(self) { + match self { + Self::Bundle => wrap(BundleInner), + Self::ExtensionValue => lots_of_calls(), + } + } +} + +macro_rules! units { + ($($n: ident)*) => { + $( + struct $n; + + impl Compare for $n { + fn eq(self) { } + } + + wrap($n); + )* + }; +} + +fn lots_of_calls() { + units! { + O1 O2 O3 O4 O5 O6 O7 O8 O9 O10 O11 O12 O13 O14 O15 O16 O17 O18 O19 O20 + O21 O22 O23 O24 O25 O26 O27 O28 O29 O30 O31 O32 O33 O34 O35 O36 O37 O38 O39 O40 + O41 O42 O43 O44 O45 O46 O47 O48 O49 O50 O51 O52 O53 O54 O55 O56 O57 O58 O59 O60 + O61 O62 O63 O64 O65 + } +} From ef8d943ecddc978169cbee1f47f34fb7e8450804 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 31 Dec 2025 11:10:29 +1100 Subject: [PATCH 1425/3801] Remove `feature(string_deref_patterns)` --- compiler/rustc_feature/src/removed.rs | 2 + compiler/rustc_feature/src/unstable.rs | 2 - compiler/rustc_hir_typeck/src/pat.rs | 14 ------ compiler/rustc_middle/src/thir.rs | 1 - .../src/builder/matches/test.rs | 30 +----------- .../rustc_mir_build/src/thir/pattern/mod.rs | 18 +------ .../src/language-features/deref-patterns.md | 3 +- .../string-deref-patterns.md | 48 ------------------- .../string.foo.PreCodegen.after.mir | 20 ++++---- .../building/match/deref-patterns/string.rs | 3 +- tests/ui/README.md | 6 --- tests/ui/deref-patterns/gate.rs | 7 --- tests/ui/deref-patterns/gate.stderr | 11 ----- .../ui/{ => pattern}/deref-patterns/basic.rs | 3 +- .../deref-patterns/basic.run.stdout | 0 .../deref-patterns/default-infer.rs | 3 +- tests/ui/{ => pattern}/deref-patterns/refs.rs | 3 +- 17 files changed, 24 insertions(+), 150 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/string-deref-patterns.md delete mode 100644 tests/ui/deref-patterns/gate.rs delete mode 100644 tests/ui/deref-patterns/gate.stderr rename tests/ui/{ => pattern}/deref-patterns/basic.rs (83%) rename tests/ui/{ => pattern}/deref-patterns/basic.run.stdout (100%) rename tests/ui/{ => pattern}/deref-patterns/default-infer.rs (66%) rename tests/ui/{ => pattern}/deref-patterns/refs.rs (79%) diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index e5d66364c2a6..9d8a84c52e98 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -271,6 +271,8 @@ declare_features! ( /// Allows `#[link(kind = "static-nobundle", ...)]`. (removed, static_nobundle, "1.63.0", Some(37403), Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#), 95818), + /// Allows string patterns to dereference values to match them. + (removed, string_deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), Some("superseded by `deref_patterns`"), 150530), (removed, struct_inherit, "1.0.0", None, None), (removed, test_removed_feature, "1.0.0", None, None), /// Allows using items which are missing stability attributes diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 692cba8035c4..34b7cac5c941 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -647,8 +647,6 @@ declare_features! ( (unstable, stmt_expr_attributes, "1.6.0", Some(15701)), /// Allows lints part of the strict provenance effort. (unstable, strict_provenance_lints, "1.61.0", Some(130351)), - /// Allows string patterns to dereference values to match them. - (unstable, string_deref_patterns, "1.67.0", Some(87121)), /// Allows `super let` statements. (unstable, super_let, "1.88.0", Some(139076)), /// Allows subtrait items to shadow supertrait items. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 1a579c4c6fa4..90e22b2cd381 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -996,20 +996,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_ty = self.tcx.types.str_; } - if self.tcx.features().string_deref_patterns() - && let hir::PatExprKind::Lit { - lit: Spanned { node: ast::LitKind::Str(..), .. }, .. - } = lt.kind - { - let tcx = self.tcx; - let expected = self.resolve_vars_if_possible(expected); - pat_ty = match expected.kind() { - ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => expected, - ty::Str => Ty::new_static_str(tcx), - _ => pat_ty, - }; - } - // Somewhat surprising: in this case, the subtyping relation goes the // opposite way as the other cases. Actually what we really want is not // a subtyping relation at all but rather that there exists a LUB diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 65bfc7d362b6..3683c1cfb7dd 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -827,7 +827,6 @@ pub enum PatKind<'tcx> { /// much simpler. /// * raw pointers derived from integers, other raw pointers will have already resulted in an /// error. - /// * `String`, if `string_deref_patterns` is enabled. Constant { value: ty::Value<'tcx>, }, diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index cac4f7b7ab4f..972d9f66fadd 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -150,7 +150,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut expect = self.literal_operand(test.span, Const::from_ty_value(tcx, value)); let mut place = place; - let mut block = block; + match cast_ty.kind() { ty::Str => { // String literal patterns may have type `str` if `deref_patterns` is @@ -175,34 +175,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { place = ref_place; cast_ty = ref_str_ty; } - ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => { - if !tcx.features().string_deref_patterns() { - span_bug!( - test.span, - "matching on `String` went through without enabling string_deref_patterns" - ); - } - let re_erased = tcx.lifetimes.re_erased; - let ref_str_ty = Ty::new_imm_ref(tcx, re_erased, tcx.types.str_); - let ref_str = self.temp(ref_str_ty, test.span); - let eq_block = self.cfg.start_new_block(); - // `let ref_str: &str = ::deref(&place);` - self.call_deref( - block, - eq_block, - place, - Mutability::Not, - cast_ty, - ref_str, - test.span, - ); - // Since we generated a `ref_str = ::deref(&place) -> eq_block` terminator, - // we need to add all further statements to `eq_block`. - // Similarly, the normal test code should be generated for the `&str`, instead of the `String`. - block = eq_block; - place = ref_str; - cast_ty = ref_str_ty; - } &ty::Pat(base, _) => { assert_eq!(cast_ty, value.ty); assert!(base.is_trivially_pure_clone_copy()); diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 063bb4a3d461..0310003e7d58 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -11,7 +11,7 @@ use rustc_abi::{FieldIdx, Integer}; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::{self as hir, LangItem, RangeEnd}; +use rustc_hir::{self as hir, RangeEnd}; use rustc_index::Idx; use rustc_middle::mir::interpret::LitToConstInput; use rustc_middle::thir::{ @@ -626,23 +626,7 @@ impl<'tcx> PatCtxt<'tcx> { // the pattern's type will be `&[u8]` whereas the literal's type is `&[u8; 3]`; using the // pattern's type means we'll properly translate it to a slice reference pattern. This works // because slices and arrays have the same valtree representation. - // HACK: As an exception, use the literal's type if `pat_ty` is `String`; this can happen if - // `string_deref_patterns` is enabled. There's a special case for that when lowering to MIR. - // FIXME(deref_patterns): This hack won't be necessary once `string_deref_patterns` is - // superseded by a more general implementation of deref patterns. let ct_ty = match pat_ty { - Some(pat_ty) - if let ty::Adt(def, _) = *pat_ty.kind() - && self.tcx.is_lang_item(def.did(), LangItem::String) => - { - if !self.tcx.features().string_deref_patterns() { - span_bug!( - expr.span, - "matching on `String` went through without enabling string_deref_patterns" - ); - } - self.typeck_results.node_type(expr.hir_id) - } Some(pat_ty) => pat_ty, None => self.typeck_results.node_type(expr.hir_id), }; diff --git a/src/doc/unstable-book/src/language-features/deref-patterns.md b/src/doc/unstable-book/src/language-features/deref-patterns.md index 4c3d456b9af8..23c2dc688400 100644 --- a/src/doc/unstable-book/src/language-features/deref-patterns.md +++ b/src/doc/unstable-book/src/language-features/deref-patterns.md @@ -7,7 +7,7 @@ The tracking issue for this feature is: [#87121] ------------------------ > **Note**: This feature is incomplete. In the future, it is meant to supersede -> [`box_patterns`] and [`string_deref_patterns`]. +> [`box_patterns`]. This feature permits pattern matching on [smart pointers in the standard library] through their `Deref` target types, either implicitly or with explicit `deref!(_)` patterns (the syntax of which @@ -103,5 +103,4 @@ match *(b"test" as &[u8]) { ``` [`box_patterns`]: ./box-patterns.md -[`string_deref_patterns`]: ./string-deref-patterns.md [smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors diff --git a/src/doc/unstable-book/src/language-features/string-deref-patterns.md b/src/doc/unstable-book/src/language-features/string-deref-patterns.md deleted file mode 100644 index 366bb15d4ea8..000000000000 --- a/src/doc/unstable-book/src/language-features/string-deref-patterns.md +++ /dev/null @@ -1,48 +0,0 @@ -# `string_deref_patterns` - -The tracking issue for this feature is: [#87121] - -[#87121]: https://github.com/rust-lang/rust/issues/87121 - ------------------------- - -> **Note**: This feature will be superseded by [`deref_patterns`] in the future. - -This feature permits pattern matching `String` to `&str` through [its `Deref` implementation]. - -```rust -#![feature(string_deref_patterns)] - -pub enum Value { - String(String), - Number(u32), -} - -pub fn is_it_the_answer(value: Value) -> bool { - match value { - Value::String("42") => true, - Value::Number(42) => true, - _ => false, - } -} -``` - -Without this feature other constructs such as match guards have to be used. - -```rust -# pub enum Value { -# String(String), -# Number(u32), -# } -# -pub fn is_it_the_answer(value: Value) -> bool { - match value { - Value::String(s) if s == "42" => true, - Value::Number(42) => true, - _ => false, - } -} -``` - -[`deref_patterns`]: ./deref-patterns.md -[its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String diff --git a/tests/mir-opt/building/match/deref-patterns/string.foo.PreCodegen.after.mir b/tests/mir-opt/building/match/deref-patterns/string.foo.PreCodegen.after.mir index 9f52a8cd1e55..c7c26d6351ad 100644 --- a/tests/mir-opt/building/match/deref-patterns/string.foo.PreCodegen.after.mir +++ b/tests/mir-opt/building/match/deref-patterns/string.foo.PreCodegen.after.mir @@ -7,10 +7,11 @@ fn foo(_1: Option) -> i32 { let mut _3: isize; let mut _4: &std::string::String; let mut _5: &str; - let mut _6: bool; - let _7: std::option::Option; + let mut _6: &str; + let mut _7: bool; + let _8: std::option::Option; scope 1 { - debug s => _7; + debug s => _8; } bb0: { @@ -26,11 +27,12 @@ fn foo(_1: Option) -> i32 { } bb2: { - _6 = ::eq(copy _5, const "a") -> [return: bb3, unwind unreachable]; + _6 = &(*_5); + _7 = ::eq(copy _6, const "a") -> [return: bb3, unwind unreachable]; } bb3: { - switchInt(move _6) -> [0: bb5, otherwise: bb4]; + switchInt(move _7) -> [0: bb5, otherwise: bb4]; } bb4: { @@ -39,15 +41,15 @@ fn foo(_1: Option) -> i32 { } bb5: { - StorageLive(_7); + StorageLive(_8); _2 = const false; - _7 = move _1; + _8 = move _1; _0 = const 4321_i32; - drop(_7) -> [return: bb6, unwind unreachable]; + drop(_8) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_7); + StorageDead(_8); goto -> bb7; } diff --git a/tests/mir-opt/building/match/deref-patterns/string.rs b/tests/mir-opt/building/match/deref-patterns/string.rs index bb4b5379b275..1f8d6fbb0bd2 100644 --- a/tests/mir-opt/building/match/deref-patterns/string.rs +++ b/tests/mir-opt/building/match/deref-patterns/string.rs @@ -1,7 +1,8 @@ // skip-filecheck //@ compile-flags: -Z mir-opt-level=0 -C panic=abort -#![feature(string_deref_patterns)] +#![feature(deref_patterns)] +#![expect(incomplete_features)] #![crate_type = "lib"] // EMIT_MIR string.foo.PreCodegen.after.mir diff --git a/tests/ui/README.md b/tests/ui/README.md index b1c813cce93f..4c91f313a735 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -380,12 +380,6 @@ These tests use the unstable command line option `query-dep-graph` to examine th Tests for `#[deprecated]` attribute and `deprecated_in_future` internal lint. -## `tests/ui/deref-patterns/`: `#![feature(deref_patterns)]` and `#![feature(string_deref_patterns)]` - -Tests for `#![feature(deref_patterns)]` and `#![feature(string_deref_patterns)]`. See [Deref patterns | The Unstable book](https://doc.rust-lang.org/nightly/unstable-book/language-features/deref-patterns.html). - -**FIXME**: May have some overlap with `tests/ui/pattern/deref-patterns`. - ## `tests/ui/derived-errors/`: Derived Error Messages Tests for quality of diagnostics involving suppression of cascading errors in some cases to avoid overwhelming the user. diff --git a/tests/ui/deref-patterns/gate.rs b/tests/ui/deref-patterns/gate.rs deleted file mode 100644 index 835fdf854d2c..000000000000 --- a/tests/ui/deref-patterns/gate.rs +++ /dev/null @@ -1,7 +0,0 @@ -// gate-test-string_deref_patterns -fn main() { - match String::new() { - "" | _ => {} - //~^ ERROR mismatched types - } -} diff --git a/tests/ui/deref-patterns/gate.stderr b/tests/ui/deref-patterns/gate.stderr deleted file mode 100644 index e3cbded339d7..000000000000 --- a/tests/ui/deref-patterns/gate.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/gate.rs:4:9 - | -LL | match String::new() { - | ------------- this expression has type `String` -LL | "" | _ => {} - | ^^ expected `String`, found `&str` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/deref-patterns/basic.rs b/tests/ui/pattern/deref-patterns/basic.rs similarity index 83% rename from tests/ui/deref-patterns/basic.rs rename to tests/ui/pattern/deref-patterns/basic.rs index d76fb697f406..dee4521e1f95 100644 --- a/tests/ui/deref-patterns/basic.rs +++ b/tests/ui/pattern/deref-patterns/basic.rs @@ -1,6 +1,7 @@ //@ run-pass //@ check-run-results -#![feature(string_deref_patterns)] +#![feature(deref_patterns)] +#![expect(incomplete_features)] fn main() { test(Some(String::from("42"))); diff --git a/tests/ui/deref-patterns/basic.run.stdout b/tests/ui/pattern/deref-patterns/basic.run.stdout similarity index 100% rename from tests/ui/deref-patterns/basic.run.stdout rename to tests/ui/pattern/deref-patterns/basic.run.stdout diff --git a/tests/ui/deref-patterns/default-infer.rs b/tests/ui/pattern/deref-patterns/default-infer.rs similarity index 66% rename from tests/ui/deref-patterns/default-infer.rs rename to tests/ui/pattern/deref-patterns/default-infer.rs index 4f926175bd33..fb0b2add132a 100644 --- a/tests/ui/deref-patterns/default-infer.rs +++ b/tests/ui/pattern/deref-patterns/default-infer.rs @@ -1,5 +1,6 @@ //@ check-pass -#![feature(string_deref_patterns)] +#![feature(deref_patterns)] +#![expect(incomplete_features)] fn main() { match <_ as Default>::default() { diff --git a/tests/ui/deref-patterns/refs.rs b/tests/ui/pattern/deref-patterns/refs.rs similarity index 79% rename from tests/ui/deref-patterns/refs.rs rename to tests/ui/pattern/deref-patterns/refs.rs index c93e579bfd80..51826225856b 100644 --- a/tests/ui/deref-patterns/refs.rs +++ b/tests/ui/pattern/deref-patterns/refs.rs @@ -1,5 +1,6 @@ //@ check-pass -#![feature(string_deref_patterns)] +#![feature(deref_patterns)] +#![expect(incomplete_features)] fn foo(s: &String) -> i32 { match *s { From 59a3ad3e13a87e1b8ab9f4481faf764484509c27 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Wed, 31 Dec 2025 05:53:50 +0000 Subject: [PATCH 1426/3801] Enable thumb interworking on ARMv7A/R and ARMv8R bare-metal targets --- compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs | 1 + compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs | 1 + compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs | 1 + compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs | 1 + compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs | 1 + compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs | 1 + compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs | 1 + 7 files changed, 7 insertions(+) diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs index 849a0f4c9a68..7a62464aea4b 100644 --- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabi.rs @@ -31,6 +31,7 @@ pub(crate) fn target() -> Target { emit_debug_gdb_scripts: false, // GCC defaults to 8 for arm-none here. c_enum_min_bits: Some(8), + has_thumb_interworking: true, ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs index 0cf3880cadc9..33147c5f1b09 100644 --- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs @@ -32,6 +32,7 @@ pub(crate) fn target() -> Target { emit_debug_gdb_scripts: false, // GCC defaults to 8 for arm-none here. c_enum_min_bits: Some(8), + has_thumb_interworking: true, ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs index 13a95a113b13..6b7707a47390 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs @@ -32,6 +32,7 @@ pub(crate) fn target() -> Target { panic_strategy: PanicStrategy::Abort, emit_debug_gdb_scripts: false, c_enum_min_bits: Some(8), + has_thumb_interworking: true, ..Default::default() }; Target { diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs index 28efdbe2291f..993390543b96 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs @@ -24,6 +24,7 @@ pub(crate) fn target() -> Target { emit_debug_gdb_scripts: false, // GCC defaults to 8 for arm-none here. c_enum_min_bits: Some(8), + has_thumb_interworking: true, ..Default::default() }; Target { diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs index b490b716f4b0..551cbf4a589f 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs @@ -29,6 +29,7 @@ pub(crate) fn target() -> Target { emit_debug_gdb_scripts: false, // GCC defaults to 8 for arm-none here. c_enum_min_bits: Some(8), + has_thumb_interworking: true, ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs index 7a3eb3b811a6..97c911ec8090 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs @@ -30,6 +30,7 @@ pub(crate) fn target() -> Target { emit_debug_gdb_scripts: false, // GCC defaults to 8 for arm-none here. c_enum_min_bits: Some(8), + has_thumb_interworking: true, ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs index 423bf260d89c..e36240b9c223 100644 --- a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs @@ -39,6 +39,7 @@ pub(crate) fn target() -> Target { emit_debug_gdb_scripts: false, // GCC defaults to 8 for arm-none here. c_enum_min_bits: Some(8), + has_thumb_interworking: true, ..Default::default() }, } From 935e3cbb86c81b88777e2de8ab45e0363e95412d Mon Sep 17 00:00:00 2001 From: Jefffrey Date: Wed, 31 Dec 2025 15:29:51 +0900 Subject: [PATCH 1427/3801] fix: don't fire `non_camel_case_types` lint for structs/enums marked with `repr(C)` --- .../crates/hir-def/src/signatures.rs | 11 ++++++ .../hir-ty/src/diagnostics/decl_check.rs | 37 ++++++++++++------- .../src/handlers/incorrect_case.rs | 15 ++++++++ .../crates/ide-diagnostics/src/lib.rs | 1 - 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs index a13ef484baa5..0dd88edbfb08 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs @@ -185,6 +185,9 @@ impl UnionSignature { bitflags! { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct EnumFlags: u8 { + /// Indicates whether this enum has `#[repr]`. + const HAS_REPR = 1 << 0; + /// Indicates whether the enum has a `#[rustc_has_incoherent_inherent_impls]` attribute. const RUSTC_HAS_INCOHERENT_INHERENT_IMPLS = 1 << 1; } } @@ -205,6 +208,9 @@ impl EnumSignature { if attrs.contains(AttrFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS) { flags |= EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS; } + if attrs.contains(AttrFlags::HAS_REPR) { + flags |= EnumFlags::HAS_REPR; + } let InFile { file_id, value: source } = loc.source(db); let (store, generic_params, source_map) = lower_generic_params( @@ -233,6 +239,11 @@ impl EnumSignature { _ => IntegerType::Pointer(true), } } + + #[inline] + pub fn repr(&self, db: &dyn DefDatabase, id: EnumId) -> Option { + if self.flags.contains(EnumFlags::HAS_REPR) { AttrFlags::repr(db, id.into()) } else { None } + } } bitflags::bitflags! { #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs index a6852b87f601..29da1b0c513b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs @@ -293,12 +293,18 @@ impl<'a> DeclValidator<'a> { fn validate_struct(&mut self, struct_id: StructId) { // Check the structure name. let data = self.db.struct_signature(struct_id); - self.create_incorrect_case_diagnostic_for_item_name( - struct_id, - &data.name, - CaseType::UpperCamelCase, - IdentType::Structure, - ); + + // rustc implementation excuses repr(C) since C structs predominantly don't + // use camel case. + let has_repr_c = data.repr(self.db, struct_id).is_some_and(|repr| repr.c()); + if !has_repr_c { + self.create_incorrect_case_diagnostic_for_item_name( + struct_id, + &data.name, + CaseType::UpperCamelCase, + IdentType::Structure, + ); + } // Check the field names. self.validate_struct_fields(struct_id); @@ -378,15 +384,20 @@ impl<'a> DeclValidator<'a> { } fn validate_enum(&mut self, enum_id: EnumId) { + // Check the enum name. let data = self.db.enum_signature(enum_id); - // Check the enum name. - self.create_incorrect_case_diagnostic_for_item_name( - enum_id, - &data.name, - CaseType::UpperCamelCase, - IdentType::Enum, - ); + // rustc implementation excuses repr(C) since C structs predominantly don't + // use camel case. + let has_repr_c = data.repr(self.db, enum_id).is_some_and(|repr| repr.c()); + if !has_repr_c { + self.create_incorrect_case_diagnostic_for_item_name( + enum_id, + &data.name, + CaseType::UpperCamelCase, + IdentType::Enum, + ); + } // Check the variant names. self.validate_enum_variants(enum_id) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs index 8f68312b40f8..c47449f2593d 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs @@ -1059,4 +1059,19 @@ fn foo(_HelloWorld: ()) {} "#, ); } + + #[test] + fn allow_with_repr_c() { + check_diagnostics( + r#" +#[repr(C)] +struct FFI_Struct; + +#[repr(C)] +enum FFI_Enum { + Field, +} + "#, + ); + } } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index 360ded1c0be4..0c6953419f7d 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -108,7 +108,6 @@ use syntax::{ ast::{self, AstNode}, }; -// FIXME: Make this an enum #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum DiagnosticCode { RustcHardError(&'static str), From c19e9ecdd912cfe55a407275bb04eaf334eb3264 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 31 Dec 2025 16:18:33 +0800 Subject: [PATCH 1428/3801] Fix incorrect dyn hint in `impl Trait for` Example --- ```rust trait T {} impl T for {} ``` **Before this PR** ```rust trait T {} impl T for {} // ^ dyn ``` **After this PR** ```rust trait T {} impl T for {} ``` --- .../ide/src/inlay_hints/implied_dyn_trait.rs | 1 + .../crates/syntax/src/ast/node_ext.rs | 23 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs index 4fbc88a210cf..ac91da9a3cec 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs @@ -105,6 +105,7 @@ impl T {} // ^ dyn impl T for (T) {} // ^ dyn +impl T for {} impl T "#, ); diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index 3357b250115c..76cfea9d5bc6 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -447,24 +447,23 @@ impl ast::UseTreeList { impl ast::Impl { pub fn self_ty(&self) -> Option { - match self.target() { - (Some(t), None) | (_, Some(t)) => Some(t), - _ => None, - } + self.target().1 } pub fn trait_(&self) -> Option { - match self.target() { - (Some(t), Some(_)) => Some(t), - _ => None, - } + self.target().0 } fn target(&self) -> (Option, Option) { - let mut types = support::children(self.syntax()); - let first = types.next(); - let second = types.next(); - (first, second) + let mut types = support::children(self.syntax()).peekable(); + let for_kw = self.for_token(); + let trait_ = types.next_if(|trait_: &ast::Type| { + for_kw.is_some_and(|for_kw| { + trait_.syntax().text_range().start() < for_kw.text_range().start() + }) + }); + let self_ty = types.next(); + (trait_, self_ty) } pub fn for_trait_name_ref(name_ref: &ast::NameRef) -> Option { From 862ab4cab6f2031800838c62f6a8b06b825a054a Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 31 Dec 2025 14:23:56 +0530 Subject: [PATCH 1429/3801] remove unwanted comment --- .../rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 25a5104c5df3..1a929a02ac3b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -81,7 +81,6 @@ fn run_new() -> io::Result<()> { } bidirectional::Request::ApiVersionCheck {} => { - // bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION).write::<_, C>(stdout) send_response::( &stdout, bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), From 03d2bccbe5795450536996d35ba2318cf1ebc71d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 31 Dec 2025 10:28:04 +0100 Subject: [PATCH 1430/3801] Run rustdoc tests in opt-dist tests --- src/tools/opt-dist/src/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index fa55805bbf21..29168b25f7f6 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -123,6 +123,7 @@ llvm-config = "{llvm_config}" "tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist", "tests/ui", "tests/crashes", + "tests/rustdoc", ]; for test_path in env.skipped_tests() { args.extend(["--skip", test_path]); From 4ba9b739a4b224ed6dd514309653a1db5cdfe486 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 31 Dec 2025 10:51:58 +0100 Subject: [PATCH 1431/3801] fix non-determinism in os_unfair_lock test --- .../fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs index 1c31236a2f80..f1389dd0821f 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs @@ -1,4 +1,5 @@ //@only-target: darwin +//@compile-flags: -Zmiri-fixed-schedule #![feature(sync_unsafe_cell)] use std::cell::SyncUnsafeCell; From ec7db072ee3cc62f825f1b918cd8043cca03c6c7 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 31 Dec 2025 12:59:40 +0200 Subject: [PATCH 1432/3801] Allow finding references from doc comments --- .../crates/ide/src/references.rs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs index ffae7bf6c7c5..4918fe4ff9a4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/references.rs +++ b/src/tools/rust-analyzer/crates/ide/src/references.rs @@ -38,7 +38,8 @@ use syntax::{ }; use crate::{ - Analysis, FilePosition, HighlightedRange, NavigationTarget, TryToNav, highlight_related, + Analysis, FilePosition, HighlightedRange, NavigationTarget, TryToNav, + doc_links::token_as_doc_comment, highlight_related, }; /// Result of a reference search operation. @@ -211,6 +212,13 @@ pub(crate) fn find_defs( syntax: &SyntaxNode, offset: TextSize, ) -> Option> { + if let Some(token) = syntax.token_at_offset(offset).left_biased() + && let Some(doc_comment) = token_as_doc_comment(&token) + { + return doc_comment + .get_definition_with_descend_at(sema, offset, |def, _, _| Some(vec![def])); + } + let token = syntax.token_at_offset(offset).find(|t| { matches!( t.kind(), @@ -785,6 +793,23 @@ fn main() { ); } + #[test] + fn test_find_all_refs_in_comments() { + check( + r#" +struct Foo; + +/// $0[`Foo`] is just above +struct Bar; +"#, + expect![[r#" + Foo Struct FileId(0) 0..11 7..10 + + (no references) + "#]], + ); + } + #[test] fn search_filters_by_range() { check( From 9d8b4cc70d8f1e8db49999120baaa254034baafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= Date: Tue, 30 Dec 2025 15:02:22 +0100 Subject: [PATCH 1433/3801] Restore builder at the end of saved bb --- .../src/builder/gpu_offload.rs | 4 +-- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 -- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 33 ------------------- 3 files changed, 2 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index 046501d08c48..5c4aa7da5143 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -430,7 +430,7 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( let fn_ty = offload_globals.mapper_fn_ty; let num_args = types.len() as u64; - let ip = unsafe { llvm::LLVMRustGetInsertPoint(&builder.llbuilder) }; + let bb = builder.llbb(); // FIXME(Sa4dUs): dummy loads are a temp workaround, we should find a proper way to prevent these // variables from being optimized away @@ -468,7 +468,7 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( // Step 1) unsafe { - llvm::LLVMRustRestoreInsertPoint(&builder.llbuilder, ip); + llvm::LLVMPositionBuilderAtEnd(&builder.llbuilder, bb); } builder.memset(tgt_bin_desc_alloca, cx.get_const_i8(0), cx.get_const_i64(32), Align::EIGHT); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 75b3e5955b78..147692721845 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2443,8 +2443,6 @@ unsafe extern "C" { pub(crate) fn LLVMRustPositionBuilderPastAllocas<'a>(B: &Builder<'a>, Fn: &'a Value); pub(crate) fn LLVMRustPositionBuilderAtStart<'a>(B: &Builder<'a>, BB: &'a BasicBlock); - pub(crate) fn LLVMRustGetInsertPoint<'a>(B: &Builder<'a>) -> &'a Value; - pub(crate) fn LLVMRustRestoreInsertPoint<'a>(B: &Builder<'a>, IP: &'a Value); pub(crate) fn LLVMRustSetModulePICLevel(M: &Module); pub(crate) fn LLVMRustSetModulePIELevel(M: &Module); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 02e6abf24627..b1cccd62d0a5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1458,39 +1458,6 @@ extern "C" void LLVMRustPositionAfter(LLVMBuilderRef B, LLVMValueRef Instr) { } } -extern "C" LLVMValueRef LLVMRustGetInsertPoint(LLVMBuilderRef B) { - llvm::IRBuilderBase &IRB = *unwrap(B); - - llvm::IRBuilderBase::InsertPoint ip = IRB.saveIP(); - llvm::BasicBlock *BB = ip.getBlock(); - - if (!BB) - return nullptr; - - auto it = ip.getPoint(); - - if (it == BB->end()) - return nullptr; - - llvm::Instruction *I = &*it; - return wrap(I); -} - -extern "C" void LLVMRustRestoreInsertPoint(LLVMBuilderRef B, - LLVMValueRef Instr) { - llvm::IRBuilderBase &IRB = *unwrap(B); - - if (!Instr) { - llvm::BasicBlock *BB = IRB.GetInsertBlock(); - if (BB) - IRB.SetInsertPoint(BB); - return; - } - - llvm::Instruction *I = unwrap(Instr); - IRB.SetInsertPoint(I); -} - extern "C" LLVMValueRef LLVMRustGetFunctionCall(LLVMValueRef Fn, const char *Name, size_t NameLen) { auto targetName = StringRef(Name, NameLen); From 41a24c4b583f0cbeb52001d093fe3486009fcd09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= Date: Wed, 31 Dec 2025 13:11:28 +0100 Subject: [PATCH 1434/3801] Add offload test for control flow handling --- .../codegen-llvm/gpu_offload/control_flow.rs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/codegen-llvm/gpu_offload/control_flow.rs diff --git a/tests/codegen-llvm/gpu_offload/control_flow.rs b/tests/codegen-llvm/gpu_offload/control_flow.rs new file mode 100644 index 000000000000..4a213f5a33a8 --- /dev/null +++ b/tests/codegen-llvm/gpu_offload/control_flow.rs @@ -0,0 +1,37 @@ +//@ compile-flags: -Zoffload=Test -Zunstable-options -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-offload + +// This test verifies that the offload intrinsic is correctly lowered even when the caller +// contains control flow. + +#![feature(abi_gpu_kernel)] +#![feature(rustc_attrs)] +#![feature(core_intrinsics)] +#![no_main] + +// CHECK: define{{( dso_local)?}} void @main() +// CHECK-NOT: define +// CHECK: %EmptyDesc = alloca %struct.__tgt_bin_desc, align 8 +// CHECK-NEXT: %.offload_baseptrs = alloca [1 x ptr], align 8 +// CHECK-NEXT: %.offload_ptrs = alloca [1 x ptr], align 8 +// CHECK-NEXT: %.offload_sizes = alloca [1 x i64], align 8 +// CHECK-NEXT: %kernel_args = alloca %struct.__tgt_kernel_arguments, align 8 +// CHECK: br label %bb3 +// CHECK-NOT define +// CHECK: bb3 +// CHECK: call void @__tgt_target_data_begin_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.foo, ptr null, ptr null) +// CHECK: %10 = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 2097152, i32 256, ptr nonnull @.foo.region_id, ptr nonnull %kernel_args) +// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.foo, ptr null, ptr null) +#[unsafe(no_mangle)] +unsafe fn main() { + let A = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]; + + for i in 0..100 { + core::intrinsics::offload::<_, _, ()>(foo, (A.as_ptr() as *const [f32; 6],)); + } +} + +unsafe extern "C" { + pub fn foo(A: *const [f32; 6]) -> (); +} From 2a7e3e6f2361d081d94822ac53474cd9e1010f6a Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 31 Dec 2025 17:50:14 +0530 Subject: [PATCH 1435/3801] add bidirectional flow for file method --- .../crates/load-cargo/src/lib.rs | 14 ++++++++++ .../src/bidirectional_protocol/msg.rs | 2 ++ .../proc-macro-srv-cli/src/main_loop.rs | 26 +++++++++++++++++++ .../crates/proc-macro-srv/src/lib.rs | 1 + .../src/server_impl/rust_analyzer_span.rs | 13 +++++----- 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 5122051fb3c2..c8a157e88e17 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -546,6 +546,20 @@ impl ProcMacroExpander for Expander { let slice = text.get(start as usize..end as usize).map(ToOwned::to_owned); Ok(SubResponse::SourceTextResult { text: slice }) } + SubRequest::FileName { file_id } => { + let file = FileId::from_raw(file_id); + let source_root_id = db.file_source_root(file).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); + + let name = source_root.path_for_file(&file).and_then(|path| { + path.name_and_extension().map(|(name, ext)| match ext { + Some(ext) => format!("{name}.{ext}"), + None => name.to_owned(), + }) + }); + + Ok(SubResponse::FileNameResult { name: name.unwrap_or_default() }) + } }; match self.0.expand( subtree.view(), diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index cf8becd922de..7edd9062d994 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -10,11 +10,13 @@ use crate::{ #[derive(Debug, Serialize, Deserialize)] pub enum SubRequest { + FileName { file_id: u32 }, SourceText { file_id: u32, start: u32, end: u32 }, } #[derive(Debug, Serialize, Deserialize)] pub enum SubResponse { + FileNameResult { name: String }, SourceTextResult { text: Option }, } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 1a929a02ac3b..279eab06c0b4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -167,6 +167,32 @@ struct ProcMacroClientHandle<'a, C: Codec> { } impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { + fn file(&mut self, file_id: u32) -> String { + let req = + bidirectional::BidirectionalMessage::SubRequest(bidirectional::SubRequest::FileName { + file_id, + }); + + if req.write::<_, C>(&mut self.stdout.lock()).is_err() { + return String::new(); + } + + let msg = match bidirectional::BidirectionalMessage::read::<_, C>( + &mut self.stdin.lock(), + self.buf, + ) { + Ok(Some(msg)) => msg, + _ => return String::new(), + }; + + match msg { + bidirectional::BidirectionalMessage::SubResponse( + bidirectional::SubResponse::FileNameResult { name }, + ) => name, + _ => String::new(), + } + } + fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option { let req = bidirectional::BidirectionalMessage::SubRequest( bidirectional::SubRequest::SourceText { file_id, start, end }, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 17ffa29ce172..1804238a32a1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -94,6 +94,7 @@ impl<'env> ProcMacroSrv<'env> { pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); pub trait ProcMacroClientInterface { + fn file(&mut self, file_id: u32) -> String; fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option; } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 5d9090c060e0..7a9d655431f5 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -127,13 +127,14 @@ impl server::Span for RaSpanServer<'_> { fn debug(&mut self, span: Self::Span) -> String { format!("{:?}", span) } - fn file(&mut self, _: Self::Span) -> String { - // FIXME - String::new() + fn file(&mut self, span: Self::Span) -> String { + self.callback + .as_mut() + .map(|cb| cb.file(span.anchor.file_id.file_id().index())) + .unwrap_or_default() } - fn local_file(&mut self, _: Self::Span) -> Option { - // FIXME - None + fn local_file(&mut self, span: Self::Span) -> Option { + self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id().index())) } fn save_span(&mut self, _span: Self::Span) -> usize { // FIXME, quote is incompatible with third-party tools From abbf0272fa13f49532ece6a125de288ba39c82c7 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 31 Dec 2025 17:50:20 +0530 Subject: [PATCH 1436/3801] add bidirectional flow for local file method --- .../crates/load-cargo/src/lib.rs | 14 +++++++++++ .../src/bidirectional_protocol/msg.rs | 2 ++ .../proc-macro-srv-cli/src/main_loop.rs | 25 +++++++++++++++++++ .../crates/proc-macro-srv/src/lib.rs | 1 + 4 files changed, 42 insertions(+) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index c8a157e88e17..dc75abe7ad8c 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -540,6 +540,20 @@ impl ProcMacroExpander for Expander { current_dir: String, ) -> Result { let mut cb = |req| match req { + SubRequest::LocalFileName { file_id } => { + let file = FileId::from_raw(file_id); + let source_root_id = db.file_source_root(file).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); + + let name = source_root + .path_for_file(&file) + .and_then(|path| path.clone().into_abs_path()) + .and_then(|path| { + path.as_path().file_name().map(|filename| filename.to_owned()) + }); + + Ok(SubResponse::LocalFileNameResult { name }) + } SubRequest::SourceText { file_id, start, end } => { let file = FileId::from_raw(file_id); let text = db.file_text(file).text(db); diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 7edd9062d994..2819a92fe33a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -12,12 +12,14 @@ use crate::{ pub enum SubRequest { FileName { file_id: u32 }, SourceText { file_id: u32, start: u32, end: u32 }, + LocalFileName { file_id: u32 }, } #[derive(Debug, Serialize, Deserialize)] pub enum SubResponse { FileNameResult { name: String }, SourceTextResult { text: Option }, + LocalFileNameResult { name: Option }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 279eab06c0b4..76119b27a8b6 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -217,6 +217,31 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl _ => None, } } + + fn local_file(&mut self, file_id: u32) -> Option { + let req = bidirectional::BidirectionalMessage::SubRequest( + bidirectional::SubRequest::LocalFileName { file_id }, + ); + + if req.write::<_, C>(&mut self.stdout.lock()).is_err() { + return Some(String::new()); + } + + let msg = match bidirectional::BidirectionalMessage::read::<_, C>( + &mut self.stdin.lock(), + self.buf, + ) { + Ok(msg) => msg, + _ => return None, + }; + + match msg { + Some(bidirectional::BidirectionalMessage::SubResponse( + bidirectional::SubResponse::LocalFileNameResult { name }, + )) => Some(name.unwrap_or_default()), + _ => None, + } + } } fn handle_expand_ra( diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 1804238a32a1..8de712dbd386 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -96,6 +96,7 @@ pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Syn pub trait ProcMacroClientInterface { fn file(&mut self, file_id: u32) -> String; fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option; + fn local_file(&mut self, file_id: u32) -> Option; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; From c4dd25f6cd2e11e0a4f055bba2cffed5a1553cb2 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 31 Dec 2025 17:54:22 +0530 Subject: [PATCH 1437/3801] add roundtrip abstraction to remove subrequest subresponse boilerplate code --- .../proc-macro-srv-cli/src/main_loop.rs | 79 ++++++------------- 1 file changed, 24 insertions(+), 55 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 76119b27a8b6..77cb8760a100 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -166,79 +166,48 @@ struct ProcMacroClientHandle<'a, C: Codec> { buf: &'a mut C::Buf, } -impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { - fn file(&mut self, file_id: u32) -> String { - let req = - bidirectional::BidirectionalMessage::SubRequest(bidirectional::SubRequest::FileName { - file_id, - }); +impl<'a, C: Codec> ProcMacroClientHandle<'a, C> { + fn roundtrip( + &mut self, + req: bidirectional::SubRequest, + ) -> Option { + let msg = bidirectional::BidirectionalMessage::SubRequest(req); - if req.write::<_, C>(&mut self.stdout.lock()).is_err() { - return String::new(); + if msg.write::<_, C>(&mut self.stdout.lock()).is_err() { + return None; } - let msg = match bidirectional::BidirectionalMessage::read::<_, C>( - &mut self.stdin.lock(), - self.buf, - ) { - Ok(Some(msg)) => msg, - _ => return String::new(), - }; + match bidirectional::BidirectionalMessage::read::<_, C>(&mut self.stdin.lock(), self.buf) { + Ok(Some(msg)) => Some(msg), + _ => None, + } + } +} - match msg { - bidirectional::BidirectionalMessage::SubResponse( +impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { + fn file(&mut self, file_id: u32) -> String { + match self.roundtrip(bidirectional::SubRequest::FileName { file_id }) { + Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::FileNameResult { name }, - ) => name, + )) => name, _ => String::new(), } } fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option { - let req = bidirectional::BidirectionalMessage::SubRequest( - bidirectional::SubRequest::SourceText { file_id, start, end }, - ); - - if req.write::<_, C>(&mut self.stdout.lock()).is_err() { - return None; - } - - let msg = match bidirectional::BidirectionalMessage::read::<_, C>( - &mut self.stdin.lock(), - self.buf, - ) { - Ok(Some(msg)) => msg, - _ => return None, - }; - - match msg { - bidirectional::BidirectionalMessage::SubResponse( + match self.roundtrip(bidirectional::SubRequest::SourceText { file_id, start, end }) { + Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::SourceTextResult { text }, - ) => text, + )) => text, _ => None, } } fn local_file(&mut self, file_id: u32) -> Option { - let req = bidirectional::BidirectionalMessage::SubRequest( - bidirectional::SubRequest::LocalFileName { file_id }, - ); - - if req.write::<_, C>(&mut self.stdout.lock()).is_err() { - return Some(String::new()); - } - - let msg = match bidirectional::BidirectionalMessage::read::<_, C>( - &mut self.stdin.lock(), - self.buf, - ) { - Ok(msg) => msg, - _ => return None, - }; - - match msg { + match self.roundtrip(bidirectional::SubRequest::LocalFileName { file_id }) { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::LocalFileNameResult { name }, - )) => Some(name.unwrap_or_default()), + )) => name, _ => None, } } From 4e90a965422a42c3c2c161f45543148a9eae429a Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Wed, 31 Dec 2025 13:54:03 +0100 Subject: [PATCH 1438/3801] Corretly link URL in internal Windows docs ``` warning: this URL is not a hyperlink --> library/std/src/sys/pal/windows/mod.rs:337:5 | 337 | /// https://docs.microsoft.com/en-us/cpp/intrinsics/fastfail | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links = note: `#[warn(rustdoc::bare_urls)]` on by default help: use an automatic link instead | 337 | /// | + + ``` --- library/std/src/sys/pal/windows/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 32bd6ea3a4f6..457b1fd70562 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -334,7 +334,7 @@ pub fn dur2timeout(dur: Duration) -> u32 { /// this sequence of instructions will be treated as an access violation, which /// will still terminate the process but might run some exception handlers. /// -/// https://docs.microsoft.com/en-us/cpp/intrinsics/fastfail +/// #[cfg(not(miri))] // inline assembly does not work in Miri pub fn abort_internal() -> ! { unsafe { From 55833a9a6dfeff37b3b7701b266dc7a6e6f0a80b Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Tue, 23 Dec 2025 00:16:22 +0100 Subject: [PATCH 1439/3801] tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs: New test --- .../some-non-zero-from-atomic-optimization.rs | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs diff --git a/tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs b/tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs new file mode 100644 index 000000000000..35317b0dd39c --- /dev/null +++ b/tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs @@ -0,0 +1,84 @@ +//! Regression test for . + +// We want to check that `unreachable!()` is optimized away. +//@ compile-flags: -O + +// Don't de-duplicate `some_non_zero_from_atomic_get2()` since we want its LLVM IR. +//@ compile-flags: -Zmerge-functions=disabled + +// So we don't have to worry about usize. +//@ only-64bit + +#![crate_type = "lib"] + +use std::num::NonZeroUsize; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering::Relaxed; + +pub static X: AtomicUsize = AtomicUsize::new(1); + +/// We don't need to check the LLVM IR of this function, but we expect its LLVM +/// IR to be identical to `some_non_zero_from_atomic_get2()`. +#[no_mangle] +pub unsafe fn some_non_zero_from_atomic_get() -> Option { + let x = X.load(Relaxed); + Some(NonZeroUsize::new_unchecked(x)) +} + +/// We want to test that the `unreachable!()` branch is optimized out. +/// +/// When that does not happen, the LLVM IR will look like this: +/// +/// ```sh +/// rustc +nightly-2024-02-08 --emit=llvm-ir -O -Zmerge-functions=disabled \ +/// tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs && \ +/// grep -B 1 -A 13 '@some_non_zero_from_atomic_get2()' some-non-zero-from-atomic-optimization.ll +/// ``` +/// ```llvm +/// ; Function Attrs: nonlazybind uwtable +/// define noundef i64 @some_non_zero_from_atomic_get2() unnamed_addr #1 { +/// start: +/// %0 = load atomic i64, ptr @_ZN38some_non_zero_from_atomic_optimization1X17h monotonic, align 8 +/// %1 = icmp eq i64 %0, 0 +/// br i1 %1, label %bb2, label %bb3 +/// +/// bb2: ; preds = %start +/// ; call core::panicking::panic +/// tail call void @_ZN4core9panicking5panic17h0cc48E(..., ..., ... ) #3 +/// unreachable +/// +/// bb3: ; preds = %start +/// ret i64 %0 +/// } +/// ``` +/// +/// When it _is_ optimized out, the LLVM IR will look like this: +/// +/// ```sh +/// rustc +nightly-2024-02-09 --emit=llvm-ir -O -Zmerge-functions=disabled \ +/// tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs && \ +/// grep -B 1 -A 6 '@some_non_zero_from_atomic_get2()' some-non-zero-from-atomic-optimization.ll +/// ``` +/// ```llvm +/// ; Function Attrs: mustprogress nofree nounwind nonlazybind willreturn memory(...) uwtable +/// define noundef i64 @some_non_zero_from_atomic_get2() unnamed_addr #0 { +/// bb3: +/// %0 = load atomic i64, ptr @_ZN38some_non_zero_from_atomic_optimization1X17h monotonic, align 8 +/// %1 = icmp ne i64 %0, 0 +/// tail call void @llvm.assume(i1 %1) +/// ret i64 %0 +/// } +/// ``` +/// +/// The way we check that the LLVM IR is correct is by making sure that neither +/// `panic` nor `unreachable` is part of the LLVM IR: +// CHECK-LABEL: define {{.*}} i64 @some_non_zero_from_atomic_get2() {{.*}} { +// CHECK-NOT: panic +// CHECK-NOT: unreachable +#[no_mangle] +pub unsafe fn some_non_zero_from_atomic_get2() -> usize { + match some_non_zero_from_atomic_get() { + Some(x) => x.get(), + None => unreachable!(), // shall be optimized out + } +} From cc01b1c3789e628ff2e339e584fd190c051a8c3c Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 31 Dec 2025 16:09:23 +0100 Subject: [PATCH 1440/3801] Back into rotation --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 5f637205fa65..09dec7675e7e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -63,7 +63,6 @@ users_on_vacation = [ "Alexendoo", "y21", "blyxyas", - "samueltardieu", ] [assign.owners] From 1a4e7f9aa9830901d02c1c04b8a511a969f68536 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 31 Dec 2025 15:14:36 +0000 Subject: [PATCH 1441/3801] Use --print target-libdir in run-make tests This makes the tests more robust against sysroot layout changes and slightly simplifies them. --- tests/run-make/apple-deployment-target/rmake.rs | 5 ++--- tests/run-make/cdylib-dylib-linkage/rmake.rs | 11 +++++------ tests/run-make/libstd-no-protected/rmake.rs | 6 ++---- tests/run-make/sysroot-crates-are-unstable/rmake.rs | 4 ++-- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/tests/run-make/apple-deployment-target/rmake.rs b/tests/run-make/apple-deployment-target/rmake.rs index 5d4512843d53..fb46c554c94c 100644 --- a/tests/run-make/apple-deployment-target/rmake.rs +++ b/tests/run-make/apple-deployment-target/rmake.rs @@ -169,9 +169,8 @@ fn main() { // Test that all binaries in rlibs produced by `rustc` have the same version. // Regression test for https://github.com/rust-lang/rust/issues/128419. - let sysroot = rustc().print("sysroot").run().stdout_utf8(); - let target_sysroot = path(sysroot.trim()).join("lib/rustlib").join(target()).join("lib"); - let rlibs = shallow_find_files(&target_sysroot, |path| has_extension(path, "rlib")); + let sysroot_libs_dir = rustc().print("target-libdir").target(target()).run().stdout_utf8(); + let rlibs = shallow_find_files(sysroot_libs_dir.trim(), |path| has_extension(path, "rlib")); let output = cmd("otool").arg("-l").args(rlibs).run().stdout_utf8(); let re = regex::Regex::new(r"(minos|version) ([0-9.]*)").unwrap(); diff --git a/tests/run-make/cdylib-dylib-linkage/rmake.rs b/tests/run-make/cdylib-dylib-linkage/rmake.rs index 3c145d9f99cf..59d8d0337daf 100644 --- a/tests/run-make/cdylib-dylib-linkage/rmake.rs +++ b/tests/run-make/cdylib-dylib-linkage/rmake.rs @@ -16,24 +16,23 @@ use run_make_support::{ fn main() { rustc().arg("-Cprefer-dynamic").input("bar.rs").run(); rustc().input("foo.rs").run(); - let sysroot = rustc().print("sysroot").run().stdout_utf8(); - let sysroot = sysroot.trim(); - let target_sysroot = path(sysroot).join("lib/rustlib").join(target()).join("lib"); + let sysroot_libs_dir = rustc().print("target-libdir").target(target()).run().stdout_utf8(); + let sysroot_libs_dir = sysroot_libs_dir.trim(); if is_windows_msvc() { - let mut libs = shallow_find_files(&target_sysroot, |path| { + let mut libs = shallow_find_files(sysroot_libs_dir, |path| { has_prefix(path, "libstd-") && has_suffix(path, ".dll.lib") }); libs.push(path(msvc_import_dynamic_lib_name("foo"))); libs.push(path(msvc_import_dynamic_lib_name("bar"))); cc().input("foo.c").args(&libs).out_exe("foo").run(); } else { - let stdlibs = shallow_find_files(&target_sysroot, |path| { + let stdlibs = shallow_find_files(sysroot_libs_dir, |path| { has_extension(path, dynamic_lib_extension()) && filename_contains(path, "std") }); cc().input("foo.c") .args(&[dynamic_lib_name("foo"), dynamic_lib_name("bar")]) .arg(stdlibs.get(0).unwrap()) - .library_search_path(&target_sysroot) + .library_search_path(sysroot_libs_dir) .output(bin_name("foo")) .run(); } diff --git a/tests/run-make/libstd-no-protected/rmake.rs b/tests/run-make/libstd-no-protected/rmake.rs index 4091406d46e2..75a1dcc4a7d0 100644 --- a/tests/run-make/libstd-no-protected/rmake.rs +++ b/tests/run-make/libstd-no-protected/rmake.rs @@ -15,10 +15,8 @@ type SymbolTable<'data> = run_make_support::object::read::elf::SymbolTable<'data fn main() { // Find libstd-...rlib - let sysroot = rustc().print("sysroot").run().stdout_utf8(); - let sysroot = sysroot.trim(); - let target_sysroot = path(sysroot).join("lib/rustlib").join(target()).join("lib"); - let mut libs = shallow_find_files(&target_sysroot, |path| { + let sysroot_libs_dir = rustc().print("target-libdir").target(target()).run().stdout_utf8(); + let mut libs = shallow_find_files(sysroot_libs_dir.trim(), |path| { has_prefix(path, "libstd-") && has_suffix(path, ".rlib") }); assert_eq!(libs.len(), 1); diff --git a/tests/run-make/sysroot-crates-are-unstable/rmake.rs b/tests/run-make/sysroot-crates-are-unstable/rmake.rs index 20ad01bef61d..623b9650771c 100644 --- a/tests/run-make/sysroot-crates-are-unstable/rmake.rs +++ b/tests/run-make/sysroot-crates-are-unstable/rmake.rs @@ -44,8 +44,8 @@ fn check_crate_is_unstable(cr: &Crate) { } fn get_unstable_sysroot_crates() -> Vec { - let sysroot = PathBuf::from(rustc().print("sysroot").run().stdout_utf8().trim()); - let sysroot_libs_dir = sysroot.join("lib").join("rustlib").join(target()).join("lib"); + let sysroot_libs_dir = + PathBuf::from(rustc().print("target-libdir").target(target()).run().stdout_utf8().trim()); println!("Sysroot libs dir: {sysroot_libs_dir:?}"); // Generate a list of all library crates in the sysroot. From 4ba73c33b8d354724d1d713be177912b1636a67c Mon Sep 17 00:00:00 2001 From: Dushyanth Date: Wed, 31 Dec 2025 21:09:11 +0530 Subject: [PATCH 1442/3801] test: add regression cases for valtree hashing ICE --- .../printing_valtrees_supports_non_values.rs | 11 ++++++ ...inting_valtrees_supports_non_values.stderr | 38 ++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs index fbe310f7de4c..484d6f14a82a 100644 --- a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs @@ -25,3 +25,14 @@ fn baz() { } fn main() {} + +fn test_ice_missing_bound() { + foo::<{Option::Some::{0: ::ASSOC}}>(); + //~^ ERROR the trait bound `T: Trait` is not satisfied + //~| ERROR the constant `Option::::Some(_)` is not of type `Foo` +} + +fn test_underscore_inference() { + foo::<{ Option::Some:: { 0: _ } }>(); + //~^ ERROR the constant `Option::::Some(_)` is not of type `Foo` +} diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr index 8b2871f2b6d3..b4f03e07b569 100644 --- a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr @@ -22,5 +22,41 @@ note: required by a const generic parameter in `foo` LL | fn foo() {} | ^^^^^^^^^^^^ required by this const generic parameter in `foo` -error: aborting due to 2 previous errors +error[E0277]: the trait bound `T: Trait` is not satisfied + --> $DIR/printing_valtrees_supports_non_values.rs:30:5 + | +LL | foo::<{Option::Some::{0: ::ASSOC}}>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` + | +help: consider restricting type parameter `T` with trait `Trait` + | +LL | fn test_ice_missing_bound() { + | +++++++ +error: the constant `Option::::Some(_)` is not of type `Foo` + --> $DIR/printing_valtrees_supports_non_values.rs:30:12 + | +LL | foo::<{Option::Some::{0: ::ASSOC}}>(); + | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | +note: required by a const generic parameter in `foo` + --> $DIR/printing_valtrees_supports_non_values.rs:15:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: the constant `Option::::Some(_)` is not of type `Foo` + --> $DIR/printing_valtrees_supports_non_values.rs:36:13 + | +LL | foo::<{ Option::Some:: { 0: _ } }>(); + | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | +note: required by a const generic parameter in `foo` + --> $DIR/printing_valtrees_supports_non_values.rs:15:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. From 6b60e81e8c6de24a5d131dab3d5d61541aa0fb96 Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 31 Dec 2025 08:51:49 -0800 Subject: [PATCH 1443/3801] Rewrite a `loop` as tail recursion --- .../rustc_hir_analysis/src/check/region.rs | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 0e8cdc266f89..0c611e6c4c9e 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -701,31 +701,25 @@ fn resolve_local<'tcx>( /// Note: ET is intended to match "rvalues or places based on rvalues". fn record_subexpr_extended_temp_scopes( scope_tree: &mut ScopeTree, - mut expr: &hir::Expr<'_>, + expr: &hir::Expr<'_>, lifetime: Option, ) { - debug!(?expr, ?lifetime); + // Note: give all the expressions matching `ET` with the + // extended temporary lifetime, not just the innermost rvalue, + // because in MIR building if we must compile e.g., `*rvalue()` + // into a temporary, we request the temporary scope of the + // outer expression. - loop { - // Note: give all the expressions matching `ET` with the - // extended temporary lifetime, not just the innermost rvalue, - // because in MIR building if we must compile e.g., `*rvalue()` - // into a temporary, we request the temporary scope of the - // outer expression. + scope_tree.record_extended_temp_scope(expr.hir_id.local_id, lifetime); - scope_tree.record_extended_temp_scope(expr.hir_id.local_id, lifetime); - - match expr.kind { - hir::ExprKind::AddrOf(_, _, subexpr) - | hir::ExprKind::Unary(hir::UnOp::Deref, subexpr) - | hir::ExprKind::Field(subexpr, _) - | hir::ExprKind::Index(subexpr, _, _) => { - expr = subexpr; - } - _ => { - return; - } + match expr.kind { + hir::ExprKind::AddrOf(_, _, subexpr) + | hir::ExprKind::Unary(hir::UnOp::Deref, subexpr) + | hir::ExprKind::Field(subexpr, _) + | hir::ExprKind::Index(subexpr, _, _) => { + record_subexpr_extended_temp_scopes(scope_tree, subexpr, lifetime); } + _ => {} } } From 215768a7347ff7388b271ccc7ed6b19c4921b24e Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Wed, 31 Dec 2025 17:05:41 +0000 Subject: [PATCH 1444/3801] fix missing_panics_doc in `std::os::fd::owned` https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc --- library/std/src/os/fd/owned.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 846ad37aad22..5ba6c9c1fd14 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -77,7 +77,11 @@ impl BorrowedFd<'_> { /// # Safety /// /// The resource pointed to by `fd` must remain open for the duration of - /// the returned `BorrowedFd`, and it must not have the value `-1`. + /// the returned `BorrowedFd`. + /// + /// # Panics + /// + /// Panics if the raw file descriptor has the value `-1`. #[inline] #[track_caller] #[rustc_const_stable(feature = "io_safety", since = "1.63.0")] @@ -177,6 +181,10 @@ impl FromRawFd for OwnedFd { /// [ownership][io-safety]. The resource must not require any cleanup other than `close`. /// /// [io-safety]: io#io-safety + /// + /// # Panics + /// + /// Panics if the raw file descriptor has the value `-1`. #[inline] #[track_caller] unsafe fn from_raw_fd(fd: RawFd) -> Self { From a3d829175a57c49bab675b35e3740685c7ca2b3a Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Wed, 31 Dec 2025 02:32:54 +0100 Subject: [PATCH 1445/3801] Update books --- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/tools/rustbook/Cargo.lock | 18 +++++++++++++++++- src/tools/rustbook/Cargo.toml | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/doc/reference b/src/doc/reference index ec78de0ffe2f..6363385ac4eb 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit ec78de0ffe2f8344bd0e222b17ac7a7d32dc7a26 +Subproject commit 6363385ac4ebe1763f1e6fb2063c0b1db681a072 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 7d21279e40e8..2e02f22a10e7 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 7d21279e40e8f0e91c2a22c5148dd2d745aef8b6 +Subproject commit 2e02f22a10e7eeb758e6aba484f13d0f1988a3e5 diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index e7b04260e4a9..941bf2829ef7 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -320,6 +320,10 @@ dependencies = [ "syn", ] +[[package]] +name = "diagnostics" +version = "0.0.0" + [[package]] name = "digest" version = "0.10.7" @@ -464,6 +468,16 @@ dependencies = [ "wasip2", ] +[[package]] +name = "grammar" +version = "0.0.0" +dependencies = [ + "diagnostics", + "pathdiff", + "regex", + "walkdir", +] + [[package]] name = "handlebars" version = "6.3.2" @@ -774,9 +788,11 @@ dependencies = [ [[package]] name = "mdbook-spec" -version = "0.1.2" +version = "0.0.0" dependencies = [ "anyhow", + "diagnostics", + "grammar", "mdbook-markdown", "mdbook-preprocessor", "once_cell", diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 2815f09105b1..6f28ebe51931 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -11,6 +11,6 @@ edition = "2021" clap = { version = "4.0.32", features = ["cargo"] } mdbook-driver = { version = "0.5.2", features = ["search"] } mdbook-i18n-helpers = "0.4.0" -mdbook-spec = { path = "../../doc/reference/mdbook-spec" } +mdbook-spec = { path = "../../doc/reference/tools/mdbook-spec" } mdbook-trpl = { path = "../../doc/book/packages/mdbook-trpl" } tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } From c2f97d194f837a21f80e3c304c0ebe847649f055 Mon Sep 17 00:00:00 2001 From: mnemonikr <138624285+mnemonikr@users.noreply.github.com> Date: Thu, 11 Dec 2025 15:48:21 -0800 Subject: [PATCH 1446/3801] Added check for next_multiple_of in manual_div_ceil --- clippy_lints/src/operators/manual_div_ceil.rs | 127 +++++++++++------- clippy_utils/src/sym.rs | 1 + tests/ui/manual_div_ceil.fixed | 29 ++++ tests/ui/manual_div_ceil.rs | 29 ++++ tests/ui/manual_div_ceil.stderr | 20 ++- tests/ui/manual_div_ceil_with_feature.fixed | 29 ++++ tests/ui/manual_div_ceil_with_feature.rs | 29 ++++ tests/ui/manual_div_ceil_with_feature.stderr | 20 ++- 8 files changed, 233 insertions(+), 51 deletions(-) diff --git a/clippy_lints/src/operators/manual_div_ceil.rs b/clippy_lints/src/operators/manual_div_ceil.rs index 98aa47421537..5ed923d719bc 100644 --- a/clippy_lints/src/operators/manual_div_ceil.rs +++ b/clippy_lints/src/operators/manual_div_ceil.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::res::{MaybeDef, MaybeQPath}; use clippy_utils::sugg::{Sugg, has_enclosing_paren}; use clippy_utils::{SpanlessEq, sym}; use rustc_ast::{BinOpKind, LitIntType, LitKind, UnOp}; @@ -7,7 +8,7 @@ use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; -use rustc_middle::ty::{self}; +use rustc_middle::ty::{self, Ty}; use rustc_span::source_map::Spanned; use super::MANUAL_DIV_CEIL; @@ -16,59 +17,84 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, op: BinOpKind, lhs: & let mut applicability = Applicability::MachineApplicable; if op == BinOpKind::Div - && check_int_ty_and_feature(cx, lhs) - && check_int_ty_and_feature(cx, rhs) - && let ExprKind::Binary(inner_op, inner_lhs, inner_rhs) = lhs.kind + && check_int_ty_and_feature(cx, cx.typeck_results().expr_ty(lhs)) + && check_int_ty_and_feature(cx, cx.typeck_results().expr_ty(rhs)) && msrv.meets(cx, msrvs::DIV_CEIL) { - // (x + (y - 1)) / y - if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind - && inner_op.node == BinOpKind::Add - && sub_op.node == BinOpKind::Sub - && check_literal(sub_rhs) - && check_eq_expr(cx, sub_lhs, rhs) - { - build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); - return; - } + match lhs.kind { + ExprKind::Binary(inner_op, inner_lhs, inner_rhs) => { + // (x + (y - 1)) / y + if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind + && inner_op.node == BinOpKind::Add + && sub_op.node == BinOpKind::Sub + && check_literal(sub_rhs) + && check_eq_expr(cx, sub_lhs, rhs) + { + build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); + return; + } - // ((y - 1) + x) / y - if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_lhs.kind - && inner_op.node == BinOpKind::Add - && sub_op.node == BinOpKind::Sub - && check_literal(sub_rhs) - && check_eq_expr(cx, sub_lhs, rhs) - { - build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability); - return; - } + // ((y - 1) + x) / y + if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_lhs.kind + && inner_op.node == BinOpKind::Add + && sub_op.node == BinOpKind::Sub + && check_literal(sub_rhs) + && check_eq_expr(cx, sub_lhs, rhs) + { + build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability); + return; + } - // (x + y - 1) / y - if let ExprKind::Binary(add_op, add_lhs, add_rhs) = inner_lhs.kind - && inner_op.node == BinOpKind::Sub - && add_op.node == BinOpKind::Add - && check_literal(inner_rhs) - && check_eq_expr(cx, add_rhs, rhs) - { - build_suggestion(cx, expr, add_lhs, rhs, &mut applicability); - } + // (x + y - 1) / y + if let ExprKind::Binary(add_op, add_lhs, add_rhs) = inner_lhs.kind + && inner_op.node == BinOpKind::Sub + && add_op.node == BinOpKind::Add + && check_literal(inner_rhs) + && check_eq_expr(cx, add_rhs, rhs) + { + build_suggestion(cx, expr, add_lhs, rhs, &mut applicability); + } - // (x + (Y - 1)) / Y - if inner_op.node == BinOpKind::Add && differ_by_one(inner_rhs, rhs) { - build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); - } + // (x + (Y - 1)) / Y + if inner_op.node == BinOpKind::Add && differ_by_one(inner_rhs, rhs) { + build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); + } - // ((Y - 1) + x) / Y - if inner_op.node == BinOpKind::Add && differ_by_one(inner_lhs, rhs) { - build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability); - } + // ((Y - 1) + x) / Y + if inner_op.node == BinOpKind::Add && differ_by_one(inner_lhs, rhs) { + build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability); + } - // (x - (-Y - 1)) / Y - if inner_op.node == BinOpKind::Sub - && let ExprKind::Unary(UnOp::Neg, abs_div_rhs) = rhs.kind - && differ_by_one(abs_div_rhs, inner_rhs) - { - build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); + // (x - (-Y - 1)) / Y + if inner_op.node == BinOpKind::Sub + && let ExprKind::Unary(UnOp::Neg, abs_div_rhs) = rhs.kind + && differ_by_one(abs_div_rhs, inner_rhs) + { + build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); + } + }, + ExprKind::MethodCall(method, receiver, [next_multiple_of_arg], _) => { + // x.next_multiple_of(Y) / Y + if method.ident.name == sym::next_multiple_of + && check_int_ty(cx.typeck_results().expr_ty(receiver)) + && check_eq_expr(cx, next_multiple_of_arg, rhs) + { + build_suggestion(cx, expr, receiver, rhs, &mut applicability); + } + }, + ExprKind::Call(callee, [receiver, next_multiple_of_arg]) => { + // int_type::next_multiple_of(x, Y) / Y + if let Some(impl_ty_binder) = callee + .ty_rel_def_if_named(cx, sym::next_multiple_of) + .assoc_fn_parent(cx) + .opt_impl_ty(cx) + && check_int_ty(impl_ty_binder.skip_binder()) + && check_eq_expr(cx, next_multiple_of_arg, rhs) + { + build_suggestion(cx, expr, receiver, rhs, &mut applicability); + } + }, + _ => (), } } } @@ -91,8 +117,11 @@ fn differ_by_one(small_expr: &Expr<'_>, large_expr: &Expr<'_>) -> bool { } } -fn check_int_ty_and_feature(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - let expr_ty = cx.typeck_results().expr_ty(expr); +fn check_int_ty(expr_ty: Ty<'_>) -> bool { + matches!(expr_ty.peel_refs().kind(), ty::Int(_) | ty::Uint(_)) +} + +fn check_int_ty_and_feature(cx: &LateContext<'_>, expr_ty: Ty<'_>) -> bool { match expr_ty.peel_refs().kind() { ty::Uint(_) => true, ty::Int(_) => cx.tcx.features().enabled(sym::int_roundings), diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 00f4a9c7e586..dd20fe16ce61 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -244,6 +244,7 @@ generate! { next_back, next_if, next_if_eq, + next_multiple_of, next_tuple, nth, ok, diff --git a/tests/ui/manual_div_ceil.fixed b/tests/ui/manual_div_ceil.fixed index cd91be87ec17..8ffd107dd42e 100644 --- a/tests/ui/manual_div_ceil.fixed +++ b/tests/ui/manual_div_ceil.fixed @@ -105,3 +105,32 @@ fn issue_15705(size: u64, c: &u64) { let _ = size.div_ceil(*c); //~^ manual_div_ceil } + +struct MyStruct(u32); +impl MyStruct { + // Method matching name on different type should not trigger lint + fn next_multiple_of(self, y: u32) -> u32 { + self.0.next_multiple_of(y) + } +} + +fn issue_16219() { + let x = 33u32; + + // Lint. + let _ = x.div_ceil(8); + //~^ manual_div_ceil + let _ = x.div_ceil(8); + //~^ manual_div_ceil + + let y = &x; + let _ = y.div_ceil(8); + //~^ manual_div_ceil + + // No lint. + let _ = x.next_multiple_of(8) / 7; + let _ = x.next_multiple_of(7) / 8; + + let z = MyStruct(x); + let _ = z.next_multiple_of(8) / 8; +} diff --git a/tests/ui/manual_div_ceil.rs b/tests/ui/manual_div_ceil.rs index 9899c7d775c2..859fb5a13c44 100644 --- a/tests/ui/manual_div_ceil.rs +++ b/tests/ui/manual_div_ceil.rs @@ -105,3 +105,32 @@ fn issue_15705(size: u64, c: &u64) { let _ = (size + c - 1) / c; //~^ manual_div_ceil } + +struct MyStruct(u32); +impl MyStruct { + // Method matching name on different type should not trigger lint + fn next_multiple_of(self, y: u32) -> u32 { + self.0.next_multiple_of(y) + } +} + +fn issue_16219() { + let x = 33u32; + + // Lint. + let _ = x.next_multiple_of(8) / 8; + //~^ manual_div_ceil + let _ = u32::next_multiple_of(x, 8) / 8; + //~^ manual_div_ceil + + let y = &x; + let _ = y.next_multiple_of(8) / 8; + //~^ manual_div_ceil + + // No lint. + let _ = x.next_multiple_of(8) / 7; + let _ = x.next_multiple_of(7) / 8; + + let z = MyStruct(x); + let _ = z.next_multiple_of(8) / 8; +} diff --git a/tests/ui/manual_div_ceil.stderr b/tests/ui/manual_div_ceil.stderr index 44de3ba99be7..0efc114c7078 100644 --- a/tests/ui/manual_div_ceil.stderr +++ b/tests/ui/manual_div_ceil.stderr @@ -131,5 +131,23 @@ error: manually reimplementing `div_ceil` LL | let _ = (size + c - 1) / c; | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `size.div_ceil(*c)` -error: aborting due to 20 previous errors +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:121:13 + | +LL | let _ = x.next_multiple_of(8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:123:13 + | +LL | let _ = u32::next_multiple_of(x, 8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:127:13 + | +LL | let _ = y.next_multiple_of(8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(8)` + +error: aborting due to 23 previous errors diff --git a/tests/ui/manual_div_ceil_with_feature.fixed b/tests/ui/manual_div_ceil_with_feature.fixed index f55999c5ad08..d77b8bc28986 100644 --- a/tests/ui/manual_div_ceil_with_feature.fixed +++ b/tests/ui/manual_div_ceil_with_feature.fixed @@ -84,3 +84,32 @@ fn issue_13950() { let _ = y.div_ceil(-7); //~^ manual_div_ceil } + +struct MyStruct(i32); +impl MyStruct { + // Method matching name on different type should not trigger lint + fn next_multiple_of(self, y: i32) -> i32 { + self.0.next_multiple_of(y) + } +} + +fn issue_16219() { + let x = 33i32; + + // Lint. + let _ = x.div_ceil(8); + //~^ manual_div_ceil + let _ = x.div_ceil(8); + //~^ manual_div_ceil + + let y = &x; + let _ = y.div_ceil(8); + //~^ manual_div_ceil + + // No lint. + let _ = x.next_multiple_of(8) / 7; + let _ = x.next_multiple_of(7) / 8; + + let z = MyStruct(x); + let _ = z.next_multiple_of(8) / 8; +} diff --git a/tests/ui/manual_div_ceil_with_feature.rs b/tests/ui/manual_div_ceil_with_feature.rs index 8a895f634cb4..5b9a4d9156a7 100644 --- a/tests/ui/manual_div_ceil_with_feature.rs +++ b/tests/ui/manual_div_ceil_with_feature.rs @@ -84,3 +84,32 @@ fn issue_13950() { let _ = (y - 8) / -7; //~^ manual_div_ceil } + +struct MyStruct(i32); +impl MyStruct { + // Method matching name on different type should not trigger lint + fn next_multiple_of(self, y: i32) -> i32 { + self.0.next_multiple_of(y) + } +} + +fn issue_16219() { + let x = 33i32; + + // Lint. + let _ = x.next_multiple_of(8) / 8; + //~^ manual_div_ceil + let _ = i32::next_multiple_of(x, 8) / 8; + //~^ manual_div_ceil + + let y = &x; + let _ = y.next_multiple_of(8) / 8; + //~^ manual_div_ceil + + // No lint. + let _ = x.next_multiple_of(8) / 7; + let _ = x.next_multiple_of(7) / 8; + + let z = MyStruct(x); + let _ = z.next_multiple_of(8) / 8; +} diff --git a/tests/ui/manual_div_ceil_with_feature.stderr b/tests/ui/manual_div_ceil_with_feature.stderr index e1160d962996..c5fa15112a87 100644 --- a/tests/ui/manual_div_ceil_with_feature.stderr +++ b/tests/ui/manual_div_ceil_with_feature.stderr @@ -139,5 +139,23 @@ error: manually reimplementing `div_ceil` LL | let _ = (y - 8) / -7; | ^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)` -error: aborting due to 23 previous errors +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:100:13 + | +LL | let _ = x.next_multiple_of(8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:102:13 + | +LL | let _ = i32::next_multiple_of(x, 8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:106:13 + | +LL | let _ = y.next_multiple_of(8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(8)` + +error: aborting due to 26 previous errors From 22bb4fe147127d72f31466e91768fb1de6347fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 31 Dec 2025 23:40:16 +0000 Subject: [PATCH 1447/3801] Detect cases where `?` is applied on a type that could be coming from a different crate version than expected ``` error[E0277]: `?` couldn't convert the error to `dependency::Error` --> replaced | LL | fn main() -> Result<(), Error> { | ----------------- expected `dependency::Error` because of this ... LL | Err(Error2)?; | -----------^ the trait `From` is not implemented for `dependency::Error` | | | this can't be annotated with `?` because it has type `Result<_, Error2>` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait help: the trait `From` is not implemented for `dependency::Error` but trait `From<()>` is implemented for it --> replaced | LL | impl From<()> for Error { | ^^^^^^^^^^^^^^^^^^^^^^^ = help: for that trait implementation, expected `()`, found `Error2` = note: there are multiple different versions of crate `dependency` in the dependency graph = help: you can use `cargo tree` to explore your dependency tree ``` The existing checks rely on having access to the actual types/traits that diverged to detect they are called the same, come from different crates with the same name. The new check is less specific, merely looking to see if the crate name the involved type belongs has multiple crates. --- .../src/rmeta/decoder/cstore_impl.rs | 9 ++++ compiler/rustc_middle/src/query/mod.rs | 9 ++++ .../traits/fulfillment_errors.rs | 22 +++++++-- .../src/error_reporting/traits/mod.rs | 2 +- .../run-make/crate-loading/dep-2-reexport.rs | 16 ++++++- tests/run-make/crate-loading/dependency-1.rs | 24 ++++++++++ tests/run-make/crate-loading/dependency-2.rs | 24 ++++++++++ .../crate-loading/multiple-dep-versions.rs | 13 ++++-- .../multiple-dep-versions.stderr | 46 ++++++++++++++++++- 9 files changed, 156 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 36fe7f380069..7bd3f7db55f9 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -559,6 +559,15 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { .filter_map(|(cnum, data)| data.used().then_some(cnum)), ) }, + duplicate_crate_names: |tcx, c: CrateNum| { + let name = tcx.crate_name(c); + tcx.arena.alloc_from_iter( + tcx.crates(()) + .into_iter() + .filter(|k| tcx.crate_name(**k) == name && **k != c) + .map(|c| *c), + ) + }, ..providers.queries }; provide_extern(&mut providers.extern_queries); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 676f0d82e4fb..88917ad8db0d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2339,6 +2339,7 @@ rustc_queries! { eval_always desc { "fetching all foreign CrateNum instances" } } + // Crates that are loaded non-speculatively (not for diagnostics or doc links). // FIXME: This is currently only used for collecting lang items, but should be used instead of // `crates` in most other cases too. @@ -2347,6 +2348,14 @@ rustc_queries! { desc { "fetching `CrateNum`s for all crates loaded non-speculatively" } } + /// All crates that share the same name as crate `c`. + /// + /// This normally occurs when multiple versions of the same dependency are present in the + /// dependency tree. + query duplicate_crate_names(c: CrateNum) -> &'tcx [CrateNum] { + desc { "fetching `CrateNum`s with same name as `{c:?}`" } + } + /// A list of all traits in a crate, used by rustdoc and error reporting. query traits(_: CrateNum) -> &'tcx [DefId] { desc { "fetching all traits in a crate" } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d96a1b0a8c0e..8d779f40a13a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -33,6 +33,7 @@ use rustc_middle::ty::{ TypeVisitableExt, Upcast, }; use rustc_middle::{bug, span_bug}; +use rustc_span::def_id::CrateNum; use rustc_span::{BytePos, DUMMY_SP, STDLIB_STABLE_CRATES, Span, Symbol, sym}; use tracing::{debug, instrument}; @@ -2172,6 +2173,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.suggest_function_pointers_impl(None, &exp_found, err); } + if let ty::Adt(def, _) = trait_pred.self_ty().skip_binder().peel_refs().kind() + && let crates = self.tcx.duplicate_crate_names(def.did().krate) + && !crates.is_empty() + { + self.note_two_crate_versions(def.did().krate, MultiSpan::new(), err); + err.help("you can use `cargo tree` to explore your dependency tree"); + } true }) }) { @@ -2282,6 +2290,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } )); } + + if let ty::Adt(def, _) = trait_pred.self_ty().skip_binder().peel_refs().kind() + && let crates = self.tcx.duplicate_crate_names(def.did().krate) + && !crates.is_empty() + { + self.note_two_crate_versions(def.did().krate, MultiSpan::new(), err); + err.help("you can use `cargo tree` to explore your dependency tree"); + } true }; @@ -2445,11 +2461,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub fn note_two_crate_versions( &self, - did: DefId, + krate: CrateNum, sp: impl Into, err: &mut Diag<'_>, ) { - let crate_name = self.tcx.crate_name(did.krate); + let crate_name = self.tcx.crate_name(krate); let crate_msg = format!( "there are multiple different versions of crate `{crate_name}` in the dependency graph" ); @@ -2514,7 +2530,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { for (similar_item, _) in similar_items { err.span_help(self.tcx.def_span(similar_item), "item with same name found"); - self.note_two_crate_versions(similar_item, MultiSpan::new(), err); + self.note_two_crate_versions(similar_item.krate, MultiSpan::new(), err); } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 3ba984b90a1d..a7a685d62b34 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -442,7 +442,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); } } - self.note_two_crate_versions(expected_did, span, err); + self.note_two_crate_versions(expected_did.krate, span, err); err.help("you can use `cargo tree` to explore your dependency tree"); } suggested diff --git a/tests/run-make/crate-loading/dep-2-reexport.rs b/tests/run-make/crate-loading/dep-2-reexport.rs index 07444511472f..8b6ee6749dcc 100644 --- a/tests/run-make/crate-loading/dep-2-reexport.rs +++ b/tests/run-make/crate-loading/dep-2-reexport.rs @@ -2,9 +2,23 @@ #![crate_type = "rlib"] extern crate dependency; -pub use dependency::{Trait2, Type, do_something_trait, do_something_type}; +pub use dependency::{Error, OtherError, Trait2, Type, do_something_trait, do_something_type}; pub struct OtherType; impl dependency::Trait for OtherType { fn foo(&self) {} fn bar() {} } +#[derive(Debug)] +pub struct Error2; + +impl From for Error2 { + fn from(_: Error) -> Error2 { + Error2 + } +} + +impl From for Error2 { + fn from(_: OtherError) -> Error2 { + Error2 + } +} diff --git a/tests/run-make/crate-loading/dependency-1.rs b/tests/run-make/crate-loading/dependency-1.rs index bfeabccf5c14..0eea7a7fae8b 100644 --- a/tests/run-make/crate-loading/dependency-1.rs +++ b/tests/run-make/crate-loading/dependency-1.rs @@ -13,3 +13,27 @@ impl Trait for Type { pub fn do_something(_: X) {} pub fn do_something_type(_: Type) {} pub fn do_something_trait(_: Box) {} + +#[derive(Debug)] +pub struct Error; + +impl From<()> for Error { + fn from(t: ()) -> Error { + Error + } +} + +#[derive(Debug)] +pub struct OtherError; + +impl From<()> for OtherError { + fn from(t: ()) -> OtherError { + OtherError + } +} + +impl From for OtherError { + fn from(t: i32) -> OtherError { + OtherError + } +} diff --git a/tests/run-make/crate-loading/dependency-2.rs b/tests/run-make/crate-loading/dependency-2.rs index 682d1ff64b82..a07873297c54 100644 --- a/tests/run-make/crate-loading/dependency-2.rs +++ b/tests/run-make/crate-loading/dependency-2.rs @@ -14,3 +14,27 @@ impl Trait for Type { pub fn do_something(_: X) {} pub fn do_something_type(_: Type) {} pub fn do_something_trait(_: Box) {} + +#[derive(Debug)] +pub struct Error; + +impl From<()> for Error { + fn from(t: ()) -> Error { + Error + } +} + +#[derive(Debug)] +pub struct OtherError; + +impl From<()> for OtherError { + fn from(_: ()) -> OtherError { + OtherError + } +} + +impl From for OtherError { + fn from(_: i32) -> OtherError { + OtherError + } +} diff --git a/tests/run-make/crate-loading/multiple-dep-versions.rs b/tests/run-make/crate-loading/multiple-dep-versions.rs index 3a4a20d38fc8..69b8360a8c92 100644 --- a/tests/run-make/crate-loading/multiple-dep-versions.rs +++ b/tests/run-make/crate-loading/multiple-dep-versions.rs @@ -1,13 +1,20 @@ extern crate dep_2_reexport; extern crate dependency; -use dep_2_reexport::{OtherType, Trait2, Type}; -use dependency::{Trait, do_something, do_something_trait, do_something_type}; +use dep_2_reexport::{Error2, OtherType, Trait2, Type}; +use dependency::{Error, OtherError, Trait, do_something, do_something_trait, do_something_type}; -fn main() { +fn main() -> Result<(), Error> { do_something(Type); Type.foo(); Type::bar(); do_something(OtherType); do_something_type(Type); do_something_trait(Box::new(Type) as Box); + Err(Error2)?; + Ok(()) +} + +fn foo() -> Result<(), OtherError> { + Err(Error2)?; + Ok(()) } diff --git a/tests/run-make/crate-loading/multiple-dep-versions.stderr b/tests/run-make/crate-loading/multiple-dep-versions.stderr index 235a44a8ce89..f8f8bfaaff6f 100644 --- a/tests/run-make/crate-loading/multiple-dep-versions.stderr +++ b/tests/run-make/crate-loading/multiple-dep-versions.stderr @@ -144,7 +144,51 @@ note: function defined here LL | pub fn do_something_trait(_: Box) {} | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error[E0277]: `?` couldn't convert the error to `dependency::Error` + --> replaced + | +LL | fn main() -> Result<(), Error> { + | ----------------- expected `dependency::Error` because of this +... +LL | Err(Error2)?; + | -----------^ the trait `From` is not implemented for `dependency::Error` + | | + | this can't be annotated with `?` because it has type `Result<_, Error2>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait +help: the trait `From` is not implemented for `dependency::Error` + but trait `From<()>` is implemented for it + --> replaced + | +LL | impl From<()> for Error { + | ^^^^^^^^^^^^^^^^^^^^^^^ + = help: for that trait implementation, expected `()`, found `Error2` + = note: there are multiple different versions of crate `dependency` in the dependency graph + = help: you can use `cargo tree` to explore your dependency tree + +error[E0277]: `?` couldn't convert the error to `dependency::OtherError` + --> replaced + | +LL | fn foo() -> Result<(), OtherError> { + | ---------------------- expected `dependency::OtherError` because of this +LL | Err(Error2)?; + | -----------^ the trait `From` is not implemented for `dependency::OtherError` + | | + | this can't be annotated with `?` because it has type `Result<_, Error2>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait +help: the following other types implement trait `From` + --> replaced + | +LL | impl From<()> for OtherError { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dependency::OtherError` implements `From<()>` +... +LL | impl From for OtherError { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dependency::OtherError` implements `From` + = note: there are multiple different versions of crate `dependency` in the dependency graph + = help: you can use `cargo tree` to explore your dependency tree + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0277, E0308, E0599. For more information about an error, try `rustc --explain E0277`. \ No newline at end of file From c6b03ae9b2fd9dab86662741784c8e34e8538c2b Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 30 Dec 2025 21:28:44 +0000 Subject: [PATCH 1448/3801] add check for `u8`s and update test --- compiler/rustc_mir_build/src/thir/constant.rs | 10 +++++---- .../byte-string-u8-validation.rs | 18 ++++++++++++++++ .../byte-string-u8-validation.stderr | 21 +++++++++++++++++++ .../mismatch-raw-ptr-in-adt.rs | 1 - .../mismatch-raw-ptr-in-adt.stderr | 13 +----------- 5 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs create mode 100644 tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 563212a51f31..7964a58a7ab0 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,5 +1,5 @@ use rustc_abi::Size; -use rustc_ast::{self as ast}; +use rustc_ast::{self as ast, UintTy}; use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::mir::interpret::LitToConstInput; @@ -44,12 +44,14 @@ pub(crate) fn lit_to_const<'tcx>( ty::ValTree::from_raw_bytes(tcx, str_bytes) } (ast::LitKind::ByteStr(byte_sym, _), ty::Ref(_, inner_ty, _)) - if matches!(inner_ty.kind(), ty::Slice(_) | ty::Array(..)) => + if let ty::Slice(ty) | ty::Array(ty, _) = inner_ty.kind() + && let ty::Uint(UintTy::U8) = ty.kind() => { ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()) } - (ast::LitKind::ByteStr(byte_sym, _), ty::Slice(_) | ty::Array(..)) - if tcx.features().deref_patterns() => + (ast::LitKind::ByteStr(byte_sym, _), ty::Slice(inner_ty) | ty::Array(inner_ty, _)) + if tcx.features().deref_patterns() + && let ty::Uint(UintTy::U8) = inner_ty.kind() => { // Byte string literal patterns may have type `[u8]` or `[u8; N]` if `deref_patterns` is // enabled, in order to allow, e.g., `deref!(b"..."): Vec`. diff --git a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs new file mode 100644 index 000000000000..703e63ae047f --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs @@ -0,0 +1,18 @@ +// Check that a byte string literal to a const parameter with a non-u8 +// element type isn't lowered to a ValTree with an incorrect type + +#![feature(adt_const_params)] +#![feature(rustc_attrs)] + +#[rustc_dump_predicates] +struct ConstBytes +//~^ ERROR rustc_dump_predicates +//~| NOTE Binder { value: ConstArgHasType(T/#0, &'static [*mut u8; 3_usize]), bound_vars: [] } +//~| NOTE Binder { value: TraitPredicate( as std::marker::Sized>, polarity:Positive), bound_vars: [] } +where + ConstBytes: Sized; +//~^ ERROR mismatched types +//~| NOTE expected `&[*mut u8; 3]`, found `&[u8; 3]` +//~| NOTE expected reference `&'static [*mut u8; 3]` + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr new file mode 100644 index 000000000000..f5f8a420a703 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr @@ -0,0 +1,21 @@ +error: rustc_dump_predicates + --> $DIR/byte-string-u8-validation.rs:8:1 + | +LL | struct ConstBytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: Binder { value: ConstArgHasType(T/#0, &'static [*mut u8; 3_usize]), bound_vars: [] } + = note: Binder { value: TraitPredicate( as std::marker::Sized>, polarity:Positive), bound_vars: [] } + +error[E0308]: mismatched types + --> $DIR/byte-string-u8-validation.rs:13:16 + | +LL | ConstBytes: Sized; + | ^^^^^^ expected `&[*mut u8; 3]`, found `&[u8; 3]` + | + = note: expected reference `&'static [*mut u8; 3]` + found reference `&'static [u8; 3]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.rs b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.rs index 7a31cd40207d..d1658bf20a74 100644 --- a/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.rs +++ b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.rs @@ -9,5 +9,4 @@ pub fn main() { let _: ConstBytes = ConstBytes::; //~^ ERROR mismatched types //~| ERROR mismatched types - //~| ERROR mismatched types } diff --git a/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr index 3384a8b385cb..717e680ee536 100644 --- a/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr +++ b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr @@ -7,17 +7,6 @@ LL | struct ConstBytes; = note: `*mut u8` must implement `ConstParamTy_`, but it does not = note: `[*mut u8; 3]` must implement `ConstParamTy_`, but it does not -error[E0308]: mismatched types - --> $DIR/mismatch-raw-ptr-in-adt.rs:9:33 - | -LL | let _: ConstBytes = ConstBytes::; - | ------------------ ^^^^^^^^^^^^^^^^^^^^ expected `&[65, 65, 65]`, found `&[66, 66, 66]` - | | - | expected due to this - | - = note: expected struct `ConstBytes<&[65, 65, 65]>` - found struct `ConstBytes<&[66, 66, 66]>` - error[E0308]: mismatched types --> $DIR/mismatch-raw-ptr-in-adt.rs:9:46 | @@ -36,7 +25,7 @@ LL | let _: ConstBytes = ConstBytes::; = note: expected reference `&'static [*mut u8; 3]` found reference `&'static [u8; 3]` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0308, E0741. For more information about an error, try `rustc --explain E0308`. From 6ba984fa337e3744ae7f47587acd32a2ac9de989 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 1 Jan 2026 04:24:07 +0000 Subject: [PATCH 1449/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 48622726c4a91c87bf6cd4dbe1000c95df59906e. --- library/stdarch/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/stdarch/rust-version b/library/stdarch/rust-version index 04d41c96f5c0..df8693cd1ca8 100644 --- a/library/stdarch/rust-version +++ b/library/stdarch/rust-version @@ -1 +1 @@ -8401398e1f14a24670ee1a3203713dc2f0f8b3a8 +48622726c4a91c87bf6cd4dbe1000c95df59906e From b725981fe266f483da0232ec9abcce8fe43331df Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Wed, 31 Dec 2025 13:17:55 +0530 Subject: [PATCH 1450/3801] std: sys: fs: uefi: Implement rename - Using the file_name field in `EFI_FILE_INFO` works for renaming, even when changing directories. - Does not work for cross-device rename, but that is already expected behaviour according to the docs: "This will not work if the new name is on a different mount point." - Also add some helper code for dealing with UefiBox. - Tested using OVMF in qemu. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 48 ++++++++++++++++---- library/std/src/sys/pal/uefi/helpers.rs | 59 ++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 11 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 1c65e3e2b155..b38d86afb093 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -385,8 +385,43 @@ pub fn unlink(p: &Path) -> io::Result<()> { } } -pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> { - unsupported() +/// The implementation mirrors `mv` implementation in UEFI shell: +/// https://github.com/tianocore/edk2/blob/66346d5edeac2a00d3cf2f2f3b5f66d423c07b3e/ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c#L455 +/// +/// In a nutshell we do the following: +/// 1. Convert both old and new paths to absolute paths. +/// 2. Check that both lie in the same disk. +/// 3. Construct the target path relative to the current disk root. +/// 4. Set this target path as the file_name in the file_info structure. +pub fn rename(old: &Path, new: &Path) -> io::Result<()> { + let old_absolute = crate::path::absolute(old)?; + let new_absolute = crate::path::absolute(new)?; + + let mut old_components = old_absolute.components(); + let mut new_components = new_absolute.components(); + + let Some(old_disk) = old_components.next() else { + return Err(io::const_error!(io::ErrorKind::InvalidInput, "Old path is not valid")); + }; + let Some(new_disk) = new_components.next() else { + return Err(io::const_error!(io::ErrorKind::InvalidInput, "New path is not valid")); + }; + + // Ensure that paths are on the same device. + if old_disk != new_disk { + return Err(io::const_error!(io::ErrorKind::CrossesDevices, "Cannot rename across device")); + } + + // Construct an path relative the current disk root. + let new_relative = + [crate::path::Component::RootDir].into_iter().chain(new_components).collect::(); + + let f = uefi_fs::File::from_path(old, file::MODE_READ | file::MODE_WRITE, 0)?; + let file_info = f.file_info()?; + + let new_info = file_info.with_file_name(new_relative.as_os_str())?; + + f.set_file_info(new_info) } pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { @@ -751,12 +786,7 @@ mod uefi_fs { } pub(crate) fn file_name_from_uefi(info: &UefiBox) -> OsString { - let file_name = { - let size = unsafe { (*info.as_ptr()).size }; - let strlen = (size as usize - crate::mem::size_of::>() - 1) / 2; - unsafe { crate::slice::from_raw_parts((*info.as_ptr()).file_name.as_ptr(), strlen) } - }; - - OsString::from_wide(file_name) + let fname = info.file_name(); + OsString::from_wide(&fname[..fname.len() - 1]) } } diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index d059be010e98..10749b5519d6 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -10,7 +10,7 @@ //! - More information about protocols can be found [here](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/3_foundation/36_protocols_and_handles) use r_efi::efi::{self, Guid}; -use r_efi::protocols::{device_path, device_path_to_text, service_binding, shell}; +use r_efi::protocols::{device_path, device_path_to_text, file, service_binding, shell}; use crate::alloc::Layout; use crate::ffi::{OsStr, OsString}; @@ -787,7 +787,7 @@ impl UefiBox { match NonNull::new(ptr.cast()) { Some(inner) => Ok(Self { inner, size: len }), - None => Err(io::Error::new(io::ErrorKind::OutOfMemory, "Allocation failed")), + None => Err(const_error!(io::ErrorKind::OutOfMemory, "Allocation failed")), } } @@ -814,3 +814,58 @@ impl Drop for UefiBox { unsafe { crate::alloc::dealloc(self.inner.as_ptr().cast(), layout) }; } } + +impl UefiBox { + fn size(&self) -> u64 { + unsafe { (*self.as_ptr()).size } + } + + fn set_size(&mut self, s: u64) { + unsafe { (*self.as_mut_ptr()).size = s } + } + + // Length of string (including NULL), not number of bytes. + fn file_name_len(&self) -> usize { + (self.size() as usize - size_of::>()) / size_of::() + } + + pub(crate) fn file_name(&self) -> &[u16] { + unsafe { + crate::slice::from_raw_parts((*self.as_ptr()).file_name.as_ptr(), self.file_name_len()) + } + } + + fn file_name_mut(&mut self) -> &mut [u16] { + unsafe { + crate::slice::from_raw_parts_mut( + (*self.as_mut_ptr()).file_name.as_mut_ptr(), + self.file_name_len(), + ) + } + } + + pub(crate) fn with_file_name(mut self, name: &OsStr) -> io::Result { + // os_string_to_raw returns NULL terminated string. So no need to handle it separately. + let fname = os_string_to_raw(name) + .ok_or(const_error!(io::ErrorKind::OutOfMemory, "Allocation failed"))?; + let new_size = size_of::>() + fname.len() * size_of::(); + + // Reuse the current structure if the new name can fit in it. + if self.size() >= new_size as u64 { + self.file_name_mut()[..fname.len()].copy_from_slice(&fname); + self.set_size(new_size as u64); + + return Ok(self); + } + + let mut new_box = UefiBox::new(new_size)?; + + unsafe { + crate::ptr::copy_nonoverlapping(self.as_ptr(), new_box.as_mut_ptr(), 1); + } + new_box.set_size(new_size as u64); + new_box.file_name_mut().copy_from_slice(&fname); + + Ok(new_box) + } +} From 80acf74fb6f5e8a101dddb33973b559ccfb76ecb Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Thu, 1 Jan 2026 21:54:07 +1030 Subject: [PATCH 1451/3801] test: added codegen tests for permutations of `Option::or` --- .../issues/multiple-option-or-permutations.rs | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 tests/codegen-llvm/issues/multiple-option-or-permutations.rs diff --git a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs new file mode 100644 index 000000000000..0106517c6fd5 --- /dev/null +++ b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs @@ -0,0 +1,155 @@ +// Tests output of multiple permutations of `Option::or` +//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled + +#![crate_type = "lib"] + +// CHECK-LABEL: @or_match_u8 +#[no_mangle] +pub fn or_match_u8(opta: Option, optb: Option) -> Option { + // CHECK: start: + // CHECK-NEXT: or i1 %0 + // CHECK-NEXT: select i1 %0 + // CHECK-NEXT: insertvalue { i1, i8 } + // CHECK-NEXT: insertvalue { i1, i8 } + // ret { i1, i8 } + match opta { + Some(x) => Some(x), + None => optb, + } +} + +// CHECK-LABEL: @or_match_alt_u8 +#[no_mangle] +pub fn or_match_alt_u8(opta: Option, optb: Option) -> Option { + // CHECK: start: + // CHECK-NEXT: select i1 + // CHECK-NEXT: or i1 + // CHECK-NEXT: insertvalue { i1, i8 } + // CHECK-NEXT: insertvalue { i1, i8 } + // ret { i1, i8 } + match opta { + Some(_) => opta, + None => optb, + } +} + +// CHECK-LABEL: @option_or_u8 +#[no_mangle] +pub fn option_or_u8(opta: Option, optb: Option) -> Option { + // CHECK: start: + // CHECK-NEXT: select i1 + // CHECK-NEXT: or i1 + // CHECK-NEXT: insertvalue { i1, i8 } + // CHECK-NEXT: insertvalue { i1, i8 } + // ret { i1, i8 } + opta.or(optb) +} + +// CHECK-LABEL: @if_some_u8 +#[no_mangle] +pub fn if_some_u8(opta: Option, optb: Option) -> Option { + // CHECK: start: + // CHECK-NEXT: select i1 + // CHECK-NEXT: or i1 + // CHECK-NEXT: insertvalue { i1, i8 } + // CHECK-NEXT: insertvalue { i1, i8 } + // ret { i1, i8 } + if opta.is_some() { opta } else { optb } +} + +// CHECK-LABEL: @or_match_slice_u8 +#[no_mangle] +pub fn or_match_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { + // CHECK: start: + // CHECK-NEXT: trunc i16 %0 to i1 + // CHECK-NEXT: select i1 %2, i16 %0, i16 %1 + // ret i16 + match opta { + Some(x) => Some(x), + None => optb, + } +} + +// CHECK-LABEL: @or_match_slice_alt_u8 +#[no_mangle] +pub fn or_match_slice_alt_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { + // CHECK: start: + // CHECK-NEXT: trunc i16 %0 to i1 + // CHECK-NEXT: select i1 %2, i16 %0, i16 %1 + // ret i16 + match opta { + Some(_) => opta, + None => optb, + } +} + +// CHECK-LABEL: @option_or_slice_u8 +#[no_mangle] +pub fn option_or_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { + // CHECK: start: + // CHECK-NEXT: trunc i16 %0 to i1 + // CHECK-NEXT: select i1 %2, i16 %0, i16 %1 + // ret i16 + opta.or(optb) +} + +// CHECK-LABEL: @if_some_slice_u8 +#[no_mangle] +pub fn if_some_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { + // CHECK: start: + // CHECK-NEXT: trunc i16 %0 to i1 + // CHECK-NEXT: select i1 %2, i16 %0, i16 %1 + // ret i16 + if opta.is_some() { opta } else { optb } +} + +pub struct Test { + _a: u8, + _b: u8, +} + +// CHECK-LABEL: @or_match_type +#[no_mangle] +pub fn or_match_type(opta: Option, optb: Option) -> Option { + // CHECK: start: + // CHECK-NEXT: trunc i24 %0 to i1 + // CHECK-NEXT: select i1 %2, i24 %0, i24 %1 + // ret i24 + match opta { + Some(x) => Some(x), + None => optb, + } +} + +// CHECK-LABEL: @or_match_alt_type +#[no_mangle] +pub fn or_match_alt_type(opta: Option, optb: Option) -> Option { + // CHECK: start: + // CHECK-NEXT: trunc i24 %0 to i1 + // CHECK-NEXT: select i1 %2, i24 %0, i24 %1 + // ret i24 + match opta { + Some(_) => opta, + None => optb, + } +} + +// CHECK-LABEL: @option_or_type +#[no_mangle] +pub fn option_or_type(opta: Option, optb: Option) -> Option { + // CHECK: start: + // CHECK-NEXT: trunc i24 %0 to i1 + // CHECK-NEXT: select i1 %2, i24 %0, i24 %1 + // ret i24 + opta.or(optb) +} + +// CHECK-LABEL: @if_some_type +#[no_mangle] +pub fn if_some_type(opta: Option, optb: Option) -> Option { + // CHECK: start: + // CHECK-NEXT: trunc i24 %0 to i1 + // CHECK-NEXT: select i1 %2, i24 %0, i24 %1 + // ret i24 + if opta.is_some() { opta } else { optb } +} From c571336420b0cf1285e5ea6de88f52c8b0791dbe Mon Sep 17 00:00:00 2001 From: Luca Versari Date: Thu, 1 Jan 2026 13:07:02 +0100 Subject: [PATCH 1452/3801] Clarify documentation around "undefined" bits in intrinsics. --- .../stdarch/crates/core_arch/src/x86/avx.rs | 18 +++++-- .../crates/core_arch/src/x86/avx512f.rs | 48 ++++++++++++++++--- .../stdarch/crates/core_arch/src/x86/sse.rs | 2 +- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx.rs b/library/stdarch/crates/core_arch/src/x86/avx.rs index 94f075894ad2..e0e01ae6d034 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx.rs @@ -2946,7 +2946,11 @@ pub const fn _mm256_castsi256_si128(a: __m256i) -> __m128i { } /// Casts vector of type __m128 to type __m256; -/// the upper 128 bits of the result are undefined. +/// the upper 128 bits of the result are indeterminate. +/// +/// In the Intel documentation, the upper bits are declared to be "undefined". +/// This is not equivalent to [`mem::MaybeUninit`]; instead, these bits are non-deterministically +/// set to some valid value. In practice, this is typically equivalent to [`mem::zeroed`]. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_castps128_ps256) #[inline] @@ -2960,7 +2964,11 @@ pub const fn _mm256_castps128_ps256(a: __m128) -> __m256 { } /// Casts vector of type __m128d to type __m256d; -/// the upper 128 bits of the result are undefined. +/// the upper 128 bits of the result are indeterminate. +/// +/// In the Intel documentation, the upper bits are declared to be "undefined". +/// This is not equivalent to [`mem::MaybeUninit`]; instead, these bits are non-deterministically +/// set to some valid value. In practice, this is typically equivalent to [`mem::zeroed`]. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_castpd128_pd256) #[inline] @@ -2974,7 +2982,11 @@ pub const fn _mm256_castpd128_pd256(a: __m128d) -> __m256d { } /// Casts vector of type __m128i to type __m256i; -/// the upper 128 bits of the result are undefined. +/// the upper 128 bits of the result are indeterminate. +/// +/// In the Intel documentation, the upper bits are declared to be "undefined". +/// This is not equivalent to [`mem::MaybeUninit`]; instead, these bits are non-deterministically +/// set to some valid value. In practice, this is typically equivalent to [`mem::zeroed`]. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_castsi128_si256) #[inline] diff --git a/library/stdarch/crates/core_arch/src/x86/avx512f.rs b/library/stdarch/crates/core_arch/src/x86/avx512f.rs index 5da633f50e93..76b753938383 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512f.rs @@ -27728,7 +27728,13 @@ pub const fn _mm_maskz_unpacklo_pd(k: __mmask8, a: __m128d, b: __m128d) -> __m12 } } -/// Cast vector of type __m128 to type __m512; the upper 384 bits of the result are undefined. This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. +/// Cast vector of type __m128 to type __m512; the upper 384 bits of the result are indeterminate. +/// +/// In the Intel documentation, the upper bits are declared to be "undefined". +/// This is not equivalent to [`mem::MaybeUninit`]; instead, these bits are non-deterministically +/// set to some valid value. In practice, this is typically equivalent to [`mem::zeroed`]. +/// +/// This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_castps128_ps512&expand=621) #[inline] @@ -27745,7 +27751,13 @@ pub const fn _mm512_castps128_ps512(a: __m128) -> __m512 { } } -/// Cast vector of type __m256 to type __m512; the upper 256 bits of the result are undefined. This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. +/// Cast vector of type __m256 to type __m512; the upper 256 bits of the result are indeterminate. +/// +/// In the Intel documentation, the upper bits are declared to be "undefined". +/// This is not equivalent to [`mem::MaybeUninit`]; instead, these bits are non-deterministically +/// set to some valid value. In practice, this is typically equivalent to [`mem::zeroed`]. +/// +/// This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_castps256_ps512&expand=623) #[inline] @@ -27840,7 +27852,13 @@ pub const fn _mm512_castps_si512(a: __m512) -> __m512i { unsafe { transmute(a) } } -/// Cast vector of type __m128d to type __m512d; the upper 384 bits of the result are undefined. This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. +/// Cast vector of type __m128d to type __m512d; the upper 384 bits of the result are indeterminate. +/// +/// In the Intel documentation, the upper bits are declared to be "undefined". +/// This is not equivalent to [`mem::MaybeUninit`]; instead, these bits are non-deterministically +/// set to some valid value. In practice, this is typically equivalent to [`mem::zeroed`]. +/// +/// This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_castpd128_pd512&expand=609) #[inline] @@ -27851,7 +27869,13 @@ pub const fn _mm512_castpd128_pd512(a: __m128d) -> __m512d { unsafe { simd_shuffle!(a, _mm_undefined_pd(), [0, 1, 2, 2, 2, 2, 2, 2]) } } -/// Cast vector of type __m256d to type __m512d; the upper 256 bits of the result are undefined. This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. +/// Cast vector of type __m256d to type __m512d; the upper 256 bits of the result are indeterminate. +/// +/// In the Intel documentation, the upper bits are declared to be "undefined". +/// This is not equivalent to [`mem::MaybeUninit`]; instead, these bits are non-deterministically +/// set to some valid value. In practice, this is typically equivalent to [`mem::zeroed`]. +/// +/// This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_castpd256_pd512&expand=611) #[inline] @@ -27928,7 +27952,13 @@ pub const fn _mm512_castpd_si512(a: __m512d) -> __m512i { unsafe { transmute(a) } } -/// Cast vector of type __m128i to type __m512i; the upper 384 bits of the result are undefined. This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. +/// Cast vector of type __m128i to type __m512i; the upper 384 bits of the result are indeterminate. +/// +/// In the Intel documentation, the upper bits are declared to be "undefined". +/// This is not equivalent to [`mem::MaybeUninit`]; instead, these bits are non-deterministically +/// set to some valid value. In practice, this is typically equivalent to [`mem::zeroed`]. +/// +/// This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_castsi128_si512&expand=629) #[inline] @@ -27939,7 +27969,13 @@ pub const fn _mm512_castsi128_si512(a: __m128i) -> __m512i { unsafe { simd_shuffle!(a, _mm_undefined_si128(), [0, 1, 2, 2, 2, 2, 2, 2]) } } -/// Cast vector of type __m256i to type __m512i; the upper 256 bits of the result are undefined. This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. +/// Cast vector of type __m256i to type __m512i; the upper 256 bits of the result are indeterminate. +/// +/// In the Intel documentation, the upper bits are declared to be "undefined". +/// This is not equivalent to [`mem::MaybeUninit`]; instead, these bits are non-deterministically +/// set to some valid value. In practice, this is typically equivalent to [`mem::zeroed`]. +/// +/// This intrinsic is only used for compilation and does not generate any instructions, thus it has zero latency. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_castsi256_si512&expand=633) #[inline] diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index 55392f994460..751f969e50c3 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -1947,7 +1947,7 @@ pub fn _mm_prefetch(p: *const i8) { } } -/// Returns vector of type __m128 with indeterminate elements.with indetermination elements. +/// Returns vector of type __m128 with indeterminate elements. /// Despite using the word "undefined" (following Intel's naming scheme), this non-deterministically /// picks some valid value and is not equivalent to [`mem::MaybeUninit`]. /// In practice, this is typically equivalent to [`mem::zeroed`]. From f89cce3acb5106b98f6ada765677dc11e41518a0 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 17 Dec 2025 14:33:10 +0100 Subject: [PATCH 1453/3801] `c_variadic`: provide `va_arg` for more targets --- compiler/rustc_codegen_llvm/src/va_arg.rs | 106 +++++++++++++++++----- 1 file changed, 83 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index b23415a732cc..688f461e7478 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -1,12 +1,13 @@ -use rustc_abi::{Align, BackendRepr, Endian, HasDataLayout, Primitive, Size, TyAndLayout}; +use rustc_abi::{Align, BackendRepr, Endian, HasDataLayout, Primitive, Size}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::common::IntPredicate; use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::traits::{ BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, LayoutTypeCodegenMethods, }; +use rustc_middle::bug; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_target::spec::{Abi, Arch, Env}; use crate::builder::Builder; @@ -82,6 +83,7 @@ enum PassMode { enum SlotSize { Bytes8 = 8, Bytes4 = 4, + Bytes1 = 1, } enum AllowHigherAlign { @@ -728,7 +730,7 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( fn copy_to_temporary_if_more_aligned<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, reg_addr: &'ll Value, - layout: TyAndLayout<'tcx, Ty<'tcx>>, + layout: TyAndLayout<'tcx>, src_align: Align, ) -> &'ll Value { if layout.layout.align.abi > src_align { @@ -751,7 +753,7 @@ fn copy_to_temporary_if_more_aligned<'ll, 'tcx>( fn x86_64_sysv64_va_arg_from_memory<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, va_list_addr: &'ll Value, - layout: TyAndLayout<'tcx, Ty<'tcx>>, + layout: TyAndLayout<'tcx>, ) -> &'ll Value { let dl = bx.cx.data_layout(); let ptr_align_abi = dl.data_layout().pointer_align().abi; @@ -1003,15 +1005,17 @@ fn emit_xtensa_va_arg<'ll, 'tcx>( return bx.load(layout.llvm_type(bx), value_ptr, layout.align.abi); } +/// Determine the va_arg implementation to use. The LLVM va_arg instruction +/// is lacking in some instances, so we should only use it as a fallback. pub(super) fn emit_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, addr: OperandRef<'tcx, &'ll Value>, target_ty: Ty<'tcx>, ) -> &'ll Value { - // Determine the va_arg implementation to use. The LLVM va_arg instruction - // is lacking in some instances, so we should only use it as a fallback. - let target = &bx.cx.tcx.sess.target; + let layout = bx.cx.layout_of(target_ty); + let target_ty_size = layout.layout.size().bytes(); + let target = &bx.cx.tcx.sess.target; match target.arch { Arch::X86 => emit_ptr_va_arg( bx, @@ -1069,23 +1073,79 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( AllowHigherAlign::Yes, ForceRightAdjust::No, ), + Arch::LoongArch32 => emit_ptr_va_arg( + bx, + addr, + target_ty, + if target_ty_size > 2 * 4 { PassMode::Indirect } else { PassMode::Direct }, + SlotSize::Bytes4, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), + Arch::LoongArch64 => emit_ptr_va_arg( + bx, + addr, + target_ty, + if target_ty_size > 2 * 8 { PassMode::Indirect } else { PassMode::Direct }, + SlotSize::Bytes8, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), + Arch::AmdGpu => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes4, + AllowHigherAlign::No, + ForceRightAdjust::No, + ), + Arch::Nvptx64 => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes1, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), + Arch::Wasm32 => emit_ptr_va_arg( + bx, + addr, + target_ty, + if layout.is_aggregate() || layout.is_zst() || layout.is_1zst() { + PassMode::Indirect + } else { + PassMode::Direct + }, + SlotSize::Bytes4, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), + Arch::Wasm64 => bug!("c-variadic functions are not fully implemented for wasm64"), + Arch::CSky => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes4, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), // Windows x86_64 - Arch::X86_64 if target.is_like_windows => { - let target_ty_size = bx.cx.size_of(target_ty).bytes(); - emit_ptr_va_arg( - bx, - addr, - target_ty, - if target_ty_size > 8 || !target_ty_size.is_power_of_two() { - PassMode::Indirect - } else { - PassMode::Direct - }, - SlotSize::Bytes8, - AllowHigherAlign::No, - ForceRightAdjust::No, - ) - } + Arch::X86_64 if target.is_like_windows => emit_ptr_va_arg( + bx, + addr, + target_ty, + if target_ty_size > 8 || !target_ty_size.is_power_of_two() { + PassMode::Indirect + } else { + PassMode::Direct + }, + SlotSize::Bytes8, + AllowHigherAlign::No, + ForceRightAdjust::No, + ), // This includes `target.is_like_darwin`, which on x86_64 targets is like sysv64. Arch::X86_64 => emit_x86_64_sysv64_va_arg(bx, addr, target_ty), Arch::Xtensa => emit_xtensa_va_arg(bx, addr, target_ty), From 6453a17534cca0089e9711cce8f6799a8433713a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 18 Dec 2025 14:11:08 +0100 Subject: [PATCH 1454/3801] add `vpdpbusd` avx512 intrinsic --- src/tools/miri/src/shims/x86/avx512.rs | 58 +++++++++++ .../pass/shims/x86/intrinsics-x86-avx512.rs | 99 ++++++++++++++++++- 2 files changed, 156 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/src/shims/x86/avx512.rs b/src/tools/miri/src/shims/x86/avx512.rs index a886f5622ced..0466ba1bd6c0 100644 --- a/src/tools/miri/src/shims/x86/avx512.rs +++ b/src/tools/miri/src/shims/x86/avx512.rs @@ -109,8 +109,66 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { pshufb(this, left, right, dest)?; } + + // Used to implement the _mm512_dpbusd_epi32 function. + "vpdpbusd.512" | "vpdpbusd.256" | "vpdpbusd.128" => { + this.expect_target_feature_for_intrinsic(link_name, "avx512vnni")?; + if matches!(unprefixed_name, "vpdpbusd.128" | "vpdpbusd.256") { + this.expect_target_feature_for_intrinsic(link_name, "avx512vl")?; + } + + let [src, a, b] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + vpdpbusd(this, src, a, b, dest)?; + } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn) } } + +/// Multiply groups of 4 adjacent pairs of unsigned 8-bit integers in `a` with corresponding signed +/// 8-bit integers in `b`, producing 4 intermediate signed 16-bit results. Sum these 4 results with +/// the corresponding 32-bit integer in `src` (using wrapping arighmetic), and store the packed +/// 32-bit results in `dst`. +/// +/// +/// +/// +fn vpdpbusd<'tcx>( + ecx: &mut crate::MiriInterpCx<'tcx>, + src: &OpTy<'tcx>, + a: &OpTy<'tcx>, + b: &OpTy<'tcx>, + dest: &MPlaceTy<'tcx>, +) -> InterpResult<'tcx, ()> { + let (src, src_len) = ecx.project_to_simd(src)?; + let (a, a_len) = ecx.project_to_simd(a)?; + let (b, b_len) = ecx.project_to_simd(b)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; + + // fn vpdpbusd(src: i32x16, a: i32x16, b: i32x16) -> i32x16; + // fn vpdpbusd256(src: i32x8, a: i32x8, b: i32x8) -> i32x8; + // fn vpdpbusd128(src: i32x4, a: i32x4, b: i32x4) -> i32x4; + assert_eq!(dest_len, src_len); + assert_eq!(dest_len, a_len); + assert_eq!(dest_len, b_len); + + for i in 0..dest_len { + let src = ecx.read_scalar(&ecx.project_index(&src, i)?)?.to_i32()?; + let a = ecx.read_scalar(&ecx.project_index(&a, i)?)?.to_u32()?; + let b = ecx.read_scalar(&ecx.project_index(&b, i)?)?.to_u32()?; + let dest = ecx.project_index(&dest, i)?; + + let zipped = a.to_le_bytes().into_iter().zip(b.to_le_bytes()); + let intermediate_sum: i32 = zipped + .map(|(a, b)| i32::from(a).strict_mul(i32::from(b.cast_signed()))) + .fold(0, |x, y| x.strict_add(y)); + + // Use `wrapping_add` because `src` is an arbitrary i32 and the addition can overflow. + let res = Scalar::from_i32(intermediate_sum.wrapping_add(src)); + ecx.write_scalar(res, &dest)?; + } + + interp_ok(()) +} diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs index f95429d59ebe..42acb6c3fb37 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs @@ -1,6 +1,6 @@ // We're testing x86 target specific features //@only-target: x86_64 i686 -//@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bitalg,+avx512vpopcntdq +//@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bitalg,+avx512vpopcntdq,+avx512vnni #[cfg(target_arch = "x86")] use std::arch::x86::*; @@ -13,12 +13,14 @@ fn main() { assert!(is_x86_feature_detected!("avx512vl")); assert!(is_x86_feature_detected!("avx512bitalg")); assert!(is_x86_feature_detected!("avx512vpopcntdq")); + assert!(is_x86_feature_detected!("avx512vnni")); unsafe { test_avx512(); test_avx512bitalg(); test_avx512vpopcntdq(); test_avx512ternarylogic(); + test_avx512vnni(); } } @@ -411,6 +413,101 @@ unsafe fn test_avx512ternarylogic() { test_mm_ternarylogic_epi32(); } +#[target_feature(enable = "avx512vnni")] +unsafe fn test_avx512vnni() { + #[target_feature(enable = "avx512vnni")] + unsafe fn test_mm512_dpbusd_epi32() { + const SRC: [i32; 16] = [ + 1, + // Test that addition with the `src` element uses wrapping arithmetic. + i32::MAX, + i32::MIN, + 0, + 0, + 7, + 12345, + -9876, + 0x01020304, + -1, + 42, + 0, + 1_000_000_000, + -1_000_000_000, + 17, + -17, + ]; + + // The `A` array must be interpreted as a sequence of unsigned 8-bit integers. Setting + // the high bit of a byte tests that this is implemented correctly. + const A: [i32; 16] = [ + 0x01010101, + i32::from_le_bytes([1; 4]), + i32::from_le_bytes([1; 4]), + i32::from_le_bytes([u8::MAX; 4]), + i32::from_le_bytes([u8::MAX; 4]), + 0x02_80_01_FF, + 0x00_FF_00_FF, + 0x7F_80_FF_01, + 0x10_20_30_40, + 0xDE_AD_BE_EFu32 as i32, + 0x00_00_00_FF, + 0x12_34_56_78, + 0xFF_00_FF_00u32 as i32, + 0x01_02_03_04, + 0xAA_55_AA_55u32 as i32, + 0x11_22_33_44, + ]; + + // The `B` array must be interpreted as a sequence of signed 8-bit integers. Setting + // the high bit of a byte tests that this is implemented correctly. + const B: [i32; 16] = [ + 0x01010101, + i32::from_le_bytes([1; 4]), + i32::from_le_bytes([(-1i8).cast_unsigned(); 4]), + i32::from_le_bytes([i8::MAX.cast_unsigned(); 4]), + i32::from_le_bytes([i8::MIN.cast_unsigned(); 4]), + 0xFF_01_80_7Fu32 as i32, + 0x01_FF_01_FF, + 0x80_7F_00_FFu32 as i32, + 0x7F_01_FF_80u32 as i32, + 0x01_02_03_04, + 0xFF_FF_FF_FFu32 as i32, + 0x80_00_7F_FFu32 as i32, + 0x7F_80_7F_80u32 as i32, + 0x40_C0_20_E0u32 as i32, + 0x00_01_02_03, + 0x7F_7E_80_81u32 as i32, + ]; + + const DST: [i32; 16] = [ + 5, + i32::MAX.wrapping_add(4), + i32::MIN.wrapping_add(-4), + 129540, + -130560, + 32390, + 11835, + -9877, + 16902884, + 2093, + -213, + 8498, + 1000064770, + -1000000096, + 697, + -8738, + ]; + + let src = _mm512_loadu_si512(SRC.as_ptr().cast::<__m512i>()); + let a = _mm512_loadu_si512(A.as_ptr().cast::<__m512i>()); + let b = _mm512_loadu_si512(B.as_ptr().cast::<__m512i>()); + let dst = _mm512_loadu_si512(DST.as_ptr().cast::<__m512i>()); + + assert_eq_m512i(_mm512_dpbusd_epi32(src, a, b), dst); + } + test_mm512_dpbusd_epi32(); +} + #[track_caller] unsafe fn assert_eq_m512i(a: __m512i, b: __m512i) { assert_eq!(transmute::<_, [i32; 16]>(a), transmute::<_, [i32; 16]>(b)) From a390881bde042f39c12001044c7476545abcb390 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 1 Jan 2026 14:46:16 +0100 Subject: [PATCH 1455/3801] Do not make suggestion machine-applicable if it may change semantics When suggesting to replace an iterator method by `.all()` or `.any()`, make the suggestion at most `MaybeIncorrect` instead of `MachineApplicable` and warn about the fact that semantics may change because those two methods are short-circuiting. --- clippy_lints/src/methods/unnecessary_fold.rs | 108 ++++++++++++------- tests/ui/unnecessary_fold.stderr | 7 ++ 2 files changed, 77 insertions(+), 38 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index 9dae6fbb48dd..7802763ef74a 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -1,10 +1,10 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath, MaybeTypeckRes}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_blocks, strip_pat_refs}; use rustc_ast::ast; use rustc_data_structures::packed::Pu128; -use rustc_errors::Applicability; +use rustc_errors::{Applicability, Diag}; use rustc_hir as hir; use rustc_hir::PatKind; use rustc_hir::def::{DefKind, Res}; @@ -59,6 +59,34 @@ struct Replacement { method_name: &'static str, has_args: bool, has_generic_return: bool, + is_short_circuiting: bool, +} + +impl Replacement { + fn default_applicability(&self) -> Applicability { + if self.is_short_circuiting { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable + } + } + + fn maybe_add_note(&self, diag: &mut Diag<'_, ()>) { + if self.is_short_circuiting { + diag.note(format!( + "the `{}` method is short circuiting and may change the program semantics if the iterator has side effects", + self.method_name + )); + } + } + + fn maybe_turbofish(&self, ty: Ty<'_>) -> String { + if self.has_generic_return { + format!("::<{ty}>") + } else { + String::new() + } + } } fn check_fold_with_op( @@ -86,32 +114,29 @@ fn check_fold_with_op( && left_expr.res_local_id() == Some(first_arg_id) && (replacement.has_args || right_expr.res_local_id() == Some(second_arg_id)) { - let mut applicability = Applicability::MachineApplicable; - - let turbofish = if replacement.has_generic_return { - format!("::<{}>", cx.typeck_results().expr_ty_adjusted(right_expr).peel_refs()) - } else { - String::new() - }; - - let sugg = if replacement.has_args { - format!( - "{method}{turbofish}(|{second_arg_ident}| {r})", - method = replacement.method_name, - r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), - ) - } else { - format!("{method}{turbofish}()", method = replacement.method_name) - }; - - span_lint_and_sugg( + let span = fold_span.with_hi(expr.span.hi()); + span_lint_and_then( cx, UNNECESSARY_FOLD, - fold_span.with_hi(expr.span.hi()), + span, "this `.fold` can be written more succinctly using another method", - "try", - sugg, - applicability, + |diag| { + let mut applicability = replacement.default_applicability(); + let turbofish = + replacement.maybe_turbofish(cx.typeck_results().expr_ty_adjusted(right_expr).peel_refs()); + let sugg = if replacement.has_args { + format!( + "{method}{turbofish}(|{second_arg_ident}| {r})", + method = replacement.method_name, + r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), + ) + } else { + format!("{method}{turbofish}()", method = replacement.method_name) + }; + + diag.span_suggestion(span, "try", sugg, applicability); + replacement.maybe_add_note(diag); + }, ); return true; } @@ -131,22 +156,25 @@ fn check_fold_with_method( // Check if the function belongs to the operator && cx.tcx.is_diagnostic_item(method, fn_did) { - let applicability = Applicability::MachineApplicable; - - let turbofish = if replacement.has_generic_return { - format!("::<{}>", cx.typeck_results().expr_ty(expr)) - } else { - String::new() - }; - - span_lint_and_sugg( + let span = fold_span.with_hi(expr.span.hi()); + span_lint_and_then( cx, UNNECESSARY_FOLD, - fold_span.with_hi(expr.span.hi()), + span, "this `.fold` can be written more succinctly using another method", - "try", - format!("{method}{turbofish}()", method = replacement.method_name), - applicability, + |diag| { + diag.span_suggestion( + span, + "try", + format!( + "{method}{turbofish}()", + method = replacement.method_name, + turbofish = replacement.maybe_turbofish(cx.typeck_results().expr_ty(expr)) + ), + replacement.default_applicability(), + ); + replacement.maybe_add_note(diag); + }, ); } } @@ -171,6 +199,7 @@ pub(super) fn check<'tcx>( method_name: "any", has_args: true, has_generic_return: false, + is_short_circuiting: true, }; check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Or, replacement); }, @@ -179,6 +208,7 @@ pub(super) fn check<'tcx>( method_name: "all", has_args: true, has_generic_return: false, + is_short_circuiting: true, }; check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, replacement); }, @@ -187,6 +217,7 @@ pub(super) fn check<'tcx>( method_name: "sum", has_args: false, has_generic_return: needs_turbofish(cx, expr), + is_short_circuiting: false, }; if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Add, replacement) { check_fold_with_method(cx, expr, acc, fold_span, sym::add, replacement); @@ -197,6 +228,7 @@ pub(super) fn check<'tcx>( method_name: "product", has_args: false, has_generic_return: needs_turbofish(cx, expr), + is_short_circuiting: false, }; if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, replacement) { check_fold_with_method(cx, expr, acc, fold_span, sym::mul, replacement); diff --git a/tests/ui/unnecessary_fold.stderr b/tests/ui/unnecessary_fold.stderr index bb8aa7e18d34..025a2bd0048b 100644 --- a/tests/ui/unnecessary_fold.stderr +++ b/tests/ui/unnecessary_fold.stderr @@ -4,6 +4,7 @@ error: this `.fold` can be written more succinctly using another method LL | let _ = (0..3).fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` | + = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects = note: `-D clippy::unnecessary-fold` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fold)]` @@ -21,6 +22,8 @@ error: this `.fold` can be written more succinctly using another method | LL | let _ = (0..3).fold(true, |acc, x| acc && x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `all(|x| x > 2)` + | + = note: the `all` method is short circuiting and may change the program semantics if the iterator has side effects error: this `.fold` can be written more succinctly using another method --> tests/ui/unnecessary_fold.rs:24:25 @@ -63,12 +66,16 @@ error: this `.fold` can be written more succinctly using another method | LL | let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` + | + = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects error: this `.fold` can be written more succinctly using another method --> tests/ui/unnecessary_fold.rs:110:10 | LL | .fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` + | + = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects error: this `.fold` can be written more succinctly using another method --> tests/ui/unnecessary_fold.rs:123:33 From e79fef40866bfbf2a4ae33b0030205ce51a7adf9 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Thu, 1 Jan 2026 22:21:57 +0800 Subject: [PATCH 1456/3801] Fix incorrect Self path expand for inline_call Example --- ```rust trait Trait { fn f() -> Self; } struct Foo<'a>(&'a ()); impl<'a> Trait for Foo<'a> { fn f() -> Self { Self(&()) } } impl Foo<'_> { fn new() -> Self { Self::$0f() } } ``` **Before this PR** ```rust trait Trait { fn f() -> Self; } struct Foo<'a>(&'a ()); impl<'a> Trait for Foo<'a> { fn f() -> Self { Self(&()) } } impl Foo<'_> { fn new() -> Self { Foo<'a>(&()) } } ``` **After this PR** ```rust trait Trait { fn f() -> Self; } struct Foo<'a>(&'a ()); impl<'a> Trait for Foo<'a> { fn f() -> Self { Self(&()) } } impl Foo<'_> { fn new() -> Self { Foo(&()) } } ``` --- .../ide-assists/src/handlers/inline_call.rs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs index fa4f2a78c8b7..21f2249a19c9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs @@ -403,6 +403,12 @@ fn inline( .find(|tok| tok.kind() == SyntaxKind::SELF_TYPE_KW) { let replace_with = t.clone_subtree().syntax().clone_for_update(); + if !is_in_type_path(&self_tok) + && let Some(ty) = ast::Type::cast(replace_with.clone()) + && let Some(generic_arg_list) = ty.generic_arg_list() + { + ted::remove(generic_arg_list.syntax()); + } ted::replace(self_tok, replace_with); } } @@ -588,6 +594,17 @@ fn inline( } } +fn is_in_type_path(self_tok: &syntax::SyntaxToken) -> bool { + self_tok + .parent_ancestors() + .skip_while(|it| !ast::Path::can_cast(it.kind())) + .map_while(ast::Path::cast) + .last() + .and_then(|it| it.syntax().parent()) + .and_then(ast::PathType::cast) + .is_some() +} + fn path_expr_as_record_field(usage: &PathExpr) -> Option { let path = usage.path()?; let name_ref = path.as_single_name_ref()?; @@ -1694,6 +1711,41 @@ fn main() { ) } + #[test] + fn inline_trait_method_call_with_lifetimes() { + check_assist( + inline_call, + r#" +trait Trait { + fn f() -> Self; +} +struct Foo<'a>(&'a ()); +impl<'a> Trait for Foo<'a> { + fn f() -> Self { Self(&()) } +} +impl Foo<'_> { + fn new() -> Self { + Self::$0f() + } +} +"#, + r#" +trait Trait { + fn f() -> Self; +} +struct Foo<'a>(&'a ()); +impl<'a> Trait for Foo<'a> { + fn f() -> Self { Self(&()) } +} +impl Foo<'_> { + fn new() -> Self { + Foo(&()) + } +} +"#, + ) + } + #[test] fn method_by_reborrow() { check_assist( From 344fc5112a5bf77e079551971f4c49614f284d21 Mon Sep 17 00:00:00 2001 From: usamoi Date: Thu, 1 Jan 2026 19:52:45 +0800 Subject: [PATCH 1457/3801] Use LLVM intrinsics for `madd` intrinsics --- .../stdarch/crates/core_arch/src/x86/avx2.rs | 26 +++++--- .../crates/core_arch/src/x86/avx512bw.rs | 64 +++++++++---------- .../stdarch/crates/core_arch/src/x86/sse2.rs | 26 +++++--- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 740b09d11642..6f56e937c6db 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -1813,14 +1813,20 @@ pub const fn _mm256_inserti128_si256(a: __m256i, b: __m128i) -> #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let r: i32x16 = simd_mul(simd_cast(a.as_i16x16()), simd_cast(b.as_i16x16())); - let even: i32x8 = simd_shuffle!(r, r, [0, 2, 4, 6, 8, 10, 12, 14]); - let odd: i32x8 = simd_shuffle!(r, r, [1, 3, 5, 7, 9, 11, 13, 15]); - simd_add(even, odd).as_m256i() - } +pub fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i { + // It's a trick used in the Adler-32 algorithm to perform a widening addition. + // + // ```rust + // #[target_feature(enable = "avx2")] + // unsafe fn widening_add(mad: __m256i) -> __m256i { + // _mm256_madd_epi16(mad, _mm256_set1_epi16(1)) + // } + // ``` + // + // If we implement this using generic vector intrinsics, the optimizer + // will eliminate this pattern, and `vpmaddwd` will no longer be emitted. + // For this reason, we use x86 intrinsics. + unsafe { transmute(pmaddwd(a.as_i16x16(), b.as_i16x16())) } } /// Vertically multiplies each unsigned 8-bit integer from `a` with the @@ -3789,6 +3795,8 @@ unsafe extern "C" { fn phaddsw(a: i16x16, b: i16x16) -> i16x16; #[link_name = "llvm.x86.avx2.phsub.sw"] fn phsubsw(a: i16x16, b: i16x16) -> i16x16; + #[link_name = "llvm.x86.avx2.pmadd.wd"] + fn pmaddwd(a: i16x16, b: i16x16) -> i32x8; #[link_name = "llvm.x86.avx2.pmadd.ub.sw"] fn pmaddubsw(a: u8x32, b: i8x32) -> i16x16; #[link_name = "llvm.x86.avx2.mpsadbw"] @@ -4637,7 +4645,7 @@ mod tests { } #[simd_test(enable = "avx2")] - const fn test_mm256_madd_epi16() { + fn test_mm256_madd_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_madd_epi16(a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index dc86f70c05c8..6b4b88621efd 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -6321,22 +6321,20 @@ pub const unsafe fn _mm_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask16, a: #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let r: i32x32 = simd_mul(simd_cast(a.as_i16x32()), simd_cast(b.as_i16x32())); - let even: i32x16 = simd_shuffle!( - r, - r, - [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30] - ); - let odd: i32x16 = simd_shuffle!( - r, - r, - [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31] - ); - simd_add(even, odd).as_m512i() - } +pub fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { + // It's a trick used in the Adler-32 algorithm to perform a widening addition. + // + // ```rust + // #[target_feature(enable = "avx512bw")] + // unsafe fn widening_add(mad: __m512i) -> __m512i { + // _mm512_madd_epi16(mad, _mm512_set1_epi16(1)) + // } + // ``` + // + // If we implement this using generic vector intrinsics, the optimizer + // will eliminate this pattern, and `vpmaddwd` will no longer be emitted. + // For this reason, we use x86 intrinsics. + unsafe { transmute(vpmaddwd(a.as_i16x32(), b.as_i16x32())) } } /// Multiply packed signed 16-bit integers in a and b, producing intermediate signed 32-bit integers. Horizontally add adjacent pairs of intermediate 32-bit integers, and pack the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6346,8 +6344,7 @@ pub const fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +pub fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let madd = _mm512_madd_epi16(a, b).as_i32x16(); transmute(simd_select_bitmask(k, madd, src.as_i32x16())) @@ -6361,8 +6358,7 @@ pub const fn _mm512_mask_madd_epi16(src: __m512i, k: __mmask16, a: __m512i, b: _ #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { +pub fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __m512i { unsafe { let madd = _mm512_madd_epi16(a, b).as_i32x16(); transmute(simd_select_bitmask(k, madd, i32x16::ZERO)) @@ -6376,8 +6372,7 @@ pub const fn _mm512_maskz_madd_epi16(k: __mmask16, a: __m512i, b: __m512i) -> __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +pub fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let madd = _mm256_madd_epi16(a, b).as_i32x8(); transmute(simd_select_bitmask(k, madd, src.as_i32x8())) @@ -6391,8 +6386,7 @@ pub const fn _mm256_mask_madd_epi16(src: __m256i, k: __mmask8, a: __m256i, b: __ #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { +pub fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m256i { unsafe { let madd = _mm256_madd_epi16(a, b).as_i32x8(); transmute(simd_select_bitmask(k, madd, i32x8::ZERO)) @@ -6406,8 +6400,7 @@ pub const fn _mm256_maskz_madd_epi16(k: __mmask8, a: __m256i, b: __m256i) -> __m #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +pub fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let madd = _mm_madd_epi16(a, b).as_i32x4(); transmute(simd_select_bitmask(k, madd, src.as_i32x4())) @@ -6421,8 +6414,7 @@ pub const fn _mm_mask_madd_epi16(src: __m128i, k: __mmask8, a: __m128i, b: __m12 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm_maskz_madd_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +pub fn _mm_maskz_madd_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let madd = _mm_madd_epi16(a, b).as_i32x4(); transmute(simd_select_bitmask(k, madd, i32x4::ZERO)) @@ -12582,6 +12574,8 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.pmul.hr.sw.512"] fn vpmulhrsw(a: i16x32, b: i16x32) -> i16x32; + #[link_name = "llvm.x86.avx512.pmaddw.d.512"] + fn vpmaddwd(a: i16x32, b: i16x32) -> i32x16; #[link_name = "llvm.x86.avx512.pmaddubs.w.512"] fn vpmaddubsw(a: u8x64, b: i8x64) -> i16x32; @@ -17486,7 +17480,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const fn test_mm512_madd_epi16() { + fn test_mm512_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_madd_epi16(a, b); @@ -17495,7 +17489,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const fn test_mm512_mask_madd_epi16() { + fn test_mm512_mask_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_mask_madd_epi16(a, 0, a, b); @@ -17523,7 +17517,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const fn test_mm512_maskz_madd_epi16() { + fn test_mm512_maskz_madd_epi16() { let a = _mm512_set1_epi16(1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_madd_epi16(0, a, b); @@ -17534,7 +17528,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - const fn test_mm256_mask_madd_epi16() { + fn test_mm256_mask_madd_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_mask_madd_epi16(a, 0, a, b); @@ -17554,7 +17548,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - const fn test_mm256_maskz_madd_epi16() { + fn test_mm256_maskz_madd_epi16() { let a = _mm256_set1_epi16(1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_madd_epi16(0, a, b); @@ -17565,7 +17559,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - const fn test_mm_mask_madd_epi16() { + fn test_mm_mask_madd_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_mask_madd_epi16(a, 0, a, b); @@ -17576,7 +17570,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - const fn test_mm_maskz_madd_epi16() { + fn test_mm_maskz_madd_epi16() { let a = _mm_set1_epi16(1); let b = _mm_set1_epi16(1); let r = _mm_maskz_madd_epi16(0, a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index d7ac00287f5e..eec01ce1db7c 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -210,14 +210,20 @@ pub const fn _mm_avg_epu16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(pmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] -#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] -pub const fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let r: i32x8 = simd_mul(simd_cast(a.as_i16x8()), simd_cast(b.as_i16x8())); - let even: i32x4 = simd_shuffle!(r, r, [0, 2, 4, 6]); - let odd: i32x4 = simd_shuffle!(r, r, [1, 3, 5, 7]); - simd_add(even, odd).as_m128i() - } +pub fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { + // It's a trick used in the Adler-32 algorithm to perform a widening addition. + // + // ```rust + // #[target_feature(enable = "sse2")] + // unsafe fn widening_add(mad: __m128i) -> __m128i { + // _mm_madd_epi16(mad, _mm_set1_epi16(1)) + // } + // ``` + // + // If we implement this using generic vector intrinsics, the optimizer + // will eliminate this pattern, and `pmaddwd` will no longer be emitted. + // For this reason, we use x86 intrinsics. + unsafe { transmute(pmaddwd(a.as_i16x8(), b.as_i16x8())) } } /// Compares packed 16-bit integers in `a` and `b`, and returns the packed @@ -3187,6 +3193,8 @@ unsafe extern "C" { fn lfence(); #[link_name = "llvm.x86.sse2.mfence"] fn mfence(); + #[link_name = "llvm.x86.sse2.pmadd.wd"] + fn pmaddwd(a: i16x8, b: i16x8) -> i32x4; #[link_name = "llvm.x86.sse2.psad.bw"] fn psadbw(a: u8x16, b: u8x16) -> u64x2; #[link_name = "llvm.x86.sse2.psll.w"] @@ -3467,7 +3475,7 @@ mod tests { } #[simd_test(enable = "sse2")] - const fn test_mm_madd_epi16() { + fn test_mm_madd_epi16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let b = _mm_setr_epi16(9, 10, 11, 12, 13, 14, 15, 16); let r = _mm_madd_epi16(a, b); From c71381f55f2cb7431b368142f96ce5d048da7324 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 Jan 2026 00:38:22 +0800 Subject: [PATCH 1458/3801] triagebot: remove `compiler-errors` triagebot entries Since they became alumni and don't want to receive pings anymore. --- triagebot.toml | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index de9ac961dc8c..4364bf3bdc52 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -954,15 +954,15 @@ cc = ["@lcnr"] [mentions."compiler/rustc_middle/src/ty/relate.rs"] message = "changes to the core type system" -cc = ["@compiler-errors", "@lcnr"] +cc = ["@lcnr"] [mentions."compiler/rustc_infer/src/infer/relate"] message = "changes to the core type system" -cc = ["@compiler-errors", "@lcnr"] +cc = ["@lcnr"] [mentions."compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs"] message = "changes to `inspect_obligations.rs`" -cc = ["@compiler-errors", "@lcnr"] +cc = ["@lcnr"] [mentions."compiler/rustc_middle/src/mir/interpret"] message = "Some changes occurred to the CTFE / Miri interpreter" @@ -974,7 +974,7 @@ cc = ["@rust-lang/wg-mir-opt"] [mentions."compiler/rustc_trait_selection/src/traits/wf.rs"] message = "changes to the core type system" -cc = ["@compiler-errors", "@lcnr"] +cc = ["@lcnr"] [mentions."compiler/rustc_trait_selection/src/traits/const_evaluatable.rs"] message = "Some changes occurred in `const_evaluatable.rs`" @@ -997,7 +997,7 @@ message = """ Some changes occurred in engine.rs, potentially modifying the public API \ of `ObligationCtxt`. """ -cc = ["@lcnr", "@compiler-errors"] +cc = ["@lcnr"] [mentions."compiler/rustc_hir_analysis/src/hir_ty_lowering"] message = "HIR ty lowering was modified" @@ -1146,7 +1146,7 @@ cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@vakaras"] [mentions."compiler/rustc_error_messages"] message = "`rustc_error_messages` was changed" -cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] +cc = ["@davidtwco", "@TaKO8Ki"] [mentions."compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs"] message = "`rustc_errors::annotate_snippet_emitter_writer` was changed" @@ -1158,11 +1158,11 @@ cc = ["@Muscraft"] [mentions."compiler/rustc_errors/src/translation.rs"] message = "`rustc_errors::translation` was changed" -cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] +cc = ["@davidtwco", "@TaKO8Ki"] [mentions."compiler/rustc_macros/src/diagnostics"] message = "`rustc_macros::diagnostics` was changed" -cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] +cc = ["@davidtwco", "@TaKO8Ki"] [mentions."compiler/rustc_public"] message = "This PR changes rustc_public" @@ -1427,7 +1427,6 @@ compiler_leads = [ compiler = [ "@BoxyUwU", "@chenyukang", - "@compiler-errors", "@davidtwco", "@eholk", "@fee1-dead", @@ -1486,13 +1485,11 @@ incremental = [ "@wesleywiser", ] diagnostics = [ - "@compiler-errors", "@davidtwco", "@oli-obk", "@chenyukang", ] parser = [ - "@compiler-errors", "@davidtwco", "@nnethercote", "@petrochenkov", @@ -1518,7 +1515,6 @@ mir-opt = [ "@saethlin", ] types = [ - "@compiler-errors", "@jackh726", "@lcnr", "@oli-obk", @@ -1530,7 +1526,6 @@ borrowck = [ "@matthewjasper" ] ast_lowering = [ - "@compiler-errors", "@spastorino", ] debuginfo = [ @@ -1545,7 +1540,6 @@ style-team = [ "@traviscross", ] project-const-traits = [ - "@compiler-errors", "@fee1-dead", "@fmease", "@oli-obk", @@ -1639,7 +1633,7 @@ dep-bumps = [ "/tests/rustdoc-ui" = ["rustdoc"] "/tests/ui" = ["compiler"] "/src/tools/cargo" = ["@ehuss"] -"/src/tools/compiletest" = ["bootstrap", "@wesleywiser", "@oli-obk", "@compiler-errors", "@jieyouxu"] +"/src/tools/compiletest" = ["bootstrap", "@wesleywiser", "@oli-obk", "@jieyouxu"] "/src/tools/linkchecker" = ["@ehuss"] "/src/tools/opt-dist" = ["@kobzol"] "/src/tools/run-make-support" = ["@jieyouxu"] From d7f3c3995c3f0dd70a8babd5a843d057bf4a3c7f Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 Jan 2026 00:39:46 +0800 Subject: [PATCH 1459/3801] triagebot: expand eligible reviewer pool for `tests/{run-make,run-make-cargo}` to `compiler` So that I don't become the only automatically-assigned reviewer due to weighting reasons. --- triagebot.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 4364bf3bdc52..161a339cdb12 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1623,8 +1623,8 @@ dep-bumps = [ "/src/llvm-project" = ["@cuviper"] "/src/rustdoc-json-types" = ["rustdoc"] "/src/stage0" = ["bootstrap"] -"/tests/run-make" = ["@jieyouxu"] -"/tests/run-make-cargo" = ["@jieyouxu"] +"/tests/run-make" = ["compiler"] +"/tests/run-make-cargo" = ["compiler"] "/tests/rustdoc" = ["rustdoc"] "/tests/rustdoc-gui" = ["rustdoc"] "/tests/rustdoc-js-std" = ["rustdoc"] From f716d6ca972294ca327eb383737e2f6c6ace2fdb Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 Jan 2026 00:51:22 +0800 Subject: [PATCH 1460/3801] triagebot: add `jieyouxu` to `fallback` `adhoc_group` So that there's `n > 1` selection pool in case one of the eligible reviewers go off rotation. --- triagebot.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 161a339cdb12..fb6660b9dd03 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1532,7 +1532,8 @@ debuginfo = [ "@davidtwco" ] fallback = [ - "@Mark-Simulacrum" + "@Mark-Simulacrum", + "@jieyouxu", ] style-team = [ "@calebcartwright", From 33add367e2b265f4ed0fcc32e7f795f87992c488 Mon Sep 17 00:00:00 2001 From: Flakebi Date: Thu, 1 Jan 2026 18:34:24 +0100 Subject: [PATCH 1461/3801] Add checks for gpu-kernel calling conv The `gpu-kernel` calling convention has several restrictions that were not enforced by the compiler until now. Add the following restrictions: 1. Cannot be async 2. Cannot be called 3. Cannot return values, return type must be `()` or `!` 4. Arguments should be primitives, i.e. passed by value. More complicated types can work when you know what you are doing, but it is rather unintuitive, one needs to know ABI/compiler internals. 5. Export name should be unmangled, either through `no_mangle` or `export_name`. Kernels are searched by name on the CPU side, having a mangled name makes it hard to find and probably almost always unintentional. --- compiler/rustc_abi/src/extern_abi.rs | 1 - .../rustc_ast_passes/src/ast_validation.rs | 34 +-- compiler/rustc_hir_typeck/messages.ftl | 4 + compiler/rustc_hir_typeck/src/callee.rs | 26 +-- compiler/rustc_hir_typeck/src/errors.rs | 8 + compiler/rustc_lint/messages.ftl | 7 + compiler/rustc_lint/src/gpukernel_abi.rs | 194 ++++++++++++++++++ compiler/rustc_lint/src/lib.rs | 3 + compiler/rustc_lint/src/lints.rs | 13 ++ tests/ui/abi/cannot-be-called.amdgpu.stderr | 87 ++++++++ tests/ui/abi/cannot-be-called.avr.stderr | 38 ++-- tests/ui/abi/cannot-be-called.i686.stderr | 38 ++-- tests/ui/abi/cannot-be-called.msp430.stderr | 38 ++-- tests/ui/abi/cannot-be-called.nvptx.stderr | 87 ++++++++ tests/ui/abi/cannot-be-called.riscv32.stderr | 42 ++-- tests/ui/abi/cannot-be-called.riscv64.stderr | 42 ++-- tests/ui/abi/cannot-be-called.rs | 39 ++-- tests/ui/abi/cannot-be-called.x64.stderr | 38 ++-- tests/ui/abi/cannot-be-called.x64_win.stderr | 38 ++-- .../ui/abi/cannot-be-coroutine.amdgpu.stderr | 23 +++ tests/ui/abi/cannot-be-coroutine.avr.stderr | 4 +- tests/ui/abi/cannot-be-coroutine.i686.stderr | 4 +- .../ui/abi/cannot-be-coroutine.msp430.stderr | 4 +- tests/ui/abi/cannot-be-coroutine.nvptx.stderr | 23 +++ .../ui/abi/cannot-be-coroutine.riscv32.stderr | 6 +- .../ui/abi/cannot-be-coroutine.riscv64.stderr | 6 +- tests/ui/abi/cannot-be-coroutine.rs | 13 +- tests/ui/abi/cannot-be-coroutine.x64.stderr | 4 +- .../ui/abi/cannot-be-coroutine.x64_win.stderr | 4 +- tests/ui/abi/cannot-return.amdgpu.stderr | 15 ++ tests/ui/abi/cannot-return.nvptx.stderr | 15 ++ tests/ui/abi/cannot-return.rs | 18 ++ tests/ui/lint/lint-gpu-kernel.amdgpu.stderr | 86 ++++++++ tests/ui/lint/lint-gpu-kernel.nvptx.stderr | 86 ++++++++ tests/ui/lint/lint-gpu-kernel.rs | 62 ++++++ 35 files changed, 998 insertions(+), 152 deletions(-) create mode 100644 compiler/rustc_lint/src/gpukernel_abi.rs create mode 100644 tests/ui/abi/cannot-be-called.amdgpu.stderr create mode 100644 tests/ui/abi/cannot-be-called.nvptx.stderr create mode 100644 tests/ui/abi/cannot-be-coroutine.amdgpu.stderr create mode 100644 tests/ui/abi/cannot-be-coroutine.nvptx.stderr create mode 100644 tests/ui/abi/cannot-return.amdgpu.stderr create mode 100644 tests/ui/abi/cannot-return.nvptx.stderr create mode 100644 tests/ui/abi/cannot-return.rs create mode 100644 tests/ui/lint/lint-gpu-kernel.amdgpu.stderr create mode 100644 tests/ui/lint/lint-gpu-kernel.nvptx.stderr create mode 100644 tests/ui/lint/lint-gpu-kernel.rs diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 6a5ea36f2a42..e44dea1ce593 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -67,7 +67,6 @@ pub enum ExternAbi { /* gpu */ /// An entry-point function called by the GPU's host - // FIXME: should not be callable from Rust on GPU targets, is for host's use only GpuKernel, /// An entry-point function called by the GPU's host // FIXME: why do we have two of these? diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0d34ba6c2ca8..3e70687c16d3 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -401,9 +401,16 @@ impl<'a> AstValidator<'a> { | CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::Arm(_) - | CanonAbi::GpuKernel | CanonAbi::X86(_) => { /* nothing to check */ } + CanonAbi::GpuKernel => { + // An `extern "gpu-kernel"` function cannot be `async` and/or `gen`. + self.reject_coroutine(abi, sig); + + // An `extern "gpu-kernel"` function cannot return a value. + self.reject_return(abi, sig); + } + CanonAbi::Custom => { // An `extern "custom"` function must be unsafe. self.reject_safe_fn(abi, ctxt, sig); @@ -433,18 +440,7 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(errors::AbiX86Interrupt { spans, param_count }); } - if let FnRetTy::Ty(ref ret_ty) = sig.decl.output - && match &ret_ty.kind { - TyKind::Never => false, - TyKind::Tup(tup) if tup.is_empty() => false, - _ => true, - } - { - self.dcx().emit_err(errors::AbiMustNotHaveReturnType { - span: ret_ty.span, - abi, - }); - } + self.reject_return(abi, sig); } else { // An `extern "interrupt"` function must have type `fn()`. self.reject_params_or_return(abi, ident, sig); @@ -496,6 +492,18 @@ impl<'a> AstValidator<'a> { } } + fn reject_return(&self, abi: ExternAbi, sig: &FnSig) { + if let FnRetTy::Ty(ref ret_ty) = sig.decl.output + && match &ret_ty.kind { + TyKind::Never => false, + TyKind::Tup(tup) if tup.is_empty() => false, + _ => true, + } + { + self.dcx().emit_err(errors::AbiMustNotHaveReturnType { span: ret_ty.span, abi }); + } + } + fn reject_params_or_return(&self, abi: ExternAbi, ident: &Ident, sig: &FnSig) { let mut spans: Vec<_> = sig.decl.inputs.iter().map(|p| p.span).collect(); if let FnRetTy::Ty(ref ret_ty) = sig.decl.output diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 325be43a0065..0c4b1f891ead 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -133,6 +133,10 @@ hir_typeck_fru_suggestion = hir_typeck_functional_record_update_on_non_struct = functional record update syntax requires a struct +hir_typeck_gpu_kernel_abi_cannot_be_called = + functions with the "gpu-kernel" ABI cannot be called + .note = an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 714c6a104a9e..b60d053957a9 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -169,27 +169,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - let valid = match canon_abi { + match canon_abi { // Rust doesn't know how to call functions with this ABI. - CanonAbi::Custom => false, - - // These is an entry point for the host, and cannot be called on the GPU. - CanonAbi::GpuKernel => false, - + CanonAbi::Custom // The interrupt ABIs should only be called by the CPU. They have complex // pre- and postconditions, and can use non-standard instructions like `iret` on x86. - CanonAbi::Interrupt(_) => false, + | CanonAbi::Interrupt(_) => { + let err = crate::errors::AbiCannotBeCalled { span, abi }; + self.tcx.dcx().emit_err(err); + } + + // This is an entry point for the host, and cannot be called directly. + CanonAbi::GpuKernel => { + let err = crate::errors::GpuKernelAbiCannotBeCalled { span }; + self.tcx.dcx().emit_err(err); + } CanonAbi::C | CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::Arm(_) - | CanonAbi::X86(_) => true, - }; - - if !valid { - let err = crate::errors::AbiCannotBeCalled { span, abi }; - self.tcx.dcx().emit_err(err); + | CanonAbi::X86(_) => {} } } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 620002915fa8..0cf7f09e9376 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1198,6 +1198,14 @@ pub(crate) struct AbiCannotBeCalled { pub abi: ExternAbi, } +#[derive(Diagnostic)] +#[diag(hir_typeck_gpu_kernel_abi_cannot_be_called)] +pub(crate) struct GpuKernelAbiCannotBeCalled { + #[primary_span] + #[note] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(hir_typeck_const_continue_bad_label)] pub(crate) struct ConstContinueBadLabel { diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 56a0a3ceebf5..2f4537b94da2 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -470,6 +470,9 @@ lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive lint_improper_ctypes_unsafe_binder = unsafe binders are incompatible with foreign function interfaces +lint_improper_gpu_kernel_arg = passing type `{$ty}` to a function with "gpu-kernel" ABI may have unexpected behavior + .help = use primitive types and raw pointers to get reliable behavior + lint_int_to_ptr_transmutes = transmuting an integer to a pointer creates a pointer without provenance .note = this is dangerous because dereferencing the resulting pointer is undefined behavior .note_exposed_provenance = exposed provenance semantics can be used to create a pointer based on some previously exposed provenance @@ -597,6 +600,10 @@ lint_mismatched_lifetime_syntaxes_suggestion_mixed = lint_mismatched_lifetime_syntaxes_suggestion_mixed_only_paths = use `'_` for type paths +lint_missing_gpu_kernel_export_name = function with the "gpu-kernel" ABI has a mangled name + .note = mangled names make it hard to find the kernel, this is usually not intended + .help = use `unsafe(no_mangle)` or `unsafe(export_name = "")` + lint_mixed_script_confusables = the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables .includes_note = the usage includes {$includes} diff --git a/compiler/rustc_lint/src/gpukernel_abi.rs b/compiler/rustc_lint/src/gpukernel_abi.rs new file mode 100644 index 000000000000..dbdf5b6e7955 --- /dev/null +++ b/compiler/rustc_lint/src/gpukernel_abi.rs @@ -0,0 +1,194 @@ +use std::iter; + +use rustc_abi::ExternAbi; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{self as hir, find_attr}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::Span; +use rustc_span::def_id::LocalDefId; + +use crate::lints::{ImproperGpuKernelArg, MissingGpuKernelExportName}; +use crate::{LateContext, LateLintPass, LintContext}; + +declare_lint! { + /// The `improper_gpu_kernel_arg` lint detects incorrect use of types in `gpu-kernel` + /// arguments. + /// + /// ### Example + /// + /// ```rust,ignore (fails on non-GPU targets) + /// #[unsafe(no_mangle)] + /// extern "gpu-kernel" fn kernel(_: [i32; 10]) {} + /// ``` + /// + /// This will produce: + /// + /// ```text + /// warning: passing type `[i32; 10]` to a function with "gpu-kernel" ABI may have unexpected behavior + /// --> t.rs:2:34 + /// | + /// 2 | extern "gpu-kernel" fn kernel(_: [i32; 10]) {} + /// | ^^^^^^^^^ + /// | + /// = help: use primitive types and raw pointers to get reliable behavior + /// = note: `#[warn(improper_gpu_kernel_arg)]` on by default + /// ``` + /// + /// ### Explanation + /// + /// The compiler has several checks to verify that types used as arguments in `gpu-kernel` + /// functions follow certain rules to ensure proper compatibility with the foreign interfaces. + /// This lint is issued when it detects a probable mistake in a signature. + IMPROPER_GPU_KERNEL_ARG, + Warn, + "GPU kernel entry points have a limited ABI" +} + +declare_lint! { + /// The `missing_gpu_kernel_export_name` lint detects `gpu-kernel` functions that have a mangled name. + /// + /// ### Example + /// + /// ```rust,ignore (fails on non-GPU targets) + /// extern "gpu-kernel" fn kernel() { } + /// ``` + /// + /// This will produce: + /// + /// ```text + /// warning: function with the "gpu-kernel" ABI has a mangled name + /// --> t.rs:1:1 + /// | + /// 1 | extern "gpu-kernel" fn kernel() {} + /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// | + /// = help: use `unsafe(no_mangle)` or `unsafe(export_name = "")` + /// = note: mangled names make it hard to find the kernel, this is usually not intended + /// = note: `#[warn(missing_gpu_kernel_export_name)]` on by default + /// ``` + /// + /// ### Explanation + /// + /// `gpu-kernel` functions are usually searched by name in the compiled file. + /// A mangled name is usually unintentional as it would need to be searched by the mangled name. + /// + /// To use an unmangled name for the kernel, either `no_mangle` or `export_name` can be used. + /// ```rust,ignore (fails on non-GPU targets) + /// // Can be found by the name "kernel" + /// #[unsafe(no_mangle)] + /// extern "gpu-kernel" fn kernel() { } + /// + /// // Can be found by the name "new_name" + /// #[unsafe(export_name = "new_name")] + /// extern "gpu-kernel" fn other_kernel() { } + /// ``` + MISSING_GPU_KERNEL_EXPORT_NAME, + Warn, + "mangled gpu-kernel function" +} + +declare_lint_pass!(ImproperGpuKernelLint => [ + IMPROPER_GPU_KERNEL_ARG, + MISSING_GPU_KERNEL_EXPORT_NAME, +]); + +/// Check for valid and invalid types. +struct CheckGpuKernelTypes<'tcx> { + tcx: TyCtxt<'tcx>, + // If one or more invalid types were encountered while folding. + has_invalid: bool, +} + +impl<'tcx> TypeFolder> for CheckGpuKernelTypes<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match ty.kind() { + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => {} + // Thin pointers are allowed but fat pointers with metadata are not + ty::RawPtr(_, _) => { + if !ty.pointee_metadata_ty_or_projection(self.tcx).is_unit() { + self.has_invalid = true; + } + } + + ty::Adt(_, _) + | ty::Alias(_, _) + | ty::Array(_, _) + | ty::Bound(_, _) + | ty::Closure(_, _) + | ty::Coroutine(_, _) + | ty::CoroutineClosure(_, _) + | ty::CoroutineWitness(..) + | ty::Dynamic(_, _) + | ty::FnDef(_, _) + | ty::FnPtr(..) + | ty::Foreign(_) + | ty::Never + | ty::Pat(_, _) + | ty::Placeholder(_) + | ty::Ref(_, _, _) + | ty::Slice(_) + | ty::Str + | ty::Tuple(_) => self.has_invalid = true, + + _ => return ty.super_fold_with(self), + } + ty + } +} + +/// `ImproperGpuKernelLint` checks `gpu-kernel` function definitions: +/// +/// - `extern "gpu-kernel" fn` arguments should be primitive types. +/// - `extern "gpu-kernel" fn` should have an unmangled name. +impl<'tcx> LateLintPass<'tcx> for ImproperGpuKernelLint { + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + kind: hir::intravisit::FnKind<'tcx>, + decl: &'tcx hir::FnDecl<'_>, + _: &'tcx hir::Body<'_>, + span: Span, + id: LocalDefId, + ) { + use hir::intravisit::FnKind; + + let abi = match kind { + FnKind::ItemFn(_, _, header, ..) => header.abi, + FnKind::Method(_, sig, ..) => sig.header.abi, + _ => return, + }; + + if abi != ExternAbi::GpuKernel { + return; + } + + let sig = cx.tcx.fn_sig(id).instantiate_identity(); + let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); + + for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { + let mut checker = CheckGpuKernelTypes { tcx: cx.tcx, has_invalid: false }; + input_ty.fold_with(&mut checker); + if checker.has_invalid { + cx.tcx.emit_node_span_lint( + IMPROPER_GPU_KERNEL_ARG, + input_hir.hir_id, + input_hir.span, + ImproperGpuKernelArg { ty: *input_ty }, + ); + } + } + + // Check for no_mangle/export_name, so the kernel can be found when querying the compiled object for the kernel function by name + if !find_attr!( + cx.tcx.get_all_attrs(id), + AttributeKind::NoMangle(..) | AttributeKind::ExportName { .. } + ) { + cx.emit_span_lint(MISSING_GPU_KERNEL_EXPORT_NAME, span, MissingGpuKernelExportName); + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 49929a0a9bc7..dd2042b57f52 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -47,6 +47,7 @@ mod expect; mod for_loops_over_fallibles; mod foreign_modules; mod function_cast_as_integer; +mod gpukernel_abi; mod if_let_rescope; mod impl_trait_overcaptures; mod interior_mutable_consts; @@ -93,6 +94,7 @@ use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; use function_cast_as_integer::*; +use gpukernel_abi::*; use if_let_rescope::IfLetRescope; use impl_trait_overcaptures::ImplTraitOvercaptures; use interior_mutable_consts::*; @@ -197,6 +199,7 @@ late_lint_methods!( DerefIntoDynSupertrait: DerefIntoDynSupertrait, DropForgetUseless: DropForgetUseless, ImproperCTypesLint: ImproperCTypesLint, + ImproperGpuKernelLint: ImproperGpuKernelLint, InvalidFromUtf8: InvalidFromUtf8, VariantSizeDifferences: VariantSizeDifferences, PathStatements: PathStatements, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 5017ce7caa52..ba486f95427d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2008,6 +2008,19 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { } } +#[derive(LintDiagnostic)] +#[diag(lint_improper_gpu_kernel_arg)] +#[help] +pub(crate) struct ImproperGpuKernelArg<'a> { + pub ty: Ty<'a>, +} + +#[derive(LintDiagnostic)] +#[diag(lint_missing_gpu_kernel_export_name)] +#[help] +#[note] +pub(crate) struct MissingGpuKernelExportName; + #[derive(LintDiagnostic)] #[diag(lint_variant_size_differences)] pub(crate) struct VariantSizeDifferencesDiag { diff --git a/tests/ui/abi/cannot-be-called.amdgpu.stderr b/tests/ui/abi/cannot-be-called.amdgpu.stderr new file mode 100644 index 000000000000..039e2d7b4f00 --- /dev/null +++ b/tests/ui/abi/cannot-be-called.amdgpu.stderr @@ -0,0 +1,87 @@ +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:43:8 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:45:8 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:47:8 + | +LL | extern "riscv-interrupt-m" fn riscv_m() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:49:8 + | +LL | extern "riscv-interrupt-s" fn riscv_s() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:51:8 + | +LL | extern "x86-interrupt" fn x86(_x: *const u8) {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:76:22 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:82:25 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:88:26 + | +LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:94:26 + | +LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:100:22 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.avr.stderr b/tests/ui/abi/cannot-be-called.avr.stderr index 2128991d83cd..752292a58705 100644 --- a/tests/ui/abi/cannot-be-called.avr.stderr +++ b/tests/ui/abi/cannot-be-called.avr.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "avr-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:53:5 + --> $DIR/cannot-be-called.rs:60:5 | LL | avr(); | ^^^^^ | note: an `extern "avr-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:53:5 + --> $DIR/cannot-be-called.rs:60:5 | LL | avr(); | ^^^^^ error: functions with the "avr-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:69:5 + --> $DIR/cannot-be-called.rs:78:5 | LL | f() | ^^^ | note: an `extern "avr-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:69:5 + --> $DIR/cannot-be-called.rs:78:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.i686.stderr b/tests/ui/abi/cannot-be-called.i686.stderr index 9b1755921aea..30e294ad61ec 100644 --- a/tests/ui/abi/cannot-be-called.i686.stderr +++ b/tests/ui/abi/cannot-be-called.i686.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.msp430.stderr b/tests/ui/abi/cannot-be-called.msp430.stderr index 9a047b11cf79..12ab88bc858b 100644 --- a/tests/ui/abi/cannot-be-called.msp430.stderr +++ b/tests/ui/abi/cannot-be-called.msp430.stderr @@ -1,75 +1,87 @@ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "msp430-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:55:5 + --> $DIR/cannot-be-called.rs:62:5 | LL | msp430(); | ^^^^^^^^ | note: an `extern "msp430-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:55:5 + --> $DIR/cannot-be-called.rs:62:5 | LL | msp430(); | ^^^^^^^^ error: functions with the "msp430-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:75:5 + --> $DIR/cannot-be-called.rs:84:5 | LL | f() | ^^^ | note: an `extern "msp430-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:75:5 + --> $DIR/cannot-be-called.rs:84:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.nvptx.stderr b/tests/ui/abi/cannot-be-called.nvptx.stderr new file mode 100644 index 000000000000..039e2d7b4f00 --- /dev/null +++ b/tests/ui/abi/cannot-be-called.nvptx.stderr @@ -0,0 +1,87 @@ +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:43:8 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:45:8 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:47:8 + | +LL | extern "riscv-interrupt-m" fn riscv_m() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:49:8 + | +LL | extern "riscv-interrupt-s" fn riscv_s() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:51:8 + | +LL | extern "x86-interrupt" fn x86(_x: *const u8) {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:76:22 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:82:25 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:88:26 + | +LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:94:26 + | +LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:100:22 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.riscv32.stderr b/tests/ui/abi/cannot-be-called.riscv32.stderr index 135b20c50d58..b1897b74ebbe 100644 --- a/tests/ui/abi/cannot-be-called.riscv32.stderr +++ b/tests/ui/abi/cannot-be-called.riscv32.stderr @@ -1,87 +1,99 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.riscv64.stderr b/tests/ui/abi/cannot-be-called.riscv64.stderr index 135b20c50d58..b1897b74ebbe 100644 --- a/tests/ui/abi/cannot-be-called.riscv64.stderr +++ b/tests/ui/abi/cannot-be-called.riscv64.stderr @@ -1,87 +1,99 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.rs b/tests/ui/abi/cannot-be-called.rs index 315ea1601633..8d1a4ae0b557 100644 --- a/tests/ui/abi/cannot-be-called.rs +++ b/tests/ui/abi/cannot-be-called.rs @@ -4,7 +4,7 @@ Interrupt ABIs share similar semantics, in that they are special entry-points un So we test that they error in essentially all of the same places. */ //@ add-minicore -//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 +//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 amdgpu nvptx // //@ [x64] needs-llvm-components: x86 //@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib @@ -20,6 +20,10 @@ So we test that they error in essentially all of the same places. //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 --crate-type=rlib +//@ [nvptx] needs-llvm-components: nvptx +//@ [nvptx] compile-flags: --target nvptx64-nvidia-cuda --crate-type=rlib //@ ignore-backends: gcc #![no_core] #![feature( @@ -27,7 +31,8 @@ So we test that they error in essentially all of the same places. abi_msp430_interrupt, abi_avr_interrupt, abi_x86_interrupt, - abi_riscv_interrupt + abi_riscv_interrupt, + abi_gpu_kernel )] extern crate minicore; @@ -36,15 +41,17 @@ use minicore::*; /* extern "interrupt" definition */ extern "msp430-interrupt" fn msp430() {} -//[x64,x64_win,i686,riscv32,riscv64,avr]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,riscv32,riscv64,avr,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "avr-interrupt" fn avr() {} -//[x64,x64_win,i686,riscv32,riscv64,msp430]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,riscv32,riscv64,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "riscv-interrupt-m" fn riscv_m() {} -//[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "riscv-interrupt-s" fn riscv_s() {} -//[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "x86-interrupt" fn x86(_x: *const u8) {} -//[riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI +//[riscv32,riscv64,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI +extern "gpu-kernel" fn gpu_kernel() {} +//[x64,x64_win,i686,riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI static BYTE: u8 = 0; @@ -60,36 +67,44 @@ fn call_the_interrupts() { //[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-s" ABI cannot be called x86(&raw const BYTE); //[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be called + gpu_kernel(); + //[amdgpu,nvptx]~^ ERROR functions with the "gpu-kernel" ABI cannot be called } /* extern "interrupt" fnptr calls */ fn avr_ptr(f: extern "avr-interrupt" fn()) { - //[x64,x64_win,i686,riscv32,riscv64,msp430]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,riscv32,riscv64,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[avr]~^ ERROR functions with the "avr-interrupt" ABI cannot be called } fn msp430_ptr(f: extern "msp430-interrupt" fn()) { - //[x64,x64_win,i686,riscv32,riscv64,avr]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,riscv32,riscv64,avr,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[msp430]~^ ERROR functions with the "msp430-interrupt" ABI cannot be called } fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { - //[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-m" ABI cannot be called } fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { - //[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-s" ABI cannot be called } fn x86_ptr(f: extern "x86-interrupt" fn()) { - //[riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI + //[riscv32,riscv64,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be called } + +fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + //[x64,x64_win,i686,riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI + f() + //[amdgpu,nvptx]~^ ERROR functions with the "gpu-kernel" ABI cannot be called +} diff --git a/tests/ui/abi/cannot-be-called.x64.stderr b/tests/ui/abi/cannot-be-called.x64.stderr index 9b1755921aea..30e294ad61ec 100644 --- a/tests/ui/abi/cannot-be-called.x64.stderr +++ b/tests/ui/abi/cannot-be-called.x64.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.x64_win.stderr b/tests/ui/abi/cannot-be-called.x64_win.stderr index 9b1755921aea..30e294ad61ec 100644 --- a/tests/ui/abi/cannot-be-called.x64_win.stderr +++ b/tests/ui/abi/cannot-be-called.x64_win.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-coroutine.amdgpu.stderr b/tests/ui/abi/cannot-be-coroutine.amdgpu.stderr new file mode 100644 index 000000000000..a36ea0caa19e --- /dev/null +++ b/tests/ui/abi/cannot-be-coroutine.amdgpu.stderr @@ -0,0 +1,23 @@ +error: functions with the "gpu-kernel" ABI cannot be `async` + --> $DIR/cannot-be-coroutine.rs:62:1 + | +LL | async extern "gpu-kernel" fn async_kernel() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `async` keyword from this definition + | +LL - async extern "gpu-kernel" fn async_kernel() { +LL + extern "gpu-kernel" fn async_kernel() { + | + +error: requires `ResumeTy` lang_item + --> $DIR/cannot-be-coroutine.rs:38:19 + | +LL | async fn vanilla(){ + | ___________________^ +LL | | +LL | | } + | |_^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/abi/cannot-be-coroutine.avr.stderr b/tests/ui/abi/cannot-be-coroutine.avr.stderr index 11bc93b1eef1..643a575bece1 100644 --- a/tests/ui/abi/cannot-be-coroutine.avr.stderr +++ b/tests/ui/abi/cannot-be-coroutine.avr.stderr @@ -1,5 +1,5 @@ error: functions with the "avr-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:37:1 + --> $DIR/cannot-be-coroutine.rs:42:1 | LL | async extern "avr-interrupt" fn avr() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "avr-interrupt" fn avr() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.i686.stderr b/tests/ui/abi/cannot-be-coroutine.i686.stderr index 4a344bb09020..f618507df47d 100644 --- a/tests/ui/abi/cannot-be-coroutine.i686.stderr +++ b/tests/ui/abi/cannot-be-coroutine.i686.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:53:1 + --> $DIR/cannot-be-coroutine.rs:58:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.msp430.stderr b/tests/ui/abi/cannot-be-coroutine.msp430.stderr index c2867705df78..f2586c8cd975 100644 --- a/tests/ui/abi/cannot-be-coroutine.msp430.stderr +++ b/tests/ui/abi/cannot-be-coroutine.msp430.stderr @@ -1,5 +1,5 @@ error: functions with the "msp430-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:41:1 + --> $DIR/cannot-be-coroutine.rs:46:1 | LL | async extern "msp430-interrupt" fn msp430() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "msp430-interrupt" fn msp430() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.nvptx.stderr b/tests/ui/abi/cannot-be-coroutine.nvptx.stderr new file mode 100644 index 000000000000..a36ea0caa19e --- /dev/null +++ b/tests/ui/abi/cannot-be-coroutine.nvptx.stderr @@ -0,0 +1,23 @@ +error: functions with the "gpu-kernel" ABI cannot be `async` + --> $DIR/cannot-be-coroutine.rs:62:1 + | +LL | async extern "gpu-kernel" fn async_kernel() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `async` keyword from this definition + | +LL - async extern "gpu-kernel" fn async_kernel() { +LL + extern "gpu-kernel" fn async_kernel() { + | + +error: requires `ResumeTy` lang_item + --> $DIR/cannot-be-coroutine.rs:38:19 + | +LL | async fn vanilla(){ + | ___________________^ +LL | | +LL | | } + | |_^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/abi/cannot-be-coroutine.riscv32.stderr b/tests/ui/abi/cannot-be-coroutine.riscv32.stderr index 398f888205df..c5a8c3f60a38 100644 --- a/tests/ui/abi/cannot-be-coroutine.riscv32.stderr +++ b/tests/ui/abi/cannot-be-coroutine.riscv32.stderr @@ -1,5 +1,5 @@ error: functions with the "riscv-interrupt-m" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:45:1 + --> $DIR/cannot-be-coroutine.rs:50:1 | LL | async extern "riscv-interrupt-m" fn riscv_m() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m() { | error: functions with the "riscv-interrupt-s" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:49:1 + --> $DIR/cannot-be-coroutine.rs:54:1 | LL | async extern "riscv-interrupt-s" fn riscv_s() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.riscv64.stderr b/tests/ui/abi/cannot-be-coroutine.riscv64.stderr index 398f888205df..c5a8c3f60a38 100644 --- a/tests/ui/abi/cannot-be-coroutine.riscv64.stderr +++ b/tests/ui/abi/cannot-be-coroutine.riscv64.stderr @@ -1,5 +1,5 @@ error: functions with the "riscv-interrupt-m" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:45:1 + --> $DIR/cannot-be-coroutine.rs:50:1 | LL | async extern "riscv-interrupt-m" fn riscv_m() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m() { | error: functions with the "riscv-interrupt-s" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:49:1 + --> $DIR/cannot-be-coroutine.rs:54:1 | LL | async extern "riscv-interrupt-s" fn riscv_s() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.rs b/tests/ui/abi/cannot-be-coroutine.rs index c070e8032e1a..239f5aa5c31f 100644 --- a/tests/ui/abi/cannot-be-coroutine.rs +++ b/tests/ui/abi/cannot-be-coroutine.rs @@ -1,6 +1,6 @@ //@ add-minicore //@ edition: 2021 -//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 +//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 amdgpu nvptx // //@ [x64] needs-llvm-components: x86 //@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib @@ -16,6 +16,10 @@ //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 --crate-type=rlib +//@ [nvptx] needs-llvm-components: nvptx +//@ [nvptx] compile-flags: --target nvptx64-nvidia-cuda --crate-type=rlib //@ ignore-backends: gcc #![no_core] #![feature( @@ -23,7 +27,8 @@ abi_msp430_interrupt, abi_avr_interrupt, abi_x86_interrupt, - abi_riscv_interrupt + abi_riscv_interrupt, + abi_gpu_kernel )] extern crate minicore; @@ -53,3 +58,7 @@ async extern "riscv-interrupt-s" fn riscv_s() { async extern "x86-interrupt" fn x86(_p: *mut ()) { //[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be `async` } + +async extern "gpu-kernel" fn async_kernel() { + //[amdgpu,nvptx]~^ ERROR functions with the "gpu-kernel" ABI cannot be `async` +} diff --git a/tests/ui/abi/cannot-be-coroutine.x64.stderr b/tests/ui/abi/cannot-be-coroutine.x64.stderr index 4a344bb09020..f618507df47d 100644 --- a/tests/ui/abi/cannot-be-coroutine.x64.stderr +++ b/tests/ui/abi/cannot-be-coroutine.x64.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:53:1 + --> $DIR/cannot-be-coroutine.rs:58:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr index 4a344bb09020..f618507df47d 100644 --- a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr +++ b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:53:1 + --> $DIR/cannot-be-coroutine.rs:58:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-return.amdgpu.stderr b/tests/ui/abi/cannot-return.amdgpu.stderr new file mode 100644 index 000000000000..f264907d00ec --- /dev/null +++ b/tests/ui/abi/cannot-return.amdgpu.stderr @@ -0,0 +1,15 @@ +error: invalid signature for `extern "gpu-kernel"` function + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + | + = note: functions with the "gpu-kernel" ABI cannot have a return type +help: remove the return type + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/cannot-return.nvptx.stderr b/tests/ui/abi/cannot-return.nvptx.stderr new file mode 100644 index 000000000000..f264907d00ec --- /dev/null +++ b/tests/ui/abi/cannot-return.nvptx.stderr @@ -0,0 +1,15 @@ +error: invalid signature for `extern "gpu-kernel"` function + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + | + = note: functions with the "gpu-kernel" ABI cannot have a return type +help: remove the return type + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/cannot-return.rs b/tests/ui/abi/cannot-return.rs new file mode 100644 index 000000000000..9a5db30431b9 --- /dev/null +++ b/tests/ui/abi/cannot-return.rs @@ -0,0 +1,18 @@ +//@ add-minicore +//@ ignore-backends: gcc +//@ edition: 2024 +//@ revisions: amdgpu nvptx +// +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 --crate-type=rlib +//@ [nvptx] needs-llvm-components: nvptx +//@ [nvptx] compile-flags: --target nvptx64-nvidia-cuda --crate-type=rlib +#![no_core] +#![feature(no_core, abi_gpu_kernel)] + +extern crate minicore; +use minicore::*; + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn ret_i32() -> i32 { 0 } +//~^ ERROR invalid signature for `extern "gpu-kernel"` function diff --git a/tests/ui/lint/lint-gpu-kernel.amdgpu.stderr b/tests/ui/lint/lint-gpu-kernel.amdgpu.stderr new file mode 100644 index 000000000000..21eebe42f8b1 --- /dev/null +++ b/tests/ui/lint/lint-gpu-kernel.amdgpu.stderr @@ -0,0 +1,86 @@ +warning: `extern` fn uses type `()`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + = note: `#[warn(improper_ctypes_definitions)]` on by default + +warning: passing type `()` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ + | + = help: use primitive types and raw pointers to get reliable behavior + = note: `#[warn(improper_gpu_kernel_arg)]` on by default + +warning: passing type `&i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:41:35 + | +LL | extern "gpu-kernel" fn arg_ref(_: &i32) { } + | ^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: passing type `&mut i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:44:39 + | +LL | extern "gpu-kernel" fn arg_ref_mut(_: &mut i32) { } + | ^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `S`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-gpu-kernel.rs:47:1 + | +LL | struct S { a: i32, b: i32 } + | ^^^^^^^^ + +warning: passing type `S` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `(i32, i32)`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + +warning: passing type `(i32, i32)` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: function with the "gpu-kernel" ABI has a mangled name + --> $DIR/lint-gpu-kernel.rs:61:1 + | +LL | pub extern "gpu-kernel" fn mangled_kernel() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `unsafe(no_mangle)` or `unsafe(export_name = "")` + = note: mangled names make it hard to find the kernel, this is usually not intended + = note: `#[warn(missing_gpu_kernel_export_name)]` on by default + +warning: 9 warnings emitted + diff --git a/tests/ui/lint/lint-gpu-kernel.nvptx.stderr b/tests/ui/lint/lint-gpu-kernel.nvptx.stderr new file mode 100644 index 000000000000..21eebe42f8b1 --- /dev/null +++ b/tests/ui/lint/lint-gpu-kernel.nvptx.stderr @@ -0,0 +1,86 @@ +warning: `extern` fn uses type `()`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + = note: `#[warn(improper_ctypes_definitions)]` on by default + +warning: passing type `()` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ + | + = help: use primitive types and raw pointers to get reliable behavior + = note: `#[warn(improper_gpu_kernel_arg)]` on by default + +warning: passing type `&i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:41:35 + | +LL | extern "gpu-kernel" fn arg_ref(_: &i32) { } + | ^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: passing type `&mut i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:44:39 + | +LL | extern "gpu-kernel" fn arg_ref_mut(_: &mut i32) { } + | ^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `S`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-gpu-kernel.rs:47:1 + | +LL | struct S { a: i32, b: i32 } + | ^^^^^^^^ + +warning: passing type `S` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `(i32, i32)`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + +warning: passing type `(i32, i32)` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: function with the "gpu-kernel" ABI has a mangled name + --> $DIR/lint-gpu-kernel.rs:61:1 + | +LL | pub extern "gpu-kernel" fn mangled_kernel() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `unsafe(no_mangle)` or `unsafe(export_name = "")` + = note: mangled names make it hard to find the kernel, this is usually not intended + = note: `#[warn(missing_gpu_kernel_export_name)]` on by default + +warning: 9 warnings emitted + diff --git a/tests/ui/lint/lint-gpu-kernel.rs b/tests/ui/lint/lint-gpu-kernel.rs new file mode 100644 index 000000000000..9b3ed0d14d8a --- /dev/null +++ b/tests/ui/lint/lint-gpu-kernel.rs @@ -0,0 +1,62 @@ +// Test argument and return type restrictions of the gpu-kernel ABI and +// check for warnings on mangled gpu-kernels. + +//@ check-pass +//@ ignore-backends: gcc +//@ revisions: amdgpu nvptx +//@ add-minicore +//@ edition: 2024 +//@[amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 +//@[amdgpu] needs-llvm-components: amdgpu +//@[nvptx] compile-flags: --target nvptx64-nvidia-cuda +//@[nvptx] needs-llvm-components: nvptx + +#![feature(no_core, abi_gpu_kernel)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +// Return types can be () or ! +#[unsafe(no_mangle)] +extern "gpu-kernel" fn ret_empty() {} +#[unsafe(no_mangle)] +extern "gpu-kernel" fn ret_never() -> ! { loop {} } + +// Arguments can be scalars or pointers +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_i32(_: i32) { } +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ptr(_: *const i32) { } +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ptr_mut(_: *mut i32) { } + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_zst(_: ()) { } +//~^ WARN passing type `()` to a function with "gpu-kernel" ABI may have unexpected behavior +//~^^ WARN `extern` fn uses type `()`, which is not FFI-safe + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ref(_: &i32) { } +//~^ WARN passing type `&i32` to a function with "gpu-kernel" ABI may have unexpected behavior +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ref_mut(_: &mut i32) { } +//~^ WARN passing type `&mut i32` to a function with "gpu-kernel" ABI may have unexpected behavior + +struct S { a: i32, b: i32 } +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_struct(_: S) { } +//~^ WARN passing type `S` to a function with "gpu-kernel" ABI may have unexpected behavior +//~^^ WARN `extern` fn uses type `S`, which is not FFI-safe + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } +//~^ WARN passing type `(i32, i32)` to a function with "gpu-kernel" ABI may have unexpected behavior +//~^^ WARN `extern` fn uses type `(i32, i32)`, which is not FFI-safe + +#[unsafe(export_name = "kernel")] +pub extern "gpu-kernel" fn allowed_kernel_name() {} + +pub extern "gpu-kernel" fn mangled_kernel() { } +//~^ WARN function with the "gpu-kernel" ABI has a mangled name From cde301fabc81b25b6ef54268139d93721448b118 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jan 2026 19:20:42 +0000 Subject: [PATCH 1462/3801] Bump qs from 6.14.0 to 6.14.1 in /editors/code Bumps [qs](https://github.com/ljharb/qs) from 6.14.0 to 6.14.1. - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](https://github.com/ljharb/qs/compare/v6.14.0...v6.14.1) --- updated-dependencies: - dependency-name: qs dependency-version: 6.14.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- src/tools/rust-analyzer/editors/code/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json index 00d83e906848..57f6bf69beb0 100644 --- a/src/tools/rust-analyzer/editors/code/package-lock.json +++ b/src/tools/rust-analyzer/editors/code/package-lock.json @@ -5584,9 +5584,9 @@ } }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { From cddda032d5b0c7d485a95f90f781568177d734e9 Mon Sep 17 00:00:00 2001 From: human9000 Date: Fri, 2 Jan 2026 00:48:29 +0500 Subject: [PATCH 1463/3801] test: modified bad-question-mark-on-trait-objects to match expected behaviour --- .../ui/try-trait/bad-question-mark-on-trait-object.rs | 1 - .../bad-question-mark-on-trait-object.stderr | 11 +++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/ui/try-trait/bad-question-mark-on-trait-object.rs b/tests/ui/try-trait/bad-question-mark-on-trait-object.rs index 2a0d14b17503..270ec2c532ac 100644 --- a/tests/ui/try-trait/bad-question-mark-on-trait-object.rs +++ b/tests/ui/try-trait/bad-question-mark-on-trait-object.rs @@ -1,6 +1,5 @@ struct E; //~^ NOTE `E` needs to implement `std::error::Error` -//~| NOTE alternatively, `E` needs to implement `Into` struct X; //~ NOTE `X` needs to implement `From` fn foo() -> Result<(), Box> { //~ NOTE required `E: std::error::Error` because of this diff --git a/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr b/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr index dd380850c9ec..7639489b891a 100644 --- a/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr +++ b/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr @@ -1,5 +1,5 @@ error[E0277]: `?` couldn't convert the error: `E: std::error::Error` is not satisfied - --> $DIR/bad-question-mark-on-trait-object.rs:7:13 + --> $DIR/bad-question-mark-on-trait-object.rs:6:13 | LL | fn foo() -> Result<(), Box> { | -------------------------------------- required `E: std::error::Error` because of this @@ -17,7 +17,7 @@ LL | struct E; = note: required for `Box` to implement `From` error[E0277]: `?` couldn't convert the error to `X` - --> $DIR/bad-question-mark-on-trait-object.rs:18:13 + --> $DIR/bad-question-mark-on-trait-object.rs:17:13 | LL | fn bat() -> Result<(), X> { | ------------- expected `X` because of this @@ -27,15 +27,10 @@ LL | Ok(bar()?) | this can't be annotated with `?` because it has type `Result<_, E>` | note: `X` needs to implement `From` - --> $DIR/bad-question-mark-on-trait-object.rs:4:1 + --> $DIR/bad-question-mark-on-trait-object.rs:3:1 | LL | struct X; | ^^^^^^^^ -note: alternatively, `E` needs to implement `Into` - --> $DIR/bad-question-mark-on-trait-object.rs:1:1 - | -LL | struct E; - | ^^^^^^^^ = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait error: aborting due to 2 previous errors From 97e5cabb9107d5285838fc1ce95665ade98db096 Mon Sep 17 00:00:00 2001 From: human9000 Date: Fri, 2 Jan 2026 00:50:05 +0500 Subject: [PATCH 1464/3801] removed confusing message from diagnostics --- .../src/error_reporting/traits/fulfillment_errors.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d96a1b0a8c0e..fc5209739f16 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1287,10 +1287,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx.def_span(def.did()), format!("`{self_ty}` needs to implement `From<{ty}>`"), ); - err.span_note( - self.tcx.def_span(found.did()), - format!("alternatively, `{ty}` needs to implement `Into<{self_ty}>`"), - ); } (ty::Adt(def, _), None) if def.did().is_local() => { let trait_path = self.tcx.short_string( From 48657cec85a38c0f1fade3eaf905b19bf23d356f Mon Sep 17 00:00:00 2001 From: Aliaksei Semianiuk Date: Fri, 2 Jan 2026 01:59:16 +0500 Subject: [PATCH 1465/3801] Update year --- COPYRIGHT | 2 +- LICENSE-APACHE | 2 +- LICENSE-MIT | 2 +- README.md | 2 +- clippy_utils/README.md | 2 +- rustc_tools_util/README.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index f402dcf465a3..5d3075903a01 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,6 +1,6 @@ // REUSE-IgnoreStart -Copyright 2014-2025 The Rust Project Developers +Copyright 2014-2026 The Rust Project Developers Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 9990a0cec474..6f6e5844208d 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work. same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright 2014-2025 The Rust Project Developers +Copyright 2014-2026 The Rust Project Developers Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/LICENSE-MIT b/LICENSE-MIT index 5d6e36ef6bfc..a51639bc0f9b 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2014-2025 The Rust Project Developers +Copyright (c) 2014-2026 The Rust Project Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/README.md b/README.md index 78498c73ae78..287dee82daaa 100644 --- a/README.md +++ b/README.md @@ -277,7 +277,7 @@ If you want to contribute to Clippy, you can find more information in [CONTRIBUT -Copyright 2014-2025 The Rust Project Developers +Copyright 2014-2026 The Rust Project Developers Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 01257c1a3059..e3ce95d30074 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -30,7 +30,7 @@ Function signatures can change or be removed without replacement without any pri -Copyright 2014-2025 The Rust Project Developers +Copyright 2014-2026 The Rust Project Developers Licensed under the Apache License, Version 2.0 <[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license diff --git a/rustc_tools_util/README.md b/rustc_tools_util/README.md index f47a4c69c2c3..083814e1e05d 100644 --- a/rustc_tools_util/README.md +++ b/rustc_tools_util/README.md @@ -51,7 +51,7 @@ The changelog for `rustc_tools_util` is available under: -Copyright 2014-2025 The Rust Project Developers +Copyright 2014-2026 The Rust Project Developers Licensed under the Apache License, Version 2.0 or the MIT license From 68ea14a27283bc5e55acbf81ae9dbe6a05506e79 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Thu, 1 Jan 2026 22:07:57 +0000 Subject: [PATCH 1466/3801] address review --- src/tools/tidy/src/extra_checks/mod.rs | 37 ++++++++++++-------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index bedcd08ca13f..2d654339e883 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -121,9 +121,7 @@ fn check_impl( ck.is_non_auto_or_matches(path) }); } - if lint_args.iter().any(|ck| ck.if_installed) { - lint_args.retain(|ck| ck.is_non_if_installed_or_matches(root_path, outdir)); - } + lint_args.retain(|ck| ck.is_non_if_installed_or_matches(root_path, outdir)); macro_rules! extra_check { ($lang:ident, $kind:ident) => { @@ -597,29 +595,26 @@ fn install_requirements( Ok(()) } +/// Returns `Ok` if shellcheck is installed, `Err` otherwise. fn has_shellcheck() -> Result<(), Error> { match Command::new("shellcheck").arg("--version").status() { Ok(_) => Ok(()), - Err(e) if e.kind() == io::ErrorKind::NotFound => { - return Err(Error::MissingReq( - "shellcheck", - "shell file checks", - Some( - "see \ - for installation instructions" - .to_owned(), - ), - )); - } - Err(e) => return Err(e.into()), + Err(e) if e.kind() == io::ErrorKind::NotFound => Err(Error::MissingReq( + "shellcheck", + "shell file checks", + Some( + "see \ + for installation instructions" + .to_owned(), + ), + )), + Err(e) => Err(e.into()), } } /// Check that shellcheck is installed then run it at the given path fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> { - if let Err(err) = has_shellcheck() { - return Err(err); - } + has_shellcheck()?; let status = Command::new("shellcheck").args(args).status()?; if status.success() { Ok(()) } else { Err(Error::FailedCheck("shellcheck")) } @@ -758,6 +753,7 @@ enum ExtraCheckParseError { } struct ExtraCheckArg { + /// Only run the check if files to check have been modified. auto: bool, /// Only run the check if the requisite software is already installed. if_installed: bool, @@ -798,8 +794,7 @@ impl ExtraCheckArg { && rustdoc_js::has_tool(build_dir, "es-check") && rustdoc_js::has_tool(build_dir, "tsc") } - // Unreachable. - Some(_) => false, + Some(_) => unreachable!("js shouldn't have other type of ExtraCheckKind"), } } ExtraCheckLang::Py | ExtraCheckLang::Cpp => { @@ -862,6 +857,8 @@ impl FromStr for ExtraCheckArg { let Some(mut first) = parts.next() else { return Err(ExtraCheckParseError::Empty); }; + // The loop allows users to specify `auto` and `if-installed` in any order. + // Both auto:if-installed: and if-installed:auto: are valid. loop { if !auto && first == "auto" { let Some(part) = parts.next() else { From 8ca47cd1fe50eb4d160d1ab801f159312a35c54a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 2 Jan 2026 09:29:26 +1100 Subject: [PATCH 1467/3801] Clarify `MoveData::init_loc_map`. Change the `SmallVec` size from 4 to 1, because that's sufficient in the vast majority of cases. (This doesn't affect performance in practice, so it's more of a code clarity change than a performance change.) --- compiler/rustc_mir_dataflow/src/move_paths/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 800d4e406cf0..8be7d210f8df 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -177,8 +177,9 @@ pub struct MoveData<'tcx> { pub rev_lookup: MovePathLookup<'tcx>, pub inits: IndexVec, /// Each Location `l` is mapped to the Inits that are effects - /// of executing the code at `l`. - pub init_loc_map: LocationMap>, + /// of executing the code at `l`. Only very rarely (e.g. inline asm) + /// is there more than one Init at any `l`. + pub init_loc_map: LocationMap>, pub init_path_map: IndexVec>, } From 6394373dccc7b4bc49617b03bd505ea0f75a57a7 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 2 Jan 2026 05:44:43 +0530 Subject: [PATCH 1468/3801] add nits --- src/tools/rust-analyzer/crates/load-cargo/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index dc75abe7ad8c..5aa96582e9f3 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -547,10 +547,8 @@ impl ProcMacroExpander for Expander { let name = source_root .path_for_file(&file) - .and_then(|path| path.clone().into_abs_path()) - .and_then(|path| { - path.as_path().file_name().map(|filename| filename.to_owned()) - }); + .and_then(|path| path.as_path()) + .and_then(|path| path.file_name().map(|filename| filename.to_owned())); Ok(SubResponse::LocalFileNameResult { name }) } From 3982d3e70648ce3769d40610d86e330e4456b0ce Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 19 Oct 2025 23:52:19 +0000 Subject: [PATCH 1469/3801] `Vec::push` in consts MVP --- library/alloc/src/alloc.rs | 259 ++++++++++++++---- library/alloc/src/collections/mod.rs | 23 +- library/alloc/src/lib.rs | 6 + library/alloc/src/raw_vec/mod.rs | 81 ++++-- library/alloc/src/vec/mod.rs | 33 ++- library/alloctests/lib.rs | 7 + library/alloctests/tests/lib.rs | 1 + library/alloctests/tests/vec.rs | 16 ++ library/core/src/alloc/mod.rs | 7 +- .../const-eval/heap/vec-not-made-global.rs | 5 + .../heap/vec-not-made-global.stderr | 10 + 11 files changed, 361 insertions(+), 87 deletions(-) create mode 100644 tests/ui/consts/const-eval/heap/vec-not-made-global.rs create mode 100644 tests/ui/consts/const-eval/heap/vec-not-made-global.stderr diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index c5f16f3708d7..ee40596c620f 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -5,8 +5,8 @@ #[stable(feature = "alloc_module", since = "1.28.0")] #[doc(inline)] pub use core::alloc::*; -use core::hint; use core::ptr::{self, NonNull}; +use core::{cmp, hint}; unsafe extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates @@ -182,7 +182,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { impl Global { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result, AllocError> { + fn alloc_impl_runtime(layout: Layout, zeroed: bool) -> Result, AllocError> { match layout.size() { 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), // SAFETY: `layout` is non-zero in size, @@ -194,10 +194,26 @@ impl Global { } } + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + fn deallocate_impl_runtime(ptr: NonNull, layout: Layout) { + if layout.size() != 0 { + // SAFETY: + // * We have checked that `layout` is non-zero in size. + // * The caller is obligated to provide a layout that "fits", and in this case, + // "fit" always means a layout that is equal to the original, because our + // `allocate()`, `grow()`, and `shrink()` implementations never returns a larger + // allocation than requested. + // * Other conditions must be upheld by the caller, as per `Allocator::deallocate()`'s + // safety documentation. + unsafe { dealloc(ptr.as_ptr(), layout) } + } + } + // SAFETY: Same as `Allocator::grow` #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - unsafe fn grow_impl( + fn grow_impl_runtime( &self, ptr: NonNull, old_layout: Layout, @@ -241,69 +257,16 @@ impl Global { }, } } -} -#[unstable(feature = "allocator_api", issue = "32838")] -unsafe impl Allocator for Global { + // SAFETY: Same as `Allocator::grow` #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - fn allocate(&self, layout: Layout) -> Result, AllocError> { - self.alloc_impl(layout, false) - } - - #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { - self.alloc_impl(layout, true) - } - - #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { - if layout.size() != 0 { - // SAFETY: - // * We have checked that `layout` is non-zero in size. - // * The caller is obligated to provide a layout that "fits", and in this case, - // "fit" always means a layout that is equal to the original, because our - // `allocate()`, `grow()`, and `shrink()` implementations never returns a larger - // allocation than requested. - // * Other conditions must be upheld by the caller, as per `Allocator::deallocate()`'s - // safety documentation. - unsafe { dealloc(ptr.as_ptr(), layout) } - } - } - - #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - unsafe fn grow( - &self, - ptr: NonNull, - old_layout: Layout, - new_layout: Layout, - ) -> Result, AllocError> { - // SAFETY: all conditions must be upheld by the caller - unsafe { self.grow_impl(ptr, old_layout, new_layout, false) } - } - - #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - unsafe fn grow_zeroed( - &self, - ptr: NonNull, - old_layout: Layout, - new_layout: Layout, - ) -> Result, AllocError> { - // SAFETY: all conditions must be upheld by the caller - unsafe { self.grow_impl(ptr, old_layout, new_layout, true) } - } - - #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - unsafe fn shrink( + fn shrink_impl_runtime( &self, ptr: NonNull, old_layout: Layout, new_layout: Layout, + _zeroed: bool, ) -> Result, AllocError> { debug_assert!( new_layout.size() <= old_layout.size(), @@ -340,6 +303,184 @@ unsafe impl Allocator for Global { }, } } + + // SAFETY: Same as `Allocator::allocate` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result, AllocError> { + core::intrinsics::const_eval_select( + (layout, zeroed), + Global::alloc_impl_const, + Global::alloc_impl_runtime, + ) + } + + // SAFETY: Same as `Allocator::deallocate` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const unsafe fn deallocate_impl(&self, ptr: NonNull, layout: Layout) { + core::intrinsics::const_eval_select( + (ptr, layout), + Global::deallocate_impl_const, + Global::deallocate_impl_runtime, + ) + } + + // SAFETY: Same as `Allocator::grow` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const unsafe fn grow_impl( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + zeroed: bool, + ) -> Result, AllocError> { + core::intrinsics::const_eval_select( + (self, ptr, old_layout, new_layout, zeroed), + Global::grow_shrink_impl_const, + Global::grow_impl_runtime, + ) + } + + // SAFETY: Same as `Allocator::shrink` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const unsafe fn shrink_impl( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + core::intrinsics::const_eval_select( + (self, ptr, old_layout, new_layout, false), + Global::grow_shrink_impl_const, + Global::shrink_impl_runtime, + ) + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const fn alloc_impl_const(layout: Layout, zeroed: bool) -> Result, AllocError> { + match layout.size() { + 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), + // SAFETY: `layout` is non-zero in size, + size => unsafe { + let raw_ptr = core::intrinsics::const_allocate(layout.size(), layout.align()); + let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; + if zeroed { + let mut offset = 0; + while offset < size { + offset += 1; + // SAFETY: the pointer returned by `const_allocate` is valid to write to. + ptr.add(offset).write(0) + } + } + Ok(NonNull::slice_from_raw_parts(ptr, size)) + }, + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const fn deallocate_impl_const(ptr: NonNull, layout: Layout) { + if layout.size() != 0 { + // SAFETY: We checked for nonzero size; other preconditions must be upheld by caller. + unsafe { + core::intrinsics::const_deallocate(ptr.as_ptr(), layout.size(), layout.align()); + } + } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const fn grow_shrink_impl_const( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + zeroed: bool, + ) -> Result, AllocError> { + let new_ptr = self.alloc_impl(new_layout, zeroed)?; + // SAFETY: both pointers are valid and this operations is in bounds. + unsafe { + ptr::copy_nonoverlapping( + ptr.as_ptr(), + new_ptr.as_mut_ptr(), + cmp::min(old_layout.size(), new_layout.size()), + ); + } + unsafe { + self.deallocate_impl(ptr, old_layout); + } + Ok(new_ptr) + } +} + +#[unstable(feature = "allocator_api", issue = "32838")] +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +unsafe impl const Allocator for Global { + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + fn allocate(&self, layout: Layout) -> Result, AllocError> { + self.alloc_impl(layout, false) + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { + self.alloc_impl(layout, true) + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + // SAFETY: all conditions must be upheld by the caller + unsafe { self.deallocate_impl(ptr, layout) } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn grow( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: all conditions must be upheld by the caller + unsafe { self.grow_impl(ptr, old_layout, new_layout, false) } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn grow_zeroed( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: all conditions must be upheld by the caller + unsafe { self.grow_impl(ptr, old_layout, new_layout, true) } + } + + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + unsafe fn shrink( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + // SAFETY: all conditions must be upheld by the caller + unsafe { self.shrink_impl(ptr, old_layout, new_layout) } + } } /// The allocator for `Box`. diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs index 212d7c8465b6..e09326759fd1 100644 --- a/library/alloc/src/collections/mod.rs +++ b/library/alloc/src/collections/mod.rs @@ -84,13 +84,14 @@ impl TryReserveError { reason = "Uncertain how much info should be exposed", issue = "48043" )] - pub fn kind(&self) -> TryReserveErrorKind { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub const fn kind(&self) -> TryReserveErrorKind { self.kind.clone() } } /// Details of the allocation that caused a `TryReserveError` -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(PartialEq, Eq, Debug)] #[unstable( feature = "try_reserve_kind", reason = "Uncertain how much info should be exposed", @@ -120,6 +121,24 @@ pub enum TryReserveErrorKind { }, } +#[unstable( + feature = "try_reserve_kind", + reason = "Uncertain how much info should be exposed", + issue = "48043" +)] +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +#[cfg(not(test))] +impl const Clone for TryReserveErrorKind { + fn clone(&self) -> Self { + match self { + TryReserveErrorKind::CapacityOverflow => TryReserveErrorKind::CapacityOverflow, + TryReserveErrorKind::AllocError { layout, non_exhaustive: () } => { + TryReserveErrorKind::AllocError { layout: *layout, non_exhaustive: () } + } + } + } +} + #[cfg(test)] pub use realalloc::collections::TryReserveErrorKind; diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index b659e904c8a0..1aee92424602 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -101,11 +101,16 @@ #![feature(char_internals)] #![feature(clone_to_uninit)] #![feature(coerce_unsized)] +#![feature(const_clone)] +#![feature(const_cmp)] #![feature(const_convert)] #![feature(const_default)] +#![feature(const_destruct)] #![feature(const_eval_select)] #![feature(const_heap)] #![feature(copied_into_inner)] +#![feature(const_option_ops)] +#![feature(const_try)] #![feature(core_intrinsics)] #![feature(deprecated_suggestion)] #![feature(deref_pure_trait)] @@ -171,6 +176,7 @@ #![feature(const_trait_impl)] #![feature(coroutine_trait)] #![feature(decl_macro)] +#![feature(derive_const)] #![feature(dropck_eyepatch)] #![feature(fundamental)] #![feature(hashmap_internals)] diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index 15b0823df9ec..4994f01047d0 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -4,7 +4,7 @@ // Note: This module is also included in the alloctests crate using #[path] to // run the tests. See the comment there for an explanation why this is the case. -use core::marker::PhantomData; +use core::marker::{Destruct, PhantomData}; use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties}; use core::ptr::{self, Alignment, NonNull, Unique}; use core::{cmp, hint}; @@ -24,7 +24,7 @@ mod tests; // only one location which panics rather than a bunch throughout the module. #[cfg(not(no_global_oom_handling))] #[cfg_attr(not(panic = "immediate-abort"), inline(never))] -fn capacity_overflow() -> ! { +const fn capacity_overflow() -> ! { panic!("capacity overflow"); } @@ -182,7 +182,11 @@ impl RawVec { /// allocator for the returned `RawVec`. #[cfg(not(no_global_oom_handling))] #[inline] - pub(crate) fn with_capacity_in(capacity: usize, alloc: A) -> Self { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub(crate) const fn with_capacity_in(capacity: usize, alloc: A) -> Self + where + A: [const] Allocator + [const] Destruct, + { Self { inner: RawVecInner::with_capacity_in(capacity, alloc, T::LAYOUT), _marker: PhantomData, @@ -331,7 +335,11 @@ impl RawVec { /// caller to ensure `len == self.capacity()`. #[cfg(not(no_global_oom_handling))] #[inline(never)] - pub(crate) fn grow_one(&mut self) { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub(crate) const fn grow_one(&mut self) + where + A: [const] Allocator, + { // SAFETY: All calls on self.inner pass T::LAYOUT as the elem_layout unsafe { self.inner.grow_one(T::LAYOUT) } } @@ -415,7 +423,11 @@ impl RawVecInner
    { #[cfg(not(no_global_oom_handling))] #[inline] - fn with_capacity_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const fn with_capacity_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self + where + A: [const] Allocator + [const] Destruct, + { match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) { Ok(this) => { unsafe { @@ -446,12 +458,16 @@ impl RawVecInner { } } - fn try_allocate_in( + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const fn try_allocate_in( capacity: usize, init: AllocInit, alloc: A, elem_layout: Layout, - ) -> Result { + ) -> Result + where + A: [const] Allocator + [const] Destruct, + { // We avoid `unwrap_or_else` here because it bloats the amount of // LLVM IR generated. let layout = match layout_array(capacity, elem_layout) { @@ -519,7 +535,8 @@ impl RawVecInner { /// initially construct `self` /// - `elem_layout`'s size must be a multiple of its alignment #[inline] - unsafe fn current_memory(&self, elem_layout: Layout) -> Option<(NonNull, Layout)> { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const unsafe fn current_memory(&self, elem_layout: Layout) -> Option<(NonNull, Layout)> { if elem_layout.size() == 0 || self.cap.as_inner() == 0 { None } else { @@ -572,7 +589,11 @@ impl RawVecInner { /// - `elem_layout`'s size must be a multiple of its alignment #[cfg(not(no_global_oom_handling))] #[inline] - unsafe fn grow_one(&mut self, elem_layout: Layout) { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const unsafe fn grow_one(&mut self, elem_layout: Layout) + where + A: [const] Allocator, + { // SAFETY: Precondition passed to caller if let Err(err) = unsafe { self.grow_amortized(self.cap.as_inner(), 1, elem_layout) } { handle_error(err); @@ -651,12 +672,13 @@ impl RawVecInner { } #[inline] - fn needs_to_grow(&self, len: usize, additional: usize, elem_layout: Layout) -> bool { + const fn needs_to_grow(&self, len: usize, additional: usize, elem_layout: Layout) -> bool { additional > self.capacity(elem_layout.size()).wrapping_sub(len) } #[inline] - unsafe fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const unsafe fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) { // Allocators currently return a `NonNull<[u8]>` whose length matches // the size requested. If that ever changes, the capacity here should // change to `ptr.len() / size_of::()`. @@ -669,12 +691,16 @@ impl RawVecInner { /// initially construct `self` /// - `elem_layout`'s size must be a multiple of its alignment /// - The sum of `len` and `additional` must be greater than the current capacity - unsafe fn grow_amortized( + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const unsafe fn grow_amortized( &mut self, len: usize, additional: usize, elem_layout: Layout, - ) -> Result<(), TryReserveError> { + ) -> Result<(), TryReserveError> + where + A: [const] Allocator, + { // This is ensured by the calling contexts. debug_assert!(additional > 0); @@ -737,15 +763,20 @@ impl RawVecInner { // not marked inline(never) since we want optimizers to be able to observe the specifics of this // function, see tests/codegen-llvm/vec-reserve-extend.rs. #[cold] - unsafe fn finish_grow( + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + const unsafe fn finish_grow( &self, cap: usize, elem_layout: Layout, - ) -> Result, TryReserveError> { + ) -> Result, TryReserveError> + where + A: [const] Allocator, + { let new_layout = layout_array(cap, elem_layout)?; let memory = if let Some((ptr, old_layout)) = unsafe { self.current_memory(elem_layout) } { - debug_assert_eq!(old_layout.align(), new_layout.align()); + // FIXME(const-hack): switch to `debug_assert_eq` + debug_assert!(old_layout.align() == new_layout.align()); unsafe { // The allocator checks for alignment equality hint::assert_unchecked(old_layout.align() == new_layout.align()); @@ -755,7 +786,11 @@ impl RawVecInner { self.alloc.allocate(new_layout) }; - memory.map_err(|_| AllocError { layout: new_layout, non_exhaustive: () }.into()) + // FIXME(const-hack): switch back to `map_err` + match memory { + Ok(memory) => Ok(memory), + Err(_) => Err(AllocError { layout: new_layout, non_exhaustive: () }.into()), + } } /// # Safety @@ -839,7 +874,8 @@ impl RawVecInner { #[cfg(not(no_global_oom_handling))] #[cold] #[optimize(size)] -fn handle_error(e: TryReserveError) -> ! { +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +const fn handle_error(e: TryReserveError) -> ! { match e.kind() { CapacityOverflow => capacity_overflow(), AllocError { layout, .. } => handle_alloc_error(layout), @@ -847,6 +883,11 @@ fn handle_error(e: TryReserveError) -> ! { } #[inline] -fn layout_array(cap: usize, elem_layout: Layout) -> Result { - elem_layout.repeat(cap).map(|(layout, _pad)| layout).map_err(|_| CapacityOverflow.into()) +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +const fn layout_array(cap: usize, elem_layout: Layout) -> Result { + // FIXME(const-hack) return to using `map` and `map_err` once `const_closures` is implemented + match elem_layout.repeat(cap) { + Ok((layout, _pad)) => Ok(layout), + Err(_) => Err(CapacityOverflow.into()), + } } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index f8a96e358d6d..10a34d17730f 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -81,6 +81,8 @@ use core::cmp::Ordering; use core::hash::{Hash, Hasher}; #[cfg(not(no_global_oom_handling))] use core::iter; +#[cfg(not(no_global_oom_handling))] +use core::marker::Destruct; use core::marker::PhantomData; use core::mem::{self, Assume, ManuallyDrop, MaybeUninit, SizedTypeProperties, TransmuteFrom}; use core::ops::{self, Index, IndexMut, Range, RangeBounds}; @@ -519,7 +521,8 @@ impl Vec { #[stable(feature = "rust1", since = "1.0.0")] #[must_use] #[rustc_diagnostic_item = "vec_with_capacity"] - pub fn with_capacity(capacity: usize) -> Self { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub const fn with_capacity(capacity: usize) -> Self { Self::with_capacity_in(capacity, Global) } @@ -881,6 +884,16 @@ impl Vec { // SAFETY: A `Vec` always has a non-null pointer. (unsafe { NonNull::new_unchecked(ptr) }, len, capacity) } + + /// Leaks the `Vec` to be interned statically. This mut be done for all + /// `Vec` created during compile time. + #[unstable(feature = "const_heap", issue = "79597")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub const fn const_leak(mut self) -> &'static [T] { + unsafe { core::intrinsics::const_make_global(self.as_mut_ptr().cast()) }; + let me = ManuallyDrop::new(self); + unsafe { slice::from_raw_parts(me.as_ptr(), me.len) } + } } impl Vec { @@ -962,7 +975,11 @@ impl Vec { #[cfg(not(no_global_oom_handling))] #[inline] #[unstable(feature = "allocator_api", issue = "32838")] - pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub const fn with_capacity_in(capacity: usize, alloc: A) -> Self + where + A: [const] Allocator + [const] Destruct, + { Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 } } @@ -2575,7 +2592,11 @@ impl Vec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_confusables("push_back", "put", "append")] - pub fn push(&mut self, value: T) { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub const fn push(&mut self, value: T) + where + A: [const] Allocator, + { let _ = self.push_mut(value); } @@ -2664,7 +2685,11 @@ impl Vec { #[inline] #[unstable(feature = "push_mut", issue = "135974")] #[must_use = "if you don't need a reference to the value, use `Vec::push` instead"] - pub fn push_mut(&mut self, value: T) -> &mut T { + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub const fn push_mut(&mut self, value: T) -> &mut T + where + A: [const] Allocator, + { // Inform codegen that the length does not change across grow_one(). let len = self.len; // This will panic or abort if we would allocate > isize::MAX bytes diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index cd02c0a53857..b85fc8eb9970 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -20,6 +20,13 @@ #![feature(assert_matches)] #![feature(box_vec_non_null)] #![feature(char_internals)] +#![feature(const_alloc_error)] +#![feature(const_cmp)] +#![feature(const_convert)] +#![feature(const_destruct)] +#![feature(const_heap)] +#![feature(const_option_ops)] +#![feature(const_try)] #![feature(copied_into_inner)] #![feature(core_intrinsics)] #![feature(exact_size_is_empty)] diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 34c65bf787c8..db01cebe5b27 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -1,5 +1,6 @@ #![feature(allocator_api)] #![feature(alloc_layout_extra)] +#![feature(const_heap)] #![feature(deque_extend_front)] #![feature(iter_array_chunks)] #![feature(assert_matches)] diff --git a/library/alloctests/tests/vec.rs b/library/alloctests/tests/vec.rs index cd5b14f6eff3..a7997cd060d3 100644 --- a/library/alloctests/tests/vec.rs +++ b/library/alloctests/tests/vec.rs @@ -2749,3 +2749,19 @@ fn zst_collections_iter_nth_back_regression() { list.push_back(Thing); let _ = list.into_iter().nth_back(1); } + +#[test] +fn const_heap() { + const X: &'static [u32] = { + let mut v = Vec::with_capacity(6); + let mut x = 1; + while x < 42 { + v.push(x); + x *= 2; + } + assert!(v.len() == 6); + v.const_leak() + }; + + assert_eq!([1, 2, 4, 8, 16, 32], X); +} diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 680b1ec105a2..ef1abcaf639a 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -102,6 +102,8 @@ impl fmt::Display for AllocError { /// /// [*currently allocated*]: #currently-allocated-memory #[unstable(feature = "allocator_api", issue = "32838")] +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +#[const_trait] pub unsafe trait Allocator { /// Attempts to allocate a block of memory. /// @@ -368,9 +370,10 @@ pub unsafe trait Allocator { } #[unstable(feature = "allocator_api", issue = "32838")] -unsafe impl Allocator for &A +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +unsafe impl const Allocator for &A where - A: Allocator + ?Sized, + A: [const] Allocator + ?Sized, { #[inline] fn allocate(&self, layout: Layout) -> Result, AllocError> { diff --git a/tests/ui/consts/const-eval/heap/vec-not-made-global.rs b/tests/ui/consts/const-eval/heap/vec-not-made-global.rs new file mode 100644 index 000000000000..4f78e977e4d5 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/vec-not-made-global.rs @@ -0,0 +1,5 @@ +#![feature(const_heap)] +const V: Vec = Vec::with_capacity(1); +//~^ ERROR: encountered `const_allocate` pointer in final value that was not made global + +fn main() {} diff --git a/tests/ui/consts/const-eval/heap/vec-not-made-global.stderr b/tests/ui/consts/const-eval/heap/vec-not-made-global.stderr new file mode 100644 index 000000000000..595cbeb8df26 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/vec-not-made-global.stderr @@ -0,0 +1,10 @@ +error: encountered `const_allocate` pointer in final value that was not made global + --> $DIR/vec-not-made-global.rs:2:1 + | +LL | const V: Vec = Vec::with_capacity(1); + | ^^^^^^^^^^^^^^^^^ + | + = note: use `const_make_global` to turn allocated pointers into immutable globals before returning + +error: aborting due to 1 previous error + From 47864e80cb4b873c1c3090be9923bfdf90148962 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 26 Oct 2025 18:42:13 +0000 Subject: [PATCH 1470/3801] address review comments; fix CI --- library/alloc/src/alloc.rs | 8 ++--- library/alloc/src/lib.rs | 1 + library/alloc/src/vec/mod.rs | 14 +++++--- library/alloctests/tests/vec.rs | 2 +- .../item-collection/opaque-return-impls.rs | 2 +- ...ce.PreCodegen.after.32bit.panic-unwind.mir | 26 ++++++++------ ...ce.PreCodegen.after.64bit.panic-unwind.mir | 26 ++++++++------ ..._constant.main.GVN.32bit.panic-unwind.diff | 36 +++++++++---------- ..._constant.main.GVN.64bit.panic-unwind.diff | 36 +++++++++---------- 9 files changed, 77 insertions(+), 74 deletions(-) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index ee40596c620f..5dd828bd54e1 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -374,12 +374,8 @@ impl Global { let raw_ptr = core::intrinsics::const_allocate(layout.size(), layout.align()); let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; if zeroed { - let mut offset = 0; - while offset < size { - offset += 1; - // SAFETY: the pointer returned by `const_allocate` is valid to write to. - ptr.add(offset).write(0) - } + // SAFETY: the pointer returned by `const_allocate` is valid to write to. + ptr.write_bytes(0, size); } Ok(NonNull::slice_from_raw_parts(ptr, size)) }, diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 1aee92424602..f15dfc9b5de7 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -124,6 +124,7 @@ #![feature(fmt_internals)] #![feature(fn_traits)] #![feature(formatting_options)] +#![feature(freeze)] #![feature(generic_atomic)] #![feature(hasher_prefixfree_extras)] #![feature(inplace_iteration)] diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 10a34d17730f..29e83113d489 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -83,7 +83,7 @@ use core::hash::{Hash, Hasher}; use core::iter; #[cfg(not(no_global_oom_handling))] use core::marker::Destruct; -use core::marker::PhantomData; +use core::marker::{Freeze, PhantomData}; use core::mem::{self, Assume, ManuallyDrop, MaybeUninit, SizedTypeProperties, TransmuteFrom}; use core::ops::{self, Index, IndexMut, Range, RangeBounds}; use core::ptr::{self, NonNull}; @@ -885,11 +885,17 @@ impl Vec { (unsafe { NonNull::new_unchecked(ptr) }, len, capacity) } - /// Leaks the `Vec` to be interned statically. This mut be done for all - /// `Vec` created during compile time. + /// Interns the `Vec`, making the underlying memory read-only. This method should be + /// called during compile time. (This is a no-op if called during runtime) + /// + /// This method must be called if the memory used by `Vec` needs to appear in the final + /// values of constants. #[unstable(feature = "const_heap", issue = "79597")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub const fn const_leak(mut self) -> &'static [T] { + pub const fn const_make_global(mut self) -> &'static [T] + where + T: Freeze, + { unsafe { core::intrinsics::const_make_global(self.as_mut_ptr().cast()) }; let me = ManuallyDrop::new(self); unsafe { slice::from_raw_parts(me.as_ptr(), me.len) } diff --git a/library/alloctests/tests/vec.rs b/library/alloctests/tests/vec.rs index a7997cd060d3..c8f9504ae14e 100644 --- a/library/alloctests/tests/vec.rs +++ b/library/alloctests/tests/vec.rs @@ -2760,7 +2760,7 @@ fn const_heap() { x *= 2; } assert!(v.len() == 6); - v.const_leak() + v.const_make_global() }; assert_eq!([1, 2, 4, 8, 16, 32], X); diff --git a/tests/codegen-units/item-collection/opaque-return-impls.rs b/tests/codegen-units/item-collection/opaque-return-impls.rs index d54951b933fd..54ab656c53db 100644 --- a/tests/codegen-units/item-collection/opaque-return-impls.rs +++ b/tests/codegen-units/item-collection/opaque-return-impls.rs @@ -44,7 +44,7 @@ pub fn foo2() -> Box { //~ MONO_ITEM fn ::test_func2 //~ MONO_ITEM fn alloc::alloc::exchange_malloc //~ MONO_ITEM fn foo2 -//~ MONO_ITEM fn std::alloc::Global::alloc_impl +//~ MONO_ITEM fn std::alloc::Global::alloc_impl_runtime //~ MONO_ITEM fn std::boxed::Box::::new //~ MONO_ITEM fn std::alloc::Layout::from_size_align_unchecked::precondition_check //~ MONO_ITEM fn std::ptr::Alignment::new_unchecked::precondition_check diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir index 791d6b71a6f7..013361d1d2fb 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir @@ -25,17 +25,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } scope 18 (inlined ::deallocate) { - let mut _9: *mut u8; - scope 19 (inlined Layout::size) { - } - scope 20 (inlined NonNull::::as_ptr) { - } - scope 21 (inlined std::alloc::dealloc) { - let mut _10: usize; - scope 22 (inlined Layout::size) { - } - scope 23 (inlined Layout::align) { - scope 24 (inlined std::ptr::Alignment::as_usize) { + scope 19 (inlined std::alloc::Global::deallocate_impl) { + scope 20 (inlined std::alloc::Global::deallocate_impl_runtime) { + let mut _9: *mut u8; + scope 21 (inlined Layout::size) { + } + scope 22 (inlined NonNull::::as_ptr) { + } + scope 23 (inlined std::alloc::dealloc) { + let mut _10: usize; + scope 24 (inlined Layout::size) { + } + scope 25 (inlined Layout::align) { + scope 26 (inlined std::ptr::Alignment::as_usize) { + } + } } } } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir index 791d6b71a6f7..013361d1d2fb 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir @@ -25,17 +25,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } scope 18 (inlined ::deallocate) { - let mut _9: *mut u8; - scope 19 (inlined Layout::size) { - } - scope 20 (inlined NonNull::::as_ptr) { - } - scope 21 (inlined std::alloc::dealloc) { - let mut _10: usize; - scope 22 (inlined Layout::size) { - } - scope 23 (inlined Layout::align) { - scope 24 (inlined std::ptr::Alignment::as_usize) { + scope 19 (inlined std::alloc::Global::deallocate_impl) { + scope 20 (inlined std::alloc::Global::deallocate_impl_runtime) { + let mut _9: *mut u8; + scope 21 (inlined Layout::size) { + } + scope 22 (inlined NonNull::::as_ptr) { + } + scope 23 (inlined std::alloc::dealloc) { + let mut _10: usize; + scope 24 (inlined Layout::size) { + } + scope 25 (inlined Layout::align) { + scope 26 (inlined std::ptr::Alignment::as_usize) { + } + } } } } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff index 15a9d9e39c49..485ff902a7b9 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff @@ -9,22 +9,22 @@ let mut _4: *mut [u8]; let mut _5: std::ptr::NonNull<[u8]>; let mut _6: std::result::Result, std::alloc::AllocError>; - let mut _7: &std::alloc::Global; - let mut _8: std::alloc::Layout; + let mut _7: std::alloc::Layout; scope 1 { debug layout => _1; - let mut _9: &std::alloc::Global; scope 2 { debug ptr => _3; } scope 5 (inlined ::allocate) { + scope 6 (inlined std::alloc::Global::alloc_impl) { + } } - scope 6 (inlined NonNull::<[u8]>::as_ptr) { + scope 7 (inlined NonNull::<[u8]>::as_ptr) { } } scope 3 (inlined #[track_caller] Option::::unwrap) { - let mut _10: isize; - let mut _11: !; + let mut _8: isize; + let mut _9: !; scope 4 { } } @@ -35,10 +35,10 @@ StorageLive(_2); - _2 = Option::::None; + _2 = const Option::::None; - StorageLive(_10); -- _10 = discriminant(_2); -- switchInt(move _10) -> [0: bb3, 1: bb4, otherwise: bb2]; -+ _10 = const 0_isize; + StorageLive(_8); +- _8 = discriminant(_2); +- switchInt(move _8) -> [0: bb3, 1: bb4, otherwise: bb2]; ++ _8 = const 0_isize; + switchInt(const 0_isize) -> [0: bb3, 1: bb4, otherwise: bb2]; } @@ -59,30 +59,26 @@ } bb3: { - _11 = option::unwrap_failed() -> unwind continue; + _9 = option::unwrap_failed() -> unwind continue; } bb4: { - _1 = move ((_2 as Some).0: std::alloc::Layout); + _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; - StorageDead(_10); + StorageDead(_8); StorageDead(_2); StorageLive(_3); StorageLive(_4); StorageLive(_5); StorageLive(_6); StorageLive(_7); - _9 = const main::promoted[0]; - _7 = copy _9; - StorageLive(_8); -- _8 = copy _1; -- _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb5, unwind continue]; -+ _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; -+ _6 = std::alloc::Global::alloc_impl(copy _9, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue]; +- _7 = copy _1; +- _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb5, unwind continue]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_8); StorageDead(_7); _5 = Result::, std::alloc::AllocError>::unwrap(move _6) -> [return: bb1, unwind continue]; } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff index df008ececae3..beee899dafe6 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff @@ -9,22 +9,22 @@ let mut _4: *mut [u8]; let mut _5: std::ptr::NonNull<[u8]>; let mut _6: std::result::Result, std::alloc::AllocError>; - let mut _7: &std::alloc::Global; - let mut _8: std::alloc::Layout; + let mut _7: std::alloc::Layout; scope 1 { debug layout => _1; - let mut _9: &std::alloc::Global; scope 2 { debug ptr => _3; } scope 5 (inlined ::allocate) { + scope 6 (inlined std::alloc::Global::alloc_impl) { + } } - scope 6 (inlined NonNull::<[u8]>::as_ptr) { + scope 7 (inlined NonNull::<[u8]>::as_ptr) { } } scope 3 (inlined #[track_caller] Option::::unwrap) { - let mut _10: isize; - let mut _11: !; + let mut _8: isize; + let mut _9: !; scope 4 { } } @@ -35,10 +35,10 @@ StorageLive(_2); - _2 = Option::::None; + _2 = const Option::::None; - StorageLive(_10); -- _10 = discriminant(_2); -- switchInt(move _10) -> [0: bb3, 1: bb4, otherwise: bb2]; -+ _10 = const 0_isize; + StorageLive(_8); +- _8 = discriminant(_2); +- switchInt(move _8) -> [0: bb3, 1: bb4, otherwise: bb2]; ++ _8 = const 0_isize; + switchInt(const 0_isize) -> [0: bb3, 1: bb4, otherwise: bb2]; } @@ -59,30 +59,26 @@ } bb3: { - _11 = option::unwrap_failed() -> unwind continue; + _9 = option::unwrap_failed() -> unwind continue; } bb4: { - _1 = move ((_2 as Some).0: std::alloc::Layout); + _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; - StorageDead(_10); + StorageDead(_8); StorageDead(_2); StorageLive(_3); StorageLive(_4); StorageLive(_5); StorageLive(_6); StorageLive(_7); - _9 = const main::promoted[0]; - _7 = copy _9; - StorageLive(_8); -- _8 = copy _1; -- _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb5, unwind continue]; -+ _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; -+ _6 = std::alloc::Global::alloc_impl(copy _9, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue]; +- _7 = copy _1; +- _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb5, unwind continue]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_8); StorageDead(_7); _5 = Result::, std::alloc::AllocError>::unwrap(move _6) -> [return: bb1, unwind continue]; } From cf61cbcb07a000ab0303baa601ea5a21f35bccda Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 21 Nov 2025 23:01:26 +0000 Subject: [PATCH 1471/3801] Move into `const impl` blocks --- library/alloc/src/raw_vec/mod.rs | 306 +++++++++++++++---------------- library/alloc/src/vec/mod.rs | 215 +++++++++++----------- library/core/src/alloc/mod.rs | 3 +- 3 files changed, 255 insertions(+), 269 deletions(-) diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index 4994f01047d0..c92deb06903d 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -165,6 +165,32 @@ const fn min_non_zero_cap(size: usize) -> usize { } } +const impl RawVec { + /// Like `with_capacity`, but parameterized over the choice of + /// allocator for the returned `RawVec`. + #[cfg(not(no_global_oom_handling))] + #[inline] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub(crate) fn with_capacity_in(capacity: usize, alloc: A) -> Self + { + Self { + inner: RawVecInner::with_capacity_in(capacity, alloc, T::LAYOUT), + _marker: PhantomData, + } + } + + /// A specialized version of `self.reserve(len, 1)` which requires the + /// caller to ensure `len == self.capacity()`. + #[cfg(not(no_global_oom_handling))] + #[inline(never)] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub(crate) fn grow_one(&mut self) + { + // SAFETY: All calls on self.inner pass T::LAYOUT as the elem_layout + unsafe { self.inner.grow_one(T::LAYOUT) } + } +} + impl RawVec { #[cfg(not(no_global_oom_handling))] pub(crate) const MIN_NON_ZERO_CAP: usize = min_non_zero_cap(size_of::()); @@ -178,21 +204,6 @@ impl RawVec { Self { inner: RawVecInner::new_in(alloc, Alignment::of::()), _marker: PhantomData } } - /// Like `with_capacity`, but parameterized over the choice of - /// allocator for the returned `RawVec`. - #[cfg(not(no_global_oom_handling))] - #[inline] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub(crate) const fn with_capacity_in(capacity: usize, alloc: A) -> Self - where - A: [const] Allocator + [const] Destruct, - { - Self { - inner: RawVecInner::with_capacity_in(capacity, alloc, T::LAYOUT), - _marker: PhantomData, - } - } - /// Like `try_with_capacity`, but parameterized over the choice of /// allocator for the returned `RawVec`. #[inline] @@ -331,19 +342,6 @@ impl RawVec { unsafe { self.inner.reserve(len, additional, T::LAYOUT) } } - /// A specialized version of `self.reserve(len, 1)` which requires the - /// caller to ensure `len == self.capacity()`. - #[cfg(not(no_global_oom_handling))] - #[inline(never)] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub(crate) const fn grow_one(&mut self) - where - A: [const] Allocator, - { - // SAFETY: All calls on self.inner pass T::LAYOUT as the elem_layout - unsafe { self.inner.grow_one(T::LAYOUT) } - } - /// The same as `reserve`, but returns on errors instead of panicking or aborting. pub(crate) fn try_reserve( &mut self, @@ -413,20 +411,11 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec { } } -impl RawVecInner { - #[inline] - const fn new_in(alloc: A, align: Alignment) -> Self { - let ptr = Unique::from_non_null(NonNull::without_provenance(align.as_nonzero())); - // `cap: 0` means "unallocated". zero-sized types are ignored. - Self { ptr, cap: ZERO_CAP, alloc } - } - +const impl RawVecInner { #[cfg(not(no_global_oom_handling))] #[inline] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - const fn with_capacity_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self - where - A: [const] Allocator + [const] Destruct, + fn with_capacity_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self { match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) { Ok(this) => { @@ -439,34 +428,13 @@ impl RawVecInner { Err(err) => handle_error(err), } } - - #[inline] - fn try_with_capacity_in( - capacity: usize, - alloc: A, - elem_layout: Layout, - ) -> Result { - Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) - } - - #[cfg(not(no_global_oom_handling))] - #[inline] - fn with_capacity_zeroed_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self { - match Self::try_allocate_in(capacity, AllocInit::Zeroed, alloc, elem_layout) { - Ok(res) => res, - Err(err) => handle_error(err), - } - } - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - const fn try_allocate_in( + fn try_allocate_in( capacity: usize, init: AllocInit, alloc: A, elem_layout: Layout, ) -> Result - where - A: [const] Allocator + [const] Destruct, { // We avoid `unwrap_or_else` here because it bloats the amount of // LLVM IR generated. @@ -500,6 +468,125 @@ impl RawVecInner { }) } + /// # Safety + /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to + /// initially construct `self` + /// - `elem_layout`'s size must be a multiple of its alignment + #[cfg(not(no_global_oom_handling))] + #[inline] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + unsafe fn grow_one(&mut self, elem_layout: Layout) + { + // SAFETY: Precondition passed to caller + if let Err(err) = unsafe { self.grow_amortized(self.cap.as_inner(), 1, elem_layout) } { + handle_error(err); + } + } + + + /// # Safety + /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to + /// initially construct `self` + /// - `elem_layout`'s size must be a multiple of its alignment + /// - The sum of `len` and `additional` must be greater than the current capacity + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + unsafe fn grow_amortized( + &mut self, + len: usize, + additional: usize, + elem_layout: Layout, + ) -> Result<(), TryReserveError> + { + // This is ensured by the calling contexts. + debug_assert!(additional > 0); + + if elem_layout.size() == 0 { + // Since we return a capacity of `usize::MAX` when `elem_size` is + // 0, getting to here necessarily means the `RawVec` is overfull. + return Err(CapacityOverflow.into()); + } + + // Nothing we can really do about these checks, sadly. + let required_cap = len.checked_add(additional).ok_or(CapacityOverflow)?; + + // This guarantees exponential growth. The doubling cannot overflow + // because `cap <= isize::MAX` and the type of `cap` is `usize`. + let cap = cmp::max(self.cap.as_inner() * 2, required_cap); + let cap = cmp::max(min_non_zero_cap(elem_layout.size()), cap); + + // SAFETY: + // - cap >= len + additional + // - other preconditions passed to caller + let ptr = unsafe { self.finish_grow(cap, elem_layout)? }; + + // SAFETY: `finish_grow` would have failed if `cap > isize::MAX` + unsafe { self.set_ptr_and_cap(ptr, cap) }; + Ok(()) + } + + /// # Safety + /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to + /// initially construct `self` + /// - `elem_layout`'s size must be a multiple of its alignment + /// - `cap` must be greater than the current capacity + // not marked inline(never) since we want optimizers to be able to observe the specifics of this + // function, see tests/codegen-llvm/vec-reserve-extend.rs. + #[cold] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + unsafe fn finish_grow( + &self, + cap: usize, + elem_layout: Layout, + ) -> Result, TryReserveError> + { + let new_layout = layout_array(cap, elem_layout)?; + + let memory = if let Some((ptr, old_layout)) = unsafe { self.current_memory(elem_layout) } { + // FIXME(const-hack): switch to `debug_assert_eq` + debug_assert!(old_layout.align() == new_layout.align()); + unsafe { + // The allocator checks for alignment equality + hint::assert_unchecked(old_layout.align() == new_layout.align()); + self.alloc.grow(ptr, old_layout, new_layout) + } + } else { + self.alloc.allocate(new_layout) + }; + + // FIXME(const-hack): switch back to `map_err` + match memory { + Ok(memory) => Ok(memory), + Err(_) => Err(AllocError { layout: new_layout, non_exhaustive: () }.into()), + } + } +} + +impl RawVecInner { + #[inline] + const fn new_in(alloc: A, align: Alignment) -> Self { + let ptr = Unique::from_non_null(NonNull::without_provenance(align.as_nonzero())); + // `cap: 0` means "unallocated". zero-sized types are ignored. + Self { ptr, cap: ZERO_CAP, alloc } + } + + #[inline] + fn try_with_capacity_in( + capacity: usize, + alloc: A, + elem_layout: Layout, + ) -> Result { + Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) + } + + #[cfg(not(no_global_oom_handling))] + #[inline] + fn with_capacity_zeroed_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self { + match Self::try_allocate_in(capacity, AllocInit::Zeroed, alloc, elem_layout) { + Ok(res) => res, + Err(err) => handle_error(err), + } + } + #[inline] unsafe fn from_raw_parts_in(ptr: *mut u8, cap: Cap, alloc: A) -> Self { Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap, alloc } @@ -583,23 +670,6 @@ impl RawVecInner { } } - /// # Safety - /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to - /// initially construct `self` - /// - `elem_layout`'s size must be a multiple of its alignment - #[cfg(not(no_global_oom_handling))] - #[inline] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - const unsafe fn grow_one(&mut self, elem_layout: Layout) - where - A: [const] Allocator, - { - // SAFETY: Precondition passed to caller - if let Err(err) = unsafe { self.grow_amortized(self.cap.as_inner(), 1, elem_layout) } { - handle_error(err); - } - } - /// # Safety /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to /// initially construct `self` @@ -686,48 +756,6 @@ impl RawVecInner { self.cap = unsafe { Cap::new_unchecked(cap) }; } - /// # Safety - /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to - /// initially construct `self` - /// - `elem_layout`'s size must be a multiple of its alignment - /// - The sum of `len` and `additional` must be greater than the current capacity - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - const unsafe fn grow_amortized( - &mut self, - len: usize, - additional: usize, - elem_layout: Layout, - ) -> Result<(), TryReserveError> - where - A: [const] Allocator, - { - // This is ensured by the calling contexts. - debug_assert!(additional > 0); - - if elem_layout.size() == 0 { - // Since we return a capacity of `usize::MAX` when `elem_size` is - // 0, getting to here necessarily means the `RawVec` is overfull. - return Err(CapacityOverflow.into()); - } - - // Nothing we can really do about these checks, sadly. - let required_cap = len.checked_add(additional).ok_or(CapacityOverflow)?; - - // This guarantees exponential growth. The doubling cannot overflow - // because `cap <= isize::MAX` and the type of `cap` is `usize`. - let cap = cmp::max(self.cap.as_inner() * 2, required_cap); - let cap = cmp::max(min_non_zero_cap(elem_layout.size()), cap); - - // SAFETY: - // - cap >= len + additional - // - other preconditions passed to caller - let ptr = unsafe { self.finish_grow(cap, elem_layout)? }; - - // SAFETY: `finish_grow` would have failed if `cap > isize::MAX` - unsafe { self.set_ptr_and_cap(ptr, cap) }; - Ok(()) - } - /// # Safety /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to /// initially construct `self` @@ -755,44 +783,6 @@ impl RawVecInner { Ok(()) } - /// # Safety - /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to - /// initially construct `self` - /// - `elem_layout`'s size must be a multiple of its alignment - /// - `cap` must be greater than the current capacity - // not marked inline(never) since we want optimizers to be able to observe the specifics of this - // function, see tests/codegen-llvm/vec-reserve-extend.rs. - #[cold] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - const unsafe fn finish_grow( - &self, - cap: usize, - elem_layout: Layout, - ) -> Result, TryReserveError> - where - A: [const] Allocator, - { - let new_layout = layout_array(cap, elem_layout)?; - - let memory = if let Some((ptr, old_layout)) = unsafe { self.current_memory(elem_layout) } { - // FIXME(const-hack): switch to `debug_assert_eq` - debug_assert!(old_layout.align() == new_layout.align()); - unsafe { - // The allocator checks for alignment equality - hint::assert_unchecked(old_layout.align() == new_layout.align()); - self.alloc.grow(ptr, old_layout, new_layout) - } - } else { - self.alloc.allocate(new_layout) - }; - - // FIXME(const-hack): switch back to `map_err` - match memory { - Ok(memory) => Ok(memory), - Err(_) => Err(AllocError { layout: new_layout, non_exhaustive: () }.into()), - } - } - /// # Safety /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to /// initially construct `self` diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 29e83113d489..e3aa4785b4f5 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -902,27 +902,7 @@ impl Vec { } } -impl Vec { - /// Constructs a new, empty `Vec`. - /// - /// The vector will not allocate until elements are pushed onto it. - /// - /// # Examples - /// - /// ``` - /// #![feature(allocator_api)] - /// - /// use std::alloc::System; - /// - /// # #[allow(unused_mut)] - /// let mut vec: Vec = Vec::new_in(System); - /// ``` - #[inline] - #[unstable(feature = "allocator_api", issue = "32838")] - pub const fn new_in(alloc: A) -> Self { - Vec { buf: RawVec::new_in(alloc), len: 0 } - } - +const impl Vec { /// Constructs a new, empty `Vec` with at least the specified capacity /// with the provided allocator. /// @@ -982,13 +962,115 @@ impl Vec { #[inline] #[unstable(feature = "allocator_api", issue = "32838")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub const fn with_capacity_in(capacity: usize, alloc: A) -> Self - where - A: [const] Allocator + [const] Destruct, + pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 } } + + /// Appends an element to the back of a collection. + /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Examples + /// + /// ``` + /// let mut vec = vec![1, 2]; + /// vec.push(3); + /// assert_eq!(vec, [1, 2, 3]); + /// ``` + /// + /// # Time complexity + /// + /// Takes amortized *O*(1) time. If the vector's length would exceed its + /// capacity after the push, *O*(*capacity*) time is taken to copy the + /// vector's elements to a larger allocation. This expensive operation is + /// offset by the *capacity* *O*(1) insertions it allows. + #[cfg(not(no_global_oom_handling))] + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_confusables("push_back", "put", "append")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub fn push(&mut self, value: T) + { + let _ = self.push_mut(value); + } + + /// Appends an element to the back of a collection, returning a reference to it. + /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Examples + /// + /// ``` + /// #![feature(push_mut)] + /// + /// + /// let mut vec = vec![1, 2]; + /// let last = vec.push_mut(3); + /// assert_eq!(*last, 3); + /// assert_eq!(vec, [1, 2, 3]); + /// + /// let last = vec.push_mut(3); + /// *last += 1; + /// assert_eq!(vec, [1, 2, 3, 4]); + /// ``` + /// + /// # Time complexity + /// + /// Takes amortized *O*(1) time. If the vector's length would exceed its + /// capacity after the push, *O*(*capacity*) time is taken to copy the + /// vector's elements to a larger allocation. This expensive operation is + /// offset by the *capacity* *O*(1) insertions it allows. + #[cfg(not(no_global_oom_handling))] + #[inline] + #[unstable(feature = "push_mut", issue = "135974")] + #[must_use = "if you don't need a reference to the value, use `Vec::push` instead"] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + pub fn push_mut(&mut self, value: T) -> &mut T + { + // Inform codegen that the length does not change across grow_one(). + let len = self.len; + // This will panic or abort if we would allocate > isize::MAX bytes + // or if the length increment would overflow for zero-sized types. + if len == self.buf.capacity() { + self.buf.grow_one(); + } + unsafe { + let end = self.as_mut_ptr().add(len); + ptr::write(end, value); + self.len = len + 1; + // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference. + &mut *end + } + } +} + +impl Vec { + /// Constructs a new, empty `Vec`. + /// + /// The vector will not allocate until elements are pushed onto it. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// + /// # #[allow(unused_mut)] + /// let mut vec: Vec = Vec::new_in(System); + /// ``` + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub const fn new_in(alloc: A) -> Self { + Vec { buf: RawVec::new_in(alloc), len: 0 } + } + /// Constructs a new, empty `Vec` with at least the specified capacity /// with the provided allocator. /// @@ -2574,38 +2656,6 @@ impl Vec { } } - /// Appends an element to the back of a collection. - /// - /// # Panics - /// - /// Panics if the new capacity exceeds `isize::MAX` _bytes_. - /// - /// # Examples - /// - /// ``` - /// let mut vec = vec![1, 2]; - /// vec.push(3); - /// assert_eq!(vec, [1, 2, 3]); - /// ``` - /// - /// # Time complexity - /// - /// Takes amortized *O*(1) time. If the vector's length would exceed its - /// capacity after the push, *O*(*capacity*) time is taken to copy the - /// vector's elements to a larger allocation. This expensive operation is - /// offset by the *capacity* *O*(1) insertions it allows. - #[cfg(not(no_global_oom_handling))] - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_confusables("push_back", "put", "append")] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub const fn push(&mut self, value: T) - where - A: [const] Allocator, - { - let _ = self.push_mut(value); - } - /// Appends an element and returns a reference to it if there is sufficient spare capacity, /// otherwise an error is returned with the element. /// @@ -2659,59 +2709,6 @@ impl Vec { } } - /// Appends an element to the back of a collection, returning a reference to it. - /// - /// # Panics - /// - /// Panics if the new capacity exceeds `isize::MAX` _bytes_. - /// - /// # Examples - /// - /// ``` - /// #![feature(push_mut)] - /// - /// - /// let mut vec = vec![1, 2]; - /// let last = vec.push_mut(3); - /// assert_eq!(*last, 3); - /// assert_eq!(vec, [1, 2, 3]); - /// - /// let last = vec.push_mut(3); - /// *last += 1; - /// assert_eq!(vec, [1, 2, 3, 4]); - /// ``` - /// - /// # Time complexity - /// - /// Takes amortized *O*(1) time. If the vector's length would exceed its - /// capacity after the push, *O*(*capacity*) time is taken to copy the - /// vector's elements to a larger allocation. This expensive operation is - /// offset by the *capacity* *O*(1) insertions it allows. - #[cfg(not(no_global_oom_handling))] - #[inline] - #[unstable(feature = "push_mut", issue = "135974")] - #[must_use = "if you don't need a reference to the value, use `Vec::push` instead"] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub const fn push_mut(&mut self, value: T) -> &mut T - where - A: [const] Allocator, - { - // Inform codegen that the length does not change across grow_one(). - let len = self.len; - // This will panic or abort if we would allocate > isize::MAX bytes - // or if the length increment would overflow for zero-sized types. - if len == self.buf.capacity() { - self.buf.grow_one(); - } - unsafe { - let end = self.as_mut_ptr().add(len); - ptr::write(end, value); - self.len = len + 1; - // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference. - &mut *end - } - } - /// Removes the last element from a vector and returns it, or [`None`] if it /// is empty. /// diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index ef1abcaf639a..959407b75348 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -103,8 +103,7 @@ impl fmt::Display for AllocError { /// [*currently allocated*]: #currently-allocated-memory #[unstable(feature = "allocator_api", issue = "32838")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] -#[const_trait] -pub unsafe trait Allocator { +pub const unsafe trait Allocator { /// Attempts to allocate a block of memory. /// /// On success, returns a [`NonNull<[u8]>`][NonNull] meeting the size and alignment guarantees of `layout`. From a913065d80129fa501ee9309fb753378d2f5f3d3 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 21 Dec 2025 14:11:40 -0500 Subject: [PATCH 1472/3801] fix rustfmt and bless tidy/tests --- library/alloc/src/lib.rs | 2 +- library/alloc/src/raw_vec/mod.rs | 34 ++++----- library/alloc/src/vec/mod.rs | 19 ++--- ...ng_operand.test.GVN.32bit.panic-abort.diff | 22 +++--- ...ace.PreCodegen.after.32bit.panic-abort.mir | 26 ++++--- ...d_constant.main.GVN.32bit.panic-abort.diff | 72 +++++++++---------- 6 files changed, 80 insertions(+), 95 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index f15dfc9b5de7..06133ce056df 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -108,9 +108,9 @@ #![feature(const_destruct)] #![feature(const_eval_select)] #![feature(const_heap)] -#![feature(copied_into_inner)] #![feature(const_option_ops)] #![feature(const_try)] +#![feature(copied_into_inner)] #![feature(core_intrinsics)] #![feature(deprecated_suggestion)] #![feature(deref_pure_trait)] diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index c92deb06903d..1e76710d3536 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -165,14 +165,14 @@ const fn min_non_zero_cap(size: usize) -> usize { } } +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +#[rustfmt::skip] // FIXME(fee1-dead): temporary measure before rustfmt is bumped const impl RawVec { /// Like `with_capacity`, but parameterized over the choice of /// allocator for the returned `RawVec`. #[cfg(not(no_global_oom_handling))] #[inline] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub(crate) fn with_capacity_in(capacity: usize, alloc: A) -> Self - { + pub(crate) fn with_capacity_in(capacity: usize, alloc: A) -> Self { Self { inner: RawVecInner::with_capacity_in(capacity, alloc, T::LAYOUT), _marker: PhantomData, @@ -183,9 +183,7 @@ const impl RawVec { /// caller to ensure `len == self.capacity()`. #[cfg(not(no_global_oom_handling))] #[inline(never)] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub(crate) fn grow_one(&mut self) - { + pub(crate) fn grow_one(&mut self) { // SAFETY: All calls on self.inner pass T::LAYOUT as the elem_layout unsafe { self.inner.grow_one(T::LAYOUT) } } @@ -411,12 +409,12 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec { } } +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +#[rustfmt::skip] // FIXME(fee1-dead): temporary measure before rustfmt is bumped const impl RawVecInner { #[cfg(not(no_global_oom_handling))] #[inline] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - fn with_capacity_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self - { + fn with_capacity_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self { match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) { Ok(this) => { unsafe { @@ -428,14 +426,13 @@ const impl RawVecInner { Err(err) => handle_error(err), } } - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] + fn try_allocate_in( capacity: usize, init: AllocInit, alloc: A, elem_layout: Layout, - ) -> Result - { + ) -> Result { // We avoid `unwrap_or_else` here because it bloats the amount of // LLVM IR generated. let layout = match layout_array(capacity, elem_layout) { @@ -474,29 +471,24 @@ const impl RawVecInner { /// - `elem_layout`'s size must be a multiple of its alignment #[cfg(not(no_global_oom_handling))] #[inline] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - unsafe fn grow_one(&mut self, elem_layout: Layout) - { + unsafe fn grow_one(&mut self, elem_layout: Layout) { // SAFETY: Precondition passed to caller if let Err(err) = unsafe { self.grow_amortized(self.cap.as_inner(), 1, elem_layout) } { handle_error(err); } } - /// # Safety /// - `elem_layout` must be valid for `self`, i.e. it must be the same `elem_layout` used to /// initially construct `self` /// - `elem_layout`'s size must be a multiple of its alignment /// - The sum of `len` and `additional` must be greater than the current capacity - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] unsafe fn grow_amortized( &mut self, len: usize, additional: usize, elem_layout: Layout, - ) -> Result<(), TryReserveError> - { + ) -> Result<(), TryReserveError> { // This is ensured by the calling contexts. debug_assert!(additional > 0); @@ -532,13 +524,11 @@ const impl RawVecInner { // not marked inline(never) since we want optimizers to be able to observe the specifics of this // function, see tests/codegen-llvm/vec-reserve-extend.rs. #[cold] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] unsafe fn finish_grow( &self, cap: usize, elem_layout: Layout, - ) -> Result, TryReserveError> - { + ) -> Result, TryReserveError> { let new_layout = layout_array(cap, elem_layout)?; let memory = if let Some((ptr, old_layout)) = unsafe { self.current_memory(elem_layout) } { diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index e3aa4785b4f5..5a9887f1de55 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -902,6 +902,9 @@ impl Vec { } } +#[cfg(not(no_global_oom_handling))] +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +#[rustfmt::skip] // FIXME(fee1-dead): temporary measure before rustfmt is bumped const impl Vec { /// Constructs a new, empty `Vec` with at least the specified capacity /// with the provided allocator. @@ -958,16 +961,12 @@ const impl Vec { /// let vec_units = Vec::<(), System>::with_capacity_in(10, System); /// assert_eq!(vec_units.capacity(), usize::MAX); /// ``` - #[cfg(not(no_global_oom_handling))] #[inline] #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub fn with_capacity_in(capacity: usize, alloc: A) -> Self - { + pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 } } - /// Appends an element to the back of a collection. /// /// # Panics @@ -988,13 +987,10 @@ const impl Vec { /// capacity after the push, *O*(*capacity*) time is taken to copy the /// vector's elements to a larger allocation. This expensive operation is /// offset by the *capacity* *O*(1) insertions it allows. - #[cfg(not(no_global_oom_handling))] #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_confusables("push_back", "put", "append")] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub fn push(&mut self, value: T) - { + pub fn push(&mut self, value: T) { let _ = self.push_mut(value); } @@ -1026,13 +1022,10 @@ const impl Vec { /// capacity after the push, *O*(*capacity*) time is taken to copy the /// vector's elements to a larger allocation. This expensive operation is /// offset by the *capacity* *O*(1) insertions it allows. - #[cfg(not(no_global_oom_handling))] #[inline] #[unstable(feature = "push_mut", issue = "135974")] #[must_use = "if you don't need a reference to the value, use `Vec::push` instead"] - #[rustc_const_unstable(feature = "const_heap", issue = "79597")] - pub fn push_mut(&mut self, value: T) -> &mut T - { + pub fn push_mut(&mut self, value: T) -> &mut T { // Inform codegen that the length does not change across grow_one(). let len = self.len; // This will panic or abort if we would allocate > isize::MAX bytes diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index 2aa92fd34ebf..bcf0ad7c165f 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -26,12 +26,12 @@ scope 4 { debug _x => _8; } - scope 18 (inlined foo) { + scope 19 (inlined foo) { let mut _27: *const [()]; } } - scope 16 (inlined slice_from_raw_parts::<()>) { - scope 17 (inlined std::ptr::from_raw_parts::<[()], ()>) { + scope 17 (inlined slice_from_raw_parts::<()>) { + scope 18 (inlined std::ptr::from_raw_parts::<[()], ()>) { } } } @@ -49,19 +49,21 @@ scope 7 { let _21: std::ptr::NonNull<[u8]>; scope 8 { - scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) { - scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) { - scope 13 (inlined NonNull::<[u8]>::cast::) { + scope 12 (inlined NonNull::<[u8]>::as_mut_ptr) { + scope 13 (inlined NonNull::<[u8]>::as_non_null_ptr) { + scope 14 (inlined NonNull::<[u8]>::cast::) { let mut _25: *mut [u8]; - scope 14 (inlined NonNull::<[u8]>::as_ptr) { + scope 15 (inlined NonNull::<[u8]>::as_ptr) { } } } - scope 15 (inlined NonNull::::as_ptr) { + scope 16 (inlined NonNull::::as_ptr) { } } } scope 10 (inlined ::allocate) { + scope 11 (inlined std::alloc::Global::alloc_impl) { + } } } scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) { @@ -192,8 +194,8 @@ + _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; StorageDead(_24); StorageLive(_19); -- _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _18, const false) -> [return: bb7, unwind unreachable]; -+ _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; +- _19 = std::alloc::Global::alloc_impl_runtime(copy _18, const false) -> [return: bb7, unwind unreachable]; ++ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; } bb7: { diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir index 791d6b71a6f7..013361d1d2fb 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir @@ -25,17 +25,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } scope 18 (inlined ::deallocate) { - let mut _9: *mut u8; - scope 19 (inlined Layout::size) { - } - scope 20 (inlined NonNull::::as_ptr) { - } - scope 21 (inlined std::alloc::dealloc) { - let mut _10: usize; - scope 22 (inlined Layout::size) { - } - scope 23 (inlined Layout::align) { - scope 24 (inlined std::ptr::Alignment::as_usize) { + scope 19 (inlined std::alloc::Global::deallocate_impl) { + scope 20 (inlined std::alloc::Global::deallocate_impl_runtime) { + let mut _9: *mut u8; + scope 21 (inlined Layout::size) { + } + scope 22 (inlined NonNull::::as_ptr) { + } + scope 23 (inlined std::alloc::dealloc) { + let mut _10: usize; + scope 24 (inlined Layout::size) { + } + scope 25 (inlined Layout::align) { + scope 26 (inlined std::ptr::Alignment::as_usize) { + } + } } } } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff index 3f854b6cbcfb..d0fda06c115c 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff @@ -9,33 +9,33 @@ let mut _4: *mut [u8]; let mut _5: std::ptr::NonNull<[u8]>; let mut _6: std::result::Result, std::alloc::AllocError>; - let mut _7: &std::alloc::Global; - let mut _8: std::alloc::Layout; + let mut _7: std::alloc::Layout; scope 1 { debug layout => _1; - let mut _9: &std::alloc::Global; scope 2 { debug ptr => _3; } scope 5 (inlined ::allocate) { - } - scope 6 (inlined #[track_caller] Result::, std::alloc::AllocError>::unwrap) { - let mut _12: isize; - let _13: std::alloc::AllocError; - let mut _14: !; - let mut _15: &dyn std::fmt::Debug; - let _16: &std::alloc::AllocError; - scope 7 { + scope 6 (inlined std::alloc::Global::alloc_impl) { } + } + scope 7 (inlined #[track_caller] Result::, std::alloc::AllocError>::unwrap) { + let mut _10: isize; + let _11: std::alloc::AllocError; + let mut _12: !; + let mut _13: &dyn std::fmt::Debug; + let _14: &std::alloc::AllocError; scope 8 { } + scope 9 { + } } - scope 9 (inlined NonNull::<[u8]>::as_ptr) { + scope 10 (inlined NonNull::<[u8]>::as_ptr) { } } scope 3 (inlined #[track_caller] Option::::unwrap) { - let mut _10: isize; - let mut _11: !; + let mut _8: isize; + let mut _9: !; scope 4 { } } @@ -46,10 +46,10 @@ StorageLive(_2); - _2 = Option::::None; + _2 = const Option::::None; - StorageLive(_10); -- _10 = discriminant(_2); -- switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb1]; -+ _10 = const 0_isize; + StorageLive(_8); +- _8 = discriminant(_2); +- switchInt(move _8) -> [0: bb2, 1: bb3, otherwise: bb1]; ++ _8 = const 0_isize; + switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb1]; } @@ -58,48 +58,44 @@ } bb2: { - _11 = option::unwrap_failed() -> unwind unreachable; + _9 = option::unwrap_failed() -> unwind unreachable; } bb3: { - _1 = move ((_2 as Some).0: std::alloc::Layout); + _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; - StorageDead(_10); + StorageDead(_8); StorageDead(_2); StorageLive(_3); StorageLive(_4); StorageLive(_5); StorageLive(_6); StorageLive(_7); - _9 = const main::promoted[0]; - _7 = copy _9; - StorageLive(_8); -- _8 = copy _1; -- _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind unreachable]; -+ _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; -+ _6 = std::alloc::Global::alloc_impl(copy _9, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable]; +- _7 = copy _1; +- _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_8); StorageDead(_7); - StorageLive(_12); - StorageLive(_16); - _12 = discriminant(_6); - switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1]; + StorageLive(_10); + StorageLive(_14); + _10 = discriminant(_6); + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb1]; } bb5: { - StorageLive(_15); - _16 = &_13; - _15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit)); - _14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable; + StorageLive(_13); + _14 = &_11; + _13 = copy _14 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit)); + _12 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _13) -> unwind unreachable; } bb6: { _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>); - StorageDead(_16); - StorageDead(_12); + StorageDead(_14); + StorageDead(_10); StorageDead(_6); _4 = copy _5 as *mut [u8] (Transmute); StorageDead(_5); From 6417c8faaedca073da26585187f911946d094d7c Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sun, 28 Dec 2025 22:26:15 +0000 Subject: [PATCH 1473/3801] Extend `needless_collect` to also cover `extend` --- clippy_lints/src/methods/needless_collect.rs | 89 +++++++++++++++----- tests/ui/needless_collect.fixed | 9 +- tests/ui/needless_collect.rs | 7 ++ tests/ui/needless_collect.stderr | 21 ++++- 4 files changed, 104 insertions(+), 22 deletions(-) diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 312133689900..4992cdf615fa 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::ops::ControlFlow; use super::NEEDLESS_COLLECT; @@ -144,7 +145,11 @@ pub(super) fn check<'tcx>( iter_replacement.push_str(&iter_call.get_iter_method(cx)); let mut remove_suggestions = vec![(l.span, String::new())]; - remove_suggestions.extend(extra_calls.iter().map(|extra| (extra.span, String::new()))); + remove_suggestions.extend( + extra_calls + .iter() + .flat_map(|extra| extra.span().map(|s| (s, String::new()))), + ); remove_suggestions.push((iter_call.span, iter_replacement)); diag.multipart_suggestion( @@ -325,29 +330,48 @@ enum IterFunctionKind { Contains(Span), } -struct ExtraFunction { - kind: ExtraFunctionKind, - span: Span, +struct ExtraFunctionSpan { + /// Span of the function call + func_span: Span, + /// Span of the argument + arg_span: Span, +} + +enum ExtraFunction { + Push(Vec), + Extend(ExtraFunctionSpan), } impl ExtraFunction { fn get_iter_method(&self, cx: &LateContext<'_>) -> String { - match &self.kind { - ExtraFunctionKind::Push(span) => { - let s = snippet(cx, *span, ".."); + match &self { + ExtraFunction::Push(spans) => { + let s = spans + .iter() + .map(|span| snippet(cx, span.arg_span, "..")) + .intersperse(Cow::Borrowed(", ")) + .collect::(); format!(".chain([{s}])") }, + ExtraFunction::Extend(span) => { + let s = snippet(cx, span.arg_span, ".."); + format!(".chain({s})") + }, } } -} -enum ExtraFunctionKind { - Push(Span), + fn span(&self) -> Box + '_> { + match &self { + ExtraFunction::Push(spans) => Box::new(spans.iter().map(|s| s.func_span)), + ExtraFunction::Extend(span) => Box::new(std::iter::once(span.func_span)), + } + } } #[derive(Clone, Copy)] struct ExtraFunctionSpec { push_symbol: Option, + extend_symbol: Option, } impl ExtraFunctionSpec { @@ -355,14 +379,23 @@ impl ExtraFunctionSpec { match target { sym::Vec => Some(ExtraFunctionSpec { push_symbol: Some(sym::push), + extend_symbol: Some(sym::extend), }), sym::VecDeque | sym::LinkedList => Some(ExtraFunctionSpec { push_symbol: Some(sym::push_back), + extend_symbol: Some(sym::extend), + }), + sym::BinaryHeap => Some(ExtraFunctionSpec { + push_symbol: None, + extend_symbol: None, }), - sym::BinaryHeap => Some(ExtraFunctionSpec { push_symbol: None }), _ => None, } } + + fn is_extra_function(self, name: Symbol) -> bool { + self.push_symbol == Some(name) || self.extend_symbol == Some(name) + } } struct IterFunctionVisitor<'a, 'tcx> { @@ -397,6 +430,7 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> { } } + #[expect(clippy::too_many_lines)] fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { // Check function calls on our collection if let ExprKind::MethodCall(method_name, recv, args, _) = &expr.kind { @@ -446,10 +480,30 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> { if let Node::Stmt(stmt) = self.cx.tcx.parent_hir_node(expr.hir_id) { span = stmt.span; } - self.extras.push(ExtraFunction { - kind: ExtraFunctionKind::Push(args[0].span), - span, - }); + if let Some(ExtraFunction::Push(spans)) = self.extras.last_mut() { + spans.push(ExtraFunctionSpan { + func_span: span, + arg_span: args[0].span, + }); + } else { + self.extras.push(ExtraFunction::Push(vec![ExtraFunctionSpan { + func_span: span, + arg_span: args[0].span, + }])); + } + }, + name if self.extra_spec.extend_symbol.is_some_and(|sym| name == sym) + && self.uses.is_empty() => + { + let mut span = expr.span; + // Remove the statement span if possible + if let Node::Stmt(stmt) = self.cx.tcx.parent_hir_node(expr.hir_id) { + span = stmt.span; + } + self.extras.push(ExtraFunction::Extend(ExtraFunctionSpan { + func_span: span, + arg_span: args[0].span, + })); }, _ => { self.seen_other = true; @@ -551,10 +605,7 @@ impl<'tcx> Visitor<'tcx> for UsedCountVisitor<'_, 'tcx> { let parent = self.cx.tcx.parent_hir_node(expr.hir_id); if let Node::Expr(expr) = parent && let ExprKind::MethodCall(method_name, _, _, _) = &expr.kind - && self - .extra_spec - .push_symbol - .is_some_and(|sym| method_name.ident.name == sym) + && self.extra_spec.is_extra_function(method_name.ident.name) { return; } diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index fff383fb1328..e24c752870cc 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -241,7 +241,7 @@ mod collect_push_then_iter { //~^ needless_collect - iter.chain([1]).chain([2]).map(|x| x + 1).collect() + iter.chain([1, 2]).map(|x| x + 1).collect() } fn linked_list_push(iter: impl Iterator) -> LinkedList { @@ -263,4 +263,11 @@ mod collect_push_then_iter { v.push(1); ok } + + fn linked_list_extend(iter: impl Iterator, s: Vec) -> LinkedList { + + //~^ needless_collect + + iter.chain(s).map(|x| x + 1).collect() + } } diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index f6e966b09ea5..7666d5e33fdb 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -263,4 +263,11 @@ mod collect_push_then_iter { v.push(1); ok } + + fn linked_list_extend(iter: impl Iterator, s: Vec) -> LinkedList { + let mut ll = iter.collect::>(); + //~^ needless_collect + ll.extend(s); + ll.into_iter().map(|x| x + 1).collect() + } } diff --git a/tests/ui/needless_collect.stderr b/tests/ui/needless_collect.stderr index 93ca32a68d6a..0decd8cd136a 100644 --- a/tests/ui/needless_collect.stderr +++ b/tests/ui/needless_collect.stderr @@ -153,7 +153,7 @@ LL ~ LL | LL ~ LL ~ -LL ~ iter.chain([1]).chain([2]).map(|x| x + 1).collect() +LL ~ iter.chain([1, 2]).map(|x| x + 1).collect() | error: avoid using `collect()` when not needed @@ -173,5 +173,22 @@ LL ~ LL ~ iter.chain([1]).map(|x| x + 1).collect() | -error: aborting due to 23 previous errors +error: avoid using `collect()` when not needed + --> tests/ui/needless_collect.rs:268:27 + | +LL | let mut ll = iter.collect::>(); + | ^^^^^^^ +... +LL | ll.into_iter().map(|x| x + 1).collect() + | -------------- the iterator could be used here instead + | +help: use the original Iterator instead of collecting it and then producing a new one + | +LL ~ +LL | +LL ~ +LL ~ iter.chain(s).map(|x| x + 1).collect() + | + +error: aborting due to 24 previous errors From 0127720eb8587a3ffecc293020b0faa79c9b8199 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 2 Jan 2026 01:26:15 +0000 Subject: [PATCH 1474/3801] Extend `needless_collect` to cover `push_front` --- clippy_lints/src/methods/needless_collect.rs | 128 ++++++++++++++----- clippy_utils/src/sym.rs | 1 + tests/ui/needless_collect.fixed | 26 +++- tests/ui/needless_collect.rs | 26 +++- tests/ui/needless_collect.stderr | 43 ++++++- 5 files changed, 187 insertions(+), 37 deletions(-) diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 4992cdf615fa..6bdb40e46b38 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -141,7 +141,9 @@ pub(super) fn check<'tcx>( |diag| { let iter_snippet = Sugg::hir(cx, iter_expr, ".."); let mut iter_replacement = iter_snippet.to_string(); - iter_replacement.extend(extra_calls.iter().map(|extra| extra.get_iter_method(cx))); + for extra in &extra_calls { + iter_replacement = extra.apply_iter_method(cx, &iter_replacement); + } iter_replacement.push_str(&iter_call.get_iter_method(cx)); let mut remove_suggestions = vec![(l.span, String::new())]; @@ -338,39 +340,62 @@ struct ExtraFunctionSpan { } enum ExtraFunction { - Push(Vec), + Push { + back: Vec, + front: Vec, + }, Extend(ExtraFunctionSpan), } impl ExtraFunction { - fn get_iter_method(&self, cx: &LateContext<'_>) -> String { + fn apply_iter_method(&self, cx: &LateContext<'_>, inner: &str) -> String { match &self { - ExtraFunction::Push(spans) => { - let s = spans + ExtraFunction::Push { back, front } => { + let back_sugg = back .iter() .map(|span| snippet(cx, span.arg_span, "..")) .intersperse(Cow::Borrowed(", ")) .collect::(); - format!(".chain([{s}])") + let front = front + .iter() + .map(|span| snippet(cx, span.arg_span, "..")) + .intersperse(Cow::Borrowed(", ")) + .collect::(); + match (front.is_empty(), back_sugg.is_empty()) { + (true, true) => inner.to_string(), + (true, false) => format!("{inner}.chain([{back_sugg}])"), + (false, true) => format!("[{front}].into_iter().chain({inner})"), + (false, false) => format!("[{front}].into_iter().chain({inner}).chain([{back_sugg}])"), + } }, ExtraFunction::Extend(span) => { let s = snippet(cx, span.arg_span, ".."); - format!(".chain({s})") + format!("{inner}.chain({s})") }, } } fn span(&self) -> Box + '_> { match &self { - ExtraFunction::Push(spans) => Box::new(spans.iter().map(|s| s.func_span)), + ExtraFunction::Push { back, front } => Box::new( + back.iter() + .map(|s| s.func_span) + .chain(front.iter().map(|s| s.func_span)), + ), ExtraFunction::Extend(span) => Box::new(std::iter::once(span.func_span)), } } } +#[derive(Clone, Copy)] +struct ExtraFunctionPushSpec { + back: Option, + front: Option, +} + #[derive(Clone, Copy)] struct ExtraFunctionSpec { - push_symbol: Option, + push_symbol: ExtraFunctionPushSpec, extend_symbol: Option, } @@ -378,15 +403,24 @@ impl ExtraFunctionSpec { fn new(target: Symbol) -> Option { match target { sym::Vec => Some(ExtraFunctionSpec { - push_symbol: Some(sym::push), + push_symbol: ExtraFunctionPushSpec { + back: Some(sym::push), + front: None, + }, extend_symbol: Some(sym::extend), }), sym::VecDeque | sym::LinkedList => Some(ExtraFunctionSpec { - push_symbol: Some(sym::push_back), + push_symbol: ExtraFunctionPushSpec { + back: Some(sym::push_back), + front: Some(sym::push_front), + }, extend_symbol: Some(sym::extend), }), sym::BinaryHeap => Some(ExtraFunctionSpec { - push_symbol: None, + push_symbol: ExtraFunctionPushSpec { + back: None, + front: None, + }, extend_symbol: None, }), _ => None, @@ -394,7 +428,7 @@ impl ExtraFunctionSpec { } fn is_extra_function(self, name: Symbol) -> bool { - self.push_symbol == Some(name) || self.extend_symbol == Some(name) + self.push_symbol.back == Some(name) || self.push_symbol.front == Some(name) || self.extend_symbol == Some(name) } } @@ -474,32 +508,48 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> { func: IterFunctionKind::Contains(args[0].span), span: expr.span, })), - name if Some(name) == self.extra_spec.push_symbol && self.uses.is_empty() => { - let mut span = expr.span; - // Remove the statement span if possible - if let Node::Stmt(stmt) = self.cx.tcx.parent_hir_node(expr.hir_id) { - span = stmt.span; - } - if let Some(ExtraFunction::Push(spans)) = self.extras.last_mut() { - spans.push(ExtraFunctionSpan { - func_span: span, - arg_span: args[0].span, - }); - } else { - self.extras.push(ExtraFunction::Push(vec![ExtraFunctionSpan { - func_span: span, - arg_span: args[0].span, - }])); + name if let is_push_back = self.extra_spec.push_symbol.back.is_some_and(|sym| name == sym) + && (is_push_back || self.extra_spec.push_symbol.front.is_some_and(|sym| name == sym)) + && self.uses.is_empty() => + { + let span = get_span_of_expr_or_parent_stmt(self.cx, expr); + match self.extras.last_mut() { + Some(ExtraFunction::Push { back, .. }) if is_push_back => { + back.push(ExtraFunctionSpan { + func_span: span, + arg_span: args[0].span, + }); + }, + Some(ExtraFunction::Push { front, .. }) => { + front.push(ExtraFunctionSpan { + func_span: span, + arg_span: args[0].span, + }); + }, + _ if is_push_back => { + self.extras.push(ExtraFunction::Push { + back: vec![ExtraFunctionSpan { + func_span: span, + arg_span: args[0].span, + }], + front: Vec::new(), + }); + }, + _ => { + self.extras.push(ExtraFunction::Push { + back: Vec::new(), + front: vec![ExtraFunctionSpan { + func_span: span, + arg_span: args[0].span, + }], + }); + }, } }, name if self.extra_spec.extend_symbol.is_some_and(|sym| name == sym) && self.uses.is_empty() => { - let mut span = expr.span; - // Remove the statement span if possible - if let Node::Stmt(stmt) = self.cx.tcx.parent_hir_node(expr.hir_id) { - span = stmt.span; - } + let span = get_span_of_expr_or_parent_stmt(self.cx, expr); self.extras.push(ExtraFunction::Extend(ExtraFunctionSpan { func_span: span, arg_span: args[0].span, @@ -542,6 +592,16 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> { } } +/// If parent of the `expr` is a statement, return the span of the statement, otherwise return the +/// span of the expression. +fn get_span_of_expr_or_parent_stmt<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Span { + if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id) { + stmt.span + } else { + expr.span + } +} + enum LoopKind<'tcx> { Conditional(&'tcx Expr<'tcx>), Loop, diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index a36f4954a06a..fbd5ce2dc2d1 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -272,6 +272,7 @@ generate! { product, push, push_back, + push_front, push_str, read, read_exact, diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index e24c752870cc..2d59c1d42b05 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -222,7 +222,7 @@ fn issue16270() { #[warn(clippy::needless_collect)] mod collect_push_then_iter { - use std::collections::{BinaryHeap, LinkedList}; + use std::collections::{BinaryHeap, LinkedList, VecDeque}; fn vec_push(iter: impl Iterator) -> Vec { @@ -270,4 +270,28 @@ mod collect_push_then_iter { iter.chain(s).map(|x| x + 1).collect() } + + fn deque_push_front(iter: impl Iterator) -> VecDeque { + + //~^ needless_collect + + + [1, 2].into_iter().chain(iter).map(|x| x + 1).collect() + } + + fn linked_list_push_front_mixed( + iter: impl Iterator, + iter2: impl Iterator, + ) -> LinkedList { + + //~^ needless_collect + + + + + + + + [5].into_iter().chain([1, 3].into_iter().chain(iter).chain([2]).chain(iter2)).chain([4, 6]).map(|x| x + 1).collect() + } } diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index 7666d5e33fdb..346cddd88e70 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -222,7 +222,7 @@ fn issue16270() { #[warn(clippy::needless_collect)] mod collect_push_then_iter { - use std::collections::{BinaryHeap, LinkedList}; + use std::collections::{BinaryHeap, LinkedList, VecDeque}; fn vec_push(iter: impl Iterator) -> Vec { let mut v = iter.collect::>(); @@ -270,4 +270,28 @@ mod collect_push_then_iter { ll.extend(s); ll.into_iter().map(|x| x + 1).collect() } + + fn deque_push_front(iter: impl Iterator) -> VecDeque { + let mut v = iter.collect::>(); + //~^ needless_collect + v.push_front(1); + v.push_front(2); + v.into_iter().map(|x| x + 1).collect() + } + + fn linked_list_push_front_mixed( + iter: impl Iterator, + iter2: impl Iterator, + ) -> LinkedList { + let mut v = iter.collect::>(); + //~^ needless_collect + v.push_front(1); + v.push_back(2); + v.push_front(3); + v.extend(iter2); + v.push_back(4); + v.push_front(5); + v.push_back(6); + v.into_iter().map(|x| x + 1).collect() + } } diff --git a/tests/ui/needless_collect.stderr b/tests/ui/needless_collect.stderr index 0decd8cd136a..b10312224c8e 100644 --- a/tests/ui/needless_collect.stderr +++ b/tests/ui/needless_collect.stderr @@ -190,5 +190,46 @@ LL ~ LL ~ iter.chain(s).map(|x| x + 1).collect() | -error: aborting due to 24 previous errors +error: avoid using `collect()` when not needed + --> tests/ui/needless_collect.rs:275:26 + | +LL | let mut v = iter.collect::>(); + | ^^^^^^^ +... +LL | v.into_iter().map(|x| x + 1).collect() + | ------------- the iterator could be used here instead + | +help: use the original Iterator instead of collecting it and then producing a new one + | +LL ~ +LL | +LL ~ +LL ~ +LL ~ [1, 2].into_iter().chain(iter).map(|x| x + 1).collect() + | + +error: avoid using `collect()` when not needed + --> tests/ui/needless_collect.rs:286:26 + | +LL | let mut v = iter.collect::>(); + | ^^^^^^^ +... +LL | v.into_iter().map(|x| x + 1).collect() + | ------------- the iterator could be used here instead + | +help: use the original Iterator instead of collecting it and then producing a new one + | +LL ~ +LL | +LL ~ +LL ~ +LL ~ +LL ~ +LL ~ +LL ~ +LL ~ +LL ~ [5].into_iter().chain([1, 3].into_iter().chain(iter).chain([2]).chain(iter2)).chain([4, 6]).map(|x| x + 1).collect() + | + +error: aborting due to 26 previous errors From f74896fc01a995ea3adea70cf4d658ef0347a8d0 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 1 Jan 2026 19:30:02 -0600 Subject: [PATCH 1475/3801] Cleanup `debuginfo_compression` unstable flag It isn't necessary to declare the option as a top-level flag when it is accessible from `unstable_opts`. --- compiler/rustc_codegen_llvm/src/back/write.rs | 2 +- compiler/rustc_session/src/config.rs | 3 --- compiler/rustc_session/src/options.rs | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index e9306e050803..bcadb6f0de92 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -250,7 +250,7 @@ pub(crate) fn target_machine_factory( let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated); - let debuginfo_compression = match sess.opts.debuginfo_compression { + let debuginfo_compression = match sess.opts.unstable_opts.debuginfo_compression { config::DebugInfoCompression::None => llvm::CompressionKind::None, config::DebugInfoCompression::Zlib => { if llvm::LLVMRustLLVMHasZlibCompression() { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f326442c0879..fe96dabf6330 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1376,7 +1376,6 @@ impl Default for Options { crate_types: Vec::new(), optimize: OptLevel::No, debuginfo: DebugInfo::None, - debuginfo_compression: DebugInfoCompression::None, lint_opts: Vec::new(), lint_cap: None, describe_lints: false, @@ -2639,7 +2638,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M // for more details. let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No); let debuginfo = select_debuginfo(matches, &cg); - let debuginfo_compression = unstable_opts.debuginfo_compression; if !unstable_options_enabled { if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) { @@ -2747,7 +2745,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M crate_types, optimize: opt_level, debuginfo, - debuginfo_compression, lint_opts, lint_cap, describe_lints, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 2b83d1225c97..f11ad12fb9dd 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -397,7 +397,6 @@ top_level_options!( /// can influence whether overflow checks are done or not. debug_assertions: bool [TRACKED], debuginfo: DebugInfo [TRACKED], - debuginfo_compression: DebugInfoCompression [TRACKED], lint_opts: Vec<(String, lint::Level)> [TRACKED_NO_CRATE_HASH], lint_cap: Option [TRACKED_NO_CRATE_HASH], describe_lints: bool [UNTRACKED], From bf2078bfcad890114e0aa17501e706e3bc1b4df0 Mon Sep 17 00:00:00 2001 From: Ryan <63398895+rwardd@users.noreply.github.com> Date: Fri, 2 Jan 2026 12:01:55 +1030 Subject: [PATCH 1476/3801] fix: add `CHECK-SAME` labels to verify generated function type for `u8` and `[u8; 1]` cases Co-authored-by: scottmcm --- tests/codegen-llvm/issues/multiple-option-or-permutations.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs index 0106517c6fd5..9fbd77166534 100644 --- a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs +++ b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs @@ -19,6 +19,7 @@ pub fn or_match_u8(opta: Option, optb: Option) -> Option { } // CHECK-LABEL: @or_match_alt_u8 +// CHECK-SAME: (i1{{.+}}%opta.0, i8 %opta.1, i1{{.+}}%optb.0, i8 %optb.1) #[no_mangle] pub fn or_match_alt_u8(opta: Option, optb: Option) -> Option { // CHECK: start: @@ -58,6 +59,7 @@ pub fn if_some_u8(opta: Option, optb: Option) -> Option { } // CHECK-LABEL: @or_match_slice_u8 +// CHECK-SAME: (i16 %0, i16 %1) #[no_mangle] pub fn or_match_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: From c7e368543c2728c76a41008577b64b0ede7f708e Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 29 Dec 2025 23:31:46 -0800 Subject: [PATCH 1477/3801] Use more principled check for generics in const ops Instead of using a visitor in typeck, we just check, whenever lowering a use of a param, whether the parent item is an MCG anon const during hir ty lowering (and instantiate_value_path). If so, we report an error since MCG anon consts should never be able to use generics. All other kinds of anon consts are at least syntactically allowed to use generic params. We use a `TypeFolder` to accomplish this; this way, we look at the fully explicit semantic representation of the type/const/whatever and don't miss subtle cases like `Self` type aliases. --- .../src/hir_ty_lowering/mod.rs | 189 +++++++++++++----- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 5 + compiler/rustc_hir_typeck/src/lib.rs | 12 -- compiler/rustc_middle/src/hir/map.rs | 48 ----- tests/crashes/140891.rs | 6 - ...ttribute-missing-in-dependent-crate-ice.rs | 2 +- tests/ui/const-generics/ice-68875.rs | 2 +- .../ui/const-generics/issues/issue-56445-2.rs | 2 +- .../ui/const-generics/issues/issue-56445-3.rs | 2 +- .../ui/const-generics/issues/issue-67945-2.rs | 2 +- .../mgca/early-bound-param-lt-bad.rs | 13 ++ .../mgca/early-bound-param-lt-bad.stderr | 8 + .../mgca/explicit_anon_consts-7.rs | 10 + .../mgca/explicit_anon_consts-7.stderr | 8 + .../mgca/higher-ranked-lts-bad.rs | 12 ++ .../mgca/higher-ranked-lts-bad.stderr | 8 + .../mgca/higher-ranked-lts-good.rs | 13 ++ .../mgca/late-bound-param-lt-bad.rs | 12 ++ .../mgca/late-bound-param-lt-bad.stderr | 11 + .../mgca/selftyalias-containing-param.rs | 13 ++ .../mgca/selftyalias-containing-param.stderr | 14 ++ tests/ui/const-generics/mgca/selftyparam.rs | 9 + .../ui/const-generics/mgca/selftyparam.stderr | 8 + .../forbid-self-no-normalize.rs | 2 +- .../type-relative-path-144547.min.stderr | 8 + .../type-relative-path-144547.rs | 43 ++++ 26 files changed, 338 insertions(+), 124 deletions(-) delete mode 100644 tests/crashes/140891.rs create mode 100644 tests/ui/const-generics/mgca/early-bound-param-lt-bad.rs create mode 100644 tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-7.rs create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-7.stderr create mode 100644 tests/ui/const-generics/mgca/higher-ranked-lts-bad.rs create mode 100644 tests/ui/const-generics/mgca/higher-ranked-lts-bad.stderr create mode 100644 tests/ui/const-generics/mgca/higher-ranked-lts-good.rs create mode 100644 tests/ui/const-generics/mgca/late-bound-param-lt-bad.rs create mode 100644 tests/ui/const-generics/mgca/late-bound-param-lt-bad.stderr create mode 100644 tests/ui/const-generics/mgca/selftyalias-containing-param.rs create mode 100644 tests/ui/const-generics/mgca/selftyalias-containing-param.stderr create mode 100644 tests/ui/const-generics/mgca/selftyparam.rs create mode 100644 tests/ui/const-generics/mgca/selftyparam.stderr create mode 100644 tests/ui/const-generics/type-relative-path-144547.min.stderr create mode 100644 tests/ui/const-generics/type-relative-path-144547.rs 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 23110d2c5c87..4c7cfde638f5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -38,8 +38,8 @@ use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::mir::interpret::LitToConstInput; use rustc_middle::ty::print::PrintPolyTraitRefExt as _; use rustc_middle::ty::{ - self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, - TypingMode, Upcast, fold_regions, + self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, + TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast, fold_regions, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; @@ -394,7 +394,118 @@ pub trait GenericArgsLowerer<'a, 'tcx> { ) -> ty::GenericArg<'tcx>; } +struct ForbidMCGParamUsesFolder<'tcx> { + tcx: TyCtxt<'tcx>, + anon_const_def_id: LocalDefId, + span: Span, + is_self_alias: bool, +} + +impl<'tcx> ForbidMCGParamUsesFolder<'tcx> { + fn error(&self) -> ErrorGuaranteed { + let msg = if self.is_self_alias { + "generic `Self` types are currently not permitted in anonymous constants" + } else { + "generic parameters may not be used in const operations" + }; + let mut diag = self.tcx.dcx().struct_span_err(self.span, msg); + if self.is_self_alias { + let anon_const_hir_id: HirId = HirId::make_owner(self.anon_const_def_id); + let parent_impl = self.tcx.hir_parent_owner_iter(anon_const_hir_id).find_map( + |(_, node)| match node { + hir::OwnerNode::Item(hir::Item { + kind: hir::ItemKind::Impl(impl_), .. + }) => Some(impl_), + _ => None, + }, + ); + if let Some(impl_) = parent_impl { + diag.span_note(impl_.self_ty.span, "not a concrete type"); + } + } + diag.emit() + } +} + +impl<'tcx> ty::TypeFolder> for ForbidMCGParamUsesFolder<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + if matches!(t.kind(), ty::Param(..)) { + return Ty::new_error(self.tcx, self.error()); + } + t.super_fold_with(self) + } + + fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> { + if matches!(c.kind(), ty::ConstKind::Param(..)) { + return Const::new_error(self.tcx, self.error()); + } + c.super_fold_with(self) + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + if matches!(r.kind(), ty::RegionKind::ReEarlyParam(..) | ty::RegionKind::ReLateParam(..)) { + return ty::Region::new_error(self.tcx, self.error()); + } + r + } +} + impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { + /// See `check_param_uses_if_mcg`. + /// + /// FIXME(mgca): this is pub only for instantiate_value_path and would be nice to avoid altogether + pub fn check_param_res_if_mcg_for_instantiate_value_path( + &self, + res: Res, + span: Span, + ) -> Result<(), ErrorGuaranteed> { + let tcx = self.tcx(); + let parent_def_id = self.item_def_id(); + if let Res::Def(DefKind::ConstParam, _) = res + && tcx.def_kind(parent_def_id) == DefKind::AnonConst + && let ty::AnonConstKind::MCG = tcx.anon_const_kind(parent_def_id) + { + let folder = ForbidMCGParamUsesFolder { + tcx, + anon_const_def_id: parent_def_id, + span, + is_self_alias: false, + }; + return Err(folder.error()); + } + Ok(()) + } + + /// Check for uses of generic parameters that are not in scope due to this being + /// in a non-generic anon const context. + #[must_use = "need to use transformed output"] + fn check_param_uses_if_mcg(&self, term: T, span: Span, is_self_alias: bool) -> T + where + T: ty::TypeFoldable>, + { + let tcx = self.tcx(); + let parent_def_id = self.item_def_id(); + if tcx.def_kind(parent_def_id) == DefKind::AnonConst + && let ty::AnonConstKind::MCG = tcx.anon_const_kind(parent_def_id) + // Fast path if contains no params/escaping bound vars. + && (term.has_param() || term.has_escaping_bound_vars()) + { + let mut folder = ForbidMCGParamUsesFolder { + tcx, + anon_const_def_id: parent_def_id, + span, + is_self_alias, + }; + term.fold_with(&mut folder) + } else { + term + } + } + /// Lower a lifetime from the HIR to our internal notion of a lifetime called a *region*. #[instrument(level = "debug", skip(self), ret)] pub fn lower_lifetime( @@ -403,7 +514,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { reason: RegionInferReason<'_>, ) -> ty::Region<'tcx> { if let Some(resolved) = self.tcx().named_bound_var(lifetime.hir_id) { - self.lower_resolved_lifetime(resolved) + let region = self.lower_resolved_lifetime(resolved); + self.check_param_uses_if_mcg(region, lifetime.ident.span, false) } else { self.re_infer(lifetime.ident.span, reason) } @@ -411,7 +523,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Lower a lifetime from the HIR to our internal notion of a lifetime called a *region*. #[instrument(level = "debug", skip(self), ret)] - pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> { + fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> { let tcx = self.tcx(); match resolved { @@ -1256,9 +1368,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { TypeRelativePath::AssocItem(def_id, args) => { let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args); let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty); + let ty = self.check_param_uses_if_mcg(ty, span, false); Ok((ty, tcx.def_kind(def_id), def_id)) } TypeRelativePath::Variant { adt, variant_did } => { + let adt = self.check_param_uses_if_mcg(adt, span, false); Ok((adt, DefKind::Variant, variant_did)) } } @@ -1275,7 +1389,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, ) -> Result, ErrorGuaranteed> { let tcx = self.tcx(); - let (def_id, args) = match self.lower_type_relative_path( + match self.lower_type_relative_path( self_ty, hir_self_ty, segment, @@ -1292,15 +1406,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { err.note("the declaration in the trait must be marked with `#[type_const]`"); return Err(err.emit()); } - (def_id, args) + let ct = Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args)); + let ct = self.check_param_uses_if_mcg(ct, span, false); + Ok(ct) } // FIXME(mgca): implement support for this once ready to support all adt ctor expressions, // not just const ctors TypeRelativePath::Variant { .. } => { span_bug!(span, "unexpected variant res for type associated const path") } - }; - Ok(Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args))) + } } /// Lower a [type-relative][hir::QPath::TypeRelative] (and type-level) path. @@ -2032,9 +2147,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { GenericsArgsErrExtend::None }, ); - tcx.types.self_param + self.check_param_uses_if_mcg(tcx.types.self_param, span, false) } - Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => { + Res::SelfTyAlias { alias_to: def_id, forbid_generic: _, .. } => { // `Self` in impl (we know the concrete type). assert_eq!(opt_self_ty, None); // Try to evaluate any array length constants. @@ -2043,42 +2158,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { path.segments.iter(), GenericsArgsErrExtend::SelfTyAlias { def_id, span }, ); - // HACK(min_const_generics): Forbid generic `Self` types - // here as we can't easily do that during nameres. - // - // We do this before normalization as we otherwise allow - // ```rust - // trait AlwaysApplicable { type Assoc; } - // impl AlwaysApplicable for T { type Assoc = usize; } - // - // trait BindsParam { - // type ArrayTy; - // } - // impl BindsParam for ::Assoc { - // type ArrayTy = [u8; Self::MAX]; - // } - // ``` - // Note that the normalization happens in the param env of - // the anon const, which is empty. This is why the - // `AlwaysApplicable` impl needs a `T: ?Sized` bound for - // this to compile if we were to normalize here. - if forbid_generic && ty.has_param() { - let mut err = self.dcx().struct_span_err( - path.span, - "generic `Self` types are currently not permitted in anonymous constants", - ); - if let Some(hir::Node::Item(&hir::Item { - kind: hir::ItemKind::Impl(impl_), - .. - })) = tcx.hir_get_if_local(def_id) - { - err.span_note(impl_.self_ty.span, "not a concrete type"); - } - let reported = err.emit(); - Ty::new_error(tcx, reported) - } else { - ty - } + self.check_param_uses_if_mcg(ty, span, true) } Res::Def(DefKind::AssocTy, def_id) => { let trait_segment = if let [modules @ .., trait_, _item] = path.segments { @@ -2138,7 +2218,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// and late-bound ones to [`ty::Bound`]. pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> { let tcx = self.tcx(); - match tcx.named_bound_var(hir_id) { + + let ty = match tcx.named_bound_var(hir_id) { Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => { let br = ty::BoundTy { var: ty::BoundVar::from_u32(index), @@ -2154,7 +2235,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar), arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), - } + }; + self.check_param_uses_if_mcg(ty, tcx.hir_span(hir_id), false) } /// Lower a const parameter from the HIR to our internal notion of a constant. @@ -2164,7 +2246,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { pub(crate) fn lower_const_param(&self, param_def_id: DefId, path_hir_id: HirId) -> Const<'tcx> { let tcx = self.tcx(); - match tcx.named_bound_var(path_hir_id) { + let ct = match tcx.named_bound_var(path_hir_id) { Some(rbv::ResolvedArg::EarlyBound(_)) => { // Find the name and index of the const parameter by indexing the generics of // the parent item and construct a `ParamConst`. @@ -2181,7 +2263,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ), Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar), arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id), - } + }; + self.check_param_uses_if_mcg(ct, tcx.hir_span(path_hir_id), false) } /// Lower a [`hir::ConstArg`] to a (type-level) [`ty::Const`](Const). @@ -2386,7 +2469,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) -> Const<'tcx> { let tcx = self.tcx(); let span = path.span; - match path.res { + let ct = match path.res { Res::Def(DefKind::ConstParam, def_id) => { assert_eq!(opt_self_ty, None); let _ = self.prohibit_generic_args( @@ -2475,7 +2558,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span, format!("invalid Res {res:?} for const path"), ), - } + }; + self.check_param_uses_if_mcg(ct, span, false) } /// Literals are eagerly converted to a constant, everything else becomes `Unevaluated`. @@ -2787,6 +2871,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| { if let Some(i) = (param.index as usize).checked_sub(offset) { let (lifetime, _) = lifetimes[i]; + // FIXME(mgca): should we be calling self.check_params_use_if_mcg here too? self.lower_resolved_lifetime(lifetime).into() } else { tcx.mk_param_from_def(param) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ff85f53ddf30..339e77ac6edd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1004,6 +1004,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err_extend, ); + if let Err(e) = self.lowerer().check_param_res_if_mcg_for_instantiate_value_path(res, span) + { + return (Ty::new_error(self.tcx, e), res); + } + if let Res::Local(hid) = res { let ty = self.local_ty(span, hid); let ty = self.normalize(span, ty); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index b8a587016427..39c28c4f4e99 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -115,18 +115,6 @@ fn typeck_with_inspect<'tcx>( return tcx.typeck(typeck_root_def_id); } - // We can't handle bodies containing generic parameters even though - // these generic parameters aren't part of its `generics_of` right now. - // - // See the FIXME on `check_anon_const_invalid_param_uses`. - if tcx.features().min_generic_const_args() - && let DefKind::AnonConst = tcx.def_kind(def_id) - && let ty::AnonConstKind::MCG = tcx.anon_const_kind(def_id) - && let Err(e) = tcx.check_anon_const_invalid_param_uses(def_id) - { - e.raise_fatal(); - } - let id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(id); let span = tcx.def_span(def_id); diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index d62ddc915d17..8cc66802e435 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -2,8 +2,6 @@ //! eliminated, and all its methods are now on `TyCtxt`. But the module name //! stays as `map` because there isn't an obviously better name for it. -use std::ops::ControlFlow; - use rustc_abi::ExternAbi; use rustc_ast::visit::{VisitorResult, walk_list}; use rustc_data_structures::fingerprint::Fingerprint; @@ -1090,52 +1088,6 @@ impl<'tcx> TyCtxt<'tcx> { None } - - // FIXME(mgca): this is pretty iffy. In the long term we should make - // HIR ty lowering able to return `Error` versions of types/consts when - // lowering them in contexts that aren't supposed to use generic parameters. - // - // This current impl strategy is incomplete and doesn't handle `Self` ty aliases. - pub fn check_anon_const_invalid_param_uses( - self, - anon: LocalDefId, - ) -> Result<(), ErrorGuaranteed> { - struct GenericParamVisitor<'tcx>(TyCtxt<'tcx>); - impl<'tcx> Visitor<'tcx> for GenericParamVisitor<'tcx> { - type NestedFilter = nested_filter::OnlyBodies; - type Result = ControlFlow; - - fn maybe_tcx(&mut self) -> TyCtxt<'tcx> { - self.0 - } - - fn visit_path( - &mut self, - path: &crate::hir::Path<'tcx>, - _id: HirId, - ) -> ControlFlow { - if let Res::Def( - DefKind::TyParam | DefKind::ConstParam | DefKind::LifetimeParam, - _, - ) = path.res - { - let e = self.0.dcx().struct_span_err( - path.span, - "generic parameters may not be used in const operations", - ); - return ControlFlow::Break(e.emit()); - } - - intravisit::walk_path(self, path) - } - } - - let body = self.hir_maybe_body_owned_by(anon).unwrap(); - match GenericParamVisitor(self).visit_expr(&body.value) { - ControlFlow::Break(e) => Err(e), - ControlFlow::Continue(()) => Ok(()), - } - } } impl<'tcx> intravisit::HirTyCtxt<'tcx> for TyCtxt<'tcx> { diff --git a/tests/crashes/140891.rs b/tests/crashes/140891.rs deleted file mode 100644 index 421919403eff..000000000000 --- a/tests/crashes/140891.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #140891 -struct A {} -impl Iterator for A { - fn next() -> [(); std::mem::size_of::>] {} -} -fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.rs b/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.rs index b9537014767e..8d7ec1867857 100644 --- a/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.rs +++ b/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.rs @@ -11,7 +11,7 @@ struct Wrapper(i64); impl aux::FromSlice for Wrapper { fn validate_slice(_: &[[u8; Self::SIZE]]) -> Result<(), aux::Error> { - //~^ ERROR generic `Self` types are currently not permitted in anonymous constants + //~^ ERROR generic `Self` Ok(()) } } diff --git a/tests/ui/const-generics/ice-68875.rs b/tests/ui/const-generics/ice-68875.rs index cc9546be2c92..7bf6a824729a 100644 --- a/tests/ui/const-generics/ice-68875.rs +++ b/tests/ui/const-generics/ice-68875.rs @@ -1,7 +1,7 @@ //@ check-fail struct DataWrapper<'a> { - data: &'a [u8; Self::SIZE], //~ ERROR generic `Self` types are currently not permitted in anonymous constants + data: &'a [u8; Self::SIZE], //~ ERROR generic `Self` } impl DataWrapper<'_> { diff --git a/tests/ui/const-generics/issues/issue-56445-2.rs b/tests/ui/const-generics/issues/issue-56445-2.rs index e078c8487c72..11c844340080 100644 --- a/tests/ui/const-generics/issues/issue-56445-2.rs +++ b/tests/ui/const-generics/issues/issue-56445-2.rs @@ -5,7 +5,7 @@ impl<'a> OnDiskDirEntry<'a> { const LFN_FRAGMENT_LEN: usize = 2; fn lfn_contents(&self) -> [char; Self::LFN_FRAGMENT_LEN] { loop { } } - //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants + //~^ ERROR: generic `Self` } fn main() {} diff --git a/tests/ui/const-generics/issues/issue-56445-3.rs b/tests/ui/const-generics/issues/issue-56445-3.rs index c29df14586e2..a9a4a48ab675 100644 --- a/tests/ui/const-generics/issues/issue-56445-3.rs +++ b/tests/ui/const-generics/issues/issue-56445-3.rs @@ -2,7 +2,7 @@ pub struct Memory<'rom> { rom: &'rom [u8], ram: [u8; Self::SIZE], - //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants + //~^ ERROR: generic `Self` } impl<'rom> Memory<'rom> { diff --git a/tests/ui/const-generics/issues/issue-67945-2.rs b/tests/ui/const-generics/issues/issue-67945-2.rs index ce48b3f86a65..d3c5c891f760 100644 --- a/tests/ui/const-generics/issues/issue-67945-2.rs +++ b/tests/ui/const-generics/issues/issue-67945-2.rs @@ -7,7 +7,7 @@ struct Bug { A: [(); { //[full]~^ ERROR overly complex generic constant let x: Option> = None; - //[min]~^ ERROR generic `Self` types are currently not permitted in anonymous constants + //[min]~^ ERROR generic `Self` 0 }], B: S diff --git a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.rs b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.rs new file mode 100644 index 000000000000..0ee2b4eb45f6 --- /dev/null +++ b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.rs @@ -0,0 +1,13 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait {} + +fn foo<'a, T>() +where + 'a: 'a, + T: Trait + //~^ ERROR generic parameters may not be used in const operations +{} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr new file mode 100644 index 000000000000..461a26e33a3c --- /dev/null +++ b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/early-bound-param-lt-bad.rs:9:30 + | +LL | T: Trait + | ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-7.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-7.rs new file mode 100644 index 000000000000..d3288d00ba6e --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-7.rs @@ -0,0 +1,10 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] +// library crates exercise weirder code paths around +// DefIds which were created for const args. +#![crate_type = "lib"] + +fn foo() -> [(); N] { + let a: [(); const { N }] = todo!(); + //~^ ERROR: generic parameters may not be used in const operations +} diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-7.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-7.stderr new file mode 100644 index 000000000000..1b28c861067d --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-7.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts-7.rs:8:25 + | +LL | let a: [(); const { N }] = todo!(); + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/higher-ranked-lts-bad.rs b/tests/ui/const-generics/mgca/higher-ranked-lts-bad.rs new file mode 100644 index 000000000000..368644b641df --- /dev/null +++ b/tests/ui/const-generics/mgca/higher-ranked-lts-bad.rs @@ -0,0 +1,12 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait {} + +fn foo() +where + for<'a> T: Trait + //~^ ERROR cannot capture late-bound lifetime in constant +{} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/higher-ranked-lts-bad.stderr b/tests/ui/const-generics/mgca/higher-ranked-lts-bad.stderr new file mode 100644 index 000000000000..0f7389cac5cd --- /dev/null +++ b/tests/ui/const-generics/mgca/higher-ranked-lts-bad.stderr @@ -0,0 +1,8 @@ +error: cannot capture late-bound lifetime in constant + --> $DIR/higher-ranked-lts-bad.rs:8:38 + | +LL | for<'a> T: Trait + | -- lifetime defined here ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/higher-ranked-lts-good.rs b/tests/ui/const-generics/mgca/higher-ranked-lts-good.rs new file mode 100644 index 000000000000..5b455bb1e71e --- /dev/null +++ b/tests/ui/const-generics/mgca/higher-ranked-lts-good.rs @@ -0,0 +1,13 @@ +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait {} + +fn foo() +where + T: Trait fn(&'a ()); 1 }> +{} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/late-bound-param-lt-bad.rs b/tests/ui/const-generics/mgca/late-bound-param-lt-bad.rs new file mode 100644 index 000000000000..5c57bdfb9024 --- /dev/null +++ b/tests/ui/const-generics/mgca/late-bound-param-lt-bad.rs @@ -0,0 +1,12 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait {} + +fn foo<'a, T>() +where + T: Trait + //~^ ERROR cannot capture late-bound lifetime in constant +{} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/late-bound-param-lt-bad.stderr b/tests/ui/const-generics/mgca/late-bound-param-lt-bad.stderr new file mode 100644 index 000000000000..e5c22f282544 --- /dev/null +++ b/tests/ui/const-generics/mgca/late-bound-param-lt-bad.stderr @@ -0,0 +1,11 @@ +error: cannot capture late-bound lifetime in constant + --> $DIR/late-bound-param-lt-bad.rs:8:30 + | +LL | fn foo<'a, T>() + | -- lifetime defined here +LL | where +LL | T: Trait + | ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/selftyalias-containing-param.rs b/tests/ui/const-generics/mgca/selftyalias-containing-param.rs new file mode 100644 index 000000000000..5ab39799078f --- /dev/null +++ b/tests/ui/const-generics/mgca/selftyalias-containing-param.rs @@ -0,0 +1,13 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +struct S([(); N]); + +impl S { + fn foo() -> [(); const { let _: Self = loop {}; 1 }] { + //~^ ERROR generic `Self` + todo!() + } +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr new file mode 100644 index 000000000000..fdd3e6efdf65 --- /dev/null +++ b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr @@ -0,0 +1,14 @@ +error: generic `Self` types are currently not permitted in anonymous constants + --> $DIR/selftyalias-containing-param.rs:7:37 + | +LL | fn foo() -> [(); const { let _: Self = loop {}; 1 }] { + | ^^^^ + | +note: not a concrete type + --> $DIR/selftyalias-containing-param.rs:6:22 + | +LL | impl S { + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/selftyparam.rs b/tests/ui/const-generics/mgca/selftyparam.rs new file mode 100644 index 000000000000..58433405b8ca --- /dev/null +++ b/tests/ui/const-generics/mgca/selftyparam.rs @@ -0,0 +1,9 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Tr { + fn foo() -> [(); const { let _: Self; 1 }]; + //~^ ERROR generic parameters +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/selftyparam.stderr b/tests/ui/const-generics/mgca/selftyparam.stderr new file mode 100644 index 000000000000..376e63da9a75 --- /dev/null +++ b/tests/ui/const-generics/mgca/selftyparam.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/selftyparam.rs:5:37 + | +LL | fn foo() -> [(); const { let _: Self; 1 }]; + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs b/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs index e1cf7b579aa5..b8739b263aee 100644 --- a/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs +++ b/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs @@ -9,7 +9,7 @@ trait BindsParam { type ArrayTy; } impl BindsParam for ::Assoc { - type ArrayTy = [u8; Self::MAX]; //~ ERROR generic `Self` types + type ArrayTy = [u8; Self::MAX]; //~ ERROR generic `Self` } fn main() {} diff --git a/tests/ui/const-generics/type-relative-path-144547.min.stderr b/tests/ui/const-generics/type-relative-path-144547.min.stderr new file mode 100644 index 000000000000..1192a7434ec8 --- /dev/null +++ b/tests/ui/const-generics/type-relative-path-144547.min.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/type-relative-path-144547.rs:39:35 + | +LL | type SupportedArray = [T; ::SUPPORTED_SLOTS]; + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/type-relative-path-144547.rs b/tests/ui/const-generics/type-relative-path-144547.rs new file mode 100644 index 000000000000..b268055e1f7d --- /dev/null +++ b/tests/ui/const-generics/type-relative-path-144547.rs @@ -0,0 +1,43 @@ +// Regression test for #144547. + +//@ revisions: min mgca +//@[mgca] check-pass + +#![cfg_attr(mgca, feature(min_generic_const_args))] +#![cfg_attr(mgca, expect(incomplete_features))] + +trait UnderlyingImpl { + type InfoType: LevelInfo; + type SupportedArray; +} + +// FIXME: cfg_attr(..., type_const) is broken (search for sym::type_const in compiler/) +trait LevelInfo { + #[cfg(mgca)] + #[type_const] + const SUPPORTED_SLOTS: usize; + + #[cfg(not(mgca))] + const SUPPORTED_SLOTS: usize; +} + +struct Info; + +impl LevelInfo for Info { + #[cfg(mgca)] + #[type_const] + const SUPPORTED_SLOTS: usize = 1; + + #[cfg(not(mgca))] + const SUPPORTED_SLOTS: usize = 1; +} + +struct SomeImpl; + +impl UnderlyingImpl for SomeImpl { + type InfoType = Info; + type SupportedArray = [T; ::SUPPORTED_SLOTS]; + //[min]~^ ERROR generic parameters +} + +fn main() {} From bad0c3230f4adab2dd3cd81ce97f9a3a01e34228 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 30 Dec 2025 18:13:56 -0800 Subject: [PATCH 1478/3801] mgca: Remove resolved FIXME --- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 14 -------------- 1 file changed, 14 deletions(-) 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 4c7cfde638f5..48b2b80c8af3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2604,20 +2604,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { _ => expr, }; - // FIXME(mgca): remove this delayed bug once we start checking this - // when lowering `Ty/ConstKind::Param`s more generally. - if let hir::ExprKind::Path(hir::QPath::Resolved( - _, - &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. }, - )) = expr.kind - { - let e = tcx.dcx().span_delayed_bug( - expr.span, - "try_lower_anon_const_lit: received const param which shouldn't be possible", - ); - return Some(ty::Const::new_error(tcx, e)); - }; - let lit_input = match expr.kind { hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: lit.node, ty, neg: false }), hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind { From f71e93821eff7df12483ee1cb1d0dd7d397a4555 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 1 Jan 2026 14:44:07 -0800 Subject: [PATCH 1479/3801] mgca: Re-merge split out tests Now that we avoid a fatal error, they can all be one test. --- .../mgca/explicit_anon_consts-2.rs | 10 ---- .../mgca/explicit_anon_consts-2.stderr | 8 ---- .../mgca/explicit_anon_consts-3.rs | 10 ---- .../mgca/explicit_anon_consts-3.stderr | 8 ---- .../mgca/explicit_anon_consts-4.rs | 9 ---- .../mgca/explicit_anon_consts-4.stderr | 8 ---- .../mgca/explicit_anon_consts-5.rs | 16 ------- .../mgca/explicit_anon_consts-5.stderr | 8 ---- .../mgca/explicit_anon_consts-6.rs | 8 ---- .../mgca/explicit_anon_consts-6.stderr | 8 ---- .../mgca/explicit_anon_consts-7.rs | 10 ---- .../mgca/explicit_anon_consts-7.stderr | 8 ---- .../mgca/explicit_anon_consts.rs | 28 +++++------ .../mgca/explicit_anon_consts.stderr | 46 +++++++++++++++++-- 14 files changed, 55 insertions(+), 130 deletions(-) delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-2.rs delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-2.stderr delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-3.rs delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-3.stderr delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-4.rs delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-4.stderr delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-5.rs delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-5.stderr delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-6.rs delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-6.stderr delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-7.rs delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-7.stderr diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-2.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-2.rs deleted file mode 100644 index 37a3321a291e..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-2.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] -#![expect(incomplete_features)] -// library crates exercise weirder code paths around -// DefIds which were created for const args. -#![crate_type = "lib"] - -struct Foo; - -type Alias = Foo; -//~^ ERROR: generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-2.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-2.stderr deleted file mode 100644 index 8d8abd9ef313..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-2.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts-2.rs:9:42 - | -LL | type Alias = Foo; - | ^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-3.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-3.rs deleted file mode 100644 index ad7ae7c511ff..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-3.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] -#![expect(incomplete_features)] -// library crates exercise weirder code paths around -// DefIds which were created for const args. -#![crate_type = "lib"] - -struct Foo; - -type Alias = [(); const { N }]; -//~^ ERROR: generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-3.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-3.stderr deleted file mode 100644 index fe2c40486aeb..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-3.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts-3.rs:9:43 - | -LL | type Alias = [(); const { N }]; - | ^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-4.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-4.rs deleted file mode 100644 index bcf34bdb13ee..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-4.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] -#![expect(incomplete_features)] -// library crates exercise weirder code paths around -// DefIds which were created for const args. -#![crate_type = "lib"] - -#[type_const] -const ITEM3: usize = const { N }; -//~^ ERROR: generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-4.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-4.stderr deleted file mode 100644 index 7fc78257aa2c..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-4.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts-4.rs:8:46 - | -LL | const ITEM3: usize = const { N }; - | ^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-5.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-5.rs deleted file mode 100644 index aa14ec4275e4..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-5.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] -#![expect(incomplete_features)] -// library crates exercise weirder code paths around -// DefIds which were created for const args. -#![crate_type = "lib"] - -trait Trait { - #[type_const] - const ASSOC: usize; -} - -fn ace_bounds< - const N: usize, - T: Trait, - //~^ ERROR: generic parameters may not be used in const operations ->() {} diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-5.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-5.stderr deleted file mode 100644 index 6d2ab078c8cf..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-5.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts-5.rs:14:30 - | -LL | T: Trait, - | ^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-6.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-6.rs deleted file mode 100644 index 600f4b9cd7f9..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-6.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] -#![expect(incomplete_features)] -// library crates exercise weirder code paths around -// DefIds which were created for const args. -#![crate_type = "lib"] - -struct Default3; -//~^ ERROR: generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-6.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-6.stderr deleted file mode 100644 index 727e478bee8e..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-6.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts-6.rs:7:58 - | -LL | struct Default3; - | ^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-7.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-7.rs deleted file mode 100644 index d3288d00ba6e..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-7.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(min_generic_const_args)] -#![expect(incomplete_features)] -// library crates exercise weirder code paths around -// DefIds which were created for const args. -#![crate_type = "lib"] - -fn foo() -> [(); N] { - let a: [(); const { N }] = todo!(); - //~^ ERROR: generic parameters may not be used in const operations -} diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-7.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-7.stderr deleted file mode 100644 index 1b28c861067d..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts-7.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts-7.rs:8:25 - | -LL | let a: [(); const { N }] = todo!(); - | ^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs index f7df3eddfa64..f3edc0b3fbf3 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -4,27 +4,25 @@ // DefIds which were created for const args. #![crate_type = "lib"] -// FIXME(mgca): merge the split out parts of this test back in - struct Foo; type Adt1 = Foo; type Adt2 = Foo<{ N }>; -// explicit_anon_consts-2.rs -// type Adt3 = Foo; +type Adt3 = Foo; +//~^ ERROR: generic parameters may not be used in const operations type Adt4 = Foo<{ 1 + 1 }>; //~^ ERROR: complex const arguments must be placed inside of a `const` block type Adt5 = Foo; type Arr = [(); N]; type Arr2 = [(); { N }]; -// explicit_anon_consts-3.rs -// type Arr3 = [(); const { N }]; +type Arr3 = [(); const { N }]; +//~^ ERROR: generic parameters may not be used in const operations type Arr4 = [(); 1 + 1]; //~^ ERROR: complex const arguments must be placed inside of a `const` block type Arr5 = [(); const { 1 + 1 }]; -fn repeats() { +fn repeats() -> [(); N] { let _1 = [(); N]; let _2 = [(); { N }]; let _3 = [(); const { N }]; @@ -32,15 +30,17 @@ fn repeats() { let _4 = [(); 1 + 1]; //~^ ERROR: complex const arguments must be placed inside of a `const` block let _5 = [(); const { 1 + 1 }]; + let _6: [(); const { N }] = todo!(); + //~^ ERROR: generic parameters may not be used in const operations } #[type_const] const ITEM1: usize = N; #[type_const] const ITEM2: usize = { N }; -// explicit_anon_consts-4.rs -// #[type_const] -// const ITEM3: usize = const { N }; +#[type_const] +const ITEM3: usize = const { N }; +//~^ ERROR: generic parameters may not be used in const operations #[type_const] const ITEM4: usize = { 1 + 1 }; //~^ ERROR: complex const arguments must be placed inside of a `const` block @@ -57,8 +57,8 @@ fn ace_bounds< // We skip the T1 case because it doesn't resolve // T1: Trait, T2: Trait, - // explicit_anon_consts-5.rs - // T3: Trait, + T3: Trait, + //~^ ERROR: generic parameters may not be used in const operations T4: Trait, //~^ ERROR: complex const arguments must be placed inside of a `const` block T5: Trait, @@ -66,8 +66,8 @@ fn ace_bounds< struct Default1; struct Default2; -// explicit_anon_consts-6.rs -// struct Default3; +struct Default3; +//~^ ERROR: generic parameters may not be used in const operations struct Default4; //~^ ERROR: complex const arguments must be placed inside of a `const` block struct Default5; diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index 1605dd8069d0..551815c4c31a 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -1,17 +1,17 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:15:33 + --> $DIR/explicit_anon_consts.rs:13:33 | LL | type Adt4 = Foo<{ 1 + 1 }>; | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:23:34 + --> $DIR/explicit_anon_consts.rs:21:34 | LL | type Arr4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:32:19 + --> $DIR/explicit_anon_consts.rs:30:19 | LL | let _4 = [(); 1 + 1]; | ^^^^^ @@ -35,10 +35,46 @@ LL | struct Default4; | ^^^^^^^^^ error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:30:27 + --> $DIR/explicit_anon_consts.rs:42:46 + | +LL | const ITEM3: usize = const { N }; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:60:31 + | +LL | T3: Trait, + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:69:58 + | +LL | struct Default3; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:28:27 | LL | let _3 = [(); const { N }]; | ^ -error: aborting due to 7 previous errors +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:33:26 + | +LL | let _6: [(); const { N }] = todo!(); + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:11:41 + | +LL | type Adt3 = Foo; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:19:42 + | +LL | type Arr3 = [(); const { N }]; + | ^ + +error: aborting due to 13 previous errors From a3e6de6e81977797fb885e9004a15901d88c7c82 Mon Sep 17 00:00:00 2001 From: Alessio Date: Fri, 2 Jan 2026 03:21:59 +0100 Subject: [PATCH 1480/3801] docs: fix typo in AsMut documentation Corrected "work" to "works", and "byte vector" to "a byte vector" to match the phrasing of "a byte slice" in the documentation of the trait `AsMut` Fixes https://github.com/rust-lang/rust/issues/149609 --- library/core/src/convert/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 89cda30c0303..ef4ab15f93c0 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -308,8 +308,8 @@ pub const trait AsRef: PointeeSized { /// both `AsMut>` and `AsMut<[T]>`. /// /// In the following, the example functions `caesar` and `null_terminate` provide a generic -/// interface which work with any type that can be converted by cheap mutable-to-mutable conversion -/// into a byte slice (`[u8]`) or byte vector (`Vec`), respectively. +/// interface which works with any type that can be converted by cheap mutable-to-mutable conversion +/// into a byte slice (`[u8]`) or a byte vector (`Vec`), respectively. /// /// [dereference]: core::ops::DerefMut /// [target type]: core::ops::Deref::Target From 66c4ead02dda94846a0801cc88c04fb04cc561fe Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Fri, 2 Jan 2026 12:52:42 +1030 Subject: [PATCH 1481/3801] fix: added further `CHECK-SAME` labels and replaced all `struct` input tests with `NonZero` input --- .../issues/multiple-option-or-permutations.rs | 82 +++++++++++-------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs index 9fbd77166534..b45402f28a3a 100644 --- a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs +++ b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs @@ -3,12 +3,16 @@ #![crate_type = "lib"] +extern crate core; +use core::num::NonZero; + // CHECK-LABEL: @or_match_u8 +// CHECK-SAME: (i1{{.+}}%0, i8 %1, i1{{.+}}%optb.0, i8 %optb.1) #[no_mangle] pub fn or_match_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-NEXT: or i1 %0 - // CHECK-NEXT: select i1 %0 + // CHECK-DAG: or i1 %0 + // CHECK-DAG: select i1 %0 // CHECK-NEXT: insertvalue { i1, i8 } // CHECK-NEXT: insertvalue { i1, i8 } // ret { i1, i8 } @@ -23,8 +27,8 @@ pub fn or_match_u8(opta: Option, optb: Option) -> Option { #[no_mangle] pub fn or_match_alt_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-NEXT: select i1 - // CHECK-NEXT: or i1 + // CHECK-DAG: select i1 + // CHECK-DAG: or i1 // CHECK-NEXT: insertvalue { i1, i8 } // CHECK-NEXT: insertvalue { i1, i8 } // ret { i1, i8 } @@ -35,11 +39,12 @@ pub fn or_match_alt_u8(opta: Option, optb: Option) -> Option { } // CHECK-LABEL: @option_or_u8 +// CHECK-SAME: (i1{{.+}}%opta.0, i8 %opta.1, i1{{.+}}%optb.0, i8 %optb.1) #[no_mangle] pub fn option_or_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-NEXT: select i1 - // CHECK-NEXT: or i1 + // CHECK-DAG: select i1 + // CHECK-DAG: or i1 // CHECK-NEXT: insertvalue { i1, i8 } // CHECK-NEXT: insertvalue { i1, i8 } // ret { i1, i8 } @@ -47,17 +52,20 @@ pub fn option_or_u8(opta: Option, optb: Option) -> Option { } // CHECK-LABEL: @if_some_u8 +// CHECK-SAME: (i1{{.+}}%opta.0, i8 %opta.1, i1{{.+}}%optb.0, i8 %optb.1) #[no_mangle] pub fn if_some_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-NEXT: select i1 - // CHECK-NEXT: or i1 + // CHECK-DAG: select i1 + // CHECK-DAG: or i1 // CHECK-NEXT: insertvalue { i1, i8 } // CHECK-NEXT: insertvalue { i1, i8 } // ret { i1, i8 } if opta.is_some() { opta } else { optb } } +// Tests a case where an input is a type that is represented as `BackendRepr::Memory` + // CHECK-LABEL: @or_match_slice_u8 // CHECK-SAME: (i16 %0, i16 %1) #[no_mangle] @@ -73,6 +81,7 @@ pub fn or_match_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option } // CHECK-LABEL: @or_match_slice_alt_u8 +// CHECK-SAME: (i16 %0, i16 %1) #[no_mangle] pub fn or_match_slice_alt_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: @@ -86,6 +95,7 @@ pub fn or_match_slice_alt_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Op } // CHECK-LABEL: @option_or_slice_u8 +// CHECK-SAME: (i16 %0, i16 %1) #[no_mangle] pub fn option_or_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: @@ -96,6 +106,7 @@ pub fn option_or_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Optio } // CHECK-LABEL: @if_some_slice_u8 +// CHECK-SAME: (i16 %0, i16 %1) #[no_mangle] pub fn if_some_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: @@ -105,53 +116,60 @@ pub fn if_some_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option< if opta.is_some() { opta } else { optb } } -pub struct Test { - _a: u8, - _b: u8, -} +// Test a niche optimization case of `NonZero` -// CHECK-LABEL: @or_match_type +// CHECK-LABEL: @or_match_nz_u8 +// CHECK-SAME: (i8{{.+}}%0, i8{{.+}}%optb) #[no_mangle] -pub fn or_match_type(opta: Option, optb: Option) -> Option { +pub fn or_match_nz_u8(opta: Option>, optb: Option>) -> Option> { // CHECK: start: - // CHECK-NEXT: trunc i24 %0 to i1 - // CHECK-NEXT: select i1 %2, i24 %0, i24 %1 - // ret i24 + // CHECK-NEXT: [[NOT_A:%.*]] = icmp eq i8 %0, 0 + // CHECK-NEXT: select i1 [[NOT_A]], i8 %optb, i8 %0 + // ret i8 match opta { Some(x) => Some(x), None => optb, } } -// CHECK-LABEL: @or_match_alt_type +// CHECK-LABEL: @or_match_alt_nz_u8 +// CHECK-SAME: (i8{{.+}}%opta, i8{{.+}}%optb) #[no_mangle] -pub fn or_match_alt_type(opta: Option, optb: Option) -> Option { +pub fn or_match_alt_nz_u8( + opta: Option>, + optb: Option>, +) -> Option> { // CHECK: start: - // CHECK-NEXT: trunc i24 %0 to i1 - // CHECK-NEXT: select i1 %2, i24 %0, i24 %1 - // ret i24 + // CHECK-NEXT: [[NOT_A:%.*]] = icmp eq i8 %opta, 0 + // CHECK-NEXT: select i1 [[NOT_A]], i8 %optb, i8 %opta + // ret i8 match opta { Some(_) => opta, None => optb, } } -// CHECK-LABEL: @option_or_type +// CHECK-LABEL: @option_or_nz_u8 +// CHECK-SAME: (i8{{.+}}%opta, i8{{.+}}%optb) #[no_mangle] -pub fn option_or_type(opta: Option, optb: Option) -> Option { +pub fn option_or_nz_u8( + opta: Option>, + optb: Option>, +) -> Option> { // CHECK: start: - // CHECK-NEXT: trunc i24 %0 to i1 - // CHECK-NEXT: select i1 %2, i24 %0, i24 %1 - // ret i24 + // CHECK-NEXT: [[NOT_A:%.*]] = icmp eq i8 %opta, 0 + // CHECK-NEXT: select i1 [[NOT_A]], i8 %optb, i8 %opta + // ret i8 opta.or(optb) } -// CHECK-LABEL: @if_some_type +// CHECK-LABEL: @if_some_nz_u8 +// CHECK-SAME: (i8{{.+}}%opta, i8{{.+}}%optb) #[no_mangle] -pub fn if_some_type(opta: Option, optb: Option) -> Option { +pub fn if_some_nz_u8(opta: Option>, optb: Option>) -> Option> { // CHECK: start: - // CHECK-NEXT: trunc i24 %0 to i1 - // CHECK-NEXT: select i1 %2, i24 %0, i24 %1 - // ret i24 + // CHECK-NEXT: [[NOT_A:%.*]] = icmp eq i8 %opta, 0 + // CHECK-NEXT: select i1 [[NOT_A]], i8 %optb, i8 %opta + // ret i8 if opta.is_some() { opta } else { optb } } From 91e169b1c9e236774bc77683aedf145236ecc8fd Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 2 Jan 2026 13:30:04 +1100 Subject: [PATCH 1482/3801] Use clearer variable names in equality-test lowering --- .../src/builder/matches/test.rs | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 972d9f66fadd..3f402b2ae414 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -141,17 +141,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate(block, self.source_info(match_start_span), terminator); } - TestKind::Eq { value, mut cast_ty } => { + TestKind::Eq { value, cast_ty: pat_ty } => { let tcx = self.tcx; let success_block = target_block(TestBranch::Success); let fail_block = target_block(TestBranch::Failure); - let mut expect_ty = value.ty; - let mut expect = self.literal_operand(test.span, Const::from_ty_value(tcx, value)); + let mut expected_value_ty = value.ty; + let mut expected_value_operand = + self.literal_operand(test.span, Const::from_ty_value(tcx, value)); - let mut place = place; + let mut actual_value_ty = pat_ty; + let mut actual_value_place = place; - match cast_ty.kind() { + match pat_ty.kind() { ty::Str => { // String literal patterns may have type `str` if `deref_patterns` is // enabled, in order to allow `deref!("..."): String`. In this case, `value` @@ -172,11 +174,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ref_place, Rvalue::Ref(re_erased, BorrowKind::Shared, place), ); - place = ref_place; - cast_ty = ref_str_ty; + actual_value_place = ref_place; + actual_value_ty = ref_str_ty; } &ty::Pat(base, _) => { - assert_eq!(cast_ty, value.ty); + assert_eq!(pat_ty, value.ty); assert!(base.is_trivially_pure_clone_copy()); let transmuted_place = self.temp(base, test.span); @@ -184,7 +186,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, self.source_info(scrutinee_span), transmuted_place, - Rvalue::Cast(CastKind::Transmute, Operand::Copy(place), base), + Rvalue::Cast( + CastKind::Transmute, + Operand::Copy(actual_value_place), + base, + ), ); let transmuted_expect = self.temp(base, test.span); @@ -192,19 +198,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, self.source_info(test.span), transmuted_expect, - Rvalue::Cast(CastKind::Transmute, expect, base), + Rvalue::Cast(CastKind::Transmute, expected_value_operand, base), ); - place = transmuted_place; - expect = Operand::Copy(transmuted_expect); - cast_ty = base; - expect_ty = base; + actual_value_place = transmuted_place; + actual_value_ty = base; + expected_value_operand = Operand::Copy(transmuted_expect); + expected_value_ty = base; } _ => {} } - assert_eq!(expect_ty, cast_ty); - if !cast_ty.is_scalar() { + assert_eq!(expected_value_ty, actual_value_ty); + if !actual_value_ty.is_scalar() { // Use `PartialEq::eq` instead of `BinOp::Eq` // (the binop can only handle primitives) // Make sure that we do *not* call any user-defined code here. @@ -212,12 +218,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // comparison defined in `core`. // (Interestingly this means that exhaustiveness analysis relies, for soundness, // on the `PartialEq` impl for `str` to b correct!) - match *cast_ty.kind() { + match *actual_value_ty.kind() { ty::Ref(_, deref_ty, _) if deref_ty == self.tcx.types.str_ => {} _ => { span_bug!( source_info.span, - "invalid type for non-scalar compare: {cast_ty}" + "invalid type for non-scalar compare: {actual_value_ty}" ) } }; @@ -226,8 +232,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { success_block, fail_block, source_info, - expect, - Operand::Copy(place), + expected_value_operand, + Operand::Copy(actual_value_place), ); } else { self.compare( @@ -236,8 +242,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fail_block, source_info, BinOp::Eq, - expect, - Operand::Copy(place), + expected_value_operand, + Operand::Copy(actual_value_place), ); } } From d68c980c22d95c95ce97b82d03cfd9d48badce30 Mon Sep 17 00:00:00 2001 From: Alessio Date: Fri, 2 Jan 2026 03:53:02 +0100 Subject: [PATCH 1483/3801] library: Document panic condition for `Iterator::last` Added a `# Panics` section to `Iterator::last` to match `Iterator::count`, after the change made in Rust 1.92.0 where now `std::iter::Repeat` panics in these methods instead of doing an infinite `loop`. Cites https://github.com/rust-lang/rust/issues/149707 --- library/core/src/iter/traits/iterator.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 29230b166538..84da778c3b91 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -236,6 +236,11 @@ pub trait Iterator { /// doing so, it keeps track of the current element. After [`None`] is /// returned, `last()` will then return the last element it saw. /// + /// # Panics + /// + /// This function might panic if the iterator has more than [`usize::MAX`] + /// elements. + /// /// # Examples /// /// ``` From 3c7c4398121b5752431ea2727534b87e434ebc10 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 2 Jan 2026 13:32:49 +1100 Subject: [PATCH 1484/3801] Split out a separate `PatConstKind::String` --- compiler/rustc_middle/src/ty/sty.rs | 6 +++++ .../src/builder/matches/buckets.rs | 9 ++++++-- .../src/builder/matches/match_pair.rs | 15 +++++++++++- .../src/builder/matches/mod.rs | 23 ++++++++++++------- .../src/builder/matches/test.rs | 10 ++++---- 5 files changed, 47 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c3834607e923..c282f2211f65 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1218,6 +1218,12 @@ impl<'tcx> Ty<'tcx> { *self.kind() == Str } + /// Returns true if this type is `&str`. The reference's lifetime is ignored. + #[inline] + pub fn is_imm_ref_str(self) -> bool { + matches!(self.kind(), ty::Ref(_, inner, hir::Mutability::Not) if inner.is_str()) + } + #[inline] pub fn is_param(self, index: u32) -> bool { match self.kind() { diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs index fce35aa9ef30..0d2e9bf87585 100644 --- a/compiler/rustc_mir_build/src/builder/matches/buckets.rs +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -314,7 +314,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ( - TestKind::Eq { value: test_val, .. }, + TestKind::StringEq { value: test_val, .. }, + TestableCase::Constant { value: case_val, kind: PatConstKind::String }, + ) + | ( + TestKind::ScalarEq { value: test_val, .. }, TestableCase::Constant { value: case_val, kind: PatConstKind::Float | PatConstKind::Other, @@ -347,7 +351,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | TestKind::If | TestKind::SliceLen { .. } | TestKind::Range { .. } - | TestKind::Eq { .. } + | TestKind::StringEq { .. } + | TestKind::ScalarEq { .. } | TestKind::Deref { .. }, _, ) => { diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 386ca61a6124..f0114c2193c3 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use rustc_abi::FieldIdx; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::thir::*; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; @@ -173,9 +174,21 @@ impl<'tcx> MatchPairTree<'tcx> { PatConstKind::IntOrChar } else if pat_ty.is_floating_point() { PatConstKind::Float + } else if pat_ty.is_str() { + // Deref-patterns can cause string-literal patterns to have + // type `str` instead of the usual `&str`. + if !cx.tcx.features().deref_patterns() { + span_bug!( + pattern.span, + "const pattern has type `str` but deref_patterns is not enabled" + ); + } + PatConstKind::String + } else if pat_ty.is_imm_ref_str() { + PatConstKind::String } else { // FIXME(Zalathar): This still covers several different - // categories (e.g. raw pointer, string, pattern-type) + // categories (e.g. raw pointer, pattern-type) // which could be split out into their own kinds. PatConstKind::Other }; diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 421065a89411..9080e2ba801b 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1290,9 +1290,10 @@ enum PatConstKind { /// These types don't support `SwitchInt` and require an equality test, /// but can also interact with range pattern tests. Float, + /// Constant string values, tested via string equality. + String, /// Any other constant-pattern is usually tested via some kind of equality /// check. Types that might be encountered here include: - /// - `&str` /// - raw pointers derived from integer values /// - pattern types, e.g. `pattern_type!(u32 is 1..)` Other, @@ -1368,14 +1369,20 @@ enum TestKind<'tcx> { /// Test whether a `bool` is `true` or `false`. If, - /// Test for equality with value, possibly after an unsizing coercion to - /// `cast_ty`, - Eq { + /// Tests the place against a string constant using string equality. + StringEq { + /// Constant `&str` value to test against. value: ty::Value<'tcx>, - // Integer types are handled by `SwitchInt`, and constants with ADT - // types and `&[T]` types are converted back into patterns, so this can - // only be `&str` or floats. - cast_ty: Ty<'tcx>, + /// Type of the corresponding pattern node. Usually `&str`, but could + /// be `str` for patterns like `deref!("..."): String`. + pat_ty: Ty<'tcx>, + }, + + /// Tests the place against a constant using scalar equality. + ScalarEq { + value: ty::Value<'tcx>, + /// Type of the corresponding pattern node. + pat_ty: Ty<'tcx>, }, /// Test whether the value falls within an inclusive or exclusive range. diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 3f402b2ae414..cb0e28c7234f 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -38,11 +38,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TestableCase::Constant { value: _, kind: PatConstKind::IntOrChar } => { TestKind::SwitchInt } - TestableCase::Constant { value, kind: PatConstKind::Float } => { - TestKind::Eq { value, cast_ty: match_pair.pattern_ty } + TestableCase::Constant { value, kind: PatConstKind::String } => { + TestKind::StringEq { value, pat_ty: match_pair.pattern_ty } } - TestableCase::Constant { value, kind: PatConstKind::Other } => { - TestKind::Eq { value, cast_ty: match_pair.pattern_ty } + TestableCase::Constant { value, kind: PatConstKind::Float | PatConstKind::Other } => { + TestKind::ScalarEq { value, pat_ty: match_pair.pattern_ty } } TestableCase::Range(ref range) => { @@ -141,7 +141,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate(block, self.source_info(match_start_span), terminator); } - TestKind::Eq { value, cast_ty: pat_ty } => { + TestKind::StringEq { value, pat_ty } | TestKind::ScalarEq { value, pat_ty } => { let tcx = self.tcx; let success_block = target_block(TestBranch::Success); let fail_block = target_block(TestBranch::Failure); From 7749e75677c55900235f5196cd9921215f555465 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 2 Jan 2026 13:36:01 +1100 Subject: [PATCH 1485/3801] Split the cases for lowering string-equality and scalar-equality tests --- .../src/builder/matches/test.rs | 85 ++++++++++--------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index cb0e28c7234f..c2e39d47a92c 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -141,13 +141,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate(block, self.source_info(match_start_span), terminator); } - TestKind::StringEq { value, pat_ty } | TestKind::ScalarEq { value, pat_ty } => { + TestKind::StringEq { value, pat_ty } => { let tcx = self.tcx; let success_block = target_block(TestBranch::Success); let fail_block = target_block(TestBranch::Failure); - let mut expected_value_ty = value.ty; - let mut expected_value_operand = + let expected_value_ty = value.ty; + let expected_value_operand = self.literal_operand(test.span, Const::from_ty_value(tcx, value)); let mut actual_value_ty = pat_ty; @@ -177,6 +177,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { actual_value_place = ref_place; actual_value_ty = ref_str_ty; } + _ => {} + } + + assert_eq!(expected_value_ty, actual_value_ty); + assert!(actual_value_ty.is_imm_ref_str()); + + // Compare two strings using `::eq`. + // (Interestingly this means that exhaustiveness analysis relies, for soundness, + // on the `PartialEq` impl for `str` to be correct!) + self.string_compare( + block, + success_block, + fail_block, + source_info, + expected_value_operand, + Operand::Copy(actual_value_place), + ); + } + + TestKind::ScalarEq { value, pat_ty } => { + let tcx = self.tcx; + let success_block = target_block(TestBranch::Success); + let fail_block = target_block(TestBranch::Failure); + + let mut expected_value_ty = value.ty; + let mut expected_value_operand = + self.literal_operand(test.span, Const::from_ty_value(tcx, value)); + + let mut actual_value_ty = pat_ty; + let mut actual_value_place = place; + + match pat_ty.kind() { &ty::Pat(base, _) => { assert_eq!(pat_ty, value.ty); assert!(base.is_trivially_pure_clone_copy()); @@ -210,42 +242,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } assert_eq!(expected_value_ty, actual_value_ty); - if !actual_value_ty.is_scalar() { - // Use `PartialEq::eq` instead of `BinOp::Eq` - // (the binop can only handle primitives) - // Make sure that we do *not* call any user-defined code here. - // The only type that can end up here is string literals, which have their - // comparison defined in `core`. - // (Interestingly this means that exhaustiveness analysis relies, for soundness, - // on the `PartialEq` impl for `str` to b correct!) - match *actual_value_ty.kind() { - ty::Ref(_, deref_ty, _) if deref_ty == self.tcx.types.str_ => {} - _ => { - span_bug!( - source_info.span, - "invalid type for non-scalar compare: {actual_value_ty}" - ) - } - }; - self.string_compare( - block, - success_block, - fail_block, - source_info, - expected_value_operand, - Operand::Copy(actual_value_place), - ); - } else { - self.compare( - block, - success_block, - fail_block, - source_info, - BinOp::Eq, - expected_value_operand, - Operand::Copy(actual_value_place), - ); - } + assert!(actual_value_ty.is_scalar()); + + self.compare( + block, + success_block, + fail_block, + source_info, + BinOp::Eq, + expected_value_operand, + Operand::Copy(actual_value_place), + ); } TestKind::Range(ref range) => { From aa4ec54dfe9e63f146847265ed0655ffa9027cea Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 2 Jan 2026 04:52:22 +0000 Subject: [PATCH 1486/3801] fix: `cmp_owned` wrongly unmangled macros --- clippy_lints/src/operators/cmp_owned.rs | 58 +++++++++-------------- tests/ui/cmp_owned/with_suggestion.fixed | 29 ++++++++++++ tests/ui/cmp_owned/with_suggestion.rs | 29 ++++++++++++ tests/ui/cmp_owned/with_suggestion.stderr | 8 +++- 4 files changed, 87 insertions(+), 37 deletions(-) diff --git a/clippy_lints/src/operators/cmp_owned.rs b/clippy_lints/src/operators/cmp_owned.rs index 05358de5b348..39097833a6c5 100644 --- a/clippy_lints/src/operators/cmp_owned.rs +++ b/clippy_lints/src/operators/cmp_owned.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeQPath; -use clippy_utils::source::snippet; +use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{implements_trait, is_copy}; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; @@ -94,51 +94,37 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) return; } - let arg_snip = snippet(cx, arg_span, ".."); - let expr_snip; - let eq_impl; - if with_deref.is_implemented() && !arg_ty.peel_refs().is_str() { - expr_snip = format!("*{arg_snip}"); - eq_impl = with_deref; + let mut applicability = Applicability::MachineApplicable; + let (arg_snip, _) = snippet_with_context(cx, arg_span, expr.span.ctxt(), "..", &mut applicability); + let (expr_snip, eq_impl) = if with_deref.is_implemented() && !arg_ty.peel_refs().is_str() { + (format!("*{arg_snip}"), with_deref) } else { - expr_snip = arg_snip.to_string(); - eq_impl = without_deref; - } + (arg_snip.to_string(), without_deref) + }; - let span; - let hint; - if (eq_impl.ty_eq_other && left) || (eq_impl.other_eq_ty && !left) { - span = expr.span; - hint = expr_snip; + let (span, hint) = if (eq_impl.ty_eq_other && left) || (eq_impl.other_eq_ty && !left) { + (expr.span, expr_snip) } else { - span = expr.span.to(other.span); + let span = expr.span.to(other.span); let cmp_span = if other.span < expr.span { other.span.between(expr.span) } else { expr.span.between(other.span) }; - if eq_impl.ty_eq_other { - hint = format!( - "{expr_snip}{}{}", - snippet(cx, cmp_span, ".."), - snippet(cx, other.span, "..") - ); - } else { - hint = format!( - "{}{}{expr_snip}", - snippet(cx, other.span, ".."), - snippet(cx, cmp_span, "..") - ); - } - } - diag.span_suggestion( - span, - "try", - hint, - Applicability::MachineApplicable, // snippet - ); + let (cmp_snippet, _) = snippet_with_context(cx, cmp_span, expr.span.ctxt(), "..", &mut applicability); + let (other_snippet, _) = + snippet_with_context(cx, other.span, expr.span.ctxt(), "..", &mut applicability); + + if eq_impl.ty_eq_other { + (span, format!("{expr_snip}{cmp_snippet}{other_snippet}")) + } else { + (span, format!("{other_snippet}{cmp_snippet}{expr_snip}")) + } + }; + + diag.span_suggestion(span, "try", hint, applicability); }, ); } diff --git a/tests/ui/cmp_owned/with_suggestion.fixed b/tests/ui/cmp_owned/with_suggestion.fixed index 85d0991bef05..4c3b13b30043 100644 --- a/tests/ui/cmp_owned/with_suggestion.fixed +++ b/tests/ui/cmp_owned/with_suggestion.fixed @@ -83,3 +83,32 @@ fn issue_8103() { let _ = foo1 == foo2; //~^ cmp_owned } + +macro_rules! issue16322_macro_generator { + ($locale:ident) => { + mod $locale { + macro_rules! _make { + ($token:tt) => { + stringify!($token) + }; + } + + pub(crate) use _make; + } + + macro_rules! t { + ($token:tt) => { + crate::$locale::_make!($token) + }; + } + }; +} + +issue16322_macro_generator!(de); + +fn issue16322(item: String) { + if item == t!(frohes_neu_Jahr) { + //~^ cmp_owned + println!("Ja!"); + } +} diff --git a/tests/ui/cmp_owned/with_suggestion.rs b/tests/ui/cmp_owned/with_suggestion.rs index 2393757d76f2..a9d7509feaaf 100644 --- a/tests/ui/cmp_owned/with_suggestion.rs +++ b/tests/ui/cmp_owned/with_suggestion.rs @@ -83,3 +83,32 @@ fn issue_8103() { let _ = foo1 == foo2.to_owned(); //~^ cmp_owned } + +macro_rules! issue16322_macro_generator { + ($locale:ident) => { + mod $locale { + macro_rules! _make { + ($token:tt) => { + stringify!($token) + }; + } + + pub(crate) use _make; + } + + macro_rules! t { + ($token:tt) => { + crate::$locale::_make!($token) + }; + } + }; +} + +issue16322_macro_generator!(de); + +fn issue16322(item: String) { + if item == t!(frohes_neu_Jahr).to_string() { + //~^ cmp_owned + println!("Ja!"); + } +} diff --git a/tests/ui/cmp_owned/with_suggestion.stderr b/tests/ui/cmp_owned/with_suggestion.stderr index dd9ffa70897a..66544ce0c217 100644 --- a/tests/ui/cmp_owned/with_suggestion.stderr +++ b/tests/ui/cmp_owned/with_suggestion.stderr @@ -49,5 +49,11 @@ error: this creates an owned instance just for comparison LL | let _ = foo1 == foo2.to_owned(); | ^^^^^^^^^^^^^^^ help: try: `foo2` -error: aborting due to 8 previous errors +error: this creates an owned instance just for comparison + --> tests/ui/cmp_owned/with_suggestion.rs:110:16 + | +LL | if item == t!(frohes_neu_Jahr).to_string() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t!(frohes_neu_Jahr)` + +error: aborting due to 9 previous errors From 2c31b0deb13d9d49ea4b651b81765b9acb446d5a Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 2 Jan 2026 15:59:03 +0900 Subject: [PATCH 1487/3801] check if redundant args spans belong to the same context --- .../errors/wrong_number_of_generic_args.rs | 3 ++ .../generics/wrong-number-of-args-in-macro.rs | 15 +++++++ .../wrong-number-of-args-in-macro.stderr | 44 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 tests/ui/generics/wrong-number-of-args-in-macro.rs create mode 100644 tests/ui/generics/wrong-number-of-args-in-macro.stderr diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index d835a7bbb8d2..2b7854769b42 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -988,6 +988,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { gen_arg_spans[self.num_expected_type_or_const_args() - 1] }; let span_hi_redundant_type_or_const_args = gen_arg_spans[gen_arg_spans.len() - 1]; + if !span_lo_redundant_type_or_const_args.eq_ctxt(span_hi_redundant_type_or_const_args) { + return; + } let span_redundant_type_or_const_args = span_lo_redundant_type_or_const_args .shrink_to_hi() .to(span_hi_redundant_type_or_const_args); diff --git a/tests/ui/generics/wrong-number-of-args-in-macro.rs b/tests/ui/generics/wrong-number-of-args-in-macro.rs new file mode 100644 index 000000000000..953e05434d25 --- /dev/null +++ b/tests/ui/generics/wrong-number-of-args-in-macro.rs @@ -0,0 +1,15 @@ +// Regression test for #149559 + +struct Foo; //~ ERROR type parameter `T` is never used + +macro_rules! foo_ty { + ($a:ty, $b:ty) => { + Foo + //~^ ERROR cannot find type `a` in this scope + //~| ERROR struct takes 1 generic argument but 2 generic arguments were supplied + }; +} + +fn foo<'a, 'b>() -> foo_ty!(&'b (), &'b ()) {} + +fn main() {} diff --git a/tests/ui/generics/wrong-number-of-args-in-macro.stderr b/tests/ui/generics/wrong-number-of-args-in-macro.stderr new file mode 100644 index 000000000000..62a5eb9414ed --- /dev/null +++ b/tests/ui/generics/wrong-number-of-args-in-macro.stderr @@ -0,0 +1,44 @@ +error[E0425]: cannot find type `a` in this scope + --> $DIR/wrong-number-of-args-in-macro.rs:7:13 + | +LL | Foo + | ^ not found in this scope +... +LL | fn foo<'a, 'b>() -> foo_ty!(&'b (), &'b ()) {} + | ----------------------- in this macro invocation + | + = note: this error originates in the macro `foo_ty` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you might be missing a type parameter + | +LL | fn foo<'a, 'b, a>() -> foo_ty!(&'b (), &'b ()) {} + | +++ + +error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied + --> $DIR/wrong-number-of-args-in-macro.rs:7:9 + | +LL | Foo + | ^^^ expected 1 generic argument +... +LL | fn foo<'a, 'b>() -> foo_ty!(&'b (), &'b ()) {} + | ----------------------- in this macro invocation + | +note: struct defined here, with 1 generic parameter: `T` + --> $DIR/wrong-number-of-args-in-macro.rs:3:8 + | +LL | struct Foo; + | ^^^ - + = note: this error originates in the macro `foo_ty` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0392]: type parameter `T` is never used + --> $DIR/wrong-number-of-args-in-macro.rs:3:12 + | +LL | struct Foo; + | ^ unused type parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0392, E0425. +For more information about an error, try `rustc --explain E0107`. From 7668154418edb8e61c1cec5e5ff05e5430f73d34 Mon Sep 17 00:00:00 2001 From: Aaryan Agrawal Date: Fri, 2 Jan 2026 14:09:39 +0530 Subject: [PATCH 1488/3801] triagebot: add autolabel for rustdoc JS files --- triagebot.toml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index fb6660b9dd03..b17c76adf33b 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -332,6 +332,14 @@ trigger_labels = [ "A-type-based-search", ] +[autolabel."A-rustdoc-js"] +trigger_files = [ + "src/librustdoc/html/static/js/", + "src/librustdoc/html/static/css/", + "tests/rustdoc-js/", + "tests/rustdoc-js-std/", +] + [autolabel."T-compiler"] trigger_files = [ # Source code From 7b8d4c602ee8af316ef06838fafbc1c4da940550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 31 Dec 2025 11:11:44 +0100 Subject: [PATCH 1489/3801] Rename the `gcc` component to `gcc-dev` To free up the `gcc` name for the actual libgccjit component that we will ship to rustup, and also make it more explicit that this component is internal and for bootstrap usages only. --- src/bootstrap/src/core/build_steps/dist.rs | 14 ++++++++------ src/bootstrap/src/core/builder/mod.rs | 2 +- src/bootstrap/src/core/download.rs | 2 +- .../docker/host-x86_64/dist-x86_64-linux/dist.sh | 4 ++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index b9ec063f4352..46cf7aed383b 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2871,24 +2871,26 @@ impl Step for ReproducibleArtifacts { /// Tarball containing a prebuilt version of the libgccjit library, /// needed as a dependency for the GCC codegen backend (similarly to the LLVM /// backend needing a prebuilt libLLVM). +/// +/// This component is used for `download-ci-gcc`. #[derive(Clone, Debug, Eq, Hash, PartialEq)] -pub struct Gcc { +pub struct GccDev { target: TargetSelection, } -impl Step for Gcc { +impl Step for GccDev { type Output = GeneratedTarball; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.alias("gcc") + run.alias("gcc-dev") } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Gcc { target: run.target }); + run.builder.ensure(GccDev { target: run.target }); } fn run(self, builder: &Builder<'_>) -> Self::Output { - let tarball = Tarball::new(builder, "gcc", &self.target.triple); + let tarball = Tarball::new(builder, "gcc-dev", &self.target.triple); let output = builder .ensure(super::gcc::Gcc { target_pair: GccTargetPair::for_native_build(self.target) }); tarball.add_file(output.libgccjit(), "lib", FileType::NativeLibrary); @@ -2896,6 +2898,6 @@ impl Step for Gcc { } fn metadata(&self) -> Option { - Some(StepMetadata::dist("gcc", self.target)) + Some(StepMetadata::dist("gcc-dev", self.target)) } } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 7d2b1685bda9..92a6eb8ce837 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -989,7 +989,7 @@ impl<'a> Builder<'a> { dist::PlainSourceTarballGpl, dist::BuildManifest, dist::ReproducibleArtifacts, - dist::Gcc + dist::GccDev ), Kind::Install => describe!( install::Docs, diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index d950dc1a1c58..43efdcd7db17 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -381,7 +381,7 @@ impl Config { } let base = &self.stage0_metadata.config.artifacts_server; let version = self.artifact_version_part(gcc_sha); - let filename = format!("gcc-{version}-{}.tar.xz", self.host_target.triple); + let filename = format!("gcc-dev-{version}-{}.tar.xz", self.host_target.triple); let tarball = gcc_cache.join(&filename); if !tarball.exists() { let help_on_error = "ERROR: failed to download gcc from ci diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh index 4c95d4a401e5..9579e0d79cb0 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh @@ -9,8 +9,8 @@ python3 ../x.py build --set rust.debug=true opt-dist --include-default-paths \ build-manifest bootstrap -# Use GCC for building GCC, as it seems to behave badly when built with Clang +# Use GCC for building GCC components, as it seems to behave badly when built with Clang # Only build GCC on full builds, not try builds if [ "${DIST_TRY_BUILD:-0}" == "0" ]; then - CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc + CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc-dev fi From 4129f3aeef37e1ec9d79863f88ece1e13eeb9800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 31 Dec 2025 11:12:05 +0100 Subject: [PATCH 1490/3801] Temporarily disable `gcc.download-ci-gcc` Because we renamed the CI component. We will have to re-enable it in a follow-up PR. --- src/ci/run.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index b486f0525f40..425ad38a6655 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -187,8 +187,9 @@ else RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.static-libstdcpp" fi - # Download GCC from CI on test builders - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set gcc.download-ci-gcc=true" + # Download GCC from CI on test builders (temporarily disabled because the CI gcc component + # was renamed). + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set gcc.download-ci-gcc=false" # download-rustc seems to be broken on CI after the stage0 redesign # Disable it until these issues are debugged and resolved From 2a893bd67feeda40adc8fa962988703cda3199b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 31 Dec 2025 13:41:31 +0100 Subject: [PATCH 1491/3801] Remove unused GCC ignore in opt-dist The `CiGcc` step is not enabled by defaut, so it does not have to be skipped. --- src/tools/opt-dist/src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 48b25f235dd6..5515dbf1940e 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -454,7 +454,6 @@ fn main() -> anyhow::Result<()> { "clippy", "miri", "rustfmt", - "gcc", "generate-copyright", "bootstrap", ] { From 4b34f4f4fbc1cb43307d31ed349909c53843a6d1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 2 Jan 2026 10:19:02 +0100 Subject: [PATCH 1492/3801] minor: Fix some minor FIXMEs --- .../crates/hir-def/src/expr_store.rs | 8 ++++---- .../crates/hir-def/src/expr_store/expander.rs | 7 +------ .../crates/hir-def/src/expr_store/lower.rs | 19 +++++++++---------- .../src/expr_store/lower/format_args.rs | 3 ++- .../crates/hir-def/src/hir/generics.rs | 3 +-- .../hir-def/src/nameres/path_resolution.rs | 2 -- .../crates/hir-def/src/resolver.rs | 2 +- .../crates/hir/src/has_source.rs | 2 +- .../crates/rust-analyzer/src/lib.rs | 3 +++ 9 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs index 66f7e25ffac4..10cd460d1d36 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs @@ -57,8 +57,7 @@ impl HygieneId { Self(ctx) } - // FIXME: Inline this - pub(crate) fn lookup(self) -> SyntaxContext { + pub(crate) fn syntax_context(self) -> SyntaxContext { self.0 } @@ -73,7 +72,8 @@ pub type ExprSource = InFile; pub type PatPtr = AstPtr; pub type PatSource = InFile; -pub type LabelPtr = AstPtr; +/// BlockExpr -> Desugared label from try block +pub type LabelPtr = AstPtr>; pub type LabelSource = InFile; pub type FieldPtr = AstPtr; @@ -942,7 +942,7 @@ impl ExpressionStoreSourceMap { } pub fn node_label(&self, node: InFile<&ast::Label>) -> Option { - let src = node.map(AstPtr::new); + let src = node.map(AstPtr::new).map(AstPtr::wrap_left); self.expr_only()?.label_map.get(&src).cloned() } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs index 6a2f06b0a6f6..de5974fff1ad 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs @@ -11,7 +11,7 @@ use hir_expand::{ ExpandError, ExpandErrorKind, ExpandResult, HirFileId, InFile, Lookup, MacroCallId, eager::EagerCallBackFn, mod_path::ModPath, span_map::SpanMap, }; -use span::{AstIdMap, Edition, SyntaxContext}; +use span::{AstIdMap, SyntaxContext}; use syntax::ast::HasAttrs; use syntax::{AstNode, Parse, ast}; use triomphe::Arc; @@ -75,11 +75,6 @@ impl Expander { AttrFlags::is_cfg_enabled_for(owner, cfg_options) } - pub(super) fn call_syntax_ctx(&self) -> SyntaxContext { - // FIXME: - SyntaxContext::root(Edition::CURRENT_FIXME) - } - pub(super) fn enter_expand( &mut self, db: &dyn DefDatabase, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 42b076abb2a6..af274f1a485b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -1096,7 +1096,7 @@ impl<'db> ExprCollector<'db> { ast::Expr::WhileExpr(e) => self.collect_while_loop(syntax_ptr, e), ast::Expr::ForExpr(e) => self.collect_for_loop(syntax_ptr, e), ast::Expr::CallExpr(e) => { - // FIXME: Remove this once we drop support for <1.86, https://github.com/rust-lang/rust/commit/ac9cb908ac4301dfc25e7a2edee574320022ae2c + // FIXME(MINIMUM_SUPPORTED_TOOLCHAIN_VERSION): Remove this once we drop support for <1.86, https://github.com/rust-lang/rust/commit/ac9cb908ac4301dfc25e7a2edee574320022ae2c let is_rustc_box = { let attrs = e.attrs(); attrs.filter_map(|it| it.as_simple_atom()).any(|it| it == "rustc_box") @@ -1649,7 +1649,7 @@ impl<'db> ExprCollector<'db> { fn desugar_try_block(&mut self, e: BlockExpr) -> ExprId { let try_from_output = self.lang_path(self.lang_items().TryTraitFromOutput); let label = self.generate_new_name(); - let label = self.alloc_label_desugared(Label { name: label }); + let label = self.alloc_label_desugared(Label { name: label }, AstPtr::new(&e).wrap_right()); let old_label = self.current_try_block_label.replace(label); let ptr = AstPtr::new(&e).upcast(); @@ -2399,7 +2399,6 @@ impl<'db> ExprCollector<'db> { }; let start = range_part_lower(p.start()); let end = range_part_lower(p.end()); - // FIXME: Exclusive ended pattern range is stabilised match p.op_kind() { Some(range_type) => Pat::Range { start, end, range_type }, None => Pat::Missing, @@ -2519,9 +2518,9 @@ impl<'db> ExprCollector<'db> { let mut hygiene_info = if hygiene_id.is_root() { None } else { - hygiene_id.lookup().outer_expn(self.db).map(|expansion| { + hygiene_id.syntax_context().outer_expn(self.db).map(|expansion| { let expansion = self.db.lookup_intern_macro_call(expansion.into()); - (hygiene_id.lookup().parent(self.db), expansion.def) + (hygiene_id.syntax_context().parent(self.db), expansion.def) }) }; let name = Name::new_lifetime(&lifetime.text()); @@ -2727,17 +2726,17 @@ impl ExprCollector<'_> { self.store.pats.alloc(Pat::Missing) } - fn alloc_label(&mut self, label: Label, ptr: LabelPtr) -> LabelId { + fn alloc_label(&mut self, label: Label, ptr: AstPtr) -> LabelId { + self.alloc_label_desugared(label, ptr.wrap_left()) + } + + fn alloc_label_desugared(&mut self, label: Label, ptr: LabelPtr) -> LabelId { let src = self.expander.in_file(ptr); let id = self.store.labels.alloc(label); self.store.label_map_back.insert(id, src); self.store.label_map.insert(src, id); id } - // FIXME: desugared labels don't have ptr, that's wrong and should be fixed somehow. - fn alloc_label_desugared(&mut self, label: Label) -> LabelId { - self.store.labels.alloc(label) - } fn is_lowering_awaitable_block(&self) -> &Awaitable { self.awaitable_context.as_ref().unwrap_or(&Awaitable::No("unknown")) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs index 32c9df3dfefb..7ef84f27f664 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs @@ -3,6 +3,7 @@ use base_db::FxIndexSet; use hir_expand::name::Name; use intern::{Symbol, sym}; +use span::SyntaxContext; use syntax::{AstPtr, AstToken as _, ast}; use crate::{ @@ -49,7 +50,7 @@ impl<'db> ExprCollector<'db> { self.expand_macros_to_string(template.clone()).map(|it| (it, template)) }) { Some(((s, is_direct_literal), template)) => { - let call_ctx = self.expander.call_syntax_ctx(); + let call_ctx = SyntaxContext::root(self.def_map.edition()); let hygiene = self.hygiene_id_for(s.syntax().text_range()); let fmt = format_args::parse( &s, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs index 1a2d5ebba467..482cf36f95b0 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs @@ -20,8 +20,7 @@ pub type LocalLifetimeParamId = Idx; /// Data about a generic type parameter (to a function, struct, impl, ...). #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct TypeParamData { - /// [`None`] only if the type ref is an [`crate::type_ref::TypeRef::ImplTrait`]. FIXME: Might be better to just - /// make it always be a value, giving impl trait a special name. + /// [`None`] only if the type ref is an [`crate::type_ref::TypeRef::ImplTrait`]. pub name: Option, pub default: Option, pub provenance: TypeParamProvenance, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs index e4b1d2a98735..cf33cecf5fba 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs @@ -267,7 +267,6 @@ impl DefMap { // plain import or absolute path in 2015: crate-relative with // fallback to extern prelude (with the simplification in // rust-lang/rust#57745) - // FIXME there must be a nicer way to write this condition PathKind::Plain | PathKind::Abs if self.data.edition == Edition::Edition2015 && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => @@ -383,7 +382,6 @@ impl DefMap { // plain import or absolute path in 2015: crate-relative with // fallback to extern prelude (with the simplification in // rust-lang/rust#57745) - // FIXME there must be a nicer way to write this condition PathKind::Plain | PathKind::Abs if self.data.edition == Edition::Edition2015 && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 263f603a0bfb..f643ed31ad53 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -950,7 +950,7 @@ fn hygiene_info( hygiene_id: HygieneId, ) -> Option<(SyntaxContext, MacroDefId)> { if !hygiene_id.is_root() { - let ctx = hygiene_id.lookup(); + let ctx = hygiene_id.syntax_context(); ctx.outer_expn(db).map(|expansion| { let expansion = db.lookup_intern_macro_call(expansion.into()); (ctx.parent(db), expansion.def) diff --git a/src/tools/rust-analyzer/crates/hir/src/has_source.rs b/src/tools/rust-analyzer/crates/hir/src/has_source.rs index 09c5b1cca7f3..e032a16989ff 100644 --- a/src/tools/rust-analyzer/crates/hir/src/has_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/has_source.rs @@ -330,7 +330,7 @@ impl HasSource for Label { let (_body, source_map) = db.body_with_source_map(self.parent); let src = source_map.label_syntax(self.label_id); let root = src.file_syntax(db); - Some(src.map(|ast| ast.to_node(&root))) + src.map(|ast| ast.to_node(&root).left()).transpose() } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 971ae2a601f7..4a37bb34aba3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -16,6 +16,9 @@ extern crate rustc_driver as _; extern crate ra_ap_rustc_type_ir as rustc_type_ir; +/* + If you bump this, grep for `FIXME(MINIMUM_SUPPORTED_TOOLCHAIN_VERSION)` to check for old support code we can drop +*/ /// Any toolchain less than this version will likely not work with rust-analyzer built from this revision. pub const MINIMUM_SUPPORTED_TOOLCHAIN_VERSION: semver::Version = semver::Version { major: 1, From 31531b3665bba1a98740de4b9264901302b7255d Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 Jan 2026 17:26:41 +0800 Subject: [PATCH 1493/3801] Add regression tests for keyword-in-identifier-position recovery ICE ... in macro invocations. Issue: . --- .../kw-in-const-item-pos-recovery-149692.rs | 11 +++++++ ...w-in-const-item-pos-recovery-149692.stderr | 11 +++++++ .../macro/kw-in-item-pos-recovery-149692.rs | 19 ++++++++++++ .../kw-in-item-pos-recovery-149692.stderr | 29 +++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs create mode 100644 tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr create mode 100644 tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs create mode 100644 tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr diff --git a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs new file mode 100644 index 000000000000..58bb62bc4bf8 --- /dev/null +++ b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs @@ -0,0 +1,11 @@ +//! More test coverage for ; this test is +//! specifically for `const` items. + +macro_rules! m { + (const $id:item()) => {} +} + +m!(const Self()); +//~^ ERROR expected one of `!` or `::`, found `(` + +fn main() {} diff --git a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr new file mode 100644 index 000000000000..f9b73109dbb4 --- /dev/null +++ b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr @@ -0,0 +1,11 @@ +error: expected one of `!` or `::`, found `(` + --> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:14 + | +LL | (const $id:item()) => {} + | -------- while parsing argument for this `item` macro fragment +... +LL | m!(const Self()); + | ^ expected one of `!` or `::` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs new file mode 100644 index 000000000000..223864e33296 --- /dev/null +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs @@ -0,0 +1,19 @@ +//! Regression test for a diagnostic ICE where we tried to recover a keyword as the identifier when +//! we are already trying to recover a missing keyword before item. +//! +//! See . + +macro_rules! m { + ($id:item()) => {} +} + +m!(Self()); +//~^ ERROR expected one of `!` or `::`, found `(` + +m!(Self{}); +//~^ ERROR expected one of `!` or `::`, found `{` + +m!(crate()); +//~^ ERROR expected one of `!` or `::`, found `(` + +fn main() {} diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr new file mode 100644 index 000000000000..a65214b0d1f9 --- /dev/null +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr @@ -0,0 +1,29 @@ +error: expected one of `!` or `::`, found `(` + --> $DIR/kw-in-item-pos-recovery-149692.rs:10:8 + | +LL | ($id:item()) => {} + | -------- while parsing argument for this `item` macro fragment +... +LL | m!(Self()); + | ^ expected one of `!` or `::` + +error: expected one of `!` or `::`, found `{` + --> $DIR/kw-in-item-pos-recovery-149692.rs:13:8 + | +LL | ($id:item()) => {} + | -------- while parsing argument for this `item` macro fragment +... +LL | m!(Self{}); + | ^ expected one of `!` or `::` + +error: expected one of `!` or `::`, found `(` + --> $DIR/kw-in-item-pos-recovery-149692.rs:16:9 + | +LL | ($id:item()) => {} + | -------- while parsing argument for this `item` macro fragment +... +LL | m!(crate()); + | ^ expected one of `!` or `::` + +error: aborting due to 3 previous errors + From 79c47278f1ec8198cb8c0ed53eda46fc43b16a0d Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 2 Jan 2026 17:27:35 +0800 Subject: [PATCH 1494/3801] Don't try to recover keyword as non-keyword identifier There's no sensible recovery scheme here, giving up the recovery is the right thing to do. --- compiler/rustc_parse/src/parser/item.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 26f60c96aed6..ea713b3cdade 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -408,6 +408,7 @@ impl<'a> Parser<'a> { let insert_span = ident_span.shrink_to_lo(); let ident = if self.token.is_ident() + && self.token.is_non_reserved_ident() && (!is_const || self.look_ahead(1, |t| *t == token::OpenParen)) && self.look_ahead(1, |t| { matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen) From 979704dacdbb0ba839de2c3f73acee891be17a63 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 26 Oct 2025 16:18:50 +0800 Subject: [PATCH 1495/3801] Fix not applicable on statement for convert_to_guarded_return Fix not applicable in statement when exist else block Example --- ```rust fn main() { some_statements(); if$0 let Ok(x) = Err(92) { foo(x); } else { return; } some_statements(); } ``` **Before this PR** Assist not applicable **After this PR** ```rust fn main() { some_statements(); let Ok(x) = Err(92) else { return; }; foo(x); some_statements(); } ``` --- .../src/handlers/convert_to_guarded_return.rs | 72 ++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index 08b114072fd9..ea5c1637b760 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -95,7 +95,9 @@ fn if_expr_to_guarded_return( let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?; - if parent_block.tail_expr()? != if_expr.clone().into() { + if parent_block.tail_expr() != Some(if_expr.clone().into()) + && !(else_block.is_some() && ast::ExprStmt::can_cast(if_expr.syntax().parent()?.kind())) + { return None; } @@ -502,6 +504,36 @@ fn main() { ); } + #[test] + fn convert_if_let_has_else_block_in_statement() { + check_assist( + convert_to_guarded_return, + r#" +fn main() { + some_statements(); + if$0 let Ok(x) = Err(92) { + foo(x); + } else { + // needless comment + return; + } + some_statements(); +} +"#, + r#" +fn main() { + some_statements(); + let Ok(x) = Err(92) else { + // needless comment + return; + }; + foo(x); + some_statements(); +} +"#, + ); + } + #[test] fn convert_if_let_result_inside_let() { check_assist( @@ -1136,6 +1168,44 @@ fn main() { ); } + #[test] + fn ignore_else_if() { + check_assist_not_applicable( + convert_to_guarded_return, + r#" +fn main() { + some_statements(); + if cond { + () + } else if$0 let Ok(x) = Err(92) { + foo(x); + } else { + return; + } + some_statements(); +} +"#, + ); + } + + #[test] + fn ignore_if_inside_let() { + check_assist_not_applicable( + convert_to_guarded_return, + r#" +fn main() { + some_statements(); + let _ = if$0 let Ok(x) = Err(92) { + foo(x); + } else { + return; + } + some_statements(); +} +"#, + ); + } + #[test] fn ignore_let_else_branch() { check_assist_not_applicable( From 58e2610f713035778a562cb7131097a504096dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= Date: Sat, 27 Dec 2025 21:50:40 +0100 Subject: [PATCH 1496/3801] Expose workgroup/thread dims as intrinsic args --- .../src/builder/gpu_offload.rs | 72 ++++++++++++++++--- compiler/rustc_codegen_llvm/src/intrinsic.rs | 7 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 14 +++- library/core/src/intrinsics/mod.rs | 15 +++- src/doc/rustc-dev-guide/src/offload/usage.md | 2 +- .../codegen-llvm/gpu_offload/control_flow.rs | 9 ++- tests/codegen-llvm/gpu_offload/gpu_host.rs | 14 ++-- 7 files changed, 108 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index 5c4aa7da5143..fba92f996aa6 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -2,7 +2,9 @@ use std::ffi::CString; use llvm::Linkage::*; use rustc_abi::Align; +use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods}; +use rustc_middle::bug; use rustc_middle::ty::offload_meta::OffloadMetadata; use crate::builder::Builder; @@ -69,6 +71,57 @@ impl<'ll> OffloadGlobals<'ll> { } } +pub(crate) struct OffloadKernelDims<'ll> { + num_workgroups: &'ll Value, + threads_per_block: &'ll Value, + workgroup_dims: &'ll Value, + thread_dims: &'ll Value, +} + +impl<'ll> OffloadKernelDims<'ll> { + pub(crate) fn from_operands<'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, + workgroup_op: &OperandRef<'tcx, &'ll llvm::Value>, + thread_op: &OperandRef<'tcx, &'ll llvm::Value>, + ) -> Self { + let cx = builder.cx; + let arr_ty = cx.type_array(cx.type_i32(), 3); + let four = Align::from_bytes(4).unwrap(); + + let OperandValue::Ref(place) = workgroup_op.val else { + bug!("expected array operand by reference"); + }; + let workgroup_val = builder.load(arr_ty, place.llval, four); + + let OperandValue::Ref(place) = thread_op.val else { + bug!("expected array operand by reference"); + }; + let thread_val = builder.load(arr_ty, place.llval, four); + + fn mul_dim3<'ll, 'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, + arr: &'ll Value, + ) -> &'ll Value { + let x = builder.extract_value(arr, 0); + let y = builder.extract_value(arr, 1); + let z = builder.extract_value(arr, 2); + + let xy = builder.mul(x, y); + builder.mul(xy, z) + } + + let num_workgroups = mul_dim3(builder, workgroup_val); + let threads_per_block = mul_dim3(builder, thread_val); + + OffloadKernelDims { + workgroup_dims: workgroup_val, + thread_dims: thread_val, + num_workgroups, + threads_per_block, + } + } +} + // ; Function Attrs: nounwind // declare i32 @__tgt_target_kernel(ptr, i64, i32, i32, ptr, ptr) #2 fn generate_launcher<'ll>(cx: &CodegenCx<'ll, '_>) -> (&'ll llvm::Value, &'ll llvm::Type) { @@ -204,12 +257,12 @@ impl KernelArgsTy { num_args: u64, memtransfer_types: &'ll Value, geps: [&'ll Value; 3], + workgroup_dims: &'ll Value, + thread_dims: &'ll Value, ) -> [(Align, &'ll Value); 13] { let four = Align::from_bytes(4).expect("4 Byte alignment should work"); let eight = Align::EIGHT; - let ti32 = cx.type_i32(); - let ci32_0 = cx.get_const_i32(0); [ (four, cx.get_const_i32(KernelArgsTy::OFFLOAD_VERSION)), (four, cx.get_const_i32(num_args)), @@ -222,8 +275,8 @@ impl KernelArgsTy { (eight, cx.const_null(cx.type_ptr())), // dbg (eight, cx.get_const_i64(KernelArgsTy::TRIPCOUNT)), (eight, cx.get_const_i64(KernelArgsTy::FLAGS)), - (four, cx.const_array(ti32, &[cx.get_const_i32(2097152), ci32_0, ci32_0])), - (four, cx.const_array(ti32, &[cx.get_const_i32(256), ci32_0, ci32_0])), + (four, workgroup_dims), + (four, thread_dims), (four, cx.get_const_i32(0)), ] } @@ -413,10 +466,13 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( types: &[&Type], metadata: &[OffloadMetadata], offload_globals: &OffloadGlobals<'ll>, + offload_dims: &OffloadKernelDims<'ll>, ) { let cx = builder.cx; let OffloadKernelGlobals { offload_sizes, offload_entry, memtransfer_types, region_id } = offload_data; + let OffloadKernelDims { num_workgroups, threads_per_block, workgroup_dims, thread_dims } = + offload_dims; let tgt_decl = offload_globals.launcher_fn; let tgt_target_kernel_ty = offload_globals.launcher_ty; @@ -554,7 +610,8 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( num_args, s_ident_t, ); - let values = KernelArgsTy::new(&cx, num_args, memtransfer_types, geps); + let values = + KernelArgsTy::new(&cx, num_args, memtransfer_types, geps, workgroup_dims, thread_dims); // Step 3) // Here we fill the KernelArgsTy, see the documentation above @@ -567,9 +624,8 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( s_ident_t, // FIXME(offload) give users a way to select which GPU to use. cx.get_const_i64(u64::MAX), // MAX == -1. - // FIXME(offload): Don't hardcode the numbers of threads in the future. - cx.get_const_i32(2097152), - cx.get_const_i32(256), + num_workgroups, + threads_per_block, region_id, a5, ]; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index b4057eea735e..481f75f337d6 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -30,7 +30,7 @@ use tracing::debug; use crate::abi::FnAbiLlvmExt; use crate::builder::Builder; use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call}; -use crate::builder::gpu_offload::{gen_call_handling, gen_define_handling}; +use crate::builder::gpu_offload::{OffloadKernelDims, gen_call_handling, gen_define_handling}; use crate::context::CodegenCx; use crate::declare::declare_raw_fn; use crate::errors::{ @@ -1384,7 +1384,8 @@ fn codegen_offload<'ll, 'tcx>( } }; - let args = get_args_from_tuple(bx, args[1], fn_target); + let offload_dims = OffloadKernelDims::from_operands(bx, &args[1], &args[2]); + let args = get_args_from_tuple(bx, args[3], fn_target); let target_symbol = symbol_name_for_instance_in_crate(tcx, fn_target, LOCAL_CRATE); let sig = tcx.fn_sig(fn_target.def_id()).skip_binder().skip_binder(); @@ -1403,7 +1404,7 @@ fn codegen_offload<'ll, 'tcx>( } }; let offload_data = gen_define_handling(&cx, &metadata, &types, target_symbol, offload_globals); - gen_call_handling(bx, &offload_data, &args, &types, &metadata, offload_globals); + gen_call_handling(bx, &offload_data, &args, &types, &metadata, offload_globals, &offload_dims); } fn get_args_from_tuple<'ll, 'tcx>( diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 4e8333f678b6..9eaf5319cb04 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -4,7 +4,7 @@ use rustc_abi::ExternAbi; use rustc_errors::DiagMessage; use rustc_hir::{self as hir, LangItem}; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Const, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, Symbol, sym}; @@ -315,7 +315,17 @@ pub(crate) fn check_intrinsic_type( let type_id = tcx.type_of(tcx.lang_items().type_id().unwrap()).instantiate_identity(); (0, 0, vec![type_id, type_id], tcx.types.bool) } - sym::offload => (3, 0, vec![param(0), param(1)], param(2)), + sym::offload => ( + 3, + 0, + vec![ + param(0), + Ty::new_array_with_const_len(tcx, tcx.types.u32, Const::from_target_usize(tcx, 3)), + Ty::new_array_with_const_len(tcx, tcx.types.u32, Const::from_target_usize(tcx, 3)), + param(1), + ], + param(2), + ), sym::offset => (2, 0, vec![param(0), param(1)], param(0)), sym::arith_offset => ( 1, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index d46d3ed9d513..0ae8d3d4a4ce 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3385,11 +3385,17 @@ pub const fn autodiff(f: F, df: G, args: T) -> /// - `T`: A tuple of arguments passed to `f`. /// - `R`: The return type of the kernel. /// +/// Arguments: +/// - `f`: The kernel function to offload. +/// - `workgroup_dim`: A 3D size specifying the number of workgroups to launch. +/// - `thread_dim`: A 3D size specifying the number of threads per workgroup. +/// - `args`: A tuple of arguments forwarded to `f`. +/// /// Example usage (pseudocode): /// /// ```rust,ignore (pseudocode) /// fn kernel(x: *mut [f64; 128]) { -/// core::intrinsics::offload(kernel_1, (x,)) +/// core::intrinsics::offload(kernel_1, [256, 1, 1], [32, 1, 1], (x,)) /// } /// /// #[cfg(target_os = "linux")] @@ -3408,7 +3414,12 @@ pub const fn autodiff(f: F, df: G, args: T) -> /// . #[rustc_nounwind] #[rustc_intrinsic] -pub const fn offload(f: F, args: T) -> R; +pub const fn offload( + f: F, + workgroup_dim: [u32; 3], + thread_dim: [u32; 3], + args: T, +) -> R; /// Inform Miri that a given pointer definitely has a certain alignment. #[cfg(miri)] diff --git a/src/doc/rustc-dev-guide/src/offload/usage.md b/src/doc/rustc-dev-guide/src/offload/usage.md index 062534a4b655..4d3222123aaf 100644 --- a/src/doc/rustc-dev-guide/src/offload/usage.md +++ b/src/doc/rustc-dev-guide/src/offload/usage.md @@ -57,7 +57,7 @@ fn main() { #[inline(never)] unsafe fn kernel(x: *mut [f64; 256]) { - core::intrinsics::offload(kernel_1, (x,)) + core::intrinsics::offload(_kernel_1, [256, 1, 1], [32, 1, 1], (x,)) } #[cfg(target_os = "linux")] diff --git a/tests/codegen-llvm/gpu_offload/control_flow.rs b/tests/codegen-llvm/gpu_offload/control_flow.rs index 4a213f5a33a8..28ee9c85b0ed 100644 --- a/tests/codegen-llvm/gpu_offload/control_flow.rs +++ b/tests/codegen-llvm/gpu_offload/control_flow.rs @@ -21,14 +21,19 @@ // CHECK-NOT define // CHECK: bb3 // CHECK: call void @__tgt_target_data_begin_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.foo, ptr null, ptr null) -// CHECK: %10 = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 2097152, i32 256, ptr nonnull @.foo.region_id, ptr nonnull %kernel_args) +// CHECK: %10 = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 256, i32 32, ptr nonnull @.foo.region_id, ptr nonnull %kernel_args) // CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.foo, ptr null, ptr null) #[unsafe(no_mangle)] unsafe fn main() { let A = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]; for i in 0..100 { - core::intrinsics::offload::<_, _, ()>(foo, (A.as_ptr() as *const [f32; 6],)); + core::intrinsics::offload::<_, _, ()>( + foo, + [256, 1, 1], + [32, 1, 1], + (A.as_ptr() as *const [f32; 6],), + ); } } diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index ac179a65828d..b4d17143720a 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -82,14 +82,14 @@ fn main() { // CHECK-NEXT: %5 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 40 // CHECK-NEXT: %6 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 72 // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(32) %5, i8 0, i64 32, i1 false) -// CHECK-NEXT: store <4 x i32> , ptr %6, align 8 -// CHECK-NEXT: %.fca.1.gep3 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 88 -// CHECK-NEXT: store i32 0, ptr %.fca.1.gep3, align 8 -// CHECK-NEXT: %.fca.2.gep4 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 92 -// CHECK-NEXT: store i32 0, ptr %.fca.2.gep4, align 4 +// CHECK-NEXT: store <4 x i32> , ptr %6, align 8 +// CHECK-NEXT: %.fca.1.gep5 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 88 +// CHECK-NEXT: store i32 1, ptr %.fca.1.gep5, align 8 +// CHECK-NEXT: %.fca.2.gep7 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 92 +// CHECK-NEXT: store i32 1, ptr %.fca.2.gep7, align 4 // CHECK-NEXT: %7 = getelementptr inbounds nuw i8, ptr %kernel_args, i64 96 // CHECK-NEXT: store i32 0, ptr %7, align 8 -// CHECK-NEXT: %8 = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 2097152, i32 256, ptr nonnull @._kernel_1.region_id, ptr nonnull %kernel_args) +// CHECK-NEXT: %8 = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 256, i32 32, ptr nonnull @._kernel_1.region_id, ptr nonnull %kernel_args) // CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes._kernel_1, ptr null, ptr null) // CHECK-NEXT: call void @__tgt_unregister_lib(ptr nonnull %EmptyDesc) // CHECK-NEXT: ret void @@ -98,7 +98,7 @@ fn main() { #[unsafe(no_mangle)] #[inline(never)] pub fn kernel_1(x: &mut [f32; 256]) { - core::intrinsics::offload(_kernel_1, (x,)) + core::intrinsics::offload(_kernel_1, [256, 1, 1], [32, 1, 1], (x,)) } #[unsafe(no_mangle)] From 9f1066b1c1934c1ce76aececa7b0973776704281 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Thu, 27 Nov 2025 18:57:00 +0100 Subject: [PATCH 1497/3801] Basic support for FFI callbacks This commit adds basic support for FFI callbacks by registering a shim function via libffi. This shim function currently only exits with an error. The main motivation for this is to prevent miri segfaulting as described in [4639](https://github.com/rust-lang/miri/issues/4639). In the future miri could try to continue execution in the registered callback, although as far as I understand Ralf that is no easy problem. --- src/tools/miri/src/alloc_addresses/mod.rs | 35 ++++-- src/tools/miri/src/diagnostics.rs | 13 -- src/tools/miri/src/shims/mod.rs | 2 +- src/tools/miri/src/shims/native_lib/mod.rs | 112 +++++++++++++++--- .../fail/call_function_ptr.notrace.stderr | 31 +++++ .../native-lib/fail/call_function_ptr.rs | 21 ++++ .../fail/call_function_ptr.trace.stderr | 32 +++++ .../pass/ptr_read_access.notrace.stderr | 13 -- .../pass/ptr_read_access.trace.stderr | 13 -- .../miri/tests/native-lib/ptr_read_access.c | 7 ++ 10 files changed, 214 insertions(+), 65 deletions(-) create mode 100644 src/tools/miri/tests/native-lib/fail/call_function_ptr.notrace.stderr create mode 100644 src/tools/miri/tests/native-lib/fail/call_function_ptr.rs create mode 100644 src/tools/miri/tests/native-lib/fail/call_function_ptr.trace.stderr diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index 05d3444a4eb1..24b1c5fc6635 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -12,6 +12,7 @@ use rustc_middle::ty::TyCtxt; pub use self::address_generator::AddressGenerator; use self::reuse_pool::ReusePool; +use crate::alloc::MiriAllocParams; use crate::concurrency::VClock; use crate::diagnostics::SpanDedupDiagnostic; use crate::*; @@ -162,18 +163,21 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.get_alloc_bytes_unchecked_raw(alloc_id)? } } - AllocKind::Function | AllocKind::VTable => { - // Allocate some dummy memory to get a unique address for this function/vtable. - let alloc_bytes = MiriAllocBytes::from_bytes( - &[0u8; 1], - Align::from_bytes(1).unwrap(), - params, - ); - let ptr = alloc_bytes.as_ptr(); - // Leak the underlying memory to ensure it remains unique. - std::mem::forget(alloc_bytes); - ptr + #[cfg(all(unix, feature = "native-lib"))] + AllocKind::Function => { + if let Some(GlobalAlloc::Function { instance, .. }) = + this.tcx.try_get_global_alloc(alloc_id) + { + let fn_sig = this.tcx.fn_sig(instance.def_id()).skip_binder().skip_binder(); + let ptr = crate::shims::native_lib::build_libffi_closure_ptr(this, fn_sig)?; + ptr.cast() + } else { + dummy_alloc(params) + } } + #[cfg(not(all(unix, feature = "native-lib")))] + AllocKind::Function => dummy_alloc(params), + AllocKind::VTable => dummy_alloc(params), AllocKind::TypeId | AllocKind::Dead => unreachable!(), }; // We don't have to expose this pointer yet, we do that in `prepare_for_native_call`. @@ -205,6 +209,15 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } +fn dummy_alloc(params: MiriAllocParams) -> *const u8 { + // Allocate some dummy memory to get a unique address for this function/vtable. + let alloc_bytes = MiriAllocBytes::from_bytes(&[0u8; 1], Align::from_bytes(1).unwrap(), params); + let ptr = alloc_bytes.as_ptr(); + // Leak the underlying memory to ensure it remains unique. + std::mem::forget(alloc_bytes); + ptr +} + impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Returns the `AllocId` that corresponds to the specified addr, diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 1f87ac60c17a..64c7096fc5c2 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -138,7 +138,6 @@ pub enum NonHaltingDiagnostic { NativeCallSharedMem { tracing: bool, }, - NativeCallFnPtr, WeakMemoryOutdatedLoad { ptr: Pointer, }, @@ -643,11 +642,6 @@ impl<'tcx> MiriMachine<'tcx> { Int2Ptr { .. } => ("integer-to-pointer cast".to_string(), DiagLevel::Warning), NativeCallSharedMem { .. } => ("sharing memory with a native function".to_string(), DiagLevel::Warning), - NativeCallFnPtr => - ( - "sharing a function pointer with a native function".to_string(), - DiagLevel::Warning, - ), ExternTypeReborrow => ("reborrow of reference to `extern type`".to_string(), DiagLevel::Warning), GenmcCompareExchangeWeak | GenmcCompareExchangeOrderingMismatch { .. } => @@ -686,8 +680,6 @@ impl<'tcx> MiriMachine<'tcx> { Int2Ptr { .. } => format!("integer-to-pointer cast"), NativeCallSharedMem { .. } => format!("sharing memory with a native function called via FFI"), - NativeCallFnPtr => - format!("sharing a function pointer with a native function called via FFI"), WeakMemoryOutdatedLoad { ptr } => format!("weak memory emulation: outdated value returned from load at {ptr}"), ExternTypeReborrow => @@ -785,11 +777,6 @@ impl<'tcx> MiriMachine<'tcx> { ), ] }, - NativeCallFnPtr => { - vec![note!( - "calling Rust functions from C is not supported and will, in the best case, crash the program" - )] - } ExternTypeReborrow => { assert!(self.borrow_tracker.as_ref().is_some_and(|b| { matches!( diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs index e51ace2fd907..345e16b8da71 100644 --- a/src/tools/miri/src/shims/mod.rs +++ b/src/tools/miri/src/shims/mod.rs @@ -6,7 +6,7 @@ mod backtrace; mod files; mod math; #[cfg(all(unix, feature = "native-lib"))] -mod native_lib; +pub mod native_lib; mod unix; mod windows; mod x86; diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index 12abe841c052..719490c08e27 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -1,6 +1,7 @@ //! Implements calling functions from a native library. use std::ops::Deref; +use std::os::raw::c_void; use std::sync::atomic::AtomicBool; use libffi::low::CodePtr; @@ -74,6 +75,13 @@ impl AccessRange { } } +/// The data passed to the closure shim function used +/// to intercept function pointer calls from native +/// code +struct CallbackData<'tcx, 'this> { + ecx: &'this InterpCx<'tcx, MiriMachine<'tcx>>, +} + impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Call native host function and return the output as an immediate. @@ -330,7 +338,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Read the bytes that make up this argument. We cannot use the normal getter as // those would fail if any part of the argument is uninitialized. Native code // is kind of outside the interpreter, after all... - Box::from(alloc.inspect_with_uninit_and_ptr_outside_interpreter(range)) + let ret: Box<[u8]> = + Box::from(alloc.inspect_with_uninit_and_ptr_outside_interpreter(range)); + ret } either::Either::Right(imm) => { let mut bytes: Box<[u8]> = vec![0; imm.layout.size.bytes_usize()].into(); @@ -429,21 +439,102 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { Primitive::Float(Float::F32) => FfiType::f32(), Primitive::Float(Float::F64) => FfiType::f64(), Primitive::Pointer(AddressSpace::ZERO) => FfiType::pointer(), - _ => - throw_unsup_format!( - "unsupported scalar argument type for native call: {}", - layout.ty - ), + _ => throw_unsup_format!("unsupported scalar type for native call: {}", layout.ty), }); } interp_ok(match layout.ty.kind() { // Scalar types have already been handled above. ty::Adt(adt_def, args) => self.adt_to_ffitype(layout.ty, *adt_def, args)?, - _ => throw_unsup_format!("unsupported argument type for native call: {}", layout.ty), + // Rust uses `()` as return type for `void` function, which becomes `Tuple([])`. + ty::Tuple(t_list) if (*t_list).deref().is_empty() => FfiType::void(), + _ => { + throw_unsup_format!("unsupported type for native call: {}", layout.ty) + } }) } } +/// This function sets up a new libffi Closure to intercept +/// calls to rust code via function pointers passed to native code. +/// +/// It manages tho setup the underlying libffi datastructure by initializing the +/// right number of arguments with the right types, as well a setting +/// the right return type +/// +/// Calling this function leaks the data passed into the libffi closure as +/// these need to be available until the execution terminates as the native +/// code side could store a function pointer and only call it at a later point. +/// This is for example done by SQLite, which uses function pointers as destructors +/// which then only run at teardown time +fn build_libffi_closure<'tcx, 'this>( + this: &'this MiriInterpCx<'tcx>, + fn_sig: rustc_middle::ty::FnSig<'tcx>, +) -> InterpResult<'tcx, libffi::middle::Closure<'this>> { + let mut args = Vec::new(); + for input in fn_sig.inputs().iter() { + let layout = this.layout_of(*input)?; + let ty = this.ty_to_ffitype(layout)?; + args.push(ty); + } + let res_type = fn_sig.output(); + let res_type = { + let layout = this.layout_of(res_type)?; + this.ty_to_ffitype(layout)? + }; + let closure_builder = libffi::middle::Builder::new().args(args).res(res_type); + let data = CallbackData { ecx: this }; + let data = Box::leak(Box::new(data)); + let closure = closure_builder.into_closure(callback_callback, data); + interp_ok(closure) +} + +/// This function wraps build_libffi_closure +/// to return the correct pointer that is expected to be +/// passed into native code as function pointer. +/// +/// This function returns a `*const c_void` ptr to erase the +/// actual function type, that is only known at runtime. +pub fn build_libffi_closure_ptr<'tcx, 'this>( + this: &'this MiriInterpCx<'tcx>, + fn_sig: rustc_middle::ty::FnSig<'tcx>, +) -> InterpResult<'tcx, *const std::ffi::c_void> { + let closure = build_libffi_closure(this, fn_sig)?; + let closure = Box::leak(Box::new(closure)); + // Libffi returns a **reference** to a function ptr here. + // (The actual argument type doesn't matter) + let fn_ptr = + unsafe { closure.instantiate_code_ptr::() }; + // Therefore we need to dereference the reference to get the actual function pointer. + let fn_ptr = *fn_ptr; + #[expect(clippy::as_conversions, reason = "No better way to cast a function ptr to a ptr")] + { + // After that we need to cast the function pointer to the + // expected pointer type. At this point we don't actually care about the + // type of this pointer. + interp_ok(fn_ptr as *const std::ffi::c_void) + } +} + +/// A shim function to intercept calls back from native code into the interpreter +/// via function pointers passed to the native code. +/// +/// For now this shim only reports that such constructs are not supported by miri. +/// As future improvement we might continue execution in the interpreter here. +unsafe extern "C" fn callback_callback<'tcx, 'this>( + _cif: &libffi::low::ffi_cif, + _result: &mut c_void, + _args: *const *const c_void, + infos: &CallbackData<'tcx, 'this>, +) { + let ecx = infos.ecx; + let err = err_unsup_format!("calling a function pointer through the FFI boundary"); + + crate::diagnostics::report_result(ecx, err.into()); + // We abort the execution at this point as we cannot return the + // expected value here. + std::process::exit(1); +} + impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Call the native host function, with supplied arguments. @@ -477,13 +568,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // pointer was passed as argument). Uninitialised memory is left as-is, but any data // exposed this way is garbage anyway. this.visit_reachable_allocs(this.exposed_allocs(), |this, alloc_id, info| { - if matches!(info.kind, AllocKind::Function) { - static DEDUP: AtomicBool = AtomicBool::new(false); - if !DEDUP.swap(true, std::sync::atomic::Ordering::Relaxed) { - // Newly set, so first time we get here. - this.emit_diagnostic(NonHaltingDiagnostic::NativeCallFnPtr); - } - } // If there is no data behind this pointer, skip this. if !matches!(info.kind, AllocKind::LiveData) { return interp_ok(()); diff --git a/src/tools/miri/tests/native-lib/fail/call_function_ptr.notrace.stderr b/src/tools/miri/tests/native-lib/fail/call_function_ptr.notrace.stderr new file mode 100644 index 000000000000..faabba9ca725 --- /dev/null +++ b/src/tools/miri/tests/native-lib/fail/call_function_ptr.notrace.stderr @@ -0,0 +1,31 @@ +warning: sharing memory with a native function called via FFI + --> tests/native-lib/fail/call_function_ptr.rs:LL:CC + | +LL | call_fn_ptr(Some(nop)); + | ^^^^^^^^^^^^^^^^^^^^^^ sharing memory with a native function + | + = help: when memory is shared with a native function call, Miri stops tracking initialization and provenance for that memory + = help: in particular, Miri assumes that the native call initializes all memory it has access to + = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory + = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free + = note: stack backtrace: + 0: pass_fn_ptr + at tests/native-lib/fail/call_function_ptr.rs:LL:CC + 1: main + at tests/native-lib/fail/call_function_ptr.rs:LL:CC + +error: unsupported operation: calling a function pointer through the FFI boundary + --> tests/native-lib/fail/call_function_ptr.rs:LL:CC + | +LL | call_fn_ptr(Some(nop)); + | ^^^^^^^^^^^^^^^^^^^^^^ 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 + = note: stack backtrace: + 0: pass_fn_ptr + at tests/native-lib/fail/call_function_ptr.rs:LL:CC + 1: main + at tests/native-lib/fail/call_function_ptr.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + diff --git a/src/tools/miri/tests/native-lib/fail/call_function_ptr.rs b/src/tools/miri/tests/native-lib/fail/call_function_ptr.rs new file mode 100644 index 000000000000..b68c4d4062b7 --- /dev/null +++ b/src/tools/miri/tests/native-lib/fail/call_function_ptr.rs @@ -0,0 +1,21 @@ +//@revisions: trace notrace +//@[trace] only-target: x86_64-unknown-linux-gnu i686-unknown-linux-gnu +//@[trace] compile-flags: -Zmiri-native-lib-enable-tracing +//@compile-flags: -Zmiri-permissive-provenance + +fn main() { + pass_fn_ptr() +} + +fn pass_fn_ptr() { + extern "C" { + fn call_fn_ptr(s: Option); + } + + extern "C" fn nop() {} + + unsafe { + call_fn_ptr(None); // this one is fine + call_fn_ptr(Some(nop)); //~ ERROR: unsupported operation: calling a function pointer through the FFI boundary + } +} diff --git a/src/tools/miri/tests/native-lib/fail/call_function_ptr.trace.stderr b/src/tools/miri/tests/native-lib/fail/call_function_ptr.trace.stderr new file mode 100644 index 000000000000..e56a5ece782b --- /dev/null +++ b/src/tools/miri/tests/native-lib/fail/call_function_ptr.trace.stderr @@ -0,0 +1,32 @@ +warning: sharing memory with a native function called via FFI + --> tests/native-lib/fail/call_function_ptr.rs:LL:CC + | +LL | call_fn_ptr(Some(nop)); + | ^^^^^^^^^^^^^^^^^^^^^^ sharing memory with a native function + | + = help: when memory is shared with a native function call, Miri can only track initialisation and provenance on a best-effort basis + = help: in particular, Miri assumes that the native call initializes all memory it has written to + = help: Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory + = help: what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free + = help: tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here + = note: stack backtrace: + 0: pass_fn_ptr + at tests/native-lib/fail/call_function_ptr.rs:LL:CC + 1: main + at tests/native-lib/fail/call_function_ptr.rs:LL:CC + +error: unsupported operation: calling a function pointer through the FFI boundary + --> tests/native-lib/fail/call_function_ptr.rs:LL:CC + | +LL | call_fn_ptr(Some(nop)); + | ^^^^^^^^^^^^^^^^^^^^^^ 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 + = note: stack backtrace: + 0: pass_fn_ptr + at tests/native-lib/fail/call_function_ptr.rs:LL:CC + 1: main + at tests/native-lib/fail/call_function_ptr.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + diff --git a/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr index b6bbb4342b77..bc2fcac08f01 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_read_access.notrace.stderr @@ -14,16 +14,3 @@ LL | unsafe { print_pointer(&x) }; 1: main at tests/native-lib/pass/ptr_read_access.rs:LL:CC -warning: sharing a function pointer with a native function called via FFI - --> tests/native-lib/pass/ptr_read_access.rs:LL:CC - | -LL | pass_fn_ptr(Some(nop)); // this one is not - | ^^^^^^^^^^^^^^^^^^^^^^ sharing a function pointer with a native function - | - = help: calling Rust functions from C is not supported and will, in the best case, crash the program - = note: stack backtrace: - 0: pass_fn_ptr - at tests/native-lib/pass/ptr_read_access.rs:LL:CC - 1: main - at tests/native-lib/pass/ptr_read_access.rs:LL:CC - diff --git a/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr b/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr index 0d86ea066099..c7f30c114f16 100644 --- a/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr +++ b/src/tools/miri/tests/native-lib/pass/ptr_read_access.trace.stderr @@ -15,16 +15,3 @@ LL | unsafe { print_pointer(&x) }; 1: main at tests/native-lib/pass/ptr_read_access.rs:LL:CC -warning: sharing a function pointer with a native function called via FFI - --> tests/native-lib/pass/ptr_read_access.rs:LL:CC - | -LL | pass_fn_ptr(Some(nop)); // this one is not - | ^^^^^^^^^^^^^^^^^^^^^^ sharing a function pointer with a native function - | - = help: calling Rust functions from C is not supported and will, in the best case, crash the program - = note: stack backtrace: - 0: pass_fn_ptr - at tests/native-lib/pass/ptr_read_access.rs:LL:CC - 1: main - at tests/native-lib/pass/ptr_read_access.rs:LL:CC - diff --git a/src/tools/miri/tests/native-lib/ptr_read_access.c b/src/tools/miri/tests/native-lib/ptr_read_access.c index 5f071ca3d424..44ba13aa54a6 100644 --- a/src/tools/miri/tests/native-lib/ptr_read_access.c +++ b/src/tools/miri/tests/native-lib/ptr_read_access.c @@ -68,3 +68,10 @@ EXPORT uintptr_t do_one_deref(const int32_t ***ptr) { EXPORT void pass_fn_ptr(void f(void)) { (void)f; // suppress unused warning } + +/* Test: function_ptrs */ +EXPORT void call_fn_ptr(void f(void)) { + if (f != NULL) { + f(); + } +} From c7f6d7800da867ad3e384d65eff0d1fed2906036 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 2 Jan 2026 11:50:17 +0100 Subject: [PATCH 1498/3801] minor cleanup --- src/tools/miri/src/alloc_addresses/mod.rs | 11 +++- src/tools/miri/src/shims/native_lib/mod.rs | 59 ++++++---------------- 2 files changed, 25 insertions(+), 45 deletions(-) diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index 24b1c5fc6635..fed51ed86433 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -169,8 +169,15 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.tcx.try_get_global_alloc(alloc_id) { let fn_sig = this.tcx.fn_sig(instance.def_id()).skip_binder().skip_binder(); - let ptr = crate::shims::native_lib::build_libffi_closure_ptr(this, fn_sig)?; - ptr.cast() + let fn_ptr = crate::shims::native_lib::build_libffi_closure(this, fn_sig)?; + + #[expect( + clippy::as_conversions, + reason = "No better way to cast a function ptr to a ptr" + )] + { + fn_ptr as *const _ + } } else { dummy_alloc(params) } diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index 719490c08e27..9f997a82ee57 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -75,9 +75,8 @@ impl AccessRange { } } -/// The data passed to the closure shim function used -/// to intercept function pointer calls from native -/// code +/// The data passed to the closure shim function used to intercept function pointer calls from +/// native code. struct CallbackData<'tcx, 'this> { ecx: &'this InterpCx<'tcx, MiriMachine<'tcx>>, } @@ -338,9 +337,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Read the bytes that make up this argument. We cannot use the normal getter as // those would fail if any part of the argument is uninitialized. Native code // is kind of outside the interpreter, after all... - let ret: Box<[u8]> = - Box::from(alloc.inspect_with_uninit_and_ptr_outside_interpreter(range)); - ret + Box::from(alloc.inspect_with_uninit_and_ptr_outside_interpreter(range)) } either::Either::Right(imm) => { let mut bytes: Box<[u8]> = vec![0; imm.layout.size.bytes_usize()].into(); @@ -446,7 +443,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Scalar types have already been handled above. ty::Adt(adt_def, args) => self.adt_to_ffitype(layout.ty, *adt_def, args)?, // Rust uses `()` as return type for `void` function, which becomes `Tuple([])`. - ty::Tuple(t_list) if (*t_list).deref().is_empty() => FfiType::void(), + ty::Tuple(t_list) if t_list.len() == 0 => FfiType::void(), _ => { throw_unsup_format!("unsupported type for native call: {}", layout.ty) } @@ -454,22 +451,17 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } -/// This function sets up a new libffi Closure to intercept +/// This function sets up a new libffi closure to intercept /// calls to rust code via function pointers passed to native code. /// -/// It manages tho setup the underlying libffi datastructure by initializing the -/// right number of arguments with the right types, as well a setting -/// the right return type -/// /// Calling this function leaks the data passed into the libffi closure as /// these need to be available until the execution terminates as the native /// code side could store a function pointer and only call it at a later point. -/// This is for example done by SQLite, which uses function pointers as destructors -/// which then only run at teardown time -fn build_libffi_closure<'tcx, 'this>( +pub fn build_libffi_closure<'tcx, 'this>( this: &'this MiriInterpCx<'tcx>, fn_sig: rustc_middle::ty::FnSig<'tcx>, -) -> InterpResult<'tcx, libffi::middle::Closure<'this>> { +) -> InterpResult<'tcx, unsafe extern "C" fn()> { + // Compute argument and return types in libffi representation. let mut args = Vec::new(); for input in fn_sig.inputs().iter() { let layout = this.layout_of(*input)?; @@ -481,38 +473,19 @@ fn build_libffi_closure<'tcx, 'this>( let layout = this.layout_of(res_type)?; this.ty_to_ffitype(layout)? }; + + // Build the actual closure. let closure_builder = libffi::middle::Builder::new().args(args).res(res_type); let data = CallbackData { ecx: this }; let data = Box::leak(Box::new(data)); - let closure = closure_builder.into_closure(callback_callback, data); - interp_ok(closure) -} - -/// This function wraps build_libffi_closure -/// to return the correct pointer that is expected to be -/// passed into native code as function pointer. -/// -/// This function returns a `*const c_void` ptr to erase the -/// actual function type, that is only known at runtime. -pub fn build_libffi_closure_ptr<'tcx, 'this>( - this: &'this MiriInterpCx<'tcx>, - fn_sig: rustc_middle::ty::FnSig<'tcx>, -) -> InterpResult<'tcx, *const std::ffi::c_void> { - let closure = build_libffi_closure(this, fn_sig)?; + let closure = closure_builder.into_closure(libffi_closure_callback, data); let closure = Box::leak(Box::new(closure)); + + // The actual argument/return type doesn't matter. + let fn_ptr = unsafe { closure.instantiate_code_ptr::() }; // Libffi returns a **reference** to a function ptr here. - // (The actual argument type doesn't matter) - let fn_ptr = - unsafe { closure.instantiate_code_ptr::() }; // Therefore we need to dereference the reference to get the actual function pointer. - let fn_ptr = *fn_ptr; - #[expect(clippy::as_conversions, reason = "No better way to cast a function ptr to a ptr")] - { - // After that we need to cast the function pointer to the - // expected pointer type. At this point we don't actually care about the - // type of this pointer. - interp_ok(fn_ptr as *const std::ffi::c_void) - } + interp_ok(*fn_ptr) } /// A shim function to intercept calls back from native code into the interpreter @@ -520,7 +493,7 @@ pub fn build_libffi_closure_ptr<'tcx, 'this>( /// /// For now this shim only reports that such constructs are not supported by miri. /// As future improvement we might continue execution in the interpreter here. -unsafe extern "C" fn callback_callback<'tcx, 'this>( +unsafe extern "C" fn libffi_closure_callback<'tcx, 'this>( _cif: &libffi::low::ffi_cif, _result: &mut c_void, _args: *const *const c_void, From bcdcabee75e5f0aad8811ce204f38e54174d26fd Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 3 Dec 2025 22:15:58 +0300 Subject: [PATCH 1499/3801] resolve: Do not break from the scope visiting loop if we already found the innermost binding. Previously we could lose the already found binding and break with an error, if some blocking error was found in the shadowed scopes. Also, avoid some impossible state in the return type of `fn resolve_ident_in_scope`. --- compiler/rustc_resolve/src/ident.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 669f045681b7..8e5c15e88ca5 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -429,10 +429,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { orig_ident.span.ctxt(), derive_fallback_lint_id, |this, scope, use_prelude, ctxt| { - // We can break with an error at this step, it means we cannot determine the - // resolution right now, but we must block and wait until we can instead of - // considering outer scopes. - match this.reborrow().resolve_ident_in_scope( + let res = match this.reborrow().resolve_ident_in_scope( orig_ident, ns, scope, @@ -445,7 +442,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { force, ignore_binding, ignore_import, - )? { + ) { + Ok(binding) => Ok(binding), + // We can break with an error at this step, it means we cannot determine the + // resolution right now, but we must block and wait until we can, instead of + // considering outer scopes. Although there's no need to do that if we already + // have a better solution. + Err(ControlFlow::Break(determinacy)) if innermost_results.is_empty() => { + return ControlFlow::Break(Err(determinacy)); + } + Err(determinacy) => Err(determinacy.into_value()), + }; + match res { Ok(binding) if sub_namespace_match(binding.macro_kinds(), macro_kind) => { // Below we report various ambiguity errors. // We do not need to report them if we are either in speculative resolution, @@ -504,8 +512,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { force: bool, ignore_binding: Option>, ignore_import: Option>, - ) -> ControlFlow, Determinacy>, Result, Determinacy>> - { + ) -> Result, ControlFlow> { let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); let ret = match scope { Scope::DeriveHelpers(expn_id) => { @@ -591,7 +598,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } Err(ControlFlow::Continue(determinacy)) => Err(determinacy), Err(ControlFlow::Break(Determinacy::Undetermined)) => { - return ControlFlow::Break(Err(Determinacy::determined(force))); + return Err(ControlFlow::Break(Determinacy::determined(force))); } // Privacy errors, do not happen during in scope resolution. Err(ControlFlow::Break(Determinacy::Determined)) => unreachable!(), @@ -680,7 +687,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }, }; - ControlFlow::Continue(ret) + ret.map_err(ControlFlow::Continue) } fn maybe_push_ambiguity( From 1f32c2a418eeabb57a643ae28817bfe00857766c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 2 Jan 2026 12:06:19 +0100 Subject: [PATCH 1500/3801] bump libffi --- src/tools/miri/Cargo.lock | 8 ++++---- src/tools/miri/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 395c37e9ade8..220fad2a1c76 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -786,9 +786,9 @@ checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libffi" -version = "5.0.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0444124f3ffd67e1b0b0c661a7f81a278a135eb54aaad4078e79fbc8be50c8a5" +checksum = "0498fe5655f857803e156523e644dcdcdc3b3c7edda42ea2afdae2e09b2db87b" dependencies = [ "libc", "libffi-sys", @@ -796,9 +796,9 @@ dependencies = [ [[package]] name = "libffi-sys" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d722da8817ea580d0669da6babe2262d7b86a1af1103da24102b8bb9c101ce7" +checksum = "71d4f1d4ce15091955144350b75db16a96d4a63728500122706fb4d29a26afbb" dependencies = [ "cc", ] diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 4a54a7e0eb71..064706d7ed04 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -32,7 +32,7 @@ serde_json = { version = "1.0", optional = true } [target.'cfg(unix)'.dependencies] libc = "0.2" # native-lib dependencies -libffi = { version = "5.0.0", optional = true } +libffi = { version = "5.1.0", optional = true } libloading = { version = "0.9", optional = true } serde = { version = "1.0.219", features = ["derive"], optional = true } From 604cf92cd4518799b8613b3ad666cbe57178b6ec Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 2 Jan 2026 12:23:55 +0100 Subject: [PATCH 1501/3801] avoid aliasing trouble around libffi closures --- src/tools/miri/src/machine.rs | 7 ++++ src/tools/miri/src/shims/native_lib/mod.rs | 44 +++++++++++++++------- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 502cdbdc57b3..f17bd5ac4319 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -599,6 +599,9 @@ pub struct MiriMachine<'tcx> { pub native_lib: Vec<(libloading::Library, std::path::PathBuf)>, #[cfg(not(all(unix, feature = "native-lib")))] pub native_lib: Vec, + /// A memory location for exchanging the current `ecx` pointer with native code. + #[cfg(all(unix, feature = "native-lib"))] + pub native_lib_ecx_interchange: &'static Cell, /// Run a garbage collector for BorTags every N basic blocks. pub(crate) gc_interval: u32, @@ -790,6 +793,8 @@ impl<'tcx> MiriMachine<'tcx> { lib_file_path.clone(), ) }).collect(), + #[cfg(all(unix, feature = "native-lib"))] + native_lib_ecx_interchange: Box::leak(Box::new(Cell::new(0))), #[cfg(not(all(unix, feature = "native-lib")))] native_lib: config.native_lib.iter().map(|_| { panic!("calling functions from native libraries via FFI is not supported in this build of Miri") @@ -1026,6 +1031,8 @@ impl VisitProvenance for MiriMachine<'_> { report_progress: _, basic_block_count: _, native_lib: _, + #[cfg(all(unix, feature = "native-lib"))] + native_lib_ecx_interchange: _, gc_interval: _, since_gc: _, num_cpus: _, diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index 9f997a82ee57..c25c1841dd70 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -1,7 +1,10 @@ //! Implements calling functions from a native library. +use std::cell::Cell; +use std::marker::PhantomData; use std::ops::Deref; use std::os::raw::c_void; +use std::ptr; use std::sync::atomic::AtomicBool; use libffi::low::CodePtr; @@ -75,12 +78,6 @@ impl AccessRange { } } -/// The data passed to the closure shim function used to intercept function pointer calls from -/// native code. -struct CallbackData<'tcx, 'this> { - ecx: &'this InterpCx<'tcx, MiriMachine<'tcx>>, -} - impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Call native host function and return the output as an immediate. @@ -93,12 +90,15 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, (crate::ImmTy<'tcx>, Option)> { let this = self.eval_context_mut(); #[cfg(target_os = "linux")] - let alloc = this.machine.allocator.as_ref().unwrap(); + let alloc = this.machine.allocator.as_ref().unwrap().clone(); #[cfg(not(target_os = "linux"))] // Placeholder value. let alloc = (); - trace::Supervisor::do_ffi(alloc, || { + // Expose InterpCx for use by closure callbacks. + this.machine.native_lib_ecx_interchange.set(ptr::from_mut(this).expose_provenance()); + + let res = trace::Supervisor::do_ffi(&alloc, || { // Call the function (`ptr`) with arguments `libffi_args`, and obtain the return value // as the specified primitive integer type let scalar = match dest.layout.ty.kind() { @@ -174,7 +174,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { .into(), }; interp_ok(ImmTy::from_scalar(scalar, dest.layout)) - }) + }); + + this.machine.native_lib_ecx_interchange.set(0); + + res } /// Get the pointer to the function of the specified name in the shared object file, @@ -451,6 +455,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } +/// The data passed to the closure shim function used to intercept function pointer calls from +/// native code. +struct LibffiClosureData<'tcx> { + ecx_interchange: &'static Cell, + marker: PhantomData>, +} + /// This function sets up a new libffi closure to intercept /// calls to rust code via function pointers passed to native code. /// @@ -476,7 +487,10 @@ pub fn build_libffi_closure<'tcx, 'this>( // Build the actual closure. let closure_builder = libffi::middle::Builder::new().args(args).res(res_type); - let data = CallbackData { ecx: this }; + let data = LibffiClosureData { + ecx_interchange: this.machine.native_lib_ecx_interchange, + marker: PhantomData, + }; let data = Box::leak(Box::new(data)); let closure = closure_builder.into_closure(libffi_closure_callback, data); let closure = Box::leak(Box::new(closure)); @@ -493,13 +507,17 @@ pub fn build_libffi_closure<'tcx, 'this>( /// /// For now this shim only reports that such constructs are not supported by miri. /// As future improvement we might continue execution in the interpreter here. -unsafe extern "C" fn libffi_closure_callback<'tcx, 'this>( +unsafe extern "C" fn libffi_closure_callback<'tcx>( _cif: &libffi::low::ffi_cif, _result: &mut c_void, _args: *const *const c_void, - infos: &CallbackData<'tcx, 'this>, + data: &LibffiClosureData<'tcx>, ) { - let ecx = infos.ecx; + let ecx = unsafe { + ptr::with_exposed_provenance_mut::>(data.ecx_interchange.get()) + .as_mut() + .expect("libffi closure called while no FFI call is active") + }; let err = err_unsup_format!("calling a function pointer through the FFI boundary"); crate::diagnostics::report_result(ecx, err.into()); From 75d90094e732948f4a45cb407f604239ae6a31ef Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 3 Dec 2025 22:24:59 +0300 Subject: [PATCH 1502/3801] resolve: Split `Scope::Module` into two scopes for non-glob and glob bindings --- compiler/rustc_resolve/src/diagnostics.rs | 7 +- compiler/rustc_resolve/src/ident.rs | 71 +++++++++++++++---- compiler/rustc_resolve/src/lib.rs | 17 +++-- tests/ui/imports/issue-114682-1.rs | 1 + tests/ui/imports/issue-114682-1.stderr | 28 +++++++- .../local-modularized-tricky-fail-1.rs | 1 + .../local-modularized-tricky-fail-1.stderr | 32 ++++++++- tests/ui/imports/macro-paths.rs | 1 + tests/ui/imports/macro-paths.stderr | 28 ++++++-- 9 files changed, 157 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 8f20b5fe5745..716e1d5a2e7f 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1206,9 +1206,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } } - Scope::Module(module, _) => { + Scope::ModuleNonGlobs(module, _) => { this.add_module_candidates(module, suggestions, filter_fn, None); } + Scope::ModuleGlobs(..) => { + // Already handled in `ModuleNonGlobs`. + } Scope::MacroUsePrelude => { suggestions.extend(this.macro_use_prelude.iter().filter_map( |(name, binding)| { @@ -2033,7 +2036,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously")) } - if let Scope::Module(module, _) = scope { + if let Scope::ModuleNonGlobs(module, _) | Scope::ModuleGlobs(module, _) = scope { if module == self.graph_root { help_msgs.push(format!( "use `crate::{ident}` to refer to this {thing} unambiguously" diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 8e5c15e88ca5..fcd058c5ae6d 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -116,9 +116,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)); let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude); let mut scope = match ns { - _ if module_and_extern_prelude => Scope::Module(module, None), + _ if module_and_extern_prelude => Scope::ModuleNonGlobs(module, None), _ if extern_prelude => Scope::ExternPreludeItems, - TypeNS | ValueNS => Scope::Module(module, None), + TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None), MacroNS => Scope::DeriveHelpers(parent_scope.expansion), }; let mut ctxt = ctxt.normalize_to_macros_2_0(); @@ -145,7 +145,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } true } - Scope::Module(..) => true, + Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..) => true, Scope::MacroUsePrelude => use_prelude || rust_2015, Scope::BuiltinAttrs => true, Scope::ExternPreludeItems | Scope::ExternPreludeFlags => { @@ -186,20 +186,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { MacroRulesScope::Invocation(invoc_id) => { Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules) } - MacroRulesScope::Empty => Scope::Module(module, None), + MacroRulesScope::Empty => Scope::ModuleNonGlobs(module, None), }, - Scope::Module(..) if module_and_extern_prelude => match ns { + Scope::ModuleNonGlobs(module, lint_id) => Scope::ModuleGlobs(module, lint_id), + Scope::ModuleGlobs(..) if module_and_extern_prelude => match ns { TypeNS => { ctxt.adjust(ExpnId::root()); Scope::ExternPreludeItems } ValueNS | MacroNS => break, }, - Scope::Module(module, prev_lint_id) => { + Scope::ModuleGlobs(module, prev_lint_id) => { use_prelude = !module.no_implicit_prelude; match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) { Some((parent_module, lint_id)) => { - Scope::Module(parent_module, lint_id.or(prev_lint_id)) + Scope::ModuleNonGlobs(parent_module, lint_id.or(prev_lint_id)) } None => { ctxt.adjust(ExpnId::root()); @@ -560,7 +561,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined), _ => Err(Determinacy::Determined), }, - Scope::Module(module, derive_fallback_lint_id) => { + Scope::ModuleNonGlobs(module, derive_fallback_lint_id) => { let (adjusted_parent_scope, adjusted_finalize) = if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) { (parent_scope, finalize) @@ -570,7 +571,51 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.map(|f| Finalize { used: Used::Scope, ..f }), ) }; - let binding = self.reborrow().resolve_ident_in_module_unadjusted( + let binding = self.reborrow().resolve_ident_in_module_non_globs_unadjusted( + module, + ident, + ns, + adjusted_parent_scope, + Shadowing::Restricted, + adjusted_finalize, + ignore_binding, + ignore_import, + ); + match binding { + Ok(binding) => { + if let Some(lint_id) = derive_fallback_lint_id { + self.get_mut().lint_buffer.buffer_lint( + PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, + lint_id, + orig_ident.span, + errors::ProcMacroDeriveResolutionFallback { + span: orig_ident.span, + ns_descr: ns.descr(), + ident, + }, + ); + } + Ok(binding) + } + Err(ControlFlow::Continue(determinacy)) => Err(determinacy), + Err(ControlFlow::Break(Determinacy::Undetermined)) => { + return Err(ControlFlow::Break(Determinacy::determined(force))); + } + // Privacy errors, do not happen during in scope resolution. + Err(ControlFlow::Break(Determinacy::Determined)) => unreachable!(), + } + } + Scope::ModuleGlobs(module, derive_fallback_lint_id) => { + let (adjusted_parent_scope, adjusted_finalize) = + if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) { + (parent_scope, finalize) + } else { + ( + &ParentScope { module, ..*parent_scope }, + finalize.map(|f| Finalize { used: Used::Scope, ..f }), + ) + }; + let binding = self.reborrow().resolve_ident_in_module_globs_unadjusted( module, ident, ns, @@ -717,12 +762,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } else if res == derive_helper_compat && innermost_res != derive_helper { span_bug!(orig_ident.span, "impossible inner resolution kind") } else if matches!(innermost_scope, Scope::MacroRules(_)) - && matches!(scope, Scope::Module(..)) + && matches!(scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..)) && !self.disambiguate_macro_rules_vs_modularized(innermost_binding, binding) { Some(AmbiguityKind::MacroRulesVsModularized) } else if matches!(scope, Scope::MacroRules(_)) - && matches!(innermost_scope, Scope::Module(..)) + && matches!(innermost_scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..)) { // should be impossible because of visitation order in // visit_scopes @@ -1177,8 +1222,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident, b1: binding, b2: shadowed_glob, - scope1: Scope::Module(self.empty_module, None), - scope2: Scope::Module(self.empty_module, None), + scope1: Scope::ModuleGlobs(self.empty_module, None), + scope2: Scope::ModuleGlobs(self.empty_module, None), warning: false, }); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 7cbf2088efce..fa53d57d175e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -123,10 +123,14 @@ enum Scope<'ra> { DeriveHelpersCompat, /// Textual `let`-like scopes introduced by `macro_rules!` items. MacroRules(MacroRulesScopeRef<'ra>), - /// Names declared in the given module. + /// Non-glob names declared in the given module. /// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` /// lint if it should be reported. - Module(Module<'ra>, Option), + ModuleNonGlobs(Module<'ra>, Option), + /// Glob names declared in the given module. + /// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` + /// lint if it should be reported. + ModuleGlobs(Module<'ra>, Option), /// Names introduced by `#[macro_use]` attributes on `extern crate` items. MacroUsePrelude, /// Built-in attributes. @@ -1926,9 +1930,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let scope_set = ScopeSet::All(TypeNS); self.cm().visit_scopes(scope_set, parent_scope, ctxt, None, |this, scope, _, _| { match scope { - Scope::Module(module, _) => { + Scope::ModuleNonGlobs(module, _) => { this.get_mut().traits_in_module(module, assoc_item, &mut found_traits); } + Scope::ModuleGlobs(..) => { + // Already handled in `ModuleNonGlobs` (but see #144993). + } Scope::StdLibPrelude => { if let Some(module) = this.prelude { this.get_mut().traits_in_module(module, assoc_item, &mut found_traits); @@ -2061,8 +2068,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident, b1: used_binding, b2, - scope1: Scope::Module(self.empty_module, None), - scope2: Scope::Module(self.empty_module, None), + scope1: Scope::ModuleGlobs(self.empty_module, None), + scope2: Scope::ModuleGlobs(self.empty_module, None), warning: warn_ambiguity, }; if !self.matches_previous_ambiguity_error(&ambiguity_error) { diff --git a/tests/ui/imports/issue-114682-1.rs b/tests/ui/imports/issue-114682-1.rs index 88fe05e51444..58b78508026d 100644 --- a/tests/ui/imports/issue-114682-1.rs +++ b/tests/ui/imports/issue-114682-1.rs @@ -22,4 +22,5 @@ mac!(); fn main() { A!(); //~^ ERROR `A` is ambiguous + //~| ERROR `A` is ambiguous } diff --git a/tests/ui/imports/issue-114682-1.stderr b/tests/ui/imports/issue-114682-1.stderr index 85fb7f7919e4..de8dc6cfb9ff 100644 --- a/tests/ui/imports/issue-114682-1.stderr +++ b/tests/ui/imports/issue-114682-1.stderr @@ -23,6 +23,32 @@ LL | pub use m::*; = help: consider adding an explicit import of `A` to disambiguate = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error +error[E0659]: `A` is ambiguous + --> $DIR/issue-114682-1.rs:23:5 + | +LL | A!(); + | ^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `A` could refer to the macro defined here + --> $DIR/issue-114682-1.rs:7:9 + | +LL | / pub macro A() { +LL | | println!("non import") +LL | | } + | |_________^ +... +LL | mac!(); + | ------ in this macro invocation + = help: use `crate::A` to refer to this macro unambiguously +note: `A` could also refer to the macro imported here + --> $DIR/issue-114682-1.rs:19:9 + | +LL | pub use m::*; + | ^^^^ + = help: use `crate::A` to refer to this macro unambiguously + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/local-modularized-tricky-fail-1.rs b/tests/ui/imports/local-modularized-tricky-fail-1.rs index ce700ae0de9b..bba26ee43a24 100644 --- a/tests/ui/imports/local-modularized-tricky-fail-1.rs +++ b/tests/ui/imports/local-modularized-tricky-fail-1.rs @@ -27,6 +27,7 @@ mod inner1 { } exported!(); //~ ERROR `exported` is ambiguous + //~| ERROR `exported` is ambiguous mod inner2 { define_exported!(); diff --git a/tests/ui/imports/local-modularized-tricky-fail-1.stderr b/tests/ui/imports/local-modularized-tricky-fail-1.stderr index 52a01e8bcdfe..54d928f7c812 100644 --- a/tests/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/tests/ui/imports/local-modularized-tricky-fail-1.stderr @@ -23,8 +23,34 @@ LL | use inner1::*; = help: consider adding an explicit import of `exported` to disambiguate = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0659]: `exported` is ambiguous + --> $DIR/local-modularized-tricky-fail-1.rs:29:1 + | +LL | exported!(); + | ^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `exported` could refer to the macro defined here + --> $DIR/local-modularized-tricky-fail-1.rs:6:5 + | +LL | / macro_rules! exported { +LL | | () => () +LL | | } + | |_____^ +... +LL | define_exported!(); + | ------------------ in this macro invocation + = help: use `crate::exported` to refer to this macro unambiguously +note: `exported` could also refer to the macro imported here + --> $DIR/local-modularized-tricky-fail-1.rs:23:5 + | +LL | use inner1::*; + | ^^^^^^^^^ + = help: use `crate::exported` to refer to this macro unambiguously + = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0659]: `panic` is ambiguous - --> $DIR/local-modularized-tricky-fail-1.rs:36:5 + --> $DIR/local-modularized-tricky-fail-1.rs:37:5 | LL | panic!(); | ^^^^^ ambiguous name @@ -45,7 +71,7 @@ LL | define_panic!(); = note: this error originates in the macro `define_panic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `include` is ambiguous - --> $DIR/local-modularized-tricky-fail-1.rs:47:1 + --> $DIR/local-modularized-tricky-fail-1.rs:48:1 | LL | include!(); | ^^^^^^^ ambiguous name @@ -65,6 +91,6 @@ LL | define_include!(); = help: use `crate::include` to refer to this macro unambiguously = note: this error originates in the macro `define_include` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/macro-paths.rs b/tests/ui/imports/macro-paths.rs index 916442a7c4ea..6fd426c34eff 100644 --- a/tests/ui/imports/macro-paths.rs +++ b/tests/ui/imports/macro-paths.rs @@ -11,6 +11,7 @@ mod foo { fn f() { use foo::*; bar::m! { //~ ERROR ambiguous + //~| ERROR `bar` is ambiguous mod bar { pub use two_macros::m; } } } diff --git a/tests/ui/imports/macro-paths.stderr b/tests/ui/imports/macro-paths.stderr index 5f113ce2bee5..5ba92072805e 100644 --- a/tests/ui/imports/macro-paths.stderr +++ b/tests/ui/imports/macro-paths.stderr @@ -6,7 +6,7 @@ LL | bar::m! { | = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution note: `bar` could refer to the module defined here - --> $DIR/macro-paths.rs:14:9 + --> $DIR/macro-paths.rs:15:9 | LL | mod bar { pub use two_macros::m; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,20 +17,38 @@ LL | use foo::*; | ^^^^^^ = help: consider adding an explicit import of `bar` to disambiguate +error[E0659]: `bar` is ambiguous + --> $DIR/macro-paths.rs:13:5 + | +LL | bar::m! { + | ^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `bar` could refer to the module defined here + --> $DIR/macro-paths.rs:15:9 + | +LL | mod bar { pub use two_macros::m; } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: `bar` could also refer to the module imported here + --> $DIR/macro-paths.rs:12:9 + | +LL | use foo::*; + | ^^^^^^ + error[E0659]: `baz` is ambiguous - --> $DIR/macro-paths.rs:23:5 + --> $DIR/macro-paths.rs:24:5 | LL | baz::m! { | ^^^ ambiguous name | = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution note: `baz` could refer to the module defined here - --> $DIR/macro-paths.rs:24:9 + --> $DIR/macro-paths.rs:25:9 | LL | mod baz { pub use two_macros::m; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: `baz` could also refer to the module defined here - --> $DIR/macro-paths.rs:18:1 + --> $DIR/macro-paths.rs:19:1 | LL | / pub mod baz { LL | | pub use two_macros::m; @@ -38,6 +56,6 @@ LL | | } | |_^ = help: use `crate::baz` to refer to this module unambiguously -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0659`. From bcfbb5619c5f2f9d69d8b60b820a2b1db266d4af Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 3 Dec 2025 22:46:42 +0300 Subject: [PATCH 1503/3801] resolve: Migrate a special ambiguity for glob vs non-glob bindings in the same module to the usual ambiguity infra in `resolve_ident_in_scope_set` --- compiler/rustc_resolve/src/ident.rs | 30 +++++++++-------------------- tests/ui/imports/macro-paths.rs | 1 - tests/ui/imports/macro-paths.stderr | 29 +++++----------------------- 3 files changed, 14 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index fcd058c5ae6d..61e98c60a5c9 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -783,9 +783,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(AmbiguityKind::GlobVsOuter) } else if innermost_binding.may_appear_after(parent_scope.expansion, binding) { Some(AmbiguityKind::MoreExpandedVsOuter) + } else if innermost_binding.expansion != LocalExpnId::ROOT + && let Scope::ModuleGlobs(m1, _) = scope + && let Scope::ModuleNonGlobs(m2, _) = innermost_scope + && m1 == m2 + { + // FIXME: this error is too conservative and technically unnecessary now when module + // scope is split into two scopes, remove it with lang team approval. + Some(AmbiguityKind::GlobVsExpanded) } else { None }; + if let Some(kind) = ambiguity_error_kind { // Skip ambiguity errors for extern flag bindings "overridden" // by extern item bindings. @@ -1008,7 +1017,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return self.get_mut().finalize_module_binding( ident, binding, - if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None }, parent_scope, module, finalize, @@ -1070,7 +1078,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return self.get_mut().finalize_module_binding( ident, binding, - if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None }, parent_scope, module, finalize, @@ -1182,7 +1189,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &mut self, ident: Ident, binding: Option>, - shadowed_glob: Option>, parent_scope: &ParentScope<'ra>, module: Module<'ra>, finalize: Finalize, @@ -1210,24 +1216,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - // Forbid expanded shadowing to avoid time travel. - if let Some(shadowed_glob) = shadowed_glob - && shadowing == Shadowing::Restricted - && finalize.stage == Stage::Early - && binding.expansion != LocalExpnId::ROOT - && binding.res() != shadowed_glob.res() - { - self.ambiguity_errors.push(AmbiguityError { - kind: AmbiguityKind::GlobVsExpanded, - ident, - b1: binding, - b2: shadowed_glob, - scope1: Scope::ModuleGlobs(self.empty_module, None), - scope2: Scope::ModuleGlobs(self.empty_module, None), - warning: false, - }); - } - if shadowing == Shadowing::Unrestricted && binding.expansion != LocalExpnId::ROOT && let NameBindingKind::Import { import, .. } = binding.kind diff --git a/tests/ui/imports/macro-paths.rs b/tests/ui/imports/macro-paths.rs index 6fd426c34eff..916442a7c4ea 100644 --- a/tests/ui/imports/macro-paths.rs +++ b/tests/ui/imports/macro-paths.rs @@ -11,7 +11,6 @@ mod foo { fn f() { use foo::*; bar::m! { //~ ERROR ambiguous - //~| ERROR `bar` is ambiguous mod bar { pub use two_macros::m; } } } diff --git a/tests/ui/imports/macro-paths.stderr b/tests/ui/imports/macro-paths.stderr index 5ba92072805e..56a40e908258 100644 --- a/tests/ui/imports/macro-paths.stderr +++ b/tests/ui/imports/macro-paths.stderr @@ -1,22 +1,3 @@ -error[E0659]: `bar` is ambiguous - --> $DIR/macro-paths.rs:13:5 - | -LL | bar::m! { - | ^^^ ambiguous name - | - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution -note: `bar` could refer to the module defined here - --> $DIR/macro-paths.rs:15:9 - | -LL | mod bar { pub use two_macros::m; } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: `bar` could also refer to the module imported here - --> $DIR/macro-paths.rs:12:9 - | -LL | use foo::*; - | ^^^^^^ - = help: consider adding an explicit import of `bar` to disambiguate - error[E0659]: `bar` is ambiguous --> $DIR/macro-paths.rs:13:5 | @@ -25,7 +6,7 @@ LL | bar::m! { | = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution note: `bar` could refer to the module defined here - --> $DIR/macro-paths.rs:15:9 + --> $DIR/macro-paths.rs:14:9 | LL | mod bar { pub use two_macros::m; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,19 +17,19 @@ LL | use foo::*; | ^^^^^^ error[E0659]: `baz` is ambiguous - --> $DIR/macro-paths.rs:24:5 + --> $DIR/macro-paths.rs:23:5 | LL | baz::m! { | ^^^ ambiguous name | = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution note: `baz` could refer to the module defined here - --> $DIR/macro-paths.rs:25:9 + --> $DIR/macro-paths.rs:24:9 | LL | mod baz { pub use two_macros::m; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: `baz` could also refer to the module defined here - --> $DIR/macro-paths.rs:19:1 + --> $DIR/macro-paths.rs:18:1 | LL | / pub mod baz { LL | | pub use two_macros::m; @@ -56,6 +37,6 @@ LL | | } | |_^ = help: use `crate::baz` to refer to this module unambiguously -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. From cd7a58e4127a66f8a641c42c6a12c5419c8d5585 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 2 Jan 2026 13:01:07 +0100 Subject: [PATCH 1504/3801] Pre-allocate intern storages with 64kb of data To reduce the amount of re-allocating the hashtables which can be expensive given the need to re-hash --- src/tools/rust-analyzer/crates/hir-ty/src/lower.rs | 2 +- .../crates/hir-ty/src/method_resolution.rs | 8 ++++---- .../crates/hir-ty/src/next_solver/infer/mod.rs | 8 +++++--- .../src/next_solver/infer/opaque_types/table.rs | 2 +- .../crates/hir-ty/src/tests/incremental.rs | 3 --- .../rust-analyzer/crates/hir-ty/src/variance.rs | 13 +++++++------ src/tools/rust-analyzer/crates/intern/src/intern.rs | 2 +- .../rust-analyzer/crates/intern/src/intern_slice.rs | 7 ++++++- 8 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 9307868f3982..e45ef113a086 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -1319,7 +1319,7 @@ fn type_for_struct_constructor( db: &dyn HirDatabase, def: StructId, ) -> Option> { - let struct_data = def.fields(db); + let struct_data = db.struct_signature(def); match struct_data.shape { FieldsShape::Record => None, FieldsShape::Unit => Some(type_for_adt(db, def.into())), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index 50dbd87d693e..3d7cc4ffbf8a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -731,6 +731,10 @@ impl TraitImpls { ) { for (_module_id, module_data) in def_map.modules() { for impl_id in module_data.scope.impls() { + let trait_ref = match db.impl_trait(impl_id) { + Some(tr) => tr.instantiate_identity(), + None => continue, + }; // Reservation impls should be ignored during trait resolution, so we never need // them during type analysis. See rust-lang/rust#64631 for details. // @@ -742,10 +746,6 @@ impl TraitImpls { { continue; } - let trait_ref = match db.impl_trait(impl_id) { - Some(tr) => tr.instantiate_identity(), - None => continue, - }; let self_ty = trait_ref.self_ty(); let interner = DbInterner::new_no_crate(db); let entry = map.entry(trait_ref.def_id.0).or_default(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs index 2926dc30def7..7d291f7ddbed 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs @@ -878,9 +878,11 @@ impl<'db> InferCtxt<'db> { self.tainted_by_errors.set(Some(e)); } - #[instrument(level = "debug", skip(self), ret)] - pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'db>, OpaqueHiddenType<'db>)> { - self.inner.borrow_mut().opaque_type_storage.take_opaque_types().collect() + #[instrument(level = "debug", skip(self))] + pub fn take_opaque_types( + &self, + ) -> impl IntoIterator, OpaqueHiddenType<'db>)> + use<'db> { + self.inner.borrow_mut().opaque_type_storage.take_opaque_types() } #[instrument(level = "debug", skip(self), ret)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/table.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/table.rs index 00177d21ac76..894fe5eb7b87 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/table.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/opaque_types/table.rs @@ -61,7 +61,7 @@ impl<'db> OpaqueTypeStorage<'db> { pub(crate) fn take_opaque_types( &mut self, - ) -> impl Iterator, OpaqueHiddenType<'db>)> { + ) -> impl IntoIterator, OpaqueHiddenType<'db>)> + use<'db> { let OpaqueTypeStorage { opaque_types, duplicate_entries } = self; std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries)) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index 1457bb2e1017..633ab43c4cec 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -632,8 +632,6 @@ fn main() { "struct_signature_with_source_map_shim", "GenericPredicates::query_with_diagnostics_", "value_ty_query", - "VariantFields::firewall_", - "VariantFields::query_", "InherentImpls::for_crate_", "impl_signature_shim", "impl_signature_with_source_map_shim", @@ -723,7 +721,6 @@ fn main() { "expr_scopes_shim", "struct_signature_with_source_map_shim", "GenericPredicates::query_with_diagnostics_", - "VariantFields::query_", "InherentImpls::for_crate_", "impl_signature_with_source_map_shim", "impl_signature_shim", diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index e5cfe85573b8..6f415a5289c9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs @@ -41,7 +41,6 @@ pub(crate) fn variances_of(db: &dyn HirDatabase, def: GenericDefId) -> Variances )] fn variances_of_query(db: &dyn HirDatabase, def: GenericDefId) -> StoredVariancesOf { tracing::debug!("variances_of(def={:?})", def); - let interner = DbInterner::new_no_crate(db); match def { GenericDefId::FunctionId(_) => (), GenericDefId::AdtId(adt) => { @@ -55,15 +54,17 @@ fn variances_of_query(db: &dyn HirDatabase, def: GenericDefId) -> StoredVariance } } } - _ => return VariancesOf::empty(interner).store(), + _ => return VariancesOf::empty(DbInterner::new_no_crate(db)).store(), } let generics = generics(db, def); let count = generics.len(); if count == 0 { - return VariancesOf::empty(interner).store(); + return VariancesOf::empty(DbInterner::new_no_crate(db)).store(); } - let variances = Context { generics, variances: vec![Variance::Bivariant; count], db }.solve(); + let variances = + Context { generics, variances: vec![Variance::Bivariant; count].into_boxed_slice(), db } + .solve(); VariancesOf::new_from_slice(&variances).store() } @@ -113,11 +114,11 @@ pub(crate) fn variances_of_cycle_initial( struct Context<'db> { db: &'db dyn HirDatabase, generics: Generics, - variances: Vec, + variances: Box<[Variance]>, } impl<'db> Context<'db> { - fn solve(mut self) -> Vec { + fn solve(mut self) -> Box<[Variance]> { tracing::debug!("solve(generics={:?})", self.generics); match self.generics.def() { GenericDefId::AdtId(adt) => { diff --git a/src/tools/rust-analyzer/crates/intern/src/intern.rs b/src/tools/rust-analyzer/crates/intern/src/intern.rs index b7acd6624b99..a96dfcfa9fe3 100644 --- a/src/tools/rust-analyzer/crates/intern/src/intern.rs +++ b/src/tools/rust-analyzer/crates/intern/src/intern.rs @@ -334,7 +334,7 @@ impl InternStorage { impl InternStorage { pub(crate) fn get(&self) -> &InternMap { - self.map.get_or_init(DashMap::default) + self.map.get_or_init(|| DashMap::with_capacity_and_hasher(1024, Default::default())) } } diff --git a/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs index 58de6e17bdff..8857771d2e01 100644 --- a/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs +++ b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs @@ -292,7 +292,12 @@ impl InternSliceStorage { impl InternSliceStorage { pub(crate) fn get(&self) -> &InternMap { - self.map.get_or_init(DashMap::default) + self.map.get_or_init(|| { + DashMap::with_capacity_and_hasher( + (64 * 1024) / std::mem::size_of::(), + Default::default(), + ) + }) } } From d7d49244ef9dafb7dff752b03561f369a9aab7e7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 4 Dec 2025 22:03:42 +0300 Subject: [PATCH 1505/3801] resolve: Introduce `ScopeSet::Module` for looking up a name in two scopes inside a module - non-glob and glob bindings. --- compiler/rustc_resolve/src/ident.rs | 187 ++++++++++++---------------- compiler/rustc_resolve/src/late.rs | 6 +- compiler/rustc_resolve/src/lib.rs | 2 + 3 files changed, 87 insertions(+), 108 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 61e98c60a5c9..82a87b8a9ed6 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -103,20 +103,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let rust_2015 = ctxt.edition().is_rust_2015(); let (ns, macro_kind) = match scope_set { - ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None), + ScopeSet::All(ns) + | ScopeSet::Module(ns, _) + | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None), ScopeSet::ExternPrelude => (TypeNS, None), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)), }; let module = match scope_set { // Start with the specified module. - ScopeSet::ModuleAndExternPrelude(_, module) => module, + ScopeSet::Module(_, module) | ScopeSet::ModuleAndExternPrelude(_, module) => module, // Jump out of trait or enum modules, they do not act as scopes. _ => parent_scope.module.nearest_item_scope(), }; + let module_only = matches!(scope_set, ScopeSet::Module(..)); let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)); let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude); let mut scope = match ns { - _ if module_and_extern_prelude => Scope::ModuleNonGlobs(module, None), + _ if module_only || module_and_extern_prelude => Scope::ModuleNonGlobs(module, None), _ if extern_prelude => Scope::ExternPreludeItems, TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None), MacroNS => Scope::DeriveHelpers(parent_scope.expansion), @@ -189,6 +192,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { MacroRulesScope::Empty => Scope::ModuleNonGlobs(module, None), }, Scope::ModuleNonGlobs(module, lint_id) => Scope::ModuleGlobs(module, lint_id), + Scope::ModuleGlobs(..) if module_only => break, Scope::ModuleGlobs(..) if module_and_extern_prelude => match ns { TypeNS => { ctxt.adjust(ExpnId::root()); @@ -336,13 +340,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { diag_metadata, ))); } else if let RibKind::Block(Some(module)) = rib.kind - && let Ok(binding) = self.cm().resolve_ident_in_module_unadjusted( - module, + && let Ok(binding) = self.cm().resolve_ident_in_scope_set( ident, - ns, + ScopeSet::Module(ns, module), parent_scope, - Shadowing::Unrestricted, finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }), + finalize.is_some(), ignore_binding, None, ) @@ -395,12 +398,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { assert!(force || finalize.is_none()); // `finalize` implies `force` // Make sure `self`, `super` etc produce an error when passed to here. - if orig_ident.is_path_segment_keyword() { + if orig_ident.is_path_segment_keyword() && !matches!(scope_set, ScopeSet::Module(..)) { return Err(Determinacy::Determined); } let (ns, macro_kind) = match scope_set { - ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None), + ScopeSet::All(ns) + | ScopeSet::Module(ns, _) + | ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None), ScopeSet::ExternPrelude => (TypeNS, None), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)), }; @@ -468,6 +473,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Found another solution, if the first one was "weak", report an error. if this.get_mut().maybe_push_ambiguity( orig_ident, + ns, + scope_set, parent_scope, binding, scope, @@ -562,21 +569,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { _ => Err(Determinacy::Determined), }, Scope::ModuleNonGlobs(module, derive_fallback_lint_id) => { - let (adjusted_parent_scope, adjusted_finalize) = - if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) { - (parent_scope, finalize) - } else { - ( - &ParentScope { module, ..*parent_scope }, - finalize.map(|f| Finalize { used: Used::Scope, ..f }), - ) - }; + let (adjusted_parent_scope, adjusted_finalize) = if matches!( + scope_set, + ScopeSet::Module(..) | ScopeSet::ModuleAndExternPrelude(..) + ) { + (parent_scope, finalize) + } else { + ( + &ParentScope { module, ..*parent_scope }, + finalize.map(|f| Finalize { used: Used::Scope, ..f }), + ) + }; let binding = self.reborrow().resolve_ident_in_module_non_globs_unadjusted( module, ident, ns, adjusted_parent_scope, - Shadowing::Restricted, + if matches!(scope_set, ScopeSet::Module(..)) { + Shadowing::Unrestricted + } else { + Shadowing::Restricted + }, adjusted_finalize, ignore_binding, ignore_import, @@ -598,29 +611,35 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Ok(binding) } Err(ControlFlow::Continue(determinacy)) => Err(determinacy), - Err(ControlFlow::Break(Determinacy::Undetermined)) => { - return Err(ControlFlow::Break(Determinacy::determined(force))); + Err(ControlFlow::Break(determinacy)) => { + return Err(ControlFlow::Break(Determinacy::determined( + determinacy == Determinacy::Determined || force, + ))); } - // Privacy errors, do not happen during in scope resolution. - Err(ControlFlow::Break(Determinacy::Determined)) => unreachable!(), } } Scope::ModuleGlobs(module, derive_fallback_lint_id) => { - let (adjusted_parent_scope, adjusted_finalize) = - if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) { - (parent_scope, finalize) - } else { - ( - &ParentScope { module, ..*parent_scope }, - finalize.map(|f| Finalize { used: Used::Scope, ..f }), - ) - }; + let (adjusted_parent_scope, adjusted_finalize) = if matches!( + scope_set, + ScopeSet::Module(..) | ScopeSet::ModuleAndExternPrelude(..) + ) { + (parent_scope, finalize) + } else { + ( + &ParentScope { module, ..*parent_scope }, + finalize.map(|f| Finalize { used: Used::Scope, ..f }), + ) + }; let binding = self.reborrow().resolve_ident_in_module_globs_unadjusted( module, ident, ns, adjusted_parent_scope, - Shadowing::Restricted, + if matches!(scope_set, ScopeSet::Module(..)) { + Shadowing::Unrestricted + } else { + Shadowing::Restricted + }, adjusted_finalize, ignore_binding, ignore_import, @@ -642,11 +661,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Ok(binding) } Err(ControlFlow::Continue(determinacy)) => Err(determinacy), - Err(ControlFlow::Break(Determinacy::Undetermined)) => { - return Err(ControlFlow::Break(Determinacy::determined(force))); + Err(ControlFlow::Break(determinacy)) => { + return Err(ControlFlow::Break(Determinacy::determined( + determinacy == Determinacy::Determined || force, + ))); } - // Privacy errors, do not happen during in scope resolution. - Err(ControlFlow::Break(Determinacy::Determined)) => unreachable!(), } } Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() { @@ -680,13 +699,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Scope::StdLibPrelude => { let mut result = Err(Determinacy::Determined); if let Some(prelude) = self.prelude - && let Ok(binding) = self.reborrow().resolve_ident_in_module_unadjusted( - prelude, + && let Ok(binding) = self.reborrow().resolve_ident_in_scope_set( ident, - ns, + ScopeSet::Module(ns, prelude), parent_scope, - Shadowing::Unrestricted, None, + false, ignore_binding, ignore_import, ) @@ -738,6 +756,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn maybe_push_ambiguity( &mut self, orig_ident: Ident, + ns: Namespace, + scope_set: ScopeSet<'ra>, parent_scope: &ParentScope<'ra>, binding: NameBinding<'ra>, scope: Scope<'ra>, @@ -751,6 +771,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // FIXME: Use `scope` instead of `res` to detect built-in attrs and derive helpers, // it will exclude imports, make slightly more code legal, and will require lang approval. + let module_only = matches!(scope_set, ScopeSet::Module(..)); let is_builtin = |res| matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..))); let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); let derive_helper_compat = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat); @@ -781,9 +802,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) } else if innermost_binding.is_glob_import() { Some(AmbiguityKind::GlobVsOuter) - } else if innermost_binding.may_appear_after(parent_scope.expansion, binding) { + } else if !module_only + && innermost_binding.may_appear_after(parent_scope.expansion, binding) + { Some(AmbiguityKind::MoreExpandedVsOuter) } else if innermost_binding.expansion != LocalExpnId::ROOT + && (!module_only || ns == MacroNS) && let Scope::ModuleGlobs(m1, _) = scope && let Scope::ModuleNonGlobs(m2, _) = innermost_scope && m1 == m2 @@ -887,18 +911,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ignore_import: Option>, ) -> Result, Determinacy> { match module { - ModuleOrUniformRoot::Module(module) => self - .resolve_ident_in_module_unadjusted( - module, - ident, - ns, - parent_scope, - Shadowing::Unrestricted, - finalize, - ignore_binding, - ignore_import, - ) - .map_err(|determinacy| determinacy.into_value()), + ModuleOrUniformRoot::Module(module) => self.resolve_ident_in_scope_set( + ident, + ScopeSet::Module(ns, module), + parent_scope, + finalize, + finalize.is_some(), + ignore_binding, + ignore_import, + ), ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set( ident, ScopeSet::ModuleAndExternPrelude(ns, module), @@ -948,48 +969,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - /// Attempts to resolve `ident` in namespace `ns` of `module`. - fn resolve_ident_in_module_unadjusted<'r>( - mut self: CmResolver<'r, 'ra, 'tcx>, - module: Module<'ra>, - ident: Ident, - ns: Namespace, - parent_scope: &ParentScope<'ra>, - shadowing: Shadowing, - finalize: Option, - // This binding should be ignored during in-module resolution, so that we don't get - // "self-confirming" import resolutions during import validation and checking. - ignore_binding: Option>, - ignore_import: Option>, - ) -> Result, ControlFlow> { - let res = self.reborrow().resolve_ident_in_module_non_globs_unadjusted( - module, - ident, - ns, - parent_scope, - shadowing, - finalize, - ignore_binding, - ignore_import, - ); - - match res { - Ok(_) | Err(ControlFlow::Break(_)) => return res, - Err(ControlFlow::Continue(_)) => {} - } - - self.resolve_ident_in_module_globs_unadjusted( - module, - ident, - ns, - parent_scope, - shadowing, - finalize, - ignore_binding, - ignore_import, - ) - } - /// Attempts to resolve `ident` in namespace `ns` of non-glob bindings in `module`. fn resolve_ident_in_module_non_globs_unadjusted<'r>( mut self: CmResolver<'r, 'ra, 'tcx>, @@ -999,6 +978,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, shadowing: Shadowing, finalize: Option, + // This binding should be ignored during in-module resolution, so that we don't get + // "self-confirming" import resolutions during import validation and checking. ignore_binding: Option>, ignore_import: Option>, ) -> Result, ControlFlow> { @@ -1156,28 +1137,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(None) => {} None => continue, }; - let result = self.reborrow().resolve_ident_in_module_unadjusted( - module, + let result = self.reborrow().resolve_ident_in_scope_set( ident, - ns, + ScopeSet::Module(ns, module), adjusted_parent_scope, - Shadowing::Unrestricted, None, + false, ignore_binding, ignore_import, ); match result { - Err(ControlFlow::Break(Determined) | ControlFlow::Continue(Determined)) => continue, + Err(Determined) => continue, Ok(binding) if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) => { continue; } - Ok(_) - | Err(ControlFlow::Break(Undetermined) | ControlFlow::Continue(Undetermined)) => { - return Err(ControlFlow::Continue(Undetermined)); - } + Ok(_) | Err(Undetermined) => return Err(ControlFlow::Continue(Undetermined)), } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index dd80f5da508c..290d21cad4b9 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -44,8 +44,8 @@ use tracing::{debug, instrument, trace}; use crate::{ BindingError, BindingKey, Finalize, LexicalScopeBinding, Module, ModuleOrUniformRoot, - NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, TyCtxt, UseError, - Used, errors, path_names_to_string, rustdoc, + NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, Stage, TyCtxt, + UseError, Used, errors, path_names_to_string, rustdoc, }; mod diagnostics; @@ -1514,7 +1514,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { opt_ns, &self.parent_scope, Some(source), - finalize, + finalize.map(|finalize| Finalize { stage: Stage::Late, ..finalize }), Some(&self.ribs), None, None, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index fa53d57d175e..1d462f173f4d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -153,6 +153,8 @@ enum Scope<'ra> { enum ScopeSet<'ra> { /// All scopes with the given namespace. All(Namespace), + /// Two scopes inside a module, for non-glob and glob bindings. + Module(Namespace, Module<'ra>), /// A module, then extern prelude (used for mixed 2015-2018 mode in macros). ModuleAndExternPrelude(Namespace, Module<'ra>), /// Just two extern prelude scopes. From f841758cf5136bd982631e497df35ddc5f80521a Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 2 Jan 2026 11:04:27 +0100 Subject: [PATCH 1506/3801] Remove unnecessary `ConstLiteralRef` enum --- .../crates/hir-def/src/expr_store/lower.rs | 1 - .../crates/hir-def/src/hir/type_ref.rs | 58 +------- .../crates/hir-ty/src/consteval.rs | 131 ++++++++++++++---- .../rust-analyzer/crates/hir-ty/src/lower.rs | 24 +--- .../crates/hir-ty/src/next_solver/ty.rs | 18 +++ 5 files changed, 132 insertions(+), 100 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index af274f1a485b..d3774ded39dc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -2319,7 +2319,6 @@ impl<'db> ExprCollector<'db> { ast::Pat::SlicePat(p) => { let SlicePatComponents { prefix, slice, suffix } = p.components(); - // FIXME properly handle `RestPat` Pat::Slice { prefix: prefix.into_iter().map(|p| self.collect_pat(p, binding_list)).collect(), slice: slice.map(|p| self.collect_pat(p, binding_list)), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs index ad8535413d67..b64199fa2697 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs @@ -1,8 +1,6 @@ //! HIR for references to types. Paths in these are not yet resolved. They can //! be directly created from an ast::TypeRef, without further queries. -use std::fmt::Write; - use hir_expand::name::Name; use intern::Symbol; use la_arena::Idx; @@ -10,12 +8,11 @@ use thin_vec::ThinVec; use crate::{ LifetimeParamId, TypeParamId, - builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, expr_store::{ ExpressionStore, path::{GenericArg, Path}, }, - hir::{ExprId, Literal}, + hir::ExprId, }; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -275,56 +272,3 @@ impl TypeBound { pub struct ConstRef { pub expr: ExprId, } - -/// A literal constant value -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum LiteralConstRef { - Int(i128), - UInt(u128), - Bool(bool), - Char(char), - - /// Case of an unknown value that rustc might know but we don't - // FIXME: this is a hack to get around chalk not being able to represent unevaluatable - // constants - // https://github.com/rust-lang/rust-analyzer/pull/8813#issuecomment-840679177 - // https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/Handling.20non.20evaluatable.20constants'.20equality/near/238386348 - Unknown, -} - -impl LiteralConstRef { - pub fn builtin_type(&self) -> BuiltinType { - match self { - LiteralConstRef::UInt(_) | LiteralConstRef::Unknown => { - BuiltinType::Uint(BuiltinUint::U128) - } - LiteralConstRef::Int(_) => BuiltinType::Int(BuiltinInt::I128), - LiteralConstRef::Char(_) => BuiltinType::Char, - LiteralConstRef::Bool(_) => BuiltinType::Bool, - } - } -} - -impl From for LiteralConstRef { - fn from(literal: Literal) -> Self { - match literal { - Literal::Char(c) => Self::Char(c), - Literal::Bool(flag) => Self::Bool(flag), - Literal::Int(num, _) => Self::Int(num), - Literal::Uint(num, _) => Self::UInt(num), - _ => Self::Unknown, - } - } -} - -impl std::fmt::Display for LiteralConstRef { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - match self { - LiteralConstRef::Int(num) => num.fmt(f), - LiteralConstRef::UInt(num) => num.fmt(f), - LiteralConstRef::Bool(flag) => flag.fmt(f), - LiteralConstRef::Char(c) => write!(f, "'{c}'"), - LiteralConstRef::Unknown => f.write_char('_'), - } - } -} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index f11240e0f78c..5bc2446fdd2d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -7,9 +7,9 @@ use base_db::Crate; use hir_def::{ ConstId, EnumVariantId, GeneralConstId, HasModule, StaticId, attrs::AttrFlags, + builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, expr_store::Body, - hir::{Expr, ExprId}, - type_ref::LiteralConstRef, + hir::{Expr, ExprId, Literal}, }; use hir_expand::Lookup; use rustc_type_ir::inherent::IntoKind; @@ -23,7 +23,7 @@ use crate::{ mir::{MirEvalError, MirLowerError}, next_solver::{ Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, - ParamEnv, StoredConst, StoredGenericArgs, Ty, ValueConst, + StoredConst, StoredGenericArgs, Ty, ValueConst, }, traits::StoredParamEnvAndCrate, }; @@ -81,47 +81,122 @@ impl From for ConstEvalError { /// Interns a constant scalar with the given type pub fn intern_const_ref<'a>( db: &'a dyn HirDatabase, - value: &LiteralConstRef, + value: &Literal, ty: Ty<'a>, - krate: Crate, + _krate: Crate, ) -> Const<'a> { let interner = DbInterner::new_no_crate(db); - let layout = db - .layout_of_ty(ty.store(), ParamEnvAndCrate { param_env: ParamEnv::empty(), krate }.store()); let kind = match value { - LiteralConstRef::Int(i) => { - // FIXME: We should handle failure of layout better. - let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16); + &Literal::Uint(i, builtin_ty) + if builtin_ty.is_none() || ty.as_builtin() == builtin_ty.map(BuiltinType::Uint) => + { + let memory = match ty.as_builtin() { + Some(BuiltinType::Uint(builtin_uint)) => match builtin_uint { + BuiltinUint::U8 => Box::new([i as u8]) as Box<[u8]>, + BuiltinUint::U16 => Box::new((i as u16).to_le_bytes()), + BuiltinUint::U32 => Box::new((i as u32).to_le_bytes()), + BuiltinUint::U64 => Box::new((i as u64).to_le_bytes()), + BuiltinUint::U128 => Box::new((i).to_le_bytes()), + BuiltinUint::Usize => Box::new((i as usize).to_le_bytes()), + }, + _ => return Const::new(interner, rustc_type_ir::ConstKind::Error(ErrorGuaranteed)), + }; rustc_type_ir::ConstKind::Value(ValueConst::new( ty, - ConstBytes { - memory: i.to_le_bytes()[0..size].into(), - memory_map: MemoryMap::default(), - }, + ConstBytes { memory, memory_map: MemoryMap::default() }, )) } - LiteralConstRef::UInt(i) => { - let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16); + &Literal::Int(i, None) + if ty + .as_builtin() + .is_some_and(|builtin_ty| matches!(builtin_ty, BuiltinType::Uint(_))) => + { + let memory = match ty.as_builtin() { + Some(BuiltinType::Uint(builtin_uint)) => match builtin_uint { + BuiltinUint::U8 => Box::new([i as u8]) as Box<[u8]>, + BuiltinUint::U16 => Box::new((i as u16).to_le_bytes()), + BuiltinUint::U32 => Box::new((i as u32).to_le_bytes()), + BuiltinUint::U64 => Box::new((i as u64).to_le_bytes()), + BuiltinUint::U128 => Box::new((i as u128).to_le_bytes()), + BuiltinUint::Usize => Box::new((i as usize).to_le_bytes()), + }, + _ => return Const::new(interner, rustc_type_ir::ConstKind::Error(ErrorGuaranteed)), + }; rustc_type_ir::ConstKind::Value(ValueConst::new( ty, - ConstBytes { - memory: i.to_le_bytes()[0..size].into(), - memory_map: MemoryMap::default(), - }, + ConstBytes { memory, memory_map: MemoryMap::default() }, )) } - LiteralConstRef::Bool(b) => rustc_type_ir::ConstKind::Value(ValueConst::new( + &Literal::Int(i, builtin_ty) + if builtin_ty.is_none() || ty.as_builtin() == builtin_ty.map(BuiltinType::Int) => + { + let memory = match ty.as_builtin() { + Some(BuiltinType::Int(builtin_int)) => match builtin_int { + BuiltinInt::I8 => Box::new([i as u8]) as Box<[u8]>, + BuiltinInt::I16 => Box::new((i as i16).to_le_bytes()), + BuiltinInt::I32 => Box::new((i as i32).to_le_bytes()), + BuiltinInt::I64 => Box::new((i as i64).to_le_bytes()), + BuiltinInt::I128 => Box::new((i).to_le_bytes()), + BuiltinInt::Isize => Box::new((i as isize).to_le_bytes()), + }, + _ => return Const::new(interner, rustc_type_ir::ConstKind::Error(ErrorGuaranteed)), + }; + rustc_type_ir::ConstKind::Value(ValueConst::new( + ty, + ConstBytes { memory, memory_map: MemoryMap::default() }, + )) + } + Literal::Float(float_type_wrapper, builtin_float) + if builtin_float.is_none() + || ty.as_builtin() == builtin_float.map(BuiltinType::Float) => + { + let memory = match ty.as_builtin().unwrap() { + BuiltinType::Float(builtin_float) => match builtin_float { + // FIXME: + hir_def::builtin_type::BuiltinFloat::F16 => Box::new([0u8; 2]) as Box<[u8]>, + hir_def::builtin_type::BuiltinFloat::F32 => { + Box::new(float_type_wrapper.to_f32().to_le_bytes()) + } + hir_def::builtin_type::BuiltinFloat::F64 => { + Box::new(float_type_wrapper.to_f64().to_le_bytes()) + } + // FIXME: + hir_def::builtin_type::BuiltinFloat::F128 => Box::new([0; 16]), + }, + _ => unreachable!(), + }; + rustc_type_ir::ConstKind::Value(ValueConst::new( + ty, + ConstBytes { memory, memory_map: MemoryMap::default() }, + )) + } + Literal::Bool(b) if ty.is_bool() => rustc_type_ir::ConstKind::Value(ValueConst::new( ty, ConstBytes { memory: Box::new([*b as u8]), memory_map: MemoryMap::default() }, )), - LiteralConstRef::Char(c) => rustc_type_ir::ConstKind::Value(ValueConst::new( + Literal::Char(c) if ty.is_char() => rustc_type_ir::ConstKind::Value(ValueConst::new( ty, ConstBytes { memory: (*c as u32).to_le_bytes().into(), memory_map: MemoryMap::default(), }, )), - LiteralConstRef::Unknown => rustc_type_ir::ConstKind::Error(ErrorGuaranteed), + Literal::String(symbol) if ty.is_str() => rustc_type_ir::ConstKind::Value(ValueConst::new( + ty, + ConstBytes { + memory: symbol.as_str().as_bytes().into(), + memory_map: MemoryMap::default(), + }, + )), + Literal::ByteString(items) if ty.as_slice().is_some_and(|ty| ty.is_u8()) => { + rustc_type_ir::ConstKind::Value(ValueConst::new( + ty, + ConstBytes { memory: items.clone(), memory_map: MemoryMap::default() }, + )) + } + // FIXME + Literal::CString(_items) => rustc_type_ir::ConstKind::Error(ErrorGuaranteed), + _ => rustc_type_ir::ConstKind::Error(ErrorGuaranteed), }; Const::new(interner, kind) } @@ -130,7 +205,15 @@ pub fn intern_const_ref<'a>( pub fn usize_const<'db>(db: &'db dyn HirDatabase, value: Option, krate: Crate) -> Const<'db> { intern_const_ref( db, - &value.map_or(LiteralConstRef::Unknown, LiteralConstRef::UInt), + &match value { + Some(value) => Literal::Uint(value, Some(BuiltinUint::Usize)), + None => { + return Const::new( + DbInterner::new_no_crate(db), + rustc_type_ir::ConstKind::Error(ErrorGuaranteed), + ); + } + }, Ty::new_uint(DbInterner::new_no_crate(db), rustc_type_ir::UintTy::Usize), krate, ) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 9307868f3982..6688cf3d6025 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -27,8 +27,8 @@ use hir_def::{ resolver::{HasResolver, LifetimeNs, Resolver, TypeNs, ValueNs}, signatures::{FunctionSignature, TraitFlags, TypeAliasFlags}, type_ref::{ - ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier, - TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId, + ConstRef, LifetimeRefId, PathId, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, + TypeRef, TypeRefId, }, }; use hir_expand::name::Name; @@ -281,21 +281,9 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { hir_def::hir::Expr::Path(path) => { self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type)) } - hir_def::hir::Expr::Literal(literal) => intern_const_ref( - self.db, - &match *literal { - hir_def::hir::Literal::Float(_, _) - | hir_def::hir::Literal::String(_) - | hir_def::hir::Literal::ByteString(_) - | hir_def::hir::Literal::CString(_) => LiteralConstRef::Unknown, - hir_def::hir::Literal::Char(c) => LiteralConstRef::Char(c), - hir_def::hir::Literal::Bool(b) => LiteralConstRef::Bool(b), - hir_def::hir::Literal::Int(val, _) => LiteralConstRef::Int(val), - hir_def::hir::Literal::Uint(val, _) => LiteralConstRef::UInt(val), - }, - const_type, - self.resolver.krate(), - ), + hir_def::hir::Expr::Literal(literal) => { + intern_const_ref(self.db, literal, const_type, self.resolver.krate()) + } hir_def::hir::Expr::UnaryOp { expr: inner_expr, op: hir_def::hir::UnaryOp::Neg } => { if let hir_def::hir::Expr::Literal(literal) = &self.store[*inner_expr] { // Only handle negation for signed integers and floats @@ -304,7 +292,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { if let Some(negated_literal) = literal.clone().negate() { intern_const_ref( self.db, - &negated_literal.into(), + &negated_literal, const_type, self.resolver.krate(), ) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs index 030ba37015f2..66a24d394990 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs @@ -383,6 +383,11 @@ impl<'db> Ty<'db> { matches!(self.kind(), TyKind::Bool) } + #[inline] + pub fn is_char(self) -> bool { + matches!(self.kind(), TyKind::Char) + } + /// A scalar type is one that denotes an atomic datum, with no sub-components. /// (A RawPtr is scalar because it represents a non-managed pointer, so its /// contents are abstract to rustc.) @@ -422,6 +427,11 @@ impl<'db> Ty<'db> { matches!(self.kind(), TyKind::Tuple(tys) if tys.is_empty()) } + #[inline] + pub fn is_u8(self) -> bool { + matches!(self.kind(), TyKind::Uint(UintTy::U8)) + } + #[inline] pub fn is_raw_ptr(self) -> bool { matches!(self.kind(), TyKind::RawPtr(..)) @@ -456,6 +466,14 @@ impl<'db> Ty<'db> { } } + #[inline] + pub fn as_slice(self) -> Option> { + match self.kind() { + TyKind::Slice(ty) => Some(ty), + _ => None, + } + } + #[inline] pub fn ty_vid(self) -> Option { match self.kind() { From 0016a7174768082ea50187847e86b288ec28281a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 5 Dec 2025 16:31:04 +0300 Subject: [PATCH 1507/3801] resolve: Migrate one more special ambiguity for glob vs non-glob bindings in the same module to the usual ambiguity infra in `resolve_ident_in_scope_set` --- compiler/rustc_resolve/src/ident.rs | 3 +- compiler/rustc_resolve/src/imports.rs | 15 +----- .../ambiguous-glob-vs-expanded-extern.rs | 4 +- .../ambiguous-glob-vs-expanded-extern.stderr | 53 ------------------- tests/ui/imports/issue-114682-1.rs | 1 - tests/ui/imports/issue-114682-1.stderr | 27 +--------- .../local-modularized-tricky-fail-1.rs | 1 - .../local-modularized-tricky-fail-1.stderr | 31 ++--------- tests/ui/imports/macros.rs | 2 +- tests/ui/imports/macros.stderr | 21 +------- 10 files changed, 11 insertions(+), 147 deletions(-) delete mode 100644 tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 82a87b8a9ed6..512b35310539 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -813,7 +813,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && m1 == m2 { // FIXME: this error is too conservative and technically unnecessary now when module - // scope is split into two scopes, remove it with lang team approval. + // scope is split into two scopes, at least when not resolving in `ScopeSet::Module`, + // remove it with lang team approval. Some(AmbiguityKind::GlobVsExpanded) } else { None diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 4e0f3db59821..a46ed5d8e69e 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -389,20 +389,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { (old_glob @ true, false) | (old_glob @ false, true) => { let (glob_binding, non_glob_binding) = if old_glob { (old_binding, binding) } else { (binding, old_binding) }; - if ns == MacroNS - && non_glob_binding.expansion != LocalExpnId::ROOT - && glob_binding.res() != non_glob_binding.res() - { - resolution.non_glob_binding = Some(this.new_ambiguity_binding( - AmbiguityKind::GlobVsExpanded, - non_glob_binding, - glob_binding, - false, - )); - } else { - resolution.non_glob_binding = Some(non_glob_binding); - } - + resolution.non_glob_binding = Some(non_glob_binding); if let Some(old_glob_binding) = resolution.glob_binding { assert!(old_glob_binding.is_glob_import()); if glob_binding.res() != old_glob_binding.res() { diff --git a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs index de632119ecba..0277da46f750 100644 --- a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs +++ b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs @@ -1,6 +1,6 @@ +//@ check-pass //@ aux-crate: glob_vs_expanded=glob-vs-expanded.rs fn main() { - glob_vs_expanded::mac!(); //~ ERROR `mac` is ambiguous - //~| WARN this was previously accepted + glob_vs_expanded::mac!(); // OK } diff --git a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr deleted file mode 100644 index 4a9a6c99819b..000000000000 --- a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr +++ /dev/null @@ -1,53 +0,0 @@ -error: `mac` is ambiguous - --> $DIR/ambiguous-glob-vs-expanded-extern.rs:4:23 - | -LL | glob_vs_expanded::mac!(); - | ^^^ ambiguous name - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #114095 - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution -note: `mac` could refer to the macro defined here - --> $DIR/auxiliary/glob-vs-expanded.rs:9:13 - | -LL | () => { pub macro mac() {} } - | ^^^^^^^^^^^^^ -LL | } -LL | define_mac!(); - | ------------- in this macro invocation -note: `mac` could also refer to the macro defined here - --> $DIR/auxiliary/glob-vs-expanded.rs:5:9 - | -LL | pub use inner::*; - | ^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default - = note: this error originates in the macro `define_mac` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 1 previous error - -Future incompatibility report: Future breakage diagnostic: -error: `mac` is ambiguous - --> $DIR/ambiguous-glob-vs-expanded-extern.rs:4:23 - | -LL | glob_vs_expanded::mac!(); - | ^^^ ambiguous name - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #114095 - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution -note: `mac` could refer to the macro defined here - --> $DIR/auxiliary/glob-vs-expanded.rs:9:13 - | -LL | () => { pub macro mac() {} } - | ^^^^^^^^^^^^^ -LL | } -LL | define_mac!(); - | ------------- in this macro invocation -note: `mac` could also refer to the macro defined here - --> $DIR/auxiliary/glob-vs-expanded.rs:5:9 - | -LL | pub use inner::*; - | ^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default - = note: this error originates in the macro `define_mac` (in Nightly builds, run with -Z macro-backtrace for more info) - diff --git a/tests/ui/imports/issue-114682-1.rs b/tests/ui/imports/issue-114682-1.rs index 58b78508026d..88fe05e51444 100644 --- a/tests/ui/imports/issue-114682-1.rs +++ b/tests/ui/imports/issue-114682-1.rs @@ -22,5 +22,4 @@ mac!(); fn main() { A!(); //~^ ERROR `A` is ambiguous - //~| ERROR `A` is ambiguous } diff --git a/tests/ui/imports/issue-114682-1.stderr b/tests/ui/imports/issue-114682-1.stderr index de8dc6cfb9ff..fd2776f50ad7 100644 --- a/tests/ui/imports/issue-114682-1.stderr +++ b/tests/ui/imports/issue-114682-1.stderr @@ -1,28 +1,3 @@ -error[E0659]: `A` is ambiguous - --> $DIR/issue-114682-1.rs:23:5 - | -LL | A!(); - | ^ ambiguous name - | - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution -note: `A` could refer to the macro defined here - --> $DIR/issue-114682-1.rs:7:9 - | -LL | / pub macro A() { -LL | | println!("non import") -LL | | } - | |_________^ -... -LL | mac!(); - | ------ in this macro invocation -note: `A` could also refer to the macro imported here - --> $DIR/issue-114682-1.rs:19:9 - | -LL | pub use m::*; - | ^^^^ - = help: consider adding an explicit import of `A` to disambiguate - = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0659]: `A` is ambiguous --> $DIR/issue-114682-1.rs:23:5 | @@ -49,6 +24,6 @@ LL | pub use m::*; = help: use `crate::A` to refer to this macro unambiguously = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/local-modularized-tricky-fail-1.rs b/tests/ui/imports/local-modularized-tricky-fail-1.rs index bba26ee43a24..ce700ae0de9b 100644 --- a/tests/ui/imports/local-modularized-tricky-fail-1.rs +++ b/tests/ui/imports/local-modularized-tricky-fail-1.rs @@ -27,7 +27,6 @@ mod inner1 { } exported!(); //~ ERROR `exported` is ambiguous - //~| ERROR `exported` is ambiguous mod inner2 { define_exported!(); diff --git a/tests/ui/imports/local-modularized-tricky-fail-1.stderr b/tests/ui/imports/local-modularized-tricky-fail-1.stderr index 54d928f7c812..b5b3be5953f9 100644 --- a/tests/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/tests/ui/imports/local-modularized-tricky-fail-1.stderr @@ -1,28 +1,3 @@ -error[E0659]: `exported` is ambiguous - --> $DIR/local-modularized-tricky-fail-1.rs:29:1 - | -LL | exported!(); - | ^^^^^^^^ ambiguous name - | - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution -note: `exported` could refer to the macro defined here - --> $DIR/local-modularized-tricky-fail-1.rs:6:5 - | -LL | / macro_rules! exported { -LL | | () => () -LL | | } - | |_____^ -... -LL | define_exported!(); - | ------------------ in this macro invocation -note: `exported` could also refer to the macro imported here - --> $DIR/local-modularized-tricky-fail-1.rs:23:5 - | -LL | use inner1::*; - | ^^^^^^^^^ - = help: consider adding an explicit import of `exported` to disambiguate - = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0659]: `exported` is ambiguous --> $DIR/local-modularized-tricky-fail-1.rs:29:1 | @@ -50,7 +25,7 @@ LL | use inner1::*; = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `panic` is ambiguous - --> $DIR/local-modularized-tricky-fail-1.rs:37:5 + --> $DIR/local-modularized-tricky-fail-1.rs:36:5 | LL | panic!(); | ^^^^^ ambiguous name @@ -71,7 +46,7 @@ LL | define_panic!(); = note: this error originates in the macro `define_panic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `include` is ambiguous - --> $DIR/local-modularized-tricky-fail-1.rs:48:1 + --> $DIR/local-modularized-tricky-fail-1.rs:47:1 | LL | include!(); | ^^^^^^^ ambiguous name @@ -91,6 +66,6 @@ LL | define_include!(); = help: use `crate::include` to refer to this macro unambiguously = note: this error originates in the macro `define_include` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/macros.rs b/tests/ui/imports/macros.rs index cf67e08c87a3..e1db42abd28f 100644 --- a/tests/ui/imports/macros.rs +++ b/tests/ui/imports/macros.rs @@ -13,7 +13,7 @@ mod m1 { mod m2 { use two_macros::*; - m! { //~ ERROR ambiguous + m! { use crate::foo::m; } } diff --git a/tests/ui/imports/macros.stderr b/tests/ui/imports/macros.stderr index 25a678c6b375..08ebfa5b8151 100644 --- a/tests/ui/imports/macros.stderr +++ b/tests/ui/imports/macros.stderr @@ -1,22 +1,3 @@ -error[E0659]: `m` is ambiguous - --> $DIR/macros.rs:16:5 - | -LL | m! { - | ^ ambiguous name - | - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution -note: `m` could refer to the macro imported here - --> $DIR/macros.rs:17:13 - | -LL | use crate::foo::m; - | ^^^^^^^^^^^^^ -note: `m` could also refer to the macro imported here - --> $DIR/macros.rs:15:9 - | -LL | use two_macros::*; - | ^^^^^^^^^^^^^ - = help: consider adding an explicit import of `m` to disambiguate - error[E0659]: `m` is ambiguous --> $DIR/macros.rs:29:9 | @@ -36,6 +17,6 @@ LL | use two_macros::m; | ^^^^^^^^^^^^^ = help: use `self::m` to refer to this macro unambiguously -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0659`. From 78c61beb4816a9f103429da9a5cf49eeb6610ec9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 5 Dec 2025 17:47:02 +0300 Subject: [PATCH 1508/3801] resolve: Patch up an inconsistent resolution ICE revealed by the previous commit --- compiler/rustc_resolve/src/ident.rs | 8 ++++++++ tests/ui/imports/macros.rs | 2 +- tests/ui/imports/macros.stderr | 22 +++++++++++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 512b35310539..f400ae8f6439 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1249,6 +1249,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, ) -> bool { for single_import in &resolution.single_imports { + if let Some(binding) = resolution.non_glob_binding + && let NameBindingKind::Import { import, .. } = binding.kind + && import == *single_import + { + // Single import has already defined the name and we are aware of it, + // no need to block the globs. + continue; + } if ignore_import == Some(*single_import) { continue; } diff --git a/tests/ui/imports/macros.rs b/tests/ui/imports/macros.rs index e1db42abd28f..121f1f7ae043 100644 --- a/tests/ui/imports/macros.rs +++ b/tests/ui/imports/macros.rs @@ -13,7 +13,7 @@ mod m1 { mod m2 { use two_macros::*; - m! { + m! { //~ ERROR `m` is ambiguous use crate::foo::m; } } diff --git a/tests/ui/imports/macros.stderr b/tests/ui/imports/macros.stderr index 08ebfa5b8151..9c081cc7af8b 100644 --- a/tests/ui/imports/macros.stderr +++ b/tests/ui/imports/macros.stderr @@ -1,3 +1,23 @@ +error[E0659]: `m` is ambiguous + --> $DIR/macros.rs:16:5 + | +LL | m! { + | ^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `m` could refer to the macro imported here + --> $DIR/macros.rs:17:13 + | +LL | use crate::foo::m; + | ^^^^^^^^^^^^^ + = help: use `self::m` to refer to this macro unambiguously +note: `m` could also refer to the macro imported here + --> $DIR/macros.rs:15:9 + | +LL | use two_macros::*; + | ^^^^^^^^^^^^^ + = help: use `self::m` to refer to this macro unambiguously + error[E0659]: `m` is ambiguous --> $DIR/macros.rs:29:9 | @@ -17,6 +37,6 @@ LL | use two_macros::m; | ^^^^^^^^^^^^^ = help: use `self::m` to refer to this macro unambiguously -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. From 2e123aef706ac12e1277b90c933055d0b4b79d9b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 2 Jan 2026 14:29:23 +0300 Subject: [PATCH 1509/3801] resolve: Avoid additional ambiguities from splitting modules into two scopes --- compiler/rustc_resolve/src/ident.rs | 15 ++++++++++++- tests/ui/imports/overwritten-glob-ambig.rs | 26 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/ui/imports/overwritten-glob-ambig.rs diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index f400ae8f6439..c9f560d2a6fa 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -828,8 +828,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && innermost_results[1..].iter().any(|(b, s)| { matches!(s, Scope::ExternPreludeItems) && *b != innermost_binding }); + // Skip ambiguity errors for nonglob module bindings "overridden" + // by glob module bindings in the same module. + // FIXME: Remove with lang team approval. + let issue_149681_hack = match scope { + Scope::ModuleGlobs(m1, _) + if innermost_results[1..] + .iter() + .any(|(_, s)| matches!(*s, Scope::ModuleNonGlobs(m2, _) if m1 == m2)) => + { + true + } + _ => false, + }; - if issue_145575_hack { + if issue_145575_hack || issue_149681_hack { self.issue_145575_hack_applied = true; } else { self.ambiguity_errors.push(AmbiguityError { diff --git a/tests/ui/imports/overwritten-glob-ambig.rs b/tests/ui/imports/overwritten-glob-ambig.rs new file mode 100644 index 000000000000..a5918568c62a --- /dev/null +++ b/tests/ui/imports/overwritten-glob-ambig.rs @@ -0,0 +1,26 @@ +// Test for a regression introduced by splitting module scope into two scopes +// (similar to issue #145575). + +//@ check-pass +//@ edition: 2018.. + +#[macro_use] +mod one { + // Macro that is in a different module, but still in scope due to `macro_use` + macro_rules! mac { () => {} } + pub(crate) use mac; +} + +mod other { + macro_rules! mac { () => {} } + pub(crate) use mac; +} + +// Single import of the same in the current module. +use one::mac; +// Glob import of a different macro in the current module (should be an ambiguity). +use other::*; + +fn main() { + mac!(); // OK for now, the ambiguity is not reported +} From 3f3db936514dca81c1e6ca6d004da9921450d981 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 2 Jan 2026 15:40:21 +0300 Subject: [PATCH 1510/3801] metadata: Stop keeping `AmbiguityKind` in name bindings It can only be `GlobVsGlob` now. --- compiler/rustc_middle/src/metadata.rs | 7 ----- .../rustc_resolve/src/build_reduced_graph.rs | 22 ++++++--------- compiler/rustc_resolve/src/imports.rs | 28 ++++++------------- compiler/rustc_resolve/src/lib.rs | 10 +++---- 4 files changed, 22 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index 2b0be9865799..b7848bc261d8 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -45,16 +45,9 @@ pub struct ModChild { pub reexport_chain: SmallVec<[Reexport; 2]>, } -#[derive(Debug, TyEncodable, TyDecodable, HashStable)] -pub enum AmbigModChildKind { - GlobVsGlob, - GlobVsExpanded, -} - /// Same as `ModChild`, however, it includes ambiguity error. #[derive(Debug, TyEncodable, TyDecodable, HashStable)] pub struct AmbigModChild { pub main: ModChild, pub second: ModChild, - pub kind: AmbigModChildKind, } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index b9c945a440f8..241c13663ae5 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -22,7 +22,7 @@ use rustc_hir::def::{self, *}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::LoadedMacro; -use rustc_middle::metadata::{AmbigModChildKind, ModChild, Reexport}; +use rustc_middle::metadata::{ModChild, Reexport}; use rustc_middle::ty::{Feed, Visibility}; use rustc_middle::{bug, span_bug}; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind}; @@ -36,9 +36,9 @@ use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use crate::ref_mut::CmCell; use crate::{ - AmbiguityKind, BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, - ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, - ResolutionError, Resolver, Segment, Used, VisResolutionError, errors, + BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot, + NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, ResolutionError, + Resolver, Segment, Used, VisResolutionError, errors, }; type Res = def::Res; @@ -82,7 +82,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { vis: Visibility, span: Span, expansion: LocalExpnId, - ambiguity: Option<(NameBinding<'ra>, AmbiguityKind)>, + ambiguity: Option>, ) { let binding = self.arenas.alloc_name_binding(NameBindingData { kind: NameBindingKind::Res(res), @@ -254,7 +254,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &child.main, parent_scope, children.len() + i, - Some((&child.second, child.kind)), + Some(&child.second), ) } } @@ -265,7 +265,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { child: &ModChild, parent_scope: ParentScope<'ra>, child_index: usize, - ambig_child: Option<(&ModChild, AmbigModChildKind)>, + ambig_child: Option<&ModChild>, ) { let parent = parent_scope.module; let child_span = |this: &Self, reexport_chain: &[Reexport], res: def::Res<_>| { @@ -280,15 +280,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let span = child_span(self, reexport_chain, res); let res = res.expect_non_local(); let expansion = parent_scope.expansion; - let ambig = ambig_child.map(|(ambig_child, ambig_kind)| { + let ambig = ambig_child.map(|ambig_child| { let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child; let span = child_span(self, reexport_chain, res); let res = res.expect_non_local(); - let ambig_kind = match ambig_kind { - AmbigModChildKind::GlobVsGlob => AmbiguityKind::GlobVsGlob, - AmbigModChildKind::GlobVsExpanded => AmbiguityKind::GlobVsExpanded, - }; - (self.arenas.new_res_binding(res, vis, span, expansion), ambig_kind) + self.arenas.new_res_binding(res, vis, span, expansion) }); // Record primary definitions. diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index a46ed5d8e69e..558f769eda19 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -9,7 +9,7 @@ use rustc_errors::codes::*; use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err}; use rustc_hir::def::{self, DefKind, PartialRes}; use rustc_hir::def_id::{DefId, LocalDefIdMap}; -use rustc_middle::metadata::{AmbigModChild, AmbigModChildKind, ModChild, Reexport}; +use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::span_bug; use rustc_middle::ty::Visibility; use rustc_session::lint::BuiltinLintDiag; @@ -32,10 +32,9 @@ use crate::errors::{ }; use crate::ref_mut::CmCell; use crate::{ - AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Determinacy, Finalize, ImportSuggestion, - Module, ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, - PathResult, PerNS, ResolutionError, Resolver, ScopeSet, Segment, Used, module_to_string, - names_to_string, + AmbiguityError, BindingKey, CmResolver, Determinacy, Finalize, ImportSuggestion, Module, + ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, + PerNS, ResolutionError, Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string, }; type Res = def::Res; @@ -373,7 +372,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { resolution.glob_binding = Some(glob_binding); } else if res != old_glob_binding.res() { resolution.glob_binding = Some(this.new_ambiguity_binding( - AmbiguityKind::GlobVsGlob, old_glob_binding, glob_binding, warn_ambiguity, @@ -394,7 +392,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { assert!(old_glob_binding.is_glob_import()); if glob_binding.res() != old_glob_binding.res() { resolution.glob_binding = Some(this.new_ambiguity_binding( - AmbiguityKind::GlobVsGlob, old_glob_binding, glob_binding, false, @@ -424,12 +421,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn new_ambiguity_binding( &self, - ambiguity_kind: AmbiguityKind, primary_binding: NameBinding<'ra>, secondary_binding: NameBinding<'ra>, warn_ambiguity: bool, ) -> NameBinding<'ra> { - let ambiguity = Some((secondary_binding, ambiguity_kind)); + let ambiguity = Some(secondary_binding); let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding }; self.arenas.alloc_name_binding(data) } @@ -645,7 +641,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let Some(binding) = resolution.best_binding() else { continue }; if let NameBindingKind::Import { import, .. } = binding.kind - && let Some((amb_binding, _)) = binding.ambiguity + && let Some(amb_binding) = binding.ambiguity && binding.res() != Res::Err && exported_ambiguities.contains(&binding) { @@ -1553,9 +1549,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { vis: binding.vis, reexport_chain, }; - if let Some((ambig_binding1, ambig_binding2, ambig_kind)) = - binding.descent_to_ambiguity() - { + if let Some((ambig_binding1, ambig_binding2)) = binding.descent_to_ambiguity() { let main = child(ambig_binding1.reexport_chain(this)); let second = ModChild { ident: ident.0, @@ -1563,13 +1557,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { vis: ambig_binding2.vis, reexport_chain: ambig_binding2.reexport_chain(this), }; - let kind = match ambig_kind { - AmbiguityKind::GlobVsGlob => AmbigModChildKind::GlobVsGlob, - AmbiguityKind::GlobVsExpanded => AmbigModChildKind::GlobVsExpanded, - _ => unreachable!(), - }; - - ambig_children.push(AmbigModChild { main, second, kind }) + ambig_children.push(AmbigModChild { main, second }) } else { children.push(child(binding.reexport_chain(this))); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 1d462f173f4d..fbd16072c2c0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -807,7 +807,7 @@ impl<'ra> fmt::Debug for Module<'ra> { #[derive(Clone, Copy, Debug)] struct NameBindingData<'ra> { kind: NameBindingKind<'ra>, - ambiguity: Option<(NameBinding<'ra>, AmbiguityKind)>, + ambiguity: Option>, /// Produce a warning instead of an error when reporting ambiguities inside this binding. /// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required. warn_ambiguity: bool, @@ -937,9 +937,9 @@ impl<'ra> NameBindingData<'ra> { fn descent_to_ambiguity( self: NameBinding<'ra>, - ) -> Option<(NameBinding<'ra>, NameBinding<'ra>, AmbiguityKind)> { + ) -> Option<(NameBinding<'ra>, NameBinding<'ra>)> { match self.ambiguity { - Some((ambig_binding, ambig_kind)) => Some((self, ambig_binding, ambig_kind)), + Some(ambig_binding) => Some((self, ambig_binding)), None => match self.kind { NameBindingKind::Import { binding, .. } => binding.descent_to_ambiguity(), _ => None, @@ -2064,9 +2064,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { used: Used, warn_ambiguity: bool, ) { - if let Some((b2, kind)) = used_binding.ambiguity { + if let Some(b2) = used_binding.ambiguity { let ambiguity_error = AmbiguityError { - kind, + kind: AmbiguityKind::GlobVsGlob, ident, b1: used_binding, b2, From bfe591aac4c83c4e542a0fa3b00a88d7d6f242ca Mon Sep 17 00:00:00 2001 From: Alessio Date: Fri, 2 Jan 2026 14:54:36 +0100 Subject: [PATCH 1511/3801] library: Fix typo in the documentatio of `Cstring::from_vec_with_nul` Fixes the sentence "Attempts to converts a Vec to a CString.", where "converts" should be in the base form as it is part of the to-infinitive form. --- library/alloc/src/ffi/c_str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 59f5857b97aa..d6dcba7107a9 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -636,7 +636,7 @@ impl CString { Self { inner: v.into_boxed_slice() } } - /// Attempts to converts a [Vec]<[u8]> to a [`CString`]. + /// Attempts to convert a [Vec]<[u8]> to a [`CString`]. /// /// Runtime checks are present to ensure there is only one nul byte in the /// [`Vec`], its last element. From 8d5a7b685e63fe8e313da974b7e5b70117db1680 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 2 Jan 2026 13:16:21 +0100 Subject: [PATCH 1512/3801] Reduce `impl_signature` query dependencies in method resolution --- .../crates/hir-def/src/item_scope.rs | 16 ++++++++++++---- .../crates/hir-def/src/item_tree.rs | 4 +++- .../crates/hir-def/src/item_tree/lower.rs | 2 +- .../crates/hir-def/src/item_tree/pretty.rs | 2 +- .../crates/hir-def/src/lang_item.rs | 2 +- .../crates/hir-def/src/nameres/collector.rs | 4 +++- .../crates/hir-ty/src/method_resolution.rs | 9 ++------- .../crates/hir-ty/src/tests/incremental.rs | 18 ++++++------------ src/tools/rust-analyzer/crates/hir/src/lib.rs | 11 +++++------ .../ide-completion/src/tests/flyimport.rs | 4 ++-- 10 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index 9e7868b273ef..a3278dd76c86 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -158,7 +158,7 @@ pub struct ItemScope { /// declared. declarations: ThinVec, - impls: ThinVec, + impls: ThinVec<(ImplId, /* trait impl */ bool)>, builtin_derive_impls: ThinVec, extern_blocks: ThinVec, unnamed_consts: ThinVec, @@ -327,7 +327,15 @@ impl ItemScope { } pub fn impls(&self) -> impl ExactSizeIterator + '_ { - self.impls.iter().copied() + self.impls.iter().map(|&(id, _)| id) + } + + pub fn trait_impls(&self) -> impl Iterator + '_ { + self.impls.iter().filter(|&&(_, is_trait_impl)| is_trait_impl).map(|&(id, _)| id) + } + + pub fn inherent_impls(&self) -> impl Iterator + '_ { + self.impls.iter().filter(|&&(_, is_trait_impl)| !is_trait_impl).map(|&(id, _)| id) } pub fn builtin_derive_impls(&self) -> impl ExactSizeIterator + '_ { @@ -472,8 +480,8 @@ impl ItemScope { self.legacy_macros.get(name).map(|it| &**it) } - pub(crate) fn define_impl(&mut self, imp: ImplId) { - self.impls.push(imp); + pub(crate) fn define_impl(&mut self, imp: ImplId, is_trait_impl: bool) { + self.impls.push((imp, is_trait_impl)); } pub(crate) fn define_builtin_derive_impl(&mut self, imp: BuiltinDeriveImplId) { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 2e838fad2e9f..a1707f17beb0 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -614,7 +614,9 @@ pub struct Trait { } #[derive(Debug, Clone, Eq, PartialEq)] -pub struct Impl {} +pub struct Impl { + pub is_trait_impl: bool, +} #[derive(Debug, Clone, PartialEq, Eq)] pub struct TypeAlias { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs index d8519f7393df..3f19e001548e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs @@ -271,7 +271,7 @@ impl<'a> Ctx<'a> { let ast_id = self.source_ast_id_map.ast_id(impl_def); // Note that trait impls don't get implicit `Self` unlike traits, because here they are a // type alias rather than a type parameter, so this is handled by the resolver. - let res = Impl {}; + let res = Impl { is_trait_impl: impl_def.trait_().is_some() }; self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Impl(res)); ast_id } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs index c89299e6d863..4113a778eaaf 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs @@ -258,7 +258,7 @@ impl Printer<'_> { w!(self, "trait {} {{ ... }}", name.display(self.db, self.edition)); } ModItemId::Impl(ast_id) => { - let Impl {} = &self.tree[ast_id]; + let Impl { is_trait_impl: _ } = &self.tree[ast_id]; self.print_ast_id(ast_id.erase()); w!(self, "impl {{ ... }}"); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 41d69c1fd624..d3f4480b207e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -41,7 +41,7 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option { let impl_id = ImplLoc { container: module_id, id: InFile::new(self.file_id(), imp) } .intern(db); - self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id) + self.def_collector.def_map.modules[self.module_id] + .scope + .define_impl(impl_id, self.item_tree[imp].is_trait_impl) } ModItemId::Function(id) => { let it = &self.item_tree[id]; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index 3d7cc4ffbf8a..e4681b464fec 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -609,12 +609,7 @@ impl InherentImpls { map: &mut FxHashMap>, ) { for (_module_id, module_data) in def_map.modules() { - for impl_id in module_data.scope.impls() { - let data = db.impl_signature(impl_id); - if data.target_trait.is_some() { - continue; - } - + for impl_id in module_data.scope.inherent_impls() { let interner = DbInterner::new_no_crate(db); let self_ty = db.impl_self_ty(impl_id); let self_ty = self_ty.instantiate_identity(); @@ -730,7 +725,7 @@ impl TraitImpls { map: &mut FxHashMap, ) { for (_module_id, module_data) in def_map.modules() { - for impl_id in module_data.scope.impls() { + for impl_id in module_data.scope.trait_impls() { let trait_ref = match db.impl_trait(impl_id) { Some(tr) => tr.instantiate_identity(), None => continue, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index 633ab43c4cec..118f433a24e6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -539,12 +539,6 @@ impl SomeStruct { "AttrFlags::query_", "AttrFlags::query_", "AttrFlags::query_", - "impl_trait_with_diagnostics_query", - "impl_signature_shim", - "impl_signature_with_source_map_shim", - "impl_self_ty_with_diagnostics_query", - "struct_signature_shim", - "struct_signature_with_source_map_shim", ] "#]], ); @@ -617,7 +611,6 @@ fn main() { "lang_items", "crate_lang_items", "AttrFlags::query_", - "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", @@ -633,13 +626,14 @@ fn main() { "GenericPredicates::query_with_diagnostics_", "value_ty_query", "InherentImpls::for_crate_", - "impl_signature_shim", - "impl_signature_with_source_map_shim", "callable_item_signature_query", "TraitImpls::for_crate_and_deps_", "TraitImpls::for_crate_", "impl_trait_with_diagnostics_query", + "impl_signature_shim", + "impl_signature_with_source_map_shim", "impl_self_ty_with_diagnostics_query", + "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", ] "#]], @@ -710,7 +704,6 @@ fn main() { "crate_lang_items", "AttrFlags::query_", "AttrFlags::query_", - "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", @@ -722,12 +715,13 @@ fn main() { "struct_signature_with_source_map_shim", "GenericPredicates::query_with_diagnostics_", "InherentImpls::for_crate_", - "impl_signature_with_source_map_shim", - "impl_signature_shim", "callable_item_signature_query", "TraitImpls::for_crate_", + "impl_signature_with_source_map_shim", + "impl_signature_shim", "impl_trait_with_diagnostics_query", "impl_self_ty_with_diagnostics_query", + "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", ] "#]], diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 1ab57c4489cf..527614d56a01 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -803,22 +803,21 @@ impl Module { emit_def_diagnostic(db, acc, diag, edition, loc.container.krate(db)); } - if impl_signature.target_trait.is_none() - && !is_inherent_impl_coherent(db, def_map, impl_id) - { + let trait_impl = impl_signature.target_trait.is_some(); + if !trait_impl && !is_inherent_impl_coherent(db, def_map, impl_id) { acc.push(IncoherentImpl { impl_: ast_id_map.get(loc.id.value), file_id }.into()) } - if !impl_def.check_orphan_rules(db) { + if trait_impl && !impl_def.check_orphan_rules(db) { acc.push(TraitImplOrphan { impl_: ast_id_map.get(loc.id.value), file_id }.into()) } - let trait_ = impl_def.trait_(db); + let trait_ = trait_impl.then(|| impl_def.trait_(db)).flatten(); let mut trait_is_unsafe = trait_.is_some_and(|t| t.is_unsafe(db)); let impl_is_negative = impl_def.is_negative(db); let impl_is_unsafe = impl_def.is_unsafe(db); - let trait_is_unresolved = trait_.is_none() && impl_signature.target_trait.is_some(); + let trait_is_unresolved = trait_.is_none() && trait_impl; if trait_is_unresolved { // Ignore trait safety errors when the trait is unresolved, as otherwise we'll treat it as safe, // which may not be correct. diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index aad881f8ce4f..2912457da1f7 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -781,9 +781,9 @@ fn main() { } "#, expect![[r#" - fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED - ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED + ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED + fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED "#]], ); } From 7e425b898540c51f73f152a353e5a138ae8602eb Mon Sep 17 00:00:00 2001 From: Antoni Spaanderman <56turtle56@gmail.com> Date: Fri, 2 Jan 2026 16:05:42 +0100 Subject: [PATCH 1513/3801] Add specialization for `deque1.prepend(deque2.drain(range))` This is used when moving elements between `VecDeque`s This pattern is also used in examples of `VecDeque::prepend`. (see its docs) --- .../alloc/src/collections/vec_deque/drain.rs | 6 +- .../src/collections/vec_deque/spec_extend.rs | 78 +++++++++++-- library/alloctests/tests/vec_deque.rs | 110 ++++++++++++++++++ 3 files changed, 180 insertions(+), 14 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/drain.rs b/library/alloc/src/collections/vec_deque/drain.rs index eee7be674c95..a43853604a2d 100644 --- a/library/alloc/src/collections/vec_deque/drain.rs +++ b/library/alloc/src/collections/vec_deque/drain.rs @@ -25,10 +25,10 @@ pub struct Drain< // drain_start is stored in deque.len pub(super) drain_len: usize, // index into the logical array, not the physical one (always lies in [0..deque.len)) - idx: usize, + pub(super) idx: usize, // number of elements after the drained range pub(super) tail_len: usize, - remaining: usize, + pub(super) remaining: usize, // Needed to make Drain covariant over T _marker: PhantomData<&'a T>, } @@ -53,7 +53,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { // Only returns pointers to the slices, as that's all we need // to drop them. May only be called if `self.remaining != 0`. - unsafe fn as_slices(&self) -> (*mut [T], *mut [T]) { + pub(super) unsafe fn as_slices(&self) -> (*mut [T], *mut [T]) { unsafe { let deque = self.deque.as_ref(); diff --git a/library/alloc/src/collections/vec_deque/spec_extend.rs b/library/alloc/src/collections/vec_deque/spec_extend.rs index f73ba795cbea..4ef854e8b327 100644 --- a/library/alloc/src/collections/vec_deque/spec_extend.rs +++ b/library/alloc/src/collections/vec_deque/spec_extend.rs @@ -1,7 +1,7 @@ use core::iter::{Copied, Rev, TrustedLen}; use core::slice; -use super::VecDeque; +use super::{Drain, VecDeque}; use crate::alloc::Allocator; #[cfg(not(test))] use crate::vec; @@ -157,7 +157,8 @@ impl SpecExtendFront> for VecDeque { #[track_caller] fn spec_extend_front(&mut self, mut iterator: vec::IntoIter) { let slice = iterator.as_slice(); - // SAFETY: elements in the slice are forgotten after this call + self.reserve(slice.len()); + // SAFETY: `slice.len()` space was just reserved and elements in the slice are forgotten after this call unsafe { prepend_reversed(self, slice) }; iterator.forget_remaining_elements(); } @@ -169,7 +170,8 @@ impl SpecExtendFront>> for VecDeque>) { let mut iterator = iterator.into_inner(); let slice = iterator.as_slice(); - // SAFETY: elements in the slice are forgotten after this call + self.reserve(slice.len()); + // SAFETY: `slice.len()` space was just reserved and elements in the slice are forgotten after this call unsafe { prepend(self, slice) }; iterator.forget_remaining_elements(); } @@ -182,7 +184,8 @@ where #[track_caller] fn spec_extend_front(&mut self, iter: Copied>) { let slice = iter.into_inner().as_slice(); - // SAFETY: T is Copy because Copied> is Iterator + self.reserve(slice.len()); + // SAFETY: `slice.len()` space was just reserved and T is Copy because Copied> is Iterator unsafe { prepend_reversed(self, slice) }; } } @@ -194,17 +197,69 @@ where #[track_caller] fn spec_extend_front(&mut self, iter: Rev>>) { let slice = iter.into_inner().into_inner().as_slice(); - // SAFETY: T is Copy because Rev>> is Iterator + self.reserve(slice.len()); + // SAFETY: `slice.len()` space was just reserved and T is Copy because Rev>> is Iterator unsafe { prepend(self, slice) }; } } +impl<'a, T, A1: Allocator, A2: Allocator> SpecExtendFront> for VecDeque { + #[track_caller] + fn spec_extend_front(&mut self, mut iter: Drain<'a, T, A2>) { + if iter.remaining == 0 { + return; + } + + self.reserve(iter.remaining); + unsafe { + // SAFETY: iter.remaining != 0. + let (left, right) = iter.as_slices(); + // SAFETY: + // - `iter.remaining` space was reserved, `iter.remaining == left.len() + right.len()`. + // - The elements in `left` and `right` are forgotten after these calls. + prepend_reversed(self, &*left); + prepend_reversed(self, &*right); + } + + iter.idx += iter.remaining; + iter.remaining = 0; + } +} + +impl<'a, T, A1: Allocator, A2: Allocator> SpecExtendFront>> + for VecDeque +{ + #[track_caller] + fn spec_extend_front(&mut self, iter: Rev>) { + let mut iter = iter.into_inner(); + + if iter.remaining == 0 { + return; + } + + self.reserve(iter.remaining); + unsafe { + // SAFETY: iter.remaining != 0. + let (left, right) = iter.as_slices(); + // SAFETY: + // - `iter.remaining` space was reserved, `iter.remaining == left.len() + right.len()`. + // - The elements in `left` and `right` are forgotten after these calls. + prepend(self, &*right); + prepend(self, &*left); + } + + iter.idx += iter.remaining; + iter.remaining = 0; + } +} + +/// Prepends elements of `slice` to `deque` using a copy. +/// /// # Safety /// -/// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`. +/// - `deque` must have space for `slice.len()` new elements. +/// - Elements of `slice` will be copied into the deque, make sure to forget the elements if `T` is not `Copy`. unsafe fn prepend(deque: &mut VecDeque, slice: &[T]) { - deque.reserve(slice.len()); - unsafe { deque.head = deque.wrap_sub(deque.head, slice.len()); deque.copy_slice(deque.head, slice); @@ -212,12 +267,13 @@ unsafe fn prepend(deque: &mut VecDeque, slice: &[T]) { } } +/// Prepends elements of `slice` to `deque` in reverse order using a copy. +/// /// # Safety /// -/// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`. +/// - `deque` must have space for `slice.len()` new elements. +/// - Elements of `slice` will be copied into the deque, make sure to forget the elements if `T` is not `Copy`. unsafe fn prepend_reversed(deque: &mut VecDeque, slice: &[T]) { - deque.reserve(slice.len()); - unsafe { deque.head = deque.wrap_sub(deque.head, slice.len()); deque.copy_slice_reversed(deque.head, slice); diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs index 82803c7a0dab..e9f860f8df9b 100644 --- a/library/alloctests/tests/vec_deque.rs +++ b/library/alloctests/tests/vec_deque.rs @@ -2156,6 +2156,116 @@ fn test_extend_front_specialization_copy_slice() { assert_eq!(v.as_slices(), ([5].as_slice(), [4, 3, 2].as_slice())); } +#[test] +fn test_extend_front_specialization_deque_drain() { + // trigger 8 code paths: all combinations of prepend and extend_front, wrap and no wrap (src deque), wrap and no wrap (dst deque) + + /// Get deque containing `[1, 2, 3, 4]`, possibly wrapping in the middle (between the 2 and 3). + fn test_deque(wrap: bool) -> VecDeque { + if wrap { + let mut v = VecDeque::with_capacity(4); + v.extend([3, 4]); + v.prepend([1, 2]); + assert_eq!(v.as_slices(), ([1, 2].as_slice(), [3, 4].as_slice())); + v + } else { + VecDeque::from([1, 2, 3, 4]) + } + } + + // prepend, v2.head == 0 + + let mut v1 = VecDeque::with_capacity(7); + + let mut v2 = test_deque(false); + v1.prepend(v2.drain(..)); + // drain removes all elements but keeps the buffer + assert_eq!(v2, []); + assert!(v2.capacity() >= 4); + + assert_eq!(v1, [1, 2, 3, 4]); + v1.pop_back(); + + let mut v2 = test_deque(false); + // this should wrap around the physical buffer + v1.prepend(v2.drain(..)); + // drain removes all elements but keeps the buffer + assert_eq!(v2, []); + assert!(v2.capacity() >= 4); + + // check it really wrapped + assert_eq!(v1.as_slices(), ([1].as_slice(), [2, 3, 4, 1, 2, 3].as_slice())); + + // extend_front, v2.head == 0 + + let mut v1 = VecDeque::with_capacity(7); + + let mut v2 = test_deque(false); + v1.extend_front(v2.drain(..)); + // drain removes all elements but keeps the buffer + assert_eq!(v2, []); + assert!(v2.capacity() >= 4); + + assert_eq!(v1, [4, 3, 2, 1]); + v1.pop_back(); + + let mut v2 = test_deque(false); + // this should wrap around the physical buffer + v1.extend_front(v2.drain(..)); + // drain removes all elements but keeps the buffer + assert_eq!(v2, []); + assert!(v2.capacity() >= 4); + + // check it really wrapped + assert_eq!(v1.as_slices(), ([4].as_slice(), [3, 2, 1, 4, 3, 2].as_slice())); + + // prepend, v2.head != 0 + + let mut v1 = VecDeque::with_capacity(7); + + let mut v2 = test_deque(true); + v1.prepend(v2.drain(..)); + // drain removes all elements but keeps the buffer + assert_eq!(v2, []); + assert!(v2.capacity() >= 4); + + assert_eq!(v1, [1, 2, 3, 4]); + v1.pop_back(); + + let mut v2 = test_deque(true); + // this should wrap around the physical buffer + v1.prepend(v2.drain(..)); + // drain removes all elements but keeps the buffer + assert_eq!(v2, []); + assert!(v2.capacity() >= 4); + + // check it really wrapped + assert_eq!(v1.as_slices(), ([1].as_slice(), [2, 3, 4, 1, 2, 3].as_slice())); + + // extend_front, v2.head != 0 + + let mut v1 = VecDeque::with_capacity(7); + + let mut v2 = test_deque(true); + v1.extend_front(v2.drain(..)); + // drain removes all elements but keeps the buffer + assert_eq!(v2, []); + assert!(v2.capacity() >= 4); + + assert_eq!(v1, [4, 3, 2, 1]); + v1.pop_back(); + + let mut v2 = test_deque(true); + // this should wrap around the physical buffer + v1.extend_front(v2.drain(..)); + // drain removes all elements but keeps the buffer + assert_eq!(v2, []); + assert!(v2.capacity() >= 4); + + // check it really wrapped + assert_eq!(v1.as_slices(), ([4].as_slice(), [3, 2, 1, 4, 3, 2].as_slice())); +} + #[test] fn test_splice() { let mut v = VecDeque::from(vec![1, 2, 3, 4, 5]); From 9a170fedd792b3373ddf7b512cff0b1463ee30e0 Mon Sep 17 00:00:00 2001 From: Antoni Spaanderman <56turtle56@gmail.com> Date: Fri, 2 Jan 2026 16:15:40 +0100 Subject: [PATCH 1514/3801] make specialization of Vec::extend and VecDeque::extend_front work for vec::IntoIter with any Allocator, not just Global --- .../alloc/src/collections/vec_deque/spec_extend.rs | 14 ++++++++------ library/alloc/src/vec/spec_extend.rs | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/spec_extend.rs b/library/alloc/src/collections/vec_deque/spec_extend.rs index f73ba795cbea..b65e229361f2 100644 --- a/library/alloc/src/collections/vec_deque/spec_extend.rs +++ b/library/alloc/src/collections/vec_deque/spec_extend.rs @@ -77,8 +77,8 @@ where } #[cfg(not(test))] -impl SpecExtend> for VecDeque { - fn spec_extend(&mut self, mut iterator: vec::IntoIter) { +impl SpecExtend> for VecDeque { + fn spec_extend(&mut self, mut iterator: vec::IntoIter) { let slice = iterator.as_slice(); self.reserve(slice.len()); @@ -153,9 +153,9 @@ where } #[cfg(not(test))] -impl SpecExtendFront> for VecDeque { +impl SpecExtendFront> for VecDeque { #[track_caller] - fn spec_extend_front(&mut self, mut iterator: vec::IntoIter) { + fn spec_extend_front(&mut self, mut iterator: vec::IntoIter) { let slice = iterator.as_slice(); // SAFETY: elements in the slice are forgotten after this call unsafe { prepend_reversed(self, slice) }; @@ -164,9 +164,11 @@ impl SpecExtendFront> for VecDeque { } #[cfg(not(test))] -impl SpecExtendFront>> for VecDeque { +impl SpecExtendFront>> + for VecDeque +{ #[track_caller] - fn spec_extend_front(&mut self, iterator: Rev>) { + fn spec_extend_front(&mut self, iterator: Rev>) { let mut iterator = iterator.into_inner(); let slice = iterator.as_slice(); // SAFETY: elements in the slice are forgotten after this call diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index f5bcd3ec9d82..7c908841c90e 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -28,8 +28,8 @@ where } } -impl SpecExtend> for Vec { - fn spec_extend(&mut self, mut iterator: IntoIter) { +impl SpecExtend> for Vec { + fn spec_extend(&mut self, mut iterator: IntoIter) { unsafe { self.append_elements(iterator.as_slice() as _); } From c7bb49458f284421012f7e4c575d2747b19075d9 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Fri, 2 Jan 2026 23:13:52 +0900 Subject: [PATCH 1515/3801] Add tracking issue for sized_hierarchy --- compiler/rustc_feature/src/unstable.rs | 4 ++-- library/core/src/marker.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index ca2ce2f18812..94e861787fc6 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -247,8 +247,6 @@ declare_features! ( (internal, profiler_runtime, "1.18.0", None), /// Allows using `rustc_*` attributes (RFC 572). (internal, rustc_attrs, "1.0.0", None), - /// Introduces a hierarchy of `Sized` traits (RFC 3729). - (unstable, sized_hierarchy, "1.89.0", None), /// Allows using the `#[stable]` and `#[unstable]` attributes. (internal, staged_api, "1.0.0", None), /// Added for testing unstable lints; perma-unstable. @@ -305,6 +303,8 @@ declare_features! ( (internal, rustdoc_internals, "1.58.0", Some(90418)), /// Allows using the `rustdoc::missing_doc_code_examples` lint (unstable, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730)), + /// Introduces a hierarchy of `Sized` traits (RFC 3729). + (unstable, sized_hierarchy, "1.89.0", Some(144404)), /// Allows using `#[structural_match]` which indicates that a type is structurally matchable. /// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library /// feature with the same name exists. diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 68f22767d6cf..5ecc2a63ea83 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -163,7 +163,7 @@ pub trait Sized: MetaSized { } /// Types with a size that can be determined from pointer metadata. -#[unstable(feature = "sized_hierarchy", issue = "none")] +#[unstable(feature = "sized_hierarchy", issue = "144404")] #[lang = "meta_sized"] #[diagnostic::on_unimplemented( message = "the size for values of type `{Self}` cannot be known", @@ -181,7 +181,7 @@ pub trait MetaSized: PointeeSized { } /// Types that may or may not have a size. -#[unstable(feature = "sized_hierarchy", issue = "none")] +#[unstable(feature = "sized_hierarchy", issue = "144404")] #[lang = "pointee_sized"] #[diagnostic::on_unimplemented( message = "values of type `{Self}` may or may not have a size", From da1ffbe181973aa47e384949a4498dd7fbd30721 Mon Sep 17 00:00:00 2001 From: alhubanov Date: Fri, 2 Jan 2026 18:02:52 +0200 Subject: [PATCH 1516/3801] fix: restrict match_bool to 2 arms --- clippy_lints/src/matches/match_bool.rs | 95 +++++++++++++------------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/clippy_lints/src/matches/match_bool.rs b/clippy_lints/src/matches/match_bool.rs index a2c8741f4f74..dc3457aa7a46 100644 --- a/clippy_lints/src/matches/match_bool.rs +++ b/clippy_lints/src/matches/match_bool.rs @@ -16,6 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>] && arms .iter() .all(|arm| arm.pat.walk_short(|p| !matches!(p.kind, PatKind::Binding(..)))) + && arms.len() == 2 { span_lint_and_then( cx, @@ -23,59 +24,57 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>] expr.span, "`match` on a boolean expression", move |diag| { - if arms.len() == 2 { - let mut app = Applicability::MachineApplicable; - let test_sugg = if let PatKind::Expr(arm_bool) = arms[0].pat.kind { - let test = Sugg::hir_with_applicability(cx, scrutinee, "_", &mut app); - if let PatExprKind::Lit { lit, .. } = arm_bool.kind { - match &lit.node { - LitKind::Bool(true) => Some(test), - LitKind::Bool(false) => Some(!test), - _ => None, - } - .map(|test| { - if let Some(guard) = &arms[0] - .guard - .map(|g| Sugg::hir_with_applicability(cx, g, "_", &mut app)) - { - test.and(guard) - } else { - test - } - }) - } else { - None + let mut app = Applicability::MachineApplicable; + let test_sugg = if let PatKind::Expr(arm_bool) = arms[0].pat.kind { + let test = Sugg::hir_with_applicability(cx, scrutinee, "_", &mut app); + if let PatExprKind::Lit { lit, .. } = arm_bool.kind { + match &lit.node { + LitKind::Bool(true) => Some(test), + LitKind::Bool(false) => Some(!test), + _ => None, } + .map(|test| { + if let Some(guard) = &arms[0] + .guard + .map(|g| Sugg::hir_with_applicability(cx, g, "_", &mut app)) + { + test.and(guard) + } else { + test + } + }) } else { None + } + } else { + None + }; + + if let Some(test_sugg) = test_sugg { + let ctxt = expr.span.ctxt(); + let (true_expr, false_expr) = (arms[0].body, arms[1].body); + let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) { + (false, false) => Some(format!( + "if {} {} else {}", + test_sugg, + expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app), + expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) + )), + (false, true) => Some(format!( + "if {} {}", + test_sugg, + expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app) + )), + (true, false) => Some(format!( + "if {} {}", + !test_sugg, + expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) + )), + (true, true) => None, }; - if let Some(test_sugg) = test_sugg { - let ctxt = expr.span.ctxt(); - let (true_expr, false_expr) = (arms[0].body, arms[1].body); - let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) { - (false, false) => Some(format!( - "if {} {} else {}", - test_sugg, - expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app), - expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) - )), - (false, true) => Some(format!( - "if {} {}", - test_sugg, - expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app) - )), - (true, false) => Some(format!( - "if {} {}", - !test_sugg, - expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) - )), - (true, true) => None, - }; - - if let Some(sugg) = sugg { - diag.span_suggestion(expr.span, "consider using an `if`/`else` expression", sugg, app); - } + if let Some(sugg) = sugg { + diag.span_suggestion(expr.span, "consider using an `if`/`else` expression", sugg, app); } } }, From 4d2ce7d36b7c96f1778621a6b0865bcaa8872c54 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 2 Jan 2026 18:09:01 +0100 Subject: [PATCH 1517/3801] use a single generic codepath for all return types --- src/tools/miri/src/shims/native_lib/ffi.rs | 32 ---- src/tools/miri/src/shims/native_lib/mod.rs | 157 +++++++----------- .../miri/src/shims/native_lib/trace/child.rs | 12 +- .../miri/src/shims/native_lib/trace/stub.rs | 10 +- .../tests/native-lib/aggregate_arguments.c | 8 + .../tests/native-lib/fail/invalid_retval.rs | 14 ++ .../native-lib/fail/invalid_retval.stderr | 13 ++ .../native-lib/pass/aggregate_arguments.rs | 18 ++ .../miri/tests/native-lib/scalar_arguments.c | 4 + 9 files changed, 131 insertions(+), 137 deletions(-) delete mode 100644 src/tools/miri/src/shims/native_lib/ffi.rs create mode 100644 src/tools/miri/tests/native-lib/fail/invalid_retval.rs create mode 100644 src/tools/miri/tests/native-lib/fail/invalid_retval.stderr diff --git a/src/tools/miri/src/shims/native_lib/ffi.rs b/src/tools/miri/src/shims/native_lib/ffi.rs deleted file mode 100644 index 196f43c6f6a6..000000000000 --- a/src/tools/miri/src/shims/native_lib/ffi.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Support code for dealing with libffi. - -use libffi::low::CodePtr; -use libffi::middle::{Arg as ArgPtr, Cif, Type as FfiType}; - -/// Perform the actual FFI call. -/// -/// # Safety -/// -/// The safety invariants of the foreign function being called must be upheld (if any). -pub unsafe fn call(fun: CodePtr, args: &mut [OwnedArg]) -> R { - let cif = Cif::new(args.iter_mut().map(|arg| arg.ty.take().unwrap()), R::reify().into_middle()); - let arg_ptrs: Vec<_> = args.iter().map(|arg| ArgPtr::new(&*arg.bytes)).collect(); - // SAFETY: Caller upholds that the function is safe to call. - unsafe { cif.call(fun, &arg_ptrs) } -} - -/// An argument for an FFI call. -#[derive(Debug, Clone)] -pub struct OwnedArg { - /// The type descriptor for this argument. - ty: Option, - /// Corresponding bytes for the value. - bytes: Box<[u8]>, -} - -impl OwnedArg { - /// Instantiates an argument from a type descriptor and bytes. - pub fn new(ty: FfiType, bytes: Box<[u8]>) -> Self { - Self { ty: Some(ty), bytes } - } -} diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index c25c1841dd70..8a761855c432 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -11,14 +11,12 @@ use libffi::low::CodePtr; use libffi::middle::Type as FfiType; use rustc_abi::{HasDataLayout, Size}; use rustc_data_structures::either; -use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout}; -use rustc_middle::ty::{self, FloatTy, IntTy, Ty, UintTy}; +use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::{self, Ty}; use rustc_span::Symbol; use serde::{Deserialize, Serialize}; -use self::helpers::ToSoft; - -mod ffi; +use crate::*; #[cfg_attr( not(all( @@ -30,8 +28,21 @@ mod ffi; )] pub mod trace; -use self::ffi::OwnedArg; -use crate::*; +/// An argument for an FFI call. +#[derive(Debug, Clone)] +pub struct OwnedArg { + /// The type descriptor for this argument. + ty: Option, + /// Corresponding bytes for the value. + bytes: Box<[u8]>, +} + +impl OwnedArg { + /// Instantiates an argument from a type descriptor and bytes. + pub fn new(ty: FfiType, bytes: Box<[u8]>) -> Self { + Self { ty: Some(ty), bytes } + } +} /// The final results of an FFI trace, containing every relevant event detected /// by the tracer. @@ -80,14 +91,14 @@ impl AccessRange { impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { - /// Call native host function and return the output as an immediate. - fn call_native_with_args( + /// Call native host function and return the output and the memory accesses + /// that occurred during the call. + fn call_native_raw( &mut self, - link_name: Symbol, - dest: &MPlaceTy<'tcx>, fun: CodePtr, - libffi_args: &mut [OwnedArg], - ) -> InterpResult<'tcx, (crate::ImmTy<'tcx>, Option)> { + args: &mut [OwnedArg], + ret: (FfiType, Size), + ) -> InterpResult<'tcx, (Box<[u8]>, Option)> { let this = self.eval_context_mut(); #[cfg(target_os = "linux")] let alloc = this.machine.allocator.as_ref().unwrap().clone(); @@ -99,81 +110,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.machine.native_lib_ecx_interchange.set(ptr::from_mut(this).expose_provenance()); let res = trace::Supervisor::do_ffi(&alloc, || { - // Call the function (`ptr`) with arguments `libffi_args`, and obtain the return value - // as the specified primitive integer type - let scalar = match dest.layout.ty.kind() { - // ints - ty::Int(IntTy::I8) => { - // Unsafe because of the call to native code. - // Because this is calling a C function it is not necessarily sound, - // but there is no way around this and we've checked as much as we can. - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_i8(x) - } - ty::Int(IntTy::I16) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_i16(x) - } - ty::Int(IntTy::I32) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_i32(x) - } - ty::Int(IntTy::I64) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_i64(x) - } - ty::Int(IntTy::Isize) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_target_isize(x.try_into().unwrap(), this) - } - // uints - ty::Uint(UintTy::U8) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_u8(x) - } - ty::Uint(UintTy::U16) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_u16(x) - } - ty::Uint(UintTy::U32) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_u32(x) - } - ty::Uint(UintTy::U64) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_u64(x) - } - ty::Uint(UintTy::Usize) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_target_usize(x.try_into().unwrap(), this) - } - ty::Float(FloatTy::F32) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_f32(x.to_soft()) - } - ty::Float(FloatTy::F64) => { - let x = unsafe { ffi::call::(fun, libffi_args) }; - Scalar::from_f64(x.to_soft()) - } - // Functions with no declared return type (i.e., the default return) - // have the output_type `Tuple([])`. - ty::Tuple(t_list) if (*t_list).deref().is_empty() => { - unsafe { ffi::call::<()>(fun, libffi_args) }; - return interp_ok(ImmTy::uninit(dest.layout)); - } - ty::RawPtr(ty, ..) if ty.is_sized(*this.tcx, this.typing_env()) => { - let x = unsafe { ffi::call::<*const ()>(fun, libffi_args) }; - let ptr = StrictPointer::new(Provenance::Wildcard, Size::from_bytes(x.addr())); - Scalar::from_pointer(ptr, this) - } - _ => - return Err(err_unsup_format!( - "unsupported return type for native call: {:?}", - link_name - )) - .into(), - }; - interp_ok(ImmTy::from_scalar(scalar, dest.layout)) + use libffi::middle::{Arg, Cif, Ret}; + + let cif = Cif::new(args.iter_mut().map(|arg| arg.ty.take().unwrap()), ret.0); + let arg_ptrs: Vec<_> = args.iter().map(|arg| Arg::new(&*arg.bytes)).collect(); + let mut ret = vec![0u8; ret.1.bytes_usize()]; + + unsafe { cif.call_return_into(fun, &arg_ptrs, Ret::new::<[u8]>(&mut *ret)) }; + ret.into() }); this.machine.native_lib_ecx_interchange.set(0); @@ -392,6 +336,30 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(OwnedArg::new(ty, bytes)) } + fn ffi_ret_to_mem(&mut self, v: Box<[u8]>, dest: &MPlaceTy<'tcx>) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + let len = v.len(); + this.write_bytes_ptr(dest.ptr(), v)?; + if len == 0 { + return interp_ok(()); + } + // We have no idea which provenance these bytes have, so we reset it to wildcard. + let tcx = this.tcx; + let (alloc_id, offset, _) = this.ptr_try_get_alloc_id(dest.ptr(), 0).unwrap(); + let alloc = this.get_alloc_raw_mut(alloc_id)?.0; + alloc.process_native_write(&tcx, Some(alloc_range(offset, dest.layout.size))); + // Run the validation that would usually be part of `return`, also to reset + // any provenance and padding that would not survive the return. + if MiriMachine::enforce_validity(this, dest.layout) { + this.validate_operand( + &dest.clone().into(), + MiriMachine::enforce_validity_recursively(this, dest.layout), + /*reset_provenance_and_padding*/ true, + )?; + } + interp_ok(()) + } + /// Parses an ADT to construct the matching libffi type. fn adt_to_ffitype( &self, @@ -399,6 +367,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { adt_def: ty::AdtDef<'tcx>, args: &'tcx ty::List>, ) -> InterpResult<'tcx, FfiType> { + let this = self.eval_context_ref(); // TODO: unions, etc. if !adt_def.is_struct() { throw_unsup_format!("passing an enum or union over FFI: {orig_ty}"); @@ -408,7 +377,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_unsup_format!("passing a non-#[repr(C)] {} over FFI: {orig_ty}", adt_def.descr()) } - let this = self.eval_context_ref(); let mut fields = vec![]; for field in &adt_def.non_enum_variant().fields { let layout = this.layout_of(field.ty(*this.tcx, args))?; @@ -533,6 +501,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// a native form (through `libffi` call). /// Then, convert the return value from the native form into something that /// can be stored in Miri's internal memory. + /// + /// Returns `true` if a call has been made, `false` if no functions of this name was found. fn call_native_fn( &mut self, link_name: Symbol, @@ -554,6 +524,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { for arg in args.iter() { libffi_args.push(this.op_to_ffi_arg(arg, tracing)?); } + let ret_ty = this.ty_to_ffitype(dest.layout)?; // Prepare all exposed memory (both previously exposed, and just newly exposed since a // pointer was passed as argument). Uninitialised memory is left as-is, but any data @@ -596,15 +567,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(()) })?; - // Call the function and store output, depending on return type in the function signature. + // Call the function and store its output. let (ret, maybe_memevents) = - this.call_native_with_args(link_name, dest, code_ptr, &mut libffi_args)?; - + this.call_native_raw(code_ptr, &mut libffi_args, (ret_ty, dest.layout.size))?; if tracing { this.tracing_apply_accesses(maybe_memevents.unwrap())?; } - - this.write_immediate(*ret, dest)?; + this.ffi_ret_to_mem(ret, dest)?; interp_ok(true) } } diff --git a/src/tools/miri/src/shims/native_lib/trace/child.rs b/src/tools/miri/src/shims/native_lib/trace/child.rs index 795ad4a32076..021ec2e9aeb3 100644 --- a/src/tools/miri/src/shims/native_lib/trace/child.rs +++ b/src/tools/miri/src/shims/native_lib/trace/child.rs @@ -5,7 +5,7 @@ use std::rc::Rc; use ipc_channel::ipc; use nix::sys::{mman, ptrace, signal}; use nix::unistd; -use rustc_const_eval::interpret::InterpResult; +use rustc_const_eval::interpret::{InterpResult, interp_ok}; use super::CALLBACK_STACK_SIZE; use super::messages::{Confirmation, StartFfiInfo, TraceRequest}; @@ -58,16 +58,16 @@ impl Supervisor { /// Performs an arbitrary FFI call, enabling tracing from the supervisor. /// As this locks the supervisor via a mutex, no other threads may enter FFI /// until this function returns. - pub fn do_ffi<'tcx>( + pub fn do_ffi<'tcx, T>( alloc: &Rc>, - f: impl FnOnce() -> InterpResult<'tcx, crate::ImmTy<'tcx>>, - ) -> InterpResult<'tcx, (crate::ImmTy<'tcx>, Option)> { + f: impl FnOnce() -> T, + ) -> InterpResult<'tcx, (T, Option)> { let mut sv_guard = SUPERVISOR.lock().unwrap(); // If the supervisor is not initialised for whatever reason, fast-return. // As a side-effect, even on platforms where ptracing // is not implemented, we enforce that only one FFI call // happens at a time. - let Some(sv) = sv_guard.as_mut() else { return f().map(|v| (v, None)) }; + let Some(sv) = sv_guard.as_mut() else { return interp_ok((f(), None)) }; // Get pointers to all the pages the supervisor must allow accesses in // and prepare the callback stack. @@ -147,7 +147,7 @@ impl Supervisor { }) .ok(); - res.map(|v| (v, events)) + interp_ok((res, events)) } } diff --git a/src/tools/miri/src/shims/native_lib/trace/stub.rs b/src/tools/miri/src/shims/native_lib/trace/stub.rs index 22787a6f6fa7..a3f6c616301c 100644 --- a/src/tools/miri/src/shims/native_lib/trace/stub.rs +++ b/src/tools/miri/src/shims/native_lib/trace/stub.rs @@ -1,4 +1,4 @@ -use rustc_const_eval::interpret::InterpResult; +use rustc_const_eval::interpret::{InterpResult, interp_ok}; static SUPERVISOR: std::sync::Mutex<()> = std::sync::Mutex::new(()); @@ -13,13 +13,13 @@ impl Supervisor { false } - pub fn do_ffi<'tcx, T>( + pub fn do_ffi<'tcx, T, U>( _: T, - f: impl FnOnce() -> InterpResult<'tcx, crate::ImmTy<'tcx>>, - ) -> InterpResult<'tcx, (crate::ImmTy<'tcx>, Option)> { + f: impl FnOnce() -> U, + ) -> InterpResult<'tcx, (U, Option)> { // We acquire the lock to ensure that no two FFI calls run concurrently. let _g = SUPERVISOR.lock().unwrap(); - f().map(|v| (v, None)) + interp_ok((f(), None)) } } diff --git a/src/tools/miri/tests/native-lib/aggregate_arguments.c b/src/tools/miri/tests/native-lib/aggregate_arguments.c index 8ad687f2aec9..e315642c13a9 100644 --- a/src/tools/miri/tests/native-lib/aggregate_arguments.c +++ b/src/tools/miri/tests/native-lib/aggregate_arguments.c @@ -24,6 +24,14 @@ EXPORT int64_t pass_struct(const PassMe pass_me) { return pass_me.value + pass_me.other_value; } +/* Test: test_return_struct */ +EXPORT PassMe return_struct(int32_t value, int64_t other_value) { + struct PassMe ret; + ret.value = value; + ret.other_value = other_value; + return ret; +} + /* Test: test_pass_struct_complex */ typedef struct Part1 { diff --git a/src/tools/miri/tests/native-lib/fail/invalid_retval.rs b/src/tools/miri/tests/native-lib/fail/invalid_retval.rs new file mode 100644 index 000000000000..4967866b7e7f --- /dev/null +++ b/src/tools/miri/tests/native-lib/fail/invalid_retval.rs @@ -0,0 +1,14 @@ +// Only works on Unix targets +//@ignore-target: windows wasm +//@only-on-host +//@normalize-stderr-test: "OS `.*`" -> "$$OS" + +extern "C" { + fn u8_id(x: u8) -> bool; +} + +fn main() { + unsafe { + u8_id(2); //~ ERROR: invalid value: encountered 0x02, but expected a boolean + } +} diff --git a/src/tools/miri/tests/native-lib/fail/invalid_retval.stderr b/src/tools/miri/tests/native-lib/fail/invalid_retval.stderr new file mode 100644 index 000000000000..9db29822d4f5 --- /dev/null +++ b/src/tools/miri/tests/native-lib/fail/invalid_retval.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: constructing invalid value: encountered 0x02, but expected a boolean + --> tests/native-lib/fail/invalid_retval.rs:LL:CC + | +LL | u8_id(2); + | ^^^^^^^^ 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 + +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/native-lib/pass/aggregate_arguments.rs b/src/tools/miri/tests/native-lib/pass/aggregate_arguments.rs index 55acb240612f..730e9d89441a 100644 --- a/src/tools/miri/tests/native-lib/pass/aggregate_arguments.rs +++ b/src/tools/miri/tests/native-lib/pass/aggregate_arguments.rs @@ -1,6 +1,7 @@ fn main() { test_pass_struct(); test_pass_struct_complex(); + test_return_struct(); } /// Test passing a basic struct as an argument. @@ -20,6 +21,23 @@ fn test_pass_struct() { assert_eq!(unsafe { pass_struct(pass_me) }, 42 + 1337); } +fn test_return_struct() { + // Exactly two fields, so that we hit the ScalarPair case. + #[repr(C)] + struct PassMe { + value: i32, + other_value: i64, + } + + extern "C" { + fn return_struct(v: i32, ov: i64) -> PassMe; + } + + let pass_me = unsafe { return_struct(1, 2) }; + assert_eq!(pass_me.value, 1); + assert_eq!(pass_me.other_value, 2); +} + /// Test passing a more complex struct as an argument. fn test_pass_struct_complex() { #[repr(C)] diff --git a/src/tools/miri/tests/native-lib/scalar_arguments.c b/src/tools/miri/tests/native-lib/scalar_arguments.c index 10b6244bdeb4..720f1982178c 100644 --- a/src/tools/miri/tests/native-lib/scalar_arguments.c +++ b/src/tools/miri/tests/native-lib/scalar_arguments.c @@ -34,6 +34,10 @@ EXPORT float add_float(float x) { return x + 1.5f; } +EXPORT uint8_t u8_id(uint8_t x) { + return x; +} + // To test that functions not marked with EXPORT cannot be called by Miri. int32_t not_exported(void) { return 0; From ae09be596846d60d14f50399da91ffcb70bfd12e Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 20:56:06 +0100 Subject: [PATCH 1518/3801] std: unify `sys::pal::common` and `sys_common` into `sys::helpers` --- library/std/src/lib.rs | 2 - library/std/src/sys/helpers/mod.rs | 38 ++++++++++++++++ .../{pal/common => helpers}/small_c_string.rs | 0 .../src/sys/{pal/common => helpers}/tests.rs | 8 +++- .../src/{sys_common => sys/helpers}/wstr.rs | 1 - library/std/src/sys/mod.rs | 1 + library/std/src/sys/pal/common/mod.rs | 16 ------- library/std/src/sys/pal/mod.rs | 2 - library/std/src/sys_common/mod.rs | 44 ------------------- library/std/src/sys_common/tests.rs | 6 --- 10 files changed, 46 insertions(+), 72 deletions(-) create mode 100644 library/std/src/sys/helpers/mod.rs rename library/std/src/sys/{pal/common => helpers}/small_c_string.rs (100%) rename library/std/src/sys/{pal/common => helpers}/tests.rs (89%) rename library/std/src/{sys_common => sys/helpers}/wstr.rs (98%) delete mode 100644 library/std/src/sys/pal/common/mod.rs delete mode 100644 library/std/src/sys_common/mod.rs delete mode 100644 library/std/src/sys_common/tests.rs diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 0dab29712f4f..f5b9f69a5f9f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -681,9 +681,7 @@ pub mod arch { #[stable(feature = "simd_x86", since = "1.27.0")] pub use std_detect::is_x86_feature_detected; -// Platform-abstraction modules mod sys; -mod sys_common; pub mod alloc; diff --git a/library/std/src/sys/helpers/mod.rs b/library/std/src/sys/helpers/mod.rs new file mode 100644 index 000000000000..c29d9d2ce2d1 --- /dev/null +++ b/library/std/src/sys/helpers/mod.rs @@ -0,0 +1,38 @@ +//! Small helper functions used inside `sys`. +//! +//! If any of these have uses outside of `sys`, please move them to a different +//! module. + +#[cfg_attr(not(target_os = "linux"), allow(unused))] // Not used on all platforms. +mod small_c_string; +#[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. +mod wstr; + +#[cfg(test)] +mod tests; + +#[cfg_attr(not(target_os = "linux"), allow(unused))] // Not used on all platforms. +pub use small_c_string::{run_path_with_cstr, run_with_cstr}; +#[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. +pub use wstr::WStrUnits; + +// Computes (value*numerator)/denom without overflow, as long as both (numerator*denom) and the +// overall result fit into i64 (which is the case for our time conversions). +#[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. +pub fn mul_div_u64(value: u64, numerator: u64, denom: u64) -> u64 { + let q = value / denom; + let r = value % denom; + // Decompose value as (value/denom*denom + value%denom), + // substitute into (value*numerator)/denom and simplify. + // r < denom, so (denom*numerator) is the upper bound of (r*numerator) + q * numerator + r * numerator / denom +} + +#[cfg_attr(not(target_os = "linux"), allow(unused))] // Not used on all platforms. +pub fn ignore_notfound(result: crate::io::Result) -> crate::io::Result<()> { + match result { + Err(err) if err.kind() == crate::io::ErrorKind::NotFound => Ok(()), + Ok(_) => Ok(()), + Err(err) => Err(err), + } +} diff --git a/library/std/src/sys/pal/common/small_c_string.rs b/library/std/src/sys/helpers/small_c_string.rs similarity index 100% rename from library/std/src/sys/pal/common/small_c_string.rs rename to library/std/src/sys/helpers/small_c_string.rs diff --git a/library/std/src/sys/pal/common/tests.rs b/library/std/src/sys/helpers/tests.rs similarity index 89% rename from library/std/src/sys/pal/common/tests.rs rename to library/std/src/sys/helpers/tests.rs index b7698907070c..b67fdb9408d6 100644 --- a/library/std/src/sys/pal/common/tests.rs +++ b/library/std/src/sys/helpers/tests.rs @@ -1,9 +1,10 @@ use core::iter::repeat; +use super::mul_div_u64; +use super::small_c_string::run_path_with_cstr; use crate::ffi::CString; use crate::hint::black_box; use crate::path::Path; -use crate::sys::common::small_c_string::run_path_with_cstr; #[test] fn stack_allocation_works() { @@ -65,3 +66,8 @@ fn bench_heap_path_alloc(b: &mut test::Bencher) { .unwrap(); }); } + +#[test] +fn test_muldiv() { + assert_eq!(mul_div_u64(1_000_000_000_001, 1_000_000_000, 1_000_000), 1_000_000_000_001_000); +} diff --git a/library/std/src/sys_common/wstr.rs b/library/std/src/sys/helpers/wstr.rs similarity index 98% rename from library/std/src/sys_common/wstr.rs rename to library/std/src/sys/helpers/wstr.rs index f9a171fb7d8f..9c4b8e09e463 100644 --- a/library/std/src/sys_common/wstr.rs +++ b/library/std/src/sys/helpers/wstr.rs @@ -1,5 +1,4 @@ //! This module contains constructs to work with 16-bit characters (UCS-2 or UTF-16) -#![allow(dead_code)] use crate::marker::PhantomData; use crate::num::NonZero; diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 0c72f6a57fe8..bfdbc6ee5d1e 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -11,6 +11,7 @@ mod configure_builtins; mod pal; mod alloc; +mod helpers; mod personality; pub mod args; diff --git a/library/std/src/sys/pal/common/mod.rs b/library/std/src/sys/pal/common/mod.rs deleted file mode 100644 index 9af4dee401cf..000000000000 --- a/library/std/src/sys/pal/common/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -// This module contains code that is shared between all platforms, mostly utility or fallback code. -// This explicitly does not include code that is shared between only a few platforms, -// such as when reusing an implementation from `unix` or `unsupported`. -// In those cases the desired code should be included directly using the #[path] attribute, -// not moved to this module. -// -// Currently `sys_common` contains a lot of code that should live in this module, -// ideally `sys_common` would only contain platform-independent abstractions on top of `sys`. -// Progress on this is tracked in #84187. - -#![allow(dead_code)] - -pub mod small_c_string; - -#[cfg(test)] -mod tests; diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index 93ad4536e18f..c039c2894877 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -22,8 +22,6 @@ #![allow(missing_debug_implementations)] -pub mod common; - cfg_select! { unix => { mod unix; diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs deleted file mode 100644 index 015042440b5a..000000000000 --- a/library/std/src/sys_common/mod.rs +++ /dev/null @@ -1,44 +0,0 @@ -//! Platform-independent platform abstraction -//! -//! This is the platform-independent portion of the standard library's -//! platform abstraction layer, whereas `std::sys` is the -//! platform-specific portion. -//! -//! The relationship between `std::sys_common`, `std::sys` and the -//! rest of `std` is complex, with dependencies going in all -//! directions: `std` depending on `sys_common`, `sys_common` -//! depending on `sys`, and `sys` depending on `sys_common` and `std`. -//! This is because `sys_common` not only contains platform-independent code, -//! but also code that is shared between the different platforms in `sys`. -//! Ideally all that shared code should be moved to `sys::common`, -//! and the dependencies between `std`, `sys_common` and `sys` all would form a DAG. -//! Progress on this is tracked in #84187. - -#![allow(missing_docs)] - -#[cfg(test)] -mod tests; - -pub mod wstr; - -// common error constructors - -// Computes (value*numerator)/denom without overflow, as long as both (numerator*denom) and the -// overall result fit into i64 (which is the case for our time conversions). -#[allow(dead_code)] // not used on all platforms -pub fn mul_div_u64(value: u64, numerator: u64, denom: u64) -> u64 { - let q = value / denom; - let r = value % denom; - // Decompose value as (value/denom*denom + value%denom), - // substitute into (value*numerator)/denom and simplify. - // r < denom, so (denom*numerator) is the upper bound of (r*numerator) - q * numerator + r * numerator / denom -} - -pub fn ignore_notfound(result: crate::io::Result) -> crate::io::Result<()> { - match result { - Err(err) if err.kind() == crate::io::ErrorKind::NotFound => Ok(()), - Ok(_) => Ok(()), - Err(err) => Err(err), - } -} diff --git a/library/std/src/sys_common/tests.rs b/library/std/src/sys_common/tests.rs deleted file mode 100644 index 1b6446db52d4..000000000000 --- a/library/std/src/sys_common/tests.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::mul_div_u64; - -#[test] -fn test_muldiv() { - assert_eq!(mul_div_u64(1_000_000_000_001, 1_000_000_000, 1_000_000), 1_000_000_000_001_000); -} From f4fe287d877d372c948730ad6720e74d818a2292 Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 21:09:11 +0100 Subject: [PATCH 1519/3801] std: update imports of `sys::helpers` --- library/std/src/sys/args/windows.rs | 2 +- library/std/src/sys/env/solid.rs | 2 +- library/std/src/sys/env/uefi.rs | 2 +- library/std/src/sys/env/unix.rs | 2 +- library/std/src/sys/env/wasi.rs | 2 +- library/std/src/sys/fs/common.rs | 2 +- library/std/src/sys/fs/hermit.rs | 2 +- library/std/src/sys/fs/mod.rs | 2 +- library/std/src/sys/fs/solid.rs | 2 +- library/std/src/sys/fs/uefi.rs | 4 ++-- library/std/src/sys/fs/unix.rs | 5 ++--- library/std/src/sys/fs/vexos.rs | 2 +- library/std/src/sys/net/connection/socket/mod.rs | 2 +- library/std/src/sys/net/connection/uefi/tcp.rs | 2 +- library/std/src/sys/pal/uefi/helpers.rs | 2 +- library/std/src/sys/pal/uefi/time.rs | 2 +- library/std/src/sys/pal/unix/os.rs | 2 +- library/std/src/sys/pal/wasi/os.rs | 2 +- library/std/src/sys/pal/windows/time.rs | 2 +- library/std/src/sys/path/cygwin.rs | 2 +- library/std/src/sys/path/uefi.rs | 3 ++- .../std/src/sys/platform_version/darwin/core_foundation.rs | 2 +- library/std/src/sys/process/uefi.rs | 2 +- 23 files changed, 26 insertions(+), 26 deletions(-) diff --git a/library/std/src/sys/args/windows.rs b/library/std/src/sys/args/windows.rs index b4de759e1a4c..c1988657ff1b 100644 --- a/library/std/src/sys/args/windows.rs +++ b/library/std/src/sys/args/windows.rs @@ -11,11 +11,11 @@ use crate::ffi::{OsStr, OsString}; use crate::num::NonZero; use crate::os::windows::prelude::*; use crate::path::{Path, PathBuf}; +use crate::sys::helpers::WStrUnits; use crate::sys::pal::os::current_exe; use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf}; use crate::sys::path::get_long_path; use crate::sys::{AsInner, c, to_u16s}; -use crate::sys_common::wstr::WStrUnits; use crate::{io, iter, ptr}; pub fn args() -> Args { diff --git a/library/std/src/sys/env/solid.rs b/library/std/src/sys/env/solid.rs index ea77fc3c1193..0ce5a22b4256 100644 --- a/library/std/src/sys/env/solid.rs +++ b/library/std/src/sys/env/solid.rs @@ -6,7 +6,7 @@ use crate::io; use crate::os::raw::{c_char, c_int}; use crate::os::solid::ffi::{OsStrExt, OsStringExt}; use crate::sync::{PoisonError, RwLock}; -use crate::sys::common::small_c_string::run_with_cstr; +use crate::sys::helpers::run_with_cstr; static ENV_LOCK: RwLock<()> = RwLock::new(()); diff --git a/library/std/src/sys/env/uefi.rs b/library/std/src/sys/env/uefi.rs index 1561df41cac3..5fe29a47a2ea 100644 --- a/library/std/src/sys/env/uefi.rs +++ b/library/std/src/sys/env/uefi.rs @@ -24,7 +24,7 @@ mod uefi_env { use crate::io; use crate::os::uefi::ffi::OsStringExt; use crate::ptr::NonNull; - use crate::sys::{helpers, unsupported_err}; + use crate::sys::pal::{helpers, unsupported_err}; pub(crate) fn get(key: &OsStr) -> Option { let shell = helpers::open_shell()?; diff --git a/library/std/src/sys/env/unix.rs b/library/std/src/sys/env/unix.rs index 78c7af65f9e3..66805ce3fa71 100644 --- a/library/std/src/sys/env/unix.rs +++ b/library/std/src/sys/env/unix.rs @@ -7,8 +7,8 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::io; use crate::os::unix::prelude::*; use crate::sync::{PoisonError, RwLock}; -use crate::sys::common::small_c_string::run_with_cstr; use crate::sys::cvt; +use crate::sys::helpers::run_with_cstr; // Use `_NSGetEnviron` on Apple platforms. // diff --git a/library/std/src/sys/env/wasi.rs b/library/std/src/sys/env/wasi.rs index 1327cbc3263b..c970aac18260 100644 --- a/library/std/src/sys/env/wasi.rs +++ b/library/std/src/sys/env/wasi.rs @@ -4,7 +4,7 @@ pub use super::common::Env; use crate::ffi::{CStr, OsStr, OsString}; use crate::io; use crate::os::wasi::prelude::*; -use crate::sys::common::small_c_string::run_with_cstr; +use crate::sys::helpers::run_with_cstr; use crate::sys::pal::os::{cvt, libc}; cfg_select! { diff --git a/library/std/src/sys/fs/common.rs b/library/std/src/sys/fs/common.rs index bfd684d295b8..fbd075d57d61 100644 --- a/library/std/src/sys/fs/common.rs +++ b/library/std/src/sys/fs/common.rs @@ -3,7 +3,7 @@ use crate::fs; use crate::io::{self, Error, ErrorKind}; use crate::path::Path; -use crate::sys_common::ignore_notfound; +use crate::sys::helpers::ignore_notfound; pub(crate) const NOT_FILE_ERROR: Error = io::const_error!( ErrorKind::InvalidInput, diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index 0914e4b6c907..bb0c44d7e9a1 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -9,9 +9,9 @@ use crate::os::hermit::hermit_abi::{ use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::path::{Path, PathBuf}; use crate::sync::Arc; -use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::fd::FileDesc; pub use crate::sys::fs::common::{copy, exists}; +use crate::sys::helpers::run_path_with_cstr; use crate::sys::time::SystemTime; use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, cvt, unsupported, unsupported_err}; use crate::{fmt, mem}; diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index 4a66227ce5f4..fa046cb8e7da 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -17,7 +17,7 @@ cfg_select! { pub(crate) use unix::debug_assert_fd_is_open; #[cfg(any(target_os = "linux", target_os = "android"))] pub(super) use unix::CachedFileMetadata; - use crate::sys::common::small_c_string::run_path_with_cstr as with_native_path; + use crate::sys::helpers::run_path_with_cstr as with_native_path; } target_os = "windows" => { mod windows; diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index f6d5d3b784d3..b6d41cc4bc84 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -10,10 +10,10 @@ use crate::os::solid::ffi::OsStrExt; use crate::path::{Path, PathBuf}; use crate::sync::Arc; pub use crate::sys::fs::common::exists; +use crate::sys::helpers::ignore_notfound; use crate::sys::pal::{abi, error}; use crate::sys::time::SystemTime; use crate::sys::{unsupported, unsupported_err}; -use crate::sys_common::ignore_notfound; type CIntNotMinusOne = core::num::niche_types::NotAllOnes; diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 8339d835dd1c..f5530962c570 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -6,8 +6,8 @@ use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; +use crate::sys::pal::{helpers, unsupported}; use crate::sys::time::SystemTime; -use crate::sys::{helpers, unsupported}; const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY; @@ -497,7 +497,7 @@ mod uefi_fs { use crate::os::uefi::ffi::OsStringExt; use crate::path::Path; use crate::ptr::NonNull; - use crate::sys::helpers::{self, UefiBox}; + use crate::sys::pal::helpers::{self, UefiBox}; use crate::sys::time::{self, SystemTime}; pub(crate) struct File { diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 7ac09cbea3da..1cc2edd0cf47 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -89,9 +89,9 @@ use crate::os::unix::prelude::*; use crate::os::wasi::prelude::*; use crate::path::{Path, PathBuf}; use crate::sync::Arc; -use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::fd::FileDesc; pub use crate::sys::fs::common::exists; +use crate::sys::helpers::run_path_with_cstr; use crate::sys::time::SystemTime; #[cfg(all(target_os = "linux", target_env = "gnu"))] use crate::sys::weak::syscall; @@ -2498,9 +2498,8 @@ mod remove_dir_impl { use crate::ffi::CStr; use crate::io; use crate::path::{Path, PathBuf}; - use crate::sys::common::small_c_string::run_path_with_cstr; + use crate::sys::helpers::{ignore_notfound, run_path_with_cstr}; use crate::sys::{cvt, cvt_r}; - use crate::sys_common::ignore_notfound; pub fn openat_nofollow_dironly(parent_fd: Option, p: &CStr) -> io::Result { let fd = cvt_r(|| unsafe { diff --git a/library/std/src/sys/fs/vexos.rs b/library/std/src/sys/fs/vexos.rs index 381c87c62c68..81083a4fa81d 100644 --- a/library/std/src/sys/fs/vexos.rs +++ b/library/std/src/sys/fs/vexos.rs @@ -4,7 +4,7 @@ use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; -use crate::sys::common::small_c_string::run_path_with_cstr; +use crate::sys::helpers::run_path_with_cstr; use crate::sys::time::SystemTime; use crate::sys::{unsupported, unsupported_err}; diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs index c6df9c6b8ae1..256b99dfa987 100644 --- a/library/std/src/sys/net/connection/socket/mod.rs +++ b/library/std/src/sys/net/connection/socket/mod.rs @@ -7,7 +7,7 @@ use crate::mem::MaybeUninit; use crate::net::{ Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, }; -use crate::sys::common::small_c_string::run_with_cstr; +use crate::sys::helpers::run_with_cstr; use crate::sys::net::connection::each_addr; use crate::sys::{AsInner, FromInner}; use crate::time::Duration; diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index 1e7e829c85f3..0c8ba08d8149 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -2,7 +2,7 @@ use super::tcp4; use crate::io::{self, IoSlice, IoSliceMut}; use crate::net::SocketAddr; use crate::ptr::NonNull; -use crate::sys::{helpers, unsupported}; +use crate::sys::pal::{helpers, unsupported}; use crate::time::Duration; pub(crate) enum Tcp { diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index d059be010e98..353702447813 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -24,7 +24,7 @@ use crate::path::Path; use crate::ptr::NonNull; use crate::slice; use crate::sync::atomic::{Atomic, AtomicPtr, Ordering}; -use crate::sys_common::wstr::WStrUnits; +use crate::sys::helpers::WStrUnits; type BootInstallMultipleProtocolInterfaces = unsafe extern "efiapi" fn(_: *mut r_efi::efi::Handle, _: ...) -> r_efi::efi::Status; diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs index c0f13de252ed..3dccd03ff3fc 100644 --- a/library/std/src/sys/pal/uefi/time.rs +++ b/library/std/src/sys/pal/uefi/time.rs @@ -300,7 +300,7 @@ pub(crate) mod instant_internal { use crate::mem::MaybeUninit; use crate::ptr::NonNull; use crate::sync::atomic::{Atomic, AtomicPtr, Ordering}; - use crate::sys_common::mul_div_u64; + use crate::sys::helpers::mul_div_u64; const NS_PER_SEC: u64 = 1_000_000_000; diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index edb7b604415b..ef3b4a02f8ae 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -10,8 +10,8 @@ use libc::{c_char, c_int, c_void}; use crate::ffi::{CStr, OsStr, OsString}; use crate::os::unix::prelude::*; use crate::path::{self, PathBuf}; -use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::cvt; +use crate::sys::helpers::run_path_with_cstr; use crate::{fmt, io, iter, mem, ptr, slice, str}; const TMPBUF_SZ: usize = 128; diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs index a3bb329c2c4f..fee187a8adf3 100644 --- a/library/std/src/sys/pal/wasi/os.rs +++ b/library/std/src/sys/pal/wasi/os.rs @@ -4,7 +4,7 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::marker::PhantomData; use crate::os::wasi::prelude::*; use crate::path::{self, PathBuf}; -use crate::sys::common::small_c_string::run_path_with_cstr; +use crate::sys::helpers::run_path_with_cstr; use crate::sys::unsupported; use crate::{fmt, io, str}; diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs index ecd46c950b5e..a555b2b54623 100644 --- a/library/std/src/sys/pal/windows/time.rs +++ b/library/std/src/sys/pal/windows/time.rs @@ -179,8 +179,8 @@ fn intervals2dur(intervals: u64) -> Duration { mod perf_counter { use super::NANOS_PER_SEC; use crate::sync::atomic::{Atomic, AtomicU64, Ordering}; + use crate::sys::helpers::mul_div_u64; use crate::sys::{c, cvt}; - use crate::sys_common::mul_div_u64; use crate::time::Duration; pub struct PerformanceCounterInstant { diff --git a/library/std/src/sys/path/cygwin.rs b/library/std/src/sys/path/cygwin.rs index 416877a7280d..75f0de6beaeb 100644 --- a/library/std/src/sys/path/cygwin.rs +++ b/library/std/src/sys/path/cygwin.rs @@ -1,8 +1,8 @@ use crate::ffi::OsString; use crate::os::unix::ffi::OsStringExt; use crate::path::{Path, PathBuf}; -use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::cvt; +use crate::sys::helpers::run_path_with_cstr; use crate::{io, ptr}; #[inline] diff --git a/library/std/src/sys/path/uefi.rs b/library/std/src/sys/path/uefi.rs index 6b8258685aa0..84d634af93cf 100644 --- a/library/std/src/sys/path/uefi.rs +++ b/library/std/src/sys/path/uefi.rs @@ -2,7 +2,8 @@ use crate::ffi::OsStr; use crate::io; use crate::path::{Path, PathBuf, Prefix}; -use crate::sys::{helpers, unsupported_err}; +use crate::sys::pal::helpers; +use crate::sys::unsupported_err; const FORWARD_SLASH: u8 = b'/'; const COLON: u8 = b':'; diff --git a/library/std/src/sys/platform_version/darwin/core_foundation.rs b/library/std/src/sys/platform_version/darwin/core_foundation.rs index 1e0d15fcf661..de2b57ea755b 100644 --- a/library/std/src/sys/platform_version/darwin/core_foundation.rs +++ b/library/std/src/sys/platform_version/darwin/core_foundation.rs @@ -3,7 +3,7 @@ use super::root_relative; use crate::ffi::{CStr, c_char, c_void}; use crate::ptr::null_mut; -use crate::sys::common::small_c_string::run_path_with_cstr; +use crate::sys::helpers::run_path_with_cstr; // MacTypes.h pub(super) type Boolean = u8; diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index 0e10bc02a0b9..d627a477dc1a 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -377,8 +377,8 @@ mod uefi_command_internal { use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; use crate::ptr::NonNull; use crate::slice; + use crate::sys::helpers::WStrUnits; use crate::sys::pal::helpers::{self, OwnedTable}; - use crate::sys_common::wstr::WStrUnits; pub struct Image { handle: NonNull, From d8489c1ea02d9af8035d8aca5d4ee16056051eeb Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 21:19:40 +0100 Subject: [PATCH 1520/3801] std: remove outdated documentation in `sys` --- library/std/src/sys/configure_builtins.rs | 4 ++++ library/std/src/sys/mod.rs | 12 ++-------- .../src/sys/net/connection/socket/hermit.rs | 1 - .../src/sys/net/connection/socket/solid.rs | 1 - .../std/src/sys/net/connection/socket/unix.rs | 1 - .../src/sys/net/connection/socket/windows.rs | 1 - library/std/src/sys/pal/mod.rs | 23 ++----------------- src/tools/tidy/src/pal.rs | 1 - 8 files changed, 8 insertions(+), 36 deletions(-) diff --git a/library/std/src/sys/configure_builtins.rs b/library/std/src/sys/configure_builtins.rs index f569ec0f5129..7cdf04ebb889 100644 --- a/library/std/src/sys/configure_builtins.rs +++ b/library/std/src/sys/configure_builtins.rs @@ -1,3 +1,7 @@ +//! The configure builtins provides runtime support compiler-builtin features +//! which require dynamic initialization to work as expected, e.g. aarch64 +//! outline-atomics. + /// Enable LSE atomic operations at startup, if supported. /// /// Linker sections are based on what [`ctor`] does, with priorities to run slightly before user diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index bfdbc6ee5d1e..c9035938cfdd 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -1,17 +1,9 @@ #![allow(unsafe_op_in_unsafe_fn)] -/// The configure builtins provides runtime support compiler-builtin features -/// which require dynamic initialization to work as expected, e.g. aarch64 -/// outline-atomics. -mod configure_builtins; - -/// The PAL (platform abstraction layer) contains platform-specific abstractions -/// for implementing the features in the other submodules, e.g. UNIX file -/// descriptors. -mod pal; - mod alloc; +mod configure_builtins; mod helpers; +mod pal; mod personality; pub mod args; diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs index c32f8dcc8de8..d57a075eb42d 100644 --- a/library/std/src/sys/net/connection/socket/hermit.rs +++ b/library/std/src/sys/net/connection/socket/hermit.rs @@ -300,7 +300,6 @@ impl Socket { if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } - // This is used by sys_common code to abstract over Windows and Unix. pub fn as_raw(&self) -> RawFd { self.0.as_raw_fd() } diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs index 673d75046d3f..e20a3fbb76b7 100644 --- a/library/std/src/sys/net/connection/socket/solid.rs +++ b/library/std/src/sys/net/connection/socket/solid.rs @@ -353,7 +353,6 @@ impl Socket { if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } - // This method is used by sys_common code to abstract over targets. pub fn as_raw(&self) -> c_int { self.as_raw_fd() } diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index 6d06a8d86bf1..d09ba97cfe01 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -614,7 +614,6 @@ impl Socket { if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } - // This is used by sys_common code to abstract over Windows and Unix. pub fn as_raw(&self) -> RawFd { self.as_raw_fd() } diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index 7355f0ce6bf5..3f99249efc47 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs @@ -439,7 +439,6 @@ impl Socket { if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } - // This is used by sys_common code to abstract over Windows and Unix. pub fn as_raw(&self) -> c::SOCKET { debug_assert_eq!(size_of::(), size_of::()); debug_assert_eq!(align_of::(), align_of::()); diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index c039c2894877..88d9d4205990 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -1,24 +1,5 @@ -//! Platform-dependent platform abstraction. -//! -//! The `std::sys` module is the abstracted interface through which -//! `std` talks to the underlying operating system. It has different -//! implementations for different operating system families, today -//! just Unix and Windows, and initial support for Redox. -//! -//! The centralization of platform-specific code in this module is -//! enforced by the "platform abstraction layer" tidy script in -//! `tools/tidy/src/pal.rs`. -//! -//! This module is closely related to the platform-independent system -//! integration code in `std::sys_common`. See that module's -//! documentation for details. -//! -//! In the future it would be desirable for the independent -//! implementations of this module to be extracted to their own crates -//! that `std` can link to, thus enabling their implementation -//! out-of-tree via crate replacement. Though due to the complex -//! inter-dependencies within `std` that will be a challenging goal to -//! achieve. +//! The PAL (platform abstraction layer) contains platform-specific abstractions +//! for implementing the features in the other submodules, such as e.g. bindings. #![allow(missing_debug_implementations)] diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index e5945a72d32a..e6423aeeba99 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -24,7 +24,6 @@ //! - `sys/` //! - `os/` //! -//! `std/sys_common` should _not_ contain platform-specific code. //! Finally, because std contains tests with platform-specific //! `ignore` attributes, once the parser encounters `mod tests`, //! platform-specific cfgs are allowed. Not sure yet how to deal with From fc9f0fbf565eb8ff20a67870b6be41919251f53c Mon Sep 17 00:00:00 2001 From: joboet Date: Mon, 29 Dec 2025 10:07:16 +0100 Subject: [PATCH 1521/3801] bless UI test referencing outdated paths --- .../miri/tests/fail/shims/fs/isolated_file.stderr | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr index af55ccfe5e67..09501f98a9aa 100644 --- a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr +++ b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr @@ -15,12 +15,12 @@ LL | let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode a at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC 3: std::sys::fs::PLATFORM::File::open::{closure#0} at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC - 4: std::sys::pal::PLATFORM::small_c_string::run_with_cstr_stack - at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - 5: std::sys::pal::PLATFORM::small_c_string::run_with_cstr - at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC - 6: std::sys::pal::PLATFORM::small_c_string::run_path_with_cstr - at RUSTLIB/std/src/sys/pal/PLATFORM/small_c_string.rs:LL:CC + 4: std::sys::helpers::small_c_string::run_with_cstr_stack + at RUSTLIB/std/src/sys/helpers/small_c_string.rs:LL:CC + 5: std::sys::helpers::small_c_string::run_with_cstr + at RUSTLIB/std/src/sys/helpers/small_c_string.rs:LL:CC + 6: std::sys::helpers::small_c_string::run_path_with_cstr + at RUSTLIB/std/src/sys/helpers/small_c_string.rs:LL:CC 7: std::sys::fs::PLATFORM::File::open at RUSTLIB/std/src/sys/fs/PLATFORM.rs:LL:CC 8: std::fs::OpenOptions::_open From 7834c43ea6913f2ccf28373fffa321a495ab2f7c Mon Sep 17 00:00:00 2001 From: joboet Date: Mon, 29 Dec 2025 10:09:57 +0100 Subject: [PATCH 1522/3801] beautify comment in `sys::helpers` --- library/std/src/sys/helpers/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/helpers/mod.rs b/library/std/src/sys/helpers/mod.rs index c29d9d2ce2d1..a6236799caea 100644 --- a/library/std/src/sys/helpers/mod.rs +++ b/library/std/src/sys/helpers/mod.rs @@ -16,8 +16,9 @@ pub use small_c_string::{run_path_with_cstr, run_with_cstr}; #[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. pub use wstr::WStrUnits; -// Computes (value*numerator)/denom without overflow, as long as both (numerator*denom) and the -// overall result fit into i64 (which is the case for our time conversions). +/// Computes `(value*numerator)/denom` without overflow, as long as both +/// `numerator*denom` and the overall result fit into `u64` (which is the case +/// for our time conversions). #[cfg_attr(not(target_os = "windows"), allow(unused))] // Not used on all platforms. pub fn mul_div_u64(value: u64, numerator: u64, denom: u64) -> u64 { let q = value / denom; From 296ab7c15c0a8d7af7a66057213835244e7c3b15 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 2 Jan 2026 19:19:38 +0100 Subject: [PATCH 1523/3801] android: get the entire test suite to pass --- src/tools/miri/README.md | 2 +- src/tools/miri/ci/ci.sh | 3 +- src/tools/miri/src/shims/env.rs | 5 +- .../src/shims/unix/android/foreign_items.rs | 69 +++++++++++++++++++ .../miri/src/shims/unix/foreign_items.rs | 2 +- .../src/shims/unix/freebsd/foreign_items.rs | 4 +- src/tools/miri/src/shims/unix/fs.rs | 34 +++++---- .../src/shims/unix/macos/foreign_items.rs | 4 +- .../src/shims/unix/solarish/foreign_items.rs | 4 +- .../miri/src/shims/unix/unnamed_socket.rs | 2 +- .../miri/tests/pass-dep/libc/libc-fs-flock.rs | 1 + .../miri/tests/pass-dep/libc/libc-pipe.rs | 2 + src/tools/miri/tests/pass-dep/shims/gettid.rs | 6 +- src/tools/miri/tests/pass-dep/tempfile.rs | 11 +-- src/tools/miri/tests/pass/shims/fs.rs | 6 +- 15 files changed, 109 insertions(+), 46 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 2832ef50adef..d5ef9c767414 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -219,7 +219,7 @@ degree documented below): - We have unofficial support (not maintained by the Miri team itself) for some further operating systems. - `solaris` / `illumos`: maintained by @devnexen. Supports the entire test suite. - `freebsd`: maintained by @YohDeadfall and @LorrensP-2158466. Supports the entire test suite. - - `android`: **maintainer wanted**. Basic OS APIs and concurrency work, but file system access is not supported. + - `android`: **maintainer wanted**. Supports the entire test suite. - For targets on other operating systems, Miri might fail before even reaching the `main` function. However, even for targets that we do support, the degree of support for accessing platform APIs diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 2dd8fc77459a..82007a8c1c1a 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -149,10 +149,11 @@ case $HOST_TARGET in i686-unknown-linux-gnu) # Host MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 CARGO_MIRI_ENV=1 run_tests + # Fully, but not officially, supported tier 2 + MANY_SEEDS=16 TEST_TARGET=aarch64-linux-android run_tests # Partially supported targets (tier 2) BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there - TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd prctl TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std ;; diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index 6915924f2a48..7c463983320b 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -119,9 +119,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_ref(); let index = thread.to_u32(); let target_os = &this.tcx.sess.target.os; - if matches!(target_os, Os::Linux | Os::NetBsd) { - // On Linux, the main thread has PID == TID so we uphold this. NetBSD also appears - // to exhibit the same behavior, though I can't find a citation. + if matches!(target_os, Os::Linux | Os::Android) { + // On Linux, the main thread has PID == TID so we uphold this. this.get_pid().strict_add(index) } else { // Other platforms do not display any relationship between PID and TID. 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 6cb0d221fc03..2b290b68c78c 100644 --- a/src/tools/miri/src/shims/unix/android/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs @@ -8,6 +8,7 @@ use crate::shims::unix::env::EvalContextExt as _; use crate::shims::unix::linux_like::epoll::EvalContextExt as _; use crate::shims::unix::linux_like::eventfd::EvalContextExt as _; use crate::shims::unix::linux_like::syscall::syscall; +use crate::shims::unix::*; use crate::*; pub fn is_dyn_sym(name: &str) -> bool { @@ -25,6 +26,74 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, EmulateItemResult> { let this = self.eval_context_mut(); match link_name.as_str() { + // File related shims + "stat" => { + let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + let result = this.stat(path, buf)?; + this.write_scalar(result, dest)?; + } + "lstat" => { + let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + let result = this.lstat(path, buf)?; + this.write_scalar(result, dest)?; + } + "readdir" => { + let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + let result = this.readdir64("dirent", dirp)?; + this.write_scalar(result, dest)?; + } + "pread64" => { + let [fd, buf, count, offset] = this.check_shim_sig( + shim_sig!(extern "C" fn(i32, *mut _, usize, libc::off64_t) -> isize), + link_name, + abi, + args, + )?; + let fd = this.read_scalar(fd)?.to_i32()?; + let buf = this.read_pointer(buf)?; + let count = this.read_target_usize(count)?; + let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; + this.read(fd, buf, count, Some(offset), dest)?; + } + "pwrite64" => { + let [fd, buf, n, offset] = this.check_shim_sig( + shim_sig!(extern "C" fn(i32, *const _, usize, libc::off64_t) -> isize), + link_name, + abi, + args, + )?; + let fd = this.read_scalar(fd)?.to_i32()?; + let buf = this.read_pointer(buf)?; + let count = this.read_target_usize(n)?; + let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; + trace!("Called pwrite64({:?}, {:?}, {:?}, {:?})", fd, buf, count, offset); + this.write(fd, buf, count, Some(offset), dest)?; + } + "lseek64" => { + 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, + )?; + let fd = this.read_scalar(fd)?.to_i32()?; + let offset = this.read_scalar(offset)?.to_int(offset.layout.size)?; + let whence = this.read_scalar(whence)?.to_i32()?; + this.lseek64(fd, offset, whence, dest)?; + } + "ftruncate64" => { + let [fd, length] = this.check_shim_sig( + shim_sig!(extern "C" fn(i32, libc::off64_t) -> i32), + link_name, + abi, + args, + )?; + let fd = this.read_scalar(fd)?.to_i32()?; + let length = this.read_scalar(length)?.to_int(length.layout.size)?; + let result = this.ftruncate64(fd, length)?; + this.write_scalar(result, dest)?; + } + // epoll, eventfd "epoll_create1" => { let [flag] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 64b8376ff4aa..8eacdc3583d4 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -510,7 +510,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pipe2" => { // Currently this function does not exist on all Unixes, e.g. on macOS. this.check_target_os( - &[Os::Linux, Os::FreeBsd, Os::Solaris, Os::Illumos], + &[Os::Linux, Os::Android, Os::FreeBsd, Os::Solaris, Os::Illumos], link_name, )?; let [pipefd, flags] = this.check_shim_sig( 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 c48301c72416..fb2d3f758420 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -140,12 +140,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // since freebsd 12 the former form can be expected. "stat" | "stat@FBSD_1.0" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_solarish_stat(path, buf)?; + let result = this.stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat@FBSD_1.0" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_solarish_lstat(path, buf)?; + let result = this.lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat@FBSD_1.0" => { diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index e17456c3bc0e..f43fd3fe2d18 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -527,15 +527,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(Scalar::from_i32(this.try_unwrap_io_result(result)?)) } - fn macos_fbsd_solarish_stat( - &mut self, - path_op: &OpTy<'tcx>, - buf_op: &OpTy<'tcx>, - ) -> InterpResult<'tcx, Scalar> { + fn stat(&mut self, path_op: &OpTy<'tcx>, buf_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos) - { + if !matches!( + &this.tcx.sess.target.os, + Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos | Os::Android + ) { panic!("`macos_fbsd_solaris_stat` should not be called on {}", this.tcx.sess.target.os); } @@ -558,15 +556,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // `lstat` is used to get symlink metadata. - fn macos_fbsd_solarish_lstat( - &mut self, - path_op: &OpTy<'tcx>, - buf_op: &OpTy<'tcx>, - ) -> InterpResult<'tcx, Scalar> { + fn lstat(&mut self, path_op: &OpTy<'tcx>, buf_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos) - { + if !matches!( + &this.tcx.sess.target.os, + Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos | Os::Android + ) { panic!( "`macos_fbsd_solaris_lstat` should not be called on {}", this.tcx.sess.target.os @@ -595,7 +591,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if !matches!( &this.tcx.sess.target.os, - Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos | Os::Linux + Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos | Os::Linux | Os::Android ) { panic!("`fstat` should not be called on {}", this.tcx.sess.target.os); } @@ -906,9 +902,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn readdir64(&mut self, dirent_type: &str, dirp_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - if !matches!(&this.tcx.sess.target.os, Os::Linux | Os::Solaris | Os::Illumos | Os::FreeBsd) - { - panic!("`linux_solaris_readdir64` should not be called on {}", this.tcx.sess.target.os); + if !matches!( + &this.tcx.sess.target.os, + Os::Linux | Os::Android | Os::Solaris | Os::Illumos | Os::FreeBsd + ) { + panic!("`readdir64` should not be called on {}", this.tcx.sess.target.os); } let dirp = this.read_target_usize(dirp_op)?; diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index dd7b95bdc82b..f798f64441b1 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -48,12 +48,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "stat" | "stat$INODE64" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_solarish_stat(path, buf)?; + let result = this.stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat$INODE64" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_solarish_lstat(path, buf)?; + let result = this.lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat$INODE64" => { 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 ae7230877a71..fa8c86b025a7 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -92,12 +92,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File related shims "stat" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_solarish_stat(path, buf)?; + let result = this.stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" => { let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let result = this.macos_fbsd_solarish_lstat(path, buf)?; + let result = this.lstat(path, buf)?; this.write_scalar(result, dest)?; } "readdir" => { diff --git a/src/tools/miri/src/shims/unix/unnamed_socket.rs b/src/tools/miri/src/shims/unix/unnamed_socket.rs index a320ac131689..cc371b43a681 100644 --- a/src/tools/miri/src/shims/unix/unnamed_socket.rs +++ b/src/tools/miri/src/shims/unix/unnamed_socket.rs @@ -459,7 +459,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Interpret the flag. Every flag we recognize is "subtracted" from `flags`, so // if there is anything left at the end, that's an unsupported flag. - if this.tcx.sess.target.os == Os::Linux { + if matches!(this.tcx.sess.target.os, Os::Linux | Os::Android) { // SOCK_NONBLOCK only exists on Linux. let sock_nonblock = this.eval_libc_i32("SOCK_NONBLOCK"); let sock_cloexec = this.eval_libc_i32("SOCK_CLOEXEC"); diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs index 0500ba05046c..52de8c7104c2 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs @@ -1,5 +1,6 @@ //@ignore-target: windows # File handling is not implemented yet //@ignore-target: solaris # Does not have flock +//@ignore-target: android # Does not (always?) have flock //@compile-flags: -Zmiri-disable-isolation use std::fs::File; diff --git a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs index ffbcf633b987..63e330fed636 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs @@ -13,6 +13,7 @@ fn main() { test_pipe_array(); #[cfg(any( target_os = "linux", + target_os = "android", target_os = "illumos", target_os = "freebsd", target_os = "solaris" @@ -133,6 +134,7 @@ fn test_pipe_array() { /// Test if pipe2 (including the O_NONBLOCK flag) is supported. #[cfg(any( target_os = "linux", + target_os = "android", target_os = "illumos", target_os = "freebsd", target_os = "solaris" diff --git a/src/tools/miri/tests/pass-dep/shims/gettid.rs b/src/tools/miri/tests/pass-dep/shims/gettid.rs index b7a2fa49ef86..9d5ff0dc5dae 100644 --- a/src/tools/miri/tests/pass-dep/shims/gettid.rs +++ b/src/tools/miri/tests/pass-dep/shims/gettid.rs @@ -165,7 +165,7 @@ fn main() { // The value is not important, we only care that whatever the value is, // won't change from execution to execution. if cfg!(with_isolation) { - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "android")) { // Linux starts the TID at the PID, which is 1000. assert_eq!(tid, 1000); } else { @@ -174,8 +174,8 @@ fn main() { } } - // On Linux and NetBSD, the first TID is the PID. - #[cfg(any(target_os = "linux", target_os = "netbsd"))] + // On Linux, the first TID is the PID. + #[cfg(any(target_os = "linux", target_os = "android"))] assert_eq!(tid, unsafe { libc::getpid() } as u64); #[cfg(any(target_vendor = "apple", windows))] diff --git a/src/tools/miri/tests/pass-dep/tempfile.rs b/src/tools/miri/tests/pass-dep/tempfile.rs index a44a7e7d9244..885190bd776a 100644 --- a/src/tools/miri/tests/pass-dep/tempfile.rs +++ b/src/tools/miri/tests/pass-dep/tempfile.rs @@ -7,15 +7,8 @@ mod utils; /// Test that the [`tempfile`] crate is compatible with miri for UNIX hosts and targets fn main() { - test_tempfile(); - test_tempfile_in(); -} - -fn test_tempfile() { - tempfile::tempfile().unwrap(); -} - -fn test_tempfile_in() { + // Only create a file in our own tmp folder; the "host" temp folder + // can be nonsensical for cross-tests. let dir_path = utils::tmp(); tempfile::tempfile_in(dir_path).unwrap(); } diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 648c90b5dd97..50b5dbfba1cd 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -37,7 +37,7 @@ fn main() { test_canonicalize(); #[cfg(unix)] test_pread_pwrite(); - #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] + #[cfg(not(any(target_os = "solaris", target_os = "android")))] test_flock(); } } @@ -399,8 +399,8 @@ fn test_pread_pwrite() { assert_eq!(&buf1, b" m"); } -// This function does seem to exist on Illumos but std does not expose it there. -#[cfg(not(any(target_os = "solaris", target_os = "illumos")))] +// The standard library does not support this operation on Solaris, Android +#[cfg(not(any(target_os = "solaris", target_os = "android")))] fn test_flock() { let bytes = b"Hello, World!\n"; let path = utils::prepare_with_content("miri_test_fs_flock.txt", bytes); From ac453d34d21bc4817dd41df0a4eeac88a541b9ba Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 2 Jan 2026 20:21:00 +0100 Subject: [PATCH 1524/3801] Update `browser-ui-test` version to `0.23.0` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 007e2c116321..ef74853b77a5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "browser-ui-test": "^0.22.2", + "browser-ui-test": "^0.23.0", "es-check": "^9.4.4", "eslint": "^8.57.1", "typescript": "^5.8.3" From 665781513e6a8d6a63ed9fab5b98f919ad3f627c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 2 Jan 2026 20:21:44 +0100 Subject: [PATCH 1525/3801] Fix changes coming from `browser-ui-test` version update --- tests/rustdoc-gui/anchors.goml | 8 ++++---- tests/rustdoc-gui/links-color.goml | 2 +- tests/rustdoc-gui/sidebar-mobile.goml | 2 +- tests/rustdoc-gui/sidebar-source-code-display.goml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/rustdoc-gui/anchors.goml b/tests/rustdoc-gui/anchors.goml index 3168c8e17c52..0e8c834a7a77 100644 --- a/tests/rustdoc-gui/anchors.goml +++ b/tests/rustdoc-gui/anchors.goml @@ -15,7 +15,7 @@ define-function: ( assert-css: (".main-heading h1 span", {"color": |main_heading_type_color|}) assert-css: ( ".rightside a.src", - {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, + {"color": |src_link_color|, "text-decoration": "none"}, ALL, ) compare-elements-css: ( @@ -32,17 +32,17 @@ define-function: ( move-cursor-to: ".main-heading a.src" assert-css: ( ".main-heading a.src", - {"color": |src_link_color|, "text-decoration": "underline solid " + |src_link_color|}, + {"color": |src_link_color|, "text-decoration": "underline"}, ) move-cursor-to: ".impl-items .rightside a.src" assert-css: ( ".impl-items .rightside a.src", - {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, + {"color": |src_link_color|, "text-decoration": "none"}, ) move-cursor-to: ".impl-items a.rightside.src" assert-css: ( ".impl-items a.rightside.src", - {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, + {"color": |src_link_color|, "text-decoration": "none"}, ) go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml index a363175c1ddb..ae1509c6fa4f 100644 --- a/tests/rustdoc-gui/links-color.goml +++ b/tests/rustdoc-gui/links-color.goml @@ -41,7 +41,7 @@ define-function: ( move-cursor-to: "dd a[href='long_code_block_link/index.html']" assert-css: ( "dd a[href='long_code_block_link/index.html']", - {"text-decoration": "underline solid " + |mod|}, + {"text-decoration": "underline"}, ) }, ) diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index f828516d7624..1fa5521baac9 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -49,7 +49,7 @@ assert-property: ("rustdoc-topbar", {"clientHeight": "45"}) // so the target is not obscured by the topbar. click: ".sidebar-menu-toggle" click: ".sidebar-elems section .block li > a" -assert-position: ("#method\.must_use", {"y": 46}) +assert-position: ("#method\.must_use", {"y": 45}) // Check that the bottom-most item on the sidebar menu can be scrolled fully into view. click: ".sidebar-menu-toggle" diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml index 99810cd78633..d2b667b498bc 100644 --- a/tests/rustdoc-gui/sidebar-source-code-display.goml +++ b/tests/rustdoc-gui/sidebar-source-code-display.goml @@ -141,7 +141,7 @@ click: "#sidebar-button" wait-for-css: (".src .sidebar > *", {"visibility": "hidden"}) // We scroll to line 117 to change the scroll position. scroll-to: '//*[@id="117"]' -store-value: (y_offset, "2567") +store-value: (y_offset, "2568") assert-window-property: {"pageYOffset": |y_offset|} // Expanding the sidebar... click: "#sidebar-button" From 0451cc012a4890abcbc217d4105b8ecf3daecf43 Mon Sep 17 00:00:00 2001 From: benodiwal Date: Sat, 3 Jan 2026 00:52:19 +0530 Subject: [PATCH 1526/3801] fix: add location links for generic type parameters in inlay hints --- .../crates/hir-ty/src/display.rs | 14 ++++++++++++-- src/tools/rust-analyzer/crates/hir/src/lib.rs | 8 ++++---- .../crates/ide/src/inlay_hints.rs | 19 +++++++++++++++++-- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 44bbd84003da..4f9406908ffd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -10,7 +10,8 @@ use std::{ use base_db::{Crate, FxIndexMap}; use either::Either; use hir_def::{ - FindPathConfig, GenericDefId, HasModule, LocalFieldId, Lookup, ModuleDefId, ModuleId, TraitId, + FindPathConfig, GenericDefId, GenericParamId, HasModule, LocalFieldId, Lookup, ModuleDefId, + ModuleId, TraitId, db::DefDatabase, expr_store::{ExpressionStore, path::Path}, find_path::{self, PrefixKind}, @@ -66,6 +67,7 @@ pub type Result = std::result::Result; pub trait HirWrite: fmt::Write { fn start_location_link(&mut self, _location: ModuleDefId) {} + fn start_location_link_generic(&mut self, _location: GenericParamId) {} fn end_location_link(&mut self) {} } @@ -147,6 +149,10 @@ impl<'db> HirFormatter<'_, 'db> { self.fmt.start_location_link(location); } + pub fn start_location_link_generic(&mut self, location: GenericParamId) { + self.fmt.start_location_link_generic(location); + } + pub fn end_location_link(&mut self) { self.fmt.end_location_link(); } @@ -1489,6 +1495,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> { match param_data { TypeOrConstParamData::TypeParamData(p) => match p.provenance { TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => { + f.start_location_link_generic(param.id.into()); write!( f, "{}", @@ -1496,7 +1503,8 @@ impl<'db> HirDisplay<'db> for Ty<'db> { .clone() .unwrap_or_else(Name::missing) .display(f.db, f.edition()) - )? + )?; + f.end_location_link(); } TypeParamProvenance::ArgumentImplTrait => { let bounds = GenericPredicates::query_all(f.db, param.id.parent()) @@ -1519,7 +1527,9 @@ impl<'db> HirDisplay<'db> for Ty<'db> { } }, TypeOrConstParamData::ConstParamData(p) => { + f.start_location_link_generic(param.id.into()); write!(f, "{}", p.name.display(f.db, f.edition()))?; + f.end_location_link(); } } } diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 1ab57c4489cf..65de6c0a554a 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -50,9 +50,9 @@ use either::Either; use hir_def::{ AdtId, AssocItemId, AssocItemLoc, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, - GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, - MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, - TypeOrConstParamId, TypeParamId, UnionId, + HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, + MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, TypeOrConstParamId, + TypeParamId, UnionId, attrs::AttrFlags, builtin_derive::BuiltinDeriveImplMethod, expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, @@ -150,7 +150,7 @@ pub use { visibility::Visibility, // FIXME: This is here since some queries take it as input that are used // outside of hir. - {ModuleDefId, TraitId}, + {GenericParamId, ModuleDefId, TraitId}, }, hir_expand::{ EditionedFileId, ExpandResult, HirFileId, MacroCallId, MacroKind, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index 06ae0b1d73d1..a58dc6f03055 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -5,8 +5,8 @@ use std::{ use either::Either; use hir::{ - ClosureStyle, DisplayTarget, EditionedFileId, HasVisibility, HirDisplay, HirDisplayError, - HirWrite, InRealFile, ModuleDef, ModuleDefId, Semantics, sym, + ClosureStyle, DisplayTarget, EditionedFileId, GenericParam, GenericParamId, HasVisibility, + HirDisplay, HirDisplayError, HirWrite, InRealFile, ModuleDef, ModuleDefId, Semantics, sym, }; use ide_db::{ FileRange, MiniCore, RootDatabase, famous_defs::FamousDefs, text_edit::TextEditBuilder, @@ -709,6 +709,21 @@ impl HirWrite for InlayHintLabelBuilder<'_> { }); } + fn start_location_link_generic(&mut self, def: GenericParamId) { + never!(self.location.is_some(), "location link is already started"); + self.make_new_part(); + + self.location = Some(if self.resolve { + LazyProperty::Lazy + } else { + LazyProperty::Computed({ + let Some(location) = GenericParam::from(def).try_to_nav(self.sema) else { return }; + let location = location.call_site(); + FileRange { file_id: location.file_id, range: location.focus_or_full_range() } + }) + }); + } + fn end_location_link(&mut self) { self.make_new_part(); } From 1222bbf29c7a0484c322006d8771dadcd47447c0 Mon Sep 17 00:00:00 2001 From: benodiwal Date: Sat, 3 Jan 2026 00:59:03 +0530 Subject: [PATCH 1527/3801] feat: added tests --- .../crates/ide/src/inlay_hints/bind_pat.rs | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index 547004687c73..79cc2bdf8f7b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -183,7 +183,8 @@ mod tests { use crate::{ClosureReturnTypeHints, fixture, inlay_hints::InlayHintsConfig}; use crate::inlay_hints::tests::{ - DISABLED_CONFIG, TEST_CONFIG, check, check_edit, check_no_edit, check_with_config, + DISABLED_CONFIG, TEST_CONFIG, check, check_edit, check_expect, check_no_edit, + check_with_config, }; #[track_caller] @@ -1255,4 +1256,40 @@ where "#, ); } + + #[test] + fn generic_param_inlay_hint_has_location_link() { + check_expect( + InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG }, + r#" +fn identity(t: T) -> T { + let x = t; + x +} +"#, + expect![[r#" + [ + ( + 36..37, + [ + InlayHintLabelPart { + text: "T", + linked_location: Some( + Computed( + FileRangeWrapper { + file_id: FileId( + 0, + ), + range: 12..13, + }, + ), + ), + tooltip: "", + }, + ], + ), + ] + "#]], + ); + } } From 9a675c09cf65539e39e90d2adb6046870ec6a745 Mon Sep 17 00:00:00 2001 From: Clara Engler Date: Fri, 2 Jan 2026 20:40:04 +0100 Subject: [PATCH 1528/3801] alloc: Move Cow impl to existing ones Right now, the `borrow.rs` module starts with a `Cow` impl, although most of them can be found below. This hurts code readability because there is `ToOwned` alongside its impl directly below it. Moving it to the others down below makes sense here, given that the entire enum depends on `ToOwned` anyways. --- library/alloc/src/borrow.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index aa973e0bb024..d1c7cd47da0f 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -16,19 +16,6 @@ use crate::fmt; #[cfg(not(no_global_oom_handling))] use crate::string::String; -// FIXME(inference): const bounds removed due to inference regressions found by crater; -// see https://github.com/rust-lang/rust/issues/147964 -// #[rustc_const_unstable(feature = "const_convert", issue = "143773")] -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, B: ?Sized + ToOwned> Borrow for Cow<'a, B> -// where -// B::Owned: [const] Borrow, -{ - fn borrow(&self) -> &B { - &**self - } -} - /// A generalization of `Clone` to borrowed data. /// /// Some types make it possible to go from borrowed to owned, usually by @@ -192,6 +179,19 @@ where Owned(#[stable(feature = "rust1", since = "1.0.0")] ::Owned), } +// FIXME(inference): const bounds removed due to inference regressions found by crater; +// see https://github.com/rust-lang/rust/issues/147964 +// #[rustc_const_unstable(feature = "const_convert", issue = "143773")] +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, B: ?Sized + ToOwned> Borrow for Cow<'a, B> +// where +// B::Owned: [const] Borrow, +{ + fn borrow(&self) -> &B { + &**self + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Cow<'_, B> { fn clone(&self) -> Self { From dd97e41d47b1bec301db3c334f4c378c946d9224 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 01:24:03 +0530 Subject: [PATCH 1529/3801] for filename, use localfilename first and then resort to other construction --- .../crates/load-cargo/src/lib.rs | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 5aa96582e9f3..023253f23f42 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -563,14 +563,23 @@ impl ProcMacroExpander for Expander { let source_root_id = db.file_source_root(file).source_root_id(db); let source_root = db.source_root(source_root_id).source_root(db); - let name = source_root.path_for_file(&file).and_then(|path| { - path.name_and_extension().map(|(name, ext)| match ext { - Some(ext) => format!("{name}.{ext}"), - None => name.to_owned(), - }) - }); + let path = source_root.path_for_file(&file); - Ok(SubResponse::FileNameResult { name: name.unwrap_or_default() }) + let name = path + .and_then(|p| p.as_path()) + .and_then(|p| p.file_name()) + .map(|n| n.to_owned()) + .or_else(|| { + path.and_then(|p| { + p.name_and_extension().map(|(name, ext)| match ext { + Some(ext) => format!("{name}.{ext}"), + None => name.into(), + }) + }) + }) + .unwrap_or_default(); + + Ok(SubResponse::FileNameResult { name }) } }; match self.0.expand( From f41fa64f97d91f3256b6c69b998705a737cf7edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Fri, 2 Jan 2026 21:18:51 +0100 Subject: [PATCH 1530/3801] Change `repr(packed)` struct to `repr(C, packed)` `repr(packed)` structs do not have a well-defined layout --- library/stdarch/crates/core_arch/src/x86_64/amx.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/stdarch/crates/core_arch/src/x86_64/amx.rs b/library/stdarch/crates/core_arch/src/x86_64/amx.rs index 3e0ac8f47cea..f372f7066d51 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/amx.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/amx.rs @@ -510,7 +510,7 @@ mod tests { use syscalls::{Sysno, syscall}; #[allow(non_camel_case_types)] - #[repr(packed)] + #[repr(C, packed)] #[derive(Copy, Clone, Default, Debug, PartialEq)] struct __tilecfg { /// 0 `or` 1 From 3114decb04b1f4d8edb46a513df2f948ded778d2 Mon Sep 17 00:00:00 2001 From: benodiwal Date: Sat, 3 Jan 2026 01:58:48 +0530 Subject: [PATCH 1531/3801] fix: add location links for type, const, and lifetime parameters in inlay hints --- .../crates/hir-ty/src/display.rs | 4 + .../crates/ide/src/inlay_hints/bind_pat.rs | 92 ++++++++++++++++++- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 4f9406908ffd..43b428c3fa51 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -692,7 +692,9 @@ impl<'db> HirDisplay<'db> for Const<'db> { ConstKind::Param(param) => { let generics = generics(f.db, param.id.parent()); let param_data = &generics[param.id.local_id()]; + f.start_location_link_generic(param.id.into()); write!(f, "{}", param_data.name().unwrap().display(f.db, f.edition()))?; + f.end_location_link(); Ok(()) } ConstKind::Value(const_bytes) => render_const_scalar( @@ -2041,7 +2043,9 @@ impl<'db> HirDisplay<'db> for Region<'db> { RegionKind::ReEarlyParam(param) => { let generics = generics(f.db, param.id.parent); let param_data = &generics[param.id.local_id]; + f.start_location_link_generic(param.id.into()); write!(f, "{}", param_data.name.display(f.db, f.edition()))?; + f.end_location_link(); Ok(()) } RegionKind::ReBound(BoundVarIndexKind::Bound(db), idx) => { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index 79cc2bdf8f7b..c74e3104c14e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -1258,7 +1258,7 @@ where } #[test] - fn generic_param_inlay_hint_has_location_link() { + fn type_param_inlay_hint_has_location_link() { check_expect( InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG }, r#" @@ -1292,4 +1292,94 @@ fn identity(t: T) -> T { "#]], ); } + + #[test] + fn const_param_inlay_hint_has_location_link() { + check_expect( + InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG }, + r#" +fn f() { + let x = [0; N]; +} +"#, + expect![[r#" + [ + ( + 33..34, + [ + "[i32; ", + InlayHintLabelPart { + text: "N", + linked_location: Some( + Computed( + FileRangeWrapper { + file_id: FileId( + 0, + ), + range: 11..12, + }, + ), + ), + tooltip: "", + }, + "]", + ], + ), + ] + "#]], + ); + } + + #[test] + fn lifetime_param_inlay_hint_has_location_link() { + check_expect( + InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG }, + r#" +struct S<'lt>(*mut &'lt ()); + +fn f<'a>() { + let x = S::<'a>(loop {}); +} +"#, + expect![[r#" + [ + ( + 51..52, + [ + InlayHintLabelPart { + text: "S", + linked_location: Some( + Computed( + FileRangeWrapper { + file_id: FileId( + 0, + ), + range: 7..8, + }, + ), + ), + tooltip: "", + }, + "<", + InlayHintLabelPart { + text: "'a", + linked_location: Some( + Computed( + FileRangeWrapper { + file_id: FileId( + 0, + ), + range: 35..37, + }, + ), + ), + tooltip: "", + }, + ">", + ], + ), + ] + "#]], + ); + } } From cecc26bf3efb41f27140bdd74f58e71a87a24ec6 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 2 Jan 2026 22:55:05 +0200 Subject: [PATCH 1532/3801] Refactor libc-fs-symlink tests to use errno_result --- .../tests/pass-dep/libc/libc-fs-symlink.rs | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs index fd7fc801dc28..52a0d978963e 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs-symlink.rs @@ -4,11 +4,14 @@ //@compile-flags: -Zmiri-disable-isolation use std::ffi::CString; -use std::io::{Error, ErrorKind}; +use std::io::ErrorKind; use std::os::unix::ffi::OsStrExt; +#[path = "../../utils/libc.rs"] +mod libc_utils; #[path = "../../utils/mod.rs"] mod utils; +use libc_utils::errno_result; fn main() { test_readlink(); @@ -31,44 +34,48 @@ fn test_readlink() { // Make the buf one byte larger than it needs to be, // and check that the last byte is not overwritten. let mut large_buf = vec![0xFF; expected_path.len() + 1]; - let res = - unsafe { libc::readlink(symlink_c_ptr, large_buf.as_mut_ptr().cast(), large_buf.len()) }; + let res = errno_result(unsafe { + libc::readlink(symlink_c_ptr, large_buf.as_mut_ptr().cast(), large_buf.len()) + }) + .unwrap(); // Check that the resolved path was properly written into the buf. assert_eq!(&large_buf[..(large_buf.len() - 1)], expected_path); assert_eq!(large_buf.last(), Some(&0xFF)); - assert_eq!(res, large_buf.len() as isize - 1); + assert_eq!(res, (large_buf.len() - 1) as isize); // Test that the resolved path is truncated if the provided buffer // is too small. let mut small_buf = [0u8; 2]; - let res = - unsafe { libc::readlink(symlink_c_ptr, small_buf.as_mut_ptr().cast(), small_buf.len()) }; + let res = errno_result(unsafe { + libc::readlink(symlink_c_ptr, small_buf.as_mut_ptr().cast(), small_buf.len()) + }) + .unwrap(); assert_eq!(small_buf, &expected_path[..small_buf.len()]); assert_eq!(res, small_buf.len() as isize); // Test that we report a proper error for a missing path. - let res = unsafe { + let err = errno_result(unsafe { libc::readlink( c"MIRI_MISSING_FILE_NAME".as_ptr(), small_buf.as_mut_ptr().cast(), small_buf.len(), ) - }; - assert_eq!(res, -1); - assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound); + }) + .unwrap_err(); + assert_eq!(err.kind(), ErrorKind::NotFound); } fn test_nofollow_symlink() { - let bytes = b"Hello, World!\n"; - let path = utils::prepare_with_content("test_nofollow_symlink_target.txt", bytes); + let path = utils::prepare_with_content("test_nofollow_symlink_target.txt", b"Hello, World!\n"); let symlink_path = utils::prepare("test_nofollow_symlink.txt"); std::os::unix::fs::symlink(&path, &symlink_path).unwrap(); let symlink_cpath = CString::new(symlink_path.as_os_str().as_bytes()).unwrap(); - let ret = unsafe { libc::open(symlink_cpath.as_ptr(), libc::O_NOFOLLOW | libc::O_CLOEXEC) }; - assert_eq!(ret, -1); - let err = Error::last_os_error().raw_os_error().unwrap(); - assert_eq!(err, libc::ELOOP); + let err = errno_result(unsafe { + libc::open(symlink_cpath.as_ptr(), libc::O_NOFOLLOW | libc::O_CLOEXEC) + }) + .unwrap_err(); + assert_eq!(err.raw_os_error(), Some(libc::ELOOP)); } From 69c7a7e40509575840cba379c32dd4d8b216519b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Thu, 1 Jan 2026 22:47:41 +0100 Subject: [PATCH 1533/3801] Use a generic type to implement SIMD types in `core_arch::simd` This allows the `types` macro to easily implement `From>` and `Into>` --- library/stdarch/crates/core_arch/rustfmt.toml | 3 - library/stdarch/crates/core_arch/src/lib.rs | 5 +- .../stdarch/crates/core_arch/src/macros.rs | 16 + .../crates/core_arch/src/powerpc/altivec.rs | 2 - .../crates/core_arch/src/powerpc/macros.rs | 20 -- .../crates/core_arch/src/s390x/macros.rs | 20 -- .../crates/core_arch/src/s390x/vector.rs | 2 - library/stdarch/crates/core_arch/src/simd.rs | 306 ++++++++++++------ 8 files changed, 219 insertions(+), 155 deletions(-) diff --git a/library/stdarch/crates/core_arch/rustfmt.toml b/library/stdarch/crates/core_arch/rustfmt.toml index 4ae742ba8d50..e69de29bb2d1 100644 --- a/library/stdarch/crates/core_arch/rustfmt.toml +++ b/library/stdarch/crates/core_arch/rustfmt.toml @@ -1,3 +0,0 @@ -ignore = [ - "src/simd.rs", -] diff --git a/library/stdarch/crates/core_arch/src/lib.rs b/library/stdarch/crates/core_arch/src/lib.rs index 5bedefe42d6e..d69089b95b0c 100644 --- a/library/stdarch/crates/core_arch/src/lib.rs +++ b/library/stdarch/crates/core_arch/src/lib.rs @@ -37,7 +37,8 @@ avx10_target_feature, const_trait_impl, const_cmp, - const_eval_select + const_eval_select, + maybe_uninit_as_bytes )] #![cfg_attr(test, feature(test, abi_vectorcall, stdarch_internal))] #![deny(clippy::missing_inline_in_public_items)] @@ -87,4 +88,4 @@ pub mod arch { } #[allow(unused_imports)] -use core::{array, convert, ffi, fmt, hint, intrinsics, marker, mem, ops, ptr, sync}; +use core::{array, cmp, convert, ffi, fmt, hint, intrinsics, marker, mem, ops, ptr, sync}; diff --git a/library/stdarch/crates/core_arch/src/macros.rs b/library/stdarch/crates/core_arch/src/macros.rs index 1030d7e9740a..849297b1fc36 100644 --- a/library/stdarch/crates/core_arch/src/macros.rs +++ b/library/stdarch/crates/core_arch/src/macros.rs @@ -135,6 +135,22 @@ macro_rules! types { crate::core_arch::simd::debug_simd_finish(f, stringify!($name), self.as_array()) } } + + $(#[$stability])+ + impl crate::convert::From> for $name { + #[inline(always)] + fn from(simd: crate::core_arch::simd::Simd<$elem_type, $len>) -> Self { + unsafe { crate::mem::transmute(simd) } + } + } + + $(#[$stability])+ + impl crate::convert::From<$name> for crate::core_arch::simd::Simd<$elem_type, $len> { + #[inline(always)] + fn from(simd: $name) -> Self { + unsafe { crate::mem::transmute(simd) } + } + } )*); } diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs index a7bbf35ed8d0..37b557c3b2af 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs @@ -364,8 +364,6 @@ unsafe extern "C" { fn vrfin(a: vector_float) -> vector_float; } -impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, f32x4 } - impl_neg! { i8x16 : 0 } impl_neg! { i16x8 : 0 } impl_neg! { i32x4 : 0 } diff --git a/library/stdarch/crates/core_arch/src/powerpc/macros.rs b/library/stdarch/crates/core_arch/src/powerpc/macros.rs index 24d86f1018c8..6097ca31adc9 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/macros.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/macros.rs @@ -274,25 +274,6 @@ macro_rules! t_b { }; } -macro_rules! impl_from { - ($s: ident) => { - #[unstable(feature = "stdarch_powerpc", issue = "111145")] - impl From<$s> for s_t_l!($s) { - #[inline] - fn from (v: $s) -> Self { - unsafe { - transmute(v) - } - } - } - }; - ($($s: ident),*) => { - $( - impl_from! { $s } - )* - }; -} - macro_rules! impl_neg { ($s: ident : $zero: expr) => { #[unstable(feature = "stdarch_powerpc", issue = "111145")] @@ -306,7 +287,6 @@ macro_rules! impl_neg { }; } -pub(crate) use impl_from; pub(crate) use impl_neg; pub(crate) use impl_vec_trait; pub(crate) use s_t_l; diff --git a/library/stdarch/crates/core_arch/src/s390x/macros.rs b/library/stdarch/crates/core_arch/src/s390x/macros.rs index 26afbaa45a74..b72560396c43 100644 --- a/library/stdarch/crates/core_arch/src/s390x/macros.rs +++ b/library/stdarch/crates/core_arch/src/s390x/macros.rs @@ -431,25 +431,6 @@ macro_rules! t_b { }; } -macro_rules! impl_from { - ($s: ident) => { - #[unstable(feature = "stdarch_s390x", issue = "135681")] - impl From<$s> for s_t_l!($s) { - #[inline] - fn from (v: $s) -> Self { - unsafe { - transmute(v) - } - } - } - }; - ($($s: ident),*) => { - $( - impl_from! { $s } - )* - }; -} - macro_rules! impl_neg { ($s: ident : $zero: expr) => { #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -463,7 +444,6 @@ macro_rules! impl_neg { }; } -pub(crate) use impl_from; pub(crate) use impl_neg; pub(crate) use impl_vec_trait; pub(crate) use l_t_t; diff --git a/library/stdarch/crates/core_arch/src/s390x/vector.rs b/library/stdarch/crates/core_arch/src/s390x/vector.rs index 1366b5c78273..d63f37eeb9a8 100644 --- a/library/stdarch/crates/core_arch/src/s390x/vector.rs +++ b/library/stdarch/crates/core_arch/src/s390x/vector.rs @@ -283,8 +283,6 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vfenezfs"] fn vfenezfs(a: i32x4, b: i32x4) -> PackedTuple; } -impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } - impl_neg! { i8x16 : 0 } impl_neg! { i16x8 : 0 } impl_neg! { i32x4 : 0 } diff --git a/library/stdarch/crates/core_arch/src/simd.rs b/library/stdarch/crates/core_arch/src/simd.rs index b9dbde75971d..926163ac4cad 100644 --- a/library/stdarch/crates/core_arch/src/simd.rs +++ b/library/stdarch/crates/core_arch/src/simd.rs @@ -16,129 +16,223 @@ pub(crate) const unsafe fn simd_imin(a: T, b: T) -> T { crate::intrinsics::simd::simd_select(mask, a, b) } +/// SAFETY: All bits patterns must be valid +pub(crate) unsafe trait SimdElement: + Copy + const PartialEq + crate::fmt::Debug +{ +} + +unsafe impl SimdElement for u8 {} +unsafe impl SimdElement for u16 {} +unsafe impl SimdElement for u32 {} +unsafe impl SimdElement for u64 {} + +unsafe impl SimdElement for i8 {} +unsafe impl SimdElement for i16 {} +unsafe impl SimdElement for i32 {} +unsafe impl SimdElement for i64 {} + +unsafe impl SimdElement for f16 {} +unsafe impl SimdElement for f32 {} +unsafe impl SimdElement for f64 {} + +#[repr(simd)] +#[derive(Copy)] +pub(crate) struct Simd([T; N]); + +impl Simd { + /// A value of this type where all elements are zeroed out. + // SAFETY: `T` implements `SimdElement`, so it is zeroable. + pub(crate) const ZERO: Self = unsafe { crate::mem::zeroed() }; + + #[inline(always)] + pub(crate) const fn from_array(elements: [T; N]) -> Self { + Self(elements) + } + + // FIXME: Workaround rust@60637 + #[inline(always)] + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + pub(crate) const fn splat(value: T) -> Self { + let one = Simd([value]); + // SAFETY: 0 is always in-bounds because we're shuffling + // a simd type with exactly one element. + unsafe { simd_shuffle!(one, one, [0; N]) } + } + + /// Extract the element at position `index`. + /// `index` is not a constant so this is not efficient! + /// Use for testing only. + // FIXME: Workaround rust@60637 + #[inline(always)] + pub(crate) const fn extract(&self, index: usize) -> T { + self.as_array()[index] + } + + #[inline] + pub(crate) const fn as_array(&self) -> &[T; N] { + let simd_ptr: *const Self = self; + let array_ptr: *const [T; N] = simd_ptr.cast(); + // SAFETY: We can always read the prefix of a simd type as an array. + // There might be more padding afterwards for some widths, but + // that's not a problem for reading less than that. + unsafe { &*array_ptr } + } +} + +// `#[derive(Clone)]` causes ICE "Projecting into SIMD type core_arch::simd::Simd is banned by MCP#838" +impl Clone for Simd { + #[inline] + fn clone(&self) -> Self { + *self + } +} + +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +impl const crate::cmp::PartialEq for Simd { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.as_array() == other.as_array() + } +} + +impl crate::fmt::Debug for Simd { + #[inline] + fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result { + debug_simd_finish(f, "Simd", self.as_array()) + } +} + +impl Simd { + #[inline] + pub(crate) const fn to_bits(self) -> Simd { + assert!(size_of::() == size_of::>()); + unsafe { crate::mem::transmute_copy(&self) } + } + + #[inline] + pub(crate) const fn from_bits(bits: Simd) -> Self { + assert!(size_of::() == size_of::>()); + unsafe { crate::mem::transmute_copy(&bits) } + } +} + +impl Simd { + #[inline] + pub(crate) const fn to_bits(self) -> Simd { + assert!(size_of::() == size_of::>()); + unsafe { crate::mem::transmute_copy(&self) } + } + + #[inline] + pub(crate) const fn from_bits(bits: Simd) -> Self { + assert!(size_of::() == size_of::>()); + unsafe { crate::mem::transmute_copy(&bits) } + } +} + +impl Simd { + #[inline] + pub(crate) const fn to_bits(self) -> Simd { + assert!(size_of::() == size_of::>()); + unsafe { crate::mem::transmute_copy(&self) } + } + + #[inline] + pub(crate) const fn from_bits(bits: Simd) -> Self { + assert!(size_of::() == size_of::>()); + unsafe { crate::mem::transmute_copy(&bits) } + } +} + macro_rules! simd_ty { ($id:ident [$elem_type:ty ; $len:literal]: $($param_name:ident),*) => { - #[repr(simd)] - #[derive(Copy, Clone)] - pub(crate) struct $id([$elem_type; $len]); + pub(crate) type $id = Simd<$elem_type, $len>; - #[allow(clippy::use_self)] impl $id { - /// A value of this type where all elements are zeroed out. - pub(crate) const ZERO: Self = unsafe { crate::mem::zeroed() }; - #[inline(always)] pub(crate) const fn new($($param_name: $elem_type),*) -> Self { - $id([$($param_name),*]) - } - #[inline(always)] - pub(crate) const fn from_array(elements: [$elem_type; $len]) -> Self { - $id(elements) - } - // FIXME: Workaround rust@60637 - #[inline(always)] - #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] - pub(crate) const fn splat(value: $elem_type) -> Self { - #[derive(Copy, Clone)] - #[repr(simd)] - struct JustOne([$elem_type; 1]); - let one = JustOne([value]); - // SAFETY: 0 is always in-bounds because we're shuffling - // a simd type with exactly one element. - unsafe { simd_shuffle!(one, one, [0; $len]) } - } - - /// Extract the element at position `index`. - /// `index` is not a constant so this is not efficient! - /// Use for testing only. - // FIXME: Workaround rust@60637 - #[inline(always)] - pub(crate) const fn extract(&self, index: usize) -> $elem_type { - self.as_array()[index] - } - - #[inline] - pub(crate) const fn as_array(&self) -> &[$elem_type; $len] { - let simd_ptr: *const Self = self; - let array_ptr: *const [$elem_type; $len] = simd_ptr.cast(); - // SAFETY: We can always read the prefix of a simd type as an array. - // There might be more padding afterwards for some widths, but - // that's not a problem for reading less than that. - unsafe { &*array_ptr } - } - } - - #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] - const impl core::cmp::PartialEq for $id { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.as_array() == other.as_array() - } - } - - impl core::fmt::Debug for $id { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - debug_simd_finish(f, stringify!($id), self.as_array()) + Self([$($param_name),*]) } } } } +#[repr(simd)] +#[derive(Copy)] +pub(crate) struct SimdM([T; N]); + +impl SimdM { + #[inline(always)] + const fn bool_to_internal(x: bool) -> T { + // SAFETY: `T` implements `SimdElement`, so all bit patterns are valid. + let zeros = const { unsafe { crate::mem::zeroed::() } }; + let ones = const { + // Ideally, this would be `transmute([0xFFu8; size_of::()])`, but + // `size_of::()` is not allowed to use a generic parameter there. + let mut r = crate::mem::MaybeUninit::::uninit(); + let mut i = 0; + while i < crate::mem::size_of::() { + r.as_bytes_mut()[i] = crate::mem::MaybeUninit::new(0xFF); + i += 1; + } + unsafe { r.assume_init() } + }; + [zeros, ones][x as usize] + } + + // FIXME: Workaround rust@60637 + #[inline(always)] + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + pub(crate) const fn splat(value: bool) -> Self { + let one = SimdM([Self::bool_to_internal(value)]); + // SAFETY: 0 is always in-bounds because we're shuffling + // a simd type with exactly one element. + unsafe { simd_shuffle!(one, one, [0; N]) } + } + + #[inline] + pub(crate) const fn as_array(&self) -> &[T; N] { + let simd_ptr: *const Self = self; + let array_ptr: *const [T; N] = simd_ptr.cast(); + // SAFETY: We can always read the prefix of a simd type as an array. + // There might be more padding afterwards for some widths, but + // that's not a problem for reading less than that. + unsafe { &*array_ptr } + } +} + +// `#[derive(Clone)]` causes ICE "Projecting into SIMD type core_arch::simd::SimdM is banned by MCP#838" +impl Clone for SimdM { + #[inline] + fn clone(&self) -> Self { + *self + } +} + +#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] +impl const crate::cmp::PartialEq for SimdM { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.as_array() == other.as_array() + } +} + +impl crate::fmt::Debug for SimdM { + #[inline] + fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result { + debug_simd_finish(f, "SimdM", self.as_array()) + } +} + macro_rules! simd_m_ty { ($id:ident [$elem_type:ident ; $len:literal]: $($param_name:ident),*) => { - #[repr(simd)] - #[derive(Copy, Clone)] - pub(crate) struct $id([$elem_type; $len]); + pub(crate) type $id = SimdM<$elem_type, $len>; - #[allow(clippy::use_self)] impl $id { - #[inline(always)] - const fn bool_to_internal(x: bool) -> $elem_type { - [0 as $elem_type, !(0 as $elem_type)][x as usize] - } - #[inline(always)] pub(crate) const fn new($($param_name: bool),*) -> Self { - $id([$(Self::bool_to_internal($param_name)),*]) - } - - // FIXME: Workaround rust@60637 - #[inline(always)] - #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] - pub(crate) const fn splat(value: bool) -> Self { - #[derive(Copy, Clone)] - #[repr(simd)] - struct JustOne([$elem_type; 1]); - let one = JustOne([Self::bool_to_internal(value)]); - // SAFETY: 0 is always in-bounds because we're shuffling - // a simd type with exactly one element. - unsafe { simd_shuffle!(one, one, [0; $len]) } - } - - #[inline] - pub(crate) const fn as_array(&self) -> &[$elem_type; $len] { - let simd_ptr: *const Self = self; - let array_ptr: *const [$elem_type; $len] = simd_ptr.cast(); - // SAFETY: We can always read the prefix of a simd type as an array. - // There might be more padding afterwards for some widths, but - // that's not a problem for reading less than that. - unsafe { &*array_ptr } - } - } - - #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] - const impl core::cmp::PartialEq for $id { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.as_array() == other.as_array() - } - } - - impl core::fmt::Debug for $id { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - debug_simd_finish(f, stringify!($id), self.as_array()) + Self([$(Self::bool_to_internal($param_name)),*]) } } } From dab553268a52a4f494f57e6db4feccae9e26a491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Thu, 1 Jan 2026 22:48:01 +0100 Subject: [PATCH 1534/3801] x86: avoid using `transmute` in some tests --- .../stdarch/crates/core_arch/src/x86/sse.rs | 266 +++++++++--------- .../stdarch/crates/core_arch/src/x86/sse2.rs | 38 ++- 2 files changed, 150 insertions(+), 154 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index 751f969e50c3..f167e8381d27 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -2079,7 +2079,7 @@ pub unsafe fn _mm_stream_ps(mem_addr: *mut f32, a: __m128) { #[cfg(test)] mod tests { use crate::core_arch::assert_eq_const as assert_eq; - use crate::{hint::black_box, mem::transmute, ptr}; + use crate::{hint::black_box, ptr}; use std::boxed; use stdarch_test::simd_test; @@ -2221,7 +2221,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_min_ps() { + fn test_mm_min_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_min_ps(a, b); @@ -2234,10 +2234,10 @@ mod tests { // `r1` to `a` and `r2` to `b`. let a = _mm_setr_ps(-0.0, 0.0, 0.0, 0.0); let b = _mm_setr_ps(0.0, 0.0, 0.0, 0.0); - let r1: [u8; 16] = transmute(_mm_min_ps(a, b)); - let r2: [u8; 16] = transmute(_mm_min_ps(b, a)); - let a: [u8; 16] = transmute(a); - let b: [u8; 16] = transmute(b); + let r1 = _mm_min_ps(a, b).as_f32x4().to_bits(); + let r2 = _mm_min_ps(b, a).as_f32x4().to_bits(); + let a = a.as_f32x4().to_bits(); + let b = b.as_f32x4().to_bits(); assert_eq!(r1, b); assert_eq!(r2, a); assert_ne!(a, b); // sanity check that -0.0 is actually present @@ -2252,7 +2252,7 @@ mod tests { } #[simd_test(enable = "sse")] - unsafe fn test_mm_max_ps() { + fn test_mm_max_ps() { let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0); let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0); let r = _mm_max_ps(a, b); @@ -2261,67 +2261,67 @@ mod tests { // Check SSE-specific semantics for -0.0 handling. let a = _mm_setr_ps(-0.0, 0.0, 0.0, 0.0); let b = _mm_setr_ps(0.0, 0.0, 0.0, 0.0); - let r1: [u8; 16] = transmute(_mm_max_ps(a, b)); - let r2: [u8; 16] = transmute(_mm_max_ps(b, a)); - let a: [u8; 16] = transmute(a); - let b: [u8; 16] = transmute(b); + let r1 = _mm_max_ps(a, b).as_f32x4().to_bits(); + let r2 = _mm_max_ps(b, a).as_f32x4().to_bits(); + let a = a.as_f32x4().to_bits(); + let b = b.as_f32x4().to_bits(); assert_eq!(r1, b); assert_eq!(r2, a); assert_ne!(a, b); // sanity check that -0.0 is actually present } #[simd_test(enable = "sse")] - const unsafe fn test_mm_and_ps() { - let a = transmute(u32x4::splat(0b0011)); - let b = transmute(u32x4::splat(0b0101)); + const fn test_mm_and_ps() { + let a = f32x4::from_bits(u32x4::splat(0b0011)).as_m128(); + let b = f32x4::from_bits(u32x4::splat(0b0101)).as_m128(); let r = _mm_and_ps(*black_box(&a), *black_box(&b)); - let e = transmute(u32x4::splat(0b0001)); + let e = f32x4::from_bits(u32x4::splat(0b0001)).as_m128(); assert_eq_m128(r, e); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_andnot_ps() { - let a = transmute(u32x4::splat(0b0011)); - let b = transmute(u32x4::splat(0b0101)); + const fn test_mm_andnot_ps() { + let a = f32x4::from_bits(u32x4::splat(0b0011)).as_m128(); + let b = f32x4::from_bits(u32x4::splat(0b0101)).as_m128(); let r = _mm_andnot_ps(*black_box(&a), *black_box(&b)); - let e = transmute(u32x4::splat(0b0100)); + let e = f32x4::from_bits(u32x4::splat(0b0100)).as_m128(); assert_eq_m128(r, e); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_or_ps() { - let a = transmute(u32x4::splat(0b0011)); - let b = transmute(u32x4::splat(0b0101)); + const fn test_mm_or_ps() { + let a = f32x4::from_bits(u32x4::splat(0b0011)).as_m128(); + let b = f32x4::from_bits(u32x4::splat(0b0101)).as_m128(); let r = _mm_or_ps(*black_box(&a), *black_box(&b)); - let e = transmute(u32x4::splat(0b0111)); + let e = f32x4::from_bits(u32x4::splat(0b0111)).as_m128(); assert_eq_m128(r, e); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_xor_ps() { - let a = transmute(u32x4::splat(0b0011)); - let b = transmute(u32x4::splat(0b0101)); + const fn test_mm_xor_ps() { + let a = f32x4::from_bits(u32x4::splat(0b0011)).as_m128(); + let b = f32x4::from_bits(u32x4::splat(0b0101)).as_m128(); let r = _mm_xor_ps(*black_box(&a), *black_box(&b)); - let e = transmute(u32x4::splat(0b0110)); + let e = f32x4::from_bits(u32x4::splat(0b0110)).as_m128(); assert_eq_m128(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpeq_ss() { + fn test_mm_cmpeq_ss() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(-1.0, 5.0, 6.0, 7.0); - let r: u32x4 = transmute(_mm_cmpeq_ss(a, b)); - let e: u32x4 = transmute(_mm_setr_ps(f32::from_bits(0), 2.0, 3.0, 4.0)); + let r = _mm_cmpeq_ss(a, b).as_f32x4().to_bits(); + let e = f32x4::new(f32::from_bits(0), 2.0, 3.0, 4.0).to_bits(); assert_eq!(r, e); let b2 = _mm_setr_ps(1.0, 5.0, 6.0, 7.0); - let r2: u32x4 = transmute(_mm_cmpeq_ss(a, b2)); - let e2: u32x4 = transmute(_mm_setr_ps(f32::from_bits(0xffffffff), 2.0, 3.0, 4.0)); + let r2 = _mm_cmpeq_ss(a, b2).as_f32x4().to_bits(); + let e2 = f32x4::new(f32::from_bits(0xffffffff), 2.0, 3.0, 4.0).to_bits(); assert_eq!(r2, e2); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmplt_ss() { + fn test_mm_cmplt_ss() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0); let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0); @@ -2331,21 +2331,21 @@ mod tests { let c1 = 0u32; // a.extract(0) < c.extract(0) let d1 = !0u32; // a.extract(0) < d.extract(0) - let rb: u32x4 = transmute(_mm_cmplt_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmplt_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmplt_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmplt_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmplt_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmplt_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmple_ss() { + fn test_mm_cmple_ss() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0); let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0); @@ -2355,21 +2355,21 @@ mod tests { let c1 = !0u32; // a.extract(0) <= c.extract(0) let d1 = !0u32; // a.extract(0) <= d.extract(0) - let rb: u32x4 = transmute(_mm_cmple_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmple_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmple_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmple_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmple_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmple_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpgt_ss() { + fn test_mm_cmpgt_ss() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0); let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0); @@ -2379,21 +2379,21 @@ mod tests { let c1 = 0u32; // a.extract(0) > c.extract(0) let d1 = 0u32; // a.extract(0) > d.extract(0) - let rb: u32x4 = transmute(_mm_cmpgt_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmpgt_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmpgt_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmpgt_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmpgt_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmpgt_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpge_ss() { + fn test_mm_cmpge_ss() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0); let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0); @@ -2403,21 +2403,21 @@ mod tests { let c1 = !0u32; // a.extract(0) >= c.extract(0) let d1 = 0u32; // a.extract(0) >= d.extract(0) - let rb: u32x4 = transmute(_mm_cmpge_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmpge_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmpge_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmpge_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmpge_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmpge_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpneq_ss() { + fn test_mm_cmpneq_ss() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0); let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0); @@ -2427,21 +2427,21 @@ mod tests { let c1 = 0u32; // a.extract(0) != c.extract(0) let d1 = !0u32; // a.extract(0) != d.extract(0) - let rb: u32x4 = transmute(_mm_cmpneq_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmpneq_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmpneq_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmpneq_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmpneq_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmpneq_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpnlt_ss() { + fn test_mm_cmpnlt_ss() { // TODO: this test is exactly the same as for `_mm_cmpge_ss`, but there // must be a difference. It may have to do with behavior in the // presence of NaNs (signaling or quiet). If so, we should add tests @@ -2456,21 +2456,21 @@ mod tests { let c1 = !0u32; // a.extract(0) >= c.extract(0) let d1 = 0u32; // a.extract(0) >= d.extract(0) - let rb: u32x4 = transmute(_mm_cmpnlt_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmpnlt_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmpnlt_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmpnlt_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmpnlt_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmpnlt_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpnle_ss() { + fn test_mm_cmpnle_ss() { // TODO: this test is exactly the same as for `_mm_cmpgt_ss`, but there // must be a difference. It may have to do with behavior in the // presence @@ -2485,21 +2485,21 @@ mod tests { let c1 = 0u32; // a.extract(0) > c.extract(0) let d1 = 0u32; // a.extract(0) > d.extract(0) - let rb: u32x4 = transmute(_mm_cmpnle_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmpnle_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmpnle_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmpnle_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmpnle_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmpnle_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpngt_ss() { + fn test_mm_cmpngt_ss() { // TODO: this test is exactly the same as for `_mm_cmple_ss`, but there // must be a difference. It may have to do with behavior in the // presence of NaNs (signaling or quiet). If so, we should add tests @@ -2514,21 +2514,21 @@ mod tests { let c1 = !0u32; // a.extract(0) <= c.extract(0) let d1 = !0u32; // a.extract(0) <= d.extract(0) - let rb: u32x4 = transmute(_mm_cmpngt_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmpngt_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmpngt_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmpngt_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmpngt_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmpngt_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpnge_ss() { + fn test_mm_cmpnge_ss() { // TODO: this test is exactly the same as for `_mm_cmplt_ss`, but there // must be a difference. It may have to do with behavior in the // presence of NaNs (signaling or quiet). If so, we should add tests @@ -2543,21 +2543,21 @@ mod tests { let c1 = 0u32; // a.extract(0) < c.extract(0) let d1 = !0u32; // a.extract(0) < d.extract(0) - let rb: u32x4 = transmute(_mm_cmpnge_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmpnge_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmpnge_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmpnge_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmpnge_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmpnge_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpord_ss() { + fn test_mm_cmpord_ss() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0); let c = _mm_setr_ps(NAN, 5.0, 6.0, 7.0); @@ -2567,21 +2567,21 @@ mod tests { let c1 = 0u32; // a.extract(0) ord c.extract(0) let d1 = !0u32; // a.extract(0) ord d.extract(0) - let rb: u32x4 = transmute(_mm_cmpord_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmpord_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmpord_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmpord_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmpord_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmpord_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpunord_ss() { + fn test_mm_cmpunord_ss() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0); let c = _mm_setr_ps(NAN, 5.0, 6.0, 7.0); @@ -2591,160 +2591,160 @@ mod tests { let c1 = !0u32; // a.extract(0) unord c.extract(0) let d1 = 0u32; // a.extract(0) unord d.extract(0) - let rb: u32x4 = transmute(_mm_cmpunord_ss(a, b)); - let eb: u32x4 = transmute(_mm_setr_ps(f32::from_bits(b1), 2.0, 3.0, 4.0)); + let rb = _mm_cmpunord_ss(a, b).as_f32x4().to_bits(); + let eb = f32x4::new(f32::from_bits(b1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rb, eb); - let rc: u32x4 = transmute(_mm_cmpunord_ss(a, c)); - let ec: u32x4 = transmute(_mm_setr_ps(f32::from_bits(c1), 2.0, 3.0, 4.0)); + let rc = _mm_cmpunord_ss(a, c).as_f32x4().to_bits(); + let ec = f32x4::new(f32::from_bits(c1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rc, ec); - let rd: u32x4 = transmute(_mm_cmpunord_ss(a, d)); - let ed: u32x4 = transmute(_mm_setr_ps(f32::from_bits(d1), 2.0, 3.0, 4.0)); + let rd = _mm_cmpunord_ss(a, d).as_f32x4().to_bits(); + let ed = f32x4::new(f32::from_bits(d1), 2.0, 3.0, 4.0).to_bits(); assert_eq!(rd, ed); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpeq_ps() { + fn test_mm_cmpeq_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN); let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN); let tru = !0u32; let fls = 0u32; let e = u32x4::new(fls, fls, tru, fls); - let r: u32x4 = transmute(_mm_cmpeq_ps(a, b)); + let r = _mm_cmpeq_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmplt_ps() { + fn test_mm_cmplt_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN); let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN); let tru = !0u32; let fls = 0u32; let e = u32x4::new(tru, fls, fls, fls); - let r: u32x4 = transmute(_mm_cmplt_ps(a, b)); + let r = _mm_cmplt_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmple_ps() { + fn test_mm_cmple_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, 4.0); let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN); let tru = !0u32; let fls = 0u32; let e = u32x4::new(tru, fls, tru, fls); - let r: u32x4 = transmute(_mm_cmple_ps(a, b)); + let r = _mm_cmple_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpgt_ps() { + fn test_mm_cmpgt_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN); let b = _mm_setr_ps(15.0, 20.0, 1.0, 42.0); let tru = !0u32; let fls = 0u32; let e = u32x4::new(fls, tru, fls, fls); - let r: u32x4 = transmute(_mm_cmpgt_ps(a, b)); + let r = _mm_cmpgt_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpge_ps() { + fn test_mm_cmpge_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN); let b = _mm_setr_ps(15.0, 20.0, 1.0, 42.0); let tru = !0u32; let fls = 0u32; let e = u32x4::new(fls, tru, tru, fls); - let r: u32x4 = transmute(_mm_cmpge_ps(a, b)); + let r = _mm_cmpge_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpneq_ps() { + fn test_mm_cmpneq_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN); let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN); let tru = !0u32; let fls = 0u32; let e = u32x4::new(tru, tru, fls, tru); - let r: u32x4 = transmute(_mm_cmpneq_ps(a, b)); + let r = _mm_cmpneq_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpnlt_ps() { + fn test_mm_cmpnlt_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN); let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0); let tru = !0u32; let fls = 0u32; let e = u32x4::new(fls, tru, tru, tru); - let r: u32x4 = transmute(_mm_cmpnlt_ps(a, b)); + let r = _mm_cmpnlt_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpnle_ps() { + fn test_mm_cmpnle_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN); let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0); let tru = !0u32; let fls = 0u32; let e = u32x4::new(fls, tru, fls, tru); - let r: u32x4 = transmute(_mm_cmpnle_ps(a, b)); + let r = _mm_cmpnle_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpngt_ps() { + fn test_mm_cmpngt_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN); let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0); let tru = !0u32; let fls = 0u32; let e = u32x4::new(tru, fls, tru, tru); - let r: u32x4 = transmute(_mm_cmpngt_ps(a, b)); + let r = _mm_cmpngt_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpnge_ps() { + fn test_mm_cmpnge_ps() { let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN); let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0); let tru = !0u32; let fls = 0u32; let e = u32x4::new(tru, fls, fls, tru); - let r: u32x4 = transmute(_mm_cmpnge_ps(a, b)); + let r = _mm_cmpnge_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpord_ps() { + fn test_mm_cmpord_ps() { let a = _mm_setr_ps(10.0, 50.0, NAN, NAN); let b = _mm_setr_ps(15.0, NAN, 1.0, NAN); let tru = !0u32; let fls = 0u32; let e = u32x4::new(tru, fls, fls, fls); - let r: u32x4 = transmute(_mm_cmpord_ps(a, b)); + let r = _mm_cmpord_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } #[simd_test(enable = "sse")] - unsafe fn test_mm_cmpunord_ps() { + fn test_mm_cmpunord_ps() { let a = _mm_setr_ps(10.0, 50.0, NAN, NAN); let b = _mm_setr_ps(15.0, NAN, 1.0, NAN); let tru = !0u32; let fls = 0u32; let e = u32x4::new(fls, tru, tru, tru); - let r: u32x4 = transmute(_mm_cmpunord_ps(a, b)); + let r = _mm_cmpunord_ps(a, b).as_f32x4().to_bits(); assert_eq!(r, e); } diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index d7ac00287f5e..0850d05445c6 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -3272,11 +3272,7 @@ mod tests { core_arch::{simd::*, x86::*}, hint::black_box, }; - use std::{ - boxed, f32, f64, - mem::{self, transmute}, - ptr, - }; + use std::{boxed, f32, f64, mem, ptr}; use stdarch_test::simd_test; const NAN: f64 = f64::NAN; @@ -4585,38 +4581,38 @@ mod tests { } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_and_pd() { - let a = transmute(u64x2::splat(5)); - let b = transmute(u64x2::splat(3)); + const fn test_mm_and_pd() { + let a = f64x2::from_bits(u64x2::splat(5)).as_m128d(); + let b = f64x2::from_bits(u64x2::splat(3)).as_m128d(); let r = _mm_and_pd(a, b); - let e = transmute(u64x2::splat(1)); + let e = f64x2::from_bits(u64x2::splat(1)).as_m128d(); assert_eq_m128d(r, e); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_andnot_pd() { - let a = transmute(u64x2::splat(5)); - let b = transmute(u64x2::splat(3)); + const fn test_mm_andnot_pd() { + let a = f64x2::from_bits(u64x2::splat(5)).as_m128d(); + let b = f64x2::from_bits(u64x2::splat(3)).as_m128d(); let r = _mm_andnot_pd(a, b); - let e = transmute(u64x2::splat(2)); + let e = f64x2::from_bits(u64x2::splat(2)).as_m128d(); assert_eq_m128d(r, e); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_or_pd() { - let a = transmute(u64x2::splat(5)); - let b = transmute(u64x2::splat(3)); + const fn test_mm_or_pd() { + let a = f64x2::from_bits(u64x2::splat(5)).as_m128d(); + let b = f64x2::from_bits(u64x2::splat(3)).as_m128d(); let r = _mm_or_pd(a, b); - let e = transmute(u64x2::splat(7)); + let e = f64x2::from_bits(u64x2::splat(7)).as_m128d(); assert_eq_m128d(r, e); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_xor_pd() { - let a = transmute(u64x2::splat(5)); - let b = transmute(u64x2::splat(3)); + const fn test_mm_xor_pd() { + let a = f64x2::from_bits(u64x2::splat(5)).as_m128d(); + let b = f64x2::from_bits(u64x2::splat(3)).as_m128d(); let r = _mm_xor_pd(a, b); - let e = transmute(u64x2::splat(6)); + let e = f64x2::from_bits(u64x2::splat(6)).as_m128d(); assert_eq_m128d(r, e); } From 68701ff93ad6e3168f7aa8a947b895746bfcb9bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Thu, 1 Jan 2026 22:48:34 +0100 Subject: [PATCH 1535/3801] arm_shared: avoid using `transmute` and `unsafe fn` in tests --- library/stdarch/ci/run.sh | 2 +- .../src/arm_shared/neon/load_tests.rs | 97 +- .../core_arch/src/arm_shared/neon/mod.rs | 2177 +++++++++-------- .../src/arm_shared/neon/store_tests.rs | 144 +- .../src/arm_shared/neon/table_lookup_tests.rs | 27 +- .../core_arch/src/arm_shared/test_support.rs | 8 +- .../stdarch/crates/simd-test-macro/src/lib.rs | 47 +- 7 files changed, 1409 insertions(+), 1093 deletions(-) diff --git a/library/stdarch/ci/run.sh b/library/stdarch/ci/run.sh index bb3dcf93e75d..8a0b5fa26f66 100755 --- a/library/stdarch/ci/run.sh +++ b/library/stdarch/ci/run.sh @@ -40,7 +40,7 @@ case ${TARGET} in export RUSTFLAGS="${RUSTFLAGS} -C llvm-args=-fast-isel=false" ;; armv7-*eabihf | thumbv7-*eabihf) - export RUSTFLAGS="${RUSTFLAGS} -Ctarget-feature=+neon" + export RUSTFLAGS="${RUSTFLAGS} -Ctarget-feature=+neon,+fp16" ;; amdgcn-*) export RUSTFLAGS="${RUSTFLAGS} -Ctarget-cpu=gfx1200" diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/load_tests.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/load_tests.rs index bdf511ecf881..cc821b4af202 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/load_tests.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/load_tests.rs @@ -13,194 +13,195 @@ use crate::core_arch::aarch64::*; use crate::core_arch::simd::*; use std::mem; use stdarch_test::simd_test; + #[simd_test(enable = "neon")] -unsafe fn test_vld1_s8() { +fn test_vld1_s8() { let a: [i8; 9] = [0, 1, 2, 3, 4, 5, 6, 7, 8]; let e = i8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: i8x8 = transmute(vld1_s8(a[1..].as_ptr())); + let r = unsafe { i8x8::from(vld1_s8(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_s8() { +fn test_vld1q_s8() { let a: [i8; 17] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let e = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); - let r: i8x16 = transmute(vld1q_s8(a[1..].as_ptr())); + let r = unsafe { i8x16::from(vld1q_s8(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_s16() { +fn test_vld1_s16() { let a: [i16; 5] = [0, 1, 2, 3, 4]; let e = i16x4::new(1, 2, 3, 4); - let r: i16x4 = transmute(vld1_s16(a[1..].as_ptr())); + let r = unsafe { i16x4::from(vld1_s16(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_s16() { +fn test_vld1q_s16() { let a: [i16; 9] = [0, 1, 2, 3, 4, 5, 6, 7, 8]; let e = i16x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: i16x8 = transmute(vld1q_s16(a[1..].as_ptr())); + let r = unsafe { i16x8::from(vld1q_s16(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_s32() { +fn test_vld1_s32() { let a: [i32; 3] = [0, 1, 2]; let e = i32x2::new(1, 2); - let r: i32x2 = transmute(vld1_s32(a[1..].as_ptr())); + let r = unsafe { i32x2::from(vld1_s32(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_s32() { +fn test_vld1q_s32() { let a: [i32; 5] = [0, 1, 2, 3, 4]; let e = i32x4::new(1, 2, 3, 4); - let r: i32x4 = transmute(vld1q_s32(a[1..].as_ptr())); + let r = unsafe { i32x4::from(vld1q_s32(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_s64() { +fn test_vld1_s64() { let a: [i64; 2] = [0, 1]; let e = i64x1::new(1); - let r: i64x1 = transmute(vld1_s64(a[1..].as_ptr())); + let r = unsafe { i64x1::from(vld1_s64(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_s64() { +fn test_vld1q_s64() { let a: [i64; 3] = [0, 1, 2]; let e = i64x2::new(1, 2); - let r: i64x2 = transmute(vld1q_s64(a[1..].as_ptr())); + let r = unsafe { i64x2::from(vld1q_s64(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_u8() { +fn test_vld1_u8() { let a: [u8; 9] = [0, 1, 2, 3, 4, 5, 6, 7, 8]; let e = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: u8x8 = transmute(vld1_u8(a[1..].as_ptr())); + let r = unsafe { u8x8::from(vld1_u8(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_u8() { +fn test_vld1q_u8() { let a: [u8; 17] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let e = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); - let r: u8x16 = transmute(vld1q_u8(a[1..].as_ptr())); + let r = unsafe { u8x16::from(vld1q_u8(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_u16() { +fn test_vld1_u16() { let a: [u16; 5] = [0, 1, 2, 3, 4]; let e = u16x4::new(1, 2, 3, 4); - let r: u16x4 = transmute(vld1_u16(a[1..].as_ptr())); + let r = unsafe { u16x4::from(vld1_u16(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_u16() { +fn test_vld1q_u16() { let a: [u16; 9] = [0, 1, 2, 3, 4, 5, 6, 7, 8]; let e = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: u16x8 = transmute(vld1q_u16(a[1..].as_ptr())); + let r = unsafe { u16x8::from(vld1q_u16(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_u32() { +fn test_vld1_u32() { let a: [u32; 3] = [0, 1, 2]; let e = u32x2::new(1, 2); - let r: u32x2 = transmute(vld1_u32(a[1..].as_ptr())); + let r = unsafe { u32x2::from(vld1_u32(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_u32() { +fn test_vld1q_u32() { let a: [u32; 5] = [0, 1, 2, 3, 4]; let e = u32x4::new(1, 2, 3, 4); - let r: u32x4 = transmute(vld1q_u32(a[1..].as_ptr())); + let r = unsafe { u32x4::from(vld1q_u32(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_u64() { +fn test_vld1_u64() { let a: [u64; 2] = [0, 1]; let e = u64x1::new(1); - let r: u64x1 = transmute(vld1_u64(a[1..].as_ptr())); + let r = unsafe { u64x1::from(vld1_u64(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_u64() { +fn test_vld1q_u64() { let a: [u64; 3] = [0, 1, 2]; let e = u64x2::new(1, 2); - let r: u64x2 = transmute(vld1q_u64(a[1..].as_ptr())); + let r = unsafe { u64x2::from(vld1q_u64(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_p8() { +fn test_vld1_p8() { let a: [p8; 9] = [0, 1, 2, 3, 4, 5, 6, 7, 8]; let e = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: u8x8 = transmute(vld1_p8(a[1..].as_ptr())); + let r = unsafe { u8x8::from(vld1_p8(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_p8() { +fn test_vld1q_p8() { let a: [p8; 17] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let e = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); - let r: u8x16 = transmute(vld1q_p8(a[1..].as_ptr())); + let r = unsafe { u8x16::from(vld1q_p8(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_p16() { +fn test_vld1_p16() { let a: [p16; 5] = [0, 1, 2, 3, 4]; let e = u16x4::new(1, 2, 3, 4); - let r: u16x4 = transmute(vld1_p16(a[1..].as_ptr())); + let r = unsafe { u16x4::from(vld1_p16(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_p16() { +fn test_vld1q_p16() { let a: [p16; 9] = [0, 1, 2, 3, 4, 5, 6, 7, 8]; let e = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: u16x8 = transmute(vld1q_p16(a[1..].as_ptr())); + let r = unsafe { u16x8::from(vld1q_p16(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon,aes")] -unsafe fn test_vld1_p64() { +fn test_vld1_p64() { let a: [p64; 2] = [0, 1]; let e = u64x1::new(1); - let r: u64x1 = transmute(vld1_p64(a[1..].as_ptr())); + let r = unsafe { u64x1::from(vld1_p64(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon,aes")] -unsafe fn test_vld1q_p64() { +fn test_vld1q_p64() { let a: [p64; 3] = [0, 1, 2]; let e = u64x2::new(1, 2); - let r: u64x2 = transmute(vld1q_p64(a[1..].as_ptr())); + let r = unsafe { u64x2::from(vld1q_p64(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1_f32() { +fn test_vld1_f32() { let a: [f32; 3] = [0., 1., 2.]; let e = f32x2::new(1., 2.); - let r: f32x2 = transmute(vld1_f32(a[1..].as_ptr())); + let r = unsafe { f32x2::from(vld1_f32(a[1..].as_ptr())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] -unsafe fn test_vld1q_f32() { +fn test_vld1q_f32() { let a: [f32; 5] = [0., 1., 2., 3., 4.]; let e = f32x4::new(1., 2., 3., 4.); - let r: f32x4 = transmute(vld1q_f32(a[1..].as_ptr())); + let r = unsafe { f32x4::from(vld1q_f32(a[1..].as_ptr())) }; assert_eq!(r, e) } diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs index 809892e0bfd4..1ca8ce2b1395 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs @@ -1247,1268 +1247,1273 @@ mod tests { use crate::core_arch::arm::*; use crate::core_arch::arm_shared::test_support::*; use crate::core_arch::simd::*; - use std::{mem::transmute, vec::Vec}; use stdarch_test::simd_test; #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_s8() { + fn test_vld1_lane_s8() { let a = i8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let elem: i8 = 42; let e = i8x8::new(0, 1, 2, 3, 4, 5, 6, 42); - let r: i8x8 = transmute(vld1_lane_s8::<7>(&elem, transmute(a))); + let r = unsafe { i8x8::from(vld1_lane_s8::<7>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_s8() { + fn test_vld1q_lane_s8() { let a = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let elem: i8 = 42; let e = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 42); - let r: i8x16 = transmute(vld1q_lane_s8::<15>(&elem, transmute(a))); + let r = unsafe { i8x16::from(vld1q_lane_s8::<15>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_s16() { + fn test_vld1_lane_s16() { let a = i16x4::new(0, 1, 2, 3); let elem: i16 = 42; let e = i16x4::new(0, 1, 2, 42); - let r: i16x4 = transmute(vld1_lane_s16::<3>(&elem, transmute(a))); + let r = unsafe { i16x4::from(vld1_lane_s16::<3>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_s16() { + fn test_vld1q_lane_s16() { let a = i16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let elem: i16 = 42; let e = i16x8::new(0, 1, 2, 3, 4, 5, 6, 42); - let r: i16x8 = transmute(vld1q_lane_s16::<7>(&elem, transmute(a))); + let r = unsafe { i16x8::from(vld1q_lane_s16::<7>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_s32() { + fn test_vld1_lane_s32() { let a = i32x2::new(0, 1); let elem: i32 = 42; let e = i32x2::new(0, 42); - let r: i32x2 = transmute(vld1_lane_s32::<1>(&elem, transmute(a))); + let r = unsafe { i32x2::from(vld1_lane_s32::<1>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_s32() { + fn test_vld1q_lane_s32() { let a = i32x4::new(0, 1, 2, 3); let elem: i32 = 42; let e = i32x4::new(0, 1, 2, 42); - let r: i32x4 = transmute(vld1q_lane_s32::<3>(&elem, transmute(a))); + let r = unsafe { i32x4::from(vld1q_lane_s32::<3>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_s64() { + fn test_vld1_lane_s64() { let a = i64x1::new(0); let elem: i64 = 42; let e = i64x1::new(42); - let r: i64x1 = transmute(vld1_lane_s64::<0>(&elem, transmute(a))); + let r = unsafe { i64x1::from(vld1_lane_s64::<0>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_s64() { + fn test_vld1q_lane_s64() { let a = i64x2::new(0, 1); let elem: i64 = 42; let e = i64x2::new(0, 42); - let r: i64x2 = transmute(vld1q_lane_s64::<1>(&elem, transmute(a))); + let r = unsafe { i64x2::from(vld1q_lane_s64::<1>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_u8() { + fn test_vld1_lane_u8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let elem: u8 = 42; let e = u8x8::new(0, 1, 2, 3, 4, 5, 6, 42); - let r: u8x8 = transmute(vld1_lane_u8::<7>(&elem, transmute(a))); + let r = unsafe { u8x8::from(vld1_lane_u8::<7>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_u8() { + fn test_vld1q_lane_u8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let elem: u8 = 42; let e = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 42); - let r: u8x16 = transmute(vld1q_lane_u8::<15>(&elem, transmute(a))); + let r = unsafe { u8x16::from(vld1q_lane_u8::<15>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_u16() { + fn test_vld1_lane_u16() { let a = u16x4::new(0, 1, 2, 3); let elem: u16 = 42; let e = u16x4::new(0, 1, 2, 42); - let r: u16x4 = transmute(vld1_lane_u16::<3>(&elem, transmute(a))); + let r = unsafe { u16x4::from(vld1_lane_u16::<3>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_u16() { + fn test_vld1q_lane_u16() { let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let elem: u16 = 42; let e = u16x8::new(0, 1, 2, 3, 4, 5, 6, 42); - let r: u16x8 = transmute(vld1q_lane_u16::<7>(&elem, transmute(a))); + let r = unsafe { u16x8::from(vld1q_lane_u16::<7>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_u32() { + fn test_vld1_lane_u32() { let a = u32x2::new(0, 1); let elem: u32 = 42; let e = u32x2::new(0, 42); - let r: u32x2 = transmute(vld1_lane_u32::<1>(&elem, transmute(a))); + let r = unsafe { u32x2::from(vld1_lane_u32::<1>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_u32() { + fn test_vld1q_lane_u32() { let a = u32x4::new(0, 1, 2, 3); let elem: u32 = 42; let e = u32x4::new(0, 1, 2, 42); - let r: u32x4 = transmute(vld1q_lane_u32::<3>(&elem, transmute(a))); + let r = unsafe { u32x4::from(vld1q_lane_u32::<3>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_u64() { + fn test_vld1_lane_u64() { let a = u64x1::new(0); let elem: u64 = 42; let e = u64x1::new(42); - let r: u64x1 = transmute(vld1_lane_u64::<0>(&elem, transmute(a))); + let r = unsafe { u64x1::from(vld1_lane_u64::<0>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_u64() { + fn test_vld1q_lane_u64() { let a = u64x2::new(0, 1); let elem: u64 = 42; let e = u64x2::new(0, 42); - let r: u64x2 = transmute(vld1q_lane_u64::<1>(&elem, transmute(a))); + let r = unsafe { u64x2::from(vld1q_lane_u64::<1>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_p8() { + fn test_vld1_lane_p8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let elem: p8 = 42; let e = u8x8::new(0, 1, 2, 3, 4, 5, 6, 42); - let r: u8x8 = transmute(vld1_lane_p8::<7>(&elem, transmute(a))); + let r = unsafe { u8x8::from(vld1_lane_p8::<7>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_p8() { + fn test_vld1q_lane_p8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let elem: p8 = 42; let e = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 42); - let r: u8x16 = transmute(vld1q_lane_p8::<15>(&elem, transmute(a))); + let r = unsafe { u8x16::from(vld1q_lane_p8::<15>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_p16() { + fn test_vld1_lane_p16() { let a = u16x4::new(0, 1, 2, 3); let elem: p16 = 42; let e = u16x4::new(0, 1, 2, 42); - let r: u16x4 = transmute(vld1_lane_p16::<3>(&elem, transmute(a))); + let r = unsafe { u16x4::from(vld1_lane_p16::<3>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_p16() { + fn test_vld1q_lane_p16() { let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let elem: p16 = 42; let e = u16x8::new(0, 1, 2, 3, 4, 5, 6, 42); - let r: u16x8 = transmute(vld1q_lane_p16::<7>(&elem, transmute(a))); + let r = unsafe { u16x8::from(vld1q_lane_p16::<7>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1_lane_p64() { + fn test_vld1_lane_p64() { let a = u64x1::new(0); let elem: u64 = 42; let e = u64x1::new(42); - let r: u64x1 = transmute(vld1_lane_p64::<0>(&elem, transmute(a))); + let r = unsafe { u64x1::from(vld1_lane_p64::<0>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1q_lane_p64() { + fn test_vld1q_lane_p64() { let a = u64x2::new(0, 1); let elem: u64 = 42; let e = u64x2::new(0, 42); - let r: u64x2 = transmute(vld1q_lane_p64::<1>(&elem, transmute(a))); + let r = unsafe { u64x2::from(vld1q_lane_p64::<1>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_lane_f32() { + fn test_vld1_lane_f32() { let a = f32x2::new(0., 1.); let elem: f32 = 42.; let e = f32x2::new(0., 42.); - let r: f32x2 = transmute(vld1_lane_f32::<1>(&elem, transmute(a))); + let r = unsafe { f32x2::from(vld1_lane_f32::<1>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_lane_f32() { + fn test_vld1q_lane_f32() { let a = f32x4::new(0., 1., 2., 3.); let elem: f32 = 42.; let e = f32x4::new(0., 1., 2., 42.); - let r: f32x4 = transmute(vld1q_lane_f32::<3>(&elem, transmute(a))); + let r = unsafe { f32x4::from(vld1q_lane_f32::<3>(&elem, a.into())) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_s8() { + fn test_vld1_dup_s8() { let elem: i8 = 42; let e = i8x8::new(42, 42, 42, 42, 42, 42, 42, 42); - let r: i8x8 = transmute(vld1_dup_s8(&elem)); + let r = unsafe { i8x8::from(vld1_dup_s8(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_s8() { + fn test_vld1q_dup_s8() { let elem: i8 = 42; let e = i8x16::new( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, ); - let r: i8x16 = transmute(vld1q_dup_s8(&elem)); + let r = unsafe { i8x16::from(vld1q_dup_s8(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_s16() { + fn test_vld1_dup_s16() { let elem: i16 = 42; let e = i16x4::new(42, 42, 42, 42); - let r: i16x4 = transmute(vld1_dup_s16(&elem)); + let r = unsafe { i16x4::from(vld1_dup_s16(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_s16() { + fn test_vld1q_dup_s16() { let elem: i16 = 42; let e = i16x8::new(42, 42, 42, 42, 42, 42, 42, 42); - let r: i16x8 = transmute(vld1q_dup_s16(&elem)); + let r = unsafe { i16x8::from(vld1q_dup_s16(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_s32() { + fn test_vld1_dup_s32() { let elem: i32 = 42; let e = i32x2::new(42, 42); - let r: i32x2 = transmute(vld1_dup_s32(&elem)); + let r = unsafe { i32x2::from(vld1_dup_s32(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_s32() { + fn test_vld1q_dup_s32() { let elem: i32 = 42; let e = i32x4::new(42, 42, 42, 42); - let r: i32x4 = transmute(vld1q_dup_s32(&elem)); + let r = unsafe { i32x4::from(vld1q_dup_s32(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_s64() { + fn test_vld1_dup_s64() { let elem: i64 = 42; let e = i64x1::new(42); - let r: i64x1 = transmute(vld1_dup_s64(&elem)); + let r = unsafe { i64x1::from(vld1_dup_s64(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_s64() { + fn test_vld1q_dup_s64() { let elem: i64 = 42; let e = i64x2::new(42, 42); - let r: i64x2 = transmute(vld1q_dup_s64(&elem)); + let r = unsafe { i64x2::from(vld1q_dup_s64(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_u8() { + fn test_vld1_dup_u8() { let elem: u8 = 42; let e = u8x8::new(42, 42, 42, 42, 42, 42, 42, 42); - let r: u8x8 = transmute(vld1_dup_u8(&elem)); + let r = unsafe { u8x8::from(vld1_dup_u8(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_u8() { + fn test_vld1q_dup_u8() { let elem: u8 = 42; let e = u8x16::new( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, ); - let r: u8x16 = transmute(vld1q_dup_u8(&elem)); + let r = unsafe { u8x16::from(vld1q_dup_u8(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_u16() { + fn test_vld1_dup_u16() { let elem: u16 = 42; let e = u16x4::new(42, 42, 42, 42); - let r: u16x4 = transmute(vld1_dup_u16(&elem)); + let r = unsafe { u16x4::from(vld1_dup_u16(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_u16() { + fn test_vld1q_dup_u16() { let elem: u16 = 42; let e = u16x8::new(42, 42, 42, 42, 42, 42, 42, 42); - let r: u16x8 = transmute(vld1q_dup_u16(&elem)); + let r = unsafe { u16x8::from(vld1q_dup_u16(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_u32() { + fn test_vld1_dup_u32() { let elem: u32 = 42; let e = u32x2::new(42, 42); - let r: u32x2 = transmute(vld1_dup_u32(&elem)); + let r = unsafe { u32x2::from(vld1_dup_u32(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_u32() { + fn test_vld1q_dup_u32() { let elem: u32 = 42; let e = u32x4::new(42, 42, 42, 42); - let r: u32x4 = transmute(vld1q_dup_u32(&elem)); + let r = unsafe { u32x4::from(vld1q_dup_u32(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_u64() { + fn test_vld1_dup_u64() { let elem: u64 = 42; let e = u64x1::new(42); - let r: u64x1 = transmute(vld1_dup_u64(&elem)); + let r = unsafe { u64x1::from(vld1_dup_u64(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_u64() { + fn test_vld1q_dup_u64() { let elem: u64 = 42; let e = u64x2::new(42, 42); - let r: u64x2 = transmute(vld1q_dup_u64(&elem)); + let r = unsafe { u64x2::from(vld1q_dup_u64(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_p8() { + fn test_vld1_dup_p8() { let elem: p8 = 42; let e = u8x8::new(42, 42, 42, 42, 42, 42, 42, 42); - let r: u8x8 = transmute(vld1_dup_p8(&elem)); + let r = unsafe { u8x8::from(vld1_dup_p8(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_p8() { + fn test_vld1q_dup_p8() { let elem: p8 = 42; let e = u8x16::new( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, ); - let r: u8x16 = transmute(vld1q_dup_p8(&elem)); + let r = unsafe { u8x16::from(vld1q_dup_p8(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_p16() { + fn test_vld1_dup_p16() { let elem: p16 = 42; let e = u16x4::new(42, 42, 42, 42); - let r: u16x4 = transmute(vld1_dup_p16(&elem)); + let r = unsafe { u16x4::from(vld1_dup_p16(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_p16() { + fn test_vld1q_dup_p16() { let elem: p16 = 42; let e = u16x8::new(42, 42, 42, 42, 42, 42, 42, 42); - let r: u16x8 = transmute(vld1q_dup_p16(&elem)); + let r = unsafe { u16x8::from(vld1q_dup_p16(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1_dup_p64() { + fn test_vld1_dup_p64() { let elem: u64 = 42; let e = u64x1::new(42); - let r: u64x1 = transmute(vld1_dup_p64(&elem)); + let r = unsafe { u64x1::from(vld1_dup_p64(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon,aes")] - unsafe fn test_vld1q_dup_p64() { + fn test_vld1q_dup_p64() { let elem: u64 = 42; let e = u64x2::new(42, 42); - let r: u64x2 = transmute(vld1q_dup_p64(&elem)); + let r = unsafe { u64x2::from(vld1q_dup_p64(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1_dup_f32() { + fn test_vld1_dup_f32() { let elem: f32 = 42.; let e = f32x2::new(42., 42.); - let r: f32x2 = transmute(vld1_dup_f32(&elem)); + let r = unsafe { f32x2::from(vld1_dup_f32(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vld1q_dup_f32() { + fn test_vld1q_dup_f32() { let elem: f32 = 42.; let e = f32x4::new(42., 42., 42., 42.); - let r: f32x4 = transmute(vld1q_dup_f32(&elem)); + let r = unsafe { f32x4::from(vld1q_dup_f32(&elem)) }; assert_eq!(r, e) } #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_u8() { - let v = i8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r = vget_lane_u8::<1>(transmute(v)); + fn test_vget_lane_u8() { + let v = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); + let r = vget_lane_u8::<1>(v.into()); assert_eq!(r, 2); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_u32() { + fn test_vgetq_lane_u32() { + let v = u32x4::new(1, 2, 3, 4); + let r = vgetq_lane_u32::<1>(v.into()); + assert_eq!(r, 2); + } + + #[simd_test(enable = "neon")] + fn test_vgetq_lane_s32() { let v = i32x4::new(1, 2, 3, 4); - let r = vgetq_lane_u32::<1>(transmute(v)); + let r = vgetq_lane_s32::<1>(v.into()); assert_eq!(r, 2); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_s32() { - let v = i32x4::new(1, 2, 3, 4); - let r = vgetq_lane_s32::<1>(transmute(v)); - assert_eq!(r, 2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_u64() { - let v: u64 = 1; - let r = vget_lane_u64::<0>(transmute(v)); - assert_eq!(r, 1); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_u16() { - let v = i16x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r = vgetq_lane_u16::<1>(transmute(v)); - assert_eq!(r, 2); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_s8() { - let v = i8x8::new(0, 1, 2, 3, 4, 5, 6, 7); - let r = vget_lane_s8::<2>(transmute(v)); - assert_eq!(r, 2); - let r = vget_lane_s8::<4>(transmute(v)); - assert_eq!(r, 4); - let r = vget_lane_s8::<5>(transmute(v)); - assert_eq!(r, 5); - } - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_p8() { - let v = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); - let r = vget_lane_p8::<2>(transmute(v)); - assert_eq!(r, 2); - let r = vget_lane_p8::<3>(transmute(v)); - assert_eq!(r, 3); - let r = vget_lane_p8::<5>(transmute(v)); - assert_eq!(r, 5); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_p16() { - let v = u16x4::new(0, 1, 2, 3); - let r = vget_lane_p16::<2>(transmute(v)); - assert_eq!(r, 2); - let r = vget_lane_p16::<3>(transmute(v)); - assert_eq!(r, 3); - let r = vget_lane_p16::<0>(transmute(v)); - assert_eq!(r, 0); - let r = vget_lane_p16::<1>(transmute(v)); - assert_eq!(r, 1); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_s16() { - let v = i16x4::new(0, 1, 2, 3); - let r = vget_lane_s16::<2>(transmute(v)); - assert_eq!(r, 2); - let r = vget_lane_s16::<3>(transmute(v)); - assert_eq!(r, 3); - let r = vget_lane_s16::<0>(transmute(v)); - assert_eq!(r, 0); - let r = vget_lane_s16::<1>(transmute(v)); - assert_eq!(r, 1); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_u16() { - let v = u16x4::new(0, 1, 2, 3); - let r = vget_lane_u16::<2>(transmute(v)); - assert_eq!(r, 2); - let r = vget_lane_u16::<3>(transmute(v)); - assert_eq!(r, 3); - let r = vget_lane_u16::<0>(transmute(v)); - assert_eq!(r, 0); - let r = vget_lane_u16::<1>(transmute(v)); - assert_eq!(r, 1); - } - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_f32() { - let v = f32x2::new(0.0, 1.0); - let r = vget_lane_f32::<1>(transmute(v)); - assert_eq!(r, 1.0); - let r = vget_lane_f32::<0>(transmute(v)); - assert_eq!(r, 0.0); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_s32() { - let v = i32x2::new(0, 1); - let r = vget_lane_s32::<1>(transmute(v)); - assert_eq!(r, 1); - let r = vget_lane_s32::<0>(transmute(v)); - assert_eq!(r, 0); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_u32() { - let v = u32x2::new(0, 1); - let r = vget_lane_u32::<1>(transmute(v)); - assert_eq!(r, 1); - let r = vget_lane_u32::<0>(transmute(v)); - assert_eq!(r, 0); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_s64() { - let v = i64x1::new(1); - let r = vget_lane_s64::<0>(transmute(v)); - assert_eq!(r, 1); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vget_lane_p64() { + fn test_vget_lane_u64() { let v = u64x1::new(1); - let r = vget_lane_p64::<0>(transmute(v)); + let r = vget_lane_u64::<0>(v.into()); assert_eq!(r, 1); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_s8() { - let v = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - let r = vgetq_lane_s8::<7>(transmute(v)); - assert_eq!(r, 7); - let r = vgetq_lane_s8::<13>(transmute(v)); - assert_eq!(r, 13); - let r = vgetq_lane_s8::<3>(transmute(v)); - assert_eq!(r, 3); - let r = vgetq_lane_s8::<0>(transmute(v)); - assert_eq!(r, 0); + fn test_vgetq_lane_u16() { + let v = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); + let r = vgetq_lane_u16::<1>(v.into()); + assert_eq!(r, 2); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_p8() { - let v = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - let r = vgetq_lane_p8::<7>(transmute(v)); - assert_eq!(r, 7); - let r = vgetq_lane_p8::<13>(transmute(v)); - assert_eq!(r, 13); - let r = vgetq_lane_p8::<3>(transmute(v)); - assert_eq!(r, 3); - let r = vgetq_lane_p8::<0>(transmute(v)); - assert_eq!(r, 0); + fn test_vget_lane_s8() { + let v = i8x8::new(0, 1, 2, 3, 4, 5, 6, 7); + let r = vget_lane_s8::<2>(v.into()); + assert_eq!(r, 2); + let r = vget_lane_s8::<4>(v.into()); + assert_eq!(r, 4); + let r = vget_lane_s8::<5>(v.into()); + assert_eq!(r, 5); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_u8() { - let v = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - let r = vgetq_lane_u8::<7>(transmute(v)); - assert_eq!(r, 7); - let r = vgetq_lane_u8::<13>(transmute(v)); - assert_eq!(r, 13); - let r = vgetq_lane_u8::<3>(transmute(v)); + fn test_vget_lane_p8() { + let v = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); + let r = vget_lane_p8::<2>(v.into()); + assert_eq!(r, 2); + let r = vget_lane_p8::<3>(v.into()); assert_eq!(r, 3); - let r = vgetq_lane_u8::<0>(transmute(v)); - assert_eq!(r, 0); + let r = vget_lane_p8::<5>(v.into()); + assert_eq!(r, 5); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_s16() { - let v = i16x8::new(0, 1, 2, 3, 4, 5, 6, 7); - let r = vgetq_lane_s16::<3>(transmute(v)); + fn test_vget_lane_p16() { + let v = u16x4::new(0, 1, 2, 3); + let r = vget_lane_p16::<2>(v.into()); + assert_eq!(r, 2); + let r = vget_lane_p16::<3>(v.into()); assert_eq!(r, 3); - let r = vgetq_lane_s16::<6>(transmute(v)); - assert_eq!(r, 6); - let r = vgetq_lane_s16::<0>(transmute(v)); + let r = vget_lane_p16::<0>(v.into()); assert_eq!(r, 0); - } - - #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_p16() { - let v = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); - let r = vgetq_lane_p16::<3>(transmute(v)); - assert_eq!(r, 3); - let r = vgetq_lane_p16::<7>(transmute(v)); - assert_eq!(r, 7); - let r = vgetq_lane_p16::<1>(transmute(v)); + let r = vget_lane_p16::<1>(v.into()); assert_eq!(r, 1); } + #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_f32() { - let v = f32x4::new(0.0, 1.0, 2.0, 3.0); - let r = vgetq_lane_f32::<3>(transmute(v)); - assert_eq!(r, 3.0); - let r = vgetq_lane_f32::<0>(transmute(v)); + fn test_vget_lane_s16() { + let v = i16x4::new(0, 1, 2, 3); + let r = vget_lane_s16::<2>(v.into()); + assert_eq!(r, 2); + let r = vget_lane_s16::<3>(v.into()); + assert_eq!(r, 3); + let r = vget_lane_s16::<0>(v.into()); + assert_eq!(r, 0); + let r = vget_lane_s16::<1>(v.into()); + assert_eq!(r, 1); + } + + #[simd_test(enable = "neon")] + fn test_vget_lane_u16() { + let v = u16x4::new(0, 1, 2, 3); + let r = vget_lane_u16::<2>(v.into()); + assert_eq!(r, 2); + let r = vget_lane_u16::<3>(v.into()); + assert_eq!(r, 3); + let r = vget_lane_u16::<0>(v.into()); + assert_eq!(r, 0); + let r = vget_lane_u16::<1>(v.into()); + assert_eq!(r, 1); + } + + #[simd_test(enable = "neon")] + fn test_vget_lane_f32() { + let v = f32x2::new(0.0, 1.0); + let r = vget_lane_f32::<1>(v.into()); + assert_eq!(r, 1.0); + let r = vget_lane_f32::<0>(v.into()); assert_eq!(r, 0.0); - let r = vgetq_lane_f32::<2>(transmute(v)); + } + + #[simd_test(enable = "neon")] + fn test_vget_lane_s32() { + let v = i32x2::new(0, 1); + let r = vget_lane_s32::<1>(v.into()); + assert_eq!(r, 1); + let r = vget_lane_s32::<0>(v.into()); + assert_eq!(r, 0); + } + + #[simd_test(enable = "neon")] + fn test_vget_lane_u32() { + let v = u32x2::new(0, 1); + let r = vget_lane_u32::<1>(v.into()); + assert_eq!(r, 1); + let r = vget_lane_u32::<0>(v.into()); + assert_eq!(r, 0); + } + + #[simd_test(enable = "neon")] + fn test_vget_lane_s64() { + let v = i64x1::new(1); + let r = vget_lane_s64::<0>(v.into()); + assert_eq!(r, 1); + } + + #[simd_test(enable = "neon")] + fn test_vget_lane_p64() { + let v = u64x1::new(1); + let r = vget_lane_p64::<0>(v.into()); + assert_eq!(r, 1); + } + + #[simd_test(enable = "neon")] + fn test_vgetq_lane_s8() { + let v = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let r = vgetq_lane_s8::<7>(v.into()); + assert_eq!(r, 7); + let r = vgetq_lane_s8::<13>(v.into()); + assert_eq!(r, 13); + let r = vgetq_lane_s8::<3>(v.into()); + assert_eq!(r, 3); + let r = vgetq_lane_s8::<0>(v.into()); + assert_eq!(r, 0); + } + + #[simd_test(enable = "neon")] + fn test_vgetq_lane_p8() { + let v = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let r = vgetq_lane_p8::<7>(v.into()); + assert_eq!(r, 7); + let r = vgetq_lane_p8::<13>(v.into()); + assert_eq!(r, 13); + let r = vgetq_lane_p8::<3>(v.into()); + assert_eq!(r, 3); + let r = vgetq_lane_p8::<0>(v.into()); + assert_eq!(r, 0); + } + + #[simd_test(enable = "neon")] + fn test_vgetq_lane_u8() { + let v = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + let r = vgetq_lane_u8::<7>(v.into()); + assert_eq!(r, 7); + let r = vgetq_lane_u8::<13>(v.into()); + assert_eq!(r, 13); + let r = vgetq_lane_u8::<3>(v.into()); + assert_eq!(r, 3); + let r = vgetq_lane_u8::<0>(v.into()); + assert_eq!(r, 0); + } + + #[simd_test(enable = "neon")] + fn test_vgetq_lane_s16() { + let v = i16x8::new(0, 1, 2, 3, 4, 5, 6, 7); + let r = vgetq_lane_s16::<3>(v.into()); + assert_eq!(r, 3); + let r = vgetq_lane_s16::<6>(v.into()); + assert_eq!(r, 6); + let r = vgetq_lane_s16::<0>(v.into()); + assert_eq!(r, 0); + } + + #[simd_test(enable = "neon")] + fn test_vgetq_lane_p16() { + let v = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); + let r = vgetq_lane_p16::<3>(v.into()); + assert_eq!(r, 3); + let r = vgetq_lane_p16::<7>(v.into()); + assert_eq!(r, 7); + let r = vgetq_lane_p16::<1>(v.into()); + assert_eq!(r, 1); + } + + #[simd_test(enable = "neon")] + fn test_vgetq_lane_f32() { + let v = f32x4::new(0.0, 1.0, 2.0, 3.0); + let r = vgetq_lane_f32::<3>(v.into()); + assert_eq!(r, 3.0); + let r = vgetq_lane_f32::<0>(v.into()); + assert_eq!(r, 0.0); + let r = vgetq_lane_f32::<2>(v.into()); assert_eq!(r, 2.0); - let r = vgetq_lane_f32::<1>(transmute(v)); + let r = vgetq_lane_f32::<1>(v.into()); assert_eq!(r, 1.0); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_s64() { + fn test_vgetq_lane_s64() { let v = i64x2::new(0, 1); - let r = vgetq_lane_s64::<1>(transmute(v)); + let r = vgetq_lane_s64::<1>(v.into()); assert_eq!(r, 1); - let r = vgetq_lane_s64::<0>(transmute(v)); + let r = vgetq_lane_s64::<0>(v.into()); assert_eq!(r, 0); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_p64() { + fn test_vgetq_lane_p64() { let v = u64x2::new(0, 1); - let r = vgetq_lane_p64::<1>(transmute(v)); + let r = vgetq_lane_p64::<1>(v.into()); assert_eq!(r, 1); - let r = vgetq_lane_p64::<0>(transmute(v)); + let r = vgetq_lane_p64::<0>(v.into()); assert_eq!(r, 0); } #[simd_test(enable = "neon")] - unsafe fn test_vext_s64() { + fn test_vext_s64() { let a: i64x1 = i64x1::new(0); let b: i64x1 = i64x1::new(1); let e: i64x1 = i64x1::new(0); - let r: i64x1 = transmute(vext_s64::<0>(transmute(a), transmute(b))); + let r = unsafe { i64x1::from(vext_s64::<0>(a.into(), b.into())) }; assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vext_u64() { + fn test_vext_u64() { let a: u64x1 = u64x1::new(0); let b: u64x1 = u64x1::new(1); let e: u64x1 = u64x1::new(0); - let r: u64x1 = transmute(vext_u64::<0>(transmute(a), transmute(b))); + let r = unsafe { u64x1::from(vext_u64::<0>(a.into(), b.into())) }; assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_s8() { + fn test_vget_high_s8() { let a = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let e = i8x8::new(9, 10, 11, 12, 13, 14, 15, 16); - let r: i8x8 = transmute(vget_high_s8(transmute(a))); + let r = i8x8::from(vget_high_s8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_s16() { + fn test_vget_high_s16() { let a = i16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let e = i16x4::new(5, 6, 7, 8); - let r: i16x4 = transmute(vget_high_s16(transmute(a))); + let r = i16x4::from(vget_high_s16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_s32() { + fn test_vget_high_s32() { let a = i32x4::new(1, 2, 3, 4); let e = i32x2::new(3, 4); - let r: i32x2 = transmute(vget_high_s32(transmute(a))); + let r = i32x2::from(vget_high_s32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_s64() { + fn test_vget_high_s64() { let a = i64x2::new(1, 2); let e = i64x1::new(2); - let r: i64x1 = transmute(vget_high_s64(transmute(a))); + let r = i64x1::from(vget_high_s64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_u8() { + fn test_vget_high_u8() { let a = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let e = u8x8::new(9, 10, 11, 12, 13, 14, 15, 16); - let r: u8x8 = transmute(vget_high_u8(transmute(a))); + let r = u8x8::from(vget_high_u8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_u16() { + fn test_vget_high_u16() { let a = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let e = u16x4::new(5, 6, 7, 8); - let r: u16x4 = transmute(vget_high_u16(transmute(a))); + let r = u16x4::from(vget_high_u16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_u32() { + fn test_vget_high_u32() { let a = u32x4::new(1, 2, 3, 4); let e = u32x2::new(3, 4); - let r: u32x2 = transmute(vget_high_u32(transmute(a))); + let r = u32x2::from(vget_high_u32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_u64() { + fn test_vget_high_u64() { let a = u64x2::new(1, 2); let e = u64x1::new(2); - let r: u64x1 = transmute(vget_high_u64(transmute(a))); + let r = u64x1::from(vget_high_u64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_p8() { + fn test_vget_high_p8() { let a = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let e = u8x8::new(9, 10, 11, 12, 13, 14, 15, 16); - let r: u8x8 = transmute(vget_high_p8(transmute(a))); + let r = u8x8::from(vget_high_p8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_p16() { + fn test_vget_high_p16() { let a = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let e = u16x4::new(5, 6, 7, 8); - let r: u16x4 = transmute(vget_high_p16(transmute(a))); + let r = u16x4::from(vget_high_p16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_high_f32() { + fn test_vget_high_f32() { let a = f32x4::new(1.0, 2.0, 3.0, 4.0); let e = f32x2::new(3.0, 4.0); - let r: f32x2 = transmute(vget_high_f32(transmute(a))); + let r = f32x2::from(vget_high_f32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_s8() { + fn test_vget_low_s8() { let a = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let e = i8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: i8x8 = transmute(vget_low_s8(transmute(a))); + let r = i8x8::from(vget_low_s8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_s16() { + fn test_vget_low_s16() { let a = i16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let e = i16x4::new(1, 2, 3, 4); - let r: i16x4 = transmute(vget_low_s16(transmute(a))); + let r = i16x4::from(vget_low_s16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_s32() { + fn test_vget_low_s32() { let a = i32x4::new(1, 2, 3, 4); let e = i32x2::new(1, 2); - let r: i32x2 = transmute(vget_low_s32(transmute(a))); + let r = i32x2::from(vget_low_s32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_s64() { + fn test_vget_low_s64() { let a = i64x2::new(1, 2); let e = i64x1::new(1); - let r: i64x1 = transmute(vget_low_s64(transmute(a))); + let r = i64x1::from(vget_low_s64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_u8() { + fn test_vget_low_u8() { let a = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let e = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: u8x8 = transmute(vget_low_u8(transmute(a))); + let r = u8x8::from(vget_low_u8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_u16() { + fn test_vget_low_u16() { let a = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let e = u16x4::new(1, 2, 3, 4); - let r: u16x4 = transmute(vget_low_u16(transmute(a))); + let r = u16x4::from(vget_low_u16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_u32() { + fn test_vget_low_u32() { let a = u32x4::new(1, 2, 3, 4); let e = u32x2::new(1, 2); - let r: u32x2 = transmute(vget_low_u32(transmute(a))); + let r = u32x2::from(vget_low_u32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_u64() { + fn test_vget_low_u64() { let a = u64x2::new(1, 2); let e = u64x1::new(1); - let r: u64x1 = transmute(vget_low_u64(transmute(a))); + let r = u64x1::from(vget_low_u64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_p8() { + fn test_vget_low_p8() { let a = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let e = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: u8x8 = transmute(vget_low_p8(transmute(a))); + let r = u8x8::from(vget_low_p8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_p16() { + fn test_vget_low_p16() { let a = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let e = u16x4::new(1, 2, 3, 4); - let r: u16x4 = transmute(vget_low_p16(transmute(a))); + let r = u16x4::from(vget_low_p16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vget_low_f32() { + fn test_vget_low_f32() { let a = f32x4::new(1.0, 2.0, 3.0, 4.0); let e = f32x2::new(1.0, 2.0); - let r: f32x2 = transmute(vget_low_f32(transmute(a))); + let r = f32x2::from(vget_low_f32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_s8() { + fn test_vdupq_n_s8() { let v: i8 = 42; let e = i8x16::new( 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, ); - let r: i8x16 = transmute(vdupq_n_s8(v)); + let r = i8x16::from(vdupq_n_s8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_s16() { + fn test_vdupq_n_s16() { let v: i16 = 64; let e = i16x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: i16x8 = transmute(vdupq_n_s16(v)); + let r = i16x8::from(vdupq_n_s16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_s32() { + fn test_vdupq_n_s32() { let v: i32 = 64; let e = i32x4::new(64, 64, 64, 64); - let r: i32x4 = transmute(vdupq_n_s32(v)); + let r = i32x4::from(vdupq_n_s32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_s64() { + fn test_vdupq_n_s64() { let v: i64 = 64; let e = i64x2::new(64, 64); - let r: i64x2 = transmute(vdupq_n_s64(v)); + let r = i64x2::from(vdupq_n_s64(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_u8() { + fn test_vdupq_n_u8() { let v: u8 = 64; let e = u8x16::new( 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, ); - let r: u8x16 = transmute(vdupq_n_u8(v)); + let r = u8x16::from(vdupq_n_u8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_u16() { + fn test_vdupq_n_u16() { let v: u16 = 64; let e = u16x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: u16x8 = transmute(vdupq_n_u16(v)); + let r = u16x8::from(vdupq_n_u16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_u32() { + fn test_vdupq_n_u32() { let v: u32 = 64; let e = u32x4::new(64, 64, 64, 64); - let r: u32x4 = transmute(vdupq_n_u32(v)); + let r = u32x4::from(vdupq_n_u32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_u64() { + fn test_vdupq_n_u64() { let v: u64 = 64; let e = u64x2::new(64, 64); - let r: u64x2 = transmute(vdupq_n_u64(v)); + let r = u64x2::from(vdupq_n_u64(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_p8() { + fn test_vdupq_n_p8() { let v: p8 = 64; let e = u8x16::new( 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, ); - let r: u8x16 = transmute(vdupq_n_p8(v)); + let r = u8x16::from(vdupq_n_p8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_p16() { + fn test_vdupq_n_p16() { let v: p16 = 64; let e = u16x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: u16x8 = transmute(vdupq_n_p16(v)); + let r = u16x8::from(vdupq_n_p16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdupq_n_f32() { + fn test_vdupq_n_f32() { let v: f32 = 64.0; let e = f32x4::new(64.0, 64.0, 64.0, 64.0); - let r: f32x4 = transmute(vdupq_n_f32(v)); + let r = f32x4::from(vdupq_n_f32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_s8() { + fn test_vdup_n_s8() { let v: i8 = 64; let e = i8x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: i8x8 = transmute(vdup_n_s8(v)); + let r = i8x8::from(vdup_n_s8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_s16() { + fn test_vdup_n_s16() { let v: i16 = 64; let e = i16x4::new(64, 64, 64, 64); - let r: i16x4 = transmute(vdup_n_s16(v)); + let r = i16x4::from(vdup_n_s16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_s32() { + fn test_vdup_n_s32() { let v: i32 = 64; let e = i32x2::new(64, 64); - let r: i32x2 = transmute(vdup_n_s32(v)); + let r = i32x2::from(vdup_n_s32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_s64() { + fn test_vdup_n_s64() { let v: i64 = 64; let e = i64x1::new(64); - let r: i64x1 = transmute(vdup_n_s64(v)); + let r = i64x1::from(vdup_n_s64(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_u8() { + fn test_vdup_n_u8() { let v: u8 = 64; let e = u8x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: u8x8 = transmute(vdup_n_u8(v)); + let r = u8x8::from(vdup_n_u8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_u16() { + fn test_vdup_n_u16() { let v: u16 = 64; let e = u16x4::new(64, 64, 64, 64); - let r: u16x4 = transmute(vdup_n_u16(v)); + let r = u16x4::from(vdup_n_u16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_u32() { + fn test_vdup_n_u32() { let v: u32 = 64; let e = u32x2::new(64, 64); - let r: u32x2 = transmute(vdup_n_u32(v)); + let r = u32x2::from(vdup_n_u32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_u64() { + fn test_vdup_n_u64() { let v: u64 = 64; let e = u64x1::new(64); - let r: u64x1 = transmute(vdup_n_u64(v)); + let r = u64x1::from(vdup_n_u64(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_p8() { + fn test_vdup_n_p8() { let v: p8 = 64; let e = u8x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: u8x8 = transmute(vdup_n_p8(v)); + let r = u8x8::from(vdup_n_p8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_p16() { + fn test_vdup_n_p16() { let v: p16 = 64; let e = u16x4::new(64, 64, 64, 64); - let r: u16x4 = transmute(vdup_n_p16(v)); + let r = u16x4::from(vdup_n_p16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vdup_n_f32() { + fn test_vdup_n_f32() { let v: f32 = 64.0; let e = f32x2::new(64.0, 64.0); - let r: f32x2 = transmute(vdup_n_f32(v)); + let r = f32x2::from(vdup_n_f32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vldrq_p128() { + fn test_vldrq_p128() { let v: [p128; 2] = [1, 2]; let e: p128 = 2; - let r: p128 = vldrq_p128(v[1..].as_ptr()); + let r: p128 = unsafe { vldrq_p128(v[1..].as_ptr()) }; assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vstrq_p128() { + fn test_vstrq_p128() { let v: [p128; 2] = [1, 2]; let e: p128 = 2; let mut r: p128 = 1; - vstrq_p128(&mut r, v[1]); + unsafe { + vstrq_p128(&mut r, v[1]); + } assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_s8() { + fn test_vmov_n_s8() { let v: i8 = 64; let e = i8x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: i8x8 = transmute(vmov_n_s8(v)); + let r = i8x8::from(vmov_n_s8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_s16() { + fn test_vmov_n_s16() { let v: i16 = 64; let e = i16x4::new(64, 64, 64, 64); - let r: i16x4 = transmute(vmov_n_s16(v)); + let r = i16x4::from(vmov_n_s16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_s32() { + fn test_vmov_n_s32() { let v: i32 = 64; let e = i32x2::new(64, 64); - let r: i32x2 = transmute(vmov_n_s32(v)); + let r = i32x2::from(vmov_n_s32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_s64() { + fn test_vmov_n_s64() { let v: i64 = 64; let e = i64x1::new(64); - let r: i64x1 = transmute(vmov_n_s64(v)); + let r = i64x1::from(vmov_n_s64(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_u8() { + fn test_vmov_n_u8() { let v: u8 = 64; let e = u8x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: u8x8 = transmute(vmov_n_u8(v)); + let r = u8x8::from(vmov_n_u8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_u16() { + fn test_vmov_n_u16() { let v: u16 = 64; let e = u16x4::new(64, 64, 64, 64); - let r: u16x4 = transmute(vmov_n_u16(v)); + let r = u16x4::from(vmov_n_u16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_u32() { + fn test_vmov_n_u32() { let v: u32 = 64; let e = u32x2::new(64, 64); - let r: u32x2 = transmute(vmov_n_u32(v)); + let r = u32x2::from(vmov_n_u32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_u64() { + fn test_vmov_n_u64() { let v: u64 = 64; let e = u64x1::new(64); - let r: u64x1 = transmute(vmov_n_u64(v)); + let r = u64x1::from(vmov_n_u64(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_p8() { + fn test_vmov_n_p8() { let v: p8 = 64; let e = u8x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: u8x8 = transmute(vmov_n_p8(v)); + let r = u8x8::from(vmov_n_p8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_p16() { + fn test_vmov_n_p16() { let v: p16 = 64; let e = u16x4::new(64, 64, 64, 64); - let r: u16x4 = transmute(vmov_n_p16(v)); + let r = u16x4::from(vmov_n_p16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmov_n_f32() { + fn test_vmov_n_f32() { let v: f32 = 64.0; let e = f32x2::new(64.0, 64.0); - let r: f32x2 = transmute(vmov_n_f32(v)); + let r = f32x2::from(vmov_n_f32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_s8() { + fn test_vmovq_n_s8() { let v: i8 = 64; let e = i8x16::new( 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, ); - let r: i8x16 = transmute(vmovq_n_s8(v)); + let r = i8x16::from(vmovq_n_s8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_s16() { + fn test_vmovq_n_s16() { let v: i16 = 64; let e = i16x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: i16x8 = transmute(vmovq_n_s16(v)); + let r = i16x8::from(vmovq_n_s16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_s32() { + fn test_vmovq_n_s32() { let v: i32 = 64; let e = i32x4::new(64, 64, 64, 64); - let r: i32x4 = transmute(vmovq_n_s32(v)); + let r = i32x4::from(vmovq_n_s32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_s64() { + fn test_vmovq_n_s64() { let v: i64 = 64; let e = i64x2::new(64, 64); - let r: i64x2 = transmute(vmovq_n_s64(v)); + let r = i64x2::from(vmovq_n_s64(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_u8() { + fn test_vmovq_n_u8() { let v: u8 = 64; let e = u8x16::new( 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, ); - let r: u8x16 = transmute(vmovq_n_u8(v)); + let r = u8x16::from(vmovq_n_u8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_u16() { + fn test_vmovq_n_u16() { let v: u16 = 64; let e = u16x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: u16x8 = transmute(vmovq_n_u16(v)); + let r = u16x8::from(vmovq_n_u16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_u32() { + fn test_vmovq_n_u32() { let v: u32 = 64; let e = u32x4::new(64, 64, 64, 64); - let r: u32x4 = transmute(vmovq_n_u32(v)); + let r = u32x4::from(vmovq_n_u32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_u64() { + fn test_vmovq_n_u64() { let v: u64 = 64; let e = u64x2::new(64, 64); - let r: u64x2 = transmute(vmovq_n_u64(v)); + let r = u64x2::from(vmovq_n_u64(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_p8() { + fn test_vmovq_n_p8() { let v: p8 = 64; let e = u8x16::new( 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, ); - let r: u8x16 = transmute(vmovq_n_p8(v)); + let r = u8x16::from(vmovq_n_p8(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_p16() { + fn test_vmovq_n_p16() { let v: p16 = 64; let e = u16x8::new(64, 64, 64, 64, 64, 64, 64, 64); - let r: u16x8 = transmute(vmovq_n_p16(v)); + let r = u16x8::from(vmovq_n_p16(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovq_n_f32() { + fn test_vmovq_n_f32() { let v: f32 = 64.0; let e = f32x4::new(64.0, 64.0, 64.0, 64.0); - let r: f32x4 = transmute(vmovq_n_f32(v)); + let r = f32x4::from(vmovq_n_f32(v)); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vgetq_lane_u64() { - let v = i64x2::new(1, 2); - let r = vgetq_lane_u64::<1>(transmute(v)); + fn test_vgetq_lane_u64() { + let v = u64x2::new(1, 2); + let r = vgetq_lane_u64::<1>(v.into()); assert_eq!(r, 2); } #[simd_test(enable = "neon")] - unsafe fn test_vadd_s8() { + fn test_vadd_s8() { test_ari_s8( |i, j| vadd_s8(i, j), |a: i8, b: i8| -> i8 { a.overflowing_add(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vaddq_s8() { + fn test_vaddq_s8() { testq_ari_s8( |i, j| vaddq_s8(i, j), |a: i8, b: i8| -> i8 { a.overflowing_add(b).0 }, ); } #[simd_test(enable = "neon")] - unsafe fn test_vadd_s16() { + fn test_vadd_s16() { test_ari_s16( |i, j| vadd_s16(i, j), |a: i16, b: i16| -> i16 { a.overflowing_add(b).0 }, ); } #[simd_test(enable = "neon")] - unsafe fn test_vaddq_s16() { + fn test_vaddq_s16() { testq_ari_s16( |i, j| vaddq_s16(i, j), |a: i16, b: i16| -> i16 { a.overflowing_add(b).0 }, ); } #[simd_test(enable = "neon")] - unsafe fn test_vadd_s32() { + fn test_vadd_s32() { test_ari_s32( |i, j| vadd_s32(i, j), |a: i32, b: i32| -> i32 { a.overflowing_add(b).0 }, ); } #[simd_test(enable = "neon")] - unsafe fn test_vaddq_s32() { + fn test_vaddq_s32() { testq_ari_s32( |i, j| vaddq_s32(i, j), |a: i32, b: i32| -> i32 { a.overflowing_add(b).0 }, @@ -2516,42 +2521,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vadd_u8() { + fn test_vadd_u8() { test_ari_u8( |i, j| vadd_u8(i, j), |a: u8, b: u8| -> u8 { a.overflowing_add(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vaddq_u8() { + fn test_vaddq_u8() { testq_ari_u8( |i, j| vaddq_u8(i, j), |a: u8, b: u8| -> u8 { a.overflowing_add(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vadd_u16() { + fn test_vadd_u16() { test_ari_u16( |i, j| vadd_u16(i, j), |a: u16, b: u16| -> u16 { a.overflowing_add(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vaddq_u16() { + fn test_vaddq_u16() { testq_ari_u16( |i, j| vaddq_u16(i, j), |a: u16, b: u16| -> u16 { a.overflowing_add(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vadd_u32() { + fn test_vadd_u32() { test_ari_u32( |i, j| vadd_u32(i, j), |a: u32, b: u32| -> u32 { a.overflowing_add(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vaddq_u32() { + fn test_vaddq_u32() { testq_ari_u32( |i, j| vaddq_u32(i, j), |a: u32, b: u32| -> u32 { a.overflowing_add(b).0 }, @@ -2559,142 +2569,143 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vadd_f32() { + fn test_vadd_f32() { test_ari_f32(|i, j| vadd_f32(i, j), |a: f32, b: f32| -> f32 { a + b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vaddq_f32() { + fn test_vaddq_f32() { testq_ari_f32(|i, j| vaddq_f32(i, j), |a: f32, b: f32| -> f32 { a + b }); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_s8() { + fn test_vaddl_s8() { let v = i8::MAX; let a = i8x8::new(v, v, v, v, v, v, v, v); let v = 2 * (v as i16); let e = i16x8::new(v, v, v, v, v, v, v, v); - let r: i16x8 = transmute(vaddl_s8(transmute(a), transmute(a))); + let r = i16x8::from(vaddl_s8(a.into(), a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_s16() { + fn test_vaddl_s16() { let v = i16::MAX; let a = i16x4::new(v, v, v, v); let v = 2 * (v as i32); let e = i32x4::new(v, v, v, v); - let r: i32x4 = transmute(vaddl_s16(transmute(a), transmute(a))); + let r = i32x4::from(vaddl_s16(a.into(), a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_s32() { + fn test_vaddl_s32() { let v = i32::MAX; let a = i32x2::new(v, v); let v = 2 * (v as i64); let e = i64x2::new(v, v); - let r: i64x2 = transmute(vaddl_s32(transmute(a), transmute(a))); + let r = i64x2::from(vaddl_s32(a.into(), a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_u8() { + fn test_vaddl_u8() { let v = u8::MAX; let a = u8x8::new(v, v, v, v, v, v, v, v); let v = 2 * (v as u16); let e = u16x8::new(v, v, v, v, v, v, v, v); - let r: u16x8 = transmute(vaddl_u8(transmute(a), transmute(a))); + let r = u16x8::from(vaddl_u8(a.into(), a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_u16() { + fn test_vaddl_u16() { let v = u16::MAX; let a = u16x4::new(v, v, v, v); let v = 2 * (v as u32); let e = u32x4::new(v, v, v, v); - let r: u32x4 = transmute(vaddl_u16(transmute(a), transmute(a))); + let r = u32x4::from(vaddl_u16(a.into(), a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_u32() { + fn test_vaddl_u32() { let v = u32::MAX; let a = u32x2::new(v, v); let v = 2 * (v as u64); let e = u64x2::new(v, v); - let r: u64x2 = transmute(vaddl_u32(transmute(a), transmute(a))); + let r = u64x2::from(vaddl_u32(a.into(), a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_high_s8() { + fn test_vaddl_high_s8() { let a = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let x = i8::MAX; let b = i8x16::new(x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x); let x = x as i16; let e = i16x8::new(x + 8, x + 9, x + 10, x + 11, x + 12, x + 13, x + 14, x + 15); - let r: i16x8 = transmute(vaddl_high_s8(transmute(a), transmute(b))); + let r = i16x8::from(vaddl_high_s8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_high_s16() { + fn test_vaddl_high_s16() { let a = i16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let x = i16::MAX; let b = i16x8::new(x, x, x, x, x, x, x, x); let x = x as i32; let e = i32x4::new(x + 4, x + 5, x + 6, x + 7); - let r: i32x4 = transmute(vaddl_high_s16(transmute(a), transmute(b))); + let r = i32x4::from(vaddl_high_s16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_high_s32() { + fn test_vaddl_high_s32() { let a = i32x4::new(0, 1, 2, 3); let x = i32::MAX; let b = i32x4::new(x, x, x, x); let x = x as i64; let e = i64x2::new(x + 2, x + 3); - let r: i64x2 = transmute(vaddl_high_s32(transmute(a), transmute(b))); + let r = i64x2::from(vaddl_high_s32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_high_u8() { + fn test_vaddl_high_u8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let x = u8::MAX; let b = u8x16::new(x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x); let x = x as u16; let e = u16x8::new(x + 8, x + 9, x + 10, x + 11, x + 12, x + 13, x + 14, x + 15); - let r: u16x8 = transmute(vaddl_high_u8(transmute(a), transmute(b))); + let r = u16x8::from(vaddl_high_u8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_high_u16() { + fn test_vaddl_high_u16() { let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let x = u16::MAX; let b = u16x8::new(x, x, x, x, x, x, x, x); let x = x as u32; let e = u32x4::new(x + 4, x + 5, x + 6, x + 7); - let r: u32x4 = transmute(vaddl_high_u16(transmute(a), transmute(b))); + let r = u32x4::from(vaddl_high_u16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddl_high_u32() { + fn test_vaddl_high_u32() { let a = u32x4::new(0, 1, 2, 3); let x = u32::MAX; let b = u32x4::new(x, x, x, x); let x = x as u64; let e = u64x2::new(x + 2, x + 3); - let r: u64x2 = transmute(vaddl_high_u32(transmute(a), transmute(b))); + let r = u64x2::from(vaddl_high_u32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_s8() { + fn test_vaddw_s8() { let x = i16::MAX; let a = i16x8::new(x, 1, 2, 3, 4, 5, 6, 7); let y = i8::MAX; @@ -2710,36 +2721,36 @@ mod tests { 6 + y, 7 + y, ); - let r: i16x8 = transmute(vaddw_s8(transmute(a), transmute(b))); + let r = i16x8::from(vaddw_s8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_s16() { + fn test_vaddw_s16() { let x = i32::MAX; let a = i32x4::new(x, 1, 2, 3); let y = i16::MAX; let b = i16x4::new(y, y, y, y); let y = y as i32; let e = i32x4::new(x.wrapping_add(y), 1 + y, 2 + y, 3 + y); - let r: i32x4 = transmute(vaddw_s16(transmute(a), transmute(b))); + let r = i32x4::from(vaddw_s16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_s32() { + fn test_vaddw_s32() { let x = i64::MAX; let a = i64x2::new(x, 1); let y = i32::MAX; let b = i32x2::new(y, y); let y = y as i64; let e = i64x2::new(x.wrapping_add(y), 1 + y); - let r: i64x2 = transmute(vaddw_s32(transmute(a), transmute(b))); + let r = i64x2::from(vaddw_s32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_u8() { + fn test_vaddw_u8() { let x = u16::MAX; let a = u16x8::new(x, 1, 2, 3, 4, 5, 6, 7); let y = u8::MAX; @@ -2755,36 +2766,36 @@ mod tests { 6 + y, 7 + y, ); - let r: u16x8 = transmute(vaddw_u8(transmute(a), transmute(b))); + let r = u16x8::from(vaddw_u8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_u16() { + fn test_vaddw_u16() { let x = u32::MAX; let a = u32x4::new(x, 1, 2, 3); let y = u16::MAX; let b = u16x4::new(y, y, y, y); let y = y as u32; let e = u32x4::new(x.wrapping_add(y), 1 + y, 2 + y, 3 + y); - let r: u32x4 = transmute(vaddw_u16(transmute(a), transmute(b))); + let r = u32x4::from(vaddw_u16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_u32() { + fn test_vaddw_u32() { let x = u64::MAX; let a = u64x2::new(x, 1); let y = u32::MAX; let b = u32x2::new(y, y); let y = y as u64; let e = u64x2::new(x.wrapping_add(y), 1 + y); - let r: u64x2 = transmute(vaddw_u32(transmute(a), transmute(b))); + let r = u64x2::from(vaddw_u32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_high_s8() { + fn test_vaddw_high_s8() { let x = i16::MAX; let a = i16x8::new(x, 1, 2, 3, 4, 5, 6, 7); let y = i8::MAX; @@ -2800,36 +2811,36 @@ mod tests { 6 + y, 7 + y, ); - let r: i16x8 = transmute(vaddw_high_s8(transmute(a), transmute(b))); + let r = i16x8::from(vaddw_high_s8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_high_s16() { + fn test_vaddw_high_s16() { let x = i32::MAX; let a = i32x4::new(x, 1, 2, 3); let y = i16::MAX; let b = i16x8::new(0, 0, 0, 0, y, y, y, y); let y = y as i32; let e = i32x4::new(x.wrapping_add(y), 1 + y, 2 + y, 3 + y); - let r: i32x4 = transmute(vaddw_high_s16(transmute(a), transmute(b))); + let r = i32x4::from(vaddw_high_s16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_high_s32() { + fn test_vaddw_high_s32() { let x = i64::MAX; let a = i64x2::new(x, 1); let y = i32::MAX; let b = i32x4::new(0, 0, y, y); let y = y as i64; let e = i64x2::new(x.wrapping_add(y), 1 + y); - let r: i64x2 = transmute(vaddw_high_s32(transmute(a), transmute(b))); + let r = i64x2::from(vaddw_high_s32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_high_u8() { + fn test_vaddw_high_u8() { let x = u16::MAX; let a = u16x8::new(x, 1, 2, 3, 4, 5, 6, 7); let y = u8::MAX; @@ -2845,165 +2856,165 @@ mod tests { 6 + y, 7 + y, ); - let r: u16x8 = transmute(vaddw_high_u8(transmute(a), transmute(b))); + let r = u16x8::from(vaddw_high_u8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_high_u16() { + fn test_vaddw_high_u16() { let x = u32::MAX; let a = u32x4::new(x, 1, 2, 3); let y = u16::MAX; let b = u16x8::new(0, 0, 0, 0, y, y, y, y); let y = y as u32; let e = u32x4::new(x.wrapping_add(y), 1 + y, 2 + y, 3 + y); - let r: u32x4 = transmute(vaddw_high_u16(transmute(a), transmute(b))); + let r = u32x4::from(vaddw_high_u16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vaddw_high_u32() { + fn test_vaddw_high_u32() { let x = u64::MAX; let a = u64x2::new(x, 1); let y = u32::MAX; let b = u32x4::new(0, 0, y, y); let y = y as u64; let e = u64x2::new(x.wrapping_add(y), 1 + y); - let r: u64x2 = transmute(vaddw_high_u32(transmute(a), transmute(b))); + let r = u64x2::from(vaddw_high_u32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvn_s8() { + fn test_vmvn_s8() { let a = i8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let e = i8x8::new(-1, -2, -3, -4, -5, -6, -7, -8); - let r: i8x8 = transmute(vmvn_s8(transmute(a))); + let r = i8x8::from(vmvn_s8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvnq_s8() { + fn test_vmvnq_s8() { let a = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e = i8x16::new( -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, ); - let r: i8x16 = transmute(vmvnq_s8(transmute(a))); + let r = i8x16::from(vmvnq_s8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvn_s16() { + fn test_vmvn_s16() { let a = i16x4::new(0, 1, 2, 3); let e = i16x4::new(-1, -2, -3, -4); - let r: i16x4 = transmute(vmvn_s16(transmute(a))); + let r = i16x4::from(vmvn_s16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvnq_s16() { + fn test_vmvnq_s16() { let a = i16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let e = i16x8::new(-1, -2, -3, -4, -5, -6, -7, -8); - let r: i16x8 = transmute(vmvnq_s16(transmute(a))); + let r = i16x8::from(vmvnq_s16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvn_s32() { + fn test_vmvn_s32() { let a = i32x2::new(0, 1); let e = i32x2::new(-1, -2); - let r: i32x2 = transmute(vmvn_s32(transmute(a))); + let r = i32x2::from(vmvn_s32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvnq_s32() { + fn test_vmvnq_s32() { let a = i32x4::new(0, 1, 2, 3); let e = i32x4::new(-1, -2, -3, -4); - let r: i32x4 = transmute(vmvnq_s32(transmute(a))); + let r = i32x4::from(vmvnq_s32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvn_u8() { + fn test_vmvn_u8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let e = u8x8::new(255, 254, 253, 252, 251, 250, 249, 248); - let r: u8x8 = transmute(vmvn_u8(transmute(a))); + let r = u8x8::from(vmvn_u8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvnq_u8() { + fn test_vmvnq_u8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e = u8x16::new( 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, ); - let r: u8x16 = transmute(vmvnq_u8(transmute(a))); + let r = u8x16::from(vmvnq_u8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvn_u16() { + fn test_vmvn_u16() { let a = u16x4::new(0, 1, 2, 3); let e = u16x4::new(65_535, 65_534, 65_533, 65_532); - let r: u16x4 = transmute(vmvn_u16(transmute(a))); + let r = u16x4::from(vmvn_u16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvnq_u16() { + fn test_vmvnq_u16() { let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let e = u16x8::new( 65_535, 65_534, 65_533, 65_532, 65_531, 65_530, 65_529, 65_528, ); - let r: u16x8 = transmute(vmvnq_u16(transmute(a))); + let r = u16x8::from(vmvnq_u16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvn_u32() { + fn test_vmvn_u32() { let a = u32x2::new(0, 1); let e = u32x2::new(4_294_967_295, 4_294_967_294); - let r: u32x2 = transmute(vmvn_u32(transmute(a))); + let r = u32x2::from(vmvn_u32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvnq_u32() { + fn test_vmvnq_u32() { let a = u32x4::new(0, 1, 2, 3); let e = u32x4::new(4_294_967_295, 4_294_967_294, 4_294_967_293, 4_294_967_292); - let r: u32x4 = transmute(vmvnq_u32(transmute(a))); + let r = u32x4::from(vmvnq_u32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvn_p8() { + fn test_vmvn_p8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let e = u8x8::new(255, 254, 253, 252, 251, 250, 249, 248); - let r: u8x8 = transmute(vmvn_p8(transmute(a))); + let r = u8x8::from(vmvn_p8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmvnq_p8() { + fn test_vmvnq_p8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let e = u8x16::new( 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, ); - let r: u8x16 = transmute(vmvnq_p8(transmute(a))); + let r = u8x16::from(vmvnq_p8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbic_s8() { + fn test_vbic_s8() { let a = i8x8::new(0, -1, -2, -3, -4, -5, -6, -7); let b = i8x8::new(1, 1, 1, 1, 1, 1, 1, 1); let e = i8x8::new(0, -2, -2, -4, -4, -6, -6, -8); - let r: i8x8 = transmute(vbic_s8(transmute(a), transmute(b))); + let r = i8x8::from(vbic_s8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbicq_s8() { + fn test_vbicq_s8() { let a = i8x16::new( 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, ); @@ -3011,138 +3022,138 @@ mod tests { let e = i8x16::new( 0, -2, -2, -4, -4, -6, -6, -8, -8, -10, -10, -12, -12, -14, -14, -16, ); - let r: i8x16 = transmute(vbicq_s8(transmute(a), transmute(b))); + let r = i8x16::from(vbicq_s8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbic_s16() { + fn test_vbic_s16() { let a = i16x4::new(0, -1, -2, -3); let b = i16x4::new(1, 1, 1, 1); let e = i16x4::new(0, -2, -2, -4); - let r: i16x4 = transmute(vbic_s16(transmute(a), transmute(b))); + let r = i16x4::from(vbic_s16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbicq_s16() { + fn test_vbicq_s16() { let a = i16x8::new(0, -1, -2, -3, -4, -5, -6, -7); let b = i16x8::new(1, 1, 1, 1, 1, 1, 1, 1); let e = i16x8::new(0, -2, -2, -4, -4, -6, -6, -8); - let r: i16x8 = transmute(vbicq_s16(transmute(a), transmute(b))); + let r = i16x8::from(vbicq_s16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbic_s32() { + fn test_vbic_s32() { let a = i32x2::new(0, -1); let b = i32x2::new(1, 1); let e = i32x2::new(0, -2); - let r: i32x2 = transmute(vbic_s32(transmute(a), transmute(b))); + let r = i32x2::from(vbic_s32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbicq_s32() { + fn test_vbicq_s32() { let a = i32x4::new(0, -1, -2, -3); let b = i32x4::new(1, 1, 1, 1); let e = i32x4::new(0, -2, -2, -4); - let r: i32x4 = transmute(vbicq_s32(transmute(a), transmute(b))); + let r = i32x4::from(vbicq_s32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbic_s64() { + fn test_vbic_s64() { let a = i64x1::new(-1); let b = i64x1::new(1); let e = i64x1::new(-2); - let r: i64x1 = transmute(vbic_s64(transmute(a), transmute(b))); + let r = i64x1::from(vbic_s64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbicq_s64() { + fn test_vbicq_s64() { let a = i64x2::new(0, -1); let b = i64x2::new(1, 1); let e = i64x2::new(0, -2); - let r: i64x2 = transmute(vbicq_s64(transmute(a), transmute(b))); + let r = i64x2::from(vbicq_s64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbic_u8() { + fn test_vbic_u8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let b = u8x8::new(1, 1, 1, 1, 1, 1, 1, 1); let e = u8x8::new(0, 0, 2, 2, 4, 4, 6, 6); - let r: u8x8 = transmute(vbic_u8(transmute(a), transmute(b))); + let r = u8x8::from(vbic_u8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbicq_u8() { + fn test_vbicq_u8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let b = u8x16::new(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let e = u8x16::new(0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14); - let r: u8x16 = transmute(vbicq_u8(transmute(a), transmute(b))); + let r = u8x16::from(vbicq_u8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbic_u16() { + fn test_vbic_u16() { let a = u16x4::new(0, 1, 2, 3); let b = u16x4::new(1, 1, 1, 1); let e = u16x4::new(0, 0, 2, 2); - let r: u16x4 = transmute(vbic_u16(transmute(a), transmute(b))); + let r = u16x4::from(vbic_u16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbicq_u16() { + fn test_vbicq_u16() { let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let b = u16x8::new(1, 1, 1, 1, 1, 1, 1, 1); let e = u16x8::new(0, 0, 2, 2, 4, 4, 6, 6); - let r: u16x8 = transmute(vbicq_u16(transmute(a), transmute(b))); + let r = u16x8::from(vbicq_u16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbic_u32() { + fn test_vbic_u32() { let a = u32x2::new(0, 1); let b = u32x2::new(1, 1); let e = u32x2::new(0, 0); - let r: u32x2 = transmute(vbic_u32(transmute(a), transmute(b))); + let r = u32x2::from(vbic_u32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbicq_u32() { + fn test_vbicq_u32() { let a = u32x4::new(0, 1, 2, 3); let b = u32x4::new(1, 1, 1, 1); let e = u32x4::new(0, 0, 2, 2); - let r: u32x4 = transmute(vbicq_u32(transmute(a), transmute(b))); + let r = u32x4::from(vbicq_u32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbic_u64() { + fn test_vbic_u64() { let a = u64x1::new(1); let b = u64x1::new(1); let e = u64x1::new(0); - let r: u64x1 = transmute(vbic_u64(transmute(a), transmute(b))); + let r = u64x1::from(vbic_u64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbicq_u64() { + fn test_vbicq_u64() { let a = u64x2::new(0, 1); let b = u64x2::new(1, 1); let e = u64x2::new(0, 0); - let r: u64x2 = transmute(vbicq_u64(transmute(a), transmute(b))); + let r = u64x2::from(vbicq_u64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vbsl_s8() { + fn test_vbsl_s8() { let a = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, 0, u8::MAX, 0); let b = i8x8::new( i8::MAX, @@ -3174,38 +3185,42 @@ mod tests { i8::MAX, i8::MIN, ); - let r: i8x8 = transmute(vbsl_s8(transmute(a), transmute(b), transmute(c))); + let r = i8x8::from(vbsl_s8(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_s16() { + fn test_vbsl_s16() { let a = u16x4::new(u16::MAX, 0, 1, 2); let b = i16x4::new(i16::MAX, i16::MAX, i16::MAX, i16::MAX); let c = i16x4::new(i16::MIN, i16::MIN, i16::MIN, i16::MIN); let e = i16x4::new(i16::MAX, i16::MIN, i16::MIN | 1, i16::MIN | 2); - let r: i16x4 = transmute(vbsl_s16(transmute(a), transmute(b), transmute(c))); + let r = i16x4::from(vbsl_s16(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_s32() { + fn test_vbsl_s32() { let a = u32x2::new(u32::MAX, 1); let b = i32x2::new(i32::MAX, i32::MAX); let c = i32x2::new(i32::MIN, i32::MIN); let e = i32x2::new(i32::MAX, i32::MIN | 1); - let r: i32x2 = transmute(vbsl_s32(transmute(a), transmute(b), transmute(c))); + let r = i32x2::from(vbsl_s32(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_s64() { + fn test_vbsl_s64() { let a = u64x1::new(1); let b = i64x1::new(i64::MAX); let c = i64x1::new(i64::MIN); let e = i64x1::new(i64::MIN | 1); - let r: i64x1 = transmute(vbsl_s64(transmute(a), transmute(b), transmute(c))); + let r = i64x1::from(vbsl_s64(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_u8() { + fn test_vbsl_u8() { let a = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, 0, u8::MAX, 0); let b = u8x8::new( u8::MAX, @@ -3228,47 +3243,52 @@ mod tests { u8::MIN, ); let e = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, u8::MIN, u8::MAX, u8::MIN); - let r: u8x8 = transmute(vbsl_u8(transmute(a), transmute(b), transmute(c))); + let r = u8x8::from(vbsl_u8(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_u16() { + fn test_vbsl_u16() { let a = u16x4::new(u16::MAX, 0, 1, 2); let b = u16x4::new(u16::MAX, u16::MAX, u16::MAX, u16::MAX); let c = u16x4::new(u16::MIN, u16::MIN, u16::MIN, u16::MIN); let e = u16x4::new(u16::MAX, 0, 1, 2); - let r: u16x4 = transmute(vbsl_u16(transmute(a), transmute(b), transmute(c))); + let r = u16x4::from(vbsl_u16(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_u32() { + fn test_vbsl_u32() { let a = u32x2::new(u32::MAX, 2); let b = u32x2::new(u32::MAX, u32::MAX); let c = u32x2::new(u32::MIN, u32::MIN); let e = u32x2::new(u32::MAX, 2); - let r: u32x2 = transmute(vbsl_u32(transmute(a), transmute(b), transmute(c))); + let r = u32x2::from(vbsl_u32(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_u64() { + fn test_vbsl_u64() { let a = u64x1::new(2); let b = u64x1::new(u64::MAX); let c = u64x1::new(u64::MIN); let e = u64x1::new(2); - let r: u64x1 = transmute(vbsl_u64(transmute(a), transmute(b), transmute(c))); + let r = u64x1::from(vbsl_u64(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_f32() { + fn test_vbsl_f32() { let a = u32x2::new(1, 0x80000000); let b = f32x2::new(8388609f32, -1.23f32); let c = f32x2::new(2097152f32, 2.34f32); let e = f32x2::new(2097152.25f32, -2.34f32); - let r: f32x2 = transmute(vbsl_f32(transmute(a), transmute(b), transmute(c))); + let r = f32x2::from(vbsl_f32(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_p8() { + fn test_vbsl_p8() { let a = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, 0, u8::MAX, 0); let b = u8x8::new( u8::MAX, @@ -3291,20 +3311,22 @@ mod tests { u8::MIN, ); let e = u8x8::new(u8::MAX, 1, u8::MAX, 2, u8::MAX, u8::MIN, u8::MAX, u8::MIN); - let r: u8x8 = transmute(vbsl_p8(transmute(a), transmute(b), transmute(c))); + let r = u8x8::from(vbsl_p8(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbsl_p16() { + fn test_vbsl_p16() { let a = u16x4::new(u16::MAX, 0, 1, 2); let b = u16x4::new(u16::MAX, u16::MAX, u16::MAX, u16::MAX); let c = u16x4::new(u16::MIN, u16::MIN, u16::MIN, u16::MIN); let e = u16x4::new(u16::MAX, 0, 1, 2); - let r: u16x4 = transmute(vbsl_p16(transmute(a), transmute(b), transmute(c))); + let r = u16x4::from(vbsl_p16(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_s8() { + fn test_vbslq_s8() { let a = u8x16::new( u8::MAX, 1, @@ -3377,11 +3399,12 @@ mod tests { i8::MAX, i8::MIN, ); - let r: i8x16 = transmute(vbslq_s8(transmute(a), transmute(b), transmute(c))); + let r = i8x16::from(vbslq_s8(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_s16() { + fn test_vbslq_s16() { let a = u16x8::new(u16::MAX, 1, u16::MAX, 2, u16::MAX, 0, u16::MAX, 0); let b = i16x8::new( i16::MAX, @@ -3413,29 +3436,32 @@ mod tests { i16::MAX, i16::MIN, ); - let r: i16x8 = transmute(vbslq_s16(transmute(a), transmute(b), transmute(c))); + let r = i16x8::from(vbslq_s16(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_s32() { + fn test_vbslq_s32() { let a = u32x4::new(u32::MAX, 1, u32::MAX, 2); let b = i32x4::new(i32::MAX, i32::MAX, i32::MAX, i32::MAX); let c = i32x4::new(i32::MIN, i32::MIN, i32::MIN, i32::MIN); let e = i32x4::new(i32::MAX, i32::MIN | 1, i32::MAX, i32::MIN | 2); - let r: i32x4 = transmute(vbslq_s32(transmute(a), transmute(b), transmute(c))); + let r = i32x4::from(vbslq_s32(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_s64() { + fn test_vbslq_s64() { let a = u64x2::new(u64::MAX, 1); let b = i64x2::new(i64::MAX, i64::MAX); let c = i64x2::new(i64::MIN, i64::MIN); let e = i64x2::new(i64::MAX, i64::MIN | 1); - let r: i64x2 = transmute(vbslq_s64(transmute(a), transmute(b), transmute(c))); + let r = i64x2::from(vbslq_s64(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_u8() { + fn test_vbslq_u8() { let a = u8x16::new( u8::MAX, 1, @@ -3508,11 +3534,12 @@ mod tests { u8::MAX, u8::MIN, ); - let r: u8x16 = transmute(vbslq_u8(transmute(a), transmute(b), transmute(c))); + let r = u8x16::from(vbslq_u8(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_u16() { + fn test_vbslq_u16() { let a = u16x8::new(u16::MAX, 1, u16::MAX, 2, u16::MAX, 0, u16::MAX, 0); let b = u16x8::new( u16::MAX, @@ -3544,38 +3571,42 @@ mod tests { u16::MAX, u16::MIN, ); - let r: u16x8 = transmute(vbslq_u16(transmute(a), transmute(b), transmute(c))); + let r = u16x8::from(vbslq_u16(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_u32() { + fn test_vbslq_u32() { let a = u32x4::new(u32::MAX, 1, u32::MAX, 2); let b = u32x4::new(u32::MAX, u32::MAX, u32::MAX, u32::MAX); let c = u32x4::new(u32::MIN, u32::MIN, u32::MIN, u32::MIN); let e = u32x4::new(u32::MAX, 1, u32::MAX, 2); - let r: u32x4 = transmute(vbslq_u32(transmute(a), transmute(b), transmute(c))); + let r = u32x4::from(vbslq_u32(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_u64() { + fn test_vbslq_u64() { let a = u64x2::new(u64::MAX, 1); let b = u64x2::new(u64::MAX, u64::MAX); let c = u64x2::new(u64::MIN, u64::MIN); let e = u64x2::new(u64::MAX, 1); - let r: u64x2 = transmute(vbslq_u64(transmute(a), transmute(b), transmute(c))); + let r = u64x2::from(vbslq_u64(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_f32() { + fn test_vbslq_f32() { let a = u32x4::new(u32::MAX, 0, 1, 0x80000000); let b = f32x4::new(-1.23f32, -1.23f32, 8388609f32, -1.23f32); let c = f32x4::new(2.34f32, 2.34f32, 2097152f32, 2.34f32); let e = f32x4::new(-1.23f32, 2.34f32, 2097152.25f32, -2.34f32); - let r: f32x4 = transmute(vbslq_f32(transmute(a), transmute(b), transmute(c))); + let r = f32x4::from(vbslq_f32(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_p8() { + fn test_vbslq_p8() { let a = u8x16::new( u8::MAX, 1, @@ -3648,11 +3679,12 @@ mod tests { u8::MAX, u8::MIN, ); - let r: u8x16 = transmute(vbslq_p8(transmute(a), transmute(b), transmute(c))); + let r = u8x16::from(vbslq_p8(a.into(), b.into(), c.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vbslq_p16() { + fn test_vbslq_p16() { let a = u16x8::new(u16::MAX, 1, u16::MAX, 2, u16::MAX, 0, u16::MAX, 0); let b = u16x8::new( u16::MAX, @@ -3684,21 +3716,21 @@ mod tests { u16::MAX, u16::MIN, ); - let r: u16x8 = transmute(vbslq_p16(transmute(a), transmute(b), transmute(c))); + let r = u16x8::from(vbslq_p16(a.into(), b.into(), c.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vorn_s8() { + fn test_vorn_s8() { let a = i8x8::new(0, -1, -2, -3, -4, -5, -6, -7); let b = i8x8::new(-2, -2, -2, -2, -2, -2, -2, -2); let e = i8x8::new(1, -1, -1, -3, -3, -5, -5, -7); - let r: i8x8 = transmute(vorn_s8(transmute(a), transmute(b))); + let r = i8x8::from(vorn_s8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vornq_s8() { + fn test_vornq_s8() { let a = i8x16::new( 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, ); @@ -3708,475 +3740,522 @@ mod tests { let e = i8x16::new( 1, -1, -1, -3, -3, -5, -5, -7, -7, -9, -9, -11, -11, -13, -13, -15, ); - let r: i8x16 = transmute(vornq_s8(transmute(a), transmute(b))); + let r = i8x16::from(vornq_s8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vorn_s16() { + fn test_vorn_s16() { let a = i16x4::new(0, -1, -2, -3); let b = i16x4::new(-2, -2, -2, -2); let e = i16x4::new(1, -1, -1, -3); - let r: i16x4 = transmute(vorn_s16(transmute(a), transmute(b))); + let r = i16x4::from(vorn_s16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vornq_s16() { + fn test_vornq_s16() { let a = i16x8::new(0, -1, -2, -3, -4, -5, -6, -7); let b = i16x8::new(-2, -2, -2, -2, -2, -2, -2, -2); let e = i16x8::new(1, -1, -1, -3, -3, -5, -5, -7); - let r: i16x8 = transmute(vornq_s16(transmute(a), transmute(b))); + let r = i16x8::from(vornq_s16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vorn_s32() { + fn test_vorn_s32() { let a = i32x2::new(0, -1); let b = i32x2::new(-2, -2); let e = i32x2::new(1, -1); - let r: i32x2 = transmute(vorn_s32(transmute(a), transmute(b))); + let r = i32x2::from(vorn_s32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vornq_s32() { + fn test_vornq_s32() { let a = i32x4::new(0, -1, -2, -3); let b = i32x4::new(-2, -2, -2, -2); let e = i32x4::new(1, -1, -1, -3); - let r: i32x4 = transmute(vornq_s32(transmute(a), transmute(b))); + let r = i32x4::from(vornq_s32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vorn_s64() { + fn test_vorn_s64() { let a = i64x1::new(0); let b = i64x1::new(-2); let e = i64x1::new(1); - let r: i64x1 = transmute(vorn_s64(transmute(a), transmute(b))); + let r = i64x1::from(vorn_s64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vornq_s64() { + fn test_vornq_s64() { let a = i64x2::new(0, -1); let b = i64x2::new(-2, -2); let e = i64x2::new(1, -1); - let r: i64x2 = transmute(vornq_s64(transmute(a), transmute(b))); + let r = i64x2::from(vornq_s64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vorn_u8() { + fn test_vorn_u8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let t = u8::MAX - 1; let b = u8x8::new(t, t, t, t, t, t, t, t); let e = u8x8::new(1, 1, 3, 3, 5, 5, 7, 7); - let r: u8x8 = transmute(vorn_u8(transmute(a), transmute(b))); + let r = u8x8::from(vorn_u8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vornq_u8() { + fn test_vornq_u8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let t = u8::MAX - 1; let b = u8x16::new(t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t); let e = u8x16::new(1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15); - let r: u8x16 = transmute(vornq_u8(transmute(a), transmute(b))); + let r = u8x16::from(vornq_u8(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vorn_u16() { + fn test_vorn_u16() { let a = u16x4::new(0, 1, 2, 3); let t = u16::MAX - 1; let b = u16x4::new(t, t, t, t); let e = u16x4::new(1, 1, 3, 3); - let r: u16x4 = transmute(vorn_u16(transmute(a), transmute(b))); + let r = u16x4::from(vorn_u16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vornq_u16() { + fn test_vornq_u16() { let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let t = u16::MAX - 1; let b = u16x8::new(t, t, t, t, t, t, t, t); let e = u16x8::new(1, 1, 3, 3, 5, 5, 7, 7); - let r: u16x8 = transmute(vornq_u16(transmute(a), transmute(b))); + let r = u16x8::from(vornq_u16(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vorn_u32() { + fn test_vorn_u32() { let a = u32x2::new(0, 1); let t = u32::MAX - 1; let b = u32x2::new(t, t); let e = u32x2::new(1, 1); - let r: u32x2 = transmute(vorn_u32(transmute(a), transmute(b))); + let r = u32x2::from(vorn_u32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vornq_u32() { + fn test_vornq_u32() { let a = u32x4::new(0, 1, 2, 3); let t = u32::MAX - 1; let b = u32x4::new(t, t, t, t); let e = u32x4::new(1, 1, 3, 3); - let r: u32x4 = transmute(vornq_u32(transmute(a), transmute(b))); + let r = u32x4::from(vornq_u32(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vorn_u64() { + fn test_vorn_u64() { let a = u64x1::new(0); let t = u64::MAX - 1; let b = u64x1::new(t); let e = u64x1::new(1); - let r: u64x1 = transmute(vorn_u64(transmute(a), transmute(b))); + let r = u64x1::from(vorn_u64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vornq_u64() { + fn test_vornq_u64() { let a = u64x2::new(0, 1); let t = u64::MAX - 1; let b = u64x2::new(t, t); let e = u64x2::new(1, 1); - let r: u64x2 = transmute(vornq_u64(transmute(a), transmute(b))); + let r = u64x2::from(vornq_u64(a.into(), b.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovn_s16() { + fn test_vmovn_s16() { let a = i16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let e = i8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: i8x8 = transmute(vmovn_s16(transmute(a))); + let r = i8x8::from(vmovn_s16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovn_s32() { + fn test_vmovn_s32() { let a = i32x4::new(1, 2, 3, 4); let e = i16x4::new(1, 2, 3, 4); - let r: i16x4 = transmute(vmovn_s32(transmute(a))); + let r = i16x4::from(vmovn_s32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovn_s64() { + fn test_vmovn_s64() { let a = i64x2::new(1, 2); let e = i32x2::new(1, 2); - let r: i32x2 = transmute(vmovn_s64(transmute(a))); + let r = i32x2::from(vmovn_s64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovn_u16() { + fn test_vmovn_u16() { let a = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let e = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: u8x8 = transmute(vmovn_u16(transmute(a))); + let r = u8x8::from(vmovn_u16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovn_u32() { + fn test_vmovn_u32() { let a = u32x4::new(1, 2, 3, 4); let e = u16x4::new(1, 2, 3, 4); - let r: u16x4 = transmute(vmovn_u32(transmute(a))); + let r = u16x4::from(vmovn_u32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovn_u64() { + fn test_vmovn_u64() { let a = u64x2::new(1, 2); let e = u32x2::new(1, 2); - let r: u32x2 = transmute(vmovn_u64(transmute(a))); + let r = u32x2::from(vmovn_u64(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovl_s8() { + fn test_vmovl_s8() { let e = i16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let a = i8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: i16x8 = transmute(vmovl_s8(transmute(a))); + let r = i16x8::from(vmovl_s8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovl_s16() { + fn test_vmovl_s16() { let e = i32x4::new(1, 2, 3, 4); let a = i16x4::new(1, 2, 3, 4); - let r: i32x4 = transmute(vmovl_s16(transmute(a))); + let r = i32x4::from(vmovl_s16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovl_s32() { + fn test_vmovl_s32() { let e = i64x2::new(1, 2); let a = i32x2::new(1, 2); - let r: i64x2 = transmute(vmovl_s32(transmute(a))); + let r = i64x2::from(vmovl_s32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovl_u8() { + fn test_vmovl_u8() { let e = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let a = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - let r: u16x8 = transmute(vmovl_u8(transmute(a))); + let r = u16x8::from(vmovl_u8(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovl_u16() { + fn test_vmovl_u16() { let e = u32x4::new(1, 2, 3, 4); let a = u16x4::new(1, 2, 3, 4); - let r: u32x4 = transmute(vmovl_u16(transmute(a))); + let r = u32x4::from(vmovl_u16(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vmovl_u32() { + fn test_vmovl_u32() { let e = u64x2::new(1, 2); let a = u32x2::new(1, 2); - let r: u64x2 = transmute(vmovl_u32(transmute(a))); + let r = u64x2::from(vmovl_u32(a.into())); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vand_s8() { + fn test_vand_s8() { test_bit_s8(|i, j| vand_s8(i, j), |a: i8, b: i8| -> i8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vandq_s8() { + fn test_vandq_s8() { testq_bit_s8(|i, j| vandq_s8(i, j), |a: i8, b: i8| -> i8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vand_s16() { + fn test_vand_s16() { test_bit_s16(|i, j| vand_s16(i, j), |a: i16, b: i16| -> i16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vandq_s16() { + fn test_vandq_s16() { testq_bit_s16(|i, j| vandq_s16(i, j), |a: i16, b: i16| -> i16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vand_s32() { + fn test_vand_s32() { test_bit_s32(|i, j| vand_s32(i, j), |a: i32, b: i32| -> i32 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vandq_s32() { + fn test_vandq_s32() { testq_bit_s32(|i, j| vandq_s32(i, j), |a: i32, b: i32| -> i32 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vand_s64() { + fn test_vand_s64() { test_bit_s64(|i, j| vand_s64(i, j), |a: i64, b: i64| -> i64 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vandq_s64() { + fn test_vandq_s64() { testq_bit_s64(|i, j| vandq_s64(i, j), |a: i64, b: i64| -> i64 { a & b }); } #[simd_test(enable = "neon")] - unsafe fn test_vand_u8() { + fn test_vand_u8() { test_bit_u8(|i, j| vand_u8(i, j), |a: u8, b: u8| -> u8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vandq_u8() { + fn test_vandq_u8() { testq_bit_u8(|i, j| vandq_u8(i, j), |a: u8, b: u8| -> u8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vand_u16() { + fn test_vand_u16() { test_bit_u16(|i, j| vand_u16(i, j), |a: u16, b: u16| -> u16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vandq_u16() { + fn test_vandq_u16() { testq_bit_u16(|i, j| vandq_u16(i, j), |a: u16, b: u16| -> u16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vand_u32() { + fn test_vand_u32() { test_bit_u32(|i, j| vand_u32(i, j), |a: u32, b: u32| -> u32 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vandq_u32() { + fn test_vandq_u32() { testq_bit_u32(|i, j| vandq_u32(i, j), |a: u32, b: u32| -> u32 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vand_u64() { + fn test_vand_u64() { test_bit_u64(|i, j| vand_u64(i, j), |a: u64, b: u64| -> u64 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vandq_u64() { + fn test_vandq_u64() { testq_bit_u64(|i, j| vandq_u64(i, j), |a: u64, b: u64| -> u64 { a & b }); } #[simd_test(enable = "neon")] - unsafe fn test_vorr_s8() { + fn test_vorr_s8() { test_bit_s8(|i, j| vorr_s8(i, j), |a: i8, b: i8| -> i8 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorrq_s8() { + fn test_vorrq_s8() { testq_bit_s8(|i, j| vorrq_s8(i, j), |a: i8, b: i8| -> i8 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorr_s16() { + fn test_vorr_s16() { test_bit_s16(|i, j| vorr_s16(i, j), |a: i16, b: i16| -> i16 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorrq_s16() { + fn test_vorrq_s16() { testq_bit_s16(|i, j| vorrq_s16(i, j), |a: i16, b: i16| -> i16 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorr_s32() { + fn test_vorr_s32() { test_bit_s32(|i, j| vorr_s32(i, j), |a: i32, b: i32| -> i32 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorrq_s32() { + fn test_vorrq_s32() { testq_bit_s32(|i, j| vorrq_s32(i, j), |a: i32, b: i32| -> i32 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorr_s64() { + fn test_vorr_s64() { test_bit_s64(|i, j| vorr_s64(i, j), |a: i64, b: i64| -> i64 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorrq_s64() { + fn test_vorrq_s64() { testq_bit_s64(|i, j| vorrq_s64(i, j), |a: i64, b: i64| -> i64 { a | b }); } #[simd_test(enable = "neon")] - unsafe fn test_vorr_u8() { + fn test_vorr_u8() { test_bit_u8(|i, j| vorr_u8(i, j), |a: u8, b: u8| -> u8 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorrq_u8() { + fn test_vorrq_u8() { testq_bit_u8(|i, j| vorrq_u8(i, j), |a: u8, b: u8| -> u8 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorr_u16() { + fn test_vorr_u16() { test_bit_u16(|i, j| vorr_u16(i, j), |a: u16, b: u16| -> u16 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorrq_u16() { + fn test_vorrq_u16() { testq_bit_u16(|i, j| vorrq_u16(i, j), |a: u16, b: u16| -> u16 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorr_u32() { + fn test_vorr_u32() { test_bit_u32(|i, j| vorr_u32(i, j), |a: u32, b: u32| -> u32 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorrq_u32() { + fn test_vorrq_u32() { testq_bit_u32(|i, j| vorrq_u32(i, j), |a: u32, b: u32| -> u32 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorr_u64() { + fn test_vorr_u64() { test_bit_u64(|i, j| vorr_u64(i, j), |a: u64, b: u64| -> u64 { a | b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vorrq_u64() { + fn test_vorrq_u64() { testq_bit_u64(|i, j| vorrq_u64(i, j), |a: u64, b: u64| -> u64 { a | b }); } #[simd_test(enable = "neon")] - unsafe fn test_veor_s8() { + fn test_veor_s8() { test_bit_s8(|i, j| veor_s8(i, j), |a: i8, b: i8| -> i8 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veorq_s8() { + fn test_veorq_s8() { testq_bit_s8(|i, j| veorq_s8(i, j), |a: i8, b: i8| -> i8 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veor_s16() { + fn test_veor_s16() { test_bit_s16(|i, j| veor_s16(i, j), |a: i16, b: i16| -> i16 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veorq_s16() { + fn test_veorq_s16() { testq_bit_s16(|i, j| veorq_s16(i, j), |a: i16, b: i16| -> i16 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veor_s32() { + fn test_veor_s32() { test_bit_s32(|i, j| veor_s32(i, j), |a: i32, b: i32| -> i32 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veorq_s32() { + fn test_veorq_s32() { testq_bit_s32(|i, j| veorq_s32(i, j), |a: i32, b: i32| -> i32 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veor_s64() { + fn test_veor_s64() { test_bit_s64(|i, j| veor_s64(i, j), |a: i64, b: i64| -> i64 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veorq_s64() { + fn test_veorq_s64() { testq_bit_s64(|i, j| veorq_s64(i, j), |a: i64, b: i64| -> i64 { a ^ b }); } #[simd_test(enable = "neon")] - unsafe fn test_veor_u8() { + fn test_veor_u8() { test_bit_u8(|i, j| veor_u8(i, j), |a: u8, b: u8| -> u8 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veorq_u8() { + fn test_veorq_u8() { testq_bit_u8(|i, j| veorq_u8(i, j), |a: u8, b: u8| -> u8 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veor_u16() { + fn test_veor_u16() { test_bit_u16(|i, j| veor_u16(i, j), |a: u16, b: u16| -> u16 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veorq_u16() { + fn test_veorq_u16() { testq_bit_u16(|i, j| veorq_u16(i, j), |a: u16, b: u16| -> u16 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veor_u32() { + fn test_veor_u32() { test_bit_u32(|i, j| veor_u32(i, j), |a: u32, b: u32| -> u32 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veorq_u32() { + fn test_veorq_u32() { testq_bit_u32(|i, j| veorq_u32(i, j), |a: u32, b: u32| -> u32 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veor_u64() { + fn test_veor_u64() { test_bit_u64(|i, j| veor_u64(i, j), |a: u64, b: u64| -> u64 { a ^ b }); } + #[simd_test(enable = "neon")] - unsafe fn test_veorq_u64() { + fn test_veorq_u64() { testq_bit_u64(|i, j| veorq_u64(i, j), |a: u64, b: u64| -> u64 { a ^ b }); } #[simd_test(enable = "neon")] - unsafe fn test_vceq_s8() { + fn test_vceq_s8() { test_cmp_s8( |i, j| vceq_s8(i, j), |a: i8, b: i8| -> u8 { if a == b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceqq_s8() { + fn test_vceqq_s8() { testq_cmp_s8( |i, j| vceqq_s8(i, j), |a: i8, b: i8| -> u8 { if a == b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceq_s16() { + fn test_vceq_s16() { test_cmp_s16( |i, j| vceq_s16(i, j), |a: i16, b: i16| -> u16 { if a == b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceqq_s16() { + fn test_vceqq_s16() { testq_cmp_s16( |i, j| vceqq_s16(i, j), |a: i16, b: i16| -> u16 { if a == b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceq_s32() { + fn test_vceq_s32() { test_cmp_s32( |i, j| vceq_s32(i, j), |a: i32, b: i32| -> u32 { if a == b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceqq_s32() { + fn test_vceqq_s32() { testq_cmp_s32( |i, j| vceqq_s32(i, j), |a: i32, b: i32| -> u32 { if a == b { 0xFFFFFFFF } else { 0 } }, @@ -4184,42 +4263,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vceq_u8() { + fn test_vceq_u8() { test_cmp_u8( |i, j| vceq_u8(i, j), |a: u8, b: u8| -> u8 { if a == b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceqq_u8() { + fn test_vceqq_u8() { testq_cmp_u8( |i, j| vceqq_u8(i, j), |a: u8, b: u8| -> u8 { if a == b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceq_u16() { + fn test_vceq_u16() { test_cmp_u16( |i, j| vceq_u16(i, j), |a: u16, b: u16| -> u16 { if a == b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceqq_u16() { + fn test_vceqq_u16() { testq_cmp_u16( |i, j| vceqq_u16(i, j), |a: u16, b: u16| -> u16 { if a == b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceq_u32() { + fn test_vceq_u32() { test_cmp_u32( |i, j| vceq_u32(i, j), |a: u32, b: u32| -> u32 { if a == b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceqq_u32() { + fn test_vceqq_u32() { testq_cmp_u32( |i, j| vceqq_u32(i, j), |a: u32, b: u32| -> u32 { if a == b { 0xFFFFFFFF } else { 0 } }, @@ -4227,14 +4311,15 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vceq_f32() { + fn test_vceq_f32() { test_cmp_f32( |i, j| vcge_f32(i, j), |a: f32, b: f32| -> u32 { if a == b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vceqq_f32() { + fn test_vceqq_f32() { testq_cmp_f32( |i, j| vcgeq_f32(i, j), |a: f32, b: f32| -> u32 { if a == b { 0xFFFFFFFF } else { 0 } }, @@ -4242,42 +4327,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vcgt_s8() { + fn test_vcgt_s8() { test_cmp_s8( |i, j| vcgt_s8(i, j), |a: i8, b: i8| -> u8 { if a > b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgtq_s8() { + fn test_vcgtq_s8() { testq_cmp_s8( |i, j| vcgtq_s8(i, j), |a: i8, b: i8| -> u8 { if a > b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgt_s16() { + fn test_vcgt_s16() { test_cmp_s16( |i, j| vcgt_s16(i, j), |a: i16, b: i16| -> u16 { if a > b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgtq_s16() { + fn test_vcgtq_s16() { testq_cmp_s16( |i, j| vcgtq_s16(i, j), |a: i16, b: i16| -> u16 { if a > b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgt_s32() { + fn test_vcgt_s32() { test_cmp_s32( |i, j| vcgt_s32(i, j), |a: i32, b: i32| -> u32 { if a > b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgtq_s32() { + fn test_vcgtq_s32() { testq_cmp_s32( |i, j| vcgtq_s32(i, j), |a: i32, b: i32| -> u32 { if a > b { 0xFFFFFFFF } else { 0 } }, @@ -4285,42 +4375,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vcgt_u8() { + fn test_vcgt_u8() { test_cmp_u8( |i, j| vcgt_u8(i, j), |a: u8, b: u8| -> u8 { if a > b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgtq_u8() { + fn test_vcgtq_u8() { testq_cmp_u8( |i, j| vcgtq_u8(i, j), |a: u8, b: u8| -> u8 { if a > b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgt_u16() { + fn test_vcgt_u16() { test_cmp_u16( |i, j| vcgt_u16(i, j), |a: u16, b: u16| -> u16 { if a > b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgtq_u16() { + fn test_vcgtq_u16() { testq_cmp_u16( |i, j| vcgtq_u16(i, j), |a: u16, b: u16| -> u16 { if a > b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgt_u32() { + fn test_vcgt_u32() { test_cmp_u32( |i, j| vcgt_u32(i, j), |a: u32, b: u32| -> u32 { if a > b { 0xFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgtq_u32() { + fn test_vcgtq_u32() { testq_cmp_u32( |i, j| vcgtq_u32(i, j), |a: u32, b: u32| -> u32 { if a > b { 0xFFFFFFFF } else { 0 } }, @@ -4328,14 +4423,15 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vcgt_f32() { + fn test_vcgt_f32() { test_cmp_f32( |i, j| vcgt_f32(i, j), |a: f32, b: f32| -> u32 { if a > b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgtq_f32() { + fn test_vcgtq_f32() { testq_cmp_f32( |i, j| vcgtq_f32(i, j), |a: f32, b: f32| -> u32 { if a > b { 0xFFFFFFFF } else { 0 } }, @@ -4343,42 +4439,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vclt_s8() { + fn test_vclt_s8() { test_cmp_s8( |i, j| vclt_s8(i, j), |a: i8, b: i8| -> u8 { if a < b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcltq_s8() { + fn test_vcltq_s8() { testq_cmp_s8( |i, j| vcltq_s8(i, j), |a: i8, b: i8| -> u8 { if a < b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vclt_s16() { + fn test_vclt_s16() { test_cmp_s16( |i, j| vclt_s16(i, j), |a: i16, b: i16| -> u16 { if a < b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcltq_s16() { + fn test_vcltq_s16() { testq_cmp_s16( |i, j| vcltq_s16(i, j), |a: i16, b: i16| -> u16 { if a < b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vclt_s32() { + fn test_vclt_s32() { test_cmp_s32( |i, j| vclt_s32(i, j), |a: i32, b: i32| -> u32 { if a < b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcltq_s32() { + fn test_vcltq_s32() { testq_cmp_s32( |i, j| vcltq_s32(i, j), |a: i32, b: i32| -> u32 { if a < b { 0xFFFFFFFF } else { 0 } }, @@ -4386,42 +4487,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vclt_u8() { + fn test_vclt_u8() { test_cmp_u8( |i, j| vclt_u8(i, j), |a: u8, b: u8| -> u8 { if a < b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcltq_u8() { + fn test_vcltq_u8() { testq_cmp_u8( |i, j| vcltq_u8(i, j), |a: u8, b: u8| -> u8 { if a < b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vclt_u16() { + fn test_vclt_u16() { test_cmp_u16( |i, j| vclt_u16(i, j), |a: u16, b: u16| -> u16 { if a < b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcltq_u16() { + fn test_vcltq_u16() { testq_cmp_u16( |i, j| vcltq_u16(i, j), |a: u16, b: u16| -> u16 { if a < b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vclt_u32() { + fn test_vclt_u32() { test_cmp_u32( |i, j| vclt_u32(i, j), |a: u32, b: u32| -> u32 { if a < b { 0xFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcltq_u32() { + fn test_vcltq_u32() { testq_cmp_u32( |i, j| vcltq_u32(i, j), |a: u32, b: u32| -> u32 { if a < b { 0xFFFFFFFF } else { 0 } }, @@ -4429,14 +4535,15 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vclt_f32() { + fn test_vclt_f32() { test_cmp_f32( |i, j| vclt_f32(i, j), |a: f32, b: f32| -> u32 { if a < b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcltq_f32() { + fn test_vcltq_f32() { testq_cmp_f32( |i, j| vcltq_f32(i, j), |a: f32, b: f32| -> u32 { if a < b { 0xFFFFFFFF } else { 0 } }, @@ -4444,42 +4551,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vcle_s8() { + fn test_vcle_s8() { test_cmp_s8( |i, j| vcle_s8(i, j), |a: i8, b: i8| -> u8 { if a <= b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcleq_s8() { + fn test_vcleq_s8() { testq_cmp_s8( |i, j| vcleq_s8(i, j), |a: i8, b: i8| -> u8 { if a <= b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcle_s16() { + fn test_vcle_s16() { test_cmp_s16( |i, j| vcle_s16(i, j), |a: i16, b: i16| -> u16 { if a <= b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcleq_s16() { + fn test_vcleq_s16() { testq_cmp_s16( |i, j| vcleq_s16(i, j), |a: i16, b: i16| -> u16 { if a <= b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcle_s32() { + fn test_vcle_s32() { test_cmp_s32( |i, j| vcle_s32(i, j), |a: i32, b: i32| -> u32 { if a <= b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcleq_s32() { + fn test_vcleq_s32() { testq_cmp_s32( |i, j| vcleq_s32(i, j), |a: i32, b: i32| -> u32 { if a <= b { 0xFFFFFFFF } else { 0 } }, @@ -4487,42 +4599,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vcle_u8() { + fn test_vcle_u8() { test_cmp_u8( |i, j| vcle_u8(i, j), |a: u8, b: u8| -> u8 { if a <= b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcleq_u8() { + fn test_vcleq_u8() { testq_cmp_u8( |i, j| vcleq_u8(i, j), |a: u8, b: u8| -> u8 { if a <= b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcle_u16() { + fn test_vcle_u16() { test_cmp_u16( |i, j| vcle_u16(i, j), |a: u16, b: u16| -> u16 { if a <= b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcleq_u16() { + fn test_vcleq_u16() { testq_cmp_u16( |i, j| vcleq_u16(i, j), |a: u16, b: u16| -> u16 { if a <= b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcle_u32() { + fn test_vcle_u32() { test_cmp_u32( |i, j| vcle_u32(i, j), |a: u32, b: u32| -> u32 { if a <= b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcleq_u32() { + fn test_vcleq_u32() { testq_cmp_u32( |i, j| vcleq_u32(i, j), |a: u32, b: u32| -> u32 { if a <= b { 0xFFFFFFFF } else { 0 } }, @@ -4530,14 +4647,15 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vcle_f32() { + fn test_vcle_f32() { test_cmp_f32( |i, j| vcle_f32(i, j), |a: f32, b: f32| -> u32 { if a <= b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcleq_f32() { + fn test_vcleq_f32() { testq_cmp_f32( |i, j| vcleq_f32(i, j), |a: f32, b: f32| -> u32 { if a <= b { 0xFFFFFFFF } else { 0 } }, @@ -4545,42 +4663,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vcge_s8() { + fn test_vcge_s8() { test_cmp_s8( |i, j| vcge_s8(i, j), |a: i8, b: i8| -> u8 { if a >= b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgeq_s8() { + fn test_vcgeq_s8() { testq_cmp_s8( |i, j| vcgeq_s8(i, j), |a: i8, b: i8| -> u8 { if a >= b { 0xFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcge_s16() { + fn test_vcge_s16() { test_cmp_s16( |i, j| vcge_s16(i, j), |a: i16, b: i16| -> u16 { if a >= b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgeq_s16() { + fn test_vcgeq_s16() { testq_cmp_s16( |i, j| vcgeq_s16(i, j), |a: i16, b: i16| -> u16 { if a >= b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcge_s32() { + fn test_vcge_s32() { test_cmp_s32( |i, j| vcge_s32(i, j), |a: i32, b: i32| -> u32 { if a >= b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgeq_s32() { + fn test_vcgeq_s32() { testq_cmp_s32( |i, j| vcgeq_s32(i, j), |a: i32, b: i32| -> u32 { if a >= b { 0xFFFFFFFF } else { 0 } }, @@ -4588,42 +4711,45 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vcge_u8() { + fn test_vcge_u8() { test_cmp_u8( |i, j| vcge_u8(i, j), |a: u8, b: u8| -> u8 { if a >= b { 0xFF } else { 0 } }, ); } #[simd_test(enable = "neon")] - unsafe fn test_vcgeq_u8() { + fn test_vcgeq_u8() { testq_cmp_u8( |i, j| vcgeq_u8(i, j), |a: u8, b: u8| -> u8 { if a >= b { 0xFF } else { 0 } }, ); } #[simd_test(enable = "neon")] - unsafe fn test_vcge_u16() { + fn test_vcge_u16() { test_cmp_u16( |i, j| vcge_u16(i, j), |a: u16, b: u16| -> u16 { if a >= b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgeq_u16() { + fn test_vcgeq_u16() { testq_cmp_u16( |i, j| vcgeq_u16(i, j), |a: u16, b: u16| -> u16 { if a >= b { 0xFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcge_u32() { + fn test_vcge_u32() { test_cmp_u32( |i, j| vcge_u32(i, j), |a: u32, b: u32| -> u32 { if a >= b { 0xFFFFFFFF } else { 0 } }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vcgeq_u32() { + fn test_vcgeq_u32() { testq_cmp_u32( |i, j| vcgeq_u32(i, j), |a: u32, b: u32| -> u32 { if a >= b { 0xFFFFFFFF } else { 0 } }, @@ -4631,14 +4757,14 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vcge_f32() { + fn test_vcge_f32() { test_cmp_f32( |i, j| vcge_f32(i, j), |a: f32, b: f32| -> u32 { if a >= b { 0xFFFFFFFF } else { 0 } }, ); } #[simd_test(enable = "neon")] - unsafe fn test_vcgeq_f32() { + fn test_vcgeq_f32() { testq_cmp_f32( |i, j| vcgeq_f32(i, j), |a: f32, b: f32| -> u32 { if a >= b { 0xFFFFFFFF } else { 0 } }, @@ -4646,42 +4772,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vqsub_s8() { + fn test_vqsub_s8() { test_ari_s8( |i, j| vqsub_s8(i, j), |a: i8, b: i8| -> i8 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsubq_s8() { + fn test_vqsubq_s8() { testq_ari_s8( |i, j| vqsubq_s8(i, j), |a: i8, b: i8| -> i8 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsub_s16() { + fn test_vqsub_s16() { test_ari_s16( |i, j| vqsub_s16(i, j), |a: i16, b: i16| -> i16 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsubq_s16() { + fn test_vqsubq_s16() { testq_ari_s16( |i, j| vqsubq_s16(i, j), |a: i16, b: i16| -> i16 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsub_s32() { + fn test_vqsub_s32() { test_ari_s32( |i, j| vqsub_s32(i, j), |a: i32, b: i32| -> i32 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsubq_s32() { + fn test_vqsubq_s32() { testq_ari_s32( |i, j| vqsubq_s32(i, j), |a: i32, b: i32| -> i32 { a.saturating_sub(b) }, @@ -4689,42 +4820,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vqsub_u8() { + fn test_vqsub_u8() { test_ari_u8( |i, j| vqsub_u8(i, j), |a: u8, b: u8| -> u8 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsubq_u8() { + fn test_vqsubq_u8() { testq_ari_u8( |i, j| vqsubq_u8(i, j), |a: u8, b: u8| -> u8 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsub_u16() { + fn test_vqsub_u16() { test_ari_u16( |i, j| vqsub_u16(i, j), |a: u16, b: u16| -> u16 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsubq_u16() { + fn test_vqsubq_u16() { testq_ari_u16( |i, j| vqsubq_u16(i, j), |a: u16, b: u16| -> u16 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsub_u32() { + fn test_vqsub_u32() { test_ari_u32( |i, j| vqsub_u32(i, j), |a: u32, b: u32| -> u32 { a.saturating_sub(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqsubq_u32() { + fn test_vqsubq_u32() { testq_ari_u32( |i, j| vqsubq_u32(i, j), |a: u32, b: u32| -> u32 { a.saturating_sub(b) }, @@ -4732,142 +4868,166 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vhadd_s8() { + fn test_vhadd_s8() { test_ari_s8(|i, j| vhadd_s8(i, j), |a: i8, b: i8| -> i8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhaddq_s8() { + fn test_vhaddq_s8() { testq_ari_s8(|i, j| vhaddq_s8(i, j), |a: i8, b: i8| -> i8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhadd_s16() { + fn test_vhadd_s16() { test_ari_s16(|i, j| vhadd_s16(i, j), |a: i16, b: i16| -> i16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhaddq_s16() { + fn test_vhaddq_s16() { testq_ari_s16(|i, j| vhaddq_s16(i, j), |a: i16, b: i16| -> i16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhadd_s32() { + fn test_vhadd_s32() { test_ari_s32(|i, j| vhadd_s32(i, j), |a: i32, b: i32| -> i32 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhaddq_s32() { + fn test_vhaddq_s32() { testq_ari_s32(|i, j| vhaddq_s32(i, j), |a: i32, b: i32| -> i32 { a & b }); } #[simd_test(enable = "neon")] - unsafe fn test_vhadd_u8() { + fn test_vhadd_u8() { test_ari_u8(|i, j| vhadd_u8(i, j), |a: u8, b: u8| -> u8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhaddq_u8() { + fn test_vhaddq_u8() { testq_ari_u8(|i, j| vhaddq_u8(i, j), |a: u8, b: u8| -> u8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhadd_u16() { + fn test_vhadd_u16() { test_ari_u16(|i, j| vhadd_u16(i, j), |a: u16, b: u16| -> u16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhaddq_u16() { + fn test_vhaddq_u16() { testq_ari_u16(|i, j| vhaddq_u16(i, j), |a: u16, b: u16| -> u16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhadd_u32() { + fn test_vhadd_u32() { test_ari_u32(|i, j| vhadd_u32(i, j), |a: u32, b: u32| -> u32 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vhaddq_u32() { + fn test_vhaddq_u32() { testq_ari_u32(|i, j| vhaddq_u32(i, j), |a: u32, b: u32| -> u32 { a & b }); } #[simd_test(enable = "neon")] - unsafe fn test_vrhadd_s8() { + fn test_vrhadd_s8() { test_ari_s8(|i, j| vrhadd_s8(i, j), |a: i8, b: i8| -> i8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhaddq_s8() { + fn test_vrhaddq_s8() { testq_ari_s8(|i, j| vrhaddq_s8(i, j), |a: i8, b: i8| -> i8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhadd_s16() { + fn test_vrhadd_s16() { test_ari_s16(|i, j| vrhadd_s16(i, j), |a: i16, b: i16| -> i16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhaddq_s16() { + fn test_vrhaddq_s16() { testq_ari_s16(|i, j| vrhaddq_s16(i, j), |a: i16, b: i16| -> i16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhadd_s32() { + fn test_vrhadd_s32() { test_ari_s32(|i, j| vrhadd_s32(i, j), |a: i32, b: i32| -> i32 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhaddq_s32() { + fn test_vrhaddq_s32() { testq_ari_s32(|i, j| vrhaddq_s32(i, j), |a: i32, b: i32| -> i32 { a & b }); } #[simd_test(enable = "neon")] - unsafe fn test_vrhadd_u8() { + fn test_vrhadd_u8() { test_ari_u8(|i, j| vrhadd_u8(i, j), |a: u8, b: u8| -> u8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhaddq_u8() { + fn test_vrhaddq_u8() { testq_ari_u8(|i, j| vrhaddq_u8(i, j), |a: u8, b: u8| -> u8 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhadd_u16() { + fn test_vrhadd_u16() { test_ari_u16(|i, j| vrhadd_u16(i, j), |a: u16, b: u16| -> u16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhaddq_u16() { + fn test_vrhaddq_u16() { testq_ari_u16(|i, j| vrhaddq_u16(i, j), |a: u16, b: u16| -> u16 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhadd_u32() { + fn test_vrhadd_u32() { test_ari_u32(|i, j| vrhadd_u32(i, j), |a: u32, b: u32| -> u32 { a & b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vrhaddq_u32() { + fn test_vrhaddq_u32() { testq_ari_u32(|i, j| vrhaddq_u32(i, j), |a: u32, b: u32| -> u32 { a & b }); } #[simd_test(enable = "neon")] - unsafe fn test_vqadd_s8() { + fn test_vqadd_s8() { test_ari_s8( |i, j| vqadd_s8(i, j), |a: i8, b: i8| -> i8 { a.saturating_add(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqaddq_s8() { + fn test_vqaddq_s8() { testq_ari_s8( |i, j| vqaddq_s8(i, j), |a: i8, b: i8| -> i8 { a.saturating_add(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqadd_s16() { + fn test_vqadd_s16() { test_ari_s16( |i, j| vqadd_s16(i, j), |a: i16, b: i16| -> i16 { a.saturating_add(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqaddq_s16() { + fn test_vqaddq_s16() { testq_ari_s16( |i, j| vqaddq_s16(i, j), |a: i16, b: i16| -> i16 { a.saturating_add(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqadd_s32() { + fn test_vqadd_s32() { test_ari_s32( |i, j| vqadd_s32(i, j), |a: i32, b: i32| -> i32 { a.saturating_add(b) }, ); } #[simd_test(enable = "neon")] - unsafe fn test_vqaddq_s32() { + fn test_vqaddq_s32() { testq_ari_s32( |i, j| vqaddq_s32(i, j), |a: i32, b: i32| -> i32 { a.saturating_add(b) }, @@ -4875,42 +5035,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vqadd_u8() { + fn test_vqadd_u8() { test_ari_u8( |i, j| vqadd_u8(i, j), |a: u8, b: u8| -> u8 { a.saturating_add(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqaddq_u8() { + fn test_vqaddq_u8() { testq_ari_u8( |i, j| vqaddq_u8(i, j), |a: u8, b: u8| -> u8 { a.saturating_add(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqadd_u16() { + fn test_vqadd_u16() { test_ari_u16( |i, j| vqadd_u16(i, j), |a: u16, b: u16| -> u16 { a.saturating_add(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqaddq_u16() { + fn test_vqaddq_u16() { testq_ari_u16( |i, j| vqaddq_u16(i, j), |a: u16, b: u16| -> u16 { a.saturating_add(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqadd_u32() { + fn test_vqadd_u32() { test_ari_u32( |i, j| vqadd_u32(i, j), |a: u32, b: u32| -> u32 { a.saturating_add(b) }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vqaddq_u32() { + fn test_vqaddq_u32() { testq_ari_u32( |i, j| vqaddq_u32(i, j), |a: u32, b: u32| -> u32 { a.saturating_add(b) }, @@ -4918,42 +5083,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vmul_s8() { + fn test_vmul_s8() { test_ari_s8( |i, j| vmul_s8(i, j), |a: i8, b: i8| -> i8 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmulq_s8() { + fn test_vmulq_s8() { testq_ari_s8( |i, j| vmulq_s8(i, j), |a: i8, b: i8| -> i8 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmul_s16() { + fn test_vmul_s16() { test_ari_s16( |i, j| vmul_s16(i, j), |a: i16, b: i16| -> i16 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmulq_s16() { + fn test_vmulq_s16() { testq_ari_s16( |i, j| vmulq_s16(i, j), |a: i16, b: i16| -> i16 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmul_s32() { + fn test_vmul_s32() { test_ari_s32( |i, j| vmul_s32(i, j), |a: i32, b: i32| -> i32 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmulq_s32() { + fn test_vmulq_s32() { testq_ari_s32( |i, j| vmulq_s32(i, j), |a: i32, b: i32| -> i32 { a.overflowing_mul(b).0 }, @@ -4961,42 +5131,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vmul_u8() { + fn test_vmul_u8() { test_ari_u8( |i, j| vmul_u8(i, j), |a: u8, b: u8| -> u8 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmulq_u8() { + fn test_vmulq_u8() { testq_ari_u8( |i, j| vmulq_u8(i, j), |a: u8, b: u8| -> u8 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmul_u16() { + fn test_vmul_u16() { test_ari_u16( |i, j| vmul_u16(i, j), |a: u16, b: u16| -> u16 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmulq_u16() { + fn test_vmulq_u16() { testq_ari_u16( |i, j| vmulq_u16(i, j), |a: u16, b: u16| -> u16 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmul_u32() { + fn test_vmul_u32() { test_ari_u32( |i, j| vmul_u32(i, j), |a: u32, b: u32| -> u32 { a.overflowing_mul(b).0 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vmulq_u32() { + fn test_vmulq_u32() { testq_ari_u32( |i, j| vmulq_u32(i, j), |a: u32, b: u32| -> u32 { a.overflowing_mul(b).0 }, @@ -5004,110 +5179,127 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vmul_f32() { + fn test_vmul_f32() { test_ari_f32(|i, j| vmul_f32(i, j), |a: f32, b: f32| -> f32 { a * b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vmulq_f32() { + fn test_vmulq_f32() { testq_ari_f32(|i, j| vmulq_f32(i, j), |a: f32, b: f32| -> f32 { a * b }); } #[simd_test(enable = "neon")] - unsafe fn test_vsub_s8() { + fn test_vsub_s8() { test_ari_s8(|i, j| vsub_s8(i, j), |a: i8, b: i8| -> i8 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsubq_s8() { + fn test_vsubq_s8() { testq_ari_s8(|i, j| vsubq_s8(i, j), |a: i8, b: i8| -> i8 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsub_s16() { + fn test_vsub_s16() { test_ari_s16(|i, j| vsub_s16(i, j), |a: i16, b: i16| -> i16 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsubq_s16() { + fn test_vsubq_s16() { testq_ari_s16(|i, j| vsubq_s16(i, j), |a: i16, b: i16| -> i16 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsub_s32() { + fn test_vsub_s32() { test_ari_s32(|i, j| vsub_s32(i, j), |a: i32, b: i32| -> i32 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsubq_s32() { + fn test_vsubq_s32() { testq_ari_s32(|i, j| vsubq_s32(i, j), |a: i32, b: i32| -> i32 { a - b }); } #[simd_test(enable = "neon")] - unsafe fn test_vsub_u8() { + fn test_vsub_u8() { test_ari_u8(|i, j| vsub_u8(i, j), |a: u8, b: u8| -> u8 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsubq_u8() { + fn test_vsubq_u8() { testq_ari_u8(|i, j| vsubq_u8(i, j), |a: u8, b: u8| -> u8 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsub_u16() { + fn test_vsub_u16() { test_ari_u16(|i, j| vsub_u16(i, j), |a: u16, b: u16| -> u16 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsubq_u16() { + fn test_vsubq_u16() { testq_ari_u16(|i, j| vsubq_u16(i, j), |a: u16, b: u16| -> u16 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsub_u32() { + fn test_vsub_u32() { test_ari_u32(|i, j| vsub_u32(i, j), |a: u32, b: u32| -> u32 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsubq_u32() { + fn test_vsubq_u32() { testq_ari_u32(|i, j| vsubq_u32(i, j), |a: u32, b: u32| -> u32 { a - b }); } #[simd_test(enable = "neon")] - unsafe fn test_vsub_f32() { + fn test_vsub_f32() { test_ari_f32(|i, j| vsub_f32(i, j), |a: f32, b: f32| -> f32 { a - b }); } + #[simd_test(enable = "neon")] - unsafe fn test_vsubq_f32() { + fn test_vsubq_f32() { testq_ari_f32(|i, j| vsubq_f32(i, j), |a: f32, b: f32| -> f32 { a - b }); } #[simd_test(enable = "neon")] - unsafe fn test_vhsub_s8() { + fn test_vhsub_s8() { test_ari_s8( |i, j| vhsub_s8(i, j), |a: i8, b: i8| -> i8 { (((a as i16) - (b as i16)) / 2) as i8 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsubq_s8() { + fn test_vhsubq_s8() { testq_ari_s8( |i, j| vhsubq_s8(i, j), |a: i8, b: i8| -> i8 { (((a as i16) - (b as i16)) / 2) as i8 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsub_s16() { + fn test_vhsub_s16() { test_ari_s16( |i, j| vhsub_s16(i, j), |a: i16, b: i16| -> i16 { (((a as i32) - (b as i32)) / 2) as i16 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsubq_s16() { + fn test_vhsubq_s16() { testq_ari_s16( |i, j| vhsubq_s16(i, j), |a: i16, b: i16| -> i16 { (((a as i32) - (b as i32)) / 2) as i16 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsub_s32() { + fn test_vhsub_s32() { test_ari_s32( |i, j| vhsub_s32(i, j), |a: i32, b: i32| -> i32 { (((a as i64) - (b as i64)) / 2) as i32 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsubq_s32() { + fn test_vhsubq_s32() { testq_ari_s32( |i, j| vhsubq_s32(i, j), |a: i32, b: i32| -> i32 { (((a as i64) - (b as i64)) / 2) as i32 }, @@ -5115,42 +5307,47 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vhsub_u8() { + fn test_vhsub_u8() { test_ari_u8( |i, j| vhsub_u8(i, j), |a: u8, b: u8| -> u8 { (((a as u16) - (b as u16)) / 2) as u8 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsubq_u8() { + fn test_vhsubq_u8() { testq_ari_u8( |i, j| vhsubq_u8(i, j), |a: u8, b: u8| -> u8 { (((a as u16) - (b as u16)) / 2) as u8 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsub_u16() { + fn test_vhsub_u16() { test_ari_u16( |i, j| vhsub_u16(i, j), |a: u16, b: u16| -> u16 { (((a as u16) - (b as u16)) / 2) as u16 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsubq_u16() { + fn test_vhsubq_u16() { testq_ari_u16( |i, j| vhsubq_u16(i, j), |a: u16, b: u16| -> u16 { (((a as u16) - (b as u16)) / 2) as u16 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsub_u32() { + fn test_vhsub_u32() { test_ari_u32( |i, j| vhsub_u32(i, j), |a: u32, b: u32| -> u32 { (((a as u64) - (b as u64)) / 2) as u32 }, ); } + #[simd_test(enable = "neon")] - unsafe fn test_vhsubq_u32() { + fn test_vhsubq_u32() { testq_ari_u32( |i, j| vhsubq_u32(i, j), |a: u32, b: u32| -> u32 { (((a as u64) - (b as u64)) / 2) as u32 }, @@ -5158,368 +5355,414 @@ mod tests { } #[simd_test(enable = "neon")] - unsafe fn test_vaba_s8() { + fn test_vaba_s8() { let a = i8x8::new(1, 2, 3, 4, 5, 6, 7, 8); let b = i8x8::new(1, 1, 1, 1, 1, 1, 1, 1); let c = i8x8::new(10, 9, 8, 7, 6, 5, 4, 3); - let r: i8x8 = transmute(vaba_s8(transmute(a), transmute(b), transmute(c))); + let r = i8x8::from(vaba_s8(a.into(), b.into(), c.into())); let e = i8x8::new(10, 10, 10, 10, 10, 10, 10, 10); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vaba_s16() { + fn test_vaba_s16() { let a = i16x4::new(1, 2, 3, 4); let b = i16x4::new(1, 1, 1, 1); let c = i16x4::new(10, 9, 8, 7); - let r: i16x4 = transmute(vaba_s16(transmute(a), transmute(b), transmute(c))); + let r = i16x4::from(vaba_s16(a.into(), b.into(), c.into())); let e = i16x4::new(10, 10, 10, 10); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vaba_s32() { + fn test_vaba_s32() { let a = i32x2::new(1, 2); let b = i32x2::new(1, 1); let c = i32x2::new(10, 9); - let r: i32x2 = transmute(vaba_s32(transmute(a), transmute(b), transmute(c))); + let r = i32x2::from(vaba_s32(a.into(), b.into(), c.into())); let e = i32x2::new(10, 10); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vaba_u8() { + fn test_vaba_u8() { let a = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); let b = u8x8::new(1, 1, 1, 1, 1, 1, 1, 1); let c = u8x8::new(10, 9, 8, 7, 6, 5, 4, 3); - let r: u8x8 = transmute(vaba_u8(transmute(a), transmute(b), transmute(c))); + let r = u8x8::from(vaba_u8(a.into(), b.into(), c.into())); let e = u8x8::new(10, 10, 10, 10, 10, 10, 10, 10); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vaba_u16() { + fn test_vaba_u16() { let a = u16x4::new(1, 2, 3, 4); let b = u16x4::new(1, 1, 1, 1); let c = u16x4::new(10, 9, 8, 7); - let r: u16x4 = transmute(vaba_u16(transmute(a), transmute(b), transmute(c))); + let r = u16x4::from(vaba_u16(a.into(), b.into(), c.into())); let e = u16x4::new(10, 10, 10, 10); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vaba_u32() { + fn test_vaba_u32() { let a = u32x2::new(1, 2); let b = u32x2::new(1, 1); let c = u32x2::new(10, 9); - let r: u32x2 = transmute(vaba_u32(transmute(a), transmute(b), transmute(c))); + let r = u32x2::from(vaba_u32(a.into(), b.into(), c.into())); let e = u32x2::new(10, 10); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vabaq_s8() { + fn test_vabaq_s8() { let a = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2); let b = i8x16::new(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let c = i8x16::new(10, 9, 8, 7, 6, 5, 4, 3, 12, 13, 14, 15, 16, 17, 18, 19); - let r: i8x16 = transmute(vabaq_s8(transmute(a), transmute(b), transmute(c))); + let r = i8x16::from(vabaq_s8(a.into(), b.into(), c.into())); let e = i8x16::new( 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 20, 20, 20, ); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vabaq_s16() { + fn test_vabaq_s16() { let a = i16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let b = i16x8::new(1, 1, 1, 1, 1, 1, 1, 1); let c = i16x8::new(10, 9, 8, 7, 6, 5, 4, 3); - let r: i16x8 = transmute(vabaq_s16(transmute(a), transmute(b), transmute(c))); + let r = i16x8::from(vabaq_s16(a.into(), b.into(), c.into())); let e = i16x8::new(10, 10, 10, 10, 10, 10, 10, 10); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vabaq_s32() { + fn test_vabaq_s32() { let a = i32x4::new(1, 2, 3, 4); let b = i32x4::new(1, 1, 1, 1); let c = i32x4::new(10, 9, 8, 7); - let r: i32x4 = transmute(vabaq_s32(transmute(a), transmute(b), transmute(c))); + let r = i32x4::from(vabaq_s32(a.into(), b.into(), c.into())); let e = i32x4::new(10, 10, 10, 10); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vabaq_u8() { + fn test_vabaq_u8() { let a = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2); let b = u8x16::new(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); let c = u8x16::new(10, 9, 8, 7, 6, 5, 4, 3, 12, 13, 14, 15, 16, 17, 18, 19); - let r: u8x16 = transmute(vabaq_u8(transmute(a), transmute(b), transmute(c))); + let r = u8x16::from(vabaq_u8(a.into(), b.into(), c.into())); let e = u8x16::new( 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 20, 20, 20, ); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vabaq_u16() { + fn test_vabaq_u16() { let a = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); let b = u16x8::new(1, 1, 1, 1, 1, 1, 1, 1); let c = u16x8::new(10, 9, 8, 7, 6, 5, 4, 3); - let r: u16x8 = transmute(vabaq_u16(transmute(a), transmute(b), transmute(c))); + let r = u16x8::from(vabaq_u16(a.into(), b.into(), c.into())); let e = u16x8::new(10, 10, 10, 10, 10, 10, 10, 10); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vabaq_u32() { + fn test_vabaq_u32() { let a = u32x4::new(1, 2, 3, 4); let b = u32x4::new(1, 1, 1, 1); let c = u32x4::new(10, 9, 8, 7); - let r: u32x4 = transmute(vabaq_u32(transmute(a), transmute(b), transmute(c))); + let r = u32x4::from(vabaq_u32(a.into(), b.into(), c.into())); let e = u32x4::new(10, 10, 10, 10); assert_eq!(r, e); } #[simd_test(enable = "neon")] - unsafe fn test_vrev16_s8() { + fn test_vrev16_s8() { let a = i8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = i8x8::new(1, 0, 3, 2, 5, 4, 7, 6); - let e: i8x8 = transmute(vrev16_s8(transmute(a))); + let e = i8x8::from(vrev16_s8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev16q_s8() { + fn test_vrev16q_s8() { let a = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = i8x16::new(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14); - let e: i8x16 = transmute(vrev16q_s8(transmute(a))); + let e = i8x16::from(vrev16q_s8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev16_u8() { + fn test_vrev16_u8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = u8x8::new(1, 0, 3, 2, 5, 4, 7, 6); - let e: u8x8 = transmute(vrev16_u8(transmute(a))); + let e = u8x8::from(vrev16_u8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev16q_u8() { + fn test_vrev16q_u8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = u8x16::new(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14); - let e: u8x16 = transmute(vrev16q_u8(transmute(a))); + let e = u8x16::from(vrev16q_u8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev16_p8() { - let a = i8x8::new(0, 1, 2, 3, 4, 5, 6, 7); - let r = i8x8::new(1, 0, 3, 2, 5, 4, 7, 6); - let e: i8x8 = transmute(vrev16_p8(transmute(a))); + fn test_vrev16_p8() { + let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); + let r = u8x8::new(1, 0, 3, 2, 5, 4, 7, 6); + let e = u8x8::from(vrev16_p8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev16q_p8() { + fn test_vrev16q_p8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = u8x16::new(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14); - let e: u8x16 = transmute(vrev16q_p8(transmute(a))); + let e = u8x16::from(vrev16q_p8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32_s8() { + fn test_vrev32_s8() { let a = i8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = i8x8::new(3, 2, 1, 0, 7, 6, 5, 4); - let e: i8x8 = transmute(vrev32_s8(transmute(a))); + let e = i8x8::from(vrev32_s8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32q_s8() { + fn test_vrev32q_s8() { let a = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = i8x16::new(3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12); - let e: i8x16 = transmute(vrev32q_s8(transmute(a))); + let e = i8x16::from(vrev32q_s8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32_u8() { + fn test_vrev32_u8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = u8x8::new(3, 2, 1, 0, 7, 6, 5, 4); - let e: u8x8 = transmute(vrev32_u8(transmute(a))); + let e = u8x8::from(vrev32_u8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32q_u8() { + fn test_vrev32q_u8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = u8x16::new(3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12); - let e: u8x16 = transmute(vrev32q_u8(transmute(a))); + let e = u8x16::from(vrev32q_u8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32_s16() { + fn test_vrev32_s16() { let a = i16x4::new(0, 1, 2, 3); let r = i16x4::new(1, 0, 3, 2); - let e: i16x4 = transmute(vrev32_s16(transmute(a))); + let e = i16x4::from(vrev32_s16(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32q_s16() { + fn test_vrev32q_s16() { let a = i16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = i16x8::new(1, 0, 3, 2, 5, 4, 7, 6); - let e: i16x8 = transmute(vrev32q_s16(transmute(a))); + let e = i16x8::from(vrev32q_s16(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32_p16() { - let a = i16x4::new(0, 1, 2, 3); - let r = i16x4::new(1, 0, 3, 2); - let e: i16x4 = transmute(vrev32_p16(transmute(a))); - assert_eq!(r, e); - } - #[simd_test(enable = "neon")] - unsafe fn test_vrev32q_p16() { - let a = i16x8::new(0, 1, 2, 3, 4, 5, 6, 7); - let r = i16x8::new(1, 0, 3, 2, 5, 4, 7, 6); - let e: i16x8 = transmute(vrev32q_p16(transmute(a))); - assert_eq!(r, e); - } - #[simd_test(enable = "neon")] - unsafe fn test_vrev32_u16() { + fn test_vrev32_p16() { let a = u16x4::new(0, 1, 2, 3); let r = u16x4::new(1, 0, 3, 2); - let e: u16x4 = transmute(vrev32_u16(transmute(a))); + let e = u16x4::from(vrev32_p16(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32q_u16() { + fn test_vrev32q_p16() { let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = u16x8::new(1, 0, 3, 2, 5, 4, 7, 6); - let e: u16x8 = transmute(vrev32q_u16(transmute(a))); + let e = u16x8::from(vrev32q_p16(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32_p8() { + fn test_vrev32_u16() { + let a = u16x4::new(0, 1, 2, 3); + let r = u16x4::new(1, 0, 3, 2); + let e = u16x4::from(vrev32_u16(a.into())); + assert_eq!(r, e); + } + + #[simd_test(enable = "neon")] + fn test_vrev32q_u16() { + let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); + let r = u16x8::new(1, 0, 3, 2, 5, 4, 7, 6); + let e = u16x8::from(vrev32q_u16(a.into())); + assert_eq!(r, e); + } + + #[simd_test(enable = "neon")] + fn test_vrev32_p8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = u8x8::new(3, 2, 1, 0, 7, 6, 5, 4); - let e: u8x8 = transmute(vrev32_p8(transmute(a))); + let e = u8x8::from(vrev32_p8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev32q_p8() { + fn test_vrev32q_p8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = u8x16::new(3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12); - let e: u8x16 = transmute(vrev32q_p8(transmute(a))); + let e = u8x16::from(vrev32q_p8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64_s8() { + fn test_vrev64_s8() { let a = i8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = i8x8::new(7, 6, 5, 4, 3, 2, 1, 0); - let e: i8x8 = transmute(vrev64_s8(transmute(a))); + let e = i8x8::from(vrev64_s8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64q_s8() { + fn test_vrev64q_s8() { let a = i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = i8x16::new(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); - let e: i8x16 = transmute(vrev64q_s8(transmute(a))); + let e = i8x16::from(vrev64q_s8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64_s16() { + fn test_vrev64_s16() { let a = i16x4::new(0, 1, 2, 3); let r = i16x4::new(3, 2, 1, 0); - let e: i16x4 = transmute(vrev64_s16(transmute(a))); + let e = i16x4::from(vrev64_s16(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64q_s16() { + fn test_vrev64q_s16() { let a = i16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = i16x8::new(3, 2, 1, 0, 7, 6, 5, 4); - let e: i16x8 = transmute(vrev64q_s16(transmute(a))); + let e = i16x8::from(vrev64q_s16(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64_s32() { + fn test_vrev64_s32() { let a = i32x2::new(0, 1); let r = i32x2::new(1, 0); - let e: i32x2 = transmute(vrev64_s32(transmute(a))); + let e = i32x2::from(vrev64_s32(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64q_s32() { + fn test_vrev64q_s32() { let a = i32x4::new(0, 1, 2, 3); let r = i32x4::new(1, 0, 3, 2); - let e: i32x4 = transmute(vrev64q_s32(transmute(a))); + let e = i32x4::from(vrev64q_s32(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64_u8() { + fn test_vrev64_u8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = u8x8::new(7, 6, 5, 4, 3, 2, 1, 0); - let e: u8x8 = transmute(vrev64_u8(transmute(a))); + let e = u8x8::from(vrev64_u8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64q_u8() { + fn test_vrev64q_u8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = u8x16::new(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); - let e: u8x16 = transmute(vrev64q_u8(transmute(a))); + let e = u8x16::from(vrev64q_u8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64_u16() { + fn test_vrev64_u16() { let a = u16x4::new(0, 1, 2, 3); let r = u16x4::new(3, 2, 1, 0); - let e: u16x4 = transmute(vrev64_u16(transmute(a))); + let e = u16x4::from(vrev64_u16(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64q_u16() { + fn test_vrev64q_u16() { let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = u16x8::new(3, 2, 1, 0, 7, 6, 5, 4); - let e: u16x8 = transmute(vrev64q_u16(transmute(a))); + let e = u16x8::from(vrev64q_u16(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64_u32() { + fn test_vrev64_u32() { let a = u32x2::new(0, 1); let r = u32x2::new(1, 0); - let e: u32x2 = transmute(vrev64_u32(transmute(a))); + let e = u32x2::from(vrev64_u32(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64q_u32() { + fn test_vrev64q_u32() { let a = u32x4::new(0, 1, 2, 3); let r = u32x4::new(1, 0, 3, 2); - let e: u32x4 = transmute(vrev64q_u32(transmute(a))); + let e = u32x4::from(vrev64q_u32(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64_f32() { + fn test_vrev64_f32() { let a = f32x2::new(1.0, 2.0); let r = f32x2::new(2.0, 1.0); - let e: f32x2 = transmute(vrev64_f32(transmute(a))); + let e = f32x2::from(vrev64_f32(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64q_f32() { + fn test_vrev64q_f32() { let a = f32x4::new(1.0, 2.0, -2.0, -1.0); let r = f32x4::new(2.0, 1.0, -1.0, -2.0); - let e: f32x4 = transmute(vrev64q_f32(transmute(a))); + let e = f32x4::from(vrev64q_f32(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64_p8() { + fn test_vrev64_p8() { let a = u8x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = u8x8::new(7, 6, 5, 4, 3, 2, 1, 0); - let e: u8x8 = transmute(vrev64_p8(transmute(a))); + let e = u8x8::from(vrev64_p8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64q_p8() { + fn test_vrev64q_p8() { let a = u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = u8x16::new(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); - let e: u8x16 = transmute(vrev64q_p8(transmute(a))); + let e = u8x16::from(vrev64q_p8(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64_p16() { + fn test_vrev64_p16() { let a = u16x4::new(0, 1, 2, 3); let r = u16x4::new(3, 2, 1, 0); - let e: u16x4 = transmute(vrev64_p16(transmute(a))); + let e = u16x4::from(vrev64_p16(a.into())); assert_eq!(r, e); } + #[simd_test(enable = "neon")] - unsafe fn test_vrev64q_p16() { + fn test_vrev64q_p16() { let a = u16x8::new(0, 1, 2, 3, 4, 5, 6, 7); let r = u16x8::new(3, 2, 1, 0, 7, 6, 5, 4); - let e: u16x8 = transmute(vrev64q_p16(transmute(a))); + let e = u16x8::from(vrev64q_p16(a.into())); assert_eq!(r, e); } @@ -5527,13 +5770,13 @@ mod tests { ($test_id:ident => $fn_id:ident ([$($a:expr),*], [$($b:expr),*])) => { #[allow(unused_assignments)] #[simd_test(enable = "neon")] - unsafe fn $test_id() { - let a = [$($a),*]; - let b = [$($b),*]; - let e = [$($a),* $(, $b)*]; - let c = $fn_id(transmute(a), transmute(b)); + fn $test_id() { + let a = Simd::from_array([$($a),*]); + let b = Simd::from_array([$($b),*]); + let e = Simd::from_array([$($a),* $(, $b)*]); + let c = $fn_id(a.into(), b.into()); let mut d = e; - d = transmute(c); + d = c.into(); assert_eq!(d, e); } } @@ -5546,11 +5789,19 @@ mod tests { test_vcombine!(test_vcombine_s16 => vcombine_s16([3_i16, -4, 5, -6], [13_i16, -14, 15, -16])); test_vcombine!(test_vcombine_u16 => vcombine_u16([3_u16, 4, 5, 6], [13_u16, 14, 15, 16])); test_vcombine!(test_vcombine_p16 => vcombine_p16([3_u16, 4, 5, 6], [13_u16, 14, 15, 16])); + #[cfg(not(target_arch = "arm64ec"))] mod fp16 { use super::*; - test_vcombine!(test_vcombine_f16 => vcombine_f16([3_f16, 4., 5., 6.], - [13_f16, 14., 15., 16.])); + #[cfg_attr(target_arch = "arm", simd_test(enable = "neon,fp16"))] + #[cfg_attr(not(target_arch = "arm"), simd_test(enable = "neon"))] + fn test_vcombine_f16() { + let a = f16x4::from_array([3_f16, 4., 5., 6.]); + let b = f16x4::from_array([13_f16, 14., 15., 16.]); + let e = f16x8::from_array([3_f16, 4., 5., 6., 13_f16, 14., 15., 16.]); + let c = f16x8::from(vcombine_f16(a.into(), b.into())); + assert_eq!(c, e); + } } test_vcombine!(test_vcombine_s32 => vcombine_s32([3_i32, -4], [13_i32, -14])); diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/store_tests.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/store_tests.rs index 6b5d4a19ad57..2b10b38f2dd8 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/store_tests.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/store_tests.rs @@ -14,11 +14,13 @@ use crate::core_arch::simd::*; use stdarch_test::simd_test; #[simd_test(enable = "neon")] -unsafe fn test_vst1_s8() { +fn test_vst1_s8() { let mut vals = [0_i8; 9]; let a = i8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - vst1_s8(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_s8(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -32,11 +34,13 @@ unsafe fn test_vst1_s8() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_s8() { +fn test_vst1q_s8() { let mut vals = [0_i8; 17]; let a = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); - vst1q_s8(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_s8(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -58,11 +62,13 @@ unsafe fn test_vst1q_s8() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_s16() { +fn test_vst1_s16() { let mut vals = [0_i16; 5]; let a = i16x4::new(1, 2, 3, 4); - vst1_s16(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_s16(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -72,11 +78,13 @@ unsafe fn test_vst1_s16() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_s16() { +fn test_vst1q_s16() { let mut vals = [0_i16; 9]; let a = i16x8::new(1, 2, 3, 4, 5, 6, 7, 8); - vst1q_s16(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_s16(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -90,11 +98,13 @@ unsafe fn test_vst1q_s16() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_s32() { +fn test_vst1_s32() { let mut vals = [0_i32; 3]; let a = i32x2::new(1, 2); - vst1_s32(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_s32(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -102,11 +112,13 @@ unsafe fn test_vst1_s32() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_s32() { +fn test_vst1q_s32() { let mut vals = [0_i32; 5]; let a = i32x4::new(1, 2, 3, 4); - vst1q_s32(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_s32(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -116,22 +128,26 @@ unsafe fn test_vst1q_s32() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_s64() { +fn test_vst1_s64() { let mut vals = [0_i64; 2]; let a = i64x1::new(1); - vst1_s64(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_s64(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_s64() { +fn test_vst1q_s64() { let mut vals = [0_i64; 3]; let a = i64x2::new(1, 2); - vst1q_s64(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_s64(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -139,11 +155,13 @@ unsafe fn test_vst1q_s64() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_u8() { +fn test_vst1_u8() { let mut vals = [0_u8; 9]; let a = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - vst1_u8(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_u8(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -157,11 +175,13 @@ unsafe fn test_vst1_u8() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_u8() { +fn test_vst1q_u8() { let mut vals = [0_u8; 17]; let a = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); - vst1q_u8(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_u8(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -183,11 +203,13 @@ unsafe fn test_vst1q_u8() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_u16() { +fn test_vst1_u16() { let mut vals = [0_u16; 5]; let a = u16x4::new(1, 2, 3, 4); - vst1_u16(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_u16(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -197,11 +219,13 @@ unsafe fn test_vst1_u16() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_u16() { +fn test_vst1q_u16() { let mut vals = [0_u16; 9]; let a = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); - vst1q_u16(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_u16(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -215,11 +239,13 @@ unsafe fn test_vst1q_u16() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_u32() { +fn test_vst1_u32() { let mut vals = [0_u32; 3]; let a = u32x2::new(1, 2); - vst1_u32(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_u32(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -227,11 +253,13 @@ unsafe fn test_vst1_u32() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_u32() { +fn test_vst1q_u32() { let mut vals = [0_u32; 5]; let a = u32x4::new(1, 2, 3, 4); - vst1q_u32(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_u32(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -241,22 +269,26 @@ unsafe fn test_vst1q_u32() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_u64() { +fn test_vst1_u64() { let mut vals = [0_u64; 2]; let a = u64x1::new(1); - vst1_u64(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_u64(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_u64() { +fn test_vst1q_u64() { let mut vals = [0_u64; 3]; let a = u64x2::new(1, 2); - vst1q_u64(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_u64(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -264,11 +296,13 @@ unsafe fn test_vst1q_u64() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_p8() { +fn test_vst1_p8() { let mut vals = [0_u8; 9]; let a = u8x8::new(1, 2, 3, 4, 5, 6, 7, 8); - vst1_p8(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_p8(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -282,11 +316,13 @@ unsafe fn test_vst1_p8() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_p8() { +fn test_vst1q_p8() { let mut vals = [0_u8; 17]; let a = u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); - vst1q_p8(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_p8(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -308,11 +344,13 @@ unsafe fn test_vst1q_p8() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_p16() { +fn test_vst1_p16() { let mut vals = [0_u16; 5]; let a = u16x4::new(1, 2, 3, 4); - vst1_p16(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_p16(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -322,11 +360,13 @@ unsafe fn test_vst1_p16() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_p16() { +fn test_vst1q_p16() { let mut vals = [0_u16; 9]; let a = u16x8::new(1, 2, 3, 4, 5, 6, 7, 8); - vst1q_p16(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_p16(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -340,22 +380,26 @@ unsafe fn test_vst1q_p16() { } #[simd_test(enable = "neon,aes")] -unsafe fn test_vst1_p64() { +fn test_vst1_p64() { let mut vals = [0_u64; 2]; let a = u64x1::new(1); - vst1_p64(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_p64(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); } #[simd_test(enable = "neon,aes")] -unsafe fn test_vst1q_p64() { +fn test_vst1q_p64() { let mut vals = [0_u64; 3]; let a = u64x2::new(1, 2); - vst1q_p64(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_p64(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0); assert_eq!(vals[1], 1); @@ -363,11 +407,13 @@ unsafe fn test_vst1q_p64() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1_f32() { +fn test_vst1_f32() { let mut vals = [0_f32; 3]; let a = f32x2::new(1., 2.); - vst1_f32(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1_f32(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0.); assert_eq!(vals[1], 1.); @@ -375,11 +421,13 @@ unsafe fn test_vst1_f32() { } #[simd_test(enable = "neon")] -unsafe fn test_vst1q_f32() { +fn test_vst1q_f32() { let mut vals = [0_f32; 5]; let a = f32x4::new(1., 2., 3., 4.); - vst1q_f32(vals[1..].as_mut_ptr(), transmute(a)); + unsafe { + vst1q_f32(vals[1..].as_mut_ptr(), a.into()); + } assert_eq!(vals[0], 0.); assert_eq!(vals[1], 1.); diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/table_lookup_tests.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/table_lookup_tests.rs index 9403855f00e0..1e0333444b94 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/table_lookup_tests.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/table_lookup_tests.rs @@ -21,19 +21,19 @@ macro_rules! test_vtbl { ) => { #[cfg(target_endian = "little")] #[simd_test(enable = "neon")] - unsafe fn $test_name() { + fn $test_name() { // create table as array, and transmute it to // arm's table type - let table: $table_t = mem::transmute([$($table_v),*]); + let table: $table_t = unsafe { mem::transmute([$($table_v),*]) }; // For each control vector, perform a table lookup and // verify the result: $( { - let ctrl: $ctrl_t = mem::transmute([$($ctrl_v),*]); - let result = $fn_id(table, mem::transmute(ctrl)); - let result: $ctrl_t = mem::transmute(result); - let expected: $ctrl_t = mem::transmute([$($exp_v),*]); + let ctrl: $ctrl_t = unsafe { mem::transmute([$($ctrl_v),*]) }; + let result = $fn_id(table, unsafe { mem::transmute(ctrl) }); + let result: $ctrl_t = unsafe { mem::transmute(result) }; + let expected: $ctrl_t = unsafe { mem::transmute([$($exp_v),*]) }; assert_eq!(result, expected); } )* @@ -171,20 +171,19 @@ macro_rules! test_vtbx { ) => { #[cfg(target_endian = "little")] #[simd_test(enable = "neon")] - unsafe fn $test_name() { + fn $test_name() { // create table as array, and transmute it to // arm's table type - let table: $table_t = mem::transmute([$($table_v),*]); - let ext: $ext_t = mem::transmute([$($ext_v),*]); - + let table: $table_t = unsafe { mem::transmute([$($table_v),*]) }; + let ext: $ext_t = unsafe { mem::transmute([$($ext_v),*]) }; // For each control vector, perform a table lookup and // verify the result: $( { - let ctrl: $ctrl_t = mem::transmute([$($ctrl_v),*]); - let result = $fn_id(ext, table, mem::transmute(ctrl)); - let result: $ctrl_t = mem::transmute(result); - let expected: $ctrl_t = mem::transmute([$($exp_v),*]); + let ctrl: $ctrl_t = unsafe { mem::transmute([$($ctrl_v),*]) }; + let result = $fn_id(ext, table, unsafe { mem::transmute(ctrl) }); + let result: $ctrl_t = unsafe { mem::transmute(result) }; + let expected: $ctrl_t = unsafe { mem::transmute([$($exp_v),*]) }; assert_eq!(result, expected); } )* diff --git a/library/stdarch/crates/core_arch/src/arm_shared/test_support.rs b/library/stdarch/crates/core_arch/src/arm_shared/test_support.rs index e2828f85561d..8117b81cd9a3 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/test_support.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/test_support.rs @@ -111,13 +111,13 @@ macro_rules! V_f32 { macro_rules! to64 { ($t : ident) => { - |v: $t| -> u64 { transmute(v) } + |v: $t| -> u64 { unsafe { transmute(v) } } }; } macro_rules! to128 { ($t : ident) => { - |v: $t| -> u128 { transmute(v) } + |v: $t| -> u128 { unsafe { transmute(v) } } }; } @@ -158,9 +158,7 @@ pub(crate) fn test( macro_rules! gen_test_fn { ($n: ident, $t: ident, $u: ident, $v: ident, $w: ident, $x: ident, $vals: expr, $fill1: expr, $fill2: expr, $cast: expr) => { pub(crate) fn $n(test_fun: fn($v, $v) -> $w, verify_fun: fn($t, $t) -> $u) { - unsafe { - test::<$t, $u, $v, $w, $x>($vals, $fill1, $fill2, $cast, test_fun, verify_fun) - }; + test::<$t, $u, $v, $w, $x>($vals, $fill1, $fill2, $cast, test_fun, verify_fun); } }; } diff --git a/library/stdarch/crates/simd-test-macro/src/lib.rs b/library/stdarch/crates/simd-test-macro/src/lib.rs index b8bb874480a0..92bb40946e1f 100644 --- a/library/stdarch/crates/simd-test-macro/src/lib.rs +++ b/library/stdarch/crates/simd-test-macro/src/lib.rs @@ -17,6 +17,15 @@ pub fn simd_test( item: proc_macro::TokenStream, ) -> proc_macro::TokenStream { let tokens = TokenStream::from(attr).into_iter().collect::>(); + + let target = env::var("TARGET").expect( + "TARGET environment variable should be set for rustc (e.g. TARGET=x86_64-apple-darwin cargo test)" + ); + let target_arch = target + .split('-') + .next() + .unwrap_or_else(|| panic!("target triple contained no \"-\": {target}")); + let (target_features, target_feature_attr) = match &tokens[..] { [] => (Vec::new(), TokenStream::new()), [ @@ -24,13 +33,20 @@ pub fn simd_test( TokenTree::Punct(equals), TokenTree::Literal(literal), ] if enable == "enable" && equals.as_char() == '=' => { - let enable_feature = literal.to_string(); - let enable_feature = enable_feature.trim_start_matches('"').trim_end_matches('"'); + let mut enable_feature = literal + .to_string() + .trim_start_matches('"') + .trim_end_matches('"') + .to_string(); let target_features: Vec<_> = enable_feature .replace('+', "") .split(',') .map(String::from) .collect(); + // Allows using `#[simd_test(enable = "neon")]` on aarch64/armv7 shared tests. + if target_arch == "armv7" && target_features.iter().any(|feat| feat == "neon") { + enable_feature.push_str(",v7"); + } ( target_features, @@ -46,14 +62,7 @@ pub fn simd_test( let item_attrs = std::mem::take(&mut item.attrs); let name = &item.sig.ident; - let target = env::var("TARGET").expect( - "TARGET environment variable should be set for rustc (e.g. TARGET=x86_64-apple-darwin cargo test)" - ); - let macro_test = match target - .split('-') - .next() - .unwrap_or_else(|| panic!("target triple contained no \"-\": {target}")) - { + let macro_test = match target_arch { "i686" | "x86_64" | "i586" => "is_x86_feature_detected", "arm" | "armv7" | "thumbv7neon" => "is_arm_feature_detected", "aarch64" | "arm64ec" | "aarch64_be" => "is_aarch64_feature_detected", @@ -85,10 +94,20 @@ pub fn simd_test( let mut detect_missing_features = TokenStream::new(); for feature in target_features { - let q = quote_spanned! { - proc_macro2::Span::call_site() => - if !::std::arch::#macro_test!(#feature) { - missing_features.push(#feature); + let q = if target_arch == "armv7" && feature == "fp16" { + // "fp16" cannot be checked at runtime + quote_spanned! { + proc_macro2::Span::call_site() => + if !cfg!(target_feature = #feature) { + missing_features.push(#feature); + } + } + } else { + quote_spanned! { + proc_macro2::Span::call_site() => + if !::std::arch::#macro_test!(#feature) { + missing_features.push(#feature); + } } }; q.to_tokens(&mut detect_missing_features); From 0d366e098c2b389a2e573056f02b07bd92b7bca4 Mon Sep 17 00:00:00 2001 From: SSD <96286755+the-ssd@users.noreply.github.com> Date: Fri, 2 Jan 2026 22:30:25 +0100 Subject: [PATCH 1536/3801] Fix a typo in `libm::Libm::roundeven` --- library/compiler-builtins/libm/src/libm_helper.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/libm/src/libm_helper.rs b/library/compiler-builtins/libm/src/libm_helper.rs index dfa1ff77bf2e..0bb669398657 100644 --- a/library/compiler-builtins/libm/src/libm_helper.rs +++ b/library/compiler-builtins/libm/src/libm_helper.rs @@ -168,7 +168,7 @@ libm_helper! { (fn remquo(x: f64, y: f64) -> (f64, i32); => remquo); (fn rint(x: f64) -> (f64); => rint); (fn round(x: f64) -> (f64); => round); - (fn roundevem(x: f64) -> (f64); => roundeven); + (fn roundeven(x: f64) -> (f64); => roundeven); (fn scalbn(x: f64, n: i32) -> (f64); => scalbn); (fn sin(x: f64) -> (f64); => sin); (fn sincos(x: f64) -> (f64, f64); => sincos); From 57e44f5046058d467b9f8731f4c49885a8664d8e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 2 Jan 2026 18:39:06 +0100 Subject: [PATCH 1537/3801] skip codegen for intrinsics with big fallback bodies if backend does not need them --- compiler/rustc_codegen_llvm/src/lib.rs | 6 +++++- compiler/rustc_codegen_ssa/src/traits/backend.rs | 6 ++++++ compiler/rustc_interface/src/interface.rs | 1 + compiler/rustc_monomorphize/src/collector.rs | 9 +++++---- compiler/rustc_session/src/session.rs | 7 ++++++- tests/codegen-llvm/intrinsics/carrying_mul_add.rs | 5 ++--- 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 095274744993..875b60ef6ddb 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -42,7 +42,7 @@ use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest}; -use rustc_span::Symbol; +use rustc_span::{Symbol, sym}; use rustc_target::spec::{RelocModel, TlsModel}; use crate::llvm::ToLlvmBool; @@ -333,6 +333,10 @@ impl CodegenBackend for LlvmCodegenBackend { target_config(sess) } + fn replaced_intrinsics(&self) -> Vec { + vec![sym::unchecked_funnel_shl, sym::unchecked_funnel_shr, sym::carrying_mul_add] + } + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { Box::new(rustc_codegen_ssa::base::codegen_crate( LlvmCodegenBackend(()), diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index cb74e2e46d65..2ca24836d046 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -78,6 +78,12 @@ pub trait CodegenBackend { fn print_version(&self) {} + /// Returns a list of all intrinsics that this backend definitely + /// replaces, which means their fallback bodies do not need to be monomorphized. + fn replaced_intrinsics(&self) -> Vec { + vec![] + } + /// Value printed by `--print=backend-has-zstd`. /// /// Used by compiletest to determine whether tests involving zstd compression diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index c0f8f33692e8..c60cf9b8992a 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -496,6 +496,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se ); codegen_backend.init(&sess); + sess.replaced_intrinsics = FxHashSet::from_iter(codegen_backend.replaced_intrinsics()); let cfg = parse_cfg(sess.dcx(), config.crate_cfg); let mut cfg = config::build_configuration(&sess, cfg); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 4b2f8e03afc1..622fdeb4e81c 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1001,11 +1001,12 @@ fn visit_instance_use<'tcx>( if tcx.should_codegen_locally(panic_instance) { output.push(create_fn_mono_item(tcx, panic_instance, source)); } - } else if !intrinsic.must_be_overridden { + } else if !intrinsic.must_be_overridden + && !tcx.sess.replaced_intrinsics.contains(&intrinsic.name) + { // Codegen the fallback body of intrinsics with fallback bodies. - // We explicitly skip this otherwise to ensure we get a linker error - // if anyone tries to call this intrinsic and the codegen backend did not - // override the implementation. + // We have to skip this otherwise as there's no body to codegen. + // We also skip intrinsics the backend handles, to reduce monomorphizations. let instance = ty::Instance::new_raw(instance.def_id(), instance.args); if tcx.should_codegen_locally(instance) { output.push(create_fn_mono_item(tcx, instance, source)); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 1a0ec600af47..b3027d902b4c 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -8,7 +8,7 @@ use std::{env, io}; use rand::{RngCore, rng}; use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::flock; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_data_structures::sync::{DynSend, DynSync, Lock, MappedReadGuard, ReadGuard, RwLock}; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; @@ -154,6 +154,10 @@ pub struct Session { /// preserved with a flag like `-C save-temps`, since these files may be /// hard linked. pub invocation_temp: Option, + + /// The names of intrinsics that the current codegen backend replaces + /// with its own implementations. + pub replaced_intrinsics: FxHashSet, } #[derive(Clone, Copy)] @@ -1091,6 +1095,7 @@ pub fn build_session( target_filesearch, host_filesearch, invocation_temp, + replaced_intrinsics: FxHashSet::default(), // filled by `run_compiler` }; validate_commandline_args_with_session_available(&sess); diff --git a/tests/codegen-llvm/intrinsics/carrying_mul_add.rs b/tests/codegen-llvm/intrinsics/carrying_mul_add.rs index 21fb49a3786a..844f4f6cff64 100644 --- a/tests/codegen-llvm/intrinsics/carrying_mul_add.rs +++ b/tests/codegen-llvm/intrinsics/carrying_mul_add.rs @@ -11,10 +11,9 @@ use std::intrinsics::{carrying_mul_add, fallback}; -// The fallbacks are emitted even when they're never used, but optimize out. +// The fallbacks should not be emitted. -// RAW: wide_mul_u128 -// OPT-NOT: wide_mul_u128 +// NOT: wide_mul_u128 // CHECK-LABEL: @cma_u8 #[no_mangle] From ebd4bc9224a5de37ce151745b00cb8039fef4385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 27 Dec 2025 20:56:37 +0000 Subject: [PATCH 1538/3801] Support long diff conflict markers git can be configured to use more than 7 characters for conflict markers, and jj automatically uses longer conflict markers when the text contains any char sequence that could be confused with conflict markers. Ensure that we only point at markers that are consistent with the start marker's length. Ensure that we only consider char sequences at the beginning of a line as a diff marker. --- .../rustc_parse/src/parser/diagnostics.rs | 54 +++++++++++++++---- .../diff-markers/long-conflict-markers.rs | 11 ++++ .../diff-markers/long-conflict-markers.stderr | 20 +++++++ 3 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 tests/ui/parser/diff-markers/long-conflict-markers.rs create mode 100644 tests/ui/parser/diff-markers/long-conflict-markers.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 70ec80a50812..9c4895e391d2 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -3037,27 +3037,53 @@ impl<'a> Parser<'a> { long_kind: &TokenKind, short_kind: &TokenKind, ) -> bool { - (0..3).all(|i| self.look_ahead(i, |tok| tok == long_kind)) - && self.look_ahead(3, |tok| tok == short_kind) + if long_kind == short_kind { + // For conflict marker chars like `%` and `\`. + (0..7).all(|i| self.look_ahead(i, |tok| tok == long_kind)) + } else { + // For conflict marker chars like `<` and `|`. + (0..3).all(|i| self.look_ahead(i, |tok| tok == long_kind)) + && self.look_ahead(3, |tok| tok == short_kind || tok == long_kind) + } } - fn conflict_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> Option { + fn conflict_marker( + &mut self, + long_kind: &TokenKind, + short_kind: &TokenKind, + expected: Option, + ) -> Option<(Span, usize)> { if self.is_vcs_conflict_marker(long_kind, short_kind) { let lo = self.token.span; - for _ in 0..4 { - self.bump(); + if self.psess.source_map().span_to_margin(lo) != Some(0) { + return None; } - return Some(lo.to(self.prev_token.span)); + let mut len = 0; + while self.token.kind == *long_kind || self.token.kind == *short_kind { + if self.token.kind.break_two_token_op(1).is_some() { + len += 2; + } else { + len += 1; + } + self.bump(); + if expected == Some(len) { + break; + } + } + if expected.is_some() && expected != Some(len) { + return None; + } + return Some((lo.to(self.prev_token.span), len)); } None } pub(super) fn recover_vcs_conflict_marker(&mut self) { // <<<<<<< - let Some(start) = self.conflict_marker(&TokenKind::Shl, &TokenKind::Lt) else { + let Some((start, len)) = self.conflict_marker(&TokenKind::Shl, &TokenKind::Lt, None) else { return; }; - let mut spans = Vec::with_capacity(3); + let mut spans = Vec::with_capacity(2); spans.push(start); // ||||||| let mut middlediff3 = None; @@ -3069,13 +3095,19 @@ impl<'a> Parser<'a> { if self.token == TokenKind::Eof { break; } - if let Some(span) = self.conflict_marker(&TokenKind::OrOr, &TokenKind::Or) { + if let Some((span, _)) = + self.conflict_marker(&TokenKind::OrOr, &TokenKind::Or, Some(len)) + { middlediff3 = Some(span); } - if let Some(span) = self.conflict_marker(&TokenKind::EqEq, &TokenKind::Eq) { + if let Some((span, _)) = + self.conflict_marker(&TokenKind::EqEq, &TokenKind::Eq, Some(len)) + { middle = Some(span); } - if let Some(span) = self.conflict_marker(&TokenKind::Shr, &TokenKind::Gt) { + if let Some((span, _)) = + self.conflict_marker(&TokenKind::Shr, &TokenKind::Gt, Some(len)) + { spans.push(span); end = Some(span); break; diff --git a/tests/ui/parser/diff-markers/long-conflict-markers.rs b/tests/ui/parser/diff-markers/long-conflict-markers.rs new file mode 100644 index 000000000000..f92615fb75b4 --- /dev/null +++ b/tests/ui/parser/diff-markers/long-conflict-markers.rs @@ -0,0 +1,11 @@ +enum E { + Foo { +<<<<<<<<< HEAD //~ ERROR encountered diff marker + x: u8, +||||||| + z: (), +========= + y: i8, +>>>>>>>>> branch + } +} diff --git a/tests/ui/parser/diff-markers/long-conflict-markers.stderr b/tests/ui/parser/diff-markers/long-conflict-markers.stderr new file mode 100644 index 000000000000..c83aaf16b741 --- /dev/null +++ b/tests/ui/parser/diff-markers/long-conflict-markers.stderr @@ -0,0 +1,20 @@ +error: encountered diff marker + --> $DIR/long-conflict-markers.rs:3:1 + | +LL | <<<<<<<<< HEAD + | ^^^^^^^^^ between this marker and `=======` is the code that you are merging into +... +LL | ========= + | --------- between this marker and `>>>>>>>` is the incoming code +LL | y: i8, +LL | >>>>>>>>> branch + | ^^^^^^^^^ this marker concludes the conflict region + | + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit + +error: aborting due to 1 previous error + From 7061adc5a40947521158bb848525717c632ef6b5 Mon Sep 17 00:00:00 2001 From: Coca Date: Fri, 2 Jan 2026 21:26:16 +0000 Subject: [PATCH 1539/3801] Add diagnostic items for `without_provenance` and `without_provenance_mut` Adds diagnostic items for `core::ptr::without_provenance` and `core::ptr::without_provenance_mut`. Will be used to enhance clippy lint `transmuting_null`, see https://github.com/rust-lang/rust-clippy/pull/16336. --- compiler/rustc_span/src/symbol.rs | 2 ++ library/core/src/ptr/mod.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 72709753b1df..c7ff28ccaffb 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1788,6 +1788,8 @@ symbols! { ptr_slice_from_raw_parts_mut, ptr_swap, ptr_swap_nonoverlapping, + ptr_without_provenance, + ptr_without_provenance_mut, ptr_write, ptr_write_bytes, ptr_write_unaligned, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 29fe77390a16..335c5c6ee944 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -880,6 +880,7 @@ pub const fn null_mut() -> *mut T { #[must_use] #[stable(feature = "strict_provenance", since = "1.84.0")] #[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_diagnostic_item = "ptr_without_provenance"] pub const fn without_provenance(addr: usize) -> *const T { without_provenance_mut(addr) } @@ -918,6 +919,7 @@ pub const fn dangling() -> *const T { #[must_use] #[stable(feature = "strict_provenance", since = "1.84.0")] #[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_diagnostic_item = "ptr_without_provenance_mut"] #[allow(integer_to_ptr_transmutes)] // Expected semantics here. pub const fn without_provenance_mut(addr: usize) -> *mut T { // An int-to-pointer transmute currently has exactly the intended semantics: it creates a From c27addbc2b4e7db0b37f7bf6d4ffd7e633f8bfe4 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Fri, 2 Jan 2026 23:35:36 +0000 Subject: [PATCH 1540/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 85c8ff69cb3efd950395cc444a54bbbdad668865. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index d32b6d0d2fc7..7b444a9ef5f1 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -7fefa09b90ca57b8a0e0e4717d672d38a0ae58b5 +85c8ff69cb3efd950395cc444a54bbbdad668865 From 3df06f5083ef6c44e7f49f6520d62adc1f05aa58 Mon Sep 17 00:00:00 2001 From: Ryan <63398895+rwardd@users.noreply.github.com> Date: Sat, 3 Jan 2026 10:53:54 +1030 Subject: [PATCH 1541/3801] fix: use `std::num::NonZero` instead of `extern crate` and extend information in `CHECK-` directives Co-authored-by: scottmcm --- .../issues/multiple-option-or-permutations.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs index b45402f28a3a..0ea7ef9a0f7e 100644 --- a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs +++ b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs @@ -3,16 +3,15 @@ #![crate_type = "lib"] -extern crate core; -use core::num::NonZero; +use std::num::NonZero; // CHECK-LABEL: @or_match_u8 // CHECK-SAME: (i1{{.+}}%0, i8 %1, i1{{.+}}%optb.0, i8 %optb.1) #[no_mangle] pub fn or_match_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-DAG: or i1 %0 // CHECK-DAG: select i1 %0 + // CHECK-DAG: or i1 %0 // CHECK-NEXT: insertvalue { i1, i8 } // CHECK-NEXT: insertvalue { i1, i8 } // ret { i1, i8 } @@ -27,8 +26,8 @@ pub fn or_match_u8(opta: Option, optb: Option) -> Option { #[no_mangle] pub fn or_match_alt_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-DAG: select i1 - // CHECK-DAG: or i1 + // CHECK-DAG: select i1 %opta.0, i8 %opta.1, i8 %optb.1 + // CHECK-DAG: or i1 {{%opta.0, %optb.0|%optb.0, %opta.0}} // CHECK-NEXT: insertvalue { i1, i8 } // CHECK-NEXT: insertvalue { i1, i8 } // ret { i1, i8 } From cc563d531503b15576b147182f6880e75271195a Mon Sep 17 00:00:00 2001 From: AprilNEA Date: Fri, 2 Jan 2026 16:57:07 +0800 Subject: [PATCH 1542/3801] Remove unneeded `forbid_generic` field from `Res::SelfTyAlias` The `forbid_generic` field in `Res::SelfTyAlias` is no longer needed. The check for generic `Self` types in anonymous constants is now handled by `check_param_uses_if_mcg` in HIR type lowering, making this field redundant. This removes: - The `forbid_generic` field from `Res::SelfTyAlias` - The hack in `rustc_resolve` that set `forbid_generic: true` when encountering `Self` in constant items - Related pattern matching and field propagation code --- compiler/rustc_hir/src/def.rs | 31 ++-------- .../src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_resolve/src/ident.rs | 56 +++++++------------ compiler/rustc_resolve/src/late.rs | 9 +-- 4 files changed, 27 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 95abe5c40dd4..e93deaa84944 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -563,29 +563,6 @@ pub enum Res { /// to get the underlying type. alias_to: DefId, - /// Whether the `Self` type is disallowed from mentioning generics (i.e. when used in an - /// anonymous constant). - /// - /// HACK(min_const_generics): self types also have an optional requirement to **not** - /// mention any generic parameters to allow the following with `min_const_generics`: - /// ``` - /// # struct Foo; - /// impl Foo { fn test() -> [u8; size_of::()] { todo!() } } - /// - /// struct Bar([u8; baz::()]); - /// const fn baz() -> usize { 10 } - /// ``` - /// We do however allow `Self` in repeat expression even if it is generic to not break code - /// which already works on stable while causing the `const_evaluatable_unchecked` future - /// compat lint: - /// ``` - /// fn foo() { - /// let _bar = [1_u8; size_of::<*mut T>()]; - /// } - /// ``` - // FIXME(generic_const_exprs): Remove this bodge once that feature is stable. - forbid_generic: bool, - /// Is this within an `impl Foo for bar`? is_trait_impl: bool, }, @@ -910,8 +887,8 @@ impl Res { Res::PrimTy(id) => Res::PrimTy(id), Res::Local(id) => Res::Local(map(id)), Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ }, - Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => { - Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } + Res::SelfTyAlias { alias_to, is_trait_impl } => { + Res::SelfTyAlias { alias_to, is_trait_impl } } Res::ToolMod => Res::ToolMod, Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind), @@ -926,8 +903,8 @@ impl Res { Res::PrimTy(id) => Res::PrimTy(id), Res::Local(id) => Res::Local(map(id)?), Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ }, - Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => { - Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } + Res::SelfTyAlias { alias_to, is_trait_impl } => { + Res::SelfTyAlias { alias_to, is_trait_impl } } Res::ToolMod => Res::ToolMod, Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_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 48b2b80c8af3..7a11a808f83e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2149,7 +2149,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); self.check_param_uses_if_mcg(tcx.types.self_param, span, false) } - Res::SelfTyAlias { alias_to: def_id, forbid_generic: _, .. } => { + Res::SelfTyAlias { alias_to: def_id, .. } => { // `Self` in impl (we know the concrete type). assert_eq!(opt_self_ty, None); // Try to evaluate any array length constants. diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index f4a594a4731d..4d9702d9e0d5 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1332,7 +1332,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &mut self, rib_index: usize, rib_ident: Ident, - mut res: Res, + res: Res, finalize: Option, original_rib_ident_def: Ident, all_ribs: &[Rib<'ra>], @@ -1485,44 +1485,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } RibKind::ConstantItem(trivial, _) => { - if let ConstantHasGenerics::No(cause) = trivial { - // HACK(min_const_generics): If we encounter `Self` in an anonymous - // constant we can't easily tell if it's generic at this stage, so - // we instead remember this and then enforce the self type to be - // concrete later on. - if let Res::SelfTyAlias { - alias_to: def, - forbid_generic: _, - is_trait_impl, - } = res - { - res = Res::SelfTyAlias { - alias_to: def, - forbid_generic: true, - is_trait_impl, - } - } else { - if let Some(span) = finalize { - let error = match cause { - NoConstantGenericsReason::IsEnumDiscriminant => { - ResolutionError::ParamInEnumDiscriminant { - name: rib_ident.name, - param_kind: ParamKindInEnumDiscriminant::Type, - } + if let ConstantHasGenerics::No(cause) = trivial + && !matches!(res, Res::SelfTyAlias { .. }) + { + if let Some(span) = finalize { + let error = match cause { + NoConstantGenericsReason::IsEnumDiscriminant => { + ResolutionError::ParamInEnumDiscriminant { + name: rib_ident.name, + param_kind: ParamKindInEnumDiscriminant::Type, } - NoConstantGenericsReason::NonTrivialConstArg => { - ResolutionError::ParamInNonTrivialAnonConst { - name: rib_ident.name, - param_kind: - ParamKindInNonTrivialAnonConst::Type, - } + } + NoConstantGenericsReason::NonTrivialConstArg => { + ResolutionError::ParamInNonTrivialAnonConst { + name: rib_ident.name, + param_kind: ParamKindInNonTrivialAnonConst::Type, } - }; - let _: ErrorGuaranteed = self.report_error(span, error); - } - - return Res::Err; + } + }; + let _: ErrorGuaranteed = self.report_error(span, error); } + + return Res::Err; } continue; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index dd80f5da508c..2630e2c811f7 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2655,11 +2655,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |this| { let item_def_id = this.r.local_def_id(item.id).to_def_id(); this.with_self_rib( - Res::SelfTyAlias { - alias_to: item_def_id, - forbid_generic: false, - is_trait_impl: false, - }, + Res::SelfTyAlias { alias_to: item_def_id, is_trait_impl: false }, |this| { visit::walk_item(this, item); }, @@ -3368,8 +3364,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let item_def_id = item_def_id.to_def_id(); let res = Res::SelfTyAlias { alias_to: item_def_id, - forbid_generic: false, - is_trait_impl: trait_id.is_some() + is_trait_impl: trait_id.is_some(), }; this.with_self_rib(res, |this| { if let Some(of_trait) = of_trait { From 3fc32260694a0e71484ba5251bc4e9c22f74bac7 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sat, 3 Jan 2026 10:24:02 +0900 Subject: [PATCH 1543/3801] Move `pattern_types` and `unqualified_local_imports` to the tracking issue group --- compiler/rustc_feature/src/unstable.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 94e861787fc6..f64702fc44b0 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -239,8 +239,6 @@ declare_features! ( (internal, negative_bounds, "1.71.0", None), /// Set the maximum pattern complexity allowed (not limited by default). (internal, pattern_complexity_limit, "1.78.0", None), - /// Allows using pattern types. - (internal, pattern_types, "1.79.0", Some(123646)), /// Allows using `#[prelude_import]` on glob `use` items. (internal, prelude_import, "1.2.0", None), /// Used to identify crates that contain the profiler runtime. @@ -251,8 +249,6 @@ declare_features! ( (internal, staged_api, "1.0.0", None), /// Added for testing unstable lints; perma-unstable. (internal, test_unstable_lint, "1.60.0", None), - /// Helps with formatting for `group_imports = "StdExternalCrate"`. - (unstable, unqualified_local_imports, "1.83.0", Some(138299)), /// Use for stable + negative coherence and strict coherence depending on trait's /// rustc_strict_coherence value. (unstable, with_negative_coherence, "1.60.0", None), @@ -293,6 +289,8 @@ declare_features! ( (internal, needs_panic_runtime, "1.10.0", Some(32837)), /// Allows using the `#![panic_runtime]` attribute. (internal, panic_runtime, "1.10.0", Some(32837)), + /// Allows using pattern types. + (internal, pattern_types, "1.79.0", Some(123646)), /// Allows using `#[rustc_allow_const_fn_unstable]`. /// This is an attribute on `const fn` for the same /// purpose as `#[allow_internal_unstable]`. @@ -311,6 +309,8 @@ declare_features! ( (unstable, structural_match, "1.8.0", Some(31434)), /// Allows using the `rust-call` ABI. (unstable, unboxed_closures, "1.0.0", Some(29625)), + /// Helps with formatting for `group_imports = "StdExternalCrate"`. + (unstable, unqualified_local_imports, "1.83.0", Some(138299)), // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! From a2fcb0de187664d27aa6c312585bcf64ff1c909a Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Sat, 3 Jan 2026 12:50:38 +1030 Subject: [PATCH 1544/3801] fix: add `CHECK` directives to `ret` comments and be more pervasive with directive contents --- .../issues/multiple-option-or-permutations.rs | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs index 0ea7ef9a0f7e..9ec4ec8eeb15 100644 --- a/tests/codegen-llvm/issues/multiple-option-or-permutations.rs +++ b/tests/codegen-llvm/issues/multiple-option-or-permutations.rs @@ -10,11 +10,11 @@ use std::num::NonZero; #[no_mangle] pub fn or_match_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-DAG: select i1 %0 - // CHECK-DAG: or i1 %0 - // CHECK-NEXT: insertvalue { i1, i8 } - // CHECK-NEXT: insertvalue { i1, i8 } - // ret { i1, i8 } + // CHECK-DAG: [[A_OR_B:%.+]] = select i1 %0, i8 %1, i8 %optb.1 + // CHECK-DAG: [[IS_SOME:%.+]] = or i1 {{%0, %optb.0|%optb.0, %0}} + // CHECK-NEXT: [[FLAG:%.+]] = insertvalue { i1, i8 } poison, i1 [[IS_SOME]], 0 + // CHECK-NEXT: [[R:%.+]] = insertvalue { i1, i8 } [[FLAG]], i8 [[A_OR_B]], 1 + // CHECK: ret { i1, i8 } [[R]] match opta { Some(x) => Some(x), None => optb, @@ -26,11 +26,11 @@ pub fn or_match_u8(opta: Option, optb: Option) -> Option { #[no_mangle] pub fn or_match_alt_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-DAG: select i1 %opta.0, i8 %opta.1, i8 %optb.1 - // CHECK-DAG: or i1 {{%opta.0, %optb.0|%optb.0, %opta.0}} - // CHECK-NEXT: insertvalue { i1, i8 } - // CHECK-NEXT: insertvalue { i1, i8 } - // ret { i1, i8 } + // CHECK-DAG: [[A_OR_B:%.+]] = select i1 %opta.0, i8 %opta.1, i8 %optb.1 + // CHECK-DAG: [[IS_SOME:%.+]] = or i1 {{%opta.0, %optb.0|%optb.0, %opta.0}} + // CHECK-NEXT: [[FLAG:%.+]] = insertvalue { i1, i8 } poison, i1 [[IS_SOME]], 0 + // CHECK-NEXT: [[R:%.+]] = insertvalue { i1, i8 } [[FLAG]], i8 [[A_OR_B]], 1 + // CHECK: ret { i1, i8 } [[R]] match opta { Some(_) => opta, None => optb, @@ -42,11 +42,11 @@ pub fn or_match_alt_u8(opta: Option, optb: Option) -> Option { #[no_mangle] pub fn option_or_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-DAG: select i1 - // CHECK-DAG: or i1 - // CHECK-NEXT: insertvalue { i1, i8 } - // CHECK-NEXT: insertvalue { i1, i8 } - // ret { i1, i8 } + // CHECK-DAG: [[A_OR_B:%.+]] = select i1 %opta.0, i8 %opta.1, i8 %optb.1 + // CHECK-DAG: [[IS_SOME:%.+]] = or i1 {{%opta.0, %optb.0|%optb.0, %opta.0}} + // CHECK-NEXT: [[FLAG:%.+]] = insertvalue { i1, i8 } poison, i1 [[IS_SOME]], 0 + // CHECK-NEXT: [[R:%.+]] = insertvalue { i1, i8 } [[FLAG]], i8 [[A_OR_B]], 1 + // CHECK: ret { i1, i8 } [[R]] opta.or(optb) } @@ -55,11 +55,11 @@ pub fn option_or_u8(opta: Option, optb: Option) -> Option { #[no_mangle] pub fn if_some_u8(opta: Option, optb: Option) -> Option { // CHECK: start: - // CHECK-DAG: select i1 - // CHECK-DAG: or i1 - // CHECK-NEXT: insertvalue { i1, i8 } - // CHECK-NEXT: insertvalue { i1, i8 } - // ret { i1, i8 } + // CHECK-DAG: [[A_OR_B:%.+]] = select i1 %opta.0, i8 %opta.1, i8 %optb.1 + // CHECK-DAG: [[IS_SOME:%.+]] = or i1 {{%opta.0, %optb.0|%optb.0, %opta.0}} + // CHECK-NEXT: [[FLAG:%.+]] = insertvalue { i1, i8 } poison, i1 [[IS_SOME]], 0 + // CHECK-NEXT: [[R:%.+]] = insertvalue { i1, i8 } [[FLAG]], i8 [[A_OR_B]], 1 + // CHECK: ret { i1, i8 } [[R]] if opta.is_some() { opta } else { optb } } @@ -70,9 +70,9 @@ pub fn if_some_u8(opta: Option, optb: Option) -> Option { #[no_mangle] pub fn or_match_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: - // CHECK-NEXT: trunc i16 %0 to i1 - // CHECK-NEXT: select i1 %2, i16 %0, i16 %1 - // ret i16 + // CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 + // CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // CHECK: ret i16 [[R]] match opta { Some(x) => Some(x), None => optb, @@ -84,9 +84,9 @@ pub fn or_match_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option #[no_mangle] pub fn or_match_slice_alt_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: - // CHECK-NEXT: trunc i16 %0 to i1 - // CHECK-NEXT: select i1 %2, i16 %0, i16 %1 - // ret i16 + // CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 + // CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // CHECK: ret i16 [[R]] match opta { Some(_) => opta, None => optb, @@ -98,9 +98,9 @@ pub fn or_match_slice_alt_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Op #[no_mangle] pub fn option_or_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: - // CHECK-NEXT: trunc i16 %0 to i1 - // CHECK-NEXT: select i1 %2, i16 %0, i16 %1 - // ret i16 + // CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 + // CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // CHECK: ret i16 [[R]] opta.or(optb) } @@ -109,9 +109,9 @@ pub fn option_or_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Optio #[no_mangle] pub fn if_some_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option<[u8; 1]> { // CHECK: start: - // CHECK-NEXT: trunc i16 %0 to i1 - // CHECK-NEXT: select i1 %2, i16 %0, i16 %1 - // ret i16 + // CHECK-NEXT: [[SOME_A:%.+]] = trunc i16 %0 to i1 + // CHECK-NEXT: [[R:%.+]] = select i1 [[SOME_A]], i16 %0, i16 %1 + // CHECK: ret i16 [[R]] if opta.is_some() { opta } else { optb } } @@ -122,9 +122,9 @@ pub fn if_some_slice_u8(opta: Option<[u8; 1]>, optb: Option<[u8; 1]>) -> Option< #[no_mangle] pub fn or_match_nz_u8(opta: Option>, optb: Option>) -> Option> { // CHECK: start: - // CHECK-NEXT: [[NOT_A:%.*]] = icmp eq i8 %0, 0 - // CHECK-NEXT: select i1 [[NOT_A]], i8 %optb, i8 %0 - // ret i8 + // CHECK-NEXT: [[NOT_A:%.+]] = icmp eq i8 %0, 0 + // CHECK-NEXT: [[R:%.+]] = select i1 [[NOT_A]], i8 %optb, i8 %0 + // CHECK: ret i8 [[R]] match opta { Some(x) => Some(x), None => optb, @@ -139,9 +139,9 @@ pub fn or_match_alt_nz_u8( optb: Option>, ) -> Option> { // CHECK: start: - // CHECK-NEXT: [[NOT_A:%.*]] = icmp eq i8 %opta, 0 - // CHECK-NEXT: select i1 [[NOT_A]], i8 %optb, i8 %opta - // ret i8 + // CHECK-NEXT: [[NOT_A:%.+]] = icmp eq i8 %opta, 0 + // CHECK-NEXT: [[R:%.+]] = select i1 [[NOT_A]], i8 %optb, i8 %opta + // CHECK: ret i8 [[R]] match opta { Some(_) => opta, None => optb, @@ -156,9 +156,9 @@ pub fn option_or_nz_u8( optb: Option>, ) -> Option> { // CHECK: start: - // CHECK-NEXT: [[NOT_A:%.*]] = icmp eq i8 %opta, 0 - // CHECK-NEXT: select i1 [[NOT_A]], i8 %optb, i8 %opta - // ret i8 + // CHECK-NEXT: [[NOT_A:%.+]] = icmp eq i8 %opta, 0 + // CHECK-NEXT: [[R:%.+]] = select i1 [[NOT_A]], i8 %optb, i8 %opta + // CHECK: ret i8 [[R]] opta.or(optb) } @@ -167,8 +167,8 @@ pub fn option_or_nz_u8( #[no_mangle] pub fn if_some_nz_u8(opta: Option>, optb: Option>) -> Option> { // CHECK: start: - // CHECK-NEXT: [[NOT_A:%.*]] = icmp eq i8 %opta, 0 - // CHECK-NEXT: select i1 [[NOT_A]], i8 %optb, i8 %opta - // ret i8 + // CHECK-NEXT: [[NOT_A:%.+]] = icmp eq i8 %opta, 0 + // CHECK-NEXT: [[R:%.+]] = select i1 [[NOT_A]], i8 %optb, i8 %opta + // CHECK: ret i8 [[R]] if opta.is_some() { opta } else { optb } } From 6326896b0c42eea27125b78fbed455a035e5e064 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 09:12:32 +0530 Subject: [PATCH 1545/3801] emit same info via localfilename and filename --- .../rust-analyzer/crates/load-cargo/src/lib.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 023253f23f42..4ffc8383b620 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -563,20 +563,10 @@ impl ProcMacroExpander for Expander { let source_root_id = db.file_source_root(file).source_root_id(db); let source_root = db.source_root(source_root_id).source_root(db); - let path = source_root.path_for_file(&file); - - let name = path - .and_then(|p| p.as_path()) - .and_then(|p| p.file_name()) - .map(|n| n.to_owned()) - .or_else(|| { - path.and_then(|p| { - p.name_and_extension().map(|(name, ext)| match ext { - Some(ext) => format!("{name}.{ext}"), - None => name.into(), - }) - }) - }) + let name = source_root + .path_for_file(&file) + .and_then(|path| path.as_path()) + .and_then(|path| path.file_name().map(|filename| filename.to_owned())) .unwrap_or_default(); Ok(SubResponse::FileNameResult { name }) From b80a3ea6d689e4cd6b619c67cfac1c630de67e2f Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 3 Jan 2026 04:57:40 +0000 Subject: [PATCH 1546/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to e8f3cfc0de70bf82583591f6656e1fba3140253e. --- 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 d32b6d0d2fc7..f22aff761e8d 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -7fefa09b90ca57b8a0e0e4717d672d38a0ae58b5 +e8f3cfc0de70bf82583591f6656e1fba3140253e From a8c23c86f01b0f8f9408ffed8ca0688453223f92 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 2 Jan 2026 23:03:51 -0500 Subject: [PATCH 1547/3801] triagebot: Add a mention for `dec2flt`, `flt2dec`, and `fmt/num` --- triagebot.toml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index fb6660b9dd03..fbb2bac2267b 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1059,6 +1059,18 @@ gets adapted for the changes, if necessary. """ cc = ["@rust-lang/miri", "@RalfJung", "@oli-obk", "@lcnr"] +[mentions."library/core/src/num/dec2flt"] +message = "Some changes occurred in float parsing" +cc = ["@tgross35"] + +[mentions."library/core/src/num/flt2dec"] +message = "Some changes occurred in float printing" +cc = ["@tgross35"] + +[mentions."library/core/src/fmt/num.rs"] +message = "Some changes occurred in integer formatting" +cc = ["@tgross35"] + [mentions."library/portable-simd"] message = """ Portable SIMD is developed in its own repository. If possible, consider \ From d79fa3ca3d8768077766bf9109225a65cb01e600 Mon Sep 17 00:00:00 2001 From: vsriram Date: Sat, 3 Jan 2026 12:58:36 +0530 Subject: [PATCH 1548/3801] Fixed edit-url-template by pointing to main instead of HEAD in both unstable book and the rustc book --- src/doc/rustc/book.toml | 2 +- src/doc/unstable-book/book.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/book.toml b/src/doc/rustc/book.toml index 9a7c28525f0e..565f6247dcb2 100644 --- a/src/doc/rustc/book.toml +++ b/src/doc/rustc/book.toml @@ -3,7 +3,7 @@ title = "The rustc book" [output.html] git-repository-url = "https://github.com/rust-lang/rust/tree/HEAD/src/doc/rustc" -edit-url-template = "https://github.com/rust-lang/rust/edit/HEAD/src/doc/rustc/{path}" +edit-url-template = "https://github.com/rust-lang/rust/edit/main/src/doc/rustc/{path}" [output.html.search] use-boolean-and = true diff --git a/src/doc/unstable-book/book.toml b/src/doc/unstable-book/book.toml index c357949f6c2e..8a3d11499cdd 100644 --- a/src/doc/unstable-book/book.toml +++ b/src/doc/unstable-book/book.toml @@ -3,4 +3,4 @@ title = "The Rust Unstable Book" [output.html] git-repository-url = "https://github.com/rust-lang/rust/tree/HEAD/src/doc/unstable-book" -edit-url-template = "https://github.com/rust-lang/rust/edit/HEAD/src/doc/unstable-book/{path}" +edit-url-template = "https://github.com/rust-lang/rust/edit/main/src/doc/unstable-book/{path}" From c56c36ea7d1e0f15c41bfaf0dfe62b8e7954758e Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 14:58:47 +0530 Subject: [PATCH 1549/3801] use fullpath instead of filename --- src/tools/rust-analyzer/crates/load-cargo/src/lib.rs | 12 ++++++------ .../proc-macro-api/src/bidirectional_protocol/msg.rs | 8 ++++---- .../crates/proc-macro-srv-cli/src/main_loop.rs | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 4ffc8383b620..e01ce0b129da 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -540,7 +540,7 @@ impl ProcMacroExpander for Expander { current_dir: String, ) -> Result { let mut cb = |req| match req { - SubRequest::LocalFileName { file_id } => { + SubRequest::LocalFilePath { file_id } => { let file = FileId::from_raw(file_id); let source_root_id = db.file_source_root(file).source_root_id(db); let source_root = db.source_root(source_root_id).source_root(db); @@ -548,9 +548,9 @@ impl ProcMacroExpander for Expander { let name = source_root .path_for_file(&file) .and_then(|path| path.as_path()) - .and_then(|path| path.file_name().map(|filename| filename.to_owned())); + .map(|path| path.to_string()); - Ok(SubResponse::LocalFileNameResult { name }) + Ok(SubResponse::LocalFilePathResult { name }) } SubRequest::SourceText { file_id, start, end } => { let file = FileId::from_raw(file_id); @@ -558,7 +558,7 @@ impl ProcMacroExpander for Expander { let slice = text.get(start as usize..end as usize).map(ToOwned::to_owned); Ok(SubResponse::SourceTextResult { text: slice }) } - SubRequest::FileName { file_id } => { + SubRequest::FilePath { file_id } => { let file = FileId::from_raw(file_id); let source_root_id = db.file_source_root(file).source_root_id(db); let source_root = db.source_root(source_root_id).source_root(db); @@ -566,10 +566,10 @@ impl ProcMacroExpander for Expander { let name = source_root .path_for_file(&file) .and_then(|path| path.as_path()) - .and_then(|path| path.file_name().map(|filename| filename.to_owned())) + .map(|path| path.to_string()) .unwrap_or_default(); - Ok(SubResponse::FileNameResult { name }) + Ok(SubResponse::FilePathResult { name }) } }; match self.0.expand( diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 2819a92fe33a..558954f7619d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -10,16 +10,16 @@ use crate::{ #[derive(Debug, Serialize, Deserialize)] pub enum SubRequest { - FileName { file_id: u32 }, + FilePath { file_id: u32 }, SourceText { file_id: u32, start: u32, end: u32 }, - LocalFileName { file_id: u32 }, + LocalFilePath { file_id: u32 }, } #[derive(Debug, Serialize, Deserialize)] pub enum SubResponse { - FileNameResult { name: String }, + FilePathResult { name: String }, SourceTextResult { text: Option }, - LocalFileNameResult { name: Option }, + LocalFilePathResult { name: Option }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 77cb8760a100..8fe3e93e4702 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -186,9 +186,9 @@ impl<'a, C: Codec> ProcMacroClientHandle<'a, C> { impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { fn file(&mut self, file_id: u32) -> String { - match self.roundtrip(bidirectional::SubRequest::FileName { file_id }) { + match self.roundtrip(bidirectional::SubRequest::FilePath { file_id }) { Some(bidirectional::BidirectionalMessage::SubResponse( - bidirectional::SubResponse::FileNameResult { name }, + bidirectional::SubResponse::FilePathResult { name }, )) => name, _ => String::new(), } @@ -204,9 +204,9 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl } fn local_file(&mut self, file_id: u32) -> Option { - match self.roundtrip(bidirectional::SubRequest::LocalFileName { file_id }) { + match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id }) { Some(bidirectional::BidirectionalMessage::SubResponse( - bidirectional::SubResponse::LocalFileNameResult { name }, + bidirectional::SubResponse::LocalFilePathResult { name }, )) => name, _ => None, } From 7af3130d257bf06c4cb4ff4e160d69d8180b9c60 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 3 Jan 2026 10:47:41 +0100 Subject: [PATCH 1550/3801] perf: Only compute lang items for `#![feature(lang_items)]` crates --- .../crates/hir-def/src/lang_item.rs | 4 ++ .../crates/hir-ty/src/consteval/tests.rs | 3 ++ .../crates/hir-ty/src/tests/incremental.rs | 37 +++---------------- .../crates/hir-ty/src/tests/patterns.rs | 19 ++++++---- .../crates/hir-ty/src/tests/regression.rs | 1 + .../hir-ty/src/tests/regression/new_solver.rs | 1 + .../crates/hir-ty/src/tests/simple.rs | 36 ++++++++++-------- .../ide-completion/src/tests/flyimport.rs | 2 +- .../handlers/trait_impl_incorrect_safety.rs | 1 + .../crates/ide/src/hover/tests.rs | 1 + .../crates/ide/src/inlay_hints/bounds.rs | 2 +- .../crates/intern/src/symbol/symbols.rs | 1 + .../crates/test-utils/src/minicore.rs | 1 + 13 files changed, 51 insertions(+), 58 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index d3f4480b207e..eba4d87ec9f8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -40,6 +40,10 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option i32 { "trait_environment_query", "lang_items", "crate_lang_items", - "AttrFlags::query_", - "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", "expr_scopes_shim", "InferenceResult::for_body_", "function_signature_shim", "function_signature_with_source_map_shim", + "AttrFlags::query_", "body_shim", "body_with_source_map_shim", "trait_environment_query", @@ -149,6 +148,7 @@ fn baz() -> i32 { "InferenceResult::for_body_", "function_signature_shim", "function_signature_with_source_map_shim", + "AttrFlags::query_", "body_shim", "body_with_source_map_shim", "trait_environment_query", @@ -197,13 +197,13 @@ fn baz() -> i32 { "body_with_source_map_shim", "body_shim", "AttrFlags::query_", - "AttrFlags::query_", "function_signature_with_source_map_shim", "function_signature_shim", "body_with_source_map_shim", "body_shim", "InferenceResult::for_body_", "expr_scopes_shim", + "AttrFlags::query_", "function_signature_with_source_map_shim", "function_signature_shim", "body_with_source_map_shim", @@ -245,8 +245,6 @@ $0", "TraitImpls::for_crate_", "lang_items", "crate_lang_items", - "AttrFlags::query_", - "AttrFlags::query_", ] "#]], ); @@ -284,9 +282,6 @@ pub struct NewStruct { "crate_local_def_map", "TraitImpls::for_crate_", "crate_lang_items", - "AttrFlags::query_", - "AttrFlags::query_", - "AttrFlags::query_", ] "#]], ); @@ -324,8 +319,6 @@ $0", "TraitImpls::for_crate_", "lang_items", "crate_lang_items", - "AttrFlags::query_", - "AttrFlags::query_", ] "#]], ); @@ -364,12 +357,6 @@ pub enum SomeEnum { "crate_local_def_map", "TraitImpls::for_crate_", "crate_lang_items", - "AttrFlags::query_", - "AttrFlags::query_", - "AttrFlags::query_", - "EnumVariants::of_", - "AttrFlags::query_", - "AttrFlags::query_", ] "#]], ); @@ -407,8 +394,6 @@ $0", "TraitImpls::for_crate_", "lang_items", "crate_lang_items", - "AttrFlags::query_", - "AttrFlags::query_", ] "#]], ); @@ -444,8 +429,6 @@ fn bar() -> f32 { "crate_local_def_map", "TraitImpls::for_crate_", "crate_lang_items", - "AttrFlags::query_", - "AttrFlags::query_", ] "#]], ); @@ -487,9 +470,6 @@ $0", "TraitImpls::for_crate_", "lang_items", "crate_lang_items", - "AttrFlags::query_", - "AttrFlags::query_", - "AttrFlags::query_", ] "#]], ); @@ -533,12 +513,6 @@ impl SomeStruct { "crate_local_def_map", "TraitImpls::for_crate_", "crate_lang_items", - "AttrFlags::query_", - "ImplItems::of_", - "AttrFlags::query_", - "AttrFlags::query_", - "AttrFlags::query_", - "AttrFlags::query_", ] "#]], ); @@ -610,7 +584,6 @@ fn main() { "trait_environment_query", "lang_items", "crate_lang_items", - "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", @@ -623,6 +596,7 @@ fn main() { "expr_scopes_shim", "struct_signature_shim", "struct_signature_with_source_map_shim", + "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "value_ty_query", "InherentImpls::for_crate_", @@ -702,8 +676,6 @@ fn main() { "body_with_source_map_shim", "body_shim", "crate_lang_items", - "AttrFlags::query_", - "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "GenericPredicates::query_with_diagnostics_", "ImplTraits::return_type_impl_traits_", @@ -713,6 +685,7 @@ fn main() { "ImplTraits::return_type_impl_traits_", "expr_scopes_shim", "struct_signature_with_source_map_shim", + "AttrFlags::query_", "GenericPredicates::query_with_diagnostics_", "InherentImpls::for_crate_", "callable_item_signature_query", diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs index c312b167596f..0b776938c5b3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs @@ -794,6 +794,8 @@ fn slice_tail_pattern() { fn box_pattern() { check_infer( r#" + #![feature(lang_items)] + pub struct Global; #[lang = "owned_box"] pub struct Box(T); @@ -805,13 +807,13 @@ fn box_pattern() { } "#, expect![[r#" - 83..89 'params': Box - 101..155 '{ ... } }': () - 107..153 'match ... }': () - 113..119 'params': Box - 130..141 'box integer': Box - 134..141 'integer': i32 - 145..147 '{}': () + 108..114 'params': Box + 126..180 '{ ... } }': () + 132..178 'match ... }': () + 138..144 'params': Box + 155..166 'box integer': Box + 159..166 'integer': i32 + 170..172 '{}': () "#]], ); check_infer( @@ -831,7 +833,6 @@ fn box_pattern() { 76..122 'match ... }': () 82..88 'params': Box 99..110 'box integer': Box - 103..110 'integer': i32 114..116 '{}': () "#]], ); @@ -1142,6 +1143,7 @@ fn my_fn(#[cfg(feature = "feature")] u8: u8, u32: u32) {} fn var_args() { check_types( r#" +#![feature(lang_items)] #[lang = "va_list"] pub struct VaListImpl<'f>; fn my_fn(foo: ...) {} @@ -1156,6 +1158,7 @@ fn my_fn2(bar: u32, foo: ...) {} fn var_args_cond() { check_types( r#" +#![feature(lang_items)] #[lang = "va_list"] pub struct VaListImpl<'f>; fn my_fn(bar: u32, #[cfg(FALSE)] foo: ..., #[cfg(not(FALSE))] foo: u32) { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index f03f8d754f2a..c805f030446c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -2374,6 +2374,7 @@ fn rust_destruct_option_clone() { check_types( r#" //- minicore: option, drop +#![feature(lang_items)] fn test(o: &Option) { o.my_clone(); //^^^^^^^^^^^^ Option diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs index e11cc85e7ff1..a4554673cdd5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs @@ -234,6 +234,7 @@ fn main() { // toolchains <= 1.88.0, before sized-hierarchy. check_no_mismatches( r#" +#![feature(lang_items)] #[lang = "sized"] pub trait Sized {} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index db557b75071f..6367521841ab 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs @@ -2702,6 +2702,8 @@ fn box_into_vec() { check_infer( r#" //- /core.rs crate:core +#![feature(lang_items)] + #[lang = "sized"] pub trait Sized {} @@ -2745,22 +2747,22 @@ struct Astruct; impl B for Astruct {} "#, expect![[r#" - 614..618 'self': Box<[T], A> - 647..679 '{ ... }': Vec - 693..863 '{ ...])); }': () - 703..706 'vec': Vec - 709..724 '<[_]>::into_vec': fn into_vec(Box<[i32], Global>) -> Vec - 709..755 '<[_]>:...i32]))': Vec - 725..754 '#[rust...1i32])': Box<[i32; 1], Global> - 747..753 '[1i32]': [i32; 1] - 748..752 '1i32': i32 - 765..766 'v': Vec, Global> - 786..803 '<[_]> ...to_vec': fn into_vec, Global>(Box<[Box], Global>) -> Vec, Global> - 786..860 '<[_]> ...ct)]))': Vec, Global> - 804..859 '#[rust...uct)])': Box<[Box; 1], Global> - 826..858 '[#[rus...ruct)]': [Box; 1] - 827..857 '#[rust...truct)': Box - 849..856 'Astruct': Astruct + 639..643 'self': Box<[T], A> + 672..704 '{ ... }': Vec + 718..888 '{ ...])); }': () + 728..731 'vec': Vec + 734..749 '<[_]>::into_vec': fn into_vec(Box<[i32], Global>) -> Vec + 734..780 '<[_]>:...i32]))': Vec + 750..779 '#[rust...1i32])': Box<[i32; 1], Global> + 772..778 '[1i32]': [i32; 1] + 773..777 '1i32': i32 + 790..791 'v': Vec, Global> + 811..828 '<[_]> ...to_vec': fn into_vec, Global>(Box<[Box], Global>) -> Vec, Global> + 811..885 '<[_]> ...ct)]))': Vec, Global> + 829..884 '#[rust...uct)])': Box<[Box; 1], Global> + 851..883 '[#[rus...ruct)]': [Box; 1] + 852..882 '#[rust...truct)': Box + 874..881 'Astruct': Astruct "#]], ) } @@ -3647,6 +3649,8 @@ fn main() { fn cstring_literals() { check_types( r#" +#![feature(lang_items)] + #[lang = "CStr"] pub struct CStr; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index 2912457da1f7..797df3f163da 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -781,9 +781,9 @@ fn main() { } "#, expect![[r#" - me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED + me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED "#]], ); } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_incorrect_safety.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_incorrect_safety.rs index 3414e972d5c9..c5b2f499d306 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_incorrect_safety.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_incorrect_safety.rs @@ -64,6 +64,7 @@ unsafe trait Unsafe {} fn drop_may_dangle() { check_diagnostics( r#" +#![feature(lang_items)] #[lang = "drop"] trait Drop {} struct S; diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index f42d3cf0dc41..0b518021e39e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -4089,6 +4089,7 @@ fn foo() { let fo$0o = async { S }; } //- /core.rs crate:core +#![feature(lang_items)] pub mod future { #[lang = "future_trait"] pub trait Future {} diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs index c9fbdf3ae754..045559fd7f46 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs @@ -143,7 +143,7 @@ fn foo() {} file_id: FileId( 1, ), - range: 446..451, + range: 470..475, }, ), ), diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 3e325b2f990d..b6efc599f181 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -297,6 +297,7 @@ define_symbols! { iterator, keyword, lang, + lang_items, le, Left, len, diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index b7c09391ec37..01274a9835f4 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs @@ -80,6 +80,7 @@ //! offset_of: #![rustc_coherence_is_core] +#![feature(lang_items)] pub mod marker { // region:sized From 0e5a4fb302aafc1b1a0677b7ffb7eb57d8cea9ab Mon Sep 17 00:00:00 2001 From: joboet Date: Sat, 3 Jan 2026 11:46:06 +0100 Subject: [PATCH 1551/3801] std: remove manual bindings on NetBSD --- .../std/src/sys/pal/unix/thread_parking.rs | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread_parking.rs b/library/std/src/sys/pal/unix/thread_parking.rs index bef8b4fb3639..6c3d04ceab21 100644 --- a/library/std/src/sys/pal/unix/thread_parking.rs +++ b/library/std/src/sys/pal/unix/thread_parking.rs @@ -2,24 +2,11 @@ // separate modules for each platform. #![cfg(target_os = "netbsd")] -use libc::{_lwp_self, CLOCK_MONOTONIC, c_long, clockid_t, lwpid_t, time_t, timespec}; +use libc::{_lwp_park, _lwp_self, _lwp_unpark, CLOCK_MONOTONIC, c_long, lwpid_t, time_t, timespec}; -use crate::ffi::{c_int, c_void}; use crate::ptr; use crate::time::Duration; -unsafe extern "C" { - fn ___lwp_park60( - clock_id: clockid_t, - flags: c_int, - ts: *mut timespec, - unpark: lwpid_t, - hint: *const c_void, - unparkhint: *const c_void, - ) -> c_int; - fn _lwp_unpark(lwp: lwpid_t, hint: *const c_void) -> c_int; -} - pub type ThreadId = lwpid_t; #[inline] @@ -30,7 +17,7 @@ pub fn current() -> ThreadId { #[inline] pub fn park(hint: usize) { unsafe { - ___lwp_park60(0, 0, ptr::null_mut(), 0, ptr::without_provenance(hint), ptr::null()); + _lwp_park(0, 0, ptr::null_mut(), 0, ptr::without_provenance(hint), ptr::null_mut()); } } @@ -45,13 +32,13 @@ pub fn park_timeout(dur: Duration, hint: usize) { // Timeout needs to be mutable since it is modified on NetBSD 9.0 and // above. unsafe { - ___lwp_park60( + _lwp_park( CLOCK_MONOTONIC, 0, &mut timeout, 0, ptr::without_provenance(hint), - ptr::null(), + ptr::null_mut(), ); } } From b2e6e0374def640e09393a93b8a555925a7b8fe3 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Sat, 3 Jan 2026 11:17:29 +0000 Subject: [PATCH 1552/3801] mutex.rs: remove needless-maybe-unsized bounds --- library/std/src/sync/nonpoison/mutex.rs | 2 +- library/std/src/sync/poison/mutex.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sync/nonpoison/mutex.rs b/library/std/src/sync/nonpoison/mutex.rs index ed3f8cfed821..307bf8eaf512 100644 --- a/library/std/src/sync/nonpoison/mutex.rs +++ b/library/std/src/sync/nonpoison/mutex.rs @@ -422,7 +422,7 @@ impl From for Mutex { } #[unstable(feature = "nonpoison_mutex", issue = "134645")] -impl Default for Mutex { +impl Default for Mutex { /// Creates a `Mutex`, with the `Default` value for T. fn default() -> Mutex { Mutex::new(Default::default()) diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 7f9e5fe62516..6eccd8a875ed 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -688,7 +688,7 @@ impl From for Mutex { } #[stable(feature = "mutex_default", since = "1.10.0")] -impl Default for Mutex { +impl Default for Mutex { /// Creates a `Mutex`, with the `Default` value for T. fn default() -> Mutex { Mutex::new(Default::default()) From 47798e261e13a905c6acae122a6111c8f1fd5eae Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Sat, 3 Jan 2026 11:36:25 +0000 Subject: [PATCH 1553/3801] vec in-place-drop: avoid creating an intermediate slice --- library/alloc/src/vec/in_place_drop.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/alloc/src/vec/in_place_drop.rs b/library/alloc/src/vec/in_place_drop.rs index 997c4c7525b5..c8cc758ac15c 100644 --- a/library/alloc/src/vec/in_place_drop.rs +++ b/library/alloc/src/vec/in_place_drop.rs @@ -1,6 +1,5 @@ use core::marker::PhantomData; use core::ptr::{self, NonNull, drop_in_place}; -use core::slice::{self}; use crate::alloc::Global; use crate::raw_vec::RawVec; @@ -22,7 +21,7 @@ impl Drop for InPlaceDrop { #[inline] fn drop(&mut self) { unsafe { - ptr::drop_in_place(slice::from_raw_parts_mut(self.inner, self.len())); + ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.inner, self.len())); } } } From c99f9c249b017c6909ea44bba6fe3efcd56208ed Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 19:04:35 +0530 Subject: [PATCH 1554/3801] Replace sourcedb with expanddb --- .../hir-def/src/macro_expansion_tests/mod.rs | 4 ++-- .../crates/hir-expand/src/proc_macro.rs | 4 ++-- .../crates/load-cargo/src/lib.rs | 19 +++++++++--------- .../crates/test-fixture/src/lib.rs | 20 +++++++++---------- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index 3f136bc59172..c63f2c1d786b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -16,7 +16,7 @@ mod proc_macros; use std::{any::TypeId, iter, ops::Range, sync}; -use base_db::{RootQueryDb, SourceDatabase}; +use base_db::RootQueryDb; use expect_test::Expect; use hir_expand::{ AstId, ExpansionInfo, InFile, MacroCallId, MacroCallKind, MacroKind, @@ -387,7 +387,7 @@ struct IdentityWhenValidProcMacroExpander; impl ProcMacroExpander for IdentityWhenValidProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &base_db::Env, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs index d2614aa5f149..467eae3122df 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs @@ -4,7 +4,7 @@ use core::fmt; use std::any::Any; use std::{panic::RefUnwindSafe, sync}; -use base_db::{Crate, CrateBuilderId, CratesIdMap, Env, ProcMacroLoadingError, SourceDatabase}; +use base_db::{Crate, CrateBuilderId, CratesIdMap, Env, ProcMacroLoadingError}; use intern::Symbol; use rustc_hash::FxHashMap; use span::Span; @@ -25,7 +25,7 @@ pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe + Any { /// [`ProcMacroKind::Attr`]), environment variables, and span information. fn expand( &self, - db: &dyn SourceDatabase, + db: &dyn ExpandDatabase, subtree: &tt::TopSubtree, attrs: Option<&tt::TopSubtree>, env: &Env, diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index e01ce0b129da..94fac0bd33f7 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -11,15 +11,16 @@ extern crate rustc_driver as _; use std::{any::Any, collections::hash_map::Entry, mem, path::Path, sync}; use crossbeam_channel::{Receiver, unbounded}; -use hir_expand::proc_macro::{ - ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacroLoadResult, - ProcMacrosBuilder, +use hir_expand::{ + db::ExpandDatabase, + proc_macro::{ + ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacroLoadResult, + ProcMacrosBuilder, + }, }; use ide_db::{ - ChangeWithProcMacros, FxHashMap, RootDatabase, - base_db::{ - CrateGraphBuilder, Env, ProcMacroLoadingError, SourceDatabase, SourceRoot, SourceRootId, - }, + ChangeWithProcMacros, EditionedFileId, FxHashMap, RootDatabase, + base_db::{CrateGraphBuilder, Env, ProcMacroLoadingError, SourceRoot, SourceRootId}, prime_caches, }; use itertools::Itertools; @@ -33,7 +34,7 @@ use proc_macro_api::{ use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace}; use span::Span; use vfs::{ - AbsPath, AbsPathBuf, FileId, VfsPath, + AbsPath, AbsPathBuf, VfsPath, file_set::FileSetConfig, loader::{Handle, LoadingProgress}, }; @@ -530,7 +531,7 @@ struct Expander(proc_macro_api::ProcMacro); impl ProcMacroExpander for Expander { fn expand( &self, - db: &dyn SourceDatabase, + db: &dyn ExpandDatabase, subtree: &tt::TopSubtree, attrs: Option<&tt::TopSubtree>, env: &Env, diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index b9c389c7694e..d81f27d7c3b1 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -738,7 +738,7 @@ struct IdentityProcMacroExpander; impl ProcMacroExpander for IdentityProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -761,7 +761,7 @@ struct Issue18089ProcMacroExpander; impl ProcMacroExpander for Issue18089ProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -797,7 +797,7 @@ struct AttributeInputReplaceProcMacroExpander; impl ProcMacroExpander for AttributeInputReplaceProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, _: &TopSubtree, attrs: Option<&TopSubtree>, _: &Env, @@ -821,7 +821,7 @@ struct Issue18840ProcMacroExpander; impl ProcMacroExpander for Issue18840ProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, fn_: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -858,7 +858,7 @@ struct MirrorProcMacroExpander; impl ProcMacroExpander for MirrorProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, input: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -897,7 +897,7 @@ struct ShortenProcMacroExpander; impl ProcMacroExpander for ShortenProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, input: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -942,7 +942,7 @@ struct Issue17479ProcMacroExpander; impl ProcMacroExpander for Issue17479ProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -973,7 +973,7 @@ struct Issue18898ProcMacroExpander; impl ProcMacroExpander for Issue18898ProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -1027,7 +1027,7 @@ struct DisallowCfgProcMacroExpander; impl ProcMacroExpander for DisallowCfgProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -1059,7 +1059,7 @@ struct GenerateSuffixedTypeProcMacroExpander; impl ProcMacroExpander for GenerateSuffixedTypeProcMacroExpander { fn expand( &self, - _: &dyn SourceDatabase, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _attrs: Option<&TopSubtree>, _env: &Env, From 38b2e9262075debeb7dfb125d9ef78268e0a069d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 19:06:26 +0530 Subject: [PATCH 1555/3801] added serde to span --- src/tools/rust-analyzer/Cargo.lock | 2 ++ .../rust-analyzer/crates/span/Cargo.toml | 1 + .../rust-analyzer/crates/span/src/ast_id.rs | 3 ++- .../rust-analyzer/crates/span/src/hygiene.rs | 5 +++- .../rust-analyzer/crates/span/src/lib.rs | 23 ++++++++++++++++--- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 42eaeb01f1f2..453c35a574d7 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1881,6 +1881,7 @@ dependencies = [ "postcard", "proc-macro-api", "proc-macro-srv", + "span", ] [[package]] @@ -2648,6 +2649,7 @@ dependencies = [ "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 2.1.1", "salsa", + "serde", "stdx", "syntax", "text-size 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/tools/rust-analyzer/crates/span/Cargo.toml b/src/tools/rust-analyzer/crates/span/Cargo.toml index cfb319d688b6..d331f63d0c53 100644 --- a/src/tools/rust-analyzer/crates/span/Cargo.toml +++ b/src/tools/rust-analyzer/crates/span/Cargo.toml @@ -21,6 +21,7 @@ text-size.workspace = true vfs.workspace = true syntax.workspace = true stdx.workspace = true +serde.workspace = true [dev-dependencies] syntax.workspace = true diff --git a/src/tools/rust-analyzer/crates/span/src/ast_id.rs b/src/tools/rust-analyzer/crates/span/src/ast_id.rs index 599b3c717522..37954ca0b062 100644 --- a/src/tools/rust-analyzer/crates/span/src/ast_id.rs +++ b/src/tools/rust-analyzer/crates/span/src/ast_id.rs @@ -29,6 +29,7 @@ use std::{ use la_arena::{Arena, Idx, RawIdx}; use rustc_hash::{FxBuildHasher, FxHashMap}; +use serde::{Deserialize, Serialize}; use syntax::{ AstNode, AstPtr, SyntaxKind, SyntaxNode, SyntaxNodePtr, ast::{self, HasName}, @@ -54,7 +55,7 @@ pub const NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER: ErasedFileAstId = ErasedFileAstId(pack_hash_index_and_kind(0, 0, ErasedFileAstIdKind::NoDownmap as u32)); /// This is a type erased FileAstId. -#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct ErasedFileAstId(u32); impl fmt::Debug for ErasedFileAstId { diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index 6805417177cd..1a82f221c6e4 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -21,11 +21,14 @@ //! `ExpnData::call_site` in rustc, [`MacroCallLoc::call_site`] in rust-analyzer. use std::fmt; +#[cfg(feature = "salsa")] +use serde::{Deserialize, Serialize}; + use crate::Edition; /// A syntax context describes a hierarchy tracking order of macro definitions. #[cfg(feature = "salsa")] -#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)] pub struct SyntaxContext( /// # Invariant /// diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs index bfe7b2620d56..f6581de38ce2 100644 --- a/src/tools/rust-analyzer/crates/span/src/lib.rs +++ b/src/tools/rust-analyzer/crates/span/src/lib.rs @@ -20,6 +20,7 @@ pub use self::{ map::{RealSpanMap, SpanMap}, }; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; pub use syntax::Edition; pub use text_size::{TextRange, TextSize}; pub use vfs::FileId; @@ -68,11 +69,12 @@ impl Span { /// Spans represent a region of code, used by the IDE to be able link macro inputs and outputs /// together. Positions in spans are relative to some [`SpanAnchor`] to make them more incremental /// friendly. -#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Span { /// The text range of this span, relative to the anchor. /// We need the anchor for incrementality, as storing absolute ranges will require /// recomputation on every change in a file at all times. + #[serde(serialize_with = "serialize_text_range", deserialize_with = "deserialize_text_range")] pub range: TextRange, /// The anchor this span is relative to. pub anchor: SpanAnchor, @@ -80,6 +82,21 @@ pub struct Span { pub ctx: SyntaxContext, } +fn serialize_text_range(range: &TextRange, serializer: S) -> Result +where + S: Serializer, +{ + (u32::from(range.start()), u32::from(range.end())).serialize(serializer) +} + +fn deserialize_text_range<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let (start, end) = <(u32, u32)>::deserialize(deserializer)?; + Ok(TextRange::new(TextSize::from(start), TextSize::from(end))) +} + impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { @@ -112,7 +129,7 @@ impl fmt::Display for Span { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct SpanAnchor { pub file_id: EditionedFileId, pub ast_id: ErasedFileAstId, @@ -126,7 +143,7 @@ impl fmt::Debug for SpanAnchor { /// A [`FileId`] and [`Edition`] bundled up together. /// The MSB is reserved for `HirFileId` encoding, more upper bits are used to then encode the edition. -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] pub struct EditionedFileId(u32); impl fmt::Debug for EditionedFileId { From 5e4168b162ba9286161226b315a2d3632f31e804 Mon Sep 17 00:00:00 2001 From: usamoi Date: Sat, 3 Jan 2026 21:36:43 +0800 Subject: [PATCH 1556/3801] partially revert https://github.com/rust-lang/rust/commit/8d597aa36528dada3cbd9bcfec889c2da6ecaaac --- src/tools/miri/src/shims/x86/avx2.rs | 36 ++++++++++++++++++++++++++++ src/tools/miri/src/shims/x86/sse2.rs | 36 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index b089a0249bd7..97b9f649c158 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -224,6 +224,42 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { shift_simd_by_scalar(this, left, right, which, dest)?; } + // Used to implement the _mm256_madd_epi16 function. + // Multiplies packed signed 16-bit integers in `left` and `right`, producing + // intermediate signed 32-bit integers. Horizontally add adjacent pairs of + // intermediate 32-bit integers, and pack the results in `dest`. + "pmadd.wd" => { + let [left, right] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + let (left, left_len) = this.project_to_simd(left)?; + let (right, right_len) = this.project_to_simd(right)?; + let (dest, dest_len) = this.project_to_simd(dest)?; + + assert_eq!(left_len, right_len); + assert_eq!(dest_len.strict_mul(2), left_len); + + for i in 0..dest_len { + let j1 = i.strict_mul(2); + let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; + let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; + + let j2 = j1.strict_add(1); + let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; + let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; + + let dest = this.project_index(&dest, i)?; + + // Multiplications are i16*i16->i32, which will not overflow. + let mul1 = i32::from(left1).strict_mul(right1.into()); + let mul2 = i32::from(left2).strict_mul(right2.into()); + // However, this addition can overflow in the most extreme case + // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 + let res = mul1.wrapping_add(mul2); + + this.write_scalar(Scalar::from_i32(res), &dest)?; + } + } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn) diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 838981390307..3fbab9ba789e 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -278,6 +278,42 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?; } } + // Used to implement the _mm_madd_epi16 function. + // Multiplies packed signed 16-bit integers in `left` and `right`, producing + // intermediate signed 32-bit integers. Horizontally add adjacent pairs of + // intermediate 32-bit integers, and pack the results in `dest`. + "pmadd.wd" => { + let [left, right] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + let (left, left_len) = this.project_to_simd(left)?; + let (right, right_len) = this.project_to_simd(right)?; + let (dest, dest_len) = this.project_to_simd(dest)?; + + assert_eq!(left_len, right_len); + assert_eq!(dest_len.strict_mul(2), left_len); + + for i in 0..dest_len { + let j1 = i.strict_mul(2); + let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; + let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; + + let j2 = j1.strict_add(1); + let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; + let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; + + let dest = this.project_index(&dest, i)?; + + // Multiplications are i16*i16->i32, which will not overflow. + let mul1 = i32::from(left1).strict_mul(right1.into()); + let mul2 = i32::from(left2).strict_mul(right2.into()); + // However, this addition can overflow in the most extreme case + // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 + let res = mul1.wrapping_add(mul2); + + this.write_scalar(Scalar::from_i32(res), &dest)?; + } + } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn) From 3941fed5017b6dce330fb14972fca968f80b3303 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 19:13:06 +0530 Subject: [PATCH 1557/3801] add span to proc-macro-srv-cliy --- src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml index 2c6e5a16ee06..875d9f6801a3 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml @@ -14,6 +14,7 @@ publish = false proc-macro-srv.workspace = true proc-macro-api.workspace = true postcard.workspace = true +span.workspace = true clap = {version = "4.5.42", default-features = false, features = ["std"]} [features] From be566f4e6b0f3d160d060d0b0508256d549e24bb Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 19:15:42 +0530 Subject: [PATCH 1558/3801] refactor subreq/resp variants to carry span --- .../src/bidirectional_protocol/msg.rs | 7 ++++--- .../crates/proc-macro-srv-cli/src/main_loop.rs | 13 +++++++------ .../rust-analyzer/crates/proc-macro-srv/src/lib.rs | 6 +++--- .../src/server_impl/rust_analyzer_span.rs | 13 +++---------- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 558954f7619d..73cf58bd9ec7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -2,6 +2,7 @@ use paths::Utf8PathBuf; use serde::{Deserialize, Serialize}; +use tt::Span; use crate::{ ProcMacroKind, @@ -10,9 +11,9 @@ use crate::{ #[derive(Debug, Serialize, Deserialize)] pub enum SubRequest { - FilePath { file_id: u32 }, - SourceText { file_id: u32, start: u32, end: u32 }, - LocalFilePath { file_id: u32 }, + FilePath { span: Span }, + SourceText { span: Span }, + LocalFilePath { span: Span }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 8fe3e93e4702..a5bf84df04de 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -6,6 +6,7 @@ use proc_macro_api::{ transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; +use span::Span; use std::io; use legacy::Message; @@ -185,8 +186,8 @@ impl<'a, C: Codec> ProcMacroClientHandle<'a, C> { } impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { - fn file(&mut self, file_id: u32) -> String { - match self.roundtrip(bidirectional::SubRequest::FilePath { file_id }) { + fn file(&mut self, span: Span) -> String { + match self.roundtrip(bidirectional::SubRequest::FilePath { span }) { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::FilePathResult { name }, )) => name, @@ -194,8 +195,8 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl } } - fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option { - match self.roundtrip(bidirectional::SubRequest::SourceText { file_id, start, end }) { + fn source_text(&mut self, span: Span) -> Option { + match self.roundtrip(bidirectional::SubRequest::SourceText { span }) { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::SourceTextResult { text }, )) => text, @@ -203,8 +204,8 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl } } - fn local_file(&mut self, file_id: u32) -> Option { - match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id }) { + fn local_file(&mut self, span: Span) -> Option { + match self.roundtrip(bidirectional::SubRequest::LocalFilePath { span }) { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::LocalFilePathResult { name }, )) => name, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 8de712dbd386..6620800779bd 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -94,9 +94,9 @@ impl<'env> ProcMacroSrv<'env> { pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); pub trait ProcMacroClientInterface { - fn file(&mut self, file_id: u32) -> String; - fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option; - fn local_file(&mut self, file_id: u32) -> Option; + fn file(&mut self, span: Span) -> String; + fn source_text(&mut self, span: Span) -> Option; + fn local_file(&mut self, span: Span) -> Option; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 7a9d655431f5..c4392a9ae110 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -128,13 +128,10 @@ impl server::Span for RaSpanServer<'_> { format!("{:?}", span) } fn file(&mut self, span: Self::Span) -> String { - self.callback - .as_mut() - .map(|cb| cb.file(span.anchor.file_id.file_id().index())) - .unwrap_or_default() + self.callback.as_mut().map(|cb| cb.file(span)).unwrap_or_default() } fn local_file(&mut self, span: Self::Span) -> Option { - self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id().index())) + self.callback.as_mut().and_then(|cb| cb.local_file(span)) } fn save_span(&mut self, _span: Self::Span) -> usize { // FIXME, quote is incompatible with third-party tools @@ -153,11 +150,7 @@ impl server::Span for RaSpanServer<'_> { /// See PR: /// https://github.com/rust-lang/rust/pull/55780 fn source_text(&mut self, span: Self::Span) -> Option { - let file_id = span.anchor.file_id; - let start: u32 = span.range.start().into(); - let end: u32 = span.range.end().into(); - - self.callback.as_mut()?.source_text(file_id.file_id().index(), start, end) + self.callback.as_mut()?.source_text(span) } fn parent(&mut self, _span: Self::Span) -> Option { From 4f5502e8fb2679b76390bc7bebf4b457e853176d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 19:18:36 +0530 Subject: [PATCH 1559/3801] Add span to callbacks and correct the source_text implementation --- .../crates/load-cargo/src/lib.rs | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 94fac0bd33f7..474046ee2fa7 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -541,31 +541,37 @@ impl ProcMacroExpander for Expander { current_dir: String, ) -> Result { let mut cb = |req| match req { - SubRequest::LocalFilePath { file_id } => { - let file = FileId::from_raw(file_id); - let source_root_id = db.file_source_root(file).source_root_id(db); + SubRequest::LocalFilePath { span } => { + let file_id = span.anchor.file_id.file_id(); + let source_root_id = db.file_source_root(file_id).source_root_id(db); let source_root = db.source_root(source_root_id).source_root(db); - let name = source_root - .path_for_file(&file) + .path_for_file(&file_id) .and_then(|path| path.as_path()) .map(|path| path.to_string()); Ok(SubResponse::LocalFilePathResult { name }) } - SubRequest::SourceText { file_id, start, end } => { - let file = FileId::from_raw(file_id); - let text = db.file_text(file).text(db); - let slice = text.get(start as usize..end as usize).map(ToOwned::to_owned); - Ok(SubResponse::SourceTextResult { text: slice }) - } - SubRequest::FilePath { file_id } => { - let file = FileId::from_raw(file_id); - let source_root_id = db.file_source_root(file).source_root_id(db); - let source_root = db.source_root(source_root_id).source_root(db); + SubRequest::SourceText { span } => { + let anchor = span.anchor; + let file_id = EditionedFileId::from_span_guess_origin(db, anchor.file_id); + let range = db + .ast_id_map(hir_expand::HirFileId::FileId(file_id)) + .get_erased(anchor.ast_id) + .text_range(); + let source = db.file_text(anchor.file_id.file_id()).text(db); + let text = source + .get(usize::from(range.start())..usize::from(range.end())) + .map(ToOwned::to_owned); + Ok(SubResponse::SourceTextResult { text }) + } + SubRequest::FilePath { span } => { + let file_id = span.anchor.file_id.file_id(); + let source_root_id = db.file_source_root(file_id).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); let name = source_root - .path_for_file(&file) + .path_for_file(&file_id) .and_then(|path| path.as_path()) .map(|path| path.to_string()) .unwrap_or_default(); From ce19860f800c974dd1eb66a3aa9c2a6716d90bb7 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 20:10:00 +0530 Subject: [PATCH 1560/3801] remove span related API from proc-macro-srv/cli/api and remove span from procmacrosrvcli --- src/tools/rust-analyzer/Cargo.lock | 1 - .../crates/load-cargo/src/lib.rs | 36 ++++++++++--------- .../src/bidirectional_protocol/msg.rs | 7 ++-- .../crates/proc-macro-srv-cli/Cargo.toml | 1 - .../proc-macro-srv-cli/src/main_loop.rs | 14 ++++---- .../crates/proc-macro-srv/src/lib.rs | 6 ++-- .../src/server_impl/rust_analyzer_span.rs | 19 ++++++++-- 7 files changed, 49 insertions(+), 35 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 453c35a574d7..fbaeff1eb560 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1881,7 +1881,6 @@ dependencies = [ "postcard", "proc-macro-api", "proc-macro-srv", - "span", ] [[package]] diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 474046ee2fa7..c302e266febd 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -34,7 +34,7 @@ use proc_macro_api::{ use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace}; use span::Span; use vfs::{ - AbsPath, AbsPathBuf, VfsPath, + AbsPath, AbsPathBuf, FileId, VfsPath, file_set::FileSetConfig, loader::{Handle, LoadingProgress}, }; @@ -541,8 +541,8 @@ impl ProcMacroExpander for Expander { current_dir: String, ) -> Result { let mut cb = |req| match req { - SubRequest::LocalFilePath { span } => { - let file_id = span.anchor.file_id.file_id(); + SubRequest::LocalFilePath { file_id } => { + let file_id = FileId::from_raw(file_id); let source_root_id = db.file_source_root(file_id).source_root_id(db); let source_root = db.source_root(source_root_id).source_root(db); let name = source_root @@ -552,22 +552,26 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::LocalFilePathResult { name }) } - SubRequest::SourceText { span } => { - let anchor = span.anchor; - let file_id = EditionedFileId::from_span_guess_origin(db, anchor.file_id); - let range = db - .ast_id_map(hir_expand::HirFileId::FileId(file_id)) - .get_erased(anchor.ast_id) - .text_range(); - let source = db.file_text(anchor.file_id.file_id()).text(db); - let text = source - .get(usize::from(range.start())..usize::from(range.end())) - .map(ToOwned::to_owned); + SubRequest::SourceText { file_id, ast_id, start, end } => { + let raw_file_id = FileId::from_raw(file_id); + let editioned_file_id = span::EditionedFileId::from_raw(file_id); + let ast_id = span::ErasedFileAstId::from_raw(ast_id); + let hir_file_id = EditionedFileId::from_span_guess_origin(db, editioned_file_id); + let anchor_offset = db + .ast_id_map(hir_expand::HirFileId::FileId(hir_file_id)) + .get_erased(ast_id) + .text_range() + .start(); + let anchor_offset = u32::from(anchor_offset); + let abs_start = start + anchor_offset; + let abs_end = end + anchor_offset; + let source = db.file_text(raw_file_id).text(db); + let text = source.get(abs_start as usize..abs_end as usize).map(ToOwned::to_owned); Ok(SubResponse::SourceTextResult { text }) } - SubRequest::FilePath { span } => { - let file_id = span.anchor.file_id.file_id(); + SubRequest::FilePath { file_id } => { + let file_id = FileId::from_raw(file_id); let source_root_id = db.file_source_root(file_id).source_root_id(db); let source_root = db.source_root(source_root_id).source_root(db); let name = source_root diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 73cf58bd9ec7..e41f8a5d7da7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -2,7 +2,6 @@ use paths::Utf8PathBuf; use serde::{Deserialize, Serialize}; -use tt::Span; use crate::{ ProcMacroKind, @@ -11,9 +10,9 @@ use crate::{ #[derive(Debug, Serialize, Deserialize)] pub enum SubRequest { - FilePath { span: Span }, - SourceText { span: Span }, - LocalFilePath { span: Span }, + FilePath { file_id: u32 }, + SourceText { file_id: u32, ast_id: u32, start: u32, end: u32 }, + LocalFilePath { file_id: u32 }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml index 875d9f6801a3..2c6e5a16ee06 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml @@ -14,7 +14,6 @@ publish = false proc-macro-srv.workspace = true proc-macro-api.workspace = true postcard.workspace = true -span.workspace = true clap = {version = "4.5.42", default-features = false, features = ["std"]} [features] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index a5bf84df04de..4891e073142d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -6,7 +6,6 @@ use proc_macro_api::{ transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; -use span::Span; use std::io; use legacy::Message; @@ -186,8 +185,8 @@ impl<'a, C: Codec> ProcMacroClientHandle<'a, C> { } impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { - fn file(&mut self, span: Span) -> String { - match self.roundtrip(bidirectional::SubRequest::FilePath { span }) { + fn file(&mut self, file_id: u32) -> String { + match self.roundtrip(bidirectional::SubRequest::FilePath { file_id }) { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::FilePathResult { name }, )) => name, @@ -195,8 +194,9 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl } } - fn source_text(&mut self, span: Span) -> Option { - match self.roundtrip(bidirectional::SubRequest::SourceText { span }) { + fn source_text(&mut self, file_id: u32, ast_id: u32, start: u32, end: u32) -> Option { + match self.roundtrip(bidirectional::SubRequest::SourceText { file_id, ast_id, start, end }) + { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::SourceTextResult { text }, )) => text, @@ -204,8 +204,8 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl } } - fn local_file(&mut self, span: Span) -> Option { - match self.roundtrip(bidirectional::SubRequest::LocalFilePath { span }) { + fn local_file(&mut self, file_id: u32) -> Option { + match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id }) { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::LocalFilePathResult { name }, )) => name, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 6620800779bd..d63aea947c1d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -94,9 +94,9 @@ impl<'env> ProcMacroSrv<'env> { pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); pub trait ProcMacroClientInterface { - fn file(&mut self, span: Span) -> String; - fn source_text(&mut self, span: Span) -> Option; - fn local_file(&mut self, span: Span) -> Option; + fn file(&mut self, file_id: u32) -> String; + fn source_text(&mut self, file_id: u32, ast_id: u32, start: u32, end: u32) -> Option; + fn local_file(&mut self, file_id: u32) -> Option; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index c4392a9ae110..2ce3b717cb0d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -128,10 +128,13 @@ impl server::Span for RaSpanServer<'_> { format!("{:?}", span) } fn file(&mut self, span: Self::Span) -> String { - self.callback.as_mut().map(|cb| cb.file(span)).unwrap_or_default() + self.callback + .as_mut() + .map(|cb| cb.file(span.anchor.file_id.file_id().index())) + .unwrap_or_default() } fn local_file(&mut self, span: Self::Span) -> Option { - self.callback.as_mut().and_then(|cb| cb.local_file(span)) + self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id().index())) } fn save_span(&mut self, _span: Self::Span) -> usize { // FIXME, quote is incompatible with third-party tools @@ -150,7 +153,17 @@ impl server::Span for RaSpanServer<'_> { /// See PR: /// https://github.com/rust-lang/rust/pull/55780 fn source_text(&mut self, span: Self::Span) -> Option { - self.callback.as_mut()?.source_text(span) + let file_id = span.anchor.file_id; + let ast_id = span.anchor.ast_id; + let start: u32 = span.range.start().into(); + let end: u32 = span.range.end().into(); + + self.callback.as_mut()?.source_text( + file_id.file_id().index(), + ast_id.into_raw(), + start, + end, + ) } fn parent(&mut self, _span: Self::Span) -> Option { From f3b06a10f259fffd2ae92334f91fd0365e33f66a Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 20:13:41 +0530 Subject: [PATCH 1561/3801] remove serde from span --- src/tools/rust-analyzer/Cargo.lock | 1 - .../rust-analyzer/crates/span/Cargo.toml | 1 - .../rust-analyzer/crates/span/src/ast_id.rs | 3 +-- .../rust-analyzer/crates/span/src/hygiene.rs | 8 ++----- .../rust-analyzer/crates/span/src/lib.rs | 23 +++---------------- 5 files changed, 6 insertions(+), 30 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index fbaeff1eb560..42eaeb01f1f2 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2648,7 +2648,6 @@ dependencies = [ "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 2.1.1", "salsa", - "serde", "stdx", "syntax", "text-size 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/tools/rust-analyzer/crates/span/Cargo.toml b/src/tools/rust-analyzer/crates/span/Cargo.toml index d331f63d0c53..cfb319d688b6 100644 --- a/src/tools/rust-analyzer/crates/span/Cargo.toml +++ b/src/tools/rust-analyzer/crates/span/Cargo.toml @@ -21,7 +21,6 @@ text-size.workspace = true vfs.workspace = true syntax.workspace = true stdx.workspace = true -serde.workspace = true [dev-dependencies] syntax.workspace = true diff --git a/src/tools/rust-analyzer/crates/span/src/ast_id.rs b/src/tools/rust-analyzer/crates/span/src/ast_id.rs index 37954ca0b062..599b3c717522 100644 --- a/src/tools/rust-analyzer/crates/span/src/ast_id.rs +++ b/src/tools/rust-analyzer/crates/span/src/ast_id.rs @@ -29,7 +29,6 @@ use std::{ use la_arena::{Arena, Idx, RawIdx}; use rustc_hash::{FxBuildHasher, FxHashMap}; -use serde::{Deserialize, Serialize}; use syntax::{ AstNode, AstPtr, SyntaxKind, SyntaxNode, SyntaxNodePtr, ast::{self, HasName}, @@ -55,7 +54,7 @@ pub const NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER: ErasedFileAstId = ErasedFileAstId(pack_hash_index_and_kind(0, 0, ErasedFileAstIdKind::NoDownmap as u32)); /// This is a type erased FileAstId. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct ErasedFileAstId(u32); impl fmt::Debug for ErasedFileAstId { diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index 1a82f221c6e4..ea4f4c5efb42 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -19,16 +19,12 @@ //! # The Call-site Hierarchy //! //! `ExpnData::call_site` in rustc, [`MacroCallLoc::call_site`] in rust-analyzer. -use std::fmt; - -#[cfg(feature = "salsa")] -use serde::{Deserialize, Serialize}; - use crate::Edition; +use std::fmt; /// A syntax context describes a hierarchy tracking order of macro definitions. #[cfg(feature = "salsa")] -#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] pub struct SyntaxContext( /// # Invariant /// diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs index f6581de38ce2..bfe7b2620d56 100644 --- a/src/tools/rust-analyzer/crates/span/src/lib.rs +++ b/src/tools/rust-analyzer/crates/span/src/lib.rs @@ -20,7 +20,6 @@ pub use self::{ map::{RealSpanMap, SpanMap}, }; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; pub use syntax::Edition; pub use text_size::{TextRange, TextSize}; pub use vfs::FileId; @@ -69,12 +68,11 @@ impl Span { /// Spans represent a region of code, used by the IDE to be able link macro inputs and outputs /// together. Positions in spans are relative to some [`SpanAnchor`] to make them more incremental /// friendly. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Span { /// The text range of this span, relative to the anchor. /// We need the anchor for incrementality, as storing absolute ranges will require /// recomputation on every change in a file at all times. - #[serde(serialize_with = "serialize_text_range", deserialize_with = "deserialize_text_range")] pub range: TextRange, /// The anchor this span is relative to. pub anchor: SpanAnchor, @@ -82,21 +80,6 @@ pub struct Span { pub ctx: SyntaxContext, } -fn serialize_text_range(range: &TextRange, serializer: S) -> Result -where - S: Serializer, -{ - (u32::from(range.start()), u32::from(range.end())).serialize(serializer) -} - -fn deserialize_text_range<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let (start, end) = <(u32, u32)>::deserialize(deserializer)?; - Ok(TextRange::new(TextSize::from(start), TextSize::from(end))) -} - impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { @@ -129,7 +112,7 @@ impl fmt::Display for Span { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct SpanAnchor { pub file_id: EditionedFileId, pub ast_id: ErasedFileAstId, @@ -143,7 +126,7 @@ impl fmt::Debug for SpanAnchor { /// A [`FileId`] and [`Edition`] bundled up together. /// The MSB is reserved for `HirFileId` encoding, more upper bits are used to then encode the edition. -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct EditionedFileId(u32); impl fmt::Debug for EditionedFileId { From aec6b9b7bf541d386e5ef21a49f4ecfee17769ed Mon Sep 17 00:00:00 2001 From: hulxv Date: Wed, 17 Dec 2025 22:56:28 +0200 Subject: [PATCH 1562/3801] Refactor libc pipe tests to use utility functions for error handling and data operations --- .../miri/tests/pass-dep/libc/libc-pipe.rs | 137 +++++++----------- src/tools/miri/tests/utils/libc.rs | 18 +++ 2 files changed, 72 insertions(+), 83 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs index ffbcf633b987..102bcbb34a26 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs @@ -5,6 +5,7 @@ use std::thread; #[path = "../../utils/libc.rs"] mod libc_utils; +use libc_utils::*; fn main() { test_pipe(); @@ -25,69 +26,46 @@ fn main() { fn test_pipe() { let mut fds = [-1, -1]; - let res = unsafe { libc::pipe(fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::pipe(fds.as_mut_ptr()) }); // Read size == data available in buffer. - let data = "12345".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); - let mut buf3: [u8; 5] = [0; 5]; - let res = unsafe { - libc_utils::read_all(fds[0], buf3.as_mut_ptr().cast(), buf3.len() as libc::size_t) - }; - assert_eq!(res, 5); - assert_eq!(buf3, "12345".as_bytes()); + let data = b"12345"; + write_all_from_slice(fds[1], data).unwrap(); + let buf3 = read_all_into_array::<5>(fds[0]).unwrap(); + assert_eq!(&buf3, data); // Read size > data available in buffer. - let data = "123".as_bytes(); - let res = unsafe { libc_utils::write_all(fds[1], data.as_ptr() as *const libc::c_void, 3) }; - assert_eq!(res, 3); + let data = b"123"; + write_all_from_slice(fds[1], data).unwrap(); let mut buf4: [u8; 5] = [0; 5]; - let res = unsafe { libc::read(fds[0], buf4.as_mut_ptr().cast(), buf4.len() as libc::size_t) }; - assert!(res > 0 && res <= 3); - let res = res as usize; + let res = read_into_slice(fds[0], &mut buf4).unwrap().0.len(); assert_eq!(buf4[..res], data[..res]); if res < 3 { // Drain the rest from the read end. - let res = unsafe { libc_utils::read_all(fds[0], buf4[res..].as_mut_ptr().cast(), 3 - res) }; + let res = read_into_slice(fds[0], &mut buf4[res..]).unwrap().0.len(); assert!(res > 0); } } fn test_pipe_threaded() { let mut fds = [-1, -1]; - let res = unsafe { libc::pipe(fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::pipe(fds.as_mut_ptr()) }); let thread1 = thread::spawn(move || { - let mut buf: [u8; 5] = [0; 5]; - let res: i64 = unsafe { - libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - .try_into() - .unwrap() - }; - assert_eq!(res, 5); - assert_eq!(buf, "abcde".as_bytes()); + let buf = read_all_into_array::<5>(fds[0]).unwrap(); + assert_eq!(&buf, b"abcde"); }); thread::yield_now(); - let data = "abcde".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); + write_all_from_slice(fds[1], b"abcde").unwrap(); thread1.join().unwrap(); // Read and write from different direction let thread2 = thread::spawn(move || { thread::yield_now(); - let data = "12345".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); + write_all_from_slice(fds[1], b"12345").unwrap(); }); - let mut buf: [u8; 5] = [0; 5]; - let res = - unsafe { libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - assert_eq!(res, 5); - assert_eq!(buf, "12345".as_bytes()); + let buf = read_all_into_array::<5>(fds[0]).unwrap(); + assert_eq!(&buf, b"12345"); thread2.join().unwrap(); } @@ -96,26 +74,17 @@ fn test_pipe_threaded() { fn test_race() { static mut VAL: u8 = 0; let mut fds = [-1, -1]; - let res = unsafe { libc::pipe(fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::pipe(fds.as_mut_ptr()) }); let thread1 = thread::spawn(move || { - let mut buf: [u8; 1] = [0; 1]; // write() from the main thread will occur before the read() here // because preemption is disabled and the main thread yields after write(). - let res: i32 = unsafe { - libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - .try_into() - .unwrap() - }; - assert_eq!(res, 1); - assert_eq!(buf, "a".as_bytes()); + let buf = read_all_into_array::<1>(fds[0]).unwrap(); + assert_eq!(&buf, b"a"); // The read above establishes a happens-before so it is now safe to access this global variable. unsafe { assert_eq!(VAL, 1) }; }); unsafe { VAL = 1 }; - let data = "a".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 1) }; - assert_eq!(res, 1); + write_all_from_slice(fds[1], b"a").unwrap(); thread::yield_now(); thread1.join().unwrap(); } @@ -139,40 +108,46 @@ fn test_pipe_array() { ))] fn test_pipe2() { let mut fds = [-1, -1]; - let res = unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_NONBLOCK) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_NONBLOCK) }); } /// Basic test for pipe fcntl's F_SETFL and F_GETFL flag. fn test_pipe_setfl_getfl() { // Initialise pipe fds. let mut fds = [-1, -1]; - let res = unsafe { libc::pipe(fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::pipe(fds.as_mut_ptr()) }); // Both sides should either have O_RONLY or O_WRONLY. - let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) }; - assert_eq!(res, libc::O_RDONLY); - let res = unsafe { libc::fcntl(fds[1], libc::F_GETFL) }; - assert_eq!(res, libc::O_WRONLY); + assert_eq!( + errno_result(unsafe { libc::fcntl(fds[0], libc::F_GETFL) }).unwrap(), + libc::O_RDONLY + ); + assert_eq!( + errno_result(unsafe { libc::fcntl(fds[1], libc::F_GETFL) }).unwrap(), + libc::O_WRONLY + ); // Add the O_NONBLOCK flag with F_SETFL. - let res = unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }); // Test if the O_NONBLOCK flag is successfully added. - let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) }; - assert_eq!(res, libc::O_RDONLY | libc::O_NONBLOCK); + assert_eq!( + errno_result(unsafe { libc::fcntl(fds[0], libc::F_GETFL) }).unwrap(), + libc::O_RDONLY | libc::O_NONBLOCK + ); // The other side remains unchanged. - let res = unsafe { libc::fcntl(fds[1], libc::F_GETFL) }; - assert_eq!(res, libc::O_WRONLY); + assert_eq!( + errno_result(unsafe { libc::fcntl(fds[1], libc::F_GETFL) }).unwrap(), + libc::O_WRONLY + ); // Test if O_NONBLOCK flag can be unset. - let res = unsafe { libc::fcntl(fds[0], libc::F_SETFL, 0) }; - assert_eq!(res, 0); - let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) }; - assert_eq!(res, libc::O_RDONLY); + errno_check(unsafe { libc::fcntl(fds[0], libc::F_SETFL, 0) }); + assert_eq!( + errno_result(unsafe { libc::fcntl(fds[0], libc::F_GETFL) }).unwrap(), + libc::O_RDONLY + ); } /// Test the behaviour of F_SETFL/F_GETFL when a fd is blocking. @@ -183,28 +158,24 @@ fn test_pipe_setfl_getfl() { /// then writes to fds[1] to unblock main thread's `read`. fn test_pipe_fcntl_threaded() { let mut fds = [-1, -1]; - let res = unsafe { libc::pipe(fds.as_mut_ptr()) }; - assert_eq!(res, 0); - let mut buf: [u8; 5] = [0; 5]; + errno_check(unsafe { libc::pipe(fds.as_mut_ptr()) }); let thread1 = thread::spawn(move || { // Add O_NONBLOCK flag while pipe is still blocked on read. - let res = unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }); // Check the new flag value while the main thread is still blocked on fds[0]. - let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) }; - assert_eq!(res, libc::O_NONBLOCK); + assert_eq!( + errno_result(unsafe { libc::fcntl(fds[0], libc::F_GETFL) }).unwrap(), + libc::O_NONBLOCK + ); // The write below will unblock the `read` in main thread: even though // the socket is now "non-blocking", the shim needs to deal correctly // with threads that were blocked before the socket was made non-blocking. - let data = "abcde".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); + write_all_from_slice(fds[1], b"abcde").unwrap(); }); // The `read` below will block. - let res = - unsafe { libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; + let buf = read_all_into_array::<5>(fds[0]).unwrap(); thread1.join().unwrap(); - assert_eq!(res, 5); + assert_eq!(&buf, b"abcde"); } diff --git a/src/tools/miri/tests/utils/libc.rs b/src/tools/miri/tests/utils/libc.rs index e42f39c64eb6..114aade7d31d 100644 --- a/src/tools/miri/tests/utils/libc.rs +++ b/src/tools/miri/tests/utils/libc.rs @@ -53,6 +53,24 @@ pub fn read_all_into_array(fd: libc::c_int) -> Result<[u8; N], l } } +pub fn read_all_into_slice(fd: libc::c_int, buf: &mut [u8]) -> Result<(), libc::ssize_t> { + let res = unsafe { read_all(fd, buf.as_mut_ptr().cast(), buf.len()) }; + if res >= 0 { + assert_eq!(res as usize, buf.len()); + Ok(()) + } else { + Err(res) + } +} + +pub fn read_into_slice( + fd: libc::c_int, + buf: &mut [u8], +) -> Result<(&mut [u8], &mut [u8]), libc::ssize_t> { + let res = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), buf.len()) }; + if res >= 0 { Ok(buf.split_at_mut(res as usize)) } else { Err(res) } +} + pub unsafe fn write_all( fd: libc::c_int, buf: *const libc::c_void, From b692fcbb4bd60691af415d42b3e58fe5d469a619 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 3 Jan 2026 16:23:55 +0100 Subject: [PATCH 1563/3801] minor tweaks --- .../miri/tests/pass-dep/libc/libc-pipe.rs | 12 ++++------ src/tools/miri/tests/utils/libc.rs | 24 +++++++++---------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs index 102bcbb34a26..1eef8eaf4452 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs @@ -38,13 +38,11 @@ fn test_pipe() { let data = b"123"; write_all_from_slice(fds[1], data).unwrap(); let mut buf4: [u8; 5] = [0; 5]; - let res = read_into_slice(fds[0], &mut buf4).unwrap().0.len(); - assert_eq!(buf4[..res], data[..res]); - if res < 3 { - // Drain the rest from the read end. - let res = read_into_slice(fds[0], &mut buf4[res..]).unwrap().0.len(); - assert!(res > 0); - } + let (part1, rest) = read_into_slice(fds[0], &mut buf4).unwrap(); + assert_eq!(part1[..], data[..part1.len()]); + // Write 2 more bytes so we can exactly fill the `rest`. + write_all_from_slice(fds[1], b"34").unwrap(); + read_all_into_slice(fds[0], rest).unwrap(); } fn test_pipe_threaded() { diff --git a/src/tools/miri/tests/utils/libc.rs b/src/tools/miri/tests/utils/libc.rs index 114aade7d31d..0765bacb6bd8 100644 --- a/src/tools/miri/tests/utils/libc.rs +++ b/src/tools/miri/tests/utils/libc.rs @@ -40,19 +40,8 @@ pub unsafe fn read_all( return read_so_far as libc::ssize_t; } -/// Read exactly `N` bytes from `fd`. Error if that many bytes could not be read. +/// Try to fill the given slice by reading from `fd`. Error if that many bytes could not be read. #[track_caller] -pub fn read_all_into_array(fd: libc::c_int) -> Result<[u8; N], libc::ssize_t> { - let mut buf = [0; N]; - let res = unsafe { read_all(fd, buf.as_mut_ptr().cast(), buf.len()) }; - if res >= 0 { - assert_eq!(res as usize, buf.len()); - Ok(buf) - } else { - Err(res) - } -} - pub fn read_all_into_slice(fd: libc::c_int, buf: &mut [u8]) -> Result<(), libc::ssize_t> { let res = unsafe { read_all(fd, buf.as_mut_ptr().cast(), buf.len()) }; if res >= 0 { @@ -63,6 +52,17 @@ pub fn read_all_into_slice(fd: libc::c_int, buf: &mut [u8]) -> Result<(), libc:: } } +/// Read exactly `N` bytes from `fd`. Error if that many bytes could not be read. +#[track_caller] +pub fn read_all_into_array(fd: libc::c_int) -> Result<[u8; N], libc::ssize_t> { + let mut buf = [0; N]; + read_all_into_slice(fd, &mut buf)?; + Ok(buf) +} + +/// Do a single read from `fd` and return the part of the buffer that was written into, +/// and the rest. +#[track_caller] pub fn read_into_slice( fd: libc::c_int, buf: &mut [u8], From 65c10702bdbbaa733858fa890a41d1f5892ab0de Mon Sep 17 00:00:00 2001 From: Sekar-C-Mca Date: Sat, 3 Jan 2026 22:41:01 +0530 Subject: [PATCH 1564/3801] Fix typo in pattern usefulness documentation Line 171 introduced `pt_1, .., pt_n` and `qt` as variable names, but line 172 incorrectly used `tp_1, .., tp_n, tq`. This commit fixes the inconsistency to use the correct variable names throughout. --- compiler/rustc_pattern_analysis/src/usefulness.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 971616b18914..bf236b7737d9 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -169,7 +169,7 @@ //! on pattern-tuples. //! //! Let `pt_1, .., pt_n` and `qt` be length-m tuples of patterns for the same type `(T_1, .., T_m)`. -//! We compute `usefulness(tp_1, .., tp_n, tq)` as follows: +//! We compute `usefulness(pt_1, .., pt_n, qt)` as follows: //! //! - Base case: `m == 0`. //! The pattern-tuples are all empty, i.e. they're all `()`. Thus `tq` is useful iff there are From d236b8a4f19b5c09f5cba0f5d69ac13c2c303d48 Mon Sep 17 00:00:00 2001 From: Jeremy Smart Date: Mon, 8 Sep 2025 13:24:24 -0400 Subject: [PATCH 1565/3801] Add Dir::open(_file) and some trait impls --- library/std/src/fs.rs | 118 +++++++++++++ library/std/src/fs/tests.rs | 31 ++++ library/std/src/sys/fs/common.rs | 25 ++- library/std/src/sys/fs/hermit.rs | 3 +- library/std/src/sys/fs/mod.rs | 2 +- library/std/src/sys/fs/solid.rs | 2 +- library/std/src/sys/fs/uefi.rs | 1 + library/std/src/sys/fs/unix.rs | 242 +++++++++++++++----------- library/std/src/sys/fs/unix/dir.rs | 114 ++++++++++++ library/std/src/sys/fs/unsupported.rs | 1 + library/std/src/sys/fs/windows.rs | 51 ++++-- library/std/src/sys/fs/windows/dir.rs | 153 ++++++++++++++++ 12 files changed, 619 insertions(+), 124 deletions(-) create mode 100644 library/std/src/sys/fs/unix/dir.rs create mode 100644 library/std/src/sys/fs/windows/dir.rs diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index f078dec21d0a..4edd35b310bd 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -152,6 +152,43 @@ pub enum TryLockError { WouldBlock, } +/// An object providing access to a directory on the filesystem. +/// +/// Directories are automatically closed when they go out of scope. Errors detected +/// on closing are ignored by the implementation of `Drop`. +/// +/// # Platform-specific behavior +/// +/// On supported systems (including Windows and some UNIX-based OSes), this function acquires a +/// handle/file descriptor for the directory. This allows functions like [`Dir::open_file`] to +/// avoid [TOCTOU] errors when the directory itself is being moved. +/// +/// On other systems, it stores an absolute path (see [`canonicalize()`]). In the latter case, no +/// [TOCTOU] guarantees are made. +/// +/// # Examples +/// +/// Opens a directory and then a file inside it. +/// +/// ```no_run +/// #![feature(dirfd)] +/// use std::{fs::Dir, io}; +/// +/// fn main() -> std::io::Result<()> { +/// let dir = Dir::open("foo")?; +/// let mut file = dir.open_file("bar.txt")?; +/// let contents = io::read_to_string(file)?; +/// assert_eq!(contents, "Hello, world!"); +/// Ok(()) +/// } +/// ``` +/// +/// [TOCTOU]: self#time-of-check-to-time-of-use-toctou +#[unstable(feature = "dirfd", issue = "120426")] +pub struct Dir { + inner: fs_imp::Dir, +} + /// Metadata information about a file. /// /// This structure is returned from the [`metadata`] or @@ -1554,6 +1591,87 @@ impl Seek for Arc { } } +impl Dir { + /// Attempts to open a directory at `path` in read-only mode. + /// + /// # Errors + /// + /// This function will return an error if `path` does not point to an existing directory. + /// Other errors may also be returned according to [`OpenOptions::open`]. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(dirfd)] + /// use std::{fs::Dir, io}; + /// + /// fn main() -> std::io::Result<()> { + /// let dir = Dir::open("foo")?; + /// let mut f = dir.open_file("bar.txt")?; + /// let contents = io::read_to_string(f)?; + /// assert_eq!(contents, "Hello, world!"); + /// Ok(()) + /// } + /// ``` + #[unstable(feature = "dirfd", issue = "120426")] + pub fn open>(path: P) -> io::Result { + fs_imp::Dir::open(path.as_ref(), &OpenOptions::new().read(true).0) + .map(|inner| Self { inner }) + } + + /// Attempts to open a file in read-only mode relative to this directory. + /// + /// # Errors + /// + /// This function will return an error if `path` does not point to an existing file. + /// Other errors may also be returned according to [`OpenOptions::open`]. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(dirfd)] + /// use std::{fs::Dir, io}; + /// + /// fn main() -> std::io::Result<()> { + /// let dir = Dir::open("foo")?; + /// let mut f = dir.open_file("bar.txt")?; + /// let contents = io::read_to_string(f)?; + /// assert_eq!(contents, "Hello, world!"); + /// Ok(()) + /// } + /// ``` + #[unstable(feature = "dirfd", issue = "120426")] + pub fn open_file>(&self, path: P) -> io::Result { + self.inner + .open_file(path.as_ref(), &OpenOptions::new().read(true).0) + .map(|f| File { inner: f }) + } +} + +impl AsInner for Dir { + #[inline] + fn as_inner(&self) -> &fs_imp::Dir { + &self.inner + } +} +impl FromInner for Dir { + fn from_inner(f: fs_imp::Dir) -> Dir { + Dir { inner: f } + } +} +impl IntoInner for Dir { + fn into_inner(self) -> fs_imp::Dir { + self.inner + } +} + +#[unstable(feature = "dirfd", issue = "120426")] +impl fmt::Debug for Dir { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.inner.fmt(f) + } +} + impl OpenOptions { /// Creates a blank new set of options ready for configuration. /// diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index f15efc7b2f0b..6a86705f2fad 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1,7 +1,11 @@ use rand::RngCore; +#[cfg(not(miri))] +use super::Dir; use crate::assert_matches::assert_matches; use crate::fs::{self, File, FileTimes, OpenOptions, TryLockError}; +#[cfg(not(miri))] +use crate::io; use crate::io::prelude::*; use crate::io::{BorrowedBuf, ErrorKind, SeekFrom}; use crate::mem::MaybeUninit; @@ -2465,3 +2469,30 @@ fn test_fs_set_times_nofollow() { assert_ne!(target_metadata.accessed().unwrap(), accessed); assert_ne!(target_metadata.modified().unwrap(), modified); } + +#[test] +// FIXME: libc calls fail on miri +#[cfg(not(miri))] +fn test_dir_smoke_test() { + let tmpdir = tmpdir(); + let dir = Dir::open(tmpdir.path()); + check!(dir); +} + +#[test] +// FIXME: libc calls fail on miri +#[cfg(not(miri))] +fn test_dir_read_file() { + let tmpdir = tmpdir(); + let mut f = check!(File::create(tmpdir.join("foo.txt"))); + check!(f.write(b"bar")); + check!(f.flush()); + drop(f); + let dir = check!(Dir::open(tmpdir.path())); + let f = check!(dir.open_file("foo.txt")); + let buf = check!(io::read_to_string(f)); + assert_eq!("bar", &buf); + let f = check!(dir.open_file(tmpdir.join("foo.txt"))); + let buf = check!(io::read_to_string(f)); + assert_eq!("bar", &buf); +} diff --git a/library/std/src/sys/fs/common.rs b/library/std/src/sys/fs/common.rs index fbd075d57d61..4d47d392a826 100644 --- a/library/std/src/sys/fs/common.rs +++ b/library/std/src/sys/fs/common.rs @@ -1,9 +1,10 @@ #![allow(dead_code)] // not used on all platforms -use crate::fs; use crate::io::{self, Error, ErrorKind}; -use crate::path::Path; +use crate::path::{Path, PathBuf}; +use crate::sys::fs::{File, OpenOptions}; use crate::sys::helpers::ignore_notfound; +use crate::{fmt, fs}; pub(crate) const NOT_FILE_ERROR: Error = io::const_error!( ErrorKind::InvalidInput, @@ -58,3 +59,23 @@ pub fn exists(path: &Path) -> io::Result { Err(error) => Err(error), } } + +pub struct Dir { + path: PathBuf, +} + +impl Dir { + pub fn open(path: &Path, _opts: &OpenOptions) -> io::Result { + path.canonicalize().map(|path| Self { path }) + } + + pub fn open_file(&self, path: &Path, opts: &OpenOptions) -> io::Result { + File::open(&self.path.join(path), &opts) + } +} + +impl fmt::Debug for Dir { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Dir").field("path", &self.path).finish() + } +} diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index bb0c44d7e9a1..1e281eb0d9d1 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -10,7 +10,7 @@ use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, Raw use crate::path::{Path, PathBuf}; use crate::sync::Arc; use crate::sys::fd::FileDesc; -pub use crate::sys::fs::common::{copy, exists}; +pub use crate::sys::fs::common::{Dir, copy, exists}; use crate::sys::helpers::run_path_with_cstr; use crate::sys::time::SystemTime; use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, cvt, unsupported, unsupported_err}; @@ -18,6 +18,7 @@ use crate::{fmt, mem}; #[derive(Debug)] pub struct File(FileDesc); + #[derive(Clone)] pub struct FileAttr { stat_val: stat_struct, diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index fa046cb8e7da..0c297c5766b8 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -59,7 +59,7 @@ pub fn with_native_path(path: &Path, f: &dyn Fn(&Path) -> io::Result) -> i } pub use imp::{ - DirBuilder, DirEntry, File, FileAttr, FilePermissions, FileTimes, FileType, OpenOptions, + Dir, DirBuilder, DirEntry, File, FileAttr, FilePermissions, FileTimes, FileType, OpenOptions, ReadDir, }; diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index b6d41cc4bc84..114ffda57bc5 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -9,7 +9,7 @@ use crate::os::raw::{c_int, c_short}; use crate::os::solid::ffi::OsStrExt; use crate::path::{Path, PathBuf}; use crate::sync::Arc; -pub use crate::sys::fs::common::exists; +pub use crate::sys::fs::common::{Dir, exists}; use crate::sys::helpers::ignore_notfound; use crate::sys::pal::{abi, error}; use crate::sys::time::SystemTime; diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index f5530962c570..14ee49e071c1 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -6,6 +6,7 @@ use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; +pub use crate::sys::fs::common::Dir; use crate::sys::pal::{helpers, unsupported}; use crate::sys::time::SystemTime; diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 1cc2edd0cf47..327b0eb7468a 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -257,7 +257,7 @@ cfg_has_statx! {{ // all DirEntry's will have a reference to this struct struct InnerReadDir { - dirp: Dir, + dirp: DirStream, root: PathBuf, } @@ -272,10 +272,134 @@ impl ReadDir { } } -struct Dir(*mut libc::DIR); +struct DirStream(*mut libc::DIR); -unsafe impl Send for Dir {} -unsafe impl Sync for Dir {} +// dir::Dir requires openat support +cfg_select! { + any( + target_os = "redox", + target_os = "espidf", + target_os = "horizon", + target_os = "vita", + target_os = "nto", + target_os = "vxworks", + ) => { + pub use crate::sys::fs::common::Dir; + } + _ => { + mod dir; + pub use dir::Dir; + } +} + +fn debug_path_fd<'a, 'b>( + fd: c_int, + f: &'a mut fmt::Formatter<'b>, + name: &str, +) -> fmt::DebugStruct<'a, 'b> { + let mut b = f.debug_struct(name); + + fn get_mode(fd: c_int) -> Option<(bool, bool)> { + let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) }; + if mode == -1 { + return None; + } + match mode & libc::O_ACCMODE { + libc::O_RDONLY => Some((true, false)), + libc::O_RDWR => Some((true, true)), + libc::O_WRONLY => Some((false, true)), + _ => None, + } + } + + b.field("fd", &fd); + if let Some(path) = get_path_from_fd(fd) { + b.field("path", &path); + } + if let Some((read, write)) = get_mode(fd) { + b.field("read", &read).field("write", &write); + } + + b +} + +fn get_path_from_fd(fd: c_int) -> Option { + #[cfg(any(target_os = "linux", target_os = "illumos", target_os = "solaris"))] + fn get_path(fd: c_int) -> Option { + let mut p = PathBuf::from("/proc/self/fd"); + p.push(&fd.to_string()); + run_path_with_cstr(&p, &readlink).ok() + } + + #[cfg(any(target_vendor = "apple", target_os = "netbsd"))] + fn get_path(fd: c_int) -> Option { + // FIXME: The use of PATH_MAX is generally not encouraged, but it + // is inevitable in this case because Apple targets and NetBSD define `fcntl` + // with `F_GETPATH` in terms of `MAXPATHLEN`, and there are no + // alternatives. If a better method is invented, it should be used + // instead. + let mut buf = vec![0; libc::PATH_MAX as usize]; + let n = unsafe { libc::fcntl(fd, libc::F_GETPATH, buf.as_ptr()) }; + if n == -1 { + cfg_select! { + target_os = "netbsd" => { + // fallback to procfs as last resort + let mut p = PathBuf::from("/proc/self/fd"); + p.push(&fd.to_string()); + return run_path_with_cstr(&p, &readlink).ok() + } + _ => { + return None; + } + } + } + let l = buf.iter().position(|&c| c == 0).unwrap(); + buf.truncate(l as usize); + buf.shrink_to_fit(); + Some(PathBuf::from(OsString::from_vec(buf))) + } + + #[cfg(target_os = "freebsd")] + fn get_path(fd: c_int) -> Option { + let info = Box::::new_zeroed(); + let mut info = unsafe { info.assume_init() }; + info.kf_structsize = size_of::() as libc::c_int; + let n = unsafe { libc::fcntl(fd, libc::F_KINFO, &mut *info) }; + if n == -1 { + return None; + } + let buf = unsafe { CStr::from_ptr(info.kf_path.as_mut_ptr()).to_bytes().to_vec() }; + Some(PathBuf::from(OsString::from_vec(buf))) + } + + #[cfg(target_os = "vxworks")] + fn get_path(fd: c_int) -> Option { + let mut buf = vec![0; libc::PATH_MAX as usize]; + let n = unsafe { libc::ioctl(fd, libc::FIOGETNAME, buf.as_ptr()) }; + if n == -1 { + return None; + } + let l = buf.iter().position(|&c| c == 0).unwrap(); + buf.truncate(l as usize); + Some(PathBuf::from(OsString::from_vec(buf))) + } + + #[cfg(not(any( + target_os = "linux", + target_os = "vxworks", + target_os = "freebsd", + target_os = "netbsd", + target_os = "illumos", + target_os = "solaris", + target_vendor = "apple", + )))] + fn get_path(_fd: c_int) -> Option { + // FIXME(#24570): implement this for other Unix platforms + None + } + + get_path(fd) +} #[cfg(any( target_os = "aix", @@ -874,7 +998,7 @@ pub(crate) fn debug_assert_fd_is_open(fd: RawFd) { } } -impl Drop for Dir { +impl Drop for DirStream { fn drop(&mut self) { // dirfd isn't supported everywhere #[cfg(not(any( @@ -902,6 +1026,11 @@ impl Drop for Dir { } } +// SAFETY: `int dirfd (DIR *dirstream)` is MT-safe, implying that the pointer +// may be safely sent among threads. +unsafe impl Send for DirStream {} +unsafe impl Sync for DirStream {} + impl DirEntry { pub fn path(&self) -> PathBuf { self.dir.root.join(self.file_name_os_str()) @@ -1860,102 +1989,8 @@ impl FromRawFd for File { impl fmt::Debug for File { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(any(target_os = "linux", target_os = "illumos", target_os = "solaris"))] - fn get_path(fd: c_int) -> Option { - let mut p = PathBuf::from("/proc/self/fd"); - p.push(&fd.to_string()); - run_path_with_cstr(&p, &readlink).ok() - } - - #[cfg(any(target_vendor = "apple", target_os = "netbsd"))] - fn get_path(fd: c_int) -> Option { - // FIXME: The use of PATH_MAX is generally not encouraged, but it - // is inevitable in this case because Apple targets and NetBSD define `fcntl` - // with `F_GETPATH` in terms of `MAXPATHLEN`, and there are no - // alternatives. If a better method is invented, it should be used - // instead. - let mut buf = vec![0; libc::PATH_MAX as usize]; - let n = unsafe { libc::fcntl(fd, libc::F_GETPATH, buf.as_ptr()) }; - if n == -1 { - cfg_select! { - target_os = "netbsd" => { - // fallback to procfs as last resort - let mut p = PathBuf::from("/proc/self/fd"); - p.push(&fd.to_string()); - return run_path_with_cstr(&p, &readlink).ok() - } - _ => { - return None; - } - } - } - let l = buf.iter().position(|&c| c == 0).unwrap(); - buf.truncate(l as usize); - buf.shrink_to_fit(); - Some(PathBuf::from(OsString::from_vec(buf))) - } - - #[cfg(target_os = "freebsd")] - fn get_path(fd: c_int) -> Option { - let info = Box::::new_zeroed(); - let mut info = unsafe { info.assume_init() }; - info.kf_structsize = size_of::() as libc::c_int; - let n = unsafe { libc::fcntl(fd, libc::F_KINFO, &mut *info) }; - if n == -1 { - return None; - } - let buf = unsafe { CStr::from_ptr(info.kf_path.as_mut_ptr()).to_bytes().to_vec() }; - Some(PathBuf::from(OsString::from_vec(buf))) - } - - #[cfg(target_os = "vxworks")] - fn get_path(fd: c_int) -> Option { - let mut buf = vec![0; libc::PATH_MAX as usize]; - let n = unsafe { libc::ioctl(fd, libc::FIOGETNAME, buf.as_ptr()) }; - if n == -1 { - return None; - } - let l = buf.iter().position(|&c| c == 0).unwrap(); - buf.truncate(l as usize); - Some(PathBuf::from(OsString::from_vec(buf))) - } - - #[cfg(not(any( - target_os = "linux", - target_os = "vxworks", - target_os = "freebsd", - target_os = "netbsd", - target_os = "illumos", - target_os = "solaris", - target_vendor = "apple", - )))] - fn get_path(_fd: c_int) -> Option { - // FIXME(#24570): implement this for other Unix platforms - None - } - - fn get_mode(fd: c_int) -> Option<(bool, bool)> { - let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) }; - if mode == -1 { - return None; - } - match mode & libc::O_ACCMODE { - libc::O_RDONLY => Some((true, false)), - libc::O_RDWR => Some((true, true)), - libc::O_WRONLY => Some((false, true)), - _ => None, - } - } - let fd = self.as_raw_fd(); - let mut b = f.debug_struct("File"); - b.field("fd", &fd); - if let Some(path) = get_path(fd) { - b.field("path", &path); - } - if let Some((read, write)) = get_mode(fd) { - b.field("read", &read).field("write", &write); - } + let mut b = debug_path_fd(fd, f, "File"); b.finish() } } @@ -2033,7 +2068,7 @@ pub fn readdir(path: &Path) -> io::Result { Err(Error::last_os_error()) } else { let root = path.to_path_buf(); - let inner = InnerReadDir { dirp: Dir(ptr), root }; + let inner = InnerReadDir { dirp: DirStream(ptr), root }; Ok(ReadDir::new(inner)) } } @@ -2493,7 +2528,8 @@ mod remove_dir_impl { use libc::{fdopendir, openat64 as openat, unlinkat}; use super::{ - AsRawFd, Dir, DirEntry, FromRawFd, InnerReadDir, IntoRawFd, OwnedFd, RawFd, ReadDir, lstat, + AsRawFd, DirEntry, DirStream, FromRawFd, InnerReadDir, IntoRawFd, OwnedFd, RawFd, ReadDir, + lstat, }; use crate::ffi::CStr; use crate::io; @@ -2517,7 +2553,7 @@ mod remove_dir_impl { if ptr.is_null() { return Err(io::Error::last_os_error()); } - let dirp = Dir(ptr); + let dirp = DirStream(ptr); // file descriptor is automatically closed by libc::closedir() now, so give up ownership let new_parent_fd = dir_fd.into_raw_fd(); // a valid root is not needed because we do not call any functions involving the full path diff --git a/library/std/src/sys/fs/unix/dir.rs b/library/std/src/sys/fs/unix/dir.rs new file mode 100644 index 000000000000..094d1bfd3168 --- /dev/null +++ b/library/std/src/sys/fs/unix/dir.rs @@ -0,0 +1,114 @@ +use libc::c_int; + +cfg_select! { + not( + any( + all(target_os = "linux", not(target_env = "musl")), + target_os = "l4re", + target_os = "android", + target_os = "hurd", + ) + ) => { + use libc::{open as open64, openat as openat64}; + } + _ => { + use libc::{open64, openat64}; + } +} + +use crate::ffi::CStr; +use crate::os::fd::{AsFd, BorrowedFd, IntoRawFd, OwnedFd, RawFd}; +#[cfg(target_family = "unix")] +use crate::os::unix::io::{AsRawFd, FromRawFd}; +#[cfg(target_os = "wasi")] +use crate::os::wasi::io::{AsRawFd, FromRawFd}; +use crate::path::Path; +use crate::sys::fd::FileDesc; +use crate::sys::fs::OpenOptions; +use crate::sys::fs::unix::{File, debug_path_fd}; +use crate::sys::helpers::run_path_with_cstr; +use crate::sys::{AsInner, FromInner, IntoInner, cvt_r}; +use crate::{fmt, fs, io}; + +pub struct Dir(OwnedFd); + +impl Dir { + pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { + run_path_with_cstr(path, &|path| Self::open_with_c(path, opts)) + } + + pub fn open_file(&self, path: &Path, opts: &OpenOptions) -> io::Result { + run_path_with_cstr(path.as_ref(), &|path| self.open_file_c(path, &opts)) + } + + pub fn open_with_c(path: &CStr, opts: &OpenOptions) -> io::Result { + let flags = libc::O_CLOEXEC + | libc::O_DIRECTORY + | opts.get_access_mode()? + | opts.get_creation_mode()? + | (opts.custom_flags as c_int & !libc::O_ACCMODE); + let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode as c_int) })?; + Ok(Self(unsafe { OwnedFd::from_raw_fd(fd) })) + } + + fn open_file_c(&self, path: &CStr, opts: &OpenOptions) -> io::Result { + let flags = libc::O_CLOEXEC + | opts.get_access_mode()? + | opts.get_creation_mode()? + | (opts.custom_flags as c_int & !libc::O_ACCMODE); + let fd = cvt_r(|| unsafe { + openat64(self.0.as_raw_fd(), path.as_ptr(), flags, opts.mode as c_int) + })?; + Ok(File(unsafe { FileDesc::from_raw_fd(fd) })) + } +} + +impl fmt::Debug for Dir { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let fd = self.0.as_raw_fd(); + let mut b = debug_path_fd(fd, f, "Dir"); + b.finish() + } +} + +#[unstable(feature = "dirfd", issue = "120426")] +impl AsRawFd for fs::Dir { + fn as_raw_fd(&self) -> RawFd { + self.as_inner().0.as_raw_fd() + } +} + +#[unstable(feature = "dirfd", issue = "120426")] +impl IntoRawFd for fs::Dir { + fn into_raw_fd(self) -> RawFd { + self.into_inner().0.into_raw_fd() + } +} + +#[unstable(feature = "dirfd", issue = "120426")] +impl FromRawFd for fs::Dir { + unsafe fn from_raw_fd(fd: RawFd) -> Self { + Self::from_inner(Dir(unsafe { FromRawFd::from_raw_fd(fd) })) + } +} + +#[unstable(feature = "dirfd", issue = "120426")] +impl AsFd for fs::Dir { + fn as_fd(&self) -> BorrowedFd<'_> { + self.as_inner().0.as_fd() + } +} + +#[unstable(feature = "dirfd", issue = "120426")] +impl From for OwnedFd { + fn from(value: fs::Dir) -> Self { + value.into_inner().0 + } +} + +#[unstable(feature = "dirfd", issue = "120426")] +impl From for fs::Dir { + fn from(value: OwnedFd) -> Self { + Self::from_inner(Dir(value)) + } +} diff --git a/library/std/src/sys/fs/unsupported.rs b/library/std/src/sys/fs/unsupported.rs index f222151d18e2..069b4fb8a29c 100644 --- a/library/std/src/sys/fs/unsupported.rs +++ b/library/std/src/sys/fs/unsupported.rs @@ -4,6 +4,7 @@ use crate::fs::TryLockError; use crate::hash::{Hash, Hasher}; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; +pub use crate::sys::fs::common::Dir; use crate::sys::time::SystemTime; use crate::sys::unsupported; diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index b588b91c753b..2e3d50aa0e08 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -18,6 +18,8 @@ use crate::sys::time::SystemTime; use crate::sys::{Align8, AsInner, FromInner, IntoInner, c, cvt}; use crate::{fmt, ptr, slice}; +mod dir; +pub use dir::Dir; mod remove_dir_all; use remove_dir_all::remove_dir_all_iterative; @@ -274,7 +276,7 @@ impl OpenOptions { } } - fn get_creation_mode(&self) -> io::Result { + fn get_cmode_disposition(&self) -> io::Result<(u32, u32)> { match (self.write, self.append) { (true, false) => {} (false, false) => { @@ -296,16 +298,24 @@ impl OpenOptions { } Ok(match (self.create, self.truncate, self.create_new) { - (false, false, false) => c::OPEN_EXISTING, - (true, false, false) => c::OPEN_ALWAYS, - (false, true, false) => c::TRUNCATE_EXISTING, + (false, false, false) => (c::OPEN_EXISTING, c::FILE_OPEN), + (true, false, false) => (c::OPEN_ALWAYS, c::FILE_OPEN_IF), + (false, true, false) => (c::TRUNCATE_EXISTING, c::FILE_OVERWRITE), // `CREATE_ALWAYS` has weird semantics so we emulate it using // `OPEN_ALWAYS` and a manual truncation step. See #115745. - (true, true, false) => c::OPEN_ALWAYS, - (_, _, true) => c::CREATE_NEW, + (true, true, false) => (c::OPEN_ALWAYS, c::FILE_OVERWRITE_IF), + (_, _, true) => (c::CREATE_NEW, c::FILE_CREATE), }) } + fn get_creation_mode(&self) -> io::Result { + self.get_cmode_disposition().map(|(mode, _)| mode) + } + + fn get_disposition(&self) -> io::Result { + self.get_cmode_disposition().map(|(_, mode)| mode) + } + fn get_flags_and_attributes(&self) -> u32 { self.custom_flags | self.attributes @@ -1019,14 +1029,23 @@ impl FromRawHandle for File { } } +fn debug_path_handle<'a, 'b>( + handle: BorrowedHandle<'a>, + f: &'a mut fmt::Formatter<'b>, + name: &str, +) -> fmt::DebugStruct<'a, 'b> { + // FIXME(#24570): add more info here (e.g., mode) + let mut b = f.debug_struct(name); + b.field("handle", &handle.as_raw_handle()); + if let Ok(path) = get_path(handle) { + b.field("path", &path); + } + b +} + impl fmt::Debug for File { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // FIXME(#24570): add more info here (e.g., mode) - let mut b = f.debug_struct("File"); - b.field("handle", &self.handle.as_raw_handle()); - if let Ok(path) = get_path(self) { - b.field("path", &path); - } + let mut b = debug_path_handle(self.handle.as_handle(), f, "File"); b.finish() } } @@ -1292,8 +1311,8 @@ pub fn rename(old: &WCStr, new: &WCStr) -> io::Result<()> { Layout::from_size_align(struct_size as usize, align_of::()) .unwrap(); - // SAFETY: We allocate enough memory for a full FILE_RENAME_INFO struct and a filename. let file_rename_info; + // SAFETY: We allocate enough memory for a full FILE_RENAME_INFO struct and a filename. unsafe { file_rename_info = alloc(layout).cast::(); if file_rename_info.is_null() { @@ -1530,10 +1549,10 @@ pub fn set_times_nofollow(p: &WCStr, times: FileTimes) -> io::Result<()> { file.set_times(times) } -fn get_path(f: &File) -> io::Result { +fn get_path(f: impl AsRawHandle) -> io::Result { fill_utf16_buf( |buf, sz| unsafe { - c::GetFinalPathNameByHandleW(f.handle.as_raw_handle(), buf, sz, c::VOLUME_NAME_DOS) + c::GetFinalPathNameByHandleW(f.as_raw_handle(), buf, sz, c::VOLUME_NAME_DOS) }, |buf| PathBuf::from(OsString::from_wide(buf)), ) @@ -1546,7 +1565,7 @@ pub fn canonicalize(p: &WCStr) -> io::Result { // This flag is so we can open directories too opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS); let f = File::open_native(p, &opts)?; - get_path(&f) + get_path(f.handle) } pub fn copy(from: &WCStr, to: &WCStr) -> io::Result { diff --git a/library/std/src/sys/fs/windows/dir.rs b/library/std/src/sys/fs/windows/dir.rs new file mode 100644 index 000000000000..3f617806c6c3 --- /dev/null +++ b/library/std/src/sys/fs/windows/dir.rs @@ -0,0 +1,153 @@ +use crate::os::windows::io::{ + AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, HandleOrInvalid, IntoRawHandle, + OwnedHandle, RawHandle, +}; +use crate::path::Path; +use crate::sys::api::{UnicodeStrRef, WinError}; +use crate::sys::fs::windows::debug_path_handle; +use crate::sys::fs::{File, OpenOptions}; +use crate::sys::handle::Handle; +use crate::sys::path::{WCStr, with_native_path}; +use crate::sys::{AsInner, FromInner, IntoInner, IoResult, c, to_u16s}; +use crate::{fmt, fs, io, ptr}; + +pub struct Dir { + handle: Handle, +} + +/// A wrapper around a raw NtCreateFile call. +/// +/// This isn't completely safe because `OBJECT_ATTRIBUTES` contains raw pointers. +unsafe fn nt_create_file( + opts: &OpenOptions, + object_attributes: &c::OBJECT_ATTRIBUTES, + create_options: c::NTCREATEFILE_CREATE_OPTIONS, +) -> io::Result { + let mut handle = ptr::null_mut(); + let mut io_status = c::IO_STATUS_BLOCK::PENDING; + // SYNCHRONIZE is included in FILE_GENERIC_READ, but not GENERIC_READ, so we add it manually + let access = opts.get_access_mode()? | c::SYNCHRONIZE; + // one of FILE_SYNCHRONOUS_IO_{,NON}ALERT is required for later operations to succeed. + let options = create_options | c::FILE_SYNCHRONOUS_IO_NONALERT; + let status = unsafe { + c::NtCreateFile( + &mut handle, + access, + object_attributes, + &mut io_status, + ptr::null(), + c::FILE_ATTRIBUTE_NORMAL, + opts.share_mode, + opts.get_disposition()?, + options, + ptr::null(), + 0, + ) + }; + if c::nt_success(status) { + // SAFETY: nt_success guarantees that handle is no longer null + unsafe { Ok(Handle::from_raw_handle(handle)) } + } else { + Err(WinError::new(unsafe { c::RtlNtStatusToDosError(status) })).io_result() + } +} + +impl Dir { + pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { + with_native_path(path, &|path| Self::open_with_native(path, opts)) + } + + pub fn open_file(&self, path: &Path, opts: &OpenOptions) -> io::Result { + // NtCreateFile will fail if given an absolute path and a non-null RootDirectory + if path.is_absolute() { + return File::open(path, opts); + } + let path = to_u16s(path)?; + let path = &path[..path.len() - 1]; // trim 0 byte + self.open_file_native(&path, opts).map(|handle| File { handle }) + } + + fn open_with_native(path: &WCStr, opts: &OpenOptions) -> io::Result { + let creation = opts.get_creation_mode()?; + let sa = c::SECURITY_ATTRIBUTES { + nLength: size_of::() as u32, + lpSecurityDescriptor: ptr::null_mut(), + bInheritHandle: opts.inherit_handle as c::BOOL, + }; + let handle = unsafe { + c::CreateFileW( + path.as_ptr(), + opts.get_access_mode()?, + opts.share_mode, + &raw const sa, + creation, + // FILE_FLAG_BACKUP_SEMANTICS is required to open a directory + opts.get_flags_and_attributes() | c::FILE_FLAG_BACKUP_SEMANTICS, + ptr::null_mut(), + ) + }; + match OwnedHandle::try_from(unsafe { HandleOrInvalid::from_raw_handle(handle) }) { + Ok(handle) => Ok(Self { handle: Handle::from_inner(handle) }), + Err(_) => Err(io::Error::last_os_error()), + } + } + + fn open_file_native(&self, path: &[u16], opts: &OpenOptions) -> io::Result { + let name = UnicodeStrRef::from_slice(path); + let object_attributes = c::OBJECT_ATTRIBUTES { + RootDirectory: self.handle.as_raw_handle(), + ObjectName: name.as_ptr(), + ..c::OBJECT_ATTRIBUTES::with_length() + }; + unsafe { nt_create_file(opts, &object_attributes, c::FILE_NON_DIRECTORY_FILE) } + } +} + +impl fmt::Debug for Dir { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut b = debug_path_handle(self.handle.as_handle(), f, "Dir"); + b.finish() + } +} + +#[unstable(feature = "dirfd", issue = "120426")] +impl AsRawHandle for fs::Dir { + fn as_raw_handle(&self) -> RawHandle { + self.as_inner().handle.as_raw_handle() + } +} + +#[unstable(feature = "dirhandle", issue = "120426")] +impl IntoRawHandle for fs::Dir { + fn into_raw_handle(self) -> RawHandle { + self.into_inner().handle.into_raw_handle() + } +} + +#[unstable(feature = "dirhandle", issue = "120426")] +impl FromRawHandle for fs::Dir { + unsafe fn from_raw_handle(handle: RawHandle) -> Self { + Self::from_inner(Dir { handle: unsafe { FromRawHandle::from_raw_handle(handle) } }) + } +} + +#[unstable(feature = "dirhandle", issue = "120426")] +impl AsHandle for fs::Dir { + fn as_handle(&self) -> BorrowedHandle<'_> { + self.as_inner().handle.as_handle() + } +} + +#[unstable(feature = "dirhandle", issue = "120426")] +impl From for OwnedHandle { + fn from(value: fs::Dir) -> Self { + value.into_inner().handle.into_inner() + } +} + +#[unstable(feature = "dirhandle", issue = "120426")] +impl From for fs::Dir { + fn from(value: OwnedHandle) -> Self { + Self::from_inner(Dir { handle: Handle::from_inner(value) }) + } +} From 52d65b8a626ae074f45e19c8d8cfe41a5f5e444b Mon Sep 17 00:00:00 2001 From: Alessio Date: Sun, 4 Jan 2026 03:53:26 +0100 Subject: [PATCH 1566/3801] library: clarify panic conditions in `Iterator::last` Now `Iterator::last`'s docs specify that it might panic only if the iterator is infinite, rather than if it has more than `usize::MAX` elements. --- library/core/src/iter/traits/iterator.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 84da778c3b91..f106900a3983 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -238,8 +238,7 @@ pub trait Iterator { /// /// # Panics /// - /// This function might panic if the iterator has more than [`usize::MAX`] - /// elements. + /// This function might panic if the iterator is infinite. /// /// # Examples /// From 759857cce3f0b4cb72de251595ecf8c28408cead Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sun, 4 Jan 2026 11:53:31 +0800 Subject: [PATCH 1567/3801] Add missing translator resources for interface parse_cfg and parse_check_cfg --- compiler/rustc_interface/src/interface.rs | 12 ++++++++++-- tests/ui/cfg/invalid-cli-cfg-pred.rs | 5 +++++ tests/ui/cfg/invalid-cli-cfg-pred.stderr | 7 +++++++ tests/ui/cfg/invalid-cli-check-cfg-pred.rs | 5 +++++ tests/ui/cfg/invalid-cli-check-cfg-pred.stderr | 10 ++++++++++ 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 tests/ui/cfg/invalid-cli-cfg-pred.rs create mode 100644 tests/ui/cfg/invalid-cli-cfg-pred.stderr create mode 100644 tests/ui/cfg/invalid-cli-check-cfg-pred.rs create mode 100644 tests/ui/cfg/invalid-cli-check-cfg-pred.stderr diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index c0f8f33692e8..b2c4a9158197 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -55,7 +55,11 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec) -> Cfg { cfgs.into_iter() .map(|s| { let psess = ParseSess::emitter_with_note( - vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + vec![ + crate::DEFAULT_LOCALE_RESOURCE, + rustc_parse::DEFAULT_LOCALE_RESOURCE, + rustc_session::DEFAULT_LOCALE_RESOURCE, + ], format!("this occurred on the command line: `--cfg={s}`"), ); let filename = FileName::cfg_spec_source_code(&s); @@ -129,7 +133,11 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec) -> Ch for s in specs { let psess = ParseSess::emitter_with_note( - vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + vec![ + crate::DEFAULT_LOCALE_RESOURCE, + rustc_parse::DEFAULT_LOCALE_RESOURCE, + rustc_session::DEFAULT_LOCALE_RESOURCE, + ], format!("this occurred on the command line: `--check-cfg={s}`"), ); let filename = FileName::cfg_spec_source_code(&s); diff --git a/tests/ui/cfg/invalid-cli-cfg-pred.rs b/tests/ui/cfg/invalid-cli-cfg-pred.rs new file mode 100644 index 000000000000..fdfb6b18d96b --- /dev/null +++ b/tests/ui/cfg/invalid-cli-cfg-pred.rs @@ -0,0 +1,5 @@ +//@ compile-flags: --cfg foo=1x + +fn main() {} + +//~? ERROR invalid `--cfg` argument diff --git a/tests/ui/cfg/invalid-cli-cfg-pred.stderr b/tests/ui/cfg/invalid-cli-cfg-pred.stderr new file mode 100644 index 000000000000..2f5ed55a6423 --- /dev/null +++ b/tests/ui/cfg/invalid-cli-cfg-pred.stderr @@ -0,0 +1,7 @@ +error: invalid suffix `x` for number literal + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + = note: this occurred on the command line: `--cfg=foo=1x` + +error: invalid `--cfg` argument: `foo=1x` (expected `key` or `key="value"`, ensure escaping is appropriate for your shell, try 'key="value"' or key=\"value\") + diff --git a/tests/ui/cfg/invalid-cli-check-cfg-pred.rs b/tests/ui/cfg/invalid-cli-check-cfg-pred.rs new file mode 100644 index 000000000000..30417a912bfc --- /dev/null +++ b/tests/ui/cfg/invalid-cli-check-cfg-pred.rs @@ -0,0 +1,5 @@ +//@ compile-flags: --check-cfg 'foo=1x' + +fn main() {} + +//~? ERROR invalid `--check-cfg` argument diff --git a/tests/ui/cfg/invalid-cli-check-cfg-pred.stderr b/tests/ui/cfg/invalid-cli-check-cfg-pred.stderr new file mode 100644 index 000000000000..be8299aa9edf --- /dev/null +++ b/tests/ui/cfg/invalid-cli-check-cfg-pred.stderr @@ -0,0 +1,10 @@ +error: invalid suffix `x` for number literal + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + = note: this occurred on the command line: `--check-cfg=foo=1x` + +error: invalid `--check-cfg` argument: `foo=1x` + | + = note: expected `cfg(name, values("value1", "value2", ... "valueN"))` + = note: visit for more details + From 46bb414d69749ad7afe3ea8e0e4fd09ae7fe3d6b Mon Sep 17 00:00:00 2001 From: enthropy7 <221884178+enthropy7@users.noreply.github.com> Date: Sat, 3 Jan 2026 16:22:29 +0300 Subject: [PATCH 1568/3801] Forbid generic parameters in types of #[type_const] items --- compiler/rustc_resolve/src/late.rs | 58 ++++++++++++++++++- .../assoc-const-eq-bound-var-in-ty-not-wf.rs | 1 + ...soc-const-eq-bound-var-in-ty-not-wf.stderr | 4 +- .../assoc-const-eq-bound-var-in-ty.rs | 1 + .../assoc-const-eq-esc-bound-var-in-ty.rs | 7 ++- .../assoc-const-eq-esc-bound-var-in-ty.stderr | 2 +- .../assoc-const-eq-param-in-ty.rs | 1 + .../assoc-const-eq-param-in-ty.stderr | 22 +++---- .../assoc-const-eq-supertraits.rs | 1 + ...pe_const-generic-param-in-type.gate.stderr | 38 ++++++++++++ ..._const-generic-param-in-type.nogate.stderr | 57 ++++++++++++++++++ .../mgca/type_const-generic-param-in-type.rs | 54 +++++++++++++++++ 12 files changed, 228 insertions(+), 18 deletions(-) create mode 100644 tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr create mode 100644 tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr create mode 100644 tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index dd80f5da508c..2bbaacce53f8 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2855,6 +2855,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ref define_opaque, .. }) => { + let is_type_const = attr::contains_name(&item.attrs, sym::type_const); self.with_generic_param_rib( &generics.params, RibKind::Item( @@ -2873,7 +2874,22 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.with_lifetime_rib( LifetimeRibKind::Elided(LifetimeRes::Static), - |this| this.visit_ty(ty), + |this| { + if is_type_const + && !this.r.tcx.features().generic_const_parameter_types() + { + this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { + this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { + this.with_lifetime_rib( + LifetimeRibKind::ConstParamTy, + |this| this.visit_ty(ty), + ) + }) + }); + } else { + this.visit_ty(ty); + } + }, ); if let Some(rhs) = rhs { @@ -3213,6 +3229,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { define_opaque, .. }) => { + let is_type_const = attr::contains_name(&item.attrs, sym::type_const); self.with_generic_param_rib( &generics.params, RibKind::AssocItem, @@ -3227,7 +3244,20 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, |this| { this.visit_generics(generics); - this.visit_ty(ty); + if is_type_const + && !this.r.tcx.features().generic_const_parameter_types() + { + this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { + this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { + this.with_lifetime_rib( + LifetimeRibKind::ConstParamTy, + |this| this.visit_ty(ty), + ) + }) + }); + } else { + this.visit_ty(ty); + } // Only impose the restrictions of `ConstRibKind` for an // actual constant expression in a provided default. @@ -3422,6 +3452,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .. }) => { debug!("resolve_implementation AssocItemKind::Const"); + let is_type_const = attr::contains_name(&item.attrs, sym::type_const); self.with_generic_param_rib( &generics.params, RibKind::AssocItem, @@ -3458,7 +3489,28 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); this.visit_generics(generics); - this.visit_ty(ty); + if is_type_const + && !this + .r + .tcx + .features() + .generic_const_parameter_types() + { + this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { + this.with_rib( + ValueNS, + RibKind::ConstParamTy, + |this| { + this.with_lifetime_rib( + LifetimeRibKind::ConstParamTy, + |this| this.visit_ty(ty), + ) + }, + ) + }); + } else { + this.visit_ty(ty); + } if let Some(rhs) = rhs { // We allow arbitrary const expressions inside of associated consts, // even if they are potentially not const evaluatable. diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index 7f8b3036c3e8..50914fb192ff 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -5,6 +5,7 @@ min_generic_const_args, adt_const_params, unsized_const_params, + generic_const_parameter_types, )] #![allow(incomplete_features)] diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index 76868715b861..fd49e151b8e6 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:22:13 | LL | K = const { () } | ^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:22:13 | LL | K = const { () } | ^^^^^^^^^^^^ diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs index d3975bc19ad3..54e199d702c9 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs @@ -8,6 +8,7 @@ min_generic_const_args, adt_const_params, unsized_const_params, + generic_const_parameter_types, )] #![allow(incomplete_features)] diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs index 2571af57e66b..7f9a04bbf0fc 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs @@ -1,6 +1,11 @@ // Detect and reject escaping late-bound generic params in // the type of assoc consts used in an equality bound. -#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] +#![feature( + associated_const_equality, + min_generic_const_args, + unsized_const_params, + generic_const_parameter_types, +)] #![allow(incomplete_features)] trait Trait<'a> { diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr index 44304443ac54..e22d9bfed7ef 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` cannot capture late-bound generic parameters - --> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:11:35 + --> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:16:35 | LL | fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} | -- ^ its type cannot capture the late-bound lifetime parameter `'r` diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs index 242ad385947a..ea2f60cd6187 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs @@ -5,6 +5,7 @@ min_generic_const_args, adt_const_params, unsized_const_params, + generic_const_parameter_types, )] #![allow(incomplete_features)] diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr index b742e68044b0..ae6a35b4b9f2 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 + --> $DIR/assoc-const-eq-param-in-ty.rs:23:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | -- the lifetime parameter `'r` is defined here @@ -10,7 +10,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 + --> $DIR/assoc-const-eq-param-in-ty.rs:23:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | - the type parameter `A` is defined here @@ -21,7 +21,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 + --> $DIR/assoc-const-eq-param-in-ty.rs:23:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | - the const parameter `Q` is defined here @@ -32,7 +32,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/assoc-const-eq-param-in-ty.rs:39:26 + --> $DIR/assoc-const-eq-param-in-ty.rs:40:26 | LL | fn take1(_: impl Project) {} | -------------^^^^------------ @@ -41,7 +41,7 @@ LL | fn take1(_: impl Project) {} | the `impl Trait` is specified here error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:21 + --> $DIR/assoc-const-eq-param-in-ty.rs:45:21 | LL | fn take2>(_: P) {} | - ^^^^ its type must not depend on the type parameter `P` @@ -51,7 +51,7 @@ LL | fn take2>(_: P) {} = note: `SELF` has type `P` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here @@ -62,7 +62,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -70,7 +70,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` @@ -80,7 +80,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here @@ -92,7 +92,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -101,7 +101,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` diff --git a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs index d9b8a8cd43d7..c092285dfcd4 100644 --- a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs +++ b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs @@ -8,6 +8,7 @@ min_generic_const_args, adt_const_params, unsized_const_params, + generic_const_parameter_types, )] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr new file mode 100644 index 000000000000..8a64af285da5 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr @@ -0,0 +1,38 @@ +error: anonymous constants referencing generics are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:9:53 + | +LL | const FOO: [T; 0] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants referencing generics are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:14:38 + | +LL | const BAR: [(); N] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants with lifetimes in their type are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:19:30 + | +LL | const BAZ<'a>: [&'a (); 0] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants referencing generics are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:39:59 + | +LL | const ASSOC: [T; 0] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants referencing generics are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:44:50 + | +LL | const ASSOC_CONST: [(); N] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants with lifetimes in their type are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:49:39 + | +LL | const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; + | ^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr new file mode 100644 index 000000000000..14ae276324ad --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr @@ -0,0 +1,57 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:9:45 + | +LL | const FOO: [T; 0] = const { [] }; + | ^ the type must not depend on the parameter `T` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:14:33 + | +LL | const BAR: [(); N] = const { [] }; + | ^ the type must not depend on the parameter `N` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:19:18 + | +LL | const BAZ<'a>: [&'a (); 0] = const { [] }; + | ^^ the type must not depend on the parameter `'a` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:25:51 + | +LL | const ASSOC: [T; 0]; + | ^ the type must not depend on the parameter `T` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:29:45 + | +LL | const ASSOC_CONST: [(); N]; + | ^ the type must not depend on the parameter `N` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:33:27 + | +LL | const ASSOC_LT<'a>: [&'a (); 0]; + | ^^ the type must not depend on the parameter `'a` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:39:51 + | +LL | const ASSOC: [T; 0] = const { [] }; + | ^ the type must not depend on the parameter `T` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:44:45 + | +LL | const ASSOC_CONST: [(); N] = const { [] }; + | ^ the type must not depend on the parameter `N` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:49:27 + | +LL | const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; + | ^^ the type must not depend on the parameter `'a` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs new file mode 100644 index 000000000000..f1a4aba9bcee --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs @@ -0,0 +1,54 @@ +//@ revisions: nogate gate +//@ [gate] check-fail +// FIXME(generic_const_parameter_types): this should pass +#![expect(incomplete_features)] +#![feature(adt_const_params, unsized_const_params, min_generic_const_args, generic_const_items)] +#![cfg_attr(gate, feature(generic_const_parameter_types))] + +#[type_const] +const FOO: [T; 0] = const { [] }; +//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters +//[gate]~^^ ERROR anonymous constants referencing generics are not yet supported + +#[type_const] +const BAR: [(); N] = const { [] }; +//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters +//[gate]~^^ ERROR anonymous constants referencing generics are not yet supported + +#[type_const] +const BAZ<'a>: [&'a (); 0] = const { [] }; +//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters +//[gate]~^^ ERROR anonymous constants with lifetimes in their type are not yet supported + +trait Tr { + #[type_const] + const ASSOC: [T; 0]; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + + #[type_const] + const ASSOC_CONST: [(); N]; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + + #[type_const] + const ASSOC_LT<'a>: [&'a (); 0]; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters +} + +impl Tr for () { + #[type_const] + const ASSOC: [T; 0] = const { [] }; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + //[gate]~^^ ERROR anonymous constants referencing generics are not yet supported + + #[type_const] + const ASSOC_CONST: [(); N] = const { [] }; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + //[gate]~^^ ERROR anonymous constants referencing generics are not yet supported + + #[type_const] + const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + //[gate]~^^ ERROR anonymous constants with lifetimes in their type are not yet supported +} + +fn main() {} From de377241fb6490ed92fc8c9b6d9d2a0428da26f8 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 4 Jan 2026 14:12:40 +1100 Subject: [PATCH 1569/3801] Prefer to pass HIR nodes instead of loose types/spans This should make it easier to keep track of where the types/spans came from. --- .../rustc_mir_build/src/thir/pattern/mod.rs | 91 +++++++++++++------ 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 0310003e7d58..988baae49141 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -4,6 +4,7 @@ mod check_match; mod const_to_pat; mod migration; +use std::assert_matches::assert_matches; use std::cmp::Ordering; use std::sync::Arc; @@ -21,7 +22,7 @@ use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment}; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; -use rustc_span::{ErrorGuaranteed, Span}; +use rustc_span::ErrorGuaranteed; use tracing::{debug, instrument}; pub(crate) use self::check_match::check_match; @@ -129,15 +130,20 @@ impl<'tcx> PatCtxt<'tcx> { fn lower_pattern_range_endpoint( &mut self, + pat: &'tcx hir::Pat<'tcx>, // Range pattern containing the endpoint expr: Option<&'tcx hir::PatExpr<'tcx>>, // Out-parameter collecting extra data to be reapplied by the caller ascriptions: &mut Vec>, ) -> Result>, ErrorGuaranteed> { + assert_matches!(pat.kind, hir::PatKind::Range(..)); + + // For partly-bounded ranges like `X..` or `..X`, an endpoint will be absent. + // Return None in that case; the caller will use NegInfinity or PosInfinity instead. let Some(expr) = expr else { return Ok(None) }; // Lower the endpoint into a temporary `PatKind` that will then be // deconstructed to obtain the constant value and other data. - let mut kind: PatKind<'tcx> = self.lower_pat_expr(expr, None); + let mut kind: PatKind<'tcx> = self.lower_pat_expr(pat, expr); // Unpeel any ascription or inline-const wrapper nodes. loop { @@ -214,12 +220,14 @@ impl<'tcx> PatCtxt<'tcx> { fn lower_pattern_range( &mut self, + pat: &'tcx hir::Pat<'tcx>, lo_expr: Option<&'tcx hir::PatExpr<'tcx>>, hi_expr: Option<&'tcx hir::PatExpr<'tcx>>, end: RangeEnd, - ty: Ty<'tcx>, - span: Span, ) -> Result, ErrorGuaranteed> { + let ty = self.typeck_results.node_type(pat.hir_id); + let span = pat.span; + if lo_expr.is_none() && hi_expr.is_none() { let msg = "found twice-open range pattern (`..`) outside of error recovery"; self.tcx.dcx().span_bug(span, msg); @@ -227,7 +235,8 @@ impl<'tcx> PatCtxt<'tcx> { // Collect extra data while lowering the endpoints, to be reapplied later. let mut ascriptions = vec![]; - let mut lower_endpoint = |expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions); + let mut lower_endpoint = + |expr| self.lower_pattern_range_endpoint(pat, expr, &mut ascriptions); let lo = lower_endpoint(lo_expr)?.unwrap_or(PatRangeBoundary::NegInfinity); let hi = lower_endpoint(hi_expr)?.unwrap_or(PatRangeBoundary::PosInfinity); @@ -299,12 +308,10 @@ impl<'tcx> PatCtxt<'tcx> { hir::PatKind::Never => PatKind::Never, - hir::PatKind::Expr(value) => self.lower_pat_expr(value, Some(ty)), + hir::PatKind::Expr(value) => self.lower_pat_expr(pat, value), - hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => { - let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref()); - self.lower_pattern_range(lo_expr, hi_expr, end, ty, span) - .unwrap_or_else(PatKind::Error) + hir::PatKind::Range(lo_expr, hi_expr, end) => { + self.lower_pattern_range(pat, lo_expr, hi_expr, end).unwrap_or_else(PatKind::Error) } hir::PatKind::Deref(subpattern) => { @@ -327,7 +334,7 @@ impl<'tcx> PatCtxt<'tcx> { }, hir::PatKind::Slice(prefix, slice, suffix) => { - self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix) + self.slice_or_array_pattern(pat, prefix, slice, suffix) } hir::PatKind::Tuple(pats, ddpos) => { @@ -389,7 +396,7 @@ impl<'tcx> PatCtxt<'tcx> { }; let variant_def = adt_def.variant_of_res(res); let subpatterns = self.lower_tuple_subpats(pats, variant_def.fields.len(), ddpos); - self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns) + self.lower_variant_or_leaf(pat, None, res, subpatterns) } hir::PatKind::Struct(ref qpath, fields, _) => { @@ -406,7 +413,7 @@ impl<'tcx> PatCtxt<'tcx> { }) .collect(); - self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns) + self.lower_variant_or_leaf(pat, None, res, subpatterns) } hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) }, @@ -445,12 +452,13 @@ impl<'tcx> PatCtxt<'tcx> { fn slice_or_array_pattern( &mut self, - span: Span, - ty: Ty<'tcx>, + pat: &'tcx hir::Pat<'tcx>, prefix: &'tcx [hir::Pat<'tcx>], slice: Option<&'tcx hir::Pat<'tcx>>, suffix: &'tcx [hir::Pat<'tcx>], ) -> PatKind<'tcx> { + let ty = self.typeck_results.node_type(pat.hir_id); + let prefix = self.lower_patterns(prefix); let slice = self.lower_opt_pattern(slice); let suffix = self.lower_patterns(suffix); @@ -465,18 +473,32 @@ impl<'tcx> PatCtxt<'tcx> { assert!(len >= prefix.len() as u64 + suffix.len() as u64); PatKind::Array { prefix, slice, suffix } } - _ => span_bug!(span, "bad slice pattern type {:?}", ty), + _ => span_bug!(pat.span, "bad slice pattern type {ty:?}"), } } fn lower_variant_or_leaf( &mut self, + pat: &'tcx hir::Pat<'tcx>, + expr: Option<&'tcx hir::PatExpr<'tcx>>, res: Res, - hir_id: hir::HirId, - span: Span, - ty: Ty<'tcx>, subpatterns: Vec>, ) -> PatKind<'tcx> { + // Check whether the caller should have provided an `expr` for this pattern kind. + assert_matches!( + (pat.kind, expr), + (hir::PatKind::Expr(..) | hir::PatKind::Range(..), Some(_)) + | (hir::PatKind::Struct(..) | hir::PatKind::TupleStruct(..), None) + ); + + // Use the id/span of the `hir::PatExpr`, if provided. + // Otherwise, use the id/span of the `hir::Pat`. + let (hir_id, span) = match expr { + Some(expr) => (expr.hir_id, expr.span), + None => (pat.hir_id, pat.span), + }; + let ty = self.typeck_results.node_type(hir_id); + let res = match res { Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => { let variant_id = self.tcx.parent(variant_ctor_id); @@ -563,7 +585,16 @@ impl<'tcx> PatCtxt<'tcx> { /// it to `const_to_pat`. Any other path (like enum variants without fields) /// is converted to the corresponding pattern via `lower_variant_or_leaf`. #[instrument(skip(self), level = "debug")] - fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) -> Box> { + fn lower_path( + &mut self, + pat: &'tcx hir::Pat<'tcx>, // Pattern that directly contains `expr` + expr: &'tcx hir::PatExpr<'tcx>, + qpath: &hir::QPath<'_>, + ) -> Box> { + assert_matches!(pat.kind, hir::PatKind::Expr(..) | hir::PatKind::Range(..)); + + let id = expr.hir_id; + let span = expr.span; let ty = self.typeck_results.node_type(id); let res = self.typeck_results.qpath_res(qpath, id); @@ -575,7 +606,7 @@ impl<'tcx> PatCtxt<'tcx> { _ => { // The path isn't the name of a constant, so it must actually // be a unit struct or unit variant (e.g. `Option::None`). - let kind = self.lower_variant_or_leaf(res, id, span, ty, vec![]); + let kind = self.lower_variant_or_leaf(pat, Some(expr), res, vec![]); return Box::new(Pat { span, ty, kind }); } }; @@ -615,24 +646,26 @@ impl<'tcx> PatCtxt<'tcx> { /// - Literals, possibly negated (e.g. `-128u8`, `"hello"`) fn lower_pat_expr( &mut self, + pat: &'tcx hir::Pat<'tcx>, // Pattern that directly contains `expr` expr: &'tcx hir::PatExpr<'tcx>, - pat_ty: Option>, ) -> PatKind<'tcx> { + assert_matches!(pat.kind, hir::PatKind::Expr(..) | hir::PatKind::Range(..)); match &expr.kind { - hir::PatExprKind::Path(qpath) => self.lower_path(qpath, expr.hir_id, expr.span).kind, + hir::PatExprKind::Path(qpath) => self.lower_path(pat, expr, qpath).kind, hir::PatExprKind::Lit { lit, negated } => { // We handle byte string literal patterns by using the pattern's type instead of the // literal's type in `const_to_pat`: if the literal `b"..."` matches on a slice reference, // the pattern's type will be `&[u8]` whereas the literal's type is `&[u8; 3]`; using the // pattern's type means we'll properly translate it to a slice reference pattern. This works // because slices and arrays have the same valtree representation. - let ct_ty = match pat_ty { - Some(pat_ty) => pat_ty, - None => self.typeck_results.node_type(expr.hir_id), - }; - let lit_input = LitToConstInput { lit: lit.node, ty: ct_ty, neg: *negated }; + // + // Under `feature(deref_patterns)`, this adjustment can also convert string literal + // patterns to `str`, and byte-string literal patterns to `[u8; N]` or `[u8]`. + + let pat_ty = self.typeck_results.node_type(pat.hir_id); + let lit_input = LitToConstInput { lit: lit.node, ty: pat_ty, neg: *negated }; let constant = self.tcx.at(expr.span).lit_to_const(lit_input); - self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind + self.const_to_pat(constant, pat_ty, expr.hir_id, lit.span).kind } } } From 9302232addcd9443e52452845d24eaf709427f82 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sun, 4 Jan 2026 05:03:43 +0000 Subject: [PATCH 1570/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to f57b9e6f565a1847e83a63f3e90faa3870536c1f. --- 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 f22aff761e8d..c44422d758c5 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -e8f3cfc0de70bf82583591f6656e1fba3140253e +f57b9e6f565a1847e83a63f3e90faa3870536c1f From 7c02e3c6ebfaa9d70d7a358dfe3209d110b2c618 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sun, 4 Jan 2026 17:44:15 +0900 Subject: [PATCH 1571/3801] Fix ambig-unambig-ty-and-consts link --- compiler/rustc_hir/src/hir.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index da3e79efd6df..817eddefe5e8 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -440,7 +440,7 @@ impl<'hir> ConstItemRhs<'hir> { /// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`). /// /// For an explanation of the `Unambig` generic parameter see the dev-guide: -/// +/// #[derive(Clone, Copy, Debug, HashStable_Generic)] #[repr(C)] pub struct ConstArg<'hir, Unambig = ()> { @@ -3374,7 +3374,7 @@ pub enum AmbigArg {} /// Represents a type in the `HIR`. /// /// For an explanation of the `Unambig` generic parameter see the dev-guide: -/// +/// #[derive(Debug, Clone, Copy, HashStable_Generic)] #[repr(C)] pub struct Ty<'hir, Unambig = ()> { @@ -3713,7 +3713,7 @@ pub enum InferDelegationKind { /// The various kinds of types recognized by the compiler. /// /// For an explanation of the `Unambig` generic parameter see the dev-guide: -/// +/// // SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind` are layout compatible #[repr(u8, C)] #[derive(Debug, Clone, Copy, HashStable_Generic)] From f4112ee9b655027dc9526c529f074e6f15fe044a Mon Sep 17 00:00:00 2001 From: Mattias Petersson Date: Sun, 28 Dec 2025 16:56:17 +0100 Subject: [PATCH 1572/3801] Fix commit according to PR review Changed so cargo specifies the binary collector, removing the need to link to its local binary. Clarified that the SHAs should be from the rustc-repo, but the command should be ran in the rustc-perf repo. --- src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md index 19935d3d262f..7c7639a1ac3d 100644 --- a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md +++ b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md @@ -34,15 +34,16 @@ To start, in the `rustc-perf` repo, build the collector, which runs the Rust com ``` cargo build --release -p collector ``` -After this the collector can be located in `.\target\release\collector`, can be run locally with `bench_local` and expects the following arguments: +The collector can then be run using cargo, specifying the collector binary. It expects the following arguments: - ``: Profiler selection for how performance should be measured. For this example we will use Cachegrind. - ``: The Rust compiler revision to benchmark, specified as a commit SHA from `rust-lang/rust`. -Optional arguments allow running profiles and scenarios as described above. `--include` in `x perf` is instead `--exact-match`. More information regarding the mandatory and +Optional arguments allow running profiles and scenarios as described above. More information regarding the mandatory and optional arguments can be found in the [rustc-perf-readme-profilers]. -Then, for the case of generating a profile diff for the crate `serve_derive-1.0.136`, for two commits `` and `` in the `rust-lang/rust` repository, run the following +Then, for the case of generating a profile diff for the crate `serve_derive-1.0.136`, for two commits `` and `` from the `rust-lang/rust` repository, +run the following in the `rustc-perf` repo: ``` -./target/release/collector profile_local cachegrind + --rustc2 + --exact-match serde_derive-1.0.136 --profiles Check --scenarios IncrUnchanged +cargo run --release --bin collector profile_local cachegrind + --rustc2 + --exact-match serde_derive-1.0.136 --profiles Check --scenarios IncrUnchanged ``` From 65639fe0dcca82defbcc3dac91a33c94ccddf303 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 4 Jan 2026 04:15:05 -0500 Subject: [PATCH 1573/3801] ci: Move the dependency installs and wall time benchmarks to scripts Make it easier to run the same steps outside of GitHub Actions. --- .../.github/workflows/main.yaml | 21 +++---------------- library/compiler-builtins/ci/bench-runtime.sh | 9 ++++++++ .../ci/install-bench-deps.sh | 11 ++++++++++ 3 files changed, 23 insertions(+), 18 deletions(-) create mode 100755 library/compiler-builtins/ci/bench-runtime.sh create mode 100755 library/compiler-builtins/ci/install-bench-deps.sh diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 38995cf0f0ff..699a9c417dde 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -203,7 +203,7 @@ jobs: # Unlike rustfmt, stable clippy does not work on code with nightly features. - name: Install nightly `clippy` run: | - rustup set profile minimal + rustup update nightly --no-self-update rustup default nightly rustup component add clippy - uses: Swatinem/rust-cache@v2 @@ -247,16 +247,7 @@ jobs: - uses: taiki-e/install-action@cargo-binstall - name: Set up dependencies - run: | - sudo apt-get update - sudo apt-get install -y valgrind gdb libc6-dbg # Needed for gungraun - rustup update "$BENCHMARK_RUSTC" --no-self-update - rustup default "$BENCHMARK_RUSTC" - # Install the version of gungraun-runner that is specified in Cargo.toml - gungraun_version="$(cargo metadata --format-version=1 --features icount | - jq -r '.packages[] | select(.name == "gungraun").version')" - cargo binstall -y gungraun-runner --version "$gungraun_version" - sudo apt-get install valgrind + run: ./ci/install-bench-deps.sh - uses: Swatinem/rust-cache@v2 with: key: ${{ matrix.target }} @@ -276,13 +267,7 @@ jobs: path: ${{ env.BASELINE_NAME }}.tar.xz - name: Run wall time benchmarks - run: | - # Always use the same seed for benchmarks. Ideally we should switch to a - # non-random generator. - export LIBM_SEED=benchesbenchesbenchesbencheswoo! - cargo bench --package libm-test \ - --no-default-features \ - --features short-benchmarks,build-musl,libm/force-soft-floats + run: ./ci/bench-runtime.sh - name: Print test logs if available if: always() diff --git a/library/compiler-builtins/ci/bench-runtime.sh b/library/compiler-builtins/ci/bench-runtime.sh new file mode 100755 index 000000000000..d272cf33463e --- /dev/null +++ b/library/compiler-builtins/ci/bench-runtime.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# Run wall time benchmarks as we do on CI. + +# Always use the same seed for benchmarks. Ideally we should switch to a +# non-random generator. +export LIBM_SEED=benchesbenchesbenchesbencheswoo! +cargo bench --package libm-test \ + --no-default-features \ + --features short-benchmarks,build-musl,libm/force-soft-floats diff --git a/library/compiler-builtins/ci/install-bench-deps.sh b/library/compiler-builtins/ci/install-bench-deps.sh new file mode 100755 index 000000000000..61f4723c0358 --- /dev/null +++ b/library/compiler-builtins/ci/install-bench-deps.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# Install needed dependencies for gungraun. + +sudo apt-get update +sudo apt-get install -y valgrind gdb libc6-dbg # Needed for gungraun +rustup update "$BENCHMARK_RUSTC" --no-self-update +rustup default "$BENCHMARK_RUSTC" +# Install the version of gungraun-runner that is specified in Cargo.toml +gungraun_version="$(cargo metadata --format-version=1 --features icount | + jq -r '.packages[] | select(.name == "gungraun").version')" +cargo binstall -y gungraun-runner --version "$gungraun_version" From 0557c759a9b7ef0f9fd8dbfef2469439289a311f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 4 Jan 2026 11:26:05 +0100 Subject: [PATCH 1574/3801] add check_only feature for faster check builds --- src/tools/miri/Cargo.lock | 17 +++++++++++------ src/tools/miri/Cargo.toml | 3 ++- src/tools/miri/ci/ci.sh | 17 +++++++++-------- src/tools/miri/etc/rust_analyzer_helix.toml | 1 - src/tools/miri/etc/rust_analyzer_vscode.json | 1 - src/tools/miri/etc/rust_analyzer_zed.json | 1 - src/tools/miri/genmc-sys/Cargo.toml | 3 +++ src/tools/miri/genmc-sys/build.rs | 5 +++++ src/tools/miri/miri-script/src/commands.rs | 6 ++++-- 9 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 220fad2a1c76..b314aaafbdf0 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -123,22 +123,21 @@ dependencies = [ [[package]] name = "capstone" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015ef5d5ca1743e3f94af9509ba6bd2886523cfee46e48d15c2ef5216fd4ac9a" +checksum = "f442ae0f2f3f1b923334b4a5386c95c69c1cfa072bafa23d6fae6d9682eb1dd4" dependencies = [ "capstone-sys", - "libc", + "static_assertions", ] [[package]] name = "capstone-sys" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2267cb8d16a1e4197863ec4284ffd1aec26fe7e57c58af46b02590a0235809a0" +checksum = "a4e8087cab6731295f5a2a2bd82989ba4f41d3a428aab2e7c98d8f4db38aac05" dependencies = [ "cc", - "libc", ] [[package]] @@ -1404,6 +1403,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.11.1" diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 064706d7ed04..e7c90e45eba5 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -39,7 +39,7 @@ 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 } ipc-channel = { version = "0.20.0", optional = true } -capstone = { version = "0.13", optional = true } +capstone = { version = "0.14", optional = true } [target.'cfg(all(target_os = "linux", target_pointer_width = "64", target_endian = "little"))'.dependencies] genmc-sys = { path = "./genmc-sys/", version = "0.1.0", optional = true } @@ -68,6 +68,7 @@ expensive-consistency-checks = ["stack-cache"] tracing = ["serde_json"] native-lib = ["dep:libffi", "dep:libloading", "dep:capstone", "dep:ipc-channel", "dep:nix", "dep:serde"] jemalloc = [] +check_only = ["libffi?/check_only", "capstone?/check_only", "genmc-sys?/check_only"] [lints.rust.unexpected_cfgs] level = "warn" diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index 82007a8c1c1a..c8e359cf2385 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -30,14 +30,15 @@ export CARGO_INCREMENTAL=0 export CARGO_EXTRA_FLAGS="--locked" # Determine configuration for installed build (used by test-cargo-miri and `./miri bench`). +# We use the default set of features for this. echo "Installing release version of Miri" time ./miri install # Prepare debug build for direct `./miri` invocations. -# We enable all features to make sure the Stacked Borrows consistency check runs. +# Here we enable some more features and checks. echo "Building debug version of Miri" -export CARGO_EXTRA_FLAGS="$CARGO_EXTRA_FLAGS --all-features" -time ./miri build # the build that all the `./miri test` below will use +export FEATURES="--features=expensive-consistency-checks,genmc" +time ./miri build $FEATURES # the build that all the `./miri test` below will use endgroup @@ -63,7 +64,7 @@ function run_tests { if [ -n "${GC_STRESS-}" ]; then time MIRIFLAGS="${MIRIFLAGS-} -Zmiri-provenance-gc=1" ./miri test $TARGET_FLAG else - time ./miri test $TARGET_FLAG + time ./miri test $FEATURES $TARGET_FLAG fi ## advanced tests @@ -74,20 +75,20 @@ function run_tests { # them. Also error locations change so we don't run the failing tests. # We explicitly enable debug-assertions here, they are disabled by -O but we have tests # which exist to check that we panic on debug assertion failures. - time MIRIFLAGS="${MIRIFLAGS-} -O -Zmir-opt-level=4 -Cdebug-assertions=yes" MIRI_SKIP_UI_CHECKS=1 ./miri test $TARGET_FLAG tests/{pass,panic} + time MIRIFLAGS="${MIRIFLAGS-} -O -Zmir-opt-level=4 -Cdebug-assertions=yes" MIRI_SKIP_UI_CHECKS=1 ./miri test $FEATURES $TARGET_FLAG tests/{pass,panic} fi if [ -n "${MANY_SEEDS-}" ]; then # Run many-seeds tests. (Also tests `./miri run`.) time for FILE in tests/many-seeds/*.rs; do - ./miri run "-Zmiri-many-seeds=0..$MANY_SEEDS" $TARGET_FLAG "$FILE" + ./miri run $FEATURES "-Zmiri-many-seeds=0..$MANY_SEEDS" $TARGET_FLAG "$FILE" done + # Smoke-test `./miri run --dep`. + ./miri run $FEATURES $TARGET_FLAG --dep tests/pass-dep/getrandom.rs fi if [ -n "${TEST_BENCH-}" ]; then # Check that the benchmarks build and run, but only once. time HYPERFINE="hyperfine -w0 -r1 --show-output" ./miri bench $TARGET_FLAG --no-install fi - # Smoke-test `./miri run --dep`. - ./miri run $TARGET_FLAG --dep tests/pass-dep/getrandom.rs ## test-cargo-miri # On Windows, there is always "python", not "python3" or "python2". diff --git a/src/tools/miri/etc/rust_analyzer_helix.toml b/src/tools/miri/etc/rust_analyzer_helix.toml index dd222c50431a..1015b4baa6b0 100644 --- a/src/tools/miri/etc/rust_analyzer_helix.toml +++ b/src/tools/miri/etc/rust_analyzer_helix.toml @@ -27,7 +27,6 @@ invocationStrategy = "once" overrideCommand = [ "./miri", "check", - "--no-default-features", "-Zunstable-options", "--compile-time-deps", "--message-format=json", diff --git a/src/tools/miri/etc/rust_analyzer_vscode.json b/src/tools/miri/etc/rust_analyzer_vscode.json index 97ba212f8ef9..e82c648f59ab 100644 --- a/src/tools/miri/etc/rust_analyzer_vscode.json +++ b/src/tools/miri/etc/rust_analyzer_vscode.json @@ -21,7 +21,6 @@ "rust-analyzer.cargo.buildScripts.overrideCommand": [ "./miri", "check", - "--no-default-features", "-Zunstable-options", "--compile-time-deps", "--message-format=json", diff --git a/src/tools/miri/etc/rust_analyzer_zed.json b/src/tools/miri/etc/rust_analyzer_zed.json index 7f60a931c46f..e5ff400e989e 100644 --- a/src/tools/miri/etc/rust_analyzer_zed.json +++ b/src/tools/miri/etc/rust_analyzer_zed.json @@ -30,7 +30,6 @@ "overrideCommand": [ "./miri", "check", - "--no-default-features", "-Zunstable-options", "--compile-time-deps", "--message-format=json" diff --git a/src/tools/miri/genmc-sys/Cargo.toml b/src/tools/miri/genmc-sys/Cargo.toml index 6443ecd969df..37fcc58070a3 100644 --- a/src/tools/miri/genmc-sys/Cargo.toml +++ b/src/tools/miri/genmc-sys/Cargo.toml @@ -13,3 +13,6 @@ cc = "1.2.16" cmake = "0.1.54" git2 = { version = "0.20.2", default-features = false, features = ["https"] } cxx-build = { version = "1.0.173", features = ["parallel"] } + +[features] +check_only = [] diff --git a/src/tools/miri/genmc-sys/build.rs b/src/tools/miri/genmc-sys/build.rs index a22e3341d67a..4fc3ce94fb8b 100644 --- a/src/tools/miri/genmc-sys/build.rs +++ b/src/tools/miri/genmc-sys/build.rs @@ -202,6 +202,11 @@ fn compile_cpp_dependencies(genmc_path: &Path, always_configure: bool) { } fn main() { + // For check-only builds, we don't need to do anything. + if cfg!(feature = "check_only") { + return; + } + // Select which path to use for the GenMC repo: let (genmc_path, always_configure) = if let Some(genmc_src_path) = option_env!("GENMC_SRC_PATH") { diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs index 5a8bf76befd6..86f6253d4558 100644 --- a/src/tools/miri/miri-script/src/commands.rs +++ b/src/tools/miri/miri-script/src/commands.rs @@ -391,7 +391,8 @@ impl Command { Ok(()) } - fn check(features: Vec, flags: Vec) -> Result<()> { + fn check(mut features: Vec, flags: Vec) -> Result<()> { + features.push("check_only".into()); let e = MiriEnv::new()?; e.check(".", &features, &flags)?; e.check("cargo-miri", &[], &flags)?; @@ -405,7 +406,8 @@ impl Command { Ok(()) } - fn clippy(features: Vec, flags: Vec) -> Result<()> { + fn clippy(mut features: Vec, flags: Vec) -> Result<()> { + features.push("check_only".into()); let e = MiriEnv::new()?; e.clippy(".", &features, &flags)?; e.clippy("cargo-miri", &[], &flags)?; From d4b9ea2e865f8de6fe994f1e9a7c0fa80b83dcbf Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 4 Jan 2026 11:44:42 +0100 Subject: [PATCH 1575/3801] internal: Clean up proc-macro-srv callback trait --- .../crates/base-db/src/editioned_file_id.rs | 3 ++ .../rust-analyzer/crates/hir-expand/src/db.rs | 14 +++++++-- .../crates/hir-expand/src/lib.rs | 24 ++++----------- .../crates/load-cargo/src/lib.rs | 29 +++++++++---------- .../crates/proc-macro-srv-cli/Cargo.toml | 1 + .../proc-macro-srv-cli/src/main_loop.rs | 22 +++++++++----- .../crates/proc-macro-srv/src/lib.rs | 7 +++-- .../src/server_impl/rust_analyzer_span.rs | 19 ++---------- 8 files changed, 58 insertions(+), 61 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/editioned_file_id.rs b/src/tools/rust-analyzer/crates/base-db/src/editioned_file_id.rs index e2791ffe6f0a..13fb05d56547 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/editioned_file_id.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/editioned_file_id.rs @@ -26,6 +26,9 @@ const _: () = { krate: Crate, } + // FIXME: This poses an invalidation problem, if one constructs an `EditionedFileId` with a + // different crate then whatever the input of a memo used, it will invalidate the memo causing + // it to recompute even if the crate is not really used. /// We like to include the origin crate in an `EditionedFileId` (for use in the item tree), /// but this poses us a problem. /// diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 40d44cd1dba2..51767f87ffb9 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs @@ -9,8 +9,8 @@ use triomphe::Arc; use crate::{ AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo, - EagerExpander, EditionedFileId, ExpandError, ExpandResult, ExpandTo, HirFileId, MacroCallId, - MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, + EagerExpander, EditionedFileId, ExpandError, ExpandResult, ExpandTo, FileRange, HirFileId, + MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, attrs::Meta, builtin::pseudo_derive_attr_expansion, cfg_process::attr_macro_input_to_token_tree, @@ -61,6 +61,9 @@ pub trait ExpandDatabase: RootQueryDb { #[salsa::lru(1024)] fn ast_id_map(&self, file_id: HirFileId) -> Arc; + #[salsa::transparent] + fn resolve_span(&self, span: Span) -> FileRange; + #[salsa::transparent] fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode; @@ -158,6 +161,13 @@ fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId, edition: Edition) -> } } +fn resolve_span(db: &dyn ExpandDatabase, Span { range, anchor, ctx: _ }: Span) -> FileRange { + let file_id = EditionedFileId::from_span_guess_origin(db, anchor.file_id); + let anchor_offset = + db.ast_id_map(file_id.into()).get_erased(anchor.ast_id).text_range().start(); + FileRange { file_id, range: range + anchor_offset } +} + /// This expands the given macro call, but with different arguments. This is /// used for completion, where we want to see what 'would happen' if we insert a /// token. The `token_to_map` mapped down into the expansion, with the mapped diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index 7b6a6135b350..05541e782efd 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -901,11 +901,8 @@ impl ExpansionInfo { let span = self.exp_map.span_at(token.start()); match &self.arg_map { SpanMap::RealSpanMap(_) => { - let file_id = - EditionedFileId::from_span_guess_origin(db, span.anchor.file_id).into(); - let anchor_offset = - db.ast_id_map(file_id).get_erased(span.anchor.ast_id).text_range().start(); - InFile { file_id, value: smallvec::smallvec![span.range + anchor_offset] } + let range = db.resolve_span(span); + InFile { file_id: range.file_id.into(), value: smallvec::smallvec![range.range] } } SpanMap::ExpansionSpanMap(arg_map) => { let Some(arg_node) = &self.arg.value else { @@ -947,7 +944,7 @@ pub fn map_node_range_up_rooted( range: TextRange, ) -> Option { let mut spans = exp_map.spans_for_range(range).filter(|span| span.ctx.is_root()); - let Span { range, anchor, ctx: _ } = spans.next()?; + let Span { range, anchor, ctx } = spans.next()?; let mut start = range.start(); let mut end = range.end(); @@ -958,10 +955,7 @@ pub fn map_node_range_up_rooted( start = start.min(span.range.start()); end = end.max(span.range.end()); } - let file_id = EditionedFileId::from_span_guess_origin(db, anchor.file_id); - let anchor_offset = - db.ast_id_map(file_id.into()).get_erased(anchor.ast_id).text_range().start(); - Some(FileRange { file_id, range: TextRange::new(start, end) + anchor_offset }) + Some(db.resolve_span(Span { range: TextRange::new(start, end), anchor, ctx })) } /// Maps up the text range out of the expansion hierarchy back into the original file its from. @@ -984,10 +978,7 @@ pub fn map_node_range_up( start = start.min(span.range.start()); end = end.max(span.range.end()); } - let file_id = EditionedFileId::from_span_guess_origin(db, anchor.file_id); - let anchor_offset = - db.ast_id_map(file_id.into()).get_erased(anchor.ast_id).text_range().start(); - Some((FileRange { file_id, range: TextRange::new(start, end) + anchor_offset }, ctx)) + Some((db.resolve_span(Span { range: TextRange::new(start, end), anchor, ctx }), ctx)) } /// Looks up the span at the given offset. @@ -997,10 +988,7 @@ pub fn span_for_offset( offset: TextSize, ) -> (FileRange, SyntaxContext) { let span = exp_map.span_at(offset); - let file_id = EditionedFileId::from_span_guess_origin(db, span.anchor.file_id); - let anchor_offset = - db.ast_id_map(file_id.into()).get_erased(span.anchor.ast_id).text_range().start(); - (FileRange { file_id, range: span.range + anchor_offset }, span.ctx) + (db.resolve_span(span), span.ctx) } /// In Rust, macros expand token trees to token trees. When we want to turn a diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index c302e266febd..e8d98b1ce661 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -19,7 +19,7 @@ use hir_expand::{ }, }; use ide_db::{ - ChangeWithProcMacros, EditionedFileId, FxHashMap, RootDatabase, + ChangeWithProcMacros, FxHashMap, RootDatabase, base_db::{CrateGraphBuilder, Env, ProcMacroLoadingError, SourceRoot, SourceRootId}, prime_caches, }; @@ -32,7 +32,8 @@ use proc_macro_api::{ }, }; use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace}; -use span::Span; +use span::{Span, SpanAnchor, SyntaxContext}; +use tt::{TextRange, TextSize}; use vfs::{ AbsPath, AbsPathBuf, FileId, VfsPath, file_set::FileSetConfig, @@ -553,20 +554,18 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::LocalFilePathResult { name }) } SubRequest::SourceText { file_id, ast_id, start, end } => { - let raw_file_id = FileId::from_raw(file_id); - let editioned_file_id = span::EditionedFileId::from_raw(file_id); let ast_id = span::ErasedFileAstId::from_raw(ast_id); - let hir_file_id = EditionedFileId::from_span_guess_origin(db, editioned_file_id); - let anchor_offset = db - .ast_id_map(hir_expand::HirFileId::FileId(hir_file_id)) - .get_erased(ast_id) - .text_range() - .start(); - let anchor_offset = u32::from(anchor_offset); - let abs_start = start + anchor_offset; - let abs_end = end + anchor_offset; - let source = db.file_text(raw_file_id).text(db); - let text = source.get(abs_start as usize..abs_end as usize).map(ToOwned::to_owned); + let editioned_file_id = span::EditionedFileId::from_raw(file_id); + let span = Span { + range: TextRange::new(TextSize::from(start), TextSize::from(end)), + anchor: SpanAnchor { file_id: editioned_file_id, ast_id }, + ctx: SyntaxContext::root(editioned_file_id.edition()), + }; + let range = db.resolve_span(span); + let source = db.file_text(range.file_id.file_id(db)).text(db); + let text = source + .get(usize::from(range.range.start())..usize::from(range.range.end())) + .map(ToOwned::to_owned); Ok(SubResponse::SourceTextResult { text }) } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml index 2c6e5a16ee06..6b2db0b269d5 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml @@ -18,6 +18,7 @@ clap = {version = "4.5.42", default-features = false, features = ["std"]} [features] default = [] +# default = ["sysroot-abi"] sysroot-abi = ["proc-macro-srv/sysroot-abi", "proc-macro-api/sysroot-abi"] in-rust-tree = ["proc-macro-srv/in-rust-tree", "sysroot-abi"] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 4891e073142d..b2f4b96bd255 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -185,8 +185,8 @@ impl<'a, C: Codec> ProcMacroClientHandle<'a, C> { } impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { - fn file(&mut self, file_id: u32) -> String { - match self.roundtrip(bidirectional::SubRequest::FilePath { file_id }) { + fn file(&mut self, file_id: proc_macro_srv::span::FileId) -> String { + match self.roundtrip(bidirectional::SubRequest::FilePath { file_id: file_id.index() }) { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::FilePathResult { name }, )) => name, @@ -194,9 +194,16 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl } } - fn source_text(&mut self, file_id: u32, ast_id: u32, start: u32, end: u32) -> Option { - match self.roundtrip(bidirectional::SubRequest::SourceText { file_id, ast_id, start, end }) - { + fn source_text( + &mut self, + proc_macro_srv::span::Span { range, anchor, ctx: _ }: proc_macro_srv::span::Span, + ) -> Option { + match self.roundtrip(bidirectional::SubRequest::SourceText { + file_id: anchor.file_id.as_u32(), + ast_id: anchor.ast_id.into_raw(), + start: range.start().into(), + end: range.end().into(), + }) { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::SourceTextResult { text }, )) => text, @@ -204,8 +211,9 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl } } - fn local_file(&mut self, file_id: u32) -> Option { - match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id }) { + fn local_file(&mut self, file_id: proc_macro_srv::span::FileId) -> Option { + match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id: file_id.index() }) + { Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::LocalFilePathResult { name }, )) => name, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index d63aea947c1d..f2d1dfbba4cc 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -53,6 +53,7 @@ use temp_dir::TempDir; pub use crate::server_impl::token_id::SpanId; pub use proc_macro::Delimiter; +pub use span; pub use crate::bridge::*; pub use crate::server_impl::literal_from_str; @@ -94,9 +95,9 @@ impl<'env> ProcMacroSrv<'env> { pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); pub trait ProcMacroClientInterface { - fn file(&mut self, file_id: u32) -> String; - fn source_text(&mut self, file_id: u32, ast_id: u32, start: u32, end: u32) -> Option; - fn local_file(&mut self, file_id: u32) -> Option; + fn file(&mut self, file_id: span::FileId) -> String; + fn source_text(&mut self, span: Span) -> Option; + fn local_file(&mut self, file_id: span::FileId) -> Option; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 2ce3b717cb0d..32725afc5527 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -128,13 +128,10 @@ impl server::Span for RaSpanServer<'_> { format!("{:?}", span) } fn file(&mut self, span: Self::Span) -> String { - self.callback - .as_mut() - .map(|cb| cb.file(span.anchor.file_id.file_id().index())) - .unwrap_or_default() + self.callback.as_mut().map(|cb| cb.file(span.anchor.file_id.file_id())).unwrap_or_default() } fn local_file(&mut self, span: Self::Span) -> Option { - self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id().index())) + self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id())) } fn save_span(&mut self, _span: Self::Span) -> usize { // FIXME, quote is incompatible with third-party tools @@ -153,17 +150,7 @@ impl server::Span for RaSpanServer<'_> { /// See PR: /// https://github.com/rust-lang/rust/pull/55780 fn source_text(&mut self, span: Self::Span) -> Option { - let file_id = span.anchor.file_id; - let ast_id = span.anchor.ast_id; - let start: u32 = span.range.start().into(); - let end: u32 = span.range.end().into(); - - self.callback.as_mut()?.source_text( - file_id.file_id().index(), - ast_id.into_raw(), - start, - end, - ) + self.callback.as_mut()?.source_text(span) } fn parent(&mut self, _span: Self::Span) -> Option { From 50b78f1bb4c8bd3a0c2d5cb5b4323be16121354d Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 4 Jan 2026 12:08:50 +0100 Subject: [PATCH 1576/3801] Add a README.md to proc-macro-srv-cli --- .../crates/proc-macro-srv-cli/README.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/tools/rust-analyzer/crates/proc-macro-srv-cli/README.md diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/README.md b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/README.md new file mode 100644 index 000000000000..02a67ac3ecc1 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/README.md @@ -0,0 +1,65 @@ +# proc-macro-srv-cli + +A standalone binary for the `proc-macro-srv` crate that provides procedural macro expansion for rust-analyzer. + +## Overview + +rust-analyzer uses a RPC (via stdio) client-server architecture for procedural macro expansion. This is necessary because: + +1. Proc macros are dynamic libraries that can segfault, bringing down the entire process, so running them out of process allows rust-analyzer to recover from fatal errors. +2. Proc macro dylibs are compiled against a specific rustc version and require matching internal APIs to load and execute, as such having this binary shipped as a rustup component allows us to always match the rustc version irrespective of the rust-analyzer version used. + +## The `sysroot-abi` Feature + +**The `sysroot-abi` feature is required for the binary to actually function.** Without it, the binary will return an error: + +``` +proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function +``` + +This feature is necessary because the proc-macro server needs access to unstable rustc internals (`proc_macro_internals`, `proc_macro_diagnostic`, `proc_macro_span`) which are only available on nightly or with `RUSTC_BOOTSTRAP=1`. +rust-analyzer is a stable toolchain project though, so the feature flag is used to have it remain compilable on stable by default. + +### Building + +```bash +# Using nightly toolchain +cargo build -p proc-macro-srv-cli --features sysroot-abi + +# Or with RUSTC_BOOTSTRAP on stable +RUSTC_BOOTSTRAP=1 cargo build -p proc-macro-srv-cli --features sysroot-abi +``` + +### Installing the proc-macro server + +For local testing purposes, you can install the proc-macro server using the xtask command: + +```bash +# Recommended: use the xtask command +cargo xtask install --proc-macro-server +``` + +## Testing + +```bash +cargo test --features sysroot-abi -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api +``` + +The tests use a test proc macro dylib built by the `proc-macro-test` crate, which compiles a small proc macro implementation during build time. + +**Note**: Tests only compile on nightly toolchains (or with `RUSTC_BOOTSTRAP=1`). + +## Usage + +The binary requires the `RUST_ANALYZER_INTERNALS_DO_NOT_USE` environment variable to be set. This is intentional—the binary is an implementation detail of rust-analyzer and its API is still unstable: + +```bash +RUST_ANALYZER_INTERNALS_DO_NOT_USE=1 rust-analyzer-proc-macro-srv --version +``` + +## Related Crates + +- `proc-macro-srv`: The core server library that handles loading dylibs and expanding macros, but not the RPC protocol. +- `proc-macro-api`: The client library used by rust-analyzer to communicate with this server as well as the protocol definitions. +- `proc-macro-test`: Test harness with sample proc macros for testing +- `proc-macro-srv-cli`: The actual server binary that handles the RPC protocol. From ff2acf0eca6e45fa5828f4d0e5e5891b4c789517 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 4 Jan 2026 12:44:38 +0100 Subject: [PATCH 1577/3801] update lockfile --- Cargo.lock | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d3637d1f4b3e..816bb1a37859 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,22 +445,21 @@ dependencies = [ [[package]] name = "capstone" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015ef5d5ca1743e3f94af9509ba6bd2886523cfee46e48d15c2ef5216fd4ac9a" +checksum = "f442ae0f2f3f1b923334b4a5386c95c69c1cfa072bafa23d6fae6d9682eb1dd4" dependencies = [ "capstone-sys", - "libc", + "static_assertions", ] [[package]] name = "capstone-sys" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2267cb8d16a1e4197863ec4284ffd1aec26fe7e57c58af46b02590a0235809a0" +checksum = "a4e8087cab6731295f5a2a2bd82989ba4f41d3a428aab2e7c98d8f4db38aac05" dependencies = [ "cc", - "libc", ] [[package]] @@ -2232,9 +2231,9 @@ dependencies = [ [[package]] name = "libffi" -version = "5.0.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0444124f3ffd67e1b0b0c661a7f81a278a135eb54aaad4078e79fbc8be50c8a5" +checksum = "0498fe5655f857803e156523e644dcdcdc3b3c7edda42ea2afdae2e09b2db87b" dependencies = [ "libc", "libffi-sys", @@ -2242,9 +2241,9 @@ dependencies = [ [[package]] name = "libffi-sys" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d722da8817ea580d0669da6babe2262d7b86a1af1103da24102b8bb9c101ce7" +checksum = "71d4f1d4ce15091955144350b75db16a96d4a63728500122706fb4d29a26afbb" dependencies = [ "cc", ] From f091a8acad5c52378be2f1b6f29cc2d21ff7bf5f Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 4 Jan 2026 20:54:19 +0800 Subject: [PATCH 1578/3801] Fix complete semicolon in array expression Example --- ```rust fn foo() {} fn bar() { let _ = [fo$0]; } ``` **Before this PR** ```rust fn foo() {} fn bar() { let _ = [foo();$0]; } ``` **After this PR** ```rust fn foo() {} fn bar() { let _ = [foo()$0]; } ``` --- .../crates/ide-completion/src/context.rs | 5 ++++- .../ide-completion/src/render/function.rs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index d116f665adbd..7f3e69c8ab30 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -821,7 +821,10 @@ impl<'db> CompletionContext<'db> { CompleteSemicolon::DoNotComplete } else if let Some(term_node) = sema.token_ancestors_with_macros(token.clone()).find(|node| { - matches!(node.kind(), BLOCK_EXPR | MATCH_ARM | CLOSURE_EXPR | ARG_LIST | PAREN_EXPR) + matches!( + node.kind(), + BLOCK_EXPR | MATCH_ARM | CLOSURE_EXPR | ARG_LIST | PAREN_EXPR | ARRAY_EXPR + ) }) { let next_token = iter::successors(token.next_token(), |it| it.next_token()) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs index 4713b1f1afa7..475e00dfcf29 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs @@ -905,6 +905,25 @@ fn baz(_: impl FnOnce()) {} fn bar() { baz(foo()$0); } +"#, + ); + } + + #[test] + fn no_semicolon_in_array() { + check_edit( + r#"foo"#, + r#" +fn foo() {} +fn bar() { + let _ = [fo$0]; +} +"#, + r#" +fn foo() {} +fn bar() { + let _ = [foo()$0]; +} "#, ); } From d7fa6e527fef7337dc25b1e824664dd5847ba4a2 Mon Sep 17 00:00:00 2001 From: sgasho Date: Sun, 4 Jan 2026 22:56:17 +0900 Subject: [PATCH 1579/3801] enrich error info when tries to dlopen Enzyme --- compiler/rustc_codegen_llvm/messages.ftl | 3 ++- compiler/rustc_codegen_llvm/src/errors.rs | 5 ++++- compiler/rustc_codegen_llvm/src/lib.rs | 6 ++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index a637ae8184b4..018d240b2ae5 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -1,4 +1,5 @@ -codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend. Did you install it via rustup? +codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend. + .note = load error: {$err} codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index c73140e041b6..439664b8b9a2 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -34,7 +34,10 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_component_unavailable)] -pub(crate) struct AutoDiffComponentUnavailable; +#[note] +pub(crate) struct AutoDiffComponentUnavailable { + pub err: String, +} #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_without_lto)] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 095274744993..801d23342973 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -249,8 +249,10 @@ impl CodegenBackend for LlvmCodegenBackend { use crate::back::lto::enable_autodiff_settings; if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) { - if let Err(_) = llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) { - sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable); + if let Err(err) = llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) { + sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable { + err: format!("{err:?}"), + }); } enable_autodiff_settings(&sess.opts.unstable_opts.autodiff); } From fa584faca5387010e37bc8172529be3b3776e0cc Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Sun, 4 Jan 2026 06:56:48 -0800 Subject: [PATCH 1580/3801] Update test and verify that tgt_(un)register_lib have the right type --- compiler/rustc_codegen_llvm/src/base.rs | 9 +++- .../src/builder/gpu_offload.rs | 5 ++- compiler/rustc_session/src/config.rs | 2 + compiler/rustc_session/src/options.rs | 10 ++++- tests/codegen-llvm/gpu_offload/gpu_host.rs | 42 +++++++++---------- 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 388118f9b4f1..d00e70638b45 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -93,8 +93,13 @@ pub(crate) fn compile_codegen_unit( // They are necessary for correct offload execution. We do this here to simplify the // `offload` intrinsic, avoiding the need for tracking whether it's the first // intrinsic call or not. - let has_host_offload = - cx.sess().opts.unstable_opts.offload.iter().any(|o| matches!(o, Offload::Host(_))); + let has_host_offload = cx + .sess() + .opts + .unstable_opts + .offload + .iter() + .any(|o| matches!(o, Offload::Host(_) | Offload::Test)); if has_host_offload && !cx.sess().target.is_like_gpu { cx.offload_globals.replace(Some(OffloadGlobals::declare(&cx))); } diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index fba92f996aa6..b8eb4f038216 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -49,8 +49,9 @@ impl<'ll> OffloadGlobals<'ll> { let bin_desc = cx.type_named_struct("struct.__tgt_bin_desc"); cx.set_struct_body(bin_desc, &tgt_bin_desc_ty, false); - let register_lib = declare_offload_fn(&cx, "__tgt_register_lib", mapper_fn_ty); - let unregister_lib = declare_offload_fn(&cx, "__tgt_unregister_lib", mapper_fn_ty); + let reg_lib_decl = cx.type_func(&[cx.type_ptr()], cx.type_void()); + let register_lib = declare_offload_fn(&cx, "__tgt_register_lib", reg_lib_decl); + let unregister_lib = declare_offload_fn(&cx, "__tgt_unregister_lib", reg_lib_decl); let init_ty = cx.type_func(&[], cx.type_void()); let init_rtls = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index fe96dabf6330..8c492fcf8f15 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -196,6 +196,8 @@ pub enum Offload { Device, /// Second step in the offload pipeline, generates the host code to call kernels. Host(String), + /// Test is similar to Host, but allows testing without a device artifact. + Test, } /// The different settings that the `-Z autodiff` flag can have. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index f11ad12fb9dd..21fa3321a30a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -794,7 +794,8 @@ mod desc { pub(crate) const parse_list_with_polarity: &str = "a comma-separated list of strings, with elements beginning with + or -"; pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintTAFn`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `PrintModFinal`, `PrintPasses`, `NoPostopt`, `LooseTypes`, `Inline`, `NoTT`"; - pub(crate) const parse_offload: &str = "a comma separated list of settings: `Enable`"; + pub(crate) const parse_offload: &str = + "a comma separated list of settings: `Host=`, `Device`, `Test`"; pub(crate) const parse_comma_list: &str = "a comma-separated list of strings"; pub(crate) const parse_opt_comma_list: &str = parse_comma_list; pub(crate) const parse_number: &str = "a number"; @@ -1471,6 +1472,13 @@ pub mod parse { } Offload::Device } + "Test" => { + if let Some(_) = arg { + // Test does not accept a value + return false; + } + Offload::Test + } _ => { // FIXME(ZuseZ4): print an error saying which value is not recognized return false; diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index b4d17143720a..dcbd65b14427 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -1,15 +1,10 @@ -//@ compile-flags: -Zoffload=Enable -Zunstable-options -C opt-level=3 -Clto=fat +//@ compile-flags: -Zoffload=Test -Zunstable-options -C opt-level=3 -Clto=fat //@ no-prefer-dynamic -//@ needs-enzyme +//@ needs-offload // This test is verifying that we generate __tgt_target_data_*_mapper before and after a call to the // kernel_1. Better documentation to what each global or variable means is available in the gpu -// offlaod code, or the LLVM offload documentation. This code does not launch any GPU kernels yet, -// and will be rewritten once a proper offload frontend has landed. -// -// We currently only handle memory transfer for specific calls to functions named `kernel_{num}`, -// when inside of a function called main. This, too, is a temporary workaround for not having a -// frontend. +// offload code, or the LLVM offload documentation. #![feature(rustc_attrs)] #![feature(core_intrinsics)] @@ -22,6 +17,20 @@ fn main() { core::hint::black_box(&x); } +#[unsafe(no_mangle)] +#[inline(never)] +pub fn kernel_1(x: &mut [f32; 256]) { + core::intrinsics::offload(_kernel_1, [256, 1, 1], [32, 1, 1], (x,)) +} + +#[unsafe(no_mangle)] +#[inline(never)] +pub fn _kernel_1(x: &mut [f32; 256]) { + for i in 0..256 { + x[i] = 21.0; + } +} + // CHECK: %struct.ident_t = type { i32, i32, i32, i32, ptr } // CHECK: %struct.__tgt_offload_entry = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK: %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } @@ -36,8 +45,9 @@ fn main() { // CHECK: @.offloading.entry_name._kernel_1 = internal unnamed_addr constant [10 x i8] c"_kernel_1\00", section ".llvm.rodata.offloading", align 1 // CHECK: @.offloading.entry._kernel_1 = internal constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr @._kernel_1.region_id, ptr @.offloading.entry_name._kernel_1, i64 0, i64 0, ptr null }, section "llvm_offload_entries", align 8 -// CHECK: Function Attrs: nounwind // CHECK: declare i32 @__tgt_target_kernel(ptr, i64, i32, i32, ptr, ptr) +// CHECK: declare void @__tgt_register_lib(ptr) local_unnamed_addr +// CHECK: declare void @__tgt_unregister_lib(ptr) local_unnamed_addr // CHECK: define{{( dso_local)?}} void @main() // CHECK-NEXT: start: @@ -94,17 +104,3 @@ fn main() { // CHECK-NEXT: call void @__tgt_unregister_lib(ptr nonnull %EmptyDesc) // CHECK-NEXT: ret void // CHECK-NEXT: } - -#[unsafe(no_mangle)] -#[inline(never)] -pub fn kernel_1(x: &mut [f32; 256]) { - core::intrinsics::offload(_kernel_1, [256, 1, 1], [32, 1, 1], (x,)) -} - -#[unsafe(no_mangle)] -#[inline(never)] -pub fn _kernel_1(x: &mut [f32; 256]) { - for i in 0..256 { - x[i] = 21.0; - } -} From a767bf74624b000064b08993148a78f1e06090a4 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Thu, 1 Jan 2026 02:16:49 +0000 Subject: [PATCH 1581/3801] init impl --- clippy_lints/src/utils/author.rs | 1 + clippy_utils/src/consts.rs | 2 +- clippy_utils/src/hir_utils.rs | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 90fa976fda38..f515f9987a80 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -320,6 +320,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { self.body(field!(anon_const.body)); }, ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), + ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), } diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 78e3d6d192a0..a44cd31dc123 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1140,7 +1140,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Struct(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { + ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { None }, }, diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 03853b5b4af5..f1ee534c500d 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -671,11 +671,19 @@ impl HirEqInterExpr<'_, '_, '_> { .iter() .zip(*inits_b) .all(|(init_a, init_b)| self.eq_const_arg(init_a.expr, init_b.expr)) - }, + } + (ConstArgKind::TupleCall(path_a, args_a), ConstArgKind::TupleCall(path_b, args_b)) => { + self.eq_qpath(path_a, path_b) + && args_a + .iter() + .zip(*args_b) + .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) + } // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) | ConstArgKind::Anon(..) + | ConstArgKind::TupleCall(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Error(..), @@ -1546,6 +1554,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(init.expr); } }, + ConstArgKind::TupleCall(path, args) => { + self.hash_qpath(path); + for arg in *args { + self.hash_const_arg(arg); + } + }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } From 05afcb6d26567d481119c8f6f4a58ccce225f224 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Thu, 1 Jan 2026 02:16:49 +0000 Subject: [PATCH 1582/3801] init impl --- compiler/rustc_ast_lowering/src/lib.rs | 34 ++++- compiler/rustc_hir/src/hir.rs | 3 + compiler/rustc_hir/src/intravisit.rs | 7 + .../src/hir_ty_lowering/mod.rs | 135 +++++++++++++++++- compiler/rustc_hir_pretty/src/lib.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + compiler/rustc_resolve/src/def_collector.rs | 2 +- src/librustdoc/clean/mod.rs | 7 +- .../clippy/clippy_lints/src/utils/author.rs | 1 + src/tools/clippy/clippy_utils/src/consts.rs | 2 +- .../clippy/clippy_utils/src/hir_utils.rs | 16 ++- tests/crashes/136379.rs | 11 -- tests/crashes/138132.rs | 10 -- .../mgca/tuple_ctor_arg_simple.rs | 52 +++++++ .../mgca/tuple_ctor_complex_args.rs | 19 +++ .../mgca/tuple_ctor_complex_args.stderr | 14 ++ .../mgca/tuple_ctor_erroneous.rs | 46 ++++++ .../mgca/tuple_ctor_erroneous.stderr | 68 +++++++++ .../mgca/tuple_ctor_in_array_len.rs | 16 +++ .../mgca/tuple_ctor_in_array_len.stderr | 23 +++ .../const-generics/mgca/tuple_ctor_nested.rs | 38 +++++ .../mgca/tuple_ctor_type_relative.rs | 26 ++++ .../mgca/type_as_const_in_array_len.rs | 14 ++ .../mgca/type_as_const_in_array_len.stderr | 19 +++ 24 files changed, 537 insertions(+), 28 deletions(-) delete mode 100644 tests/crashes/136379.rs delete mode 100644 tests/crashes/138132.rs create mode 100644 tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs create mode 100644 tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs create mode 100644 tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr create mode 100644 tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs create mode 100644 tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr create mode 100644 tests/ui/const-generics/mgca/tuple_ctor_in_array_len.rs create mode 100644 tests/ui/const-generics/mgca/tuple_ctor_in_array_len.stderr create mode 100644 tests/ui/const-generics/mgca/tuple_ctor_nested.rs create mode 100644 tests/ui/const-generics/mgca/tuple_ctor_type_relative.rs create mode 100644 tests/ui/const-generics/mgca/type_as_const_in_array_len.rs create mode 100644 tests/ui/const-generics/mgca/type_as_const_in_array_len.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 416fef8e3af3..9a459156aba1 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2396,6 +2396,35 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; match &expr.kind { + ExprKind::Call(func, args) if let ExprKind::Path(qself, path) = &func.kind => { + let qpath = self.lower_qpath( + func.id, + qself, + path, + ParamMode::Explicit, + AllowReturnTypeNotation::No, + ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, + ); + + let lowered_args = self.arena.alloc_from_iter(args.iter().map(|arg| { + let const_arg = if let ExprKind::ConstBlock(anon_const) = &arg.kind { + let def_id = self.local_def_id(anon_const.id); + let def_kind = self.tcx.def_kind(def_id); + assert_eq!(DefKind::AnonConst, def_kind); + self.lower_anon_const_to_const_arg_direct(anon_const) + } else { + self.lower_expr_to_const_arg_direct(arg) + }; + + &*self.arena.alloc(const_arg) + })); + + ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::TupleCall(qpath, lowered_args), + } + } ExprKind::Path(qself, path) => { let qpath = self.lower_qpath( expr.id, @@ -2460,7 +2489,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { && let StmtKind::Expr(expr) = &stmt.kind && matches!( expr.kind, - ExprKind::Block(..) | ExprKind::Path(..) | ExprKind::Struct(..) + ExprKind::Block(..) + | ExprKind::Path(..) + | ExprKind::Struct(..) + | ExprKind::Call(..) ) { return self.lower_expr_to_const_arg_direct(expr); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index da3e79efd6df..252d32fa3365 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -499,6 +499,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> { match self.kind { ConstArgKind::Struct(path, _) => path.span(), ConstArgKind::Path(path) => path.span(), + ConstArgKind::TupleCall(path, _) => path.span(), ConstArgKind::Anon(anon) => anon.span, ConstArgKind::Error(span, _) => span, ConstArgKind::Infer(span, _) => span, @@ -519,6 +520,8 @@ pub enum ConstArgKind<'hir, Unambig = ()> { Anon(&'hir AnonConst), /// Represents construction of struct/struct variants Struct(QPath<'hir>, &'hir [&'hir ConstArgExprField<'hir>]), + /// Tuple constructor variant + TupleCall(QPath<'hir>, &'hir [&'hir ConstArg<'hir>]), /// Error const Error(Span, ErrorGuaranteed), /// This variant is not always used to represent inference consts, sometimes diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index e636b3fff654..853e7db0757a 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1090,6 +1090,13 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( V::Result::output() } + ConstArgKind::TupleCall(qpath, args) => { + try_visit!(visitor.visit_qpath(qpath, *hir_id, qpath.span())); + for arg in *args { + try_visit!(visitor.visit_const_arg_unambig(*arg)); + } + V::Result::output() + } ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), ConstArgKind::Error(_, _) => V::Result::output(), // errors and spans are not important 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 23110d2c5c87..680c44e80480 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -314,6 +314,7 @@ pub enum PermitVariants { enum TypeRelativePath<'tcx> { AssocItem(DefId, GenericArgsRef<'tcx>), Variant { adt: Ty<'tcx>, variant_did: DefId }, + Ctor { ctor_def_id: DefId, args: GenericArgsRef<'tcx> }, } /// New-typed boolean indicating whether explicit late-bound lifetimes @@ -1261,6 +1262,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { TypeRelativePath::Variant { adt, variant_did } => { Ok((adt, DefKind::Variant, variant_did)) } + TypeRelativePath::Ctor { .. } => { + let e = tcx.dcx().span_err(span, "expected type, found tuple constructor"); + Err(e) + } } } @@ -1294,6 +1299,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } (def_id, args) } + TypeRelativePath::Ctor { ctor_def_id, args } => { + return Ok(ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, ctor_def_id, args))); + } // FIXME(mgca): implement support for this once ready to support all adt ctor expressions, // not just const ctors TypeRelativePath::Variant { .. } => { @@ -1326,6 +1334,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .find(|vd| tcx.hygienic_eq(segment.ident, vd.ident(tcx), adt_def.did())); if let Some(variant_def) = variant_def { + // FIXME(mgca): do we want constructor resolutions to take priority over + // other possible resolutions? + if matches!(mode, LowerTypeRelativePathMode::Const) + && let Some((CtorKind::Fn, ctor_def_id)) = variant_def.ctor + { + tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None); + let _ = self.prohibit_generic_args( + slice::from_ref(segment).iter(), + GenericsArgsErrExtend::EnumVariant { + qself: hir_self_ty, + assoc_segment: segment, + adt_def, + }, + ); + let ty::Adt(_, enum_args) = self_ty.kind() else { unreachable!() }; + return Ok(TypeRelativePath::Ctor { ctor_def_id, args: enum_args }); + } if let PermitVariants::Yes = mode.permit_variants() { tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None); let _ = self.prohibit_generic_args( @@ -2266,12 +2291,106 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::ConstArgKind::Struct(qpath, inits) => { self.lower_const_arg_struct(hir_id, qpath, inits, const_arg.span()) } + hir::ConstArgKind::TupleCall(qpath, args) => { + self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span()) + } hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span), hir::ConstArgKind::Error(_, e) => ty::Const::new_error(tcx, e), } } + fn lower_const_arg_tuple_call( + &self, + hir_id: HirId, + qpath: hir::QPath<'tcx>, + args: &'tcx [&'tcx hir::ConstArg<'tcx>], + span: Span, + ) -> Const<'tcx> { + let tcx = self.tcx(); + + let non_adt_or_variant_res = || { + let e = tcx.dcx().span_err(span, "tuple constructor with invalid base path"); + ty::Const::new_error(tcx, e) + }; + + let ctor_const = match qpath { + hir::QPath::Resolved(maybe_qself, path) => { + let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself)); + self.lower_resolved_const_path(opt_self_ty, path, hir_id) + } + hir::QPath::TypeRelative(hir_self_ty, segment) => { + let self_ty = self.lower_ty(hir_self_ty); + match self.lower_type_relative_const_path( + self_ty, + hir_self_ty, + segment, + hir_id, + span, + ) { + Ok(c) => c, + Err(_) => return non_adt_or_variant_res(), + } + } + }; + + let Some(value) = ctor_const.try_to_value() else { + return non_adt_or_variant_res(); + }; + + let (adt_def, adt_args, variant_did) = match value.ty.kind() { + ty::FnDef(def_id, fn_args) + if let DefKind::Ctor(CtorOf::Variant, _) = tcx.def_kind(*def_id) => + { + let parent_did = tcx.parent(*def_id); + let enum_did = tcx.parent(parent_did); + (tcx.adt_def(enum_did), fn_args, parent_did) + } + ty::FnDef(def_id, fn_args) + if let DefKind::Ctor(CtorOf::Struct, _) = tcx.def_kind(*def_id) => + { + let parent_did = tcx.parent(*def_id); + (tcx.adt_def(parent_did), fn_args, parent_did) + } + _ => return non_adt_or_variant_res(), + }; + + let variant_def = adt_def.variant_with_id(variant_did); + let variant_idx = adt_def.variant_index_with_id(variant_did).as_u32(); + + if args.len() != variant_def.fields.len() { + let e = tcx.dcx().span_err( + span, + format!( + "tuple constructor has {} arguments but {} were provided", + variant_def.fields.len(), + args.len() + ), + ); + return ty::Const::new_error(tcx, e); + } + + let fields = variant_def + .fields + .iter() + .zip(args) + .map(|(field_def, arg)| { + self.lower_const_arg(arg, FeedConstTy::Param(field_def.did, adt_args)) + }) + .collect::>(); + + let opt_discr_const = if adt_def.is_enum() { + let valtree = ty::ValTree::from_scalar_int(tcx, variant_idx.into()); + Some(ty::Const::new_value(tcx, valtree, tcx.types.u32)) + } else { + None + }; + + let valtree = ty::ValTree::from_branches(tcx, opt_discr_const.into_iter().chain(fields)); + let adt_ty = Ty::new_adt(tcx, adt_def, adt_args); + ty::Const::new_value(tcx, valtree, adt_ty) + } + fn lower_const_arg_struct( &self, hir_id: HirId, @@ -2403,6 +2522,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let args = self.lower_generic_args_of_path_segment(span, did, segment); ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args)) } + Res::Def(DefKind::Ctor(_, CtorKind::Fn), did) => { + assert_eq!(opt_self_ty, None); + let [leading_segments @ .., segment] = path.segments else { bug!() }; + let _ = self + .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None); + let parent_did = tcx.parent(did); + let generics_did = if let DefKind::Ctor(CtorOf::Variant, _) = tcx.def_kind(did) { + tcx.parent(parent_did) + } else { + parent_did + }; + let args = self.lower_generic_args_of_path_segment(span, generics_did, segment); + ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args)) + } Res::Def(DefKind::AssocConst, did) => { let trait_segment = if let [modules @ .., trait_, _item] = path.segments { let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None); @@ -2438,9 +2571,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { DefKind::Mod | DefKind::Enum | DefKind::Variant - | DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) | DefKind::Struct - | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) | DefKind::OpaqueTy | DefKind::TyAlias | DefKind::TraitAlias diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 5c03135ee1bf..533afc372063 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1139,6 +1139,7 @@ impl<'a> State<'a> { match &const_arg.kind { // FIXME(mgca): proper printing for struct exprs ConstArgKind::Struct(..) => self.word("/* STRUCT EXPR */"), + ConstArgKind::TupleCall(..) => self.word("/* TUPLE CALL */"), ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), ConstArgKind::Anon(anon) => self.print_anon_const(anon), ConstArgKind::Error(_, _) => self.word("/*ERROR*/"), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 920c896d5a47..d79ab9eaf759 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1441,6 +1441,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Skip encoding defs for these as they should not have had a `DefId` created hir::ConstArgKind::Error(..) | hir::ConstArgKind::Struct(..) + | hir::ConstArgKind::TupleCall(..) | hir::ConstArgKind::Path(..) | hir::ConstArgKind::Infer(..) => true, hir::ConstArgKind::Anon(..) => false, diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index b50fc201bdb8..f7b85453448c 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -419,7 +419,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // Avoid overwriting `const_arg_context` as we may want to treat const blocks // as being anon consts if we are inside a const argument. - ExprKind::Struct(_) => return visit::walk_expr(self, expr), + ExprKind::Struct(_) | ExprKind::Call(..) => return visit::walk_expr(self, expr), // FIXME(mgca): we may want to handle block labels in some manner ExprKind::Block(block, _) if let [stmt] = block.stmts.as_slice() => match stmt.kind { // FIXME(mgca): this probably means that mac calls that expand diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 707b48b355ba..d75a93606ea2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -323,6 +323,9 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind // FIXME(mgca): proper printing :3 ConstantKind::Path { path: "/* STRUCT EXPR */".to_string().into() } } + hir::ConstArgKind::TupleCall(..) => { + ConstantKind::Path { path: "/* TUPLE CALL */".to_string().into() } + } hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer, } @@ -1804,7 +1807,9 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T let ct = cx.tcx.normalize_erasing_regions(typing_env, ct); print_const(cx, ct) } - hir::ConstArgKind::Struct(..) | hir::ConstArgKind::Path(..) => { + hir::ConstArgKind::Struct(..) + | hir::ConstArgKind::Path(..) + | hir::ConstArgKind::TupleCall(..) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); print_const(cx, ct) } diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 90fa976fda38..f515f9987a80 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -320,6 +320,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { self.body(field!(anon_const.body)); }, ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), + ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 78e3d6d192a0..a44cd31dc123 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1140,7 +1140,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Struct(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { + ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { None }, }, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 03853b5b4af5..f1ee534c500d 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -671,11 +671,19 @@ impl HirEqInterExpr<'_, '_, '_> { .iter() .zip(*inits_b) .all(|(init_a, init_b)| self.eq_const_arg(init_a.expr, init_b.expr)) - }, + } + (ConstArgKind::TupleCall(path_a, args_a), ConstArgKind::TupleCall(path_b, args_b)) => { + self.eq_qpath(path_a, path_b) + && args_a + .iter() + .zip(*args_b) + .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) + } // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) | ConstArgKind::Anon(..) + | ConstArgKind::TupleCall(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Error(..), @@ -1546,6 +1554,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(init.expr); } }, + ConstArgKind::TupleCall(path, args) => { + self.hash_qpath(path); + for arg in *args { + self.hash_const_arg(arg); + } + }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } diff --git a/tests/crashes/136379.rs b/tests/crashes/136379.rs deleted file mode 100644 index 077b373e3b5d..000000000000 --- a/tests/crashes/136379.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #136379 -#![feature(min_generic_const_args)] -pub struct S(); - -impl S { - pub fn f() -> [u8; S] { - [] - } -} - -pub fn main() {} diff --git a/tests/crashes/138132.rs b/tests/crashes/138132.rs deleted file mode 100644 index 3e31117c526a..000000000000 --- a/tests/crashes/138132.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #138132 -#![feature(min_generic_const_args)] -struct b(Box<[u8; c]>); -impl b { - fn d(self) { - self.0.e() - } -} -struct c<'a>(&'a u8); -fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs b/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs new file mode 100644 index 000000000000..a5b3d3d0d5b6 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs @@ -0,0 +1,52 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +use std::marker::ConstParamTy; + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +struct Point(u32, u32); + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +enum MyEnum { + Variant(T), + Other, +} + +trait Trait { + #[type_const] + const ASSOC: u32; +} + +fn with_point() -> Point { + P +} + +fn with_enum>() -> MyEnum { + E +} + +fn test() { + with_point::<{ Point(::ASSOC, N) }>(); +} + +fn test_basic() { + with_point::<{ Point(N, N) }>(); + with_point::<{ Point(const { 5 }, const { 10 }) }>(); + + with_enum::<{ MyEnum::Variant::(N) }>(); + with_enum::<{ MyEnum::Variant::(const { 42 }) }>(); + + with_enum::<{ >::Variant(N) }>(); +} + +fn main() { + test_basic::<5>(); + + let p = with_point::<{ Point(const { 1 }, const { 2 }) }>(); + assert_eq!(p, Point(1, 2)); + + let e = with_enum::<{ MyEnum::Variant::(const { 10 }) }>(); + assert_eq!(e, MyEnum::Variant(10)); +} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs new file mode 100644 index 000000000000..2e39f8952b11 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs @@ -0,0 +1,19 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Point(u32, u32); + +fn with_point() {} + +fn test() { + with_point::<{ Point(N + 1, N) }>(); + //~^ ERROR complex const arguments must be placed inside of a `const` block + + with_point::<{ Point(const { N + 1 }, N) }>(); + //~^ ERROR generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr new file mode 100644 index 000000000000..e0ea3fd5560c --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr @@ -0,0 +1,14 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/tuple_ctor_complex_args.rs:12:26 + | +LL | with_point::<{ Point(N + 1, N) }>(); + | ^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/tuple_ctor_complex_args.rs:15:34 + | +LL | with_point::<{ Point(const { N + 1 }, N) }>(); + | ^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs new file mode 100644 index 000000000000..84ded05fdd0e --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs @@ -0,0 +1,46 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Point(u32, u32); + +#[derive(Eq, PartialEq, ConstParamTy)] +enum MyEnum { + Variant(T), + Unit, +} + +const CONST_ITEM: u32 = 42; + +fn accepts_point() {} +fn accepts_enum>() {} + +fn non_ctor() {} + +fn test_errors() { + accepts_point::<{ Point(N) }>(); + //~^ ERROR tuple constructor has 2 arguments but 1 were provided + + accepts_point::<{ Point(N, N, N) }>(); + //~^ ERROR tuple constructor has 2 arguments but 3 were provided + + accepts_point::<{ UnresolvedIdent(N, N) }>(); + //~^ ERROR cannot find function, tuple struct or tuple variant `UnresolvedIdent` in this scope + //~| ERROR tuple constructor with invalid base path + + accepts_point::<{ non_ctor(N, N) }>(); + //~^ ERROR tuple constructor with invalid base path + + accepts_point::<{ CONST_ITEM(N, N) }>(); + //~^ ERROR tuple constructor with invalid base path + + accepts_point::<{ Point }>(); + //~^ ERROR the constant `Point` is not of type `Point` + + accepts_enum::<{ MyEnum::Variant:: }>(); + //~^ ERROR the constant `MyEnum::::Variant` is not of type `MyEnum` +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr new file mode 100644 index 000000000000..fbcdf35461ec --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr @@ -0,0 +1,68 @@ +error[E0425]: cannot find function, tuple struct or tuple variant `UnresolvedIdent` in this scope + --> $DIR/tuple_ctor_erroneous.rs:29:23 + | +LL | accepts_point::<{ UnresolvedIdent(N, N) }>(); + | ^^^^^^^^^^^^^^^ not found in this scope + | +help: you might be missing a const parameter + | +LL | fn test_errors() { + | +++++++++++++++++++++++++++++++++++ + +error: tuple constructor has 2 arguments but 1 were provided + --> $DIR/tuple_ctor_erroneous.rs:23:23 + | +LL | accepts_point::<{ Point(N) }>(); + | ^^^^^ + +error: tuple constructor has 2 arguments but 3 were provided + --> $DIR/tuple_ctor_erroneous.rs:26:23 + | +LL | accepts_point::<{ Point(N, N, N) }>(); + | ^^^^^ + +error: tuple constructor with invalid base path + --> $DIR/tuple_ctor_erroneous.rs:29:23 + | +LL | accepts_point::<{ UnresolvedIdent(N, N) }>(); + | ^^^^^^^^^^^^^^^ + +error: tuple constructor with invalid base path + --> $DIR/tuple_ctor_erroneous.rs:33:23 + | +LL | accepts_point::<{ non_ctor(N, N) }>(); + | ^^^^^^^^ + +error: tuple constructor with invalid base path + --> $DIR/tuple_ctor_erroneous.rs:36:23 + | +LL | accepts_point::<{ CONST_ITEM(N, N) }>(); + | ^^^^^^^^^^ + +error: the constant `Point` is not of type `Point` + --> $DIR/tuple_ctor_erroneous.rs:39:23 + | +LL | accepts_point::<{ Point }>(); + | ^^^^^ expected `Point`, found struct constructor + | +note: required by a const generic parameter in `accepts_point` + --> $DIR/tuple_ctor_erroneous.rs:17:18 + | +LL | fn accepts_point() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `accepts_point` + +error: the constant `MyEnum::::Variant` is not of type `MyEnum` + --> $DIR/tuple_ctor_erroneous.rs:42:22 + | +LL | accepts_enum::<{ MyEnum::Variant:: }>(); + | ^^^^^^^^^^^^^^^^^^^^^^ expected `MyEnum`, found enum constructor + | +note: required by a const generic parameter in `accepts_enum` + --> $DIR/tuple_ctor_erroneous.rs:18:17 + | +LL | fn accepts_enum>() {} + | ^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `accepts_enum` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.rs b/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.rs new file mode 100644 index 000000000000..5c7290b40be2 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.rs @@ -0,0 +1,16 @@ +//! Regression test for + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +pub struct S(); + +impl S { + pub fn f() -> [u8; S] { + //~^ ERROR the constant `S` is not of type `usize` + [] + //~^ ERROR mismatched types [E0308] + } +} + +pub fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.stderr b/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.stderr new file mode 100644 index 000000000000..64c3cecd4fb5 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.stderr @@ -0,0 +1,23 @@ +error: the constant `S` is not of type `usize` + --> $DIR/tuple_ctor_in_array_len.rs:9:19 + | +LL | pub fn f() -> [u8; S] { + | ^^^^^^^ expected `usize`, found struct constructor + | + = note: the length of array `[u8; S]` must be type `usize` + +error[E0308]: mismatched types + --> $DIR/tuple_ctor_in_array_len.rs:11:9 + | +LL | pub fn f() -> [u8; S] { + | ------- expected `[u8; S]` because of return type +LL | +LL | [] + | ^^ expected an array with a size of S, found one with a size of 0 + | + = note: expected array `[u8; S]` + found array `[_; 0]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/tuple_ctor_nested.rs b/tests/ui/const-generics/mgca/tuple_ctor_nested.rs new file mode 100644 index 000000000000..49a31ea3e527 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_nested.rs @@ -0,0 +1,38 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +struct Inner(u32); + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +struct Outer(Inner); + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +enum Container { + Wrap(T), +} + +fn with_outer() -> Outer { + O +} + +fn with_container>() -> Container { + C +} + +fn test() { + with_outer::<{ Outer(Inner(N)) }>(); + with_outer::<{ Outer(Inner(const { 42 })) }>(); + + with_container::<{ Container::Wrap::(Inner(N)) }>(); +} + +fn main() { + test::<5>(); + + let o = with_outer::<{ Outer(Inner(const { 10 })) }>(); + assert_eq!(o, Outer(Inner(10))); +} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_type_relative.rs b/tests/ui/const-generics/mgca/tuple_ctor_type_relative.rs new file mode 100644 index 000000000000..d5a07cbb7d70 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_type_relative.rs @@ -0,0 +1,26 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +enum Option { + Some(T), +} + +fn with_option>() -> Option { + O +} + +fn test() { + with_option::<{ >::Some(N) }>(); + with_option::<{ >::Some(const { 42 }) }>(); +} + +fn main() { + test::<5>(); + + let o = with_option::<{ >::Some(const { 10 }) }>(); + assert_eq!(o, Option::Some(10)); +} diff --git a/tests/ui/const-generics/mgca/type_as_const_in_array_len.rs b/tests/ui/const-generics/mgca/type_as_const_in_array_len.rs new file mode 100644 index 000000000000..b6b76fe3fc91 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_as_const_in_array_len.rs @@ -0,0 +1,14 @@ +//! Regression test for + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +struct B(Box<[u8; C]>); +//~^ ERROR missing generics for struct `C` +impl B { + fn d(self) { + self.0.e() + } +} +struct C<'a>(&'a u8); +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_as_const_in_array_len.stderr b/tests/ui/const-generics/mgca/type_as_const_in_array_len.stderr new file mode 100644 index 000000000000..482fd730a71c --- /dev/null +++ b/tests/ui/const-generics/mgca/type_as_const_in_array_len.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for struct `C` + --> $DIR/type_as_const_in_array_len.rs:6:19 + | +LL | struct B(Box<[u8; C]>); + | ^ expected 1 lifetime argument + | +note: struct defined here, with 1 lifetime parameter: `'a` + --> $DIR/type_as_const_in_array_len.rs:13:8 + | +LL | struct C<'a>(&'a u8); + | ^ -- +help: add missing lifetime argument + | +LL | struct B(Box<[u8; C<'a>]>); + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. From 08e0400116f8fd5ccb84ac7c0839ae4afc465449 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sun, 4 Jan 2026 12:50:21 +0000 Subject: [PATCH 1583/3801] add unit test for ExtraCheckArg::from_str --- src/tools/tidy/src/extra_checks/mod.rs | 50 ++++++++------ src/tools/tidy/src/extra_checks/tests.rs | 86 ++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 22 deletions(-) create mode 100644 src/tools/tidy/src/extra_checks/tests.rs diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index 2d654339e883..fd3dfbcf19b8 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -28,6 +28,9 @@ use crate::{CiInfo, ensure_version}; mod rustdoc_js; +#[cfg(test)] +mod tests; + const MIN_PY_REV: (u32, u32) = (3, 9); const MIN_PY_REV_STR: &str = "≥3.9"; @@ -735,7 +738,7 @@ impl From for Error { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] enum ExtraCheckParseError { #[allow(dead_code, reason = "shown through Debug")] UnknownKind(String), @@ -752,6 +755,7 @@ enum ExtraCheckParseError { IfInstalledRequiresLang, } +#[derive(PartialEq, Debug)] struct ExtraCheckArg { /// Only run the check if files to check have been modified. auto: bool, @@ -854,30 +858,32 @@ impl FromStr for ExtraCheckArg { let mut auto = false; let mut if_installed = false; let mut parts = s.split(':'); - let Some(mut first) = parts.next() else { - return Err(ExtraCheckParseError::Empty); + let mut first = match parts.next() { + Some("") | None => return Err(ExtraCheckParseError::Empty), + Some(part) => part, }; + // The loop allows users to specify `auto` and `if-installed` in any order. // Both auto:if-installed: and if-installed:auto: are valid. loop { - if !auto && first == "auto" { - let Some(part) = parts.next() else { - return Err(ExtraCheckParseError::AutoRequiresLang); - }; - auto = true; - first = part; - continue; + match (first, auto, if_installed) { + ("auto", false, _) => { + let Some(part) = parts.next() else { + return Err(ExtraCheckParseError::AutoRequiresLang); + }; + auto = true; + first = part; + } + ("if-installed", _, false) => { + let Some(part) = parts.next() else { + return Err(ExtraCheckParseError::IfInstalledRequiresLang); + }; + if_installed = true; + first = part; + continue; + } + _ => break, } - - if !if_installed && first == "if-installed" { - let Some(part) = parts.next() else { - return Err(ExtraCheckParseError::IfInstalledRequiresLang); - }; - if_installed = true; - first = part; - continue; - } - break; } let second = parts.next(); if parts.next().is_some() { @@ -897,7 +903,7 @@ impl FromStr for ExtraCheckArg { } } -#[derive(PartialEq, Copy, Clone)] +#[derive(PartialEq, Copy, Clone, Debug)] enum ExtraCheckLang { Py, Shell, @@ -921,7 +927,7 @@ impl FromStr for ExtraCheckLang { } } -#[derive(PartialEq, Copy, Clone)] +#[derive(PartialEq, Copy, Clone, Debug)] enum ExtraCheckKind { Lint, Fmt, diff --git a/src/tools/tidy/src/extra_checks/tests.rs b/src/tools/tidy/src/extra_checks/tests.rs new file mode 100644 index 000000000000..62501803b255 --- /dev/null +++ b/src/tools/tidy/src/extra_checks/tests.rs @@ -0,0 +1,86 @@ +use std::str::FromStr; + +use crate::extra_checks::{ExtraCheckArg, ExtraCheckKind, ExtraCheckLang, ExtraCheckParseError}; + +#[test] +fn test_extra_check_arg_from_str_ok() { + let test_cases = [ + ( + "auto:if-installed:spellcheck", + Ok(ExtraCheckArg { + auto: true, + if_installed: true, + lang: ExtraCheckLang::Spellcheck, + kind: None, + }), + ), + ( + "if-installed:auto:spellcheck", + Ok(ExtraCheckArg { + auto: true, + if_installed: true, + lang: ExtraCheckLang::Spellcheck, + kind: None, + }), + ), + ( + "auto:spellcheck", + Ok(ExtraCheckArg { + auto: true, + if_installed: false, + lang: ExtraCheckLang::Spellcheck, + kind: None, + }), + ), + ( + "if-installed:spellcheck", + Ok(ExtraCheckArg { + auto: false, + if_installed: true, + lang: ExtraCheckLang::Spellcheck, + kind: None, + }), + ), + ( + "spellcheck", + Ok(ExtraCheckArg { + auto: false, + if_installed: false, + lang: ExtraCheckLang::Spellcheck, + kind: None, + }), + ), + ( + "js:lint", + Ok(ExtraCheckArg { + auto: false, + if_installed: false, + lang: ExtraCheckLang::Js, + kind: Some(ExtraCheckKind::Lint), + }), + ), + ]; + + for (s, expected) in test_cases { + assert_eq!(ExtraCheckArg::from_str(s), expected); + } +} + +#[test] +fn test_extra_check_arg_from_str_err() { + let test_cases = [ + ("some:spellcheck", Err(ExtraCheckParseError::UnknownLang("some".to_string()))), + ("spellcheck:some", Err(ExtraCheckParseError::UnknownKind("some".to_string()))), + ("spellcheck:lint", Err(ExtraCheckParseError::UnsupportedKindForLang)), + ("auto:spellcheck:some", Err(ExtraCheckParseError::UnknownKind("some".to_string()))), + ("auto:js:lint:some", Err(ExtraCheckParseError::TooManyParts)), + ("some", Err(ExtraCheckParseError::UnknownLang("some".to_string()))), + ("auto", Err(ExtraCheckParseError::AutoRequiresLang)), + ("if-installed", Err(ExtraCheckParseError::IfInstalledRequiresLang)), + ("", Err(ExtraCheckParseError::Empty)), + ]; + + for (s, expected) in test_cases { + assert_eq!(ExtraCheckArg::from_str(s), expected); + } +} From 359f060175a99e73d576c08aa9f6140a13df0f4a Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Sun, 4 Jan 2026 17:06:39 +0000 Subject: [PATCH 1584/3801] relate.rs: tiny cleanup: eliminate temp vars --- compiler/rustc_type_ir/src/relate.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 4954ebc51cfc..9e14bf6b60ad 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -155,11 +155,10 @@ impl Relate for ty::FnSig { let cx = relation.cx(); if a.c_variadic != b.c_variadic { - return Err(TypeError::VariadicMismatch({ - let a = a.c_variadic; - let b = b.c_variadic; - ExpectedFound::new(a, b) - })); + return Err(TypeError::VariadicMismatch(ExpectedFound::new( + a.c_variadic, + b.c_variadic, + ))); } if a.safety != b.safety { From dfe7d8a9b647d1e6b9bd51bc81bdbba067a69e13 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sun, 4 Jan 2026 16:24:00 +0000 Subject: [PATCH 1585/3801] move ensure_version/ensure_version_or_cargo_install to extra_checks --- src/tools/tidy/src/extra_checks/mod.rs | 103 ++++++++++++++++++++++--- src/tools/tidy/src/lib.rs | 81 ------------------- 2 files changed, 93 insertions(+), 91 deletions(-) diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index fd3dfbcf19b8..a1d9ad436885 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -21,10 +21,12 @@ use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::process::Command; use std::str::FromStr; -use std::{fmt, fs, io}; +use std::{env, fmt, fs, io}; +use build_helper::ci::CiEnv; + +use crate::CiInfo; use crate::diagnostics::TidyCtx; -use crate::{CiInfo, ensure_version}; mod rustdoc_js; @@ -630,13 +632,8 @@ fn spellcheck_runner( cargo: &Path, args: &[&str], ) -> Result<(), Error> { - let bin_path = crate::ensure_version_or_cargo_install( - outdir, - cargo, - "typos-cli", - "typos", - SPELLCHECK_VER, - )?; + let bin_path = + ensure_version_or_cargo_install(outdir, cargo, "typos-cli", "typos", SPELLCHECK_VER)?; match Command::new(bin_path).current_dir(src_root).args(args).status() { Ok(status) => { if status.success() { @@ -690,6 +687,83 @@ fn find_with_extension( Ok(output) } +/// Check if the given executable is installed and the version is expected. +fn ensure_version(build_dir: &Path, bin_name: &str, version: &str) -> Result { + let bin_path = build_dir.join("misc-tools").join("bin").join(bin_name); + + match Command::new(&bin_path).arg("--version").output() { + Ok(output) => { + let Some(v) = str::from_utf8(&output.stdout).unwrap().trim().split_whitespace().last() + else { + return Err(Error::Generic("version check failed".to_string())); + }; + + if v != version { + return Err(Error::Version { program: "", required: "", installed: v.to_string() }); + } + Ok(bin_path) + } + Err(e) => Err(Error::Io(e)), + } +} + +/// If the given executable is installed with the given version, use that, +/// otherwise install via cargo. +fn ensure_version_or_cargo_install( + build_dir: &Path, + cargo: &Path, + pkg_name: &str, + bin_name: &str, + version: &str, +) -> Result { + if let Ok(bin_path) = ensure_version(build_dir, bin_name, version) { + return Ok(bin_path); + } + + eprintln!("building external tool {bin_name} from package {pkg_name}@{version}"); + + let tool_root_dir = build_dir.join("misc-tools"); + let tool_bin_dir = tool_root_dir.join("bin"); + let bin_path = tool_bin_dir.join(bin_name).with_extension(env::consts::EXE_EXTENSION); + + // use --force to ensure that if the required version is bumped, we update it. + // use --target-dir to ensure we have a build cache so repeated invocations aren't slow. + // modify PATH so that cargo doesn't print a warning telling the user to modify the path. + let mut cmd = Command::new(cargo); + cmd.args(["install", "--locked", "--force", "--quiet"]) + .arg("--root") + .arg(&tool_root_dir) + .arg("--target-dir") + .arg(tool_root_dir.join("target")) + .arg(format!("{pkg_name}@{version}")) + .env( + "PATH", + env::join_paths( + env::split_paths(&env::var("PATH").unwrap()) + .chain(std::iter::once(tool_bin_dir.clone())), + ) + .expect("build dir contains invalid char"), + ); + + // On CI, we set opt-level flag for quicker installation. + // Since lower opt-level decreases the tool's performance, + // we don't set this option on local. + if CiEnv::is_ci() { + cmd.env("RUSTFLAGS", "-Copt-level=0"); + } + + let cargo_exit_code = cmd.spawn()?.wait()?; + if !cargo_exit_code.success() { + return Err(Error::Generic("cargo install failed".to_string())); + } + assert!( + matches!(bin_path.try_exists(), Ok(true)), + "cargo install did not produce the expected binary" + ); + eprintln!("finished building tool {bin_name}"); + Ok(bin_path) +} + #[derive(Debug)] enum Error { Io(io::Error), @@ -778,7 +852,16 @@ impl ExtraCheckArg { match self.lang { ExtraCheckLang::Spellcheck => { - ensure_version(build_dir, "typos", SPELLCHECK_VER).is_ok() + match ensure_version(build_dir, "typos", SPELLCHECK_VER) { + Ok(_) => true, + Err(Error::Version { installed, .. }) => { + eprintln!( + "warning: the tool `typos` is detected, but version {installed} doesn't match with the expected version {SPELLCHECK_VER}" + ); + false + } + _ => false, + } } ExtraCheckLang::Shell => has_shellcheck().is_ok(), ExtraCheckLang::Js => { diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 62da0191da9e..425f43e42b7f 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -4,9 +4,7 @@ //! to be used by tools. use std::ffi::OsStr; -use std::path::{Path, PathBuf}; use std::process::Command; -use std::{env, io}; use build_helper::ci::CiEnv; use build_helper::git::{GitConfig, get_closest_upstream_commit}; @@ -158,85 +156,6 @@ pub fn files_modified(ci_info: &CiInfo, pred: impl Fn(&str) -> bool) -> bool { !v.is_empty() } -/// Check if the given executable is installed and the version is expected. -pub fn ensure_version(build_dir: &Path, bin_name: &str, version: &str) -> io::Result { - let bin_path = build_dir.join("misc-tools").join("bin").join(bin_name); - - match Command::new(&bin_path).arg("--version").output() { - Ok(output) => { - let Some(v) = str::from_utf8(&output.stdout).unwrap().trim().split_whitespace().last() - else { - return Err(io::Error::other("version check failed")); - }; - - if v != version { - eprintln!( - "warning: the tool `{bin_name}` is detected, but version {v} doesn't match with the expected version {version}" - ); - } - Ok(bin_path) - } - Err(e) => Err(e), - } -} - -/// If the given executable is installed with the given version, use that, -/// otherwise install via cargo. -pub fn ensure_version_or_cargo_install( - build_dir: &Path, - cargo: &Path, - pkg_name: &str, - bin_name: &str, - version: &str, -) -> io::Result { - if let Ok(bin_path) = ensure_version(build_dir, bin_name, version) { - return Ok(bin_path); - } - - eprintln!("building external tool {bin_name} from package {pkg_name}@{version}"); - - let tool_root_dir = build_dir.join("misc-tools"); - let tool_bin_dir = tool_root_dir.join("bin"); - let bin_path = tool_bin_dir.join(bin_name).with_extension(env::consts::EXE_EXTENSION); - - // use --force to ensure that if the required version is bumped, we update it. - // use --target-dir to ensure we have a build cache so repeated invocations aren't slow. - // modify PATH so that cargo doesn't print a warning telling the user to modify the path. - let mut cmd = Command::new(cargo); - cmd.args(["install", "--locked", "--force", "--quiet"]) - .arg("--root") - .arg(&tool_root_dir) - .arg("--target-dir") - .arg(tool_root_dir.join("target")) - .arg(format!("{pkg_name}@{version}")) - .env( - "PATH", - env::join_paths( - env::split_paths(&env::var("PATH").unwrap()) - .chain(std::iter::once(tool_bin_dir.clone())), - ) - .expect("build dir contains invalid char"), - ); - - // On CI, we set opt-level flag for quicker installation. - // Since lower opt-level decreases the tool's performance, - // we don't set this option on local. - if CiEnv::is_ci() { - cmd.env("RUSTFLAGS", "-Copt-level=0"); - } - - let cargo_exit_code = cmd.spawn()?.wait()?; - if !cargo_exit_code.success() { - return Err(io::Error::other("cargo install failed")); - } - assert!( - matches!(bin_path.try_exists(), Ok(true)), - "cargo install did not produce the expected binary" - ); - eprintln!("finished building tool {bin_name}"); - Ok(bin_path) -} - pub mod alphabetical; pub mod bins; pub mod debug_artifacts; From 7dbe12ec729ed3ce6d7b228cbb213d8e73df30b4 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Mon, 5 Jan 2026 00:37:40 +0900 Subject: [PATCH 1586/3801] fix: Suppress false positive missing assoc item diag on specialization --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 42 +++++++++++++++++++ .../handlers/trait_impl_missing_assoc_item.rs | 18 ++++++++ 2 files changed, 60 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index ef35694774e0..78be5a7e8fa9 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -920,6 +920,48 @@ impl Module { } } + // HACK: When specialization is enabled in the current crate, and there exists + // *any* blanket impl that provides a default implementation for the missing item, + // suppress the missing associated item diagnostic. + // This can lead to false negatives when the impl in question does not actually + // specialize that blanket impl, but determining the exact specialization + // relationship here would be significantly more expensive. + if !missing.is_empty() { + let krate = self.krate(db).id; + let def_map = crate_def_map(db, krate); + if def_map.is_unstable_feature_enabled(&sym::specialization) + || def_map.is_unstable_feature_enabled(&sym::min_specialization) + { + missing.retain(|(assoc_name, assoc_item)| { + let AssocItem::Function(_) = assoc_item else { + return true; + }; + + for &impl_ in TraitImpls::for_crate(db, krate).blanket_impls(trait_.id) + { + if impl_ == impl_id { + continue; + } + + for (name, item) in &impl_.impl_items(db).items { + let AssocItemId::FunctionId(fn_) = item else { + continue; + }; + if name != assoc_name { + continue; + } + + if db.function_signature(*fn_).is_default() { + return false; + } + } + } + + true + }); + } + } + if !missing.is_empty() { acc.push( TraitImplMissingAssocItems { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs index 0e18ce967404..2c0554470187 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs @@ -156,4 +156,22 @@ impl Trait for dyn OtherTrait {} "#, ) } + + #[test] + fn no_false_positive_on_specialization() { + check_diagnostics( + r#" +#![feature(specialization)] + +pub trait Foo { + fn foo(); +} + +impl Foo for T { + default fn foo() {} +} +impl Foo for bool {} +"#, + ); + } } From 65c17223c1fa4792be28f533c17f680d9eef0e66 Mon Sep 17 00:00:00 2001 From: is57primenumber <58158444+is57primenumber@users.noreply.github.com> Date: Wed, 17 Dec 2025 02:30:19 +0900 Subject: [PATCH 1587/3801] add CSE optimization tests for iterating over slice --- tests/codegen-llvm/slice_cse_optimization.rs | 46 ++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/codegen-llvm/slice_cse_optimization.rs diff --git a/tests/codegen-llvm/slice_cse_optimization.rs b/tests/codegen-llvm/slice_cse_optimization.rs new file mode 100644 index 000000000000..2b1851d8ae44 --- /dev/null +++ b/tests/codegen-llvm/slice_cse_optimization.rs @@ -0,0 +1,46 @@ +//! Various iterating method over slice correctly optimized using common subexpression elimination. +//! Checks function has memory(argmem: read) attribute. +//! Regression test for . +//@ compile-flags: -O + +#![crate_type = "lib"] +// CHECK-LABEL: @has_zero_iter +// CHECK-SAME: #[[ATTR:[0-9]+]] +#[inline(never)] +#[unsafe(no_mangle)] +pub fn has_zero_iter(xs: &[u8]) -> bool { + xs.iter().any(|&x| x == 0) +} + +// CHECK-LABEL: @has_zero_ptr +// CHECK-SAME: #[[ATTR]] +#[inline(never)] +#[unsafe(no_mangle)] +fn has_zero_ptr(xs: &[u8]) -> bool { + let range = xs.as_ptr_range(); + let mut start = range.start; + let end = range.end; + while start < end { + unsafe { + if *start == 0 { + return true; + } + start = start.add(1); + } + } + false +} +// CHECK-LABEL: @has_zero_for +// CHECK-SAME: #[[ATTR]] +#[inline(never)] +#[unsafe(no_mangle)] +fn has_zero_for(xs: &[u8]) -> bool { + for x in xs { + if *x == 0 { + return true; + } + } + false +} + +// CHECK: attributes #[[ATTR]] = { {{.*}}memory(argmem: read){{.*}} } From 814ee134f7ffb50369e46e94bf2829108cff0baf Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sun, 4 Jan 2026 22:07:40 +0000 Subject: [PATCH 1588/3801] Bump `askama` to 0.15 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 67078adea2b4..7379dcbb7b37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ walkdir = "2.3" filetime = "0.2.9" itertools = "0.12" pulldown-cmark = { version = "0.11", default-features = false, features = ["html"] } -askama = { version = "0.14", default-features = false, features = ["alloc", "config", "derive"] } +askama = { version = "0.15", default-features = false, features = ["alloc", "config", "derive"] } [dev-dependencies.toml] version = "0.9.7" From 9ba5b5e7f7b99bc9579d4893b5dd7582924ac68c Mon Sep 17 00:00:00 2001 From: Connor Tsui Date: Tue, 29 Jul 2025 11:10:17 +0200 Subject: [PATCH 1589/3801] add experimental `oneshot` channel The `oneshot` channel is gated under the `oneshot_channel` feature. Signed-off-by: Connor Tsui --- library/std/src/sync/mod.rs | 2 + library/std/src/sync/mpmc/mod.rs | 4 +- library/std/src/sync/mpsc.rs | 6 +- library/std/src/sync/oneshot.rs | 466 +++++++++++++++++++++++++++++++ 4 files changed, 474 insertions(+), 4 deletions(-) create mode 100644 library/std/src/sync/oneshot.rs diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs index 19b3040dcb27..5da50480c723 100644 --- a/library/std/src/sync/mod.rs +++ b/library/std/src/sync/mod.rs @@ -184,6 +184,8 @@ pub use alloc_crate::sync::{Arc, Weak}; #[unstable(feature = "mpmc_channel", issue = "126840")] pub mod mpmc; pub mod mpsc; +#[unstable(feature = "oneshot_channel", issue = "143674")] +pub mod oneshot; pub(crate) mod once; // `pub(crate)` for the `sys::sync::once` implementations and `LazyLock`. diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs index ee9795a52812..8df81a580f7b 100644 --- a/library/std/src/sync/mpmc/mod.rs +++ b/library/std/src/sync/mpmc/mod.rs @@ -654,7 +654,7 @@ impl Clone for Sender { #[unstable(feature = "mpmc_channel", issue = "126840")] impl fmt::Debug for Sender { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad("Sender { .. }") + f.debug_struct("Sender").finish_non_exhaustive() } } @@ -1380,7 +1380,7 @@ impl Clone for Receiver { #[unstable(feature = "mpmc_channel", issue = "126840")] impl fmt::Debug for Receiver { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad("Receiver { .. }") + f.debug_struct("Receiver").finish_non_exhaustive() } } diff --git a/library/std/src/sync/mpsc.rs b/library/std/src/sync/mpsc.rs index f91c26aa22cf..0ae23f6e13bf 100644 --- a/library/std/src/sync/mpsc.rs +++ b/library/std/src/sync/mpsc.rs @@ -1114,8 +1114,10 @@ impl error::Error for SendError {} impl fmt::Debug for TrySendError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - TrySendError::Full(..) => "Full(..)".fmt(f), - TrySendError::Disconnected(..) => "Disconnected(..)".fmt(f), + TrySendError::Full(..) => f.debug_tuple("TrySendError::Full").finish_non_exhaustive(), + TrySendError::Disconnected(..) => { + f.debug_tuple("TrySendError::Disconnected").finish_non_exhaustive() + } } } } diff --git a/library/std/src/sync/oneshot.rs b/library/std/src/sync/oneshot.rs new file mode 100644 index 000000000000..b2c9ba34c0ff --- /dev/null +++ b/library/std/src/sync/oneshot.rs @@ -0,0 +1,466 @@ +//! A single-producer, single-consumer (oneshot) channel. +//! +//! This is an experimental module, so the API will likely change. + +use crate::sync::mpmc; +use crate::sync::mpsc::{RecvError, SendError}; +use crate::time::{Duration, Instant}; +use crate::{error, fmt}; + +/// Creates a new oneshot channel, returning the sender/receiver halves. +/// +/// # Examples +/// +/// ``` +/// #![feature(oneshot_channel)] +/// use std::sync::oneshot; +/// use std::thread; +/// +/// let (sender, receiver) = oneshot::channel(); +/// +/// // Spawn off an expensive computation. +/// thread::spawn(move || { +/// # fn expensive_computation() -> i32 { 42 } +/// sender.send(expensive_computation()).unwrap(); +/// // `sender` is consumed by `send`, so we cannot use it anymore. +/// }); +/// +/// # fn do_other_work() -> i32 { 42 } +/// do_other_work(); +/// +/// // Let's see what that answer was... +/// println!("{:?}", receiver.recv().unwrap()); +/// // `receiver` is consumed by `recv`, so we cannot use it anymore. +/// ``` +#[must_use] +#[unstable(feature = "oneshot_channel", issue = "143674")] +pub fn channel() -> (Sender, Receiver) { + // Using a `sync_channel` with capacity 1 means that the internal implementation will use the + // `Array`-flavored channel implementation. + let (sender, receiver) = mpmc::sync_channel(1); + (Sender { inner: sender }, Receiver { inner: receiver }) +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Sender +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/// The sending half of a oneshot channel. +/// +/// # Examples +/// +/// ``` +/// #![feature(oneshot_channel)] +/// use std::sync::oneshot; +/// use std::thread; +/// +/// let (sender, receiver) = oneshot::channel(); +/// +/// thread::spawn(move || { +/// sender.send("Hello from thread!").unwrap(); +/// }); +/// +/// assert_eq!(receiver.recv().unwrap(), "Hello from thread!"); +/// ``` +/// +/// `Sender` cannot be sent between threads if it is sending non-`Send` types. +/// +/// ```compile_fail +/// #![feature(oneshot_channel)] +/// use std::sync::oneshot; +/// use std::thread; +/// use std::ptr; +/// +/// let (sender, receiver) = oneshot::channel(); +/// +/// struct NotSend(*mut ()); +/// thread::spawn(move || { +/// sender.send(NotSend(ptr::null_mut())); +/// }); +/// +/// let reply = receiver.try_recv().unwrap(); +/// ``` +#[unstable(feature = "oneshot_channel", issue = "143674")] +pub struct Sender { + /// The `oneshot` channel is simply a wrapper around a `mpmc` channel. + inner: mpmc::Sender, +} + +// SAFETY: Since the only methods in which synchronization must occur take full ownership of the +// [`Sender`], it is perfectly safe to share a `&Sender` between threads (as it is effectively +// useless without ownership). +#[unstable(feature = "oneshot_channel", issue = "143674")] +unsafe impl Sync for Sender {} + +impl Sender { + /// Attempts to send a value through this channel. This can only fail if the corresponding + /// [`Receiver`] has been dropped. + /// + /// This method is non-blocking (wait-free). + /// + /// # Examples + /// + /// ``` + /// #![feature(oneshot_channel)] + /// use std::sync::oneshot; + /// use std::thread; + /// + /// let (tx, rx) = oneshot::channel(); + /// + /// thread::spawn(move || { + /// // Perform some computation. + /// let result = 2 + 2; + /// tx.send(result).unwrap(); + /// }); + /// + /// assert_eq!(rx.recv().unwrap(), 4); + /// ``` + #[unstable(feature = "oneshot_channel", issue = "143674")] + pub fn send(self, t: T) -> Result<(), SendError> { + self.inner.send(t) + } +} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl fmt::Debug for Sender { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Sender").finish_non_exhaustive() + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Receiver +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/// The receiving half of a oneshot channel. +/// +/// # Examples +/// +/// ``` +/// #![feature(oneshot_channel)] +/// use std::sync::oneshot; +/// use std::thread; +/// use std::time::Duration; +/// +/// let (sender, receiver) = oneshot::channel(); +/// +/// thread::spawn(move || { +/// thread::sleep(Duration::from_millis(100)); +/// sender.send("Hello after delay!").unwrap(); +/// }); +/// +/// println!("Waiting for message..."); +/// println!("{}", receiver.recv().unwrap()); +/// ``` +/// +/// `Receiver` cannot be sent between threads if it is receiving non-`Send` types. +/// +/// ```compile_fail +/// # #![feature(oneshot_channel)] +/// # use std::sync::oneshot; +/// # use std::thread; +/// # use std::ptr; +/// # +/// let (sender, receiver) = oneshot::channel(); +/// +/// struct NotSend(*mut ()); +/// sender.send(NotSend(ptr::null_mut())); +/// +/// thread::spawn(move || { +/// let reply = receiver.try_recv().unwrap(); +/// }); +/// ``` +#[unstable(feature = "oneshot_channel", issue = "143674")] +pub struct Receiver { + /// The `oneshot` channel is simply a wrapper around a `mpmc` channel. + inner: mpmc::Receiver, +} + +// SAFETY: Since the only methods in which synchronization must occur take full ownership of the +// [`Receiver`], it is perfectly safe to share a `&Receiver` between threads (as it is unable to +// receive any values without ownership). +#[unstable(feature = "oneshot_channel", issue = "143674")] +unsafe impl Sync for Receiver {} + +impl Receiver { + /// Receives the value from the sending end, blocking the calling thread until it gets it. + /// + /// Can only fail if the corresponding [`Sender`] has been dropped. + /// + /// # Examples + /// + /// ``` + /// #![feature(oneshot_channel)] + /// use std::sync::oneshot; + /// use std::thread; + /// use std::time::Duration; + /// + /// let (tx, rx) = oneshot::channel(); + /// + /// thread::spawn(move || { + /// thread::sleep(Duration::from_millis(500)); + /// tx.send("Done!").unwrap(); + /// }); + /// + /// // This will block until the message arrives. + /// println!("{}", rx.recv().unwrap()); + /// ``` + #[unstable(feature = "oneshot_channel", issue = "143674")] + pub fn recv(self) -> Result { + self.inner.recv() + } + + // Fallible methods. + + /// Attempts to return a pending value on this receiver without blocking. + /// + /// # Examples + /// + /// ``` + /// #![feature(oneshot_channel)] + /// use std::sync::oneshot; + /// use std::thread; + /// use std::time::Duration; + /// + /// let (sender, mut receiver) = oneshot::channel(); + /// + /// thread::spawn(move || { + /// thread::sleep(Duration::from_millis(100)); + /// sender.send(42).unwrap(); + /// }); + /// + /// // Keep trying until we get the message, doing other work in the process. + /// loop { + /// match receiver.try_recv() { + /// Ok(value) => { + /// assert_eq!(value, 42); + /// break; + /// } + /// Err(oneshot::TryRecvError::Empty(rx)) => { + /// // Retake ownership of the receiver. + /// receiver = rx; + /// # fn do_other_work() { thread::sleep(Duration::from_millis(25)); } + /// do_other_work(); + /// } + /// Err(oneshot::TryRecvError::Disconnected) => panic!("Sender disconnected"), + /// } + /// } + /// ``` + #[unstable(feature = "oneshot_channel", issue = "143674")] + pub fn try_recv(self) -> Result> { + self.inner.try_recv().map_err(|err| match err { + mpmc::TryRecvError::Empty => TryRecvError::Empty(self), + mpmc::TryRecvError::Disconnected => TryRecvError::Disconnected, + }) + } + + /// Attempts to wait for a value on this receiver, returning an error if the corresponding + /// [`Sender`] half of this channel has been dropped, or if it waits more than `timeout`. + /// + /// # Examples + /// + /// ``` + /// #![feature(oneshot_channel)] + /// use std::sync::oneshot; + /// use std::thread; + /// use std::time::Duration; + /// + /// let (sender, receiver) = oneshot::channel(); + /// + /// thread::spawn(move || { + /// thread::sleep(Duration::from_millis(500)); + /// sender.send("Success!").unwrap(); + /// }); + /// + /// // Wait up to 1 second for the message + /// match receiver.recv_timeout(Duration::from_secs(1)) { + /// Ok(msg) => println!("Received: {}", msg), + /// Err(oneshot::RecvTimeoutError::Timeout(_)) => println!("Timed out!"), + /// Err(oneshot::RecvTimeoutError::Disconnected) => println!("Sender dropped!"), + /// } + /// ``` + #[unstable(feature = "oneshot_channel", issue = "143674")] + pub fn recv_timeout(self, timeout: Duration) -> Result> { + self.inner.recv_timeout(timeout).map_err(|err| match err { + mpmc::RecvTimeoutError::Timeout => RecvTimeoutError::Timeout(self), + mpmc::RecvTimeoutError::Disconnected => RecvTimeoutError::Disconnected, + }) + } + + /// Attempts to wait for a value on this receiver, returning an error if the corresponding + /// [`Sender`] half of this channel has been dropped, or if `deadline` is reached. + /// + /// # Examples + /// + /// ``` + /// #![feature(oneshot_channel)] + /// use std::sync::oneshot; + /// use std::thread; + /// use std::time::{Duration, Instant}; + /// + /// let (sender, receiver) = oneshot::channel(); + /// + /// thread::spawn(move || { + /// thread::sleep(Duration::from_millis(100)); + /// sender.send("Just in time!").unwrap(); + /// }); + /// + /// let deadline = Instant::now() + Duration::from_millis(500); + /// match receiver.recv_deadline(deadline) { + /// Ok(msg) => println!("Received: {}", msg), + /// Err(oneshot::RecvTimeoutError::Timeout(_)) => println!("Missed deadline!"), + /// Err(oneshot::RecvTimeoutError::Disconnected) => println!("Sender dropped!"), + /// } + /// ``` + #[unstable(feature = "oneshot_channel", issue = "143674")] + pub fn recv_deadline(self, deadline: Instant) -> Result> { + self.inner.recv_deadline(deadline).map_err(|err| match err { + mpmc::RecvTimeoutError::Timeout => RecvTimeoutError::Timeout(self), + mpmc::RecvTimeoutError::Disconnected => RecvTimeoutError::Disconnected, + }) + } +} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl fmt::Debug for Receiver { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Receiver").finish_non_exhaustive() + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Receiver Errors +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/// An error returned from the [`try_recv`](Receiver::try_recv) method. +/// +/// See the documentation for [`try_recv`] for more information on how to use this error. +/// +/// [`try_recv`]: Receiver::try_recv +#[unstable(feature = "oneshot_channel", issue = "143674")] +pub enum TryRecvError { + /// The [`Sender`] has not sent a message yet, but it might in the future (as it has not yet + /// disconnected). This variant contains the [`Receiver`] that [`try_recv`](Receiver::try_recv) + /// took ownership over. + Empty(Receiver), + /// The corresponding [`Sender`] half of this channel has become disconnected, and there will + /// never be any more data sent over the channel. + Disconnected, +} + +/// An error returned from the [`recv_timeout`](Receiver::recv_timeout) or +/// [`recv_deadline`](Receiver::recv_deadline) methods. +/// +/// # Examples +/// +/// Usage of this error is similar to [`TryRecvError`]. +/// +/// ``` +/// #![feature(oneshot_channel)] +/// use std::sync::oneshot::{self, RecvTimeoutError}; +/// use std::thread; +/// use std::time::Duration; +/// +/// let (sender, receiver) = oneshot::channel(); +/// +/// let send_failure = thread::spawn(move || { +/// // Simulate a long computation that takes longer than our timeout. +/// thread::sleep(Duration::from_millis(250)); +/// +/// // This will likely fail to send because we drop the receiver in the main thread. +/// sender.send("Goodbye!".to_string()).unwrap(); +/// }); +/// +/// // Try to receive the message with a short timeout. +/// match receiver.recv_timeout(Duration::from_millis(10)) { +/// Ok(msg) => println!("Received: {}", msg), +/// Err(RecvTimeoutError::Timeout(rx)) => { +/// println!("Timed out waiting for message!"); +/// +/// // Note that you can reuse the receiver without dropping it. +/// drop(rx); +/// }, +/// Err(RecvTimeoutError::Disconnected) => println!("Sender dropped!"), +/// } +/// +/// send_failure.join().unwrap_err(); +/// ``` +#[unstable(feature = "oneshot_channel", issue = "143674")] +pub enum RecvTimeoutError { + /// The [`Sender`] has not sent a message yet, but it might in the future (as it has not yet + /// disconnected). This variant contains the [`Receiver`] that either + /// [`recv_timeout`](Receiver::recv_timeout) or [`recv_deadline`](Receiver::recv_deadline) took + /// ownership over. + Timeout(Receiver), + /// The corresponding [`Sender`] half of this channel has become disconnected, and there will + /// never be any more data sent over the channel. + Disconnected, +} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl fmt::Debug for TryRecvError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("TryRecvError").finish_non_exhaustive() + } +} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl fmt::Display for TryRecvError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + TryRecvError::Empty(..) => "receiving on an empty oneshot channel".fmt(f), + TryRecvError::Disconnected => "receiving on a closed oneshot channel".fmt(f), + } + } +} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl error::Error for TryRecvError {} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl From for TryRecvError { + /// Converts a `RecvError` into a `TryRecvError`. + /// + /// This conversion always returns `TryRecvError::Disconnected`. + /// + /// No data is allocated on the heap. + fn from(err: RecvError) -> TryRecvError { + match err { + RecvError => TryRecvError::Disconnected, + } + } +} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl fmt::Debug for RecvTimeoutError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("RecvTimeoutError").finish_non_exhaustive() + } +} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl fmt::Display for RecvTimeoutError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + RecvTimeoutError::Timeout(..) => "timed out waiting on oneshot channel".fmt(f), + RecvTimeoutError::Disconnected => "receiving on a closed oneshot channel".fmt(f), + } + } +} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl error::Error for RecvTimeoutError {} + +#[unstable(feature = "oneshot_channel", issue = "143674")] +impl From for RecvTimeoutError { + /// Converts a `RecvError` into a `RecvTimeoutError`. + /// + /// This conversion always returns `RecvTimeoutError::Disconnected`. + /// + /// No data is allocated on the heap. + fn from(err: RecvError) -> RecvTimeoutError { + match err { + RecvError => RecvTimeoutError::Disconnected, + } + } +} From b481ecd8b51eba60c7223cef2453a0a9d4c554c0 Mon Sep 17 00:00:00 2001 From: Connor Tsui Date: Tue, 29 Jul 2025 11:11:18 +0200 Subject: [PATCH 1590/3801] add `oneshot` tests Tests inspired by tests in the `oneshot` third-party crate. --- library/std/tests/sync/lib.rs | 3 + library/std/tests/sync/oneshot.rs | 342 ++++++++++++++++++++++++++++++ 2 files changed, 345 insertions(+) create mode 100644 library/std/tests/sync/oneshot.rs diff --git a/library/std/tests/sync/lib.rs b/library/std/tests/sync/lib.rs index 7ade9f623147..32a7efde2a25 100644 --- a/library/std/tests/sync/lib.rs +++ b/library/std/tests/sync/lib.rs @@ -1,5 +1,6 @@ #![feature(mapped_lock_guards)] #![feature(mpmc_channel)] +#![feature(oneshot_channel)] #![feature(once_cell_try)] #![feature(lock_value_accessors)] #![feature(reentrant_lock)] @@ -26,6 +27,8 @@ mod mutex; mod once; mod once_lock; #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] +mod oneshot; +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] mod reentrant_lock; #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] mod rwlock; diff --git a/library/std/tests/sync/oneshot.rs b/library/std/tests/sync/oneshot.rs new file mode 100644 index 000000000000..6a87c72b9cb5 --- /dev/null +++ b/library/std/tests/sync/oneshot.rs @@ -0,0 +1,342 @@ +//! Inspired by tests from + +use std::sync::mpsc::RecvError; +use std::sync::oneshot; +use std::sync::oneshot::{RecvTimeoutError, TryRecvError}; +use std::time::{Duration, Instant}; +use std::{mem, thread}; + +#[test] +fn send_before_try_recv() { + let (sender, receiver) = oneshot::channel(); + + assert!(sender.send(19i128).is_ok()); + + match receiver.try_recv() { + Ok(19) => {} + _ => panic!("expected Ok(19)"), + } +} + +#[test] +fn send_before_recv() { + let (sender, receiver) = oneshot::channel::<()>(); + + assert!(sender.send(()).is_ok()); + assert_eq!(receiver.recv(), Ok(())); + + let (sender, receiver) = oneshot::channel::(); + + assert!(sender.send(42).is_ok()); + assert_eq!(receiver.recv(), Ok(42)); + + let (sender, receiver) = oneshot::channel::<[u8; 4096]>(); + + assert!(sender.send([0b10101010; 4096]).is_ok()); + assert!(receiver.recv().unwrap()[..] == [0b10101010; 4096][..]); +} + +#[test] +fn sender_drop() { + { + let (sender, receiver) = oneshot::channel::(); + + mem::drop(sender); + + match receiver.recv() { + Err(RecvError) => {} + _ => panic!("expected recv error"), + } + } + + { + let (sender, receiver) = oneshot::channel::(); + + mem::drop(sender); + + match receiver.try_recv() { + Err(TryRecvError::Disconnected) => {} + _ => panic!("expected disconnected error"), + } + } + { + let (sender, receiver) = oneshot::channel::(); + + mem::drop(sender); + + match receiver.recv_timeout(Duration::from_secs(1)) { + Err(RecvTimeoutError::Disconnected) => {} + _ => panic!("expected disconnected error"), + } + } +} + +#[test] +fn send_never_deadline() { + let (sender, receiver) = oneshot::channel::(); + + mem::drop(sender); + + match receiver.recv_deadline(Instant::now()) { + Err(RecvTimeoutError::Disconnected) => {} + _ => panic!("expected disconnected error"), + } +} + +#[test] +fn send_before_recv_timeout() { + let (sender, receiver) = oneshot::channel(); + + assert!(sender.send(22i128).is_ok()); + + let start = Instant::now(); + + let timeout = Duration::from_secs(1); + match receiver.recv_timeout(timeout) { + Ok(22) => {} + _ => panic!("expected Ok(22)"), + } + + assert!(start.elapsed() < timeout); +} + +#[test] +fn send_error() { + let (sender, receiver) = oneshot::channel(); + + mem::drop(receiver); + + let send_error = sender.send(32u128).unwrap_err(); + assert_eq!(send_error.0, 32); +} + +#[test] +fn recv_before_send() { + let (sender, receiver) = oneshot::channel(); + + let t1 = thread::spawn(move || { + thread::sleep(Duration::from_millis(10)); + sender.send(9u128).unwrap(); + }); + let t2 = thread::spawn(move || { + assert_eq!(receiver.recv(), Ok(9)); + }); + + t1.join().unwrap(); + t2.join().unwrap(); +} + +#[test] +fn recv_timeout_before_send() { + let (sender, receiver) = oneshot::channel(); + + let t = thread::spawn(move || { + thread::sleep(Duration::from_millis(100)); + sender.send(99u128).unwrap(); + }); + + match receiver.recv_timeout(Duration::from_secs(1)) { + Ok(99) => {} + _ => panic!("expected Ok(99)"), + } + + t.join().unwrap(); +} + +#[test] +fn recv_then_drop_sender() { + let (sender, receiver) = oneshot::channel::(); + + let t1 = thread::spawn(move || match receiver.recv() { + Err(RecvError) => {} + _ => panic!("expected recv error"), + }); + + let t2 = thread::spawn(move || { + thread::sleep(Duration::from_millis(10)); + mem::drop(sender); + }); + + t1.join().unwrap(); + t2.join().unwrap(); +} + +#[test] +fn drop_sender_then_recv() { + let (sender, receiver) = oneshot::channel::(); + + let t1 = thread::spawn(move || { + thread::sleep(Duration::from_millis(10)); + mem::drop(sender); + }); + + let t2 = thread::spawn(move || match receiver.recv() { + Err(RecvError) => {} + _ => panic!("expected disconnected error"), + }); + + t1.join().unwrap(); + t2.join().unwrap(); +} + +#[test] +fn try_recv_empty() { + let (sender, receiver) = oneshot::channel::(); + match receiver.try_recv() { + Err(TryRecvError::Empty(_)) => {} + _ => panic!("expected empty error"), + } + mem::drop(sender); +} + +#[test] +fn try_recv_then_drop_receiver() { + let (sender, receiver) = oneshot::channel::(); + + let t1 = thread::spawn(move || { + thread::sleep(Duration::from_millis(100)); + let _ = sender.send(42); + }); + + let t2 = thread::spawn(move || match receiver.try_recv() { + Ok(_) => {} + Err(TryRecvError::Empty(r)) => { + mem::drop(r); + } + Err(TryRecvError::Disconnected) => {} + }); + + t2.join().unwrap(); + t1.join().unwrap(); +} + +#[test] +fn recv_no_time() { + let (_sender, receiver) = oneshot::channel::(); + + let start = Instant::now(); + match receiver.recv_deadline(start) { + Err(RecvTimeoutError::Timeout(_)) => {} + _ => panic!("expected timeout error"), + } + + let (_sender, receiver) = oneshot::channel::(); + match receiver.recv_timeout(Duration::from_millis(0)) { + Err(RecvTimeoutError::Timeout(_)) => {} + _ => panic!("expected timeout error"), + } +} + +#[test] +fn recv_deadline_passed() { + let (_sender, receiver) = oneshot::channel::(); + + let start = Instant::now(); + let timeout = Duration::from_millis(100); + + match receiver.recv_deadline(start + timeout) { + Err(RecvTimeoutError::Timeout(_)) => {} + _ => panic!("expected timeout error"), + } + + assert!(start.elapsed() >= timeout); + assert!(start.elapsed() < timeout * 3); +} + +#[test] +fn recv_time_passed() { + let (_sender, receiver) = oneshot::channel::(); + + let start = Instant::now(); + let timeout = Duration::from_millis(100); + match receiver.recv_timeout(timeout) { + Err(RecvTimeoutError::Timeout(_)) => {} + _ => panic!("expected timeout error"), + } + assert!(start.elapsed() >= timeout); + assert!(start.elapsed() < timeout * 3); +} + +#[test] +fn non_send_type_can_be_used_on_same_thread() { + use std::ptr; + + #[derive(Debug, Eq, PartialEq)] + struct NotSend(*mut ()); + + let (sender, receiver) = oneshot::channel(); + sender.send(NotSend(ptr::null_mut())).unwrap(); + let reply = receiver.try_recv().unwrap(); + assert_eq!(reply, NotSend(ptr::null_mut())); +} + +/// Helper for testing drop behavior (taken directly from the `oneshot` crate). +struct DropCounter { + count: std::rc::Rc>, +} + +impl DropCounter { + fn new() -> (DropTracker, DropCounter) { + let count = std::rc::Rc::new(std::cell::RefCell::new(0)); + (DropTracker { count: count.clone() }, DropCounter { count }) + } + + fn count(&self) -> usize { + *self.count.borrow() + } +} + +struct DropTracker { + count: std::rc::Rc>, +} + +impl Drop for DropTracker { + fn drop(&mut self) { + *self.count.borrow_mut() += 1; + } +} + +#[test] +fn message_in_channel_dropped_on_receiver_drop() { + let (sender, receiver) = oneshot::channel(); + + let (message, counter) = DropCounter::new(); + assert_eq!(counter.count(), 0); + + sender.send(message).unwrap(); + assert_eq!(counter.count(), 0); + + mem::drop(receiver); + assert_eq!(counter.count(), 1); +} + +#[test] +fn send_error_drops_message_correctly() { + let (sender, receiver) = oneshot::channel(); + mem::drop(receiver); + + let (message, counter) = DropCounter::new(); + + let send_error = sender.send(message).unwrap_err(); + assert_eq!(counter.count(), 0); + + mem::drop(send_error); + assert_eq!(counter.count(), 1); +} + +#[test] +fn send_error_drops_message_correctly_on_extract() { + let (sender, receiver) = oneshot::channel(); + mem::drop(receiver); + + let (message, counter) = DropCounter::new(); + + let send_error = sender.send(message).unwrap_err(); + assert_eq!(counter.count(), 0); + + let message = send_error.0; // Access the inner value directly + assert_eq!(counter.count(), 0); + + mem::drop(message); + assert_eq!(counter.count(), 1); +} From 3f1dd92cc7e5c97b54b58e70ad9d904ce08e372c Mon Sep 17 00:00:00 2001 From: "U. Lasiotus" Date: Sun, 4 Jan 2026 16:55:57 -0800 Subject: [PATCH 1591/3801] Motor OS: fix compile error PR https://github.com/rust-lang/rust/pull/146341 introduced a compilation error. This fixes it. --- library/std/src/sys/fs/motor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/motor.rs b/library/std/src/sys/fs/motor.rs index 8f3336e2fa96..2ae01db24be5 100644 --- a/library/std/src/sys/fs/motor.rs +++ b/library/std/src/sys/fs/motor.rs @@ -4,7 +4,7 @@ use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::path::{Path, PathBuf}; use crate::sys::fd::FileDesc; -pub use crate::sys::fs::common::exists; +pub use crate::sys::fs::common::{Dir, exists}; use crate::sys::time::SystemTime; use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, map_motor_error, unsupported}; From 5c5c1ff6dbe84e1d9eddd158116f6e40b941ed03 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Thu, 25 Dec 2025 23:29:35 +0900 Subject: [PATCH 1592/3801] moved some test delete tests/ui/issues/issue-22426.rs duplicated of tests/ui/match/guards.rs --- .../associated-type-const-nomalization.rs} | 0 .../ui/{issues/issue-2428.rs => cast/cast-enum-const.rs} | 0 .../ui/{issues/issue-22403.rs => cast/cast-to-box-arr.rs} | 0 .../issue-41998.rs => cast/cast-to-char-compare.rs} | 0 .../const-static-ref-to-closure.rs} | 0 .../derive-debug-generic-with-lifetime.rs} | 0 .../derive-debug-newtype-unsized-slice.rs} | 0 .../call-unit-struct-impl-fn-once.rs} | 0 .../fn-trait-explicit-call.rs} | 0 tests/ui/issues/issue-22426.rs | 8 -------- tests/ui/{issues => resolve}/auxiliary/i8.rs | 0 .../const-iter-no-conflict-for-loop.rs} | 0 .../issue-20427.rs => resolve/shadow-primitives.rs} | 0 .../self-in-method-body-resolves.rs} | 0 .../bound/recursive-trait-bound-on-type-param.rs} | 0 .../tuple-ref-order-distinct-impls.rs} | 0 .../issue-20676.rs => ufcs/ufcs-trait-object-format.rs} | 0 17 files changed, 8 deletions(-) rename tests/ui/{issues/issue-26614.rs => associated-types/associated-type-const-nomalization.rs} (100%) rename tests/ui/{issues/issue-2428.rs => cast/cast-enum-const.rs} (100%) rename tests/ui/{issues/issue-22403.rs => cast/cast-to-box-arr.rs} (100%) rename tests/ui/{issues/issue-41998.rs => cast/cast-to-char-compare.rs} (100%) rename tests/ui/{issues/issue-25180.rs => consts/const-static-ref-to-closure.rs} (100%) rename tests/ui/{issues/issue-29030.rs => derives/derive-debug-generic-with-lifetime.rs} (100%) rename tests/ui/{issues/issue-25394.rs => derives/derive-debug-newtype-unsized-slice.rs} (100%) rename tests/ui/{issues/issue-33687.rs => fn_traits/call-unit-struct-impl-fn-once.rs} (100%) rename tests/ui/{issues/issue-20847.rs => fn_traits/fn-trait-explicit-call.rs} (100%) delete mode 100644 tests/ui/issues/issue-22426.rs rename tests/ui/{issues => resolve}/auxiliary/i8.rs (100%) rename tests/ui/{issues/issue-27639.rs => resolve/const-iter-no-conflict-for-loop.rs} (100%) rename tests/ui/{issues/issue-20427.rs => resolve/shadow-primitives.rs} (100%) rename tests/ui/{issues/issue-24389.rs => self/self-in-method-body-resolves.rs} (100%) rename tests/ui/{issues/issue-19601.rs => traits/bound/recursive-trait-bound-on-type-param.rs} (100%) rename tests/ui/{issues/issue-11384.rs => typeck/tuple-ref-order-distinct-impls.rs} (100%) rename tests/ui/{issues/issue-20676.rs => ufcs/ufcs-trait-object-format.rs} (100%) diff --git a/tests/ui/issues/issue-26614.rs b/tests/ui/associated-types/associated-type-const-nomalization.rs similarity index 100% rename from tests/ui/issues/issue-26614.rs rename to tests/ui/associated-types/associated-type-const-nomalization.rs diff --git a/tests/ui/issues/issue-2428.rs b/tests/ui/cast/cast-enum-const.rs similarity index 100% rename from tests/ui/issues/issue-2428.rs rename to tests/ui/cast/cast-enum-const.rs diff --git a/tests/ui/issues/issue-22403.rs b/tests/ui/cast/cast-to-box-arr.rs similarity index 100% rename from tests/ui/issues/issue-22403.rs rename to tests/ui/cast/cast-to-box-arr.rs diff --git a/tests/ui/issues/issue-41998.rs b/tests/ui/cast/cast-to-char-compare.rs similarity index 100% rename from tests/ui/issues/issue-41998.rs rename to tests/ui/cast/cast-to-char-compare.rs diff --git a/tests/ui/issues/issue-25180.rs b/tests/ui/consts/const-static-ref-to-closure.rs similarity index 100% rename from tests/ui/issues/issue-25180.rs rename to tests/ui/consts/const-static-ref-to-closure.rs diff --git a/tests/ui/issues/issue-29030.rs b/tests/ui/derives/derive-debug-generic-with-lifetime.rs similarity index 100% rename from tests/ui/issues/issue-29030.rs rename to tests/ui/derives/derive-debug-generic-with-lifetime.rs diff --git a/tests/ui/issues/issue-25394.rs b/tests/ui/derives/derive-debug-newtype-unsized-slice.rs similarity index 100% rename from tests/ui/issues/issue-25394.rs rename to tests/ui/derives/derive-debug-newtype-unsized-slice.rs diff --git a/tests/ui/issues/issue-33687.rs b/tests/ui/fn_traits/call-unit-struct-impl-fn-once.rs similarity index 100% rename from tests/ui/issues/issue-33687.rs rename to tests/ui/fn_traits/call-unit-struct-impl-fn-once.rs diff --git a/tests/ui/issues/issue-20847.rs b/tests/ui/fn_traits/fn-trait-explicit-call.rs similarity index 100% rename from tests/ui/issues/issue-20847.rs rename to tests/ui/fn_traits/fn-trait-explicit-call.rs diff --git a/tests/ui/issues/issue-22426.rs b/tests/ui/issues/issue-22426.rs deleted file mode 100644 index 0857ac9dfb4d..000000000000 --- a/tests/ui/issues/issue-22426.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass - -fn main() { - match 42 { - x if x < 7 => (), - _ => () - } -} diff --git a/tests/ui/issues/auxiliary/i8.rs b/tests/ui/resolve/auxiliary/i8.rs similarity index 100% rename from tests/ui/issues/auxiliary/i8.rs rename to tests/ui/resolve/auxiliary/i8.rs diff --git a/tests/ui/issues/issue-27639.rs b/tests/ui/resolve/const-iter-no-conflict-for-loop.rs similarity index 100% rename from tests/ui/issues/issue-27639.rs rename to tests/ui/resolve/const-iter-no-conflict-for-loop.rs diff --git a/tests/ui/issues/issue-20427.rs b/tests/ui/resolve/shadow-primitives.rs similarity index 100% rename from tests/ui/issues/issue-20427.rs rename to tests/ui/resolve/shadow-primitives.rs diff --git a/tests/ui/issues/issue-24389.rs b/tests/ui/self/self-in-method-body-resolves.rs similarity index 100% rename from tests/ui/issues/issue-24389.rs rename to tests/ui/self/self-in-method-body-resolves.rs diff --git a/tests/ui/issues/issue-19601.rs b/tests/ui/traits/bound/recursive-trait-bound-on-type-param.rs similarity index 100% rename from tests/ui/issues/issue-19601.rs rename to tests/ui/traits/bound/recursive-trait-bound-on-type-param.rs diff --git a/tests/ui/issues/issue-11384.rs b/tests/ui/typeck/tuple-ref-order-distinct-impls.rs similarity index 100% rename from tests/ui/issues/issue-11384.rs rename to tests/ui/typeck/tuple-ref-order-distinct-impls.rs diff --git a/tests/ui/issues/issue-20676.rs b/tests/ui/ufcs/ufcs-trait-object-format.rs similarity index 100% rename from tests/ui/issues/issue-20676.rs rename to tests/ui/ufcs/ufcs-trait-object-format.rs From 442127051669be574107571773c669006413dedf Mon Sep 17 00:00:00 2001 From: AprilNEA Date: Sat, 3 Jan 2026 16:24:56 +0800 Subject: [PATCH 1593/3801] Merge `associated_const_equality` feature gate into MGCA This removes `associated_const_equality` as a separate feature gate and makes it part of `min_generic_const_args` (mgca). Key changes: - Remove `associated_const_equality` from unstable features, add to removed - Update all test files to use `min_generic_const_args` instead - Preserve the original "associated const equality is incomplete" error message by specially handling `sym::associated_const_equality` spans in `feature_gate.rs` - Rename FIXME(associated_const_equality) to FIXME(mgca) --- compiler/rustc_ast_passes/src/feature_gate.rs | 18 +++++- .../src/debuginfo/type_names.rs | 2 +- compiler/rustc_feature/src/removed.rs | 3 + compiler/rustc_feature/src/unstable.rs | 2 - .../src/hir_ty_lowering/bounds.rs | 4 +- .../src/hir_ty_lowering/dyn_trait.rs | 2 +- .../src/hir_ty_lowering/errors.rs | 4 +- compiler/rustc_middle/src/ty/context.rs | 4 -- .../src/solve/assembly/structural_traits.rs | 2 +- compiler/rustc_type_ir/src/inherent.rs | 2 - ...duplication_in_bounds_assoc_const_eq.fixed | 2 +- ...it_duplication_in_bounds_assoc_const_eq.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/lower.rs | 2 +- tests/crashes/mgca/ace-with-const-ctor.rs | 2 +- .../associated-constant-not-allowed-102467.rs | 2 +- .../auxiliary/assoc-const-equality.rs | 2 +- .../assoc-const-eq-ambiguity.rs | 2 +- .../assoc-const-eq-bound-var-in-ty-not-wf.rs | 1 - ...soc-const-eq-bound-var-in-ty-not-wf.stderr | 4 +- .../assoc-const-eq-bound-var-in-ty.rs | 1 - ...oc-const-eq-const_evaluatable_unchecked.rs | 2 +- .../assoc-const-eq-esc-bound-var-in-ty.rs | 1 - .../assoc-const-eq-esc-bound-var-in-ty.stderr | 2 +- .../assoc-const-eq-missing.rs | 4 +- .../assoc-const-eq-param-in-ty.rs | 1 - .../assoc-const-eq-param-in-ty.stderr | 22 +++---- .../assoc-const-eq-supertraits.rs | 1 - .../assoc-const-eq-ty-alias-noninteracting.rs | 2 +- .../assoc-const-ty-mismatch.rs | 4 +- tests/ui/associated-consts/assoc-const.rs | 2 +- .../equality-unused-issue-126729.rs | 2 +- .../associated-consts/issue-102335-const.rs | 2 +- .../ui/associated-consts/issue-105330.stderr | 8 +-- tests/ui/associated-consts/issue-110933.rs | 2 +- tests/ui/associated-consts/issue-93835.rs | 4 +- tests/ui/associated-consts/issue-93835.stderr | 8 +-- .../projection-unspecified-but-bounded.rs | 2 +- .../const-projection-err.rs | 2 +- .../duplicate-bound-err.rs | 1 - .../duplicate-bound-err.stderr | 64 +++++++++---------- .../associated-type-bounds/duplicate-bound.rs | 2 +- .../associated-type-bounds/issue-99828.stderr | 4 +- .../associated-types-eq-2.stderr | 16 ++--- .../assoc_const_eq_diagnostic.rs | 3 +- .../assoc_const_eq_diagnostic.stderr | 16 ++--- .../associated_const_equality/coherence.rs | 2 +- .../equality_bound_with_infer.rs | 2 +- ...with-generic-in-ace-no-feature-gate.stderr | 20 +++--- .../mismatched-types-with-generic-in-ace.rs | 2 +- .../unconstrained_impl_param.stderr | 4 +- .../mgca/explicit_anon_consts.rs | 2 +- .../explicit_anon_consts_literals_hack.rs | 2 +- .../mgca/type_const-only-in-impl.rs | 2 +- .../mgca/type_const-only-in-trait.rs | 2 +- .../mgca/using-fnptr-as-type_const.rs | 2 +- .../issue-89013-no-kw.stderr | 4 +- .../parser-error-recovery/issue-89013.stderr | 4 +- .../feature-gate-associated_const_equality.rs | 2 +- ...ture-gate-associated_const_equality.stderr | 4 +- .../assoc-const-no-infer-ice-115806.rs | 2 +- .../associated-const-equality.rs | 2 +- .../no-name-for-DefPath-issue-133426.stderr | 4 +- .../recover-assoc-const-constraint.stderr | 8 +-- .../overlap-due-to-unsatisfied-const-bound.rs | 2 +- ...rlap-due-to-unsatisfied-const-bound.stderr | 12 ++-- .../dont-ice-on-assoc-projection.stderr | 4 +- 66 files changed, 166 insertions(+), 162 deletions(-) diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index dbbd3906b525..f2fdd1b0eb8b 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -505,7 +505,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { half_open_range_patterns_in_slices, "half-open range patterns in slices are unstable" ); - gate_all!(associated_const_equality, "associated const equality is incomplete"); gate_all!(yeet_expr, "`do yeet` expression is experimental"); gate_all!(const_closures, "const closures are experimental"); gate_all!(builtin_syntax, "`builtin #` syntax is unstable"); @@ -518,6 +517,23 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(postfix_match, "postfix match is experimental"); gate_all!(mut_ref, "mutable by-reference bindings are experimental"); gate_all!(min_generic_const_args, "unbraced const blocks as const args are experimental"); + // associated_const_equality is stabilized as part of min_generic_const_args + if let Some(spans) = spans.get(&sym::associated_const_equality) { + for span in spans { + if !visitor.features.min_generic_const_args() + && !span.allows_unstable(sym::min_generic_const_args) + { + #[allow(rustc::untranslatable_diagnostic)] + feature_err( + &visitor.sess, + sym::min_generic_const_args, + *span, + "associated const equality is incomplete", + ) + .emit(); + } + } + } gate_all!(global_registration, "global registration is experimental"); gate_all!(return_type_notation, "return type notation is experimental"); gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 18279a4d05fe..02476a332252 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -260,7 +260,7 @@ fn push_debuginfo_type_name<'tcx>( .map(|bound| { let ExistentialProjection { def_id: item_def_id, term, .. } = tcx.instantiate_bound_regions_with_erased(bound); - // FIXME(associated_const_equality): allow for consts here + // FIXME(mgca): allow for consts here (item_def_id, term.expect_type()) }) .collect(); diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 9d8a84c52e98..6aaf4542260c 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -60,6 +60,9 @@ declare_features! ( (removed, allocator, "1.0.0", None, None), /// Allows a test to fail without failing the whole suite. (removed, allow_fail, "1.60.0", Some(46488), Some("removed due to no clear use cases"), 93416), + /// Allows users to enforce equality of associated constants `TraitImpl`. + (removed, associated_const_equality, "CURRENT_RUSTC_VERSION", Some(92827), + Some("merged into `min_generic_const_args`")), (removed, await_macro, "1.38.0", Some(50547), Some("subsumed by `.await` syntax"), 62293), /// Allows using the `box $expr` syntax. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index f64702fc44b0..387a01967ae5 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -363,8 +363,6 @@ declare_features! ( (unstable, asm_goto_with_outputs, "1.85.0", Some(119364)), /// Allows the `may_unwind` option in inline assembly. (unstable, asm_unwind, "1.58.0", Some(93334)), - /// Allows users to enforce equality of associated constants `TraitImpl`. - (unstable, associated_const_equality, "1.58.0", Some(92827)), /// Allows associated type defaults. (unstable, associated_type_defaults, "1.2.0", Some(29661)), /// Allows implementing `AsyncDrop`. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 555ef5c45e12..9ae6a9fac504 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -610,9 +610,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { AttributeKind::TypeConst(_) ) { - if tcx.features().min_generic_const_args() - || tcx.features().associated_const_equality() - { + if tcx.features().min_generic_const_args() { let mut err = self.dcx().struct_span_err( constraint.span, "use of trait associated const without `#[type_const]`", diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs index 15d7da3a0070..edb79592e6c5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs @@ -239,7 +239,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `trait_object_dummy_self`, so check for that. let references_self = match pred.skip_binder().term.kind() { ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()), - // FIXME(associated_const_equality): We should walk the const instead of not doing anything + // FIXME(mgca): We should walk the const instead of not doing anything ty::TermKind::Const(_) => false, }; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 5fc201db68e5..51c664921804 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -359,12 +359,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { None }; - // FIXME(associated_const_equality): This has quite a few false positives and negatives. + // FIXME(mgca): This has quite a few false positives and negatives. let wrap_in_braces_sugg = if let Some(constraint) = constraint && let Some(hir_ty) = constraint.ty() && let ty = self.lower_ty(hir_ty) && (ty.is_enum() || ty.references_error()) - && tcx.features().associated_const_equality() + && tcx.features().min_generic_const_args() { Some(errors::AssocKindMismatchWrapInBracesSugg { lo: hir_ty.span.shrink_to_lo(), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 25cc739f5ff9..a2f4714d1b2c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -907,10 +907,6 @@ impl<'tcx> rustc_type_ir::inherent::Features> for &'tcx rustc_featu self.coroutine_clone() } - fn associated_const_equality(self) -> bool { - self.associated_const_equality() - } - fn feature_bound_holds_in_crate(self, symbol: Symbol) -> bool { // We don't consider feature bounds to hold in the crate when `staged_api` feature is // enabled, even if it is enabled through `#[feature]`. diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 2f6ff12e1e8d..05ea217c1de0 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -868,7 +868,7 @@ where .map(|(pred, _)| pred), )); - // FIXME(associated_const_equality): Also add associated consts to + // FIXME(mgca): Also add associated consts to // the requirements here. for associated_type_def_id in cx.associated_type_def_ids(trait_ref.def_id) { // associated types that require `Self: Sized` do not show up in the built-in diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 16f837141e97..4323b1ca6469 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -646,8 +646,6 @@ pub trait Features: Copy { fn coroutine_clone(self) -> bool; - fn associated_const_equality(self) -> bool; - fn feature_bound_holds_in_crate(self, symbol: I::Symbol) -> bool; } diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed index f2bd306a99e4..f8be3331317c 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait AssocConstTrait { #[type_const] diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs index 8e7d843a44c0..a0d7a653993f 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait AssocConstTrait { #[type_const] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 9307868f3982..6c224f875d3a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -862,7 +862,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { TermKind::Ty(ty) => { ty.walk().any(|arg| arg == dummy_self_ty.into()) } - // FIXME(associated_const_equality): We should walk the const instead of not doing anything + // FIXME(mgca): We should walk the const instead of not doing anything TermKind::Const(_) => false, }; diff --git a/tests/crashes/mgca/ace-with-const-ctor.rs b/tests/crashes/mgca/ace-with-const-ctor.rs index 9e49bca06d52..28e85f37de1f 100644 --- a/tests/crashes/mgca/ace-with-const-ctor.rs +++ b/tests/crashes/mgca/ace-with-const-ctor.rs @@ -3,7 +3,7 @@ // readded once fixed. // Previous issue (before mgca): https://github.com/rust-lang/rust/issues/105952 #![crate_name = "foo"] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] pub enum ParseMode { Raw, } diff --git a/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs index c4bbcfc2b077..5b8a90d64121 100644 --- a/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs +++ b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs @@ -2,7 +2,7 @@ // It ensures that the expected error is displayed. #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait T { type A: S = 34>; diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs b/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs index f6c03d189b5e..598d2b5bf29d 100644 --- a/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs +++ b/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs @@ -1,5 +1,5 @@ #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] pub fn accept(_: impl Trait) {} diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs index 27261a4806eb..6bc2a6d5d153 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs @@ -1,7 +1,7 @@ // We used to say "ambiguous associated type" on ambiguous associated consts. // Ensure that we now use the correct label. -#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] +#![feature(min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait0: Parent0 + Parent0 {} diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index 50914fb192ff..803cc59cc93d 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -1,7 +1,6 @@ // Check that we eventually catch types of assoc const bounds // (containing late-bound vars) that are ill-formed. #![feature( - associated_const_equality, min_generic_const_args, adt_const_params, unsized_const_params, diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index fd49e151b8e6..76868715b861 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:22:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 | LL | K = const { () } | ^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:22:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 | LL | K = const { () } | ^^^^^^^^^^^^ diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs index 54e199d702c9..e6fd5bdad002 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs @@ -4,7 +4,6 @@ //@ check-pass #![feature( - associated_const_equality, min_generic_const_args, adt_const_params, unsized_const_params, diff --git a/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs b/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs index 22a03e47b2f7..161eef63d36f 100644 --- a/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs +++ b/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs @@ -4,7 +4,7 @@ // // issue: //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] #![allow(incomplete_features)] pub trait TraitA { diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs index 7f9a04bbf0fc..d32737fcb62f 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs @@ -1,7 +1,6 @@ // Detect and reject escaping late-bound generic params in // the type of assoc consts used in an equality bound. #![feature( - associated_const_equality, min_generic_const_args, unsized_const_params, generic_const_parameter_types, diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr index e22d9bfed7ef..ef861cb7f49a 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` cannot capture late-bound generic parameters - --> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:16:35 + --> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:15:35 | LL | fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} | -- ^ its type cannot capture the late-bound lifetime parameter `'r` diff --git a/tests/ui/associated-consts/assoc-const-eq-missing.rs b/tests/ui/associated-consts/assoc-const-eq-missing.rs index f384927e4a34..22b565cb27d2 100644 --- a/tests/ui/associated-consts/assoc-const-eq-missing.rs +++ b/tests/ui/associated-consts/assoc-const-eq-missing.rs @@ -1,5 +1,5 @@ -#![feature(associated_const_equality)] -#![allow(unused)] +#![feature(min_generic_const_args)] +#![allow(incomplete_features, unused)] pub trait Foo { const N: usize; diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs index ea2f60cd6187..44e7e3f19ef2 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs @@ -1,7 +1,6 @@ // Regression test for issue #108271. // Detect and reject generic params in the type of assoc consts used in an equality bound. #![feature( - associated_const_equality, min_generic_const_args, adt_const_params, unsized_const_params, diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr index ae6a35b4b9f2..b742e68044b0 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:23:29 + --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | -- the lifetime parameter `'r` is defined here @@ -10,7 +10,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:23:29 + --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | - the type parameter `A` is defined here @@ -21,7 +21,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:23:29 + --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | - the const parameter `Q` is defined here @@ -32,7 +32,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/assoc-const-eq-param-in-ty.rs:40:26 + --> $DIR/assoc-const-eq-param-in-ty.rs:39:26 | LL | fn take1(_: impl Project) {} | -------------^^^^------------ @@ -41,7 +41,7 @@ LL | fn take1(_: impl Project) {} | the `impl Trait` is specified here error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:45:21 + --> $DIR/assoc-const-eq-param-in-ty.rs:44:21 | LL | fn take2>(_: P) {} | - ^^^^ its type must not depend on the type parameter `P` @@ -51,7 +51,7 @@ LL | fn take2>(_: P) {} = note: `SELF` has type `P` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here @@ -62,7 +62,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -70,7 +70,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` @@ -80,7 +80,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here @@ -92,7 +92,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -101,7 +101,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:54:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` diff --git a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs index c092285dfcd4..a5f8859c92bd 100644 --- a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs +++ b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs @@ -4,7 +4,6 @@ //@ check-pass #![feature( - associated_const_equality, min_generic_const_args, adt_const_params, unsized_const_params, diff --git a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs b/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs index 41857eca87de..004215986711 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs +++ b/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs @@ -5,7 +5,7 @@ //@ check-pass -#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] +#![feature(min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait: SuperTrait { diff --git a/tests/ui/associated-consts/assoc-const-ty-mismatch.rs b/tests/ui/associated-consts/assoc-const-ty-mismatch.rs index 7211637659bd..1092733a8e2e 100644 --- a/tests/ui/associated-consts/assoc-const-ty-mismatch.rs +++ b/tests/ui/associated-consts/assoc-const-ty-mismatch.rs @@ -1,5 +1,5 @@ -#![feature(associated_const_equality)] -#![allow(unused)] +#![feature(min_generic_const_args)] +#![allow(incomplete_features, unused)] pub trait Foo { const N: usize; diff --git a/tests/ui/associated-consts/assoc-const.rs b/tests/ui/associated-consts/assoc-const.rs index 6295fd50b8ff..ac9f7e53b3cb 100644 --- a/tests/ui/associated-consts/assoc-const.rs +++ b/tests/ui/associated-consts/assoc-const.rs @@ -1,5 +1,5 @@ //@ run-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] #![allow(unused, incomplete_features)] pub trait Foo { diff --git a/tests/ui/associated-consts/equality-unused-issue-126729.rs b/tests/ui/associated-consts/equality-unused-issue-126729.rs index 35b49314b5f5..614ed8c803d4 100644 --- a/tests/ui/associated-consts/equality-unused-issue-126729.rs +++ b/tests/ui/associated-consts/equality-unused-issue-126729.rs @@ -1,6 +1,6 @@ //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] #![allow(incomplete_features)] #![deny(dead_code)] diff --git a/tests/ui/associated-consts/issue-102335-const.rs b/tests/ui/associated-consts/issue-102335-const.rs index f9b816fd3bc9..a88a3abf0a12 100644 --- a/tests/ui/associated-consts/issue-102335-const.rs +++ b/tests/ui/associated-consts/issue-102335-const.rs @@ -1,4 +1,4 @@ -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] #![allow(incomplete_features)] trait T { diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index 5d6dc48e36c0..06900404ec34 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -21,8 +21,8 @@ error[E0658]: associated const equality is incomplete LL | fn foo>() { | ^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -31,8 +31,8 @@ error[E0658]: associated const equality is incomplete LL | fn main>() { | ^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0562]: `impl Trait` is not allowed in impl headers diff --git a/tests/ui/associated-consts/issue-110933.rs b/tests/ui/associated-consts/issue-110933.rs index 731ff1564ce2..9a013ee71274 100644 --- a/tests/ui/associated-consts/issue-110933.rs +++ b/tests/ui/associated-consts/issue-110933.rs @@ -1,6 +1,6 @@ //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] #![allow(incomplete_features)] pub trait Trait { diff --git a/tests/ui/associated-consts/issue-93835.rs b/tests/ui/associated-consts/issue-93835.rs index d6c2acaa9edc..26d0bbe3a40f 100644 --- a/tests/ui/associated-consts/issue-93835.rs +++ b/tests/ui/associated-consts/issue-93835.rs @@ -4,9 +4,9 @@ fn e() { type_ascribe!(p, a>); //~^ ERROR cannot find type `a` in this scope //~| ERROR cannot find value - //~| ERROR associated const equality + //~| ERROR associated const equality is incomplete //~| ERROR cannot find trait `p` in this scope - //~| ERROR associated const equality + //~| ERROR associated const equality is incomplete } fn main() {} diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/associated-consts/issue-93835.stderr index 3f1679890130..990d22bba4de 100644 --- a/tests/ui/associated-consts/issue-93835.stderr +++ b/tests/ui/associated-consts/issue-93835.stderr @@ -22,8 +22,8 @@ error[E0658]: associated const equality is incomplete LL | type_ascribe!(p, a>); | ^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -32,8 +32,8 @@ error[E0658]: associated const equality is incomplete LL | type_ascribe!(p, a>); | ^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs index 7f3304f07656..8a78b26dbc5d 100644 --- a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs @@ -1,4 +1,4 @@ -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] #![allow(incomplete_features)] // Issue 110549 diff --git a/tests/ui/associated-type-bounds/const-projection-err.rs b/tests/ui/associated-type-bounds/const-projection-err.rs index b230ea77f5fe..d485316ce371 100644 --- a/tests/ui/associated-type-bounds/const-projection-err.rs +++ b/tests/ui/associated-type-bounds/const-projection-err.rs @@ -1,4 +1,4 @@ -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] #![allow(incomplete_features)] trait TraitWAssocConst { diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.rs b/tests/ui/associated-type-bounds/duplicate-bound-err.rs index 7e86148eb811..1587be7200e7 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.rs @@ -1,7 +1,6 @@ //@ edition: 2024 #![feature( - associated_const_equality, min_generic_const_args, type_alias_impl_trait, return_type_notation diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr index 6484880392d6..ec864c1dd96e 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/duplicate-bound-err.rs:15:5 + --> $DIR/duplicate-bound-err.rs:14:5 | LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` @@ -10,7 +10,7 @@ LL | iter::empty::() | +++++ error[E0282]: type annotations needed - --> $DIR/duplicate-bound-err.rs:19:5 + --> $DIR/duplicate-bound-err.rs:18:5 | LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` @@ -21,7 +21,7 @@ LL | iter::empty::() | +++++ error[E0282]: type annotations needed - --> $DIR/duplicate-bound-err.rs:23:5 + --> $DIR/duplicate-bound-err.rs:22:5 | LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` @@ -32,7 +32,7 @@ LL | iter::empty::() | +++++ error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:27:51 + --> $DIR/duplicate-bound-err.rs:26:51 | LL | type Tait1> = impl Copy; | ^^^^^^^^^ @@ -40,7 +40,7 @@ LL | type Tait1> = impl Copy; = note: `Tait1` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:29:51 + --> $DIR/duplicate-bound-err.rs:28:51 | LL | type Tait2> = impl Copy; | ^^^^^^^^^ @@ -48,7 +48,7 @@ LL | type Tait2> = impl Copy; = note: `Tait2` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:31:57 + --> $DIR/duplicate-bound-err.rs:30:57 | LL | type Tait3> = impl Copy; | ^^^^^^^^^ @@ -56,7 +56,7 @@ LL | type Tait3> = impl Copy; = note: `Tait3` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:34:14 + --> $DIR/duplicate-bound-err.rs:33:14 | LL | type Tait4 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | type Tait4 = impl Iterator; = note: `Tait4` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:36:14 + --> $DIR/duplicate-bound-err.rs:35:14 | LL | type Tait5 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | type Tait5 = impl Iterator; = note: `Tait5` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:38:14 + --> $DIR/duplicate-bound-err.rs:37:14 | LL | type Tait6 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | type Tait6 = impl Iterator; = note: `Tait6` must be used in combination with a concrete type within the same crate error[E0277]: `*const ()` cannot be sent between threads safely - --> $DIR/duplicate-bound-err.rs:41:18 + --> $DIR/duplicate-bound-err.rs:40:18 | LL | fn mismatch() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely @@ -91,7 +91,7 @@ LL | iter::empty::<*const ()>() = help: the trait `Send` is not implemented for `*const ()` error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/duplicate-bound-err.rs:46:20 + --> $DIR/duplicate-bound-err.rs:45:20 | LL | fn mismatch_2() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` @@ -100,7 +100,7 @@ LL | iter::empty::() | ----------------------- return type was inferred to be `std::iter::Empty` here error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:112:17 + --> $DIR/duplicate-bound-err.rs:111:17 | LL | fn foo() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -109,7 +109,7 @@ LL | [2u32].into_iter() | ------------------ return type was inferred to be `std::array::IntoIter` here error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:88:42 + --> $DIR/duplicate-bound-err.rs:87:42 | LL | type MustFail = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -117,7 +117,7 @@ LL | type MustFail = dyn Iterator; | `Item` bound here first error: conflicting associated type bounds for `Item` - --> $DIR/duplicate-bound-err.rs:88:17 + --> $DIR/duplicate-bound-err.rs:87:17 | LL | type MustFail = dyn Iterator; | ^^^^^^^^^^^^^----------^^----------^ @@ -126,7 +126,7 @@ LL | type MustFail = dyn Iterator; | `Item` is specified to be `i32` here error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:97:43 + --> $DIR/duplicate-bound-err.rs:96:43 | LL | type MustFail2 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here @@ -134,7 +134,7 @@ LL | type MustFail2 = dyn Trait2; | `ASSOC` bound here first error: conflicting associated type bounds for `ASSOC` - --> $DIR/duplicate-bound-err.rs:97:18 + --> $DIR/duplicate-bound-err.rs:96:18 | LL | type MustFail2 = dyn Trait2; | ^^^^^^^^^^^------------^^------------^ @@ -143,7 +143,7 @@ LL | type MustFail2 = dyn Trait2; | `ASSOC` is specified to be `3` here error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:101:43 + --> $DIR/duplicate-bound-err.rs:100:43 | LL | type MustFail3 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -151,7 +151,7 @@ LL | type MustFail3 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:104:43 + --> $DIR/duplicate-bound-err.rs:103:43 | LL | type MustFail4 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here @@ -159,19 +159,19 @@ LL | type MustFail4 = dyn Trait2; | `ASSOC` bound here first error[E0271]: expected `impl Iterator` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:112:17 + --> $DIR/duplicate-bound-err.rs:111:17 | LL | fn foo() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` | note: required by a bound in `Trait3::foo::{anon_assoc#0}` - --> $DIR/duplicate-bound-err.rs:108:31 + --> $DIR/duplicate-bound-err.rs:107:31 | LL | fn foo() -> impl Iterator; | ^^^^^^^^^^ required by this bound in `Trait3::foo::{anon_assoc#0}` error[E0271]: expected `Empty` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:120:16 + --> $DIR/duplicate-bound-err.rs:119:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -179,13 +179,13 @@ LL | uncallable(iter::empty::()); | required by a bound introduced by this call | note: required by a bound in `uncallable` - --> $DIR/duplicate-bound-err.rs:80:32 + --> $DIR/duplicate-bound-err.rs:79:32 | LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: expected `Empty` to be an iterator that yields `u32`, but it yields `i32` - --> $DIR/duplicate-bound-err.rs:121:16 + --> $DIR/duplicate-bound-err.rs:120:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `i32` @@ -193,13 +193,13 @@ LL | uncallable(iter::empty::()); | required by a bound introduced by this call | note: required by a bound in `uncallable` - --> $DIR/duplicate-bound-err.rs:80:44 + --> $DIR/duplicate-bound-err.rs:79:44 | LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:122:22 + --> $DIR/duplicate-bound-err.rs:121:22 | LL | uncallable_const(()); | ---------------- ^^ expected `4`, found `3` @@ -209,13 +209,13 @@ LL | uncallable_const(()); = note: expected constant `4` found constant `3` note: required by a bound in `uncallable_const` - --> $DIR/duplicate-bound-err.rs:82:46 + --> $DIR/duplicate-bound-err.rs:81:46 | LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:123:22 + --> $DIR/duplicate-bound-err.rs:122:22 | LL | uncallable_const(4u32); | ---------------- ^^^^ expected `3`, found `4` @@ -225,13 +225,13 @@ LL | uncallable_const(4u32); = note: expected constant `3` found constant `4` note: required by a bound in `uncallable_const` - --> $DIR/duplicate-bound-err.rs:82:35 + --> $DIR/duplicate-bound-err.rs:81:35 | LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:124:20 + --> $DIR/duplicate-bound-err.rs:123:20 | LL | uncallable_rtn(()); | -------------- ^^ expected `4`, found `3` @@ -241,7 +241,7 @@ LL | uncallable_rtn(()); = note: expected constant `4` found constant `3` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:85:61 + --> $DIR/duplicate-bound-err.rs:84:61 | LL | fn uncallable_rtn( | -------------- required by a bound in this function @@ -249,7 +249,7 @@ LL | _: impl Trait, foo(..): Trait> | ^^^^^^^^^ required by this bound in `uncallable_rtn` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:125:20 + --> $DIR/duplicate-bound-err.rs:124:20 | LL | uncallable_rtn(17u32); | -------------- ^^^^^ expected `3`, found `4` @@ -259,7 +259,7 @@ LL | uncallable_rtn(17u32); = note: expected constant `3` found constant `4` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:85:34 + --> $DIR/duplicate-bound-err.rs:84:34 | LL | fn uncallable_rtn( | -------------- required by a bound in this function diff --git a/tests/ui/associated-type-bounds/duplicate-bound.rs b/tests/ui/associated-type-bounds/duplicate-bound.rs index 6ea0daeca2c4..1aeb0022a04f 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound.rs @@ -1,7 +1,7 @@ //@ edition: 2024 //@ run-pass -#![feature(associated_const_equality, min_generic_const_args, return_type_notation)] +#![feature(min_generic_const_args, return_type_notation)] #![expect(incomplete_features)] #![allow(dead_code, refining_impl_trait_internal, type_alias_bounds)] diff --git a/tests/ui/associated-type-bounds/issue-99828.stderr b/tests/ui/associated-type-bounds/issue-99828.stderr index 132d5251987b..e1dc1f07d9cb 100644 --- a/tests/ui/associated-type-bounds/issue-99828.stderr +++ b/tests/ui/associated-type-bounds/issue-99828.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { | ^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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: expected type, found constant diff --git a/tests/ui/associated-types/associated-types-eq-2.stderr b/tests/ui/associated-types/associated-types-eq-2.stderr index 19c34241e5f2..9be346516c89 100644 --- a/tests/ui/associated-types/associated-types-eq-2.stderr +++ b/tests/ui/associated-types/associated-types-eq-2.stderr @@ -7,8 +7,8 @@ LL | impl Tr3 for Bar { | |____^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -17,8 +17,8 @@ error[E0658]: associated const equality is incomplete LL | impl Tr3 for Qux { | ^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -27,8 +27,8 @@ error[E0658]: associated const equality is incomplete LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { | ^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -37,8 +37,8 @@ error[E0658]: associated const equality is incomplete LL | impl Tr3 for Bar { | ^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0229]: associated item constraints are not allowed here diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.rs b/tests/ui/const-generics/assoc_const_eq_diagnostic.rs index 6ab82f45e684..f2b581412a72 100644 --- a/tests/ui/const-generics/assoc_const_eq_diagnostic.rs +++ b/tests/ui/const-generics/assoc_const_eq_diagnostic.rs @@ -1,5 +1,6 @@ //@ edition:2015 -#![feature(associated_const_equality)] +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] pub enum Mode { Cool, diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr b/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr index bcfad9d1538c..05e0ec93d494 100644 --- a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr +++ b/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found variant `Mode::Cool` - --> $DIR/assoc_const_eq_diagnostic.rs:12:35 + --> $DIR/assoc_const_eq_diagnostic.rs:13:35 | LL | pub trait CoolStuff: Parse {} | ^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | pub trait CoolStuff: Parse {} | help: try using the variant's enum: `Mode` error[E0573]: expected type, found variant `Mode::Cool` - --> $DIR/assoc_const_eq_diagnostic.rs:18:17 + --> $DIR/assoc_const_eq_diagnostic.rs:19:17 | LL | fn no_help() -> Mode::Cool {} | ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn no_help() -> Mode::Cool {} | help: try using the variant's enum: `Mode` error: expected constant, found type - --> $DIR/assoc_const_eq_diagnostic.rs:12:35 + --> $DIR/assoc_const_eq_diagnostic.rs:13:35 | LL | pub trait CoolStuff: Parse {} | ---- ^^^^^^^^^^ unexpected type @@ -25,7 +25,7 @@ LL | pub trait CoolStuff: Parse {} | expected a constant because of this associated constant | note: the associated constant is defined here - --> $DIR/assoc_const_eq_diagnostic.rs:9:5 + --> $DIR/assoc_const_eq_diagnostic.rs:10:5 | LL | const MODE: Mode; | ^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | pub trait CoolStuff: Parse {} | + + error: expected constant, found type - --> $DIR/assoc_const_eq_diagnostic.rs:12:35 + --> $DIR/assoc_const_eq_diagnostic.rs:13:35 | LL | pub trait CoolStuff: Parse {} | ---- ^^^^^^^^^^ unexpected type @@ -43,7 +43,7 @@ LL | pub trait CoolStuff: Parse {} | expected a constant because of this associated constant | note: the associated constant is defined here - --> $DIR/assoc_const_eq_diagnostic.rs:9:5 + --> $DIR/assoc_const_eq_diagnostic.rs:10:5 | LL | const MODE: Mode; | ^^^^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | pub trait CoolStuff: Parse {} | + + error: expected constant, found type - --> $DIR/assoc_const_eq_diagnostic.rs:12:35 + --> $DIR/assoc_const_eq_diagnostic.rs:13:35 | LL | pub trait CoolStuff: Parse {} | ---- ^^^^^^^^^^ unexpected type @@ -62,7 +62,7 @@ LL | pub trait CoolStuff: Parse {} | expected a constant because of this associated constant | note: the associated constant is defined here - --> $DIR/assoc_const_eq_diagnostic.rs:9:5 + --> $DIR/assoc_const_eq_diagnostic.rs:10:5 | LL | const MODE: Mode; | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/associated_const_equality/coherence.rs b/tests/ui/const-generics/associated_const_equality/coherence.rs index fb5f255c1dc4..f4081fae6144 100644 --- a/tests/ui/const-generics/associated_const_equality/coherence.rs +++ b/tests/ui/const-generics/associated_const_equality/coherence.rs @@ -1,4 +1,4 @@ -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] #![expect(incomplete_features)] pub trait IsVoid { diff --git a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs index 3973c7af15b4..b7ed8ee39f87 100644 --- a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs +++ b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs @@ -1,6 +1,6 @@ //@ check-pass -#![feature(associated_const_equality, min_generic_const_args, generic_const_items)] +#![feature(min_generic_const_args, generic_const_items)] #![expect(incomplete_features)] // Regression test for #133066 where we would try to evaluate `<() as Foo>::ASSOC<_>` even diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr index 0b487b6a7aa0..d2f28a62e04e 100644 --- a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr +++ b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr @@ -1,13 +1,3 @@ -error[E0658]: associated const equality is incomplete - --> $DIR/mismatched-types-with-generic-in-ace-no-feature-gate.rs:7:38 - | -LL | fn take0(_: impl Owner = { N }>) {} - | ^^^^^^^^^^^^ - | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` 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[E0658]: generic const items are experimental --> $DIR/mismatched-types-with-generic-in-ace-no-feature-gate.rs:2:12 | @@ -18,6 +8,16 @@ LL | const C: u32 = N; = help: add `#![feature(generic_const_items)]` 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[E0658]: associated const equality is incomplete + --> $DIR/mismatched-types-with-generic-in-ace-no-feature-gate.rs:7:38 + | +LL | fn take0(_: impl Owner = { N }>) {} + | ^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs index 33afa7e3228e..77f0f06f8040 100644 --- a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs +++ b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs @@ -1,4 +1,4 @@ -#![feature(generic_const_items, associated_const_equality, min_generic_const_args)] +#![feature(generic_const_items, min_generic_const_args)] #![expect(incomplete_features)] trait Foo { diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr index 092faff93511..c34674604b51 100644 --- a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr +++ b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | impl Trait for () where (U,): AssocConst {} | ^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs index f3edc0b3fbf3..bf825a44b1c0 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -1,4 +1,4 @@ -#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] +#![feature(generic_const_items, min_generic_const_args)] #![expect(incomplete_features)] // library crates exercise weirder code paths around // DefIds which were created for const args. diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs index 8c8c5c8e8f88..eb8f04b8b24b 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs @@ -4,7 +4,7 @@ // However, we don't allow so for const arguments in field init positions. // This is just harder to implement so we did not do so. -#![feature(min_generic_const_args, adt_const_params, associated_const_equality)] +#![feature(min_generic_const_args, adt_const_params)] #![expect(incomplete_features)] trait Trait { diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl.rs b/tests/ui/const-generics/mgca/type_const-only-in-impl.rs index ae4a0004232b..1887f511bd62 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl.rs @@ -1,5 +1,5 @@ #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait BadTr { const NUM: usize; diff --git a/tests/ui/const-generics/mgca/type_const-only-in-trait.rs b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs index 8c8ff6259cae..2ff38648206a 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-trait.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs @@ -1,5 +1,5 @@ #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait GoodTr { #[type_const] diff --git a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs index d97b3a9f0929..5c494031d4fa 100644 --- a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs +++ b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs @@ -1,7 +1,7 @@ // Regression test for #119783 #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait Trait { #[type_const] diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr index d435af07db2a..9c956d79a7bb 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | impl Foo for Bar { | ^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0229]: associated item constraints are not allowed here diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr index f852c14b1784..4a4ff098dc4b 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -16,8 +16,8 @@ error[E0658]: associated const equality is incomplete LL | impl Foo for Bar { | ^^^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0229]: associated item constraints are not allowed here diff --git a/tests/ui/feature-gates/feature-gate-associated_const_equality.rs b/tests/ui/feature-gates/feature-gate-associated_const_equality.rs index 2534c527be46..6b643b629a29 100644 --- a/tests/ui/feature-gates/feature-gate-associated_const_equality.rs +++ b/tests/ui/feature-gates/feature-gate-associated_const_equality.rs @@ -8,7 +8,7 @@ impl TraitWAssocConst for Demo { } fn foo>() {} -//~^ ERROR associated const equality +//~^ ERROR associated const equality is incomplete fn main() { foo::(); diff --git a/tests/ui/feature-gates/feature-gate-associated_const_equality.stderr b/tests/ui/feature-gates/feature-gate-associated_const_equality.stderr index 5a0fb69b6ba7..096755701931 100644 --- a/tests/ui/feature-gates/feature-gate-associated_const_equality.stderr +++ b/tests/ui/feature-gates/feature-gate-associated_const_equality.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | fn foo>() {} | ^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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 diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index a72aaedb980e..fb2506daf078 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -1,6 +1,6 @@ // ICE: assertion failed: !value.has_infer() // issue: rust-lang/rust#115806 -#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] +#![feature(min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] pub struct NoPin; diff --git a/tests/ui/generic-const-items/associated-const-equality.rs b/tests/ui/generic-const-items/associated-const-equality.rs index 37cf381e6824..d0301b920e27 100644 --- a/tests/ui/generic-const-items/associated-const-equality.rs +++ b/tests/ui/generic-const-items/associated-const-equality.rs @@ -1,7 +1,7 @@ //@ check-pass #![feature(generic_const_items, min_generic_const_args)] -#![feature(associated_const_equality, adt_const_params)] +#![feature(adt_const_params)] #![allow(incomplete_features)] trait Owner { diff --git a/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr b/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr index 555d8eec6bab..3d1233cdd019 100644 --- a/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr +++ b/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | fn b(_: impl Iterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0614]: type `!` cannot be dereferenced diff --git a/tests/ui/parser/recover/recover-assoc-const-constraint.stderr b/tests/ui/parser/recover/recover-assoc-const-constraint.stderr index 02b1c3fe68a9..766acd0398d2 100644 --- a/tests/ui/parser/recover/recover-assoc-const-constraint.stderr +++ b/tests/ui/parser/recover/recover-assoc-const-constraint.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | bar::(); | ^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -14,8 +14,8 @@ error[E0658]: associated const equality is incomplete LL | bar::(); | ^^^^^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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 2 previous errors diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs index edea6f75444f..538b0c2b1d46 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs @@ -1,6 +1,6 @@ // Regression test for #140571. The compiler used to ICE -#![feature(associated_const_equality, min_generic_const_args, specialization)] +#![feature(min_generic_const_args, specialization)] //~^ WARN the feature `specialization` is incomplete //~| WARN the feature `min_generic_const_args` is incomplete diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr index bf15d0fae4e5..6159c2ed331a 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr @@ -1,17 +1,17 @@ warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:39 + --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:12 | -LL | #![feature(associated_const_equality, min_generic_const_args, specialization)] - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(min_generic_const_args, specialization)] + | ^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #132980 for more information = note: `#[warn(incomplete_features)]` on by default warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:63 + --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:36 | -LL | #![feature(associated_const_equality, min_generic_const_args, specialization)] - | ^^^^^^^^^^^^^^ +LL | #![feature(min_generic_const_args, specialization)] + | ^^^^^^^^^^^^^^ | = note: see issue #31844 for more information = help: consider using `min_specialization` instead, which is more stable and complete diff --git a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr index db7d2dd3e3a3..8334fdae9485 100644 --- a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr +++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | impl Foo for T where T: Bar {} | ^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0119]: conflicting implementations of trait `Foo` for type `()` From af5bebeae3d66b2b92bee4187108f64d931537f8 Mon Sep 17 00:00:00 2001 From: AprilNEA Date: Sat, 3 Jan 2026 16:24:56 +0800 Subject: [PATCH 1594/3801] Merge `associated_const_equality` feature gate into MGCA This removes `associated_const_equality` as a separate feature gate and makes it part of `min_generic_const_args` (mgca). Key changes: - Remove `associated_const_equality` from unstable features, add to removed - Update all test files to use `min_generic_const_args` instead - Preserve the original "associated const equality is incomplete" error message by specially handling `sym::associated_const_equality` spans in `feature_gate.rs` - Rename FIXME(associated_const_equality) to FIXME(mgca) --- tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed | 2 +- tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed index f2bd306a99e4..f8be3331317c 100644 --- a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed +++ b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait AssocConstTrait { #[type_const] diff --git a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs index 8e7d843a44c0..a0d7a653993f 100644 --- a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs +++ b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait AssocConstTrait { #[type_const] From 3f773fac3b5a1ed57ffd9918789dab7ce0e7c0ac Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Wed, 31 Dec 2025 12:29:01 +0530 Subject: [PATCH 1595/3801] std: sys: fs: uefi: Implement remove_dir_all - Using the implementation from sys::fs::common since UEFI does not have a built-in for this functionality. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 14ee49e071c1..5a07e6332109 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -6,7 +6,7 @@ use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; -pub use crate::sys::fs::common::Dir; +pub use crate::sys::fs::common::{Dir, remove_dir_all}; use crate::sys::pal::{helpers, unsupported}; use crate::sys::time::SystemTime; @@ -446,10 +446,6 @@ pub fn rmdir(p: &Path) -> io::Result<()> { } } -pub fn remove_dir_all(_path: &Path) -> io::Result<()> { - unsupported() -} - pub fn exists(path: &Path) -> io::Result { let f = uefi_fs::File::from_path(path, r_efi::protocols::file::MODE_READ, 0); match f { From 93f8ad99507ecb851ace4b1d4e3e7c5cd67ed80c Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Fri, 26 Dec 2025 00:13:11 +0900 Subject: [PATCH 1596/3801] cleaned up some tests cleaned up cast-enum-const.rs cleaned up ufcs-trait-object-format.rs add comment to cast-to-box-arr.rs add comment to shadow-primitives.rs add comment to associated-type-const-nomalization.rs add comment to fn-trait-explicit-call.rs add comment to call-unit-struct-impl-fn-once.rs add comment to cast-to-char-compare.rs add comment to self-in-method-body-resolves.rs add comment to derive-debug-newtype-unsized-slice.rs add comment to tuple-ref-order-distinct-impls.rs add comment to derive-debug-generic-with-lifetime.rs add comment to recursive-trait-bound-on-type-param.rs cleaned up const-static-ref-to-closure.rs add comment to const-iter-no-conflict-for-loop.rs --- .../associated-type-const-nomalization.rs | 1 + tests/ui/cast/cast-enum-const.rs | 12 +++---- tests/ui/cast/cast-to-box-arr.rs | 1 + tests/ui/cast/cast-to-char-compare.rs | 2 +- .../ui/consts/const-static-ref-to-closure.rs | 4 +-- .../derive-debug-generic-with-lifetime.rs | 1 + .../derive-debug-newtype-unsized-slice.rs | 1 + .../call-unit-struct-impl-fn-once.rs | 1 + tests/ui/fn_traits/fn-trait-explicit-call.rs | 1 + .../const-iter-no-conflict-for-loop.rs | 4 +++ tests/ui/resolve/shadow-primitives.rs | 33 ++++++++++--------- tests/ui/self/self-in-method-body-resolves.rs | 9 +++-- .../recursive-trait-bound-on-type-param.rs | 8 ++++- .../typeck/tuple-ref-order-distinct-impls.rs | 5 ++- tests/ui/ufcs/ufcs-trait-object-format.rs | 9 ++--- 15 files changed, 59 insertions(+), 33 deletions(-) diff --git a/tests/ui/associated-types/associated-type-const-nomalization.rs b/tests/ui/associated-types/associated-type-const-nomalization.rs index 576c7545924b..b7951ba9a435 100644 --- a/tests/ui/associated-types/associated-type-const-nomalization.rs +++ b/tests/ui/associated-types/associated-type-const-nomalization.rs @@ -1,3 +1,4 @@ +//! regression test for //@ check-pass trait Mirror { diff --git a/tests/ui/cast/cast-enum-const.rs b/tests/ui/cast/cast-enum-const.rs index 9cb02460f35b..cfad40c07b0e 100644 --- a/tests/ui/cast/cast-enum-const.rs +++ b/tests/ui/cast/cast-enum-const.rs @@ -1,14 +1,12 @@ +//! regression test for //@ run-pass -#![allow(non_upper_case_globals)] - -pub fn main() { - let _foo = 100; - const quux: isize = 5; +fn main() { + const QUUX: isize = 5; enum Stuff { - Bar = quux + Bar = QUUX, } - assert_eq!(Stuff::Bar as isize, quux); + assert_eq!(Stuff::Bar as isize, QUUX); } diff --git a/tests/ui/cast/cast-to-box-arr.rs b/tests/ui/cast/cast-to-box-arr.rs index 89c956913f93..1a9004cd074e 100644 --- a/tests/ui/cast/cast-to-box-arr.rs +++ b/tests/ui/cast/cast-to-box-arr.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass fn main() { let x = Box::new([1, 2, 3]); diff --git a/tests/ui/cast/cast-to-char-compare.rs b/tests/ui/cast/cast-to-char-compare.rs index 303bf7a57513..159b8ee04e02 100644 --- a/tests/ui/cast/cast-to-char-compare.rs +++ b/tests/ui/cast/cast-to-char-compare.rs @@ -1,6 +1,6 @@ +//! regression test for //@ check-pass - fn main() { if ('x' as char) < ('y' as char) { print!("x"); diff --git a/tests/ui/consts/const-static-ref-to-closure.rs b/tests/ui/consts/const-static-ref-to-closure.rs index 339aca037546..06b5ca5a935c 100644 --- a/tests/ui/consts/const-static-ref-to-closure.rs +++ b/tests/ui/consts/const-static-ref-to-closure.rs @@ -1,7 +1,7 @@ +//! regression test for //@ check-pass #![allow(dead_code)] -#![allow(non_upper_case_globals)] -const x: &'static dyn Fn() = &|| println!("ICE here"); +const X: &'static dyn Fn() = &|| println!("ICE here"); fn main() {} diff --git a/tests/ui/derives/derive-debug-generic-with-lifetime.rs b/tests/ui/derives/derive-debug-generic-with-lifetime.rs index c92853fb5dc2..430ade071795 100644 --- a/tests/ui/derives/derive-debug-generic-with-lifetime.rs +++ b/tests/ui/derives/derive-debug-generic-with-lifetime.rs @@ -1,3 +1,4 @@ +//! regression test for //@ check-pass #![allow(dead_code)] #[derive(Debug)] diff --git a/tests/ui/derives/derive-debug-newtype-unsized-slice.rs b/tests/ui/derives/derive-debug-newtype-unsized-slice.rs index 689c9f33af02..c735d9f039d2 100644 --- a/tests/ui/derives/derive-debug-newtype-unsized-slice.rs +++ b/tests/ui/derives/derive-debug-newtype-unsized-slice.rs @@ -1,3 +1,4 @@ +//! regression test for //@ check-pass #![allow(dead_code)] #[derive(Debug)] diff --git a/tests/ui/fn_traits/call-unit-struct-impl-fn-once.rs b/tests/ui/fn_traits/call-unit-struct-impl-fn-once.rs index a5693b3aca8e..15554482931b 100644 --- a/tests/ui/fn_traits/call-unit-struct-impl-fn-once.rs +++ b/tests/ui/fn_traits/call-unit-struct-impl-fn-once.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass #![feature(unboxed_closures)] #![feature(fn_traits)] diff --git a/tests/ui/fn_traits/fn-trait-explicit-call.rs b/tests/ui/fn_traits/fn-trait-explicit-call.rs index 364b07bf6922..f37e0a558baa 100644 --- a/tests/ui/fn_traits/fn-trait-explicit-call.rs +++ b/tests/ui/fn_traits/fn-trait-explicit-call.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass #![feature(fn_traits)] diff --git a/tests/ui/resolve/const-iter-no-conflict-for-loop.rs b/tests/ui/resolve/const-iter-no-conflict-for-loop.rs index 95edcb8695e2..ddbba64e5a31 100644 --- a/tests/ui/resolve/const-iter-no-conflict-for-loop.rs +++ b/tests/ui/resolve/const-iter-no-conflict-for-loop.rs @@ -1,3 +1,7 @@ +//! regression test for +//! Ensure that a constant named `iter` does not +//! interfere with the name resolution of the `iter` methods used internally +//! by `for` loops //@ run-pass #![allow(dead_code)] #![allow(non_upper_case_globals)] diff --git a/tests/ui/resolve/shadow-primitives.rs b/tests/ui/resolve/shadow-primitives.rs index 4018043c371e..17da0cd0530c 100644 --- a/tests/ui/resolve/shadow-primitives.rs +++ b/tests/ui/resolve/shadow-primitives.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] @@ -31,17 +32,10 @@ mod char { mod char_ {} mod str { - use super::i8 as i8; - use super::i32_ as i32; - use super::i64_ as i64; - use super::u8_ as u8; - use super::f_ as f64; - use super::u16_ as u16; - use super::u32_ as u32; - use super::u64_ as u64; - use super::bool_ as bool; - use super::{bool_ as str}; - use super::char_ as char; + use super::{ + bool_ as bool, bool_ as str, char_ as char, f_ as f64, i8, i32_ as i32, i64_ as i64, + u8_ as u8, u16_ as u16, u32_ as u32, u64_ as u64, + }; } } @@ -49,7 +43,9 @@ trait isize_ { type isize; } -fn usize<'usize>(usize: &'usize usize) -> &'usize usize { usize } +fn usize<'usize>(usize: &'usize usize) -> &'usize usize { + usize +} mod reuse { use std::mem::size_of; @@ -68,9 +64,10 @@ mod reuse { mod guard { pub fn check() { use std::u8; // bring module u8 in scope - fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8 + fn f() -> u8 { + // OK, resolves to primitive u8, not to std::u8 u8::max_value() // OK, resolves to associated function ::max_value, - // not to non-existent std::u8::max_value + // not to non-existent std::u8::max_value } assert_eq!(f(), u8::MAX); // OK, resolves to std::u8::MAX } @@ -79,7 +76,13 @@ mod guard { fn main() { let bool = true; let _ = match bool { - str @ true => if str { i32 as i64 } else { i64 }, + str @ true => { + if str { + i32 as i64 + } else { + i64 + } + } false => i64, }; diff --git a/tests/ui/self/self-in-method-body-resolves.rs b/tests/ui/self/self-in-method-body-resolves.rs index 95bb2af9b25c..636922cd87ce 100644 --- a/tests/ui/self/self-in-method-body-resolves.rs +++ b/tests/ui/self/self-in-method-body-resolves.rs @@ -1,11 +1,16 @@ +//! regression test for //@ check-pass #![allow(dead_code)] struct Foo; impl Foo { - fn new() -> Self { Foo } - fn bar() { Self::new(); } + fn new() -> Self { + Foo + } + fn bar() { + Self::new(); + } } fn main() {} diff --git a/tests/ui/traits/bound/recursive-trait-bound-on-type-param.rs b/tests/ui/traits/bound/recursive-trait-bound-on-type-param.rs index e97819e4122d..41ae91afad49 100644 --- a/tests/ui/traits/bound/recursive-trait-bound-on-type-param.rs +++ b/tests/ui/traits/bound/recursive-trait-bound-on-type-param.rs @@ -1,6 +1,12 @@ +//! regression test for //@ check-pass trait A {} -struct B where B: A> { t: T } +struct B +where + B: A>, +{ + t: T, +} fn main() {} diff --git a/tests/ui/typeck/tuple-ref-order-distinct-impls.rs b/tests/ui/typeck/tuple-ref-order-distinct-impls.rs index ad0affa4b0d2..fdede8a1d9c4 100644 --- a/tests/ui/typeck/tuple-ref-order-distinct-impls.rs +++ b/tests/ui/typeck/tuple-ref-order-distinct-impls.rs @@ -1,6 +1,9 @@ +//! regression test for //@ check-pass -trait Common { fn dummy(&self) { } } +trait Common { + fn dummy(&self) {} +} impl<'t, T> Common for (T, &'t T) {} diff --git a/tests/ui/ufcs/ufcs-trait-object-format.rs b/tests/ui/ufcs/ufcs-trait-object-format.rs index 2059365c7d62..7d50a2444806 100644 --- a/tests/ui/ufcs/ufcs-trait-object-format.rs +++ b/tests/ui/ufcs/ufcs-trait-object-format.rs @@ -1,8 +1,9 @@ //@ run-pass -// Regression test for #20676. Error was that we didn't support -// UFCS-style calls to a method in `Trait` where `Self` was bound to a -// trait object of type `Trait`. See also `ufcs-trait-object.rs`. - +//! Regression test for . +//! Error was that we didn't support +//! UFCS-style calls to a method in `Trait` where `Self` was bound to a +//! trait object of type `Trait`. +//! See also . use std::fmt; From de505d24db776bf399b9932f673f3f3de8c591a0 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 5 Jan 2026 08:08:02 +0100 Subject: [PATCH 1597/3801] tests/debuginfo/basic-stepping.rs: Don't mix `compile-flags` with `ignore-*` We want directives nice and tidy. --- tests/debuginfo/basic-stepping.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/debuginfo/basic-stepping.rs b/tests/debuginfo/basic-stepping.rs index ffb5d87710dc..72d4e354a6f1 100644 --- a/tests/debuginfo/basic-stepping.rs +++ b/tests/debuginfo/basic-stepping.rs @@ -5,9 +5,11 @@ //@ ignore-aarch64: Doesn't work yet. //@ ignore-loongarch64: Doesn't work yet. //@ ignore-riscv64: Doesn't work yet. -//@ compile-flags: -g //@ ignore-backends: gcc +// Debugger tests need debuginfo +//@ compile-flags: -g + //@ gdb-command: run // FIXME(#97083): Should we be able to break on initialization of zero-sized types? // FIXME(#97083): Right now the first breakable line is: From 622572f6df87a8b374159a8ee95a1195a600754b Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Tue, 7 Oct 2025 06:41:09 +0200 Subject: [PATCH 1598/3801] tests/debuginfo/basic-stepping.rs: Add revisions `default-mir-passes`, `no-SingleUseConsts-mir-pass` To prevent regressions our test must cover the code both inside and outside of the `SingleUseConsts` MIR pass. Use revisions for that. --- tests/debuginfo/basic-stepping.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/debuginfo/basic-stepping.rs b/tests/debuginfo/basic-stepping.rs index 72d4e354a6f1..744f8f5dd654 100644 --- a/tests/debuginfo/basic-stepping.rs +++ b/tests/debuginfo/basic-stepping.rs @@ -10,6 +10,10 @@ // Debugger tests need debuginfo //@ compile-flags: -g +// FIXME(#128945): SingleUseConsts shouldn't need to be disabled. +//@ revisions: default-mir-passes no-SingleUseConsts-mir-pass +//@ [no-SingleUseConsts-mir-pass] compile-flags: -Zmir-enable-passes=-SingleUseConsts + //@ gdb-command: run // FIXME(#97083): Should we be able to break on initialization of zero-sized types? // FIXME(#97083): Right now the first breakable line is: @@ -17,12 +21,12 @@ //@ gdb-command: next //@ gdb-check: let d = c = 99; //@ gdb-command: next -// FIXME(#33013): gdb-check: let e = "hi bob"; -// FIXME(#33013): gdb-command: next -// FIXME(#33013): gdb-check: let f = b"hi bob"; -// FIXME(#33013): gdb-command: next -// FIXME(#33013): gdb-check: let g = b'9'; -// FIXME(#33013): gdb-command: next +//@ [no-SingleUseConsts-mir-pass] gdb-check: let e = "hi bob"; +//@ [no-SingleUseConsts-mir-pass] gdb-command: next +//@ [no-SingleUseConsts-mir-pass] gdb-check: let f = b"hi bob"; +//@ [no-SingleUseConsts-mir-pass] gdb-command: next +//@ [no-SingleUseConsts-mir-pass] gdb-check: let g = b'9'; +//@ [no-SingleUseConsts-mir-pass] gdb-command: next //@ gdb-check: let h = ["whatever"; 8]; //@ gdb-command: next //@ gdb-check: let i = [1,2,3,4]; From c0ecf1ad40a953f01d8ebf5c035eef268cc001f8 Mon Sep 17 00:00:00 2001 From: Till Adam Date: Fri, 2 Jan 2026 21:57:02 +0100 Subject: [PATCH 1599/3801] Implement Span::line() and Span::column() for proc-macro server Add proper line/column resolution for proc-macro spans via a callback mechanism. Previously these methods returned hardcoded 1 values. The implementation adds: - SubRequest::LineColumn and SubResponse::LineColumnResult to the bidirectional protocol - ProcMacroClientInterface::line_column() method - Callback handling in load-cargo using LineIndex - Server implementation in RaSpanServer that uses the callback - a test for Span::line() and Span::column() in proc-macro server Add fn_like_span_line_column test proc-macro that exercises the new line/column API, and a corresponding test with a mock callback. --- src/tools/rust-analyzer/Cargo.lock | 1 + .../crates/load-cargo/src/lib.rs | 42 +++++++++--- .../src/bidirectional_protocol/msg.rs | 18 ++++- .../proc-macro-srv-cli/src/main_loop.rs | 14 ++++ .../crates/proc-macro-srv/Cargo.toml | 1 + .../proc-macro-test/imp/src/lib.rs | 10 +++ .../crates/proc-macro-srv/src/lib.rs | 2 + .../src/server_impl/rust_analyzer_span.rs | 10 ++- .../crates/proc-macro-srv/src/tests/mod.rs | 15 +++++ .../crates/proc-macro-srv/src/tests/utils.rs | 66 ++++++++++++++++++- 10 files changed, 161 insertions(+), 18 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 42eaeb01f1f2..8188fbf96064 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1864,6 +1864,7 @@ dependencies = [ "intern", "libc", "libloading", + "line-index 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "memmap2", "object", "paths", diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index e8d98b1ce661..33468a5003c3 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -554,14 +554,12 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::LocalFilePathResult { name }) } SubRequest::SourceText { file_id, ast_id, start, end } => { - let ast_id = span::ErasedFileAstId::from_raw(ast_id); - let editioned_file_id = span::EditionedFileId::from_raw(file_id); - let span = Span { - range: TextRange::new(TextSize::from(start), TextSize::from(end)), - anchor: SpanAnchor { file_id: editioned_file_id, ast_id }, - ctx: SyntaxContext::root(editioned_file_id.edition()), - }; - let range = db.resolve_span(span); + let range = resolve_sub_span( + db, + file_id, + ast_id, + TextRange::new(TextSize::from(start), TextSize::from(end)), + ); let source = db.file_text(range.file_id.file_id(db)).text(db); let text = source .get(usize::from(range.range.start())..usize::from(range.range.end())) @@ -569,6 +567,18 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::SourceTextResult { text }) } + SubRequest::LineColumn { file_id, ast_id, offset } => { + let range = + resolve_sub_span(db, file_id, ast_id, TextRange::empty(TextSize::from(offset))); + let source = db.file_text(range.file_id.file_id(db)).text(db); + let line_index = ide_db::line_index::LineIndex::new(source); + let (line, column) = line_index + .try_line_col(range.range.start()) + .map(|lc| (lc.line + 1, lc.col + 1)) + .unwrap_or((1, 1)); + // proc_macro::Span line/column are 1-based + Ok(SubResponse::LineColumnResult { line, column }) + } SubRequest::FilePath { file_id } => { let file_id = FileId::from_raw(file_id); let source_root_id = db.file_source_root(file_id).source_root_id(db); @@ -603,6 +613,22 @@ impl ProcMacroExpander for Expander { } } +fn resolve_sub_span( + db: &dyn ExpandDatabase, + file_id: u32, + ast_id: u32, + range: TextRange, +) -> hir_expand::FileRange { + let ast_id = span::ErasedFileAstId::from_raw(ast_id); + let editioned_file_id = span::EditionedFileId::from_raw(file_id); + let span = Span { + range, + anchor: SpanAnchor { file_id: editioned_file_id, ast_id }, + ctx: SyntaxContext::root(editioned_file_id.edition()), + }; + db.resolve_span(span) +} + #[cfg(test)] mod tests { use ide_db::base_db::RootQueryDb; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index e41f8a5d7da7..0e3b700dcc5a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -13,13 +13,25 @@ pub enum SubRequest { FilePath { file_id: u32 }, SourceText { file_id: u32, ast_id: u32, start: u32, end: u32 }, LocalFilePath { file_id: u32 }, + LineColumn { file_id: u32, ast_id: u32, offset: u32 }, } #[derive(Debug, Serialize, Deserialize)] pub enum SubResponse { - FilePathResult { name: String }, - SourceTextResult { text: Option }, - LocalFilePathResult { name: Option }, + FilePathResult { + name: String, + }, + SourceTextResult { + text: Option, + }, + LocalFilePathResult { + name: Option, + }, + /// Line and column are 1-based. + LineColumnResult { + line: u32, + column: u32, + }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index b2f4b96bd255..22536a4e52b1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -220,6 +220,20 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl _ => None, } } + + fn line_column(&mut self, span: proc_macro_srv::span::Span) -> Option<(u32, u32)> { + let proc_macro_srv::span::Span { range, anchor, ctx: _ } = span; + match self.roundtrip(bidirectional::SubRequest::LineColumn { + file_id: anchor.file_id.as_u32(), + ast_id: anchor.ast_id.into_raw(), + offset: range.start().into(), + }) { + Some(bidirectional::BidirectionalMessage::SubResponse( + bidirectional::SubResponse::LineColumnResult { line, column }, + )) => Some((line, column)), + _ => None, + } + } } fn handle_expand_ra( diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml index 361017178409..8e5617f8a20e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml @@ -31,6 +31,7 @@ libc.workspace = true [dev-dependencies] expect-test.workspace = true +line-index.workspace = true # used as proc macro test targets proc-macro-test.path = "./proc-macro-test" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs index b4fac26d6e72..06c76b6d0381 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs @@ -79,6 +79,16 @@ pub fn fn_like_span_ops(args: TokenStream) -> TokenStream { TokenStream::from_iter(vec![first, second, third]) } +/// Returns the line and column of the first token's span as two integer literals. +#[proc_macro] +pub fn fn_like_span_line_column(args: TokenStream) -> TokenStream { + let first = args.into_iter().next().unwrap(); + let span = first.span(); + let line = Literal::usize_unsuffixed(span.line()); + let column = Literal::usize_unsuffixed(span.column()); + TokenStream::from_iter(vec![TokenTree::Literal(line), TokenTree::Literal(column)]) +} + #[proc_macro_attribute] pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream { item diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index f2d1dfbba4cc..c1ef49a7176b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -98,6 +98,8 @@ pub trait ProcMacroClientInterface { fn file(&mut self, file_id: span::FileId) -> String; fn source_text(&mut self, span: Span) -> Option; fn local_file(&mut self, file_id: span::FileId) -> Option; + /// Line and column are 1-based. + fn line_column(&mut self, span: Span) -> Option<(u32, u32)>; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 32725afc5527..3a25391b573b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -257,14 +257,12 @@ impl server::Span for RaSpanServer<'_> { Span { range: TextRange::empty(span.range.start()), ..span } } - fn line(&mut self, _span: Self::Span) -> usize { - // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL - 1 + fn line(&mut self, span: Self::Span) -> usize { + self.callback.as_mut().and_then(|cb| cb.line_column(span)).map_or(1, |(l, _)| l as usize) } - fn column(&mut self, _span: Self::Span) -> usize { - // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL - 1 + fn column(&mut self, span: Self::Span) -> usize { + self.callback.as_mut().and_then(|cb| cb.line_column(span)).map_or(1, |(_, c)| c as usize) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs index 20507a6def54..ebef9a9a519a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs @@ -703,6 +703,7 @@ fn list_test_macros() { fn_like_mk_idents [Bang] fn_like_span_join [Bang] fn_like_span_ops [Bang] + fn_like_span_line_column [Bang] attr_noop [Attr] attr_panic [Attr] attr_error [Attr] @@ -712,3 +713,17 @@ fn list_test_macros() { DeriveError [CustomDerive]"#]] .assert_eq(&res); } + +#[test] +fn test_fn_like_span_line_column() { + assert_expand_with_callback( + "fn_like_span_line_column", + // Input text with known position: "hello" starts at offset 1 (line 2, column 1 in 1-based) + " +hello", + expect![[r#" + LITER 42:Root[0000, 0]@0..100#ROOT2024 Integer 2 + LITER 42:Root[0000, 0]@0..100#ROOT2024 Integer 1 + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs index 61fcd810b1d9..81ff1965d68b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs @@ -6,7 +6,8 @@ use span::{ }; use crate::{ - EnvSnapshot, ProcMacroSrv, SpanId, dylib, proc_macro_test_dylib_path, token_stream::TokenStream, + EnvSnapshot, ProcMacroClientInterface, ProcMacroSrv, SpanId, dylib, proc_macro_test_dylib_path, + token_stream::TokenStream, }; fn parse_string(call_site: SpanId, src: &str) -> TokenStream { @@ -109,3 +110,66 @@ pub(crate) fn list() -> Vec { let res = srv.list_macros(&dylib_path).unwrap(); res.into_iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect() } + +/// A mock callback for testing that computes line/column from the input text. +struct MockCallback<'a> { + text: &'a str, +} + +impl ProcMacroClientInterface for MockCallback<'_> { + fn source_text(&mut self, span: Span) -> Option { + self.text + .get(usize::from(span.range.start())..usize::from(span.range.end())) + .map(ToOwned::to_owned) + } + + fn file(&mut self, _file_id: FileId) -> String { + String::new() + } + + fn local_file(&mut self, _file_id: FileId) -> Option { + None + } + + fn line_column(&mut self, span: Span) -> Option<(u32, u32)> { + let line_index = line_index::LineIndex::new(self.text); + let line_col = line_index.try_line_col(span.range.start())?; + // proc_macro uses 1-based line/column + Some((line_col.line as u32 + 1, line_col.col as u32 + 1)) + } +} + +pub fn assert_expand_with_callback( + macro_name: &str, + #[rust_analyzer::rust_fixture] ra_fixture: &str, + expect_spanned: Expect, +) { + let path = proc_macro_test_dylib_path(); + let expander = dylib::Expander::new(&temp_dir::TempDir::new().unwrap(), &path).unwrap(); + + let def_site = Span { + range: TextRange::new(0.into(), 150.into()), + anchor: SpanAnchor { + file_id: EditionedFileId::current_edition(FileId::from_raw(41)), + ast_id: ROOT_ERASED_FILE_AST_ID, + }, + ctx: SyntaxContext::root(span::Edition::CURRENT), + }; + let call_site = Span { + range: TextRange::new(0.into(), 100.into()), + anchor: SpanAnchor { + file_id: EditionedFileId::current_edition(FileId::from_raw(42)), + ast_id: ROOT_ERASED_FILE_AST_ID, + }, + ctx: SyntaxContext::root(span::Edition::CURRENT), + }; + let mixed_site = call_site; + + let fixture = parse_string_spanned(call_site.anchor, call_site.ctx, ra_fixture); + + let mut callback = MockCallback { text: ra_fixture }; + let res = expander + .expand(macro_name, fixture, None, def_site, call_site, mixed_site, Some(&mut callback)) + .unwrap(); + expect_spanned.assert_eq(&format!("{res:?}")); +} From 38ab51943c5726ce71f5656e8345e0487f94e2ce Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 5 Jan 2026 09:28:05 +0100 Subject: [PATCH 1600/3801] ./x check miri: enable check_only feature --- src/bootstrap/src/core/build_steps/check.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index df82b7baa9f9..7da2551c76fe 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -793,8 +793,7 @@ tool_check_step!(Clippy { path: "src/tools/clippy", mode: Mode::ToolRustcPrivate tool_check_step!(Miri { path: "src/tools/miri", mode: Mode::ToolRustcPrivate, - enable_features: ["stack-cache"], - default_features: false, + enable_features: ["check_only"], }); tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: Mode::ToolRustcPrivate }); tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: Mode::ToolRustcPrivate }); From 0330cc24468ac4a009df902a4313c472448658bf Mon Sep 17 00:00:00 2001 From: Khashayar Fereidani Date: Mon, 5 Jan 2026 13:14:11 +0330 Subject: [PATCH 1601/3801] Add feature flag `likely/unlikely` for alloc --- library/alloc/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index b659e904c8a0..595329c38fc2 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -126,6 +126,7 @@ #![feature(iter_next_chunk)] #![feature(layout_for_ptr)] #![feature(legacy_receiver_trait)] +#![feature(likely_unlikely)] #![feature(local_waker)] #![feature(maybe_uninit_uninit_array_transpose)] #![feature(panic_internals)] From bd79ea1b743cccde61ffda92ba4f41abdfab515c Mon Sep 17 00:00:00 2001 From: Khashayar Fereidani Date: Mon, 5 Jan 2026 13:18:41 +0330 Subject: [PATCH 1602/3801] Improve and optimize retain_mut implementation --- library/alloc/src/vec/mod.rs | 117 +++++++++++++++++------------------ 1 file changed, 56 insertions(+), 61 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index f8a96e358d6d..4e76a34a72c7 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -86,7 +86,7 @@ use core::mem::{self, Assume, ManuallyDrop, MaybeUninit, SizedTypeProperties, Tr use core::ops::{self, Index, IndexMut, Range, RangeBounds}; use core::ptr::{self, NonNull}; use core::slice::{self, SliceIndex}; -use core::{fmt, intrinsics, ub_checks}; +use core::{fmt, hint, intrinsics, ub_checks}; #[stable(feature = "extract_if", since = "1.87.0")] pub use self::extract_if::ExtractIf; @@ -2292,13 +2292,8 @@ impl Vec { return; } - // Avoid double drop if the drop guard is not executed, - // since we may make some holes during the process. - unsafe { self.set_len(0) }; - // Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked] - // |<- processed len ->| ^- next to check - // |<- deleted cnt ->| + // | ^- write ^- read | // |<- original_len ->| // Kept: Elements which predicate returns true on. // Hole: Moved or dropped element slot. @@ -2307,77 +2302,77 @@ impl Vec { // This drop guard will be invoked when predicate or `drop` of element panicked. // It shifts unchecked elements to cover holes and `set_len` to the correct length. // In cases when predicate and `drop` never panick, it will be optimized out. - struct BackshiftOnDrop<'a, T, A: Allocator> { + struct PanicGuard<'a, T, A: Allocator> { v: &'a mut Vec, - processed_len: usize, - deleted_cnt: usize, + read: usize, + write: usize, original_len: usize, } - impl Drop for BackshiftOnDrop<'_, T, A> { + impl Drop for PanicGuard<'_, T, A> { + #[cold] fn drop(&mut self) { - if self.deleted_cnt > 0 { - // SAFETY: Trailing unchecked items must be valid since we never touch them. - unsafe { - ptr::copy( - self.v.as_ptr().add(self.processed_len), - self.v.as_mut_ptr().add(self.processed_len - self.deleted_cnt), - self.original_len - self.processed_len, - ); - } + let remaining = self.original_len - self.read; + // SAFETY: Trailing unchecked items must be valid since we never touch them. + unsafe { + ptr::copy( + self.v.as_ptr().add(self.read), + self.v.as_mut_ptr().add(self.write), + remaining, + ); } // SAFETY: After filling holes, all items are in contiguous memory. unsafe { - self.v.set_len(self.original_len - self.deleted_cnt); + self.v.set_len(self.write + remaining); } } } - let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len }; - - fn process_loop( - original_len: usize, - f: &mut F, - g: &mut BackshiftOnDrop<'_, T, A>, - ) where - F: FnMut(&mut T) -> bool, - { - while g.processed_len != original_len { - // SAFETY: Unchecked element must be valid. - let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.processed_len) }; - if !f(cur) { - // Advance early to avoid double drop if `drop_in_place` panicked. - g.processed_len += 1; - g.deleted_cnt += 1; - // SAFETY: We never touch this element again after dropped. - unsafe { ptr::drop_in_place(cur) }; - // We already advanced the counter. - if DELETED { - continue; - } else { - break; - } - } - if DELETED { - // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element. - // We use copy for move, and never touch this element again. - unsafe { - let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt); - ptr::copy_nonoverlapping(cur, hole_slot, 1); - } - } - g.processed_len += 1; + let mut read = 0; + loop { + // SAFETY: read < original_len + let cur = unsafe { self.get_unchecked_mut(read) }; + if hint::unlikely(!f(cur)) { + break; + } + read += 1; + if read == original_len { + // All elements are kept, return early. + return; } } - // Stage 1: Nothing was deleted. - process_loop::(original_len, &mut f, &mut g); + // Critical section starts here and at least one element is going to be removed. + // Advance `g.read` early to avoid double drop if `drop_in_place` panicked. + let mut g = PanicGuard { v: self, read: read + 1, write: read, original_len }; + // SAFETY: previous `read` is always less than original_len. + unsafe { ptr::drop_in_place(&mut *g.v.as_mut_ptr().add(read)) }; - // Stage 2: Some elements were deleted. - process_loop::(original_len, &mut f, &mut g); + while g.read < g.original_len { + // SAFETY: `read` is always less than original_len. + let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.read) }; + if !f(cur) { + // Advance `read` early to avoid double drop if `drop_in_place` panicked. + g.read += 1; + // SAFETY: We never touch this element again after dropped. + unsafe { ptr::drop_in_place(cur) }; + } else { + // SAFETY: `read` > `write`, so the slots don't overlap. + // We use copy for move, and never touch the source element again. + unsafe { + let hole = g.v.as_mut_ptr().add(g.write); + ptr::copy_nonoverlapping(cur, hole, 1); + } + g.write += 1; + g.read += 1; + } + } - // All item are processed. This can be optimized to `set_len` by LLVM. - drop(g); + // We are leaving the critical section and no panic happened, + // Commit the length change and forget the guard. + // SAFETY: `write` is always less than or equal to original_len. + unsafe { g.v.set_len(g.write) }; + mem::forget(g); } /// Removes all but the first of consecutive elements in the vector that resolve to the same From 75eaa452681e8008a24a7bd2ce8d44bad38d5a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 31 Dec 2025 13:23:13 +0100 Subject: [PATCH 1603/3801] Allow building cg_gcc without building libgccjit --- src/bootstrap/src/core/build_steps/compile.rs | 106 ++++++++---------- 1 file changed, 47 insertions(+), 59 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 762aeea9f451..adfb3c21d38e 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -19,7 +19,7 @@ use serde_derive::Deserialize; #[cfg(feature = "tracing")] use tracing::span; -use crate::core::build_steps::gcc::{Gcc, GccOutput, GccTargetPair, add_cg_gcc_cargo_flags}; +use crate::core::build_steps::gcc::{Gcc, GccOutput, GccTargetPair}; use crate::core::build_steps::tool::{RustcPrivateCompilers, SourceType, copy_lld_artifacts}; use crate::core::build_steps::{dist, llvm}; use crate::core::builder; @@ -1569,21 +1569,29 @@ impl Step for RustcLink { } /// Set of `libgccjit` dylibs that can be used by `cg_gcc` to compile code for a set of targets. +/// `libgccjit` requires a separate build for each `(host, target)` pair. +/// So if you are on linux-x64 and build for linux-aarch64, you will need at least: +/// - linux-x64 -> linux-x64 libgccjit (for building host code like proc macros) +/// - linux-x64 -> linux-aarch64 libgccjit (for the aarch64 target code) #[derive(Clone)] pub struct GccDylibSet { dylibs: BTreeMap, - host_pair: GccTargetPair, } impl GccDylibSet { - /// Returns the libgccjit.so dylib that corresponds to a host target on which `cg_gcc` will be - /// executed, and which will target the host. So e.g. if `cg_gcc` will be executed on - /// x86_64-unknown-linux-gnu, the host dylib will be for compilation pair - /// `(x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu)`. - fn host_dylib(&self) -> &GccOutput { - self.dylibs.get(&self.host_pair).unwrap_or_else(|| { - panic!("libgccjit.so was not built for host target {}", self.host_pair) - }) + /// Build a set of libgccjit dylibs that will be executed on `host` and will generate code for + /// each specified target. + pub fn build( + builder: &Builder<'_>, + host: TargetSelection, + targets: Vec, + ) -> Self { + let dylibs = targets + .iter() + .map(|t| GccTargetPair::for_target_pair(host, *t)) + .map(|target_pair| (target_pair, builder.ensure(Gcc { target_pair }))) + .collect(); + Self { dylibs } } /// Install the libgccjit dylibs to the corresponding target directories of the given compiler. @@ -1626,39 +1634,28 @@ impl GccDylibSet { /// Output of the `compile::GccCodegenBackend` step. /// -/// It contains paths to all built libgccjit libraries on which this backend depends here. +/// It contains a build stamp with the path to the built cg_gcc dylib. #[derive(Clone)] pub struct GccCodegenBackendOutput { stamp: BuildStamp, - dylib_set: GccDylibSet, } /// Builds the GCC codegen backend (`cg_gcc`). -/// The `cg_gcc` backend uses `libgccjit`, which requires a separate build for each -/// `host -> target` pair. So if you are on linux-x64 and build for linux-aarch64, -/// you will need at least: -/// - linux-x64 -> linux-x64 libgccjit (for building host code like proc macros) -/// - linux-x64 -> linux-aarch64 libgccjit (for the aarch64 target code) -/// -/// We model this by having a single cg_gcc for a given host target, which contains one -/// libgccjit per (host, target) pair. -/// Note that the host target is taken from `self.compilers.target_compiler.host`. +/// Note that this **does not** build libgccjit, which is a dependency of cg_gcc. +/// That has to be built separately, because a separate copy of libgccjit is required +/// for each (host, target) compilation pair. +/// cg_gcc goes to great lengths to ensure that it does not *directly* link to libgccjit, +/// so we respect that here and allow building cg_gcc without building libgccjit itself. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct GccCodegenBackend { compilers: RustcPrivateCompilers, - targets: Vec, + target: TargetSelection, } impl GccCodegenBackend { - /// Build `cg_gcc` that will run on host `H` (`compilers.target_compiler.host`) and will be - /// able to produce code target pairs (`H`, `T`) for all `T` from `targets`. - pub fn for_targets( - compilers: RustcPrivateCompilers, - mut targets: Vec, - ) -> Self { - // Sort targets to improve step cache hits - targets.sort(); - Self { compilers, targets } + /// Build `cg_gcc` that will run on the given host target. + pub fn for_target(compilers: RustcPrivateCompilers, target: TargetSelection) -> Self { + Self { compilers, target } } } @@ -1672,10 +1669,8 @@ impl Step for GccCodegenBackend { } fn make_run(run: RunConfig<'_>) { - // By default, build cg_gcc that will only be able to compile native code for the given - // host target. let compilers = RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target); - run.builder.ensure(GccCodegenBackend { compilers, targets: vec![run.target] }); + run.builder.ensure(GccCodegenBackend::for_target(compilers, run.target)); } fn run(self, builder: &Builder<'_>) -> Self::Output { @@ -1689,18 +1684,6 @@ impl Step for GccCodegenBackend { &CodegenBackendKind::Gcc, ); - let dylib_set = GccDylibSet { - dylibs: self - .targets - .iter() - .map(|&target| { - let target_pair = GccTargetPair::for_target_pair(host, target); - (target_pair, builder.ensure(Gcc { target_pair })) - }) - .collect(), - host_pair: GccTargetPair::for_native_build(host), - }; - if builder.config.keep_stage.contains(&build_compiler.stage) { trace!("`keep-stage` requested"); builder.info( @@ -1709,7 +1692,7 @@ impl Step for GccCodegenBackend { ); // Codegen backends are linked separately from this step today, so we don't do // anything here. - return GccCodegenBackendOutput { stamp, dylib_set }; + return GccCodegenBackendOutput { stamp }; } let mut cargo = builder::Cargo::new( @@ -1723,15 +1706,12 @@ impl Step for GccCodegenBackend { cargo.arg("--manifest-path").arg(builder.src.join("compiler/rustc_codegen_gcc/Cargo.toml")); rustc_cargo_env(builder, &mut cargo, host); - add_cg_gcc_cargo_flags(&mut cargo, dylib_set.host_dylib()); - let _guard = builder.msg(Kind::Build, "codegen backend gcc", Mode::Codegen, build_compiler, host); let files = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false); GccCodegenBackendOutput { stamp: write_codegen_backend_stamp(stamp, files, builder.config.dry_run()), - dylib_set, } } @@ -2457,12 +2437,18 @@ impl Step for Assemble { // GCC dylibs built below by taking a look at the current stage and whether // cg_gcc is used as the default codegen backend. + // First, the easy part: build cg_gcc let compilers = prepare_compilers(); + let cg_gcc = builder + .ensure(GccCodegenBackend::for_target(compilers, target_compiler.host)); + copy_codegen_backends_to_sysroot(builder, cg_gcc.stamp, target_compiler); + + // Then, the hard part: prepare all required libgccjit dylibs. // The left side of the target pairs below is implied. It has to match the - // host target on which cg_gcc will run, which is the host target of + // host target on which libgccjit will be used, which is the host target of // `target_compiler`. We only pass the right side of the target pairs to - // the `GccCodegenBackend` constructor. + // the `GccDylibSet` constructor. let mut targets = HashSet::new(); // Add all host targets, so that we are able to build host code in this // bootstrap invocation using cg_gcc. @@ -2477,14 +2463,16 @@ impl Step for Assemble { // host code (e.g. proc macros) using cg_gcc. targets.insert(compilers.target_compiler().host); - let output = builder.ensure(GccCodegenBackend::for_targets( - compilers, + // Now build all the required libgccjit dylibs + let dylib_set = GccDylibSet::build( + builder, + compilers.target_compiler().host, targets.into_iter().collect(), - )); - copy_codegen_backends_to_sysroot(builder, output.stamp, target_compiler); - // Also copy all requires libgccjit dylibs to the corresponding - // library sysroots, so that they are available for the codegen backend. - output.dylib_set.install_to(builder, target_compiler); + ); + + // And then copy all the dylibs to the corresponding + // library sysroots, so that they are available for cg_gcc. + dylib_set.install_to(builder, target_compiler); } CodegenBackendKind::Llvm | CodegenBackendKind::Custom(_) => continue, } From 2b53ecaff4ab1a7c8279ca182c6433f488312b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 31 Dec 2025 13:39:15 +0100 Subject: [PATCH 1604/3801] Add a dist step for the GCC codegen backend --- src/bootstrap/src/core/build_steps/compile.rs | 6 + src/bootstrap/src/core/build_steps/dist.rs | 125 +++++++++++++++--- src/bootstrap/src/core/builder/mod.rs | 1 + src/bootstrap/src/utils/tarball.rs | 7 + src/tools/opt-dist/src/main.rs | 1 + 5 files changed, 123 insertions(+), 17 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index adfb3c21d38e..a42d46a8c018 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1640,6 +1640,12 @@ pub struct GccCodegenBackendOutput { stamp: BuildStamp, } +impl GccCodegenBackendOutput { + pub fn stamp(&self) -> &BuildStamp { + &self.stamp + } +} + /// Builds the GCC codegen backend (`cg_gcc`). /// Note that this **does not** build libgccjit, which is a dependency of cg_gcc. /// That has to be built separately, because a separate copy of libgccjit is required diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 0e7051cc22df..f47b0c0b0072 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1652,23 +1652,7 @@ impl Step for CraneliftCodegenBackend { return None; } - // Get the relative path of where the codegen backend should be stored. - let backends_dst = builder.sysroot_codegen_backends(compilers.target_compiler()); - let backends_rel = backends_dst - .strip_prefix(builder.sysroot(compilers.target_compiler())) - .unwrap() - .strip_prefix(builder.sysroot_libdir_relative(compilers.target_compiler())) - .unwrap(); - // Don't use custom libdir here because ^lib/ will be resolved again with installer - let backends_dst = PathBuf::from("lib").join(backends_rel); - - let codegen_backend_dylib = get_codegen_backend_file(&stamp); - tarball.add_renamed_file( - &codegen_backend_dylib, - &backends_dst, - &normalize_codegen_backend_name(builder, &codegen_backend_dylib), - FileType::NativeLibrary, - ); + add_codegen_backend_to_tarball(builder, &tarball, compilers.target_compiler(), &stamp); Some(tarball.generate()) } @@ -1681,6 +1665,113 @@ impl Step for CraneliftCodegenBackend { } } +/// Builds a dist component containing the GCC codegen backend. +/// Note that for this backend to work, it must have a set of libgccjit dylibs available +/// at runtime. +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct GccCodegenBackend { + pub compilers: RustcPrivateCompilers, + pub target: TargetSelection, +} + +impl Step for GccCodegenBackend { + type Output = Option; + const IS_HOST: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("rustc_codegen_gcc") + } + + fn is_default_step(builder: &Builder<'_>) -> bool { + // We only want to build the gcc backend in `x dist` if the backend was enabled + // in rust.codegen-backends. + // Sadly, we don't have access to the actual target for which we're disting clif here.. + // So we just use the host target. + builder + .config + .enabled_codegen_backends(builder.host_target) + .contains(&CodegenBackendKind::Gcc) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(GccCodegenBackend { + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), + target: run.target, + }); + } + + fn run(self, builder: &Builder<'_>) -> Option { + // This prevents rustc_codegen_gcc from being built for "dist" + // or "install" on the stable/beta channels. It is not yet stable and + // should not be included. + if !builder.build.unstable_features() { + return None; + } + + let target = self.target; + if target != "x86_64-unknown-linux-gnu" { + builder + .info(&format!("target `{target}` not supported by rustc_codegen_gcc. skipping")); + return None; + } + + let mut tarball = Tarball::new(builder, "rustc-codegen-gcc", &target.triple); + tarball.set_overlay(OverlayKind::RustcCodegenGcc); + tarball.is_preview(true); + tarball.add_legal_and_readme_to("share/doc/rustc_codegen_gcc"); + + let compilers = self.compilers; + let backend = builder.ensure(compile::GccCodegenBackend::for_target(compilers, target)); + + if builder.config.dry_run() { + return None; + } + + add_codegen_backend_to_tarball( + builder, + &tarball, + compilers.target_compiler(), + backend.stamp(), + ); + + Some(tarball.generate()) + } + + fn metadata(&self) -> Option { + Some( + StepMetadata::dist("rustc_codegen_gcc", self.target) + .built_by(self.compilers.build_compiler()), + ) + } +} + +/// Add a codegen backend built for `compiler`, with its artifacts stored in `stamp`, to the given +/// `tarball` at the correct place. +fn add_codegen_backend_to_tarball( + builder: &Builder<'_>, + tarball: &Tarball<'_>, + compiler: Compiler, + stamp: &BuildStamp, +) { + // Get the relative path of where the codegen backend should be stored. + let backends_dst = builder.sysroot_codegen_backends(compiler); + let backends_rel = backends_dst + .strip_prefix(builder.sysroot(compiler)) + .unwrap() + .strip_prefix(builder.sysroot_libdir_relative(compiler)) + .unwrap(); + // Don't use custom libdir here because ^lib/ will be resolved again with installer + let backends_dst = PathBuf::from("lib").join(backends_rel); + + let codegen_backend_dylib = get_codegen_backend_file(stamp); + tarball.add_renamed_file( + &codegen_backend_dylib, + &backends_dst, + &normalize_codegen_backend_name(builder, &codegen_backend_dylib), + FileType::NativeLibrary, + ); +} + #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Rustfmt { pub compilers: RustcPrivateCompilers, diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 92a6eb8ce837..0164cc5310c2 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -967,6 +967,7 @@ impl<'a> Builder<'a> { dist::Mingw, dist::Rustc, dist::CraneliftCodegenBackend, + dist::GccCodegenBackend, dist::Std, dist::RustcDev, dist::Analysis, diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 079afb7a0054..7db06dcc3e9a 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -25,6 +25,7 @@ pub(crate) enum OverlayKind { Rustfmt, RustAnalyzer, RustcCodegenCranelift, + RustcCodegenGcc, LlvmBitcodeLinker, } @@ -66,6 +67,11 @@ impl OverlayKind { "compiler/rustc_codegen_cranelift/LICENSE-APACHE", "compiler/rustc_codegen_cranelift/LICENSE-MIT", ], + OverlayKind::RustcCodegenGcc => &[ + "compiler/rustc_codegen_gcc/Readme.md", + "compiler/rustc_codegen_gcc/LICENSE-APACHE", + "compiler/rustc_codegen_gcc/LICENSE-MIT", + ], OverlayKind::LlvmBitcodeLinker => &[ "COPYRIGHT", "LICENSE-APACHE", @@ -93,6 +99,7 @@ impl OverlayKind { .rust_analyzer_info .version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")), OverlayKind::RustcCodegenCranelift => builder.rust_version(), + OverlayKind::RustcCodegenGcc => builder.rust_version(), OverlayKind::LlvmBitcodeLinker => builder.rust_version(), } } diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 5515dbf1940e..b17cfb567e5b 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -456,6 +456,7 @@ fn main() -> anyhow::Result<()> { "rustfmt", "generate-copyright", "bootstrap", + "rustc_codegen_gcc", ] { build_args.extend(["--skip".to_string(), target.to_string()]); } From 9b789f0bd05477690eaf01dc8698f34678652f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 31 Dec 2025 13:39:23 +0100 Subject: [PATCH 1605/3801] Dist cg_gcc on CI --- src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh index 9579e0d79cb0..f77a0d562f03 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh @@ -7,7 +7,9 @@ python3 ../x.py build --set rust.debug=true opt-dist ./build/$HOSTS/stage1-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \ --host $HOSTS --target $HOSTS \ --include-default-paths \ - build-manifest bootstrap + build-manifest \ + bootstrap \ + rustc_codegen_gcc # Use GCC for building GCC components, as it seems to behave badly when built with Clang # Only build GCC on full builds, not try builds From 04707f4f86ea0b484da9c368dcb81fdfb7939bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 2 Jan 2026 10:05:30 +0100 Subject: [PATCH 1606/3801] Only keep old cg_gcc if the stamp file actually exists --- src/bootstrap/src/core/build_steps/compile.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index a42d46a8c018..02be3f2cc735 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1690,7 +1690,7 @@ impl Step for GccCodegenBackend { &CodegenBackendKind::Gcc, ); - if builder.config.keep_stage.contains(&build_compiler.stage) { + if builder.config.keep_stage.contains(&build_compiler.stage) && stamp.path().exists() { trace!("`keep-stage` requested"); builder.info( "WARNING: Using a potentially old codegen backend. \ From 4fbc52085fda746d8128a79b878a5008e94a81fe Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 5 Jan 2026 11:30:51 +0100 Subject: [PATCH 1607/3801] perf: Re-use scratch allocations for `try_evaluate_obligations` --- .../crates/hir-ty/src/next_solver/fulfill.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs index 0fe073297279..a8bff44a0258 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/fulfill.rs @@ -48,6 +48,7 @@ pub struct FulfillmentCtxt<'db> { /// use the context in exactly this snapshot. #[expect(unused)] usable_in_snapshot: usize, + try_evaluate_obligations_scratch: PendingObligations<'db>, } #[derive(Default, Debug, Clone)] @@ -115,6 +116,7 @@ impl<'db> FulfillmentCtxt<'db> { FulfillmentCtxt { obligations: Default::default(), usable_in_snapshot: infcx.num_open_snapshots(), + try_evaluate_obligations_scratch: Default::default(), } } } @@ -162,12 +164,12 @@ impl<'db> FulfillmentCtxt<'db> { // and select. They should use a different `ObligationCtxt` instead. Then we'll be also able // to not put the obligations queue in `InferenceTable`'s snapshots. // assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); + self.try_evaluate_obligations_scratch.clear(); let mut errors = Vec::new(); - let mut obligations = Vec::new(); loop { let mut any_changed = false; - obligations.extend(self.obligations.drain_pending(|_| true)); - for (mut obligation, stalled_on) in obligations.drain(..) { + self.try_evaluate_obligations_scratch.extend(self.obligations.drain_pending(|_| true)); + for (mut obligation, stalled_on) in self.try_evaluate_obligations_scratch.drain(..) { if obligation.recursion_depth >= infcx.interner.recursion_limit() { self.obligations.on_fulfillment_overflow(infcx); // Only return true errors that we have accumulated while processing. From 304101f21241f8ba3692b5c917e23252a37709b0 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 4 Jan 2026 18:39:59 +1100 Subject: [PATCH 1608/3801] Move all `thir::Pat` creation into `rustc_mir_build::thir::pattern` --- compiler/rustc_mir_build/src/thir/cx/block.rs | 24 +------------- compiler/rustc_mir_build/src/thir/cx/mod.rs | 22 +++++++++---- .../rustc_mir_build/src/thir/pattern/mod.rs | 32 +++++++++++++++++-- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 57ddb8eddb8e..7cdd70a7fc27 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -2,8 +2,6 @@ use rustc_hir as hir; use rustc_index::Idx; use rustc_middle::middle::region; use rustc_middle::thir::*; -use rustc_middle::ty; -use rustc_middle::ty::CanonicalUserTypeAnnotation; use tracing::debug; use crate::thir::cx::ThirBuildCx; @@ -73,29 +71,9 @@ impl<'tcx> ThirBuildCx<'tcx> { let else_block = local.els.map(|els| self.mirror_block(els)); - let mut pattern = self.pattern_from_hir(local.pat); + let pattern = self.pattern_from_hir_with_annotation(local.pat, local.ty); debug!(?pattern); - if let Some(ty) = &local.ty - && let Some(&user_ty) = - self.typeck_results.user_provided_types().get(ty.hir_id) - { - debug!("mirror_stmts: user_ty={:?}", user_ty); - let annotation = CanonicalUserTypeAnnotation { - user_ty: Box::new(user_ty), - span: ty.span, - inferred_ty: self.typeck_results.node_type(ty.hir_id), - }; - pattern = Box::new(Pat { - ty: pattern.ty, - span: pattern.span, - kind: PatKind::AscribeUserType { - ascription: Ascription { annotation, variance: ty::Covariant }, - subpattern: pattern, - }, - }); - } - let span = match local.init { Some(init) => local.span.with_hi(init.span.hi()), None => local.span, diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index d26dfac0c2ab..79e85a243f40 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -12,9 +12,6 @@ use rustc_hir::{self as hir, HirId, find_attr}; use rustc_middle::bug; use rustc_middle::thir::*; use rustc_middle::ty::{self, TyCtxt}; -use tracing::instrument; - -use crate::thir::pattern::pat_from_hir; /// Query implementation for [`TyCtxt::thir_body`]. pub(crate) fn thir_body( @@ -111,9 +108,22 @@ impl<'tcx> ThirBuildCx<'tcx> { } } - #[instrument(level = "debug", skip(self))] - fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box> { - pat_from_hir(self.tcx, self.typing_env, self.typeck_results, p) + fn pattern_from_hir(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box> { + self.pattern_from_hir_with_annotation(pat, None) + } + + fn pattern_from_hir_with_annotation( + &mut self, + pat: &'tcx hir::Pat<'tcx>, + let_stmt_type: Option<&hir::Ty<'tcx>>, + ) -> Box> { + crate::thir::pattern::pat_from_hir( + self.tcx, + self.typing_env, + self.typeck_results, + pat, + let_stmt_type, + ) } fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option> { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 0310003e7d58..76890316ba44 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -38,11 +38,14 @@ struct PatCtxt<'tcx> { rust_2024_migration: Option>, } +#[instrument(level = "debug", skip(tcx, typing_env, typeck_results), ret)] pub(super) fn pat_from_hir<'tcx>( tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, typeck_results: &'tcx ty::TypeckResults<'tcx>, pat: &'tcx hir::Pat<'tcx>, + // Present if `pat` came from a let statement with an explicit type annotation + let_stmt_type: Option<&hir::Ty<'tcx>>, ) -> Box> { let mut pcx = PatCtxt { tcx, @@ -53,12 +56,35 @@ pub(super) fn pat_from_hir<'tcx>( .get(pat.hir_id) .map(PatMigration::new), }; - let result = pcx.lower_pattern(pat); - debug!("pat_from_hir({:?}) = {:?}", pat, result); + + let mut thir_pat = pcx.lower_pattern(pat); + + // If this pattern came from a let statement with an explicit type annotation + // (e.g. `let x: Foo = ...`), retain that user type information in the THIR pattern. + if let Some(let_stmt_type) = let_stmt_type + && let Some(&user_ty) = typeck_results.user_provided_types().get(let_stmt_type.hir_id) + { + debug!(?user_ty); + let annotation = CanonicalUserTypeAnnotation { + user_ty: Box::new(user_ty), + span: let_stmt_type.span, + inferred_ty: typeck_results.node_type(let_stmt_type.hir_id), + }; + thir_pat = Box::new(Pat { + ty: thir_pat.ty, + span: thir_pat.span, + kind: PatKind::AscribeUserType { + ascription: Ascription { annotation, variance: ty::Covariant }, + subpattern: thir_pat, + }, + }); + } + if let Some(m) = pcx.rust_2024_migration { m.emit(tcx, pat.hir_id); } - result + + thir_pat } impl<'tcx> PatCtxt<'tcx> { From 3d6a2c5ae1685cda3a1ec8357a21fc7f76c7c6be Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Mon, 5 Jan 2026 12:05:23 +0000 Subject: [PATCH 1609/3801] relate.rs: tiny cleanup: eliminate temp vars 2 --- compiler/rustc_type_ir/src/relate.rs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 9e14bf6b60ad..3610605462ba 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -216,11 +216,7 @@ impl Relate for ty::AliasTy { b: ty::AliasTy, ) -> RelateResult> { if a.def_id != b.def_id { - Err(TypeError::ProjectionMismatched({ - let a = a.def_id; - let b = b.def_id; - ExpectedFound::new(a, b) - })) + Err(TypeError::ProjectionMismatched(ExpectedFound::new(a.def_id, b.def_id))) } else { let cx = relation.cx(); let args = if let Some(variances) = cx.opt_alias_variances(a.kind(cx), a.def_id) { @@ -240,11 +236,7 @@ impl Relate for ty::AliasTerm { b: ty::AliasTerm, ) -> RelateResult> { if a.def_id != b.def_id { - Err(TypeError::ProjectionMismatched({ - let a = a.def_id; - let b = b.def_id; - ExpectedFound::new(a, b) - })) + Err(TypeError::ProjectionMismatched(ExpectedFound::new(a.def_id, b.def_id))) } else { let args = match a.kind(relation.cx()) { ty::AliasTermKind::OpaqueTy => relate_args_with_variances( @@ -275,11 +267,7 @@ impl Relate for ty::ExistentialProjection { b: ty::ExistentialProjection, ) -> RelateResult> { if a.def_id != b.def_id { - Err(TypeError::ProjectionMismatched({ - let a = a.def_id; - let b = b.def_id; - ExpectedFound::new(a, b) - })) + Err(TypeError::ProjectionMismatched(ExpectedFound::new(a.def_id, b.def_id))) } else { let term = relation.relate_with_variance( ty::Invariant, From a956b56d6db0f9ad54b555b8ef52539c0c6b3bc2 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Mon, 5 Jan 2026 14:10:50 +0100 Subject: [PATCH 1610/3801] Improve comment clarity in candidate_may_shadow --- compiler/rustc_hir_typeck/src/method/probe.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 1a25f6a582f2..beb0337d8c59 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -190,8 +190,8 @@ impl PickConstraintsForShadowed { // An item never shadows itself candidate.item.def_id != self.def_id // and we're only concerned about inherent impls doing the shadowing. - // Shadowing can only occur if the shadowed is further along - // the Receiver dereferencing chain than the shadowed. + // Shadowing can only occur if the impl being shadowed is further along + // the Receiver dereferencing chain than the impl doing the shadowing. && match candidate.kind { CandidateKind::InherentImplCandidate { receiver_steps, .. } => match self.receiver_steps { Some(shadowed_receiver_steps) => receiver_steps > shadowed_receiver_steps, From c5f67830c2a1395da5589a87e84facbcfe30ea54 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 19 Dec 2025 10:27:38 -0800 Subject: [PATCH 1611/3801] Convert Windows to use check_shim_sig instead of check_shim_sig_lenient --- src/tools/miri/src/shims/sig.rs | 11 +- .../miri/src/shims/windows/foreign_items.rs | 605 ++++++++++++++---- src/tools/miri/tests/pass-dep/getrandom.rs | 2 + src/tools/miri/tests/pass/tls/windows-tls.rs | 8 +- 4 files changed, 497 insertions(+), 129 deletions(-) diff --git a/src/tools/miri/src/shims/sig.rs b/src/tools/miri/src/shims/sig.rs index bc5e7f584f50..a49689d11fd7 100644 --- a/src/tools/miri/src/shims/sig.rs +++ b/src/tools/miri/src/shims/sig.rs @@ -17,11 +17,14 @@ pub struct ShimSig<'tcx, const ARGS: usize> { /// Construct a `ShimSig` with convenient syntax: /// ```rust,ignore -/// shim_sig!(this, extern "C" fn (*const T, i32) -> usize) +/// shim_sig!(extern "C" fn (*const T, i32) -> usize) /// ``` +/// +/// In type position, `winapi::` can be used as a shorthand for the full path used by +/// `windows_ty_layout`. #[macro_export] macro_rules! shim_sig { - (extern $abi:literal fn($($arg:ty),*) -> $ret:ty) => { + (extern $abi:literal fn($($arg:ty),* $(,)?) -> $ret:ty) => { |this| $crate::shims::sig::ShimSig { abi: std::str::FromStr::from_str($abi).expect("incorrect abi specified"), args: [$(shim_sig_arg!(this, $arg)),*], @@ -53,7 +56,9 @@ macro_rules! shim_sig_arg { "*const _" => $this.machine.layouts.const_raw_ptr.ty, "*mut _" => $this.machine.layouts.mut_raw_ptr.ty, ty if let Some(libc_ty) = ty.strip_prefix("libc::") => $this.libc_ty_layout(libc_ty).ty, - ty => panic!("unsupported signature type {ty:?}"), + ty if let Some(win_ty) = ty.strip_prefix("winapi::") => + $this.windows_ty_layout(win_ty).ty, + ty => helpers::path_ty_layout($this, &ty.split("::").collect::>()).ty, } }}; } diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 3bc52dddfe8b..1905fb22e26a 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -2,11 +2,11 @@ use std::ffi::OsStr; use std::path::{self, Path, PathBuf}; use std::{io, iter, str}; -use rustc_abi::{Align, CanonAbi, Size, X86Call}; +use rustc_abi::{Align, Size}; use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use rustc_target::spec::{Arch, Env}; +use rustc_target::spec::Env; use self::shims::windows::handle::{Handle, PseudoHandle}; use crate::shims::os_str::bytes_to_os_str; @@ -137,65 +137,93 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, EmulateItemResult> { let this = self.eval_context_mut(); - // According to - // https://github.com/rust-lang/rust/blob/fb00adbdb69266f10df95a4527b767b0ad35ea48/compiler/rustc_target/src/spec/mod.rs#L2766-L2768, - // x86-32 Windows uses a different calling convention than other Windows targets - // for the "system" ABI. - let sys_conv = if this.tcx.sess.target.arch == Arch::X86 { - CanonAbi::X86(X86Call::Stdcall) - } else { - CanonAbi::C - }; - // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern. // Windows API stubs. - // HANDLE = isize - // NTSTATUS = LONH = i32 + // HANDLE = *mut c_void (formerly: isize) + // NTSTATUS = LONG = i32 // DWORD = ULONG = u32 // BOOL = i32 // BOOLEAN = u8 match link_name.as_str() { // Environment related shims "GetEnvironmentVariableW" => { - let [name, buf, size] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [name, buf, size] = this.check_shim_sig( + shim_sig!(extern "system" fn(*const _, *mut _, u32) -> u32), + link_name, + abi, + args, + )?; let result = this.GetEnvironmentVariableW(name, buf, size)?; this.write_scalar(result, dest)?; } "SetEnvironmentVariableW" => { - let [name, value] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [name, value] = this.check_shim_sig( + shim_sig!(extern "system" fn(*const _, *const _) -> winapi::BOOL), + link_name, + abi, + args, + )?; let result = this.SetEnvironmentVariableW(name, value)?; this.write_scalar(result, dest)?; } "GetEnvironmentStringsW" => { - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> *mut _), + link_name, + abi, + args, + )?; let result = this.GetEnvironmentStringsW()?; this.write_pointer(result, dest)?; } "FreeEnvironmentStringsW" => { - let [env_block] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [env_block] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; let result = this.FreeEnvironmentStringsW(env_block)?; this.write_scalar(result, dest)?; } "GetCurrentDirectoryW" => { - let [size, buf] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [size, buf] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32, *mut _) -> u32), + link_name, + abi, + args, + )?; let result = this.GetCurrentDirectoryW(size, buf)?; this.write_scalar(result, dest)?; } "SetCurrentDirectoryW" => { - let [path] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [path] = this.check_shim_sig( + shim_sig!(extern "system" fn(*const _) -> winapi::BOOL), + link_name, + abi, + args, + )?; let result = this.SetCurrentDirectoryW(path)?; this.write_scalar(result, dest)?; } "GetUserProfileDirectoryW" => { - let [token, buf, size] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [token, buf, size] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, *mut _, *mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; let result = this.GetUserProfileDirectoryW(token, buf, size)?; this.write_scalar(result, dest)?; } "GetCurrentProcessId" => { - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> u32), + link_name, + abi, + args, + )?; let result = this.GetCurrentProcessId()?; this.write_scalar(result, dest)?; } @@ -212,7 +240,24 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { n, byte_offset, key, - ] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + ] = this.check_shim_sig( + shim_sig!( + extern "system" fn( + winapi::HANDLE, + winapi::HANDLE, + *mut _, + *mut _, + *mut _, + *mut _, + u32, + *mut _, + *mut _, + ) -> i32 + ), + link_name, + abi, + args, + )?; this.NtWriteFile( handle, event, @@ -237,7 +282,24 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { n, byte_offset, key, - ] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + ] = this.check_shim_sig( + shim_sig!( + extern "system" fn( + winapi::HANDLE, + winapi::HANDLE, + *mut _, + *mut _, + *mut _, + *mut _, + u32, + *mut _, + *mut _, + ) -> i32 + ), + link_name, + abi, + args, + )?; this.NtReadFile( handle, event, @@ -252,8 +314,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "GetFullPathNameW" => { - let [filename, size, buffer, filepart] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [filename, size, buffer, filepart] = this.check_shim_sig( + shim_sig!(extern "system" fn(*const _, u32, *mut _, *mut _) -> u32), + link_name, + abi, + args, + )?; this.check_no_isolation("`GetFullPathNameW`")?; let filename = this.read_pointer(filename)?; @@ -290,7 +356,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { creation_disposition, flags_and_attributes, template_file, - ] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + ] = this.check_shim_sig( + shim_sig!( + extern "system" fn( + *const _, + u32, + u32, + *mut _, + u32, + u32, + winapi::HANDLE, + ) -> winapi::HANDLE + ), + link_name, + abi, + args, + )?; let handle = this.CreateFileW( file_name, desired_access, @@ -303,29 +384,60 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(handle.to_scalar(this), dest)?; } "GetFileInformationByHandle" => { - let [handle, info] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle, info] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, *mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; let res = this.GetFileInformationByHandle(handle, info)?; this.write_scalar(res, dest)?; } "SetFileInformationByHandle" => { - let [handle, class, info, size] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle, class, info, size] = this.check_shim_sig( + shim_sig!( + extern "system" fn( + winapi::HANDLE, + winapi::FILE_INFO_BY_HANDLE_CLASS, + *mut _, + u32, + ) -> winapi::BOOL + ), + link_name, + abi, + args, + )?; let res = this.SetFileInformationByHandle(handle, class, info, size)?; this.write_scalar(res, dest)?; } "FlushFileBuffers" => { - let [handle] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE) -> winapi::BOOL), + link_name, + abi, + args, + )?; let res = this.FlushFileBuffers(handle)?; this.write_scalar(res, dest)?; } "DeleteFileW" => { - let [file_name] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [file_name] = this.check_shim_sig( + shim_sig!(extern "system" fn(*const _) -> winapi::BOOL), + link_name, + abi, + args, + )?; let res = this.DeleteFileW(file_name)?; this.write_scalar(res, dest)?; } "SetFilePointerEx" => { - let [file, distance_to_move, new_file_pointer, move_method] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + 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, *mut _, u32) -> winapi::BOOL), + link_name, + abi, + args, + )?; let res = this.SetFilePointerEx(file, distance_to_move, new_file_pointer, move_method)?; this.write_scalar(res, dest)?; @@ -333,8 +445,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Allocation "HeapAlloc" => { - let [handle, flags, size] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle, flags, size] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, u32, usize) -> *mut _), + link_name, + abi, + args, + )?; this.read_target_isize(handle)?; let flags = this.read_scalar(flags)?.to_u32()?; let size = this.read_target_usize(size)?; @@ -356,8 +472,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr, dest)?; } "HeapFree" => { - let [handle, flags, ptr] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle, flags, ptr] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, u32, *mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let ptr = this.read_pointer(ptr)?; @@ -369,8 +489,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_i32(1), dest)?; } "HeapReAlloc" => { - let [handle, flags, old_ptr, size] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle, flags, old_ptr, size] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, u32, *mut _, usize) -> *mut _), + link_name, + abi, + args, + )?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let old_ptr = this.read_pointer(old_ptr)?; @@ -390,7 +514,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(new_ptr, dest)?; } "LocalFree" => { - let [ptr] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [ptr] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HLOCAL) -> winapi::HLOCAL), + link_name, + abi, + args, + )?; let ptr = this.read_pointer(ptr)?; // "If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL." // (https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localfree) @@ -402,17 +531,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // errno "SetLastError" => { - let [error] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [error] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32) -> ()), + link_name, + abi, + args, + )?; let error = this.read_scalar(error)?; this.set_last_error(error)?; } "GetLastError" => { - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> u32), + link_name, + abi, + args, + )?; let last_error = this.get_last_error()?; this.write_scalar(last_error, dest)?; } "RtlNtStatusToDosError" => { - let [status] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [status] = this.check_shim_sig( + shim_sig!(extern "system" fn(i32) -> u32), + link_name, + abi, + args, + )?; let status = this.read_scalar(status)?.to_u32()?; let err = match status { // STATUS_MEDIA_WRITE_PROTECTED => ERROR_WRITE_PROTECT @@ -434,7 +578,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "GetSystemInfo" => { // Also called from `page_size` crate. - let [system_info] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [system_info] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _) -> ()), + link_name, + abi, + args, + )?; let system_info = this.deref_pointer_as(system_info, this.windows_ty_layout("SYSTEM_INFO"))?; // Initialize with `0`. @@ -457,19 +606,34 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This just creates a key; Windows does not natively support TLS destructors. // Create key and return it. - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> u32), + 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)?; } "TlsGetValue" => { - let [key] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [key] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32) -> *mut _), + link_name, + abi, + args, + )?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let ptr = this.machine.tls.load_tls(key, active_thread, this)?; this.write_scalar(ptr, dest)?; } "TlsSetValue" => { - let [key, new_ptr] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [key, new_ptr] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32, *mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let new_data = this.read_scalar(new_ptr)?; @@ -479,7 +643,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_int(1, dest)?; } "TlsFree" => { - let [key] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [key] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32) -> winapi::BOOL), + link_name, + abi, + args, + )?; let key = u128::from(this.read_scalar(key)?.to_u32()?); this.machine.tls.delete_tls_key(key)?; @@ -489,7 +658,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Access to command-line arguments "GetCommandLineW" => { - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> *mut _), + link_name, + abi, + args, + )?; this.write_pointer( this.machine.cmd_line.expect("machine must be initialized"), dest, @@ -498,31 +672,51 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Time related shims "GetSystemTimeAsFileTime" | "GetSystemTimePreciseAsFileTime" => { - #[allow(non_snake_case)] - let [LPFILETIME] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; - this.GetSystemTimeAsFileTime(link_name.as_str(), LPFILETIME)?; + let [filetime] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _) -> ()), + link_name, + abi, + args, + )?; + this.GetSystemTimeAsFileTime(link_name.as_str(), filetime)?; } "QueryPerformanceCounter" => { - #[allow(non_snake_case)] - let [lpPerformanceCount] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; - let result = this.QueryPerformanceCounter(lpPerformanceCount)?; + let [performance_count] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; + let result = this.QueryPerformanceCounter(performance_count)?; this.write_scalar(result, dest)?; } "QueryPerformanceFrequency" => { - #[allow(non_snake_case)] - let [lpFrequency] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; - let result = this.QueryPerformanceFrequency(lpFrequency)?; + let [frequency] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; + let result = this.QueryPerformanceFrequency(frequency)?; this.write_scalar(result, dest)?; } "Sleep" => { - let [timeout] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [timeout] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32) -> ()), + link_name, + abi, + args, + )?; this.Sleep(timeout)?; } "CreateWaitableTimerExW" => { - let [attributes, name, flags, access] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [attributes, name, flags, access] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _, *const _, u32, u32) -> winapi::HANDLE), + link_name, + abi, + args, + )?; this.read_pointer(attributes)?; this.read_pointer(name)?; this.read_scalar(flags)?.to_u32()?; @@ -535,40 +729,66 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Synchronization primitives "InitOnceBeginInitialize" => { - let [ptr, flags, pending, context] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [ptr, flags, pending, context] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _, u32, *mut _, *mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; this.InitOnceBeginInitialize(ptr, flags, pending, context, dest)?; } "InitOnceComplete" => { - let [ptr, flags, context] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [ptr, flags, context] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _, u32, *mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; let result = this.InitOnceComplete(ptr, flags, context)?; this.write_scalar(result, dest)?; } "WaitOnAddress" => { - let [ptr_op, compare_op, size_op, timeout_op] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [ptr_op, compare_op, size_op, timeout_op] = this.check_shim_sig( + // First pointer is volatile + shim_sig!(extern "system" fn(*mut _, *mut _, usize, u32) -> winapi::BOOL), + link_name, + abi, + args, + )?; this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?; } "WakeByAddressSingle" => { - let [ptr_op] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [ptr_op] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _) -> ()), + link_name, + abi, + args, + )?; this.WakeByAddressSingle(ptr_op)?; } "WakeByAddressAll" => { - let [ptr_op] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [ptr_op] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _) -> ()), + link_name, + abi, + args, + )?; this.WakeByAddressAll(ptr_op)?; } // Dynamic symbol loading "GetProcAddress" => { - #[allow(non_snake_case)] - let [hModule, lpProcName] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; - this.read_target_isize(hModule)?; - let name = this.read_c_str(this.read_pointer(lpProcName)?)?; + let [module, proc_name] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HMODULE, *const _) -> winapi::FARPROC), + link_name, + abi, + args, + )?; + this.read_target_isize(module)?; + let name = this.read_c_str(this.read_pointer(proc_name)?)?; if let Ok(name) = str::from_utf8(name) && is_dyn_sym(name) { @@ -581,8 +801,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "CreateThread" => { - let [security, stacksize, start, arg, flags, thread] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [security, stacksize, start, arg, flags, thread] = this.check_shim_sig( + shim_sig!( + extern "system" fn( + *mut _, + usize, + *mut _, + *mut _, + u32, + *mut _, + ) -> winapi::HANDLE + ), + link_name, + abi, + args, + )?; let thread_id = this.CreateThread(security, stacksize, start, arg, flags, thread)?; @@ -590,13 +823,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Handle::Thread(thread_id).to_scalar(this), dest)?; } "WaitForSingleObject" => { - let [handle, timeout] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle, timeout] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, u32) -> u32), + link_name, + abi, + args, + )?; this.WaitForSingleObject(handle, timeout, dest)?; } "GetCurrentProcess" => { - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> winapi::HANDLE), + link_name, + abi, + args, + )?; this.write_scalar( Handle::Pseudo(PseudoHandle::CurrentProcess).to_scalar(this), @@ -604,7 +846,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "GetCurrentThread" => { - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> winapi::HANDLE), + link_name, + abi, + args, + )?; this.write_scalar( Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this), @@ -612,7 +859,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "SetThreadDescription" => { - let [handle, name] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle, name] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, *const _) -> i32), + link_name, + abi, + args, + )?; let handle = this.read_handle(handle, "SetThreadDescription")?; let name = this.read_wide_str(this.read_pointer(name)?)?; @@ -627,8 +879,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_u32(0), dest)?; } "GetThreadDescription" => { - let [handle, name_ptr] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle, name_ptr] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, *mut _) -> i32), + link_name, + abi, + args, + )?; let handle = this.read_handle(handle, "GetThreadDescription")?; let name_ptr = this.deref_pointer_as(name_ptr, this.machine.layouts.mut_raw_ptr)?; // the pointer where we should store the ptr to the name @@ -651,7 +907,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "GetThreadId" => { - let [handle] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE) -> u32), + link_name, + abi, + args, + )?; let handle = this.read_handle(handle, "GetThreadId")?; let thread = match handle { Handle::Thread(thread) => thread, @@ -662,7 +923,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_u32(tid), dest)?; } "GetCurrentThreadId" => { - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> u32), + link_name, + abi, + args, + )?; let thread = this.active_thread(); let tid = this.get_tid(thread); this.write_scalar(Scalar::from_u32(tid), dest)?; @@ -670,7 +936,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "ExitProcess" => { - let [code] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [code] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32) -> ()), + 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()?; throw_machine_stop!(TerminationInfo::Exit { code, leak_check: false }); @@ -678,7 +949,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "SystemFunction036" => { // used by getrandom 0.1 // This is really 'RtlGenRandom'. - let [ptr, len] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [ptr, len] = this.check_shim_sig( + // Returns winapi::BOOLEAN, which is a byte + shim_sig!(extern "system" fn(*mut _, u32) -> u8), + link_name, + abi, + args, + )?; let ptr = this.read_pointer(ptr)?; let len = this.read_scalar(len)?.to_u32()?; this.gen_random(ptr, len.into())?; @@ -686,7 +963,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "ProcessPrng" => { // used by `std` - let [ptr, len] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [ptr, len] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _, usize) -> winapi::BOOL), + link_name, + abi, + args, + )?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; @@ -694,8 +976,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "BCryptGenRandom" => { // used by getrandom 0.2 - let [algorithm, ptr, len, flags] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [algorithm, ptr, len, flags] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _, *mut _, u32, u32) -> i32), + link_name, + abi, + args, + )?; let algorithm = this.read_scalar(algorithm)?; let algorithm = algorithm.to_target_usize(this)?; let ptr = this.read_pointer(ptr)?; @@ -729,8 +1015,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetConsoleScreenBufferInfo" => { // `term` needs this, so we fake it. - let [console, buffer_info] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [console, buffer_info] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, *mut _) -> winapi::BOOL), + 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 this.deref_pointer(buffer_info)?; @@ -739,13 +1029,33 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "GetStdHandle" => { - let [which] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [which] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32) -> winapi::HANDLE), + link_name, + abi, + args, + )?; let res = this.GetStdHandle(which)?; this.write_scalar(res, dest)?; } "DuplicateHandle" => { let [src_proc, src_handle, target_proc, target_handle, access, inherit, options] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + this.check_shim_sig( + shim_sig!( + extern "system" fn( + winapi::HANDLE, + winapi::HANDLE, + winapi::HANDLE, + *mut _, + u32, + winapi::BOOL, + u32, + ) -> winapi::BOOL + ), + link_name, + abi, + args, + )?; let res = this.DuplicateHandle( src_proc, src_handle, @@ -758,15 +1068,24 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "CloseHandle" => { - let [handle] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE) -> winapi::BOOL), + link_name, + abi, + args, + )?; let ret = this.CloseHandle(handle)?; this.write_scalar(ret, dest)?; } "GetModuleFileNameW" => { - let [handle, filename, size] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [handle, filename, size] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HMODULE, *mut _, u32) -> u32), + link_name, + abi, + args, + )?; this.check_no_isolation("`GetModuleFileNameW`")?; let handle = this.read_handle(handle, "GetModuleFileNameW")?; @@ -799,8 +1118,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "FormatMessageW" => { - let [flags, module, message_id, language_id, buffer, size, arguments] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [flags, module, message_id, language_id, buffer, size, arguments] = this + .check_shim_sig( + shim_sig!( + extern "system" fn(u32, *const _, u32, u32, *mut _, u32, *mut _) -> u32 + ), + link_name, + abi, + args, + )?; let flags = this.read_scalar(flags)?.to_u32()?; let _module = this.read_pointer(module)?; // seems to contain a module name @@ -843,7 +1169,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } // This function looks and behaves excatly like miri_start_unwind. - let [payload] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + let [payload] = this.check_shim_sig( + shim_sig!(extern "C" fn(*mut _) -> unwind::libunwind::_Unwind_Reason_Code), + link_name, + abi, + args, + )?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } @@ -851,56 +1182,86 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. "GetProcessHeap" if this.frame_in_std() => { - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> winapi::HANDLE), + link_name, + abi, + args, + )?; // Just fake a HANDLE // It's fine to not use the Handle type here because its a stub this.write_int(1, dest)?; } "GetModuleHandleA" if this.frame_in_std() => { - #[allow(non_snake_case)] - let [_lpModuleName] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [_module_name] = this.check_shim_sig( + shim_sig!(extern "system" fn(*const _) -> winapi::HMODULE), + link_name, + abi, + args, + )?; // We need to return something non-null here to make `compat_fn!` work. this.write_int(1, dest)?; } "SetConsoleTextAttribute" if this.frame_in_std() => { - #[allow(non_snake_case)] - let [_hConsoleOutput, _wAttribute] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [_console_output, _attribute] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, u16) -> winapi::BOOL), + link_name, + abi, + args, + )?; // Pretend these does not exist / nothing happened, by returning zero. this.write_null(dest)?; } "GetConsoleMode" if this.frame_in_std() => { - let [console, mode] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [console, mode] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE, *mut _) -> winapi::BOOL), + link_name, + abi, + args, + )?; this.read_target_isize(console)?; this.deref_pointer_as(mode, this.machine.layouts.u32)?; // Indicate an error. this.write_null(dest)?; } "GetFileType" if this.frame_in_std() => { - #[allow(non_snake_case)] - let [_hFile] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [_file] = this.check_shim_sig( + shim_sig!(extern "system" fn(winapi::HANDLE) -> u32), + link_name, + abi, + args, + )?; // Return unknown file type. this.write_null(dest)?; } "AddVectoredExceptionHandler" if this.frame_in_std() => { - #[allow(non_snake_case)] - let [_First, _Handler] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [_first, _handler] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32, *mut _) -> *mut _), + 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)?; } "SetThreadStackGuarantee" if this.frame_in_std() => { - #[allow(non_snake_case)] - let [_StackSizeInBytes] = - this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [_stack_size_in_bytes] = this.check_shim_sig( + shim_sig!(extern "system" fn(*mut _) -> winapi::BOOL), + 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)?; } // this is only callable from std because we know that std ignores the return value "SwitchToThread" if this.frame_in_std() => { - let [] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let [] = this.check_shim_sig( + shim_sig!(extern "system" fn() -> winapi::BOOL), + link_name, + abi, + args, + )?; this.yield_active_thread(); diff --git a/src/tools/miri/tests/pass-dep/getrandom.rs b/src/tools/miri/tests/pass-dep/getrandom.rs index d359730e7f97..9adb48fb1c3c 100644 --- a/src/tools/miri/tests/pass-dep/getrandom.rs +++ b/src/tools/miri/tests/pass-dep/getrandom.rs @@ -12,6 +12,8 @@ fn main() { #[cfg(not(target_os = "solaris"))] getrandom_01::getrandom(&mut data).unwrap(); + // On Windows, getrandom 0.2 uses the wrong return type for BCryptGenRandom + #[cfg(not(target_os = "windows"))] getrandom_02::getrandom(&mut data).unwrap(); getrandom_03::fill(&mut data).unwrap(); diff --git a/src/tools/miri/tests/pass/tls/windows-tls.rs b/src/tools/miri/tests/pass/tls/windows-tls.rs index 58131be19037..9c5e8eea4d3f 100644 --- a/src/tools/miri/tests/pass/tls/windows-tls.rs +++ b/src/tools/miri/tests/pass/tls/windows-tls.rs @@ -5,14 +5,14 @@ use std::ptr; extern "system" { fn TlsAlloc() -> u32; - fn TlsSetValue(key: u32, val: *mut c_void) -> bool; + fn TlsSetValue(key: u32, val: *mut c_void) -> i32; fn TlsGetValue(key: u32) -> *mut c_void; - fn TlsFree(key: u32) -> bool; + fn TlsFree(key: u32) -> i32; } fn main() { let key = unsafe { TlsAlloc() }; - assert!(unsafe { TlsSetValue(key, ptr::without_provenance_mut(1)) }); + assert!(unsafe { TlsSetValue(key, ptr::without_provenance_mut(1)) != 0 }); assert_eq!(unsafe { TlsGetValue(key).addr() }, 1); - assert!(unsafe { TlsFree(key) }); + assert!(unsafe { TlsFree(key) != 0 }); } From 00693a8b2523ff78fd8d0f62bad17ccaa5f7e422 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 5 Jan 2026 15:10:44 +0100 Subject: [PATCH 1612/3801] tweak shim_sig --- src/tools/miri/src/shims/sig.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/tools/miri/src/shims/sig.rs b/src/tools/miri/src/shims/sig.rs index a49689d11fd7..e88cc66b6ea5 100644 --- a/src/tools/miri/src/shims/sig.rs +++ b/src/tools/miri/src/shims/sig.rs @@ -20,8 +20,12 @@ pub struct ShimSig<'tcx, const ARGS: usize> { /// shim_sig!(extern "C" fn (*const T, i32) -> usize) /// ``` /// -/// In type position, `winapi::` can be used as a shorthand for the full path used by -/// `windows_ty_layout`. +/// The following types are supported: +/// - primitive integer types +/// - `()` +/// - (thin) raw pointers, written `*const _` and `*mut _` since the pointee type is irrelevant +/// - `$crate::$mod::...::$ty` for a type from the given crate (most commonly that is `libc`) +/// - `winapi::$ty` for a type from `std::sys::pal::windows::c` #[macro_export] macro_rules! shim_sig { (extern $abi:literal fn($($arg:ty),* $(,)?) -> $ret:ty) => { @@ -55,10 +59,11 @@ macro_rules! shim_sig_arg { "()" => $this.tcx.types.unit, "*const _" => $this.machine.layouts.const_raw_ptr.ty, "*mut _" => $this.machine.layouts.mut_raw_ptr.ty, - ty if let Some(libc_ty) = ty.strip_prefix("libc::") => $this.libc_ty_layout(libc_ty).ty, ty if let Some(win_ty) = ty.strip_prefix("winapi::") => $this.windows_ty_layout(win_ty).ty, - ty => helpers::path_ty_layout($this, &ty.split("::").collect::>()).ty, + ty if ty.contains("::") => + helpers::path_ty_layout($this, &ty.split("::").collect::>()).ty, + ty => panic!("unsupported signature type {ty:?}"), } }}; } From ba13bb44edd8a96c6de25e98ac70d9b6eefc163e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 5 Jan 2026 08:05:20 -0800 Subject: [PATCH 1613/3801] Update wasm-component-ld Same as 147495, just keeping it up-to-date. --- Cargo.lock | 53 +++++++++++++------------- src/tools/wasm-component-ld/Cargo.toml | 2 +- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 816bb1a37859..470b38d5a91c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6221,9 +6221,9 @@ dependencies = [ [[package]] name = "wasi-preview1-component-adapter-provider" -version = "38.0.4" +version = "40.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec3ef3783e18f2457796ed91b1e6c2adc46f2905f740d1527ab3053fe8e5682" +checksum = "bb5e2b9858989c3a257de4ca169977f4f79897b64e4f482f188f4fcf8ac557d1" [[package]] name = "wasm-bindgen" @@ -6272,17 +6272,18 @@ dependencies = [ [[package]] name = "wasm-component-ld" -version = "0.5.19" +version = "0.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bfc50dd0b883d841bc1dba5ff7020ca52fa7b2c3bb1266d8bf6a09dd032e115" +checksum = "846d20ed66ae37b7a237e36dfcd2fdc979eae82a46cdb0586f9bba80782fd789" dependencies = [ "anyhow", "clap", + "clap_lex", "lexopt", "libc", "tempfile", "wasi-preview1-component-adapter-provider", - "wasmparser 0.241.2", + "wasmparser 0.243.0", "wat", "windows-sys 0.61.2", "winsplit", @@ -6309,24 +6310,24 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.241.2" +version = "0.243.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01164c9dda68301e34fdae536c23ed6fe90ce6d97213ccc171eebbd3d02d6b8" +checksum = "c55db9c896d70bd9fa535ce83cd4e1f2ec3726b0edd2142079f594fc3be1cb35" dependencies = [ "leb128fmt", - "wasmparser 0.241.2", + "wasmparser 0.243.0", ] [[package]] name = "wasm-metadata" -version = "0.241.2" +version = "0.243.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876fe286f2fa416386deedebe8407e6f19e0b5aeaef3d03161e77a15fa80f167" +checksum = "eae05bf9579f45a62e8d0a4e3f52eaa8da518883ac5afa482ec8256c329ecd56" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.241.2", - "wasmparser 0.241.2", + "wasm-encoder 0.243.0", + "wasmparser 0.243.0", ] [[package]] @@ -6351,9 +6352,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.241.2" +version = "0.243.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46d90019b1afd4b808c263e428de644f3003691f243387d30d673211ee0cb8e8" +checksum = "f6d8db401b0528ec316dfbe579e6ab4152d61739cfe076706d2009127970159d" dependencies = [ "bitflags", "hashbrown 0.15.5", @@ -6364,22 +6365,22 @@ dependencies = [ [[package]] name = "wast" -version = "241.0.2" +version = "243.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63f66e07e2ddf531fef6344dbf94d112df7c2f23ed6ffb10962e711500b8d816" +checksum = "df21d01c2d91e46cb7a221d79e58a2d210ea02020d57c092e79255cc2999ca7f" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width 0.2.2", - "wasm-encoder 0.241.2", + "wasm-encoder 0.243.0", ] [[package]] name = "wat" -version = "1.241.2" +version = "1.243.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f923705c40830af909c5dec2352ec2821202e4a66008194585e1917458a26d" +checksum = "226a9a91cd80a50449312fef0c75c23478fcecfcc4092bdebe1dc8e760ef521b" dependencies = [ "wast", ] @@ -6775,9 +6776,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.241.2" +version = "0.243.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0c57df25e7ee612d946d3b7646c1ddb2310f8280aa2c17e543b66e0812241" +checksum = "36f9fc53513e461ce51dcf17a3e331752cb829f1d187069e54af5608fc998fe4" dependencies = [ "anyhow", "bitflags", @@ -6786,17 +6787,17 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.241.2", + "wasm-encoder 0.243.0", "wasm-metadata", - "wasmparser 0.241.2", + "wasmparser 0.243.0", "wit-parser", ] [[package]] name = "wit-parser" -version = "0.241.2" +version = "0.243.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ef1c6ad67f35c831abd4039c02894de97034100899614d1c44e2268ad01c91" +checksum = "df983a8608e513d8997f435bb74207bf0933d0e49ca97aa9d8a6157164b9b7fc" dependencies = [ "anyhow", "id-arena", @@ -6807,7 +6808,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.241.2", + "wasmparser 0.243.0", ] [[package]] diff --git a/src/tools/wasm-component-ld/Cargo.toml b/src/tools/wasm-component-ld/Cargo.toml index 744b67c17f65..2d44358c7433 100644 --- a/src/tools/wasm-component-ld/Cargo.toml +++ b/src/tools/wasm-component-ld/Cargo.toml @@ -10,4 +10,4 @@ name = "wasm-component-ld" path = "src/main.rs" [dependencies] -wasm-component-ld = "0.5.19" +wasm-component-ld = "0.5.20" From 1925afb7b08e3de09af0bb06fd60fbc3ce82b178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 5 Jan 2026 17:18:52 +0100 Subject: [PATCH 1614/3801] Enable merge queue in new bors --- rust-bors.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rust-bors.toml b/rust-bors.toml index 384343e431dc..0d59918e3f77 100644 --- a/rust-bors.toml +++ b/rust-bors.toml @@ -29,8 +29,7 @@ labels_blocking_approval = [ # If CI runs quicker than this duration, consider it to be a failure min_ci_time = 600 -# Flip this once new bors is used for actual merges on this repository -merge_queue_enabled = false +merge_queue_enabled = true report_merge_conflicts = true [labels] @@ -55,7 +54,9 @@ try_failed = [ "-S-waiting-on-review", "-S-waiting-on-crater" ] -auto_build_succeeded = ["+merged-by-bors"] +auto_build_succeeded = [ + "+merged-by-bors" +] auto_build_failed = [ "+S-waiting-on-review", "-S-blocked", From accfc34e43b0fb6ef9ac162ca256ae270b6d468e Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Thu, 11 Dec 2025 10:31:33 -0500 Subject: [PATCH 1615/3801] rustc_codegen_llvm: update alignment for double on AIX This was recently fixed upstream in LLVM, so we update our default layout to match. @rustbot label: +llvm-main --- compiler/rustc_codegen_llvm/src/context.rs | 4 ++++ compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 07b04863af6b..4b2544b7efdf 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -211,6 +211,10 @@ pub(crate) unsafe fn create_module<'ll>( // LLVM 22 updated the NVPTX layout to indicate 256-bit vector load/store: https://github.com/llvm/llvm-project/pull/155198 target_data_layout = target_data_layout.replace("-i256:256", ""); } + if sess.target.arch == Arch::PowerPC64 { + // LLVM 22 updated the ABI alignment for double on AIX: https://github.com/llvm/llvm-project/pull/144673 + target_data_layout = target_data_layout.replace("-f64:32:64", ""); + } } // Ensure the data-layout values hardcoded remain the defaults. diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs index b4f394643a9d..b83f5544a351 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs @@ -17,7 +17,8 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 64, - data_layout: "E-m:a-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512".into(), + data_layout: "E-m:a-Fi64-i64:64-i128:128-n32:64-f64:32:64-S128-v256:256:256-v512:512:512" + .into(), arch: Arch::PowerPC64, options: base, } From 85c8e41f62f1c347f2b5c2f5f008a238ecff22e9 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Mon, 5 Jan 2026 09:01:23 +0000 Subject: [PATCH 1616/3801] add pretty printing --- compiler/rustc_hir_pretty/src/lib.rs | 36 ++++++++++++++--- ...struct-exprs-tuple-call-pretty-printing.rs | 33 ++++++++++++++++ ...ct-exprs-tuple-call-pretty-printing.stdout | 39 +++++++++++++++++++ 3 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.rs create mode 100644 tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 533afc372063..feaada638f07 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -17,9 +17,9 @@ use rustc_ast_pretty::pprust::state::MacHeader; use rustc_ast_pretty::pprust::{Comments, PrintState}; use rustc_hir::attrs::{AttributeKind, PrintAttribute}; use rustc_hir::{ - BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind, - HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, - TyPatKind, + BindingMode, ByRef, ConstArg, ConstArgExprField, ConstArgKind, GenericArg, GenericBound, + GenericParam, GenericParamKind, HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind, + PreciseCapturingArg, RangeEnd, Term, TyPatKind, }; use rustc_span::source_map::SourceMap; use rustc_span::{FileName, Ident, Span, Symbol, kw, sym}; @@ -1137,9 +1137,8 @@ impl<'a> State<'a> { fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) { match &const_arg.kind { - // FIXME(mgca): proper printing for struct exprs - ConstArgKind::Struct(..) => self.word("/* STRUCT EXPR */"), - ConstArgKind::TupleCall(..) => self.word("/* TUPLE CALL */"), + ConstArgKind::Struct(qpath, fields) => self.print_const_struct(qpath, fields), + ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args), ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), ConstArgKind::Anon(anon) => self.print_anon_const(anon), ConstArgKind::Error(_, _) => self.word("/*ERROR*/"), @@ -1147,6 +1146,31 @@ impl<'a> State<'a> { } } + fn print_const_struct(&mut self, qpath: &hir::QPath<'_>, fields: &&[&ConstArgExprField<'_>]) { + self.print_qpath(qpath, true); + self.word(" "); + self.word("{"); + if !fields.is_empty() { + self.nbsp(); + } + self.commasep(Inconsistent, *fields, |s, field| { + s.word(field.field.as_str().to_string()); + s.word(":"); + s.nbsp(); + s.print_const_arg(field.expr); + }); + self.word("}"); + } + + fn print_const_ctor(&mut self, qpath: &hir::QPath<'_>, args: &&[&ConstArg<'_, ()>]) { + self.print_qpath(qpath, true); + self.word("("); + self.commasep(Inconsistent, *args, |s, arg| { + s.print_const_arg(arg); + }); + self.word(")"); + } + fn print_call_post(&mut self, args: &[hir::Expr<'_>]) { self.popen(); self.commasep_exprs(Inconsistent, args); diff --git a/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.rs b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.rs new file mode 100644 index 000000000000..5f2d6680efac --- /dev/null +++ b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.rs @@ -0,0 +1,33 @@ +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +use std::marker::ConstParamTy; + +struct Point(u32, u32); + +struct Point3(); + +struct Point1 { + a: u32, + b: u32, +} + +struct Point2 {} + +fn with_point() {} +fn with_point1() {} +fn with_point2() {} +fn with_point3() {} + +fn test() { + with_point::<{ Point(N, N) }>(); + with_point1::<{ Point1 { a: N, b: N } }>(); + with_point2::<{ Point2 {} }>(); + with_point3::<{ Point3() }>(); +} + +fn main() {} diff --git a/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout new file mode 100644 index 000000000000..fc0fbe8ef237 --- /dev/null +++ b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout @@ -0,0 +1,39 @@ +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] +#[attr = MacroUse {arguments: UseAll}] +extern crate std; +#[prelude_import] +use ::std::prelude::rust_2015::*; + +use std::marker::ConstParamTy; + +struct Point(u32, u32); + +struct Point3(); + +struct Point1 { + a: u32, + b: u32, +} + +struct Point2 { +} + +fn with_point() { } +fn with_point1() { } +fn with_point2() { } +fn with_point3() { } + +fn test() { + with_point::(); + with_point1::(); + with_point2::(); + with_point3::(); +} + +fn main() { } From 85d7fb0755432cdd65f88c3d9cb372fbc49c29fb Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Mon, 5 Jan 2026 23:28:24 +0000 Subject: [PATCH 1617/3801] Remove copyright year --- COPYRIGHT | 2 +- LICENSE-APACHE | 2 +- LICENSE-MIT | 2 +- README.md | 2 +- clippy_utils/README.md | 2 +- rustc_tools_util/README.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index 5d3075903a01..d3b4c9e5fb2c 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,6 +1,6 @@ // REUSE-IgnoreStart -Copyright 2014-2026 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 6f6e5844208d..773ae298cc19 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work. same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright 2014-2026 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/LICENSE-MIT b/LICENSE-MIT index a51639bc0f9b..9549420685cc 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2014-2026 The Rust Project Developers +Copyright (c) The Rust Project Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/README.md b/README.md index 287dee82daaa..8bccd040c1f9 100644 --- a/README.md +++ b/README.md @@ -277,7 +277,7 @@ If you want to contribute to Clippy, you can find more information in [CONTRIBUT -Copyright 2014-2026 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/clippy_utils/README.md b/clippy_utils/README.md index e3ce95d30074..69bb6a2d6669 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -30,7 +30,7 @@ Function signatures can change or be removed without replacement without any pri -Copyright 2014-2026 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 <[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license diff --git a/rustc_tools_util/README.md b/rustc_tools_util/README.md index 083814e1e05d..45d2844ad00b 100644 --- a/rustc_tools_util/README.md +++ b/rustc_tools_util/README.md @@ -51,7 +51,7 @@ The changelog for `rustc_tools_util` is available under: -Copyright 2014-2026 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 or the MIT license From fa4a62b06656b46afbd3398dc75b10997b3ab7db Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 27 Dec 2025 00:26:21 +0100 Subject: [PATCH 1618/3801] use PIDFD_GET_INFO ioctl when available This way using pidfd_spawnp won't have to rely on procfs, avoiding an unpleasant edge-case where the child is spawned but we can't get the pid. And `pidfd.{try_}wait` will be able to return the exit status even after a process has been reaped. At least on newer kernels. --- library/std/src/os/linux/process.rs | 10 +- library/std/src/sys/pal/unix/linux/pidfd.rs | 101 ++++++++++++++---- .../std/src/sys/pal/unix/linux/pidfd/tests.rs | 38 ++++--- library/std/src/sys/process/unix/unix.rs | 40 +++---- 4 files changed, 132 insertions(+), 57 deletions(-) diff --git a/library/std/src/os/linux/process.rs b/library/std/src/os/linux/process.rs index fef321436f6a..60851db831bf 100644 --- a/library/std/src/os/linux/process.rs +++ b/library/std/src/os/linux/process.rs @@ -67,8 +67,10 @@ impl PidFd { /// Waits for the child to exit completely, returning the status that it exited with. /// /// Unlike [`Child::wait`] it does not ensure that the stdin handle is closed. - /// Additionally it will not return an `ExitStatus` if the child - /// has already been reaped. Instead an error will be returned. + /// + /// Additionally on kernels prior to 6.15 only the first attempt to + /// reap a child will return an ExitStatus, further attempts + /// will return an Error. /// /// [`Child::wait`]: process::Child::wait pub fn wait(&self) -> Result { @@ -77,8 +79,8 @@ impl PidFd { /// Attempts to collect the exit status of the child if it has already exited. /// - /// Unlike [`Child::try_wait`] this method will return an Error - /// if the child has already been reaped. + /// On kernels prior to 6.15, and unlike [`Child::try_wait`], only the first attempt + /// to reap a child will return an ExitStatus, further attempts will return an Error. /// /// [`Child::try_wait`]: process::Child::try_wait pub fn try_wait(&self) -> Result> { diff --git a/library/std/src/sys/pal/unix/linux/pidfd.rs b/library/std/src/sys/pal/unix/linux/pidfd.rs index 7859854e96b4..e9e4831fcc02 100644 --- a/library/std/src/sys/pal/unix/linux/pidfd.rs +++ b/library/std/src/sys/pal/unix/linux/pidfd.rs @@ -1,5 +1,5 @@ use crate::io; -use crate::os::fd::{AsRawFd, FromRawFd, RawFd}; +use crate::os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; use crate::sys::fd::FileDesc; use crate::sys::process::ExitStatus; use crate::sys::{AsInner, FromInner, IntoInner, cvt}; @@ -15,6 +15,73 @@ impl PidFd { self.send_signal(libc::SIGKILL) } + #[cfg(any(test, target_env = "gnu", target_env = "musl"))] + pub(crate) fn current_process() -> io::Result { + let pid = crate::process::id(); + let pidfd = cvt(unsafe { libc::syscall(libc::SYS_pidfd_open, pid, 0) })?; + Ok(unsafe { PidFd::from_raw_fd(pidfd as RawFd) }) + } + + #[cfg(any(test, target_env = "gnu", target_env = "musl"))] + pub(crate) fn pid(&self) -> io::Result { + use crate::sys::weak::weak; + + // since kernel 6.13 + // https://lore.kernel.org/all/20241010155401.2268522-1-luca.boccassi@gmail.com/ + let mut pidfd_info: libc::pidfd_info = unsafe { crate::mem::zeroed() }; + pidfd_info.mask = libc::PIDFD_INFO_PID as u64; + match cvt(unsafe { libc::ioctl(self.0.as_raw_fd(), libc::PIDFD_GET_INFO, &mut pidfd_info) }) + { + Ok(_) => {} + Err(e) if e.raw_os_error() == Some(libc::EINVAL) => { + // kernel doesn't support that ioctl, try the glibc helper that looks at procfs + weak!( + fn pidfd_getpid(pidfd: RawFd) -> libc::pid_t; + ); + if let Some(pidfd_getpid) = pidfd_getpid.get() { + let pid: libc::c_int = cvt(unsafe { pidfd_getpid(self.0.as_raw_fd()) })?; + return Ok(pid as u32); + } + return Err(e); + } + Err(e) => return Err(e), + } + + Ok(pidfd_info.pid) + } + + fn exit_for_reaped_child(&self) -> io::Result { + // since kernel 6.15 + // https://lore.kernel.org/linux-fsdevel/20250305-work-pidfs-kill_on_last_close-v3-0-c8c3d8361705@kernel.org/T/ + let mut pidfd_info: libc::pidfd_info = unsafe { crate::mem::zeroed() }; + pidfd_info.mask = libc::PIDFD_INFO_EXIT as u64; + cvt(unsafe { libc::ioctl(self.0.as_raw_fd(), libc::PIDFD_GET_INFO, &mut pidfd_info) })?; + Ok(ExitStatus::new(pidfd_info.exit_code)) + } + + fn waitid(&self, options: libc::c_int) -> io::Result> { + let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() }; + let r = cvt(unsafe { + libc::waitid(libc::P_PIDFD, self.0.as_raw_fd() as u32, &mut siginfo, options) + }); + match r { + Err(waitid_err) if waitid_err.raw_os_error() == Some(libc::ECHILD) => { + // already reaped + match self.exit_for_reaped_child() { + Ok(exit_status) => return Ok(Some(exit_status)), + Err(_) => return Err(waitid_err), + } + } + Err(e) => return Err(e), + Ok(_) => {} + } + if unsafe { siginfo.si_pid() } == 0 { + Ok(None) + } else { + Ok(Some(ExitStatus::from_waitid_siginfo(siginfo))) + } + } + pub(crate) fn send_signal(&self, signal: i32) -> io::Result<()> { cvt(unsafe { libc::syscall( @@ -29,29 +96,15 @@ impl PidFd { } pub fn wait(&self) -> io::Result { - let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() }; - cvt(unsafe { - libc::waitid(libc::P_PIDFD, self.0.as_raw_fd() as u32, &mut siginfo, libc::WEXITED) - })?; - Ok(ExitStatus::from_waitid_siginfo(siginfo)) + let r = self.waitid(libc::WEXITED)?; + match r { + Some(exit_status) => Ok(exit_status), + None => unreachable!("waitid with WEXITED should not return None"), + } } pub fn try_wait(&self) -> io::Result> { - let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() }; - - cvt(unsafe { - libc::waitid( - libc::P_PIDFD, - self.0.as_raw_fd() as u32, - &mut siginfo, - libc::WEXITED | libc::WNOHANG, - ) - })?; - if unsafe { siginfo.si_pid() } == 0 { - Ok(None) - } else { - Ok(Some(ExitStatus::from_waitid_siginfo(siginfo))) - } + self.waitid(libc::WEXITED | libc::WNOHANG) } } @@ -78,3 +131,9 @@ impl FromRawFd for PidFd { Self(FileDesc::from_raw_fd(fd)) } } + +impl IntoRawFd for PidFd { + fn into_raw_fd(self) -> RawFd { + self.0.into_raw_fd() + } +} diff --git a/library/std/src/sys/pal/unix/linux/pidfd/tests.rs b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs index 17b06bea9127..a3bb5d5d64ba 100644 --- a/library/std/src/sys/pal/unix/linux/pidfd/tests.rs +++ b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs @@ -1,8 +1,11 @@ +use super::PidFd as InternalPidFd; use crate::assert_matches::assert_matches; -use crate::os::fd::{AsRawFd, RawFd}; +use crate::io::ErrorKind; +use crate::os::fd::AsRawFd; use crate::os::linux::process::{ChildExt, CommandExt as _}; use crate::os::unix::process::{CommandExt as _, ExitStatusExt}; use crate::process::Command; +use crate::sys::AsInner; #[test] fn test_command_pidfd() { @@ -48,11 +51,22 @@ fn test_command_pidfd() { let mut cmd = Command::new("false"); let mut child = unsafe { cmd.pre_exec(|| Ok(())) }.create_pidfd(true).spawn().unwrap(); - assert!(child.id() > 0 && child.id() < -1i32 as u32); + let id = child.id(); + + assert!(id > 0 && id < -1i32 as u32, "spawning with pidfd still returns a sane pid"); if pidfd_open_available { assert!(child.pidfd().is_ok()) } + + if let Ok(pidfd) = child.pidfd() { + match pidfd.as_inner().pid() { + Ok(pid) => assert_eq!(pid, id), + Err(e) if e.kind() == ErrorKind::InvalidInput => { /* older kernel */ } + Err(e) => panic!("unexpected error getting pid from pidfd: {}", e), + } + } + child.wait().expect("error waiting on child"); } @@ -77,9 +91,15 @@ fn test_pidfd() { assert_eq!(status.signal(), Some(libc::SIGKILL)); // Trying to wait again for a reaped child is safe since there's no pid-recycling race. - // But doing so will return an error. + // But doing so may return an error. let res = fd.wait(); - assert_matches!(res, Err(e) if e.raw_os_error() == Some(libc::ECHILD)); + match res { + // older kernels + Err(e) if e.raw_os_error() == Some(libc::ECHILD) => {} + // 6.15+ + Ok(exit) if exit.signal() == Some(libc::SIGKILL) => {} + other => panic!("expected ECHILD error, got {:?}", other), + } // Ditto for additional attempts to kill an already-dead child. let res = fd.kill(); @@ -87,13 +107,5 @@ fn test_pidfd() { } fn probe_pidfd_support() -> bool { - // pidfds require the pidfd_open syscall - let our_pid = crate::process::id(); - let pidfd = unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) }; - if pidfd >= 0 { - unsafe { libc::close(pidfd as RawFd) }; - true - } else { - false - } + InternalPidFd::current_process().is_ok() } diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 5ba57e11679c..df64a1716d52 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -482,10 +482,6 @@ impl Command { ) -> libc::c_int; ); - weak!( - fn pidfd_getpid(pidfd: libc::c_int) -> libc::c_int; - ); - static PIDFD_SUPPORTED: Atomic = AtomicU8::new(0); const UNKNOWN: u8 = 0; const SPAWN: u8 = 1; @@ -502,24 +498,26 @@ impl Command { } if support == UNKNOWN { support = NO; - let our_pid = crate::process::id(); - let pidfd = cvt(unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) } as c_int); - match pidfd { + + match PidFd::current_process() { Ok(pidfd) => { + // if pidfd_open works then we at least know the fork path is available. support = FORK_EXEC; - if let Some(Ok(pid)) = pidfd_getpid.get().map(|f| cvt(unsafe { f(pidfd) } as i32)) { - if pidfd_spawnp.get().is_some() && pid as u32 == our_pid { - support = SPAWN - } + // but for the fast path we need both spawnp and the + // pidfd -> pid conversion to work. + if pidfd_spawnp.get().is_some() && let Ok(pid) = pidfd.pid() { + assert_eq!(pid, crate::process::id(), "sanity check"); + support = SPAWN; } - unsafe { libc::close(pidfd) }; } Err(e) if e.raw_os_error() == Some(libc::EMFILE) => { - // We're temporarily(?) out of file descriptors. In this case obtaining a pidfd would also fail + // We're temporarily(?) out of file descriptors. In this case pidfd_spawnp would also fail // Don't update the support flag so we can probe again later. return Err(e) } - _ => {} + _ => { + // pidfd_open not available? likely an old kernel without pidfd support. + } } PIDFD_SUPPORTED.store(support, Ordering::Relaxed); if support == FORK_EXEC { @@ -791,13 +789,17 @@ impl Command { } spawn_res?; - let pid = match cvt(pidfd_getpid.get().unwrap()(pidfd)) { + use crate::os::fd::{FromRawFd, IntoRawFd}; + + let pidfd = PidFd::from_raw_fd(pidfd); + let pid = match pidfd.pid() { Ok(pid) => pid, Err(e) => { // The child has been spawned and we are holding its pidfd. - // But we cannot obtain its pid even though pidfd_getpid support was verified earlier. - // This might happen if libc can't open procfs because the file descriptor limit has been reached. - libc::close(pidfd); + // But we cannot obtain its pid even though pidfd_spawnp and getpid support + // was verified earlier. + // This is quite unlikely, but might happen if the ioctl is not supported, + // glibc tries to use procfs and we're out of file descriptors. return Err(Error::new( e.kind(), "pidfd_spawnp succeeded but the child's PID could not be obtained", @@ -805,7 +807,7 @@ impl Command { } }; - return Ok(Some(Process::new(pid, pidfd))); + return Ok(Some(Process::new(pid as i32, pidfd.into_raw_fd()))); } // Safety: -1 indicates we don't have a pidfd. From b0a581d51d7656379bd26c2e6c3c28db73ff97ce Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Tue, 6 Jan 2026 09:19:03 +0900 Subject: [PATCH 1619/3801] rename the `lower_ty` and `lower_ty_direct` to `lower_ty_and_alloc` and `lower_ty` --- compiler/rustc_ast_lowering/src/block.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 17 ++++---- compiler/rustc_ast_lowering/src/item.rs | 51 ++++++++++++++---------- compiler/rustc_ast_lowering/src/lib.rs | 38 +++++++++--------- compiler/rustc_ast_lowering/src/path.rs | 15 +++---- 5 files changed, 70 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index 5bfe63008516..cf3f331a701b 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -98,7 +98,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Let statements are allowed to have impl trait in bindings. let super_ = l.super_.map(|span| self.lower_span(span)); let ty = l.ty.as_ref().map(|t| { - self.lower_ty(t, self.impl_trait_in_bindings_ctxt(ImplTraitPosition::Variable)) + self.lower_ty_alloc(t, self.impl_trait_in_bindings_ctxt(ImplTraitPosition::Variable)) }); let init = l.kind.init().map(|init| self.lower_expr(init)); let hir_id = self.lower_node_id(l.id); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 0502fd2873e9..9fbfeb7a11e6 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -158,14 +158,14 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::Cast(expr, ty) => { let expr = self.lower_expr(expr); - let ty = - self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast)); + let ty = self + .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast)); hir::ExprKind::Cast(expr, ty) } ExprKind::Type(expr, ty) => { let expr = self.lower_expr(expr); - let ty = - self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast)); + let ty = self + .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast)); hir::ExprKind::Type(expr, ty) } ExprKind::AddrOf(k, m, ohs) => { @@ -335,7 +335,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::FormatArgs(fmt) => self.lower_format_args(e.span, fmt), ExprKind::OffsetOf(container, fields) => hir::ExprKind::OffsetOf( - self.lower_ty( + self.lower_ty_alloc( container, ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf), ), @@ -371,7 +371,10 @@ impl<'hir> LoweringContext<'_, 'hir> { *kind, self.lower_expr(expr), ty.as_ref().map(|ty| { - self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast)) + self.lower_ty_alloc( + ty, + ImplTraitContext::Disallowed(ImplTraitPosition::Cast), + ) }), ), @@ -617,7 +620,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }); if let Some(ty) = opt_ty { - let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path)); + let ty = self.lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path)); let block_expr = self.arena.alloc(self.expr_block(whole_block)); hir::ExprKind::Type(block_expr, ty) } else { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index bfce7c25b75d..f8b98a5ece40 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -264,8 +264,8 @@ impl<'hir> LoweringContext<'_, 'hir> { define_opaque, }) => { let ident = self.lower_ident(*ident); - let ty = - self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); + let ty = self + .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); let body_id = self.lower_const_body(span, e.as_deref()); self.lower_define_opaque(hir_id, define_opaque); hir::ItemKind::Static(*m, ident, ty, body_id) @@ -279,8 +279,10 @@ impl<'hir> LoweringContext<'_, 'hir> { id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { - let ty = this - .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); + let ty = this.lower_ty_alloc( + ty, + ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy), + ); let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), span); (ty, rhs) }, @@ -379,7 +381,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); this.arena.alloc(this.ty(span, hir::TyKind::Err(guar))) } - Some(ty) => this.lower_ty( + Some(ty) => this.lower_ty_alloc( ty, ImplTraitContext::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias { @@ -453,7 +455,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .as_deref() .map(|of_trait| this.lower_trait_impl_header(of_trait)); - let lowered_ty = this.lower_ty( + let lowered_ty = this.lower_ty_alloc( ty, ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf), ); @@ -758,8 +760,8 @@ impl<'hir> LoweringContext<'_, 'hir> { safety, define_opaque, }) => { - let ty = - self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); + let ty = self + .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); let safety = self.lower_safety(*safety, hir::Safety::Unsafe); if define_opaque.is_some() { self.dcx().span_err(i.span, "foreign statics cannot define opaque types"); @@ -870,7 +872,8 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, (index, f): (usize, &FieldDef), ) -> hir::FieldDef<'hir> { - let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy)); + let ty = + self.lower_ty_alloc(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy)); let hir_id = self.lower_node_id(f.id); self.lower_attrs(hir_id, &f.attrs, f.span, Target::Field); hir::FieldDef { @@ -908,8 +911,10 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { - let ty = this - .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); + let ty = this.lower_ty_alloc( + ty, + ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy), + ); let rhs = rhs .as_ref() .map(|rhs| this.lower_const_item_rhs(attrs, Some(rhs), i.span)); @@ -1008,7 +1013,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { let ty = ty.as_ref().map(|x| { - this.lower_ty( + this.lower_ty_alloc( x, ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy), ) @@ -1120,8 +1125,10 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { - let ty = this - .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); + let ty = this.lower_ty_alloc( + ty, + ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy), + ); this.lower_define_opaque(hir_id, &define_opaque); let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), i.span); hir::ImplItemKind::Const(ty, rhs) @@ -1180,7 +1187,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ImplItemKind::Type(ty) } Some(ty) => { - let ty = this.lower_ty( + let ty = this.lower_ty_alloc( ty, ImplTraitContext::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias { @@ -1916,7 +1923,7 @@ impl<'hir> LoweringContext<'_, 'hir> { bound_generic_params, hir::GenericParamSource::Binder, ), - bounded_ty: self.lower_ty( + bounded_ty: self.lower_ty_alloc( bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound), ), @@ -1945,10 +1952,14 @@ impl<'hir> LoweringContext<'_, 'hir> { } WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => { hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { - lhs_ty: self - .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), - rhs_ty: self - .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), + lhs_ty: self.lower_ty_alloc( + lhs_ty, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + ), + rhs_ty: self.lower_ty_alloc( + rhs_ty, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + ), }) } }); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 9a459156aba1..0d1388a2441d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1125,7 +1125,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let kind = match &constraint.kind { AssocItemConstraintKind::Equality { term } => { let term = match term { - Term::Ty(ty) => self.lower_ty(ty, itctx).into(), + Term::Ty(ty) => self.lower_ty_alloc(ty, itctx).into(), Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(), }; hir::AssocItemConstraintKind::Equality { term } @@ -1250,7 +1250,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } _ => {} } - GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap()) + GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap()) } ast::GenericArg::Const(ct) => { GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap()) @@ -1259,8 +1259,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } #[instrument(level = "debug", skip(self))] - fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> { - self.arena.alloc(self.lower_ty_direct(t, itctx)) + fn lower_ty_alloc(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> { + self.arena.alloc(self.lower_ty(t, itctx)) } fn lower_path_ty( @@ -1324,11 +1324,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.ty(span, hir::TyKind::Tup(tys)) } - fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> { + fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> { let kind = match &t.kind { TyKind::Infer => hir::TyKind::Infer(()), TyKind::Err(guar) => hir::TyKind::Err(*guar), - TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), + TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)), TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), TyKind::Ref(region, mt) => { let lifetime = self.lower_ty_direct_lifetime(t, *region); @@ -1362,15 +1362,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params); hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy { generic_params, - inner_ty: self.lower_ty(&f.inner_ty, itctx), + inner_ty: self.lower_ty_alloc(&f.inner_ty, itctx), })) } TyKind::Never => hir::TyKind::Never, TyKind::Tup(tys) => hir::TyKind::Tup( - self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))), + self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty(ty, itctx))), ), TyKind::Paren(ty) => { - return self.lower_ty_direct(ty, itctx); + return self.lower_ty(ty, itctx); } TyKind::Path(qself, path) => { return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx); @@ -1393,7 +1393,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { )) } TyKind::Array(ty, length) => hir::TyKind::Array( - self.lower_ty(ty, itctx), + self.lower_ty_alloc(ty, itctx), self.lower_array_length_to_const_arg(length), ), TyKind::TraitObject(bounds, kind) => { @@ -1493,7 +1493,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } TyKind::Pat(ty, pat) => { - hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span)) + hir::TyKind::Pat(self.lower_ty_alloc(ty, itctx), self.lower_ty_pat(pat, ty.span)) } TyKind::MacCall(_) => { span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now") @@ -1693,7 +1693,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam) } }; - self.lower_ty_direct(¶m.ty, itctx) + self.lower_ty(¶m.ty, itctx) })); let output = match coro { @@ -1732,7 +1732,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn) } }; - hir::FnRetTy::Return(self.lower_ty(ty, itctx)) + hir::FnRetTy::Return(self.lower_ty_alloc(ty, itctx)) } FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)), }, @@ -1843,7 +1843,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the // `impl Future` opaque type that `async fn` implicitly // generates. - self.lower_ty(ty, itctx) + self.lower_ty_alloc(ty, itctx) } FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])), }; @@ -2036,7 +2036,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } }) .map(|def| { - self.lower_ty( + self.lower_ty_alloc( def, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), ) @@ -2047,8 +2047,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(self.lower_ident(param.ident)), kind) } GenericParamKind::Const { ty, span: _, default } => { - let ty = self - .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault)); + let ty = self.lower_ty_alloc( + ty, + ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), + ); // Not only do we deny const param defaults in binders but we also map them to `None` // since later compiler stages cannot handle them (and shouldn't need to be able to). @@ -2198,7 +2200,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> { - hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl } + hir::MutTy { ty: self.lower_ty_alloc(&mt.ty, itctx), mutbl: mt.mutbl } } #[instrument(level = "debug", skip(self), ret)] diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 3322e0fb66b4..bfb42efb684f 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -36,7 +36,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let qself = qself .as_ref() // Reject cases like `::Assoc` and `::Assoc`. - .map(|q| self.lower_ty(&q.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path))); + .map(|q| { + self.lower_ty_alloc(&q.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path)) + }); let partial_res = self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); @@ -510,7 +512,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // we generally don't permit such things (see #51008). let ParenthesizedArgs { span, inputs, inputs_span, output } = data; let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| { - self.lower_ty_direct(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam)) + self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam)) })); let output_ty = match output { // Only allow `impl Trait` in return position. i.e.: @@ -520,9 +522,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // ``` FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::OpaqueTy { .. }) => { if self.tcx.features().impl_trait_in_fn_trait_return() { - self.lower_ty(ty, itctx) + self.lower_ty_alloc(ty, itctx) } else { - self.lower_ty( + self.lower_ty_alloc( ty, ImplTraitContext::FeatureGated( ImplTraitPosition::FnTraitReturn, @@ -531,9 +533,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } } - FnRetTy::Ty(ty) => { - self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)) - } + FnRetTy::Ty(ty) => self + .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)), FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])), }; let args = smallvec![GenericArg::Type( From 56cb5d598bc4b0e3b106752720feb3934316bfb5 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Tue, 6 Jan 2026 09:24:41 +0900 Subject: [PATCH 1620/3801] rename the `lower_anon_const_to_const_arg` and `lower_anon_const_to_const_arg_direct` to `lower_anon_const_to_const_arg_and_alloc` and `lower_anon_const_to_const_arg` --- compiler/rustc_ast_lowering/src/lib.rs | 27 ++++++++++++++------------ compiler/rustc_ast_lowering/src/pat.rs | 18 +++++++++-------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0d1388a2441d..e11e24c0263f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1126,7 +1126,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { AssocItemConstraintKind::Equality { term } => { let term = match term { Term::Ty(ty) => self.lower_ty_alloc(ty, itctx).into(), - Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(), + Term::Const(c) => self.lower_anon_const_to_const_arg_and_alloc(c).into(), }; hir::AssocItemConstraintKind::Equality { term } } @@ -1252,9 +1252,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap()) } - ast::GenericArg::Const(ct) => { - GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap()) - } + ast::GenericArg::Const(ct) => GenericArg::Const( + self.lower_anon_const_to_const_arg_and_alloc(ct).try_as_ambig_ct().unwrap(), + ), } } @@ -2066,7 +2066,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { false } }) - .map(|def| self.lower_anon_const_to_const_arg(def)); + .map(|def| self.lower_anon_const_to_const_arg_and_alloc(def)); ( hir::ParamName::Plain(self.lower_ident(param.ident)), @@ -2288,7 +2288,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ()); self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind }) } - _ => self.lower_anon_const_to_const_arg(c), + _ => self.lower_anon_const_to_const_arg_and_alloc(c), } } @@ -2367,7 +2367,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::ConstItemRhs<'hir> { match rhs { Some(ConstItemRhs::TypeConst(anon)) => { - hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg(anon)) + hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg_and_alloc(anon)) } None if attr::contains_name(attrs, sym::type_const) => { let const_arg = ConstArg { @@ -2414,7 +2414,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let def_id = self.local_def_id(anon_const.id); let def_kind = self.tcx.def_kind(def_id); assert_eq!(DefKind::AnonConst, def_kind); - self.lower_anon_const_to_const_arg_direct(anon_const) + self.lower_anon_const_to_const_arg(anon_const) } else { self.lower_expr_to_const_arg_direct(arg) }; @@ -2467,7 +2467,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let def_kind = self.tcx.def_kind(def_id); assert_eq!(DefKind::AnonConst, def_kind); - self.lower_anon_const_to_const_arg_direct(anon_const) + self.lower_anon_const_to_const_arg(anon_const) } else { self.lower_expr_to_const_arg_direct(&f.expr) }; @@ -2508,12 +2508,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// See [`hir::ConstArg`] for when to use this function vs /// [`Self::lower_anon_const_to_anon_const`]. - fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> { - self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon)) + fn lower_anon_const_to_const_arg_and_alloc( + &mut self, + anon: &AnonConst, + ) -> &'hir hir::ConstArg<'hir> { + self.arena.alloc(self.lower_anon_const_to_const_arg(anon)) } #[instrument(level = "debug", skip(self))] - fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> { + fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> { let tcx = self.tcx; // We cannot change parsing depending on feature gates available, diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 7a5d8d9847a1..f09bbb9c4972 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -444,16 +444,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let pat_hir_id = self.lower_node_id(pattern.id); let node = match &pattern.kind { TyPatKind::Range(e1, e2, Spanned { node: end, span }) => hir::TyPatKind::Range( - e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)).unwrap_or_else(|| { - self.lower_ty_pat_range_end( - hir::LangItem::RangeMin, - span.shrink_to_lo(), - base_type, - ) - }), + e1.as_deref() + .map(|e| self.lower_anon_const_to_const_arg_and_alloc(e)) + .unwrap_or_else(|| { + self.lower_ty_pat_range_end( + hir::LangItem::RangeMin, + span.shrink_to_lo(), + base_type, + ) + }), e2.as_deref() .map(|e| match end { - RangeEnd::Included(..) => self.lower_anon_const_to_const_arg(e), + RangeEnd::Included(..) => self.lower_anon_const_to_const_arg_and_alloc(e), RangeEnd::Excluded => self.lower_excluded_range_end(e), }) .unwrap_or_else(|| { From e603055d89063ee3fea237f34deccbf333a6e91a Mon Sep 17 00:00:00 2001 From: delta17920 Date: Mon, 5 Jan 2026 16:20:36 +0000 Subject: [PATCH 1621/3801] Fix ICE when transmute Assume field is invalid --- compiler/rustc_transmute/src/lib.rs | 10 +++--- .../non_scalar_alignment_value.rs | 30 ++++++++++++++++ .../non_scalar_alignment_value.stderr | 35 +++++++++++++++++++ 3 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 tests/ui/transmutability/non_scalar_alignment_value.rs create mode 100644 tests/ui/transmutability/non_scalar_alignment_value.stderr diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 58cb2eb6556e..08ae561c972c 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -155,14 +155,14 @@ mod rustc { .enumerate() .find(|(_, field_def)| name == field_def.name) .unwrap_or_else(|| panic!("There were no fields named `{name}`.")); - fields[field_idx].to_leaf() == ScalarInt::TRUE + fields[field_idx].try_to_leaf().map(|leaf| leaf == ScalarInt::TRUE) }; Some(Self { - alignment: get_field(sym::alignment), - lifetimes: get_field(sym::lifetimes), - safety: get_field(sym::safety), - validity: get_field(sym::validity), + alignment: get_field(sym::alignment)?, + lifetimes: get_field(sym::lifetimes)?, + safety: get_field(sym::safety)?, + validity: get_field(sym::validity)?, }) } } diff --git a/tests/ui/transmutability/non_scalar_alignment_value.rs b/tests/ui/transmutability/non_scalar_alignment_value.rs new file mode 100644 index 000000000000..45c9e61fcfe2 --- /dev/null +++ b/tests/ui/transmutability/non_scalar_alignment_value.rs @@ -0,0 +1,30 @@ +#![feature(min_generic_const_args)] +//~^ WARN the feature `min_generic_const_args` is incomplete + +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, TransmuteFrom}; + struct Dst {} + fn is_maybe_transmutable() + where + Dst: TransmuteFrom< + (), + { + Assume { + alignment: Assume {}, + //~^ ERROR struct expression with missing field initialiser for `alignment` + //~| ERROR struct expression with missing field initialiser for `lifetimes` + //~| ERROR struct expression with missing field initialiser for `safety` + //~| ERROR struct expression with missing field initialiser for `validity` + lifetimes: const { true }, + safety: const { true }, + validity: const { true }, + } + }, + >, + { + } +} + +fn main() {} diff --git a/tests/ui/transmutability/non_scalar_alignment_value.stderr b/tests/ui/transmutability/non_scalar_alignment_value.stderr new file mode 100644 index 000000000000..06487dea82e0 --- /dev/null +++ b/tests/ui/transmutability/non_scalar_alignment_value.stderr @@ -0,0 +1,35 @@ +warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/non_scalar_alignment_value.rs:1:12 + | +LL | #![feature(min_generic_const_args)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: struct expression with missing field initialiser for `alignment` + --> $DIR/non_scalar_alignment_value.rs:15:32 + | +LL | alignment: Assume {}, + | ^^^^^^ + +error: struct expression with missing field initialiser for `lifetimes` + --> $DIR/non_scalar_alignment_value.rs:15:32 + | +LL | alignment: Assume {}, + | ^^^^^^ + +error: struct expression with missing field initialiser for `safety` + --> $DIR/non_scalar_alignment_value.rs:15:32 + | +LL | alignment: Assume {}, + | ^^^^^^ + +error: struct expression with missing field initialiser for `validity` + --> $DIR/non_scalar_alignment_value.rs:15:32 + | +LL | alignment: Assume {}, + | ^^^^^^ + +error: aborting due to 4 previous errors; 1 warning emitted + From 8233943e818eb570ba715ce935ad9764bba5af47 Mon Sep 17 00:00:00 2001 From: Redddy Date: Tue, 6 Jan 2026 14:11:22 +0900 Subject: [PATCH 1622/3801] Fix indent in rust code --- src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md b/src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md index 64a15b7f9aa8..33b685861df3 100644 --- a/src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md +++ b/src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md @@ -6,7 +6,7 @@ parse. ```rust fn func(arg: T) { - // ^ Unambig type position + // ^ Unambig type position let a: _ = arg; // ^ Unambig type position @@ -108,4 +108,4 @@ This has a number of benefits: [`ast::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.AnonConst.html [`hir::GenericArg::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Infer [`ast::ExprKind::Underscore`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.ExprKind.html#variant.Underscore -[`ast::Ty::Path(N)`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.TyKind.html#variant.Path \ No newline at end of file +[`ast::Ty::Path(N)`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.TyKind.html#variant.Path From dd948f96f30af19cf2cb7041de577ee1bf29bb9f Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 6 Jan 2026 09:42:42 +0800 Subject: [PATCH 1623/3801] Thread `--jobs` from `bootstrap` -> `compiletest` -> `run-make-support` --- src/bootstrap/src/core/build_steps/test.rs | 2 ++ src/tools/compiletest/src/common.rs | 5 +++++ src/tools/compiletest/src/directives/tests.rs | 1 + src/tools/compiletest/src/lib.rs | 10 +++++++++- src/tools/compiletest/src/runtest/run_make.rs | 3 +++ src/tools/compiletest/src/rustdoc_gui_test.rs | 1 + src/tools/run-make-support/src/env.rs | 14 ++++++++++++++ tests/run-make/compiletest-self-test/jobs/rmake.rs | 5 +++++ 8 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/run-make/compiletest-self-test/jobs/rmake.rs diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index a3c13fc4b095..4008ede6c0d4 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2265,6 +2265,8 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--with-std-remap-debuginfo"); } + cmd.arg("--jobs").arg(builder.jobs().to_string()); + let mut llvm_components_passed = false; let mut copts_passed = false; if builder.config.llvm_enabled(test_compiler.host) { diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 5563abe92a80..800ce4f3088e 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -715,6 +715,11 @@ pub struct Config { pub override_codegen_backend: Option, /// Whether to ignore `//@ ignore-backends`. pub bypass_ignore_backends: bool, + + /// Number of parallel jobs configured for the build. + /// + /// This is forwarded from bootstrap's `jobs` configuration. + pub jobs: u32, } impl Config { diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 0d3777b8e60c..71343080cfa2 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -225,6 +225,7 @@ impl ConfigBuilder { "--nightly-branch=", "--git-merge-commit-email=", "--minicore-path=", + "--jobs=0", ]; let mut args: Vec = args.iter().map(ToString::to_string).collect(); diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index a64c7850aad4..997f570393f2 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -218,7 +218,8 @@ fn parse_config(args: Vec) -> Config { "the codegen backend to use instead of the default one", "CODEGEN BACKEND [NAME | PATH]", ) - .optflag("", "bypass-ignore-backends", "ignore `//@ ignore-backends` directives"); + .optflag("", "bypass-ignore-backends", "ignore `//@ ignore-backends` directives") + .reqopt("", "jobs", "number of parallel jobs bootstrap was configured with", "JOBS"); let (argv0, args_) = args.split_first().unwrap(); if args.len() == 1 || args[1] == "-h" || args[1] == "--help" { @@ -363,6 +364,11 @@ fn parse_config(args: Vec) -> Config { let build_test_suite_root = opt_path(matches, "build-test-suite-root"); assert!(build_test_suite_root.starts_with(&build_root)); + let jobs = match matches.opt_str("jobs") { + Some(jobs) => jobs.parse::().expect("expected `--jobs` to be an `u32`"), + None => panic!("`--jobs` is required"), + }; + Config { bless: matches.opt_present("bless"), fail_fast: matches.opt_present("fail-fast") @@ -481,6 +487,8 @@ fn parse_config(args: Vec) -> Config { default_codegen_backend, override_codegen_backend, bypass_ignore_backends: matches.opt_present("bypass-ignore-backends"), + + jobs, } } diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index ba3a12347367..4eb8f91fe894 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -249,6 +249,9 @@ impl TestCx<'_> { cmd.env("__STD_REMAP_DEBUGINFO_ENABLED", "1"); } + // Used for `run_make_support::env::jobs`. + cmd.env("__BOOTSTRAP_JOBS", self.config.jobs.to_string()); + // We don't want RUSTFLAGS set from the outside to interfere with // compiler flags set in the test cases: cmd.env_remove("RUSTFLAGS"); diff --git a/src/tools/compiletest/src/rustdoc_gui_test.rs b/src/tools/compiletest/src/rustdoc_gui_test.rs index 4454ffb1f59e..06b66ef9fd0a 100644 --- a/src/tools/compiletest/src/rustdoc_gui_test.rs +++ b/src/tools/compiletest/src/rustdoc_gui_test.rs @@ -139,5 +139,6 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { default_codegen_backend: CodegenBackend::Llvm, override_codegen_backend: None, bypass_ignore_backends: Default::default(), + jobs: Default::default(), } } diff --git a/src/tools/run-make-support/src/env.rs b/src/tools/run-make-support/src/env.rs index 507d51471df0..65b6d3db85d5 100644 --- a/src/tools/run-make-support/src/env.rs +++ b/src/tools/run-make-support/src/env.rs @@ -49,3 +49,17 @@ pub fn set_current_dir>(dir: P) { std::env::set_current_dir(dir.as_ref()) .expect(&format!("could not set current directory to \"{}\"", dir.as_ref().display())); } + +/// Number of parallel jobs bootstrap was configured with. +/// +/// This may fallback to [`std::thread::available_parallelism`] when no explicit jobs count has been +/// configured. Refer to bootstrap's jobs fallback logic. +#[track_caller] +pub fn jobs() -> u32 { + std::env::var_os("__BOOTSTRAP_JOBS") + .expect("`__BOOTSTRAP_JOBS` must be set by `compiletest`") + .to_str() + .expect("`__BOOTSTRAP_JOBS` must be a valid string") + .parse::() + .expect("`__BOOTSTRAP_JOBS` must be a valid `u32`") +} diff --git a/tests/run-make/compiletest-self-test/jobs/rmake.rs b/tests/run-make/compiletest-self-test/jobs/rmake.rs new file mode 100644 index 000000000000..d21b44ada1c3 --- /dev/null +++ b/tests/run-make/compiletest-self-test/jobs/rmake.rs @@ -0,0 +1,5 @@ +//! Very basic smoke test to make sure `run_make_support::env::jobs` at least does not panic. + +fn main() { + println!("{}", run_make_support::env::jobs()); +} From 03fb7eecedf37b28a1feab1383c917d9e91dfaef Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 26 Dec 2025 20:54:15 +0100 Subject: [PATCH 1624/3801] Create a `rustc_ast` representation for parsed attributes --- compiler/rustc_ast/src/ast.rs | 45 ++++++++++++++++++- compiler/rustc_ast/src/attr/mod.rs | 33 +++++++++++--- compiler/rustc_ast/src/visit.rs | 2 + compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- .../rustc_attr_parsing/src/attributes/cfg.rs | 10 ++--- compiler/rustc_attr_parsing/src/parser.rs | 4 +- .../rustc_attr_parsing/src/validate_attr.rs | 4 +- compiler/rustc_builtin_macros/src/autodiff.rs | 14 +++--- .../src/deriving/generic/mod.rs | 41 +++++++++-------- compiler/rustc_expand/src/expand.rs | 4 +- compiler/rustc_parse/src/parser/attr.rs | 4 +- 11 files changed, 115 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7c922417ee29..571e840795b5 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -34,6 +34,7 @@ use rustc_span::source_map::{Spanned, respan}; use rustc_span::{ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym}; use thin_vec::{ThinVec, thin_vec}; +use crate::attr::data_structures::CfgEntry; pub use crate::format::*; use crate::token::{self, CommentKind, Delimiter}; use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream}; @@ -3390,7 +3391,7 @@ impl NormalAttr { item: AttrItem { unsafety: Safety::Default, path: Path::from_ident(ident), - args: AttrArgs::Empty, + args: AttrItemKind::Unparsed(AttrArgs::Empty), tokens: None, }, tokens: None, @@ -3402,11 +3403,51 @@ impl NormalAttr { pub struct AttrItem { pub unsafety: Safety, pub path: Path, - pub args: AttrArgs, + pub args: AttrItemKind, // Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`. pub tokens: Option, } +/// Some attributes are stored in a parsed form, for performance reasons. +/// Their arguments don't have to be reparsed everytime they're used +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub enum AttrItemKind { + Parsed(EarlyParsedAttribute), + Unparsed(AttrArgs), +} + +impl AttrItemKind { + pub fn unparsed(self) -> Option { + match self { + AttrItemKind::Unparsed(args) => Some(args), + AttrItemKind::Parsed(_) => None, + } + } + + pub fn unparsed_ref(&self) -> Option<&AttrArgs> { + match self { + AttrItemKind::Unparsed(args) => Some(args), + AttrItemKind::Parsed(_) => None, + } + } + + pub fn span(&self) -> Option { + match self { + AttrItemKind::Unparsed(args) => args.span(), + AttrItemKind::Parsed(_) => None, + } + } +} + +/// Some attributes are stored in parsed form in the AST. +/// This is done for performance reasons, so the attributes don't need to be reparsed on every use. +/// +/// Currently all early parsed attributes are excluded from pretty printing at rustc_ast_pretty::pprust::state::print_attribute_inline. +/// When adding new early parsed attributes, consider whether they should be pretty printed. +#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum EarlyParsedAttribute { +} + impl AttrItem { pub fn is_valid_for_outer_style(&self) -> bool { self.path == sym::cfg_attr diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index c0ed6e24e222..6ecba865c815 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,5 +1,8 @@ //! Functions dealing with attributes and meta items. +pub mod data_structures; +pub mod version; + use std::fmt::Debug; use std::sync::atomic::{AtomicU32, Ordering}; @@ -8,6 +11,7 @@ use rustc_span::{Ident, Span, Symbol, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::{ThinVec, thin_vec}; +use crate::AttrItemKind; use crate::ast::{ AttrArgs, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NormalAttr, Path, @@ -62,6 +66,15 @@ impl Attribute { } } + /// Replaces the arguments of this attribute with new arguments `AttrItemKind`. + /// This is useful for making this attribute into a trace attribute, and should otherwise be avoided. + pub fn replace_args(&mut self, new_args: AttrItemKind) { + match &mut self.kind { + AttrKind::Normal(normal) => normal.item.args = new_args, + AttrKind::DocComment(..) => panic!("unexpected doc comment"), + } + } + pub fn unwrap_normal_item(self) -> AttrItem { match self.kind { AttrKind::Normal(normal) => normal.item, @@ -77,7 +90,7 @@ impl AttributeExt for Attribute { fn value_span(&self) -> Option { match &self.kind { - AttrKind::Normal(normal) => match &normal.item.args { + AttrKind::Normal(normal) => match &normal.item.args.unparsed_ref()? { AttrArgs::Eq { expr, .. } => Some(expr.span), _ => None, }, @@ -147,7 +160,7 @@ impl AttributeExt for Attribute { fn is_word(&self) -> bool { if let AttrKind::Normal(normal) = &self.kind { - matches!(normal.item.args, AttrArgs::Empty) + matches!(normal.item.args, AttrItemKind::Unparsed(AttrArgs::Empty)) } else { false } @@ -303,7 +316,7 @@ impl AttrItem { } pub fn meta_item_list(&self) -> Option> { - match &self.args { + match &self.args.unparsed_ref()? { AttrArgs::Delimited(args) if args.delim == Delimiter::Parenthesis => { MetaItemKind::list_from_tokens(args.tokens.clone()) } @@ -324,7 +337,7 @@ impl AttrItem { /// #[attr("value")] /// ``` fn value_str(&self) -> Option { - match &self.args { + match &self.args.unparsed_ref()? { AttrArgs::Eq { expr, .. } => match expr.kind { ExprKind::Lit(token_lit) => { LitKind::from_token_lit(token_lit).ok().and_then(|lit| lit.str()) @@ -348,7 +361,7 @@ impl AttrItem { /// #[attr("value")] /// ``` fn value_span(&self) -> Option { - match &self.args { + match &self.args.unparsed_ref()? { AttrArgs::Eq { expr, .. } => Some(expr.span), AttrArgs::Delimited(_) | AttrArgs::Empty => None, } @@ -364,7 +377,7 @@ impl AttrItem { } pub fn meta_kind(&self) -> Option { - MetaItemKind::from_attr_args(&self.args) + MetaItemKind::from_attr_args(self.args.unparsed_ref()?) } } @@ -699,7 +712,13 @@ fn mk_attr( args: AttrArgs, span: Span, ) -> Attribute { - mk_attr_from_item(g, AttrItem { unsafety, path, args, tokens: None }, None, style, span) + mk_attr_from_item( + g, + AttrItem { unsafety, path, args: AttrItemKind::Unparsed(args), tokens: None }, + None, + style, + span, + ) } pub fn mk_attr_from_item( diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index d122adfdf966..83b751fbde90 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -366,6 +366,7 @@ macro_rules! common_visitor_and_walkers { crate::token::LitKind, crate::tokenstream::LazyAttrTokenStream, crate::tokenstream::TokenStream, + EarlyParsedAttribute, Movability, Mutability, Pinnedness, @@ -457,6 +458,7 @@ macro_rules! common_visitor_and_walkers { ModSpans, MutTy, NormalAttr, + AttrItemKind, Parens, ParenthesizedArgs, PatFieldsRest, diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 1aa08dfd3d5e..0cf0eae821e9 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -694,7 +694,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } ast::Safety::Default | ast::Safety::Safe(_) => {} } - match &item.args { + match &item.args.unparsed_ref().expect("Parsed attributes are never printed") { AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self.print_mac_common( Some(MacHeader::Path(&item.path)), false, diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 66f0f8d391f6..ccf0a394afd0 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -294,11 +294,9 @@ pub fn parse_cfg_attr( sess: &Session, features: Option<&Features>, ) -> Option<(CfgEntry, Vec<(AttrItem, Span)>)> { - match cfg_attr.get_normal_item().args { - ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens }) - if !tokens.is_empty() => - { - check_cfg_attr_bad_delim(&sess.psess, dspan, delim); + match cfg_attr.get_normal_item().args.unparsed_ref().unwrap() { + ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, tokens }) if !tokens.is_empty() => { + check_cfg_attr_bad_delim(&sess.psess, *dspan, *delim); match parse_in(&sess.psess, tokens.clone(), "`cfg_attr` input", |p| { parse_cfg_attr_internal(p, sess, features, cfg_attr) }) { @@ -322,7 +320,7 @@ pub fn parse_cfg_attr( } _ => { let (span, reason) = if let ast::AttrArgs::Delimited(ast::DelimArgs { dspan, .. }) = - cfg_attr.get_normal_item().args + cfg_attr.get_normal_item().args.unparsed_ref()? { (dspan.entire(), AttributeParseErrorReason::ExpectedAtLeastOneArgument) } else { diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 39419dfa4ed8..d79579fdf0b7 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -122,10 +122,10 @@ impl ArgParser { } if args.delim != Delimiter::Parenthesis { - psess.dcx().emit_err(MetaBadDelim { + should_emit.emit_err(psess.dcx().create_err(MetaBadDelim { span: args.dspan.entire(), sugg: MetaBadDelimSugg { open: args.dspan.open, close: args.dspan.close }, - }); + })); return None; } diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index 4879646a1107..f56e85b11061 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -48,7 +48,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { } _ => { let attr_item = attr.get_normal_item(); - if let AttrArgs::Eq { .. } = attr_item.args { + if let AttrArgs::Eq { .. } = attr_item.args.unparsed_ref().unwrap() { // All key-value attributes are restricted to meta-item syntax. match parse_meta(psess, attr) { Ok(_) => {} @@ -67,7 +67,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met unsafety: item.unsafety, span: attr.span, path: item.path.clone(), - kind: match &item.args { + kind: match &item.args.unparsed_ref().unwrap() { AttrArgs::Empty => MetaItemKind::Word, AttrArgs::Delimited(DelimArgs { dspan, delim, tokens }) => { check_meta_bad_delim(psess, *dspan, *delim); diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 39abb66df30c..95191b82ff3f 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -358,7 +358,7 @@ mod llvm_enzyme { let inline_item = ast::AttrItem { unsafety: ast::Safety::Default, path: ast::Path::from_ident(Ident::with_dummy_span(sym::inline)), - args: ast::AttrArgs::Delimited(never_arg), + args: rustc_ast::ast::AttrItemKind::Unparsed(ast::AttrArgs::Delimited(never_arg)), tokens: None, }; let inline_never_attr = Box::new(ast::NormalAttr { item: inline_item, tokens: None }); @@ -421,11 +421,13 @@ mod llvm_enzyme { } }; // Now update for d_fn - rustc_ad_attr.item.args = rustc_ast::AttrArgs::Delimited(rustc_ast::DelimArgs { - dspan: DelimSpan::dummy(), - delim: rustc_ast::token::Delimiter::Parenthesis, - tokens: ts, - }); + rustc_ad_attr.item.args = rustc_ast::ast::AttrItemKind::Unparsed( + rustc_ast::AttrArgs::Delimited(rustc_ast::DelimArgs { + dspan: DelimSpan::dummy(), + delim: rustc_ast::token::Delimiter::Parenthesis, + tokens: ts, + }), + ); let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id(); let d_attr = outer_normal_attr(&rustc_ad_attr, new_id, span); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index bb6557802ece..7c84530abbee 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -807,24 +807,29 @@ impl<'a> TraitDef<'a> { rustc_ast::AttrItem { unsafety: Safety::Default, path: rustc_const_unstable, - args: AttrArgs::Delimited(DelimArgs { - dspan: DelimSpan::from_single(self.span), - delim: rustc_ast::token::Delimiter::Parenthesis, - tokens: [ - TokenKind::Ident(sym::feature, IdentIsRaw::No), - TokenKind::Eq, - TokenKind::lit(LitKind::Str, sym::derive_const, None), - TokenKind::Comma, - TokenKind::Ident(sym::issue, IdentIsRaw::No), - TokenKind::Eq, - TokenKind::lit(LitKind::Str, sym::derive_const_issue, None), - ] - .into_iter() - .map(|kind| { - TokenTree::Token(Token { kind, span: self.span }, Spacing::Alone) - }) - .collect(), - }), + args: rustc_ast::ast::AttrItemKind::Unparsed(AttrArgs::Delimited( + DelimArgs { + dspan: DelimSpan::from_single(self.span), + delim: rustc_ast::token::Delimiter::Parenthesis, + tokens: [ + TokenKind::Ident(sym::feature, IdentIsRaw::No), + TokenKind::Eq, + TokenKind::lit(LitKind::Str, sym::derive_const, None), + TokenKind::Comma, + TokenKind::Ident(sym::issue, IdentIsRaw::No), + TokenKind::Eq, + TokenKind::lit(LitKind::Str, sym::derive_const_issue, None), + ] + .into_iter() + .map(|kind| { + TokenTree::Token( + Token { kind, span: self.span }, + Spacing::Alone, + ) + }) + .collect(), + }, + )), tokens: None, }, self.span, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 52b7339e0140..8102f8e6dac7 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -813,10 +813,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let attr_item = attr.get_normal_item(); let safety = attr_item.unsafety; - if let AttrArgs::Eq { .. } = attr_item.args { + if let AttrArgs::Eq { .. } = attr_item.args.unparsed_ref().unwrap() { self.cx.dcx().emit_err(UnsupportedKeyValue { span }); } - let inner_tokens = attr_item.args.inner_tokens(); + let inner_tokens = attr_item.args.unparsed_ref().unwrap().inner_tokens(); match expander.expand_with_safety(self.cx, safety, span, inner_tokens, tokens) { Ok(tok_result) => { let fragment = self.parse_ast_fragment( diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 63109c7ba5cb..1cb9a1b65d65 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -1,7 +1,7 @@ use rustc_ast as ast; use rustc_ast::token::{self, MetaVarKind}; use rustc_ast::tokenstream::ParserRange; -use rustc_ast::{Attribute, attr}; +use rustc_ast::{AttrItemKind, Attribute, attr}; use rustc_errors::codes::*; use rustc_errors::{Diag, PResult}; use rustc_span::{BytePos, Span}; @@ -313,7 +313,7 @@ impl<'a> Parser<'a> { this.expect(exp!(CloseParen))?; } Ok(( - ast::AttrItem { unsafety, path, args, tokens: None }, + ast::AttrItem { unsafety, path, args: AttrItemKind::Unparsed(args), tokens: None }, Trailing::No, UsePreAttrPos::No, )) From 5590fc034c2c965f20844841e9e2a7382b25a0fb Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 26 Dec 2025 20:56:42 +0100 Subject: [PATCH 1625/3801] Make `cfg` and `cfg_attr` trace attributes into early parsed attributes --- compiler/rustc_ast/src/ast.rs | 2 + .../rustc_ast/src/attr/data_structures.rs | 101 ++++++++++++++++++ .../src => rustc_ast/src/attr}/version.rs | 16 +-- .../rustc_attr_parsing/src/early_parsed.rs | 53 +++++++++ compiler/rustc_attr_parsing/src/interface.rs | 44 +++++--- compiler/rustc_attr_parsing/src/lib.rs | 1 + compiler/rustc_attr_parsing/src/safety.rs | 7 +- compiler/rustc_expand/src/config.rs | 8 +- compiler/rustc_expand/src/expand.rs | 57 ++++++---- .../rustc_hir/src/attrs/data_structures.rs | 85 ++------------- .../rustc_hir/src/attrs/encode_cross_crate.rs | 2 + .../rustc_hir/src/attrs/pretty_printing.rs | 4 + compiler/rustc_hir/src/hir.rs | 1 + compiler/rustc_hir/src/lib.rs | 3 +- compiler/rustc_passes/src/check_attr.rs | 6 +- 15 files changed, 247 insertions(+), 143 deletions(-) create mode 100644 compiler/rustc_ast/src/attr/data_structures.rs rename compiler/{rustc_hir/src => rustc_ast/src/attr}/version.rs (75%) create mode 100644 compiler/rustc_attr_parsing/src/early_parsed.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 571e840795b5..d4407dbf7be7 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3446,6 +3446,8 @@ impl AttrItemKind { /// When adding new early parsed attributes, consider whether they should be pretty printed. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub enum EarlyParsedAttribute { + CfgTrace(CfgEntry), + CfgAttrTrace, } impl AttrItem { diff --git a/compiler/rustc_ast/src/attr/data_structures.rs b/compiler/rustc_ast/src/attr/data_structures.rs new file mode 100644 index 000000000000..2eab91801cd6 --- /dev/null +++ b/compiler/rustc_ast/src/attr/data_structures.rs @@ -0,0 +1,101 @@ +use std::fmt; + +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +use rustc_span::{Span, Symbol}; +use thin_vec::ThinVec; + +use crate::attr::version::RustcVersion; + +#[derive(Encodable, Decodable, Clone, Debug, PartialEq, Eq, Hash, HashStable_Generic)] +pub enum CfgEntry { + All(ThinVec, Span), + Any(ThinVec, Span), + Not(Box, Span), + Bool(bool, Span), + NameValue { name: Symbol, value: Option, span: Span }, + Version(Option, Span), +} + +impl CfgEntry { + pub fn lower_spans(&mut self, lower_span: impl Copy + Fn(Span) -> Span) { + match self { + CfgEntry::All(subs, span) | CfgEntry::Any(subs, span) => { + *span = lower_span(*span); + subs.iter_mut().for_each(|sub| sub.lower_spans(lower_span)); + } + CfgEntry::Not(sub, span) => { + *span = lower_span(*span); + sub.lower_spans(lower_span); + } + CfgEntry::Bool(_, span) + | CfgEntry::NameValue { span, .. } + | CfgEntry::Version(_, span) => { + *span = lower_span(*span); + } + } + } + + pub fn span(&self) -> Span { + let (Self::All(_, span) + | Self::Any(_, span) + | Self::Not(_, span) + | Self::Bool(_, span) + | Self::NameValue { span, .. } + | Self::Version(_, span)) = self; + *span + } + + /// Same as `PartialEq` but doesn't check spans and ignore order of cfgs. + pub fn is_equivalent_to(&self, other: &Self) -> bool { + match (self, other) { + (Self::All(a, _), Self::All(b, _)) | (Self::Any(a, _), Self::Any(b, _)) => { + a.len() == b.len() && a.iter().all(|a| b.iter().any(|b| a.is_equivalent_to(b))) + } + (Self::Not(a, _), Self::Not(b, _)) => a.is_equivalent_to(b), + (Self::Bool(a, _), Self::Bool(b, _)) => a == b, + ( + Self::NameValue { name: name1, value: value1, .. }, + Self::NameValue { name: name2, value: value2, .. }, + ) => name1 == name2 && value1 == value2, + (Self::Version(a, _), Self::Version(b, _)) => a == b, + _ => false, + } + } +} + +impl fmt::Display for CfgEntry { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fn write_entries( + name: &str, + entries: &[CfgEntry], + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + write!(f, "{name}(")?; + for (nb, entry) in entries.iter().enumerate() { + if nb != 0 { + f.write_str(", ")?; + } + entry.fmt(f)?; + } + f.write_str(")") + } + match self { + Self::All(entries, _) => write_entries("all", entries, f), + Self::Any(entries, _) => write_entries("any", entries, f), + Self::Not(entry, _) => write!(f, "not({entry})"), + Self::Bool(value, _) => write!(f, "{value}"), + Self::NameValue { name, value, .. } => { + match value { + // We use `as_str` and debug display to have characters escaped and `"` + // characters surrounding the string. + Some(value) => write!(f, "{name} = {:?}", value.as_str()), + None => write!(f, "{name}"), + } + } + Self::Version(version, _) => match version { + Some(version) => write!(f, "{version}"), + None => Ok(()), + }, + } + } +} diff --git a/compiler/rustc_hir/src/version.rs b/compiler/rustc_ast/src/attr/version.rs similarity index 75% rename from compiler/rustc_hir/src/version.rs rename to compiler/rustc_ast/src/attr/version.rs index 03182088d4c0..59deee40ae28 100644 --- a/compiler/rustc_hir/src/version.rs +++ b/compiler/rustc_ast/src/attr/version.rs @@ -1,16 +1,10 @@ -use std::borrow::Cow; use std::fmt::{self, Display}; use std::sync::OnceLock; -use rustc_error_messages::{DiagArgValue, IntoDiagArg}; -use rustc_macros::{ - BlobDecodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version, -}; - -use crate::attrs::PrintAttribute; +use rustc_macros::{BlobDecodable, Encodable, HashStable_Generic, current_rustc_version}; #[derive(Encodable, BlobDecodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[derive(HashStable_Generic, PrintAttribute)] +#[derive(HashStable_Generic)] pub struct RustcVersion { pub major: u16, pub minor: u16, @@ -47,9 +41,3 @@ impl Display for RustcVersion { write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch) } } - -impl IntoDiagArg for RustcVersion { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(self.to_string())) - } -} diff --git a/compiler/rustc_attr_parsing/src/early_parsed.rs b/compiler/rustc_attr_parsing/src/early_parsed.rs new file mode 100644 index 000000000000..6a33cb38edf9 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/early_parsed.rs @@ -0,0 +1,53 @@ +use rustc_ast::EarlyParsedAttribute; +use rustc_ast::attr::data_structures::CfgEntry; +use rustc_hir::Attribute; +use rustc_hir::attrs::AttributeKind; +use rustc_span::{Span, Symbol, sym}; +use thin_vec::ThinVec; + +pub(crate) const EARLY_PARSED_ATTRIBUTES: &[&[Symbol]] = + &[&[sym::cfg_trace], &[sym::cfg_attr_trace]]; + +/// This struct contains the state necessary to convert early parsed attributes to hir attributes +/// The only conversion that really happens here is that multiple early parsed attributes are +/// merged into a single hir attribute, representing their combined state. +/// FIXME: We should make this a nice and extendable system if this is going to be used more often +#[derive(Default)] +pub(crate) struct EarlyParsedState { + /// Attribute state for `#[cfg]` trace attributes + cfg_trace: ThinVec<(CfgEntry, Span)>, + + /// Attribute state for `#[cfg_attr]` trace attributes + /// The arguments of these attributes is no longer relevant for any later passes, only their presence. + /// So we discard the arguments here. + cfg_attr_trace: bool, +} + +impl EarlyParsedState { + pub(crate) fn accept_early_parsed_attribute( + &mut self, + attr_span: Span, + lower_span: impl Copy + Fn(Span) -> Span, + parsed: &EarlyParsedAttribute, + ) { + match parsed { + EarlyParsedAttribute::CfgTrace(cfg) => { + let mut cfg = cfg.clone(); + cfg.lower_spans(lower_span); + self.cfg_trace.push((cfg, attr_span)); + } + EarlyParsedAttribute::CfgAttrTrace => { + self.cfg_attr_trace = true; + } + } + } + + pub(crate) fn finalize_early_parsed_attributes(self, attributes: &mut Vec) { + if !self.cfg_trace.is_empty() { + attributes.push(Attribute::Parsed(AttributeKind::CfgTrace(self.cfg_trace))); + } + if self.cfg_attr_trace { + attributes.push(Attribute::Parsed(AttributeKind::CfgAttrTrace)); + } + } +} diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 91596ff0de60..e38fffa6587c 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -2,7 +2,7 @@ use std::convert::identity; use rustc_ast as ast; use rustc_ast::token::DocFragmentKind; -use rustc_ast::{AttrStyle, NodeId, Safety}; +use rustc_ast::{AttrItemKind, AttrStyle, NodeId, Safety}; use rustc_errors::DiagCtxtHandle; use rustc_feature::{AttributeTemplate, Features}; use rustc_hir::attrs::AttributeKind; @@ -13,6 +13,7 @@ use rustc_session::lint::BuiltinLintDiag; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage}; +use crate::early_parsed::{EARLY_PARSED_ATTRIBUTES, EarlyParsedState}; use crate::parser::{ArgParser, PathParser, RefPathParser}; use crate::session_diagnostics::ParsedDescription; use crate::{Early, Late, OmitDoc, ShouldEmit}; @@ -146,8 +147,12 @@ impl<'sess> AttributeParser<'sess, Early> { normal_attr.item.path.segments.iter().map(|seg| seg.ident.name).collect::>(); let path = AttrPath::from_ast(&normal_attr.item.path, identity); - let args = - ArgParser::from_attr_args(&normal_attr.item.args, &parts, &sess.psess, emit_errors)?; + let args = ArgParser::from_attr_args( + &normal_attr.item.args.unparsed_ref().unwrap(), + &parts, + &sess.psess, + emit_errors, + )?; Self::parse_single_args( sess, attr.span, @@ -263,12 +268,12 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { target_id: S::Id, target: Target, omit_doc: OmitDoc, - lower_span: impl Copy + Fn(Span) -> Span, mut emit_lint: impl FnMut(AttributeLint), ) -> Vec { let mut attributes = Vec::new(); let mut attr_paths: Vec> = Vec::new(); + let mut early_parsed_state = EarlyParsedState::default(); for attr in attrs { // If we're only looking for a single attribute, skip all the ones we don't care about. @@ -288,6 +293,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { continue; } + let attr_span = lower_span(attr.span); match &attr.kind { ast::AttrKind::DocComment(comment_kind, symbol) => { if omit_doc == OmitDoc::Skip { @@ -297,7 +303,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attributes.push(Attribute::Parsed(AttributeKind::DocComment { style: attr.style, kind: DocFragmentKind::Sugared(*comment_kind), - span: lower_span(attr.span), + span: attr_span, comment: *symbol, })) } @@ -305,6 +311,15 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attr_paths.push(PathParser(&n.item.path)); let attr_path = AttrPath::from_ast(&n.item.path, lower_span); + let args = match &n.item.args { + AttrItemKind::Unparsed(args) => args, + AttrItemKind::Parsed(parsed) => { + early_parsed_state + .accept_early_parsed_attribute(attr_span, lower_span, parsed); + continue; + } + }; + self.check_attribute_safety( &attr_path, lower_span(n.item.span()), @@ -318,7 +333,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { if let Some(accepts) = S::parsers().accepters.get(parts.as_slice()) { let Some(args) = ArgParser::from_attr_args( - &n.item.args, + args, &parts, &self.sess.psess, self.stage.should_emit(), @@ -351,7 +366,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attributes.push(Attribute::Parsed(AttributeKind::DocComment { style: attr.style, kind: DocFragmentKind::Raw(nv.value_span), - span: attr.span, + span: attr_span, comment, })); continue; @@ -365,7 +380,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { target_id, emit_lint: &mut emit_lint, }, - attr_span: lower_span(attr.span), + attr_span, inner_span: lower_span(n.item.span()), attr_style: attr.style, parsed_description: ParsedDescription::Attribute, @@ -396,17 +411,18 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attributes.push(Attribute::Unparsed(Box::new(AttrItem { path: attr_path.clone(), - args: self.lower_attr_args(&n.item.args, lower_span), + args: self + .lower_attr_args(n.item.args.unparsed_ref().unwrap(), lower_span), id: HashIgnoredAttrId { attr_id: attr.id }, style: attr.style, - span: lower_span(attr.span), + span: attr_span, }))); } } } } - let mut parsed_attributes = Vec::new(); + early_parsed_state.finalize_early_parsed_attributes(&mut attributes); for f in &S::parsers().finalizers { if let Some(attr) = f(&mut FinalizeContext { shared: SharedContext { @@ -417,18 +433,16 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { }, all_attrs: &attr_paths, }) { - parsed_attributes.push(Attribute::Parsed(attr)); + attributes.push(Attribute::Parsed(attr)); } } - attributes.extend(parsed_attributes); - attributes } /// Returns whether there is a parser for an attribute with this name pub fn is_parsed_attribute(path: &[Symbol]) -> bool { - Late::parsers().accepters.contains_key(path) + Late::parsers().accepters.contains_key(path) || EARLY_PARSED_ATTRIBUTES.contains(&path) } fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs { diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 411b4dd75e66..349e6c234520 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -99,6 +99,7 @@ mod interface; /// like lists or name-value pairs. pub mod parser; +mod early_parsed; mod safety; mod session_diagnostics; mod target_checking; diff --git a/compiler/rustc_attr_parsing/src/safety.rs b/compiler/rustc_attr_parsing/src/safety.rs index 68aeca2bbda9..9fca57f88025 100644 --- a/compiler/rustc_attr_parsing/src/safety.rs +++ b/compiler/rustc_attr_parsing/src/safety.rs @@ -4,7 +4,7 @@ use rustc_hir::AttrPath; use rustc_hir::lints::{AttributeLint, AttributeLintKind}; use rustc_session::lint::LintId; use rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE; -use rustc_span::{Span, sym}; +use rustc_span::Span; use crate::context::Stage; use crate::{AttributeParser, ShouldEmit}; @@ -23,11 +23,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { } let name = (attr_path.segments.len() == 1).then_some(attr_path.segments[0]); - if let Some(name) = name - && [sym::cfg_trace, sym::cfg_attr_trace].contains(&name) - { - return; - } // FIXME: We should retrieve this information from the attribute parsers instead of from `BUILTIN_ATTRIBUTE_MAP` let builtin_attr_info = name.and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)); diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 492c845df171..28f711f362bd 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -7,8 +7,8 @@ use rustc_ast::tokenstream::{ AttrTokenStream, AttrTokenTree, LazyAttrTokenStream, Spacing, TokenTree, }; use rustc_ast::{ - self as ast, AttrKind, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner, - NodeId, NormalAttr, + self as ast, AttrItemKind, AttrKind, AttrStyle, Attribute, EarlyParsedAttribute, HasAttrs, + HasTokens, MetaItem, MetaItemInner, NodeId, NormalAttr, }; use rustc_attr_parsing as attr; use rustc_attr_parsing::{ @@ -288,7 +288,9 @@ impl<'a> StripUnconfigured<'a> { pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec { // A trace attribute left in AST in place of the original `cfg_attr` attribute. // It can later be used by lints or other diagnostics. - let trace_attr = attr_into_trace(cfg_attr.clone(), sym::cfg_attr_trace); + let mut trace_attr = cfg_attr.clone(); + trace_attr.replace_args(AttrItemKind::Parsed(EarlyParsedAttribute::CfgAttrTrace)); + let trace_attr = attr_into_trace(trace_attr, sym::cfg_attr_trace); let Some((cfg_predicate, expanded_attrs)) = rustc_attr_parsing::parse_cfg_attr(cfg_attr, &self.sess, self.features) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 8102f8e6dac7..c130d9f59940 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -7,12 +7,16 @@ use rustc_ast::mut_visit::*; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list}; use rustc_ast::{ - self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, DUMMY_NODE_ID, - ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner, - MetaItemKind, ModKind, NodeId, PatKind, StmtKind, TyKind, token, + self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrItemKind, AttrStyle, AttrVec, + DUMMY_NODE_ID, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline, + ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId, PatKind, StmtKind, + TyKind, token, }; use rustc_ast_pretty::pprust; -use rustc_attr_parsing::{AttributeParser, Early, EvalConfigResult, ShouldEmit, validate_attr}; +use rustc_attr_parsing::{ + AttributeParser, CFG_TEMPLATE, Early, EvalConfigResult, ShouldEmit, eval_config_entry, + parse_cfg, validate_attr, +}; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::PResult; @@ -2188,21 +2192,17 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { && !AttributeParser::::is_parsed_attribute(&attr.path()) { let attr_name = attr.name().unwrap(); - // `#[cfg]` and `#[cfg_attr]` are special - they are - // eagerly evaluated. - if attr_name != sym::cfg_trace && attr_name != sym::cfg_attr_trace { - self.cx.sess.psess.buffer_lint( - UNUSED_ATTRIBUTES, - attr.span, - self.cx.current_expansion.lint_node_id, - crate::errors::UnusedBuiltinAttribute { - attr_name, - macro_name: pprust::path_to_string(&call.path), - invoc_span: call.path.span, - attr_span: attr.span, - }, - ); - } + self.cx.sess.psess.buffer_lint( + UNUSED_ATTRIBUTES, + attr.span, + self.cx.current_expansion.lint_node_id, + crate::errors::UnusedBuiltinAttribute { + attr_name, + macro_name: pprust::path_to_string(&call.path), + invoc_span: call.path.span, + attr_span: attr.span, + }, + ); } } } @@ -2213,11 +2213,26 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { attr: ast::Attribute, pos: usize, ) -> EvalConfigResult { - let res = self.cfg().cfg_true(&attr, ShouldEmit::ErrorsAndLints); + let Some(cfg) = AttributeParser::parse_single( + self.cfg().sess, + &attr, + attr.span, + self.cfg().lint_node_id, + self.cfg().features, + ShouldEmit::ErrorsAndLints, + parse_cfg, + &CFG_TEMPLATE, + ) else { + // Cfg attribute was not parsable, give up + return EvalConfigResult::True; + }; + + let res = eval_config_entry(self.cfg().sess, &cfg); if res.as_bool() { // A trace attribute left in AST in place of the original `cfg` attribute. // It can later be used by lints or other diagnostics. - let trace_attr = attr_into_trace(attr, sym::cfg_trace); + let mut trace_attr = attr_into_trace(attr, sym::cfg_trace); + trace_attr.replace_args(AttrItemKind::Parsed(EarlyParsedAttribute::CfgTrace(cfg))); node.visit_attrs(|attrs| attrs.insert(pos, trace_attr)); } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index f418c391ece7..fa8998f0546d 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1,9 +1,9 @@ use std::borrow::Cow; -use std::fmt; use std::path::PathBuf; pub use ReprAttr::*; use rustc_abi::Align; +pub use rustc_ast::attr::data_structures::*; use rustc_ast::token::DocFragmentKind; use rustc_ast::{AttrStyle, ast}; use rustc_data_structures::fx::FxIndexMap; @@ -212,83 +212,6 @@ impl StrippedCfgItem { } } -#[derive(Encodable, Decodable, Clone, Debug, PartialEq, Eq, Hash)] -#[derive(HashStable_Generic, PrintAttribute)] -pub enum CfgEntry { - All(ThinVec, Span), - Any(ThinVec, Span), - Not(Box, Span), - Bool(bool, Span), - NameValue { name: Symbol, value: Option, span: Span }, - Version(Option, Span), -} - -impl CfgEntry { - pub fn span(&self) -> Span { - let (Self::All(_, span) - | Self::Any(_, span) - | Self::Not(_, span) - | Self::Bool(_, span) - | Self::NameValue { span, .. } - | Self::Version(_, span)) = self; - *span - } - - /// Same as `PartialEq` but doesn't check spans and ignore order of cfgs. - pub fn is_equivalent_to(&self, other: &Self) -> bool { - match (self, other) { - (Self::All(a, _), Self::All(b, _)) | (Self::Any(a, _), Self::Any(b, _)) => { - a.len() == b.len() && a.iter().all(|a| b.iter().any(|b| a.is_equivalent_to(b))) - } - (Self::Not(a, _), Self::Not(b, _)) => a.is_equivalent_to(b), - (Self::Bool(a, _), Self::Bool(b, _)) => a == b, - ( - Self::NameValue { name: name1, value: value1, .. }, - Self::NameValue { name: name2, value: value2, .. }, - ) => name1 == name2 && value1 == value2, - (Self::Version(a, _), Self::Version(b, _)) => a == b, - _ => false, - } - } -} - -impl fmt::Display for CfgEntry { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fn write_entries( - name: &str, - entries: &[CfgEntry], - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - write!(f, "{name}(")?; - for (nb, entry) in entries.iter().enumerate() { - if nb != 0 { - f.write_str(", ")?; - } - entry.fmt(f)?; - } - f.write_str(")") - } - match self { - Self::All(entries, _) => write_entries("all", entries, f), - Self::Any(entries, _) => write_entries("any", entries, f), - Self::Not(entry, _) => write!(f, "not({entry})"), - Self::Bool(value, _) => write!(f, "{value}"), - Self::NameValue { name, value, .. } => { - match value { - // We use `as_str` and debug display to have characters escaped and `"` - // characters surrounding the string. - Some(value) => write!(f, "{name} = {:?}", value.as_str()), - None => write!(f, "{name}"), - } - } - Self::Version(version, _) => match version { - Some(version) => write!(f, "{version}"), - None => Ok(()), - }, - } - } -} - /// Possible values for the `#[linkage]` attribute, allowing to specify the /// linkage type for a `MonoItem`. /// @@ -713,6 +636,12 @@ pub enum AttributeKind { span: Span, }, + /// Represents the trace attribute of `#[cfg_attr]` + CfgAttrTrace, + + /// Represents the trace attribute of `#[cfg]` + CfgTrace(ThinVec<(CfgEntry, Span)>), + /// Represents `#[cfi_encoding]` CfiEncoding { encoding: Symbol }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 57d2d6c5875e..3efa876ed6a9 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -26,6 +26,8 @@ impl AttributeKind { AsPtr(..) => Yes, AutomaticallyDerived(..) => Yes, BodyStability { .. } => No, + CfgAttrTrace => Yes, + CfgTrace(..) => Yes, CfiEncoding { .. } => Yes, Coinductive(..) => No, Cold(..) => No, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index f8ac2a547ca8..806f5c4d3ed9 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -2,6 +2,8 @@ use std::num::NonZero; use std::ops::Deref; use rustc_abi::Align; +use rustc_ast::attr::data_structures::CfgEntry; +use rustc_ast::attr::version::RustcVersion; use rustc_ast::token::{CommentKind, DocFragmentKind}; use rustc_ast::{AttrStyle, IntTy, UintTy}; use rustc_ast_pretty::pp::Printer; @@ -182,4 +184,6 @@ print_debug!( Transparency, SanitizerSet, DefId, + RustcVersion, + CfgEntry, ); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e13782282891..1a9bc8a2781b 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1371,6 +1371,7 @@ impl AttributeExt for Attribute { // FIXME: should not be needed anymore when all attrs are parsed Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span, Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span, + Attribute::Parsed(AttributeKind::CfgTrace(cfgs)) => cfgs[0].1, a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"), } } diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 7c9c15c16df4..fa46c0f085a2 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -33,7 +33,6 @@ pub mod pat_util; mod stability; mod stable_hash_impls; mod target; -mod version; pub mod weak_lang_items; #[cfg(test)] @@ -42,9 +41,9 @@ mod tests; #[doc(no_inline)] pub use hir::*; pub use lang_items::{LangItem, LanguageItems}; +pub use rustc_ast::attr::version::*; pub use stability::*; pub use stable_hash_impls::HashStableContext; pub use target::{MethodKind, Target}; -pub use version::*; arena_types!(rustc_arena::declare_arena); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7516460155e7..f1cbb72554d2 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -229,6 +229,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect | AttributeKind::MacroTransparency(_) + | AttributeKind::CfgTrace(..) | AttributeKind::Pointee(..) | AttributeKind::Dummy | AttributeKind::RustcBuiltinMacro { .. } @@ -302,6 +303,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) | AttributeKind::PinV2(..) | AttributeKind::WindowsSubsystem(..) + | AttributeKind::CfgAttrTrace | AttributeKind::ThreadLocal | AttributeKind::CfiEncoding { .. } ) => { /* do nothing */ } @@ -338,8 +340,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::forbid | sym::cfg | sym::cfg_attr - | sym::cfg_trace - | sym::cfg_attr_trace // need to be fixed | sym::patchable_function_entry // FIXME(patchable_function_entry) | sym::deprecated_safe // FIXME(deprecated_safe) @@ -1950,12 +1950,10 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { // only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed // if we allow more attributes (e.g., tool attributes and `allow/deny/warn`) // in where clauses. After that, only `self.check_attributes` should be enough. - const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg_trace, sym::cfg_attr_trace]; let spans = self .tcx .hir_attrs(where_predicate.hir_id) .iter() - .filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym))) // FIXME: We shouldn't need to special-case `doc`! .filter(|attr| { matches!( From 442981441294894978b8a1ce9cefcf52e2755bcd Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 26 Dec 2025 20:57:26 +0100 Subject: [PATCH 1626/3801] Convert librustdoc to use the new parsed representation --- src/librustdoc/clean/cfg.rs | 129 +------------------- src/librustdoc/clean/cfg/tests.rs | 133 --------------------- src/librustdoc/clean/mod.rs | 16 +-- src/librustdoc/passes/propagate_doc_cfg.rs | 6 +- 4 files changed, 11 insertions(+), 273 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 61ebc73182c0..485af5ab1d01 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -7,7 +7,6 @@ use std::sync::Arc; use std::{fmt, mem, ops}; use itertools::Either; -use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::thin_vec::{ThinVec, thin_vec}; use rustc_hir as hir; @@ -29,12 +28,6 @@ mod tests; #[cfg_attr(test, derive(PartialEq))] pub(crate) struct Cfg(CfgEntry); -#[derive(PartialEq, Debug)] -pub(crate) struct InvalidCfgError { - pub(crate) msg: &'static str, - pub(crate) span: Span, -} - /// Whether the configuration consists of just `Cfg` or `Not`. fn is_simple_cfg(cfg: &CfgEntry) -> bool { match cfg { @@ -105,106 +98,6 @@ fn should_capitalize_first_letter(cfg: &CfgEntry) -> bool { } impl Cfg { - /// Parses a `MetaItemInner` into a `Cfg`. - fn parse_nested( - nested_cfg: &MetaItemInner, - exclude: &FxHashSet, - ) -> Result, InvalidCfgError> { - match nested_cfg { - MetaItemInner::MetaItem(cfg) => Cfg::parse_without(cfg, exclude), - MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => { - Ok(Some(Cfg(CfgEntry::Bool(*b, DUMMY_SP)))) - } - MetaItemInner::Lit(lit) => { - Err(InvalidCfgError { msg: "unexpected literal", span: lit.span }) - } - } - } - - fn parse_without( - cfg: &MetaItem, - exclude: &FxHashSet, - ) -> Result, InvalidCfgError> { - let name = match cfg.ident() { - Some(ident) => ident.name, - None => { - return Err(InvalidCfgError { - msg: "expected a single identifier", - span: cfg.span, - }); - } - }; - match cfg.kind { - MetaItemKind::Word => { - if exclude.contains(&NameValueCfg::new(name)) { - Ok(None) - } else { - Ok(Some(Cfg(CfgEntry::NameValue { name, value: None, span: DUMMY_SP }))) - } - } - MetaItemKind::NameValue(ref lit) => match lit.kind { - LitKind::Str(value, _) => { - if exclude.contains(&NameValueCfg::new_value(name, value)) { - Ok(None) - } else { - Ok(Some(Cfg(CfgEntry::NameValue { - name, - value: Some(value), - span: DUMMY_SP, - }))) - } - } - _ => Err(InvalidCfgError { - // FIXME: if the main #[cfg] syntax decided to support non-string literals, - // this should be changed as well. - msg: "value of cfg option should be a string literal", - span: lit.span, - }), - }, - MetaItemKind::List(ref items) => { - let orig_len = items.len(); - let mut sub_cfgs = - items.iter().filter_map(|i| Cfg::parse_nested(i, exclude).transpose()); - let ret = match name { - sym::all => { - sub_cfgs.try_fold(Cfg(CfgEntry::Bool(true, DUMMY_SP)), |x, y| Ok(x & y?)) - } - sym::any => { - sub_cfgs.try_fold(Cfg(CfgEntry::Bool(false, DUMMY_SP)), |x, y| Ok(x | y?)) - } - sym::not => { - if orig_len == 1 { - let mut sub_cfgs = sub_cfgs.collect::>(); - if sub_cfgs.len() == 1 { - Ok(!sub_cfgs.pop().unwrap()?) - } else { - return Ok(None); - } - } else { - Err(InvalidCfgError { msg: "expected 1 cfg-pattern", span: cfg.span }) - } - } - _ => Err(InvalidCfgError { msg: "invalid predicate", span: cfg.span }), - }; - match ret { - Ok(c) => Ok(Some(c)), - Err(e) => Err(e), - } - } - } - } - - /// Parses a `MetaItem` into a `Cfg`. - /// - /// The `MetaItem` should be the content of the `#[cfg(...)]`, e.g., `unix` or - /// `target_os = "redox"`. - /// - /// If the content is not properly formatted, it will return an error indicating what and where - /// the error is. - pub(crate) fn parse(cfg: &MetaItemInner) -> Result { - Self::parse_nested(cfg, &FxHashSet::default()).map(|ret| ret.unwrap()) - } - /// Renders the configuration for human display, as a short HTML description. pub(crate) fn render_short_html(&self) -> String { let mut msg = Display(&self.0, Format::ShortHtml).to_string(); @@ -644,10 +537,6 @@ impl NameValueCfg { fn new(name: Symbol) -> Self { Self { name, value: None } } - - fn new_value(name: Symbol, value: Symbol) -> Self { - Self { name, value: Some(value) } - } } impl<'a> From<&'a CfgEntry> for NameValueCfg { @@ -751,15 +640,6 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator tcx: TyCtxt<'_>, cfg_info: &mut CfgInfo, ) -> Option> { - fn single(it: T) -> Option { - let mut iter = it.into_iter(); - let item = iter.next()?; - if iter.next().is_some() { - return None; - } - Some(item) - } - fn check_changed_auto_active_status( changed_auto_active_status: &mut Option, attr_span: Span, @@ -859,12 +739,11 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator } continue; } else if !cfg_info.parent_is_doc_cfg - && let Some(name) = attr.name() - && matches!(name, sym::cfg | sym::cfg_trace) - && let Some(attr) = single(attr.meta_item_list()?) - && let Ok(new_cfg) = Cfg::parse(&attr) + && let hir::Attribute::Parsed(AttributeKind::CfgTrace(cfgs)) = attr { - cfg_info.current_cfg &= new_cfg; + for (new_cfg, _) in cfgs { + cfg_info.current_cfg &= Cfg(new_cfg.clone()); + } } } diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 09316ead76ac..e0c21865d8df 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -1,8 +1,5 @@ -use rustc_ast::ast::LitIntType; -use rustc_ast::{MetaItemInner, MetaItemLit, Path, Safety, StrStyle}; use rustc_data_structures::thin_vec::thin_vec; use rustc_hir::attrs::CfgEntry; -use rustc_span::symbol::{Ident, kw}; use rustc_span::{DUMMY_SP, create_default_session_globals_then}; use super::*; @@ -28,10 +25,6 @@ fn name_value_cfg_e(name: &str, value: &str) -> CfgEntry { } } -fn dummy_lit(symbol: Symbol, kind: LitKind) -> MetaItemInner { - MetaItemInner::Lit(MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP }) -} - fn cfg_all(v: ThinVec) -> Cfg { Cfg(cfg_all_e(v)) } @@ -52,51 +45,6 @@ fn cfg_not(v: CfgEntry) -> Cfg { Cfg(CfgEntry::Not(Box::new(v), DUMMY_SP)) } -fn dummy_meta_item_word(name: &str) -> MetaItemInner { - MetaItemInner::MetaItem(MetaItem { - unsafety: Safety::Default, - path: Path::from_ident(Ident::from_str(name)), - kind: MetaItemKind::Word, - span: DUMMY_SP, - }) -} - -fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> MetaItemInner { - let lit = MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP }; - MetaItemInner::MetaItem(MetaItem { - unsafety: Safety::Default, - path: Path::from_ident(Ident::from_str(name)), - kind: MetaItemKind::NameValue(lit), - span: DUMMY_SP, - }) -} - -macro_rules! dummy_meta_item_list { - ($name:ident, [$($list:ident),* $(,)?]) => { - MetaItemInner::MetaItem(MetaItem { - unsafety: Safety::Default, - path: Path::from_ident(Ident::from_str(stringify!($name))), - kind: MetaItemKind::List(thin_vec![ - $( - dummy_meta_item_word(stringify!($list)), - )* - ]), - span: DUMMY_SP, - }) - }; - - ($name:ident, [$($list:expr),* $(,)?]) => { - MetaItemInner::MetaItem(MetaItem { - unsafety: Safety::Default, - path: Path::from_ident(Ident::from_str(stringify!($name))), - kind: MetaItemKind::List(thin_vec![ - $($list,)* - ]), - span: DUMMY_SP, - }) - }; -} - fn cfg_true() -> Cfg { Cfg(CfgEntry::Bool(true, DUMMY_SP)) } @@ -303,87 +251,6 @@ fn test_cfg_or() { }) } -#[test] -fn test_parse_ok() { - create_default_session_globals_then(|| { - let r#true = Symbol::intern("true"); - let mi = dummy_lit(r#true, LitKind::Bool(true)); - assert_eq!(Cfg::parse(&mi), Ok(cfg_true())); - - let r#false = Symbol::intern("false"); - let mi = dummy_lit(r#false, LitKind::Bool(false)); - assert_eq!(Cfg::parse(&mi), Ok(cfg_false())); - - let mi = dummy_meta_item_word("all"); - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); - - let done = Symbol::intern("done"); - let mi = dummy_meta_item_name_value("all", done, LitKind::Str(done, StrStyle::Cooked)); - assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done"))); - - let mi = dummy_meta_item_list!(all, [a, b]); - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b"))); - - let mi = dummy_meta_item_list!(any, [a, b]); - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") | word_cfg("b"))); - - let mi = dummy_meta_item_list!(not, [a]); - assert_eq!(Cfg::parse(&mi), Ok(!word_cfg("a"))); - - let mi = dummy_meta_item_list!( - not, - [dummy_meta_item_list!( - any, - [dummy_meta_item_word("a"), dummy_meta_item_list!(all, [b, c]),] - ),] - ); - assert_eq!(Cfg::parse(&mi), Ok(!(word_cfg("a") | (word_cfg("b") & word_cfg("c"))))); - - let mi = dummy_meta_item_list!(all, [a, b, c]); - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b") & word_cfg("c"))); - }) -} - -#[test] -fn test_parse_err() { - create_default_session_globals_then(|| { - let mi = dummy_meta_item_name_value("foo", kw::False, LitKind::Bool(false)); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!(not, [a, b]); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!(not, []); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!(foo, []); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!( - all, - [dummy_meta_item_list!(foo, []), dummy_meta_item_word("b"),] - ); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!( - any, - [dummy_meta_item_word("a"), dummy_meta_item_list!(foo, []),] - ); - assert!(Cfg::parse(&mi).is_err()); - - let mi = dummy_meta_item_list!(not, [dummy_meta_item_list!(foo, []),]); - assert!(Cfg::parse(&mi).is_err()); - - let c = Symbol::intern("e"); - let mi = dummy_lit(c, LitKind::Char('e')); - assert!(Cfg::parse(&mi).is_err()); - - let five = Symbol::intern("5"); - let mi = dummy_lit(five, LitKind::Int(5.into(), LitIntType::Unsuffixed)); - assert!(Cfg::parse(&mi).is_err()); - }) -} - #[test] fn test_render_short_html() { create_default_session_globals_then(|| { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0768e6a56b3c..8de3722fa69d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -51,7 +51,7 @@ use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeVisitableE use rustc_middle::{bug, span_bug}; use rustc_span::ExpnKind; use rustc_span::hygiene::{AstPass, MacroKind}; -use rustc_span::symbol::{Ident, Symbol, kw, sym}; +use rustc_span::symbol::{Ident, Symbol, kw}; use rustc_trait_selection::traits::wf::object_region_bounds; use tracing::{debug, instrument}; use utils::*; @@ -2682,17 +2682,13 @@ fn add_without_unwanted_attributes<'hir>( import_parent, )); } - hir::Attribute::Unparsed(normal) if let [name] = &*normal.path.segments => { - if is_inline || *name != sym::cfg_trace { - // If it's not a `cfg()` attribute, we keep it. - attrs.push((Cow::Borrowed(attr), import_parent)); - } - } - // FIXME: make sure to exclude `#[cfg_trace]` here when it is ported to the new parsers - hir::Attribute::Parsed(..) => { + + // We discard `#[cfg(...)]` attributes unless we're inlining + hir::Attribute::Parsed(AttributeKind::CfgTrace(..)) if !is_inline => {} + // We keep all other attributes + _ => { attrs.push((Cow::Borrowed(attr), import_parent)); } - _ => {} } } } diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index d4bf74c29514..54da158d4d39 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -2,7 +2,6 @@ use rustc_hir::Attribute; use rustc_hir::attrs::{AttributeKind, DocAttribute}; -use rustc_span::symbol::sym; use crate::clean::inline::{load_attrs, merge_attrs}; use crate::clean::{CfgInfo, Crate, Item, ItemKind}; @@ -39,10 +38,7 @@ fn add_only_cfg_attributes(attrs: &mut Vec, new_attrs: &[Attribute]) let mut new_attr = DocAttribute::default(); new_attr.cfg = d.cfg.clone(); attrs.push(Attribute::Parsed(AttributeKind::Doc(Box::new(new_attr)))); - } else if let Attribute::Unparsed(normal) = attr - && let [name] = &*normal.path.segments - && *name == sym::cfg_trace - { + } else if let Attribute::Parsed(AttributeKind::CfgTrace(..)) = attr { // If it's a `cfg()` attribute, we keep it. attrs.push(attr.clone()); } From e9fdf11c665f194bc269794e8523f61c7fb1591a Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 26 Dec 2025 20:57:35 +0100 Subject: [PATCH 1627/3801] Convert clippy to use the new parsed representation --- .../clippy/clippy_lints/src/attrs/mod.rs | 4 +- .../src/attrs/should_panic_without_expect.rs | 6 +-- .../clippy/clippy_lints/src/cfg_not_test.rs | 52 +++++++++++-------- .../src/doc/include_in_doc_without_cfg.rs | 4 +- .../clippy_lints/src/incompatible_msrv.rs | 9 ++-- .../clippy_lints/src/large_include_file.rs | 3 +- .../clippy_lints/src/methods/is_empty.rs | 5 +- .../clippy_lints/src/new_without_default.rs | 11 ++-- .../clippy/clippy_utils/src/ast_utils/mod.rs | 10 +++- src/tools/clippy/clippy_utils/src/lib.rs | 25 ++++----- 10 files changed, 72 insertions(+), 57 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index 679ccfb8de3a..366f5873a1aa 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -16,7 +16,7 @@ mod utils; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::msrvs::{self, Msrv, MsrvStack}; -use rustc_ast::{self as ast, AttrArgs, AttrKind, Attribute, MetaItemInner, MetaItemKind}; +use rustc_ast::{self as ast, AttrArgs, AttrKind, Attribute, MetaItemInner, MetaItemKind, AttrItemKind}; use rustc_hir::{ImplItem, Item, ItemKind, TraitItem}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc_session::impl_lint_pass; @@ -604,7 +604,7 @@ impl EarlyLintPass for PostExpansionEarlyAttributes { if attr.has_name(sym::ignore) && match &attr.kind { - AttrKind::Normal(normal_attr) => !matches!(normal_attr.item.args, AttrArgs::Eq { .. }), + AttrKind::Normal(normal_attr) => !matches!(normal_attr.item.args, AttrItemKind::Unparsed(AttrArgs::Eq { .. })), AttrKind::DocComment(..) => true, } { diff --git a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs index fd27e30a67f3..b854a3070bef 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs @@ -2,19 +2,19 @@ use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT}; use clippy_utils::diagnostics::span_lint_and_sugg; use rustc_ast::token::{Token, TokenKind}; use rustc_ast::tokenstream::TokenTree; -use rustc_ast::{AttrArgs, AttrKind}; +use rustc_ast::{AttrArgs, AttrKind, AttrItemKind}; use rustc_errors::Applicability; use rustc_lint::EarlyContext; use rustc_span::sym; pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) { if let AttrKind::Normal(normal_attr) = &attr.kind { - if let AttrArgs::Eq { .. } = &normal_attr.item.args { + if let AttrItemKind::Unparsed(AttrArgs::Eq { .. }) = &normal_attr.item.args { // `#[should_panic = ".."]` found, good return; } - if let AttrArgs::Delimited(args) = &normal_attr.item.args + if let AttrItemKind::Unparsed(AttrArgs::Delimited(args)) = &normal_attr.item.args && let mut tt_iter = args.tokens.iter() && let Some(TokenTree::Token( Token { diff --git a/src/tools/clippy/clippy_lints/src/cfg_not_test.rs b/src/tools/clippy/clippy_lints/src/cfg_not_test.rs index 7590fe96fd21..ec543d02c9dd 100644 --- a/src/tools/clippy/clippy_lints/src/cfg_not_test.rs +++ b/src/tools/clippy/clippy_lints/src/cfg_not_test.rs @@ -1,7 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_then; -use rustc_ast::MetaItemInner; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; +use rustc_ast::AttrItemKind; +use rustc_ast::EarlyParsedAttribute; +use rustc_span::sym; +use rustc_ast::attr::data_structures::CfgEntry; declare_clippy_lint! { /// ### What it does @@ -32,29 +35,34 @@ declare_lint_pass!(CfgNotTest => [CFG_NOT_TEST]); impl EarlyLintPass for CfgNotTest { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &rustc_ast::Attribute) { - if attr.has_name(rustc_span::sym::cfg_trace) && contains_not_test(attr.meta_item_list().as_deref(), false) { - span_lint_and_then( - cx, - CFG_NOT_TEST, - attr.span, - "code is excluded from test builds", - |diag| { - diag.help("consider not excluding any code from test builds"); - diag.note_once("this could increase code coverage despite not actually being tested"); - }, - ); + if attr.has_name(sym::cfg_trace) { + let AttrItemKind::Parsed(EarlyParsedAttribute::CfgTrace(cfg)) = &attr.get_normal_item().args else { + unreachable!() + }; + + if contains_not_test(&cfg, false) { + span_lint_and_then( + cx, + CFG_NOT_TEST, + attr.span, + "code is excluded from test builds", + |diag| { + diag.help("consider not excluding any code from test builds"); + diag.note_once("this could increase code coverage despite not actually being tested"); + }, + ); + } } } } -fn contains_not_test(list: Option<&[MetaItemInner]>, not: bool) -> bool { - list.is_some_and(|list| { - list.iter().any(|item| { - item.ident().is_some_and(|ident| match ident.name { - rustc_span::sym::not => contains_not_test(item.meta_item_list(), !not), - rustc_span::sym::test => not, - _ => contains_not_test(item.meta_item_list(), not), - }) - }) - }) +fn contains_not_test(cfg: &CfgEntry, not: bool) -> bool { + match cfg { + CfgEntry::All(subs, _) | CfgEntry::Any(subs, _) => subs.iter().any(|item| { + contains_not_test(item, not) + }), + CfgEntry::Not(sub, _) => contains_not_test(sub, !not), + CfgEntry::NameValue { name: sym::test, .. } => not, + _ => false + } } diff --git a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs index bca1cd03bb7e..f8e9e870f629 100644 --- a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs +++ b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; -use rustc_ast::{AttrArgs, AttrKind, AttrStyle, Attribute}; +use rustc_ast::{AttrArgs, AttrKind, AttrStyle, Attribute, AttrItemKind}; use rustc_errors::Applicability; use rustc_lint::EarlyContext; @@ -11,7 +11,7 @@ pub fn check(cx: &EarlyContext<'_>, attrs: &[Attribute]) { if !attr.span.from_expansion() && let AttrKind::Normal(ref item) = attr.kind && attr.doc_str().is_some() - && let AttrArgs::Eq { expr: meta, .. } = &item.item.args + && let AttrItemKind::Unparsed(AttrArgs::Eq { expr: meta, .. }) = &item.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs index 28ea2e4fa1f0..e0149a23fccf 100644 --- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs +++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs @@ -9,6 +9,8 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::{ExpnKind, Span}; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; declare_clippy_lint! { /// ### What it does @@ -268,11 +270,6 @@ impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv { /// attribute. fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool { cx.tcx.hir_parent_id_iter(hir_id).any(|id| { - cx.tcx.hir_attrs(id).iter().any(|attr| { - matches!( - attr.name(), - Some(sym::cfg_trace | sym::cfg_attr_trace) - ) - }) + find_attr!(cx.tcx.hir_attrs(id), AttributeKind::CfgTrace(..) | AttributeKind::CfgAttrTrace) }) } diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs index 48ce1afc6e69..5c37747b8c9b 100644 --- a/src/tools/clippy/clippy_lints/src/large_include_file.rs +++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs @@ -1,3 +1,4 @@ +use rustc_ast::AttrItemKind; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::root_macro_call_first_node; @@ -92,7 +93,7 @@ impl EarlyLintPass for LargeIncludeFile { && let AttrKind::Normal(ref item) = attr.kind && let Some(doc) = attr.doc_str() && doc.as_str().len() as u64 > self.max_file_size - && let AttrArgs::Eq { expr: meta, .. } = &item.item.args + && let AttrItemKind::Unparsed(AttrArgs::Eq { expr: meta, .. }) = &item.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs index add01b6a0837..834456ff6668 100644 --- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs +++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs @@ -5,7 +5,8 @@ use clippy_utils::res::MaybeResPath; use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context}; use rustc_hir::{Expr, HirId}; use rustc_lint::{LateContext, LintContext}; -use rustc_span::sym; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; use super::CONST_IS_EMPTY; @@ -40,7 +41,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool { cx.tcx .hir_parent_id_iter(id) - .any(|id| cx.tcx.hir_attrs(id).iter().any(|attr| attr.has_name(sym::cfg_trace))) + .any(|id| find_attr!(cx.tcx.hir_attrs(id), AttributeKind::CfgTrace(..))) } /// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index 6fc034b6fc5d..67493d54b552 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -9,6 +9,8 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::AssocKind; use rustc_session::impl_lint_pass; use rustc_span::sym; +use rustc_hir::Attribute; +use rustc_hir::attrs::AttributeKind; declare_clippy_lint! { /// ### What it does @@ -121,7 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { let attrs_sugg = { let mut sugg = String::new(); for attr in cx.tcx.hir_attrs(assoc_item_hir_id) { - if !attr.has_name(sym::cfg_trace) { + let Attribute::Parsed(AttributeKind::CfgTrace(attrs)) = attr else { // This might be some other attribute that the `impl Default` ought to inherit. // But it could also be one of the many attributes that: // - can't be put on an impl block -- like `#[inline]` @@ -131,10 +133,13 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { // reduce the applicability app = Applicability::MaybeIncorrect; continue; + }; + + for (_, attr_span) in attrs { + sugg.push_str(&snippet_with_applicability(cx.sess(), *attr_span, "_", &mut app)); + sugg.push('\n'); } - sugg.push_str(&snippet_with_applicability(cx.sess(), attr.span(), "_", &mut app)); - sugg.push('\n'); } sugg }; diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 432d7a251a21..618719286e8f 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -976,11 +976,19 @@ pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool { l.style == r.style && match (&l.kind, &r.kind) { (DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2, - (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_attr_args(&l.item.args, &r.item.args), + (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_attr_item_kind(&l.item.args, &r.item.args), _ => false, } } +pub fn eq_attr_item_kind(l: &AttrItemKind, r: &AttrItemKind) -> bool { + match (l, r) { + (AttrItemKind::Unparsed(l), AttrItemKind::Unparsed(r)) => eq_attr_args(l, r), + (AttrItemKind::Parsed(_l), AttrItemKind::Parsed(_r)) => todo!(), + _ => false, + } +} + pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool { use AttrArgs::*; match (l, r) { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 954c32687af6..38e1542cd758 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -121,6 +121,7 @@ use rustc_middle::ty::{ self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, GenericArgKind, GenericArgsRef, IntTy, Ty, TyCtxt, TypeFlags, TypeVisitableExt, UintTy, UpvarCapture, }; +use rustc_hir::attrs::CfgEntry; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{Ident, Symbol, kw}; @@ -2401,17 +2402,12 @@ pub fn is_test_function(tcx: TyCtxt<'_>, fn_def_id: LocalDefId) -> bool { /// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent /// use [`is_in_cfg_test`] pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.hir_attrs(id).iter().any(|attr| { - if attr.has_name(sym::cfg_trace) - && let Some(items) = attr.meta_item_list() - && let [item] = &*items - && item.has_name(sym::test) - { - true - } else { - false - } - }) + if let Some(cfgs) = find_attr!(tcx.hir_attrs(id), AttributeKind::CfgTrace(cfgs) => cfgs) + && cfgs.iter().any(|(cfg, _)| { matches!(cfg, CfgEntry::NameValue { name: sym::test, ..})}) { + true + } else { + false + } } /// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied @@ -2426,11 +2422,10 @@ pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied. pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - tcx.has_attr(def_id, sym::cfg_trace) - || tcx + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::CfgTrace(..)) + || find_attr!(tcx .hir_parent_iter(tcx.local_def_id_to_hir_id(def_id)) - .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)) - .any(|attr| attr.has_name(sym::cfg_trace)) + .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)), AttributeKind::CfgTrace(..)) } /// Walks up the HIR tree from the given expression in an attempt to find where the value is From f1ce0dd4dece601b131e794854ef219f40a7a444 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 26 Dec 2025 20:57:35 +0100 Subject: [PATCH 1628/3801] Convert clippy to use the new parsed representation --- clippy_lints/src/attrs/mod.rs | 4 +- .../src/attrs/should_panic_without_expect.rs | 6 +-- clippy_lints/src/cfg_not_test.rs | 52 +++++++++++-------- .../src/doc/include_in_doc_without_cfg.rs | 4 +- clippy_lints/src/incompatible_msrv.rs | 9 ++-- clippy_lints/src/large_include_file.rs | 3 +- clippy_lints/src/methods/is_empty.rs | 5 +- clippy_lints/src/new_without_default.rs | 11 ++-- clippy_utils/src/ast_utils/mod.rs | 10 +++- clippy_utils/src/lib.rs | 25 ++++----- 10 files changed, 72 insertions(+), 57 deletions(-) diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index 679ccfb8de3a..366f5873a1aa 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -16,7 +16,7 @@ mod utils; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::msrvs::{self, Msrv, MsrvStack}; -use rustc_ast::{self as ast, AttrArgs, AttrKind, Attribute, MetaItemInner, MetaItemKind}; +use rustc_ast::{self as ast, AttrArgs, AttrKind, Attribute, MetaItemInner, MetaItemKind, AttrItemKind}; use rustc_hir::{ImplItem, Item, ItemKind, TraitItem}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc_session::impl_lint_pass; @@ -604,7 +604,7 @@ impl EarlyLintPass for PostExpansionEarlyAttributes { if attr.has_name(sym::ignore) && match &attr.kind { - AttrKind::Normal(normal_attr) => !matches!(normal_attr.item.args, AttrArgs::Eq { .. }), + AttrKind::Normal(normal_attr) => !matches!(normal_attr.item.args, AttrItemKind::Unparsed(AttrArgs::Eq { .. })), AttrKind::DocComment(..) => true, } { diff --git a/clippy_lints/src/attrs/should_panic_without_expect.rs b/clippy_lints/src/attrs/should_panic_without_expect.rs index fd27e30a67f3..b854a3070bef 100644 --- a/clippy_lints/src/attrs/should_panic_without_expect.rs +++ b/clippy_lints/src/attrs/should_panic_without_expect.rs @@ -2,19 +2,19 @@ use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT}; use clippy_utils::diagnostics::span_lint_and_sugg; use rustc_ast::token::{Token, TokenKind}; use rustc_ast::tokenstream::TokenTree; -use rustc_ast::{AttrArgs, AttrKind}; +use rustc_ast::{AttrArgs, AttrKind, AttrItemKind}; use rustc_errors::Applicability; use rustc_lint::EarlyContext; use rustc_span::sym; pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) { if let AttrKind::Normal(normal_attr) = &attr.kind { - if let AttrArgs::Eq { .. } = &normal_attr.item.args { + if let AttrItemKind::Unparsed(AttrArgs::Eq { .. }) = &normal_attr.item.args { // `#[should_panic = ".."]` found, good return; } - if let AttrArgs::Delimited(args) = &normal_attr.item.args + if let AttrItemKind::Unparsed(AttrArgs::Delimited(args)) = &normal_attr.item.args && let mut tt_iter = args.tokens.iter() && let Some(TokenTree::Token( Token { diff --git a/clippy_lints/src/cfg_not_test.rs b/clippy_lints/src/cfg_not_test.rs index 7590fe96fd21..ec543d02c9dd 100644 --- a/clippy_lints/src/cfg_not_test.rs +++ b/clippy_lints/src/cfg_not_test.rs @@ -1,7 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_then; -use rustc_ast::MetaItemInner; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; +use rustc_ast::AttrItemKind; +use rustc_ast::EarlyParsedAttribute; +use rustc_span::sym; +use rustc_ast::attr::data_structures::CfgEntry; declare_clippy_lint! { /// ### What it does @@ -32,29 +35,34 @@ declare_lint_pass!(CfgNotTest => [CFG_NOT_TEST]); impl EarlyLintPass for CfgNotTest { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &rustc_ast::Attribute) { - if attr.has_name(rustc_span::sym::cfg_trace) && contains_not_test(attr.meta_item_list().as_deref(), false) { - span_lint_and_then( - cx, - CFG_NOT_TEST, - attr.span, - "code is excluded from test builds", - |diag| { - diag.help("consider not excluding any code from test builds"); - diag.note_once("this could increase code coverage despite not actually being tested"); - }, - ); + if attr.has_name(sym::cfg_trace) { + let AttrItemKind::Parsed(EarlyParsedAttribute::CfgTrace(cfg)) = &attr.get_normal_item().args else { + unreachable!() + }; + + if contains_not_test(&cfg, false) { + span_lint_and_then( + cx, + CFG_NOT_TEST, + attr.span, + "code is excluded from test builds", + |diag| { + diag.help("consider not excluding any code from test builds"); + diag.note_once("this could increase code coverage despite not actually being tested"); + }, + ); + } } } } -fn contains_not_test(list: Option<&[MetaItemInner]>, not: bool) -> bool { - list.is_some_and(|list| { - list.iter().any(|item| { - item.ident().is_some_and(|ident| match ident.name { - rustc_span::sym::not => contains_not_test(item.meta_item_list(), !not), - rustc_span::sym::test => not, - _ => contains_not_test(item.meta_item_list(), not), - }) - }) - }) +fn contains_not_test(cfg: &CfgEntry, not: bool) -> bool { + match cfg { + CfgEntry::All(subs, _) | CfgEntry::Any(subs, _) => subs.iter().any(|item| { + contains_not_test(item, not) + }), + CfgEntry::Not(sub, _) => contains_not_test(sub, !not), + CfgEntry::NameValue { name: sym::test, .. } => not, + _ => false + } } diff --git a/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/clippy_lints/src/doc/include_in_doc_without_cfg.rs index bca1cd03bb7e..f8e9e870f629 100644 --- a/clippy_lints/src/doc/include_in_doc_without_cfg.rs +++ b/clippy_lints/src/doc/include_in_doc_without_cfg.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; -use rustc_ast::{AttrArgs, AttrKind, AttrStyle, Attribute}; +use rustc_ast::{AttrArgs, AttrKind, AttrStyle, Attribute, AttrItemKind}; use rustc_errors::Applicability; use rustc_lint::EarlyContext; @@ -11,7 +11,7 @@ pub fn check(cx: &EarlyContext<'_>, attrs: &[Attribute]) { if !attr.span.from_expansion() && let AttrKind::Normal(ref item) = attr.kind && attr.doc_str().is_some() - && let AttrArgs::Eq { expr: meta, .. } = &item.item.args + && let AttrItemKind::Unparsed(AttrArgs::Eq { expr: meta, .. }) = &item.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/clippy_lints/src/incompatible_msrv.rs b/clippy_lints/src/incompatible_msrv.rs index 28ea2e4fa1f0..e0149a23fccf 100644 --- a/clippy_lints/src/incompatible_msrv.rs +++ b/clippy_lints/src/incompatible_msrv.rs @@ -9,6 +9,8 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::{ExpnKind, Span}; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; declare_clippy_lint! { /// ### What it does @@ -268,11 +270,6 @@ impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv { /// attribute. fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool { cx.tcx.hir_parent_id_iter(hir_id).any(|id| { - cx.tcx.hir_attrs(id).iter().any(|attr| { - matches!( - attr.name(), - Some(sym::cfg_trace | sym::cfg_attr_trace) - ) - }) + find_attr!(cx.tcx.hir_attrs(id), AttributeKind::CfgTrace(..) | AttributeKind::CfgAttrTrace) }) } diff --git a/clippy_lints/src/large_include_file.rs b/clippy_lints/src/large_include_file.rs index 48ce1afc6e69..5c37747b8c9b 100644 --- a/clippy_lints/src/large_include_file.rs +++ b/clippy_lints/src/large_include_file.rs @@ -1,3 +1,4 @@ +use rustc_ast::AttrItemKind; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::root_macro_call_first_node; @@ -92,7 +93,7 @@ impl EarlyLintPass for LargeIncludeFile { && let AttrKind::Normal(ref item) = attr.kind && let Some(doc) = attr.doc_str() && doc.as_str().len() as u64 > self.max_file_size - && let AttrArgs::Eq { expr: meta, .. } = &item.item.args + && let AttrItemKind::Unparsed(AttrArgs::Eq { expr: meta, .. }) = &item.item.args && !attr.span.contains(meta.span) // Since the `include_str` is already expanded at this point, we can only take the // whole attribute snippet and then modify for our suggestion. diff --git a/clippy_lints/src/methods/is_empty.rs b/clippy_lints/src/methods/is_empty.rs index add01b6a0837..834456ff6668 100644 --- a/clippy_lints/src/methods/is_empty.rs +++ b/clippy_lints/src/methods/is_empty.rs @@ -5,7 +5,8 @@ use clippy_utils::res::MaybeResPath; use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context}; use rustc_hir::{Expr, HirId}; use rustc_lint::{LateContext, LintContext}; -use rustc_span::sym; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; use super::CONST_IS_EMPTY; @@ -40,7 +41,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool { cx.tcx .hir_parent_id_iter(id) - .any(|id| cx.tcx.hir_attrs(id).iter().any(|attr| attr.has_name(sym::cfg_trace))) + .any(|id| find_attr!(cx.tcx.hir_attrs(id), AttributeKind::CfgTrace(..))) } /// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index 6fc034b6fc5d..67493d54b552 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -9,6 +9,8 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::AssocKind; use rustc_session::impl_lint_pass; use rustc_span::sym; +use rustc_hir::Attribute; +use rustc_hir::attrs::AttributeKind; declare_clippy_lint! { /// ### What it does @@ -121,7 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { let attrs_sugg = { let mut sugg = String::new(); for attr in cx.tcx.hir_attrs(assoc_item_hir_id) { - if !attr.has_name(sym::cfg_trace) { + let Attribute::Parsed(AttributeKind::CfgTrace(attrs)) = attr else { // This might be some other attribute that the `impl Default` ought to inherit. // But it could also be one of the many attributes that: // - can't be put on an impl block -- like `#[inline]` @@ -131,10 +133,13 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { // reduce the applicability app = Applicability::MaybeIncorrect; continue; + }; + + for (_, attr_span) in attrs { + sugg.push_str(&snippet_with_applicability(cx.sess(), *attr_span, "_", &mut app)); + sugg.push('\n'); } - sugg.push_str(&snippet_with_applicability(cx.sess(), attr.span(), "_", &mut app)); - sugg.push('\n'); } sugg }; diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index 432d7a251a21..618719286e8f 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -976,11 +976,19 @@ pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool { l.style == r.style && match (&l.kind, &r.kind) { (DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2, - (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_attr_args(&l.item.args, &r.item.args), + (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_attr_item_kind(&l.item.args, &r.item.args), _ => false, } } +pub fn eq_attr_item_kind(l: &AttrItemKind, r: &AttrItemKind) -> bool { + match (l, r) { + (AttrItemKind::Unparsed(l), AttrItemKind::Unparsed(r)) => eq_attr_args(l, r), + (AttrItemKind::Parsed(_l), AttrItemKind::Parsed(_r)) => todo!(), + _ => false, + } +} + pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool { use AttrArgs::*; match (l, r) { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 954c32687af6..38e1542cd758 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -121,6 +121,7 @@ use rustc_middle::ty::{ self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, GenericArgKind, GenericArgsRef, IntTy, Ty, TyCtxt, TypeFlags, TypeVisitableExt, UintTy, UpvarCapture, }; +use rustc_hir::attrs::CfgEntry; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{Ident, Symbol, kw}; @@ -2401,17 +2402,12 @@ pub fn is_test_function(tcx: TyCtxt<'_>, fn_def_id: LocalDefId) -> bool { /// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent /// use [`is_in_cfg_test`] pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.hir_attrs(id).iter().any(|attr| { - if attr.has_name(sym::cfg_trace) - && let Some(items) = attr.meta_item_list() - && let [item] = &*items - && item.has_name(sym::test) - { - true - } else { - false - } - }) + if let Some(cfgs) = find_attr!(tcx.hir_attrs(id), AttributeKind::CfgTrace(cfgs) => cfgs) + && cfgs.iter().any(|(cfg, _)| { matches!(cfg, CfgEntry::NameValue { name: sym::test, ..})}) { + true + } else { + false + } } /// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied @@ -2426,11 +2422,10 @@ pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied. pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - tcx.has_attr(def_id, sym::cfg_trace) - || tcx + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::CfgTrace(..)) + || find_attr!(tcx .hir_parent_iter(tcx.local_def_id_to_hir_id(def_id)) - .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)) - .any(|attr| attr.has_name(sym::cfg_trace)) + .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)), AttributeKind::CfgTrace(..)) } /// Walks up the HIR tree from the given expression in an attempt to find where the value is From 4699fdc2887bd9a28921ca9e73193aa38f94d0c4 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 6 Jan 2026 16:53:34 +0800 Subject: [PATCH 1629/3801] Fix loses exists guard for move_guard Example --- ```rust fn main() { let cond = true; match 92 { 3 => true, x if cond => if x $0> 10 { false } else if x > 5 { true } else if x > 4 || x < -2 { false } else { true }, } } ``` **Before this PR** ```rust fn main() { let cond = true; match 92 { 3 => true, x if x > 10 => false, x if x > 5 => true, x if x > 4 || x < -2 => false, x => true, } } ``` **After this PR** ```rust fn main() { let cond = true; match 92 { 3 => true, x if cond && x > 10 => false, x if cond && x > 5 => true, x if cond && (x > 4 || x < -2) => false, x if cond => true, } } ``` --- .../ide-assists/src/handlers/move_guard.rs | 65 +++++++++++++++++-- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs index 1c0c6e43d53b..31baa63372ff 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs @@ -3,7 +3,7 @@ use syntax::{ SyntaxKind::WHITESPACE, ast::{ AstNode, BlockExpr, ElseBranch, Expr, IfExpr, MatchArm, Pat, edit::AstNodeEdit, make, - syntax_factory::SyntaxFactory, + prec::ExprPrecedence, syntax_factory::SyntaxFactory, }, syntax_editor::Element, }; @@ -109,6 +109,7 @@ pub(crate) fn move_arm_cond_to_match_guard( let match_arm: MatchArm = ctx.find_node_at_offset::()?; let match_pat = match_arm.pat()?; let arm_body = match_arm.expr()?; + let arm_guard = match_arm.guard().and_then(|it| it.condition()); let mut replace_node = None; let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone()).or_else(|| { @@ -149,6 +150,25 @@ pub(crate) fn move_arm_cond_to_match_guard( 0 }; let indent_level = match_arm.indent_level(); + let make_guard = |cond: Option| { + let condition = match (arm_guard.clone(), cond) { + (None, None) => return None, + (None, Some(it)) | (Some(it), None) => it, + (Some(lhs), Some(rhs)) => { + let op_expr = |expr: Expr| { + if expr.precedence().needs_parentheses_in(ExprPrecedence::LAnd) { + make.expr_paren(expr).into() + } else { + expr + } + }; + let op = syntax::ast::BinaryOp::LogicOp(syntax::ast::LogicOp::And); + let expr_bin = make.expr_bin(op_expr(lhs), op, op_expr(rhs)); + expr_bin.into() + } + }; + Some(make.match_guard(condition)) + }; for (cond, block) in conds_blocks { let only_expr = block.statements().next().is_none(); @@ -156,8 +176,7 @@ pub(crate) fn move_arm_cond_to_match_guard( Some(then_expr) if only_expr => then_expr, _ => block.dedent(dedent.into()).into(), }; - let guard = make.match_guard(cond); - let new_arm = make.match_arm(match_pat.clone(), Some(guard), expr); + let new_arm = make.match_arm(match_pat.clone(), make_guard(Some(cond)), expr); replace_arms.push(new_arm); } if let Some(block) = tail { @@ -170,7 +189,7 @@ pub(crate) fn move_arm_cond_to_match_guard( } _ => block.dedent(dedent.into()).into(), }; - let new_arm = make.match_arm(match_pat, None, expr); + let new_arm = make.match_arm(match_pat, make_guard(None), expr); replace_arms.push(new_arm); } else { // There's no else branch. Add a pattern without guard, unless the following match @@ -185,7 +204,7 @@ pub(crate) fn move_arm_cond_to_match_guard( } _ => { let block_expr = make.expr_empty_block().into(); - replace_arms.push(make.match_arm(match_pat, None, block_expr)); + replace_arms.push(make.match_arm(match_pat, make_guard(None), block_expr)); } } } @@ -1081,6 +1100,42 @@ fn main() { x => {} } } +"#, + ) + } + + #[test] + fn move_arm_cond_to_match_guard_elseif_exist_guard() { + check_assist( + move_arm_cond_to_match_guard, + r#" +fn main() { + let cond = true; + match 92 { + 3 => true, + x if cond => if x $0> 10 { + false + } else if x > 5 { + true + } else if x > 4 || x < -2 { + false + } else { + true + }, + } +} +"#, + r#" +fn main() { + let cond = true; + match 92 { + 3 => true, + x if cond && x > 10 => false, + x if cond && x > 5 => true, + x if cond && (x > 4 || x < -2) => false, + x if cond => true, + } +} "#, ) } From bd5526c2cf7a040d96ef7c41fce8b9f0ca6b9374 Mon Sep 17 00:00:00 2001 From: andjsrk Date: Tue, 6 Jan 2026 20:14:52 +0900 Subject: [PATCH 1630/3801] accept test changes related to binary ops --- src/tools/clippy/tests/ui/manual_clamp.fixed | 3 +- src/tools/clippy/tests/ui/manual_clamp.rs | 3 +- src/tools/clippy/tests/ui/manual_clamp.stderr | 70 +++++++++---------- .../tests/ui/needless_bitwise_bool.fixed | 4 +- .../clippy/tests/ui/needless_bitwise_bool.rs | 2 + .../tests/ui/needless_bitwise_bool.stderr | 8 ++- 6 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/tools/clippy/tests/ui/manual_clamp.fixed b/src/tools/clippy/tests/ui/manual_clamp.fixed index 2450a4f4c611..b279a413bc17 100644 --- a/src/tools/clippy/tests/ui/manual_clamp.fixed +++ b/src/tools/clippy/tests/ui/manual_clamp.fixed @@ -4,7 +4,8 @@ dead_code, clippy::unnecessary_operation, clippy::no_effect, - clippy::if_same_then_else + clippy::if_same_then_else, + clippy::needless_match )] use std::cmp::{max as cmp_max, min as cmp_min}; diff --git a/src/tools/clippy/tests/ui/manual_clamp.rs b/src/tools/clippy/tests/ui/manual_clamp.rs index ee341d50768f..7fda41cd4c35 100644 --- a/src/tools/clippy/tests/ui/manual_clamp.rs +++ b/src/tools/clippy/tests/ui/manual_clamp.rs @@ -4,7 +4,8 @@ dead_code, clippy::unnecessary_operation, clippy::no_effect, - clippy::if_same_then_else + clippy::if_same_then_else, + clippy::needless_match )] use std::cmp::{max as cmp_max, min as cmp_min}; diff --git a/src/tools/clippy/tests/ui/manual_clamp.stderr b/src/tools/clippy/tests/ui/manual_clamp.stderr index 4a0e4fa51646..775a16418eba 100644 --- a/src/tools/clippy/tests/ui/manual_clamp.stderr +++ b/src/tools/clippy/tests/ui/manual_clamp.stderr @@ -1,5 +1,5 @@ error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:212:5 + --> tests/ui/manual_clamp.rs:213:5 | LL | / if x9 < CONST_MIN { LL | | @@ -15,7 +15,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_clamp)]` error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:230:5 + --> tests/ui/manual_clamp.rs:231:5 | LL | / if x11 > CONST_MAX { LL | | @@ -29,7 +29,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:240:5 + --> tests/ui/manual_clamp.rs:241:5 | LL | / if CONST_MIN > x12 { LL | | @@ -43,7 +43,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:250:5 + --> tests/ui/manual_clamp.rs:251:5 | LL | / if CONST_MAX < x13 { LL | | @@ -57,7 +57,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:363:5 + --> tests/ui/manual_clamp.rs:364:5 | LL | / if CONST_MAX < x35 { LL | | @@ -71,7 +71,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:144:14 + --> tests/ui/manual_clamp.rs:145:14 | LL | let x0 = if CONST_MAX < input { | ______________^ @@ -86,7 +86,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:154:14 + --> tests/ui/manual_clamp.rs:155:14 | LL | let x1 = if input > CONST_MAX { | ______________^ @@ -101,7 +101,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:164:14 + --> tests/ui/manual_clamp.rs:165:14 | LL | let x2 = if input < CONST_MIN { | ______________^ @@ -116,7 +116,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:174:14 + --> tests/ui/manual_clamp.rs:175:14 | LL | let x3 = if CONST_MIN > input { | ______________^ @@ -131,7 +131,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:184:14 + --> tests/ui/manual_clamp.rs:185:14 | LL | let x4 = input.max(CONST_MIN).min(CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -139,7 +139,7 @@ LL | let x4 = input.max(CONST_MIN).min(CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:187:14 + --> tests/ui/manual_clamp.rs:188:14 | LL | let x5 = input.min(CONST_MAX).max(CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -147,7 +147,7 @@ LL | let x5 = input.min(CONST_MAX).max(CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:190:14 + --> tests/ui/manual_clamp.rs:191:14 | LL | let x6 = match input { | ______________^ @@ -161,7 +161,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:197:14 + --> tests/ui/manual_clamp.rs:198:14 | LL | let x7 = match input { | ______________^ @@ -175,7 +175,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:204:14 + --> tests/ui/manual_clamp.rs:205:14 | LL | let x8 = match input { | ______________^ @@ -189,7 +189,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:221:15 + --> tests/ui/manual_clamp.rs:222:15 | LL | let x10 = match input { | _______________^ @@ -203,7 +203,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:259:15 + --> tests/ui/manual_clamp.rs:260:15 | LL | let x14 = if input > CONST_MAX { | _______________^ @@ -218,7 +218,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:270:19 + --> tests/ui/manual_clamp.rs:271:19 | LL | let x15 = if input > CONST_F64_MAX { | ___________________^ @@ -234,7 +234,7 @@ LL | | }; = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:283:19 + --> tests/ui/manual_clamp.rs:284:19 | LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -242,7 +242,7 @@ LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:286:19 + --> tests/ui/manual_clamp.rs:287:19 | LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -250,7 +250,7 @@ LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:289:19 + --> tests/ui/manual_clamp.rs:290:19 | LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -258,7 +258,7 @@ LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:292:19 + --> tests/ui/manual_clamp.rs:293:19 | LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -266,7 +266,7 @@ LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:295:19 + --> tests/ui/manual_clamp.rs:296:19 | LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -274,7 +274,7 @@ LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:298:19 + --> tests/ui/manual_clamp.rs:299:19 | LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -282,7 +282,7 @@ LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:301:19 + --> tests/ui/manual_clamp.rs:302:19 | LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -290,7 +290,7 @@ LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:304:19 + --> tests/ui/manual_clamp.rs:305:19 | LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -298,7 +298,7 @@ LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:308:19 + --> tests/ui/manual_clamp.rs:309:19 | LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -307,7 +307,7 @@ LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:311:19 + --> tests/ui/manual_clamp.rs:312:19 | LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -316,7 +316,7 @@ LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:314:19 + --> tests/ui/manual_clamp.rs:315:19 | LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -325,7 +325,7 @@ LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:317:19 + --> tests/ui/manual_clamp.rs:318:19 | LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -334,7 +334,7 @@ LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:320:19 + --> tests/ui/manual_clamp.rs:321:19 | LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -343,7 +343,7 @@ LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:323:19 + --> tests/ui/manual_clamp.rs:324:19 | LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -352,7 +352,7 @@ LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:326:19 + --> tests/ui/manual_clamp.rs:327:19 | LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -361,7 +361,7 @@ LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:329:19 + --> tests/ui/manual_clamp.rs:330:19 | LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -370,7 +370,7 @@ LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:333:5 + --> tests/ui/manual_clamp.rs:334:5 | LL | / if x32 < CONST_MIN { LL | | @@ -384,7 +384,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:525:13 + --> tests/ui/manual_clamp.rs:526:13 | LL | let _ = if input > CONST_MAX { | _____________^ diff --git a/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed b/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed index 89a3c1474f25..751d3d257000 100644 --- a/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed +++ b/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed @@ -34,7 +34,9 @@ fn main() { println!("true") // This is a const method call } - if y & (0 < 1) { + // Resolved + if y && (0 < 1) { + //~^ needless_bitwise_bool println!("true") // This is a BinOp with no side effects } } diff --git a/src/tools/clippy/tests/ui/needless_bitwise_bool.rs b/src/tools/clippy/tests/ui/needless_bitwise_bool.rs index f5aa7a9f3d9e..5d3ff3b2079c 100644 --- a/src/tools/clippy/tests/ui/needless_bitwise_bool.rs +++ b/src/tools/clippy/tests/ui/needless_bitwise_bool.rs @@ -34,7 +34,9 @@ fn main() { println!("true") // This is a const method call } + // Resolved if y & (0 < 1) { + //~^ needless_bitwise_bool println!("true") // This is a BinOp with no side effects } } diff --git a/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr b/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr index 9f14646c3e5a..4f64c7136916 100644 --- a/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr +++ b/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr @@ -7,5 +7,11 @@ LL | if y & !x { = note: `-D clippy::needless-bitwise-bool` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_bitwise_bool)]` -error: aborting due to 1 previous error +error: use of bitwise operator instead of lazy operator between booleans + --> tests/ui/needless_bitwise_bool.rs:38:8 + | +LL | if y & (0 < 1) { + | ^^^^^^^^^^^ help: try: `y && (0 < 1)` + +error: aborting due to 2 previous errors From ce012da28e4d69cc24a4ecb6afb262564183f2bc Mon Sep 17 00:00:00 2001 From: andjsrk Date: Tue, 6 Jan 2026 20:14:52 +0900 Subject: [PATCH 1631/3801] accept test changes related to binary ops --- tests/ui/manual_clamp.fixed | 3 +- tests/ui/manual_clamp.rs | 3 +- tests/ui/manual_clamp.stderr | 70 +++++++++++++-------------- tests/ui/needless_bitwise_bool.fixed | 4 +- tests/ui/needless_bitwise_bool.rs | 2 + tests/ui/needless_bitwise_bool.stderr | 8 ++- 6 files changed, 51 insertions(+), 39 deletions(-) diff --git a/tests/ui/manual_clamp.fixed b/tests/ui/manual_clamp.fixed index 2450a4f4c611..b279a413bc17 100644 --- a/tests/ui/manual_clamp.fixed +++ b/tests/ui/manual_clamp.fixed @@ -4,7 +4,8 @@ dead_code, clippy::unnecessary_operation, clippy::no_effect, - clippy::if_same_then_else + clippy::if_same_then_else, + clippy::needless_match )] use std::cmp::{max as cmp_max, min as cmp_min}; diff --git a/tests/ui/manual_clamp.rs b/tests/ui/manual_clamp.rs index ee341d50768f..7fda41cd4c35 100644 --- a/tests/ui/manual_clamp.rs +++ b/tests/ui/manual_clamp.rs @@ -4,7 +4,8 @@ dead_code, clippy::unnecessary_operation, clippy::no_effect, - clippy::if_same_then_else + clippy::if_same_then_else, + clippy::needless_match )] use std::cmp::{max as cmp_max, min as cmp_min}; diff --git a/tests/ui/manual_clamp.stderr b/tests/ui/manual_clamp.stderr index 4a0e4fa51646..775a16418eba 100644 --- a/tests/ui/manual_clamp.stderr +++ b/tests/ui/manual_clamp.stderr @@ -1,5 +1,5 @@ error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:212:5 + --> tests/ui/manual_clamp.rs:213:5 | LL | / if x9 < CONST_MIN { LL | | @@ -15,7 +15,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::manual_clamp)]` error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:230:5 + --> tests/ui/manual_clamp.rs:231:5 | LL | / if x11 > CONST_MAX { LL | | @@ -29,7 +29,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:240:5 + --> tests/ui/manual_clamp.rs:241:5 | LL | / if CONST_MIN > x12 { LL | | @@ -43,7 +43,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:250:5 + --> tests/ui/manual_clamp.rs:251:5 | LL | / if CONST_MAX < x13 { LL | | @@ -57,7 +57,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:363:5 + --> tests/ui/manual_clamp.rs:364:5 | LL | / if CONST_MAX < x35 { LL | | @@ -71,7 +71,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:144:14 + --> tests/ui/manual_clamp.rs:145:14 | LL | let x0 = if CONST_MAX < input { | ______________^ @@ -86,7 +86,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:154:14 + --> tests/ui/manual_clamp.rs:155:14 | LL | let x1 = if input > CONST_MAX { | ______________^ @@ -101,7 +101,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:164:14 + --> tests/ui/manual_clamp.rs:165:14 | LL | let x2 = if input < CONST_MIN { | ______________^ @@ -116,7 +116,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:174:14 + --> tests/ui/manual_clamp.rs:175:14 | LL | let x3 = if CONST_MIN > input { | ______________^ @@ -131,7 +131,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:184:14 + --> tests/ui/manual_clamp.rs:185:14 | LL | let x4 = input.max(CONST_MIN).min(CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -139,7 +139,7 @@ LL | let x4 = input.max(CONST_MIN).min(CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:187:14 + --> tests/ui/manual_clamp.rs:188:14 | LL | let x5 = input.min(CONST_MAX).max(CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -147,7 +147,7 @@ LL | let x5 = input.min(CONST_MAX).max(CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:190:14 + --> tests/ui/manual_clamp.rs:191:14 | LL | let x6 = match input { | ______________^ @@ -161,7 +161,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:197:14 + --> tests/ui/manual_clamp.rs:198:14 | LL | let x7 = match input { | ______________^ @@ -175,7 +175,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:204:14 + --> tests/ui/manual_clamp.rs:205:14 | LL | let x8 = match input { | ______________^ @@ -189,7 +189,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:221:15 + --> tests/ui/manual_clamp.rs:222:15 | LL | let x10 = match input { | _______________^ @@ -203,7 +203,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:259:15 + --> tests/ui/manual_clamp.rs:260:15 | LL | let x14 = if input > CONST_MAX { | _______________^ @@ -218,7 +218,7 @@ LL | | }; = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:270:19 + --> tests/ui/manual_clamp.rs:271:19 | LL | let x15 = if input > CONST_F64_MAX { | ___________________^ @@ -234,7 +234,7 @@ LL | | }; = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:283:19 + --> tests/ui/manual_clamp.rs:284:19 | LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -242,7 +242,7 @@ LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:286:19 + --> tests/ui/manual_clamp.rs:287:19 | LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -250,7 +250,7 @@ LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:289:19 + --> tests/ui/manual_clamp.rs:290:19 | LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -258,7 +258,7 @@ LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:292:19 + --> tests/ui/manual_clamp.rs:293:19 | LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -266,7 +266,7 @@ LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:295:19 + --> tests/ui/manual_clamp.rs:296:19 | LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -274,7 +274,7 @@ LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:298:19 + --> tests/ui/manual_clamp.rs:299:19 | LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -282,7 +282,7 @@ LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:301:19 + --> tests/ui/manual_clamp.rs:302:19 | LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -290,7 +290,7 @@ LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:304:19 + --> tests/ui/manual_clamp.rs:305:19 | LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)` @@ -298,7 +298,7 @@ LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input)); = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:308:19 + --> tests/ui/manual_clamp.rs:309:19 | LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -307,7 +307,7 @@ LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:311:19 + --> tests/ui/manual_clamp.rs:312:19 | LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -316,7 +316,7 @@ LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:314:19 + --> tests/ui/manual_clamp.rs:315:19 | LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -325,7 +325,7 @@ LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:317:19 + --> tests/ui/manual_clamp.rs:318:19 | LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -334,7 +334,7 @@ LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:320:19 + --> tests/ui/manual_clamp.rs:321:19 | LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -343,7 +343,7 @@ LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:323:19 + --> tests/ui/manual_clamp.rs:324:19 | LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -352,7 +352,7 @@ LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:326:19 + --> tests/ui/manual_clamp.rs:327:19 | LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -361,7 +361,7 @@ LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:329:19 + --> tests/ui/manual_clamp.rs:330:19 | LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)` @@ -370,7 +370,7 @@ LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input)); = note: clamp returns NaN if the input is NaN error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:333:5 + --> tests/ui/manual_clamp.rs:334:5 | LL | / if x32 < CONST_MIN { LL | | @@ -384,7 +384,7 @@ LL | | } = note: clamp will panic if max < min error: clamp-like pattern without using clamp function - --> tests/ui/manual_clamp.rs:525:13 + --> tests/ui/manual_clamp.rs:526:13 | LL | let _ = if input > CONST_MAX { | _____________^ diff --git a/tests/ui/needless_bitwise_bool.fixed b/tests/ui/needless_bitwise_bool.fixed index 89a3c1474f25..751d3d257000 100644 --- a/tests/ui/needless_bitwise_bool.fixed +++ b/tests/ui/needless_bitwise_bool.fixed @@ -34,7 +34,9 @@ fn main() { println!("true") // This is a const method call } - if y & (0 < 1) { + // Resolved + if y && (0 < 1) { + //~^ needless_bitwise_bool println!("true") // This is a BinOp with no side effects } } diff --git a/tests/ui/needless_bitwise_bool.rs b/tests/ui/needless_bitwise_bool.rs index f5aa7a9f3d9e..5d3ff3b2079c 100644 --- a/tests/ui/needless_bitwise_bool.rs +++ b/tests/ui/needless_bitwise_bool.rs @@ -34,7 +34,9 @@ fn main() { println!("true") // This is a const method call } + // Resolved if y & (0 < 1) { + //~^ needless_bitwise_bool println!("true") // This is a BinOp with no side effects } } diff --git a/tests/ui/needless_bitwise_bool.stderr b/tests/ui/needless_bitwise_bool.stderr index 9f14646c3e5a..4f64c7136916 100644 --- a/tests/ui/needless_bitwise_bool.stderr +++ b/tests/ui/needless_bitwise_bool.stderr @@ -7,5 +7,11 @@ LL | if y & !x { = note: `-D clippy::needless-bitwise-bool` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_bitwise_bool)]` -error: aborting due to 1 previous error +error: use of bitwise operator instead of lazy operator between booleans + --> tests/ui/needless_bitwise_bool.rs:38:8 + | +LL | if y & (0 < 1) { + | ^^^^^^^^^^^ help: try: `y && (0 < 1)` + +error: aborting due to 2 previous errors From d32f1c695fb7a1082b710fd0ff7516a824bc2cff Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Mon, 5 Jan 2026 13:59:22 +0000 Subject: [PATCH 1632/3801] add const ctor support --- .../src/hir_ty_lowering/mod.rs | 58 ++++++++++++-- tests/crashes/132985.rs | 17 ---- tests/crashes/136138.rs | 7 -- tests/crashes/139596.rs | 10 --- tests/crashes/mgca/ace-with-const-ctor.rs | 16 ---- .../ice-associated-const-equality-105952.rs | 20 +++++ .../mgca/const-ctor-overflow-eval.rs | 19 +++++ .../mgca/const-ctor-overflow-eval.stderr | 80 +++++++++++++++++++ .../mgca/const-ctor-with-error.rs | 19 +++++ .../mgca/const-ctor-with-error.stderr | 14 ++++ tests/ui/const-generics/mgca/const-ctor.rs | 49 ++++++++++++ 11 files changed, 254 insertions(+), 55 deletions(-) delete mode 100644 tests/crashes/132985.rs delete mode 100644 tests/crashes/136138.rs delete mode 100644 tests/crashes/139596.rs delete mode 100644 tests/crashes/mgca/ace-with-const-ctor.rs create mode 100644 tests/rustdoc/constant/ice-associated-const-equality-105952.rs create mode 100644 tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs create mode 100644 tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr create mode 100644 tests/ui/const-generics/mgca/const-ctor-with-error.rs create mode 100644 tests/ui/const-generics/mgca/const-ctor-with-error.stderr create mode 100644 tests/ui/const-generics/mgca/const-ctor.rs 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 d0f25e8fc321..a22729fd287e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1415,9 +1415,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ct = self.check_param_uses_if_mcg(ct, span, false); Ok(ct) } - TypeRelativePath::Ctor { ctor_def_id, args } => { - return Ok(ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, ctor_def_id, args))); - } + TypeRelativePath::Ctor { ctor_def_id, args } => match tcx.def_kind(ctor_def_id) { + DefKind::Ctor(_, CtorKind::Fn) => { + Ok(ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, ctor_def_id, args))) + } + DefKind::Ctor(ctor_of, CtorKind::Const) => { + Ok(self.construct_const_ctor_value(ctor_def_id, ctor_of, args)) + } + _ => unreachable!(), + }, // FIXME(mgca): implement support for this once ready to support all adt ctor expressions, // not just const ctors TypeRelativePath::Variant { .. } => { @@ -1452,7 +1458,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME(mgca): do we want constructor resolutions to take priority over // other possible resolutions? if matches!(mode, LowerTypeRelativePathMode::Const) - && let Some((CtorKind::Fn, ctor_def_id)) = variant_def.ctor + && let Some((_, ctor_def_id)) = variant_def.ctor { tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None); let _ = self.prohibit_generic_args( @@ -2597,7 +2603,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); self.lower_const_param(def_id, hir_id) } - Res::Def(DefKind::Const | DefKind::Ctor(_, CtorKind::Const), did) => { + Res::Def(DefKind::Const, did) => { assert_eq!(opt_self_ty, None); let [leading_segments @ .., segment] = path.segments else { bug!() }; let _ = self @@ -2605,6 +2611,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let args = self.lower_generic_args_of_path_segment(span, did, segment); ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args)) } + Res::Def(DefKind::Ctor(ctor_of, CtorKind::Const), did) => { + assert_eq!(opt_self_ty, None); + let [leading_segments @ .., segment] = path.segments else { bug!() }; + let _ = self + .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None); + + let parent_did = tcx.parent(did); + let generics_did = match ctor_of { + CtorOf::Variant => tcx.parent(parent_did), + CtorOf::Struct => parent_did, + }; + let args = self.lower_generic_args_of_path_segment(span, generics_did, segment); + + self.construct_const_ctor_value(did, ctor_of, args) + } Res::Def(DefKind::Ctor(_, CtorKind::Fn), did) => { assert_eq!(opt_self_ty, None); let [leading_segments @ .., segment] = path.segments else { bug!() }; @@ -3174,4 +3195,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } Some(r) } + + fn construct_const_ctor_value( + &self, + ctor_def_id: DefId, + ctor_of: CtorOf, + args: GenericArgsRef<'tcx>, + ) -> Const<'tcx> { + let tcx = self.tcx(); + let parent_did = tcx.parent(ctor_def_id); + + let adt_def = tcx.adt_def(match ctor_of { + CtorOf::Variant => tcx.parent(parent_did), + CtorOf::Struct => parent_did, + }); + + let variant_idx = adt_def.variant_index_with_id(parent_did); + + let valtree = if adt_def.is_enum() { + let discr = ty::ValTree::from_scalar_int(tcx, variant_idx.as_u32().into()); + ty::ValTree::from_branches(tcx, [ty::Const::new_value(tcx, discr, tcx.types.u32)]) + } else { + ty::ValTree::zst(tcx) + }; + + let adt_ty = Ty::new_adt(tcx, adt_def, args); + ty::Const::new_value(tcx, valtree, adt_ty) + } } diff --git a/tests/crashes/132985.rs b/tests/crashes/132985.rs deleted file mode 100644 index 2735074f44d1..000000000000 --- a/tests/crashes/132985.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #132985 -//@ aux-build:aux132985.rs - -#![allow(incomplete_features)] -#![feature(min_generic_const_args)] -#![feature(adt_const_params)] - -extern crate aux132985; -use aux132985::Foo; - -fn bar() {} - -fn baz() { - bar::<{ Foo }>(); -} - -fn main() {} diff --git a/tests/crashes/136138.rs b/tests/crashes/136138.rs deleted file mode 100644 index c3893dc9c8e6..000000000000 --- a/tests/crashes/136138.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #136138 -#![feature(min_generic_const_args)] -struct U; -struct S() -where - S<{ U }>:; -fn main() {} diff --git a/tests/crashes/139596.rs b/tests/crashes/139596.rs deleted file mode 100644 index 590cfddf83e2..000000000000 --- a/tests/crashes/139596.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #139596 - -#![feature(min_generic_const_args)] -struct Colour; - -struct Led; - -fn main() { - Led::<{ Colour}>; -} diff --git a/tests/crashes/mgca/ace-with-const-ctor.rs b/tests/crashes/mgca/ace-with-const-ctor.rs deleted file mode 100644 index 28e85f37de1f..000000000000 --- a/tests/crashes/mgca/ace-with-const-ctor.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: #132980 -// Originally a rustdoc test. Should be moved back there with @has checks -// readded once fixed. -// Previous issue (before mgca): https://github.com/rust-lang/rust/issues/105952 -#![crate_name = "foo"] -#![feature(min_generic_const_args)] -pub enum ParseMode { - Raw, -} -pub trait Parse { - #[type_const] - const PARSE_MODE: ParseMode; -} -pub trait RenderRaw {} - -impl> RenderRaw for T {} diff --git a/tests/rustdoc/constant/ice-associated-const-equality-105952.rs b/tests/rustdoc/constant/ice-associated-const-equality-105952.rs new file mode 100644 index 000000000000..310e56b917fc --- /dev/null +++ b/tests/rustdoc/constant/ice-associated-const-equality-105952.rs @@ -0,0 +1,20 @@ +//! Regression test for + +#![crate_name = "foo"] +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +pub enum ParseMode { + Raw, +} +pub trait Parse { + #[type_const] + const PARSE_MODE: ParseMode; +} +pub trait RenderRaw {} + +//@ hasraw foo/trait.RenderRaw.html 'impl' +//@ hasraw foo/trait.RenderRaw.html 'ParseMode::Raw' +impl> RenderRaw for T {} diff --git a/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs new file mode 100644 index 000000000000..6a4ee3ed1772 --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs @@ -0,0 +1,19 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +use std::marker::ConstParamTy; + +#[derive(ConstParamTy, PartialEq, Eq)] +struct U; + +#[derive(ConstParamTy, PartialEq, Eq)] +//~^ ERROR overflow evaluating the requirement `S well-formed` +//~| ERROR overflow evaluating the requirement `S well-formed` + +struct S() +where + S<{ U }>:; +//~^ ERROR overflow evaluating the requirement `S well-formed` +//~| ERROR overflow evaluating the requirement `S well-formed` +//~| ERROR overflow evaluating the requirement `S well-formed` + +fn main() {} diff --git a/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr new file mode 100644 index 000000000000..4c5ad645bc45 --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr @@ -0,0 +1,80 @@ +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | S<{ U }>:; + | ^^^^^^^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | S<{ U }>:; + | ^^^^^^^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | S<{ U }>:; + | ^^^^^^^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:8:24 + | +LL | #[derive(ConstParamTy, PartialEq, Eq)] + | ^^^^^^^^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:8:35 + | +LL | #[derive(ConstParamTy, PartialEq, Eq)] + | ^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/const-generics/mgca/const-ctor-with-error.rs b/tests/ui/const-generics/mgca/const-ctor-with-error.rs new file mode 100644 index 000000000000..95a910e3dd2c --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor-with-error.rs @@ -0,0 +1,19 @@ +// to ensure it does not ices like before + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +use std::marker::ConstParamTy; + +#[derive(ConstParamTy, PartialEq, Eq)] +enum Option { + #[allow(dead_code)] + Some(T), + None, +} + +fn pass_enum>() {} + +fn main() { + pass_enum::<{ None }>(); + //~^ ERROR missing generics for enum `std::option::Option` +} diff --git a/tests/ui/const-generics/mgca/const-ctor-with-error.stderr b/tests/ui/const-generics/mgca/const-ctor-with-error.stderr new file mode 100644 index 000000000000..8684457a978b --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor-with-error.stderr @@ -0,0 +1,14 @@ +error[E0107]: missing generics for enum `std::option::Option` + --> $DIR/const-ctor-with-error.rs:17:19 + | +LL | pass_enum::<{ None }>(); + | ^^^^ expected 1 generic argument + | +help: add missing generic argument + | +LL | pass_enum::<{ None }>(); + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/const-generics/mgca/const-ctor.rs b/tests/ui/const-generics/mgca/const-ctor.rs new file mode 100644 index 000000000000..19900b56a816 --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor.rs @@ -0,0 +1,49 @@ +//! Regression test for +//! +//! + +//@ check-pass + +#![feature( + min_generic_const_args, + adt_const_params, + generic_const_parameter_types, + unsized_const_params +)] +#![expect(incomplete_features)] +use std::marker::{ConstParamTy, ConstParamTy_}; +#[derive(ConstParamTy, PartialEq, Eq)] +struct Colour; + +#[derive(ConstParamTy, PartialEq, Eq)] +enum A { + B, +} + +#[derive(ConstParamTy, PartialEq, Eq)] +enum MyOption { + #[allow(dead_code)] + Some(T), + None, +} + +#[derive(ConstParamTy, PartialEq, Eq)] +struct Led; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Foo; + +fn pass_enum>() {} + +fn accepts_foo>() {} + +fn accepts_bar>() {} + +fn test() { + accepts_foo:: }>(); + accepts_bar:: }>(); +} + +fn main() { + Led::<{ Colour }>; +} From 460f22c38823b3478ff5aa5f9083968974532177 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Dec 2025 20:02:51 +0300 Subject: [PATCH 1633/3801] resolve: Rename `NameBinding(Data,Kind)` to `Decl(Data,Kind)` Also, rename `DeclKind::Res` to `DeclKind::Def`. --- compiler/rustc_middle/src/metadata.rs | 2 +- .../rustc_resolve/src/build_reduced_graph.rs | 16 +- compiler/rustc_resolve/src/check_unused.rs | 6 +- compiler/rustc_resolve/src/diagnostics.rs | 56 +++---- .../src/effective_visibilities.rs | 20 +-- compiler/rustc_resolve/src/ident.rs | 60 +++---- compiler/rustc_resolve/src/imports.rs | 76 ++++----- compiler/rustc_resolve/src/late.rs | 8 +- compiler/rustc_resolve/src/lib.rs | 153 +++++++++--------- compiler/rustc_resolve/src/macros.rs | 14 +- 10 files changed, 195 insertions(+), 216 deletions(-) diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index b7848bc261d8..9e5b3ef61905 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -26,7 +26,7 @@ impl Reexport { } } -/// This structure is supposed to keep enough data to re-create `NameBinding`s for other crates +/// This structure is supposed to keep enough data to re-create `Decl`s for other crates /// during name resolution. Right now the bindings are not recreated entirely precisely so we may /// need to add more data in the future to correctly support macros 2.0, for example. /// Module child can be either a proper item or a reexport (including private imports). diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 241c13663ae5..d31723844290 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -36,9 +36,9 @@ use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use crate::ref_mut::CmCell; use crate::{ - BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot, - NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, ResolutionError, - Resolver, Segment, Used, VisResolutionError, errors, + BindingKey, Decl, DeclData, DeclKind, ExternPreludeEntry, Finalize, MacroData, Module, + ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, ResolutionError, Resolver, Segment, + Used, VisResolutionError, errors, }; type Res = def::Res; @@ -51,7 +51,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent: Module<'ra>, ident: Ident, ns: Namespace, - binding: NameBinding<'ra>, + binding: Decl<'ra>, ) { if let Err(old_binding) = self.try_define_local(parent, ident, ns, binding, false) { self.report_conflict(parent, ident, ns, old_binding, binding); @@ -82,10 +82,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { vis: Visibility, span: Span, expansion: LocalExpnId, - ambiguity: Option>, + ambiguity: Option>, ) { - let binding = self.arenas.alloc_name_binding(NameBindingData { - kind: NameBindingKind::Res(res), + let binding = self.arenas.alloc_name_binding(DeclData { + kind: DeclKind::Def(res), ambiguity, // External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment. warn_ambiguity: true, @@ -1092,7 +1092,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { fn add_macro_use_binding( &mut self, name: Symbol, - binding: NameBinding<'ra>, + binding: Decl<'ra>, span: Span, allow_shadowing: bool, ) { diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 5349cf6d7dbe..b7705773041f 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -36,7 +36,7 @@ use rustc_session::lint::builtin::{ use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, kw}; use crate::imports::{Import, ImportKind}; -use crate::{LexicalScopeBinding, NameBindingKind, Resolver, module_to_string}; +use crate::{DeclKind, LexicalScopeBinding, Resolver, module_to_string}; struct UnusedImport { use_tree: ast::UseTree, @@ -515,7 +515,7 @@ impl Resolver<'_, '_> { for module in &self.local_modules { for (_key, resolution) in self.resolutions(*module).borrow().iter() { if let Some(binding) = resolution.borrow().best_binding() - && let NameBindingKind::Import { import, .. } = binding.kind + && let DeclKind::Import { import, .. } = binding.kind && let ImportKind::Single { id, .. } = import.kind { if let Some(unused_import) = unused_imports.get(&import.root_id) @@ -543,7 +543,7 @@ impl Resolver<'_, '_> { // in the item not being found. for unn_qua in &self.potentially_unnecessary_qualifications { if let LexicalScopeBinding::Item(name_binding) = unn_qua.binding - && let NameBindingKind::Import { import, .. } = name_binding.kind + && let DeclKind::Import { import, .. } = name_binding.kind && (is_unused_import(import, &unused_imports) || is_redundant_import(import, &redundant_imports)) { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 716e1d5a2e7f..7e78f66574ed 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -44,11 +44,11 @@ use crate::errors::{ use crate::imports::{Import, ImportKind}; use crate::late::{DiagMetadata, PatternSource, Rib}; use crate::{ - AmbiguityError, AmbiguityKind, BindingError, BindingKey, Finalize, + AmbiguityError, AmbiguityKind, BindingError, BindingKey, Decl, DeclKind, Finalize, ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, - ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, - PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, - VisResolutionError, errors as errs, path_names_to_string, + ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError, + Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs, + path_names_to_string, }; type Res = def::Res; @@ -149,8 +149,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if ambiguity_error.warning { let node_id = match ambiguity_error.b1.0.kind { - NameBindingKind::Import { import, .. } => import.root_id, - NameBindingKind::Res(_) => CRATE_NODE_ID, + DeclKind::Import { import, .. } => import.root_id, + DeclKind::Def(_) => CRATE_NODE_ID, }; self.lint_buffer.buffer_lint( AMBIGUOUS_GLOB_IMPORTS, @@ -212,8 +212,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent: Module<'_>, ident: Ident, ns: Namespace, - new_binding: NameBinding<'ra>, - old_binding: NameBinding<'ra>, + new_binding: Decl<'ra>, + old_binding: Decl<'ra>, ) { // Error on the second of two conflicting names if old_binding.span.lo() > new_binding.span.lo() { @@ -288,8 +288,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .with_code(code); // See https://github.com/rust-lang/rust/issues/32354 - use NameBindingKind::Import; - let can_suggest = |binding: NameBinding<'_>, import: self::Import<'_>| { + use DeclKind::Import; + let can_suggest = |binding: Decl<'_>, import: self::Import<'_>| { !binding.span.is_dummy() && !matches!(import.kind, ImportKind::MacroUse { .. } | ImportKind::MacroExport) }; @@ -473,7 +473,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &mut self, finalize: Finalize, path: &[Segment], - second_binding: Option>, + second_binding: Option>, ) { let Finalize { node_id, root_span, .. } = finalize; @@ -506,7 +506,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // `ExternCrate` (also used for `crate::...`) then no need to issue a // warning, this looks all good! if let Some(binding) = second_binding - && let NameBindingKind::Import { import, .. } = binding.kind + && let DeclKind::Import { import, .. } = binding.kind // Careful: we still want to rewrite paths from renamed extern crates. && let ImportKind::ExternCrate { source: None, .. } = import.kind { @@ -1360,7 +1360,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // #90113: Do not count an inaccessible reexported item as a candidate. - if let NameBindingKind::Import { binding, .. } = name_binding.kind + if let DeclKind::Import { binding, .. } = name_binding.kind && this.is_accessible_from(binding.vis, parent_scope.module) && !this.is_accessible_from(name_binding.vis, parent_scope.module) { @@ -1469,8 +1469,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut path_segments = path_segments.clone(); path_segments.push(ast::PathSegment::from_ident(ident.0)); - let alias_import = if let NameBindingKind::Import { import, .. } = - name_binding.kind + let alias_import = if let DeclKind::Import { import, .. } = name_binding.kind && let ImportKind::ExternCrate { source: Some(_), .. } = import.kind && import.parent_scope.expansion == parent_scope.expansion { @@ -1754,7 +1753,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { macro_kind.descr_expected(), ), }; - if let crate::NameBindingKind::Import { import, .. } = binding.kind + if let crate::DeclKind::Import { import, .. } = binding.kind && !import.span.is_dummy() { let note = errors::IdentImporterHereButItIsDesc { @@ -1971,7 +1970,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { true } - fn binding_description(&self, b: NameBinding<'_>, ident: Ident, scope: Scope<'_>) -> String { + fn binding_description(&self, b: Decl<'_>, ident: Ident, scope: Scope<'_>) -> String { let res = b.res(); if b.span.is_dummy() || !self.tcx.sess.source_map().is_span_accessible(b.span) { let (built_in, from) = match scope { @@ -2016,7 +2015,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { (b1, b2, scope1, scope2, false) }; - let could_refer_to = |b: NameBinding<'_>, scope: Scope<'ra>, also: &str| { + let could_refer_to = |b: Decl<'_>, scope: Scope<'ra>, also: &str| { let what = self.binding_description(b, ident, scope); let note_msg = format!("`{ident}` could{also} refer to {what}"); @@ -2075,11 +2074,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// If the binding refers to a tuple struct constructor with fields, /// returns the span of its fields. - fn ctor_fields_span(&self, binding: NameBinding<'_>) -> Option { - let NameBindingKind::Res(Res::Def( - DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), - ctor_def_id, - )) = binding.kind + fn ctor_fields_span(&self, binding: Decl<'_>) -> Option { + let DeclKind::Def(Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id)) = + binding.kind else { return None; }; @@ -2105,8 +2102,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let nonimport_descr = if ctor_fields_span.is_some() { plain_descr + " constructor" } else { plain_descr }; let import_descr = nonimport_descr.clone() + " import"; - let get_descr = - |b: NameBinding<'_>| if b.is_import() { &import_descr } else { &nonimport_descr }; + let get_descr = |b: Decl<'_>| if b.is_import() { &import_descr } else { &nonimport_descr }; // Print the primary message. let ident_descr = get_descr(binding); @@ -2217,7 +2213,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let name = next_ident; next_binding = match binding.kind { _ if res == Res::Err => None, - NameBindingKind::Import { binding, import, .. } => match import.kind { + DeclKind::Import { binding, import, .. } => match import.kind { _ if binding.span.is_dummy() => None, ImportKind::Single { source, .. } => { next_ident = source; @@ -2232,7 +2228,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; match binding.kind { - NameBindingKind::Import { import, .. } => { + DeclKind::Import { import, .. } => { for segment in import.module_path.iter().skip(1) { // Don't include `{{root}}` in suggestions - it's an internal symbol // that should never be shown to users. @@ -2245,14 +2241,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { true, // re-export )); } - NameBindingKind::Res(_) => {} + DeclKind::Def(_) => {} } let first = binding == first_binding; let def_span = self.tcx.sess.source_map().guess_head_span(binding.span); let mut note_span = MultiSpan::from_span(def_span); if !first && binding.vis.is_public() { let desc = match binding.kind { - NameBindingKind::Import { .. } => "re-export", + DeclKind::Import { .. } => "re-export", _ => "directly", }; note_span.push_span_label(def_span, format!("you could import this {desc}")); @@ -2418,7 +2414,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { opt_ns: Option, // `None` indicates a module path in import parent_scope: &ParentScope<'ra>, ribs: Option<&PerNS>>>, - ignore_binding: Option>, + ignore_binding: Option>, ignore_import: Option>, module: Option>, failed_segment_idx: usize, diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index fe6e5b8e6eb6..5d78f3752439 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -8,12 +8,12 @@ use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, use rustc_middle::ty::Visibility; use tracing::info; -use crate::{NameBinding, NameBindingKind, Resolver}; +use crate::{Decl, DeclKind, Resolver}; #[derive(Clone, Copy)] enum ParentId<'ra> { Def(LocalDefId), - Import(NameBinding<'ra>), + Import(Decl<'ra>), } impl ParentId<'_> { @@ -31,7 +31,7 @@ pub(crate) struct EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { /// While walking import chains we need to track effective visibilities per-binding, and def id /// keys in `Resolver::effective_visibilities` are not enough for that, because multiple /// bindings can correspond to a single def id in imports. So we keep a separate table. - import_effective_visibilities: EffectiveVisibilities>, + import_effective_visibilities: EffectiveVisibilities>, // It's possible to recalculate this at any point, but it's relatively expensive. current_private_vis: Visibility, changed: bool, @@ -42,8 +42,8 @@ impl Resolver<'_, '_> { self.get_nearest_non_block_module(def_id.to_def_id()).nearest_parent_mod().expect_local() } - fn private_vis_import(&self, binding: NameBinding<'_>) -> Visibility { - let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() }; + fn private_vis_import(&self, binding: Decl<'_>) -> Visibility { + let DeclKind::Import { import, .. } = binding.kind else { unreachable!() }; Visibility::Restricted( import .id() @@ -70,7 +70,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { pub(crate) fn compute_effective_visibilities<'c>( r: &'a mut Resolver<'ra, 'tcx>, krate: &'c Crate, - ) -> FxHashSet> { + ) -> FxHashSet> { let mut visitor = EffectiveVisibilitiesVisitor { r, def_effective_visibilities: Default::default(), @@ -95,7 +95,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { // information, but are used by later passes. Effective visibility of an import def id // is the maximum value among visibilities of bindings corresponding to that def id. for (binding, eff_vis) in visitor.import_effective_visibilities.iter() { - let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() }; + let DeclKind::Import { import, .. } = binding.kind else { unreachable!() }; if !binding.is_ambiguity_recursive() { if let Some(node_id) = import.id() { r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx) @@ -126,10 +126,10 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { // leading to it into the table. They are used by the `ambiguous_glob_reexports` // lint. For all bindings added to the table this way `is_ambiguity` returns true. let is_ambiguity = - |binding: NameBinding<'ra>, warn: bool| binding.ambiguity.is_some() && !warn; + |binding: Decl<'ra>, warn: bool| binding.ambiguity.is_some() && !warn; let mut parent_id = ParentId::Def(module_id); let mut warn_ambiguity = binding.warn_ambiguity; - while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind { + while let DeclKind::Import { binding: nested_binding, .. } = binding.kind { self.update_import(binding, parent_id); if is_ambiguity(binding, warn_ambiguity) { @@ -188,7 +188,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { } } - fn update_import(&mut self, binding: NameBinding<'ra>, parent_id: ParentId<'ra>) { + fn update_import(&mut self, binding: Decl<'ra>, parent_id: ParentId<'ra>) { let nominal_vis = binding.vis.expect_local(); let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return }; let inherited_eff_vis = self.effective_vis_or_private(parent_id); diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index b6ec26be5ca1..7ebc75abca89 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -19,10 +19,10 @@ use crate::late::{ }; use crate::macros::{MacroRulesScope, sub_namespace_match}; use crate::{ - AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Determinacy, Finalize, ImportKind, - LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, - ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, - Segment, Stage, Used, errors, + AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Decl, DeclKind, Determinacy, Finalize, + ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, + PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, + Used, errors, }; #[derive(Copy, Clone)] @@ -305,7 +305,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, finalize: Option, ribs: &[Rib<'ra>], - ignore_binding: Option>, + ignore_binding: Option>, diag_metadata: Option<&DiagMetadata<'_>>, ) -> Option> { let orig_ident = ident; @@ -392,9 +392,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, finalize: Option, force: bool, - ignore_binding: Option>, + ignore_binding: Option>, ignore_import: Option>, - ) -> Result, Determinacy> { + ) -> Result, Determinacy> { assert!(force || finalize.is_none()); // `finalize` implies `force` // Make sure `self`, `super` etc produce an error when passed to here. @@ -425,7 +425,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // } // So we have to save the innermost solution and continue searching in outer scopes // to detect potential ambiguities. - let mut innermost_results: Vec<(NameBinding<'_>, Scope<'_>)> = Vec::new(); + let mut innermost_results: Vec<(Decl<'_>, Scope<'_>)> = Vec::new(); let mut determinacy = Determinacy::Determined; // Go through all the scopes and try to resolve the name. @@ -518,9 +518,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, finalize: Option, force: bool, - ignore_binding: Option>, + ignore_binding: Option>, ignore_import: Option>, - ) -> Result, ControlFlow> { + ) -> Result, ControlFlow> { let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); let ret = match scope { Scope::DeriveHelpers(expn_id) => { @@ -759,9 +759,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns: Namespace, scope_set: ScopeSet<'ra>, parent_scope: &ParentScope<'ra>, - binding: NameBinding<'ra>, + binding: Decl<'ra>, scope: Scope<'ra>, - innermost_results: &[(NameBinding<'ra>, Scope<'ra>)], + innermost_results: &[(Decl<'ra>, Scope<'ra>)], ) -> bool { let (innermost_binding, innermost_scope) = *innermost_results.first().unwrap(); let (res, innermost_res) = (binding.res(), innermost_binding.res()); @@ -869,7 +869,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns: Namespace, parent_scope: &ParentScope<'ra>, ignore_import: Option>, - ) -> Result, Determinacy> { + ) -> Result, Determinacy> { self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import) } @@ -881,9 +881,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns: Namespace, parent_scope: &ParentScope<'ra>, finalize: Option, - ignore_binding: Option>, + ignore_binding: Option>, ignore_import: Option>, - ) -> Result, Determinacy> { + ) -> Result, Determinacy> { let tmp_parent_scope; let mut adjusted_parent_scope = parent_scope; match module { @@ -921,9 +921,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns: Namespace, parent_scope: &ParentScope<'ra>, finalize: Option, - ignore_binding: Option>, + ignore_binding: Option>, ignore_import: Option>, - ) -> Result, Determinacy> { + ) -> Result, Determinacy> { match module { ModuleOrUniformRoot::Module(module) => self.resolve_ident_in_scope_set( ident, @@ -994,9 +994,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize: Option, // This binding should be ignored during in-module resolution, so that we don't get // "self-confirming" import resolutions during import validation and checking. - ignore_binding: Option>, + ignore_binding: Option>, ignore_import: Option>, - ) -> Result, ControlFlow> { + ) -> Result, ControlFlow> { let key = BindingKey::new(ident, ns); // `try_borrow_mut` is required to ensure exclusive access, even if the resulting binding // doesn't need to be mutable. It will fail when there is a cycle of imports, and without @@ -1055,9 +1055,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, shadowing: Shadowing, finalize: Option, - ignore_binding: Option>, + ignore_binding: Option>, ignore_import: Option>, - ) -> Result, ControlFlow> { + ) -> Result, ControlFlow> { let key = BindingKey::new(ident, ns); // `try_borrow_mut` is required to ensure exclusive access, even if the resulting binding // doesn't need to be mutable. It will fail when there is a cycle of imports, and without @@ -1179,12 +1179,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn finalize_module_binding( &mut self, ident: Ident, - binding: Option>, + binding: Option>, parent_scope: &ParentScope<'ra>, module: Module<'ra>, finalize: Finalize, shadowing: Shadowing, - ) -> Result, ControlFlow> { + ) -> Result, ControlFlow> { let Finalize { path_span, report_private, used, root_span, .. } = finalize; let Some(binding) = binding else { @@ -1209,7 +1209,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if shadowing == Shadowing::Unrestricted && binding.expansion != LocalExpnId::ROOT - && let NameBindingKind::Import { import, .. } = binding.kind + && let DeclKind::Import { import, .. } = binding.kind && matches!(import.kind, ImportKind::MacroExport) { self.macro_expanded_macro_export_errors.insert((path_span, binding.span)); @@ -1255,15 +1255,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn single_import_can_define_name<'r>( mut self: CmResolver<'r, 'ra, 'tcx>, resolution: &NameResolution<'ra>, - binding: Option>, + binding: Option>, ns: Namespace, ignore_import: Option>, - ignore_binding: Option>, + ignore_binding: Option>, parent_scope: &ParentScope<'ra>, ) -> bool { for single_import in &resolution.single_imports { if let Some(binding) = resolution.non_glob_binding - && let NameBindingKind::Import { import, .. } = binding.kind + && let DeclKind::Import { import, .. } = binding.kind && import == *single_import { // Single import has already defined the name and we are aware of it, @@ -1277,7 +1277,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { continue; } if let Some(ignored) = ignore_binding - && let NameBindingKind::Import { import, .. } = ignored.kind + && let DeclKind::Import { import, .. } = ignored.kind && import == *single_import { continue; @@ -1668,7 +1668,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { opt_ns: Option, // `None` indicates a module path in import parent_scope: &ParentScope<'ra>, finalize: Option, - ignore_binding: Option>, + ignore_binding: Option>, ignore_import: Option>, ) -> PathResult<'ra> { self.resolve_path_with_ribs( @@ -1692,7 +1692,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { source: Option>, finalize: Option, ribs: Option<&PerNS>>>, - ignore_binding: Option>, + ignore_binding: Option>, ignore_import: Option>, diag_metadata: Option<&DiagMetadata<'_>>, ) -> PathResult<'ra> { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 558f769eda19..7648b980ec5c 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -32,23 +32,23 @@ use crate::errors::{ }; use crate::ref_mut::CmCell; use crate::{ - AmbiguityError, BindingKey, CmResolver, Determinacy, Finalize, ImportSuggestion, Module, - ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult, - PerNS, ResolutionError, Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string, + AmbiguityError, BindingKey, CmResolver, Decl, DeclData, DeclKind, Determinacy, Finalize, + ImportSuggestion, Module, ModuleOrUniformRoot, ParentScope, PathResult, PerNS, ResolutionError, + Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string, }; type Res = def::Res; -/// A [`NameBinding`] in the process of being resolved. +/// A [`Decl`] in the process of being resolved. #[derive(Clone, Copy, Default, PartialEq)] pub(crate) enum PendingBinding<'ra> { - Ready(Option>), + Ready(Option>), #[default] Pending, } impl<'ra> PendingBinding<'ra> { - pub(crate) fn binding(self) -> Option> { + pub(crate) fn binding(self) -> Option> { match self { PendingBinding::Ready(binding) => binding, PendingBinding::Pending => None, @@ -244,14 +244,14 @@ pub(crate) struct NameResolution<'ra> { /// Imports are arena-allocated, so it's ok to use pointers as keys. pub single_imports: FxIndexSet>, /// The non-glob binding for this name, if it is known to exist. - pub non_glob_binding: Option>, + pub non_glob_binding: Option>, /// The glob binding for this name, if it is known to exist. - pub glob_binding: Option>, + pub glob_binding: Option>, } impl<'ra> NameResolution<'ra> { /// Returns the binding for the name if it is known or None if it not known. - pub(crate) fn binding(&self) -> Option> { + pub(crate) fn binding(&self) -> Option> { self.best_binding().and_then(|binding| { if !binding.is_glob_import() || self.single_imports.is_empty() { Some(binding) @@ -261,7 +261,7 @@ impl<'ra> NameResolution<'ra> { }) } - pub(crate) fn best_binding(&self) -> Option> { + pub(crate) fn best_binding(&self) -> Option> { self.non_glob_binding.or(self.glob_binding) } } @@ -282,12 +282,9 @@ struct UnresolvedImportError { // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;` // are permitted for backward-compatibility under a deprecation lint. -fn pub_use_of_private_extern_crate_hack( - import: Import<'_>, - binding: NameBinding<'_>, -) -> Option { +fn pub_use_of_private_extern_crate_hack(import: Import<'_>, binding: Decl<'_>) -> Option { match (&import.kind, &binding.kind) { - (ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. }) + (ImportKind::Single { .. }, DeclKind::Import { import: binding_import, .. }) if let ImportKind::ExternCrate { id, .. } = binding_import.kind && import.vis.is_public() => { @@ -300,11 +297,7 @@ fn pub_use_of_private_extern_crate_hack( impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Given a binding and an import that resolves to it, /// return the corresponding binding defined by the import. - pub(crate) fn import( - &self, - binding: NameBinding<'ra>, - import: Import<'ra>, - ) -> NameBinding<'ra> { + pub(crate) fn import(&self, binding: Decl<'ra>, import: Import<'ra>) -> Decl<'ra> { let import_vis = import.vis.to_def_id(); let vis = if binding.vis.is_at_least(import_vis, self.tcx) || pub_use_of_private_extern_crate_hack(import, binding).is_some() @@ -321,8 +314,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { max_vis.set_unchecked(Some(vis.expect_local())) } - self.arenas.alloc_name_binding(NameBindingData { - kind: NameBindingKind::Import { binding, import }, + self.arenas.alloc_name_binding(DeclData { + kind: DeclKind::Import { binding, import }, ambiguity: None, warn_ambiguity: false, span: import.span, @@ -337,9 +330,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module: Module<'ra>, ident: Ident, ns: Namespace, - binding: NameBinding<'ra>, + binding: Decl<'ra>, warn_ambiguity: bool, - ) -> Result<(), NameBinding<'ra>> { + ) -> Result<(), Decl<'ra>> { let res = binding.res(); self.check_reserved_macro_name(ident, res); self.set_binding_parent_module(binding, module); @@ -361,9 +354,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let (glob_binding, old_glob_binding) = (binding, old_binding); // FIXME: remove `!binding.is_ambiguity_recursive()` after delete the warning ambiguity. if !binding.is_ambiguity_recursive() - && let NameBindingKind::Import { import: old_import, .. } = + && let DeclKind::Import { import: old_import, .. } = old_glob_binding.kind - && let NameBindingKind::Import { import, .. } = glob_binding.kind + && let DeclKind::Import { import, .. } = glob_binding.kind && old_import == import { // When imported from the same glob-import statement, we should replace @@ -421,18 +414,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn new_ambiguity_binding( &self, - primary_binding: NameBinding<'ra>, - secondary_binding: NameBinding<'ra>, + primary_binding: Decl<'ra>, + secondary_binding: Decl<'ra>, warn_ambiguity: bool, - ) -> NameBinding<'ra> { + ) -> Decl<'ra> { let ambiguity = Some(secondary_binding); - let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding }; + let data = DeclData { ambiguity, warn_ambiguity, ..*primary_binding }; self.arenas.alloc_name_binding(data) } - fn new_warn_ambiguity_binding(&self, binding: NameBinding<'ra>) -> NameBinding<'ra> { + fn new_warn_ambiguity_binding(&self, binding: Decl<'ra>) -> Decl<'ra> { assert!(binding.is_ambiguity_recursive()); - self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding }) + self.arenas.alloc_name_binding(DeclData { warn_ambiguity: true, ..*binding }) } // Use `f` to mutate the resolution of the name in the module. @@ -634,13 +627,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - pub(crate) fn lint_reexports(&mut self, exported_ambiguities: FxHashSet>) { + pub(crate) fn lint_reexports(&mut self, exported_ambiguities: FxHashSet>) { for module in &self.local_modules { for (key, resolution) in self.resolutions(*module).borrow().iter() { let resolution = resolution.borrow(); let Some(binding) = resolution.best_binding() else { continue }; - if let NameBindingKind::Import { import, .. } = binding.kind + if let DeclKind::Import { import, .. } = binding.kind && let Some(amb_binding) = binding.ambiguity && binding.res() != Res::Err && exported_ambiguities.contains(&binding) @@ -663,8 +656,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { { if binding.res() != Res::Err && glob_binding.res() != Res::Err - && let NameBindingKind::Import { import: glob_import, .. } = - glob_binding.kind + && let DeclKind::Import { import: glob_import, .. } = glob_binding.kind && let Some(glob_import_id) = glob_import.id() && let glob_import_def_id = self.local_def_id(glob_import_id) && self.effective_visibilities.is_exported(glob_import_def_id) @@ -672,10 +664,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && !binding.vis.is_public() { let binding_id = match binding.kind { - NameBindingKind::Res(res) => { + DeclKind::Def(res) => { Some(self.def_id_to_node_id(res.def_id().expect_local())) } - NameBindingKind::Import { import, .. } => import.id(), + DeclKind::Import { import, .. } => import.id(), }; if let Some(binding_id) = binding_id { self.lint_buffer.buffer_lint( @@ -693,7 +685,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - if let NameBindingKind::Import { import, .. } = binding.kind + if let DeclKind::Import { import, .. } = binding.kind && let Some(binding_id) = import.id() && let import_def_id = self.local_def_id(binding_id) && self.effective_visibilities.is_exported(import_def_id) @@ -1207,11 +1199,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let resolution = resolution.borrow(); if let Some(name_binding) = resolution.best_binding() { match name_binding.kind { - NameBindingKind::Import { binding, .. } => { + DeclKind::Import { binding, .. } => { match binding.kind { // Never suggest the name that has binding error // i.e., the name that cannot be previously resolved - NameBindingKind::Res(Res::Err) => None, + DeclKind::Def(Res::Err) => None, _ => Some(i.name), } } @@ -1342,7 +1334,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; match binding.kind { - NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id)) + DeclKind::Def(Res::Def(DefKind::Macro(_), def_id)) // exclude decl_macro if self.get_macro_by_def_id(def_id).macro_rules => { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 0bf6fcba539e..0ec17a2d6d57 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -43,9 +43,9 @@ use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; use crate::{ - BindingError, BindingKey, Finalize, LexicalScopeBinding, Module, ModuleOrUniformRoot, - NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, Stage, TyCtxt, - UseError, Used, errors, path_names_to_string, rustdoc, + BindingError, BindingKey, Decl, Finalize, LexicalScopeBinding, Module, ModuleOrUniformRoot, + ParentScope, PathResult, ResolutionError, Resolver, Segment, Stage, TyCtxt, UseError, Used, + errors, path_names_to_string, rustdoc, }; mod diagnostics; @@ -1489,7 +1489,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ident: Ident, ns: Namespace, finalize: Option, - ignore_binding: Option>, + ignore_binding: Option>, ) -> Option> { self.r.resolve_ident_in_lexical_scope( ident, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index fbd16072c2c0..a0fda5511048 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -431,7 +431,7 @@ impl<'a> From<&'a ast::PathSegment> for Segment { /// forward. #[derive(Debug, Copy, Clone)] enum LexicalScopeBinding<'ra> { - Item(NameBinding<'ra>), + Item(Decl<'ra>), Res(Res), } @@ -624,8 +624,7 @@ struct ModuleData<'ra> { globs: CmRefCell>>, /// Used to memoize the traits in this module for faster searches through all traits in scope. - traits: - CmRefCell, Option>)]>>>, + traits: CmRefCell, Option>)]>>>, /// Span of the module itself. Used for error reporting. span: Span, @@ -634,7 +633,7 @@ struct ModuleData<'ra> { /// Binding for implicitly declared names that come with a module, /// like `self` (not yet used), or `crate`/`$crate` (for root modules). - self_binding: Option>, + self_binding: Option>, } /// All modules are unique and allocated on a same arena, @@ -663,7 +662,7 @@ impl<'ra> ModuleData<'ra> { expansion: ExpnId, span: Span, no_implicit_prelude: bool, - self_binding: Option>, + self_binding: Option>, ) -> Self { let is_foreign = match kind { ModuleKind::Def(_, def_id, _) => !def_id.is_local(), @@ -691,7 +690,7 @@ impl<'ra> Module<'ra> { fn for_each_child<'tcx, R: AsRef>>( self, resolver: &R, - mut f: impl FnMut(&R, Macros20NormalizedIdent, Namespace, NameBinding<'ra>), + mut f: impl FnMut(&R, Macros20NormalizedIdent, Namespace, Decl<'ra>), ) { for (key, name_resolution) in resolver.as_ref().resolutions(self).borrow().iter() { if let Some(binding) = name_resolution.borrow().best_binding() { @@ -703,7 +702,7 @@ impl<'ra> Module<'ra> { fn for_each_child_mut<'tcx, R: AsMut>>( self, resolver: &mut R, - mut f: impl FnMut(&mut R, Macros20NormalizedIdent, Namespace, NameBinding<'ra>), + mut f: impl FnMut(&mut R, Macros20NormalizedIdent, Namespace, Decl<'ra>), ) { for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() { if let Some(binding) = name_resolution.borrow().best_binding() { @@ -803,11 +802,11 @@ impl<'ra> fmt::Debug for Module<'ra> { } } -/// Records a possibly-private value, type, or module definition. +/// Data associated with any name declaration. #[derive(Clone, Copy, Debug)] -struct NameBindingData<'ra> { - kind: NameBindingKind<'ra>, - ambiguity: Option>, +struct DeclData<'ra> { + kind: DeclKind<'ra>, + ambiguity: Option>, /// Produce a warning instead of an error when reporting ambiguities inside this binding. /// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required. warn_ambiguity: bool, @@ -816,15 +815,15 @@ struct NameBindingData<'ra> { vis: Visibility, } -/// All name bindings are unique and allocated on a same arena, +/// All name declarations are unique and allocated on a same arena, /// so we can use referential equality to compare them. -type NameBinding<'ra> = Interned<'ra, NameBindingData<'ra>>; +type Decl<'ra> = Interned<'ra, DeclData<'ra>>; // Allows us to use Interned without actually enforcing (via Hash/PartialEq/...) uniqueness of the // contained data. // FIXME: We may wish to actually have at least debug-level assertions that Interned's guarantees // are upheld. -impl std::hash::Hash for NameBindingData<'_> { +impl std::hash::Hash for DeclData<'_> { fn hash(&self, _: &mut H) where H: std::hash::Hasher, @@ -833,23 +832,27 @@ impl std::hash::Hash for NameBindingData<'_> { } } +/// Name declaration kind. #[derive(Clone, Copy, Debug)] -enum NameBindingKind<'ra> { - Res(Res), - Import { binding: NameBinding<'ra>, import: Import<'ra> }, +enum DeclKind<'ra> { + /// The name declaration is a definition (possibly without a `DefId`), + /// can be provided by source code or built into the language. + Def(Res), + /// The name declaration is a link to another name declaration. + Import { binding: Decl<'ra>, import: Import<'ra> }, } -impl<'ra> NameBindingKind<'ra> { +impl<'ra> DeclKind<'ra> { /// Is this a name binding of an import? fn is_import(&self) -> bool { - matches!(*self, NameBindingKind::Import { .. }) + matches!(*self, DeclKind::Import { .. }) } } #[derive(Debug)] struct PrivacyError<'ra> { ident: Ident, - binding: NameBinding<'ra>, + binding: Decl<'ra>, dedup_span: Span, outermost_res: Option<(Res, Ident)>, parent_scope: ParentScope<'ra>, @@ -912,36 +915,34 @@ impl AmbiguityKind { struct AmbiguityError<'ra> { kind: AmbiguityKind, ident: Ident, - b1: NameBinding<'ra>, - b2: NameBinding<'ra>, + b1: Decl<'ra>, + b2: Decl<'ra>, // `empty_module` in module scope serves as an unknown module here. scope1: Scope<'ra>, scope2: Scope<'ra>, warning: bool, } -impl<'ra> NameBindingData<'ra> { +impl<'ra> DeclData<'ra> { fn res(&self) -> Res { match self.kind { - NameBindingKind::Res(res) => res, - NameBindingKind::Import { binding, .. } => binding.res(), + DeclKind::Def(res) => res, + DeclKind::Import { binding, .. } => binding.res(), } } - fn import_source(&self) -> NameBinding<'ra> { + fn import_source(&self) -> Decl<'ra> { match self.kind { - NameBindingKind::Import { binding, .. } => binding, + DeclKind::Import { binding, .. } => binding, _ => unreachable!(), } } - fn descent_to_ambiguity( - self: NameBinding<'ra>, - ) -> Option<(NameBinding<'ra>, NameBinding<'ra>)> { + fn descent_to_ambiguity(self: Decl<'ra>) -> Option<(Decl<'ra>, Decl<'ra>)> { match self.ambiguity { Some(ambig_binding) => Some((self, ambig_binding)), None => match self.kind { - NameBindingKind::Import { binding, .. } => binding.descent_to_ambiguity(), + DeclKind::Import { binding, .. } => binding.descent_to_ambiguity(), _ => None, }, } @@ -950,7 +951,7 @@ impl<'ra> NameBindingData<'ra> { fn is_ambiguity_recursive(&self) -> bool { self.ambiguity.is_some() || match self.kind { - NameBindingKind::Import { binding, .. } => binding.is_ambiguity_recursive(), + DeclKind::Import { binding, .. } => binding.is_ambiguity_recursive(), _ => false, } } @@ -958,46 +959,45 @@ impl<'ra> NameBindingData<'ra> { fn warn_ambiguity_recursive(&self) -> bool { self.warn_ambiguity || match self.kind { - NameBindingKind::Import { binding, .. } => binding.warn_ambiguity_recursive(), + DeclKind::Import { binding, .. } => binding.warn_ambiguity_recursive(), _ => false, } } fn is_possibly_imported_variant(&self) -> bool { match self.kind { - NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(), - NameBindingKind::Res(Res::Def( - DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), - _, - )) => true, - NameBindingKind::Res(..) => false, + DeclKind::Import { binding, .. } => binding.is_possibly_imported_variant(), + DeclKind::Def(Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _)) => { + true + } + DeclKind::Def(..) => false, } } fn is_extern_crate(&self) -> bool { match self.kind { - NameBindingKind::Import { import, .. } => { + DeclKind::Import { import, .. } => { matches!(import.kind, ImportKind::ExternCrate { .. }) } - NameBindingKind::Res(Res::Def(_, def_id)) => def_id.is_crate_root(), + DeclKind::Def(Res::Def(_, def_id)) => def_id.is_crate_root(), _ => false, } } fn is_import(&self) -> bool { - matches!(self.kind, NameBindingKind::Import { .. }) + matches!(self.kind, DeclKind::Import { .. }) } /// The binding introduced by `#[macro_export] macro_rules` is a public import, but it might /// not be perceived as such by users, so treat it as a non-import in some diagnostics. fn is_import_user_facing(&self) -> bool { - matches!(self.kind, NameBindingKind::Import { import, .. } + matches!(self.kind, DeclKind::Import { import, .. } if !matches!(import.kind, ImportKind::MacroExport)) } fn is_glob_import(&self) -> bool { match self.kind { - NameBindingKind::Import { import, .. } => import.is_glob(), + DeclKind::Import { import, .. } => import.is_glob(), _ => false, } } @@ -1010,10 +1010,10 @@ impl<'ra> NameBindingData<'ra> { self.res().macro_kinds() } - fn reexport_chain(self: NameBinding<'ra>, r: &Resolver<'_, '_>) -> SmallVec<[Reexport; 2]> { + fn reexport_chain(self: Decl<'ra>, r: &Resolver<'_, '_>) -> SmallVec<[Reexport; 2]> { let mut reexport_chain = SmallVec::new(); let mut next_binding = self; - while let NameBindingKind::Import { binding, import, .. } = next_binding.kind { + while let DeclKind::Import { binding, import, .. } = next_binding.kind { reexport_chain.push(import.simplify(r)); next_binding = binding; } @@ -1026,11 +1026,7 @@ impl<'ra> NameBindingData<'ra> { // in some later round and screw up our previously found resolution. // See more detailed explanation in // https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049 - fn may_appear_after( - &self, - invoc_parent_expansion: LocalExpnId, - binding: NameBinding<'_>, - ) -> bool { + fn may_appear_after(&self, invoc_parent_expansion: LocalExpnId, binding: Decl<'_>) -> bool { // self > max(invoc, binding) => !(self <= invoc || self <= binding) // Expansions are partially ordered, so "may appear after" is an inversion of // "certainly appears before or simultaneously" and includes unordered cases. @@ -1048,7 +1044,7 @@ impl<'ra> NameBindingData<'ra> { // FIXME: How can we integrate it with the `update_resolution`? fn determined(&self) -> bool { match &self.kind { - NameBindingKind::Import { binding, import, .. } if import.is_glob() => { + DeclKind::Import { binding, import, .. } if import.is_glob() => { import.parent_scope.module.unexpanded_invocations.borrow().is_empty() && binding.determined() } @@ -1061,7 +1057,7 @@ struct ExternPreludeEntry<'ra> { /// Binding from an `extern crate` item. /// The boolean flag is true is `item_binding` is non-redundant, happens either when /// `flag_binding` is `None`, or when `extern crate` introducing `item_binding` used renaming. - item_binding: Option<(NameBinding<'ra>, /* introduced by item */ bool)>, + item_binding: Option<(Decl<'ra>, /* introduced by item */ bool)>, /// Binding from an `--extern` flag, lazily populated on first use. flag_binding: Option, /* finalized */ bool)>>, } @@ -1181,7 +1177,7 @@ pub struct Resolver<'ra, 'tcx> { local_module_map: FxIndexMap>, /// Lazily populated cache of modules loaded from external crates. extern_module_map: CacheRefCell>>, - binding_parent_modules: FxHashMap, Module<'ra>>, + binding_parent_modules: FxHashMap, Module<'ra>>, /// Maps glob imports to the names of items actually imported. glob_map: FxIndexMap>, @@ -1206,14 +1202,14 @@ pub struct Resolver<'ra, 'tcx> { inaccessible_ctor_reexport: FxHashMap, arenas: &'ra ResolverArenas<'ra>, - dummy_binding: NameBinding<'ra>, - builtin_types_bindings: FxHashMap>, - builtin_attrs_bindings: FxHashMap>, - registered_tool_bindings: FxHashMap>, + dummy_binding: Decl<'ra>, + builtin_types_bindings: FxHashMap>, + builtin_attrs_bindings: FxHashMap>, + registered_tool_bindings: FxHashMap>, macro_names: FxHashSet, builtin_macros: FxHashMap, registered_tools: &'tcx RegisteredTools, - macro_use_prelude: FxIndexMap>, + macro_use_prelude: FxIndexMap>, /// Eagerly populated map of all local macro definitions. local_macro_map: FxHashMap, /// Lazily populated cache of macro definitions loaded from external crates. @@ -1229,7 +1225,7 @@ pub struct Resolver<'ra, 'tcx> { proc_macro_stubs: FxHashSet, /// Traces collected during macro resolution and validated when it's complete. single_segment_macro_resolutions: - CmRefCell, Option>, Option)>>, + CmRefCell, Option>, Option)>>, multi_segment_macro_resolutions: CmRefCell, Span, MacroKind, ParentScope<'ra>, Option, Namespace)>>, builtin_attrs: Vec<(Ident, ParentScope<'ra>)>, @@ -1246,7 +1242,7 @@ pub struct Resolver<'ra, 'tcx> { /// `macro_rules` scopes produced by `macro_rules` item definitions. macro_rules_scopes: FxHashMap>, /// Helper attributes that are in scope for the given expansion. - helper_attrs: FxHashMap)>>, + helper_attrs: FxHashMap)>>, /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute /// with the given `ExpnId`. derive_data: FxHashMap, @@ -1344,9 +1340,9 @@ impl<'ra> ResolverArenas<'ra> { vis: Visibility, span: Span, expansion: LocalExpnId, - ) -> NameBinding<'ra> { - self.alloc_name_binding(NameBindingData { - kind: NameBindingKind::Res(res), + ) -> Decl<'ra> { + self.alloc_name_binding(DeclData { + kind: DeclKind::Def(res), ambiguity: None, warn_ambiguity: false, vis, @@ -1355,12 +1351,7 @@ impl<'ra> ResolverArenas<'ra> { }) } - fn new_pub_res_binding( - &'ra self, - res: Res, - span: Span, - expn_id: LocalExpnId, - ) -> NameBinding<'ra> { + fn new_pub_res_binding(&'ra self, res: Res, span: Span, expn_id: LocalExpnId) -> Decl<'ra> { self.new_res_binding(res, Visibility::Public, span, expn_id) } @@ -1387,7 +1378,7 @@ impl<'ra> ResolverArenas<'ra> { self_binding, )))) } - fn alloc_name_binding(&'ra self, name_binding: NameBindingData<'ra>) -> NameBinding<'ra> { + fn alloc_name_binding(&'ra self, name_binding: DeclData<'ra>) -> Decl<'ra> { Interned::new_unchecked(self.dropless.alloc(name_binding)) } fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> { @@ -1994,11 +1985,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn find_transitive_imports( &mut self, - mut kind: &NameBindingKind<'_>, + mut kind: &DeclKind<'_>, trait_name: Ident, ) -> SmallVec<[LocalDefId; 1]> { let mut import_ids = smallvec![]; - while let NameBindingKind::Import { import, binding, .. } = kind { + while let DeclKind::Import { import, binding, .. } = kind { if let Some(node_id) = import.id() { let def_id = self.local_def_id(node_id); self.maybe_unused_trait_imports.insert(def_id); @@ -2053,14 +2044,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { false } - fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'ra>, used: Used) { + fn record_use(&mut self, ident: Ident, used_binding: Decl<'ra>, used: Used) { self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity); } fn record_use_inner( &mut self, ident: Ident, - used_binding: NameBinding<'ra>, + used_binding: Decl<'ra>, used: Used, warn_ambiguity: bool, ) { @@ -2079,7 +2070,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.ambiguity_errors.push(ambiguity_error); } } - if let NameBindingKind::Import { import, binding } = used_binding.kind { + if let DeclKind::Import { import, binding } = used_binding.kind { if let ImportKind::MacroUse { warn_private: true } = import.kind { // Do not report the lint if the macro name resolves in stdlib prelude // even without the problematic `macro_use` import. @@ -2236,7 +2227,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { vis.is_accessible_from(module.nearest_parent_mod(), self.tcx) } - fn set_binding_parent_module(&mut self, binding: NameBinding<'ra>, module: Module<'ra>) { + fn set_binding_parent_module(&mut self, binding: Decl<'ra>, module: Module<'ra>) { if let Some(old_module) = self.binding_parent_modules.insert(binding, module) { if module != old_module { span_bug!(binding.span, "parent module is reset for binding"); @@ -2246,8 +2237,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn disambiguate_macro_rules_vs_modularized( &self, - macro_rules: NameBinding<'ra>, - modularized: NameBinding<'ra>, + macro_rules: Decl<'ra>, + modularized: Decl<'ra>, ) -> bool { // Some non-controversial subset of ambiguities "modularized macro name" vs "macro_rules" // is disambiguated to mitigate regressions from macro modularization. @@ -2266,7 +2257,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { mut self: CmResolver<'r, 'ra, 'tcx>, ident: Ident, finalize: bool, - ) -> Option> { + ) -> Option> { let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)); entry.and_then(|entry| entry.item_binding).map(|(binding, _)| { if finalize { @@ -2276,7 +2267,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } - fn extern_prelude_get_flag(&self, ident: Ident, finalize: bool) -> Option> { + fn extern_prelude_get_flag(&self, ident: Ident, finalize: bool) -> Option> { let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)); entry.and_then(|entry| entry.flag_binding.as_ref()).and_then(|flag_binding| { let (pending_binding, finalized) = flag_binding.get(); diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 6bba985d87dd..07dd5d8fc889 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -38,9 +38,9 @@ use crate::errors::{ }; use crate::imports::Import; use crate::{ - BindingKey, CacheCell, CmResolver, DeriveData, Determinacy, Finalize, InvocationParent, - MacroData, ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, - PathResult, ResolutionError, Resolver, ScopeSet, Segment, Used, + BindingKey, CacheCell, CmResolver, Decl, DeclKind, DeriveData, Determinacy, Finalize, + InvocationParent, MacroData, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, + ResolutionError, Resolver, ScopeSet, Segment, Used, }; type Res = def::Res; @@ -49,7 +49,7 @@ type Res = def::Res; /// Not modularized, can shadow previous `macro_rules` bindings, etc. #[derive(Debug)] pub(crate) struct MacroRulesBinding<'ra> { - pub(crate) binding: NameBinding<'ra>, + pub(crate) binding: Decl<'ra>, /// `macro_rules` scope into which the `macro_rules` item was planted. pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'ra>, pub(crate) ident: Ident, @@ -1062,7 +1062,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn prohibit_imported_non_macro_attrs( &self, - binding: Option>, + binding: Option>, res: Option, span: Span, ) { @@ -1084,12 +1084,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { path: &ast::Path, parent_scope: &ParentScope<'ra>, invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>, - binding: Option>, + binding: Option>, ) { if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr && let Some(binding) = binding // This is a `macro_rules` itself, not some import. - && let NameBindingKind::Res(res) = binding.kind + && let DeclKind::Def(res) = binding.kind && let Res::Def(DefKind::Macro(kinds), def_id) = res && kinds.contains(MacroKinds::BANG) // And the `macro_rules` is defined inside the attribute's module, From 7a34af2f67bde4d4ab067c5a41c2b388adfc9531 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Dec 2025 20:36:30 +0300 Subject: [PATCH 1634/3801] resolve: Rename `LexicalScopeBinding::(Item,Res)` to `LateDecl::(Decl,RibDef)` --- compiler/rustc_resolve/src/check_unused.rs | 4 ++-- compiler/rustc_resolve/src/diagnostics.rs | 13 +++++----- compiler/rustc_resolve/src/ident.rs | 17 +++++++------ compiler/rustc_resolve/src/late.rs | 28 +++++++++++----------- compiler/rustc_resolve/src/lib.rs | 21 ++++++++-------- 5 files changed, 40 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index b7705773041f..a2e903ce48eb 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -36,7 +36,7 @@ use rustc_session::lint::builtin::{ use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, kw}; use crate::imports::{Import, ImportKind}; -use crate::{DeclKind, LexicalScopeBinding, Resolver, module_to_string}; +use crate::{DeclKind, LateDecl, Resolver, module_to_string}; struct UnusedImport { use_tree: ast::UseTree, @@ -542,7 +542,7 @@ impl Resolver<'_, '_> { // Deleting both unused imports and unnecessary segments of an item may result // in the item not being found. for unn_qua in &self.potentially_unnecessary_qualifications { - if let LexicalScopeBinding::Item(name_binding) = unn_qua.binding + if let LateDecl::Decl(name_binding) = unn_qua.binding && let DeclKind::Import { import, .. } = name_binding.kind && (is_unused_import(import, &unused_imports) || is_redundant_import(import, &redundant_imports)) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7e78f66574ed..99812fe4df53 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -45,10 +45,9 @@ use crate::imports::{Import, ImportKind}; use crate::late::{DiagMetadata, PatternSource, Rib}; use crate::{ AmbiguityError, AmbiguityKind, BindingError, BindingKey, Decl, DeclKind, Finalize, - ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, - ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError, - Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs, - path_names_to_string, + ForwardGenericParamBanReason, HasGenericParams, LateDecl, MacroRulesScope, Module, ModuleKind, + ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError, Resolver, Scope, + ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs, path_names_to_string, }; type Res = def::Res; @@ -2528,7 +2527,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { diag_metadata, ) { // we found a locally-imported or available item/module - Some(LexicalScopeBinding::Item(binding)) => Some(binding), + Some(LateDecl::Decl(binding)) => Some(binding), _ => None, } } else { @@ -2590,7 +2589,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // // variable `Foo`. // } // ``` - Some(LexicalScopeBinding::Res(Res::Local(id))) => { + Some(LateDecl::RibDef(Res::Local(id))) => { Some(*self.pat_span_map.get(&id).unwrap()) } // Name matches item from a local name binding @@ -2604,7 +2603,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // // binding `Foo`. // } // ``` - Some(LexicalScopeBinding::Item(name_binding)) => Some(name_binding.span), + Some(LateDecl::Decl(name_binding)) => Some(name_binding.span), _ => None, }; let suggestion = match_span.map(|span| { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 7ebc75abca89..a6a8545ac69e 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -20,9 +20,8 @@ use crate::late::{ use crate::macros::{MacroRulesScope, sub_namespace_match}; use crate::{ AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Decl, DeclKind, Determinacy, Finalize, - ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, - PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, - Used, errors, + ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, + PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Used, errors, }; #[derive(Copy, Clone)] @@ -307,7 +306,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ribs: &[Rib<'ra>], ignore_binding: Option>, diag_metadata: Option<&DiagMetadata<'_>>, - ) -> Option> { + ) -> Option> { let orig_ident = ident; let (general_span, normalized_span) = if ident.name == kw::SelfUpper { // FIXME(jseyfried) improve `Self` hygiene @@ -330,7 +329,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident }; if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) { // The ident resolves to a type parameter or local variable. - return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs( + return Some(LateDecl::RibDef(self.validate_res_from_ribs( i, rib_ident, *res, @@ -351,7 +350,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { // The ident resolves to an item in a block. - return Some(LexicalScopeBinding::Item(binding)); + return Some(LateDecl::Decl(binding)); } else if let RibKind::Module(module) = rib.kind { // Encountered a module item, abandon ribs and look into that module and preludes. let parent_scope = &ParentScope { module, ..*parent_scope }; @@ -368,7 +367,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, ) .ok() - .map(LexicalScopeBinding::Item); + .map(LateDecl::Decl); } if let RibKind::MacroDefinition(def) = rib.kind @@ -1836,9 +1835,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { diag_metadata, ) { // we found a locally-imported or available item/module - Some(LexicalScopeBinding::Item(binding)) => Ok(binding), + Some(LateDecl::Decl(binding)) => Ok(binding), // we found a local variable or type param - Some(LexicalScopeBinding::Res(res)) => { + Some(LateDecl::RibDef(res)) => { record_segment_res(self.reborrow(), finalize, res, id); return PathResult::NonModule(PartialRes::with_unresolved_segments( res, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 0ec17a2d6d57..2685efa28b64 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -43,9 +43,9 @@ use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; use crate::{ - BindingError, BindingKey, Decl, Finalize, LexicalScopeBinding, Module, ModuleOrUniformRoot, - ParentScope, PathResult, ResolutionError, Resolver, Segment, Stage, TyCtxt, UseError, Used, - errors, path_names_to_string, rustdoc, + BindingError, BindingKey, Decl, Finalize, LateDecl, Module, ModuleOrUniformRoot, ParentScope, + PathResult, ResolutionError, Resolver, Segment, Stage, TyCtxt, UseError, Used, errors, + path_names_to_string, rustdoc, }; mod diagnostics; @@ -677,7 +677,7 @@ impl MaybeExported<'_> { /// Used for recording UnnecessaryQualification. #[derive(Debug)] pub(crate) struct UnnecessaryQualification<'ra> { - pub binding: LexicalScopeBinding<'ra>, + pub binding: LateDecl<'ra>, pub node_id: NodeId, pub path_span: Span, pub removal_span: Span, @@ -1472,7 +1472,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { &mut self, ident: Ident, ns: Namespace, - ) -> Option> { + ) -> Option> { self.r.resolve_ident_in_lexical_scope( ident, ns, @@ -1490,7 +1490,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ns: Namespace, finalize: Option, ignore_binding: Option>, - ) -> Option> { + ) -> Option> { self.r.resolve_ident_in_lexical_scope( ident, ns, @@ -2685,11 +2685,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { for &ns in nss { match self.maybe_resolve_ident_in_lexical_scope(ident, ns) { - Some(LexicalScopeBinding::Res(..)) => { + Some(LateDecl::RibDef(..)) => { report_error(self, ns); } - Some(LexicalScopeBinding::Item(binding)) => { - if let Some(LexicalScopeBinding::Res(..)) = + Some(LateDecl::Decl(binding)) => { + if let Some(LateDecl::RibDef(..)) = self.resolve_ident_in_lexical_scope(ident, ns, None, Some(binding)) { report_error(self, ns); @@ -4257,7 +4257,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?; let (res, binding) = match ls_binding { - LexicalScopeBinding::Item(binding) + LateDecl::Decl(binding) if is_syntactic_ambiguity && binding.is_ambiguity_recursive() => { // For ambiguous bindings we don't know all their definitions and cannot check @@ -4267,8 +4267,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.r.record_use(ident, binding, Used::Other); return None; } - LexicalScopeBinding::Item(binding) => (binding.res(), Some(binding)), - LexicalScopeBinding::Res(res) => (res, None), + LateDecl::Decl(binding) => (binding.res(), Some(binding)), + LateDecl::RibDef(res) => (res, None), }; match res { @@ -4641,13 +4641,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { fn self_type_is_available(&mut self) -> bool { let binding = self .maybe_resolve_ident_in_lexical_scope(Ident::with_dummy_span(kw::SelfUpper), TypeNS); - if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false } + if let Some(LateDecl::RibDef(res)) = binding { res != Res::Err } else { false } } fn self_value_is_available(&mut self, self_span: Span) -> bool { let ident = Ident::new(kw::SelfLower, self_span); let binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS); - if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false } + if let Some(LateDecl::RibDef(res)) = binding { res != Res::Err } else { false } } /// A wrapper around [`Resolver::report_error`]. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index a0fda5511048..8982ec15de8f 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -424,22 +424,21 @@ impl<'a> From<&'a ast::PathSegment> for Segment { } } -/// An intermediate resolution result. -/// -/// This refers to the thing referred by a name. The difference between `Res` and `Item` is that -/// items are visible in their whole block, while `Res`es only from the place they are defined -/// forward. +/// Name declaration used during late resolution. #[derive(Debug, Copy, Clone)] -enum LexicalScopeBinding<'ra> { - Item(Decl<'ra>), - Res(Res), +enum LateDecl<'ra> { + /// A regular name declaration. + Decl(Decl<'ra>), + /// A name definition from a rib, e.g. a local variable. + /// Omits most of the data from regular `Decl` for performance reasons. + RibDef(Res), } -impl<'ra> LexicalScopeBinding<'ra> { +impl<'ra> LateDecl<'ra> { fn res(self) -> Res { match self { - LexicalScopeBinding::Item(binding) => binding.res(), - LexicalScopeBinding::Res(res) => res, + LateDecl::Decl(binding) => binding.res(), + LateDecl::RibDef(res) => res, } } } From 844e085de69c4d17cc21cbfda08d58caa286fa49 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Dec 2025 20:47:03 +0300 Subject: [PATCH 1635/3801] resolve: `MacroRulesScope::Binding` -> `MacroRulesScope::Def` `MacroRulesBinding` -> `MacroRulesDef` --- compiler/rustc_resolve/src/build_reduced_graph.rs | 6 +++--- compiler/rustc_resolve/src/diagnostics.rs | 2 +- compiler/rustc_resolve/src/ident.rs | 6 ++---- compiler/rustc_resolve/src/lib.rs | 6 +++--- compiler/rustc_resolve/src/macros.rs | 6 +++--- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index d31723844290..d23e86273e52 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -33,7 +33,7 @@ use tracing::debug; use crate::Namespace::{MacroNS, TypeNS, ValueNS}; use crate::def_collector::collect_definitions; use crate::imports::{ImportData, ImportKind}; -use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; +use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef}; use crate::ref_mut::CmCell; use crate::{ BindingKey, Decl, DeclData, DeclKind, ExternPreludeEntry, Finalize, MacroData, Module, @@ -1326,8 +1326,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { self.insert_unused_macro(ident, def_id, item.id); } self.r.feed_visibility(feed, vis); - let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding( - self.r.arenas.alloc_macro_rules_binding(MacroRulesBinding { + let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Def( + self.r.arenas.alloc_macro_rules_binding(MacroRulesDecl { parent_macro_rules_scope: parent_scope.macro_rules, binding, ident, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 99812fe4df53..21328b39623e 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1195,7 +1195,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Never recommend deprecated helper attributes. } Scope::MacroRules(macro_rules_scope) => { - if let MacroRulesScope::Binding(macro_rules_binding) = macro_rules_scope.get() { + if let MacroRulesScope::Def(macro_rules_binding) = macro_rules_scope.get() { let res = macro_rules_binding.binding.res(); if filter_fn(res) { suggestions.push(TypoSuggestion::typo_from_ident( diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index a6a8545ac69e..7438403a4745 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -182,7 +182,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } Scope::DeriveHelpersCompat => Scope::MacroRules(parent_scope.macro_rules), Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() { - MacroRulesScope::Binding(binding) => { + MacroRulesScope::Def(binding) => { Scope::MacroRules(binding.parent_macro_rules_scope) } MacroRulesScope::Invocation(invoc_id) => { @@ -559,9 +559,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { result } Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() { - MacroRulesScope::Binding(macro_rules_binding) - if ident == macro_rules_binding.ident => - { + MacroRulesScope::Def(macro_rules_binding) if ident == macro_rules_binding.ident => { Ok(macro_rules_binding.binding) } MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined), diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 8982ec15de8f..ea13125f5417 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -38,7 +38,7 @@ use late::{ ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource, UnnecessaryQualification, }; -use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; +use macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef}; use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::node_id::NodeMap; use rustc_ast::{ @@ -1391,8 +1391,8 @@ impl<'ra> ResolverArenas<'ra> { } fn alloc_macro_rules_binding( &'ra self, - binding: MacroRulesBinding<'ra>, - ) -> &'ra MacroRulesBinding<'ra> { + binding: MacroRulesDecl<'ra>, + ) -> &'ra MacroRulesDecl<'ra> { self.dropless.alloc(binding) } fn alloc_ast_paths(&'ra self, paths: &[ast::Path]) -> &'ra [ast::Path] { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 07dd5d8fc889..e07bb46ac568 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -45,10 +45,10 @@ use crate::{ type Res = def::Res; -/// Binding produced by a `macro_rules` item. +/// Name declaration produced by a `macro_rules` item definition. /// Not modularized, can shadow previous `macro_rules` bindings, etc. #[derive(Debug)] -pub(crate) struct MacroRulesBinding<'ra> { +pub(crate) struct MacroRulesDecl<'ra> { pub(crate) binding: Decl<'ra>, /// `macro_rules` scope into which the `macro_rules` item was planted. pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'ra>, @@ -65,7 +65,7 @@ pub(crate) enum MacroRulesScope<'ra> { /// Empty "root" scope at the crate start containing no names. Empty, /// The scope introduced by a `macro_rules!` macro definition. - Binding(&'ra MacroRulesBinding<'ra>), + Def(&'ra MacroRulesDecl<'ra>), /// The scope introduced by a macro invocation that can potentially /// create a `macro_rules!` macro definition. Invocation(LocalExpnId), From a67e289b4d9f0aaf3fef25a819b42a58536474c0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Dec 2025 21:32:07 +0300 Subject: [PATCH 1636/3801] Update some function names and fields from bindings to declarations --- .../rustc_resolve/src/build_reduced_graph.rs | 52 +++---- compiler/rustc_resolve/src/diagnostics.rs | 12 +- .../src/effective_visibilities.rs | 22 +-- compiler/rustc_resolve/src/ident.rs | 18 +-- compiler/rustc_resolve/src/imports.rs | 90 ++++++------- compiler/rustc_resolve/src/lib.rs | 127 +++++++++--------- compiler/rustc_resolve/src/macros.rs | 18 ++- 7 files changed, 167 insertions(+), 172 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index d23e86273e52..7569fc3d716b 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -51,10 +51,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent: Module<'ra>, ident: Ident, ns: Namespace, - binding: Decl<'ra>, + decl: Decl<'ra>, ) { - if let Err(old_binding) = self.try_define_local(parent, ident, ns, binding, false) { - self.report_conflict(parent, ident, ns, old_binding, binding); + if let Err(old_binding) = self.try_define_local(parent, ident, ns, decl, false) { + self.report_conflict(parent, ident, ns, old_binding, decl); } } @@ -68,7 +68,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { span: Span, expn_id: LocalExpnId, ) { - let binding = self.arenas.new_res_binding(res, vis.to_def_id(), span, expn_id); + let binding = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id); self.define_binding_local(parent, ident, ns, binding); } @@ -84,7 +84,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { expansion: LocalExpnId, ambiguity: Option>, ) { - let binding = self.arenas.alloc_name_binding(DeclData { + let binding = self.arenas.alloc_decl(DeclData { kind: DeclKind::Def(res), ambiguity, // External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment. @@ -284,7 +284,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child; let span = child_span(self, reexport_chain, res); let res = res.expect_non_local(); - self.arenas.new_res_binding(res, vis, span, expansion) + self.arenas.new_def_decl(res, vis, span, expansion) }); // Record primary definitions. @@ -977,7 +977,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let parent_scope = self.parent_scope; let expansion = parent_scope.expansion; - let (used, module, binding) = if orig_name.is_none() && ident.name == kw::SelfLower { + let (used, module, decl) = if orig_name.is_none() && ident.name == kw::SelfLower { self.r.dcx().emit_err(errors::ExternCrateSelfRequiresRenaming { span: sp }); return; } else if orig_name == Some(kw::SelfLower) { @@ -997,10 +997,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } .map(|module| { let used = self.process_macro_use_imports(item, module); - let binding = self.r.arenas.new_pub_res_binding(module.res().unwrap(), sp, expansion); - (used, Some(ModuleOrUniformRoot::Module(module)), binding) + let decl = self.r.arenas.new_pub_def_decl(module.res().unwrap(), sp, expansion); + (used, Some(ModuleOrUniformRoot::Module(module)), decl) }) - .unwrap_or((true, None, self.r.dummy_binding)); + .unwrap_or((true, None, self.r.dummy_decl)); let import = self.r.arenas.alloc_import(ImportData { kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id }, root_id: item.id, @@ -1019,7 +1019,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { self.r.import_use_map.insert(import, Used::Other); } self.r.potentially_unused_imports.push(import); - let imported_binding = self.r.import(binding, import); + let imported_binding = self.r.import(decl, import); if ident.name != kw::Underscore && parent == self.r.graph_root { let norm_ident = Macros20NormalizedIdent::new(ident); // FIXME: this error is technically unnecessary now when extern prelude is split into @@ -1027,7 +1027,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if let Some(entry) = self.r.extern_prelude.get(&norm_ident) && expansion != LocalExpnId::ROOT && orig_name.is_some() - && entry.item_binding.is_none() + && entry.item_decl.is_none() { self.r.dcx().emit_err( errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span }, @@ -1038,17 +1038,17 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { match self.r.extern_prelude.entry(norm_ident) { Entry::Occupied(mut occupied) => { let entry = occupied.get_mut(); - if entry.item_binding.is_some() { + if entry.item_decl.is_some() { let msg = format!("extern crate `{ident}` already in extern prelude"); self.r.tcx.dcx().span_delayed_bug(item.span, msg); } else { - entry.item_binding = Some((imported_binding, orig_name.is_some())); + entry.item_decl = Some((imported_binding, orig_name.is_some())); } entry } Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry { - item_binding: Some((imported_binding, true)), - flag_binding: None, + item_decl: Some((imported_binding, true)), + flag_decl: None, }), }; } @@ -1089,14 +1089,14 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } } - fn add_macro_use_binding( + fn add_macro_use_decl( &mut self, name: Symbol, - binding: Decl<'ra>, + decl: Decl<'ra>, span: Span, allow_shadowing: bool, ) { - if self.r.macro_use_prelude.insert(name, binding).is_some() && !allow_shadowing { + if self.r.macro_use_prelude.insert(name, decl).is_some() && !allow_shadowing { self.r.dcx().emit_err(errors::MacroUseNameAlreadyInUse { span, name }); } } @@ -1168,7 +1168,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { macro_use_import(this, span, true) }; let import_binding = this.r.import(binding, import); - this.add_macro_use_binding(ident.name, import_binding, span, allow_shadowing); + this.add_macro_use_decl(ident.name, import_binding, span, allow_shadowing); } }); } else { @@ -1184,7 +1184,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let import = macro_use_import(self, ident.span, false); self.r.potentially_unused_imports.push(import); let imported_binding = self.r.import(binding, import); - self.add_macro_use_binding( + self.add_macro_use_decl( ident.name, imported_binding, ident.span, @@ -1300,8 +1300,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } else { Visibility::Restricted(CRATE_DEF_ID) }; - let binding = self.r.arenas.new_res_binding(res, vis.to_def_id(), span, expansion); - self.r.set_binding_parent_module(binding, parent_scope.module); + let decl = self.r.arenas.new_def_decl(res, vis.to_def_id(), span, expansion); + self.r.set_decl_parent_module(decl, parent_scope.module); self.r.all_macro_rules.insert(ident.name); if is_macro_export { let import = self.r.arenas.alloc_import(ImportData { @@ -1319,7 +1319,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { vis_span: item.vis.span, }); self.r.import_use_map.insert(import, Used::Other); - let import_binding = self.r.import(binding, import); + let import_binding = self.r.import(decl, import); self.r.define_binding_local(self.r.graph_root, ident, MacroNS, import_binding); } else { self.r.check_reserved_macro_name(ident, res); @@ -1327,9 +1327,9 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } self.r.feed_visibility(feed, vis); let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Def( - self.r.arenas.alloc_macro_rules_binding(MacroRulesDecl { + self.r.arenas.alloc_macro_rules_decl(MacroRulesDecl { parent_macro_rules_scope: parent_scope.macro_rules, - binding, + decl, ident, }), )); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 21328b39623e..b77481d1b3ad 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1196,7 +1196,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } Scope::MacroRules(macro_rules_scope) => { if let MacroRulesScope::Def(macro_rules_binding) = macro_rules_scope.get() { - let res = macro_rules_binding.binding.res(); + let res = macro_rules_binding.decl.res(); if filter_fn(res) { suggestions.push(TypoSuggestion::typo_from_ident( macro_rules_binding.ident, @@ -1969,7 +1969,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { true } - fn binding_description(&self, b: Decl<'_>, ident: Ident, scope: Scope<'_>) -> String { + fn decl_description(&self, b: Decl<'_>, ident: Ident, scope: Scope<'_>) -> String { let res = b.res(); if b.span.is_dummy() || !self.tcx.sess.source_map().is_span_accessible(b.span) { let (built_in, from) = match scope { @@ -2005,7 +2005,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && self .extern_prelude .get(&Macros20NormalizedIdent::new(ident)) - .is_some_and(|entry| entry.item_binding.map(|(b, _)| b) == Some(b1)) + .is_some_and(|entry| entry.item_decl.map(|(b, _)| b) == Some(b1)) }; let (b1, b2, scope1, scope2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() { // We have to print the span-less alternative first, otherwise formatting looks bad. @@ -2015,7 +2015,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; let could_refer_to = |b: Decl<'_>, scope: Scope<'ra>, also: &str| { - let what = self.binding_description(b, ident, scope); + let what = self.decl_description(b, ident, scope); let note_msg = format!("`{ident}` could{also} refer to {what}"); let thing = b.res().descr(); @@ -2073,9 +2073,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// If the binding refers to a tuple struct constructor with fields, /// returns the span of its fields. - fn ctor_fields_span(&self, binding: Decl<'_>) -> Option { + fn ctor_fields_span(&self, decl: Decl<'_>) -> Option { let DeclKind::Def(Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id)) = - binding.kind + decl.kind else { return None; }; diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 5d78f3752439..389bdbbec62b 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -42,8 +42,8 @@ impl Resolver<'_, '_> { self.get_nearest_non_block_module(def_id.to_def_id()).nearest_parent_mod().expect_local() } - fn private_vis_import(&self, binding: Decl<'_>) -> Visibility { - let DeclKind::Import { import, .. } = binding.kind else { unreachable!() }; + fn private_vis_import(&self, decl: Decl<'_>) -> Visibility { + let DeclKind::Import { import, .. } = decl.kind else { unreachable!() }; Visibility::Restricted( import .id() @@ -94,14 +94,14 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { // `EffectiveVisibilitiesVisitor` pass, because we have more detailed binding-based // information, but are used by later passes. Effective visibility of an import def id // is the maximum value among visibilities of bindings corresponding to that def id. - for (binding, eff_vis) in visitor.import_effective_visibilities.iter() { - let DeclKind::Import { import, .. } = binding.kind else { unreachable!() }; - if !binding.is_ambiguity_recursive() { + for (decl, eff_vis) in visitor.import_effective_visibilities.iter() { + let DeclKind::Import { import, .. } = decl.kind else { unreachable!() }; + if !decl.is_ambiguity_recursive() { if let Some(node_id) = import.id() { r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx) } - } else if binding.ambiguity.is_some() && eff_vis.is_public_at_level(Level::Reexported) { - exported_ambiguities.insert(*binding); + } else if decl.ambiguity.is_some() && eff_vis.is_public_at_level(Level::Reexported) { + exported_ambiguities.insert(*decl); } } @@ -188,15 +188,15 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { } } - fn update_import(&mut self, binding: Decl<'ra>, parent_id: ParentId<'ra>) { - let nominal_vis = binding.vis.expect_local(); + fn update_import(&mut self, decl: Decl<'ra>, parent_id: ParentId<'ra>) { + let nominal_vis = decl.vis.expect_local(); let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return }; let inherited_eff_vis = self.effective_vis_or_private(parent_id); let tcx = self.r.tcx; self.changed |= self.import_effective_visibilities.update( - binding, + decl, Some(nominal_vis), - || cheap_private_vis.unwrap_or_else(|| self.r.private_vis_import(binding)), + || cheap_private_vis.unwrap_or_else(|| self.r.private_vis_import(decl)), inherited_eff_vis, parent_id.level(), tcx, diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 7438403a4745..a5d9c1bae74f 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -543,7 +543,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { Ok((Some(ext), _)) => { if ext.helper_attrs.contains(&ident.name) { - let binding = self.arenas.new_pub_res_binding( + let binding = self.arenas.new_pub_def_decl( Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat), derive.span, LocalExpnId::ROOT, @@ -559,8 +559,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { result } Scope::MacroRules(macro_rules_scope) => match macro_rules_scope.get() { - MacroRulesScope::Def(macro_rules_binding) if ident == macro_rules_binding.ident => { - Ok(macro_rules_binding.binding) + MacroRulesScope::Def(macro_rules_def) if ident == macro_rules_def.ident => { + Ok(macro_rules_def.decl) } MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined), _ => Err(Determinacy::Determined), @@ -671,7 +671,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.graph_root.unexpanded_invocations.borrow().is_empty(), )), }, - Scope::BuiltinAttrs => match self.builtin_attrs_bindings.get(&ident.name) { + Scope::BuiltinAttrs => match self.builtin_attr_decls.get(&ident.name) { Some(binding) => Ok(*binding), None => Err(Determinacy::Determined), }, @@ -689,7 +689,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None => Err(Determinacy::Determined), } } - Scope::ToolPrelude => match self.registered_tool_bindings.get(&ident) { + Scope::ToolPrelude => match self.registered_tool_decls.get(&ident) { Some(binding) => Ok(*binding), None => Err(Determinacy::Determined), }, @@ -713,7 +713,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { result } - Scope::BuiltinTypes => match self.builtin_types_bindings.get(&ident.name) { + Scope::BuiltinTypes => match self.builtin_type_decls.get(&ident.name) { Some(binding) => { if matches!(ident.name, sym::f16) && !self.tcx.features().f16() @@ -959,7 +959,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if ns == TypeNS { if ident.name == kw::Crate || ident.name == kw::DollarCrate { let module = self.resolve_crate_root(ident); - return Ok(module.self_binding.unwrap()); + return Ok(module.self_decl.unwrap()); } else if ident.name == kw::Super || ident.name == kw::SelfLower { // FIXME: Implement these with renaming requirements so that e.g. // `use super;` doesn't work, but `use super as name;` does. @@ -1287,9 +1287,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { unreachable!(); }; if source != target { - if bindings.iter().all(|binding| binding.get().binding().is_none()) { + if bindings.iter().all(|binding| binding.get().decl().is_none()) { return true; - } else if bindings[ns].get().binding().is_none() && binding.is_some() { + } else if bindings[ns].get().decl().is_none() && binding.is_some() { return true; } } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 7648b980ec5c..4f8877401638 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -39,19 +39,20 @@ use crate::{ type Res = def::Res; -/// A [`Decl`] in the process of being resolved. +/// A potential import declaration in the process of being planted into a module. +/// Also used for lazily planting names from `--extern` flags to extern prelude. #[derive(Clone, Copy, Default, PartialEq)] -pub(crate) enum PendingBinding<'ra> { +pub(crate) enum PendingDecl<'ra> { Ready(Option>), #[default] Pending, } -impl<'ra> PendingBinding<'ra> { - pub(crate) fn binding(self) -> Option> { +impl<'ra> PendingDecl<'ra> { + pub(crate) fn decl(self) -> Option> { match self { - PendingBinding::Ready(binding) => binding, - PendingBinding::Pending => None, + PendingDecl::Ready(decl) => decl, + PendingDecl::Pending => None, } } } @@ -66,7 +67,7 @@ pub(crate) enum ImportKind<'ra> { /// It will directly use `source` when the format is `use prefix::source`. target: Ident, /// Bindings introduced by the import. - bindings: PerNS>>, + bindings: PerNS>>, /// `true` for `...::{self [as target]}` imports, `false` otherwise. type_ns_only: bool, /// Did this import result from a nested import? ie. `use foo::{bar, baz};` @@ -116,7 +117,7 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> { // Ignore the nested bindings to avoid an infinite loop while printing. .field( "bindings", - &bindings.clone().map(|b| b.into_inner().binding().map(|_| format_args!(".."))), + &bindings.clone().map(|b| b.into_inner().decl().map(|_| format_args!(".."))), ) .field("type_ns_only", type_ns_only) .field("nested", nested) @@ -282,10 +283,10 @@ struct UnresolvedImportError { // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;` // are permitted for backward-compatibility under a deprecation lint. -fn pub_use_of_private_extern_crate_hack(import: Import<'_>, binding: Decl<'_>) -> Option { - match (&import.kind, &binding.kind) { - (ImportKind::Single { .. }, DeclKind::Import { import: binding_import, .. }) - if let ImportKind::ExternCrate { id, .. } = binding_import.kind +fn pub_use_of_private_extern_crate_hack(import: Import<'_>, decl: Decl<'_>) -> Option { + match (&import.kind, &decl.kind) { + (ImportKind::Single { .. }, DeclKind::Import { import: decl_import, .. }) + if let ImportKind::ExternCrate { id, .. } = decl_import.kind && import.vis.is_public() => { Some(id) @@ -314,7 +315,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { max_vis.set_unchecked(Some(vis.expect_local())) } - self.arenas.alloc_name_binding(DeclData { + self.arenas.alloc_decl(DeclData { kind: DeclKind::Import { binding, import }, ambiguity: None, warn_ambiguity: false, @@ -335,7 +336,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) -> Result<(), Decl<'ra>> { let res = binding.res(); self.check_reserved_macro_name(ident, res); - self.set_binding_parent_module(binding, module); + self.set_decl_parent_module(binding, module); // Even if underscore names cannot be looked up, we still need to add them to modules, // because they can be fetched by glob imports from those modules, and bring traits // into scope both directly and through glob imports. @@ -364,7 +365,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // they have the same resolution or not. resolution.glob_binding = Some(glob_binding); } else if res != old_glob_binding.res() { - resolution.glob_binding = Some(this.new_ambiguity_binding( + resolution.glob_binding = Some(this.new_decl_with_ambiguity( old_glob_binding, glob_binding, warn_ambiguity, @@ -374,7 +375,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { resolution.glob_binding = Some(glob_binding); } else if binding.is_ambiguity_recursive() { resolution.glob_binding = - Some(this.new_warn_ambiguity_binding(glob_binding)); + Some(this.new_decl_with_warn_ambiguity(glob_binding)); } } (old_glob @ true, false) | (old_glob @ false, true) => { @@ -384,7 +385,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some(old_glob_binding) = resolution.glob_binding { assert!(old_glob_binding.is_glob_import()); if glob_binding.res() != old_glob_binding.res() { - resolution.glob_binding = Some(this.new_ambiguity_binding( + resolution.glob_binding = Some(this.new_decl_with_ambiguity( old_glob_binding, glob_binding, false, @@ -412,20 +413,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } - fn new_ambiguity_binding( + fn new_decl_with_ambiguity( &self, - primary_binding: Decl<'ra>, - secondary_binding: Decl<'ra>, + primary_decl: Decl<'ra>, + secondary_decl: Decl<'ra>, warn_ambiguity: bool, ) -> Decl<'ra> { - let ambiguity = Some(secondary_binding); - let data = DeclData { ambiguity, warn_ambiguity, ..*primary_binding }; - self.arenas.alloc_name_binding(data) + let ambiguity = Some(secondary_decl); + let data = DeclData { ambiguity, warn_ambiguity, ..*primary_decl }; + self.arenas.alloc_decl(data) } - fn new_warn_ambiguity_binding(&self, binding: Decl<'ra>) -> Decl<'ra> { - assert!(binding.is_ambiguity_recursive()); - self.arenas.alloc_name_binding(DeclData { warn_ambiguity: true, ..*binding }) + fn new_decl_with_warn_ambiguity(&self, decl: Decl<'ra>) -> Decl<'ra> { + assert!(decl.is_ambiguity_recursive()); + self.arenas.alloc_decl(DeclData { warn_ambiguity: true, ..*decl }) } // Use `f` to mutate the resolution of the name in the module. @@ -488,16 +489,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics. fn import_dummy_binding(&mut self, import: Import<'ra>, is_indeterminate: bool) { if let ImportKind::Single { target, ref bindings, .. } = import.kind { - if !(is_indeterminate - || bindings.iter().all(|binding| binding.get().binding().is_none())) + if !(is_indeterminate || bindings.iter().all(|binding| binding.get().decl().is_none())) { return; // Has resolution, do not create the dummy binding } - let dummy_binding = self.dummy_binding; - let dummy_binding = self.import(dummy_binding, import); + let dummy_decl = self.dummy_decl; + let dummy_decl = self.import(dummy_decl, import); self.per_ns(|this, ns| { let module = import.parent_scope.module; - let _ = this.try_define_local(module, target, ns, dummy_binding, false); + let _ = this.try_define_local(module, target, ns, dummy_decl, false); // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { let key = BindingKey::new(target, ns); @@ -506,7 +506,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } }); - self.record_use(target, dummy_binding, Used::Other); + self.record_use(target, dummy_decl, Used::Other); } else if import.imported_module.get().is_none() { self.import_use_map.insert(import, Used::Other); if let Some(id) = import.id() { @@ -577,7 +577,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let ImportKind::Single { source, ref bindings, .. } = import.kind && source.name == kw::SelfLower // Silence `unresolved import` error if E0429 is already emitted - && let PendingBinding::Ready(None) = bindings.value_ns.get() + && let PendingDecl::Ready(None) = bindings.value_ns.get() { continue; } @@ -851,7 +851,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut indeterminate_count = 0; self.per_ns_cm(|this, ns| { if !type_ns_only || ns == TypeNS { - if bindings[ns].get() != PendingBinding::Pending { + if bindings[ns].get() != PendingDecl::Pending { return; }; let binding_result = this.reborrow().maybe_resolve_ident_in_module( @@ -883,7 +883,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns, imported_binding, ); - PendingBinding::Ready(Some(imported_binding)) + PendingDecl::Ready(Some(imported_binding)) } Err(Determinacy::Determined) => { // Don't remove underscores from `single_imports`, they were never added. @@ -898,11 +898,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }, ); } - PendingBinding::Ready(None) + PendingDecl::Ready(None) } Err(Determinacy::Undetermined) => { indeterminate_count += 1; - PendingBinding::Pending + PendingDecl::Pending } }; bindings[ns].set_unchecked(binding); @@ -918,7 +918,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// consolidate multiple unresolved import errors into a single diagnostic. fn finalize_import(&mut self, import: Import<'ra>) -> Option { let ignore_binding = match &import.kind { - ImportKind::Single { bindings, .. } => bindings[TypeNS].get().binding(), + ImportKind::Single { bindings, .. } => bindings[TypeNS].get().decl(), _ => None, }; let ambiguity_errors_len = @@ -1113,14 +1113,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns, &import.parent_scope, Some(Finalize { report_private: false, ..finalize }), - bindings[ns].get().binding(), + bindings[ns].get().decl(), Some(import), ); match binding { Ok(binding) => { // Consistency checks, analogous to `finalize_macro_resolutions`. - let initial_res = bindings[ns].get().binding().map(|binding| { + let initial_res = bindings[ns].get().decl().map(|binding| { let initial_binding = binding.import_source(); all_ns_err = false; if target.name == kw::Underscore @@ -1287,7 +1287,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut any_successful_reexport = false; let mut crate_private_reexport = false; self.per_ns(|this, ns| { - let Some(binding) = bindings[ns].get().binding().map(|b| b.import_source()) else { + let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) else { return; }; @@ -1362,7 +1362,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(ident)); self.per_ns(|this, ns| { - if let Some(binding) = bindings[ns].get().binding().map(|b| b.import_source()) { + if let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) { this.lint_if_path_starts_with_module(finalize, &full_path, Some(binding)); } }); @@ -1372,7 +1372,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // this may resolve to either a value or a type, but for documentation // purposes it's good enough to just favor one over the other. self.per_ns(|this, ns| { - if let Some(binding) = bindings[ns].get().binding().map(|b| b.import_source()) { + if let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) { this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res()); } }); @@ -1410,7 +1410,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut is_redundant = true; let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None }; self.per_ns(|this, ns| { - let binding = bindings[ns].get().binding().map(|b| b.import_source()); + let binding = bindings[ns].get().decl().map(|b| b.import_source()); if is_redundant && let Some(binding) = binding { if binding.res() == Res::Err { return; @@ -1422,7 +1422,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &import.parent_scope, None, false, - bindings[ns].get().binding(), + bindings[ns].get().decl(), None, ) { Ok(other_binding) => { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ea13125f5417..67449050aea9 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -33,7 +33,7 @@ use std::sync::Arc; use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; use effective_visibilities::EffectiveVisibilitiesVisitor; use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; -use imports::{Import, ImportData, ImportKind, NameResolution, PendingBinding}; +use imports::{Import, ImportData, ImportKind, NameResolution, PendingDecl}; use late::{ ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource, UnnecessaryQualification, @@ -630,9 +630,9 @@ struct ModuleData<'ra> { expansion: ExpnId, - /// Binding for implicitly declared names that come with a module, + /// Declaration for implicitly declared names that come with a module, /// like `self` (not yet used), or `crate`/`$crate` (for root modules). - self_binding: Option>, + self_decl: Option>, } /// All modules are unique and allocated on a same arena, @@ -661,7 +661,7 @@ impl<'ra> ModuleData<'ra> { expansion: ExpnId, span: Span, no_implicit_prelude: bool, - self_binding: Option>, + self_decl: Option>, ) -> Self { let is_foreign = match kind { ModuleKind::Def(_, def_id, _) => !def_id.is_local(), @@ -680,7 +680,7 @@ impl<'ra> ModuleData<'ra> { traits: CmRefCell::new(None), span, expansion, - self_binding, + self_decl, } } } @@ -1025,12 +1025,12 @@ impl<'ra> DeclData<'ra> { // in some later round and screw up our previously found resolution. // See more detailed explanation in // https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049 - fn may_appear_after(&self, invoc_parent_expansion: LocalExpnId, binding: Decl<'_>) -> bool { - // self > max(invoc, binding) => !(self <= invoc || self <= binding) + fn may_appear_after(&self, invoc_parent_expansion: LocalExpnId, decl: Decl<'_>) -> bool { + // self > max(invoc, decl) => !(self <= invoc || self <= decl) // Expansions are partially ordered, so "may appear after" is an inversion of // "certainly appears before or simultaneously" and includes unordered cases. let self_parent_expansion = self.expansion; - let other_parent_expansion = binding.expansion; + let other_parent_expansion = decl.expansion; let certainly_before_other_or_simultaneously = other_parent_expansion.is_descendant_of(self_parent_expansion); let certainly_before_invoc_or_simultaneously = @@ -1053,23 +1053,23 @@ impl<'ra> DeclData<'ra> { } struct ExternPreludeEntry<'ra> { - /// Binding from an `extern crate` item. - /// The boolean flag is true is `item_binding` is non-redundant, happens either when - /// `flag_binding` is `None`, or when `extern crate` introducing `item_binding` used renaming. - item_binding: Option<(Decl<'ra>, /* introduced by item */ bool)>, - /// Binding from an `--extern` flag, lazily populated on first use. - flag_binding: Option, /* finalized */ bool)>>, + /// Name declaration from an `extern crate` item. + /// The boolean flag is true is `item_decl` is non-redundant, happens either when + /// `flag_decl` is `None`, or when `extern crate` introducing `item_decl` used renaming. + item_decl: Option<(Decl<'ra>, /* introduced by item */ bool)>, + /// Name declaration from an `--extern` flag, lazily populated on first use. + flag_decl: Option, /* finalized */ bool)>>, } impl ExternPreludeEntry<'_> { fn introduced_by_item(&self) -> bool { - matches!(self.item_binding, Some((_, true))) + matches!(self.item_decl, Some((_, true))) } fn flag() -> Self { ExternPreludeEntry { - item_binding: None, - flag_binding: Some(CacheCell::new((PendingBinding::Pending, false))), + item_decl: None, + flag_decl: Some(CacheCell::new((PendingDecl::Pending, false))), } } } @@ -1176,7 +1176,7 @@ pub struct Resolver<'ra, 'tcx> { local_module_map: FxIndexMap>, /// Lazily populated cache of modules loaded from external crates. extern_module_map: CacheRefCell>>, - binding_parent_modules: FxHashMap, Module<'ra>>, + decl_parent_modules: FxHashMap, Module<'ra>>, /// Maps glob imports to the names of items actually imported. glob_map: FxIndexMap>, @@ -1201,10 +1201,10 @@ pub struct Resolver<'ra, 'tcx> { inaccessible_ctor_reexport: FxHashMap, arenas: &'ra ResolverArenas<'ra>, - dummy_binding: Decl<'ra>, - builtin_types_bindings: FxHashMap>, - builtin_attrs_bindings: FxHashMap>, - registered_tool_bindings: FxHashMap>, + dummy_decl: Decl<'ra>, + builtin_type_decls: FxHashMap>, + builtin_attr_decls: FxHashMap>, + registered_tool_decls: FxHashMap>, macro_names: FxHashSet, builtin_macros: FxHashMap, registered_tools: &'tcx RegisteredTools, @@ -1333,14 +1333,14 @@ pub struct ResolverArenas<'ra> { } impl<'ra> ResolverArenas<'ra> { - fn new_res_binding( + fn new_def_decl( &'ra self, res: Res, vis: Visibility, span: Span, expansion: LocalExpnId, ) -> Decl<'ra> { - self.alloc_name_binding(DeclData { + self.alloc_decl(DeclData { kind: DeclKind::Def(res), ambiguity: None, warn_ambiguity: false, @@ -1350,8 +1350,8 @@ impl<'ra> ResolverArenas<'ra> { }) } - fn new_pub_res_binding(&'ra self, res: Res, span: Span, expn_id: LocalExpnId) -> Decl<'ra> { - self.new_res_binding(res, Visibility::Public, span, expn_id) + fn new_pub_def_decl(&'ra self, res: Res, span: Span, expn_id: LocalExpnId) -> Decl<'ra> { + self.new_def_decl(res, Visibility::Public, span, expn_id) } fn new_module( @@ -1362,9 +1362,9 @@ impl<'ra> ResolverArenas<'ra> { span: Span, no_implicit_prelude: bool, ) -> Module<'ra> { - let self_binding = match kind { + let self_decl = match kind { ModuleKind::Def(def_kind, def_id, _) => { - Some(self.new_pub_res_binding(Res::Def(def_kind, def_id), span, LocalExpnId::ROOT)) + Some(self.new_pub_def_decl(Res::Def(def_kind, def_id), span, LocalExpnId::ROOT)) } ModuleKind::Block => None, }; @@ -1374,11 +1374,11 @@ impl<'ra> ResolverArenas<'ra> { expn_id, span, no_implicit_prelude, - self_binding, + self_decl, )))) } - fn alloc_name_binding(&'ra self, name_binding: DeclData<'ra>) -> Decl<'ra> { - Interned::new_unchecked(self.dropless.alloc(name_binding)) + fn alloc_decl(&'ra self, data: DeclData<'ra>) -> Decl<'ra> { + Interned::new_unchecked(self.dropless.alloc(data)) } fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> { Interned::new_unchecked(self.imports.alloc(import)) @@ -1389,11 +1389,8 @@ impl<'ra> ResolverArenas<'ra> { fn alloc_macro_rules_scope(&'ra self, scope: MacroRulesScope<'ra>) -> MacroRulesScopeRef<'ra> { self.dropless.alloc(CacheCell::new(scope)) } - fn alloc_macro_rules_binding( - &'ra self, - binding: MacroRulesDecl<'ra>, - ) -> &'ra MacroRulesDecl<'ra> { - self.dropless.alloc(binding) + fn alloc_macro_rules_decl(&'ra self, decl: MacroRulesDecl<'ra>) -> &'ra MacroRulesDecl<'ra> { + self.dropless.alloc(decl) } fn alloc_ast_paths(&'ra self, paths: &[ast::Path]) -> &'ra [ast::Path] { self.ast_paths.alloc_from_iter(paths.iter().cloned()) @@ -1609,7 +1606,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { local_module_map, extern_module_map: Default::default(), block_map: Default::default(), - binding_parent_modules: FxHashMap::default(), + decl_parent_modules: FxHashMap::default(), ast_transform_scopes: FxHashMap::default(), glob_map: Default::default(), @@ -1618,29 +1615,29 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { inaccessible_ctor_reexport: Default::default(), arenas, - dummy_binding: arenas.new_pub_res_binding(Res::Err, DUMMY_SP, LocalExpnId::ROOT), - builtin_types_bindings: PrimTy::ALL + dummy_decl: arenas.new_pub_def_decl(Res::Err, DUMMY_SP, LocalExpnId::ROOT), + builtin_type_decls: PrimTy::ALL .iter() .map(|prim_ty| { let res = Res::PrimTy(*prim_ty); - let binding = arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT); - (prim_ty.name(), binding) + let decl = arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT); + (prim_ty.name(), decl) }) .collect(), - builtin_attrs_bindings: BUILTIN_ATTRIBUTES + builtin_attr_decls: BUILTIN_ATTRIBUTES .iter() .map(|builtin_attr| { let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(builtin_attr.name)); - let binding = arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT); - (builtin_attr.name, binding) + let decl = arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT); + (builtin_attr.name, decl) }) .collect(), - registered_tool_bindings: registered_tools + registered_tool_decls: registered_tools .iter() .map(|ident| { let res = Res::ToolMod; - let binding = arenas.new_pub_res_binding(res, ident.span, LocalExpnId::ROOT); - (*ident, binding) + let decl = arenas.new_pub_def_decl(res, ident.span, LocalExpnId::ROOT); + (*ident, decl) }) .collect(), macro_names: FxHashSet::default(), @@ -2043,8 +2040,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { false } - fn record_use(&mut self, ident: Ident, used_binding: Decl<'ra>, used: Used) { - self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity); + fn record_use(&mut self, ident: Ident, used_decl: Decl<'ra>, used: Used) { + self.record_use_inner(ident, used_decl, used, used_decl.warn_ambiguity); } fn record_use_inner( @@ -2099,7 +2096,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // but not introduce it, as used if they are accessed from lexical scope. if used == Used::Scope && let Some(entry) = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)) - && entry.item_binding == Some((used_binding, false)) + && entry.item_decl == Some((used_binding, false)) { return; } @@ -2226,10 +2223,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { vis.is_accessible_from(module.nearest_parent_mod(), self.tcx) } - fn set_binding_parent_module(&mut self, binding: Decl<'ra>, module: Module<'ra>) { - if let Some(old_module) = self.binding_parent_modules.insert(binding, module) { + fn set_decl_parent_module(&mut self, decl: Decl<'ra>, module: Module<'ra>) { + if let Some(old_module) = self.decl_parent_modules.insert(decl, module) { if module != old_module { - span_bug!(binding.span, "parent module is reset for binding"); + span_bug!(decl.span, "parent module is reset for a name declaration"); } } } @@ -2246,8 +2243,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // panic on index should be impossible, the only name_bindings passed in should be from // `resolve_ident_in_scope_set` which will always refer to a local binding from an // import or macro definition - let macro_rules = &self.binding_parent_modules[¯o_rules]; - let modularized = &self.binding_parent_modules[&modularized]; + let macro_rules = &self.decl_parent_modules[¯o_rules]; + let modularized = &self.decl_parent_modules[&modularized]; macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod() && modularized.is_ancestor_of(*macro_rules) } @@ -2258,7 +2255,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize: bool, ) -> Option> { let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)); - entry.and_then(|entry| entry.item_binding).map(|(binding, _)| { + entry.and_then(|entry| entry.item_decl).map(|(binding, _)| { if finalize { self.get_mut().record_use(ident, binding, Used::Scope); } @@ -2268,16 +2265,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn extern_prelude_get_flag(&self, ident: Ident, finalize: bool) -> Option> { let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)); - entry.and_then(|entry| entry.flag_binding.as_ref()).and_then(|flag_binding| { - let (pending_binding, finalized) = flag_binding.get(); - let binding = match pending_binding { - PendingBinding::Ready(binding) => { + entry.and_then(|entry| entry.flag_decl.as_ref()).and_then(|flag_decl| { + let (pending_decl, finalized) = flag_decl.get(); + let decl = match pending_decl { + PendingDecl::Ready(decl) => { if finalize && !finalized { self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span); } - binding + decl } - PendingBinding::Pending => { + PendingDecl::Pending => { debug_assert!(!finalized); let crate_id = if finalize { self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span) @@ -2286,12 +2283,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; crate_id.map(|crate_id| { let res = Res::Def(DefKind::Mod, crate_id.as_def_id()); - self.arenas.new_pub_res_binding(res, DUMMY_SP, LocalExpnId::ROOT) + self.arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT) }) } }; - flag_binding.set((PendingBinding::Ready(binding), finalize || finalized)); - binding.or_else(|| finalize.then_some(self.dummy_binding)) + flag_decl.set((PendingDecl::Ready(decl), finalize || finalized)); + decl.or_else(|| finalize.then_some(self.dummy_decl)) }) } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index e07bb46ac568..898d198c5475 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -49,7 +49,7 @@ type Res = def::Res; /// Not modularized, can shadow previous `macro_rules` bindings, etc. #[derive(Debug)] pub(crate) struct MacroRulesDecl<'ra> { - pub(crate) binding: Decl<'ra>, + pub(crate) decl: Decl<'ra>, /// `macro_rules` scope into which the `macro_rules` item was planted. pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'ra>, pub(crate) ident: Ident, @@ -431,8 +431,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { .iter() .map(|(_, ident)| { let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); - let binding = self.arenas.new_pub_res_binding(res, ident.span, expn_id); - (*ident, binding) + (*ident, self.arenas.new_pub_def_decl(res, ident.span, expn_id)) }) .collect(); self.helper_attrs.insert(expn_id, helper_attrs); @@ -1062,18 +1061,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn prohibit_imported_non_macro_attrs( &self, - binding: Option>, + decl: Option>, res: Option, span: Span, ) { if let Some(Res::NonMacroAttr(kind)) = res { - if kind != NonMacroAttrKind::Tool && binding.is_none_or(|b| b.is_import()) { - let binding_span = binding.map(|binding| binding.span); + if kind != NonMacroAttrKind::Tool && decl.is_none_or(|b| b.is_import()) { self.dcx().emit_err(errors::CannotUseThroughAnImport { span, article: kind.article(), descr: kind.descr(), - binding_span, + binding_span: decl.map(|d| d.span), }); } } @@ -1084,12 +1082,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { path: &ast::Path, parent_scope: &ParentScope<'ra>, invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>, - binding: Option>, + decl: Option>, ) { if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr - && let Some(binding) = binding + && let Some(decl) = decl // This is a `macro_rules` itself, not some import. - && let DeclKind::Def(res) = binding.kind + && let DeclKind::Def(res) = decl.kind && let Res::Def(DefKind::Macro(kinds), def_id) = res && kinds.contains(MacroKinds::BANG) // And the `macro_rules` is defined inside the attribute's module, From a0ea3b0635064a9191e5df6e36ecb75cd5168df8 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Dec 2025 22:27:43 +0300 Subject: [PATCH 1637/3801] Update more function names and fields from bindings to declarations --- .../rustc_resolve/src/build_reduced_graph.rs | 50 +++-- compiler/rustc_resolve/src/check_unused.rs | 8 +- compiler/rustc_resolve/src/diagnostics.rs | 38 ++-- .../src/effective_visibilities.rs | 33 ++- compiler/rustc_resolve/src/ident.rs | 165 +++++++-------- compiler/rustc_resolve/src/imports.rs | 200 +++++++++--------- compiler/rustc_resolve/src/late.rs | 28 +-- .../rustc_resolve/src/late/diagnostics.rs | 34 ++- compiler/rustc_resolve/src/lib.rs | 22 +- compiler/rustc_resolve/src/macros.rs | 2 +- 10 files changed, 284 insertions(+), 296 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 7569fc3d716b..d56ca7c079cb 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -44,20 +44,22 @@ use crate::{ type Res = def::Res; impl<'ra, 'tcx> Resolver<'ra, 'tcx> { - /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; - /// otherwise, reports an error. - pub(crate) fn define_binding_local( + /// Attempt to put the declaration with the given name and namespace into the module, + /// and report an error in case of a collision. + pub(crate) fn plant_decl_into_local_module( &mut self, parent: Module<'ra>, ident: Ident, ns: Namespace, decl: Decl<'ra>, ) { - if let Err(old_binding) = self.try_define_local(parent, ident, ns, decl, false) { - self.report_conflict(parent, ident, ns, old_binding, decl); + if let Err(old_decl) = self.try_plant_decl_into_local_module(parent, ident, ns, decl, false) + { + self.report_conflict(parent, ident, ns, old_decl, decl); } } + /// Create a name definitinon from the given components, and put it into the local module. fn define_local( &mut self, parent: Module<'ra>, @@ -68,10 +70,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { span: Span, expn_id: LocalExpnId, ) { - let binding = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id); - self.define_binding_local(parent, ident, ns, binding); + let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id); + self.plant_decl_into_local_module(parent, ident, ns, decl); } + /// Create a name definitinon from the given components, and put it into the extern module. fn define_extern( &self, parent: Module<'ra>, @@ -84,7 +87,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { expansion: LocalExpnId, ambiguity: Option>, ) { - let binding = self.arenas.alloc_decl(DeclData { + let decl = self.arenas.alloc_decl(DeclData { kind: DeclKind::Def(res), ambiguity, // External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment. @@ -101,8 +104,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if self .resolution_or_default(parent, key) .borrow_mut_unchecked() - .non_glob_binding - .replace(binding) + .non_glob_decl + .replace(decl) .is_some() { span_bug!(span, "an external binding was already defined"); @@ -691,7 +694,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let kind = ImportKind::Single { source: source.ident, target: ident, - bindings: Default::default(), + decls: Default::default(), type_ns_only, nested, id, @@ -1019,7 +1022,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { self.r.import_use_map.insert(import, Used::Other); } self.r.potentially_unused_imports.push(import); - let imported_binding = self.r.import(decl, import); + let import_decl = self.r.new_import_decl(decl, import); if ident.name != kw::Underscore && parent == self.r.graph_root { let norm_ident = Macros20NormalizedIdent::new(ident); // FIXME: this error is technically unnecessary now when extern prelude is split into @@ -1042,17 +1045,17 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let msg = format!("extern crate `{ident}` already in extern prelude"); self.r.tcx.dcx().span_delayed_bug(item.span, msg); } else { - entry.item_decl = Some((imported_binding, orig_name.is_some())); + entry.item_decl = Some((import_decl, orig_name.is_some())); } entry } Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry { - item_decl: Some((imported_binding, true)), + item_decl: Some((import_decl, true)), flag_decl: None, }), }; } - self.r.define_binding_local(parent, ident, TypeNS, imported_binding); + self.r.plant_decl_into_local_module(parent, ident, TypeNS, import_decl); } /// Constructs the reduced graph for one foreign item. @@ -1167,8 +1170,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } macro_use_import(this, span, true) }; - let import_binding = this.r.import(binding, import); - this.add_macro_use_decl(ident.name, import_binding, span, allow_shadowing); + let import_decl = this.r.new_import_decl(binding, import); + this.add_macro_use_decl(ident.name, import_decl, span, allow_shadowing); } }); } else { @@ -1183,13 +1186,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if let Ok(binding) = result { let import = macro_use_import(self, ident.span, false); self.r.potentially_unused_imports.push(import); - let imported_binding = self.r.import(binding, import); - self.add_macro_use_decl( - ident.name, - imported_binding, - ident.span, - allow_shadowing, - ); + let import_decl = self.r.new_import_decl(binding, import); + self.add_macro_use_decl(ident.name, import_decl, ident.span, allow_shadowing); } else { self.r.dcx().emit_err(errors::ImportedMacroNotFound { span: ident.span }); } @@ -1319,8 +1317,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { vis_span: item.vis.span, }); self.r.import_use_map.insert(import, Used::Other); - let import_binding = self.r.import(decl, import); - self.r.define_binding_local(self.r.graph_root, ident, MacroNS, import_binding); + let import_decl = self.r.new_import_decl(decl, import); + self.r.plant_decl_into_local_module(self.r.graph_root, ident, MacroNS, import_decl); } else { self.r.check_reserved_macro_name(ident, res); self.insert_unused_macro(ident, def_id, item.id); diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index a2e903ce48eb..3724fcfce40f 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -514,8 +514,8 @@ impl Resolver<'_, '_> { let mut check_redundant_imports = FxIndexSet::default(); for module in &self.local_modules { for (_key, resolution) in self.resolutions(*module).borrow().iter() { - if let Some(binding) = resolution.borrow().best_binding() - && let DeclKind::Import { import, .. } = binding.kind + if let Some(decl) = resolution.borrow().best_decl() + && let DeclKind::Import { import, .. } = decl.kind && let ImportKind::Single { id, .. } = import.kind { if let Some(unused_import) = unused_imports.get(&import.root_id) @@ -542,8 +542,8 @@ impl Resolver<'_, '_> { // Deleting both unused imports and unnecessary segments of an item may result // in the item not being found. for unn_qua in &self.potentially_unnecessary_qualifications { - if let LateDecl::Decl(name_binding) = unn_qua.binding - && let DeclKind::Import { import, .. } = name_binding.kind + if let LateDecl::Decl(decl) = unn_qua.decl + && let DeclKind::Import { import, .. } = decl.kind && (is_unused_import(import, &unused_imports) || is_redundant_import(import, &redundant_imports)) { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index b77481d1b3ad..7ed29b91b67a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1195,13 +1195,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Never recommend deprecated helper attributes. } Scope::MacroRules(macro_rules_scope) => { - if let MacroRulesScope::Def(macro_rules_binding) = macro_rules_scope.get() { - let res = macro_rules_binding.decl.res(); + if let MacroRulesScope::Def(macro_rules_def) = macro_rules_scope.get() { + let res = macro_rules_def.decl.res(); if filter_fn(res) { - suggestions.push(TypoSuggestion::typo_from_ident( - macro_rules_binding.ident, - res, - )) + suggestions + .push(TypoSuggestion::typo_from_ident(macro_rules_def.ident, res)) } } } @@ -1581,9 +1579,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |(key, name_resolution)| { if key.ns == TypeNS && key.ident == ident - && let Some(binding) = name_resolution.borrow().best_binding() + && let Some(decl) = name_resolution.borrow().best_decl() { - match binding.res() { + match decl.res() { // No disambiguation needed if the identically named item we // found in scope actually refers to the crate in question. Res::Def(_, def_id) => def_id != crate_def_id, @@ -2087,7 +2085,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) { let PrivacyError { ident, - binding, + decl, outermost_res, parent_scope, single_nested, @@ -2095,8 +2093,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ref source, } = *privacy_error; - let res = binding.res(); - let ctor_fields_span = self.ctor_fields_span(binding); + let res = decl.res(); + let ctor_fields_span = self.ctor_fields_span(decl); let plain_descr = res.descr().to_string(); let nonimport_descr = if ctor_fields_span.is_some() { plain_descr + " constructor" } else { plain_descr }; @@ -2104,7 +2102,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let get_descr = |b: Decl<'_>| if b.is_import() { &import_descr } else { &nonimport_descr }; // Print the primary message. - let ident_descr = get_descr(binding); + let ident_descr = get_descr(decl); let mut err = self.dcx().create_err(errors::IsPrivate { span: ident.span, ident_descr, ident }); @@ -2204,8 +2202,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // Print the whole import chain to make it easier to see what happens. - let first_binding = binding; - let mut next_binding = Some(binding); + let first_binding = decl; + let mut next_binding = Some(decl); let mut next_ident = ident; let mut path = vec![]; while let Some(binding) = next_binding { @@ -2413,7 +2411,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { opt_ns: Option, // `None` indicates a module path in import parent_scope: &ParentScope<'ra>, ribs: Option<&PerNS>>>, - ignore_binding: Option>, + ignore_decl: Option>, ignore_import: Option>, module: Option>, failed_segment_idx: usize, @@ -2509,7 +2507,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns_to_try, parent_scope, None, - ignore_binding, + ignore_decl, ignore_import, ) .ok() @@ -2523,7 +2521,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, None, &ribs[ns_to_try], - ignore_binding, + ignore_decl, diag_metadata, ) { // we found a locally-imported or available item/module @@ -2538,7 +2536,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, None, false, - ignore_binding, + ignore_decl, ignore_import, ) .ok() @@ -2574,7 +2572,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, None, &ribs[ValueNS], - ignore_binding, + ignore_decl, diag_metadata, ) } else { @@ -2642,7 +2640,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, None, false, - ignore_binding, + ignore_decl, ignore_import, ) { let descr = binding.res().descr(); diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 389bdbbec62b..87be913df535 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -28,9 +28,9 @@ impl ParentId<'_> { pub(crate) struct EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { r: &'a mut Resolver<'ra, 'tcx>, def_effective_visibilities: EffectiveVisibilities, - /// While walking import chains we need to track effective visibilities per-binding, and def id + /// While walking import chains we need to track effective visibilities per-decl, and def id /// keys in `Resolver::effective_visibilities` are not enough for that, because multiple - /// bindings can correspond to a single def id in imports. So we keep a separate table. + /// declarations can correspond to a single def id in imports. So we keep a separate table. import_effective_visibilities: EffectiveVisibilities>, // It's possible to recalculate this at any point, but it's relatively expensive. current_private_vis: Visibility, @@ -91,9 +91,9 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { let mut exported_ambiguities = FxHashSet::default(); // Update visibilities for import def ids. These are not used during the - // `EffectiveVisibilitiesVisitor` pass, because we have more detailed binding-based + // `EffectiveVisibilitiesVisitor` pass, because we have more detailed declaration-based // information, but are used by later passes. Effective visibility of an import def id - // is the maximum value among visibilities of bindings corresponding to that def id. + // is the maximum value among visibilities of declarations corresponding to that def id. for (decl, eff_vis) in visitor.import_effective_visibilities.iter() { let DeclKind::Import { import, .. } = decl.kind else { unreachable!() }; if !decl.is_ambiguity_recursive() { @@ -110,12 +110,12 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { exported_ambiguities } - /// Update effective visibilities of bindings in the given module, + /// Update effective visibilities of name declarations in the given module, /// including their whole reexport chains. fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) { let module = self.r.expect_module(module_id.to_def_id()); for (_, name_resolution) in self.r.resolutions(module).borrow().iter() { - let Some(mut binding) = name_resolution.borrow().binding() else { + let Some(mut decl) = name_resolution.borrow().binding() else { continue; }; // Set the given effective visibility level to `Level::Direct` and @@ -125,28 +125,27 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { // If the binding is ambiguous, put the root ambiguity binding and all reexports // leading to it into the table. They are used by the `ambiguous_glob_reexports` // lint. For all bindings added to the table this way `is_ambiguity` returns true. - let is_ambiguity = - |binding: Decl<'ra>, warn: bool| binding.ambiguity.is_some() && !warn; + let is_ambiguity = |decl: Decl<'ra>, warn: bool| decl.ambiguity.is_some() && !warn; let mut parent_id = ParentId::Def(module_id); - let mut warn_ambiguity = binding.warn_ambiguity; - while let DeclKind::Import { binding: nested_binding, .. } = binding.kind { - self.update_import(binding, parent_id); + let mut warn_ambiguity = decl.warn_ambiguity; + while let DeclKind::Import { binding: nested_binding, .. } = decl.kind { + self.update_import(decl, parent_id); - if is_ambiguity(binding, warn_ambiguity) { + if is_ambiguity(decl, warn_ambiguity) { // Stop at the root ambiguity, further bindings in the chain should not // be reexported because the root ambiguity blocks any access to them. // (Those further bindings are most likely not ambiguities themselves.) break; } - parent_id = ParentId::Import(binding); - binding = nested_binding; + parent_id = ParentId::Import(decl); + decl = nested_binding; warn_ambiguity |= nested_binding.warn_ambiguity; } - if !is_ambiguity(binding, warn_ambiguity) - && let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) + if !is_ambiguity(decl, warn_ambiguity) + && let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local()) { - self.update_def(def_id, binding.vis.expect_local(), parent_id); + self.update_def(def_id, decl.vis.expect_local(), parent_id); } } } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index a5d9c1bae74f..e0acf043ffcf 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -304,7 +304,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, finalize: Option, ribs: &[Rib<'ra>], - ignore_binding: Option>, + ignore_decl: Option>, diag_metadata: Option<&DiagMetadata<'_>>, ) -> Option> { let orig_ident = ident; @@ -345,7 +345,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }), finalize.is_some(), - ignore_binding, + ignore_decl, None, ) { @@ -363,7 +363,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, finalize, finalize.is_some(), - ignore_binding, + ignore_decl, None, ) .ok() @@ -391,7 +391,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, finalize: Option, force: bool, - ignore_binding: Option>, + ignore_decl: Option>, ignore_import: Option>, ) -> Result, Determinacy> { assert!(force || finalize.is_none()); // `finalize` implies `force` @@ -442,13 +442,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ctxt, scope_set, parent_scope, - // Shadowed bindings don't need to be marked as used or non-speculatively loaded. + // Shadowed decls don't need to be marked as used or non-speculatively loaded. if innermost_results.is_empty() { finalize } else { None }, force, - ignore_binding, + ignore_decl, ignore_import, ) { - Ok(binding) => Ok(binding), + Ok(decl) => Ok(decl), // We can break with an error at this step, it means we cannot determine the // resolution right now, but we must block and wait until we can, instead of // considering outer scopes. Although there's no need to do that if we already @@ -459,32 +459,32 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Err(determinacy) => Err(determinacy.into_value()), }; match res { - Ok(binding) if sub_namespace_match(binding.macro_kinds(), macro_kind) => { + Ok(decl) if sub_namespace_match(decl.macro_kinds(), macro_kind) => { // Below we report various ambiguity errors. // We do not need to report them if we are either in speculative resolution, // or in late resolution when everything is already imported and expanded // and no ambiguities exist. if matches!(finalize, None | Some(Finalize { stage: Stage::Late, .. })) { - return ControlFlow::Break(Ok(binding)); + return ControlFlow::Break(Ok(decl)); } - if let Some(&(innermost_binding, _)) = innermost_results.first() { + if let Some(&(innermost_decl, _)) = innermost_results.first() { // Found another solution, if the first one was "weak", report an error. if this.get_mut().maybe_push_ambiguity( orig_ident, ns, scope_set, parent_scope, - binding, + decl, scope, &innermost_results, ) { // No need to search for more potential ambiguities, one is enough. - return ControlFlow::Break(Ok(innermost_binding)); + return ControlFlow::Break(Ok(innermost_decl)); } } - innermost_results.push((binding, scope)); + innermost_results.push((decl, scope)); } Ok(_) | Err(Determinacy::Determined) => {} Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined, @@ -501,7 +501,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Scope visiting walked all the scopes and maybe found something in one of them. match innermost_results.first() { - Some(&(binding, ..)) => Ok(binding), + Some(&(decl, ..)) => Ok(decl), None => Err(Determinacy::determined(determinacy == Determinacy::Determined || force)), } } @@ -517,16 +517,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, finalize: Option, force: bool, - ignore_binding: Option>, + ignore_decl: Option>, ignore_import: Option>, ) -> Result, ControlFlow> { let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); let ret = match scope { Scope::DeriveHelpers(expn_id) => { - if let Some(binding) = self.helper_attrs.get(&expn_id).and_then(|attrs| { - attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding) - }) { - Ok(binding) + if let Some(decl) = self + .helper_attrs + .get(&expn_id) + .and_then(|attrs| attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, d)| *d)) + { + Ok(decl) } else { Err(Determinacy::Determined) } @@ -543,12 +545,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { Ok((Some(ext), _)) => { if ext.helper_attrs.contains(&ident.name) { - let binding = self.arenas.new_pub_def_decl( + let decl = self.arenas.new_pub_def_decl( Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat), derive.span, LocalExpnId::ROOT, ); - result = Ok(binding); + result = Ok(decl); break; } } @@ -577,7 +579,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.map(|f| Finalize { used: Used::Scope, ..f }), ) }; - let binding = self.reborrow().resolve_ident_in_module_non_globs_unadjusted( + let decl = self.reborrow().resolve_ident_in_module_non_globs_unadjusted( module, ident, ns, @@ -588,11 +590,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Shadowing::Restricted }, adjusted_finalize, - ignore_binding, + ignore_decl, ignore_import, ); - match binding { - Ok(binding) => { + match decl { + Ok(decl) => { if let Some(lint_id) = derive_fallback_lint_id { self.get_mut().lint_buffer.buffer_lint( PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, @@ -605,7 +607,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }, ); } - Ok(binding) + Ok(decl) } Err(ControlFlow::Continue(determinacy)) => Err(determinacy), Err(ControlFlow::Break(determinacy)) => { @@ -638,7 +640,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Shadowing::Restricted }, adjusted_finalize, - ignore_binding, + ignore_decl, ignore_import, ); match binding { @@ -666,18 +668,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() { - Some(binding) => Ok(binding), + Some(decl) => Ok(decl), None => Err(Determinacy::determined( self.graph_root.unexpanded_invocations.borrow().is_empty(), )), }, Scope::BuiltinAttrs => match self.builtin_attr_decls.get(&ident.name) { - Some(binding) => Ok(*binding), + Some(decl) => Ok(*decl), None => Err(Determinacy::Determined), }, Scope::ExternPreludeItems => { match self.reborrow().extern_prelude_get_item(ident, finalize.is_some()) { - Some(binding) => Ok(binding), + Some(decl) => Ok(decl), None => Err(Determinacy::determined( self.graph_root.unexpanded_invocations.borrow().is_empty(), )), @@ -685,36 +687,35 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } Scope::ExternPreludeFlags => { match self.extern_prelude_get_flag(ident, finalize.is_some()) { - Some(binding) => Ok(binding), + Some(decl) => Ok(decl), None => Err(Determinacy::Determined), } } Scope::ToolPrelude => match self.registered_tool_decls.get(&ident) { - Some(binding) => Ok(*binding), + Some(decl) => Ok(*decl), None => Err(Determinacy::Determined), }, Scope::StdLibPrelude => { let mut result = Err(Determinacy::Determined); if let Some(prelude) = self.prelude - && let Ok(binding) = self.reborrow().resolve_ident_in_scope_set( + && let Ok(decl) = self.reborrow().resolve_ident_in_scope_set( ident, ScopeSet::Module(ns, prelude), parent_scope, None, false, - ignore_binding, + ignore_decl, ignore_import, ) - && (matches!(use_prelude, UsePrelude::Yes) - || self.is_builtin_macro(binding.res())) + && (matches!(use_prelude, UsePrelude::Yes) || self.is_builtin_macro(decl.res())) { - result = Ok(binding) + result = Ok(decl) } result } Scope::BuiltinTypes => match self.builtin_type_decls.get(&ident.name) { - Some(binding) => { + Some(decl) => { if matches!(ident.name, sym::f16) && !self.tcx.features().f16() && !ident.span.allows_unstable(sym::f16) @@ -741,7 +742,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) .emit(); } - Ok(*binding) + Ok(*decl) } None => Err(Determinacy::Determined), }, @@ -756,12 +757,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns: Namespace, scope_set: ScopeSet<'ra>, parent_scope: &ParentScope<'ra>, - binding: Decl<'ra>, + decl: Decl<'ra>, scope: Scope<'ra>, innermost_results: &[(Decl<'ra>, Scope<'ra>)], ) -> bool { - let (innermost_binding, innermost_scope) = *innermost_results.first().unwrap(); - let (res, innermost_res) = (binding.res(), innermost_binding.res()); + let (innermost_decl, innermost_scope) = innermost_results[0]; + let (res, innermost_res) = (decl.res(), innermost_decl.res()); if res == innermost_res { return false; } @@ -781,7 +782,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { span_bug!(orig_ident.span, "impossible inner resolution kind") } else if matches!(innermost_scope, Scope::MacroRules(_)) && matches!(scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..)) - && !self.disambiguate_macro_rules_vs_modularized(innermost_binding, binding) + && !self.disambiguate_macro_rules_vs_modularized(innermost_decl, decl) { Some(AmbiguityKind::MacroRulesVsModularized) } else if matches!(scope, Scope::MacroRules(_)) @@ -797,13 +798,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { "ambiguous scoped macro resolutions with path-based \ scope resolution as first candidate" ) - } else if innermost_binding.is_glob_import() { + } else if innermost_decl.is_glob_import() { Some(AmbiguityKind::GlobVsOuter) - } else if !module_only - && innermost_binding.may_appear_after(parent_scope.expansion, binding) - { + } else if !module_only && innermost_decl.may_appear_after(parent_scope.expansion, decl) { Some(AmbiguityKind::MoreExpandedVsOuter) - } else if innermost_binding.expansion != LocalExpnId::ROOT + } else if innermost_decl.expansion != LocalExpnId::ROOT && (!module_only || ns == MacroNS) && let Scope::ModuleGlobs(m1, _) = scope && let Scope::ModuleNonGlobs(m2, _) = innermost_scope @@ -822,9 +821,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // by extern item bindings. // FIXME: Remove with lang team approval. let issue_145575_hack = matches!(scope, Scope::ExternPreludeFlags) - && innermost_results[1..].iter().any(|(b, s)| { - matches!(s, Scope::ExternPreludeItems) && *b != innermost_binding - }); + && innermost_results[1..] + .iter() + .any(|(b, s)| matches!(s, Scope::ExternPreludeItems) && *b != innermost_decl); // Skip ambiguity errors for nonglob module bindings "overridden" // by glob module bindings in the same module. // FIXME: Remove with lang team approval. @@ -845,8 +844,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.ambiguity_errors.push(AmbiguityError { kind, ident: orig_ident, - b1: innermost_binding, - b2: binding, + b1: innermost_decl, + b2: decl, scope1: innermost_scope, scope2: scope, warning: false, @@ -878,7 +877,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns: Namespace, parent_scope: &ParentScope<'ra>, finalize: Option, - ignore_binding: Option>, + ignore_decl: Option>, ignore_import: Option>, ) -> Result, Determinacy> { let tmp_parent_scope; @@ -904,7 +903,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns, adjusted_parent_scope, finalize, - ignore_binding, + ignore_decl, ignore_import, ) } @@ -918,7 +917,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns: Namespace, parent_scope: &ParentScope<'ra>, finalize: Option, - ignore_binding: Option>, + ignore_decl: Option>, ignore_import: Option>, ) -> Result, Determinacy> { match module { @@ -928,7 +927,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, finalize, finalize.is_some(), - ignore_binding, + ignore_decl, ignore_import, ), ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set( @@ -937,7 +936,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, finalize, finalize.is_some(), - ignore_binding, + ignore_decl, ignore_import, ), ModuleOrUniformRoot::ExternPrelude => { @@ -950,7 +949,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, finalize, finalize.is_some(), - ignore_binding, + ignore_decl, ignore_import, ) } @@ -973,7 +972,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, finalize, finalize.is_some(), - ignore_binding, + ignore_decl, ignore_import, ) } @@ -991,7 +990,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize: Option, // This binding should be ignored during in-module resolution, so that we don't get // "self-confirming" import resolutions during import validation and checking. - ignore_binding: Option>, + ignore_decl: Option>, ignore_import: Option>, ) -> Result, ControlFlow> { let key = BindingKey::new(ident, ns); @@ -1003,7 +1002,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .try_borrow_mut_unchecked() .map_err(|_| ControlFlow::Continue(Determined))?; - let binding = resolution.non_glob_binding.filter(|b| Some(*b) != ignore_binding); + let binding = resolution.non_glob_decl.filter(|b| Some(*b) != ignore_decl); if let Some(finalize) = finalize { return self.get_mut().finalize_module_binding( @@ -1028,7 +1027,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, ns, ignore_import, - ignore_binding, + ignore_decl, parent_scope, ) { return Err(ControlFlow::Break(Undetermined)); @@ -1052,7 +1051,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope: &ParentScope<'ra>, shadowing: Shadowing, finalize: Option, - ignore_binding: Option>, + ignore_decl: Option>, ignore_import: Option>, ) -> Result, ControlFlow> { let key = BindingKey::new(ident, ns); @@ -1064,7 +1063,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .try_borrow_mut_unchecked() .map_err(|_| ControlFlow::Continue(Determined))?; - let binding = resolution.glob_binding.filter(|b| Some(*b) != ignore_binding); + let binding = resolution.glob_decl.filter(|b| Some(*b) != ignore_decl); if let Some(finalize) = finalize { return self.get_mut().finalize_module_binding( @@ -1084,7 +1083,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { binding, ns, ignore_import, - ignore_binding, + ignore_decl, parent_scope, ) { return Err(ControlFlow::Break(Undetermined)); @@ -1154,7 +1153,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { adjusted_parent_scope, None, false, - ignore_binding, + ignore_decl, ignore_import, ); @@ -1192,7 +1191,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if report_private { self.privacy_errors.push(PrivacyError { ident, - binding, + decl: binding, dedup_span: path_span, outermost_res: None, source: None, @@ -1255,12 +1254,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { binding: Option>, ns: Namespace, ignore_import: Option>, - ignore_binding: Option>, + ignore_decl: Option>, parent_scope: &ParentScope<'ra>, ) -> bool { for single_import in &resolution.single_imports { - if let Some(binding) = resolution.non_glob_binding - && let DeclKind::Import { import, .. } = binding.kind + if let Some(decl) = resolution.non_glob_decl + && let DeclKind::Import { import, .. } = decl.kind && import == *single_import { // Single import has already defined the name and we are aware of it, @@ -1273,7 +1272,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if !self.is_accessible_from(single_import.vis, parent_scope.module) { continue; } - if let Some(ignored) = ignore_binding + if let Some(ignored) = ignore_decl && let DeclKind::Import { import, .. } = ignored.kind && import == *single_import { @@ -1283,13 +1282,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let Some(module) = single_import.imported_module.get() else { return true; }; - let ImportKind::Single { source, target, bindings, .. } = &single_import.kind else { + let ImportKind::Single { source, target, decls, .. } = &single_import.kind else { unreachable!(); }; if source != target { - if bindings.iter().all(|binding| binding.get().decl().is_none()) { + if decls.iter().all(|d| d.get().decl().is_none()) { return true; - } else if bindings[ns].get().decl().is_none() && binding.is_some() { + } else if decls[ns].get().decl().is_none() && binding.is_some() { return true; } } @@ -1300,7 +1299,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns, &single_import.parent_scope, None, - ignore_binding, + ignore_decl, ignore_import, ) { Err(Determined) => continue, @@ -1665,7 +1664,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { opt_ns: Option, // `None` indicates a module path in import parent_scope: &ParentScope<'ra>, finalize: Option, - ignore_binding: Option>, + ignore_decl: Option>, ignore_import: Option>, ) -> PathResult<'ra> { self.resolve_path_with_ribs( @@ -1675,7 +1674,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, finalize, None, - ignore_binding, + ignore_decl, ignore_import, None, ) @@ -1689,7 +1688,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { source: Option>, finalize: Option, ribs: Option<&PerNS>>>, - ignore_binding: Option>, + ignore_decl: Option>, ignore_import: Option>, diag_metadata: Option<&DiagMetadata<'_>>, ) -> PathResult<'ra> { @@ -1816,7 +1815,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns, parent_scope, finalize, - ignore_binding, + ignore_decl, ignore_import, ) } else if let Some(ribs) = ribs @@ -1829,7 +1828,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, finalize, &ribs[ns], - ignore_binding, + ignore_decl, diag_metadata, ) { // we found a locally-imported or available item/module @@ -1851,7 +1850,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { parent_scope, finalize, finalize.is_some(), - ignore_binding, + ignore_decl, ignore_import, ) }; @@ -1951,7 +1950,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { opt_ns, parent_scope, ribs, - ignore_binding, + ignore_decl, ignore_import, module, segment_idx, diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 4f8877401638..0fbfbd95a026 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -66,8 +66,8 @@ pub(crate) enum ImportKind<'ra> { /// `target` in `use prefix::source as target`. /// It will directly use `source` when the format is `use prefix::source`. target: Ident, - /// Bindings introduced by the import. - bindings: PerNS>>, + /// Name declarations introduced by the import. + decls: PerNS>>, /// `true` for `...::{self [as target]}` imports, `false` otherwise. type_ns_only: bool, /// Did this import result from a nested import? ie. `use foo::{bar, baz};` @@ -110,14 +110,14 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use ImportKind::*; match self { - Single { source, target, bindings, type_ns_only, nested, id, .. } => f + Single { source, target, decls, type_ns_only, nested, id, .. } => f .debug_struct("Single") .field("source", source) .field("target", target) // Ignore the nested bindings to avoid an infinite loop while printing. .field( - "bindings", - &bindings.clone().map(|b| b.into_inner().decl().map(|_| format_args!(".."))), + "decls", + &decls.clone().map(|b| b.into_inner().decl().map(|_| format_args!(".."))), ) .field("type_ns_only", type_ns_only) .field("nested", nested) @@ -244,16 +244,16 @@ pub(crate) struct NameResolution<'ra> { /// Single imports that may define the name in the namespace. /// Imports are arena-allocated, so it's ok to use pointers as keys. pub single_imports: FxIndexSet>, - /// The non-glob binding for this name, if it is known to exist. - pub non_glob_binding: Option>, - /// The glob binding for this name, if it is known to exist. - pub glob_binding: Option>, + /// The non-glob declaration for this name, if it is known to exist. + pub non_glob_decl: Option>, + /// The glob declaration for this name, if it is known to exist. + pub glob_decl: Option>, } impl<'ra> NameResolution<'ra> { /// Returns the binding for the name if it is known or None if it not known. pub(crate) fn binding(&self) -> Option> { - self.best_binding().and_then(|binding| { + self.best_decl().and_then(|binding| { if !binding.is_glob_import() || self.single_imports.is_empty() { Some(binding) } else { @@ -262,8 +262,8 @@ impl<'ra> NameResolution<'ra> { }) } - pub(crate) fn best_binding(&self) -> Option> { - self.non_glob_binding.or(self.glob_binding) + pub(crate) fn best_decl(&self) -> Option> { + self.non_glob_decl.or(self.glob_decl) } } @@ -296,16 +296,16 @@ fn pub_use_of_private_extern_crate_hack(import: Import<'_>, decl: Decl<'_>) -> O } impl<'ra, 'tcx> Resolver<'ra, 'tcx> { - /// Given a binding and an import that resolves to it, - /// return the corresponding binding defined by the import. - pub(crate) fn import(&self, binding: Decl<'ra>, import: Import<'ra>) -> Decl<'ra> { + /// Given an import and the declaration that it points to, + /// create the corresponding import declaration. + pub(crate) fn new_import_decl(&self, decl: Decl<'ra>, import: Import<'ra>) -> Decl<'ra> { let import_vis = import.vis.to_def_id(); - let vis = if binding.vis.is_at_least(import_vis, self.tcx) - || pub_use_of_private_extern_crate_hack(import, binding).is_some() + let vis = if decl.vis.is_at_least(import_vis, self.tcx) + || pub_use_of_private_extern_crate_hack(import, decl).is_some() { import_vis } else { - binding.vis + decl.vis }; if let ImportKind::Glob { ref max_vis, .. } = import.kind @@ -316,7 +316,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } self.arenas.alloc_decl(DeclData { - kind: DeclKind::Import { binding, import }, + kind: DeclKind::Import { binding: decl, import }, ambiguity: None, warn_ambiguity: false, span: import.span, @@ -325,18 +325,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } - /// Define the name or return the existing binding if there is a collision. - pub(crate) fn try_define_local( + /// Attempt to put the declaration with the given name and namespace into the module, + /// and return existing declaration if there is a collision. + pub(crate) fn try_plant_decl_into_local_module( &mut self, module: Module<'ra>, ident: Ident, ns: Namespace, - binding: Decl<'ra>, + decl: Decl<'ra>, warn_ambiguity: bool, ) -> Result<(), Decl<'ra>> { - let res = binding.res(); + let res = decl.res(); self.check_reserved_macro_name(ident, res); - self.set_decl_parent_module(binding, module); + self.set_decl_parent_module(decl, module); // Even if underscore names cannot be looked up, we still need to add them to modules, // because they can be fetched by glob imports from those modules, and bring traits // into scope both directly and through glob imports. @@ -345,67 +346,66 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module.underscore_disambiguator.get() }); self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| { - if let Some(old_binding) = resolution.best_binding() { - if res == Res::Err && old_binding.res() != Res::Err { - // Do not override real bindings with `Res::Err`s from error recovery. + if let Some(old_decl) = resolution.best_decl() { + if res == Res::Err && old_decl.res() != Res::Err { + // Do not override real declarations with `Res::Err`s from error recovery. return Ok(()); } - match (old_binding.is_glob_import(), binding.is_glob_import()) { + match (old_decl.is_glob_import(), decl.is_glob_import()) { (true, true) => { - let (glob_binding, old_glob_binding) = (binding, old_binding); - // FIXME: remove `!binding.is_ambiguity_recursive()` after delete the warning ambiguity. - if !binding.is_ambiguity_recursive() - && let DeclKind::Import { import: old_import, .. } = - old_glob_binding.kind - && let DeclKind::Import { import, .. } = glob_binding.kind + let (glob_decl, old_glob_decl) = (decl, old_decl); + // FIXME: remove `!decl.is_ambiguity_recursive()` after delete the warning ambiguity. + if !decl.is_ambiguity_recursive() + && let DeclKind::Import { import: old_import, .. } = old_glob_decl.kind + && let DeclKind::Import { import, .. } = glob_decl.kind && old_import == import { // When imported from the same glob-import statement, we should replace - // `old_glob_binding` with `glob_binding`, regardless of whether + // `old_glob_decl` with `glob_decl`, regardless of whether // they have the same resolution or not. - resolution.glob_binding = Some(glob_binding); - } else if res != old_glob_binding.res() { - resolution.glob_binding = Some(this.new_decl_with_ambiguity( - old_glob_binding, - glob_binding, + resolution.glob_decl = Some(glob_decl); + } else if res != old_glob_decl.res() { + resolution.glob_decl = Some(this.new_decl_with_ambiguity( + old_glob_decl, + glob_decl, warn_ambiguity, )); - } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { + } else if !old_decl.vis.is_at_least(decl.vis, this.tcx) { // We are glob-importing the same item but with greater visibility. - resolution.glob_binding = Some(glob_binding); - } else if binding.is_ambiguity_recursive() { - resolution.glob_binding = - Some(this.new_decl_with_warn_ambiguity(glob_binding)); + resolution.glob_decl = Some(glob_decl); + } else if decl.is_ambiguity_recursive() { + resolution.glob_decl = + Some(this.new_decl_with_warn_ambiguity(glob_decl)); } } (old_glob @ true, false) | (old_glob @ false, true) => { - let (glob_binding, non_glob_binding) = - if old_glob { (old_binding, binding) } else { (binding, old_binding) }; - resolution.non_glob_binding = Some(non_glob_binding); - if let Some(old_glob_binding) = resolution.glob_binding { - assert!(old_glob_binding.is_glob_import()); - if glob_binding.res() != old_glob_binding.res() { - resolution.glob_binding = Some(this.new_decl_with_ambiguity( - old_glob_binding, - glob_binding, + let (glob_decl, non_glob_decl) = + if old_glob { (old_decl, decl) } else { (decl, old_decl) }; + resolution.non_glob_decl = Some(non_glob_decl); + if let Some(old_glob_decl) = resolution.glob_decl { + assert!(old_glob_decl.is_glob_import()); + if glob_decl.res() != old_glob_decl.res() { + resolution.glob_decl = Some(this.new_decl_with_ambiguity( + old_glob_decl, + glob_decl, false, )); - } else if !old_glob_binding.vis.is_at_least(binding.vis, this.tcx) { - resolution.glob_binding = Some(glob_binding); + } else if !old_glob_decl.vis.is_at_least(decl.vis, this.tcx) { + resolution.glob_decl = Some(glob_decl); } } else { - resolution.glob_binding = Some(glob_binding); + resolution.glob_decl = Some(glob_decl); } } (false, false) => { - return Err(old_binding); + return Err(old_decl); } } } else { - if binding.is_glob_import() { - resolution.glob_binding = Some(binding); + if decl.is_glob_import() { + resolution.glob_decl = Some(decl); } else { - resolution.non_glob_binding = Some(binding); + resolution.non_glob_decl = Some(decl); } } @@ -445,14 +445,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // during which the resolution might end up getting re-defined via a glob cycle. let (binding, t, warn_ambiguity) = { let resolution = &mut *self.resolution_or_default(module, key).borrow_mut_unchecked(); - let old_binding = resolution.binding(); + let old_decl = resolution.binding(); let t = f(self, resolution); if let Some(binding) = resolution.binding() - && old_binding != Some(binding) + && old_decl != Some(binding) { - (binding, t, warn_ambiguity || old_binding.is_some()) + (binding, t, warn_ambiguity || old_decl.is_some()) } else { return t; } @@ -471,12 +471,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None => continue, }; if self.is_accessible_from(binding.vis, scope) { - let imported_binding = self.import(binding, *import); - let _ = self.try_define_local( + let import_decl = self.new_import_decl(binding, *import); + let _ = self.try_plant_decl_into_local_module( import.parent_scope.module, ident.0, key.ns, - imported_binding, + import_decl, warn_ambiguity, ); } @@ -488,16 +488,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics. fn import_dummy_binding(&mut self, import: Import<'ra>, is_indeterminate: bool) { - if let ImportKind::Single { target, ref bindings, .. } = import.kind { - if !(is_indeterminate || bindings.iter().all(|binding| binding.get().decl().is_none())) - { + if let ImportKind::Single { target, ref decls, .. } = import.kind { + if !(is_indeterminate || decls.iter().all(|d| d.get().decl().is_none())) { return; // Has resolution, do not create the dummy binding } let dummy_decl = self.dummy_decl; - let dummy_decl = self.import(dummy_decl, import); + let dummy_decl = self.new_import_decl(dummy_decl, import); self.per_ns(|this, ns| { let module = import.parent_scope.module; - let _ = this.try_define_local(module, target, ns, dummy_decl, false); + let _ = + this.try_plant_decl_into_local_module(module, target, ns, dummy_decl, false); // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { let key = BindingKey::new(target, ns); @@ -574,10 +574,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { glob_error |= import.is_glob(); - if let ImportKind::Single { source, ref bindings, .. } = import.kind + if let ImportKind::Single { source, ref decls, .. } = import.kind && source.name == kw::SelfLower // Silence `unresolved import` error if E0429 is already emitted - && let PendingDecl::Ready(None) = bindings.value_ns.get() + && let PendingDecl::Ready(None) = decls.value_ns.get() { continue; } @@ -631,7 +631,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { for module in &self.local_modules { for (key, resolution) in self.resolutions(*module).borrow().iter() { let resolution = resolution.borrow(); - let Some(binding) = resolution.best_binding() else { continue }; + let Some(binding) = resolution.best_decl() else { continue }; if let DeclKind::Import { import, .. } = binding.kind && let Some(amb_binding) = binding.ambiguity @@ -651,16 +651,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ); } - if let Some(glob_binding) = resolution.glob_binding - && resolution.non_glob_binding.is_some() + if let Some(glob_decl) = resolution.glob_decl + && resolution.non_glob_decl.is_some() { if binding.res() != Res::Err - && glob_binding.res() != Res::Err - && let DeclKind::Import { import: glob_import, .. } = glob_binding.kind + && glob_decl.res() != Res::Err + && let DeclKind::Import { import: glob_import, .. } = glob_decl.kind && let Some(glob_import_id) = glob_import.id() && let glob_import_def_id = self.local_def_id(glob_import_id) && self.effective_visibilities.is_exported(glob_import_def_id) - && glob_binding.vis.is_public() + && glob_decl.vis.is_public() && !binding.vis.is_public() { let binding_id = match binding.kind { @@ -677,7 +677,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { BuiltinLintDiag::HiddenGlobReexports { name: key.ident.name.to_string(), namespace: key.ns.descr().to_owned(), - glob_reexport_span: glob_binding.span, + glob_reexport_span: glob_decl.span, private_item_span: binding.span, }, ); @@ -838,8 +838,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { import.imported_module.set_unchecked(Some(module)); let (source, target, bindings, type_ns_only) = match import.kind { - ImportKind::Single { source, target, ref bindings, type_ns_only, .. } => { - (source, target, bindings, type_ns_only) + ImportKind::Single { source, target, ref decls, type_ns_only, .. } => { + (source, target, decls, type_ns_only) } ImportKind::Glob { .. } => { self.get_mut_unchecked().resolve_glob_import(import); @@ -876,14 +876,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .emit(); } // We need the `target`, `source` can be extracted. - let imported_binding = this.import(binding, import); - this.get_mut_unchecked().define_binding_local( + let import_decl = this.new_import_decl(binding, import); + this.get_mut_unchecked().plant_decl_into_local_module( parent, target, ns, - imported_binding, + import_decl, ); - PendingDecl::Ready(Some(imported_binding)) + PendingDecl::Ready(Some(import_decl)) } Err(Determinacy::Determined) => { // Don't remove underscores from `single_imports`, they were never added. @@ -917,8 +917,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Optionally returns an unresolved import error. This error is buffered and used to /// consolidate multiple unresolved import errors into a single diagnostic. fn finalize_import(&mut self, import: Import<'ra>) -> Option { - let ignore_binding = match &import.kind { - ImportKind::Single { bindings, .. } => bindings[TypeNS].get().decl(), + let ignore_decl = match &import.kind { + ImportKind::Single { decls, .. } => decls[TypeNS].get().decl(), _ => None, }; let ambiguity_errors_len = @@ -934,7 +934,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, &import.parent_scope, Some(finalize), - ignore_binding, + ignore_decl, Some(import), ); @@ -1037,8 +1037,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; let (ident, target, bindings, type_ns_only, import_id) = match import.kind { - ImportKind::Single { source, target, ref bindings, type_ns_only, id, .. } => { - (source, target, bindings, type_ns_only, id) + ImportKind::Single { source, target, ref decls, type_ns_only, id, .. } => { + (source, target, decls, type_ns_only, id) } ImportKind::Glob { ref max_vis, id } => { if import.module_path.len() <= 1 { @@ -1094,7 +1094,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, &import.parent_scope, Some(finalize), - ignore_binding, + ignore_decl, None, ) { let res = module.res().map(|r| (r, ident)); @@ -1197,7 +1197,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // Never suggest the same name let resolution = resolution.borrow(); - if let Some(name_binding) = resolution.best_binding() { + if let Some(name_binding) = resolution.best_decl() { match name_binding.kind { DeclKind::Import { binding, .. } => { match binding.kind { @@ -1383,7 +1383,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool { // This function is only called for single imports. - let ImportKind::Single { source, target, ref bindings, id, .. } = import.kind else { + let ImportKind::Single { source, target, ref decls, id, .. } = import.kind else { unreachable!() }; @@ -1410,7 +1410,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut is_redundant = true; let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None }; self.per_ns(|this, ns| { - let binding = bindings[ns].get().decl().map(|b| b.import_source()); + let binding = decls[ns].get().decl().map(|b| b.import_source()); if is_redundant && let Some(binding) = binding { if binding.res() == Res::Err { return; @@ -1422,7 +1422,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &import.parent_scope, None, false, - bindings[ns].get().decl(), + decls[ns].get().decl(), None, ) { Ok(other_binding) => { @@ -1497,16 +1497,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None => continue, }; if self.is_accessible_from(binding.vis, scope) { - let imported_binding = self.import(binding, import); + let import_decl = self.new_import_decl(binding, import); let warn_ambiguity = self .resolution(import.parent_scope.module, key) .and_then(|r| r.binding()) .is_some_and(|binding| binding.warn_ambiguity_recursive()); - let _ = self.try_define_local( + let _ = self.try_plant_decl_into_local_module( import.parent_scope.module, key.ident.0, key.ns, - imported_binding, + import_decl, warn_ambiguity, ); } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2685efa28b64..b4941a6f5b99 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -677,7 +677,7 @@ impl MaybeExported<'_> { /// Used for recording UnnecessaryQualification. #[derive(Debug)] pub(crate) struct UnnecessaryQualification<'ra> { - pub binding: LateDecl<'ra>, + pub decl: LateDecl<'ra>, pub node_id: NodeId, pub path_span: Span, pub removal_span: Span, @@ -1489,7 +1489,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ident: Ident, ns: Namespace, finalize: Option, - ignore_binding: Option>, + ignore_decl: Option>, ) -> Option> { self.r.resolve_ident_in_lexical_scope( ident, @@ -1497,7 +1497,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { &self.parent_scope, finalize, &self.ribs[ns], - ignore_binding, + ignore_decl, Some(&self.diag_metadata), ) } @@ -3630,9 +3630,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }; ident.span.normalize_to_macros_2_0_and_adjust(module.expansion); let key = BindingKey::new(ident, ns); - let mut binding = self.r.resolution(module, key).and_then(|r| r.best_binding()); - debug!(?binding); - if binding.is_none() { + let mut decl = self.r.resolution(module, key).and_then(|r| r.best_decl()); + debug!(?decl); + if decl.is_none() { // We could not find the trait item in the correct namespace. // Check the other namespace to report an error. let ns = match ns { @@ -3641,8 +3641,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { _ => ns, }; let key = BindingKey::new(ident, ns); - binding = self.r.resolution(module, key).and_then(|r| r.best_binding()); - debug!(?binding); + decl = self.r.resolution(module, key).and_then(|r| r.best_decl()); + debug!(?decl); } let feed_visibility = |this: &mut Self, def_id| { @@ -3659,7 +3659,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.r.feed_visibility(this.r.feed(id), vis); }; - let Some(binding) = binding else { + let Some(decl) = decl else { // We could not find the method: report an error. let candidate = self.find_similarly_named_assoc_item(ident.name, kind); let path = &self.current_trait_ref.as_ref().unwrap().1.path; @@ -3669,7 +3669,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { return; }; - let res = binding.res(); + let res = decl.res(); let Res::Def(def_kind, id_in_trait) = res else { bug!() }; feed_visibility(self, id_in_trait); @@ -3680,7 +3680,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ResolutionError::TraitImplDuplicate { name: ident, old_span: *entry.get(), - trait_item_span: binding.span, + trait_item_span: decl.span, }, ); return; @@ -3720,7 +3720,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { kind, code, trait_path, - trait_item_span: binding.span, + trait_item_span: decl.span, }, ); } @@ -5356,9 +5356,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { (res == binding.res()).then_some((seg, binding)) }); - if let Some((seg, binding)) = unqualified { + if let Some((seg, decl)) = unqualified { self.r.potentially_unnecessary_qualifications.push(UnnecessaryQualification { - binding, + decl, node_id: finalize.node_id, path_span: finalize.path_span, removal_span: path[0].ident.span.until(seg.ident.span), diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index f75ac400dc0b..73e1a8f0c3bc 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -891,10 +891,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn lookup_doc_alias_name(&mut self, path: &[Segment], ns: Namespace) -> Option<(DefId, Ident)> { let find_doc_alias_name = |r: &mut Resolver<'ra, '_>, m: Module<'ra>, item_name: Symbol| { for resolution in r.resolutions(m).borrow().values() { - let Some(did) = resolution - .borrow() - .best_binding() - .and_then(|binding| binding.res().opt_def_id()) + let Some(did) = + resolution.borrow().best_decl().and_then(|binding| binding.res().opt_def_id()) else { continue; }; @@ -1589,19 +1587,17 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path(mod_path, None, None, *source) { - let targets: Vec<_> = self - .r - .resolutions(module) - .borrow() - .iter() - .filter_map(|(key, resolution)| { - resolution - .borrow() - .best_binding() - .map(|binding| binding.res()) - .and_then(|res| if filter_fn(res) { Some((*key, res)) } else { None }) - }) - .collect(); + let targets: Vec<_> = + self.r + .resolutions(module) + .borrow() + .iter() + .filter_map(|(key, resolution)| { + resolution.borrow().best_decl().map(|binding| binding.res()).and_then( + |res| if filter_fn(res) { Some((*key, res)) } else { None }, + ) + }) + .collect(); if let [target] = targets.as_slice() { return Some(TypoSuggestion::single_item_from_ident( target.0.ident.0, @@ -2486,9 +2482,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .resolutions(*module) .borrow() .iter() - .filter_map(|(key, res)| { - res.borrow().best_binding().map(|binding| (key, binding.res())) - }) + .filter_map(|(key, res)| res.borrow().best_decl().map(|binding| (key, binding.res()))) .filter(|(_, res)| match (kind, res) { (AssocItemKind::Const(..), Res::Def(DefKind::AssocConst, _)) => true, (AssocItemKind::Fn(_), Res::Def(DefKind::AssocFn, _)) => true, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 67449050aea9..27817c0473ab 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -692,8 +692,8 @@ impl<'ra> Module<'ra> { mut f: impl FnMut(&R, Macros20NormalizedIdent, Namespace, Decl<'ra>), ) { for (key, name_resolution) in resolver.as_ref().resolutions(self).borrow().iter() { - if let Some(binding) = name_resolution.borrow().best_binding() { - f(resolver, key.ident, key.ns, binding); + if let Some(decl) = name_resolution.borrow().best_decl() { + f(resolver, key.ident, key.ns, decl); } } } @@ -704,8 +704,8 @@ impl<'ra> Module<'ra> { mut f: impl FnMut(&mut R, Macros20NormalizedIdent, Namespace, Decl<'ra>), ) { for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() { - if let Some(binding) = name_resolution.borrow().best_binding() { - f(resolver, key.ident, key.ns, binding); + if let Some(decl) = name_resolution.borrow().best_decl() { + f(resolver, key.ident, key.ns, decl); } } } @@ -842,7 +842,7 @@ enum DeclKind<'ra> { } impl<'ra> DeclKind<'ra> { - /// Is this a name binding of an import? + /// Is this an import declaration? fn is_import(&self) -> bool { matches!(*self, DeclKind::Import { .. }) } @@ -851,7 +851,7 @@ impl<'ra> DeclKind<'ra> { #[derive(Debug)] struct PrivacyError<'ra> { ident: Ident, - binding: Decl<'ra>, + decl: Decl<'ra>, dedup_span: Span, outermost_res: Option<(Res, Ident)>, parent_scope: ParentScope<'ra>, @@ -2047,15 +2047,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn record_use_inner( &mut self, ident: Ident, - used_binding: Decl<'ra>, + used_decl: Decl<'ra>, used: Used, warn_ambiguity: bool, ) { - if let Some(b2) = used_binding.ambiguity { + if let Some(b2) = used_decl.ambiguity { let ambiguity_error = AmbiguityError { kind: AmbiguityKind::GlobVsGlob, ident, - b1: used_binding, + b1: used_decl, b2, scope1: Scope::ModuleGlobs(self.empty_module, None), scope2: Scope::ModuleGlobs(self.empty_module, None), @@ -2066,7 +2066,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.ambiguity_errors.push(ambiguity_error); } } - if let DeclKind::Import { import, binding } = used_binding.kind { + if let DeclKind::Import { import, binding } = used_decl.kind { if let ImportKind::MacroUse { warn_private: true } = import.kind { // Do not report the lint if the macro name resolves in stdlib prelude // even without the problematic `macro_use` import. @@ -2096,7 +2096,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // but not introduce it, as used if they are accessed from lexical scope. if used == Used::Scope && let Some(entry) = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)) - && entry.item_decl == Some((used_binding, false)) + && entry.item_decl == Some((used_decl, false)) { return; } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 898d198c5475..c9c754374c87 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -46,7 +46,7 @@ use crate::{ type Res = def::Res; /// Name declaration produced by a `macro_rules` item definition. -/// Not modularized, can shadow previous `macro_rules` bindings, etc. +/// Not modularized, can shadow previous `macro_rules` definitions, etc. #[derive(Debug)] pub(crate) struct MacroRulesDecl<'ra> { pub(crate) decl: Decl<'ra>, From db26d01211b55e1834b427049fc06c64a1ca0d0c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Dec 2025 23:51:07 +0300 Subject: [PATCH 1638/3801] resolve: `DeclKind::Import::binding` -> `DeclKind::Import::source_decl` --- compiler/rustc_resolve/src/diagnostics.rs | 12 +++---- .../src/effective_visibilities.rs | 6 ++-- compiler/rustc_resolve/src/imports.rs | 10 +++--- compiler/rustc_resolve/src/lib.rs | 32 +++++++++---------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7ed29b91b67a..7c86ed91a07a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1357,8 +1357,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // #90113: Do not count an inaccessible reexported item as a candidate. - if let DeclKind::Import { binding, .. } = name_binding.kind - && this.is_accessible_from(binding.vis, parent_scope.module) + if let DeclKind::Import { source_decl, .. } = name_binding.kind + && this.is_accessible_from(source_decl.vis, parent_scope.module) && !this.is_accessible_from(name_binding.vis, parent_scope.module) { return; @@ -2210,15 +2210,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let name = next_ident; next_binding = match binding.kind { _ if res == Res::Err => None, - DeclKind::Import { binding, import, .. } => match import.kind { - _ if binding.span.is_dummy() => None, + DeclKind::Import { source_decl, import, .. } => match import.kind { + _ if source_decl.span.is_dummy() => None, ImportKind::Single { source, .. } => { next_ident = source; - Some(binding) + Some(source_decl) } ImportKind::Glob { .. } | ImportKind::MacroUse { .. } - | ImportKind::MacroExport => Some(binding), + | ImportKind::MacroExport => Some(source_decl), ImportKind::ExternCrate { .. } => None, }, _ => None, diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 87be913df535..e5144332f2b7 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -128,7 +128,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { let is_ambiguity = |decl: Decl<'ra>, warn: bool| decl.ambiguity.is_some() && !warn; let mut parent_id = ParentId::Def(module_id); let mut warn_ambiguity = decl.warn_ambiguity; - while let DeclKind::Import { binding: nested_binding, .. } = decl.kind { + while let DeclKind::Import { source_decl, .. } = decl.kind { self.update_import(decl, parent_id); if is_ambiguity(decl, warn_ambiguity) { @@ -139,8 +139,8 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { } parent_id = ParentId::Import(decl); - decl = nested_binding; - warn_ambiguity |= nested_binding.warn_ambiguity; + decl = source_decl; + warn_ambiguity |= source_decl.warn_ambiguity; } if !is_ambiguity(decl, warn_ambiguity) && let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local()) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 0fbfbd95a026..a8bb53cc7f27 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -316,7 +316,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } self.arenas.alloc_decl(DeclData { - kind: DeclKind::Import { binding: decl, import }, + kind: DeclKind::Import { source_decl: decl, import }, ambiguity: None, warn_ambiguity: false, span: import.span, @@ -1199,10 +1199,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let resolution = resolution.borrow(); if let Some(name_binding) = resolution.best_decl() { match name_binding.kind { - DeclKind::Import { binding, .. } => { - match binding.kind { - // Never suggest the name that has binding error - // i.e., the name that cannot be previously resolved + DeclKind::Import { source_decl, .. } => { + match source_decl.kind { + // Never suggest names that previously could not + // be resolved. DeclKind::Def(Res::Err) => None, _ => Some(i.name), } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 27817c0473ab..063b6b4058f0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -838,7 +838,7 @@ enum DeclKind<'ra> { /// can be provided by source code or built into the language. Def(Res), /// The name declaration is a link to another name declaration. - Import { binding: Decl<'ra>, import: Import<'ra> }, + Import { source_decl: Decl<'ra>, import: Import<'ra> }, } impl<'ra> DeclKind<'ra> { @@ -926,13 +926,13 @@ impl<'ra> DeclData<'ra> { fn res(&self) -> Res { match self.kind { DeclKind::Def(res) => res, - DeclKind::Import { binding, .. } => binding.res(), + DeclKind::Import { source_decl, .. } => source_decl.res(), } } fn import_source(&self) -> Decl<'ra> { match self.kind { - DeclKind::Import { binding, .. } => binding, + DeclKind::Import { source_decl, .. } => source_decl, _ => unreachable!(), } } @@ -941,7 +941,7 @@ impl<'ra> DeclData<'ra> { match self.ambiguity { Some(ambig_binding) => Some((self, ambig_binding)), None => match self.kind { - DeclKind::Import { binding, .. } => binding.descent_to_ambiguity(), + DeclKind::Import { source_decl, .. } => source_decl.descent_to_ambiguity(), _ => None, }, } @@ -950,7 +950,7 @@ impl<'ra> DeclData<'ra> { fn is_ambiguity_recursive(&self) -> bool { self.ambiguity.is_some() || match self.kind { - DeclKind::Import { binding, .. } => binding.is_ambiguity_recursive(), + DeclKind::Import { source_decl, .. } => source_decl.is_ambiguity_recursive(), _ => false, } } @@ -958,14 +958,14 @@ impl<'ra> DeclData<'ra> { fn warn_ambiguity_recursive(&self) -> bool { self.warn_ambiguity || match self.kind { - DeclKind::Import { binding, .. } => binding.warn_ambiguity_recursive(), + DeclKind::Import { source_decl, .. } => source_decl.warn_ambiguity_recursive(), _ => false, } } fn is_possibly_imported_variant(&self) -> bool { match self.kind { - DeclKind::Import { binding, .. } => binding.is_possibly_imported_variant(), + DeclKind::Import { source_decl, .. } => source_decl.is_possibly_imported_variant(), DeclKind::Def(Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _)) => { true } @@ -1012,9 +1012,9 @@ impl<'ra> DeclData<'ra> { fn reexport_chain(self: Decl<'ra>, r: &Resolver<'_, '_>) -> SmallVec<[Reexport; 2]> { let mut reexport_chain = SmallVec::new(); let mut next_binding = self; - while let DeclKind::Import { binding, import, .. } = next_binding.kind { + while let DeclKind::Import { source_decl, import, .. } = next_binding.kind { reexport_chain.push(import.simplify(r)); - next_binding = binding; + next_binding = source_decl; } reexport_chain } @@ -1043,9 +1043,9 @@ impl<'ra> DeclData<'ra> { // FIXME: How can we integrate it with the `update_resolution`? fn determined(&self) -> bool { match &self.kind { - DeclKind::Import { binding, import, .. } if import.is_glob() => { + DeclKind::Import { source_decl, import, .. } if import.is_glob() => { import.parent_scope.module.unexpanded_invocations.borrow().is_empty() - && binding.determined() + && source_decl.determined() } _ => true, } @@ -1985,14 +1985,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { trait_name: Ident, ) -> SmallVec<[LocalDefId; 1]> { let mut import_ids = smallvec![]; - while let DeclKind::Import { import, binding, .. } = kind { + while let DeclKind::Import { import, source_decl, .. } = kind { if let Some(node_id) = import.id() { let def_id = self.local_def_id(node_id); self.maybe_unused_trait_imports.insert(def_id); import_ids.push(def_id); } self.add_to_glob_map(*import, trait_name); - kind = &binding.kind; + kind = &source_decl.kind; } import_ids } @@ -2066,7 +2066,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.ambiguity_errors.push(ambiguity_error); } } - if let DeclKind::Import { import, binding } = used_decl.kind { + if let DeclKind::Import { import, source_decl } = used_decl.kind { if let ImportKind::MacroUse { warn_private: true } = import.kind { // Do not report the lint if the macro name resolves in stdlib prelude // even without the problematic `macro_use` import. @@ -2110,9 +2110,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.add_to_glob_map(import, ident); self.record_use_inner( ident, - binding, + source_decl, Used::Other, - warn_ambiguity || binding.warn_ambiguity, + warn_ambiguity || source_decl.warn_ambiguity, ); } } From 14ac6a1d3a3e153a546d3e71b51866ca77a02dcd Mon Sep 17 00:00:00 2001 From: sgasho Date: Wed, 7 Jan 2026 00:19:09 +0900 Subject: [PATCH 1639/3801] Modified to output error messages appropriate to the situation --- compiler/rustc_codegen_llvm/messages.ftl | 6 ++-- compiler/rustc_codegen_llvm/src/errors.rs | 8 ++++- compiler/rustc_codegen_llvm/src/lib.rs | 12 ++++--- .../rustc_codegen_llvm/src/llvm/enzyme_ffi.rs | 34 ++++++++++++++----- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index 018d240b2ae5..85cb7499cca4 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -1,5 +1,7 @@ -codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend. - .note = load error: {$err} +codegen_llvm_autodiff_component_missing = autodiff backend not found in the sysroot: {$err} + .note = it will be distributed via rustup in the future + +codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend: {$err} codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 439664b8b9a2..bd42cf556966 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -34,11 +34,17 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_component_unavailable)] -#[note] pub(crate) struct AutoDiffComponentUnavailable { pub err: String, } +#[derive(Diagnostic)] +#[diag(codegen_llvm_autodiff_component_missing)] +#[note] +pub(crate) struct AutoDiffComponentMissing { + pub err: String, +} + #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_without_lto)] pub(crate) struct AutoDiffWithoutLto; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 801d23342973..438a74e0a091 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -249,10 +249,14 @@ impl CodegenBackend for LlvmCodegenBackend { use crate::back::lto::enable_autodiff_settings; if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) { - if let Err(err) = llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) { - sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable { - err: format!("{err:?}"), - }); + match llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) { + Ok(_) => {} + Err(llvm::EnzymeLibraryError::NotFound { err }) => { + sess.dcx().emit_fatal(crate::errors::AutoDiffComponentMissing { err }); + } + Err(llvm::EnzymeLibraryError::LoadFailed { err }) => { + sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable { err }); + } } enable_autodiff_settings(&sess.opts.unstable_opts.autodiff); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index b11310b970d0..67fbc0f53adc 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -153,7 +153,7 @@ pub(crate) mod Enzyme_AD { fn load_ptr_by_symbol_mut_void( lib: &libloading::Library, bytes: &[u8], - ) -> Result<*mut c_void, Box> { + ) -> Result<*mut c_void, libloading::Error> { unsafe { let s: libloading::Symbol<'_, *mut c_void> = lib.get(bytes)?; // libloading = 0.9.0: try_as_raw_ptr always succeeds and returns Some @@ -192,15 +192,27 @@ pub(crate) mod Enzyme_AD { static ENZYME_INSTANCE: OnceLock> = OnceLock::new(); + #[derive(Debug)] + pub(crate) enum EnzymeLibraryError { + NotFound { err: String }, + LoadFailed { err: String }, + } + + impl From for EnzymeLibraryError { + fn from(err: libloading::Error) -> Self { + Self::LoadFailed { err: format!("{err:?}") } + } + } + impl EnzymeWrapper { /// Initialize EnzymeWrapper with the given sysroot if not already initialized. /// Safe to call multiple times - subsequent calls are no-ops due to OnceLock. pub(crate) fn get_or_init( sysroot: &rustc_session::config::Sysroot, - ) -> Result, Box> { + ) -> Result, EnzymeLibraryError> { let mtx: &'static Mutex = ENZYME_INSTANCE.get_or_try_init(|| { let w = Self::call_dynamic(sysroot)?; - Ok::<_, Box>(Mutex::new(w)) + Ok::<_, EnzymeLibraryError>(Mutex::new(w)) })?; Ok(mtx.lock().unwrap()) @@ -351,7 +363,7 @@ pub(crate) mod Enzyme_AD { #[allow(non_snake_case)] fn call_dynamic( sysroot: &rustc_session::config::Sysroot, - ) -> Result> { + ) -> Result { let enzyme_path = Self::get_enzyme_path(sysroot)?; let lib = unsafe { libloading::Library::new(enzyme_path)? }; @@ -416,7 +428,7 @@ pub(crate) mod Enzyme_AD { }) } - fn get_enzyme_path(sysroot: &Sysroot) -> Result { + fn get_enzyme_path(sysroot: &Sysroot) -> Result { let llvm_version_major = unsafe { LLVMRustVersionMajor() }; let path_buf = sysroot @@ -434,15 +446,19 @@ pub(crate) mod Enzyme_AD { .map(|p| p.join("lib").display().to_string()) .collect::>() .join("\n* "); - format!( - "failed to find a `libEnzyme-{llvm_version_major}` folder \ + EnzymeLibraryError::NotFound { + err: format!( + "failed to find a `libEnzyme-{llvm_version_major}` folder \ in the sysroot candidates:\n* {candidates}" - ) + ), + } })?; Ok(path_buf .to_str() - .ok_or_else(|| format!("invalid UTF-8 in path: {}", path_buf.display()))? + .ok_or_else(|| EnzymeLibraryError::LoadFailed { + err: format!("invalid UTF-8 in path: {}", path_buf.display()), + })? .to_string()) } } From 76d0843f8d05e34b49b4ec830ff745593269d8e4 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 31 Oct 2025 19:07:29 +0100 Subject: [PATCH 1640/3801] naked functions: emit `.private_extern` on macos --- .../rustc_codegen_ssa/src/mir/naked_asm.rs | 3 +- .../rustc_monomorphize/src/partitioning.rs | 10 +++++ tests/assembly-llvm/naked-functions/aix.rs | 2 +- tests/assembly-llvm/naked-functions/hidden.rs | 41 +++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 tests/assembly-llvm/naked-functions/hidden.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 4a47799b2bdc..4bbb7470debe 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -181,7 +181,8 @@ fn prefix_and_suffix<'tcx>( } } Linkage::Internal => { - // write nothing + // LTO can fail when internal linkage is used. + emit_fatal("naked functions may not have internal linkage") } Linkage::Common => emit_fatal("Functions may not have common linkage"), Linkage::AvailableExternally => { diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 1c8d6db08c31..e7af1d45cff8 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -580,6 +580,16 @@ fn internalize_symbols<'tcx>( } } + // When LTO inlines the caller of a naked function, it will attempt but fail to make the + // naked function symbol visible. To ensure that LTO works correctly, do not default + // naked functions to internal linkage and default visibility. + if let MonoItem::Fn(instance) = item { + let flags = cx.tcx.codegen_instance_attrs(instance.def).flags; + if flags.contains(CodegenFnAttrFlags::NAKED) { + continue; + } + } + // If we got here, we did not find any uses from other CGUs, so // it's fine to make this monomorphization internal. data.linkage = Linkage::Internal; diff --git a/tests/assembly-llvm/naked-functions/aix.rs b/tests/assembly-llvm/naked-functions/aix.rs index 3cc84fa0c9c6..8391331d8341 100644 --- a/tests/assembly-llvm/naked-functions/aix.rs +++ b/tests/assembly-llvm/naked-functions/aix.rs @@ -9,7 +9,7 @@ //@[aix] needs-llvm-components: powerpc #![crate_type = "lib"] -#![feature(no_core, asm_experimental_arch, f128, linkage, fn_align)] +#![feature(no_core, asm_experimental_arch)] #![no_core] // tests that naked functions work for the `powerpc64-ibm-aix` target. diff --git a/tests/assembly-llvm/naked-functions/hidden.rs b/tests/assembly-llvm/naked-functions/hidden.rs new file mode 100644 index 000000000000..7686dbab07fb --- /dev/null +++ b/tests/assembly-llvm/naked-functions/hidden.rs @@ -0,0 +1,41 @@ +//@ revisions: macos-x86 macos-aarch64 linux-x86 +//@ add-minicore +//@ assembly-output: emit-asm +// +//@[macos-aarch64] compile-flags: --target aarch64-apple-darwin +//@[macos-aarch64] needs-llvm-components: aarch64 +// +//@[macos-x86] compile-flags: --target x86_64-apple-darwin +//@[macos-x86] needs-llvm-components: x86 +// +//@[linux-x86] compile-flags: --target x86_64-unknown-linux-gnu +//@[linux-x86] needs-llvm-components: x86 + +#![crate_type = "lib"] +#![feature(no_core, asm_experimental_arch)] +#![no_core] + +// Tests that naked functions that are not externally linked (e.g. via `no_mangle`) +// are marked as `Visibility::Hidden` and emit `.private_extern` or `.hidden`. +// +// Without this directive, LTO may fail because the symbol is not visible. +// See also https://github.com/rust-lang/rust/issues/148307. + +extern crate minicore; +use minicore::*; + +// CHECK: .p2align 2 +// macos-x86,macos-aarch64: .private_extern +// linux-x86: .globl +// linux-x86: .hidden +// CHECK: ret +#[unsafe(naked)] +extern "C" fn ret() { + naked_asm!("ret") +} + +// CHECK-LABEL: entry +#[no_mangle] +pub fn entry() { + ret() +} From 021a551d5da251d91251ad08f976319dc78d25c4 Mon Sep 17 00:00:00 2001 From: andjsrk Date: Wed, 7 Jan 2026 00:51:54 +0900 Subject: [PATCH 1641/3801] add test for repeats --- ...can-have-side-effects-depend-on-element.rs | 19 +++++++++++++++++++ ...have-side-effects-depend-on-element.stderr | 13 +++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/ui/repeat-expr/can-have-side-effects-depend-on-element.rs create mode 100644 tests/ui/repeat-expr/can-have-side-effects-depend-on-element.stderr diff --git a/tests/ui/repeat-expr/can-have-side-effects-depend-on-element.rs b/tests/ui/repeat-expr/can-have-side-effects-depend-on-element.rs new file mode 100644 index 000000000000..cd385587d491 --- /dev/null +++ b/tests/ui/repeat-expr/can-have-side-effects-depend-on-element.rs @@ -0,0 +1,19 @@ +//@ check-pass + +#![allow(unused)] + +// Test if `Expr::can_have_side_effects` considers element of repeat expressions. + +fn drop_repeat_in_arm_body() { + // Built-in lint `dropping_copy_types` relies on `Expr::can_have_side_effects` (See rust-clippy#9482) + + match () { + () => drop([0; 1]), // No side effects + //~^ WARNING calls to `std::mem::drop` with a value that implements `Copy` does nothing + } + match () { + () => drop([return; 1]), // Definitely has side effects + } +} + +fn main() {} diff --git a/tests/ui/repeat-expr/can-have-side-effects-depend-on-element.stderr b/tests/ui/repeat-expr/can-have-side-effects-depend-on-element.stderr new file mode 100644 index 000000000000..0f15e7577dca --- /dev/null +++ b/tests/ui/repeat-expr/can-have-side-effects-depend-on-element.stderr @@ -0,0 +1,13 @@ +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/can-have-side-effects-depend-on-element.rs:11:15 + | +LL | () => drop([0; 1]), // No side effects + | ^^^^^------^ + | | + | argument has type `[i32; 1]` + | + = note: use `let _ = ...` to ignore the expression or result + = note: `#[warn(dropping_copy_types)]` on by default + +warning: 1 warning emitted + From 61ca012d4b6b1678fb6649811187d8f1335d1df8 Mon Sep 17 00:00:00 2001 From: andjsrk Date: Wed, 7 Jan 2026 00:55:58 +0900 Subject: [PATCH 1642/3801] rename test --- ...-on-element.rs => can-have-side-effects-consider-element.rs} | 0 ...ent.stderr => can-have-side-effects-consider-element.stderr} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/ui/repeat-expr/{can-have-side-effects-depend-on-element.rs => can-have-side-effects-consider-element.rs} (100%) rename tests/ui/repeat-expr/{can-have-side-effects-depend-on-element.stderr => can-have-side-effects-consider-element.stderr} (87%) diff --git a/tests/ui/repeat-expr/can-have-side-effects-depend-on-element.rs b/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs similarity index 100% rename from tests/ui/repeat-expr/can-have-side-effects-depend-on-element.rs rename to tests/ui/repeat-expr/can-have-side-effects-consider-element.rs diff --git a/tests/ui/repeat-expr/can-have-side-effects-depend-on-element.stderr b/tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr similarity index 87% rename from tests/ui/repeat-expr/can-have-side-effects-depend-on-element.stderr rename to tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr index 0f15e7577dca..6948d64ebcc3 100644 --- a/tests/ui/repeat-expr/can-have-side-effects-depend-on-element.stderr +++ b/tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr @@ -1,5 +1,5 @@ warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing - --> $DIR/can-have-side-effects-depend-on-element.rs:11:15 + --> $DIR/can-have-side-effects-consider-element.rs:11:15 | LL | () => drop([0; 1]), // No side effects | ^^^^^------^ From 1cd87525e6b566b560a540626de9bfac6cc90b4a Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 4 Jan 2026 11:23:35 +0100 Subject: [PATCH 1643/3801] Unix implementation for stdio set/take/replace --- library/std/src/os/unix/io/mod.rs | 129 ++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs index 6d4090ee31cf..708ebaec362e 100644 --- a/library/std/src/os/unix/io/mod.rs +++ b/library/std/src/os/unix/io/mod.rs @@ -92,9 +92,138 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::io::{self, Stderr, StderrLock, Stdin, StdinLock, Stdout, StdoutLock, Write}; #[stable(feature = "rust1", since = "1.0.0")] pub use crate::os::fd::*; +#[allow(unused_imports)] // not used on all targets +use crate::sys::cvt; // Tests for this module #[cfg(test)] mod tests; + +#[unstable(feature = "stdio_swap", issue = "150667", reason = "recently added")] +pub trait StdioExt: crate::sealed::Sealed { + /// Redirects the stdio file descriptor to point to the file description underpinning `fd`. + /// + /// Rust std::io write buffers (if any) are flushed, but other runtimes + /// (e.g. C stdio) or libraries that acquire a clone of the file descriptor + /// will not be aware of this change. + /// + /// # Platform-specific behavior + /// + /// This is [currently] implemented using + /// + /// - `fd_renumber` on wasip1 + /// - `dup2` on most unixes + /// + /// [currently]: crate::io#platform-specific-behavior + /// + /// ``` + /// #![feature(stdio_swap)] + /// use std::io::{self, Read, Write}; + /// use std::os::unix::io::StdioExt; + /// + /// fn main() -> io::Result<()> { + /// let (reader, mut writer) = io::pipe()?; + /// let mut stdin = io::stdin(); + /// stdin.set_fd(reader)?; + /// writer.write_all(b"Hello, world!")?; + /// let mut buffer = vec![0; 13]; + /// assert_eq!(stdin.read(&mut buffer)?, 13); + /// assert_eq!(&buffer, b"Hello, world!"); + /// Ok(()) + /// } + /// ``` + fn set_fd>(&mut self, fd: T) -> io::Result<()>; + + /// Redirects the stdio file descriptor and returns a new `OwnedFd` + /// backed by the previous file description. + /// + /// See [`set_fd()`] for details. + /// + /// [`set_fd()`]: StdioExt::set_fd + fn replace_fd>(&mut self, replace_with: T) -> io::Result; + + /// Redirects the stdio file descriptor to the null device (`/dev/null`) + /// and returns a new `OwnedFd` backed by the previous file description. + /// + /// Programs that communicate structured data via stdio can use this early in `main()` to + /// extract the fds, treat them as other IO types (`File`, `UnixStream`, etc), + /// apply custom buffering or avoid interference from stdio use later in the program. + /// + /// See [`set_fd()`] for additional details. + /// + /// [`set_fd()`]: StdioExt::set_fd + fn take_fd(&mut self) -> io::Result; +} + +macro io_ext_impl($stdio_ty:ty, $stdio_lock_ty:ty, $writer:literal) { + #[unstable(feature = "stdio_swap", issue = "150667", reason = "recently added")] + impl StdioExt for $stdio_ty { + fn set_fd>(&mut self, fd: T) -> io::Result<()> { + self.lock().set_fd(fd) + } + + fn take_fd(&mut self) -> io::Result { + self.lock().take_fd() + } + + fn replace_fd>(&mut self, replace_with: T) -> io::Result { + self.lock().replace_fd(replace_with) + } + } + + #[unstable(feature = "stdio_swap", issue = "150667", reason = "recently added")] + impl StdioExt for $stdio_lock_ty { + fn set_fd>(&mut self, fd: T) -> io::Result<()> { + #[cfg($writer)] + self.flush()?; + replace_stdio_fd(self.as_fd(), fd.into()) + } + + fn take_fd(&mut self) -> io::Result { + let null = null_fd()?; + let cloned = self.as_fd().try_clone_to_owned()?; + self.set_fd(null)?; + Ok(cloned) + } + + fn replace_fd>(&mut self, replace_with: T) -> io::Result { + let cloned = self.as_fd().try_clone_to_owned()?; + self.set_fd(replace_with)?; + Ok(cloned) + } + } +} + +io_ext_impl!(Stdout, StdoutLock<'_>, true); +io_ext_impl!(Stdin, StdinLock<'_>, false); +io_ext_impl!(Stderr, StderrLock<'_>, true); + +fn null_fd() -> io::Result { + let null_dev = crate::fs::OpenOptions::new().read(true).write(true).open("/dev/null")?; + Ok(null_dev.into()) +} + +/// Replaces the underlying file descriptor with the one from `other`. +/// Does not set CLOEXEC. +fn replace_stdio_fd(this: BorrowedFd<'_>, other: OwnedFd) -> io::Result<()> { + cfg_select! { + all(target_os = "wasi", target_env = "p1") => { + cvt(unsafe { libc::__wasilibc_fd_renumber(other.as_raw_fd(), this.as_raw_fd()) }).map(|_| ()) + } + not(any( + target_arch = "wasm32", + target_os = "hermit", + target_os = "trusty", + target_os = "motor" + )) => { + cvt(unsafe {libc::dup2(other.as_raw_fd(), this.as_raw_fd())}).map(|_| ()) + } + _ => { + let _ = (this, other); + Err(io::Error::UNSUPPORTED_PLATFORM) + } + } +} From 630c7596e959e6ab9b18552e81081e5ff346b1c3 Mon Sep 17 00:00:00 2001 From: kulst Date: Thu, 1 Jan 2026 19:25:29 +0100 Subject: [PATCH 1644/3801] Ensure that static initializers are acyclic for NVPTX NVPTX does not support cycles in static initializers. LLVM produces an error when attempting to codegen such constructs (like self referential structs). To not produce LLVM UB we instead emit a post-monomorphization error on Rust side before reaching codegen. This is achieved by analysing a subgraph of the "mono item graph" that only contains statics: 1. Calculate the strongly connected components (SCCs) of the graph 2. Check for cycles (more than one node in a SCC or exactly one node which references itself) --- Cargo.lock | 1 + compiler/rustc_monomorphize/Cargo.toml | 1 + compiler/rustc_monomorphize/messages.ftl | 4 + compiler/rustc_monomorphize/src/collector.rs | 3 +- compiler/rustc_monomorphize/src/errors.rs | 12 ++ .../src/graph_checks/mod.rs | 18 +++ .../src/graph_checks/statics.rs | 115 ++++++++++++++++++ compiler/rustc_monomorphize/src/lib.rs | 1 + .../rustc_monomorphize/src/partitioning.rs | 3 + compiler/rustc_target/src/spec/json.rs | 3 + compiler/rustc_target/src/spec/mod.rs | 4 + .../src/spec/targets/nvptx64_nvidia_cuda.rs | 3 + .../platform-support/nvptx64-nvidia-cuda.md | 33 +++++ tests/auxiliary/minicore.rs | 2 +- ...static-initializer-acyclic-issue-146787.rs | 29 +++++ ...ic-initializer-acyclic-issue-146787.stderr | 32 +++++ 16 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 compiler/rustc_monomorphize/src/graph_checks/mod.rs create mode 100644 compiler/rustc_monomorphize/src/graph_checks/statics.rs create mode 100644 tests/ui/static/static-initializer-acyclic-issue-146787.rs create mode 100644 tests/ui/static/static-initializer-acyclic-issue-146787.stderr diff --git a/Cargo.lock b/Cargo.lock index 816bb1a37859..d0d47f882a89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4421,6 +4421,7 @@ dependencies = [ "rustc_errors", "rustc_fluent_macro", "rustc_hir", + "rustc_index", "rustc_macros", "rustc_middle", "rustc_session", diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 09a55f0b5f8d..0829d52283ab 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -10,6 +10,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index edb91d8f2eda..09500ba73359 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -75,4 +75,8 @@ monomorphize_recursion_limit = monomorphize_start_not_found = using `fn main` requires the standard library .help = use `#![no_main]` to bypass the Rust generated entrypoint and declare a platform specific entrypoint yourself, usually with `#[no_mangle]` +monomorphize_static_initializer_cyclic = static initializer forms a cycle involving `{$head}` + .label = part of this cycle + .note = cyclic static initializers are not supported for target `{$target}` + monomorphize_symbol_already_defined = symbol `{$symbol}` is already defined diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 4b2f8e03afc1..070db1ae6b5e 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -267,7 +267,8 @@ pub(crate) struct UsageMap<'tcx> { // Maps every mono item to the mono items used by it. pub used_map: UnordMap, Vec>>, - // Maps every mono item to the mono items that use it. + // Maps each mono item with users to the mono items that use it. + // Be careful: subsets `used_map`, so unused items are vacant. user_map: UnordMap, Vec>>, } diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 4949d9ae3922..723649f22117 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -117,3 +117,15 @@ pub(crate) struct AbiRequiredTargetFeature<'a> { /// Whether this is a problem at a call site or at a declaration. pub is_call: bool, } + +#[derive(Diagnostic)] +#[diag(monomorphize_static_initializer_cyclic)] +#[note] +pub(crate) struct StaticInitializerCyclic<'a> { + #[primary_span] + pub span: Span, + #[label] + pub labels: Vec, + pub head: &'a str, + pub target: &'a str, +} diff --git a/compiler/rustc_monomorphize/src/graph_checks/mod.rs b/compiler/rustc_monomorphize/src/graph_checks/mod.rs new file mode 100644 index 000000000000..2b9b7cfff0b2 --- /dev/null +++ b/compiler/rustc_monomorphize/src/graph_checks/mod.rs @@ -0,0 +1,18 @@ +//! Checks that need to operate on the entire mono item graph +use rustc_middle::mir::mono::MonoItem; +use rustc_middle::ty::TyCtxt; + +use crate::collector::UsageMap; +use crate::graph_checks::statics::check_static_initializers_are_acyclic; + +mod statics; + +pub(super) fn target_specific_checks<'tcx, 'a, 'b>( + tcx: TyCtxt<'tcx>, + mono_items: &'a [MonoItem<'tcx>], + usage_map: &'b UsageMap<'tcx>, +) { + if tcx.sess.target.options.static_initializer_must_be_acyclic { + check_static_initializers_are_acyclic(tcx, mono_items, usage_map); + } +} diff --git a/compiler/rustc_monomorphize/src/graph_checks/statics.rs b/compiler/rustc_monomorphize/src/graph_checks/statics.rs new file mode 100644 index 000000000000..a764d307b3d4 --- /dev/null +++ b/compiler/rustc_monomorphize/src/graph_checks/statics.rs @@ -0,0 +1,115 @@ +use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::graph::scc::Sccs; +use rustc_data_structures::graph::{DirectedGraph, Successors}; +use rustc_data_structures::unord::UnordMap; +use rustc_hir::def_id::DefId; +use rustc_index::{Idx, IndexVec, newtype_index}; +use rustc_middle::mir::mono::MonoItem; +use rustc_middle::ty::TyCtxt; + +use crate::collector::UsageMap; +use crate::errors; + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +struct StaticNodeIdx(usize); + +impl Idx for StaticNodeIdx { + fn new(idx: usize) -> Self { + Self(idx) + } + + fn index(self) -> usize { + self.0 + } +} + +impl From for StaticNodeIdx { + fn from(value: usize) -> Self { + StaticNodeIdx(value) + } +} + +newtype_index! { + #[derive(Ord, PartialOrd)] + struct StaticSccIdx {} +} + +// Adjacency-list graph for statics using `StaticNodeIdx` as node type. +// We cannot use `DefId` as the node type directly because each node must be +// represented by an index in the range `0..num_nodes`. +struct StaticRefGraph<'a, 'b, 'tcx> { + // maps from `StaticNodeIdx` to `DefId` and vice versa + statics: &'a FxIndexSet, + // contains for each `MonoItem` the `MonoItem`s it uses + used_map: &'b UnordMap, Vec>>, +} + +impl<'a, 'b, 'tcx> DirectedGraph for StaticRefGraph<'a, 'b, 'tcx> { + type Node = StaticNodeIdx; + + fn num_nodes(&self) -> usize { + self.statics.len() + } +} + +impl<'a, 'b, 'tcx> Successors for StaticRefGraph<'a, 'b, 'tcx> { + fn successors(&self, node_idx: StaticNodeIdx) -> impl Iterator { + let def_id = self.statics[node_idx.index()]; + self.used_map[&MonoItem::Static(def_id)].iter().filter_map(|&mono_item| match mono_item { + MonoItem::Static(def_id) => self.statics.get_index_of(&def_id).map(|idx| idx.into()), + _ => None, + }) + } +} + +pub(super) fn check_static_initializers_are_acyclic<'tcx, 'a, 'b>( + tcx: TyCtxt<'tcx>, + mono_items: &'a [MonoItem<'tcx>], + usage_map: &'b UsageMap<'tcx>, +) { + // Collect statics + let statics: FxIndexSet = mono_items + .iter() + .filter_map(|&mono_item| match mono_item { + MonoItem::Static(def_id) => Some(def_id), + _ => None, + }) + .collect(); + + // If we don't have any statics the check is not necessary + if statics.is_empty() { + return; + } + // Create a subgraph from the mono item graph, which only contains statics + let graph = StaticRefGraph { statics: &statics, used_map: &usage_map.used_map }; + // Calculate its SCCs + let sccs: Sccs = Sccs::new(&graph); + // Group statics by SCCs + let mut nodes_of_sccs: IndexVec> = + IndexVec::from_elem_n(Vec::new(), sccs.num_sccs()); + for i in graph.iter_nodes() { + nodes_of_sccs[sccs.scc(i)].push(i); + } + let is_cyclic = |nodes_of_scc: &[StaticNodeIdx]| -> bool { + match nodes_of_scc.len() { + 0 => false, + 1 => graph.successors(nodes_of_scc[0]).any(|x| x == nodes_of_scc[0]), + 2.. => true, + } + }; + // Emit errors for all cycles + for nodes in nodes_of_sccs.iter_mut().filter(|nodes| is_cyclic(nodes)) { + // We sort the nodes by their Span to have consistent error line numbers + nodes.sort_by_key(|node| tcx.def_span(statics[node.index()])); + + let head_def = statics[nodes[0].index()]; + let head_span = tcx.def_span(head_def); + + tcx.dcx().emit_err(errors::StaticInitializerCyclic { + span: head_span, + labels: nodes.iter().map(|&n| tcx.def_span(statics[n.index()])).collect(), + head: &tcx.def_path_str(head_def), + target: &tcx.sess.target.llvm_target, + }); + } +} diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 8b48cf5a6501..5b4f74ca6a70 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -16,6 +16,7 @@ use rustc_span::ErrorGuaranteed; mod collector; mod errors; +mod graph_checks; mod mono_checks; mod partitioning; mod util; diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 1c8d6db08c31..6a1d64bd28bc 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -124,6 +124,7 @@ use tracing::debug; use crate::collector::{self, MonoItemCollectionStrategy, UsageMap}; use crate::errors::{CouldntDumpMonoStats, SymbolAlreadyDefined}; +use crate::graph_checks::target_specific_checks; struct PartitioningCx<'a, 'tcx> { tcx: TyCtxt<'tcx>, @@ -1125,6 +1126,8 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio }; let (items, usage_map) = collector::collect_crate_mono_items(tcx, collection_strategy); + // Perform checks that need to operate on the entire mono item graph + target_specific_checks(tcx, &items, &usage_map); // If there was an error during collection (e.g. from one of the constants we evaluated), // then we stop here. This way codegen does not have to worry about failing constants. diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index a972299deeac..20fbb687b308 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -163,6 +163,7 @@ impl Target { forward!(relro_level); forward!(archive_format); forward!(allow_asm); + forward!(static_initializer_must_be_acyclic); forward!(main_needs_argc_argv); forward!(has_thread_local); forward!(obj_is_bitcode); @@ -360,6 +361,7 @@ impl ToJson for Target { target_option_val!(relro_level); target_option_val!(archive_format); target_option_val!(allow_asm); + target_option_val!(static_initializer_must_be_acyclic); target_option_val!(main_needs_argc_argv); target_option_val!(has_thread_local); target_option_val!(obj_is_bitcode); @@ -581,6 +583,7 @@ struct TargetSpecJson { relro_level: Option, archive_format: Option>, allow_asm: Option, + static_initializer_must_be_acyclic: Option, main_needs_argc_argv: Option, has_thread_local: Option, obj_is_bitcode: Option, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index b06339f59425..89c9fdc935cc 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2394,6 +2394,9 @@ pub struct TargetOptions { pub archive_format: StaticCow, /// Is asm!() allowed? Defaults to true. pub allow_asm: bool, + /// Static initializers must be acyclic. + /// Defaults to false + pub static_initializer_must_be_acyclic: bool, /// Whether the runtime startup code requires the `main` function be passed /// `argc` and `argv` values. pub main_needs_argc_argv: bool, @@ -2777,6 +2780,7 @@ impl Default for TargetOptions { archive_format: "gnu".into(), main_needs_argc_argv: true, allow_asm: true, + static_initializer_must_be_acyclic: false, has_thread_local: false, obj_is_bitcode: false, min_atomic_width: None, diff --git a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs index be09681b1f35..87c2693e9877 100644 --- a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs @@ -59,6 +59,9 @@ pub(crate) fn target() -> Target { // Support using `self-contained` linkers like the llvm-bitcode-linker link_self_contained: LinkSelfContainedDefault::True, + // Static initializers must not have cycles on this target + static_initializer_must_be_acyclic: true, + ..Default::default() }, } diff --git a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md index 0eb7e1d84bd0..c722a7086967 100644 --- a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md +++ b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md @@ -49,6 +49,39 @@ $ rustup component add llvm-tools --toolchain nightly $ rustup component add llvm-bitcode-linker --toolchain nightly ``` +## Target specific restrictions + +The PTX instruction set architecture has special requirements regarding what is +and isn't allowed. In order to avoid producing invalid PTX or generating undefined +behavior by LLVM, some Rust language features are disallowed when compiling for this target. + +### Static initializers must be acyclic + +A static's initializer must not form a cycle with itself or another static's +initializer. Therefore, the compiler will reject not only the self-referencing static `A`, +but all of the following statics. + +```Rust +struct Foo(&'static Foo); + +static A: Foo = Foo(&A); //~ ERROR static initializer forms a cycle involving `A` + +static B0: Foo = Foo(&B1); //~ ERROR static initializer forms a cycle involving `B0` +static B1: Foo = Foo(&B0); + +static C0: Foo = Foo(&C1); //~ ERROR static initializer forms a cycle involving `C0` +static C1: Foo = Foo(&C2); +static C2: Foo = Foo(&C0); +``` + +Initializers that are acyclic are allowed: + +```Rust +struct Bar(&'static u32); + +static BAR: Bar = Bar(&INT); // is allowed +static INT: u32 = 42u32; // also allowed +``` $DIR/static-initializer-acyclic-issue-146787.rs:21:1 + | +LL | static C0: Foo = Foo(&C1); + | ^^^^^^^^^^^^^^ part of this cycle +LL | static C1: Foo = Foo(&C2); + | -------------- part of this cycle +LL | static C2: Foo = Foo(&C0); + | -------------- part of this cycle + | + = note: cyclic static initializers are not supported for target `nvptx64-nvidia-cuda` + +error: static initializer forms a cycle involving `B0` + --> $DIR/static-initializer-acyclic-issue-146787.rs:18:1 + | +LL | static B0: Foo = Foo(&B1); + | ^^^^^^^^^^^^^^ part of this cycle +LL | static B1: Foo = Foo(&B0); + | -------------- part of this cycle + | + = note: cyclic static initializers are not supported for target `nvptx64-nvidia-cuda` + +error: static initializer forms a cycle involving `A` + --> $DIR/static-initializer-acyclic-issue-146787.rs:16:1 + | +LL | static A: Foo = Foo(&A); + | ^^^^^^^^^^^^^ part of this cycle + | + = note: cyclic static initializers are not supported for target `nvptx64-nvidia-cuda` + +error: aborting due to 3 previous errors + From f805d1b210b5bd1e765e07903804b7cdea1d48ae Mon Sep 17 00:00:00 2001 From: andjsrk Date: Wed, 7 Jan 2026 01:08:19 +0900 Subject: [PATCH 1645/3801] format --- tests/ui/repeat-expr/can-have-side-effects-consider-element.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs b/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs index cd385587d491..d0b5d12455dc 100644 --- a/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs +++ b/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs @@ -5,7 +5,8 @@ // Test if `Expr::can_have_side_effects` considers element of repeat expressions. fn drop_repeat_in_arm_body() { - // Built-in lint `dropping_copy_types` relies on `Expr::can_have_side_effects` (See rust-clippy#9482) + // Built-in lint `dropping_copy_types` relies on + // `Expr::can_have_side_effects` (See rust-clippy#9482) match () { () => drop([0; 1]), // No side effects From c73b64b8c518e055681ba3a35802f2f316b58988 Mon Sep 17 00:00:00 2001 From: andjsrk Date: Wed, 7 Jan 2026 02:02:26 +0900 Subject: [PATCH 1646/3801] update expected output as well --- .../repeat-expr/can-have-side-effects-consider-element.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr b/tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr index 6948d64ebcc3..70c7e8b404e0 100644 --- a/tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr +++ b/tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr @@ -1,5 +1,5 @@ warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing - --> $DIR/can-have-side-effects-consider-element.rs:11:15 + --> $DIR/can-have-side-effects-consider-element.rs:12:15 | LL | () => drop([0; 1]), // No side effects | ^^^^^------^ From d101412517a4fdbb108c193eb1cf5632c89534f3 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 6 Jan 2026 17:23:16 +0000 Subject: [PATCH 1647/3801] Cleanup some ui tests for const-traits --- tests/ui/const-generics/issues/issue-88119.rs | 3 +- .../const-generics/issues/issue-88119.stderr | 95 ------------------- .../consts/rustc-impl-const-stability.stderr | 11 --- .../ui/specialization/const_trait_impl.stderr | 59 ------------ .../derive-const-non-const-type.rs | 12 +-- .../derive-const-non-const-type.stderr | 21 ++-- .../rustc-impl-const-stability.rs | 9 +- ...fault-bound-non-const-specialized-bound.rs | 8 +- ...t-bound-non-const-specialized-bound.stderr | 8 +- .../const-traits/specialization/pass.rs} | 14 ++- .../specializing-constness-2.rs | 5 +- .../specializing-constness-2.stderr | 2 +- .../specializing-constness.rs | 0 .../specializing-constness.stderr | 0 14 files changed, 35 insertions(+), 212 deletions(-) delete mode 100644 tests/ui/const-generics/issues/issue-88119.stderr delete mode 100644 tests/ui/consts/rustc-impl-const-stability.stderr delete mode 100644 tests/ui/specialization/const_trait_impl.stderr rename tests/ui/{consts => traits/const-traits}/rustc-impl-const-stability.rs (63%) rename tests/ui/{specialization/const_trait_impl.rs => traits/const-traits/specialization/pass.rs} (70%) rename tests/ui/traits/const-traits/{ => specialization}/specializing-constness-2.rs (81%) rename tests/ui/traits/const-traits/{ => specialization}/specializing-constness-2.stderr (88%) rename tests/ui/traits/const-traits/{ => specialization}/specializing-constness.rs (100%) rename tests/ui/traits/const-traits/{ => specialization}/specializing-constness.stderr (100%) diff --git a/tests/ui/const-generics/issues/issue-88119.rs b/tests/ui/const-generics/issues/issue-88119.rs index d44b5ab985b0..fb279dd824f8 100644 --- a/tests/ui/const-generics/issues/issue-88119.rs +++ b/tests/ui/const-generics/issues/issue-88119.rs @@ -1,5 +1,4 @@ -//@ known-bug: #110395 -//@ compile-flags: -Znext-solver +//@ check-pass #![allow(incomplete_features)] #![feature(const_trait_impl, generic_const_exprs)] diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr deleted file mode 100644 index 0bdf153468bc..000000000000 --- a/tests/ui/const-generics/issues/issue-88119.stderr +++ /dev/null @@ -1,95 +0,0 @@ -error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed - --> $DIR/issue-88119.rs:4:30 - | -LL | #![feature(const_trait_impl, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = help: remove one of these features - -error[E0275]: overflow evaluating the requirement `&T: [const] ConstName` - --> $DIR/issue-88119.rs:18:49 - | -LL | impl const ConstName for &T - | ^^ - -error[E0275]: overflow evaluating the requirement `&T: ConstName` - --> $DIR/issue-88119.rs:18:49 - | -LL | impl const ConstName for &T - | ^^ - -error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:20:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `<&T as ConstName>` - --> $DIR/issue-88119.rs:20:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` - -error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:20:10 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^ - | -note: required by a bound in `<&T as ConstName>` - --> $DIR/issue-88119.rs:20:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` - -error[E0275]: overflow evaluating the requirement `&mut T: [const] ConstName` - --> $DIR/issue-88119.rs:25:49 - | -LL | impl const ConstName for &mut T - | ^^^^^^ - -error[E0275]: overflow evaluating the requirement `&mut T: ConstName` - --> $DIR/issue-88119.rs:25:49 - | -LL | impl const ConstName for &mut T - | ^^^^^^ - -error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:27:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `<&mut T as ConstName>` - --> $DIR/issue-88119.rs:27:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` - -error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:27:10 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^ - | -note: required by a bound in `<&mut T as ConstName>` - --> $DIR/issue-88119.rs:27:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` - -error[E0275]: overflow evaluating the requirement `&&mut u8: ConstName` - --> $DIR/issue-88119.rs:32:35 - | -LL | pub const ICE_1: &'static [u8] = <&&mut u8 as ConstName>::NAME_BYTES; - | ^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `&mut &u8: ConstName` - --> $DIR/issue-88119.rs:33:35 - | -LL | pub const ICE_2: &'static [u8] = <&mut &u8 as ConstName>::NAME_BYTES; - | ^^^^^^^^ - -error: aborting due to 11 previous errors - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr deleted file mode 100644 index 55c085396882..000000000000 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: const `impl` for trait `Debug` which is not `const` - --> $DIR/rustc-impl-const-stability.rs:15:12 - | -LL | impl const std::fmt::Debug for Data { - | ^^^^^^^^^^^^^^^ this trait is not `const` - | - = note: marking a trait with `const` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: aborting due to 1 previous error - diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr deleted file mode 100644 index 93ed7234e563..000000000000 --- a/tests/ui/specialization/const_trait_impl.stderr +++ /dev/null @@ -1,59 +0,0 @@ -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:33:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:39:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:45:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:39:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:33:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:45:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 6 previous errors - diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs index 0bc25ce5f650..e61ae2760aab 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs +++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs @@ -1,15 +1,15 @@ -//@ known-bug: #110395 -#![feature(derive_const)] +#![feature(const_default, derive_const)] pub struct A; -impl std::fmt::Debug for A { - fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - panic!() +impl Default for A { + fn default() -> A { + A } } -#[derive_const(Debug)] +#[derive_const(Default)] pub struct S(A); +//~^ ERROR: cannot call non-const associated function fn main() {} diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr index 93638801895d..558957985328 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr @@ -1,20 +1,13 @@ -error: const `impl` for trait `Debug` which is not `const` - --> $DIR/derive-const-non-const-type.rs:12:16 +error[E0015]: cannot call non-const associated function `::default` in constant functions + --> $DIR/derive-const-non-const-type.rs:12:14 | -LL | #[derive_const(Debug)] - | ^^^^^ this trait is not `const` - | - = note: marking a trait with `const` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error[E0015]: cannot call non-const method `Formatter::<'_>::debug_tuple_field1_finish` in constant functions - --> $DIR/derive-const-non-const-type.rs:12:16 - | -LL | #[derive_const(Debug)] - | ^^^^^ +LL | #[derive_const(Default)] + | ------- in this derive macro expansion +LL | pub struct S(A); + | ^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/traits/const-traits/rustc-impl-const-stability.rs similarity index 63% rename from tests/ui/consts/rustc-impl-const-stability.rs rename to tests/ui/traits/const-traits/rustc-impl-const-stability.rs index 93a5e8e4f458..7d30342d11ca 100644 --- a/tests/ui/consts/rustc-impl-const-stability.rs +++ b/tests/ui/traits/const-traits/rustc-impl-const-stability.rs @@ -1,5 +1,4 @@ -//@ compile-flags: -Znext-solver -//@ known-bug: #110395 +//@ check-pass #![crate_type = "lib"] #![feature(staged_api, const_trait_impl, const_default)] @@ -12,8 +11,8 @@ pub struct Data { #[stable(feature = "potato", since = "1.27.0")] #[rustc_const_unstable(feature = "data_foo", issue = "none")] -impl const std::fmt::Debug for Data { - fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - Ok(()) +impl const Default for Data { + fn default() -> Data { + Data { _data: 0xbeef } } } diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs index 5125d2580238..f771107ec068 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs +++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs @@ -1,7 +1,5 @@ // Tests that trait bounds on specializing trait impls must be `[const]` if the // same bound is present on the default impl and is `[const]` there. -//@ known-bug: #110395 -// FIXME(const_trait_impl) ^ should error #![feature(const_trait_impl)] #![feature(rustc_attrs)] @@ -23,9 +21,9 @@ where default fn bar() {} } -impl Bar for T +impl Bar for T //~ ERROR conflicting implementations of trait `Bar` where - T: Foo, //FIXME ~ ERROR missing `[const]` qualifier + T: Foo, T: Specialize, { fn bar() {} @@ -42,7 +40,7 @@ where default fn baz() {} } -impl const Baz for T //FIXME ~ ERROR conflicting implementations of trait `Baz` +impl const Baz for T //~ ERROR conflicting implementations of trait `Baz` where T: Foo, T: Specialize, diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr index 85e9fda5c2a3..ff27559c8ec6 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Bar` - --> $DIR/const-default-bound-non-const-specialized-bound.rs:26:1 + --> $DIR/const-default-bound-non-const-specialized-bound.rs:24:1 | LL | / impl const Bar for T LL | | where @@ -8,19 +8,19 @@ LL | | T: [const] Foo, ... LL | / impl Bar for T LL | | where -LL | | T: Foo, //FIXME ~ ERROR missing `[const]` qualifier +LL | | T: Foo, LL | | T: Specialize, | |__________________^ conflicting implementation error[E0119]: conflicting implementations of trait `Baz` - --> $DIR/const-default-bound-non-const-specialized-bound.rs:45:1 + --> $DIR/const-default-bound-non-const-specialized-bound.rs:43:1 | LL | / impl const Baz for T LL | | where LL | | T: [const] Foo, | |___________________- first implementation here ... -LL | / impl const Baz for T //FIXME ~ ERROR conflicting implementations of trait `Baz` +LL | / impl const Baz for T LL | | where LL | | T: Foo, LL | | T: Specialize, diff --git a/tests/ui/specialization/const_trait_impl.rs b/tests/ui/traits/const-traits/specialization/pass.rs similarity index 70% rename from tests/ui/specialization/const_trait_impl.rs rename to tests/ui/traits/const-traits/specialization/pass.rs index adfef77a15ca..0ba4e40ee30a 100644 --- a/tests/ui/specialization/const_trait_impl.rs +++ b/tests/ui/traits/const-traits/specialization/pass.rs @@ -1,8 +1,6 @@ -//@ known-bug: #110395 - -#![feature(const_trait_impl, min_specialization, rustc_attrs)] - -use std::fmt::Debug; +//@ check-pass +#![feature(const_trait_impl, const_default, min_specialization, rustc_attrs)] +#![allow(internal_features)] #[rustc_specialization_trait] pub const unsafe trait Sup { @@ -30,19 +28,19 @@ pub const trait A { fn a() -> u32; } -impl const A for T { +impl const A for T { default fn a() -> u32 { 2 } } -impl const A for T { +impl const A for T { default fn a() -> u32 { 3 } } -impl const A for T { +impl const A for T { fn a() -> u32 { T::foo() } diff --git a/tests/ui/traits/const-traits/specializing-constness-2.rs b/tests/ui/traits/const-traits/specialization/specializing-constness-2.rs similarity index 81% rename from tests/ui/traits/const-traits/specializing-constness-2.rs rename to tests/ui/traits/const-traits/specialization/specializing-constness-2.rs index 455dd111603d..78cfbe361d91 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.rs +++ b/tests/ui/traits/const-traits/specialization/specializing-constness-2.rs @@ -1,5 +1,6 @@ #![feature(const_trait_impl, min_specialization, rustc_attrs)] -//@ known-bug: #110395 +#![allow(internal_features)] + #[rustc_specialization_trait] pub const trait Sup {} @@ -23,7 +24,7 @@ impl const A for T { const fn generic() { ::a(); - //FIXME ~^ ERROR: the trait bound `T: [const] Sup` is not satisfied + //~^ ERROR: the trait bound `T: [const] A` is not satisfied } fn main() {} diff --git a/tests/ui/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specialization/specializing-constness-2.stderr similarity index 88% rename from tests/ui/traits/const-traits/specializing-constness-2.stderr rename to tests/ui/traits/const-traits/specialization/specializing-constness-2.stderr index bd6ffa544d0e..bb1c9ac78531 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.stderr +++ b/tests/ui/traits/const-traits/specialization/specializing-constness-2.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `T: [const] A` is not satisfied - --> $DIR/specializing-constness-2.rs:25:6 + --> $DIR/specializing-constness-2.rs:26:6 | LL | ::a(); | ^ diff --git a/tests/ui/traits/const-traits/specializing-constness.rs b/tests/ui/traits/const-traits/specialization/specializing-constness.rs similarity index 100% rename from tests/ui/traits/const-traits/specializing-constness.rs rename to tests/ui/traits/const-traits/specialization/specializing-constness.rs diff --git a/tests/ui/traits/const-traits/specializing-constness.stderr b/tests/ui/traits/const-traits/specialization/specializing-constness.stderr similarity index 100% rename from tests/ui/traits/const-traits/specializing-constness.stderr rename to tests/ui/traits/const-traits/specialization/specializing-constness.stderr From 064b95ed04dca45f583c96001ef3b9eaa953fc3a Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 27 Dec 2025 22:37:19 +0000 Subject: [PATCH 1648/3801] Allow `expect` on `impl` for `derive_ord_xor_partial_ord` --- .../src/derive/derive_ord_xor_partial_ord.rs | 9 ++++++--- clippy_lints/src/derive/mod.rs | 2 +- tests/ui/derive_ord_xor_partial_ord.rs | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs b/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs index 2bd5e2cbfb1a..316d800a70c9 100644 --- a/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs +++ b/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs @@ -1,15 +1,16 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; +use clippy_utils::fulfill_or_allowed; use rustc_hir::{self as hir, HirId}; use rustc_lint::LateContext; use rustc_middle::ty::Ty; -use rustc_span::{Span, sym}; +use rustc_span::sym; use super::DERIVE_ORD_XOR_PARTIAL_ORD; /// Implementation of the `DERIVE_ORD_XOR_PARTIAL_ORD` lint. pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, - span: Span, + item: &hir::Item<'_>, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>, adt_hir_id: HirId, @@ -19,6 +20,8 @@ pub(super) fn check<'tcx>( && let Some(partial_ord_trait_def_id) = cx.tcx.lang_items().partial_ord_trait() && let Some(def_id) = &trait_ref.trait_def_id() && *def_id == ord_trait_def_id + && let item_hir_id = cx.tcx.local_def_id_to_hir_id(item.owner_id) + && !fulfill_or_allowed(cx, DERIVE_ORD_XOR_PARTIAL_ORD, [adt_hir_id]) { // Look for the PartialOrd implementations for `ty` cx.tcx.for_each_relevant_impl(partial_ord_trait_def_id, ty, |impl_id| { @@ -39,7 +42,7 @@ pub(super) fn check<'tcx>( "you are deriving `Ord` but have implemented `PartialOrd` explicitly" }; - span_lint_hir_and_then(cx, DERIVE_ORD_XOR_PARTIAL_ORD, adt_hir_id, span, mess, |diag| { + span_lint_hir_and_then(cx, DERIVE_ORD_XOR_PARTIAL_ORD, item_hir_id, item.span, mess, |diag| { if let Some(local_def_id) = impl_id.as_local() { let hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id); diag.span_note(cx.tcx.hir_span(hir_id), "`PartialOrd` implemented here"); diff --git a/clippy_lints/src/derive/mod.rs b/clippy_lints/src/derive/mod.rs index eafe7c4bb9f2..86614201c406 100644 --- a/clippy_lints/src/derive/mod.rs +++ b/clippy_lints/src/derive/mod.rs @@ -208,7 +208,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive { let is_automatically_derived = cx.tcx.is_automatically_derived(item.owner_id.to_def_id()); derived_hash_with_manual_eq::check(cx, item.span, trait_ref, ty, adt_hir_id, is_automatically_derived); - derive_ord_xor_partial_ord::check(cx, item.span, trait_ref, ty, adt_hir_id, is_automatically_derived); + derive_ord_xor_partial_ord::check(cx, item, trait_ref, ty, adt_hir_id, is_automatically_derived); if is_automatically_derived { unsafe_derive_deserialize::check(cx, item, trait_ref, ty, adt_hir_id); diff --git a/tests/ui/derive_ord_xor_partial_ord.rs b/tests/ui/derive_ord_xor_partial_ord.rs index b4bb24b0d2fe..386ab39401c5 100644 --- a/tests/ui/derive_ord_xor_partial_ord.rs +++ b/tests/ui/derive_ord_xor_partial_ord.rs @@ -91,3 +91,17 @@ mod issue15708 { } } } + +mod issue16298 { + #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] + struct Normalized(S); + + impl Eq for Normalized {} + + #[expect(clippy::derive_ord_xor_partial_ord)] + impl Ord for Normalized { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.partial_cmp(other).unwrap() + } + } +} From a978fdcdace3c9bee4d11e03ee3ea2be5792025c Mon Sep 17 00:00:00 2001 From: Hendrik Lind Date: Tue, 6 Jan 2026 20:49:14 +0100 Subject: [PATCH 1649/3801] fix: use crates where ADT was defined in deref_chain of trait_applicable_items --- .../ide-completion/src/tests/flyimport.rs | 48 +++++++++++++++++++ .../ide-db/src/imports/import_assets.rs | 14 +++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index 797df3f163da..d7db896679df 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -1976,3 +1976,51 @@ fn main() { "#]], ); } + +#[test] +fn trait_method_import_across_multiple_crates() { + let fixture = r#" + //- /lib.rs crate:test-trait + pub trait TestTrait { + fn test_function(&self) -> u32; + } + + //- /lib.rs crate:test-implementation deps:test-trait + pub struct TestStruct(pub usize); + + impl test_trait::TestTrait for TestStruct { + fn test_function(&self) -> u32 { + 1 + } + } + + //- /main.rs crate:main deps:test-implementation,test-trait + use test_implementation::TestStruct; + + fn main() { + let test = TestStruct(42); + test.test_f$0 + } + "#; + + check( + fixture, + expect![[r#" + me test_function() (use test_trait::TestTrait) fn(&self) -> u32 + "#]], + ); + + check_edit( + "test_function", + fixture, + r#" +use test_implementation::TestStruct; +use test_trait::TestTrait; + +fn main() { + let test = TestStruct(42); + test.test_function()$0 +} +"#, + ); +} diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 90e3bb61f44d..35579eb2590d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -600,7 +600,19 @@ fn trait_applicable_items<'db>( } deref_chain .into_iter() - .filter_map(|ty| Some((ty.krate(db).into(), ty.fingerprint_for_trait_impl()?))) + .flat_map(|ty| { + let fingerprint = ty.fingerprint_for_trait_impl()?; + let mut crates = vec![]; + + if let Some(adt) = ty.as_adt() { + // Push crate where ADT was defined + crates.push((adt.krate(db).into(), fingerprint)); + } + // Always include environment crate + crates.push((ty.krate(db).into(), fingerprint)); + Some(crates) + }) + .flatten() .unique() .collect::>() }; From 1f207edc5a646a6c4d98f929423974bbe3a1cb5e Mon Sep 17 00:00:00 2001 From: keir Date: Wed, 17 Dec 2025 19:04:50 +0530 Subject: [PATCH 1650/3801] fix(useless_conversion): stop adjustments when target type is reached --- clippy_lints/src/useless_conversion.rs | 14 ++- tests/ui/useless_conversion.fixed | 10 ++ tests/ui/useless_conversion.rs | 10 ++ tests/ui/useless_conversion.stderr | 135 ++++++++++++++----------- 4 files changed, 109 insertions(+), 60 deletions(-) diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index c06313d1a4c4..423301edfe83 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -456,13 +456,25 @@ fn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>) fn adjustments(cx: &LateContext<'_>, expr: &Expr<'_>) -> String { let mut prefix = String::new(); - for adj in cx.typeck_results().expr_adjustments(expr) { + + let adjustments = cx.typeck_results().expr_adjustments(expr); + + let [.., last] = adjustments else { return prefix }; + let target = last.target; + + for adj in adjustments { match adj.kind { Adjust::Deref(_) => prefix = format!("*{prefix}"), Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })) => prefix = format!("&mut {prefix}"), Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)) => prefix = format!("&{prefix}"), _ => {}, } + + // Stop once we reach the final target type. + // This prevents over-adjusting (e.g. suggesting &**y instead of *y). + if adj.target == target { + break; + } } prefix } diff --git a/tests/ui/useless_conversion.fixed b/tests/ui/useless_conversion.fixed index adf5e58d9a1a..4832e922fa8e 100644 --- a/tests/ui/useless_conversion.fixed +++ b/tests/ui/useless_conversion.fixed @@ -1,4 +1,5 @@ #![deny(clippy::useless_conversion)] +#![allow(clippy::into_iter_on_ref)] #![allow(clippy::needless_ifs, clippy::unnecessary_wraps, unused)] // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint #![allow(static_mut_refs)] @@ -131,6 +132,15 @@ fn main() { dont_lint_into_iter_on_copy_iter(); dont_lint_into_iter_on_static_copy_iter(); + { + // triggers the IntoIterator trait + fn consume(_: impl IntoIterator) {} + + // Should suggest `*items` instead of `&**items` + let items = &&[1, 2, 3]; + consume(*items); //~ useless_conversion + } + let _: String = "foo".into(); let _: String = From::from("foo"); let _ = String::from("foo"); diff --git a/tests/ui/useless_conversion.rs b/tests/ui/useless_conversion.rs index d95fe49e2e2b..6ef1f93a5606 100644 --- a/tests/ui/useless_conversion.rs +++ b/tests/ui/useless_conversion.rs @@ -1,4 +1,5 @@ #![deny(clippy::useless_conversion)] +#![allow(clippy::into_iter_on_ref)] #![allow(clippy::needless_ifs, clippy::unnecessary_wraps, unused)] // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint #![allow(static_mut_refs)] @@ -131,6 +132,15 @@ fn main() { dont_lint_into_iter_on_copy_iter(); dont_lint_into_iter_on_static_copy_iter(); + { + // triggers the IntoIterator trait + fn consume(_: impl IntoIterator) {} + + // Should suggest `*items` instead of `&**items` + let items = &&[1, 2, 3]; + consume(items.into_iter()); //~ useless_conversion + } + let _: String = "foo".into(); let _: String = From::from("foo"); let _ = String::from("foo"); diff --git a/tests/ui/useless_conversion.stderr b/tests/ui/useless_conversion.stderr index 052c664f6f2e..d28b7a5cbfb6 100644 --- a/tests/ui/useless_conversion.stderr +++ b/tests/ui/useless_conversion.stderr @@ -1,5 +1,5 @@ error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion.rs:9:13 + --> tests/ui/useless_conversion.rs:10:13 | LL | let _ = T::from(val); | ^^^^^^^^^^^^ help: consider removing `T::from()`: `val` @@ -11,115 +11,132 @@ LL | #![deny(clippy::useless_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion.rs:11:5 + --> tests/ui/useless_conversion.rs:12:5 | LL | val.into() | ^^^^^^^^^^ help: consider removing `.into()`: `val` error: useless conversion to the same type: `i32` - --> tests/ui/useless_conversion.rs:24:22 + --> tests/ui/useless_conversion.rs:25:22 | LL | let _: i32 = 0i32.into(); | ^^^^^^^^^^^ help: consider removing `.into()`: `0i32` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:55:22 + --> tests/ui/useless_conversion.rs:56:22 | LL | if Some("ok") == lines.into_iter().next() {} | ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:61:21 + --> tests/ui/useless_conversion.rs:62:21 | LL | let mut lines = text.lines().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:68:22 + --> tests/ui/useless_conversion.rs:69:22 | LL | if Some("ok") == text.lines().into_iter().next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:75:13 + --> tests/ui/useless_conversion.rs:76:13 | LL | let _ = NUMBERS.into_iter().next(); | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:81:17 + --> tests/ui/useless_conversion.rs:82:17 | LL | let mut n = NUMBERS.into_iter(); | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` +error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` + --> tests/ui/useless_conversion.rs:141:17 + | +LL | consume(items.into_iter()); + | ^^^^^^^^^^^^^^^^^ + | +note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` + --> tests/ui/useless_conversion.rs:137:28 + | +LL | fn consume(_: impl IntoIterator) {} + | ^^^^^^^^^^^^ +help: consider removing the `.into_iter()` + | +LL - consume(items.into_iter()); +LL + consume(*items); + | + error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:144:21 + --> tests/ui/useless_conversion.rs:154:21 | LL | let _: String = "foo".to_string().into(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:146:21 + --> tests/ui/useless_conversion.rs:156:21 | LL | let _: String = From::from("foo".to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:148:13 + --> tests/ui/useless_conversion.rs:158:13 | LL | let _ = String::from("foo".to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:150:13 + --> tests/ui/useless_conversion.rs:160:13 | LL | let _ = String::from(format!("A: {:04}", 123)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:152:13 + --> tests/ui/useless_conversion.rs:162:13 | LL | let _ = "".lines().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()` error: useless conversion to the same type: `std::vec::IntoIter` - --> tests/ui/useless_conversion.rs:154:13 + --> tests/ui/useless_conversion.rs:164:13 | LL | let _ = vec![1, 2, 3].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:156:21 + --> tests/ui/useless_conversion.rs:166:21 | LL | let _: String = format!("Hello {}", "world").into(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")` error: useless conversion to the same type: `i32` - --> tests/ui/useless_conversion.rs:162:13 + --> tests/ui/useless_conversion.rs:172:13 | LL | let _ = i32::from(a + b) * 3; | ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)` error: useless conversion to the same type: `Foo<'a'>` - --> tests/ui/useless_conversion.rs:169:23 + --> tests/ui/useless_conversion.rs:179:23 | LL | let _: Foo<'a'> = s2.into(); | ^^^^^^^^^ help: consider removing `.into()`: `s2` error: useless conversion to the same type: `Foo<'a'>` - --> tests/ui/useless_conversion.rs:172:13 + --> tests/ui/useless_conversion.rs:182:13 | LL | let _ = Foo::<'a'>::from(s3); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3` error: useless conversion to the same type: `std::vec::IntoIter>` - --> tests/ui/useless_conversion.rs:175:13 + --> tests/ui/useless_conversion.rs:185:13 | LL | let _ = vec![s4, s4, s4].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:208:7 + --> tests/ui/useless_conversion.rs:218:7 | LL | b(vec![1, 2].into_iter()); | ^^^^^^^^^^------------ @@ -127,13 +144,13 @@ LL | b(vec![1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:198:13 + --> tests/ui/useless_conversion.rs:208:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:210:7 + --> tests/ui/useless_conversion.rs:220:7 | LL | c(vec![1, 2].into_iter()); | ^^^^^^^^^^------------ @@ -141,13 +158,13 @@ LL | c(vec![1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:199:18 + --> tests/ui/useless_conversion.rs:209:18 | LL | fn c(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:212:7 + --> tests/ui/useless_conversion.rs:222:7 | LL | d(vec![1, 2].into_iter()); | ^^^^^^^^^^------------ @@ -155,13 +172,13 @@ LL | d(vec![1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:202:12 + --> tests/ui/useless_conversion.rs:212:12 | LL | T: IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:216:7 + --> tests/ui/useless_conversion.rs:226:7 | LL | b(vec![1, 2].into_iter().into_iter()); | ^^^^^^^^^^------------------------ @@ -169,13 +186,13 @@ LL | b(vec![1, 2].into_iter().into_iter()); | help: consider removing the `.into_iter()`s | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:198:13 + --> tests/ui/useless_conversion.rs:208:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:218:7 + --> tests/ui/useless_conversion.rs:228:7 | LL | b(vec![1, 2].into_iter().into_iter().into_iter()); | ^^^^^^^^^^------------------------------------ @@ -183,13 +200,13 @@ LL | b(vec![1, 2].into_iter().into_iter().into_iter()); | help: consider removing the `.into_iter()`s | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:198:13 + --> tests/ui/useless_conversion.rs:208:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:265:24 + --> tests/ui/useless_conversion.rs:275:24 | LL | foo2::([1, 2, 3].into_iter()); | ^^^^^^^^^------------ @@ -197,13 +214,13 @@ LL | foo2::([1, 2, 3].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:244:12 + --> tests/ui/useless_conversion.rs:254:12 | LL | I: IntoIterator + Helper, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:274:14 + --> tests/ui/useless_conversion.rs:284:14 | LL | foo3([1, 2, 3].into_iter()); | ^^^^^^^^^------------ @@ -211,13 +228,13 @@ LL | foo3([1, 2, 3].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:253:12 + --> tests/ui/useless_conversion.rs:263:12 | LL | I: IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:284:16 + --> tests/ui/useless_conversion.rs:294:16 | LL | S1.foo([1, 2].into_iter()); | ^^^^^^------------ @@ -225,13 +242,13 @@ LL | S1.foo([1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:281:27 + --> tests/ui/useless_conversion.rs:291:27 | LL | pub fn foo(&self, _: I) {} | ^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:304:44 + --> tests/ui/useless_conversion.rs:314:44 | LL | v0.into_iter().interleave_shortest(v1.into_iter()); | ^^------------ @@ -239,67 +256,67 @@ LL | v0.into_iter().interleave_shortest(v1.into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:291:20 + --> tests/ui/useless_conversion.rs:301:20 | LL | J: IntoIterator, | ^^^^^^^^^^^^ error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:332:58 + --> tests/ui/useless_conversion.rs:342:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map(Into::into); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `std::io::Error` - --> tests/ui/useless_conversion.rs:335:58 + --> tests/ui/useless_conversion.rs:345:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map_err(Into::into); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:338:58 + --> tests/ui/useless_conversion.rs:348:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map(From::from); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `std::io::Error` - --> tests/ui/useless_conversion.rs:341:58 + --> tests/ui/useless_conversion.rs:351:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:345:31 + --> tests/ui/useless_conversion.rs:355:31 | LL | let _: ControlFlow<()> = c.map_break(Into::into); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:349:31 + --> tests/ui/useless_conversion.rs:359:31 | LL | let _: ControlFlow<()> = c.map_continue(Into::into); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `u32` - --> tests/ui/useless_conversion.rs:363:41 + --> tests/ui/useless_conversion.rs:373:41 | LL | let _: Vec = [1u32].into_iter().map(Into::into).collect(); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion.rs:374:18 + --> tests/ui/useless_conversion.rs:384:18 | LL | x.into_iter().map(Into::into).collect() | ^^^^^^^^^^^^^^^^ help: consider removing error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:390:29 + --> tests/ui/useless_conversion.rs:400:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -310,13 +327,13 @@ LL + takes_into_iter(&self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:398:29 + --> tests/ui/useless_conversion.rs:408:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -327,13 +344,13 @@ LL + takes_into_iter(&mut self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:407:29 + --> tests/ui/useless_conversion.rs:417:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -344,13 +361,13 @@ LL + takes_into_iter(*self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:416:29 + --> tests/ui/useless_conversion.rs:426:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -361,13 +378,13 @@ LL + takes_into_iter(&*self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:425:29 + --> tests/ui/useless_conversion.rs:435:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -378,22 +395,22 @@ LL + takes_into_iter(&mut *self.my_field); | error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:440:5 + --> tests/ui/useless_conversion.rs:450:5 | LL | R.into_iter().for_each(|_x| {}); | ^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `R` error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:442:13 + --> tests/ui/useless_conversion.rs:452:13 | LL | let _ = R.into_iter().map(|_x| 0); | ^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `R` error: useless conversion to the same type: `std::slice::Iter<'_, i32>` - --> tests/ui/useless_conversion.rs:453:14 + --> tests/ui/useless_conversion.rs:463:14 | LL | for _ in mac!(iter [1, 2]).into_iter() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `mac!(iter [1, 2])` -error: aborting due to 44 previous errors +error: aborting due to 45 previous errors From af69f157129e154f050a224ba384703e57115032 Mon Sep 17 00:00:00 2001 From: Orson Peters Date: Tue, 6 Jan 2026 22:09:11 +0100 Subject: [PATCH 1651/3801] Add AtomicPtr::null --- library/core/src/sync/atomic.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 1eae06ebd33e..c675fd1381d8 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1550,6 +1550,23 @@ impl AtomicPtr { unsafe { &*ptr.cast() } } + /// Creates a new `AtomicPtr` initialized with a null pointer. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let atomic_ptr = AtomicPtr::<()>::null(); + /// assert!(atomic_ptr.load(Ordering::Relaxed).is_null()); + /// ``` + #[inline] + #[must_use] + #[unstable(feature = "atomic_ptr_null", issue = "150733")] + pub const fn null() -> AtomicPtr { + AtomicPtr::new(crate::ptr::null_mut()) + } + /// Returns a mutable reference to the underlying pointer. /// /// This is safe because the mutable reference guarantees that no other threads are From 0dfff23114662255119e33030de7ccc289a385b0 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Tue, 6 Jan 2026 21:43:21 +0000 Subject: [PATCH 1652/3801] address reviews --- src/tools/tidy/src/extra_checks/mod.rs | 3 +- src/tools/tidy/src/extra_checks/tests.rs | 46 ++++++++++++------------ 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index a1d9ad436885..1c81a485608a 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -121,12 +121,12 @@ fn check_impl( .collect(), None => vec![], }; + lint_args.retain(|ck| ck.is_non_if_installed_or_matches(root_path, outdir)); if lint_args.iter().any(|ck| ck.auto) { crate::files_modified_batch_filter(ci_info, &mut lint_args, |ck, path| { ck.is_non_auto_or_matches(path) }); } - lint_args.retain(|ck| ck.is_non_if_installed_or_matches(root_path, outdir)); macro_rules! extra_check { ($lang:ident, $kind:ident) => { @@ -963,7 +963,6 @@ impl FromStr for ExtraCheckArg { }; if_installed = true; first = part; - continue; } _ => break, } diff --git a/src/tools/tidy/src/extra_checks/tests.rs b/src/tools/tidy/src/extra_checks/tests.rs index 62501803b255..5d274069a80c 100644 --- a/src/tools/tidy/src/extra_checks/tests.rs +++ b/src/tools/tidy/src/extra_checks/tests.rs @@ -7,80 +7,80 @@ fn test_extra_check_arg_from_str_ok() { let test_cases = [ ( "auto:if-installed:spellcheck", - Ok(ExtraCheckArg { + ExtraCheckArg { auto: true, if_installed: true, lang: ExtraCheckLang::Spellcheck, kind: None, - }), + }, ), ( "if-installed:auto:spellcheck", - Ok(ExtraCheckArg { + ExtraCheckArg { auto: true, if_installed: true, lang: ExtraCheckLang::Spellcheck, kind: None, - }), + }, ), ( "auto:spellcheck", - Ok(ExtraCheckArg { + ExtraCheckArg { auto: true, if_installed: false, lang: ExtraCheckLang::Spellcheck, kind: None, - }), + }, ), ( "if-installed:spellcheck", - Ok(ExtraCheckArg { + ExtraCheckArg { auto: false, if_installed: true, lang: ExtraCheckLang::Spellcheck, kind: None, - }), + }, ), ( "spellcheck", - Ok(ExtraCheckArg { + ExtraCheckArg { auto: false, if_installed: false, lang: ExtraCheckLang::Spellcheck, kind: None, - }), + }, ), ( "js:lint", - Ok(ExtraCheckArg { + ExtraCheckArg { auto: false, if_installed: false, lang: ExtraCheckLang::Js, kind: Some(ExtraCheckKind::Lint), - }), + }, ), ]; for (s, expected) in test_cases { - assert_eq!(ExtraCheckArg::from_str(s), expected); + assert_eq!(ExtraCheckArg::from_str(s), Ok(expected)); } } #[test] fn test_extra_check_arg_from_str_err() { let test_cases = [ - ("some:spellcheck", Err(ExtraCheckParseError::UnknownLang("some".to_string()))), - ("spellcheck:some", Err(ExtraCheckParseError::UnknownKind("some".to_string()))), - ("spellcheck:lint", Err(ExtraCheckParseError::UnsupportedKindForLang)), - ("auto:spellcheck:some", Err(ExtraCheckParseError::UnknownKind("some".to_string()))), - ("auto:js:lint:some", Err(ExtraCheckParseError::TooManyParts)), - ("some", Err(ExtraCheckParseError::UnknownLang("some".to_string()))), - ("auto", Err(ExtraCheckParseError::AutoRequiresLang)), - ("if-installed", Err(ExtraCheckParseError::IfInstalledRequiresLang)), - ("", Err(ExtraCheckParseError::Empty)), + ("some:spellcheck", ExtraCheckParseError::UnknownLang("some".to_string())), + ("spellcheck:some", ExtraCheckParseError::UnknownKind("some".to_string())), + ("spellcheck:lint", ExtraCheckParseError::UnsupportedKindForLang), + ("auto:spellcheck:some", ExtraCheckParseError::UnknownKind("some".to_string())), + ("auto:js:lint:some", ExtraCheckParseError::TooManyParts), + ("some", ExtraCheckParseError::UnknownLang("some".to_string())), + ("auto", ExtraCheckParseError::AutoRequiresLang), + ("if-installed", ExtraCheckParseError::IfInstalledRequiresLang), + ("", ExtraCheckParseError::Empty), ]; for (s, expected) in test_cases { - assert_eq!(ExtraCheckArg::from_str(s), expected); + assert_eq!(ExtraCheckArg::from_str(s), Err(expected)); } } From bd0d0f707e10fe9ee278c53c58f5cd7bce7f2bda Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 6 Jan 2026 23:02:48 +0100 Subject: [PATCH 1653/3801] Factorize triagebot float parsing mentions with a glob matching --- triagebot.toml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index fbb2bac2267b..2d3757d241f5 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1059,14 +1059,10 @@ gets adapted for the changes, if necessary. """ cc = ["@rust-lang/miri", "@RalfJung", "@oli-obk", "@lcnr"] -[mentions."library/core/src/num/dec2flt"] +[mentions."library/core/src/num/{dec2flt,flt2dec}"] message = "Some changes occurred in float parsing" cc = ["@tgross35"] -[mentions."library/core/src/num/flt2dec"] -message = "Some changes occurred in float printing" -cc = ["@tgross35"] - [mentions."library/core/src/fmt/num.rs"] message = "Some changes occurred in integer formatting" cc = ["@tgross35"] From fff9c623bfc75bce9f9e5c64ed67d9b04ea655c1 Mon Sep 17 00:00:00 2001 From: Orson Peters Date: Tue, 6 Jan 2026 23:38:31 +0100 Subject: [PATCH 1654/3801] Add feature to doc example --- library/core/src/sync/atomic.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index c675fd1381d8..22f46ec385ce 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1555,6 +1555,7 @@ impl AtomicPtr { /// # Examples /// /// ``` + /// #![feature(atomic_ptr_null)] /// use std::sync::atomic::{AtomicPtr, Ordering}; /// /// let atomic_ptr = AtomicPtr::<()>::null(); From af76a2456d1ce3ff200215e3593c10090ddfa725 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sun, 4 Jan 2026 10:36:36 +0800 Subject: [PATCH 1655/3801] MGCA: Support tuple expressions as direct const arguments --- compiler/rustc_ast_lowering/src/lib.rs | 18 +++++ compiler/rustc_hir/src/hir.rs | 2 + compiler/rustc_hir/src/intravisit.rs | 4 ++ compiler/rustc_hir_analysis/src/collect.rs | 9 +-- .../src/hir_ty_lowering/mod.rs | 68 ++++++++++++++----- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 10 +++ .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 +- .../rustc_hir_typeck/src/method/confirm.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + compiler/rustc_resolve/src/def_collector.rs | 4 +- src/librustdoc/clean/mod.rs | 7 +- .../doesnt_unify_evaluatable.stderr | 4 +- .../mgca/adt_expr_arg_tuple_expr_complex.rs | 20 ++++++ .../adt_expr_arg_tuple_expr_complex.stderr | 26 +++++++ .../mgca/adt_expr_arg_tuple_expr_simple.rs | 22 ++++++ ...ce-hir-wf-check-anon-const-issue-122989.rs | 1 - ...ir-wf-check-anon-const-issue-122989.stderr | 26 +------ 18 files changed, 177 insertions(+), 53 deletions(-) create mode 100644 tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.rs create mode 100644 tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr create mode 100644 tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e11e24c0263f..5c65aa192b7e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2427,6 +2427,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { kind: hir::ConstArgKind::TupleCall(qpath, lowered_args), } } + ExprKind::Tup(exprs) => { + let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| { + let expr = if let ExprKind::ConstBlock(anon_const) = &expr.kind { + let def_id = self.local_def_id(anon_const.id); + let def_kind = self.tcx.def_kind(def_id); + assert_eq!(DefKind::AnonConst, def_kind); + + self.lower_anon_const_to_const_arg(anon_const) + } else { + self.lower_expr_to_const_arg_direct(&expr) + }; + + &*self.arena.alloc(expr) + })); + + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Tup(expr.span, exprs) } + } ExprKind::Path(qself, path) => { let qpath = self.lower_qpath( expr.id, @@ -2495,6 +2512,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | ExprKind::Path(..) | ExprKind::Struct(..) | ExprKind::Call(..) + | ExprKind::Tup(..) ) { return self.lower_expr_to_const_arg_direct(expr); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e13782282891..5c3f0e5ccd31 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -497,6 +497,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> { pub fn span(&self) -> Span { match self.kind { + ConstArgKind::Tup(span, ..) => span, ConstArgKind::Struct(path, _) => path.span(), ConstArgKind::Path(path) => path.span(), ConstArgKind::TupleCall(path, _) => path.span(), @@ -511,6 +512,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> { #[derive(Clone, Copy, Debug, HashStable_Generic)] #[repr(u8, C)] pub enum ConstArgKind<'hir, Unambig = ()> { + Tup(Span, &'hir [&'hir ConstArg<'hir, Unambig>]), /// **Note:** Currently this is only used for bare const params /// (`N` where `fn foo(...)`), /// not paths to any const (`N` where `const N: usize = ...`). diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 853e7db0757a..576f74b8b02b 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1081,6 +1081,10 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( let ConstArg { hir_id, kind } = const_arg; try_visit!(visitor.visit_id(*hir_id)); match kind { + ConstArgKind::Tup(_, exprs) => { + walk_list!(visitor, visit_const_arg, *exprs); + V::Result::output() + } ConstArgKind::Struct(qpath, field_exprs) => { try_visit!(visitor.visit_qpath(qpath, *hir_id, qpath.span())); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 9343bcd27a33..9d4cb6d7684b 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1493,9 +1493,10 @@ fn const_param_default<'tcx>( }; let icx = ItemCtxt::new(tcx, def_id); let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); - let ct = icx - .lowerer() - .lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id(), identity_args)); + let ct = icx.lowerer().lower_const_arg( + default_ct, + FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args), + ); ty::EarlyBinder::bind(ct) } @@ -1553,7 +1554,7 @@ fn const_of_item<'tcx>( let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let ct = icx .lowerer() - .lower_const_arg(ct_arg, FeedConstTy::Param(def_id.to_def_id(), identity_args)); + .lower_const_arg(ct_arg, FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args)); if let Err(e) = icx.check_tainted_by_errors() && !ct.references_error() { 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 a22729fd287e..ad037c195d55 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -259,17 +259,26 @@ impl AssocItemQSelf { /// Use this enum with `::lower_const_arg` to instruct it with the /// desired behavior. #[derive(Debug, Clone, Copy)] -pub enum FeedConstTy<'a, 'tcx> { - /// Feed the type. - /// +pub enum FeedConstTy<'tcx> { + /// Feed the type to the (anno) const arg. + WithTy(Ty<'tcx>), + /// Don't feed the type. + No, +} + +impl<'tcx> FeedConstTy<'tcx> { /// The `DefId` belongs to the const param that we are supplying /// this (anon) const arg to. /// /// The list of generic args is used to instantiate the parameters /// used by the type of the const param specified by `DefId`. - Param(DefId, &'a [ty::GenericArg<'tcx>]), - /// Don't feed the type. - No, + pub fn with_type_of( + tcx: TyCtxt<'tcx>, + def_id: DefId, + generic_args: &[ty::GenericArg<'tcx>], + ) -> Self { + Self::WithTy(tcx.type_of(def_id).instantiate(tcx, generic_args)) + } } #[derive(Debug, Clone, Copy)] @@ -723,7 +732,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Ambig portions of `ConstArg` are handled in the match arm below .lower_const_arg( ct.as_unambig_ct(), - FeedConstTy::Param(param.def_id, preceding_args), + FeedConstTy::with_type_of(tcx, param.def_id, preceding_args), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { @@ -2303,15 +2312,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { pub fn lower_const_arg( &self, const_arg: &hir::ConstArg<'tcx>, - feed: FeedConstTy<'_, 'tcx>, + feed: FeedConstTy<'tcx>, ) -> Const<'tcx> { let tcx = self.tcx(); - if let FeedConstTy::Param(param_def_id, args) = feed + if let FeedConstTy::WithTy(anon_const_type) = feed && let hir::ConstArgKind::Anon(anon) = &const_arg.kind { - let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args); - // FIXME(generic_const_parameter_types): Ideally we remove these errors below when // we have the ability to intermix typeck of anon const const args with the parent // bodies typeck. @@ -2352,14 +2359,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return ty::Const::new_error(tcx, e); } - tcx.feed_anon_const_type( - anon.def_id, - ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)), - ); + tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(anon_const_type)); } let hir_id = const_arg.hir_id; match const_arg.kind { + hir::ConstArgKind::Tup(span, exprs) => self.lower_const_arg_tup(exprs, feed, span), hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => { debug!(?maybe_qself, ?path); let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself)); @@ -2464,7 +2469,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .zip(args) .map(|(field_def, arg)| { - self.lower_const_arg(arg, FeedConstTy::Param(field_def.did, adt_args)) + self.lower_const_arg(arg, FeedConstTy::with_type_of(tcx, field_def.did, adt_args)) }) .collect::>(); @@ -2480,6 +2485,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::Const::new_value(tcx, valtree, adt_ty) } + fn lower_const_arg_tup( + &self, + exprs: &'tcx [&'tcx hir::ConstArg<'tcx>], + feed: FeedConstTy<'tcx>, + span: Span, + ) -> Const<'tcx> { + let tcx = self.tcx(); + + let FeedConstTy::WithTy(ty) = feed else { + return Const::new_error_with_message(tcx, span, "unsupported const tuple"); + }; + + let ty::Tuple(tys) = ty.kind() else { + return Const::new_error_with_message(tcx, span, "const tuple must have a tuple type"); + }; + + let exprs = exprs + .iter() + .zip(tys.iter()) + .map(|(expr, ty)| self.lower_const_arg(expr, FeedConstTy::WithTy(ty))) + .collect::>(); + + let valtree = ty::ValTree::from_branches(tcx, exprs); + ty::Const::new_value(tcx, valtree, ty) + } + fn lower_const_arg_struct( &self, hir_id: HirId, @@ -2558,7 +2589,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return ty::Const::new_error(tcx, e); } - self.lower_const_arg(expr.expr, FeedConstTy::Param(field_def.did, adt_args)) + self.lower_const_arg( + expr.expr, + FeedConstTy::with_type_of(tcx, field_def.did, adt_args), + ) } None => { let e = tcx.dcx().span_err( diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 65f6a11e8e9b..7296ba6f964a 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -301,7 +301,7 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { pub fn lower_const_arg_for_rustdoc<'tcx>( tcx: TyCtxt<'tcx>, hir_ct: &hir::ConstArg<'tcx>, - feed: FeedConstTy<'_, 'tcx>, + feed: FeedConstTy<'tcx>, ) -> Const<'tcx> { let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id); collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 932e78958345..d360a18676ff 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1141,6 +1141,16 @@ impl<'a> State<'a> { fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) { match &const_arg.kind { + ConstArgKind::Tup(_, exprs) => { + self.popen(); + self.commasep_cmnt( + Inconsistent, + exprs, + |s, arg| s.print_const_arg(arg), + |arg| arg.span(), + ); + self.pclose(); + } ConstArgKind::Struct(qpath, fields) => self.print_const_struct(qpath, fields), ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args), ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 339e77ac6edd..a66ff2a23c25 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -525,7 +525,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn lower_const_arg( &self, const_arg: &'tcx hir::ConstArg<'tcx>, - feed: FeedConstTy<'_, 'tcx>, + feed: FeedConstTy<'tcx>, ) -> ty::Const<'tcx> { let ct = self.lowerer().lower_const_arg(const_arg, feed); self.register_wf_obligation( @@ -1228,7 +1228,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Ambiguous parts of `ConstArg` are handled in the match arms below .lower_const_arg( ct.as_unambig_ct(), - FeedConstTy::Param(param.def_id, preceding_args), + FeedConstTy::with_type_of(self.fcx.tcx, param.def_id, preceding_args), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index e81537008bb5..aab4e3985555 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -447,7 +447,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // We handle the ambig portions of `ConstArg` in the match arms below .lower_const_arg( ct.as_unambig_ct(), - FeedConstTy::Param(param.def_id, preceding_args), + FeedConstTy::with_type_of(self.cfcx.tcx, param.def_id, preceding_args), ) .into(), (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d79ab9eaf759..d0e8bc50c495 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1442,6 +1442,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ConstArgKind::Error(..) | hir::ConstArgKind::Struct(..) | hir::ConstArgKind::TupleCall(..) + | hir::ConstArgKind::Tup(..) | hir::ConstArgKind::Path(..) | hir::ConstArgKind::Infer(..) => true, hir::ConstArgKind::Anon(..) => false, diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index f7b85453448c..b392b7747b55 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -419,7 +419,9 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // Avoid overwriting `const_arg_context` as we may want to treat const blocks // as being anon consts if we are inside a const argument. - ExprKind::Struct(_) | ExprKind::Call(..) => return visit::walk_expr(self, expr), + ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) => { + return visit::walk_expr(self, expr); + } // FIXME(mgca): we may want to handle block labels in some manner ExprKind::Block(block, _) if let [stmt] = block.stmts.as_slice() => match stmt.kind { // FIXME(mgca): this probably means that mac calls that expand diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0768e6a56b3c..01f5d6f22f91 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -326,6 +326,10 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind hir::ConstArgKind::TupleCall(..) => { ConstantKind::Path { path: "/* TUPLE CALL */".to_string().into() } } + hir::ConstArgKind::Tup(..) => { + // FIXME(mgca): proper printing :3 + ConstantKind::Path { path: "/* TUPLE EXPR */".to_string().into() } + } hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer, } @@ -1809,7 +1813,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } hir::ConstArgKind::Struct(..) | hir::ConstArgKind::Path(..) - | hir::ConstArgKind::TupleCall(..) => { + | hir::ConstArgKind::TupleCall(..) + | hir::ConstArgKind::Tup(..) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); print_const(cx, ct) } diff --git a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr index 6cf4e881adae..62bebd53b14a 100644 --- a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr +++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr @@ -1,8 +1,8 @@ error: unconstrained generic constant - --> $DIR/doesnt_unify_evaluatable.rs:9:11 + --> $DIR/doesnt_unify_evaluatable.rs:9:13 | LL | bar::<{ T::ASSOC }>(); - | ^^^^^^^^^^^^ + | ^^^^^^^^ | help: try adding a `where` bound | diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.rs b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.rs new file mode 100644 index 000000000000..e47052523fa3 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.rs @@ -0,0 +1,20 @@ +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +fn takes_tuple() {} +fn takes_nested_tuple() {} + +fn generic_caller() { + takes_tuple::<{ (N, N + 1) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_tuple::<{ (N, T::ASSOC + 1) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + + takes_nested_tuple::<{ (N, (N, N + 1)) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); //~ ERROR generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr new file mode 100644 index 000000000000..dbc64a1bf59d --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr @@ -0,0 +1,26 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/adt_expr_arg_tuple_expr_complex.rs:13:25 + | +LL | takes_tuple::<{ (N, N + 1) }>(); + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/adt_expr_arg_tuple_expr_complex.rs:14:25 + | +LL | takes_tuple::<{ (N, T::ASSOC + 1) }>(); + | ^^^^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/adt_expr_arg_tuple_expr_complex.rs:16:36 + | +LL | takes_nested_tuple::<{ (N, (N, N + 1)) }>(); + | ^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/adt_expr_arg_tuple_expr_complex.rs:17:44 + | +LL | takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); + | ^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs new file mode 100644 index 000000000000..60c4c6e952cf --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs @@ -0,0 +1,22 @@ +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +fn takes_tuple() {} +fn takes_nested_tuple() {} + +fn generic_caller() { + takes_tuple::<{ (N, N2) }>(); + takes_tuple::<{ (N, T::ASSOC) }>(); + + takes_nested_tuple::<{ (N, (N, N2)) }>(); + takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); +} + +fn main() {} diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs index 519e913480ec..f2b9f037ea5f 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs @@ -4,7 +4,6 @@ trait Foo> { //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| ERROR cycle detected when computing type of `Foo::N` - //~| ERROR cycle detected when computing type of `Foo::N` fn func() {} } diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr index 0ecb3e74eb57..4024f57af4ff 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr @@ -13,7 +13,7 @@ LL | trait Foo> { | +++ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:20 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:20 | LL | trait Bar> {} | ^^^^^^ @@ -32,7 +32,7 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^ | note: ...which requires computing type of `Bar::M`... - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:11 | LL | trait Bar> {} | ^^^^^^^^^^^^^^^ @@ -44,26 +44,6 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error[E0391]: cycle detected when computing type of `Foo::N` - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:3:11 - | -LL | trait Foo> { - | ^^^^^^^^^^^^^^^ - | -note: ...which requires computing type of `Bar::M`... - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11 - | -LL | trait Bar> {} - | ^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `Foo::N`, completing the cycle -note: cycle used when checking that `Foo` is well-formed - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:3:1 - | -LL | trait Foo> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 1 previous error; 2 warnings emitted For more information about this error, try `rustc --explain E0391`. From d572e6d415ab0796ef6d7beb960ff479be3628c2 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Tue, 6 Jan 2026 20:23:31 +0800 Subject: [PATCH 1656/3801] Add span field for ConstArg --- compiler/rustc_ast_lowering/src/index.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 47 ++++++++++++++----- compiler/rustc_ast_lowering/src/pat.rs | 3 +- compiler/rustc_hir/src/hir.rs | 25 +++------- compiler/rustc_hir/src/hir/tests.rs | 12 +++-- compiler/rustc_hir/src/intravisit.rs | 10 ++-- .../src/hir_ty_lowering/errors.rs | 4 +- .../src/hir_ty_lowering/mod.rs | 18 +++---- compiler/rustc_hir_pretty/src/lib.rs | 6 +-- compiler/rustc_hir_typeck/src/expr.rs | 4 +- compiler/rustc_lint/src/pass_by_value.rs | 9 ++-- compiler/rustc_middle/src/hir/map.rs | 2 +- .../src/error_reporting/infer/mod.rs | 2 +- .../clippy_lints/src/large_stack_arrays.rs | 2 +- .../clippy/clippy_lints/src/utils/author.rs | 1 + src/tools/clippy/clippy_utils/src/consts.rs | 2 +- .../clippy/clippy_utils/src/hir_utils.rs | 16 +++++++ .../mgca/adt_expr_erroneuous_inits.stderr | 6 +-- ...inting_valtrees_supports_non_values.stderr | 8 ++-- .../mgca/tuple_ctor_erroneous.stderr | 10 ++-- 20 files changed, 111 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index f6edcaa64dfe..be0a1d490da6 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -312,7 +312,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir, AmbigArg>) { self.insert( - const_arg.as_unambig_ct().span(), + const_arg.as_unambig_ct().span, const_arg.hir_id, Node::ConstArg(const_arg.as_unambig_ct()), ); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5c65aa192b7e..a81d2297ef85 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2285,8 +2285,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // `ExprKind::Paren(ExprKind::Underscore)` and should also be lowered to `GenericArg::Infer` match c.value.peel_parens().kind { ExprKind::Underscore => { - let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ()); - self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind }) + let ct_kind = hir::ConstArgKind::Infer(()); + self.arena.alloc(hir::ConstArg { + hir_id: self.lower_node_id(c.id), + kind: ct_kind, + span: self.lower_span(c.value.span), + }) } _ => self.lower_anon_const_to_const_arg_and_alloc(c), } @@ -2356,7 +2360,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::ConstArgKind::Anon(ct) }; - self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind }) + self.arena.alloc(hir::ConstArg { + hir_id: self.next_id(), + kind: ct_kind, + span: self.lower_span(span), + }) } fn lower_const_item_rhs( @@ -2373,9 +2381,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let const_arg = ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Error( - DUMMY_SP, self.dcx().span_delayed_bug(DUMMY_SP, "no block"), ), + span: DUMMY_SP, }; hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg)) } @@ -2388,13 +2396,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "debug", skip(self), ret)] fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir> { + let span = self.lower_span(expr.span); + let overly_complex_const = |this: &mut Self| { let e = this.dcx().struct_span_err( expr.span, "complex const arguments must be placed inside of a `const` block", ); - ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(expr.span, e.emit()) } + ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(e.emit()), span } }; match &expr.kind { @@ -2425,6 +2435,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::TupleCall(qpath, lowered_args), + span, } } ExprKind::Tup(exprs) => { @@ -2442,7 +2453,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &*self.arena.alloc(expr) })); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Tup(expr.span, exprs) } + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Tup(exprs), span } } ExprKind::Path(qself, path) => { let qpath = self.lower_qpath( @@ -2456,7 +2467,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { None, ); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath) } + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath), span } } ExprKind::Struct(se) => { let path = self.lower_qpath( @@ -2497,11 +2508,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) })); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Struct(path, fields) } + ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Struct(path, fields), + span, + } } ExprKind::Underscore => ConstArg { hir_id: self.lower_node_id(expr.id), - kind: hir::ConstArgKind::Infer(expr.span, ()), + kind: hir::ConstArgKind::Infer(()), + span, }, ExprKind::Block(block, _) => { if let [stmt] = block.stmts.as_slice() @@ -2546,7 +2562,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return match anon.mgca_disambiguation { MgcaDisambiguation::AnonConst => { let lowered_anon = self.lower_anon_const_to_anon_const(anon); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) } + ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Anon(lowered_anon), + span: lowered_anon.span, + } } MgcaDisambiguation::Direct => self.lower_expr_to_const_arg_direct(&anon.value), }; @@ -2583,11 +2603,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { return ConstArg { hir_id: self.lower_node_id(anon.id), kind: hir::ConstArgKind::Path(qpath), + span: self.lower_span(expr.span), }; } let lowered_anon = self.lower_anon_const_to_anon_const(anon); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) } + ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Anon(lowered_anon), + span: self.lower_span(expr.span), + } } /// See [`hir::ConstArg`] for when to use this function vs diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index f09bbb9c4972..e066bce95158 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -513,6 +513,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(self.arena.alloc(anon_const)), + span, }) } @@ -557,6 +558,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) }); let hir_id = self.next_id(); - self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id }) + self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id, span }) } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5c3f0e5ccd31..dc6790f7a3f1 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -423,7 +423,7 @@ impl<'hir> ConstItemRhs<'hir> { pub fn span<'tcx>(&self, tcx: impl crate::intravisit::HirTyCtxt<'tcx>) -> Span { match self { ConstItemRhs::Body(body_id) => tcx.hir_body(*body_id).value.span, - ConstItemRhs::TypeConst(ct_arg) => ct_arg.span(), + ConstItemRhs::TypeConst(ct_arg) => ct_arg.span, } } } @@ -447,6 +447,7 @@ pub struct ConstArg<'hir, Unambig = ()> { #[stable_hasher(ignore)] pub hir_id: HirId, pub kind: ConstArgKind<'hir, Unambig>, + pub span: Span, } impl<'hir> ConstArg<'hir, AmbigArg> { @@ -475,7 +476,7 @@ impl<'hir> ConstArg<'hir> { /// Functions accepting ambiguous consts will not handle the [`ConstArgKind::Infer`] variant, if /// infer consts are relevant to you then care should be taken to handle them separately. pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> { - if let ConstArgKind::Infer(_, ()) = self.kind { + if let ConstArgKind::Infer(()) = self.kind { return None; } @@ -494,25 +495,13 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> { _ => None, } } - - pub fn span(&self) -> Span { - match self.kind { - ConstArgKind::Tup(span, ..) => span, - ConstArgKind::Struct(path, _) => path.span(), - ConstArgKind::Path(path) => path.span(), - ConstArgKind::TupleCall(path, _) => path.span(), - ConstArgKind::Anon(anon) => anon.span, - ConstArgKind::Error(span, _) => span, - ConstArgKind::Infer(span, _) => span, - } - } } /// See [`ConstArg`]. #[derive(Clone, Copy, Debug, HashStable_Generic)] #[repr(u8, C)] pub enum ConstArgKind<'hir, Unambig = ()> { - Tup(Span, &'hir [&'hir ConstArg<'hir, Unambig>]), + Tup(&'hir [&'hir ConstArg<'hir, Unambig>]), /// **Note:** Currently this is only used for bare const params /// (`N` where `fn foo(...)`), /// not paths to any const (`N` where `const N: usize = ...`). @@ -525,10 +514,10 @@ pub enum ConstArgKind<'hir, Unambig = ()> { /// Tuple constructor variant TupleCall(QPath<'hir>, &'hir [&'hir ConstArg<'hir>]), /// Error const - Error(Span, ErrorGuaranteed), + Error(ErrorGuaranteed), /// This variant is not always used to represent inference consts, sometimes /// [`GenericArg::Infer`] is used instead. - Infer(Span, Unambig), + Infer(Unambig), } #[derive(Clone, Copy, Debug, HashStable_Generic)] @@ -574,7 +563,7 @@ impl GenericArg<'_> { match self { GenericArg::Lifetime(l) => l.ident.span, GenericArg::Type(t) => t.span, - GenericArg::Const(c) => c.span(), + GenericArg::Const(c) => c.span, GenericArg::Infer(i) => i.span, } } diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs index 4f9609fd360d..2ac33a369cbd 100644 --- a/compiler/rustc_hir/src/hir/tests.rs +++ b/compiler/rustc_hir/src/hir/tests.rs @@ -24,12 +24,16 @@ define_tests! { cast_ptr TyKind Ptr { 0: MutTy { ty: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }, mutbl: Mutability::Not }} cast_array TyKind Array { 0: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }, - 1: &ConstArg { hir_id: HirId::INVALID, kind: ConstArgKind::Anon(&AnonConst { + 1: &ConstArg { hir_id: HirId::INVALID, - def_id: LocalDefId { local_def_index: DefIndex::ZERO }, - body: BodyId { hir_id: HirId::INVALID }, + kind: ConstArgKind::Anon(&AnonConst { + hir_id: HirId::INVALID, + def_id: LocalDefId { local_def_index: DefIndex::ZERO }, + body: BodyId { hir_id: HirId::INVALID }, + span: DUMMY_SP, + }), span: DUMMY_SP, - })} + }, } cast_anon ConstArgKind Anon { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 576f74b8b02b..59db60fdc55c 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1068,8 +1068,8 @@ pub fn walk_unambig_const_arg<'v, V: Visitor<'v>>( match const_arg.try_as_ambig_ct() { Some(ambig_ct) => visitor.visit_const_arg(ambig_ct), None => { - let ConstArg { hir_id, kind: _ } = const_arg; - visitor.visit_infer(*hir_id, const_arg.span(), InferKind::Const(const_arg)) + let ConstArg { hir_id, kind: _, span } = const_arg; + visitor.visit_infer(*hir_id, *span, InferKind::Const(const_arg)) } } } @@ -1078,10 +1078,10 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( visitor: &mut V, const_arg: &'v ConstArg<'v, AmbigArg>, ) -> V::Result { - let ConstArg { hir_id, kind } = const_arg; + let ConstArg { hir_id, kind, span: _ } = const_arg; try_visit!(visitor.visit_id(*hir_id)); match kind { - ConstArgKind::Tup(_, exprs) => { + ConstArgKind::Tup(exprs) => { walk_list!(visitor, visit_const_arg, *exprs); V::Result::output() } @@ -1103,7 +1103,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( } ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), - ConstArgKind::Error(_, _) => V::Result::output(), // errors and spans are not important + ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 51c664921804..92b77a2042b1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -381,7 +381,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { { let span = match term { hir::Term::Ty(ty) => ty.span, - hir::Term::Const(ct) => ct.span(), + hir::Term::Const(ct) => ct.span, }; (span, Some(ident.span), assoc_item.as_tag(), assoc_tag) } else { @@ -1466,7 +1466,7 @@ pub fn prohibit_assoc_item_constraint( hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(c) }, GenericParamDefKind::Const { .. }, ) => { - suggest_direct_use(&mut err, c.span()); + suggest_direct_use(&mut err, c.span); } (hir::AssocItemConstraintKind::Bound { bounds }, _) => { // Suggest `impl Trait for Foo` when finding 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 ad037c195d55..aaa566760013 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2331,7 +2331,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions()) { let e = self.dcx().span_err( - const_arg.span(), + const_arg.span, "anonymous constants with lifetimes in their type are not yet supported", ); tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); @@ -2342,7 +2342,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // variables otherwise we will ICE. if anon_const_type.has_non_region_infer() { let e = self.dcx().span_err( - const_arg.span(), + const_arg.span, "anonymous constants with inferred types are not yet supported", ); tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); @@ -2352,7 +2352,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // give the anon const any of the generics from the parent. if anon_const_type.has_non_region_param() { let e = self.dcx().span_err( - const_arg.span(), + const_arg.span, "anonymous constants referencing generics are not yet supported", ); tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e))); @@ -2364,7 +2364,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let hir_id = const_arg.hir_id; match const_arg.kind { - hir::ConstArgKind::Tup(span, exprs) => self.lower_const_arg_tup(exprs, feed, span), + hir::ConstArgKind::Tup(exprs) => self.lower_const_arg_tup(exprs, feed, const_arg.span), hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => { debug!(?maybe_qself, ?path); let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself)); @@ -2378,19 +2378,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_self_ty, segment, hir_id, - const_arg.span(), + const_arg.span, ) .unwrap_or_else(|guar| Const::new_error(tcx, guar)) } hir::ConstArgKind::Struct(qpath, inits) => { - self.lower_const_arg_struct(hir_id, qpath, inits, const_arg.span()) + self.lower_const_arg_struct(hir_id, qpath, inits, const_arg.span) } hir::ConstArgKind::TupleCall(qpath, args) => { - self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span()) + self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span) } hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), - hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span), - hir::ConstArgKind::Error(_, e) => ty::Const::new_error(tcx, e), + hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span), + hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e), } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index d360a18676ff..2c160ccef2b6 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1141,13 +1141,13 @@ impl<'a> State<'a> { fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) { match &const_arg.kind { - ConstArgKind::Tup(_, exprs) => { + ConstArgKind::Tup(exprs) => { self.popen(); self.commasep_cmnt( Inconsistent, exprs, |s, arg| s.print_const_arg(arg), - |arg| arg.span(), + |arg| arg.span, ); self.pclose(); } @@ -1155,7 +1155,7 @@ impl<'a> State<'a> { ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args), ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), ConstArgKind::Anon(anon) => self.print_anon_const(anon), - ConstArgKind::Error(_, _) => self.word("/*ERROR*/"), + ConstArgKind::Error(_) => self.word("/*ERROR*/"), ConstArgKind::Infer(..) => self.word("_"), } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index c4fa39c6c2c8..9d7e09b020a7 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1705,7 +1705,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; }; if let hir::TyKind::Array(_, ct) = ty.peel_refs().kind { - let span = ct.span(); + let span = ct.span; self.dcx().try_steal_modify_and_emit_err( span, StashKey::UnderscoreForArrayLengths, @@ -1746,7 +1746,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; - let count_span = count.span(); + let count_span = count.span; let count = self.try_structurally_resolve_const( count_span, self.normalize(count_span, self.lower_const_arg(count, FeedConstTy::No)), diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index 29006732aade..f4a506d50a41 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -74,12 +74,9 @@ fn gen_args(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> String { GenericArg::Type(ty) => { cx.tcx.sess.source_map().span_to_snippet(ty.span).unwrap_or_else(|_| "_".into()) } - GenericArg::Const(c) => cx - .tcx - .sess - .source_map() - .span_to_snippet(c.span()) - .unwrap_or_else(|_| "_".into()), + GenericArg::Const(c) => { + cx.tcx.sess.source_map().span_to_snippet(c.span).unwrap_or_else(|_| "_".into()) + } GenericArg::Infer(_) => String::from("_"), }) .collect::>(); diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 8cc66802e435..ca783311586f 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1003,7 +1003,7 @@ impl<'tcx> TyCtxt<'tcx> { Node::Field(field) => field.span, Node::AnonConst(constant) => constant.span, Node::ConstBlock(constant) => self.hir_body(constant.body).value.span, - Node::ConstArg(const_arg) => const_arg.span(), + Node::ConstArg(const_arg) => const_arg.span, Node::Expr(expr) => expr.span, Node::ExprField(field) => field.span, Node::ConstArgExprField(field) => field.span, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index cea69c699628..47810e2578df 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1879,7 +1879,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let Some(length_val) = sz.found.try_to_target_usize(self.tcx) { Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { - span: length_arg.span(), + span: length_arg.span, length: length_val, }) } else { diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index 620e27fa67c6..261b03abba17 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -126,7 +126,7 @@ fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool { let ExprKind::Repeat(_, len_ct) = expr.kind else { return false; }; - !expr.span.contains(len_ct.span()) + !expr.span.contains(len_ct.span) } expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(expr) diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index f515f9987a80..455f76edc904 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -321,6 +321,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), + ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index a44cd31dc123..46b87fd5df96 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1140,7 +1140,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { + ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { None }, }, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index f1ee534c500d..57c896c97172 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -661,6 +661,10 @@ impl HirEqInterExpr<'_, '_, '_> { } fn eq_const_arg(&mut self, left: &ConstArg<'_>, right: &ConstArg<'_>) -> bool { + if !self.check_ctxt(left.span.ctxt(), right.span.ctxt()) { + return false; + } + match (&left.kind, &right.kind) { (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), @@ -679,11 +683,18 @@ impl HirEqInterExpr<'_, '_, '_> { .zip(*args_b) .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) } + (ConstArgKind::Tup(args_a), ConstArgKind::Tup(args_b)) => { + args_a + .iter() + .zip(*args_b) + .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) + } // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) | ConstArgKind::Anon(..) | ConstArgKind::TupleCall(..) + | ConstArgKind::Tup(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Error(..), @@ -1560,6 +1571,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(arg); } }, + ConstArgKind::Tup(args) => { + for arg in *args { + self.hash_const_arg(arg); + } + }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } diff --git a/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr index 49d3f67003dc..72e0e94ff625 100644 --- a/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr @@ -23,7 +23,7 @@ error: struct expression with missing field initialiser for `field` --> $DIR/adt_expr_erroneuous_inits.rs:16:17 | LL | accepts::<{ Foo:: { }}>(); - | ^^^^^^^^^ + | ^^^^^^^^^^^^^ error: struct expression with multiple initialisers for `field` --> $DIR/adt_expr_erroneuous_inits.rs:18:49 @@ -35,13 +35,13 @@ error: struct expression with invalid base path --> $DIR/adt_expr_erroneuous_inits.rs:20:17 | LL | accepts::<{ Fooo:: { field: const { 1 } }}>(); - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: struct expression with invalid base path --> $DIR/adt_expr_erroneuous_inits.rs:23:17 | LL | accepts::<{ NonStruct { }}>(); - | ^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr index b4f03e07b569..bd2162468944 100644 --- a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr @@ -2,7 +2,7 @@ error: the constant `Option::::Some(N)` is not of type `Foo` --> $DIR/printing_valtrees_supports_non_values.rs:18:13 | LL | foo::<{ Option::Some:: { 0: N } }>; - | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` | note: required by a const generic parameter in `foo` --> $DIR/printing_valtrees_supports_non_values.rs:15:8 @@ -14,7 +14,7 @@ error: the constant `Option::::Some(::ASSOC)` is not of type `F --> $DIR/printing_valtrees_supports_non_values.rs:23:13 | LL | foo::<{ Option::Some:: { 0: ::ASSOC } }>(); - | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` | note: required by a const generic parameter in `foo` --> $DIR/printing_valtrees_supports_non_values.rs:15:8 @@ -37,7 +37,7 @@ error: the constant `Option::::Some(_)` is not of type `Foo` --> $DIR/printing_valtrees_supports_non_values.rs:30:12 | LL | foo::<{Option::Some::{0: ::ASSOC}}>(); - | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` | note: required by a const generic parameter in `foo` --> $DIR/printing_valtrees_supports_non_values.rs:15:8 @@ -49,7 +49,7 @@ error: the constant `Option::::Some(_)` is not of type `Foo` --> $DIR/printing_valtrees_supports_non_values.rs:36:13 | LL | foo::<{ Option::Some:: { 0: _ } }>(); - | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` | note: required by a const generic parameter in `foo` --> $DIR/printing_valtrees_supports_non_values.rs:15:8 diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr index fbcdf35461ec..cc6144b9c88a 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr @@ -13,31 +13,31 @@ error: tuple constructor has 2 arguments but 1 were provided --> $DIR/tuple_ctor_erroneous.rs:23:23 | LL | accepts_point::<{ Point(N) }>(); - | ^^^^^ + | ^^^^^^^^ error: tuple constructor has 2 arguments but 3 were provided --> $DIR/tuple_ctor_erroneous.rs:26:23 | LL | accepts_point::<{ Point(N, N, N) }>(); - | ^^^^^ + | ^^^^^^^^^^^^^^ error: tuple constructor with invalid base path --> $DIR/tuple_ctor_erroneous.rs:29:23 | LL | accepts_point::<{ UnresolvedIdent(N, N) }>(); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ error: tuple constructor with invalid base path --> $DIR/tuple_ctor_erroneous.rs:33:23 | LL | accepts_point::<{ non_ctor(N, N) }>(); - | ^^^^^^^^ + | ^^^^^^^^^^^^^^ error: tuple constructor with invalid base path --> $DIR/tuple_ctor_erroneous.rs:36:23 | LL | accepts_point::<{ CONST_ITEM(N, N) }>(); - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: the constant `Point` is not of type `Point` --> $DIR/tuple_ctor_erroneous.rs:39:23 From cb1de296591e7220495c7f37a862678ee55edd71 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Tue, 6 Jan 2026 23:07:24 +0800 Subject: [PATCH 1657/3801] Use parent's identity_args to instantiate the type of const param --- compiler/rustc_hir_analysis/src/collect.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 9d4cb6d7684b..bacdf0049806 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1479,24 +1479,27 @@ fn rendered_precise_capturing_args<'tcx>( fn const_param_default<'tcx>( tcx: TyCtxt<'tcx>, - def_id: LocalDefId, + local_def_id: LocalDefId, ) -> ty::EarlyBinder<'tcx, Const<'tcx>> { let hir::Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { default: Some(default_ct), .. }, .. - }) = tcx.hir_node_by_def_id(def_id) + }) = tcx.hir_node_by_def_id(local_def_id) else { span_bug!( - tcx.def_span(def_id), + tcx.def_span(local_def_id), "`const_param_default` expected a generic parameter with a constant" ) }; - let icx = ItemCtxt::new(tcx, def_id); - let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); - let ct = icx.lowerer().lower_const_arg( - default_ct, - FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args), - ); + + let icx = ItemCtxt::new(tcx, local_def_id); + + let def_id = local_def_id.to_def_id(); + let identity_args = ty::GenericArgs::identity_for_item(tcx, tcx.parent(def_id)); + + let ct = icx + .lowerer() + .lower_const_arg(default_ct, FeedConstTy::with_type_of(tcx, def_id, identity_args)); ty::EarlyBinder::bind(ct) } From 6b11237e7dca81a57340ac4ab5ca2437b2c59a93 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Tue, 6 Jan 2026 20:23:31 +0800 Subject: [PATCH 1658/3801] Add span field for ConstArg --- clippy_lints/src/large_stack_arrays.rs | 2 +- clippy_lints/src/utils/author.rs | 1 + clippy_utils/src/consts.rs | 2 +- clippy_utils/src/hir_utils.rs | 16 ++++++++++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index 620e27fa67c6..261b03abba17 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -126,7 +126,7 @@ fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool { let ExprKind::Repeat(_, len_ct) = expr.kind else { return false; }; - !expr.span.contains(len_ct.span()) + !expr.span.contains(len_ct.span) } expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(expr) diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index f515f9987a80..455f76edc904 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -321,6 +321,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), + ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), } diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index a44cd31dc123..46b87fd5df96 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1140,7 +1140,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { + ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { None }, }, diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index f1ee534c500d..57c896c97172 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -661,6 +661,10 @@ impl HirEqInterExpr<'_, '_, '_> { } fn eq_const_arg(&mut self, left: &ConstArg<'_>, right: &ConstArg<'_>) -> bool { + if !self.check_ctxt(left.span.ctxt(), right.span.ctxt()) { + return false; + } + match (&left.kind, &right.kind) { (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), @@ -679,11 +683,18 @@ impl HirEqInterExpr<'_, '_, '_> { .zip(*args_b) .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) } + (ConstArgKind::Tup(args_a), ConstArgKind::Tup(args_b)) => { + args_a + .iter() + .zip(*args_b) + .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) + } // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) | ConstArgKind::Anon(..) | ConstArgKind::TupleCall(..) + | ConstArgKind::Tup(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Error(..), @@ -1560,6 +1571,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(arg); } }, + ConstArgKind::Tup(args) => { + for arg in *args { + self.hash_const_arg(arg); + } + }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } From 139d59f7ecbf0146a5c0e475473e71aca47e0b39 Mon Sep 17 00:00:00 2001 From: neo Date: Wed, 7 Jan 2026 09:53:06 +0900 Subject: [PATCH 1659/3801] Reword the collect() docs to stress that the return type determines the resulting collection --- library/core/src/iter/traits/iterator.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index f106900a3983..e418f481ad2a 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1906,9 +1906,12 @@ pub trait Iterator { /// Transforms an iterator into a collection. /// - /// `collect()` can take anything iterable, and turn it into a relevant - /// collection. This is one of the more powerful methods in the standard - /// library, used in a variety of contexts. + /// `collect()` takes ownership of an iterator and produces whichever + /// collection type you request. The iterator itself carries no knowledge of + /// the eventual container; the target collection is chosen entirely by the + /// type you ask `collect()` to return. This makes `collect()` one of the + /// more powerful methods in the standard library, and it shows up in a wide + /// variety of contexts. /// /// The most basic pattern in which `collect()` is used is to turn one /// collection into another. You take a collection, call [`iter`] on it, From 6346d14202ce2c4ac3e92595a6fd1b619803145d Mon Sep 17 00:00:00 2001 From: tison Date: Wed, 7 Jan 2026 09:31:59 +0800 Subject: [PATCH 1660/3801] Apply suggestion from @tisonkun --- library/alloc/src/task.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index 73b732241974..aa1901314e37 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -360,6 +360,7 @@ impl From> for RawWaker { /// waker.wake_by_ref(); // Prints "woken". /// waker.wake(); // Prints "woken". /// ``` +// #[unstable(feature = "local_waker", issue = "118959")] #[unstable(feature = "waker_fn", issue = "149580")] pub fn local_waker_fn(f: F) -> LocalWaker { struct LocalWakeFn { From 6c2dc40666b1564a9621fcccc2f32a70d3e89e38 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Wed, 7 Jan 2026 00:03:32 +0800 Subject: [PATCH 1661/3801] Bless other tests --- tests/crashes/133965.rs | 9 --- tests/incremental/const-generic-type-cycle.rs | 1 - ...ith-same-name-and-derive-default-133965.rs | 14 ++++ ...same-name-and-derive-default-133965.stderr | 81 +++++++++++++++++++ .../non_scalar_alignment_value.stderr | 8 +- 5 files changed, 99 insertions(+), 14 deletions(-) delete mode 100644 tests/crashes/133965.rs create mode 100644 tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs create mode 100644 tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr diff --git a/tests/crashes/133965.rs b/tests/crashes/133965.rs deleted file mode 100644 index 69f533ccbe98..000000000000 --- a/tests/crashes/133965.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #133965 -//@ needs-rustc-debug-assertions - -struct NonGeneric {} - -#[derive(Default)] -struct NonGeneric<'a, const N: usize> {} - -pub fn main() {} diff --git a/tests/incremental/const-generic-type-cycle.rs b/tests/incremental/const-generic-type-cycle.rs index 40a40ebd13fe..5bcbc1d5dafe 100644 --- a/tests/incremental/const-generic-type-cycle.rs +++ b/tests/incremental/const-generic-type-cycle.rs @@ -14,7 +14,6 @@ trait Bar {} trait Bar {} //[cfail]~^ ERROR cycle detected when computing type of `Bar::N` //[cfail]~| ERROR cycle detected when computing type of `Bar::N` -//[cfail]~| ERROR cycle detected when computing type of `Bar::N` //[cfail]~| ERROR `(dyn Bar<{ 2 + 1 }> + 'static)` is forbidden as the type of a const generic parameter trait BB = Bar<{ 2 + 1 }>; diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs new file mode 100644 index 000000000000..8e5cd4248f14 --- /dev/null +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs @@ -0,0 +1,14 @@ +//@ needs-rustc-debug-assertions + +struct NonGeneric {} + +#[derive(Default)] +//~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied +//~^^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied +//~^^^ ERROR struct takes 0 generic arguments but 1 generic argument was supplied +//~^^^^ ERROR struct takes 0 generic arguments but 1 generic argument was supplied +struct NonGeneric<'a, const N: usize> {} +//~^ ERROR lifetime parameter `'a` is never used +//~^^ ERROR the name `NonGeneric` is defined multiple times + +pub fn main() {} diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr new file mode 100644 index 000000000000..cf9c0d0ad3be --- /dev/null +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr @@ -0,0 +1,81 @@ +error[E0428]: the name `NonGeneric` is defined multiple times + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:10:1 + | +LL | struct NonGeneric {} + | ----------------- previous definition of the type `NonGeneric` here +... +LL | struct NonGeneric<'a, const N: usize> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonGeneric` redefined here + | + = note: `NonGeneric` must be defined only once in the type namespace of this module + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 lifetime arguments +... +LL | struct NonGeneric<'a, const N: usize> {} + | -- help: remove the lifetime argument + | +note: struct defined here, with 0 lifetime parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 generic arguments + | +note: struct defined here, with 0 generic parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:10:19 + | +LL | struct NonGeneric<'a, const N: usize> {} + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 lifetime arguments +... +LL | struct NonGeneric<'a, const N: usize> {} + | -- help: remove the lifetime argument + | +note: struct defined here, with 0 lifetime parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 generic arguments +... +LL | struct NonGeneric<'a, const N: usize> {} + | - help: remove the unnecessary generic argument + | +note: struct defined here, with 0 generic parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0107, E0392, E0428. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/transmutability/non_scalar_alignment_value.stderr b/tests/ui/transmutability/non_scalar_alignment_value.stderr index 06487dea82e0..d22c6d0b27e8 100644 --- a/tests/ui/transmutability/non_scalar_alignment_value.stderr +++ b/tests/ui/transmutability/non_scalar_alignment_value.stderr @@ -11,25 +11,25 @@ error: struct expression with missing field initialiser for `alignment` --> $DIR/non_scalar_alignment_value.rs:15:32 | LL | alignment: Assume {}, - | ^^^^^^ + | ^^^^^^^^^ error: struct expression with missing field initialiser for `lifetimes` --> $DIR/non_scalar_alignment_value.rs:15:32 | LL | alignment: Assume {}, - | ^^^^^^ + | ^^^^^^^^^ error: struct expression with missing field initialiser for `safety` --> $DIR/non_scalar_alignment_value.rs:15:32 | LL | alignment: Assume {}, - | ^^^^^^ + | ^^^^^^^^^ error: struct expression with missing field initialiser for `validity` --> $DIR/non_scalar_alignment_value.rs:15:32 | LL | alignment: Assume {}, - | ^^^^^^ + | ^^^^^^^^^ error: aborting due to 4 previous errors; 1 warning emitted From d848437814ac8796a540b762dcb446f20384969e Mon Sep 17 00:00:00 2001 From: andjsrk Date: Wed, 7 Jan 2026 12:09:07 +0900 Subject: [PATCH 1662/3801] add more information in comment --- .../ui/repeat-expr/can-have-side-effects-consider-element.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs b/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs index d0b5d12455dc..274942f9379f 100644 --- a/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs +++ b/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs @@ -5,8 +5,8 @@ // Test if `Expr::can_have_side_effects` considers element of repeat expressions. fn drop_repeat_in_arm_body() { - // Built-in lint `dropping_copy_types` relies on - // `Expr::can_have_side_effects` (See rust-clippy#9482) + // Built-in lint `dropping_copy_types` relies on `Expr::can_have_side_effects` + // (See rust-clippy#9482 and rust#113231) match () { () => drop([0; 1]), // No side effects From 11324546168855ddb221b019e0fa004e9de78881 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 7 Jan 2026 06:03:51 +0100 Subject: [PATCH 1663/3801] tests/ui/runtime/on-broken-pipe/with-rustc_main.rs: Not needed so remove It was added in ddee45e1d7fd when SIGPIPE was controlled with an attribute on `fn main()` which meant it could also be combined with `#[rustc_main]`: #[unix_sigpipe = "sig_dfl"] #[rustc_main] fn rustc_main() { It stopped being needed cde0cde151f3 when `#[unix_sigpipe = "..."]` was replaced by `-Zon-broken-pipe=...`. And it will not be needed when `-Zon-broken-pipe=...` is replaced by an Externally Implementable Item. Let's remove this test. --- .../ui/runtime/on-broken-pipe/with-rustc_main.rs | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 tests/ui/runtime/on-broken-pipe/with-rustc_main.rs diff --git a/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs b/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs deleted file mode 100644 index c40590ad87f4..000000000000 --- a/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-pass -//@ aux-build:sigpipe-utils.rs -//@ compile-flags: -Zon-broken-pipe=kill -//@ only-unix because SIGPIPE is a unix thing - -#![feature(rustc_attrs)] - -#[rustc_main] -fn rustc_main() { - extern crate sigpipe_utils; - - // `-Zon-broken-pipe=kill` is active, so SIGPIPE handler shall be - // SIG_DFL. Note that we have a #[rustc_main], but it should still work. - sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default); -} From 6cc9e5ccd3728842f23502dc9d1f9de08056a340 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 7 Jan 2026 08:15:27 +0100 Subject: [PATCH 1664/3801] Document `Query` --- .../crates/ide-db/src/symbol_index.rs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index eb0529d6b5e7..06e1f6bb4560 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -40,15 +40,61 @@ use salsa::Update; use crate::RootDatabase; +/// A query for searching symbols in the workspace or dependencies. +/// +/// This struct configures how symbol search is performed, including the search text, +/// matching strategy, and filtering options. It is used by [`world_symbols`] to find +/// symbols across the codebase. +/// +/// # Example +/// ```ignore +/// let mut query = Query::new("MyStruct".to_string()); +/// query.only_types(); // Only search for type definitions +/// query.libs(); // Include library dependencies +/// query.exact(); // Use exact matching instead of fuzzy +/// ``` #[derive(Debug, Clone)] pub struct Query { + /// The original search query string as provided by the user. + /// Used for the final matching check via [`SearchMode::check`]. query: String, + /// Lowercase version of [`Self::query`], pre-computed for efficiency. + /// Used to build FST automata for case-insensitive index lookups. lowercased: String, + /// The search strategy to use when matching symbols. + /// - [`SearchMode::Exact`]: Symbol name must exactly match the query. + /// - [`SearchMode::Fuzzy`]: Symbol name must contain all query characters in order (subsequence match). + /// - [`SearchMode::Prefix`]: Symbol name must start with the query string. + /// + /// Defaults to [`SearchMode::Fuzzy`]. mode: SearchMode, + /// Controls filtering of trait-associated items (methods, constants, types). + /// - [`AssocSearchMode::Include`]: Include both associated and non-associated items. + /// - [`AssocSearchMode::Exclude`]: Exclude trait-associated items from results. + /// - [`AssocSearchMode::AssocItemsOnly`]: Only return trait-associated items. + /// + /// Defaults to [`AssocSearchMode::Include`]. assoc_mode: AssocSearchMode, + /// Whether the final symbol name comparison should be case-sensitive. + /// When `false`, matching is case-insensitive (e.g., "foo" matches "Foo"). + /// + /// Defaults to `false`. case_sensitive: bool, + /// When `true`, only return type definitions: structs, enums, unions, + /// type aliases, built-in types, and traits. Functions, constants, statics, + /// and modules are excluded. + /// + /// Defaults to `false`. only_types: bool, + /// When `true`, search library dependency roots instead of local workspace crates. + /// This enables finding symbols in external dependencies including the standard library. + /// + /// Defaults to `false` (search local workspace only). libs: bool, + /// When `true`, exclude re-exported/imported symbols from results, + /// showing only the original definitions. + /// + /// Defaults to `false`. exclude_imports: bool, } From d37d04a37c6a9cd62e4c9518ffd47352a2a2ad1e Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 4 Jan 2026 04:51:44 +0100 Subject: [PATCH 1665/3801] recognize safety comments inside blocks and on same line in macros allow only whitespace between the comment marker and `SAFETY:` --- .../src/undocumented_unsafe_blocks.rs | 35 ++++ .../undocumented_unsafe_blocks.default.stderr | 156 +++++++++------- ...undocumented_unsafe_blocks.disabled.stderr | 168 ++++++++++-------- .../undocumented_unsafe_blocks.rs | 67 +++++++ 4 files changed, 288 insertions(+), 138 deletions(-) diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index 9d27a66a9ab8..1b26b1b32b80 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -115,6 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id) && !is_unsafe_from_proc_macro(cx, block.span) && !block_has_safety_comment(cx, block.span, self.accept_comment_above_attributes) + && !block_has_inner_safety_comment(cx, block.span) && !block_parents_have_safety_comment( self.accept_comment_above_statement, self.accept_comment_above_attributes, @@ -839,6 +840,23 @@ fn text_has_safety_comment( } } } + // Check for a comment that appears after other code on the same line (e.g., `let x = // SAFETY:`) + // This handles cases in macros where the comment is on the same line as preceding code. + // We only check the first (immediate preceding) line for this pattern. + // Only whitespace is allowed between the comment marker and `SAFETY:`. + if let Some(comment_start) = [line.find("//"), line.find("/*")].into_iter().flatten().min() + && let after_marker = &line[comment_start + 2..] // skip marker + && let trimmed = after_marker.trim_start() // skip whitespace + && trimmed.get(..7).is_some_and(|s| s.eq_ignore_ascii_case("SAFETY:")) + { + let safety_offset = 2 + (after_marker.len() - trimmed.len()); + return HasSafetyComment::Yes( + start_pos + + BytePos(u32::try_from(line_start).unwrap()) + + BytePos(u32::try_from(comment_start + safety_offset).unwrap()), + false, + ); + } // No line comments; look for the start of a block comment. // This will only find them if they are at the start of a line. let (mut line_start, mut line) = (line_start, line); @@ -894,3 +912,20 @@ fn is_const_or_static(node: &Node<'_>) -> bool { }) ) } + +fn block_has_inner_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { + let source_map = cx.sess().source_map(); + if let Ok(src) = source_map.span_to_snippet(span) + && let Some(after_brace) = src + .strip_prefix("unsafe") + .and_then(|s| s.trim_start().strip_prefix('{')) + && let Some(comment) = after_brace + .trim_start() + .strip_prefix("//") + .or_else(|| after_brace.trim_start().strip_prefix("/*")) + { + comment.trim_start().to_ascii_uppercase().starts_with("SAFETY:") + } else { + false + } +} diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr index 61e5af81d827..bcc46adda8a0 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr @@ -1,15 +1,39 @@ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:270:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:244:22 + | +LL | let _x = unsafe { 1 }; + | ^^^^^^^^^^^^ +... +LL | t!(); + | ---- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]` + = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe block missing a safety comment + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:256:13 + | +LL | unsafe { 1 }; + | ^^^^^^^^^^^^ +... +LL | t!(); + | ---- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe block missing a safety comment + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:337:19 | LL | /* Safety: */ unsafe {} | ^^^^^^^^^ | = help: consider adding a safety comment on the preceding line - = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]` error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:342:5 | LL | unsafe {} | ^^^^^^^^^ @@ -17,7 +41,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:14 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -25,7 +49,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:29 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:29 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -33,7 +57,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:48 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:48 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -41,7 +65,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:18 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:18 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -49,7 +73,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:37 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:37 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -57,7 +81,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:293:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:360:14 | LL | let _ = *unsafe { &42 }; | ^^^^^^^^^^^^^^ @@ -65,7 +89,7 @@ LL | let _ = *unsafe { &42 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:299:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:366:19 | LL | let _ = match unsafe {} { | ^^^^^^^^^ @@ -73,7 +97,7 @@ LL | let _ = match unsafe {} { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:373:14 | LL | let _ = &unsafe {}; | ^^^^^^^^^ @@ -81,7 +105,7 @@ LL | let _ = &unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:311:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:378:14 | LL | let _ = [unsafe {}; 5]; | ^^^^^^^^^ @@ -89,7 +113,7 @@ LL | let _ = [unsafe {}; 5]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383:13 | LL | let _ = unsafe {}; | ^^^^^^^^^ @@ -97,7 +121,7 @@ LL | let _ = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:327:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:394:8 | LL | t!(unsafe {}); | ^^^^^^^^^ @@ -105,7 +129,7 @@ LL | t!(unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:401:13 | LL | unsafe {} | ^^^^^^^^^ @@ -117,7 +141,7 @@ LL | t!(); = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:410:5 | LL | unsafe {} // SAFETY: | ^^^^^^^^^ @@ -125,7 +149,7 @@ LL | unsafe {} // SAFETY: = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:349:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416:5 | LL | unsafe { | ^^^^^^^^ @@ -133,7 +157,7 @@ LL | unsafe { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:360:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:427:5 | LL | unsafe {}; | ^^^^^^^^^ @@ -141,7 +165,7 @@ LL | unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:365:20 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:432:20 | LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +173,7 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:373:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:440:5 | LL | unsafe impl A for () {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +181,7 @@ LL | unsafe impl A for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:381:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:448:9 | LL | unsafe impl B for (u32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,7 +189,7 @@ LL | unsafe impl B for (u32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:470:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +201,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:429:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +213,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:439:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:5 | LL | unsafe impl T for (i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -197,7 +221,7 @@ LL | unsafe impl T for (i32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:429:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +233,7 @@ LL | no_safety_comment!(u32); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:446:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:513:5 | LL | unsafe impl T for (bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +241,7 @@ LL | unsafe impl T for (bool) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:493:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:560:5 | LL | unsafe impl NoComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -225,7 +249,7 @@ LL | unsafe impl NoComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:498:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:565:19 | LL | /* SAFETY: */ unsafe impl InlineComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,7 +257,7 @@ LL | /* SAFETY: */ unsafe impl InlineComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:503:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:570:5 | LL | unsafe impl TrailingComment for () {} // SAFETY: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,13 +265,13 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: = help: consider adding a safety comment on the preceding line error: constant has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:575:5 | LL | const BIG_NUMBER: i32 = 1000000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:507:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:574:8 | LL | // SAFETY: | ^^^^^^^ @@ -255,7 +279,7 @@ LL | // SAFETY: = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:577:5 | LL | unsafe impl Interference for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +287,7 @@ LL | unsafe impl Interference for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:518:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:585:5 | LL | unsafe impl ImplInFn for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -271,7 +295,7 @@ LL | unsafe impl ImplInFn for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:528:1 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:595:1 | LL | unsafe impl CrateRoot for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +303,7 @@ LL | unsafe impl CrateRoot for () {} = help: consider adding a safety comment on the preceding line error: statement has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:543:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:610:5 | LL | / let _ = { LL | | @@ -289,13 +313,13 @@ LL | | }; | |______^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:542:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:609:8 | LL | // SAFETY: this is more than one level away, so it should warn | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:545:12 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:612:12 | LL | if unsafe { true } { | ^^^^^^^^^^^^^^^ @@ -303,7 +327,7 @@ LL | if unsafe { true } { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:549:23 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:616:23 | LL | let bar = unsafe {}; | ^^^^^^^^^ @@ -311,7 +335,7 @@ LL | let bar = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:638:52 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:705:52 | LL | const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 }; | ^^^^^^^^^^^^ @@ -319,7 +343,7 @@ LL | const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:647:41 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:714:41 | LL | const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 }; | ^^^^^^^^^^^^ @@ -327,7 +351,7 @@ LL | const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:657:42 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:724:42 | LL | const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 }; | ^^^^^^^^^^^^ @@ -335,7 +359,7 @@ LL | const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:662:40 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:729:40 | LL | const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 }; | ^^^^^^^^^^^^ @@ -343,136 +367,136 @@ LL | const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 }; = help: consider adding a safety comment on the preceding line error: constant has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:701:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:768:5 | LL | const UNIX_EPOCH_JULIAN_DAY: i32 = | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:699:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:766:8 | LL | // SAFETY: fail ONLY if `accept-comment-above-attribute = false` | ^^^^^^^ error: statement has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:721:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:788:5 | LL | _ = bar(); | ^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:720:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:787:8 | LL | // SAFETY: unnecessary_safety_comment triggers here | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: module has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:741:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:808:5 | LL | mod x {} | ^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:740:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:807:8 | LL | // SAFETY: ... | ^^^^^^^ error: module has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:746:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:813:5 | LL | mod y {} | ^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:744:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:811:8 | LL | // SAFETY: ... | ^^^^^^^ error: module has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:751:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:818:5 | LL | mod z {} | ^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:750:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:817:8 | LL | // SAFETY: ... | ^^^^^^^ error: module has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:759:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:826:5 | LL | mod y {} | ^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:757:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:824:8 | LL | // SAFETY: ... | ^^^^^^^ error: statement has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:774:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:841:9 | LL | let x = 34; | ^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:772:12 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:839:12 | LL | // SAFETY: ... | ^^^^^^^^^^^ error: function has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:781:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:848:5 | LL | unsafe fn unsafe_comment() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider changing the `safety` comment for a `# Safety` doc comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:780:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:847:8 | LL | // SAFETY: Bla | ^^^^^^^ error: function has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:787:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:854:5 | LL | unsafe fn unsafe_block_comment() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider changing the `safety` comment for a `# Safety` doc comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:785:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:852:8 | LL | SAFETY: Bla | ^^^^^^^ error: function has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:791:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:858:5 | LL | fn safe_comment() {} | ^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:790:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:857:8 | LL | // SAFETY: Bla | ^^^^^^^ error: function has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:795:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:862:5 | LL | fn safe_doc_comment() {} | ^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:794:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:861:9 | LL | /// SAFETY: Bla | ^^^^^^^ -error: aborting due to 50 previous errors +error: aborting due to 52 previous errors diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr index e252cffea916..0de8ed716bed 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr @@ -1,15 +1,39 @@ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:270:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:244:22 + | +LL | let _x = unsafe { 1 }; + | ^^^^^^^^^^^^ +... +LL | t!(); + | ---- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]` + = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe block missing a safety comment + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:256:13 + | +LL | unsafe { 1 }; + | ^^^^^^^^^^^^ +... +LL | t!(); + | ---- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe block missing a safety comment + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:337:19 | LL | /* Safety: */ unsafe {} | ^^^^^^^^^ | = help: consider adding a safety comment on the preceding line - = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]` error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:342:5 | LL | unsafe {} | ^^^^^^^^^ @@ -17,7 +41,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:14 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -25,7 +49,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:29 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:29 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -33,7 +57,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:280:48 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:48 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -41,7 +65,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:18 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:18 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -49,7 +73,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:37 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:37 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -57,7 +81,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:293:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:360:14 | LL | let _ = *unsafe { &42 }; | ^^^^^^^^^^^^^^ @@ -65,7 +89,7 @@ LL | let _ = *unsafe { &42 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:299:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:366:19 | LL | let _ = match unsafe {} { | ^^^^^^^^^ @@ -73,7 +97,7 @@ LL | let _ = match unsafe {} { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:373:14 | LL | let _ = &unsafe {}; | ^^^^^^^^^ @@ -81,7 +105,7 @@ LL | let _ = &unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:311:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:378:14 | LL | let _ = [unsafe {}; 5]; | ^^^^^^^^^ @@ -89,7 +113,7 @@ LL | let _ = [unsafe {}; 5]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383:13 | LL | let _ = unsafe {}; | ^^^^^^^^^ @@ -97,7 +121,7 @@ LL | let _ = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:327:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:394:8 | LL | t!(unsafe {}); | ^^^^^^^^^ @@ -105,7 +129,7 @@ LL | t!(unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:401:13 | LL | unsafe {} | ^^^^^^^^^ @@ -117,7 +141,7 @@ LL | t!(); = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:410:5 | LL | unsafe {} // SAFETY: | ^^^^^^^^^ @@ -125,7 +149,7 @@ LL | unsafe {} // SAFETY: = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:349:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416:5 | LL | unsafe { | ^^^^^^^^ @@ -133,7 +157,7 @@ LL | unsafe { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:360:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:427:5 | LL | unsafe {}; | ^^^^^^^^^ @@ -141,7 +165,7 @@ LL | unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:365:20 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:432:20 | LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +173,7 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:373:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:440:5 | LL | unsafe impl A for () {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +181,7 @@ LL | unsafe impl A for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:381:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:448:9 | LL | unsafe impl B for (u32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,7 +189,7 @@ LL | unsafe impl B for (u32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:470:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +201,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:429:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +213,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:439:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:5 | LL | unsafe impl T for (i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -197,7 +221,7 @@ LL | unsafe impl T for (i32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:429:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +233,7 @@ LL | no_safety_comment!(u32); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:446:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:513:5 | LL | unsafe impl T for (bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +241,7 @@ LL | unsafe impl T for (bool) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:493:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:560:5 | LL | unsafe impl NoComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -225,7 +249,7 @@ LL | unsafe impl NoComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:498:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:565:19 | LL | /* SAFETY: */ unsafe impl InlineComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,7 +257,7 @@ LL | /* SAFETY: */ unsafe impl InlineComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:503:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:570:5 | LL | unsafe impl TrailingComment for () {} // SAFETY: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,13 +265,13 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: = help: consider adding a safety comment on the preceding line error: constant has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:575:5 | LL | const BIG_NUMBER: i32 = 1000000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:507:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:574:8 | LL | // SAFETY: | ^^^^^^^ @@ -255,7 +279,7 @@ LL | // SAFETY: = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:577:5 | LL | unsafe impl Interference for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +287,7 @@ LL | unsafe impl Interference for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:518:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:585:5 | LL | unsafe impl ImplInFn for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -271,7 +295,7 @@ LL | unsafe impl ImplInFn for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:528:1 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:595:1 | LL | unsafe impl CrateRoot for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +303,7 @@ LL | unsafe impl CrateRoot for () {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:539:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:606:9 | LL | unsafe {}; | ^^^^^^^^^ @@ -287,7 +311,7 @@ LL | unsafe {}; = help: consider adding a safety comment on the preceding line error: statement has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:543:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:610:5 | LL | / let _ = { LL | | @@ -297,13 +321,13 @@ LL | | }; | |______^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:542:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:609:8 | LL | // SAFETY: this is more than one level away, so it should warn | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:545:12 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:612:12 | LL | if unsafe { true } { | ^^^^^^^^^^^^^^^ @@ -311,7 +335,7 @@ LL | if unsafe { true } { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:549:23 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:616:23 | LL | let bar = unsafe {}; | ^^^^^^^^^ @@ -319,7 +343,7 @@ LL | let bar = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:568:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:635:9 | LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -327,7 +351,7 @@ LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:573:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:640:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -335,7 +359,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:578:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:645:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -343,7 +367,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:585:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:652:5 | LL | unsafe {} | ^^^^^^^^^ @@ -351,7 +375,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:590:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:657:5 | LL | unsafe { | ^^^^^^^^ @@ -359,7 +383,7 @@ LL | unsafe { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:598:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:665:9 | LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -367,7 +391,7 @@ LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:604:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:671:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -375,7 +399,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:611:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:678:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -383,7 +407,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:617:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:684:5 | LL | unsafe {} | ^^^^^^^^^ @@ -391,7 +415,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:638:52 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:705:52 | LL | const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 }; | ^^^^^^^^^^^^ @@ -399,7 +423,7 @@ LL | const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:647:41 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:714:41 | LL | const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 }; | ^^^^^^^^^^^^ @@ -407,7 +431,7 @@ LL | const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:657:42 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:724:42 | LL | const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 }; | ^^^^^^^^^^^^ @@ -415,7 +439,7 @@ LL | const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:662:40 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:729:40 | LL | const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 }; | ^^^^^^^^^^^^ @@ -423,7 +447,7 @@ LL | const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:673:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:740:9 | LL | unsafe { here_is_another_variable_with_long_name }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -431,7 +455,7 @@ LL | unsafe { here_is_another_variable_with_long_name }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:702:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:769:9 | LL | unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian_day_just_make_this_line_longer(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -439,19 +463,19 @@ LL | unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian = help: consider adding a safety comment on the preceding line error: statement has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:721:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:788:5 | LL | _ = bar(); | ^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:720:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:787:8 | LL | // SAFETY: unnecessary_safety_comment triggers here | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:735:12 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:802:12 | LL | return unsafe { h() }; | ^^^^^^^^^^^^^^ @@ -459,31 +483,31 @@ LL | return unsafe { h() }; = help: consider adding a safety comment on the preceding line error: module has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:741:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:808:5 | LL | mod x {} | ^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:740:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:807:8 | LL | // SAFETY: ... | ^^^^^^^ error: module has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:751:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:818:5 | LL | mod z {} | ^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:750:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:817:8 | LL | // SAFETY: ... | ^^^^^^^ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:766:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:833:9 | LL | unsafe {} | ^^^^^^^^^ @@ -491,52 +515,52 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: function has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:781:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:848:5 | LL | unsafe fn unsafe_comment() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider changing the `safety` comment for a `# Safety` doc comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:780:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:847:8 | LL | // SAFETY: Bla | ^^^^^^^ error: function has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:787:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:854:5 | LL | unsafe fn unsafe_block_comment() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider changing the `safety` comment for a `# Safety` doc comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:785:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:852:8 | LL | SAFETY: Bla | ^^^^^^^ error: function has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:791:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:858:5 | LL | fn safe_comment() {} | ^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:790:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:857:8 | LL | // SAFETY: Bla | ^^^^^^^ error: function has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:795:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:862:5 | LL | fn safe_doc_comment() {} | ^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:794:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:861:9 | LL | /// SAFETY: Bla | ^^^^^^^ -error: aborting due to 60 previous errors +error: aborting due to 62 previous errors diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs index db9e81cf10a1..8032c388ccfe 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs @@ -201,6 +201,66 @@ fn comment_macro_def() { t!(); } +fn comment_macro_def_with_let() { + macro_rules! t { + () => { + let _x = + // SAFETY: here be exactly one dragon + unsafe { 1 }; + }; + } + + t!(); +} + +#[rustfmt::skip] +fn comment_macro_def_with_let_same_line() { + macro_rules! t { + () => { + let _x =// SAFETY: same line comment + unsafe { 1 }; + }; + } + + t!(); +} + +fn inner_comment_macro_def_with_let() { + macro_rules! t { + () => { + let _x = unsafe { + // SAFETY: inside the block + 1 + }; + }; + } + + t!(); +} + +fn no_comment_macro_def_with_let() { + macro_rules! t { + () => { + let _x = unsafe { 1 }; + //~^ undocumented_unsafe_blocks + }; + } + + t!(); +} + +fn prefixed_safety_comment_macro_def_with_let() { + macro_rules! t { + () => { + let _x =// not a SAFETY: comment, should lint + unsafe { 1 }; + //~^ undocumented_unsafe_blocks + }; + } + + t!(); +} + fn non_ascii_comment() { // ॐ᧻໒ SaFeTy: ௵∰ unsafe {}; @@ -263,6 +323,13 @@ fn in_closure(x: *const u32) { let _ = || unsafe { *x }; } +fn inner_block_comment_block_style(x: *const u32) { + let _ = unsafe { + /* SAFETY: block comment inside */ + *x + }; +} + // Invalid comments #[rustfmt::skip] From f02ed7b565e6d9ba3b7b13abe86ea3a2dec3bf3c Mon Sep 17 00:00:00 2001 From: Spxg Date: Wed, 7 Jan 2026 17:10:56 +0800 Subject: [PATCH 1666/3801] Fix `alloc_error_handler` signature mismatch --- compiler/rustc_codegen_ssa/src/base.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 8ab0b367f08a..c8aa7c04585c 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -6,7 +6,8 @@ use std::time::{Duration, Instant}; use itertools::Itertools; use rustc_abi::FIRST_VARIANT; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorMethod, AllocatorTy, + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorMethod, AllocatorMethodInput, + AllocatorTy, }; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; @@ -671,7 +672,7 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec Date: Wed, 7 Jan 2026 10:03:04 +0100 Subject: [PATCH 1667/3801] Do not warn about large stack arrays without having a valid span The libtest harness generates an array with all the tests on the stack. However, it is generated with no location information, so we cannot tell the user anything useful. This commit is not accompanied by a test, as it would require running Clippy on the result of libtest harness with a lot of tests, which would take a very long time. A note has been added to the source to indicate not to remove the check. --- clippy_lints/src/large_stack_arrays.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index 620e27fa67c6..7bb7bc91f0c9 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -94,6 +94,15 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { }) && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size) { + // libtest might generate a large array containing the test cases, and no span will be associated + // to it. In this case it is better not to complain. + // + // Note that this condition is not checked explicitly by a unit test. Do not remove it without + // ensuring that stays fixed. + if expr.span.is_dummy() { + return; + } + span_lint_and_then( cx, LARGE_STACK_ARRAYS, From d2497820d02ddec3b57cd9cb60e698bf472d2808 Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Wed, 7 Jan 2026 12:06:37 +0100 Subject: [PATCH 1668/3801] build-manifest: Add `rust-mingw` also as extension for "pc-windows-gnu" hosts. This should enable `rustup component add --target aarch64-pc-windows-gnullvm rust-mingw` when running an `x86_64-pc-windows-gnullvm` toolchain (and vice-versa). Which itself enables proper cross-compiling of Windows ARM64 binaries on a Windows x64 host without using commercial MSVC. --- src/tools/build-manifest/src/main.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 42db12e5e117..4cec1b1f164b 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -282,6 +282,14 @@ impl Builder { PkgType::RustMingw => { if host.contains("pc-windows-gnu") { components.push(host_component(pkg)); + extensions.extend( + TARGETS + .iter() + .filter(|&&target| { + target.contains("pc-windows-gnu") && target != host + }) + .map(|target| Component::from_pkg(pkg, target)), + ); } } // Tools are always present in the manifest, From 6f7313e8adaec57196cec3d368cac8dd5fbf3d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 7 Jan 2026 12:55:38 +0100 Subject: [PATCH 1669/3801] Make verify-channel.sh script compatible with new bors --- src/ci/scripts/verify-channel.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/scripts/verify-channel.sh b/src/ci/scripts/verify-channel.sh index 9a9e713243d7..cac8ba332ed1 100755 --- a/src/ci/scripts/verify-channel.sh +++ b/src/ci/scripts/verify-channel.sh @@ -8,7 +8,8 @@ IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" -if isCiBranch auto || isCiBranch try || isCiBranch try-perf || isCiBranch automation/bors/try; then +if isCiBranch auto || isCiBranch try || isCiBranch try-perf || \ + isCiBranch automation/bors/try || isCiBranch automation/bors/auto; then echo "channel verification is only executed on PR builds" exit fi From 1af7813baa02ec2f05acbaae5238b37bc0ebe5d7 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 7 Jan 2026 09:12:00 +0100 Subject: [PATCH 1670/3801] Document `WithFixture` --- .../crates/test-fixture/src/lib.rs | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index d81f27d7c3b1..ca68edd88c05 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -37,7 +37,110 @@ use triomphe::Arc; pub const WORKSPACE: base_db::SourceRootId = base_db::SourceRootId(0); +/// A trait for setting up test databases from fixture strings. +/// +/// Fixtures are strings containing Rust source code with optional metadata that describe +/// a project setup. This is the primary way to write tests for rust-analyzer without +/// having to depend on the entire sysroot. +/// +/// # Fixture Syntax +/// +/// ## Basic Structure +/// +/// A fixture without metadata is parsed into a single source file (`/main.rs`). +/// Metadata is added after a `//-` comment prefix. +/// +/// ```text +/// //- /main.rs +/// fn main() { +/// println!("Hello"); +/// } +/// ``` +/// +/// Note that the fixture syntax is optional and can be omitted if the test only requires +/// a simple single file. +/// +/// ## File Metadata +/// +/// Each file can have the following metadata after `//-`: +/// +/// - **Path** (required): Must start with `/`, e.g., `/main.rs`, `/lib.rs`, `/foo/bar.rs` +/// - **`crate:`**: Defines a new crate with this file as its root +/// - Optional version: `crate:foo@0.1.0,https://example.com/repo.git` +/// - **`deps:,`**: Dependencies (requires `crate:`) +/// - **`extern-prelude:,`**: Limits extern prelude to specified crates +/// - **`edition:`**: Rust edition (2015, 2018, 2021, 2024). Defaults to current. +/// - **`cfg:=,`**: Configuration options, e.g., `cfg:test,feature="foo"` +/// - **`env:=`**: Environment variables +/// - **`crate-attr:`**: Crate-level attributes, e.g., `crate-attr:no_std` +/// - **`new_source_root:local|library`**: Starts a new source root +/// - **`library`**: Marks crate as external library (not workspace member) +/// +/// ## Global Meta (must appear at the top, in order) +/// +/// - **`//- toolchain: nightly|stable`**: Sets the Rust toolchain (default: stable) +/// - **`//- target_data_layout: `**: LLVM data layout string +/// - **`//- target_arch: `**: Target architecture (default: x86_64) +/// - **`//- proc_macros: ,`**: Enables predefined test proc macros +/// - **`//- minicore: , `**: Includes subset of libcore +/// +/// ## Cursor Markers +/// +/// Use `$0` to mark cursor position(s) in the fixture: +/// - Single `$0`: marks a position (use with [`with_position`](Self::with_position)) +/// - Two `$0` markers: marks a range (use with [`with_range`](Self::with_range)) +/// - Escape as `\$0` if you need a literal `$0` +/// +/// # Examples +/// +/// ## Single file with cursor position +/// ```text +/// r#" +/// fn main() { +/// let x$0 = 42; +/// } +/// "# +/// ``` +/// +/// ## Multiple crates with dependencies +/// ```text +/// r#" +/// //- /main.rs crate:main deps:helper +/// use helper::greet; +/// fn main() { greet(); } +/// +/// //- /lib.rs crate:helper +/// pub fn greet() {} +/// "# +/// ``` +/// +/// ## Using minicore for lang items +/// ```text +/// r#" +/// //- minicore: option, result, iterator +/// //- /main.rs +/// fn foo() -> Option { Some(42) } +/// "# +/// ``` +/// +/// The available minicore flags are listed at the top of crates\test-utils\src\minicore.rs. +/// +/// ## Using test proc macros +/// ```text +/// r#" +/// //- proc_macros: identity, mirror +/// //- /main.rs crate:main deps:proc_macros +/// use proc_macros::identity; +/// +/// #[identity] +/// fn foo() {} +/// "# +/// ``` +/// +/// Available proc macros: `identity` (attr), `DeriveIdentity` (derive), `input_replace` (attr), +/// `mirror` (bang), `shorten` (bang) pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_single_file( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -50,6 +153,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, file) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_many_files( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -66,6 +170,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, files) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_files(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> Self { let mut db = Self::default(); @@ -75,6 +180,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { db } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_files_extra_proc_macros( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -88,6 +194,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { db } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_position(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Self, FilePosition) { let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture); @@ -95,6 +202,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, FilePosition { file_id, offset }) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_range(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Self, FileRange) { let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture); @@ -102,6 +210,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, FileRange { file_id, range }) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_range_or_offset( #[rust_analyzer::rust_fixture] ra_fixture: &str, From ad020937855df0af1dc7416be0b12d0b8c2a89a1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 7 Jan 2026 08:46:47 +0100 Subject: [PATCH 1671/3801] feat: Allow rust paths in symbol search --- .../rust-analyzer/crates/hir/src/symbols.rs | 72 +- .../crates/ide-db/src/symbol_index.rs | 664 +++++++++++++++++- 2 files changed, 724 insertions(+), 12 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 073142670d2a..544c759ed3a7 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -9,6 +9,7 @@ use hir_def::{ ModuleDefId, ModuleId, TraitId, db::DefDatabase, item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob}, + nameres::crate_def_map, per_ns::Item, src::{HasChildSource, HasSource}, visibility::{Visibility, VisibilityExplicitness}, @@ -20,9 +21,12 @@ use hir_ty::{ }; use intern::Symbol; use rustc_hash::FxHashMap; -use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, ToSmolStr, ast::HasName}; +use syntax::{ + AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, ToSmolStr, + ast::{HasModuleItem, HasName}, +}; -use crate::{HasCrate, Module, ModuleDef, Semantics}; +use crate::{Crate, HasCrate, Module, ModuleDef, Semantics}; /// The actual data that is stored in the index. It should be as compact as /// possible. @@ -57,6 +61,70 @@ impl DeclarationLocation { } } +impl<'db> FileSymbol<'db> { + /// Create a `FileSymbol` representing a crate's root module. + /// This is used for crate search queries like `::` or `::foo`. + pub fn for_crate_root(db: &'db dyn HirDatabase, krate: Crate) -> Option> { + let display_name = krate.display_name(db)?; + let crate_name = display_name.crate_name(); + let root_module = krate.root_module(db); + let def_map = crate_def_map(db, krate.into()); + let module_data = &def_map[root_module.into()]; + + // Get the definition source (the source file for crate roots) + let definition = module_data.origin.definition_source(db); + let hir_file_id = definition.file_id; + + // For a crate root, the "declaration" is the source file itself + // We use the entire file's syntax node as the location + let syntax_node = definition.value.node(); + let ptr = SyntaxNodePtr::new(&syntax_node); + + // For the name, we need to create a synthetic name pointer. + // We'll use the first token of the file as a placeholder since crate roots + // don't have an explicit name in the source. + // We create a name_ptr pointing to the start of the file. + let name_ptr = match &definition.value { + crate::ModuleSource::SourceFile(sf) => { + // Try to find the first item with a name as a reasonable location for focus + // This is a bit of a hack but works for navigation purposes + let first_item: Option = sf.items().next(); + if let Some(item) = first_item { + if let Some(name) = item.syntax().children().find_map(syntax::ast::Name::cast) { + AstPtr::new(&name).wrap_left() + } else { + // No name found, try to use a NameRef instead + if let Some(name_ref) = + item.syntax().descendants().find_map(syntax::ast::NameRef::cast) + { + AstPtr::new(&name_ref).wrap_right() + } else { + return None; + } + } + } else { + return None; + } + } + _ => return None, + }; + + let loc = DeclarationLocation { hir_file_id, ptr, name_ptr }; + + Some(FileSymbol { + name: Symbol::intern(crate_name.as_str()), + def: ModuleDef::Module(root_module), + loc, + container_name: None, + is_alias: false, + is_assoc: false, + is_import: false, + do_not_complete: Complete::Yes, + _marker: PhantomData, + }) + } +} + /// Represents an outstanding module that the symbol collector must collect symbols from. #[derive(Debug)] struct SymbolCollectorWork { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index 06e1f6bb4560..ca0d5ec1e5e6 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -55,12 +55,17 @@ use crate::RootDatabase; /// ``` #[derive(Debug, Clone)] pub struct Query { - /// The original search query string as provided by the user. - /// Used for the final matching check via [`SearchMode::check`]. + /// The item name to search for (last segment of the path, or full query if no path). + /// When empty with a non-empty `path_filter`, returns all items in that module. query: String, /// Lowercase version of [`Self::query`], pre-computed for efficiency. /// Used to build FST automata for case-insensitive index lookups. lowercased: String, + /// Path segments to filter by (all segments except the last). + /// Empty if no `::` in the original query. + path_filter: Vec, + /// If true, the first path segment must be a crate name (query started with `::`). + anchor_to_crate: bool, /// The search strategy to use when matching symbols. /// - [`SearchMode::Exact`]: Symbol name must exactly match the query. /// - [`SearchMode::Fuzzy`]: Symbol name must contain all query characters in order (subsequence match). @@ -100,10 +105,13 @@ pub struct Query { impl Query { pub fn new(query: String) -> Query { - let lowercased = query.to_lowercase(); + let (path_filter, item_query, anchor_to_crate) = Self::parse_path_query(&query); + let lowercased = item_query.to_lowercase(); Query { - query, + query: item_query, lowercased, + path_filter, + anchor_to_crate, only_types: false, libs: false, mode: SearchMode::Fuzzy, @@ -113,6 +121,74 @@ impl Query { } } + /// Parse a query string that may contain path segments. + /// + /// Returns (path_filter, item_query, anchor_to_crate) where: + /// - `path_filter`: Path segments to match (all but the last segment) + /// - `item_query`: The item name to search for (last segment) + /// - `anchor_to_crate`: Whether the first segment must be a crate name + fn parse_path_query(query: &str) -> (Vec, String, bool) { + // Check for leading :: (absolute path / crate search) + let anchor_to_crate = query.starts_with("::"); + let query = if anchor_to_crate { &query[2..] } else { query }; + + // Handle sole "::" - return all crates + if query.is_empty() && anchor_to_crate { + return (vec![], String::new(), true); + } + + // Check for trailing :: (module browsing - returns all items in module) + let return_all_in_module = query.ends_with("::"); + let query = if return_all_in_module { query.trim_end_matches("::") } else { query }; + + if !query.contains("::") { + // No path separator - single segment + if anchor_to_crate && !return_all_in_module { + // "::foo" - fuzzy search crate names only + return (vec![], query.to_string(), true); + } + if return_all_in_module { + // "foo::" - browse all items in module "foo" + // path_filter = ["foo"], query = "", anchor_to_crate = false/true + return (vec![query.to_string()], String::new(), anchor_to_crate); + } + // Plain "foo" - normal fuzzy search + return (vec![], query.to_string(), false); + } + + // Filter out empty segments (e.g., "foo::::bar" -> "foo::bar") + let segments: Vec<&str> = query.split("::").filter(|s| !s.is_empty()).collect(); + + if segments.is_empty() { + return (vec![], String::new(), anchor_to_crate); + } + + let path: Vec = + segments[..segments.len() - 1].iter().map(|s| s.to_string()).collect(); + let item = if return_all_in_module { + // All segments go to path, item is empty + let mut path = path; + path.push(segments.last().unwrap().to_string()); + return (path, String::new(), anchor_to_crate); + } else { + segments.last().unwrap_or(&"").to_string() + }; + + (path, item, anchor_to_crate) + } + + /// Returns true if this query should return all items in a module + /// (i.e., the original query ended with `::`) + fn is_module_browsing(&self) -> bool { + self.query.is_empty() && !self.path_filter.is_empty() + } + + /// Returns true if this query is searching for crates + /// (i.e., the query was "::" alone or "::foo" for fuzzy crate search) + fn is_crate_search(&self) -> bool { + self.anchor_to_crate && self.path_filter.is_empty() + } + pub fn only_types(&mut self) { self.only_types = true; } @@ -181,7 +257,28 @@ pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex<'_ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> { let _p = tracing::info_span!("world_symbols", query = ?query.query).entered(); - let indices: Vec<_> = if query.libs { + // Handle special case: "::" alone or "::foo" for crate search + if query.is_crate_search() { + return search_crates(db, &query); + } + + // If we have a path filter, resolve it to target modules first + let indices: Vec<_> = if !query.path_filter.is_empty() { + let target_modules = resolve_path_to_modules( + db, + &query.path_filter, + query.anchor_to_crate, + query.case_sensitive, + ); + + if target_modules.is_empty() { + return vec![]; // Path doesn't resolve to any module + } + + // Get symbol indices only for the resolved modules + target_modules.iter().map(|&module| SymbolIndex::module_symbols(db, module)).collect() + } else if query.libs { + // Original behavior for non-path queries searching libs LibraryRoots::get(db) .roots(db) .par_iter() @@ -192,6 +289,7 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> { .map(|&root| SymbolIndex::library_symbols(db, root)) .collect() } else { + // Original behavior for non-path queries searching local crates let mut crates = Vec::new(); for &root in LocalRoots::get(db).roots(db).iter() { @@ -204,13 +302,131 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> { }; let mut res = vec![]; - query.search::<()>(&indices, |f| { - res.push(f.clone()); - ControlFlow::Continue(()) - }); + + // For module browsing (empty query, non-empty path_filter), return all symbols + if query.is_module_browsing() { + for index in &indices { + for symbol in index.symbols.iter() { + // Apply existing filters (only_types, assoc_mode, exclude_imports, etc.) + if query.matches_symbol_filters(symbol) { + res.push(symbol.clone()); + } + } + } + } else { + // Normal search: use FST to match item name + query.search::<()>(&indices, |f| { + res.push(f.clone()); + ControlFlow::Continue(()) + }); + } + res } +/// Search for crates by name (handles "::" and "::foo" queries) +fn search_crates<'db>(db: &'db RootDatabase, query: &Query) -> Vec> { + let mut res = vec![]; + + for krate in Crate::all(db) { + let Some(display_name) = krate.display_name(db) else { continue }; + let crate_name = display_name.crate_name().as_str(); + + // If query is empty (sole "::"), return all crates + // Otherwise, fuzzy match the crate name + let matches = if query.query.is_empty() { + true + } else { + query.mode.check(&query.query, query.case_sensitive, crate_name) + }; + + if matches { + // Create a FileSymbol for the crate's root module + if let Some(symbol) = hir::symbols::FileSymbol::for_crate_root(db, krate) { + res.push(symbol); + } + } + } + + res +} + +/// Resolve a path filter to the target module(s) it points to. +/// Returns the modules whose symbol indices should be searched. +/// +/// The path_filter contains segments like ["std", "vec"] for a query like "std::vec::Vec". +/// We resolve this by: +/// 1. Finding crates matching the first segment +/// 2. Walking down the module tree following subsequent segments +fn resolve_path_to_modules( + db: &dyn HirDatabase, + path_filter: &[String], + anchor_to_crate: bool, + case_sensitive: bool, +) -> Vec { + let [first_segment, rest_segments @ ..] = path_filter else { + return vec![]; + }; + + // Helper for name comparison + let names_match = |actual: &str, expected: &str| -> bool { + if case_sensitive { actual == expected } else { actual.eq_ignore_ascii_case(expected) } + }; + + // Find crates matching the first segment + let matching_crates: Vec = Crate::all(db) + .into_iter() + .filter(|krate| { + krate + .display_name(db) + .is_some_and(|name| names_match(name.crate_name().as_str(), first_segment)) + }) + .collect(); + + // If anchor_to_crate is true, first segment MUST be a crate name + // If anchor_to_crate is false, first segment could be a crate OR a module in local crates + let mut candidate_modules: Vec = vec![]; + + // Add crate root modules for matching crates + for krate in matching_crates { + candidate_modules.push(krate.root_module(db)); + } + + // If not anchored to crate, also search for modules matching first segment in local crates + if !anchor_to_crate { + for &root in LocalRoots::get(db).roots(db).iter() { + for &krate in db.source_root_crates(root).iter() { + let root_module = Crate::from(krate).root_module(db); + for child in root_module.children(db) { + if let Some(name) = child.name(db) { + if names_match(name.as_str(), first_segment) { + candidate_modules.push(child); + } + } + } + } + } + } + + // Walk down the module tree for remaining path segments + for segment in rest_segments { + candidate_modules = candidate_modules + .into_iter() + .flat_map(|module| { + module.children(db).filter(|child| { + child.name(db).is_some_and(|name| names_match(name.as_str(), segment)) + }) + }) + .collect(); + + if candidate_modules.is_empty() { + break; + } + } + + candidate_modules +} + #[derive(Default)] pub struct SymbolIndex<'db> { symbols: Box<[FileSymbol<'db>]>, @@ -382,12 +598,14 @@ impl<'db> SymbolIndex<'db> { } impl Query { + /// Search symbols in the given indices. pub(crate) fn search<'db, T>( - self, + &self, indices: &[&'db SymbolIndex<'db>], cb: impl FnMut(&'db FileSymbol<'db>) -> ControlFlow, ) -> Option { let _p = tracing::info_span!("symbol_index::Query::search").entered(); + let mut op = fst::map::OpBuilder::new(); match self.mode { SearchMode::Exact => { @@ -466,6 +684,41 @@ impl Query { (true, AssocSearchMode::Exclude) | (false, AssocSearchMode::AssocItemsOnly) ) } + + /// Check if a symbol passes all filters except name matching. + /// Used for module browsing where we want all items in a module. + fn matches_symbol_filters(&self, symbol: &FileSymbol<'_>) -> bool { + // Check only_types filter + if self.only_types + && !matches!( + symbol.def, + hir::ModuleDef::Adt(..) + | hir::ModuleDef::TypeAlias(..) + | hir::ModuleDef::BuiltinType(..) + | hir::ModuleDef::Trait(..) + ) + { + return false; + } + + // Check assoc_mode filter + if !self.matches_assoc_mode(symbol.is_assoc) { + return false; + } + + // Check exclude_imports filter + if self.exclude_imports && symbol.is_import { + return false; + } + + // Check underscore prefix + let ignore_underscore_prefixed = !self.query.starts_with("__"); + if ignore_underscore_prefixed && symbol.name.as_str().starts_with("__") { + return false; + } + + true + } } #[cfg(test)] @@ -622,4 +875,395 @@ pub struct Foo; let symbols = world_symbols(&db, query); expect_file!["./test_data/test_symbols_exclude_imports.txt"].assert_debug_eq(&symbols); } + + #[test] + fn test_parse_path_query() { + // Plain query - no path + let (path, item, anchor) = Query::parse_path_query("Item"); + assert_eq!(path, Vec::::new()); + assert_eq!(item, "Item"); + assert!(!anchor); + + // Path with item + let (path, item, anchor) = Query::parse_path_query("foo::Item"); + assert_eq!(path, vec!["foo"]); + assert_eq!(item, "Item"); + assert!(!anchor); + + // Multi-segment path + let (path, item, anchor) = Query::parse_path_query("foo::bar::Item"); + assert_eq!(path, vec!["foo", "bar"]); + assert_eq!(item, "Item"); + assert!(!anchor); + + // Leading :: (anchor to crate) + let (path, item, anchor) = Query::parse_path_query("::std::vec::Vec"); + assert_eq!(path, vec!["std", "vec"]); + assert_eq!(item, "Vec"); + assert!(anchor); + + // Just "::" - return all crates + let (path, item, anchor) = Query::parse_path_query("::"); + assert_eq!(path, Vec::::new()); + assert_eq!(item, ""); + assert!(anchor); + + // "::foo" - fuzzy search crate names + let (path, item, anchor) = Query::parse_path_query("::foo"); + assert_eq!(path, Vec::::new()); + assert_eq!(item, "foo"); + assert!(anchor); + + // Trailing :: (module browsing) + let (path, item, anchor) = Query::parse_path_query("foo::"); + assert_eq!(path, vec!["foo"]); + assert_eq!(item, ""); + assert!(!anchor); + + // Full path with trailing :: + let (path, item, anchor) = Query::parse_path_query("foo::bar::"); + assert_eq!(path, vec!["foo", "bar"]); + assert_eq!(item, ""); + assert!(!anchor); + + // Absolute path with trailing :: + let (path, item, anchor) = Query::parse_path_query("::std::vec::"); + assert_eq!(path, vec!["std", "vec"]); + assert_eq!(item, ""); + assert!(anchor); + + // Empty segments should be filtered + let (path, item, anchor) = Query::parse_path_query("foo::::bar"); + assert_eq!(path, vec!["foo"]); + assert_eq!(item, "bar"); + assert!(!anchor); + } + + #[test] + fn test_query_modes() { + // Test is_module_browsing + let query = Query::new("foo::".to_owned()); + assert!(query.is_module_browsing()); + assert!(!query.is_crate_search()); + + // Test is_crate_search with sole :: + let query = Query::new("::".to_owned()); + assert!(!query.is_module_browsing()); + assert!(query.is_crate_search()); + + // Test is_crate_search with ::foo + let query = Query::new("::foo".to_owned()); + assert!(!query.is_module_browsing()); + assert!(query.is_crate_search()); + + // Normal query should be neither + let query = Query::new("foo".to_owned()); + assert!(!query.is_module_browsing()); + assert!(!query.is_crate_search()); + + // Path query should be neither + let query = Query::new("foo::bar".to_owned()); + assert!(!query.is_module_browsing()); + assert!(!query.is_crate_search()); + } + + #[test] + fn test_path_search() { + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:main +mod inner; +pub struct RootStruct; + +//- /inner.rs +pub struct InnerStruct; +pub mod nested { + pub struct NestedStruct; +} +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // Search for item in specific module + let query = Query::new("inner::InnerStruct".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!(names.contains(&"InnerStruct"), "Expected InnerStruct in {:?}", names); + + // Search for item in nested module + let query = Query::new("inner::nested::NestedStruct".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!(names.contains(&"NestedStruct"), "Expected NestedStruct in {:?}", names); + + // Search with crate prefix + let query = Query::new("main::inner::InnerStruct".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!(names.contains(&"InnerStruct"), "Expected InnerStruct in {:?}", names); + + // Wrong path should return empty + let query = Query::new("wrong::InnerStruct".to_owned()); + let symbols = world_symbols(&db, query); + assert!(symbols.is_empty(), "Expected empty results for wrong path"); + } + + #[test] + fn test_module_browsing() { + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:main +mod mymod; + +//- /mymod.rs +pub struct MyStruct; +pub fn my_func() {} +pub const MY_CONST: u32 = 1; +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // Browse all items in module + let query = Query::new("main::mymod::".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + + assert!(names.contains(&"MyStruct"), "Expected MyStruct in {:?}", names); + assert!(names.contains(&"my_func"), "Expected my_func in {:?}", names); + assert!(names.contains(&"MY_CONST"), "Expected MY_CONST in {:?}", names); + } + + #[test] + fn test_fuzzy_item_with_path() { + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:main +mod mymod; + +//- /mymod.rs +pub struct MyLongStructName; +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // Fuzzy match on item name with exact path + let query = Query::new("main::mymod::MyLong".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!( + names.contains(&"MyLongStructName"), + "Expected fuzzy match for MyLongStructName in {:?}", + names + ); + } + + #[test] + fn test_case_insensitive_path() { + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:main +mod MyMod; + +//- /MyMod.rs +pub struct MyStruct; +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // Case insensitive path matching (default) + let query = Query::new("main::mymod::MyStruct".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!(names.contains(&"MyStruct"), "Expected case-insensitive match in {:?}", names); + } + + #[test] + fn test_absolute_path_search() { + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:mycrate +mod inner; +pub struct CrateRoot; + +//- /inner.rs +pub struct InnerItem; +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // Absolute path with leading :: + let query = Query::new("::mycrate::inner::InnerItem".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!( + names.contains(&"InnerItem"), + "Expected InnerItem with absolute path in {:?}", + names + ); + + // Absolute path should NOT match if crate name is wrong + let query = Query::new("::wrongcrate::inner::InnerItem".to_owned()); + let symbols = world_symbols(&db, query); + assert!(symbols.is_empty(), "Expected empty results for wrong crate name"); + } + + #[test] + fn test_wrong_path_returns_empty() { + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:main +mod existing; + +//- /existing.rs +pub struct MyStruct; +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // Non-existent module path + let query = Query::new("nonexistent::MyStruct".to_owned()); + let symbols = world_symbols(&db, query); + assert!(symbols.is_empty(), "Expected empty results for non-existent path"); + + // Correct item, wrong module + let query = Query::new("wrongmod::MyStruct".to_owned()); + let symbols = world_symbols(&db, query); + assert!(symbols.is_empty(), "Expected empty results for wrong module"); + } + + #[test] + fn test_root_module_items() { + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:mylib +pub struct RootItem; +pub fn root_fn() {} +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // Items at crate root - path is just the crate name + let query = Query::new("mylib::RootItem".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!(names.contains(&"RootItem"), "Expected RootItem at crate root in {:?}", names); + + // Browse crate root + let query = Query::new("mylib::".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!( + names.contains(&"RootItem"), + "Expected RootItem when browsing crate root in {:?}", + names + ); + assert!( + names.contains(&"root_fn"), + "Expected root_fn when browsing crate root in {:?}", + names + ); + } + + #[test] + fn test_crate_search_all() { + // Test that sole "::" returns all crates + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:alpha +pub struct AlphaStruct; + +//- /beta.rs crate:beta +pub struct BetaStruct; + +//- /gamma.rs crate:gamma +pub struct GammaStruct; +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // Sole "::" should return all crates (as module symbols) + let query = Query::new("::".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + + assert!(names.contains(&"alpha"), "Expected alpha crate in {:?}", names); + assert!(names.contains(&"beta"), "Expected beta crate in {:?}", names); + assert!(names.contains(&"gamma"), "Expected gamma crate in {:?}", names); + assert_eq!(symbols.len(), 3, "Expected exactly 3 crates, got {:?}", names); + } + + #[test] + fn test_crate_search_fuzzy() { + // Test that "::foo" fuzzy-matches crate names + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:my_awesome_lib +pub struct AwesomeStruct; + +//- /other.rs crate:another_lib +pub struct OtherStruct; + +//- /foo.rs crate:foobar +pub struct FooStruct; +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // "::foo" should fuzzy-match crate names containing "foo" + let query = Query::new("::foo".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + + assert!(names.contains(&"foobar"), "Expected foobar crate in {:?}", names); + assert_eq!(symbols.len(), 1, "Expected only foobar crate, got {:?}", names); + + // "::awesome" should match my_awesome_lib + let query = Query::new("::awesome".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + + assert!(names.contains(&"my_awesome_lib"), "Expected my_awesome_lib crate in {:?}", names); + assert_eq!(symbols.len(), 1, "Expected only my_awesome_lib crate, got {:?}", names); + + // "::lib" should match multiple crates + let query = Query::new("::lib".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + + assert!(names.contains(&"my_awesome_lib"), "Expected my_awesome_lib in {:?}", names); + assert!(names.contains(&"another_lib"), "Expected another_lib in {:?}", names); + assert_eq!(symbols.len(), 2, "Expected 2 crates matching 'lib', got {:?}", names); + + // "::nonexistent" should return empty + let query = Query::new("::nonexistent".to_owned()); + let symbols = world_symbols(&db, query); + assert!(symbols.is_empty(), "Expected empty results for non-matching crate pattern"); + } } From 43e1604defa289b21cacf5f8e3c7d1ae741ecdca Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 7 Jan 2026 14:51:18 +0200 Subject: [PATCH 1672/3801] rustc book: fix grammar --- src/doc/rustc/src/remap-source-paths.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/remap-source-paths.md b/src/doc/rustc/src/remap-source-paths.md index ebe92d71158a..a499f9d3c77e 100644 --- a/src/doc/rustc/src/remap-source-paths.md +++ b/src/doc/rustc/src/remap-source-paths.md @@ -41,7 +41,7 @@ This example replaces all occurrences of `/home/user/project` in emitted paths w ## Caveats and Limitations -### Linkers generated paths +### Paths generated by linkers On some platforms like `x86_64-pc-windows-msvc`, the linker may embed absolute host paths and compiler arguments into debug info files (like `.pdb`) independently of `rustc`. From 5b4dbe02131e184a21cffea58f4550b1787edf9b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 7 Jan 2026 14:53:21 +0200 Subject: [PATCH 1673/3801] add missing commas --- src/doc/rustc/src/remap-source-paths.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/remap-source-paths.md b/src/doc/rustc/src/remap-source-paths.md index a499f9d3c77e..dc00278fac67 100644 --- a/src/doc/rustc/src/remap-source-paths.md +++ b/src/doc/rustc/src/remap-source-paths.md @@ -3,7 +3,7 @@ `rustc` supports remapping source paths prefixes **as a best effort** in all compiler generated output, including compiler diagnostics, debugging information, macro expansions, etc. -This is useful for normalizing build products, for example by removing the current directory +This is useful for normalizing build products, for example, by removing the current directory out of the paths emitted into object files. The remapping is done via the `--remap-path-prefix` option. @@ -54,7 +54,7 @@ The `--remap-path-prefix` option does not affect these linker-generated paths. ### Textual replacement only The remapping is strictly textual and does not account for different path separator conventions across -platforms. Care must be taken when specifying prefixes, especially on Windows where both `/` and `\` may +platforms. Care must be taken when specifying prefixes, especially on Windows, where both `/` and `\` may appear in paths. ### External tools From ea7ada90c61c4edc748c7a1a3c89c77ec5648b99 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Jan 2026 13:55:53 +0100 Subject: [PATCH 1674/3801] Update browser-ui-test version to `0.23.1` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef74853b77a5..0cba589d23f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "browser-ui-test": "^0.23.0", + "browser-ui-test": "^0.23.1", "es-check": "^9.4.4", "eslint": "^8.57.1", "typescript": "^5.8.3" From a928f3352d43ce4034e664aa310982657dc55c26 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 3 Jan 2026 13:06:54 +0100 Subject: [PATCH 1675/3801] Rename `tests/rustdoc` into `tests/rustdoc-html` --- rustfmt.toml | 2 +- src/bootstrap/src/core/build_steps/test.rs | 14 +++++++------- .../src/core/build_steps/test/compiletest.rs | 4 ++-- src/bootstrap/src/core/builder/cli_paths.rs | 2 +- .../builder/cli_paths/snapshots/x_test.snap | 5 ++--- .../snapshots/x_test_librustdoc_rustdoc.snap | 3 --- .../x_test_librustdoc_rustdoc_html.snap | 10 ++++++++++ .../cli_paths/snapshots/x_test_rustdoc.snap | 3 --- .../snapshots/x_test_rustdoc_html.snap | 7 +++++++ .../snapshots/x_test_skip_coverage.snap | 5 ++--- .../cli_paths/snapshots/x_test_tests.snap | 6 +++--- .../snapshots/x_test_tests_skip_coverage.snap | 6 +++--- .../src/core/builder/cli_paths/tests.rs | 2 ++ src/bootstrap/src/core/builder/mod.rs | 2 +- src/bootstrap/src/core/builder/tests.rs | 19 ++++++++----------- src/ci/citool/tests/test-jobs.yml | 2 +- .../host-x86_64/x86_64-gnu-gcc/Dockerfile | 2 +- src/librustdoc/html/render/write_shared.rs | 3 ++- src/tools/compiletest/src/common.rs | 4 ++-- src/tools/compiletest/src/directives.rs | 2 +- src/tools/compiletest/src/directives/tests.rs | 2 +- src/tools/compiletest/src/lib.rs | 6 +++--- src/tools/compiletest/src/runtest.rs | 4 ++-- src/tools/compiletest/src/runtest/rustdoc.rs | 2 +- src/tools/compiletest/src/rustdoc_gui_test.rs | 2 +- src/tools/opt-dist/src/tests.rs | 2 +- src/tools/tidy/src/features.rs | 2 +- tests/{rustdoc => rustdoc-html}/all.rs | 0 .../anchor-id-duplicate-method-name-25001.rs | 0 .../anchors/anchor-id-trait-method-15169.rs | 0 .../anchors/anchor-id-trait-tymethod-28478.rs | 0 .../anchors/anchors.no_const_anchor.html | 0 .../anchors/anchors.no_const_anchor2.html | 0 .../anchors/anchors.no_method_anchor.html | 0 .../anchors.no_trait_method_anchor.html | 0 .../anchors/anchors.no_tymethod_anchor.html | 0 .../anchors/anchors.no_type_anchor.html | 0 .../anchors/anchors.no_type_anchor2.html | 0 .../anchors/anchors.rs | 0 .../anchors/auxiliary/issue-86620-1.rs | 0 .../anchors/disambiguate-anchors-32890.rs | 0 .../disambiguate-anchors-header-29449.rs | 0 .../method-anchor-in-blanket-impl-86620.rs | 0 .../trait-impl-items-links-and-anchors.rs | 0 .../anon-fn-params.rs | 0 .../anonymous-lifetime.rs | 0 .../array-links.link_box_generic.html | 0 .../array-links.link_box_u32.html | 0 .../array-links.link_slice_generic.html | 0 .../array-links.link_slice_u32.html | 0 .../{rustdoc => rustdoc-html}/array-links.rs | 0 .../{rustdoc => rustdoc-html}/asm-foreign.rs | 0 .../{rustdoc => rustdoc-html}/asm-foreign2.rs | 0 .../asref-for-and-of-local-82465.rs | 0 .../assoc/assoc-fns.rs | 0 .../assoc/assoc-item-cast.rs | 0 .../assoc/assoc-type-bindings-20646.rs | 0 .../assoc/assoc-types.rs | 0 .../cross-crate-hidden-assoc-trait-items.rs | 0 .../assoc/auxiliary/issue-20646.rs | 0 .../assoc/auxiliary/issue-20727.rs | 0 .../assoc/auxiliary/normalize-assoc-item.rs | 0 .../cross-crate-hidden-assoc-trait-items.rs | 0 .../assoc/doc-assoc-item.rs | 0 .../assoc/inline-assoc-type-20727-bindings.rs | 0 .../inline-assoc-type-20727-bounds-deref.rs | 0 .../inline-assoc-type-20727-bounds-index.rs | 0 .../assoc/inline-assoc-type-20727-bounds.rs | 0 .../assoc/normalize-assoc-item.rs | 0 .../async/async-fn-opaque-item.rs | 0 .../async/async-fn.rs | 0 .../async/async-move-doctest.rs | 0 .../async/async-trait-sig.rs | 0 .../async/async-trait.rs | 0 .../async/auxiliary/async-trait-dep.rs | 0 .../attributes-2021-edition.rs | 0 .../attributes-inlining-108281.rs | 0 .../attributes-re-export-2021-edition.rs | 0 .../attributes-re-export.rs | 0 tests/{rustdoc => rustdoc-html}/attributes.rs | 0 .../auto/auto-impl-for-trait.rs | 0 .../auto/auto-impl-primitive.rs | 0 ...o-trait-bounds-by-associated-type-50159.rs | 0 ...-trait-bounds-inference-variables-54705.rs | 0 .../auto/auto-trait-bounds-where-51236.rs | 0 .../auto/auto-trait-negative-impl-55321.rs | 0 .../auto/auto-trait-not-send.rs | 0 .../auto/auto-traits.rs | 0 .../auto/auto_aliases.rs | 0 .../auto/auxiliary/auto-traits.rs | 0 .../auxiliary/all-item-types.rs | 0 .../auxiliary/cross_crate_generic_typedef.rs | 0 .../auxiliary/elided-lifetime.rs | 0 .../auxiliary/empty.rs | 0 .../auxiliary/enum-primitive.rs | 0 .../auxiliary/ext-anon-fn-params.rs | 0 .../auxiliary/ext-repr.rs | 0 .../auxiliary/ext-trait-aliases.rs | 0 .../auxiliary/inline-default-methods.rs | 0 .../auxiliary/issue-106421-force-unstable.rs | 0 .../auxiliary/issue-13698.rs | 0 .../auxiliary/issue-19190-3.rs | 0 .../auxiliary/issue-61592.rs | 0 .../auxiliary/issue-99221-aux.rs | 0 .../auxiliary/issue-99734-aux.rs | 0 .../jump-to-def-res-err-handling-aux.rs | 0 .../auxiliary/masked.rs | 0 .../auxiliary/mod-stackoverflow.rs | 0 .../auxiliary/reexp-stripped.rs | 0 .../auxiliary/remapped-paths.rs | 0 .../auxiliary/rustdoc-ffi.rs | 0 .../auxiliary/trait-visibility.rs | 0 .../auxiliary/unit-return.rs | 0 .../auxiliary/unsafe-binder-dep.rs | 0 .../auxiliary/unstable-trait.rs | 0 .../bad-codeblock-syntax.rs | 0 .../blank-line-in-doc-block-47197.rs | 0 .../bold-tag-101743.rs | 0 tests/{rustdoc => rustdoc-html}/bounds.rs | 0 tests/{rustdoc => rustdoc-html}/cap-lints.rs | 0 tests/{rustdoc => rustdoc-html}/cfg-bool.rs | 0 .../{rustdoc => rustdoc-html}/cfg-doctest.rs | 0 .../check-styled-link.rs | 0 tests/{rustdoc => rustdoc-html}/check.rs | 0 .../codeblock-title.rs | 0 .../comment-in-doctest.rs | 0 .../const-fn-76501.rs | 0 .../const-fn-effects.rs | 0 tests/{rustdoc => rustdoc-html}/const-fn.rs | 0 .../const-generics/add-impl.rs | 0 .../const-generics/auxiliary/extern_crate.rs | 0 .../const-generics/const-generic-defaults.rs | 0 .../const-generics/const-generic-slice.rs | 0 .../const-generics/const-generics-docs.rs | 0 .../const-generics/const-impl.rs | 0 .../const-param-type-references-generics.rs | 0 .../const-generics/generic_const_exprs.rs | 0 .../const-equate-pred.rs | 0 .../const-generics/type-alias.rs | 0 .../const-intrinsic.rs | 0 .../constant/assoc-consts-underscore.rs | 0 .../constant/assoc-consts-version.rs | 0 .../constant/assoc-consts.rs | 0 .../constant/associated-consts.rs | 0 .../constant/const-display.rs | 0 .../constant/const-doc.rs | 0 .../constant/const-effect-param.rs | 0 .../constant/const-trait-and-impl-methods.rs | 0 .../constant/const-underscore.rs | 0 .../constant/const-value-display.rs | 0 .../constant/const.rs | 0 ...m-with-associated-const-in-where-clause.rs | 0 .../constant/generic-const-items.rs | 0 .../constant/generic_const_exprs.rs | 0 .../constant/glob-shadowing-const.rs | 0 ...ide-complex-unevaluated-const-arguments.rs | 0 .../hide-complex-unevaluated-consts.rs | 0 .../ice-associated-const-equality-105952.rs | 0 .../constant/legacy-const-generic.rs | 0 .../constant/link-assoc-const.rs | 0 .../constant/redirect-const.rs | 0 .../constant/rfc-2632-const-trait-impl.rs | 0 .../constant/show-const-contents.rs | 0 .../constructor-imports.rs | 0 .../crate-doc-hidden-109695.rs | 0 .../crate-version-escape.rs | 0 .../crate-version-extra.rs | 0 .../crate-version.rs | 0 .../cargo-transitive-no-index/auxiliary/q.rs | 0 .../cargo-transitive-no-index/auxiliary/t.rs | 0 .../cargo-transitive-no-index/s.rs | 0 .../cargo-transitive/auxiliary/q.rs | 0 .../cargo-transitive/auxiliary/t.rs | 0 .../cross-crate-info/cargo-transitive/s.rs | 0 .../cargo-two-no-index/auxiliary/f.rs | 0 .../cross-crate-info/cargo-two-no-index/e.rs | 0 .../cross-crate-info/cargo-two/auxiliary/f.rs | 0 .../cross-crate-info/cargo-two/e.rs | 0 .../index-on-last/auxiliary/f.rs | 0 .../cross-crate-info/index-on-last/e.rs | 0 .../kitchen-sink/auxiliary/q.rs | 0 .../kitchen-sink/auxiliary/r.rs | 0 .../kitchen-sink/auxiliary/s.rs | 0 .../kitchen-sink/auxiliary/t.rs | 0 .../cross-crate-info/kitchen-sink/i.rs | 0 .../single-crate-baseline/q.rs | 0 .../single-crate-no-index/q.rs | 0 .../transitive/auxiliary/q.rs | 0 .../transitive/auxiliary/t.rs | 0 .../cross-crate-info/transitive/s.rs | 0 .../cross-crate-info/two/auxiliary/f.rs | 0 .../cross-crate-info/two/e.rs | 0 .../working-dir-examples/q.rs | 0 .../write-docs-somewhere-else/auxiliary/f.rs | 0 .../write-docs-somewhere-else/e.rs | 0 .../cross-crate-links.rs | 0 .../custom_code_classes.rs | 0 ...ecl-line-wrapping-empty-arg-list.decl.html | 0 .../decl-line-wrapping-empty-arg-list.rs | 0 .../decl-trailing-whitespace.declaration.html | 0 .../decl-trailing-whitespace.rs | 0 .../deep-structures.rs | 0 .../default-theme.rs | 0 .../default-trait-method-link.rs | 0 .../default-trait-method.rs | 0 .../demo-allocator-54478.rs | 0 .../deprecated-future-staged-api.rs | 0 .../deprecated-future.rs | 0 tests/{rustdoc => rustdoc-html}/deprecated.rs | 0 .../deref-methods-19190-foreign-type.rs | 0 .../deref-methods-19190-inline.rs | 0 .../deref-methods-19190.rs | 0 .../deref-mut-35169-2.rs | 0 .../deref-mut-35169.rs | 0 .../deref/deref-const-fn.rs | 0 .../deref/deref-methods-24686-target.rs | 0 .../deref/deref-multiple-impl-blocks.rs | 0 .../deref/deref-mut-methods.rs | 0 .../deref/deref-recursive-pathbuf.rs | 0 .../deref/deref-recursive.rs | 0 .../deref/deref-slice-core.rs | 0 .../deref/deref-to-primitive.rs | 0 .../deref/deref-typedef.rs | 0 .../deref/escape-deref-methods.rs | 0 .../deref/recursive-deref-sidebar.rs | 0 .../deref/recursive-deref.rs | 0 .../deref/sidebar-links-deref-100679.rs | 0 .../{rustdoc => rustdoc-html}/description.rs | 0 .../description_default.rs | 0 .../display-hidden-items.rs | 0 .../doc-attr-comment-mix-42760.rs | 0 .../doc-attribute.rs | 0 .../doc-auto-cfg-public-in-private.rs | 0 .../{rustdoc => rustdoc-html}/doc-auto-cfg.rs | 0 .../doc-cfg/doc-cfg-hide.rs | 0 .../doc-cfg/doc-cfg-implicit-gate.rs | 0 .../doc-cfg/doc-cfg-implicit.rs | 0 .../doc-cfg-inherit-from-module-79201.rs | 0 .../doc-cfg/doc-cfg-simplification.rs | 0 .../doc-cfg/doc-cfg-target-feature.rs | 0 .../doc-cfg/doc-cfg-traits.rs | 0 .../doc-cfg/doc-cfg.rs | 0 .../doc-cfg/duplicate-cfg.rs | 0 .../doc-hidden-crate.rs | 0 .../doc-hidden-method-13698.rs | 0 .../doc-on-keyword.rs | 0 .../doc-test-attr-18199.rs | 0 .../{rustdoc => rustdoc-html}/doc_auto_cfg.rs | 0 .../doc_auto_cfg_reexports.rs | 0 .../doctest/auxiliary/doctest-runtool.rs | 0 .../doctest/auxiliary/empty.rs | 0 .../doctest/doctest-cfg-feature-30252.rs | 0 .../doctest/doctest-crate-attributes-38129.rs | 0 ...doctest-escape-boring-41783.codeblock.html | 0 .../doctest/doctest-escape-boring-41783.rs | 0 .../doctest/doctest-hide-empty-line-23106.rs | 0 .../doctest/doctest-ignore-32556.rs | 0 .../doctest/doctest-include-43153.rs | 0 .../doctest/doctest-macro-38219.rs | 0 .../doctest/doctest-manual-crate-name.rs | 0 .../doctest-markdown-inline-parse-23744.rs | 0 ...octest-markdown-trailing-docblock-48377.rs | 0 ...doctest-multi-line-string-literal-25944.rs | 0 .../doctest/doctest-runtool.rs | 0 .../doctest/ignore-sometimes.rs | 0 .../document-hidden-items-15347.rs | 0 .../double-hyphen-to-dash.rs | 0 .../double-quote-escape.rs | 0 .../duplicate-flags.rs | 0 .../duplicate_impls/impls.rs | 0 .../sidebar-links-duplicate-impls-33054.rs | 0 .../dyn-compatibility.rs | 0 .../early-unindent.rs | 0 .../edition-doctest.rs | 0 .../{rustdoc => rustdoc-html}/edition-flag.rs | 0 .../elided-lifetime.rs | 0 .../empty-doc-comment.rs | 0 .../empty-mod-public.rs | 0 .../empty-section.rs | 0 .../empty-tuple-struct-118180.rs | 0 .../ensure-src-link.rs | 0 .../enum/auxiliary/enum-variant.rs | 0 .../enum/auxiliary/variant-struct.rs | 0 .../enum/enum-headings.rs | 0 .../enum/enum-non-exhaustive-108925.rs | 0 .../enum-variant-doc-hidden-field-88600.rs | 0 .../enum/enum-variant-fields-heading.rs | 0 .../enum-variant-fields-heading.variants.html | 0 .../enum/enum-variant-non_exhaustive.rs | 0 ...ariant-non_exhaustive.type-alias-code.html | 0 ...enum-variant-non_exhaustive.type-code.html | 0 .../enum/enum-variant-value.rs | 0 .../render-enum-variant-structlike-32395.rs | 0 .../enum/strip-enum-variant.no-not-shown.html | 0 .../enum/strip-enum-variant.rs | 0 .../extern/auxiliary/empty.rs | 0 .../extern/auxiliary/extern-links.rs | 0 .../extern/auxiliary/external-cross-doc.md | 0 .../extern/auxiliary/external-cross.rs | 0 .../extern/auxiliary/external-doc.md | 0 .../extern/auxiliary/html_root.rs | 0 .../extern/auxiliary/issue-30109-1.rs | 0 .../extern/auxiliary/no_html_root.rs | 0 .../extern/auxiliary/panic-item.rs | 0 .../extern/auxiliary/pub-extern-crate.rs | 0 .../rustdoc-extern-default-method.rs | 0 .../extern/auxiliary/rustdoc-extern-method.rs | 0 .../extern/auxiliary/variant-struct.rs | 0 .../duplicate-reexports-section-150211.rs | 0 ...tern-default-method.no_href_on_anchor.html | 0 .../extern/extern-default-method.rs | 0 .../extern/extern-fn-22038.rs | 0 .../extern/extern-html-alias.rs | 0 .../extern/extern-html-fallback.rs | 0 .../extern/extern-html-root-url-precedence.rs | 0 .../extern/extern-html-root-url.rs | 0 .../extern/extern-links.rs | 0 .../extern/extern-method.rs | 0 .../extern/external-cross.rs | 0 .../extern/external-doc.rs | 0 .../extern/hidden-extern-34025.rs | 0 .../extern/link-extern-crate-33178.rs | 0 .../extern/link-extern-crate-item-30109.rs | 0 .../extern/link-extern-crate-title-33178.rs | 0 .../extern/pub-extern-crate-150176.rs | 0 .../extern/pub-extern-crate.rs | 0 .../extern/unsafe-extern-blocks.rs | 0 .../extern/unused-extern-crate.rs | 0 ...long_typename.extremely_long_typename.html | 0 .../extremely_long_typename.rs | 0 .../feature-gate-doc_auto_cfg.rs | 0 tests/{rustdoc => rustdoc-html}/ffi.rs | 0 .../file-creation-111249.rs | 0 .../files-creation-hidden.rs | 0 tests/{rustdoc => rustdoc-html}/fn-bound.rs | 0 .../fn-pointer-arg-name.rs | 0 tests/{rustdoc => rustdoc-html}/fn-sidebar.rs | 0 tests/{rustdoc => rustdoc-html}/fn-type.rs | 0 ...te-definition-without-blank-line-100638.rs | 0 .../{rustdoc => rustdoc-html}/footnote-ids.rs | 0 .../footnote-in-summary.rs | 0 .../footnote-reference-ids.rs | 0 .../footnote-reference-in-footnote-def.rs | 0 .../force-target-feature.rs | 0 ...nstable-if-unmarked-106421-not-internal.rs | 0 .../force-unstable-if-unmarked-106421.rs | 0 .../{rustdoc => rustdoc-html}/foreigntype.rs | 0 .../gat-elided-lifetime-94683.rs | 0 .../gat-linkification-109488.rs | 0 .../generic-associated-types/gats.rs | 0 .../glob-shadowing.rs | 0 .../heading-levels-89309.rs | 0 .../heterogeneous-concat.rs | 0 .../{rustdoc => rustdoc-html}/hidden-line.rs | 0 .../hidden-methods.rs | 0 ...rait-methods-with-document-hidden-items.rs | 0 .../hidden-trait-methods.rs | 0 .../hide-unstable-trait.rs | 0 .../higher-ranked-trait-bounds.rs | 0 .../highlight-invalid-rust-12834.rs | 0 .../ice-type-error-19181.rs | 0 .../cross-crate-hidden-impl-parameter.rs | 0 .../impl/auxiliary/extern-impl-trait.rs | 0 .../impl/auxiliary/incoherent-impl-types.rs | 0 .../impl/auxiliary/issue-100204-aux.rs | 0 .../impl/auxiliary/issue-17476.rs | 0 .../impl/auxiliary/issue-21092.rs | 0 .../impl/auxiliary/issue-22025.rs | 0 .../impl/auxiliary/issue-53689.rs | 0 .../impl/auxiliary/precise-capturing.rs | 0 .../impl/auxiliary/real_gimli.rs | 0 .../impl/auxiliary/realcore.rs | 0 .../impl/auxiliary/rustdoc-default-impl.rs | 0 .../rustdoc-impl-parts-crosscrate.rs | 0 .../impl/blanket-impl-29503.rs | 0 .../impl/blanket-impl-78673.rs | 0 .../impl/cross-crate-hidden-impl-parameter.rs | 0 .../deduplicate-glob-import-impl-21474.rs | 0 .../impl/deduplicate-trait-impl-22025.rs | 0 .../impl/default-impl.rs | 0 .../impl/deprecated-impls.rs | 0 .../doc-hidden-trait-implementors-33069.rs | 0 .../impl/doc_auto_cfg_nested_impl.rs | 0 .../impl/duplicated_impl.rs | 0 .../impl/empty-impl-block.rs | 0 .../impl/empty-impls.rs | 0 .../impl/extern-impl-trait.rs | 0 .../impl/extern-impl.rs | 0 .../impl/foreign-implementors-js-43701.rs | 0 .../impl/generic-impl.rs | 0 .../impl/hidden-implementors-90781.rs | 0 .../impl/hidden-impls.rs | 0 .../impl/hidden-trait-struct-impls.rs | 0 ...e-mut-methods-if-no-derefmut-impl-74083.rs | 0 .../impl/impl-alias-substituted.rs | 0 .../impl/impl-assoc-type-21092.rs | 0 .../impl/impl-associated-items-order.rs | 0 .../impl/impl-associated-items-sidebar.rs | 0 .../impl/impl-blanket-53689.rs | 0 .../impl/impl-box.rs | 0 .../impl/impl-disambiguation.rs | 0 .../impl/impl-everywhere.rs | 0 .../impl/impl-in-const-block.rs | 0 .../impl/impl-on-ty-alias-issue-119015.rs | 0 .../impl/impl-parts-crosscrate.rs | 0 .../impl/impl-parts.rs | 0 .../impl/impl-ref-20175.rs | 0 .../impl/impl-trait-43869.rs | 0 .../impl/impl-trait-alias.rs | 0 .../impl/impl-trait-precise-capturing.rs | 0 .../impl/impl-type-parameter-33592.rs | 0 .../impl/implementor-stable-version.rs | 0 .../impl/implementors-unstable-75588.rs | 0 .../inline-impl-through-glob-import-100204.rs | 0 .../impl/manual_impl.rs | 0 .../method-link-foreign-trait-impl-17476.rs | 0 .../impl/module-impls.rs | 0 .../impl/must_implement_one_of.rs | 0 .../impl/negative-impl-no-items.rs | 0 .../impl/negative-impl-sidebar.rs | 0 .../impl/negative-impl.rs | 0 .../impl/return-impl-trait.rs | 0 .../impl/rustc-incoherent-impls.rs | 0 .../impl/same-crate-hidden-impl-parameter.rs | 0 .../sidebar-trait-impl-disambiguate-78701.rs | 0 .../impl/struct-implementations-title.rs | 0 .../impl/trait-impl.rs | 0 ...it-implementations-duplicate-self-45584.rs | 0 .../underscore-type-in-trait-impl-96381.rs | 0 .../impl/universal-impl-trait.rs | 0 .../unneeded-trait-implementations-title.rs | 0 .../import-remapped-paths.rs | 0 .../impossible-default.rs | 0 .../include_str_cut.rs | 0 tests/{rustdoc => rustdoc-html}/index-page.rs | 0 .../infinite-redirection-16265-1.rs | 0 .../infinite-redirection-16265-2.rs | 0 .../infinite-redirection.rs | 0 .../inherent-projections.rs | 0 .../inline-default-methods.rs | 0 .../inline-rename-34473.rs | 0 .../inline_cross/add-docs.rs | 0 .../inline_cross/assoc-const-equality.rs | 0 .../inline_cross/assoc-items.rs | 0 .../assoc_item_trait_bounds.out0.html | 0 .../assoc_item_trait_bounds.out2.html | 0 .../assoc_item_trait_bounds.out9.html | 0 .../inline_cross/assoc_item_trait_bounds.rs | 0 .../inline_cross/async-fn.rs | 0 .../inline_cross/attributes.rs | 0 .../inline_cross/auxiliary/add-docs.rs | 0 .../auxiliary/assoc-const-equality.rs | 0 .../inline_cross/auxiliary/assoc-items.rs | 0 .../auxiliary/assoc_item_trait_bounds.rs | 0 .../inline_cross/auxiliary/async-fn.rs | 0 .../inline_cross/auxiliary/attributes.rs | 0 .../auxiliary/const-effect-param.rs | 0 .../inline_cross/auxiliary/cross-glob.rs | 0 .../auxiliary/default-generic-args.rs | 0 .../auxiliary/default-trait-method.rs | 0 .../inline_cross/auxiliary/doc-auto-cfg.rs | 0 .../inline_cross/auxiliary/dyn_trait.rs | 0 .../early-late-bound-lifetime-params.rs | 0 .../inline_cross/auxiliary/fn-ptr-ty.rs | 0 .../auxiliary/generic-const-items.rs | 0 .../auxiliary/impl-inline-without-trait.rs | 0 .../inline_cross/auxiliary/impl-sized.rs | 0 .../inline_cross/auxiliary/impl_trait_aux.rs | 0 .../auxiliary/implementors_inline.rs | 0 .../inline_cross/auxiliary/issue-21801.rs | 0 .../inline_cross/auxiliary/issue-23207-1.rs | 0 .../inline_cross/auxiliary/issue-23207-2.rs | 0 .../inline_cross/auxiliary/issue-24183.rs | 0 .../inline_cross/auxiliary/issue-27362-aux.rs | 0 .../inline_cross/auxiliary/issue-29584.rs | 0 .../inline_cross/auxiliary/issue-33113.rs | 0 .../inline_cross/auxiliary/issue-46727.rs | 0 .../inline_cross/auxiliary/issue-57180.rs | 0 .../inline_cross/auxiliary/issue-76736-1.rs | 0 .../inline_cross/auxiliary/issue-76736-2.rs | 0 .../inline_cross/auxiliary/issue-85454.rs | 0 .../inline_cross/auxiliary/macro-vis.rs | 0 .../inline_cross/auxiliary/macros.rs | 0 .../auxiliary/non_lifetime_binders.rs | 0 .../inline_cross/auxiliary/proc_macro.rs | 0 .../reexport-with-anonymous-lifetime-98697.rs | 0 .../auxiliary/renamed-via-module.rs | 0 .../auxiliary/ret-pos-impl-trait-in-trait.rs | 0 .../auxiliary/rustdoc-hidden-sig.rs | 0 .../inline_cross/auxiliary/rustdoc-hidden.rs | 0 .../auxiliary/rustdoc-nonreachable-impls.rs | 0 .../auxiliary/rustdoc-trait-object-impl.rs | 0 .../inline_cross/auxiliary/trait-vis.rs | 0 .../inline_cross/auxiliary/use_crate.rs | 0 .../inline_cross/auxiliary/use_crate_2.rs | 0 .../inline_cross/const-effect-param.rs | 0 .../inline_cross/const-eval-46727.rs | 0 .../inline_cross/const-fn-27362.rs | 0 .../inline_cross/cross-glob.rs | 0 .../deduplicate-inlined-items-23207.rs | 0 .../inline_cross/default-generic-args.rs | 0 .../inline_cross/default-trait-method.rs | 0 .../inline_cross/doc-auto-cfg.rs | 0 .../doc-hidden-broken-link-28480.rs | 0 .../doc-hidden-extern-trait-impl-29584.rs | 0 .../doc-reachability-impl-31948-1.rs | 0 .../doc-reachability-impl-31948-2.rs | 0 .../doc-reachability-impl-31948.rs | 0 .../inline_cross/dyn_trait.rs | 0 .../early-late-bound-lifetime-params.rs | 0 .../inline_cross/fn-ptr-ty.rs | 0 .../inline_cross/generic-const-items.rs | 0 .../inline_cross/hidden-use.rs | 0 .../inline_cross/ice-import-crate-57180.rs | 0 .../inline_cross/impl-dyn-trait-32881.rs | 0 .../inline_cross/impl-inline-without-trait.rs | 0 .../inline_cross/impl-ref-33113.rs | 0 .../inline_cross/impl-sized.rs | 0 .../inline_cross/impl_trait.rs | 0 .../inline_cross/implementors-js.rs | 0 .../inline_cross/inline_hidden.rs | 0 .../inline_cross/macro-vis.rs | 0 .../inline_cross/macros.rs | 0 .../inline_cross/non_lifetime_binders.rs | 0 .../inline_cross/proc_macro.rs | 0 .../inline_cross/qpath-self-85454.rs | 0 .../reexport-with-anonymous-lifetime-98697.rs | 0 .../inline_cross/renamed-via-module.rs | 0 .../ret-pos-impl-trait-in-trait.rs | 0 .../inline_cross/rustc-private-76736-1.rs | 0 .../inline_cross/rustc-private-76736-2.rs | 0 .../inline_cross/rustc-private-76736-3.rs | 0 .../inline_cross/rustc-private-76736-4.rs | 0 ...unds-24183.method_no_where_self_sized.html | 0 .../inline_cross/self-sized-bounds-24183.rs | 0 .../inline_cross/sugar-closure-crate-21801.rs | 0 .../inline_cross/trait-vis.rs | 0 .../inline_cross/use_crate.rs | 0 .../blanket-impl-reexported-trait-94183.rs | 0 .../inline_local/doc-no-inline-32343.rs | 0 .../enum-variant-reexport-46766.rs | 0 .../fully-stable-path-is-better.rs | 0 .../glob-extern-document-private-items.rs | 0 .../inline_local/glob-extern.rs | 0 .../glob-private-document-private-items.rs | 0 .../inline_local/glob-private.rs | 0 .../inline_local/hidden-use.rs | 0 .../inline_local/macro_by_example.rs | 0 .../inline_local/parent-path-is-better.rs | 0 .../inline_local/please_inline.rs | 0 .../private-reexport-in-public-api-81141-2.rs | 0 .../private-reexport-in-public-api-81141.rs | 0 ...e-reexport-in-public-api-generics-81141.rs | 0 ...ate-reexport-in-public-api-hidden-81141.rs | 0 ...te-reexport-in-public-api-private-81141.rs | 0 .../inline_local/pub-re-export-28537.rs | 0 ...ed-macro-and-macro-export-sidebar-89852.rs | 0 .../inline_local/staged-inline.rs | 0 .../inline_local/trait-vis.rs | 0 tests/{rustdoc => rustdoc-html}/internal.rs | 0 .../intra-doc-crate/auxiliary/self.rs | 0 .../intra-doc-crate/self.rs | 0 .../intra-doc/anchors.rs | 0 .../intra-doc/assoc-reexport-super.rs | 0 .../intra-doc/associated-defaults.rs | 0 .../intra-doc/associated-items.rs | 0 .../intra-doc/auxiliary/empty.rs | 0 .../intra-doc/auxiliary/empty2.rs | 0 .../auxiliary/extern-builtin-type-impl-dep.rs | 0 .../auxiliary/extern-inherent-impl-dep.rs | 0 .../auxiliary/intra-link-extern-crate.rs | 0 .../intra-doc/auxiliary/intra-link-pub-use.rs | 0 .../intra-link-reexport-additional-docs.rs | 0 .../auxiliary/intra-links-external-traits.rs | 0 .../intra-doc/auxiliary/issue-66159-1.rs | 0 .../intra-doc/auxiliary/my-core.rs | 0 .../intra-doc/auxiliary/proc-macro-macro.rs | 0 .../intra-doc/auxiliary/pub-struct.rs | 0 .../intra-doc/basic.rs | 0 .../intra-doc/builtin-macros.rs | 0 .../intra-doc/crate-relative-assoc.rs | 0 .../intra-doc/crate-relative.rs | 0 .../intra-doc/cross-crate/additional_doc.rs | 0 .../cross-crate/auxiliary/additional_doc.rs | 0 .../intra-doc/cross-crate/auxiliary/hidden.rs | 0 .../cross-crate/auxiliary/intra-doc-basic.rs | 0 .../auxiliary/intra-link-cross-crate-crate.rs | 0 .../cross-crate/auxiliary/macro_inner.rs | 0 .../intra-doc/cross-crate/auxiliary/module.rs | 0 .../cross-crate/auxiliary/proc_macro.rs | 0 .../cross-crate/auxiliary/submodule-inner.rs | 0 .../cross-crate/auxiliary/submodule-outer.rs | 0 .../intra-doc/cross-crate/auxiliary/traits.rs | 0 .../intra-doc/cross-crate/basic.rs | 0 .../intra-doc/cross-crate/crate.rs | 0 .../intra-doc/cross-crate/hidden.rs | 0 .../intra-doc/cross-crate/macro.rs | 0 .../intra-doc/cross-crate/module.rs | 0 .../intra-doc/cross-crate/submodule-inner.rs | 0 .../intra-doc/cross-crate/submodule-outer.rs | 0 .../intra-doc/cross-crate/traits.rs | 0 .../intra-doc/deps.rs | 0 .../intra-doc/disambiguators-removed.rs | 0 .../intra-doc/email-address.rs | 0 .../intra-doc/enum-self-82209.rs | 0 .../intra-doc/enum-struct-field.rs | 0 .../intra-doc/extern-builtin-type-impl.rs | 0 .../extern-crate-only-used-in-link.rs | 0 .../intra-doc/extern-crate.rs | 0 .../intra-doc/extern-inherent-impl.rs | 0 .../intra-doc/extern-reference-link.rs | 0 .../intra-doc/extern-type.rs | 0 .../intra-doc/external-traits.rs | 0 .../intra-doc/field.rs | 0 .../intra-doc/filter-out-private.rs | 0 .../intra-doc/generic-params.rs | 0 .../intra-doc/generic-trait-impl.rs | 0 .../intra-doc/ice-intra-doc-links-107995.rs | 0 .../intra-doc/in-bodies.rs | 0 .../intra-doc/inherent-associated-types.rs | 0 .../intra-doc-link-method-trait-impl-72340.rs | 0 .../intra-doc/libstd-re-export.rs | 0 .../intra-doc/link-in-footnotes-132208.rs | 0 ...ame-name-different-disambiguator-108459.rs | 0 .../intra-doc/link-to-proc-macro.rs | 0 .../intra-doc/macro-caching-144965.rs | 0 .../intra-doc/macros-disambiguators.rs | 0 .../intra-doc/mod-ambiguity.rs | 0 .../intra-doc/mod-relative.rs | 0 .../module-scope-name-resolution-55364.rs | 0 .../intra-doc/nested-use.rs | 0 .../intra-doc/no-doc-primitive.rs | 0 .../intra-doc/non-path-primitives.rs | 0 .../intra-doc/prim-assoc.rs | 0 .../intra-doc/prim-associated-traits.rs | 0 .../intra-doc/prim-methods-external-core.rs | 0 .../intra-doc/prim-methods-local.rs | 0 .../intra-doc/prim-methods.rs | 0 .../intra-doc/prim-precedence.rs | 0 .../intra-doc/prim-self.rs | 0 .../intra-doc/primitive-disambiguators.rs | 0 .../intra-doc/primitive-non-default-impl.rs | 0 .../intra-doc/private-failures-ignored.rs | 0 .../intra-doc/private.rs | 0 .../intra-doc/proc-macro.rs | 0 .../intra-doc/pub-use.rs | 0 .../intra-doc/raw-ident-self.rs | 0 .../intra-doc/reexport-additional-docs.rs | 0 .../same-name-different-crates-66159.rs | 0 .../intra-doc/self-cache.rs | 0 .../intra-doc/self.rs | 0 .../intra-doc/trait-impl.rs | 0 .../intra-doc/trait-item.rs | 0 .../intra-doc/true-false.rs | 0 .../intra-doc/type-alias-primitive.rs | 0 .../intra-doc/type-alias.rs | 0 .../invalid$crate$name.rs | 0 .../item-desc-list-at-start.item-table.html | 0 .../item-desc-list-at-start.rs | 0 .../jump-to-def/assoc-items.rs | 0 .../jump-to-def/assoc-types.rs | 0 .../jump-to-def/auxiliary/symbols.rs | 0 .../jump-to-def/derive-macro.rs | 0 .../jump-to-def/doc-links-calls.rs | 0 .../jump-to-def/doc-links.rs | 0 .../jump-to-def/macro.rs | 0 .../jump-to-def/no-body-items.rs | 0 .../jump-to-def/non-local-method.rs | 0 .../jump-to-def/patterns.rs | 0 .../jump-to-def/prelude-types.rs | 0 .../jump-to-def/shebang.rs | 0 tests/{rustdoc => rustdoc-html}/keyword.rs | 0 .../lifetime-name.rs | 0 .../{rustdoc => rustdoc-html}/line-breaks.rs | 0 .../link-on-path-with-generics.rs | 0 .../link-title-escape.rs | 0 .../links-in-headings.rs | 0 .../logo-class-default.rs | 0 .../logo-class-rust.rs | 0 tests/{rustdoc => rustdoc-html}/logo-class.rs | 0 .../field-followed-by-exclamation.rs | 0 .../macro-expansion/type-macro-expansion.rs | 0 .../macro/auxiliary/external-macro-src.rs | 0 .../macro/auxiliary/issue-99221-aux.rs | 0 .../macro/auxiliary/macro_pub_in_module.rs | 0 .../macro/auxiliary/one-line-expand.rs | 0 .../macro/auxiliary/pub-use-extern-macros.rs | 0 .../macro/compiler-derive-proc-macro.rs | 0 .../macro/const-rendering-macros-33302.rs | 0 .../macro/decl_macro.rs | 0 .../macro/decl_macro_priv.rs | 0 .../macro/doc-proc-macro.rs | 0 .../macro/external-macro-src.rs | 0 .../macro/macro-const-display-115295.rs | 0 .../macro/macro-doc-comment-23812.rs | 0 .../macro/macro-export-crate-root-108231.rs | 0 ...o-generated-macro.macro_linebreak_pre.html | 0 ...o-generated-macro.macro_morestuff_pre.html | 0 .../macro/macro-generated-macro.rs | 0 .../macro/macro-higher-kinded-function.rs | 0 .../macro/macro-ice-16019.rs | 0 .../macro/macro-in-async-block.rs | 0 .../macro/macro-in-closure.rs | 0 .../macro/macro-indirect-use.rs | 0 .../macro/macro_expansion.rs | 0 .../macro/macro_pub_in_module.rs | 0 .../macro/macro_rules-matchers.rs | 0 .../{rustdoc => rustdoc-html}/macro/macros.rs | 0 .../multiple-macro-rules-w-same-name-99221.rs | 0 ...macro-rules-w-same-name-submodule-99221.rs | 0 .../macro/one-line-expand.rs | 0 .../macro/proc-macro.rs | 0 .../macro/pub-use-extern-macros.rs | 0 .../macro/rustc-macro-crate.rs | 0 .../markdown-60482.rs | 0 .../markdown-table-escape-pipe-27862.rs | 0 tests/{rustdoc => rustdoc-html}/masked.rs | 0 .../auxiliary/quebec.rs | 0 .../auxiliary/tango.rs | 0 .../cargo-transitive-read-write/sierra.rs | 0 .../auxiliary/quebec.rs | 0 .../auxiliary/romeo.rs | 0 .../auxiliary/sierra.rs | 0 .../auxiliary/tango.rs | 0 .../kitchen-sink-separate-dirs/indigo.rs | 0 .../no-merge-separate/auxiliary/quebec.rs | 0 .../no-merge-separate/auxiliary/tango.rs | 0 .../no-merge-separate/sierra.rs | 0 .../no-merge-write-anyway/auxiliary/quebec.rs | 0 .../no-merge-write-anyway/auxiliary/tango.rs | 0 .../no-merge-write-anyway/sierra.rs | 0 .../overwrite-but-include/auxiliary/quebec.rs | 0 .../overwrite-but-include/auxiliary/tango.rs | 0 .../overwrite-but-include/sierra.rs | 0 .../auxiliary/quebec.rs | 0 .../overwrite-but-separate/auxiliary/tango.rs | 0 .../overwrite-but-separate/sierra.rs | 0 .../overwrite/auxiliary/quebec.rs | 0 .../overwrite/auxiliary/tango.rs | 0 .../overwrite/sierra.rs | 0 .../single-crate-finalize/quebec.rs | 0 .../single-crate-read-write/quebec.rs | 0 .../single-crate-write-anyway/quebec.rs | 0 .../single-merge-none-useless-write/quebec.rs | 0 .../transitive-finalize/auxiliary/quebec.rs | 0 .../transitive-finalize/auxiliary/tango.rs | 0 .../transitive-finalize/sierra.rs | 0 .../transitive-merge-none/auxiliary/quebec.rs | 0 .../transitive-merge-none/auxiliary/tango.rs | 0 .../transitive-merge-none/sierra.rs | 0 .../auxiliary/quebec.rs | 0 .../auxiliary/tango.rs | 0 .../transitive-merge-read-write/sierra.rs | 0 .../transitive-no-info/auxiliary/quebec.rs | 0 .../transitive-no-info/auxiliary/tango.rs | 0 .../transitive-no-info/sierra.rs | 0 .../two-separate-out-dir/auxiliary/foxtrot.rs | 0 .../two-separate-out-dir/echo.rs | 0 .../{rustdoc => rustdoc-html}/method-list.rs | 0 ...ing-doc-comments-and-attrs.S1_top-doc.html | 0 ...ing-doc-comments-and-attrs.S2_top-doc.html | 0 ...ing-doc-comments-and-attrs.S3_top-doc.html | 0 .../mixing-doc-comments-and-attrs.rs | 0 .../mod-stackoverflow.rs | 0 .../multiple-foreigns-w-same-name-99734.rs | 0 .../multiple-import-levels.rs | 0 .../multiple-mods-w-same-name-99734.rs | 0 ...tiple-mods-w-same-name-doc-inline-83375.rs | 0 ...-w-same-name-doc-inline-last-item-83375.rs | 0 .../multiple-structs-w-same-name-99221.rs | 0 tests/{rustdoc => rustdoc-html}/mut-params.rs | 0 tests/{rustdoc => rustdoc-html}/namespaces.rs | 0 .../nested-items-issue-111415.rs | 0 .../nested-modules.rs | 0 .../no-run-still-checks-lints.rs | 0 .../no-stack-overflow-25295.rs | 0 .../no-unit-struct-field.rs | 0 .../non_lifetime_binders.rs | 0 ...-notable_trait-mut_t_is_not_an_iterator.rs | 0 .../doc-notable_trait-mut_t_is_not_ref_t.rs | 0 .../doc-notable_trait-negative.negative.html | 0 .../doc-notable_trait-negative.positive.html | 0 .../doc-notable_trait-negative.rs | 0 ...c-notable_trait-slice.bare_fn_matches.html | 0 .../notable-trait/doc-notable_trait-slice.rs | 0 .../doc-notable_trait.bare-fn.html | 0 .../notable-trait/doc-notable_trait.rs | 0 .../doc-notable_trait.some-struct-new.html | 0 .../doc-notable_trait.wrap-me.html | 0 ...oc-notable_trait_box_is_not_an_iterator.rs | 0 .../notable-trait/notable-trait-generics.rs | 0 .../spotlight-from-dependency.odd.html | 0 .../spotlight-from-dependency.rs | 0 tests/{rustdoc => rustdoc-html}/nul-error.rs | 0 .../playground-arg.rs | 0 .../playground-empty.rs | 0 .../playground-none.rs | 0 .../playground-syntax-error.rs | 0 tests/{rustdoc => rustdoc-html}/playground.rs | 0 .../primitive/auxiliary/issue-15318.rs | 0 .../primitive/auxiliary/primitive-doc.rs | 0 .../primitive/cross-crate-primitive-doc.rs | 0 .../primitive/no_std-primitive.rs | 0 .../primitive/no_std.rs | 0 .../primitive/primitive-generic-impl.rs | 0 .../primitive/primitive-link.rs | 0 .../primitive-raw-pointer-dox-15318-3.rs | 0 .../primitive-raw-pointer-link-15318.rs | 0 ...ive-raw-pointer-link-no-inlined-15318-2.rs | 0 .../primitive/primitive-reference.rs | 0 .../primitive/primitive-slice-auto-trait.rs | 0 .../primitive/primitive-tuple-auto-trait.rs | 0 .../primitive/primitive-tuple-variadic.rs | 0 .../primitive/primitive-unit-auto-trait.rs | 0 .../primitive/primitive.rs | 0 ...h-index-primitive-inherent-method-23511.rs | 0 .../private/doc-hidden-private-67851-both.rs | 0 .../doc-hidden-private-67851-hidden.rs | 0 .../doc-hidden-private-67851-neither.rs | 0 .../doc-hidden-private-67851-private.rs | 0 .../empty-impl-block-private-with-doc.rs | 0 .../private/empty-impl-block-private.rs | 0 .../private/empty-mod-private.rs | 0 .../private/enum-variant-private-46767.rs | 0 .../private/files-creation-private.rs | 0 .../private/hidden-private.rs | 0 ...ne-private-with-intermediate-doc-hidden.rs | 0 .../private/inner-private-110422.rs | 0 .../macro-document-private-duplicate.rs | 0 .../private/macro-document-private.rs | 0 .../private/macro-private-not-documented.rs | 0 .../missing-private-inlining-109258.rs | 0 .../private/private-fields-tuple-struct.rs | 0 .../private/private-non-local-fields-2.rs | 0 .../private/private-non-local-fields.rs | 0 .../private/private-type-alias.rs | 0 .../private/private-type-cycle-110629.rs | 0 .../private/private-use-decl-macro-47038.rs | 0 .../private/private-use.rs | 0 ...ic-impl-mention-private-generic-46380-2.rs | 0 .../private/traits-in-bodies-private.rs | 0 .../process-termination.rs | 0 tests/{rustdoc => rustdoc-html}/pub-method.rs | 0 .../pub-use-loop-107350.rs | 0 .../pub-use-root-path-95873.rs | 0 .../range-arg-pattern.rs | 0 .../raw-ident-eliminate-r-hashtag.rs | 0 .../read-more-unneeded.rs | 0 tests/{rustdoc => rustdoc-html}/recursion1.rs | 0 tests/{rustdoc => rustdoc-html}/recursion2.rs | 0 tests/{rustdoc => rustdoc-html}/recursion3.rs | 0 .../redirect-map-empty.rs | 0 .../{rustdoc => rustdoc-html}/redirect-map.rs | 0 .../redirect-rename.rs | 0 tests/{rustdoc => rustdoc-html}/redirect.rs | 0 .../reexport/alias-reexport.rs | 0 .../reexport/alias-reexport2.rs | 0 .../reexport/anonymous-reexport-108931.rs | 0 .../reexport/anonymous-reexport.rs | 0 .../reexport/auxiliary/alias-reexport.rs | 0 .../reexport/auxiliary/alias-reexport2.rs | 0 .../reexport/auxiliary/all-item-types.rs | 0 .../reexport/auxiliary/issue-28927-1.rs | 0 .../reexport/auxiliary/issue-28927-2.rs | 0 .../reexport/auxiliary/primitive-reexport.rs | 0 .../reexport/auxiliary/reexport-check.rs | 0 .../reexport/auxiliary/reexport-doc-aux.rs | 0 .../reexport/auxiliary/reexports.rs | 0 .../reexport/auxiliary/wrap-unnamable-type.rs | 0 .../reexport/blanket-reexport-item.rs | 0 .../reexport/cfg_doc_reexport.rs | 0 .../reexport/doc-hidden-reexports-109449.rs | 0 .../duplicated-glob-reexport-60522.rs | 0 .../reexport/enum-variant-reexport-35488.rs | 0 .../reexport/enum-variant.rs | 0 .../reexport/extern-135092.rs | 0 .../reexport/foreigntype-reexport.rs | 0 .../glob-reexport-attribute-merge-120487.rs | 0 ...b-reexport-attribute-merge-doc-auto-cfg.rs | 0 .../reexport/ice-reexport-crate-root-28927.rs | 0 .../import_trait_associated_functions.rs | 0 .../reexport/local-reexport-doc.rs | 0 .../reexport/merge-glob-and-non-glob.rs | 0 .../reexport/no-compiler-reexport.rs | 0 .../reexport/overlapping-reexport-105735-2.rs | 0 .../reexport/overlapping-reexport-105735.rs | 0 .../reexport/primitive-reexport.rs | 0 .../reexport/private-mod-override-reexport.rs | 0 .../pub-reexport-of-pub-reexport-46506.rs | 0 .../reexport/reexport-attr-merge.rs | 0 .../reexport/reexport-cfg.rs | 0 .../reexport/reexport-check.rs | 0 .../reexport/reexport-dep-foreign-fn.rs | 0 .../reexport-doc-hidden-inside-private.rs | 0 .../reexport/reexport-doc-hidden.rs | 0 .../reexport/reexport-doc.rs | 0 .../reexport/reexport-hidden-macro.rs | 0 .../reexport/reexport-macro.rs | 0 .../reexport/reexport-of-doc-hidden.rs | 0 .../reexport/reexport-of-reexport-108679.rs | 0 ...ability-tags-deprecated-and-portability.rs | 0 ...stability-tags-unstable-and-portability.rs | 0 .../reexport-trait-from-hidden-111064-2.rs | 0 .../reexport-trait-from-hidden-111064.rs | 0 .../reexport/reexports-of-same-name.rs | 0 .../reexport/reexports-priv.rs | 0 .../reexport/reexports.rs | 0 .../reexport/wrapped-unnamble-type-143222.rs | 0 .../remove-duplicates.rs | 0 .../remove-url-from-headings.rs | 0 tests/{rustdoc => rustdoc-html}/repr.rs | 0 .../resolve-ice-124363.rs | 0 .../return-type-notation.rs | 0 .../safe-intrinsic.rs | 0 .../sanitizer-option.rs | 0 .../search-index-summaries.rs | 0 .../{rustdoc => rustdoc-html}/search-index.rs | 0 .../short-docblock-codeblock.rs | 0 .../short-docblock.rs | 0 tests/{rustdoc => rustdoc-html}/short-line.md | 0 .../sidebar/module.rs | 0 .../sidebar/sidebar-all-page.rs | 0 .../sidebar/sidebar-items.rs | 0 .../sidebar/sidebar-link-generation.rs | 0 .../sidebar/sidebar-links-to-foreign-impl.rs | 0 .../sidebar/top-toc-html.rs | 0 .../sidebar/top-toc-idmap.rs | 0 .../sidebar/top-toc-nil.rs | 0 .../{rustdoc => rustdoc-html}/sized_trait.rs | 0 .../slice-links.link_box_generic.html | 0 .../slice-links.link_box_u32.html | 0 .../slice-links.link_slice_generic.html | 0 .../slice-links.link_slice_u32.html | 0 .../{rustdoc => rustdoc-html}/slice-links.rs | 0 .../{rustdoc => rustdoc-html}/smart-punct.rs | 0 tests/{rustdoc => rustdoc-html}/smoke.rs | 0 tests/{rustdoc => rustdoc-html}/sort-53812.rs | 0 .../sort-modules-by-appearance.rs | 0 .../assoc-type-source-link.rs | 0 .../auxiliary/issue-26606-macro.rs | 0 .../auxiliary/issue-34274.rs | 0 .../auxiliary/source-code-bar.rs | 0 .../auxiliary/source_code.rs | 0 .../auxiliary/src-links-external.rs | 0 .../check-source-code-urls-to-def-std.rs | 0 .../check-source-code-urls-to-def.rs | 0 .../source-code-pages/doc-hidden-source.rs | 0 .../failing-expansion-on-wrong-macro.rs | 0 .../source-code-pages/frontmatter.rs | 0 .../source-code-pages/html-no-source.rs | 0 .../source-code-pages/keyword-macros.rs | 0 .../source-code-pages/shebang.rs | 0 .../source-code-highlight.rs | 0 .../source-code-pages/source-file.rs | 0 .../source-code-pages/source-line-numbers.rs | 0 .../source-version-separator.rs | 0 .../src-link-external-macro-26606.rs | 0 .../source-code-pages/src-links-auto-impls.rs | 0 .../source-code-pages/src-links-external.rs | 0 .../src-links-implementor-43893.rs | 0 .../src-links-inlined-34274.rs | 0 .../source-code-pages/src-links.rs | 0 .../src-links/compiletest-ignore-dir | 0 .../source-code-pages/src-links/fizz.rs | 0 .../source-code-pages/src-links/mod.rs | 0 .../src-mod-path-absolute-26995.rs | 0 .../version-separator-without-source.rs | 0 tests/{rustdoc => rustdoc-html}/stability.rs | 0 .../staged-api-deprecated-unstable-32374.rs | 0 .../staged-api-feature-issue-27759.rs | 0 .../static-root-path.rs | 0 tests/{rustdoc => rustdoc-html}/static.rs | 0 ...rip-block-doc-comments-stars.docblock.html | 0 .../strip-block-doc-comments-stars.rs | 0 .../strip-priv-imports-pass-27104.rs | 0 .../struct-arg-pattern.rs | 0 .../{rustdoc => rustdoc-html}/struct-field.rs | 0 .../{rustdoc => rustdoc-html}/structfields.rs | 0 .../summary-codeblock-31899.rs | 0 .../summary-header-46377.rs | 0 .../summary-reference-link-30366.rs | 0 .../auto-trait-lifetimes-56822.rs | 0 .../synthetic_auto/basic.rs | 0 .../synthetic_auto/bounds.rs | 0 .../synthetic_auto/complex.rs | 0 .../synthetic_auto/crate-local.rs | 0 .../issue-72213-projection-lifetime.rs | 0 .../synthetic_auto/lifetimes.rs | 0 .../synthetic_auto/manual.rs | 0 .../synthetic_auto/negative.rs | 0 .../synthetic_auto/nested.rs | 0 .../synthetic_auto/no-redundancy.rs | 0 .../normalize-auto-trait-80233.rs | 0 .../synthetic_auto/overflow.rs | 0 .../synthetic_auto/project.rs | 0 .../synthetic_auto/self-referential.rs | 0 .../send-impl-conditional-60726.rs | 0 .../synthetic_auto/static-region.rs | 0 .../synthetic_auto/supertrait-bounds.rs | 0 tests/{rustdoc => rustdoc-html}/tab_title.rs | 0 .../table-in-docblock.rs | 0 .../target-feature.rs | 0 tests/{rustdoc => rustdoc-html}/task-lists.rs | 0 tests/{rustdoc => rustdoc-html}/test-lists.rs | 0 .../{rustdoc => rustdoc-html}/test-parens.rs | 0 .../test-strikethrough.rs | 0 .../test_option_check/bar.rs | 0 .../test_option_check/test.rs | 0 .../thread-local-src.rs | 0 tests/{rustdoc => rustdoc-html}/titles.rs | 0 .../toggle-item-contents.rs | 0 .../toggle-method.rs | 0 .../toggle-trait-fn.rs | 0 .../trait-aliases.rs | 0 .../trait-item-info.rs | 0 .../trait-self-link.rs | 0 .../trait-src-link.rs | 0 .../trait-visibility.rs | 0 .../traits-in-bodies.rs | 0 .../tuple-struct-fields-doc.rs | 0 .../tuple-struct-where-clause-34928.rs | 0 .../tuples.link1_i32.html | 0 .../tuples.link1_t.html | 0 .../tuples.link2_i32.html | 0 .../tuples.link2_t.html | 0 .../tuples.link2_tu.html | 0 .../tuples.link_unit.html | 0 tests/{rustdoc => rustdoc-html}/tuples.rs | 0 .../auxiliary/parent-crate-115718.rs | 0 .../type-alias/cross-crate-115718.rs | 0 .../type-alias/deeply-nested-112515.rs | 0 .../type-alias/deref-32077.rs | 0 .../type-alias/impl_trait_in_assoc_type.rs | 0 .../type-alias/primitive-local-link-121106.rs | 0 .../type-alias/repr.rs | 0 .../type-alias/same-crate-115718.rs | 0 .../type-layout-flag-required.rs | 0 .../{rustdoc => rustdoc-html}/type-layout.rs | 0 .../typedef-inner-variants-lazy_type_alias.rs | 0 .../typedef-inner-variants.rs | 0 tests/{rustdoc => rustdoc-html}/typedef.rs | 0 .../underscore-import-61592.rs | 0 tests/{rustdoc => rustdoc-html}/unindent.md | 0 tests/{rustdoc => rustdoc-html}/unindent.rs | 0 .../union-fields-html.rs | 0 tests/{rustdoc => rustdoc-html}/union.rs | 0 .../{rustdoc => rustdoc-html}/unit-return.rs | 0 .../unsafe-binder.rs | 0 tests/{rustdoc => rustdoc-html}/use-attr.rs | 0 .../useless_lifetime_bound.rs | 0 tests/{rustdoc => rustdoc-html}/variadic.rs | 0 .../viewpath-rename.rs | 0 .../viewpath-self.rs | 0 tests/{rustdoc => rustdoc-html}/visibility.rs | 0 .../where-clause-order.rs | 0 .../{rustdoc => rustdoc-html}/where-sized.rs | 0 .../where.SWhere_Echo_impl.html | 0 .../where.SWhere_Simd_item-decl.html | 0 .../where.SWhere_TraitWhere_item-decl.html | 0 .../where.alpha_trait_decl.html | 0 .../where.bravo_trait_decl.html | 0 .../where.charlie_fn_decl.html | 0 .../where.golf_type_alias_decl.html | 0 tests/{rustdoc => rustdoc-html}/where.rs | 0 .../whitespace-after-where-clause.enum.html | 0 .../whitespace-after-where-clause.enum2.html | 0 .../whitespace-after-where-clause.rs | 0 .../whitespace-after-where-clause.struct.html | 0 ...whitespace-after-where-clause.struct2.html | 0 .../whitespace-after-where-clause.trait.html | 0 .../whitespace-after-where-clause.trait2.html | 0 .../whitespace-after-where-clause.union.html | 0 .../whitespace-after-where-clause.union2.html | 0 .../without-redirect.rs | 0 tests/{rustdoc => rustdoc-html}/wrapping.rs | 0 triagebot.toml | 6 +++--- 1076 files changed, 69 insertions(+), 60 deletions(-) create mode 100644 src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc_html.snap create mode 100644 src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc_html.snap rename tests/{rustdoc => rustdoc-html}/all.rs (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchor-id-duplicate-method-name-25001.rs (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchor-id-trait-method-15169.rs (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchor-id-trait-tymethod-28478.rs (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchors.no_const_anchor.html (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchors.no_const_anchor2.html (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchors.no_method_anchor.html (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchors.no_trait_method_anchor.html (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchors.no_tymethod_anchor.html (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchors.no_type_anchor.html (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchors.no_type_anchor2.html (100%) rename tests/{rustdoc => rustdoc-html}/anchors/anchors.rs (100%) rename tests/{rustdoc => rustdoc-html}/anchors/auxiliary/issue-86620-1.rs (100%) rename tests/{rustdoc => rustdoc-html}/anchors/disambiguate-anchors-32890.rs (100%) rename tests/{rustdoc => rustdoc-html}/anchors/disambiguate-anchors-header-29449.rs (100%) rename tests/{rustdoc => rustdoc-html}/anchors/method-anchor-in-blanket-impl-86620.rs (100%) rename tests/{rustdoc => rustdoc-html}/anchors/trait-impl-items-links-and-anchors.rs (100%) rename tests/{rustdoc => rustdoc-html}/anon-fn-params.rs (100%) rename tests/{rustdoc => rustdoc-html}/anonymous-lifetime.rs (100%) rename tests/{rustdoc => rustdoc-html}/array-links.link_box_generic.html (100%) rename tests/{rustdoc => rustdoc-html}/array-links.link_box_u32.html (100%) rename tests/{rustdoc => rustdoc-html}/array-links.link_slice_generic.html (100%) rename tests/{rustdoc => rustdoc-html}/array-links.link_slice_u32.html (100%) rename tests/{rustdoc => rustdoc-html}/array-links.rs (100%) rename tests/{rustdoc => rustdoc-html}/asm-foreign.rs (100%) rename tests/{rustdoc => rustdoc-html}/asm-foreign2.rs (100%) rename tests/{rustdoc => rustdoc-html}/asref-for-and-of-local-82465.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/assoc-fns.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/assoc-item-cast.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/assoc-type-bindings-20646.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/assoc-types.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/auxiliary/issue-20646.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/auxiliary/issue-20727.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/auxiliary/normalize-assoc-item.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/cross-crate-hidden-assoc-trait-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/doc-assoc-item.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/inline-assoc-type-20727-bindings.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/inline-assoc-type-20727-bounds-deref.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/inline-assoc-type-20727-bounds-index.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/inline-assoc-type-20727-bounds.rs (100%) rename tests/{rustdoc => rustdoc-html}/assoc/normalize-assoc-item.rs (100%) rename tests/{rustdoc => rustdoc-html}/async/async-fn-opaque-item.rs (100%) rename tests/{rustdoc => rustdoc-html}/async/async-fn.rs (100%) rename tests/{rustdoc => rustdoc-html}/async/async-move-doctest.rs (100%) rename tests/{rustdoc => rustdoc-html}/async/async-trait-sig.rs (100%) rename tests/{rustdoc => rustdoc-html}/async/async-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/async/auxiliary/async-trait-dep.rs (100%) rename tests/{rustdoc => rustdoc-html}/attributes-2021-edition.rs (100%) rename tests/{rustdoc => rustdoc-html}/attributes-inlining-108281.rs (100%) rename tests/{rustdoc => rustdoc-html}/attributes-re-export-2021-edition.rs (100%) rename tests/{rustdoc => rustdoc-html}/attributes-re-export.rs (100%) rename tests/{rustdoc => rustdoc-html}/attributes.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auto-impl-for-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auto-impl-primitive.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auto-trait-bounds-by-associated-type-50159.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auto-trait-bounds-inference-variables-54705.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auto-trait-bounds-where-51236.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auto-trait-negative-impl-55321.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auto-trait-not-send.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auto-traits.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auto_aliases.rs (100%) rename tests/{rustdoc => rustdoc-html}/auto/auxiliary/auto-traits.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/all-item-types.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/cross_crate_generic_typedef.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/elided-lifetime.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/empty.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/enum-primitive.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/ext-anon-fn-params.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/ext-repr.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/ext-trait-aliases.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/inline-default-methods.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/issue-106421-force-unstable.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/issue-13698.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/issue-19190-3.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/issue-61592.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/issue-99221-aux.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/issue-99734-aux.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/jump-to-def-res-err-handling-aux.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/masked.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/mod-stackoverflow.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/reexp-stripped.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/remapped-paths.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/rustdoc-ffi.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/trait-visibility.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/unit-return.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/unsafe-binder-dep.rs (100%) rename tests/{rustdoc => rustdoc-html}/auxiliary/unstable-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/bad-codeblock-syntax.rs (100%) rename tests/{rustdoc => rustdoc-html}/blank-line-in-doc-block-47197.rs (100%) rename tests/{rustdoc => rustdoc-html}/bold-tag-101743.rs (100%) rename tests/{rustdoc => rustdoc-html}/bounds.rs (100%) rename tests/{rustdoc => rustdoc-html}/cap-lints.rs (100%) rename tests/{rustdoc => rustdoc-html}/cfg-bool.rs (100%) rename tests/{rustdoc => rustdoc-html}/cfg-doctest.rs (100%) rename tests/{rustdoc => rustdoc-html}/check-styled-link.rs (100%) rename tests/{rustdoc => rustdoc-html}/check.rs (100%) rename tests/{rustdoc => rustdoc-html}/codeblock-title.rs (100%) rename tests/{rustdoc => rustdoc-html}/comment-in-doctest.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-fn-76501.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-fn-effects.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-fn.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/add-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/auxiliary/extern_crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/const-generic-defaults.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/const-generic-slice.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/const-generics-docs.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/const-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/const-param-type-references-generics.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/generic_const_exprs.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/lazy_normalization_consts/const-equate-pred.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-generics/type-alias.rs (100%) rename tests/{rustdoc => rustdoc-html}/const-intrinsic.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/assoc-consts-underscore.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/assoc-consts-version.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/assoc-consts.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/associated-consts.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/const-display.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/const-doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/const-effect-param.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/const-trait-and-impl-methods.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/const-underscore.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/const-value-display.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/const.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/document-item-with-associated-const-in-where-clause.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/generic-const-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/generic_const_exprs.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/glob-shadowing-const.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/hide-complex-unevaluated-const-arguments.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/hide-complex-unevaluated-consts.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/ice-associated-const-equality-105952.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/legacy-const-generic.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/link-assoc-const.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/redirect-const.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/rfc-2632-const-trait-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/constant/show-const-contents.rs (100%) rename tests/{rustdoc => rustdoc-html}/constructor-imports.rs (100%) rename tests/{rustdoc => rustdoc-html}/crate-doc-hidden-109695.rs (100%) rename tests/{rustdoc => rustdoc-html}/crate-version-escape.rs (100%) rename tests/{rustdoc => rustdoc-html}/crate-version-extra.rs (100%) rename tests/{rustdoc => rustdoc-html}/crate-version.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-transitive-no-index/s.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-transitive/auxiliary/q.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-transitive/auxiliary/t.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-transitive/s.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-two-no-index/auxiliary/f.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-two-no-index/e.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-two/auxiliary/f.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/cargo-two/e.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/index-on-last/auxiliary/f.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/index-on-last/e.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/kitchen-sink/auxiliary/q.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/kitchen-sink/auxiliary/r.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/kitchen-sink/auxiliary/s.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/kitchen-sink/auxiliary/t.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/kitchen-sink/i.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/single-crate-baseline/q.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/single-crate-no-index/q.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/transitive/auxiliary/q.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/transitive/auxiliary/t.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/transitive/s.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/two/auxiliary/f.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/two/e.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/working-dir-examples/q.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-info/write-docs-somewhere-else/e.rs (100%) rename tests/{rustdoc => rustdoc-html}/cross-crate-links.rs (100%) rename tests/{rustdoc => rustdoc-html}/custom_code_classes.rs (100%) rename tests/{rustdoc => rustdoc-html}/decl-line-wrapping-empty-arg-list.decl.html (100%) rename tests/{rustdoc => rustdoc-html}/decl-line-wrapping-empty-arg-list.rs (100%) rename tests/{rustdoc => rustdoc-html}/decl-trailing-whitespace.declaration.html (100%) rename tests/{rustdoc => rustdoc-html}/decl-trailing-whitespace.rs (100%) rename tests/{rustdoc => rustdoc-html}/deep-structures.rs (100%) rename tests/{rustdoc => rustdoc-html}/default-theme.rs (100%) rename tests/{rustdoc => rustdoc-html}/default-trait-method-link.rs (100%) rename tests/{rustdoc => rustdoc-html}/default-trait-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/demo-allocator-54478.rs (100%) rename tests/{rustdoc => rustdoc-html}/deprecated-future-staged-api.rs (100%) rename tests/{rustdoc => rustdoc-html}/deprecated-future.rs (100%) rename tests/{rustdoc => rustdoc-html}/deprecated.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref-methods-19190-foreign-type.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref-methods-19190-inline.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref-methods-19190.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref-mut-35169-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref-mut-35169.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/deref-const-fn.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/deref-methods-24686-target.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/deref-multiple-impl-blocks.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/deref-mut-methods.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/deref-recursive-pathbuf.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/deref-recursive.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/deref-slice-core.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/deref-to-primitive.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/deref-typedef.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/escape-deref-methods.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/recursive-deref-sidebar.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/recursive-deref.rs (100%) rename tests/{rustdoc => rustdoc-html}/deref/sidebar-links-deref-100679.rs (100%) rename tests/{rustdoc => rustdoc-html}/description.rs (100%) rename tests/{rustdoc => rustdoc-html}/description_default.rs (100%) rename tests/{rustdoc => rustdoc-html}/display-hidden-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-attr-comment-mix-42760.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-attribute.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-auto-cfg-public-in-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-auto-cfg.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-cfg/doc-cfg-hide.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-cfg/doc-cfg-implicit-gate.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-cfg/doc-cfg-implicit.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-cfg/doc-cfg-inherit-from-module-79201.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-cfg/doc-cfg-simplification.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-cfg/doc-cfg-target-feature.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-cfg/doc-cfg-traits.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-cfg/doc-cfg.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-cfg/duplicate-cfg.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-hidden-crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-hidden-method-13698.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-on-keyword.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc-test-attr-18199.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc_auto_cfg.rs (100%) rename tests/{rustdoc => rustdoc-html}/doc_auto_cfg_reexports.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/auxiliary/doctest-runtool.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/auxiliary/empty.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-cfg-feature-30252.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-crate-attributes-38129.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-escape-boring-41783.codeblock.html (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-escape-boring-41783.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-hide-empty-line-23106.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-ignore-32556.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-include-43153.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-macro-38219.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-manual-crate-name.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-markdown-inline-parse-23744.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-markdown-trailing-docblock-48377.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-multi-line-string-literal-25944.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/doctest-runtool.rs (100%) rename tests/{rustdoc => rustdoc-html}/doctest/ignore-sometimes.rs (100%) rename tests/{rustdoc => rustdoc-html}/document-hidden-items-15347.rs (100%) rename tests/{rustdoc => rustdoc-html}/double-hyphen-to-dash.rs (100%) rename tests/{rustdoc => rustdoc-html}/double-quote-escape.rs (100%) rename tests/{rustdoc => rustdoc-html}/duplicate-flags.rs (100%) rename tests/{rustdoc => rustdoc-html}/duplicate_impls/impls.rs (100%) rename tests/{rustdoc => rustdoc-html}/duplicate_impls/sidebar-links-duplicate-impls-33054.rs (100%) rename tests/{rustdoc => rustdoc-html}/dyn-compatibility.rs (100%) rename tests/{rustdoc => rustdoc-html}/early-unindent.rs (100%) rename tests/{rustdoc => rustdoc-html}/edition-doctest.rs (100%) rename tests/{rustdoc => rustdoc-html}/edition-flag.rs (100%) rename tests/{rustdoc => rustdoc-html}/elided-lifetime.rs (100%) rename tests/{rustdoc => rustdoc-html}/empty-doc-comment.rs (100%) rename tests/{rustdoc => rustdoc-html}/empty-mod-public.rs (100%) rename tests/{rustdoc => rustdoc-html}/empty-section.rs (100%) rename tests/{rustdoc => rustdoc-html}/empty-tuple-struct-118180.rs (100%) rename tests/{rustdoc => rustdoc-html}/ensure-src-link.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/auxiliary/enum-variant.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/auxiliary/variant-struct.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/enum-headings.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/enum-non-exhaustive-108925.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/enum-variant-doc-hidden-field-88600.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/enum-variant-fields-heading.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/enum-variant-fields-heading.variants.html (100%) rename tests/{rustdoc => rustdoc-html}/enum/enum-variant-non_exhaustive.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/enum-variant-non_exhaustive.type-alias-code.html (100%) rename tests/{rustdoc => rustdoc-html}/enum/enum-variant-non_exhaustive.type-code.html (100%) rename tests/{rustdoc => rustdoc-html}/enum/enum-variant-value.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/render-enum-variant-structlike-32395.rs (100%) rename tests/{rustdoc => rustdoc-html}/enum/strip-enum-variant.no-not-shown.html (100%) rename tests/{rustdoc => rustdoc-html}/enum/strip-enum-variant.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/empty.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/extern-links.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/external-cross-doc.md (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/external-cross.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/external-doc.md (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/html_root.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/issue-30109-1.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/no_html_root.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/panic-item.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/pub-extern-crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/rustdoc-extern-default-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/rustdoc-extern-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/auxiliary/variant-struct.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/duplicate-reexports-section-150211.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/extern-default-method.no_href_on_anchor.html (100%) rename tests/{rustdoc => rustdoc-html}/extern/extern-default-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/extern-fn-22038.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/extern-html-alias.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/extern-html-fallback.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/extern-html-root-url-precedence.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/extern-html-root-url.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/extern-links.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/extern-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/external-cross.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/external-doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/hidden-extern-34025.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/link-extern-crate-33178.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/link-extern-crate-item-30109.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/link-extern-crate-title-33178.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/pub-extern-crate-150176.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/pub-extern-crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/unsafe-extern-blocks.rs (100%) rename tests/{rustdoc => rustdoc-html}/extern/unused-extern-crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/extremely_long_typename.extremely_long_typename.html (100%) rename tests/{rustdoc => rustdoc-html}/extremely_long_typename.rs (100%) rename tests/{rustdoc => rustdoc-html}/feature-gate-doc_auto_cfg.rs (100%) rename tests/{rustdoc => rustdoc-html}/ffi.rs (100%) rename tests/{rustdoc => rustdoc-html}/file-creation-111249.rs (100%) rename tests/{rustdoc => rustdoc-html}/files-creation-hidden.rs (100%) rename tests/{rustdoc => rustdoc-html}/fn-bound.rs (100%) rename tests/{rustdoc => rustdoc-html}/fn-pointer-arg-name.rs (100%) rename tests/{rustdoc => rustdoc-html}/fn-sidebar.rs (100%) rename tests/{rustdoc => rustdoc-html}/fn-type.rs (100%) rename tests/{rustdoc => rustdoc-html}/footnote-definition-without-blank-line-100638.rs (100%) rename tests/{rustdoc => rustdoc-html}/footnote-ids.rs (100%) rename tests/{rustdoc => rustdoc-html}/footnote-in-summary.rs (100%) rename tests/{rustdoc => rustdoc-html}/footnote-reference-ids.rs (100%) rename tests/{rustdoc => rustdoc-html}/footnote-reference-in-footnote-def.rs (100%) rename tests/{rustdoc => rustdoc-html}/force-target-feature.rs (100%) rename tests/{rustdoc => rustdoc-html}/force-unstable-if-unmarked-106421-not-internal.rs (100%) rename tests/{rustdoc => rustdoc-html}/force-unstable-if-unmarked-106421.rs (100%) rename tests/{rustdoc => rustdoc-html}/foreigntype.rs (100%) rename tests/{rustdoc => rustdoc-html}/generic-associated-types/gat-elided-lifetime-94683.rs (100%) rename tests/{rustdoc => rustdoc-html}/generic-associated-types/gat-linkification-109488.rs (100%) rename tests/{rustdoc => rustdoc-html}/generic-associated-types/gats.rs (100%) rename tests/{rustdoc => rustdoc-html}/glob-shadowing.rs (100%) rename tests/{rustdoc => rustdoc-html}/heading-levels-89309.rs (100%) rename tests/{rustdoc => rustdoc-html}/heterogeneous-concat.rs (100%) rename tests/{rustdoc => rustdoc-html}/hidden-line.rs (100%) rename tests/{rustdoc => rustdoc-html}/hidden-methods.rs (100%) rename tests/{rustdoc => rustdoc-html}/hidden-trait-methods-with-document-hidden-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/hidden-trait-methods.rs (100%) rename tests/{rustdoc => rustdoc-html}/hide-unstable-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/higher-ranked-trait-bounds.rs (100%) rename tests/{rustdoc => rustdoc-html}/highlight-invalid-rust-12834.rs (100%) rename tests/{rustdoc => rustdoc-html}/ice-type-error-19181.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/cross-crate-hidden-impl-parameter.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/extern-impl-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/incoherent-impl-types.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/issue-100204-aux.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/issue-17476.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/issue-21092.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/issue-22025.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/issue-53689.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/precise-capturing.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/real_gimli.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/realcore.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/rustdoc-default-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/blanket-impl-29503.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/blanket-impl-78673.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/cross-crate-hidden-impl-parameter.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/deduplicate-glob-import-impl-21474.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/deduplicate-trait-impl-22025.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/default-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/deprecated-impls.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/doc-hidden-trait-implementors-33069.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/doc_auto_cfg_nested_impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/duplicated_impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/empty-impl-block.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/empty-impls.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/extern-impl-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/extern-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/foreign-implementors-js-43701.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/generic-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/hidden-implementors-90781.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/hidden-impls.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/hidden-trait-struct-impls.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-alias-substituted.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-assoc-type-21092.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-associated-items-order.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-associated-items-sidebar.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-blanket-53689.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-box.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-disambiguation.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-everywhere.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-in-const-block.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-on-ty-alias-issue-119015.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-parts-crosscrate.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-parts.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-ref-20175.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-trait-43869.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-trait-alias.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-trait-precise-capturing.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/impl-type-parameter-33592.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/implementor-stable-version.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/implementors-unstable-75588.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/inline-impl-through-glob-import-100204.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/manual_impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/method-link-foreign-trait-impl-17476.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/module-impls.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/must_implement_one_of.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/negative-impl-no-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/negative-impl-sidebar.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/negative-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/return-impl-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/rustc-incoherent-impls.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/same-crate-hidden-impl-parameter.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/sidebar-trait-impl-disambiguate-78701.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/struct-implementations-title.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/trait-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/trait-implementations-duplicate-self-45584.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/underscore-type-in-trait-impl-96381.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/universal-impl-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/impl/unneeded-trait-implementations-title.rs (100%) rename tests/{rustdoc => rustdoc-html}/import-remapped-paths.rs (100%) rename tests/{rustdoc => rustdoc-html}/impossible-default.rs (100%) rename tests/{rustdoc => rustdoc-html}/include_str_cut.rs (100%) rename tests/{rustdoc => rustdoc-html}/index-page.rs (100%) rename tests/{rustdoc => rustdoc-html}/infinite-redirection-16265-1.rs (100%) rename tests/{rustdoc => rustdoc-html}/infinite-redirection-16265-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/infinite-redirection.rs (100%) rename tests/{rustdoc => rustdoc-html}/inherent-projections.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline-default-methods.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline-rename-34473.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/add-docs.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/assoc-const-equality.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/assoc-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/assoc_item_trait_bounds.out0.html (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/assoc_item_trait_bounds.out2.html (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/assoc_item_trait_bounds.out9.html (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/assoc_item_trait_bounds.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/async-fn.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/attributes.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/add-docs.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/assoc-const-equality.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/assoc-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/assoc_item_trait_bounds.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/async-fn.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/attributes.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/const-effect-param.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/cross-glob.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/default-generic-args.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/default-trait-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/doc-auto-cfg.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/dyn_trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/early-late-bound-lifetime-params.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/fn-ptr-ty.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/generic-const-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/impl-inline-without-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/impl-sized.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/impl_trait_aux.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/implementors_inline.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-21801.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-23207-1.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-23207-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-24183.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-27362-aux.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-29584.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-33113.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-46727.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-57180.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-76736-1.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-76736-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/issue-85454.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/macro-vis.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/macros.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/non_lifetime_binders.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/proc_macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/reexport-with-anonymous-lifetime-98697.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/renamed-via-module.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/rustdoc-hidden-sig.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/rustdoc-hidden.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/rustdoc-trait-object-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/trait-vis.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/use_crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/auxiliary/use_crate_2.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/const-effect-param.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/const-eval-46727.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/const-fn-27362.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/cross-glob.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/deduplicate-inlined-items-23207.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/default-generic-args.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/default-trait-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/doc-auto-cfg.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/doc-hidden-broken-link-28480.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/doc-hidden-extern-trait-impl-29584.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/doc-reachability-impl-31948-1.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/doc-reachability-impl-31948-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/doc-reachability-impl-31948.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/dyn_trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/early-late-bound-lifetime-params.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/fn-ptr-ty.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/generic-const-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/hidden-use.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/ice-import-crate-57180.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/impl-dyn-trait-32881.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/impl-inline-without-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/impl-ref-33113.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/impl-sized.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/impl_trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/implementors-js.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/inline_hidden.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/macro-vis.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/macros.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/non_lifetime_binders.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/proc_macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/qpath-self-85454.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/reexport-with-anonymous-lifetime-98697.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/renamed-via-module.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/ret-pos-impl-trait-in-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/rustc-private-76736-1.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/rustc-private-76736-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/rustc-private-76736-3.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/rustc-private-76736-4.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/self-sized-bounds-24183.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/sugar-closure-crate-21801.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/trait-vis.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_cross/use_crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/blanket-impl-reexported-trait-94183.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/doc-no-inline-32343.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/enum-variant-reexport-46766.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/fully-stable-path-is-better.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/glob-extern-document-private-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/glob-extern.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/glob-private-document-private-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/glob-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/hidden-use.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/macro_by_example.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/parent-path-is-better.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/please_inline.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/private-reexport-in-public-api-81141-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/private-reexport-in-public-api-81141.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/private-reexport-in-public-api-generics-81141.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/private-reexport-in-public-api-hidden-81141.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/private-reexport-in-public-api-private-81141.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/pub-re-export-28537.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/reexported-macro-and-macro-export-sidebar-89852.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/staged-inline.rs (100%) rename tests/{rustdoc => rustdoc-html}/inline_local/trait-vis.rs (100%) rename tests/{rustdoc => rustdoc-html}/internal.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc-crate/auxiliary/self.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc-crate/self.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/anchors.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/assoc-reexport-super.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/associated-defaults.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/associated-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/empty.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/empty2.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/extern-inherent-impl-dep.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/intra-link-extern-crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/intra-link-pub-use.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/intra-links-external-traits.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/issue-66159-1.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/my-core.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/proc-macro-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/auxiliary/pub-struct.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/basic.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/builtin-macros.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/crate-relative-assoc.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/crate-relative.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/additional_doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/additional_doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/hidden.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/macro_inner.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/module.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/proc_macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/submodule-inner.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/submodule-outer.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/auxiliary/traits.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/basic.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/hidden.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/module.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/submodule-inner.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/submodule-outer.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/cross-crate/traits.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/deps.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/disambiguators-removed.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/email-address.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/enum-self-82209.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/enum-struct-field.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/extern-builtin-type-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/extern-crate-only-used-in-link.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/extern-crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/extern-inherent-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/extern-reference-link.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/extern-type.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/external-traits.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/field.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/filter-out-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/generic-params.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/generic-trait-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/ice-intra-doc-links-107995.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/in-bodies.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/inherent-associated-types.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/intra-doc-link-method-trait-impl-72340.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/libstd-re-export.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/link-in-footnotes-132208.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/link-same-name-different-disambiguator-108459.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/link-to-proc-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/macro-caching-144965.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/macros-disambiguators.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/mod-ambiguity.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/mod-relative.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/module-scope-name-resolution-55364.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/nested-use.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/no-doc-primitive.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/non-path-primitives.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/prim-assoc.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/prim-associated-traits.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/prim-methods-external-core.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/prim-methods-local.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/prim-methods.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/prim-precedence.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/prim-self.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/primitive-disambiguators.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/primitive-non-default-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/private-failures-ignored.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/private.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/proc-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/pub-use.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/raw-ident-self.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/reexport-additional-docs.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/same-name-different-crates-66159.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/self-cache.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/self.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/trait-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/trait-item.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/true-false.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/type-alias-primitive.rs (100%) rename tests/{rustdoc => rustdoc-html}/intra-doc/type-alias.rs (100%) rename tests/{rustdoc => rustdoc-html}/invalid$crate$name.rs (100%) rename tests/{rustdoc => rustdoc-html}/item-desc-list-at-start.item-table.html (100%) rename tests/{rustdoc => rustdoc-html}/item-desc-list-at-start.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/assoc-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/assoc-types.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/auxiliary/symbols.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/derive-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/doc-links-calls.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/doc-links.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/no-body-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/non-local-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/patterns.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/prelude-types.rs (100%) rename tests/{rustdoc => rustdoc-html}/jump-to-def/shebang.rs (100%) rename tests/{rustdoc => rustdoc-html}/keyword.rs (100%) rename tests/{rustdoc => rustdoc-html}/lifetime-name.rs (100%) rename tests/{rustdoc => rustdoc-html}/line-breaks.rs (100%) rename tests/{rustdoc => rustdoc-html}/link-on-path-with-generics.rs (100%) rename tests/{rustdoc => rustdoc-html}/link-title-escape.rs (100%) rename tests/{rustdoc => rustdoc-html}/links-in-headings.rs (100%) rename tests/{rustdoc => rustdoc-html}/logo-class-default.rs (100%) rename tests/{rustdoc => rustdoc-html}/logo-class-rust.rs (100%) rename tests/{rustdoc => rustdoc-html}/logo-class.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro-expansion/field-followed-by-exclamation.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro-expansion/type-macro-expansion.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/auxiliary/external-macro-src.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/auxiliary/issue-99221-aux.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/auxiliary/macro_pub_in_module.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/auxiliary/one-line-expand.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/auxiliary/pub-use-extern-macros.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/compiler-derive-proc-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/const-rendering-macros-33302.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/decl_macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/decl_macro_priv.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/doc-proc-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/external-macro-src.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-const-display-115295.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-doc-comment-23812.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-export-crate-root-108231.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-generated-macro.macro_linebreak_pre.html (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-generated-macro.macro_morestuff_pre.html (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-generated-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-higher-kinded-function.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-ice-16019.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-in-async-block.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-in-closure.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro-indirect-use.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro_expansion.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro_pub_in_module.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macro_rules-matchers.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/macros.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/multiple-macro-rules-w-same-name-99221.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/multiple-macro-rules-w-same-name-submodule-99221.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/one-line-expand.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/proc-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/pub-use-extern-macros.rs (100%) rename tests/{rustdoc => rustdoc-html}/macro/rustc-macro-crate.rs (100%) rename tests/{rustdoc => rustdoc-html}/markdown-60482.rs (100%) rename tests/{rustdoc => rustdoc-html}/markdown-table-escape-pipe-27862.rs (100%) rename tests/{rustdoc => rustdoc-html}/masked.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/no-merge-separate/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/no-merge-write-anyway/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/overwrite-but-include/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/overwrite-but-separate/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/overwrite/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/overwrite/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/overwrite/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/single-crate-finalize/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/single-crate-read-write/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/single-crate-write-anyway/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-finalize/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-merge-none/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-merge-read-write/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/transitive-no-info/sierra.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs (100%) rename tests/{rustdoc => rustdoc-html}/merge-cross-crate-info/two-separate-out-dir/echo.rs (100%) rename tests/{rustdoc => rustdoc-html}/method-list.rs (100%) rename tests/{rustdoc => rustdoc-html}/mixing-doc-comments-and-attrs.S1_top-doc.html (100%) rename tests/{rustdoc => rustdoc-html}/mixing-doc-comments-and-attrs.S2_top-doc.html (100%) rename tests/{rustdoc => rustdoc-html}/mixing-doc-comments-and-attrs.S3_top-doc.html (100%) rename tests/{rustdoc => rustdoc-html}/mixing-doc-comments-and-attrs.rs (100%) rename tests/{rustdoc => rustdoc-html}/mod-stackoverflow.rs (100%) rename tests/{rustdoc => rustdoc-html}/multiple-foreigns-w-same-name-99734.rs (100%) rename tests/{rustdoc => rustdoc-html}/multiple-import-levels.rs (100%) rename tests/{rustdoc => rustdoc-html}/multiple-mods-w-same-name-99734.rs (100%) rename tests/{rustdoc => rustdoc-html}/multiple-mods-w-same-name-doc-inline-83375.rs (100%) rename tests/{rustdoc => rustdoc-html}/multiple-mods-w-same-name-doc-inline-last-item-83375.rs (100%) rename tests/{rustdoc => rustdoc-html}/multiple-structs-w-same-name-99221.rs (100%) rename tests/{rustdoc => rustdoc-html}/mut-params.rs (100%) rename tests/{rustdoc => rustdoc-html}/namespaces.rs (100%) rename tests/{rustdoc => rustdoc-html}/nested-items-issue-111415.rs (100%) rename tests/{rustdoc => rustdoc-html}/nested-modules.rs (100%) rename tests/{rustdoc => rustdoc-html}/no-run-still-checks-lints.rs (100%) rename tests/{rustdoc => rustdoc-html}/no-stack-overflow-25295.rs (100%) rename tests/{rustdoc => rustdoc-html}/no-unit-struct-field.rs (100%) rename tests/{rustdoc => rustdoc-html}/non_lifetime_binders.rs (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait-negative.negative.html (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait-negative.positive.html (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait-negative.rs (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait-slice.bare_fn_matches.html (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait-slice.rs (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait.bare-fn.html (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait.some-struct-new.html (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait.wrap-me.html (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/notable-trait-generics.rs (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/spotlight-from-dependency.odd.html (100%) rename tests/{rustdoc => rustdoc-html}/notable-trait/spotlight-from-dependency.rs (100%) rename tests/{rustdoc => rustdoc-html}/nul-error.rs (100%) rename tests/{rustdoc => rustdoc-html}/playground-arg.rs (100%) rename tests/{rustdoc => rustdoc-html}/playground-empty.rs (100%) rename tests/{rustdoc => rustdoc-html}/playground-none.rs (100%) rename tests/{rustdoc => rustdoc-html}/playground-syntax-error.rs (100%) rename tests/{rustdoc => rustdoc-html}/playground.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/auxiliary/issue-15318.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/auxiliary/primitive-doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/cross-crate-primitive-doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/no_std-primitive.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/no_std.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-generic-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-link.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-raw-pointer-dox-15318-3.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-raw-pointer-link-15318.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-reference.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-slice-auto-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-tuple-auto-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-tuple-variadic.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive-unit-auto-trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/primitive.rs (100%) rename tests/{rustdoc => rustdoc-html}/primitive/search-index-primitive-inherent-method-23511.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/doc-hidden-private-67851-both.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/doc-hidden-private-67851-hidden.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/doc-hidden-private-67851-neither.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/doc-hidden-private-67851-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/empty-impl-block-private-with-doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/empty-impl-block-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/empty-mod-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/enum-variant-private-46767.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/files-creation-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/hidden-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/inline-private-with-intermediate-doc-hidden.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/inner-private-110422.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/macro-document-private-duplicate.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/macro-document-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/macro-private-not-documented.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/missing-private-inlining-109258.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/private-fields-tuple-struct.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/private-non-local-fields-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/private-non-local-fields.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/private-type-alias.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/private-type-cycle-110629.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/private-use-decl-macro-47038.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/private-use.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/public-impl-mention-private-generic-46380-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/private/traits-in-bodies-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/process-termination.rs (100%) rename tests/{rustdoc => rustdoc-html}/pub-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/pub-use-loop-107350.rs (100%) rename tests/{rustdoc => rustdoc-html}/pub-use-root-path-95873.rs (100%) rename tests/{rustdoc => rustdoc-html}/range-arg-pattern.rs (100%) rename tests/{rustdoc => rustdoc-html}/raw-ident-eliminate-r-hashtag.rs (100%) rename tests/{rustdoc => rustdoc-html}/read-more-unneeded.rs (100%) rename tests/{rustdoc => rustdoc-html}/recursion1.rs (100%) rename tests/{rustdoc => rustdoc-html}/recursion2.rs (100%) rename tests/{rustdoc => rustdoc-html}/recursion3.rs (100%) rename tests/{rustdoc => rustdoc-html}/redirect-map-empty.rs (100%) rename tests/{rustdoc => rustdoc-html}/redirect-map.rs (100%) rename tests/{rustdoc => rustdoc-html}/redirect-rename.rs (100%) rename tests/{rustdoc => rustdoc-html}/redirect.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/alias-reexport.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/alias-reexport2.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/anonymous-reexport-108931.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/anonymous-reexport.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/alias-reexport.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/alias-reexport2.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/all-item-types.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/issue-28927-1.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/issue-28927-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/primitive-reexport.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/reexport-check.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/reexport-doc-aux.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/reexports.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/auxiliary/wrap-unnamable-type.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/blanket-reexport-item.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/cfg_doc_reexport.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/doc-hidden-reexports-109449.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/duplicated-glob-reexport-60522.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/enum-variant-reexport-35488.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/enum-variant.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/extern-135092.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/foreigntype-reexport.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/glob-reexport-attribute-merge-120487.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/ice-reexport-crate-root-28927.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/import_trait_associated_functions.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/local-reexport-doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/merge-glob-and-non-glob.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/no-compiler-reexport.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/overlapping-reexport-105735-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/overlapping-reexport-105735.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/primitive-reexport.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/private-mod-override-reexport.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/pub-reexport-of-pub-reexport-46506.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-attr-merge.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-cfg.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-check.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-dep-foreign-fn.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-doc-hidden-inside-private.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-doc-hidden.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-hidden-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-of-doc-hidden.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-of-reexport-108679.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-stability-tags-deprecated-and-portability.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-stability-tags-unstable-and-portability.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-trait-from-hidden-111064-2.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexport-trait-from-hidden-111064.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexports-of-same-name.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexports-priv.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/reexports.rs (100%) rename tests/{rustdoc => rustdoc-html}/reexport/wrapped-unnamble-type-143222.rs (100%) rename tests/{rustdoc => rustdoc-html}/remove-duplicates.rs (100%) rename tests/{rustdoc => rustdoc-html}/remove-url-from-headings.rs (100%) rename tests/{rustdoc => rustdoc-html}/repr.rs (100%) rename tests/{rustdoc => rustdoc-html}/resolve-ice-124363.rs (100%) rename tests/{rustdoc => rustdoc-html}/return-type-notation.rs (100%) rename tests/{rustdoc => rustdoc-html}/safe-intrinsic.rs (100%) rename tests/{rustdoc => rustdoc-html}/sanitizer-option.rs (100%) rename tests/{rustdoc => rustdoc-html}/search-index-summaries.rs (100%) rename tests/{rustdoc => rustdoc-html}/search-index.rs (100%) rename tests/{rustdoc => rustdoc-html}/short-docblock-codeblock.rs (100%) rename tests/{rustdoc => rustdoc-html}/short-docblock.rs (100%) rename tests/{rustdoc => rustdoc-html}/short-line.md (100%) rename tests/{rustdoc => rustdoc-html}/sidebar/module.rs (100%) rename tests/{rustdoc => rustdoc-html}/sidebar/sidebar-all-page.rs (100%) rename tests/{rustdoc => rustdoc-html}/sidebar/sidebar-items.rs (100%) rename tests/{rustdoc => rustdoc-html}/sidebar/sidebar-link-generation.rs (100%) rename tests/{rustdoc => rustdoc-html}/sidebar/sidebar-links-to-foreign-impl.rs (100%) rename tests/{rustdoc => rustdoc-html}/sidebar/top-toc-html.rs (100%) rename tests/{rustdoc => rustdoc-html}/sidebar/top-toc-idmap.rs (100%) rename tests/{rustdoc => rustdoc-html}/sidebar/top-toc-nil.rs (100%) rename tests/{rustdoc => rustdoc-html}/sized_trait.rs (100%) rename tests/{rustdoc => rustdoc-html}/slice-links.link_box_generic.html (100%) rename tests/{rustdoc => rustdoc-html}/slice-links.link_box_u32.html (100%) rename tests/{rustdoc => rustdoc-html}/slice-links.link_slice_generic.html (100%) rename tests/{rustdoc => rustdoc-html}/slice-links.link_slice_u32.html (100%) rename tests/{rustdoc => rustdoc-html}/slice-links.rs (100%) rename tests/{rustdoc => rustdoc-html}/smart-punct.rs (100%) rename tests/{rustdoc => rustdoc-html}/smoke.rs (100%) rename tests/{rustdoc => rustdoc-html}/sort-53812.rs (100%) rename tests/{rustdoc => rustdoc-html}/sort-modules-by-appearance.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/assoc-type-source-link.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/auxiliary/issue-26606-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/auxiliary/issue-34274.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/auxiliary/source-code-bar.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/auxiliary/source_code.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/auxiliary/src-links-external.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/check-source-code-urls-to-def-std.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/check-source-code-urls-to-def.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/doc-hidden-source.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/failing-expansion-on-wrong-macro.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/frontmatter.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/html-no-source.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/keyword-macros.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/shebang.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/source-code-highlight.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/source-file.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/source-line-numbers.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/source-version-separator.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-link-external-macro-26606.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-links-auto-impls.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-links-external.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-links-implementor-43893.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-links-inlined-34274.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-links.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-links/compiletest-ignore-dir (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-links/fizz.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-links/mod.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/src-mod-path-absolute-26995.rs (100%) rename tests/{rustdoc => rustdoc-html}/source-code-pages/version-separator-without-source.rs (100%) rename tests/{rustdoc => rustdoc-html}/stability.rs (100%) rename tests/{rustdoc => rustdoc-html}/staged-api-deprecated-unstable-32374.rs (100%) rename tests/{rustdoc => rustdoc-html}/staged-api-feature-issue-27759.rs (100%) rename tests/{rustdoc => rustdoc-html}/static-root-path.rs (100%) rename tests/{rustdoc => rustdoc-html}/static.rs (100%) rename tests/{rustdoc => rustdoc-html}/strip-block-doc-comments-stars.docblock.html (100%) rename tests/{rustdoc => rustdoc-html}/strip-block-doc-comments-stars.rs (100%) rename tests/{rustdoc => rustdoc-html}/strip-priv-imports-pass-27104.rs (100%) rename tests/{rustdoc => rustdoc-html}/struct-arg-pattern.rs (100%) rename tests/{rustdoc => rustdoc-html}/struct-field.rs (100%) rename tests/{rustdoc => rustdoc-html}/structfields.rs (100%) rename tests/{rustdoc => rustdoc-html}/summary-codeblock-31899.rs (100%) rename tests/{rustdoc => rustdoc-html}/summary-header-46377.rs (100%) rename tests/{rustdoc => rustdoc-html}/summary-reference-link-30366.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/auto-trait-lifetimes-56822.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/basic.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/bounds.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/complex.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/crate-local.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/issue-72213-projection-lifetime.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/lifetimes.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/manual.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/negative.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/nested.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/no-redundancy.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/normalize-auto-trait-80233.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/overflow.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/project.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/self-referential.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/send-impl-conditional-60726.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/static-region.rs (100%) rename tests/{rustdoc => rustdoc-html}/synthetic_auto/supertrait-bounds.rs (100%) rename tests/{rustdoc => rustdoc-html}/tab_title.rs (100%) rename tests/{rustdoc => rustdoc-html}/table-in-docblock.rs (100%) rename tests/{rustdoc => rustdoc-html}/target-feature.rs (100%) rename tests/{rustdoc => rustdoc-html}/task-lists.rs (100%) rename tests/{rustdoc => rustdoc-html}/test-lists.rs (100%) rename tests/{rustdoc => rustdoc-html}/test-parens.rs (100%) rename tests/{rustdoc => rustdoc-html}/test-strikethrough.rs (100%) rename tests/{rustdoc => rustdoc-html}/test_option_check/bar.rs (100%) rename tests/{rustdoc => rustdoc-html}/test_option_check/test.rs (100%) rename tests/{rustdoc => rustdoc-html}/thread-local-src.rs (100%) rename tests/{rustdoc => rustdoc-html}/titles.rs (100%) rename tests/{rustdoc => rustdoc-html}/toggle-item-contents.rs (100%) rename tests/{rustdoc => rustdoc-html}/toggle-method.rs (100%) rename tests/{rustdoc => rustdoc-html}/toggle-trait-fn.rs (100%) rename tests/{rustdoc => rustdoc-html}/trait-aliases.rs (100%) rename tests/{rustdoc => rustdoc-html}/trait-item-info.rs (100%) rename tests/{rustdoc => rustdoc-html}/trait-self-link.rs (100%) rename tests/{rustdoc => rustdoc-html}/trait-src-link.rs (100%) rename tests/{rustdoc => rustdoc-html}/trait-visibility.rs (100%) rename tests/{rustdoc => rustdoc-html}/traits-in-bodies.rs (100%) rename tests/{rustdoc => rustdoc-html}/tuple-struct-fields-doc.rs (100%) rename tests/{rustdoc => rustdoc-html}/tuple-struct-where-clause-34928.rs (100%) rename tests/{rustdoc => rustdoc-html}/tuples.link1_i32.html (100%) rename tests/{rustdoc => rustdoc-html}/tuples.link1_t.html (100%) rename tests/{rustdoc => rustdoc-html}/tuples.link2_i32.html (100%) rename tests/{rustdoc => rustdoc-html}/tuples.link2_t.html (100%) rename tests/{rustdoc => rustdoc-html}/tuples.link2_tu.html (100%) rename tests/{rustdoc => rustdoc-html}/tuples.link_unit.html (100%) rename tests/{rustdoc => rustdoc-html}/tuples.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-alias/auxiliary/parent-crate-115718.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-alias/cross-crate-115718.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-alias/deeply-nested-112515.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-alias/deref-32077.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-alias/impl_trait_in_assoc_type.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-alias/primitive-local-link-121106.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-alias/repr.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-alias/same-crate-115718.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-layout-flag-required.rs (100%) rename tests/{rustdoc => rustdoc-html}/type-layout.rs (100%) rename tests/{rustdoc => rustdoc-html}/typedef-inner-variants-lazy_type_alias.rs (100%) rename tests/{rustdoc => rustdoc-html}/typedef-inner-variants.rs (100%) rename tests/{rustdoc => rustdoc-html}/typedef.rs (100%) rename tests/{rustdoc => rustdoc-html}/underscore-import-61592.rs (100%) rename tests/{rustdoc => rustdoc-html}/unindent.md (100%) rename tests/{rustdoc => rustdoc-html}/unindent.rs (100%) rename tests/{rustdoc => rustdoc-html}/union-fields-html.rs (100%) rename tests/{rustdoc => rustdoc-html}/union.rs (100%) rename tests/{rustdoc => rustdoc-html}/unit-return.rs (100%) rename tests/{rustdoc => rustdoc-html}/unsafe-binder.rs (100%) rename tests/{rustdoc => rustdoc-html}/use-attr.rs (100%) rename tests/{rustdoc => rustdoc-html}/useless_lifetime_bound.rs (100%) rename tests/{rustdoc => rustdoc-html}/variadic.rs (100%) rename tests/{rustdoc => rustdoc-html}/viewpath-rename.rs (100%) rename tests/{rustdoc => rustdoc-html}/viewpath-self.rs (100%) rename tests/{rustdoc => rustdoc-html}/visibility.rs (100%) rename tests/{rustdoc => rustdoc-html}/where-clause-order.rs (100%) rename tests/{rustdoc => rustdoc-html}/where-sized.rs (100%) rename tests/{rustdoc => rustdoc-html}/where.SWhere_Echo_impl.html (100%) rename tests/{rustdoc => rustdoc-html}/where.SWhere_Simd_item-decl.html (100%) rename tests/{rustdoc => rustdoc-html}/where.SWhere_TraitWhere_item-decl.html (100%) rename tests/{rustdoc => rustdoc-html}/where.alpha_trait_decl.html (100%) rename tests/{rustdoc => rustdoc-html}/where.bravo_trait_decl.html (100%) rename tests/{rustdoc => rustdoc-html}/where.charlie_fn_decl.html (100%) rename tests/{rustdoc => rustdoc-html}/where.golf_type_alias_decl.html (100%) rename tests/{rustdoc => rustdoc-html}/where.rs (100%) rename tests/{rustdoc => rustdoc-html}/whitespace-after-where-clause.enum.html (100%) rename tests/{rustdoc => rustdoc-html}/whitespace-after-where-clause.enum2.html (100%) rename tests/{rustdoc => rustdoc-html}/whitespace-after-where-clause.rs (100%) rename tests/{rustdoc => rustdoc-html}/whitespace-after-where-clause.struct.html (100%) rename tests/{rustdoc => rustdoc-html}/whitespace-after-where-clause.struct2.html (100%) rename tests/{rustdoc => rustdoc-html}/whitespace-after-where-clause.trait.html (100%) rename tests/{rustdoc => rustdoc-html}/whitespace-after-where-clause.trait2.html (100%) rename tests/{rustdoc => rustdoc-html}/whitespace-after-where-clause.union.html (100%) rename tests/{rustdoc => rustdoc-html}/whitespace-after-where-clause.union2.html (100%) rename tests/{rustdoc => rustdoc-html}/without-redirect.rs (100%) rename tests/{rustdoc => rustdoc-html}/wrapping.rs (100%) diff --git a/rustfmt.toml b/rustfmt.toml index 6172a2bb3bf9..910eea103798 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -21,7 +21,7 @@ ignore = [ "/tests/pretty/", # These tests are very sensitive to source code layout. "/tests/run-make/export", # These tests contain syntax errors. "/tests/run-make/translation/test.rs", # This test contains syntax errors. - "/tests/rustdoc/", # Some have syntax errors, some are whitespace-sensitive. + "/tests/rustdoc-html/", # Some have syntax errors, some are whitespace-sensitive. "/tests/rustdoc-gui/", # Some tests are sensitive to source code layout. "/tests/rustdoc-ui/", # Some have syntax errors, some are whitespace-sensitive. "/tests/ui/", # Some have syntax errors, some are whitespace-sensitive. diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index a3c13fc4b095..b26df1586e71 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1582,10 +1582,10 @@ test!(UiFullDeps { IS_HOST: true, }); -test!(Rustdoc { - path: "tests/rustdoc", - mode: CompiletestMode::Rustdoc, - suite: "rustdoc", +test!(RustdocHtml { + path: "tests/rustdoc-html", + mode: CompiletestMode::RustdocHtml, + suite: "rustdoc-html", default: true, IS_HOST: true, }); @@ -1969,7 +1969,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the if matches!( mode, CompiletestMode::RunMake - | CompiletestMode::Rustdoc + | CompiletestMode::RustdocHtml | CompiletestMode::RustdocJs | CompiletestMode::RustdocJson ) || matches!(suite, "rustdoc-ui" | "coverage-run-rustdoc") @@ -2758,7 +2758,7 @@ impl Step for ErrorIndex { fn make_run(run: RunConfig<'_>) { // error_index_generator depends on librustdoc. Use the compiler that // is normally used to build rustdoc for other tests (like compiletest - // tests in tests/rustdoc) so that it shares the same artifacts. + // tests in tests/rustdoc-html) so that it shares the same artifacts. let compilers = RustcPrivateCompilers::new( run.builder, run.builder.top_stage, @@ -3159,7 +3159,7 @@ impl Step for CrateRustdoc { builder.compiler(builder.top_stage, target) } else { // Use the previous stage compiler to reuse the artifacts that are - // created when running compiletest for tests/rustdoc. If this used + // created when running compiletest for tests/rustdoc-html. If this used // `compiler`, then it would cause rustdoc to be built *again*, which // isn't really necessary. builder.compiler_for(builder.top_stage, target, target) diff --git a/src/bootstrap/src/core/build_steps/test/compiletest.rs b/src/bootstrap/src/core/build_steps/test/compiletest.rs index 359f6bb1a6ef..230ed75a0868 100644 --- a/src/bootstrap/src/core/build_steps/test/compiletest.rs +++ b/src/bootstrap/src/core/build_steps/test/compiletest.rs @@ -21,7 +21,7 @@ pub(crate) enum CompiletestMode { MirOpt, Pretty, RunMake, - Rustdoc, + RustdocHtml, RustdocJs, RustdocJson, Ui, @@ -49,7 +49,7 @@ impl CompiletestMode { Self::MirOpt => "mir-opt", Self::Pretty => "pretty", Self::RunMake => "run-make", - Self::Rustdoc => "rustdoc", + Self::RustdocHtml => "rustdoc-html", Self::RustdocJs => "rustdoc-js", Self::RustdocJson => "rustdoc-json", Self::Ui => "ui", diff --git a/src/bootstrap/src/core/builder/cli_paths.rs b/src/bootstrap/src/core/builder/cli_paths.rs index 470e83d341c7..5ff2b380e4b9 100644 --- a/src/bootstrap/src/core/builder/cli_paths.rs +++ b/src/bootstrap/src/core/builder/cli_paths.rs @@ -31,8 +31,8 @@ pub(crate) const PATH_REMAP: &[(&str, &[&str])] = &[ "tests/pretty", "tests/run-make", "tests/run-make-cargo", - "tests/rustdoc", "tests/rustdoc-gui", + "tests/rustdoc-html", "tests/rustdoc-js", "tests/rustdoc-js-std", "tests/rustdoc-json", diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap index fd18b59a9c6d..4ab84c3cabc1 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap @@ -1,6 +1,5 @@ --- source: src/bootstrap/src/core/builder/cli_paths/tests.rs -assertion_line: 68 expression: test --- [Test] test::Tidy @@ -38,9 +37,9 @@ expression: test [Test] test::UiFullDeps targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/ui-fulldeps) -[Test] test::Rustdoc +[Test] test::RustdocHtml targets: [x86_64-unknown-linux-gnu] - - Suite(test::tests/rustdoc) + - Suite(test::tests/rustdoc-html) [Test] test::CoverageRunRustdoc targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/coverage-run-rustdoc) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc.snap index 6522a7e8edaf..c8eee72aec42 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc.snap @@ -5,9 +5,6 @@ expression: test librustdoc rustdoc [Test] test::CrateRustdoc targets: [x86_64-unknown-linux-gnu] - Set({test::src/librustdoc, test::src/tools/rustdoc}) -[Test] test::Rustdoc - targets: [x86_64-unknown-linux-gnu] - - Suite(test::tests/rustdoc) [Test] test::RustdocBook targets: [x86_64-unknown-linux-gnu] - Set({test::src/doc/rustdoc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc_html.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc_html.snap new file mode 100644 index 000000000000..21acc1e46069 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_librustdoc_rustdoc_html.snap @@ -0,0 +1,10 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test librustdoc rustdoc-html +--- +[Test] test::CrateRustdoc + targets: [x86_64-unknown-linux-gnu] + - Set({test::src/librustdoc}) +[Test] test::RustdocHtml + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-html) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc.snap index 337ad33fe35f..897372dcd1c7 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc.snap @@ -2,9 +2,6 @@ source: src/bootstrap/src/core/builder/cli_paths/tests.rs expression: test rustdoc --- -[Test] test::Rustdoc - targets: [x86_64-unknown-linux-gnu] - - Suite(test::tests/rustdoc) [Test] test::CrateRustdoc targets: [x86_64-unknown-linux-gnu] - Set({test::src/tools/rustdoc}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc_html.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc_html.snap new file mode 100644 index 000000000000..a6a2a27c075e --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_rustdoc_html.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test rustdoc-html +--- +[Test] test::RustdocHtml + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-html) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap index 171680515476..2a4805e4fd68 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap @@ -1,6 +1,5 @@ --- source: src/bootstrap/src/core/builder/cli_paths/tests.rs -assertion_line: 68 expression: test --skip=coverage --- [Test] test::Tidy @@ -37,9 +36,9 @@ expression: test --skip=coverage [Test] test::UiFullDeps targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/ui-fulldeps) -[Test] test::Rustdoc +[Test] test::RustdocHtml targets: [x86_64-unknown-linux-gnu] - - Suite(test::tests/rustdoc) + - Suite(test::tests/rustdoc-html) [Test] test::CoverageRunRustdoc targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/coverage-run-rustdoc) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap index b38af13d49c3..ad9660ef5c91 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap @@ -38,12 +38,12 @@ expression: test tests [Test] test::RunMakeCargo targets: [aarch64-unknown-linux-gnu] - Suite(test::tests/run-make-cargo) -[Test] test::Rustdoc - targets: [x86_64-unknown-linux-gnu] - - Suite(test::tests/rustdoc) [Test] test::RustdocGUI targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/rustdoc-gui) +[Test] test::RustdocHtml + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-html) [Test] test::RustdocJSNotStd targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/rustdoc-js) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap index 6a158ea62bb3..4572f089b0ae 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap @@ -35,12 +35,12 @@ expression: test tests --skip=coverage [Test] test::RunMakeCargo targets: [aarch64-unknown-linux-gnu] - Suite(test::tests/run-make-cargo) -[Test] test::Rustdoc - targets: [x86_64-unknown-linux-gnu] - - Suite(test::tests/rustdoc) [Test] test::RustdocGUI targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/rustdoc-gui) +[Test] test::RustdocHtml + targets: [x86_64-unknown-linux-gnu] + - Suite(test::tests/rustdoc-html) [Test] test::RustdocJSNotStd targets: [x86_64-unknown-linux-gnu] - Suite(test::tests/rustdoc-js) diff --git a/src/bootstrap/src/core/builder/cli_paths/tests.rs b/src/bootstrap/src/core/builder/cli_paths/tests.rs index 49f75c8bea77..39293abd4fb9 100644 --- a/src/bootstrap/src/core/builder/cli_paths/tests.rs +++ b/src/bootstrap/src/core/builder/cli_paths/tests.rs @@ -169,7 +169,9 @@ declare_tests!( (x_test_library, "test library"), (x_test_librustdoc, "test librustdoc"), (x_test_librustdoc_rustdoc, "test librustdoc rustdoc"), + (x_test_librustdoc_rustdoc_html, "test librustdoc rustdoc-html"), (x_test_rustdoc, "test rustdoc"), + (x_test_rustdoc_html, "test rustdoc-html"), (x_test_skip_coverage, "test --skip=coverage"), // FIXME(Zalathar): This doesn't skip the coverage-map or coverage-run tests. (x_test_skip_tests, "test --skip=tests"), diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 92a6eb8ce837..9e1a65bca79d 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -880,7 +880,7 @@ impl<'a> Builder<'a> { test::Incremental, test::Debuginfo, test::UiFullDeps, - test::Rustdoc, + test::RustdocHtml, test::CoverageRunRustdoc, test::Pretty, test::CodegenCranelift, diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 9146c470e358..66614cc6cced 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2099,7 +2099,7 @@ mod snapshot { [test] compiletest-debuginfo 1 [test] compiletest-ui-fulldeps 1 [build] rustdoc 1 - [test] compiletest-rustdoc 1 + [test] compiletest-rustdoc-html 1 [test] compiletest-coverage-run-rustdoc 1 [test] compiletest-pretty 1 [build] rustc 1 -> std 1 @@ -2169,7 +2169,7 @@ mod snapshot { let ctx = TestCtx::new(); insta::assert_snapshot!( ctx.config("test") - .args(&["ui", "ui-fulldeps", "run-make", "rustdoc", "rustdoc-gui", "incremental"]) + .args(&["ui", "ui-fulldeps", "run-make", "rustdoc-html", "rustdoc-gui", "incremental"]) .render_steps(), @r" [build] llvm [build] rustc 0 -> rustc 1 @@ -2180,11 +2180,10 @@ mod snapshot { [build] rustc 0 -> RunMakeSupport 1 [build] rustdoc 1 [test] compiletest-run-make 1 - [test] compiletest-rustdoc 1 + [test] compiletest-rustdoc-html 1 [build] rustc 0 -> RustdocGUITest 1 [test] rustdoc-gui 1 [test] compiletest-incremental 1 - [build] rustc 1 -> rustc 2 "); } @@ -2193,7 +2192,7 @@ mod snapshot { let ctx = TestCtx::new(); insta::assert_snapshot!( ctx.config("test") - .args(&["ui", "ui-fulldeps", "run-make", "rustdoc", "rustdoc-gui", "incremental"]) + .args(&["ui", "ui-fulldeps", "run-make", "rustdoc-html", "rustdoc-gui", "incremental"]) .stage(2) .render_steps(), @r" [build] llvm @@ -2208,11 +2207,10 @@ mod snapshot { [build] rustc 0 -> RunMakeSupport 1 [build] rustdoc 2 [test] compiletest-run-make 2 - [test] compiletest-rustdoc 2 + [test] compiletest-rustdoc-html 2 [build] rustc 0 -> RustdocGUITest 1 [test] rustdoc-gui 2 [test] compiletest-incremental 2 - [build] rustdoc 1 "); } @@ -2241,12 +2239,11 @@ mod snapshot { [build] rustc 0 -> RunMakeSupport 1 [build] rustdoc 2 [test] compiletest-run-make 2 - [test] compiletest-rustdoc 2 + [build] rustc 1 -> rustc 2 + [build] rustdoc 1 [build] rustc 0 -> RustdocGUITest 1 [test] rustdoc-gui 2 [test] compiletest-incremental 2 - [build] rustc 1 -> rustc 2 - [build] rustdoc 1 [build] rustc 2 -> std 2 [build] rustdoc 2 "); @@ -2283,7 +2280,7 @@ mod snapshot { [build] rustc 2 -> rustc 3 [test] compiletest-ui-fulldeps 2 [build] rustdoc 2 - [test] compiletest-rustdoc 2 + [test] compiletest-rustdoc-html 2 [test] compiletest-coverage-run-rustdoc 2 [test] compiletest-pretty 2 [build] rustc 2 -> std 2 diff --git a/src/ci/citool/tests/test-jobs.yml b/src/ci/citool/tests/test-jobs.yml index 512c80628574..e26104905491 100644 --- a/src/ci/citool/tests/test-jobs.yml +++ b/src/ci/citool/tests/test-jobs.yml @@ -27,7 +27,7 @@ runners: <<: *base-job envs: env-x86_64-apple-tests: &env-x86_64-apple-tests - SCRIPT: ./x.py check compiletest && ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact + SCRIPT: ./x.py check compiletest && ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc-html -- --exact RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 # Ensure that host tooling is tested on our minimum supported macOS version. diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-gcc/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-gcc/Dockerfile index 0fd14ae232d7..f9c1ea531add 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-gcc/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-gcc/Dockerfile @@ -45,7 +45,7 @@ ENV SCRIPT python3 ../x.py \ --test-codegen-backend gcc \ --skip tests/coverage \ --skip tests/coverage-run-rustdoc \ - --skip tests/rustdoc \ + --skip tests/rustdoc-html \ --skip tests/rustdoc-gui \ --skip tests/rustdoc-js \ --skip tests/rustdoc-js-std \ diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index e0a37c95257c..af97ae93a2b9 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -882,7 +882,8 @@ impl<'item> DocVisitor<'item> for TypeImplCollector<'_, '_, 'item> { // // FIXME(lazy_type_alias): Once the feature is complete or stable, rewrite this // to use type unification. - // Be aware of `tests/rustdoc/type-alias/deeply-nested-112515.rs` which might regress. + // Be aware of `tests/rustdoc-html/type-alias/deeply-nested-112515.rs` which might + // regress. let Some(impl_did) = impl_item_id.as_def_id() else { continue }; let for_ty = self.cx.tcx().type_of(impl_did).skip_binder(); let reject_cx = DeepRejectCtxt::relate_infer_infer(self.cx.tcx()); diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 5563abe92a80..450fde3bbc38 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -18,7 +18,7 @@ string_enum! { Pretty => "pretty", DebugInfo => "debuginfo", Codegen => "codegen", - Rustdoc => "rustdoc", + RustdocHtml => "rustdoc-html", RustdocJson => "rustdoc-json", CodegenUnits => "codegen-units", Incremental => "incremental", @@ -69,7 +69,7 @@ string_enum! { Pretty => "pretty", RunMake => "run-make", RunMakeCargo => "run-make-cargo", - Rustdoc => "rustdoc", + RustdocHtml => "rustdoc-html", RustdocGui => "rustdoc-gui", RustdocJs => "rustdoc-js", RustdocJsStd=> "rustdoc-js-std", diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 5865954558d8..624f4dd7c2b1 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -552,7 +552,7 @@ fn check_directive<'a>( let is_known_directive = KNOWN_DIRECTIVE_NAMES_SET.contains(&directive_name) || match mode { - TestMode::Rustdoc => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES.contains(&directive_name), + TestMode::RustdocHtml => KNOWN_HTMLDOCCK_DIRECTIVE_NAMES.contains(&directive_name), TestMode::RustdocJson => KNOWN_JSONDOCCK_DIRECTIVE_NAMES.contains(&directive_name), _ => false, }; diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 0d3777b8e60c..2dc878fa2a20 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -630,7 +630,7 @@ fn test_forbidden_revisions_allowed_in_non_filecheck_dir() { let modes = [ "pretty", "debuginfo", - "rustdoc", + "rustdoc-html", "rustdoc-json", "codegen-units", "incremental", diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index a64c7850aad4..c219a8887f8f 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -85,7 +85,7 @@ fn parse_config(args: Vec) -> Config { "", "mode", "which sort of compile tests to run", - "pretty | debug-info | codegen | rustdoc \ + "pretty | debug-info | codegen | rustdoc-html \ | rustdoc-json | codegen-units | incremental | run-make | ui \ | rustdoc-js | mir-opt | assembly | crashes", ) @@ -1094,8 +1094,8 @@ fn make_test_name_and_filterable_path( /// of some other tests's name. /// /// For example, suppose the test suite contains these two test files: -/// - `tests/rustdoc/primitive.rs` -/// - `tests/rustdoc/primitive/no_std.rs` +/// - `tests/rustdoc-html/primitive.rs` +/// - `tests/rustdoc-html/primitive/no_std.rs` /// /// The test runner might put the output from those tests in these directories: /// - `$build/test/rustdoc/primitive/` diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1216ba888328..6efdb5a99ee2 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -269,7 +269,7 @@ impl<'test> TestCx<'test> { TestMode::Pretty => self.run_pretty_test(), TestMode::DebugInfo => self.run_debuginfo_test(), TestMode::Codegen => self.run_codegen_test(), - TestMode::Rustdoc => self.run_rustdoc_test(), + TestMode::RustdocHtml => self.run_rustdoc_html_test(), TestMode::RustdocJson => self.run_rustdoc_json_test(), TestMode::CodegenUnits => self.run_codegen_units_test(), TestMode::Incremental => self.run_incremental_test(), @@ -1758,7 +1758,7 @@ impl<'test> TestCx<'test> { } TestMode::Pretty | TestMode::DebugInfo - | TestMode::Rustdoc + | TestMode::RustdocHtml | TestMode::RustdocJson | TestMode::RunMake | TestMode::RustdocJs => { diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index 3c80521e51ec..8907848e0ca5 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -3,7 +3,7 @@ use std::process::Command; use super::{DocKind, TestCx, remove_and_create_dir_all}; impl TestCx<'_> { - pub(super) fn run_rustdoc_test(&self) { + pub(super) fn run_rustdoc_html_test(&self) { assert!(self.revision.is_none(), "revisions not supported in this test suite"); let out_dir = self.output_base_dir(); diff --git a/src/tools/compiletest/src/rustdoc_gui_test.rs b/src/tools/compiletest/src/rustdoc_gui_test.rs index 4454ffb1f59e..bacc8061d209 100644 --- a/src/tools/compiletest/src/rustdoc_gui_test.rs +++ b/src/tools/compiletest/src/rustdoc_gui_test.rs @@ -50,7 +50,7 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { // // For instance, `//@ ignore-stage1` will not work at all. Config { - mode: TestMode::Rustdoc, + mode: TestMode::RustdocHtml, // E.g. this has no sensible default tbh. suite: TestSuite::Ui, diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index 29168b25f7f6..1aacfeaf538e 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -123,7 +123,7 @@ llvm-config = "{llvm_config}" "tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist", "tests/ui", "tests/crashes", - "tests/rustdoc", + "tests/rustdoc-html", ]; for test_path in env.skipped_tests() { args.extend(["--skip", test_path]); diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 08061bd834e3..43e6c18382af 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -107,7 +107,7 @@ pub fn check( &tests_path.join("ui"), &tests_path.join("ui-fulldeps"), &tests_path.join("rustdoc-ui"), - &tests_path.join("rustdoc"), + &tests_path.join("rustdoc-html"), ], |path, _is_dir| { filter_dirs(path) diff --git a/tests/rustdoc/all.rs b/tests/rustdoc-html/all.rs similarity index 100% rename from tests/rustdoc/all.rs rename to tests/rustdoc-html/all.rs diff --git a/tests/rustdoc/anchors/anchor-id-duplicate-method-name-25001.rs b/tests/rustdoc-html/anchors/anchor-id-duplicate-method-name-25001.rs similarity index 100% rename from tests/rustdoc/anchors/anchor-id-duplicate-method-name-25001.rs rename to tests/rustdoc-html/anchors/anchor-id-duplicate-method-name-25001.rs diff --git a/tests/rustdoc/anchors/anchor-id-trait-method-15169.rs b/tests/rustdoc-html/anchors/anchor-id-trait-method-15169.rs similarity index 100% rename from tests/rustdoc/anchors/anchor-id-trait-method-15169.rs rename to tests/rustdoc-html/anchors/anchor-id-trait-method-15169.rs diff --git a/tests/rustdoc/anchors/anchor-id-trait-tymethod-28478.rs b/tests/rustdoc-html/anchors/anchor-id-trait-tymethod-28478.rs similarity index 100% rename from tests/rustdoc/anchors/anchor-id-trait-tymethod-28478.rs rename to tests/rustdoc-html/anchors/anchor-id-trait-tymethod-28478.rs diff --git a/tests/rustdoc/anchors/anchors.no_const_anchor.html b/tests/rustdoc-html/anchors/anchors.no_const_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_const_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_const_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_const_anchor2.html b/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_const_anchor2.html rename to tests/rustdoc-html/anchors/anchors.no_const_anchor2.html diff --git a/tests/rustdoc/anchors/anchors.no_method_anchor.html b/tests/rustdoc-html/anchors/anchors.no_method_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_method_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_method_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_trait_method_anchor.html b/tests/rustdoc-html/anchors/anchors.no_trait_method_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_trait_method_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_trait_method_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_tymethod_anchor.html b/tests/rustdoc-html/anchors/anchors.no_tymethod_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_tymethod_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_tymethod_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_type_anchor.html b/tests/rustdoc-html/anchors/anchors.no_type_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_type_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_type_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_type_anchor2.html b/tests/rustdoc-html/anchors/anchors.no_type_anchor2.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_type_anchor2.html rename to tests/rustdoc-html/anchors/anchors.no_type_anchor2.html diff --git a/tests/rustdoc/anchors/anchors.rs b/tests/rustdoc-html/anchors/anchors.rs similarity index 100% rename from tests/rustdoc/anchors/anchors.rs rename to tests/rustdoc-html/anchors/anchors.rs diff --git a/tests/rustdoc/anchors/auxiliary/issue-86620-1.rs b/tests/rustdoc-html/anchors/auxiliary/issue-86620-1.rs similarity index 100% rename from tests/rustdoc/anchors/auxiliary/issue-86620-1.rs rename to tests/rustdoc-html/anchors/auxiliary/issue-86620-1.rs diff --git a/tests/rustdoc/anchors/disambiguate-anchors-32890.rs b/tests/rustdoc-html/anchors/disambiguate-anchors-32890.rs similarity index 100% rename from tests/rustdoc/anchors/disambiguate-anchors-32890.rs rename to tests/rustdoc-html/anchors/disambiguate-anchors-32890.rs diff --git a/tests/rustdoc/anchors/disambiguate-anchors-header-29449.rs b/tests/rustdoc-html/anchors/disambiguate-anchors-header-29449.rs similarity index 100% rename from tests/rustdoc/anchors/disambiguate-anchors-header-29449.rs rename to tests/rustdoc-html/anchors/disambiguate-anchors-header-29449.rs diff --git a/tests/rustdoc/anchors/method-anchor-in-blanket-impl-86620.rs b/tests/rustdoc-html/anchors/method-anchor-in-blanket-impl-86620.rs similarity index 100% rename from tests/rustdoc/anchors/method-anchor-in-blanket-impl-86620.rs rename to tests/rustdoc-html/anchors/method-anchor-in-blanket-impl-86620.rs diff --git a/tests/rustdoc/anchors/trait-impl-items-links-and-anchors.rs b/tests/rustdoc-html/anchors/trait-impl-items-links-and-anchors.rs similarity index 100% rename from tests/rustdoc/anchors/trait-impl-items-links-and-anchors.rs rename to tests/rustdoc-html/anchors/trait-impl-items-links-and-anchors.rs diff --git a/tests/rustdoc/anon-fn-params.rs b/tests/rustdoc-html/anon-fn-params.rs similarity index 100% rename from tests/rustdoc/anon-fn-params.rs rename to tests/rustdoc-html/anon-fn-params.rs diff --git a/tests/rustdoc/anonymous-lifetime.rs b/tests/rustdoc-html/anonymous-lifetime.rs similarity index 100% rename from tests/rustdoc/anonymous-lifetime.rs rename to tests/rustdoc-html/anonymous-lifetime.rs diff --git a/tests/rustdoc/array-links.link_box_generic.html b/tests/rustdoc-html/array-links.link_box_generic.html similarity index 100% rename from tests/rustdoc/array-links.link_box_generic.html rename to tests/rustdoc-html/array-links.link_box_generic.html diff --git a/tests/rustdoc/array-links.link_box_u32.html b/tests/rustdoc-html/array-links.link_box_u32.html similarity index 100% rename from tests/rustdoc/array-links.link_box_u32.html rename to tests/rustdoc-html/array-links.link_box_u32.html diff --git a/tests/rustdoc/array-links.link_slice_generic.html b/tests/rustdoc-html/array-links.link_slice_generic.html similarity index 100% rename from tests/rustdoc/array-links.link_slice_generic.html rename to tests/rustdoc-html/array-links.link_slice_generic.html diff --git a/tests/rustdoc/array-links.link_slice_u32.html b/tests/rustdoc-html/array-links.link_slice_u32.html similarity index 100% rename from tests/rustdoc/array-links.link_slice_u32.html rename to tests/rustdoc-html/array-links.link_slice_u32.html diff --git a/tests/rustdoc/array-links.rs b/tests/rustdoc-html/array-links.rs similarity index 100% rename from tests/rustdoc/array-links.rs rename to tests/rustdoc-html/array-links.rs diff --git a/tests/rustdoc/asm-foreign.rs b/tests/rustdoc-html/asm-foreign.rs similarity index 100% rename from tests/rustdoc/asm-foreign.rs rename to tests/rustdoc-html/asm-foreign.rs diff --git a/tests/rustdoc/asm-foreign2.rs b/tests/rustdoc-html/asm-foreign2.rs similarity index 100% rename from tests/rustdoc/asm-foreign2.rs rename to tests/rustdoc-html/asm-foreign2.rs diff --git a/tests/rustdoc/asref-for-and-of-local-82465.rs b/tests/rustdoc-html/asref-for-and-of-local-82465.rs similarity index 100% rename from tests/rustdoc/asref-for-and-of-local-82465.rs rename to tests/rustdoc-html/asref-for-and-of-local-82465.rs diff --git a/tests/rustdoc/assoc/assoc-fns.rs b/tests/rustdoc-html/assoc/assoc-fns.rs similarity index 100% rename from tests/rustdoc/assoc/assoc-fns.rs rename to tests/rustdoc-html/assoc/assoc-fns.rs diff --git a/tests/rustdoc/assoc/assoc-item-cast.rs b/tests/rustdoc-html/assoc/assoc-item-cast.rs similarity index 100% rename from tests/rustdoc/assoc/assoc-item-cast.rs rename to tests/rustdoc-html/assoc/assoc-item-cast.rs diff --git a/tests/rustdoc/assoc/assoc-type-bindings-20646.rs b/tests/rustdoc-html/assoc/assoc-type-bindings-20646.rs similarity index 100% rename from tests/rustdoc/assoc/assoc-type-bindings-20646.rs rename to tests/rustdoc-html/assoc/assoc-type-bindings-20646.rs diff --git a/tests/rustdoc/assoc/assoc-types.rs b/tests/rustdoc-html/assoc/assoc-types.rs similarity index 100% rename from tests/rustdoc/assoc/assoc-types.rs rename to tests/rustdoc-html/assoc/assoc-types.rs diff --git a/tests/rustdoc/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs b/tests/rustdoc-html/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs similarity index 100% rename from tests/rustdoc/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs rename to tests/rustdoc-html/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs diff --git a/tests/rustdoc/assoc/auxiliary/issue-20646.rs b/tests/rustdoc-html/assoc/auxiliary/issue-20646.rs similarity index 100% rename from tests/rustdoc/assoc/auxiliary/issue-20646.rs rename to tests/rustdoc-html/assoc/auxiliary/issue-20646.rs diff --git a/tests/rustdoc/assoc/auxiliary/issue-20727.rs b/tests/rustdoc-html/assoc/auxiliary/issue-20727.rs similarity index 100% rename from tests/rustdoc/assoc/auxiliary/issue-20727.rs rename to tests/rustdoc-html/assoc/auxiliary/issue-20727.rs diff --git a/tests/rustdoc/assoc/auxiliary/normalize-assoc-item.rs b/tests/rustdoc-html/assoc/auxiliary/normalize-assoc-item.rs similarity index 100% rename from tests/rustdoc/assoc/auxiliary/normalize-assoc-item.rs rename to tests/rustdoc-html/assoc/auxiliary/normalize-assoc-item.rs diff --git a/tests/rustdoc/assoc/cross-crate-hidden-assoc-trait-items.rs b/tests/rustdoc-html/assoc/cross-crate-hidden-assoc-trait-items.rs similarity index 100% rename from tests/rustdoc/assoc/cross-crate-hidden-assoc-trait-items.rs rename to tests/rustdoc-html/assoc/cross-crate-hidden-assoc-trait-items.rs diff --git a/tests/rustdoc/assoc/doc-assoc-item.rs b/tests/rustdoc-html/assoc/doc-assoc-item.rs similarity index 100% rename from tests/rustdoc/assoc/doc-assoc-item.rs rename to tests/rustdoc-html/assoc/doc-assoc-item.rs diff --git a/tests/rustdoc/assoc/inline-assoc-type-20727-bindings.rs b/tests/rustdoc-html/assoc/inline-assoc-type-20727-bindings.rs similarity index 100% rename from tests/rustdoc/assoc/inline-assoc-type-20727-bindings.rs rename to tests/rustdoc-html/assoc/inline-assoc-type-20727-bindings.rs diff --git a/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-deref.rs b/tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds-deref.rs similarity index 100% rename from tests/rustdoc/assoc/inline-assoc-type-20727-bounds-deref.rs rename to tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds-deref.rs diff --git a/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-index.rs b/tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds-index.rs similarity index 100% rename from tests/rustdoc/assoc/inline-assoc-type-20727-bounds-index.rs rename to tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds-index.rs diff --git a/tests/rustdoc/assoc/inline-assoc-type-20727-bounds.rs b/tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds.rs similarity index 100% rename from tests/rustdoc/assoc/inline-assoc-type-20727-bounds.rs rename to tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds.rs diff --git a/tests/rustdoc/assoc/normalize-assoc-item.rs b/tests/rustdoc-html/assoc/normalize-assoc-item.rs similarity index 100% rename from tests/rustdoc/assoc/normalize-assoc-item.rs rename to tests/rustdoc-html/assoc/normalize-assoc-item.rs diff --git a/tests/rustdoc/async/async-fn-opaque-item.rs b/tests/rustdoc-html/async/async-fn-opaque-item.rs similarity index 100% rename from tests/rustdoc/async/async-fn-opaque-item.rs rename to tests/rustdoc-html/async/async-fn-opaque-item.rs diff --git a/tests/rustdoc/async/async-fn.rs b/tests/rustdoc-html/async/async-fn.rs similarity index 100% rename from tests/rustdoc/async/async-fn.rs rename to tests/rustdoc-html/async/async-fn.rs diff --git a/tests/rustdoc/async/async-move-doctest.rs b/tests/rustdoc-html/async/async-move-doctest.rs similarity index 100% rename from tests/rustdoc/async/async-move-doctest.rs rename to tests/rustdoc-html/async/async-move-doctest.rs diff --git a/tests/rustdoc/async/async-trait-sig.rs b/tests/rustdoc-html/async/async-trait-sig.rs similarity index 100% rename from tests/rustdoc/async/async-trait-sig.rs rename to tests/rustdoc-html/async/async-trait-sig.rs diff --git a/tests/rustdoc/async/async-trait.rs b/tests/rustdoc-html/async/async-trait.rs similarity index 100% rename from tests/rustdoc/async/async-trait.rs rename to tests/rustdoc-html/async/async-trait.rs diff --git a/tests/rustdoc/async/auxiliary/async-trait-dep.rs b/tests/rustdoc-html/async/auxiliary/async-trait-dep.rs similarity index 100% rename from tests/rustdoc/async/auxiliary/async-trait-dep.rs rename to tests/rustdoc-html/async/auxiliary/async-trait-dep.rs diff --git a/tests/rustdoc/attributes-2021-edition.rs b/tests/rustdoc-html/attributes-2021-edition.rs similarity index 100% rename from tests/rustdoc/attributes-2021-edition.rs rename to tests/rustdoc-html/attributes-2021-edition.rs diff --git a/tests/rustdoc/attributes-inlining-108281.rs b/tests/rustdoc-html/attributes-inlining-108281.rs similarity index 100% rename from tests/rustdoc/attributes-inlining-108281.rs rename to tests/rustdoc-html/attributes-inlining-108281.rs diff --git a/tests/rustdoc/attributes-re-export-2021-edition.rs b/tests/rustdoc-html/attributes-re-export-2021-edition.rs similarity index 100% rename from tests/rustdoc/attributes-re-export-2021-edition.rs rename to tests/rustdoc-html/attributes-re-export-2021-edition.rs diff --git a/tests/rustdoc/attributes-re-export.rs b/tests/rustdoc-html/attributes-re-export.rs similarity index 100% rename from tests/rustdoc/attributes-re-export.rs rename to tests/rustdoc-html/attributes-re-export.rs diff --git a/tests/rustdoc/attributes.rs b/tests/rustdoc-html/attributes.rs similarity index 100% rename from tests/rustdoc/attributes.rs rename to tests/rustdoc-html/attributes.rs diff --git a/tests/rustdoc/auto/auto-impl-for-trait.rs b/tests/rustdoc-html/auto/auto-impl-for-trait.rs similarity index 100% rename from tests/rustdoc/auto/auto-impl-for-trait.rs rename to tests/rustdoc-html/auto/auto-impl-for-trait.rs diff --git a/tests/rustdoc/auto/auto-impl-primitive.rs b/tests/rustdoc-html/auto/auto-impl-primitive.rs similarity index 100% rename from tests/rustdoc/auto/auto-impl-primitive.rs rename to tests/rustdoc-html/auto/auto-impl-primitive.rs diff --git a/tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs b/tests/rustdoc-html/auto/auto-trait-bounds-by-associated-type-50159.rs similarity index 100% rename from tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs rename to tests/rustdoc-html/auto/auto-trait-bounds-by-associated-type-50159.rs diff --git a/tests/rustdoc/auto/auto-trait-bounds-inference-variables-54705.rs b/tests/rustdoc-html/auto/auto-trait-bounds-inference-variables-54705.rs similarity index 100% rename from tests/rustdoc/auto/auto-trait-bounds-inference-variables-54705.rs rename to tests/rustdoc-html/auto/auto-trait-bounds-inference-variables-54705.rs diff --git a/tests/rustdoc/auto/auto-trait-bounds-where-51236.rs b/tests/rustdoc-html/auto/auto-trait-bounds-where-51236.rs similarity index 100% rename from tests/rustdoc/auto/auto-trait-bounds-where-51236.rs rename to tests/rustdoc-html/auto/auto-trait-bounds-where-51236.rs diff --git a/tests/rustdoc/auto/auto-trait-negative-impl-55321.rs b/tests/rustdoc-html/auto/auto-trait-negative-impl-55321.rs similarity index 100% rename from tests/rustdoc/auto/auto-trait-negative-impl-55321.rs rename to tests/rustdoc-html/auto/auto-trait-negative-impl-55321.rs diff --git a/tests/rustdoc/auto/auto-trait-not-send.rs b/tests/rustdoc-html/auto/auto-trait-not-send.rs similarity index 100% rename from tests/rustdoc/auto/auto-trait-not-send.rs rename to tests/rustdoc-html/auto/auto-trait-not-send.rs diff --git a/tests/rustdoc/auto/auto-traits.rs b/tests/rustdoc-html/auto/auto-traits.rs similarity index 100% rename from tests/rustdoc/auto/auto-traits.rs rename to tests/rustdoc-html/auto/auto-traits.rs diff --git a/tests/rustdoc/auto/auto_aliases.rs b/tests/rustdoc-html/auto/auto_aliases.rs similarity index 100% rename from tests/rustdoc/auto/auto_aliases.rs rename to tests/rustdoc-html/auto/auto_aliases.rs diff --git a/tests/rustdoc/auto/auxiliary/auto-traits.rs b/tests/rustdoc-html/auto/auxiliary/auto-traits.rs similarity index 100% rename from tests/rustdoc/auto/auxiliary/auto-traits.rs rename to tests/rustdoc-html/auto/auxiliary/auto-traits.rs diff --git a/tests/rustdoc/auxiliary/all-item-types.rs b/tests/rustdoc-html/auxiliary/all-item-types.rs similarity index 100% rename from tests/rustdoc/auxiliary/all-item-types.rs rename to tests/rustdoc-html/auxiliary/all-item-types.rs diff --git a/tests/rustdoc/auxiliary/cross_crate_generic_typedef.rs b/tests/rustdoc-html/auxiliary/cross_crate_generic_typedef.rs similarity index 100% rename from tests/rustdoc/auxiliary/cross_crate_generic_typedef.rs rename to tests/rustdoc-html/auxiliary/cross_crate_generic_typedef.rs diff --git a/tests/rustdoc/auxiliary/elided-lifetime.rs b/tests/rustdoc-html/auxiliary/elided-lifetime.rs similarity index 100% rename from tests/rustdoc/auxiliary/elided-lifetime.rs rename to tests/rustdoc-html/auxiliary/elided-lifetime.rs diff --git a/tests/rustdoc/auxiliary/empty.rs b/tests/rustdoc-html/auxiliary/empty.rs similarity index 100% rename from tests/rustdoc/auxiliary/empty.rs rename to tests/rustdoc-html/auxiliary/empty.rs diff --git a/tests/rustdoc/auxiliary/enum-primitive.rs b/tests/rustdoc-html/auxiliary/enum-primitive.rs similarity index 100% rename from tests/rustdoc/auxiliary/enum-primitive.rs rename to tests/rustdoc-html/auxiliary/enum-primitive.rs diff --git a/tests/rustdoc/auxiliary/ext-anon-fn-params.rs b/tests/rustdoc-html/auxiliary/ext-anon-fn-params.rs similarity index 100% rename from tests/rustdoc/auxiliary/ext-anon-fn-params.rs rename to tests/rustdoc-html/auxiliary/ext-anon-fn-params.rs diff --git a/tests/rustdoc/auxiliary/ext-repr.rs b/tests/rustdoc-html/auxiliary/ext-repr.rs similarity index 100% rename from tests/rustdoc/auxiliary/ext-repr.rs rename to tests/rustdoc-html/auxiliary/ext-repr.rs diff --git a/tests/rustdoc/auxiliary/ext-trait-aliases.rs b/tests/rustdoc-html/auxiliary/ext-trait-aliases.rs similarity index 100% rename from tests/rustdoc/auxiliary/ext-trait-aliases.rs rename to tests/rustdoc-html/auxiliary/ext-trait-aliases.rs diff --git a/tests/rustdoc/auxiliary/inline-default-methods.rs b/tests/rustdoc-html/auxiliary/inline-default-methods.rs similarity index 100% rename from tests/rustdoc/auxiliary/inline-default-methods.rs rename to tests/rustdoc-html/auxiliary/inline-default-methods.rs diff --git a/tests/rustdoc/auxiliary/issue-106421-force-unstable.rs b/tests/rustdoc-html/auxiliary/issue-106421-force-unstable.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-106421-force-unstable.rs rename to tests/rustdoc-html/auxiliary/issue-106421-force-unstable.rs diff --git a/tests/rustdoc/auxiliary/issue-13698.rs b/tests/rustdoc-html/auxiliary/issue-13698.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-13698.rs rename to tests/rustdoc-html/auxiliary/issue-13698.rs diff --git a/tests/rustdoc/auxiliary/issue-19190-3.rs b/tests/rustdoc-html/auxiliary/issue-19190-3.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-19190-3.rs rename to tests/rustdoc-html/auxiliary/issue-19190-3.rs diff --git a/tests/rustdoc/auxiliary/issue-61592.rs b/tests/rustdoc-html/auxiliary/issue-61592.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-61592.rs rename to tests/rustdoc-html/auxiliary/issue-61592.rs diff --git a/tests/rustdoc/auxiliary/issue-99221-aux.rs b/tests/rustdoc-html/auxiliary/issue-99221-aux.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-99221-aux.rs rename to tests/rustdoc-html/auxiliary/issue-99221-aux.rs diff --git a/tests/rustdoc/auxiliary/issue-99734-aux.rs b/tests/rustdoc-html/auxiliary/issue-99734-aux.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-99734-aux.rs rename to tests/rustdoc-html/auxiliary/issue-99734-aux.rs diff --git a/tests/rustdoc/auxiliary/jump-to-def-res-err-handling-aux.rs b/tests/rustdoc-html/auxiliary/jump-to-def-res-err-handling-aux.rs similarity index 100% rename from tests/rustdoc/auxiliary/jump-to-def-res-err-handling-aux.rs rename to tests/rustdoc-html/auxiliary/jump-to-def-res-err-handling-aux.rs diff --git a/tests/rustdoc/auxiliary/masked.rs b/tests/rustdoc-html/auxiliary/masked.rs similarity index 100% rename from tests/rustdoc/auxiliary/masked.rs rename to tests/rustdoc-html/auxiliary/masked.rs diff --git a/tests/rustdoc/auxiliary/mod-stackoverflow.rs b/tests/rustdoc-html/auxiliary/mod-stackoverflow.rs similarity index 100% rename from tests/rustdoc/auxiliary/mod-stackoverflow.rs rename to tests/rustdoc-html/auxiliary/mod-stackoverflow.rs diff --git a/tests/rustdoc/auxiliary/reexp-stripped.rs b/tests/rustdoc-html/auxiliary/reexp-stripped.rs similarity index 100% rename from tests/rustdoc/auxiliary/reexp-stripped.rs rename to tests/rustdoc-html/auxiliary/reexp-stripped.rs diff --git a/tests/rustdoc/auxiliary/remapped-paths.rs b/tests/rustdoc-html/auxiliary/remapped-paths.rs similarity index 100% rename from tests/rustdoc/auxiliary/remapped-paths.rs rename to tests/rustdoc-html/auxiliary/remapped-paths.rs diff --git a/tests/rustdoc/auxiliary/rustdoc-ffi.rs b/tests/rustdoc-html/auxiliary/rustdoc-ffi.rs similarity index 100% rename from tests/rustdoc/auxiliary/rustdoc-ffi.rs rename to tests/rustdoc-html/auxiliary/rustdoc-ffi.rs diff --git a/tests/rustdoc/auxiliary/trait-visibility.rs b/tests/rustdoc-html/auxiliary/trait-visibility.rs similarity index 100% rename from tests/rustdoc/auxiliary/trait-visibility.rs rename to tests/rustdoc-html/auxiliary/trait-visibility.rs diff --git a/tests/rustdoc/auxiliary/unit-return.rs b/tests/rustdoc-html/auxiliary/unit-return.rs similarity index 100% rename from tests/rustdoc/auxiliary/unit-return.rs rename to tests/rustdoc-html/auxiliary/unit-return.rs diff --git a/tests/rustdoc/auxiliary/unsafe-binder-dep.rs b/tests/rustdoc-html/auxiliary/unsafe-binder-dep.rs similarity index 100% rename from tests/rustdoc/auxiliary/unsafe-binder-dep.rs rename to tests/rustdoc-html/auxiliary/unsafe-binder-dep.rs diff --git a/tests/rustdoc/auxiliary/unstable-trait.rs b/tests/rustdoc-html/auxiliary/unstable-trait.rs similarity index 100% rename from tests/rustdoc/auxiliary/unstable-trait.rs rename to tests/rustdoc-html/auxiliary/unstable-trait.rs diff --git a/tests/rustdoc/bad-codeblock-syntax.rs b/tests/rustdoc-html/bad-codeblock-syntax.rs similarity index 100% rename from tests/rustdoc/bad-codeblock-syntax.rs rename to tests/rustdoc-html/bad-codeblock-syntax.rs diff --git a/tests/rustdoc/blank-line-in-doc-block-47197.rs b/tests/rustdoc-html/blank-line-in-doc-block-47197.rs similarity index 100% rename from tests/rustdoc/blank-line-in-doc-block-47197.rs rename to tests/rustdoc-html/blank-line-in-doc-block-47197.rs diff --git a/tests/rustdoc/bold-tag-101743.rs b/tests/rustdoc-html/bold-tag-101743.rs similarity index 100% rename from tests/rustdoc/bold-tag-101743.rs rename to tests/rustdoc-html/bold-tag-101743.rs diff --git a/tests/rustdoc/bounds.rs b/tests/rustdoc-html/bounds.rs similarity index 100% rename from tests/rustdoc/bounds.rs rename to tests/rustdoc-html/bounds.rs diff --git a/tests/rustdoc/cap-lints.rs b/tests/rustdoc-html/cap-lints.rs similarity index 100% rename from tests/rustdoc/cap-lints.rs rename to tests/rustdoc-html/cap-lints.rs diff --git a/tests/rustdoc/cfg-bool.rs b/tests/rustdoc-html/cfg-bool.rs similarity index 100% rename from tests/rustdoc/cfg-bool.rs rename to tests/rustdoc-html/cfg-bool.rs diff --git a/tests/rustdoc/cfg-doctest.rs b/tests/rustdoc-html/cfg-doctest.rs similarity index 100% rename from tests/rustdoc/cfg-doctest.rs rename to tests/rustdoc-html/cfg-doctest.rs diff --git a/tests/rustdoc/check-styled-link.rs b/tests/rustdoc-html/check-styled-link.rs similarity index 100% rename from tests/rustdoc/check-styled-link.rs rename to tests/rustdoc-html/check-styled-link.rs diff --git a/tests/rustdoc/check.rs b/tests/rustdoc-html/check.rs similarity index 100% rename from tests/rustdoc/check.rs rename to tests/rustdoc-html/check.rs diff --git a/tests/rustdoc/codeblock-title.rs b/tests/rustdoc-html/codeblock-title.rs similarity index 100% rename from tests/rustdoc/codeblock-title.rs rename to tests/rustdoc-html/codeblock-title.rs diff --git a/tests/rustdoc/comment-in-doctest.rs b/tests/rustdoc-html/comment-in-doctest.rs similarity index 100% rename from tests/rustdoc/comment-in-doctest.rs rename to tests/rustdoc-html/comment-in-doctest.rs diff --git a/tests/rustdoc/const-fn-76501.rs b/tests/rustdoc-html/const-fn-76501.rs similarity index 100% rename from tests/rustdoc/const-fn-76501.rs rename to tests/rustdoc-html/const-fn-76501.rs diff --git a/tests/rustdoc/const-fn-effects.rs b/tests/rustdoc-html/const-fn-effects.rs similarity index 100% rename from tests/rustdoc/const-fn-effects.rs rename to tests/rustdoc-html/const-fn-effects.rs diff --git a/tests/rustdoc/const-fn.rs b/tests/rustdoc-html/const-fn.rs similarity index 100% rename from tests/rustdoc/const-fn.rs rename to tests/rustdoc-html/const-fn.rs diff --git a/tests/rustdoc/const-generics/add-impl.rs b/tests/rustdoc-html/const-generics/add-impl.rs similarity index 100% rename from tests/rustdoc/const-generics/add-impl.rs rename to tests/rustdoc-html/const-generics/add-impl.rs diff --git a/tests/rustdoc/const-generics/auxiliary/extern_crate.rs b/tests/rustdoc-html/const-generics/auxiliary/extern_crate.rs similarity index 100% rename from tests/rustdoc/const-generics/auxiliary/extern_crate.rs rename to tests/rustdoc-html/const-generics/auxiliary/extern_crate.rs diff --git a/tests/rustdoc/const-generics/const-generic-defaults.rs b/tests/rustdoc-html/const-generics/const-generic-defaults.rs similarity index 100% rename from tests/rustdoc/const-generics/const-generic-defaults.rs rename to tests/rustdoc-html/const-generics/const-generic-defaults.rs diff --git a/tests/rustdoc/const-generics/const-generic-slice.rs b/tests/rustdoc-html/const-generics/const-generic-slice.rs similarity index 100% rename from tests/rustdoc/const-generics/const-generic-slice.rs rename to tests/rustdoc-html/const-generics/const-generic-slice.rs diff --git a/tests/rustdoc/const-generics/const-generics-docs.rs b/tests/rustdoc-html/const-generics/const-generics-docs.rs similarity index 100% rename from tests/rustdoc/const-generics/const-generics-docs.rs rename to tests/rustdoc-html/const-generics/const-generics-docs.rs diff --git a/tests/rustdoc/const-generics/const-impl.rs b/tests/rustdoc-html/const-generics/const-impl.rs similarity index 100% rename from tests/rustdoc/const-generics/const-impl.rs rename to tests/rustdoc-html/const-generics/const-impl.rs diff --git a/tests/rustdoc/const-generics/const-param-type-references-generics.rs b/tests/rustdoc-html/const-generics/const-param-type-references-generics.rs similarity index 100% rename from tests/rustdoc/const-generics/const-param-type-references-generics.rs rename to tests/rustdoc-html/const-generics/const-param-type-references-generics.rs diff --git a/tests/rustdoc/const-generics/generic_const_exprs.rs b/tests/rustdoc-html/const-generics/generic_const_exprs.rs similarity index 100% rename from tests/rustdoc/const-generics/generic_const_exprs.rs rename to tests/rustdoc-html/const-generics/generic_const_exprs.rs diff --git a/tests/rustdoc/const-generics/lazy_normalization_consts/const-equate-pred.rs b/tests/rustdoc-html/const-generics/lazy_normalization_consts/const-equate-pred.rs similarity index 100% rename from tests/rustdoc/const-generics/lazy_normalization_consts/const-equate-pred.rs rename to tests/rustdoc-html/const-generics/lazy_normalization_consts/const-equate-pred.rs diff --git a/tests/rustdoc/const-generics/type-alias.rs b/tests/rustdoc-html/const-generics/type-alias.rs similarity index 100% rename from tests/rustdoc/const-generics/type-alias.rs rename to tests/rustdoc-html/const-generics/type-alias.rs diff --git a/tests/rustdoc/const-intrinsic.rs b/tests/rustdoc-html/const-intrinsic.rs similarity index 100% rename from tests/rustdoc/const-intrinsic.rs rename to tests/rustdoc-html/const-intrinsic.rs diff --git a/tests/rustdoc/constant/assoc-consts-underscore.rs b/tests/rustdoc-html/constant/assoc-consts-underscore.rs similarity index 100% rename from tests/rustdoc/constant/assoc-consts-underscore.rs rename to tests/rustdoc-html/constant/assoc-consts-underscore.rs diff --git a/tests/rustdoc/constant/assoc-consts-version.rs b/tests/rustdoc-html/constant/assoc-consts-version.rs similarity index 100% rename from tests/rustdoc/constant/assoc-consts-version.rs rename to tests/rustdoc-html/constant/assoc-consts-version.rs diff --git a/tests/rustdoc/constant/assoc-consts.rs b/tests/rustdoc-html/constant/assoc-consts.rs similarity index 100% rename from tests/rustdoc/constant/assoc-consts.rs rename to tests/rustdoc-html/constant/assoc-consts.rs diff --git a/tests/rustdoc/constant/associated-consts.rs b/tests/rustdoc-html/constant/associated-consts.rs similarity index 100% rename from tests/rustdoc/constant/associated-consts.rs rename to tests/rustdoc-html/constant/associated-consts.rs diff --git a/tests/rustdoc/constant/const-display.rs b/tests/rustdoc-html/constant/const-display.rs similarity index 100% rename from tests/rustdoc/constant/const-display.rs rename to tests/rustdoc-html/constant/const-display.rs diff --git a/tests/rustdoc/constant/const-doc.rs b/tests/rustdoc-html/constant/const-doc.rs similarity index 100% rename from tests/rustdoc/constant/const-doc.rs rename to tests/rustdoc-html/constant/const-doc.rs diff --git a/tests/rustdoc/constant/const-effect-param.rs b/tests/rustdoc-html/constant/const-effect-param.rs similarity index 100% rename from tests/rustdoc/constant/const-effect-param.rs rename to tests/rustdoc-html/constant/const-effect-param.rs diff --git a/tests/rustdoc/constant/const-trait-and-impl-methods.rs b/tests/rustdoc-html/constant/const-trait-and-impl-methods.rs similarity index 100% rename from tests/rustdoc/constant/const-trait-and-impl-methods.rs rename to tests/rustdoc-html/constant/const-trait-and-impl-methods.rs diff --git a/tests/rustdoc/constant/const-underscore.rs b/tests/rustdoc-html/constant/const-underscore.rs similarity index 100% rename from tests/rustdoc/constant/const-underscore.rs rename to tests/rustdoc-html/constant/const-underscore.rs diff --git a/tests/rustdoc/constant/const-value-display.rs b/tests/rustdoc-html/constant/const-value-display.rs similarity index 100% rename from tests/rustdoc/constant/const-value-display.rs rename to tests/rustdoc-html/constant/const-value-display.rs diff --git a/tests/rustdoc/constant/const.rs b/tests/rustdoc-html/constant/const.rs similarity index 100% rename from tests/rustdoc/constant/const.rs rename to tests/rustdoc-html/constant/const.rs diff --git a/tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs b/tests/rustdoc-html/constant/document-item-with-associated-const-in-where-clause.rs similarity index 100% rename from tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs rename to tests/rustdoc-html/constant/document-item-with-associated-const-in-where-clause.rs diff --git a/tests/rustdoc/constant/generic-const-items.rs b/tests/rustdoc-html/constant/generic-const-items.rs similarity index 100% rename from tests/rustdoc/constant/generic-const-items.rs rename to tests/rustdoc-html/constant/generic-const-items.rs diff --git a/tests/rustdoc/constant/generic_const_exprs.rs b/tests/rustdoc-html/constant/generic_const_exprs.rs similarity index 100% rename from tests/rustdoc/constant/generic_const_exprs.rs rename to tests/rustdoc-html/constant/generic_const_exprs.rs diff --git a/tests/rustdoc/constant/glob-shadowing-const.rs b/tests/rustdoc-html/constant/glob-shadowing-const.rs similarity index 100% rename from tests/rustdoc/constant/glob-shadowing-const.rs rename to tests/rustdoc-html/constant/glob-shadowing-const.rs diff --git a/tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs b/tests/rustdoc-html/constant/hide-complex-unevaluated-const-arguments.rs similarity index 100% rename from tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs rename to tests/rustdoc-html/constant/hide-complex-unevaluated-const-arguments.rs diff --git a/tests/rustdoc/constant/hide-complex-unevaluated-consts.rs b/tests/rustdoc-html/constant/hide-complex-unevaluated-consts.rs similarity index 100% rename from tests/rustdoc/constant/hide-complex-unevaluated-consts.rs rename to tests/rustdoc-html/constant/hide-complex-unevaluated-consts.rs diff --git a/tests/rustdoc/constant/ice-associated-const-equality-105952.rs b/tests/rustdoc-html/constant/ice-associated-const-equality-105952.rs similarity index 100% rename from tests/rustdoc/constant/ice-associated-const-equality-105952.rs rename to tests/rustdoc-html/constant/ice-associated-const-equality-105952.rs diff --git a/tests/rustdoc/constant/legacy-const-generic.rs b/tests/rustdoc-html/constant/legacy-const-generic.rs similarity index 100% rename from tests/rustdoc/constant/legacy-const-generic.rs rename to tests/rustdoc-html/constant/legacy-const-generic.rs diff --git a/tests/rustdoc/constant/link-assoc-const.rs b/tests/rustdoc-html/constant/link-assoc-const.rs similarity index 100% rename from tests/rustdoc/constant/link-assoc-const.rs rename to tests/rustdoc-html/constant/link-assoc-const.rs diff --git a/tests/rustdoc/constant/redirect-const.rs b/tests/rustdoc-html/constant/redirect-const.rs similarity index 100% rename from tests/rustdoc/constant/redirect-const.rs rename to tests/rustdoc-html/constant/redirect-const.rs diff --git a/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs b/tests/rustdoc-html/constant/rfc-2632-const-trait-impl.rs similarity index 100% rename from tests/rustdoc/constant/rfc-2632-const-trait-impl.rs rename to tests/rustdoc-html/constant/rfc-2632-const-trait-impl.rs diff --git a/tests/rustdoc/constant/show-const-contents.rs b/tests/rustdoc-html/constant/show-const-contents.rs similarity index 100% rename from tests/rustdoc/constant/show-const-contents.rs rename to tests/rustdoc-html/constant/show-const-contents.rs diff --git a/tests/rustdoc/constructor-imports.rs b/tests/rustdoc-html/constructor-imports.rs similarity index 100% rename from tests/rustdoc/constructor-imports.rs rename to tests/rustdoc-html/constructor-imports.rs diff --git a/tests/rustdoc/crate-doc-hidden-109695.rs b/tests/rustdoc-html/crate-doc-hidden-109695.rs similarity index 100% rename from tests/rustdoc/crate-doc-hidden-109695.rs rename to tests/rustdoc-html/crate-doc-hidden-109695.rs diff --git a/tests/rustdoc/crate-version-escape.rs b/tests/rustdoc-html/crate-version-escape.rs similarity index 100% rename from tests/rustdoc/crate-version-escape.rs rename to tests/rustdoc-html/crate-version-escape.rs diff --git a/tests/rustdoc/crate-version-extra.rs b/tests/rustdoc-html/crate-version-extra.rs similarity index 100% rename from tests/rustdoc/crate-version-extra.rs rename to tests/rustdoc-html/crate-version-extra.rs diff --git a/tests/rustdoc/crate-version.rs b/tests/rustdoc-html/crate-version.rs similarity index 100% rename from tests/rustdoc/crate-version.rs rename to tests/rustdoc-html/crate-version.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/s.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/s.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive-no-index/s.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/s.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/q.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive/auxiliary/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/q.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive/auxiliary/q.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/t.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive/auxiliary/t.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/t.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive/auxiliary/t.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive/s.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive/s.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive/s.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive/s.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-two-no-index/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/cargo-two-no-index/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-two-no-index/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/cargo-two-no-index/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-two-no-index/e.rs b/tests/rustdoc-html/cross-crate-info/cargo-two-no-index/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-two-no-index/e.rs rename to tests/rustdoc-html/cross-crate-info/cargo-two-no-index/e.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-two/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/cargo-two/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-two/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/cargo-two/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-two/e.rs b/tests/rustdoc-html/cross-crate-info/cargo-two/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-two/e.rs rename to tests/rustdoc-html/cross-crate-info/cargo-two/e.rs diff --git a/tests/rustdoc/cross-crate-info/index-on-last/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/index-on-last/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/index-on-last/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/index-on-last/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/index-on-last/e.rs b/tests/rustdoc-html/cross-crate-info/index-on-last/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/index-on-last/e.rs rename to tests/rustdoc-html/cross-crate-info/index-on-last/e.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/q.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/q.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/q.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/r.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/r.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/r.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/r.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/s.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/s.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/s.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/s.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/t.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/t.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/t.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/t.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/i.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/i.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/i.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/i.rs diff --git a/tests/rustdoc/cross-crate-info/single-crate-baseline/q.rs b/tests/rustdoc-html/cross-crate-info/single-crate-baseline/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/single-crate-baseline/q.rs rename to tests/rustdoc-html/cross-crate-info/single-crate-baseline/q.rs diff --git a/tests/rustdoc/cross-crate-info/single-crate-no-index/q.rs b/tests/rustdoc-html/cross-crate-info/single-crate-no-index/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/single-crate-no-index/q.rs rename to tests/rustdoc-html/cross-crate-info/single-crate-no-index/q.rs diff --git a/tests/rustdoc/cross-crate-info/transitive/auxiliary/q.rs b/tests/rustdoc-html/cross-crate-info/transitive/auxiliary/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/transitive/auxiliary/q.rs rename to tests/rustdoc-html/cross-crate-info/transitive/auxiliary/q.rs diff --git a/tests/rustdoc/cross-crate-info/transitive/auxiliary/t.rs b/tests/rustdoc-html/cross-crate-info/transitive/auxiliary/t.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/transitive/auxiliary/t.rs rename to tests/rustdoc-html/cross-crate-info/transitive/auxiliary/t.rs diff --git a/tests/rustdoc/cross-crate-info/transitive/s.rs b/tests/rustdoc-html/cross-crate-info/transitive/s.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/transitive/s.rs rename to tests/rustdoc-html/cross-crate-info/transitive/s.rs diff --git a/tests/rustdoc/cross-crate-info/two/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/two/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/two/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/two/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/two/e.rs b/tests/rustdoc-html/cross-crate-info/two/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/two/e.rs rename to tests/rustdoc-html/cross-crate-info/two/e.rs diff --git a/tests/rustdoc/cross-crate-info/working-dir-examples/q.rs b/tests/rustdoc-html/cross-crate-info/working-dir-examples/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/working-dir-examples/q.rs rename to tests/rustdoc-html/cross-crate-info/working-dir-examples/q.rs diff --git a/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/e.rs b/tests/rustdoc-html/cross-crate-info/write-docs-somewhere-else/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/write-docs-somewhere-else/e.rs rename to tests/rustdoc-html/cross-crate-info/write-docs-somewhere-else/e.rs diff --git a/tests/rustdoc/cross-crate-links.rs b/tests/rustdoc-html/cross-crate-links.rs similarity index 100% rename from tests/rustdoc/cross-crate-links.rs rename to tests/rustdoc-html/cross-crate-links.rs diff --git a/tests/rustdoc/custom_code_classes.rs b/tests/rustdoc-html/custom_code_classes.rs similarity index 100% rename from tests/rustdoc/custom_code_classes.rs rename to tests/rustdoc-html/custom_code_classes.rs diff --git a/tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html b/tests/rustdoc-html/decl-line-wrapping-empty-arg-list.decl.html similarity index 100% rename from tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html rename to tests/rustdoc-html/decl-line-wrapping-empty-arg-list.decl.html diff --git a/tests/rustdoc/decl-line-wrapping-empty-arg-list.rs b/tests/rustdoc-html/decl-line-wrapping-empty-arg-list.rs similarity index 100% rename from tests/rustdoc/decl-line-wrapping-empty-arg-list.rs rename to tests/rustdoc-html/decl-line-wrapping-empty-arg-list.rs diff --git a/tests/rustdoc/decl-trailing-whitespace.declaration.html b/tests/rustdoc-html/decl-trailing-whitespace.declaration.html similarity index 100% rename from tests/rustdoc/decl-trailing-whitespace.declaration.html rename to tests/rustdoc-html/decl-trailing-whitespace.declaration.html diff --git a/tests/rustdoc/decl-trailing-whitespace.rs b/tests/rustdoc-html/decl-trailing-whitespace.rs similarity index 100% rename from tests/rustdoc/decl-trailing-whitespace.rs rename to tests/rustdoc-html/decl-trailing-whitespace.rs diff --git a/tests/rustdoc/deep-structures.rs b/tests/rustdoc-html/deep-structures.rs similarity index 100% rename from tests/rustdoc/deep-structures.rs rename to tests/rustdoc-html/deep-structures.rs diff --git a/tests/rustdoc/default-theme.rs b/tests/rustdoc-html/default-theme.rs similarity index 100% rename from tests/rustdoc/default-theme.rs rename to tests/rustdoc-html/default-theme.rs diff --git a/tests/rustdoc/default-trait-method-link.rs b/tests/rustdoc-html/default-trait-method-link.rs similarity index 100% rename from tests/rustdoc/default-trait-method-link.rs rename to tests/rustdoc-html/default-trait-method-link.rs diff --git a/tests/rustdoc/default-trait-method.rs b/tests/rustdoc-html/default-trait-method.rs similarity index 100% rename from tests/rustdoc/default-trait-method.rs rename to tests/rustdoc-html/default-trait-method.rs diff --git a/tests/rustdoc/demo-allocator-54478.rs b/tests/rustdoc-html/demo-allocator-54478.rs similarity index 100% rename from tests/rustdoc/demo-allocator-54478.rs rename to tests/rustdoc-html/demo-allocator-54478.rs diff --git a/tests/rustdoc/deprecated-future-staged-api.rs b/tests/rustdoc-html/deprecated-future-staged-api.rs similarity index 100% rename from tests/rustdoc/deprecated-future-staged-api.rs rename to tests/rustdoc-html/deprecated-future-staged-api.rs diff --git a/tests/rustdoc/deprecated-future.rs b/tests/rustdoc-html/deprecated-future.rs similarity index 100% rename from tests/rustdoc/deprecated-future.rs rename to tests/rustdoc-html/deprecated-future.rs diff --git a/tests/rustdoc/deprecated.rs b/tests/rustdoc-html/deprecated.rs similarity index 100% rename from tests/rustdoc/deprecated.rs rename to tests/rustdoc-html/deprecated.rs diff --git a/tests/rustdoc/deref-methods-19190-foreign-type.rs b/tests/rustdoc-html/deref-methods-19190-foreign-type.rs similarity index 100% rename from tests/rustdoc/deref-methods-19190-foreign-type.rs rename to tests/rustdoc-html/deref-methods-19190-foreign-type.rs diff --git a/tests/rustdoc/deref-methods-19190-inline.rs b/tests/rustdoc-html/deref-methods-19190-inline.rs similarity index 100% rename from tests/rustdoc/deref-methods-19190-inline.rs rename to tests/rustdoc-html/deref-methods-19190-inline.rs diff --git a/tests/rustdoc/deref-methods-19190.rs b/tests/rustdoc-html/deref-methods-19190.rs similarity index 100% rename from tests/rustdoc/deref-methods-19190.rs rename to tests/rustdoc-html/deref-methods-19190.rs diff --git a/tests/rustdoc/deref-mut-35169-2.rs b/tests/rustdoc-html/deref-mut-35169-2.rs similarity index 100% rename from tests/rustdoc/deref-mut-35169-2.rs rename to tests/rustdoc-html/deref-mut-35169-2.rs diff --git a/tests/rustdoc/deref-mut-35169.rs b/tests/rustdoc-html/deref-mut-35169.rs similarity index 100% rename from tests/rustdoc/deref-mut-35169.rs rename to tests/rustdoc-html/deref-mut-35169.rs diff --git a/tests/rustdoc/deref/deref-const-fn.rs b/tests/rustdoc-html/deref/deref-const-fn.rs similarity index 100% rename from tests/rustdoc/deref/deref-const-fn.rs rename to tests/rustdoc-html/deref/deref-const-fn.rs diff --git a/tests/rustdoc/deref/deref-methods-24686-target.rs b/tests/rustdoc-html/deref/deref-methods-24686-target.rs similarity index 100% rename from tests/rustdoc/deref/deref-methods-24686-target.rs rename to tests/rustdoc-html/deref/deref-methods-24686-target.rs diff --git a/tests/rustdoc/deref/deref-multiple-impl-blocks.rs b/tests/rustdoc-html/deref/deref-multiple-impl-blocks.rs similarity index 100% rename from tests/rustdoc/deref/deref-multiple-impl-blocks.rs rename to tests/rustdoc-html/deref/deref-multiple-impl-blocks.rs diff --git a/tests/rustdoc/deref/deref-mut-methods.rs b/tests/rustdoc-html/deref/deref-mut-methods.rs similarity index 100% rename from tests/rustdoc/deref/deref-mut-methods.rs rename to tests/rustdoc-html/deref/deref-mut-methods.rs diff --git a/tests/rustdoc/deref/deref-recursive-pathbuf.rs b/tests/rustdoc-html/deref/deref-recursive-pathbuf.rs similarity index 100% rename from tests/rustdoc/deref/deref-recursive-pathbuf.rs rename to tests/rustdoc-html/deref/deref-recursive-pathbuf.rs diff --git a/tests/rustdoc/deref/deref-recursive.rs b/tests/rustdoc-html/deref/deref-recursive.rs similarity index 100% rename from tests/rustdoc/deref/deref-recursive.rs rename to tests/rustdoc-html/deref/deref-recursive.rs diff --git a/tests/rustdoc/deref/deref-slice-core.rs b/tests/rustdoc-html/deref/deref-slice-core.rs similarity index 100% rename from tests/rustdoc/deref/deref-slice-core.rs rename to tests/rustdoc-html/deref/deref-slice-core.rs diff --git a/tests/rustdoc/deref/deref-to-primitive.rs b/tests/rustdoc-html/deref/deref-to-primitive.rs similarity index 100% rename from tests/rustdoc/deref/deref-to-primitive.rs rename to tests/rustdoc-html/deref/deref-to-primitive.rs diff --git a/tests/rustdoc/deref/deref-typedef.rs b/tests/rustdoc-html/deref/deref-typedef.rs similarity index 100% rename from tests/rustdoc/deref/deref-typedef.rs rename to tests/rustdoc-html/deref/deref-typedef.rs diff --git a/tests/rustdoc/deref/escape-deref-methods.rs b/tests/rustdoc-html/deref/escape-deref-methods.rs similarity index 100% rename from tests/rustdoc/deref/escape-deref-methods.rs rename to tests/rustdoc-html/deref/escape-deref-methods.rs diff --git a/tests/rustdoc/deref/recursive-deref-sidebar.rs b/tests/rustdoc-html/deref/recursive-deref-sidebar.rs similarity index 100% rename from tests/rustdoc/deref/recursive-deref-sidebar.rs rename to tests/rustdoc-html/deref/recursive-deref-sidebar.rs diff --git a/tests/rustdoc/deref/recursive-deref.rs b/tests/rustdoc-html/deref/recursive-deref.rs similarity index 100% rename from tests/rustdoc/deref/recursive-deref.rs rename to tests/rustdoc-html/deref/recursive-deref.rs diff --git a/tests/rustdoc/deref/sidebar-links-deref-100679.rs b/tests/rustdoc-html/deref/sidebar-links-deref-100679.rs similarity index 100% rename from tests/rustdoc/deref/sidebar-links-deref-100679.rs rename to tests/rustdoc-html/deref/sidebar-links-deref-100679.rs diff --git a/tests/rustdoc/description.rs b/tests/rustdoc-html/description.rs similarity index 100% rename from tests/rustdoc/description.rs rename to tests/rustdoc-html/description.rs diff --git a/tests/rustdoc/description_default.rs b/tests/rustdoc-html/description_default.rs similarity index 100% rename from tests/rustdoc/description_default.rs rename to tests/rustdoc-html/description_default.rs diff --git a/tests/rustdoc/display-hidden-items.rs b/tests/rustdoc-html/display-hidden-items.rs similarity index 100% rename from tests/rustdoc/display-hidden-items.rs rename to tests/rustdoc-html/display-hidden-items.rs diff --git a/tests/rustdoc/doc-attr-comment-mix-42760.rs b/tests/rustdoc-html/doc-attr-comment-mix-42760.rs similarity index 100% rename from tests/rustdoc/doc-attr-comment-mix-42760.rs rename to tests/rustdoc-html/doc-attr-comment-mix-42760.rs diff --git a/tests/rustdoc/doc-attribute.rs b/tests/rustdoc-html/doc-attribute.rs similarity index 100% rename from tests/rustdoc/doc-attribute.rs rename to tests/rustdoc-html/doc-attribute.rs diff --git a/tests/rustdoc/doc-auto-cfg-public-in-private.rs b/tests/rustdoc-html/doc-auto-cfg-public-in-private.rs similarity index 100% rename from tests/rustdoc/doc-auto-cfg-public-in-private.rs rename to tests/rustdoc-html/doc-auto-cfg-public-in-private.rs diff --git a/tests/rustdoc/doc-auto-cfg.rs b/tests/rustdoc-html/doc-auto-cfg.rs similarity index 100% rename from tests/rustdoc/doc-auto-cfg.rs rename to tests/rustdoc-html/doc-auto-cfg.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-hide.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-hide.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-hide.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-hide.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-implicit-gate.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-implicit-gate.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-implicit.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-implicit.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-implicit.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-inherit-from-module-79201.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-inherit-from-module-79201.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-inherit-from-module-79201.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-inherit-from-module-79201.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-simplification.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-simplification.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-simplification.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-simplification.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-target-feature.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-target-feature.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-target-feature.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-target-feature.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-traits.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-traits.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-traits.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-traits.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg.rs b/tests/rustdoc-html/doc-cfg/doc-cfg.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg.rs diff --git a/tests/rustdoc/doc-cfg/duplicate-cfg.rs b/tests/rustdoc-html/doc-cfg/duplicate-cfg.rs similarity index 100% rename from tests/rustdoc/doc-cfg/duplicate-cfg.rs rename to tests/rustdoc-html/doc-cfg/duplicate-cfg.rs diff --git a/tests/rustdoc/doc-hidden-crate.rs b/tests/rustdoc-html/doc-hidden-crate.rs similarity index 100% rename from tests/rustdoc/doc-hidden-crate.rs rename to tests/rustdoc-html/doc-hidden-crate.rs diff --git a/tests/rustdoc/doc-hidden-method-13698.rs b/tests/rustdoc-html/doc-hidden-method-13698.rs similarity index 100% rename from tests/rustdoc/doc-hidden-method-13698.rs rename to tests/rustdoc-html/doc-hidden-method-13698.rs diff --git a/tests/rustdoc/doc-on-keyword.rs b/tests/rustdoc-html/doc-on-keyword.rs similarity index 100% rename from tests/rustdoc/doc-on-keyword.rs rename to tests/rustdoc-html/doc-on-keyword.rs diff --git a/tests/rustdoc/doc-test-attr-18199.rs b/tests/rustdoc-html/doc-test-attr-18199.rs similarity index 100% rename from tests/rustdoc/doc-test-attr-18199.rs rename to tests/rustdoc-html/doc-test-attr-18199.rs diff --git a/tests/rustdoc/doc_auto_cfg.rs b/tests/rustdoc-html/doc_auto_cfg.rs similarity index 100% rename from tests/rustdoc/doc_auto_cfg.rs rename to tests/rustdoc-html/doc_auto_cfg.rs diff --git a/tests/rustdoc/doc_auto_cfg_reexports.rs b/tests/rustdoc-html/doc_auto_cfg_reexports.rs similarity index 100% rename from tests/rustdoc/doc_auto_cfg_reexports.rs rename to tests/rustdoc-html/doc_auto_cfg_reexports.rs diff --git a/tests/rustdoc/doctest/auxiliary/doctest-runtool.rs b/tests/rustdoc-html/doctest/auxiliary/doctest-runtool.rs similarity index 100% rename from tests/rustdoc/doctest/auxiliary/doctest-runtool.rs rename to tests/rustdoc-html/doctest/auxiliary/doctest-runtool.rs diff --git a/tests/rustdoc/doctest/auxiliary/empty.rs b/tests/rustdoc-html/doctest/auxiliary/empty.rs similarity index 100% rename from tests/rustdoc/doctest/auxiliary/empty.rs rename to tests/rustdoc-html/doctest/auxiliary/empty.rs diff --git a/tests/rustdoc/doctest/doctest-cfg-feature-30252.rs b/tests/rustdoc-html/doctest/doctest-cfg-feature-30252.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-cfg-feature-30252.rs rename to tests/rustdoc-html/doctest/doctest-cfg-feature-30252.rs diff --git a/tests/rustdoc/doctest/doctest-crate-attributes-38129.rs b/tests/rustdoc-html/doctest/doctest-crate-attributes-38129.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-crate-attributes-38129.rs rename to tests/rustdoc-html/doctest/doctest-crate-attributes-38129.rs diff --git a/tests/rustdoc/doctest/doctest-escape-boring-41783.codeblock.html b/tests/rustdoc-html/doctest/doctest-escape-boring-41783.codeblock.html similarity index 100% rename from tests/rustdoc/doctest/doctest-escape-boring-41783.codeblock.html rename to tests/rustdoc-html/doctest/doctest-escape-boring-41783.codeblock.html diff --git a/tests/rustdoc/doctest/doctest-escape-boring-41783.rs b/tests/rustdoc-html/doctest/doctest-escape-boring-41783.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-escape-boring-41783.rs rename to tests/rustdoc-html/doctest/doctest-escape-boring-41783.rs diff --git a/tests/rustdoc/doctest/doctest-hide-empty-line-23106.rs b/tests/rustdoc-html/doctest/doctest-hide-empty-line-23106.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-hide-empty-line-23106.rs rename to tests/rustdoc-html/doctest/doctest-hide-empty-line-23106.rs diff --git a/tests/rustdoc/doctest/doctest-ignore-32556.rs b/tests/rustdoc-html/doctest/doctest-ignore-32556.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-ignore-32556.rs rename to tests/rustdoc-html/doctest/doctest-ignore-32556.rs diff --git a/tests/rustdoc/doctest/doctest-include-43153.rs b/tests/rustdoc-html/doctest/doctest-include-43153.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-include-43153.rs rename to tests/rustdoc-html/doctest/doctest-include-43153.rs diff --git a/tests/rustdoc/doctest/doctest-macro-38219.rs b/tests/rustdoc-html/doctest/doctest-macro-38219.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-macro-38219.rs rename to tests/rustdoc-html/doctest/doctest-macro-38219.rs diff --git a/tests/rustdoc/doctest/doctest-manual-crate-name.rs b/tests/rustdoc-html/doctest/doctest-manual-crate-name.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-manual-crate-name.rs rename to tests/rustdoc-html/doctest/doctest-manual-crate-name.rs diff --git a/tests/rustdoc/doctest/doctest-markdown-inline-parse-23744.rs b/tests/rustdoc-html/doctest/doctest-markdown-inline-parse-23744.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-markdown-inline-parse-23744.rs rename to tests/rustdoc-html/doctest/doctest-markdown-inline-parse-23744.rs diff --git a/tests/rustdoc/doctest/doctest-markdown-trailing-docblock-48377.rs b/tests/rustdoc-html/doctest/doctest-markdown-trailing-docblock-48377.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-markdown-trailing-docblock-48377.rs rename to tests/rustdoc-html/doctest/doctest-markdown-trailing-docblock-48377.rs diff --git a/tests/rustdoc/doctest/doctest-multi-line-string-literal-25944.rs b/tests/rustdoc-html/doctest/doctest-multi-line-string-literal-25944.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-multi-line-string-literal-25944.rs rename to tests/rustdoc-html/doctest/doctest-multi-line-string-literal-25944.rs diff --git a/tests/rustdoc/doctest/doctest-runtool.rs b/tests/rustdoc-html/doctest/doctest-runtool.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-runtool.rs rename to tests/rustdoc-html/doctest/doctest-runtool.rs diff --git a/tests/rustdoc/doctest/ignore-sometimes.rs b/tests/rustdoc-html/doctest/ignore-sometimes.rs similarity index 100% rename from tests/rustdoc/doctest/ignore-sometimes.rs rename to tests/rustdoc-html/doctest/ignore-sometimes.rs diff --git a/tests/rustdoc/document-hidden-items-15347.rs b/tests/rustdoc-html/document-hidden-items-15347.rs similarity index 100% rename from tests/rustdoc/document-hidden-items-15347.rs rename to tests/rustdoc-html/document-hidden-items-15347.rs diff --git a/tests/rustdoc/double-hyphen-to-dash.rs b/tests/rustdoc-html/double-hyphen-to-dash.rs similarity index 100% rename from tests/rustdoc/double-hyphen-to-dash.rs rename to tests/rustdoc-html/double-hyphen-to-dash.rs diff --git a/tests/rustdoc/double-quote-escape.rs b/tests/rustdoc-html/double-quote-escape.rs similarity index 100% rename from tests/rustdoc/double-quote-escape.rs rename to tests/rustdoc-html/double-quote-escape.rs diff --git a/tests/rustdoc/duplicate-flags.rs b/tests/rustdoc-html/duplicate-flags.rs similarity index 100% rename from tests/rustdoc/duplicate-flags.rs rename to tests/rustdoc-html/duplicate-flags.rs diff --git a/tests/rustdoc/duplicate_impls/impls.rs b/tests/rustdoc-html/duplicate_impls/impls.rs similarity index 100% rename from tests/rustdoc/duplicate_impls/impls.rs rename to tests/rustdoc-html/duplicate_impls/impls.rs diff --git a/tests/rustdoc/duplicate_impls/sidebar-links-duplicate-impls-33054.rs b/tests/rustdoc-html/duplicate_impls/sidebar-links-duplicate-impls-33054.rs similarity index 100% rename from tests/rustdoc/duplicate_impls/sidebar-links-duplicate-impls-33054.rs rename to tests/rustdoc-html/duplicate_impls/sidebar-links-duplicate-impls-33054.rs diff --git a/tests/rustdoc/dyn-compatibility.rs b/tests/rustdoc-html/dyn-compatibility.rs similarity index 100% rename from tests/rustdoc/dyn-compatibility.rs rename to tests/rustdoc-html/dyn-compatibility.rs diff --git a/tests/rustdoc/early-unindent.rs b/tests/rustdoc-html/early-unindent.rs similarity index 100% rename from tests/rustdoc/early-unindent.rs rename to tests/rustdoc-html/early-unindent.rs diff --git a/tests/rustdoc/edition-doctest.rs b/tests/rustdoc-html/edition-doctest.rs similarity index 100% rename from tests/rustdoc/edition-doctest.rs rename to tests/rustdoc-html/edition-doctest.rs diff --git a/tests/rustdoc/edition-flag.rs b/tests/rustdoc-html/edition-flag.rs similarity index 100% rename from tests/rustdoc/edition-flag.rs rename to tests/rustdoc-html/edition-flag.rs diff --git a/tests/rustdoc/elided-lifetime.rs b/tests/rustdoc-html/elided-lifetime.rs similarity index 100% rename from tests/rustdoc/elided-lifetime.rs rename to tests/rustdoc-html/elided-lifetime.rs diff --git a/tests/rustdoc/empty-doc-comment.rs b/tests/rustdoc-html/empty-doc-comment.rs similarity index 100% rename from tests/rustdoc/empty-doc-comment.rs rename to tests/rustdoc-html/empty-doc-comment.rs diff --git a/tests/rustdoc/empty-mod-public.rs b/tests/rustdoc-html/empty-mod-public.rs similarity index 100% rename from tests/rustdoc/empty-mod-public.rs rename to tests/rustdoc-html/empty-mod-public.rs diff --git a/tests/rustdoc/empty-section.rs b/tests/rustdoc-html/empty-section.rs similarity index 100% rename from tests/rustdoc/empty-section.rs rename to tests/rustdoc-html/empty-section.rs diff --git a/tests/rustdoc/empty-tuple-struct-118180.rs b/tests/rustdoc-html/empty-tuple-struct-118180.rs similarity index 100% rename from tests/rustdoc/empty-tuple-struct-118180.rs rename to tests/rustdoc-html/empty-tuple-struct-118180.rs diff --git a/tests/rustdoc/ensure-src-link.rs b/tests/rustdoc-html/ensure-src-link.rs similarity index 100% rename from tests/rustdoc/ensure-src-link.rs rename to tests/rustdoc-html/ensure-src-link.rs diff --git a/tests/rustdoc/enum/auxiliary/enum-variant.rs b/tests/rustdoc-html/enum/auxiliary/enum-variant.rs similarity index 100% rename from tests/rustdoc/enum/auxiliary/enum-variant.rs rename to tests/rustdoc-html/enum/auxiliary/enum-variant.rs diff --git a/tests/rustdoc/enum/auxiliary/variant-struct.rs b/tests/rustdoc-html/enum/auxiliary/variant-struct.rs similarity index 100% rename from tests/rustdoc/enum/auxiliary/variant-struct.rs rename to tests/rustdoc-html/enum/auxiliary/variant-struct.rs diff --git a/tests/rustdoc/enum/enum-headings.rs b/tests/rustdoc-html/enum/enum-headings.rs similarity index 100% rename from tests/rustdoc/enum/enum-headings.rs rename to tests/rustdoc-html/enum/enum-headings.rs diff --git a/tests/rustdoc/enum/enum-non-exhaustive-108925.rs b/tests/rustdoc-html/enum/enum-non-exhaustive-108925.rs similarity index 100% rename from tests/rustdoc/enum/enum-non-exhaustive-108925.rs rename to tests/rustdoc-html/enum/enum-non-exhaustive-108925.rs diff --git a/tests/rustdoc/enum/enum-variant-doc-hidden-field-88600.rs b/tests/rustdoc-html/enum/enum-variant-doc-hidden-field-88600.rs similarity index 100% rename from tests/rustdoc/enum/enum-variant-doc-hidden-field-88600.rs rename to tests/rustdoc-html/enum/enum-variant-doc-hidden-field-88600.rs diff --git a/tests/rustdoc/enum/enum-variant-fields-heading.rs b/tests/rustdoc-html/enum/enum-variant-fields-heading.rs similarity index 100% rename from tests/rustdoc/enum/enum-variant-fields-heading.rs rename to tests/rustdoc-html/enum/enum-variant-fields-heading.rs diff --git a/tests/rustdoc/enum/enum-variant-fields-heading.variants.html b/tests/rustdoc-html/enum/enum-variant-fields-heading.variants.html similarity index 100% rename from tests/rustdoc/enum/enum-variant-fields-heading.variants.html rename to tests/rustdoc-html/enum/enum-variant-fields-heading.variants.html diff --git a/tests/rustdoc/enum/enum-variant-non_exhaustive.rs b/tests/rustdoc-html/enum/enum-variant-non_exhaustive.rs similarity index 100% rename from tests/rustdoc/enum/enum-variant-non_exhaustive.rs rename to tests/rustdoc-html/enum/enum-variant-non_exhaustive.rs diff --git a/tests/rustdoc/enum/enum-variant-non_exhaustive.type-alias-code.html b/tests/rustdoc-html/enum/enum-variant-non_exhaustive.type-alias-code.html similarity index 100% rename from tests/rustdoc/enum/enum-variant-non_exhaustive.type-alias-code.html rename to tests/rustdoc-html/enum/enum-variant-non_exhaustive.type-alias-code.html diff --git a/tests/rustdoc/enum/enum-variant-non_exhaustive.type-code.html b/tests/rustdoc-html/enum/enum-variant-non_exhaustive.type-code.html similarity index 100% rename from tests/rustdoc/enum/enum-variant-non_exhaustive.type-code.html rename to tests/rustdoc-html/enum/enum-variant-non_exhaustive.type-code.html diff --git a/tests/rustdoc/enum/enum-variant-value.rs b/tests/rustdoc-html/enum/enum-variant-value.rs similarity index 100% rename from tests/rustdoc/enum/enum-variant-value.rs rename to tests/rustdoc-html/enum/enum-variant-value.rs diff --git a/tests/rustdoc/enum/render-enum-variant-structlike-32395.rs b/tests/rustdoc-html/enum/render-enum-variant-structlike-32395.rs similarity index 100% rename from tests/rustdoc/enum/render-enum-variant-structlike-32395.rs rename to tests/rustdoc-html/enum/render-enum-variant-structlike-32395.rs diff --git a/tests/rustdoc/enum/strip-enum-variant.no-not-shown.html b/tests/rustdoc-html/enum/strip-enum-variant.no-not-shown.html similarity index 100% rename from tests/rustdoc/enum/strip-enum-variant.no-not-shown.html rename to tests/rustdoc-html/enum/strip-enum-variant.no-not-shown.html diff --git a/tests/rustdoc/enum/strip-enum-variant.rs b/tests/rustdoc-html/enum/strip-enum-variant.rs similarity index 100% rename from tests/rustdoc/enum/strip-enum-variant.rs rename to tests/rustdoc-html/enum/strip-enum-variant.rs diff --git a/tests/rustdoc/extern/auxiliary/empty.rs b/tests/rustdoc-html/extern/auxiliary/empty.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/empty.rs rename to tests/rustdoc-html/extern/auxiliary/empty.rs diff --git a/tests/rustdoc/extern/auxiliary/extern-links.rs b/tests/rustdoc-html/extern/auxiliary/extern-links.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/extern-links.rs rename to tests/rustdoc-html/extern/auxiliary/extern-links.rs diff --git a/tests/rustdoc/extern/auxiliary/external-cross-doc.md b/tests/rustdoc-html/extern/auxiliary/external-cross-doc.md similarity index 100% rename from tests/rustdoc/extern/auxiliary/external-cross-doc.md rename to tests/rustdoc-html/extern/auxiliary/external-cross-doc.md diff --git a/tests/rustdoc/extern/auxiliary/external-cross.rs b/tests/rustdoc-html/extern/auxiliary/external-cross.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/external-cross.rs rename to tests/rustdoc-html/extern/auxiliary/external-cross.rs diff --git a/tests/rustdoc/extern/auxiliary/external-doc.md b/tests/rustdoc-html/extern/auxiliary/external-doc.md similarity index 100% rename from tests/rustdoc/extern/auxiliary/external-doc.md rename to tests/rustdoc-html/extern/auxiliary/external-doc.md diff --git a/tests/rustdoc/extern/auxiliary/html_root.rs b/tests/rustdoc-html/extern/auxiliary/html_root.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/html_root.rs rename to tests/rustdoc-html/extern/auxiliary/html_root.rs diff --git a/tests/rustdoc/extern/auxiliary/issue-30109-1.rs b/tests/rustdoc-html/extern/auxiliary/issue-30109-1.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/issue-30109-1.rs rename to tests/rustdoc-html/extern/auxiliary/issue-30109-1.rs diff --git a/tests/rustdoc/extern/auxiliary/no_html_root.rs b/tests/rustdoc-html/extern/auxiliary/no_html_root.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/no_html_root.rs rename to tests/rustdoc-html/extern/auxiliary/no_html_root.rs diff --git a/tests/rustdoc/extern/auxiliary/panic-item.rs b/tests/rustdoc-html/extern/auxiliary/panic-item.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/panic-item.rs rename to tests/rustdoc-html/extern/auxiliary/panic-item.rs diff --git a/tests/rustdoc/extern/auxiliary/pub-extern-crate.rs b/tests/rustdoc-html/extern/auxiliary/pub-extern-crate.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/pub-extern-crate.rs rename to tests/rustdoc-html/extern/auxiliary/pub-extern-crate.rs diff --git a/tests/rustdoc/extern/auxiliary/rustdoc-extern-default-method.rs b/tests/rustdoc-html/extern/auxiliary/rustdoc-extern-default-method.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/rustdoc-extern-default-method.rs rename to tests/rustdoc-html/extern/auxiliary/rustdoc-extern-default-method.rs diff --git a/tests/rustdoc/extern/auxiliary/rustdoc-extern-method.rs b/tests/rustdoc-html/extern/auxiliary/rustdoc-extern-method.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/rustdoc-extern-method.rs rename to tests/rustdoc-html/extern/auxiliary/rustdoc-extern-method.rs diff --git a/tests/rustdoc/extern/auxiliary/variant-struct.rs b/tests/rustdoc-html/extern/auxiliary/variant-struct.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/variant-struct.rs rename to tests/rustdoc-html/extern/auxiliary/variant-struct.rs diff --git a/tests/rustdoc/extern/duplicate-reexports-section-150211.rs b/tests/rustdoc-html/extern/duplicate-reexports-section-150211.rs similarity index 100% rename from tests/rustdoc/extern/duplicate-reexports-section-150211.rs rename to tests/rustdoc-html/extern/duplicate-reexports-section-150211.rs diff --git a/tests/rustdoc/extern/extern-default-method.no_href_on_anchor.html b/tests/rustdoc-html/extern/extern-default-method.no_href_on_anchor.html similarity index 100% rename from tests/rustdoc/extern/extern-default-method.no_href_on_anchor.html rename to tests/rustdoc-html/extern/extern-default-method.no_href_on_anchor.html diff --git a/tests/rustdoc/extern/extern-default-method.rs b/tests/rustdoc-html/extern/extern-default-method.rs similarity index 100% rename from tests/rustdoc/extern/extern-default-method.rs rename to tests/rustdoc-html/extern/extern-default-method.rs diff --git a/tests/rustdoc/extern/extern-fn-22038.rs b/tests/rustdoc-html/extern/extern-fn-22038.rs similarity index 100% rename from tests/rustdoc/extern/extern-fn-22038.rs rename to tests/rustdoc-html/extern/extern-fn-22038.rs diff --git a/tests/rustdoc/extern/extern-html-alias.rs b/tests/rustdoc-html/extern/extern-html-alias.rs similarity index 100% rename from tests/rustdoc/extern/extern-html-alias.rs rename to tests/rustdoc-html/extern/extern-html-alias.rs diff --git a/tests/rustdoc/extern/extern-html-fallback.rs b/tests/rustdoc-html/extern/extern-html-fallback.rs similarity index 100% rename from tests/rustdoc/extern/extern-html-fallback.rs rename to tests/rustdoc-html/extern/extern-html-fallback.rs diff --git a/tests/rustdoc/extern/extern-html-root-url-precedence.rs b/tests/rustdoc-html/extern/extern-html-root-url-precedence.rs similarity index 100% rename from tests/rustdoc/extern/extern-html-root-url-precedence.rs rename to tests/rustdoc-html/extern/extern-html-root-url-precedence.rs diff --git a/tests/rustdoc/extern/extern-html-root-url.rs b/tests/rustdoc-html/extern/extern-html-root-url.rs similarity index 100% rename from tests/rustdoc/extern/extern-html-root-url.rs rename to tests/rustdoc-html/extern/extern-html-root-url.rs diff --git a/tests/rustdoc/extern/extern-links.rs b/tests/rustdoc-html/extern/extern-links.rs similarity index 100% rename from tests/rustdoc/extern/extern-links.rs rename to tests/rustdoc-html/extern/extern-links.rs diff --git a/tests/rustdoc/extern/extern-method.rs b/tests/rustdoc-html/extern/extern-method.rs similarity index 100% rename from tests/rustdoc/extern/extern-method.rs rename to tests/rustdoc-html/extern/extern-method.rs diff --git a/tests/rustdoc/extern/external-cross.rs b/tests/rustdoc-html/extern/external-cross.rs similarity index 100% rename from tests/rustdoc/extern/external-cross.rs rename to tests/rustdoc-html/extern/external-cross.rs diff --git a/tests/rustdoc/extern/external-doc.rs b/tests/rustdoc-html/extern/external-doc.rs similarity index 100% rename from tests/rustdoc/extern/external-doc.rs rename to tests/rustdoc-html/extern/external-doc.rs diff --git a/tests/rustdoc/extern/hidden-extern-34025.rs b/tests/rustdoc-html/extern/hidden-extern-34025.rs similarity index 100% rename from tests/rustdoc/extern/hidden-extern-34025.rs rename to tests/rustdoc-html/extern/hidden-extern-34025.rs diff --git a/tests/rustdoc/extern/link-extern-crate-33178.rs b/tests/rustdoc-html/extern/link-extern-crate-33178.rs similarity index 100% rename from tests/rustdoc/extern/link-extern-crate-33178.rs rename to tests/rustdoc-html/extern/link-extern-crate-33178.rs diff --git a/tests/rustdoc/extern/link-extern-crate-item-30109.rs b/tests/rustdoc-html/extern/link-extern-crate-item-30109.rs similarity index 100% rename from tests/rustdoc/extern/link-extern-crate-item-30109.rs rename to tests/rustdoc-html/extern/link-extern-crate-item-30109.rs diff --git a/tests/rustdoc/extern/link-extern-crate-title-33178.rs b/tests/rustdoc-html/extern/link-extern-crate-title-33178.rs similarity index 100% rename from tests/rustdoc/extern/link-extern-crate-title-33178.rs rename to tests/rustdoc-html/extern/link-extern-crate-title-33178.rs diff --git a/tests/rustdoc/extern/pub-extern-crate-150176.rs b/tests/rustdoc-html/extern/pub-extern-crate-150176.rs similarity index 100% rename from tests/rustdoc/extern/pub-extern-crate-150176.rs rename to tests/rustdoc-html/extern/pub-extern-crate-150176.rs diff --git a/tests/rustdoc/extern/pub-extern-crate.rs b/tests/rustdoc-html/extern/pub-extern-crate.rs similarity index 100% rename from tests/rustdoc/extern/pub-extern-crate.rs rename to tests/rustdoc-html/extern/pub-extern-crate.rs diff --git a/tests/rustdoc/extern/unsafe-extern-blocks.rs b/tests/rustdoc-html/extern/unsafe-extern-blocks.rs similarity index 100% rename from tests/rustdoc/extern/unsafe-extern-blocks.rs rename to tests/rustdoc-html/extern/unsafe-extern-blocks.rs diff --git a/tests/rustdoc/extern/unused-extern-crate.rs b/tests/rustdoc-html/extern/unused-extern-crate.rs similarity index 100% rename from tests/rustdoc/extern/unused-extern-crate.rs rename to tests/rustdoc-html/extern/unused-extern-crate.rs diff --git a/tests/rustdoc/extremely_long_typename.extremely_long_typename.html b/tests/rustdoc-html/extremely_long_typename.extremely_long_typename.html similarity index 100% rename from tests/rustdoc/extremely_long_typename.extremely_long_typename.html rename to tests/rustdoc-html/extremely_long_typename.extremely_long_typename.html diff --git a/tests/rustdoc/extremely_long_typename.rs b/tests/rustdoc-html/extremely_long_typename.rs similarity index 100% rename from tests/rustdoc/extremely_long_typename.rs rename to tests/rustdoc-html/extremely_long_typename.rs diff --git a/tests/rustdoc/feature-gate-doc_auto_cfg.rs b/tests/rustdoc-html/feature-gate-doc_auto_cfg.rs similarity index 100% rename from tests/rustdoc/feature-gate-doc_auto_cfg.rs rename to tests/rustdoc-html/feature-gate-doc_auto_cfg.rs diff --git a/tests/rustdoc/ffi.rs b/tests/rustdoc-html/ffi.rs similarity index 100% rename from tests/rustdoc/ffi.rs rename to tests/rustdoc-html/ffi.rs diff --git a/tests/rustdoc/file-creation-111249.rs b/tests/rustdoc-html/file-creation-111249.rs similarity index 100% rename from tests/rustdoc/file-creation-111249.rs rename to tests/rustdoc-html/file-creation-111249.rs diff --git a/tests/rustdoc/files-creation-hidden.rs b/tests/rustdoc-html/files-creation-hidden.rs similarity index 100% rename from tests/rustdoc/files-creation-hidden.rs rename to tests/rustdoc-html/files-creation-hidden.rs diff --git a/tests/rustdoc/fn-bound.rs b/tests/rustdoc-html/fn-bound.rs similarity index 100% rename from tests/rustdoc/fn-bound.rs rename to tests/rustdoc-html/fn-bound.rs diff --git a/tests/rustdoc/fn-pointer-arg-name.rs b/tests/rustdoc-html/fn-pointer-arg-name.rs similarity index 100% rename from tests/rustdoc/fn-pointer-arg-name.rs rename to tests/rustdoc-html/fn-pointer-arg-name.rs diff --git a/tests/rustdoc/fn-sidebar.rs b/tests/rustdoc-html/fn-sidebar.rs similarity index 100% rename from tests/rustdoc/fn-sidebar.rs rename to tests/rustdoc-html/fn-sidebar.rs diff --git a/tests/rustdoc/fn-type.rs b/tests/rustdoc-html/fn-type.rs similarity index 100% rename from tests/rustdoc/fn-type.rs rename to tests/rustdoc-html/fn-type.rs diff --git a/tests/rustdoc/footnote-definition-without-blank-line-100638.rs b/tests/rustdoc-html/footnote-definition-without-blank-line-100638.rs similarity index 100% rename from tests/rustdoc/footnote-definition-without-blank-line-100638.rs rename to tests/rustdoc-html/footnote-definition-without-blank-line-100638.rs diff --git a/tests/rustdoc/footnote-ids.rs b/tests/rustdoc-html/footnote-ids.rs similarity index 100% rename from tests/rustdoc/footnote-ids.rs rename to tests/rustdoc-html/footnote-ids.rs diff --git a/tests/rustdoc/footnote-in-summary.rs b/tests/rustdoc-html/footnote-in-summary.rs similarity index 100% rename from tests/rustdoc/footnote-in-summary.rs rename to tests/rustdoc-html/footnote-in-summary.rs diff --git a/tests/rustdoc/footnote-reference-ids.rs b/tests/rustdoc-html/footnote-reference-ids.rs similarity index 100% rename from tests/rustdoc/footnote-reference-ids.rs rename to tests/rustdoc-html/footnote-reference-ids.rs diff --git a/tests/rustdoc/footnote-reference-in-footnote-def.rs b/tests/rustdoc-html/footnote-reference-in-footnote-def.rs similarity index 100% rename from tests/rustdoc/footnote-reference-in-footnote-def.rs rename to tests/rustdoc-html/footnote-reference-in-footnote-def.rs diff --git a/tests/rustdoc/force-target-feature.rs b/tests/rustdoc-html/force-target-feature.rs similarity index 100% rename from tests/rustdoc/force-target-feature.rs rename to tests/rustdoc-html/force-target-feature.rs diff --git a/tests/rustdoc/force-unstable-if-unmarked-106421-not-internal.rs b/tests/rustdoc-html/force-unstable-if-unmarked-106421-not-internal.rs similarity index 100% rename from tests/rustdoc/force-unstable-if-unmarked-106421-not-internal.rs rename to tests/rustdoc-html/force-unstable-if-unmarked-106421-not-internal.rs diff --git a/tests/rustdoc/force-unstable-if-unmarked-106421.rs b/tests/rustdoc-html/force-unstable-if-unmarked-106421.rs similarity index 100% rename from tests/rustdoc/force-unstable-if-unmarked-106421.rs rename to tests/rustdoc-html/force-unstable-if-unmarked-106421.rs diff --git a/tests/rustdoc/foreigntype.rs b/tests/rustdoc-html/foreigntype.rs similarity index 100% rename from tests/rustdoc/foreigntype.rs rename to tests/rustdoc-html/foreigntype.rs diff --git a/tests/rustdoc/generic-associated-types/gat-elided-lifetime-94683.rs b/tests/rustdoc-html/generic-associated-types/gat-elided-lifetime-94683.rs similarity index 100% rename from tests/rustdoc/generic-associated-types/gat-elided-lifetime-94683.rs rename to tests/rustdoc-html/generic-associated-types/gat-elided-lifetime-94683.rs diff --git a/tests/rustdoc/generic-associated-types/gat-linkification-109488.rs b/tests/rustdoc-html/generic-associated-types/gat-linkification-109488.rs similarity index 100% rename from tests/rustdoc/generic-associated-types/gat-linkification-109488.rs rename to tests/rustdoc-html/generic-associated-types/gat-linkification-109488.rs diff --git a/tests/rustdoc/generic-associated-types/gats.rs b/tests/rustdoc-html/generic-associated-types/gats.rs similarity index 100% rename from tests/rustdoc/generic-associated-types/gats.rs rename to tests/rustdoc-html/generic-associated-types/gats.rs diff --git a/tests/rustdoc/glob-shadowing.rs b/tests/rustdoc-html/glob-shadowing.rs similarity index 100% rename from tests/rustdoc/glob-shadowing.rs rename to tests/rustdoc-html/glob-shadowing.rs diff --git a/tests/rustdoc/heading-levels-89309.rs b/tests/rustdoc-html/heading-levels-89309.rs similarity index 100% rename from tests/rustdoc/heading-levels-89309.rs rename to tests/rustdoc-html/heading-levels-89309.rs diff --git a/tests/rustdoc/heterogeneous-concat.rs b/tests/rustdoc-html/heterogeneous-concat.rs similarity index 100% rename from tests/rustdoc/heterogeneous-concat.rs rename to tests/rustdoc-html/heterogeneous-concat.rs diff --git a/tests/rustdoc/hidden-line.rs b/tests/rustdoc-html/hidden-line.rs similarity index 100% rename from tests/rustdoc/hidden-line.rs rename to tests/rustdoc-html/hidden-line.rs diff --git a/tests/rustdoc/hidden-methods.rs b/tests/rustdoc-html/hidden-methods.rs similarity index 100% rename from tests/rustdoc/hidden-methods.rs rename to tests/rustdoc-html/hidden-methods.rs diff --git a/tests/rustdoc/hidden-trait-methods-with-document-hidden-items.rs b/tests/rustdoc-html/hidden-trait-methods-with-document-hidden-items.rs similarity index 100% rename from tests/rustdoc/hidden-trait-methods-with-document-hidden-items.rs rename to tests/rustdoc-html/hidden-trait-methods-with-document-hidden-items.rs diff --git a/tests/rustdoc/hidden-trait-methods.rs b/tests/rustdoc-html/hidden-trait-methods.rs similarity index 100% rename from tests/rustdoc/hidden-trait-methods.rs rename to tests/rustdoc-html/hidden-trait-methods.rs diff --git a/tests/rustdoc/hide-unstable-trait.rs b/tests/rustdoc-html/hide-unstable-trait.rs similarity index 100% rename from tests/rustdoc/hide-unstable-trait.rs rename to tests/rustdoc-html/hide-unstable-trait.rs diff --git a/tests/rustdoc/higher-ranked-trait-bounds.rs b/tests/rustdoc-html/higher-ranked-trait-bounds.rs similarity index 100% rename from tests/rustdoc/higher-ranked-trait-bounds.rs rename to tests/rustdoc-html/higher-ranked-trait-bounds.rs diff --git a/tests/rustdoc/highlight-invalid-rust-12834.rs b/tests/rustdoc-html/highlight-invalid-rust-12834.rs similarity index 100% rename from tests/rustdoc/highlight-invalid-rust-12834.rs rename to tests/rustdoc-html/highlight-invalid-rust-12834.rs diff --git a/tests/rustdoc/ice-type-error-19181.rs b/tests/rustdoc-html/ice-type-error-19181.rs similarity index 100% rename from tests/rustdoc/ice-type-error-19181.rs rename to tests/rustdoc-html/ice-type-error-19181.rs diff --git a/tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc-html/impl/auxiliary/cross-crate-hidden-impl-parameter.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs rename to tests/rustdoc-html/impl/auxiliary/cross-crate-hidden-impl-parameter.rs diff --git a/tests/rustdoc/impl/auxiliary/extern-impl-trait.rs b/tests/rustdoc-html/impl/auxiliary/extern-impl-trait.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/extern-impl-trait.rs rename to tests/rustdoc-html/impl/auxiliary/extern-impl-trait.rs diff --git a/tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs b/tests/rustdoc-html/impl/auxiliary/incoherent-impl-types.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs rename to tests/rustdoc-html/impl/auxiliary/incoherent-impl-types.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-100204-aux.rs b/tests/rustdoc-html/impl/auxiliary/issue-100204-aux.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-100204-aux.rs rename to tests/rustdoc-html/impl/auxiliary/issue-100204-aux.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-17476.rs b/tests/rustdoc-html/impl/auxiliary/issue-17476.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-17476.rs rename to tests/rustdoc-html/impl/auxiliary/issue-17476.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-21092.rs b/tests/rustdoc-html/impl/auxiliary/issue-21092.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-21092.rs rename to tests/rustdoc-html/impl/auxiliary/issue-21092.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-22025.rs b/tests/rustdoc-html/impl/auxiliary/issue-22025.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-22025.rs rename to tests/rustdoc-html/impl/auxiliary/issue-22025.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-53689.rs b/tests/rustdoc-html/impl/auxiliary/issue-53689.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-53689.rs rename to tests/rustdoc-html/impl/auxiliary/issue-53689.rs diff --git a/tests/rustdoc/impl/auxiliary/precise-capturing.rs b/tests/rustdoc-html/impl/auxiliary/precise-capturing.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/precise-capturing.rs rename to tests/rustdoc-html/impl/auxiliary/precise-capturing.rs diff --git a/tests/rustdoc/impl/auxiliary/real_gimli.rs b/tests/rustdoc-html/impl/auxiliary/real_gimli.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/real_gimli.rs rename to tests/rustdoc-html/impl/auxiliary/real_gimli.rs diff --git a/tests/rustdoc/impl/auxiliary/realcore.rs b/tests/rustdoc-html/impl/auxiliary/realcore.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/realcore.rs rename to tests/rustdoc-html/impl/auxiliary/realcore.rs diff --git a/tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs b/tests/rustdoc-html/impl/auxiliary/rustdoc-default-impl.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs rename to tests/rustdoc-html/impl/auxiliary/rustdoc-default-impl.rs diff --git a/tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs b/tests/rustdoc-html/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs rename to tests/rustdoc-html/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs diff --git a/tests/rustdoc/impl/blanket-impl-29503.rs b/tests/rustdoc-html/impl/blanket-impl-29503.rs similarity index 100% rename from tests/rustdoc/impl/blanket-impl-29503.rs rename to tests/rustdoc-html/impl/blanket-impl-29503.rs diff --git a/tests/rustdoc/impl/blanket-impl-78673.rs b/tests/rustdoc-html/impl/blanket-impl-78673.rs similarity index 100% rename from tests/rustdoc/impl/blanket-impl-78673.rs rename to tests/rustdoc-html/impl/blanket-impl-78673.rs diff --git a/tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc-html/impl/cross-crate-hidden-impl-parameter.rs similarity index 100% rename from tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs rename to tests/rustdoc-html/impl/cross-crate-hidden-impl-parameter.rs diff --git a/tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs b/tests/rustdoc-html/impl/deduplicate-glob-import-impl-21474.rs similarity index 100% rename from tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs rename to tests/rustdoc-html/impl/deduplicate-glob-import-impl-21474.rs diff --git a/tests/rustdoc/impl/deduplicate-trait-impl-22025.rs b/tests/rustdoc-html/impl/deduplicate-trait-impl-22025.rs similarity index 100% rename from tests/rustdoc/impl/deduplicate-trait-impl-22025.rs rename to tests/rustdoc-html/impl/deduplicate-trait-impl-22025.rs diff --git a/tests/rustdoc/impl/default-impl.rs b/tests/rustdoc-html/impl/default-impl.rs similarity index 100% rename from tests/rustdoc/impl/default-impl.rs rename to tests/rustdoc-html/impl/default-impl.rs diff --git a/tests/rustdoc/impl/deprecated-impls.rs b/tests/rustdoc-html/impl/deprecated-impls.rs similarity index 100% rename from tests/rustdoc/impl/deprecated-impls.rs rename to tests/rustdoc-html/impl/deprecated-impls.rs diff --git a/tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs b/tests/rustdoc-html/impl/doc-hidden-trait-implementors-33069.rs similarity index 100% rename from tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs rename to tests/rustdoc-html/impl/doc-hidden-trait-implementors-33069.rs diff --git a/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs b/tests/rustdoc-html/impl/doc_auto_cfg_nested_impl.rs similarity index 100% rename from tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs rename to tests/rustdoc-html/impl/doc_auto_cfg_nested_impl.rs diff --git a/tests/rustdoc/impl/duplicated_impl.rs b/tests/rustdoc-html/impl/duplicated_impl.rs similarity index 100% rename from tests/rustdoc/impl/duplicated_impl.rs rename to tests/rustdoc-html/impl/duplicated_impl.rs diff --git a/tests/rustdoc/impl/empty-impl-block.rs b/tests/rustdoc-html/impl/empty-impl-block.rs similarity index 100% rename from tests/rustdoc/impl/empty-impl-block.rs rename to tests/rustdoc-html/impl/empty-impl-block.rs diff --git a/tests/rustdoc/impl/empty-impls.rs b/tests/rustdoc-html/impl/empty-impls.rs similarity index 100% rename from tests/rustdoc/impl/empty-impls.rs rename to tests/rustdoc-html/impl/empty-impls.rs diff --git a/tests/rustdoc/impl/extern-impl-trait.rs b/tests/rustdoc-html/impl/extern-impl-trait.rs similarity index 100% rename from tests/rustdoc/impl/extern-impl-trait.rs rename to tests/rustdoc-html/impl/extern-impl-trait.rs diff --git a/tests/rustdoc/impl/extern-impl.rs b/tests/rustdoc-html/impl/extern-impl.rs similarity index 100% rename from tests/rustdoc/impl/extern-impl.rs rename to tests/rustdoc-html/impl/extern-impl.rs diff --git a/tests/rustdoc/impl/foreign-implementors-js-43701.rs b/tests/rustdoc-html/impl/foreign-implementors-js-43701.rs similarity index 100% rename from tests/rustdoc/impl/foreign-implementors-js-43701.rs rename to tests/rustdoc-html/impl/foreign-implementors-js-43701.rs diff --git a/tests/rustdoc/impl/generic-impl.rs b/tests/rustdoc-html/impl/generic-impl.rs similarity index 100% rename from tests/rustdoc/impl/generic-impl.rs rename to tests/rustdoc-html/impl/generic-impl.rs diff --git a/tests/rustdoc/impl/hidden-implementors-90781.rs b/tests/rustdoc-html/impl/hidden-implementors-90781.rs similarity index 100% rename from tests/rustdoc/impl/hidden-implementors-90781.rs rename to tests/rustdoc-html/impl/hidden-implementors-90781.rs diff --git a/tests/rustdoc/impl/hidden-impls.rs b/tests/rustdoc-html/impl/hidden-impls.rs similarity index 100% rename from tests/rustdoc/impl/hidden-impls.rs rename to tests/rustdoc-html/impl/hidden-impls.rs diff --git a/tests/rustdoc/impl/hidden-trait-struct-impls.rs b/tests/rustdoc-html/impl/hidden-trait-struct-impls.rs similarity index 100% rename from tests/rustdoc/impl/hidden-trait-struct-impls.rs rename to tests/rustdoc-html/impl/hidden-trait-struct-impls.rs diff --git a/tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs b/tests/rustdoc-html/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs similarity index 100% rename from tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs rename to tests/rustdoc-html/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs diff --git a/tests/rustdoc/impl/impl-alias-substituted.rs b/tests/rustdoc-html/impl/impl-alias-substituted.rs similarity index 100% rename from tests/rustdoc/impl/impl-alias-substituted.rs rename to tests/rustdoc-html/impl/impl-alias-substituted.rs diff --git a/tests/rustdoc/impl/impl-assoc-type-21092.rs b/tests/rustdoc-html/impl/impl-assoc-type-21092.rs similarity index 100% rename from tests/rustdoc/impl/impl-assoc-type-21092.rs rename to tests/rustdoc-html/impl/impl-assoc-type-21092.rs diff --git a/tests/rustdoc/impl/impl-associated-items-order.rs b/tests/rustdoc-html/impl/impl-associated-items-order.rs similarity index 100% rename from tests/rustdoc/impl/impl-associated-items-order.rs rename to tests/rustdoc-html/impl/impl-associated-items-order.rs diff --git a/tests/rustdoc/impl/impl-associated-items-sidebar.rs b/tests/rustdoc-html/impl/impl-associated-items-sidebar.rs similarity index 100% rename from tests/rustdoc/impl/impl-associated-items-sidebar.rs rename to tests/rustdoc-html/impl/impl-associated-items-sidebar.rs diff --git a/tests/rustdoc/impl/impl-blanket-53689.rs b/tests/rustdoc-html/impl/impl-blanket-53689.rs similarity index 100% rename from tests/rustdoc/impl/impl-blanket-53689.rs rename to tests/rustdoc-html/impl/impl-blanket-53689.rs diff --git a/tests/rustdoc/impl/impl-box.rs b/tests/rustdoc-html/impl/impl-box.rs similarity index 100% rename from tests/rustdoc/impl/impl-box.rs rename to tests/rustdoc-html/impl/impl-box.rs diff --git a/tests/rustdoc/impl/impl-disambiguation.rs b/tests/rustdoc-html/impl/impl-disambiguation.rs similarity index 100% rename from tests/rustdoc/impl/impl-disambiguation.rs rename to tests/rustdoc-html/impl/impl-disambiguation.rs diff --git a/tests/rustdoc/impl/impl-everywhere.rs b/tests/rustdoc-html/impl/impl-everywhere.rs similarity index 100% rename from tests/rustdoc/impl/impl-everywhere.rs rename to tests/rustdoc-html/impl/impl-everywhere.rs diff --git a/tests/rustdoc/impl/impl-in-const-block.rs b/tests/rustdoc-html/impl/impl-in-const-block.rs similarity index 100% rename from tests/rustdoc/impl/impl-in-const-block.rs rename to tests/rustdoc-html/impl/impl-in-const-block.rs diff --git a/tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs b/tests/rustdoc-html/impl/impl-on-ty-alias-issue-119015.rs similarity index 100% rename from tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs rename to tests/rustdoc-html/impl/impl-on-ty-alias-issue-119015.rs diff --git a/tests/rustdoc/impl/impl-parts-crosscrate.rs b/tests/rustdoc-html/impl/impl-parts-crosscrate.rs similarity index 100% rename from tests/rustdoc/impl/impl-parts-crosscrate.rs rename to tests/rustdoc-html/impl/impl-parts-crosscrate.rs diff --git a/tests/rustdoc/impl/impl-parts.rs b/tests/rustdoc-html/impl/impl-parts.rs similarity index 100% rename from tests/rustdoc/impl/impl-parts.rs rename to tests/rustdoc-html/impl/impl-parts.rs diff --git a/tests/rustdoc/impl/impl-ref-20175.rs b/tests/rustdoc-html/impl/impl-ref-20175.rs similarity index 100% rename from tests/rustdoc/impl/impl-ref-20175.rs rename to tests/rustdoc-html/impl/impl-ref-20175.rs diff --git a/tests/rustdoc/impl/impl-trait-43869.rs b/tests/rustdoc-html/impl/impl-trait-43869.rs similarity index 100% rename from tests/rustdoc/impl/impl-trait-43869.rs rename to tests/rustdoc-html/impl/impl-trait-43869.rs diff --git a/tests/rustdoc/impl/impl-trait-alias.rs b/tests/rustdoc-html/impl/impl-trait-alias.rs similarity index 100% rename from tests/rustdoc/impl/impl-trait-alias.rs rename to tests/rustdoc-html/impl/impl-trait-alias.rs diff --git a/tests/rustdoc/impl/impl-trait-precise-capturing.rs b/tests/rustdoc-html/impl/impl-trait-precise-capturing.rs similarity index 100% rename from tests/rustdoc/impl/impl-trait-precise-capturing.rs rename to tests/rustdoc-html/impl/impl-trait-precise-capturing.rs diff --git a/tests/rustdoc/impl/impl-type-parameter-33592.rs b/tests/rustdoc-html/impl/impl-type-parameter-33592.rs similarity index 100% rename from tests/rustdoc/impl/impl-type-parameter-33592.rs rename to tests/rustdoc-html/impl/impl-type-parameter-33592.rs diff --git a/tests/rustdoc/impl/implementor-stable-version.rs b/tests/rustdoc-html/impl/implementor-stable-version.rs similarity index 100% rename from tests/rustdoc/impl/implementor-stable-version.rs rename to tests/rustdoc-html/impl/implementor-stable-version.rs diff --git a/tests/rustdoc/impl/implementors-unstable-75588.rs b/tests/rustdoc-html/impl/implementors-unstable-75588.rs similarity index 100% rename from tests/rustdoc/impl/implementors-unstable-75588.rs rename to tests/rustdoc-html/impl/implementors-unstable-75588.rs diff --git a/tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs b/tests/rustdoc-html/impl/inline-impl-through-glob-import-100204.rs similarity index 100% rename from tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs rename to tests/rustdoc-html/impl/inline-impl-through-glob-import-100204.rs diff --git a/tests/rustdoc/impl/manual_impl.rs b/tests/rustdoc-html/impl/manual_impl.rs similarity index 100% rename from tests/rustdoc/impl/manual_impl.rs rename to tests/rustdoc-html/impl/manual_impl.rs diff --git a/tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs b/tests/rustdoc-html/impl/method-link-foreign-trait-impl-17476.rs similarity index 100% rename from tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs rename to tests/rustdoc-html/impl/method-link-foreign-trait-impl-17476.rs diff --git a/tests/rustdoc/impl/module-impls.rs b/tests/rustdoc-html/impl/module-impls.rs similarity index 100% rename from tests/rustdoc/impl/module-impls.rs rename to tests/rustdoc-html/impl/module-impls.rs diff --git a/tests/rustdoc/impl/must_implement_one_of.rs b/tests/rustdoc-html/impl/must_implement_one_of.rs similarity index 100% rename from tests/rustdoc/impl/must_implement_one_of.rs rename to tests/rustdoc-html/impl/must_implement_one_of.rs diff --git a/tests/rustdoc/impl/negative-impl-no-items.rs b/tests/rustdoc-html/impl/negative-impl-no-items.rs similarity index 100% rename from tests/rustdoc/impl/negative-impl-no-items.rs rename to tests/rustdoc-html/impl/negative-impl-no-items.rs diff --git a/tests/rustdoc/impl/negative-impl-sidebar.rs b/tests/rustdoc-html/impl/negative-impl-sidebar.rs similarity index 100% rename from tests/rustdoc/impl/negative-impl-sidebar.rs rename to tests/rustdoc-html/impl/negative-impl-sidebar.rs diff --git a/tests/rustdoc/impl/negative-impl.rs b/tests/rustdoc-html/impl/negative-impl.rs similarity index 100% rename from tests/rustdoc/impl/negative-impl.rs rename to tests/rustdoc-html/impl/negative-impl.rs diff --git a/tests/rustdoc/impl/return-impl-trait.rs b/tests/rustdoc-html/impl/return-impl-trait.rs similarity index 100% rename from tests/rustdoc/impl/return-impl-trait.rs rename to tests/rustdoc-html/impl/return-impl-trait.rs diff --git a/tests/rustdoc/impl/rustc-incoherent-impls.rs b/tests/rustdoc-html/impl/rustc-incoherent-impls.rs similarity index 100% rename from tests/rustdoc/impl/rustc-incoherent-impls.rs rename to tests/rustdoc-html/impl/rustc-incoherent-impls.rs diff --git a/tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs b/tests/rustdoc-html/impl/same-crate-hidden-impl-parameter.rs similarity index 100% rename from tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs rename to tests/rustdoc-html/impl/same-crate-hidden-impl-parameter.rs diff --git a/tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs b/tests/rustdoc-html/impl/sidebar-trait-impl-disambiguate-78701.rs similarity index 100% rename from tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs rename to tests/rustdoc-html/impl/sidebar-trait-impl-disambiguate-78701.rs diff --git a/tests/rustdoc/impl/struct-implementations-title.rs b/tests/rustdoc-html/impl/struct-implementations-title.rs similarity index 100% rename from tests/rustdoc/impl/struct-implementations-title.rs rename to tests/rustdoc-html/impl/struct-implementations-title.rs diff --git a/tests/rustdoc/impl/trait-impl.rs b/tests/rustdoc-html/impl/trait-impl.rs similarity index 100% rename from tests/rustdoc/impl/trait-impl.rs rename to tests/rustdoc-html/impl/trait-impl.rs diff --git a/tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs b/tests/rustdoc-html/impl/trait-implementations-duplicate-self-45584.rs similarity index 100% rename from tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs rename to tests/rustdoc-html/impl/trait-implementations-duplicate-self-45584.rs diff --git a/tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs b/tests/rustdoc-html/impl/underscore-type-in-trait-impl-96381.rs similarity index 100% rename from tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs rename to tests/rustdoc-html/impl/underscore-type-in-trait-impl-96381.rs diff --git a/tests/rustdoc/impl/universal-impl-trait.rs b/tests/rustdoc-html/impl/universal-impl-trait.rs similarity index 100% rename from tests/rustdoc/impl/universal-impl-trait.rs rename to tests/rustdoc-html/impl/universal-impl-trait.rs diff --git a/tests/rustdoc/impl/unneeded-trait-implementations-title.rs b/tests/rustdoc-html/impl/unneeded-trait-implementations-title.rs similarity index 100% rename from tests/rustdoc/impl/unneeded-trait-implementations-title.rs rename to tests/rustdoc-html/impl/unneeded-trait-implementations-title.rs diff --git a/tests/rustdoc/import-remapped-paths.rs b/tests/rustdoc-html/import-remapped-paths.rs similarity index 100% rename from tests/rustdoc/import-remapped-paths.rs rename to tests/rustdoc-html/import-remapped-paths.rs diff --git a/tests/rustdoc/impossible-default.rs b/tests/rustdoc-html/impossible-default.rs similarity index 100% rename from tests/rustdoc/impossible-default.rs rename to tests/rustdoc-html/impossible-default.rs diff --git a/tests/rustdoc/include_str_cut.rs b/tests/rustdoc-html/include_str_cut.rs similarity index 100% rename from tests/rustdoc/include_str_cut.rs rename to tests/rustdoc-html/include_str_cut.rs diff --git a/tests/rustdoc/index-page.rs b/tests/rustdoc-html/index-page.rs similarity index 100% rename from tests/rustdoc/index-page.rs rename to tests/rustdoc-html/index-page.rs diff --git a/tests/rustdoc/infinite-redirection-16265-1.rs b/tests/rustdoc-html/infinite-redirection-16265-1.rs similarity index 100% rename from tests/rustdoc/infinite-redirection-16265-1.rs rename to tests/rustdoc-html/infinite-redirection-16265-1.rs diff --git a/tests/rustdoc/infinite-redirection-16265-2.rs b/tests/rustdoc-html/infinite-redirection-16265-2.rs similarity index 100% rename from tests/rustdoc/infinite-redirection-16265-2.rs rename to tests/rustdoc-html/infinite-redirection-16265-2.rs diff --git a/tests/rustdoc/infinite-redirection.rs b/tests/rustdoc-html/infinite-redirection.rs similarity index 100% rename from tests/rustdoc/infinite-redirection.rs rename to tests/rustdoc-html/infinite-redirection.rs diff --git a/tests/rustdoc/inherent-projections.rs b/tests/rustdoc-html/inherent-projections.rs similarity index 100% rename from tests/rustdoc/inherent-projections.rs rename to tests/rustdoc-html/inherent-projections.rs diff --git a/tests/rustdoc/inline-default-methods.rs b/tests/rustdoc-html/inline-default-methods.rs similarity index 100% rename from tests/rustdoc/inline-default-methods.rs rename to tests/rustdoc-html/inline-default-methods.rs diff --git a/tests/rustdoc/inline-rename-34473.rs b/tests/rustdoc-html/inline-rename-34473.rs similarity index 100% rename from tests/rustdoc/inline-rename-34473.rs rename to tests/rustdoc-html/inline-rename-34473.rs diff --git a/tests/rustdoc/inline_cross/add-docs.rs b/tests/rustdoc-html/inline_cross/add-docs.rs similarity index 100% rename from tests/rustdoc/inline_cross/add-docs.rs rename to tests/rustdoc-html/inline_cross/add-docs.rs diff --git a/tests/rustdoc/inline_cross/assoc-const-equality.rs b/tests/rustdoc-html/inline_cross/assoc-const-equality.rs similarity index 100% rename from tests/rustdoc/inline_cross/assoc-const-equality.rs rename to tests/rustdoc-html/inline_cross/assoc-const-equality.rs diff --git a/tests/rustdoc/inline_cross/assoc-items.rs b/tests/rustdoc-html/inline_cross/assoc-items.rs similarity index 100% rename from tests/rustdoc/inline_cross/assoc-items.rs rename to tests/rustdoc-html/inline_cross/assoc-items.rs diff --git a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.out0.html b/tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out0.html similarity index 100% rename from tests/rustdoc/inline_cross/assoc_item_trait_bounds.out0.html rename to tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out0.html diff --git a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.out2.html b/tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out2.html similarity index 100% rename from tests/rustdoc/inline_cross/assoc_item_trait_bounds.out2.html rename to tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out2.html diff --git a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.out9.html b/tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out9.html similarity index 100% rename from tests/rustdoc/inline_cross/assoc_item_trait_bounds.out9.html rename to tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out9.html diff --git a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.rs b/tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.rs similarity index 100% rename from tests/rustdoc/inline_cross/assoc_item_trait_bounds.rs rename to tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.rs diff --git a/tests/rustdoc/inline_cross/async-fn.rs b/tests/rustdoc-html/inline_cross/async-fn.rs similarity index 100% rename from tests/rustdoc/inline_cross/async-fn.rs rename to tests/rustdoc-html/inline_cross/async-fn.rs diff --git a/tests/rustdoc/inline_cross/attributes.rs b/tests/rustdoc-html/inline_cross/attributes.rs similarity index 100% rename from tests/rustdoc/inline_cross/attributes.rs rename to tests/rustdoc-html/inline_cross/attributes.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/add-docs.rs b/tests/rustdoc-html/inline_cross/auxiliary/add-docs.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/add-docs.rs rename to tests/rustdoc-html/inline_cross/auxiliary/add-docs.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs b/tests/rustdoc-html/inline_cross/auxiliary/assoc-const-equality.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs rename to tests/rustdoc-html/inline_cross/auxiliary/assoc-const-equality.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc-items.rs b/tests/rustdoc-html/inline_cross/auxiliary/assoc-items.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/assoc-items.rs rename to tests/rustdoc-html/inline_cross/auxiliary/assoc-items.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs b/tests/rustdoc-html/inline_cross/auxiliary/assoc_item_trait_bounds.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs rename to tests/rustdoc-html/inline_cross/auxiliary/assoc_item_trait_bounds.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/async-fn.rs b/tests/rustdoc-html/inline_cross/auxiliary/async-fn.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/async-fn.rs rename to tests/rustdoc-html/inline_cross/auxiliary/async-fn.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/attributes.rs b/tests/rustdoc-html/inline_cross/auxiliary/attributes.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/attributes.rs rename to tests/rustdoc-html/inline_cross/auxiliary/attributes.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs b/tests/rustdoc-html/inline_cross/auxiliary/const-effect-param.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs rename to tests/rustdoc-html/inline_cross/auxiliary/const-effect-param.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/cross-glob.rs b/tests/rustdoc-html/inline_cross/auxiliary/cross-glob.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/cross-glob.rs rename to tests/rustdoc-html/inline_cross/auxiliary/cross-glob.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/default-generic-args.rs b/tests/rustdoc-html/inline_cross/auxiliary/default-generic-args.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/default-generic-args.rs rename to tests/rustdoc-html/inline_cross/auxiliary/default-generic-args.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/default-trait-method.rs b/tests/rustdoc-html/inline_cross/auxiliary/default-trait-method.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/default-trait-method.rs rename to tests/rustdoc-html/inline_cross/auxiliary/default-trait-method.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/doc-auto-cfg.rs b/tests/rustdoc-html/inline_cross/auxiliary/doc-auto-cfg.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/doc-auto-cfg.rs rename to tests/rustdoc-html/inline_cross/auxiliary/doc-auto-cfg.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs b/tests/rustdoc-html/inline_cross/auxiliary/dyn_trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs rename to tests/rustdoc-html/inline_cross/auxiliary/dyn_trait.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/early-late-bound-lifetime-params.rs b/tests/rustdoc-html/inline_cross/auxiliary/early-late-bound-lifetime-params.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/early-late-bound-lifetime-params.rs rename to tests/rustdoc-html/inline_cross/auxiliary/early-late-bound-lifetime-params.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/fn-ptr-ty.rs b/tests/rustdoc-html/inline_cross/auxiliary/fn-ptr-ty.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/fn-ptr-ty.rs rename to tests/rustdoc-html/inline_cross/auxiliary/fn-ptr-ty.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/generic-const-items.rs b/tests/rustdoc-html/inline_cross/auxiliary/generic-const-items.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/generic-const-items.rs rename to tests/rustdoc-html/inline_cross/auxiliary/generic-const-items.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs b/tests/rustdoc-html/inline_cross/auxiliary/impl-inline-without-trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs rename to tests/rustdoc-html/inline_cross/auxiliary/impl-inline-without-trait.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/impl-sized.rs b/tests/rustdoc-html/inline_cross/auxiliary/impl-sized.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/impl-sized.rs rename to tests/rustdoc-html/inline_cross/auxiliary/impl-sized.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/tests/rustdoc-html/inline_cross/auxiliary/impl_trait_aux.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs rename to tests/rustdoc-html/inline_cross/auxiliary/impl_trait_aux.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/implementors_inline.rs b/tests/rustdoc-html/inline_cross/auxiliary/implementors_inline.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/implementors_inline.rs rename to tests/rustdoc-html/inline_cross/auxiliary/implementors_inline.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-21801.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-21801.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-21801.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-21801.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-23207-1.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-23207-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-23207-1.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-23207-1.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-23207-2.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-23207-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-23207-2.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-23207-2.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-24183.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-24183.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-24183.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-24183.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-27362-aux.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-27362-aux.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-27362-aux.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-27362-aux.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-29584.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-29584.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-29584.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-29584.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-33113.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-33113.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-33113.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-33113.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-46727.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-46727.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-46727.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-46727.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-57180.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-57180.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-57180.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-57180.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-76736-1.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-76736-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-76736-1.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-76736-1.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-76736-2.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-76736-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-76736-2.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-76736-2.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-85454.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-85454.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-85454.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-85454.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/macro-vis.rs b/tests/rustdoc-html/inline_cross/auxiliary/macro-vis.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/macro-vis.rs rename to tests/rustdoc-html/inline_cross/auxiliary/macro-vis.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/macros.rs b/tests/rustdoc-html/inline_cross/auxiliary/macros.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/macros.rs rename to tests/rustdoc-html/inline_cross/auxiliary/macros.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/non_lifetime_binders.rs b/tests/rustdoc-html/inline_cross/auxiliary/non_lifetime_binders.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/non_lifetime_binders.rs rename to tests/rustdoc-html/inline_cross/auxiliary/non_lifetime_binders.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/proc_macro.rs b/tests/rustdoc-html/inline_cross/auxiliary/proc_macro.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/proc_macro.rs rename to tests/rustdoc-html/inline_cross/auxiliary/proc_macro.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/reexport-with-anonymous-lifetime-98697.rs b/tests/rustdoc-html/inline_cross/auxiliary/reexport-with-anonymous-lifetime-98697.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/reexport-with-anonymous-lifetime-98697.rs rename to tests/rustdoc-html/inline_cross/auxiliary/reexport-with-anonymous-lifetime-98697.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/renamed-via-module.rs b/tests/rustdoc-html/inline_cross/auxiliary/renamed-via-module.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/renamed-via-module.rs rename to tests/rustdoc-html/inline_cross/auxiliary/renamed-via-module.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs b/tests/rustdoc-html/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs rename to tests/rustdoc-html/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/rustdoc-hidden-sig.rs b/tests/rustdoc-html/inline_cross/auxiliary/rustdoc-hidden-sig.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/rustdoc-hidden-sig.rs rename to tests/rustdoc-html/inline_cross/auxiliary/rustdoc-hidden-sig.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/rustdoc-hidden.rs b/tests/rustdoc-html/inline_cross/auxiliary/rustdoc-hidden.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/rustdoc-hidden.rs rename to tests/rustdoc-html/inline_cross/auxiliary/rustdoc-hidden.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs b/tests/rustdoc-html/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs rename to tests/rustdoc-html/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs b/tests/rustdoc-html/inline_cross/auxiliary/rustdoc-trait-object-impl.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs rename to tests/rustdoc-html/inline_cross/auxiliary/rustdoc-trait-object-impl.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/trait-vis.rs b/tests/rustdoc-html/inline_cross/auxiliary/trait-vis.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/trait-vis.rs rename to tests/rustdoc-html/inline_cross/auxiliary/trait-vis.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/use_crate.rs b/tests/rustdoc-html/inline_cross/auxiliary/use_crate.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/use_crate.rs rename to tests/rustdoc-html/inline_cross/auxiliary/use_crate.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/use_crate_2.rs b/tests/rustdoc-html/inline_cross/auxiliary/use_crate_2.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/use_crate_2.rs rename to tests/rustdoc-html/inline_cross/auxiliary/use_crate_2.rs diff --git a/tests/rustdoc/inline_cross/const-effect-param.rs b/tests/rustdoc-html/inline_cross/const-effect-param.rs similarity index 100% rename from tests/rustdoc/inline_cross/const-effect-param.rs rename to tests/rustdoc-html/inline_cross/const-effect-param.rs diff --git a/tests/rustdoc/inline_cross/const-eval-46727.rs b/tests/rustdoc-html/inline_cross/const-eval-46727.rs similarity index 100% rename from tests/rustdoc/inline_cross/const-eval-46727.rs rename to tests/rustdoc-html/inline_cross/const-eval-46727.rs diff --git a/tests/rustdoc/inline_cross/const-fn-27362.rs b/tests/rustdoc-html/inline_cross/const-fn-27362.rs similarity index 100% rename from tests/rustdoc/inline_cross/const-fn-27362.rs rename to tests/rustdoc-html/inline_cross/const-fn-27362.rs diff --git a/tests/rustdoc/inline_cross/cross-glob.rs b/tests/rustdoc-html/inline_cross/cross-glob.rs similarity index 100% rename from tests/rustdoc/inline_cross/cross-glob.rs rename to tests/rustdoc-html/inline_cross/cross-glob.rs diff --git a/tests/rustdoc/inline_cross/deduplicate-inlined-items-23207.rs b/tests/rustdoc-html/inline_cross/deduplicate-inlined-items-23207.rs similarity index 100% rename from tests/rustdoc/inline_cross/deduplicate-inlined-items-23207.rs rename to tests/rustdoc-html/inline_cross/deduplicate-inlined-items-23207.rs diff --git a/tests/rustdoc/inline_cross/default-generic-args.rs b/tests/rustdoc-html/inline_cross/default-generic-args.rs similarity index 100% rename from tests/rustdoc/inline_cross/default-generic-args.rs rename to tests/rustdoc-html/inline_cross/default-generic-args.rs diff --git a/tests/rustdoc/inline_cross/default-trait-method.rs b/tests/rustdoc-html/inline_cross/default-trait-method.rs similarity index 100% rename from tests/rustdoc/inline_cross/default-trait-method.rs rename to tests/rustdoc-html/inline_cross/default-trait-method.rs diff --git a/tests/rustdoc/inline_cross/doc-auto-cfg.rs b/tests/rustdoc-html/inline_cross/doc-auto-cfg.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-auto-cfg.rs rename to tests/rustdoc-html/inline_cross/doc-auto-cfg.rs diff --git a/tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs b/tests/rustdoc-html/inline_cross/doc-hidden-broken-link-28480.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs rename to tests/rustdoc-html/inline_cross/doc-hidden-broken-link-28480.rs diff --git a/tests/rustdoc/inline_cross/doc-hidden-extern-trait-impl-29584.rs b/tests/rustdoc-html/inline_cross/doc-hidden-extern-trait-impl-29584.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-hidden-extern-trait-impl-29584.rs rename to tests/rustdoc-html/inline_cross/doc-hidden-extern-trait-impl-29584.rs diff --git a/tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs b/tests/rustdoc-html/inline_cross/doc-reachability-impl-31948-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs rename to tests/rustdoc-html/inline_cross/doc-reachability-impl-31948-1.rs diff --git a/tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs b/tests/rustdoc-html/inline_cross/doc-reachability-impl-31948-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs rename to tests/rustdoc-html/inline_cross/doc-reachability-impl-31948-2.rs diff --git a/tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs b/tests/rustdoc-html/inline_cross/doc-reachability-impl-31948.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs rename to tests/rustdoc-html/inline_cross/doc-reachability-impl-31948.rs diff --git a/tests/rustdoc/inline_cross/dyn_trait.rs b/tests/rustdoc-html/inline_cross/dyn_trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/dyn_trait.rs rename to tests/rustdoc-html/inline_cross/dyn_trait.rs diff --git a/tests/rustdoc/inline_cross/early-late-bound-lifetime-params.rs b/tests/rustdoc-html/inline_cross/early-late-bound-lifetime-params.rs similarity index 100% rename from tests/rustdoc/inline_cross/early-late-bound-lifetime-params.rs rename to tests/rustdoc-html/inline_cross/early-late-bound-lifetime-params.rs diff --git a/tests/rustdoc/inline_cross/fn-ptr-ty.rs b/tests/rustdoc-html/inline_cross/fn-ptr-ty.rs similarity index 100% rename from tests/rustdoc/inline_cross/fn-ptr-ty.rs rename to tests/rustdoc-html/inline_cross/fn-ptr-ty.rs diff --git a/tests/rustdoc/inline_cross/generic-const-items.rs b/tests/rustdoc-html/inline_cross/generic-const-items.rs similarity index 100% rename from tests/rustdoc/inline_cross/generic-const-items.rs rename to tests/rustdoc-html/inline_cross/generic-const-items.rs diff --git a/tests/rustdoc/inline_cross/hidden-use.rs b/tests/rustdoc-html/inline_cross/hidden-use.rs similarity index 100% rename from tests/rustdoc/inline_cross/hidden-use.rs rename to tests/rustdoc-html/inline_cross/hidden-use.rs diff --git a/tests/rustdoc/inline_cross/ice-import-crate-57180.rs b/tests/rustdoc-html/inline_cross/ice-import-crate-57180.rs similarity index 100% rename from tests/rustdoc/inline_cross/ice-import-crate-57180.rs rename to tests/rustdoc-html/inline_cross/ice-import-crate-57180.rs diff --git a/tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs b/tests/rustdoc-html/inline_cross/impl-dyn-trait-32881.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs rename to tests/rustdoc-html/inline_cross/impl-dyn-trait-32881.rs diff --git a/tests/rustdoc/inline_cross/impl-inline-without-trait.rs b/tests/rustdoc-html/inline_cross/impl-inline-without-trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl-inline-without-trait.rs rename to tests/rustdoc-html/inline_cross/impl-inline-without-trait.rs diff --git a/tests/rustdoc/inline_cross/impl-ref-33113.rs b/tests/rustdoc-html/inline_cross/impl-ref-33113.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl-ref-33113.rs rename to tests/rustdoc-html/inline_cross/impl-ref-33113.rs diff --git a/tests/rustdoc/inline_cross/impl-sized.rs b/tests/rustdoc-html/inline_cross/impl-sized.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl-sized.rs rename to tests/rustdoc-html/inline_cross/impl-sized.rs diff --git a/tests/rustdoc/inline_cross/impl_trait.rs b/tests/rustdoc-html/inline_cross/impl_trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl_trait.rs rename to tests/rustdoc-html/inline_cross/impl_trait.rs diff --git a/tests/rustdoc/inline_cross/implementors-js.rs b/tests/rustdoc-html/inline_cross/implementors-js.rs similarity index 100% rename from tests/rustdoc/inline_cross/implementors-js.rs rename to tests/rustdoc-html/inline_cross/implementors-js.rs diff --git a/tests/rustdoc/inline_cross/inline_hidden.rs b/tests/rustdoc-html/inline_cross/inline_hidden.rs similarity index 100% rename from tests/rustdoc/inline_cross/inline_hidden.rs rename to tests/rustdoc-html/inline_cross/inline_hidden.rs diff --git a/tests/rustdoc/inline_cross/macro-vis.rs b/tests/rustdoc-html/inline_cross/macro-vis.rs similarity index 100% rename from tests/rustdoc/inline_cross/macro-vis.rs rename to tests/rustdoc-html/inline_cross/macro-vis.rs diff --git a/tests/rustdoc/inline_cross/macros.rs b/tests/rustdoc-html/inline_cross/macros.rs similarity index 100% rename from tests/rustdoc/inline_cross/macros.rs rename to tests/rustdoc-html/inline_cross/macros.rs diff --git a/tests/rustdoc/inline_cross/non_lifetime_binders.rs b/tests/rustdoc-html/inline_cross/non_lifetime_binders.rs similarity index 100% rename from tests/rustdoc/inline_cross/non_lifetime_binders.rs rename to tests/rustdoc-html/inline_cross/non_lifetime_binders.rs diff --git a/tests/rustdoc/inline_cross/proc_macro.rs b/tests/rustdoc-html/inline_cross/proc_macro.rs similarity index 100% rename from tests/rustdoc/inline_cross/proc_macro.rs rename to tests/rustdoc-html/inline_cross/proc_macro.rs diff --git a/tests/rustdoc/inline_cross/qpath-self-85454.rs b/tests/rustdoc-html/inline_cross/qpath-self-85454.rs similarity index 100% rename from tests/rustdoc/inline_cross/qpath-self-85454.rs rename to tests/rustdoc-html/inline_cross/qpath-self-85454.rs diff --git a/tests/rustdoc/inline_cross/reexport-with-anonymous-lifetime-98697.rs b/tests/rustdoc-html/inline_cross/reexport-with-anonymous-lifetime-98697.rs similarity index 100% rename from tests/rustdoc/inline_cross/reexport-with-anonymous-lifetime-98697.rs rename to tests/rustdoc-html/inline_cross/reexport-with-anonymous-lifetime-98697.rs diff --git a/tests/rustdoc/inline_cross/renamed-via-module.rs b/tests/rustdoc-html/inline_cross/renamed-via-module.rs similarity index 100% rename from tests/rustdoc/inline_cross/renamed-via-module.rs rename to tests/rustdoc-html/inline_cross/renamed-via-module.rs diff --git a/tests/rustdoc/inline_cross/ret-pos-impl-trait-in-trait.rs b/tests/rustdoc-html/inline_cross/ret-pos-impl-trait-in-trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/ret-pos-impl-trait-in-trait.rs rename to tests/rustdoc-html/inline_cross/ret-pos-impl-trait-in-trait.rs diff --git a/tests/rustdoc/inline_cross/rustc-private-76736-1.rs b/tests/rustdoc-html/inline_cross/rustc-private-76736-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/rustc-private-76736-1.rs rename to tests/rustdoc-html/inline_cross/rustc-private-76736-1.rs diff --git a/tests/rustdoc/inline_cross/rustc-private-76736-2.rs b/tests/rustdoc-html/inline_cross/rustc-private-76736-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/rustc-private-76736-2.rs rename to tests/rustdoc-html/inline_cross/rustc-private-76736-2.rs diff --git a/tests/rustdoc/inline_cross/rustc-private-76736-3.rs b/tests/rustdoc-html/inline_cross/rustc-private-76736-3.rs similarity index 100% rename from tests/rustdoc/inline_cross/rustc-private-76736-3.rs rename to tests/rustdoc-html/inline_cross/rustc-private-76736-3.rs diff --git a/tests/rustdoc/inline_cross/rustc-private-76736-4.rs b/tests/rustdoc-html/inline_cross/rustc-private-76736-4.rs similarity index 100% rename from tests/rustdoc/inline_cross/rustc-private-76736-4.rs rename to tests/rustdoc-html/inline_cross/rustc-private-76736-4.rs diff --git a/tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html b/tests/rustdoc-html/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html similarity index 100% rename from tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html rename to tests/rustdoc-html/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html diff --git a/tests/rustdoc/inline_cross/self-sized-bounds-24183.rs b/tests/rustdoc-html/inline_cross/self-sized-bounds-24183.rs similarity index 100% rename from tests/rustdoc/inline_cross/self-sized-bounds-24183.rs rename to tests/rustdoc-html/inline_cross/self-sized-bounds-24183.rs diff --git a/tests/rustdoc/inline_cross/sugar-closure-crate-21801.rs b/tests/rustdoc-html/inline_cross/sugar-closure-crate-21801.rs similarity index 100% rename from tests/rustdoc/inline_cross/sugar-closure-crate-21801.rs rename to tests/rustdoc-html/inline_cross/sugar-closure-crate-21801.rs diff --git a/tests/rustdoc/inline_cross/trait-vis.rs b/tests/rustdoc-html/inline_cross/trait-vis.rs similarity index 100% rename from tests/rustdoc/inline_cross/trait-vis.rs rename to tests/rustdoc-html/inline_cross/trait-vis.rs diff --git a/tests/rustdoc/inline_cross/use_crate.rs b/tests/rustdoc-html/inline_cross/use_crate.rs similarity index 100% rename from tests/rustdoc/inline_cross/use_crate.rs rename to tests/rustdoc-html/inline_cross/use_crate.rs diff --git a/tests/rustdoc/inline_local/blanket-impl-reexported-trait-94183.rs b/tests/rustdoc-html/inline_local/blanket-impl-reexported-trait-94183.rs similarity index 100% rename from tests/rustdoc/inline_local/blanket-impl-reexported-trait-94183.rs rename to tests/rustdoc-html/inline_local/blanket-impl-reexported-trait-94183.rs diff --git a/tests/rustdoc/inline_local/doc-no-inline-32343.rs b/tests/rustdoc-html/inline_local/doc-no-inline-32343.rs similarity index 100% rename from tests/rustdoc/inline_local/doc-no-inline-32343.rs rename to tests/rustdoc-html/inline_local/doc-no-inline-32343.rs diff --git a/tests/rustdoc/inline_local/enum-variant-reexport-46766.rs b/tests/rustdoc-html/inline_local/enum-variant-reexport-46766.rs similarity index 100% rename from tests/rustdoc/inline_local/enum-variant-reexport-46766.rs rename to tests/rustdoc-html/inline_local/enum-variant-reexport-46766.rs diff --git a/tests/rustdoc/inline_local/fully-stable-path-is-better.rs b/tests/rustdoc-html/inline_local/fully-stable-path-is-better.rs similarity index 100% rename from tests/rustdoc/inline_local/fully-stable-path-is-better.rs rename to tests/rustdoc-html/inline_local/fully-stable-path-is-better.rs diff --git a/tests/rustdoc/inline_local/glob-extern-document-private-items.rs b/tests/rustdoc-html/inline_local/glob-extern-document-private-items.rs similarity index 100% rename from tests/rustdoc/inline_local/glob-extern-document-private-items.rs rename to tests/rustdoc-html/inline_local/glob-extern-document-private-items.rs diff --git a/tests/rustdoc/inline_local/glob-extern.rs b/tests/rustdoc-html/inline_local/glob-extern.rs similarity index 100% rename from tests/rustdoc/inline_local/glob-extern.rs rename to tests/rustdoc-html/inline_local/glob-extern.rs diff --git a/tests/rustdoc/inline_local/glob-private-document-private-items.rs b/tests/rustdoc-html/inline_local/glob-private-document-private-items.rs similarity index 100% rename from tests/rustdoc/inline_local/glob-private-document-private-items.rs rename to tests/rustdoc-html/inline_local/glob-private-document-private-items.rs diff --git a/tests/rustdoc/inline_local/glob-private.rs b/tests/rustdoc-html/inline_local/glob-private.rs similarity index 100% rename from tests/rustdoc/inline_local/glob-private.rs rename to tests/rustdoc-html/inline_local/glob-private.rs diff --git a/tests/rustdoc/inline_local/hidden-use.rs b/tests/rustdoc-html/inline_local/hidden-use.rs similarity index 100% rename from tests/rustdoc/inline_local/hidden-use.rs rename to tests/rustdoc-html/inline_local/hidden-use.rs diff --git a/tests/rustdoc/inline_local/macro_by_example.rs b/tests/rustdoc-html/inline_local/macro_by_example.rs similarity index 100% rename from tests/rustdoc/inline_local/macro_by_example.rs rename to tests/rustdoc-html/inline_local/macro_by_example.rs diff --git a/tests/rustdoc/inline_local/parent-path-is-better.rs b/tests/rustdoc-html/inline_local/parent-path-is-better.rs similarity index 100% rename from tests/rustdoc/inline_local/parent-path-is-better.rs rename to tests/rustdoc-html/inline_local/parent-path-is-better.rs diff --git a/tests/rustdoc/inline_local/please_inline.rs b/tests/rustdoc-html/inline_local/please_inline.rs similarity index 100% rename from tests/rustdoc/inline_local/please_inline.rs rename to tests/rustdoc-html/inline_local/please_inline.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-81141-2.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-81141-2.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-81141-2.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-81141-2.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-81141.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-81141.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-81141.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-81141.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-generics-81141.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-generics-81141.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-generics-81141.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-generics-81141.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-hidden-81141.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-hidden-81141.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-hidden-81141.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-hidden-81141.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-private-81141.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-private-81141.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-private-81141.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-private-81141.rs diff --git a/tests/rustdoc/inline_local/pub-re-export-28537.rs b/tests/rustdoc-html/inline_local/pub-re-export-28537.rs similarity index 100% rename from tests/rustdoc/inline_local/pub-re-export-28537.rs rename to tests/rustdoc-html/inline_local/pub-re-export-28537.rs diff --git a/tests/rustdoc/inline_local/reexported-macro-and-macro-export-sidebar-89852.rs b/tests/rustdoc-html/inline_local/reexported-macro-and-macro-export-sidebar-89852.rs similarity index 100% rename from tests/rustdoc/inline_local/reexported-macro-and-macro-export-sidebar-89852.rs rename to tests/rustdoc-html/inline_local/reexported-macro-and-macro-export-sidebar-89852.rs diff --git a/tests/rustdoc/inline_local/staged-inline.rs b/tests/rustdoc-html/inline_local/staged-inline.rs similarity index 100% rename from tests/rustdoc/inline_local/staged-inline.rs rename to tests/rustdoc-html/inline_local/staged-inline.rs diff --git a/tests/rustdoc/inline_local/trait-vis.rs b/tests/rustdoc-html/inline_local/trait-vis.rs similarity index 100% rename from tests/rustdoc/inline_local/trait-vis.rs rename to tests/rustdoc-html/inline_local/trait-vis.rs diff --git a/tests/rustdoc/internal.rs b/tests/rustdoc-html/internal.rs similarity index 100% rename from tests/rustdoc/internal.rs rename to tests/rustdoc-html/internal.rs diff --git a/tests/rustdoc/intra-doc-crate/auxiliary/self.rs b/tests/rustdoc-html/intra-doc-crate/auxiliary/self.rs similarity index 100% rename from tests/rustdoc/intra-doc-crate/auxiliary/self.rs rename to tests/rustdoc-html/intra-doc-crate/auxiliary/self.rs diff --git a/tests/rustdoc/intra-doc-crate/self.rs b/tests/rustdoc-html/intra-doc-crate/self.rs similarity index 100% rename from tests/rustdoc/intra-doc-crate/self.rs rename to tests/rustdoc-html/intra-doc-crate/self.rs diff --git a/tests/rustdoc/intra-doc/anchors.rs b/tests/rustdoc-html/intra-doc/anchors.rs similarity index 100% rename from tests/rustdoc/intra-doc/anchors.rs rename to tests/rustdoc-html/intra-doc/anchors.rs diff --git a/tests/rustdoc/intra-doc/assoc-reexport-super.rs b/tests/rustdoc-html/intra-doc/assoc-reexport-super.rs similarity index 100% rename from tests/rustdoc/intra-doc/assoc-reexport-super.rs rename to tests/rustdoc-html/intra-doc/assoc-reexport-super.rs diff --git a/tests/rustdoc/intra-doc/associated-defaults.rs b/tests/rustdoc-html/intra-doc/associated-defaults.rs similarity index 100% rename from tests/rustdoc/intra-doc/associated-defaults.rs rename to tests/rustdoc-html/intra-doc/associated-defaults.rs diff --git a/tests/rustdoc/intra-doc/associated-items.rs b/tests/rustdoc-html/intra-doc/associated-items.rs similarity index 100% rename from tests/rustdoc/intra-doc/associated-items.rs rename to tests/rustdoc-html/intra-doc/associated-items.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/empty.rs b/tests/rustdoc-html/intra-doc/auxiliary/empty.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/empty.rs rename to tests/rustdoc-html/intra-doc/auxiliary/empty.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/empty2.rs b/tests/rustdoc-html/intra-doc/auxiliary/empty2.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/empty2.rs rename to tests/rustdoc-html/intra-doc/auxiliary/empty2.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs b/tests/rustdoc-html/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs rename to tests/rustdoc-html/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs b/tests/rustdoc-html/intra-doc/auxiliary/extern-inherent-impl-dep.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs rename to tests/rustdoc-html/intra-doc/auxiliary/extern-inherent-impl-dep.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/intra-link-extern-crate.rs b/tests/rustdoc-html/intra-doc/auxiliary/intra-link-extern-crate.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/intra-link-extern-crate.rs rename to tests/rustdoc-html/intra-doc/auxiliary/intra-link-extern-crate.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/intra-link-pub-use.rs b/tests/rustdoc-html/intra-doc/auxiliary/intra-link-pub-use.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/intra-link-pub-use.rs rename to tests/rustdoc-html/intra-doc/auxiliary/intra-link-pub-use.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs b/tests/rustdoc-html/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs rename to tests/rustdoc-html/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/intra-links-external-traits.rs b/tests/rustdoc-html/intra-doc/auxiliary/intra-links-external-traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/intra-links-external-traits.rs rename to tests/rustdoc-html/intra-doc/auxiliary/intra-links-external-traits.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/issue-66159-1.rs b/tests/rustdoc-html/intra-doc/auxiliary/issue-66159-1.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/issue-66159-1.rs rename to tests/rustdoc-html/intra-doc/auxiliary/issue-66159-1.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/my-core.rs b/tests/rustdoc-html/intra-doc/auxiliary/my-core.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/my-core.rs rename to tests/rustdoc-html/intra-doc/auxiliary/my-core.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/proc-macro-macro.rs b/tests/rustdoc-html/intra-doc/auxiliary/proc-macro-macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/proc-macro-macro.rs rename to tests/rustdoc-html/intra-doc/auxiliary/proc-macro-macro.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/pub-struct.rs b/tests/rustdoc-html/intra-doc/auxiliary/pub-struct.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/pub-struct.rs rename to tests/rustdoc-html/intra-doc/auxiliary/pub-struct.rs diff --git a/tests/rustdoc/intra-doc/basic.rs b/tests/rustdoc-html/intra-doc/basic.rs similarity index 100% rename from tests/rustdoc/intra-doc/basic.rs rename to tests/rustdoc-html/intra-doc/basic.rs diff --git a/tests/rustdoc/intra-doc/builtin-macros.rs b/tests/rustdoc-html/intra-doc/builtin-macros.rs similarity index 100% rename from tests/rustdoc/intra-doc/builtin-macros.rs rename to tests/rustdoc-html/intra-doc/builtin-macros.rs diff --git a/tests/rustdoc/intra-doc/crate-relative-assoc.rs b/tests/rustdoc-html/intra-doc/crate-relative-assoc.rs similarity index 100% rename from tests/rustdoc/intra-doc/crate-relative-assoc.rs rename to tests/rustdoc-html/intra-doc/crate-relative-assoc.rs diff --git a/tests/rustdoc/intra-doc/crate-relative.rs b/tests/rustdoc-html/intra-doc/crate-relative.rs similarity index 100% rename from tests/rustdoc/intra-doc/crate-relative.rs rename to tests/rustdoc-html/intra-doc/crate-relative.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/additional_doc.rs b/tests/rustdoc-html/intra-doc/cross-crate/additional_doc.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/additional_doc.rs rename to tests/rustdoc-html/intra-doc/cross-crate/additional_doc.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/additional_doc.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/additional_doc.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/additional_doc.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/additional_doc.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/hidden.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/hidden.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/hidden.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/hidden.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/macro_inner.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/macro_inner.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/macro_inner.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/macro_inner.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/module.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/module.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/module.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/module.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/proc_macro.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/proc_macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/proc_macro.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/proc_macro.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/submodule-inner.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/submodule-inner.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/submodule-inner.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/submodule-inner.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/submodule-outer.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/submodule-outer.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/submodule-outer.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/submodule-outer.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/traits.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/traits.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/traits.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/basic.rs b/tests/rustdoc-html/intra-doc/cross-crate/basic.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/basic.rs rename to tests/rustdoc-html/intra-doc/cross-crate/basic.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/crate.rs b/tests/rustdoc-html/intra-doc/cross-crate/crate.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/crate.rs rename to tests/rustdoc-html/intra-doc/cross-crate/crate.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/hidden.rs b/tests/rustdoc-html/intra-doc/cross-crate/hidden.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/hidden.rs rename to tests/rustdoc-html/intra-doc/cross-crate/hidden.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/macro.rs b/tests/rustdoc-html/intra-doc/cross-crate/macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/macro.rs rename to tests/rustdoc-html/intra-doc/cross-crate/macro.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/module.rs b/tests/rustdoc-html/intra-doc/cross-crate/module.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/module.rs rename to tests/rustdoc-html/intra-doc/cross-crate/module.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/submodule-inner.rs b/tests/rustdoc-html/intra-doc/cross-crate/submodule-inner.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/submodule-inner.rs rename to tests/rustdoc-html/intra-doc/cross-crate/submodule-inner.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/submodule-outer.rs b/tests/rustdoc-html/intra-doc/cross-crate/submodule-outer.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/submodule-outer.rs rename to tests/rustdoc-html/intra-doc/cross-crate/submodule-outer.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/traits.rs b/tests/rustdoc-html/intra-doc/cross-crate/traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/traits.rs rename to tests/rustdoc-html/intra-doc/cross-crate/traits.rs diff --git a/tests/rustdoc/intra-doc/deps.rs b/tests/rustdoc-html/intra-doc/deps.rs similarity index 100% rename from tests/rustdoc/intra-doc/deps.rs rename to tests/rustdoc-html/intra-doc/deps.rs diff --git a/tests/rustdoc/intra-doc/disambiguators-removed.rs b/tests/rustdoc-html/intra-doc/disambiguators-removed.rs similarity index 100% rename from tests/rustdoc/intra-doc/disambiguators-removed.rs rename to tests/rustdoc-html/intra-doc/disambiguators-removed.rs diff --git a/tests/rustdoc/intra-doc/email-address.rs b/tests/rustdoc-html/intra-doc/email-address.rs similarity index 100% rename from tests/rustdoc/intra-doc/email-address.rs rename to tests/rustdoc-html/intra-doc/email-address.rs diff --git a/tests/rustdoc/intra-doc/enum-self-82209.rs b/tests/rustdoc-html/intra-doc/enum-self-82209.rs similarity index 100% rename from tests/rustdoc/intra-doc/enum-self-82209.rs rename to tests/rustdoc-html/intra-doc/enum-self-82209.rs diff --git a/tests/rustdoc/intra-doc/enum-struct-field.rs b/tests/rustdoc-html/intra-doc/enum-struct-field.rs similarity index 100% rename from tests/rustdoc/intra-doc/enum-struct-field.rs rename to tests/rustdoc-html/intra-doc/enum-struct-field.rs diff --git a/tests/rustdoc/intra-doc/extern-builtin-type-impl.rs b/tests/rustdoc-html/intra-doc/extern-builtin-type-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-builtin-type-impl.rs rename to tests/rustdoc-html/intra-doc/extern-builtin-type-impl.rs diff --git a/tests/rustdoc/intra-doc/extern-crate-only-used-in-link.rs b/tests/rustdoc-html/intra-doc/extern-crate-only-used-in-link.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-crate-only-used-in-link.rs rename to tests/rustdoc-html/intra-doc/extern-crate-only-used-in-link.rs diff --git a/tests/rustdoc/intra-doc/extern-crate.rs b/tests/rustdoc-html/intra-doc/extern-crate.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-crate.rs rename to tests/rustdoc-html/intra-doc/extern-crate.rs diff --git a/tests/rustdoc/intra-doc/extern-inherent-impl.rs b/tests/rustdoc-html/intra-doc/extern-inherent-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-inherent-impl.rs rename to tests/rustdoc-html/intra-doc/extern-inherent-impl.rs diff --git a/tests/rustdoc/intra-doc/extern-reference-link.rs b/tests/rustdoc-html/intra-doc/extern-reference-link.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-reference-link.rs rename to tests/rustdoc-html/intra-doc/extern-reference-link.rs diff --git a/tests/rustdoc/intra-doc/extern-type.rs b/tests/rustdoc-html/intra-doc/extern-type.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-type.rs rename to tests/rustdoc-html/intra-doc/extern-type.rs diff --git a/tests/rustdoc/intra-doc/external-traits.rs b/tests/rustdoc-html/intra-doc/external-traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/external-traits.rs rename to tests/rustdoc-html/intra-doc/external-traits.rs diff --git a/tests/rustdoc/intra-doc/field.rs b/tests/rustdoc-html/intra-doc/field.rs similarity index 100% rename from tests/rustdoc/intra-doc/field.rs rename to tests/rustdoc-html/intra-doc/field.rs diff --git a/tests/rustdoc/intra-doc/filter-out-private.rs b/tests/rustdoc-html/intra-doc/filter-out-private.rs similarity index 100% rename from tests/rustdoc/intra-doc/filter-out-private.rs rename to tests/rustdoc-html/intra-doc/filter-out-private.rs diff --git a/tests/rustdoc/intra-doc/generic-params.rs b/tests/rustdoc-html/intra-doc/generic-params.rs similarity index 100% rename from tests/rustdoc/intra-doc/generic-params.rs rename to tests/rustdoc-html/intra-doc/generic-params.rs diff --git a/tests/rustdoc/intra-doc/generic-trait-impl.rs b/tests/rustdoc-html/intra-doc/generic-trait-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/generic-trait-impl.rs rename to tests/rustdoc-html/intra-doc/generic-trait-impl.rs diff --git a/tests/rustdoc/intra-doc/ice-intra-doc-links-107995.rs b/tests/rustdoc-html/intra-doc/ice-intra-doc-links-107995.rs similarity index 100% rename from tests/rustdoc/intra-doc/ice-intra-doc-links-107995.rs rename to tests/rustdoc-html/intra-doc/ice-intra-doc-links-107995.rs diff --git a/tests/rustdoc/intra-doc/in-bodies.rs b/tests/rustdoc-html/intra-doc/in-bodies.rs similarity index 100% rename from tests/rustdoc/intra-doc/in-bodies.rs rename to tests/rustdoc-html/intra-doc/in-bodies.rs diff --git a/tests/rustdoc/intra-doc/inherent-associated-types.rs b/tests/rustdoc-html/intra-doc/inherent-associated-types.rs similarity index 100% rename from tests/rustdoc/intra-doc/inherent-associated-types.rs rename to tests/rustdoc-html/intra-doc/inherent-associated-types.rs diff --git a/tests/rustdoc/intra-doc/intra-doc-link-method-trait-impl-72340.rs b/tests/rustdoc-html/intra-doc/intra-doc-link-method-trait-impl-72340.rs similarity index 100% rename from tests/rustdoc/intra-doc/intra-doc-link-method-trait-impl-72340.rs rename to tests/rustdoc-html/intra-doc/intra-doc-link-method-trait-impl-72340.rs diff --git a/tests/rustdoc/intra-doc/libstd-re-export.rs b/tests/rustdoc-html/intra-doc/libstd-re-export.rs similarity index 100% rename from tests/rustdoc/intra-doc/libstd-re-export.rs rename to tests/rustdoc-html/intra-doc/libstd-re-export.rs diff --git a/tests/rustdoc/intra-doc/link-in-footnotes-132208.rs b/tests/rustdoc-html/intra-doc/link-in-footnotes-132208.rs similarity index 100% rename from tests/rustdoc/intra-doc/link-in-footnotes-132208.rs rename to tests/rustdoc-html/intra-doc/link-in-footnotes-132208.rs diff --git a/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs b/tests/rustdoc-html/intra-doc/link-same-name-different-disambiguator-108459.rs similarity index 100% rename from tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs rename to tests/rustdoc-html/intra-doc/link-same-name-different-disambiguator-108459.rs diff --git a/tests/rustdoc/intra-doc/link-to-proc-macro.rs b/tests/rustdoc-html/intra-doc/link-to-proc-macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/link-to-proc-macro.rs rename to tests/rustdoc-html/intra-doc/link-to-proc-macro.rs diff --git a/tests/rustdoc/intra-doc/macro-caching-144965.rs b/tests/rustdoc-html/intra-doc/macro-caching-144965.rs similarity index 100% rename from tests/rustdoc/intra-doc/macro-caching-144965.rs rename to tests/rustdoc-html/intra-doc/macro-caching-144965.rs diff --git a/tests/rustdoc/intra-doc/macros-disambiguators.rs b/tests/rustdoc-html/intra-doc/macros-disambiguators.rs similarity index 100% rename from tests/rustdoc/intra-doc/macros-disambiguators.rs rename to tests/rustdoc-html/intra-doc/macros-disambiguators.rs diff --git a/tests/rustdoc/intra-doc/mod-ambiguity.rs b/tests/rustdoc-html/intra-doc/mod-ambiguity.rs similarity index 100% rename from tests/rustdoc/intra-doc/mod-ambiguity.rs rename to tests/rustdoc-html/intra-doc/mod-ambiguity.rs diff --git a/tests/rustdoc/intra-doc/mod-relative.rs b/tests/rustdoc-html/intra-doc/mod-relative.rs similarity index 100% rename from tests/rustdoc/intra-doc/mod-relative.rs rename to tests/rustdoc-html/intra-doc/mod-relative.rs diff --git a/tests/rustdoc/intra-doc/module-scope-name-resolution-55364.rs b/tests/rustdoc-html/intra-doc/module-scope-name-resolution-55364.rs similarity index 100% rename from tests/rustdoc/intra-doc/module-scope-name-resolution-55364.rs rename to tests/rustdoc-html/intra-doc/module-scope-name-resolution-55364.rs diff --git a/tests/rustdoc/intra-doc/nested-use.rs b/tests/rustdoc-html/intra-doc/nested-use.rs similarity index 100% rename from tests/rustdoc/intra-doc/nested-use.rs rename to tests/rustdoc-html/intra-doc/nested-use.rs diff --git a/tests/rustdoc/intra-doc/no-doc-primitive.rs b/tests/rustdoc-html/intra-doc/no-doc-primitive.rs similarity index 100% rename from tests/rustdoc/intra-doc/no-doc-primitive.rs rename to tests/rustdoc-html/intra-doc/no-doc-primitive.rs diff --git a/tests/rustdoc/intra-doc/non-path-primitives.rs b/tests/rustdoc-html/intra-doc/non-path-primitives.rs similarity index 100% rename from tests/rustdoc/intra-doc/non-path-primitives.rs rename to tests/rustdoc-html/intra-doc/non-path-primitives.rs diff --git a/tests/rustdoc/intra-doc/prim-assoc.rs b/tests/rustdoc-html/intra-doc/prim-assoc.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-assoc.rs rename to tests/rustdoc-html/intra-doc/prim-assoc.rs diff --git a/tests/rustdoc/intra-doc/prim-associated-traits.rs b/tests/rustdoc-html/intra-doc/prim-associated-traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-associated-traits.rs rename to tests/rustdoc-html/intra-doc/prim-associated-traits.rs diff --git a/tests/rustdoc/intra-doc/prim-methods-external-core.rs b/tests/rustdoc-html/intra-doc/prim-methods-external-core.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-methods-external-core.rs rename to tests/rustdoc-html/intra-doc/prim-methods-external-core.rs diff --git a/tests/rustdoc/intra-doc/prim-methods-local.rs b/tests/rustdoc-html/intra-doc/prim-methods-local.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-methods-local.rs rename to tests/rustdoc-html/intra-doc/prim-methods-local.rs diff --git a/tests/rustdoc/intra-doc/prim-methods.rs b/tests/rustdoc-html/intra-doc/prim-methods.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-methods.rs rename to tests/rustdoc-html/intra-doc/prim-methods.rs diff --git a/tests/rustdoc/intra-doc/prim-precedence.rs b/tests/rustdoc-html/intra-doc/prim-precedence.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-precedence.rs rename to tests/rustdoc-html/intra-doc/prim-precedence.rs diff --git a/tests/rustdoc/intra-doc/prim-self.rs b/tests/rustdoc-html/intra-doc/prim-self.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-self.rs rename to tests/rustdoc-html/intra-doc/prim-self.rs diff --git a/tests/rustdoc/intra-doc/primitive-disambiguators.rs b/tests/rustdoc-html/intra-doc/primitive-disambiguators.rs similarity index 100% rename from tests/rustdoc/intra-doc/primitive-disambiguators.rs rename to tests/rustdoc-html/intra-doc/primitive-disambiguators.rs diff --git a/tests/rustdoc/intra-doc/primitive-non-default-impl.rs b/tests/rustdoc-html/intra-doc/primitive-non-default-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/primitive-non-default-impl.rs rename to tests/rustdoc-html/intra-doc/primitive-non-default-impl.rs diff --git a/tests/rustdoc/intra-doc/private-failures-ignored.rs b/tests/rustdoc-html/intra-doc/private-failures-ignored.rs similarity index 100% rename from tests/rustdoc/intra-doc/private-failures-ignored.rs rename to tests/rustdoc-html/intra-doc/private-failures-ignored.rs diff --git a/tests/rustdoc/intra-doc/private.rs b/tests/rustdoc-html/intra-doc/private.rs similarity index 100% rename from tests/rustdoc/intra-doc/private.rs rename to tests/rustdoc-html/intra-doc/private.rs diff --git a/tests/rustdoc/intra-doc/proc-macro.rs b/tests/rustdoc-html/intra-doc/proc-macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/proc-macro.rs rename to tests/rustdoc-html/intra-doc/proc-macro.rs diff --git a/tests/rustdoc/intra-doc/pub-use.rs b/tests/rustdoc-html/intra-doc/pub-use.rs similarity index 100% rename from tests/rustdoc/intra-doc/pub-use.rs rename to tests/rustdoc-html/intra-doc/pub-use.rs diff --git a/tests/rustdoc/intra-doc/raw-ident-self.rs b/tests/rustdoc-html/intra-doc/raw-ident-self.rs similarity index 100% rename from tests/rustdoc/intra-doc/raw-ident-self.rs rename to tests/rustdoc-html/intra-doc/raw-ident-self.rs diff --git a/tests/rustdoc/intra-doc/reexport-additional-docs.rs b/tests/rustdoc-html/intra-doc/reexport-additional-docs.rs similarity index 100% rename from tests/rustdoc/intra-doc/reexport-additional-docs.rs rename to tests/rustdoc-html/intra-doc/reexport-additional-docs.rs diff --git a/tests/rustdoc/intra-doc/same-name-different-crates-66159.rs b/tests/rustdoc-html/intra-doc/same-name-different-crates-66159.rs similarity index 100% rename from tests/rustdoc/intra-doc/same-name-different-crates-66159.rs rename to tests/rustdoc-html/intra-doc/same-name-different-crates-66159.rs diff --git a/tests/rustdoc/intra-doc/self-cache.rs b/tests/rustdoc-html/intra-doc/self-cache.rs similarity index 100% rename from tests/rustdoc/intra-doc/self-cache.rs rename to tests/rustdoc-html/intra-doc/self-cache.rs diff --git a/tests/rustdoc/intra-doc/self.rs b/tests/rustdoc-html/intra-doc/self.rs similarity index 100% rename from tests/rustdoc/intra-doc/self.rs rename to tests/rustdoc-html/intra-doc/self.rs diff --git a/tests/rustdoc/intra-doc/trait-impl.rs b/tests/rustdoc-html/intra-doc/trait-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/trait-impl.rs rename to tests/rustdoc-html/intra-doc/trait-impl.rs diff --git a/tests/rustdoc/intra-doc/trait-item.rs b/tests/rustdoc-html/intra-doc/trait-item.rs similarity index 100% rename from tests/rustdoc/intra-doc/trait-item.rs rename to tests/rustdoc-html/intra-doc/trait-item.rs diff --git a/tests/rustdoc/intra-doc/true-false.rs b/tests/rustdoc-html/intra-doc/true-false.rs similarity index 100% rename from tests/rustdoc/intra-doc/true-false.rs rename to tests/rustdoc-html/intra-doc/true-false.rs diff --git a/tests/rustdoc/intra-doc/type-alias-primitive.rs b/tests/rustdoc-html/intra-doc/type-alias-primitive.rs similarity index 100% rename from tests/rustdoc/intra-doc/type-alias-primitive.rs rename to tests/rustdoc-html/intra-doc/type-alias-primitive.rs diff --git a/tests/rustdoc/intra-doc/type-alias.rs b/tests/rustdoc-html/intra-doc/type-alias.rs similarity index 100% rename from tests/rustdoc/intra-doc/type-alias.rs rename to tests/rustdoc-html/intra-doc/type-alias.rs diff --git a/tests/rustdoc/invalid$crate$name.rs b/tests/rustdoc-html/invalid$crate$name.rs similarity index 100% rename from tests/rustdoc/invalid$crate$name.rs rename to tests/rustdoc-html/invalid$crate$name.rs diff --git a/tests/rustdoc/item-desc-list-at-start.item-table.html b/tests/rustdoc-html/item-desc-list-at-start.item-table.html similarity index 100% rename from tests/rustdoc/item-desc-list-at-start.item-table.html rename to tests/rustdoc-html/item-desc-list-at-start.item-table.html diff --git a/tests/rustdoc/item-desc-list-at-start.rs b/tests/rustdoc-html/item-desc-list-at-start.rs similarity index 100% rename from tests/rustdoc/item-desc-list-at-start.rs rename to tests/rustdoc-html/item-desc-list-at-start.rs diff --git a/tests/rustdoc/jump-to-def/assoc-items.rs b/tests/rustdoc-html/jump-to-def/assoc-items.rs similarity index 100% rename from tests/rustdoc/jump-to-def/assoc-items.rs rename to tests/rustdoc-html/jump-to-def/assoc-items.rs diff --git a/tests/rustdoc/jump-to-def/assoc-types.rs b/tests/rustdoc-html/jump-to-def/assoc-types.rs similarity index 100% rename from tests/rustdoc/jump-to-def/assoc-types.rs rename to tests/rustdoc-html/jump-to-def/assoc-types.rs diff --git a/tests/rustdoc/jump-to-def/auxiliary/symbols.rs b/tests/rustdoc-html/jump-to-def/auxiliary/symbols.rs similarity index 100% rename from tests/rustdoc/jump-to-def/auxiliary/symbols.rs rename to tests/rustdoc-html/jump-to-def/auxiliary/symbols.rs diff --git a/tests/rustdoc/jump-to-def/derive-macro.rs b/tests/rustdoc-html/jump-to-def/derive-macro.rs similarity index 100% rename from tests/rustdoc/jump-to-def/derive-macro.rs rename to tests/rustdoc-html/jump-to-def/derive-macro.rs diff --git a/tests/rustdoc/jump-to-def/doc-links-calls.rs b/tests/rustdoc-html/jump-to-def/doc-links-calls.rs similarity index 100% rename from tests/rustdoc/jump-to-def/doc-links-calls.rs rename to tests/rustdoc-html/jump-to-def/doc-links-calls.rs diff --git a/tests/rustdoc/jump-to-def/doc-links.rs b/tests/rustdoc-html/jump-to-def/doc-links.rs similarity index 100% rename from tests/rustdoc/jump-to-def/doc-links.rs rename to tests/rustdoc-html/jump-to-def/doc-links.rs diff --git a/tests/rustdoc/jump-to-def/macro.rs b/tests/rustdoc-html/jump-to-def/macro.rs similarity index 100% rename from tests/rustdoc/jump-to-def/macro.rs rename to tests/rustdoc-html/jump-to-def/macro.rs diff --git a/tests/rustdoc/jump-to-def/no-body-items.rs b/tests/rustdoc-html/jump-to-def/no-body-items.rs similarity index 100% rename from tests/rustdoc/jump-to-def/no-body-items.rs rename to tests/rustdoc-html/jump-to-def/no-body-items.rs diff --git a/tests/rustdoc/jump-to-def/non-local-method.rs b/tests/rustdoc-html/jump-to-def/non-local-method.rs similarity index 100% rename from tests/rustdoc/jump-to-def/non-local-method.rs rename to tests/rustdoc-html/jump-to-def/non-local-method.rs diff --git a/tests/rustdoc/jump-to-def/patterns.rs b/tests/rustdoc-html/jump-to-def/patterns.rs similarity index 100% rename from tests/rustdoc/jump-to-def/patterns.rs rename to tests/rustdoc-html/jump-to-def/patterns.rs diff --git a/tests/rustdoc/jump-to-def/prelude-types.rs b/tests/rustdoc-html/jump-to-def/prelude-types.rs similarity index 100% rename from tests/rustdoc/jump-to-def/prelude-types.rs rename to tests/rustdoc-html/jump-to-def/prelude-types.rs diff --git a/tests/rustdoc/jump-to-def/shebang.rs b/tests/rustdoc-html/jump-to-def/shebang.rs similarity index 100% rename from tests/rustdoc/jump-to-def/shebang.rs rename to tests/rustdoc-html/jump-to-def/shebang.rs diff --git a/tests/rustdoc/keyword.rs b/tests/rustdoc-html/keyword.rs similarity index 100% rename from tests/rustdoc/keyword.rs rename to tests/rustdoc-html/keyword.rs diff --git a/tests/rustdoc/lifetime-name.rs b/tests/rustdoc-html/lifetime-name.rs similarity index 100% rename from tests/rustdoc/lifetime-name.rs rename to tests/rustdoc-html/lifetime-name.rs diff --git a/tests/rustdoc/line-breaks.rs b/tests/rustdoc-html/line-breaks.rs similarity index 100% rename from tests/rustdoc/line-breaks.rs rename to tests/rustdoc-html/line-breaks.rs diff --git a/tests/rustdoc/link-on-path-with-generics.rs b/tests/rustdoc-html/link-on-path-with-generics.rs similarity index 100% rename from tests/rustdoc/link-on-path-with-generics.rs rename to tests/rustdoc-html/link-on-path-with-generics.rs diff --git a/tests/rustdoc/link-title-escape.rs b/tests/rustdoc-html/link-title-escape.rs similarity index 100% rename from tests/rustdoc/link-title-escape.rs rename to tests/rustdoc-html/link-title-escape.rs diff --git a/tests/rustdoc/links-in-headings.rs b/tests/rustdoc-html/links-in-headings.rs similarity index 100% rename from tests/rustdoc/links-in-headings.rs rename to tests/rustdoc-html/links-in-headings.rs diff --git a/tests/rustdoc/logo-class-default.rs b/tests/rustdoc-html/logo-class-default.rs similarity index 100% rename from tests/rustdoc/logo-class-default.rs rename to tests/rustdoc-html/logo-class-default.rs diff --git a/tests/rustdoc/logo-class-rust.rs b/tests/rustdoc-html/logo-class-rust.rs similarity index 100% rename from tests/rustdoc/logo-class-rust.rs rename to tests/rustdoc-html/logo-class-rust.rs diff --git a/tests/rustdoc/logo-class.rs b/tests/rustdoc-html/logo-class.rs similarity index 100% rename from tests/rustdoc/logo-class.rs rename to tests/rustdoc-html/logo-class.rs diff --git a/tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs b/tests/rustdoc-html/macro-expansion/field-followed-by-exclamation.rs similarity index 100% rename from tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs rename to tests/rustdoc-html/macro-expansion/field-followed-by-exclamation.rs diff --git a/tests/rustdoc/macro-expansion/type-macro-expansion.rs b/tests/rustdoc-html/macro-expansion/type-macro-expansion.rs similarity index 100% rename from tests/rustdoc/macro-expansion/type-macro-expansion.rs rename to tests/rustdoc-html/macro-expansion/type-macro-expansion.rs diff --git a/tests/rustdoc/macro/auxiliary/external-macro-src.rs b/tests/rustdoc-html/macro/auxiliary/external-macro-src.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/external-macro-src.rs rename to tests/rustdoc-html/macro/auxiliary/external-macro-src.rs diff --git a/tests/rustdoc/macro/auxiliary/issue-99221-aux.rs b/tests/rustdoc-html/macro/auxiliary/issue-99221-aux.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/issue-99221-aux.rs rename to tests/rustdoc-html/macro/auxiliary/issue-99221-aux.rs diff --git a/tests/rustdoc/macro/auxiliary/macro_pub_in_module.rs b/tests/rustdoc-html/macro/auxiliary/macro_pub_in_module.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/macro_pub_in_module.rs rename to tests/rustdoc-html/macro/auxiliary/macro_pub_in_module.rs diff --git a/tests/rustdoc/macro/auxiliary/one-line-expand.rs b/tests/rustdoc-html/macro/auxiliary/one-line-expand.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/one-line-expand.rs rename to tests/rustdoc-html/macro/auxiliary/one-line-expand.rs diff --git a/tests/rustdoc/macro/auxiliary/pub-use-extern-macros.rs b/tests/rustdoc-html/macro/auxiliary/pub-use-extern-macros.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/pub-use-extern-macros.rs rename to tests/rustdoc-html/macro/auxiliary/pub-use-extern-macros.rs diff --git a/tests/rustdoc/macro/compiler-derive-proc-macro.rs b/tests/rustdoc-html/macro/compiler-derive-proc-macro.rs similarity index 100% rename from tests/rustdoc/macro/compiler-derive-proc-macro.rs rename to tests/rustdoc-html/macro/compiler-derive-proc-macro.rs diff --git a/tests/rustdoc/macro/const-rendering-macros-33302.rs b/tests/rustdoc-html/macro/const-rendering-macros-33302.rs similarity index 100% rename from tests/rustdoc/macro/const-rendering-macros-33302.rs rename to tests/rustdoc-html/macro/const-rendering-macros-33302.rs diff --git a/tests/rustdoc/macro/decl_macro.rs b/tests/rustdoc-html/macro/decl_macro.rs similarity index 100% rename from tests/rustdoc/macro/decl_macro.rs rename to tests/rustdoc-html/macro/decl_macro.rs diff --git a/tests/rustdoc/macro/decl_macro_priv.rs b/tests/rustdoc-html/macro/decl_macro_priv.rs similarity index 100% rename from tests/rustdoc/macro/decl_macro_priv.rs rename to tests/rustdoc-html/macro/decl_macro_priv.rs diff --git a/tests/rustdoc/macro/doc-proc-macro.rs b/tests/rustdoc-html/macro/doc-proc-macro.rs similarity index 100% rename from tests/rustdoc/macro/doc-proc-macro.rs rename to tests/rustdoc-html/macro/doc-proc-macro.rs diff --git a/tests/rustdoc/macro/external-macro-src.rs b/tests/rustdoc-html/macro/external-macro-src.rs similarity index 100% rename from tests/rustdoc/macro/external-macro-src.rs rename to tests/rustdoc-html/macro/external-macro-src.rs diff --git a/tests/rustdoc/macro/macro-const-display-115295.rs b/tests/rustdoc-html/macro/macro-const-display-115295.rs similarity index 100% rename from tests/rustdoc/macro/macro-const-display-115295.rs rename to tests/rustdoc-html/macro/macro-const-display-115295.rs diff --git a/tests/rustdoc/macro/macro-doc-comment-23812.rs b/tests/rustdoc-html/macro/macro-doc-comment-23812.rs similarity index 100% rename from tests/rustdoc/macro/macro-doc-comment-23812.rs rename to tests/rustdoc-html/macro/macro-doc-comment-23812.rs diff --git a/tests/rustdoc/macro/macro-export-crate-root-108231.rs b/tests/rustdoc-html/macro/macro-export-crate-root-108231.rs similarity index 100% rename from tests/rustdoc/macro/macro-export-crate-root-108231.rs rename to tests/rustdoc-html/macro/macro-export-crate-root-108231.rs diff --git a/tests/rustdoc/macro/macro-generated-macro.macro_linebreak_pre.html b/tests/rustdoc-html/macro/macro-generated-macro.macro_linebreak_pre.html similarity index 100% rename from tests/rustdoc/macro/macro-generated-macro.macro_linebreak_pre.html rename to tests/rustdoc-html/macro/macro-generated-macro.macro_linebreak_pre.html diff --git a/tests/rustdoc/macro/macro-generated-macro.macro_morestuff_pre.html b/tests/rustdoc-html/macro/macro-generated-macro.macro_morestuff_pre.html similarity index 100% rename from tests/rustdoc/macro/macro-generated-macro.macro_morestuff_pre.html rename to tests/rustdoc-html/macro/macro-generated-macro.macro_morestuff_pre.html diff --git a/tests/rustdoc/macro/macro-generated-macro.rs b/tests/rustdoc-html/macro/macro-generated-macro.rs similarity index 100% rename from tests/rustdoc/macro/macro-generated-macro.rs rename to tests/rustdoc-html/macro/macro-generated-macro.rs diff --git a/tests/rustdoc/macro/macro-higher-kinded-function.rs b/tests/rustdoc-html/macro/macro-higher-kinded-function.rs similarity index 100% rename from tests/rustdoc/macro/macro-higher-kinded-function.rs rename to tests/rustdoc-html/macro/macro-higher-kinded-function.rs diff --git a/tests/rustdoc/macro/macro-ice-16019.rs b/tests/rustdoc-html/macro/macro-ice-16019.rs similarity index 100% rename from tests/rustdoc/macro/macro-ice-16019.rs rename to tests/rustdoc-html/macro/macro-ice-16019.rs diff --git a/tests/rustdoc/macro/macro-in-async-block.rs b/tests/rustdoc-html/macro/macro-in-async-block.rs similarity index 100% rename from tests/rustdoc/macro/macro-in-async-block.rs rename to tests/rustdoc-html/macro/macro-in-async-block.rs diff --git a/tests/rustdoc/macro/macro-in-closure.rs b/tests/rustdoc-html/macro/macro-in-closure.rs similarity index 100% rename from tests/rustdoc/macro/macro-in-closure.rs rename to tests/rustdoc-html/macro/macro-in-closure.rs diff --git a/tests/rustdoc/macro/macro-indirect-use.rs b/tests/rustdoc-html/macro/macro-indirect-use.rs similarity index 100% rename from tests/rustdoc/macro/macro-indirect-use.rs rename to tests/rustdoc-html/macro/macro-indirect-use.rs diff --git a/tests/rustdoc/macro/macro_expansion.rs b/tests/rustdoc-html/macro/macro_expansion.rs similarity index 100% rename from tests/rustdoc/macro/macro_expansion.rs rename to tests/rustdoc-html/macro/macro_expansion.rs diff --git a/tests/rustdoc/macro/macro_pub_in_module.rs b/tests/rustdoc-html/macro/macro_pub_in_module.rs similarity index 100% rename from tests/rustdoc/macro/macro_pub_in_module.rs rename to tests/rustdoc-html/macro/macro_pub_in_module.rs diff --git a/tests/rustdoc/macro/macro_rules-matchers.rs b/tests/rustdoc-html/macro/macro_rules-matchers.rs similarity index 100% rename from tests/rustdoc/macro/macro_rules-matchers.rs rename to tests/rustdoc-html/macro/macro_rules-matchers.rs diff --git a/tests/rustdoc/macro/macros.rs b/tests/rustdoc-html/macro/macros.rs similarity index 100% rename from tests/rustdoc/macro/macros.rs rename to tests/rustdoc-html/macro/macros.rs diff --git a/tests/rustdoc/macro/multiple-macro-rules-w-same-name-99221.rs b/tests/rustdoc-html/macro/multiple-macro-rules-w-same-name-99221.rs similarity index 100% rename from tests/rustdoc/macro/multiple-macro-rules-w-same-name-99221.rs rename to tests/rustdoc-html/macro/multiple-macro-rules-w-same-name-99221.rs diff --git a/tests/rustdoc/macro/multiple-macro-rules-w-same-name-submodule-99221.rs b/tests/rustdoc-html/macro/multiple-macro-rules-w-same-name-submodule-99221.rs similarity index 100% rename from tests/rustdoc/macro/multiple-macro-rules-w-same-name-submodule-99221.rs rename to tests/rustdoc-html/macro/multiple-macro-rules-w-same-name-submodule-99221.rs diff --git a/tests/rustdoc/macro/one-line-expand.rs b/tests/rustdoc-html/macro/one-line-expand.rs similarity index 100% rename from tests/rustdoc/macro/one-line-expand.rs rename to tests/rustdoc-html/macro/one-line-expand.rs diff --git a/tests/rustdoc/macro/proc-macro.rs b/tests/rustdoc-html/macro/proc-macro.rs similarity index 100% rename from tests/rustdoc/macro/proc-macro.rs rename to tests/rustdoc-html/macro/proc-macro.rs diff --git a/tests/rustdoc/macro/pub-use-extern-macros.rs b/tests/rustdoc-html/macro/pub-use-extern-macros.rs similarity index 100% rename from tests/rustdoc/macro/pub-use-extern-macros.rs rename to tests/rustdoc-html/macro/pub-use-extern-macros.rs diff --git a/tests/rustdoc/macro/rustc-macro-crate.rs b/tests/rustdoc-html/macro/rustc-macro-crate.rs similarity index 100% rename from tests/rustdoc/macro/rustc-macro-crate.rs rename to tests/rustdoc-html/macro/rustc-macro-crate.rs diff --git a/tests/rustdoc/markdown-60482.rs b/tests/rustdoc-html/markdown-60482.rs similarity index 100% rename from tests/rustdoc/markdown-60482.rs rename to tests/rustdoc-html/markdown-60482.rs diff --git a/tests/rustdoc/markdown-table-escape-pipe-27862.rs b/tests/rustdoc-html/markdown-table-escape-pipe-27862.rs similarity index 100% rename from tests/rustdoc/markdown-table-escape-pipe-27862.rs rename to tests/rustdoc-html/markdown-table-escape-pipe-27862.rs diff --git a/tests/rustdoc/masked.rs b/tests/rustdoc-html/masked.rs similarity index 100% rename from tests/rustdoc/masked.rs rename to tests/rustdoc-html/masked.rs diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/single-crate-finalize/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/single-crate-finalize/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/single-crate-read-write/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/single-crate-read-write/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/single-crate-write-anyway/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/single-crate-write-anyway/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs b/tests/rustdoc-html/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs rename to tests/rustdoc-html/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs diff --git a/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs b/tests/rustdoc-html/merge-cross-crate-info/two-separate-out-dir/echo.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs rename to tests/rustdoc-html/merge-cross-crate-info/two-separate-out-dir/echo.rs diff --git a/tests/rustdoc/method-list.rs b/tests/rustdoc-html/method-list.rs similarity index 100% rename from tests/rustdoc/method-list.rs rename to tests/rustdoc-html/method-list.rs diff --git a/tests/rustdoc/mixing-doc-comments-and-attrs.S1_top-doc.html b/tests/rustdoc-html/mixing-doc-comments-and-attrs.S1_top-doc.html similarity index 100% rename from tests/rustdoc/mixing-doc-comments-and-attrs.S1_top-doc.html rename to tests/rustdoc-html/mixing-doc-comments-and-attrs.S1_top-doc.html diff --git a/tests/rustdoc/mixing-doc-comments-and-attrs.S2_top-doc.html b/tests/rustdoc-html/mixing-doc-comments-and-attrs.S2_top-doc.html similarity index 100% rename from tests/rustdoc/mixing-doc-comments-and-attrs.S2_top-doc.html rename to tests/rustdoc-html/mixing-doc-comments-and-attrs.S2_top-doc.html diff --git a/tests/rustdoc/mixing-doc-comments-and-attrs.S3_top-doc.html b/tests/rustdoc-html/mixing-doc-comments-and-attrs.S3_top-doc.html similarity index 100% rename from tests/rustdoc/mixing-doc-comments-and-attrs.S3_top-doc.html rename to tests/rustdoc-html/mixing-doc-comments-and-attrs.S3_top-doc.html diff --git a/tests/rustdoc/mixing-doc-comments-and-attrs.rs b/tests/rustdoc-html/mixing-doc-comments-and-attrs.rs similarity index 100% rename from tests/rustdoc/mixing-doc-comments-and-attrs.rs rename to tests/rustdoc-html/mixing-doc-comments-and-attrs.rs diff --git a/tests/rustdoc/mod-stackoverflow.rs b/tests/rustdoc-html/mod-stackoverflow.rs similarity index 100% rename from tests/rustdoc/mod-stackoverflow.rs rename to tests/rustdoc-html/mod-stackoverflow.rs diff --git a/tests/rustdoc/multiple-foreigns-w-same-name-99734.rs b/tests/rustdoc-html/multiple-foreigns-w-same-name-99734.rs similarity index 100% rename from tests/rustdoc/multiple-foreigns-w-same-name-99734.rs rename to tests/rustdoc-html/multiple-foreigns-w-same-name-99734.rs diff --git a/tests/rustdoc/multiple-import-levels.rs b/tests/rustdoc-html/multiple-import-levels.rs similarity index 100% rename from tests/rustdoc/multiple-import-levels.rs rename to tests/rustdoc-html/multiple-import-levels.rs diff --git a/tests/rustdoc/multiple-mods-w-same-name-99734.rs b/tests/rustdoc-html/multiple-mods-w-same-name-99734.rs similarity index 100% rename from tests/rustdoc/multiple-mods-w-same-name-99734.rs rename to tests/rustdoc-html/multiple-mods-w-same-name-99734.rs diff --git a/tests/rustdoc/multiple-mods-w-same-name-doc-inline-83375.rs b/tests/rustdoc-html/multiple-mods-w-same-name-doc-inline-83375.rs similarity index 100% rename from tests/rustdoc/multiple-mods-w-same-name-doc-inline-83375.rs rename to tests/rustdoc-html/multiple-mods-w-same-name-doc-inline-83375.rs diff --git a/tests/rustdoc/multiple-mods-w-same-name-doc-inline-last-item-83375.rs b/tests/rustdoc-html/multiple-mods-w-same-name-doc-inline-last-item-83375.rs similarity index 100% rename from tests/rustdoc/multiple-mods-w-same-name-doc-inline-last-item-83375.rs rename to tests/rustdoc-html/multiple-mods-w-same-name-doc-inline-last-item-83375.rs diff --git a/tests/rustdoc/multiple-structs-w-same-name-99221.rs b/tests/rustdoc-html/multiple-structs-w-same-name-99221.rs similarity index 100% rename from tests/rustdoc/multiple-structs-w-same-name-99221.rs rename to tests/rustdoc-html/multiple-structs-w-same-name-99221.rs diff --git a/tests/rustdoc/mut-params.rs b/tests/rustdoc-html/mut-params.rs similarity index 100% rename from tests/rustdoc/mut-params.rs rename to tests/rustdoc-html/mut-params.rs diff --git a/tests/rustdoc/namespaces.rs b/tests/rustdoc-html/namespaces.rs similarity index 100% rename from tests/rustdoc/namespaces.rs rename to tests/rustdoc-html/namespaces.rs diff --git a/tests/rustdoc/nested-items-issue-111415.rs b/tests/rustdoc-html/nested-items-issue-111415.rs similarity index 100% rename from tests/rustdoc/nested-items-issue-111415.rs rename to tests/rustdoc-html/nested-items-issue-111415.rs diff --git a/tests/rustdoc/nested-modules.rs b/tests/rustdoc-html/nested-modules.rs similarity index 100% rename from tests/rustdoc/nested-modules.rs rename to tests/rustdoc-html/nested-modules.rs diff --git a/tests/rustdoc/no-run-still-checks-lints.rs b/tests/rustdoc-html/no-run-still-checks-lints.rs similarity index 100% rename from tests/rustdoc/no-run-still-checks-lints.rs rename to tests/rustdoc-html/no-run-still-checks-lints.rs diff --git a/tests/rustdoc/no-stack-overflow-25295.rs b/tests/rustdoc-html/no-stack-overflow-25295.rs similarity index 100% rename from tests/rustdoc/no-stack-overflow-25295.rs rename to tests/rustdoc-html/no-stack-overflow-25295.rs diff --git a/tests/rustdoc/no-unit-struct-field.rs b/tests/rustdoc-html/no-unit-struct-field.rs similarity index 100% rename from tests/rustdoc/no-unit-struct-field.rs rename to tests/rustdoc-html/no-unit-struct-field.rs diff --git a/tests/rustdoc/non_lifetime_binders.rs b/tests/rustdoc-html/non_lifetime_binders.rs similarity index 100% rename from tests/rustdoc/non_lifetime_binders.rs rename to tests/rustdoc-html/non_lifetime_binders.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-negative.negative.html b/tests/rustdoc-html/notable-trait/doc-notable_trait-negative.negative.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-negative.negative.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait-negative.negative.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-negative.positive.html b/tests/rustdoc-html/notable-trait/doc-notable_trait-negative.positive.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-negative.positive.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait-negative.positive.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-negative.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-negative.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-negative.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait-negative.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html b/tests/rustdoc-html/notable-trait/doc-notable_trait-slice.bare_fn_matches.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait-slice.bare_fn_matches.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-slice.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-slice.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-slice.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait-slice.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html b/tests/rustdoc-html/notable-trait/doc-notable_trait.bare-fn.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait.bare-fn.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html b/tests/rustdoc-html/notable-trait/doc-notable_trait.some-struct-new.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait.some-struct-new.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html b/tests/rustdoc-html/notable-trait/doc-notable_trait.wrap-me.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait.wrap-me.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs diff --git a/tests/rustdoc/notable-trait/notable-trait-generics.rs b/tests/rustdoc-html/notable-trait/notable-trait-generics.rs similarity index 100% rename from tests/rustdoc/notable-trait/notable-trait-generics.rs rename to tests/rustdoc-html/notable-trait/notable-trait-generics.rs diff --git a/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html b/tests/rustdoc-html/notable-trait/spotlight-from-dependency.odd.html similarity index 100% rename from tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html rename to tests/rustdoc-html/notable-trait/spotlight-from-dependency.odd.html diff --git a/tests/rustdoc/notable-trait/spotlight-from-dependency.rs b/tests/rustdoc-html/notable-trait/spotlight-from-dependency.rs similarity index 100% rename from tests/rustdoc/notable-trait/spotlight-from-dependency.rs rename to tests/rustdoc-html/notable-trait/spotlight-from-dependency.rs diff --git a/tests/rustdoc/nul-error.rs b/tests/rustdoc-html/nul-error.rs similarity index 100% rename from tests/rustdoc/nul-error.rs rename to tests/rustdoc-html/nul-error.rs diff --git a/tests/rustdoc/playground-arg.rs b/tests/rustdoc-html/playground-arg.rs similarity index 100% rename from tests/rustdoc/playground-arg.rs rename to tests/rustdoc-html/playground-arg.rs diff --git a/tests/rustdoc/playground-empty.rs b/tests/rustdoc-html/playground-empty.rs similarity index 100% rename from tests/rustdoc/playground-empty.rs rename to tests/rustdoc-html/playground-empty.rs diff --git a/tests/rustdoc/playground-none.rs b/tests/rustdoc-html/playground-none.rs similarity index 100% rename from tests/rustdoc/playground-none.rs rename to tests/rustdoc-html/playground-none.rs diff --git a/tests/rustdoc/playground-syntax-error.rs b/tests/rustdoc-html/playground-syntax-error.rs similarity index 100% rename from tests/rustdoc/playground-syntax-error.rs rename to tests/rustdoc-html/playground-syntax-error.rs diff --git a/tests/rustdoc/playground.rs b/tests/rustdoc-html/playground.rs similarity index 100% rename from tests/rustdoc/playground.rs rename to tests/rustdoc-html/playground.rs diff --git a/tests/rustdoc/primitive/auxiliary/issue-15318.rs b/tests/rustdoc-html/primitive/auxiliary/issue-15318.rs similarity index 100% rename from tests/rustdoc/primitive/auxiliary/issue-15318.rs rename to tests/rustdoc-html/primitive/auxiliary/issue-15318.rs diff --git a/tests/rustdoc/primitive/auxiliary/primitive-doc.rs b/tests/rustdoc-html/primitive/auxiliary/primitive-doc.rs similarity index 100% rename from tests/rustdoc/primitive/auxiliary/primitive-doc.rs rename to tests/rustdoc-html/primitive/auxiliary/primitive-doc.rs diff --git a/tests/rustdoc/primitive/cross-crate-primitive-doc.rs b/tests/rustdoc-html/primitive/cross-crate-primitive-doc.rs similarity index 100% rename from tests/rustdoc/primitive/cross-crate-primitive-doc.rs rename to tests/rustdoc-html/primitive/cross-crate-primitive-doc.rs diff --git a/tests/rustdoc/primitive/no_std-primitive.rs b/tests/rustdoc-html/primitive/no_std-primitive.rs similarity index 100% rename from tests/rustdoc/primitive/no_std-primitive.rs rename to tests/rustdoc-html/primitive/no_std-primitive.rs diff --git a/tests/rustdoc/primitive/no_std.rs b/tests/rustdoc-html/primitive/no_std.rs similarity index 100% rename from tests/rustdoc/primitive/no_std.rs rename to tests/rustdoc-html/primitive/no_std.rs diff --git a/tests/rustdoc/primitive/primitive-generic-impl.rs b/tests/rustdoc-html/primitive/primitive-generic-impl.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-generic-impl.rs rename to tests/rustdoc-html/primitive/primitive-generic-impl.rs diff --git a/tests/rustdoc/primitive/primitive-link.rs b/tests/rustdoc-html/primitive/primitive-link.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-link.rs rename to tests/rustdoc-html/primitive/primitive-link.rs diff --git a/tests/rustdoc/primitive/primitive-raw-pointer-dox-15318-3.rs b/tests/rustdoc-html/primitive/primitive-raw-pointer-dox-15318-3.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-raw-pointer-dox-15318-3.rs rename to tests/rustdoc-html/primitive/primitive-raw-pointer-dox-15318-3.rs diff --git a/tests/rustdoc/primitive/primitive-raw-pointer-link-15318.rs b/tests/rustdoc-html/primitive/primitive-raw-pointer-link-15318.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-raw-pointer-link-15318.rs rename to tests/rustdoc-html/primitive/primitive-raw-pointer-link-15318.rs diff --git a/tests/rustdoc/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs b/tests/rustdoc-html/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs rename to tests/rustdoc-html/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs diff --git a/tests/rustdoc/primitive/primitive-reference.rs b/tests/rustdoc-html/primitive/primitive-reference.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-reference.rs rename to tests/rustdoc-html/primitive/primitive-reference.rs diff --git a/tests/rustdoc/primitive/primitive-slice-auto-trait.rs b/tests/rustdoc-html/primitive/primitive-slice-auto-trait.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-slice-auto-trait.rs rename to tests/rustdoc-html/primitive/primitive-slice-auto-trait.rs diff --git a/tests/rustdoc/primitive/primitive-tuple-auto-trait.rs b/tests/rustdoc-html/primitive/primitive-tuple-auto-trait.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-tuple-auto-trait.rs rename to tests/rustdoc-html/primitive/primitive-tuple-auto-trait.rs diff --git a/tests/rustdoc/primitive/primitive-tuple-variadic.rs b/tests/rustdoc-html/primitive/primitive-tuple-variadic.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-tuple-variadic.rs rename to tests/rustdoc-html/primitive/primitive-tuple-variadic.rs diff --git a/tests/rustdoc/primitive/primitive-unit-auto-trait.rs b/tests/rustdoc-html/primitive/primitive-unit-auto-trait.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-unit-auto-trait.rs rename to tests/rustdoc-html/primitive/primitive-unit-auto-trait.rs diff --git a/tests/rustdoc/primitive/primitive.rs b/tests/rustdoc-html/primitive/primitive.rs similarity index 100% rename from tests/rustdoc/primitive/primitive.rs rename to tests/rustdoc-html/primitive/primitive.rs diff --git a/tests/rustdoc/primitive/search-index-primitive-inherent-method-23511.rs b/tests/rustdoc-html/primitive/search-index-primitive-inherent-method-23511.rs similarity index 100% rename from tests/rustdoc/primitive/search-index-primitive-inherent-method-23511.rs rename to tests/rustdoc-html/primitive/search-index-primitive-inherent-method-23511.rs diff --git a/tests/rustdoc/private/doc-hidden-private-67851-both.rs b/tests/rustdoc-html/private/doc-hidden-private-67851-both.rs similarity index 100% rename from tests/rustdoc/private/doc-hidden-private-67851-both.rs rename to tests/rustdoc-html/private/doc-hidden-private-67851-both.rs diff --git a/tests/rustdoc/private/doc-hidden-private-67851-hidden.rs b/tests/rustdoc-html/private/doc-hidden-private-67851-hidden.rs similarity index 100% rename from tests/rustdoc/private/doc-hidden-private-67851-hidden.rs rename to tests/rustdoc-html/private/doc-hidden-private-67851-hidden.rs diff --git a/tests/rustdoc/private/doc-hidden-private-67851-neither.rs b/tests/rustdoc-html/private/doc-hidden-private-67851-neither.rs similarity index 100% rename from tests/rustdoc/private/doc-hidden-private-67851-neither.rs rename to tests/rustdoc-html/private/doc-hidden-private-67851-neither.rs diff --git a/tests/rustdoc/private/doc-hidden-private-67851-private.rs b/tests/rustdoc-html/private/doc-hidden-private-67851-private.rs similarity index 100% rename from tests/rustdoc/private/doc-hidden-private-67851-private.rs rename to tests/rustdoc-html/private/doc-hidden-private-67851-private.rs diff --git a/tests/rustdoc/private/empty-impl-block-private-with-doc.rs b/tests/rustdoc-html/private/empty-impl-block-private-with-doc.rs similarity index 100% rename from tests/rustdoc/private/empty-impl-block-private-with-doc.rs rename to tests/rustdoc-html/private/empty-impl-block-private-with-doc.rs diff --git a/tests/rustdoc/private/empty-impl-block-private.rs b/tests/rustdoc-html/private/empty-impl-block-private.rs similarity index 100% rename from tests/rustdoc/private/empty-impl-block-private.rs rename to tests/rustdoc-html/private/empty-impl-block-private.rs diff --git a/tests/rustdoc/private/empty-mod-private.rs b/tests/rustdoc-html/private/empty-mod-private.rs similarity index 100% rename from tests/rustdoc/private/empty-mod-private.rs rename to tests/rustdoc-html/private/empty-mod-private.rs diff --git a/tests/rustdoc/private/enum-variant-private-46767.rs b/tests/rustdoc-html/private/enum-variant-private-46767.rs similarity index 100% rename from tests/rustdoc/private/enum-variant-private-46767.rs rename to tests/rustdoc-html/private/enum-variant-private-46767.rs diff --git a/tests/rustdoc/private/files-creation-private.rs b/tests/rustdoc-html/private/files-creation-private.rs similarity index 100% rename from tests/rustdoc/private/files-creation-private.rs rename to tests/rustdoc-html/private/files-creation-private.rs diff --git a/tests/rustdoc/private/hidden-private.rs b/tests/rustdoc-html/private/hidden-private.rs similarity index 100% rename from tests/rustdoc/private/hidden-private.rs rename to tests/rustdoc-html/private/hidden-private.rs diff --git a/tests/rustdoc/private/inline-private-with-intermediate-doc-hidden.rs b/tests/rustdoc-html/private/inline-private-with-intermediate-doc-hidden.rs similarity index 100% rename from tests/rustdoc/private/inline-private-with-intermediate-doc-hidden.rs rename to tests/rustdoc-html/private/inline-private-with-intermediate-doc-hidden.rs diff --git a/tests/rustdoc/private/inner-private-110422.rs b/tests/rustdoc-html/private/inner-private-110422.rs similarity index 100% rename from tests/rustdoc/private/inner-private-110422.rs rename to tests/rustdoc-html/private/inner-private-110422.rs diff --git a/tests/rustdoc/private/macro-document-private-duplicate.rs b/tests/rustdoc-html/private/macro-document-private-duplicate.rs similarity index 100% rename from tests/rustdoc/private/macro-document-private-duplicate.rs rename to tests/rustdoc-html/private/macro-document-private-duplicate.rs diff --git a/tests/rustdoc/private/macro-document-private.rs b/tests/rustdoc-html/private/macro-document-private.rs similarity index 100% rename from tests/rustdoc/private/macro-document-private.rs rename to tests/rustdoc-html/private/macro-document-private.rs diff --git a/tests/rustdoc/private/macro-private-not-documented.rs b/tests/rustdoc-html/private/macro-private-not-documented.rs similarity index 100% rename from tests/rustdoc/private/macro-private-not-documented.rs rename to tests/rustdoc-html/private/macro-private-not-documented.rs diff --git a/tests/rustdoc/private/missing-private-inlining-109258.rs b/tests/rustdoc-html/private/missing-private-inlining-109258.rs similarity index 100% rename from tests/rustdoc/private/missing-private-inlining-109258.rs rename to tests/rustdoc-html/private/missing-private-inlining-109258.rs diff --git a/tests/rustdoc/private/private-fields-tuple-struct.rs b/tests/rustdoc-html/private/private-fields-tuple-struct.rs similarity index 100% rename from tests/rustdoc/private/private-fields-tuple-struct.rs rename to tests/rustdoc-html/private/private-fields-tuple-struct.rs diff --git a/tests/rustdoc/private/private-non-local-fields-2.rs b/tests/rustdoc-html/private/private-non-local-fields-2.rs similarity index 100% rename from tests/rustdoc/private/private-non-local-fields-2.rs rename to tests/rustdoc-html/private/private-non-local-fields-2.rs diff --git a/tests/rustdoc/private/private-non-local-fields.rs b/tests/rustdoc-html/private/private-non-local-fields.rs similarity index 100% rename from tests/rustdoc/private/private-non-local-fields.rs rename to tests/rustdoc-html/private/private-non-local-fields.rs diff --git a/tests/rustdoc/private/private-type-alias.rs b/tests/rustdoc-html/private/private-type-alias.rs similarity index 100% rename from tests/rustdoc/private/private-type-alias.rs rename to tests/rustdoc-html/private/private-type-alias.rs diff --git a/tests/rustdoc/private/private-type-cycle-110629.rs b/tests/rustdoc-html/private/private-type-cycle-110629.rs similarity index 100% rename from tests/rustdoc/private/private-type-cycle-110629.rs rename to tests/rustdoc-html/private/private-type-cycle-110629.rs diff --git a/tests/rustdoc/private/private-use-decl-macro-47038.rs b/tests/rustdoc-html/private/private-use-decl-macro-47038.rs similarity index 100% rename from tests/rustdoc/private/private-use-decl-macro-47038.rs rename to tests/rustdoc-html/private/private-use-decl-macro-47038.rs diff --git a/tests/rustdoc/private/private-use.rs b/tests/rustdoc-html/private/private-use.rs similarity index 100% rename from tests/rustdoc/private/private-use.rs rename to tests/rustdoc-html/private/private-use.rs diff --git a/tests/rustdoc/private/public-impl-mention-private-generic-46380-2.rs b/tests/rustdoc-html/private/public-impl-mention-private-generic-46380-2.rs similarity index 100% rename from tests/rustdoc/private/public-impl-mention-private-generic-46380-2.rs rename to tests/rustdoc-html/private/public-impl-mention-private-generic-46380-2.rs diff --git a/tests/rustdoc/private/traits-in-bodies-private.rs b/tests/rustdoc-html/private/traits-in-bodies-private.rs similarity index 100% rename from tests/rustdoc/private/traits-in-bodies-private.rs rename to tests/rustdoc-html/private/traits-in-bodies-private.rs diff --git a/tests/rustdoc/process-termination.rs b/tests/rustdoc-html/process-termination.rs similarity index 100% rename from tests/rustdoc/process-termination.rs rename to tests/rustdoc-html/process-termination.rs diff --git a/tests/rustdoc/pub-method.rs b/tests/rustdoc-html/pub-method.rs similarity index 100% rename from tests/rustdoc/pub-method.rs rename to tests/rustdoc-html/pub-method.rs diff --git a/tests/rustdoc/pub-use-loop-107350.rs b/tests/rustdoc-html/pub-use-loop-107350.rs similarity index 100% rename from tests/rustdoc/pub-use-loop-107350.rs rename to tests/rustdoc-html/pub-use-loop-107350.rs diff --git a/tests/rustdoc/pub-use-root-path-95873.rs b/tests/rustdoc-html/pub-use-root-path-95873.rs similarity index 100% rename from tests/rustdoc/pub-use-root-path-95873.rs rename to tests/rustdoc-html/pub-use-root-path-95873.rs diff --git a/tests/rustdoc/range-arg-pattern.rs b/tests/rustdoc-html/range-arg-pattern.rs similarity index 100% rename from tests/rustdoc/range-arg-pattern.rs rename to tests/rustdoc-html/range-arg-pattern.rs diff --git a/tests/rustdoc/raw-ident-eliminate-r-hashtag.rs b/tests/rustdoc-html/raw-ident-eliminate-r-hashtag.rs similarity index 100% rename from tests/rustdoc/raw-ident-eliminate-r-hashtag.rs rename to tests/rustdoc-html/raw-ident-eliminate-r-hashtag.rs diff --git a/tests/rustdoc/read-more-unneeded.rs b/tests/rustdoc-html/read-more-unneeded.rs similarity index 100% rename from tests/rustdoc/read-more-unneeded.rs rename to tests/rustdoc-html/read-more-unneeded.rs diff --git a/tests/rustdoc/recursion1.rs b/tests/rustdoc-html/recursion1.rs similarity index 100% rename from tests/rustdoc/recursion1.rs rename to tests/rustdoc-html/recursion1.rs diff --git a/tests/rustdoc/recursion2.rs b/tests/rustdoc-html/recursion2.rs similarity index 100% rename from tests/rustdoc/recursion2.rs rename to tests/rustdoc-html/recursion2.rs diff --git a/tests/rustdoc/recursion3.rs b/tests/rustdoc-html/recursion3.rs similarity index 100% rename from tests/rustdoc/recursion3.rs rename to tests/rustdoc-html/recursion3.rs diff --git a/tests/rustdoc/redirect-map-empty.rs b/tests/rustdoc-html/redirect-map-empty.rs similarity index 100% rename from tests/rustdoc/redirect-map-empty.rs rename to tests/rustdoc-html/redirect-map-empty.rs diff --git a/tests/rustdoc/redirect-map.rs b/tests/rustdoc-html/redirect-map.rs similarity index 100% rename from tests/rustdoc/redirect-map.rs rename to tests/rustdoc-html/redirect-map.rs diff --git a/tests/rustdoc/redirect-rename.rs b/tests/rustdoc-html/redirect-rename.rs similarity index 100% rename from tests/rustdoc/redirect-rename.rs rename to tests/rustdoc-html/redirect-rename.rs diff --git a/tests/rustdoc/redirect.rs b/tests/rustdoc-html/redirect.rs similarity index 100% rename from tests/rustdoc/redirect.rs rename to tests/rustdoc-html/redirect.rs diff --git a/tests/rustdoc/reexport/alias-reexport.rs b/tests/rustdoc-html/reexport/alias-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/alias-reexport.rs rename to tests/rustdoc-html/reexport/alias-reexport.rs diff --git a/tests/rustdoc/reexport/alias-reexport2.rs b/tests/rustdoc-html/reexport/alias-reexport2.rs similarity index 100% rename from tests/rustdoc/reexport/alias-reexport2.rs rename to tests/rustdoc-html/reexport/alias-reexport2.rs diff --git a/tests/rustdoc/reexport/anonymous-reexport-108931.rs b/tests/rustdoc-html/reexport/anonymous-reexport-108931.rs similarity index 100% rename from tests/rustdoc/reexport/anonymous-reexport-108931.rs rename to tests/rustdoc-html/reexport/anonymous-reexport-108931.rs diff --git a/tests/rustdoc/reexport/anonymous-reexport.rs b/tests/rustdoc-html/reexport/anonymous-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/anonymous-reexport.rs rename to tests/rustdoc-html/reexport/anonymous-reexport.rs diff --git a/tests/rustdoc/reexport/auxiliary/alias-reexport.rs b/tests/rustdoc-html/reexport/auxiliary/alias-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/alias-reexport.rs rename to tests/rustdoc-html/reexport/auxiliary/alias-reexport.rs diff --git a/tests/rustdoc/reexport/auxiliary/alias-reexport2.rs b/tests/rustdoc-html/reexport/auxiliary/alias-reexport2.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/alias-reexport2.rs rename to tests/rustdoc-html/reexport/auxiliary/alias-reexport2.rs diff --git a/tests/rustdoc/reexport/auxiliary/all-item-types.rs b/tests/rustdoc-html/reexport/auxiliary/all-item-types.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/all-item-types.rs rename to tests/rustdoc-html/reexport/auxiliary/all-item-types.rs diff --git a/tests/rustdoc/reexport/auxiliary/issue-28927-1.rs b/tests/rustdoc-html/reexport/auxiliary/issue-28927-1.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/issue-28927-1.rs rename to tests/rustdoc-html/reexport/auxiliary/issue-28927-1.rs diff --git a/tests/rustdoc/reexport/auxiliary/issue-28927-2.rs b/tests/rustdoc-html/reexport/auxiliary/issue-28927-2.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/issue-28927-2.rs rename to tests/rustdoc-html/reexport/auxiliary/issue-28927-2.rs diff --git a/tests/rustdoc/reexport/auxiliary/primitive-reexport.rs b/tests/rustdoc-html/reexport/auxiliary/primitive-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/primitive-reexport.rs rename to tests/rustdoc-html/reexport/auxiliary/primitive-reexport.rs diff --git a/tests/rustdoc/reexport/auxiliary/reexport-check.rs b/tests/rustdoc-html/reexport/auxiliary/reexport-check.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/reexport-check.rs rename to tests/rustdoc-html/reexport/auxiliary/reexport-check.rs diff --git a/tests/rustdoc/reexport/auxiliary/reexport-doc-aux.rs b/tests/rustdoc-html/reexport/auxiliary/reexport-doc-aux.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/reexport-doc-aux.rs rename to tests/rustdoc-html/reexport/auxiliary/reexport-doc-aux.rs diff --git a/tests/rustdoc/reexport/auxiliary/reexports.rs b/tests/rustdoc-html/reexport/auxiliary/reexports.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/reexports.rs rename to tests/rustdoc-html/reexport/auxiliary/reexports.rs diff --git a/tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs b/tests/rustdoc-html/reexport/auxiliary/wrap-unnamable-type.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs rename to tests/rustdoc-html/reexport/auxiliary/wrap-unnamable-type.rs diff --git a/tests/rustdoc/reexport/blanket-reexport-item.rs b/tests/rustdoc-html/reexport/blanket-reexport-item.rs similarity index 100% rename from tests/rustdoc/reexport/blanket-reexport-item.rs rename to tests/rustdoc-html/reexport/blanket-reexport-item.rs diff --git a/tests/rustdoc/reexport/cfg_doc_reexport.rs b/tests/rustdoc-html/reexport/cfg_doc_reexport.rs similarity index 100% rename from tests/rustdoc/reexport/cfg_doc_reexport.rs rename to tests/rustdoc-html/reexport/cfg_doc_reexport.rs diff --git a/tests/rustdoc/reexport/doc-hidden-reexports-109449.rs b/tests/rustdoc-html/reexport/doc-hidden-reexports-109449.rs similarity index 100% rename from tests/rustdoc/reexport/doc-hidden-reexports-109449.rs rename to tests/rustdoc-html/reexport/doc-hidden-reexports-109449.rs diff --git a/tests/rustdoc/reexport/duplicated-glob-reexport-60522.rs b/tests/rustdoc-html/reexport/duplicated-glob-reexport-60522.rs similarity index 100% rename from tests/rustdoc/reexport/duplicated-glob-reexport-60522.rs rename to tests/rustdoc-html/reexport/duplicated-glob-reexport-60522.rs diff --git a/tests/rustdoc/reexport/enum-variant-reexport-35488.rs b/tests/rustdoc-html/reexport/enum-variant-reexport-35488.rs similarity index 100% rename from tests/rustdoc/reexport/enum-variant-reexport-35488.rs rename to tests/rustdoc-html/reexport/enum-variant-reexport-35488.rs diff --git a/tests/rustdoc/reexport/enum-variant.rs b/tests/rustdoc-html/reexport/enum-variant.rs similarity index 100% rename from tests/rustdoc/reexport/enum-variant.rs rename to tests/rustdoc-html/reexport/enum-variant.rs diff --git a/tests/rustdoc/reexport/extern-135092.rs b/tests/rustdoc-html/reexport/extern-135092.rs similarity index 100% rename from tests/rustdoc/reexport/extern-135092.rs rename to tests/rustdoc-html/reexport/extern-135092.rs diff --git a/tests/rustdoc/reexport/foreigntype-reexport.rs b/tests/rustdoc-html/reexport/foreigntype-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/foreigntype-reexport.rs rename to tests/rustdoc-html/reexport/foreigntype-reexport.rs diff --git a/tests/rustdoc/reexport/glob-reexport-attribute-merge-120487.rs b/tests/rustdoc-html/reexport/glob-reexport-attribute-merge-120487.rs similarity index 100% rename from tests/rustdoc/reexport/glob-reexport-attribute-merge-120487.rs rename to tests/rustdoc-html/reexport/glob-reexport-attribute-merge-120487.rs diff --git a/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs b/tests/rustdoc-html/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs similarity index 100% rename from tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs rename to tests/rustdoc-html/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs diff --git a/tests/rustdoc/reexport/ice-reexport-crate-root-28927.rs b/tests/rustdoc-html/reexport/ice-reexport-crate-root-28927.rs similarity index 100% rename from tests/rustdoc/reexport/ice-reexport-crate-root-28927.rs rename to tests/rustdoc-html/reexport/ice-reexport-crate-root-28927.rs diff --git a/tests/rustdoc/reexport/import_trait_associated_functions.rs b/tests/rustdoc-html/reexport/import_trait_associated_functions.rs similarity index 100% rename from tests/rustdoc/reexport/import_trait_associated_functions.rs rename to tests/rustdoc-html/reexport/import_trait_associated_functions.rs diff --git a/tests/rustdoc/reexport/local-reexport-doc.rs b/tests/rustdoc-html/reexport/local-reexport-doc.rs similarity index 100% rename from tests/rustdoc/reexport/local-reexport-doc.rs rename to tests/rustdoc-html/reexport/local-reexport-doc.rs diff --git a/tests/rustdoc/reexport/merge-glob-and-non-glob.rs b/tests/rustdoc-html/reexport/merge-glob-and-non-glob.rs similarity index 100% rename from tests/rustdoc/reexport/merge-glob-and-non-glob.rs rename to tests/rustdoc-html/reexport/merge-glob-and-non-glob.rs diff --git a/tests/rustdoc/reexport/no-compiler-reexport.rs b/tests/rustdoc-html/reexport/no-compiler-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/no-compiler-reexport.rs rename to tests/rustdoc-html/reexport/no-compiler-reexport.rs diff --git a/tests/rustdoc/reexport/overlapping-reexport-105735-2.rs b/tests/rustdoc-html/reexport/overlapping-reexport-105735-2.rs similarity index 100% rename from tests/rustdoc/reexport/overlapping-reexport-105735-2.rs rename to tests/rustdoc-html/reexport/overlapping-reexport-105735-2.rs diff --git a/tests/rustdoc/reexport/overlapping-reexport-105735.rs b/tests/rustdoc-html/reexport/overlapping-reexport-105735.rs similarity index 100% rename from tests/rustdoc/reexport/overlapping-reexport-105735.rs rename to tests/rustdoc-html/reexport/overlapping-reexport-105735.rs diff --git a/tests/rustdoc/reexport/primitive-reexport.rs b/tests/rustdoc-html/reexport/primitive-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/primitive-reexport.rs rename to tests/rustdoc-html/reexport/primitive-reexport.rs diff --git a/tests/rustdoc/reexport/private-mod-override-reexport.rs b/tests/rustdoc-html/reexport/private-mod-override-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/private-mod-override-reexport.rs rename to tests/rustdoc-html/reexport/private-mod-override-reexport.rs diff --git a/tests/rustdoc/reexport/pub-reexport-of-pub-reexport-46506.rs b/tests/rustdoc-html/reexport/pub-reexport-of-pub-reexport-46506.rs similarity index 100% rename from tests/rustdoc/reexport/pub-reexport-of-pub-reexport-46506.rs rename to tests/rustdoc-html/reexport/pub-reexport-of-pub-reexport-46506.rs diff --git a/tests/rustdoc/reexport/reexport-attr-merge.rs b/tests/rustdoc-html/reexport/reexport-attr-merge.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-attr-merge.rs rename to tests/rustdoc-html/reexport/reexport-attr-merge.rs diff --git a/tests/rustdoc/reexport/reexport-cfg.rs b/tests/rustdoc-html/reexport/reexport-cfg.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-cfg.rs rename to tests/rustdoc-html/reexport/reexport-cfg.rs diff --git a/tests/rustdoc/reexport/reexport-check.rs b/tests/rustdoc-html/reexport/reexport-check.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-check.rs rename to tests/rustdoc-html/reexport/reexport-check.rs diff --git a/tests/rustdoc/reexport/reexport-dep-foreign-fn.rs b/tests/rustdoc-html/reexport/reexport-dep-foreign-fn.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-dep-foreign-fn.rs rename to tests/rustdoc-html/reexport/reexport-dep-foreign-fn.rs diff --git a/tests/rustdoc/reexport/reexport-doc-hidden-inside-private.rs b/tests/rustdoc-html/reexport/reexport-doc-hidden-inside-private.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-doc-hidden-inside-private.rs rename to tests/rustdoc-html/reexport/reexport-doc-hidden-inside-private.rs diff --git a/tests/rustdoc/reexport/reexport-doc-hidden.rs b/tests/rustdoc-html/reexport/reexport-doc-hidden.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-doc-hidden.rs rename to tests/rustdoc-html/reexport/reexport-doc-hidden.rs diff --git a/tests/rustdoc/reexport/reexport-doc.rs b/tests/rustdoc-html/reexport/reexport-doc.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-doc.rs rename to tests/rustdoc-html/reexport/reexport-doc.rs diff --git a/tests/rustdoc/reexport/reexport-hidden-macro.rs b/tests/rustdoc-html/reexport/reexport-hidden-macro.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-hidden-macro.rs rename to tests/rustdoc-html/reexport/reexport-hidden-macro.rs diff --git a/tests/rustdoc/reexport/reexport-macro.rs b/tests/rustdoc-html/reexport/reexport-macro.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-macro.rs rename to tests/rustdoc-html/reexport/reexport-macro.rs diff --git a/tests/rustdoc/reexport/reexport-of-doc-hidden.rs b/tests/rustdoc-html/reexport/reexport-of-doc-hidden.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-of-doc-hidden.rs rename to tests/rustdoc-html/reexport/reexport-of-doc-hidden.rs diff --git a/tests/rustdoc/reexport/reexport-of-reexport-108679.rs b/tests/rustdoc-html/reexport/reexport-of-reexport-108679.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-of-reexport-108679.rs rename to tests/rustdoc-html/reexport/reexport-of-reexport-108679.rs diff --git a/tests/rustdoc/reexport/reexport-stability-tags-deprecated-and-portability.rs b/tests/rustdoc-html/reexport/reexport-stability-tags-deprecated-and-portability.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-stability-tags-deprecated-and-portability.rs rename to tests/rustdoc-html/reexport/reexport-stability-tags-deprecated-and-portability.rs diff --git a/tests/rustdoc/reexport/reexport-stability-tags-unstable-and-portability.rs b/tests/rustdoc-html/reexport/reexport-stability-tags-unstable-and-portability.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-stability-tags-unstable-and-portability.rs rename to tests/rustdoc-html/reexport/reexport-stability-tags-unstable-and-portability.rs diff --git a/tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs b/tests/rustdoc-html/reexport/reexport-trait-from-hidden-111064-2.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs rename to tests/rustdoc-html/reexport/reexport-trait-from-hidden-111064-2.rs diff --git a/tests/rustdoc/reexport/reexport-trait-from-hidden-111064.rs b/tests/rustdoc-html/reexport/reexport-trait-from-hidden-111064.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-trait-from-hidden-111064.rs rename to tests/rustdoc-html/reexport/reexport-trait-from-hidden-111064.rs diff --git a/tests/rustdoc/reexport/reexports-of-same-name.rs b/tests/rustdoc-html/reexport/reexports-of-same-name.rs similarity index 100% rename from tests/rustdoc/reexport/reexports-of-same-name.rs rename to tests/rustdoc-html/reexport/reexports-of-same-name.rs diff --git a/tests/rustdoc/reexport/reexports-priv.rs b/tests/rustdoc-html/reexport/reexports-priv.rs similarity index 100% rename from tests/rustdoc/reexport/reexports-priv.rs rename to tests/rustdoc-html/reexport/reexports-priv.rs diff --git a/tests/rustdoc/reexport/reexports.rs b/tests/rustdoc-html/reexport/reexports.rs similarity index 100% rename from tests/rustdoc/reexport/reexports.rs rename to tests/rustdoc-html/reexport/reexports.rs diff --git a/tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs b/tests/rustdoc-html/reexport/wrapped-unnamble-type-143222.rs similarity index 100% rename from tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs rename to tests/rustdoc-html/reexport/wrapped-unnamble-type-143222.rs diff --git a/tests/rustdoc/remove-duplicates.rs b/tests/rustdoc-html/remove-duplicates.rs similarity index 100% rename from tests/rustdoc/remove-duplicates.rs rename to tests/rustdoc-html/remove-duplicates.rs diff --git a/tests/rustdoc/remove-url-from-headings.rs b/tests/rustdoc-html/remove-url-from-headings.rs similarity index 100% rename from tests/rustdoc/remove-url-from-headings.rs rename to tests/rustdoc-html/remove-url-from-headings.rs diff --git a/tests/rustdoc/repr.rs b/tests/rustdoc-html/repr.rs similarity index 100% rename from tests/rustdoc/repr.rs rename to tests/rustdoc-html/repr.rs diff --git a/tests/rustdoc/resolve-ice-124363.rs b/tests/rustdoc-html/resolve-ice-124363.rs similarity index 100% rename from tests/rustdoc/resolve-ice-124363.rs rename to tests/rustdoc-html/resolve-ice-124363.rs diff --git a/tests/rustdoc/return-type-notation.rs b/tests/rustdoc-html/return-type-notation.rs similarity index 100% rename from tests/rustdoc/return-type-notation.rs rename to tests/rustdoc-html/return-type-notation.rs diff --git a/tests/rustdoc/safe-intrinsic.rs b/tests/rustdoc-html/safe-intrinsic.rs similarity index 100% rename from tests/rustdoc/safe-intrinsic.rs rename to tests/rustdoc-html/safe-intrinsic.rs diff --git a/tests/rustdoc/sanitizer-option.rs b/tests/rustdoc-html/sanitizer-option.rs similarity index 100% rename from tests/rustdoc/sanitizer-option.rs rename to tests/rustdoc-html/sanitizer-option.rs diff --git a/tests/rustdoc/search-index-summaries.rs b/tests/rustdoc-html/search-index-summaries.rs similarity index 100% rename from tests/rustdoc/search-index-summaries.rs rename to tests/rustdoc-html/search-index-summaries.rs diff --git a/tests/rustdoc/search-index.rs b/tests/rustdoc-html/search-index.rs similarity index 100% rename from tests/rustdoc/search-index.rs rename to tests/rustdoc-html/search-index.rs diff --git a/tests/rustdoc/short-docblock-codeblock.rs b/tests/rustdoc-html/short-docblock-codeblock.rs similarity index 100% rename from tests/rustdoc/short-docblock-codeblock.rs rename to tests/rustdoc-html/short-docblock-codeblock.rs diff --git a/tests/rustdoc/short-docblock.rs b/tests/rustdoc-html/short-docblock.rs similarity index 100% rename from tests/rustdoc/short-docblock.rs rename to tests/rustdoc-html/short-docblock.rs diff --git a/tests/rustdoc/short-line.md b/tests/rustdoc-html/short-line.md similarity index 100% rename from tests/rustdoc/short-line.md rename to tests/rustdoc-html/short-line.md diff --git a/tests/rustdoc/sidebar/module.rs b/tests/rustdoc-html/sidebar/module.rs similarity index 100% rename from tests/rustdoc/sidebar/module.rs rename to tests/rustdoc-html/sidebar/module.rs diff --git a/tests/rustdoc/sidebar/sidebar-all-page.rs b/tests/rustdoc-html/sidebar/sidebar-all-page.rs similarity index 100% rename from tests/rustdoc/sidebar/sidebar-all-page.rs rename to tests/rustdoc-html/sidebar/sidebar-all-page.rs diff --git a/tests/rustdoc/sidebar/sidebar-items.rs b/tests/rustdoc-html/sidebar/sidebar-items.rs similarity index 100% rename from tests/rustdoc/sidebar/sidebar-items.rs rename to tests/rustdoc-html/sidebar/sidebar-items.rs diff --git a/tests/rustdoc/sidebar/sidebar-link-generation.rs b/tests/rustdoc-html/sidebar/sidebar-link-generation.rs similarity index 100% rename from tests/rustdoc/sidebar/sidebar-link-generation.rs rename to tests/rustdoc-html/sidebar/sidebar-link-generation.rs diff --git a/tests/rustdoc/sidebar/sidebar-links-to-foreign-impl.rs b/tests/rustdoc-html/sidebar/sidebar-links-to-foreign-impl.rs similarity index 100% rename from tests/rustdoc/sidebar/sidebar-links-to-foreign-impl.rs rename to tests/rustdoc-html/sidebar/sidebar-links-to-foreign-impl.rs diff --git a/tests/rustdoc/sidebar/top-toc-html.rs b/tests/rustdoc-html/sidebar/top-toc-html.rs similarity index 100% rename from tests/rustdoc/sidebar/top-toc-html.rs rename to tests/rustdoc-html/sidebar/top-toc-html.rs diff --git a/tests/rustdoc/sidebar/top-toc-idmap.rs b/tests/rustdoc-html/sidebar/top-toc-idmap.rs similarity index 100% rename from tests/rustdoc/sidebar/top-toc-idmap.rs rename to tests/rustdoc-html/sidebar/top-toc-idmap.rs diff --git a/tests/rustdoc/sidebar/top-toc-nil.rs b/tests/rustdoc-html/sidebar/top-toc-nil.rs similarity index 100% rename from tests/rustdoc/sidebar/top-toc-nil.rs rename to tests/rustdoc-html/sidebar/top-toc-nil.rs diff --git a/tests/rustdoc/sized_trait.rs b/tests/rustdoc-html/sized_trait.rs similarity index 100% rename from tests/rustdoc/sized_trait.rs rename to tests/rustdoc-html/sized_trait.rs diff --git a/tests/rustdoc/slice-links.link_box_generic.html b/tests/rustdoc-html/slice-links.link_box_generic.html similarity index 100% rename from tests/rustdoc/slice-links.link_box_generic.html rename to tests/rustdoc-html/slice-links.link_box_generic.html diff --git a/tests/rustdoc/slice-links.link_box_u32.html b/tests/rustdoc-html/slice-links.link_box_u32.html similarity index 100% rename from tests/rustdoc/slice-links.link_box_u32.html rename to tests/rustdoc-html/slice-links.link_box_u32.html diff --git a/tests/rustdoc/slice-links.link_slice_generic.html b/tests/rustdoc-html/slice-links.link_slice_generic.html similarity index 100% rename from tests/rustdoc/slice-links.link_slice_generic.html rename to tests/rustdoc-html/slice-links.link_slice_generic.html diff --git a/tests/rustdoc/slice-links.link_slice_u32.html b/tests/rustdoc-html/slice-links.link_slice_u32.html similarity index 100% rename from tests/rustdoc/slice-links.link_slice_u32.html rename to tests/rustdoc-html/slice-links.link_slice_u32.html diff --git a/tests/rustdoc/slice-links.rs b/tests/rustdoc-html/slice-links.rs similarity index 100% rename from tests/rustdoc/slice-links.rs rename to tests/rustdoc-html/slice-links.rs diff --git a/tests/rustdoc/smart-punct.rs b/tests/rustdoc-html/smart-punct.rs similarity index 100% rename from tests/rustdoc/smart-punct.rs rename to tests/rustdoc-html/smart-punct.rs diff --git a/tests/rustdoc/smoke.rs b/tests/rustdoc-html/smoke.rs similarity index 100% rename from tests/rustdoc/smoke.rs rename to tests/rustdoc-html/smoke.rs diff --git a/tests/rustdoc/sort-53812.rs b/tests/rustdoc-html/sort-53812.rs similarity index 100% rename from tests/rustdoc/sort-53812.rs rename to tests/rustdoc-html/sort-53812.rs diff --git a/tests/rustdoc/sort-modules-by-appearance.rs b/tests/rustdoc-html/sort-modules-by-appearance.rs similarity index 100% rename from tests/rustdoc/sort-modules-by-appearance.rs rename to tests/rustdoc-html/sort-modules-by-appearance.rs diff --git a/tests/rustdoc/source-code-pages/assoc-type-source-link.rs b/tests/rustdoc-html/source-code-pages/assoc-type-source-link.rs similarity index 100% rename from tests/rustdoc/source-code-pages/assoc-type-source-link.rs rename to tests/rustdoc-html/source-code-pages/assoc-type-source-link.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/issue-26606-macro.rs b/tests/rustdoc-html/source-code-pages/auxiliary/issue-26606-macro.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/issue-26606-macro.rs rename to tests/rustdoc-html/source-code-pages/auxiliary/issue-26606-macro.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/issue-34274.rs b/tests/rustdoc-html/source-code-pages/auxiliary/issue-34274.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/issue-34274.rs rename to tests/rustdoc-html/source-code-pages/auxiliary/issue-34274.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/source-code-bar.rs b/tests/rustdoc-html/source-code-pages/auxiliary/source-code-bar.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/source-code-bar.rs rename to tests/rustdoc-html/source-code-pages/auxiliary/source-code-bar.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/source_code.rs b/tests/rustdoc-html/source-code-pages/auxiliary/source_code.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/source_code.rs rename to tests/rustdoc-html/source-code-pages/auxiliary/source_code.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/src-links-external.rs b/tests/rustdoc-html/source-code-pages/auxiliary/src-links-external.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/src-links-external.rs rename to tests/rustdoc-html/source-code-pages/auxiliary/src-links-external.rs diff --git a/tests/rustdoc/source-code-pages/check-source-code-urls-to-def-std.rs b/tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def-std.rs similarity index 100% rename from tests/rustdoc/source-code-pages/check-source-code-urls-to-def-std.rs rename to tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def-std.rs diff --git a/tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs b/tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def.rs similarity index 100% rename from tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs rename to tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def.rs diff --git a/tests/rustdoc/source-code-pages/doc-hidden-source.rs b/tests/rustdoc-html/source-code-pages/doc-hidden-source.rs similarity index 100% rename from tests/rustdoc/source-code-pages/doc-hidden-source.rs rename to tests/rustdoc-html/source-code-pages/doc-hidden-source.rs diff --git a/tests/rustdoc/source-code-pages/failing-expansion-on-wrong-macro.rs b/tests/rustdoc-html/source-code-pages/failing-expansion-on-wrong-macro.rs similarity index 100% rename from tests/rustdoc/source-code-pages/failing-expansion-on-wrong-macro.rs rename to tests/rustdoc-html/source-code-pages/failing-expansion-on-wrong-macro.rs diff --git a/tests/rustdoc/source-code-pages/frontmatter.rs b/tests/rustdoc-html/source-code-pages/frontmatter.rs similarity index 100% rename from tests/rustdoc/source-code-pages/frontmatter.rs rename to tests/rustdoc-html/source-code-pages/frontmatter.rs diff --git a/tests/rustdoc/source-code-pages/html-no-source.rs b/tests/rustdoc-html/source-code-pages/html-no-source.rs similarity index 100% rename from tests/rustdoc/source-code-pages/html-no-source.rs rename to tests/rustdoc-html/source-code-pages/html-no-source.rs diff --git a/tests/rustdoc/source-code-pages/keyword-macros.rs b/tests/rustdoc-html/source-code-pages/keyword-macros.rs similarity index 100% rename from tests/rustdoc/source-code-pages/keyword-macros.rs rename to tests/rustdoc-html/source-code-pages/keyword-macros.rs diff --git a/tests/rustdoc/source-code-pages/shebang.rs b/tests/rustdoc-html/source-code-pages/shebang.rs similarity index 100% rename from tests/rustdoc/source-code-pages/shebang.rs rename to tests/rustdoc-html/source-code-pages/shebang.rs diff --git a/tests/rustdoc/source-code-pages/source-code-highlight.rs b/tests/rustdoc-html/source-code-pages/source-code-highlight.rs similarity index 100% rename from tests/rustdoc/source-code-pages/source-code-highlight.rs rename to tests/rustdoc-html/source-code-pages/source-code-highlight.rs diff --git a/tests/rustdoc/source-code-pages/source-file.rs b/tests/rustdoc-html/source-code-pages/source-file.rs similarity index 100% rename from tests/rustdoc/source-code-pages/source-file.rs rename to tests/rustdoc-html/source-code-pages/source-file.rs diff --git a/tests/rustdoc/source-code-pages/source-line-numbers.rs b/tests/rustdoc-html/source-code-pages/source-line-numbers.rs similarity index 100% rename from tests/rustdoc/source-code-pages/source-line-numbers.rs rename to tests/rustdoc-html/source-code-pages/source-line-numbers.rs diff --git a/tests/rustdoc/source-code-pages/source-version-separator.rs b/tests/rustdoc-html/source-code-pages/source-version-separator.rs similarity index 100% rename from tests/rustdoc/source-code-pages/source-version-separator.rs rename to tests/rustdoc-html/source-code-pages/source-version-separator.rs diff --git a/tests/rustdoc/source-code-pages/src-link-external-macro-26606.rs b/tests/rustdoc-html/source-code-pages/src-link-external-macro-26606.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-link-external-macro-26606.rs rename to tests/rustdoc-html/source-code-pages/src-link-external-macro-26606.rs diff --git a/tests/rustdoc/source-code-pages/src-links-auto-impls.rs b/tests/rustdoc-html/source-code-pages/src-links-auto-impls.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links-auto-impls.rs rename to tests/rustdoc-html/source-code-pages/src-links-auto-impls.rs diff --git a/tests/rustdoc/source-code-pages/src-links-external.rs b/tests/rustdoc-html/source-code-pages/src-links-external.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links-external.rs rename to tests/rustdoc-html/source-code-pages/src-links-external.rs diff --git a/tests/rustdoc/source-code-pages/src-links-implementor-43893.rs b/tests/rustdoc-html/source-code-pages/src-links-implementor-43893.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links-implementor-43893.rs rename to tests/rustdoc-html/source-code-pages/src-links-implementor-43893.rs diff --git a/tests/rustdoc/source-code-pages/src-links-inlined-34274.rs b/tests/rustdoc-html/source-code-pages/src-links-inlined-34274.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links-inlined-34274.rs rename to tests/rustdoc-html/source-code-pages/src-links-inlined-34274.rs diff --git a/tests/rustdoc/source-code-pages/src-links.rs b/tests/rustdoc-html/source-code-pages/src-links.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links.rs rename to tests/rustdoc-html/source-code-pages/src-links.rs diff --git a/tests/rustdoc/source-code-pages/src-links/compiletest-ignore-dir b/tests/rustdoc-html/source-code-pages/src-links/compiletest-ignore-dir similarity index 100% rename from tests/rustdoc/source-code-pages/src-links/compiletest-ignore-dir rename to tests/rustdoc-html/source-code-pages/src-links/compiletest-ignore-dir diff --git a/tests/rustdoc/source-code-pages/src-links/fizz.rs b/tests/rustdoc-html/source-code-pages/src-links/fizz.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links/fizz.rs rename to tests/rustdoc-html/source-code-pages/src-links/fizz.rs diff --git a/tests/rustdoc/source-code-pages/src-links/mod.rs b/tests/rustdoc-html/source-code-pages/src-links/mod.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links/mod.rs rename to tests/rustdoc-html/source-code-pages/src-links/mod.rs diff --git a/tests/rustdoc/source-code-pages/src-mod-path-absolute-26995.rs b/tests/rustdoc-html/source-code-pages/src-mod-path-absolute-26995.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-mod-path-absolute-26995.rs rename to tests/rustdoc-html/source-code-pages/src-mod-path-absolute-26995.rs diff --git a/tests/rustdoc/source-code-pages/version-separator-without-source.rs b/tests/rustdoc-html/source-code-pages/version-separator-without-source.rs similarity index 100% rename from tests/rustdoc/source-code-pages/version-separator-without-source.rs rename to tests/rustdoc-html/source-code-pages/version-separator-without-source.rs diff --git a/tests/rustdoc/stability.rs b/tests/rustdoc-html/stability.rs similarity index 100% rename from tests/rustdoc/stability.rs rename to tests/rustdoc-html/stability.rs diff --git a/tests/rustdoc/staged-api-deprecated-unstable-32374.rs b/tests/rustdoc-html/staged-api-deprecated-unstable-32374.rs similarity index 100% rename from tests/rustdoc/staged-api-deprecated-unstable-32374.rs rename to tests/rustdoc-html/staged-api-deprecated-unstable-32374.rs diff --git a/tests/rustdoc/staged-api-feature-issue-27759.rs b/tests/rustdoc-html/staged-api-feature-issue-27759.rs similarity index 100% rename from tests/rustdoc/staged-api-feature-issue-27759.rs rename to tests/rustdoc-html/staged-api-feature-issue-27759.rs diff --git a/tests/rustdoc/static-root-path.rs b/tests/rustdoc-html/static-root-path.rs similarity index 100% rename from tests/rustdoc/static-root-path.rs rename to tests/rustdoc-html/static-root-path.rs diff --git a/tests/rustdoc/static.rs b/tests/rustdoc-html/static.rs similarity index 100% rename from tests/rustdoc/static.rs rename to tests/rustdoc-html/static.rs diff --git a/tests/rustdoc/strip-block-doc-comments-stars.docblock.html b/tests/rustdoc-html/strip-block-doc-comments-stars.docblock.html similarity index 100% rename from tests/rustdoc/strip-block-doc-comments-stars.docblock.html rename to tests/rustdoc-html/strip-block-doc-comments-stars.docblock.html diff --git a/tests/rustdoc/strip-block-doc-comments-stars.rs b/tests/rustdoc-html/strip-block-doc-comments-stars.rs similarity index 100% rename from tests/rustdoc/strip-block-doc-comments-stars.rs rename to tests/rustdoc-html/strip-block-doc-comments-stars.rs diff --git a/tests/rustdoc/strip-priv-imports-pass-27104.rs b/tests/rustdoc-html/strip-priv-imports-pass-27104.rs similarity index 100% rename from tests/rustdoc/strip-priv-imports-pass-27104.rs rename to tests/rustdoc-html/strip-priv-imports-pass-27104.rs diff --git a/tests/rustdoc/struct-arg-pattern.rs b/tests/rustdoc-html/struct-arg-pattern.rs similarity index 100% rename from tests/rustdoc/struct-arg-pattern.rs rename to tests/rustdoc-html/struct-arg-pattern.rs diff --git a/tests/rustdoc/struct-field.rs b/tests/rustdoc-html/struct-field.rs similarity index 100% rename from tests/rustdoc/struct-field.rs rename to tests/rustdoc-html/struct-field.rs diff --git a/tests/rustdoc/structfields.rs b/tests/rustdoc-html/structfields.rs similarity index 100% rename from tests/rustdoc/structfields.rs rename to tests/rustdoc-html/structfields.rs diff --git a/tests/rustdoc/summary-codeblock-31899.rs b/tests/rustdoc-html/summary-codeblock-31899.rs similarity index 100% rename from tests/rustdoc/summary-codeblock-31899.rs rename to tests/rustdoc-html/summary-codeblock-31899.rs diff --git a/tests/rustdoc/summary-header-46377.rs b/tests/rustdoc-html/summary-header-46377.rs similarity index 100% rename from tests/rustdoc/summary-header-46377.rs rename to tests/rustdoc-html/summary-header-46377.rs diff --git a/tests/rustdoc/summary-reference-link-30366.rs b/tests/rustdoc-html/summary-reference-link-30366.rs similarity index 100% rename from tests/rustdoc/summary-reference-link-30366.rs rename to tests/rustdoc-html/summary-reference-link-30366.rs diff --git a/tests/rustdoc/synthetic_auto/auto-trait-lifetimes-56822.rs b/tests/rustdoc-html/synthetic_auto/auto-trait-lifetimes-56822.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/auto-trait-lifetimes-56822.rs rename to tests/rustdoc-html/synthetic_auto/auto-trait-lifetimes-56822.rs diff --git a/tests/rustdoc/synthetic_auto/basic.rs b/tests/rustdoc-html/synthetic_auto/basic.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/basic.rs rename to tests/rustdoc-html/synthetic_auto/basic.rs diff --git a/tests/rustdoc/synthetic_auto/bounds.rs b/tests/rustdoc-html/synthetic_auto/bounds.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/bounds.rs rename to tests/rustdoc-html/synthetic_auto/bounds.rs diff --git a/tests/rustdoc/synthetic_auto/complex.rs b/tests/rustdoc-html/synthetic_auto/complex.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/complex.rs rename to tests/rustdoc-html/synthetic_auto/complex.rs diff --git a/tests/rustdoc/synthetic_auto/crate-local.rs b/tests/rustdoc-html/synthetic_auto/crate-local.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/crate-local.rs rename to tests/rustdoc-html/synthetic_auto/crate-local.rs diff --git a/tests/rustdoc/synthetic_auto/issue-72213-projection-lifetime.rs b/tests/rustdoc-html/synthetic_auto/issue-72213-projection-lifetime.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/issue-72213-projection-lifetime.rs rename to tests/rustdoc-html/synthetic_auto/issue-72213-projection-lifetime.rs diff --git a/tests/rustdoc/synthetic_auto/lifetimes.rs b/tests/rustdoc-html/synthetic_auto/lifetimes.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/lifetimes.rs rename to tests/rustdoc-html/synthetic_auto/lifetimes.rs diff --git a/tests/rustdoc/synthetic_auto/manual.rs b/tests/rustdoc-html/synthetic_auto/manual.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/manual.rs rename to tests/rustdoc-html/synthetic_auto/manual.rs diff --git a/tests/rustdoc/synthetic_auto/negative.rs b/tests/rustdoc-html/synthetic_auto/negative.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/negative.rs rename to tests/rustdoc-html/synthetic_auto/negative.rs diff --git a/tests/rustdoc/synthetic_auto/nested.rs b/tests/rustdoc-html/synthetic_auto/nested.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/nested.rs rename to tests/rustdoc-html/synthetic_auto/nested.rs diff --git a/tests/rustdoc/synthetic_auto/no-redundancy.rs b/tests/rustdoc-html/synthetic_auto/no-redundancy.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/no-redundancy.rs rename to tests/rustdoc-html/synthetic_auto/no-redundancy.rs diff --git a/tests/rustdoc/synthetic_auto/normalize-auto-trait-80233.rs b/tests/rustdoc-html/synthetic_auto/normalize-auto-trait-80233.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/normalize-auto-trait-80233.rs rename to tests/rustdoc-html/synthetic_auto/normalize-auto-trait-80233.rs diff --git a/tests/rustdoc/synthetic_auto/overflow.rs b/tests/rustdoc-html/synthetic_auto/overflow.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/overflow.rs rename to tests/rustdoc-html/synthetic_auto/overflow.rs diff --git a/tests/rustdoc/synthetic_auto/project.rs b/tests/rustdoc-html/synthetic_auto/project.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/project.rs rename to tests/rustdoc-html/synthetic_auto/project.rs diff --git a/tests/rustdoc/synthetic_auto/self-referential.rs b/tests/rustdoc-html/synthetic_auto/self-referential.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/self-referential.rs rename to tests/rustdoc-html/synthetic_auto/self-referential.rs diff --git a/tests/rustdoc/synthetic_auto/send-impl-conditional-60726.rs b/tests/rustdoc-html/synthetic_auto/send-impl-conditional-60726.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/send-impl-conditional-60726.rs rename to tests/rustdoc-html/synthetic_auto/send-impl-conditional-60726.rs diff --git a/tests/rustdoc/synthetic_auto/static-region.rs b/tests/rustdoc-html/synthetic_auto/static-region.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/static-region.rs rename to tests/rustdoc-html/synthetic_auto/static-region.rs diff --git a/tests/rustdoc/synthetic_auto/supertrait-bounds.rs b/tests/rustdoc-html/synthetic_auto/supertrait-bounds.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/supertrait-bounds.rs rename to tests/rustdoc-html/synthetic_auto/supertrait-bounds.rs diff --git a/tests/rustdoc/tab_title.rs b/tests/rustdoc-html/tab_title.rs similarity index 100% rename from tests/rustdoc/tab_title.rs rename to tests/rustdoc-html/tab_title.rs diff --git a/tests/rustdoc/table-in-docblock.rs b/tests/rustdoc-html/table-in-docblock.rs similarity index 100% rename from tests/rustdoc/table-in-docblock.rs rename to tests/rustdoc-html/table-in-docblock.rs diff --git a/tests/rustdoc/target-feature.rs b/tests/rustdoc-html/target-feature.rs similarity index 100% rename from tests/rustdoc/target-feature.rs rename to tests/rustdoc-html/target-feature.rs diff --git a/tests/rustdoc/task-lists.rs b/tests/rustdoc-html/task-lists.rs similarity index 100% rename from tests/rustdoc/task-lists.rs rename to tests/rustdoc-html/task-lists.rs diff --git a/tests/rustdoc/test-lists.rs b/tests/rustdoc-html/test-lists.rs similarity index 100% rename from tests/rustdoc/test-lists.rs rename to tests/rustdoc-html/test-lists.rs diff --git a/tests/rustdoc/test-parens.rs b/tests/rustdoc-html/test-parens.rs similarity index 100% rename from tests/rustdoc/test-parens.rs rename to tests/rustdoc-html/test-parens.rs diff --git a/tests/rustdoc/test-strikethrough.rs b/tests/rustdoc-html/test-strikethrough.rs similarity index 100% rename from tests/rustdoc/test-strikethrough.rs rename to tests/rustdoc-html/test-strikethrough.rs diff --git a/tests/rustdoc/test_option_check/bar.rs b/tests/rustdoc-html/test_option_check/bar.rs similarity index 100% rename from tests/rustdoc/test_option_check/bar.rs rename to tests/rustdoc-html/test_option_check/bar.rs diff --git a/tests/rustdoc/test_option_check/test.rs b/tests/rustdoc-html/test_option_check/test.rs similarity index 100% rename from tests/rustdoc/test_option_check/test.rs rename to tests/rustdoc-html/test_option_check/test.rs diff --git a/tests/rustdoc/thread-local-src.rs b/tests/rustdoc-html/thread-local-src.rs similarity index 100% rename from tests/rustdoc/thread-local-src.rs rename to tests/rustdoc-html/thread-local-src.rs diff --git a/tests/rustdoc/titles.rs b/tests/rustdoc-html/titles.rs similarity index 100% rename from tests/rustdoc/titles.rs rename to tests/rustdoc-html/titles.rs diff --git a/tests/rustdoc/toggle-item-contents.rs b/tests/rustdoc-html/toggle-item-contents.rs similarity index 100% rename from tests/rustdoc/toggle-item-contents.rs rename to tests/rustdoc-html/toggle-item-contents.rs diff --git a/tests/rustdoc/toggle-method.rs b/tests/rustdoc-html/toggle-method.rs similarity index 100% rename from tests/rustdoc/toggle-method.rs rename to tests/rustdoc-html/toggle-method.rs diff --git a/tests/rustdoc/toggle-trait-fn.rs b/tests/rustdoc-html/toggle-trait-fn.rs similarity index 100% rename from tests/rustdoc/toggle-trait-fn.rs rename to tests/rustdoc-html/toggle-trait-fn.rs diff --git a/tests/rustdoc/trait-aliases.rs b/tests/rustdoc-html/trait-aliases.rs similarity index 100% rename from tests/rustdoc/trait-aliases.rs rename to tests/rustdoc-html/trait-aliases.rs diff --git a/tests/rustdoc/trait-item-info.rs b/tests/rustdoc-html/trait-item-info.rs similarity index 100% rename from tests/rustdoc/trait-item-info.rs rename to tests/rustdoc-html/trait-item-info.rs diff --git a/tests/rustdoc/trait-self-link.rs b/tests/rustdoc-html/trait-self-link.rs similarity index 100% rename from tests/rustdoc/trait-self-link.rs rename to tests/rustdoc-html/trait-self-link.rs diff --git a/tests/rustdoc/trait-src-link.rs b/tests/rustdoc-html/trait-src-link.rs similarity index 100% rename from tests/rustdoc/trait-src-link.rs rename to tests/rustdoc-html/trait-src-link.rs diff --git a/tests/rustdoc/trait-visibility.rs b/tests/rustdoc-html/trait-visibility.rs similarity index 100% rename from tests/rustdoc/trait-visibility.rs rename to tests/rustdoc-html/trait-visibility.rs diff --git a/tests/rustdoc/traits-in-bodies.rs b/tests/rustdoc-html/traits-in-bodies.rs similarity index 100% rename from tests/rustdoc/traits-in-bodies.rs rename to tests/rustdoc-html/traits-in-bodies.rs diff --git a/tests/rustdoc/tuple-struct-fields-doc.rs b/tests/rustdoc-html/tuple-struct-fields-doc.rs similarity index 100% rename from tests/rustdoc/tuple-struct-fields-doc.rs rename to tests/rustdoc-html/tuple-struct-fields-doc.rs diff --git a/tests/rustdoc/tuple-struct-where-clause-34928.rs b/tests/rustdoc-html/tuple-struct-where-clause-34928.rs similarity index 100% rename from tests/rustdoc/tuple-struct-where-clause-34928.rs rename to tests/rustdoc-html/tuple-struct-where-clause-34928.rs diff --git a/tests/rustdoc/tuples.link1_i32.html b/tests/rustdoc-html/tuples.link1_i32.html similarity index 100% rename from tests/rustdoc/tuples.link1_i32.html rename to tests/rustdoc-html/tuples.link1_i32.html diff --git a/tests/rustdoc/tuples.link1_t.html b/tests/rustdoc-html/tuples.link1_t.html similarity index 100% rename from tests/rustdoc/tuples.link1_t.html rename to tests/rustdoc-html/tuples.link1_t.html diff --git a/tests/rustdoc/tuples.link2_i32.html b/tests/rustdoc-html/tuples.link2_i32.html similarity index 100% rename from tests/rustdoc/tuples.link2_i32.html rename to tests/rustdoc-html/tuples.link2_i32.html diff --git a/tests/rustdoc/tuples.link2_t.html b/tests/rustdoc-html/tuples.link2_t.html similarity index 100% rename from tests/rustdoc/tuples.link2_t.html rename to tests/rustdoc-html/tuples.link2_t.html diff --git a/tests/rustdoc/tuples.link2_tu.html b/tests/rustdoc-html/tuples.link2_tu.html similarity index 100% rename from tests/rustdoc/tuples.link2_tu.html rename to tests/rustdoc-html/tuples.link2_tu.html diff --git a/tests/rustdoc/tuples.link_unit.html b/tests/rustdoc-html/tuples.link_unit.html similarity index 100% rename from tests/rustdoc/tuples.link_unit.html rename to tests/rustdoc-html/tuples.link_unit.html diff --git a/tests/rustdoc/tuples.rs b/tests/rustdoc-html/tuples.rs similarity index 100% rename from tests/rustdoc/tuples.rs rename to tests/rustdoc-html/tuples.rs diff --git a/tests/rustdoc/type-alias/auxiliary/parent-crate-115718.rs b/tests/rustdoc-html/type-alias/auxiliary/parent-crate-115718.rs similarity index 100% rename from tests/rustdoc/type-alias/auxiliary/parent-crate-115718.rs rename to tests/rustdoc-html/type-alias/auxiliary/parent-crate-115718.rs diff --git a/tests/rustdoc/type-alias/cross-crate-115718.rs b/tests/rustdoc-html/type-alias/cross-crate-115718.rs similarity index 100% rename from tests/rustdoc/type-alias/cross-crate-115718.rs rename to tests/rustdoc-html/type-alias/cross-crate-115718.rs diff --git a/tests/rustdoc/type-alias/deeply-nested-112515.rs b/tests/rustdoc-html/type-alias/deeply-nested-112515.rs similarity index 100% rename from tests/rustdoc/type-alias/deeply-nested-112515.rs rename to tests/rustdoc-html/type-alias/deeply-nested-112515.rs diff --git a/tests/rustdoc/type-alias/deref-32077.rs b/tests/rustdoc-html/type-alias/deref-32077.rs similarity index 100% rename from tests/rustdoc/type-alias/deref-32077.rs rename to tests/rustdoc-html/type-alias/deref-32077.rs diff --git a/tests/rustdoc/type-alias/impl_trait_in_assoc_type.rs b/tests/rustdoc-html/type-alias/impl_trait_in_assoc_type.rs similarity index 100% rename from tests/rustdoc/type-alias/impl_trait_in_assoc_type.rs rename to tests/rustdoc-html/type-alias/impl_trait_in_assoc_type.rs diff --git a/tests/rustdoc/type-alias/primitive-local-link-121106.rs b/tests/rustdoc-html/type-alias/primitive-local-link-121106.rs similarity index 100% rename from tests/rustdoc/type-alias/primitive-local-link-121106.rs rename to tests/rustdoc-html/type-alias/primitive-local-link-121106.rs diff --git a/tests/rustdoc/type-alias/repr.rs b/tests/rustdoc-html/type-alias/repr.rs similarity index 100% rename from tests/rustdoc/type-alias/repr.rs rename to tests/rustdoc-html/type-alias/repr.rs diff --git a/tests/rustdoc/type-alias/same-crate-115718.rs b/tests/rustdoc-html/type-alias/same-crate-115718.rs similarity index 100% rename from tests/rustdoc/type-alias/same-crate-115718.rs rename to tests/rustdoc-html/type-alias/same-crate-115718.rs diff --git a/tests/rustdoc/type-layout-flag-required.rs b/tests/rustdoc-html/type-layout-flag-required.rs similarity index 100% rename from tests/rustdoc/type-layout-flag-required.rs rename to tests/rustdoc-html/type-layout-flag-required.rs diff --git a/tests/rustdoc/type-layout.rs b/tests/rustdoc-html/type-layout.rs similarity index 100% rename from tests/rustdoc/type-layout.rs rename to tests/rustdoc-html/type-layout.rs diff --git a/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs b/tests/rustdoc-html/typedef-inner-variants-lazy_type_alias.rs similarity index 100% rename from tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs rename to tests/rustdoc-html/typedef-inner-variants-lazy_type_alias.rs diff --git a/tests/rustdoc/typedef-inner-variants.rs b/tests/rustdoc-html/typedef-inner-variants.rs similarity index 100% rename from tests/rustdoc/typedef-inner-variants.rs rename to tests/rustdoc-html/typedef-inner-variants.rs diff --git a/tests/rustdoc/typedef.rs b/tests/rustdoc-html/typedef.rs similarity index 100% rename from tests/rustdoc/typedef.rs rename to tests/rustdoc-html/typedef.rs diff --git a/tests/rustdoc/underscore-import-61592.rs b/tests/rustdoc-html/underscore-import-61592.rs similarity index 100% rename from tests/rustdoc/underscore-import-61592.rs rename to tests/rustdoc-html/underscore-import-61592.rs diff --git a/tests/rustdoc/unindent.md b/tests/rustdoc-html/unindent.md similarity index 100% rename from tests/rustdoc/unindent.md rename to tests/rustdoc-html/unindent.md diff --git a/tests/rustdoc/unindent.rs b/tests/rustdoc-html/unindent.rs similarity index 100% rename from tests/rustdoc/unindent.rs rename to tests/rustdoc-html/unindent.rs diff --git a/tests/rustdoc/union-fields-html.rs b/tests/rustdoc-html/union-fields-html.rs similarity index 100% rename from tests/rustdoc/union-fields-html.rs rename to tests/rustdoc-html/union-fields-html.rs diff --git a/tests/rustdoc/union.rs b/tests/rustdoc-html/union.rs similarity index 100% rename from tests/rustdoc/union.rs rename to tests/rustdoc-html/union.rs diff --git a/tests/rustdoc/unit-return.rs b/tests/rustdoc-html/unit-return.rs similarity index 100% rename from tests/rustdoc/unit-return.rs rename to tests/rustdoc-html/unit-return.rs diff --git a/tests/rustdoc/unsafe-binder.rs b/tests/rustdoc-html/unsafe-binder.rs similarity index 100% rename from tests/rustdoc/unsafe-binder.rs rename to tests/rustdoc-html/unsafe-binder.rs diff --git a/tests/rustdoc/use-attr.rs b/tests/rustdoc-html/use-attr.rs similarity index 100% rename from tests/rustdoc/use-attr.rs rename to tests/rustdoc-html/use-attr.rs diff --git a/tests/rustdoc/useless_lifetime_bound.rs b/tests/rustdoc-html/useless_lifetime_bound.rs similarity index 100% rename from tests/rustdoc/useless_lifetime_bound.rs rename to tests/rustdoc-html/useless_lifetime_bound.rs diff --git a/tests/rustdoc/variadic.rs b/tests/rustdoc-html/variadic.rs similarity index 100% rename from tests/rustdoc/variadic.rs rename to tests/rustdoc-html/variadic.rs diff --git a/tests/rustdoc/viewpath-rename.rs b/tests/rustdoc-html/viewpath-rename.rs similarity index 100% rename from tests/rustdoc/viewpath-rename.rs rename to tests/rustdoc-html/viewpath-rename.rs diff --git a/tests/rustdoc/viewpath-self.rs b/tests/rustdoc-html/viewpath-self.rs similarity index 100% rename from tests/rustdoc/viewpath-self.rs rename to tests/rustdoc-html/viewpath-self.rs diff --git a/tests/rustdoc/visibility.rs b/tests/rustdoc-html/visibility.rs similarity index 100% rename from tests/rustdoc/visibility.rs rename to tests/rustdoc-html/visibility.rs diff --git a/tests/rustdoc/where-clause-order.rs b/tests/rustdoc-html/where-clause-order.rs similarity index 100% rename from tests/rustdoc/where-clause-order.rs rename to tests/rustdoc-html/where-clause-order.rs diff --git a/tests/rustdoc/where-sized.rs b/tests/rustdoc-html/where-sized.rs similarity index 100% rename from tests/rustdoc/where-sized.rs rename to tests/rustdoc-html/where-sized.rs diff --git a/tests/rustdoc/where.SWhere_Echo_impl.html b/tests/rustdoc-html/where.SWhere_Echo_impl.html similarity index 100% rename from tests/rustdoc/where.SWhere_Echo_impl.html rename to tests/rustdoc-html/where.SWhere_Echo_impl.html diff --git a/tests/rustdoc/where.SWhere_Simd_item-decl.html b/tests/rustdoc-html/where.SWhere_Simd_item-decl.html similarity index 100% rename from tests/rustdoc/where.SWhere_Simd_item-decl.html rename to tests/rustdoc-html/where.SWhere_Simd_item-decl.html diff --git a/tests/rustdoc/where.SWhere_TraitWhere_item-decl.html b/tests/rustdoc-html/where.SWhere_TraitWhere_item-decl.html similarity index 100% rename from tests/rustdoc/where.SWhere_TraitWhere_item-decl.html rename to tests/rustdoc-html/where.SWhere_TraitWhere_item-decl.html diff --git a/tests/rustdoc/where.alpha_trait_decl.html b/tests/rustdoc-html/where.alpha_trait_decl.html similarity index 100% rename from tests/rustdoc/where.alpha_trait_decl.html rename to tests/rustdoc-html/where.alpha_trait_decl.html diff --git a/tests/rustdoc/where.bravo_trait_decl.html b/tests/rustdoc-html/where.bravo_trait_decl.html similarity index 100% rename from tests/rustdoc/where.bravo_trait_decl.html rename to tests/rustdoc-html/where.bravo_trait_decl.html diff --git a/tests/rustdoc/where.charlie_fn_decl.html b/tests/rustdoc-html/where.charlie_fn_decl.html similarity index 100% rename from tests/rustdoc/where.charlie_fn_decl.html rename to tests/rustdoc-html/where.charlie_fn_decl.html diff --git a/tests/rustdoc/where.golf_type_alias_decl.html b/tests/rustdoc-html/where.golf_type_alias_decl.html similarity index 100% rename from tests/rustdoc/where.golf_type_alias_decl.html rename to tests/rustdoc-html/where.golf_type_alias_decl.html diff --git a/tests/rustdoc/where.rs b/tests/rustdoc-html/where.rs similarity index 100% rename from tests/rustdoc/where.rs rename to tests/rustdoc-html/where.rs diff --git a/tests/rustdoc/whitespace-after-where-clause.enum.html b/tests/rustdoc-html/whitespace-after-where-clause.enum.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.enum.html rename to tests/rustdoc-html/whitespace-after-where-clause.enum.html diff --git a/tests/rustdoc/whitespace-after-where-clause.enum2.html b/tests/rustdoc-html/whitespace-after-where-clause.enum2.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.enum2.html rename to tests/rustdoc-html/whitespace-after-where-clause.enum2.html diff --git a/tests/rustdoc/whitespace-after-where-clause.rs b/tests/rustdoc-html/whitespace-after-where-clause.rs similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.rs rename to tests/rustdoc-html/whitespace-after-where-clause.rs diff --git a/tests/rustdoc/whitespace-after-where-clause.struct.html b/tests/rustdoc-html/whitespace-after-where-clause.struct.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.struct.html rename to tests/rustdoc-html/whitespace-after-where-clause.struct.html diff --git a/tests/rustdoc/whitespace-after-where-clause.struct2.html b/tests/rustdoc-html/whitespace-after-where-clause.struct2.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.struct2.html rename to tests/rustdoc-html/whitespace-after-where-clause.struct2.html diff --git a/tests/rustdoc/whitespace-after-where-clause.trait.html b/tests/rustdoc-html/whitespace-after-where-clause.trait.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.trait.html rename to tests/rustdoc-html/whitespace-after-where-clause.trait.html diff --git a/tests/rustdoc/whitespace-after-where-clause.trait2.html b/tests/rustdoc-html/whitespace-after-where-clause.trait2.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.trait2.html rename to tests/rustdoc-html/whitespace-after-where-clause.trait2.html diff --git a/tests/rustdoc/whitespace-after-where-clause.union.html b/tests/rustdoc-html/whitespace-after-where-clause.union.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.union.html rename to tests/rustdoc-html/whitespace-after-where-clause.union.html diff --git a/tests/rustdoc/whitespace-after-where-clause.union2.html b/tests/rustdoc-html/whitespace-after-where-clause.union2.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.union2.html rename to tests/rustdoc-html/whitespace-after-where-clause.union2.html diff --git a/tests/rustdoc/without-redirect.rs b/tests/rustdoc-html/without-redirect.rs similarity index 100% rename from tests/rustdoc/without-redirect.rs rename to tests/rustdoc-html/without-redirect.rs diff --git a/tests/rustdoc/wrapping.rs b/tests/rustdoc-html/wrapping.rs similarity index 100% rename from tests/rustdoc/wrapping.rs rename to tests/rustdoc-html/wrapping.rs diff --git a/triagebot.toml b/triagebot.toml index fbb2bac2267b..4c3e5c2a5931 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -240,7 +240,7 @@ trigger_files = [ "src/rustdoc-json-types", # Tests - "tests/rustdoc", + "tests/rustdoc-html", "tests/rustdoc-ui", "tests/rustdoc-gui", "tests/rustdoc-js/", @@ -315,7 +315,7 @@ trigger_labels = [ ] trigger_files = [ "src/librustdoc/html/", - "tests/rustdoc/", + "tests/rustdoc-html/", "tests/rustdoc-gui/", "tests/rustdoc-js/", "tests/rustdoc-js-std/", @@ -1638,7 +1638,7 @@ dep-bumps = [ "/src/stage0" = ["bootstrap"] "/tests/run-make" = ["compiler"] "/tests/run-make-cargo" = ["compiler"] -"/tests/rustdoc" = ["rustdoc"] +"/tests/rustdoc-html" = ["rustdoc"] "/tests/rustdoc-gui" = ["rustdoc"] "/tests/rustdoc-js-std" = ["rustdoc"] "/tests/rustdoc-js/" = ["rustdoc"] From 8256623ab478ff8d79f3b0305e002acdb6cbb76d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 3 Jan 2026 16:06:28 +0100 Subject: [PATCH 1676/3801] Update `rustc-dev-guide` about `tests/rustdoc` renamed into `tests/rustdoc-html` --- src/doc/rustc-dev-guide/src/SUMMARY.md | 2 +- .../{rustdoc-test-suite.md => rustdoc-html-test-suite.md} | 4 ++-- .../src/rustdoc-internals/rustdoc-json-test-suite.md | 2 +- src/doc/rustc-dev-guide/src/tests/compiletest.md | 4 ++-- src/doc/rustc-dev-guide/src/tests/directives.md | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) rename src/doc/rustc-dev-guide/src/rustdoc-internals/{rustdoc-test-suite.md => rustdoc-html-test-suite.md} (98%) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index e80ee6a5137d..2dd07144a78c 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -100,7 +100,7 @@ - [Parallel compilation](./parallel-rustc.md) - [Rustdoc internals](./rustdoc-internals.md) - [Search](./rustdoc-internals/search.md) - - [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md) + - [The `rustdoc-html` test suite](./rustdoc-internals/rustdoc-html-test-suite.md) - [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md) - [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md) - [GPU offload internals](./offload/internals.md) diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-html-test-suite.md similarity index 98% rename from src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md rename to src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-html-test-suite.md index 9516968df803..b74405d310eb 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-html-test-suite.md @@ -1,6 +1,6 @@ -# The `rustdoc` test suite +# The `rustdoc-html` test suite -This page is about the test suite named `rustdoc` used to test the HTML output of `rustdoc`. +This page is about the test suite named `rustdoc-html` used to test the HTML output of `rustdoc`. For other rustdoc-specific test suites, see [Rustdoc test suites]. Each test file in this test suite is simply a Rust source file `file.rs` sprinkled with diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md index 5781a12ca44c..7a846b711326 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md @@ -24,7 +24,7 @@ Also, talk about how it works ## jsondocck [jsondocck] processes directives given in comments, to assert that the values in the output are expected. -It's a lot like [htmldocck](./rustdoc-test-suite.md) in that way. +It's a lot like [htmldocck](./rustdoc-html-test-suite.md) in that way. It uses [JSONPath] as a query language, which takes a path, and returns a *list* of values that that path is said to match to. diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index e0924f8538ef..d69e0a5ce988 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -82,7 +82,7 @@ The following test suites are available, with links for more information: | Test suite | Purpose | |--------------------------------------|--------------------------------------------------------------------------| -| [`rustdoc`][rustdoc-html-tests] | Check HTML output of `rustdoc` | +| [`rustdoc-html`][rustdoc-html-tests] | Check HTML output of `rustdoc` | | [`rustdoc-gui`][rustdoc-gui-tests] | Check `rustdoc`'s GUI using a web browser | | [`rustdoc-js`][rustdoc-js-tests] | Check `rustdoc`'s search engine and index | | [`rustdoc-js-std`][rustdoc-js-tests] | Check `rustdoc`'s search engine and index on the std library docs | @@ -94,7 +94,7 @@ These tests ensure that certain lints that are emitted as part of executing rust are also run when executing rustc. Run-make tests pertaining to rustdoc are typically named `run-make/rustdoc-*/`. -[rustdoc-html-tests]: ../rustdoc-internals/rustdoc-test-suite.md +[rustdoc-html-tests]: ../rustdoc-internals/rustdoc-html-test-suite.md [rustdoc-gui-tests]: ../rustdoc-internals/rustdoc-gui-test-suite.md [rustdoc-js-tests]: ../rustdoc-internals/search.md#testing-the-search-engine [rustdoc-json-tests]: ../rustdoc-internals/rustdoc-json-test-suite.md diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 4852c3623b05..52e1f09dca0f 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -308,12 +308,12 @@ Asked in #### Test-suite-specific directives -The test suites [`rustdoc`][rustdoc-html-tests], [`rustdoc-js`/`rustdoc-js-std`][rustdoc-js-tests] +The test suites [`rustdoc-html`][rustdoc-html-tests], [`rustdoc-js`/`rustdoc-js-std`][rustdoc-js-tests] and [`rustdoc-json`][rustdoc-json-tests] each feature an additional set of directives whose basic syntax resembles the one of compiletest directives but which are ultimately read and checked by separate tools. For more information, please read their respective chapters as linked above. -[rustdoc-html-tests]: ../rustdoc-internals/rustdoc-test-suite.md +[rustdoc-html-tests]: ../rustdoc-internals/rustdoc-html-test-suite.md [rustdoc-js-tests]: ../rustdoc-internals/search.html#testing-the-search-engine [rustdoc-json-tests]: ../rustdoc-internals/rustdoc-json-test-suite.md From 3d965bdc282a4a45cf2d5f83794cbe68a316bf60 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 7 Jan 2026 13:15:17 +0000 Subject: [PATCH 1677/3801] Convert static lifetime to an nll var --- compiler/rustc_borrowck/src/type_check/mod.rs | 10 ++++++++-- ...-to-ptr-unsized-adt-tail-with-static-region.rs | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 097416b4f280..e5aad4cdbd06 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1581,12 +1581,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { .unwrap(); } (None, None) => { + // `struct_tail` returns regions which haven't been mapped + // to nll vars yet so we do it here as `outlives_constraints` + // expects nll vars. + let src_lt = self.universal_regions.to_region_vid(src_lt); + let dst_lt = self.universal_regions.to_region_vid(dst_lt); + // The principalless (no non-auto traits) case: // You can only cast `dyn Send + 'long` to `dyn Send + 'short`. self.constraints.outlives_constraints.push( OutlivesConstraint { - sup: src_lt.as_var(), - sub: dst_lt.as_var(), + sup: src_lt, + sub: dst_lt, locations: location.to_locations(), span: location.to_locations().span(self.body), category: ConstraintCategory::Cast { diff --git a/tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs b/tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs new file mode 100644 index 000000000000..7319a670c881 --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs @@ -0,0 +1,15 @@ +//@ check-pass + +// During MIR typeck when casting `*mut dyn Sync + '?x` to +// `*mut Wrap` we compute the tail of `Wrap` as `dyn Sync + 'static`. +// +// This test ensures that we first convert the `'static` lifetime to +// the nll var `'?0` before introducing the region constraint `'?x: 'static`. + +struct Wrap(dyn Sync + 'static); + +fn cast(x: *mut (dyn Sync + 'static)) { + x as *mut Wrap; +} + +fn main() {} From 87195e7a2a5046153ad6b718aa562a862d562ed6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 6 Jan 2026 23:30:40 +0300 Subject: [PATCH 1678/3801] resolve: Do not query edition too eagerly in `visit_scopes` --- compiler/rustc_resolve/src/ident.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index e0acf043ffcf..cc05f35b327f 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -50,7 +50,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { mut self: CmResolver<'r, 'ra, 'tcx>, scope_set: ScopeSet<'ra>, parent_scope: &ParentScope<'ra>, - ctxt: SyntaxContext, + orig_ctxt: SyntaxContext, derive_fallback_lint_id: Option, mut visitor: impl FnMut( &mut CmResolver<'r, 'ra, 'tcx>, @@ -100,7 +100,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // 4c. Standard library prelude (de-facto closed, controlled). // 6. Language prelude: builtin attributes (closed, controlled). - let rust_2015 = ctxt.edition().is_rust_2015(); let (ns, macro_kind) = match scope_set { ScopeSet::All(ns) | ScopeSet::Module(ns, _) @@ -123,7 +122,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None), MacroNS => Scope::DeriveHelpers(parent_scope.expansion), }; - let mut ctxt = ctxt.normalize_to_macros_2_0(); + let mut ctxt = orig_ctxt.normalize_to_macros_2_0(); let mut use_prelude = !module.no_implicit_prelude; loop { @@ -148,7 +147,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { true } Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..) => true, - Scope::MacroUsePrelude => use_prelude || rust_2015, + Scope::MacroUsePrelude => use_prelude || orig_ctxt.edition().is_rust_2015(), Scope::BuiltinAttrs => true, Scope::ExternPreludeItems | Scope::ExternPreludeFlags => { use_prelude || module_and_extern_prelude || extern_prelude From adbdf8dbf04593bcdadf2edda98c6284eef5d295 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Wed, 7 Jan 2026 14:02:09 +0000 Subject: [PATCH 1679/3801] Allow invoking all help options at once --- compiler/rustc_driver_impl/src/lib.rs | 92 ++++++++++++++++++++++----- compiler/rustc_session/src/options.rs | 2 + 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 7820198f2dcf..81d25a307bdd 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -228,8 +228,10 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) let args = args::arg_expand_all(&default_early_dcx, at_args); - let Some(matches) = handle_options(&default_early_dcx, &args) else { - return; + let (matches, help_only) = match handle_options(&default_early_dcx, &args) { + HandledOptions::None => return, + HandledOptions::Normal(matches) => (matches, false), + HandledOptions::HelpOnly(matches) => (matches, true), }; let sopts = config::build_session_options(&mut default_early_dcx, &matches); @@ -291,6 +293,11 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) return early_exit(); } + // We have now handled all help options, exit + if help_only { + return early_exit(); + } + if print_crate_info(codegen_backend, sess, has_input) == Compilation::Stop { return early_exit(); } @@ -1092,7 +1099,7 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) -> // Don't handle -W help here, because we might first load additional lints. let debug_flags = matches.opt_strs("Z"); if debug_flags.iter().any(|x| *x == "help") { - describe_debug_flags(); + describe_unstable_flags(); return true; } @@ -1131,8 +1138,8 @@ fn get_backend_from_raw_matches( get_codegen_backend(early_dcx, &sysroot, backend_name, &target) } -fn describe_debug_flags() { - safe_println!("\nAvailable options:\n"); +fn describe_unstable_flags() { + safe_println!("\nAvailable unstable options:\n"); print_flag_list("-Z", config::Z_OPTIONS); } @@ -1156,6 +1163,16 @@ fn print_flag_list(cmdline_opt: &str, flag_list: &[OptionDesc]) { } } +pub enum HandledOptions { + /// Parsing failed, or we parsed a flag causing an early exit + None, + /// Successful parsing + Normal(getopts::Matches), + /// Parsing succeeded, but we received one or more 'help' flags + /// The compiler should proceed only until a possible `-W help` flag has been processed + HelpOnly(getopts::Matches), +} + /// Process command line options. Emits messages as appropriate. If compilation /// should continue, returns a getopts::Matches object parsed from args, /// otherwise returns `None`. @@ -1183,7 +1200,7 @@ fn print_flag_list(cmdline_opt: &str, flag_list: &[OptionDesc]) { /// This does not need to be `pub` for rustc itself, but @chaosite needs it to /// be public when using rustc as a library, see /// -pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option { +pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> HandledOptions { // Parse with *all* options defined in the compiler, we don't worry about // option stability here we just want to parse as much as possible. let mut options = getopts::Options::new(); @@ -1229,26 +1246,69 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option bool { + let opt_pos = |opt| matches.opt_positions(opt).first().copied(); + let opt_help_pos = |opt| { + matches + .opt_strs_pos(opt) + .iter() + .filter_map(|(pos, oval)| if oval == "help" { Some(*pos) } else { None }) + .next() + }; + let help_pos = if args.is_empty() { Some(0) } else { opt_pos("h").or_else(|| opt_pos("help")) }; + let zhelp_pos = opt_help_pos("Z"); + let chelp_pos = opt_help_pos("C"); + let print_help = || { + // Only show unstable options in --help if we accept unstable options. + let unstable_enabled = nightly_options::is_unstable_enabled(&matches); + let nightly_build = nightly_options::match_is_nightly_build(&matches); + usage(matches.opt_present("verbose"), unstable_enabled, nightly_build); + }; + + let mut helps = [ + (help_pos, &print_help as &dyn Fn()), + (zhelp_pos, &describe_unstable_flags), + (chelp_pos, &describe_codegen_flags), + ]; + helps.sort_by_key(|(pos, _)| pos.clone()); + let mut printed_any = false; + for printer in helps.iter().filter_map(|(pos, func)| pos.is_some().then_some(func)) { + printer(); + printed_any = true; + } + printed_any } /// Warn if `-o` is used without a space between the flag name and the value diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 21fa3321a30a..0a29d45457d5 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2125,6 +2125,7 @@ options! { #[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")] force_unwind_tables: Option = (None, parse_opt_bool, [TRACKED], "force use of unwind tables"), + help: bool = (false, parse_no_value, [UNTRACKED], "Print codegen options"), incremental: Option = (None, parse_opt_string, [UNTRACKED], "enable incremental compilation"), #[rustc_lint_opt_deny_field_access("documented to do nothing")] @@ -2395,6 +2396,7 @@ options! { environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"), has_thread_local: Option = (None, parse_opt_bool, [TRACKED], "explicitly enable the `cfg(target_thread_local)` directive"), + help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"), higher_ranked_assumptions: bool = (false, parse_bool, [TRACKED], "allow deducing higher-ranked outlives assumptions from coroutines when proving auto traits"), hint_mostly_unused: bool = (false, parse_bool, [TRACKED], From 12007736ac5dc0a4020464ace43409ec6280f2b6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 7 Jan 2026 00:08:18 +0300 Subject: [PATCH 1680/3801] resolve: Use `Macros20NormalizedIdent` in more interfaces It allows to avoid expensive double normalization in some cases --- .../rustc_resolve/src/build_reduced_graph.rs | 26 ++++++++-------- compiler/rustc_resolve/src/diagnostics.rs | 6 ++-- compiler/rustc_resolve/src/ident.rs | 26 ++++++++-------- compiler/rustc_resolve/src/imports.rs | 20 ++++++------- compiler/rustc_resolve/src/late.rs | 8 +++-- compiler/rustc_resolve/src/lib.rs | 30 +++++++++++-------- compiler/rustc_resolve/src/macros.rs | 17 +++++------ 7 files changed, 69 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index d56ca7c079cb..ac0f388009d6 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -49,13 +49,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn plant_decl_into_local_module( &mut self, parent: Module<'ra>, - ident: Ident, + ident: Macros20NormalizedIdent, ns: Namespace, decl: Decl<'ra>, ) { if let Err(old_decl) = self.try_plant_decl_into_local_module(parent, ident, ns, decl, false) { - self.report_conflict(parent, ident, ns, old_decl, decl); + self.report_conflict(parent, ident.0, ns, old_decl, decl); } } @@ -71,6 +71,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { expn_id: LocalExpnId, ) { let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id); + let ident = Macros20NormalizedIdent::new(ident); self.plant_decl_into_local_module(parent, ident, ns, decl); } @@ -78,7 +79,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn define_extern( &self, parent: Module<'ra>, - ident: Ident, + ident: Macros20NormalizedIdent, ns: Namespace, child_index: usize, res: Res, @@ -280,6 +281,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) }; let ModChild { ident, res, vis, ref reexport_chain } = *child; + let ident = Macros20NormalizedIdent::new(ident); let span = child_span(self, reexport_chain, res); let res = res.expect_non_local(); let expansion = parent_scope.expansion; @@ -532,7 +534,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if target.name != kw::Underscore { self.r.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { - let key = BindingKey::new(target, ns); + let key = BindingKey::new(Macros20NormalizedIdent::new(target), ns); this.resolution_or_default(current_module, key) .borrow_mut(this) .single_imports @@ -1023,11 +1025,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } self.r.potentially_unused_imports.push(import); let import_decl = self.r.new_import_decl(decl, import); + let ident = Macros20NormalizedIdent::new(ident); if ident.name != kw::Underscore && parent == self.r.graph_root { - let norm_ident = Macros20NormalizedIdent::new(ident); // FIXME: this error is technically unnecessary now when extern prelude is split into // two scopes, remove it with lang team approval. - if let Some(entry) = self.r.extern_prelude.get(&norm_ident) + if let Some(entry) = self.r.extern_prelude.get(&ident) && expansion != LocalExpnId::ROOT && orig_name.is_some() && entry.item_decl.is_none() @@ -1038,7 +1040,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } use indexmap::map::Entry; - match self.r.extern_prelude.entry(norm_ident) { + match self.r.extern_prelude.entry(ident) { Entry::Occupied(mut occupied) => { let entry = occupied.get_mut(); if entry.item_decl.is_some() { @@ -1290,8 +1292,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { self.r.local_macro_def_scopes.insert(def_id, parent_scope.module); if macro_rules { - let ident = ident.normalize_to_macros_2_0(); - self.r.macro_names.insert(ident); + let ident = Macros20NormalizedIdent::new(ident); + self.r.macro_names.insert(ident.0); let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export); let vis = if is_macro_export { Visibility::Public @@ -1320,8 +1322,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let import_decl = self.r.new_import_decl(decl, import); self.r.plant_decl_into_local_module(self.r.graph_root, ident, MacroNS, import_decl); } else { - self.r.check_reserved_macro_name(ident, res); - self.insert_unused_macro(ident, def_id, item.id); + self.r.check_reserved_macro_name(ident.0, res); + self.insert_unused_macro(ident.0, def_id, item.id); } self.r.feed_visibility(feed, vis); let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Def( @@ -1488,7 +1490,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { { // Don't add underscore names, they cannot be looked up anyway. let impl_def_id = self.r.tcx.local_parent(local_def_id); - let key = BindingKey::new(ident, ns); + let key = BindingKey::new(Macros20NormalizedIdent::new(ident), ns); self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7c86ed91a07a..71444770ae37 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1187,7 +1187,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .get(&expn_id) .into_iter() .flatten() - .map(|(ident, _)| TypoSuggestion::typo_from_ident(*ident, res)), + .map(|(ident, _)| TypoSuggestion::typo_from_ident(ident.0, res)), ); } } @@ -1199,7 +1199,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let res = macro_rules_def.decl.res(); if filter_fn(res) { suggestions - .push(TypoSuggestion::typo_from_ident(macro_rules_def.ident, res)) + .push(TypoSuggestion::typo_from_ident(macro_rules_def.ident.0, res)) } } } @@ -2892,7 +2892,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return None; } - let binding_key = BindingKey::new(ident, MacroNS); + let binding_key = BindingKey::new(Macros20NormalizedIdent::new(ident), MacroNS); let binding = self.resolution(crate_module, binding_key)?.binding()?; let Res::Def(DefKind::Macro(kinds), _) = binding.res() else { return None; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index cc05f35b327f..811f48925f51 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -9,7 +9,7 @@ use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK; use rustc_session::parse::feature_err; use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext}; -use rustc_span::{Ident, Span, kw, sym}; +use rustc_span::{Ident, Macros20NormalizedIdent, Span, kw, sym}; use tracing::{debug, instrument}; use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; @@ -519,7 +519,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ignore_decl: Option>, ignore_import: Option>, ) -> Result, ControlFlow> { - let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); + let unnorm_ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); + let ident = Macros20NormalizedIdent::new(unnorm_ident); let ret = match scope { Scope::DeriveHelpers(expn_id) => { if let Some(decl) = self @@ -602,7 +603,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { errors::ProcMacroDeriveResolutionFallback { span: orig_ident.span, ns_descr: ns.descr(), - ident, + ident: unnorm_ident, }, ); } @@ -652,7 +653,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { errors::ProcMacroDeriveResolutionFallback { span: orig_ident.span, ns_descr: ns.descr(), - ident, + ident: unnorm_ident, }, ); } @@ -698,7 +699,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut result = Err(Determinacy::Determined); if let Some(prelude) = self.prelude && let Ok(decl) = self.reborrow().resolve_ident_in_scope_set( - ident, + unnorm_ident, ScopeSet::Module(ns, prelude), parent_scope, None, @@ -982,7 +983,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn resolve_ident_in_module_non_globs_unadjusted<'r>( mut self: CmResolver<'r, 'ra, 'tcx>, module: Module<'ra>, - ident: Ident, + ident: Macros20NormalizedIdent, ns: Namespace, parent_scope: &ParentScope<'ra>, shadowing: Shadowing, @@ -1005,7 +1006,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some(finalize) = finalize { return self.get_mut().finalize_module_binding( - ident, + ident.0, binding, parent_scope, module, @@ -1045,7 +1046,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn resolve_ident_in_module_globs_unadjusted<'r>( mut self: CmResolver<'r, 'ra, 'tcx>, module: Module<'ra>, - ident: Ident, + ident: Macros20NormalizedIdent, ns: Namespace, parent_scope: &ParentScope<'ra>, shadowing: Shadowing, @@ -1066,7 +1067,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some(finalize) = finalize { return self.get_mut().finalize_module_binding( - ident, + ident.0, binding, parent_scope, module, @@ -1135,9 +1136,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None => return Err(ControlFlow::Continue(Undetermined)), }; let tmp_parent_scope; - let (mut adjusted_parent_scope, mut ident) = - (parent_scope, ident.normalize_to_macros_2_0()); - match ident.span.glob_adjust(module.expansion, glob_import.span) { + let (mut adjusted_parent_scope, mut ident) = (parent_scope, ident); + match ident.0.span.glob_adjust(module.expansion, glob_import.span) { Some(Some(def)) => { tmp_parent_scope = ParentScope { module: self.expn_def_scope(def), ..*parent_scope }; @@ -1147,7 +1147,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None => continue, }; let result = self.reborrow().resolve_ident_in_scope_set( - ident, + ident.0, ScopeSet::Module(ns, module), adjusted_parent_scope, None, diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index a8bb53cc7f27..30e980afadec 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -20,7 +20,7 @@ use rustc_session::lint::builtin::{ use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::LocalExpnId; -use rustc_span::{Ident, Span, Symbol, kw, sym}; +use rustc_span::{Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym}; use tracing::debug; use crate::Namespace::{self, *}; @@ -330,13 +330,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn try_plant_decl_into_local_module( &mut self, module: Module<'ra>, - ident: Ident, + ident: Macros20NormalizedIdent, ns: Namespace, decl: Decl<'ra>, warn_ambiguity: bool, ) -> Result<(), Decl<'ra>> { let res = decl.res(); - self.check_reserved_macro_name(ident, res); + self.check_reserved_macro_name(ident.0, res); self.set_decl_parent_module(decl, module); // Even if underscore names cannot be looked up, we still need to add them to modules, // because they can be fetched by glob imports from those modules, and bring traits @@ -474,7 +474,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let import_decl = self.new_import_decl(binding, *import); let _ = self.try_plant_decl_into_local_module( import.parent_scope.module, - ident.0, + ident, key.ns, import_decl, warn_ambiguity, @@ -496,11 +496,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let dummy_decl = self.new_import_decl(dummy_decl, import); self.per_ns(|this, ns| { let module = import.parent_scope.module; - let _ = - this.try_plant_decl_into_local_module(module, target, ns, dummy_decl, false); + let ident = Macros20NormalizedIdent::new(target); + let _ = this.try_plant_decl_into_local_module(module, ident, ns, dummy_decl, false); // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { - let key = BindingKey::new(target, ns); + let key = BindingKey::new(ident, ns); this.update_local_resolution(module, key, false, |_, resolution| { resolution.single_imports.swap_remove(&import); }) @@ -879,7 +879,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let import_decl = this.new_import_decl(binding, import); this.get_mut_unchecked().plant_decl_into_local_module( parent, - target, + Macros20NormalizedIdent::new(target), ns, import_decl, ); @@ -888,7 +888,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Err(Determinacy::Determined) => { // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { - let key = BindingKey::new(target, ns); + let key = BindingKey::new(Macros20NormalizedIdent::new(target), ns); this.get_mut_unchecked().update_local_resolution( parent, key, @@ -1504,7 +1504,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .is_some_and(|binding| binding.warn_ambiguity_recursive()); let _ = self.try_plant_decl_into_local_module( import.parent_scope.module, - key.ident.0, + key.ident, key.ns, import_decl, warn_ambiguity, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b4941a6f5b99..33344c64ebc7 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -37,7 +37,9 @@ use rustc_session::config::{CrateType, ResolveDocLinks}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::source_map::{Spanned, respan}; -use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, SyntaxContext, kw, sym}; +use rustc_span::{ + BytePos, DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, SyntaxContext, kw, sym, +}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; @@ -3629,7 +3631,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { return; }; ident.span.normalize_to_macros_2_0_and_adjust(module.expansion); - let key = BindingKey::new(ident, ns); + let key = BindingKey::new(Macros20NormalizedIdent::new(ident), ns); let mut decl = self.r.resolution(module, key).and_then(|r| r.best_decl()); debug!(?decl); if decl.is_none() { @@ -3640,7 +3642,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { TypeNS => ValueNS, _ => ns, }; - let key = BindingKey::new(ident, ns); + let key = BindingKey::new(Macros20NormalizedIdent::new(ident), ns); decl = self.r.resolution(module, key).and_then(|r| r.best_decl()); debug!(?decl); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 063b6b4058f0..36afcb455f23 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -572,17 +572,17 @@ struct BindingKey { } impl BindingKey { - fn new(ident: Ident, ns: Namespace) -> Self { - BindingKey { ident: Macros20NormalizedIdent::new(ident), ns, disambiguator: 0 } + fn new(ident: Macros20NormalizedIdent, ns: Namespace) -> Self { + BindingKey { ident, ns, disambiguator: 0 } } fn new_disambiguated( - ident: Ident, + ident: Macros20NormalizedIdent, ns: Namespace, disambiguator: impl FnOnce() -> u32, ) -> BindingKey { let disambiguator = if ident.name == kw::Underscore { disambiguator() } else { 0 }; - BindingKey { ident: Macros20NormalizedIdent::new(ident), ns, disambiguator } + BindingKey { ident, ns, disambiguator } } } @@ -1076,7 +1076,7 @@ impl ExternPreludeEntry<'_> { struct DeriveData { resolutions: Vec, - helper_attrs: Vec<(usize, Ident)>, + helper_attrs: Vec<(usize, Macros20NormalizedIdent)>, has_derive_copy: bool, } @@ -1241,7 +1241,7 @@ pub struct Resolver<'ra, 'tcx> { /// `macro_rules` scopes produced by `macro_rules` item definitions. macro_rules_scopes: FxHashMap>, /// Helper attributes that are in scope for the given expansion. - helper_attrs: FxHashMap)>>, + helper_attrs: FxHashMap)>>, /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute /// with the given `ExpnId`. derive_data: FxHashMap, @@ -2251,20 +2251,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn extern_prelude_get_item<'r>( mut self: CmResolver<'r, 'ra, 'tcx>, - ident: Ident, + ident: Macros20NormalizedIdent, finalize: bool, ) -> Option> { - let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)); - entry.and_then(|entry| entry.item_decl).map(|(binding, _)| { + let entry = self.extern_prelude.get(&ident); + entry.and_then(|entry| entry.item_decl).map(|(decl, _)| { if finalize { - self.get_mut().record_use(ident, binding, Used::Scope); + self.get_mut().record_use(ident.0, decl, Used::Scope); } - binding + decl }) } - fn extern_prelude_get_flag(&self, ident: Ident, finalize: bool) -> Option> { - let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)); + fn extern_prelude_get_flag( + &self, + ident: Macros20NormalizedIdent, + finalize: bool, + ) -> Option> { + let entry = self.extern_prelude.get(&ident); entry.and_then(|entry| entry.flag_decl.as_ref()).and_then(|flag_decl| { let (pending_decl, finalized) = flag_decl.get(); let decl = match pending_decl { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index c9c754374c87..32d686d4f702 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -29,7 +29,7 @@ use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; -use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; +use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym}; use crate::Namespace::*; use crate::errors::{ @@ -52,7 +52,7 @@ pub(crate) struct MacroRulesDecl<'ra> { pub(crate) decl: Decl<'ra>, /// `macro_rules` scope into which the `macro_rules` item was planted. pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'ra>, - pub(crate) ident: Ident, + pub(crate) ident: Macros20NormalizedIdent, } /// The scope introduced by a `macro_rules!` macro. @@ -403,13 +403,10 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { ) { Ok((Some(ext), _)) => { if !ext.helper_attrs.is_empty() { - let last_seg = resolution.path.segments.last().unwrap(); - let span = last_seg.ident.span.normalize_to_macros_2_0(); - entry.helper_attrs.extend( - ext.helper_attrs - .iter() - .map(|name| (i, Ident::new(*name, span))), - ); + let span = resolution.path.segments.last().unwrap().ident.span; + entry.helper_attrs.extend(ext.helper_attrs.iter().map(|name| { + (i, Macros20NormalizedIdent::new(Ident::new(*name, span))) + })); } entry.has_derive_copy |= ext.builtin_name == Some(sym::Copy); ext @@ -530,7 +527,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { target_trait.for_each_child(self, |this, ident, ns, _binding| { // FIXME: Adjust hygiene for idents from globs, like for glob imports. if let Some(overriding_keys) = this.impl_binding_keys.get(&impl_def_id) - && overriding_keys.contains(&BindingKey::new(ident.0, ns)) + && overriding_keys.contains(&BindingKey::new(ident, ns)) { // The name is overridden, do not produce it from the glob delegation. } else { From 888e28b41b05e2b27f7ba530e1f330dbe852de92 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 7 Jan 2026 01:17:11 +0300 Subject: [PATCH 1681/3801] resolve: Pass a normalized ident to `resolve_ident_in_scope` In practice it was already normalized because `visit_scopes` normalized it --- compiler/rustc_resolve/src/ident.rs | 25 ++++++++++++------------- tests/ui/proc-macro/generate-mod.stderr | 10 ---------- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 811f48925f51..8baf194e4a06 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -433,12 +433,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { orig_ident.span.ctxt(), derive_fallback_lint_id, |this, scope, use_prelude, ctxt| { + let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); + // The passed `ctxt` is already normalized, so avoid expensive double normalization. + let ident = Macros20NormalizedIdent(ident); let res = match this.reborrow().resolve_ident_in_scope( - orig_ident, + ident, ns, scope, use_prelude, - ctxt, scope_set, parent_scope, // Shadowed decls don't need to be marked as used or non-speculatively loaded. @@ -507,11 +509,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn resolve_ident_in_scope<'r>( mut self: CmResolver<'r, 'ra, 'tcx>, - orig_ident: Ident, + ident: Macros20NormalizedIdent, ns: Namespace, scope: Scope<'ra>, use_prelude: UsePrelude, - ctxt: SyntaxContext, scope_set: ScopeSet<'ra>, parent_scope: &ParentScope<'ra>, finalize: Option, @@ -519,8 +520,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ignore_decl: Option>, ignore_import: Option>, ) -> Result, ControlFlow> { - let unnorm_ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); - let ident = Macros20NormalizedIdent::new(unnorm_ident); let ret = match scope { Scope::DeriveHelpers(expn_id) => { if let Some(decl) = self @@ -599,11 +598,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.get_mut().lint_buffer.buffer_lint( PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, lint_id, - orig_ident.span, + ident.span, errors::ProcMacroDeriveResolutionFallback { - span: orig_ident.span, + span: ident.span, ns_descr: ns.descr(), - ident: unnorm_ident, + ident: ident.0, }, ); } @@ -649,11 +648,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.get_mut().lint_buffer.buffer_lint( PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, lint_id, - orig_ident.span, + ident.span, errors::ProcMacroDeriveResolutionFallback { - span: orig_ident.span, + span: ident.span, ns_descr: ns.descr(), - ident: unnorm_ident, + ident: ident.0, }, ); } @@ -699,7 +698,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut result = Err(Determinacy::Determined); if let Some(prelude) = self.prelude && let Ok(decl) = self.reborrow().resolve_ident_in_scope_set( - unnorm_ident, + ident.0, ScopeSet::Module(ns, prelude), parent_scope, None, diff --git a/tests/ui/proc-macro/generate-mod.stderr b/tests/ui/proc-macro/generate-mod.stderr index af90df2c3dc3..371fd73e507b 100644 --- a/tests/ui/proc-macro/generate-mod.stderr +++ b/tests/ui/proc-macro/generate-mod.stderr @@ -47,7 +47,6 @@ LL | #[derive(generate_mod::CheckDerive)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 = note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find type `OuterDerive` in this scope --> $DIR/generate-mod.rs:18:10 @@ -57,7 +56,6 @@ LL | #[derive(generate_mod::CheckDerive)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:25:14 @@ -67,7 +65,6 @@ LL | #[derive(generate_mod::CheckDerive)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find type `OuterDerive` in this scope --> $DIR/generate-mod.rs:25:14 @@ -77,7 +74,6 @@ LL | #[derive(generate_mod::CheckDerive)] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 8 previous errors @@ -92,7 +88,6 @@ LL | #[derive(generate_mod::CheckDerive)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 = note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: error: cannot find type `OuterDerive` in this scope @@ -104,7 +99,6 @@ LL | #[derive(generate_mod::CheckDerive)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 = note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: error: cannot find type `FromOutside` in this scope @@ -116,7 +110,6 @@ LL | #[derive(generate_mod::CheckDerive)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 = note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: error: cannot find type `OuterDerive` in this scope @@ -128,7 +121,6 @@ LL | #[derive(generate_mod::CheckDerive)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 = note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default - = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: warning: cannot find type `FromOutside` in this scope @@ -139,7 +131,6 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 - = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: warning: cannot find type `OuterDeriveLint` in this scope @@ -150,5 +141,4 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 - = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) From 99a7d285d46474e10bb854dccee73484916e3fb7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 7 Jan 2026 17:10:57 +0300 Subject: [PATCH 1682/3801] resolve: Avoid most allocations in `resolve_ident_in_scope_set` Also evaluate one cheap and often-false condition first --- compiler/rustc_resolve/src/ident.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 8baf194e4a06..6ed99042a43f 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -10,6 +10,7 @@ use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK; use rustc_session::parse::feature_err; use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext}; use rustc_span::{Ident, Macros20NormalizedIdent, Span, kw, sym}; +use smallvec::SmallVec; use tracing::{debug, instrument}; use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; @@ -396,7 +397,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { assert!(force || finalize.is_none()); // `finalize` implies `force` // Make sure `self`, `super` etc produce an error when passed to here. - if orig_ident.is_path_segment_keyword() && !matches!(scope_set, ScopeSet::Module(..)) { + if !matches!(scope_set, ScopeSet::Module(..)) && orig_ident.is_path_segment_keyword() { return Err(Determinacy::Determined); } @@ -423,7 +424,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // } // So we have to save the innermost solution and continue searching in outer scopes // to detect potential ambiguities. - let mut innermost_results: Vec<(Decl<'_>, Scope<'_>)> = Vec::new(); + let mut innermost_results: SmallVec<[(Decl<'_>, Scope<'_>); 2]> = SmallVec::new(); let mut determinacy = Determinacy::Determined; // Go through all the scopes and try to resolve the name. From 9c4ead681480427806416cb09ea1f667bd6052b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 7 Jan 2026 16:44:51 +0100 Subject: [PATCH 1683/3801] Remove legacy homu `try` and `auto` branch mentions --- .github/workflows/ci.yml | 19 +++++++++---------- src/ci/citool/src/main.rs | 6 ++---- src/ci/scripts/verify-channel.sh | 3 +-- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb6bc325a3bb..5d26d617ba88 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,11 +11,9 @@ name: CI on: push: branches: - - auto - - try - - try-perf - - automation/bors/try - automation/bors/auto + - automation/bors/try + - try-perf pull_request: branches: - "**" @@ -33,9 +31,10 @@ defaults: concurrency: # For a given workflow, if we push to the same branch, cancel all previous builds on that branch. - # We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which - # are all triggered on the same branch, but which should be able to run concurrently. - group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try') && github.sha) || github.ref }} + # We add an exception for try builds (automation/bors/try branch) and unrolled rollup builds + # (try-perf), which are all triggered on the same branch, but which should be able to run + # concurrently. + group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try') && github.sha) || github.ref }} cancel-in-progress: true env: TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" @@ -57,7 +56,7 @@ jobs: - name: Test citool # Only test citool on the auto branch, to reduce latency of the calculate matrix job # on PR/try builds. - if: ${{ github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto' }} + if: ${{ github.ref == 'refs/heads/automation/bors/auto' }} run: | cd src/ci/citool CARGO_INCREMENTAL=0 cargo test @@ -80,7 +79,7 @@ jobs: # access the environment. # # We only enable the environment for the rust-lang/rust repository, so that CI works on forks. - environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} + environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} env: CI_JOB_NAME: ${{ matrix.name }} CI_JOB_DOC_URL: ${{ matrix.doc_url }} @@ -314,7 +313,7 @@ jobs: needs: [ calculate_matrix, job ] # !cancelled() executes the job regardless of whether the previous jobs passed or failed if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }} - environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} + environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} steps: - name: checkout the source code uses: actions/checkout@v5 diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index d7b491d38f41..01c0650b3c98 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -41,14 +41,12 @@ impl GitHubContext { match (self.event_name.as_str(), self.branch_ref.as_str()) { ("pull_request", _) => Some(RunType::PullRequest), ("push", "refs/heads/try-perf") => Some(RunType::TryJob { job_patterns: None }), - ("push", "refs/heads/try" | "refs/heads/automation/bors/try") => { + ("push", "refs/heads/automation/bors/try") => { let patterns = self.get_try_job_patterns(); let patterns = if !patterns.is_empty() { Some(patterns) } else { None }; Some(RunType::TryJob { job_patterns: patterns }) } - ("push", "refs/heads/auto" | "refs/heads/automation/bors/auto") => { - Some(RunType::AutoJob) - } + ("push", "refs/heads/automation/bors/auto") => Some(RunType::AutoJob), ("push", "refs/heads/main") => Some(RunType::MainJob), _ => None, } diff --git a/src/ci/scripts/verify-channel.sh b/src/ci/scripts/verify-channel.sh index cac8ba332ed1..286869e8a411 100755 --- a/src/ci/scripts/verify-channel.sh +++ b/src/ci/scripts/verify-channel.sh @@ -8,8 +8,7 @@ IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" -if isCiBranch auto || isCiBranch try || isCiBranch try-perf || \ - isCiBranch automation/bors/try || isCiBranch automation/bors/auto; then +if isCiBranch try-perf || isCiBranch automation/bors/try || isCiBranch automation/bors/auto; then echo "channel verification is only executed on PR builds" exit fi From 4909fd8c7732ffa7d9641dc200b1010a2614c30f Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Wed, 7 Jan 2026 16:53:05 +0000 Subject: [PATCH 1684/3801] Add tests for invoking multiple help options at once --- tests/run-make/rustc-help/rmake.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/run-make/rustc-help/rmake.rs b/tests/run-make/rustc-help/rmake.rs index 85e90e6352d0..3569cba3fcce 100644 --- a/tests/run-make/rustc-help/rmake.rs +++ b/tests/run-make/rustc-help/rmake.rs @@ -18,4 +18,31 @@ fn main() { // Check the diff between `rustc --help` and `rustc --help -v`. let help_v_diff = similar::TextDiff::from_lines(&help, &help_v).unified_diff().to_string(); diff().expected_file("help-v.diff").actual_text("actual", &help_v_diff).run(); + + // Check that all help options can be invoked at once + let codegen_help = bare_rustc().arg("-Chelp").run().stdout_utf8(); + let unstable_help = bare_rustc().arg("-Zhelp").run().stdout_utf8(); + let lints_help = bare_rustc().arg("-Whelp").run().stdout_utf8(); + let expected_all = format!("{help}{codegen_help}{unstable_help}{lints_help}"); + let all_help = bare_rustc().args(["--help", "-Chelp", "-Zhelp", "-Whelp"]).run().stdout_utf8(); + diff() + .expected_text( + "(rustc --help && rustc -Chelp && rustc -Zhelp && rustc -Whelp)", + &expected_all, + ) + .actual_text("(rustc --help -Chelp -Zhelp -Whelp)", &all_help) + .run(); + + // Check that the ordering of help options is respected + // Note that this is except for `-Whelp`, which always comes last + let expected_ordered_help = format!("{unstable_help}{codegen_help}{help}{lints_help}"); + let ordered_help = + bare_rustc().args(["-Whelp", "-Zhelp", "-Chelp", "--help"]).run().stdout_utf8(); + diff() + .expected_text( + "(rustc -Whelp && rustc -Zhelp && rustc -Chelp && rustc --help)", + &expected_ordered_help, + ) + .actual_text("(rustc -Whelp -Zhelp -Chelp --help)", &ordered_help) + .run(); } From e834e60987288843436e7d44bb784cb297475dc0 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Wed, 7 Jan 2026 16:55:37 +0000 Subject: [PATCH 1685/3801] Test behavior of `--help --invalid-flag` --- tests/run-make/rustc-help/rmake.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/run-make/rustc-help/rmake.rs b/tests/run-make/rustc-help/rmake.rs index 3569cba3fcce..17811ef18449 100644 --- a/tests/run-make/rustc-help/rmake.rs +++ b/tests/run-make/rustc-help/rmake.rs @@ -45,4 +45,7 @@ fn main() { ) .actual_text("(rustc -Whelp -Zhelp -Chelp --help)", &ordered_help) .run(); + + // Test that `rustc --help` does not suppress invalid flag errors + let help = bare_rustc().arg("--help --invalid-flag").run_fail().stdout_utf8(); } From 7630884c55c77baf3cb399b67146f1f5bd5b18df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Tue, 6 Jan 2026 20:01:25 +0100 Subject: [PATCH 1686/3801] Avoid `unsafe fn` in remaining x86 tests --- .../stdarch/crates/core_arch/src/x86/avx.rs | 231 +++-- .../stdarch/crates/core_arch/src/x86/avx2.rs | 374 ++++--- .../crates/core_arch/src/x86/avx512bf16.rs | 279 ++--- .../crates/core_arch/src/x86/avx512bw.rs | 314 +++--- .../crates/core_arch/src/x86/avx512dq.rs | 52 +- .../crates/core_arch/src/x86/avx512f.rs | 966 +++++++++++------- .../crates/core_arch/src/x86/avx512fp16.rs | 99 +- .../crates/core_arch/src/x86/avx512vbmi2.rs | 124 ++- .../crates/core_arch/src/x86/avxneconvert.rs | 56 +- .../stdarch/crates/core_arch/src/x86/f16c.rs | 2 +- .../stdarch/crates/core_arch/src/x86/fxsr.rs | 10 +- .../stdarch/crates/core_arch/src/x86/gfni.rs | 210 ++-- .../stdarch/crates/core_arch/src/x86/kl.rs | 88 +- .../stdarch/crates/core_arch/src/x86/rtm.rs | 34 +- .../stdarch/crates/core_arch/src/x86/sse.rs | 60 +- .../stdarch/crates/core_arch/src/x86/sse2.rs | 178 ++-- .../stdarch/crates/core_arch/src/x86/sse3.rs | 8 +- .../stdarch/crates/core_arch/src/x86/sse41.rs | 12 +- .../stdarch/crates/core_arch/src/x86/sse42.rs | 3 +- .../stdarch/crates/core_arch/src/x86/sse4a.rs | 12 +- .../stdarch/crates/core_arch/src/x86/xsave.rs | 36 +- .../crates/core_arch/src/x86_64/amx.rs | 854 ++++++++-------- .../crates/core_arch/src/x86_64/avx512f.rs | 659 +++++++----- .../crates/core_arch/src/x86_64/fxsr.rs | 10 +- .../crates/core_arch/src/x86_64/sse2.rs | 6 +- .../crates/core_arch/src/x86_64/xsave.rs | 30 +- 26 files changed, 2691 insertions(+), 2016 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx.rs b/library/stdarch/crates/core_arch/src/x86/avx.rs index e0e01ae6d034..c406d537bc1c 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx.rs @@ -3369,6 +3369,7 @@ unsafe extern "C" { #[cfg(test)] mod tests { use crate::core_arch::assert_eq_const as assert_eq; + use crate::core_arch::simd::*; use crate::hint::black_box; use crate::ptr; use stdarch_test::simd_test; @@ -3464,7 +3465,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_max_pd() { + fn test_mm256_max_pd() { let a = _mm256_setr_pd(1., 4., 5., 8.); let b = _mm256_setr_pd(2., 3., 6., 7.); let r = _mm256_max_pd(a, b); @@ -3474,23 +3475,22 @@ mod tests { // > value in the second operand (source operand) is returned. let w = _mm256_max_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(-0.0)); let x = _mm256_max_pd(_mm256_set1_pd(-0.0), _mm256_set1_pd(0.0)); - let wu: [u64; 4] = transmute(w); - let xu: [u64; 4] = transmute(x); - assert_eq!(wu, [0x8000_0000_0000_0000u64; 4]); - assert_eq!(xu, [0u64; 4]); + let wu = _mm256_castpd_si256(w).as_u64x4(); + let xu = _mm256_castpd_si256(x).as_u64x4(); + assert_eq!(wu, u64x4::splat(0x8000_0000_0000_0000u64)); + assert_eq!(xu, u64x4::splat(0u64)); // > If only one value is a NaN (SNaN or QNaN) for this instruction, the // > second operand (source operand), either a NaN or a valid // > floating-point value, is written to the result. let y = _mm256_max_pd(_mm256_set1_pd(f64::NAN), _mm256_set1_pd(0.0)); let z = _mm256_max_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(f64::NAN)); - let yf: [f64; 4] = transmute(y); - let zf: [f64; 4] = transmute(z); - assert_eq!(yf, [0.0; 4]); + assert_eq_m256d(y, _mm256_set1_pd(0.0)); + let zf = *z.as_f64x4().as_array(); assert!(zf.iter().all(|f| f.is_nan()), "{:?}", zf); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_max_ps() { + fn test_mm256_max_ps() { let a = _mm256_setr_ps(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm256_setr_ps(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm256_max_ps(a, b); @@ -3500,23 +3500,22 @@ mod tests { // > value in the second operand (source operand) is returned. let w = _mm256_max_ps(_mm256_set1_ps(0.0), _mm256_set1_ps(-0.0)); let x = _mm256_max_ps(_mm256_set1_ps(-0.0), _mm256_set1_ps(0.0)); - let wu: [u32; 8] = transmute(w); - let xu: [u32; 8] = transmute(x); - assert_eq!(wu, [0x8000_0000u32; 8]); - assert_eq!(xu, [0u32; 8]); + let wu = _mm256_castps_si256(w).as_u32x8(); + let xu = _mm256_castps_si256(x).as_u32x8(); + assert_eq!(wu, u32x8::splat(0x8000_0000u32)); + assert_eq!(xu, u32x8::splat(0u32)); // > If only one value is a NaN (SNaN or QNaN) for this instruction, the // > second operand (source operand), either a NaN or a valid // > floating-point value, is written to the result. let y = _mm256_max_ps(_mm256_set1_ps(f32::NAN), _mm256_set1_ps(0.0)); let z = _mm256_max_ps(_mm256_set1_ps(0.0), _mm256_set1_ps(f32::NAN)); - let yf: [f32; 8] = transmute(y); - let zf: [f32; 8] = transmute(z); - assert_eq!(yf, [0.0; 8]); + assert_eq_m256(y, _mm256_set1_ps(0.0)); + let zf = *z.as_f32x8().as_array(); assert!(zf.iter().all(|f| f.is_nan()), "{:?}", zf); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_min_pd() { + fn test_mm256_min_pd() { let a = _mm256_setr_pd(1., 4., 5., 8.); let b = _mm256_setr_pd(2., 3., 6., 7.); let r = _mm256_min_pd(a, b); @@ -3526,23 +3525,22 @@ mod tests { // > value in the second operand (source operand) is returned. let w = _mm256_min_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(-0.0)); let x = _mm256_min_pd(_mm256_set1_pd(-0.0), _mm256_set1_pd(0.0)); - let wu: [u64; 4] = transmute(w); - let xu: [u64; 4] = transmute(x); - assert_eq!(wu, [0x8000_0000_0000_0000u64; 4]); - assert_eq!(xu, [0u64; 4]); + let wu = _mm256_castpd_si256(w).as_u64x4(); + let xu = _mm256_castpd_si256(x).as_u64x4(); + assert_eq!(wu, u64x4::splat(0x8000_0000_0000_0000u64)); + assert_eq!(xu, u64x4::splat(0u64)); // > If only one value is a NaN (SNaN or QNaN) for this instruction, the // > second operand (source operand), either a NaN or a valid // > floating-point value, is written to the result. let y = _mm256_min_pd(_mm256_set1_pd(f64::NAN), _mm256_set1_pd(0.0)); let z = _mm256_min_pd(_mm256_set1_pd(0.0), _mm256_set1_pd(f64::NAN)); - let yf: [f64; 4] = transmute(y); - let zf: [f64; 4] = transmute(z); - assert_eq!(yf, [0.0; 4]); + assert_eq_m256d(y, _mm256_set1_pd(0.0)); + let zf = *z.as_f64x4().as_array(); assert!(zf.iter().all(|f| f.is_nan()), "{:?}", zf); } #[simd_test(enable = "avx")] - unsafe fn test_mm256_min_ps() { + fn test_mm256_min_ps() { let a = _mm256_setr_ps(1., 4., 5., 8., 9., 12., 13., 16.); let b = _mm256_setr_ps(2., 3., 6., 7., 10., 11., 14., 15.); let r = _mm256_min_ps(a, b); @@ -3552,18 +3550,17 @@ mod tests { // > value in the second operand (source operand) is returned. let w = _mm256_min_ps(_mm256_set1_ps(0.0), _mm256_set1_ps(-0.0)); let x = _mm256_min_ps(_mm256_set1_ps(-0.0), _mm256_set1_ps(0.0)); - let wu: [u32; 8] = transmute(w); - let xu: [u32; 8] = transmute(x); - assert_eq!(wu, [0x8000_0000u32; 8]); - assert_eq!(xu, [0u32; 8]); + let wu = _mm256_castps_si256(w).as_u32x8(); + let xu = _mm256_castps_si256(x).as_u32x8(); + assert_eq!(wu, u32x8::splat(0x8000_0000u32)); + assert_eq!(xu, u32x8::splat(0u32)); // > If only one value is a NaN (SNaN or QNaN) for this instruction, the // > second operand (source operand), either a NaN or a valid // > floating-point value, is written to the result. let y = _mm256_min_ps(_mm256_set1_ps(f32::NAN), _mm256_set1_ps(0.0)); let z = _mm256_min_ps(_mm256_set1_ps(0.0), _mm256_set1_ps(f32::NAN)); - let yf: [f32; 8] = transmute(y); - let zf: [f32; 8] = transmute(z); - assert_eq!(yf, [0.0; 8]); + assert_eq_m256(y, _mm256_set1_ps(0.0)); + let zf = *z.as_f32x8().as_array(); assert!(zf.iter().all(|f| f.is_nan()), "{:?}", zf); } @@ -4247,183 +4244,203 @@ mod tests { } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_load_pd() { + const fn test_mm256_load_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let p = ptr::addr_of!(a) as *const f64; - let r = _mm256_load_pd(p); + let r = unsafe { _mm256_load_pd(p) }; let e = _mm256_setr_pd(1., 2., 3., 4.); assert_eq_m256d(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_store_pd() { + const fn test_mm256_store_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let mut r = _mm256_undefined_pd(); - _mm256_store_pd(ptr::addr_of_mut!(r) as *mut f64, a); + unsafe { + _mm256_store_pd(ptr::addr_of_mut!(r) as *mut f64, a); + } assert_eq_m256d(r, a); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_load_ps() { + const fn test_mm256_load_ps() { let a = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let p = ptr::addr_of!(a) as *const f32; - let r = _mm256_load_ps(p); + let r = unsafe { _mm256_load_ps(p) }; let e = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); assert_eq_m256(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_store_ps() { + const fn test_mm256_store_ps() { let a = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); let mut r = _mm256_undefined_ps(); - _mm256_store_ps(ptr::addr_of_mut!(r) as *mut f32, a); + unsafe { + _mm256_store_ps(ptr::addr_of_mut!(r) as *mut f32, a); + } assert_eq_m256(r, a); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_loadu_pd() { + const fn test_mm256_loadu_pd() { let a = &[1.0f64, 2., 3., 4.]; let p = a.as_ptr(); - let r = _mm256_loadu_pd(black_box(p)); + let r = unsafe { _mm256_loadu_pd(black_box(p)) }; let e = _mm256_setr_pd(1., 2., 3., 4.); assert_eq_m256d(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_storeu_pd() { + const fn test_mm256_storeu_pd() { let a = _mm256_set1_pd(9.); let mut r = _mm256_undefined_pd(); - _mm256_storeu_pd(ptr::addr_of_mut!(r) as *mut f64, a); + unsafe { + _mm256_storeu_pd(ptr::addr_of_mut!(r) as *mut f64, a); + } assert_eq_m256d(r, a); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_loadu_ps() { + const fn test_mm256_loadu_ps() { let a = &[4., 3., 2., 5., 8., 9., 64., 50.]; let p = a.as_ptr(); - let r = _mm256_loadu_ps(black_box(p)); + let r = unsafe { _mm256_loadu_ps(black_box(p)) }; let e = _mm256_setr_ps(4., 3., 2., 5., 8., 9., 64., 50.); assert_eq_m256(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_storeu_ps() { + const fn test_mm256_storeu_ps() { let a = _mm256_set1_ps(9.); let mut r = _mm256_undefined_ps(); - _mm256_storeu_ps(ptr::addr_of_mut!(r) as *mut f32, a); + unsafe { + _mm256_storeu_ps(ptr::addr_of_mut!(r) as *mut f32, a); + } assert_eq_m256(r, a); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_load_si256() { + const fn test_mm256_load_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let p = ptr::addr_of!(a); - let r = _mm256_load_si256(p); + let r = unsafe { _mm256_load_si256(p) }; let e = _mm256_setr_epi64x(1, 2, 3, 4); assert_eq_m256i(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_store_si256() { + const fn test_mm256_store_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let mut r = _mm256_undefined_si256(); - _mm256_store_si256(ptr::addr_of_mut!(r), a); + unsafe { + _mm256_store_si256(ptr::addr_of_mut!(r), a); + } assert_eq_m256i(r, a); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_loadu_si256() { + const fn test_mm256_loadu_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let p = ptr::addr_of!(a); - let r = _mm256_loadu_si256(black_box(p)); + let r = unsafe { _mm256_loadu_si256(black_box(p)) }; let e = _mm256_setr_epi64x(1, 2, 3, 4); assert_eq_m256i(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_storeu_si256() { + const fn test_mm256_storeu_si256() { let a = _mm256_set1_epi8(9); let mut r = _mm256_undefined_si256(); - _mm256_storeu_si256(ptr::addr_of_mut!(r), a); + unsafe { + _mm256_storeu_si256(ptr::addr_of_mut!(r), a); + } assert_eq_m256i(r, a); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_maskload_pd() { + const fn test_mm256_maskload_pd() { let a = &[1.0f64, 2., 3., 4.]; let p = a.as_ptr(); let mask = _mm256_setr_epi64x(0, !0, 0, !0); - let r = _mm256_maskload_pd(black_box(p), mask); + let r = unsafe { _mm256_maskload_pd(black_box(p), mask) }; let e = _mm256_setr_pd(0., 2., 0., 4.); assert_eq_m256d(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_maskstore_pd() { + const fn test_mm256_maskstore_pd() { let mut r = _mm256_set1_pd(0.); let mask = _mm256_setr_epi64x(0, !0, 0, !0); let a = _mm256_setr_pd(1., 2., 3., 4.); - _mm256_maskstore_pd(ptr::addr_of_mut!(r) as *mut f64, mask, a); + unsafe { + _mm256_maskstore_pd(ptr::addr_of_mut!(r) as *mut f64, mask, a); + } let e = _mm256_setr_pd(0., 2., 0., 4.); assert_eq_m256d(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm_maskload_pd() { + const fn test_mm_maskload_pd() { let a = &[1.0f64, 2.]; let p = a.as_ptr(); let mask = _mm_setr_epi64x(0, !0); - let r = _mm_maskload_pd(black_box(p), mask); + let r = unsafe { _mm_maskload_pd(black_box(p), mask) }; let e = _mm_setr_pd(0., 2.); assert_eq_m128d(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm_maskstore_pd() { + const fn test_mm_maskstore_pd() { let mut r = _mm_set1_pd(0.); let mask = _mm_setr_epi64x(0, !0); let a = _mm_setr_pd(1., 2.); - _mm_maskstore_pd(ptr::addr_of_mut!(r) as *mut f64, mask, a); + unsafe { + _mm_maskstore_pd(ptr::addr_of_mut!(r) as *mut f64, mask, a); + } let e = _mm_setr_pd(0., 2.); assert_eq_m128d(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_maskload_ps() { + const fn test_mm256_maskload_ps() { let a = &[1.0f32, 2., 3., 4., 5., 6., 7., 8.]; let p = a.as_ptr(); let mask = _mm256_setr_epi32(0, !0, 0, !0, 0, !0, 0, !0); - let r = _mm256_maskload_ps(black_box(p), mask); + let r = unsafe { _mm256_maskload_ps(black_box(p), mask) }; let e = _mm256_setr_ps(0., 2., 0., 4., 0., 6., 0., 8.); assert_eq_m256(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_maskstore_ps() { + const fn test_mm256_maskstore_ps() { let mut r = _mm256_set1_ps(0.); let mask = _mm256_setr_epi32(0, !0, 0, !0, 0, !0, 0, !0); let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); - _mm256_maskstore_ps(ptr::addr_of_mut!(r) as *mut f32, mask, a); + unsafe { + _mm256_maskstore_ps(ptr::addr_of_mut!(r) as *mut f32, mask, a); + } let e = _mm256_setr_ps(0., 2., 0., 4., 0., 6., 0., 8.); assert_eq_m256(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm_maskload_ps() { + const fn test_mm_maskload_ps() { let a = &[1.0f32, 2., 3., 4.]; let p = a.as_ptr(); let mask = _mm_setr_epi32(0, !0, 0, !0); - let r = _mm_maskload_ps(black_box(p), mask); + let r = unsafe { _mm_maskload_ps(black_box(p), mask) }; let e = _mm_setr_ps(0., 2., 0., 4.); assert_eq_m128(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm_maskstore_ps() { + const fn test_mm_maskstore_ps() { let mut r = _mm_set1_ps(0.); let mask = _mm_setr_epi32(0, !0, 0, !0); let a = _mm_setr_ps(1., 2., 3., 4.); - _mm_maskstore_ps(ptr::addr_of_mut!(r) as *mut f32, mask, a); + unsafe { + _mm_maskstore_ps(ptr::addr_of_mut!(r) as *mut f32, mask, a); + } let e = _mm_setr_ps(0., 2., 0., 4.); assert_eq_m128(r, e); } @@ -4453,7 +4470,7 @@ mod tests { } #[simd_test(enable = "avx")] - unsafe fn test_mm256_lddqu_si256() { + fn test_mm256_lddqu_si256() { #[rustfmt::skip] let a = _mm256_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -4462,7 +4479,7 @@ mod tests { 25, 26, 27, 28, 29, 30, 31, 32, ); let p = ptr::addr_of!(a); - let r = _mm256_lddqu_si256(black_box(p)); + let r = unsafe { _mm256_lddqu_si256(black_box(p)) }; #[rustfmt::skip] let e = _mm256_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -4475,17 +4492,19 @@ mod tests { #[simd_test(enable = "avx")] #[cfg_attr(miri, ignore)] // Non-temporal store, which is not supported by Miri - unsafe fn test_mm256_stream_si256() { + fn test_mm256_stream_si256() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let mut r = _mm256_undefined_si256(); - _mm256_stream_si256(ptr::addr_of_mut!(r), a); + unsafe { + _mm256_stream_si256(ptr::addr_of_mut!(r), a); + } _mm_sfence(); assert_eq_m256i(r, a); } #[simd_test(enable = "avx")] #[cfg_attr(miri, ignore)] // Non-temporal store, which is not supported by Miri - unsafe fn test_mm256_stream_pd() { + fn test_mm256_stream_pd() { #[repr(align(32))] struct Memory { pub data: [f64; 4], @@ -4493,7 +4512,9 @@ mod tests { let a = _mm256_set1_pd(7.0); let mut mem = Memory { data: [-1.0; 4] }; - _mm256_stream_pd(ptr::addr_of_mut!(mem.data[0]), a); + unsafe { + _mm256_stream_pd(ptr::addr_of_mut!(mem.data[0]), a); + } _mm_sfence(); for i in 0..4 { assert_eq!(mem.data[i], get_m256d(a, i)); @@ -4502,7 +4523,7 @@ mod tests { #[simd_test(enable = "avx")] #[cfg_attr(miri, ignore)] // Non-temporal store, which is not supported by Miri - unsafe fn test_mm256_stream_ps() { + fn test_mm256_stream_ps() { #[repr(align(32))] struct Memory { pub data: [f32; 8], @@ -4510,7 +4531,9 @@ mod tests { let a = _mm256_set1_ps(7.0); let mut mem = Memory { data: [-1.0; 8] }; - _mm256_stream_ps(ptr::addr_of_mut!(mem.data[0]), a); + unsafe { + _mm256_stream_ps(ptr::addr_of_mut!(mem.data[0]), a); + } _mm_sfence(); for i in 0..8 { assert_eq!(mem.data[i], get_m256(a, i)); @@ -5147,29 +5170,29 @@ mod tests { } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_loadu2_m128() { + const fn test_mm256_loadu2_m128() { let hi = &[5., 6., 7., 8.]; let hiaddr = hi.as_ptr(); let lo = &[1., 2., 3., 4.]; let loaddr = lo.as_ptr(); - let r = _mm256_loadu2_m128(hiaddr, loaddr); + let r = unsafe { _mm256_loadu2_m128(hiaddr, loaddr) }; let e = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); assert_eq_m256(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_loadu2_m128d() { + const fn test_mm256_loadu2_m128d() { let hi = &[3., 4.]; let hiaddr = hi.as_ptr(); let lo = &[1., 2.]; let loaddr = lo.as_ptr(); - let r = _mm256_loadu2_m128d(hiaddr, loaddr); + let r = unsafe { _mm256_loadu2_m128d(hiaddr, loaddr) }; let e = _mm256_setr_pd(1., 2., 3., 4.); assert_eq_m256d(r, e); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_loadu2_m128i() { + const fn test_mm256_loadu2_m128i() { #[rustfmt::skip] let hi = _mm_setr_epi8( 17, 18, 19, 20, 21, 22, 23, 24, @@ -5180,7 +5203,9 @@ mod tests { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ); - let r = _mm256_loadu2_m128i(ptr::addr_of!(hi) as *const _, ptr::addr_of!(lo) as *const _); + let r = unsafe { + _mm256_loadu2_m128i(ptr::addr_of!(hi) as *const _, ptr::addr_of!(lo) as *const _) + }; #[rustfmt::skip] let e = _mm256_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -5192,35 +5217,39 @@ mod tests { } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_storeu2_m128() { + const fn test_mm256_storeu2_m128() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); let mut hi = _mm_undefined_ps(); let mut lo = _mm_undefined_ps(); - _mm256_storeu2_m128( - ptr::addr_of_mut!(hi) as *mut f32, - ptr::addr_of_mut!(lo) as *mut f32, - a, - ); + unsafe { + _mm256_storeu2_m128( + ptr::addr_of_mut!(hi) as *mut f32, + ptr::addr_of_mut!(lo) as *mut f32, + a, + ); + } assert_eq_m128(hi, _mm_setr_ps(5., 6., 7., 8.)); assert_eq_m128(lo, _mm_setr_ps(1., 2., 3., 4.)); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_storeu2_m128d() { + const fn test_mm256_storeu2_m128d() { let a = _mm256_setr_pd(1., 2., 3., 4.); let mut hi = _mm_undefined_pd(); let mut lo = _mm_undefined_pd(); - _mm256_storeu2_m128d( - ptr::addr_of_mut!(hi) as *mut f64, - ptr::addr_of_mut!(lo) as *mut f64, - a, - ); + unsafe { + _mm256_storeu2_m128d( + ptr::addr_of_mut!(hi) as *mut f64, + ptr::addr_of_mut!(lo) as *mut f64, + a, + ); + } assert_eq_m128d(hi, _mm_setr_pd(3., 4.)); assert_eq_m128d(lo, _mm_setr_pd(1., 2.)); } #[simd_test(enable = "avx")] - const unsafe fn test_mm256_storeu2_m128i() { + const fn test_mm256_storeu2_m128i() { #[rustfmt::skip] let a = _mm256_setr_epi8( 1, 2, 3, 4, 5, 6, 7, 8, @@ -5230,7 +5259,9 @@ mod tests { ); let mut hi = _mm_undefined_si128(); let mut lo = _mm_undefined_si128(); - _mm256_storeu2_m128i(ptr::addr_of_mut!(hi), ptr::addr_of_mut!(lo), a); + unsafe { + _mm256_storeu2_m128i(ptr::addr_of_mut!(hi), ptr::addr_of_mut!(lo), a); + } #[rustfmt::skip] let e_hi = _mm_setr_epi8( 17, 18, 19, 20, 21, 22, 23, 24, diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 6f56e937c6db..6a39a0aaf8fe 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -4672,81 +4672,89 @@ mod tests { } #[simd_test(enable = "avx2")] - const unsafe fn test_mm_maskload_epi32() { + const fn test_mm_maskload_epi32() { let nums = [1, 2, 3, 4]; let a = &nums as *const i32; let mask = _mm_setr_epi32(-1, 0, 0, -1); - let r = _mm_maskload_epi32(a, mask); + let r = unsafe { _mm_maskload_epi32(a, mask) }; let e = _mm_setr_epi32(1, 0, 0, 4); assert_eq_m128i(r, e); } #[simd_test(enable = "avx2")] - const unsafe fn test_mm256_maskload_epi32() { + const fn test_mm256_maskload_epi32() { let nums = [1, 2, 3, 4, 5, 6, 7, 8]; let a = &nums as *const i32; let mask = _mm256_setr_epi32(-1, 0, 0, -1, 0, -1, -1, 0); - let r = _mm256_maskload_epi32(a, mask); + let r = unsafe { _mm256_maskload_epi32(a, mask) }; let e = _mm256_setr_epi32(1, 0, 0, 4, 0, 6, 7, 0); assert_eq_m256i(r, e); } #[simd_test(enable = "avx2")] - const unsafe fn test_mm_maskload_epi64() { + const fn test_mm_maskload_epi64() { let nums = [1_i64, 2_i64]; let a = &nums as *const i64; let mask = _mm_setr_epi64x(0, -1); - let r = _mm_maskload_epi64(a, mask); + let r = unsafe { _mm_maskload_epi64(a, mask) }; let e = _mm_setr_epi64x(0, 2); assert_eq_m128i(r, e); } #[simd_test(enable = "avx2")] - const unsafe fn test_mm256_maskload_epi64() { + const fn test_mm256_maskload_epi64() { let nums = [1_i64, 2_i64, 3_i64, 4_i64]; let a = &nums as *const i64; let mask = _mm256_setr_epi64x(0, -1, -1, 0); - let r = _mm256_maskload_epi64(a, mask); + let r = unsafe { _mm256_maskload_epi64(a, mask) }; let e = _mm256_setr_epi64x(0, 2, 3, 0); assert_eq_m256i(r, e); } #[simd_test(enable = "avx2")] - const unsafe fn test_mm_maskstore_epi32() { + const fn test_mm_maskstore_epi32() { let a = _mm_setr_epi32(1, 2, 3, 4); let mut arr = [-1, -1, -1, -1]; let mask = _mm_setr_epi32(-1, 0, 0, -1); - _mm_maskstore_epi32(arr.as_mut_ptr(), mask, a); + unsafe { + _mm_maskstore_epi32(arr.as_mut_ptr(), mask, a); + } let e = [1, -1, -1, 4]; assert_eq!(arr, e); } #[simd_test(enable = "avx2")] - const unsafe fn test_mm256_maskstore_epi32() { + const fn test_mm256_maskstore_epi32() { let a = _mm256_setr_epi32(1, 0x6d726f, 3, 42, 0x777161, 6, 7, 8); let mut arr = [-1, -1, -1, 0x776173, -1, 0x68657265, -1, -1]; let mask = _mm256_setr_epi32(-1, 0, 0, -1, 0, -1, -1, 0); - _mm256_maskstore_epi32(arr.as_mut_ptr(), mask, a); + unsafe { + _mm256_maskstore_epi32(arr.as_mut_ptr(), mask, a); + } let e = [1, -1, -1, 42, -1, 6, 7, -1]; assert_eq!(arr, e); } #[simd_test(enable = "avx2")] - const unsafe fn test_mm_maskstore_epi64() { + const fn test_mm_maskstore_epi64() { let a = _mm_setr_epi64x(1_i64, 2_i64); let mut arr = [-1_i64, -1_i64]; let mask = _mm_setr_epi64x(0, -1); - _mm_maskstore_epi64(arr.as_mut_ptr(), mask, a); + unsafe { + _mm_maskstore_epi64(arr.as_mut_ptr(), mask, a); + } let e = [-1, 2]; assert_eq!(arr, e); } #[simd_test(enable = "avx2")] - const unsafe fn test_mm256_maskstore_epi64() { + const fn test_mm256_maskstore_epi64() { let a = _mm256_setr_epi64x(1_i64, 2_i64, 3_i64, 4_i64); let mut arr = [-1_i64, -1_i64, -1_i64, -1_i64]; let mask = _mm256_setr_epi64x(0, -1, -1, 0); - _mm256_maskstore_epi64(arr.as_mut_ptr(), mask, a); + unsafe { + _mm256_maskstore_epi64(arr.as_mut_ptr(), mask, a); + } let e = [-1, 2, 3, -1]; assert_eq!(arr, e); } @@ -5301,9 +5309,9 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_stream_load_si256() { + fn test_mm256_stream_load_si256() { let a = _mm256_set_epi64x(5, 6, 7, 8); - let r = _mm256_stream_load_si256(core::ptr::addr_of!(a) as *const _); + let r = unsafe { _mm256_stream_load_si256(core::ptr::addr_of!(a) as *const _) }; assert_eq_m256i(a, r); } @@ -5506,88 +5514,98 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_i32gather_epi32() { + fn test_mm_i32gather_epi32() { let arr: [i32; 128] = core::array::from_fn(|i| i as i32); // A multiplier of 4 is word-addressing - let r = _mm_i32gather_epi32::<4>(arr.as_ptr(), _mm_setr_epi32(0, 16, 32, 48)); + let r = unsafe { _mm_i32gather_epi32::<4>(arr.as_ptr(), _mm_setr_epi32(0, 16, 32, 48)) }; assert_eq_m128i(r, _mm_setr_epi32(0, 16, 32, 48)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_mask_i32gather_epi32() { + fn test_mm_mask_i32gather_epi32() { let arr: [i32; 128] = core::array::from_fn(|i| i as i32); // A multiplier of 4 is word-addressing - let r = _mm_mask_i32gather_epi32::<4>( - _mm_set1_epi32(256), - arr.as_ptr(), - _mm_setr_epi32(0, 16, 64, 96), - _mm_setr_epi32(-1, -1, -1, 0), - ); + let r = unsafe { + _mm_mask_i32gather_epi32::<4>( + _mm_set1_epi32(256), + arr.as_ptr(), + _mm_setr_epi32(0, 16, 64, 96), + _mm_setr_epi32(-1, -1, -1, 0), + ) + }; assert_eq_m128i(r, _mm_setr_epi32(0, 16, 64, 256)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_i32gather_epi32() { + fn test_mm256_i32gather_epi32() { let arr: [i32; 128] = core::array::from_fn(|i| i as i32); // A multiplier of 4 is word-addressing - let r = - _mm256_i32gather_epi32::<4>(arr.as_ptr(), _mm256_setr_epi32(0, 16, 32, 48, 1, 2, 3, 4)); + let r = unsafe { + _mm256_i32gather_epi32::<4>(arr.as_ptr(), _mm256_setr_epi32(0, 16, 32, 48, 1, 2, 3, 4)) + }; assert_eq_m256i(r, _mm256_setr_epi32(0, 16, 32, 48, 1, 2, 3, 4)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mask_i32gather_epi32() { + fn test_mm256_mask_i32gather_epi32() { let arr: [i32; 128] = core::array::from_fn(|i| i as i32); // A multiplier of 4 is word-addressing - let r = _mm256_mask_i32gather_epi32::<4>( - _mm256_set1_epi32(256), - arr.as_ptr(), - _mm256_setr_epi32(0, 16, 64, 96, 0, 0, 0, 0), - _mm256_setr_epi32(-1, -1, -1, 0, 0, 0, 0, 0), - ); + let r = unsafe { + _mm256_mask_i32gather_epi32::<4>( + _mm256_set1_epi32(256), + arr.as_ptr(), + _mm256_setr_epi32(0, 16, 64, 96, 0, 0, 0, 0), + _mm256_setr_epi32(-1, -1, -1, 0, 0, 0, 0, 0), + ) + }; assert_eq_m256i(r, _mm256_setr_epi32(0, 16, 64, 256, 256, 256, 256, 256)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_i32gather_ps() { + fn test_mm_i32gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing for f32s - let r = _mm_i32gather_ps::<4>(arr.as_ptr(), _mm_setr_epi32(0, 16, 32, 48)); + let r = unsafe { _mm_i32gather_ps::<4>(arr.as_ptr(), _mm_setr_epi32(0, 16, 32, 48)) }; assert_eq_m128(r, _mm_setr_ps(0.0, 16.0, 32.0, 48.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_mask_i32gather_ps() { + fn test_mm_mask_i32gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing for f32s - let r = _mm_mask_i32gather_ps::<4>( - _mm_set1_ps(256.0), - arr.as_ptr(), - _mm_setr_epi32(0, 16, 64, 96), - _mm_setr_ps(-1.0, -1.0, -1.0, 0.0), - ); + let r = unsafe { + _mm_mask_i32gather_ps::<4>( + _mm_set1_ps(256.0), + arr.as_ptr(), + _mm_setr_epi32(0, 16, 64, 96), + _mm_setr_ps(-1.0, -1.0, -1.0, 0.0), + ) + }; assert_eq_m128(r, _mm_setr_ps(0.0, 16.0, 64.0, 256.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_i32gather_ps() { + fn test_mm256_i32gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing for f32s - let r = - _mm256_i32gather_ps::<4>(arr.as_ptr(), _mm256_setr_epi32(0, 16, 32, 48, 1, 2, 3, 4)); + let r = unsafe { + _mm256_i32gather_ps::<4>(arr.as_ptr(), _mm256_setr_epi32(0, 16, 32, 48, 1, 2, 3, 4)) + }; assert_eq_m256(r, _mm256_setr_ps(0.0, 16.0, 32.0, 48.0, 1.0, 2.0, 3.0, 4.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mask_i32gather_ps() { + fn test_mm256_mask_i32gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing for f32s - let r = _mm256_mask_i32gather_ps::<4>( - _mm256_set1_ps(256.0), - arr.as_ptr(), - _mm256_setr_epi32(0, 16, 64, 96, 0, 0, 0, 0), - _mm256_setr_ps(-1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0), - ); + let r = unsafe { + _mm256_mask_i32gather_ps::<4>( + _mm256_set1_ps(256.0), + arr.as_ptr(), + _mm256_setr_epi32(0, 16, 64, 96, 0, 0, 0, 0), + _mm256_setr_ps(-1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0), + ) + }; assert_eq_m256( r, _mm256_setr_ps(0.0, 16.0, 64.0, 256.0, 256.0, 256.0, 256.0, 256.0), @@ -5595,254 +5613,282 @@ mod tests { } #[simd_test(enable = "avx2")] - unsafe fn test_mm_i32gather_epi64() { + fn test_mm_i32gather_epi64() { let arr: [i64; 128] = core::array::from_fn(|i| i as i64); // A multiplier of 8 is word-addressing for i64s - let r = _mm_i32gather_epi64::<8>(arr.as_ptr(), _mm_setr_epi32(0, 16, 0, 0)); + let r = unsafe { _mm_i32gather_epi64::<8>(arr.as_ptr(), _mm_setr_epi32(0, 16, 0, 0)) }; assert_eq_m128i(r, _mm_setr_epi64x(0, 16)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_mask_i32gather_epi64() { + fn test_mm_mask_i32gather_epi64() { let arr: [i64; 128] = core::array::from_fn(|i| i as i64); // A multiplier of 8 is word-addressing for i64s - let r = _mm_mask_i32gather_epi64::<8>( - _mm_set1_epi64x(256), - arr.as_ptr(), - _mm_setr_epi32(16, 16, 16, 16), - _mm_setr_epi64x(-1, 0), - ); + let r = unsafe { + _mm_mask_i32gather_epi64::<8>( + _mm_set1_epi64x(256), + arr.as_ptr(), + _mm_setr_epi32(16, 16, 16, 16), + _mm_setr_epi64x(-1, 0), + ) + }; assert_eq_m128i(r, _mm_setr_epi64x(16, 256)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_i32gather_epi64() { + fn test_mm256_i32gather_epi64() { let arr: [i64; 128] = core::array::from_fn(|i| i as i64); // A multiplier of 8 is word-addressing for i64s - let r = _mm256_i32gather_epi64::<8>(arr.as_ptr(), _mm_setr_epi32(0, 16, 32, 48)); + let r = unsafe { _mm256_i32gather_epi64::<8>(arr.as_ptr(), _mm_setr_epi32(0, 16, 32, 48)) }; assert_eq_m256i(r, _mm256_setr_epi64x(0, 16, 32, 48)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mask_i32gather_epi64() { + fn test_mm256_mask_i32gather_epi64() { let arr: [i64; 128] = core::array::from_fn(|i| i as i64); // A multiplier of 8 is word-addressing for i64s - let r = _mm256_mask_i32gather_epi64::<8>( - _mm256_set1_epi64x(256), - arr.as_ptr(), - _mm_setr_epi32(0, 16, 64, 96), - _mm256_setr_epi64x(-1, -1, -1, 0), - ); + let r = unsafe { + _mm256_mask_i32gather_epi64::<8>( + _mm256_set1_epi64x(256), + arr.as_ptr(), + _mm_setr_epi32(0, 16, 64, 96), + _mm256_setr_epi64x(-1, -1, -1, 0), + ) + }; assert_eq_m256i(r, _mm256_setr_epi64x(0, 16, 64, 256)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_i32gather_pd() { + fn test_mm_i32gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing for f64s - let r = _mm_i32gather_pd::<8>(arr.as_ptr(), _mm_setr_epi32(0, 16, 0, 0)); + let r = unsafe { _mm_i32gather_pd::<8>(arr.as_ptr(), _mm_setr_epi32(0, 16, 0, 0)) }; assert_eq_m128d(r, _mm_setr_pd(0.0, 16.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_mask_i32gather_pd() { + fn test_mm_mask_i32gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing for f64s - let r = _mm_mask_i32gather_pd::<8>( - _mm_set1_pd(256.0), - arr.as_ptr(), - _mm_setr_epi32(16, 16, 16, 16), - _mm_setr_pd(-1.0, 0.0), - ); + let r = unsafe { + _mm_mask_i32gather_pd::<8>( + _mm_set1_pd(256.0), + arr.as_ptr(), + _mm_setr_epi32(16, 16, 16, 16), + _mm_setr_pd(-1.0, 0.0), + ) + }; assert_eq_m128d(r, _mm_setr_pd(16.0, 256.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_i32gather_pd() { + fn test_mm256_i32gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing for f64s - let r = _mm256_i32gather_pd::<8>(arr.as_ptr(), _mm_setr_epi32(0, 16, 32, 48)); + let r = unsafe { _mm256_i32gather_pd::<8>(arr.as_ptr(), _mm_setr_epi32(0, 16, 32, 48)) }; assert_eq_m256d(r, _mm256_setr_pd(0.0, 16.0, 32.0, 48.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mask_i32gather_pd() { + fn test_mm256_mask_i32gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing for f64s - let r = _mm256_mask_i32gather_pd::<8>( - _mm256_set1_pd(256.0), - arr.as_ptr(), - _mm_setr_epi32(0, 16, 64, 96), - _mm256_setr_pd(-1.0, -1.0, -1.0, 0.0), - ); + let r = unsafe { + _mm256_mask_i32gather_pd::<8>( + _mm256_set1_pd(256.0), + arr.as_ptr(), + _mm_setr_epi32(0, 16, 64, 96), + _mm256_setr_pd(-1.0, -1.0, -1.0, 0.0), + ) + }; assert_eq_m256d(r, _mm256_setr_pd(0.0, 16.0, 64.0, 256.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_i64gather_epi32() { + fn test_mm_i64gather_epi32() { let arr: [i32; 128] = core::array::from_fn(|i| i as i32); // A multiplier of 4 is word-addressing - let r = _mm_i64gather_epi32::<4>(arr.as_ptr(), _mm_setr_epi64x(0, 16)); + let r = unsafe { _mm_i64gather_epi32::<4>(arr.as_ptr(), _mm_setr_epi64x(0, 16)) }; assert_eq_m128i(r, _mm_setr_epi32(0, 16, 0, 0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_mask_i64gather_epi32() { + fn test_mm_mask_i64gather_epi32() { let arr: [i32; 128] = core::array::from_fn(|i| i as i32); // A multiplier of 4 is word-addressing - let r = _mm_mask_i64gather_epi32::<4>( - _mm_set1_epi32(256), - arr.as_ptr(), - _mm_setr_epi64x(0, 16), - _mm_setr_epi32(-1, 0, -1, 0), - ); + let r = unsafe { + _mm_mask_i64gather_epi32::<4>( + _mm_set1_epi32(256), + arr.as_ptr(), + _mm_setr_epi64x(0, 16), + _mm_setr_epi32(-1, 0, -1, 0), + ) + }; assert_eq_m128i(r, _mm_setr_epi32(0, 256, 0, 0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_i64gather_epi32() { + fn test_mm256_i64gather_epi32() { let arr: [i32; 128] = core::array::from_fn(|i| i as i32); // A multiplier of 4 is word-addressing - let r = _mm256_i64gather_epi32::<4>(arr.as_ptr(), _mm256_setr_epi64x(0, 16, 32, 48)); + let r = + unsafe { _mm256_i64gather_epi32::<4>(arr.as_ptr(), _mm256_setr_epi64x(0, 16, 32, 48)) }; assert_eq_m128i(r, _mm_setr_epi32(0, 16, 32, 48)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mask_i64gather_epi32() { + fn test_mm256_mask_i64gather_epi32() { let arr: [i32; 128] = core::array::from_fn(|i| i as i32); // A multiplier of 4 is word-addressing - let r = _mm256_mask_i64gather_epi32::<4>( - _mm_set1_epi32(256), - arr.as_ptr(), - _mm256_setr_epi64x(0, 16, 64, 96), - _mm_setr_epi32(-1, -1, -1, 0), - ); + let r = unsafe { + _mm256_mask_i64gather_epi32::<4>( + _mm_set1_epi32(256), + arr.as_ptr(), + _mm256_setr_epi64x(0, 16, 64, 96), + _mm_setr_epi32(-1, -1, -1, 0), + ) + }; assert_eq_m128i(r, _mm_setr_epi32(0, 16, 64, 256)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_i64gather_ps() { + fn test_mm_i64gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing for f32s - let r = _mm_i64gather_ps::<4>(arr.as_ptr(), _mm_setr_epi64x(0, 16)); + let r = unsafe { _mm_i64gather_ps::<4>(arr.as_ptr(), _mm_setr_epi64x(0, 16)) }; assert_eq_m128(r, _mm_setr_ps(0.0, 16.0, 0.0, 0.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_mask_i64gather_ps() { + fn test_mm_mask_i64gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing for f32s - let r = _mm_mask_i64gather_ps::<4>( - _mm_set1_ps(256.0), - arr.as_ptr(), - _mm_setr_epi64x(0, 16), - _mm_setr_ps(-1.0, 0.0, -1.0, 0.0), - ); + let r = unsafe { + _mm_mask_i64gather_ps::<4>( + _mm_set1_ps(256.0), + arr.as_ptr(), + _mm_setr_epi64x(0, 16), + _mm_setr_ps(-1.0, 0.0, -1.0, 0.0), + ) + }; assert_eq_m128(r, _mm_setr_ps(0.0, 256.0, 0.0, 0.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_i64gather_ps() { + fn test_mm256_i64gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing for f32s - let r = _mm256_i64gather_ps::<4>(arr.as_ptr(), _mm256_setr_epi64x(0, 16, 32, 48)); + let r = + unsafe { _mm256_i64gather_ps::<4>(arr.as_ptr(), _mm256_setr_epi64x(0, 16, 32, 48)) }; assert_eq_m128(r, _mm_setr_ps(0.0, 16.0, 32.0, 48.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mask_i64gather_ps() { + fn test_mm256_mask_i64gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing for f32s - let r = _mm256_mask_i64gather_ps::<4>( - _mm_set1_ps(256.0), - arr.as_ptr(), - _mm256_setr_epi64x(0, 16, 64, 96), - _mm_setr_ps(-1.0, -1.0, -1.0, 0.0), - ); + let r = unsafe { + _mm256_mask_i64gather_ps::<4>( + _mm_set1_ps(256.0), + arr.as_ptr(), + _mm256_setr_epi64x(0, 16, 64, 96), + _mm_setr_ps(-1.0, -1.0, -1.0, 0.0), + ) + }; assert_eq_m128(r, _mm_setr_ps(0.0, 16.0, 64.0, 256.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_i64gather_epi64() { + fn test_mm_i64gather_epi64() { let arr: [i64; 128] = core::array::from_fn(|i| i as i64); // A multiplier of 8 is word-addressing for i64s - let r = _mm_i64gather_epi64::<8>(arr.as_ptr(), _mm_setr_epi64x(0, 16)); + let r = unsafe { _mm_i64gather_epi64::<8>(arr.as_ptr(), _mm_setr_epi64x(0, 16)) }; assert_eq_m128i(r, _mm_setr_epi64x(0, 16)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_mask_i64gather_epi64() { + fn test_mm_mask_i64gather_epi64() { let arr: [i64; 128] = core::array::from_fn(|i| i as i64); // A multiplier of 8 is word-addressing for i64s - let r = _mm_mask_i64gather_epi64::<8>( - _mm_set1_epi64x(256), - arr.as_ptr(), - _mm_setr_epi64x(16, 16), - _mm_setr_epi64x(-1, 0), - ); + let r = unsafe { + _mm_mask_i64gather_epi64::<8>( + _mm_set1_epi64x(256), + arr.as_ptr(), + _mm_setr_epi64x(16, 16), + _mm_setr_epi64x(-1, 0), + ) + }; assert_eq_m128i(r, _mm_setr_epi64x(16, 256)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_i64gather_epi64() { + fn test_mm256_i64gather_epi64() { let arr: [i64; 128] = core::array::from_fn(|i| i as i64); // A multiplier of 8 is word-addressing for i64s - let r = _mm256_i64gather_epi64::<8>(arr.as_ptr(), _mm256_setr_epi64x(0, 16, 32, 48)); + let r = + unsafe { _mm256_i64gather_epi64::<8>(arr.as_ptr(), _mm256_setr_epi64x(0, 16, 32, 48)) }; assert_eq_m256i(r, _mm256_setr_epi64x(0, 16, 32, 48)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mask_i64gather_epi64() { + fn test_mm256_mask_i64gather_epi64() { let arr: [i64; 128] = core::array::from_fn(|i| i as i64); // A multiplier of 8 is word-addressing for i64s - let r = _mm256_mask_i64gather_epi64::<8>( - _mm256_set1_epi64x(256), - arr.as_ptr(), - _mm256_setr_epi64x(0, 16, 64, 96), - _mm256_setr_epi64x(-1, -1, -1, 0), - ); + let r = unsafe { + _mm256_mask_i64gather_epi64::<8>( + _mm256_set1_epi64x(256), + arr.as_ptr(), + _mm256_setr_epi64x(0, 16, 64, 96), + _mm256_setr_epi64x(-1, -1, -1, 0), + ) + }; assert_eq_m256i(r, _mm256_setr_epi64x(0, 16, 64, 256)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_i64gather_pd() { + fn test_mm_i64gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing for f64s - let r = _mm_i64gather_pd::<8>(arr.as_ptr(), _mm_setr_epi64x(0, 16)); + let r = unsafe { _mm_i64gather_pd::<8>(arr.as_ptr(), _mm_setr_epi64x(0, 16)) }; assert_eq_m128d(r, _mm_setr_pd(0.0, 16.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm_mask_i64gather_pd() { + fn test_mm_mask_i64gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing for f64s - let r = _mm_mask_i64gather_pd::<8>( - _mm_set1_pd(256.0), - arr.as_ptr(), - _mm_setr_epi64x(16, 16), - _mm_setr_pd(-1.0, 0.0), - ); + let r = unsafe { + _mm_mask_i64gather_pd::<8>( + _mm_set1_pd(256.0), + arr.as_ptr(), + _mm_setr_epi64x(16, 16), + _mm_setr_pd(-1.0, 0.0), + ) + }; assert_eq_m128d(r, _mm_setr_pd(16.0, 256.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_i64gather_pd() { + fn test_mm256_i64gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing for f64s - let r = _mm256_i64gather_pd::<8>(arr.as_ptr(), _mm256_setr_epi64x(0, 16, 32, 48)); + let r = + unsafe { _mm256_i64gather_pd::<8>(arr.as_ptr(), _mm256_setr_epi64x(0, 16, 32, 48)) }; assert_eq_m256d(r, _mm256_setr_pd(0.0, 16.0, 32.0, 48.0)); } #[simd_test(enable = "avx2")] - unsafe fn test_mm256_mask_i64gather_pd() { + fn test_mm256_mask_i64gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing for f64s - let r = _mm256_mask_i64gather_pd::<8>( - _mm256_set1_pd(256.0), - arr.as_ptr(), - _mm256_setr_epi64x(0, 16, 64, 96), - _mm256_setr_pd(-1.0, -1.0, -1.0, 0.0), - ); + let r = unsafe { + _mm256_mask_i64gather_pd::<8>( + _mm256_set1_pd(256.0), + arr.as_ptr(), + _mm256_setr_epi64x(0, 16, 64, 96), + _mm256_setr_pd(-1.0, -1.0, -1.0, 0.0), + ) + }; assert_eq_m256d(r, _mm256_setr_pd(0.0, 16.0, 64.0, 256.0)); } diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bf16.rs b/library/stdarch/crates/core_arch/src/x86/avx512bf16.rs index 83dbc540a0c8..66eef063eed8 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bf16.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bf16.rs @@ -593,7 +593,7 @@ pub fn _mm_cvtness_sbh(a: f32) -> bf16 { #[cfg(test)] mod tests { - use crate::core_arch::simd::u16x4; + use crate::core_arch::simd::{f32x4, f32x8, f32x16, u16x4, u16x8, u16x16, u16x32}; use crate::{ core_arch::x86::*, mem::{transmute, transmute_copy}, @@ -601,13 +601,13 @@ mod tests { use stdarch_test::simd_test; #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm_cvtne2ps_pbh() { + fn test_mm_cvtne2ps_pbh() { let a_array = [178.125_f32, 10.5_f32, 3.75_f32, 50.25_f32]; let b_array = [-178.125_f32, -10.5_f32, -3.75_f32, -50.25_f32]; - let a: __m128 = transmute(a_array); - let b: __m128 = transmute(b_array); + let a = f32x4::from_array(a_array).as_m128(); + let b = f32x4::from_array(b_array).as_m128(); let c: __m128bh = _mm_cvtne2ps_pbh(a, b); - let result: [u16; 8] = transmute(c.as_u16x8()); + let result = *c.as_u16x8().as_array(); #[rustfmt::skip] let expected_result: [u16; 8] = [ 0b1_10000110_0110010, @@ -623,7 +623,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm_mask_cvtne2ps_pbh() { + fn test_mm_mask_cvtne2ps_pbh() { let a_array = [178.125_f32, 10.5_f32, 3.75_f32, 50.25_f32]; let b_array = [-178.125_f32, -10.5_f32, -3.75_f32, -50.25_f32]; #[rustfmt::skip] @@ -637,12 +637,12 @@ mod tests { 0b0_10000000_1110000, 0b0_10000100_1001001, ]; - let src: __m128bh = transmute(src_array); - let a: __m128 = transmute(a_array); - let b: __m128 = transmute(b_array); + let src = u16x8::from_array(src_array).as_m128bh(); + let a = f32x4::from_array(a_array).as_m128(); + let b = f32x4::from_array(b_array).as_m128(); let k: __mmask8 = 0b1111_1111; let c: __m128bh = _mm_mask_cvtne2ps_pbh(src, k, a, b); - let result: [u16; 8] = transmute(c.as_u16x8()); + let result = *c.as_u16x8().as_array(); #[rustfmt::skip] let expected_result: [u16; 8] = [ 0b1_10000110_0110010, @@ -657,20 +657,20 @@ mod tests { assert_eq!(result, expected_result); let k = 0b0000_0000; let c = _mm_mask_cvtne2ps_pbh(src, k, a, b); - let result: [u16; 8] = transmute(c.as_u16x8()); + let result = *c.as_u16x8().as_array(); let expected_result = src_array; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm_maskz_cvtne2ps_pbh() { + fn test_mm_maskz_cvtne2ps_pbh() { let a_array = [178.125_f32, 10.5_f32, 3.75_f32, 50.25_f32]; let b_array = [-178.125_f32, -10.5_f32, -3.75_f32, -50.25_f32]; - let a: __m128 = transmute(a_array); - let b: __m128 = transmute(b_array); + let a = f32x4::from_array(a_array).as_m128(); + let b = f32x4::from_array(b_array).as_m128(); let k: __mmask8 = 0b1111_1111; let c: __m128bh = _mm_maskz_cvtne2ps_pbh(k, a, b); - let result: [u16; 8] = transmute(c.as_u16x8()); + let result = *c.as_u16x8().as_array(); #[rustfmt::skip] let expected_result: [u16; 8] = [ 0b1_10000110_0110010, @@ -685,7 +685,7 @@ mod tests { assert_eq!(result, expected_result); let k = 0b0011_1100; let c = _mm_maskz_cvtne2ps_pbh(k, a, b); - let result: [u16; 8] = transmute(c.as_u16x8()); + let result = *c.as_u16x8().as_array(); #[rustfmt::skip] let expected_result: [u16; 8] = [ 0, @@ -701,7 +701,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm256_cvtne2ps_pbh() { + fn test_mm256_cvtne2ps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -723,10 +723,10 @@ mod tests { -1000.158_f32, -575.575_f32, ]; - let a: __m256 = transmute(a_array); - let b: __m256 = transmute(b_array); + let a = f32x8::from_array(a_array).as_m256(); + let b = f32x8::from_array(b_array).as_m256(); let c: __m256bh = _mm256_cvtne2ps_pbh(a, b); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); #[rustfmt::skip] let expected_result: [u16; 16] = [ 0b1_10000110_0110010, @@ -750,7 +750,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm256_mask_cvtne2ps_pbh() { + fn test_mm256_mask_cvtne2ps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -790,12 +790,12 @@ mod tests { 0b0_10000000_1110000, 0b0_10000100_1001001, ]; - let src: __m256bh = transmute(src_array); - let a: __m256 = transmute(a_array); - let b: __m256 = transmute(b_array); + let src = u16x16::from_array(src_array).as_m256bh(); + let a = f32x8::from_array(a_array).as_m256(); + let b = f32x8::from_array(b_array).as_m256(); let k: __mmask16 = 0xffff; let c: __m256bh = _mm256_mask_cvtne2ps_pbh(src, k, a, b); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); #[rustfmt::skip] let expected_result: [u16; 16] = [ 0b1_10000110_0110010, @@ -818,13 +818,13 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask16 = 0; let c: __m256bh = _mm256_mask_cvtne2ps_pbh(src, k, a, b); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); let expected_result = src_array; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm256_maskz_cvtne2ps_pbh() { + fn test_mm256_maskz_cvtne2ps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -846,11 +846,11 @@ mod tests { -1000.158_f32, -575.575_f32, ]; - let a: __m256 = transmute(a_array); - let b: __m256 = transmute(b_array); + let a = f32x8::from_array(a_array).as_m256(); + let b = f32x8::from_array(b_array).as_m256(); let k: __mmask16 = 0xffff; let c: __m256bh = _mm256_maskz_cvtne2ps_pbh(k, a, b); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); #[rustfmt::skip] let expected_result: [u16; 16] = [ 0b1_10000110_0110010, @@ -873,7 +873,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask16 = 0b0110_1100_0011_0110; let c: __m256bh = _mm256_maskz_cvtne2ps_pbh(k, a, b); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); #[rustfmt::skip] let expected_result: [u16; 16] = [ 0, @@ -897,7 +897,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512f")] - unsafe fn test_mm512_cvtne2ps_pbh() { + fn test_mm512_cvtne2ps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -935,10 +935,10 @@ mod tests { -1000.158_f32, -575.575_f32, ]; - let a: __m512 = transmute(a_array); - let b: __m512 = transmute(b_array); + let a = f32x16::from_array(a_array).as_m512(); + let b = f32x16::from_array(b_array).as_m512(); let c: __m512bh = _mm512_cvtne2ps_pbh(a, b); - let result: [u16; 32] = transmute(c.as_u16x32()); + let result = *c.as_u16x32().as_array(); #[rustfmt::skip] let expected_result: [u16; 32] = [ 0b1_10000110_0110010, @@ -978,7 +978,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512f")] - unsafe fn test_mm512_mask_cvtne2ps_pbh() { + fn test_mm512_mask_cvtne2ps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -1050,12 +1050,12 @@ mod tests { 0b0_10000000_1110000, 0b0_10000100_1001001, ]; - let src: __m512bh = transmute(src_array); - let a: __m512 = transmute(a_array); - let b: __m512 = transmute(b_array); + let src = u16x32::from_array(src_array).as_m512bh(); + let a = f32x16::from_array(a_array).as_m512(); + let b = f32x16::from_array(b_array).as_m512(); let k: __mmask32 = 0xffffffff; let c: __m512bh = _mm512_mask_cvtne2ps_pbh(src, k, a, b); - let result: [u16; 32] = transmute(c.as_u16x32()); + let result = *c.as_u16x32().as_array(); #[rustfmt::skip] let expected_result: [u16; 32] = [ 0b1_10000110_0110010, @@ -1094,13 +1094,13 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask32 = 0; let c: __m512bh = _mm512_mask_cvtne2ps_pbh(src, k, a, b); - let result: [u16; 32] = transmute(c.as_u16x32()); + let result = *c.as_u16x32().as_array(); let expected_result = src_array; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512f")] - unsafe fn test_mm512_maskz_cvtne2ps_pbh() { + fn test_mm512_maskz_cvtne2ps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -1138,11 +1138,11 @@ mod tests { -1000.158_f32, -575.575_f32, ]; - let a: __m512 = transmute(a_array); - let b: __m512 = transmute(b_array); + let a = f32x16::from_array(a_array).as_m512(); + let b = f32x16::from_array(b_array).as_m512(); let k: __mmask32 = 0xffffffff; let c: __m512bh = _mm512_maskz_cvtne2ps_pbh(k, a, b); - let result: [u16; 32] = transmute(c.as_u16x32()); + let result = *c.as_u16x32().as_array(); #[rustfmt::skip] let expected_result: [u16; 32] = [ 0b1_10000110_0110010, @@ -1181,7 +1181,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask32 = 0b1100_1010_1001_0110_1010_0011_0101_0110; let c: __m512bh = _mm512_maskz_cvtne2ps_pbh(k, a, b); - let result: [u16; 32] = transmute(c.as_u16x32()); + let result = *c.as_u16x32().as_array(); #[rustfmt::skip] let expected_result: [u16; 32] = [ 0, @@ -1221,7 +1221,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm256_cvtneps_pbh() { + fn test_mm256_cvtneps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -1233,9 +1233,9 @@ mod tests { 1000.158_f32, 575.575_f32, ]; - let a: __m256 = transmute(a_array); + let a = f32x8::from_array(a_array).as_m256(); let c: __m128bh = _mm256_cvtneps_pbh(a); - let result: [u16; 8] = transmute(c.as_u16x8()); + let result = *c.as_u16x8().as_array(); #[rustfmt::skip] let expected_result: [u16; 8] = [ 0b0_10000110_0110010, @@ -1251,7 +1251,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm256_mask_cvtneps_pbh() { + fn test_mm256_mask_cvtneps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -1273,11 +1273,11 @@ mod tests { 0b1_10001000_1111010, 0b1_10001000_0010000, ]; - let src: __m128bh = transmute(src_array); - let a: __m256 = transmute(a_array); + let src = u16x8::from_array(src_array).as_m128bh(); + let a = f32x8::from_array(a_array).as_m256(); let k: __mmask8 = 0xff; let b = _mm256_mask_cvtneps_pbh(src, k, a); - let result: [u16; 8] = transmute(b.as_u16x8()); + let result = *b.as_u16x8().as_array(); #[rustfmt::skip] let expected_result: [u16; 8] = [ 0b0_10000110_0110010, @@ -1292,13 +1292,13 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask8 = 0x0; let b: __m128bh = _mm256_mask_cvtneps_pbh(src, k, a); - let result: [u16; 8] = transmute(b.as_u16x8()); + let result = *b.as_u16x8().as_array(); let expected_result: [u16; 8] = src_array; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm256_maskz_cvtneps_pbh() { + fn test_mm256_maskz_cvtneps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -1310,10 +1310,10 @@ mod tests { 1000.158_f32, 575.575_f32, ]; - let a: __m256 = transmute(a_array); + let a = f32x8::from_array(a_array).as_m256(); let k: __mmask8 = 0xff; let b = _mm256_maskz_cvtneps_pbh(k, a); - let result: [u16; 8] = transmute(b.as_u16x8()); + let result = *b.as_u16x8().as_array(); #[rustfmt::skip] let expected_result: [u16; 8] = [ 0b0_10000110_0110010, @@ -1328,14 +1328,14 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask8 = 0x6; let b: __m128bh = _mm256_maskz_cvtneps_pbh(k, a); - let result: [u16; 8] = transmute(b.as_u16x8()); + let result = *b.as_u16x8().as_array(); let expected_result: [u16; 8] = [0, 0b0_10000010_0101000, 0b0_10000000_1110000, 0, 0, 0, 0, 0]; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512f")] - unsafe fn test_mm512_cvtneps_pbh() { + fn test_mm512_cvtneps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -1355,9 +1355,9 @@ mod tests { 1000.158_f32, 575.575_f32, ]; - let a: __m512 = transmute(a_array); + let a = f32x16::from_array(a_array).as_m512(); let c: __m256bh = _mm512_cvtneps_pbh(a); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); #[rustfmt::skip] let expected_result: [u16; 16] = [ 0b0_10000110_0110010, @@ -1381,7 +1381,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512f")] - unsafe fn test_mm512_mask_cvtneps_pbh() { + fn test_mm512_mask_cvtneps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -1419,11 +1419,11 @@ mod tests { 0b1_10001000_1111010, 0b1_10001000_0010000, ]; - let src: __m256bh = transmute(src_array); - let a: __m512 = transmute(a_array); + let src = u16x16::from_array(src_array).as_m256bh(); + let a = f32x16::from_array(a_array).as_m512(); let k: __mmask16 = 0xffff; let c: __m256bh = _mm512_mask_cvtneps_pbh(src, k, a); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); #[rustfmt::skip] let expected_result: [u16; 16] = [ 0b0_10000110_0110010, @@ -1446,13 +1446,13 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask16 = 0; let c: __m256bh = _mm512_mask_cvtneps_pbh(src, k, a); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); let expected_result = src_array; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512f")] - unsafe fn test_mm512_maskz_cvtneps_pbh() { + fn test_mm512_maskz_cvtneps_pbh() { #[rustfmt::skip] let a_array = [ 178.125_f32, @@ -1472,10 +1472,10 @@ mod tests { 1000.158_f32, 575.575_f32, ]; - let a: __m512 = transmute(a_array); + let a = f32x16::from_array(a_array).as_m512(); let k: __mmask16 = 0xffff; let c: __m256bh = _mm512_maskz_cvtneps_pbh(k, a); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); #[rustfmt::skip] let expected_result: [u16; 16] = [ 0b0_10000110_0110010, @@ -1498,7 +1498,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask16 = 0x653a; let c: __m256bh = _mm512_maskz_cvtneps_pbh(k, a); - let result: [u16; 16] = transmute(c.as_u16x16()); + let result = *c.as_u16x16().as_array(); #[rustfmt::skip] let expected_result: [u16; 16] = [ 0, @@ -1522,74 +1522,74 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm_dpbf16_ps() { + fn test_mm_dpbf16_ps() { let a_array = [8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32]; let b_array = [-1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32]; - let a1: __m128 = transmute(a_array); - let b1: __m128 = transmute(b_array); - let src: __m128 = transmute([1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32]); + let a1 = f32x4::from_array(a_array).as_m128(); + let b1 = f32x4::from_array(b_array).as_m128(); + let src = f32x4::from_array([1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32]).as_m128(); let a: __m128bh = _mm_cvtne2ps_pbh(a1, a1); let b: __m128bh = _mm_cvtne2ps_pbh(b1, b1); let c: __m128 = _mm_dpbf16_ps(src, a, b); - let result: [f32; 4] = transmute(c.as_f32x4()); + let result = *c.as_f32x4().as_array(); let expected_result: [f32; 4] = [-18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32]; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm_mask_dpbf16_ps() { + fn test_mm_mask_dpbf16_ps() { let a_array = [8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32]; let b_array = [-1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32]; - let a1: __m128 = transmute(a_array); - let b1: __m128 = transmute(b_array); + let a1 = f32x4::from_array(a_array).as_m128(); + let b1 = f32x4::from_array(b_array).as_m128(); let k: __mmask8 = 0xf3; - let src: __m128 = transmute([1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32]); + let src = f32x4::from_array([1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32]).as_m128(); let a: __m128bh = _mm_cvtne2ps_pbh(a1, a1); let b: __m128bh = _mm_cvtne2ps_pbh(b1, b1); let c: __m128 = _mm_mask_dpbf16_ps(src, k, a, b); - let result: [f32; 4] = transmute(c.as_f32x4()); + let result = *c.as_f32x4().as_array(); let expected_result: [f32; 4] = [-18.0_f32, -52.0_f32, 3.0_f32, 4.0_f32]; assert_eq!(result, expected_result); let k: __mmask8 = 0xff; let c: __m128 = _mm_mask_dpbf16_ps(src, k, a, b); - let result: [f32; 4] = transmute(c.as_f32x4()); + let result = *c.as_f32x4().as_array(); let expected_result: [f32; 4] = [-18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32]; assert_eq!(result, expected_result); let k: __mmask8 = 0; let c: __m128 = _mm_mask_dpbf16_ps(src, k, a, b); - let result: [f32; 4] = transmute(c.as_f32x4()); + let result = *c.as_f32x4().as_array(); let expected_result: [f32; 4] = [1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32]; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm_maskz_dpbf16_ps() { + fn test_mm_maskz_dpbf16_ps() { let a_array = [8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32]; let b_array = [-1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32]; - let a1: __m128 = transmute(a_array); - let b1: __m128 = transmute(b_array); + let a1 = f32x4::from_array(a_array).as_m128(); + let b1 = f32x4::from_array(b_array).as_m128(); let k: __mmask8 = 0xf3; - let src: __m128 = transmute([1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32]); + let src = f32x4::from_array([1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32]).as_m128(); let a: __m128bh = _mm_cvtne2ps_pbh(a1, a1); let b: __m128bh = _mm_cvtne2ps_pbh(b1, b1); let c: __m128 = _mm_maskz_dpbf16_ps(k, src, a, b); - let result: [f32; 4] = transmute(c.as_f32x4()); + let result = *c.as_f32x4().as_array(); let expected_result: [f32; 4] = [-18.0_f32, -52.0_f32, 0.0, 0.0]; assert_eq!(result, expected_result); let k: __mmask8 = 0xff; let c: __m128 = _mm_maskz_dpbf16_ps(k, src, a, b); - let result: [f32; 4] = transmute(c.as_f32x4()); + let result = *c.as_f32x4().as_array(); let expected_result: [f32; 4] = [-18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32]; assert_eq!(result, expected_result); let k: __mmask8 = 0; let c: __m128 = _mm_maskz_dpbf16_ps(k, src, a, b); - let result: [f32; 4] = transmute(c.as_f32x4()); + let result = *c.as_f32x4().as_array(); let expected_result: [f32; 4] = [0.0, 0.0, 0.0, 0.0]; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm256_dpbf16_ps() { + fn test_mm256_dpbf16_ps() { #[rustfmt::skip] let a_array = [ 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, @@ -1597,16 +1597,16 @@ mod tests { let b_array = [ -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, ]; - let a1: __m256 = transmute(a_array); - let b1: __m256 = transmute(b_array); + let a1 = f32x8::from_array(a_array).as_m256(); + let b1 = f32x8::from_array(b_array).as_m256(); #[rustfmt::skip] - let src: __m256 = transmute([ + let src = f32x8::from_array([ 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, - ]); + ]).as_m256(); let a: __m256bh = _mm256_cvtne2ps_pbh(a1, a1); let b: __m256bh = _mm256_cvtne2ps_pbh(b1, b1); let c: __m256 = _mm256_dpbf16_ps(src, a, b); - let result: [f32; 8] = transmute(c.as_f32x8()); + let result = *c.as_f32x8().as_array(); #[rustfmt::skip] let expected_result: [f32; 8] = [ -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, @@ -1615,7 +1615,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm256_mask_dpbf16_ps() { + fn test_mm256_mask_dpbf16_ps() { #[rustfmt::skip] let a_array = [ 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, @@ -1623,17 +1623,17 @@ mod tests { let b_array = [ -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, ]; - let a1: __m256 = transmute(a_array); - let b1: __m256 = transmute(b_array); + let a1 = f32x8::from_array(a_array).as_m256(); + let b1 = f32x8::from_array(b_array).as_m256(); let k: __mmask8 = 0x33; #[rustfmt::skip] - let src: __m256 = transmute([ + let src = f32x8::from_array([ 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, - ]); + ]).as_m256(); let a: __m256bh = _mm256_cvtne2ps_pbh(a1, a1); let b: __m256bh = _mm256_cvtne2ps_pbh(b1, b1); let c: __m256 = _mm256_mask_dpbf16_ps(src, k, a, b); - let result: [f32; 8] = transmute(c.as_f32x8()); + let result = *c.as_f32x8().as_array(); #[rustfmt::skip] let expected_result: [f32; 8] = [ -18.0_f32, -52.0_f32, 3.0_f32, 4.0_f32, -18.0_f32, -52.0_f32, 3.0_f32, 4.0_f32, @@ -1641,7 +1641,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask8 = 0xff; let c: __m256 = _mm256_mask_dpbf16_ps(src, k, a, b); - let result: [f32; 8] = transmute(c.as_f32x8()); + let result = *c.as_f32x8().as_array(); #[rustfmt::skip] let expected_result: [f32; 8] = [ -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, @@ -1649,7 +1649,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask8 = 0; let c: __m256 = _mm256_mask_dpbf16_ps(src, k, a, b); - let result: [f32; 8] = transmute(c.as_f32x8()); + let result = *c.as_f32x8().as_array(); #[rustfmt::skip] let expected_result: [f32; 8] = [ 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, @@ -1658,7 +1658,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm256_maskz_dpbf16_ps() { + fn test_mm256_maskz_dpbf16_ps() { #[rustfmt::skip] let a_array = [ 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, @@ -1666,17 +1666,17 @@ mod tests { let b_array = [ -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, ]; - let a1: __m256 = transmute(a_array); - let b1: __m256 = transmute(b_array); + let a1 = f32x8::from_array(a_array).as_m256(); + let b1 = f32x8::from_array(b_array).as_m256(); let k: __mmask8 = 0x33; #[rustfmt::skip] - let src: __m256 = transmute([ + let src = f32x8::from_array([ 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, - ]); + ]).as_m256(); let a: __m256bh = _mm256_cvtne2ps_pbh(a1, a1); let b: __m256bh = _mm256_cvtne2ps_pbh(b1, b1); let c: __m256 = _mm256_maskz_dpbf16_ps(k, src, a, b); - let result: [f32; 8] = transmute(c.as_f32x8()); + let result = *c.as_f32x8().as_array(); #[rustfmt::skip] let expected_result: [f32; 8] = [ -18.0_f32, -52.0_f32, 0.0, 0.0, -18.0_f32, -52.0_f32, 0.0, 0.0, @@ -1684,7 +1684,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask8 = 0xff; let c: __m256 = _mm256_maskz_dpbf16_ps(k, src, a, b); - let result: [f32; 8] = transmute(c.as_f32x8()); + let result = *c.as_f32x8().as_array(); #[rustfmt::skip] let expected_result: [f32; 8] = [ -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, @@ -1692,13 +1692,13 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask8 = 0; let c: __m256 = _mm256_maskz_dpbf16_ps(k, src, a, b); - let result: [f32; 8] = transmute(c.as_f32x8()); + let result = *c.as_f32x8().as_array(); let expected_result: [f32; 8] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]; assert_eq!(result, expected_result); } #[simd_test(enable = "avx512bf16,avx512f")] - unsafe fn test_mm512_dpbf16_ps() { + fn test_mm512_dpbf16_ps() { #[rustfmt::skip] let a_array = [ 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, @@ -1708,16 +1708,17 @@ mod tests { -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, ]; - let a1: __m512 = transmute(a_array); - let b1: __m512 = transmute(b_array); - let src: __m512 = transmute([ + let a1 = f32x16::from_array(a_array).as_m512(); + let b1 = f32x16::from_array(b_array).as_m512(); + let src = f32x16::from_array([ 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, - ]); + ]) + .as_m512(); let a: __m512bh = _mm512_cvtne2ps_pbh(a1, a1); let b: __m512bh = _mm512_cvtne2ps_pbh(b1, b1); let c: __m512 = _mm512_dpbf16_ps(src, a, b); - let result: [f32; 16] = transmute(c.as_f32x16()); + let result = *c.as_f32x16().as_array(); #[rustfmt::skip] let expected_result: [f32; 16] = [ -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, @@ -1727,7 +1728,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512f")] - unsafe fn test_mm512_mask_dpbf16_ps() { + fn test_mm512_mask_dpbf16_ps() { #[rustfmt::skip] let a_array = [ 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, @@ -1737,18 +1738,18 @@ mod tests { -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, ]; - let a1: __m512 = transmute(a_array); - let b1: __m512 = transmute(b_array); + let a1 = f32x16::from_array(a_array).as_m512(); + let b1 = f32x16::from_array(b_array).as_m512(); let k: __mmask16 = 0x3333; #[rustfmt::skip] - let src: __m512 = transmute([ + let src = f32x16::from_array([ 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, - ]); + ]).as_m512(); let a: __m512bh = _mm512_cvtne2ps_pbh(a1, a1); let b: __m512bh = _mm512_cvtne2ps_pbh(b1, b1); let c: __m512 = _mm512_mask_dpbf16_ps(src, k, a, b); - let result: [f32; 16] = transmute(c.as_f32x16()); + let result = *c.as_f32x16().as_array(); #[rustfmt::skip] let expected_result: [f32; 16] = [ -18.0_f32, -52.0_f32, 3.0_f32, 4.0_f32, -18.0_f32, -52.0_f32, 3.0_f32, 4.0_f32, @@ -1757,7 +1758,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask16 = 0xffff; let c: __m512 = _mm512_mask_dpbf16_ps(src, k, a, b); - let result: [f32; 16] = transmute(c.as_f32x16()); + let result = *c.as_f32x16().as_array(); #[rustfmt::skip] let expected_result: [f32; 16] = [ -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, @@ -1766,7 +1767,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask16 = 0; let c: __m512 = _mm512_mask_dpbf16_ps(src, k, a, b); - let result: [f32; 16] = transmute(c.as_f32x16()); + let result = *c.as_f32x16().as_array(); #[rustfmt::skip] let expected_result: [f32; 16] = [ 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, @@ -1776,7 +1777,7 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512f")] - unsafe fn test_mm512_maskz_dpbf16_ps() { + fn test_mm512_maskz_dpbf16_ps() { #[rustfmt::skip] let a_array = [ 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, 8.5_f32, 10.5_f32, 3.75_f32, 50.25_f32, @@ -1786,18 +1787,18 @@ mod tests { -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, -1.0_f32, ]; - let a1: __m512 = transmute(a_array); - let b1: __m512 = transmute(b_array); + let a1 = f32x16::from_array(a_array).as_m512(); + let b1 = f32x16::from_array(b_array).as_m512(); let k: __mmask16 = 0x3333; #[rustfmt::skip] - let src: __m512 = transmute([ + let src = f32x16::from_array([ 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, 1.0_f32, 2.0_f32, 3.0_f32, 4.0_f32, - ]); + ]).as_m512(); let a: __m512bh = _mm512_cvtne2ps_pbh(a1, a1); let b: __m512bh = _mm512_cvtne2ps_pbh(b1, b1); let c: __m512 = _mm512_maskz_dpbf16_ps(k, src, a, b); - let result: [f32; 16] = transmute(c.as_f32x16()); + let result = *c.as_f32x16().as_array(); #[rustfmt::skip] let expected_result: [f32; 16] = [ -18.0_f32, -52.0_f32, 0.0, 0.0, -18.0_f32, -52.0_f32, 0.0, 0.0, -18.0_f32, -52.0_f32, @@ -1806,7 +1807,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask16 = 0xffff; let c: __m512 = _mm512_maskz_dpbf16_ps(k, src, a, b); - let result: [f32; 16] = transmute(c.as_f32x16()); + let result = *c.as_f32x16().as_array(); #[rustfmt::skip] let expected_result: [f32; 16] = [ -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, -18.0_f32, -52.0_f32, -16.0_f32, -50.0_f32, @@ -1815,7 +1816,7 @@ mod tests { assert_eq!(result, expected_result); let k: __mmask16 = 0; let c: __m512 = _mm512_maskz_dpbf16_ps(k, src, a, b); - let result: [f32; 16] = transmute(c.as_f32x16()); + let result = *c.as_f32x16().as_array(); #[rustfmt::skip] let expected_result: [f32; 16] = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, @@ -1943,28 +1944,28 @@ mod tests { } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm_cvtneps_pbh() { + fn test_mm_cvtneps_pbh() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); - let r: u16x4 = transmute_copy(&_mm_cvtneps_pbh(a)); + let r: u16x4 = unsafe { transmute_copy(&_mm_cvtneps_pbh(a)) }; let e = u16x4::new(BF16_ONE, BF16_TWO, BF16_THREE, BF16_FOUR); assert_eq!(r, e); } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm_mask_cvtneps_pbh() { + fn test_mm_mask_cvtneps_pbh() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let src = __m128bh([5, 6, 7, 8, !0, !0, !0, !0]); let k = 0b1010; - let r: u16x4 = transmute_copy(&_mm_mask_cvtneps_pbh(src, k, a)); + let r: u16x4 = unsafe { transmute_copy(&_mm_mask_cvtneps_pbh(src, k, a)) }; let e = u16x4::new(5, BF16_TWO, 7, BF16_FOUR); assert_eq!(r, e); } #[simd_test(enable = "avx512bf16,avx512vl")] - unsafe fn test_mm_maskz_cvtneps_pbh() { + fn test_mm_maskz_cvtneps_pbh() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let k = 0b1010; - let r: u16x4 = transmute_copy(&_mm_maskz_cvtneps_pbh(k, a)); + let r: u16x4 = unsafe { transmute_copy(&_mm_maskz_cvtneps_pbh(k, a)) }; let e = u16x4::new(0, BF16_TWO, 0, BF16_FOUR); assert_eq!(r, e); } diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 6b4b88621efd..8e074fdcfa48 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -17098,37 +17098,37 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_loadu_epi16() { + const fn test_mm512_loadu_epi16() { #[rustfmt::skip] let a: [i16; 32] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]; - let r = _mm512_loadu_epi16(&a[0]); + let r = unsafe { _mm512_loadu_epi16(&a[0]) }; #[rustfmt::skip] let e = _mm512_set_epi16(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_loadu_epi16() { + const fn test_mm256_loadu_epi16() { let a: [i16; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; - let r = _mm256_loadu_epi16(&a[0]); + let r = unsafe { _mm256_loadu_epi16(&a[0]) }; let e = _mm256_set_epi16(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_loadu_epi16() { + const fn test_mm_loadu_epi16() { let a: [i16; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; - let r = _mm_loadu_epi16(&a[0]); + let r = unsafe { _mm_loadu_epi16(&a[0]) }; let e = _mm_set_epi16(8, 7, 6, 5, 4, 3, 2, 1); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_loadu_epi8() { + const fn test_mm512_loadu_epi8() { #[rustfmt::skip] let a: [i8; 64] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]; - let r = _mm512_loadu_epi8(&a[0]); + let r = unsafe { _mm512_loadu_epi8(&a[0]) }; #[rustfmt::skip] let e = _mm512_set_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); @@ -17136,73 +17136,85 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_loadu_epi8() { + const fn test_mm256_loadu_epi8() { #[rustfmt::skip] let a: [i8; 32] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]; - let r = _mm256_loadu_epi8(&a[0]); + let r = unsafe { _mm256_loadu_epi8(&a[0]) }; #[rustfmt::skip] let e = _mm256_set_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_loadu_epi8() { + const fn test_mm_loadu_epi8() { let a: [i8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; - let r = _mm_loadu_epi8(&a[0]); + let r = unsafe { _mm_loadu_epi8(&a[0]) }; let e = _mm_set_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_storeu_epi16() { + const fn test_mm512_storeu_epi16() { let a = _mm512_set1_epi16(9); let mut r = _mm512_undefined_epi32(); - _mm512_storeu_epi16(&mut r as *mut _ as *mut i16, a); + unsafe { + _mm512_storeu_epi16(&mut r as *mut _ as *mut i16, a); + } assert_eq_m512i(r, a); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_storeu_epi16() { + const fn test_mm256_storeu_epi16() { let a = _mm256_set1_epi16(9); let mut r = _mm256_set1_epi32(0); - _mm256_storeu_epi16(&mut r as *mut _ as *mut i16, a); + unsafe { + _mm256_storeu_epi16(&mut r as *mut _ as *mut i16, a); + } assert_eq_m256i(r, a); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_storeu_epi16() { + const fn test_mm_storeu_epi16() { let a = _mm_set1_epi16(9); let mut r = _mm_set1_epi32(0); - _mm_storeu_epi16(&mut r as *mut _ as *mut i16, a); + unsafe { + _mm_storeu_epi16(&mut r as *mut _ as *mut i16, a); + } assert_eq_m128i(r, a); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_storeu_epi8() { + const fn test_mm512_storeu_epi8() { let a = _mm512_set1_epi8(9); let mut r = _mm512_undefined_epi32(); - _mm512_storeu_epi8(&mut r as *mut _ as *mut i8, a); + unsafe { + _mm512_storeu_epi8(&mut r as *mut _ as *mut i8, a); + } assert_eq_m512i(r, a); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_storeu_epi8() { + const fn test_mm256_storeu_epi8() { let a = _mm256_set1_epi8(9); let mut r = _mm256_set1_epi32(0); - _mm256_storeu_epi8(&mut r as *mut _ as *mut i8, a); + unsafe { + _mm256_storeu_epi8(&mut r as *mut _ as *mut i8, a); + } assert_eq_m256i(r, a); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_storeu_epi8() { + const fn test_mm_storeu_epi8() { let a = _mm_set1_epi8(9); let mut r = _mm_set1_epi32(0); - _mm_storeu_epi8(&mut r as *mut _ as *mut i8, a); + unsafe { + _mm_storeu_epi8(&mut r as *mut _ as *mut i8, a); + } assert_eq_m128i(r, a); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_mask_loadu_epi16() { + const fn test_mm512_mask_loadu_epi16() { let src = _mm512_set1_epi16(42); let a = &[ 1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -17210,52 +17222,54 @@ mod tests { ]; let p = a.as_ptr(); let m = 0b10101010_11001100_11101000_11001010; - let r = _mm512_mask_loadu_epi16(src, m, black_box(p)); + let r = unsafe { _mm512_mask_loadu_epi16(src, m, black_box(p)) }; let e = &[ 42_i16, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, 42, 42, 19, 20, 42, 42, 23, 24, 42, 26, 42, 28, 42, 30, 42, 32, ]; - let e = _mm512_loadu_epi16(e.as_ptr()); + let e = unsafe { _mm512_loadu_epi16(e.as_ptr()) }; assert_eq_m512i(r, e); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_maskz_loadu_epi16() { + const fn test_mm512_maskz_loadu_epi16() { let a = &[ 1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ]; let p = a.as_ptr(); let m = 0b10101010_11001100_11101000_11001010; - let r = _mm512_maskz_loadu_epi16(m, black_box(p)); + let r = unsafe { _mm512_maskz_loadu_epi16(m, black_box(p)) }; let e = &[ 0_i16, 2, 0, 4, 0, 0, 7, 8, 0, 0, 0, 12, 0, 14, 15, 16, 0, 0, 19, 20, 0, 0, 23, 24, 0, 26, 0, 28, 0, 30, 0, 32, ]; - let e = _mm512_loadu_epi16(e.as_ptr()); + let e = unsafe { _mm512_loadu_epi16(e.as_ptr()) }; assert_eq_m512i(r, e); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_mask_storeu_epi16() { + const fn test_mm512_mask_storeu_epi16() { let mut r = [42_i16; 32]; let a = &[ 1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ]; - let a = _mm512_loadu_epi16(a.as_ptr()); + let a = unsafe { _mm512_loadu_epi16(a.as_ptr()) }; let m = 0b10101010_11001100_11101000_11001010; - _mm512_mask_storeu_epi16(r.as_mut_ptr(), m, a); + unsafe { + _mm512_mask_storeu_epi16(r.as_mut_ptr(), m, a); + } let e = &[ 42_i16, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, 42, 42, 19, 20, 42, 42, 23, 24, 42, 26, 42, 28, 42, 30, 42, 32, ]; - let e = _mm512_loadu_epi16(e.as_ptr()); - assert_eq_m512i(_mm512_loadu_epi16(r.as_ptr()), e); + let e = unsafe { _mm512_loadu_epi16(e.as_ptr()) }; + assert_eq_m512i(unsafe { _mm512_loadu_epi16(r.as_ptr()) }, e); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_mask_loadu_epi8() { + const fn test_mm512_mask_loadu_epi8() { let src = _mm512_set1_epi8(42); let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -17264,18 +17278,18 @@ mod tests { ]; let p = a.as_ptr(); let m = 0b00000000_11111111_11111111_00000000_10101010_11001100_11101000_11001010; - let r = _mm512_mask_loadu_epi8(src, m, black_box(p)); + let r = unsafe { _mm512_mask_loadu_epi8(src, m, black_box(p)) }; let e = &[ 42_i8, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, 42, 42, 19, 20, 42, 42, 23, 24, 42, 26, 42, 28, 42, 30, 42, 32, 42, 42, 42, 42, 42, 42, 42, 42, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 42, 42, 42, 42, 42, 42, 42, 42, ]; - let e = _mm512_loadu_epi8(e.as_ptr()); + let e = unsafe { _mm512_loadu_epi8(e.as_ptr()) }; assert_eq_m512i(r, e); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_maskz_loadu_epi8() { + const fn test_mm512_maskz_loadu_epi8() { let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, @@ -17283,77 +17297,81 @@ mod tests { ]; let p = a.as_ptr(); let m = 0b00000000_11111111_11111111_00000000_10101010_11001100_11101000_11001010; - let r = _mm512_maskz_loadu_epi8(m, black_box(p)); + let r = unsafe { _mm512_maskz_loadu_epi8(m, black_box(p)) }; let e = &[ 0_i8, 2, 0, 4, 0, 0, 7, 8, 0, 0, 0, 12, 0, 14, 15, 16, 0, 0, 19, 20, 0, 0, 23, 24, 0, 26, 0, 28, 0, 30, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 0, 0, 0, 0, 0, 0, 0, 0, ]; - let e = _mm512_loadu_epi8(e.as_ptr()); + let e = unsafe { _mm512_loadu_epi8(e.as_ptr()) }; assert_eq_m512i(r, e); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_mm512_mask_storeu_epi8() { + const fn test_mm512_mask_storeu_epi8() { let mut r = [42_i8; 64]; let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, ]; - let a = _mm512_loadu_epi8(a.as_ptr()); + let a = unsafe { _mm512_loadu_epi8(a.as_ptr()) }; let m = 0b00000000_11111111_11111111_00000000_10101010_11001100_11101000_11001010; - _mm512_mask_storeu_epi8(r.as_mut_ptr(), m, a); + unsafe { + _mm512_mask_storeu_epi8(r.as_mut_ptr(), m, a); + } let e = &[ 42_i8, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, 42, 42, 19, 20, 42, 42, 23, 24, 42, 26, 42, 28, 42, 30, 42, 32, 42, 42, 42, 42, 42, 42, 42, 42, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 42, 42, 42, 42, 42, 42, 42, 42, ]; - let e = _mm512_loadu_epi8(e.as_ptr()); - assert_eq_m512i(_mm512_loadu_epi8(r.as_ptr()), e); + let e = unsafe { _mm512_loadu_epi8(e.as_ptr()) }; + assert_eq_m512i(unsafe { _mm512_loadu_epi8(r.as_ptr()) }, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_mask_loadu_epi16() { + const fn test_mm256_mask_loadu_epi16() { let src = _mm256_set1_epi16(42); let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm256_mask_loadu_epi16(src, m, black_box(p)); + let r = unsafe { _mm256_mask_loadu_epi16(src, m, black_box(p)) }; let e = &[ 42_i16, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, ]; - let e = _mm256_loadu_epi16(e.as_ptr()); + let e = unsafe { _mm256_loadu_epi16(e.as_ptr()) }; assert_eq_m256i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_maskz_loadu_epi16() { + const fn test_mm256_maskz_loadu_epi16() { let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm256_maskz_loadu_epi16(m, black_box(p)); + let r = unsafe { _mm256_maskz_loadu_epi16(m, black_box(p)) }; let e = &[0_i16, 2, 0, 4, 0, 0, 7, 8, 0, 0, 0, 12, 0, 14, 15, 16]; - let e = _mm256_loadu_epi16(e.as_ptr()); + let e = unsafe { _mm256_loadu_epi16(e.as_ptr()) }; assert_eq_m256i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_mask_storeu_epi16() { + const fn test_mm256_mask_storeu_epi16() { let mut r = [42_i16; 16]; let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; - let a = _mm256_loadu_epi16(a.as_ptr()); + let a = unsafe { _mm256_loadu_epi16(a.as_ptr()) }; let m = 0b11101000_11001010; - _mm256_mask_storeu_epi16(r.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_storeu_epi16(r.as_mut_ptr(), m, a); + } let e = &[ 42_i16, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, ]; - let e = _mm256_loadu_epi16(e.as_ptr()); - assert_eq_m256i(_mm256_loadu_epi16(r.as_ptr()), e); + let e = unsafe { _mm256_loadu_epi16(e.as_ptr()) }; + assert_eq_m256i(unsafe { _mm256_loadu_epi16(r.as_ptr()) }, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_mask_loadu_epi8() { + const fn test_mm256_mask_loadu_epi8() { let src = _mm256_set1_epi8(42); let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -17361,122 +17379,124 @@ mod tests { ]; let p = a.as_ptr(); let m = 0b10101010_11001100_11101000_11001010; - let r = _mm256_mask_loadu_epi8(src, m, black_box(p)); + let r = unsafe { _mm256_mask_loadu_epi8(src, m, black_box(p)) }; let e = &[ 42_i8, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, 42, 42, 19, 20, 42, 42, 23, 24, 42, 26, 42, 28, 42, 30, 42, 32, ]; - let e = _mm256_loadu_epi8(e.as_ptr()); + let e = unsafe { _mm256_loadu_epi8(e.as_ptr()) }; assert_eq_m256i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_maskz_loadu_epi8() { + const fn test_mm256_maskz_loadu_epi8() { let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ]; let p = a.as_ptr(); let m = 0b10101010_11001100_11101000_11001010; - let r = _mm256_maskz_loadu_epi8(m, black_box(p)); + let r = unsafe { _mm256_maskz_loadu_epi8(m, black_box(p)) }; let e = &[ 0_i8, 2, 0, 4, 0, 0, 7, 8, 0, 0, 0, 12, 0, 14, 15, 16, 0, 0, 19, 20, 0, 0, 23, 24, 0, 26, 0, 28, 0, 30, 0, 32, ]; - let e = _mm256_loadu_epi8(e.as_ptr()); + let e = unsafe { _mm256_loadu_epi8(e.as_ptr()) }; assert_eq_m256i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm256_mask_storeu_epi8() { + const fn test_mm256_mask_storeu_epi8() { let mut r = [42_i8; 32]; let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ]; - let a = _mm256_loadu_epi8(a.as_ptr()); + let a = unsafe { _mm256_loadu_epi8(a.as_ptr()) }; let m = 0b10101010_11001100_11101000_11001010; - _mm256_mask_storeu_epi8(r.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_storeu_epi8(r.as_mut_ptr(), m, a); + } let e = &[ 42_i8, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, 42, 42, 19, 20, 42, 42, 23, 24, 42, 26, 42, 28, 42, 30, 42, 32, ]; - let e = _mm256_loadu_epi8(e.as_ptr()); - assert_eq_m256i(_mm256_loadu_epi8(r.as_ptr()), e); + let e = unsafe { _mm256_loadu_epi8(e.as_ptr()) }; + assert_eq_m256i(unsafe { _mm256_loadu_epi8(r.as_ptr()) }, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_mask_loadu_epi16() { + const fn test_mm_mask_loadu_epi16() { let src = _mm_set1_epi16(42); let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm_mask_loadu_epi16(src, m, black_box(p)); + let r = unsafe { _mm_mask_loadu_epi16(src, m, black_box(p)) }; let e = &[42_i16, 2, 42, 4, 42, 42, 7, 8]; - let e = _mm_loadu_epi16(e.as_ptr()); + let e = unsafe { _mm_loadu_epi16(e.as_ptr()) }; assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_maskz_loadu_epi16() { + const fn test_mm_maskz_loadu_epi16() { let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm_maskz_loadu_epi16(m, black_box(p)); + let r = unsafe { _mm_maskz_loadu_epi16(m, black_box(p)) }; let e = &[0_i16, 2, 0, 4, 0, 0, 7, 8]; - let e = _mm_loadu_epi16(e.as_ptr()); + let e = unsafe { _mm_loadu_epi16(e.as_ptr()) }; assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_mask_storeu_epi16() { + const fn test_mm_mask_storeu_epi16() { let mut r = [42_i16; 8]; let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8]; - let a = _mm_loadu_epi16(a.as_ptr()); + let a = unsafe { _mm_loadu_epi16(a.as_ptr()) }; let m = 0b11001010; - _mm_mask_storeu_epi16(r.as_mut_ptr(), m, a); + unsafe { _mm_mask_storeu_epi16(r.as_mut_ptr(), m, a) }; let e = &[42_i16, 2, 42, 4, 42, 42, 7, 8]; - let e = _mm_loadu_epi16(e.as_ptr()); - assert_eq_m128i(_mm_loadu_epi16(r.as_ptr()), e); + let e = unsafe { _mm_loadu_epi16(e.as_ptr()) }; + assert_eq_m128i(unsafe { _mm_loadu_epi16(r.as_ptr()) }, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_mask_loadu_epi8() { + const fn test_mm_mask_loadu_epi8() { let src = _mm_set1_epi8(42); let a = &[1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm_mask_loadu_epi8(src, m, black_box(p)); + let r = unsafe { _mm_mask_loadu_epi8(src, m, black_box(p)) }; let e = &[ 42_i8, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, ]; - let e = _mm_loadu_epi8(e.as_ptr()); + let e = unsafe { _mm_loadu_epi8(e.as_ptr()) }; assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_maskz_loadu_epi8() { + const fn test_mm_maskz_loadu_epi8() { let a = &[1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm_maskz_loadu_epi8(m, black_box(p)); + let r = unsafe { _mm_maskz_loadu_epi8(m, black_box(p)) }; let e = &[0_i8, 2, 0, 4, 0, 0, 7, 8, 0, 0, 0, 12, 0, 14, 15, 16]; - let e = _mm_loadu_epi8(e.as_ptr()); + let e = unsafe { _mm_loadu_epi8(e.as_ptr()) }; assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - const unsafe fn test_mm_mask_storeu_epi8() { + const fn test_mm_mask_storeu_epi8() { let mut r = [42_i8; 16]; let a = &[1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; - let a = _mm_loadu_epi8(a.as_ptr()); + let a = unsafe { _mm_loadu_epi8(a.as_ptr()) }; let m = 0b11101000_11001010; - _mm_mask_storeu_epi8(r.as_mut_ptr(), m, a); + unsafe { _mm_mask_storeu_epi8(r.as_mut_ptr(), m, a) }; let e = &[ 42_i8, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16, ]; - let e = _mm_loadu_epi8(e.as_ptr()); - assert_eq_m128i(_mm_loadu_epi8(r.as_ptr()), e); + let e = unsafe { _mm_loadu_epi8(e.as_ptr()) }; + assert_eq_m128i(unsafe { _mm_loadu_epi8(r.as_ptr()) }, e); } #[simd_test(enable = "avx512bw")] @@ -20714,36 +20734,40 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const unsafe fn test_store_mask64() { + const fn test_store_mask64() { let a: __mmask64 = 0b11111111_00000000_11111111_00000000_11111111_00000000_11111111_00000000; let mut r = 0; - _store_mask64(&mut r, a); + unsafe { + _store_mask64(&mut r, a); + } assert_eq!(r, a); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_store_mask32() { + const fn test_store_mask32() { let a: __mmask32 = 0b11111111_00000000_11111111_00000000; let mut r = 0; - _store_mask32(&mut r, a); + unsafe { + _store_mask32(&mut r, a); + } assert_eq!(r, a); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_load_mask64() { + const fn test_load_mask64() { let p: __mmask64 = 0b11111111_00000000_11111111_00000000_11111111_00000000_11111111_00000000; - let r = _load_mask64(&p); + let r = unsafe { _load_mask64(&p) }; let e: __mmask64 = 0b11111111_00000000_11111111_00000000_11111111_00000000_11111111_00000000; assert_eq!(r, e); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_load_mask32() { + const fn test_load_mask32() { let p: __mmask32 = 0b11111111_00000000_11111111_00000000; - let r = _load_mask32(&p); + let r = unsafe { _load_mask32(&p) }; let e: __mmask32 = 0b11111111_00000000_11111111_00000000; assert_eq!(r, e); } @@ -21163,21 +21187,21 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const unsafe fn test_kortest_mask32_u8() { + const fn test_kortest_mask32_u8() { let a: __mmask32 = 0b0110100101101001_0110100101101001; let b: __mmask32 = 0b1011011010110110_1011011010110110; let mut all_ones: u8 = 0; - let r = _kortest_mask32_u8(a, b, &mut all_ones); + let r = unsafe { _kortest_mask32_u8(a, b, &mut all_ones) }; assert_eq!(r, 0); assert_eq!(all_ones, 1); } #[simd_test(enable = "avx512bw")] - const unsafe fn test_kortest_mask64_u8() { + const fn test_kortest_mask64_u8() { let a: __mmask64 = 0b0110100101101001_0110100101101001; let b: __mmask64 = 0b1011011010110110_1011011010110110; let mut all_ones: u8 = 0; - let r = _kortest_mask64_u8(a, b, &mut all_ones); + let r = unsafe { _kortest_mask64_u8(a, b, &mut all_ones) }; assert_eq!(r, 0); assert_eq!(all_ones, 0); } @@ -21299,11 +21323,11 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const unsafe fn test_ktest_mask32_u8() { + const fn test_ktest_mask32_u8() { let a: __mmask32 = 0b0110100100111100_0110100100111100; let b: __mmask32 = 0b1001011011000011_1001011011000011; let mut and_not: u8 = 0; - let r = _ktest_mask32_u8(a, b, &mut and_not); + let r = unsafe { _ktest_mask32_u8(a, b, &mut and_not) }; assert_eq!(r, 1); assert_eq!(and_not, 0); } @@ -21325,11 +21349,11 @@ mod tests { } #[simd_test(enable = "avx512bw")] - const unsafe fn test_ktest_mask64_u8() { + const fn test_ktest_mask64_u8() { let a: __mmask64 = 0b0110100100111100_0110100100111100; let b: __mmask64 = 0b1001011011000011_1001011011000011; let mut and_not: u8 = 0; - let r = _ktest_mask64_u8(a, b, &mut and_not); + let r = unsafe { _ktest_mask64_u8(a, b, &mut and_not) }; assert_eq!(r, 1); assert_eq!(and_not, 0); } @@ -21951,32 +21975,38 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cvtsepi16_storeu_epi8() { + fn test_mm512_mask_cvtsepi16_storeu_epi8() { let a = _mm512_set1_epi16(i16::MAX); let mut r = _mm256_undefined_si256(); - _mm512_mask_cvtsepi16_storeu_epi8( - &mut r as *mut _ as *mut i8, - 0b11111111_11111111_11111111_11111111, - a, - ); + unsafe { + _mm512_mask_cvtsepi16_storeu_epi8( + &mut r as *mut _ as *mut i8, + 0b11111111_11111111_11111111_11111111, + a, + ); + } let e = _mm256_set1_epi8(i8::MAX); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cvtsepi16_storeu_epi8() { + fn test_mm256_mask_cvtsepi16_storeu_epi8() { let a = _mm256_set1_epi16(i16::MAX); let mut r = _mm_undefined_si128(); - _mm256_mask_cvtsepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + unsafe { + _mm256_mask_cvtsepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + } let e = _mm_set1_epi8(i8::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cvtsepi16_storeu_epi8() { + fn test_mm_mask_cvtsepi16_storeu_epi8() { let a = _mm_set1_epi16(i16::MAX); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtsepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm_mask_cvtsepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, @@ -21986,63 +22016,75 @@ mod tests { } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cvtepi16_storeu_epi8() { + fn test_mm512_mask_cvtepi16_storeu_epi8() { let a = _mm512_set1_epi16(8); let mut r = _mm256_undefined_si256(); - _mm512_mask_cvtepi16_storeu_epi8( - &mut r as *mut _ as *mut i8, - 0b11111111_11111111_11111111_11111111, - a, - ); + unsafe { + _mm512_mask_cvtepi16_storeu_epi8( + &mut r as *mut _ as *mut i8, + 0b11111111_11111111_11111111_11111111, + a, + ); + } let e = _mm256_set1_epi8(8); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cvtepi16_storeu_epi8() { + fn test_mm256_mask_cvtepi16_storeu_epi8() { let a = _mm256_set1_epi16(8); let mut r = _mm_undefined_si128(); - _mm256_mask_cvtepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + unsafe { + _mm256_mask_cvtepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + } let e = _mm_set1_epi8(8); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cvtepi16_storeu_epi8() { + fn test_mm_mask_cvtepi16_storeu_epi8() { let a = _mm_set1_epi16(8); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm_mask_cvtepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } let e = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw")] - unsafe fn test_mm512_mask_cvtusepi16_storeu_epi8() { + fn test_mm512_mask_cvtusepi16_storeu_epi8() { let a = _mm512_set1_epi16(i16::MAX); let mut r = _mm256_undefined_si256(); - _mm512_mask_cvtusepi16_storeu_epi8( - &mut r as *mut _ as *mut i8, - 0b11111111_11111111_11111111_11111111, - a, - ); + unsafe { + _mm512_mask_cvtusepi16_storeu_epi8( + &mut r as *mut _ as *mut i8, + 0b11111111_11111111_11111111_11111111, + a, + ); + } let e = _mm256_set1_epi8(u8::MAX as i8); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm256_mask_cvtusepi16_storeu_epi8() { + fn test_mm256_mask_cvtusepi16_storeu_epi8() { let a = _mm256_set1_epi16(i16::MAX); let mut r = _mm_undefined_si128(); - _mm256_mask_cvtusepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + unsafe { + _mm256_mask_cvtusepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + } let e = _mm_set1_epi8(u8::MAX as i8); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512bw,avx512vl")] - unsafe fn test_mm_mask_cvtusepi16_storeu_epi8() { + fn test_mm_mask_cvtusepi16_storeu_epi8() { let a = _mm_set1_epi16(i16::MAX); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtusepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm_mask_cvtusepi16_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, diff --git a/library/stdarch/crates/core_arch/src/x86/avx512dq.rs b/library/stdarch/crates/core_arch/src/x86/avx512dq.rs index ebe75cd22d8e..9e1a4c0b2955 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512dq.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512dq.rs @@ -7401,27 +7401,25 @@ unsafe extern "C" { mod tests { use super::*; use crate::core_arch::assert_eq_const as assert_eq; + use crate::core_arch::x86::*; use stdarch_test::simd_test; - use crate::core_arch::x86::*; - use crate::mem::transmute; + const OPRND1_64: f64 = f64::from_bits(0x3333333333333333); + const OPRND2_64: f64 = f64::from_bits(0x5555555555555555); - const OPRND1_64: f64 = unsafe { transmute(0x3333333333333333_u64) }; - const OPRND2_64: f64 = unsafe { transmute(0x5555555555555555_u64) }; + const AND_64: f64 = f64::from_bits(0x1111111111111111); + const ANDN_64: f64 = f64::from_bits(0x4444444444444444); + const OR_64: f64 = f64::from_bits(0x7777777777777777); + const XOR_64: f64 = f64::from_bits(0x6666666666666666); - const AND_64: f64 = unsafe { transmute(0x1111111111111111_u64) }; - const ANDN_64: f64 = unsafe { transmute(0x4444444444444444_u64) }; - const OR_64: f64 = unsafe { transmute(0x7777777777777777_u64) }; - const XOR_64: f64 = unsafe { transmute(0x6666666666666666_u64) }; + const OPRND1_32: f32 = f32::from_bits(0x33333333); + const OPRND2_32: f32 = f32::from_bits(0x55555555); - const OPRND1_32: f32 = unsafe { transmute(0x33333333_u32) }; - const OPRND2_32: f32 = unsafe { transmute(0x55555555_u32) }; - - const AND_32: f32 = unsafe { transmute(0x11111111_u32) }; - const ANDN_32: f32 = unsafe { transmute(0x44444444_u32) }; - const OR_32: f32 = unsafe { transmute(0x77777777_u32) }; - const XOR_32: f32 = unsafe { transmute(0x66666666_u32) }; + const AND_32: f32 = f32::from_bits(0x11111111); + const ANDN_32: f32 = f32::from_bits(0x44444444); + const OR_32: f32 = f32::from_bits(0x77777777); + const XOR_32: f32 = f32::from_bits(0x66666666); #[simd_test(enable = "avx512dq,avx512vl")] const fn test_mm_mask_and_pd() { @@ -10023,11 +10021,11 @@ mod tests { } #[simd_test(enable = "avx512dq")] - const unsafe fn test_kortest_mask8_u8() { + const fn test_kortest_mask8_u8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10110110; let mut all_ones: u8 = 0; - let r = _kortest_mask8_u8(a, b, &mut all_ones); + let r = unsafe { _kortest_mask8_u8(a, b, &mut all_ones) }; assert_eq!(r, 0); assert_eq!(all_ones, 1); } @@ -10049,7 +10047,7 @@ mod tests { } #[simd_test(enable = "avx512dq")] - const unsafe fn test_kshiftli_mask8() { + const fn test_kshiftli_mask8() { let a: __mmask8 = 0b01101001; let r = _kshiftli_mask8::<3>(a); let e: __mmask8 = 0b01001000; @@ -10089,11 +10087,11 @@ mod tests { } #[simd_test(enable = "avx512dq")] - const unsafe fn test_ktest_mask8_u8() { + const fn test_ktest_mask8_u8() { let a: __mmask8 = 0b01101001; let b: __mmask8 = 0b10010110; let mut and_not: u8 = 0; - let r = _ktest_mask8_u8(a, b, &mut and_not); + let r = unsafe { _ktest_mask8_u8(a, b, &mut and_not) }; assert_eq!(r, 1); assert_eq!(and_not, 0); } @@ -10115,11 +10113,11 @@ mod tests { } #[simd_test(enable = "avx512dq")] - const unsafe fn test_ktest_mask16_u8() { + const fn test_ktest_mask16_u8() { let a: __mmask16 = 0b0110100100111100; let b: __mmask16 = 0b1001011011000011; let mut and_not: u8 = 0; - let r = _ktest_mask16_u8(a, b, &mut and_not); + let r = unsafe { _ktest_mask16_u8(a, b, &mut and_not) }; assert_eq!(r, 1); assert_eq!(and_not, 0); } @@ -10141,18 +10139,20 @@ mod tests { } #[simd_test(enable = "avx512dq")] - const unsafe fn test_load_mask8() { + const fn test_load_mask8() { let a: __mmask8 = 0b01101001; - let r = _load_mask8(&a); + let r = unsafe { _load_mask8(&a) }; let e: __mmask8 = 0b01101001; assert_eq!(r, e); } #[simd_test(enable = "avx512dq")] - const unsafe fn test_store_mask8() { + const fn test_store_mask8() { let a: __mmask8 = 0b01101001; let mut r = 0; - _store_mask8(&mut r, a); + unsafe { + _store_mask8(&mut r, a); + } let e: __mmask8 = 0b01101001; assert_eq!(r, e); } diff --git a/library/stdarch/crates/core_arch/src/x86/avx512f.rs b/library/stdarch/crates/core_arch/src/x86/avx512f.rs index 76b753938383..3730496e1ec3 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512f.rs @@ -48062,9 +48062,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_ternarylogic_epi32() { - use core::intrinsics::simd::simd_xor; - + fn test_mm512_ternarylogic_epi32() { let a = _mm512_set4_epi32(0b100, 0b110, 0b001, 0b101); let b = _mm512_set4_epi32(0b010, 0b011, 0b001, 0b110); let c = _mm512_set4_epi32(0b001, 0b000, 0b001, 0b111); @@ -48077,7 +48075,7 @@ mod tests { let r = _mm512_ternarylogic_epi32::<0b10010110>(a, b, c); let e = _mm512_set4_epi32(0b111, 0b101, 0b001, 0b100); assert_eq_m512i(r, e); - assert_eq_m512i(r, simd_xor(simd_xor(a, b), c)); + assert_eq_m512i(r, _mm512_xor_si512(_mm512_xor_si512(a, b), c)); // Majority (2 or more bits set). let r = _mm512_ternarylogic_epi32::<0b1110_1000>(a, b, c); @@ -48110,9 +48108,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_ternarylogic_epi32() { - use core::intrinsics::simd::simd_xor; - + fn test_mm256_ternarylogic_epi32() { let _mm256_set4_epi32 = |a, b, c, d| _mm256_setr_epi32(a, b, c, d, a, b, c, d); let a = _mm256_set4_epi32(0b100, 0b110, 0b001, 0b101); @@ -48127,7 +48123,7 @@ mod tests { let r = _mm256_ternarylogic_epi32::<0b10010110>(a, b, c); let e = _mm256_set4_epi32(0b111, 0b101, 0b001, 0b100); assert_eq_m256i(r, e); - assert_eq_m256i(r, simd_xor(simd_xor(a, b), c)); + assert_eq_m256i(r, _mm256_xor_si256(_mm256_xor_si256(a, b), c)); // Majority (2 or more bits set). let r = _mm256_ternarylogic_epi32::<0b1110_1000>(a, b, c); @@ -48160,9 +48156,7 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_ternarylogic_epi32() { - use core::intrinsics::simd::simd_xor; - + fn test_mm_ternarylogic_epi32() { let a = _mm_setr_epi32(0b100, 0b110, 0b001, 0b101); let b = _mm_setr_epi32(0b010, 0b011, 0b001, 0b110); let c = _mm_setr_epi32(0b001, 0b000, 0b001, 0b111); @@ -48175,7 +48169,7 @@ mod tests { let r = _mm_ternarylogic_epi32::<0b10010110>(a, b, c); let e = _mm_setr_epi32(0b111, 0b101, 0b001, 0b100); assert_eq_m128i(r, e); - assert_eq_m128i(r, simd_xor(simd_xor(a, b), c)); + assert_eq_m128i(r, _mm_xor_si128(_mm_xor_si128(a, b), c)); // Majority (2 or more bits set). let r = _mm_ternarylogic_epi32::<0b1110_1000>(a, b, c); @@ -51447,20 +51441,20 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32gather_ps() { + fn test_mm512_i32gather_ps() { let arr: [f32; 256] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing #[rustfmt::skip] let index = _mm512_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112, 120, 128, 136, 144, 152, 160, 168, 176); - let r = _mm512_i32gather_ps::<4>(index, arr.as_ptr()); + let r = unsafe { _mm512_i32gather_ps::<4>(index, arr.as_ptr()) }; #[rustfmt::skip] assert_eq_m512(r, _mm512_setr_ps(0., 16., 32., 48., 64., 80., 96., 112., 120., 128., 136., 144., 152., 160., 168., 176.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32gather_ps() { + fn test_mm512_mask_i32gather_ps() { let arr: [f32; 256] = core::array::from_fn(|i| i as f32); let src = _mm512_set1_ps(2.); let mask = 0b10101010_10101010; @@ -51468,27 +51462,27 @@ mod tests { let index = _mm512_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112, 120, 128, 136, 144, 152, 160, 168, 176); // A multiplier of 4 is word-addressing - let r = _mm512_mask_i32gather_ps::<4>(src, mask, index, arr.as_ptr()); + let r = unsafe { _mm512_mask_i32gather_ps::<4>(src, mask, index, arr.as_ptr()) }; #[rustfmt::skip] assert_eq_m512(r, _mm512_setr_ps(2., 16., 2., 48., 2., 80., 2., 112., 2., 128., 2., 144., 2., 160., 2., 176.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32gather_epi32() { + fn test_mm512_i32gather_epi32() { let arr: [i32; 256] = core::array::from_fn(|i| i as i32); // A multiplier of 4 is word-addressing #[rustfmt::skip] let index = _mm512_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112, 120, 128, 136, 144, 152, 160, 168, 176); - let r = _mm512_i32gather_epi32::<4>(index, arr.as_ptr()); + let r = unsafe { _mm512_i32gather_epi32::<4>(index, arr.as_ptr()) }; #[rustfmt::skip] assert_eq_m512i(r, _mm512_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112, 120, 128, 136, 144, 152, 160, 168, 176)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32gather_epi32() { + fn test_mm512_mask_i32gather_epi32() { let arr: [i32; 256] = core::array::from_fn(|i| i as i32); let src = _mm512_set1_epi32(2); let mask = 0b10101010_10101010; @@ -51496,7 +51490,7 @@ mod tests { 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, ); // A multiplier of 4 is word-addressing - let r = _mm512_mask_i32gather_epi32::<4>(src, mask, index, arr.as_ptr()); + let r = unsafe { _mm512_mask_i32gather_epi32::<4>(src, mask, index, arr.as_ptr()) }; assert_eq_m512i( r, _mm512_setr_epi32(2, 16, 2, 48, 2, 80, 2, 112, 2, 144, 2, 176, 2, 208, 2, 240), @@ -51504,7 +51498,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32scatter_ps() { + fn test_mm512_i32scatter_ps() { let mut arr = [0f32; 256]; #[rustfmt::skip] let index = _mm512_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112, @@ -51513,7 +51507,9 @@ mod tests { 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); // A multiplier of 4 is word-addressing - _mm512_i32scatter_ps::<4>(arr.as_mut_ptr(), index, src); + unsafe { + _mm512_i32scatter_ps::<4>(arr.as_mut_ptr(), index, src); + } let mut expected = [0f32; 256]; for i in 0..16 { expected[i * 16] = (i + 1) as f32; @@ -51522,7 +51518,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32scatter_ps() { + fn test_mm512_mask_i32scatter_ps() { let mut arr = [0f32; 256]; let mask = 0b10101010_10101010; #[rustfmt::skip] @@ -51532,7 +51528,9 @@ mod tests { 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ); // A multiplier of 4 is word-addressing - _mm512_mask_i32scatter_ps::<4>(arr.as_mut_ptr(), mask, index, src); + unsafe { + _mm512_mask_i32scatter_ps::<4>(arr.as_mut_ptr(), mask, index, src); + } let mut expected = [0f32; 256]; for i in 0..8 { expected[i * 32 + 16] = 2. * (i + 1) as f32; @@ -51541,7 +51539,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32scatter_epi32() { + fn test_mm512_i32scatter_epi32() { let mut arr = [0i32; 256]; #[rustfmt::skip] @@ -51549,7 +51547,9 @@ mod tests { 128, 144, 160, 176, 192, 208, 224, 240); let src = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); // A multiplier of 4 is word-addressing - _mm512_i32scatter_epi32::<4>(arr.as_mut_ptr(), index, src); + unsafe { + _mm512_i32scatter_epi32::<4>(arr.as_mut_ptr(), index, src); + } let mut expected = [0i32; 256]; for i in 0..16 { expected[i * 16] = (i + 1) as i32; @@ -51558,7 +51558,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32scatter_epi32() { + fn test_mm512_mask_i32scatter_epi32() { let mut arr = [0i32; 256]; let mask = 0b10101010_10101010; #[rustfmt::skip] @@ -51566,7 +51566,9 @@ mod tests { 128, 144, 160, 176, 192, 208, 224, 240); let src = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); // A multiplier of 4 is word-addressing - _mm512_mask_i32scatter_epi32::<4>(arr.as_mut_ptr(), mask, index, src); + unsafe { + _mm512_mask_i32scatter_epi32::<4>(arr.as_mut_ptr(), mask, index, src); + } let mut expected = [0i32; 256]; for i in 0..8 { expected[i * 32 + 16] = 2 * (i + 1) as i32; @@ -52850,29 +52852,31 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_loadu_pd() { + const fn test_mm512_loadu_pd() { let a = &[4., 3., 2., 5., 8., 9., 64., 50.]; let p = a.as_ptr(); - let r = _mm512_loadu_pd(black_box(p)); + let r = unsafe { _mm512_loadu_pd(black_box(p)) }; let e = _mm512_setr_pd(4., 3., 2., 5., 8., 9., 64., 50.); assert_eq_m512d(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_storeu_pd() { + const fn test_mm512_storeu_pd() { let a = _mm512_set1_pd(9.); let mut r = _mm512_undefined_pd(); - _mm512_storeu_pd(&mut r as *mut _ as *mut f64, a); + unsafe { + _mm512_storeu_pd(&mut r as *mut _ as *mut f64, a); + } assert_eq_m512d(r, a); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_loadu_ps() { + const fn test_mm512_loadu_ps() { let a = &[ 4., 3., 2., 5., 8., 9., 64., 50., -4., -3., -2., -5., -8., -9., -64., -50., ]; let p = a.as_ptr(); - let r = _mm512_loadu_ps(black_box(p)); + let r = unsafe { _mm512_loadu_ps(black_box(p)) }; let e = _mm512_setr_ps( 4., 3., 2., 5., 8., 9., 64., 50., -4., -3., -2., -5., -8., -9., -64., -50., ); @@ -52880,36 +52884,38 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_storeu_ps() { + const fn test_mm512_storeu_ps() { let a = _mm512_set1_ps(9.); let mut r = _mm512_undefined_ps(); - _mm512_storeu_ps(&mut r as *mut _ as *mut f32, a); + unsafe { + _mm512_storeu_ps(&mut r as *mut _ as *mut f32, a); + } assert_eq_m512(r, a); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_loadu_epi32() { + const fn test_mm512_mask_loadu_epi32() { let src = _mm512_set1_epi32(42); let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_mask_loadu_epi32(src, m, black_box(p)); + let r = unsafe { _mm512_mask_loadu_epi32(src, m, black_box(p)) }; let e = _mm512_setr_epi32(42, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_maskz_loadu_epi32() { + const fn test_mm512_maskz_loadu_epi32() { let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_maskz_loadu_epi32(m, black_box(p)); + let r = unsafe { _mm512_maskz_loadu_epi32(m, black_box(p)) }; let e = _mm512_setr_epi32(0, 2, 0, 4, 0, 0, 7, 8, 0, 0, 0, 12, 0, 14, 15, 16); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_load_epi32() { + const fn test_mm512_mask_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 16], // 64 bytes @@ -52920,13 +52926,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_mask_load_epi32(src, m, black_box(p)); + let r = unsafe { _mm512_mask_load_epi32(src, m, black_box(p)) }; let e = _mm512_setr_epi32(42, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_maskz_load_epi32() { + const fn test_mm512_maskz_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 16], // 64 bytes @@ -52936,23 +52942,25 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_maskz_load_epi32(m, black_box(p)); + let r = unsafe { _mm512_maskz_load_epi32(m, black_box(p)) }; let e = _mm512_setr_epi32(0, 2, 0, 4, 0, 0, 7, 8, 0, 0, 0, 12, 0, 14, 15, 16); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_storeu_epi32() { + const fn test_mm512_mask_storeu_epi32() { let mut r = [42_i32; 16]; let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let m = 0b11101000_11001010; - _mm512_mask_storeu_epi32(r.as_mut_ptr(), m, a); + unsafe { + _mm512_mask_storeu_epi32(r.as_mut_ptr(), m, a); + } let e = _mm512_setr_epi32(42, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16); - assert_eq_m512i(_mm512_loadu_epi32(r.as_ptr()), e); + assert_eq_m512i(unsafe { _mm512_loadu_epi32(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_store_epi32() { + const fn test_mm512_mask_store_epi32() { #[repr(align(64))] struct Align { data: [i32; 16], @@ -52960,34 +52968,36 @@ mod tests { let mut r = Align { data: [42; 16] }; let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let m = 0b11101000_11001010; - _mm512_mask_store_epi32(r.data.as_mut_ptr(), m, a); + unsafe { + _mm512_mask_store_epi32(r.data.as_mut_ptr(), m, a); + } let e = _mm512_setr_epi32(42, 2, 42, 4, 42, 42, 7, 8, 42, 42, 42, 12, 42, 14, 15, 16); - assert_eq_m512i(_mm512_load_epi32(r.data.as_ptr()), e); + assert_eq_m512i(unsafe { _mm512_load_epi32(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_loadu_epi64() { + const fn test_mm512_mask_loadu_epi64() { let src = _mm512_set1_epi64(42); let a = &[1_i64, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm512_mask_loadu_epi64(src, m, black_box(p)); + let r = unsafe { _mm512_mask_loadu_epi64(src, m, black_box(p)) }; let e = _mm512_setr_epi64(42, 2, 42, 4, 42, 42, 7, 8); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_maskz_loadu_epi64() { + const fn test_mm512_maskz_loadu_epi64() { let a = &[1_i64, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm512_maskz_loadu_epi64(m, black_box(p)); + let r = unsafe { _mm512_maskz_loadu_epi64(m, black_box(p)) }; let e = _mm512_setr_epi64(0, 2, 0, 4, 0, 0, 7, 8); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_load_epi64() { + const fn test_mm512_mask_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 8], // 64 bytes @@ -52998,13 +53008,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11001010; - let r = _mm512_mask_load_epi64(src, m, black_box(p)); + let r = unsafe { _mm512_mask_load_epi64(src, m, black_box(p)) }; let e = _mm512_setr_epi64(42, 2, 42, 4, 42, 42, 7, 8); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_maskz_load_epi64() { + const fn test_mm512_maskz_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 8], // 64 bytes @@ -53014,23 +53024,25 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11001010; - let r = _mm512_maskz_load_epi64(m, black_box(p)); + let r = unsafe { _mm512_maskz_load_epi64(m, black_box(p)) }; let e = _mm512_setr_epi64(0, 2, 0, 4, 0, 0, 7, 8); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_storeu_epi64() { + const fn test_mm512_mask_storeu_epi64() { let mut r = [42_i64; 8]; let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let m = 0b11001010; - _mm512_mask_storeu_epi64(r.as_mut_ptr(), m, a); + unsafe { + _mm512_mask_storeu_epi64(r.as_mut_ptr(), m, a); + } let e = _mm512_setr_epi64(42, 2, 42, 4, 42, 42, 7, 8); - assert_eq_m512i(_mm512_loadu_epi64(r.as_ptr()), e); + assert_eq_m512i(unsafe { _mm512_loadu_epi64(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_store_epi64() { + const fn test_mm512_mask_store_epi64() { #[repr(align(64))] struct Align { data: [i64; 8], @@ -53039,13 +53051,15 @@ mod tests { let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let m = 0b11001010; let p = r.data.as_mut_ptr(); - _mm512_mask_store_epi64(p, m, a); + unsafe { + _mm512_mask_store_epi64(p, m, a); + } let e = _mm512_setr_epi64(42, 2, 42, 4, 42, 42, 7, 8); - assert_eq_m512i(_mm512_load_epi64(r.data.as_ptr()), e); + assert_eq_m512i(unsafe { _mm512_load_epi64(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_loadu_ps() { + const fn test_mm512_mask_loadu_ps() { let src = _mm512_set1_ps(42.0); let a = &[ 1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, @@ -53053,7 +53067,7 @@ mod tests { ]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_mask_loadu_ps(src, m, black_box(p)); + let r = unsafe { _mm512_mask_loadu_ps(src, m, black_box(p)) }; let e = _mm512_setr_ps( 42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0, 42.0, 42.0, 42.0, 12.0, 42.0, 14.0, 15.0, 16.0, @@ -53062,14 +53076,14 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_maskz_loadu_ps() { + const fn test_mm512_maskz_loadu_ps() { let a = &[ 1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_maskz_loadu_ps(m, black_box(p)); + let r = unsafe { _mm512_maskz_loadu_ps(m, black_box(p)) }; let e = _mm512_setr_ps( 0.0, 2.0, 0.0, 4.0, 0.0, 0.0, 7.0, 8.0, 0.0, 0.0, 0.0, 12.0, 0.0, 14.0, 15.0, 16.0, ); @@ -53077,7 +53091,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_load_ps() { + const fn test_mm512_mask_load_ps() { #[repr(align(64))] struct Align { data: [f32; 16], // 64 bytes @@ -53091,7 +53105,7 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_mask_load_ps(src, m, black_box(p)); + let r = unsafe { _mm512_mask_load_ps(src, m, black_box(p)) }; let e = _mm512_setr_ps( 42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0, 42.0, 42.0, 42.0, 12.0, 42.0, 14.0, 15.0, 16.0, @@ -53100,7 +53114,7 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_maskz_load_ps() { + const fn test_mm512_maskz_load_ps() { #[repr(align(64))] struct Align { data: [f32; 16], // 64 bytes @@ -53113,7 +53127,7 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_maskz_load_ps(m, black_box(p)); + let r = unsafe { _mm512_maskz_load_ps(m, black_box(p)) }; let e = _mm512_setr_ps( 0.0, 2.0, 0.0, 4.0, 0.0, 0.0, 7.0, 8.0, 0.0, 0.0, 0.0, 12.0, 0.0, 14.0, 15.0, 16.0, ); @@ -53121,22 +53135,24 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_storeu_ps() { + const fn test_mm512_mask_storeu_ps() { let mut r = [42_f32; 16]; let a = _mm512_setr_ps( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); let m = 0b11101000_11001010; - _mm512_mask_storeu_ps(r.as_mut_ptr(), m, a); + unsafe { + _mm512_mask_storeu_ps(r.as_mut_ptr(), m, a); + } let e = _mm512_setr_ps( 42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0, 42.0, 42.0, 42.0, 12.0, 42.0, 14.0, 15.0, 16.0, ); - assert_eq_m512(_mm512_loadu_ps(r.as_ptr()), e); + assert_eq_m512(unsafe { _mm512_loadu_ps(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_store_ps() { + const fn test_mm512_mask_store_ps() { #[repr(align(64))] struct Align { data: [f32; 16], @@ -53146,37 +53162,39 @@ mod tests { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); let m = 0b11101000_11001010; - _mm512_mask_store_ps(r.data.as_mut_ptr(), m, a); + unsafe { + _mm512_mask_store_ps(r.data.as_mut_ptr(), m, a); + } let e = _mm512_setr_ps( 42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0, 42.0, 42.0, 42.0, 12.0, 42.0, 14.0, 15.0, 16.0, ); - assert_eq_m512(_mm512_load_ps(r.data.as_ptr()), e); + assert_eq_m512(unsafe { _mm512_load_ps(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_loadu_pd() { + const fn test_mm512_mask_loadu_pd() { let src = _mm512_set1_pd(42.0); let a = &[1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm512_mask_loadu_pd(src, m, black_box(p)); + let r = unsafe { _mm512_mask_loadu_pd(src, m, black_box(p)) }; let e = _mm512_setr_pd(42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0); assert_eq_m512d(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_maskz_loadu_pd() { + const fn test_mm512_maskz_loadu_pd() { let a = &[1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm512_maskz_loadu_pd(m, black_box(p)); + let r = unsafe { _mm512_maskz_loadu_pd(m, black_box(p)) }; let e = _mm512_setr_pd(0.0, 2.0, 0.0, 4.0, 0.0, 0.0, 7.0, 8.0); assert_eq_m512d(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_load_pd() { + const fn test_mm512_mask_load_pd() { #[repr(align(64))] struct Align { data: [f64; 8], // 64 bytes @@ -53187,13 +53205,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11001010; - let r = _mm512_mask_load_pd(src, m, black_box(p)); + let r = unsafe { _mm512_mask_load_pd(src, m, black_box(p)) }; let e = _mm512_setr_pd(42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0); assert_eq_m512d(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_maskz_load_pd() { + const fn test_mm512_maskz_load_pd() { #[repr(align(64))] struct Align { data: [f64; 8], // 64 bytes @@ -53203,23 +53221,25 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11001010; - let r = _mm512_maskz_load_pd(m, black_box(p)); + let r = unsafe { _mm512_maskz_load_pd(m, black_box(p)) }; let e = _mm512_setr_pd(0.0, 2.0, 0.0, 4.0, 0.0, 0.0, 7.0, 8.0); assert_eq_m512d(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_storeu_pd() { + const fn test_mm512_mask_storeu_pd() { let mut r = [42_f64; 8]; let a = _mm512_setr_pd(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let m = 0b11001010; - _mm512_mask_storeu_pd(r.as_mut_ptr(), m, a); + unsafe { + _mm512_mask_storeu_pd(r.as_mut_ptr(), m, a); + } let e = _mm512_setr_pd(42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0); - assert_eq_m512d(_mm512_loadu_pd(r.as_ptr()), e); + assert_eq_m512d(unsafe { _mm512_loadu_pd(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_mask_store_pd() { + const fn test_mm512_mask_store_pd() { #[repr(align(64))] struct Align { data: [f64; 8], @@ -53227,34 +53247,36 @@ mod tests { let mut r = Align { data: [42.0; 8] }; let a = _mm512_setr_pd(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let m = 0b11001010; - _mm512_mask_store_pd(r.data.as_mut_ptr(), m, a); + unsafe { + _mm512_mask_store_pd(r.data.as_mut_ptr(), m, a); + } let e = _mm512_setr_pd(42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0); - assert_eq_m512d(_mm512_load_pd(r.data.as_ptr()), e); + assert_eq_m512d(unsafe { _mm512_load_pd(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_loadu_epi32() { + const fn test_mm256_mask_loadu_epi32() { let src = _mm256_set1_epi32(42); let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm256_mask_loadu_epi32(src, m, black_box(p)); + let r = unsafe { _mm256_mask_loadu_epi32(src, m, black_box(p)) }; let e = _mm256_setr_epi32(42, 2, 42, 4, 42, 42, 7, 8); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_maskz_loadu_epi32() { + const fn test_mm256_maskz_loadu_epi32() { let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm256_maskz_loadu_epi32(m, black_box(p)); + let r = unsafe { _mm256_maskz_loadu_epi32(m, black_box(p)) }; let e = _mm256_setr_epi32(0, 2, 0, 4, 0, 0, 7, 8); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_load_epi32() { + const fn test_mm256_mask_load_epi32() { #[repr(align(32))] struct Align { data: [i32; 8], // 32 bytes @@ -53265,13 +53287,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11001010; - let r = _mm256_mask_load_epi32(src, m, black_box(p)); + let r = unsafe { _mm256_mask_load_epi32(src, m, black_box(p)) }; let e = _mm256_setr_epi32(42, 2, 42, 4, 42, 42, 7, 8); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_maskz_load_epi32() { + const fn test_mm256_maskz_load_epi32() { #[repr(align(32))] struct Align { data: [i32; 8], // 32 bytes @@ -53281,23 +53303,25 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11001010; - let r = _mm256_maskz_load_epi32(m, black_box(p)); + let r = unsafe { _mm256_maskz_load_epi32(m, black_box(p)) }; let e = _mm256_setr_epi32(0, 2, 0, 4, 0, 0, 7, 8); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_storeu_epi32() { + const fn test_mm256_mask_storeu_epi32() { let mut r = [42_i32; 8]; let a = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); let m = 0b11001010; - _mm256_mask_storeu_epi32(r.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_storeu_epi32(r.as_mut_ptr(), m, a); + } let e = _mm256_setr_epi32(42, 2, 42, 4, 42, 42, 7, 8); - assert_eq_m256i(_mm256_loadu_epi32(r.as_ptr()), e); + assert_eq_m256i(unsafe { _mm256_loadu_epi32(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_store_epi32() { + const fn test_mm256_mask_store_epi32() { #[repr(align(64))] struct Align { data: [i32; 8], @@ -53305,34 +53329,36 @@ mod tests { let mut r = Align { data: [42; 8] }; let a = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); let m = 0b11001010; - _mm256_mask_store_epi32(r.data.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_store_epi32(r.data.as_mut_ptr(), m, a); + } let e = _mm256_setr_epi32(42, 2, 42, 4, 42, 42, 7, 8); - assert_eq_m256i(_mm256_load_epi32(r.data.as_ptr()), e); + assert_eq_m256i(unsafe { _mm256_load_epi32(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_loadu_epi64() { + const fn test_mm256_mask_loadu_epi64() { let src = _mm256_set1_epi64x(42); let a = &[1_i64, 2, 3, 4]; let p = a.as_ptr(); let m = 0b1010; - let r = _mm256_mask_loadu_epi64(src, m, black_box(p)); + let r = unsafe { _mm256_mask_loadu_epi64(src, m, black_box(p)) }; let e = _mm256_setr_epi64x(42, 2, 42, 4); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_maskz_loadu_epi64() { + const fn test_mm256_maskz_loadu_epi64() { let a = &[1_i64, 2, 3, 4]; let p = a.as_ptr(); let m = 0b1010; - let r = _mm256_maskz_loadu_epi64(m, black_box(p)); + let r = unsafe { _mm256_maskz_loadu_epi64(m, black_box(p)) }; let e = _mm256_setr_epi64x(0, 2, 0, 4); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_load_epi64() { + const fn test_mm256_mask_load_epi64() { #[repr(align(32))] struct Align { data: [i64; 4], // 32 bytes @@ -53343,13 +53369,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b1010; - let r = _mm256_mask_load_epi64(src, m, black_box(p)); + let r = unsafe { _mm256_mask_load_epi64(src, m, black_box(p)) }; let e = _mm256_setr_epi64x(42, 2, 42, 4); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_maskz_load_epi64() { + const fn test_mm256_maskz_load_epi64() { #[repr(align(32))] struct Align { data: [i64; 4], // 32 bytes @@ -53359,23 +53385,25 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b1010; - let r = _mm256_maskz_load_epi64(m, black_box(p)); + let r = unsafe { _mm256_maskz_load_epi64(m, black_box(p)) }; let e = _mm256_setr_epi64x(0, 2, 0, 4); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_storeu_epi64() { + const fn test_mm256_mask_storeu_epi64() { let mut r = [42_i64; 4]; let a = _mm256_setr_epi64x(1, 2, 3, 4); let m = 0b1010; - _mm256_mask_storeu_epi64(r.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_storeu_epi64(r.as_mut_ptr(), m, a); + } let e = _mm256_setr_epi64x(42, 2, 42, 4); - assert_eq_m256i(_mm256_loadu_epi64(r.as_ptr()), e); + assert_eq_m256i(unsafe { _mm256_loadu_epi64(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_store_epi64() { + const fn test_mm256_mask_store_epi64() { #[repr(align(32))] struct Align { data: [i64; 4], @@ -53383,34 +53411,36 @@ mod tests { let mut r = Align { data: [42; 4] }; let a = _mm256_setr_epi64x(1, 2, 3, 4); let m = 0b1010; - _mm256_mask_store_epi64(r.data.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_store_epi64(r.data.as_mut_ptr(), m, a); + } let e = _mm256_setr_epi64x(42, 2, 42, 4); - assert_eq_m256i(_mm256_load_epi64(r.data.as_ptr()), e); + assert_eq_m256i(unsafe { _mm256_load_epi64(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_loadu_ps() { + const fn test_mm256_mask_loadu_ps() { let src = _mm256_set1_ps(42.0); let a = &[1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm256_mask_loadu_ps(src, m, black_box(p)); + let r = unsafe { _mm256_mask_loadu_ps(src, m, black_box(p)) }; let e = _mm256_setr_ps(42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0); assert_eq_m256(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_maskz_loadu_ps() { + const fn test_mm256_maskz_loadu_ps() { let a = &[1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; let p = a.as_ptr(); let m = 0b11001010; - let r = _mm256_maskz_loadu_ps(m, black_box(p)); + let r = unsafe { _mm256_maskz_loadu_ps(m, black_box(p)) }; let e = _mm256_setr_ps(0.0, 2.0, 0.0, 4.0, 0.0, 0.0, 7.0, 8.0); assert_eq_m256(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_load_ps() { + const fn test_mm256_mask_load_ps() { #[repr(align(32))] struct Align { data: [f32; 8], // 32 bytes @@ -53421,13 +53451,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11001010; - let r = _mm256_mask_load_ps(src, m, black_box(p)); + let r = unsafe { _mm256_mask_load_ps(src, m, black_box(p)) }; let e = _mm256_setr_ps(42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0); assert_eq_m256(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_maskz_load_ps() { + const fn test_mm256_maskz_load_ps() { #[repr(align(32))] struct Align { data: [f32; 8], // 32 bytes @@ -53437,23 +53467,25 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b11001010; - let r = _mm256_maskz_load_ps(m, black_box(p)); + let r = unsafe { _mm256_maskz_load_ps(m, black_box(p)) }; let e = _mm256_setr_ps(0.0, 2.0, 0.0, 4.0, 0.0, 0.0, 7.0, 8.0); assert_eq_m256(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_storeu_ps() { + const fn test_mm256_mask_storeu_ps() { let mut r = [42_f32; 8]; let a = _mm256_setr_ps(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let m = 0b11001010; - _mm256_mask_storeu_ps(r.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_storeu_ps(r.as_mut_ptr(), m, a); + } let e = _mm256_setr_ps(42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0); - assert_eq_m256(_mm256_loadu_ps(r.as_ptr()), e); + assert_eq_m256(unsafe { _mm256_loadu_ps(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_store_ps() { + const fn test_mm256_mask_store_ps() { #[repr(align(32))] struct Align { data: [f32; 8], @@ -53461,34 +53493,36 @@ mod tests { let mut r = Align { data: [42.0; 8] }; let a = _mm256_setr_ps(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let m = 0b11001010; - _mm256_mask_store_ps(r.data.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_store_ps(r.data.as_mut_ptr(), m, a); + } let e = _mm256_setr_ps(42.0, 2.0, 42.0, 4.0, 42.0, 42.0, 7.0, 8.0); - assert_eq_m256(_mm256_load_ps(r.data.as_ptr()), e); + assert_eq_m256(unsafe { _mm256_load_ps(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_loadu_pd() { + const fn test_mm256_mask_loadu_pd() { let src = _mm256_set1_pd(42.0); let a = &[1.0_f64, 2.0, 3.0, 4.0]; let p = a.as_ptr(); let m = 0b1010; - let r = _mm256_mask_loadu_pd(src, m, black_box(p)); + let r = unsafe { _mm256_mask_loadu_pd(src, m, black_box(p)) }; let e = _mm256_setr_pd(42.0, 2.0, 42.0, 4.0); assert_eq_m256d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_maskz_loadu_pd() { + const fn test_mm256_maskz_loadu_pd() { let a = &[1.0_f64, 2.0, 3.0, 4.0]; let p = a.as_ptr(); let m = 0b1010; - let r = _mm256_maskz_loadu_pd(m, black_box(p)); + let r = unsafe { _mm256_maskz_loadu_pd(m, black_box(p)) }; let e = _mm256_setr_pd(0.0, 2.0, 0.0, 4.0); assert_eq_m256d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_load_pd() { + const fn test_mm256_mask_load_pd() { #[repr(align(32))] struct Align { data: [f64; 4], // 32 bytes @@ -53499,13 +53533,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b1010; - let r = _mm256_mask_load_pd(src, m, black_box(p)); + let r = unsafe { _mm256_mask_load_pd(src, m, black_box(p)) }; let e = _mm256_setr_pd(42.0, 2.0, 42.0, 4.0); assert_eq_m256d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_maskz_load_pd() { + const fn test_mm256_maskz_load_pd() { #[repr(align(32))] struct Align { data: [f64; 4], // 32 bytes @@ -53515,23 +53549,25 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b1010; - let r = _mm256_maskz_load_pd(m, black_box(p)); + let r = unsafe { _mm256_maskz_load_pd(m, black_box(p)) }; let e = _mm256_setr_pd(0.0, 2.0, 0.0, 4.0); assert_eq_m256d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_storeu_pd() { + const fn test_mm256_mask_storeu_pd() { let mut r = [42_f64; 4]; let a = _mm256_setr_pd(1.0, 2.0, 3.0, 4.0); let m = 0b1010; - _mm256_mask_storeu_pd(r.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_storeu_pd(r.as_mut_ptr(), m, a); + } let e = _mm256_setr_pd(42.0, 2.0, 42.0, 4.0); - assert_eq_m256d(_mm256_loadu_pd(r.as_ptr()), e); + assert_eq_m256d(unsafe { _mm256_loadu_pd(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_mask_store_pd() { + const fn test_mm256_mask_store_pd() { #[repr(align(32))] struct Align { data: [f64; 4], @@ -53539,34 +53575,36 @@ mod tests { let mut r = Align { data: [42.0; 4] }; let a = _mm256_setr_pd(1.0, 2.0, 3.0, 4.0); let m = 0b1010; - _mm256_mask_store_pd(r.data.as_mut_ptr(), m, a); + unsafe { + _mm256_mask_store_pd(r.data.as_mut_ptr(), m, a); + } let e = _mm256_setr_pd(42.0, 2.0, 42.0, 4.0); - assert_eq_m256d(_mm256_load_pd(r.data.as_ptr()), e); + assert_eq_m256d(unsafe { _mm256_load_pd(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_loadu_epi32() { + const fn test_mm_mask_loadu_epi32() { let src = _mm_set1_epi32(42); let a = &[1_i32, 2, 3, 4]; let p = a.as_ptr(); let m = 0b1010; - let r = _mm_mask_loadu_epi32(src, m, black_box(p)); + let r = unsafe { _mm_mask_loadu_epi32(src, m, black_box(p)) }; let e = _mm_setr_epi32(42, 2, 42, 4); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_maskz_loadu_epi32() { + const fn test_mm_maskz_loadu_epi32() { let a = &[1_i32, 2, 3, 4]; let p = a.as_ptr(); let m = 0b1010; - let r = _mm_maskz_loadu_epi32(m, black_box(p)); + let r = unsafe { _mm_maskz_loadu_epi32(m, black_box(p)) }; let e = _mm_setr_epi32(0, 2, 0, 4); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_load_epi32() { + const fn test_mm_mask_load_epi32() { #[repr(align(16))] struct Align { data: [i32; 4], // 32 bytes @@ -53577,13 +53615,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b1010; - let r = _mm_mask_load_epi32(src, m, black_box(p)); + let r = unsafe { _mm_mask_load_epi32(src, m, black_box(p)) }; let e = _mm_setr_epi32(42, 2, 42, 4); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_maskz_load_epi32() { + const fn test_mm_maskz_load_epi32() { #[repr(align(16))] struct Align { data: [i32; 4], // 16 bytes @@ -53593,23 +53631,25 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b1010; - let r = _mm_maskz_load_epi32(m, black_box(p)); + let r = unsafe { _mm_maskz_load_epi32(m, black_box(p)) }; let e = _mm_setr_epi32(0, 2, 0, 4); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_storeu_epi32() { + const fn test_mm_mask_storeu_epi32() { let mut r = [42_i32; 4]; let a = _mm_setr_epi32(1, 2, 3, 4); let m = 0b1010; - _mm_mask_storeu_epi32(r.as_mut_ptr(), m, a); + unsafe { + _mm_mask_storeu_epi32(r.as_mut_ptr(), m, a); + } let e = _mm_setr_epi32(42, 2, 42, 4); - assert_eq_m128i(_mm_loadu_epi32(r.as_ptr()), e); + assert_eq_m128i(unsafe { _mm_loadu_epi32(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_store_epi32() { + const fn test_mm_mask_store_epi32() { #[repr(align(16))] struct Align { data: [i32; 4], // 16 bytes @@ -53617,34 +53657,36 @@ mod tests { let mut r = Align { data: [42; 4] }; let a = _mm_setr_epi32(1, 2, 3, 4); let m = 0b1010; - _mm_mask_store_epi32(r.data.as_mut_ptr(), m, a); + unsafe { + _mm_mask_store_epi32(r.data.as_mut_ptr(), m, a); + } let e = _mm_setr_epi32(42, 2, 42, 4); - assert_eq_m128i(_mm_load_epi32(r.data.as_ptr()), e); + assert_eq_m128i(unsafe { _mm_load_epi32(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_loadu_epi64() { + const fn test_mm_mask_loadu_epi64() { let src = _mm_set1_epi64x(42); let a = &[1_i64, 2]; let p = a.as_ptr(); let m = 0b10; - let r = _mm_mask_loadu_epi64(src, m, black_box(p)); + let r = unsafe { _mm_mask_loadu_epi64(src, m, black_box(p)) }; let e = _mm_setr_epi64x(42, 2); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_maskz_loadu_epi64() { + const fn test_mm_maskz_loadu_epi64() { let a = &[1_i64, 2]; let p = a.as_ptr(); let m = 0b10; - let r = _mm_maskz_loadu_epi64(m, black_box(p)); + let r = unsafe { _mm_maskz_loadu_epi64(m, black_box(p)) }; let e = _mm_setr_epi64x(0, 2); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_load_epi64() { + const fn test_mm_mask_load_epi64() { #[repr(align(16))] struct Align { data: [i64; 2], // 16 bytes @@ -53653,13 +53695,13 @@ mod tests { let a = Align { data: [1_i64, 2] }; let p = a.data.as_ptr(); let m = 0b10; - let r = _mm_mask_load_epi64(src, m, black_box(p)); + let r = unsafe { _mm_mask_load_epi64(src, m, black_box(p)) }; let e = _mm_setr_epi64x(42, 2); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_maskz_load_epi64() { + const fn test_mm_maskz_load_epi64() { #[repr(align(16))] struct Align { data: [i64; 2], // 16 bytes @@ -53667,23 +53709,25 @@ mod tests { let a = Align { data: [1_i64, 2] }; let p = a.data.as_ptr(); let m = 0b10; - let r = _mm_maskz_load_epi64(m, black_box(p)); + let r = unsafe { _mm_maskz_load_epi64(m, black_box(p)) }; let e = _mm_setr_epi64x(0, 2); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_storeu_epi64() { + const fn test_mm_mask_storeu_epi64() { let mut r = [42_i64; 2]; let a = _mm_setr_epi64x(1, 2); let m = 0b10; - _mm_mask_storeu_epi64(r.as_mut_ptr(), m, a); + unsafe { + _mm_mask_storeu_epi64(r.as_mut_ptr(), m, a); + } let e = _mm_setr_epi64x(42, 2); - assert_eq_m128i(_mm_loadu_epi64(r.as_ptr()), e); + assert_eq_m128i(unsafe { _mm_loadu_epi64(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_store_epi64() { + const fn test_mm_mask_store_epi64() { #[repr(align(16))] struct Align { data: [i64; 2], // 16 bytes @@ -53691,34 +53735,36 @@ mod tests { let mut r = Align { data: [42; 2] }; let a = _mm_setr_epi64x(1, 2); let m = 0b10; - _mm_mask_store_epi64(r.data.as_mut_ptr(), m, a); + unsafe { + _mm_mask_store_epi64(r.data.as_mut_ptr(), m, a); + } let e = _mm_setr_epi64x(42, 2); - assert_eq_m128i(_mm_load_epi64(r.data.as_ptr()), e); + assert_eq_m128i(unsafe { _mm_load_epi64(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_loadu_ps() { + const fn test_mm_mask_loadu_ps() { let src = _mm_set1_ps(42.0); let a = &[1.0_f32, 2.0, 3.0, 4.0]; let p = a.as_ptr(); let m = 0b1010; - let r = _mm_mask_loadu_ps(src, m, black_box(p)); + let r = unsafe { _mm_mask_loadu_ps(src, m, black_box(p)) }; let e = _mm_setr_ps(42.0, 2.0, 42.0, 4.0); assert_eq_m128(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_maskz_loadu_ps() { + const fn test_mm_maskz_loadu_ps() { let a = &[1.0_f32, 2.0, 3.0, 4.0]; let p = a.as_ptr(); let m = 0b1010; - let r = _mm_maskz_loadu_ps(m, black_box(p)); + let r = unsafe { _mm_maskz_loadu_ps(m, black_box(p)) }; let e = _mm_setr_ps(0.0, 2.0, 0.0, 4.0); assert_eq_m128(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_load_ps() { + const fn test_mm_mask_load_ps() { #[repr(align(16))] struct Align { data: [f32; 4], // 16 bytes @@ -53729,13 +53775,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b1010; - let r = _mm_mask_load_ps(src, m, black_box(p)); + let r = unsafe { _mm_mask_load_ps(src, m, black_box(p)) }; let e = _mm_setr_ps(42.0, 2.0, 42.0, 4.0); assert_eq_m128(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_maskz_load_ps() { + const fn test_mm_maskz_load_ps() { #[repr(align(16))] struct Align { data: [f32; 4], // 16 bytes @@ -53745,23 +53791,25 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b1010; - let r = _mm_maskz_load_ps(m, black_box(p)); + let r = unsafe { _mm_maskz_load_ps(m, black_box(p)) }; let e = _mm_setr_ps(0.0, 2.0, 0.0, 4.0); assert_eq_m128(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_storeu_ps() { + const fn test_mm_mask_storeu_ps() { let mut r = [42_f32; 4]; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let m = 0b1010; - _mm_mask_storeu_ps(r.as_mut_ptr(), m, a); + unsafe { + _mm_mask_storeu_ps(r.as_mut_ptr(), m, a); + } let e = _mm_setr_ps(42.0, 2.0, 42.0, 4.0); - assert_eq_m128(_mm_loadu_ps(r.as_ptr()), e); + assert_eq_m128(unsafe { _mm_loadu_ps(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_store_ps() { + const fn test_mm_mask_store_ps() { #[repr(align(16))] struct Align { data: [f32; 4], // 16 bytes @@ -53769,34 +53817,36 @@ mod tests { let mut r = Align { data: [42.0; 4] }; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let m = 0b1010; - _mm_mask_store_ps(r.data.as_mut_ptr(), m, a); + unsafe { + _mm_mask_store_ps(r.data.as_mut_ptr(), m, a); + } let e = _mm_setr_ps(42.0, 2.0, 42.0, 4.0); - assert_eq_m128(_mm_load_ps(r.data.as_ptr()), e); + assert_eq_m128(unsafe { _mm_load_ps(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_loadu_pd() { + const fn test_mm_mask_loadu_pd() { let src = _mm_set1_pd(42.0); let a = &[1.0_f64, 2.0]; let p = a.as_ptr(); let m = 0b10; - let r = _mm_mask_loadu_pd(src, m, black_box(p)); + let r = unsafe { _mm_mask_loadu_pd(src, m, black_box(p)) }; let e = _mm_setr_pd(42.0, 2.0); assert_eq_m128d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_maskz_loadu_pd() { + const fn test_mm_maskz_loadu_pd() { let a = &[1.0_f64, 2.0]; let p = a.as_ptr(); let m = 0b10; - let r = _mm_maskz_loadu_pd(m, black_box(p)); + let r = unsafe { _mm_maskz_loadu_pd(m, black_box(p)) }; let e = _mm_setr_pd(0.0, 2.0); assert_eq_m128d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_load_pd() { + const fn test_mm_mask_load_pd() { #[repr(align(16))] struct Align { data: [f64; 2], // 16 bytes @@ -53807,13 +53857,13 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b10; - let r = _mm_mask_load_pd(src, m, black_box(p)); + let r = unsafe { _mm_mask_load_pd(src, m, black_box(p)) }; let e = _mm_setr_pd(42.0, 2.0); assert_eq_m128d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_maskz_load_pd() { + const fn test_mm_maskz_load_pd() { #[repr(align(16))] struct Align { data: [f64; 2], // 16 bytes @@ -53823,77 +53873,79 @@ mod tests { }; let p = a.data.as_ptr(); let m = 0b10; - let r = _mm_maskz_load_pd(m, black_box(p)); + let r = unsafe { _mm_maskz_load_pd(m, black_box(p)) }; let e = _mm_setr_pd(0.0, 2.0); assert_eq_m128d(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_load_ss() { + fn test_mm_mask_load_ss() { #[repr(align(16))] struct Align { data: f32, } let src = _mm_set_ss(2.0); let mem = Align { data: 1.0 }; - let r = _mm_mask_load_ss(src, 0b1, &mem.data); + let r = unsafe { _mm_mask_load_ss(src, 0b1, &mem.data) }; assert_eq_m128(r, _mm_set_ss(1.0)); - let r = _mm_mask_load_ss(src, 0b0, &mem.data); + let r = unsafe { _mm_mask_load_ss(src, 0b0, &mem.data) }; assert_eq_m128(r, _mm_set_ss(2.0)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_load_ss() { + fn test_mm_maskz_load_ss() { #[repr(align(16))] struct Align { data: f32, } let mem = Align { data: 1.0 }; - let r = _mm_maskz_load_ss(0b1, &mem.data); + let r = unsafe { _mm_maskz_load_ss(0b1, &mem.data) }; assert_eq_m128(r, _mm_set_ss(1.0)); - let r = _mm_maskz_load_ss(0b0, &mem.data); + let r = unsafe { _mm_maskz_load_ss(0b0, &mem.data) }; assert_eq_m128(r, _mm_set_ss(0.0)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_load_sd() { + fn test_mm_mask_load_sd() { #[repr(align(16))] struct Align { data: f64, } let src = _mm_set_sd(2.0); let mem = Align { data: 1.0 }; - let r = _mm_mask_load_sd(src, 0b1, &mem.data); + let r = unsafe { _mm_mask_load_sd(src, 0b1, &mem.data) }; assert_eq_m128d(r, _mm_set_sd(1.0)); - let r = _mm_mask_load_sd(src, 0b0, &mem.data); + let r = unsafe { _mm_mask_load_sd(src, 0b0, &mem.data) }; assert_eq_m128d(r, _mm_set_sd(2.0)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_maskz_load_sd() { + fn test_mm_maskz_load_sd() { #[repr(align(16))] struct Align { data: f64, } let mem = Align { data: 1.0 }; - let r = _mm_maskz_load_sd(0b1, &mem.data); + let r = unsafe { _mm_maskz_load_sd(0b1, &mem.data) }; assert_eq_m128d(r, _mm_set_sd(1.0)); - let r = _mm_maskz_load_sd(0b0, &mem.data); + let r = unsafe { _mm_maskz_load_sd(0b0, &mem.data) }; assert_eq_m128d(r, _mm_set_sd(0.0)); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_storeu_pd() { + const fn test_mm_mask_storeu_pd() { let mut r = [42_f64; 2]; let a = _mm_setr_pd(1.0, 2.0); let m = 0b10; - _mm_mask_storeu_pd(r.as_mut_ptr(), m, a); + unsafe { + _mm_mask_storeu_pd(r.as_mut_ptr(), m, a); + } let e = _mm_setr_pd(42.0, 2.0); - assert_eq_m128d(_mm_loadu_pd(r.as_ptr()), e); + assert_eq_m128d(unsafe { _mm_loadu_pd(r.as_ptr()) }, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_mask_store_pd() { + const fn test_mm_mask_store_pd() { #[repr(align(16))] struct Align { data: [f64; 2], // 16 bytes @@ -53901,36 +53953,46 @@ mod tests { let mut r = Align { data: [42.0; 2] }; let a = _mm_setr_pd(1.0, 2.0); let m = 0b10; - _mm_mask_store_pd(r.data.as_mut_ptr(), m, a); + unsafe { + _mm_mask_store_pd(r.data.as_mut_ptr(), m, a); + } let e = _mm_setr_pd(42.0, 2.0); - assert_eq_m128d(_mm_load_pd(r.data.as_ptr()), e); + assert_eq_m128d(unsafe { _mm_load_pd(r.data.as_ptr()) }, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_store_ss() { + fn test_mm_mask_store_ss() { #[repr(align(16))] struct Align { data: f32, } let a = _mm_set_ss(2.0); let mut mem = Align { data: 1.0 }; - _mm_mask_store_ss(&mut mem.data, 0b1, a); + unsafe { + _mm_mask_store_ss(&mut mem.data, 0b1, a); + } assert_eq!(mem.data, 2.0); - _mm_mask_store_ss(&mut mem.data, 0b0, a); + unsafe { + _mm_mask_store_ss(&mut mem.data, 0b0, a); + } assert_eq!(mem.data, 2.0); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm_mask_store_sd() { + fn test_mm_mask_store_sd() { #[repr(align(16))] struct Align { data: f64, } let a = _mm_set_sd(2.0); let mut mem = Align { data: 1.0 }; - _mm_mask_store_sd(&mut mem.data, 0b1, a); + unsafe { + _mm_mask_store_sd(&mut mem.data, 0b1, a); + } assert_eq!(mem.data, 2.0); - _mm_mask_store_sd(&mut mem.data, 0b0, a); + unsafe { + _mm_mask_store_sd(&mut mem.data, 0b0, a); + } assert_eq!(mem.data, 2.0); } @@ -57931,11 +57993,11 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_kortest_mask16_u8() { + const fn test_kortest_mask16_u8() { let a: __mmask16 = 0b0110100101101001; let b: __mmask16 = 0b1011011010110110; let mut all_ones: u8 = 0; - let r = _kortest_mask16_u8(a, b, &mut all_ones); + let r = unsafe { _kortest_mask16_u8(a, b, &mut all_ones) }; assert_eq!(r, 0); assert_eq!(all_ones, 1); } @@ -57997,18 +58059,20 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_load_mask16() { + const fn test_load_mask16() { let a: __mmask16 = 0b1001011011000011; - let r = _load_mask16(&a); + let r = unsafe { _load_mask16(&a) }; let e: __mmask16 = 0b1001011011000011; assert_eq!(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_store_mask16() { + const fn test_store_mask16() { let a: __mmask16 = 0b0110100100111100; let mut r = 0; - _store_mask16(&mut r, a); + unsafe { + _store_mask16(&mut r, a); + } let e: __mmask16 = 0b0110100100111100; assert_eq!(r, e); } @@ -58189,7 +58253,7 @@ mod tests { #[simd_test(enable = "avx512f")] #[cfg_attr(miri, ignore)] - unsafe fn test_mm512_stream_ps() { + fn test_mm512_stream_ps() { #[repr(align(64))] struct Memory { pub data: [f32; 16], // 64 bytes @@ -58197,7 +58261,9 @@ mod tests { let a = _mm512_set1_ps(7.0); let mut mem = Memory { data: [-1.0; 16] }; - _mm512_stream_ps(&mut mem.data[0] as *mut f32, a); + unsafe { + _mm512_stream_ps(&mut mem.data[0] as *mut f32, a); + } _mm_sfence(); for i in 0..16 { assert_eq!(mem.data[i], get_m512(a, i)); @@ -58206,7 +58272,7 @@ mod tests { #[simd_test(enable = "avx512f")] #[cfg_attr(miri, ignore)] - unsafe fn test_mm512_stream_pd() { + fn test_mm512_stream_pd() { #[repr(align(64))] struct Memory { pub data: [f64; 8], @@ -58214,7 +58280,9 @@ mod tests { let a = _mm512_set1_pd(7.0); let mut mem = Memory { data: [-1.0; 8] }; - _mm512_stream_pd(&mut mem.data[0] as *mut f64, a); + unsafe { + _mm512_stream_pd(&mut mem.data[0] as *mut f64, a); + } _mm_sfence(); for i in 0..8 { assert_eq!(mem.data[i], get_m512d(a, i)); @@ -58223,7 +58291,7 @@ mod tests { #[simd_test(enable = "avx512f")] #[cfg_attr(miri, ignore)] - unsafe fn test_mm512_stream_si512() { + fn test_mm512_stream_si512() { #[repr(align(64))] struct Memory { pub data: [i64; 8], @@ -58231,7 +58299,9 @@ mod tests { let a = _mm512_set1_epi32(7); let mut mem = Memory { data: [-1; 8] }; - _mm512_stream_si512(mem.data.as_mut_ptr().cast(), a); + unsafe { + _mm512_stream_si512(mem.data.as_mut_ptr().cast(), a); + } _mm_sfence(); for i in 0..8 { assert_eq!(mem.data[i], get_m512i(a, i)); @@ -58239,9 +58309,9 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_stream_load_si512() { + fn test_mm512_stream_load_si512() { let a = _mm512_set_epi64(1, 2, 3, 4, 5, 6, 7, 8); - let r = _mm512_stream_load_si512(core::ptr::addr_of!(a) as *const _); + let r = unsafe { _mm512_stream_load_si512(core::ptr::addr_of!(a) as *const _) }; assert_eq_m512i(a, r); } @@ -58558,75 +58628,103 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_compressstoreu_epi32() { + fn test_mm512_mask_compressstoreu_epi32() { let a = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); let mut r = [0_i32; 16]; - _mm512_mask_compressstoreu_epi32(r.as_mut_ptr(), 0, a); + unsafe { + _mm512_mask_compressstoreu_epi32(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i32; 16]); - _mm512_mask_compressstoreu_epi32(r.as_mut_ptr(), 0b1111000011001010, a); + unsafe { + _mm512_mask_compressstoreu_epi32(r.as_mut_ptr(), 0b1111000011001010, a); + } assert_eq!(&r, &[2, 4, 7, 8, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0]); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_compressstoreu_epi32() { + fn test_mm256_mask_compressstoreu_epi32() { let a = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); let mut r = [0_i32; 8]; - _mm256_mask_compressstoreu_epi32(r.as_mut_ptr(), 0, a); + unsafe { + _mm256_mask_compressstoreu_epi32(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i32; 8]); - _mm256_mask_compressstoreu_epi32(r.as_mut_ptr(), 0b11001010, a); + unsafe { + _mm256_mask_compressstoreu_epi32(r.as_mut_ptr(), 0b11001010, a); + } assert_eq!(&r, &[2, 4, 7, 8, 0, 0, 0, 0]); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_compressstoreu_epi32() { + fn test_mm_mask_compressstoreu_epi32() { let a = _mm_setr_epi32(1, 2, 3, 4); let mut r = [0_i32; 4]; - _mm_mask_compressstoreu_epi32(r.as_mut_ptr(), 0, a); + unsafe { + _mm_mask_compressstoreu_epi32(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i32; 4]); - _mm_mask_compressstoreu_epi32(r.as_mut_ptr(), 0b1011, a); + unsafe { + _mm_mask_compressstoreu_epi32(r.as_mut_ptr(), 0b1011, a); + } assert_eq!(&r, &[1, 2, 4, 0]); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_compressstoreu_epi64() { + fn test_mm512_mask_compressstoreu_epi64() { let a = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); let mut r = [0_i64; 8]; - _mm512_mask_compressstoreu_epi64(r.as_mut_ptr(), 0, a); + unsafe { + _mm512_mask_compressstoreu_epi64(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i64; 8]); - _mm512_mask_compressstoreu_epi64(r.as_mut_ptr(), 0b11001010, a); + unsafe { + _mm512_mask_compressstoreu_epi64(r.as_mut_ptr(), 0b11001010, a); + } assert_eq!(&r, &[2, 4, 7, 8, 0, 0, 0, 0]); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_compressstoreu_epi64() { + fn test_mm256_mask_compressstoreu_epi64() { let a = _mm256_setr_epi64x(1, 2, 3, 4); let mut r = [0_i64; 4]; - _mm256_mask_compressstoreu_epi64(r.as_mut_ptr(), 0, a); + unsafe { + _mm256_mask_compressstoreu_epi64(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i64; 4]); - _mm256_mask_compressstoreu_epi64(r.as_mut_ptr(), 0b1011, a); + unsafe { + _mm256_mask_compressstoreu_epi64(r.as_mut_ptr(), 0b1011, a); + } assert_eq!(&r, &[1, 2, 4, 0]); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_compressstoreu_epi64() { + fn test_mm_mask_compressstoreu_epi64() { let a = _mm_setr_epi64x(1, 2); let mut r = [0_i64; 2]; - _mm_mask_compressstoreu_epi64(r.as_mut_ptr(), 0, a); + unsafe { + _mm_mask_compressstoreu_epi64(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i64; 2]); - _mm_mask_compressstoreu_epi64(r.as_mut_ptr(), 0b10, a); + unsafe { + _mm_mask_compressstoreu_epi64(r.as_mut_ptr(), 0b10, a); + } assert_eq!(&r, &[2, 0]); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_compressstoreu_ps() { + fn test_mm512_mask_compressstoreu_ps() { let a = _mm512_setr_ps( 1_f32, 2_f32, 3_f32, 4_f32, 5_f32, 6_f32, 7_f32, 8_f32, 9_f32, 10_f32, 11_f32, 12_f32, 13_f32, 14_f32, 15_f32, 16_f32, ); let mut r = [0_f32; 16]; - _mm512_mask_compressstoreu_ps(r.as_mut_ptr(), 0, a); + unsafe { + _mm512_mask_compressstoreu_ps(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_f32; 16]); - _mm512_mask_compressstoreu_ps(r.as_mut_ptr(), 0b1111000011001010, a); + unsafe { + _mm512_mask_compressstoreu_ps(r.as_mut_ptr(), 0b1111000011001010, a); + } assert_eq!( &r, &[ @@ -58637,12 +58735,16 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_compressstoreu_ps() { + fn test_mm256_mask_compressstoreu_ps() { let a = _mm256_setr_ps(1_f32, 2_f32, 3_f32, 4_f32, 5_f32, 6_f32, 7_f32, 8_f32); let mut r = [0_f32; 8]; - _mm256_mask_compressstoreu_ps(r.as_mut_ptr(), 0, a); + unsafe { + _mm256_mask_compressstoreu_ps(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_f32; 8]); - _mm256_mask_compressstoreu_ps(r.as_mut_ptr(), 0b11001010, a); + unsafe { + _mm256_mask_compressstoreu_ps(r.as_mut_ptr(), 0b11001010, a); + } assert_eq!( &r, &[2_f32, 4_f32, 7_f32, 8_f32, 0_f32, 0_f32, 0_f32, 0_f32] @@ -58650,47 +58752,63 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_compressstoreu_ps() { + fn test_mm_mask_compressstoreu_ps() { let a = _mm_setr_ps(1_f32, 2_f32, 3_f32, 4_f32); let mut r = [0.; 4]; - _mm_mask_compressstoreu_ps(r.as_mut_ptr(), 0, a); + unsafe { + _mm_mask_compressstoreu_ps(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0.; 4]); - _mm_mask_compressstoreu_ps(r.as_mut_ptr(), 0b1011, a); + unsafe { + _mm_mask_compressstoreu_ps(r.as_mut_ptr(), 0b1011, a); + } assert_eq!(&r, &[1_f32, 2_f32, 4_f32, 0_f32]); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_compressstoreu_pd() { + fn test_mm512_mask_compressstoreu_pd() { let a = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); let mut r = [0.; 8]; - _mm512_mask_compressstoreu_pd(r.as_mut_ptr(), 0, a); + unsafe { + _mm512_mask_compressstoreu_pd(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0.; 8]); - _mm512_mask_compressstoreu_pd(r.as_mut_ptr(), 0b11001010, a); + unsafe { + _mm512_mask_compressstoreu_pd(r.as_mut_ptr(), 0b11001010, a); + } assert_eq!(&r, &[2., 4., 7., 8., 0., 0., 0., 0.]); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_compressstoreu_pd() { + fn test_mm256_mask_compressstoreu_pd() { let a = _mm256_setr_pd(1., 2., 3., 4.); let mut r = [0.; 4]; - _mm256_mask_compressstoreu_pd(r.as_mut_ptr(), 0, a); + unsafe { + _mm256_mask_compressstoreu_pd(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0.; 4]); - _mm256_mask_compressstoreu_pd(r.as_mut_ptr(), 0b1011, a); + unsafe { + _mm256_mask_compressstoreu_pd(r.as_mut_ptr(), 0b1011, a); + } assert_eq!(&r, &[1., 2., 4., 0.]); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_compressstoreu_pd() { + fn test_mm_mask_compressstoreu_pd() { let a = _mm_setr_pd(1., 2.); let mut r = [0.; 2]; - _mm_mask_compressstoreu_pd(r.as_mut_ptr(), 0, a); + unsafe { + _mm_mask_compressstoreu_pd(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0.; 2]); - _mm_mask_compressstoreu_pd(r.as_mut_ptr(), 0b10, a); + unsafe { + _mm_mask_compressstoreu_pd(r.as_mut_ptr(), 0b10, a); + } assert_eq!(&r, &[2., 0.]); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_expand_epi32() { + fn test_mm512_mask_expand_epi32() { let src = _mm512_set1_epi32(200); let a = _mm512_set_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); let r = _mm512_mask_expand_epi32(src, 0, a); @@ -58826,109 +58944,135 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_loadu_epi32() { + const fn test_mm512_loadu_epi32() { let a = &[4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50]; let p = a.as_ptr(); - let r = _mm512_loadu_epi32(black_box(p)); + let r = unsafe { _mm512_loadu_epi32(black_box(p)) }; let e = _mm512_setr_epi32(4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_loadu_epi32() { + const fn test_mm256_loadu_epi32() { let a = &[4, 3, 2, 5, 8, 9, 64, 50]; let p = a.as_ptr(); - let r = _mm256_loadu_epi32(black_box(p)); + let r = unsafe { _mm256_loadu_epi32(black_box(p)) }; let e = _mm256_setr_epi32(4, 3, 2, 5, 8, 9, 64, 50); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_loadu_epi32() { + const fn test_mm_loadu_epi32() { let a = &[4, 3, 2, 5]; let p = a.as_ptr(); - let r = _mm_loadu_epi32(black_box(p)); + let r = unsafe { _mm_loadu_epi32(black_box(p)) }; let e = _mm_setr_epi32(4, 3, 2, 5); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi32_storeu_epi16() { + fn test_mm512_mask_cvtepi32_storeu_epi16() { let a = _mm512_set1_epi32(9); let mut r = _mm256_undefined_si256(); - _mm512_mask_cvtepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111_11111111, a); + unsafe { + _mm512_mask_cvtepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111_11111111, a); + } let e = _mm256_set1_epi16(9); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi32_storeu_epi16() { + fn test_mm256_mask_cvtepi32_storeu_epi16() { let a = _mm256_set1_epi32(9); let mut r = _mm_undefined_si128(); - _mm256_mask_cvtepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm256_mask_cvtepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set1_epi16(9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi32_storeu_epi16() { + fn test_mm_mask_cvtepi32_storeu_epi16() { let a = _mm_set1_epi32(9); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm_mask_cvtepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set_epi16(0, 0, 0, 0, 9, 9, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtsepi32_storeu_epi16() { + fn test_mm512_mask_cvtsepi32_storeu_epi16() { let a = _mm512_set1_epi32(i32::MAX); let mut r = _mm256_undefined_si256(); - _mm512_mask_cvtsepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111_11111111, a); + unsafe { + _mm512_mask_cvtsepi32_storeu_epi16( + &mut r as *mut _ as *mut i16, + 0b11111111_11111111, + a, + ); + } let e = _mm256_set1_epi16(i16::MAX); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtsepi32_storeu_epi16() { + fn test_mm256_mask_cvtsepi32_storeu_epi16() { let a = _mm256_set1_epi32(i32::MAX); let mut r = _mm_undefined_si128(); - _mm256_mask_cvtsepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm256_mask_cvtsepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set1_epi16(i16::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtsepi32_storeu_epi16() { + fn test_mm_mask_cvtsepi32_storeu_epi16() { let a = _mm_set1_epi32(i32::MAX); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtsepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm_mask_cvtsepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set_epi16(0, 0, 0, 0, i16::MAX, i16::MAX, i16::MAX, i16::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtusepi32_storeu_epi16() { + fn test_mm512_mask_cvtusepi32_storeu_epi16() { let a = _mm512_set1_epi32(i32::MAX); let mut r = _mm256_undefined_si256(); - _mm512_mask_cvtusepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111_11111111, a); + unsafe { + _mm512_mask_cvtusepi32_storeu_epi16( + &mut r as *mut _ as *mut i16, + 0b11111111_11111111, + a, + ); + } let e = _mm256_set1_epi16(u16::MAX as i16); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtusepi32_storeu_epi16() { + fn test_mm256_mask_cvtusepi32_storeu_epi16() { let a = _mm256_set1_epi32(i32::MAX); let mut r = _mm_undefined_si128(); - _mm256_mask_cvtusepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm256_mask_cvtusepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set1_epi16(u16::MAX as i16); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtusepi32_storeu_epi16() { + fn test_mm_mask_cvtusepi32_storeu_epi16() { let a = _mm_set1_epi32(i32::MAX); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtusepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm_mask_cvtusepi32_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set_epi16( 0, 0, @@ -58943,46 +59087,56 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi32_storeu_epi8() { + fn test_mm512_mask_cvtepi32_storeu_epi8() { let a = _mm512_set1_epi32(9); let mut r = _mm_undefined_si128(); - _mm512_mask_cvtepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + unsafe { + _mm512_mask_cvtepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + } let e = _mm_set1_epi8(9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi32_storeu_epi8() { + fn test_mm256_mask_cvtepi32_storeu_epi8() { let a = _mm256_set1_epi32(9); let mut r = _mm_set1_epi8(0); - _mm256_mask_cvtepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm256_mask_cvtepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } let e = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi32_storeu_epi8() { + fn test_mm_mask_cvtepi32_storeu_epi8() { let a = _mm_set1_epi32(9); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm_mask_cvtepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } let e = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtsepi32_storeu_epi8() { + fn test_mm512_mask_cvtsepi32_storeu_epi8() { let a = _mm512_set1_epi32(i32::MAX); let mut r = _mm_undefined_si128(); - _mm512_mask_cvtsepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + unsafe { + _mm512_mask_cvtsepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + } let e = _mm_set1_epi8(i8::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtsepi32_storeu_epi8() { + fn test_mm256_mask_cvtsepi32_storeu_epi8() { let a = _mm256_set1_epi32(i32::MAX); let mut r = _mm_set1_epi8(0); - _mm256_mask_cvtsepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm256_mask_cvtsepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, @@ -58994,10 +59148,12 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtsepi32_storeu_epi8() { + fn test_mm_mask_cvtsepi32_storeu_epi8() { let a = _mm_set1_epi32(i32::MAX); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtsepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm_mask_cvtsepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, @@ -59009,19 +59165,23 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtusepi32_storeu_epi8() { + fn test_mm512_mask_cvtusepi32_storeu_epi8() { let a = _mm512_set1_epi32(i32::MAX); let mut r = _mm_undefined_si128(); - _mm512_mask_cvtusepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + unsafe { + _mm512_mask_cvtusepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111_11111111, a); + } let e = _mm_set1_epi8(u8::MAX as i8); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtusepi32_storeu_epi8() { + fn test_mm256_mask_cvtusepi32_storeu_epi8() { let a = _mm256_set1_epi32(i32::MAX); let mut r = _mm_set1_epi8(0); - _mm256_mask_cvtusepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm256_mask_cvtusepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, @@ -59033,10 +59193,12 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtusepi32_storeu_epi8() { + fn test_mm_mask_cvtusepi32_storeu_epi8() { let a = _mm_set1_epi32(i32::MAX); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtusepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm_mask_cvtusepi32_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, @@ -59048,48 +59210,56 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_storeu_epi32() { + const fn test_mm512_storeu_epi32() { let a = _mm512_set1_epi32(9); let mut r = _mm512_undefined_epi32(); - _mm512_storeu_epi32(&mut r as *mut _ as *mut i32, a); + unsafe { + _mm512_storeu_epi32(&mut r as *mut _ as *mut i32, a); + } assert_eq_m512i(r, a); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_storeu_epi32() { + const fn test_mm256_storeu_epi32() { let a = _mm256_set1_epi32(9); let mut r = _mm256_undefined_si256(); - _mm256_storeu_epi32(&mut r as *mut _ as *mut i32, a); + unsafe { + _mm256_storeu_epi32(&mut r as *mut _ as *mut i32, a); + } assert_eq_m256i(r, a); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_storeu_epi32() { + const fn test_mm_storeu_epi32() { let a = _mm_set1_epi32(9); let mut r = _mm_undefined_si128(); - _mm_storeu_epi32(&mut r as *mut _ as *mut i32, a); + unsafe { + _mm_storeu_epi32(&mut r as *mut _ as *mut i32, a); + } assert_eq_m128i(r, a); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_loadu_si512() { + const fn test_mm512_loadu_si512() { let a = &[4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50]; let p = a.as_ptr().cast(); - let r = _mm512_loadu_si512(black_box(p)); + let r = unsafe { _mm512_loadu_si512(black_box(p)) }; let e = _mm512_setr_epi32(4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_storeu_si512() { + const fn test_mm512_storeu_si512() { let a = _mm512_set1_epi32(9); let mut r = _mm512_undefined_epi32(); - _mm512_storeu_si512(&mut r as *mut _, a); + unsafe { + _mm512_storeu_si512(&mut r as *mut _, a); + } assert_eq_m512i(r, a); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_load_si512() { + const fn test_mm512_load_si512() { #[repr(align(64))] struct Align { data: [i32; 16], // 64 bytes @@ -59098,21 +59268,23 @@ mod tests { data: [4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50], }; let p = (a.data).as_ptr().cast(); - let r = _mm512_load_si512(black_box(p)); + let r = unsafe { _mm512_load_si512(black_box(p)) }; let e = _mm512_setr_epi32(4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_store_si512() { + const fn test_mm512_store_si512() { let a = _mm512_set1_epi32(9); let mut r = _mm512_undefined_epi32(); - _mm512_store_si512(&mut r as *mut _, a); + unsafe { + _mm512_store_si512(&mut r as *mut _, a); + } assert_eq_m512i(r, a); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_load_epi32() { + const fn test_mm512_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 16], // 64 bytes @@ -59121,13 +59293,13 @@ mod tests { data: [4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50], }; let p = (a.data).as_ptr(); - let r = _mm512_load_epi32(black_box(p)); + let r = unsafe { _mm512_load_epi32(black_box(p)) }; let e = _mm512_setr_epi32(4, 3, 2, 5, 8, 9, 64, 50, -4, -3, -2, -5, -8, -9, -64, -50); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_load_epi32() { + const fn test_mm256_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 8], @@ -59136,50 +59308,56 @@ mod tests { data: [4, 3, 2, 5, 8, 9, 64, 50], }; let p = (a.data).as_ptr(); - let r = _mm256_load_epi32(black_box(p)); + let r = unsafe { _mm256_load_epi32(black_box(p)) }; let e = _mm256_setr_epi32(4, 3, 2, 5, 8, 9, 64, 50); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_load_epi32() { + const fn test_mm_load_epi32() { #[repr(align(64))] struct Align { data: [i32; 4], } let a = Align { data: [4, 3, 2, 5] }; let p = (a.data).as_ptr(); - let r = _mm_load_epi32(black_box(p)); + let r = unsafe { _mm_load_epi32(black_box(p)) }; let e = _mm_setr_epi32(4, 3, 2, 5); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_store_epi32() { + const fn test_mm512_store_epi32() { let a = _mm512_set1_epi32(9); let mut r = _mm512_undefined_epi32(); - _mm512_store_epi32(&mut r as *mut _ as *mut i32, a); + unsafe { + _mm512_store_epi32(&mut r as *mut _ as *mut i32, a); + } assert_eq_m512i(r, a); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_store_epi32() { + const fn test_mm256_store_epi32() { let a = _mm256_set1_epi32(9); let mut r = _mm256_undefined_si256(); - _mm256_store_epi32(&mut r as *mut _ as *mut i32, a); + unsafe { + _mm256_store_epi32(&mut r as *mut _ as *mut i32, a); + } assert_eq_m256i(r, a); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_store_epi32() { + const fn test_mm_store_epi32() { let a = _mm_set1_epi32(9); let mut r = _mm_undefined_si128(); - _mm_store_epi32(&mut r as *mut _ as *mut i32, a); + unsafe { + _mm_store_epi32(&mut r as *mut _ as *mut i32, a); + } assert_eq_m128i(r, a); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_load_ps() { + const fn test_mm512_load_ps() { #[repr(align(64))] struct Align { data: [f32; 16], // 64 bytes @@ -59190,7 +59368,7 @@ mod tests { ], }; let p = (a.data).as_ptr(); - let r = _mm512_load_ps(black_box(p)); + let r = unsafe { _mm512_load_ps(black_box(p)) }; let e = _mm512_setr_ps( 4., 3., 2., 5., 8., 9., 64., 50., -4., -3., -2., -5., -8., -9., -64., -50., ); @@ -59198,10 +59376,12 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_store_ps() { + const fn test_mm512_store_ps() { let a = _mm512_set1_ps(9.); let mut r = _mm512_undefined_ps(); - _mm512_store_ps(&mut r as *mut _ as *mut f32, a); + unsafe { + _mm512_store_ps(&mut r as *mut _ as *mut f32, a); + } assert_eq_m512(r, a); } @@ -62191,140 +62371,140 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_expandloadu_epi32() { + fn test_mm512_mask_expandloadu_epi32() { let src = _mm512_set1_epi32(42); let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_mask_expandloadu_epi32(src, m, black_box(p)); + let r = unsafe { _mm512_mask_expandloadu_epi32(src, m, black_box(p)) }; let e = _mm512_set_epi32(8, 7, 6, 42, 5, 42, 42, 42, 4, 3, 42, 42, 2, 42, 1, 42); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_expandloadu_epi32() { + fn test_mm512_maskz_expandloadu_epi32() { let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_maskz_expandloadu_epi32(m, black_box(p)); + let r = unsafe { _mm512_maskz_expandloadu_epi32(m, black_box(p)) }; let e = _mm512_set_epi32(8, 7, 6, 0, 5, 0, 0, 0, 4, 3, 0, 0, 2, 0, 1, 0); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_expandloadu_epi32() { + fn test_mm256_mask_expandloadu_epi32() { let src = _mm256_set1_epi32(42); let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm256_mask_expandloadu_epi32(src, m, black_box(p)); + let r = unsafe { _mm256_mask_expandloadu_epi32(src, m, black_box(p)) }; let e = _mm256_set_epi32(4, 3, 2, 42, 1, 42, 42, 42); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_expandloadu_epi32() { + fn test_mm256_maskz_expandloadu_epi32() { let a = &[1_i32, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm256_maskz_expandloadu_epi32(m, black_box(p)); + let r = unsafe { _mm256_maskz_expandloadu_epi32(m, black_box(p)) }; let e = _mm256_set_epi32(4, 3, 2, 0, 1, 0, 0, 0); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_expandloadu_epi32() { + fn test_mm_mask_expandloadu_epi32() { let src = _mm_set1_epi32(42); let a = &[1_i32, 2, 3, 4]; let p = a.as_ptr(); let m = 0b11111000; - let r = _mm_mask_expandloadu_epi32(src, m, black_box(p)); + let r = unsafe { _mm_mask_expandloadu_epi32(src, m, black_box(p)) }; let e = _mm_set_epi32(1, 42, 42, 42); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_expandloadu_epi32() { + fn test_mm_maskz_expandloadu_epi32() { let a = &[1_i32, 2, 3, 4]; let p = a.as_ptr(); let m = 0b11111000; - let r = _mm_maskz_expandloadu_epi32(m, black_box(p)); + let r = unsafe { _mm_maskz_expandloadu_epi32(m, black_box(p)) }; let e = _mm_set_epi32(1, 0, 0, 0); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_expandloadu_epi64() { + fn test_mm512_mask_expandloadu_epi64() { let src = _mm512_set1_epi64(42); let a = &[1_i64, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm512_mask_expandloadu_epi64(src, m, black_box(p)); + let r = unsafe { _mm512_mask_expandloadu_epi64(src, m, black_box(p)) }; let e = _mm512_set_epi64(4, 3, 2, 42, 1, 42, 42, 42); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_expandloadu_epi64() { + fn test_mm512_maskz_expandloadu_epi64() { let a = &[1_i64, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm512_maskz_expandloadu_epi64(m, black_box(p)); + let r = unsafe { _mm512_maskz_expandloadu_epi64(m, black_box(p)) }; let e = _mm512_set_epi64(4, 3, 2, 0, 1, 0, 0, 0); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_expandloadu_epi64() { + fn test_mm256_mask_expandloadu_epi64() { let src = _mm256_set1_epi64x(42); let a = &[1_i64, 2, 3, 4]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm256_mask_expandloadu_epi64(src, m, black_box(p)); + let r = unsafe { _mm256_mask_expandloadu_epi64(src, m, black_box(p)) }; let e = _mm256_set_epi64x(1, 42, 42, 42); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_expandloadu_epi64() { + fn test_mm256_maskz_expandloadu_epi64() { let a = &[1_i64, 2, 3, 4]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm256_maskz_expandloadu_epi64(m, black_box(p)); + let r = unsafe { _mm256_maskz_expandloadu_epi64(m, black_box(p)) }; let e = _mm256_set_epi64x(1, 0, 0, 0); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_expandloadu_epi64() { + fn test_mm_mask_expandloadu_epi64() { let src = _mm_set1_epi64x(42); let a = &[1_i64, 2]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm_mask_expandloadu_epi64(src, m, black_box(p)); + let r = unsafe { _mm_mask_expandloadu_epi64(src, m, black_box(p)) }; let e = _mm_set_epi64x(42, 42); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_expandloadu_epi64() { + fn test_mm_maskz_expandloadu_epi64() { let a = &[1_i64, 2]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm_maskz_expandloadu_epi64(m, black_box(p)); + let r = unsafe { _mm_maskz_expandloadu_epi64(m, black_box(p)) }; let e = _mm_set_epi64x(0, 0); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_expandloadu_ps() { + fn test_mm512_mask_expandloadu_ps() { let src = _mm512_set1_ps(42.); let a = &[ 1.0f32, 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_mask_expandloadu_ps(src, m, black_box(p)); + let r = unsafe { _mm512_mask_expandloadu_ps(src, m, black_box(p)) }; let e = _mm512_set_ps( 8., 7., 6., 42., 5., 42., 42., 42., 4., 3., 42., 42., 2., 42., 1., 42., ); @@ -62332,13 +62512,13 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_expandloadu_ps() { + fn test_mm512_maskz_expandloadu_ps() { let a = &[ 1.0f32, 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., ]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm512_maskz_expandloadu_ps(m, black_box(p)); + let r = unsafe { _mm512_maskz_expandloadu_ps(m, black_box(p)) }; let e = _mm512_set_ps( 8., 7., 6., 0., 5., 0., 0., 0., 4., 3., 0., 0., 2., 0., 1., 0., ); @@ -62346,106 +62526,106 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_expandloadu_ps() { + fn test_mm256_mask_expandloadu_ps() { let src = _mm256_set1_ps(42.); let a = &[1.0f32, 2., 3., 4., 5., 6., 7., 8.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm256_mask_expandloadu_ps(src, m, black_box(p)); + let r = unsafe { _mm256_mask_expandloadu_ps(src, m, black_box(p)) }; let e = _mm256_set_ps(4., 3., 2., 42., 1., 42., 42., 42.); assert_eq_m256(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_expandloadu_ps() { + fn test_mm256_maskz_expandloadu_ps() { let a = &[1.0f32, 2., 3., 4., 5., 6., 7., 8.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm256_maskz_expandloadu_ps(m, black_box(p)); + let r = unsafe { _mm256_maskz_expandloadu_ps(m, black_box(p)) }; let e = _mm256_set_ps(4., 3., 2., 0., 1., 0., 0., 0.); assert_eq_m256(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_expandloadu_ps() { + fn test_mm_mask_expandloadu_ps() { let src = _mm_set1_ps(42.); let a = &[1.0f32, 2., 3., 4.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm_mask_expandloadu_ps(src, m, black_box(p)); + let r = unsafe { _mm_mask_expandloadu_ps(src, m, black_box(p)) }; let e = _mm_set_ps(1., 42., 42., 42.); assert_eq_m128(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_expandloadu_ps() { + fn test_mm_maskz_expandloadu_ps() { let a = &[1.0f32, 2., 3., 4.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm_maskz_expandloadu_ps(m, black_box(p)); + let r = unsafe { _mm_maskz_expandloadu_ps(m, black_box(p)) }; let e = _mm_set_ps(1., 0., 0., 0.); assert_eq_m128(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_expandloadu_pd() { + fn test_mm512_mask_expandloadu_pd() { let src = _mm512_set1_pd(42.); let a = &[1.0f64, 2., 3., 4., 5., 6., 7., 8.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm512_mask_expandloadu_pd(src, m, black_box(p)); + let r = unsafe { _mm512_mask_expandloadu_pd(src, m, black_box(p)) }; let e = _mm512_set_pd(4., 3., 2., 42., 1., 42., 42., 42.); assert_eq_m512d(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_maskz_expandloadu_pd() { + fn test_mm512_maskz_expandloadu_pd() { let a = &[1.0f64, 2., 3., 4., 5., 6., 7., 8.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm512_maskz_expandloadu_pd(m, black_box(p)); + let r = unsafe { _mm512_maskz_expandloadu_pd(m, black_box(p)) }; let e = _mm512_set_pd(4., 3., 2., 0., 1., 0., 0., 0.); assert_eq_m512d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_expandloadu_pd() { + fn test_mm256_mask_expandloadu_pd() { let src = _mm256_set1_pd(42.); let a = &[1.0f64, 2., 3., 4.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm256_mask_expandloadu_pd(src, m, black_box(p)); + let r = unsafe { _mm256_mask_expandloadu_pd(src, m, black_box(p)) }; let e = _mm256_set_pd(1., 42., 42., 42.); assert_eq_m256d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_maskz_expandloadu_pd() { + fn test_mm256_maskz_expandloadu_pd() { let a = &[1.0f64, 2., 3., 4.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm256_maskz_expandloadu_pd(m, black_box(p)); + let r = unsafe { _mm256_maskz_expandloadu_pd(m, black_box(p)) }; let e = _mm256_set_pd(1., 0., 0., 0.); assert_eq_m256d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_expandloadu_pd() { + fn test_mm_mask_expandloadu_pd() { let src = _mm_set1_pd(42.); let a = &[1.0f64, 2.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm_mask_expandloadu_pd(src, m, black_box(p)); + let r = unsafe { _mm_mask_expandloadu_pd(src, m, black_box(p)) }; let e = _mm_set_pd(42., 42.); assert_eq_m128d(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_maskz_expandloadu_pd() { + fn test_mm_maskz_expandloadu_pd() { let a = &[1.0f64, 2.]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm_maskz_expandloadu_pd(m, black_box(p)); + let r = unsafe { _mm_maskz_expandloadu_pd(m, black_box(p)) }; let e = _mm_set_pd(0., 0.); assert_eq_m128d(r, e); } diff --git a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs index 57d47c0bb010..f581711a3c99 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs @@ -16932,7 +16932,6 @@ unsafe extern "C" { mod tests { use crate::core_arch::assert_eq_const as assert_eq; use crate::core_arch::x86::*; - use crate::mem::transmute; use crate::ptr::{addr_of, addr_of_mut}; use stdarch_test::simd_test; @@ -17569,72 +17568,72 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm_load_ph() { + const fn test_mm_load_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); - let b = _mm_load_ph(addr_of!(a).cast()); + let b = unsafe { _mm_load_ph(addr_of!(a).cast()) }; assert_eq_m128h(a, b); } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm256_load_ph() { + const fn test_mm256_load_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); - let b = _mm256_load_ph(addr_of!(a).cast()); + let b = unsafe { _mm256_load_ph(addr_of!(a).cast()) }; assert_eq_m256h(a, b); } #[simd_test(enable = "avx512fp16")] - const unsafe fn test_mm512_load_ph() { + const fn test_mm512_load_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, ); - let b = _mm512_load_ph(addr_of!(a).cast()); + let b = unsafe { _mm512_load_ph(addr_of!(a).cast()) }; assert_eq_m512h(a, b); } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm_load_sh() { + const fn test_mm_load_sh() { let a = _mm_set_sh(1.0); - let b = _mm_load_sh(addr_of!(a).cast()); + let b = unsafe { _mm_load_sh(addr_of!(a).cast()) }; assert_eq_m128h(a, b); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_load_sh() { + fn test_mm_mask_load_sh() { let a = _mm_set_sh(1.0); let src = _mm_set_sh(2.); - let b = _mm_mask_load_sh(src, 1, addr_of!(a).cast()); + let b = unsafe { _mm_mask_load_sh(src, 1, addr_of!(a).cast()) }; assert_eq_m128h(a, b); - let b = _mm_mask_load_sh(src, 0, addr_of!(a).cast()); + let b = unsafe { _mm_mask_load_sh(src, 0, addr_of!(a).cast()) }; assert_eq_m128h(src, b); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_maskz_load_sh() { + fn test_mm_maskz_load_sh() { let a = _mm_set_sh(1.0); - let b = _mm_maskz_load_sh(1, addr_of!(a).cast()); + let b = unsafe { _mm_maskz_load_sh(1, addr_of!(a).cast()) }; assert_eq_m128h(a, b); - let b = _mm_maskz_load_sh(0, addr_of!(a).cast()); + let b = unsafe { _mm_maskz_load_sh(0, addr_of!(a).cast()) }; assert_eq_m128h(_mm_setzero_ph(), b); } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm_loadu_ph() { + const fn test_mm_loadu_ph() { let array = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; - let r = _mm_loadu_ph(array.as_ptr()); + let r = unsafe { _mm_loadu_ph(array.as_ptr()) }; let e = _mm_setr_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); assert_eq_m128h(r, e); } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm256_loadu_ph() { + const fn test_mm256_loadu_ph() { let array = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ]; - let r = _mm256_loadu_ph(array.as_ptr()); + let r = unsafe { _mm256_loadu_ph(array.as_ptr()) }; let e = _mm256_setr_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); @@ -17642,13 +17641,13 @@ mod tests { } #[simd_test(enable = "avx512fp16")] - const unsafe fn test_mm512_loadu_ph() { + const fn test_mm512_loadu_ph() { let array = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, ]; - let r = _mm512_loadu_ph(array.as_ptr()); + let r = unsafe { _mm512_loadu_ph(array.as_ptr()) }; let e = _mm512_setr_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, @@ -17686,81 +17685,99 @@ mod tests { } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm_store_ph() { + const fn test_mm_store_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let mut b = _mm_setzero_ph(); - _mm_store_ph(addr_of_mut!(b).cast(), a); + unsafe { + _mm_store_ph(addr_of_mut!(b).cast(), a); + } assert_eq_m128h(a, b); } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm256_store_ph() { + const fn test_mm256_store_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); let mut b = _mm256_setzero_ph(); - _mm256_store_ph(addr_of_mut!(b).cast(), a); + unsafe { + _mm256_store_ph(addr_of_mut!(b).cast(), a); + } assert_eq_m256h(a, b); } #[simd_test(enable = "avx512fp16")] - const unsafe fn test_mm512_store_ph() { + const fn test_mm512_store_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, ); let mut b = _mm512_setzero_ph(); - _mm512_store_ph(addr_of_mut!(b).cast(), a); + unsafe { + _mm512_store_ph(addr_of_mut!(b).cast(), a); + } assert_eq_m512h(a, b); } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm_store_sh() { + const fn test_mm_store_sh() { let a = _mm_set_sh(1.0); let mut b = _mm_setzero_ph(); - _mm_store_sh(addr_of_mut!(b).cast(), a); + unsafe { + _mm_store_sh(addr_of_mut!(b).cast(), a); + } assert_eq_m128h(a, b); } #[simd_test(enable = "avx512fp16,avx512vl")] - unsafe fn test_mm_mask_store_sh() { + fn test_mm_mask_store_sh() { let a = _mm_set_sh(1.0); let mut b = _mm_setzero_ph(); - _mm_mask_store_sh(addr_of_mut!(b).cast(), 0, a); + unsafe { + _mm_mask_store_sh(addr_of_mut!(b).cast(), 0, a); + } assert_eq_m128h(_mm_setzero_ph(), b); - _mm_mask_store_sh(addr_of_mut!(b).cast(), 1, a); + unsafe { + _mm_mask_store_sh(addr_of_mut!(b).cast(), 1, a); + } assert_eq_m128h(a, b); } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm_storeu_ph() { + const fn test_mm_storeu_ph() { let a = _mm_set_ph(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); let mut array = [0.0; 8]; - _mm_storeu_ph(array.as_mut_ptr(), a); - assert_eq_m128h(a, _mm_loadu_ph(array.as_ptr())); + unsafe { + _mm_storeu_ph(array.as_mut_ptr(), a); + } + assert_eq_m128h(a, unsafe { _mm_loadu_ph(array.as_ptr()) }); } #[simd_test(enable = "avx512fp16,avx512vl")] - const unsafe fn test_mm256_storeu_ph() { + const fn test_mm256_storeu_ph() { let a = _mm256_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ); let mut array = [0.0; 16]; - _mm256_storeu_ph(array.as_mut_ptr(), a); - assert_eq_m256h(a, _mm256_loadu_ph(array.as_ptr())); + unsafe { + _mm256_storeu_ph(array.as_mut_ptr(), a); + } + assert_eq_m256h(a, unsafe { _mm256_loadu_ph(array.as_ptr()) }); } #[simd_test(enable = "avx512fp16")] - const unsafe fn test_mm512_storeu_ph() { + const fn test_mm512_storeu_ph() { let a = _mm512_set_ph( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, ); let mut array = [0.0; 32]; - _mm512_storeu_ph(array.as_mut_ptr(), a); - assert_eq_m512h(a, _mm512_loadu_ph(array.as_ptr())); + unsafe { + _mm512_storeu_ph(array.as_mut_ptr(), a); + } + assert_eq_m512h(a, unsafe { _mm512_loadu_ph(array.as_ptr()) }); } #[simd_test(enable = "avx512fp16,avx512vl")] diff --git a/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs b/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs index 26cef5814e9c..78a50b90c861 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs @@ -3932,7 +3932,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_expandloadu_epi16() { + fn test_mm512_mask_expandloadu_epi16() { let src = _mm512_set1_epi16(42); let a = &[ 1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -3940,7 +3940,7 @@ mod tests { ]; let p = a.as_ptr(); let m = 0b11101000_11001010_11110000_00001111; - let r = _mm512_mask_expandloadu_epi16(src, m, black_box(p)); + let r = unsafe { _mm512_mask_expandloadu_epi16(src, m, black_box(p)) }; let e = _mm512_set_epi16( 16, 15, 14, 42, 13, 42, 42, 42, 12, 11, 42, 42, 10, 42, 9, 42, 8, 7, 6, 5, 42, 42, 42, 42, 42, 42, 42, 42, 4, 3, 2, 1, @@ -3949,14 +3949,14 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_expandloadu_epi16() { + fn test_mm512_maskz_expandloadu_epi16() { let a = &[ 1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ]; let p = a.as_ptr(); let m = 0b11101000_11001010_11110000_00001111; - let r = _mm512_maskz_expandloadu_epi16(m, black_box(p)); + let r = unsafe { _mm512_maskz_expandloadu_epi16(m, black_box(p)) }; let e = _mm512_set_epi16( 16, 15, 14, 0, 13, 0, 0, 0, 12, 11, 0, 0, 10, 0, 9, 0, 8, 7, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 1, @@ -3965,49 +3965,49 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_expandloadu_epi16() { + fn test_mm256_mask_expandloadu_epi16() { let src = _mm256_set1_epi16(42); let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm256_mask_expandloadu_epi16(src, m, black_box(p)); + let r = unsafe { _mm256_mask_expandloadu_epi16(src, m, black_box(p)) }; let e = _mm256_set_epi16(8, 7, 6, 42, 5, 42, 42, 42, 4, 3, 42, 42, 2, 42, 1, 42); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_expandloadu_epi16() { + fn test_mm256_maskz_expandloadu_epi16() { let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm256_maskz_expandloadu_epi16(m, black_box(p)); + let r = unsafe { _mm256_maskz_expandloadu_epi16(m, black_box(p)) }; let e = _mm256_set_epi16(8, 7, 6, 0, 5, 0, 0, 0, 4, 3, 0, 0, 2, 0, 1, 0); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_expandloadu_epi16() { + fn test_mm_mask_expandloadu_epi16() { let src = _mm_set1_epi16(42); let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm_mask_expandloadu_epi16(src, m, black_box(p)); + let r = unsafe { _mm_mask_expandloadu_epi16(src, m, black_box(p)) }; let e = _mm_set_epi16(4, 3, 2, 42, 1, 42, 42, 42); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_expandloadu_epi16() { + fn test_mm_maskz_expandloadu_epi16() { let a = &[1_i16, 2, 3, 4, 5, 6, 7, 8]; let p = a.as_ptr(); let m = 0b11101000; - let r = _mm_maskz_expandloadu_epi16(m, black_box(p)); + let r = unsafe { _mm_maskz_expandloadu_epi16(m, black_box(p)) }; let e = _mm_set_epi16(4, 3, 2, 0, 1, 0, 0, 0); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_expandloadu_epi8() { + fn test_mm512_mask_expandloadu_epi8() { let src = _mm512_set1_epi8(42); let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -4016,7 +4016,7 @@ mod tests { ]; let p = a.as_ptr(); let m = 0b11101000_11001010_11110000_00001111_11111111_00000000_10101010_01010101; - let r = _mm512_mask_expandloadu_epi8(src, m, black_box(p)); + let r = unsafe { _mm512_mask_expandloadu_epi8(src, m, black_box(p)) }; let e = _mm512_set_epi8( 32, 31, 30, 42, 29, 42, 42, 42, 28, 27, 42, 42, 26, 42, 25, 42, 24, 23, 22, 21, 42, 42, 42, 42, 42, 42, 42, 42, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 42, 42, 42, 42, @@ -4026,7 +4026,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_maskz_expandloadu_epi8() { + fn test_mm512_maskz_expandloadu_epi8() { let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, @@ -4034,7 +4034,7 @@ mod tests { ]; let p = a.as_ptr(); let m = 0b11101000_11001010_11110000_00001111_11111111_00000000_10101010_01010101; - let r = _mm512_maskz_expandloadu_epi8(m, black_box(p)); + let r = unsafe { _mm512_maskz_expandloadu_epi8(m, black_box(p)) }; let e = _mm512_set_epi8( 32, 31, 30, 0, 29, 0, 0, 0, 28, 27, 0, 0, 26, 0, 25, 0, 24, 23, 22, 21, 0, 0, 0, 0, 0, 0, 0, 0, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, @@ -4044,7 +4044,7 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_expandloadu_epi8() { + fn test_mm256_mask_expandloadu_epi8() { let src = _mm256_set1_epi8(42); let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -4052,7 +4052,7 @@ mod tests { ]; let p = a.as_ptr(); let m = 0b11101000_11001010_11110000_00001111; - let r = _mm256_mask_expandloadu_epi8(src, m, black_box(p)); + let r = unsafe { _mm256_mask_expandloadu_epi8(src, m, black_box(p)) }; let e = _mm256_set_epi8( 16, 15, 14, 42, 13, 42, 42, 42, 12, 11, 42, 42, 10, 42, 9, 42, 8, 7, 6, 5, 42, 42, 42, 42, 42, 42, 42, 42, 4, 3, 2, 1, @@ -4061,14 +4061,14 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_maskz_expandloadu_epi8() { + fn test_mm256_maskz_expandloadu_epi8() { let a = &[ 1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ]; let p = a.as_ptr(); let m = 0b11101000_11001010_11110000_00001111; - let r = _mm256_maskz_expandloadu_epi8(m, black_box(p)); + let r = unsafe { _mm256_maskz_expandloadu_epi8(m, black_box(p)) }; let e = _mm256_set_epi8( 16, 15, 14, 0, 13, 0, 0, 0, 12, 11, 0, 0, 10, 0, 9, 0, 8, 7, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 1, @@ -4077,36 +4077,44 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_expandloadu_epi8() { + fn test_mm_mask_expandloadu_epi8() { let src = _mm_set1_epi8(42); let a = &[1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm_mask_expandloadu_epi8(src, m, black_box(p)); + let r = unsafe { _mm_mask_expandloadu_epi8(src, m, black_box(p)) }; let e = _mm_set_epi8(8, 7, 6, 42, 5, 42, 42, 42, 4, 3, 42, 42, 2, 42, 1, 42); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_maskz_expandloadu_epi8() { + fn test_mm_maskz_expandloadu_epi8() { let a = &[1_i8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; let p = a.as_ptr(); let m = 0b11101000_11001010; - let r = _mm_maskz_expandloadu_epi8(m, black_box(p)); + let r = unsafe { _mm_maskz_expandloadu_epi8(m, black_box(p)) }; let e = _mm_set_epi8(8, 7, 6, 0, 5, 0, 0, 0, 4, 3, 0, 0, 2, 0, 1, 0); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_compressstoreu_epi16() { + fn test_mm512_mask_compressstoreu_epi16() { let a = _mm512_set_epi16( 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ); let mut r = [0_i16; 32]; - _mm512_mask_compressstoreu_epi16(r.as_mut_ptr(), 0, a); + unsafe { + _mm512_mask_compressstoreu_epi16(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i16; 32]); - _mm512_mask_compressstoreu_epi16(r.as_mut_ptr(), 0b11110000_11001010_11111111_00000000, a); + unsafe { + _mm512_mask_compressstoreu_epi16( + r.as_mut_ptr(), + 0b11110000_11001010_11111111_00000000, + a, + ); + } assert_eq!( &r, &[ @@ -4117,40 +4125,52 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_compressstoreu_epi16() { + fn test_mm256_mask_compressstoreu_epi16() { let a = _mm256_set_epi16(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); let mut r = [0_i16; 16]; - _mm256_mask_compressstoreu_epi16(r.as_mut_ptr(), 0, a); + unsafe { + _mm256_mask_compressstoreu_epi16(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i16; 16]); - _mm256_mask_compressstoreu_epi16(r.as_mut_ptr(), 0b11110000_11001010, a); + unsafe { + _mm256_mask_compressstoreu_epi16(r.as_mut_ptr(), 0b11110000_11001010, a); + } assert_eq!(&r, &[2, 4, 7, 8, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0]); } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_compressstoreu_epi16() { + fn test_mm_mask_compressstoreu_epi16() { let a = _mm_set_epi16(8, 7, 6, 5, 4, 3, 2, 1); let mut r = [0_i16; 8]; - _mm_mask_compressstoreu_epi16(r.as_mut_ptr(), 0, a); + unsafe { + _mm_mask_compressstoreu_epi16(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i16; 8]); - _mm_mask_compressstoreu_epi16(r.as_mut_ptr(), 0b11110000, a); + unsafe { + _mm_mask_compressstoreu_epi16(r.as_mut_ptr(), 0b11110000, a); + } assert_eq!(&r, &[5, 6, 7, 8, 0, 0, 0, 0]); } #[simd_test(enable = "avx512vbmi2")] - unsafe fn test_mm512_mask_compressstoreu_epi8() { + fn test_mm512_mask_compressstoreu_epi8() { let a = _mm512_set_epi8( 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ); let mut r = [0_i8; 64]; - _mm512_mask_compressstoreu_epi8(r.as_mut_ptr(), 0, a); + unsafe { + _mm512_mask_compressstoreu_epi8(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i8; 64]); - _mm512_mask_compressstoreu_epi8( - r.as_mut_ptr(), - 0b11110000_11001010_11111111_00000000_10101010_01010101_11110000_00001111, - a, - ); + unsafe { + _mm512_mask_compressstoreu_epi8( + r.as_mut_ptr(), + 0b11110000_11001010_11111111_00000000_10101010_01010101_11110000_00001111, + a, + ); + } assert_eq!( &r, &[ @@ -4162,15 +4182,23 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm256_mask_compressstoreu_epi8() { + fn test_mm256_mask_compressstoreu_epi8() { let a = _mm256_set_epi8( 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ); let mut r = [0_i8; 32]; - _mm256_mask_compressstoreu_epi8(r.as_mut_ptr(), 0, a); + unsafe { + _mm256_mask_compressstoreu_epi8(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i8; 32]); - _mm256_mask_compressstoreu_epi8(r.as_mut_ptr(), 0b11110000_11001010_11111111_00000000, a); + unsafe { + _mm256_mask_compressstoreu_epi8( + r.as_mut_ptr(), + 0b11110000_11001010_11111111_00000000, + a, + ); + } assert_eq!( &r, &[ @@ -4181,12 +4209,16 @@ mod tests { } #[simd_test(enable = "avx512vbmi2,avx512vl")] - unsafe fn test_mm_mask_compressstoreu_epi8() { + fn test_mm_mask_compressstoreu_epi8() { let a = _mm_set_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); let mut r = [0_i8; 16]; - _mm_mask_compressstoreu_epi8(r.as_mut_ptr(), 0, a); + unsafe { + _mm_mask_compressstoreu_epi8(r.as_mut_ptr(), 0, a); + } assert_eq!(&r, &[0_i8; 16]); - _mm_mask_compressstoreu_epi8(r.as_mut_ptr(), 0b11110000_11001010, a); + unsafe { + _mm_mask_compressstoreu_epi8(r.as_mut_ptr(), 0b11110000_11001010, a); + } assert_eq!(&r, &[2, 4, 7, 8, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0]); } } diff --git a/library/stdarch/crates/core_arch/src/x86/avxneconvert.rs b/library/stdarch/crates/core_arch/src/x86/avxneconvert.rs index a53d6d97e8a0..91b6be2b09d7 100644 --- a/library/stdarch/crates/core_arch/src/x86/avxneconvert.rs +++ b/library/stdarch/crates/core_arch/src/x86/avxneconvert.rs @@ -242,127 +242,127 @@ mod tests { const BF16_EIGHT: u16 = 0b0_10000010_0000000; #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm_bcstnebf16_ps() { + fn test_mm_bcstnebf16_ps() { let a = bf16::from_bits(BF16_ONE); - let r = _mm_bcstnebf16_ps(addr_of!(a)); + let r = unsafe { _mm_bcstnebf16_ps(addr_of!(a)) }; let e = _mm_set_ps(1., 1., 1., 1.); assert_eq_m128(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm256_bcstnebf16_ps() { + fn test_mm256_bcstnebf16_ps() { let a = bf16::from_bits(BF16_ONE); - let r = _mm256_bcstnebf16_ps(addr_of!(a)); + let r = unsafe { _mm256_bcstnebf16_ps(addr_of!(a)) }; let e = _mm256_set_ps(1., 1., 1., 1., 1., 1., 1., 1.); assert_eq_m256(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm_bcstnesh_ps() { + fn test_mm_bcstnesh_ps() { let a = 1.0_f16; - let r = _mm_bcstnesh_ps(addr_of!(a)); + let r = unsafe { _mm_bcstnesh_ps(addr_of!(a)) }; let e = _mm_set_ps(1., 1., 1., 1.); assert_eq_m128(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm256_bcstnesh_ps() { + fn test_mm256_bcstnesh_ps() { let a = 1.0_f16; - let r = _mm256_bcstnesh_ps(addr_of!(a)); + let r = unsafe { _mm256_bcstnesh_ps(addr_of!(a)) }; let e = _mm256_set_ps(1., 1., 1., 1., 1., 1., 1., 1.); assert_eq_m256(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm_cvtneebf16_ps() { + fn test_mm_cvtneebf16_ps() { let a = __m128bh([ BF16_ONE, BF16_TWO, BF16_THREE, BF16_FOUR, BF16_FIVE, BF16_SIX, BF16_SEVEN, BF16_EIGHT, ]); - let r = _mm_cvtneebf16_ps(addr_of!(a)); + let r = unsafe { _mm_cvtneebf16_ps(addr_of!(a)) }; let e = _mm_setr_ps(1., 3., 5., 7.); assert_eq_m128(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm256_cvtneebf16_ps() { + fn test_mm256_cvtneebf16_ps() { let a = __m256bh([ BF16_ONE, BF16_TWO, BF16_THREE, BF16_FOUR, BF16_FIVE, BF16_SIX, BF16_SEVEN, BF16_EIGHT, BF16_ONE, BF16_TWO, BF16_THREE, BF16_FOUR, BF16_FIVE, BF16_SIX, BF16_SEVEN, BF16_EIGHT, ]); - let r = _mm256_cvtneebf16_ps(addr_of!(a)); + let r = unsafe { _mm256_cvtneebf16_ps(addr_of!(a)) }; let e = _mm256_setr_ps(1., 3., 5., 7., 1., 3., 5., 7.); assert_eq_m256(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm_cvtneeph_ps() { + fn test_mm_cvtneeph_ps() { let a = __m128h([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]); - let r = _mm_cvtneeph_ps(addr_of!(a)); + let r = unsafe { _mm_cvtneeph_ps(addr_of!(a)) }; let e = _mm_setr_ps(1., 3., 5., 7.); assert_eq_m128(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm256_cvtneeph_ps() { + fn test_mm256_cvtneeph_ps() { let a = __m256h([ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ]); - let r = _mm256_cvtneeph_ps(addr_of!(a)); + let r = unsafe { _mm256_cvtneeph_ps(addr_of!(a)) }; let e = _mm256_setr_ps(1., 3., 5., 7., 9., 11., 13., 15.); assert_eq_m256(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm_cvtneobf16_ps() { + fn test_mm_cvtneobf16_ps() { let a = __m128bh([ BF16_ONE, BF16_TWO, BF16_THREE, BF16_FOUR, BF16_FIVE, BF16_SIX, BF16_SEVEN, BF16_EIGHT, ]); - let r = _mm_cvtneobf16_ps(addr_of!(a)); + let r = unsafe { _mm_cvtneobf16_ps(addr_of!(a)) }; let e = _mm_setr_ps(2., 4., 6., 8.); assert_eq_m128(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm256_cvtneobf16_ps() { + fn test_mm256_cvtneobf16_ps() { let a = __m256bh([ BF16_ONE, BF16_TWO, BF16_THREE, BF16_FOUR, BF16_FIVE, BF16_SIX, BF16_SEVEN, BF16_EIGHT, BF16_ONE, BF16_TWO, BF16_THREE, BF16_FOUR, BF16_FIVE, BF16_SIX, BF16_SEVEN, BF16_EIGHT, ]); - let r = _mm256_cvtneobf16_ps(addr_of!(a)); + let r = unsafe { _mm256_cvtneobf16_ps(addr_of!(a)) }; let e = _mm256_setr_ps(2., 4., 6., 8., 2., 4., 6., 8.); assert_eq_m256(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm_cvtneoph_ps() { + fn test_mm_cvtneoph_ps() { let a = __m128h([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]); - let r = _mm_cvtneoph_ps(addr_of!(a)); + let r = unsafe { _mm_cvtneoph_ps(addr_of!(a)) }; let e = _mm_setr_ps(2., 4., 6., 8.); assert_eq_m128(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm256_cvtneoph_ps() { + fn test_mm256_cvtneoph_ps() { let a = __m256h([ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, ]); - let r = _mm256_cvtneoph_ps(addr_of!(a)); + let r = unsafe { _mm256_cvtneoph_ps(addr_of!(a)) }; let e = _mm256_setr_ps(2., 4., 6., 8., 10., 12., 14., 16.); assert_eq_m256(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm_cvtneps_avx_pbh() { + fn test_mm_cvtneps_avx_pbh() { let a = _mm_setr_ps(1., 2., 3., 4.); - let r: u16x4 = transmute_copy(&_mm_cvtneps_avx_pbh(a)); + let r: u16x4 = unsafe { transmute_copy(&_mm_cvtneps_avx_pbh(a)) }; let e = u16x4::new(BF16_ONE, BF16_TWO, BF16_THREE, BF16_FOUR); assert_eq!(r, e); } #[simd_test(enable = "avxneconvert")] - unsafe fn test_mm256_cvtneps_avx_pbh() { + fn test_mm256_cvtneps_avx_pbh() { let a = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); - let r: u16x8 = transmute(_mm256_cvtneps_avx_pbh(a)); + let r: u16x8 = _mm256_cvtneps_avx_pbh(a).as_u16x8(); let e = u16x8::new( BF16_ONE, BF16_TWO, BF16_THREE, BF16_FOUR, BF16_FIVE, BF16_SIX, BF16_SEVEN, BF16_EIGHT, ); diff --git a/library/stdarch/crates/core_arch/src/x86/f16c.rs b/library/stdarch/crates/core_arch/src/x86/f16c.rs index 0a26a9ff8d25..a0bb992bb9d4 100644 --- a/library/stdarch/crates/core_arch/src/x86/f16c.rs +++ b/library/stdarch/crates/core_arch/src/x86/f16c.rs @@ -106,7 +106,7 @@ pub fn _mm256_cvtps_ph(a: __m256) -> __m128i { #[cfg(test)] mod tests { use crate::core_arch::assert_eq_const as assert_eq; - use crate::{core_arch::x86::*, mem::transmute}; + use crate::core_arch::x86::*; use stdarch_test::simd_test; const F16_ONE: i16 = 0x3c00; diff --git a/library/stdarch/crates/core_arch/src/x86/fxsr.rs b/library/stdarch/crates/core_arch/src/x86/fxsr.rs index 71fd52ca1496..08619efe7c9e 100644 --- a/library/stdarch/crates/core_arch/src/x86/fxsr.rs +++ b/library/stdarch/crates/core_arch/src/x86/fxsr.rs @@ -77,12 +77,14 @@ mod tests { #[simd_test(enable = "fxsr")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri - unsafe fn test_fxsave() { + fn test_fxsave() { let mut a = FxsaveArea::new(); let mut b = FxsaveArea::new(); - fxsr::_fxsave(a.ptr()); - fxsr::_fxrstor(a.ptr()); - fxsr::_fxsave(b.ptr()); + unsafe { + fxsr::_fxsave(a.ptr()); + fxsr::_fxrstor(a.ptr()); + fxsr::_fxsave(b.ptr()); + } } } diff --git a/library/stdarch/crates/core_arch/src/x86/gfni.rs b/library/stdarch/crates/core_arch/src/x86/gfni.rs index 681b8ae330d4..e9ee27a7b823 100644 --- a/library/stdarch/crates/core_arch/src/x86/gfni.rs +++ b/library/stdarch/crates/core_arch/src/x86/gfni.rs @@ -898,25 +898,25 @@ mod tests { } #[simd_test(enable = "gfni,avx512f")] - unsafe fn test_mm512_gf2p8mul_epi8() { + fn test_mm512_gf2p8mul_epi8() { let (left, right, expected) = generate_byte_mul_test_data(); for i in 0..NUM_TEST_WORDS_512 { - let left = load_m512i_word(&left, i); - let right = load_m512i_word(&right, i); - let expected = load_m512i_word(&expected, i); + let left = unsafe { load_m512i_word(&left, i) }; + let right = unsafe { load_m512i_word(&right, i) }; + let expected = unsafe { load_m512i_word(&expected, i) }; let result = _mm512_gf2p8mul_epi8(left, right); assert_eq_m512i(result, expected); } } #[simd_test(enable = "gfni,avx512bw")] - unsafe fn test_mm512_maskz_gf2p8mul_epi8() { + fn test_mm512_maskz_gf2p8mul_epi8() { let (left, right, _expected) = generate_byte_mul_test_data(); for i in 0..NUM_TEST_WORDS_512 { - let left = load_m512i_word(&left, i); - let right = load_m512i_word(&right, i); + let left = unsafe { load_m512i_word(&left, i) }; + let right = unsafe { load_m512i_word(&right, i) }; let result_zero = _mm512_maskz_gf2p8mul_epi8(0, left, right); assert_eq_m512i(result_zero, _mm512_setzero_si512()); let mask_bytes: __mmask64 = 0x0F_0F_0F_0F_FF_FF_00_00; @@ -930,12 +930,12 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw")] - unsafe fn test_mm512_mask_gf2p8mul_epi8() { + fn test_mm512_mask_gf2p8mul_epi8() { let (left, right, _expected) = generate_byte_mul_test_data(); for i in 0..NUM_TEST_WORDS_512 { - let left = load_m512i_word(&left, i); - let right = load_m512i_word(&right, i); + let left = unsafe { load_m512i_word(&left, i) }; + let right = unsafe { load_m512i_word(&right, i) }; let result_left = _mm512_mask_gf2p8mul_epi8(left, 0, left, right); assert_eq_m512i(result_left, left); let mask_bytes: __mmask64 = 0x0F_0F_0F_0F_FF_FF_00_00; @@ -948,25 +948,25 @@ mod tests { } #[simd_test(enable = "gfni,avx")] - unsafe fn test_mm256_gf2p8mul_epi8() { + fn test_mm256_gf2p8mul_epi8() { let (left, right, expected) = generate_byte_mul_test_data(); for i in 0..NUM_TEST_WORDS_256 { - let left = load_m256i_word(&left, i); - let right = load_m256i_word(&right, i); - let expected = load_m256i_word(&expected, i); + let left = unsafe { load_m256i_word(&left, i) }; + let right = unsafe { load_m256i_word(&right, i) }; + let expected = unsafe { load_m256i_word(&expected, i) }; let result = _mm256_gf2p8mul_epi8(left, right); assert_eq_m256i(result, expected); } } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_gf2p8mul_epi8() { + fn test_mm256_maskz_gf2p8mul_epi8() { let (left, right, _expected) = generate_byte_mul_test_data(); for i in 0..NUM_TEST_WORDS_256 { - let left = load_m256i_word(&left, i); - let right = load_m256i_word(&right, i); + let left = unsafe { load_m256i_word(&left, i) }; + let right = unsafe { load_m256i_word(&right, i) }; let result_zero = _mm256_maskz_gf2p8mul_epi8(0, left, right); assert_eq_m256i(result_zero, _mm256_setzero_si256()); let mask_bytes: __mmask32 = 0x0F_F0_FF_00; @@ -980,12 +980,12 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm256_mask_gf2p8mul_epi8() { + fn test_mm256_mask_gf2p8mul_epi8() { let (left, right, _expected) = generate_byte_mul_test_data(); for i in 0..NUM_TEST_WORDS_256 { - let left = load_m256i_word(&left, i); - let right = load_m256i_word(&right, i); + let left = unsafe { load_m256i_word(&left, i) }; + let right = unsafe { load_m256i_word(&right, i) }; let result_left = _mm256_mask_gf2p8mul_epi8(left, 0, left, right); assert_eq_m256i(result_left, left); let mask_bytes: __mmask32 = 0x0F_F0_FF_00; @@ -998,25 +998,25 @@ mod tests { } #[simd_test(enable = "gfni")] - unsafe fn test_mm_gf2p8mul_epi8() { + fn test_mm_gf2p8mul_epi8() { let (left, right, expected) = generate_byte_mul_test_data(); for i in 0..NUM_TEST_WORDS_128 { - let left = load_m128i_word(&left, i); - let right = load_m128i_word(&right, i); - let expected = load_m128i_word(&expected, i); + let left = unsafe { load_m128i_word(&left, i) }; + let right = unsafe { load_m128i_word(&right, i) }; + let expected = unsafe { load_m128i_word(&expected, i) }; let result = _mm_gf2p8mul_epi8(left, right); assert_eq_m128i(result, expected); } } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm_maskz_gf2p8mul_epi8() { + fn test_mm_maskz_gf2p8mul_epi8() { let (left, right, _expected) = generate_byte_mul_test_data(); for i in 0..NUM_TEST_WORDS_128 { - let left = load_m128i_word(&left, i); - let right = load_m128i_word(&right, i); + let left = unsafe { load_m128i_word(&left, i) }; + let right = unsafe { load_m128i_word(&right, i) }; let result_zero = _mm_maskz_gf2p8mul_epi8(0, left, right); assert_eq_m128i(result_zero, _mm_setzero_si128()); let mask_bytes: __mmask16 = 0x0F_F0; @@ -1030,12 +1030,12 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm_mask_gf2p8mul_epi8() { + fn test_mm_mask_gf2p8mul_epi8() { let (left, right, _expected) = generate_byte_mul_test_data(); for i in 0..NUM_TEST_WORDS_128 { - let left = load_m128i_word(&left, i); - let right = load_m128i_word(&right, i); + let left = unsafe { load_m128i_word(&left, i) }; + let right = unsafe { load_m128i_word(&right, i) }; let result_left = _mm_mask_gf2p8mul_epi8(left, 0, left, right); assert_eq_m128i(result_left, left); let mask_bytes: __mmask16 = 0x0F_F0; @@ -1048,7 +1048,7 @@ mod tests { } #[simd_test(enable = "gfni,avx512f")] - unsafe fn test_mm512_gf2p8affine_epi64_epi8() { + fn test_mm512_gf2p8affine_epi64_epi8() { let identity: i64 = 0x01_02_04_08_10_20_40_80; const IDENTITY_BYTE: i32 = 0; let constant: i64 = 0; @@ -1061,20 +1061,20 @@ mod tests { let (matrices, vectors, references) = generate_affine_mul_test_data(IDENTITY_BYTE as u8); for i in 0..NUM_TEST_WORDS_512 { - let data = load_m512i_word(&bytes, i); + let data = unsafe { load_m512i_word(&bytes, i) }; let result = _mm512_gf2p8affine_epi64_epi8::(data, identity); assert_eq_m512i(result, data); let result = _mm512_gf2p8affine_epi64_epi8::(data, constant); assert_eq_m512i(result, constant_reference); - let data = load_m512i_word(&more_bytes, i); + let data = unsafe { load_m512i_word(&more_bytes, i) }; let result = _mm512_gf2p8affine_epi64_epi8::(data, identity); assert_eq_m512i(result, data); let result = _mm512_gf2p8affine_epi64_epi8::(data, constant); assert_eq_m512i(result, constant_reference); - let matrix = load_m512i_word(&matrices, i); - let vector = load_m512i_word(&vectors, i); - let reference = load_m512i_word(&references, i); + let matrix = unsafe { load_m512i_word(&matrices, i) }; + let vector = unsafe { load_m512i_word(&vectors, i) }; + let reference = unsafe { load_m512i_word(&references, i) }; let result = _mm512_gf2p8affine_epi64_epi8::(vector, matrix); assert_eq_m512i(result, reference); @@ -1082,13 +1082,13 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw")] - unsafe fn test_mm512_maskz_gf2p8affine_epi64_epi8() { + fn test_mm512_maskz_gf2p8affine_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_512 { - let matrix = load_m512i_word(&matrices, i); - let vector = load_m512i_word(&vectors, i); + let matrix = unsafe { load_m512i_word(&matrices, i) }; + let vector = unsafe { load_m512i_word(&vectors, i) }; let result_zero = _mm512_maskz_gf2p8affine_epi64_epi8::(0, vector, matrix); assert_eq_m512i(result_zero, _mm512_setzero_si512()); @@ -1104,13 +1104,13 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw")] - unsafe fn test_mm512_mask_gf2p8affine_epi64_epi8() { + fn test_mm512_mask_gf2p8affine_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_512 { - let left = load_m512i_word(&vectors, i); - let right = load_m512i_word(&matrices, i); + let left = unsafe { load_m512i_word(&vectors, i) }; + let right = unsafe { load_m512i_word(&matrices, i) }; let result_left = _mm512_mask_gf2p8affine_epi64_epi8::(left, 0, left, right); assert_eq_m512i(result_left, left); @@ -1125,7 +1125,7 @@ mod tests { } #[simd_test(enable = "gfni,avx")] - unsafe fn test_mm256_gf2p8affine_epi64_epi8() { + fn test_mm256_gf2p8affine_epi64_epi8() { let identity: i64 = 0x01_02_04_08_10_20_40_80; const IDENTITY_BYTE: i32 = 0; let constant: i64 = 0; @@ -1138,20 +1138,20 @@ mod tests { let (matrices, vectors, references) = generate_affine_mul_test_data(IDENTITY_BYTE as u8); for i in 0..NUM_TEST_WORDS_256 { - let data = load_m256i_word(&bytes, i); + let data = unsafe { load_m256i_word(&bytes, i) }; let result = _mm256_gf2p8affine_epi64_epi8::(data, identity); assert_eq_m256i(result, data); let result = _mm256_gf2p8affine_epi64_epi8::(data, constant); assert_eq_m256i(result, constant_reference); - let data = load_m256i_word(&more_bytes, i); + let data = unsafe { load_m256i_word(&more_bytes, i) }; let result = _mm256_gf2p8affine_epi64_epi8::(data, identity); assert_eq_m256i(result, data); let result = _mm256_gf2p8affine_epi64_epi8::(data, constant); assert_eq_m256i(result, constant_reference); - let matrix = load_m256i_word(&matrices, i); - let vector = load_m256i_word(&vectors, i); - let reference = load_m256i_word(&references, i); + let matrix = unsafe { load_m256i_word(&matrices, i) }; + let vector = unsafe { load_m256i_word(&vectors, i) }; + let reference = unsafe { load_m256i_word(&references, i) }; let result = _mm256_gf2p8affine_epi64_epi8::(vector, matrix); assert_eq_m256i(result, reference); @@ -1159,13 +1159,13 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_gf2p8affine_epi64_epi8() { + fn test_mm256_maskz_gf2p8affine_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_256 { - let matrix = load_m256i_word(&matrices, i); - let vector = load_m256i_word(&vectors, i); + let matrix = unsafe { load_m256i_word(&matrices, i) }; + let vector = unsafe { load_m256i_word(&vectors, i) }; let result_zero = _mm256_maskz_gf2p8affine_epi64_epi8::(0, vector, matrix); assert_eq_m256i(result_zero, _mm256_setzero_si256()); @@ -1181,13 +1181,13 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm256_mask_gf2p8affine_epi64_epi8() { + fn test_mm256_mask_gf2p8affine_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_256 { - let left = load_m256i_word(&vectors, i); - let right = load_m256i_word(&matrices, i); + let left = unsafe { load_m256i_word(&vectors, i) }; + let right = unsafe { load_m256i_word(&matrices, i) }; let result_left = _mm256_mask_gf2p8affine_epi64_epi8::(left, 0, left, right); assert_eq_m256i(result_left, left); @@ -1202,7 +1202,7 @@ mod tests { } #[simd_test(enable = "gfni")] - unsafe fn test_mm_gf2p8affine_epi64_epi8() { + fn test_mm_gf2p8affine_epi64_epi8() { let identity: i64 = 0x01_02_04_08_10_20_40_80; const IDENTITY_BYTE: i32 = 0; let constant: i64 = 0; @@ -1215,20 +1215,20 @@ mod tests { let (matrices, vectors, references) = generate_affine_mul_test_data(IDENTITY_BYTE as u8); for i in 0..NUM_TEST_WORDS_128 { - let data = load_m128i_word(&bytes, i); + let data = unsafe { load_m128i_word(&bytes, i) }; let result = _mm_gf2p8affine_epi64_epi8::(data, identity); assert_eq_m128i(result, data); let result = _mm_gf2p8affine_epi64_epi8::(data, constant); assert_eq_m128i(result, constant_reference); - let data = load_m128i_word(&more_bytes, i); + let data = unsafe { load_m128i_word(&more_bytes, i) }; let result = _mm_gf2p8affine_epi64_epi8::(data, identity); assert_eq_m128i(result, data); let result = _mm_gf2p8affine_epi64_epi8::(data, constant); assert_eq_m128i(result, constant_reference); - let matrix = load_m128i_word(&matrices, i); - let vector = load_m128i_word(&vectors, i); - let reference = load_m128i_word(&references, i); + let matrix = unsafe { load_m128i_word(&matrices, i) }; + let vector = unsafe { load_m128i_word(&vectors, i) }; + let reference = unsafe { load_m128i_word(&references, i) }; let result = _mm_gf2p8affine_epi64_epi8::(vector, matrix); assert_eq_m128i(result, reference); @@ -1236,13 +1236,13 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm_maskz_gf2p8affine_epi64_epi8() { + fn test_mm_maskz_gf2p8affine_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_128 { - let matrix = load_m128i_word(&matrices, i); - let vector = load_m128i_word(&vectors, i); + let matrix = unsafe { load_m128i_word(&matrices, i) }; + let vector = unsafe { load_m128i_word(&vectors, i) }; let result_zero = _mm_maskz_gf2p8affine_epi64_epi8::(0, vector, matrix); assert_eq_m128i(result_zero, _mm_setzero_si128()); let mask_bytes: __mmask16 = 0x0F_F0; @@ -1257,13 +1257,13 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm_mask_gf2p8affine_epi64_epi8() { + fn test_mm_mask_gf2p8affine_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_128 { - let left = load_m128i_word(&vectors, i); - let right = load_m128i_word(&matrices, i); + let left = unsafe { load_m128i_word(&vectors, i) }; + let right = unsafe { load_m128i_word(&matrices, i) }; let result_left = _mm_mask_gf2p8affine_epi64_epi8::(left, 0, left, right); assert_eq_m128i(result_left, left); @@ -1278,7 +1278,7 @@ mod tests { } #[simd_test(enable = "gfni,avx512f")] - unsafe fn test_mm512_gf2p8affineinv_epi64_epi8() { + fn test_mm512_gf2p8affineinv_epi64_epi8() { let identity: i64 = 0x01_02_04_08_10_20_40_80; const IDENTITY_BYTE: i32 = 0; const CONSTANT_BYTE: i32 = 0x63; @@ -1288,8 +1288,8 @@ mod tests { let (inputs, results) = generate_inv_tests_data(); for i in 0..NUM_BYTES_WORDS_512 { - let input = load_m512i_word(&inputs, i); - let reference = load_m512i_word(&results, i); + let input = unsafe { load_m512i_word(&inputs, i) }; + let reference = unsafe { load_m512i_word(&results, i) }; let result = _mm512_gf2p8affineinv_epi64_epi8::(input, identity); let remultiplied = _mm512_gf2p8mul_epi8(result, input); assert_eq_m512i(remultiplied, reference); @@ -1300,8 +1300,8 @@ mod tests { generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_512 { - let vector = load_m512i_word(&vectors, i); - let matrix = load_m512i_word(&matrices, i); + let vector = unsafe { load_m512i_word(&vectors, i) }; + let matrix = unsafe { load_m512i_word(&matrices, i) }; let inv_vec = _mm512_gf2p8affineinv_epi64_epi8::(vector, identity); let reference = _mm512_gf2p8affine_epi64_epi8::(inv_vec, matrix); @@ -1314,21 +1314,21 @@ mod tests { let sbox_matrix = _mm512_set1_epi64(AES_S_BOX_MATRIX); for i in 0..NUM_BYTES_WORDS_512 { - let reference = load_m512i_word(&AES_S_BOX, i); - let input = load_m512i_word(&inputs, i); + let reference = unsafe { load_m512i_word(&AES_S_BOX, i) }; + let input = unsafe { load_m512i_word(&inputs, i) }; let result = _mm512_gf2p8affineinv_epi64_epi8::(input, sbox_matrix); assert_eq_m512i(result, reference); } } #[simd_test(enable = "gfni,avx512bw")] - unsafe fn test_mm512_maskz_gf2p8affineinv_epi64_epi8() { + fn test_mm512_maskz_gf2p8affineinv_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_512 { - let matrix = load_m512i_word(&matrices, i); - let vector = load_m512i_word(&vectors, i); + let matrix = unsafe { load_m512i_word(&matrices, i) }; + let vector = unsafe { load_m512i_word(&vectors, i) }; let result_zero = _mm512_maskz_gf2p8affineinv_epi64_epi8::(0, vector, matrix); assert_eq_m512i(result_zero, _mm512_setzero_si512()); @@ -1344,13 +1344,13 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw")] - unsafe fn test_mm512_mask_gf2p8affineinv_epi64_epi8() { + fn test_mm512_mask_gf2p8affineinv_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_512 { - let left = load_m512i_word(&vectors, i); - let right = load_m512i_word(&matrices, i); + let left = unsafe { load_m512i_word(&vectors, i) }; + let right = unsafe { load_m512i_word(&matrices, i) }; let result_left = _mm512_mask_gf2p8affineinv_epi64_epi8::(left, 0, left, right); assert_eq_m512i(result_left, left); @@ -1366,7 +1366,7 @@ mod tests { } #[simd_test(enable = "gfni,avx")] - unsafe fn test_mm256_gf2p8affineinv_epi64_epi8() { + fn test_mm256_gf2p8affineinv_epi64_epi8() { let identity: i64 = 0x01_02_04_08_10_20_40_80; const IDENTITY_BYTE: i32 = 0; const CONSTANT_BYTE: i32 = 0x63; @@ -1376,8 +1376,8 @@ mod tests { let (inputs, results) = generate_inv_tests_data(); for i in 0..NUM_BYTES_WORDS_256 { - let input = load_m256i_word(&inputs, i); - let reference = load_m256i_word(&results, i); + let input = unsafe { load_m256i_word(&inputs, i) }; + let reference = unsafe { load_m256i_word(&results, i) }; let result = _mm256_gf2p8affineinv_epi64_epi8::(input, identity); let remultiplied = _mm256_gf2p8mul_epi8(result, input); assert_eq_m256i(remultiplied, reference); @@ -1388,8 +1388,8 @@ mod tests { generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_256 { - let vector = load_m256i_word(&vectors, i); - let matrix = load_m256i_word(&matrices, i); + let vector = unsafe { load_m256i_word(&vectors, i) }; + let matrix = unsafe { load_m256i_word(&matrices, i) }; let inv_vec = _mm256_gf2p8affineinv_epi64_epi8::(vector, identity); let reference = _mm256_gf2p8affine_epi64_epi8::(inv_vec, matrix); @@ -1402,21 +1402,21 @@ mod tests { let sbox_matrix = _mm256_set1_epi64x(AES_S_BOX_MATRIX); for i in 0..NUM_BYTES_WORDS_256 { - let reference = load_m256i_word(&AES_S_BOX, i); - let input = load_m256i_word(&inputs, i); + let reference = unsafe { load_m256i_word(&AES_S_BOX, i) }; + let input = unsafe { load_m256i_word(&inputs, i) }; let result = _mm256_gf2p8affineinv_epi64_epi8::(input, sbox_matrix); assert_eq_m256i(result, reference); } } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm256_maskz_gf2p8affineinv_epi64_epi8() { + fn test_mm256_maskz_gf2p8affineinv_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_256 { - let matrix = load_m256i_word(&matrices, i); - let vector = load_m256i_word(&vectors, i); + let matrix = unsafe { load_m256i_word(&matrices, i) }; + let vector = unsafe { load_m256i_word(&vectors, i) }; let result_zero = _mm256_maskz_gf2p8affineinv_epi64_epi8::(0, vector, matrix); assert_eq_m256i(result_zero, _mm256_setzero_si256()); @@ -1432,13 +1432,13 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm256_mask_gf2p8affineinv_epi64_epi8() { + fn test_mm256_mask_gf2p8affineinv_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_256 { - let left = load_m256i_word(&vectors, i); - let right = load_m256i_word(&matrices, i); + let left = unsafe { load_m256i_word(&vectors, i) }; + let right = unsafe { load_m256i_word(&matrices, i) }; let result_left = _mm256_mask_gf2p8affineinv_epi64_epi8::(left, 0, left, right); assert_eq_m256i(result_left, left); @@ -1454,7 +1454,7 @@ mod tests { } #[simd_test(enable = "gfni")] - unsafe fn test_mm_gf2p8affineinv_epi64_epi8() { + fn test_mm_gf2p8affineinv_epi64_epi8() { let identity: i64 = 0x01_02_04_08_10_20_40_80; const IDENTITY_BYTE: i32 = 0; const CONSTANT_BYTE: i32 = 0x63; @@ -1464,8 +1464,8 @@ mod tests { let (inputs, results) = generate_inv_tests_data(); for i in 0..NUM_BYTES_WORDS_128 { - let input = load_m128i_word(&inputs, i); - let reference = load_m128i_word(&results, i); + let input = unsafe { load_m128i_word(&inputs, i) }; + let reference = unsafe { load_m128i_word(&results, i) }; let result = _mm_gf2p8affineinv_epi64_epi8::(input, identity); let remultiplied = _mm_gf2p8mul_epi8(result, input); assert_eq_m128i(remultiplied, reference); @@ -1476,8 +1476,8 @@ mod tests { generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_128 { - let vector = load_m128i_word(&vectors, i); - let matrix = load_m128i_word(&matrices, i); + let vector = unsafe { load_m128i_word(&vectors, i) }; + let matrix = unsafe { load_m128i_word(&matrices, i) }; let inv_vec = _mm_gf2p8affineinv_epi64_epi8::(vector, identity); let reference = _mm_gf2p8affine_epi64_epi8::(inv_vec, matrix); @@ -1490,21 +1490,21 @@ mod tests { let sbox_matrix = _mm_set1_epi64x(AES_S_BOX_MATRIX); for i in 0..NUM_BYTES_WORDS_128 { - let reference = load_m128i_word(&AES_S_BOX, i); - let input = load_m128i_word(&inputs, i); + let reference = unsafe { load_m128i_word(&AES_S_BOX, i) }; + let input = unsafe { load_m128i_word(&inputs, i) }; let result = _mm_gf2p8affineinv_epi64_epi8::(input, sbox_matrix); assert_eq_m128i(result, reference); } } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm_maskz_gf2p8affineinv_epi64_epi8() { + fn test_mm_maskz_gf2p8affineinv_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_128 { - let matrix = load_m128i_word(&matrices, i); - let vector = load_m128i_word(&vectors, i); + let matrix = unsafe { load_m128i_word(&matrices, i) }; + let vector = unsafe { load_m128i_word(&vectors, i) }; let result_zero = _mm_maskz_gf2p8affineinv_epi64_epi8::(0, vector, matrix); assert_eq_m128i(result_zero, _mm_setzero_si128()); @@ -1520,13 +1520,13 @@ mod tests { } #[simd_test(enable = "gfni,avx512bw,avx512vl")] - unsafe fn test_mm_mask_gf2p8affineinv_epi64_epi8() { + fn test_mm_mask_gf2p8affineinv_epi64_epi8() { const CONSTANT_BYTE: i32 = 0x63; let (matrices, vectors, _expected) = generate_affine_mul_test_data(CONSTANT_BYTE as u8); for i in 0..NUM_TEST_WORDS_128 { - let left = load_m128i_word(&vectors, i); - let right = load_m128i_word(&matrices, i); + let left = unsafe { load_m128i_word(&vectors, i) }; + let right = unsafe { load_m128i_word(&matrices, i) }; let result_left = _mm_mask_gf2p8affineinv_epi64_epi8::(left, 0, left, right); assert_eq_m128i(result_left, left); diff --git a/library/stdarch/crates/core_arch/src/x86/kl.rs b/library/stdarch/crates/core_arch/src/x86/kl.rs index 26e5a46c6293..7cb52847f50d 100644 --- a/library/stdarch/crates/core_arch/src/x86/kl.rs +++ b/library/stdarch/crates/core_arch/src/x86/kl.rs @@ -352,45 +352,47 @@ mod tests { use stdarch_test::simd_test; #[target_feature(enable = "kl")] - unsafe fn encodekey128() -> [u8; 48] { + fn encodekey128() -> [u8; 48] { let mut handle = [0; 48]; - let _ = _mm_encodekey128_u32(0, _mm_setzero_si128(), handle.as_mut_ptr()); + let _ = unsafe { _mm_encodekey128_u32(0, _mm_setzero_si128(), handle.as_mut_ptr()) }; handle } #[target_feature(enable = "kl")] - unsafe fn encodekey256() -> [u8; 64] { + fn encodekey256() -> [u8; 64] { let mut handle = [0; 64]; - let _ = _mm_encodekey256_u32( - 0, - _mm_setzero_si128(), - _mm_setzero_si128(), - handle.as_mut_ptr(), - ); + let _ = unsafe { + _mm_encodekey256_u32( + 0, + _mm_setzero_si128(), + _mm_setzero_si128(), + handle.as_mut_ptr(), + ) + }; handle } #[simd_test(enable = "kl")] - unsafe fn test_mm_encodekey128_u32() { + fn test_mm_encodekey128_u32() { encodekey128(); } #[simd_test(enable = "kl")] - unsafe fn test_mm_encodekey256_u32() { + fn test_mm_encodekey256_u32() { encodekey256(); } #[simd_test(enable = "kl")] - unsafe fn test_mm_aesenc128kl_u8() { + fn test_mm_aesenc128kl_u8() { let mut buffer = _mm_setzero_si128(); let key = encodekey128(); for _ in 0..100 { - let status = _mm_aesenc128kl_u8(&mut buffer, buffer, key.as_ptr()); + let status = unsafe { _mm_aesenc128kl_u8(&mut buffer, buffer, key.as_ptr()) }; assert_eq!(status, 0); } for _ in 0..100 { - let status = _mm_aesdec128kl_u8(&mut buffer, buffer, key.as_ptr()); + let status = unsafe { _mm_aesdec128kl_u8(&mut buffer, buffer, key.as_ptr()) }; assert_eq!(status, 0); } @@ -398,16 +400,16 @@ mod tests { } #[simd_test(enable = "kl")] - unsafe fn test_mm_aesdec128kl_u8() { + fn test_mm_aesdec128kl_u8() { let mut buffer = _mm_setzero_si128(); let key = encodekey128(); for _ in 0..100 { - let status = _mm_aesdec128kl_u8(&mut buffer, buffer, key.as_ptr()); + let status = unsafe { _mm_aesdec128kl_u8(&mut buffer, buffer, key.as_ptr()) }; assert_eq!(status, 0); } for _ in 0..100 { - let status = _mm_aesenc128kl_u8(&mut buffer, buffer, key.as_ptr()); + let status = unsafe { _mm_aesenc128kl_u8(&mut buffer, buffer, key.as_ptr()) }; assert_eq!(status, 0); } @@ -415,16 +417,16 @@ mod tests { } #[simd_test(enable = "kl")] - unsafe fn test_mm_aesenc256kl_u8() { + fn test_mm_aesenc256kl_u8() { let mut buffer = _mm_setzero_si128(); let key = encodekey256(); for _ in 0..100 { - let status = _mm_aesenc256kl_u8(&mut buffer, buffer, key.as_ptr()); + let status = unsafe { _mm_aesenc256kl_u8(&mut buffer, buffer, key.as_ptr()) }; assert_eq!(status, 0); } for _ in 0..100 { - let status = _mm_aesdec256kl_u8(&mut buffer, buffer, key.as_ptr()); + let status = unsafe { _mm_aesdec256kl_u8(&mut buffer, buffer, key.as_ptr()) }; assert_eq!(status, 0); } @@ -432,16 +434,16 @@ mod tests { } #[simd_test(enable = "kl")] - unsafe fn test_mm_aesdec256kl_u8() { + fn test_mm_aesdec256kl_u8() { let mut buffer = _mm_setzero_si128(); let key = encodekey256(); for _ in 0..100 { - let status = _mm_aesdec256kl_u8(&mut buffer, buffer, key.as_ptr()); + let status = unsafe { _mm_aesdec256kl_u8(&mut buffer, buffer, key.as_ptr()) }; assert_eq!(status, 0); } for _ in 0..100 { - let status = _mm_aesenc256kl_u8(&mut buffer, buffer, key.as_ptr()); + let status = unsafe { _mm_aesenc256kl_u8(&mut buffer, buffer, key.as_ptr()) }; assert_eq!(status, 0); } @@ -449,16 +451,20 @@ mod tests { } #[simd_test(enable = "widekl")] - unsafe fn test_mm_aesencwide128kl_u8() { + fn test_mm_aesencwide128kl_u8() { let mut buffer = [_mm_setzero_si128(); 8]; let key = encodekey128(); for _ in 0..100 { - let status = _mm_aesencwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()); + let status = unsafe { + _mm_aesencwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()) + }; assert_eq!(status, 0); } for _ in 0..100 { - let status = _mm_aesdecwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()); + let status = unsafe { + _mm_aesdecwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()) + }; assert_eq!(status, 0); } @@ -468,16 +474,20 @@ mod tests { } #[simd_test(enable = "widekl")] - unsafe fn test_mm_aesdecwide128kl_u8() { + fn test_mm_aesdecwide128kl_u8() { let mut buffer = [_mm_setzero_si128(); 8]; let key = encodekey128(); for _ in 0..100 { - let status = _mm_aesdecwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()); + let status = unsafe { + _mm_aesdecwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()) + }; assert_eq!(status, 0); } for _ in 0..100 { - let status = _mm_aesencwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()); + let status = unsafe { + _mm_aesencwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()) + }; assert_eq!(status, 0); } @@ -487,16 +497,20 @@ mod tests { } #[simd_test(enable = "widekl")] - unsafe fn test_mm_aesencwide256kl_u8() { + fn test_mm_aesencwide256kl_u8() { let mut buffer = [_mm_setzero_si128(); 8]; let key = encodekey256(); for _ in 0..100 { - let status = _mm_aesencwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()); + let status = unsafe { + _mm_aesencwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()) + }; assert_eq!(status, 0); } for _ in 0..100 { - let status = _mm_aesdecwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()); + let status = unsafe { + _mm_aesdecwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()) + }; assert_eq!(status, 0); } @@ -506,16 +520,20 @@ mod tests { } #[simd_test(enable = "widekl")] - unsafe fn test_mm_aesdecwide256kl_u8() { + fn test_mm_aesdecwide256kl_u8() { let mut buffer = [_mm_setzero_si128(); 8]; let key = encodekey256(); for _ in 0..100 { - let status = _mm_aesdecwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()); + let status = unsafe { + _mm_aesdecwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()) + }; assert_eq!(status, 0); } for _ in 0..100 { - let status = _mm_aesencwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()); + let status = unsafe { + _mm_aesencwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr()) + }; assert_eq!(status, 0); } diff --git a/library/stdarch/crates/core_arch/src/x86/rtm.rs b/library/stdarch/crates/core_arch/src/x86/rtm.rs index b37e7571eb8f..c88bd6592d78 100644 --- a/library/stdarch/crates/core_arch/src/x86/rtm.rs +++ b/library/stdarch/crates/core_arch/src/x86/rtm.rs @@ -120,13 +120,15 @@ mod tests { use crate::core_arch::x86::*; #[simd_test(enable = "rtm")] - unsafe fn test_xbegin() { + fn test_xbegin() { let mut x = 0; for _ in 0..10 { - let code = _xbegin(); + let code = unsafe { _xbegin() }; if code == _XBEGIN_STARTED { x += 1; - _xend(); + unsafe { + _xend(); + } assert_eq!(x, 1); break; } @@ -135,19 +137,23 @@ mod tests { } #[simd_test(enable = "rtm")] - unsafe fn test_xabort() { + fn test_xabort() { const ABORT_CODE: u32 = 42; // aborting outside a transactional region does nothing - _xabort::(); + unsafe { + _xabort::(); + } for _ in 0..10 { let mut x = 0; - let code = rtm::_xbegin(); + let code = unsafe { _xbegin() }; if code == _XBEGIN_STARTED { x += 1; - rtm::_xabort::(); + unsafe { + _xabort::(); + } } else if code & _XABORT_EXPLICIT != 0 { - let test_abort_code = rtm::_xabort_code(code); + let test_abort_code = _xabort_code(code); assert_eq!(test_abort_code, ABORT_CODE); } assert_eq!(x, 0); @@ -155,14 +161,16 @@ mod tests { } #[simd_test(enable = "rtm")] - unsafe fn test_xtest() { - assert_eq!(_xtest(), 0); + fn test_xtest() { + assert_eq!(unsafe { _xtest() }, 0); for _ in 0..10 { - let code = rtm::_xbegin(); + let code = unsafe { _xbegin() }; if code == _XBEGIN_STARTED { - let in_tx = _xtest(); - rtm::_xend(); + let in_tx = unsafe { _xtest() }; + unsafe { + _xend(); + } // putting the assert inside the transaction would abort the transaction on fail // without any output/panic/etc diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index f167e8381d27..1812721db4d3 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -3147,21 +3147,21 @@ mod tests { } #[simd_test(enable = "sse")] - const unsafe fn test_mm_load_ss() { + const fn test_mm_load_ss() { let a = 42.0f32; - let r = _mm_load_ss(ptr::addr_of!(a)); + let r = unsafe { _mm_load_ss(ptr::addr_of!(a)) }; assert_eq_m128(r, _mm_setr_ps(42.0, 0.0, 0.0, 0.0)); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_load1_ps() { + const fn test_mm_load1_ps() { let a = 42.0f32; - let r = _mm_load1_ps(ptr::addr_of!(a)); + let r = unsafe { _mm_load1_ps(ptr::addr_of!(a)) }; assert_eq_m128(r, _mm_setr_ps(42.0, 42.0, 42.0, 42.0)); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_load_ps() { + const fn test_mm_load_ps() { let vals = Memory { data: [1.0f32, 2.0, 3.0, 4.0], }; @@ -3169,21 +3169,21 @@ mod tests { // guaranteed to be aligned to 16 bytes let p = vals.data.as_ptr(); - let r = _mm_load_ps(p); + let r = unsafe { _mm_load_ps(p) }; let e = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); assert_eq_m128(r, e); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_loadu_ps() { + const fn test_mm_loadu_ps() { let vals = &[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; - let p = vals.as_ptr().add(3); - let r = _mm_loadu_ps(black_box(p)); + let p = unsafe { vals.as_ptr().add(3) }; + let r = unsafe { _mm_loadu_ps(black_box(p)) }; assert_eq_m128(r, _mm_setr_ps(4.0, 5.0, 6.0, 7.0)); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_loadr_ps() { + const fn test_mm_loadr_ps() { let vals = Memory { data: [1.0f32, 2.0, 3.0, 4.0], }; @@ -3191,16 +3191,18 @@ mod tests { // guaranteed to be aligned to 16 bytes let p = vals.data.as_ptr(); - let r = _mm_loadr_ps(p); + let r = unsafe { _mm_loadr_ps(p) }; let e = _mm_setr_ps(4.0, 3.0, 2.0, 1.0); assert_eq_m128(r, e); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_store_ss() { + const fn test_mm_store_ss() { let mut vals = [0.0f32; 8]; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); - _mm_store_ss(vals.as_mut_ptr().add(1), a); + unsafe { + _mm_store_ss(vals.as_mut_ptr().add(1), a); + } assert_eq!(vals[0], 0.0); assert_eq!(vals[1], 1.0); @@ -3208,46 +3210,52 @@ mod tests { } #[simd_test(enable = "sse")] - const unsafe fn test_mm_store1_ps() { + const fn test_mm_store1_ps() { let mut vals = Memory { data: [0.0f32; 4] }; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); // guaranteed to be aligned to 16 bytes let p = vals.data.as_mut_ptr(); - _mm_store1_ps(p, *black_box(&a)); + unsafe { + _mm_store1_ps(p, *black_box(&a)); + } assert_eq!(vals.data, [1.0, 1.0, 1.0, 1.0]); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_store_ps() { + const fn test_mm_store_ps() { let mut vals = Memory { data: [0.0f32; 4] }; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); // guaranteed to be aligned to 16 bytes let p = vals.data.as_mut_ptr(); - _mm_store_ps(p, *black_box(&a)); + unsafe { + _mm_store_ps(p, *black_box(&a)); + } assert_eq!(vals.data, [1.0, 2.0, 3.0, 4.0]); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_storer_ps() { + const fn test_mm_storer_ps() { let mut vals = Memory { data: [0.0f32; 4] }; let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); // guaranteed to be aligned to 16 bytes let p = vals.data.as_mut_ptr(); - _mm_storer_ps(p, *black_box(&a)); + unsafe { + _mm_storer_ps(p, *black_box(&a)); + } assert_eq!(vals.data, [4.0, 3.0, 2.0, 1.0]); } #[simd_test(enable = "sse")] - const unsafe fn test_mm_storeu_ps() { + const fn test_mm_storeu_ps() { #[repr(align(16))] struct Memory8 { data: [f32; 8], @@ -3258,9 +3266,11 @@ mod tests { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); // guaranteed to be *not* aligned to 16 bytes - let p = vals.data.as_mut_ptr().offset(1); + let p = unsafe { vals.data.as_mut_ptr().offset(1) }; - _mm_storeu_ps(p, *black_box(&a)); + unsafe { + _mm_storeu_ps(p, *black_box(&a)); + } assert_eq!(vals.data, [0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0]); } @@ -3315,11 +3325,13 @@ mod tests { // Miri cannot support this until it is clear how it fits in the Rust memory model // (non-temporal store) #[cfg_attr(miri, ignore)] - unsafe fn test_mm_stream_ps() { + fn test_mm_stream_ps() { let a = _mm_set1_ps(7.0); let mut mem = Memory { data: [-1.0; 4] }; - _mm_stream_ps(ptr::addr_of_mut!(mem.data[0]), a); + unsafe { + _mm_stream_ps(ptr::addr_of_mut!(mem.data[0]), a); + } _mm_sfence(); for i in 0..4 { assert_eq!(mem.data[i], get_m128(a, i)); diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index fc010e8467bb..c58e1b86a470 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -3291,9 +3291,11 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_clflush() { + fn test_mm_clflush() { let x = 0_u8; - _mm_clflush(ptr::addr_of!(x)); + unsafe { + _mm_clflush(ptr::addr_of!(x)); + } } #[simd_test(enable = "sse2")] @@ -3725,7 +3727,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_sll_epi16() { + fn test_mm_sll_epi16() { let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF); let r = _mm_sll_epi16(a, _mm_set_epi64x(0, 4)); assert_eq_m128i( @@ -4071,7 +4073,7 @@ mod tests { } #[simd_test(enable = "sse2")] - unsafe fn test_mm_cvtps_epi32() { + fn test_mm_cvtps_epi32() { let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0); let r = _mm_cvtps_epi32(a); assert_eq_m128i(r, _mm_setr_epi32(1, 2, 3, 4)); @@ -4178,23 +4180,23 @@ mod tests { } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_loadl_epi64() { + const fn test_mm_loadl_epi64() { let a = _mm_setr_epi64x(6, 5); - let r = _mm_loadl_epi64(ptr::addr_of!(a)); + let r = unsafe { _mm_loadl_epi64(ptr::addr_of!(a)) }; assert_eq_m128i(r, _mm_setr_epi64x(6, 0)); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_load_si128() { + const fn test_mm_load_si128() { let a = _mm_set_epi64x(5, 6); - let r = _mm_load_si128(ptr::addr_of!(a) as *const _); + let r = unsafe { _mm_load_si128(ptr::addr_of!(a) as *const _) }; assert_eq_m128i(a, r); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_loadu_si128() { + const fn test_mm_loadu_si128() { let a = _mm_set_epi64x(5, 6); - let r = _mm_loadu_si128(ptr::addr_of!(a) as *const _); + let r = unsafe { _mm_loadu_si128(ptr::addr_of!(a) as *const _) }; assert_eq_m128i(a, r); } @@ -4202,7 +4204,7 @@ mod tests { // Miri cannot support this until it is clear how it fits in the Rust memory model // (non-temporal store) #[cfg_attr(miri, ignore)] - unsafe fn test_mm_maskmoveu_si128() { + fn test_mm_maskmoveu_si128() { let a = _mm_set1_epi8(9); #[rustfmt::skip] let mask = _mm_set_epi8( @@ -4210,33 +4212,41 @@ mod tests { 0, 0, 0, 0, 0, 0, 0, 0, ); let mut r = _mm_set1_epi8(0); - _mm_maskmoveu_si128(a, mask, ptr::addr_of_mut!(r) as *mut i8); + unsafe { + _mm_maskmoveu_si128(a, mask, ptr::addr_of_mut!(r) as *mut i8); + } _mm_sfence(); let e = _mm_set_epi8(0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); assert_eq_m128i(r, e); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_store_si128() { + const fn test_mm_store_si128() { let a = _mm_set1_epi8(9); let mut r = _mm_set1_epi8(0); - _mm_store_si128(&mut r, a); + unsafe { + _mm_store_si128(&mut r, a); + } assert_eq_m128i(r, a); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_storeu_si128() { + const fn test_mm_storeu_si128() { let a = _mm_set1_epi8(9); let mut r = _mm_set1_epi8(0); - _mm_storeu_si128(&mut r, a); + unsafe { + _mm_storeu_si128(&mut r, a); + } assert_eq_m128i(r, a); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_storel_epi64() { + const fn test_mm_storel_epi64() { let a = _mm_setr_epi64x(2, 9); let mut r = _mm_set1_epi8(0); - _mm_storel_epi64(&mut r, a); + unsafe { + _mm_storel_epi64(&mut r, a); + } assert_eq_m128i(r, _mm_setr_epi64x(2, 0)); } @@ -4244,10 +4254,12 @@ mod tests { // Miri cannot support this until it is clear how it fits in the Rust memory model // (non-temporal store) #[cfg_attr(miri, ignore)] - unsafe fn test_mm_stream_si128() { + fn test_mm_stream_si128() { let a = _mm_setr_epi32(1, 2, 3, 4); let mut r = _mm_undefined_si128(); - _mm_stream_si128(ptr::addr_of_mut!(r), a); + unsafe { + _mm_stream_si128(ptr::addr_of_mut!(r), a); + } _mm_sfence(); assert_eq_m128i(r, a); } @@ -4256,10 +4268,12 @@ mod tests { // Miri cannot support this until it is clear how it fits in the Rust memory model // (non-temporal store) #[cfg_attr(miri, ignore)] - unsafe fn test_mm_stream_si32() { + fn test_mm_stream_si32() { let a: i32 = 7; let mut mem = boxed::Box::::new(-1); - _mm_stream_si32(ptr::addr_of_mut!(*mem), a); + unsafe { + _mm_stream_si32(ptr::addr_of_mut!(*mem), a); + } _mm_sfence(); assert_eq!(a, *mem); } @@ -4909,40 +4923,40 @@ mod tests { } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_load_pd() { + const fn test_mm_load_pd() { let mem = Memory { data: [1.0f64, 2.0, 3.0, 4.0], }; let vals = &mem.data; let d = vals.as_ptr(); - let r = _mm_load_pd(d); + let r = unsafe { _mm_load_pd(d) }; assert_eq_m128d(r, _mm_setr_pd(1.0, 2.0)); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_load_sd() { + const fn test_mm_load_sd() { let a = 1.; let expected = _mm_setr_pd(a, 0.); - let r = _mm_load_sd(&a); + let r = unsafe { _mm_load_sd(&a) }; assert_eq_m128d(r, expected); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_loadh_pd() { + const fn test_mm_loadh_pd() { let a = _mm_setr_pd(1., 2.); let b = 3.; let expected = _mm_setr_pd(_mm_cvtsd_f64(a), 3.); - let r = _mm_loadh_pd(a, &b); + let r = unsafe { _mm_loadh_pd(a, &b) }; assert_eq_m128d(r, expected); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_loadl_pd() { + const fn test_mm_loadl_pd() { let a = _mm_setr_pd(1., 2.); let b = 3.; let expected = _mm_setr_pd(3., get_m128d(a, 1)); - let r = _mm_loadl_pd(a, &b); + let r = unsafe { _mm_loadl_pd(a, &b) }; assert_eq_m128d(r, expected); } @@ -4950,7 +4964,7 @@ mod tests { // Miri cannot support this until it is clear how it fits in the Rust memory model // (non-temporal store) #[cfg_attr(miri, ignore)] - unsafe fn test_mm_stream_pd() { + fn test_mm_stream_pd() { #[repr(align(128))] struct Memory { pub data: [f64; 2], @@ -4958,7 +4972,9 @@ mod tests { let a = _mm_set1_pd(7.0); let mut mem = Memory { data: [-1.0; 2] }; - _mm_stream_pd(ptr::addr_of_mut!(mem.data[0]), a); + unsafe { + _mm_stream_pd(ptr::addr_of_mut!(mem.data[0]), a); + } _mm_sfence(); for i in 0..2 { assert_eq!(mem.data[i], get_m128d(a, i)); @@ -4966,132 +4982,154 @@ mod tests { } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_store_sd() { + const fn test_mm_store_sd() { let mut dest = 0.; let a = _mm_setr_pd(1., 2.); - _mm_store_sd(&mut dest, a); + unsafe { + _mm_store_sd(&mut dest, a); + } assert_eq!(dest, _mm_cvtsd_f64(a)); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_store_pd() { + const fn test_mm_store_pd() { let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); let d = vals.as_mut_ptr(); - _mm_store_pd(d, *black_box(&a)); + unsafe { + _mm_store_pd(d, *black_box(&a)); + } assert_eq!(vals[0], 1.0); assert_eq!(vals[1], 2.0); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_storeu_pd() { + const fn test_mm_storeu_pd() { // guaranteed to be aligned to 16 bytes let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); // so p is *not* aligned to 16 bytes - let p = vals.as_mut_ptr().offset(1); - _mm_storeu_pd(p, *black_box(&a)); + unsafe { + let p = vals.as_mut_ptr().offset(1); + _mm_storeu_pd(p, *black_box(&a)); + } assert_eq!(*vals, [0.0, 1.0, 2.0, 0.0]); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_storeu_si16() { + const fn test_mm_storeu_si16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); let mut r = _mm_setr_epi16(9, 10, 11, 12, 13, 14, 15, 16); - _mm_storeu_si16(ptr::addr_of_mut!(r).cast(), a); + unsafe { + _mm_storeu_si16(ptr::addr_of_mut!(r).cast(), a); + } let e = _mm_setr_epi16(1, 10, 11, 12, 13, 14, 15, 16); assert_eq_m128i(r, e); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_storeu_si32() { + const fn test_mm_storeu_si32() { let a = _mm_setr_epi32(1, 2, 3, 4); let mut r = _mm_setr_epi32(5, 6, 7, 8); - _mm_storeu_si32(ptr::addr_of_mut!(r).cast(), a); + unsafe { + _mm_storeu_si32(ptr::addr_of_mut!(r).cast(), a); + } let e = _mm_setr_epi32(1, 6, 7, 8); assert_eq_m128i(r, e); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_storeu_si64() { + const fn test_mm_storeu_si64() { let a = _mm_setr_epi64x(1, 2); let mut r = _mm_setr_epi64x(3, 4); - _mm_storeu_si64(ptr::addr_of_mut!(r).cast(), a); + unsafe { + _mm_storeu_si64(ptr::addr_of_mut!(r).cast(), a); + } let e = _mm_setr_epi64x(1, 4); assert_eq_m128i(r, e); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_store1_pd() { + const fn test_mm_store1_pd() { let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); let d = vals.as_mut_ptr(); - _mm_store1_pd(d, *black_box(&a)); + unsafe { + _mm_store1_pd(d, *black_box(&a)); + } assert_eq!(vals[0], 1.0); assert_eq!(vals[1], 1.0); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_store_pd1() { + const fn test_mm_store_pd1() { let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); let d = vals.as_mut_ptr(); - _mm_store_pd1(d, *black_box(&a)); + unsafe { + _mm_store_pd1(d, *black_box(&a)); + } assert_eq!(vals[0], 1.0); assert_eq!(vals[1], 1.0); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_storer_pd() { + const fn test_mm_storer_pd() { let mut mem = Memory { data: [0.0f64; 4] }; let vals = &mut mem.data; let a = _mm_setr_pd(1.0, 2.0); let d = vals.as_mut_ptr(); - _mm_storer_pd(d, *black_box(&a)); + unsafe { + _mm_storer_pd(d, *black_box(&a)); + } assert_eq!(vals[0], 2.0); assert_eq!(vals[1], 1.0); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_storeh_pd() { + const fn test_mm_storeh_pd() { let mut dest = 0.; let a = _mm_setr_pd(1., 2.); - _mm_storeh_pd(&mut dest, a); + unsafe { + _mm_storeh_pd(&mut dest, a); + } assert_eq!(dest, get_m128d(a, 1)); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_storel_pd() { + const fn test_mm_storel_pd() { let mut dest = 0.; let a = _mm_setr_pd(1., 2.); - _mm_storel_pd(&mut dest, a); + unsafe { + _mm_storel_pd(&mut dest, a); + } assert_eq!(dest, _mm_cvtsd_f64(a)); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_loadr_pd() { + const fn test_mm_loadr_pd() { let mut mem = Memory { data: [1.0f64, 2.0, 3.0, 4.0], }; let vals = &mut mem.data; let d = vals.as_ptr(); - let r = _mm_loadr_pd(d); + let r = unsafe { _mm_loadr_pd(d) }; assert_eq_m128d(r, _mm_setr_pd(2.0, 1.0)); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_loadu_pd() { + const fn test_mm_loadu_pd() { // guaranteed to be aligned to 16 bytes let mut mem = Memory { data: [1.0f64, 2.0, 3.0, 4.0], @@ -5099,31 +5137,31 @@ mod tests { let vals = &mut mem.data; // so this will *not* be aligned to 16 bytes - let d = vals.as_ptr().offset(1); + let d = unsafe { vals.as_ptr().offset(1) }; - let r = _mm_loadu_pd(d); + let r = unsafe { _mm_loadu_pd(d) }; let e = _mm_setr_pd(2.0, 3.0); assert_eq_m128d(r, e); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_loadu_si16() { + const fn test_mm_loadu_si16() { let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); - let r = _mm_loadu_si16(ptr::addr_of!(a) as *const _); + let r = unsafe { _mm_loadu_si16(ptr::addr_of!(a) as *const _) }; assert_eq_m128i(r, _mm_setr_epi16(1, 0, 0, 0, 0, 0, 0, 0)); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_loadu_si32() { + const fn test_mm_loadu_si32() { let a = _mm_setr_epi32(1, 2, 3, 4); - let r = _mm_loadu_si32(ptr::addr_of!(a) as *const _); + let r = unsafe { _mm_loadu_si32(ptr::addr_of!(a) as *const _) }; assert_eq_m128i(r, _mm_setr_epi32(1, 0, 0, 0)); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_loadu_si64() { + const fn test_mm_loadu_si64() { let a = _mm_setr_epi64x(5, 6); - let r = _mm_loadu_si64(ptr::addr_of!(a) as *const _); + let r = unsafe { _mm_loadu_si64(ptr::addr_of!(a) as *const _) }; assert_eq_m128i(r, _mm_setr_epi64x(5, 0)); } @@ -5302,16 +5340,16 @@ mod tests { } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_load1_pd() { + const fn test_mm_load1_pd() { let d = -5.0; - let r = _mm_load1_pd(&d); + let r = unsafe { _mm_load1_pd(&d) }; assert_eq_m128d(r, _mm_setr_pd(d, d)); } #[simd_test(enable = "sse2")] - const unsafe fn test_mm_load_pd1() { + const fn test_mm_load_pd1() { let d = -5.0; - let r = _mm_load_pd1(&d); + let r = unsafe { _mm_load_pd1(&d) }; assert_eq_m128d(r, _mm_setr_pd(d, d)); } diff --git a/library/stdarch/crates/core_arch/src/x86/sse3.rs b/library/stdarch/crates/core_arch/src/x86/sse3.rs index 68817856f44a..e4c75702544d 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse3.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse3.rs @@ -239,7 +239,7 @@ mod tests { } #[simd_test(enable = "sse3")] - unsafe fn test_mm_lddqu_si128() { + fn test_mm_lddqu_si128() { #[rustfmt::skip] let a = _mm_setr_epi8( 1, 2, 3, 4, @@ -247,7 +247,7 @@ mod tests { 9, 10, 11, 12, 13, 14, 15, 16, ); - let r = _mm_lddqu_si128(&a); + let r = unsafe { _mm_lddqu_si128(&a) }; assert_eq_m128i(a, r); } @@ -273,9 +273,9 @@ mod tests { } #[simd_test(enable = "sse3")] - const unsafe fn test_mm_loaddup_pd() { + const fn test_mm_loaddup_pd() { let d = -5.0; - let r = _mm_loaddup_pd(&d); + let r = unsafe { _mm_loaddup_pd(&d) }; assert_eq_m128d(r, _mm_setr_pd(d, d)); } } diff --git a/library/stdarch/crates/core_arch/src/x86/sse41.rs b/library/stdarch/crates/core_arch/src/x86/sse41.rs index a499bf898b80..7ad4306f36f2 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse41.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse41.rs @@ -1219,20 +1219,20 @@ mod tests { } #[simd_test(enable = "sse4.1")] - const unsafe fn test_mm_blendv_pd() { + const fn test_mm_blendv_pd() { let a = _mm_set1_pd(0.0); let b = _mm_set1_pd(1.0); - let mask = transmute(_mm_setr_epi64x(0, -1)); + let mask = _mm_castsi128_pd(_mm_setr_epi64x(0, -1)); let r = _mm_blendv_pd(a, b, mask); let e = _mm_setr_pd(0.0, 1.0); assert_eq_m128d(r, e); } #[simd_test(enable = "sse4.1")] - const unsafe fn test_mm_blendv_ps() { + const fn test_mm_blendv_ps() { let a = _mm_set1_ps(0.0); let b = _mm_set1_ps(1.0); - let mask = transmute(_mm_setr_epi32(0, -1, 0, -1)); + let mask = _mm_castsi128_ps(_mm_setr_epi32(0, -1, 0, -1)); let r = _mm_blendv_ps(a, b, mask); let e = _mm_setr_ps(0.0, 1.0, 0.0, 1.0); assert_eq_m128(r, e); @@ -1949,9 +1949,9 @@ mod tests { } #[simd_test(enable = "sse4.1")] - unsafe fn test_mm_stream_load_si128() { + fn test_mm_stream_load_si128() { let a = _mm_set_epi64x(5, 6); - let r = _mm_stream_load_si128(core::ptr::addr_of!(a) as *const _); + let r = unsafe { _mm_stream_load_si128(core::ptr::addr_of!(a) as *const _) }; assert_eq_m128i(a, r); } } diff --git a/library/stdarch/crates/core_arch/src/x86/sse42.rs b/library/stdarch/crates/core_arch/src/x86/sse42.rs index 65d1fe4d6233..55e22592637f 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse42.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse42.rs @@ -613,6 +613,7 @@ mod tests { use crate::core_arch::assert_eq_const as assert_eq; use stdarch_test::simd_test; + use crate::core_arch::simd::*; use crate::core_arch::x86::*; use std::ptr; @@ -625,7 +626,7 @@ mod tests { assert!(s.len() <= 16); let mut array = [0u8; 16]; array[..s.len()].copy_from_slice(s); - unsafe { transmute(array) } + u8x16::from_array(array).as_m128i() } #[simd_test(enable = "sse4.2")] diff --git a/library/stdarch/crates/core_arch/src/x86/sse4a.rs b/library/stdarch/crates/core_arch/src/x86/sse4a.rs index 020baeff152d..f36b879a030e 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse4a.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse4a.rs @@ -206,7 +206,7 @@ mod tests { // Miri cannot support this until it is clear how it fits in the Rust memory model // (non-temporal store) #[cfg_attr(miri, ignore)] - unsafe fn test_mm_stream_sd() { + fn test_mm_stream_sd() { let mut mem = MemoryF64 { data: [1.0_f64, 2.0], }; @@ -216,7 +216,9 @@ mod tests { let x = _mm_setr_pd(3.0, 4.0); - _mm_stream_sd(d, x); + unsafe { + _mm_stream_sd(d, x); + } _mm_sfence(); } assert_eq!(mem.data[0], 3.0); @@ -232,7 +234,7 @@ mod tests { // Miri cannot support this until it is clear how it fits in the Rust memory model // (non-temporal store) #[cfg_attr(miri, ignore)] - unsafe fn test_mm_stream_ss() { + fn test_mm_stream_ss() { let mut mem = MemoryF32 { data: [1.0_f32, 2.0, 3.0, 4.0], }; @@ -242,7 +244,9 @@ mod tests { let x = _mm_setr_ps(5.0, 6.0, 7.0, 8.0); - _mm_stream_ss(d, x); + unsafe { + _mm_stream_ss(d, x); + } _mm_sfence(); } assert_eq!(mem.data[0], 5.0); diff --git a/library/stdarch/crates/core_arch/src/x86/xsave.rs b/library/stdarch/crates/core_arch/src/x86/xsave.rs index 653eb28c4268..e22d3580ff46 100644 --- a/library/stdarch/crates/core_arch/src/x86/xsave.rs +++ b/library/stdarch/crates/core_arch/src/x86/xsave.rs @@ -197,47 +197,53 @@ mod tests { #[simd_test(enable = "xsave")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri - unsafe fn test_xsave() { + fn test_xsave() { let m = 0xFFFFFFFFFFFFFFFF_u64; //< all registers let mut a = XsaveArea::new(); let mut b = XsaveArea::new(); - _xsave(a.ptr(), m); - _xrstor(a.ptr(), m); - _xsave(b.ptr(), m); + unsafe { + _xsave(a.ptr(), m); + _xrstor(a.ptr(), m); + _xsave(b.ptr(), m); + } } #[simd_test(enable = "xsave")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri - unsafe fn test_xgetbv() { + fn test_xgetbv() { let xcr_n: u32 = _XCR_XFEATURE_ENABLED_MASK; - let xcr: u64 = _xgetbv(xcr_n); - let xcr_cpy: u64 = _xgetbv(xcr_n); + let xcr: u64 = unsafe { _xgetbv(xcr_n) }; + let xcr_cpy: u64 = unsafe { _xgetbv(xcr_n) }; assert_eq!(xcr, xcr_cpy); } #[simd_test(enable = "xsave,xsaveopt")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri - unsafe fn test_xsaveopt() { + fn test_xsaveopt() { let m = 0xFFFFFFFFFFFFFFFF_u64; //< all registers let mut a = XsaveArea::new(); let mut b = XsaveArea::new(); - _xsaveopt(a.ptr(), m); - _xrstor(a.ptr(), m); - _xsaveopt(b.ptr(), m); + unsafe { + _xsaveopt(a.ptr(), m); + _xrstor(a.ptr(), m); + _xsaveopt(b.ptr(), m); + } } #[simd_test(enable = "xsave,xsavec")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri - unsafe fn test_xsavec() { + fn test_xsavec() { let m = 0xFFFFFFFFFFFFFFFF_u64; //< all registers let mut a = XsaveArea::new(); let mut b = XsaveArea::new(); - _xsavec(a.ptr(), m); - _xrstor(a.ptr(), m); - _xsavec(b.ptr(), m); + unsafe { + _xsavec(a.ptr(), m); + _xrstor(a.ptr(), m); + _xsavec(b.ptr(), m); + } } } diff --git a/library/stdarch/crates/core_arch/src/x86_64/amx.rs b/library/stdarch/crates/core_arch/src/x86_64/amx.rs index f372f7066d51..4e20e014cf20 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/amx.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/amx.rs @@ -581,267 +581,297 @@ mod tests { } #[simd_test(enable = "amx-tile")] - unsafe fn test_tile_loadconfig() { - let config = __tilecfg::default(); - _tile_loadconfig(config.as_ptr()); - _tile_release(); + fn test_tile_loadconfig() { + unsafe { + let config = __tilecfg::default(); + _tile_loadconfig(config.as_ptr()); + _tile_release(); + } } #[simd_test(enable = "amx-tile")] - unsafe fn test_tile_storeconfig() { - let config = __tilecfg::new(1, 0, [32; 8], [8; 8]); - _tile_loadconfig(config.as_ptr()); - let mut _config = __tilecfg::default(); - _tile_storeconfig(_config.as_mut_ptr()); - _tile_release(); - assert_eq!(config, _config); + fn test_tile_storeconfig() { + unsafe { + let config = __tilecfg::new(1, 0, [32; 8], [8; 8]); + _tile_loadconfig(config.as_ptr()); + let mut _config = __tilecfg::default(); + _tile_storeconfig(_config.as_mut_ptr()); + _tile_release(); + assert_eq!(config, _config); + } } #[simd_test(enable = "amx-tile")] - unsafe fn test_tile_zero() { - _init_amx(); - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - let mut out = [[1_i8; 64]; 16]; - _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); - _tile_release(); - assert_eq!(out, [[0; 64]; 16]); + fn test_tile_zero() { + unsafe { + _init_amx(); + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + let mut out = [[1_i8; 64]; 16]; + _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); + _tile_release(); + assert_eq!(out, [[0; 64]; 16]); + } } #[simd_test(enable = "amx-tile")] - unsafe fn test_tile_stored() { - _init_amx(); - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - let mut out = [[1_i8; 64]; 16]; - _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); - _tile_release(); - assert_eq!(out, [[0; 64]; 16]); + fn test_tile_stored() { + unsafe { + _init_amx(); + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + let mut out = [[1_i8; 64]; 16]; + _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); + _tile_release(); + assert_eq!(out, [[0; 64]; 16]); + } } #[simd_test(enable = "amx-tile")] - unsafe fn test_tile_loadd() { - _init_amx(); - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - let mat = [1_i8; 1024]; - _tile_loadd::<0>(&mat as *const i8 as *const u8, 64); - let mut out = [[0_i8; 64]; 16]; - _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); - _tile_release(); - assert_eq!(out, [[1; 64]; 16]); + fn test_tile_loadd() { + unsafe { + _init_amx(); + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + let mat = [1_i8; 1024]; + _tile_loadd::<0>(&mat as *const i8 as *const u8, 64); + let mut out = [[0_i8; 64]; 16]; + _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); + _tile_release(); + assert_eq!(out, [[1; 64]; 16]); + } } #[simd_test(enable = "amx-tile")] - unsafe fn test_tile_stream_loadd() { - _init_amx(); - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - let mat = [1_i8; 1024]; - _tile_stream_loadd::<0>(&mat as *const i8 as *const u8, 64); - let mut out = [[0_i8; 64]; 16]; - _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); - _tile_release(); - assert_eq!(out, [[1; 64]; 16]); + fn test_tile_stream_loadd() { + unsafe { + _init_amx(); + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + let mat = [1_i8; 1024]; + _tile_stream_loadd::<0>(&mat as *const i8 as *const u8, 64); + let mut out = [[0_i8; 64]; 16]; + _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); + _tile_release(); + assert_eq!(out, [[1; 64]; 16]); + } } #[simd_test(enable = "amx-tile")] - unsafe fn test_tile_release() { - _tile_release(); + fn test_tile_release() { + unsafe { + _tile_release(); + } } #[simd_test(enable = "amx-bf16,avx512f")] - unsafe fn test_tile_dpbf16ps() { - _init_amx(); - let bf16_1: u16 = _mm_cvtness_sbh(1.0).to_bits(); - let bf16_2: u16 = _mm_cvtness_sbh(2.0).to_bits(); - let ones: [u8; 1024] = transmute([bf16_1; 512]); - let twos: [u8; 1024] = transmute([bf16_2; 512]); - let mut res = [[0f32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const u8, 64); - _tile_loadd::<2>(&twos as *const u8, 64); - _tile_dpbf16ps::<0, 1, 2>(); - _tile_stored::<0>(&mut res as *mut [f32; 16] as *mut u8, 64); - _tile_release(); - assert_eq!(res, [[64f32; 16]; 16]); + fn test_tile_dpbf16ps() { + unsafe { + _init_amx(); + let bf16_1: u16 = _mm_cvtness_sbh(1.0).to_bits(); + let bf16_2: u16 = _mm_cvtness_sbh(2.0).to_bits(); + let ones: [u8; 1024] = transmute([bf16_1; 512]); + let twos: [u8; 1024] = transmute([bf16_2; 512]); + let mut res = [[0f32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const u8, 64); + _tile_loadd::<2>(&twos as *const u8, 64); + _tile_dpbf16ps::<0, 1, 2>(); + _tile_stored::<0>(&mut res as *mut [f32; 16] as *mut u8, 64); + _tile_release(); + assert_eq!(res, [[64f32; 16]; 16]); + } } #[simd_test(enable = "amx-int8")] - unsafe fn test_tile_dpbssd() { - _init_amx(); - let ones = [-1_i8; 1024]; - let twos = [-2_i8; 1024]; - let mut res = [[0_i32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const i8 as *const u8, 64); - _tile_loadd::<2>(&twos as *const i8 as *const u8, 64); - _tile_dpbssd::<0, 1, 2>(); - _tile_stored::<0>(&mut res as *mut [i32; 16] as *mut u8, 64); - _tile_release(); - assert_eq!(res, [[128_i32; 16]; 16]); + fn test_tile_dpbssd() { + unsafe { + _init_amx(); + let ones = [-1_i8; 1024]; + let twos = [-2_i8; 1024]; + let mut res = [[0_i32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const i8 as *const u8, 64); + _tile_loadd::<2>(&twos as *const i8 as *const u8, 64); + _tile_dpbssd::<0, 1, 2>(); + _tile_stored::<0>(&mut res as *mut [i32; 16] as *mut u8, 64); + _tile_release(); + assert_eq!(res, [[128_i32; 16]; 16]); + } } #[simd_test(enable = "amx-int8")] - unsafe fn test_tile_dpbsud() { - _init_amx(); - let ones = [-1_i8; 1024]; - let twos = [2_u8; 1024]; - let mut res = [[0_i32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const i8 as *const u8, 64); - _tile_loadd::<2>(&twos as *const u8, 64); - _tile_dpbsud::<0, 1, 2>(); - _tile_stored::<0>(&mut res as *mut [i32; 16] as *mut u8, 64); - _tile_release(); - assert_eq!(res, [[-128_i32; 16]; 16]); + fn test_tile_dpbsud() { + unsafe { + _init_amx(); + let ones = [-1_i8; 1024]; + let twos = [2_u8; 1024]; + let mut res = [[0_i32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const i8 as *const u8, 64); + _tile_loadd::<2>(&twos as *const u8, 64); + _tile_dpbsud::<0, 1, 2>(); + _tile_stored::<0>(&mut res as *mut [i32; 16] as *mut u8, 64); + _tile_release(); + assert_eq!(res, [[-128_i32; 16]; 16]); + } } #[simd_test(enable = "amx-int8")] - unsafe fn test_tile_dpbusd() { - _init_amx(); - let ones = [1_u8; 1024]; - let twos = [-2_i8; 1024]; - let mut res = [[0_i32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const u8, 64); - _tile_loadd::<2>(&twos as *const i8 as *const u8, 64); - _tile_dpbusd::<0, 1, 2>(); - _tile_stored::<0>(&mut res as *mut [i32; 16] as *mut u8, 64); - _tile_release(); - assert_eq!(res, [[-128_i32; 16]; 16]); + fn test_tile_dpbusd() { + unsafe { + _init_amx(); + let ones = [1_u8; 1024]; + let twos = [-2_i8; 1024]; + let mut res = [[0_i32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const u8, 64); + _tile_loadd::<2>(&twos as *const i8 as *const u8, 64); + _tile_dpbusd::<0, 1, 2>(); + _tile_stored::<0>(&mut res as *mut [i32; 16] as *mut u8, 64); + _tile_release(); + assert_eq!(res, [[-128_i32; 16]; 16]); + } } #[simd_test(enable = "amx-int8")] - unsafe fn test_tile_dpbuud() { - _init_amx(); - let ones = [1_u8; 1024]; - let twos = [2_u8; 1024]; - let mut res = [[0_i32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const u8, 64); - _tile_loadd::<2>(&twos as *const u8, 64); - _tile_dpbuud::<0, 1, 2>(); - _tile_stored::<0>(&mut res as *mut [i32; 16] as *mut u8, 64); - _tile_release(); - assert_eq!(res, [[128_i32; 16]; 16]); + fn test_tile_dpbuud() { + unsafe { + _init_amx(); + let ones = [1_u8; 1024]; + let twos = [2_u8; 1024]; + let mut res = [[0_i32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const u8, 64); + _tile_loadd::<2>(&twos as *const u8, 64); + _tile_dpbuud::<0, 1, 2>(); + _tile_stored::<0>(&mut res as *mut [i32; 16] as *mut u8, 64); + _tile_release(); + assert_eq!(res, [[128_i32; 16]; 16]); + } } #[simd_test(enable = "amx-fp16")] - unsafe fn test_tile_dpfp16ps() { - _init_amx(); - let ones = [1f16; 512]; - let twos = [2f16; 512]; - let mut res = [[0f32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const f16 as *const u8, 64); - _tile_loadd::<2>(&twos as *const f16 as *const u8, 64); - _tile_dpfp16ps::<0, 1, 2>(); - _tile_stored::<0>(&mut res as *mut [f32; 16] as *mut u8, 64); - _tile_release(); - assert_eq!(res, [[64f32; 16]; 16]); + fn test_tile_dpfp16ps() { + unsafe { + _init_amx(); + let ones = [1f16; 512]; + let twos = [2f16; 512]; + let mut res = [[0f32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const f16 as *const u8, 64); + _tile_loadd::<2>(&twos as *const f16 as *const u8, 64); + _tile_dpfp16ps::<0, 1, 2>(); + _tile_stored::<0>(&mut res as *mut [f32; 16] as *mut u8, 64); + _tile_release(); + assert_eq!(res, [[64f32; 16]; 16]); + } } #[simd_test(enable = "amx-complex")] - unsafe fn test_tile_cmmimfp16ps() { - _init_amx(); - let ones = [1f16; 512]; - let twos = [2f16; 512]; - let mut res = [[0f32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const f16 as *const u8, 64); - _tile_loadd::<2>(&twos as *const f16 as *const u8, 64); - _tile_cmmimfp16ps::<0, 1, 2>(); - _tile_stored::<0>(&mut res as *mut [f32; 16] as *mut u8, 64); - _tile_release(); - assert_eq!(res, [[64f32; 16]; 16]); + fn test_tile_cmmimfp16ps() { + unsafe { + _init_amx(); + let ones = [1f16; 512]; + let twos = [2f16; 512]; + let mut res = [[0f32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const f16 as *const u8, 64); + _tile_loadd::<2>(&twos as *const f16 as *const u8, 64); + _tile_cmmimfp16ps::<0, 1, 2>(); + _tile_stored::<0>(&mut res as *mut [f32; 16] as *mut u8, 64); + _tile_release(); + assert_eq!(res, [[64f32; 16]; 16]); + } } #[simd_test(enable = "amx-complex")] - unsafe fn test_tile_cmmrlfp16ps() { - _init_amx(); - let ones = [1f16; 512]; - let twos = [2f16; 512]; - let mut res = [[0f32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const f16 as *const u8, 64); - _tile_loadd::<2>(&twos as *const f16 as *const u8, 64); - _tile_cmmrlfp16ps::<0, 1, 2>(); - _tile_stored::<0>(&mut res as *mut [f32; 16] as *mut u8, 64); - _tile_release(); - assert_eq!(res, [[0f32; 16]; 16]); + fn test_tile_cmmrlfp16ps() { + unsafe { + _init_amx(); + let ones = [1f16; 512]; + let twos = [2f16; 512]; + let mut res = [[0f32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const f16 as *const u8, 64); + _tile_loadd::<2>(&twos as *const f16 as *const u8, 64); + _tile_cmmrlfp16ps::<0, 1, 2>(); + _tile_stored::<0>(&mut res as *mut [f32; 16] as *mut u8, 64); + _tile_release(); + assert_eq!(res, [[0f32; 16]; 16]); + } } const BF8_ONE: u8 = 0x3c; @@ -850,223 +880,245 @@ mod tests { const HF8_TWO: u8 = 0x40; #[simd_test(enable = "amx-fp8")] - unsafe fn test_tile_dpbf8ps() { - _init_amx(); - let ones = [BF8_ONE; 1024]; - let twos = [BF8_TWO; 1024]; - let mut res = [[0.0_f32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const u8, 64); - _tile_loadd::<2>(&twos as *const u8, 64); - _tile_dpbf8ps::<0, 1, 2>(); - _tile_stored::<0>(res.as_mut_ptr().cast(), 64); - _tile_release(); - assert_eq!(res, [[128.0_f32; 16]; 16]); + fn test_tile_dpbf8ps() { + unsafe { + _init_amx(); + let ones = [BF8_ONE; 1024]; + let twos = [BF8_TWO; 1024]; + let mut res = [[0.0_f32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const u8, 64); + _tile_loadd::<2>(&twos as *const u8, 64); + _tile_dpbf8ps::<0, 1, 2>(); + _tile_stored::<0>(res.as_mut_ptr().cast(), 64); + _tile_release(); + assert_eq!(res, [[128.0_f32; 16]; 16]); + } } #[simd_test(enable = "amx-fp8")] - unsafe fn test_tile_dpbhf8ps() { - _init_amx(); - let ones = [BF8_ONE; 1024]; - let twos = [HF8_TWO; 1024]; - let mut res = [[0.0_f32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const u8, 64); - _tile_loadd::<2>(&twos as *const u8, 64); - _tile_dpbhf8ps::<0, 1, 2>(); - _tile_stored::<0>(res.as_mut_ptr().cast(), 64); - _tile_release(); - assert_eq!(res, [[128.0_f32; 16]; 16]); + fn test_tile_dpbhf8ps() { + unsafe { + _init_amx(); + let ones = [BF8_ONE; 1024]; + let twos = [HF8_TWO; 1024]; + let mut res = [[0.0_f32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const u8, 64); + _tile_loadd::<2>(&twos as *const u8, 64); + _tile_dpbhf8ps::<0, 1, 2>(); + _tile_stored::<0>(res.as_mut_ptr().cast(), 64); + _tile_release(); + assert_eq!(res, [[128.0_f32; 16]; 16]); + } } #[simd_test(enable = "amx-fp8")] - unsafe fn test_tile_dphbf8ps() { - _init_amx(); - let ones = [HF8_ONE; 1024]; - let twos = [BF8_TWO; 1024]; - let mut res = [[0.0_f32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const u8, 64); - _tile_loadd::<2>(&twos as *const u8, 64); - _tile_dphbf8ps::<0, 1, 2>(); - _tile_stored::<0>(res.as_mut_ptr().cast(), 64); - _tile_release(); - assert_eq!(res, [[128.0_f32; 16]; 16]); + fn test_tile_dphbf8ps() { + unsafe { + _init_amx(); + let ones = [HF8_ONE; 1024]; + let twos = [BF8_TWO; 1024]; + let mut res = [[0.0_f32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const u8, 64); + _tile_loadd::<2>(&twos as *const u8, 64); + _tile_dphbf8ps::<0, 1, 2>(); + _tile_stored::<0>(res.as_mut_ptr().cast(), 64); + _tile_release(); + assert_eq!(res, [[128.0_f32; 16]; 16]); + } } #[simd_test(enable = "amx-fp8")] - unsafe fn test_tile_dphf8ps() { - _init_amx(); - let ones = [HF8_ONE; 1024]; - let twos = [HF8_TWO; 1024]; - let mut res = [[0.0_f32; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(&ones as *const u8, 64); - _tile_loadd::<2>(&twos as *const u8, 64); - _tile_dphf8ps::<0, 1, 2>(); - _tile_stored::<0>(res.as_mut_ptr().cast(), 64); - _tile_release(); - assert_eq!(res, [[128.0_f32; 16]; 16]); + fn test_tile_dphf8ps() { + unsafe { + _init_amx(); + let ones = [HF8_ONE; 1024]; + let twos = [HF8_TWO; 1024]; + let mut res = [[0.0_f32; 16]; 16]; + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(&ones as *const u8, 64); + _tile_loadd::<2>(&twos as *const u8, 64); + _tile_dphf8ps::<0, 1, 2>(); + _tile_stored::<0>(res.as_mut_ptr().cast(), 64); + _tile_release(); + assert_eq!(res, [[128.0_f32; 16]; 16]); + } } #[simd_test(enable = "amx-movrs")] - unsafe fn test_tile_loaddrs() { - _init_amx(); - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - let mat = [1_i8; 1024]; - _tile_loaddrs::<0>(&mat as *const i8 as *const u8, 64); - let mut out = [[0_i8; 64]; 16]; - _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); - _tile_release(); - assert_eq!(out, [[1; 64]; 16]); + fn test_tile_loaddrs() { + unsafe { + _init_amx(); + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + let mat = [1_i8; 1024]; + _tile_loaddrs::<0>(&mat as *const i8 as *const u8, 64); + let mut out = [[0_i8; 64]; 16]; + _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); + _tile_release(); + assert_eq!(out, [[1; 64]; 16]); + } } #[simd_test(enable = "amx-movrs")] - unsafe fn test_tile_stream_loaddrs() { - _init_amx(); - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - let mat = [1_i8; 1024]; - _tile_stream_loaddrs::<0>(&mat as *const i8 as *const u8, 64); - let mut out = [[0_i8; 64]; 16]; - _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); - _tile_release(); - assert_eq!(out, [[1; 64]; 16]); - } - - #[simd_test(enable = "amx-avx512,avx10.2")] - unsafe fn test_tile_movrow() { - _init_amx(); - let array: [[u8; 64]; 16] = array::from_fn(|i| [i as _; _]); - - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_loadd::<0>(array.as_ptr().cast(), 64); - for i in 0..16 { - let row = _tile_movrow::<0>(i); - assert_eq!(*row.as_u8x64().as_array(), [i as _; _]); + fn test_tile_stream_loaddrs() { + unsafe { + _init_amx(); + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + let mat = [1_i8; 1024]; + _tile_stream_loaddrs::<0>(&mat as *const i8 as *const u8, 64); + let mut out = [[0_i8; 64]; 16]; + _tile_stored::<0>(&mut out as *mut [i8; 64] as *mut u8, 64); + _tile_release(); + assert_eq!(out, [[1; 64]; 16]); } } #[simd_test(enable = "amx-avx512,avx10.2")] - unsafe fn test_tile_cvtrowd2ps() { - _init_amx(); - let array: [[u32; 16]; 16] = array::from_fn(|i| [i as _; _]); + fn test_tile_movrow() { + unsafe { + _init_amx(); + let array: [[u8; 64]; 16] = array::from_fn(|i| [i as _; _]); - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_loadd::<0>(array.as_ptr().cast(), 64); - for i in 0..16 { - let row = _tile_cvtrowd2ps::<0>(i); - assert_eq!(*row.as_f32x16().as_array(), [i as _; _]); + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_loadd::<0>(array.as_ptr().cast(), 64); + for i in 0..16 { + let row = _tile_movrow::<0>(i); + assert_eq!(*row.as_u8x64().as_array(), [i as _; _]); + } } } #[simd_test(enable = "amx-avx512,avx10.2")] - unsafe fn test_tile_cvtrowps2phh() { - _init_amx(); - let array: [[f32; 16]; 16] = array::from_fn(|i| [i as _; _]); + fn test_tile_cvtrowd2ps() { + unsafe { + _init_amx(); + let array: [[u32; 16]; 16] = array::from_fn(|i| [i as _; _]); - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_loadd::<0>(array.as_ptr().cast(), 64); - for i in 0..16 { - let row = _tile_cvtrowps2phh::<0>(i); - assert_eq!( - *row.as_f16x32().as_array(), - array::from_fn(|j| if j & 1 == 0 { 0.0 } else { i as _ }) - ); + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_loadd::<0>(array.as_ptr().cast(), 64); + for i in 0..16 { + let row = _tile_cvtrowd2ps::<0>(i); + assert_eq!(*row.as_f32x16().as_array(), [i as _; _]); + } } } #[simd_test(enable = "amx-avx512,avx10.2")] - unsafe fn test_tile_cvtrowps2phl() { - _init_amx(); - let array: [[f32; 16]; 16] = array::from_fn(|i| [i as _; _]); + fn test_tile_cvtrowps2phh() { + unsafe { + _init_amx(); + let array: [[f32; 16]; 16] = array::from_fn(|i| [i as _; _]); - let mut config = __tilecfg::default(); - config.palette = 1; - config.colsb[0] = 64; - config.rows[0] = 16; - _tile_loadconfig(config.as_ptr()); - _tile_loadd::<0>(array.as_ptr().cast(), 64); - for i in 0..16 { - let row = _tile_cvtrowps2phl::<0>(i); - assert_eq!( - *row.as_f16x32().as_array(), - array::from_fn(|j| if j & 1 == 0 { i as _ } else { 0.0 }) - ); + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_loadd::<0>(array.as_ptr().cast(), 64); + for i in 0..16 { + let row = _tile_cvtrowps2phh::<0>(i); + assert_eq!( + *row.as_f16x32().as_array(), + array::from_fn(|j| if j & 1 == 0 { 0.0 } else { i as _ }) + ); + } + } + } + + #[simd_test(enable = "amx-avx512,avx10.2")] + fn test_tile_cvtrowps2phl() { + unsafe { + _init_amx(); + let array: [[f32; 16]; 16] = array::from_fn(|i| [i as _; _]); + + let mut config = __tilecfg::default(); + config.palette = 1; + config.colsb[0] = 64; + config.rows[0] = 16; + _tile_loadconfig(config.as_ptr()); + _tile_loadd::<0>(array.as_ptr().cast(), 64); + for i in 0..16 { + let row = _tile_cvtrowps2phl::<0>(i); + assert_eq!( + *row.as_f16x32().as_array(), + array::from_fn(|j| if j & 1 == 0 { i as _ } else { 0.0 }) + ); + } } } #[simd_test(enable = "amx-tf32")] - unsafe fn test_tile_mmultf32ps() { - _init_amx(); - let a: [[f32; 16]; 16] = array::from_fn(|i| [i as _; _]); - let b: [[f32; 16]; 16] = [array::from_fn(|j| j as _); _]; - let mut res = [[0.0; 16]; 16]; + fn test_tile_mmultf32ps() { + unsafe { + _init_amx(); + let a: [[f32; 16]; 16] = array::from_fn(|i| [i as _; _]); + let b: [[f32; 16]; 16] = [array::from_fn(|j| j as _); _]; + let mut res = [[0.0; 16]; 16]; - let mut config = __tilecfg::default(); - config.palette = 1; - (0..=2).for_each(|i| { - config.colsb[i] = 64; - config.rows[i] = 16; - }); - _tile_loadconfig(config.as_ptr()); - _tile_zero::<0>(); - _tile_loadd::<1>(a.as_ptr().cast(), 64); - _tile_loadd::<2>(b.as_ptr().cast(), 64); - _tile_mmultf32ps::<0, 1, 2>(); - _tile_stored::<0>(res.as_mut_ptr().cast(), 64); - _tile_release(); + let mut config = __tilecfg::default(); + config.palette = 1; + (0..=2).for_each(|i| { + config.colsb[i] = 64; + config.rows[i] = 16; + }); + _tile_loadconfig(config.as_ptr()); + _tile_zero::<0>(); + _tile_loadd::<1>(a.as_ptr().cast(), 64); + _tile_loadd::<2>(b.as_ptr().cast(), 64); + _tile_mmultf32ps::<0, 1, 2>(); + _tile_stored::<0>(res.as_mut_ptr().cast(), 64); + _tile_release(); - let expected = array::from_fn(|i| array::from_fn(|j| 16.0 * i as f32 * j as f32)); - assert_eq!(res, expected); + let expected = array::from_fn(|i| array::from_fn(|j| 16.0 * i as f32 * j as f32)); + assert_eq!(res, expected); + } } } diff --git a/library/stdarch/crates/core_arch/src/x86_64/avx512f.rs b/library/stdarch/crates/core_arch/src/x86_64/avx512f.rs index 368fb0c238e4..0fd9b09363d4 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/avx512f.rs @@ -7446,81 +7446,81 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32gather_pd() { + fn test_mm512_i32gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing let index = _mm256_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112); - let r = _mm512_i32gather_pd::<8>(index, arr.as_ptr()); + let r = unsafe { _mm512_i32gather_pd::<8>(index, arr.as_ptr()) }; assert_eq_m512d(r, _mm512_setr_pd(0., 16., 32., 48., 64., 80., 96., 112.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32gather_pd() { + fn test_mm512_mask_i32gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); let src = _mm512_set1_pd(2.); let mask = 0b10101010; let index = _mm256_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112); // A multiplier of 8 is word-addressing - let r = _mm512_mask_i32gather_pd::<8>(src, mask, index, arr.as_ptr()); + let r = unsafe { _mm512_mask_i32gather_pd::<8>(src, mask, index, arr.as_ptr()) }; assert_eq_m512d(r, _mm512_setr_pd(2., 16., 2., 48., 2., 80., 2., 112.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i64gather_pd() { + fn test_mm512_i64gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); // A multiplier of 8 is word-addressing let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); - let r = _mm512_i64gather_pd::<8>(index, arr.as_ptr()); + let r = unsafe { _mm512_i64gather_pd::<8>(index, arr.as_ptr()) }; assert_eq_m512d(r, _mm512_setr_pd(0., 16., 32., 48., 64., 80., 96., 112.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i64gather_pd() { + fn test_mm512_mask_i64gather_pd() { let arr: [f64; 128] = core::array::from_fn(|i| i as f64); let src = _mm512_set1_pd(2.); let mask = 0b10101010; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); // A multiplier of 8 is word-addressing - let r = _mm512_mask_i64gather_pd::<8>(src, mask, index, arr.as_ptr()); + let r = unsafe { _mm512_mask_i64gather_pd::<8>(src, mask, index, arr.as_ptr()) }; assert_eq_m512d(r, _mm512_setr_pd(2., 16., 2., 48., 2., 80., 2., 112.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i64gather_ps() { + fn test_mm512_i64gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); // A multiplier of 4 is word-addressing #[rustfmt::skip] let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); - let r = _mm512_i64gather_ps::<4>(index, arr.as_ptr()); + let r = unsafe { _mm512_i64gather_ps::<4>(index, arr.as_ptr()) }; assert_eq_m256(r, _mm256_setr_ps(0., 16., 32., 48., 64., 80., 96., 112.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i64gather_ps() { + fn test_mm512_mask_i64gather_ps() { let arr: [f32; 128] = core::array::from_fn(|i| i as f32); let src = _mm256_set1_ps(2.); let mask = 0b10101010; #[rustfmt::skip] let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); // A multiplier of 4 is word-addressing - let r = _mm512_mask_i64gather_ps::<4>(src, mask, index, arr.as_ptr()); + let r = unsafe { _mm512_mask_i64gather_ps::<4>(src, mask, index, arr.as_ptr()) }; assert_eq_m256(r, _mm256_setr_ps(2., 16., 2., 48., 2., 80., 2., 112.)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32gather_epi64() { + fn test_mm512_i32gather_epi64() { let mut arr = [0i64; 128]; for i in 0..128i64 { arr[i as usize] = i; } // A multiplier of 8 is word-addressing let index = _mm256_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112); - let r = _mm512_i32gather_epi64::<8>(index, arr.as_ptr()); + let r = unsafe { _mm512_i32gather_epi64::<8>(index, arr.as_ptr()) }; assert_eq_m512i(r, _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32gather_epi64() { + fn test_mm512_mask_i32gather_epi64() { let mut arr = [0i64; 128]; for i in 0..128i64 { arr[i as usize] = i; @@ -7529,24 +7529,24 @@ mod tests { let mask = 0b10101010; let index = _mm256_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112); // A multiplier of 8 is word-addressing - let r = _mm512_mask_i32gather_epi64::<8>(src, mask, index, arr.as_ptr()); + let r = unsafe { _mm512_mask_i32gather_epi64::<8>(src, mask, index, arr.as_ptr()) }; assert_eq_m512i(r, _mm512_setr_epi64(2, 16, 2, 48, 2, 80, 2, 112)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i64gather_epi64() { + fn test_mm512_i64gather_epi64() { let mut arr = [0i64; 128]; for i in 0..128i64 { arr[i as usize] = i; } // A multiplier of 8 is word-addressing let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); - let r = _mm512_i64gather_epi64::<8>(index, arr.as_ptr()); + let r = unsafe { _mm512_i64gather_epi64::<8>(index, arr.as_ptr()) }; assert_eq_m512i(r, _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i64gather_epi64() { + fn test_mm512_mask_i64gather_epi64() { let mut arr = [0i64; 128]; for i in 0..128i64 { arr[i as usize] = i; @@ -7555,24 +7555,24 @@ mod tests { let mask = 0b10101010; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); // A multiplier of 8 is word-addressing - let r = _mm512_mask_i64gather_epi64::<8>(src, mask, index, arr.as_ptr()); + let r = unsafe { _mm512_mask_i64gather_epi64::<8>(src, mask, index, arr.as_ptr()) }; assert_eq_m512i(r, _mm512_setr_epi64(2, 16, 2, 48, 2, 80, 2, 112)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i64gather_epi32() { + fn test_mm512_i64gather_epi32() { let mut arr = [0i64; 128]; for i in 0..128i64 { arr[i as usize] = i; } // A multiplier of 8 is word-addressing let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); - let r = _mm512_i64gather_epi32::<8>(index, arr.as_ptr() as *const i32); + let r = unsafe { _mm512_i64gather_epi32::<8>(index, arr.as_ptr() as *const i32) }; assert_eq_m256i(r, _mm256_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i64gather_epi32() { + fn test_mm512_mask_i64gather_epi32() { let mut arr = [0i64; 128]; for i in 0..128i64 { arr[i as usize] = i; @@ -7581,17 +7581,21 @@ mod tests { let mask = 0b10101010; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); // A multiplier of 8 is word-addressing - let r = _mm512_mask_i64gather_epi32::<8>(src, mask, index, arr.as_ptr() as *const i32); + let r = unsafe { + _mm512_mask_i64gather_epi32::<8>(src, mask, index, arr.as_ptr() as *const i32) + }; assert_eq_m256i(r, _mm256_setr_epi32(2, 16, 2, 48, 2, 80, 2, 112)); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32scatter_pd() { + fn test_mm512_i32scatter_pd() { let mut arr = [0f64; 128]; let index = _mm256_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); // A multiplier of 8 is word-addressing - _mm512_i32scatter_pd::<8>(arr.as_mut_ptr(), index, src); + unsafe { + _mm512_i32scatter_pd::<8>(arr.as_mut_ptr(), index, src); + } let mut expected = [0f64; 128]; for i in 0..8 { expected[i * 16] = (i + 1) as f64; @@ -7600,13 +7604,15 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32scatter_pd() { + fn test_mm512_mask_i32scatter_pd() { let mut arr = [0f64; 128]; let mask = 0b10101010; let index = _mm256_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); // A multiplier of 8 is word-addressing - _mm512_mask_i32scatter_pd::<8>(arr.as_mut_ptr(), mask, index, src); + unsafe { + _mm512_mask_i32scatter_pd::<8>(arr.as_mut_ptr(), mask, index, src); + } let mut expected = [0f64; 128]; for i in 0..4 { expected[i * 32 + 16] = 2. * (i + 1) as f64; @@ -7615,12 +7621,14 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i64scatter_pd() { + fn test_mm512_i64scatter_pd() { let mut arr = [0f64; 128]; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); // A multiplier of 8 is word-addressing - _mm512_i64scatter_pd::<8>(arr.as_mut_ptr(), index, src); + unsafe { + _mm512_i64scatter_pd::<8>(arr.as_mut_ptr(), index, src); + } let mut expected = [0f64; 128]; for i in 0..8 { expected[i * 16] = (i + 1) as f64; @@ -7629,13 +7637,15 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i64scatter_pd() { + fn test_mm512_mask_i64scatter_pd() { let mut arr = [0f64; 128]; let mask = 0b10101010; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm512_setr_pd(1., 2., 3., 4., 5., 6., 7., 8.); // A multiplier of 8 is word-addressing - _mm512_mask_i64scatter_pd::<8>(arr.as_mut_ptr(), mask, index, src); + unsafe { + _mm512_mask_i64scatter_pd::<8>(arr.as_mut_ptr(), mask, index, src); + } let mut expected = [0f64; 128]; for i in 0..4 { expected[i * 32 + 16] = 2. * (i + 1) as f64; @@ -7644,12 +7654,14 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i64scatter_ps() { + fn test_mm512_i64scatter_ps() { let mut arr = [0f32; 128]; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); // A multiplier of 4 is word-addressing - _mm512_i64scatter_ps::<4>(arr.as_mut_ptr(), index, src); + unsafe { + _mm512_i64scatter_ps::<4>(arr.as_mut_ptr(), index, src); + } let mut expected = [0f32; 128]; for i in 0..8 { expected[i * 16] = (i + 1) as f32; @@ -7658,13 +7670,15 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i64scatter_ps() { + fn test_mm512_mask_i64scatter_ps() { let mut arr = [0f32; 128]; let mask = 0b10101010; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm256_setr_ps(1., 2., 3., 4., 5., 6., 7., 8.); // A multiplier of 4 is word-addressing - _mm512_mask_i64scatter_ps::<4>(arr.as_mut_ptr(), mask, index, src); + unsafe { + _mm512_mask_i64scatter_ps::<4>(arr.as_mut_ptr(), mask, index, src); + } let mut expected = [0f32; 128]; for i in 0..4 { expected[i * 32 + 16] = 2. * (i + 1) as f32; @@ -7673,12 +7687,14 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32scatter_epi64() { + fn test_mm512_i32scatter_epi64() { let mut arr = [0i64; 128]; let index = _mm256_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); // A multiplier of 8 is word-addressing - _mm512_i32scatter_epi64::<8>(arr.as_mut_ptr(), index, src); + unsafe { + _mm512_i32scatter_epi64::<8>(arr.as_mut_ptr(), index, src); + } let mut expected = [0i64; 128]; for i in 0..8 { expected[i * 16] = (i + 1) as i64; @@ -7687,13 +7703,15 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32scatter_epi64() { + fn test_mm512_mask_i32scatter_epi64() { let mut arr = [0i64; 128]; let mask = 0b10101010; let index = _mm256_setr_epi32(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); // A multiplier of 8 is word-addressing - _mm512_mask_i32scatter_epi64::<8>(arr.as_mut_ptr(), mask, index, src); + unsafe { + _mm512_mask_i32scatter_epi64::<8>(arr.as_mut_ptr(), mask, index, src); + } let mut expected = [0i64; 128]; for i in 0..4 { expected[i * 32 + 16] = 2 * (i + 1) as i64; @@ -7702,12 +7720,14 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i64scatter_epi64() { + fn test_mm512_i64scatter_epi64() { let mut arr = [0i64; 128]; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); // A multiplier of 8 is word-addressing - _mm512_i64scatter_epi64::<8>(arr.as_mut_ptr(), index, src); + unsafe { + _mm512_i64scatter_epi64::<8>(arr.as_mut_ptr(), index, src); + } let mut expected = [0i64; 128]; for i in 0..8 { expected[i * 16] = (i + 1) as i64; @@ -7716,13 +7736,15 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i64scatter_epi64() { + fn test_mm512_mask_i64scatter_epi64() { let mut arr = [0i64; 128]; let mask = 0b10101010; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm512_setr_epi64(1, 2, 3, 4, 5, 6, 7, 8); // A multiplier of 8 is word-addressing - _mm512_mask_i64scatter_epi64::<8>(arr.as_mut_ptr(), mask, index, src); + unsafe { + _mm512_mask_i64scatter_epi64::<8>(arr.as_mut_ptr(), mask, index, src); + } let mut expected = [0i64; 128]; for i in 0..4 { expected[i * 32 + 16] = 2 * (i + 1) as i64; @@ -7731,12 +7753,14 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i64scatter_epi32() { + fn test_mm512_i64scatter_epi32() { let mut arr = [0i32; 128]; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); // A multiplier of 4 is word-addressing - _mm512_i64scatter_epi32::<4>(arr.as_mut_ptr(), index, src); + unsafe { + _mm512_i64scatter_epi32::<4>(arr.as_mut_ptr(), index, src); + } let mut expected = [0i32; 128]; for i in 0..8 { expected[i * 16] = (i + 1) as i32; @@ -7745,13 +7769,15 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i64scatter_epi32() { + fn test_mm512_mask_i64scatter_epi32() { let mut arr = [0i32; 128]; let mask = 0b10101010; let index = _mm512_setr_epi64(0, 16, 32, 48, 64, 80, 96, 112); let src = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8); // A multiplier of 4 is word-addressing - _mm512_mask_i64scatter_epi32::<4>(arr.as_mut_ptr(), mask, index, src); + unsafe { + _mm512_mask_i64scatter_epi32::<4>(arr.as_mut_ptr(), mask, index, src); + } let mut expected = [0i32; 128]; for i in 0..4 { expected[i * 32 + 16] = 2 * (i + 1) as i32; @@ -7760,559 +7786,640 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32logather_epi64() { + fn test_mm512_i32logather_epi64() { let base_addr: [i64; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; let vindex = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1); - let r = _mm512_i32logather_epi64::<8>(vindex, base_addr.as_ptr()); + let r = unsafe { _mm512_i32logather_epi64::<8>(vindex, base_addr.as_ptr()) }; let expected = _mm512_setr_epi64(2, 3, 4, 5, 6, 7, 8, 1); assert_eq_m512i(expected, r); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32logather_epi64() { + fn test_mm512_mask_i32logather_epi64() { let base_addr: [i64; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; let src = _mm512_setr_epi64(9, 10, 11, 12, 13, 14, 15, 16); let vindex = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1); - let r = _mm512_mask_i32logather_epi64::<8>(src, 0b01010101, vindex, base_addr.as_ptr()); + let r = unsafe { + _mm512_mask_i32logather_epi64::<8>(src, 0b01010101, vindex, base_addr.as_ptr()) + }; let expected = _mm512_setr_epi64(2, 10, 4, 12, 6, 14, 8, 16); assert_eq_m512i(expected, r); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32logather_pd() { + fn test_mm512_i32logather_pd() { let base_addr: [f64; 8] = [1., 2., 3., 4., 5., 6., 7., 8.]; let vindex = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1); - let r = _mm512_i32logather_pd::<8>(vindex, base_addr.as_ptr()); + let r = unsafe { _mm512_i32logather_pd::<8>(vindex, base_addr.as_ptr()) }; let expected = _mm512_setr_pd(2., 3., 4., 5., 6., 7., 8., 1.); assert_eq_m512d(expected, r); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32logather_pd() { + fn test_mm512_mask_i32logather_pd() { let base_addr: [f64; 8] = [1., 2., 3., 4., 5., 6., 7., 8.]; let src = _mm512_setr_pd(9., 10., 11., 12., 13., 14., 15., 16.); let vindex = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1); - let r = _mm512_mask_i32logather_pd::<8>(src, 0b01010101, vindex, base_addr.as_ptr()); + let r = + unsafe { _mm512_mask_i32logather_pd::<8>(src, 0b01010101, vindex, base_addr.as_ptr()) }; let expected = _mm512_setr_pd(2., 10., 4., 12., 6., 14., 8., 16.); assert_eq_m512d(expected, r); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32loscatter_epi64() { + fn test_mm512_i32loscatter_epi64() { let mut base_addr: [i64; 8] = [0; 8]; let vindex = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1); let src = _mm512_setr_epi64(2, 3, 4, 5, 6, 7, 8, 1); - _mm512_i32loscatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm512_i32loscatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1, 2, 3, 4, 5, 6, 7, 8]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32loscatter_epi64() { + fn test_mm512_mask_i32loscatter_epi64() { let mut base_addr: [i64; 8] = [0; 8]; let vindex = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1); let src = _mm512_setr_epi64(2, 3, 4, 5, 6, 7, 8, 1); - _mm512_mask_i32loscatter_epi64::<8>(base_addr.as_mut_ptr(), 0b01010101, vindex, src); + unsafe { + _mm512_mask_i32loscatter_epi64::<8>(base_addr.as_mut_ptr(), 0b01010101, vindex, src); + } let expected = [0, 2, 0, 4, 0, 6, 0, 8]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_i32loscatter_pd() { + fn test_mm512_i32loscatter_pd() { let mut base_addr: [f64; 8] = [0.; 8]; let vindex = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1); let src = _mm512_setr_pd(2., 3., 4., 5., 6., 7., 8., 1.); - _mm512_i32loscatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm512_i32loscatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1., 2., 3., 4., 5., 6., 7., 8.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_i32loscatter_pd() { + fn test_mm512_mask_i32loscatter_pd() { let mut base_addr: [f64; 8] = [0.; 8]; let vindex = _mm512_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1); let src = _mm512_setr_pd(2., 3., 4., 5., 6., 7., 8., 1.); - _mm512_mask_i32loscatter_pd::<8>(base_addr.as_mut_ptr(), 0b01010101, vindex, src); + unsafe { + _mm512_mask_i32loscatter_pd::<8>(base_addr.as_mut_ptr(), 0b01010101, vindex, src); + } let expected = [0., 2., 0., 4., 0., 6., 0., 8.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mmask_i32gather_epi32() { + fn test_mm_mmask_i32gather_epi32() { let base_addr: [i32; 4] = [1, 2, 3, 4]; let src = _mm_setr_epi32(5, 6, 7, 8); let vindex = _mm_setr_epi32(1, 2, 3, 0); - let r = _mm_mmask_i32gather_epi32::<4>(src, 0b0101, vindex, base_addr.as_ptr()); + let r = unsafe { _mm_mmask_i32gather_epi32::<4>(src, 0b0101, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_epi32(2, 6, 4, 8); assert_eq_m128i(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mmask_i32gather_epi64() { + fn test_mm_mmask_i32gather_epi64() { let base_addr: [i64; 2] = [1, 2]; let src = _mm_setr_epi64x(5, 6); let vindex = _mm_setr_epi32(1, 0, -1, -1); - let r = _mm_mmask_i32gather_epi64::<8>(src, 0b01, vindex, base_addr.as_ptr()); + let r = unsafe { _mm_mmask_i32gather_epi64::<8>(src, 0b01, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_epi64x(2, 6); assert_eq_m128i(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mmask_i32gather_pd() { + fn test_mm_mmask_i32gather_pd() { let base_addr: [f64; 2] = [1., 2.]; let src = _mm_setr_pd(5., 6.); let vindex = _mm_setr_epi32(1, 0, -1, -1); - let r = _mm_mmask_i32gather_pd::<8>(src, 0b01, vindex, base_addr.as_ptr()); + let r = unsafe { _mm_mmask_i32gather_pd::<8>(src, 0b01, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_pd(2., 6.); assert_eq_m128d(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mmask_i32gather_ps() { + fn test_mm_mmask_i32gather_ps() { let base_addr: [f32; 4] = [1., 2., 3., 4.]; let src = _mm_setr_ps(5., 6., 7., 8.); let vindex = _mm_setr_epi32(1, 2, 3, 0); - let r = _mm_mmask_i32gather_ps::<4>(src, 0b0101, vindex, base_addr.as_ptr()); + let r = unsafe { _mm_mmask_i32gather_ps::<4>(src, 0b0101, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_ps(2., 6., 4., 8.); assert_eq_m128(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mmask_i64gather_epi32() { + fn test_mm_mmask_i64gather_epi32() { let base_addr: [i32; 2] = [1, 2]; let src = _mm_setr_epi32(5, 6, 7, 8); let vindex = _mm_setr_epi64x(1, 0); - let r = _mm_mmask_i64gather_epi32::<4>(src, 0b01, vindex, base_addr.as_ptr()); + let r = unsafe { _mm_mmask_i64gather_epi32::<4>(src, 0b01, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_epi32(2, 6, 0, 0); assert_eq_m128i(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mmask_i64gather_epi64() { + fn test_mm_mmask_i64gather_epi64() { let base_addr: [i64; 2] = [1, 2]; let src = _mm_setr_epi64x(5, 6); let vindex = _mm_setr_epi64x(1, 0); - let r = _mm_mmask_i64gather_epi64::<8>(src, 0b01, vindex, base_addr.as_ptr()); + let r = unsafe { _mm_mmask_i64gather_epi64::<8>(src, 0b01, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_epi64x(2, 6); assert_eq_m128i(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mmask_i64gather_pd() { + fn test_mm_mmask_i64gather_pd() { let base_addr: [f64; 2] = [1., 2.]; let src = _mm_setr_pd(5., 6.); let vindex = _mm_setr_epi64x(1, 0); - let r = _mm_mmask_i64gather_pd::<8>(src, 0b01, vindex, base_addr.as_ptr()); + let r = unsafe { _mm_mmask_i64gather_pd::<8>(src, 0b01, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_pd(2., 6.); assert_eq_m128d(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mmask_i64gather_ps() { + fn test_mm_mmask_i64gather_ps() { let base_addr: [f32; 2] = [1., 2.]; let src = _mm_setr_ps(5., 6., 7., 8.); let vindex = _mm_setr_epi64x(1, 0); - let r = _mm_mmask_i64gather_ps::<4>(src, 0b01, vindex, base_addr.as_ptr()); + let r = unsafe { _mm_mmask_i64gather_ps::<4>(src, 0b01, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_ps(2., 6., 0., 0.); assert_eq_m128(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mmask_i32gather_epi32() { + fn test_mm256_mmask_i32gather_epi32() { let base_addr: [i32; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; let src = _mm256_setr_epi32(9, 10, 11, 12, 13, 14, 15, 16); let vindex = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0); - let r = _mm256_mmask_i32gather_epi32::<4>(src, 0b01010101, vindex, base_addr.as_ptr()); + let r = unsafe { + _mm256_mmask_i32gather_epi32::<4>(src, 0b01010101, vindex, base_addr.as_ptr()) + }; let expected = _mm256_setr_epi32(2, 10, 4, 12, 6, 14, 8, 16); assert_eq_m256i(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mmask_i32gather_epi64() { + fn test_mm256_mmask_i32gather_epi64() { let base_addr: [i64; 4] = [1, 2, 3, 4]; let src = _mm256_setr_epi64x(9, 10, 11, 12); let vindex = _mm_setr_epi32(1, 2, 3, 4); - let r = _mm256_mmask_i32gather_epi64::<8>(src, 0b0101, vindex, base_addr.as_ptr()); + let r = + unsafe { _mm256_mmask_i32gather_epi64::<8>(src, 0b0101, vindex, base_addr.as_ptr()) }; let expected = _mm256_setr_epi64x(2, 10, 4, 12); assert_eq_m256i(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mmask_i32gather_pd() { + fn test_mm256_mmask_i32gather_pd() { let base_addr: [f64; 4] = [1., 2., 3., 4.]; let src = _mm256_setr_pd(9., 10., 11., 12.); let vindex = _mm_setr_epi32(1, 2, 3, 4); - let r = _mm256_mmask_i32gather_pd::<8>(src, 0b0101, vindex, base_addr.as_ptr()); + let r = unsafe { _mm256_mmask_i32gather_pd::<8>(src, 0b0101, vindex, base_addr.as_ptr()) }; let expected = _mm256_setr_pd(2., 10., 4., 12.); assert_eq_m256d(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mmask_i32gather_ps() { + fn test_mm256_mmask_i32gather_ps() { let base_addr: [f32; 8] = [1., 2., 3., 4., 5., 6., 7., 8.]; let src = _mm256_setr_ps(9., 10., 11., 12., 13., 14., 15., 16.); let vindex = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0); - let r = _mm256_mmask_i32gather_ps::<4>(src, 0b01010101, vindex, base_addr.as_ptr()); + let r = + unsafe { _mm256_mmask_i32gather_ps::<4>(src, 0b01010101, vindex, base_addr.as_ptr()) }; let expected = _mm256_setr_ps(2., 10., 4., 12., 6., 14., 8., 16.); assert_eq_m256(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mmask_i64gather_epi32() { + fn test_mm256_mmask_i64gather_epi32() { let base_addr: [i32; 4] = [1, 2, 3, 4]; let src = _mm_setr_epi32(9, 10, 11, 12); let vindex = _mm256_setr_epi64x(1, 2, 3, 0); - let r = _mm256_mmask_i64gather_epi32::<4>(src, 0b0101, vindex, base_addr.as_ptr()); + let r = + unsafe { _mm256_mmask_i64gather_epi32::<4>(src, 0b0101, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_epi32(2, 10, 4, 12); assert_eq_m128i(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mmask_i64gather_epi64() { + fn test_mm256_mmask_i64gather_epi64() { let base_addr: [i64; 4] = [1, 2, 3, 4]; let src = _mm256_setr_epi64x(9, 10, 11, 12); let vindex = _mm256_setr_epi64x(1, 2, 3, 0); - let r = _mm256_mmask_i64gather_epi64::<8>(src, 0b0101, vindex, base_addr.as_ptr()); + let r = + unsafe { _mm256_mmask_i64gather_epi64::<8>(src, 0b0101, vindex, base_addr.as_ptr()) }; let expected = _mm256_setr_epi64x(2, 10, 4, 12); assert_eq_m256i(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mmask_i64gather_pd() { + fn test_mm256_mmask_i64gather_pd() { let base_addr: [f64; 4] = [1., 2., 3., 4.]; let src = _mm256_setr_pd(9., 10., 11., 12.); let vindex = _mm256_setr_epi64x(1, 2, 3, 0); - let r = _mm256_mmask_i64gather_pd::<8>(src, 0b0101, vindex, base_addr.as_ptr()); + let r = unsafe { _mm256_mmask_i64gather_pd::<8>(src, 0b0101, vindex, base_addr.as_ptr()) }; let expected = _mm256_setr_pd(2., 10., 4., 12.); assert_eq_m256d(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mmask_i64gather_ps() { + fn test_mm256_mmask_i64gather_ps() { let base_addr: [f32; 4] = [1., 2., 3., 4.]; let src = _mm_setr_ps(9., 10., 11., 12.); let vindex = _mm256_setr_epi64x(1, 2, 3, 0); - let r = _mm256_mmask_i64gather_ps::<4>(src, 0b0101, vindex, base_addr.as_ptr()); + let r = unsafe { _mm256_mmask_i64gather_ps::<4>(src, 0b0101, vindex, base_addr.as_ptr()) }; let expected = _mm_setr_ps(2., 10., 4., 12.); assert_eq_m128(expected, r); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_i32scatter_epi32() { + fn test_mm_i32scatter_epi32() { let mut base_addr: [i32; 4] = [0; 4]; let vindex = _mm_setr_epi32(1, 2, 3, 0); let src = _mm_setr_epi32(2, 3, 4, 1); - _mm_i32scatter_epi32::<4>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm_i32scatter_epi32::<4>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1, 2, 3, 4]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_i32scatter_epi32() { + fn test_mm_mask_i32scatter_epi32() { let mut base_addr: [i32; 4] = [0; 4]; let vindex = _mm_setr_epi32(1, 2, 3, 0); let src = _mm_setr_epi32(2, 3, 4, 1); - _mm_mask_i32scatter_epi32::<4>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + unsafe { + _mm_mask_i32scatter_epi32::<4>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + } let expected = [0, 2, 0, 4]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_i32scatter_epi64() { + fn test_mm_i32scatter_epi64() { let mut base_addr: [i64; 2] = [0; 2]; let vindex = _mm_setr_epi32(1, 0, -1, -1); let src = _mm_setr_epi64x(2, 1); - _mm_i32scatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm_i32scatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1, 2]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_i32scatter_epi64() { + fn test_mm_mask_i32scatter_epi64() { let mut base_addr: [i64; 2] = [0; 2]; let vindex = _mm_setr_epi32(1, 0, -1, -1); let src = _mm_setr_epi64x(2, 1); - _mm_mask_i32scatter_epi64::<8>(base_addr.as_mut_ptr(), 0b01, vindex, src); + unsafe { + _mm_mask_i32scatter_epi64::<8>(base_addr.as_mut_ptr(), 0b01, vindex, src); + } let expected = [0, 2]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_i32scatter_pd() { + fn test_mm_i32scatter_pd() { let mut base_addr: [f64; 2] = [0.; 2]; let vindex = _mm_setr_epi32(1, 0, -1, -1); let src = _mm_setr_pd(2., 1.); - _mm_i32scatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm_i32scatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1., 2.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_i32scatter_pd() { + fn test_mm_mask_i32scatter_pd() { let mut base_addr: [f64; 2] = [0.; 2]; let vindex = _mm_setr_epi32(1, 0, -1, -1); let src = _mm_setr_pd(2., 1.); - _mm_mask_i32scatter_pd::<8>(base_addr.as_mut_ptr(), 0b01, vindex, src); + unsafe { + _mm_mask_i32scatter_pd::<8>(base_addr.as_mut_ptr(), 0b01, vindex, src); + } let expected = [0., 2.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_i32scatter_ps() { + fn test_mm_i32scatter_ps() { let mut base_addr: [f32; 4] = [0.; 4]; let vindex = _mm_setr_epi32(1, 2, 3, 0); let src = _mm_setr_ps(2., 3., 4., 1.); - _mm_i32scatter_ps::<4>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm_i32scatter_ps::<4>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1., 2., 3., 4.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_i32scatter_ps() { + fn test_mm_mask_i32scatter_ps() { let mut base_addr: [f32; 4] = [0.; 4]; let vindex = _mm_setr_epi32(1, 2, 3, 0); let src = _mm_setr_ps(2., 3., 4., 1.); - _mm_mask_i32scatter_ps::<4>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + unsafe { + _mm_mask_i32scatter_ps::<4>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + } let expected = [0., 2., 0., 4.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_i64scatter_epi32() { + fn test_mm_i64scatter_epi32() { let mut base_addr: [i32; 2] = [0; 2]; let vindex = _mm_setr_epi64x(1, 0); let src = _mm_setr_epi32(2, 1, -1, -1); - _mm_i64scatter_epi32::<4>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm_i64scatter_epi32::<4>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1, 2]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_i64scatter_epi32() { + fn test_mm_mask_i64scatter_epi32() { let mut base_addr: [i32; 2] = [0; 2]; let vindex = _mm_setr_epi64x(1, 0); let src = _mm_setr_epi32(2, 1, -1, -1); - _mm_mask_i64scatter_epi32::<4>(base_addr.as_mut_ptr(), 0b01, vindex, src); + unsafe { + _mm_mask_i64scatter_epi32::<4>(base_addr.as_mut_ptr(), 0b01, vindex, src); + } let expected = [0, 2]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_i64scatter_epi64() { + fn test_mm_i64scatter_epi64() { let mut base_addr: [i64; 2] = [0; 2]; let vindex = _mm_setr_epi64x(1, 0); let src = _mm_setr_epi64x(2, 1); - _mm_i64scatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm_i64scatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1, 2]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_i64scatter_epi64() { + fn test_mm_mask_i64scatter_epi64() { let mut base_addr: [i64; 2] = [0; 2]; let vindex = _mm_setr_epi64x(1, 0); let src = _mm_setr_epi64x(2, 1); - _mm_mask_i64scatter_epi64::<8>(base_addr.as_mut_ptr(), 0b01, vindex, src); + unsafe { + _mm_mask_i64scatter_epi64::<8>(base_addr.as_mut_ptr(), 0b01, vindex, src); + } let expected = [0, 2]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_i64scatter_pd() { + fn test_mm_i64scatter_pd() { let mut base_addr: [f64; 2] = [0.; 2]; let vindex = _mm_setr_epi64x(1, 0); let src = _mm_setr_pd(2., 1.); - _mm_i64scatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm_i64scatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1., 2.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_i64scatter_pd() { + fn test_mm_mask_i64scatter_pd() { let mut base_addr: [f64; 2] = [0.; 2]; let vindex = _mm_setr_epi64x(1, 0); let src = _mm_setr_pd(2., 1.); - _mm_mask_i64scatter_pd::<8>(base_addr.as_mut_ptr(), 0b01, vindex, src); + unsafe { + _mm_mask_i64scatter_pd::<8>(base_addr.as_mut_ptr(), 0b01, vindex, src); + } let expected = [0., 2.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_i64scatter_ps() { + fn test_mm_i64scatter_ps() { let mut base_addr: [f32; 2] = [0.; 2]; let vindex = _mm_setr_epi64x(1, 0); let src = _mm_setr_ps(2., 1., -1., -1.); - _mm_i64scatter_ps::<4>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm_i64scatter_ps::<4>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1., 2.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_i64scatter_ps() { + fn test_mm_mask_i64scatter_ps() { let mut base_addr: [f32; 2] = [0.; 2]; let vindex = _mm_setr_epi64x(1, 0); let src = _mm_setr_ps(2., 1., -1., -1.); - _mm_mask_i64scatter_ps::<4>(base_addr.as_mut_ptr(), 0b01, vindex, src); + unsafe { + _mm_mask_i64scatter_ps::<4>(base_addr.as_mut_ptr(), 0b01, vindex, src); + } let expected = [0., 2.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_i32scatter_epi32() { + fn test_mm256_i32scatter_epi32() { let mut base_addr: [i32; 8] = [0; 8]; let vindex = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0); let src = _mm256_setr_epi32(2, 3, 4, 5, 6, 7, 8, 1); - _mm256_i32scatter_epi32::<4>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm256_i32scatter_epi32::<4>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1, 2, 3, 4, 5, 6, 7, 8]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_i32scatter_epi32() { + fn test_mm256_mask_i32scatter_epi32() { let mut base_addr: [i32; 8] = [0; 8]; let vindex = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0); let src = _mm256_setr_epi32(2, 3, 4, 5, 6, 7, 8, 1); - _mm256_mask_i32scatter_epi32::<4>(base_addr.as_mut_ptr(), 0b01010101, vindex, src); + unsafe { + _mm256_mask_i32scatter_epi32::<4>(base_addr.as_mut_ptr(), 0b01010101, vindex, src); + } let expected = [0, 2, 0, 4, 0, 6, 0, 8]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_i32scatter_epi64() { + fn test_mm256_i32scatter_epi64() { let mut base_addr: [i64; 4] = [0; 4]; let vindex = _mm_setr_epi32(1, 2, 3, 0); let src = _mm256_setr_epi64x(2, 3, 4, 1); - _mm256_i32scatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm256_i32scatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1, 2, 3, 4]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_i32scatter_epi64() { + fn test_mm256_mask_i32scatter_epi64() { let mut base_addr: [i64; 4] = [0; 4]; let vindex = _mm_setr_epi32(1, 2, 3, 0); let src = _mm256_setr_epi64x(2, 3, 4, 1); - _mm256_mask_i32scatter_epi64::<8>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + unsafe { + _mm256_mask_i32scatter_epi64::<8>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + } let expected = [0, 2, 0, 4]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_i32scatter_pd() { + fn test_mm256_i32scatter_pd() { let mut base_addr: [f64; 4] = [0.; 4]; let vindex = _mm_setr_epi32(1, 2, 3, 0); let src = _mm256_setr_pd(2., 3., 4., 1.); - _mm256_i32scatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm256_i32scatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1., 2., 3., 4.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_i32scatter_pd() { + fn test_mm256_mask_i32scatter_pd() { let mut base_addr: [f64; 4] = [0.; 4]; let vindex = _mm_setr_epi32(1, 2, 3, 0); let src = _mm256_setr_pd(2., 3., 4., 1.); - _mm256_mask_i32scatter_pd::<8>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + unsafe { + _mm256_mask_i32scatter_pd::<8>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + } let expected = [0., 2., 0., 4.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_i32scatter_ps() { + fn test_mm256_i32scatter_ps() { let mut base_addr: [f32; 8] = [0.; 8]; let vindex = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0); let src = _mm256_setr_ps(2., 3., 4., 5., 6., 7., 8., 1.); - _mm256_i32scatter_ps::<4>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm256_i32scatter_ps::<4>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1., 2., 3., 4., 5., 6., 7., 8.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_i32scatter_ps() { + fn test_mm256_mask_i32scatter_ps() { let mut base_addr: [f32; 8] = [0.; 8]; let vindex = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0); let src = _mm256_setr_ps(2., 3., 4., 5., 6., 7., 8., 1.); - _mm256_mask_i32scatter_ps::<4>(base_addr.as_mut_ptr(), 0b01010101, vindex, src); + unsafe { + _mm256_mask_i32scatter_ps::<4>(base_addr.as_mut_ptr(), 0b01010101, vindex, src); + } let expected = [0., 2., 0., 4., 0., 6., 0., 8.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_i64scatter_epi32() { + fn test_mm256_i64scatter_epi32() { let mut base_addr: [i32; 4] = [0; 4]; let vindex = _mm256_setr_epi64x(1, 2, 3, 0); let src = _mm_setr_epi32(2, 3, 4, 1); - _mm256_i64scatter_epi32::<4>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm256_i64scatter_epi32::<4>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1, 2, 3, 4]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_i64scatter_epi32() { + fn test_mm256_mask_i64scatter_epi32() { let mut base_addr: [i32; 4] = [0; 4]; let vindex = _mm256_setr_epi64x(1, 2, 3, 0); let src = _mm_setr_epi32(2, 3, 4, 1); - _mm256_mask_i64scatter_epi32::<4>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + unsafe { + _mm256_mask_i64scatter_epi32::<4>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + } let expected = [0, 2, 0, 4]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_i64scatter_epi64() { + fn test_mm256_i64scatter_epi64() { let mut base_addr: [i64; 4] = [0; 4]; let vindex = _mm256_setr_epi64x(1, 2, 3, 0); let src = _mm256_setr_epi64x(2, 3, 4, 1); - _mm256_i64scatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm256_i64scatter_epi64::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1, 2, 3, 4]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_i64scatter_epi64() { + fn test_mm256_mask_i64scatter_epi64() { let mut base_addr: [i64; 4] = [0; 4]; let vindex = _mm256_setr_epi64x(1, 2, 3, 0); let src = _mm256_setr_epi64x(2, 3, 4, 1); - _mm256_mask_i64scatter_epi64::<8>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + unsafe { + _mm256_mask_i64scatter_epi64::<8>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + } let expected = [0, 2, 0, 4]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_i64scatter_pd() { + fn test_mm256_i64scatter_pd() { let mut base_addr: [f64; 4] = [0.; 4]; let vindex = _mm256_setr_epi64x(1, 2, 3, 0); let src = _mm256_setr_pd(2., 3., 4., 1.); - _mm256_i64scatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm256_i64scatter_pd::<8>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1., 2., 3., 4.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_i64scatter_pd() { + fn test_mm256_mask_i64scatter_pd() { let mut base_addr: [f64; 4] = [0.; 4]; let vindex = _mm256_setr_epi64x(1, 2, 3, 0); let src = _mm256_setr_pd(2., 3., 4., 1.); - _mm256_mask_i64scatter_pd::<8>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + unsafe { + _mm256_mask_i64scatter_pd::<8>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + } let expected = [0., 2., 0., 4.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_i64scatter_ps() { + fn test_mm256_i64scatter_ps() { let mut base_addr: [f32; 4] = [0.; 4]; let vindex = _mm256_setr_epi64x(1, 2, 3, 0); let src = _mm_setr_ps(2., 3., 4., 1.); - _mm256_i64scatter_ps::<4>(base_addr.as_mut_ptr(), vindex, src); + unsafe { + _mm256_i64scatter_ps::<4>(base_addr.as_mut_ptr(), vindex, src); + } let expected = [1., 2., 3., 4.]; assert_eq!(expected, base_addr); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_i64scatter_ps() { + fn test_mm256_mask_i64scatter_ps() { let mut base_addr: [f32; 4] = [0.; 4]; let vindex = _mm256_setr_epi64x(1, 2, 3, 0); let src = _mm_setr_ps(2., 3., 4., 1.); - _mm256_mask_i64scatter_ps::<4>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + unsafe { + _mm256_mask_i64scatter_ps::<4>(base_addr.as_mut_ptr(), 0b0101, vindex, src); + } let expected = [0., 2., 0., 4.]; assert_eq!(expected, base_addr); } @@ -12168,100 +12275,116 @@ mod tests { } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_loadu_epi64() { + const fn test_mm512_loadu_epi64() { let a = &[4, 3, 2, 5, -8, -9, -64, -50]; let p = a.as_ptr(); - let r = _mm512_loadu_epi64(black_box(p)); + let r = unsafe { _mm512_loadu_epi64(black_box(p)) }; let e = _mm512_setr_epi64(4, 3, 2, 5, -8, -9, -64, -50); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_loadu_epi64() { + const fn test_mm256_loadu_epi64() { let a = &[4, 3, 2, 5]; let p = a.as_ptr(); - let r = _mm256_loadu_epi64(black_box(p)); + let r = unsafe { _mm256_loadu_epi64(black_box(p)) }; let e = _mm256_setr_epi64x(4, 3, 2, 5); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_loadu_epi64() { + const fn test_mm_loadu_epi64() { let a = &[4, 3]; let p = a.as_ptr(); - let r = _mm_loadu_epi64(black_box(p)); + let r = unsafe { _mm_loadu_epi64(black_box(p)) }; let e = _mm_setr_epi64x(4, 3); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi64_storeu_epi16() { + fn test_mm512_mask_cvtepi64_storeu_epi16() { let a = _mm512_set1_epi64(9); let mut r = _mm_undefined_si128(); - _mm512_mask_cvtepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm512_mask_cvtepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set1_epi16(9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi64_storeu_epi16() { + fn test_mm256_mask_cvtepi64_storeu_epi16() { let a = _mm256_set1_epi64x(9); let mut r = _mm_set1_epi16(0); - _mm256_mask_cvtepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm256_mask_cvtepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set_epi16(0, 0, 0, 0, 9, 9, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi64_storeu_epi16() { + fn test_mm_mask_cvtepi64_storeu_epi16() { let a = _mm_set1_epi64x(9); let mut r = _mm_set1_epi16(0); - _mm_mask_cvtepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm_mask_cvtepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set_epi16(0, 0, 0, 0, 0, 0, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtsepi64_storeu_epi16() { + fn test_mm512_mask_cvtsepi64_storeu_epi16() { let a = _mm512_set1_epi64(i64::MAX); let mut r = _mm_undefined_si128(); - _mm512_mask_cvtsepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm512_mask_cvtsepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set1_epi16(i16::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtsepi64_storeu_epi16() { + fn test_mm256_mask_cvtsepi64_storeu_epi16() { let a = _mm256_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi16(0); - _mm256_mask_cvtsepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm256_mask_cvtsepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set_epi16(0, 0, 0, 0, i16::MAX, i16::MAX, i16::MAX, i16::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtsepi64_storeu_epi16() { + fn test_mm_mask_cvtsepi64_storeu_epi16() { let a = _mm_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi16(0); - _mm_mask_cvtsepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm_mask_cvtsepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set_epi16(0, 0, 0, 0, 0, 0, i16::MAX, i16::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtusepi64_storeu_epi16() { + fn test_mm512_mask_cvtusepi64_storeu_epi16() { let a = _mm512_set1_epi64(i64::MAX); let mut r = _mm_undefined_si128(); - _mm512_mask_cvtusepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm512_mask_cvtusepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set1_epi16(u16::MAX as i16); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtusepi64_storeu_epi16() { + fn test_mm256_mask_cvtusepi64_storeu_epi16() { let a = _mm256_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi16(0); - _mm256_mask_cvtusepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm256_mask_cvtusepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set_epi16( 0, 0, @@ -12276,46 +12399,56 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtusepi64_storeu_epi16() { + fn test_mm_mask_cvtusepi64_storeu_epi16() { let a = _mm_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi16(0); - _mm_mask_cvtusepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + unsafe { + _mm_mask_cvtusepi64_storeu_epi16(&mut r as *mut _ as *mut i16, 0b11111111, a); + } let e = _mm_set_epi16(0, 0, 0, 0, 0, 0, u16::MAX as i16, u16::MAX as i16); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi64_storeu_epi8() { + fn test_mm512_mask_cvtepi64_storeu_epi8() { let a = _mm512_set1_epi64(9); let mut r = _mm_set1_epi8(0); - _mm512_mask_cvtepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm512_mask_cvtepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } let e = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi64_storeu_epi8() { + fn test_mm256_mask_cvtepi64_storeu_epi8() { let a = _mm256_set1_epi64x(9); let mut r = _mm_set1_epi8(0); - _mm256_mask_cvtepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm256_mask_cvtepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } let e = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi64_storeu_epi8() { + fn test_mm_mask_cvtepi64_storeu_epi8() { let a = _mm_set1_epi64x(9); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm_mask_cvtepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } let e = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtsepi64_storeu_epi8() { + fn test_mm512_mask_cvtsepi64_storeu_epi8() { let a = _mm512_set1_epi64(i64::MAX); let mut r = _mm_set1_epi8(0); - _mm512_mask_cvtsepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm512_mask_cvtsepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, @@ -12327,10 +12460,12 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtsepi64_storeu_epi8() { + fn test_mm256_mask_cvtsepi64_storeu_epi8() { let a = _mm256_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi8(0); - _mm256_mask_cvtsepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm256_mask_cvtsepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, @@ -12342,19 +12477,23 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtsepi64_storeu_epi8() { + fn test_mm_mask_cvtsepi64_storeu_epi8() { let a = _mm_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtsepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm_mask_cvtsepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } let e = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, i8::MAX, i8::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtusepi64_storeu_epi8() { + fn test_mm512_mask_cvtusepi64_storeu_epi8() { let a = _mm512_set1_epi64(i64::MAX); let mut r = _mm_set1_epi8(0); - _mm512_mask_cvtusepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm512_mask_cvtusepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, @@ -12366,10 +12505,12 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtusepi64_storeu_epi8() { + fn test_mm256_mask_cvtusepi64_storeu_epi8() { let a = _mm256_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi8(0); - _mm256_mask_cvtusepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm256_mask_cvtusepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, @@ -12381,10 +12522,12 @@ mod tests { } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtusepi64_storeu_epi8() { + fn test_mm_mask_cvtusepi64_storeu_epi8() { let a = _mm_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi8(0); - _mm_mask_cvtusepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + unsafe { + _mm_mask_cvtusepi64_storeu_epi8(&mut r as *mut _ as *mut i8, 0b11111111, a); + } #[rustfmt::skip] let e = _mm_set_epi8( 0, 0, 0, 0, @@ -12396,112 +12539,136 @@ mod tests { } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtepi64_storeu_epi32() { + fn test_mm512_mask_cvtepi64_storeu_epi32() { let a = _mm512_set1_epi64(9); let mut r = _mm256_undefined_si256(); - _mm512_mask_cvtepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + unsafe { + _mm512_mask_cvtepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + } let e = _mm256_set1_epi32(9); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtepi64_storeu_epi32() { + fn test_mm256_mask_cvtepi64_storeu_epi32() { let a = _mm256_set1_epi64x(9); let mut r = _mm_set1_epi32(0); - _mm256_mask_cvtepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + unsafe { + _mm256_mask_cvtepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + } let e = _mm_set_epi32(9, 9, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtepi64_storeu_epi32() { + fn test_mm_mask_cvtepi64_storeu_epi32() { let a = _mm_set1_epi64x(9); let mut r = _mm_set1_epi16(0); - _mm_mask_cvtepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + unsafe { + _mm_mask_cvtepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + } let e = _mm_set_epi32(0, 0, 9, 9); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtsepi64_storeu_epi32() { + fn test_mm512_mask_cvtsepi64_storeu_epi32() { let a = _mm512_set1_epi64(i64::MAX); let mut r = _mm256_undefined_si256(); - _mm512_mask_cvtsepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + unsafe { + _mm512_mask_cvtsepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + } let e = _mm256_set1_epi32(i32::MAX); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtsepi64_storeu_epi32() { + fn test_mm256_mask_cvtsepi64_storeu_epi32() { let a = _mm256_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi32(0); - _mm256_mask_cvtsepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b00001111, a); + unsafe { + _mm256_mask_cvtsepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b00001111, a); + } let e = _mm_set1_epi32(i32::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtsepi64_storeu_epi32() { + fn test_mm_mask_cvtsepi64_storeu_epi32() { let a = _mm_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi16(0); - _mm_mask_cvtsepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b00000011, a); + unsafe { + _mm_mask_cvtsepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b00000011, a); + } let e = _mm_set_epi32(0, 0, i32::MAX, i32::MAX); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - unsafe fn test_mm512_mask_cvtusepi64_storeu_epi32() { + fn test_mm512_mask_cvtusepi64_storeu_epi32() { let a = _mm512_set1_epi64(i64::MAX); let mut r = _mm256_undefined_si256(); - _mm512_mask_cvtusepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + unsafe { + _mm512_mask_cvtusepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b11111111, a); + } let e = _mm256_set1_epi32(u32::MAX as i32); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm256_mask_cvtusepi64_storeu_epi32() { + fn test_mm256_mask_cvtusepi64_storeu_epi32() { let a = _mm256_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi32(0); - _mm256_mask_cvtusepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b00001111, a); + unsafe { + _mm256_mask_cvtusepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b00001111, a); + } let e = _mm_set1_epi32(u32::MAX as i32); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - unsafe fn test_mm_mask_cvtusepi64_storeu_epi32() { + fn test_mm_mask_cvtusepi64_storeu_epi32() { let a = _mm_set1_epi64x(i64::MAX); let mut r = _mm_set1_epi16(0); - _mm_mask_cvtusepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b00000011, a); + unsafe { + _mm_mask_cvtusepi64_storeu_epi32(&mut r as *mut _ as *mut i32, 0b00000011, a); + } let e = _mm_set_epi32(0, 0, u32::MAX as i32, u32::MAX as i32); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_storeu_epi64() { + const fn test_mm512_storeu_epi64() { let a = _mm512_set1_epi64(9); let mut r = _mm512_set1_epi64(0); - _mm512_storeu_epi64(&mut r as *mut _ as *mut i64, a); + unsafe { + _mm512_storeu_epi64(&mut r as *mut _ as *mut i64, a); + } assert_eq_m512i(r, a); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_storeu_epi64() { + const fn test_mm256_storeu_epi64() { let a = _mm256_set1_epi64x(9); let mut r = _mm256_set1_epi64x(0); - _mm256_storeu_epi64(&mut r as *mut _ as *mut i64, a); + unsafe { + _mm256_storeu_epi64(&mut r as *mut _ as *mut i64, a); + } assert_eq_m256i(r, a); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_storeu_epi64() { + const fn test_mm_storeu_epi64() { let a = _mm_set1_epi64x(9); let mut r = _mm_set1_epi64x(0); - _mm_storeu_epi64(&mut r as *mut _ as *mut i64, a); + unsafe { + _mm_storeu_epi64(&mut r as *mut _ as *mut i64, a); + } assert_eq_m128i(r, a); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_load_epi64() { + const fn test_mm512_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 8], // 64 bytes @@ -12510,63 +12677,69 @@ mod tests { data: [4, 3, 2, 5, -8, -9, -64, -50], }; let p = (a.data).as_ptr(); - let r = _mm512_load_epi64(black_box(p)); + let r = unsafe { _mm512_load_epi64(black_box(p)) }; let e = _mm512_setr_epi64(4, 3, 2, 5, -8, -9, -64, -50); assert_eq_m512i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_load_epi64() { + const fn test_mm256_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 4], } let a = Align { data: [4, 3, 2, 5] }; let p = (a.data).as_ptr(); - let r = _mm256_load_epi64(black_box(p)); + let r = unsafe { _mm256_load_epi64(black_box(p)) }; let e = _mm256_set_epi64x(5, 2, 3, 4); assert_eq_m256i(r, e); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_load_epi64() { + const fn test_mm_load_epi64() { #[repr(align(64))] struct Align { data: [i64; 2], } let a = Align { data: [4, 3] }; let p = (a.data).as_ptr(); - let r = _mm_load_epi64(black_box(p)); + let r = unsafe { _mm_load_epi64(black_box(p)) }; let e = _mm_set_epi64x(3, 4); assert_eq_m128i(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_store_epi64() { + const fn test_mm512_store_epi64() { let a = _mm512_set1_epi64(9); let mut r = _mm512_set1_epi64(0); - _mm512_store_epi64(&mut r as *mut _ as *mut i64, a); + unsafe { + _mm512_store_epi64(&mut r as *mut _ as *mut i64, a); + } assert_eq_m512i(r, a); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm256_store_epi64() { + const fn test_mm256_store_epi64() { let a = _mm256_set1_epi64x(9); let mut r = _mm256_set1_epi64x(0); - _mm256_store_epi64(&mut r as *mut _ as *mut i64, a); + unsafe { + _mm256_store_epi64(&mut r as *mut _ as *mut i64, a); + } assert_eq_m256i(r, a); } #[simd_test(enable = "avx512f,avx512vl")] - const unsafe fn test_mm_store_epi64() { + const fn test_mm_store_epi64() { let a = _mm_set1_epi64x(9); let mut r = _mm_set1_epi64x(0); - _mm_store_epi64(&mut r as *mut _ as *mut i64, a); + unsafe { + _mm_store_epi64(&mut r as *mut _ as *mut i64, a); + } assert_eq_m128i(r, a); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_load_pd() { + const fn test_mm512_load_pd() { #[repr(align(64))] struct Align { data: [f64; 8], // 64 bytes @@ -12575,16 +12748,18 @@ mod tests { data: [4., 3., 2., 5., -8., -9., -64., -50.], }; let p = (a.data).as_ptr(); - let r = _mm512_load_pd(black_box(p)); + let r = unsafe { _mm512_load_pd(black_box(p)) }; let e = _mm512_setr_pd(4., 3., 2., 5., -8., -9., -64., -50.); assert_eq_m512d(r, e); } #[simd_test(enable = "avx512f")] - const unsafe fn test_mm512_store_pd() { + const fn test_mm512_store_pd() { let a = _mm512_set1_pd(9.); let mut r = _mm512_undefined_pd(); - _mm512_store_pd(&mut r as *mut _ as *mut f64, a); + unsafe { + _mm512_store_pd(&mut r as *mut _ as *mut f64, a); + } assert_eq_m512d(r, a); } diff --git a/library/stdarch/crates/core_arch/src/x86_64/fxsr.rs b/library/stdarch/crates/core_arch/src/x86_64/fxsr.rs index a24b44fb1f7e..28bf1951167a 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/fxsr.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/fxsr.rs @@ -77,12 +77,14 @@ mod tests { #[simd_test(enable = "fxsr")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri - unsafe fn test_fxsave64() { + fn test_fxsave64() { let mut a = FxsaveArea::new(); let mut b = FxsaveArea::new(); - fxsr::_fxsave64(a.ptr()); - fxsr::_fxrstor64(a.ptr()); - fxsr::_fxsave64(b.ptr()); + unsafe { + fxsr::_fxsave64(a.ptr()); + fxsr::_fxrstor64(a.ptr()); + fxsr::_fxsave64(b.ptr()); + } } } diff --git a/library/stdarch/crates/core_arch/src/x86_64/sse2.rs b/library/stdarch/crates/core_arch/src/x86_64/sse2.rs index b156af078a32..08dabf053d42 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/sse2.rs @@ -204,10 +204,12 @@ mod tests { // Miri cannot support this until it is clear how it fits in the Rust memory model // (non-temporal store) #[cfg_attr(miri, ignore)] - unsafe fn test_mm_stream_si64() { + fn test_mm_stream_si64() { let a: i64 = 7; let mut mem = boxed::Box::::new(-1); - _mm_stream_si64(ptr::addr_of_mut!(*mem), a); + unsafe { + _mm_stream_si64(ptr::addr_of_mut!(*mem), a); + } _mm_sfence(); assert_eq!(a, *mem); } diff --git a/library/stdarch/crates/core_arch/src/x86_64/xsave.rs b/library/stdarch/crates/core_arch/src/x86_64/xsave.rs index fa1454a822e3..30a7123315e5 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/xsave.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/xsave.rs @@ -132,37 +132,43 @@ mod tests { #[simd_test(enable = "xsave")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri - unsafe fn test_xsave64() { + fn test_xsave64() { let m = 0xFFFFFFFFFFFFFFFF_u64; //< all registers let mut a = XsaveArea::new(); let mut b = XsaveArea::new(); - _xsave64(a.ptr(), m); - _xrstor64(a.ptr(), m); - _xsave64(b.ptr(), m); + unsafe { + _xsave64(a.ptr(), m); + _xrstor64(a.ptr(), m); + _xsave64(b.ptr(), m); + } } #[simd_test(enable = "xsave,xsaveopt")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri - unsafe fn test_xsaveopt64() { + fn test_xsaveopt64() { let m = 0xFFFFFFFFFFFFFFFF_u64; //< all registers let mut a = XsaveArea::new(); let mut b = XsaveArea::new(); - _xsaveopt64(a.ptr(), m); - _xrstor64(a.ptr(), m); - _xsaveopt64(b.ptr(), m); + unsafe { + _xsaveopt64(a.ptr(), m); + _xrstor64(a.ptr(), m); + _xsaveopt64(b.ptr(), m); + } } #[simd_test(enable = "xsave,xsavec")] #[cfg_attr(miri, ignore)] // Register saving/restoring is not supported in Miri - unsafe fn test_xsavec64() { + fn test_xsavec64() { let m = 0xFFFFFFFFFFFFFFFF_u64; //< all registers let mut a = XsaveArea::new(); let mut b = XsaveArea::new(); - _xsavec64(a.ptr(), m); - _xrstor64(a.ptr(), m); - _xsavec64(b.ptr(), m); + unsafe { + _xsavec64(a.ptr(), m); + _xrstor64(a.ptr(), m); + _xsavec64(b.ptr(), m); + } } } From bbdba48aeb9029b0cf95ce3d6b7d417ce2be3860 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 7 Jan 2026 00:03:46 +0100 Subject: [PATCH 1687/3801] Update tidy check for triagebot path mentions with glob support --- Cargo.lock | 1 + src/tools/tidy/Cargo.toml | 1 + src/tools/tidy/src/triagebot.rs | 35 ++++++++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 470b38d5a91c..427e93e56cd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5658,6 +5658,7 @@ dependencies = [ "build_helper", "cargo_metadata 0.21.0", "fluent-syntax", + "globset", "ignore", "miropt-test-tools", "regex", diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 47b59543c59c..cbf27ea87a07 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -8,6 +8,7 @@ autobins = false build_helper = { path = "../../build_helper" } cargo_metadata = "0.21" regex = "1" +globset = "0.4.18" miropt-test-tools = { path = "../miropt-test-tools" } walkdir = "2" ignore = "0.4.18" diff --git a/src/tools/tidy/src/triagebot.rs b/src/tools/tidy/src/triagebot.rs index 01401c94d730..59cd9d80b07a 100644 --- a/src/tools/tidy/src/triagebot.rs +++ b/src/tools/tidy/src/triagebot.rs @@ -1,5 +1,6 @@ //! Tidy check to ensure paths mentioned in triagebot.toml exist in the project. +use std::collections::HashSet; use std::path::Path; use toml::Value; @@ -22,6 +23,9 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) { // Check [mentions."*"] sections, i.e. [mentions."compiler/rustc_const_eval/src/"] if let Some(Value::Table(mentions)) = config.get("mentions") { + let mut builder = globset::GlobSetBuilder::new(); + let mut glob_entries = Vec::new(); + for (entry_key, entry_val) in mentions.iter() { // If the type is set to something other than "filename", then this is not a path. if entry_val.get("type").is_some_and(|t| t.as_str().unwrap_or_default() != "filename") { @@ -33,8 +37,37 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) { let full_path = path.join(clean_path); if !full_path.exists() { + // The full-path doesn't exists, maybe it's a glob, let's add it to the glob set builder + // to be checked against all the file and directories in the repository. + builder.add(globset::Glob::new(&format!("{clean_path}*")).unwrap()); + glob_entries.push(clean_path.to_string()); + } + } + + let gs = builder.build().unwrap(); + + let mut found = HashSet::new(); + let mut matches = Vec::new(); + + // Walk the entire repository and match any entry against the remaining paths + for entry in ignore::WalkBuilder::new(path).build().flatten() { + // Strip the prefix as mentions entries are always relative to the repo + let entry_path = entry.path().strip_prefix(path).unwrap(); + + // Find the matches and add them to the found set + gs.matches_into(entry_path, &mut matches); + found.extend(matches.iter().copied()); + + // Early-exist if all the globs have been matched + if found.len() == glob_entries.len() { + break; + } + } + + for (i, clean_path) in glob_entries.iter().enumerate() { + if !found.contains(&i) { check.error(format!( - "triagebot.toml [mentions.*] contains path '{clean_path}' which doesn't exist" + "triagebot.toml [mentions.*] contains '{clean_path}' which doesn't match any file or directory in the repository" )); } } From f36b249f3fdca81c227075b7dafe61f3014ad508 Mon Sep 17 00:00:00 2001 From: Sergio Giro Date: Wed, 7 Jan 2026 17:29:11 +0000 Subject: [PATCH 1688/3801] missing_enforced_import_rename: Do not enforce for underscores --- clippy_lints/src/missing_enforced_import_rename.rs | 3 ++- tests/ui-toml/missing_enforced_import_rename/clippy.toml | 3 ++- .../conf_missing_enforced_import_rename.fixed | 1 + .../conf_missing_enforced_import_rename.rs | 1 + .../conf_missing_enforced_import_rename.stderr | 2 +- 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/missing_enforced_import_rename.rs b/clippy_lints/src/missing_enforced_import_rename.rs index eeea6dfd5f4b..5dd38cf059c2 100644 --- a/clippy_lints/src/missing_enforced_import_rename.rs +++ b/clippy_lints/src/missing_enforced_import_rename.rs @@ -82,7 +82,8 @@ impl LateLintPass<'_> for ImportRename { && let Some(import) = match snip.split_once(" as ") { None => Some(snip.as_str()), Some((import, rename)) => { - if rename.trim() == name.as_str() { + let trimmed_rename = rename.trim(); + if trimmed_rename == "_" || trimmed_rename == name.as_str() { None } else { Some(import.trim()) diff --git a/tests/ui-toml/missing_enforced_import_rename/clippy.toml b/tests/ui-toml/missing_enforced_import_rename/clippy.toml index 05ba822874d5..11af5b0a3306 100644 --- a/tests/ui-toml/missing_enforced_import_rename/clippy.toml +++ b/tests/ui-toml/missing_enforced_import_rename/clippy.toml @@ -6,5 +6,6 @@ enforced-import-renames = [ { path = "std::clone", rename = "foo" }, { path = "std::thread::sleep", rename = "thread_sleep" }, { path = "std::any::type_name", rename = "ident" }, - { path = "std::sync::Mutex", rename = "StdMutie" } + { path = "std::sync::Mutex", rename = "StdMutie" }, + { path = "std::io::Write", rename = "to_test_rename_as_underscore" } ] diff --git a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed index 3e882f496985..c96df2884b8d 100644 --- a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed +++ b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed @@ -15,6 +15,7 @@ use std::{ sync :: Mutex as StdMutie, //~^ missing_enforced_import_renames }; +use std::io::Write as _; fn main() { use std::collections::BTreeMap as Map; diff --git a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs index 32255af5117f..662e89157675 100644 --- a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs +++ b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs @@ -15,6 +15,7 @@ use std::{ sync :: Mutex, //~^ missing_enforced_import_renames }; +use std::io::Write as _; fn main() { use std::collections::BTreeMap as OopsWrongRename; diff --git a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr index 982b144eb872..139331d17619 100644 --- a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr +++ b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr @@ -32,7 +32,7 @@ LL | sync :: Mutex, | ^^^^^^^^^^^^^ help: try: `sync :: Mutex as StdMutie` error: this import should be renamed - --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:20:5 + --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:21:5 | LL | use std::collections::BTreeMap as OopsWrongRename; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `use std::collections::BTreeMap as Map` From ebd0151c81a39b358c6e6e17caf9458b0a4f78b4 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Wed, 7 Jan 2026 10:42:00 -0700 Subject: [PATCH 1689/3801] Fix the connect_error test on FreeBSD 15+ On FreeBSD 15, the error code returned in this situation changed. It's now ENETUNREACH. I think that error code is reasonable, and it's documented for connect(2), so we should expect that it might be returned. --- library/std/src/net/tcp/tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs index 7c7ef7b2f701..e4a30b80e3df 100644 --- a/library/std/src/net/tcp/tests.rs +++ b/library/std/src/net/tcp/tests.rs @@ -37,7 +37,8 @@ fn connect_error() { e.kind() == ErrorKind::ConnectionRefused || e.kind() == ErrorKind::InvalidInput || e.kind() == ErrorKind::AddrInUse - || e.kind() == ErrorKind::AddrNotAvailable, + || e.kind() == ErrorKind::AddrNotAvailable + || e.kind() == ErrorKind::NetworkUnreachable, "bad error: {} {:?}", e, e.kind() From 870626a390f267fc1a21e0712b6639bde3091c71 Mon Sep 17 00:00:00 2001 From: Immad Mir Date: Wed, 7 Jan 2026 23:10:44 +0530 Subject: [PATCH 1690/3801] Move issue-12660 to 'ui/cross-crate/ with a descriptive name Author: Immad Mir --- .../issue-12660-aux.rs => cross-crate/auxiliary/aux-12660.rs} | 0 .../cross-crate-unit-struct-reexport.rs} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/ui/{issues/auxiliary/issue-12660-aux.rs => cross-crate/auxiliary/aux-12660.rs} (100%) rename tests/ui/{issues/issue-12660.rs => cross-crate/cross-crate-unit-struct-reexport.rs} (82%) diff --git a/tests/ui/issues/auxiliary/issue-12660-aux.rs b/tests/ui/cross-crate/auxiliary/aux-12660.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-12660-aux.rs rename to tests/ui/cross-crate/auxiliary/aux-12660.rs diff --git a/tests/ui/issues/issue-12660.rs b/tests/ui/cross-crate/cross-crate-unit-struct-reexport.rs similarity index 82% rename from tests/ui/issues/issue-12660.rs rename to tests/ui/cross-crate/cross-crate-unit-struct-reexport.rs index 3aa3426519af..2d4e0c654ef3 100644 --- a/tests/ui/issues/issue-12660.rs +++ b/tests/ui/cross-crate/cross-crate-unit-struct-reexport.rs @@ -1,5 +1,5 @@ //@ run-pass -//@ aux-build:issue-12660-aux.rs +//@ aux-build:aux-12660.rs extern crate issue12660aux; From 5548a84c87c61697454c04b4762a5e55e5bab815 Mon Sep 17 00:00:00 2001 From: wr7 Date: Wed, 7 Jan 2026 10:57:20 -0700 Subject: [PATCH 1691/3801] Stabilize `slice::element_offset` --- library/core/src/slice/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 889fd4cd65df..1bca13b14ed4 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4809,8 +4809,6 @@ impl [T] { /// # Examples /// Basic usage: /// ``` - /// #![feature(substr_range)] - /// /// let nums: &[u32] = &[1, 7, 1, 1]; /// let num = &nums[2]; /// @@ -4819,8 +4817,6 @@ impl [T] { /// ``` /// Returning `None` with an unaligned element: /// ``` - /// #![feature(substr_range)] - /// /// let arr: &[[u32; 2]] = &[[0, 1], [2, 3]]; /// let flat_arr: &[u32] = arr.as_flattened(); /// @@ -4834,7 +4830,7 @@ impl [T] { /// assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1 /// ``` #[must_use] - #[unstable(feature = "substr_range", issue = "126769")] + #[stable(feature = "element_offset", since = "CURRENT_RUSTC_VERSION")] pub fn element_offset(&self, element: &T) -> Option { if T::IS_ZST { panic!("elements are zero-sized"); From ac505cc2cb98e625844f7c49b00c58dd90193d7c Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 20 Dec 2025 18:53:58 +0000 Subject: [PATCH 1692/3801] fix: `str_to_string` wrongly unmangled macros --- clippy_lints/src/strings.rs | 5 +++-- tests/ui/str_to_string.fixed | 14 ++++++++++++++ tests/ui/str_to_string.rs | 14 ++++++++++++++ tests/ui/str_to_string.stderr | 8 +++++++- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 1d0efa46a14c..609504ffc233 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::res::{MaybeDef, MaybeQPath}; -use clippy_utils::source::{snippet, snippet_with_applicability}; +use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context}; use clippy_utils::{ SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, method_calls, peel_blocks, sym, }; @@ -404,7 +404,8 @@ impl<'tcx> LateLintPass<'tcx> for StrToString { "`to_string()` called on a `&str`", |diag| { let mut applicability = Applicability::MachineApplicable; - let snippet = snippet_with_applicability(cx, self_arg.span, "..", &mut applicability); + let (snippet, _) = + snippet_with_context(cx, self_arg.span, expr.span.ctxt(), "..", &mut applicability); diag.span_suggestion(expr.span, "try", format!("{snippet}.to_owned()"), applicability); }, ); diff --git a/tests/ui/str_to_string.fixed b/tests/ui/str_to_string.fixed index 2941c4dbd33d..8713c4f9bc86 100644 --- a/tests/ui/str_to_string.fixed +++ b/tests/ui/str_to_string.fixed @@ -8,3 +8,17 @@ fn main() { msg.to_owned(); //~^ str_to_string } + +fn issue16271(key: &[u8]) { + macro_rules! t { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + } + }; + } + + let _value = t!(str::from_utf8(key)).to_owned(); + //~^ str_to_string +} diff --git a/tests/ui/str_to_string.rs b/tests/ui/str_to_string.rs index 4c4d2bb18062..b81759e1037b 100644 --- a/tests/ui/str_to_string.rs +++ b/tests/ui/str_to_string.rs @@ -8,3 +8,17 @@ fn main() { msg.to_string(); //~^ str_to_string } + +fn issue16271(key: &[u8]) { + macro_rules! t { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + } + }; + } + + let _value = t!(str::from_utf8(key)).to_string(); + //~^ str_to_string +} diff --git a/tests/ui/str_to_string.stderr b/tests/ui/str_to_string.stderr index cb7b6b48843a..c0a38c8ebe46 100644 --- a/tests/ui/str_to_string.stderr +++ b/tests/ui/str_to_string.stderr @@ -13,5 +13,11 @@ error: `to_string()` called on a `&str` LL | msg.to_string(); | ^^^^^^^^^^^^^^^ help: try: `msg.to_owned()` -error: aborting due to 2 previous errors +error: `to_string()` called on a `&str` + --> tests/ui/str_to_string.rs:22:18 + | +LL | let _value = t!(str::from_utf8(key)).to_string(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t!(str::from_utf8(key)).to_owned()` + +error: aborting due to 3 previous errors From 15fc6cfd1ca770891a10ea1eb2ddf2fe05bc2428 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 2 Jan 2026 05:20:23 +0000 Subject: [PATCH 1693/3801] fix: `string_from_utf8_as_bytes` wrongly unmangled macros --- clippy_lints/src/strings.rs | 3 ++- tests/ui/string_from_utf8_as_bytes.fixed | 10 ++++++++++ tests/ui/string_from_utf8_as_bytes.rs | 10 ++++++++++ tests/ui/string_from_utf8_as_bytes.stderr | 10 ++++++++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 609504ffc233..c0be724bcdee 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -273,6 +273,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { let string_expression = &expressions[0].0; let snippet_app = snippet_with_applicability(cx, string_expression.span, "..", &mut applicability); + let (right_snip, _) = snippet_with_context(cx, right.span, e.span.ctxt(), "..", &mut applicability); span_lint_and_sugg( cx, @@ -280,7 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { e.span, "calling a slice of `as_bytes()` with `from_utf8` should be not necessary", "try", - format!("Some(&{snippet_app}[{}])", snippet(cx, right.span, "..")), + format!("Some(&{snippet_app}[{right_snip}])"), applicability, ); } diff --git a/tests/ui/string_from_utf8_as_bytes.fixed b/tests/ui/string_from_utf8_as_bytes.fixed index 193217114d88..98fa3a4fcf70 100644 --- a/tests/ui/string_from_utf8_as_bytes.fixed +++ b/tests/ui/string_from_utf8_as_bytes.fixed @@ -1,6 +1,16 @@ #![warn(clippy::string_from_utf8_as_bytes)] +macro_rules! test_range { + ($start:expr, $end:expr) => { + $start..$end + }; +} + fn main() { let _ = Some(&"Hello World!"[6..11]); //~^ string_from_utf8_as_bytes + + let s = "Hello World!"; + let _ = Some(&s[test_range!(6, 11)]); + //~^ string_from_utf8_as_bytes } diff --git a/tests/ui/string_from_utf8_as_bytes.rs b/tests/ui/string_from_utf8_as_bytes.rs index 49beb19ee40f..6354d5376ad6 100644 --- a/tests/ui/string_from_utf8_as_bytes.rs +++ b/tests/ui/string_from_utf8_as_bytes.rs @@ -1,6 +1,16 @@ #![warn(clippy::string_from_utf8_as_bytes)] +macro_rules! test_range { + ($start:expr, $end:expr) => { + $start..$end + }; +} + fn main() { let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]); //~^ string_from_utf8_as_bytes + + let s = "Hello World!"; + let _ = std::str::from_utf8(&s.as_bytes()[test_range!(6, 11)]); + //~^ string_from_utf8_as_bytes } diff --git a/tests/ui/string_from_utf8_as_bytes.stderr b/tests/ui/string_from_utf8_as_bytes.stderr index 99c8d8ae4eab..bba9ec0caf19 100644 --- a/tests/ui/string_from_utf8_as_bytes.stderr +++ b/tests/ui/string_from_utf8_as_bytes.stderr @@ -1,5 +1,5 @@ error: calling a slice of `as_bytes()` with `from_utf8` should be not necessary - --> tests/ui/string_from_utf8_as_bytes.rs:4:13 + --> tests/ui/string_from_utf8_as_bytes.rs:10:13 | LL | let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&"Hello World!"[6..11])` @@ -7,5 +7,11 @@ LL | let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]); = note: `-D clippy::string-from-utf8-as-bytes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::string_from_utf8_as_bytes)]` -error: aborting due to 1 previous error +error: calling a slice of `as_bytes()` with `from_utf8` should be not necessary + --> tests/ui/string_from_utf8_as_bytes.rs:14:13 + | +LL | let _ = std::str::from_utf8(&s.as_bytes()[test_range!(6, 11)]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&s[test_range!(6, 11)])` + +error: aborting due to 2 previous errors From 2617622015f7294eead28ad6793ba04a3c16a643 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 2 Jan 2026 22:41:03 +0000 Subject: [PATCH 1694/3801] fix: `redundant_pattern_matching` wrongly unmangled macros --- .../src/matches/redundant_pattern_match.rs | 9 +++---- .../redundant_pattern_matching_result.fixed | 20 ++++++++++++++++ tests/ui/redundant_pattern_matching_result.rs | 24 +++++++++++++++++++ .../redundant_pattern_matching_result.stderr | 19 ++++++++++++++- 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index 897e7da5a967..bf0c0c4aec3c 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -267,13 +267,14 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op if let Ok(arms) = arms.try_into() // TODO: use `slice::as_array` once stabilized && let Some((good_method, maybe_guard)) = found_good_method(cx, arms) { - let span = is_expn_of(expr.span, sym::matches).unwrap_or(expr.span.to(op.span)); + let expr_span = is_expn_of(expr.span, sym::matches).unwrap_or(expr.span); + let result_expr = match &op.kind { ExprKind::AddrOf(_, _, borrowed) => borrowed, _ => op, }; let mut app = Applicability::MachineApplicable; - let receiver_sugg = Sugg::hir_with_applicability(cx, result_expr, "_", &mut app).maybe_paren(); + let receiver_sugg = Sugg::hir_with_context(cx, result_expr, expr_span.ctxt(), "_", &mut app).maybe_paren(); let mut sugg = format!("{receiver_sugg}.{good_method}"); if let Some(guard) = maybe_guard { @@ -296,14 +297,14 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op return; } - let guard = Sugg::hir(cx, guard, ".."); + let guard = Sugg::hir_with_context(cx, guard, expr_span.ctxt(), "..", &mut app); let _ = write!(sugg, " && {}", guard.maybe_paren()); } span_lint_and_sugg( cx, REDUNDANT_PATTERN_MATCHING, - span, + expr_span, format!("redundant pattern matching, consider using `{good_method}`"), "try", sugg, diff --git a/tests/ui/redundant_pattern_matching_result.fixed b/tests/ui/redundant_pattern_matching_result.fixed index 261d82fc35c8..8754d71aa629 100644 --- a/tests/ui/redundant_pattern_matching_result.fixed +++ b/tests/ui/redundant_pattern_matching_result.fixed @@ -165,3 +165,23 @@ fn issue10803() { // Don't lint let _ = matches!(x, Err(16)); } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Ok::($val) + }; + } + + let _ = test_expr!(42).is_ok(); + + macro_rules! test_guard { + ($val:expr) => { + ($val + 1) > 0 + }; + } + + let x: Result = Ok(42); + let _ = x.is_ok() && test_guard!(42); + //~^ redundant_pattern_matching +} diff --git a/tests/ui/redundant_pattern_matching_result.rs b/tests/ui/redundant_pattern_matching_result.rs index 6cae4cc4b6b0..b83b02588fb6 100644 --- a/tests/ui/redundant_pattern_matching_result.rs +++ b/tests/ui/redundant_pattern_matching_result.rs @@ -205,3 +205,27 @@ fn issue10803() { // Don't lint let _ = matches!(x, Err(16)); } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Ok::($val) + }; + } + + let _ = match test_expr!(42) { + //~^ redundant_pattern_matching + Ok(_) => true, + Err(_) => false, + }; + + macro_rules! test_guard { + ($val:expr) => { + ($val + 1) > 0 + }; + } + + let x: Result = Ok(42); + let _ = matches!(x, Ok(_) if test_guard!(42)); + //~^ redundant_pattern_matching +} diff --git a/tests/ui/redundant_pattern_matching_result.stderr b/tests/ui/redundant_pattern_matching_result.stderr index 7e7d27d07a7f..dda203b753c3 100644 --- a/tests/ui/redundant_pattern_matching_result.stderr +++ b/tests/ui/redundant_pattern_matching_result.stderr @@ -209,5 +209,22 @@ error: redundant pattern matching, consider using `is_err()` LL | let _ = matches!(x, Err(_)); | ^^^^^^^^^^^^^^^^^^^ help: try: `x.is_err()` -error: aborting due to 28 previous errors +error: redundant pattern matching, consider using `is_ok()` + --> tests/ui/redundant_pattern_matching_result.rs:216:13 + | +LL | let _ = match test_expr!(42) { + | _____________^ +LL | | +LL | | Ok(_) => true, +LL | | Err(_) => false, +LL | | }; + | |_____^ help: try: `test_expr!(42).is_ok()` + +error: redundant pattern matching, consider using `is_ok()` + --> tests/ui/redundant_pattern_matching_result.rs:229:13 + | +LL | let _ = matches!(x, Ok(_) if test_guard!(42)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_ok() && test_guard!(42)` + +error: aborting due to 30 previous errors From 02e4f853efb393887dea4f481352e107e8d07998 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 2 Jan 2026 22:58:07 +0000 Subject: [PATCH 1695/3801] fix: `unnecessary_fold` wrongly unmangled macros --- clippy_lints/src/methods/unnecessary_fold.rs | 7 ++++--- tests/ui/unnecessary_fold.fixed | 11 +++++++++++ tests/ui/unnecessary_fold.rs | 11 +++++++++++ tests/ui/unnecessary_fold.stderr | 10 +++++++++- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index 7802763ef74a..c3f031edff2e 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath, MaybeTypeckRes}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_blocks, strip_pat_refs}; use rustc_ast::ast; use rustc_data_structures::packed::Pu128; @@ -124,11 +124,12 @@ fn check_fold_with_op( let mut applicability = replacement.default_applicability(); let turbofish = replacement.maybe_turbofish(cx.typeck_results().expr_ty_adjusted(right_expr).peel_refs()); + let (r_snippet, _) = + snippet_with_context(cx, right_expr.span, expr.span.ctxt(), "EXPR", &mut applicability); let sugg = if replacement.has_args { format!( - "{method}{turbofish}(|{second_arg_ident}| {r})", + "{method}{turbofish}(|{second_arg_ident}| {r_snippet})", method = replacement.method_name, - r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), ) } else { format!("{method}{turbofish}()", method = replacement.method_name) diff --git a/tests/ui/unnecessary_fold.fixed b/tests/ui/unnecessary_fold.fixed index c3eeafbc39cd..d51359349cb9 100644 --- a/tests/ui/unnecessary_fold.fixed +++ b/tests/ui/unnecessary_fold.fixed @@ -178,4 +178,15 @@ fn issue10000() { } } +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($e:expr) => { + ($e + 1) > 2 + }; + } + + let _ = (0..3).any(|x| test_expr!(x)); + //~^ unnecessary_fold +} + fn main() {} diff --git a/tests/ui/unnecessary_fold.rs b/tests/ui/unnecessary_fold.rs index 6ab41a942625..c6eb7157ab12 100644 --- a/tests/ui/unnecessary_fold.rs +++ b/tests/ui/unnecessary_fold.rs @@ -178,4 +178,15 @@ fn issue10000() { } } +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($e:expr) => { + ($e + 1) > 2 + }; + } + + let _ = (0..3).fold(false, |acc: bool, x| acc || test_expr!(x)); + //~^ unnecessary_fold +} + fn main() {} diff --git a/tests/ui/unnecessary_fold.stderr b/tests/ui/unnecessary_fold.stderr index 025a2bd0048b..560427a681a9 100644 --- a/tests/ui/unnecessary_fold.stderr +++ b/tests/ui/unnecessary_fold.stderr @@ -203,5 +203,13 @@ error: this `.fold` can be written more succinctly using another method LL | (0..3).fold(1, |acc, x| acc * x) | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` -error: aborting due to 32 previous errors +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:188:20 + | +LL | let _ = (0..3).fold(false, |acc: bool, x| acc || test_expr!(x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| test_expr!(x))` + | + = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects + +error: aborting due to 33 previous errors From 0cfbe56d0497f2210314c4101adff6bc74ea97f7 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 2 Jan 2026 23:07:31 +0000 Subject: [PATCH 1696/3801] fix: `match_as_ref` wrongly unmangled macros --- clippy_lints/src/matches/match_as_ref.rs | 5 +++-- tests/ui/match_as_ref.fixed | 10 ++++++++++ tests/ui/match_as_ref.rs | 14 ++++++++++++++ tests/ui/match_as_ref.stderr | 23 ++++++++++++++++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/matches/match_as_ref.rs b/clippy_lints/src/matches/match_as_ref.rs index 795355f25f9e..12fe44ef2f13 100644 --- a/clippy_lints/src/matches/match_as_ref.rs +++ b/clippy_lints/src/matches/match_as_ref.rs @@ -46,6 +46,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: let cast = if input_ty == output_ty { "" } else { ".map(|x| x as _)" }; let mut applicability = Applicability::MachineApplicable; + let ctxt = expr.span.ctxt(); span_lint_and_then( cx, MATCH_AS_REF, @@ -59,7 +60,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: "use `Option::as_ref()`", format!( "{}.as_ref(){cast}", - Sugg::hir_with_applicability(cx, ex, "_", &mut applicability).maybe_paren(), + Sugg::hir_with_context(cx, ex, ctxt, "_", &mut applicability).maybe_paren(), ), applicability, ); @@ -69,7 +70,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: format!("use `Option::{method}()` directly"), format!( "{}.{method}(){cast}", - Sugg::hir_with_applicability(cx, ex, "_", &mut applicability).maybe_paren(), + Sugg::hir_with_context(cx, ex, ctxt, "_", &mut applicability).maybe_paren(), ), applicability, ); diff --git a/tests/ui/match_as_ref.fixed b/tests/ui/match_as_ref.fixed index 09a6ed169390..b1b8ffb885f5 100644 --- a/tests/ui/match_as_ref.fixed +++ b/tests/ui/match_as_ref.fixed @@ -90,3 +90,13 @@ fn issue15932() { let _: Option<&dyn std::fmt::Debug> = Some(0).as_ref().map(|x| x as _); } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Some($val) + }; + } + + let _: Option<&u32> = test_expr!(42).as_ref(); +} diff --git a/tests/ui/match_as_ref.rs b/tests/ui/match_as_ref.rs index 347b6d186887..3113167957d4 100644 --- a/tests/ui/match_as_ref.rs +++ b/tests/ui/match_as_ref.rs @@ -114,3 +114,17 @@ fn issue15932() { Some(ref mut v) => Some(v), }; } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Some($val) + }; + } + + let _: Option<&u32> = match test_expr!(42) { + //~^ match_as_ref + None => None, + Some(ref v) => Some(v), + }; +} diff --git a/tests/ui/match_as_ref.stderr b/tests/ui/match_as_ref.stderr index df06e358f296..3eab499fe409 100644 --- a/tests/ui/match_as_ref.stderr +++ b/tests/ui/match_as_ref.stderr @@ -127,5 +127,26 @@ LL - }; LL + let _: Option<&dyn std::fmt::Debug> = Some(0).as_ref().map(|x| x as _); | -error: aborting due to 6 previous errors +error: manual implementation of `Option::as_ref` + --> tests/ui/match_as_ref.rs:125:27 + | +LL | let _: Option<&u32> = match test_expr!(42) { + | ___________________________^ +LL | | +LL | | None => None, +LL | | Some(ref v) => Some(v), +LL | | }; + | |_____^ + | +help: use `Option::as_ref()` directly + | +LL - let _: Option<&u32> = match test_expr!(42) { +LL - +LL - None => None, +LL - Some(ref v) => Some(v), +LL - }; +LL + let _: Option<&u32> = test_expr!(42).as_ref(); + | + +error: aborting due to 7 previous errors From 9d08eb487bdac4927386bbfaaba71ef6bfd73ff1 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 2 Jan 2026 23:13:18 +0000 Subject: [PATCH 1697/3801] fix: `match_bool` wrongly unmangled macros --- clippy_lints/src/matches/match_bool.rs | 5 +++-- tests/ui/match_bool.fixed | 11 +++++++++++ tests/ui/match_bool.rs | 15 +++++++++++++++ tests/ui/match_bool.stderr | 12 +++++++++++- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/matches/match_bool.rs b/clippy_lints/src/matches/match_bool.rs index dc3457aa7a46..3e76231b6ef1 100644 --- a/clippy_lints/src/matches/match_bool.rs +++ b/clippy_lints/src/matches/match_bool.rs @@ -25,8 +25,9 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>] "`match` on a boolean expression", move |diag| { let mut app = Applicability::MachineApplicable; + let ctxt = expr.span.ctxt(); let test_sugg = if let PatKind::Expr(arm_bool) = arms[0].pat.kind { - let test = Sugg::hir_with_applicability(cx, scrutinee, "_", &mut app); + let test = Sugg::hir_with_context(cx, scrutinee, ctxt, "_", &mut app); if let PatExprKind::Lit { lit, .. } = arm_bool.kind { match &lit.node { LitKind::Bool(true) => Some(test), @@ -36,7 +37,7 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>] .map(|test| { if let Some(guard) = &arms[0] .guard - .map(|g| Sugg::hir_with_applicability(cx, g, "_", &mut app)) + .map(|g| Sugg::hir_with_context(cx, g, ctxt, "_", &mut app)) { test.and(guard) } else { diff --git a/tests/ui/match_bool.fixed b/tests/ui/match_bool.fixed index 876ae935afde..3d5d0a0d532c 100644 --- a/tests/ui/match_bool.fixed +++ b/tests/ui/match_bool.fixed @@ -74,4 +74,15 @@ fn issue15351() { } } +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + ($val + 1) > 0 + }; + } + + let x = 5; + if test_expr!(x) { 1 } else { 0 }; +} + fn main() {} diff --git a/tests/ui/match_bool.rs b/tests/ui/match_bool.rs index a134ad8346e2..4db0aedf3260 100644 --- a/tests/ui/match_bool.rs +++ b/tests/ui/match_bool.rs @@ -126,4 +126,19 @@ fn issue15351() { } } +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + ($val + 1) > 0 + }; + } + + let x = 5; + match test_expr!(x) { + //~^ match_bool + true => 1, + false => 0, + }; +} + fn main() {} diff --git a/tests/ui/match_bool.stderr b/tests/ui/match_bool.stderr index c05742e56339..223acd17aead 100644 --- a/tests/ui/match_bool.stderr +++ b/tests/ui/match_bool.stderr @@ -183,5 +183,15 @@ LL + break 'a; LL + } } | -error: aborting due to 13 previous errors +error: `match` on a boolean expression + --> tests/ui/match_bool.rs:137:5 + | +LL | / match test_expr!(x) { +LL | | +LL | | true => 1, +LL | | false => 0, +LL | | }; + | |_____^ help: consider using an `if`/`else` expression: `if test_expr!(x) { 1 } else { 0 }` + +error: aborting due to 14 previous errors From 908860ed106e1540741bf7d2cbd5877bc62ef3ea Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Fri, 2 Jan 2026 23:20:24 +0000 Subject: [PATCH 1698/3801] fix: `match_ok_err` wrongly unmangled macros --- clippy_lints/src/matches/manual_ok_err.rs | 2 +- tests/ui/manual_ok_err.fixed | 10 ++++++++++ tests/ui/manual_ok_err.rs | 14 ++++++++++++++ tests/ui/manual_ok_err.stderr | 13 ++++++++++++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/matches/manual_ok_err.rs b/clippy_lints/src/matches/manual_ok_err.rs index c35c3d1f62e6..1fc8bb9acce2 100644 --- a/clippy_lints/src/matches/manual_ok_err.rs +++ b/clippy_lints/src/matches/manual_ok_err.rs @@ -135,7 +135,7 @@ fn apply_lint(cx: &LateContext<'_>, expr: &Expr<'_>, scrutinee: &Expr<'_>, is_ok } else { Applicability::MachineApplicable }; - let scrut = Sugg::hir_with_applicability(cx, scrutinee, "..", &mut app).maybe_paren(); + let scrut = Sugg::hir_with_context(cx, scrutinee, expr.span.ctxt(), "..", &mut app).maybe_paren(); let scrutinee_ty = cx.typeck_results().expr_ty(scrutinee); let (_, _, mutability) = peel_and_count_ty_refs(scrutinee_ty); diff --git a/tests/ui/manual_ok_err.fixed b/tests/ui/manual_ok_err.fixed index 9b70ce0df43a..e22f91a0155f 100644 --- a/tests/ui/manual_ok_err.fixed +++ b/tests/ui/manual_ok_err.fixed @@ -127,3 +127,13 @@ mod issue15051 { result_with_ref_mut(x).as_mut().ok() } } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Ok::($val) + }; + } + + let _ = test_expr!(42).ok(); +} diff --git a/tests/ui/manual_ok_err.rs b/tests/ui/manual_ok_err.rs index dee904638245..c1355f0d4096 100644 --- a/tests/ui/manual_ok_err.rs +++ b/tests/ui/manual_ok_err.rs @@ -177,3 +177,17 @@ mod issue15051 { } } } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Ok::($val) + }; + } + + let _ = match test_expr!(42) { + //~^ manual_ok_err + Ok(v) => Some(v), + Err(_) => None, + }; +} diff --git a/tests/ui/manual_ok_err.stderr b/tests/ui/manual_ok_err.stderr index 448fbffc0509..0c2ed368eb97 100644 --- a/tests/ui/manual_ok_err.stderr +++ b/tests/ui/manual_ok_err.stderr @@ -141,5 +141,16 @@ LL | | Err(_) => None, LL | | } | |_________^ help: replace with: `result_with_ref_mut(x).as_mut().ok()` -error: aborting due to 12 previous errors +error: manual implementation of `ok` + --> tests/ui/manual_ok_err.rs:188:13 + | +LL | let _ = match test_expr!(42) { + | _____________^ +LL | | +LL | | Ok(v) => Some(v), +LL | | Err(_) => None, +LL | | }; + | |_____^ help: replace with: `test_expr!(42).ok()` + +error: aborting due to 13 previous errors From 8ccfc833a03dec7f84a01abc54b8e8a7d24bd09b Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 3 Jan 2026 01:59:18 +0000 Subject: [PATCH 1699/3801] fix: `for_kv_map` wrongly unmangled macros --- clippy_lints/src/loops/for_kv_map.rs | 24 +++++++++++++++++------- clippy_lints/src/loops/mod.rs | 2 +- tests/ui/for_kv_map.fixed | 17 +++++++++++++++++ tests/ui/for_kv_map.rs | 17 +++++++++++++++++ tests/ui/for_kv_map.stderr | 14 +++++++++++++- 5 files changed, 65 insertions(+), 9 deletions(-) diff --git a/clippy_lints/src/loops/for_kv_map.rs b/clippy_lints/src/loops/for_kv_map.rs index 39b2391c98ec..7fb8e51377a2 100644 --- a/clippy_lints/src/loops/for_kv_map.rs +++ b/clippy_lints/src/loops/for_kv_map.rs @@ -1,16 +1,22 @@ use super::FOR_KV_MAP; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeDef; -use clippy_utils::source::snippet; +use clippy_utils::source::{snippet_with_applicability, walk_span_to_context}; use clippy_utils::{pat_is_wild, sugg}; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::sym; +use rustc_span::{Span, sym}; /// Checks for the `FOR_KV_MAP` lint. -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>) { +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + span: Span, +) { let pat_span = pat.span; if let PatKind::Tuple(pat, _) = pat.kind @@ -34,21 +40,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx _ => arg, }; - if matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) { + if matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) + && let Some(arg_span) = walk_span_to_context(arg_span, span.ctxt()) + { span_lint_and_then( cx, FOR_KV_MAP, arg_span, format!("you seem to want to iterate on a map's {kind}s"), |diag| { - let map = sugg::Sugg::hir(cx, arg, "map"); + let mut applicability = Applicability::MachineApplicable; + let map = sugg::Sugg::hir_with_context(cx, arg, span.ctxt(), "map", &mut applicability); + let pat = snippet_with_applicability(cx, new_pat_span, kind, &mut applicability); diag.multipart_suggestion( "use the corresponding method", vec![ - (pat_span, snippet(cx, new_pat_span, kind).into_owned()), + (pat_span, pat.to_string()), (arg_span, format!("{}.{kind}s{mutbl}()", map.maybe_paren())), ], - Applicability::MachineApplicable, + applicability, ); }, ); diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index ddc783069385..83574cab6b67 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -943,7 +943,7 @@ impl Loops { explicit_counter_loop::check(cx, pat, arg, body, expr, label); } self.check_for_loop_arg(cx, pat, arg); - for_kv_map::check(cx, pat, arg, body); + for_kv_map::check(cx, pat, arg, body, span); mut_range_bound::check(cx, arg, body); single_element_loop::check(cx, pat, arg, body, expr); same_item_push::check(cx, pat, arg, body, expr, self.msrv); diff --git a/tests/ui/for_kv_map.fixed b/tests/ui/for_kv_map.fixed index 2a68b7443fbf..6ec4cb01ffd1 100644 --- a/tests/ui/for_kv_map.fixed +++ b/tests/ui/for_kv_map.fixed @@ -69,3 +69,20 @@ fn main() { let _v = v; } } + +fn wrongly_unmangled_macros() { + use std::collections::HashMap; + + macro_rules! test_map { + ($val:expr) => { + &*$val + }; + } + + let m: HashMap = HashMap::new(); + let wrapped = Rc::new(m); + for v in test_map!(wrapped).values() { + //~^ for_kv_map + let _v = v; + } +} diff --git a/tests/ui/for_kv_map.rs b/tests/ui/for_kv_map.rs index 485a97815e3c..19e907ff10a6 100644 --- a/tests/ui/for_kv_map.rs +++ b/tests/ui/for_kv_map.rs @@ -69,3 +69,20 @@ fn main() { let _v = v; } } + +fn wrongly_unmangled_macros() { + use std::collections::HashMap; + + macro_rules! test_map { + ($val:expr) => { + &*$val + }; + } + + let m: HashMap = HashMap::new(); + let wrapped = Rc::new(m); + for (_, v) in test_map!(wrapped) { + //~^ for_kv_map + let _v = v; + } +} diff --git a/tests/ui/for_kv_map.stderr b/tests/ui/for_kv_map.stderr index 0bd474a10682..5436592f2ab6 100644 --- a/tests/ui/for_kv_map.stderr +++ b/tests/ui/for_kv_map.stderr @@ -72,5 +72,17 @@ LL - 'label: for (k, _value) in rm { LL + 'label: for k in rm.keys() { | -error: aborting due to 6 previous errors +error: you seem to want to iterate on a map's values + --> tests/ui/for_kv_map.rs:84:19 + | +LL | for (_, v) in test_map!(wrapped) { + | ^^^^^^^^^^^^^^^^^^ + | +help: use the corresponding method + | +LL - for (_, v) in test_map!(wrapped) { +LL + for v in test_map!(wrapped).values() { + | + +error: aborting due to 7 previous errors From 209e4d7d853950574dab187d360d71a479ce2402 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 3 Jan 2026 02:40:38 +0000 Subject: [PATCH 1700/3801] fix: `question_mark` wrongly unmangled macros --- clippy_lints/src/question_mark.rs | 7 ++++--- tests/ui/question_mark.fixed | 17 ++++++++++++++++- tests/ui/question_mark.rs | 22 +++++++++++++++++++++- tests/ui/question_mark.stderr | 19 ++++++++++++++++++- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index 59d31f782bc3..e5fb3c0fa431 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -5,7 +5,7 @@ use clippy_config::types::MatchLintBehaviour; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{implements_trait, is_copy}; use clippy_utils::usage::local_used_after_expr; @@ -147,7 +147,8 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) { && !span_contains_cfg(cx, els.span) { let mut applicability = Applicability::MaybeIncorrect; - let init_expr_str = Sugg::hir_with_applicability(cx, init_expr, "..", &mut applicability).maybe_paren(); + let init_expr_str = + Sugg::hir_with_context(cx, init_expr, stmt.span.ctxt(), "..", &mut applicability).maybe_paren(); // Take care when binding is `ref` let sugg = if let PatKind::Binding( BindingMode(ByRef::Yes(_, ref_mutability), binding_mutability), @@ -295,7 +296,7 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex && (is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block)) { let mut applicability = Applicability::MachineApplicable; - let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability); + let receiver_str = snippet_with_context(cx, caller.span, expr.span.ctxt(), "..", &mut applicability).0; let by_ref = !cx.type_is_copy_modulo_regions(caller_ty) && !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)); let sugg = if let Some(else_inner) = r#else { diff --git a/tests/ui/question_mark.fixed b/tests/ui/question_mark.fixed index 2c5ee0245038..b8072932c4ea 100644 --- a/tests/ui/question_mark.fixed +++ b/tests/ui/question_mark.fixed @@ -1,5 +1,5 @@ #![feature(try_blocks)] -#![allow(clippy::unnecessary_wraps)] +#![allow(clippy::unnecessary_wraps, clippy::no_effect)] use std::sync::MutexGuard; @@ -500,3 +500,18 @@ mod issue14894 { Ok(()) } } + +fn wrongly_unmangled_macros() -> Option { + macro_rules! test_expr { + ($val:expr) => { + Some($val) + }; + } + + let x = test_expr!(42)?; + //~^^^ question_mark + Some(x); + + test_expr!(42)?; + test_expr!(42) +} diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs index b9ff9d1565b2..b320dcd4b0bc 100644 --- a/tests/ui/question_mark.rs +++ b/tests/ui/question_mark.rs @@ -1,5 +1,5 @@ #![feature(try_blocks)] -#![allow(clippy::unnecessary_wraps)] +#![allow(clippy::unnecessary_wraps, clippy::no_effect)] use std::sync::MutexGuard; @@ -615,3 +615,23 @@ mod issue14894 { Ok(()) } } + +fn wrongly_unmangled_macros() -> Option { + macro_rules! test_expr { + ($val:expr) => { + Some($val) + }; + } + + let Some(x) = test_expr!(42) else { + return None; + }; + //~^^^ question_mark + Some(x); + + if test_expr!(42).is_none() { + //~^ question_mark + return None; + } + test_expr!(42) +} diff --git a/tests/ui/question_mark.stderr b/tests/ui/question_mark.stderr index 9b2896328e66..d645c8830adc 100644 --- a/tests/ui/question_mark.stderr +++ b/tests/ui/question_mark.stderr @@ -333,5 +333,22 @@ LL | | return Err(reason); LL | | } | |_________^ help: replace it with: `result?;` -error: aborting due to 35 previous errors +error: this `let...else` may be rewritten with the `?` operator + --> tests/ui/question_mark.rs:626:5 + | +LL | / let Some(x) = test_expr!(42) else { +LL | | return None; +LL | | }; + | |______^ help: replace it with: `let x = test_expr!(42)?;` + +error: this block may be rewritten with the `?` operator + --> tests/ui/question_mark.rs:632:5 + | +LL | / if test_expr!(42).is_none() { +LL | | +LL | | return None; +LL | | } + | |_____^ help: replace it with: `test_expr!(42)?;` + +error: aborting due to 37 previous errors From 108436c6f98acc83b2a281465bc96ed505bbcb95 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sun, 4 Jan 2026 20:57:16 +0000 Subject: [PATCH 1701/3801] fix: `iter_kv_map` wrongly unmangled macros --- clippy_lints/src/methods/iter_kv_map.rs | 7 ++++--- tests/ui/iter_kv_map.fixed | 6 ++++++ tests/ui/iter_kv_map.rs | 6 ++++++ tests/ui/iter_kv_map.stderr | 8 +++++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index 16db8663941e..366bfaed73d4 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -2,7 +2,7 @@ use super::ITER_KV_MAP; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeDef; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::{pat_is_wild, sym}; use rustc_hir::{Body, Expr, ExprKind, PatKind}; use rustc_lint::LateContext; @@ -58,6 +58,8 @@ pub(super) fn check<'tcx>( applicability, ); } else { + let (body_snippet, _) = + snippet_with_context(cx, body_expr.span, expr.span.ctxt(), "..", &mut applicability); span_lint_and_sugg( cx, ITER_KV_MAP, @@ -65,9 +67,8 @@ pub(super) fn check<'tcx>( format!("iterating on a map's {replacement_kind}s"), "try", format!( - "{recv_snippet}.{into_prefix}{replacement_kind}s().map(|{}{bound_ident}| {})", + "{recv_snippet}.{into_prefix}{replacement_kind}s().map(|{}{bound_ident}| {body_snippet})", annotation.prefix_str(), - snippet_with_applicability(cx, body_expr.span, "/* body */", &mut applicability) ), applicability, ); diff --git a/tests/ui/iter_kv_map.fixed b/tests/ui/iter_kv_map.fixed index b18dda358877..189d76bc9431 100644 --- a/tests/ui/iter_kv_map.fixed +++ b/tests/ui/iter_kv_map.fixed @@ -189,3 +189,9 @@ fn issue14595() { let _ = map.as_ref().values().copied().collect::>(); //~^ iter_kv_map } + +fn issue16340() { + let hm: HashMap<&str, &str> = HashMap::new(); + let _ = hm.keys().map(|key| vec![key]); + //~^ iter_kv_map +} diff --git a/tests/ui/iter_kv_map.rs b/tests/ui/iter_kv_map.rs index 729e4e8a266c..cfc303447004 100644 --- a/tests/ui/iter_kv_map.rs +++ b/tests/ui/iter_kv_map.rs @@ -193,3 +193,9 @@ fn issue14595() { let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::>(); //~^ iter_kv_map } + +fn issue16340() { + let hm: HashMap<&str, &str> = HashMap::new(); + let _ = hm.iter().map(|(key, _)| vec![key]); + //~^ iter_kv_map +} diff --git a/tests/ui/iter_kv_map.stderr b/tests/ui/iter_kv_map.stderr index 8f73541f5033..866e69ea1922 100644 --- a/tests/ui/iter_kv_map.stderr +++ b/tests/ui/iter_kv_map.stderr @@ -269,5 +269,11 @@ error: iterating on a map's values LL | let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.as_ref().values()` -error: aborting due to 39 previous errors +error: iterating on a map's keys + --> tests/ui/iter_kv_map.rs:199:13 + | +LL | let _ = hm.iter().map(|(key, _)| vec![key]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hm.keys().map(|key| vec![key])` + +error: aborting due to 40 previous errors From 8c129e4219c21a0aafd2c8446ab57f0d76154ec7 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Mon, 5 Jan 2026 17:50:50 +0000 Subject: [PATCH 1702/3801] fix: `mutex_atomic` wrongly unmangled macros --- clippy_lints/src/mutex_atomic.rs | 2 +- tests/ui/mutex_atomic.fixed | 12 ++++++++++++ tests/ui/mutex_atomic.rs | 12 ++++++++++++ tests/ui/mutex_atomic.stderr | 10 +++++++++- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index 2fef8404f824..ad44d65b4d66 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -143,7 +143,7 @@ fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, ty_ascription: &T && new.ident.name == sym::new { let mut applicability = Applicability::MaybeIncorrect; - let arg = Sugg::hir_with_applicability(cx, arg, "_", &mut applicability); + let arg = Sugg::hir_with_context(cx, arg, expr.span.ctxt(), "_", &mut applicability); let mut suggs = vec![(expr.span, format!("std::sync::atomic::{atomic_name}::new({arg})"))]; match ty_ascription { TypeAscriptionKind::Required(ty_ascription) => { diff --git a/tests/ui/mutex_atomic.fixed b/tests/ui/mutex_atomic.fixed index e4218726019f..dc05d8a2c61f 100644 --- a/tests/ui/mutex_atomic.fixed +++ b/tests/ui/mutex_atomic.fixed @@ -65,3 +65,15 @@ fn issue13378() { let (funky_mtx) = std::sync::atomic::AtomicU64::new(0); //~^ mutex_integer } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + ($val > 0 && true) + }; + } + + let _ = std::sync::atomic::AtomicBool::new(test_expr!(1)); + //~^ mutex_atomic + // The suggestion should preserve the macro call: `AtomicBool::new(test_expr!(true))` +} diff --git a/tests/ui/mutex_atomic.rs b/tests/ui/mutex_atomic.rs index 95f2b135903f..33745f8fc5e1 100644 --- a/tests/ui/mutex_atomic.rs +++ b/tests/ui/mutex_atomic.rs @@ -65,3 +65,15 @@ fn issue13378() { let (funky_mtx): Mutex = Mutex::new(0); //~^ mutex_integer } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + ($val > 0 && true) + }; + } + + let _ = Mutex::new(test_expr!(1)); + //~^ mutex_atomic + // The suggestion should preserve the macro call: `AtomicBool::new(test_expr!(true))` +} diff --git a/tests/ui/mutex_atomic.stderr b/tests/ui/mutex_atomic.stderr index 0afc6d541dea..56d94035583c 100644 --- a/tests/ui/mutex_atomic.stderr +++ b/tests/ui/mutex_atomic.stderr @@ -130,5 +130,13 @@ LL - let (funky_mtx): Mutex = Mutex::new(0); LL + let (funky_mtx) = std::sync::atomic::AtomicU64::new(0); | -error: aborting due to 14 previous errors +error: using a `Mutex` where an atomic would do + --> tests/ui/mutex_atomic.rs:76:13 + | +LL | let _ = Mutex::new(test_expr!(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::sync::atomic::AtomicBool::new(test_expr!(1))` + | + = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>` + +error: aborting due to 15 previous errors From dc64aef1ed2ea86e42fe83f10e00c2f362dec114 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sun, 4 Jan 2026 19:10:10 +0900 Subject: [PATCH 1703/3801] fix: Properly lower `SelfOnly` predicates --- .../rust-analyzer/crates/hir-ty/src/lower.rs | 369 +++++++++++++----- .../crates/hir-ty/src/lower/path.rs | 34 +- .../crates/hir-ty/src/next_solver/interner.rs | 7 +- .../crates/hir-ty/src/next_solver/util.rs | 15 + .../hir-ty/src/tests/regression/new_solver.rs | 60 +++ 5 files changed, 373 insertions(+), 112 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 46ec554e0a65..9da32464c86f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -77,6 +77,7 @@ pub struct ImplTraits { #[derive(PartialEq, Eq, Debug, Hash)] pub struct ImplTrait { pub(crate) predicates: StoredClauses, + pub(crate) assoc_ty_bounds_start: u32, } pub type ImplTraitIdx = Idx; @@ -166,6 +167,12 @@ impl<'db> LifetimeElisionKind<'db> { } } +#[derive(Clone, Copy, PartialEq, Debug)] +pub(crate) enum GenericPredicateSource { + SelfOnly, + AssocTyBound, +} + #[derive(Debug)] pub struct TyLoweringContext<'db, 'a> { pub db: &'db dyn HirDatabase, @@ -465,10 +472,10 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { // this dance is to make sure the data is in the right // place even if we encounter more opaque types while // lowering the bounds - let idx = self - .impl_trait_mode - .opaque_type_data - .alloc(ImplTrait { predicates: Clauses::empty(interner).store() }); + let idx = self.impl_trait_mode.opaque_type_data.alloc(ImplTrait { + predicates: Clauses::empty(interner).store(), + assoc_ty_bounds_start: 0, + }); let impl_trait_id = origin.either( |f| ImplTraitId::ReturnTypeImplTrait(f, idx), @@ -608,7 +615,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { ignore_bindings: bool, generics: &Generics, predicate_filter: PredicateFilter, - ) -> impl Iterator> + use<'a, 'b, 'db> { + ) -> impl Iterator, GenericPredicateSource)> + use<'a, 'b, 'db> { match where_predicate { WherePredicate::ForLifetime { target, bound, .. } | WherePredicate::TypeBound { target, bound } => { @@ -634,8 +641,8 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { let self_ty = self.lower_ty(*target); Either::Left(Either::Right(self.lower_type_bound(bound, self_ty, ignore_bindings))) } - &WherePredicate::Lifetime { bound, target } => { - Either::Right(iter::once(Clause(Predicate::new( + &WherePredicate::Lifetime { bound, target } => Either::Right(iter::once(( + Clause(Predicate::new( self.interner, Binder::dummy(rustc_type_ir::PredicateKind::Clause( rustc_type_ir::ClauseKind::RegionOutlives(OutlivesPredicate( @@ -643,8 +650,9 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { self.lower_lifetime(target), )), )), - )))) - } + )), + GenericPredicateSource::SelfOnly, + ))), } .into_iter() } @@ -654,7 +662,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { bound: &'b TypeBound, self_ty: Ty<'db>, ignore_bindings: bool, - ) -> impl Iterator> + use<'b, 'a, 'db> { + ) -> impl Iterator, GenericPredicateSource)> + use<'b, 'a, 'db> { let interner = self.interner; let meta_sized = self.lang_items.MetaSized; let pointee_sized = self.lang_items.PointeeSized; @@ -712,7 +720,10 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { } TypeBound::Use(_) | TypeBound::Error => {} } - clause.into_iter().chain(assoc_bounds.into_iter().flatten()) + clause + .into_iter() + .map(|pred| (pred, GenericPredicateSource::SelfOnly)) + .chain(assoc_bounds.into_iter().flatten()) } fn lower_dyn_trait(&mut self, bounds: &[TypeBound]) -> Ty<'db> { @@ -732,7 +743,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { for b in bounds { let db = ctx.db; - ctx.lower_type_bound(b, dummy_self_ty, false).for_each(|b| { + ctx.lower_type_bound(b, dummy_self_ty, false).for_each(|(b, _)| { match b.kind().skip_binder() { rustc_type_ir::ClauseKind::Trait(t) => { let id = t.def_id(); @@ -990,35 +1001,49 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { rustc_type_ir::AliasTyKind::Opaque, AliasTy::new_from_args(interner, def_id, args), ); - let predicates = self.with_shifted_in(DebruijnIndex::from_u32(1), |ctx| { - let mut predicates = Vec::new(); - for b in bounds { - predicates.extend(ctx.lower_type_bound(b, self_ty, false)); - } + let (predicates, assoc_ty_bounds_start) = + self.with_shifted_in(DebruijnIndex::from_u32(1), |ctx| { + let mut predicates = Vec::new(); + let mut assoc_ty_bounds = Vec::new(); + for b in bounds { + for (pred, source) in ctx.lower_type_bound(b, self_ty, false) { + match source { + GenericPredicateSource::SelfOnly => predicates.push(pred), + GenericPredicateSource::AssocTyBound => assoc_ty_bounds.push(pred), + } + } + } - if !ctx.unsized_types.contains(&self_ty) { - let sized_trait = self.lang_items.Sized; - let sized_clause = sized_trait.map(|trait_id| { - let trait_ref = TraitRef::new_from_args( - interner, - trait_id.into(), - GenericArgs::new_from_slice(&[self_ty.into()]), - ); - Clause(Predicate::new( - interner, - Binder::dummy(rustc_type_ir::PredicateKind::Clause( - rustc_type_ir::ClauseKind::Trait(TraitPredicate { - trait_ref, - polarity: rustc_type_ir::PredicatePolarity::Positive, - }), - )), - )) - }); - predicates.extend(sized_clause); - } - predicates - }); - ImplTrait { predicates: Clauses::new_from_slice(&predicates).store() } + if !ctx.unsized_types.contains(&self_ty) { + let sized_trait = self.lang_items.Sized; + let sized_clause = sized_trait.map(|trait_id| { + let trait_ref = TraitRef::new_from_args( + interner, + trait_id.into(), + GenericArgs::new_from_slice(&[self_ty.into()]), + ); + Clause(Predicate::new( + interner, + Binder::dummy(rustc_type_ir::PredicateKind::Clause( + rustc_type_ir::ClauseKind::Trait(TraitPredicate { + trait_ref, + polarity: rustc_type_ir::PredicatePolarity::Positive, + }), + )), + )) + }); + predicates.extend(sized_clause); + } + + let assoc_ty_bounds_start = predicates.len() as u32; + predicates.extend(assoc_ty_bounds); + (predicates, assoc_ty_bounds_start) + }); + + ImplTrait { + predicates: Clauses::new_from_slice(&predicates).store(), + assoc_ty_bounds_start, + } } pub(crate) fn lower_lifetime(&mut self, lifetime: LifetimeRefId) -> Region<'db> { @@ -1139,6 +1164,31 @@ impl ImplTraitId { .expect("owner should have opaque type") .get_with(|it| it.impl_traits[idx].predicates.as_ref().as_slice()) } + + #[inline] + pub fn self_predicates<'db>( + self, + db: &'db dyn HirDatabase, + ) -> EarlyBinder<'db, &'db [Clause<'db>]> { + let (impl_traits, idx) = match self { + ImplTraitId::ReturnTypeImplTrait(owner, idx) => { + (ImplTraits::return_type_impl_traits(db, owner), idx) + } + ImplTraitId::TypeAliasImplTrait(owner, idx) => { + (ImplTraits::type_alias_impl_traits(db, owner), idx) + } + }; + let predicates = + impl_traits.as_deref().expect("owner should have opaque type").get_with(|it| { + let impl_trait = &it.impl_traits[idx]; + ( + impl_trait.predicates.as_ref().as_slice(), + impl_trait.assoc_ty_bounds_start as usize, + ) + }); + + predicates.map_bound(|(preds, len)| &preds[..len]) + } } impl InternedOpaqueTyId { @@ -1146,6 +1196,14 @@ impl InternedOpaqueTyId { pub fn predicates<'db>(self, db: &'db dyn HirDatabase) -> EarlyBinder<'db, &'db [Clause<'db>]> { self.loc(db).predicates(db) } + + #[inline] + pub fn self_predicates<'db>( + self, + db: &'db dyn HirDatabase, + ) -> EarlyBinder<'db, &'db [Clause<'db>]> { + self.loc(db).self_predicates(db) + } } #[salsa::tracked] @@ -1655,12 +1713,15 @@ pub(crate) fn generic_predicates_for_param<'db>( ctx.store = maybe_parent_generics.store(); for pred in maybe_parent_generics.where_predicates() { if predicate(pred, &mut ctx) { - predicates.extend(ctx.lower_where_predicate( - pred, - true, - maybe_parent_generics, - PredicateFilter::All, - )); + predicates.extend( + ctx.lower_where_predicate( + pred, + true, + maybe_parent_generics, + PredicateFilter::All, + ) + .map(|(pred, _)| pred), + ); } } } @@ -1696,21 +1757,44 @@ pub(crate) fn type_alias_bounds<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, ) -> EarlyBinder<'db, &'db [Clause<'db>]> { - type_alias_bounds_with_diagnostics(db, type_alias).0.map_bound(|it| it.as_slice()) + type_alias_bounds_with_diagnostics(db, type_alias).0.predicates.map_bound(|it| it.as_slice()) } -pub(crate) fn type_alias_bounds_with_diagnostics<'db>( +#[inline] +pub(crate) fn type_alias_self_bounds<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, -) -> (EarlyBinder<'db, Clauses<'db>>, Diagnostics) { - let (bounds, diags) = type_alias_bounds_with_diagnostics_query(db, type_alias); - return (bounds.get(), diags.clone()); +) -> EarlyBinder<'db, &'db [Clause<'db>]> { + let (TypeAliasBounds { predicates, assoc_ty_bounds_start }, _) = + type_alias_bounds_with_diagnostics(db, type_alias); + predicates.map_bound(|it| &it.as_slice()[..assoc_ty_bounds_start as usize]) +} + +#[derive(PartialEq, Eq, Debug, Hash)] +struct TypeAliasBounds { + predicates: T, + assoc_ty_bounds_start: u32, +} + +fn type_alias_bounds_with_diagnostics<'db>( + db: &'db dyn HirDatabase, + type_alias: TypeAliasId, +) -> (TypeAliasBounds>>, Diagnostics) { + let (TypeAliasBounds { predicates, assoc_ty_bounds_start }, diags) = + type_alias_bounds_with_diagnostics_query(db, type_alias); + return ( + TypeAliasBounds { + predicates: predicates.get(), + assoc_ty_bounds_start: *assoc_ty_bounds_start, + }, + diags.clone(), + ); #[salsa::tracked(returns(ref))] pub fn type_alias_bounds_with_diagnostics_query<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, - ) -> (StoredEarlyBinder, Diagnostics) { + ) -> (TypeAliasBounds>, Diagnostics) { let type_alias_data = db.type_alias_signature(type_alias); let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); let mut ctx = TyLoweringContext::new( @@ -1727,10 +1811,18 @@ pub(crate) fn type_alias_bounds_with_diagnostics<'db>( let interner_ty = Ty::new_projection_from_args(interner, def_id, item_args); let mut bounds = Vec::new(); + let mut assoc_ty_bounds = Vec::new(); for bound in &type_alias_data.bounds { - ctx.lower_type_bound(bound, interner_ty, false).for_each(|pred| { - bounds.push(pred); - }); + ctx.lower_type_bound(bound, interner_ty, false).for_each( + |(pred, source)| match source { + GenericPredicateSource::SelfOnly => { + bounds.push(pred); + } + GenericPredicateSource::AssocTyBound => { + assoc_ty_bounds.push(pred); + } + }, + ); } if !ctx.unsized_types.contains(&interner_ty) { @@ -1745,8 +1837,14 @@ pub(crate) fn type_alias_bounds_with_diagnostics<'db>( }; } + let assoc_ty_bounds_start = bounds.len() as u32; + bounds.extend(assoc_ty_bounds); + ( - StoredEarlyBinder::bind(Clauses::new_from_slice(&bounds).store()), + TypeAliasBounds { + predicates: StoredEarlyBinder::bind(Clauses::new_from_slice(&bounds).store()), + assoc_ty_bounds_start, + }, create_diagnostics(ctx.diagnostics), ) } @@ -1754,11 +1852,15 @@ pub(crate) fn type_alias_bounds_with_diagnostics<'db>( #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct GenericPredicates { - // The order is the following: first, if `parent_is_trait == true`, comes the implicit trait predicate for the - // parent. Then come the explicit predicates for the parent, then the explicit trait predicate for the child, + // The order is the following: first, if `parent_is_trait == true`, comes the implicit trait + // predicate for the parent. Then come the bounds of the associated types of the parents, + // then the explicit, self-only predicates for the parent, then the explicit, self-only trait + // predicate for the child, then the bounds of the associated types of the child, // then the implicit trait predicate for the child, if `is_trait` is `true`. predicates: StoredEarlyBinder, + parent_explicit_self_predicates_start: u32, own_predicates_start: u32, + own_assoc_ty_bounds_start: u32, is_trait: bool, parent_is_trait: bool, } @@ -1782,7 +1884,15 @@ impl GenericPredicates { pub(crate) fn from_explicit_own_predicates( predicates: StoredEarlyBinder, ) -> Self { - Self { predicates, own_predicates_start: 0, is_trait: false, parent_is_trait: false } + let len = predicates.get().skip_binder().len() as u32; + Self { + predicates, + parent_explicit_self_predicates_start: 0, + own_predicates_start: 0, + own_assoc_ty_bounds_start: len, + is_trait: false, + parent_is_trait: false, + } } #[inline] @@ -1814,6 +1924,14 @@ impl GenericPredicates { Self::query(db, def).explicit_predicates() } + #[inline] + pub fn query_explicit_implied<'db>( + db: &'db dyn HirDatabase, + def: GenericDefId, + ) -> EarlyBinder<'db, &'db [Clause<'db>]> { + Self::query(db, def).explicit_implied_predicates() + } + #[inline] pub fn all_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { self.predicates.get().map_bound(|it| it.as_slice()) @@ -1824,9 +1942,18 @@ impl GenericPredicates { self.predicates.get().map_bound(|it| &it.as_slice()[self.own_predicates_start as usize..]) } - /// Returns the predicates, minus the implicit `Self: Trait` predicate for a trait. + /// Returns the predicates, minus the implicit `Self: Trait` predicate and bounds of the + /// associated types for a trait. #[inline] pub fn explicit_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { + self.predicates.get().map_bound(|it| { + &it.as_slice()[self.parent_explicit_self_predicates_start as usize + ..self.own_assoc_ty_bounds_start as usize] + }) + } + + #[inline] + pub fn explicit_implied_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { self.predicates.get().map_bound(|it| { &it.as_slice()[usize::from(self.parent_is_trait)..it.len() - usize::from(self.is_trait)] }) @@ -1902,26 +2029,22 @@ where ); let sized_trait = ctx.lang_items.Sized; - let mut predicates = Vec::new(); + // We need to lower parents and self separately - see the comment below lowering of implicit + // `Sized` predicates for why. + let mut own_predicates = Vec::new(); + let mut parent_predicates = Vec::new(); + let mut own_assoc_ty_bounds = Vec::new(); + let mut parent_assoc_ty_bounds = Vec::new(); let all_generics = std::iter::successors(Some(&generics), |generics| generics.parent_generics()) .collect::>(); - let mut is_trait = false; - let mut parent_is_trait = false; - if all_generics.len() > 1 { - add_implicit_trait_predicate( - interner, - all_generics.last().unwrap().def(), - predicate_filter, - &mut predicates, - &mut parent_is_trait, - ); - } - // We need to lower parent predicates first - see the comment below lowering of implicit `Sized` predicates - // for why. - let mut own_predicates_start = 0; + let own_implicit_trait_predicate = implicit_trait_predicate(interner, def, predicate_filter); + let parent_implicit_trait_predicate = if all_generics.len() > 1 { + implicit_trait_predicate(interner, all_generics.last().unwrap().def(), predicate_filter) + } else { + None + }; for &maybe_parent_generics in all_generics.iter().rev() { - let current_def_predicates_start = predicates.len(); // Collect only diagnostics from the child, not including parents. ctx.diagnostics.clear(); @@ -1929,15 +2052,37 @@ where ctx.store = maybe_parent_generics.store(); for pred in maybe_parent_generics.where_predicates() { tracing::debug!(?pred); - predicates.extend(ctx.lower_where_predicate( - pred, - false, - maybe_parent_generics, - predicate_filter, - )); + for (pred, source) in + ctx.lower_where_predicate(pred, false, maybe_parent_generics, predicate_filter) + { + match source { + GenericPredicateSource::SelfOnly => { + if maybe_parent_generics.def() == def { + own_predicates.push(pred); + } else { + parent_predicates.push(pred); + } + } + GenericPredicateSource::AssocTyBound => { + if maybe_parent_generics.def() == def { + own_assoc_ty_bounds.push(pred); + } else { + parent_assoc_ty_bounds.push(pred); + } + } + } + } } - push_const_arg_has_type_predicates(db, &mut predicates, maybe_parent_generics); + if maybe_parent_generics.def() == def { + push_const_arg_has_type_predicates(db, &mut own_predicates, maybe_parent_generics); + } else { + push_const_arg_has_type_predicates( + db, + &mut parent_predicates, + maybe_parent_generics, + ); + } if let Some(sized_trait) = sized_trait { let mut add_sized_clause = |param_idx, param_id, param_data| { @@ -1971,7 +2116,11 @@ where }), )), )); - predicates.push(clause); + if maybe_parent_generics.def() == def { + own_predicates.push(clause); + } else { + parent_predicates.push(clause); + } }; let parent_params_len = maybe_parent_generics.len_parent(); maybe_parent_generics.iter_self().enumerate().for_each( @@ -1990,30 +2139,55 @@ where // predicates before lowering the child, as a child cannot define a `?Sized` predicate for its parent. // But we do have to lower the parent first. } - - if maybe_parent_generics.def() == def { - own_predicates_start = current_def_predicates_start as u32; - } } - add_implicit_trait_predicate(interner, def, predicate_filter, &mut predicates, &mut is_trait); - let diagnostics = create_diagnostics(ctx.diagnostics); + + // The order is: + // + // 1. parent implicit trait pred + // 2. parent assoc bounds + // 3. parent self only preds + // 4. own self only preds + // 5. own assoc ty bounds + // 6. own implicit trait pred + // + // The purpose of this is to index the slice of the followings, without making extra `Vec`s or + // iterators: + // - explicit self only predicates, of own or own + self + // - explicit predicates, of own or own + self + let predicates = parent_implicit_trait_predicate + .iter() + .chain(parent_assoc_ty_bounds.iter()) + .chain(parent_predicates.iter()) + .chain(own_predicates.iter()) + .chain(own_assoc_ty_bounds.iter()) + .chain(own_implicit_trait_predicate.iter()) + .copied() + .collect::>(); + let parent_is_trait = parent_implicit_trait_predicate.is_some(); + let is_trait = own_implicit_trait_predicate.is_some(); + let parent_explicit_self_predicates_start = + parent_is_trait as u32 + parent_assoc_ty_bounds.len() as u32; + let own_predicates_start = + parent_explicit_self_predicates_start + parent_predicates.len() as u32; + let own_assoc_ty_bounds_start = own_predicates_start + own_predicates.len() as u32; + let predicates = GenericPredicates { + parent_explicit_self_predicates_start, own_predicates_start, + own_assoc_ty_bounds_start, is_trait, parent_is_trait, predicates: StoredEarlyBinder::bind(Clauses::new_from_slice(&predicates).store()), }; return (predicates, diagnostics); - fn add_implicit_trait_predicate<'db>( + fn implicit_trait_predicate<'db>( interner: DbInterner<'db>, def: GenericDefId, predicate_filter: PredicateFilter, - predicates: &mut Vec>, - set_is_trait: &mut bool, - ) { + ) -> Option> { // For traits, add `Self: Trait` predicate. This is // not part of the predicates that a user writes, but it // is something that one must prove in order to invoke a @@ -2029,8 +2203,9 @@ where if let GenericDefId::TraitId(def_id) = def && predicate_filter == PredicateFilter::All { - *set_is_trait = true; - predicates.push(TraitRef::identity(interner, def_id.into()).upcast(interner)); + Some(TraitRef::identity(interner, def_id.into()).upcast(interner)) + } else { + None } } } @@ -2327,7 +2502,7 @@ pub(crate) fn associated_ty_item_bounds<'db>( let mut bounds = Vec::new(); for bound in &type_alias_data.bounds { - ctx.lower_type_bound(bound, self_ty, false).for_each(|pred| { + ctx.lower_type_bound(bound, self_ty, false).for_each(|(pred, _)| { if let Some(bound) = pred .kind() .map_bound(|c| match c { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index a79f547c2a44..b77aeab62d15 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs @@ -32,7 +32,8 @@ use crate::{ db::HirDatabase, generics::{Generics, generics}, lower::{ - LifetimeElisionKind, PathDiagnosticCallbackData, named_associated_type_shorthand_candidates, + GenericPredicateSource, LifetimeElisionKind, PathDiagnosticCallbackData, + named_associated_type_shorthand_candidates, }, next_solver::{ Binder, Clause, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Predicate, @@ -853,7 +854,8 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { pub(super) fn assoc_type_bindings_from_type_bound<'c>( mut self, trait_ref: TraitRef<'db>, - ) -> Option> + use<'a, 'b, 'c, 'db>> { + ) -> Option, GenericPredicateSource)> + use<'a, 'b, 'c, 'db>> + { let interner = self.ctx.interner; self.current_or_prev_segment.args_and_bindings.map(|args_and_bindings| { args_and_bindings.bindings.iter().enumerate().flat_map(move |(binding_idx, binding)| { @@ -921,21 +923,29 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { ), )), )); - predicates.push(pred); + predicates.push((pred, GenericPredicateSource::SelfOnly)); } } }) } for bound in binding.bounds.iter() { - predicates.extend(self.ctx.lower_type_bound( - bound, - Ty::new_alias( - self.ctx.interner, - AliasTyKind::Projection, - AliasTy::new_from_args(self.ctx.interner, associated_ty.into(), args), - ), - false, - )); + predicates.extend( + self.ctx + .lower_type_bound( + bound, + Ty::new_alias( + self.ctx.interner, + AliasTyKind::Projection, + AliasTy::new_from_args( + self.ctx.interner, + associated_ty.into(), + args, + ), + ), + false, + ) + .map(|(pred, _)| (pred, GenericPredicateSource::AssocTyBound)), + ); } predicates }) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 2a3df1d32a30..e17bdac68cdd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -41,7 +41,8 @@ use crate::{ AdtIdWrapper, AnyImplId, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper, CoroutineIdWrapper, Ctor, FnSig, FxIndexMap, GeneralConstIdWrapper, OpaqueTypeKey, RegionAssumptions, SimplifiedType, SolverContext, SolverDefIds, TraitIdWrapper, - TypeAliasIdWrapper, UnevaluatedConst, util::explicit_item_bounds, + TypeAliasIdWrapper, UnevaluatedConst, + util::{explicit_item_bounds, explicit_item_self_bounds}, }, }; @@ -1421,7 +1422,7 @@ impl<'db> Interner for DbInterner<'db> { self, def_id: Self::DefId, ) -> EarlyBinder> { - explicit_item_bounds(self, def_id) + explicit_item_self_bounds(self, def_id) .map_bound(|bounds| elaborate(self, bounds).filter_only_self()) } @@ -1500,7 +1501,7 @@ impl<'db> Interner for DbInterner<'db> { } } - predicates_of(self.db, def_id).explicit_predicates().map_bound(|predicates| { + predicates_of(self.db, def_id).explicit_implied_predicates().map_bound(|predicates| { predicates .iter() .copied() diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs index 34ecfed08f29..9a1b476976e3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/util.rs @@ -455,6 +455,21 @@ pub fn explicit_item_bounds<'db>( clauses.map_bound(|clauses| clauses.iter().copied()) } +pub fn explicit_item_self_bounds<'db>( + interner: DbInterner<'db>, + def_id: SolverDefId, +) -> EarlyBinder<'db, impl DoubleEndedIterator> + ExactSizeIterator> { + let db = interner.db(); + let clauses = match def_id { + SolverDefId::TypeAliasId(type_alias) => { + crate::lower::type_alias_self_bounds(db, type_alias) + } + SolverDefId::InternedOpaqueTyId(id) => id.self_predicates(db), + _ => panic!("Unexpected GenericDefId"), + }; + clauses.map_bound(|clauses| clauses.iter().copied()) +} + pub struct ContainsTypeErrors; impl<'db> TypeVisitor> for ContainsTypeErrors { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs index a4554673cdd5..be6ab23ad761 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs @@ -750,3 +750,63 @@ fn main() { "#]], ); } + +#[test] +fn regression_19339() { + check_infer( + r#" +trait Bar { + type Baz; + + fn baz(&self) -> Self::Baz; +} + +trait Foo { + type Bar; + + fn bar(&self) -> Self::Bar; +} + +trait FooFactory { + type Output: Foo>; + + fn foo(&self) -> Self::Output; + + fn foo_rpit(&self) -> impl Foo>; +} + +fn test1(foo: impl Foo>) { + let baz = foo.bar().baz(); +} + +fn test2(factory: T) { + let baz = factory.foo().bar().baz(); + let baz = factory.foo_rpit().bar().baz(); +} +"#, + expect![[r#" + 39..43 'self': &'? Self + 101..105 'self': &'? Self + 198..202 'self': &'? Self + 239..243 'self': &'? Self + 290..293 'foo': impl Foo + ?Sized + 325..359 '{ ...z(); }': () + 335..338 'baz': u8 + 341..344 'foo': impl Foo + ?Sized + 341..350 'foo.bar()': impl Bar + 341..356 'foo.bar().baz()': u8 + 385..392 'factory': T + 397..487 '{ ...z(); }': () + 407..410 'baz': u8 + 413..420 'factory': T + 413..426 'factory.foo()': ::Output + 413..432 'factor....bar()': <::Output as Foo>::Bar + 413..438 'factor....baz()': u8 + 448..451 'baz': u8 + 454..461 'factory': T + 454..472 'factor...rpit()': impl Foo + Bar + ?Sized + 454..478 'factor....bar()': + ?Sized as Foo>::Bar + 454..484 'factor....baz()': u8 + "#]], + ); +} From 6750919d47f8150bf53381981150b8af8571d575 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 7 Jan 2026 19:36:10 +0100 Subject: [PATCH 1704/3801] add `pmaddwd` shim --- src/tools/miri/src/shims/x86/avx2.rs | 30 +------- src/tools/miri/src/shims/x86/avx512.rs | 11 ++- src/tools/miri/src/shims/x86/mod.rs | 46 ++++++++++++ src/tools/miri/src/shims/x86/sse2.rs | 30 +------- .../pass/shims/x86/intrinsics-x86-avx512.rs | 71 +++++++++++++++++++ 5 files changed, 131 insertions(+), 57 deletions(-) diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 97b9f649c158..7d8e52db73d6 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -6,7 +6,7 @@ use rustc_target::callconv::FnAbi; use super::{ ShiftOp, horizontal_bin_op, mpsadbw, packssdw, packsswb, packusdw, packuswb, permute, pmaddbw, - pmulhrsw, psadbw, pshufb, psign, shift_simd_by_scalar, + pmaddwd, pmulhrsw, psadbw, pshufb, psign, shift_simd_by_scalar, }; use crate::*; @@ -232,33 +232,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [left, right] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; - - assert_eq!(left_len, right_len); - assert_eq!(dest_len.strict_mul(2), left_len); - - for i in 0..dest_len { - let j1 = i.strict_mul(2); - let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; - let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; - - let j2 = j1.strict_add(1); - let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; - let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; - - let dest = this.project_index(&dest, i)?; - - // Multiplications are i16*i16->i32, which will not overflow. - let mul1 = i32::from(left1).strict_mul(right1.into()); - let mul2 = i32::from(left2).strict_mul(right2.into()); - // However, this addition can overflow in the most extreme case - // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 - let res = mul1.wrapping_add(mul2); - - this.write_scalar(Scalar::from_i32(res), &dest)?; - } + pmaddwd(this, left, right, dest)?; } _ => return interp_ok(EmulateItemResult::NotSupported), } diff --git a/src/tools/miri/src/shims/x86/avx512.rs b/src/tools/miri/src/shims/x86/avx512.rs index 0466ba1bd6c0..9231fc446919 100644 --- a/src/tools/miri/src/shims/x86/avx512.rs +++ b/src/tools/miri/src/shims/x86/avx512.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use super::{permute, pmaddbw, psadbw, pshufb}; +use super::{permute, pmaddbw, pmaddwd, psadbw, pshufb}; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -88,6 +88,15 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { psadbw(this, left, right, dest)? } + // Used to implement the _mm512_madd_epi16 function. + "pmaddw.d.512" => { + this.expect_target_feature_for_intrinsic(link_name, "avx512bw")?; + + let [left, right] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + pmaddwd(this, left, right, dest)?; + } // Used to implement the _mm512_maddubs_epi16 function. "pmaddubs.w.512" => { let [left, right] = diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index a5164cc87ab4..dc0d8d48ac9b 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -964,6 +964,52 @@ fn psadbw<'tcx>( interp_ok(()) } +/// Multiply packed signed 16-bit integers in `left` and `right`, producing intermediate signed 32-bit integers. +/// Horizontally add adjacent pairs of intermediate 32-bit integers, and pack the results in `dest`. +/// +/// +/// +/// +fn pmaddwd<'tcx>( + ecx: &mut crate::MiriInterpCx<'tcx>, + left: &OpTy<'tcx>, + right: &OpTy<'tcx>, + dest: &MPlaceTy<'tcx>, +) -> InterpResult<'tcx, ()> { + let (left, left_len) = ecx.project_to_simd(left)?; + let (right, right_len) = ecx.project_to_simd(right)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; + + // fn pmaddwd(a: i16x8, b: i16x8) -> i32x4; + // fn pmaddwd(a: i16x16, b: i16x16) -> i32x8; + // fn vpmaddwd(a: i16x32, b: i16x32) -> i32x16; + assert_eq!(left_len, right_len); + assert_eq!(dest_len.strict_mul(2), left_len); + + for i in 0..dest_len { + let j1 = i.strict_mul(2); + let left1 = ecx.read_scalar(&ecx.project_index(&left, j1)?)?.to_i16()?; + let right1 = ecx.read_scalar(&ecx.project_index(&right, j1)?)?.to_i16()?; + + let j2 = j1.strict_add(1); + let left2 = ecx.read_scalar(&ecx.project_index(&left, j2)?)?.to_i16()?; + let right2 = ecx.read_scalar(&ecx.project_index(&right, j2)?)?.to_i16()?; + + let dest = ecx.project_index(&dest, i)?; + + // Multiplications are i16*i16->i32, which will not overflow. + let mul1 = i32::from(left1).strict_mul(right1.into()); + let mul2 = i32::from(left2).strict_mul(right2.into()); + // However, this addition can overflow in the most extreme case + // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 + let res = mul1.wrapping_add(mul2); + + ecx.write_scalar(Scalar::from_i32(res), &dest)?; + } + + interp_ok(()) +} + /// Multiplies packed 8-bit unsigned integers from `left` and packed /// signed 8-bit integers from `right` into 16-bit signed integers. Then, /// the saturating sum of the products with indices `2*i` and `2*i+1` diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 3fbab9ba789e..f712814a5eda 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -6,7 +6,7 @@ use rustc_target::callconv::FnAbi; use super::{ FloatBinOp, ShiftOp, bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int, - packssdw, packsswb, packuswb, psadbw, shift_simd_by_scalar, + packssdw, packsswb, packuswb, pmaddwd, psadbw, shift_simd_by_scalar, }; use crate::*; @@ -286,33 +286,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [left, right] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; - - assert_eq!(left_len, right_len); - assert_eq!(dest_len.strict_mul(2), left_len); - - for i in 0..dest_len { - let j1 = i.strict_mul(2); - let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; - let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; - - let j2 = j1.strict_add(1); - let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; - let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; - - let dest = this.project_index(&dest, i)?; - - // Multiplications are i16*i16->i32, which will not overflow. - let mul1 = i32::from(left1).strict_mul(right1.into()); - let mul2 = i32::from(left2).strict_mul(right2.into()); - // However, this addition can overflow in the most extreme case - // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 - let res = mul1.wrapping_add(mul2); - - this.write_scalar(Scalar::from_i32(res), &dest)?; - } + pmaddwd(this, left, right, dest)?; } _ => return interp_ok(EmulateItemResult::NotSupported), } diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs index 42acb6c3fb37..7cc554ef5a3c 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs @@ -100,6 +100,77 @@ unsafe fn test_avx512() { } test_mm512_maddubs_epi16(); + #[target_feature(enable = "avx512bw")] + unsafe fn test_mm512_madd_epi16() { + // Input pairs + // + // - `i16::MIN * i16::MIN + i16::MIN * i16::MIN`: the 32-bit addition overflows + // - `i16::MAX * i16::MAX + i16::MAX * i16::MAX`: check that widening happens before + // arithmetic + // - `i16::MIN * i16::MAX + i16::MAX * i16::MIN`: check that large negative values are + // handled correctly + // - `3 * 1 + 4 * 2`: A sanity check, the result should be 14. + + #[rustfmt::skip] + let a = _mm512_set_epi16( + i16::MIN, i16::MIN, + i16::MAX, i16::MAX, + i16::MIN, i16::MAX, + 3, 1, + + i16::MIN, i16::MIN, + i16::MAX, i16::MAX, + i16::MIN, i16::MAX, + 3, 1, + + i16::MIN, i16::MIN, + i16::MAX, i16::MAX, + i16::MIN, i16::MAX, + 3, 1, + + i16::MIN, i16::MIN, + i16::MAX, i16::MAX, + i16::MIN, i16::MAX, + 3, 1, + ); + + #[rustfmt::skip] + let b = _mm512_set_epi16( + i16::MIN, i16::MIN, + i16::MAX, i16::MAX, + i16::MAX, i16::MIN, + 4, 2, + + i16::MIN, i16::MIN, + i16::MAX, i16::MAX, + i16::MAX, i16::MIN, + 4, 2, + + i16::MIN, i16::MIN, + i16::MAX, i16::MAX, + i16::MAX, i16::MIN, + 4, 2, + + i16::MIN, i16::MIN, + i16::MAX, i16::MAX, + i16::MAX, i16::MIN, + 4, 2, + ); + + let r = _mm512_madd_epi16(a, b); + + #[rustfmt::skip] + let e = _mm512_set_epi32( + i32::MIN, 2_147_352_578, -2_147_418_112, 14, + i32::MIN, 2_147_352_578, -2_147_418_112, 14, + i32::MIN, 2_147_352_578, -2_147_418_112, 14, + i32::MIN, 2_147_352_578, -2_147_418_112, 14, + ); + + assert_eq_m512i(r, e); + } + test_mm512_madd_epi16(); + #[target_feature(enable = "avx512f")] unsafe fn test_mm512_permutexvar_epi32() { let a = _mm512_set_epi32( From 93f2e80f4a885dd4eacce00e7a52aeeb41b7ce70 Mon Sep 17 00:00:00 2001 From: Farid Zakaria Date: Wed, 7 Jan 2026 11:25:17 -0800 Subject: [PATCH 1705/3801] Add -Z large-data-threshold This flag allows specifying the threshold size for placing static data in large data sections when using the medium code model on x86-64. When using -Ccode-model=medium, data smaller than this threshold uses RIP-relative addressing (32-bit offsets), while larger data uses absolute 64-bit addressing. This allows the compiler to generate more efficient code for smaller data while still supporting data larger than 2GB. This mirrors the -mlarge-data-threshold flag available in GCC and Clang. The default threshold is 65536 bytes (64KB) if not specified, matching LLVM's default behavior. --- .../src/back/owned_target_machine.rs | 2 + compiler/rustc_codegen_llvm/src/back/write.rs | 3 + compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 7 +- compiler/rustc_session/src/options.rs | 3 + .../compiler-flags/large-data-threshold.md | 27 +++++++ tests/assembly-llvm/large_data_threshold.rs | 73 +++++++++++++++++++ 7 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/large-data-threshold.md create mode 100644 tests/assembly-llvm/large_data_threshold.rs diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs index f88932d43d2a..65cf4cad24bd 100644 --- a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs +++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs @@ -39,6 +39,7 @@ impl OwnedTargetMachine { debug_info_compression: llvm::CompressionKind, use_emulated_tls: bool, use_wasm_eh: bool, + large_data_threshold: u64, ) -> Result> { // SAFETY: llvm::LLVMRustCreateTargetMachine copies pointed to data let tm_ptr = unsafe { @@ -65,6 +66,7 @@ impl OwnedTargetMachine { debug_info_compression, use_emulated_tls, use_wasm_eh, + large_data_threshold, ) }; diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index bcadb6f0de92..6c29d0470766 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -272,6 +272,8 @@ pub(crate) fn target_machine_factory( let use_wasm_eh = wants_wasm_eh(sess); + let large_data_threshold = sess.opts.unstable_opts.large_data_threshold.unwrap_or(0); + let prof = SelfProfilerRef::clone(&sess.prof); Arc::new(move |config: TargetMachineFactoryConfig| { // Self-profile timer for invoking a factory to create a target machine. @@ -313,6 +315,7 @@ pub(crate) fn target_machine_factory( debuginfo_compression, use_emulated_tls, use_wasm_eh, + large_data_threshold, ) }) } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index a90013801c8c..70fc62d08d5c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2338,6 +2338,7 @@ unsafe extern "C" { DebugInfoCompression: CompressionKind, UseEmulatedTls: bool, UseWasmEH: bool, + LargeDataThreshold: u64, ) -> *mut TargetMachine; pub(crate) fn LLVMRustAddLibraryInfo<'a>( diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 733f5fd0df0a..97f95ac01e86 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -305,7 +305,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, const char *SplitDwarfFile, const char *OutputObjFile, LLVMRustCompressionKind DebugInfoCompression, bool UseEmulatedTls, - bool UseWasmEH) { + bool UseWasmEH, uint64_t LargeDataThreshold) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -381,6 +381,11 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( TargetMachine *TM = TheTarget->createTargetMachine( Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel); #endif + + if (LargeDataThreshold != 0) { + TM->setLargeDataThreshold(LargeDataThreshold); + } + return wrap(TM); } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 21fa3321a30a..0bdca21ff644 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2444,6 +2444,9 @@ options! { `=skip-entry` `=skip-exit` Multiple options can be combined with commas."), + large_data_threshold: Option = (None, parse_opt_number, [TRACKED], + "set the threshold for objects to be stored in a \"large data\" section \ + (only effective with -Ccode-model=medium, default: 65536)"), layout_seed: Option = (None, parse_opt_number, [TRACKED], "seed layout randomization"), link_directives: bool = (true, parse_bool, [TRACKED], diff --git a/src/doc/unstable-book/src/compiler-flags/large-data-threshold.md b/src/doc/unstable-book/src/compiler-flags/large-data-threshold.md new file mode 100644 index 000000000000..27c86079a6c8 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/large-data-threshold.md @@ -0,0 +1,27 @@ +# `large-data-threshold` + +----------------------- + +This flag controls the threshold for static data to be placed in large data +sections when using the `medium` code model on x86-64. + +When using `-Ccode-model=medium`, static data smaller than this threshold will +use RIP-relative addressing (32-bit offsets), while larger data will use +absolute 64-bit addressing. This allows the compiler to generate more efficient +code for smaller data while still supporting data larger than 2GB. + +The default threshold is 65536 bytes (64KB) if not specified. + +## Example + +```sh +rustc -Ccode-model=medium -Zlarge-data-threshold=1024 main.rs +``` + +This sets the threshold to 1KB, meaning only data smaller than 1024 bytes will +use RIP-relative addressing. + +## Platform Support + +This flag is only effective on x86-64 targets when using `-Ccode-model=medium`. +On other architectures or with other code models, this flag has no effect. diff --git a/tests/assembly-llvm/large_data_threshold.rs b/tests/assembly-llvm/large_data_threshold.rs new file mode 100644 index 000000000000..f3b37eb7f83d --- /dev/null +++ b/tests/assembly-llvm/large_data_threshold.rs @@ -0,0 +1,73 @@ +// Test for -Z large_data_threshold=... +// This test verifies that with the medium code model, data above the threshold +// is placed in large data sections (.ldata, .lbss, .lrodata). +//@ assembly-output: emit-asm +//@ compile-flags: -Ccode-model=medium -Zlarge-data-threshold=4 +//@ compile-flags: --target=x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 + +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] +#![crate_type = "lib"] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + +#[lang = "drop_in_place"] +fn drop_in_place(_: *mut T) {} + +#[used] +#[no_mangle] +// U is below the threshold, should be in .data +static mut U: u16 = 123; + +#[used] +#[no_mangle] +// V is below the threshold, should be in .bss +static mut V: u16 = 0; + +#[used] +#[no_mangle] +// W is at the threshold, should be in .data +static mut W: u32 = 123; + +#[used] +#[no_mangle] +// X is at the threshold, should be in .bss +static mut X: u32 = 0; + +#[used] +#[no_mangle] +// Y is over the threshold, should be in .ldata +static mut Y: u64 = 123; + +#[used] +#[no_mangle] +// Z is over the threshold, should be in .lbss +static mut Z: u64 = 0; + +// CHECK: .section .data.U, +// CHECK-NOT: .section +// CHECK: U: +// CHECK: .section .bss.V, +// CHECK-NOT: .section +// CHECK: V: +// CHECK: .section .data.W, +// CHECK-NOT: .section +// CHECK: W: +// CHECK: .section .bss.X, +// CHECK-NOT: .section +// CHECK: X: +// CHECK: .section .ldata.Y, +// CHECK-NOT: .section +// CHECK: Y: +// CHECK: .section .lbss.Z, +// CHECK-NOT: .section +// CHECK: Z: From f82dd820a51b5b7ea20b257bce7d891269e2d2e6 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Wed, 7 Jan 2026 22:31:33 +0200 Subject: [PATCH 1706/3801] Use `rand` crate more idiomatically --- library/alloctests/benches/btree/map.rs | 4 +++- library/alloctests/tests/sort/patterns.rs | 15 +++++++-------- library/coretests/benches/num/int_bits/mod.rs | 7 ++++--- library/coretests/benches/num/int_sqrt/mod.rs | 17 +++++++++++------ 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/library/alloctests/benches/btree/map.rs b/library/alloctests/benches/btree/map.rs index 778065fd9657..c2bf43caf131 100644 --- a/library/alloctests/benches/btree/map.rs +++ b/library/alloctests/benches/btree/map.rs @@ -2,6 +2,7 @@ use std::collections::BTreeMap; use std::ops::RangeBounds; use rand::Rng; +use rand::distr::{Distribution, Uniform}; use rand::seq::SliceRandom; use test::{Bencher, black_box}; @@ -106,7 +107,8 @@ macro_rules! map_find_rand_bench { // setup let mut rng = crate::bench_rng(); - let mut keys: Vec<_> = (0..n).map(|_| rng.random::() % n).collect(); + let mut keys: Vec<_> = + Uniform::new(0, n).unwrap().sample_iter(&mut rng).take(n as usize).collect(); for &k in &keys { map.insert(k, k); diff --git a/library/alloctests/tests/sort/patterns.rs b/library/alloctests/tests/sort/patterns.rs index 0f1ec664d3d4..1ed645cf99dc 100644 --- a/library/alloctests/tests/sort/patterns.rs +++ b/library/alloctests/tests/sort/patterns.rs @@ -27,21 +27,20 @@ where { // :.:.:.:: - let mut rng: XorShiftRng = rand::SeedableRng::seed_from_u64(get_or_init_rand_seed()); + let rng: XorShiftRng = rand::SeedableRng::seed_from_u64(get_or_init_rand_seed()); // Abstracting over ranges in Rust :( let dist = Uniform::try_from(range).unwrap(); - (0..len).map(|_| dist.sample(&mut rng)).collect() + rng.sample_iter(dist).take(len).collect() } pub fn random_zipf(len: usize, exponent: f64) -> Vec { // https://en.wikipedia.org/wiki/Zipf's_law - let mut rng: XorShiftRng = rand::SeedableRng::seed_from_u64(get_or_init_rand_seed()); + let rng: XorShiftRng = rand::SeedableRng::seed_from_u64(get_or_init_rand_seed()); - // Abstracting over ranges in Rust :( let dist = ZipfDistribution::new(len, exponent).unwrap(); - (0..len).map(|_| dist.sample(&mut rng) as i32).collect() + rng.sample_iter(dist).map(|val| val as i32).take(len).collect() } pub fn random_sorted(len: usize, sorted_percent: f64) -> Vec { @@ -68,7 +67,7 @@ pub fn all_equal(len: usize) -> Vec { // ...... // :::::: - (0..len).map(|_| 66).collect::>() + vec![66; len] } pub fn ascending(len: usize) -> Vec { @@ -206,6 +205,6 @@ fn rand_root_seed() -> u64 { } fn random_vec(len: usize) -> Vec { - let mut rng: XorShiftRng = rand::SeedableRng::seed_from_u64(get_or_init_rand_seed()); - (0..len).map(|_| rng.random::()).collect() + let rng: XorShiftRng = rand::SeedableRng::seed_from_u64(get_or_init_rand_seed()); + rng.random_iter().take(len).collect() } diff --git a/library/coretests/benches/num/int_bits/mod.rs b/library/coretests/benches/num/int_bits/mod.rs index 43531b0b5de9..c6ec51f248ba 100644 --- a/library/coretests/benches/num/int_bits/mod.rs +++ b/library/coretests/benches/num/int_bits/mod.rs @@ -4,11 +4,12 @@ macro_rules! bench_template { ($op:path, $name:ident, $mask:expr) => { #[bench] fn $name(bench: &mut ::test::Bencher) { - use ::rand::Rng; + use ::rand::distr::{Distribution, Uniform}; let mut rng = crate::bench_rng(); let mut dst = vec![0; ITERATIONS]; - let src1: Vec = (0..ITERATIONS).map(|_| rng.random_range(0..=U::MAX)).collect(); - let mut src2: Vec = (0..ITERATIONS).map(|_| rng.random_range(0..=U::MAX)).collect(); + let distr = &Uniform::try_from(0..=U::MAX).unwrap(); + let src1: Vec = distr.sample_iter(&mut rng).take(ITERATIONS).collect(); + let mut src2: Vec = distr.sample_iter(&mut rng).take(ITERATIONS).collect(); // Fix the loop invariant mask src2[0] = U::MAX / 3; let dst = dst.first_chunk_mut().unwrap(); diff --git a/library/coretests/benches/num/int_sqrt/mod.rs b/library/coretests/benches/num/int_sqrt/mod.rs index 05cb3c5383b2..56172f71dd88 100644 --- a/library/coretests/benches/num/int_sqrt/mod.rs +++ b/library/coretests/benches/num/int_sqrt/mod.rs @@ -1,3 +1,5 @@ +use std::iter; + use rand::Rng; use test::{Bencher, black_box}; @@ -20,7 +22,9 @@ macro_rules! int_sqrt_bench { let mut rng = crate::bench_rng(); /* Exponentially distributed random numbers from the whole range of the type. */ let numbers: Vec<$t> = - (0..256).map(|_| rng.random::<$t>() >> rng.random_range(0..<$t>::BITS)).collect(); + iter::repeat_with(|| rng.random::<$t>() >> rng.random_range(0..<$t>::BITS)) + .take(256) + .collect(); bench.iter(|| { for x in &numbers { black_box(black_box(x).isqrt()); @@ -32,9 +36,10 @@ macro_rules! int_sqrt_bench { fn $random_small(bench: &mut Bencher) { let mut rng = crate::bench_rng(); /* Exponentially distributed random numbers from the range 0..256. */ - let numbers: Vec<$t> = (0..256) - .map(|_| (rng.random::() >> rng.random_range(0..u8::BITS)) as $t) - .collect(); + let numbers: Vec<$t> = + iter::repeat_with(|| (rng.random::() >> rng.random_range(0..u8::BITS)) as $t) + .take(256) + .collect(); bench.iter(|| { for x in &numbers { black_box(black_box(x).isqrt()); @@ -44,9 +49,9 @@ macro_rules! int_sqrt_bench { #[bench] fn $random_uniform(bench: &mut Bencher) { - let mut rng = crate::bench_rng(); + let rng = crate::bench_rng(); /* Exponentially distributed random numbers from the whole range of the type. */ - let numbers: Vec<$t> = (0..256).map(|_| rng.random::<$t>()).collect(); + let numbers: Vec<$t> = rng.random_iter().take(256).collect(); bench.iter(|| { for x in &numbers { black_box(black_box(x).isqrt()); From 138cc27f490aac4f98325a27853c3b0d7d25ae77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 7 Jan 2026 22:45:41 +0100 Subject: [PATCH 1707/3801] Update bors e-mail lookup --- .github/workflows/post-merge.yml | 2 +- src/build_helper/src/git.rs | 24 ++++++++++++++++++++++-- src/stage0 | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index d38cc0e8a17f..51e0a40d46f2 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -29,7 +29,7 @@ jobs: sleep 60 # Get closest bors merge commit - PARENT_COMMIT=`git rev-list --author='bors ' -n1 --first-parent HEAD^1` + PARENT_COMMIT=`git rev-list --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` echo "Parent: ${PARENT_COMMIT}" # Find PR for the current commit diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 42d9b00f004a..1fdc2ddb4cfc 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -152,6 +152,14 @@ pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool { }) } +const LEGACY_BORS_EMAIL: &str = "bors@rust-lang.org"; + +/// Escape characters from the git user e-mail, so that git commands do not interpret it as regex +/// special characters. +fn escape_email_git_regex(text: &str) -> String { + text.replace("[", "\\[").replace("]", "\\]").replace(".", "\\.") +} + /// Returns the latest upstream commit that modified `target_paths`, or `None` if no such commit /// was found. fn get_latest_upstream_commit_that_modified_files( @@ -182,9 +190,15 @@ fn get_latest_upstream_commit_that_modified_files( "-n1", &upstream, "--author", - git_config.git_merge_commit_email, + &escape_email_git_regex(git_config.git_merge_commit_email), ]); + // Also search for legacy bors account, before we accrue enough commits to + // have changes to all relevant file paths done by new bors. + if git_config.git_merge_commit_email != LEGACY_BORS_EMAIL { + git.args(["--author", LEGACY_BORS_EMAIL]); + } + if !target_paths.is_empty() { git.arg("--").args(target_paths); } @@ -229,11 +243,17 @@ pub fn get_closest_upstream_commit( git.args([ "rev-list", "--author-date-order", - &format!("--author={}", config.git_merge_commit_email), + &format!("--author={}", &escape_email_git_regex(config.git_merge_commit_email),), "-n1", base, ]); + // Also search for legacy bors account, before we accrue enough commits to + // have changes to all relevant file paths done by new bors. + if config.git_merge_commit_email != LEGACY_BORS_EMAIL { + git.args(["--author", LEGACY_BORS_EMAIL]); + } + let output = output_result(&mut git)?.trim().to_owned(); if output.is_empty() { Ok(None) } else { Ok(Some(output)) } } diff --git a/src/stage0 b/src/stage0 index 66b652a844f3..226f1d6f645e 100644 --- a/src/stage0 +++ b/src/stage0 @@ -1,7 +1,7 @@ dist_server=https://static.rust-lang.org artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt -git_merge_commit_email=bors@rust-lang.org +git_merge_commit_email=122020455+rust-bors[bot]@users.noreply.github.com nightly_branch=main # The configuration above this comment is editable, and can be changed From f2d0d52c2fe5c6719480b422578038000fcfa00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 7 Jan 2026 22:50:35 +0100 Subject: [PATCH 1708/3801] Remove unused environment variable Its last use was removed in https://github.com/rust-lang/rust/pull/142827. --- src/ci/docker/run.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 044f5a8fff32..691b8b8deb81 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -312,16 +312,6 @@ else command=(/checkout/src/ci/run.sh) fi -if isCI; then - # Get some needed information for $BASE_COMMIT - # - # This command gets the last merge commit which we'll use as base to list - # deleted files since then. - BASE_COMMIT="$(git log --author=bors@rust-lang.org -n 2 --pretty=format:%H | tail -n 1)" -else - BASE_COMMIT="" -fi - SUMMARY_FILE=github-summary.md touch $objdir/${SUMMARY_FILE} @@ -359,7 +349,6 @@ docker \ --env RUST_CI_OVERRIDE_RELEASE_CHANNEL \ --env CI_JOB_NAME="${CI_JOB_NAME-$image}" \ --env CI_JOB_DOC_URL="${CI_JOB_DOC_URL}" \ - --env BASE_COMMIT="$BASE_COMMIT" \ --env DIST_TRY_BUILD \ --env PR_CI_JOB \ --env OBJDIR_ON_HOST="$objdir" \ From 0db25dbd9dfef774e4dcc2a00e37674b5bac87de Mon Sep 17 00:00:00 2001 From: yanglsh Date: Wed, 24 Sep 2025 08:53:48 +0800 Subject: [PATCH 1709/3801] fix: `map_unwrap_or` suggests wrongly for empty slice --- clippy_lints/src/derivable_impls.rs | 2 +- clippy_lints/src/methods/map_unwrap_or.rs | 231 ++++++++++-------- .../src/methods/map_unwrap_or_else.rs | 81 +++--- tests/ui/map_unwrap_or.rs | 8 + tests/ui/map_unwrap_or.stderr | 8 +- tests/ui/map_unwrap_or_fixable.fixed | 6 +- tests/ui/map_unwrap_or_fixable.rs | 6 +- tests/ui/map_unwrap_or_fixable.stderr | 46 ++-- 8 files changed, 211 insertions(+), 177 deletions(-) diff --git a/clippy_lints/src/derivable_impls.rs b/clippy_lints/src/derivable_impls.rs index 6b8a6aec92fa..992ed320ce68 100644 --- a/clippy_lints/src/derivable_impls.rs +++ b/clippy_lints/src/derivable_impls.rs @@ -105,7 +105,7 @@ fn check_struct<'tcx>( if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind && let Some(PathSegment { args, .. }) = p.segments.last() { - let args = args.map(|a| a.args).unwrap_or(&[]); + let args = args.map(|a| a.args).unwrap_or_default(); // ty_args contains the generic parameters of the type declaration, while args contains the // arguments used at instantiation time. If both len are not equal, it means that some diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs index f2e3cc5c0091..ac2f99180486 100644 --- a/clippy_lints/src/methods/map_unwrap_or.rs +++ b/clippy_lints/src/methods/map_unwrap_or.rs @@ -1,13 +1,13 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::res::MaybeDef; +use clippy_utils::res::{MaybeDef as _, MaybeResPath as _}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_copy; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::intravisit::{Visitor, walk_path}; -use rustc_hir::{ExprKind, HirId, Node, PatKind, Path, QPath}; +use rustc_hir::intravisit::{Visitor, walk_expr, walk_path}; +use rustc_hir::{ExprKind, HirId, LangItem, Node, PatKind, Path, QPath}; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_span::{Span, sym}; @@ -28,116 +28,131 @@ pub(super) fn check<'tcx>( msrv: Msrv, ) { let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs(); - let is_option = recv_ty.is_diag_item(cx, sym::Option); - let is_result = recv_ty.is_diag_item(cx, sym::Result); + let recv_ty_kind = match recv_ty.opt_diag_name(cx) { + Some(sym::Option) => sym::Option, + Some(sym::Result) if msrv.meets(cx, msrvs::RESULT_MAP_OR) => sym::Result, + _ => return, + }; - if is_result && !msrv.meets(cx, msrvs::RESULT_MAP_OR) { + let unwrap_arg_ty = cx.typeck_results().expr_ty(unwrap_arg); + if !is_copy(cx, unwrap_arg_ty) { + // Replacing `.map().unwrap_or()` with `.map_or(, )` can sometimes lead to + // borrowck errors, see #10579 for one such instance. + // In particular, if `a` causes a move and `f` references that moved binding, then we cannot lint: + // ``` + // let x = vec![1, 2]; + // x.get(0..1).map(|s| s.to_vec()).unwrap_or(x); + // ``` + // This compiles, but changing it to `map_or` will produce a compile error: + // ``` + // let x = vec![1, 2]; + // x.get(0..1).map_or(x, |s| s.to_vec()) + // ^ moving `x` here + // ^^^^^^^^^^^ while it is borrowed here (and later used in the closure) + // ``` + // So, we have to check that `a` is not referenced anywhere (even outside of the `.map` closure!) + // before the call to `unwrap_or`. + + let mut unwrap_visitor = UnwrapVisitor { + cx, + identifiers: FxHashSet::default(), + }; + unwrap_visitor.visit_expr(unwrap_arg); + + let mut reference_visitor = ReferenceVisitor { + cx, + identifiers: unwrap_visitor.identifiers, + unwrap_or_span: unwrap_arg.span, + }; + + let body = cx.tcx.hir_body_owned_by(cx.tcx.hir_enclosing_body_owner(expr.hir_id)); + + // Visit the body, and return if we've found a reference + if reference_visitor.visit_body(body).is_break() { + return; + } + } + + if !unwrap_arg.span.eq_ctxt(map_span) { return; } - // lint if the caller of `map()` is an `Option` - if is_option || is_result { - if !is_copy(cx, cx.typeck_results().expr_ty(unwrap_arg)) { - // Replacing `.map().unwrap_or()` with `.map_or(, )` can sometimes lead to - // borrowck errors, see #10579 for one such instance. - // In particular, if `a` causes a move and `f` references that moved binding, then we cannot lint: - // ``` - // let x = vec![1, 2]; - // x.get(0..1).map(|s| s.to_vec()).unwrap_or(x); - // ``` - // This compiles, but changing it to `map_or` will produce a compile error: - // ``` - // let x = vec![1, 2]; - // x.get(0..1).map_or(x, |s| s.to_vec()) - // ^ moving `x` here - // ^^^^^^^^^^^ while it is borrowed here (and later used in the closure) - // ``` - // So, we have to check that `a` is not referenced anywhere (even outside of the `.map` closure!) - // before the call to `unwrap_or`. + let mut applicability = Applicability::MachineApplicable; + // get snippet for unwrap_or() + let unwrap_snippet = snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability); + // lint message - let mut unwrap_visitor = UnwrapVisitor { - cx, - identifiers: FxHashSet::default(), - }; - unwrap_visitor.visit_expr(unwrap_arg); - - let mut reference_visitor = ReferenceVisitor { - cx, - identifiers: unwrap_visitor.identifiers, - unwrap_or_span: unwrap_arg.span, - }; - - let body = cx.tcx.hir_body_owned_by(cx.tcx.hir_enclosing_body_owner(expr.hir_id)); - - // Visit the body, and return if we've found a reference - if reference_visitor.visit_body(body).is_break() { - return; - } - } - - if !unwrap_arg.span.eq_ctxt(map_span) { - return; - } - - // is_some_and is stabilised && `unwrap_or` argument is false; suggest `is_some_and` instead - let suggest_is_some_and = matches!(&unwrap_arg.kind, ExprKind::Lit(lit) - if matches!(lit.node, rustc_ast::LitKind::Bool(false))) - && msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND); - - let mut applicability = Applicability::MachineApplicable; - // get snippet for unwrap_or() - let unwrap_snippet = snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability); - // lint message - // comparing the snippet from source to raw text ("None") below is safe - // because we already have checked the type. - let unwrap_snippet_none = is_option && unwrap_snippet == "None"; - let arg = if unwrap_snippet_none { - "None" - } else if suggest_is_some_and { - "false" - } else { - "" - }; - let suggest = if unwrap_snippet_none { - "and_then()" - } else if suggest_is_some_and { - if is_result { - "is_ok_and()" - } else { - "is_some_and()" - } - } else { - "map_or(, )" - }; - let msg = format!( - "called `map().unwrap_or({arg})` on an `{}` value", - if is_option { "Option" } else { "Result" } - ); - - span_lint_and_then(cx, MAP_UNWRAP_OR, expr.span, msg, |diag| { - let map_arg_span = map_arg.span; - - let mut suggestion = vec![ - ( - map_span, - String::from(if unwrap_snippet_none { - "and_then" - } else if suggest_is_some_and { - if is_result { "is_ok_and" } else { "is_some_and" } - } else { - "map_or" - }), - ), - (expr.span.with_lo(unwrap_recv.span.hi()), String::new()), - ]; - - if !unwrap_snippet_none && !suggest_is_some_and { - suggestion.push((map_arg_span.with_hi(map_arg_span.lo()), format!("{unwrap_snippet}, "))); - } - - diag.multipart_suggestion(format!("use `{suggest}` instead"), suggestion, applicability); - }); + let suggest_kind = if recv_ty_kind == sym::Option + && unwrap_arg + .basic_res() + .ctor_parent(cx) + .is_lang_item(cx, LangItem::OptionNone) + { + SuggestedKind::AndThen } + // is_some_and is stabilised && `unwrap_or` argument is false; suggest `is_some_and` instead + else if matches!(&unwrap_arg.kind, ExprKind::Lit(lit) + if matches!(lit.node, rustc_ast::LitKind::Bool(false))) + && msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) + { + SuggestedKind::IsVariantAnd + } else { + SuggestedKind::Other + }; + + let arg = match suggest_kind { + SuggestedKind::AndThen => "None", + SuggestedKind::IsVariantAnd => "false", + SuggestedKind::Other => "", + }; + + let suggest = match (suggest_kind, recv_ty_kind) { + (SuggestedKind::AndThen, _) => "and_then()", + (SuggestedKind::IsVariantAnd, sym::Result) => "is_ok_and()", + (SuggestedKind::IsVariantAnd, sym::Option) => "is_some_and()", + _ => "map_or(, )", + }; + + let msg = format!( + "called `map().unwrap_or({arg})` on {} `{recv_ty_kind}` value", + if recv_ty_kind == sym::Option { "an" } else { "a" } + ); + + span_lint_and_then(cx, MAP_UNWRAP_OR, expr.span, msg, |diag| { + let map_arg_span = map_arg.span; + + let mut suggestion = vec![ + ( + map_span, + String::from(match (suggest_kind, recv_ty_kind) { + (SuggestedKind::AndThen, _) => "and_then", + (SuggestedKind::IsVariantAnd, sym::Result) => "is_ok_and", + (SuggestedKind::IsVariantAnd, sym::Option) => "is_some_and", + (SuggestedKind::Other, _) + if unwrap_arg_ty.peel_refs().is_array() + && cx.typeck_results().expr_ty_adjusted(unwrap_arg).peel_refs().is_slice() => + { + return; + }, + _ => "map_or", + }), + ), + (expr.span.with_lo(unwrap_recv.span.hi()), String::new()), + ]; + + if matches!(suggest_kind, SuggestedKind::Other) { + suggestion.push((map_arg_span.with_hi(map_arg_span.lo()), format!("{unwrap_snippet}, "))); + } + + diag.multipart_suggestion(format!("use `{suggest}` instead"), suggestion, applicability); + }); +} + +#[derive(Clone, Copy, PartialEq, Eq)] +enum SuggestedKind { + AndThen, + IsVariantAnd, + Other, } struct UnwrapVisitor<'a, 'tcx> { @@ -186,7 +201,7 @@ impl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> { { return ControlFlow::Break(()); } - rustc_hir::intravisit::walk_expr(self, expr) + walk_expr(self, expr) } fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { diff --git a/clippy_lints/src/methods/map_unwrap_or_else.rs b/clippy_lints/src/methods/map_unwrap_or_else.rs index a2f157c0cb8a..8bb532b21635 100644 --- a/clippy_lints/src/methods/map_unwrap_or_else.rs +++ b/clippy_lints/src/methods/map_unwrap_or_else.rs @@ -1,18 +1,18 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::res::MaybeDef; +use clippy_utils::res::MaybeDef as _; use clippy_utils::source::snippet; +use clippy_utils::sym; use clippy_utils::usage::mutated_variables; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::symbol::sym; use super::MAP_UNWRAP_OR; /// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s /// -/// Returns true if the lint was emitted +/// Is part of the `map_unwrap_or` lint, split into separate files for readability. pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, @@ -22,49 +22,46 @@ pub(super) fn check<'tcx>( msrv: Msrv, ) -> bool { let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs(); - let is_option = recv_ty.is_diag_item(cx, sym::Option); - let is_result = recv_ty.is_diag_item(cx, sym::Result); + let recv_ty_kind = match recv_ty.opt_diag_name(cx) { + Some(sym::Option) => sym::Option, + Some(sym::Result) if msrv.meets(cx, msrvs::RESULT_MAP_OR_ELSE) => sym::Result, + _ => return false, + }; - if is_result && !msrv.meets(cx, msrvs::RESULT_MAP_OR_ELSE) { + // Don't make a suggestion that may fail to compile due to mutably borrowing + // the same variable twice. + let Some(map_mutated_vars) = mutated_variables(recv, cx) else { + return false; + }; + let Some(unwrap_mutated_vars) = mutated_variables(unwrap_arg, cx) else { + return false; + }; + if map_mutated_vars.intersection(&unwrap_mutated_vars).next().is_some() { return false; } - if is_option || is_result { - // Don't make a suggestion that may fail to compile due to mutably borrowing - // the same variable twice. - let map_mutated_vars = mutated_variables(recv, cx); - let unwrap_mutated_vars = mutated_variables(unwrap_arg, cx); - if let (Some(map_mutated_vars), Some(unwrap_mutated_vars)) = (map_mutated_vars, unwrap_mutated_vars) { - if map_mutated_vars.intersection(&unwrap_mutated_vars).next().is_some() { - return false; - } - } else { - return false; - } - - // lint message - let msg = if is_option { - "called `map().unwrap_or_else()` on an `Option` value" - } else { - "called `map().unwrap_or_else()` on a `Result` value" - }; - // get snippets for args to map() and unwrap_or_else() - let map_snippet = snippet(cx, map_arg.span, ".."); - let unwrap_snippet = snippet(cx, unwrap_arg.span, ".."); - // lint, with note if both map() and unwrap_or_else() have the same span - if map_arg.span.eq_ctxt(unwrap_arg.span) { - let var_snippet = snippet(cx, recv.span, ".."); - span_lint_and_sugg( - cx, - MAP_UNWRAP_OR, - expr.span, - msg, - "try", - format!("{var_snippet}.map_or_else({unwrap_snippet}, {map_snippet})"), - Applicability::MachineApplicable, - ); - return true; - } + // lint message + let msg = if recv_ty_kind == sym::Option { + "called `map().unwrap_or_else()` on an `Option` value" + } else { + "called `map().unwrap_or_else()` on a `Result` value" + }; + // get snippets for args to map() and unwrap_or_else() + let map_snippet = snippet(cx, map_arg.span, ".."); + let unwrap_snippet = snippet(cx, unwrap_arg.span, ".."); + // lint, with note if both map() and unwrap_or_else() have the same span + if map_arg.span.eq_ctxt(unwrap_arg.span) { + let var_snippet = snippet(cx, recv.span, ".."); + span_lint_and_sugg( + cx, + MAP_UNWRAP_OR, + expr.span, + msg, + "try", + format!("{var_snippet}.map_or_else({unwrap_snippet}, {map_snippet})"), + Applicability::MachineApplicable, + ); + return true; } false diff --git a/tests/ui/map_unwrap_or.rs b/tests/ui/map_unwrap_or.rs index fba81cb493cd..dccacd7df8af 100644 --- a/tests/ui/map_unwrap_or.rs +++ b/tests/ui/map_unwrap_or.rs @@ -156,3 +156,11 @@ mod issue_10579 { println!("{y:?}"); } } + +fn issue15752() { + struct Foo<'a>(&'a [u32]); + + let x = Some(Foo(&[1, 2, 3])); + x.map(|y| y.0).unwrap_or(&[]); + //~^ map_unwrap_or +} diff --git a/tests/ui/map_unwrap_or.stderr b/tests/ui/map_unwrap_or.stderr index df0207c420e6..bd9e0eeb0bda 100644 --- a/tests/ui/map_unwrap_or.stderr +++ b/tests/ui/map_unwrap_or.stderr @@ -232,5 +232,11 @@ LL - let _ = opt.map(|x| x > 5).unwrap_or(false); LL + let _ = opt.is_some_and(|x| x > 5); | -error: aborting due to 15 previous errors +error: called `map().unwrap_or()` on an `Option` value + --> tests/ui/map_unwrap_or.rs:164:5 + | +LL | x.map(|y| y.0).unwrap_or(&[]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 16 previous errors diff --git a/tests/ui/map_unwrap_or_fixable.fixed b/tests/ui/map_unwrap_or_fixable.fixed index 1789c7f4d487..dca2536132d7 100644 --- a/tests/ui/map_unwrap_or_fixable.fixed +++ b/tests/ui/map_unwrap_or_fixable.fixed @@ -1,7 +1,11 @@ //@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] -#![allow(clippy::unnecessary_lazy_evaluations)] +#![allow( + clippy::unnecessary_lazy_evaluations, + clippy::manual_is_variant_and, + clippy::unnecessary_map_or +)] #[macro_use] extern crate option_helpers; diff --git a/tests/ui/map_unwrap_or_fixable.rs b/tests/ui/map_unwrap_or_fixable.rs index 309067edce4d..c60cb082ae3c 100644 --- a/tests/ui/map_unwrap_or_fixable.rs +++ b/tests/ui/map_unwrap_or_fixable.rs @@ -1,7 +1,11 @@ //@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] -#![allow(clippy::unnecessary_lazy_evaluations)] +#![allow( + clippy::unnecessary_lazy_evaluations, + clippy::manual_is_variant_and, + clippy::unnecessary_map_or +)] #[macro_use] extern crate option_helpers; diff --git a/tests/ui/map_unwrap_or_fixable.stderr b/tests/ui/map_unwrap_or_fixable.stderr index 696f516ee055..33a865d6769c 100644 --- a/tests/ui/map_unwrap_or_fixable.stderr +++ b/tests/ui/map_unwrap_or_fixable.stderr @@ -1,5 +1,5 @@ error: called `map().unwrap_or_else()` on an `Option` value - --> tests/ui/map_unwrap_or_fixable.rs:17:13 + --> tests/ui/map_unwrap_or_fixable.rs:21:13 | LL | let _ = opt.map(|x| x + 1) | _____________^ @@ -11,7 +11,7 @@ LL | | .unwrap_or_else(|| 0); = help: to override `-D warnings` add `#[allow(clippy::map_unwrap_or)]` error: called `map().unwrap_or_else()` on a `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:48:13 + --> tests/ui/map_unwrap_or_fixable.rs:52:13 | LL | let _ = res.map(|x| x + 1) | _____________^ @@ -20,7 +20,7 @@ LL | | .unwrap_or_else(|_e| 0); | |_______________________________^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)` error: called `map().unwrap_or()` on an `Option` value - --> tests/ui/map_unwrap_or_fixable.rs:65:20 + --> tests/ui/map_unwrap_or_fixable.rs:69:20 | LL | println!("{}", o.map(|y| y + 1).unwrap_or(3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,13 +32,13 @@ LL + println!("{}", o.map_or(3, |y| y + 1)); | error: called `map().unwrap_or_else()` on an `Option` value - --> tests/ui/map_unwrap_or_fixable.rs:67:20 + --> tests/ui/map_unwrap_or_fixable.rs:71:20 | LL | println!("{}", o.map(|y| y + 1).unwrap_or_else(|| 3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `o.map_or_else(|| 3, |y| y + 1)` -error: called `map().unwrap_or()` on an `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:69:20 +error: called `map().unwrap_or()` on a `Result` value + --> tests/ui/map_unwrap_or_fixable.rs:73:20 | LL | println!("{}", r.map(|y| y + 1).unwrap_or(3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,13 +50,13 @@ LL + println!("{}", r.map_or(3, |y| y + 1)); | error: called `map().unwrap_or_else()` on a `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:71:20 + --> tests/ui/map_unwrap_or_fixable.rs:75:20 | LL | println!("{}", r.map(|y| y + 1).unwrap_or_else(|()| 3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `r.map_or_else(|()| 3, |y| y + 1)` -error: called `map().unwrap_or(false)` on an `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:74:20 +error: called `map().unwrap_or(false)` on a `Result` value + --> tests/ui/map_unwrap_or_fixable.rs:78:20 | LL | println!("{}", r.map(|y| y == 1).unwrap_or(false)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,18 +68,6 @@ LL + println!("{}", r.is_ok_and(|y| y == 1)); | error: called `map().unwrap_or()` on an `Option` value - --> tests/ui/map_unwrap_or_fixable.rs:80:20 - | -LL | println!("{}", x.map(|y| y + 1).unwrap_or(3)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: use `map_or(, )` instead - | -LL - println!("{}", x.map(|y| y + 1).unwrap_or(3)); -LL + println!("{}", x.map_or(3, |y| y + 1)); - | - -error: called `map().unwrap_or()` on an `Result` value --> tests/ui/map_unwrap_or_fixable.rs:84:20 | LL | println!("{}", x.map(|y| y + 1).unwrap_or(3)); @@ -91,14 +79,26 @@ LL - println!("{}", x.map(|y| y + 1).unwrap_or(3)); LL + println!("{}", x.map_or(3, |y| y + 1)); | -error: called `map().unwrap_or_else()` on an `Option` value +error: called `map().unwrap_or()` on a `Result` value --> tests/ui/map_unwrap_or_fixable.rs:88:20 | +LL | println!("{}", x.map(|y| y + 1).unwrap_or(3)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `map_or(, )` instead + | +LL - println!("{}", x.map(|y| y + 1).unwrap_or(3)); +LL + println!("{}", x.map_or(3, |y| y + 1)); + | + +error: called `map().unwrap_or_else()` on an `Option` value + --> tests/ui/map_unwrap_or_fixable.rs:92:20 + | LL | println!("{}", x.map(|y| y + 1).unwrap_or_else(|| 3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map_or_else(|| 3, |y| y + 1)` error: called `map().unwrap_or_else()` on a `Result` value - --> tests/ui/map_unwrap_or_fixable.rs:92:20 + --> tests/ui/map_unwrap_or_fixable.rs:96:20 | LL | println!("{}", x.map(|y| y + 1).unwrap_or_else(|_| 3)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map_or_else(|_| 3, |y| y + 1)` From ac0b17bcf94517c301d4abd9c0278ab180c3248d Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Wed, 7 Jan 2026 22:32:16 +0000 Subject: [PATCH 1710/3801] fix: `unnecessary_to_owned` wrongly unmangled macros --- .../src/methods/unnecessary_to_owned.rs | 22 +++++++++++-------- tests/ui/unnecessary_to_owned.fixed | 9 ++++++++ tests/ui/unnecessary_to_owned.rs | 9 ++++++++ tests/ui/unnecessary_to_owned.stderr | 8 ++++++- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index a6a39cb6ab30..74e8dbc15a6c 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -3,7 +3,7 @@ use super::unnecessary_iter_cloned::{self, is_into_iter}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeDef; -use clippy_utils::source::{SpanRangeExt, snippet}; +use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_context}; use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, peel_and_count_ty_refs}; use clippy_utils::visitors::find_all_ret_expressions; use clippy_utils::{fn_def_id, get_parent_expr, is_expr_temporary_value, return_ty, sym}; @@ -131,8 +131,10 @@ fn check_addr_of_expr( && (*referent_ty != receiver_ty || (matches!(referent_ty.kind(), ty::Array(..)) && is_copy(cx, *referent_ty)) || is_cow_into_owned(cx, method_name, method_parent_id)) - && let Some(receiver_snippet) = receiver.span.get_source_text(cx) { + let mut applicability = Applicability::MachineApplicable; + let (receiver_snippet, _) = snippet_with_context(cx, receiver.span, expr.span.ctxt(), "..", &mut applicability); + if receiver_ty == target_ty && n_target_refs >= n_receiver_refs { span_lint_and_sugg( cx, @@ -145,7 +147,7 @@ fn check_addr_of_expr( "", width = n_target_refs - n_receiver_refs ), - Applicability::MachineApplicable, + applicability, ); return true; } @@ -165,8 +167,8 @@ fn check_addr_of_expr( parent.span, format!("unnecessary use of `{method_name}`"), "use", - receiver_snippet.to_owned(), - Applicability::MachineApplicable, + receiver_snippet.to_string(), + applicability, ); } else { span_lint_and_sugg( @@ -176,7 +178,7 @@ fn check_addr_of_expr( format!("unnecessary use of `{method_name}`"), "remove this", String::new(), - Applicability::MachineApplicable, + applicability, ); } return true; @@ -191,7 +193,7 @@ fn check_addr_of_expr( format!("unnecessary use of `{method_name}`"), "use", format!("{receiver_snippet}.as_ref()"), - Applicability::MachineApplicable, + applicability, ); return true; } @@ -409,8 +411,10 @@ fn check_other_call_arg<'tcx>( None } && can_change_type(cx, maybe_arg, receiver_ty) - && let Some(receiver_snippet) = receiver.span.get_source_text(cx) { + let mut applicability = Applicability::MachineApplicable; + let (receiver_snippet, _) = snippet_with_context(cx, receiver.span, expr.span.ctxt(), "..", &mut applicability); + span_lint_and_sugg( cx, UNNECESSARY_TO_OWNED, @@ -418,7 +422,7 @@ fn check_other_call_arg<'tcx>( format!("unnecessary use of `{method_name}`"), "use", format!("{:&>n_refs$}{receiver_snippet}", ""), - Applicability::MachineApplicable, + applicability, ); return true; } diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed index 316eac0b58b7..590359bc1ad2 100644 --- a/tests/ui/unnecessary_to_owned.fixed +++ b/tests/ui/unnecessary_to_owned.fixed @@ -681,3 +681,12 @@ fn issue14833() { let mut s = HashSet::<&String>::new(); s.remove(&"hello".to_owned()); } + +#[allow(clippy::redundant_clone)] +fn issue16351() { + fn take(_: impl AsRef) {} + + let dot = "."; + take(&format!("ouch{dot}")); + //~^ unnecessary_to_owned +} diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs index f2dbd1db3c9f..d1e3e6497c0a 100644 --- a/tests/ui/unnecessary_to_owned.rs +++ b/tests/ui/unnecessary_to_owned.rs @@ -681,3 +681,12 @@ fn issue14833() { let mut s = HashSet::<&String>::new(); s.remove(&"hello".to_owned()); } + +#[allow(clippy::redundant_clone)] +fn issue16351() { + fn take(_: impl AsRef) {} + + let dot = "."; + take(format!("ouch{dot}").to_string()); + //~^ unnecessary_to_owned +} diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr index 6c52be839301..50e3d5eb2195 100644 --- a/tests/ui/unnecessary_to_owned.stderr +++ b/tests/ui/unnecessary_to_owned.stderr @@ -550,5 +550,11 @@ error: unnecessary use of `to_vec` LL | s.remove(&(&["b"]).to_vec()); | ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()` -error: aborting due to 82 previous errors +error: unnecessary use of `to_string` + --> tests/ui/unnecessary_to_owned.rs:690:10 + | +LL | take(format!("ouch{dot}").to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `&format!("ouch{dot}")` + +error: aborting due to 83 previous errors From 4976fdf203b5122bf3b26acf02af5ae6ea25f138 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Wed, 7 Jan 2026 23:17:33 +0000 Subject: [PATCH 1711/3801] fix: `significant_drop_tightening` suggests wrongly for non-method usage --- .../src/significant_drop_tightening.rs | 24 ++++--- tests/ui/significant_drop_tightening.fixed | 36 ++++++++++ tests/ui/significant_drop_tightening.rs | 33 +++++++++ tests/ui/significant_drop_tightening.stderr | 71 ++++++++++++++++++- 4 files changed, 152 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs index fabb21f78b9e..8557e8d18d10 100644 --- a/clippy_lints/src/significant_drop_tightening.rs +++ b/clippy_lints/src/significant_drop_tightening.rs @@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeResPath; use clippy_utils::source::{indent_of, snippet}; use clippy_utils::{expr_or_init, get_builtin_attr, peel_hir_expr_unary, sym}; +use rustc_ast::BindingMode; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; @@ -89,13 +90,14 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> { |diag| { match apa.counter { 0 | 1 => {}, - 2 => { + 2 if let Some(last_method_span) = apa.last_method_span => { let indent = " ".repeat(indent_of(cx, apa.last_stmt_span).unwrap_or(0)); let init_method = snippet(cx, apa.first_method_span, ".."); - let usage_method = snippet(cx, apa.last_method_span, ".."); - let stmt = if let Some(last_bind_ident) = apa.last_bind_ident { + let usage_method = snippet(cx, last_method_span, ".."); + let stmt = if let Some((binding_mode, last_bind_ident)) = apa.last_bind_ident { format!( - "\n{indent}let {} = {init_method}.{usage_method};", + "\n{indent}let {}{} = {init_method}.{usage_method};", + binding_mode.prefix_str(), snippet(cx, last_bind_ident.span, ".."), ) } else { @@ -310,13 +312,13 @@ impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> { }; match self.ap.curr_stmt.kind { hir::StmtKind::Let(local) => { - if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind { - apa.last_bind_ident = Some(ident); + if let hir::PatKind::Binding(binding_mode, _, ident, _) = local.pat.kind { + apa.last_bind_ident = Some((binding_mode, ident)); } if let Some(local_init) = local.init && let hir::ExprKind::MethodCall(_, _, _, span) = local_init.kind { - apa.last_method_span = span; + apa.last_method_span = Some(span); } }, hir::StmtKind::Semi(semi_expr) => { @@ -326,7 +328,7 @@ impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> { return; } if let hir::ExprKind::MethodCall(_, _, _, span) = semi_expr.kind { - apa.last_method_span = span; + apa.last_method_span = Some(span); } }, _ => {}, @@ -385,9 +387,9 @@ struct AuxParamsAttr { /// The last visited binding or variable span within a block that had any referenced inner type /// marked with `#[has_significant_drop]`. - last_bind_ident: Option, + last_bind_ident: Option<(BindingMode, Ident)>, /// Similar to `last_bind_span` but encompasses the right-hand method call. - last_method_span: Span, + last_method_span: Option, /// Similar to `last_bind_span` but encompasses the whole contained statement. last_stmt_span: Span, } @@ -403,7 +405,7 @@ impl Default for AuxParamsAttr { first_method_span: DUMMY_SP, first_stmt_span: DUMMY_SP, last_bind_ident: None, - last_method_span: DUMMY_SP, + last_method_span: None, last_stmt_span: DUMMY_SP, } } diff --git a/tests/ui/significant_drop_tightening.fixed b/tests/ui/significant_drop_tightening.fixed index 3d416056226c..559c1bb94570 100644 --- a/tests/ui/significant_drop_tightening.fixed +++ b/tests/ui/significant_drop_tightening.fixed @@ -146,3 +146,39 @@ pub fn unnecessary_contention_with_single_owned_results() { pub fn do_heavy_computation_that_takes_time(_: T) {} fn main() {} + +fn issue15574() { + use std::io::{BufRead, Read, stdin}; + use std::process; + + println!("Hello, what's your name?"); + + let mut stdin = stdin().lock().take(40); + //~^ significant_drop_tightening + let mut buffer = String::with_capacity(10); + + + //~^ significant_drop_tightening + if stdin.read_line(&mut buffer).is_err() { + eprintln!("An error has occured while reading."); + return; + } + drop(stdin); + println!("Our string has a capacity of {}", buffer.capacity()); + println!("Hello {}!", buffer); +} + +fn issue16343() { + fn get_items(x: &()) -> Vec<()> { + vec![*x] + } + + let storage = Mutex::new(()); + let lock = storage.lock().unwrap(); + //~^ significant_drop_tightening + let items = get_items(&lock); + drop(lock); + for item in items { + println!("item {:?}", item); + } +} diff --git a/tests/ui/significant_drop_tightening.rs b/tests/ui/significant_drop_tightening.rs index d9c4ad543593..dff36baf383d 100644 --- a/tests/ui/significant_drop_tightening.rs +++ b/tests/ui/significant_drop_tightening.rs @@ -142,3 +142,36 @@ pub fn unnecessary_contention_with_single_owned_results() { pub fn do_heavy_computation_that_takes_time(_: T) {} fn main() {} + +fn issue15574() { + use std::io::{BufRead, Read, stdin}; + use std::process; + + println!("Hello, what's your name?"); + let stdin = stdin().lock(); + //~^ significant_drop_tightening + let mut buffer = String::with_capacity(10); + + let mut stdin = stdin.take(40); + //~^ significant_drop_tightening + if stdin.read_line(&mut buffer).is_err() { + eprintln!("An error has occured while reading."); + return; + } + println!("Our string has a capacity of {}", buffer.capacity()); + println!("Hello {}!", buffer); +} + +fn issue16343() { + fn get_items(x: &()) -> Vec<()> { + vec![*x] + } + + let storage = Mutex::new(()); + let lock = storage.lock().unwrap(); + //~^ significant_drop_tightening + let items = get_items(&lock); + for item in items { + println!("item {:?}", item); + } +} diff --git a/tests/ui/significant_drop_tightening.stderr b/tests/ui/significant_drop_tightening.stderr index 25cd9da73a10..785bee4970ec 100644 --- a/tests/ui/significant_drop_tightening.stderr +++ b/tests/ui/significant_drop_tightening.stderr @@ -83,5 +83,74 @@ LL | LL ~ | -error: aborting due to 4 previous errors +error: temporary with significant `Drop` can be early dropped + --> tests/ui/significant_drop_tightening.rs:151:9 + | +LL | fn issue15574() { + | _________________- +LL | | use std::io::{BufRead, Read, stdin}; +LL | | use std::process; +... | +LL | | let stdin = stdin().lock(); + | | ^^^^^ +... | +LL | | println!("Hello {}!", buffer); +LL | | } + | |_- temporary `stdin` is currently being dropped at the end of its contained scope + | + = note: this might lead to unnecessary resource contention +help: merge the temporary construction with its single usage + | +LL ~ +LL + let mut stdin = stdin().lock().take(40); +LL | +LL | let mut buffer = String::with_capacity(10); +LL | +LL ~ + | + +error: temporary with significant `Drop` can be early dropped + --> tests/ui/significant_drop_tightening.rs:155:13 + | +LL | fn issue15574() { + | _________________- +LL | | use std::io::{BufRead, Read, stdin}; +LL | | use std::process; +... | +LL | | let mut stdin = stdin.take(40); + | | ^^^^^ +... | +LL | | println!("Hello {}!", buffer); +LL | | } + | |_- temporary `stdin` is currently being dropped at the end of its contained scope + | + = note: this might lead to unnecessary resource contention +help: drop the temporary after the end of its last usage + | +LL ~ } +LL + drop(stdin); + | + +error: temporary with significant `Drop` can be early dropped + --> tests/ui/significant_drop_tightening.rs:171:9 + | +LL | fn issue16343() { + | _________________- +LL | | fn get_items(x: &()) -> Vec<()> { +LL | | vec![*x] +... | +LL | | let lock = storage.lock().unwrap(); + | | ^^^^ +... | +LL | | } + | |_- temporary `lock` is currently being dropped at the end of its contained scope + | + = note: this might lead to unnecessary resource contention +help: drop the temporary after the end of its last usage + | +LL ~ let items = get_items(&lock); +LL + drop(lock); + | + +error: aborting due to 7 previous errors From e2b507233c3224187dd5ef53a9044a430e4f9129 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Tue, 2 Dec 2025 13:05:47 +1100 Subject: [PATCH 1712/3801] Add ProjectJsonTargetSpec.project_root Needed to support flychecking in a later diff --- src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs | 1 + src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 9beab3c0e45c..81d60179cc94 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -833,6 +833,7 @@ impl GlobalStateSnapshot { label: build.label, target_kind: build.target_kind, shell_runnables: project.runnables().to_owned(), + project_root: project.project_root().to_owned(), })); } ProjectWorkspaceKind::DetachedFile { .. } => {} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index e0f95a7830ea..8452b6493e87 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -68,6 +68,7 @@ pub(crate) struct ProjectJsonTargetSpec { pub(crate) label: String, pub(crate) target_kind: TargetKind, pub(crate) shell_runnables: Vec, + pub(crate) project_root: AbsPathBuf, } impl ProjectJsonTargetSpec { From ff94498ef2a831c47d9237262f612a3bb530bd69 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Tue, 2 Dec 2025 14:02:07 +1100 Subject: [PATCH 1713/3801] project-model: Helpers for traversing dep graph in ProjectJson Needed for all_workspace_dependencies_for_package implementation. --- .../crates/project-model/src/project_json.rs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index b3478d2cfe03..adc9b1a49fd4 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -78,6 +78,13 @@ pub struct ProjectJson { runnables: Vec, } +impl std::ops::Index for ProjectJson { + type Output = Crate; + fn index(&self, index: CrateArrayIdx) -> &Self::Output { + &self.crates[index.0] + } +} + impl ProjectJson { /// Create a new ProjectJson instance. /// @@ -218,6 +225,14 @@ impl ProjectJson { .find(|build| build.build_file.as_std_path() == path) } + pub fn crate_by_label(&self, label: &str) -> Option<&Crate> { + // this is fast enough for now, but it's unfortunate that this is O(crates). + self.crates + .iter() + .filter(|krate| krate.is_workspace_member) + .find(|krate| krate.build.as_ref().is_some_and(|build| build.label == label)) + } + /// Returns the path to the project's manifest or root folder, if no manifest exists. pub fn manifest_or_root(&self) -> &AbsPath { self.manifest.as_ref().map_or(&self.project_root, |manifest| manifest.as_ref()) @@ -258,6 +273,12 @@ pub struct Crate { pub build: Option, } +impl Crate { + pub fn iter_deps(&self) -> impl ExactSizeIterator { + self.deps.iter().map(|dep| dep.krate) + } +} + /// Additional, build-specific data about a crate. #[derive(Clone, Debug, Eq, PartialEq)] pub struct Build { From 3083bde73d2e7a1e2227ef77f1f248598005ba08 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Tue, 2 Dec 2025 14:02:25 +1100 Subject: [PATCH 1714/3801] project-model: Don't do O(n) clones as well as O(n) search --- .../rust-analyzer/crates/project-model/src/project_json.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index adc9b1a49fd4..8fe7885983a7 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -221,8 +221,9 @@ impl ProjectJson { self.crates .iter() .filter(|krate| krate.is_workspace_member) - .filter_map(|krate| krate.build.clone()) + .filter_map(|krate| krate.build.as_ref()) .find(|build| build.build_file.as_std_path() == path) + .cloned() } pub fn crate_by_label(&self, label: &str) -> Option<&Crate> { From ac641771a83d23f965b3dcb180bb854de21002fb Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 4 Sep 2024 13:52:59 +1000 Subject: [PATCH 1715/3801] project-model: Return crate by reference --- .../rust-analyzer/crates/project-model/src/project_json.rs | 3 +-- .../rust-analyzer/crates/rust-analyzer/src/global_state.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index 8fe7885983a7..a7fba6936244 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -202,12 +202,11 @@ impl ProjectJson { &self.project_root } - pub fn crate_by_root(&self, root: &AbsPath) -> Option { + pub fn crate_by_root(&self, root: &AbsPath) -> Option<&Crate> { self.crates .iter() .filter(|krate| krate.is_workspace_member) .find(|krate| krate.root_module == root) - .cloned() } /// Returns the path to the project's manifest, if it exists. diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 81d60179cc94..99dc8bce062e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -825,7 +825,7 @@ impl GlobalStateSnapshot { let Some(krate) = project.crate_by_root(path) else { continue; }; - let Some(build) = krate.build else { + let Some(build) = krate.build.clone() else { continue; }; From 3b97d38702700a274b22dcd9cc21d836d4dc1ce0 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Tue, 2 Dec 2025 14:11:52 +1100 Subject: [PATCH 1716/3801] Fix misuse of ? This exited the whole loop instead of having continue semantics and continuing to find workspaces. So wrap in find_map. --- .../crates/rust-analyzer/src/global_state.rs | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 99dc8bce062e..68d65cdee6f3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -847,21 +847,18 @@ impl GlobalStateSnapshot { &self, package: &Arc, ) -> Option>> { - for workspace in self.workspaces.iter() { - match &workspace.kind { - ProjectWorkspaceKind::Cargo { cargo, .. } - | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _, _)), .. } => { - let package = cargo.packages().find(|p| cargo[*p].id == *package)?; + self.workspaces.iter().find_map(|workspace| match &workspace.kind { + ProjectWorkspaceKind::Cargo { cargo, .. } + | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _, _)), .. } => { + let package = cargo.packages().find(|p| cargo[*p].id == *package)?; - return cargo[package] - .all_member_deps - .as_ref() - .map(|deps| deps.iter().map(|dep| cargo[*dep].id.clone()).collect()); - } - _ => {} + return cargo[package] + .all_member_deps + .as_ref() + .map(|deps| deps.iter().map(|dep| cargo[*dep].id.clone()).collect()); } - } - None + _ => None, + }) } pub(crate) fn file_exists(&self, file_id: FileId) -> bool { From 327ea186f07053f70b4bf6af394e6f8ec80f303e Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 4 Sep 2024 13:52:59 +1000 Subject: [PATCH 1717/3801] flycheck: Make the flycheckable unit a flycheck::PackageSpecifier enum You should be able to flycheck a ProjectJson crate based on its build label. This paves the way for that. Context: I don't think this has been working for some time. It used to be that we would use cargo to build ProjectJson crates. Support for ProjectJson seems to have been somewhat steamrolled in PR 18845 (e4bf6e1bc36e4cbc8a36d7911788176eb9fac76e). --- .../crates/rust-analyzer/src/diagnostics.rs | 16 +++-- .../crates/rust-analyzer/src/flycheck.rs | 69 +++++++++++++++---- .../crates/rust-analyzer/src/global_state.rs | 50 ++++++++++---- .../src/handlers/notification.rs | 42 +++++++---- 4 files changed, 130 insertions(+), 47 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs index 4a247800af9d..712960f13d7e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs @@ -3,7 +3,6 @@ pub(crate) mod flycheck_to_proto; use std::mem; -use cargo_metadata::PackageId; use ide::FileId; use ide_db::{FxHashMap, base_db::DbPanicContext}; use itertools::Itertools; @@ -12,10 +11,13 @@ use smallvec::SmallVec; use stdx::iter_eq_by; use triomphe::Arc; -use crate::{global_state::GlobalStateSnapshot, lsp, lsp_ext, main_loop::DiagnosticsTaskKind}; +use crate::{ + flycheck::PackageSpecifier, global_state::GlobalStateSnapshot, lsp, lsp_ext, + main_loop::DiagnosticsTaskKind, +}; pub(crate) type CheckFixes = - Arc>, FxHashMap>>>>; + Arc, FxHashMap>>>>; #[derive(Debug, Default, Clone)] pub struct DiagnosticsMapConfig { @@ -29,7 +31,7 @@ pub(crate) type DiagnosticsGeneration = usize; #[derive(Debug, Clone, Default)] pub(crate) struct WorkspaceFlycheckDiagnostic { - pub(crate) per_package: FxHashMap>, PackageFlycheckDiagnostic>, + pub(crate) per_package: FxHashMap, PackageFlycheckDiagnostic>, } #[derive(Debug, Clone)] @@ -85,7 +87,7 @@ impl DiagnosticCollection { pub(crate) fn clear_check_for_package( &mut self, flycheck_id: usize, - package_id: Arc, + package_id: PackageSpecifier, ) { let Some(check) = self.check.get_mut(flycheck_id) else { return; @@ -124,7 +126,7 @@ impl DiagnosticCollection { pub(crate) fn clear_check_older_than_for_package( &mut self, flycheck_id: usize, - package_id: Arc, + package_id: PackageSpecifier, generation: DiagnosticsGeneration, ) { let Some(check) = self.check.get_mut(flycheck_id) else { @@ -154,7 +156,7 @@ impl DiagnosticCollection { &mut self, flycheck_id: usize, generation: DiagnosticsGeneration, - package_id: &Option>, + package_id: &Option, file_id: FileId, diagnostic: lsp_types::Diagnostic, fix: Option>, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index b06264169188..2819ae98daaf 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -195,9 +195,9 @@ impl FlycheckHandle { /// Schedule a re-start of the cargo check worker to do a package wide check. pub(crate) fn restart_for_package( &self, - package: Arc, + package: PackageSpecifier, target: Option, - workspace_deps: Option>>, + workspace_deps: Option>, ) { let generation = self.generation.fetch_add(1, Ordering::Relaxed) + 1; self.sender @@ -233,7 +233,7 @@ pub(crate) enum ClearDiagnosticsKind { #[derive(Debug)] pub(crate) enum ClearScope { Workspace, - Package(Arc), + Package(PackageSpecifier), } pub(crate) enum FlycheckMessage { @@ -243,7 +243,7 @@ pub(crate) enum FlycheckMessage { generation: DiagnosticsGeneration, workspace_root: Arc, diagnostic: Diagnostic, - package_id: Option>, + package_id: Option, }, /// Request clearing all outdated diagnostics. @@ -295,7 +295,32 @@ pub(crate) enum Progress { enum FlycheckScope { Workspace, - Package { package: Arc, workspace_deps: Option>> }, + Package { + // Either a cargo package or a $label in rust-project.check.overrideCommand + package: PackageSpecifier, + workspace_deps: Option>, + }, +} + +#[derive(Debug, Hash, PartialEq, Eq, Clone)] +pub(crate) enum PackageSpecifier { + Cargo { + /// The one in Cargo.toml, assumed to work with `cargo check -p {}` etc + package_id: Arc, + }, + BuildInfo { + /// If a `build` field is present in rust-project.json, its label field + label: String, + }, +} + +impl PackageSpecifier { + pub(crate) fn as_str(&self) -> &str { + match self { + Self::Cargo { package_id } => &package_id.repr, + Self::BuildInfo { label } => label, + } + } } enum StateChange { @@ -331,7 +356,7 @@ struct FlycheckActor { command_handle: Option>, /// The receiver side of the channel mentioned above. command_receiver: Option>, - diagnostics_cleared_for: FxHashSet>, + diagnostics_cleared_for: FxHashSet, diagnostics_received: DiagnosticsReceived, } @@ -564,7 +589,10 @@ impl FlycheckActor { msg.target.kind.iter().format_with(", ", |kind, f| f(&kind)), ))); let package_id = Arc::new(msg.package_id); - if self.diagnostics_cleared_for.insert(package_id.clone()) { + if self + .diagnostics_cleared_for + .insert(PackageSpecifier::Cargo { package_id: package_id.clone() }) + { tracing::trace!( flycheck_id = self.id, package_id = package_id.repr, @@ -572,7 +600,9 @@ impl FlycheckActor { ); self.send(FlycheckMessage::ClearDiagnostics { id: self.id, - kind: ClearDiagnosticsKind::All(ClearScope::Package(package_id)), + kind: ClearDiagnosticsKind::All(ClearScope::Package( + PackageSpecifier::Cargo { package_id }, + )), }); } } @@ -580,7 +610,7 @@ impl FlycheckActor { tracing::trace!( flycheck_id = self.id, message = diagnostic.message, - package_id = package_id.as_ref().map(|it| &it.repr), + package_id = package_id.as_ref().map(|it| it.as_str()), "diagnostic received" ); if self.diagnostics_received == DiagnosticsReceived::No { @@ -590,7 +620,7 @@ impl FlycheckActor { if self.diagnostics_cleared_for.insert(package_id.clone()) { tracing::trace!( flycheck_id = self.id, - package_id = package_id.repr, + package_id = package_id.as_str(), "clearing diagnostics" ); self.send(FlycheckMessage::ClearDiagnostics { @@ -666,7 +696,18 @@ impl FlycheckActor { match scope { FlycheckScope::Workspace => cmd.arg("--workspace"), - FlycheckScope::Package { package, .. } => cmd.arg("-p").arg(&package.repr), + FlycheckScope::Package { + package: PackageSpecifier::Cargo { package_id }, + .. + } => cmd.arg("-p").arg(&package_id.repr), + FlycheckScope::Package { + package: PackageSpecifier::BuildInfo { .. }, .. + } => { + // No way to flycheck this single package. All we have is a build label. + // There's no way to really say whether this build label happens to be + // a cargo canonical name, so we won't try. + return None; + } }; if let Some(tgt) = target { @@ -748,7 +789,7 @@ impl FlycheckActor { #[allow(clippy::large_enum_variant)] enum CargoCheckMessage { CompilerArtifact(cargo_metadata::Artifact), - Diagnostic { diagnostic: Diagnostic, package_id: Option> }, + Diagnostic { diagnostic: Diagnostic, package_id: Option }, } struct CargoCheckParser; @@ -767,7 +808,9 @@ impl JsonLinesParser for CargoCheckParser { cargo_metadata::Message::CompilerMessage(msg) => { Some(CargoCheckMessage::Diagnostic { diagnostic: msg.message, - package_id: Some(Arc::new(msg.package_id)), + package_id: Some(PackageSpecifier::Cargo { + package_id: Arc::new(msg.package_id), + }), }) } _ => None, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 68d65cdee6f3..0cfd0a141bae 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -9,7 +9,6 @@ use std::{ time::{Duration, Instant}, }; -use cargo_metadata::PackageId; use crossbeam_channel::{Receiver, Sender, unbounded}; use hir::ChangeWithProcMacros; use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId}; @@ -36,7 +35,7 @@ use crate::{ config::{Config, ConfigChange, ConfigErrors, RatomlFileKind}, diagnostics::{CheckFixes, DiagnosticCollection}, discover, - flycheck::{FlycheckHandle, FlycheckMessage}, + flycheck::{FlycheckHandle, FlycheckMessage, PackageSpecifier}, line_index::{LineEndings, LineIndex}, lsp::{from_proto, to_proto::url_from_abs_path}, lsp_ext, @@ -845,20 +844,43 @@ impl GlobalStateSnapshot { pub(crate) fn all_workspace_dependencies_for_package( &self, - package: &Arc, - ) -> Option>> { - self.workspaces.iter().find_map(|workspace| match &workspace.kind { - ProjectWorkspaceKind::Cargo { cargo, .. } - | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _, _)), .. } => { - let package = cargo.packages().find(|p| cargo[*p].id == *package)?; + package: &PackageSpecifier, + ) -> Option> { + match package { + PackageSpecifier::Cargo { package_id } => { + self.workspaces.iter().find_map(|workspace| match &workspace.kind { + ProjectWorkspaceKind::Cargo { cargo, .. } + | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _, _)), .. } => { + let package = cargo.packages().find(|p| cargo[*p].id == *package_id)?; - return cargo[package] - .all_member_deps - .as_ref() - .map(|deps| deps.iter().map(|dep| cargo[*dep].id.clone()).collect()); + cargo[package].all_member_deps.as_ref().map(|deps| { + deps.iter() + .map(|dep| cargo[*dep].id.clone()) + .map(|p| PackageSpecifier::Cargo { package_id: p }) + .collect() + }) + } + _ => None, + }) } - _ => None, - }) + PackageSpecifier::BuildInfo { label } => { + self.workspaces.iter().find_map(|workspace| match &workspace.kind { + ProjectWorkspaceKind::Json(p) => { + let krate = p.crate_by_label(label)?; + Some( + krate + .iter_deps() + .filter_map(|dep| p[dep].build.as_ref()) + .map(|build| PackageSpecifier::BuildInfo { + label: build.label.clone(), + }) + .collect(), + ) + } + _ => None, + }) + } + } } pub(crate) fn file_exists(&self, file_id: FileId) -> bool { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs index 4a6544508ff4..57adbbfe72a7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs @@ -18,7 +18,7 @@ use vfs::{AbsPathBuf, ChangeKind, VfsPath}; use crate::{ config::{Config, ConfigChange}, - flycheck::{InvocationStrategy, Target}, + flycheck::{InvocationStrategy, PackageSpecifier, Target}, global_state::{FetchWorkspaceRequest, GlobalState}, lsp::{from_proto, utils::apply_document_changes}, lsp_ext::{self, RunFlycheckParams}, @@ -328,22 +328,32 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { } InvocationStrategy::PerWorkspace => { Box::new(move || { - let target = TargetSpec::for_file(&world, file_id)?.and_then(|it| { + let target = TargetSpec::for_file(&world, file_id)?.map(|it| { let tgt_kind = it.target_kind(); let (tgt_name, root, package) = match it { - TargetSpec::Cargo(c) => (c.target, c.workspace_root, c.package_id), - _ => return None, + TargetSpec::Cargo(c) => ( + Some(c.target), + c.workspace_root, + PackageSpecifier::Cargo { package_id: c.package_id }, + ), + TargetSpec::ProjectJson(p) => ( + None, + p.project_root, + PackageSpecifier::BuildInfo { label: p.label.clone() }, + ), }; - let tgt = match tgt_kind { - project_model::TargetKind::Bin => Target::Bin(tgt_name), - project_model::TargetKind::Example => Target::Example(tgt_name), - project_model::TargetKind::Test => Target::Test(tgt_name), - project_model::TargetKind::Bench => Target::Benchmark(tgt_name), - _ => return Some((None, root, package)), - }; + let tgt = tgt_name.and_then(|tgt_name| { + Some(match tgt_kind { + project_model::TargetKind::Bin => Target::Bin(tgt_name), + project_model::TargetKind::Example => Target::Example(tgt_name), + project_model::TargetKind::Test => Target::Test(tgt_name), + project_model::TargetKind::Bench => Target::Benchmark(tgt_name), + _ => return None, + }) + }); - Some((Some(tgt), root, package)) + (tgt, root, package) }); tracing::debug!(?target, "flycheck target"); // we have a specific non-library target, attempt to only check that target, nothing @@ -365,7 +375,13 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { cargo: Some((cargo, _, _)), .. } => *cargo.workspace_root() == root, - _ => false, + project_model::ProjectWorkspaceKind::Json(p) => { + *p.project_root() == root + } + project_model::ProjectWorkspaceKind::DetachedFile { + cargo: None, + .. + } => false, }); if let Some(idx) = package_workspace_idx { let workspace_deps = From 95a07dbfa06ad7c30d4e9fa2f85de2b991d610f3 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 4 Sep 2024 13:52:59 +1000 Subject: [PATCH 1718/3801] project-model: Introduce RunnableKind::Flycheck We need to distinguish from RunnableKind::Check, which is human-readable. --- .../crates/project-model/src/project_json.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index a7fba6936244..536f170e1192 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -246,6 +246,10 @@ impl ProjectJson { pub fn runnables(&self) -> &[Runnable] { &self.runnables } + + pub fn runnable_template(&self, kind: RunnableKind) -> Option<&Runnable> { + self.runnables().iter().find(|r| r.kind == kind) + } } /// A crate points to the root module of a crate and lists the dependencies of the crate. This is @@ -349,6 +353,7 @@ pub struct Runnable { /// The kind of runnable. #[derive(Debug, Clone, PartialEq, Eq)] pub enum RunnableKind { + /// `cargo check`, basically, with human-readable output. Check, /// Can run a binary. @@ -356,6 +361,10 @@ pub enum RunnableKind { /// Run a single test. TestOne, + + /// Template for checking a target, emitting rustc JSON diagnostics. + /// May include {label} which will get the label from the `build` section of a crate. + Flycheck, } #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] @@ -462,6 +471,7 @@ pub struct RunnableData { #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub enum RunnableKindData { + Flycheck, Check, Run, TestOne, @@ -532,6 +542,7 @@ impl From for RunnableKind { RunnableKindData::Check => RunnableKind::Check, RunnableKindData::Run => RunnableKind::Run, RunnableKindData::TestOne => RunnableKind::TestOne, + RunnableKindData::Flycheck => RunnableKind::Flycheck, } } } From 2a899bb119bd9e33eadce3b7179cb1b8bc49fd78 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 4 Sep 2024 13:52:59 +1000 Subject: [PATCH 1719/3801] flycheck: Use RunnableKind::Flycheck from ProjectJson to flycheck This adds a substitution helper to get the right behaviour re {label} and $saved_file. --- .../crates/rust-analyzer/src/flycheck.rs | 226 +++++++++++++++++- .../crates/rust-analyzer/src/reload.rs | 19 +- 2 files changed, 238 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 2819ae98daaf..1b1e3344e25f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -14,6 +14,7 @@ use ide_db::FxHashSet; use itertools::Itertools; use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf}; use project_model::TargetDirectoryConfig; +use project_model::project_json; use rustc_hash::FxHashMap; use serde::Deserialize as _; use serde_derive::Deserialize; @@ -89,6 +90,24 @@ impl CargoOptions { } } +/// The flycheck config from a rust-project.json file or discoverConfig JSON output. +#[derive(Debug, Default)] +pub(crate) struct FlycheckConfigJson { + /// The template with [project_json::RunnableKind::Flycheck] + pub single_template: Option, +} + +impl FlycheckConfigJson { + pub(crate) fn any_configured(&self) -> bool { + // self.workspace_template.is_some() || + self.single_template.is_some() + } +} + +/// The flycheck config from rust-analyzer's own configuration. +/// +/// We rely on this when rust-project.json does not specify a flycheck runnable +/// #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum FlycheckConfig { CargoCommand { @@ -128,7 +147,7 @@ impl fmt::Display for FlycheckConfig { // in the IDE (e.g. in the VS Code status bar). let display_args = args .iter() - .map(|arg| if arg == SAVED_FILE_PLACEHOLDER { "..." } else { arg }) + .map(|arg| if arg == SAVED_FILE_PLACEHOLDER_DOLLAR { "..." } else { arg }) .collect::>(); write!(f, "{command} {}", display_args.join(" ")) @@ -156,6 +175,7 @@ impl FlycheckHandle { generation: Arc, sender: Sender, config: FlycheckConfig, + config_json: FlycheckConfigJson, sysroot_root: Option, workspace_root: AbsPathBuf, manifest_path: Option, @@ -166,6 +186,7 @@ impl FlycheckHandle { generation.load(Ordering::Relaxed), sender, config, + config_json, sysroot_root, workspace_root, manifest_path, @@ -341,6 +362,8 @@ struct FlycheckActor { generation: DiagnosticsGeneration, sender: Sender, config: FlycheckConfig, + config_json: FlycheckConfigJson, + manifest_path: Option, ws_target_dir: Option, /// Either the workspace root of the workspace we are flychecking, @@ -373,7 +396,66 @@ enum Event { CheckEvent(Option), } -pub(crate) const SAVED_FILE_PLACEHOLDER: &str = "$saved_file"; +/// This is stable behaviour. Don't change. +const SAVED_FILE_PLACEHOLDER_DOLLAR: &str = "$saved_file"; +const LABEL_INLINE: &str = "{label}"; +const SAVED_FILE_INLINE: &str = "{saved_file}"; + +struct Substitutions<'a> { + label: Option<&'a str>, + saved_file: Option<&'a str>, +} + +impl<'a> Substitutions<'a> { + /// If you have a runnable, and it has {label} in it somewhere, treat it as a template that + /// may be unsatisfied if you do not provide a label to substitute into it. Returns None in + /// that situation. Otherwise performs the requested substitutions. + /// + /// Same for {saved_file}. + /// + #[allow(clippy::disallowed_types)] /* generic parameter allows for FxHashMap */ + fn substitute( + self, + template: &project_json::Runnable, + extra_env: &std::collections::HashMap, H>, + ) -> Option { + let mut cmd = toolchain::command(&template.program, &template.cwd, extra_env); + for arg in &template.args { + if let Some(ix) = arg.find(LABEL_INLINE) { + if let Some(label) = self.label { + let mut arg = arg.to_string(); + arg.replace_range(ix..ix + LABEL_INLINE.len(), label); + cmd.arg(arg); + continue; + } else { + return None; + } + } + if let Some(ix) = arg.find(SAVED_FILE_INLINE) { + if let Some(saved_file) = self.saved_file { + let mut arg = arg.to_string(); + arg.replace_range(ix..ix + SAVED_FILE_INLINE.len(), saved_file); + cmd.arg(arg); + continue; + } else { + return None; + } + } + // Legacy syntax: full argument match + if arg == SAVED_FILE_PLACEHOLDER_DOLLAR { + if let Some(saved_file) = self.saved_file { + cmd.arg(saved_file); + continue; + } else { + return None; + } + } + cmd.arg(arg); + } + cmd.current_dir(&template.cwd); + Some(cmd) + } +} impl FlycheckActor { fn new( @@ -381,6 +463,7 @@ impl FlycheckActor { generation: DiagnosticsGeneration, sender: Sender, config: FlycheckConfig, + config_json: FlycheckConfigJson, sysroot_root: Option, workspace_root: AbsPathBuf, manifest_path: Option, @@ -392,6 +475,7 @@ impl FlycheckActor { generation, sender, config, + config_json, sysroot_root, root: Arc::new(workspace_root), scope: FlycheckScope::Workspace, @@ -672,6 +756,29 @@ impl FlycheckActor { self.diagnostics_received = DiagnosticsReceived::No; } + fn explicit_check_command( + &self, + scope: &FlycheckScope, + saved_file: Option<&AbsPath>, + ) -> Option { + let label = match scope { + // We could add a runnable like "RunnableKind::FlycheckWorkspace". But generally + // if you're not running cargo, it's because your workspace is too big to check + // all at once. You can always use `check_overrideCommand` with no {label}. + FlycheckScope::Workspace => return None, + FlycheckScope::Package { package: PackageSpecifier::BuildInfo { label }, .. } => { + label.as_str() + } + FlycheckScope::Package { + package: PackageSpecifier::Cargo { package_id: label }, + .. + } => &label.repr, + }; + let template = self.config_json.single_template.as_ref()?; + let subs = Substitutions { label: Some(label), saved_file: saved_file.map(|x| x.as_str()) }; + subs.substitute(template, &FxHashMap::default()) + } + /// Construct a `Command` object for checking the user's code. If the user /// has specified a custom command with placeholders that we cannot fill, /// return None. @@ -683,6 +790,20 @@ impl FlycheckActor { ) -> Option { match &self.config { FlycheckConfig::CargoCommand { command, options, ansi_color_output } => { + // Only use the rust-project.json's flycheck config when no check_overrideCommand + // is configured. In the FlycheckConcig::CustomCommand branch we will still do + // label substitution, but on the overrideCommand instead. + // + // There needs to be SOME way to override what your discoverConfig tool says, + // because to change the flycheck runnable there you may have to literally + // recompile the tool. + if self.config_json.any_configured() { + // Completely handle according to rust-project.json. + // We don't consider this to be "using cargo" so we will not apply any of the + // CargoOptions to the command. + return self.explicit_check_command(scope, saved_file); + } + let mut cmd = toolchain::command(Tool::Cargo.path(), &*self.root, &options.extra_env); if let Some(sysroot_root) = &self.sysroot_root @@ -757,7 +878,7 @@ impl FlycheckActor { // we're saving a file, replace the placeholder in the arguments. if let Some(saved_file) = saved_file { for arg in args { - if arg == SAVED_FILE_PLACEHOLDER { + if arg == SAVED_FILE_PLACEHOLDER_DOLLAR { cmd.arg(saved_file); } else { cmd.arg(arg); @@ -765,7 +886,7 @@ impl FlycheckActor { } } else { for arg in args { - if arg == SAVED_FILE_PLACEHOLDER { + if arg == SAVED_FILE_PLACEHOLDER_DOLLAR { // The custom command has a $saved_file placeholder, // but we had an IDE event that wasn't a file save. Do nothing. return None; @@ -837,3 +958,100 @@ enum JsonMessage { Cargo(cargo_metadata::Message), Rustc(Diagnostic), } + +#[cfg(test)] +mod tests { + use ide_db::FxHashMap; + use itertools::Itertools; + use paths::Utf8Path; + use project_model::project_json; + + use crate::flycheck::Substitutions; + + #[test] + fn test_substitutions() { + let label = ":label"; + let saved_file = "file.rs"; + + // Runnable says it needs both; you need both. + assert_eq!(test_substitute(None, None, "{label} {saved_file}").as_deref(), None); + assert_eq!(test_substitute(Some(label), None, "{label} {saved_file}").as_deref(), None); + assert_eq!( + test_substitute(None, Some(saved_file), "{label} {saved_file}").as_deref(), + None + ); + assert_eq!( + test_substitute(Some(label), Some(saved_file), "{label} {saved_file}").as_deref(), + Some("build :label file.rs") + ); + + // Only need label? only need label. + assert_eq!(test_substitute(None, None, "{label}").as_deref(), None); + assert_eq!(test_substitute(Some(label), None, "{label}").as_deref(), Some("build :label"),); + assert_eq!(test_substitute(None, Some(saved_file), "{label}").as_deref(), None,); + assert_eq!( + test_substitute(Some(label), Some(saved_file), "{label}").as_deref(), + Some("build :label"), + ); + + // Only need saved_file + assert_eq!(test_substitute(None, None, "{saved_file}").as_deref(), None); + assert_eq!(test_substitute(Some(label), None, "{saved_file}").as_deref(), None); + assert_eq!( + test_substitute(None, Some(saved_file), "{saved_file}").as_deref(), + Some("build file.rs") + ); + assert_eq!( + test_substitute(Some(label), Some(saved_file), "{saved_file}").as_deref(), + Some("build file.rs") + ); + + // Need neither + assert_eq!(test_substitute(None, None, "xxx").as_deref(), Some("build xxx")); + assert_eq!(test_substitute(Some(label), None, "xxx").as_deref(), Some("build xxx")); + assert_eq!(test_substitute(None, Some(saved_file), "xxx").as_deref(), Some("build xxx")); + assert_eq!( + test_substitute(Some(label), Some(saved_file), "xxx").as_deref(), + Some("build xxx") + ); + + // {label} mid-argument substitution + assert_eq!( + test_substitute(Some(label), None, "--label={label}").as_deref(), + Some("build --label=:label") + ); + + // {saved_file} mid-argument substitution + assert_eq!( + test_substitute(None, Some(saved_file), "--saved={saved_file}").as_deref(), + Some("build --saved=file.rs") + ); + + // $saved_file legacy support (no mid-argument substitution, we never supported that) + assert_eq!( + test_substitute(None, Some(saved_file), "$saved_file").as_deref(), + Some("build file.rs") + ); + + fn test_substitute( + label: Option<&str>, + saved_file: Option<&str>, + args: &str, + ) -> Option { + Substitutions { label, saved_file } + .substitute( + &project_json::Runnable { + program: "build".to_owned(), + args: Vec::from_iter(args.split_whitespace().map(ToOwned::to_owned)), + cwd: Utf8Path::new("/path").to_owned(), + kind: project_json::RunnableKind::Flycheck, + }, + &FxHashMap::default(), + ) + .map(|command| { + command.get_args().map(|x| x.to_string_lossy()).collect_vec().join(" ") + }) + .map(|args| format!("build {}", args)) + } + } +} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index e3a5ee221973..0a16b7a5614c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -25,7 +25,9 @@ use load_cargo::{ProjectFolders, load_proc_macro}; use lsp_types::FileSystemWatcher; use paths::Utf8Path; use proc_macro_api::ProcMacroClient; -use project_model::{ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, WorkspaceBuildScripts}; +use project_model::{ + ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, WorkspaceBuildScripts, project_json, +}; use stdx::{format_to, thread::ThreadIntent}; use triomphe::Arc; use vfs::{AbsPath, AbsPathBuf, ChangeKind}; @@ -875,6 +877,7 @@ impl GlobalState { generation.clone(), sender.clone(), config, + crate::flycheck::FlycheckConfigJson::default(), None, self.config.root_path().clone(), None, @@ -894,16 +897,25 @@ impl GlobalState { cargo: Some((cargo, _, _)), .. } => ( + crate::flycheck::FlycheckConfigJson::default(), cargo.workspace_root(), Some(cargo.manifest_path()), Some(cargo.target_directory()), ), ProjectWorkspaceKind::Json(project) => { + let config_json = crate::flycheck::FlycheckConfigJson { + single_template: project + .runnable_template(project_json::RunnableKind::Flycheck) + .cloned(), + }; // Enable flychecks for json projects if a custom flycheck command was supplied // in the workspace configuration. match config { + _ if config_json.any_configured() => { + (config_json, project.path(), None, None) + } FlycheckConfig::CustomCommand { .. } => { - (project.path(), None, None) + (config_json, project.path(), None, None) } _ => return None, } @@ -913,12 +925,13 @@ impl GlobalState { ws.sysroot.root().map(ToOwned::to_owned), )) }) - .map(|(id, (root, manifest_path, target_dir), sysroot_root)| { + .map(|(id, (config_json, root, manifest_path, target_dir), sysroot_root)| { FlycheckHandle::spawn( id, generation.clone(), sender.clone(), config.clone(), + config_json, sysroot_root, root.to_path_buf(), manifest_path.map(|it| it.to_path_buf()), From 7f608da06af36c0c21b6119959e47d9480ccb18a Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 4 Sep 2024 13:52:59 +1000 Subject: [PATCH 1720/3801] flycheck: Support {label} in check_overrideCommand as well as $saved_file --- .../crates/rust-analyzer/src/flycheck.rs | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 1b1e3344e25f..cf4ab29b8649 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -872,29 +872,23 @@ impl FlycheckActor { &*self.root } }; - let mut cmd = toolchain::command(command, root, extra_env); + let runnable = project_json::Runnable { + program: command.clone(), + cwd: Utf8Path::to_owned(root.as_ref()), + args: args.clone(), + kind: project_json::RunnableKind::Flycheck, + }; - // If the custom command has a $saved_file placeholder, and - // we're saving a file, replace the placeholder in the arguments. - if let Some(saved_file) = saved_file { - for arg in args { - if arg == SAVED_FILE_PLACEHOLDER_DOLLAR { - cmd.arg(saved_file); - } else { - cmd.arg(arg); - } - } - } else { - for arg in args { - if arg == SAVED_FILE_PLACEHOLDER_DOLLAR { - // The custom command has a $saved_file placeholder, - // but we had an IDE event that wasn't a file save. Do nothing. - return None; - } + let label = match scope { + FlycheckScope::Workspace => None, + // We support substituting both build labels (e.g. buck, bazel) and cargo package ids. + // With cargo package ids, you get `cargo check -p path+file:///path/to/rust-analyzer/crates/hir#0.0.0`. + // That does work! + FlycheckScope::Package { package, .. } => Some(package.as_str()), + }; - cmd.arg(arg); - } - } + let subs = Substitutions { label, saved_file: saved_file.map(|x| x.as_str()) }; + let cmd = subs.substitute(&runnable, extra_env)?; Some(cmd) } From 4e61c6052124c2e71403973cc3adb34c4ee5454d Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 4 Sep 2024 13:52:59 +1000 Subject: [PATCH 1721/3801] flycheck: Always flycheck single crate if there is a build label from rust-project.json This requires us to add $saved_file / {saved_file} interpolation back to restart_for_package. Otherwise we break existing users of $saved_file. No grand reason why we can't delete saved_file later, although I would just leave it because sometimes a build system might really know better which target(s) to build, including multiple targets. --- .../rust-analyzer/crates/rust-analyzer/src/flycheck.rs | 3 ++- .../crates/rust-analyzer/src/handlers/notification.rs | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index cf4ab29b8649..57ad774b1850 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -219,13 +219,14 @@ impl FlycheckHandle { package: PackageSpecifier, target: Option, workspace_deps: Option>, + saved_file: Option, ) { let generation = self.generation.fetch_add(1, Ordering::Relaxed) + 1; self.sender .send(StateChange::Restart { generation, scope: FlycheckScope::Package { package, workspace_deps }, - saved_file: None, + saved_file, target, }) .unwrap(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs index 57adbbfe72a7..d95601043330 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs @@ -328,6 +328,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { } InvocationStrategy::PerWorkspace => { Box::new(move || { + let saved_file = vfs_path.as_path().map(ToOwned::to_owned); let target = TargetSpec::for_file(&world, file_id)?.map(|it| { let tgt_kind = it.target_kind(); let (tgt_name, root, package) = match it { @@ -362,8 +363,10 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { if let Some((target, root, package)) = target { // trigger a package check if we have a non-library target as that can't affect // anything else in the workspace OR if we're not allowed to check the workspace as - // the user opted into package checks then - let package_check_allowed = target.is_some() || !may_flycheck_workspace; + // the user opted into package checks then OR if this is not cargo. + let package_check_allowed = target.is_some() + || !may_flycheck_workspace + || matches!(package, PackageSpecifier::BuildInfo { .. }); if package_check_allowed { package_workspace_idx = world.workspaces.iter().position(|ws| match &ws.kind { @@ -390,6 +393,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { package, target, workspace_deps, + saved_file.clone(), ); } } @@ -460,7 +464,6 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { ws_contains_file && !is_pkg_ws }); - let saved_file = vfs_path.as_path().map(ToOwned::to_owned); let mut workspace_check_triggered = false; // Find and trigger corresponding flychecks 'flychecks: for flycheck in world.flycheck.iter() { From 778de45547f9a584894fad295c86539e7c57aa9d Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 4 Sep 2024 13:52:59 +1000 Subject: [PATCH 1722/3801] flycheck: Add display_command to pretty-print flycheck command being run in a notification --- .../crates/rust-analyzer/src/flycheck.rs | 82 +++++++++++++++++++ .../rust-analyzer/crates/toolchain/src/lib.rs | 3 + 2 files changed, 85 insertions(+) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 57ad774b1850..7f814121e909 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -22,6 +22,7 @@ use serde_derive::Deserialize; pub(crate) use cargo_metadata::diagnostic::{ Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan, }; +use toolchain::DISPLAY_COMMAND_IGNORE_ENVS; use toolchain::Tool; use triomphe::Arc; @@ -954,6 +955,54 @@ enum JsonMessage { Rustc(Diagnostic), } +/// Not good enough to execute in a shell, but good enough to show the user without all the noisy +/// quotes +/// +/// Pass implicit_cwd if there is one regarded as the obvious by the user, so we can skip showing it. +/// Compactness is the aim of the game, the output typically gets truncated quite a lot. +fn display_command(c: &Command, implicit_cwd: Option<&std::path::Path>) -> String { + let mut o = String::new(); + use std::fmt::Write; + let lossy = std::ffi::OsStr::to_string_lossy; + if let Some(dir) = c.get_current_dir() { + if Some(dir) == implicit_cwd.map(std::path::Path::new) { + // pass + } else if dir.to_string_lossy().contains(" ") { + write!(o, "cd {:?} && ", dir).unwrap(); + } else { + write!(o, "cd {} && ", dir.display()).unwrap(); + } + } + for (env, val) in c.get_envs() { + let (env, val) = (lossy(env), val.map(lossy).unwrap_or(std::borrow::Cow::Borrowed(""))); + if DISPLAY_COMMAND_IGNORE_ENVS.contains(&env.as_ref()) { + continue; + } + if env.contains(" ") { + write!(o, "\"{}={}\" ", env, val).unwrap(); + } else if val.contains(" ") { + write!(o, "{}=\"{}\" ", env, val).unwrap(); + } else { + write!(o, "{}={} ", env, val).unwrap(); + } + } + let prog = lossy(c.get_program()); + if prog.contains(" ") { + write!(o, "{:?}", prog).unwrap(); + } else { + write!(o, "{}", prog).unwrap(); + } + for arg in c.get_args() { + let arg = lossy(arg); + if arg.contains(" ") { + write!(o, " \"{}\"", arg).unwrap(); + } else { + write!(o, " {}", arg).unwrap(); + } + } + o +} + #[cfg(test)] mod tests { use ide_db::FxHashMap; @@ -962,6 +1011,7 @@ mod tests { use project_model::project_json; use crate::flycheck::Substitutions; + use crate::flycheck::display_command; #[test] fn test_substitutions() { @@ -1049,4 +1099,36 @@ mod tests { .map(|args| format!("build {}", args)) } } + + #[test] + fn test_display_command() { + use std::path::Path; + let workdir = Path::new("workdir"); + let mut cmd = toolchain::command("command", workdir, &FxHashMap::default()); + assert_eq!(display_command(cmd.arg("--arg"), Some(workdir)), "command --arg"); + assert_eq!( + display_command(cmd.arg("spaced arg"), Some(workdir)), + "command --arg \"spaced arg\"" + ); + assert_eq!( + display_command(cmd.env("ENVIRON", "yeah"), Some(workdir)), + "ENVIRON=yeah command --arg \"spaced arg\"" + ); + assert_eq!( + display_command(cmd.env("OTHER", "spaced env"), Some(workdir)), + "ENVIRON=yeah OTHER=\"spaced env\" command --arg \"spaced arg\"" + ); + assert_eq!( + display_command(cmd.current_dir("/tmp"), Some(workdir)), + "cd /tmp && ENVIRON=yeah OTHER=\"spaced env\" command --arg \"spaced arg\"" + ); + assert_eq!( + display_command(cmd.current_dir("/tmp and/thing"), Some(workdir)), + "cd \"/tmp and/thing\" && ENVIRON=yeah OTHER=\"spaced env\" command --arg \"spaced arg\"" + ); + assert_eq!( + display_command(cmd.current_dir("/tmp and/thing"), Some(Path::new("/tmp and/thing"))), + "ENVIRON=yeah OTHER=\"spaced env\" command --arg \"spaced arg\"" + ); + } } diff --git a/src/tools/rust-analyzer/crates/toolchain/src/lib.rs b/src/tools/rust-analyzer/crates/toolchain/src/lib.rs index 39319886cfe4..1a1726983870 100644 --- a/src/tools/rust-analyzer/crates/toolchain/src/lib.rs +++ b/src/tools/rust-analyzer/crates/toolchain/src/lib.rs @@ -74,6 +74,9 @@ impl Tool { // Prevent rustup from automatically installing toolchains, see https://github.com/rust-lang/rust-analyzer/issues/20719. pub const NO_RUSTUP_AUTO_INSTALL_ENV: (&str, &str) = ("RUSTUP_AUTO_INSTALL", "0"); +// These get ignored when displaying what command is running in LSP status messages. +pub const DISPLAY_COMMAND_IGNORE_ENVS: &[&str] = &[NO_RUSTUP_AUTO_INSTALL_ENV.0]; + #[allow(clippy::disallowed_types)] /* generic parameter allows for FxHashMap */ pub fn command( cmd: impl AsRef, From 53a371c505a00be220aca18dfba091ee2b2d8f31 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 4 Sep 2024 13:52:59 +1000 Subject: [PATCH 1723/3801] flycheck: notifications show full command when configured in a rust-project.json runnable For JSON / override users, pretty-print the custom flycheck command with fewer quote characters Better debug logging in flycheck --- .../crates/rust-analyzer/src/flycheck.rs | 52 ++++++++++++++----- .../crates/rust-analyzer/src/global_state.rs | 2 + .../crates/rust-analyzer/src/main_loop.rs | 27 +++++++--- .../crates/rust-analyzer/src/reload.rs | 1 + 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 7f814121e909..6dcae76c9354 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -309,13 +309,18 @@ impl fmt::Debug for FlycheckMessage { #[derive(Debug)] pub(crate) enum Progress { - DidStart, + DidStart { + /// The user sees this in VSCode, etc. May be a shortened version of the command we actually + /// executed, otherwise it is way too long. + user_facing_command: String, + }, DidCheckCrate(String), DidFinish(io::Result<()>), DidCancel, DidFailToRestart(String), } +#[derive(Debug, Clone)] enum FlycheckScope { Workspace, Package { @@ -346,6 +351,16 @@ impl PackageSpecifier { } } +#[derive(Debug)] +enum FlycheckCommandOrigin { + /// Regular cargo invocation + Cargo, + /// Configured via check_overrideCommand + CheckOverrideCommand, + /// From a runnable with [project_json::RunnableKind::Flycheck] + ProjectJsonRunnable, +} + enum StateChange { Restart { generation: DiagnosticsGeneration, @@ -529,16 +544,28 @@ impl FlycheckActor { } let command = self.check_command(&scope, saved_file.as_deref(), target); - self.scope = scope; + self.scope = scope.clone(); self.generation = generation; - let Some(command) = command else { + let Some((command, origin)) = command else { + tracing::debug!(?scope, "failed to build flycheck command"); continue; }; - let formatted_command = format!("{command:?}"); + let debug_command = format!("{command:?}"); + let user_facing_command = match origin { + // Don't show all the --format=json-with-blah-blah args, just the simple + // version + FlycheckCommandOrigin::Cargo => self.config.to_string(), + // show them the full command but pretty printed. advanced user + FlycheckCommandOrigin::ProjectJsonRunnable + | FlycheckCommandOrigin::CheckOverrideCommand => display_command( + &command, + Some(std::path::Path::new(self.root.as_path())), + ), + }; - tracing::debug!(?command, "will restart flycheck"); + tracing::debug!(?origin, ?command, "will restart flycheck"); let (sender, receiver) = unbounded(); match CommandHandle::spawn( command, @@ -575,14 +602,14 @@ impl FlycheckActor { }, ) { Ok(command_handle) => { - tracing::debug!(command = formatted_command, "did restart flycheck"); + tracing::debug!(?origin, command = %debug_command, "did restart flycheck"); self.command_handle = Some(command_handle); self.command_receiver = Some(receiver); - self.report_progress(Progress::DidStart); + self.report_progress(Progress::DidStart { user_facing_command }); } Err(error) => { self.report_progress(Progress::DidFailToRestart(format!( - "Failed to run the following command: {formatted_command} error={error}" + "Failed to run the following command: {debug_command} origin={origin:?} error={error}" ))); } } @@ -789,7 +816,7 @@ impl FlycheckActor { scope: &FlycheckScope, saved_file: Option<&AbsPath>, target: Option, - ) -> Option { + ) -> Option<(Command, FlycheckCommandOrigin)> { match &self.config { FlycheckConfig::CargoCommand { command, options, ansi_color_output } => { // Only use the rust-project.json's flycheck config when no check_overrideCommand @@ -803,7 +830,8 @@ impl FlycheckActor { // Completely handle according to rust-project.json. // We don't consider this to be "using cargo" so we will not apply any of the // CargoOptions to the command. - return self.explicit_check_command(scope, saved_file); + let cmd = self.explicit_check_command(scope, saved_file)?; + return Some((cmd, FlycheckCommandOrigin::ProjectJsonRunnable)); } let mut cmd = @@ -864,7 +892,7 @@ impl FlycheckActor { self.ws_target_dir.as_ref().map(Utf8PathBuf::as_path), ); cmd.args(&options.extra_args); - Some(cmd) + Some((cmd, FlycheckCommandOrigin::Cargo)) } FlycheckConfig::CustomCommand { command, args, extra_env, invocation_strategy } => { let root = match invocation_strategy { @@ -892,7 +920,7 @@ impl FlycheckActor { let subs = Substitutions { label, saved_file: saved_file.map(|x| x.as_str()) }; let cmd = subs.substitute(&runnable, extra_env)?; - Some(cmd) + Some((cmd, FlycheckCommandOrigin::CheckOverrideCommand)) } } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 0cfd0a141bae..39b4aaa64738 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -112,6 +112,7 @@ pub(crate) struct GlobalState { pub(crate) flycheck_sender: Sender, pub(crate) flycheck_receiver: Receiver, pub(crate) last_flycheck_error: Option, + pub(crate) flycheck_formatted_commands: Vec, // Test explorer pub(crate) test_run_session: Option>, @@ -288,6 +289,7 @@ impl GlobalState { flycheck_sender, flycheck_receiver, last_flycheck_error: None, + flycheck_formatted_commands: vec![], test_run_session: None, test_run_sender, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index dd0813c14454..62a3b3a17bdf 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -1179,8 +1179,24 @@ impl GlobalState { kind: ClearDiagnosticsKind::OlderThan(generation, ClearScope::Package(package_id)), } => self.diagnostics.clear_check_older_than_for_package(id, package_id, generation), FlycheckMessage::Progress { id, progress } => { + let format_with_id = |user_facing_command: String| { + if self.flycheck.len() == 1 { + user_facing_command + } else { + format!("{user_facing_command} (#{})", id + 1) + } + }; + + self.flycheck_formatted_commands + .resize_with(self.flycheck.len().max(id + 1), || { + format_with_id(self.config.flycheck(None).to_string()) + }); + let (state, message) = match progress { - flycheck::Progress::DidStart => (Progress::Begin, None), + flycheck::Progress::DidStart { user_facing_command } => { + self.flycheck_formatted_commands[id] = format_with_id(user_facing_command); + (Progress::Begin, None) + } flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)), flycheck::Progress::DidCancel => { self.last_flycheck_error = None; @@ -1200,13 +1216,8 @@ impl GlobalState { } }; - // When we're running multiple flychecks, we have to include a disambiguator in - // the title, or the editor complains. Note that this is a user-facing string. - let title = if self.flycheck.len() == 1 { - format!("{}", self.config.flycheck(None)) - } else { - format!("{} (#{})", self.config.flycheck(None), id + 1) - }; + // Clone because we &mut self for report_progress + let title = self.flycheck_formatted_commands[id].clone(); self.report_progress( &title, state, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 0a16b7a5614c..ccafbd7b30b9 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -942,6 +942,7 @@ impl GlobalState { } } .into(); + self.flycheck_formatted_commands = vec![]; } } From 3fdb78cba695824cba5be894a032779c9b4a4ac3 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 3 Dec 2025 11:34:58 +1100 Subject: [PATCH 1724/3801] flycheck: Rename FlycheckConfig::CargoCommand to Automatic Because (1) it is what we use when there is no relevant config (2) we automatically use either rust-project.json's flycheck, or cargo This also puts check_command config into CargoOptions. It's a cargo option, after all. --- .../crates/rust-analyzer/src/config.rs | 20 ++++++----- .../crates/rust-analyzer/src/flycheck.rs | 36 ++++++++++++------- .../crates/rust-analyzer/src/test_runner.rs | 2 +- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index e39569e108de..c2f7ada8c8ca 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -2431,6 +2431,8 @@ impl Config { pub(crate) fn cargo_test_options(&self, source_root: Option) -> CargoOptions { CargoOptions { + // Might be nice to allow users to specify test_command = "nextest" + subcommand: "test".into(), target_tuples: self.cargo_target(source_root).clone().into_iter().collect(), all_targets: false, no_default_features: *self.cargo_noDefaultFeatures(source_root), @@ -2464,9 +2466,9 @@ impl Config { }, } } - Some(_) | None => FlycheckConfig::CargoCommand { - command: self.check_command(source_root).clone(), - options: CargoOptions { + Some(_) | None => FlycheckConfig::Automatic { + cargo_options: CargoOptions { + subcommand: self.check_command(source_root).clone(), target_tuples: self .check_targets(source_root) .clone() @@ -4171,8 +4173,8 @@ mod tests { assert_eq!(config.cargo_targetDir(None), &None); assert!(matches!( config.flycheck(None), - FlycheckConfig::CargoCommand { - options: CargoOptions { target_dir_config: TargetDirectoryConfig::None, .. }, + FlycheckConfig::Automatic { + cargo_options: CargoOptions { target_dir_config: TargetDirectoryConfig::None, .. }, .. } )); @@ -4195,8 +4197,8 @@ mod tests { Utf8PathBuf::from(std::env::var("CARGO_TARGET_DIR").unwrap_or("target".to_owned())); assert!(matches!( config.flycheck(None), - FlycheckConfig::CargoCommand { - options: CargoOptions { target_dir_config, .. }, + FlycheckConfig::Automatic { + cargo_options: CargoOptions { target_dir_config, .. }, .. } if target_dir_config.target_dir(Some(&ws_target_dir)).map(Cow::into_owned) == Some(ws_target_dir.join("rust-analyzer")) @@ -4221,8 +4223,8 @@ mod tests { ); assert!(matches!( config.flycheck(None), - FlycheckConfig::CargoCommand { - options: CargoOptions { target_dir_config, .. }, + FlycheckConfig::Automatic { + cargo_options: CargoOptions { target_dir_config, .. }, .. } if target_dir_config.target_dir(None).map(Cow::into_owned) == Some(Utf8PathBuf::from("other_folder")) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 6dcae76c9354..512c231990cb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -38,8 +38,11 @@ pub(crate) enum InvocationStrategy { PerWorkspace, } +/// Data needed to construct a `cargo` command invocation, e.g. for flycheck or running a test. #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct CargoOptions { + /// The cargo subcommand to run, e.g. "check" or "clippy" + pub(crate) subcommand: String, pub(crate) target_tuples: Vec, pub(crate) all_targets: bool, pub(crate) set_test: bool, @@ -111,11 +114,16 @@ impl FlycheckConfigJson { /// #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum FlycheckConfig { - CargoCommand { - command: String, - options: CargoOptions, + /// Automatically use rust-project.json's flycheck runnable or just use cargo (the common case) + /// + /// We can't have a variant for ProjectJson because that is configured on the fly during + /// discoverConfig. We only know what we can read at config time. + Automatic { + /// If we do use cargo, how to build the check command + cargo_options: CargoOptions, ansi_color_output: bool, }, + /// check_overrideCommand. This overrides both cargo and rust-project.json's flycheck runnable. CustomCommand { command: String, args: Vec, @@ -127,7 +135,7 @@ pub(crate) enum FlycheckConfig { impl FlycheckConfig { pub(crate) fn invocation_strategy(&self) -> InvocationStrategy { match self { - FlycheckConfig::CargoCommand { .. } => InvocationStrategy::PerWorkspace, + FlycheckConfig::Automatic { .. } => InvocationStrategy::PerWorkspace, FlycheckConfig::CustomCommand { invocation_strategy, .. } => { invocation_strategy.clone() } @@ -138,7 +146,9 @@ impl FlycheckConfig { impl fmt::Display for FlycheckConfig { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - FlycheckConfig::CargoCommand { command, .. } => write!(f, "cargo {command}"), + FlycheckConfig::Automatic { cargo_options, .. } => { + write!(f, "cargo {}", cargo_options.subcommand) + } FlycheckConfig::CustomCommand { command, args, .. } => { // Don't show `my_custom_check --foo $saved_file` literally to the user, as it // looks like we've forgotten to substitute $saved_file. @@ -572,11 +582,11 @@ impl FlycheckActor { CargoCheckParser, sender, match &self.config { - FlycheckConfig::CargoCommand { options, .. } => { + FlycheckConfig::Automatic { cargo_options, .. } => { let ws_target_dir = self.ws_target_dir.as_ref().map(Utf8PathBuf::as_path); let target_dir = - options.target_dir_config.target_dir(ws_target_dir); + cargo_options.target_dir_config.target_dir(ws_target_dir); // If `"rust-analyzer.cargo.targetDir": null`, we should use // workspace's target dir instead of hard-coded fallback. @@ -818,7 +828,7 @@ impl FlycheckActor { target: Option, ) -> Option<(Command, FlycheckCommandOrigin)> { match &self.config { - FlycheckConfig::CargoCommand { command, options, ansi_color_output } => { + FlycheckConfig::Automatic { cargo_options, ansi_color_output } => { // Only use the rust-project.json's flycheck config when no check_overrideCommand // is configured. In the FlycheckConcig::CustomCommand branch we will still do // label substitution, but on the overrideCommand instead. @@ -835,15 +845,15 @@ impl FlycheckActor { } let mut cmd = - toolchain::command(Tool::Cargo.path(), &*self.root, &options.extra_env); + toolchain::command(Tool::Cargo.path(), &*self.root, &cargo_options.extra_env); if let Some(sysroot_root) = &self.sysroot_root - && !options.extra_env.contains_key("RUSTUP_TOOLCHAIN") + && !cargo_options.extra_env.contains_key("RUSTUP_TOOLCHAIN") && std::env::var_os("RUSTUP_TOOLCHAIN").is_none() { cmd.env("RUSTUP_TOOLCHAIN", AsRef::::as_ref(sysroot_root)); } cmd.env("CARGO_LOG", "cargo::core::compiler::fingerprint=info"); - cmd.arg(command); + cmd.arg(&cargo_options.subcommand); match scope { FlycheckScope::Workspace => cmd.arg("--workspace"), @@ -887,11 +897,11 @@ impl FlycheckActor { cmd.arg("--keep-going"); - options.apply_on_command( + cargo_options.apply_on_command( &mut cmd, self.ws_target_dir.as_ref().map(Utf8PathBuf::as_path), ); - cmd.args(&options.extra_args); + cmd.args(&cargo_options.extra_args); Some((cmd, FlycheckCommandOrigin::Cargo)) } FlycheckConfig::CustomCommand { command, args, extra_env, invocation_strategy } => { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs index 7111a15d0246..f0020f9088e3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs @@ -105,7 +105,7 @@ impl CargoTestHandle { let mut cmd = toolchain::command(Tool::Cargo.path(), root, &options.extra_env); cmd.env("RUSTC_BOOTSTRAP", "1"); cmd.arg("--color=always"); - cmd.arg("test"); + cmd.arg(&options.subcommand); // test, usually cmd.arg("--package"); cmd.arg(&test_target.package); From 2d581773fed793f9d62b190e56374065d37291d7 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 3 Dec 2025 12:03:05 +1100 Subject: [PATCH 1725/3801] Fix RunnableKind::Run label interpolation It was pretty useless without this. Previously: Parsing target pattern `{label}` Caused by: Invalid target name `{label}`. (...) Build ID: 6dab5942-d81c-4430-83b0-5ba523999050 Network: Up: 0B Down: 0B Command: run. Time elapsed: 0.3s BUILD FAILED * The terminal process "buck2 'run', '{label}'" terminated with exit code: 3. --- .../crates/rust-analyzer/src/target_spec.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index 8452b6493e87..b8d9acc02a32 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -77,7 +77,16 @@ impl ProjectJsonTargetSpec { RunnableKind::Bin => { for runnable in &self.shell_runnables { if matches!(runnable.kind, project_model::project_json::RunnableKind::Run) { - return Some(runnable.clone()); + let mut runnable = runnable.clone(); + + let replaced_args: Vec<_> = runnable + .args + .iter() + .map(|arg| arg.replace("{label}", &self.label)) + .collect(); + runnable.args = replaced_args; + + return Some(runnable); } } From 71e2ded9fb196bc9b4a1736759f9465f5d4d9619 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 3 Dec 2025 13:32:03 +1100 Subject: [PATCH 1726/3801] doc: Update docs for runnables to include run/flycheck --- .../crates/project-model/src/project_json.rs | 3 +++ .../docs/book/src/non_cargo_based_projects.md | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index 536f170e1192..6938010cbd70 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -357,9 +357,12 @@ pub enum RunnableKind { Check, /// Can run a binary. + /// May include {label} which will get the label from the `build` section of a crate. Run, /// Run a single test. + /// May include {label} which will get the label from the `build` section of a crate. + /// May include {test_id} which will get the test clicked on by the user. TestOne, /// Template for checking a target, emitting rustc JSON diagnostics. diff --git a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md index e7df4a5d7668..d8be9a82d0c9 100644 --- a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md +++ b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md @@ -204,16 +204,25 @@ interface Runnable { args: string[]; /// The current working directory of the runnable. cwd: string; - /// Used to decide what code lens to offer. + /// Maps a runnable to a piece of rust-analyzer functionality. /// - /// `testOne`: This runnable will be used when the user clicks the 'Run Test' - /// CodeLens above a test. + /// - `testOne`: This runnable will be used when the user clicks the 'Run Test' + /// CodeLens above a test. + /// - `run`: This runnable will be used when the user clicks the 'Run' CodeLens + /// above a main function or triggers a run command. + /// - `flycheck`: This is run to provide check-on-save diagnostics when the user + /// saves a file. It must emit rustc JSON diagnostics that rust-analyzer can + /// parse. If this runnable is not specified, we may try to use `cargo check -p`. + /// This is only run for a single crate that the user saved a file in. The + /// {label} syntax is replaced with `BuildInfo::label`. + /// Alternatively, you may use `{saved_file}` and figure out which crate + /// to produce diagnostics for based on that. /// /// The args for testOne can contain two template strings: /// `{label}` and `{test_id}`. `{label}` will be replaced - /// with the `Build::label` and `{test_id}` will be replaced + /// with the `BuildInfo::label` and `{test_id}` will be replaced /// with the test name. - kind: 'testOne' | string; + kind: 'testOne' | 'run' | 'flycheck' | string; } ``` From 422597f76395060d968fcb5c9e7de311bf1dc9a4 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 3 Dec 2025 14:44:40 +1100 Subject: [PATCH 1727/3801] doc: make example for workspace.discoverConfig actually work rust-project requires {arg} these days. No good giving people bad information even if it's not crucial to documenting this. --- .../rust-analyzer/crates/rust-analyzer/src/config.rs | 9 +++++---- .../docs/book/src/configuration_generated.md | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index c2f7ada8c8ca..2b7ade6c26ef 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -480,8 +480,8 @@ config_data! { /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. /// - /// [`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`. - /// `progress_label` is used for the title in progress indicators, whereas `files_to_watch` + /// [`DiscoverWorkspaceConfig`] also requires setting `progressLabel` and `filesToWatch`. + /// `progressLabel` is used for the title in progress indicators, whereas `filesToWatch` /// is used to determine which build system-specific files should be watched in order to /// reload rust-analyzer. /// @@ -490,9 +490,10 @@ config_data! { /// "rust-analyzer.workspace.discoverConfig": { /// "command": [ /// "rust-project", - /// "develop-json" + /// "develop-json", + /// "{arg}" /// ], - /// "progressLabel": "rust-analyzer", + /// "progressLabel": "buck2/rust-project", /// "filesToWatch": [ /// "BUCK" /// ] diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index 58b636334527..a0738ca0e179 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1623,9 +1623,10 @@ Below is an example of a valid configuration: "rust-analyzer.workspace.discoverConfig": { "command": [ "rust-project", - "develop-json" + "develop-json", + "{arg}" ], - "progressLabel": "rust-analyzer", + "progressLabel": "buck2/rust-project", "filesToWatch": [ "BUCK" ] From f06a6b9fdcb9db492a364b48a08f70afa98da182 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Wed, 3 Dec 2025 17:11:16 +1100 Subject: [PATCH 1728/3801] doc: overhaul non-cargo build system docs --- .../crates/rust-analyzer/src/config.rs | 18 ++- .../docs/book/src/configuration_generated.md | 22 ++-- .../docs/book/src/non_cargo_based_projects.md | 105 +++++++++++++++--- .../rust-analyzer/editors/code/package.json | 4 +- 4 files changed, 120 insertions(+), 29 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 2b7ade6c26ef..28ac94e4deb6 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -500,7 +500,7 @@ config_data! { /// } /// ``` /// - /// ## On `DiscoverWorkspaceConfig::command` + /// ## Workspace Discovery Protocol /// /// **Warning**: This format is provisional and subject to change. /// @@ -871,10 +871,18 @@ config_data! { /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten /// by changing `#rust-analyzer.check.invocationStrategy#`. /// - /// If `$saved_file` is part of the command, rust-analyzer will pass - /// the absolute path of the saved file to the provided command. This is - /// intended to be used with non-Cargo build systems. - /// Note that `$saved_file` is experimental and may be removed in the future. + /// It supports two interpolation syntaxes, both mainly intended to be used with + /// [non-Cargo build systems](./non_cargo_based_projects.md): + /// + /// - If `{saved_file}` is part of the command, rust-analyzer will pass + /// the absolute path of the saved file to the provided command. + /// (A previous version, `$saved_file`, also works.) + /// - If `{label}` is part of the command, rust-analyzer will pass the + /// Cargo package ID, which can be used with `cargo check -p`, or a build label from + /// `rust-project.json`. If `{label}` is included, rust-analyzer behaves much like + /// [`"rust-analyzer.check.workspace": false`](#check.workspace). + /// + /// /// /// An example command would be: /// diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index a0738ca0e179..c4124aaae075 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -323,10 +323,18 @@ each of them, with the working directory being the workspace root (i.e., the folder containing the `Cargo.toml`). This can be overwritten by changing `#rust-analyzer.check.invocationStrategy#`. -If `$saved_file` is part of the command, rust-analyzer will pass -the absolute path of the saved file to the provided command. This is -intended to be used with non-Cargo build systems. -Note that `$saved_file` is experimental and may be removed in the future. +It supports two interpolation syntaxes, both mainly intended to be used with +[non-Cargo build systems](./non_cargo_based_projects.md): + +- If `{saved_file}` is part of the command, rust-analyzer will pass + the absolute path of the saved file to the provided command. + (A previous version, `$saved_file`, also works.) +- If `{label}` is part of the command, rust-analyzer will pass the + Cargo package ID, which can be used with `cargo check -p`, or a build label from + `rust-project.json`. If `{label}` is included, rust-analyzer behaves much like + [`"rust-analyzer.check.workspace": false`](#check.workspace). + + An example command would be: @@ -1613,8 +1621,8 @@ Default: `null` Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. -[`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`. -`progress_label` is used for the title in progress indicators, whereas `files_to_watch` +[`DiscoverWorkspaceConfig`] also requires setting `progressLabel` and `filesToWatch`. +`progressLabel` is used for the title in progress indicators, whereas `filesToWatch` is used to determine which build system-specific files should be watched in order to reload rust-analyzer. @@ -1633,7 +1641,7 @@ Below is an example of a valid configuration: } ``` -## On `DiscoverWorkspaceConfig::command` +## Workspace Discovery Protocol **Warning**: This format is provisional and subject to change. diff --git a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md index d8be9a82d0c9..a48b025c7b3a 100644 --- a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md +++ b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md @@ -229,7 +229,15 @@ interface Runnable { This format is provisional and subject to change. Specifically, the `roots` setup will be different eventually. -There are three ways to feed `rust-project.json` to rust-analyzer: +### Providing a JSON project to rust-analyzer + +There are four ways to feed `rust-project.json` to rust-analyzer: + +- Use + [`"rust-analyzer.workspace.discoverConfig": … }`](./configuration.md#workspace.discoverConfig) + to specify a workspace discovery command to generate project descriptions + on-the-fly. Please note that the command output is message-oriented and must + follow [the discovery protocol](./configuration.md#workspace-discovery-protocol). - Place `rust-project.json` file at the root of the project, and rust-analyzer will discover it. @@ -249,19 +257,86 @@ location or (for inline JSON) relative to `rootUri`. You can set the `RA_LOG` environment variable to `rust_analyzer=info` to inspect how rust-analyzer handles config and project loading. -Note that calls to `cargo check` are disabled when using -`rust-project.json` by default, so compilation errors and warnings will -no longer be sent to your LSP client. To enable these compilation errors -you will need to specify explicitly what command rust-analyzer should -run to perform the checks using the -`rust-analyzer.check.overrideCommand` configuration. As an example, the -following configuration explicitly sets `cargo check` as the `check` -command. +### Flycheck support - { "rust-analyzer.check.overrideCommand": ["cargo", "check", "--message-format=json"] } +Rust-analyzer has functionality to run an actual build of a crate when the user saves a file, to +fill in diagnostics it does not implement natively. This is known as "flycheck". -`check.overrideCommand` requires the command specified to output json -error messages for rust-analyzer to consume. The `--message-format=json` -flag does this for `cargo check` so whichever command you use must also -output errors in this format. See the [Configuration](#_configuration) -section for more information. +**Flycheck is disabled when using `rust-project.json` unless explicitly configured**, so compilation +errors and warnings will no longer be sent to your LSP client by default. To enable these +compilation errors you will need to specify explicitly what command rust-analyzer should run to +perform the checks. There are two ways to do this: + +- `rust-project.json` may contain a `runnables` field. The `flycheck` runnable may be used to + configure a check command. See above for documentation. + +- Using the [`rust-analyzer.check.overrideCommand`](./configuration.md#check.overrideCommand) + configuration. This will also override anything in `rust-project.json`. As an example, the + following configuration explicitly sets `cargo check` as the `check` command. + + ```json + { "rust-analyzer.check.overrideCommand": ["cargo", "check", "--message-format=json"] } + ``` + + Note also that this works with cargo projects. + +Either option requires the command specified to output JSON error messages for rust-analyzer to +consume. The `--message-format=json` flag does this for `cargo check` so whichever command you use +must also output errors in this format. + +Either option also supports two syntaxes within each argument: + +- `{label}` will be replaced with the `BuildInfo::label` of the crate + containing a saved file, if `BuildInfo` is provided. In the case of `check.overrideCommand` being + used in a Cargo project, this will be the cargo package ID, which can be used with `cargo check -p`. +- `{saved_file}` will be replaced with an absolute path to the saved file. This can be queried against a + build system to find targets that include the file. + +For example: + +```json +{ "rust-analyzer.check.overrideCommand": ["custom_crate_checker", "{label}"] } +``` + +If you do use `{label}` or `{saved_file}`, the command will not be run unless the relevant value can +be substituted. + + +#### Flycheck considerations + +##### Diagnostic output on error + +A flycheck command using a complex build orchestrator like `"bazel", "build", "{label}"`, even with +a tweak to return JSON messages, is often insufficient. Such a command will typically succeed if +there are warnings, but if there are errors, it might "fail to compile" the diagnostics and not +produce any output. You must build a package in such a way that the build succeeds even if `rustc` +exits with an error, and prints the JSON build messages in every case. + +##### Diagnostics for upstream crates + +`cargo check -p` re-prints any errors and warnings in crates higher up in the dependency graph +than the one requested. We do clear all diagnostics when flychecking, so if you manage to +replicate this behaviour, diagnostics for crates other than the one being checked will show up in +the editor. If you do not, then users may be confused that diagnostics are "stuck" or disappear +entirely when there is a build error in an upstream crate. + +##### Compiler options + +`cargo check` invokes rustc differently from `cargo build`. It turns off codegen (with `rustc +--emit=metadata`), which results in lower latency to get to diagnostics. If your build system can +configure this, it is recommended. + +If your build tool can configure rustc for incremental compiles, this is also recommended. + +##### Locking and pre-emption + +In any good build system, including Cargo, build commands sometimes block each other. Running a +flycheck will (by default) frequently block you from running other build commands. Generally this is +undesirable. Users will have to (unintuitively) press save again in the editor to cancel a +flycheck, so that some other command may proceed. + +If your build system has the ability to isolate any rust-analyzer-driven flychecks and prevent lock +contention, for example a separate build output directory and/or daemon instance, this is +recommended. Alternatively, consider using a feature if available that can set the priority of +various build invocations and automatically cancel lower-priority ones when needed. Flychecks should +be set to a lower priority than general direct build invocations. diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 2157cbd48653..0d91378706a4 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -1213,7 +1213,7 @@ "title": "Check", "properties": { "rust-analyzer.check.overrideCommand": { - "markdownDescription": "Override the command rust-analyzer uses instead of `cargo check` for\ndiagnostics on save. The command is required to output json and\nshould therefore include `--message-format=json` or a similar option\n(if your client supports the `colorDiagnosticOutput` experimental\ncapability, you can use `--message-format=json-diagnostic-rendered-ansi`).\n\nIf you're changing this because you're using some tool wrapping\nCargo, you might also want to change\n`#rust-analyzer.cargo.buildScripts.overrideCommand#`.\n\nIf there are multiple linked projects/workspaces, this command is invoked for\neach of them, with the working directory being the workspace root\n(i.e., the folder containing the `Cargo.toml`). This can be overwritten\nby changing `#rust-analyzer.check.invocationStrategy#`.\n\nIf `$saved_file` is part of the command, rust-analyzer will pass\nthe absolute path of the saved file to the provided command. This is\nintended to be used with non-Cargo build systems.\nNote that `$saved_file` is experimental and may be removed in the future.\n\nAn example command would be:\n\n```bash\ncargo check --workspace --message-format=json --all-targets\n```\n\nNote: The option must be specified as an array of command line arguments, with\nthe first argument being the name of the command to run.", + "markdownDescription": "Override the command rust-analyzer uses instead of `cargo check` for\ndiagnostics on save. The command is required to output json and\nshould therefore include `--message-format=json` or a similar option\n(if your client supports the `colorDiagnosticOutput` experimental\ncapability, you can use `--message-format=json-diagnostic-rendered-ansi`).\n\nIf you're changing this because you're using some tool wrapping\nCargo, you might also want to change\n`#rust-analyzer.cargo.buildScripts.overrideCommand#`.\n\nIf there are multiple linked projects/workspaces, this command is invoked for\neach of them, with the working directory being the workspace root\n(i.e., the folder containing the `Cargo.toml`). This can be overwritten\nby changing `#rust-analyzer.check.invocationStrategy#`.\n\nIt supports two interpolation syntaxes, both mainly intended to be used with\n[non-Cargo build systems](./non_cargo_based_projects.md):\n\n- If `{saved_file}` is part of the command, rust-analyzer will pass\n the absolute path of the saved file to the provided command.\n (A previous version, `$saved_file`, also works.)\n- If `{label}` is part of the command, rust-analyzer will pass the\n Cargo package ID, which can be used with `cargo check -p`, or a build label from\n `rust-project.json`. If `{label}` is included, rust-analyzer behaves much like\n [`\"rust-analyzer.check.workspace\": false`](#check.workspace).\n\n\n\nAn example command would be:\n\n```bash\ncargo check --workspace --message-format=json --all-targets\n```\n\nNote: The option must be specified as an array of command line arguments, with\nthe first argument being the name of the command to run.", "default": null, "type": [ "null", @@ -3135,7 +3135,7 @@ "title": "Workspace", "properties": { "rust-analyzer.workspace.discoverConfig": { - "markdownDescription": "Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].\n\n[`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`.\n`progress_label` is used for the title in progress indicators, whereas `files_to_watch`\nis used to determine which build system-specific files should be watched in order to\nreload rust-analyzer.\n\nBelow is an example of a valid configuration:\n```json\n\"rust-analyzer.workspace.discoverConfig\": {\n \"command\": [\n \"rust-project\",\n \"develop-json\"\n ],\n \"progressLabel\": \"rust-analyzer\",\n \"filesToWatch\": [\n \"BUCK\"\n ]\n}\n```\n\n## On `DiscoverWorkspaceConfig::command`\n\n**Warning**: This format is provisional and subject to change.\n\n[`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to\n`DiscoverProjectData::Finished`:\n\n```norun\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(tag = \"kind\")]\n#[serde(rename_all = \"snake_case\")]\nenum DiscoverProjectData {\n Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },\n Error { error: String, source: Option },\n Progress { message: String },\n}\n```\n\nAs JSON, `DiscoverProjectData::Finished` is:\n\n```json\n{\n // the internally-tagged representation of the enum.\n \"kind\": \"finished\",\n // the file used by a non-Cargo build system to define\n // a package or target.\n \"buildfile\": \"rust-analyzer/BUILD\",\n // the contents of a rust-project.json, elided for brevity\n \"project\": {\n \"sysroot\": \"foo\",\n \"crates\": []\n }\n}\n```\n\nIt is encouraged, but not required, to use the other variants on `DiscoverProjectData`\nto provide a more polished end-user experience.\n\n`DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`, which will be\nsubstituted with the JSON-serialized form of the following enum:\n\n```norun\n#[derive(PartialEq, Clone, Debug, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub enum DiscoverArgument {\n Path(AbsPathBuf),\n Buildfile(AbsPathBuf),\n}\n```\n\nThe JSON representation of `DiscoverArgument::Path` is:\n\n```json\n{\n \"path\": \"src/main.rs\"\n}\n```\n\nSimilarly, the JSON representation of `DiscoverArgument::Buildfile` is:\n\n```json\n{\n \"buildfile\": \"BUILD\"\n}\n```\n\n`DiscoverArgument::Path` is used to find and generate a `rust-project.json`, and\ntherefore, a workspace, whereas `DiscoverArgument::buildfile` is used to to update an\nexisting workspace. As a reference for implementors, buck2's `rust-project` will likely\nbe useful: .", + "markdownDescription": "Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].\n\n[`DiscoverWorkspaceConfig`] also requires setting `progressLabel` and `filesToWatch`.\n`progressLabel` is used for the title in progress indicators, whereas `filesToWatch`\nis used to determine which build system-specific files should be watched in order to\nreload rust-analyzer.\n\nBelow is an example of a valid configuration:\n```json\n\"rust-analyzer.workspace.discoverConfig\": {\n \"command\": [\n \"rust-project\",\n \"develop-json\",\n \"{arg}\"\n ],\n \"progressLabel\": \"buck2/rust-project\",\n \"filesToWatch\": [\n \"BUCK\"\n ]\n}\n```\n\n## Workspace Discovery Protocol\n\n**Warning**: This format is provisional and subject to change.\n\n[`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to\n`DiscoverProjectData::Finished`:\n\n```norun\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(tag = \"kind\")]\n#[serde(rename_all = \"snake_case\")]\nenum DiscoverProjectData {\n Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },\n Error { error: String, source: Option },\n Progress { message: String },\n}\n```\n\nAs JSON, `DiscoverProjectData::Finished` is:\n\n```json\n{\n // the internally-tagged representation of the enum.\n \"kind\": \"finished\",\n // the file used by a non-Cargo build system to define\n // a package or target.\n \"buildfile\": \"rust-analyzer/BUILD\",\n // the contents of a rust-project.json, elided for brevity\n \"project\": {\n \"sysroot\": \"foo\",\n \"crates\": []\n }\n}\n```\n\nIt is encouraged, but not required, to use the other variants on `DiscoverProjectData`\nto provide a more polished end-user experience.\n\n`DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`, which will be\nsubstituted with the JSON-serialized form of the following enum:\n\n```norun\n#[derive(PartialEq, Clone, Debug, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub enum DiscoverArgument {\n Path(AbsPathBuf),\n Buildfile(AbsPathBuf),\n}\n```\n\nThe JSON representation of `DiscoverArgument::Path` is:\n\n```json\n{\n \"path\": \"src/main.rs\"\n}\n```\n\nSimilarly, the JSON representation of `DiscoverArgument::Buildfile` is:\n\n```json\n{\n \"buildfile\": \"BUILD\"\n}\n```\n\n`DiscoverArgument::Path` is used to find and generate a `rust-project.json`, and\ntherefore, a workspace, whereas `DiscoverArgument::buildfile` is used to to update an\nexisting workspace. As a reference for implementors, buck2's `rust-project` will likely\nbe useful: .", "default": null, "anyOf": [ { From b02e9756f2d0b0367cdedcba16016fc5e867999c Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Thu, 8 Jan 2026 09:53:00 +1100 Subject: [PATCH 1729/3801] Fix hir-ty clippy issue I am not familiar with this code at allso just doing what I can to unblock. --- .../crates/hir-ty/src/next_solver/infer/traits.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs index 14df42dc2aeb..dde623483642 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/traits.rs @@ -55,6 +55,13 @@ impl ObligationCause { } } +impl Default for ObligationCause { + #[inline] + fn default() -> Self { + Self::new() + } +} + /// An `Obligation` represents some trait reference (e.g., `i32: Eq`) for /// which the "impl_source" must be found. The process of finding an "impl_source" is /// called "resolving" the `Obligation`. This process consists of From fb9b6bd5351c3eb4f62da83c35ca1636a3523a60 Mon Sep 17 00:00:00 2001 From: hulxv Date: Wed, 17 Dec 2025 22:57:32 +0200 Subject: [PATCH 1730/3801] Refactor socketpair tests to use utility functions for reading and writing inline byte slices for data writes Refactor socketpair tests to use utility functions for reading and writing --- .../tests/pass-dep/libc/libc-socketpair.rs | 189 ++++++------------ 1 file changed, 61 insertions(+), 128 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs index ce3927ce48ca..2031149aaf4f 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs @@ -9,6 +9,7 @@ use std::thread; #[path = "../../utils/libc.rs"] mod libc_utils; +use libc_utils::*; fn main() { test_socketpair(); @@ -21,139 +22,92 @@ fn main() { fn test_socketpair() { let mut fds = [-1, -1]; - let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Read size == data available in buffer. - let data = "abcde".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); - let mut buf: [u8; 5] = [0; 5]; - let res = - unsafe { libc_utils::read_all(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - assert_eq!(res, 5); - assert_eq!(buf, "abcde".as_bytes()); + let data = b"abcde"; + write_all_from_slice(fds[0], data).unwrap(); + let buf = read_all_into_array::<5>(fds[1]).unwrap(); + assert_eq!(&buf, data); // Read size > data available in buffer. - let data = "abc".as_bytes(); - let res = unsafe { libc_utils::write_all(fds[0], data.as_ptr() as *const libc::c_void, 3) }; - assert_eq!(res, 3); + let data = b"abc"; + write_all_from_slice(fds[0], data).unwrap(); let mut buf2: [u8; 5] = [0; 5]; - let res = unsafe { libc::read(fds[1], buf2.as_mut_ptr().cast(), buf2.len() as libc::size_t) }; - assert!(res > 0 && res <= 3); - let res = res as usize; - assert_eq!(buf2[..res], data[..res]); - if res < 3 { - // Drain the rest from the read end. - let res = unsafe { libc_utils::read_all(fds[1], buf2[res..].as_mut_ptr().cast(), 3 - res) }; - assert!(res > 0); - } + let (read, rest) = read_into_slice(fds[1], &mut buf2).unwrap(); + assert_eq!(read[..], data[..read.len()]); + // Write 2 more bytes so we can exactly fill the `rest`. + write_all_from_slice(fds[0], b"12").unwrap(); + read_all_into_slice(fds[1], rest).unwrap(); // Test read and write from another direction. // Read size == data available in buffer. - let data = "12345".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); - let mut buf3: [u8; 5] = [0; 5]; - let res = unsafe { - libc_utils::read_all(fds[0], buf3.as_mut_ptr().cast(), buf3.len() as libc::size_t) - }; - assert_eq!(res, 5); - assert_eq!(buf3, "12345".as_bytes()); + let data = b"12345"; + write_all_from_slice(fds[1], data).unwrap(); + let buf3 = read_all_into_array::<5>(fds[0]).unwrap(); + assert_eq!(&buf3, data); // Read size > data available in buffer. - let data = "123".as_bytes(); - let res = unsafe { libc_utils::write_all(fds[1], data.as_ptr() as *const libc::c_void, 3) }; - assert_eq!(res, 3); + let data = b"123"; + write_all_from_slice(fds[1], data).unwrap(); let mut buf4: [u8; 5] = [0; 5]; - let res = unsafe { libc::read(fds[0], buf4.as_mut_ptr().cast(), buf4.len() as libc::size_t) }; - assert!(res > 0 && res <= 3); - let res = res as usize; - assert_eq!(buf4[..res], data[..res]); - if res < 3 { - // Drain the rest from the read end. - let res = unsafe { libc_utils::read_all(fds[0], buf4[res..].as_mut_ptr().cast(), 3 - res) }; - assert!(res > 0); - } + let (read, rest) = read_into_slice(fds[0], &mut buf4).unwrap(); + assert_eq!(read[..], data[..read.len()]); + // Write 2 more bytes so we can exactly fill the `rest`. + write_all_from_slice(fds[1], b"12").unwrap(); + read_all_into_slice(fds[0], rest).unwrap(); // Test when happens when we close one end, with some data in the buffer. - let res = unsafe { libc_utils::write_all(fds[0], data.as_ptr() as *const libc::c_void, 3) }; - assert_eq!(res, 3); - unsafe { libc::close(fds[0]) }; + write_all_from_slice(fds[0], data).unwrap(); + errno_check(unsafe { libc::close(fds[0]) }); // Reading the other end should return that data, then EOF. let mut buf: [u8; 5] = [0; 5]; - let res = - unsafe { libc_utils::read_all(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - assert_eq!(res, 3); - assert_eq!(&buf[0..3], "123".as_bytes()); - let res = - unsafe { libc_utils::read_all(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; + read_all_into_slice(fds[1], &mut buf[0..3]).unwrap(); + assert_eq!(&buf[0..3], data); + let res = read_into_slice(fds[1], &mut buf[3..5]).unwrap().0.len(); assert_eq!(res, 0); // 0-sized read: EOF. // Writing the other end should emit EPIPE. - let res = unsafe { libc_utils::write_all(fds[1], data.as_ptr() as *const libc::c_void, 1) }; - assert_eq!(res, -1); + let res = write_all_from_slice(fds[1], &mut buf); + assert_eq!(res, Err(-1)); assert_eq!(std::io::Error::last_os_error().raw_os_error(), Some(libc::EPIPE)); } fn test_socketpair_threaded() { let mut fds = [-1, -1]; - let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); let thread1 = thread::spawn(move || { - let mut buf: [u8; 5] = [0; 5]; - let res: i64 = unsafe { - libc_utils::read_all(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - .try_into() - .unwrap() - }; - assert_eq!(res, 5); - assert_eq!(buf, "abcde".as_bytes()); + let buf = read_all_into_array::<5>(fds[1]).unwrap(); + assert_eq!(&buf, b"abcde"); }); thread::yield_now(); - let data = "abcde".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); + write_all_from_slice(fds[0], b"abcde").unwrap(); thread1.join().unwrap(); // Read and write from different direction let thread2 = thread::spawn(move || { thread::yield_now(); - let data = "12345".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); + write_all_from_slice(fds[1], b"12345").unwrap(); }); - let mut buf: [u8; 5] = [0; 5]; - let res = - unsafe { libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; - assert_eq!(res, 5); - assert_eq!(buf, "12345".as_bytes()); + let buf = read_all_into_array::<5>(fds[0]).unwrap(); + assert_eq!(&buf, b"12345"); thread2.join().unwrap(); } fn test_race() { static mut VAL: u8 = 0; let mut fds = [-1, -1]; - let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); let thread1 = thread::spawn(move || { - let mut buf: [u8; 1] = [0; 1]; // write() from the main thread will occur before the read() here // because preemption is disabled and the main thread yields after write(). - let res: i32 = unsafe { - libc_utils::read_all(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - .try_into() - .unwrap() - }; - assert_eq!(res, 1); - assert_eq!(buf, "a".as_bytes()); + let buf = read_all_into_array::<1>(fds[1]).unwrap(); + assert_eq!(&buf, b"a"); // The read above establishes a happens-before so it is now safe to access this global variable. unsafe { assert_eq!(VAL, 1) }; }); unsafe { VAL = 1 }; - let data = "a".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 1) }; - assert_eq!(res, 1); + write_all_from_slice(fds[0], b"a").unwrap(); thread::yield_now(); thread1.join().unwrap(); } @@ -161,22 +115,15 @@ fn test_race() { // Test the behaviour of a socketpair getting blocked on read and subsequently unblocked. fn test_blocking_read() { let mut fds = [-1, -1]; - let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); let thread1 = thread::spawn(move || { // Let this thread block on read. - let mut buf: [u8; 3] = [0; 3]; - let res = unsafe { - libc_utils::read_all(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - }; - assert_eq!(res, 3); - assert_eq!(&buf, "abc".as_bytes()); + let buf = read_all_into_array::<3>(fds[1]).unwrap(); + assert_eq!(&buf, b"abc"); }); let thread2 = thread::spawn(move || { // Unblock thread1 by doing writing something. - let data = "abc".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 3) }; - assert_eq!(res, 3); + write_all_from_slice(fds[0], b"abc").unwrap(); }); thread1.join().unwrap(); thread2.join().unwrap(); @@ -185,26 +132,17 @@ fn test_blocking_read() { // Test the behaviour of a socketpair getting blocked on write and subsequently unblocked. fn test_blocking_write() { let mut fds = [-1, -1]; - let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); let arr1: [u8; 0x34000] = [1; 0x34000]; // Exhaust the space in the buffer so the subsequent write will block. - let res = - unsafe { libc_utils::write_all(fds[0], arr1.as_ptr() as *const libc::c_void, arr1.len()) }; - assert_eq!(res, 0x34000); + write_all_from_slice(fds[0], &arr1).unwrap(); let thread1 = thread::spawn(move || { - let data = "abc".as_bytes().as_ptr(); // The write below will be blocked because the buffer is already full. - let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 3) }; - assert_eq!(res, 3); + write_all_from_slice(fds[0], b"abc").unwrap(); }); let thread2 = thread::spawn(move || { // Unblock thread1 by freeing up some space. - let mut buf: [u8; 3] = [0; 3]; - let res = unsafe { - libc_utils::read_all(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) - }; - assert_eq!(res, 3); + let buf = read_all_into_array::<3>(fds[1]).unwrap(); assert_eq!(buf, [1, 1, 1]); }); thread1.join().unwrap(); @@ -215,30 +153,25 @@ fn test_blocking_write() { fn test_socketpair_setfl_getfl() { // Initialise socketpair fds. let mut fds = [-1, -1]; - let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Test if both sides have O_RDWR. - let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) }; - assert_eq!(res, libc::O_RDWR); - let res = unsafe { libc::fcntl(fds[1], libc::F_GETFL) }; - assert_eq!(res, libc::O_RDWR); + assert_eq!(errno_result(unsafe { libc::fcntl(fds[0], libc::F_GETFL) }).unwrap(), libc::O_RDWR); + assert_eq!(errno_result(unsafe { libc::fcntl(fds[1], libc::F_GETFL) }).unwrap(), libc::O_RDWR); // Add the O_NONBLOCK flag with F_SETFL. - let res = unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK) }); // Test if the O_NONBLOCK flag is successfully added. - let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) }; - assert_eq!(res, libc::O_RDWR | libc::O_NONBLOCK); + assert_eq!( + errno_result(unsafe { libc::fcntl(fds[0], libc::F_GETFL) }).unwrap(), + libc::O_RDWR | libc::O_NONBLOCK + ); // The other side remains unchanged. - let res = unsafe { libc::fcntl(fds[1], libc::F_GETFL) }; - assert_eq!(res, libc::O_RDWR); + assert_eq!(errno_result(unsafe { libc::fcntl(fds[1], libc::F_GETFL) }).unwrap(), libc::O_RDWR); // Test if O_NONBLOCK flag can be unset. - let res = unsafe { libc::fcntl(fds[0], libc::F_SETFL, 0) }; - assert_eq!(res, 0); - let res = unsafe { libc::fcntl(fds[0], libc::F_GETFL) }; - assert_eq!(res, libc::O_RDWR); + errno_check(unsafe { libc::fcntl(fds[0], libc::F_SETFL, 0) }); + assert_eq!(errno_result(unsafe { libc::fcntl(fds[0], libc::F_GETFL) }).unwrap(), libc::O_RDWR); } From ffaf76a7cfbf29968e6a33387fc96aa7b17a88fc Mon Sep 17 00:00:00 2001 From: hulxv Date: Wed, 17 Dec 2025 23:05:49 +0200 Subject: [PATCH 1731/3801] Refactor epoll tests to use errno_result and improve notification checks --- .../pass-dep/libc/libc-epoll-blocking.rs | 162 ++++++------------ .../pass-dep/libc/libc-epoll-no-blocking.rs | 20 +-- src/tools/miri/tests/utils/libc.rs | 11 +- 3 files changed, 75 insertions(+), 118 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs index c67386b4f84c..d5a59796de02 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs @@ -7,6 +7,8 @@ use std::thread; #[path = "../../utils/libc.rs"] mod libc_utils; +use libc_utils::epoll::*; +use libc_utils::*; // This is a set of testcases for blocking epoll. @@ -20,47 +22,22 @@ fn main() { } // Using `as` cast since `EPOLLET` wraps around -const EPOLL_IN_OUT_ET: u32 = (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _; - -#[track_caller] -fn check_epoll_wait( - epfd: i32, - expected_notifications: &[(u32, u64)], - timeout: i32, -) { - let epoll_event = libc::epoll_event { events: 0, u64: 0 }; - let mut array: [libc::epoll_event; N] = [epoll_event; N]; - let maxsize = N; - let array_ptr = array.as_mut_ptr(); - let res = unsafe { libc::epoll_wait(epfd, array_ptr, maxsize.try_into().unwrap(), timeout) }; - if res < 0 { - panic!("epoll_wait failed: {}", std::io::Error::last_os_error()); - } - let got_notifications = - unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) }; - let got_notifications = got_notifications.iter().map(|e| (e.events, e.u64)).collect::>(); - assert_eq!(got_notifications, expected_notifications, "got wrong notifications"); -} +const EPOLL_IN_OUT_ET: i32 = (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _; // This test allows epoll_wait to block, then unblock without notification. fn test_epoll_block_without_notification() { // Create an epoll instance. - let epfd = unsafe { libc::epoll_create1(0) }; - assert_ne!(epfd, -1); + let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap(); // Create an eventfd instances. let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC; - let fd = unsafe { libc::eventfd(0, flags) }; + let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap(); // Register eventfd with epoll. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fd as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fd, EPOLL_IN_OUT_ET).unwrap(); // epoll_wait to clear notification. - let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); - let expected_value = fd as u64; - check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 0); + check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT as _, data: fd }], 0); // This epoll wait blocks, and timeout without notification. check_epoll_wait::<1>(epfd, &[], 5); @@ -69,102 +46,86 @@ fn test_epoll_block_without_notification() { // This test triggers notification and unblocks the epoll_wait before timeout. fn test_epoll_block_then_unblock() { // Create an epoll instance. - let epfd = unsafe { libc::epoll_create1(0) }; - assert_ne!(epfd, -1); + let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap(); // Create a socketpair instance. let mut fds = [-1, -1]; - let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Register one side of the socketpair with epoll. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fds[0], EPOLL_IN_OUT_ET).unwrap(); // epoll_wait to clear notification. - let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); - let expected_value = fds[0] as u64; - check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 0); + check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT as _, data: fds[0] }], 0); // epoll_wait before triggering notification so it will block then get unblocked before timeout. - let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); - let expected_value = fds[0] as u64; let thread1 = thread::spawn(move || { thread::yield_now(); - let data = "abcde".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); + write_all_from_slice(fds[1], b"abcde").unwrap(); }); - check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 10); + check_epoll_wait::<1>( + epfd, + &[Ev { events: (libc::EPOLLIN | libc::EPOLLOUT) as _, data: fds[0] }], + 10, + ); thread1.join().unwrap(); } // This test triggers a notification after epoll_wait times out. fn test_notification_after_timeout() { // Create an epoll instance. - let epfd = unsafe { libc::epoll_create1(0) }; - assert_ne!(epfd, -1); + let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap(); // Create a socketpair instance. let mut fds = [-1, -1]; - let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Register one side of the socketpair with epoll. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fds[0], EPOLL_IN_OUT_ET).unwrap(); // epoll_wait to clear notification. - let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); - let expected_value = fds[0] as u64; - check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 0); + check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT as _, data: fds[0] }], 0); // epoll_wait timeouts without notification. check_epoll_wait::<1>(epfd, &[], 10); // Trigger epoll notification after timeout. - let data = "abcde".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); + write_all_from_slice(fds[1], b"abcde").unwrap(); // Check the result of the notification. - let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); - let expected_value = fds[0] as u64; - check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 10); + check_epoll_wait::<1>( + epfd, + &[Ev { events: (libc::EPOLLIN | libc::EPOLLOUT) as _, data: fds[0] }], + 10, + ); } // This test shows a data_race before epoll had vector clocks added. fn test_epoll_race() { // Create an epoll instance. - let epfd = unsafe { libc::epoll_create1(0) }; - assert_ne!(epfd, -1); + let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap(); // Create an eventfd instance. let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC; - let fd = unsafe { libc::eventfd(0, flags) }; + let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap(); // Register eventfd with the epoll instance. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fd as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fd, EPOLL_IN_OUT_ET).unwrap(); static mut VAL: u8 = 0; let thread1 = thread::spawn(move || { // Write to the static mut variable. unsafe { VAL = 1 }; // Write to the eventfd instance. - let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes(); - let res = unsafe { libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8) }; - // write returns number of bytes written, which is always 8. - assert_eq!(res, 8); + write_all_from_slice(fd, &1_u64.to_ne_bytes()).unwrap(); }); thread::yield_now(); // epoll_wait for the event to happen. - let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); - let expected_value = u64::try_from(fd).unwrap(); - check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)], -1); + check_epoll_wait::<8>( + epfd, + &[Ev { events: (libc::EPOLLIN | libc::EPOLLOUT) as _, data: fd }], + -1, + ); // Read from the static mut variable. #[allow(static_mut_refs)] unsafe { @@ -177,35 +138,28 @@ fn test_epoll_race() { /// epoll it is blocked on. fn wakeup_on_new_interest() { // Create an epoll instance. - let epfd = unsafe { libc::epoll_create1(0) }; - assert_ne!(epfd, -1); + let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap(); // Create a socketpair instance. let mut fds = [-1, -1]; - let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; - assert_eq!(res, 0); + errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Write to fd[0] - let data = "abcde".as_bytes().as_ptr(); - let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; - assert_eq!(res, 5); + write_all_from_slice(fds[0], b"abcde").unwrap(); // Block a thread on the epoll instance. let t = std::thread::spawn(move || { - let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); - let expected_value = u64::try_from(fds[1]).unwrap(); - check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)], -1); + check_epoll_wait::<8>( + epfd, + &[Ev { events: (libc::EPOLLIN | libc::EPOLLOUT) as _, data: fds[1] }], + -1, + ); }); // Ensure the thread is blocked. std::thread::yield_now(); // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP - let mut ev = libc::epoll_event { - events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP) as _, - u64: u64::try_from(fds[1]).unwrap(), - }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fds[1], EPOLL_IN_OUT_ET | libc::EPOLLRDHUP as i32).unwrap(); // This should wake up the thread. t.join().unwrap(); @@ -215,25 +169,23 @@ fn wakeup_on_new_interest() { /// to consume them all. fn multiple_events_wake_multiple_threads() { // Create an epoll instance. - let epfd = unsafe { libc::epoll_create1(0) }; - assert_ne!(epfd, -1); + let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap(); // Create an eventfd instance. let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC; - let fd1 = unsafe { libc::eventfd(0, flags) }; + let fd1 = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap(); // Make a duplicate so that we have two file descriptors for the same file description. - let fd2 = unsafe { libc::dup(fd1) }; + let fd2 = errno_result(unsafe { libc::dup(fd1) }).unwrap(); // Register both with epoll. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fd1 as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd1, &mut ev) }; - assert_eq!(res, 0); - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fd2 as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd2, &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fd1, EPOLL_IN_OUT_ET).unwrap(); + epoll_ctl_add(epfd, fd2, EPOLL_IN_OUT_ET).unwrap(); // Consume the initial events. - let expected = [(libc::EPOLLOUT as u32, fd1 as u64), (libc::EPOLLOUT as u32, fd2 as u64)]; + let expected = [ + Ev { events: libc::EPOLLOUT as _, data: fd1 }, + Ev { events: libc::EPOLLOUT as _, data: fd2 }, + ]; check_epoll_wait::<8>(epfd, &expected, -1); // Block two threads on the epoll, both wanting to get just one event. @@ -241,19 +193,19 @@ fn multiple_events_wake_multiple_threads() { let mut e = libc::epoll_event { events: 0, u64: 0 }; let res = unsafe { libc::epoll_wait(epfd, &raw mut e, 1, -1) }; assert!(res == 1); - (e.events, e.u64) + Ev { events: e.events.cast_signed(), data: e.u64.try_into().unwrap() } }); let t2 = thread::spawn(move || { let mut e = libc::epoll_event { events: 0, u64: 0 }; let res = unsafe { libc::epoll_wait(epfd, &raw mut e, 1, -1) }; assert!(res == 1); - (e.events, e.u64) + Ev { events: e.events.cast_signed(), data: e.u64.try_into().unwrap() } }); // Yield so both threads are waiting now. thread::yield_now(); // Trigger the eventfd. This triggers two events at once! - libc_utils::write_all_from_slice(fd1, &0_u64.to_ne_bytes()).unwrap(); + write_all_from_slice(fd1, &0_u64.to_ne_bytes()).unwrap(); // Both threads should have been woken up so that both events can be consumed. let e1 = t1.join().unwrap(); diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs index c2789eb2f6c6..490895c8541b 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs @@ -60,7 +60,7 @@ fn test_epoll_socketpair() { errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Write to fd[0] - write_all_from_slice(fds[0], "abcde".as_bytes()).unwrap(); + write_all_from_slice(fds[0], b"abcde").unwrap(); // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP epoll_ctl_add(epfd, fds[1], EPOLLIN | EPOLLOUT | EPOLLET | EPOLLRDHUP).unwrap(); @@ -72,7 +72,7 @@ fn test_epoll_socketpair() { check_epoll_wait_noblock::<8>(epfd, &[]); // Write some more to fd[0]. - write_all_from_slice(fds[0], "abcde".as_bytes()).unwrap(); + write_all_from_slice(fds[0], b"abcde").unwrap(); // This did not change the readiness of fd[1], so we should get no event. // However, Linux seems to always deliver spurious events to the peer on each write, @@ -140,7 +140,7 @@ fn test_epoll_ctl_del() { errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Write to fd[0] - let data = "abcde".as_bytes().as_ptr(); + let data = b"abcde".as_ptr(); let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); @@ -168,7 +168,7 @@ fn test_two_epoll_instance() { errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Write to the socketpair. - let data = "abcde".as_bytes().as_ptr(); + let data = b"abcde".as_ptr(); let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); @@ -208,7 +208,7 @@ fn test_two_same_fd_in_same_epoll_instance() { assert_eq!(res, 0); // Write to the socketpair. - let data = "abcde".as_bytes().as_ptr(); + let data = b"abcde".as_ptr(); let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); @@ -288,7 +288,7 @@ fn test_epoll_socketpair_both_sides() { // Write to fds[1]. // (We do the write after the register here, unlike in `test_epoll_socketpair`, to ensure // we cover both orders in which this could be done.) - let data = "abcde".as_bytes().as_ptr(); + let data = b"abcde".as_ptr(); let res = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5) }; assert_eq!(res, 5); @@ -307,7 +307,7 @@ fn test_epoll_socketpair_both_sides() { let res = unsafe { libc_utils::read_all(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; assert_eq!(res, 5); - assert_eq!(buf, "abcde".as_bytes()); + assert_eq!(buf, *b"abcde"); // The state of fds[1] does not change (was writable, is writable). // However, we force a spurious wakeup as the read buffer just got emptied. @@ -500,7 +500,7 @@ fn test_no_notification_for_unregister_flag() { assert_eq!(res, 0); // Write to fd[1]. - let data = "abcde".as_bytes().as_ptr(); + let data = b"abcde".as_ptr(); let res: i32 = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5).try_into().unwrap() }; @@ -534,7 +534,7 @@ fn test_socketpair_epollerr() { errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Write to fd[0] - let data = "abcde".as_bytes().as_ptr(); + let data = b"abcde".as_ptr(); let res = unsafe { libc_utils::write_all(fds[0], data as *const libc::c_void, 5) }; assert_eq!(res, 5); @@ -747,7 +747,7 @@ fn test_issue_4374_reads() { assert_eq!(unsafe { libc::fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK) }, 0); // Write to fds[1] so that fds[0] becomes readable. - let data = "abcde".as_bytes().as_ptr(); + let data = b"abcde".as_ptr(); let res: i32 = unsafe { libc_utils::write_all(fds[1], data as *const libc::c_void, 5).try_into().unwrap() }; diff --git a/src/tools/miri/tests/utils/libc.rs b/src/tools/miri/tests/utils/libc.rs index 0765bacb6bd8..4492f5080180 100644 --- a/src/tools/miri/tests/utils/libc.rs +++ b/src/tools/miri/tests/utils/libc.rs @@ -113,7 +113,7 @@ pub mod epoll { /// The libc epoll_event type doesn't fit to the EPOLLIN etc constants, so we have our /// own type. We also make the data field an int since we typically want to store FDs there. - #[derive(PartialEq, Debug)] + #[derive(PartialEq, Debug, Clone, Copy)] pub struct Ev { pub events: c_int, pub data: c_int, @@ -138,10 +138,10 @@ pub mod epoll { } #[track_caller] - pub fn check_epoll_wait_noblock(epfd: i32, expected: &[Ev]) { + pub fn check_epoll_wait(epfd: i32, expected: &[Ev], timeout: i32) { let mut array: [libc::epoll_event; N] = [libc::epoll_event { events: 0, u64: 0 }; N]; let num = errno_result(unsafe { - libc::epoll_wait(epfd, array.as_mut_ptr(), N.try_into().unwrap(), 0) + libc::epoll_wait(epfd, array.as_mut_ptr(), N.try_into().unwrap(), timeout) }) .expect("epoll_wait returned an error"); let got = &mut array[..num.try_into().unwrap()]; @@ -151,4 +151,9 @@ pub mod epoll { .collect::>(); assert_eq!(got, expected, "got wrong notifications"); } + + #[track_caller] + pub fn check_epoll_wait_noblock(epfd: i32, expected: &[Ev]) { + check_epoll_wait::(epfd, expected, 0); + } } From b0e65da2af8f3e12015d78a1828fceed6360642a Mon Sep 17 00:00:00 2001 From: Usman Akinyemi Date: Wed, 7 Jan 2026 19:01:19 +0530 Subject: [PATCH 1732/3801] rustc_parse_format: improve error for missing `:` before `?` in format args MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detect the `{ident?}` pattern where `?` is immediately followed by `}` and emit a clearer diagnostic explaining that `:` is required for Debug formatting. This avoids falling back to a generic “invalid format string” error and adds a targeted UI test for the case. Signed-off-by: Usman Akinyemi --- compiler/rustc_builtin_macros/messages.ftl | 2 ++ compiler/rustc_builtin_macros/src/errors.rs | 9 +++++++ compiler/rustc_builtin_macros/src/format.rs | 4 +++ compiler/rustc_parse_format/src/lib.rs | 29 ++++++++++++++++++--- tests/ui/fmt/format-string-error-2.rs | 3 +++ tests/ui/fmt/format-string-error-2.stderr | 13 ++++++++- 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index f0f6f2dcf82c..e4fded0cb01e 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -182,6 +182,8 @@ builtin_macros_expected_other = expected operand, {$is_inline_asm -> builtin_macros_export_macro_rules = cannot export macro_rules! macros from a `proc-macro` crate type currently +builtin_macros_format_add_missing_colon = add a colon before the format specifier + builtin_macros_format_duplicate_arg = duplicate argument named `{$ident}` .label1 = previously here .label2 = duplicate argument diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index ad31eae10f60..e673ad3f8a64 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -643,6 +643,15 @@ pub(crate) enum InvalidFormatStringSuggestion { span: Span, replacement: String, }, + #[suggestion( + builtin_macros_format_add_missing_colon, + code = ":?", + applicability = "machine-applicable" + )] + AddMissingColon { + #[primary_span] + span: Span, + }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index a0ee7ac19899..12cb2cd00694 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -329,6 +329,10 @@ fn make_format_args( replacement, }); } + parse::Suggestion::AddMissingColon(span) => { + let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end)); + e.sugg_ = Some(errors::InvalidFormatStringSuggestion::AddMissingColon { span }); + } } let guar = ecx.dcx().emit_err(e); return ExpandResult::Ready(Err(guar)); diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 86326fc6536c..143fd0c4436c 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -184,6 +184,9 @@ pub enum Suggestion { /// `format!("{foo:?x}")` -> `format!("{foo:x?}")` /// `format!("{foo:?X}")` -> `format!("{foo:X?}")` ReorderFormatParameter(Range, String), + /// Add missing colon: + /// `format!("{foo?}")` -> `format!("{foo:?}")` + AddMissingColon(Range), } /// The parser structure for interpreting the input format string. This is @@ -453,10 +456,11 @@ impl<'input> Parser<'input> { suggestion: Suggestion::None, }); - if let Some((_, _, c)) = self.peek() { - match c { - '?' => self.suggest_format_debug(), - '<' | '^' | '>' => self.suggest_format_align(c), + if let (Some((_, _, c)), Some((_, _, nc))) = (self.peek(), self.peek_ahead()) { + match (c, nc) { + ('?', '}') => self.missing_colon_before_debug_formatter(), + ('?', _) => self.suggest_format_debug(), + ('<' | '^' | '>', _) => self.suggest_format_align(c), _ => self.suggest_positional_arg_instead_of_captured_arg(arg), } } @@ -849,6 +853,23 @@ impl<'input> Parser<'input> { } } + fn missing_colon_before_debug_formatter(&mut self) { + if let Some((range, _)) = self.consume_pos('?') { + let span = range.clone(); + self.errors.insert( + 0, + ParseError { + description: "expected `}`, found `?`".to_owned(), + note: Some(format!("to print `{{`, you can escape it using `{{{{`",)), + label: "expected `:` before `?` to format with `Debug`".to_owned(), + span: range, + secondary_label: None, + suggestion: Suggestion::AddMissingColon(span), + }, + ); + } + } + fn suggest_format_align(&mut self, alignment: char) { if let Some((range, _)) = self.consume_pos(alignment) { self.errors.insert( diff --git a/tests/ui/fmt/format-string-error-2.rs b/tests/ui/fmt/format-string-error-2.rs index 357dd7b10a3e..e14a4064aa83 100644 --- a/tests/ui/fmt/format-string-error-2.rs +++ b/tests/ui/fmt/format-string-error-2.rs @@ -83,4 +83,7 @@ raw { \n println!(r#"\x7B}\u8 {"#, 1); //~^ ERROR invalid format string: unmatched `}` found + + println!("{x?}, world!",); + //~^ ERROR invalid format string: expected `}`, found `?` } diff --git a/tests/ui/fmt/format-string-error-2.stderr b/tests/ui/fmt/format-string-error-2.stderr index 6d8c34fdb709..b117fb57cf07 100644 --- a/tests/ui/fmt/format-string-error-2.stderr +++ b/tests/ui/fmt/format-string-error-2.stderr @@ -177,5 +177,16 @@ LL | println!(r#"\x7B}\u8 {"#, 1); | = note: if you intended to print `}`, you can escape it using `}}` -error: aborting due to 18 previous errors +error: invalid format string: expected `}`, found `?` + --> $DIR/format-string-error-2.rs:87:17 + | +LL | println!("{x?}, world!",); + | ^ + | | + | expected `:` before `?` to format with `Debug` in format string + | help: add a colon before the format specifier: `:?` + | + = note: to print `{`, you can escape it using `{{` + +error: aborting due to 19 previous errors From 600102c09b4e2a65969b1a1c1e857552fe1b83c2 Mon Sep 17 00:00:00 2001 From: Aelin Reidel Date: Thu, 8 Jan 2026 02:12:49 +0100 Subject: [PATCH 1733/3801] Add myself as co-maintainer for s390x-unknown-linux-musl Having two dedicated target maintainers is a prerequisite for promoting this target to tier 2. I've been in contact with Ulrich and he's agreed to having me as a co-maintainer in preparation for a MCP to promote it to tier 2. --- src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md index b8bee11055fe..cb7d05515453 100644 --- a/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md @@ -7,6 +7,7 @@ IBM z/Architecture (s390x) targets (including IBM Z and LinuxONE) running Linux. ## Target maintainers [@uweigand](https://github.com/uweigand) +[@Gelbpunkt](https://github.com/Gelbpunkt) ## Requirements From a3b72d3de584a524d677bbaedf440f9223d439c0 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Thu, 8 Jan 2026 02:06:20 +0000 Subject: [PATCH 1734/3801] Fix copy-n-paste error in `vtable_for` docs This is a safe function, which doesn't take a `ptr` parameter. --- library/core/src/intrinsics/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 0ae8d3d4a4ce..27e1673c51de 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2738,10 +2738,6 @@ pub unsafe fn vtable_align(ptr: *const ()) -> usize; /// Determining whether `T` can be coerced to the trait object type `U` requires trait resolution by the compiler. /// In some cases, that resolution can exceed the recursion limit, /// and compilation will fail instead of this function returning `None`. -/// -/// # Safety -/// -/// `ptr` must point to a vtable. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] From e2c73b806e629b4fb5a7f082643d602ca541f7b5 Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Thu, 8 Jan 2026 02:32:51 +0000 Subject: [PATCH 1735/3801] docs:improve const generics --- src/doc/rustc-dev-guide/src/const-generics.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/const-generics.md b/src/doc/rustc-dev-guide/src/const-generics.md index cb8c7adc07f4..4c2a0ddbabd5 100644 --- a/src/doc/rustc-dev-guide/src/const-generics.md +++ b/src/doc/rustc-dev-guide/src/const-generics.md @@ -111,14 +111,15 @@ The third point is also somewhat subtle, by not inheriting any of the where clau This also makes it much more likely that the compiler will ICE or atleast incidentally emit some kind of error if we *do* accidentally allow generic parameters in an anon const, as the anon const will have none of the necessary information in its environment to properly handle the generic parameters. +#### Array repeat expressions +The one exception to all of the above is repeat counts of array expressions. As a *backwards compatibility hack* we allow the repeat count const argument to use generic parameters. + ```rust fn foo() { - let a = [1_u8; size_of::<*mut T>()]; + let a = [1_u8; size_of::()]; } ``` -The one exception to all of the above is repeat counts of array expressions. As a *backwards compatibility hack* we allow the repeat count const argument to use generic parameters. - However, to avoid most of the problems involved in allowing generic parameters in anon const const arguments we require that the constant be evaluated before monomorphization (e.g. during type checking). In some sense we only allow generic parameters here when they are semantically unused. In the previous example the anon const can be evaluated for any type parameter `T` because raw pointers to sized types always have the same size (e.g. `8` on 64bit platforms). From a4da8e8cefd95b8b5e7c0cea97a9f6331e578276 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 7 Jan 2026 11:23:48 +1100 Subject: [PATCH 1736/3801] Remove some unnecessary braces in patterns. --- .../rustc_next_trait_solver/src/canonical/canonicalizer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 9162284422d0..289538a6163b 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -417,7 +417,7 @@ impl, I: Interner> TypeFolder for Canonicaliz // We don't canonicalize `ReStatic` in the `param_env` as we use it // when checking whether a `ParamEnv` candidate is global. ty::ReStatic => match self.canonicalize_mode { - CanonicalizeMode::Input(CanonicalizeInputKind::Predicate { .. }) => { + CanonicalizeMode::Input(CanonicalizeInputKind::Predicate) => { CanonicalVarKind::Region(ty::UniverseIndex::ROOT) } CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv) @@ -545,7 +545,7 @@ impl, I: Interner> TypeFolder for Canonicaliz match self.canonicalize_mode { CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv) | CanonicalizeMode::Response { max_input_universe: _ } => {} - CanonicalizeMode::Input(CanonicalizeInputKind::Predicate { .. }) => { + CanonicalizeMode::Input(CanonicalizeInputKind::Predicate) => { panic!("erasing 'static in env") } } From 5ca112fb9712d260d1aa5214a116663971fc770d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 5 Jan 2026 17:48:51 +1100 Subject: [PATCH 1737/3801] Factor out duplicated code in `Canonicalizer::finalize`. --- .../src/canonical/canonicalizer.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 289538a6163b..6c114d601157 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -109,6 +109,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { let (max_universe, variables) = canonicalizer.finalize(); Canonical { max_universe, variables, value } } + fn canonicalize_param_env( delegate: &'a D, variables: &'a mut Vec, @@ -280,15 +281,14 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { let mut var_kinds = self.var_kinds; // See the rustc-dev-guide section about how we deal with universes // during canonicalization in the new solver. - match self.canonicalize_mode { + let max_universe = match self.canonicalize_mode { // All placeholders and vars are canonicalized in the root universe. CanonicalizeMode::Input { .. } => { debug_assert!( var_kinds.iter().all(|var| var.universe() == ty::UniverseIndex::ROOT), "expected all vars to be canonicalized in root universe: {var_kinds:#?}" ); - let var_kinds = self.delegate.cx().mk_canonical_var_kinds(&var_kinds); - (ty::UniverseIndex::ROOT, var_kinds) + ty::UniverseIndex::ROOT } // When canonicalizing a response we map a universes already entered // by the caller to the root universe and only return useful universe @@ -302,15 +302,15 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { ); *var = var.with_updated_universe(new_uv); } - let max_universe = var_kinds + var_kinds .iter() .map(|kind| kind.universe()) .max() - .unwrap_or(ty::UniverseIndex::ROOT); - let var_kinds = self.delegate.cx().mk_canonical_var_kinds(&var_kinds); - (max_universe, var_kinds) + .unwrap_or(ty::UniverseIndex::ROOT) } - } + }; + let var_kinds = self.delegate.cx().mk_canonical_var_kinds(&var_kinds); + (max_universe, var_kinds) } fn inner_fold_ty(&mut self, t: I::Ty) -> I::Ty { From 0ad7701b04f03602ef1cd86ebbae09d4a0f5a2b1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 5 Jan 2026 16:34:41 +1100 Subject: [PATCH 1738/3801] Remove `variables` arg from `Canonicalizer::canonicalize_response`. It's an empty `Vec` at both call sites, and so is unnecessary. --- .../rustc_next_trait_solver/src/canonical/canonicalizer.rs | 4 ++-- compiler/rustc_next_trait_solver/src/canonical/mod.rs | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 6c114d601157..c2a7414911ff 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -84,14 +84,14 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { pub(super) fn canonicalize_response>( delegate: &'a D, max_input_universe: ty::UniverseIndex, - variables: &'a mut Vec, value: T, ) -> ty::Canonical { + let mut variables = Vec::new(); let mut canonicalizer = Canonicalizer { delegate, canonicalize_mode: CanonicalizeMode::Response { max_input_universe }, - variables, + variables: &mut variables, variable_lookup_table: Default::default(), sub_root_lookup_table: Default::default(), var_kinds: Vec::new(), diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index b4cea8701d82..d562b8fac4c4 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -82,10 +82,7 @@ where I: Interner, T: TypeFoldable, { - let mut orig_values = Default::default(); - let canonical = - Canonicalizer::canonicalize_response(delegate, max_input_universe, &mut orig_values, value); - canonical + Canonicalizer::canonicalize_response(delegate, max_input_universe, value) } /// After calling a canonical query, we apply the constraints returned @@ -308,7 +305,7 @@ where let var_values = CanonicalVarValues { var_values: delegate.cx().mk_args(var_values) }; let state = inspect::State { var_values, data }; let state = eager_resolve_vars(delegate, state); - Canonicalizer::canonicalize_response(delegate, max_input_universe, &mut vec![], state) + Canonicalizer::canonicalize_response(delegate, max_input_universe, state) } // FIXME: needs to be pub to be accessed by downstream From 4ae3c85a5ef8597aa11d1a547581312ebf56e3b1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 7 Jan 2026 13:10:22 +1100 Subject: [PATCH 1739/3801] Use the name `var_kinds` more. Variables that are collections of `CanonicalVarKind` are sometimes called `var_kinds` and sometimes called `variables`. The former is much better, because `variables` is (a) non-descript, and (b) often used nearby for collections of `I::GenericArg`. I found the inconsistency made the canonicalization code harder to understand. This commit renames various `variables` things as `var_kinds`. --- .../src/infer/canonical/canonicalizer.rs | 38 ++++++------ .../src/infer/canonical/instantiate.rs | 2 +- .../rustc_infer/src/infer/canonical/mod.rs | 2 +- .../src/infer/canonical/query_response.rs | 8 +-- compiler/rustc_middle/src/infer/canonical.rs | 2 +- .../src/canonical/canonicalizer.rs | 8 +-- .../src/canonical/mod.rs | 12 ++-- .../src/solve/eval_ctxt/mod.rs | 8 +-- .../src/solve/eval_ctxt/probe.rs | 2 +- .../src/solve/search_graph.rs | 2 +- compiler/rustc_type_ir/src/canonical.rs | 24 ++++---- ..._of_reborrow.SimplifyCfg-initial.after.mir | 60 +++++++++---------- ...ignment.main.SimplifyCfg-initial.after.mir | 4 +- .../issue_101867.main.built.after.mir | 4 +- ...ceiver_ptr_mutability.main.built.after.mir | 8 +-- ..._type_annotations.let_else.built.after.mir | 4 +- ...otations.let_else_bindless.built.after.mir | 4 +- ..._type_annotations.let_init.built.after.mir | 4 +- ...otations.let_init_bindless.built.after.mir | 4 +- ...ype_annotations.let_uninit.built.after.mir | 2 +- ...ations.let_uninit_bindless.built.after.mir | 2 +- ...otations.match_assoc_const.built.after.mir | 4 +- ...ns.match_assoc_const_range.built.after.mir | 8 +-- .../issue_72181_1.main.built.after.mir | 4 +- .../issue_99325.main.built.after.32bit.mir | 4 +- .../issue_99325.main.built.after.64bit.mir | 4 +- 26 files changed, 114 insertions(+), 114 deletions(-) diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index c07b41b56caa..23f6fee406a5 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -289,7 +289,7 @@ struct Canonicalizer<'cx, 'tcx> { /// Set to `None` to disable the resolution of inference variables. infcx: Option<&'cx InferCtxt<'tcx>>, tcx: TyCtxt<'tcx>, - variables: SmallVec<[CanonicalVarKind<'tcx>; 8]>, + var_kinds: SmallVec<[CanonicalVarKind<'tcx>; 8]>, query_state: &'cx mut OriginalQueryValues<'tcx>, // Note that indices is only used once `var_values` is big enough to be // heap-allocated. @@ -507,7 +507,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { { let base = Canonical { max_universe: ty::UniverseIndex::ROOT, - variables: List::empty(), + var_kinds: List::empty(), value: (), }; Canonicalizer::canonicalize_with_base( @@ -548,7 +548,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { tcx, canonicalize_mode: canonicalize_region_mode, needs_canonical_flags, - variables: SmallVec::from_slice(base.variables), + var_kinds: SmallVec::from_slice(base.var_kinds), query_state, indices: FxHashMap::default(), sub_root_lookup_table: Default::default(), @@ -569,16 +569,16 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { // anymore. debug_assert!(!out_value.has_infer() && !out_value.has_placeholders()); - let canonical_variables = - tcx.mk_canonical_var_kinds(&canonicalizer.universe_canonicalized_variables()); + let canonical_var_kinds = + tcx.mk_canonical_var_kinds(&canonicalizer.universe_canonicalized_var_kinds()); - let max_universe = canonical_variables + let max_universe = canonical_var_kinds .iter() .map(|cvar| cvar.universe()) .max() .unwrap_or(ty::UniverseIndex::ROOT); - Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) } + Canonical { max_universe, var_kinds: canonical_var_kinds, value: (base.value, out_value) } } /// Creates a canonical variable replacing `kind` from the input, @@ -590,7 +590,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { var_kind: CanonicalVarKind<'tcx>, value: GenericArg<'tcx>, ) -> BoundVar { - let Canonicalizer { variables, query_state, indices, .. } = self; + let Canonicalizer { var_kinds, query_state, indices, .. } = self; let var_values = &mut query_state.var_values; @@ -607,7 +607,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { } } - // This code is hot. `variables` and `var_values` are usually small + // This code is hot. `var_kinds` and `var_values` are usually small // (fewer than 8 elements ~95% of the time). They are SmallVec's to // avoid allocations in those cases. We also don't use `indices` to // determine if a kind has been seen before until the limit of 8 has @@ -620,10 +620,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { BoundVar::new(idx) } else { // `kind` isn't present in `var_values`. Append it. Likewise - // for `var_kind` and `variables`. - variables.push(var_kind); + // for `var_kind` and `var_kinds`. + var_kinds.push(var_kind); var_values.push(value); - assert_eq!(variables.len(), var_values.len()); + assert_eq!(var_kinds.len(), var_values.len()); // If `var_values` has become big enough to be heap-allocated, // fill up `indices` to facilitate subsequent lookups. @@ -641,10 +641,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { } else { // `var_values` is large. Do a hashmap search via `indices`. *indices.entry(value).or_insert_with(|| { - variables.push(var_kind); + var_kinds.push(var_kind); var_values.push(value); - assert_eq!(variables.len(), var_values.len()); - BoundVar::new(variables.len() - 1) + assert_eq!(var_kinds.len(), var_values.len()); + BoundVar::new(var_kinds.len() - 1) }) } } @@ -652,16 +652,16 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { fn get_or_insert_sub_root(&mut self, vid: ty::TyVid) -> ty::BoundVar { let root_vid = self.infcx.unwrap().sub_unification_table_root_var(vid); let idx = - *self.sub_root_lookup_table.entry(root_vid).or_insert_with(|| self.variables.len()); + *self.sub_root_lookup_table.entry(root_vid).or_insert_with(|| self.var_kinds.len()); ty::BoundVar::from(idx) } /// Replaces the universe indexes used in `var_values` with their index in /// `query_state.universe_map`. This minimizes the maximum universe used in /// the canonicalized value. - fn universe_canonicalized_variables(self) -> SmallVec<[CanonicalVarKind<'tcx>; 8]> { + fn universe_canonicalized_var_kinds(self) -> SmallVec<[CanonicalVarKind<'tcx>; 8]> { if self.query_state.universe_map.len() == 1 { - return self.variables; + return self.var_kinds; } let reverse_universe_map: FxHashMap = self @@ -672,7 +672,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { .map(|(idx, universe)| (*universe, ty::UniverseIndex::from_usize(idx))) .collect(); - self.variables + self.var_kinds .iter() .map(|&kind| match kind { CanonicalVarKind::Int | CanonicalVarKind::Float => { diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs index c215a9db2a0a..66a7bd2fc636 100644 --- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs +++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs @@ -43,7 +43,7 @@ impl<'tcx, V> Canonical<'tcx, V> { where T: TypeFoldable>, { - assert_eq!(self.variables.len(), var_values.len()); + assert_eq!(self.var_kinds.len(), var_values.len()); let value = projection_fn(&self.value); instantiate_value(tcx, var_values, value) } diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 9af0e17be4e2..c6826d774216 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -68,7 +68,7 @@ impl<'tcx> InferCtxt<'tcx> { .collect(); let var_values = - CanonicalVarValues::instantiate(self.tcx, &canonical.variables, |var_values, info| { + CanonicalVarValues::instantiate(self.tcx, &canonical.var_kinds, |var_values, info| { self.instantiate_canonical_var(span, info, &var_values, |ui| universes[ui]) }); let result = canonical.instantiate(self.tcx, &var_values); diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index b4952e7bfe15..65b0f8211432 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -430,7 +430,7 @@ impl<'tcx> InferCtxt<'tcx> { // result, then we can type the corresponding value from the // input. See the example above. let mut opt_values: IndexVec>> = - IndexVec::from_elem_n(None, query_response.variables.len()); + IndexVec::from_elem_n(None, query_response.var_kinds.len()); for (original_value, result_value) in iter::zip(&original_values.var_values, result_values) { @@ -442,7 +442,7 @@ impl<'tcx> InferCtxt<'tcx> { // more involved. They are also a lot rarer than region variables. if let ty::Bound(index_kind, b) = *result_value.kind() && !matches!( - query_response.variables[b.var.as_usize()], + query_response.var_kinds[b.var.as_usize()], CanonicalVarKind::Ty { .. } ) { @@ -472,8 +472,8 @@ impl<'tcx> InferCtxt<'tcx> { // given variable in the loop above, use that. Otherwise, use // a fresh inference variable. let tcx = self.tcx; - let variables = query_response.variables; - let var_values = CanonicalVarValues::instantiate(tcx, variables, |var_values, kind| { + let var_kinds = query_response.var_kinds; + let var_values = CanonicalVarValues::instantiate(tcx, var_kinds, |var_values, kind| { if kind.universe() != ty::UniverseIndex::ROOT { // A variable from inside a binder of the query. While ideally these shouldn't // exist at all, we have to deal with them for now. diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 153605ee7f81..32c6b6e9c0ba 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -169,7 +169,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> { ) { return Canonical { max_universe: ty::UniverseIndex::ROOT, - variables: List::empty(), + var_kinds: List::empty(), value: key, }; } diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index c2a7414911ff..5349b5657d51 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -106,8 +106,8 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { }; debug_assert!(!value.has_infer(), "unexpected infer in {value:?}"); debug_assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}"); - let (max_universe, variables) = canonicalizer.finalize(); - Canonical { max_universe, variables, value } + let (max_universe, var_kinds) = canonicalizer.finalize(); + Canonical { max_universe, var_kinds, value } } fn canonicalize_param_env( @@ -235,8 +235,8 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { debug_assert!(!value.has_infer(), "unexpected infer in {value:?}"); debug_assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}"); - let (max_universe, variables) = rest_canonicalizer.finalize(); - Canonical { max_universe, variables, value } + let (max_universe, var_kinds) = rest_canonicalizer.finalize(); + Canonical { max_universe, var_kinds, value } } fn get_or_insert_bound_var( diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index d562b8fac4c4..ffc666e36179 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -154,7 +154,7 @@ where // // We therefore instantiate the existential variable in the canonical response with the // inference variable of the input right away, which is more performant. - let mut opt_values = IndexVec::from_elem_n(None, response.variables.len()); + let mut opt_values = IndexVec::from_elem_n(None, response.var_kinds.len()); for (original_value, result_value) in iter::zip(original_values, var_values.var_values.iter()) { match result_value.kind() { ty::GenericArgKind::Type(t) => { @@ -164,7 +164,7 @@ where // more involved. They are also a lot rarer than region variables. if let ty::Bound(index_kind, b) = t.kind() && !matches!( - response.variables.get(b.var().as_usize()).unwrap(), + response.var_kinds.get(b.var().as_usize()).unwrap(), CanonicalVarKind::Ty { .. } ) { @@ -186,7 +186,7 @@ where } } } - CanonicalVarValues::instantiate(delegate.cx(), response.variables, |var_values, kind| { + CanonicalVarValues::instantiate(delegate.cx(), response.var_kinds, |var_values, kind| { if kind.universe() != ty::UniverseIndex::ROOT { // A variable from inside a binder of the query. While ideally these shouldn't // exist at all (see the FIXME at the start of this method), we have to deal with @@ -342,14 +342,14 @@ where pub fn response_no_constraints_raw( cx: I, max_universe: ty::UniverseIndex, - variables: I::CanonicalVarKinds, + var_kinds: I::CanonicalVarKinds, certainty: Certainty, ) -> CanonicalResponse { ty::Canonical { max_universe, - variables, + var_kinds, value: Response { - var_values: ty::CanonicalVarValues::make_identity(cx, variables), + var_values: ty::CanonicalVarValues::make_identity(cx, var_kinds), // FIXME: maybe we should store the "no response" version in cx, like // we do for cx.types and stuff. external_constraints: cx.mk_external_constraints(ExternalConstraintsData::default()), diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 8d0a3ac94d5a..2fd79f593a5f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -97,7 +97,7 @@ where /// The variable info for the `var_values`, only used to make an ambiguous response /// with no constraints. - variables: I::CanonicalVarKinds, + var_kinds: I::CanonicalVarKinds, /// What kind of goal we're currently computing, see the enum definition /// for more info. @@ -325,7 +325,7 @@ where // which we don't do within this evaluation context. max_input_universe: ty::UniverseIndex::ROOT, initial_opaque_types_storage_num_entries: Default::default(), - variables: Default::default(), + var_kinds: Default::default(), var_values: CanonicalVarValues::dummy(), current_goal_kind: CurrentGoalKind::Misc, origin_span, @@ -376,7 +376,7 @@ where let initial_opaque_types_storage_num_entries = delegate.opaque_types_storage_num_entries(); let mut ecx = EvalCtxt { delegate, - variables: canonical_input.canonical.variables, + var_kinds: canonical_input.canonical.var_kinds, var_values, current_goal_kind: CurrentGoalKind::from_query_input(cx, input), max_input_universe: canonical_input.canonical.max_universe, @@ -1323,7 +1323,7 @@ where response_no_constraints_raw( self.cx(), self.max_input_universe, - self.variables, + self.var_kinds, Certainty::Maybe { cause, opaque_types_jank }, ) } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs index e5658ba32ff6..edf2a5d1ba8d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs @@ -47,7 +47,7 @@ where let max_input_universe = outer.max_input_universe; let mut nested = EvalCtxt { delegate, - variables: outer.variables, + var_kinds: outer.var_kinds, var_values: outer.var_values, current_goal_kind: outer.current_goal_kind, max_input_universe, diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index ea45d5096990..73044b7943ae 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -143,7 +143,7 @@ fn response_no_constraints( Ok(response_no_constraints_raw( cx, input.canonical.max_universe, - input.canonical.variables, + input.canonical.var_kinds, certainty, )) } diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 47e753d78731..12d222258b0c 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -38,7 +38,7 @@ impl Eq for CanonicalQueryInput {} pub struct Canonical { pub value: V, pub max_universe: UniverseIndex, - pub variables: I::CanonicalVarKinds, + pub var_kinds: I::CanonicalVarKinds, } impl Eq for Canonical {} @@ -68,17 +68,17 @@ impl Canonical { /// let b: Canonical)> = a.unchecked_map(|v| (v, ty)); /// ``` pub fn unchecked_map(self, map_op: impl FnOnce(V) -> W) -> Canonical { - let Canonical { max_universe, variables, value } = self; - Canonical { max_universe, variables, value: map_op(value) } + let Canonical { max_universe, var_kinds, value } = self; + Canonical { max_universe, var_kinds, value: map_op(value) } } } impl fmt::Display for Canonical { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { value, max_universe, variables } = self; + let Self { value, max_universe, var_kinds } = self; write!( f, - "Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?} }}", + "Canonical {{ value: {value}, max_universe: {max_universe:?}, var_kinds: {var_kinds:?} }}", ) } } @@ -311,30 +311,30 @@ impl CanonicalVarValues { pub fn instantiate( cx: I, - variables: I::CanonicalVarKinds, + var_kinds: I::CanonicalVarKinds, mut f: impl FnMut(&[I::GenericArg], CanonicalVarKind) -> I::GenericArg, ) -> CanonicalVarValues { // Instantiating `CanonicalVarValues` is really hot, but limited to less than // 4 most of the time. Avoid creating a `Vec` here. - if variables.len() <= 4 { + if var_kinds.len() <= 4 { let mut var_values = ArrayVec::<_, 4>::new(); - for info in variables.iter() { + for info in var_kinds.iter() { var_values.push(f(&var_values, info)); } CanonicalVarValues { var_values: cx.mk_args(&var_values) } } else { - CanonicalVarValues::instantiate_cold(cx, variables, f) + CanonicalVarValues::instantiate_cold(cx, var_kinds, f) } } #[cold] fn instantiate_cold( cx: I, - variables: I::CanonicalVarKinds, + var_kinds: I::CanonicalVarKinds, mut f: impl FnMut(&[I::GenericArg], CanonicalVarKind) -> I::GenericArg, ) -> CanonicalVarValues { - let mut var_values = Vec::with_capacity(variables.len()); - for info in variables.iter() { + let mut var_values = Vec::with_capacity(var_kinds.len()); + for info in var_kinds.iter() { var_values.push(f(&var_values, info)); } CanonicalVarValues { var_values: cx.mk_args(&var_values) } diff --git a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir index a1fe278c6520..40527446e5dd 100644 --- a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -1,36 +1,36 @@ // MIR for `address_of_reborrow` after SimplifyCfg-initial | User Type Annotations -| 0: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10] -| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send -| 2: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] -| 3: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] -| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] -| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] -| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send -| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send -| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] -| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] -| 10: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10] -| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send -| 12: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] -| 13: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] -| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] -| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] -| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send -| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send -| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] -| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] -| 20: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10] -| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send -| 22: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] -| 23: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] -| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] -| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] -| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send -| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send -| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32] -| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32] +| 0: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, var_kinds: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10] +| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, var_kinds: [Region(U0)] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send +| 2: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, var_kinds: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] +| 3: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, var_kinds: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] +| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] +| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] +| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, var_kinds: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send +| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, var_kinds: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send +| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] +| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] +| 10: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, var_kinds: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10] +| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, var_kinds: [Region(U0)] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send +| 12: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, var_kinds: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] +| 13: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, var_kinds: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] +| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] +| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] +| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, var_kinds: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send +| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, var_kinds: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send +| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] +| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] +| 20: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, var_kinds: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10] +| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, var_kinds: [Region(U0)] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send +| 22: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, var_kinds: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] +| 23: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, var_kinds: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] +| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] +| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] +| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, var_kinds: [Region(U0)] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send +| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, var_kinds: [Region(U0)] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send +| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32] +| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, var_kinds: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32] | fn address_of_reborrow() -> () { let mut _0: (); diff --git a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir index b9d26c67538e..aa7d75242b40 100644 --- a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir @@ -1,8 +1,8 @@ // MIR for `main` after SimplifyCfg-initial | User Type Annotations -| 0: user_ty: Canonical { value: Ty(std::option::Option>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option> -| 1: user_ty: Canonical { value: Ty(std::option::Option>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option> +| 0: user_ty: Canonical { value: Ty(std::option::Option>), max_universe: U0, var_kinds: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option> +| 1: user_ty: Canonical { value: Ty(std::option::Option>), max_universe: U0, var_kinds: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option> | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir index fa35658a16d4..83281dea44db 100644 --- a/tests/mir-opt/building/issue_101867.main.built.after.mir +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty(std::option::Option), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:5:12: 5:22, inferred_ty: std::option::Option -| 1: user_ty: Canonical { value: Ty(std::option::Option), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:5:12: 5:22, inferred_ty: std::option::Option +| 0: user_ty: Canonical { value: Ty(std::option::Option), max_universe: U0, var_kinds: [] }, span: $DIR/issue_101867.rs:5:12: 5:22, inferred_ty: std::option::Option +| 1: user_ty: Canonical { value: Ty(std::option::Option), max_universe: U0, var_kinds: [] }, span: $DIR/issue_101867.rs:5:12: 5:22, inferred_ty: std::option::Option | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir index 5cf182c21c31..0c73bd8ac654 100644 --- a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir +++ b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir @@ -1,10 +1,10 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:16:14: 16:23, inferred_ty: *mut Test -| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:16:14: 16:23, inferred_ty: *mut Test -| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [Region(U0), Region(U0), Region(U0), Region(U0)] }, span: $DIR/receiver_ptr_mutability.rs:20:18: 20:31, inferred_ty: &&&&*mut Test -| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [Region(U0), Region(U0), Region(U0), Region(U0)] }, span: $DIR/receiver_ptr_mutability.rs:20:18: 20:31, inferred_ty: &&&&*mut Test +| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, var_kinds: [] }, span: $DIR/receiver_ptr_mutability.rs:16:14: 16:23, inferred_ty: *mut Test +| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, var_kinds: [] }, span: $DIR/receiver_ptr_mutability.rs:16:14: 16:23, inferred_ty: *mut Test +| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, var_kinds: [Region(U0), Region(U0), Region(U0), Region(U0)] }, span: $DIR/receiver_ptr_mutability.rs:20:18: 20:31, inferred_ty: &&&&*mut Test +| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, var_kinds: [Region(U0), Region(U0), Region(U0), Region(U0)] }, span: $DIR/receiver_ptr_mutability.rs:20:18: 20:31, inferred_ty: &&&&*mut Test | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir index bbf504d311f6..4b6aa46129a4 100644 --- a/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir @@ -1,8 +1,8 @@ // MIR for `let_else` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:36:20: 36:45, inferred_ty: (u32, u64, &char) -| 1: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:36:20: 36:45, inferred_ty: (u32, u64, &char) +| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:36:20: 36:45, inferred_ty: (u32, u64, &char) +| 1: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:36:20: 36:45, inferred_ty: (u32, u64, &char) | fn let_else() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir index 7bf2551e99f2..3814980b4306 100644 --- a/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir @@ -1,8 +1,8 @@ // MIR for `let_else_bindless` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:41:20: 41:45, inferred_ty: (u32, u64, &char) -| 1: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:41:20: 41:45, inferred_ty: (u32, u64, &char) +| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:41:20: 41:45, inferred_ty: (u32, u64, &char) +| 1: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:41:20: 41:45, inferred_ty: (u32, u64, &char) | fn let_else_bindless() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/user_type_annotations.let_init.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_init.built.after.mir index 0cf681d8ab2c..dd05ef37de3c 100644 --- a/tests/mir-opt/building/user_type_annotations.let_init.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_init.built.after.mir @@ -1,8 +1,8 @@ // MIR for `let_init` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:26:20: 26:45, inferred_ty: (u32, u64, &char) -| 1: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:26:20: 26:45, inferred_ty: (u32, u64, &char) +| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:26:20: 26:45, inferred_ty: (u32, u64, &char) +| 1: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:26:20: 26:45, inferred_ty: (u32, u64, &char) | fn let_init() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/user_type_annotations.let_init_bindless.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_init_bindless.built.after.mir index 968813c826e4..d949e1945339 100644 --- a/tests/mir-opt/building/user_type_annotations.let_init_bindless.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_init_bindless.built.after.mir @@ -1,8 +1,8 @@ // MIR for `let_init_bindless` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:31:20: 31:45, inferred_ty: (u32, u64, &char) -| 1: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:31:20: 31:45, inferred_ty: (u32, u64, &char) +| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:31:20: 31:45, inferred_ty: (u32, u64, &char) +| 1: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:31:20: 31:45, inferred_ty: (u32, u64, &char) | fn let_init_bindless() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/user_type_annotations.let_uninit.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_uninit.built.after.mir index b6fdc4ff46dc..22bf17bd7898 100644 --- a/tests/mir-opt/building/user_type_annotations.let_uninit.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_uninit.built.after.mir @@ -1,7 +1,7 @@ // MIR for `let_uninit` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:16:20: 16:45, inferred_ty: (u32, u64, &char) +| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:16:20: 16:45, inferred_ty: (u32, u64, &char) | fn let_uninit() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/user_type_annotations.let_uninit_bindless.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_uninit_bindless.built.after.mir index 472dbfb63043..aad2de0e7d6e 100644 --- a/tests/mir-opt/building/user_type_annotations.let_uninit_bindless.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_uninit_bindless.built.after.mir @@ -1,7 +1,7 @@ // MIR for `let_uninit_bindless` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:21:20: 21:45, inferred_ty: (u32, u64, &char) +| 0: user_ty: Canonical { value: Ty((u32, u64, &'static char)), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:21:20: 21:45, inferred_ty: (u32, u64, &char) | fn let_uninit_bindless() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/user_type_annotations.match_assoc_const.built.after.mir b/tests/mir-opt/building/user_type_annotations.match_assoc_const.built.after.mir index ff4b0bf7600d..8ec5028250b0 100644 --- a/tests/mir-opt/building/user_type_annotations.match_assoc_const.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.match_assoc_const.built.after.mir @@ -1,8 +1,8 @@ // MIR for `match_assoc_const` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:55:9: 55:44, inferred_ty: u32 -| 1: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:55:9: 55:44, inferred_ty: u32 +| 0: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:55:9: 55:44, inferred_ty: u32 +| 1: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:55:9: 55:44, inferred_ty: u32 | fn match_assoc_const() -> () { let mut _0: (); diff --git a/tests/mir-opt/building/user_type_annotations.match_assoc_const_range.built.after.mir b/tests/mir-opt/building/user_type_annotations.match_assoc_const_range.built.after.mir index 4cc433f475f6..61e5d9b459d0 100644 --- a/tests/mir-opt/building/user_type_annotations.match_assoc_const_range.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.match_assoc_const_range.built.after.mir @@ -1,10 +1,10 @@ // MIR for `match_assoc_const_range` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:63:11: 63:46, inferred_ty: u32 -| 1: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:63:11: 63:46, inferred_ty: u32 -| 2: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:64:9: 64:44, inferred_ty: u32 -| 3: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/user_type_annotations.rs:64:9: 64:44, inferred_ty: u32 +| 0: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:63:11: 63:46, inferred_ty: u32 +| 1: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:63:11: 63:46, inferred_ty: u32 +| 2: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:64:9: 64:44, inferred_ty: u32 +| 3: user_ty: Canonical { value: TypeOf(DefId(0:11 ~ user_type_annotations[ee8e]::MyTrait::FOO), UserArgs { args: [MyStruct, 'static], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/user_type_annotations.rs:64:9: 64:44, inferred_ty: u32 | fn match_assoc_const_range() -> () { let mut _0: (); diff --git a/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir index 79eaf9668330..398a4bcb3ab3 100644 --- a/tests/mir-opt/issue_72181_1.main.built.after.mir +++ b/tests/mir-opt/issue_72181_1.main.built.after.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void -| 1: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void +| 0: user_ty: Canonical { value: Ty(Void), max_universe: U0, var_kinds: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void +| 1: user_ty: Canonical { value: Ty(Void), max_universe: U0, var_kinds: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir index 48a399eb39ce..9e48cf038bf2 100644 --- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir index 48a399eb39ce..9e48cf038bf2 100644 --- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, var_kinds: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); From 65756bed80e0ce759cb5b6fa9fe80578e18d6981 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 8 Jan 2026 14:54:26 +1100 Subject: [PATCH 1740/3801] Remove out of date FIXME comment. In #127273 I added a test and a FIXME comment pointing out how it does the wrong thing. In the next commit I fixed the problem but forgot to remove the FIXME comment, whoops. --- compiler/rustc_parse/src/parser/tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index a46fcd30fef4..62e97c0c308c 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -2666,7 +2666,6 @@ fn look_ahead_non_outermost_stream() { }); } -// FIXME(nnethercote) All the output is currently wrong. #[test] fn debug_lookahead() { create_default_session_globals_then(|| { From f8240839704855d24823c5b2daf398144bcc7f43 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 7 Jan 2026 13:14:23 +1100 Subject: [PATCH 1741/3801] Make `Canonicalizer::variables` owned. Currently it's a mutable reference, but it doesn't need to be, because what's passed in is always a mutable reference to an empty `Vec`. This requires returning variables in a few extra places, which is fine. It makes the handling of `variables` the same as the handling of `var_kinds` and `variable_lookup_table`. --- .../src/canonical/canonicalizer.rs | 48 +++++++++---------- .../src/canonical/mod.rs | 4 +- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 5349b5657d51..f71c8b122007 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -64,7 +64,7 @@ pub(super) struct Canonicalizer<'a, D: SolverDelegate, I: Interner canonicalize_mode: CanonicalizeMode, // Mutable fields. - variables: &'a mut Vec, + variables: Vec, var_kinds: Vec>, variable_lookup_table: HashMap, /// Maps each `sub_unification_table_root_var` to the index of the first @@ -86,12 +86,11 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { max_input_universe: ty::UniverseIndex, value: T, ) -> ty::Canonical { - let mut variables = Vec::new(); let mut canonicalizer = Canonicalizer { delegate, canonicalize_mode: CanonicalizeMode::Response { max_input_universe }, - variables: &mut variables, + variables: Vec::new(), variable_lookup_table: Default::default(), sub_root_lookup_table: Default::default(), var_kinds: Vec::new(), @@ -106,17 +105,17 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { }; debug_assert!(!value.has_infer(), "unexpected infer in {value:?}"); debug_assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}"); - let (max_universe, var_kinds) = canonicalizer.finalize(); + let (max_universe, _variables, var_kinds) = canonicalizer.finalize(); Canonical { max_universe, var_kinds, value } } fn canonicalize_param_env( delegate: &'a D, - variables: &'a mut Vec, param_env: I::ParamEnv, - ) -> (I::ParamEnv, HashMap, Vec>) { + ) -> (I::ParamEnv, Vec, Vec>, HashMap) + { if !param_env.has_type_flags(NEEDS_CANONICAL) { - return (param_env, Default::default(), Vec::new()); + return (param_env, Vec::new(), Vec::new(), Default::default()); } // Check whether we can use the global cache for this param_env. As we only use @@ -130,12 +129,11 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { delegate.cx().canonical_param_env_cache_get_or_insert( param_env, || { - let mut variables = Vec::new(); let mut env_canonicalizer = Canonicalizer { delegate, canonicalize_mode: CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv), - variables: &mut variables, + variables: Vec::new(), variable_lookup_table: Default::default(), sub_root_lookup_table: Default::default(), var_kinds: Vec::new(), @@ -148,18 +146,16 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { param_env, variable_lookup_table: env_canonicalizer.variable_lookup_table, var_kinds: env_canonicalizer.var_kinds, - variables, + variables: env_canonicalizer.variables, } }, |&CanonicalParamEnvCacheEntry { param_env, - variables: ref cache_variables, + ref variables, ref variable_lookup_table, ref var_kinds, }| { - debug_assert!(variables.is_empty()); - variables.extend(cache_variables.iter().copied()); - (param_env, variable_lookup_table.clone(), var_kinds.clone()) + (param_env, variables.clone(), var_kinds.clone(), variable_lookup_table.clone()) }, ) } else { @@ -167,7 +163,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { delegate, canonicalize_mode: CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv), - variables, + variables: Vec::new(), variable_lookup_table: Default::default(), sub_root_lookup_table: Default::default(), var_kinds: Vec::new(), @@ -176,7 +172,12 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { }; let param_env = param_env.fold_with(&mut env_canonicalizer); debug_assert!(env_canonicalizer.sub_root_lookup_table.is_empty()); - (param_env, env_canonicalizer.variable_lookup_table, env_canonicalizer.var_kinds) + ( + param_env, + env_canonicalizer.variables, + env_canonicalizer.var_kinds, + env_canonicalizer.variable_lookup_table, + ) } } @@ -190,12 +191,11 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { /// variable in the future by changing the way we detect global where-bounds. pub(super) fn canonicalize_input>( delegate: &'a D, - variables: &'a mut Vec, input: QueryInput, - ) -> ty::Canonical> { + ) -> (Vec, ty::Canonical>) { // First canonicalize the `param_env` while keeping `'static` - let (param_env, variable_lookup_table, var_kinds) = - Canonicalizer::canonicalize_param_env(delegate, variables, input.goal.param_env); + let (param_env, variables, var_kinds, variable_lookup_table) = + Canonicalizer::canonicalize_param_env(delegate, input.goal.param_env); // Then canonicalize the rest of the input without keeping `'static` // while *mostly* reusing the canonicalizer from above. let mut rest_canonicalizer = Canonicalizer { @@ -235,8 +235,8 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { debug_assert!(!value.has_infer(), "unexpected infer in {value:?}"); debug_assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}"); - let (max_universe, var_kinds) = rest_canonicalizer.finalize(); - Canonical { max_universe, var_kinds, value } + let (max_universe, variables, var_kinds) = rest_canonicalizer.finalize(); + (variables, Canonical { max_universe, var_kinds, value }) } fn get_or_insert_bound_var( @@ -277,7 +277,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { ty::BoundVar::from(idx) } - fn finalize(self) -> (ty::UniverseIndex, I::CanonicalVarKinds) { + fn finalize(self) -> (ty::UniverseIndex, Vec, I::CanonicalVarKinds) { let mut var_kinds = self.var_kinds; // See the rustc-dev-guide section about how we deal with universes // during canonicalization in the new solver. @@ -310,7 +310,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { } }; let var_kinds = self.delegate.cx().mk_canonical_var_kinds(&var_kinds); - (max_universe, var_kinds) + (max_universe, self.variables, var_kinds) } fn inner_fold_ty(&mut self, t: I::Ty) -> I::Ty { diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index ffc666e36179..96fea09013a1 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -59,10 +59,8 @@ where D: SolverDelegate, I: Interner, { - let mut orig_values = Default::default(); - let canonical = Canonicalizer::canonicalize_input( + let (orig_values, canonical) = Canonicalizer::canonicalize_input( delegate, - &mut orig_values, QueryInput { goal, predefined_opaques_in_body: delegate.cx().mk_predefined_opaques_in_body(opaque_types), From e4bbfe88566c5e06066809558ae655455777d151 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 7 Jan 2026 14:00:04 +1100 Subject: [PATCH 1742/3801] Avoid using `to_vec` to clone `Vec`s. It's weird. `clone` is better. --- compiler/rustc_trait_selection/src/solve/inspect/analyse.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index cdbf2b0aeb83..944d57bf95d1 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -144,7 +144,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { pub fn instantiate_nested_goals(&self, span: Span) -> Vec> { let infcx = self.goal.infcx; let param_env = self.goal.goal.param_env; - let mut orig_values = self.goal.orig_values.to_vec(); + let mut orig_values = self.goal.orig_values.clone(); let mut instantiated_goals = vec![]; for step in &self.steps { @@ -186,7 +186,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { pub fn instantiate_impl_args(&self, span: Span) -> ty::GenericArgsRef<'tcx> { let infcx = self.goal.infcx; let param_env = self.goal.goal.param_env; - let mut orig_values = self.goal.orig_values.to_vec(); + let mut orig_values = self.goal.orig_values.clone(); for step in &self.steps { match **step { From eb1645653b0993fa699c23bfbab94249be15bf1d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 7 Jan 2026 15:05:53 +1100 Subject: [PATCH 1743/3801] Update a comment. I did some measurements. The current choice of 16 is fine. --- .../rustc_next_trait_solver/src/canonical/canonicalizer.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index f71c8b122007..f6ec0dd09c57 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -244,8 +244,9 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { arg: impl Into, kind: CanonicalVarKind, ) -> ty::BoundVar { - // FIXME: 16 is made up and arbitrary. We should look at some - // perf data here. + // The exact value of 16 here doesn't matter that much (8 and 32 give extremely similar + // results). So long as we have protection against the rare cases where the length reaches + // 1000+ (e.g. `wg-grammar`). let arg = arg.into(); let idx = if self.variables.len() > 16 { if self.variable_lookup_table.is_empty() { From a07f71704adc575d56c353f5f08febda4af7fc3b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 7 Jan 2026 17:19:36 +1100 Subject: [PATCH 1744/3801] Add comments about predicate folding. This explains why the predicate folding code looks different to the ty/const folding code, something I was wondering. --- compiler/rustc_middle/src/ty/structural_impls.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 1a5a3f3965fa..314d2ba39632 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -586,11 +586,18 @@ impl<'tcx> TypeSuperFoldable> for ty::Predicate<'tcx> { self, folder: &mut F, ) -> Result { + // This method looks different to `Ty::try_super_fold_with` and `Const::super_fold_with`. + // Why is that? `PredicateKind` provides little scope for optimized folding, unlike + // `TyKind` and `ConstKind` (which have common variants that don't require recursive + // `fold_with` calls on their fields). So we just derive the `TypeFoldable` impl for + // `PredicateKind` and call it here because the derived code is as fast as hand-written + // code would be. let new = self.kind().try_fold_with(folder)?; Ok(folder.cx().reuse_or_mk_predicate(self, new)) } fn super_fold_with>>(self, folder: &mut F) -> Self { + // See comment in `Predicate::try_super_fold_with`. let new = self.kind().fold_with(folder); folder.cx().reuse_or_mk_predicate(self, new) } @@ -598,6 +605,7 @@ impl<'tcx> TypeSuperFoldable> for ty::Predicate<'tcx> { impl<'tcx> TypeSuperVisitable> for ty::Predicate<'tcx> { fn super_visit_with>>(&self, visitor: &mut V) -> V::Result { + // See comment in `Predicate::try_super_fold_with`. self.kind().visit_with(visitor) } } From b222cf3874eb8d3c1a881206f037f0aad1befede Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 8 Jan 2026 15:03:41 +1100 Subject: [PATCH 1745/3801] Tweak variable cloning. --- .../src/canonical/canonicalizer.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index f6ec0dd09c57..8dfa875ca6f9 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -151,11 +151,16 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { }, |&CanonicalParamEnvCacheEntry { param_env, - ref variables, + variables: ref cache_variables, ref variable_lookup_table, ref var_kinds, }| { - (param_env, variables.clone(), var_kinds.clone(), variable_lookup_table.clone()) + // FIXME(nnethercote): for reasons I don't understand, this `new`+`extend` + // combination is faster than `variables.clone()`, because it somehow avoids + // some allocations. + let mut variables = Vec::new(); + variables.extend(cache_variables.iter().copied()); + (param_env, variables, var_kinds.clone(), variable_lookup_table.clone()) }, ) } else { From 6a9de224c463f54dc66dec6e3dbe3e244d2d7014 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 8 Jan 2026 04:20:55 +0000 Subject: [PATCH 1746/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 548e586795f6b6fe089d8329aa5edbf0f5202646. --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 5ffe95a0b54f..4b08b0884ca8 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -e7d44143a12a526488e4f0c0d7ea8e62a4fe9354 +548e586795f6b6fe089d8329aa5edbf0f5202646 From e454835eef0df5c920377bba45b115e896f3bff9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 8 Jan 2026 10:25:58 +0300 Subject: [PATCH 1747/3801] resolve: Factor out and document the glob binding overwriting logic --- compiler/rustc_resolve/src/imports.rs | 116 ++++++++++++++++++-------- 1 file changed, 81 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index a8bb53cc7f27..3f998b8c8aa0 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -295,6 +295,24 @@ fn pub_use_of_private_extern_crate_hack(import: Import<'_>, decl: Decl<'_>) -> O } } +/// Removes identical import layers from two declarations. +fn remove_same_import<'ra>(d1: Decl<'ra>, d2: Decl<'ra>) -> (Decl<'ra>, Decl<'ra>) { + if let DeclKind::Import { import: import1, source_decl: d1_next } = d1.kind + && let DeclKind::Import { import: import2, source_decl: d2_next } = d2.kind + && import1 == import2 + && d1.ambiguity == d2.ambiguity + { + assert!(d1.ambiguity.is_none()); + assert_eq!(d1.warn_ambiguity, d2.warn_ambiguity); + assert_eq!(d1.expansion, d2.expansion); + assert_eq!(d1.span, d2.span); + assert_eq!(d1.vis, d2.vis); + remove_same_import(d1_next, d2_next) + } else { + (d1, d2) + } +} + impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Given an import and the declaration that it points to, /// create the corresponding import declaration. @@ -325,6 +343,61 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } + /// If `glob_decl` attempts to overwrite `old_glob_decl` in a module, + /// decide which one to keep. + fn select_glob_decl( + &self, + glob_decl: Decl<'ra>, + old_glob_decl: Decl<'ra>, + warn_ambiguity: bool, + ) -> Decl<'ra> { + assert!(glob_decl.is_glob_import()); + assert!(old_glob_decl.is_glob_import()); + assert_ne!(glob_decl, old_glob_decl); + // `best_decl` with a given key in a module may be overwritten in a + // number of cases (all of them can be seen below in the `match` in `try_define_local`), + // all these overwrites will be re-fetched by glob imports importing + // from that module without generating new ambiguities. + // - A glob decl is overwritten by a non-glob decl arriving later. + // - A glob decl is overwritten by an ambiguous glob decl. + // FIXME: avoid this by putting `DeclData::ambiguity` under a + // cell and updating it in place. + // - A glob decl is overwritten by the same decl with `warn_ambiguity == true`. + // FIXME: avoid this by putting `DeclData::warn_ambiguity` under a + // cell and updating it in place. + // - A glob decl is overwritten by a glob decl with larger visibility. + // FIXME: avoid this by putting `DeclData::vis` under a cell + // and updating it in place. + // - A glob decl is overwritten by a glob decl re-fetching an + // overwritten decl from other module (the recursive case). + // Here we are detecting all such re-fetches and overwrite old decls + // with the re-fetched decls. + // This is probably incorrect in corner cases, and the outdated decls still get + // propagated to other places and get stuck there, but that's what we have at the moment. + let (deep_decl, old_deep_decl) = remove_same_import(glob_decl, old_glob_decl); + if deep_decl != glob_decl { + // Some import layers have been removed, need to overwrite. + assert_ne!(old_deep_decl, old_glob_decl); + assert_ne!(old_deep_decl, deep_decl); + assert!(old_deep_decl.is_glob_import()); + if glob_decl.is_ambiguity_recursive() { + self.new_decl_with_warn_ambiguity(glob_decl) + } else { + glob_decl + } + } else if glob_decl.res() != old_glob_decl.res() { + self.new_decl_with_ambiguity(old_glob_decl, glob_decl, warn_ambiguity) + } else if !old_glob_decl.vis.is_at_least(glob_decl.vis, self.tcx) { + // We are glob-importing the same item but with greater visibility. + glob_decl + } else if glob_decl.is_ambiguity_recursive() { + // Overwriting with an ambiguous glob import. + self.new_decl_with_warn_ambiguity(glob_decl) + } else { + old_glob_decl + } + } + /// Attempt to put the declaration with the given name and namespace into the module, /// and return existing declaration if there is a collision. pub(crate) fn try_plant_decl_into_local_module( @@ -347,52 +420,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }); self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| { if let Some(old_decl) = resolution.best_decl() { + assert_ne!(decl, old_decl); if res == Res::Err && old_decl.res() != Res::Err { // Do not override real declarations with `Res::Err`s from error recovery. return Ok(()); } match (old_decl.is_glob_import(), decl.is_glob_import()) { (true, true) => { - let (glob_decl, old_glob_decl) = (decl, old_decl); - // FIXME: remove `!decl.is_ambiguity_recursive()` after delete the warning ambiguity. - if !decl.is_ambiguity_recursive() - && let DeclKind::Import { import: old_import, .. } = old_glob_decl.kind - && let DeclKind::Import { import, .. } = glob_decl.kind - && old_import == import - { - // When imported from the same glob-import statement, we should replace - // `old_glob_decl` with `glob_decl`, regardless of whether - // they have the same resolution or not. - resolution.glob_decl = Some(glob_decl); - } else if res != old_glob_decl.res() { - resolution.glob_decl = Some(this.new_decl_with_ambiguity( - old_glob_decl, - glob_decl, - warn_ambiguity, - )); - } else if !old_decl.vis.is_at_least(decl.vis, this.tcx) { - // We are glob-importing the same item but with greater visibility. - resolution.glob_decl = Some(glob_decl); - } else if decl.is_ambiguity_recursive() { - resolution.glob_decl = - Some(this.new_decl_with_warn_ambiguity(glob_decl)); - } + resolution.glob_decl = + Some(this.select_glob_decl(decl, old_decl, warn_ambiguity)); } (old_glob @ true, false) | (old_glob @ false, true) => { let (glob_decl, non_glob_decl) = if old_glob { (old_decl, decl) } else { (decl, old_decl) }; resolution.non_glob_decl = Some(non_glob_decl); - if let Some(old_glob_decl) = resolution.glob_decl { - assert!(old_glob_decl.is_glob_import()); - if glob_decl.res() != old_glob_decl.res() { - resolution.glob_decl = Some(this.new_decl_with_ambiguity( - old_glob_decl, - glob_decl, - false, - )); - } else if !old_glob_decl.vis.is_at_least(decl.vis, this.tcx) { - resolution.glob_decl = Some(glob_decl); - } + if let Some(old_glob_decl) = resolution.glob_decl + && old_glob_decl != glob_decl + { + resolution.glob_decl = + Some(this.select_glob_decl(glob_decl, old_glob_decl, false)); } else { resolution.glob_decl = Some(glob_decl); } From 32cf3a96d7d2695f16f00e594e291ae18c00dc32 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 29 Dec 2025 22:12:56 +0300 Subject: [PATCH 1748/3801] resolve: Update `NameBindingData::warn_ambiguity` in place instead of creating fresh bindings. --- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- .../src/effective_visibilities.rs | 4 ++-- compiler/rustc_resolve/src/imports.rs | 21 +++++++------------ compiler/rustc_resolve/src/lib.rs | 12 +++++------ 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index d56ca7c079cb..0159e9c9eda4 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -91,7 +91,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { kind: DeclKind::Def(res), ambiguity, // External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment. - warn_ambiguity: true, + warn_ambiguity: CmCell::new(true), vis, span, expansion, diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index e5144332f2b7..eee12922e511 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -127,7 +127,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { // lint. For all bindings added to the table this way `is_ambiguity` returns true. let is_ambiguity = |decl: Decl<'ra>, warn: bool| decl.ambiguity.is_some() && !warn; let mut parent_id = ParentId::Def(module_id); - let mut warn_ambiguity = decl.warn_ambiguity; + let mut warn_ambiguity = decl.warn_ambiguity.get(); while let DeclKind::Import { source_decl, .. } = decl.kind { self.update_import(decl, parent_id); @@ -140,7 +140,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { parent_id = ParentId::Import(decl); decl = source_decl; - warn_ambiguity |= source_decl.warn_ambiguity; + warn_ambiguity |= source_decl.warn_ambiguity.get(); } if !is_ambiguity(decl, warn_ambiguity) && let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local()) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 3f998b8c8aa0..7f28ac29ac1d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -303,7 +303,7 @@ fn remove_same_import<'ra>(d1: Decl<'ra>, d2: Decl<'ra>) -> (Decl<'ra>, Decl<'ra && d1.ambiguity == d2.ambiguity { assert!(d1.ambiguity.is_none()); - assert_eq!(d1.warn_ambiguity, d2.warn_ambiguity); + assert_eq!(d1.warn_ambiguity.get(), d2.warn_ambiguity.get()); assert_eq!(d1.expansion, d2.expansion); assert_eq!(d1.span, d2.span); assert_eq!(d1.vis, d2.vis); @@ -336,7 +336,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.arenas.alloc_decl(DeclData { kind: DeclKind::Import { source_decl: decl, import }, ambiguity: None, - warn_ambiguity: false, + warn_ambiguity: CmCell::new(false), span: import.span, vis, expansion: import.parent_scope.expansion, @@ -362,9 +362,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // - A glob decl is overwritten by an ambiguous glob decl. // FIXME: avoid this by putting `DeclData::ambiguity` under a // cell and updating it in place. - // - A glob decl is overwritten by the same decl with `warn_ambiguity == true`. - // FIXME: avoid this by putting `DeclData::warn_ambiguity` under a - // cell and updating it in place. // - A glob decl is overwritten by a glob decl with larger visibility. // FIXME: avoid this by putting `DeclData::vis` under a cell // and updating it in place. @@ -381,10 +378,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { assert_ne!(old_deep_decl, deep_decl); assert!(old_deep_decl.is_glob_import()); if glob_decl.is_ambiguity_recursive() { - self.new_decl_with_warn_ambiguity(glob_decl) - } else { - glob_decl + glob_decl.warn_ambiguity.set_unchecked(true); } + glob_decl } else if glob_decl.res() != old_glob_decl.res() { self.new_decl_with_ambiguity(old_glob_decl, glob_decl, warn_ambiguity) } else if !old_glob_decl.vis.is_at_least(glob_decl.vis, self.tcx) { @@ -392,7 +388,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { glob_decl } else if glob_decl.is_ambiguity_recursive() { // Overwriting with an ambiguous glob import. - self.new_decl_with_warn_ambiguity(glob_decl) + glob_decl.warn_ambiguity.set_unchecked(true); + glob_decl } else { old_glob_decl } @@ -466,15 +463,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { warn_ambiguity: bool, ) -> Decl<'ra> { let ambiguity = Some(secondary_decl); + let warn_ambiguity = CmCell::new(warn_ambiguity); let data = DeclData { ambiguity, warn_ambiguity, ..*primary_decl }; self.arenas.alloc_decl(data) } - fn new_decl_with_warn_ambiguity(&self, decl: Decl<'ra>) -> Decl<'ra> { - assert!(decl.is_ambiguity_recursive()); - self.arenas.alloc_decl(DeclData { warn_ambiguity: true, ..*decl }) - } - // Use `f` to mutate the resolution of the name in the module. // If the resolution becomes a success, define it in the module's glob importers. fn update_local_resolution( diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 063b6b4058f0..cf8d1952d4a0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -802,13 +802,13 @@ impl<'ra> fmt::Debug for Module<'ra> { } /// Data associated with any name declaration. -#[derive(Clone, Copy, Debug)] +#[derive(Debug)] struct DeclData<'ra> { kind: DeclKind<'ra>, ambiguity: Option>, /// Produce a warning instead of an error when reporting ambiguities inside this binding. /// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required. - warn_ambiguity: bool, + warn_ambiguity: CmCell, expansion: LocalExpnId, span: Span, vis: Visibility, @@ -956,7 +956,7 @@ impl<'ra> DeclData<'ra> { } fn warn_ambiguity_recursive(&self) -> bool { - self.warn_ambiguity + self.warn_ambiguity.get() || match self.kind { DeclKind::Import { source_decl, .. } => source_decl.warn_ambiguity_recursive(), _ => false, @@ -1343,7 +1343,7 @@ impl<'ra> ResolverArenas<'ra> { self.alloc_decl(DeclData { kind: DeclKind::Def(res), ambiguity: None, - warn_ambiguity: false, + warn_ambiguity: CmCell::new(false), vis, span, expansion, @@ -2041,7 +2041,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn record_use(&mut self, ident: Ident, used_decl: Decl<'ra>, used: Used) { - self.record_use_inner(ident, used_decl, used, used_decl.warn_ambiguity); + self.record_use_inner(ident, used_decl, used, used_decl.warn_ambiguity.get()); } fn record_use_inner( @@ -2112,7 +2112,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident, source_decl, Used::Other, - warn_ambiguity || source_decl.warn_ambiguity, + warn_ambiguity || source_decl.warn_ambiguity.get(), ); } } From 227e7bd48b5a7f3479bc4b231cf042e092fadd89 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Dec 2025 01:47:50 +0300 Subject: [PATCH 1749/3801] resolve: Update `NameBindingData::vis` in place instead of overwriting bindings in modules. --- .../rustc_resolve/src/build_reduced_graph.rs | 26 +++++++------- compiler/rustc_resolve/src/diagnostics.rs | 8 ++--- .../src/effective_visibilities.rs | 4 +-- compiler/rustc_resolve/src/ident.rs | 11 +++--- compiler/rustc_resolve/src/imports.rs | 35 +++++++++---------- .../rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 8 +++-- 7 files changed, 49 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 0159e9c9eda4..0167b8038649 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -92,7 +92,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ambiguity, // External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment. warn_ambiguity: CmCell::new(true), - vis, + vis: CmCell::new(vis), span, expansion, }); @@ -1158,18 +1158,18 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { self.r.potentially_unused_imports.push(import); module.for_each_child_mut(self, |this, ident, ns, binding| { if ns == MacroNS { - let import = if this.r.is_accessible_from(binding.vis, this.parent_scope.module) - { - import - } else { - // FIXME: This branch is used for reporting the `private_macro_use` lint - // and should eventually be removed. - if this.r.macro_use_prelude.contains_key(&ident.name) { - // Do not override already existing entries with compatibility entries. - return; - } - macro_use_import(this, span, true) - }; + let import = + if this.r.is_accessible_from(binding.vis(), this.parent_scope.module) { + import + } else { + // FIXME: This branch is used for reporting the `private_macro_use` lint + // and should eventually be removed. + if this.r.macro_use_prelude.contains_key(&ident.name) { + // Do not override already existing entries with compatibility entries. + return; + } + macro_use_import(this, span, true) + }; let import_decl = this.r.new_import_decl(binding, import); this.add_macro_use_decl(ident.name, import_decl, span, allow_shadowing); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7c86ed91a07a..d704280f3fa2 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1338,7 +1338,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } let child_accessible = - accessible && this.is_accessible_from(name_binding.vis, parent_scope.module); + accessible && this.is_accessible_from(name_binding.vis(), parent_scope.module); // do not venture inside inaccessible items of other crates if in_module_is_extern && !child_accessible { @@ -1358,8 +1358,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // #90113: Do not count an inaccessible reexported item as a candidate. if let DeclKind::Import { source_decl, .. } = name_binding.kind - && this.is_accessible_from(source_decl.vis, parent_scope.module) - && !this.is_accessible_from(name_binding.vis, parent_scope.module) + && this.is_accessible_from(source_decl.vis(), parent_scope.module) + && !this.is_accessible_from(name_binding.vis(), parent_scope.module) { return; } @@ -2243,7 +2243,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let first = binding == first_binding; let def_span = self.tcx.sess.source_map().guess_head_span(binding.span); let mut note_span = MultiSpan::from_span(def_span); - if !first && binding.vis.is_public() { + if !first && binding.vis().is_public() { let desc = match binding.kind { DeclKind::Import { .. } => "re-export", _ => "directly", diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index eee12922e511..7272314b9aa7 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -145,7 +145,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { if !is_ambiguity(decl, warn_ambiguity) && let Some(def_id) = decl.res().opt_def_id().and_then(|id| id.as_local()) { - self.update_def(def_id, decl.vis.expect_local(), parent_id); + self.update_def(def_id, decl.vis().expect_local(), parent_id); } } } @@ -188,7 +188,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { } fn update_import(&mut self, decl: Decl<'ra>, parent_id: ParentId<'ra>) { - let nominal_vis = decl.vis.expect_local(); + let nominal_vis = decl.vis().expect_local(); let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return }; let inherited_eff_vis = self.effective_vis_or_private(parent_id); let tcx = self.r.tcx; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index e0acf043ffcf..f47bb28d3fa1 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1017,7 +1017,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Items and single imports are not shadowable, if we have one, then it's determined. if let Some(binding) = binding { - let accessible = self.is_accessible_from(binding.vis, parent_scope.module); + let accessible = self.is_accessible_from(binding.vis(), parent_scope.module); return if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) }; } @@ -1103,7 +1103,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // shadowing is enabled, see `macro_expanded_macro_export_errors`). if let Some(binding) = binding { return if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted { - let accessible = self.is_accessible_from(binding.vis, parent_scope.module); + let accessible = self.is_accessible_from(binding.vis(), parent_scope.module); if accessible { Ok(binding) } else { Err(ControlFlow::Break(Determined)) } } else { Err(ControlFlow::Break(Undetermined)) @@ -1160,7 +1160,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match result { Err(Determined) => continue, Ok(binding) - if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) => + if !self.is_accessible_from(binding.vis(), glob_import.parent_scope.module) => { continue; } @@ -1187,7 +1187,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return Err(ControlFlow::Continue(Determined)); }; - if !self.is_accessible_from(binding.vis, parent_scope.module) { + if !self.is_accessible_from(binding.vis(), parent_scope.module) { if report_private { self.privacy_errors.push(PrivacyError { ident, @@ -1304,7 +1304,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { Err(Determined) => continue, Ok(binding) - if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) => + if !self + .is_accessible_from(binding.vis(), single_import.parent_scope.module) => { continue; } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 7f28ac29ac1d..5b0755dbde25 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -306,7 +306,7 @@ fn remove_same_import<'ra>(d1: Decl<'ra>, d2: Decl<'ra>) -> (Decl<'ra>, Decl<'ra assert_eq!(d1.warn_ambiguity.get(), d2.warn_ambiguity.get()); assert_eq!(d1.expansion, d2.expansion); assert_eq!(d1.span, d2.span); - assert_eq!(d1.vis, d2.vis); + assert_eq!(d1.vis(), d2.vis()); remove_same_import(d1_next, d2_next) } else { (d1, d2) @@ -318,12 +318,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// create the corresponding import declaration. pub(crate) fn new_import_decl(&self, decl: Decl<'ra>, import: Import<'ra>) -> Decl<'ra> { let import_vis = import.vis.to_def_id(); - let vis = if decl.vis.is_at_least(import_vis, self.tcx) + let vis = if decl.vis().is_at_least(import_vis, self.tcx) || pub_use_of_private_extern_crate_hack(import, decl).is_some() { import_vis } else { - decl.vis + decl.vis() }; if let ImportKind::Glob { ref max_vis, .. } = import.kind @@ -338,7 +338,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ambiguity: None, warn_ambiguity: CmCell::new(false), span: import.span, - vis, + vis: CmCell::new(vis), expansion: import.parent_scope.expansion, }) } @@ -362,9 +362,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // - A glob decl is overwritten by an ambiguous glob decl. // FIXME: avoid this by putting `DeclData::ambiguity` under a // cell and updating it in place. - // - A glob decl is overwritten by a glob decl with larger visibility. - // FIXME: avoid this by putting `DeclData::vis` under a cell - // and updating it in place. // - A glob decl is overwritten by a glob decl re-fetching an // overwritten decl from other module (the recursive case). // Here we are detecting all such re-fetches and overwrite old decls @@ -383,9 +380,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { glob_decl } else if glob_decl.res() != old_glob_decl.res() { self.new_decl_with_ambiguity(old_glob_decl, glob_decl, warn_ambiguity) - } else if !old_glob_decl.vis.is_at_least(glob_decl.vis, self.tcx) { + } else if !old_glob_decl.vis().is_at_least(glob_decl.vis(), self.tcx) { // We are glob-importing the same item but with greater visibility. - glob_decl + old_glob_decl.vis.set_unchecked(glob_decl.vis()); + old_glob_decl } else if glob_decl.is_ambiguity_recursive() { // Overwriting with an ambiguous glob import. glob_decl.warn_ambiguity.set_unchecked(true); @@ -464,7 +462,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) -> Decl<'ra> { let ambiguity = Some(secondary_decl); let warn_ambiguity = CmCell::new(warn_ambiguity); - let data = DeclData { ambiguity, warn_ambiguity, ..*primary_decl }; + let vis = primary_decl.vis.clone(); + let data = DeclData { ambiguity, warn_ambiguity, vis, ..*primary_decl }; self.arenas.alloc_decl(data) } @@ -509,7 +508,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(None) => import.parent_scope.module, None => continue, }; - if self.is_accessible_from(binding.vis, scope) { + if self.is_accessible_from(binding.vis(), scope) { let import_decl = self.new_import_decl(binding, *import); let _ = self.try_plant_decl_into_local_module( import.parent_scope.module, @@ -699,8 +698,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && let Some(glob_import_id) = glob_import.id() && let glob_import_def_id = self.local_def_id(glob_import_id) && self.effective_visibilities.is_exported(glob_import_def_id) - && glob_decl.vis.is_public() - && !binding.vis.is_public() + && glob_decl.vis().is_public() + && !binding.vis().is_public() { let binding_id = match binding.kind { DeclKind::Def(res) => { @@ -1330,9 +1329,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return; }; - if !binding.vis.is_at_least(import.vis, this.tcx) { + if !binding.vis().is_at_least(import.vis, this.tcx) { reexport_error = Some((ns, binding)); - if let Visibility::Restricted(binding_def_id) = binding.vis + if let Visibility::Restricted(binding_def_id) = binding.vis() && binding_def_id.is_top_level_module() { crate_private_reexport = true; @@ -1535,7 +1534,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(None) => import.parent_scope.module, None => continue, }; - if self.is_accessible_from(binding.vis, scope) { + if self.is_accessible_from(binding.vis(), scope) { let import_decl = self.new_import_decl(binding, import); let warn_ambiguity = self .resolution(import.parent_scope.module, key) @@ -1577,7 +1576,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let child = |reexport_chain| ModChild { ident: ident.0, res, - vis: binding.vis, + vis: binding.vis(), reexport_chain, }; if let Some((ambig_binding1, ambig_binding2)) = binding.descent_to_ambiguity() { @@ -1585,7 +1584,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let second = ModChild { ident: ident.0, res: ambig_binding2.res().expect_non_local(), - vis: ambig_binding2.vis, + vis: ambig_binding2.vis(), reexport_chain: ambig_binding2.reexport_chain(this), }; ambig_children.push(AmbigModChild { main, second }) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 73e1a8f0c3bc..a2805497e796 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2793,7 +2793,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { in_module.for_each_child(self.r, |r, ident, _, name_binding| { // abort if the module is already found or if name_binding is private external - if result.is_some() || !name_binding.vis.is_visible_locally() { + if result.is_some() || !name_binding.vis().is_visible_locally() { return; } if let Some(module_def_id) = name_binding.res().module_like_def_id() { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index cf8d1952d4a0..bce14f5376d7 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -811,7 +811,7 @@ struct DeclData<'ra> { warn_ambiguity: CmCell, expansion: LocalExpnId, span: Span, - vis: Visibility, + vis: CmCell>, } /// All name declarations are unique and allocated on a same arena, @@ -923,6 +923,10 @@ struct AmbiguityError<'ra> { } impl<'ra> DeclData<'ra> { + fn vis(&self) -> Visibility { + self.vis.get() + } + fn res(&self) -> Res { match self.kind { DeclKind::Def(res) => res, @@ -1344,7 +1348,7 @@ impl<'ra> ResolverArenas<'ra> { kind: DeclKind::Def(res), ambiguity: None, warn_ambiguity: CmCell::new(false), - vis, + vis: CmCell::new(vis), span, expansion, }) From c2379717a2e9f2befdbea2795fea696d7c86d82c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Dec 2025 02:49:14 +0300 Subject: [PATCH 1750/3801] resolve: Tweak overwriting with ambiguous globs Do not overwrite unless necessary, and combine both globs instead of losing the first one. --- compiler/rustc_resolve/src/imports.rs | 7 +++---- tests/ui/imports/ambiguous-14.stderr | 12 ++++++------ tests/ui/imports/duplicate.stderr | 12 ++++++------ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 5b0755dbde25..76aeb7ba85b8 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -384,10 +384,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // We are glob-importing the same item but with greater visibility. old_glob_decl.vis.set_unchecked(glob_decl.vis()); old_glob_decl - } else if glob_decl.is_ambiguity_recursive() { - // Overwriting with an ambiguous glob import. - glob_decl.warn_ambiguity.set_unchecked(true); - glob_decl + } else if glob_decl.is_ambiguity_recursive() && !old_glob_decl.is_ambiguity_recursive() { + // Overwriting a non-ambiguous glob import with an ambiguous glob import. + self.new_decl_with_ambiguity(old_glob_decl, glob_decl, true) } else { old_glob_decl } diff --git a/tests/ui/imports/ambiguous-14.stderr b/tests/ui/imports/ambiguous-14.stderr index 4efa31c61e32..2a3557c31f12 100644 --- a/tests/ui/imports/ambiguous-14.stderr +++ b/tests/ui/imports/ambiguous-14.stderr @@ -8,15 +8,15 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/ambiguous-14.rs:13:13 + --> $DIR/ambiguous-14.rs:18:13 | LL | pub use a::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/ambiguous-14.rs:14:13 + --> $DIR/ambiguous-14.rs:19:13 | -LL | pub use b::*; +LL | pub use f::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default @@ -34,15 +34,15 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/ambiguous-14.rs:13:13 + --> $DIR/ambiguous-14.rs:18:13 | LL | pub use a::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/ambiguous-14.rs:14:13 + --> $DIR/ambiguous-14.rs:19:13 | -LL | pub use b::*; +LL | pub use f::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default diff --git a/tests/ui/imports/duplicate.stderr b/tests/ui/imports/duplicate.stderr index 5cd3b0c2c8a5..74829fc21e22 100644 --- a/tests/ui/imports/duplicate.stderr +++ b/tests/ui/imports/duplicate.stderr @@ -78,15 +78,15 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/duplicate.rs:24:13 + --> $DIR/duplicate.rs:29:13 | LL | pub use crate::a::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/duplicate.rs:25:13 + --> $DIR/duplicate.rs:30:13 | -LL | pub use crate::b::*; +LL | pub use crate::f::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default @@ -106,15 +106,15 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/duplicate.rs:24:13 + --> $DIR/duplicate.rs:29:13 | LL | pub use crate::a::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/duplicate.rs:25:13 + --> $DIR/duplicate.rs:30:13 | -LL | pub use crate::b::*; +LL | pub use crate::f::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default From 5d8a7daf2ab5d13330030880af021cf1cf418a7e Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 8 Jan 2026 09:25:28 +0200 Subject: [PATCH 1751/3801] Fixes for builtin derive expansions - Do not store the `MacroCallId` of the "real" expansion anywhere, so that the IDE layer could not expand it by mistake - Fix a stupid bug where we used the directive of the `derive` itself instead of of the macro, leading us to re-expand it again and again. --- .../crates/hir-def/src/builtin_derive.rs | 22 ++++- .../crates/hir-def/src/dyn_map.rs | 10 ++- .../crates/hir-def/src/item_scope.rs | 19 ++-- .../crates/hir-def/src/lang_item.rs | 54 ++++++++++-- .../crates/hir-def/src/nameres.rs | 10 ++- .../crates/hir-def/src/nameres/collector.rs | 88 ++++++++++++------- .../rust-analyzer/crates/hir/src/semantics.rs | 31 +++++-- .../crates/hir/src/semantics/source_to_def.rs | 17 ++-- .../crates/ide/src/expand_macro.rs | 60 +++++-------- .../crates/intern/src/symbol/symbols.rs | 1 + 10 files changed, 211 insertions(+), 101 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs index 32385516ab58..946f08ec3682 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs @@ -8,7 +8,8 @@ use intern::{Symbol, sym}; use tt::TextRange; use crate::{ - AdtId, BuiltinDeriveImplId, BuiltinDeriveImplLoc, FunctionId, HasModule, db::DefDatabase, + AdtId, BuiltinDeriveImplId, BuiltinDeriveImplLoc, FunctionId, HasModule, MacroId, + db::DefDatabase, lang_item::LangItems, }; macro_rules! declare_enum { @@ -86,6 +87,25 @@ declare_enum!( DispatchFromDyn => [], ); +impl BuiltinDeriveImplTrait { + pub fn derive_macro(self, lang_items: &LangItems) -> Option { + match self { + BuiltinDeriveImplTrait::Copy => lang_items.CopyDerive, + BuiltinDeriveImplTrait::Clone => lang_items.CloneDerive, + BuiltinDeriveImplTrait::Default => lang_items.DefaultDerive, + BuiltinDeriveImplTrait::Debug => lang_items.DebugDerive, + BuiltinDeriveImplTrait::Hash => lang_items.HashDerive, + BuiltinDeriveImplTrait::Ord => lang_items.OrdDerive, + BuiltinDeriveImplTrait::PartialOrd => lang_items.PartialOrdDerive, + BuiltinDeriveImplTrait::Eq => lang_items.EqDerive, + BuiltinDeriveImplTrait::PartialEq => lang_items.PartialEqDerive, + BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { + lang_items.CoercePointeeDerive + } + } + } +} + impl BuiltinDeriveImplMethod { pub fn trait_method( self, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs index 7d3a94b03833..4308d0ef1c29 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs @@ -27,14 +27,15 @@ pub mod keys { use std::marker::PhantomData; + use either::Either; use hir_expand::{MacroCallId, attrs::AttrId}; use rustc_hash::FxHashMap; use syntax::{AstNode, AstPtr, ast}; use crate::{ - BlockId, ConstId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FieldId, FunctionId, - ImplId, LifetimeParamId, Macro2Id, MacroRulesId, ProcMacroId, StaticId, StructId, TraitId, - TypeAliasId, TypeOrConstParamId, UnionId, UseId, + BlockId, BuiltinDeriveImplId, ConstId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, + FieldId, FunctionId, ImplId, LifetimeParamId, Macro2Id, MacroRulesId, ProcMacroId, + StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, UnionId, UseId, dyn_map::{DynMap, Policy}, }; @@ -71,7 +72,8 @@ pub mod keys { ( AttrId, /* derive() */ MacroCallId, - /* actual derive macros */ Box<[Option]>, + /* actual derive macros */ + Box<[Option>]>, ), > = Key::new(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index a3278dd76c86..9e1efb977786 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -4,6 +4,7 @@ use std::{fmt, sync::LazyLock}; use base_db::Crate; +use either::Either; use hir_expand::{AstId, MacroCallId, attrs::AttrId, name::Name}; use indexmap::map::Entry; use itertools::Itertools; @@ -199,7 +200,7 @@ struct DeriveMacroInvocation { attr_id: AttrId, /// The `#[derive]` call attr_call_id: MacroCallId, - derive_call_ids: SmallVec<[Option; 4]>, + derive_call_ids: SmallVec<[Option>; 4]>, } pub(crate) static BUILTIN_SCOPE: LazyLock> = LazyLock::new(|| { @@ -345,7 +346,9 @@ impl ItemScope { pub fn all_macro_calls(&self) -> impl Iterator + '_ { self.macro_invocations.values().copied().chain(self.attr_macros.values().copied()).chain( self.derive_macros.values().flat_map(|it| { - it.iter().flat_map(|it| it.derive_call_ids.iter().copied().flatten()) + it.iter().flat_map(|it| { + it.derive_call_ids.iter().copied().flatten().flat_map(|it| it.left()) + }) }), ) } @@ -379,6 +382,10 @@ impl ItemScope { self.types.get(name).map(|item| (item.def, item.vis)) } + pub(crate) fn makro(&self, name: &Name) -> Option { + self.macros.get(name).map(|item| item.def) + } + /// XXX: this is O(N) rather than O(1), try to not introduce new usages. pub(crate) fn name_of(&self, item: ItemInNs) -> Option<(&Name, Visibility, /*declared*/ bool)> { match item { @@ -519,7 +526,7 @@ impl ItemScope { pub(crate) fn set_derive_macro_invoc( &mut self, adt: AstId, - call: MacroCallId, + call: Either, id: AttrId, idx: usize, ) { @@ -539,7 +546,7 @@ impl ItemScope { adt: AstId, attr_id: AttrId, attr_call_id: MacroCallId, - mut derive_call_ids: SmallVec<[Option; 4]>, + mut derive_call_ids: SmallVec<[Option>; 4]>, ) { derive_call_ids.shrink_to_fit(); self.derive_macros.entry(adt).or_default().push(DeriveMacroInvocation { @@ -554,7 +561,9 @@ impl ItemScope { ) -> impl Iterator< Item = ( AstId, - impl Iterator])>, + impl Iterator< + Item = (AttrId, MacroCallId, &[Option>]), + >, ), > + '_ { self.derive_macros.iter().map(|(k, v)| { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index eba4d87ec9f8..092ff6e48671 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -7,8 +7,8 @@ use intern::{Symbol, sym}; use stdx::impl_from; use crate::{ - AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, ModuleDefId, - StaticId, StructId, TraitId, TypeAliasId, UnionId, + AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, MacroId, + ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId, attrs::AttrFlags, db::DefDatabase, nameres::{DefMap, assoc::TraitItems, crate_def_map, crate_local_def_map}, @@ -99,7 +99,7 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option Option { + let mut current = &core_def_map[core_def_map.root]; + for module in modules { + let Some((ModuleDefId::ModuleId(cur), _)) = + current.scope.type_(&Name::new_symbol_root(module.clone())) + else { + return None; + }; + if cur.krate(db) != core_def_map.krate() || cur.block(db) != core_def_map.block_id() { + return None; + } + current = &core_def_map[cur]; + } + current.scope.makro(&Name::new_symbol_root(name)) +} + #[salsa::tracked(returns(as_deref))] pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option> { let mut traits = Vec::new(); @@ -195,7 +216,11 @@ macro_rules! language_item_table { @non_lang_core_traits: - $( core::$($non_lang_module:ident)::*, $non_lang_trait:ident; )* + $( core::$($non_lang_trait_module:ident)::*, $non_lang_trait:ident; )* + + @non_lang_core_macros: + + $( core::$($non_lang_macro_module:ident)::*, $non_lang_macro:ident, $non_lang_macro_field:ident; )* ) => { #[allow(non_snake_case)] // FIXME: Should we remove this? #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] @@ -207,6 +232,9 @@ macro_rules! language_item_table { $( pub $non_lang_trait: Option, )* + $( + pub $non_lang_macro_field: Option, + )* } impl LangItems { @@ -218,6 +246,7 @@ macro_rules! language_item_table { fn merge_prefer_self(&mut self, other: &Self) { $( self.$lang_item = self.$lang_item.or(other.$lang_item); )* $( self.$non_lang_trait = self.$non_lang_trait.or(other.$non_lang_trait); )* + $( self.$non_lang_macro_field = self.$non_lang_macro_field.or(other.$non_lang_macro_field); )* } fn assign_lang_item(&mut self, name: Symbol, target: LangItemTarget) { @@ -233,8 +262,9 @@ macro_rules! language_item_table { } } - fn fill_non_lang_core_traits(&mut self, db: &dyn DefDatabase, core_def_map: &DefMap) { - $( self.$non_lang_trait = resolve_core_trait(db, core_def_map, &[ $(sym::$non_lang_module),* ], sym::$non_lang_trait); )* + fn fill_non_lang_core_items(&mut self, db: &dyn DefDatabase, core_def_map: &DefMap) { + $( self.$non_lang_trait = resolve_core_trait(db, core_def_map, &[ $(sym::$non_lang_trait_module),* ], sym::$non_lang_trait); )* + $( self.$non_lang_macro_field = resolve_core_macro(db, core_def_map, &[ $(sym::$non_lang_macro_module),* ], sym::$non_lang_macro); )* } } @@ -479,4 +509,16 @@ language_item_table! { LangItems => core::hash, Hash; core::cmp, Ord; core::cmp, Eq; + + @non_lang_core_macros: + core::default, Default, DefaultDerive; + core::fmt, Debug, DebugDerive; + core::hash, Hash, HashDerive; + core::cmp, PartialOrd, PartialOrdDerive; + core::cmp, Ord, OrdDerive; + core::cmp, PartialEq, PartialEqDerive; + core::cmp, Eq, EqDerive; + core::marker, CoercePointee, CoercePointeeDerive; + core::marker, Copy, CopyDerive; + core::clone, Clone, CloneDerive; } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 5f05cdb1e2ba..150372f1a0d9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -61,6 +61,7 @@ mod tests; use std::ops::{Deref, DerefMut, Index, IndexMut}; use base_db::Crate; +use either::Either; use hir_expand::{ EditionedFileId, ErasedAstId, HirFileId, InFile, MacroCallId, mod_path::ModPath, name::Name, proc_macro::ProcMacroKind, @@ -75,8 +76,8 @@ use triomphe::Arc; use tt::TextRange; use crate::{ - AstId, BlockId, BlockLoc, ExternCrateId, FunctionId, FxIndexMap, Lookup, MacroCallStyles, - MacroExpander, MacroId, ModuleId, ModuleIdLt, ProcMacroId, UseId, + AstId, BlockId, BlockLoc, BuiltinDeriveImplId, ExternCrateId, FunctionId, FxIndexMap, Lookup, + MacroCallStyles, MacroExpander, MacroId, ModuleId, ModuleIdLt, ProcMacroId, UseId, db::DefDatabase, item_scope::{BuiltinShadowMode, ItemScope}, item_tree::TreeId, @@ -192,7 +193,8 @@ pub struct DefMap { /// Tracks which custom derives are in scope for an item, to allow resolution of derive helper /// attributes. // FIXME: Figure out a better way for the IDE layer to resolve these? - derive_helpers_in_scope: FxHashMap, Vec<(Name, MacroId, MacroCallId)>>, + derive_helpers_in_scope: + FxHashMap, Vec<(Name, MacroId, Either)>>, /// A mapping from [`hir_expand::MacroDefId`] to [`crate::MacroId`]. pub macro_def_to_macro_id: FxHashMap, @@ -540,7 +542,7 @@ impl DefMap { pub fn derive_helpers_in_scope( &self, id: AstId, - ) -> Option<&[(Name, MacroId, MacroCallId)]> { + ) -> Option<&[(Name, MacroId, Either)]> { self.derive_helpers_in_scope.get(&id.map(|it| it.upcast())).map(Deref::deref) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 87ade0651762..323060f61d15 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -3,7 +3,7 @@ //! `DefCollector::collect` contains the fixed-point iteration loop which //! resolves imports and expands macros. -use std::{iter, mem}; +use std::{iter, mem, ops::Range}; use base_db::{BuiltDependency, Crate, CrateOrigin, LangCrateOrigin}; use cfg::{CfgAtom, CfgExpr, CfgOptions}; @@ -226,6 +226,7 @@ struct DeferredBuiltinDerive { container: ItemContainerId, derive_attr_id: AttrId, derive_index: u32, + helpers_range: Range, } /// Walks the tree of module recursively @@ -1354,7 +1355,7 @@ impl<'db> DefCollector<'db> { if let Ok((macro_id, def_id, call_id)) = id { self.def_map.modules[directive.module_id].scope.set_derive_macro_invoc( ast_id.ast_id, - call_id, + Either::Left(call_id), *derive_attr, *derive_pos, ); @@ -1369,7 +1370,7 @@ impl<'db> DefCollector<'db> { .extend(izip!( helpers.iter().cloned(), iter::repeat(macro_id), - iter::repeat(call_id), + iter::repeat(Either::Left(call_id)), )); } } @@ -1492,6 +1493,8 @@ impl<'db> DefCollector<'db> { Interned::new(path), ); + derive_call_ids.push(None); + // Try to resolve the derive immediately. If we succeed, we can also use the fast path // for builtin derives. If not, we cannot use it, as it can cause the ADT to become // interned while the derive is still unresolved, which will cause it to get forgotten. @@ -1506,23 +1509,42 @@ impl<'db> DefCollector<'db> { call_id, ); + let ast_id_without_path = ast_id.ast_id; + let directive = MacroDirective { + module_id: directive.module_id, + depth: directive.depth + 1, + kind: MacroDirectiveKind::Derive { + ast_id, + derive_attr: *attr_id, + derive_pos: idx, + ctxt: call_site.ctx, + derive_macro_id: call_id, + }, + container: directive.container, + }; + if let Ok((macro_id, def_id, call_id)) = id { - derive_call_ids.push(Some(call_id)); + let (mut helpers_start, mut helpers_end) = (0, 0); // Record its helper attributes. if def_id.krate != self.def_map.krate { let def_map = crate_def_map(self.db, def_id.krate); if let Some(helpers) = def_map.data.exported_derives.get(¯o_id) { - self.def_map + let derive_helpers = self + .def_map .derive_helpers_in_scope - .entry(ast_id.ast_id.map(|it| it.upcast())) - .or_default() - .extend(izip!( - helpers.iter().cloned(), - iter::repeat(macro_id), - iter::repeat(call_id), - )); + .entry( + ast_id_without_path.map(|it| it.upcast()), + ) + .or_default(); + helpers_start = derive_helpers.len(); + derive_helpers.extend(izip!( + helpers.iter().cloned(), + iter::repeat(macro_id), + iter::repeat(Either::Left(call_id)), + )); + helpers_end = derive_helpers.len(); } } @@ -1531,7 +1553,7 @@ impl<'db> DefCollector<'db> { def_id.kind { self.deferred_builtin_derives - .entry(ast_id.ast_id.upcast()) + .entry(ast_id_without_path.upcast()) .or_default() .push(DeferredBuiltinDerive { call_id, @@ -1541,24 +1563,15 @@ impl<'db> DefCollector<'db> { depth: directive.depth, derive_attr_id: *attr_id, derive_index: idx as u32, + helpers_range: helpers_start..helpers_end, }); } else { - push_resolved(&mut resolved, directive, call_id); + push_resolved(&mut resolved, &directive, call_id); + *derive_call_ids.last_mut().unwrap() = + Some(Either::Left(call_id)); } } else { - derive_call_ids.push(None); - self.unresolved_macros.push(MacroDirective { - module_id: directive.module_id, - depth: directive.depth + 1, - kind: MacroDirectiveKind::Derive { - ast_id, - derive_attr: *attr_id, - derive_pos: idx, - ctxt: call_site.ctx, - derive_macro_id: call_id, - }, - container: directive.container, - }); + self.unresolved_macros.push(directive); } } @@ -1858,9 +1871,8 @@ impl ModCollector<'_, '_> { ast_id: FileAstId, id: AdtId, def_map: &mut DefMap| { - let Some(deferred_derives) = - deferred_derives.remove(&InFile::new(file_id, ast_id.upcast())) - else { + let ast_id = InFile::new(file_id, ast_id.upcast()); + let Some(deferred_derives) = deferred_derives.remove(&ast_id.upcast()) else { return; }; let module = &mut def_map.modules[module_id]; @@ -1876,6 +1888,22 @@ impl ModCollector<'_, '_> { }, ); module.scope.define_builtin_derive_impl(impl_id); + module.scope.set_derive_macro_invoc( + ast_id, + Either::Right(impl_id), + deferred_derive.derive_attr_id, + deferred_derive.derive_index as usize, + ); + // Change its helper attributes to the new id. + if let Some(derive_helpers) = + def_map.derive_helpers_in_scope.get_mut(&ast_id.map(|it| it.upcast())) + { + for (_, _, call_id) in + &mut derive_helpers[deferred_derive.helpers_range.clone()] + { + *call_id = Either::Right(impl_id); + } + } }); } }; diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index f4c42537de93..e55b693ef018 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -13,7 +13,7 @@ use std::{ use base_db::FxIndexSet; use either::Either; use hir_def::{ - DefWithBodyId, MacroId, StructId, TraitId, VariantId, + BuiltinDeriveImplId, DefWithBodyId, HasModule, MacroId, StructId, TraitId, VariantId, attrs::parse_extra_crate_attrs, expr_store::{Body, ExprOrPatSource, HygieneId, path::Path}, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, @@ -622,7 +622,20 @@ impl<'db> SemanticsImpl<'db> { Some( calls .into_iter() - .map(|call| macro_call_to_macro_id(ctx, call?).map(|id| Macro { id })) + .map(|call| { + let call = call?; + match call { + Either::Left(call) => { + macro_call_to_macro_id(ctx, call).map(|id| Macro { id }) + } + Either::Right(call) => { + let call = call.loc(self.db); + let krate = call.krate(self.db); + let lang_items = hir_def::lang_item::lang_items(self.db, krate); + call.trait_.derive_macro(lang_items).map(|id| Macro { id }) + } + } + }) .collect(), ) }) @@ -633,7 +646,7 @@ impl<'db> SemanticsImpl<'db> { .derive_macro_calls(attr)? .into_iter() .flat_map(|call| { - let file_id = call?; + let file_id = call?.left()?; let ExpandResult { value, err } = self.db.parse_macro_expansion(file_id); let root_node = value.0.syntax_node(); self.cache(root_node.clone(), file_id.into()); @@ -643,7 +656,10 @@ impl<'db> SemanticsImpl<'db> { Some(res) } - fn derive_macro_calls(&self, attr: &ast::Attr) -> Option>> { + fn derive_macro_calls( + &self, + attr: &ast::Attr, + ) -> Option>>> { let adt = attr.syntax().parent().and_then(ast::Adt::cast)?; let file_id = self.find_file(adt.syntax()).file_id; let adt = InFile::new(file_id, &adt); @@ -690,8 +706,9 @@ impl<'db> SemanticsImpl<'db> { .derive_helpers_in_scope(InFile::new(sa.file_id, id))? .iter() .filter(|&(name, _, _)| *name == attr_name) - .map(|&(_, macro_, call)| (macro_.into(), call)) + .filter_map(|&(_, macro_, call)| Some((macro_.into(), call.left()?))) .collect(); + // FIXME: We filter our builtin derive "fake" expansions, is this correct? Should we still expose them somehow? res.is_empty().not().then_some(res) } @@ -1338,6 +1355,7 @@ impl<'db> SemanticsImpl<'db> { // FIXME: We need to call `f` for all of them as well though! process_expansion_for_token(ctx, &mut stack, derive_attr); for derive in derives.into_iter().flatten() { + let Either::Left(derive) = derive else { continue }; process_expansion_for_token(ctx, &mut stack, derive); } } @@ -1467,11 +1485,12 @@ impl<'db> SemanticsImpl<'db> { for (.., derive) in helpers.iter().filter(|(helper, ..)| *helper == attr_name) { + let Either::Left(derive) = *derive else { continue }; // as there may be multiple derives registering the same helper // name, we gotta make sure to call this for all of them! // FIXME: We need to call `f` for all of them as well though! res = res - .or(process_expansion_for_token(ctx, &mut stack, *derive)); + .or(process_expansion_for_token(ctx, &mut stack, derive)); } res }) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 257405992731..d222c3dc7ed1 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -87,10 +87,10 @@ use either::Either; use hir_def::{ - AdtId, BlockId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, - ExternCrateId, FieldId, FunctionId, GenericDefId, GenericParamId, ImplId, LifetimeParamId, - Lookup, MacroId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, - UseId, VariantId, + AdtId, BlockId, BuiltinDeriveImplId, ConstId, ConstParamId, DefWithBodyId, EnumId, + EnumVariantId, ExternBlockId, ExternCrateId, FieldId, FunctionId, GenericDefId, GenericParamId, + ImplId, LifetimeParamId, Lookup, MacroId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, + TypeParamId, UnionId, UseId, VariantId, dyn_map::{ DynMap, keys::{self, Key}, @@ -394,7 +394,7 @@ impl SourceToDefCtx<'_, '_> { &mut self, item: InFile<&ast::Adt>, src: InFile, - ) -> Option<(AttrId, MacroCallId, &[Option])> { + ) -> Option<(AttrId, MacroCallId, &[Option>])> { let map = self.dyn_map(item)?; map[keys::DERIVE_MACRO_CALL] .get(&AstPtr::new(&src.value)) @@ -409,8 +409,11 @@ impl SourceToDefCtx<'_, '_> { pub(super) fn derive_macro_calls<'slf>( &'slf mut self, adt: InFile<&ast::Adt>, - ) -> Option])> + use<'slf>> - { + ) -> Option< + impl Iterator< + Item = (AttrId, MacroCallId, &'slf [Option>]), + > + use<'slf>, + > { self.dyn_map(adt).as_ref().map(|&map| { let dyn_map = &map[keys::DERIVE_MACRO_CALL]; adt.value diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 7d02b8091890..ba8b3aa9cafe 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -583,26 +583,16 @@ fn main() { fn macro_expand_derive() { check( r#" -//- proc_macros: identity -//- minicore: clone, derive +//- proc_macros: identity, derive_identity +//- minicore: derive #[proc_macros::identity] -#[derive(C$0lone)] +#[derive(proc_macros::DeriveIde$0ntity)] struct Foo {} "#, expect![[r#" - Clone - impl <>core::clone::Clone for Foo< >where { - fn clone(&self) -> Self { - match self { - Foo{} - => Foo{} - , - - } - } - - }"#]], + proc_macros::DeriveIdentity + struct Foo{}"#]], ); } @@ -610,15 +600,17 @@ struct Foo {} fn macro_expand_derive2() { check( r#" -//- minicore: copy, clone, derive +//- proc_macros: derive_identity +//- minicore: derive -#[derive(Cop$0y)] -#[derive(Clone)] +#[derive(proc_macros::$0DeriveIdentity)] +#[derive(proc_macros::DeriveIdentity)] struct Foo {} "#, expect![[r#" - Copy - impl <>core::marker::Copy for Foo< >where{}"#]], + proc_macros::DeriveIdentity + #[derive(proc_macros::DeriveIdentity)] + struct Foo{}"#]], ); } @@ -626,35 +618,27 @@ struct Foo {} fn macro_expand_derive_multi() { check( r#" -//- minicore: copy, clone, derive +//- proc_macros: derive_identity +//- minicore: derive -#[derive(Cop$0y, Clone)] +#[derive(proc_macros::DeriveIdent$0ity, proc_macros::DeriveIdentity)] struct Foo {} "#, expect![[r#" - Copy - impl <>core::marker::Copy for Foo< >where{}"#]], + proc_macros::DeriveIdentity + struct Foo{}"#]], ); check( r#" -//- minicore: copy, clone, derive +//- proc_macros: derive_identity +//- minicore: derive -#[derive(Copy, Cl$0one)] +#[derive(proc_macros::DeriveIdentity, proc_macros::De$0riveIdentity)] struct Foo {} "#, expect![[r#" - Clone - impl <>core::clone::Clone for Foo< >where { - fn clone(&self) -> Self { - match self { - Foo{} - => Foo{} - , - - } - } - - }"#]], + proc_macros::DeriveIdentity + struct Foo{}"#]], ); } diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index b6efc599f181..3fadca29d118 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -532,4 +532,5 @@ define_symbols! { CoerceUnsized, DispatchFromDyn, define_opaque, + marker, } From a251ae2615bd92b90e4c850a8026bff47e4786bf Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 30 Dec 2025 02:54:43 +0300 Subject: [PATCH 1752/3801] resolve: Update `NameBindingData::ambiguity` in place instead of creating fresh bindings, except in one case. --- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- .../src/effective_visibilities.rs | 7 ++- compiler/rustc_resolve/src/imports.rs | 51 ++++++++++--------- compiler/rustc_resolve/src/lib.rs | 12 ++--- tests/ui/imports/issue-55884-1.rs | 2 +- tests/ui/imports/issue-55884-1.stderr | 22 +++++++- 6 files changed, 60 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 0167b8038649..6bface926edc 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -89,7 +89,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { let decl = self.arenas.alloc_decl(DeclData { kind: DeclKind::Def(res), - ambiguity, + ambiguity: CmCell::new(ambiguity), // External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment. warn_ambiguity: CmCell::new(true), vis: CmCell::new(vis), diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 7272314b9aa7..ebdb0060e1b9 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -100,7 +100,9 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { if let Some(node_id) = import.id() { r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx) } - } else if decl.ambiguity.is_some() && eff_vis.is_public_at_level(Level::Reexported) { + } else if decl.ambiguity.get().is_some() + && eff_vis.is_public_at_level(Level::Reexported) + { exported_ambiguities.insert(*decl); } } @@ -125,7 +127,8 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { // If the binding is ambiguous, put the root ambiguity binding and all reexports // leading to it into the table. They are used by the `ambiguous_glob_reexports` // lint. For all bindings added to the table this way `is_ambiguity` returns true. - let is_ambiguity = |decl: Decl<'ra>, warn: bool| decl.ambiguity.is_some() && !warn; + let is_ambiguity = + |decl: Decl<'ra>, warn: bool| decl.ambiguity.get().is_some() && !warn; let mut parent_id = ParentId::Def(module_id); let mut warn_ambiguity = decl.warn_ambiguity.get(); while let DeclKind::Import { source_decl, .. } = decl.kind { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 76aeb7ba85b8..68f042c6e041 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -300,10 +300,10 @@ fn remove_same_import<'ra>(d1: Decl<'ra>, d2: Decl<'ra>) -> (Decl<'ra>, Decl<'ra if let DeclKind::Import { import: import1, source_decl: d1_next } = d1.kind && let DeclKind::Import { import: import2, source_decl: d2_next } = d2.kind && import1 == import2 - && d1.ambiguity == d2.ambiguity + && d1.warn_ambiguity.get() == d2.warn_ambiguity.get() { - assert!(d1.ambiguity.is_none()); - assert_eq!(d1.warn_ambiguity.get(), d2.warn_ambiguity.get()); + assert_eq!(d1.ambiguity.get(), d2.ambiguity.get()); + assert!(!d1.warn_ambiguity.get()); assert_eq!(d1.expansion, d2.expansion); assert_eq!(d1.span, d2.span); assert_eq!(d1.vis(), d2.vis()); @@ -335,7 +335,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.arenas.alloc_decl(DeclData { kind: DeclKind::Import { source_decl: decl, import }, - ambiguity: None, + ambiguity: CmCell::new(None), warn_ambiguity: CmCell::new(false), span: import.span, vis: CmCell::new(vis), @@ -359,9 +359,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // all these overwrites will be re-fetched by glob imports importing // from that module without generating new ambiguities. // - A glob decl is overwritten by a non-glob decl arriving later. - // - A glob decl is overwritten by an ambiguous glob decl. - // FIXME: avoid this by putting `DeclData::ambiguity` under a - // cell and updating it in place. + // - A glob decl is overwritten by its clone after setting ambiguity in it. + // FIXME: avoid this by removing `warn_ambiguity`, or by triggering glob re-fetch + // with the same decl in some way. // - A glob decl is overwritten by a glob decl re-fetching an // overwritten decl from other module (the recursive case). // Here we are detecting all such re-fetches and overwrite old decls @@ -372,21 +372,34 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if deep_decl != glob_decl { // Some import layers have been removed, need to overwrite. assert_ne!(old_deep_decl, old_glob_decl); - assert_ne!(old_deep_decl, deep_decl); - assert!(old_deep_decl.is_glob_import()); + // FIXME: reenable the asserts when `warn_ambiguity` is removed (#149195). + // assert_ne!(old_deep_decl, deep_decl); + // assert!(old_deep_decl.is_glob_import()); + assert!(!deep_decl.is_glob_import()); if glob_decl.is_ambiguity_recursive() { glob_decl.warn_ambiguity.set_unchecked(true); } glob_decl } else if glob_decl.res() != old_glob_decl.res() { - self.new_decl_with_ambiguity(old_glob_decl, glob_decl, warn_ambiguity) + old_glob_decl.ambiguity.set_unchecked(Some(glob_decl)); + old_glob_decl.warn_ambiguity.set_unchecked(warn_ambiguity); + if warn_ambiguity { + old_glob_decl + } else { + // Need a fresh decl so other glob imports importing it could re-fetch it + // and set their own `warn_ambiguity` to true. + // FIXME: remove this when `warn_ambiguity` is removed (#149195). + self.arenas.alloc_decl((*old_glob_decl).clone()) + } } else if !old_glob_decl.vis().is_at_least(glob_decl.vis(), self.tcx) { // We are glob-importing the same item but with greater visibility. old_glob_decl.vis.set_unchecked(glob_decl.vis()); old_glob_decl } else if glob_decl.is_ambiguity_recursive() && !old_glob_decl.is_ambiguity_recursive() { // Overwriting a non-ambiguous glob import with an ambiguous glob import. - self.new_decl_with_ambiguity(old_glob_decl, glob_decl, true) + old_glob_decl.ambiguity.set_unchecked(Some(glob_decl)); + old_glob_decl.warn_ambiguity.set_unchecked(true); + old_glob_decl } else { old_glob_decl } @@ -415,6 +428,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| { if let Some(old_decl) = resolution.best_decl() { assert_ne!(decl, old_decl); + assert!(!decl.warn_ambiguity.get()); if res == Res::Err && old_decl.res() != Res::Err { // Do not override real declarations with `Res::Err`s from error recovery. return Ok(()); @@ -453,19 +467,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } - fn new_decl_with_ambiguity( - &self, - primary_decl: Decl<'ra>, - secondary_decl: Decl<'ra>, - warn_ambiguity: bool, - ) -> Decl<'ra> { - let ambiguity = Some(secondary_decl); - let warn_ambiguity = CmCell::new(warn_ambiguity); - let vis = primary_decl.vis.clone(); - let data = DeclData { ambiguity, warn_ambiguity, vis, ..*primary_decl }; - self.arenas.alloc_decl(data) - } - // Use `f` to mutate the resolution of the name in the module. // If the resolution becomes a success, define it in the module's glob importers. fn update_local_resolution( @@ -671,7 +672,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let Some(binding) = resolution.best_decl() else { continue }; if let DeclKind::Import { import, .. } = binding.kind - && let Some(amb_binding) = binding.ambiguity + && let Some(amb_binding) = binding.ambiguity.get() && binding.res() != Res::Err && exported_ambiguities.contains(&binding) { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index bce14f5376d7..311efb3e881b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -802,10 +802,10 @@ impl<'ra> fmt::Debug for Module<'ra> { } /// Data associated with any name declaration. -#[derive(Debug)] +#[derive(Clone, Debug)] struct DeclData<'ra> { kind: DeclKind<'ra>, - ambiguity: Option>, + ambiguity: CmCell>>, /// Produce a warning instead of an error when reporting ambiguities inside this binding. /// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required. warn_ambiguity: CmCell, @@ -942,7 +942,7 @@ impl<'ra> DeclData<'ra> { } fn descent_to_ambiguity(self: Decl<'ra>) -> Option<(Decl<'ra>, Decl<'ra>)> { - match self.ambiguity { + match self.ambiguity.get() { Some(ambig_binding) => Some((self, ambig_binding)), None => match self.kind { DeclKind::Import { source_decl, .. } => source_decl.descent_to_ambiguity(), @@ -952,7 +952,7 @@ impl<'ra> DeclData<'ra> { } fn is_ambiguity_recursive(&self) -> bool { - self.ambiguity.is_some() + self.ambiguity.get().is_some() || match self.kind { DeclKind::Import { source_decl, .. } => source_decl.is_ambiguity_recursive(), _ => false, @@ -1346,7 +1346,7 @@ impl<'ra> ResolverArenas<'ra> { ) -> Decl<'ra> { self.alloc_decl(DeclData { kind: DeclKind::Def(res), - ambiguity: None, + ambiguity: CmCell::new(None), warn_ambiguity: CmCell::new(false), vis: CmCell::new(vis), span, @@ -2055,7 +2055,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { used: Used, warn_ambiguity: bool, ) { - if let Some(b2) = used_decl.ambiguity { + if let Some(b2) = used_decl.ambiguity.get() { let ambiguity_error = AmbiguityError { kind: AmbiguityKind::GlobVsGlob, ident, diff --git a/tests/ui/imports/issue-55884-1.rs b/tests/ui/imports/issue-55884-1.rs index 21744aa5d7bf..3c9c033c158e 100644 --- a/tests/ui/imports/issue-55884-1.rs +++ b/tests/ui/imports/issue-55884-1.rs @@ -17,5 +17,5 @@ mod m { fn main() { use m::S; //~ ERROR `S` is ambiguous - let s = S {}; + let s = S {}; //~ ERROR `S` is ambiguous } diff --git a/tests/ui/imports/issue-55884-1.stderr b/tests/ui/imports/issue-55884-1.stderr index ae8edb049564..a0b63ddc9108 100644 --- a/tests/ui/imports/issue-55884-1.stderr +++ b/tests/ui/imports/issue-55884-1.stderr @@ -18,6 +18,26 @@ LL | pub use self::m2::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `S` to disambiguate -error: aborting due to 1 previous error +error[E0659]: `S` is ambiguous + --> $DIR/issue-55884-1.rs:20:13 + | +LL | let s = S {}; + | ^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `S` could refer to the struct imported here + --> $DIR/issue-55884-1.rs:14:13 + | +LL | pub use self::m1::*; + | ^^^^^^^^^^^ + = help: consider adding an explicit import of `S` to disambiguate +note: `S` could also refer to the struct imported here + --> $DIR/issue-55884-1.rs:15:13 + | +LL | pub use self::m2::*; + | ^^^^^^^^^^^ + = help: consider adding an explicit import of `S` to disambiguate + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. From 69bedd10d203edfd6559da629c78013345fa0d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Wed, 7 Jan 2026 14:27:27 +0100 Subject: [PATCH 1753/3801] compiler-builtins: Enable AArch64 `__chkstk` for MinGW Similarly to i686 and X86_64 MinGW targets, Rust needs to provide the right chkstk symbol for AArch64 to avoid relying on the linker to provide it. CC https://github.com/rust-lang/rust/issues/150725 --- library/compiler-builtins/compiler-builtins/src/aarch64.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/compiler-builtins/src/aarch64.rs b/library/compiler-builtins/compiler-builtins/src/aarch64.rs index 039fab2061c5..1b230a214eef 100644 --- a/library/compiler-builtins/compiler-builtins/src/aarch64.rs +++ b/library/compiler-builtins/compiler-builtins/src/aarch64.rs @@ -4,7 +4,7 @@ use core::intrinsics; intrinsics! { #[unsafe(naked)] - #[cfg(target_os = "uefi")] + #[cfg(any(all(windows, target_env = "gnu"), target_os = "uefi"))] pub unsafe extern "custom" fn __chkstk() { core::arch::naked_asm!( ".p2align 2", From 64c78f6e74b885a0afaa4d6ad7d53e44033d714f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 5 Jan 2026 19:30:41 +0100 Subject: [PATCH 1754/3801] make `MarkdownItemInfo` a field struct --- src/librustdoc/html/markdown.rs | 17 ++++++++++++----- src/librustdoc/html/markdown/tests.rs | 2 +- src/librustdoc/html/render/mod.rs | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index a4d377432c91..834c0cb669c0 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -111,7 +111,10 @@ pub(crate) struct MarkdownWithToc<'a> { } /// A tuple struct like `Markdown` that renders the markdown escaping HTML tags /// and includes no paragraph tags. -pub(crate) struct MarkdownItemInfo<'a>(pub(crate) &'a str, pub(crate) &'a mut IdMap); +pub(crate) struct MarkdownItemInfo<'a> { + pub(crate) content: &'a str, + pub(crate) ids: &'a mut IdMap, +} /// A tuple struct like `Markdown` that renders only the first paragraph. pub(crate) struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [RenderedLink]); @@ -1459,15 +1462,19 @@ impl MarkdownWithToc<'_> { } } -impl MarkdownItemInfo<'_> { +impl<'a> MarkdownItemInfo<'a> { + pub(crate) fn new(content: &'a str, ids: &'a mut IdMap) -> Self { + Self { content, ids } + } + pub(crate) fn write_into(self, mut f: impl fmt::Write) -> fmt::Result { - let MarkdownItemInfo(md, ids) = self; + let MarkdownItemInfo { content, ids } = self; // This is actually common enough to special-case - if md.is_empty() { + if content.is_empty() { return Ok(()); } - let p = Parser::new_ext(md, main_body_opts()).into_offset_iter(); + let p = Parser::new_ext(content, main_body_opts()).into_offset_iter(); // Treat inline HTML as plain text. let p = p.map(|event| match event.0 { diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index 61fd42874633..14d86a8abf57 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -471,7 +471,7 @@ fn test_markdown_html_escape() { fn t(input: &str, expect: &str) { let mut idmap = IdMap::new(); let mut output = String::new(); - MarkdownItemInfo(input, &mut idmap).write_into(&mut output).unwrap(); + MarkdownItemInfo::new(input, &mut idmap).write_into(&mut output).unwrap(); assert_eq!(output, expect, "original: {}", input); } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 4529f5a8c016..de5c8a765275 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -877,7 +877,7 @@ fn short_item_info( if let Some(note) = note { let note = note.as_str(); let mut id_map = cx.id_map.borrow_mut(); - let html = MarkdownItemInfo(note, &mut id_map); + let html = MarkdownItemInfo::new(note, &mut id_map); message.push_str(": "); html.write_into(&mut message).unwrap(); } From 3be74a744114ed8cdfd9dcd0bada5e17ff35e662 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 6 Jan 2026 12:04:38 +0100 Subject: [PATCH 1755/3801] render intra-doc links in the `#[deprectated]` note --- compiler/rustc_ast/src/attr/mod.rs | 34 ++++++++++++++ compiler/rustc_hir/src/hir.rs | 8 ++++ compiler/rustc_resolve/src/rustdoc.rs | 13 +++++- src/librustdoc/clean/types.rs | 10 +++++ src/librustdoc/html/markdown.rs | 21 ++++++--- src/librustdoc/html/markdown/tests.rs | 2 +- src/librustdoc/html/render/mod.rs | 3 +- .../passes/collect_intra_doc_links.rs | 45 +++++++++++++------ tests/rustdoc-html/intra-doc/deprecated.rs | 12 +++++ tests/rustdoc-ui/intra-doc/deprecated.rs | 10 +++++ tests/rustdoc-ui/intra-doc/deprecated.stderr | 43 ++++++++++++++++++ 11 files changed, 179 insertions(+), 22 deletions(-) create mode 100644 tests/rustdoc-html/intra-doc/deprecated.rs create mode 100644 tests/rustdoc-ui/intra-doc/deprecated.rs create mode 100644 tests/rustdoc-ui/intra-doc/deprecated.stderr diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 6ecba865c815..0a2a34d932f6 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -235,6 +235,34 @@ impl AttributeExt for Attribute { } } + fn deprecation_note(&self) -> Option { + match &self.kind { + AttrKind::Normal(normal) if normal.item.path == sym::deprecated => { + let meta = &normal.item; + + // #[deprecated = "..."] + if let Some(s) = meta.value_str() { + return Some(s); + } + + // #[deprecated(note = "...")] + if let Some(list) = meta.meta_item_list() { + for nested in list { + if let Some(mi) = nested.meta_item() + && mi.path == sym::note + && let Some(s) = mi.value_str() + { + return Some(s); + } + } + } + + None + } + _ => None, + } + } + fn doc_resolution_scope(&self) -> Option { match &self.kind { AttrKind::DocComment(..) => Some(self.style), @@ -277,6 +305,7 @@ impl Attribute { pub fn may_have_doc_links(&self) -> bool { self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str())) + || self.deprecation_note().is_some_and(|s| comments::may_have_doc_links(s.as_str())) } /// Extracts the MetaItem from inside this Attribute. @@ -873,6 +902,11 @@ pub trait AttributeExt: Debug { /// * `#[doc(...)]` returns `None`. fn doc_str(&self) -> Option; + /// Returns the deprecation note if this is deprecation attribute. + /// * `#[deprecated = "note"]` returns `Some("note")`. + /// * `#[deprecated(note = "note", ...)]` returns `Some("note")`. + fn deprecation_note(&self) -> Option; + fn is_proc_macro_attr(&self) -> bool { [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] .iter() diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index aacd6324bb03..883ba23ca214 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1400,6 +1400,14 @@ impl AttributeExt for Attribute { } } + #[inline] + fn deprecation_note(&self) -> Option { + match &self { + Attribute::Parsed(AttributeKind::Deprecation { deprecation, .. }) => deprecation.note, + _ => None, + } + } + fn is_automatically_derived_attr(&self) -> bool { matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..))) } diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 7f7c423acb40..9f74a7801d2e 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -410,8 +410,17 @@ pub fn may_be_doc_link(link_type: LinkType) -> bool { /// Simplified version of `preprocessed_markdown_links` from rustdoc. /// Must return at least the same links as it, but may add some more links on top of that. pub(crate) fn attrs_to_preprocessed_links(attrs: &[A]) -> Vec> { - let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true); - let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap(); + let (doc_fragments, other_attrs) = + attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), false); + let mut doc = + prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap_or_default(); + + for attr in other_attrs { + if let Some(note) = attr.deprecation_note() { + doc += note.as_str(); + doc += "\n"; + } + } parse_links(&doc) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index a390a03ff114..c3bafd3db13a 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -7,6 +7,7 @@ use std::{fmt, iter}; use arrayvec::ArrayVec; use itertools::Either; use rustc_abi::{ExternAbi, VariantIdx}; +use rustc_ast::attr::AttributeExt; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::thin_vec::ThinVec; use rustc_hir::attrs::{AttributeKind, DeprecatedSince, Deprecation, DocAttribute}; @@ -450,7 +451,16 @@ impl Item { } pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span { + let deprecation_notes = self + .attrs + .other_attrs + .iter() + .filter_map(|attr| attr.deprecation_note().map(|_| attr.span())); + span_of_fragments(&self.attrs.doc_strings) + .into_iter() + .chain(deprecation_notes) + .reduce(|a, b| a.to(b)) .unwrap_or_else(|| self.span(tcx).map_or(DUMMY_SP, |span| span.inner())) } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 834c0cb669c0..c472c20a7dc7 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -113,6 +113,7 @@ pub(crate) struct MarkdownWithToc<'a> { /// and includes no paragraph tags. pub(crate) struct MarkdownItemInfo<'a> { pub(crate) content: &'a str, + pub(crate) links: &'a [RenderedLink], pub(crate) ids: &'a mut IdMap, } /// A tuple struct like `Markdown` that renders only the first paragraph. @@ -1463,18 +1464,27 @@ impl MarkdownWithToc<'_> { } impl<'a> MarkdownItemInfo<'a> { - pub(crate) fn new(content: &'a str, ids: &'a mut IdMap) -> Self { - Self { content, ids } + pub(crate) fn new(content: &'a str, links: &'a [RenderedLink], ids: &'a mut IdMap) -> Self { + Self { content, links, ids } } pub(crate) fn write_into(self, mut f: impl fmt::Write) -> fmt::Result { - let MarkdownItemInfo { content, ids } = self; + let MarkdownItemInfo { content: md, links, ids } = self; // This is actually common enough to special-case - if content.is_empty() { + if md.is_empty() { return Ok(()); } - let p = Parser::new_ext(content, main_body_opts()).into_offset_iter(); + + let replacer = move |broken_link: BrokenLink<'_>| { + links + .iter() + .find(|link| *link.original_text == *broken_link.reference) + .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into())) + }; + + let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(replacer)); + let p = p.into_offset_iter(); // Treat inline HTML as plain text. let p = p.map(|event| match event.0 { @@ -1484,6 +1494,7 @@ impl<'a> MarkdownItemInfo<'a> { ids.handle_footnotes(|ids, existing_footnotes| { let p = HeadingLinks::new(p, None, ids, HeadingOffset::H1); + let p = SpannedLinkReplacer::new(p, links); let p = footnotes::Footnotes::new(p, existing_footnotes); let p = TableWrapper::new(p.map(|(ev, _)| ev)); let p = p.filter(|event| { diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index 14d86a8abf57..1c99ccc5228b 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -471,7 +471,7 @@ fn test_markdown_html_escape() { fn t(input: &str, expect: &str) { let mut idmap = IdMap::new(); let mut output = String::new(); - MarkdownItemInfo::new(input, &mut idmap).write_into(&mut output).unwrap(); + MarkdownItemInfo::new(input, &[], &mut idmap).write_into(&mut output).unwrap(); assert_eq!(output, expect, "original: {}", input); } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index de5c8a765275..63de870f07f4 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -877,7 +877,8 @@ fn short_item_info( if let Some(note) = note { let note = note.as_str(); let mut id_map = cx.id_map.borrow_mut(); - let html = MarkdownItemInfo::new(note, &mut id_map); + let links = item.links(cx); + let html = MarkdownItemInfo::new(note, &links, &mut id_map); message.push_str(": "); html.write_into(&mut message).unwrap(); } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3abf0fee3959..07d6efaa97e1 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -7,6 +7,7 @@ use std::fmt::Display; use std::mem; use std::ops::Range; +use rustc_ast::attr::AttributeExt; use rustc_ast::util::comments::may_have_doc_links; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; @@ -1047,18 +1048,7 @@ impl LinkCollector<'_, '_> { return; } - // We want to resolve in the lexical scope of the documentation. - // In the presence of re-exports, this is not the same as the module of the item. - // Rather than merging all documentation into one, resolve it one attribute at a time - // so we know which module it came from. - for (item_id, doc) in prepare_to_doc_link_resolution(&item.attrs.doc_strings) { - if !may_have_doc_links(&doc) { - continue; - } - debug!("combined_docs={doc}"); - // NOTE: if there are links that start in one crate and end in another, this will not resolve them. - // This is a degenerate case and it's not supported by rustdoc. - let item_id = item_id.unwrap_or_else(|| item.item_id.expect_def_id()); + let mut insert_links = |item_id, doc: &str| { let module_id = match self.cx.tcx.def_kind(item_id) { DefKind::Mod if item.inner_docs(self.cx.tcx) => item_id, _ => find_nearest_parent_module(self.cx.tcx, item_id).unwrap(), @@ -1074,6 +1064,35 @@ impl LinkCollector<'_, '_> { .insert(link); } } + }; + + // We want to resolve in the lexical scope of the documentation. + // In the presence of re-exports, this is not the same as the module of the item. + // Rather than merging all documentation into one, resolve it one attribute at a time + // so we know which module it came from. + for (item_id, doc) in prepare_to_doc_link_resolution(&item.attrs.doc_strings) { + if !may_have_doc_links(&doc) { + continue; + } + + debug!("combined_docs={doc}"); + // NOTE: if there are links that start in one crate and end in another, this will not resolve them. + // This is a degenerate case and it's not supported by rustdoc. + let item_id = item_id.unwrap_or_else(|| item.item_id.expect_def_id()); + insert_links(item_id, &doc) + } + + // Also resolve links in the note text of `#[deprecated]`. + for attr in &item.attrs.other_attrs { + let Some(note_sym) = attr.deprecation_note() else { continue }; + let note = note_sym.as_str(); + + if !may_have_doc_links(note) { + continue; + } + + debug!("deprecated_note={note}"); + insert_links(item.item_id.expect_def_id(), note) } } @@ -1086,7 +1105,7 @@ impl LinkCollector<'_, '_> { /// FIXME(jynelson): this is way too many arguments fn resolve_link( &mut self, - dox: &String, + dox: &str, item: &Item, item_id: DefId, module_id: DefId, diff --git a/tests/rustdoc-html/intra-doc/deprecated.rs b/tests/rustdoc-html/intra-doc/deprecated.rs new file mode 100644 index 000000000000..6f8639593a2d --- /dev/null +++ b/tests/rustdoc-html/intra-doc/deprecated.rs @@ -0,0 +1,12 @@ +//@ has deprecated/struct.A.html '//a[@href="{{channel}}/core/ops/range/struct.Range.html#structfield.start"]' 'start' +//@ has deprecated/struct.B1.html '//a[@href="{{channel}}/std/io/error/enum.ErrorKind.html#variant.NotFound"]' 'not_found' +//@ has deprecated/struct.B2.html '//a[@href="{{channel}}/std/io/error/enum.ErrorKind.html#variant.NotFound"]' 'not_found' + +#[deprecated = "[start][std::ops::Range::start]"] +pub struct A; + +#[deprecated(since = "0.0.0", note = "[not_found][std::io::ErrorKind::NotFound]")] +pub struct B1; + +#[deprecated(note = "[not_found][std::io::ErrorKind::NotFound]", since = "0.0.0")] +pub struct B2; diff --git a/tests/rustdoc-ui/intra-doc/deprecated.rs b/tests/rustdoc-ui/intra-doc/deprecated.rs new file mode 100644 index 000000000000..37c27dcde598 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deprecated.rs @@ -0,0 +1,10 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +#[deprecated = "[broken cross-reference](TypeAlias::hoge)"] //~ ERROR +pub struct A; + +#[deprecated(since = "0.0.0", note = "[broken cross-reference](TypeAlias::hoge)")] //~ ERROR +pub struct B1; + +#[deprecated(note = "[broken cross-reference](TypeAlias::hoge)", since = "0.0.0")] //~ ERROR +pub struct B2; diff --git a/tests/rustdoc-ui/intra-doc/deprecated.stderr b/tests/rustdoc-ui/intra-doc/deprecated.stderr new file mode 100644 index 000000000000..9bd64544eef8 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deprecated.stderr @@ -0,0 +1,43 @@ +error: unresolved link to `TypeAlias::hoge` + --> $DIR/deprecated.rs:3:1 + | +LL | #[deprecated = "[broken cross-reference](TypeAlias::hoge)"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [broken cross-reference](TypeAlias::hoge) + ^^^^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope +note: the lint level is defined here + --> $DIR/deprecated.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `TypeAlias::hoge` + --> $DIR/deprecated.rs:6:1 + | +LL | #[deprecated(since = "0.0.0", note = "[broken cross-reference](TypeAlias::hoge)")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [broken cross-reference](TypeAlias::hoge) + ^^^^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope + +error: unresolved link to `TypeAlias::hoge` + --> $DIR/deprecated.rs:9:1 + | +LL | #[deprecated(note = "[broken cross-reference](TypeAlias::hoge)", since = "0.0.0")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [broken cross-reference](TypeAlias::hoge) + ^^^^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope + +error: aborting due to 3 previous errors + From acc8c0bd65a057c7e61d3e70556e66b66d3f45b7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:05:09 +0000 Subject: [PATCH 1756/3801] Reduce usage of FnAbi in codegen_llvm_intrinsic_call --- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 88 ++++++++++++++++++- compiler/rustc_codegen_llvm/src/intrinsic.rs | 30 ++++++- 2 files changed, 111 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 36ea76cbc51a..f138b87d3405 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -4,10 +4,10 @@ mod simd; #[cfg(feature = "master")] use std::iter; -#[cfg(feature = "master")] -use gccjit::Type; use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; #[cfg(feature = "master")] +use gccjit::{FnAttribute, Type}; +#[cfg(feature = "master")] use rustc_abi::ExternAbi; use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange}; use rustc_codegen_ssa::MemFlags; @@ -22,13 +22,18 @@ use rustc_codegen_ssa::traits::{ ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods, }; +use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; use rustc_middle::ty::{self, Instance, Ty}; +#[cfg(feature = "master")] +use rustc_session::config; use rustc_span::{Span, Symbol, sym}; +#[cfg(feature = "master")] +use rustc_target::callconv::ArgAttributes; use rustc_target::callconv::{ArgAbi, PassMode}; -use crate::abi::{FnAbiGccExt, GccType}; +use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType}; use crate::builder::Builder; use crate::common::{SignType, TypeReflection}; use crate::context::CodegenCx; @@ -621,7 +626,82 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } else { self.linkage.set(FunctionType::Extern); let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); - let fn_ty = fn_abi.gcc_type(self); + assert!(!fn_abi.ret.is_indirect()); + assert!(!fn_abi.c_variadic); + + let return_type = match fn_abi.ret.mode { + PassMode::Ignore => self.type_void(), + PassMode::Direct(_) | PassMode::Pair(..) => { + fn_abi.ret.layout.immediate_gcc_type(self) + } + PassMode::Cast { .. } | PassMode::Indirect { .. } => { + unreachable!() + } + }; + + #[cfg(feature = "master")] + let mut non_null_args = Vec::new(); + + #[cfg(feature = "master")] + let mut apply_attrs = + |mut ty: Type<'gcc>, attrs: &ArgAttributes, arg_index: usize| { + if self.sess().opts.optimize == config::OptLevel::No { + return ty; + } + if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NoAlias) { + ty = ty.make_restrict() + } + if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NonNull) { + non_null_args.push(arg_index as i32 + 1); + } + ty + }; + #[cfg(not(feature = "master"))] + let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes, _arg_index: usize| ty; + + let mut argument_tys = Vec::with_capacity(fn_abi.args.len()); + for arg in fn_abi.args.iter() { + match arg.mode { + PassMode::Ignore => {} + PassMode::Pair(a, b) => { + let arg_pos = argument_tys.len(); + argument_tys.push(apply_attrs( + arg.layout.scalar_pair_element_gcc_type(self, 0), + &a, + arg_pos, + )); + argument_tys.push(apply_attrs( + arg.layout.scalar_pair_element_gcc_type(self, 1), + &b, + arg_pos + 1, + )); + } + PassMode::Direct(attrs) => argument_tys.push(apply_attrs( + arg.layout.immediate_gcc_type(self), + &attrs, + argument_tys.len(), + )), + PassMode::Indirect { .. } | PassMode::Cast { .. } => { + unreachable!() + } + } + } + + #[cfg(feature = "master")] + let fn_attrs = if non_null_args.is_empty() { + Vec::new() + } else { + vec![FnAttribute::NonNull(non_null_args)] + }; + + let fn_ty = FnAbiGcc { + return_type, + arguments_type: argument_tys, + is_c_variadic: false, + on_stack_param_indices: FxHashSet::default(), + #[cfg(feature = "master")] + fn_attributes: fn_attrs, + }; let func = match sym { "llvm.fma.f16" => { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 481f75f337d6..7327137fbbdd 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -649,7 +649,32 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { // FIXME remove usage of fn_abi let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); assert!(!fn_abi.ret.is_indirect()); - let fn_ty = fn_abi.llvm_type(self); + assert!(!fn_abi.c_variadic); + + let llreturn_ty = match &fn_abi.ret.mode { + PassMode::Ignore => self.type_void(), + PassMode::Direct(_) | PassMode::Pair(..) => fn_abi.ret.layout.immediate_llvm_type(self), + PassMode::Cast { .. } | PassMode::Indirect { .. } => { + unreachable!() + } + }; + + let mut llargument_tys = Vec::with_capacity(fn_abi.args.len()); + for arg in &fn_abi.args { + match &arg.mode { + PassMode::Ignore => {} + PassMode::Direct(_) => llargument_tys.push(arg.layout.immediate_llvm_type(self)), + PassMode::Pair(..) => { + llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(self, 0, true)); + llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(self, 1, true)); + } + PassMode::Indirect { .. } | PassMode::Cast { .. } => { + unreachable!() + } + }; + } + + let fn_ty = self.type_func(&llargument_tys, llreturn_ty); let fn_ptr = if let Some(&llfn) = self.intrinsic_instances.borrow().get(&instance) { llfn @@ -665,12 +690,11 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let llfn = declare_raw_fn( self, sym, - fn_abi.llvm_cconv(self), + llvm::CCallConv, llvm::UnnamedAddr::Global, llvm::Visibility::Default, fn_ty, ); - fn_abi.apply_attrs_llfn(self, llfn, Some(instance)); llfn }; From f004b3eb19b988a9066ca9dc9b2a63919f504ada Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:05:09 +0000 Subject: [PATCH 1757/3801] Reduce usage of FnAbi in codegen_llvm_intrinsic_call --- src/intrinsic/mod.rs | 88 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 36ea76cbc51a..f138b87d3405 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -4,10 +4,10 @@ mod simd; #[cfg(feature = "master")] use std::iter; -#[cfg(feature = "master")] -use gccjit::Type; use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; #[cfg(feature = "master")] +use gccjit::{FnAttribute, Type}; +#[cfg(feature = "master")] use rustc_abi::ExternAbi; use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange}; use rustc_codegen_ssa::MemFlags; @@ -22,13 +22,18 @@ use rustc_codegen_ssa::traits::{ ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods, }; +use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; use rustc_middle::ty::{self, Instance, Ty}; +#[cfg(feature = "master")] +use rustc_session::config; use rustc_span::{Span, Symbol, sym}; +#[cfg(feature = "master")] +use rustc_target::callconv::ArgAttributes; use rustc_target::callconv::{ArgAbi, PassMode}; -use crate::abi::{FnAbiGccExt, GccType}; +use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType}; use crate::builder::Builder; use crate::common::{SignType, TypeReflection}; use crate::context::CodegenCx; @@ -621,7 +626,82 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } else { self.linkage.set(FunctionType::Extern); let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); - let fn_ty = fn_abi.gcc_type(self); + assert!(!fn_abi.ret.is_indirect()); + assert!(!fn_abi.c_variadic); + + let return_type = match fn_abi.ret.mode { + PassMode::Ignore => self.type_void(), + PassMode::Direct(_) | PassMode::Pair(..) => { + fn_abi.ret.layout.immediate_gcc_type(self) + } + PassMode::Cast { .. } | PassMode::Indirect { .. } => { + unreachable!() + } + }; + + #[cfg(feature = "master")] + let mut non_null_args = Vec::new(); + + #[cfg(feature = "master")] + let mut apply_attrs = + |mut ty: Type<'gcc>, attrs: &ArgAttributes, arg_index: usize| { + if self.sess().opts.optimize == config::OptLevel::No { + return ty; + } + if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NoAlias) { + ty = ty.make_restrict() + } + if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NonNull) { + non_null_args.push(arg_index as i32 + 1); + } + ty + }; + #[cfg(not(feature = "master"))] + let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes, _arg_index: usize| ty; + + let mut argument_tys = Vec::with_capacity(fn_abi.args.len()); + for arg in fn_abi.args.iter() { + match arg.mode { + PassMode::Ignore => {} + PassMode::Pair(a, b) => { + let arg_pos = argument_tys.len(); + argument_tys.push(apply_attrs( + arg.layout.scalar_pair_element_gcc_type(self, 0), + &a, + arg_pos, + )); + argument_tys.push(apply_attrs( + arg.layout.scalar_pair_element_gcc_type(self, 1), + &b, + arg_pos + 1, + )); + } + PassMode::Direct(attrs) => argument_tys.push(apply_attrs( + arg.layout.immediate_gcc_type(self), + &attrs, + argument_tys.len(), + )), + PassMode::Indirect { .. } | PassMode::Cast { .. } => { + unreachable!() + } + } + } + + #[cfg(feature = "master")] + let fn_attrs = if non_null_args.is_empty() { + Vec::new() + } else { + vec![FnAttribute::NonNull(non_null_args)] + }; + + let fn_ty = FnAbiGcc { + return_type, + arguments_type: argument_tys, + is_c_variadic: false, + on_stack_param_indices: FxHashSet::default(), + #[cfg(feature = "master")] + fn_attributes: fn_attrs, + }; let func = match sym { "llvm.fma.f16" => { From f1ab0036585e64bffbdc8ac20e7b0a5fb9507e95 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 8 Jan 2026 10:47:29 +0000 Subject: [PATCH 1758/3801] Don't compute FnAbi for LLVM intrinsics in backends --- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 101 ++---------------- compiler/rustc_codegen_llvm/src/intrinsic.rs | 48 +++++---- 2 files changed, 34 insertions(+), 115 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index f138b87d3405..de262994fa45 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -4,9 +4,9 @@ mod simd; #[cfg(feature = "master")] use std::iter; -use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; #[cfg(feature = "master")] -use gccjit::{FnAttribute, Type}; +use gccjit::Type; +use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; #[cfg(feature = "master")] use rustc_abi::ExternAbi; use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange}; @@ -24,16 +24,16 @@ use rustc_codegen_ssa::traits::{ }; use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; -use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; +#[cfg(feature = "master")] +use rustc_middle::ty::layout::FnAbiOf; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance, Ty}; -#[cfg(feature = "master")] -use rustc_session::config; use rustc_span::{Span, Symbol, sym}; -#[cfg(feature = "master")] -use rustc_target::callconv::ArgAttributes; use rustc_target::callconv::{ArgAbi, PassMode}; -use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType}; +#[cfg(feature = "master")] +use crate::abi::FnAbiGccExt; +use crate::abi::GccType; use crate::builder::Builder; use crate::common::{SignType, TypeReflection}; use crate::context::CodegenCx; @@ -625,83 +625,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc *func } else { self.linkage.set(FunctionType::Extern); - let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); - assert!(!fn_abi.ret.is_indirect()); - assert!(!fn_abi.c_variadic); - - let return_type = match fn_abi.ret.mode { - PassMode::Ignore => self.type_void(), - PassMode::Direct(_) | PassMode::Pair(..) => { - fn_abi.ret.layout.immediate_gcc_type(self) - } - PassMode::Cast { .. } | PassMode::Indirect { .. } => { - unreachable!() - } - }; - - #[cfg(feature = "master")] - let mut non_null_args = Vec::new(); - - #[cfg(feature = "master")] - let mut apply_attrs = - |mut ty: Type<'gcc>, attrs: &ArgAttributes, arg_index: usize| { - if self.sess().opts.optimize == config::OptLevel::No { - return ty; - } - if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NoAlias) { - ty = ty.make_restrict() - } - if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NonNull) { - non_null_args.push(arg_index as i32 + 1); - } - ty - }; - #[cfg(not(feature = "master"))] - let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes, _arg_index: usize| ty; - - let mut argument_tys = Vec::with_capacity(fn_abi.args.len()); - for arg in fn_abi.args.iter() { - match arg.mode { - PassMode::Ignore => {} - PassMode::Pair(a, b) => { - let arg_pos = argument_tys.len(); - argument_tys.push(apply_attrs( - arg.layout.scalar_pair_element_gcc_type(self, 0), - &a, - arg_pos, - )); - argument_tys.push(apply_attrs( - arg.layout.scalar_pair_element_gcc_type(self, 1), - &b, - arg_pos + 1, - )); - } - PassMode::Direct(attrs) => argument_tys.push(apply_attrs( - arg.layout.immediate_gcc_type(self), - &attrs, - argument_tys.len(), - )), - PassMode::Indirect { .. } | PassMode::Cast { .. } => { - unreachable!() - } - } - } - - #[cfg(feature = "master")] - let fn_attrs = if non_null_args.is_empty() { - Vec::new() - } else { - vec![FnAttribute::NonNull(non_null_args)] - }; - - let fn_ty = FnAbiGcc { - return_type, - arguments_type: argument_tys, - is_c_variadic: false, - on_stack_param_indices: FxHashSet::default(), - #[cfg(feature = "master")] - fn_attributes: fn_attrs, - }; let func = match sym { "llvm.fma.f16" => { @@ -714,13 +637,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc self.intrinsics.borrow_mut().insert(sym.to_string(), func); - self.on_stack_function_params - .borrow_mut() - .insert(func, fn_ty.on_stack_param_indices); - #[cfg(feature = "master")] - for fn_attr in fn_ty.fn_attributes { - func.add_attribute(fn_attr); - } + self.on_stack_function_params.borrow_mut().insert(func, FxHashSet::default()); crate::attributes::from_fn_attrs(self, func, instance); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7327137fbbdd..13402edd13e2 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -646,32 +646,34 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { ) -> Self::Value { let tcx = self.tcx(); - // FIXME remove usage of fn_abi - let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); - assert!(!fn_abi.ret.is_indirect()); - assert!(!fn_abi.c_variadic); - - let llreturn_ty = match &fn_abi.ret.mode { - PassMode::Ignore => self.type_void(), - PassMode::Direct(_) | PassMode::Pair(..) => fn_abi.ret.layout.immediate_llvm_type(self), - PassMode::Cast { .. } | PassMode::Indirect { .. } => { - unreachable!() + let fn_ty = instance.ty(tcx, self.typing_env()); + let fn_sig = match *fn_ty.kind() { + ty::FnDef(def_id, args) => { + tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args)) } + _ => unreachable!(), + }; + assert!(!fn_sig.c_variadic); + + let ret_layout = self.layout_of(fn_sig.output()); + let llreturn_ty = if ret_layout.is_zst() { + self.type_void() + } else { + ret_layout.immediate_llvm_type(self) }; - let mut llargument_tys = Vec::with_capacity(fn_abi.args.len()); - for arg in &fn_abi.args { - match &arg.mode { - PassMode::Ignore => {} - PassMode::Direct(_) => llargument_tys.push(arg.layout.immediate_llvm_type(self)), - PassMode::Pair(..) => { - llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(self, 0, true)); - llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(self, 1, true)); - } - PassMode::Indirect { .. } | PassMode::Cast { .. } => { - unreachable!() - } - }; + let mut llargument_tys = Vec::with_capacity(fn_sig.inputs().len()); + for &arg in fn_sig.inputs() { + let arg_layout = self.layout_of(arg); + if arg_layout.is_zst() { + continue; + } + if let BackendRepr::ScalarPair(_, _) = arg_layout.backend_repr { + llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 0, true)); + llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 1, true)); + continue; + } + llargument_tys.push(arg_layout.immediate_llvm_type(self)); } let fn_ty = self.type_func(&llargument_tys, llreturn_ty); From e90414f6224b95662c2f52fcfc508a316f54db09 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 8 Jan 2026 10:47:29 +0000 Subject: [PATCH 1759/3801] Don't compute FnAbi for LLVM intrinsics in backends --- src/intrinsic/mod.rs | 101 ++++--------------------------------------- 1 file changed, 9 insertions(+), 92 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index f138b87d3405..de262994fa45 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -4,9 +4,9 @@ mod simd; #[cfg(feature = "master")] use std::iter; -use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; #[cfg(feature = "master")] -use gccjit::{FnAttribute, Type}; +use gccjit::Type; +use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; #[cfg(feature = "master")] use rustc_abi::ExternAbi; use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange}; @@ -24,16 +24,16 @@ use rustc_codegen_ssa::traits::{ }; use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; -use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; +#[cfg(feature = "master")] +use rustc_middle::ty::layout::FnAbiOf; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance, Ty}; -#[cfg(feature = "master")] -use rustc_session::config; use rustc_span::{Span, Symbol, sym}; -#[cfg(feature = "master")] -use rustc_target::callconv::ArgAttributes; use rustc_target::callconv::{ArgAbi, PassMode}; -use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType}; +#[cfg(feature = "master")] +use crate::abi::FnAbiGccExt; +use crate::abi::GccType; use crate::builder::Builder; use crate::common::{SignType, TypeReflection}; use crate::context::CodegenCx; @@ -625,83 +625,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc *func } else { self.linkage.set(FunctionType::Extern); - let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); - assert!(!fn_abi.ret.is_indirect()); - assert!(!fn_abi.c_variadic); - - let return_type = match fn_abi.ret.mode { - PassMode::Ignore => self.type_void(), - PassMode::Direct(_) | PassMode::Pair(..) => { - fn_abi.ret.layout.immediate_gcc_type(self) - } - PassMode::Cast { .. } | PassMode::Indirect { .. } => { - unreachable!() - } - }; - - #[cfg(feature = "master")] - let mut non_null_args = Vec::new(); - - #[cfg(feature = "master")] - let mut apply_attrs = - |mut ty: Type<'gcc>, attrs: &ArgAttributes, arg_index: usize| { - if self.sess().opts.optimize == config::OptLevel::No { - return ty; - } - if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NoAlias) { - ty = ty.make_restrict() - } - if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NonNull) { - non_null_args.push(arg_index as i32 + 1); - } - ty - }; - #[cfg(not(feature = "master"))] - let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes, _arg_index: usize| ty; - - let mut argument_tys = Vec::with_capacity(fn_abi.args.len()); - for arg in fn_abi.args.iter() { - match arg.mode { - PassMode::Ignore => {} - PassMode::Pair(a, b) => { - let arg_pos = argument_tys.len(); - argument_tys.push(apply_attrs( - arg.layout.scalar_pair_element_gcc_type(self, 0), - &a, - arg_pos, - )); - argument_tys.push(apply_attrs( - arg.layout.scalar_pair_element_gcc_type(self, 1), - &b, - arg_pos + 1, - )); - } - PassMode::Direct(attrs) => argument_tys.push(apply_attrs( - arg.layout.immediate_gcc_type(self), - &attrs, - argument_tys.len(), - )), - PassMode::Indirect { .. } | PassMode::Cast { .. } => { - unreachable!() - } - } - } - - #[cfg(feature = "master")] - let fn_attrs = if non_null_args.is_empty() { - Vec::new() - } else { - vec![FnAttribute::NonNull(non_null_args)] - }; - - let fn_ty = FnAbiGcc { - return_type, - arguments_type: argument_tys, - is_c_variadic: false, - on_stack_param_indices: FxHashSet::default(), - #[cfg(feature = "master")] - fn_attributes: fn_attrs, - }; let func = match sym { "llvm.fma.f16" => { @@ -714,13 +637,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc self.intrinsics.borrow_mut().insert(sym.to_string(), func); - self.on_stack_function_params - .borrow_mut() - .insert(func, fn_ty.on_stack_param_indices); - #[cfg(feature = "master")] - for fn_attr in fn_ty.fn_attributes { - func.add_attribute(fn_attr); - } + self.on_stack_function_params.borrow_mut().insert(func, FxHashSet::default()); crate::attributes::from_fn_attrs(self, func, instance); From aec8b698784311402bd193497a26357297d105bc Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 7 Jan 2026 16:26:52 +0000 Subject: [PATCH 1760/3801] Minor cleanups to fn_abi_new_uncached --- compiler/rustc_target/src/callconv/mod.rs | 11 +++++------ compiler/rustc_ty_utils/src/abi.rs | 12 +++--------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 092d99e91118..6faa57252ca2 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -381,15 +381,14 @@ impl<'a, Ty> ArgAbi<'a, Ty> { pub fn new( cx: &impl HasDataLayout, layout: TyAndLayout<'a, Ty>, - scalar_attrs: impl Fn(&TyAndLayout<'a, Ty>, Scalar, Size) -> ArgAttributes, + scalar_attrs: impl Fn(Scalar, Size) -> ArgAttributes, ) -> Self { let mode = match layout.backend_repr { - BackendRepr::Scalar(scalar) => { - PassMode::Direct(scalar_attrs(&layout, scalar, Size::ZERO)) - } + _ if layout.is_zst() => PassMode::Ignore, + BackendRepr::Scalar(scalar) => PassMode::Direct(scalar_attrs(scalar, Size::ZERO)), BackendRepr::ScalarPair(a, b) => PassMode::Pair( - scalar_attrs(&layout, a, Size::ZERO), - scalar_attrs(&layout, b, a.size(cx).align_to(b.align(cx).abi)), + scalar_attrs(a, Size::ZERO), + scalar_attrs(b, a.size(cx).align_to(b.align(cx).abi)), ), BackendRepr::SimdVector { .. } => PassMode::Direct(ArgAttributes::new()), BackendRepr::Memory { .. } => Self::indirect_pass_mode(&layout), diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 0676fa99d826..ad621c67772c 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -549,15 +549,9 @@ fn fn_abi_new_uncached<'tcx>( layout }; - let mut arg = ArgAbi::new(cx, layout, |layout, scalar, offset| { - arg_attrs_for_rust_scalar(*cx, scalar, *layout, offset, is_return, drop_target_pointee) - }); - - if arg.layout.is_zst() { - arg.mode = PassMode::Ignore; - } - - Ok(arg) + Ok(ArgAbi::new(cx, layout, |scalar, offset| { + arg_attrs_for_rust_scalar(*cx, scalar, layout, offset, is_return, drop_target_pointee) + })) }; let mut fn_abi = FnAbi { From a3359bdd4f117b6f315fce15e1d97d02c7bad015 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Mar 2025 10:26:37 +0000 Subject: [PATCH 1761/3801] Compile-Time Reflection MVP: tuples --- .../src/const_eval/machine.rs | 9 +- .../rustc_const_eval/src/const_eval/mod.rs | 1 + .../src/const_eval/type_info.rs | 158 ++++++++++++++++++ .../src/interpret/intrinsics.rs | 5 +- compiler/rustc_hir/src/lang_items.rs | 1 + .../rustc_hir_analysis/src/check/intrinsic.rs | 18 +- compiler/rustc_span/src/symbol.rs | 5 + library/core/src/intrinsics/mod.rs | 9 + library/core/src/lib.rs | 1 + library/core/src/mem/mod.rs | 3 + library/core/src/mem/type_info.rs | 69 ++++++++ src/tools/clippy/clippy_utils/src/sym.rs | 1 - .../abi/issues/issue-22565-rust-call.stderr | 4 +- tests/ui/error-codes/E0059.stderr | 4 +- tests/ui/impl-trait/where-allowed.stderr | 6 +- ...rust-call-abi-not-a-tuple-ice-81974.stderr | 16 +- .../overloaded-calls-nontuple.stderr | 12 +- tests/ui/reflection/dump.rs | 30 ++++ tests/ui/reflection/dump.run.stdout | 23 +++ tests/ui/reflection/feature_gate.rs | 8 + tests/ui/reflection/feature_gate.stderr | 33 ++++ tests/ui/reflection/tuples.rs | 36 ++++ .../resolve/resolve-assoc-suggestions.stderr | 4 + tests/ui/suggestions/fn-trait-notation.stderr | 4 +- tests/ui/thir-print/offset_of.stdout | 18 +- tests/ui/traits/ignore-err-impls.stderr | 6 +- .../next-solver/well-formed-in-relate.stderr | 6 +- tests/ui/tuple/builtin-fail.stderr | 8 +- tests/ui/typeck/issue-57404.stderr | 2 +- .../non-tupled-arg-mismatch.stderr | 2 +- triagebot.toml | 7 + 31 files changed, 456 insertions(+), 53 deletions(-) create mode 100644 compiler/rustc_const_eval/src/const_eval/type_info.rs create mode 100644 library/core/src/mem/type_info.rs create mode 100644 tests/ui/reflection/dump.rs create mode 100644 tests/ui/reflection/dump.run.stdout create mode 100644 tests/ui/reflection/feature_gate.rs create mode 100644 tests/ui/reflection/feature_gate.stderr create mode 100644 tests/ui/reflection/tuples.rs diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 7538130e9d92..719187b99012 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem}; use rustc_middle::mir::AssertMessage; -use rustc_middle::mir::interpret::ReportedErrorInfo; +use rustc_middle::mir::interpret::{Pointer, ReportedErrorInfo}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout, ValidityRequirement}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -22,7 +22,7 @@ use crate::errors::{LongRunning, LongRunningWarn}; use crate::fluent_generated as fluent; use crate::interpret::{ self, AllocId, AllocInit, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame, - GlobalAlloc, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, Pointer, RangeSet, Scalar, + GlobalAlloc, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, RangeSet, Scalar, compile_time_machine, err_inval, interp_ok, throw_exhaust, throw_inval, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format, }; @@ -586,6 +586,11 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { } } + sym::type_of => { + let ty = ecx.read_type_id(&args[0])?; + ecx.write_type_info(ty, dest)?; + } + _ => { // We haven't handled the intrinsic, let's see if we can use a fallback body. if ecx.tcx.intrinsic(instance.def_id()).unwrap().must_be_overridden { diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 624ca1dd2da0..e70488b81c4c 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -13,6 +13,7 @@ mod error; mod eval_queries; mod fn_queries; mod machine; +mod type_info; mod valtrees; pub use self::dummy_machine::*; diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs new file mode 100644 index 000000000000..a94ef580027b --- /dev/null +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -0,0 +1,158 @@ +use rustc_abi::FieldIdx; +use rustc_hir::LangItem; +use rustc_middle::mir::interpret::CtfeProvenance; +use rustc_middle::span_bug; +use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::{self, ScalarInt, Ty}; +use rustc_span::{Symbol, sym}; + +use crate::const_eval::CompileTimeMachine; +use crate::interpret::{ + Immediate, InterpCx, InterpResult, MPlaceTy, MemoryKind, Writeable, interp_ok, +}; + +impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { + /// Writes a `core::mem::type_info::TypeInfo` for a given type, `ty` to the given place. + pub(crate) fn write_type_info( + &mut self, + ty: Ty<'tcx>, + dest: &impl Writeable<'tcx, CtfeProvenance>, + ) -> InterpResult<'tcx> { + let ty_struct = self.tcx.require_lang_item(LangItem::Type, self.tcx.span); + let ty_struct = self.tcx.type_of(ty_struct).no_bound_vars().unwrap(); + assert_eq!(ty_struct, dest.layout().ty); + let ty_struct = ty_struct.ty_adt_def().unwrap().non_enum_variant(); + // Fill all fields of the `TypeInfo` struct. + for (idx, field) in ty_struct.fields.iter_enumerated() { + let field_dest = self.project_field(dest, idx)?; + let downcast = |name: Symbol| { + let variants = field_dest.layout().ty.ty_adt_def().unwrap().variants(); + let variant_id = variants + .iter_enumerated() + .find(|(_idx, var)| var.name == name) + .unwrap_or_else(|| panic!("got {name} but expected one of {variants:#?}")) + .0; + + interp_ok((variant_id, self.project_downcast(&field_dest, variant_id)?)) + }; + match field.name { + sym::kind => { + let variant_index = match ty.kind() { + ty::Tuple(fields) => { + let (variant, variant_place) = downcast(sym::Tuple)?; + // project to the single tuple variant field of `type_info::Tuple` struct type + let tuple_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + assert_eq!( + 1, + tuple_place + .layout() + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .len() + ); + self.write_tuple_fields(tuple_place, fields, ty)?; + variant + } + // For now just merge all primitives into one `Leaf` variant with no data + ty::Uint(_) | ty::Int(_) | ty::Float(_) | ty::Char | ty::Bool => { + downcast(sym::Leaf)?.0 + } + ty::Adt(_, _) + | ty::Foreign(_) + | ty::Str + | ty::Array(_, _) + | ty::Pat(_, _) + | ty::Slice(_) + | ty::RawPtr(..) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::UnsafeBinder(..) + | ty::Dynamic(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Never + | ty::Alias(..) + | ty::Param(_) + | ty::Bound(..) + | ty::Placeholder(_) + | ty::Infer(..) + | ty::Error(_) => downcast(sym::Other)?.0, + }; + self.write_discriminant(variant_index, &field_dest)? + } + other => span_bug!(self.tcx.span, "unknown `Type` field {other}"), + } + } + + interp_ok(()) + } + + pub(crate) fn write_tuple_fields( + &mut self, + tuple_place: impl Writeable<'tcx, CtfeProvenance>, + fields: &[Ty<'tcx>], + tuple_ty: Ty<'tcx>, + ) -> InterpResult<'tcx> { + // project into the `type_info::Tuple::fields` field + let fields_slice_place = self.project_field(&tuple_place, FieldIdx::ZERO)?; + // get the `type_info::Field` type from `fields: &[Field]` + let field_type = fields_slice_place + .layout() + .ty + .builtin_deref(false) + .unwrap() + .sequence_element_type(self.tcx.tcx); + // Create an array with as many elements as the number of fields in the inspected tuple + let fields_layout = + self.layout_of(Ty::new_array(self.tcx.tcx, field_type, fields.len() as u64))?; + let fields_place = self.allocate(fields_layout, MemoryKind::Stack)?; + let mut fields_places = self.project_array_fields(&fields_place)?; + + let tuple_layout = self.layout_of(tuple_ty)?; + + while let Some((i, place)) = fields_places.next(self)? { + let field_ty = fields[i as usize]; + self.write_field(field_ty, place, tuple_layout, i)?; + } + + let fields_place = fields_place.map_provenance(CtfeProvenance::as_immutable); + + let ptr = Immediate::new_slice(fields_place.ptr(), fields.len() as u64, self); + + self.write_immediate(ptr, &fields_slice_place) + } + + fn write_field( + &mut self, + field_ty: Ty<'tcx>, + place: MPlaceTy<'tcx>, + layout: TyAndLayout<'tcx>, + idx: u64, + ) -> InterpResult<'tcx> { + for (field_idx, field_ty_field) in + place.layout.ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + match field_ty_field.name { + sym::ty => self.write_type_id(field_ty, &field_place)?, + sym::offset => { + let offset = layout.fields.offset(idx as usize); + self.write_scalar( + ScalarInt::try_from_target_usize(offset.bytes(), self.tcx.tcx).unwrap(), + &field_place, + )?; + } + other => { + span_bug!(self.tcx.def_span(field_ty_field.did), "unimplemented field {other}") + } + } + } + interp_ok(()) + } +} diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index d70d157d8808..94832c0c2577 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -27,6 +27,7 @@ use super::{ throw_ub_custom, throw_ub_format, }; use crate::fluent_generated as fluent; +use crate::interpret::Writeable; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum MulAddType { @@ -68,10 +69,10 @@ pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (AllocId } impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Generates a value of `TypeId` for `ty` in-place. - fn write_type_id( + pub(crate) fn write_type_id( &mut self, ty: Ty<'tcx>, - dest: &PlaceTy<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx, ()> { let tcx = self.tcx; let type_id_hash = tcx.type_id_hash(ty).as_u128(); diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 4ac3e4e83e80..557f76208bfe 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -278,6 +278,7 @@ language_item_table! { PartialOrd, sym::partial_ord, partial_ord_trait, Target::Trait, GenericRequirement::Exact(1); CVoid, sym::c_void, c_void, Target::Enum, GenericRequirement::None; + Type, sym::type_info, type_struct, Target::Struct, GenericRequirement::None; TypeId, sym::type_id, type_id, Target::Struct, GenericRequirement::None; // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 9eaf5319cb04..c84c1a8ca16d 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -213,6 +213,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::type_id | sym::type_id_eq | sym::type_name + | sym::type_of | sym::ub_checks | sym::variant_count | sym::vtable_for @@ -308,13 +309,22 @@ pub(crate) fn check_intrinsic_type( sym::needs_drop => (1, 0, vec![], tcx.types.bool), sym::type_name => (1, 0, vec![], Ty::new_static_str(tcx)), - sym::type_id => { - (1, 0, vec![], tcx.type_of(tcx.lang_items().type_id().unwrap()).instantiate_identity()) - } + sym::type_id => ( + 1, + 0, + vec![], + tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap(), + ), sym::type_id_eq => { - let type_id = tcx.type_of(tcx.lang_items().type_id().unwrap()).instantiate_identity(); + let type_id = tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap(); (0, 0, vec![type_id, type_id], tcx.types.bool) } + sym::type_of => ( + 0, + 0, + vec![tcx.type_of(tcx.lang_items().type_id().unwrap()).no_bound_vars().unwrap()], + tcx.type_of(tcx.lang_items().type_struct().unwrap()).no_bound_vars().unwrap(), + ), sym::offload => ( 3, 0, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 72709753b1df..1e288adc11cb 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -284,6 +284,7 @@ symbols! { IteratorItem, IteratorMap, Layout, + Leaf, Left, LinkedList, LintDiagnostic, @@ -302,6 +303,7 @@ symbols! { Ordering, OsStr, OsString, + Other, Output, Param, ParamSet, @@ -380,6 +382,7 @@ symbols! { TryCapturePrintable, TryFrom, TryInto, + Tuple, Ty, TyCtxt, TyKind, @@ -2317,6 +2320,7 @@ symbols! { type_const, type_id, type_id_eq, + type_info, type_ir, type_ir_infer_ctxt_like, type_ir_inherent, @@ -2324,6 +2328,7 @@ symbols! { type_length_limit, type_macros, type_name, + type_of, type_privacy_lints, typed_swap_nonoverlapping, u8, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 0ae8d3d4a4ce..e8e0cda38e9b 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2849,6 +2849,15 @@ pub const unsafe fn size_of_val(ptr: *const T) -> usize; #[rustc_intrinsic_const_stable_indirect] pub const unsafe fn align_of_val(ptr: *const T) -> usize; +/// Compute the type information of a concrete type. +/// It can only be called at compile time, the backends do +/// not implement it. +#[rustc_intrinsic] +#[unstable(feature = "core_intrinsics", issue = "none")] +pub const fn type_of(_id: crate::any::TypeId) -> crate::mem::type_info::Type { + panic!("`TypeId::info` can only be called at compile-time") +} + /// Gets a static string slice containing the name of a type. /// /// Note that, unlike most intrinsics, this can only be called at compile-time diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 962b0cea4a4f..dfc9a7b5dbc3 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -124,6 +124,7 @@ #![feature(str_internals)] #![feature(str_split_inclusive_remainder)] #![feature(str_split_remainder)] +#![feature(type_info)] #![feature(ub_checks)] #![feature(unsafe_pinned)] #![feature(utf16_extra)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 4f7edce1e977..1671c8219de1 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -37,6 +37,9 @@ pub use drop_guard::DropGuard; #[doc(inline)] pub use crate::intrinsics::transmute; +#[unstable(feature = "type_info", issue = "146922")] +pub mod type_info; + /// Takes ownership and "forgets" about the value **without running its destructor**. /// /// Any resources the value manages, such as heap memory or a file handle, will linger diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs new file mode 100644 index 000000000000..b188504f76d9 --- /dev/null +++ b/library/core/src/mem/type_info.rs @@ -0,0 +1,69 @@ +//! MVP for exposing compile-time information about types in a +//! runtime or const-eval processable way. + +use crate::any::TypeId; +use crate::intrinsics::type_of; + +/// Compile-time type information. +#[derive(Debug)] +#[non_exhaustive] +#[lang = "type_info"] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Type { + /// Per-type information + pub kind: TypeKind, +} + +impl TypeId { + /// Compute the type information of a concrete type. + /// It can only be called at compile time. + #[unstable(feature = "type_info", issue = "146922")] + #[rustc_const_unstable(feature = "type_info", issue = "146922")] + pub const fn info(self) -> Type { + type_of(self) + } +} + +impl Type { + /// Returns the type information of the generic type parameter. + #[unstable(feature = "type_info", issue = "146922")] + #[rustc_const_unstable(feature = "type_info", issue = "146922")] + // FIXME(reflection): don't require the 'static bound + pub const fn of() -> Self { + const { TypeId::of::().info() } + } +} + +/// Compile-time type information. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub enum TypeKind { + /// Tuples. + Tuple(Tuple), + /// Primitives + /// FIXME(#146922): disambiguate further + Leaf, + /// FIXME(#146922): add all the common types + Other, +} + +/// Compile-time type information about tuples. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Tuple { + /// All fields of a tuple. + pub fields: &'static [Field], +} + +/// Compile-time type information about fields of tuples, structs and enum variants. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Field { + /// The field's type. + pub ty: TypeId, + /// Offset in bytes from the parent type + pub offset: usize, +} diff --git a/src/tools/clippy/clippy_utils/src/sym.rs b/src/tools/clippy/clippy_utils/src/sym.rs index a0d2e8673fe6..74f89cfc6811 100644 --- a/src/tools/clippy/clippy_utils/src/sym.rs +++ b/src/tools/clippy/clippy_utils/src/sym.rs @@ -62,7 +62,6 @@ generate! { MsrvStack, Octal, OpenOptions, - Other, PathLookup, Regex, RegexBuilder, diff --git a/tests/ui/abi/issues/issue-22565-rust-call.stderr b/tests/ui/abi/issues/issue-22565-rust-call.stderr index 0fd3285cd3a5..3e296bdaea41 100644 --- a/tests/ui/abi/issues/issue-22565-rust-call.stderr +++ b/tests/ui/abi/issues/issue-22565-rust-call.stderr @@ -2,7 +2,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/issue-22565-rust-call.rs:3:1 | LL | extern "rust-call" fn b(_i: i32) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `i32` error: functions with the "rust-call" ABI must take a single non-self tuple argument --> $DIR/issue-22565-rust-call.rs:17:5 @@ -32,7 +32,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/issue-22565-rust-call.rs:27:7 | LL | b(10); - | ^^ the trait `Tuple` is not implemented for `i32` + | ^^ the trait `std::marker::Tuple` is not implemented for `i32` error: functions with the "rust-call" ABI must take a single non-self tuple argument --> $DIR/issue-22565-rust-call.rs:29:5 diff --git a/tests/ui/error-codes/E0059.stderr b/tests/ui/error-codes/E0059.stderr index d26fadcdbfa7..698ee0a2a902 100644 --- a/tests/ui/error-codes/E0059.stderr +++ b/tests/ui/error-codes/E0059.stderr @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `Fn` trait must be a tuple --> $DIR/E0059.rs:3:11 | LL | fn foo>(f: F) -> F::Output { f(3) } - | ^^^^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^^^^ the trait `std::marker::Tuple` is not implemented for `i32` | note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -11,7 +11,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/E0059.rs:3:41 | LL | fn foo>(f: F) -> F::Output { f(3) } - | ^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^ the trait `std::marker::Tuple` is not implemented for `i32` error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit --> $DIR/E0059.rs:3:41 diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 6cab4fabb1ff..1a8d6509e137 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -384,11 +384,11 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani | = note: multiple `impl`s satisfying `_: Fn()` found in the following crates: `alloc`, `core`: - impl Fn for &F - where A: Tuple, F: Fn, F: ?Sized; + where A: std::marker::Tuple, F: Fn, F: ?Sized; - impl Fn for Box - where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; + where Args: std::marker::Tuple, F: Fn, A: Allocator, F: ?Sized; - impl Fn for Exclusive - where F: Sync, F: Fn, Args: Tuple; + where F: Sync, F: Fn, Args: std::marker::Tuple; error[E0118]: no nominal type found for inherent implementation --> $DIR/where-allowed.rs:241:1 diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr index 75ee936d9e8b..e7cb82687fa7 100644 --- a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5 | LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A` | note: required by a bound in `FnOnce` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -15,7 +15,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:24:12 | LL | impl FnOnce for CachedFun - | ^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A` | note: required by a bound in `FnOnce` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -28,7 +28,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5 | LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A` | note: required by a bound in `FnOnce` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -41,7 +41,7 @@ error[E0059]: type parameter to bare `FnMut` trait must be a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:39:12 | LL | impl FnMut for CachedFun - | ^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A` | note: required by a bound in `FnMut` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -54,7 +54,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5 | LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A` | help: consider further restricting type parameter `A` with unstable trait `Tuple` | @@ -65,7 +65,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5 | LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A` | help: consider further restricting type parameter `A` with unstable trait `Tuple` | @@ -76,7 +76,7 @@ error[E0277]: `A` is not a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:34:19 | LL | self.call_mut(a) - | -------- ^ the trait `Tuple` is not implemented for `A` + | -------- ^ the trait `std::marker::Tuple` is not implemented for `A` | | | required by a bound introduced by this call | @@ -91,7 +91,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:59:26 | LL | cachedcoso.call_once(1); - | --------- ^ the trait `Tuple` is not implemented for `i32` + | --------- ^ the trait `std::marker::Tuple` is not implemented for `i32` | | | required by a bound introduced by this call | diff --git a/tests/ui/overloaded/overloaded-calls-nontuple.stderr b/tests/ui/overloaded/overloaded-calls-nontuple.stderr index 22598f3a3901..54a9d1f09b52 100644 --- a/tests/ui/overloaded/overloaded-calls-nontuple.stderr +++ b/tests/ui/overloaded/overloaded-calls-nontuple.stderr @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `FnMut` trait must be a tuple --> $DIR/overloaded-calls-nontuple.rs:10:6 | LL | impl FnMut for S { - | ^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `isize` | note: required by a bound in `FnMut` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -11,7 +11,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple --> $DIR/overloaded-calls-nontuple.rs:18:6 | LL | impl FnOnce for S { - | ^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `isize` | note: required by a bound in `FnOnce` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -20,19 +20,19 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/overloaded-calls-nontuple.rs:12:5 | LL | extern "rust-call" fn call_mut(&mut self, z: isize) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `isize` error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument --> $DIR/overloaded-calls-nontuple.rs:21:5 | LL | extern "rust-call" fn call_once(mut self, z: isize) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `isize` error[E0277]: `isize` is not a tuple --> $DIR/overloaded-calls-nontuple.rs:23:23 | LL | self.call_mut(z) - | -------- ^ the trait `Tuple` is not implemented for `isize` + | -------- ^ the trait `std::marker::Tuple` is not implemented for `isize` | | | required by a bound introduced by this call | @@ -53,7 +53,7 @@ error[E0277]: `isize` is not a tuple --> $DIR/overloaded-calls-nontuple.rs:29:10 | LL | drop(s(3)) - | ^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^ the trait `std::marker::Tuple` is not implemented for `isize` error: aborting due to 7 previous errors diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs new file mode 100644 index 000000000000..3bf4f32b6641 --- /dev/null +++ b/tests/ui/reflection/dump.rs @@ -0,0 +1,30 @@ +#![feature(type_info)] +//@ run-pass +//@ check-run-results +#![allow(dead_code)] + +use std::mem::type_info::Type; + +struct Foo { + a: u32, +} + +enum Bar { + Some(u32), + None, + Foomp { a: (), b: &'static str }, +} + +struct Unsized { + x: u16, + s: str, +} + +fn main() { + println!("{:#?}", const { Type::of::<(u8, u8, ())>() }.kind); + println!("{:#?}", const { Type::of::() }.kind); + println!("{:#?}", const { Type::of::() }.kind); + println!("{:#?}", const { Type::of::<&Unsized>() }.kind); + println!("{:#?}", const { Type::of::<&str>() }.kind); + println!("{:#?}", const { Type::of::<&[u8]>() }.kind); +} diff --git a/tests/ui/reflection/dump.run.stdout b/tests/ui/reflection/dump.run.stdout new file mode 100644 index 000000000000..71fd80b46658 --- /dev/null +++ b/tests/ui/reflection/dump.run.stdout @@ -0,0 +1,23 @@ +Tuple( + Tuple { + fields: [ + Field { + ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + offset: 0, + }, + Field { + ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + offset: 1, + }, + Field { + ty: TypeId(0x41223169ff28813ba79b7268a2a968d9), + offset: 2, + }, + ], + }, +) +Other +Other +Other +Other +Other diff --git a/tests/ui/reflection/feature_gate.rs b/tests/ui/reflection/feature_gate.rs new file mode 100644 index 000000000000..2dde26809793 --- /dev/null +++ b/tests/ui/reflection/feature_gate.rs @@ -0,0 +1,8 @@ +use std::mem::type_info::Type; +//~^ ERROR: use of unstable library feature `type_info` + +fn main() { + let ty = std::mem::type_info::Type::of::<()>(); + //~^ ERROR: use of unstable library feature `type_info` + //~| ERROR: use of unstable library feature `type_info` +} diff --git a/tests/ui/reflection/feature_gate.stderr b/tests/ui/reflection/feature_gate.stderr new file mode 100644 index 000000000000..76ad18ffb0ba --- /dev/null +++ b/tests/ui/reflection/feature_gate.stderr @@ -0,0 +1,33 @@ +error[E0658]: use of unstable library feature `type_info` + --> $DIR/feature_gate.rs:1:5 + | +LL | use std::mem::type_info::Type; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146922 for more information + = help: add `#![feature(type_info)]` 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[E0658]: use of unstable library feature `type_info` + --> $DIR/feature_gate.rs:5:14 + | +LL | let ty = std::mem::type_info::Type::of::<()>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146922 for more information + = help: add `#![feature(type_info)]` 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[E0658]: use of unstable library feature `type_info` + --> $DIR/feature_gate.rs:5:14 + | +LL | let ty = std::mem::type_info::Type::of::<()>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146922 for more information + = help: add `#![feature(type_info)]` 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 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/reflection/tuples.rs b/tests/ui/reflection/tuples.rs new file mode 100644 index 000000000000..eab25a691efe --- /dev/null +++ b/tests/ui/reflection/tuples.rs @@ -0,0 +1,36 @@ +#![feature(type_info)] + +//@ run-pass + +use std::mem::type_info::{Type, TypeKind}; + +fn assert_tuple_arity() { + const { + match &Type::of::().kind { + TypeKind::Tuple(tup) => { + assert!(tup.fields.len() == N); + } + _ => unreachable!(), + } + } +} + +fn main() { + assert_tuple_arity::<(), 0>(); + assert_tuple_arity::<(u8,), 1>(); + assert_tuple_arity::<(u8, u8), 2>(); + const { + match &Type::of::<(u8, u8)>().kind { + TypeKind::Tuple(tup) => { + let [a, b] = tup.fields else { unreachable!() }; + assert!(a.offset == 0); + assert!(b.offset == 1); + match (&a.ty.info().kind, &b.ty.info().kind) { + (TypeKind::Leaf, TypeKind::Leaf) => {} + _ => unreachable!(), + } + } + _ => unreachable!(), + } + } +} diff --git a/tests/ui/resolve/resolve-assoc-suggestions.stderr b/tests/ui/resolve/resolve-assoc-suggestions.stderr index ef519ac0d921..7d94fb5ca35f 100644 --- a/tests/ui/resolve/resolve-assoc-suggestions.stderr +++ b/tests/ui/resolve/resolve-assoc-suggestions.stderr @@ -31,6 +31,10 @@ help: you might have meant to use the associated type | LL | let _: Self::Type; | ++++++ +help: consider importing this struct + | +LL + use std::mem::type_info::Type; + | error[E0531]: cannot find tuple struct or tuple variant `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:25:13 diff --git a/tests/ui/suggestions/fn-trait-notation.stderr b/tests/ui/suggestions/fn-trait-notation.stderr index 9b47c8c02a78..9d0845478527 100644 --- a/tests/ui/suggestions/fn-trait-notation.stderr +++ b/tests/ui/suggestions/fn-trait-notation.stderr @@ -32,7 +32,7 @@ error[E0059]: type parameter to bare `Fn` trait must be a tuple --> $DIR/fn-trait-notation.rs:4:8 | LL | F: Fn, - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `i32` | note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -47,7 +47,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/fn-trait-notation.rs:9:5 | LL | f(3); - | ^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^ the trait `std::marker::Tuple` is not implemented for `i32` error[E0308]: mismatched types --> $DIR/fn-trait-notation.rs:17:5 diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index ab924091ba7a..dcf60a86af9b 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -68,7 +68,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).10)) - span: $DIR/offset_of.rs:37:5: 1437:57 (#0) + span: $DIR/offset_of.rs:37:5: 1440:57 (#0) } } Stmt { @@ -117,7 +117,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).20)) - span: $DIR/offset_of.rs:38:5: 1437:57 (#0) + span: $DIR/offset_of.rs:38:5: 1440:57 (#0) } } Stmt { @@ -166,7 +166,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).30)) - span: $DIR/offset_of.rs:39:5: 1437:57 (#0) + span: $DIR/offset_of.rs:39:5: 1440:57 (#0) } } Stmt { @@ -215,7 +215,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).40)) - span: $DIR/offset_of.rs:40:5: 1437:57 (#0) + span: $DIR/offset_of.rs:40:5: 1440:57 (#0) } } Stmt { @@ -264,7 +264,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).50)) - span: $DIR/offset_of.rs:41:5: 1437:57 (#0) + span: $DIR/offset_of.rs:41:5: 1440:57 (#0) } } ] @@ -864,7 +864,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).12)) - span: $DIR/offset_of.rs:45:5: 1437:57 (#0) + span: $DIR/offset_of.rs:45:5: 1440:57 (#0) } } Stmt { @@ -913,7 +913,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).24)) - span: $DIR/offset_of.rs:46:5: 1437:57 (#0) + span: $DIR/offset_of.rs:46:5: 1440:57 (#0) } } Stmt { @@ -962,7 +962,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).36)) - span: $DIR/offset_of.rs:47:5: 1437:57 (#0) + span: $DIR/offset_of.rs:47:5: 1440:57 (#0) } } Stmt { @@ -1011,7 +1011,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).48)) - span: $DIR/offset_of.rs:48:5: 1437:57 (#0) + span: $DIR/offset_of.rs:48:5: 1440:57 (#0) } } ] diff --git a/tests/ui/traits/ignore-err-impls.stderr b/tests/ui/traits/ignore-err-impls.stderr index 68077c435135..46a2a7d55a2e 100644 --- a/tests/ui/traits/ignore-err-impls.stderr +++ b/tests/ui/traits/ignore-err-impls.stderr @@ -4,10 +4,10 @@ error[E0425]: cannot find type `Type` in this scope LL | impl Generic for S {} | ^^^^ not found in this scope | -help: you might be missing a type parameter +help: consider importing this struct + | +LL + use std::mem::type_info::Type; | -LL | impl Generic for S {} - | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/well-formed-in-relate.stderr b/tests/ui/traits/next-solver/well-formed-in-relate.stderr index d79e465b3e38..264ab9bebbb9 100644 --- a/tests/ui/traits/next-solver/well-formed-in-relate.stderr +++ b/tests/ui/traits/next-solver/well-formed-in-relate.stderr @@ -9,11 +9,11 @@ LL | x = unconstrained_map(); | = note: multiple `impl`s satisfying `_: Fn()` found in the following crates: `alloc`, `core`: - impl Fn for &F - where A: Tuple, F: Fn, F: ?Sized; + where A: std::marker::Tuple, F: Fn, F: ?Sized; - impl Fn for Box - where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; + where Args: std::marker::Tuple, F: Fn, A: Allocator, F: ?Sized; - impl Fn for Exclusive - where F: Sync, F: Fn, Args: Tuple; + where F: Sync, F: Fn, Args: std::marker::Tuple; note: required by a bound in `unconstrained_map` --> $DIR/well-formed-in-relate.rs:21:25 | diff --git a/tests/ui/tuple/builtin-fail.stderr b/tests/ui/tuple/builtin-fail.stderr index 44e79578f4c9..0dec88ded7ce 100644 --- a/tests/ui/tuple/builtin-fail.stderr +++ b/tests/ui/tuple/builtin-fail.stderr @@ -2,7 +2,7 @@ error[E0277]: `T` is not a tuple --> $DIR/builtin-fail.rs:8:23 | LL | assert_is_tuple::(); - | ^ the trait `Tuple` is not implemented for `T` + | ^ the trait `std::marker::Tuple` is not implemented for `T` | note: required by a bound in `assert_is_tuple` --> $DIR/builtin-fail.rs:3:23 @@ -18,7 +18,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/builtin-fail.rs:13:23 | LL | assert_is_tuple::(); - | ^^^ the trait `Tuple` is not implemented for `i32` + | ^^^ the trait `std::marker::Tuple` is not implemented for `i32` | note: required by a bound in `assert_is_tuple` --> $DIR/builtin-fail.rs:3:23 @@ -30,7 +30,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/builtin-fail.rs:15:24 | LL | assert_is_tuple::<(i32)>(); - | ^^^ the trait `Tuple` is not implemented for `i32` + | ^^^ the trait `std::marker::Tuple` is not implemented for `i32` | note: required by a bound in `assert_is_tuple` --> $DIR/builtin-fail.rs:3:23 @@ -44,7 +44,7 @@ error[E0277]: `TupleStruct` is not a tuple LL | assert_is_tuple::(); | ^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `Tuple` is not implemented for `TupleStruct` +help: the trait `std::marker::Tuple` is not implemented for `TupleStruct` --> $DIR/builtin-fail.rs:5:1 | LL | struct TupleStruct(i32, i32); diff --git a/tests/ui/typeck/issue-57404.stderr b/tests/ui/typeck/issue-57404.stderr index 4c1bfc0cbf77..f1d28e475a07 100644 --- a/tests/ui/typeck/issue-57404.stderr +++ b/tests/ui/typeck/issue-57404.stderr @@ -2,7 +2,7 @@ error[E0277]: `&mut ()` is not a tuple --> $DIR/issue-57404.rs:6:41 | LL | handlers.unwrap().as_mut().call_mut(&mut ()); - | -------- ^^^^^^^ the trait `Tuple` is not implemented for `&mut ()` + | -------- ^^^^^^^ the trait `std::marker::Tuple` is not implemented for `&mut ()` | | | required by a bound introduced by this call | diff --git a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr index 0d4265ddf8bd..621a533dd1c5 100644 --- a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr +++ b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `Fn` trait must be a tuple --> $DIR/non-tupled-arg-mismatch.rs:3:9 | LL | fn a>(f: F) {} - | ^^^^^^^^^ the trait `Tuple` is not implemented for `usize` + | ^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `usize` | note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL diff --git a/triagebot.toml b/triagebot.toml index fb6660b9dd03..9afe66c24717 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1003,6 +1003,13 @@ cc = ["@lcnr"] message = "HIR ty lowering was modified" cc = ["@fmease"] +[mentions."library/core/src/mem/type_info.rs"] +message = """ +The reflection data structures are tied exactly to the implementation +in the compiler. Make sure to also adjust `rustc_const_eval/src/const_eval/type_info.rs +""" +cc = ["@oli-obk"] + [mentions."compiler/rustc_error_codes/src/lib.rs"] message = "Some changes occurred in diagnostic error codes" cc = ["@GuillaumeGomez"] From 72f1ac9fbdbff5b432519891ac3d826a0333cf34 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Mar 2025 10:26:37 +0000 Subject: [PATCH 1762/3801] Compile-Time Reflection MVP: tuples --- clippy_utils/src/sym.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index a0d2e8673fe6..74f89cfc6811 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -62,7 +62,6 @@ generate! { MsrvStack, Octal, OpenOptions, - Other, PathLookup, Regex, RegexBuilder, From 2afe5b1a837b5e4d1cb27f675218de4c800d2b80 Mon Sep 17 00:00:00 2001 From: Jamie Cunliffe Date: Thu, 8 Jan 2026 11:59:41 +0000 Subject: [PATCH 1763/3801] Fix ICE in inline always warning emission. The calls to `def_path_str` were outside the decorate callback in `node_span_lint` which caused an ICE when the warning was an allowed warning due to the call to `def_path_str` being executed but the warning not actually being emitted. --- compiler/rustc_mir_transform/src/errors.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index ee21d4fbcead..21a6c4d653bc 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -19,14 +19,14 @@ pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>( caller_def_id: DefId, callee_only: &[&'a str], ) { - let callee = tcx.def_path_str(callee_def_id); - let caller = tcx.def_path_str(caller_def_id); - tcx.node_span_lint( lint::builtin::INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES, tcx.local_def_id_to_hir_id(caller_def_id.as_local().unwrap()), call_span, |lint| { + let callee = tcx.def_path_str(callee_def_id); + let caller = tcx.def_path_str(caller_def_id); + lint.primary_message(format!( "call to `#[inline(always)]`-annotated `{callee}` \ requires the same target features to be inlined" From 82028b0f9a9695edd3f70d54234df0bb61e4184d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 14 Mar 2025 14:39:58 +0000 Subject: [PATCH 1764/3801] Add size information --- .../src/const_eval/type_info.rs | 17 +++++++++++++++++ library/core/src/mem/type_info.rs | 2 ++ 2 files changed, 19 insertions(+) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index a94ef580027b..f932b198b426 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -86,6 +86,23 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { }; self.write_discriminant(variant_index, &field_dest)? } + sym::size => { + let layout = self.layout_of(ty)?; + let variant_index = if layout.is_sized() { + let (variant, variant_place) = downcast(sym::Some)?; + let size_field_place = + self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_scalar( + ScalarInt::try_from_target_usize(layout.size.bytes(), self.tcx.tcx) + .unwrap(), + &size_field_place, + )?; + variant + } else { + downcast(sym::None)?.0 + }; + self.write_discriminant(variant_index, &field_dest)?; + } other => span_bug!(self.tcx.span, "unknown `Type` field {other}"), } } diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index b188504f76d9..7938e2b52ed0 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -12,6 +12,8 @@ use crate::intrinsics::type_of; pub struct Type { /// Per-type information pub kind: TypeKind, + /// Size of the type. `None` if it is unsized + pub size: Option, } impl TypeId { From d41191958a87e483de72fd73fc4470b0f9b9e6f2 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 8 Jan 2026 12:35:30 +0000 Subject: [PATCH 1765/3801] rename the `derive_{eq, clone_copy}` features to `*_internals` --- library/core/src/clone.rs | 6 +++--- library/core/src/cmp.rs | 8 ++++++-- library/core/src/marker.rs | 2 +- .../{derive-eq.md => derive-clone-copy-internals.md} | 2 +- .../{derive-clone-copy.md => derive-eq-internals.md} | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) rename src/doc/unstable-book/src/library-features/{derive-eq.md => derive-clone-copy-internals.md} (77%) rename src/doc/unstable-book/src/library-features/{derive-clone-copy.md => derive-eq-internals.md} (82%) diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index e3d4b5c3331c..85b09ee06f1f 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -285,7 +285,7 @@ pub const unsafe trait TrivialClone: [const] Clone {} /// Derive macro generating an impl of the trait `Clone`. #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -#[allow_internal_unstable(core_intrinsics, derive_clone_copy, trivial_clone)] +#[allow_internal_unstable(core_intrinsics, derive_clone_copy_internals, trivial_clone)] pub macro Clone($item:item) { /* compiler built-in */ } @@ -350,7 +350,7 @@ impl_use_cloned! { #[doc(hidden)] #[allow(missing_debug_implementations)] #[unstable( - feature = "derive_clone_copy", + feature = "derive_clone_copy_internals", reason = "deriving hack, should not be public", issue = "none" )] @@ -360,7 +360,7 @@ pub struct AssertParamIsClone { #[doc(hidden)] #[allow(missing_debug_implementations)] #[unstable( - feature = "derive_clone_copy", + feature = "derive_clone_copy_internals", reason = "deriving hack, should not be public", issue = "none" )] diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index feb9c4319604..2f2477008206 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -351,7 +351,7 @@ pub const trait Eq: [const] PartialEq + PointeeSized { /// Derive macro generating an impl of the trait [`Eq`]. #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)] +#[allow_internal_unstable(core_intrinsics, derive_eq_internals, structural_match)] #[allow_internal_unstable(coverage_attribute)] pub macro Eq($item:item) { /* compiler built-in */ @@ -363,7 +363,11 @@ pub macro Eq($item:item) { // This struct should never appear in user code. #[doc(hidden)] #[allow(missing_debug_implementations)] -#[unstable(feature = "derive_eq", reason = "deriving hack, should not be public", issue = "none")] +#[unstable( + feature = "derive_eq_internals", + reason = "deriving hack, should not be public", + issue = "none" +)] pub struct AssertParamIsEq { _field: crate::marker::PhantomData, } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 5ecc2a63ea83..68f5649210de 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -466,7 +466,7 @@ pub trait Copy: Clone { /// Derive macro generating an impl of the trait `Copy`. #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -#[allow_internal_unstable(core_intrinsics, derive_clone_copy)] +#[allow_internal_unstable(core_intrinsics, derive_clone_copy_internals)] pub macro Copy($item:item) { /* compiler built-in */ } diff --git a/src/doc/unstable-book/src/library-features/derive-eq.md b/src/doc/unstable-book/src/library-features/derive-clone-copy-internals.md similarity index 77% rename from src/doc/unstable-book/src/library-features/derive-eq.md rename to src/doc/unstable-book/src/library-features/derive-clone-copy-internals.md index 68a275f5419d..c53a55132de5 100644 --- a/src/doc/unstable-book/src/library-features/derive-eq.md +++ b/src/doc/unstable-book/src/library-features/derive-clone-copy-internals.md @@ -1,4 +1,4 @@ -# `derive_eq` +# `derive_clone_copy_internals` This feature is internal to the Rust compiler and is not intended for general use. diff --git a/src/doc/unstable-book/src/library-features/derive-clone-copy.md b/src/doc/unstable-book/src/library-features/derive-eq-internals.md similarity index 82% rename from src/doc/unstable-book/src/library-features/derive-clone-copy.md rename to src/doc/unstable-book/src/library-features/derive-eq-internals.md index cc603911cbd2..3f334b5ad3b6 100644 --- a/src/doc/unstable-book/src/library-features/derive-clone-copy.md +++ b/src/doc/unstable-book/src/library-features/derive-eq-internals.md @@ -1,4 +1,4 @@ -# `derive_clone_copy` +# `derive_eq_internals` This feature is internal to the Rust compiler and is not intended for general use. From 27b1083a96ab1bcc8b511882b31534e333a8e5c9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Jan 2026 14:10:33 +0100 Subject: [PATCH 1766/3801] Update `literal-escaper` version to `0.0.7` --- Cargo.lock | 4 ++-- compiler/rustc_ast/Cargo.toml | 2 +- compiler/rustc_parse/Cargo.toml | 2 +- compiler/rustc_parse_format/Cargo.toml | 2 +- compiler/rustc_proc_macro/Cargo.toml | 2 +- library/Cargo.lock | 5 ++--- library/proc_macro/Cargo.toml | 2 +- src/tools/clippy/clippy_dev/Cargo.toml | 2 +- src/tools/lint-docs/Cargo.toml | 2 +- 9 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 427e93e56cd8..4c1697ec4d0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3412,9 +3412,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc-literal-escaper" -version = "0.0.5" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ee29da77c5a54f42697493cd4c9b9f31b74df666a6c04dfc4fde77abe0438b" +checksum = "8be87abb9e40db7466e0681dc8ecd9dcfd40360cb10b4c8fe24a7c4c3669b198" [[package]] name = "rustc-main" diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 34d90adf5cb3..471a6bf1df13 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" # tidy-alphabetical-start bitflags = "2.4.1" memchr = "2.7.6" -rustc-literal-escaper = "0.0.5" +rustc-literal-escaper = "0.0.7" rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index 04a51c905661..f0c84e07a56f 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start bitflags = "2.4.1" -rustc-literal-escaper = "0.0.5" +rustc-literal-escaper = "0.0.7" rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml index d178fcda1fb9..10b41a39c3bf 100644 --- a/compiler/rustc_parse_format/Cargo.toml +++ b/compiler/rustc_parse_format/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -rustc-literal-escaper = "0.0.5" +rustc-literal-escaper = "0.0.7" rustc_lexer = { path = "../rustc_lexer" } # tidy-alphabetical-end diff --git a/compiler/rustc_proc_macro/Cargo.toml b/compiler/rustc_proc_macro/Cargo.toml index beb95aa3b52f..54c765075113 100644 --- a/compiler/rustc_proc_macro/Cargo.toml +++ b/compiler/rustc_proc_macro/Cargo.toml @@ -16,7 +16,7 @@ doctest = false [dependencies] # tidy-alphabetical-start -rustc-literal-escaper = "0.0.5" +rustc-literal-escaper = "0.0.7" # tidy-alphabetical-end [features] diff --git a/library/Cargo.lock b/library/Cargo.lock index 5e49843dae06..f6c14bc58a04 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -283,12 +283,11 @@ dependencies = [ [[package]] name = "rustc-literal-escaper" -version = "0.0.5" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ee29da77c5a54f42697493cd4c9b9f31b74df666a6c04dfc4fde77abe0438b" +checksum = "8be87abb9e40db7466e0681dc8ecd9dcfd40360cb10b4c8fe24a7c4c3669b198" dependencies = [ "rustc-std-workspace-core", - "rustc-std-workspace-std", ] [[package]] diff --git a/library/proc_macro/Cargo.toml b/library/proc_macro/Cargo.toml index 3a4840a57334..1e5046ca61c3 100644 --- a/library/proc_macro/Cargo.toml +++ b/library/proc_macro/Cargo.toml @@ -9,7 +9,7 @@ std = { path = "../std" } # `core` when resolving doc links. Without this line a different `core` will be # loaded from sysroot causing duplicate lang items and other similar errors. core = { path = "../core" } -rustc-literal-escaper = { version = "0.0.5", features = ["rustc-dep-of-std"] } +rustc-literal-escaper = { version = "0.0.7", features = ["rustc-dep-of-std"] } [features] default = ["rustc-dep-of-std"] diff --git a/src/tools/clippy/clippy_dev/Cargo.toml b/src/tools/clippy/clippy_dev/Cargo.toml index c2abbac37535..238465210ee2 100644 --- a/src/tools/clippy/clippy_dev/Cargo.toml +++ b/src/tools/clippy/clippy_dev/Cargo.toml @@ -10,7 +10,7 @@ clap = { version = "4.4", features = ["derive"] } indoc = "1.0" itertools = "0.12" opener = "0.7" -rustc-literal-escaper = "0.0.5" +rustc-literal-escaper = "0.0.7" walkdir = "2.3" [package.metadata.rust-analyzer] diff --git a/src/tools/lint-docs/Cargo.toml b/src/tools/lint-docs/Cargo.toml index 6e1ab84ed18d..ab99eb8ea3b7 100644 --- a/src/tools/lint-docs/Cargo.toml +++ b/src/tools/lint-docs/Cargo.toml @@ -7,7 +7,7 @@ description = "A script to extract the lint documentation for the rustc book." # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rustc-literal-escaper = "0.0.5" +rustc-literal-escaper = "0.0.7" serde_json = "1.0.57" tempfile = "3.1.0" walkdir = "2.3.1" From 21f6afca40cb423b4920fbc571490f801aa95d16 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Jan 2026 14:10:33 +0100 Subject: [PATCH 1767/3801] Update `literal-escaper` version to `0.0.7` --- clippy_dev/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml index c2abbac37535..238465210ee2 100644 --- a/clippy_dev/Cargo.toml +++ b/clippy_dev/Cargo.toml @@ -10,7 +10,7 @@ clap = { version = "4.4", features = ["derive"] } indoc = "1.0" itertools = "0.12" opener = "0.7" -rustc-literal-escaper = "0.0.5" +rustc-literal-escaper = "0.0.7" walkdir = "2.3" [package.metadata.rust-analyzer] From 0051e31f6f8000c6bf2fab1549a55a26d4d455ff Mon Sep 17 00:00:00 2001 From: dianqk Date: Tue, 23 Dec 2025 22:25:11 +0800 Subject: [PATCH 1768/3801] New MIR Pass: SsaRangePropagation --- compiler/rustc_middle/src/mir/statement.rs | 6 + compiler/rustc_mir_transform/src/lib.rs | 4 + .../rustc_mir_transform/src/ssa_range_prop.rs | 203 ++++++++++++++++++ ...a_range.on_assert.SsaRangePropagation.diff | 69 ++++++ .../ssa_range.on_if.SsaRangePropagation.diff | 63 ++++++ ...ssa_range.on_if_2.SsaRangePropagation.diff | 20 ++ ...sa_range.on_match.SsaRangePropagation.diff | 33 +++ ..._range.on_match_2.SsaRangePropagation.diff | 26 +++ tests/mir-opt/range/ssa_range.rs | 70 ++++++ 9 files changed, 494 insertions(+) create mode 100644 compiler/rustc_mir_transform/src/ssa_range_prop.rs create mode 100644 tests/mir-opt/range/ssa_range.on_assert.SsaRangePropagation.diff create mode 100644 tests/mir-opt/range/ssa_range.on_if.SsaRangePropagation.diff create mode 100644 tests/mir-opt/range/ssa_range.on_if_2.SsaRangePropagation.diff create mode 100644 tests/mir-opt/range/ssa_range.on_match.SsaRangePropagation.diff create mode 100644 tests/mir-opt/range/ssa_range.on_match_2.SsaRangePropagation.diff create mode 100644 tests/mir-opt/range/ssa_range.rs diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 1ba1ae3e1531..2ee1d53cabd5 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -374,6 +374,12 @@ impl<'tcx> Place<'tcx> { self.projection.iter().any(|elem| elem.is_indirect()) } + /// Returns `true` if the `Place` always refers to the same memory region + /// whatever the state of the program. + pub fn is_stable_offset(&self) -> bool { + self.projection.iter().all(|elem| elem.is_stable_offset()) + } + /// Returns `true` if this `Place`'s first projection is `Deref`. /// /// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 701d7ff854a7..24ea4a5cd6df 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -198,6 +198,7 @@ declare_passes! { mod single_use_consts : SingleUseConsts; mod sroa : ScalarReplacementOfAggregates; mod strip_debuginfo : StripDebugInfo; + mod ssa_range_prop: SsaRangePropagation; mod unreachable_enum_branching : UnreachableEnumBranching; mod unreachable_prop : UnreachablePropagation; mod validate : Validator; @@ -741,6 +742,9 @@ pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<' &dead_store_elimination::DeadStoreElimination::Initial, &gvn::GVN, &simplify::SimplifyLocals::AfterGVN, + // This pass does attempt to track assignments. + // Keep it close to GVN which merges identical values into the same local. + &ssa_range_prop::SsaRangePropagation, &match_branches::MatchBranchSimplification, &dataflow_const_prop::DataflowConstProp, &single_use_consts::SingleUseConsts, diff --git a/compiler/rustc_mir_transform/src/ssa_range_prop.rs b/compiler/rustc_mir_transform/src/ssa_range_prop.rs new file mode 100644 index 000000000000..47e17de0560b --- /dev/null +++ b/compiler/rustc_mir_transform/src/ssa_range_prop.rs @@ -0,0 +1,203 @@ +//! A pass that propagates the known ranges of SSA locals. +//! We can know the ranges of SSA locals in certain locations for the following code: +//! ``` +//! fn foo(a: u32) { +//! let b = a < 9; // the integer representation of b is within the full range [0, 2). +//! if b { +//! let c = b; // c is true since b is within the range [1, 2). +//! let d = a < 8; // d is true since a is within the range [0, 9). +//! } +//! } +//! ``` +use rustc_abi::WrappingRange; +use rustc_const_eval::interpret::Scalar; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::graph::dominators::Dominators; +use rustc_index::bit_set::DenseBitSet; +use rustc_middle::mir::visit::MutVisitor; +use rustc_middle::mir::{BasicBlock, Body, Location, Operand, Place, TerminatorKind, *}; +use rustc_middle::ty::{TyCtxt, TypingEnv}; +use rustc_span::DUMMY_SP; + +use crate::ssa::SsaLocals; + +pub(super) struct SsaRangePropagation; + +impl<'tcx> crate::MirPass<'tcx> for SsaRangePropagation { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + sess.mir_opt_level() > 1 + } + + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let typing_env = body.typing_env(tcx); + let ssa = SsaLocals::new(tcx, body, typing_env); + // Clone dominators because we need them while mutating the body. + let dominators = body.basic_blocks.dominators().clone(); + let mut range_set = + RangeSet::new(tcx, typing_env, body, &ssa, &body.local_decls, dominators); + + let reverse_postorder = body.basic_blocks.reverse_postorder().to_vec(); + for bb in reverse_postorder { + let data = &mut body.basic_blocks.as_mut_preserves_cfg()[bb]; + range_set.visit_basic_block_data(bb, data); + } + } + + fn is_required(&self) -> bool { + false + } +} + +struct RangeSet<'tcx, 'body, 'a> { + tcx: TyCtxt<'tcx>, + typing_env: TypingEnv<'tcx>, + ssa: &'a SsaLocals, + local_decls: &'body LocalDecls<'tcx>, + dominators: Dominators, + /// Known ranges at each locations. + ranges: FxHashMap, Vec<(Location, WrappingRange)>>, + /// Determines if the basic block has a single unique predecessor. + unique_predecessors: DenseBitSet, +} + +impl<'tcx, 'body, 'a> RangeSet<'tcx, 'body, 'a> { + fn new( + tcx: TyCtxt<'tcx>, + typing_env: TypingEnv<'tcx>, + body: &Body<'tcx>, + ssa: &'a SsaLocals, + local_decls: &'body LocalDecls<'tcx>, + dominators: Dominators, + ) -> Self { + let predecessors = body.basic_blocks.predecessors(); + let mut unique_predecessors = DenseBitSet::new_empty(body.basic_blocks.len()); + for bb in body.basic_blocks.indices() { + if predecessors[bb].len() == 1 { + unique_predecessors.insert(bb); + } + } + RangeSet { + tcx, + typing_env, + ssa, + local_decls, + dominators, + ranges: FxHashMap::default(), + unique_predecessors, + } + } + + /// Create a new known range at the location. + fn insert_range(&mut self, place: Place<'tcx>, location: Location, range: WrappingRange) { + assert!(self.is_ssa(place)); + self.ranges.entry(place).or_default().push((location, range)); + } + + /// Get the known range at the location. + fn get_range(&self, place: &Place<'tcx>, location: Location) -> Option { + let Some(ranges) = self.ranges.get(place) else { + return None; + }; + // FIXME: This should use the intersection of all valid ranges. + let (_, range) = + ranges.iter().find(|(range_loc, _)| range_loc.dominates(location, &self.dominators))?; + Some(*range) + } + + fn try_as_constant( + &mut self, + place: Place<'tcx>, + location: Location, + ) -> Option> { + if let Some(range) = self.get_range(&place, location) + && range.start == range.end + { + let ty = place.ty(self.local_decls, self.tcx).ty; + let layout = self.tcx.layout_of(self.typing_env.as_query_input(ty)).ok()?; + let value = ConstValue::Scalar(Scalar::from_uint(range.start, layout.size)); + let const_ = Const::Val(value, ty); + return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_ }); + } + None + } + + fn is_ssa(&self, place: Place<'tcx>) -> bool { + self.ssa.is_ssa(place.local) && place.is_stable_offset() + } +} + +impl<'tcx> MutVisitor<'tcx> for RangeSet<'tcx, '_, '_> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) { + // Attempts to simplify an operand to a constant value. + if let Some(place) = operand.place() + && let Some(const_) = self.try_as_constant(place, location) + { + *operand = Operand::Constant(Box::new(const_)); + }; + } + + fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { + self.super_terminator(terminator, location); + match &terminator.kind { + TerminatorKind::Assert { cond, expected, target, .. } => { + if let Some(place) = cond.place() + && self.is_ssa(place) + { + let successor = Location { block: *target, statement_index: 0 }; + if location.dominates(successor, &self.dominators) { + assert_ne!(location.block, successor.block); + let val = *expected as u128; + let range = WrappingRange { start: val, end: val }; + self.insert_range(place, successor, range); + } + } + } + TerminatorKind::SwitchInt { discr, targets } => { + if let Some(place) = discr.place() + && self.is_ssa(place) + // Reduce the potential compile-time overhead. + && targets.all_targets().len() < 16 + { + let mut distinct_targets: FxHashMap = FxHashMap::default(); + for (_, target) in targets.iter() { + let targets = distinct_targets.entry(target).or_default(); + *targets += 1; + } + for (val, target) in targets.iter() { + if distinct_targets[&target] != 1 { + // FIXME: For multiple targets, the range can be the union of their values. + continue; + } + let successor = Location { block: target, statement_index: 0 }; + if self.unique_predecessors.contains(successor.block) { + assert_ne!(location.block, successor.block); + let range = WrappingRange { start: val, end: val }; + self.insert_range(place, successor, range); + } + } + + // FIXME: The range for the otherwise target be extend to more types. + // For instance, `val` is within the range [4, 1) at the otherwise target of `matches!(val, 1 | 2 | 3)`. + let otherwise = Location { block: targets.otherwise(), statement_index: 0 }; + if place.ty(self.local_decls, self.tcx).ty.is_bool() + && let [val] = targets.all_values() + && self.unique_predecessors.contains(otherwise.block) + { + assert_ne!(location.block, otherwise.block); + let range = if val.get() == 0 { + WrappingRange { start: 1, end: 1 } + } else { + WrappingRange { start: 0, end: 0 } + }; + self.insert_range(place, otherwise, range); + } + } + } + _ => {} + } + } +} diff --git a/tests/mir-opt/range/ssa_range.on_assert.SsaRangePropagation.diff b/tests/mir-opt/range/ssa_range.on_assert.SsaRangePropagation.diff new file mode 100644 index 000000000000..ae3f49a8847b --- /dev/null +++ b/tests/mir-opt/range/ssa_range.on_assert.SsaRangePropagation.diff @@ -0,0 +1,69 @@ +- // MIR for `on_assert` before SsaRangePropagation ++ // MIR for `on_assert` after SsaRangePropagation + + fn on_assert(_1: usize, _2: &[u8]) -> u8 { + debug i => _1; + debug v => _2; + let mut _0: u8; + let _3: (); + let mut _4: bool; + let mut _5: usize; + let mut _6: usize; + let mut _7: &[u8]; + let mut _8: !; + let _9: usize; + let mut _10: usize; + let mut _11: bool; + scope 1 (inlined core::slice::::len) { + scope 2 (inlined std::ptr::metadata::<[u8]>) { + } + } + + bb0: { + StorageLive(_3); + nop; + StorageLive(_5); + _5 = copy _1; + nop; + StorageLive(_7); + _7 = &(*_2); + _6 = PtrMetadata(copy _2); + StorageDead(_7); + _4 = Lt(copy _1, copy _6); + switchInt(copy _4) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + nop; + StorageDead(_5); + _3 = const (); + nop; + StorageDead(_3); + StorageLive(_9); + _9 = copy _1; + _10 = copy _6; +- _11 = copy _4; +- assert(copy _4, "index out of bounds: the length is {} but the index is {}", copy _6, copy _1) -> [success: bb3, unwind unreachable]; ++ _11 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", copy _6, copy _1) -> [success: bb3, unwind unreachable]; + } + + bb2: { + nop; + StorageDead(_5); + StorageLive(_8); + _8 = panic(const "assertion failed: i < v.len()") -> unwind unreachable; + } + + bb3: { + _0 = copy (*_2)[_1]; + StorageDead(_9); + return; + } + } + + ALLOC0 (size: 29, align: 1) { + 0x00 │ 61 73 73 65 72 74 69 6f 6e 20 66 61 69 6c 65 64 │ assertion failed + 0x10 │ 3a 20 69 20 3c 20 76 2e 6c 65 6e 28 29 │ : i < v.len() + } + diff --git a/tests/mir-opt/range/ssa_range.on_if.SsaRangePropagation.diff b/tests/mir-opt/range/ssa_range.on_if.SsaRangePropagation.diff new file mode 100644 index 000000000000..2493e069edd4 --- /dev/null +++ b/tests/mir-opt/range/ssa_range.on_if.SsaRangePropagation.diff @@ -0,0 +1,63 @@ +- // MIR for `on_if` before SsaRangePropagation ++ // MIR for `on_if` after SsaRangePropagation + + fn on_if(_1: usize, _2: &[u8]) -> u8 { + debug i => _1; + debug v => _2; + let mut _0: u8; + let mut _3: bool; + let mut _4: usize; + let mut _5: usize; + let mut _6: &[u8]; + let _7: usize; + let mut _8: usize; + let mut _9: bool; + scope 1 (inlined core::slice::::len) { + scope 2 (inlined std::ptr::metadata::<[u8]>) { + } + } + + bb0: { + nop; + StorageLive(_4); + _4 = copy _1; + nop; + StorageLive(_6); + _6 = &(*_2); + _5 = PtrMetadata(copy _2); + StorageDead(_6); + _3 = Lt(copy _1, copy _5); + switchInt(copy _3) -> [0: bb3, otherwise: bb1]; + } + + bb1: { + nop; + StorageDead(_4); + StorageLive(_7); + _7 = copy _1; + _8 = copy _5; +- _9 = copy _3; +- assert(copy _3, "index out of bounds: the length is {} but the index is {}", copy _5, copy _1) -> [success: bb2, unwind unreachable]; ++ _9 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", copy _5, copy _1) -> [success: bb2, unwind unreachable]; + } + + bb2: { + _0 = copy (*_2)[_1]; + StorageDead(_7); + goto -> bb4; + } + + bb3: { + nop; + StorageDead(_4); + _0 = const 0_u8; + goto -> bb4; + } + + bb4: { + nop; + return; + } + } + diff --git a/tests/mir-opt/range/ssa_range.on_if_2.SsaRangePropagation.diff b/tests/mir-opt/range/ssa_range.on_if_2.SsaRangePropagation.diff new file mode 100644 index 000000000000..8a957238c845 --- /dev/null +++ b/tests/mir-opt/range/ssa_range.on_if_2.SsaRangePropagation.diff @@ -0,0 +1,20 @@ +- // MIR for `on_if_2` before SsaRangePropagation ++ // MIR for `on_if_2` after SsaRangePropagation + + fn on_if_2(_1: bool) -> bool { + let mut _0: bool; + + bb0: { + switchInt(copy _1) -> [1: bb2, otherwise: bb1]; + } + + bb1: { + goto -> bb2; + } + + bb2: { + _0 = copy _1; + return; + } + } + diff --git a/tests/mir-opt/range/ssa_range.on_match.SsaRangePropagation.diff b/tests/mir-opt/range/ssa_range.on_match.SsaRangePropagation.diff new file mode 100644 index 000000000000..f91ac7090dde --- /dev/null +++ b/tests/mir-opt/range/ssa_range.on_match.SsaRangePropagation.diff @@ -0,0 +1,33 @@ +- // MIR for `on_match` before SsaRangePropagation ++ // MIR for `on_match` after SsaRangePropagation + + fn on_match(_1: u8) -> u8 { + debug i => _1; + let mut _0: u8; + + bb0: { + switchInt(copy _1) -> [1: bb3, 2: bb2, otherwise: bb1]; + } + + bb1: { + _0 = const 0_u8; + goto -> bb4; + } + + bb2: { +- _0 = copy _1; ++ _0 = const 2_u8; + goto -> bb4; + } + + bb3: { +- _0 = copy _1; ++ _0 = const 1_u8; + goto -> bb4; + } + + bb4: { + return; + } + } + diff --git a/tests/mir-opt/range/ssa_range.on_match_2.SsaRangePropagation.diff b/tests/mir-opt/range/ssa_range.on_match_2.SsaRangePropagation.diff new file mode 100644 index 000000000000..53433d9fe4ba --- /dev/null +++ b/tests/mir-opt/range/ssa_range.on_match_2.SsaRangePropagation.diff @@ -0,0 +1,26 @@ +- // MIR for `on_match_2` before SsaRangePropagation ++ // MIR for `on_match_2` after SsaRangePropagation + + fn on_match_2(_1: u8) -> u8 { + debug i => _1; + let mut _0: u8; + + bb0: { + switchInt(copy _1) -> [1: bb2, 2: bb2, otherwise: bb1]; + } + + bb1: { + _0 = const 0_u8; + goto -> bb3; + } + + bb2: { + _0 = copy _1; + goto -> bb3; + } + + bb3: { + return; + } + } + diff --git a/tests/mir-opt/range/ssa_range.rs b/tests/mir-opt/range/ssa_range.rs new file mode 100644 index 000000000000..964d9b97cf92 --- /dev/null +++ b/tests/mir-opt/range/ssa_range.rs @@ -0,0 +1,70 @@ +//@ test-mir-pass: SsaRangePropagation +//@ compile-flags: -Zmir-enable-passes=+GVN,+Inline --crate-type=lib -Cpanic=abort + +#![feature(custom_mir, core_intrinsics)] + +use std::intrinsics::mir::*; + +// EMIT_MIR ssa_range.on_if.SsaRangePropagation.diff +pub fn on_if(i: usize, v: &[u8]) -> u8 { + // CHECK-LABEL: fn on_if( + // CHECK: assert(const true + if i < v.len() { v[i] } else { 0 } +} + +// EMIT_MIR ssa_range.on_assert.SsaRangePropagation.diff +pub fn on_assert(i: usize, v: &[u8]) -> u8 { + // CHECK-LABEL: fn on_assert( + // CHECK: assert(const true + assert!(i < v.len()); + v[i] +} + +// EMIT_MIR ssa_range.on_match.SsaRangePropagation.diff +pub fn on_match(i: u8) -> u8 { + // CHECK-LABEL: fn on_match( + // CHECK: switchInt(copy _1) -> [1: [[BB_V1:bb.*]], 2: [[BB_V2:bb.*]], + // CHECK: [[BB_V2]]: { + // CHECK-NEXT: _0 = const 2_u8; + // CHECK: [[BB_V1]]: { + // CHECK-NEXT: _0 = const 1_u8; + match i { + 1 => i, + 2 => i, + _ => 0, + } +} + +// EMIT_MIR ssa_range.on_match_2.SsaRangePropagation.diff +pub fn on_match_2(i: u8) -> u8 { + // CHECK-LABEL: fn on_match_2( + // CHECK: switchInt(copy _1) -> [1: [[BB:bb.*]], 2: [[BB]], + // CHECK: [[BB]]: { + // CHECK-NEXT: _0 = copy _1; + match i { + 1 | 2 => i, + _ => 0, + } +} + +// EMIT_MIR ssa_range.on_if_2.SsaRangePropagation.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub fn on_if_2(a: bool) -> bool { + // CHECK-LABEL: fn on_if_2( + // CHECK: _0 = copy _1; + mir! { + { + match a { + true => bb2, + _ => bb1 + } + } + bb1 = { + Goto(bb2) + } + bb2 = { + RET = a; + Return() + } + } +} From e9a67c74720911c531290c8ebc330e0fb5dc34d9 Mon Sep 17 00:00:00 2001 From: dianqk Date: Fri, 2 Jan 2026 22:15:40 +0800 Subject: [PATCH 1769/3801] Propagates assume --- .../rustc_mir_transform/src/ssa_range_prop.rs | 16 ++++++ ...a_range.on_assume.SsaRangePropagation.diff | 56 +++++++++++++++++++ tests/mir-opt/range/ssa_range.rs | 10 ++++ 3 files changed, 82 insertions(+) create mode 100644 tests/mir-opt/range/ssa_range.on_assume.SsaRangePropagation.diff diff --git a/compiler/rustc_mir_transform/src/ssa_range_prop.rs b/compiler/rustc_mir_transform/src/ssa_range_prop.rs index 47e17de0560b..7a8be8efdfd1 100644 --- a/compiler/rustc_mir_transform/src/ssa_range_prop.rs +++ b/compiler/rustc_mir_transform/src/ssa_range_prop.rs @@ -140,6 +140,22 @@ impl<'tcx> MutVisitor<'tcx> for RangeSet<'tcx, '_, '_> { }; } + fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { + self.super_statement(statement, location); + match &statement.kind { + StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(operand)) => { + if let Some(place) = operand.place() + && self.is_ssa(place) + { + let successor = location.successor_within_block(); + let range = WrappingRange { start: 1, end: 1 }; + self.insert_range(place, successor, range); + } + } + _ => {} + } + } + fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { self.super_terminator(terminator, location); match &terminator.kind { diff --git a/tests/mir-opt/range/ssa_range.on_assume.SsaRangePropagation.diff b/tests/mir-opt/range/ssa_range.on_assume.SsaRangePropagation.diff new file mode 100644 index 000000000000..3be6f083604d --- /dev/null +++ b/tests/mir-opt/range/ssa_range.on_assume.SsaRangePropagation.diff @@ -0,0 +1,56 @@ +- // MIR for `on_assume` before SsaRangePropagation ++ // MIR for `on_assume` after SsaRangePropagation + + fn on_assume(_1: usize, _2: &[u8]) -> u8 { + debug i => _1; + debug v => _2; + let mut _0: u8; + let _3: (); + let _4: (); + let mut _5: bool; + let mut _6: usize; + let mut _7: usize; + let mut _8: &[u8]; + let _9: usize; + let mut _10: usize; + let mut _11: bool; + scope 1 (inlined core::slice::::len) { + scope 2 (inlined std::ptr::metadata::<[u8]>) { + } + } + + bb0: { + StorageLive(_3); + StorageLive(_4); + nop; + StorageLive(_6); + _6 = copy _1; + nop; + StorageLive(_8); + _8 = &(*_2); + _7 = PtrMetadata(copy _2); + StorageDead(_8); + _5 = Lt(copy _1, copy _7); + nop; + StorageDead(_6); + assume(copy _5); + nop; + StorageDead(_4); + _3 = const (); + StorageDead(_3); + StorageLive(_9); + _9 = copy _1; + _10 = copy _7; +- _11 = copy _5; +- assert(copy _5, "index out of bounds: the length is {} but the index is {}", copy _7, copy _1) -> [success: bb1, unwind unreachable]; ++ _11 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", copy _7, copy _1) -> [success: bb1, unwind unreachable]; + } + + bb1: { + _0 = copy (*_2)[_1]; + StorageDead(_9); + return; + } + } + diff --git a/tests/mir-opt/range/ssa_range.rs b/tests/mir-opt/range/ssa_range.rs index 964d9b97cf92..c8440a10a408 100644 --- a/tests/mir-opt/range/ssa_range.rs +++ b/tests/mir-opt/range/ssa_range.rs @@ -20,6 +20,16 @@ pub fn on_assert(i: usize, v: &[u8]) -> u8 { v[i] } +// EMIT_MIR ssa_range.on_assume.SsaRangePropagation.diff +pub fn on_assume(i: usize, v: &[u8]) -> u8 { + // CHECK-LABEL: fn on_assume( + // CHECK: assert(const true + unsafe { + std::intrinsics::assume(i < v.len()); + } + v[i] +} + // EMIT_MIR ssa_range.on_match.SsaRangePropagation.diff pub fn on_match(i: u8) -> u8 { // CHECK-LABEL: fn on_match( From 665770ec84032d2ce7e5c90fa116764c0d9c61cf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 8 Jan 2026 12:03:56 +0000 Subject: [PATCH 1770/3801] Remove std_detect_file_io and std_detect_dlsym_getauxval features They were introduced back when std_detect was a standalone crate published to crates.io. The motivation for std_detect_dlsym_getauxval was to allow using getauxval without dlopen when statically linking musl, which we now unconditionally do for musl. And for std_detect_file_io to allow no_std usage, which std_detect now supports even with that feature enabled as it directly uses libc. This also prevents accidentally disabling runtime feature detection when using cargo build -Zbuild-std -Zbuild-std-features= --- library/std/Cargo.toml | 4 -- library/std_detect/Cargo.toml | 7 +-- library/std_detect/README.md | 26 ----------- library/std_detect/src/detect/mod.rs | 8 ++-- .../src/detect/os/linux/aarch64/tests.rs | 1 - .../std_detect/src/detect/os/linux/auxvec.rs | 44 +++++++------------ .../src/detect/os/linux/auxvec/tests.rs | 3 -- library/std_detect/src/detect/os/linux/mod.rs | 4 +- library/std_detect/src/lib.rs | 3 +- library/sysroot/Cargo.toml | 4 +- 10 files changed, 24 insertions(+), 80 deletions(-) diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 43caf7734fdb..5c9ae52d9e6c 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -128,10 +128,6 @@ debug_refcell = ["core/debug_refcell"] llvm_enzyme = ["core/llvm_enzyme"] -# Enable std_detect features: -std_detect_file_io = ["std_detect/std_detect_file_io"] -std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"] - # Enable using raw-dylib for Windows imports. # This will eventually be the default. windows_raw_dylib = ["windows-targets/windows_raw_dylib"] diff --git a/library/std_detect/Cargo.toml b/library/std_detect/Cargo.toml index 2739bb592300..bcfdb3901957 100644 --- a/library/std_detect/Cargo.toml +++ b/library/std_detect/Cargo.toml @@ -25,10 +25,7 @@ core = { version = "1.0.0", package = 'rustc-std-workspace-core' } alloc = { version = "1.0.0", package = 'rustc-std-workspace-alloc' } [target.'cfg(not(windows))'.dependencies] -libc = { version = "0.2.0", optional = true, default-features = false } +libc = { version = "0.2.0", default-features = false } [features] -default = [] -std_detect_file_io = [ "libc" ] -std_detect_dlsym_getauxval = [ "libc" ] -std_detect_env_override = [ "libc" ] +std_detect_env_override = [] diff --git a/library/std_detect/README.md b/library/std_detect/README.md index 177848dec104..895f3426d049 100644 --- a/library/std_detect/README.md +++ b/library/std_detect/README.md @@ -21,32 +21,6 @@ run-time feature detection support than the one offered by Rust's standard library. We intend to make `std_detect` more flexible and configurable in this regard to better serve the needs of `#[no_std]` targets. -# Features - -* `std_detect_dlsym_getauxval` (enabled by default, requires `libc`): Enable to -use `libc::dlsym` to query whether [`getauxval`] is linked into the binary. When -this is not the case, this feature allows other fallback methods to perform -run-time feature detection. When this feature is disabled, `std_detect` assumes -that [`getauxval`] is linked to the binary. If that is not the case the behavior -is undefined. - - Note: This feature is ignored on `*-linux-{gnu,musl,ohos}*` and `*-android*` targets - because we can safely assume `getauxval` is linked to the binary. - * `*-linux-gnu*` targets ([since Rust 1.64](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html)) - have glibc requirements higher than [glibc 2.16 that added `getauxval`](https://sourceware.org/legacy-ml/libc-announce/2012/msg00000.html). - * `*-linux-musl*` targets ([at least since Rust 1.15](https://github.com/rust-lang/rust/blob/1.15.0/src/ci/docker/x86_64-musl/build-musl.sh#L15)) - use musl newer than [musl 1.1.0 that added `getauxval`](https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.0#n1197) - * `*-linux-ohos*` targets use a [fork of musl 1.2](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/native-lib/musl.md) - * `*-android*` targets ([since Rust 1.68](https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html)) - have the minimum supported API level higher than [Android 4.3 (API level 18) that added `getauxval`](https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/auxv.h#L49). - -* `std_detect_file_io` (enabled by default, requires `std`): Enable to perform run-time feature -detection using file APIs (e.g. `/proc/self/auxv`, etc.) if other more performant -methods fail. This feature requires `libstd` as a dependency, preventing the -crate from working on applications in which `std` is not available. - -[`getauxval`]: https://man7.org/linux/man-pages/man3/getauxval.3.html - # Platform support * All `x86`/`x86_64` targets are supported on all platforms by querying the diff --git a/library/std_detect/src/detect/mod.rs b/library/std_detect/src/detect/mod.rs index ae6fb2ab3727..c888dd34d9db 100644 --- a/library/std_detect/src/detect/mod.rs +++ b/library/std_detect/src/detect/mod.rs @@ -47,21 +47,21 @@ cfg_select! { #[path = "os/x86.rs"] mod os; } - all(any(target_os = "linux", target_os = "android"), feature = "libc") => { + any(target_os = "linux", target_os = "android") => { #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] #[path = "os/riscv.rs"] mod riscv; #[path = "os/linux/mod.rs"] mod os; } - all(target_os = "freebsd", feature = "libc") => { + target_os = "freebsd" => { #[cfg(target_arch = "aarch64")] #[path = "os/aarch64.rs"] mod aarch64; #[path = "os/freebsd/mod.rs"] mod os; } - all(target_os = "openbsd", feature = "libc") => { + target_os = "openbsd" => { #[allow(dead_code)] // we don't use code that calls the mrs instruction. #[cfg(target_arch = "aarch64")] #[path = "os/aarch64.rs"] @@ -73,7 +73,7 @@ cfg_select! { #[path = "os/windows/aarch64.rs"] mod os; } - all(target_vendor = "apple", target_arch = "aarch64", feature = "libc") => { + all(target_vendor = "apple", target_arch = "aarch64") => { #[path = "os/darwin/aarch64.rs"] mod os; } diff --git a/library/std_detect/src/detect/os/linux/aarch64/tests.rs b/library/std_detect/src/detect/os/linux/aarch64/tests.rs index a3562f2fd936..912d116d57b8 100644 --- a/library/std_detect/src/detect/os/linux/aarch64/tests.rs +++ b/library/std_detect/src/detect/os/linux/aarch64/tests.rs @@ -1,6 +1,5 @@ use super::*; -#[cfg(feature = "std_detect_file_io")] mod auxv_from_file { use super::auxvec::auxv_from_file; use super::*; diff --git a/library/std_detect/src/detect/os/linux/auxvec.rs b/library/std_detect/src/detect/os/linux/auxvec.rs index 75e01bdc4499..c0bbc7d4efa8 100644 --- a/library/std_detect/src/detect/os/linux/auxvec.rs +++ b/library/std_detect/src/detect/os/linux/auxvec.rs @@ -44,20 +44,16 @@ pub(crate) struct AuxVec { /// /// There is no perfect way of reading the auxiliary vector. /// -/// - If the `std_detect_dlsym_getauxval` cargo feature is enabled, this will use -/// `getauxval` if its linked to the binary, and otherwise proceed to a fallback implementation. -/// When `std_detect_dlsym_getauxval` is disabled, this will assume that `getauxval` is -/// linked to the binary - if that is not the case the behavior is undefined. -/// - Otherwise, if the `std_detect_file_io` cargo feature is enabled, it will +/// - If [`getauxval`] is linked to the binary we use it, and otherwise it will /// try to read `/proc/self/auxv`. /// - If that fails, this function returns an error. /// /// Note that run-time feature detection is not invoked for features that can /// be detected at compile-time. /// -/// Note: The `std_detect_dlsym_getauxval` cargo feature is ignored on -/// `*-linux-{gnu,musl,ohos}*` and `*-android*` targets because we can safely assume `getauxval` -/// is linked to the binary. +/// Note: We always directly use `getauxval` on `*-linux-{gnu,musl,ohos}*` and +/// `*-android*` targets rather than `dlsym` it because we can safely assume +/// `getauxval` is linked to the binary. /// - `*-linux-gnu*` targets ([since Rust 1.64](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html)) /// have glibc requirements higher than [glibc 2.16 that added `getauxval`](https://sourceware.org/legacy-ml/libc-announce/2012/msg00000.html). /// - `*-linux-musl*` targets ([at least since Rust 1.15](https://github.com/rust-lang/rust/blob/1.15.0/src/ci/docker/x86_64-musl/build-musl.sh#L15)) @@ -71,6 +67,7 @@ pub(crate) struct AuxVec { /// /// [auxvec_h]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/auxvec.h /// [auxv_docs]: https://docs.rs/auxv/0.3.3/auxv/ +/// [`getauxval`]: https://man7.org/linux/man-pages/man3/getauxval.3.html pub(crate) fn auxv() -> Result { // Try to call a getauxval function. if let Ok(hwcap) = getauxval(AT_HWCAP) { @@ -115,16 +112,9 @@ pub(crate) fn auxv() -> Result { let _ = hwcap; } - #[cfg(feature = "std_detect_file_io")] - { - // If calling getauxval fails, try to read the auxiliary vector from - // its file: - auxv_from_file("/proc/self/auxv").map_err(|_| ()) - } - #[cfg(not(feature = "std_detect_file_io"))] - { - Err(()) - } + // If calling getauxval fails, try to read the auxiliary vector from + // its file: + auxv_from_file("/proc/self/auxv").map_err(|_| ()) } /// Tries to read the `key` from the auxiliary vector by calling the @@ -132,14 +122,16 @@ pub(crate) fn auxv() -> Result { fn getauxval(key: usize) -> Result { type F = unsafe extern "C" fn(libc::c_ulong) -> libc::c_ulong; cfg_select! { - all( - feature = "std_detect_dlsym_getauxval", - not(all( + any( + all( target_os = "linux", any(target_env = "gnu", target_env = "musl", target_env = "ohos"), - )), - not(target_os = "android"), + ), + target_os = "android", ) => { + let ffi_getauxval: F = libc::getauxval; + } + _ => { let ffi_getauxval: F = unsafe { let ptr = libc::dlsym(libc::RTLD_DEFAULT, c"getauxval".as_ptr()); if ptr.is_null() { @@ -148,23 +140,18 @@ fn getauxval(key: usize) -> Result { core::mem::transmute(ptr) }; } - _ => { - let ffi_getauxval: F = libc::getauxval; - } } Ok(unsafe { ffi_getauxval(key as libc::c_ulong) as usize }) } /// Tries to read the auxiliary vector from the `file`. If this fails, this /// function returns `Err`. -#[cfg(feature = "std_detect_file_io")] pub(super) fn auxv_from_file(file: &str) -> Result { let file = super::read_file(file)?; auxv_from_file_bytes(&file) } /// Read auxiliary vector from a slice of bytes. -#[cfg(feature = "std_detect_file_io")] pub(super) fn auxv_from_file_bytes(bytes: &[u8]) -> Result { // See . // @@ -181,7 +168,6 @@ pub(super) fn auxv_from_file_bytes(bytes: &[u8]) -> Result Result { // Targets with only AT_HWCAP: #[cfg(any( diff --git a/library/std_detect/src/detect/os/linux/auxvec/tests.rs b/library/std_detect/src/detect/os/linux/auxvec/tests.rs index 631a3e5e9ef1..88f0d6d49337 100644 --- a/library/std_detect/src/detect/os/linux/auxvec/tests.rs +++ b/library/std_detect/src/detect/os/linux/auxvec/tests.rs @@ -41,7 +41,6 @@ fn auxv_dump() { } } -#[cfg(feature = "std_detect_file_io")] cfg_select! { target_arch = "arm" => { // The tests below can be executed under qemu, where we do not have access to the test @@ -86,7 +85,6 @@ cfg_select! { } #[test] -#[cfg(feature = "std_detect_file_io")] fn auxv_dump_procfs() { if let Ok(auxvec) = auxv_from_file("/proc/self/auxv") { println!("{:?}", auxvec); @@ -103,7 +101,6 @@ fn auxv_dump_procfs() { target_arch = "s390x", ))] #[test] -#[cfg(feature = "std_detect_file_io")] fn auxv_crate_procfs() { if let Ok(procfs_auxv) = auxv_from_file("/proc/self/auxv") { assert_eq!(auxv().unwrap(), procfs_auxv); diff --git a/library/std_detect/src/detect/os/linux/mod.rs b/library/std_detect/src/detect/os/linux/mod.rs index 5273c16c0893..aec94f963f5c 100644 --- a/library/std_detect/src/detect/os/linux/mod.rs +++ b/library/std_detect/src/detect/os/linux/mod.rs @@ -1,11 +1,9 @@ //! Run-time feature detection on Linux -//! -#[cfg(feature = "std_detect_file_io")] + use alloc::vec::Vec; mod auxvec; -#[cfg(feature = "std_detect_file_io")] fn read_file(orig_path: &str) -> Result, alloc::string::String> { use alloc::format; diff --git a/library/std_detect/src/lib.rs b/library/std_detect/src/lib.rs index 73e2f5dd9644..5e1d21bbfd17 100644 --- a/library/std_detect/src/lib.rs +++ b/library/std_detect/src/lib.rs @@ -27,8 +27,7 @@ extern crate std; // rust-lang/rust#83888: removing `extern crate` gives an error that `vec_spare> -#[cfg_attr(feature = "std_detect_file_io", allow(unused_extern_crates))] -#[cfg(feature = "std_detect_file_io")] +#[allow(unused_extern_crates)] extern crate alloc; #[doc(hidden)] diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index eec8c461b6db..a18868082916 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -20,7 +20,7 @@ test = { path = "../test", public = true } # Forward features to the `std` crate as necessary [features] -default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"] +default = ["panic-unwind"] backtrace = ["std/backtrace"] backtrace-trace-only = ["std/backtrace-trace-only"] compiler-builtins-c = ["std/compiler-builtins-c"] @@ -32,7 +32,5 @@ system-llvm-libunwind = ["std/system-llvm-libunwind"] optimize_for_size = ["std/optimize_for_size"] panic-unwind = ["std/panic-unwind"] profiler = ["dep:profiler_builtins"] -std_detect_file_io = ["std/std_detect_file_io"] -std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"] windows_raw_dylib = ["std/windows_raw_dylib"] llvm_enzyme = ["std/llvm_enzyme"] From 3fed6e67ef0af1da28254cfc4d8078f0ba222c24 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 8 Jan 2026 12:14:18 +0000 Subject: [PATCH 1771/3801] Remove a couple of outdated fields in std_detect Cargo.toml It is no longer a part of the stdarch repo and the rest is not necessary anymore due to no longer publishing to crates.io. --- library/std_detect/Cargo.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/library/std_detect/Cargo.toml b/library/std_detect/Cargo.toml index bcfdb3901957..a6785bb20555 100644 --- a/library/std_detect/Cargo.toml +++ b/library/std_detect/Cargo.toml @@ -7,11 +7,6 @@ authors = [ "Gonzalo Brito Gadeschi ", ] description = "`std::detect` - Rust's standard library run-time CPU feature detection." -homepage = "https://github.com/rust-lang/stdarch" -repository = "https://github.com/rust-lang/stdarch" -readme = "README.md" -keywords = ["std", "run-time", "feature", "detection"] -categories = ["hardware-support"] license = "MIT OR Apache-2.0" edition = "2024" From c873d163239a000bb0d3c29a15a24a98f6f6adf3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 8 Jan 2026 15:02:42 +0000 Subject: [PATCH 1772/3801] Remove unnecessary module --- .../src/detect/os/linux/aarch64/tests.rs | 140 +++++++++--------- 1 file changed, 67 insertions(+), 73 deletions(-) diff --git a/library/std_detect/src/detect/os/linux/aarch64/tests.rs b/library/std_detect/src/detect/os/linux/aarch64/tests.rs index 912d116d57b8..4d7c9a419d38 100644 --- a/library/std_detect/src/detect/os/linux/aarch64/tests.rs +++ b/library/std_detect/src/detect/os/linux/aarch64/tests.rs @@ -1,76 +1,70 @@ +use super::auxvec::auxv_from_file; use super::*; - -mod auxv_from_file { - use super::auxvec::auxv_from_file; - use super::*; - // The baseline hwcaps used in the (artificial) auxv test files. - fn baseline_hwcaps() -> AtHwcap { - AtHwcap { - fp: true, - asimd: true, - aes: true, - pmull: true, - sha1: true, - sha2: true, - crc32: true, - atomics: true, - fphp: true, - asimdhp: true, - asimdrdm: true, - lrcpc: true, - dcpop: true, - asimddp: true, - ssbs: true, - ..AtHwcap::default() - } - } - - #[test] - fn linux_empty_hwcap2_aarch64() { - let file = concat!( - env!("CARGO_MANIFEST_DIR"), - "/src/detect/test_data/linux-empty-hwcap2-aarch64.auxv" - ); - println!("file: {file}"); - let v = auxv_from_file(file).unwrap(); - println!("HWCAP : 0x{:0x}", v.hwcap); - println!("HWCAP2: 0x{:0x}", v.hwcap2); - assert_eq!(AtHwcap::from(v), baseline_hwcaps()); - } - #[test] - fn linux_no_hwcap2_aarch64() { - let file = concat!( - env!("CARGO_MANIFEST_DIR"), - "/src/detect/test_data/linux-no-hwcap2-aarch64.auxv" - ); - println!("file: {file}"); - let v = auxv_from_file(file).unwrap(); - println!("HWCAP : 0x{:0x}", v.hwcap); - println!("HWCAP2: 0x{:0x}", v.hwcap2); - assert_eq!(AtHwcap::from(v), baseline_hwcaps()); - } - #[test] - fn linux_hwcap2_aarch64() { - let file = - concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-hwcap2-aarch64.auxv"); - println!("file: {file}"); - let v = auxv_from_file(file).unwrap(); - println!("HWCAP : 0x{:0x}", v.hwcap); - println!("HWCAP2: 0x{:0x}", v.hwcap2); - assert_eq!( - AtHwcap::from(v), - AtHwcap { - // Some other HWCAP bits. - paca: true, - pacg: true, - // HWCAP2-only bits. - dcpodp: true, - frint: true, - rng: true, - bti: true, - mte: true, - ..baseline_hwcaps() - } - ); +// The baseline hwcaps used in the (artificial) auxv test files. +fn baseline_hwcaps() -> AtHwcap { + AtHwcap { + fp: true, + asimd: true, + aes: true, + pmull: true, + sha1: true, + sha2: true, + crc32: true, + atomics: true, + fphp: true, + asimdhp: true, + asimdrdm: true, + lrcpc: true, + dcpop: true, + asimddp: true, + ssbs: true, + ..AtHwcap::default() } } + +#[test] +fn linux_empty_hwcap2_aarch64() { + let file = concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/detect/test_data/linux-empty-hwcap2-aarch64.auxv" + ); + println!("file: {file}"); + let v = auxv_from_file(file).unwrap(); + println!("HWCAP : 0x{:0x}", v.hwcap); + println!("HWCAP2: 0x{:0x}", v.hwcap2); + assert_eq!(AtHwcap::from(v), baseline_hwcaps()); +} +#[test] +fn linux_no_hwcap2_aarch64() { + let file = + concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-no-hwcap2-aarch64.auxv"); + println!("file: {file}"); + let v = auxv_from_file(file).unwrap(); + println!("HWCAP : 0x{:0x}", v.hwcap); + println!("HWCAP2: 0x{:0x}", v.hwcap2); + assert_eq!(AtHwcap::from(v), baseline_hwcaps()); +} +#[test] +fn linux_hwcap2_aarch64() { + let file = + concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-hwcap2-aarch64.auxv"); + println!("file: {file}"); + let v = auxv_from_file(file).unwrap(); + println!("HWCAP : 0x{:0x}", v.hwcap); + println!("HWCAP2: 0x{:0x}", v.hwcap2); + assert_eq!( + AtHwcap::from(v), + AtHwcap { + // Some other HWCAP bits. + paca: true, + pacg: true, + // HWCAP2-only bits. + dcpodp: true, + frint: true, + rng: true, + bti: true, + mte: true, + ..baseline_hwcaps() + } + ); +} From 6b88c6b7c2a8322de6ff2211bd3f683e4fb1edbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 8 Jan 2026 16:25:03 +0100 Subject: [PATCH 1773/3801] store defids instead of symbol names in the aliases list --- compiler/rustc_codegen_llvm/src/mono_item.rs | 7 ++++--- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 8 +++----- compiler/rustc_middle/src/middle/codegen_fn_attrs.rs | 3 ++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 41cf92390b0d..3ce28612ddfc 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -10,7 +10,6 @@ use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use rustc_session::config::CrateType; -use rustc_span::Symbol; use rustc_target::spec::{Arch, RelocModel}; use tracing::debug; @@ -92,17 +91,19 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { } impl CodegenCx<'_, '_> { - fn add_aliases(&self, aliasee: &llvm::Value, aliases: &[(Symbol, Linkage, Visibility)]) { + fn add_aliases(&self, aliasee: &llvm::Value, aliases: &[(DefId, Linkage, Visibility)]) { let ty = self.get_type_of_global(aliasee); for (alias, linkage, visibility) in aliases { + let symbol_name = self.tcx.symbol_name(Instance::mono(self.tcx, *alias)); + tracing::debug!("ALIAS: {alias:?} {linkage:?} {visibility:?}"); let lldecl = llvm::add_alias( self.llmod, ty, AddressSpace::ZERO, aliasee, - &CString::new(alias.as_str()).unwrap(), + &CString::new(symbol_name.name).unwrap(), ); llvm::set_visibility(lldecl, base::visibility_to_llvm(*visibility)); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 94dc3f44a68b..74f4662118b6 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -13,10 +13,10 @@ use rustc_middle::middle::codegen_fn_attrs::{ use rustc_middle::mir::mono::Visibility; use rustc_middle::query::Providers; use rustc_middle::span_bug; -use rustc_middle::ty::{self as ty, Instance, TyCtxt}; +use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; -use rustc_span::{Span, Symbol, sym}; +use rustc_span::{Span, sym}; use rustc_target::spec::Os; use crate::errors; @@ -291,8 +291,6 @@ fn process_builtin_attrs( ) .expect("eii should have declaration macro with extern target attribute"); - let symbol_name = tcx.symbol_name(Instance::mono(tcx, extern_item)); - // this is to prevent a bug where a single crate defines both the default and explicit implementation // for an EII. In that case, both of them may be part of the same final object file. I'm not 100% sure // what happens, either rustc deduplicates the symbol or llvm, or it's random/order-dependent. @@ -310,7 +308,7 @@ fn process_builtin_attrs( } codegen_fn_attrs.foreign_item_symbol_aliases.push(( - Symbol::intern(symbol_name.name), + extern_item, if i.is_default { Linkage::LinkOnceAny } else { Linkage::External }, Visibility::Default, )); diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 9033d9c46d54..4f600af0cbfc 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use rustc_abi::Align; use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, Linkage, OptimizeAttr, RtsanSetting}; +use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; @@ -72,7 +73,7 @@ pub struct CodegenFnAttrs { /// generate this function under its real name, /// but *also* under the same name as this foreign function so that the foreign function has an implementation. // FIXME: make "SymbolName<'tcx>" - pub foreign_item_symbol_aliases: Vec<(Symbol, Linkage, Visibility)>, + pub foreign_item_symbol_aliases: Vec<(DefId, Linkage, Visibility)>, /// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an /// imported function has in the dynamic library. Note that this must not /// be set when `link_name` is set. This is for foreign items with the From 9f3956f37863800fa6dd325607adf8e43bd66196 Mon Sep 17 00:00:00 2001 From: human9000 Date: Mon, 5 Jan 2026 18:14:12 +0500 Subject: [PATCH 1774/3801] MGCA: literals support --- compiler/rustc_ast_lowering/src/lib.rs | 10 ++++++++++ compiler/rustc_hir/src/hir.rs | 1 + compiler/rustc_hir/src/intravisit.rs | 1 + .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 15 +++++++++++++++ compiler/rustc_hir_pretty/src/lib.rs | 6 +++++- compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + src/librustdoc/clean/mod.rs | 6 +++++- src/tools/clippy/clippy_lints/src/utils/author.rs | 1 + src/tools/clippy/clippy_utils/src/consts.rs | 2 +- src/tools/clippy/clippy_utils/src/hir_utils.rs | 5 +++++ .../mgca/explicit_anon_consts_literals_hack.rs | 8 ++------ .../explicit_anon_consts_literals_hack.stderr | 8 -------- 12 files changed, 47 insertions(+), 17 deletions(-) delete mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a81d2297ef85..fd7c3360b05e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2536,6 +2536,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { overly_complex_const(self) } + ExprKind::Lit(literal) => { + let span = expr.span; + let literal = self.lower_lit(literal, span); + + ConstArg { + hir_id: self.lower_node_id(expr.id), + kind: hir::ConstArgKind::Literal(literal.node), + span, + } + } _ => overly_complex_const(self), } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index aacd6324bb03..666987860d50 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -518,6 +518,7 @@ pub enum ConstArgKind<'hir, Unambig = ()> { /// This variant is not always used to represent inference consts, sometimes /// [`GenericArg::Infer`] is used instead. Infer(Unambig), + Literal(LitKind), } #[derive(Clone, Copy, Debug, HashStable_Generic)] diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 59db60fdc55c..e5e6fc7b1d8d 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1104,6 +1104,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important + ConstArgKind::Literal(..) => V::Result::output(), // FIXME(mcga) } } 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 aaa566760013..1dd9bff42575 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -22,6 +22,7 @@ pub mod generics; use std::assert_matches::assert_matches; use std::slice; +use rustc_ast::LitKind; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{ @@ -2391,6 +2392,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span), hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e), + hir::ConstArgKind::Literal(kind) if let FeedConstTy::WithTy(anon_const_type) = feed => { + self.lower_const_arg_literal(&kind, anon_const_type, const_arg.span) + } + hir::ConstArgKind::Literal(..) => { + let e = self.dcx().span_err(const_arg.span, "literal of unknown type"); + ty::Const::new_error(tcx, e) + } } } @@ -2773,6 +2781,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + #[instrument(skip(self), level = "debug")] + fn lower_const_arg_literal(&self, kind: &LitKind, ty: Ty<'tcx>, span: Span) -> Const<'tcx> { + let tcx = self.tcx(); + let input = LitToConstInput { lit: *kind, ty, neg: false }; + tcx.at(span).lit_to_const(input) + } + #[instrument(skip(self), level = "debug")] fn try_lower_anon_const_lit( &self, diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2c160ccef2b6..37fa18c00887 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -21,7 +21,7 @@ use rustc_hir::{ GenericParam, GenericParamKind, HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, TyPatKind, }; -use rustc_span::source_map::SourceMap; +use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym}; use {rustc_ast as ast, rustc_hir as hir}; @@ -1157,6 +1157,10 @@ impl<'a> State<'a> { ConstArgKind::Anon(anon) => self.print_anon_const(anon), ConstArgKind::Error(_) => self.word("/*ERROR*/"), ConstArgKind::Infer(..) => self.word("_"), + ConstArgKind::Literal(node) => { + let span = const_arg.span; + self.print_literal(&Spanned { span, node: *node }) + } } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d0e8bc50c495..c85327dc3db1 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1444,6 +1444,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { | hir::ConstArgKind::TupleCall(..) | hir::ConstArgKind::Tup(..) | hir::ConstArgKind::Path(..) + | hir::ConstArgKind::Literal(..) | hir::ConstArgKind::Infer(..) => true, hir::ConstArgKind::Anon(..) => false, }, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e05d3e416430..817eda4c52ec 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -332,6 +332,9 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind } hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer, + hir::ConstArgKind::Literal(..) => { + ConstantKind::Path { path: "/* LITERAL */".to_string().into() } + } } } @@ -1814,7 +1817,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T hir::ConstArgKind::Struct(..) | hir::ConstArgKind::Path(..) | hir::ConstArgKind::TupleCall(..) - | hir::ConstArgKind::Tup(..) => { + | hir::ConstArgKind::Tup(..) + | hir::ConstArgKind::Literal(..) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); print_const(cx, ct) } diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 455f76edc904..7a54ba7a8fe1 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -324,6 +324,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), + ConstArgKind::Literal(..) => chain!(self, "let ConstArgKind::Literal(..) = {const_arg}.kind") } } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 46b87fd5df96..5f4b87590dc1 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1140,7 +1140,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { + ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) | ConstArgKind::Literal(..) => { None }, }, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 57c896c97172..b4e483ea8072 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -689,6 +689,9 @@ impl HirEqInterExpr<'_, '_, '_> { .zip(*args_b) .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) } + (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => { + kind_l == kind_r + }, // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) @@ -697,6 +700,7 @@ impl HirEqInterExpr<'_, '_, '_> { | ConstArgKind::Tup(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) + | ConstArgKind::Literal(..) | ConstArgKind::Error(..), _, ) => false, @@ -1577,6 +1581,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, + ConstArgKind::Literal(lit) => lit.hash(&mut self.s) } } diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs index eb8f04b8b24b..8131a5b72343 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs @@ -1,8 +1,4 @@ -// We allow for literals to implicitly be anon consts still regardless -// of whether a const block is placed around them or not -// -// However, we don't allow so for const arguments in field init positions. -// This is just harder to implement so we did not do so. +//@ check-pass #![feature(min_generic_const_args, adt_const_params)] #![expect(incomplete_features)] @@ -27,7 +23,7 @@ fn struct_expr() { fn takes_n() {} takes_n::<{ ADT { field: 1 } }>(); - //~^ ERROR: complex const arguments must be placed inside of a `const` block + takes_n::<{ ADT { field: const { 1 } } }>(); } diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.stderr deleted file mode 100644 index 02647fd808cc..000000000000 --- a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts_literals_hack.rs:29:30 - | -LL | takes_n::<{ ADT { field: 1 } }>(); - | ^ - -error: aborting due to 1 previous error - From fb5c85071b47a7d1c1c5db9381c0e8722507d350 Mon Sep 17 00:00:00 2001 From: human9000 Date: Mon, 5 Jan 2026 18:14:12 +0500 Subject: [PATCH 1775/3801] MGCA: literals support --- clippy_lints/src/utils/author.rs | 1 + clippy_utils/src/consts.rs | 2 +- clippy_utils/src/hir_utils.rs | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 455f76edc904..7a54ba7a8fe1 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -324,6 +324,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), + ConstArgKind::Literal(..) => chain!(self, "let ConstArgKind::Literal(..) = {const_arg}.kind") } } diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 46b87fd5df96..5f4b87590dc1 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1140,7 +1140,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { + ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) | ConstArgKind::Literal(..) => { None }, }, diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 57c896c97172..b4e483ea8072 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -689,6 +689,9 @@ impl HirEqInterExpr<'_, '_, '_> { .zip(*args_b) .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) } + (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => { + kind_l == kind_r + }, // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) @@ -697,6 +700,7 @@ impl HirEqInterExpr<'_, '_, '_> { | ConstArgKind::Tup(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) + | ConstArgKind::Literal(..) | ConstArgKind::Error(..), _, ) => false, @@ -1577,6 +1581,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, + ConstArgKind::Literal(lit) => lit.hash(&mut self.s) } } From 331f75f4a773fadba135664190905457946ea98e Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 8 Jan 2026 16:37:55 +0100 Subject: [PATCH 1776/3801] Do not warn on arithmetic side effect for `String`+`String` The previous fix only handled `String`+`str`. --- .../src/operators/arithmetic_side_effects.rs | 5 +- tests/ui/arithmetic_side_effects.rs | 1 - tests/ui/arithmetic_side_effects.stderr | 266 +++++++++--------- 3 files changed, 134 insertions(+), 138 deletions(-) diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs index 91a069559f7b..106286d16d18 100644 --- a/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -33,7 +33,10 @@ impl ArithmeticSideEffects { allowed_binary.extend([ ("f32", FxHashSet::from_iter(["f32"])), ("f64", FxHashSet::from_iter(["f64"])), - ("std::string::String", FxHashSet::from_iter(["str"])), + ( + "std::string::String", + FxHashSet::from_iter(["str", "std::string::String"]), + ), ]); for (lhs, rhs) in &conf.arithmetic_side_effects_allowed_binary { allowed_binary.entry(lhs).or_default().insert(rhs); diff --git a/tests/ui/arithmetic_side_effects.rs b/tests/ui/arithmetic_side_effects.rs index b7ed596d811e..87397a549bf4 100644 --- a/tests/ui/arithmetic_side_effects.rs +++ b/tests/ui/arithmetic_side_effects.rs @@ -174,7 +174,6 @@ pub fn hard_coded_allowed() { let _ = Saturating(0u32) + Saturating(0u32); let _ = String::new() + ""; let _ = String::new() + &String::new(); - //~^ arithmetic_side_effects let _ = Wrapping(0u32) + Wrapping(0u32); let saturating: Saturating = Saturating(0u32); diff --git a/tests/ui/arithmetic_side_effects.stderr b/tests/ui/arithmetic_side_effects.stderr index 22742a82601a..2767a051786e 100644 --- a/tests/ui/arithmetic_side_effects.stderr +++ b/tests/ui/arithmetic_side_effects.stderr @@ -14,784 +14,778 @@ LL | let _ = 1f128 + 1f128; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:176:13 - | -LL | let _ = String::new() + &String::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:312:5 + --> tests/ui/arithmetic_side_effects.rs:311:5 | LL | _n += 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:314:5 + --> tests/ui/arithmetic_side_effects.rs:313:5 | LL | _n += &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:316:5 + --> tests/ui/arithmetic_side_effects.rs:315:5 | LL | _n -= 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:318:5 + --> tests/ui/arithmetic_side_effects.rs:317:5 | LL | _n -= &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:320:5 + --> tests/ui/arithmetic_side_effects.rs:319:5 | LL | _n /= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:322:5 + --> tests/ui/arithmetic_side_effects.rs:321:5 | LL | _n /= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:324:5 + --> tests/ui/arithmetic_side_effects.rs:323:5 | LL | _n %= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:326:5 + --> tests/ui/arithmetic_side_effects.rs:325:5 | LL | _n %= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:328:5 + --> tests/ui/arithmetic_side_effects.rs:327:5 | LL | _n *= 2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:330:5 + --> tests/ui/arithmetic_side_effects.rs:329:5 | LL | _n *= &2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:332:5 + --> tests/ui/arithmetic_side_effects.rs:331:5 | LL | _n += -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:334:5 + --> tests/ui/arithmetic_side_effects.rs:333:5 | LL | _n += &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:336:5 + --> tests/ui/arithmetic_side_effects.rs:335:5 | LL | _n -= -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:338:5 + --> tests/ui/arithmetic_side_effects.rs:337:5 | LL | _n -= &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:340:5 + --> tests/ui/arithmetic_side_effects.rs:339:5 | LL | _n /= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:342:5 + --> tests/ui/arithmetic_side_effects.rs:341:5 | LL | _n /= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:344:5 + --> tests/ui/arithmetic_side_effects.rs:343:5 | LL | _n %= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:346:5 + --> tests/ui/arithmetic_side_effects.rs:345:5 | LL | _n %= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:348:5 + --> tests/ui/arithmetic_side_effects.rs:347:5 | LL | _n *= -2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:350:5 + --> tests/ui/arithmetic_side_effects.rs:349:5 | LL | _n *= &-2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:352:5 + --> tests/ui/arithmetic_side_effects.rs:351:5 | LL | _custom += Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:354:5 + --> tests/ui/arithmetic_side_effects.rs:353:5 | LL | _custom += &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:356:5 + --> tests/ui/arithmetic_side_effects.rs:355:5 | LL | _custom -= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:358:5 + --> tests/ui/arithmetic_side_effects.rs:357:5 | LL | _custom -= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:360:5 + --> tests/ui/arithmetic_side_effects.rs:359:5 | LL | _custom /= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:362:5 + --> tests/ui/arithmetic_side_effects.rs:361:5 | LL | _custom /= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:364:5 + --> tests/ui/arithmetic_side_effects.rs:363:5 | LL | _custom %= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:366:5 + --> tests/ui/arithmetic_side_effects.rs:365:5 | LL | _custom %= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:368:5 + --> tests/ui/arithmetic_side_effects.rs:367:5 | LL | _custom *= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:370:5 + --> tests/ui/arithmetic_side_effects.rs:369:5 | LL | _custom *= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:372:5 + --> tests/ui/arithmetic_side_effects.rs:371:5 | LL | _custom >>= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:374:5 + --> tests/ui/arithmetic_side_effects.rs:373:5 | LL | _custom >>= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:376:5 + --> tests/ui/arithmetic_side_effects.rs:375:5 | LL | _custom <<= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:378:5 + --> tests/ui/arithmetic_side_effects.rs:377:5 | LL | _custom <<= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:380:5 + --> tests/ui/arithmetic_side_effects.rs:379:5 | LL | _custom += -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:382:5 + --> tests/ui/arithmetic_side_effects.rs:381:5 | LL | _custom += &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:384:5 + --> tests/ui/arithmetic_side_effects.rs:383:5 | LL | _custom -= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:386:5 + --> tests/ui/arithmetic_side_effects.rs:385:5 | LL | _custom -= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:388:5 + --> tests/ui/arithmetic_side_effects.rs:387:5 | LL | _custom /= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:390:5 + --> tests/ui/arithmetic_side_effects.rs:389:5 | LL | _custom /= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:392:5 + --> tests/ui/arithmetic_side_effects.rs:391:5 | LL | _custom %= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:394:5 + --> tests/ui/arithmetic_side_effects.rs:393:5 | LL | _custom %= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:396:5 + --> tests/ui/arithmetic_side_effects.rs:395:5 | LL | _custom *= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:398:5 + --> tests/ui/arithmetic_side_effects.rs:397:5 | LL | _custom *= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:400:5 + --> tests/ui/arithmetic_side_effects.rs:399:5 | LL | _custom >>= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:402:5 + --> tests/ui/arithmetic_side_effects.rs:401:5 | LL | _custom >>= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:404:5 + --> tests/ui/arithmetic_side_effects.rs:403:5 | LL | _custom <<= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:406:5 + --> tests/ui/arithmetic_side_effects.rs:405:5 | LL | _custom <<= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:410:10 + --> tests/ui/arithmetic_side_effects.rs:409:10 | LL | _n = _n + 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:412:10 + --> tests/ui/arithmetic_side_effects.rs:411:10 | LL | _n = _n + &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:414:10 + --> tests/ui/arithmetic_side_effects.rs:413:10 | LL | _n = 1 + _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:416:10 + --> tests/ui/arithmetic_side_effects.rs:415:10 | LL | _n = &1 + _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:418:10 + --> tests/ui/arithmetic_side_effects.rs:417:10 | LL | _n = _n - 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:420:10 + --> tests/ui/arithmetic_side_effects.rs:419:10 | LL | _n = _n - &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:422:10 + --> tests/ui/arithmetic_side_effects.rs:421:10 | LL | _n = 1 - _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:424:10 + --> tests/ui/arithmetic_side_effects.rs:423:10 | LL | _n = &1 - _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:426:10 + --> tests/ui/arithmetic_side_effects.rs:425:10 | LL | _n = _n / 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:428:10 + --> tests/ui/arithmetic_side_effects.rs:427:10 | LL | _n = _n / &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:430:10 + --> tests/ui/arithmetic_side_effects.rs:429:10 | LL | _n = _n % 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:432:10 + --> tests/ui/arithmetic_side_effects.rs:431:10 | LL | _n = _n % &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:434:10 + --> tests/ui/arithmetic_side_effects.rs:433:10 | LL | _n = _n * 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:436:10 + --> tests/ui/arithmetic_side_effects.rs:435:10 | LL | _n = _n * &2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:438:10 + --> tests/ui/arithmetic_side_effects.rs:437:10 | LL | _n = 2 * _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:440:10 + --> tests/ui/arithmetic_side_effects.rs:439:10 | LL | _n = &2 * _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:442:10 + --> tests/ui/arithmetic_side_effects.rs:441:10 | LL | _n = 23 + &85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:444:10 + --> tests/ui/arithmetic_side_effects.rs:443:10 | LL | _n = &23 + 85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:446:10 + --> tests/ui/arithmetic_side_effects.rs:445:10 | LL | _n = &23 + &85; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:448:15 + --> tests/ui/arithmetic_side_effects.rs:447:15 | LL | _custom = _custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:450:15 + --> tests/ui/arithmetic_side_effects.rs:449:15 | LL | _custom = _custom + &_custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:452:15 + --> tests/ui/arithmetic_side_effects.rs:451:15 | LL | _custom = Custom + _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:454:15 + --> tests/ui/arithmetic_side_effects.rs:453:15 | LL | _custom = &Custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:456:15 + --> tests/ui/arithmetic_side_effects.rs:455:15 | LL | _custom = _custom - Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:458:15 + --> tests/ui/arithmetic_side_effects.rs:457:15 | LL | _custom = _custom - &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:460:15 + --> tests/ui/arithmetic_side_effects.rs:459:15 | LL | _custom = Custom - _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:462:15 + --> tests/ui/arithmetic_side_effects.rs:461:15 | LL | _custom = &Custom - _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:464:15 + --> tests/ui/arithmetic_side_effects.rs:463:15 | LL | _custom = _custom / Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:466:15 + --> tests/ui/arithmetic_side_effects.rs:465:15 | LL | _custom = _custom / &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:468:15 + --> tests/ui/arithmetic_side_effects.rs:467:15 | LL | _custom = _custom % Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:470:15 + --> tests/ui/arithmetic_side_effects.rs:469:15 | LL | _custom = _custom % &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:472:15 + --> tests/ui/arithmetic_side_effects.rs:471:15 | LL | _custom = _custom * Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:474:15 + --> tests/ui/arithmetic_side_effects.rs:473:15 | LL | _custom = _custom * &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:476:15 + --> tests/ui/arithmetic_side_effects.rs:475:15 | LL | _custom = Custom * _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:478:15 + --> tests/ui/arithmetic_side_effects.rs:477:15 | LL | _custom = &Custom * _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:480:15 + --> tests/ui/arithmetic_side_effects.rs:479:15 | LL | _custom = Custom + &Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:482:15 + --> tests/ui/arithmetic_side_effects.rs:481:15 | LL | _custom = &Custom + Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:484:15 + --> tests/ui/arithmetic_side_effects.rs:483:15 | LL | _custom = &Custom + &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:486:15 + --> tests/ui/arithmetic_side_effects.rs:485:15 | LL | _custom = _custom >> _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:488:15 + --> tests/ui/arithmetic_side_effects.rs:487:15 | LL | _custom = _custom >> &_custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:490:15 + --> tests/ui/arithmetic_side_effects.rs:489:15 | LL | _custom = Custom << _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:492:15 + --> tests/ui/arithmetic_side_effects.rs:491:15 | LL | _custom = &Custom << _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:496:23 + --> tests/ui/arithmetic_side_effects.rs:495:23 | LL | _n.saturating_div(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:498:21 + --> tests/ui/arithmetic_side_effects.rs:497:21 | LL | _n.wrapping_div(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:500:21 + --> tests/ui/arithmetic_side_effects.rs:499:21 | LL | _n.wrapping_rem(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:502:28 + --> tests/ui/arithmetic_side_effects.rs:501:28 | LL | _n.wrapping_rem_euclid(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:505:23 + --> tests/ui/arithmetic_side_effects.rs:504:23 | LL | _n.saturating_div(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:507:21 + --> tests/ui/arithmetic_side_effects.rs:506:21 | LL | _n.wrapping_div(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:509:21 + --> tests/ui/arithmetic_side_effects.rs:508:21 | LL | _n.wrapping_rem(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:511:28 + --> tests/ui/arithmetic_side_effects.rs:510:28 | LL | _n.wrapping_rem_euclid(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:514:23 + --> tests/ui/arithmetic_side_effects.rs:513:23 | LL | _n.saturating_div(*Box::new(_n)); | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:518:10 + --> tests/ui/arithmetic_side_effects.rs:517:10 | LL | _n = -_n; | ^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:520:10 + --> tests/ui/arithmetic_side_effects.rs:519:10 | LL | _n = -&_n; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:522:15 + --> tests/ui/arithmetic_side_effects.rs:521:15 | LL | _custom = -_custom; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:524:15 + --> tests/ui/arithmetic_side_effects.rs:523:15 | LL | _custom = -&_custom; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:526:9 + --> tests/ui/arithmetic_side_effects.rs:525:9 | LL | _ = -*Box::new(_n); | ^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:536:5 + --> tests/ui/arithmetic_side_effects.rs:535:5 | LL | 1 + i; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:538:5 + --> tests/ui/arithmetic_side_effects.rs:537:5 | LL | i * 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:540:5 + --> tests/ui/arithmetic_side_effects.rs:539:5 | LL | 1 % i / 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:542:5 + --> tests/ui/arithmetic_side_effects.rs:541:5 | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:544:5 + --> tests/ui/arithmetic_side_effects.rs:543:5 | LL | -i; | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:556:5 + --> tests/ui/arithmetic_side_effects.rs:555:5 | LL | i += 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:558:5 + --> tests/ui/arithmetic_side_effects.rs:557:5 | LL | i -= 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:560:5 + --> tests/ui/arithmetic_side_effects.rs:559:5 | LL | i *= 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:563:5 + --> tests/ui/arithmetic_side_effects.rs:562:5 | LL | i /= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:566:5 + --> tests/ui/arithmetic_side_effects.rs:565:5 | LL | i /= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:568:5 + --> tests/ui/arithmetic_side_effects.rs:567:5 | LL | i /= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:571:5 + --> tests/ui/arithmetic_side_effects.rs:570:5 | LL | i %= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:574:5 + --> tests/ui/arithmetic_side_effects.rs:573:5 | LL | i %= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:576:5 + --> tests/ui/arithmetic_side_effects.rs:575:5 | LL | i %= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:587:5 + --> tests/ui/arithmetic_side_effects.rs:586:5 | LL | 10 / a | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:642:9 + --> tests/ui/arithmetic_side_effects.rs:641:9 | LL | x / maybe_zero | ^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:647:9 + --> tests/ui/arithmetic_side_effects.rs:646:9 | LL | x % maybe_zero | ^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:659:5 + --> tests/ui/arithmetic_side_effects.rs:658:5 | LL | one.add_assign(1); | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:664:5 + --> tests/ui/arithmetic_side_effects.rs:663:5 | LL | one.sub_assign(1); | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:685:5 + --> tests/ui/arithmetic_side_effects.rs:684:5 | LL | one.add(&one); | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:687:5 + --> tests/ui/arithmetic_side_effects.rs:686:5 | LL | Box::new(one).add(one); | ^^^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:696:13 + --> tests/ui/arithmetic_side_effects.rs:695:13 | LL | let _ = u128::MAX + u128::from(1u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:713:13 + --> tests/ui/arithmetic_side_effects.rs:712:13 | LL | let _ = u128::MAX * u128::from(1u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:736:33 + --> tests/ui/arithmetic_side_effects.rs:735:33 | LL | let _ = Duration::from_secs(86400 * Foo::from(1)); | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:742:33 + --> tests/ui/arithmetic_side_effects.rs:741:33 | LL | let _ = Duration::from_secs(86400 * shift(1)); | ^^^^^^^^^^^^^^^^ -error: aborting due to 132 previous errors +error: aborting due to 131 previous errors From 20a94d65e5e6ea1c187fe14e5ae79a7078dcd206 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 8 Jan 2026 23:55:57 +0800 Subject: [PATCH 1777/3801] Bump `diesel` to the most recent commit in `cargotest` `cargotest` can only detect the worst offenders (like tests failing, or hard compiler errors / ICEs), but regardless, bumping `diesel` to a way more recent version hopefully contributes slightly towards helping us not break `diesel` if at all possible. --- src/tools/cargotest/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 4c57683806e6..5bbed35e2068 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -84,7 +84,7 @@ const TEST_REPOS: &[Test] = &[ Test { name: "diesel", repo: "https://github.com/diesel-rs/diesel", - sha: "91493fe47175076f330ce5fc518f0196c0476f56", + sha: "3db7c17c5b069656ed22750e84d6498c8ab5b81d", lock: None, packages: &[], // Test the embedded sqlite variant of diesel From 80dedb601aababe989be488a18f14a4d3c4b7234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 31 Dec 2025 14:11:32 +0100 Subject: [PATCH 1778/3801] Add a dist step for GCC --- src/bootstrap/src/core/build_steps/compile.rs | 29 ++++--- src/bootstrap/src/core/build_steps/dist.rs | 84 ++++++++++++++++++- src/bootstrap/src/core/builder/mod.rs | 3 +- src/bootstrap/src/utils/tarball.rs | 10 +++ 4 files changed, 114 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 02be3f2cc735..79a564cfb1ff 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1612,26 +1612,35 @@ impl GccDylibSet { "Trying to install libgccjit ({target_pair}) to a compiler with a different host ({})", compiler.host ); - let libgccjit = libgccjit.libgccjit(); - let target_filename = libgccjit.file_name().unwrap().to_str().unwrap(); + let libgccjit_path = libgccjit.libgccjit(); // If we build libgccjit ourselves, then `libgccjit` can actually be a symlink. // In that case, we have to resolve it first, otherwise we'd create a symlink to a // symlink, which wouldn't work. - let actual_libgccjit_path = t!( - libgccjit.canonicalize(), - format!("Cannot find libgccjit at {}", libgccjit.display()) + let libgccjit_path = t!( + libgccjit_path.canonicalize(), + format!("Cannot find libgccjit at {}", libgccjit_path.display()) ); - // /lib//libgccjit.so - let dest_dir = cg_sysroot.join("lib").join(target_pair.target()); - t!(fs::create_dir_all(&dest_dir)); - let dst = dest_dir.join(target_filename); - builder.copy_link(&actual_libgccjit_path, &dst, FileType::NativeLibrary); + let dst = cg_sysroot.join(libgccjit_path_relative_to_cg_dir(target_pair, libgccjit)); + t!(std::fs::create_dir_all(dst.parent().unwrap())); + builder.copy_link(&libgccjit_path, &dst, FileType::NativeLibrary); } } } +/// Returns a path where libgccjit.so should be stored, **relative** to the +/// **codegen backend directory**. +pub fn libgccjit_path_relative_to_cg_dir( + target_pair: &GccTargetPair, + libgccjit: &GccOutput, +) -> PathBuf { + let target_filename = libgccjit.libgccjit().file_name().unwrap().to_str().unwrap(); + + // /lib//libgccjit.so + Path::new("lib").join(target_pair.target()).join(target_filename) +} + /// Output of the `compile::GccCodegenBackend` step. /// /// It contains a build stamp with the path to the built cg_gcc dylib. diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index f47b0c0b0072..cfcb144e0993 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -19,7 +19,9 @@ use object::read::archive::ArchiveFile; #[cfg(feature = "tracing")] use tracing::instrument; -use crate::core::build_steps::compile::{get_codegen_backend_file, normalize_codegen_backend_name}; +use crate::core::build_steps::compile::{ + get_codegen_backend_file, libgccjit_path_relative_to_cg_dir, normalize_codegen_backend_name, +}; use crate::core::build_steps::doc::DocumentationFormat; use crate::core::build_steps::gcc::GccTargetPair; use crate::core::build_steps::tool::{ @@ -2992,3 +2994,83 @@ impl Step for GccDev { Some(StepMetadata::dist("gcc-dev", self.target)) } } + +/// Tarball containing a libgccjit dylib, +/// needed as a dependency for the GCC codegen backend (similarly to the LLVM +/// backend needing a prebuilt libLLVM). +/// +/// This component is used for distribution through rustup. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Gcc { + host: TargetSelection, + target: TargetSelection, +} + +impl Step for Gcc { + type Output = Option; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("gcc") + } + + fn make_run(run: RunConfig<'_>) { + // GCC is always built for a target pair, (host, target). + // We do not yet support cross-compilation here, so the host target is always inferred to + // be the bootstrap host target. + run.builder.ensure(Gcc { host: run.builder.host_target, target: run.target }); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + // This prevents gcc from being built for "dist" + // or "install" on the stable/beta channels. It is not yet stable and + // should not be included. + if !builder.build.unstable_features() { + return None; + } + + let host = self.host; + let target = self.target; + if host != "x86_64-unknown-linux-gnu" { + builder.info(&format!("host target `{host}` not supported by gcc. skipping")); + return None; + } + + // We need the GCC sources to build GCC and also to add its license and README + // files to the tarball + builder.require_submodule( + "src/gcc", + Some("The src/gcc submodule is required for disting libgccjit"), + ); + + let target_pair = GccTargetPair::for_target_pair(host, target); + let libgccjit = builder.ensure(super::gcc::Gcc { target_pair }); + + // We have to include the target name in the component name, so that rustup can somehow + // distinguish that there are multiple gcc components on a given host target. + // So the tarball includes the target name. + let mut tarball = Tarball::new(builder, &format!("gcc-{target}"), &host.triple); + tarball.set_overlay(OverlayKind::Gcc); + tarball.is_preview(true); + tarball.add_legal_and_readme_to("share/doc/gcc"); + + // The path where to put libgccjit is determined by GccDylibSet. + // However, it requires a Compiler to figure out the path to the codegen backend sysroot. + // We don't really have any compiler here, because we just build libgccjit. + // So we duplicate the logic for determining the CG sysroot here. + let cg_dir = PathBuf::from(format!("lib/rustlib/{host}/codegen-backends")); + + // This returns the path to the actual file, but here we need its parent + let rel_libgccjit_path = libgccjit_path_relative_to_cg_dir(&target_pair, &libgccjit); + let path = cg_dir.join(rel_libgccjit_path.parent().unwrap()); + + tarball.add_file(libgccjit.libgccjit(), path, FileType::NativeLibrary); + Some(tarball.generate()) + } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist( + "gcc", + TargetSelection::from_user(&format!("({}, {})", self.host, self.target)), + )) + } +} diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 4a04b97c549a..f63b8e044550 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -990,7 +990,8 @@ impl<'a> Builder<'a> { dist::PlainSourceTarballGpl, dist::BuildManifest, dist::ReproducibleArtifacts, - dist::GccDev + dist::GccDev, + dist::Gcc ), Kind::Install => describe!( install::Docs, diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 7db06dcc3e9a..cd6a03c84870 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -26,6 +26,7 @@ pub(crate) enum OverlayKind { RustAnalyzer, RustcCodegenCranelift, RustcCodegenGcc, + Gcc, LlvmBitcodeLinker, } @@ -78,6 +79,14 @@ impl OverlayKind { "LICENSE-MIT", "src/tools/llvm-bitcode-linker/README.md", ], + OverlayKind::Gcc => &[ + "src/gcc/README", + "src/gcc/COPYING", + "src/gcc/COPYING.LIB", + "src/gcc/COPYING.RUNTIME", + "src/gcc/COPYING3", + "src/gcc/COPYING3.LIB", + ], } } @@ -101,6 +110,7 @@ impl OverlayKind { OverlayKind::RustcCodegenCranelift => builder.rust_version(), OverlayKind::RustcCodegenGcc => builder.rust_version(), OverlayKind::LlvmBitcodeLinker => builder.rust_version(), + OverlayKind::Gcc => builder.rust_version(), } } } From b0aa77a0267040b6155d75487e8ecc7be7790bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 31 Dec 2025 14:12:17 +0100 Subject: [PATCH 1779/3801] Build GCC on CI --- src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh index f77a0d562f03..c78b76a53f44 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh @@ -14,5 +14,7 @@ python3 ../x.py build --set rust.debug=true opt-dist # Use GCC for building GCC components, as it seems to behave badly when built with Clang # Only build GCC on full builds, not try builds if [ "${DIST_TRY_BUILD:-0}" == "0" ]; then - CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc-dev + CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist \ + gcc-dev \ + gcc fi From 308c6076ec614ce401f77e38670391fb0b5c7ff6 Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 8 Jan 2026 08:44:04 -0800 Subject: [PATCH 1780/3801] remove borrowck handling for inline const patterns --- compiler/rustc_borrowck/src/type_check/mod.rs | 67 +++---------------- 1 file changed, 9 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index e5aad4cdbd06..d2464c7e99ee 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -19,6 +19,7 @@ use rustc_infer::infer::{ BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, }; use rustc_infer::traits::PredicateObligations; +use rustc_middle::bug; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::traits::query::NoSolution; @@ -28,7 +29,6 @@ use rustc_middle::ty::{ self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, UserArgs, UserTypeAnnotationIndex, fold_regions, }; -use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::def_id::CRATE_DEF_ID; @@ -387,18 +387,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { #[instrument(skip(self), level = "debug")] fn check_user_type_annotations(&mut self) { debug!(?self.user_type_annotations); - let tcx = self.tcx(); for user_annotation in self.user_type_annotations { let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation; let annotation = self.instantiate_canonical(span, user_ty); - if let ty::UserTypeKind::TypeOf(def, args) = annotation.kind - && let DefKind::InlineConst = tcx.def_kind(def) - { - assert!(annotation.bounds.is_empty()); - self.check_inline_const(inferred_ty, def.expect_local(), args, span); - } else { - self.ascribe_user_type(inferred_ty, annotation, span); - } + self.ascribe_user_type(inferred_ty, annotation, span); } } @@ -560,36 +552,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.constraints.liveness_constraints.add_location(region, location); } } - - fn check_inline_const( - &mut self, - inferred_ty: Ty<'tcx>, - def_id: LocalDefId, - args: UserArgs<'tcx>, - span: Span, - ) { - assert!(args.user_self_ty.is_none()); - let tcx = self.tcx(); - let const_ty = tcx.type_of(def_id).instantiate(tcx, args.args); - if let Err(terr) = - self.eq_types(const_ty, inferred_ty, Locations::All(span), ConstraintCategory::Boring) - { - span_bug!( - span, - "bad inline const pattern: ({:?} = {:?}) {:?}", - const_ty, - inferred_ty, - terr - ); - } - let args = self.infcx.resolve_vars_if_possible(args.args); - let predicates = self.prove_closure_bounds(tcx, def_id, args, Locations::All(span)); - self.normalize_and_prove_instantiated_predicates( - def_id.to_def_id(), - predicates, - Locations::All(span), - ); - } } impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { @@ -1731,12 +1693,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let def_id = uv.def; if tcx.def_kind(def_id) == DefKind::InlineConst { let def_id = def_id.expect_local(); - let predicates = self.prove_closure_bounds( - tcx, - def_id, - uv.args, - location.to_locations(), - ); + let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location); self.normalize_and_prove_instantiated_predicates( def_id.to_def_id(), predicates, @@ -2519,15 +2476,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // clauses on the struct. AggregateKind::Closure(def_id, args) | AggregateKind::CoroutineClosure(def_id, args) - | AggregateKind::Coroutine(def_id, args) => ( - def_id, - self.prove_closure_bounds( - tcx, - def_id.expect_local(), - args, - location.to_locations(), - ), - ), + | AggregateKind::Coroutine(def_id, args) => { + (def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location)) + } AggregateKind::Array(_) | AggregateKind::Tuple | AggregateKind::RawPtr(..) => { (CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty()) @@ -2546,12 +2497,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { tcx: TyCtxt<'tcx>, def_id: LocalDefId, args: GenericArgsRef<'tcx>, - locations: Locations, + location: Location, ) -> ty::InstantiatedPredicates<'tcx> { let root_def_id = self.root_cx.root_def_id(); // We will have to handle propagated closure requirements for this closure, // but need to defer this until the nested body has been fully borrow checked. - self.deferred_closure_requirements.push((def_id, args, locations)); + self.deferred_closure_requirements.push((def_id, args, location.to_locations())); // Equate closure args to regions inherited from `root_def_id`. Fixes #98589. let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, root_def_id); @@ -2575,7 +2526,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Err(_) = self.eq_args( typeck_root_args, parent_args, - locations, + location.to_locations(), ConstraintCategory::BoringNoLocation, ) { span_mirbug!( From 5356be04a8c8ee194e200c66b6c5eeb34c0543ca Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 8 Jan 2026 18:36:51 +0100 Subject: [PATCH 1781/3801] Bump nightly version -> 2026-01-08 --- clippy_utils/README.md | 2 +- rust-toolchain.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 69bb6a2d6669..ecd36b157571 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-12-25 +nightly-2026-01-08 ``` diff --git a/rust-toolchain.toml b/rust-toolchain.toml index dbec79e111fb..0755e1d29c69 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-12-25" +channel = "nightly-2026-01-08" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" From 6ed95301410f592c97b4a7499fb22ea087148291 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Thu, 8 Jan 2026 18:21:54 +0100 Subject: [PATCH 1782/3801] tests/ui/borrowck/issue-92157.rs: Remove (bug not fixed) --- src/tools/tidy/src/issues.txt | 1 - tests/ui/borrowck/issue-92157.rs | 20 -------------------- tests/ui/borrowck/issue-92157.stderr | 12 ------------ 3 files changed, 33 deletions(-) delete mode 100644 tests/ui/borrowck/issue-92157.rs delete mode 100644 tests/ui/borrowck/issue-92157.stderr diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 45187a0b6450..b3e17b73237d 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -379,7 +379,6 @@ ui/borrowck/issue-88434-minimal-example.rs ui/borrowck/issue-88434-removal-index-should-be-less.rs ui/borrowck/issue-91206.rs ui/borrowck/issue-92015.rs -ui/borrowck/issue-92157.rs ui/borrowck/issue-93078.rs ui/borrowck/issue-93093.rs ui/borrowck/issue-95079-missing-move-in-nested-closure.rs diff --git a/tests/ui/borrowck/issue-92157.rs b/tests/ui/borrowck/issue-92157.rs deleted file mode 100644 index 3dbcb4ad8b7f..000000000000 --- a/tests/ui/borrowck/issue-92157.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ add-minicore -#![feature(no_core)] -#![feature(lang_items)] - -#![no_core] - -#[cfg(target_os = "linux")] -#[link(name = "c")] -extern "C" {} - -#[lang = "start"] -fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { - //~^ ERROR lang item `start` function has wrong type [E0308] - 40+2 -} - -extern crate minicore; -use minicore::*; - -fn main() {} diff --git a/tests/ui/borrowck/issue-92157.stderr b/tests/ui/borrowck/issue-92157.stderr deleted file mode 100644 index 248d700ab4b9..000000000000 --- a/tests/ui/borrowck/issue-92157.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0308]: lang item `start` function has wrong type - --> $DIR/issue-92157.rs:12:1 - | -LL | fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters - | - = note: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _` - found signature `fn(fn() -> T, isize, *const *const u8) -> _` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. From 8e3d60447cfe78a7467a61a509032b45dca66c0b Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Thu, 1 Jan 2026 10:47:22 +0100 Subject: [PATCH 1783/3801] Finish transition from `semitransparent` to `semiopaque` for `rustc_macro_transparency` --- compiler/rustc_arena/src/lib.rs | 2 +- .../src/attributes/transparency.rs | 6 +++--- .../rustc_codegen_cranelift/example/mini_core.rs | 14 +++++++------- compiler/rustc_codegen_cranelift/src/global_asm.rs | 2 +- compiler/rustc_codegen_gcc/example/mini_core.rs | 8 ++++---- compiler/rustc_span/src/symbol.rs | 1 - library/core/src/macros/mod.rs | 4 ++-- library/core/src/panic.rs | 8 ++++---- library/core/src/pin.rs | 2 +- library/core/src/ptr/mod.rs | 4 ++-- library/core/src/task/ready.rs | 2 +- library/std/src/io/error.rs | 2 +- library/std/src/panic.rs | 2 +- library/std/src/sys/thread_local/native/mod.rs | 4 ++-- library/std/src/sys/thread_local/no_threads.rs | 4 ++-- library/std/src/sys/thread_local/os.rs | 4 ++-- library/std/src/thread/local.rs | 2 +- tests/rustdoc-html/macro/macro_pub_in_module.rs | 2 +- tests/ui/attributes/malformed-attrs.stderr | 4 ++-- tests/ui/hygiene/duplicate_lifetimes.rs | 2 +- tests/ui/hygiene/generic_params.rs | 6 +++--- tests/ui/hygiene/rustc-macro-transparency.rs | 2 +- tests/ui/single-use-lifetime/issue-104440.rs | 6 +++--- 23 files changed, 46 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index a0350dd6ff31..5e81ec28ee35 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -618,7 +618,7 @@ impl DroplessArena { /// - Types that are `!Copy` and `Drop`: these must be specified in the /// arguments. The `TypedArena` will be used for them. /// -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) { #[derive(Default)] pub struct Arena<'tcx> { diff --git a/compiler/rustc_attr_parsing/src/attributes/transparency.rs b/compiler/rustc_attr_parsing/src/attributes/transparency.rs index 52aa42b1085a..7db84f8f2d95 100644 --- a/compiler/rustc_attr_parsing/src/attributes/transparency.rs +++ b/compiler/rustc_attr_parsing/src/attributes/transparency.rs @@ -15,7 +15,7 @@ impl SingleAttributeParser for TransparencyParser { }); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); const TEMPLATE: AttributeTemplate = - template!(NameValueStr: ["transparent", "semitransparent", "opaque"]); + template!(NameValueStr: ["transparent", "semiopaque", "opaque"]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(nv) = args.name_value() else { @@ -24,12 +24,12 @@ impl SingleAttributeParser for TransparencyParser { }; match nv.value_as_str() { Some(sym::transparent) => Some(Transparency::Transparent), - Some(sym::semiopaque | sym::semitransparent) => Some(Transparency::SemiOpaque), + Some(sym::semiopaque) => Some(Transparency::SemiOpaque), Some(sym::opaque) => Some(Transparency::Opaque), Some(_) => { cx.expected_specific_argument_strings( nv.value_span, - &[sym::transparent, sym::semitransparent, sym::opaque], + &[sym::transparent, sym::semiopaque, sym::opaque], ); None } diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index b522ea193716..301547cadaf7 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -744,43 +744,43 @@ unsafe extern "C" { pub struct VaList<'a>(&'a mut VaListImpl); #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro stringify($($t:tt)*) { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro file() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro line() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro cfg() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro asm() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro global_asm() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro naked_asm() { /* compiler built-in */ } diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 8d8cdb14dbc6..97d6cecf6848 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -233,7 +233,7 @@ pub(crate) fn compile_global_asm( #![allow(internal_features)] #![no_core] #[rustc_builtin_macro] - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro global_asm() { /* compiler built-in */ } global_asm!(r###" "####, diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index 64a5b431bd07..0aba44a88c5a 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -748,25 +748,25 @@ extern "C" { pub struct VaList<'a>(&'a mut VaListImpl); #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro stringify($($t:tt)*) { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro file() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro line() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro cfg() { /* compiler built-in */ } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c7ff28ccaffb..1b868a933af8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2041,7 +2041,6 @@ symbols! { self_in_typedefs, self_struct_ctor, semiopaque, - semitransparent, sha2, sha3, sha512_sm_x86, diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index a12ee60277f0..338c5688bf10 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -168,7 +168,7 @@ macro_rules! assert_ne { /// ``` #[unstable(feature = "assert_matches", issue = "82775")] #[allow_internal_unstable(panic_internals)] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro assert_matches { ($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => { match $left { @@ -401,7 +401,7 @@ macro_rules! debug_assert_ne { /// ``` #[unstable(feature = "assert_matches", issue = "82775")] #[allow_internal_unstable(assert_matches)] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro debug_assert_matches($($arg:tt)*) { if $crate::cfg!(debug_assertions) { $crate::assert_matches::assert_matches!($($arg)*); diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 81520c3ecd1b..cf0750446680 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -20,7 +20,7 @@ use crate::any::Any; #[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")] #[allow_internal_unstable(panic_internals, const_format_args)] #[rustc_diagnostic_item = "core_panic_2015_macro"] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro panic_2015 { () => ( $crate::panicking::panic("explicit panic") @@ -47,7 +47,7 @@ pub macro panic_2015 { #[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")] #[allow_internal_unstable(panic_internals, const_format_args)] #[rustc_diagnostic_item = "core_panic_2021_macro"] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro panic_2021 { () => ( $crate::panicking::panic("explicit panic") @@ -67,7 +67,7 @@ pub macro panic_2021 { #[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")] #[allow_internal_unstable(panic_internals)] #[rustc_diagnostic_item = "unreachable_2015_macro"] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro unreachable_2015 { () => ( $crate::panicking::panic("internal error: entered unreachable code") @@ -85,7 +85,7 @@ pub macro unreachable_2015 { #[doc(hidden)] #[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")] #[allow_internal_unstable(panic_internals)] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro unreachable_2021 { () => ( $crate::panicking::panic("internal error: entered unreachable code") diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 74ecb5ee4946..4791f5612bfa 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -2027,7 +2027,7 @@ unsafe impl PinCoerceUnsized for *mut T {} /// /// [`Box::pin`]: ../../std/boxed/struct.Box.html#method.pin #[stable(feature = "pin_macro", since = "1.68.0")] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] #[allow_internal_unstable(super_let)] #[rustc_diagnostic_item = "pin_macro"] // `super` gets removed by rustfmt diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 335c5c6ee944..ad74a8628c61 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -2662,7 +2662,7 @@ impl fmt::Debug for F { /// same requirements apply to field projections, even inside `addr_of!`. (In particular, it makes /// no difference whether the pointer is null or dangling.) #[stable(feature = "raw_ref_macros", since = "1.51.0")] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro addr_of($place:expr) { &raw const $place } @@ -2752,7 +2752,7 @@ pub macro addr_of($place:expr) { /// same requirements apply to field projections, even inside `addr_of_mut!`. (In particular, it /// makes no difference whether the pointer is null or dangling.) #[stable(feature = "raw_ref_macros", since = "1.51.0")] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro addr_of_mut($place:expr) { &raw mut $place } diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs index 495d72fd14be..468b3b4e528e 100644 --- a/library/core/src/task/ready.rs +++ b/library/core/src/task/ready.rs @@ -46,7 +46,7 @@ /// # } /// ``` #[stable(feature = "ready_macro", since = "1.64.0")] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro ready($e:expr) { match $e { $crate::task::Poll::Ready(t) => t, diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 528eb185df08..898ed0f7469c 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -187,7 +187,7 @@ pub struct SimpleMessage { /// Err(FAIL) /// } /// ``` -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] #[unstable(feature = "io_const_error", issue = "133448")] #[allow_internal_unstable(hint_must_use, io_const_error_internals)] pub macro const_error($kind:expr, $message:expr $(,)?) { diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index beddc328582c..658026a8020f 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -212,7 +212,7 @@ impl fmt::Display for PanicHookInfo<'_> { #[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")] #[allow_internal_unstable(libstd_sys_internals, const_format_args, panic_internals, rt)] #[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro panic_2015 { () => ({ $crate::rt::begin_panic("explicit panic") diff --git a/library/std/src/sys/thread_local/native/mod.rs b/library/std/src/sys/thread_local/native/mod.rs index 38b373be56c9..4dad81685a94 100644 --- a/library/std/src/sys/thread_local/native/mod.rs +++ b/library/std/src/sys/thread_local/native/mod.rs @@ -47,7 +47,7 @@ pub use lazy::Storage as LazyStorage; )] #[allow_internal_unsafe] #[unstable(feature = "thread_local_internals", issue = "none")] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro thread_local_inner { // NOTE: we cannot import `LocalKey`, `LazyStorage` or `EagerStorage` with a `use` because that // can shadow user provided type or type alias with a matching name. Please update the shadowing @@ -110,7 +110,7 @@ pub macro thread_local_inner { }}, } -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub(crate) macro local_pointer { () => {}, ($vis:vis static $name:ident; $($rest:tt)*) => { diff --git a/library/std/src/sys/thread_local/no_threads.rs b/library/std/src/sys/thread_local/no_threads.rs index 936d464be9f1..27a589a4a76a 100644 --- a/library/std/src/sys/thread_local/no_threads.rs +++ b/library/std/src/sys/thread_local/no_threads.rs @@ -9,7 +9,7 @@ use crate::ptr; #[allow_internal_unstable(thread_local_internals)] #[allow_internal_unsafe] #[unstable(feature = "thread_local_internals", issue = "none")] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro thread_local_inner { // used to generate the `LocalKey` value for const-initialized thread locals (@key $t:ty, $(#[$align_attr:meta])*, const $init:expr) => {{ @@ -119,7 +119,7 @@ impl LazyStorage { // SAFETY: the target doesn't have threads. unsafe impl Sync for LazyStorage {} -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub(crate) macro local_pointer { () => {}, ($vis:vis static $name:ident; $($rest:tt)*) => { diff --git a/library/std/src/sys/thread_local/os.rs b/library/std/src/sys/thread_local/os.rs index 07b93a2cbbc3..3f06c9bd1d77 100644 --- a/library/std/src/sys/thread_local/os.rs +++ b/library/std/src/sys/thread_local/os.rs @@ -12,7 +12,7 @@ use crate::ptr::{self, NonNull}; #[allow_internal_unstable(thread_local_internals)] #[allow_internal_unsafe] #[unstable(feature = "thread_local_internals", issue = "none")] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro thread_local_inner { // NOTE: we cannot import `Storage` or `LocalKey` with a `use` because that can shadow user // provided type or type alias with a matching name. Please update the shadowing test in @@ -261,7 +261,7 @@ unsafe extern "C" fn destroy_value(ptr: *mut u8) }); } -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub(crate) macro local_pointer { () => {}, ($vis:vis static $name:ident; $($rest:tt)*) => { diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 06e4b252fc8f..1318d8dc2780 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -140,7 +140,7 @@ impl fmt::Debug for LocalKey { #[doc(hidden)] #[allow_internal_unstable(thread_local_internals)] #[unstable(feature = "thread_local_internals", issue = "none")] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro thread_local_process_attrs { // Parse `cfg_attr` to figure out whether it's a `rustc_align_static`. diff --git a/tests/rustdoc-html/macro/macro_pub_in_module.rs b/tests/rustdoc-html/macro/macro_pub_in_module.rs index 2dce73c2cf26..a4b39e20d126 100644 --- a/tests/rustdoc-html/macro/macro_pub_in_module.rs +++ b/tests/rustdoc-html/macro/macro_pub_in_module.rs @@ -33,7 +33,7 @@ pub mod inner { // Make sure the logic is not affected by re-exports. mod unrenamed { //@ !has krate/macro.unrenamed.html - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] pub macro unrenamed() {} } //@ has krate/inner/macro.unrenamed.html diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 7027328bc27b..fd6f34fb45e2 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -223,8 +223,8 @@ help: try changing it to one of the following valid forms of the attribute | LL | #[rustc_macro_transparency = "opaque"] | ++++++++++ -LL | #[rustc_macro_transparency = "semitransparent"] - | +++++++++++++++++++ +LL | #[rustc_macro_transparency = "semiopaque"] + | ++++++++++++++ LL | #[rustc_macro_transparency = "transparent"] | +++++++++++++++ diff --git a/tests/ui/hygiene/duplicate_lifetimes.rs b/tests/ui/hygiene/duplicate_lifetimes.rs index 8971fb62626c..4d128da7fdbf 100644 --- a/tests/ui/hygiene/duplicate_lifetimes.rs +++ b/tests/ui/hygiene/duplicate_lifetimes.rs @@ -3,7 +3,7 @@ #![feature(decl_macro, rustc_attrs)] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] macro m($a:lifetime) { fn g<$a, 'a>() {} //~ ERROR the name `'a` is already used for a generic parameter } diff --git a/tests/ui/hygiene/generic_params.rs b/tests/ui/hygiene/generic_params.rs index def9be3a1b64..bb0de15d9a0a 100644 --- a/tests/ui/hygiene/generic_params.rs +++ b/tests/ui/hygiene/generic_params.rs @@ -11,7 +11,7 @@ mod type_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($T:ident) { fn g<$T: Clone>(t1: $T, t2: T) -> (T, $T) { (t1.clone(), t2.clone()) @@ -43,7 +43,7 @@ mod lifetime_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($a:lifetime) { fn g<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { (t1, t2) @@ -75,7 +75,7 @@ mod const_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($C:ident) { fn g(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { (t1, t2) diff --git a/tests/ui/hygiene/rustc-macro-transparency.rs b/tests/ui/hygiene/rustc-macro-transparency.rs index 1a78a7543cfd..0c680abb4153 100644 --- a/tests/ui/hygiene/rustc-macro-transparency.rs +++ b/tests/ui/hygiene/rustc-macro-transparency.rs @@ -5,7 +5,7 @@ macro transparent() { struct Transparent; let transparent = 0; } -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] macro semiopaque() { struct SemiOpaque; let semiopaque = 0; diff --git a/tests/ui/single-use-lifetime/issue-104440.rs b/tests/ui/single-use-lifetime/issue-104440.rs index 0795e95303a1..cecd17fb930b 100644 --- a/tests/ui/single-use-lifetime/issue-104440.rs +++ b/tests/ui/single-use-lifetime/issue-104440.rs @@ -8,7 +8,7 @@ mod type_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($T:ident) { fn g<$T: Clone>(t1: $T, t2: T) -> (T, $T) { (t1.clone(), t2.clone()) @@ -40,7 +40,7 @@ mod lifetime_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($a:lifetime) { fn g<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { (t1, t2) @@ -72,7 +72,7 @@ mod const_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($C:ident) { fn g(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { (t1, t2) From 9e00663d73301dbc0482526f9019deaa14f348e1 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Thu, 1 Jan 2026 10:58:23 +0100 Subject: [PATCH 1784/3801] rust-analyzer: Also use `semiopaque` instead of `semitransparent` Like in rustc. --- .../crates/hir-def/src/expr_store/expander.rs | 2 +- .../crates/hir-def/src/expr_store/lower.rs | 2 +- .../crates/hir-def/src/resolver.rs | 2 +- .../crates/hir-expand/src/declarative.rs | 5 +++-- .../crates/hir-expand/src/hygiene.rs | 14 +++++++------- .../crates/hir-expand/src/inert_attr_macro.rs | 2 +- .../crates/hir-expand/src/mod_path.rs | 4 ++-- .../crates/hir-ty/src/tests/simple.rs | 2 +- .../crates/hir/src/source_analyzer.rs | 2 +- .../crates/intern/src/symbol/symbols.rs | 1 - .../rust-analyzer/crates/span/src/hygiene.rs | 18 +++++++++--------- .../crates/test-utils/src/minicore.rs | 4 ++-- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs index de5974fff1ad..d34ec9bbc182 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/expander.rs @@ -61,7 +61,7 @@ impl Expander { pub(super) fn hygiene_for_range(&self, db: &dyn DefDatabase, range: TextRange) -> HygieneId { match self.span_map.as_ref() { hir_expand::span_map::SpanMapRef::ExpansionSpanMap(span_map) => { - HygieneId::new(span_map.span_at(range.start()).ctx.opaque_and_semitransparent(db)) + HygieneId::new(span_map.span_at(range.start()).ctx.opaque_and_semiopaque(db)) } hir_expand::span_map::SpanMapRef::RealSpanMap(_) => HygieneId::ROOT, } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index d3774ded39dc..4ae4271b92f5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -2546,7 +2546,7 @@ impl<'db> ExprCollector<'db> { // Therefore, if we got to the rib of its declaration, give up its hygiene // and use its parent expansion. - hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(self.db)); + hygiene_id = HygieneId::new(parent_ctx.opaque_and_semiopaque(self.db)); hygiene_info = parent_ctx.outer_expn(self.db).map(|expansion| { let expansion = self.db.lookup_intern_macro_call(expansion.into()); (parent_ctx.parent(self.db), expansion.def) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index f643ed31ad53..2ac0f90fb209 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -936,7 +936,7 @@ fn handle_macro_def_scope( // A macro is allowed to refer to variables from before its declaration. // Therefore, if we got to the rib of its declaration, give up its hygiene // and use its parent expansion. - *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(db)); + *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semiopaque(db)); *hygiene_info = parent_ctx.outer_expn(db).map(|expansion| { let expansion = db.lookup_intern_macro_call(expansion.into()); (parent_ctx.parent(db), expansion.def) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index d2df9a1ff6b2..d10e122a5deb 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -100,7 +100,8 @@ impl DeclarativeMacroExpander { { match &*value { "transparent" => ControlFlow::Break(Transparency::Transparent), - "semitransparent" => ControlFlow::Break(Transparency::SemiTransparent), + // "semitransparent" is for old rustc versions. + "semiopaque" | "semitransparent" => ControlFlow::Break(Transparency::SemiOpaque), "opaque" => ControlFlow::Break(Transparency::Opaque), _ => ControlFlow::Continue(()), } @@ -140,7 +141,7 @@ impl DeclarativeMacroExpander { )), }, transparency(ast::AnyHasAttrs::from(macro_rules)) - .unwrap_or(Transparency::SemiTransparent), + .unwrap_or(Transparency::SemiOpaque), ), ast::Macro::MacroDef(macro_def) => ( match macro_def.body() { diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs index bd6f7e4f2b77..ce7650d07711 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs @@ -54,7 +54,7 @@ pub fn span_with_mixed_site_ctxt( expn_id: MacroCallId, edition: Edition, ) -> Span { - span_with_ctxt_from_mark(db, span, expn_id, Transparency::SemiTransparent, edition) + span_with_ctxt_from_mark(db, span, expn_id, Transparency::SemiOpaque, edition) } fn span_with_ctxt_from_mark( @@ -82,7 +82,7 @@ pub(super) fn apply_mark( } let call_site_ctxt = db.lookup_intern_macro_call(call_id.into()).ctxt; - let mut call_site_ctxt = if transparency == Transparency::SemiTransparent { + let mut call_site_ctxt = if transparency == Transparency::SemiOpaque { call_site_ctxt.normalize_to_macros_2_0(db) } else { call_site_ctxt.normalize_to_macro_rules(db) @@ -117,16 +117,16 @@ fn apply_mark_internal( let call_id = Some(call_id); let mut opaque = ctxt.opaque(db); - let mut opaque_and_semitransparent = ctxt.opaque_and_semitransparent(db); + let mut opaque_and_semiopaque = ctxt.opaque_and_semiopaque(db); if transparency >= Transparency::Opaque { let parent = opaque; opaque = SyntaxContext::new(db, call_id, transparency, edition, parent, identity, identity); } - if transparency >= Transparency::SemiTransparent { - let parent = opaque_and_semitransparent; - opaque_and_semitransparent = + if transparency >= Transparency::SemiOpaque { + let parent = opaque_and_semiopaque; + opaque_and_semiopaque = SyntaxContext::new(db, call_id, transparency, edition, parent, |_| opaque, identity); } @@ -138,6 +138,6 @@ fn apply_mark_internal( edition, parent, |_| opaque, - |_| opaque_and_semitransparent, + |_| opaque_and_semiopaque, ) } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs index 385c98ef8778..b49190237776 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs @@ -429,7 +429,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE), rustc_attr!( rustc_macro_transparency, Normal, - template!(NameValueStr: "transparent|semitransparent|opaque"), ErrorFollowing, + template!(NameValueStr: "transparent|semiopaque|opaque"), ErrorFollowing, "used internally for testing macro hygiene", ), diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs index 51e449fe5085..1712c28aa8ab 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs @@ -401,8 +401,8 @@ pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContext) -> O result_mark = Some(mark); iter.next(); } - // Then find the last semi-transparent mark from the end if it exists. - while let Some((mark, Transparency::SemiTransparent)) = iter.next() { + // Then find the last semi-opaque mark from the end if it exists. + while let Some((mark, Transparency::SemiOpaque)) = iter.next() { result_mark = Some(mark); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index 6367521841ab..a9a5e96f75cc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs @@ -3708,7 +3708,7 @@ fn main() { } #[test] -fn macro_semitransparent_hygiene() { +fn macro_semiopaque_hygiene() { check_types( r#" macro_rules! m { diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index bf123e13f94d..6ba7a42c1946 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -1808,5 +1808,5 @@ pub(crate) fn name_hygiene(db: &dyn HirDatabase, name: InFile<&SyntaxNode>) -> H }; let span_map = db.expansion_span_map(macro_file); let ctx = span_map.span_at(name.value.text_range().start()).ctx; - HygieneId::new(ctx.opaque_and_semitransparent(db)) + HygieneId::new(ctx.opaque_and_semiopaque(db)) } diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index b6efc599f181..6181413a46db 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -442,7 +442,6 @@ define_symbols! { rustc_skip_array_during_method_dispatch, rustc_skip_during_method_dispatch, rustc_force_inline, - semitransparent, shl_assign, shl, shr_assign, diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index ea4f4c5efb42..fdfa94dfee4e 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -46,7 +46,7 @@ const _: () = { edition: Edition, parent: SyntaxContext, opaque: SyntaxContext, - opaque_and_semitransparent: SyntaxContext, + opaque_and_semiopaque: SyntaxContext, } impl PartialEq for SyntaxContextData { @@ -214,7 +214,7 @@ const _: () = { edition: T2, parent: T3, opaque: impl FnOnce(SyntaxContext) -> SyntaxContext, - opaque_and_semitransparent: impl FnOnce(SyntaxContext) -> SyntaxContext, + opaque_and_semiopaque: impl FnOnce(SyntaxContext) -> SyntaxContext, ) -> Self where Db: ?Sized + salsa::Database, @@ -241,7 +241,7 @@ const _: () = { edition: zalsa_::interned::Lookup::into_owned(data.2), parent: zalsa_::interned::Lookup::into_owned(data.3), opaque: opaque(zalsa_::FromId::from_id(id)), - opaque_and_semitransparent: opaque_and_semitransparent( + opaque_and_semiopaque: opaque_and_semiopaque( zalsa_::FromId::from_id(id), ), }, @@ -301,7 +301,7 @@ const _: () = { } } - /// This context, but with all transparent and semi-transparent expansions filtered away. + /// This context, but with all transparent and semi-opaque expansions filtered away. pub fn opaque(self, db: &'db Db) -> SyntaxContext where Db: ?Sized + zalsa_::Database, @@ -317,7 +317,7 @@ const _: () = { } /// This context, but with all transparent expansions filtered away. - pub fn opaque_and_semitransparent(self, db: &'db Db) -> SyntaxContext + pub fn opaque_and_semiopaque(self, db: &'db Db) -> SyntaxContext where Db: ?Sized + zalsa_::Database, { @@ -325,7 +325,7 @@ const _: () = { Some(id) => { let zalsa = db.zalsa(); let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id); - fields.opaque_and_semitransparent + fields.opaque_and_semiopaque } None => self, } @@ -405,7 +405,7 @@ impl<'db> SyntaxContext { #[inline] pub fn normalize_to_macro_rules(self, db: &'db dyn salsa::Database) -> SyntaxContext { - self.opaque_and_semitransparent(db) + self.opaque_and_semiopaque(db) } pub fn is_opaque(self, db: &'db dyn salsa::Database) -> bool { @@ -476,13 +476,13 @@ pub enum Transparency { /// Identifier produced by a transparent expansion is always resolved at call-site. /// Call-site spans in procedural macros, hygiene opt-out in `macro` should use this. Transparent, - /// Identifier produced by a semi-transparent expansion may be resolved + /// Identifier produced by a semi-opaque expansion may be resolved /// either at call-site or at definition-site. /// If it's a local variable, label or `$crate` then it's resolved at def-site. /// Otherwise it's resolved at call-site. /// `macro_rules` macros behave like this, built-in macros currently behave like this too, /// but that's an implementation detail. - SemiTransparent, + SemiOpaque, /// Identifier produced by an opaque expansion is always resolved at definition-site. /// Def-site spans in procedural macros, identifiers from `macro` by default use this. Opaque, diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index 01274a9835f4..c3429356d9e5 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs @@ -546,11 +546,11 @@ pub mod ptr { // endregion:non_null // region:addr_of - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] pub macro addr_of($place:expr) { &raw const $place } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] pub macro addr_of_mut($place:expr) { &raw mut $place } From fe0facf0f6f021f0c5d597fb214d96ae48571c91 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Thu, 1 Jan 2026 10:47:22 +0100 Subject: [PATCH 1785/3801] Finish transition from `semitransparent` to `semiopaque` for `rustc_macro_transparency` --- example/mini_core.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 64a5b431bd07..0aba44a88c5a 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -748,25 +748,25 @@ extern "C" { pub struct VaList<'a>(&'a mut VaListImpl); #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro stringify($($t:tt)*) { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro file() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro line() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro cfg() { /* compiler built-in */ } From a4f0937a9a28b4e1faacfc3ae1281e568d0ad59c Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Wed, 7 Jan 2026 11:03:40 +0100 Subject: [PATCH 1786/3801] clean-up --- .../src/methods/unnecessary_sort_by.rs | 71 ++++++++----------- 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs index 4a3e4c092f3b..dbaa801eaf50 100644 --- a/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -9,7 +9,7 @@ use rustc_lint::LateContext; use rustc_middle::ty; use rustc_middle::ty::GenericArgKind; use rustc_span::sym; -use rustc_span::symbol::Ident; +use rustc_span::symbol::{Ident, Symbol}; use std::iter; use super::UNNECESSARY_SORT_BY; @@ -20,29 +20,29 @@ enum LintTrigger { } struct SortDetection { - vec_name: String, + vec_name: Sugg<'static>, } struct SortByKeyDetection { - vec_name: String, - closure_arg: String, - closure_body: String, + vec_name: Sugg<'static>, + closure_arg: Symbol, + closure_body: Sugg<'static>, reverse: bool, } /// Detect if the two expressions are mirrored (identical, except one /// contains a and the other replaces it with b) -fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, b_ident: &Ident) -> bool { - match (&a_expr.kind, &b_expr.kind) { +fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: Ident, b_expr: &Expr<'_>, b_ident: Ident) -> bool { + match (a_expr.kind, b_expr.kind) { // Two arrays with mirrored contents (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => { - iter::zip(*left_exprs, *right_exprs).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) + iter::zip(left_exprs, right_exprs).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) }, // The two exprs are function calls. // Check to see that the function itself and its arguments are mirrored (ExprKind::Call(left_expr, left_args), ExprKind::Call(right_expr, right_args)) => { mirrored_exprs(left_expr, a_ident, right_expr, b_ident) - && iter::zip(*left_args, *right_args).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) + && iter::zip(left_args, right_args).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) }, // The two exprs are method calls. // Check to see that the function is the same and the arguments and receivers are mirrored @@ -51,12 +51,12 @@ fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, b_ident ExprKind::MethodCall(right_segment, right_receiver, right_args, _), ) => { left_segment.ident == right_segment.ident - && iter::zip(*left_args, *right_args).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) + && iter::zip(left_args, right_args).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) && mirrored_exprs(left_receiver, a_ident, right_receiver, b_ident) }, // Two tuples with mirrored contents (ExprKind::Tup(left_exprs), ExprKind::Tup(right_exprs)) => { - iter::zip(*left_exprs, *right_exprs).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) + iter::zip(left_exprs, right_exprs).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) }, // Two binary ops, which are the same operation and which have mirrored arguments (ExprKind::Binary(left_op, left_left, left_right), ExprKind::Binary(right_op, right_left, right_right)) => { @@ -81,27 +81,27 @@ fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, b_ident ( ExprKind::Path(QPath::Resolved( _, - Path { + &Path { segments: left_segments, .. }, )), ExprKind::Path(QPath::Resolved( _, - Path { + &Path { segments: right_segments, .. }, )), ) => { - (iter::zip(*left_segments, *right_segments).all(|(left, right)| left.ident == right.ident) + (iter::zip(left_segments, right_segments).all(|(left, right)| left.ident == right.ident) && left_segments .iter() - .all(|seg| &seg.ident != a_ident && &seg.ident != b_ident)) + .all(|seg| seg.ident != a_ident && seg.ident != b_ident)) || (left_segments.len() == 1 - && &left_segments[0].ident == a_ident + && left_segments[0].ident == a_ident && right_segments.len() == 1 - && &right_segments[0].ident == b_ident) + && right_segments[0].ident == b_ident) }, // Matching expressions, but one or both is borrowed ( @@ -123,7 +123,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp && let &[ Param { pat: - Pat { + &Pat { kind: PatKind::Binding(_, _, left_ident, _), .. }, @@ -131,36 +131,26 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp }, Param { pat: - Pat { + &Pat { kind: PatKind::Binding(_, _, right_ident, _), .. }, .. }, - ] = &closure_body.params + ] = closure_body.params && let ExprKind::MethodCall(method_path, left_expr, [right_expr], _) = closure_body.value.kind && method_path.ident.name == sym::cmp - && cx - .ty_based_def(closure_body.value) - .opt_parent(cx) - .is_diag_item(cx, sym::Ord) + && let Some(ord_trait) = cx.tcx.get_diagnostic_item(sym::Ord) + && cx.ty_based_def(closure_body.value).opt_parent(cx).opt_def_id() == Some(ord_trait) { let (closure_body, closure_arg, reverse) = if mirrored_exprs(left_expr, left_ident, right_expr, right_ident) { - ( - Sugg::hir(cx, left_expr, "..").to_string(), - left_ident.name.to_string(), - false, - ) + (Sugg::hir(cx, left_expr, "_"), left_ident.name, false) } else if mirrored_exprs(left_expr, right_ident, right_expr, left_ident) { - ( - Sugg::hir(cx, left_expr, "..").to_string(), - right_ident.name.to_string(), - true, - ) + (Sugg::hir(cx, left_expr, "_"), right_ident.name, true) } else { return None; }; - let vec_name = Sugg::hir(cx, recv, "..").to_string(); + let vec_name = Sugg::hir(cx, recv, "(_)"); if let ExprKind::Path(QPath::Resolved( _, @@ -168,12 +158,9 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp segments: [PathSegment { ident: left_name, .. }], .. }, - )) = &left_expr.kind - && left_name == left_ident - && cx - .tcx - .get_diagnostic_item(sym::Ord) - .is_some_and(|id| implements_trait(cx, cx.typeck_results().expr_ty(left_expr), id, &[])) + )) = left_expr.kind + && *left_name == left_ident + && implements_trait(cx, cx.typeck_results().expr_ty(left_expr), ord_trait, &[]) { return Some(LintTrigger::Sort(SortDetection { vec_name })); } @@ -226,7 +213,7 @@ pub(super) fn check<'tcx>( { format!("{}::cmp::Reverse({})", std_or_core, trigger.closure_body) } else { - trigger.closure_body + trigger.closure_body.to_string() }, ), if trigger.reverse { From 0cfc4ee541d819e7cf93cdebb1c43fd0d9eb444b Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Wed, 7 Jan 2026 16:25:41 +0100 Subject: [PATCH 1787/3801] fix: respect applicability reduction due to `Sugg` By postponing the creation of `Sugg`s, we can properly account for their effect on applicability --- .../src/methods/unnecessary_sort_by.rs | 83 ++++++++++--------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs index dbaa801eaf50..c8cb85c05156 100644 --- a/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; use clippy_utils::std_or_core; use clippy_utils::sugg::Sugg; @@ -14,19 +14,14 @@ use std::iter; use super::UNNECESSARY_SORT_BY; -enum LintTrigger { - Sort(SortDetection), - SortByKey(SortByKeyDetection), +enum LintTrigger<'tcx> { + Sort, + SortByKey(SortByKeyDetection<'tcx>), } -struct SortDetection { - vec_name: Sugg<'static>, -} - -struct SortByKeyDetection { - vec_name: Sugg<'static>, +struct SortByKeyDetection<'tcx> { closure_arg: Symbol, - closure_body: Sugg<'static>, + closure_body: &'tcx Expr<'tcx>, reverse: bool, } @@ -114,7 +109,7 @@ fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: Ident, b_expr: &Expr<'_>, b_ident: } } -fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) -> Option { +fn detect_lint<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, arg: &Expr<'_>) -> Option> { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) && cx.tcx.type_of(impl_id).instantiate_identity().is_slice() @@ -144,13 +139,12 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp && cx.ty_based_def(closure_body.value).opt_parent(cx).opt_def_id() == Some(ord_trait) { let (closure_body, closure_arg, reverse) = if mirrored_exprs(left_expr, left_ident, right_expr, right_ident) { - (Sugg::hir(cx, left_expr, "_"), left_ident.name, false) + (left_expr, left_ident.name, false) } else if mirrored_exprs(left_expr, right_ident, right_expr, left_ident) { - (Sugg::hir(cx, left_expr, "_"), right_ident.name, true) + (left_expr, right_ident.name, true) } else { return None; }; - let vec_name = Sugg::hir(cx, recv, "(_)"); if let ExprKind::Path(QPath::Resolved( _, @@ -162,12 +156,11 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp && *left_name == left_ident && implements_trait(cx, cx.typeck_results().expr_ty(left_expr), ord_trait, &[]) { - return Some(LintTrigger::Sort(SortDetection { vec_name })); + return Some(LintTrigger::Sort); } if !expr_borrows(cx, left_expr) { return Some(LintTrigger::SortByKey(SortByKeyDetection { - vec_name, closure_arg, closure_body, reverse, @@ -190,49 +183,57 @@ pub(super) fn check<'tcx>( arg: &'tcx Expr<'_>, is_unstable: bool, ) { - match detect_lint(cx, expr, recv, arg) { + match detect_lint(cx, expr, arg) { Some(LintTrigger::SortByKey(trigger)) => { let method = if is_unstable { "sort_unstable_by_key" } else { "sort_by_key" }; - span_lint_and_sugg( + span_lint_and_then( cx, UNNECESSARY_SORT_BY, expr.span, format!("consider using `{method}`"), - "try", - format!( - "{}.{}(|{}| {})", - trigger.vec_name, - method, - trigger.closure_arg, - if let Some(std_or_core) = std_or_core(cx) - && trigger.reverse - { - format!("{}::cmp::Reverse({})", std_or_core, trigger.closure_body) + |diag| { + let mut app = if trigger.reverse { + Applicability::MaybeIncorrect } else { - trigger.closure_body.to_string() - }, - ), - if trigger.reverse { - Applicability::MaybeIncorrect - } else { - Applicability::MachineApplicable + Applicability::MachineApplicable + }; + let recv = Sugg::hir_with_applicability(cx, recv, "(_)", &mut app); + let closure_body = Sugg::hir_with_applicability(cx, trigger.closure_body, "_", &mut app); + diag.span_suggestion( + expr.span, + "try", + format!( + "{recv}.{method}(|{}| {})", + trigger.closure_arg, + if let Some(std_or_core) = std_or_core(cx) + && trigger.reverse + { + format!("{std_or_core}::cmp::Reverse({closure_body})") + } else { + closure_body.to_string() + }, + ), + app, + ); }, ); }, - Some(LintTrigger::Sort(trigger)) => { + Some(LintTrigger::Sort) => { let method = if is_unstable { "sort_unstable" } else { "sort" }; - span_lint_and_sugg( + span_lint_and_then( cx, UNNECESSARY_SORT_BY, expr.span, format!("consider using `{method}`"), - "try", - format!("{}.{}()", trigger.vec_name, method), - Applicability::MachineApplicable, + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, recv, "(_)", &mut app); + diag.span_suggestion(expr.span, "try", format!("{recv}.{method}()"), app); + }, ); }, None => {}, From 1eb605f6346055b91acbb23cdaa81284abe4aa70 Mon Sep 17 00:00:00 2001 From: Clara Engler Date: Thu, 8 Jan 2026 19:41:24 +0100 Subject: [PATCH 1788/3801] Query associated_item_def_ids when needed This commit moves a query to `associated_item_defs` from above an error condition caused independently of it to below it. It looks generally cleaner and might potentially save some runtime in case the error condition is met, rendering `items` to be left unused, yet still queried. --- compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 38ae7852ca99..984a812246eb 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -79,13 +79,12 @@ impl<'tcx> InherentCollect<'tcx> { } if self.tcx.features().rustc_attrs() { - let items = self.tcx.associated_item_def_ids(impl_def_id); - if !self.tcx.has_attr(ty_def_id, sym::rustc_has_incoherent_inherent_impls) { let impl_span = self.tcx.def_span(impl_def_id); return Err(self.tcx.dcx().emit_err(errors::InherentTyOutside { span: impl_span })); } + let items = self.tcx.associated_item_def_ids(impl_def_id); for &impl_item in items { if !find_attr!( self.tcx.get_all_attrs(impl_item), From fe9715b5e8fb9e425fa14ce2830a3faafd3adf78 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 8 Jan 2026 18:44:38 +0000 Subject: [PATCH 1789/3801] Remove support for ScalarPair unadjusted arguments --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 13402edd13e2..d7a928f492f0 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -668,11 +668,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { if arg_layout.is_zst() { continue; } - if let BackendRepr::ScalarPair(_, _) = arg_layout.backend_repr { - llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 0, true)); - llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 1, true)); - continue; - } llargument_tys.push(arg_layout.immediate_llvm_type(self)); } From 68365697b3ab5e57c7a4e1cc4878e9a77ef002ae Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 8 Jan 2026 19:33:24 +0100 Subject: [PATCH 1790/3801] A `return` in an iterator closure should not trigger `never_loop` The iterator never loops when the closure used in, e.g., `.any()`, panics, not when it diverges as a regular `return` lets the iterator continue. --- clippy_lints/src/loops/never_loop.rs | 4 ++-- tests/ui/never_loop_iterator_reduction.rs | 9 ++++++++- tests/ui/never_loop_iterator_reduction.stderr | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index a037af3433c3..e7b9b1cd3881 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -4,8 +4,8 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::ForLoop; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::{snippet, snippet_with_context}; -use clippy_utils::sym; use clippy_utils::visitors::{Descend, for_each_expr_without_closures}; +use clippy_utils::{contains_return, sym}; use rustc_errors::Applicability; use rustc_hir::{ Block, Closure, Destination, Expr, ExprKind, HirId, InlineAsm, InlineAsmOperand, Node, Pat, Stmt, StmtKind, @@ -82,7 +82,7 @@ pub(super) fn check_iterator_reduction<'tcx>( ) { let closure_body = cx.tcx.hir_body(closure.body).value; let body_ty = cx.typeck_results().expr_ty(closure_body); - if body_ty.is_never() { + if body_ty.is_never() && !contains_return(closure_body) { span_lint_and_then( cx, NEVER_LOOP, diff --git a/tests/ui/never_loop_iterator_reduction.rs b/tests/ui/never_loop_iterator_reduction.rs index 6b07b91db29a..27f1766b841d 100644 --- a/tests/ui/never_loop_iterator_reduction.rs +++ b/tests/ui/never_loop_iterator_reduction.rs @@ -1,8 +1,9 @@ //@no-rustfix #![warn(clippy::never_loop)] +#![expect(clippy::needless_return)] fn main() { - // diverging closure: should trigger + // diverging closure with no `return`: should trigger [0, 1].into_iter().for_each(|x| { //~^ never_loop @@ -14,4 +15,10 @@ fn main() { [0, 1].into_iter().for_each(|x| { let _ = x + 1; }); + + // `return` should NOT trigger even though it is diverging + [0, 1].into_iter().for_each(|x| { + println!("x = {x}"); + return; + }); } diff --git a/tests/ui/never_loop_iterator_reduction.stderr b/tests/ui/never_loop_iterator_reduction.stderr index b76ee283146c..92483c85432d 100644 --- a/tests/ui/never_loop_iterator_reduction.stderr +++ b/tests/ui/never_loop_iterator_reduction.stderr @@ -1,5 +1,5 @@ error: this iterator reduction never loops (closure always diverges) - --> tests/ui/never_loop_iterator_reduction.rs:6:5 + --> tests/ui/never_loop_iterator_reduction.rs:7:5 | LL | / [0, 1].into_iter().for_each(|x| { LL | | From bdb1050a0f433be29982de0668102ec15a2c9b96 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Wed, 7 Jan 2026 16:42:15 +0100 Subject: [PATCH 1791/3801] fix: don't lint if `std` or `core` are required for a suggestion but unavailable --- .../src/methods/unnecessary_sort_by.rs | 23 ++++++++-------- tests/ui/unnecessary_sort_by_no_core.rs | 26 +++++++++++++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 tests/ui/unnecessary_sort_by_no_core.rs diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs index c8cb85c05156..9dddbe814317 100644 --- a/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -190,6 +190,12 @@ pub(super) fn check<'tcx>( } else { "sort_by_key" }; + let Some(std_or_core) = std_or_core(cx) else { + // To make it this far the crate has to reference diagnostic items defined in core. Either this is + // the `core` crate, there's an `extern crate core` somewhere, or another crate is defining the + // diagnostic items. It's fine to not lint in all those cases even if we might be able to. + return; + }; span_lint_and_then( cx, UNNECESSARY_SORT_BY, @@ -203,20 +209,15 @@ pub(super) fn check<'tcx>( }; let recv = Sugg::hir_with_applicability(cx, recv, "(_)", &mut app); let closure_body = Sugg::hir_with_applicability(cx, trigger.closure_body, "_", &mut app); + let closure_body = if trigger.reverse { + format!("{std_or_core}::cmp::Reverse({closure_body})") + } else { + closure_body.to_string() + }; diag.span_suggestion( expr.span, "try", - format!( - "{recv}.{method}(|{}| {})", - trigger.closure_arg, - if let Some(std_or_core) = std_or_core(cx) - && trigger.reverse - { - format!("{std_or_core}::cmp::Reverse({closure_body})") - } else { - closure_body.to_string() - }, - ), + format!("{recv}.{method}(|{}| {})", trigger.closure_arg, closure_body), app, ); }, diff --git a/tests/ui/unnecessary_sort_by_no_core.rs b/tests/ui/unnecessary_sort_by_no_core.rs new file mode 100644 index 000000000000..cb0da6339cb3 --- /dev/null +++ b/tests/ui/unnecessary_sort_by_no_core.rs @@ -0,0 +1,26 @@ +//@check-pass +#![feature(no_core)] +#![no_std] +#![no_core] +extern crate alloc; +extern crate core as mycore; +use alloc::vec; +use alloc::vec::Vec; +use mycore::cmp::Ord as _; + +fn issue_11524() -> Vec { + let mut vec = vec![1, 2, 3]; + + // We could lint and suggest `vec.sort_by_key(|a| a + 1);`, but we don't bother to -- see the + // comment in the lint at line 194 + vec.sort_by(|a, b| (a + 1).cmp(&(b + 1))); + vec +} + +fn issue_11524_2() -> Vec { + let mut vec = vec![1, 2, 3]; + + // Should not lint, as even `vec.sort_by_key(|b| core::cmp::Reverse(b + 1));` would not compile + vec.sort_by(|a, b| (b + 1).cmp(&(a + 1))); + vec +} From a9749be514923d929a75f8d0a16013ac0e68c887 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 5 Jan 2026 10:47:04 -0800 Subject: [PATCH 1792/3801] mgca: Type-check fields of ADT constructor expr const args --- .../rustc_trait_selection/src/traits/wf.rs | 26 ++++++++++- .../mgca/adt_expr_arg_simple.rs | 2 +- .../mgca/adt_expr_fields_type_check.rs | 35 ++++++++++++--- .../mgca/adt_expr_fields_type_check.stderr | 45 +++++++++++++++++++ .../printing_valtrees_supports_non_values.rs | 4 +- ...inting_valtrees_supports_non_values.stderr | 10 ++--- 6 files changed, 106 insertions(+), 16 deletions(-) create mode 100644 tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 394095508393..58a35bb9ad8c 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -1051,7 +1051,31 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { | ty::ConstKind::Placeholder(..) => { // These variants are trivially WF, so nothing to do here. } - ty::ConstKind::Value(..) => { + ty::ConstKind::Value(val) => { + // FIXME(mgca): no need to feature-gate once valtree lifetimes are not erased + if tcx.features().min_generic_const_args() + && let ty::Adt(adt_def, args) = val.ty.kind() + { + let adt_val = val.destructure_adt_const(); + let variant_def = adt_def.variant(adt_val.variant); + let cause = self.cause(ObligationCauseCode::WellFormed(None)); + self.out.extend(variant_def.fields.iter().zip(adt_val.fields).map( + |(field_def, &field_val)| { + let field_ty = tcx.type_of(field_def.did).instantiate(tcx, args); + let predicate = ty::PredicateKind::Clause( + ty::ClauseKind::ConstArgHasType(field_val, field_ty), + ); + traits::Obligation::with_depth( + tcx, + cause.clone(), + self.recursion_depth, + self.param_env, + predicate, + ) + }, + )); + } + // FIXME: Enforce that values are structurally-matchable. } } diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs index ffb763da325c..16479ba3f64f 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs @@ -12,7 +12,7 @@ fn foo>() {} trait Trait { #[type_const] - const ASSOC: usize; + const ASSOC: u32; } fn bar() { diff --git a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs index eafc8382966b..496a424bac65 100644 --- a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs +++ b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs @@ -1,17 +1,38 @@ -//@ check-pass -// FIXME(mgca): This should error - #![feature(min_generic_const_args, adt_const_params)] #![expect(incomplete_features)] #[derive(Eq, PartialEq, std::marker::ConstParamTy)] -struct Foo { field: T } +struct S1 { + f1: T, + f2: isize, +} -fn accepts>() {} +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct S2(T, isize); + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +enum En { + Var1(bool, T), + Var2 { field: i64 }, +} + +fn accepts_1>() {} +fn accepts_2>() {} +fn accepts_3>() {} fn bar() { - // `N` is not of type `u8` but we don't actually check this anywhere yet - accepts::<{ Foo:: { field: N }}>(); + accepts_1::<{ S1:: { f1: N, f2: N } }>(); + //~^ ERROR the constant `N` is not of type `u8` + //~| ERROR the constant `N` is not of type `isize` + accepts_2::<{ S2::(N, N) }>(); + //~^ ERROR the constant `N` is not of type `u8` + //~| ERROR the constant `N` is not of type `isize` + accepts_3::<{ En::Var1::(N, N) }>(); + //~^ ERROR the constant `N` is not of type `u8` + accepts_3::<{ En::Var2:: { field: N } }>(); + //~^ ERROR the constant `N` is not of type `i64` + accepts_3::<{ En::Var2:: { field: const { false } } }>(); + //~^ ERROR mismatched types } fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr new file mode 100644 index 000000000000..81f7c5366b46 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr @@ -0,0 +1,45 @@ +error: the constant `N` is not of type `u8` + --> $DIR/adt_expr_fields_type_check.rs:24:19 + | +LL | accepts_1::<{ S1:: { f1: N, f2: N } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `bool` + +error: the constant `N` is not of type `isize` + --> $DIR/adt_expr_fields_type_check.rs:24:19 + | +LL | accepts_1::<{ S1:: { f1: N, f2: N } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `bool` + +error: the constant `N` is not of type `u8` + --> $DIR/adt_expr_fields_type_check.rs:27:19 + | +LL | accepts_2::<{ S2::(N, N) }>(); + | ^^^^^^^^^^^^^^ expected `u8`, found `bool` + +error: the constant `N` is not of type `isize` + --> $DIR/adt_expr_fields_type_check.rs:27:19 + | +LL | accepts_2::<{ S2::(N, N) }>(); + | ^^^^^^^^^^^^^^ expected `isize`, found `bool` + +error: the constant `N` is not of type `u8` + --> $DIR/adt_expr_fields_type_check.rs:30:19 + | +LL | accepts_3::<{ En::Var1::(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `bool` + +error: the constant `N` is not of type `i64` + --> $DIR/adt_expr_fields_type_check.rs:32:19 + | +LL | accepts_3::<{ En::Var2:: { field: N } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i64`, found `bool` + +error[E0308]: mismatched types + --> $DIR/adt_expr_fields_type_check.rs:34:51 + | +LL | accepts_3::<{ En::Var2:: { field: const { false } } }>(); + | ^^^^^ expected `i64`, found `bool` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs index 484d6f14a82a..819323d9cbec 100644 --- a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs @@ -9,7 +9,7 @@ struct Foo; trait Trait { #[type_const] - const ASSOC: usize; + const ASSOC: u32; } fn foo() {} @@ -27,7 +27,7 @@ fn baz() { fn main() {} fn test_ice_missing_bound() { - foo::<{Option::Some::{0: ::ASSOC}}>(); + foo::<{ Option::Some:: { 0: ::ASSOC } }>(); //~^ ERROR the trait bound `T: Trait` is not satisfied //~| ERROR the constant `Option::::Some(_)` is not of type `Foo` } diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr index bd2162468944..0184aebf157a 100644 --- a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr @@ -25,8 +25,8 @@ LL | fn foo() {} error[E0277]: the trait bound `T: Trait` is not satisfied --> $DIR/printing_valtrees_supports_non_values.rs:30:5 | -LL | foo::<{Option::Some::{0: ::ASSOC}}>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` +LL | foo::<{ Option::Some:: { 0: ::ASSOC } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` | help: consider restricting type parameter `T` with trait `Trait` | @@ -34,10 +34,10 @@ LL | fn test_ice_missing_bound() { | +++++++ error: the constant `Option::::Some(_)` is not of type `Foo` - --> $DIR/printing_valtrees_supports_non_values.rs:30:12 + --> $DIR/printing_valtrees_supports_non_values.rs:30:13 | -LL | foo::<{Option::Some::{0: ::ASSOC}}>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` +LL | foo::<{ Option::Some:: { 0: ::ASSOC } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` | note: required by a const generic parameter in `foo` --> $DIR/printing_valtrees_supports_non_values.rs:15:8 From 156b08184ebeadfc2968bfc454defaab44df20cd Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 8 Jan 2026 20:04:50 +0100 Subject: [PATCH 1793/3801] fix(single_range_in_vec_init): don't apply the suggestion automatically --- clippy_lints/src/single_range_in_vec_init.rs | 2 +- tests/ui/single_range_in_vec_init_unfixable.rs | 12 ++++++++++++ .../ui/single_range_in_vec_init_unfixable.stderr | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/ui/single_range_in_vec_init_unfixable.rs create mode 100644 tests/ui/single_range_in_vec_init_unfixable.stderr diff --git a/clippy_lints/src/single_range_in_vec_init.rs b/clippy_lints/src/single_range_in_vec_init.rs index 92d1b112198f..e4906eb0c777 100644 --- a/clippy_lints/src/single_range_in_vec_init.rs +++ b/clippy_lints/src/single_range_in_vec_init.rs @@ -98,7 +98,7 @@ impl LateLintPass<'_> for SingleRangeInVecInit { && snippet.starts_with(suggested_type.starts_with()) && snippet.ends_with(suggested_type.ends_with()) { - let mut applicability = Applicability::MachineApplicable; + let mut applicability = Applicability::MaybeIncorrect; let (start_snippet, _) = snippet_with_context(cx, start.expr.span, span.ctxt(), "..", &mut applicability); let (end_snippet, _) = snippet_with_context(cx, end.expr.span, span.ctxt(), "..", &mut applicability); diff --git a/tests/ui/single_range_in_vec_init_unfixable.rs b/tests/ui/single_range_in_vec_init_unfixable.rs new file mode 100644 index 000000000000..33378b386f34 --- /dev/null +++ b/tests/ui/single_range_in_vec_init_unfixable.rs @@ -0,0 +1,12 @@ +//@no-rustfix +#![warn(clippy::single_range_in_vec_init)] + +use std::ops::Range; + +fn issue16306(v: &[i32]) { + fn takes_range_slice(_: &[Range]) {} + + let len = v.len(); + takes_range_slice(&[0..len as i64]); + //~^ single_range_in_vec_init +} diff --git a/tests/ui/single_range_in_vec_init_unfixable.stderr b/tests/ui/single_range_in_vec_init_unfixable.stderr new file mode 100644 index 000000000000..b10af21ed21c --- /dev/null +++ b/tests/ui/single_range_in_vec_init_unfixable.stderr @@ -0,0 +1,16 @@ +error: an array of `Range` that is only one element + --> tests/ui/single_range_in_vec_init_unfixable.rs:10:24 + | +LL | takes_range_slice(&[0..len as i64]); + | ^^^^^^^^^^^^^^^ + | + = note: `-D clippy::single-range-in-vec-init` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::single_range_in_vec_init)]` +help: if you wanted a `Vec` that contains the entire range, try + | +LL - takes_range_slice(&[0..len as i64]); +LL + takes_range_slice(&(0..len as i64).collect::>()); + | + +error: aborting due to 1 previous error + From 1c2cb16e8232843004ee277c1819d2d5e1c03e11 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 8 Jan 2026 11:09:07 -0800 Subject: [PATCH 1794/3801] mgca: Type-check fields of tuple expr const args --- .../rustc_middle/src/ty/consts/valtree.rs | 3 +- .../rustc_trait_selection/src/traits/wf.rs | 64 +++++++++++++------ .../mgca/adt_expr_arg_tuple_expr_fail.rs | 26 ++++++++ .../mgca/adt_expr_arg_tuple_expr_fail.stderr | 38 +++++++++++ .../mgca/adt_expr_arg_tuple_expr_simple.rs | 2 +- 5 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs create mode 100644 tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 6501ddeed6fa..5a5bf7d38ea4 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -191,8 +191,7 @@ impl<'tcx> Value<'tcx> { } } - /// Destructures array, ADT or tuple constants into the constants - /// of their fields. + /// Destructures ADT constants into the constants of their fields. pub fn destructure_adt_const(&self) -> ty::DestructuredAdtConst<'tcx> { let fields = self.to_branch(); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 58a35bb9ad8c..d383cb9d91dd 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -1053,27 +1053,49 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { } ty::ConstKind::Value(val) => { // FIXME(mgca): no need to feature-gate once valtree lifetimes are not erased - if tcx.features().min_generic_const_args() - && let ty::Adt(adt_def, args) = val.ty.kind() - { - let adt_val = val.destructure_adt_const(); - let variant_def = adt_def.variant(adt_val.variant); - let cause = self.cause(ObligationCauseCode::WellFormed(None)); - self.out.extend(variant_def.fields.iter().zip(adt_val.fields).map( - |(field_def, &field_val)| { - let field_ty = tcx.type_of(field_def.did).instantiate(tcx, args); - let predicate = ty::PredicateKind::Clause( - ty::ClauseKind::ConstArgHasType(field_val, field_ty), - ); - traits::Obligation::with_depth( - tcx, - cause.clone(), - self.recursion_depth, - self.param_env, - predicate, - ) - }, - )); + if tcx.features().min_generic_const_args() { + match val.ty.kind() { + ty::Adt(adt_def, args) => { + let adt_val = val.destructure_adt_const(); + let variant_def = adt_def.variant(adt_val.variant); + let cause = self.cause(ObligationCauseCode::WellFormed(None)); + self.out.extend(variant_def.fields.iter().zip(adt_val.fields).map( + |(field_def, &field_val)| { + let field_ty = + tcx.type_of(field_def.did).instantiate(tcx, args); + let predicate = ty::PredicateKind::Clause( + ty::ClauseKind::ConstArgHasType(field_val, field_ty), + ); + traits::Obligation::with_depth( + tcx, + cause.clone(), + self.recursion_depth, + self.param_env, + predicate, + ) + }, + )); + } + ty::Tuple(field_tys) => { + let field_vals = val.to_branch(); + let cause = self.cause(ObligationCauseCode::WellFormed(None)); + self.out.extend(field_tys.iter().zip(field_vals).map( + |(field_ty, &field_val)| { + let predicate = ty::PredicateKind::Clause( + ty::ClauseKind::ConstArgHasType(field_val, field_ty), + ); + traits::Obligation::with_depth( + tcx, + cause.clone(), + self.recursion_depth, + self.param_env, + predicate, + ) + }, + )); + } + _ => {} + } } // FIXME: Enforce that values are structurally-matchable. diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs new file mode 100644 index 000000000000..5f0d6c924bd1 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs @@ -0,0 +1,26 @@ +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +fn takes_tuple() {} +fn takes_nested_tuple() {} + +fn generic_caller() { + takes_tuple::<{ (N, N2) }>(); + //~^ ERROR the constant `N` is not of type `u32` + takes_tuple::<{ (N, T::ASSOC) }>(); + //~^ ERROR the constant `N` is not of type `u32` + //~| ERROR the constant `::ASSOC` is not of type `u32` + + takes_nested_tuple::<{ (N, (N, N2)) }>(); + //~^ ERROR the constant `N` is not of type `u32` + takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); + //~^ ERROR the constant `N` is not of type `u32` + //~| ERROR the constant `::ASSOC` is not of type `u32` +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr new file mode 100644 index 000000000000..9d80ebeaa680 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr @@ -0,0 +1,38 @@ +error: the constant `N` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:13:21 + | +LL | takes_tuple::<{ (N, N2) }>(); + | ^^^^^^^ expected `u32`, found `usize` + +error: the constant `N` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:15:21 + | +LL | takes_tuple::<{ (N, T::ASSOC) }>(); + | ^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `::ASSOC` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:15:21 + | +LL | takes_tuple::<{ (N, T::ASSOC) }>(); + | ^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `N` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:19:28 + | +LL | takes_nested_tuple::<{ (N, (N, N2)) }>(); + | ^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `N` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:21:28 + | +LL | takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); + | ^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `::ASSOC` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:21:28 + | +LL | takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); + | ^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs index 60c4c6e952cf..3fde431e27e2 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs @@ -5,7 +5,7 @@ trait Trait { #[type_const] - const ASSOC: usize; + const ASSOC: u32; } fn takes_tuple() {} From 98d3026c416a2a588bf271414a4695436cd7ef25 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 1 Jan 2026 20:19:21 -0800 Subject: [PATCH 1795/3801] Resolve intra-doc links to variant fields behind type aliases Previously, these failed to resolve, despite them working for struct fields or enum variants that were behind aliases. However, there is now an inconsistency where enum variant fields behind an alias resolve to the entry on the alias's page, while enum variants and struct fields resolve to the page of the backing ADT. --- .../passes/collect_intra_doc_links.rs | 35 ++++++++++--------- .../intra-doc/adt-through-alias.rs | 25 +++++++++++++ 2 files changed, 44 insertions(+), 16 deletions(-) create mode 100644 tests/rustdoc-html/intra-doc/adt-through-alias.rs diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3abf0fee3959..44affba9a8c0 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -308,24 +308,27 @@ impl<'tcx> LinkCollector<'_, 'tcx> { let ty_res = self.resolve_path(path, TypeNS, item_id, module_id).ok_or_else(no_res)?; match ty_res { - Res::Def(DefKind::Enum, did) => match tcx.type_of(did).instantiate_identity().kind() { - ty::Adt(def, _) if def.is_enum() => { - if let Some(variant) = def.variants().iter().find(|v| v.name == variant_name) - && let Some(field) = - variant.fields.iter().find(|f| f.name == variant_field_name) - { - Ok((ty_res, field.did)) - } else { - Err(UnresolvedPath { - item_id, - module_id, - partial_res: Some(Res::Def(DefKind::Enum, def.did())), - unresolved: variant_field_name.to_string().into(), - }) + Res::Def(DefKind::Enum | DefKind::TyAlias, did) => { + match tcx.type_of(did).instantiate_identity().kind() { + ty::Adt(def, _) if def.is_enum() => { + if let Some(variant) = + def.variants().iter().find(|v| v.name == variant_name) + && let Some(field) = + variant.fields.iter().find(|f| f.name == variant_field_name) + { + Ok((ty_res, field.did)) + } else { + Err(UnresolvedPath { + item_id, + module_id, + partial_res: Some(Res::Def(DefKind::Enum, def.did())), + unresolved: variant_field_name.to_string().into(), + }) + } } + _ => unreachable!(), } - _ => unreachable!(), - }, + } _ => Err(UnresolvedPath { item_id, module_id, diff --git a/tests/rustdoc-html/intra-doc/adt-through-alias.rs b/tests/rustdoc-html/intra-doc/adt-through-alias.rs new file mode 100644 index 000000000000..58e0f37edbab --- /dev/null +++ b/tests/rustdoc-html/intra-doc/adt-through-alias.rs @@ -0,0 +1,25 @@ +#![crate_name = "foo"] + +//! [`TheStructAlias::the_field`] +//! [`TheEnumAlias::TheVariant`] +//! [`TheEnumAlias::TheVariant::the_field`] + +// FIXME: this should resolve to the alias's version +//@ has foo/index.html '//a[@href="struct.TheStruct.html#structfield.the_field"]' 'TheStructAlias::the_field' +// FIXME: this should resolve to the alias's version +//@ has foo/index.html '//a[@href="enum.TheEnum.html#variant.TheVariant"]' 'TheEnumAlias::TheVariant' +//@ has foo/index.html '//a[@href="type.TheEnumAlias.html#variant.TheVariant.field.the_field"]' 'TheEnumAlias::TheVariant::the_field' + +pub struct TheStruct { + pub the_field: i32, +} + +pub type TheStructAlias = TheStruct; + +pub enum TheEnum { + TheVariant { the_field: i32 }, +} + +pub type TheEnumAlias = TheEnum; + +fn main() {} From a90e0418c69e2f46000e918c404d4490cd5f2b4e Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 1 Jan 2026 20:29:43 -0800 Subject: [PATCH 1796/3801] rustdoc: Refactor `def_id_to_res` as `ty_to_res` The old name and API were confusing. In my opinion, looking up the type at the call site is clearer. --- src/librustdoc/passes/collect_intra_doc_links.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 44affba9a8c0..512f0f418702 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -384,7 +384,7 @@ impl<'tcx> LinkCollector<'_, 'tcx> { }; match tcx.def_kind(self_id) { - DefKind::Impl { .. } => self.def_id_to_res(self_id), + DefKind::Impl { .. } => self.ty_to_res(tcx.type_of(self_id).instantiate_identity()), DefKind::Use => None, def_kind => Some(Res::Def(def_kind, self_id)), } @@ -506,12 +506,12 @@ impl<'tcx> LinkCollector<'_, 'tcx> { } } - /// Convert a DefId to a Res, where possible. + /// Convert a Ty to a Res, where possible. /// /// This is used for resolving type aliases. - fn def_id_to_res(&self, ty_id: DefId) -> Option { + fn ty_to_res(&self, ty: Ty<'tcx>) -> Option { use PrimitiveType::*; - Some(match *self.cx.tcx.type_of(ty_id).instantiate_identity().kind() { + Some(match *ty.kind() { ty::Bool => Res::Primitive(Bool), ty::Char => Res::Primitive(Char), ty::Int(ity) => Res::Primitive(ity.into()), @@ -614,7 +614,7 @@ impl<'tcx> LinkCollector<'_, 'tcx> { // Resolve the link on the type the alias points to. // FIXME: if the associated item is defined directly on the type alias, // it will show up on its documentation page, we should link there instead. - let Some(res) = self.def_id_to_res(did) else { return Vec::new() }; + let Some(res) = self.ty_to_res(tcx.type_of(did).instantiate_identity()) else { return Vec::new() }; self.resolve_associated_item(res, item_name, ns, disambiguator, module_id) } Res::Def( From 945f3f91712b2ccbfce0bde5c1d0f4ad36a69876 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 1 Jan 2026 23:46:46 -0800 Subject: [PATCH 1797/3801] rustdoc: Use trait as root `Res` instead of assoc item All the other parts of this function return the Res for the containing page, but for some reason, this returns the associated item itself. It doesn't seem to affect the behavior of rustdoc because e.g. the href functions use the parent if the DefId is for an assoc item. But it's clearer and simpler to be consistent. --- src/librustdoc/passes/collect_intra_doc_links.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 512f0f418702..4233f0903b23 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -614,7 +614,9 @@ impl<'tcx> LinkCollector<'_, 'tcx> { // Resolve the link on the type the alias points to. // FIXME: if the associated item is defined directly on the type alias, // it will show up on its documentation page, we should link there instead. - let Some(res) = self.ty_to_res(tcx.type_of(did).instantiate_identity()) else { return Vec::new() }; + let Some(res) = self.ty_to_res(tcx.type_of(did).instantiate_identity()) else { + return Vec::new(); + }; self.resolve_associated_item(res, item_name, ns, disambiguator, module_id) } Res::Def( @@ -720,10 +722,7 @@ impl<'tcx> LinkCollector<'_, 'tcx> { Ident::with_dummy_span(item_name), ns, ) - .map(|item| { - let res = Res::Def(item.as_def_kind(), item.def_id); - (res, item.def_id) - }) + .map(|item| (root_res, item.def_id)) .collect::>(), _ => Vec::new(), } From f503b894e912532299fd7669844efbdebaedcfd7 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 1 Jan 2026 23:54:43 -0800 Subject: [PATCH 1798/3801] rustdoc: Extract helper function for resolving assoc items on ADTs --- .../passes/collect_intra_doc_links.rs | 200 ++++++++++-------- 1 file changed, 106 insertions(+), 94 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 4233f0903b23..cb3fd72bc196 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -622,100 +622,7 @@ impl<'tcx> LinkCollector<'_, 'tcx> { Res::Def( def_kind @ (DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::ForeignTy), did, - ) => { - debug!("looking for associated item named {item_name} for item {did:?}"); - // Checks if item_name is a variant of the `SomeItem` enum - if ns == TypeNS && def_kind == DefKind::Enum { - match tcx.type_of(did).instantiate_identity().kind() { - ty::Adt(adt_def, _) => { - for variant in adt_def.variants() { - if variant.name == item_name { - return vec![(root_res, variant.def_id)]; - } - } - } - _ => unreachable!(), - } - } - - let search_for_field = || { - let (DefKind::Struct | DefKind::Union) = def_kind else { return vec![] }; - debug!("looking for fields named {item_name} for {did:?}"); - // FIXME: this doesn't really belong in `associated_item` (maybe `variant_field` is better?) - // NOTE: it's different from variant_field because it only resolves struct fields, - // not variant fields (2 path segments, not 3). - // - // We need to handle struct (and union) fields in this code because - // syntactically their paths are identical to associated item paths: - // `module::Type::field` and `module::Type::Assoc`. - // - // On the other hand, variant fields can't be mistaken for associated - // items because they look like this: `module::Type::Variant::field`. - // - // Variants themselves don't need to be handled here, even though - // they also look like associated items (`module::Type::Variant`), - // because they are real Rust syntax (unlike the intra-doc links - // field syntax) and are handled by the compiler's resolver. - let ty::Adt(def, _) = tcx.type_of(did).instantiate_identity().kind() else { - unreachable!() - }; - def.non_enum_variant() - .fields - .iter() - .filter(|field| field.name == item_name) - .map(|field| (root_res, field.did)) - .collect::>() - }; - - if let Some(Disambiguator::Kind(DefKind::Field)) = disambiguator { - return search_for_field(); - } - - // Checks if item_name belongs to `impl SomeItem` - let mut assoc_items: Vec<_> = tcx - .inherent_impls(did) - .iter() - .flat_map(|&imp| { - filter_assoc_items_by_name_and_namespace( - tcx, - imp, - Ident::with_dummy_span(item_name), - ns, - ) - }) - .map(|item| (root_res, item.def_id)) - .collect(); - - if assoc_items.is_empty() { - // Check if item_name belongs to `impl SomeTrait for SomeItem` - // FIXME(#74563): This gives precedence to `impl SomeItem`: - // Although having both would be ambiguous, use impl version for compatibility's sake. - // To handle that properly resolve() would have to support - // something like [`ambi_fn`](::ambi_fn) - assoc_items = resolve_associated_trait_item( - tcx.type_of(did).instantiate_identity(), - module_id, - item_name, - ns, - self.cx, - ) - .into_iter() - .map(|item| (root_res, item.def_id)) - .collect::>(); - } - - debug!("got associated item {assoc_items:?}"); - - if !assoc_items.is_empty() { - return assoc_items; - } - - if ns != Namespace::ValueNS { - return Vec::new(); - } - - search_for_field() - } + ) => self.resolve_assoc_on_adt(), Res::Def(DefKind::Trait, did) => filter_assoc_items_by_name_and_namespace( tcx, did, @@ -727,6 +634,111 @@ impl<'tcx> LinkCollector<'_, 'tcx> { _ => Vec::new(), } } + + fn resolve_assoc_on_adt( + &mut self, + adt_def_kind: DefKind, + adt_def_id: DefId, + item_name: Symbol, + ns: Namespace, + disambiguator: Option, + module_id: DefId, + ) -> Vec<(Res, DefId)> { + let tcx = self.cx.tcx; + let root_res = Res::Def(adt_def_kind, adt_def_id); + debug!("looking for associated item named {item_name} for item {adt_def_id:?}"); + // Checks if item_name is a variant of the `SomeItem` enum + if ns == TypeNS && adt_def_kind == DefKind::Enum { + match tcx.type_of(adt_def_id).instantiate_identity().kind() { + ty::Adt(adt_def, _) => { + for variant in adt_def.variants() { + if variant.name == item_name { + return vec![(root_res, variant.def_id)]; + } + } + } + _ => unreachable!(), + } + } + + let search_for_field = || { + let (DefKind::Struct | DefKind::Union) = adt_def_kind else { return vec![] }; + debug!("looking for fields named {item_name} for {adt_def_id:?}"); + // FIXME: this doesn't really belong in `associated_item` (maybe `variant_field` is better?) + // NOTE: it's different from variant_field because it only resolves struct fields, + // not variant fields (2 path segments, not 3). + // + // We need to handle struct (and union) fields in this code because + // syntactically their paths are identical to associated item paths: + // `module::Type::field` and `module::Type::Assoc`. + // + // On the other hand, variant fields can't be mistaken for associated + // items because they look like this: `module::Type::Variant::field`. + // + // Variants themselves don't need to be handled here, even though + // they also look like associated items (`module::Type::Variant`), + // because they are real Rust syntax (unlike the intra-doc links + // field syntax) and are handled by the compiler's resolver. + let ty::Adt(def, _) = tcx.type_of(adt_def_id).instantiate_identity().kind() else { + unreachable!() + }; + def.non_enum_variant() + .fields + .iter() + .filter(|field| field.name == item_name) + .map(|field| (root_res, field.did)) + .collect::>() + }; + + if let Some(Disambiguator::Kind(DefKind::Field)) = disambiguator { + return search_for_field(); + } + + // Checks if item_name belongs to `impl SomeItem` + let mut assoc_items: Vec<_> = tcx + .inherent_impls(adt_def_id) + .iter() + .flat_map(|&imp| { + filter_assoc_items_by_name_and_namespace( + tcx, + imp, + Ident::with_dummy_span(item_name), + ns, + ) + }) + .map(|item| (root_res, item.def_id)) + .collect(); + + if assoc_items.is_empty() { + // Check if item_name belongs to `impl SomeTrait for SomeItem` + // FIXME(#74563): This gives precedence to `impl SomeItem`: + // Although having both would be ambiguous, use impl version for compatibility's sake. + // To handle that properly resolve() would have to support + // something like [`ambi_fn`](::ambi_fn) + assoc_items = resolve_associated_trait_item( + tcx.type_of(adt_def_id).instantiate_identity(), + module_id, + item_name, + ns, + self.cx, + ) + .into_iter() + .map(|item| (root_res, item.def_id)) + .collect::>(); + } + + debug!("got associated item {assoc_items:?}"); + + if !assoc_items.is_empty() { + return assoc_items; + } + + if ns != Namespace::ValueNS { + return Vec::new(); + } + + search_for_field() + } } fn full_res(tcx: TyCtxt<'_>, (base, assoc_item): (Res, Option)) -> Res { From 2c98517faea2f0dc5b96282c2677cdb4628abd34 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 2 Jan 2026 00:36:30 -0800 Subject: [PATCH 1799/3801] Refactor out many free functions from intra-doc link code --- .../passes/collect_intra_doc_links.rs | 602 +++++++++--------- 1 file changed, 291 insertions(+), 311 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index cb3fd72bc196..553d8636c85b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -338,58 +338,6 @@ impl<'tcx> LinkCollector<'_, 'tcx> { } } - /// Given a primitive type, try to resolve an associated item. - fn resolve_primitive_associated_item( - &self, - prim_ty: PrimitiveType, - ns: Namespace, - item_name: Symbol, - ) -> Vec<(Res, DefId)> { - let tcx = self.cx.tcx; - - prim_ty - .impls(tcx) - .flat_map(|impl_| { - filter_assoc_items_by_name_and_namespace( - tcx, - impl_, - Ident::with_dummy_span(item_name), - ns, - ) - .map(|item| (Res::Primitive(prim_ty), item.def_id)) - }) - .collect::>() - } - - fn resolve_self_ty(&self, path_str: &str, ns: Namespace, item_id: DefId) -> Option { - if ns != TypeNS || path_str != "Self" { - return None; - } - - let tcx = self.cx.tcx; - let self_id = match tcx.def_kind(item_id) { - def_kind @ (DefKind::AssocFn - | DefKind::AssocConst - | DefKind::AssocTy - | DefKind::Variant - | DefKind::Field) => { - let parent_def_id = tcx.parent(item_id); - if def_kind == DefKind::Field && tcx.def_kind(parent_def_id) == DefKind::Variant { - tcx.parent(parent_def_id) - } else { - parent_def_id - } - } - _ => item_id, - }; - - match tcx.def_kind(self_id) { - DefKind::Impl { .. } => self.ty_to_res(tcx.type_of(self_id).instantiate_identity()), - DefKind::Use => None, - def_kind => Some(Res::Def(def_kind, self_id)), - } - } - /// Convenience wrapper around `doc_link_resolutions`. /// /// This also handles resolving `true` and `false` as booleans. @@ -402,7 +350,7 @@ impl<'tcx> LinkCollector<'_, 'tcx> { item_id: DefId, module_id: DefId, ) -> Option { - if let res @ Some(..) = self.resolve_self_ty(path_str, ns, item_id) { + if let res @ Some(..) = resolve_self_ty(self.cx.tcx, path_str, ns, item_id) { return res; } @@ -432,13 +380,15 @@ impl<'tcx> LinkCollector<'_, 'tcx> { /// Resolves a string as a path within a particular namespace. Returns an /// optional URL fragment in the case of variants and methods. fn resolve<'path>( - &mut self, + &self, path_str: &'path str, ns: Namespace, disambiguator: Option, item_id: DefId, module_id: DefId, ) -> Result)>, UnresolvedPath<'path>> { + let tcx = self.cx.tcx; + if let Some(res) = self.resolve_path(path_str, ns, item_id, module_id) { return Ok(match res { Res::Def( @@ -484,7 +434,7 @@ impl<'tcx> LinkCollector<'_, 'tcx> { match resolve_primitive(path_root, TypeNS) .or_else(|| self.resolve_path(path_root, TypeNS, item_id, module_id)) .map(|ty_res| { - self.resolve_associated_item(ty_res, item_name, ns, disambiguator, module_id) + resolve_associated_item(tcx, ty_res, item_name, ns, disambiguator, module_id) .into_iter() .map(|(res, def_id)| (res, Some(def_id))) .collect::>() @@ -505,257 +455,293 @@ impl<'tcx> LinkCollector<'_, 'tcx> { } } } - - /// Convert a Ty to a Res, where possible. - /// - /// This is used for resolving type aliases. - fn ty_to_res(&self, ty: Ty<'tcx>) -> Option { - use PrimitiveType::*; - Some(match *ty.kind() { - ty::Bool => Res::Primitive(Bool), - ty::Char => Res::Primitive(Char), - ty::Int(ity) => Res::Primitive(ity.into()), - ty::Uint(uty) => Res::Primitive(uty.into()), - ty::Float(fty) => Res::Primitive(fty.into()), - ty::Str => Res::Primitive(Str), - ty::Tuple(tys) if tys.is_empty() => Res::Primitive(Unit), - ty::Tuple(_) => Res::Primitive(Tuple), - ty::Pat(..) => Res::Primitive(Pat), - ty::Array(..) => Res::Primitive(Array), - ty::Slice(_) => Res::Primitive(Slice), - ty::RawPtr(_, _) => Res::Primitive(RawPointer), - ty::Ref(..) => Res::Primitive(Reference), - ty::FnDef(..) => panic!("type alias to a function definition"), - ty::FnPtr(..) => Res::Primitive(Fn), - ty::Never => Res::Primitive(Never), - ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) | ty::Foreign(did) => { - Res::from_def_id(self.cx.tcx, did) - } - ty::Alias(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Dynamic(..) - | ty::UnsafeBinder(_) - | ty::Param(_) - | ty::Bound(..) - | ty::Placeholder(_) - | ty::Infer(_) - | ty::Error(_) => return None, - }) - } - - /// Convert a PrimitiveType to a Ty, where possible. - /// - /// This is used for resolving trait impls for primitives - fn primitive_type_to_ty(&mut self, prim: PrimitiveType) -> Option> { - use PrimitiveType::*; - let tcx = self.cx.tcx; - - // FIXME: Only simple types are supported here, see if we can support - // other types such as Tuple, Array, Slice, etc. - // See https://github.com/rust-lang/rust/issues/90703#issuecomment-1004263455 - Some(match prim { - Bool => tcx.types.bool, - Str => tcx.types.str_, - Char => tcx.types.char, - Never => tcx.types.never, - I8 => tcx.types.i8, - I16 => tcx.types.i16, - I32 => tcx.types.i32, - I64 => tcx.types.i64, - I128 => tcx.types.i128, - Isize => tcx.types.isize, - F16 => tcx.types.f16, - F32 => tcx.types.f32, - F64 => tcx.types.f64, - F128 => tcx.types.f128, - U8 => tcx.types.u8, - U16 => tcx.types.u16, - U32 => tcx.types.u32, - U64 => tcx.types.u64, - U128 => tcx.types.u128, - Usize => tcx.types.usize, - _ => return None, - }) - } - - /// Resolve an associated item, returning its containing page's `Res` - /// and the fragment targeting the associated item on its page. - fn resolve_associated_item( - &mut self, - root_res: Res, - item_name: Symbol, - ns: Namespace, - disambiguator: Option, - module_id: DefId, - ) -> Vec<(Res, DefId)> { - let tcx = self.cx.tcx; - - match root_res { - Res::Primitive(prim) => { - let items = self.resolve_primitive_associated_item(prim, ns, item_name); - if !items.is_empty() { - items - // Inherent associated items take precedence over items that come from trait impls. - } else { - self.primitive_type_to_ty(prim) - .map(|ty| { - resolve_associated_trait_item(ty, module_id, item_name, ns, self.cx) - .iter() - .map(|item| (root_res, item.def_id)) - .collect::>() - }) - .unwrap_or_default() - } - } - Res::Def(DefKind::TyAlias, did) => { - // Resolve the link on the type the alias points to. - // FIXME: if the associated item is defined directly on the type alias, - // it will show up on its documentation page, we should link there instead. - let Some(res) = self.ty_to_res(tcx.type_of(did).instantiate_identity()) else { - return Vec::new(); - }; - self.resolve_associated_item(res, item_name, ns, disambiguator, module_id) - } - Res::Def( - def_kind @ (DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::ForeignTy), - did, - ) => self.resolve_assoc_on_adt(), - Res::Def(DefKind::Trait, did) => filter_assoc_items_by_name_and_namespace( - tcx, - did, - Ident::with_dummy_span(item_name), - ns, - ) - .map(|item| (root_res, item.def_id)) - .collect::>(), - _ => Vec::new(), - } - } - - fn resolve_assoc_on_adt( - &mut self, - adt_def_kind: DefKind, - adt_def_id: DefId, - item_name: Symbol, - ns: Namespace, - disambiguator: Option, - module_id: DefId, - ) -> Vec<(Res, DefId)> { - let tcx = self.cx.tcx; - let root_res = Res::Def(adt_def_kind, adt_def_id); - debug!("looking for associated item named {item_name} for item {adt_def_id:?}"); - // Checks if item_name is a variant of the `SomeItem` enum - if ns == TypeNS && adt_def_kind == DefKind::Enum { - match tcx.type_of(adt_def_id).instantiate_identity().kind() { - ty::Adt(adt_def, _) => { - for variant in adt_def.variants() { - if variant.name == item_name { - return vec![(root_res, variant.def_id)]; - } - } - } - _ => unreachable!(), - } - } - - let search_for_field = || { - let (DefKind::Struct | DefKind::Union) = adt_def_kind else { return vec![] }; - debug!("looking for fields named {item_name} for {adt_def_id:?}"); - // FIXME: this doesn't really belong in `associated_item` (maybe `variant_field` is better?) - // NOTE: it's different from variant_field because it only resolves struct fields, - // not variant fields (2 path segments, not 3). - // - // We need to handle struct (and union) fields in this code because - // syntactically their paths are identical to associated item paths: - // `module::Type::field` and `module::Type::Assoc`. - // - // On the other hand, variant fields can't be mistaken for associated - // items because they look like this: `module::Type::Variant::field`. - // - // Variants themselves don't need to be handled here, even though - // they also look like associated items (`module::Type::Variant`), - // because they are real Rust syntax (unlike the intra-doc links - // field syntax) and are handled by the compiler's resolver. - let ty::Adt(def, _) = tcx.type_of(adt_def_id).instantiate_identity().kind() else { - unreachable!() - }; - def.non_enum_variant() - .fields - .iter() - .filter(|field| field.name == item_name) - .map(|field| (root_res, field.did)) - .collect::>() - }; - - if let Some(Disambiguator::Kind(DefKind::Field)) = disambiguator { - return search_for_field(); - } - - // Checks if item_name belongs to `impl SomeItem` - let mut assoc_items: Vec<_> = tcx - .inherent_impls(adt_def_id) - .iter() - .flat_map(|&imp| { - filter_assoc_items_by_name_and_namespace( - tcx, - imp, - Ident::with_dummy_span(item_name), - ns, - ) - }) - .map(|item| (root_res, item.def_id)) - .collect(); - - if assoc_items.is_empty() { - // Check if item_name belongs to `impl SomeTrait for SomeItem` - // FIXME(#74563): This gives precedence to `impl SomeItem`: - // Although having both would be ambiguous, use impl version for compatibility's sake. - // To handle that properly resolve() would have to support - // something like [`ambi_fn`](::ambi_fn) - assoc_items = resolve_associated_trait_item( - tcx.type_of(adt_def_id).instantiate_identity(), - module_id, - item_name, - ns, - self.cx, - ) - .into_iter() - .map(|item| (root_res, item.def_id)) - .collect::>(); - } - - debug!("got associated item {assoc_items:?}"); - - if !assoc_items.is_empty() { - return assoc_items; - } - - if ns != Namespace::ValueNS { - return Vec::new(); - } - - search_for_field() - } } fn full_res(tcx: TyCtxt<'_>, (base, assoc_item): (Res, Option)) -> Res { assoc_item.map_or(base, |def_id| Res::from_def_id(tcx, def_id)) } +/// Given a primitive type, try to resolve an associated item. +fn resolve_primitive_associated_item<'tcx>( + tcx: TyCtxt<'tcx>, + prim_ty: PrimitiveType, + ns: Namespace, + item_ident: Ident, +) -> Vec<(Res, DefId)> { + prim_ty + .impls(tcx) + .flat_map(|impl_| { + filter_assoc_items_by_name_and_namespace(tcx, impl_, item_ident, ns) + .map(|item| (Res::Primitive(prim_ty), item.def_id)) + }) + .collect::>() +} + +fn resolve_self_ty<'tcx>( + tcx: TyCtxt<'tcx>, + path_str: &str, + ns: Namespace, + item_id: DefId, +) -> Option { + if ns != TypeNS || path_str != "Self" { + return None; + } + + let self_id = match tcx.def_kind(item_id) { + def_kind @ (DefKind::AssocFn + | DefKind::AssocConst + | DefKind::AssocTy + | DefKind::Variant + | DefKind::Field) => { + let parent_def_id = tcx.parent(item_id); + if def_kind == DefKind::Field && tcx.def_kind(parent_def_id) == DefKind::Variant { + tcx.parent(parent_def_id) + } else { + parent_def_id + } + } + _ => item_id, + }; + + match tcx.def_kind(self_id) { + DefKind::Impl { .. } => ty_to_res(tcx, tcx.type_of(self_id).instantiate_identity()), + DefKind::Use => None, + def_kind => Some(Res::Def(def_kind, self_id)), + } +} + +/// Convert a Ty to a Res, where possible. +/// +/// This is used for resolving type aliases. +fn ty_to_res<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { + use PrimitiveType::*; + Some(match *ty.kind() { + ty::Bool => Res::Primitive(Bool), + ty::Char => Res::Primitive(Char), + ty::Int(ity) => Res::Primitive(ity.into()), + ty::Uint(uty) => Res::Primitive(uty.into()), + ty::Float(fty) => Res::Primitive(fty.into()), + ty::Str => Res::Primitive(Str), + ty::Tuple(tys) if tys.is_empty() => Res::Primitive(Unit), + ty::Tuple(_) => Res::Primitive(Tuple), + ty::Pat(..) => Res::Primitive(Pat), + ty::Array(..) => Res::Primitive(Array), + ty::Slice(_) => Res::Primitive(Slice), + ty::RawPtr(_, _) => Res::Primitive(RawPointer), + ty::Ref(..) => Res::Primitive(Reference), + ty::FnDef(..) => panic!("type alias to a function definition"), + ty::FnPtr(..) => Res::Primitive(Fn), + ty::Never => Res::Primitive(Never), + ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) | ty::Foreign(did) => { + Res::from_def_id(tcx, did) + } + ty::Alias(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Dynamic(..) + | ty::UnsafeBinder(_) + | ty::Param(_) + | ty::Bound(..) + | ty::Placeholder(_) + | ty::Infer(_) + | ty::Error(_) => return None, + }) +} + +/// Convert a PrimitiveType to a Ty, where possible. +/// +/// This is used for resolving trait impls for primitives +fn primitive_type_to_ty<'tcx>(tcx: TyCtxt<'tcx>, prim: PrimitiveType) -> Option> { + use PrimitiveType::*; + + // FIXME: Only simple types are supported here, see if we can support + // other types such as Tuple, Array, Slice, etc. + // See https://github.com/rust-lang/rust/issues/90703#issuecomment-1004263455 + Some(match prim { + Bool => tcx.types.bool, + Str => tcx.types.str_, + Char => tcx.types.char, + Never => tcx.types.never, + I8 => tcx.types.i8, + I16 => tcx.types.i16, + I32 => tcx.types.i32, + I64 => tcx.types.i64, + I128 => tcx.types.i128, + Isize => tcx.types.isize, + F16 => tcx.types.f16, + F32 => tcx.types.f32, + F64 => tcx.types.f64, + F128 => tcx.types.f128, + U8 => tcx.types.u8, + U16 => tcx.types.u16, + U32 => tcx.types.u32, + U64 => tcx.types.u64, + U128 => tcx.types.u128, + Usize => tcx.types.usize, + _ => return None, + }) +} + +/// Resolve an associated item, returning its containing page's `Res` +/// and the fragment targeting the associated item on its page. +fn resolve_associated_item<'tcx>( + tcx: TyCtxt<'tcx>, + root_res: Res, + item_name: Symbol, + ns: Namespace, + disambiguator: Option, + module_id: DefId, +) -> Vec<(Res, DefId)> { + let item_ident = Ident::with_dummy_span(item_name); + + match root_res { + Res::Primitive(prim) => { + let items = resolve_primitive_associated_item(tcx, prim, ns, item_ident); + if !items.is_empty() { + items + // Inherent associated items take precedence over items that come from trait impls. + } else { + primitive_type_to_ty(tcx, prim) + .map(|ty| { + resolve_associated_trait_item(ty, module_id, item_ident, ns, tcx) + .iter() + .map(|item| (root_res, item.def_id)) + .collect::>() + }) + .unwrap_or_default() + } + } + Res::Def(DefKind::TyAlias, did) => { + // Resolve the link on the type the alias points to. + // FIXME: if the associated item is defined directly on the type alias, + // it will show up on its documentation page, we should link there instead. + let Some(res) = ty_to_res(tcx, tcx.type_of(did).instantiate_identity()) else { + return Vec::new(); + }; + resolve_associated_item(tcx, res, item_name, ns, disambiguator, module_id) + } + Res::Def(DefKind::Struct | DefKind::Union | DefKind::Enum, did) => { + resolve_assoc_on_adt(tcx, did, item_name, ns, disambiguator, module_id) + } + Res::Def(DefKind::ForeignTy, did) => { + resolve_assoc_on_simple_type(tcx, did, item_ident, ns, module_id) + } + Res::Def(DefKind::Trait, did) => filter_assoc_items_by_name_and_namespace( + tcx, + did, + Ident::with_dummy_span(item_name), + ns, + ) + .map(|item| (root_res, item.def_id)) + .collect::>(), + _ => Vec::new(), + } +} + +fn resolve_assoc_on_adt<'tcx>( + tcx: TyCtxt<'tcx>, + adt_def_id: DefId, + item_name: Symbol, + ns: Namespace, + disambiguator: Option, + module_id: DefId, +) -> Vec<(Res, DefId)> { + debug!("looking for associated item named {item_name} for item {adt_def_id:?}"); + let root_res = Res::from_def_id(tcx, adt_def_id); + let adt_ty = tcx.type_of(adt_def_id).instantiate_identity(); + let adt_def = adt_ty.ty_adt_def().expect("must be ADT"); + let item_ident = Ident::with_dummy_span(item_name); + // Checks if item_name is a variant of the `SomeItem` enum + if ns == TypeNS && adt_def.is_enum() { + for variant in adt_def.variants() { + if variant.name == item_name { + return vec![(root_res, variant.def_id)]; + } + } + } + + if let Some(Disambiguator::Kind(DefKind::Field)) = disambiguator + && (adt_def.is_struct() || adt_def.is_union()) + { + return resolve_structfield(adt_def, item_name) + .into_iter() + .map(|did| (root_res, did)) + .collect(); + } + + let assoc_items = resolve_assoc_on_simple_type(tcx, adt_def_id, item_ident, ns, module_id); + if !assoc_items.is_empty() { + return assoc_items; + } + + if ns == Namespace::ValueNS && (adt_def.is_struct() || adt_def.is_union()) { + return resolve_structfield(adt_def, item_name) + .into_iter() + .map(|did| (root_res, did)) + .collect(); + } + + vec![] +} + +/// "Simple" i.e. an ADT, foreign type, etc. -- not a type alias, primitive type, or other trickier type. +fn resolve_assoc_on_simple_type<'tcx>( + tcx: TyCtxt<'tcx>, + ty_def_id: DefId, + item_ident: Ident, + ns: Namespace, + module_id: DefId, +) -> Vec<(Res, DefId)> { + let root_res = Res::from_def_id(tcx, ty_def_id); + // Checks if item_name belongs to `impl SomeItem` + let inherent_assoc_items: Vec<_> = tcx + .inherent_impls(ty_def_id) + .iter() + .flat_map(|&imp| filter_assoc_items_by_name_and_namespace(tcx, imp, item_ident, ns)) + .map(|item| (root_res, item.def_id)) + .collect(); + debug!("got inherent assoc items {inherent_assoc_items:?}"); + if !inherent_assoc_items.is_empty() { + return inherent_assoc_items; + } + + // Check if item_name belongs to `impl SomeTrait for SomeItem` + // FIXME(#74563): This gives precedence to `impl SomeItem`: + // Although having both would be ambiguous, use impl version for compatibility's sake. + // To handle that properly resolve() would have to support + // something like [`ambi_fn`](::ambi_fn) + let ty = tcx.type_of(ty_def_id).instantiate_identity(); + let trait_assoc_items = resolve_associated_trait_item(ty, module_id, item_ident, ns, tcx) + .into_iter() + .map(|item| (root_res, item.def_id)) + .collect::>(); + debug!("got trait assoc items {trait_assoc_items:?}"); + trait_assoc_items +} + +fn resolve_structfield<'tcx>(adt_def: ty::AdtDef<'tcx>, item_name: Symbol) -> Option { + debug!("looking for fields named {item_name} for {adt_def:?}"); + adt_def + .non_enum_variant() + .fields + .iter() + .find(|field| field.name == item_name) + .map(|field| field.did) +} + /// Look to see if a resolved item has an associated item named `item_name`. /// /// Given `[std::io::Error::source]`, where `source` is unresolved, this would /// find `std::error::Error::source` and return /// `::source`. -fn resolve_associated_trait_item<'a>( - ty: Ty<'a>, +fn resolve_associated_trait_item<'tcx>( + ty: Ty<'tcx>, module: DefId, - item_name: Symbol, + item_ident: Ident, ns: Namespace, - cx: &mut DocContext<'a>, + tcx: TyCtxt<'tcx>, ) -> Vec { // FIXME: this should also consider blanket impls (`impl X for T`). Unfortunately // `get_auto_trait_and_blanket_impls` is broken because the caching behavior is wrong. In the @@ -763,22 +749,17 @@ fn resolve_associated_trait_item<'a>( // Next consider explicit impls: `impl MyTrait for MyType` // Give precedence to inherent impls. - let traits = trait_impls_for(cx, ty, module); - let tcx = cx.tcx; + let traits = trait_impls_for(tcx, ty, module); debug!("considering traits {traits:?}"); let candidates = traits .iter() .flat_map(|&(impl_, trait_)| { - filter_assoc_items_by_name_and_namespace( - tcx, - trait_, - Ident::with_dummy_span(item_name), - ns, + filter_assoc_items_by_name_and_namespace(tcx, trait_, item_ident, ns).map( + move |trait_assoc| { + trait_assoc_to_impl_assoc_item(tcx, impl_, trait_assoc.def_id) + .unwrap_or(*trait_assoc) + }, ) - .map(move |trait_assoc| { - trait_assoc_to_impl_assoc_item(tcx, impl_, trait_assoc.def_id) - .unwrap_or(*trait_assoc) - }) }) .collect::>(); // FIXME(#74563): warn about ambiguity @@ -813,13 +794,12 @@ fn trait_assoc_to_impl_assoc_item<'tcx>( /// /// NOTE: this cannot be a query because more traits could be available when more crates are compiled! /// So it is not stable to serialize cross-crate. -#[instrument(level = "debug", skip(cx))] -fn trait_impls_for<'a>( - cx: &mut DocContext<'a>, - ty: Ty<'a>, +#[instrument(level = "debug", skip(tcx))] +fn trait_impls_for<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, module: DefId, ) -> FxIndexSet<(DefId, DefId)> { - let tcx = cx.tcx; let mut impls = FxIndexSet::default(); for &trait_ in tcx.doc_link_traits_in_scope(module) { @@ -1535,7 +1515,7 @@ impl LinkCollector<'_, '_> { } None => { // Try everything! - let mut candidate = |ns| { + let candidate = |ns| { self.resolve(path_str, ns, None, item_id, module_id) .map_err(ResolutionFailure::NotResolved) }; @@ -1921,7 +1901,7 @@ fn report_diagnostic( /// handled earlier. For example, if passed `Item::Crate(std)` and `path_str` /// `std::io::Error::x`, this will resolve `std::io::Error`. fn resolution_failure( - collector: &mut LinkCollector<'_, '_>, + collector: &LinkCollector<'_, '_>, diag_info: DiagnosticInfo<'_>, path_str: &str, disambiguator: Option, From 742d276dc1d9f21c2196a057e2ac4bcaf70e3cc5 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Thu, 8 Jan 2026 20:24:49 +0100 Subject: [PATCH 1800/3801] make attrs actually use `Target::GenericParam` --- compiler/rustc_ast_lowering/src/lib.rs | 9 ++++--- .../src/attributes/stability.rs | 3 ++- .../rustc_attr_parsing/src/target_checking.rs | 24 +++++++++++++++++++ compiler/rustc_hir/src/lib.rs | 2 +- ...id-attributes-on-const-params-78957.stderr | 12 +++++----- tests/ui/force-inlining/invalid.stderr | 2 +- .../unused/unused_attributes-must_use.stderr | 2 +- tests/ui/pin-ergonomics/pin_v2-attr.rs | 4 ++-- tests/ui/pin-ergonomics/pin_v2-attr.stderr | 4 ++-- tests/ui/scalable-vectors/invalid.rs | 2 +- tests/ui/scalable-vectors/invalid.stderr | 2 +- 11 files changed, 47 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a81d2297ef85..6f8dab21e2b6 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1986,8 +1986,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let (name, kind) = self.lower_generic_param_kind(param, source); let hir_id = self.lower_node_id(param.id); - self.lower_attrs(hir_id, ¶m.attrs, param.span(), Target::Param); - hir::GenericParam { + let param_attrs = ¶m.attrs; + let param_span = param.span(); + let param = hir::GenericParam { hir_id, def_id: self.local_def_id(param.id), name, @@ -1996,7 +1997,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { kind, colon_span: param.colon_span.map(|s| self.lower_span(s)), source, - } + }; + self.lower_attrs(hir_id, param_attrs, param_span, Target::from_generic_param(¶m)); + param } fn lower_generic_param_kind( diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index 6d4f77ef1751..8d27e2e276dd 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -1,6 +1,7 @@ use std::num::NonZero; use rustc_errors::ErrorGuaranteed; +use rustc_hir::target::GenericParamKind; use rustc_hir::{ DefaultBodyStability, MethodKind, PartialConstStability, Stability, StabilityLevel, StableSince, Target, UnstableReason, VERSION_PLACEHOLDER, @@ -43,7 +44,7 @@ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::TyAlias), Allow(Target::Variant), Allow(Target::Field), - Allow(Target::Param), + Allow(Target::GenericParam { kind: GenericParamKind::Type, has_default: true }), Allow(Target::Static), Allow(Target::ForeignFn), Allow(Target::ForeignStatic), diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index e86ecb451fc2..88fa3e436292 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -310,5 +310,29 @@ pub(crate) const ALL_TARGETS: &'static [Policy] = { Allow(Target::Crate), Allow(Target::Delegation { mac: false }), Allow(Target::Delegation { mac: true }), + Allow(Target::GenericParam { + kind: rustc_hir::target::GenericParamKind::Const, + has_default: false, + }), + Allow(Target::GenericParam { + kind: rustc_hir::target::GenericParamKind::Const, + has_default: true, + }), + Allow(Target::GenericParam { + kind: rustc_hir::target::GenericParamKind::Lifetime, + has_default: false, + }), + Allow(Target::GenericParam { + kind: rustc_hir::target::GenericParamKind::Lifetime, + has_default: true, + }), + Allow(Target::GenericParam { + kind: rustc_hir::target::GenericParamKind::Type, + has_default: false, + }), + Allow(Target::GenericParam { + kind: rustc_hir::target::GenericParamKind::Type, + has_default: true, + }), ] }; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index fa46c0f085a2..9c2fec867785 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -32,7 +32,7 @@ pub mod lints; pub mod pat_util; mod stability; mod stable_hash_impls; -mod target; +pub mod target; pub mod weak_lang_items; #[cfg(test)] diff --git a/tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr b/tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr index f8010b4ea687..5fc7e7fef75d 100644 --- a/tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr +++ b/tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr @@ -1,4 +1,4 @@ -error: `#[inline]` attribute cannot be used on function params +error: `#[inline]` attribute cannot be used on const parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:6:16 | LL | pub struct Foo<#[inline] const N: usize>; @@ -6,7 +6,7 @@ LL | pub struct Foo<#[inline] const N: usize>; | = help: `#[inline]` can only be applied to functions -error: `#[inline]` attribute cannot be used on function params +error: `#[inline]` attribute cannot be used on lifetime parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:14:17 | LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); @@ -14,7 +14,7 @@ LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); | = help: `#[inline]` can only be applied to functions -error: `#[inline]` attribute cannot be used on function params +error: `#[inline]` attribute cannot be used on type parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:22:17 | LL | pub struct Foo3<#[inline] T>(PhantomData); @@ -40,7 +40,7 @@ error[E0517]: attribute should be applied to a struct, enum, or union LL | pub struct Baz3<#[repr(C)] T>(PhantomData); | ^ - not a struct, enum, or union -error: `#[cold]` attribute cannot be used on function params +error: `#[cold]` attribute cannot be used on const parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:8:16 | LL | pub struct Bar<#[cold] const N: usize>; @@ -54,7 +54,7 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error: `#[cold]` attribute cannot be used on function params +error: `#[cold]` attribute cannot be used on lifetime parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:16:17 | LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); @@ -63,7 +63,7 @@ LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[cold]` can only be applied to functions -error: `#[cold]` attribute cannot be used on function params +error: `#[cold]` attribute cannot be used on type parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:24:17 | LL | pub struct Bar3<#[cold] T>(PhantomData); diff --git a/tests/ui/force-inlining/invalid.stderr b/tests/ui/force-inlining/invalid.stderr index df3b646b6cec..ce4f1d77ad2d 100644 --- a/tests/ui/force-inlining/invalid.stderr +++ b/tests/ui/force-inlining/invalid.stderr @@ -152,7 +152,7 @@ LL | #[rustc_force_inline] | = help: `#[rustc_force_inline]` can only be applied to functions -error: `#[rustc_force_inline]` attribute cannot be used on function params +error: `#[rustc_force_inline]` attribute cannot be used on type parameters --> $DIR/invalid.rs:72:10 | LL | enum Bar<#[rustc_force_inline] T> { diff --git a/tests/ui/lint/unused/unused_attributes-must_use.stderr b/tests/ui/lint/unused/unused_attributes-must_use.stderr index 9b9a6a9c9f3d..3192c0994548 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.stderr +++ b/tests/ui/lint/unused/unused_attributes-must_use.stderr @@ -93,7 +93,7 @@ LL | #[must_use] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[must_use]` can be applied to data types, functions, traits, and unions -error: `#[must_use]` attribute cannot be used on function params +error: `#[must_use]` attribute cannot be used on type parameters --> $DIR/unused_attributes-must_use.rs:77:8 | LL | fn qux<#[must_use] T>(_: T) {} diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.rs b/tests/ui/pin-ergonomics/pin_v2-attr.rs index cfafe4b0b899..ba25d3587edd 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.rs +++ b/tests/ui/pin-ergonomics/pin_v2-attr.rs @@ -25,8 +25,8 @@ union Union { // disallowed enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { - //~^ ERROR `#[pin_v2]` attribute cannot be used on function params - //~| ERROR `#[pin_v2]` attribute cannot be used on function params + //~^ ERROR `#[pin_v2]` attribute cannot be used on type parameters + //~| ERROR `#[pin_v2]` attribute cannot be used on type parameters #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on enum variants UnitVariant, TupleVariant(#[pin_v2] T), //~ ERROR `#[pin_v2]` attribute cannot be used on struct fields diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.stderr b/tests/ui/pin-ergonomics/pin_v2-attr.stderr index 81e086f5a7ef..c297afa87a73 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.stderr +++ b/tests/ui/pin-ergonomics/pin_v2-attr.stderr @@ -20,7 +20,7 @@ LL | #![pin_v2] | = help: `#[pin_v2]` can be applied to data types and unions -error: `#[pin_v2]` attribute cannot be used on function params +error: `#[pin_v2]` attribute cannot be used on type parameters --> $DIR/pin_v2-attr.rs:27:10 | LL | enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { @@ -28,7 +28,7 @@ LL | enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { | = help: `#[pin_v2]` can be applied to data types and unions -error: `#[pin_v2]` attribute cannot be used on function params +error: `#[pin_v2]` attribute cannot be used on type parameters --> $DIR/pin_v2-attr.rs:27:23 | LL | enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { diff --git a/tests/ui/scalable-vectors/invalid.rs b/tests/ui/scalable-vectors/invalid.rs index beb3ad66b78b..90e9839c9e11 100644 --- a/tests/ui/scalable-vectors/invalid.rs +++ b/tests/ui/scalable-vectors/invalid.rs @@ -48,7 +48,7 @@ type Foo = u32; #[rustc_scalable_vector(4)] //~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on enums enum Bar<#[rustc_scalable_vector(4)] T> { -//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on function params +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on type parameters #[rustc_scalable_vector(4)] //~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on enum variants Baz(std::marker::PhantomData), diff --git a/tests/ui/scalable-vectors/invalid.stderr b/tests/ui/scalable-vectors/invalid.stderr index 43be84a8b005..d73b5abf7030 100644 --- a/tests/ui/scalable-vectors/invalid.stderr +++ b/tests/ui/scalable-vectors/invalid.stderr @@ -92,7 +92,7 @@ LL | #[rustc_scalable_vector(4)] | = help: `#[rustc_scalable_vector]` can only be applied to structs -error: `#[rustc_scalable_vector]` attribute cannot be used on function params +error: `#[rustc_scalable_vector]` attribute cannot be used on type parameters --> $DIR/invalid.rs:50:10 | LL | enum Bar<#[rustc_scalable_vector(4)] T> { From dc505a51a4adea72efe1f1b08af6bf75b45ffdca Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Thu, 1 Jan 2026 19:24:41 +0100 Subject: [PATCH 1801/3801] Hash all spans relatively to their parent Co-authored-by: Camille Gillot --- .../rustc_middle/src/query/on_disk_cache.rs | 46 +++++++++++-------- compiler/rustc_query_system/src/ich/hcx.rs | 6 +-- .../rustc_span/src/caching_source_map_view.rs | 8 ++-- compiler/rustc_span/src/lib.rs | 37 ++++++++++----- 4 files changed, 58 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index c882d5d499bd..29cceb708850 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -20,8 +20,8 @@ use rustc_span::hygiene::{ }; use rustc_span::source_map::Spanned; use rustc_span::{ - BlobDecoder, BytePos, ByteSymbol, CachingSourceMapView, ExpnData, ExpnHash, Pos, - RelativeBytePos, SourceFile, Span, SpanDecoder, SpanEncoder, StableSourceFileId, Symbol, + BlobDecoder, BytePos, ByteSymbol, CachingSourceMapView, ExpnData, ExpnHash, RelativeBytePos, + SourceFile, Span, SpanDecoder, SpanEncoder, StableSourceFileId, Symbol, }; use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; @@ -652,7 +652,10 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> { let dto = u32::decode(self); let enclosing = self.tcx.source_span_untracked(parent.unwrap()).data_untracked(); - (enclosing.lo + BytePos::from_u32(dlo), enclosing.lo + BytePos::from_u32(dto)) + ( + BytePos(enclosing.lo.0.wrapping_add(dlo)), + BytePos(enclosing.lo.0.wrapping_add(dto)), + ) } TAG_FULL_SPAN => { let file_lo_index = SourceFileIndex::decode(self); @@ -894,30 +897,33 @@ impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> { return TAG_PARTIAL_SPAN.encode(self); } - if let Some(parent) = span_data.parent { - let enclosing = self.tcx.source_span_untracked(parent).data_untracked(); - if enclosing.contains(span_data) { - TAG_RELATIVE_SPAN.encode(self); - (span_data.lo - enclosing.lo).to_u32().encode(self); - (span_data.hi - enclosing.lo).to_u32().encode(self); - return; - } + let parent = + span_data.parent.map(|parent| self.tcx.source_span_untracked(parent).data_untracked()); + if let Some(parent) = parent + && parent.contains(span_data) + { + TAG_RELATIVE_SPAN.encode(self); + (span_data.lo.0.wrapping_sub(parent.lo.0)).encode(self); + (span_data.hi.0.wrapping_sub(parent.lo.0)).encode(self); + return; } - let pos = self.source_map.byte_pos_to_line_and_col(span_data.lo); - let partial_span = match &pos { - Some((file_lo, _, _)) => !file_lo.contains(span_data.hi), - None => true, + let Some((file_lo, line_lo, col_lo)) = + self.source_map.byte_pos_to_line_and_col(span_data.lo) + else { + return TAG_PARTIAL_SPAN.encode(self); }; - if partial_span { - return TAG_PARTIAL_SPAN.encode(self); + if let Some(parent) = parent + && file_lo.contains(parent.lo) + { + TAG_RELATIVE_SPAN.encode(self); + (span_data.lo.0.wrapping_sub(parent.lo.0)).encode(self); + (span_data.hi.0.wrapping_sub(parent.lo.0)).encode(self); + return; } - let (file_lo, line_lo, col_lo) = pos.unwrap(); - let len = span_data.hi - span_data.lo; - let source_file_index = self.source_file_index(file_lo); TAG_FULL_SPAN.encode(self); diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index be838f689e53..840f0b35266d 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -5,9 +5,7 @@ use rustc_hir::definitions::DefPathHash; use rustc_session::Session; use rustc_session::cstore::Untracked; use rustc_span::source_map::SourceMap; -use rustc_span::{ - BytePos, CachingSourceMapView, DUMMY_SP, Span, SpanData, StableSourceFileId, Symbol, -}; +use rustc_span::{BytePos, CachingSourceMapView, DUMMY_SP, SourceFile, Span, SpanData, Symbol}; use crate::ich; @@ -118,7 +116,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { fn span_data_to_lines_and_cols( &mut self, span: &SpanData, - ) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)> { + ) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> { self.source_map().span_data_to_lines_and_cols(span) } diff --git a/compiler/rustc_span/src/caching_source_map_view.rs b/compiler/rustc_span/src/caching_source_map_view.rs index 41cfaa3ee34e..11507a3d9e45 100644 --- a/compiler/rustc_span/src/caching_source_map_view.rs +++ b/compiler/rustc_span/src/caching_source_map_view.rs @@ -2,7 +2,7 @@ use std::ops::Range; use std::sync::Arc; use crate::source_map::SourceMap; -use crate::{BytePos, Pos, RelativeBytePos, SourceFile, SpanData, StableSourceFileId}; +use crate::{BytePos, Pos, RelativeBytePos, SourceFile, SpanData}; #[derive(Clone)] struct CacheEntry { @@ -114,7 +114,7 @@ impl<'sm> CachingSourceMapView<'sm> { pub fn span_data_to_lines_and_cols( &mut self, span_data: &SpanData, - ) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)> { + ) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> { self.time_stamp += 1; // Check if lo and hi are in the cached lines. @@ -136,7 +136,7 @@ impl<'sm> CachingSourceMapView<'sm> { let lo = &self.line_cache[lo_cache_idx as usize]; let hi = &self.line_cache[hi_cache_idx as usize]; return Some(( - lo.file.stable_id, + &lo.file, lo.line_number, span_data.lo - lo.line.start, hi.line_number, @@ -224,7 +224,7 @@ impl<'sm> CachingSourceMapView<'sm> { assert_eq!(lo.file_index, hi.file_index); Some(( - lo.file.stable_id, + &lo.file, lo.line_number, span_data.lo - lo.line.start, hi.line_number, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index d3e0e303d0c6..1c430099835b 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -2831,7 +2831,7 @@ pub trait HashStableContext { fn span_data_to_lines_and_cols( &mut self, span: &SpanData, - ) -> Option<(StableSourceFileId, usize, BytePos, usize, BytePos)>; + ) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)>; fn hashing_controls(&self) -> HashingControls; } @@ -2849,6 +2849,8 @@ where /// codepoint offsets. For the purpose of the hash that's sufficient. /// Also, hashing filenames is expensive so we avoid doing it twice when the /// span starts and ends in the same file, which is almost always the case. + /// + /// IMPORTANT: changes to this method should be reflected in implementations of `SpanEncoder`. fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { const TAG_VALID_SPAN: u8 = 0; const TAG_INVALID_SPAN: u8 = 1; @@ -2867,15 +2869,17 @@ where return; } - if let Some(parent) = span.parent { - let def_span = ctx.def_span(parent).data_untracked(); - if def_span.contains(span) { - // This span is enclosed in a definition: only hash the relative position. - Hash::hash(&TAG_RELATIVE_SPAN, hasher); - (span.lo - def_span.lo).to_u32().hash_stable(ctx, hasher); - (span.hi - def_span.lo).to_u32().hash_stable(ctx, hasher); - return; - } + let parent = span.parent.map(|parent| ctx.def_span(parent).data_untracked()); + if let Some(parent) = parent + && parent.contains(span) + { + // This span is enclosed in a definition: only hash the relative position. + // This catches a subset of the cases from the `file.contains(parent.lo)`, + // But we can do this check cheaply without the expensive `span_data_to_lines_and_cols` query. + Hash::hash(&TAG_RELATIVE_SPAN, hasher); + (span.lo - parent.lo).to_u32().hash_stable(ctx, hasher); + (span.hi - parent.lo).to_u32().hash_stable(ctx, hasher); + return; } // If this is not an empty or invalid span, we want to hash the last @@ -2887,8 +2891,19 @@ where return; }; + if let Some(parent) = parent + && file.contains(parent.lo) + { + // This span is relative to another span in the same file, + // only hash the relative position. + Hash::hash(&TAG_RELATIVE_SPAN, hasher); + Hash::hash(&(span.lo.0.wrapping_sub(parent.lo.0)), hasher); + Hash::hash(&(span.hi.0.wrapping_sub(parent.lo.0)), hasher); + return; + } + Hash::hash(&TAG_VALID_SPAN, hasher); - Hash::hash(&file, hasher); + Hash::hash(&file.stable_id, hasher); // Hash both the length and the end location (line/column) of a span. If we // hash only the length, for example, then two otherwise equal spans with From 459d77e863f0607f4f0fdc25be19db6f49fdc9c0 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 8 Jan 2026 22:23:16 +0200 Subject: [PATCH 1802/3801] Publish smol_str v0.3.5 --- src/tools/rust-analyzer/Cargo.lock | 2 +- src/tools/rust-analyzer/lib/smol_str/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 8188fbf96064..5bdde7c7c3e6 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2629,7 +2629,7 @@ dependencies = [ [[package]] name = "smol_str" -version = "0.3.4" +version = "0.3.5" dependencies = [ "arbitrary", "borsh", diff --git a/src/tools/rust-analyzer/lib/smol_str/Cargo.toml b/src/tools/rust-analyzer/lib/smol_str/Cargo.toml index 118b25993ffe..4e7844b49e19 100644 --- a/src/tools/rust-analyzer/lib/smol_str/Cargo.toml +++ b/src/tools/rust-analyzer/lib/smol_str/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smol_str" -version = "0.3.4" +version = "0.3.5" description = "small-string optimized string type with O(1) clone" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/smol_str" From c502d7fce0e057eee00bfab471360ea751ef3762 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Jan 2026 16:53:50 +0100 Subject: [PATCH 1803/3801] Fix trait method anchor disappearing before user can click on it --- src/librustdoc/html/static/css/rustdoc.css | 4 +++- tests/rustdoc-gui/anchor-navigable.goml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index b93e921dd5b7..b770a0e2a0e4 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1200,9 +1200,11 @@ nav.sub { display: initial; } .anchor { + --anchor-link-shift: 0.5em; display: none; position: absolute; - left: -0.5em; + left: calc(var(--anchor-link-shift) * -1); + padding-right: var(--anchor-link-shift); background: none !important; } .anchor.field { diff --git a/tests/rustdoc-gui/anchor-navigable.goml b/tests/rustdoc-gui/anchor-navigable.goml index 61d7c89d434f..db7fc3bbf182 100644 --- a/tests/rustdoc-gui/anchor-navigable.goml +++ b/tests/rustdoc-gui/anchor-navigable.goml @@ -7,5 +7,5 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" // We check that ".item-info" is bigger than its content. move-cursor-to: ".impl" -assert-property: (".impl > a.anchor", {"offsetWidth": "8"}) +assert-property: (".impl > a.anchor", {"offsetWidth": "16"}) assert-css: (".impl > a.anchor", {"left": "-8px"}) From bfb117ac744d6e1dd73b25eb46066bf3a36380c7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Jan 2026 17:09:07 +0100 Subject: [PATCH 1804/3801] Clean up `tests/rustdoc-gui/anchors.goml` test code --- tests/rustdoc-gui/anchors.goml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/tests/rustdoc-gui/anchors.goml b/tests/rustdoc-gui/anchors.goml index 0e8c834a7a77..371a4583c7b2 100644 --- a/tests/rustdoc-gui/anchors.goml +++ b/tests/rustdoc-gui/anchors.goml @@ -14,9 +14,9 @@ define-function: ( assert-css: ("#toggle-all-docs", {"color": |main_color|}) assert-css: (".main-heading h1 span", {"color": |main_heading_type_color|}) assert-css: ( - ".rightside a.src", - {"color": |src_link_color|, "text-decoration": "none"}, - ALL, + ".rightside a.src", + {"color": |src_link_color|, "text-decoration": "none"}, + ALL, ) compare-elements-css: ( ".rightside a.src", @@ -31,25 +31,23 @@ define-function: ( move-cursor-to: ".main-heading a.src" assert-css: ( - ".main-heading a.src", - {"color": |src_link_color|, "text-decoration": "underline"}, + ".main-heading a.src", + {"color": |src_link_color|, "text-decoration": "underline"}, ) move-cursor-to: ".impl-items .rightside a.src" assert-css: ( - ".impl-items .rightside a.src", - {"color": |src_link_color|, "text-decoration": "none"}, + ".impl-items .rightside a.src", + {"color": |src_link_color|, "text-decoration": "none"}, ) move-cursor-to: ".impl-items a.rightside.src" assert-css: ( - ".impl-items a.rightside.src", - {"color": |src_link_color|, "text-decoration": "none"}, + ".impl-items a.rightside.src", + {"color": |src_link_color|, "text-decoration": "none"}, ) go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" // Since we changed page, we need to set the theme again. - set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} - // We reload the page so the local storage settings are being used. - reload: + call-function: ("switch-theme", {"theme": |theme|}) assert-css: ("#top-doc-prose-title", {"color": |title_color|}) From 16fbf6a27b5962b818f4c6ca14d391c6911ed6a8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Jan 2026 17:41:42 +0100 Subject: [PATCH 1805/3801] Add check for trait impl method anchor --- tests/rustdoc-gui/anchors.goml | 16 ++++++++++++++++ tests/rustdoc-gui/src/staged_api/lib.rs | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/tests/rustdoc-gui/anchors.goml b/tests/rustdoc-gui/anchors.goml index 371a4583c7b2..eaec73f50e97 100644 --- a/tests/rustdoc-gui/anchors.goml +++ b/tests/rustdoc-gui/anchors.goml @@ -45,6 +45,22 @@ define-function: ( {"color": |src_link_color|, "text-decoration": "none"}, ) + // Now we ensure that the `§` anchor is "reachable" for users on trait methods. + // To ensure the anchor is not hovered, we move the cursor to another item. + move-cursor-to: "#search-button" + // By default, the anchor is not displayed. + wait-for-css: ("#method\.vroum .anchor", {"display": "none"}) + // Once we move the cursor to the method, the anchor should appear. + move-cursor-to: "#method\.vroum .code-header" + assert-css-false: ("#method\.vroum .anchor", {"display": "none"}) + // Now we move the cursor to the anchor to check there is no gap between the method and the + // anchor, making the anchor disappear and preventing users to click on it. + // To make it work, we need to first move it between the method and the anchor. + store-position: ("#method\.vroum .code-header", {"x": method_x, "y": method_y}) + move-cursor-to: (|method_x| - 2, |method_y|) + // Anchor should still be displayed. + assert-css-false: ("#method\.vroum .anchor", {"display": "none"}) + go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" // Since we changed page, we need to set the theme again. call-function: ("switch-theme", {"theme": |theme|}) diff --git a/tests/rustdoc-gui/src/staged_api/lib.rs b/tests/rustdoc-gui/src/staged_api/lib.rs index 9b5ad1c5ff32..7304d2f02ab1 100644 --- a/tests/rustdoc-gui/src/staged_api/lib.rs +++ b/tests/rustdoc-gui/src/staged_api/lib.rs @@ -4,6 +4,10 @@ #![stable(feature = "some_feature", since = "1.3.5")] #![doc(rust_logo)] +pub trait X { + fn vroum(); +} + #[stable(feature = "some_feature", since = "1.3.5")] pub struct Foo {} @@ -13,3 +17,7 @@ impl Foo { #[stable(feature = "some_other_feature", since = "1.3.6")] pub fn yo() {} } + +impl X for Foo { + fn vroum() {} +} From 945e7c78d2624e9647c8c608284f23e7a2fea32e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Jan 2026 13:56:16 +0100 Subject: [PATCH 1806/3801] Use functions more in rustdoc GUI tests --- tests/rustdoc-gui/copy-code.goml | 11 +++-- tests/rustdoc-gui/font-serif-change.goml | 7 ++- tests/rustdoc-gui/notable-trait.goml | 11 ++--- tests/rustdoc-gui/search-filter.goml | 6 +-- ...setting-auto-hide-content-large-items.goml | 5 +- .../setting-auto-hide-item-methods-docs.goml | 5 +- ...tting-auto-hide-trait-implementations.goml | 5 +- .../setting-go-to-only-result.goml | 11 +++-- tests/rustdoc-gui/settings.goml | 14 ++---- tests/rustdoc-gui/sidebar-mobile.goml | 13 +---- .../sidebar-resize-close-popover.goml | 7 ++- tests/rustdoc-gui/sidebar-resize-setting.goml | 4 +- tests/rustdoc-gui/source-code-wrapping.goml | 7 ++- tests/rustdoc-gui/theme-change.goml | 10 +--- tests/rustdoc-gui/theme-defaults.goml | 7 ++- tests/rustdoc-gui/utils.goml | 49 +++++++++++-------- 16 files changed, 78 insertions(+), 94 deletions(-) diff --git a/tests/rustdoc-gui/copy-code.goml b/tests/rustdoc-gui/copy-code.goml index 14421ab746f5..eb003ef5e1ca 100644 --- a/tests/rustdoc-gui/copy-code.goml +++ b/tests/rustdoc-gui/copy-code.goml @@ -1,5 +1,6 @@ // Checks that the "copy code" button is not triggering JS error and its display // isn't broken. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" define-function: ( @@ -47,15 +48,15 @@ assert: |copy_height| > 0 && |copy_width| > 0 // First we ensure that the clipboard is empty. assert-clipboard: "" + // We make the line numbers appear. -click: "rustdoc-toolbar .settings-menu" -wait-for-css: ("#settings", {"display": "block"}) -// We make the line numbers appear. +call-function: ("open-settings-menu", {}) click: "#line-numbers" wait-for-local-storage: {"rustdoc-line-numbers": "true" } + // We close the settings menu. -click: "rustdoc-toolbar .settings-menu" -wait-for-css-false: ("#settings", {"display": "block"}) +call-function: ("close-settings-menu", {}) + // We ensure that there are actually line numbers generated in the DOM. assert-text: (".example-wrap pre.rust code span[data-nosnippet]", "1") // We make the copy button appear. diff --git a/tests/rustdoc-gui/font-serif-change.goml b/tests/rustdoc-gui/font-serif-change.goml index 1e9f21c35416..32e95cdc6ee1 100644 --- a/tests/rustdoc-gui/font-serif-change.goml +++ b/tests/rustdoc-gui/font-serif-change.goml @@ -1,4 +1,5 @@ // Ensures that the font serif change is working as expected. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // By default, it should be the serif fonts. @@ -8,8 +9,7 @@ assert-css: ("body", {"font-family": |serif_font|}) assert-css: ("p code", {"font-family": |serif_code_font|}) // We now switch to the sans serif font -click: "main .settings-menu" -wait-for: "#sans-serif-fonts" +call-function: ("open-settings-menu", {}) click: "#sans-serif-fonts" store-value: (font, '"Fira Sans", sans-serif') @@ -23,8 +23,7 @@ assert-css: ("body", {"font-family": |font|}) assert-css: ("p code", {"font-family": |code_font|}) // We switch back to the serif font -click: "main .settings-menu" -wait-for: "#sans-serif-fonts" +call-function: ("open-settings-menu", {}) click: "#sans-serif-fonts" assert-css: ("body", {"font-family": |serif_font|}) diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml index 6bd4661ac8f4..839988021fce 100644 --- a/tests/rustdoc-gui/notable-trait.goml +++ b/tests/rustdoc-gui/notable-trait.goml @@ -82,15 +82,15 @@ call-function: ("check-notable-tooltip-position", { "i_x": 528, }) +go-to: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html" +// This is needed to ensure that the text color is computed. +show-text: true + // Now check the colors. define-function: ( "check-colors", [theme, header_color, content_color, type_color, trait_color, link_color], block { - go-to: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html" - // This is needed to ensure that the text color is computed. - show-text: true - call-function: ("switch-theme", {"theme": |theme|}) assert-css: ( @@ -251,7 +251,6 @@ reload: assert-count: ("//*[@class='tooltip popover']", 0) click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" assert-count: ("//*[@class='tooltip popover']", 1) -click: "rustdoc-toolbar .settings-menu a" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) assert-count: ("//*[@class='tooltip popover']", 0) assert-false: "#method\.create_an_iterator_from_read .tooltip:focus" diff --git a/tests/rustdoc-gui/search-filter.goml b/tests/rustdoc-gui/search-filter.goml index d92d522c119d..6bd7eaa92063 100644 --- a/tests/rustdoc-gui/search-filter.goml +++ b/tests/rustdoc-gui/search-filter.goml @@ -70,9 +70,7 @@ assert-css: ("#crate-search", { }) // We now check the dark theme. -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" -click: "#theme-dark" +call-function: ("switch-theme", {"theme": "dark"}) wait-for-css: ("#crate-search", { "border": "1px solid #e0e0e0", "color": "#ddd", @@ -80,7 +78,7 @@ wait-for-css: ("#crate-search", { }) // And finally we check the ayu theme. -click: "#theme-ayu" +call-function: ("switch-theme", {"theme": "ayu"}) wait-for-css: ("#crate-search", { "border": "1px solid #5c6773", "color": "#c5c5c5", diff --git a/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml b/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml index 342bd726694e..dbf80ae34912 100644 --- a/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml +++ b/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml @@ -1,6 +1,8 @@ // This test ensures that the "Auto-hide item contents for large items" setting is working as // expected. +include: "utils.goml" + // We need to disable this check because `trait.impl/test_docs/trait.Iterator.js` doesn't exist. fail-on-request-error: false @@ -9,8 +11,7 @@ define-function: ( [storage_value, setting_attribute_value, toggle_attribute_value], block { assert-local-storage: {"rustdoc-auto-hide-large-items": |storage_value|} - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" + call-function: ("open-settings-menu", {}) assert-property: ("#auto-hide-large-items", {"checked": |setting_attribute_value|}) assert-attribute: (".item-decl .type-contents-toggle", {"open": |toggle_attribute_value|}) } diff --git a/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml index 02d4ce8855fd..89c1a8b0e98e 100644 --- a/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml +++ b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml @@ -1,13 +1,14 @@ // This test ensures that the "Auto-hide item methods' documentation" setting is working as // expected. +include: "utils.goml" + define-function: ( "check-setting", [storage_value, setting_attribute_value, toggle_attribute_value], block { assert-local-storage: {"rustdoc-auto-hide-method-docs": |storage_value|} - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" + call-function: ("open-settings-menu", {}) assert-property: ("#auto-hide-method-docs", {"checked": |setting_attribute_value|}) assert-attribute: (".toggle.method-toggle", {"open": |toggle_attribute_value|}) } diff --git a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml index 4af1e829b31c..81c26bfb7f3a 100644 --- a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml +++ b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml @@ -1,12 +1,13 @@ // Checks that the setting "auto hide trait implementations" is working as expected. +include: "utils.goml" + define-function: ( "check-setting", [storage_value, setting_attribute_value, toggle_attribute_value], block { assert-local-storage: {"rustdoc-auto-hide-trait-implementations": |storage_value|} - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" + call-function: ("open-settings-menu", {}) assert-property: ("#auto-hide-trait-implementations", {"checked": |setting_attribute_value|}) assert-attribute: ("#trait-implementations-list > details", {"open": |toggle_attribute_value|}, ALL) } diff --git a/tests/rustdoc-gui/setting-go-to-only-result.goml b/tests/rustdoc-gui/setting-go-to-only-result.goml index 5a9c81e0b836..72c1e2bf59ca 100644 --- a/tests/rustdoc-gui/setting-go-to-only-result.goml +++ b/tests/rustdoc-gui/setting-go-to-only-result.goml @@ -1,12 +1,14 @@ -// Checks that the setting "Directly go to item in search if there is only one result " is working as expected. +// Checks that the setting "Directly go to item in search if there is only one result " is working +// as expected. + +include: "utils.goml" define-function: ( "check-setting", [storage_value, setting_attribute_value], block { assert-local-storage: {"rustdoc-go-to-only-result": |storage_value|} - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" + call-function: ("open-settings-menu", {}) assert-property: ("#go-to-only-result", {"checked": |setting_attribute_value|}) } ) @@ -25,8 +27,7 @@ wait-for: "#search" assert-document-property: ({"URL": "/lib2/index.html"}, CONTAINS) // Now we change its value. -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) click: "#go-to-only-result" assert-local-storage: {"rustdoc-go-to-only-result": "true"} diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index 7a163103b5ab..85994be468d3 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -1,20 +1,18 @@ // This test ensures that the settings menu display is working as expected and that // the settings page is also rendered as expected. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" show-text: true // needed when we check for colors below. // First, we check that the settings page doesn't exist. assert-false: "#settings" -// We now click on the settings button. -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) assert-css: ("#settings", {"display": "block"}) // Store the line margin to compare with the settings.html later. store-css: (".setting-line", {"margin": setting_line_margin}) // Let's close it by clicking on the same button. -click: "rustdoc-toolbar .settings-menu" -wait-for-css: ("#settings", {"display": "none"}) +call-function: ("close-settings-menu", {}) // Let's check that pressing "ESCAPE" is closing it. click: "rustdoc-toolbar .settings-menu" @@ -28,8 +26,7 @@ write: "test" // To be SURE that the search will be run. press-key: 'Enter' wait-for: "#alternative-display #search" -click: "rustdoc-toolbar .settings-menu" -wait-for-css: ("#settings", {"display": "block"}) +call-function: ("open-settings-menu", {}) // Ensure that the search is still displayed. wait-for: "#alternative-display #search" assert: "#main-content.hidden" @@ -41,8 +38,7 @@ set-local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false" // We reload the page so the local storage settings are being used. reload: -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) // We check that the "Use system theme" is disabled. assert-property: ("#theme-system-preference", {"checked": "false"}) diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index 1fa5521baac9..3183650b555a 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -65,8 +65,7 @@ define-function: ( "check-colors", [theme, color, background], block { - call-function: ("switch-theme-mobile", {"theme": |theme|}) - reload: + call-function: ("switch-theme", {"theme": |theme|}) // Open the sidebar menu. click: ".sidebar-menu-toggle" @@ -86,13 +85,3 @@ call-function: ("check-colors", { "color": "#c5c5c5", "background": "#14191f", }) -call-function: ("check-colors", { - "theme": "dark", - "color": "#ddd", - "background": "#505050", -}) -call-function: ("check-colors", { - "theme": "light", - "color": "black", - "background": "#F5F5F5", -}) diff --git a/tests/rustdoc-gui/sidebar-resize-close-popover.goml b/tests/rustdoc-gui/sidebar-resize-close-popover.goml index d3fea9b0f400..ac8f7e9c65fa 100644 --- a/tests/rustdoc-gui/sidebar-resize-close-popover.goml +++ b/tests/rustdoc-gui/sidebar-resize-close-popover.goml @@ -1,9 +1,9 @@ // Checks sidebar resizing close the Settings popover +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" assert-property: (".sidebar", {"clientWidth": "199"}) show-text: true -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) assert-css: ("#settings", {"display": "block"}) // normal resizing drag-and-drop: ((205, 100), (185, 100)) @@ -12,8 +12,7 @@ assert-css: ("#settings", {"display": "none"}) // Now same thing, but for source code go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) assert-css: ("#settings", {"display": "block"}) assert-property: (".sidebar", {"clientWidth": "49"}) drag-and-drop: ((52, 100), (185, 100)) diff --git a/tests/rustdoc-gui/sidebar-resize-setting.goml b/tests/rustdoc-gui/sidebar-resize-setting.goml index a4572c670f81..132f5f387b29 100644 --- a/tests/rustdoc-gui/sidebar-resize-setting.goml +++ b/tests/rustdoc-gui/sidebar-resize-setting.goml @@ -1,11 +1,11 @@ // Checks sidebar resizing stays synced with the setting +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" assert-property: (".sidebar", {"clientWidth": "199"}) show-text: true // Verify that the "hide" option is unchecked -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) assert-css: ("#settings", {"display": "block"}) assert-property: ("#hide-sidebar", {"checked": "false"}) press-key: "Escape" diff --git a/tests/rustdoc-gui/source-code-wrapping.goml b/tests/rustdoc-gui/source-code-wrapping.goml index c1fc2835c89a..6dc56672da80 100644 --- a/tests/rustdoc-gui/source-code-wrapping.goml +++ b/tests/rustdoc-gui/source-code-wrapping.goml @@ -1,4 +1,5 @@ // Checks that the interactions with the source code pages are working as expected. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" show-text: true set-window-size: (1000, 1000) @@ -13,8 +14,7 @@ define-function: ( ) store-size: (".rust code", {"width": width, "height": height}) -click: "main .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) call-function: ("click-code-wrapping", {"expected": "true"}) wait-for-size-false: (".rust code", {"width": |width|, "height": |height|}) store-size: (".rust code", {"width": new_width, "height": new_height}) @@ -28,8 +28,7 @@ assert-size: (".rust code", {"width": |width|, "height": |height|}) // Now let's check in docs code examples. go-to: "file://" + |DOC_PATH| + "/test_docs/trait_bounds/index.html" -click: "main .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) store-property: (".example-wrap .rust code", {"scrollWidth": rust_width, "scrollHeight": rust_height}) store-property: (".example-wrap .language-text code", {"scrollWidth": txt_width, "scrollHeight": txt_height}) diff --git a/tests/rustdoc-gui/theme-change.goml b/tests/rustdoc-gui/theme-change.goml index 3860596e3433..14b32baac57e 100644 --- a/tests/rustdoc-gui/theme-change.goml +++ b/tests/rustdoc-gui/theme-change.goml @@ -7,8 +7,7 @@ store-value: (background_light, "white") store-value: (background_dark, "#353535") store-value: (background_ayu, "#0f1419") -click: "rustdoc-toolbar .settings-menu" -wait-for: "#theme-ayu" +call-function: ("open-settings-menu", {}) click: "#theme-ayu" // should be the ayu theme so let's check the color. wait-for-css: ("body", { "background-color": |background_ayu| }) @@ -22,10 +21,6 @@ click: "#theme-dark" wait-for-css: ("body", { "background-color": |background_dark| }) assert-local-storage: { "rustdoc-theme": "dark" } -set-local-storage: { - "rustdoc-preferred-light-theme": "light", - "rustdoc-preferred-dark-theme": "light", -} go-to: "file://" + |DOC_PATH| + "/settings.html" wait-for: "#settings" @@ -75,8 +70,7 @@ store-value: (background_dark, "#353535") store-value: (background_ayu, "#0f1419") store-value: (background_custom_theme, "red") -click: "rustdoc-toolbar .settings-menu" -wait-for: "#theme-ayu" +call-function: ("open-settings-menu", {}) click: "#theme-ayu" // should be the ayu theme so let's check the color. wait-for-css: ("body", { "background-color": |background_ayu| }) diff --git a/tests/rustdoc-gui/theme-defaults.goml b/tests/rustdoc-gui/theme-defaults.goml index 12c17166e874..b7ba64a4adaa 100644 --- a/tests/rustdoc-gui/theme-defaults.goml +++ b/tests/rustdoc-gui/theme-defaults.goml @@ -1,7 +1,7 @@ // Ensure that the theme picker always starts with the actual defaults. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -click: "rustdoc-toolbar .settings-menu" -wait-for: "#theme-system-preference" +call-function: ("open-settings-menu", {}) assert: "#theme-system-preference:checked" assert: "#preferred-light-theme-light:checked" assert: "#preferred-dark-theme-dark:checked" @@ -16,8 +16,7 @@ set-local-storage: { "rustdoc-theme": "ayu" } go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -click: "rustdoc-toolbar .settings-menu" -wait-for: "#theme-system-preference" +call-function: ("open-settings-menu", {}) assert: "#theme-system-preference:checked" assert: "#preferred-light-theme-light:checked" assert-false: "#preferred-dark-theme-dark:checked" diff --git a/tests/rustdoc-gui/utils.goml b/tests/rustdoc-gui/utils.goml index a40f9fc6fdd7..c0625ead2f1a 100644 --- a/tests/rustdoc-gui/utils.goml +++ b/tests/rustdoc-gui/utils.goml @@ -1,11 +1,35 @@ // This file contains code to be re-used by other tests. +define-function: ( + "click-settings-button", + [], + block { + store-count: ("rustdoc-topbar", __topbar_count) + store-value: (__topbar_display, "none") + // The `rustdoc-topbar` element is created with JS when the window size is below a given + // size, however if the window size gets bigger again, the element isn't deleted, just + // hidden, so we need to check for both that it exists and is visible. + if: (|__topbar_count| != 0, block { + store-css: ("rustdoc-topbar", {"display": __topbar_display}) + }) + + // Open the settings menu. + if: (|__topbar_display| != "none", block { + // In mobile mode, this is instead the "topbar" the settings button is located into. + click: "rustdoc-topbar .settings-menu" + }) + else: block { + // We're not in mobile mode so clicking on the "normal" sidebar. + click: "rustdoc-toolbar .settings-menu" + } + } +) + define-function: ( "open-settings-menu", [], block { - // Open the settings menu. - click: "rustdoc-toolbar .settings-menu" + call-function: ("click-settings-button", {}) // Wait for the popover to appear... wait-for-css: ("#settings", {"display": "block"}) } @@ -15,7 +39,8 @@ define-function: ( "close-settings-menu", [], block { - click: "rustdoc-toolbar .settings-menu" + call-function: ("click-settings-button", {}) + // Wait for the popover to disappear... wait-for-css-false: ("#settings", {"display": "block"}) } ) @@ -34,24 +59,6 @@ define-function: ( }, ) -// FIXME: To be removed once `browser-ui-test` has conditions. -define-function: ( - "switch-theme-mobile", - [theme], - block { - // Open the settings menu. - click: "rustdoc-topbar .settings-menu" - // Wait for the popover to appear... - wait-for-css: ("#settings", {"display": "block"}) - // Change the setting. - click: "#theme-"+ |theme| - click: "rustdoc-topbar .settings-menu" - wait-for-css-false: ("#settings", {"display": "block"}) - // Ensure that the local storage was correctly updated. - assert-local-storage: {"rustdoc-theme": |theme|} - }, -) - define-function: ( "perform-search", [query], From 5466c6b25506f16fb6f030481d0e02a180c54a07 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Thu, 8 Jan 2026 14:48:56 -0600 Subject: [PATCH 1807/3801] Move feature(multiple_supertrait_upcastable) to the actual feature gates section (from the internal feature gates section) and give it a tracking issue. --- compiler/rustc_feature/src/unstable.rs | 4 ++-- .../feature-gate-multiple_supertrait_upcastable.stderr | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 387a01967ae5..8959bc586af7 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -233,8 +233,6 @@ declare_features! ( (internal, link_cfg, "1.14.0", None), /// Allows using `?Trait` trait bounds in more contexts. (internal, more_maybe_bounds, "1.82.0", None), - /// Allows the `multiple_supertrait_upcastable` lint. - (unstable, multiple_supertrait_upcastable, "1.69.0", None), /// Allow negative trait bounds. This is an internal-only feature for testing the trait solver! (internal, negative_bounds, "1.71.0", None), /// Set the maximum pattern complexity allowed (not limited by default). @@ -569,6 +567,8 @@ declare_features! ( (unstable, more_qualified_paths, "1.54.0", Some(86935)), /// The `movrs` target feature on x86. (unstable, movrs_target_feature, "1.88.0", Some(137976)), + /// Allows the `multiple_supertrait_upcastable` lint. + (unstable, multiple_supertrait_upcastable, "1.69.0", Some(150833)), /// Allows the `#[must_not_suspend]` attribute. (unstable, must_not_suspend, "1.57.0", Some(83310)), /// Allows `mut ref` and `mut ref mut` identifier patterns. diff --git a/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr b/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr index 0c7e68a599cd..0fd987e40289 100644 --- a/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr +++ b/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr @@ -5,6 +5,7 @@ LL | #![deny(multiple_supertrait_upcastable)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `multiple_supertrait_upcastable` lint is unstable + = note: see issue #150833 for more information = help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `#[warn(unknown_lints)]` on by default @@ -16,6 +17,7 @@ LL | #![warn(multiple_supertrait_upcastable)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `multiple_supertrait_upcastable` lint is unstable + = note: see issue #150833 for more information = help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date From 291d0a9a4b175b61b7c499551751ad5023b38bbc Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Tue, 6 Jan 2026 16:08:10 -0500 Subject: [PATCH 1808/3801] diagnostics: make implicit Sized bounds explicit in E0277 When a trait parameter depends upon Sized, the error message only referred to the full trait itself and didn't mention Sized. This makes the failure to implement Sized explicit. It also notes when the Sized trait bound is explicit or implicit. --- .../src/error_reporting/traits/suggestions.rs | 57 +++++++++++--- .../substs-ppaux.normal.stderr | 2 +- .../substs-ppaux.verbose.stderr | 2 +- tests/ui/error-codes/E0277-4.rs | 50 ++++++++++++ tests/ui/error-codes/E0277-4.stderr | 77 +++++++++++++++++++ tests/ui/recursion/issue-23122-2.stderr | 2 +- tests/ui/suggestions/slice-issue-87994.stderr | 10 +-- ...-iterator-deref-in-for-loop.current.stderr | 4 +- ...dyn-iterator-deref-in-for-loop.next.stderr | 4 +- tests/ui/traits/issue-18400.stderr | 2 +- 10 files changed, 186 insertions(+), 24 deletions(-) create mode 100644 tests/ui/error-codes/E0277-4.rs create mode 100644 tests/ui/error-codes/E0277-4.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 511e9e85b5f6..08a3fd4a0bb3 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1391,25 +1391,45 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // return early in the caller. let mut label = || { + // Special case `Sized` as `old_pred` will be the trait itself instead of + // `Sized` when the trait bound is the source of the error. + let is_sized = match obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => { + self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized) + } + _ => false, + }; + let msg = format!( "the trait bound `{}` is not satisfied", self.tcx.short_string(old_pred, err.long_ty_path()), ); - let self_ty_str = - self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path()); + let self_ty_str = self.tcx.short_string(old_pred.self_ty(), err.long_ty_path()); let trait_path = self .tcx .short_string(old_pred.print_modifiers_and_trait_path(), err.long_ty_path()); if has_custom_message { + let msg = if is_sized { + "the trait bound `Sized` is not satisfied".into() + } else { + msg + }; err.note(msg); } else { err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)]; } - err.span_label( - span, - format!("the trait `{trait_path}` is not implemented for `{self_ty_str}`"), - ); + if is_sized { + err.span_label( + span, + format!("the trait `Sized` is not implemented for `{self_ty_str}`"), + ); + } else { + err.span_label( + span, + format!("the trait `{trait_path}` is not implemented for `{self_ty_str}`"), + ); + } }; let mut sugg_prefixes = vec![]; @@ -3578,10 +3598,27 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { "unsatisfied trait bound introduced in this `derive` macro", ); } else if !data.span.is_dummy() && !data.span.overlaps(self_ty.span) { - spans.push_span_label( - data.span, - "unsatisfied trait bound introduced here", - ); + // `Sized` may be an explicit or implicit trait bound. If it is + // implicit, mention it as such. + if let Some(pred) = predicate.as_trait_clause() + && self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) + && self + .tcx + .generics_of(data.impl_or_alias_def_id) + .own_params + .iter() + .any(|param| self.tcx.def_span(param.def_id) == data.span) + { + spans.push_span_label( + data.span, + "unsatisfied trait bound implicitly introduced here", + ); + } else { + spans.push_span_label( + data.span, + "unsatisfied trait bound introduced here", + ); + } } err.span_note(spans, msg); point_at_assoc_type_restriction( diff --git a/tests/ui/associated-types/substs-ppaux.normal.stderr b/tests/ui/associated-types/substs-ppaux.normal.stderr index aa2aca7426e1..b1c9ce3f22b6 100644 --- a/tests/ui/associated-types/substs-ppaux.normal.stderr +++ b/tests/ui/associated-types/substs-ppaux.normal.stderr @@ -88,7 +88,7 @@ note: required for `str` to implement `Foo<'_, '_, u8>` LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {} | - ^^^^^^^^^^^^^^ ^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here error: aborting due to 5 previous errors diff --git a/tests/ui/associated-types/substs-ppaux.verbose.stderr b/tests/ui/associated-types/substs-ppaux.verbose.stderr index 23cf222a1d37..46cae5db56fd 100644 --- a/tests/ui/associated-types/substs-ppaux.verbose.stderr +++ b/tests/ui/associated-types/substs-ppaux.verbose.stderr @@ -88,7 +88,7 @@ note: required for `str` to implement `Foo<'?0, '?1, u8>` LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {} | - ^^^^^^^^^^^^^^ ^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here error: aborting due to 5 previous errors diff --git a/tests/ui/error-codes/E0277-4.rs b/tests/ui/error-codes/E0277-4.rs new file mode 100644 index 000000000000..ead57f00dde5 --- /dev/null +++ b/tests/ui/error-codes/E0277-4.rs @@ -0,0 +1,50 @@ +use std::fmt::Display; + +trait ImplicitTrait { + fn foo(&self); +} + +trait ExplicitTrait { + fn foo(&self); +} + +trait DisplayTrait { + fn foo(&self); +} + +trait UnimplementedTrait { + fn foo(&self); +} + +// Implicitly requires `T: Sized`. +impl ImplicitTrait for T { + fn foo(&self) {} +} + +// Explicitly requires `T: Sized`. +impl ExplicitTrait for T { + fn foo(&self) {} +} + +// Requires `T: Display`. +impl DisplayTrait for T { + fn foo(&self) {} +} + +fn main() { + // `[u8]` does not implement `Sized`. + let x: &[u8] = &[]; + ImplicitTrait::foo(x); + //~^ ERROR: the trait bound `[u8]: ImplicitTrait` is not satisfied [E0277] + ExplicitTrait::foo(x); + //~^ ERROR: the trait bound `[u8]: ExplicitTrait` is not satisfied [E0277] + + // `UnimplementedTrait` has no implementations. + UnimplementedTrait::foo(x); + //~^ ERROR: the trait bound `[u8]: UnimplementedTrait` is not satisfied [E0277] + + // `[u8; 0]` implements `Sized` but not `Display`. + let x: &[u8; 0] = &[]; + DisplayTrait::foo(x); + //~^ ERROR: the trait bound `[u8; 0]: DisplayTrait` is not satisfied [E0277] +} diff --git a/tests/ui/error-codes/E0277-4.stderr b/tests/ui/error-codes/E0277-4.stderr new file mode 100644 index 000000000000..f38b8146a63d --- /dev/null +++ b/tests/ui/error-codes/E0277-4.stderr @@ -0,0 +1,77 @@ +error[E0277]: the trait bound `[u8]: ImplicitTrait` is not satisfied + --> $DIR/E0277-4.rs:37:24 + | +LL | ImplicitTrait::foo(x); + | ------------------ ^ the trait `Sized` is not implemented for `[u8]` + | | + | required by a bound introduced by this call + | +note: required for `[u8]` to implement `ImplicitTrait` + --> $DIR/E0277-4.rs:20:9 + | +LL | impl ImplicitTrait for T { + | - ^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound implicitly introduced here +help: consider borrowing here + | +LL | ImplicitTrait::foo(&x); + | + +LL | ImplicitTrait::foo(&mut x); + | ++++ + +error[E0277]: the trait bound `[u8]: ExplicitTrait` is not satisfied + --> $DIR/E0277-4.rs:39:24 + | +LL | ExplicitTrait::foo(x); + | ------------------ ^ the trait `Sized` is not implemented for `[u8]` + | | + | required by a bound introduced by this call + | +note: required for `[u8]` to implement `ExplicitTrait` + --> $DIR/E0277-4.rs:25:16 + | +LL | impl ExplicitTrait for T { + | ----- ^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +help: consider borrowing here + | +LL | ExplicitTrait::foo(&x); + | + +LL | ExplicitTrait::foo(&mut x); + | ++++ + +error[E0277]: the trait bound `[u8]: UnimplementedTrait` is not satisfied + --> $DIR/E0277-4.rs:43:29 + | +LL | UnimplementedTrait::foo(x); + | ----------------------- ^ the trait `UnimplementedTrait` is not implemented for `[u8]` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/E0277-4.rs:15:1 + | +LL | trait UnimplementedTrait { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `[u8; 0]: DisplayTrait` is not satisfied + --> $DIR/E0277-4.rs:48:23 + | +LL | DisplayTrait::foo(x); + | ----------------- ^ the trait `std::fmt::Display` is not implemented for `[u8; 0]` + | | + | required by a bound introduced by this call + | +note: required for `[u8; 0]` to implement `DisplayTrait` + --> $DIR/E0277-4.rs:30:18 + | +LL | impl DisplayTrait for T { + | ------- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/recursion/issue-23122-2.stderr b/tests/ui/recursion/issue-23122-2.stderr index de402d65e6d6..39cd0eb35a63 100644 --- a/tests/ui/recursion/issue-23122-2.stderr +++ b/tests/ui/recursion/issue-23122-2.stderr @@ -11,7 +11,7 @@ note: required for `GetNext<<<<... as Next>::Next as Next>::Next as Next>::Next> LL | impl Next for GetNext { | - ^^^^ ^^^^^^^^^^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-23122-2.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/suggestions/slice-issue-87994.stderr b/tests/ui/suggestions/slice-issue-87994.stderr index 22ad5d352120..dd5c00af90b2 100644 --- a/tests/ui/suggestions/slice-issue-87994.stderr +++ b/tests/ui/suggestions/slice-issue-87994.stderr @@ -17,11 +17,10 @@ error[E0277]: `[i32]` is not an iterator --> $DIR/slice-issue-87994.rs:3:12 | LL | for _ in v[1..] { - | ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]` + | ^^^^^^ the trait `Sized` is not implemented for `[i32]` | - = note: the trait bound `[i32]: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `[i32]` to implement `IntoIterator` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider borrowing here | LL | for _ in &v[1..] { @@ -48,11 +47,10 @@ error[E0277]: `[K]` is not an iterator --> $DIR/slice-issue-87994.rs:11:13 | LL | for i2 in v2[1..] { - | ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]` + | ^^^^^^^ the trait `Sized` is not implemented for `[K]` | - = note: the trait bound `[K]: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `[K]` to implement `IntoIterator` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider borrowing here | LL | for i2 in &v2[1..] { diff --git a/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr b/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr index b5a9b82a93a3..0dd2ffffdfea 100644 --- a/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr +++ b/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr @@ -2,9 +2,9 @@ error[E0277]: `dyn Iterator` is not an iterator --> $DIR/dyn-iterator-deref-in-for-loop.rs:9:17 | LL | for item in *things { - | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + | ^^^^^^^ the trait `Sized` is not implemented for `dyn Iterator` | - = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `dyn Iterator` to implement `IntoIterator` help: consider mutably borrowing here | diff --git a/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr b/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr index b5a9b82a93a3..0dd2ffffdfea 100644 --- a/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr +++ b/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr @@ -2,9 +2,9 @@ error[E0277]: `dyn Iterator` is not an iterator --> $DIR/dyn-iterator-deref-in-for-loop.rs:9:17 | LL | for item in *things { - | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + | ^^^^^^^ the trait `Sized` is not implemented for `dyn Iterator` | - = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `dyn Iterator` to implement `IntoIterator` help: consider mutably borrowing here | diff --git a/tests/ui/traits/issue-18400.stderr b/tests/ui/traits/issue-18400.stderr index 146ba16397a2..af5519a15c23 100644 --- a/tests/ui/traits/issue-18400.stderr +++ b/tests/ui/traits/issue-18400.stderr @@ -11,7 +11,7 @@ note: required for `{integer}` to implement `Set<&[_]>` LL | impl<'a, T, S> Set<&'a [T]> for S where | - ^^^^^^^^^^^^ ^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here = note: 128 redundant requirements hidden = note: required for `{integer}` to implement `Set<&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[_]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]>` From 2b618ed6da5f0e55b2c00e32c767ba3dec6d7951 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 2 Jan 2026 00:57:49 -0800 Subject: [PATCH 1809/3801] rustdoc: Correctly resolve variant and struct fields on alias --- .../passes/collect_intra_doc_links.rs | 86 +++++++++++++------ .../intra-doc/adt-through-alias.rs | 54 +++++++++++- .../intra-doc/associated-items.rs | 9 +- 3 files changed, 113 insertions(+), 36 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 553d8636c85b..9e86781224d3 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -462,7 +462,7 @@ fn full_res(tcx: TyCtxt<'_>, (base, assoc_item): (Res, Option)) -> Res { } /// Given a primitive type, try to resolve an associated item. -fn resolve_primitive_associated_item<'tcx>( +fn resolve_primitive_inherent_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, prim_ty: PrimitiveType, ns: Namespace, @@ -597,33 +597,30 @@ fn resolve_associated_item<'tcx>( let item_ident = Ident::with_dummy_span(item_name); match root_res { - Res::Primitive(prim) => { - let items = resolve_primitive_associated_item(tcx, prim, ns, item_ident); - if !items.is_empty() { - items - // Inherent associated items take precedence over items that come from trait impls. - } else { - primitive_type_to_ty(tcx, prim) - .map(|ty| { - resolve_associated_trait_item(ty, module_id, item_ident, ns, tcx) - .iter() - .map(|item| (root_res, item.def_id)) - .collect::>() - }) - .unwrap_or_default() - } - } - Res::Def(DefKind::TyAlias, did) => { + Res::Def(DefKind::TyAlias, alias_did) => { // Resolve the link on the type the alias points to. // FIXME: if the associated item is defined directly on the type alias, // it will show up on its documentation page, we should link there instead. - let Some(res) = ty_to_res(tcx, tcx.type_of(did).instantiate_identity()) else { - return Vec::new(); + let Some(aliased_res) = ty_to_res(tcx, tcx.type_of(alias_did).instantiate_identity()) + else { + return vec![]; }; - resolve_associated_item(tcx, res, item_name, ns, disambiguator, module_id) + let aliased_items = + resolve_associated_item(tcx, aliased_res, item_name, ns, disambiguator, module_id); + aliased_items + .into_iter() + .map(|(res, assoc_did)| { + if is_assoc_item_on_alias_page(tcx, assoc_did) { + (root_res, assoc_did) + } else { + (res, assoc_did) + } + }) + .collect() } + Res::Primitive(prim) => resolve_assoc_on_primitive(tcx, prim, ns, item_ident, module_id), Res::Def(DefKind::Struct | DefKind::Union | DefKind::Enum, did) => { - resolve_assoc_on_adt(tcx, did, item_name, ns, disambiguator, module_id) + resolve_assoc_on_adt(tcx, did, item_ident, ns, disambiguator, module_id) } Res::Def(DefKind::ForeignTy, did) => { resolve_assoc_on_simple_type(tcx, did, item_ident, ns, module_id) @@ -640,23 +637,56 @@ fn resolve_associated_item<'tcx>( } } +// FIXME: make this fully complete by also including ALL inherent impls +// and trait impls BUT ONLY if on alias directly +fn is_assoc_item_on_alias_page<'tcx>(tcx: TyCtxt<'tcx>, assoc_did: DefId) -> bool { + match tcx.def_kind(assoc_did) { + // Variants and fields always have docs on the alias page. + DefKind::Variant | DefKind::Field => true, + _ => false, + } +} + +fn resolve_assoc_on_primitive<'tcx>( + tcx: TyCtxt<'tcx>, + prim: PrimitiveType, + ns: Namespace, + item_ident: Ident, + module_id: DefId, +) -> Vec<(Res, DefId)> { + let root_res = Res::Primitive(prim); + let items = resolve_primitive_inherent_assoc_item(tcx, prim, ns, item_ident); + if !items.is_empty() { + items + // Inherent associated items take precedence over items that come from trait impls. + } else { + primitive_type_to_ty(tcx, prim) + .map(|ty| { + resolve_associated_trait_item(ty, module_id, item_ident, ns, tcx) + .iter() + .map(|item| (root_res, item.def_id)) + .collect::>() + }) + .unwrap_or_default() + } +} + fn resolve_assoc_on_adt<'tcx>( tcx: TyCtxt<'tcx>, adt_def_id: DefId, - item_name: Symbol, + item_ident: Ident, ns: Namespace, disambiguator: Option, module_id: DefId, ) -> Vec<(Res, DefId)> { - debug!("looking for associated item named {item_name} for item {adt_def_id:?}"); + debug!("looking for associated item named {item_ident} for item {adt_def_id:?}"); let root_res = Res::from_def_id(tcx, adt_def_id); let adt_ty = tcx.type_of(adt_def_id).instantiate_identity(); let adt_def = adt_ty.ty_adt_def().expect("must be ADT"); - let item_ident = Ident::with_dummy_span(item_name); // Checks if item_name is a variant of the `SomeItem` enum if ns == TypeNS && adt_def.is_enum() { for variant in adt_def.variants() { - if variant.name == item_name { + if variant.name == item_ident.name { return vec![(root_res, variant.def_id)]; } } @@ -665,7 +695,7 @@ fn resolve_assoc_on_adt<'tcx>( if let Some(Disambiguator::Kind(DefKind::Field)) = disambiguator && (adt_def.is_struct() || adt_def.is_union()) { - return resolve_structfield(adt_def, item_name) + return resolve_structfield(adt_def, item_ident.name) .into_iter() .map(|did| (root_res, did)) .collect(); @@ -677,7 +707,7 @@ fn resolve_assoc_on_adt<'tcx>( } if ns == Namespace::ValueNS && (adt_def.is_struct() || adt_def.is_union()) { - return resolve_structfield(adt_def, item_name) + return resolve_structfield(adt_def, item_ident.name) .into_iter() .map(|did| (root_res, did)) .collect(); diff --git a/tests/rustdoc-html/intra-doc/adt-through-alias.rs b/tests/rustdoc-html/intra-doc/adt-through-alias.rs index 58e0f37edbab..6d5454bbaf20 100644 --- a/tests/rustdoc-html/intra-doc/adt-through-alias.rs +++ b/tests/rustdoc-html/intra-doc/adt-through-alias.rs @@ -3,12 +3,35 @@ //! [`TheStructAlias::the_field`] //! [`TheEnumAlias::TheVariant`] //! [`TheEnumAlias::TheVariant::the_field`] +//! [`TheUnionAlias::f1`] +//! +//! [`TheStruct::trait_`] +//! [`TheStructAlias::trait_`] +//! [`TheEnum::trait_`] +//! [`TheEnumAlias::trait_`] +//! +//! [`TheStruct::inherent`] +//! [`TheStructAlias::inherent`] +//! [`TheEnum::inherent`] +//! [`TheEnumAlias::inherent`] -// FIXME: this should resolve to the alias's version -//@ has foo/index.html '//a[@href="struct.TheStruct.html#structfield.the_field"]' 'TheStructAlias::the_field' -// FIXME: this should resolve to the alias's version -//@ has foo/index.html '//a[@href="enum.TheEnum.html#variant.TheVariant"]' 'TheEnumAlias::TheVariant' +//@ has foo/index.html '//a[@href="type.TheStructAlias.html#structfield.the_field"]' 'TheStructAlias::the_field' +//@ has foo/index.html '//a[@href="type.TheEnumAlias.html#variant.TheVariant"]' 'TheEnumAlias::TheVariant' //@ has foo/index.html '//a[@href="type.TheEnumAlias.html#variant.TheVariant.field.the_field"]' 'TheEnumAlias::TheVariant::the_field' +//@ has foo/index.html '//a[@href="type.TheUnionAlias.html#structfield.f1"]' 'TheUnionAlias::f1' + +//@ has foo/index.html '//a[@href="struct.TheStruct.html#method.trait_"]' 'TheStruct::trait_' +//@ has foo/index.html '//a[@href="struct.TheStruct.html#method.trait_"]' 'TheStructAlias::trait_' +//@ has foo/index.html '//a[@href="enum.TheEnum.html#method.trait_"]' 'TheEnum::trait_' +// FIXME: this one should resolve to alias since it's impl Trait for TheEnumAlias +//@ has foo/index.html '//a[@href="enum.TheEnum.html#method.trait_"]' 'TheEnumAlias::trait_' + +//@ has foo/index.html '//a[@href="struct.TheStruct.html#method.inherent"]' 'TheStruct::inherent' +// FIXME: this one should resolve to alias +//@ has foo/index.html '//a[@href="struct.TheStruct.html#method.inherent"]' 'TheStructAlias::inherent' +//@ has foo/index.html '//a[@href="enum.TheEnum.html#method.inherent"]' 'TheEnum::inherent' +// FIXME: this one should resolve to alias +//@ has foo/index.html '//a[@href="enum.TheEnum.html#method.inherent"]' 'TheEnumAlias::inherent' pub struct TheStruct { pub the_field: i32, @@ -22,4 +45,27 @@ pub enum TheEnum { pub type TheEnumAlias = TheEnum; +pub trait Trait { + fn trait_() {} +} + +impl Trait for TheStruct {} + +impl Trait for TheEnumAlias {} + +impl TheStruct { + pub fn inherent() {} +} + +impl TheEnumAlias { + pub fn inherent() {} +} + +pub union TheUnion { + pub f1: usize, + pub f2: isize, +} + +pub type TheUnionAlias = TheUnion; + fn main() {} diff --git a/tests/rustdoc-html/intra-doc/associated-items.rs b/tests/rustdoc-html/intra-doc/associated-items.rs index 84cfd06111df..b3bed196aded 100644 --- a/tests/rustdoc-html/intra-doc/associated-items.rs +++ b/tests/rustdoc-html/intra-doc/associated-items.rs @@ -13,7 +13,9 @@ pub fn foo() {} //@ has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.method"]' 'link from struct' //@ has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.clone"]' 'MyStruct::clone' //@ has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#associatedtype.Input"]' 'MyStruct::Input' -pub struct MyStruct { foo: () } +pub struct MyStruct { + foo: (), +} impl Clone for MyStruct { fn clone(&self) -> Self { @@ -31,8 +33,7 @@ impl T for MyStruct { /// [link from method][MyStruct::method] on method //@ has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.method"]' 'link from method' - fn method(i: usize) { - } + fn method(i: usize) {} } /// Ambiguity between which trait to use @@ -57,7 +58,7 @@ impl T2 for S { fn ambiguous_method() {} } -//@ has associated_items/enum.MyEnum.html '//a/@href' 'enum.MyEnum.html#variant.MyVariant' +//@ has associated_items/enum.MyEnum.html '//a/@href' 'type.MyEnumAlias.html#variant.MyVariant' /// Link to [MyEnumAlias::MyVariant] pub enum MyEnum { MyVariant, From d0d725133fb501ffb9f4572d2ea59454e68bb75a Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 8 Jan 2026 21:08:15 +0100 Subject: [PATCH 1810/3801] clean-up --- clippy_lints/src/floating_point_arithmetic.rs | 202 +++++++++--------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 5f022ba307ff..0a8f6c6ebf6b 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -1,6 +1,6 @@ use clippy_utils::consts::Constant::{F32, F64, Int}; use clippy_utils::consts::{ConstEvalCtxt, Constant}; -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; use clippy_utils::{ eq_expr_value, get_parent_expr, has_ambiguous_literal_in_expr, higher, is_in_const_context, is_no_std_crate, @@ -128,16 +128,16 @@ fn get_specialized_log_method(cx: &LateContext<'_>, base: &Expr<'_>, ctxt: Synta // Adds type suffixes and parenthesis to method receivers if necessary fn prepare_receiver_sugg<'a>(cx: &LateContext<'_>, mut expr: &'a Expr<'a>) -> Sugg<'a> { - let mut suggestion = Sugg::hir(cx, expr, ".."); + let mut suggestion = Sugg::hir(cx, expr, "_"); - if let ExprKind::Unary(UnOp::Neg, inner_expr) = &expr.kind { + if let ExprKind::Unary(UnOp::Neg, inner_expr) = expr.kind { expr = inner_expr; } if let ty::Float(float_ty) = cx.typeck_results().expr_ty(expr).kind() // if the expression is a float literal and it is unsuffixed then // add a suffix so the suggestion is valid and unambiguous - && let ExprKind::Lit(lit) = &expr.kind + && let ExprKind::Lit(lit) = expr.kind && let ast::LitKind::Float(sym, ast::LitFloatType::Unsuffixed) = lit.node { let op = format!( @@ -166,7 +166,7 @@ fn check_log_base(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, ar expr.span, "logarithm for bases 2, 10 and e can be computed more accurately", "consider using", - format!("{}.{method}()", Sugg::hir(cx, receiver, "..").maybe_paren()), + format!("{}.{method}()", Sugg::hir(cx, receiver, "_").maybe_paren()), Applicability::MachineApplicable, ); } @@ -251,25 +251,25 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: // Check argument if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0]) { + let recv = Sugg::hir(cx, receiver, "_").maybe_paren(); let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value { ( SUBOPTIMAL_FLOPS, "square-root of a number can be computed more efficiently and accurately", - format!("{}.sqrt()", Sugg::hir(cx, receiver, "..").maybe_paren()), + format!("{recv}.sqrt()"), ) } else if F32(1.0 / 3.0) == value || F64(1.0 / 3.0) == value { ( IMPRECISE_FLOPS, "cube-root of a number can be computed more accurately", - format!("{}.cbrt()", Sugg::hir(cx, receiver, "..").maybe_paren()), + format!("{recv}.cbrt()"), ) } else if let Some(exponent) = get_integer_from_float_constant(&value) { ( SUBOPTIMAL_FLOPS, "exponentiation with integer powers can be computed more efficiently", format!( - "{}.powi({})", - Sugg::hir(cx, receiver, "..").maybe_paren(), + "{recv}.powi({})", numeric_literal::format(&exponent.to_string(), None, false) ), ) @@ -311,31 +311,36 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: rhs, ) = parent.kind { - let other_addend = if lhs.hir_id == expr.hir_id { rhs } else { lhs }; - - // Negate expr if original code has subtraction and expr is on the right side - let maybe_neg_sugg = |expr, hir_id| { - let sugg = Sugg::hir(cx, expr, ".."); - if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id { - -sugg - } else { - sugg - } - }; - - span_lint_and_sugg( + span_lint_and_then( cx, SUBOPTIMAL_FLOPS, parent.span, "multiply and add expressions can be calculated more efficiently and accurately", - "consider using", - format!( - "{}.mul_add({}, {})", - Sugg::hir(cx, receiver, "..").maybe_paren(), - maybe_neg_sugg(receiver, expr.hir_id), - maybe_neg_sugg(other_addend, other_addend.hir_id), - ), - Applicability::MachineApplicable, + |diag| { + let other_addend = if lhs.hir_id == expr.hir_id { rhs } else { lhs }; + + // Negate expr if original code has subtraction and expr is on the right side + let maybe_neg_sugg = |expr, hir_id| { + let sugg = Sugg::hir(cx, expr, "_"); + if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id { + -sugg + } else { + sugg + } + }; + + diag.span_suggestion( + parent.span, + "consider using", + format!( + "{}.mul_add({}, {})", + Sugg::hir(cx, receiver, "_").maybe_paren(), + maybe_neg_sugg(receiver, expr.hir_id), + maybe_neg_sugg(other_addend, other_addend.hir_id), + ), + Applicability::MachineApplicable, + ); + }, ); } } @@ -370,14 +375,14 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option { { return Some(format!( "{}.hypot({})", - Sugg::hir(cx, lmul_lhs, "..").maybe_paren(), - Sugg::hir(cx, rmul_lhs, "..") + Sugg::hir(cx, lmul_lhs, "_").maybe_paren(), + Sugg::hir(cx, rmul_lhs, "_") )); } // check if expression of the form x.powi(2) + y.powi(2) - if let ExprKind::MethodCall(PathSegment { ident: lmethod, .. }, largs_0, [largs_1, ..], _) = &add_lhs.kind - && let ExprKind::MethodCall(PathSegment { ident: rmethod, .. }, rargs_0, [rargs_1, ..], _) = &add_rhs.kind + if let ExprKind::MethodCall(PathSegment { ident: lmethod, .. }, largs_0, [largs_1, ..], _) = add_lhs.kind + && let ExprKind::MethodCall(PathSegment { ident: rmethod, .. }, rargs_0, [rargs_1, ..], _) = add_rhs.kind && lmethod.name == sym::powi && rmethod.name == sym::powi && let ecx = ConstEvalCtxt::new(cx) @@ -388,8 +393,8 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option { { return Some(format!( "{}.hypot({})", - Sugg::hir(cx, largs_0, "..").maybe_paren(), - Sugg::hir(cx, rargs_0, "..") + Sugg::hir(cx, largs_0, "_").maybe_paren(), + Sugg::hir(cx, rargs_0, "_") )); } } @@ -421,7 +426,7 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { lhs, rhs, ) = expr.kind - && let ExprKind::MethodCall(path, self_arg, [], _) = &lhs.kind + && let ExprKind::MethodCall(path, self_arg, [], _) = lhs.kind && path.ident.name == sym::exp && cx.typeck_results().expr_ty(lhs).is_floating_point() && let Some(value) = ConstEvalCtxt::new(cx).eval(rhs) @@ -434,7 +439,7 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { expr.span, "(e.pow(x) - 1) can be computed more accurately", "consider using", - format!("{}.exp_m1()", Sugg::hir(cx, self_arg, "..").maybe_paren()), + format!("{}.exp_m1()", Sugg::hir(cx, self_arg, "_").maybe_paren()), Applicability::MachineApplicable, ); } @@ -447,7 +452,7 @@ fn is_float_mul_expr<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(&' }, lhs, rhs, - ) = &expr.kind + ) = expr.kind && cx.typeck_results().expr_ty(lhs).is_floating_point() && cx.typeck_results().expr_ty(rhs).is_floating_point() { @@ -476,18 +481,18 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) { } let maybe_neg_sugg = |expr| { - let sugg = Sugg::hir(cx, expr, ".."); + let sugg = Sugg::hir(cx, expr, "_"); if let BinOpKind::Sub = op { -sugg } else { sugg } }; let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) && cx.typeck_results().expr_ty(rhs).is_floating_point() { - (inner_lhs, Sugg::hir(cx, inner_rhs, ".."), maybe_neg_sugg(rhs)) + (inner_lhs, Sugg::hir(cx, inner_rhs, "_"), maybe_neg_sugg(rhs)) } else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) && cx.typeck_results().expr_ty(lhs).is_floating_point() { - (inner_lhs, maybe_neg_sugg(inner_rhs), Sugg::hir(cx, lhs, "..")) + (inner_lhs, maybe_neg_sugg(inner_rhs), Sugg::hir(cx, lhs, "_")) } else { return; }; @@ -558,12 +563,12 @@ fn is_zero(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> bool { /// If the two expressions are not negations of each other, then it /// returns None. fn are_negated<'a>(cx: &LateContext<'_>, expr1: &'a Expr<'a>, expr2: &'a Expr<'a>) -> Option<(bool, &'a Expr<'a>)> { - if let ExprKind::Unary(UnOp::Neg, expr1_negated) = &expr1.kind + if let ExprKind::Unary(UnOp::Neg, expr1_negated) = expr1.kind && eq_expr_value(cx, expr1_negated, expr2) { return Some((false, expr2)); } - if let ExprKind::Unary(UnOp::Neg, expr2_negated) = &expr2.kind + if let ExprKind::Unary(UnOp::Neg, expr2_negated) = expr2.kind && eq_expr_value(cx, expr1, expr2_negated) { return Some((true, expr1)); @@ -581,29 +586,20 @@ fn check_custom_abs(cx: &LateContext<'_>, expr: &Expr<'_>) { && let else_body_expr = peel_blocks(r#else) && let Some((if_expr_positive, body)) = are_negated(cx, if_body_expr, else_body_expr) { - let positive_abs_sugg = ( - "manual implementation of `abs` method", - format!("{}.abs()", Sugg::hir(cx, body, "..").maybe_paren()), - ); - let negative_abs_sugg = ( - "manual implementation of negation of `abs` method", - format!("-{}.abs()", Sugg::hir(cx, body, "..").maybe_paren()), - ); - let sugg = if is_testing_positive(cx, cond, body) { - if if_expr_positive { - positive_abs_sugg - } else { - negative_abs_sugg - } + let sugg_positive_abs = if is_testing_positive(cx, cond, body) { + if_expr_positive } else if is_testing_negative(cx, cond, body) { - if if_expr_positive { - negative_abs_sugg - } else { - positive_abs_sugg - } + !if_expr_positive } else { return; }; + let body = Sugg::hir(cx, body, "_").maybe_paren(); + let sugg = if sugg_positive_abs { + ("manual implementation of `abs` method", format!("{body}.abs()")) + } else { + #[rustfmt::skip] + ("manual implementation of negation of `abs` method", format!("-{body}.abs()")) + }; span_lint_and_sugg( cx, SUBOPTIMAL_FLOPS, @@ -637,10 +633,10 @@ fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) { }, lhs, rhs, - ) = &expr.kind + ) = expr.kind && are_same_base_logs(cx, lhs, rhs) - && let ExprKind::MethodCall(_, largs_self, ..) = &lhs.kind - && let ExprKind::MethodCall(_, rargs_self, ..) = &rhs.kind + && let ExprKind::MethodCall(_, largs_self, ..) = lhs.kind + && let ExprKind::MethodCall(_, rargs_self, ..) = rhs.kind { span_lint_and_sugg( cx, @@ -650,8 +646,8 @@ fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) { "consider using", format!( "{}.log({})", - Sugg::hir(cx, largs_self, "..").maybe_paren(), - Sugg::hir(cx, rargs_self, ".."), + Sugg::hir(cx, largs_self, "_").maybe_paren(), + Sugg::hir(cx, rargs_self, "_"), ), Applicability::MachineApplicable, ); @@ -665,14 +661,14 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { }, div_lhs, div_rhs, - ) = &expr.kind + ) = expr.kind && let ExprKind::Binary( Spanned { node: BinOpKind::Mul, .. }, mul_lhs, mul_rhs, - ) = &div_lhs.kind + ) = div_lhs.kind && let ecx = ConstEvalCtxt::new(cx) && let Some(rvalue) = ecx.eval(div_rhs) && let Some(lvalue) = ecx.eval(mul_rhs) @@ -681,48 +677,52 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue) && (F32(180_f32) == lvalue || F64(180_f64) == lvalue) { - let mut proposal = format!("{}.to_degrees()", Sugg::hir(cx, mul_lhs, "..").maybe_paren()); - if let ExprKind::Lit(literal) = mul_lhs.kind - && let ast::LitKind::Float(ref value, float_type) = literal.node - && float_type == ast::LitFloatType::Unsuffixed - { - if value.as_str().ends_with('.') { - proposal = format!("{}0_f64.to_degrees()", Sugg::hir(cx, mul_lhs, "..")); - } else { - proposal = format!("{}_f64.to_degrees()", Sugg::hir(cx, mul_lhs, "..")); - } - } - span_lint_and_sugg( + span_lint_and_then( cx, SUBOPTIMAL_FLOPS, expr.span, "conversion to degrees can be done more accurately", - "consider using", - proposal, - Applicability::MachineApplicable, + |diag| { + let recv = Sugg::hir(cx, mul_lhs, "num"); + let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind + && let ast::LitKind::Float(ref value, float_type) = literal.node + && float_type == ast::LitFloatType::Unsuffixed + { + if value.as_str().ends_with('.') { + format!("{recv}0_f64.to_degrees()") + } else { + format!("{recv}_f64.to_degrees()") + } + } else { + format!("{}.to_degrees()", recv.maybe_paren()) + }; + diag.span_suggestion(expr.span, "consider using", proposal, Applicability::MachineApplicable); + }, ); } else if (F32(180_f32) == rvalue || F64(180_f64) == rvalue) && (F32(f32_consts::PI) == lvalue || F64(f64_consts::PI) == lvalue) { - let mut proposal = format!("{}.to_radians()", Sugg::hir(cx, mul_lhs, "..").maybe_paren()); - if let ExprKind::Lit(literal) = mul_lhs.kind - && let ast::LitKind::Float(ref value, float_type) = literal.node - && float_type == ast::LitFloatType::Unsuffixed - { - if value.as_str().ends_with('.') { - proposal = format!("{}0_f64.to_radians()", Sugg::hir(cx, mul_lhs, "..")); - } else { - proposal = format!("{}_f64.to_radians()", Sugg::hir(cx, mul_lhs, "..")); - } - } - span_lint_and_sugg( + span_lint_and_then( cx, SUBOPTIMAL_FLOPS, expr.span, "conversion to radians can be done more accurately", - "consider using", - proposal, - Applicability::MachineApplicable, + |diag| { + let recv = Sugg::hir(cx, mul_lhs, "num"); + let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind + && let ast::LitKind::Float(ref value, float_type) = literal.node + && float_type == ast::LitFloatType::Unsuffixed + { + if value.as_str().ends_with('.') { + format!("{recv}0_f64.to_radians()") + } else { + format!("{recv}_f64.to_radians()") + } + } else { + format!("{}.to_radians()", recv.maybe_paren()) + }; + diag.span_suggestion(expr.span, "consider using", proposal, Applicability::MachineApplicable); + }, ); } } @@ -735,7 +735,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { return; } - if let ExprKind::MethodCall(path, receiver, args, _) = &expr.kind { + if let ExprKind::MethodCall(path, receiver, args, _) = expr.kind { let recv_ty = cx.typeck_results().expr_ty(receiver); if recv_ty.is_floating_point() && !is_no_std_crate(cx) && cx.ty_based_def(expr).opt_parent(cx).is_impl(cx) { From eb101b1d2a2b7ee1407935ba8c5bee36ac9ee31d Mon Sep 17 00:00:00 2001 From: Paul Mabileau Date: Thu, 18 Dec 2025 12:55:04 +0100 Subject: [PATCH 1811/3801] Fix(lib/win/thread): Ensure `Sleep`'s usage passes over the requested duration under Win7 Fixes #149935. See the added comment for more details. Signed-off-by: Paul Mabileau --- library/std/src/sys/thread/windows.rs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/thread/windows.rs b/library/std/src/sys/thread/windows.rs index 6a21b11e0312..ea18572489ee 100644 --- a/library/std/src/sys/thread/windows.rs +++ b/library/std/src/sys/thread/windows.rs @@ -8,7 +8,7 @@ use crate::sys::pal::time::WaitableTimer; use crate::sys::pal::{dur2timeout, to_u16s}; use crate::sys::{FromInner, c, stack_overflow}; use crate::thread::ThreadInit; -use crate::time::Duration; +use crate::time::{Duration, Instant}; use crate::{io, ptr}; pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; @@ -120,11 +120,28 @@ pub fn sleep(dur: Duration) { timer.set(dur)?; timer.wait() } + // Directly forward to `Sleep` for its zero duration behavior when indeed + // zero in order to skip the `Instant::now` calls, useless in this case. + if dur.is_zero() { + unsafe { c::Sleep(0) }; // Attempt to use high-precision sleep (Windows 10, version 1803+). - // On error fallback to the standard `Sleep` function. - // Also preserves the zero duration behavior of `Sleep`. - if dur.is_zero() || high_precision_sleep(dur).is_err() { - unsafe { c::Sleep(dur2timeout(dur)) } + // On error, fallback to the standard `Sleep` function. + } else if high_precision_sleep(dur).is_err() { + let start = Instant::now(); + unsafe { c::Sleep(dur2timeout(dur)) }; + + // See #149935: `Sleep` under Windows 7 and probably 8 as well seems a + // bit buggy for us as it can last less than the requested time while + // our API is meant to guarantee that. This is fixed by measuring the + // effective time difference and if needed, sleeping a bit more in + // order to ensure the duration is always exceeded. A fixed single + // millisecond works because `Sleep` operates based on a system-wide + // (until Windows 10 2004 that makes it process-local) interrupt timer + // that counts in "tick" units of ~15ms by default: a 1ms timeout + // therefore passes the next tick boundary. + if start.elapsed() < dur { + unsafe { c::Sleep(1) }; + } } } From cb9a079f608e6fed49a9303ff68ecca322e5b06b Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 8 Jan 2026 21:24:50 +0100 Subject: [PATCH 1812/3801] fix(float_point_arithmetic): respect reduced applicability --- clippy_lints/src/floating_point_arithmetic.rs | 142 ++++++++++-------- 1 file changed, 76 insertions(+), 66 deletions(-) diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 0a8f6c6ebf6b..64a2af38a108 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -127,8 +127,8 @@ fn get_specialized_log_method(cx: &LateContext<'_>, base: &Expr<'_>, ctxt: Synta } // Adds type suffixes and parenthesis to method receivers if necessary -fn prepare_receiver_sugg<'a>(cx: &LateContext<'_>, mut expr: &'a Expr<'a>) -> Sugg<'a> { - let mut suggestion = Sugg::hir(cx, expr, "_"); +fn prepare_receiver_sugg<'a>(cx: &LateContext<'_>, mut expr: &'a Expr<'a>, app: &mut Applicability) -> Sugg<'a> { + let mut suggestion = Sugg::hir_with_applicability(cx, expr, "_", app); if let ExprKind::Unary(UnOp::Neg, inner_expr) = expr.kind { expr = inner_expr; @@ -160,14 +160,16 @@ fn prepare_receiver_sugg<'a>(cx: &LateContext<'_>, mut expr: &'a Expr<'a>) -> Su fn check_log_base(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) { if let Some(method) = get_specialized_log_method(cx, &args[0], expr.span.ctxt()) { - span_lint_and_sugg( + span_lint_and_then( cx, SUBOPTIMAL_FLOPS, expr.span, "logarithm for bases 2, 10 and e can be computed more accurately", - "consider using", - format!("{}.{method}()", Sugg::hir(cx, receiver, "_").maybe_paren()), - Applicability::MachineApplicable, + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, receiver, "_", &mut app).maybe_paren(); + diag.span_suggestion(expr.span, "consider using", format!("{recv}.{method}()"), app); + }, ); } } @@ -190,14 +192,16 @@ fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) { _ => return, }; - span_lint_and_sugg( + span_lint_and_then( cx, IMPRECISE_FLOPS, expr.span, "ln(1 + x) can be computed more accurately", - "consider using", - format!("{}.ln_1p()", prepare_receiver_sugg(cx, recv)), - Applicability::MachineApplicable, + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = prepare_receiver_sugg(cx, recv, &mut app); + diag.span_suggestion(expr.span, "consider using", format!("{recv}.ln_1p()"), app); + }, ); } } @@ -238,20 +242,23 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: None } { - span_lint_and_sugg( + span_lint_and_then( cx, SUBOPTIMAL_FLOPS, expr.span, "exponent for bases 2 and e can be computed more accurately", - "consider using", - format!("{}.{method}()", prepare_receiver_sugg(cx, &args[0])), - Applicability::MachineApplicable, + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = prepare_receiver_sugg(cx, &args[0], &mut app); + diag.span_suggestion(expr.span, "consider using", format!("{recv}.{method}()"), app); + }, ); } // Check argument if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0]) { - let recv = Sugg::hir(cx, receiver, "_").maybe_paren(); + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, receiver, "_", &mut app).maybe_paren(); let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value { ( SUBOPTIMAL_FLOPS, @@ -277,15 +284,7 @@ fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: return; }; - span_lint_and_sugg( - cx, - lint, - expr.span, - help, - "consider using", - suggestion, - Applicability::MachineApplicable, - ); + span_lint_and_sugg(cx, lint, expr.span, help, "consider using", suggestion, app); } } @@ -297,7 +296,8 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: if let Some(grandparent) = get_parent_expr(cx, parent) && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = grandparent.kind && method.name == sym::sqrt - && detect_hypot(cx, receiver).is_some() + // we don't care about the applicability as this is an early-return condition + && detect_hypot(cx, receiver, &mut Applicability::Unspecified).is_some() { return; } @@ -320,8 +320,8 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: let other_addend = if lhs.hir_id == expr.hir_id { rhs } else { lhs }; // Negate expr if original code has subtraction and expr is on the right side - let maybe_neg_sugg = |expr, hir_id| { - let sugg = Sugg::hir(cx, expr, "_"); + let maybe_neg_sugg = |expr, hir_id, app: &mut _| { + let sugg = Sugg::hir_with_applicability(cx, expr, "_", app); if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id { -sugg } else { @@ -329,16 +329,17 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: } }; + let mut app = Applicability::MachineApplicable; diag.span_suggestion( parent.span, "consider using", format!( "{}.mul_add({}, {})", - Sugg::hir(cx, receiver, "_").maybe_paren(), - maybe_neg_sugg(receiver, expr.hir_id), - maybe_neg_sugg(other_addend, other_addend.hir_id), + Sugg::hir_with_applicability(cx, receiver, "_", &mut app).maybe_paren(), + maybe_neg_sugg(receiver, expr.hir_id, &mut app), + maybe_neg_sugg(other_addend, other_addend.hir_id, &mut app), ), - Applicability::MachineApplicable, + app, ); }, ); @@ -346,7 +347,7 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: } } -fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option { +fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>, app: &mut Applicability) -> Option { if let ExprKind::Binary( Spanned { node: BinOpKind::Add, .. @@ -375,8 +376,8 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option { { return Some(format!( "{}.hypot({})", - Sugg::hir(cx, lmul_lhs, "_").maybe_paren(), - Sugg::hir(cx, rmul_lhs, "_") + Sugg::hir_with_applicability(cx, lmul_lhs, "_", app).maybe_paren(), + Sugg::hir_with_applicability(cx, rmul_lhs, "_", app) )); } @@ -393,8 +394,8 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option { { return Some(format!( "{}.hypot({})", - Sugg::hir(cx, largs_0, "_").maybe_paren(), - Sugg::hir(cx, rargs_0, "_") + Sugg::hir_with_applicability(cx, largs_0, "_", app).maybe_paren(), + Sugg::hir_with_applicability(cx, rargs_0, "_", app) )); } } @@ -403,7 +404,8 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option { } fn check_hypot(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) { - if let Some(message) = detect_hypot(cx, receiver) { + let mut app = Applicability::MachineApplicable; + if let Some(message) = detect_hypot(cx, receiver, &mut app) { span_lint_and_sugg( cx, IMPRECISE_FLOPS, @@ -411,7 +413,7 @@ fn check_hypot(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) { "hypotenuse can be computed more accurately", "consider using", message, - Applicability::MachineApplicable, + app, ); } } @@ -433,14 +435,16 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { && (F32(1.0) == value || F64(1.0) == value) && cx.typeck_results().expr_ty(self_arg).is_floating_point() { - span_lint_and_sugg( + span_lint_and_then( cx, IMPRECISE_FLOPS, expr.span, "(e.pow(x) - 1) can be computed more accurately", - "consider using", - format!("{}.exp_m1()", Sugg::hir(cx, self_arg, "_").maybe_paren()), - Applicability::MachineApplicable, + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, self_arg, "_", &mut app).maybe_paren(); + diag.span_suggestion(expr.span, "consider using", format!("{recv}.exp_m1()"), app); + }, ); } } @@ -475,24 +479,34 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) { if let Some(parent) = get_parent_expr(cx, expr) && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = parent.kind && method.name == sym::sqrt - && detect_hypot(cx, receiver).is_some() + // we don't care about the applicability as this is an early-return condition + && detect_hypot(cx, receiver, &mut Applicability::Unspecified).is_some() { return; } - let maybe_neg_sugg = |expr| { - let sugg = Sugg::hir(cx, expr, "_"); + let maybe_neg_sugg = |expr, app: &mut _| { + let sugg = Sugg::hir_with_applicability(cx, expr, "_", app); if let BinOpKind::Sub = op { -sugg } else { sugg } }; + let mut app = Applicability::MachineApplicable; let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) && cx.typeck_results().expr_ty(rhs).is_floating_point() { - (inner_lhs, Sugg::hir(cx, inner_rhs, "_"), maybe_neg_sugg(rhs)) + ( + inner_lhs, + Sugg::hir_with_applicability(cx, inner_rhs, "_", &mut app), + maybe_neg_sugg(rhs, &mut app), + ) } else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) && cx.typeck_results().expr_ty(lhs).is_floating_point() { - (inner_lhs, maybe_neg_sugg(inner_rhs), Sugg::hir(cx, lhs, "_")) + ( + inner_lhs, + maybe_neg_sugg(inner_rhs, &mut app), + Sugg::hir_with_applicability(cx, lhs, "_", &mut app), + ) } else { return; }; @@ -511,8 +525,8 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) { expr.span, "multiply and add expressions can be calculated more efficiently and accurately", "consider using", - format!("{}.mul_add({arg1}, {arg2})", prepare_receiver_sugg(cx, recv)), - Applicability::MachineApplicable, + format!("{}.mul_add({arg1}, {arg2})", prepare_receiver_sugg(cx, recv, &mut app)), + app, ); } } @@ -593,22 +607,15 @@ fn check_custom_abs(cx: &LateContext<'_>, expr: &Expr<'_>) { } else { return; }; - let body = Sugg::hir(cx, body, "_").maybe_paren(); + let mut app = Applicability::MachineApplicable; + let body = Sugg::hir_with_applicability(cx, body, "_", &mut app).maybe_paren(); let sugg = if sugg_positive_abs { ("manual implementation of `abs` method", format!("{body}.abs()")) } else { #[rustfmt::skip] ("manual implementation of negation of `abs` method", format!("-{body}.abs()")) }; - span_lint_and_sugg( - cx, - SUBOPTIMAL_FLOPS, - expr.span, - sugg.0, - "try", - sugg.1, - Applicability::MachineApplicable, - ); + span_lint_and_sugg(cx, SUBOPTIMAL_FLOPS, expr.span, sugg.0, "try", sugg.1, app); } } @@ -638,6 +645,7 @@ fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) { && let ExprKind::MethodCall(_, largs_self, ..) = lhs.kind && let ExprKind::MethodCall(_, rargs_self, ..) = rhs.kind { + let mut app = Applicability::MachineApplicable; span_lint_and_sugg( cx, SUBOPTIMAL_FLOPS, @@ -646,10 +654,10 @@ fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) { "consider using", format!( "{}.log({})", - Sugg::hir(cx, largs_self, "_").maybe_paren(), - Sugg::hir(cx, rargs_self, "_"), + Sugg::hir_with_applicability(cx, largs_self, "_", &mut app).maybe_paren(), + Sugg::hir_with_applicability(cx, rargs_self, "_", &mut app), ), - Applicability::MachineApplicable, + app, ); } } @@ -683,7 +691,8 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { expr.span, "conversion to degrees can be done more accurately", |diag| { - let recv = Sugg::hir(cx, mul_lhs, "num"); + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, mul_lhs, "num", &mut app); let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind && let ast::LitKind::Float(ref value, float_type) = literal.node && float_type == ast::LitFloatType::Unsuffixed @@ -696,7 +705,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { } else { format!("{}.to_degrees()", recv.maybe_paren()) }; - diag.span_suggestion(expr.span, "consider using", proposal, Applicability::MachineApplicable); + diag.span_suggestion(expr.span, "consider using", proposal, app); }, ); } else if (F32(180_f32) == rvalue || F64(180_f64) == rvalue) @@ -708,7 +717,8 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { expr.span, "conversion to radians can be done more accurately", |diag| { - let recv = Sugg::hir(cx, mul_lhs, "num"); + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, mul_lhs, "num", &mut app); let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind && let ast::LitKind::Float(ref value, float_type) = literal.node && float_type == ast::LitFloatType::Unsuffixed @@ -721,7 +731,7 @@ fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { } else { format!("{}.to_radians()", recv.maybe_paren()) }; - diag.span_suggestion(expr.span, "consider using", proposal, Applicability::MachineApplicable); + diag.span_suggestion(expr.span, "consider using", proposal, app); }, ); } From 7a377d66727e441c8472c18cb7aab3a597be1639 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 8 Jan 2026 22:03:26 +0100 Subject: [PATCH 1813/3801] move `floating_point_arithmetic.rs` to `floating_point_arithmetic/mod.rs` --- .../mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clippy_lints/src/{floating_point_arithmetic.rs => floating_point_arithmetic/mod.rs} (100%) diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic/mod.rs similarity index 100% rename from clippy_lints/src/floating_point_arithmetic.rs rename to clippy_lints/src/floating_point_arithmetic/mod.rs From 44a41041fcb00f6fd1f76beeef53db936d39e31d Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Thu, 8 Jan 2026 22:46:58 +0100 Subject: [PATCH 1814/3801] extract each check into a separate module --- .../floating_point_arithmetic/custom_abs.rs | 100 +++ .../src/floating_point_arithmetic/expm1.rs | 42 ++ .../src/floating_point_arithmetic/hypot.rs | 82 +++ .../src/floating_point_arithmetic/lib.rs | 42 ++ .../src/floating_point_arithmetic/ln1p.rs | 41 ++ .../src/floating_point_arithmetic/log_base.rs | 44 ++ .../floating_point_arithmetic/log_division.rs | 52 ++ .../src/floating_point_arithmetic/mod.rs | 678 +----------------- .../src/floating_point_arithmetic/mul_add.rs | 94 +++ .../src/floating_point_arithmetic/powf.rs | 94 +++ .../src/floating_point_arithmetic/powi.rs | 70 ++ .../src/floating_point_arithmetic/radians.rs | 89 +++ 12 files changed, 774 insertions(+), 654 deletions(-) create mode 100644 clippy_lints/src/floating_point_arithmetic/custom_abs.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/expm1.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/hypot.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/lib.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/ln1p.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/log_base.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/log_division.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/mul_add.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/powf.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/powi.rs create mode 100644 clippy_lints/src/floating_point_arithmetic/radians.rs diff --git a/clippy_lints/src/floating_point_arithmetic/custom_abs.rs b/clippy_lints/src/floating_point_arithmetic/custom_abs.rs new file mode 100644 index 000000000000..d12a32e15881 --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/custom_abs.rs @@ -0,0 +1,100 @@ +use clippy_utils::consts::ConstEvalCtxt; +use clippy_utils::consts::Constant::{F32, F64, Int}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::sugg::Sugg; +use clippy_utils::{eq_expr_value, higher, peel_blocks}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; +use rustc_lint::LateContext; +use rustc_span::SyntaxContext; +use rustc_span::source_map::Spanned; + +use super::SUBOPTIMAL_FLOPS; + +/// Returns true iff expr is an expression which tests whether or not +/// test is positive or an expression which tests whether or not test +/// is nonnegative. +/// Used for check-custom-abs function below +fn is_testing_positive(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool { + if let ExprKind::Binary(Spanned { node: op, .. }, left, right) = expr.kind { + match op { + BinOpKind::Gt | BinOpKind::Ge => is_zero(cx, right, expr.span.ctxt()) && eq_expr_value(cx, left, test), + BinOpKind::Lt | BinOpKind::Le => is_zero(cx, left, expr.span.ctxt()) && eq_expr_value(cx, right, test), + _ => false, + } + } else { + false + } +} + +/// See [`is_testing_positive`] +fn is_testing_negative(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool { + if let ExprKind::Binary(Spanned { node: op, .. }, left, right) = expr.kind { + match op { + BinOpKind::Gt | BinOpKind::Ge => is_zero(cx, left, expr.span.ctxt()) && eq_expr_value(cx, right, test), + BinOpKind::Lt | BinOpKind::Le => is_zero(cx, right, expr.span.ctxt()) && eq_expr_value(cx, left, test), + _ => false, + } + } else { + false + } +} + +/// Returns true iff expr is some zero literal +fn is_zero(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> bool { + match ConstEvalCtxt::new(cx).eval_local(expr, ctxt) { + Some(Int(i)) => i == 0, + Some(F32(f)) => f == 0.0, + Some(F64(f)) => f == 0.0, + _ => false, + } +} + +/// If the two expressions are negations of each other, then it returns +/// a tuple, in which the first element is true iff expr1 is the +/// positive expressions, and the second element is the positive +/// one of the two expressions +/// If the two expressions are not negations of each other, then it +/// returns None. +fn are_negated<'a>(cx: &LateContext<'_>, expr1: &'a Expr<'a>, expr2: &'a Expr<'a>) -> Option<(bool, &'a Expr<'a>)> { + if let ExprKind::Unary(UnOp::Neg, expr1_negated) = expr1.kind + && eq_expr_value(cx, expr1_negated, expr2) + { + return Some((false, expr2)); + } + if let ExprKind::Unary(UnOp::Neg, expr2_negated) = expr2.kind + && eq_expr_value(cx, expr1, expr2_negated) + { + return Some((true, expr1)); + } + None +} + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { + if let Some(higher::If { + cond, + then, + r#else: Some(r#else), + }) = higher::If::hir(expr) + && let if_body_expr = peel_blocks(then) + && let else_body_expr = peel_blocks(r#else) + && let Some((if_expr_positive, body)) = are_negated(cx, if_body_expr, else_body_expr) + { + let sugg_positive_abs = if is_testing_positive(cx, cond, body) { + if_expr_positive + } else if is_testing_negative(cx, cond, body) { + !if_expr_positive + } else { + return; + }; + let mut app = Applicability::MachineApplicable; + let body = Sugg::hir_with_applicability(cx, body, "_", &mut app).maybe_paren(); + let sugg = if sugg_positive_abs { + ("manual implementation of `abs` method", format!("{body}.abs()")) + } else { + #[rustfmt::skip] + ("manual implementation of negation of `abs` method", format!("-{body}.abs()")) + }; + span_lint_and_sugg(cx, SUBOPTIMAL_FLOPS, expr.span, sugg.0, "try", sugg.1, app); + } +} diff --git a/clippy_lints/src/floating_point_arithmetic/expm1.rs b/clippy_lints/src/floating_point_arithmetic/expm1.rs new file mode 100644 index 000000000000..9a4c97569308 --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/expm1.rs @@ -0,0 +1,42 @@ +use clippy_utils::consts::ConstEvalCtxt; +use clippy_utils::consts::Constant::{F32, F64}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::sugg::Sugg; +use clippy_utils::sym; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_span::source_map::Spanned; + +use super::IMPRECISE_FLOPS; + +// TODO: Lint expressions of the form `x.exp() - y` where y > 1 +// and suggest usage of `x.exp_m1() - (y - 1)` instead +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Sub, .. + }, + lhs, + rhs, + ) = expr.kind + && let ExprKind::MethodCall(path, self_arg, [], _) = lhs.kind + && path.ident.name == sym::exp + && cx.typeck_results().expr_ty(lhs).is_floating_point() + && let Some(value) = ConstEvalCtxt::new(cx).eval(rhs) + && (F32(1.0) == value || F64(1.0) == value) + && cx.typeck_results().expr_ty(self_arg).is_floating_point() + { + span_lint_and_then( + cx, + IMPRECISE_FLOPS, + expr.span, + "(e.pow(x) - 1) can be computed more accurately", + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, self_arg, "_", &mut app).maybe_paren(); + diag.span_suggestion(expr.span, "consider using", format!("{recv}.exp_m1()"), app); + }, + ); + } +} diff --git a/clippy_lints/src/floating_point_arithmetic/hypot.rs b/clippy_lints/src/floating_point_arithmetic/hypot.rs new file mode 100644 index 000000000000..49f8ba4bf825 --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/hypot.rs @@ -0,0 +1,82 @@ +use clippy_utils::consts::ConstEvalCtxt; +use clippy_utils::consts::Constant::Int; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::sugg::Sugg; +use clippy_utils::{eq_expr_value, sym}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment}; +use rustc_lint::LateContext; +use rustc_span::source_map::Spanned; + +use super::IMPRECISE_FLOPS; + +pub(super) fn detect(cx: &LateContext<'_>, receiver: &Expr<'_>, app: &mut Applicability) -> Option { + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Add, .. + }, + add_lhs, + add_rhs, + ) = receiver.kind + { + // check if expression of the form x * x + y * y + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Mul, .. + }, + lmul_lhs, + lmul_rhs, + ) = add_lhs.kind + && let ExprKind::Binary( + Spanned { + node: BinOpKind::Mul, .. + }, + rmul_lhs, + rmul_rhs, + ) = add_rhs.kind + && eq_expr_value(cx, lmul_lhs, lmul_rhs) + && eq_expr_value(cx, rmul_lhs, rmul_rhs) + { + return Some(format!( + "{}.hypot({})", + Sugg::hir_with_applicability(cx, lmul_lhs, "_", app).maybe_paren(), + Sugg::hir_with_applicability(cx, rmul_lhs, "_", app) + )); + } + + // check if expression of the form x.powi(2) + y.powi(2) + if let ExprKind::MethodCall(PathSegment { ident: lmethod, .. }, largs_0, [largs_1, ..], _) = add_lhs.kind + && let ExprKind::MethodCall(PathSegment { ident: rmethod, .. }, rargs_0, [rargs_1, ..], _) = add_rhs.kind + && lmethod.name == sym::powi + && rmethod.name == sym::powi + && let ecx = ConstEvalCtxt::new(cx) + && let Some(lvalue) = ecx.eval(largs_1) + && let Some(rvalue) = ecx.eval(rargs_1) + && Int(2) == lvalue + && Int(2) == rvalue + { + return Some(format!( + "{}.hypot({})", + Sugg::hir_with_applicability(cx, largs_0, "_", app).maybe_paren(), + Sugg::hir_with_applicability(cx, rargs_0, "_", app) + )); + } + } + + None +} + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) { + let mut app = Applicability::MachineApplicable; + if let Some(message) = detect(cx, receiver, &mut app) { + span_lint_and_sugg( + cx, + IMPRECISE_FLOPS, + expr.span, + "hypotenuse can be computed more accurately", + "consider using", + message, + app, + ); + } +} diff --git a/clippy_lints/src/floating_point_arithmetic/lib.rs b/clippy_lints/src/floating_point_arithmetic/lib.rs new file mode 100644 index 000000000000..3fa041f97802 --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/lib.rs @@ -0,0 +1,42 @@ +use clippy_utils::sugg::Sugg; +use rustc_ast::ast; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, UnOp}; +use rustc_lint::LateContext; +use rustc_middle::ty; + +// Adds type suffixes and parenthesis to method receivers if necessary +pub(super) fn prepare_receiver_sugg<'a>( + cx: &LateContext<'_>, + mut expr: &'a Expr<'a>, + app: &mut Applicability, +) -> Sugg<'a> { + let mut suggestion = Sugg::hir_with_applicability(cx, expr, "_", app); + + if let ExprKind::Unary(UnOp::Neg, inner_expr) = expr.kind { + expr = inner_expr; + } + + if let ty::Float(float_ty) = cx.typeck_results().expr_ty(expr).kind() + // if the expression is a float literal and it is unsuffixed then + // add a suffix so the suggestion is valid and unambiguous + && let ExprKind::Lit(lit) = expr.kind + && let ast::LitKind::Float(sym, ast::LitFloatType::Unsuffixed) = lit.node + { + let op = format!( + "{suggestion}{}{}", + // Check for float literals without numbers following the decimal + // separator such as `2.` and adds a trailing zero + if sym.as_str().ends_with('.') { "0" } else { "" }, + float_ty.name_str() + ) + .into(); + + suggestion = match suggestion { + Sugg::MaybeParen(_) | Sugg::UnOp(UnOp::Neg, _) => Sugg::MaybeParen(op), + _ => Sugg::NonParen(op), + }; + } + + suggestion.maybe_paren() +} diff --git a/clippy_lints/src/floating_point_arithmetic/ln1p.rs b/clippy_lints/src/floating_point_arithmetic/ln1p.rs new file mode 100644 index 000000000000..4c9aa96b5042 --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/ln1p.rs @@ -0,0 +1,41 @@ +use clippy_utils::consts::ConstEvalCtxt; +use clippy_utils::consts::Constant::{F32, F64}; +use clippy_utils::diagnostics::span_lint_and_then; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_span::source_map::Spanned; + +use super::IMPRECISE_FLOPS; + +// TODO: Lint expressions of the form `(x + y).ln()` where y > 1 and +// suggest usage of `(x + (y - 1)).ln_1p()` instead +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) { + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Add, .. + }, + lhs, + rhs, + ) = receiver.kind + { + let ecx = ConstEvalCtxt::new(cx); + let recv = match (ecx.eval(lhs), ecx.eval(rhs)) { + (Some(value), _) if F32(1.0) == value || F64(1.0) == value => rhs, + (_, Some(value)) if F32(1.0) == value || F64(1.0) == value => lhs, + _ => return, + }; + + span_lint_and_then( + cx, + IMPRECISE_FLOPS, + expr.span, + "ln(1 + x) can be computed more accurately", + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = super::lib::prepare_receiver_sugg(cx, recv, &mut app); + diag.span_suggestion(expr.span, "consider using", format!("{recv}.ln_1p()"), app); + }, + ); + } +} diff --git a/clippy_lints/src/floating_point_arithmetic/log_base.rs b/clippy_lints/src/floating_point_arithmetic/log_base.rs new file mode 100644 index 000000000000..4ccc784655ed --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/log_base.rs @@ -0,0 +1,44 @@ +use clippy_utils::consts::ConstEvalCtxt; +use clippy_utils::consts::Constant::{F32, F64}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::sugg::Sugg; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_span::SyntaxContext; +use std::f32::consts as f32_consts; +use std::f64::consts as f64_consts; + +use super::SUBOPTIMAL_FLOPS; + +// Returns the specialized log method for a given base if base is constant +// and is one of 2, 10 and e +fn get_specialized_log_method(cx: &LateContext<'_>, base: &Expr<'_>, ctxt: SyntaxContext) -> Option<&'static str> { + if let Some(value) = ConstEvalCtxt::new(cx).eval_local(base, ctxt) { + if F32(2.0) == value || F64(2.0) == value { + return Some("log2"); + } else if F32(10.0) == value || F64(10.0) == value { + return Some("log10"); + } else if F32(f32_consts::E) == value || F64(f64_consts::E) == value { + return Some("ln"); + } + } + + None +} + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) { + if let Some(method) = get_specialized_log_method(cx, &args[0], expr.span.ctxt()) { + span_lint_and_then( + cx, + SUBOPTIMAL_FLOPS, + expr.span, + "logarithm for bases 2, 10 and e can be computed more accurately", + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, receiver, "_", &mut app).maybe_paren(); + diag.span_suggestion(expr.span, "consider using", format!("{recv}.{method}()"), app); + }, + ); + } +} diff --git a/clippy_lints/src/floating_point_arithmetic/log_division.rs b/clippy_lints/src/floating_point_arithmetic/log_division.rs new file mode 100644 index 000000000000..e3419ffad72a --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/log_division.rs @@ -0,0 +1,52 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::sugg::Sugg; +use clippy_utils::{eq_expr_value, sym}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment}; +use rustc_lint::LateContext; +use rustc_span::source_map::Spanned; + +use super::SUBOPTIMAL_FLOPS; + +fn are_same_base_logs(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool { + if let ExprKind::MethodCall(PathSegment { ident: method_a, .. }, _, args_a, _) = expr_a.kind + && let ExprKind::MethodCall(PathSegment { ident: method_b, .. }, _, args_b, _) = expr_b.kind + { + return method_a.name == method_b.name + && args_a.len() == args_b.len() + && (matches!(method_a.name, sym::ln | sym::log2 | sym::log10) + || method_a.name == sym::log && args_a.len() == 1 && eq_expr_value(cx, &args_a[0], &args_b[0])); + } + + false +} + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { + // check if expression of the form x.logN() / y.logN() + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Div, .. + }, + lhs, + rhs, + ) = expr.kind + && are_same_base_logs(cx, lhs, rhs) + && let ExprKind::MethodCall(_, largs_self, ..) = lhs.kind + && let ExprKind::MethodCall(_, rargs_self, ..) = rhs.kind + { + let mut app = Applicability::MachineApplicable; + span_lint_and_sugg( + cx, + SUBOPTIMAL_FLOPS, + expr.span, + "log base can be expressed more clearly", + "consider using", + format!( + "{}.log({})", + Sugg::hir_with_applicability(cx, largs_self, "_", &mut app).maybe_paren(), + Sugg::hir_with_applicability(cx, rargs_self, "_", &mut app), + ), + app, + ); + } +} diff --git a/clippy_lints/src/floating_point_arithmetic/mod.rs b/clippy_lints/src/floating_point_arithmetic/mod.rs index 64a2af38a108..edc638c96bbf 100644 --- a/clippy_lints/src/floating_point_arithmetic/mod.rs +++ b/clippy_lints/src/floating_point_arithmetic/mod.rs @@ -1,22 +1,20 @@ -use clippy_utils::consts::Constant::{F32, F64, Int}; -use clippy_utils::consts::{ConstEvalCtxt, Constant}; -use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; -use clippy_utils::{ - eq_expr_value, get_parent_expr, has_ambiguous_literal_in_expr, higher, is_in_const_context, is_no_std_crate, - numeric_literal, peel_blocks, sugg, sym, -}; -use rustc_ast::ast; -use rustc_errors::Applicability; -use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp}; +use clippy_utils::{is_in_const_context, is_no_std_crate, sym}; +use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; use rustc_session::declare_lint_pass; -use rustc_span::SyntaxContext; -use rustc_span::source_map::Spanned; -use std::f32::consts as f32_consts; -use std::f64::consts as f64_consts; -use sugg::Sugg; + +mod custom_abs; +mod expm1; +mod hypot; +mod lib; +mod ln1p; +mod log_base; +mod log_division; +mod mul_add; +mod powf; +mod powi; +mod radians; declare_clippy_lint! { /// ### What it does @@ -110,634 +108,6 @@ declare_lint_pass!(FloatingPointArithmetic => [ SUBOPTIMAL_FLOPS ]); -// Returns the specialized log method for a given base if base is constant -// and is one of 2, 10 and e -fn get_specialized_log_method(cx: &LateContext<'_>, base: &Expr<'_>, ctxt: SyntaxContext) -> Option<&'static str> { - if let Some(value) = ConstEvalCtxt::new(cx).eval_local(base, ctxt) { - if F32(2.0) == value || F64(2.0) == value { - return Some("log2"); - } else if F32(10.0) == value || F64(10.0) == value { - return Some("log10"); - } else if F32(f32_consts::E) == value || F64(f64_consts::E) == value { - return Some("ln"); - } - } - - None -} - -// Adds type suffixes and parenthesis to method receivers if necessary -fn prepare_receiver_sugg<'a>(cx: &LateContext<'_>, mut expr: &'a Expr<'a>, app: &mut Applicability) -> Sugg<'a> { - let mut suggestion = Sugg::hir_with_applicability(cx, expr, "_", app); - - if let ExprKind::Unary(UnOp::Neg, inner_expr) = expr.kind { - expr = inner_expr; - } - - if let ty::Float(float_ty) = cx.typeck_results().expr_ty(expr).kind() - // if the expression is a float literal and it is unsuffixed then - // add a suffix so the suggestion is valid and unambiguous - && let ExprKind::Lit(lit) = expr.kind - && let ast::LitKind::Float(sym, ast::LitFloatType::Unsuffixed) = lit.node - { - let op = format!( - "{suggestion}{}{}", - // Check for float literals without numbers following the decimal - // separator such as `2.` and adds a trailing zero - if sym.as_str().ends_with('.') { "0" } else { "" }, - float_ty.name_str() - ) - .into(); - - suggestion = match suggestion { - Sugg::MaybeParen(_) | Sugg::UnOp(UnOp::Neg, _) => Sugg::MaybeParen(op), - _ => Sugg::NonParen(op), - }; - } - - suggestion.maybe_paren() -} - -fn check_log_base(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) { - if let Some(method) = get_specialized_log_method(cx, &args[0], expr.span.ctxt()) { - span_lint_and_then( - cx, - SUBOPTIMAL_FLOPS, - expr.span, - "logarithm for bases 2, 10 and e can be computed more accurately", - |diag| { - let mut app = Applicability::MachineApplicable; - let recv = Sugg::hir_with_applicability(cx, receiver, "_", &mut app).maybe_paren(); - diag.span_suggestion(expr.span, "consider using", format!("{recv}.{method}()"), app); - }, - ); - } -} - -// TODO: Lint expressions of the form `(x + y).ln()` where y > 1 and -// suggest usage of `(x + (y - 1)).ln_1p()` instead -fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) { - if let ExprKind::Binary( - Spanned { - node: BinOpKind::Add, .. - }, - lhs, - rhs, - ) = receiver.kind - { - let ecx = ConstEvalCtxt::new(cx); - let recv = match (ecx.eval(lhs), ecx.eval(rhs)) { - (Some(value), _) if F32(1.0) == value || F64(1.0) == value => rhs, - (_, Some(value)) if F32(1.0) == value || F64(1.0) == value => lhs, - _ => return, - }; - - span_lint_and_then( - cx, - IMPRECISE_FLOPS, - expr.span, - "ln(1 + x) can be computed more accurately", - |diag| { - let mut app = Applicability::MachineApplicable; - let recv = prepare_receiver_sugg(cx, recv, &mut app); - diag.span_suggestion(expr.span, "consider using", format!("{recv}.ln_1p()"), app); - }, - ); - } -} - -// Returns an integer if the float constant is a whole number and it can be -// converted to an integer without loss of precision. For now we only check -// ranges [-16777215, 16777216) for type f32 as whole number floats outside -// this range are lossy and ambiguous. -#[expect(clippy::cast_possible_truncation)] -fn get_integer_from_float_constant(value: &Constant) -> Option { - match value { - F32(num) if num.fract() == 0.0 => { - if (-16_777_215.0..16_777_216.0).contains(num) { - Some(num.round() as i32) - } else { - None - } - }, - F64(num) if num.fract() == 0.0 => { - if (-2_147_483_648.0..2_147_483_648.0).contains(num) { - Some(num.round() as i32) - } else { - None - } - }, - _ => None, - } -} - -fn check_powf(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) { - // Check receiver - if let Some(value) = ConstEvalCtxt::new(cx).eval(receiver) - && let Some(method) = if F32(f32_consts::E) == value || F64(f64_consts::E) == value { - Some("exp") - } else if F32(2.0) == value || F64(2.0) == value { - Some("exp2") - } else { - None - } - { - span_lint_and_then( - cx, - SUBOPTIMAL_FLOPS, - expr.span, - "exponent for bases 2 and e can be computed more accurately", - |diag| { - let mut app = Applicability::MachineApplicable; - let recv = prepare_receiver_sugg(cx, &args[0], &mut app); - diag.span_suggestion(expr.span, "consider using", format!("{recv}.{method}()"), app); - }, - ); - } - - // Check argument - if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0]) { - let mut app = Applicability::MachineApplicable; - let recv = Sugg::hir_with_applicability(cx, receiver, "_", &mut app).maybe_paren(); - let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value { - ( - SUBOPTIMAL_FLOPS, - "square-root of a number can be computed more efficiently and accurately", - format!("{recv}.sqrt()"), - ) - } else if F32(1.0 / 3.0) == value || F64(1.0 / 3.0) == value { - ( - IMPRECISE_FLOPS, - "cube-root of a number can be computed more accurately", - format!("{recv}.cbrt()"), - ) - } else if let Some(exponent) = get_integer_from_float_constant(&value) { - ( - SUBOPTIMAL_FLOPS, - "exponentiation with integer powers can be computed more efficiently", - format!( - "{recv}.powi({})", - numeric_literal::format(&exponent.to_string(), None, false) - ), - ) - } else { - return; - }; - - span_lint_and_sugg(cx, lint, expr.span, help, "consider using", suggestion, app); - } -} - -fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) { - if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0]) - && value == Int(2) - && let Some(parent) = get_parent_expr(cx, expr) - { - if let Some(grandparent) = get_parent_expr(cx, parent) - && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = grandparent.kind - && method.name == sym::sqrt - // we don't care about the applicability as this is an early-return condition - && detect_hypot(cx, receiver, &mut Applicability::Unspecified).is_some() - { - return; - } - - if let ExprKind::Binary( - Spanned { - node: op @ (BinOpKind::Add | BinOpKind::Sub), - .. - }, - lhs, - rhs, - ) = parent.kind - { - span_lint_and_then( - cx, - SUBOPTIMAL_FLOPS, - parent.span, - "multiply and add expressions can be calculated more efficiently and accurately", - |diag| { - let other_addend = if lhs.hir_id == expr.hir_id { rhs } else { lhs }; - - // Negate expr if original code has subtraction and expr is on the right side - let maybe_neg_sugg = |expr, hir_id, app: &mut _| { - let sugg = Sugg::hir_with_applicability(cx, expr, "_", app); - if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id { - -sugg - } else { - sugg - } - }; - - let mut app = Applicability::MachineApplicable; - diag.span_suggestion( - parent.span, - "consider using", - format!( - "{}.mul_add({}, {})", - Sugg::hir_with_applicability(cx, receiver, "_", &mut app).maybe_paren(), - maybe_neg_sugg(receiver, expr.hir_id, &mut app), - maybe_neg_sugg(other_addend, other_addend.hir_id, &mut app), - ), - app, - ); - }, - ); - } - } -} - -fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>, app: &mut Applicability) -> Option { - if let ExprKind::Binary( - Spanned { - node: BinOpKind::Add, .. - }, - add_lhs, - add_rhs, - ) = receiver.kind - { - // check if expression of the form x * x + y * y - if let ExprKind::Binary( - Spanned { - node: BinOpKind::Mul, .. - }, - lmul_lhs, - lmul_rhs, - ) = add_lhs.kind - && let ExprKind::Binary( - Spanned { - node: BinOpKind::Mul, .. - }, - rmul_lhs, - rmul_rhs, - ) = add_rhs.kind - && eq_expr_value(cx, lmul_lhs, lmul_rhs) - && eq_expr_value(cx, rmul_lhs, rmul_rhs) - { - return Some(format!( - "{}.hypot({})", - Sugg::hir_with_applicability(cx, lmul_lhs, "_", app).maybe_paren(), - Sugg::hir_with_applicability(cx, rmul_lhs, "_", app) - )); - } - - // check if expression of the form x.powi(2) + y.powi(2) - if let ExprKind::MethodCall(PathSegment { ident: lmethod, .. }, largs_0, [largs_1, ..], _) = add_lhs.kind - && let ExprKind::MethodCall(PathSegment { ident: rmethod, .. }, rargs_0, [rargs_1, ..], _) = add_rhs.kind - && lmethod.name == sym::powi - && rmethod.name == sym::powi - && let ecx = ConstEvalCtxt::new(cx) - && let Some(lvalue) = ecx.eval(largs_1) - && let Some(rvalue) = ecx.eval(rargs_1) - && Int(2) == lvalue - && Int(2) == rvalue - { - return Some(format!( - "{}.hypot({})", - Sugg::hir_with_applicability(cx, largs_0, "_", app).maybe_paren(), - Sugg::hir_with_applicability(cx, rargs_0, "_", app) - )); - } - } - - None -} - -fn check_hypot(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) { - let mut app = Applicability::MachineApplicable; - if let Some(message) = detect_hypot(cx, receiver, &mut app) { - span_lint_and_sugg( - cx, - IMPRECISE_FLOPS, - expr.span, - "hypotenuse can be computed more accurately", - "consider using", - message, - app, - ); - } -} - -// TODO: Lint expressions of the form `x.exp() - y` where y > 1 -// and suggest usage of `x.exp_m1() - (y - 1)` instead -fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { - if let ExprKind::Binary( - Spanned { - node: BinOpKind::Sub, .. - }, - lhs, - rhs, - ) = expr.kind - && let ExprKind::MethodCall(path, self_arg, [], _) = lhs.kind - && path.ident.name == sym::exp - && cx.typeck_results().expr_ty(lhs).is_floating_point() - && let Some(value) = ConstEvalCtxt::new(cx).eval(rhs) - && (F32(1.0) == value || F64(1.0) == value) - && cx.typeck_results().expr_ty(self_arg).is_floating_point() - { - span_lint_and_then( - cx, - IMPRECISE_FLOPS, - expr.span, - "(e.pow(x) - 1) can be computed more accurately", - |diag| { - let mut app = Applicability::MachineApplicable; - let recv = Sugg::hir_with_applicability(cx, self_arg, "_", &mut app).maybe_paren(); - diag.span_suggestion(expr.span, "consider using", format!("{recv}.exp_m1()"), app); - }, - ); - } -} - -fn is_float_mul_expr<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(&'a Expr<'a>, &'a Expr<'a>)> { - if let ExprKind::Binary( - Spanned { - node: BinOpKind::Mul, .. - }, - lhs, - rhs, - ) = expr.kind - && cx.typeck_results().expr_ty(lhs).is_floating_point() - && cx.typeck_results().expr_ty(rhs).is_floating_point() - { - return Some((lhs, rhs)); - } - - None -} - -fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) { - if let ExprKind::Binary( - Spanned { - node: op @ (BinOpKind::Add | BinOpKind::Sub), - .. - }, - lhs, - rhs, - ) = &expr.kind - { - if let Some(parent) = get_parent_expr(cx, expr) - && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = parent.kind - && method.name == sym::sqrt - // we don't care about the applicability as this is an early-return condition - && detect_hypot(cx, receiver, &mut Applicability::Unspecified).is_some() - { - return; - } - - let maybe_neg_sugg = |expr, app: &mut _| { - let sugg = Sugg::hir_with_applicability(cx, expr, "_", app); - if let BinOpKind::Sub = op { -sugg } else { sugg } - }; - - let mut app = Applicability::MachineApplicable; - let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) - && cx.typeck_results().expr_ty(rhs).is_floating_point() - { - ( - inner_lhs, - Sugg::hir_with_applicability(cx, inner_rhs, "_", &mut app), - maybe_neg_sugg(rhs, &mut app), - ) - } else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) - && cx.typeck_results().expr_ty(lhs).is_floating_point() - { - ( - inner_lhs, - maybe_neg_sugg(inner_rhs, &mut app), - Sugg::hir_with_applicability(cx, lhs, "_", &mut app), - ) - } else { - return; - }; - - // Check if any variable in the expression has an ambiguous type (could be f32 or f64) - // see: https://github.com/rust-lang/rust-clippy/issues/14897 - if (matches!(recv.kind, ExprKind::Path(_)) || matches!(recv.kind, ExprKind::Call(_, _))) - && has_ambiguous_literal_in_expr(cx, recv) - { - return; - } - - span_lint_and_sugg( - cx, - SUBOPTIMAL_FLOPS, - expr.span, - "multiply and add expressions can be calculated more efficiently and accurately", - "consider using", - format!("{}.mul_add({arg1}, {arg2})", prepare_receiver_sugg(cx, recv, &mut app)), - app, - ); - } -} - -/// Returns true iff expr is an expression which tests whether or not -/// test is positive or an expression which tests whether or not test -/// is nonnegative. -/// Used for check-custom-abs function below -fn is_testing_positive(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool { - if let ExprKind::Binary(Spanned { node: op, .. }, left, right) = expr.kind { - match op { - BinOpKind::Gt | BinOpKind::Ge => is_zero(cx, right, expr.span.ctxt()) && eq_expr_value(cx, left, test), - BinOpKind::Lt | BinOpKind::Le => is_zero(cx, left, expr.span.ctxt()) && eq_expr_value(cx, right, test), - _ => false, - } - } else { - false - } -} - -/// See [`is_testing_positive`] -fn is_testing_negative(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool { - if let ExprKind::Binary(Spanned { node: op, .. }, left, right) = expr.kind { - match op { - BinOpKind::Gt | BinOpKind::Ge => is_zero(cx, left, expr.span.ctxt()) && eq_expr_value(cx, right, test), - BinOpKind::Lt | BinOpKind::Le => is_zero(cx, right, expr.span.ctxt()) && eq_expr_value(cx, left, test), - _ => false, - } - } else { - false - } -} - -/// Returns true iff expr is some zero literal -fn is_zero(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> bool { - match ConstEvalCtxt::new(cx).eval_local(expr, ctxt) { - Some(Int(i)) => i == 0, - Some(F32(f)) => f == 0.0, - Some(F64(f)) => f == 0.0, - _ => false, - } -} - -/// If the two expressions are negations of each other, then it returns -/// a tuple, in which the first element is true iff expr1 is the -/// positive expressions, and the second element is the positive -/// one of the two expressions -/// If the two expressions are not negations of each other, then it -/// returns None. -fn are_negated<'a>(cx: &LateContext<'_>, expr1: &'a Expr<'a>, expr2: &'a Expr<'a>) -> Option<(bool, &'a Expr<'a>)> { - if let ExprKind::Unary(UnOp::Neg, expr1_negated) = expr1.kind - && eq_expr_value(cx, expr1_negated, expr2) - { - return Some((false, expr2)); - } - if let ExprKind::Unary(UnOp::Neg, expr2_negated) = expr2.kind - && eq_expr_value(cx, expr1, expr2_negated) - { - return Some((true, expr1)); - } - None -} - -fn check_custom_abs(cx: &LateContext<'_>, expr: &Expr<'_>) { - if let Some(higher::If { - cond, - then, - r#else: Some(r#else), - }) = higher::If::hir(expr) - && let if_body_expr = peel_blocks(then) - && let else_body_expr = peel_blocks(r#else) - && let Some((if_expr_positive, body)) = are_negated(cx, if_body_expr, else_body_expr) - { - let sugg_positive_abs = if is_testing_positive(cx, cond, body) { - if_expr_positive - } else if is_testing_negative(cx, cond, body) { - !if_expr_positive - } else { - return; - }; - let mut app = Applicability::MachineApplicable; - let body = Sugg::hir_with_applicability(cx, body, "_", &mut app).maybe_paren(); - let sugg = if sugg_positive_abs { - ("manual implementation of `abs` method", format!("{body}.abs()")) - } else { - #[rustfmt::skip] - ("manual implementation of negation of `abs` method", format!("-{body}.abs()")) - }; - span_lint_and_sugg(cx, SUBOPTIMAL_FLOPS, expr.span, sugg.0, "try", sugg.1, app); - } -} - -fn are_same_base_logs(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool { - if let ExprKind::MethodCall(PathSegment { ident: method_a, .. }, _, args_a, _) = expr_a.kind - && let ExprKind::MethodCall(PathSegment { ident: method_b, .. }, _, args_b, _) = expr_b.kind - { - return method_a.name == method_b.name - && args_a.len() == args_b.len() - && (matches!(method_a.name, sym::ln | sym::log2 | sym::log10) - || method_a.name == sym::log && args_a.len() == 1 && eq_expr_value(cx, &args_a[0], &args_b[0])); - } - - false -} - -fn check_log_division(cx: &LateContext<'_>, expr: &Expr<'_>) { - // check if expression of the form x.logN() / y.logN() - if let ExprKind::Binary( - Spanned { - node: BinOpKind::Div, .. - }, - lhs, - rhs, - ) = expr.kind - && are_same_base_logs(cx, lhs, rhs) - && let ExprKind::MethodCall(_, largs_self, ..) = lhs.kind - && let ExprKind::MethodCall(_, rargs_self, ..) = rhs.kind - { - let mut app = Applicability::MachineApplicable; - span_lint_and_sugg( - cx, - SUBOPTIMAL_FLOPS, - expr.span, - "log base can be expressed more clearly", - "consider using", - format!( - "{}.log({})", - Sugg::hir_with_applicability(cx, largs_self, "_", &mut app).maybe_paren(), - Sugg::hir_with_applicability(cx, rargs_self, "_", &mut app), - ), - app, - ); - } -} - -fn check_radians(cx: &LateContext<'_>, expr: &Expr<'_>) { - if let ExprKind::Binary( - Spanned { - node: BinOpKind::Div, .. - }, - div_lhs, - div_rhs, - ) = expr.kind - && let ExprKind::Binary( - Spanned { - node: BinOpKind::Mul, .. - }, - mul_lhs, - mul_rhs, - ) = div_lhs.kind - && let ecx = ConstEvalCtxt::new(cx) - && let Some(rvalue) = ecx.eval(div_rhs) - && let Some(lvalue) = ecx.eval(mul_rhs) - { - // TODO: also check for constant values near PI/180 or 180/PI - if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue) - && (F32(180_f32) == lvalue || F64(180_f64) == lvalue) - { - span_lint_and_then( - cx, - SUBOPTIMAL_FLOPS, - expr.span, - "conversion to degrees can be done more accurately", - |diag| { - let mut app = Applicability::MachineApplicable; - let recv = Sugg::hir_with_applicability(cx, mul_lhs, "num", &mut app); - let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind - && let ast::LitKind::Float(ref value, float_type) = literal.node - && float_type == ast::LitFloatType::Unsuffixed - { - if value.as_str().ends_with('.') { - format!("{recv}0_f64.to_degrees()") - } else { - format!("{recv}_f64.to_degrees()") - } - } else { - format!("{}.to_degrees()", recv.maybe_paren()) - }; - diag.span_suggestion(expr.span, "consider using", proposal, app); - }, - ); - } else if (F32(180_f32) == rvalue || F64(180_f64) == rvalue) - && (F32(f32_consts::PI) == lvalue || F64(f64_consts::PI) == lvalue) - { - span_lint_and_then( - cx, - SUBOPTIMAL_FLOPS, - expr.span, - "conversion to radians can be done more accurately", - |diag| { - let mut app = Applicability::MachineApplicable; - let recv = Sugg::hir_with_applicability(cx, mul_lhs, "num", &mut app); - let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind - && let ast::LitKind::Float(ref value, float_type) = literal.node - && float_type == ast::LitFloatType::Unsuffixed - { - if value.as_str().ends_with('.') { - format!("{recv}0_f64.to_radians()") - } else { - format!("{recv}_f64.to_radians()") - } - } else { - format!("{}.to_radians()", recv.maybe_paren()) - }; - diag.span_suggestion(expr.span, "consider using", proposal, app); - }, - ); - } - } -} - impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { // All of these operations are currently not const and are in std. @@ -750,22 +120,22 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { if recv_ty.is_floating_point() && !is_no_std_crate(cx) && cx.ty_based_def(expr).opt_parent(cx).is_impl(cx) { match path.ident.name { - sym::ln => check_ln1p(cx, expr, receiver), - sym::log => check_log_base(cx, expr, receiver, args), - sym::powf => check_powf(cx, expr, receiver, args), - sym::powi => check_powi(cx, expr, receiver, args), - sym::sqrt => check_hypot(cx, expr, receiver), + sym::ln => ln1p::check(cx, expr, receiver), + sym::log => log_base::check(cx, expr, receiver, args), + sym::powf => powf::check(cx, expr, receiver, args), + sym::powi => powi::check(cx, expr, receiver, args), + sym::sqrt => hypot::check(cx, expr, receiver), _ => {}, } } } else { if !is_no_std_crate(cx) { - check_expm1(cx, expr); - check_mul_add(cx, expr); - check_custom_abs(cx, expr); - check_log_division(cx, expr); + expm1::check(cx, expr); + mul_add::check(cx, expr); + custom_abs::check(cx, expr); + log_division::check(cx, expr); } - check_radians(cx, expr); + radians::check(cx, expr); } } } diff --git a/clippy_lints/src/floating_point_arithmetic/mul_add.rs b/clippy_lints/src/floating_point_arithmetic/mul_add.rs new file mode 100644 index 000000000000..03a9d3b05f88 --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/mul_add.rs @@ -0,0 +1,94 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::sugg::Sugg; +use clippy_utils::{get_parent_expr, has_ambiguous_literal_in_expr, sym}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment}; +use rustc_lint::LateContext; +use rustc_span::source_map::Spanned; + +use super::SUBOPTIMAL_FLOPS; + +fn is_float_mul_expr<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(&'a Expr<'a>, &'a Expr<'a>)> { + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Mul, .. + }, + lhs, + rhs, + ) = expr.kind + && cx.typeck_results().expr_ty(lhs).is_floating_point() + && cx.typeck_results().expr_ty(rhs).is_floating_point() + { + return Some((lhs, rhs)); + } + + None +} + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { + if let ExprKind::Binary( + Spanned { + node: op @ (BinOpKind::Add | BinOpKind::Sub), + .. + }, + lhs, + rhs, + ) = &expr.kind + { + if let Some(parent) = get_parent_expr(cx, expr) + && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = parent.kind + && method.name == sym::sqrt + // we don't care about the applicability as this is an early-return condition + && super::hypot::detect(cx, receiver, &mut Applicability::Unspecified).is_some() + { + return; + } + + let maybe_neg_sugg = |expr, app: &mut _| { + let sugg = Sugg::hir_with_applicability(cx, expr, "_", app); + if let BinOpKind::Sub = op { -sugg } else { sugg } + }; + + let mut app = Applicability::MachineApplicable; + let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) + && cx.typeck_results().expr_ty(rhs).is_floating_point() + { + ( + inner_lhs, + Sugg::hir_with_applicability(cx, inner_rhs, "_", &mut app), + maybe_neg_sugg(rhs, &mut app), + ) + } else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) + && cx.typeck_results().expr_ty(lhs).is_floating_point() + { + ( + inner_lhs, + maybe_neg_sugg(inner_rhs, &mut app), + Sugg::hir_with_applicability(cx, lhs, "_", &mut app), + ) + } else { + return; + }; + + // Check if any variable in the expression has an ambiguous type (could be f32 or f64) + // see: https://github.com/rust-lang/rust-clippy/issues/14897 + if (matches!(recv.kind, ExprKind::Path(_)) || matches!(recv.kind, ExprKind::Call(_, _))) + && has_ambiguous_literal_in_expr(cx, recv) + { + return; + } + + span_lint_and_sugg( + cx, + SUBOPTIMAL_FLOPS, + expr.span, + "multiply and add expressions can be calculated more efficiently and accurately", + "consider using", + format!( + "{}.mul_add({arg1}, {arg2})", + super::lib::prepare_receiver_sugg(cx, recv, &mut app) + ), + app, + ); + } +} diff --git a/clippy_lints/src/floating_point_arithmetic/powf.rs b/clippy_lints/src/floating_point_arithmetic/powf.rs new file mode 100644 index 000000000000..8e4a7388e784 --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/powf.rs @@ -0,0 +1,94 @@ +use clippy_utils::consts::Constant::{F32, F64}; +use clippy_utils::consts::{ConstEvalCtxt, Constant}; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::numeric_literal; +use clippy_utils::sugg::Sugg; +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use std::f32::consts as f32_consts; +use std::f64::consts as f64_consts; + +use super::{IMPRECISE_FLOPS, SUBOPTIMAL_FLOPS}; + +// Returns an integer if the float constant is a whole number and it can be +// converted to an integer without loss of precision. For now we only check +// ranges [-16777215, 16777216) for type f32 as whole number floats outside +// this range are lossy and ambiguous. +#[expect(clippy::cast_possible_truncation)] +fn get_integer_from_float_constant(value: &Constant) -> Option { + match value { + F32(num) if num.fract() == 0.0 => { + if (-16_777_215.0..16_777_216.0).contains(num) { + Some(num.round() as i32) + } else { + None + } + }, + F64(num) if num.fract() == 0.0 => { + if (-2_147_483_648.0..2_147_483_648.0).contains(num) { + Some(num.round() as i32) + } else { + None + } + }, + _ => None, + } +} + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) { + // Check receiver + if let Some(value) = ConstEvalCtxt::new(cx).eval(receiver) + && let Some(method) = if F32(f32_consts::E) == value || F64(f64_consts::E) == value { + Some("exp") + } else if F32(2.0) == value || F64(2.0) == value { + Some("exp2") + } else { + None + } + { + span_lint_and_then( + cx, + SUBOPTIMAL_FLOPS, + expr.span, + "exponent for bases 2 and e can be computed more accurately", + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = super::lib::prepare_receiver_sugg(cx, &args[0], &mut app); + diag.span_suggestion(expr.span, "consider using", format!("{recv}.{method}()"), app); + }, + ); + } + + // Check argument + if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0]) { + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, receiver, "_", &mut app).maybe_paren(); + let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value { + ( + SUBOPTIMAL_FLOPS, + "square-root of a number can be computed more efficiently and accurately", + format!("{recv}.sqrt()"), + ) + } else if F32(1.0 / 3.0) == value || F64(1.0 / 3.0) == value { + ( + IMPRECISE_FLOPS, + "cube-root of a number can be computed more accurately", + format!("{recv}.cbrt()"), + ) + } else if let Some(exponent) = get_integer_from_float_constant(&value) { + ( + SUBOPTIMAL_FLOPS, + "exponentiation with integer powers can be computed more efficiently", + format!( + "{recv}.powi({})", + numeric_literal::format(&exponent.to_string(), None, false) + ), + ) + } else { + return; + }; + + span_lint_and_sugg(cx, lint, expr.span, help, "consider using", suggestion, app); + } +} diff --git a/clippy_lints/src/floating_point_arithmetic/powi.rs b/clippy_lints/src/floating_point_arithmetic/powi.rs new file mode 100644 index 000000000000..a61a2a82c023 --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/powi.rs @@ -0,0 +1,70 @@ +use clippy_utils::consts::ConstEvalCtxt; +use clippy_utils::consts::Constant::Int; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::sugg::Sugg; +use clippy_utils::{get_parent_expr, sym}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment}; +use rustc_lint::LateContext; +use rustc_span::source_map::Spanned; + +use super::SUBOPTIMAL_FLOPS; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) { + if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0]) + && value == Int(2) + && let Some(parent) = get_parent_expr(cx, expr) + { + if let Some(grandparent) = get_parent_expr(cx, parent) + && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = grandparent.kind + && method.name == sym::sqrt + // we don't care about the applicability as this is an early-return condition + && super::hypot::detect(cx, receiver, &mut Applicability::Unspecified).is_some() + { + return; + } + + if let ExprKind::Binary( + Spanned { + node: op @ (BinOpKind::Add | BinOpKind::Sub), + .. + }, + lhs, + rhs, + ) = parent.kind + { + span_lint_and_then( + cx, + SUBOPTIMAL_FLOPS, + parent.span, + "multiply and add expressions can be calculated more efficiently and accurately", + |diag| { + let other_addend = if lhs.hir_id == expr.hir_id { rhs } else { lhs }; + + // Negate expr if original code has subtraction and expr is on the right side + let maybe_neg_sugg = |expr, hir_id, app: &mut _| { + let sugg = Sugg::hir_with_applicability(cx, expr, "_", app); + if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id { + -sugg + } else { + sugg + } + }; + + let mut app = Applicability::MachineApplicable; + diag.span_suggestion( + parent.span, + "consider using", + format!( + "{}.mul_add({}, {})", + Sugg::hir_with_applicability(cx, receiver, "_", &mut app).maybe_paren(), + maybe_neg_sugg(receiver, expr.hir_id, &mut app), + maybe_neg_sugg(other_addend, other_addend.hir_id, &mut app), + ), + app, + ); + }, + ); + } + } +} diff --git a/clippy_lints/src/floating_point_arithmetic/radians.rs b/clippy_lints/src/floating_point_arithmetic/radians.rs new file mode 100644 index 000000000000..2021f00a97e8 --- /dev/null +++ b/clippy_lints/src/floating_point_arithmetic/radians.rs @@ -0,0 +1,89 @@ +use clippy_utils::consts::ConstEvalCtxt; +use clippy_utils::consts::Constant::{F32, F64}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::sugg::Sugg; +use rustc_ast::ast; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::LateContext; +use rustc_span::source_map::Spanned; +use std::f32::consts as f32_consts; +use std::f64::consts as f64_consts; + +use super::SUBOPTIMAL_FLOPS; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { + if let ExprKind::Binary( + Spanned { + node: BinOpKind::Div, .. + }, + div_lhs, + div_rhs, + ) = expr.kind + && let ExprKind::Binary( + Spanned { + node: BinOpKind::Mul, .. + }, + mul_lhs, + mul_rhs, + ) = div_lhs.kind + && let ecx = ConstEvalCtxt::new(cx) + && let Some(rvalue) = ecx.eval(div_rhs) + && let Some(lvalue) = ecx.eval(mul_rhs) + { + // TODO: also check for constant values near PI/180 or 180/PI + if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue) + && (F32(180_f32) == lvalue || F64(180_f64) == lvalue) + { + span_lint_and_then( + cx, + SUBOPTIMAL_FLOPS, + expr.span, + "conversion to degrees can be done more accurately", + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, mul_lhs, "num", &mut app); + let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind + && let ast::LitKind::Float(ref value, float_type) = literal.node + && float_type == ast::LitFloatType::Unsuffixed + { + if value.as_str().ends_with('.') { + format!("{recv}0_f64.to_degrees()") + } else { + format!("{recv}_f64.to_degrees()") + } + } else { + format!("{}.to_degrees()", recv.maybe_paren()) + }; + diag.span_suggestion(expr.span, "consider using", proposal, app); + }, + ); + } else if (F32(180_f32) == rvalue || F64(180_f64) == rvalue) + && (F32(f32_consts::PI) == lvalue || F64(f64_consts::PI) == lvalue) + { + span_lint_and_then( + cx, + SUBOPTIMAL_FLOPS, + expr.span, + "conversion to radians can be done more accurately", + |diag| { + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_applicability(cx, mul_lhs, "num", &mut app); + let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind + && let ast::LitKind::Float(ref value, float_type) = literal.node + && float_type == ast::LitFloatType::Unsuffixed + { + if value.as_str().ends_with('.') { + format!("{recv}0_f64.to_radians()") + } else { + format!("{recv}_f64.to_radians()") + } + } else { + format!("{}.to_radians()", recv.maybe_paren()) + }; + diag.span_suggestion(expr.span, "consider using", proposal, app); + }, + ); + } + } +} From 092e522fa8f1de4fff005782ba198e6dcb8ce353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 7 Jan 2026 18:28:12 +0100 Subject: [PATCH 1815/3801] Move tests for assoc const bindings into dedicated directory --- src/tools/tidy/src/issues.txt | 7 +++--- .../const-projection-err.stock.stderr | 17 -------------- .../associated-const-bindings/ambiguity.rs} | 0 .../ambiguity.stderr} | 4 ++-- .../assoc-const-ty-mismatch.rs | 0 .../assoc-const-ty-mismatch.stderr | 0 .../associated-const-bindings}/assoc-const.rs | 0 .../bound-var-in-ty-not-wf.rs} | 0 .../bound-var-in-ty-not-wf.stderr} | 4 ++-- .../bound-var-in-ty.rs} | 0 .../coexisting-with-type-binding.rs} | 0 .../coherence.rs | 0 .../coherence.stderr | 0 .../const-bound-to-assoc-ty-99828.rs} | 0 .../const-bound-to-assoc-ty-99828.stderr} | 6 ++--- .../const-projection-err.rs | 0 .../const-projection-err.stderr | 0 .../const_evaluatable_unchecked.rs} | 0 .../equality-unused-issue-126729.rs | 0 .../equality_bound_with_infer.rs | 0 .../esc-bound-var-in-ty.rs} | 0 .../esc-bound-var-in-ty.stderr} | 2 +- .../issue-102335-const.rs | 0 .../issue-102335-const.stderr | 0 .../issue-105330.rs | 0 .../issue-105330.stderr | 0 .../associated-const-bindings}/issue-93835.rs | 0 .../issue-93835.stderr | 0 ...pes-with-generic-in-ace-no-feature-gate.rs | 0 ...with-generic-in-ace-no-feature-gate.stderr | 0 .../mismatched-types-with-generic-in-ace.rs | 0 ...ismatched-types-with-generic-in-ace.stderr | 0 .../associated-const-bindings/missing.rs} | 0 .../associated-const-bindings/missing.stderr} | 6 ++--- .../associated-const-bindings/param-in-ty.rs} | 0 .../param-in-ty.stderr} | 22 +++++++++---------- .../projection-unspecified-but-bounded.rs | 0 .../projection-unspecified-but-bounded.stderr | 0 .../associated-const-bindings/supertraits.rs} | 0 .../unbraced-enum-variant.rs} | 0 .../unbraced-enum-variant.stderr} | 16 +++++++------- .../unconstrained_impl_param.rs | 0 .../unconstrained_impl_param.stderr | 0 .../using-fnptr-as-type_const.rs | 0 .../using-fnptr-as-type_const.stderr | 0 45 files changed, 33 insertions(+), 51 deletions(-) delete mode 100644 tests/ui/associated-type-bounds/const-projection-err.stock.stderr rename tests/ui/{associated-consts/assoc-const-eq-ambiguity.rs => const-generics/associated-const-bindings/ambiguity.rs} (100%) rename tests/ui/{associated-consts/assoc-const-eq-ambiguity.stderr => const-generics/associated-const-bindings/ambiguity.stderr} (92%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/assoc-const-ty-mismatch.rs (100%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/assoc-const-ty-mismatch.stderr (100%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/assoc-const.rs (100%) rename tests/ui/{associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs => const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs} (100%) rename tests/ui/{associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr => const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr} (73%) rename tests/ui/{associated-consts/assoc-const-eq-bound-var-in-ty.rs => const-generics/associated-const-bindings/bound-var-in-ty.rs} (100%) rename tests/ui/{associated-consts/assoc-const-eq-ty-alias-noninteracting.rs => const-generics/associated-const-bindings/coexisting-with-type-binding.rs} (100%) rename tests/ui/const-generics/{associated_const_equality => associated-const-bindings}/coherence.rs (100%) rename tests/ui/const-generics/{associated_const_equality => associated-const-bindings}/coherence.stderr (100%) rename tests/ui/{associated-type-bounds/issue-99828.rs => const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.rs} (100%) rename tests/ui/{associated-type-bounds/issue-99828.stderr => const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.stderr} (91%) rename tests/ui/{associated-type-bounds => const-generics/associated-const-bindings}/const-projection-err.rs (100%) rename tests/ui/{associated-type-bounds => const-generics/associated-const-bindings}/const-projection-err.stderr (100%) rename tests/ui/{associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs => const-generics/associated-const-bindings/const_evaluatable_unchecked.rs} (100%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/equality-unused-issue-126729.rs (100%) rename tests/ui/const-generics/{associated_const_equality => associated-const-bindings}/equality_bound_with_infer.rs (100%) rename tests/ui/{associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs => const-generics/associated-const-bindings/esc-bound-var-in-ty.rs} (100%) rename tests/ui/{associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr => const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr} (89%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/issue-102335-const.rs (100%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/issue-102335-const.stderr (100%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/issue-105330.rs (100%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/issue-105330.stderr (100%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/issue-93835.rs (100%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/issue-93835.stderr (100%) rename tests/ui/const-generics/{associated_const_equality => associated-const-bindings}/mismatched-types-with-generic-in-ace-no-feature-gate.rs (100%) rename tests/ui/const-generics/{associated_const_equality => associated-const-bindings}/mismatched-types-with-generic-in-ace-no-feature-gate.stderr (100%) rename tests/ui/const-generics/{associated_const_equality => associated-const-bindings}/mismatched-types-with-generic-in-ace.rs (100%) rename tests/ui/const-generics/{associated_const_equality => associated-const-bindings}/mismatched-types-with-generic-in-ace.stderr (100%) rename tests/ui/{associated-consts/assoc-const-eq-missing.rs => const-generics/associated-const-bindings/missing.rs} (100%) rename tests/ui/{associated-consts/assoc-const-eq-missing.stderr => const-generics/associated-const-bindings/missing.stderr} (82%) rename tests/ui/{associated-consts/assoc-const-eq-param-in-ty.rs => const-generics/associated-const-bindings/param-in-ty.rs} (100%) rename tests/ui/{associated-consts/assoc-const-eq-param-in-ty.stderr => const-generics/associated-const-bindings/param-in-ty.stderr} (89%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/projection-unspecified-but-bounded.rs (100%) rename tests/ui/{associated-consts => const-generics/associated-const-bindings}/projection-unspecified-but-bounded.stderr (100%) rename tests/ui/{associated-consts/assoc-const-eq-supertraits.rs => const-generics/associated-const-bindings/supertraits.rs} (100%) rename tests/ui/const-generics/{assoc_const_eq_diagnostic.rs => associated-const-bindings/unbraced-enum-variant.rs} (100%) rename tests/ui/const-generics/{assoc_const_eq_diagnostic.stderr => associated-const-bindings/unbraced-enum-variant.stderr} (87%) rename tests/ui/const-generics/{associated_const_equality => associated-const-bindings}/unconstrained_impl_param.rs (100%) rename tests/ui/const-generics/{associated_const_equality => associated-const-bindings}/unconstrained_impl_param.stderr (100%) rename tests/ui/const-generics/{mgca => associated-const-bindings}/using-fnptr-as-type_const.rs (100%) rename tests/ui/const-generics/{mgca => associated-const-bindings}/using-fnptr-as-type_const.stderr (100%) diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 45187a0b6450..0b7fbad2a8a4 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -33,8 +33,6 @@ ui/asm/issue-99122.rs ui/asm/x86_64/issue-82869.rs ui/asm/x86_64/issue-89875.rs ui/asm/x86_64/issue-96797.rs -ui/associated-consts/issue-102335-const.rs -ui/associated-consts/issue-105330.rs ui/associated-consts/issue-110933.rs ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs @@ -45,7 +43,6 @@ ui/associated-consts/issue-63496.rs ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs ui/associated-consts/issue-88599-ref-self.rs ui/associated-consts/issue-93775.rs -ui/associated-consts/issue-93835.rs ui/associated-inherent-types/issue-104260.rs ui/associated-inherent-types/issue-109071.rs ui/associated-inherent-types/issue-109299-1.rs @@ -70,7 +67,6 @@ ui/associated-type-bounds/issue-73818.rs ui/associated-type-bounds/issue-79949.rs ui/associated-type-bounds/issue-81193.rs ui/associated-type-bounds/issue-83017.rs -ui/associated-type-bounds/issue-99828.rs ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.rs ui/associated-types/issue-18655.rs ui/associated-types/issue-19081.rs @@ -499,6 +495,9 @@ ui/confuse-field-and-method/issue-18343.rs ui/confuse-field-and-method/issue-2392.rs ui/confuse-field-and-method/issue-32128.rs ui/confuse-field-and-method/issue-33784.rs +ui/const-generics/associated-const-bindings/issue-102335-const.rs +ui/const-generics/associated-const-bindings/issue-105330.rs +ui/const-generics/associated-const-bindings/issue-93835.rs ui/const-generics/generic_arg_infer/issue-91614.rs ui/const-generics/generic_const_exprs/const_kind_expr/issue_114151.rs ui/const-generics/generic_const_exprs/issue-100217.rs diff --git a/tests/ui/associated-type-bounds/const-projection-err.stock.stderr b/tests/ui/associated-type-bounds/const-projection-err.stock.stderr deleted file mode 100644 index 0cacec26aaee..000000000000 --- a/tests/ui/associated-type-bounds/const-projection-err.stock.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0271]: type mismatch resolving `::A == 1` - --> $DIR/const-projection-err.rs:16:11 - | -LL | foo::(); - | ^ expected `1`, found `0` - | - = note: expected constant `1` - found constant `0` -note: required by a bound in `foo` - --> $DIR/const-projection-err.rs:13:28 - | -LL | fn foo>() {} - | ^^^^^ required by this bound in `foo` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs b/tests/ui/const-generics/associated-const-bindings/ambiguity.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-eq-ambiguity.rs rename to tests/ui/const-generics/associated-const-bindings/ambiguity.rs diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr b/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr similarity index 92% rename from tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr rename to tests/ui/const-generics/associated-const-bindings/ambiguity.stderr index cf4805aaf592..a14afe9d6923 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr +++ b/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr @@ -1,5 +1,5 @@ error[E0222]: ambiguous associated constant `K` in bounds of `Trait0` - --> $DIR/assoc-const-eq-ambiguity.rs:13:25 + --> $DIR/ambiguity.rs:13:25 | LL | const K: (); | ----------- @@ -17,7 +17,7 @@ LL | fn take0(_: impl Trait0) {} T: Parent0::K = const { } error[E0222]: ambiguous associated constant `C` in bounds of `Trait1` - --> $DIR/assoc-const-eq-ambiguity.rs:26:25 + --> $DIR/ambiguity.rs:26:25 | LL | const C: i32; | ------------ ambiguous `C` from `Parent1` diff --git a/tests/ui/associated-consts/assoc-const-ty-mismatch.rs b/tests/ui/const-generics/associated-const-bindings/assoc-const-ty-mismatch.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-ty-mismatch.rs rename to tests/ui/const-generics/associated-const-bindings/assoc-const-ty-mismatch.rs diff --git a/tests/ui/associated-consts/assoc-const-ty-mismatch.stderr b/tests/ui/const-generics/associated-const-bindings/assoc-const-ty-mismatch.stderr similarity index 100% rename from tests/ui/associated-consts/assoc-const-ty-mismatch.stderr rename to tests/ui/const-generics/associated-const-bindings/assoc-const-ty-mismatch.stderr diff --git a/tests/ui/associated-consts/assoc-const.rs b/tests/ui/const-generics/associated-const-bindings/assoc-const.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const.rs rename to tests/ui/const-generics/associated-const-bindings/assoc-const.rs diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs rename to tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr similarity index 73% rename from tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr rename to tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr index 76868715b861..a4f97525b515 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 + --> $DIR/bound-var-in-ty-not-wf.rs:21:13 | LL | K = const { () } | ^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 + --> $DIR/bound-var-in-ty-not-wf.rs:21:13 | LL | K = const { () } | ^^^^^^^^^^^^ diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs rename to tests/ui/const-generics/associated-const-bindings/bound-var-in-ty.rs diff --git a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs b/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs rename to tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs diff --git a/tests/ui/const-generics/associated_const_equality/coherence.rs b/tests/ui/const-generics/associated-const-bindings/coherence.rs similarity index 100% rename from tests/ui/const-generics/associated_const_equality/coherence.rs rename to tests/ui/const-generics/associated-const-bindings/coherence.rs diff --git a/tests/ui/const-generics/associated_const_equality/coherence.stderr b/tests/ui/const-generics/associated-const-bindings/coherence.stderr similarity index 100% rename from tests/ui/const-generics/associated_const_equality/coherence.stderr rename to tests/ui/const-generics/associated-const-bindings/coherence.stderr diff --git a/tests/ui/associated-type-bounds/issue-99828.rs b/tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.rs similarity index 100% rename from tests/ui/associated-type-bounds/issue-99828.rs rename to tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.rs diff --git a/tests/ui/associated-type-bounds/issue-99828.stderr b/tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.stderr similarity index 91% rename from tests/ui/associated-type-bounds/issue-99828.stderr rename to tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.stderr index e1dc1f07d9cb..692e511fb469 100644 --- a/tests/ui/associated-type-bounds/issue-99828.stderr +++ b/tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.stderr @@ -1,5 +1,5 @@ error[E0658]: associated const equality is incomplete - --> $DIR/issue-99828.rs:1:43 + --> $DIR/const-bound-to-assoc-ty-99828.rs:1:43 | LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { | ^^^^^^^^^ @@ -9,7 +9,7 @@ LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: expected type, found constant - --> $DIR/issue-99828.rs:1:50 + --> $DIR/const-bound-to-assoc-ty-99828.rs:1:50 | LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { | ---- ^^ unexpected constant @@ -20,7 +20,7 @@ note: the associated type is defined here --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL error: expected type, found constant - --> $DIR/issue-99828.rs:1:50 + --> $DIR/const-bound-to-assoc-ty-99828.rs:1:50 | LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { | ---- ^^ unexpected constant diff --git a/tests/ui/associated-type-bounds/const-projection-err.rs b/tests/ui/const-generics/associated-const-bindings/const-projection-err.rs similarity index 100% rename from tests/ui/associated-type-bounds/const-projection-err.rs rename to tests/ui/const-generics/associated-const-bindings/const-projection-err.rs diff --git a/tests/ui/associated-type-bounds/const-projection-err.stderr b/tests/ui/const-generics/associated-const-bindings/const-projection-err.stderr similarity index 100% rename from tests/ui/associated-type-bounds/const-projection-err.stderr rename to tests/ui/const-generics/associated-const-bindings/const-projection-err.stderr diff --git a/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs b/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs rename to tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs diff --git a/tests/ui/associated-consts/equality-unused-issue-126729.rs b/tests/ui/const-generics/associated-const-bindings/equality-unused-issue-126729.rs similarity index 100% rename from tests/ui/associated-consts/equality-unused-issue-126729.rs rename to tests/ui/const-generics/associated-const-bindings/equality-unused-issue-126729.rs diff --git a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs b/tests/ui/const-generics/associated-const-bindings/equality_bound_with_infer.rs similarity index 100% rename from tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs rename to tests/ui/const-generics/associated-const-bindings/equality_bound_with_infer.rs diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs rename to tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr similarity index 89% rename from tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr rename to tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr index ef861cb7f49a..122893662933 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr +++ b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` cannot capture late-bound generic parameters - --> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:15:35 + --> $DIR/esc-bound-var-in-ty.rs:15:35 | LL | fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} | -- ^ its type cannot capture the late-bound lifetime parameter `'r` diff --git a/tests/ui/associated-consts/issue-102335-const.rs b/tests/ui/const-generics/associated-const-bindings/issue-102335-const.rs similarity index 100% rename from tests/ui/associated-consts/issue-102335-const.rs rename to tests/ui/const-generics/associated-const-bindings/issue-102335-const.rs diff --git a/tests/ui/associated-consts/issue-102335-const.stderr b/tests/ui/const-generics/associated-const-bindings/issue-102335-const.stderr similarity index 100% rename from tests/ui/associated-consts/issue-102335-const.stderr rename to tests/ui/const-generics/associated-const-bindings/issue-102335-const.stderr diff --git a/tests/ui/associated-consts/issue-105330.rs b/tests/ui/const-generics/associated-const-bindings/issue-105330.rs similarity index 100% rename from tests/ui/associated-consts/issue-105330.rs rename to tests/ui/const-generics/associated-const-bindings/issue-105330.rs diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/const-generics/associated-const-bindings/issue-105330.stderr similarity index 100% rename from tests/ui/associated-consts/issue-105330.stderr rename to tests/ui/const-generics/associated-const-bindings/issue-105330.stderr diff --git a/tests/ui/associated-consts/issue-93835.rs b/tests/ui/const-generics/associated-const-bindings/issue-93835.rs similarity index 100% rename from tests/ui/associated-consts/issue-93835.rs rename to tests/ui/const-generics/associated-const-bindings/issue-93835.rs diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/const-generics/associated-const-bindings/issue-93835.stderr similarity index 100% rename from tests/ui/associated-consts/issue-93835.stderr rename to tests/ui/const-generics/associated-const-bindings/issue-93835.stderr diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.rs b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace-no-feature-gate.rs similarity index 100% rename from tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.rs rename to tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace-no-feature-gate.rs diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace-no-feature-gate.stderr similarity index 100% rename from tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr rename to tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace-no-feature-gate.stderr diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.rs similarity index 100% rename from tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs rename to tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.rs diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.stderr b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr similarity index 100% rename from tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.stderr rename to tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr diff --git a/tests/ui/associated-consts/assoc-const-eq-missing.rs b/tests/ui/const-generics/associated-const-bindings/missing.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-eq-missing.rs rename to tests/ui/const-generics/associated-const-bindings/missing.rs diff --git a/tests/ui/associated-consts/assoc-const-eq-missing.stderr b/tests/ui/const-generics/associated-const-bindings/missing.stderr similarity index 82% rename from tests/ui/associated-consts/assoc-const-eq-missing.stderr rename to tests/ui/const-generics/associated-const-bindings/missing.stderr index 318c85dcfd6f..cbcfcf4c62d1 100644 --- a/tests/ui/associated-consts/assoc-const-eq-missing.stderr +++ b/tests/ui/const-generics/associated-const-bindings/missing.stderr @@ -1,17 +1,17 @@ error[E0220]: associated constant `Z` not found for `Foo` - --> $DIR/assoc-const-eq-missing.rs:14:16 + --> $DIR/missing.rs:14:16 | LL | fn foo1>() {} | ^ help: there is an associated constant with a similar name: `N` error[E0220]: associated type `Z` not found for `Foo` - --> $DIR/assoc-const-eq-missing.rs:16:16 + --> $DIR/missing.rs:16:16 | LL | fn foo2>() {} | ^ associated type `Z` not found error[E0220]: associated constant `Z` not found for `Foo` - --> $DIR/assoc-const-eq-missing.rs:18:16 + --> $DIR/missing.rs:18:16 | LL | fn foo3>() {} | ^ help: there is an associated constant with a similar name: `N` diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/param-in-ty.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs rename to tests/ui/const-generics/associated-const-bindings/param-in-ty.rs diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr similarity index 89% rename from tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr rename to tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr index b742e68044b0..719dad816a6f 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ b/tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 + --> $DIR/param-in-ty.rs:22:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | -- the lifetime parameter `'r` is defined here @@ -10,7 +10,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 + --> $DIR/param-in-ty.rs:22:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | - the type parameter `A` is defined here @@ -21,7 +21,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 + --> $DIR/param-in-ty.rs:22:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | - the const parameter `Q` is defined here @@ -32,7 +32,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/assoc-const-eq-param-in-ty.rs:39:26 + --> $DIR/param-in-ty.rs:39:26 | LL | fn take1(_: impl Project) {} | -------------^^^^------------ @@ -41,7 +41,7 @@ LL | fn take1(_: impl Project) {} | the `impl Trait` is specified here error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:21 + --> $DIR/param-in-ty.rs:44:21 | LL | fn take2>(_: P) {} | - ^^^^ its type must not depend on the type parameter `P` @@ -51,7 +51,7 @@ LL | fn take2>(_: P) {} = note: `SELF` has type `P` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:53:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here @@ -62,7 +62,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:53:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -70,7 +70,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:53:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` @@ -80,7 +80,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:53:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here @@ -92,7 +92,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:53:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -101,7 +101,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:53:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.rs similarity index 100% rename from tests/ui/associated-consts/projection-unspecified-but-bounded.rs rename to tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.rs diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.stderr similarity index 100% rename from tests/ui/associated-consts/projection-unspecified-but-bounded.stderr rename to tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.stderr diff --git a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs b/tests/ui/const-generics/associated-const-bindings/supertraits.rs similarity index 100% rename from tests/ui/associated-consts/assoc-const-eq-supertraits.rs rename to tests/ui/const-generics/associated-const-bindings/supertraits.rs diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.rs b/tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.rs similarity index 100% rename from tests/ui/const-generics/assoc_const_eq_diagnostic.rs rename to tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.rs diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr b/tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.stderr similarity index 87% rename from tests/ui/const-generics/assoc_const_eq_diagnostic.stderr rename to tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.stderr index 05e0ec93d494..6608df2ebfbc 100644 --- a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr +++ b/tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found variant `Mode::Cool` - --> $DIR/assoc_const_eq_diagnostic.rs:13:35 + --> $DIR/unbraced-enum-variant.rs:13:35 | LL | pub trait CoolStuff: Parse {} | ^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | pub trait CoolStuff: Parse {} | help: try using the variant's enum: `Mode` error[E0573]: expected type, found variant `Mode::Cool` - --> $DIR/assoc_const_eq_diagnostic.rs:19:17 + --> $DIR/unbraced-enum-variant.rs:19:17 | LL | fn no_help() -> Mode::Cool {} | ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn no_help() -> Mode::Cool {} | help: try using the variant's enum: `Mode` error: expected constant, found type - --> $DIR/assoc_const_eq_diagnostic.rs:13:35 + --> $DIR/unbraced-enum-variant.rs:13:35 | LL | pub trait CoolStuff: Parse {} | ---- ^^^^^^^^^^ unexpected type @@ -25,7 +25,7 @@ LL | pub trait CoolStuff: Parse {} | expected a constant because of this associated constant | note: the associated constant is defined here - --> $DIR/assoc_const_eq_diagnostic.rs:10:5 + --> $DIR/unbraced-enum-variant.rs:10:5 | LL | const MODE: Mode; | ^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | pub trait CoolStuff: Parse {} | + + error: expected constant, found type - --> $DIR/assoc_const_eq_diagnostic.rs:13:35 + --> $DIR/unbraced-enum-variant.rs:13:35 | LL | pub trait CoolStuff: Parse {} | ---- ^^^^^^^^^^ unexpected type @@ -43,7 +43,7 @@ LL | pub trait CoolStuff: Parse {} | expected a constant because of this associated constant | note: the associated constant is defined here - --> $DIR/assoc_const_eq_diagnostic.rs:10:5 + --> $DIR/unbraced-enum-variant.rs:10:5 | LL | const MODE: Mode; | ^^^^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | pub trait CoolStuff: Parse {} | + + error: expected constant, found type - --> $DIR/assoc_const_eq_diagnostic.rs:13:35 + --> $DIR/unbraced-enum-variant.rs:13:35 | LL | pub trait CoolStuff: Parse {} | ---- ^^^^^^^^^^ unexpected type @@ -62,7 +62,7 @@ LL | pub trait CoolStuff: Parse {} | expected a constant because of this associated constant | note: the associated constant is defined here - --> $DIR/assoc_const_eq_diagnostic.rs:10:5 + --> $DIR/unbraced-enum-variant.rs:10:5 | LL | const MODE: Mode; | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.rs similarity index 100% rename from tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs rename to tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.rs diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr similarity index 100% rename from tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr rename to tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr diff --git a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.rs similarity index 100% rename from tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs rename to tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.rs diff --git a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.stderr similarity index 100% rename from tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr rename to tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.stderr From b144a11d2cefaac358ea2e7f103893197fe58b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 7 Jan 2026 13:20:18 +0100 Subject: [PATCH 1816/3801] Replace more mentions of `associated_const_equality` --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs | 3 +-- compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs | 3 +-- .../{associated-const-equality.rs => assoc-const-bindings.rs} | 0 5 files changed, 4 insertions(+), 6 deletions(-) rename tests/ui/generic-const-items/{associated-const-equality.rs => assoc-const-bindings.rs} (100%) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7c922417ee29..4ad32d7c9fd9 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2394,7 +2394,7 @@ impl FnSig { /// * the `G = Ty` in `Trait = Ty>` /// * the `A: Bound` in `Trait` /// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy` -/// * the `C = { Ct }` in `Trait` (feature `associated_const_equality`) +/// * the `C = { Ct }` in `Trait` (feature `min_generic_const_args`) /// * the `f(..): Bound` in `Trait` (feature `return_type_notation`) #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct AssocItemConstraint { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e13782282891..1f3831243139 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3298,7 +3298,7 @@ pub enum ImplItemKind<'hir> { /// * the `G = Ty` in `Trait = Ty>` /// * the `A: Bound` in `Trait` /// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy` -/// * the `C = { Ct }` in `Trait` (feature `associated_const_equality`) +/// * the `C = { Ct }` in `Trait` (feature `min_generic_const_args`) /// * the `f(..): Bound` in `Trait` (feature `return_type_notation`) #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct AssocItemConstraint<'hir> { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 9ae6a9fac504..72d21371f66c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -575,8 +575,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME: point at the type params that don't have appropriate lifetimes: // struct S1 Fn(&i32, &i32) -> &'a i32>(F); // ---- ---- ^^^^^^^ - // NOTE(associated_const_equality): This error should be impossible to trigger - // with associated const equality constraints. + // NOTE(mgca): This error should be impossible to trigger with assoc const bindings. self.validate_late_bound_regions( late_bound_in_projection_ty, late_bound_in_term, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs index edb79592e6c5..2aed66d27e96 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs @@ -503,8 +503,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME: point at the type params that don't have appropriate lifetimes: // struct S1 Fn(&i32, &i32) -> &'a i32>(F); // ---- ---- ^^^^^^^ - // NOTE(associated_const_equality): This error should be impossible to trigger - // with associated const equality constraints. + // NOTE(mgca): This error should be impossible to trigger with assoc const bindings. self.validate_late_bound_regions( late_bound_in_projection_term, late_bound_in_term, diff --git a/tests/ui/generic-const-items/associated-const-equality.rs b/tests/ui/generic-const-items/assoc-const-bindings.rs similarity index 100% rename from tests/ui/generic-const-items/associated-const-equality.rs rename to tests/ui/generic-const-items/assoc-const-bindings.rs From 9f8bfd6b4a368b36181a4894fc9a89ccfd643385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 4 Dec 2025 21:17:40 +0100 Subject: [PATCH 1817/3801] Revert "Rollup merge of #149147 - chenyukang:yukang-fix-unused_assignments-macro-gen-147648, r=JonathanBrouwer" This reverts commit 82a17b30d8cd379a43c3ee8d12598e89e3be0fbd, reversing changes made to 5019bdaefeebecac42b778ae98def56cab69ab30. (cherry picked from commit 74387157c7edaf8a0ace3cbb54c42d2dfa7b8f93) --- compiler/rustc_mir_transform/src/liveness.rs | 5 ----- tests/ui/liveness/auxiliary/aux_issue_147648.rs | 7 ------- .../liveness/unused-assignments-from-macro-147648.rs | 10 ---------- 3 files changed, 22 deletions(-) delete mode 100644 tests/ui/liveness/auxiliary/aux_issue_147648.rs delete mode 100644 tests/ui/liveness/unused-assignments-from-macro-147648.rs diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 7ee7c3a81c7e..1d1ba455a81e 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -75,11 +75,6 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den return DenseBitSet::new_empty(0); } - // Don't run unused pass for items generated by foreign macros - if tcx.def_span(parent).in_external_macro(tcx.sess.source_map()) { - return DenseBitSet::new_empty(0); - } - let mut body = &*tcx.mir_promoted(def_id).0.borrow(); let mut body_mem; diff --git a/tests/ui/liveness/auxiliary/aux_issue_147648.rs b/tests/ui/liveness/auxiliary/aux_issue_147648.rs deleted file mode 100644 index ccb5ad6b8fc0..000000000000 --- a/tests/ui/liveness/auxiliary/aux_issue_147648.rs +++ /dev/null @@ -1,7 +0,0 @@ -#[macro_export] -macro_rules! unused_assign { - ($x:ident) => { - let mut $x = 1; - $x = 2; - }; -} diff --git a/tests/ui/liveness/unused-assignments-from-macro-147648.rs b/tests/ui/liveness/unused-assignments-from-macro-147648.rs deleted file mode 100644 index c32c281538b4..000000000000 --- a/tests/ui/liveness/unused-assignments-from-macro-147648.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ check-pass -//@ aux-build:aux_issue_147648.rs - -#![deny(unused_assignments)] - -extern crate aux_issue_147648; - -fn main() { - aux_issue_147648::unused_assign!(y); -} From 0aa11b5dd2abf908fc47c1d8d13abfa8b78c6117 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 19 Dec 2025 17:55:19 +0100 Subject: [PATCH 1818/3801] Add regression test for `const_item_interior_mutations` deref FP (cherry picked from commit 0bc29cec45412ee3cc68a1ef1556814885543d55) --- ...nst-item-interior-mutations-const-deref.rs | 30 +++++++++++++++ ...item-interior-mutations-const-deref.stderr | 37 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/ui/lint/const-item-interior-mutations-const-deref.rs create mode 100644 tests/ui/lint/const-item-interior-mutations-const-deref.stderr diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.rs b/tests/ui/lint/const-item-interior-mutations-const-deref.rs new file mode 100644 index 000000000000..ce684abacccd --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-deref.rs @@ -0,0 +1,30 @@ +// Regression test for +// +// We shouldn't lint on user types, including through deref. + +//@ check-pass + +use std::cell::Cell; +use std::ops::Deref; + +// Cut down version of the issue reproducer without the thread local to just a Deref +pub struct LocalKey { + inner: T, +} + +impl Deref for LocalKey { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; + +fn main() { + let count = LOCAL_COUNT.get(); + //~^ WARN mutation of an interior mutable `const` + LOCAL_COUNT.set(count); + //~^ WARN mutation of an interior mutable `const` +} diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.stderr b/tests/ui/lint/const-item-interior-mutations-const-deref.stderr new file mode 100644 index 000000000000..35696d0ba100 --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-deref.stderr @@ -0,0 +1,37 @@ +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/const-item-interior-mutations-const-deref.rs:26:17 + | +LL | let count = LOCAL_COUNT.get(); + | -----------^^^^^^ + | | + | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified + = help: for more details on interior mutability see + = note: `#[warn(const_item_interior_mutations)]` on by default +help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead + | +LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; +LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/const-item-interior-mutations-const-deref.rs:28:5 + | +LL | LOCAL_COUNT.set(count); + | -----------^^^^^^^^^^^ + | | + | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead + | +LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; +LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; + | + +warning: 2 warnings emitted + From 249d399caaa19663e9a0d0a9cf2765f304e6d7b4 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 19 Dec 2025 18:13:07 +0100 Subject: [PATCH 1819/3801] Don't lint on interior mutable `const` item coming from derefs (cherry picked from commit 2581c2571c904c180ec8dc2b0242413a5b251358) --- .../rustc_lint/src/interior_mutable_consts.rs | 8 ++++ ...nst-item-interior-mutations-const-deref.rs | 2 - ...item-interior-mutations-const-deref.stderr | 37 ------------------- 3 files changed, 8 insertions(+), 39 deletions(-) delete mode 100644 tests/ui/lint/const-item-interior-mutations-const-deref.stderr diff --git a/compiler/rustc_lint/src/interior_mutable_consts.rs b/compiler/rustc_lint/src/interior_mutable_consts.rs index 8576698dec33..4c7d2c6af93b 100644 --- a/compiler/rustc_lint/src/interior_mutable_consts.rs +++ b/compiler/rustc_lint/src/interior_mutable_consts.rs @@ -1,6 +1,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Expr, ExprKind, ItemKind, Node, find_attr}; +use rustc_middle::ty::adjustment::Adjust; use rustc_session::{declare_lint, declare_lint_pass}; use crate::lints::{ConstItemInteriorMutationsDiag, ConstItemInteriorMutationsSuggestionStatic}; @@ -77,6 +78,13 @@ impl<'tcx> LateLintPass<'tcx> for InteriorMutableConsts { if let ExprKind::Path(qpath) = &receiver.kind && let Res::Def(DefKind::Const | DefKind::AssocConst, const_did) = typeck.qpath_res(qpath, receiver.hir_id) + // Don't consider derefs as those can do arbitrary things + // like using thread local (see rust-lang/rust#150157) + && !cx + .typeck_results() + .expr_adjustments(receiver) + .into_iter() + .any(|adj| matches!(adj.kind, Adjust::Deref(_))) // Let's do the attribute check after the other checks for perf reasons && find_attr!( cx.tcx.get_all_attrs(method_did), diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.rs b/tests/ui/lint/const-item-interior-mutations-const-deref.rs index ce684abacccd..021e0952da70 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-deref.rs +++ b/tests/ui/lint/const-item-interior-mutations-const-deref.rs @@ -24,7 +24,5 @@ const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; fn main() { let count = LOCAL_COUNT.get(); - //~^ WARN mutation of an interior mutable `const` LOCAL_COUNT.set(count); - //~^ WARN mutation of an interior mutable `const` } diff --git a/tests/ui/lint/const-item-interior-mutations-const-deref.stderr b/tests/ui/lint/const-item-interior-mutations-const-deref.stderr deleted file mode 100644 index 35696d0ba100..000000000000 --- a/tests/ui/lint/const-item-interior-mutations-const-deref.stderr +++ /dev/null @@ -1,37 +0,0 @@ -warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-deref.rs:26:17 - | -LL | let count = LOCAL_COUNT.get(); - | -----------^^^^^^ - | | - | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` - | - = note: each usage of a `const` item creates a new temporary - = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified - = help: for more details on interior mutability see - = note: `#[warn(const_item_interior_mutations)]` on by default -help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead - | -LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; -LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; - | - -warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const-deref.rs:28:5 - | -LL | LOCAL_COUNT.set(count); - | -----------^^^^^^^^^^^ - | | - | `LOCAL_COUNT` is a interior mutable `const` item of type `LocalKey>` - | - = note: each usage of a `const` item creates a new temporary - = note: only the temporaries and never the original `const LOCAL_COUNT` will be modified - = help: for more details on interior mutability see -help: for a shared instance of `LOCAL_COUNT`, consider making it a `static` item instead - | -LL - const LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; -LL + static LOCAL_COUNT: LocalKey> = LocalKey { inner: Cell::new(8) }; - | - -warning: 2 warnings emitted - From c5b220e1de013b5cdac52d9820f5f55b40401ab7 Mon Sep 17 00:00:00 2001 From: Sayantan Chakraborty <142906350+sayantn@users.noreply.github.com> Date: Fri, 2 Jan 2026 19:35:29 +0000 Subject: [PATCH 1820/3801] Merge pull request #1985 from usamoi/vpmaddwd Use LLVM intrinsics for `madd` intrinsics (cherry picked from commit 85f3ba3dd1d4d510c9ce1c6f7aed58fcb53a448c) --- .../stdarch/crates/core_arch/src/x86/avx2.rs | 21 ++++++++++---- .../crates/core_arch/src/x86/avx512bw.rs | 29 ++++++++++--------- .../stdarch/crates/core_arch/src/x86/sse2.rs | 21 ++++++++++---- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 8be302cabc77..e22e39fca882 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -1754,12 +1754,19 @@ pub fn _mm256_inserti128_si256(a: __m256i, b: __m128i) -> __m25 #[cfg_attr(test, assert_instr(vpmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { - let r: i32x16 = simd_mul(simd_cast(a.as_i16x16()), simd_cast(b.as_i16x16())); - let even: i32x8 = simd_shuffle!(r, r, [0, 2, 4, 6, 8, 10, 12, 14]); - let odd: i32x8 = simd_shuffle!(r, r, [1, 3, 5, 7, 9, 11, 13, 15]); - simd_add(even, odd).as_m256i() - } + // It's a trick used in the Adler-32 algorithm to perform a widening addition. + // + // ```rust + // #[target_feature(enable = "avx2")] + // unsafe fn widening_add(mad: __m256i) -> __m256i { + // _mm256_madd_epi16(mad, _mm256_set1_epi16(1)) + // } + // ``` + // + // If we implement this using generic vector intrinsics, the optimizer + // will eliminate this pattern, and `vpmaddwd` will no longer be emitted. + // For this reason, we use x86 intrinsics. + unsafe { transmute(pmaddwd(a.as_i16x16(), b.as_i16x16())) } } /// Vertically multiplies each unsigned 8-bit integer from `a` with the @@ -3701,6 +3708,8 @@ unsafe extern "C" { fn phaddsw(a: i16x16, b: i16x16) -> i16x16; #[link_name = "llvm.x86.avx2.phsub.sw"] fn phsubsw(a: i16x16, b: i16x16) -> i16x16; + #[link_name = "llvm.x86.avx2.pmadd.wd"] + fn pmaddwd(a: i16x16, b: i16x16) -> i32x8; #[link_name = "llvm.x86.avx2.pmadd.ub.sw"] fn pmaddubsw(a: u8x32, b: i8x32) -> i16x16; #[link_name = "llvm.x86.avx2.mpsadbw"] diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 0e2dd3ad4068..d6cc0921750b 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -5847,20 +5847,19 @@ pub unsafe fn _mm_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask16, a: __m128 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmaddwd))] pub fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i { - unsafe { - let r: i32x32 = simd_mul(simd_cast(a.as_i16x32()), simd_cast(b.as_i16x32())); - let even: i32x16 = simd_shuffle!( - r, - r, - [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30] - ); - let odd: i32x16 = simd_shuffle!( - r, - r, - [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31] - ); - simd_add(even, odd).as_m512i() - } + // It's a trick used in the Adler-32 algorithm to perform a widening addition. + // + // ```rust + // #[target_feature(enable = "avx512bw")] + // unsafe fn widening_add(mad: __m512i) -> __m512i { + // _mm512_madd_epi16(mad, _mm512_set1_epi16(1)) + // } + // ``` + // + // If we implement this using generic vector intrinsics, the optimizer + // will eliminate this pattern, and `vpmaddwd` will no longer be emitted. + // For this reason, we use x86 intrinsics. + unsafe { transmute(vpmaddwd(a.as_i16x32(), b.as_i16x32())) } } /// Multiply packed signed 16-bit integers in a and b, producing intermediate signed 32-bit integers. Horizontally add adjacent pairs of intermediate 32-bit integers, and pack the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -11687,6 +11686,8 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.pmul.hr.sw.512"] fn vpmulhrsw(a: i16x32, b: i16x32) -> i16x32; + #[link_name = "llvm.x86.avx512.pmaddw.d.512"] + fn vpmaddwd(a: i16x32, b: i16x32) -> i32x16; #[link_name = "llvm.x86.avx512.pmaddubs.w.512"] fn vpmaddubsw(a: u8x64, b: i8x64) -> i16x32; diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index 11335856fb22..c5b051bfb69d 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -201,12 +201,19 @@ pub fn _mm_avg_epu16(a: __m128i, b: __m128i) -> __m128i { #[cfg_attr(test, assert_instr(pmaddwd))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { - let r: i32x8 = simd_mul(simd_cast(a.as_i16x8()), simd_cast(b.as_i16x8())); - let even: i32x4 = simd_shuffle!(r, r, [0, 2, 4, 6]); - let odd: i32x4 = simd_shuffle!(r, r, [1, 3, 5, 7]); - simd_add(even, odd).as_m128i() - } + // It's a trick used in the Adler-32 algorithm to perform a widening addition. + // + // ```rust + // #[target_feature(enable = "sse2")] + // unsafe fn widening_add(mad: __m128i) -> __m128i { + // _mm_madd_epi16(mad, _mm_set1_epi16(1)) + // } + // ``` + // + // If we implement this using generic vector intrinsics, the optimizer + // will eliminate this pattern, and `pmaddwd` will no longer be emitted. + // For this reason, we use x86 intrinsics. + unsafe { transmute(pmaddwd(a.as_i16x8(), b.as_i16x8())) } } /// Compares packed 16-bit integers in `a` and `b`, and returns the packed @@ -3054,6 +3061,8 @@ unsafe extern "C" { fn lfence(); #[link_name = "llvm.x86.sse2.mfence"] fn mfence(); + #[link_name = "llvm.x86.sse2.pmadd.wd"] + fn pmaddwd(a: i16x8, b: i16x8) -> i32x4; #[link_name = "llvm.x86.sse2.psad.bw"] fn psadbw(a: u8x16, b: u8x16) -> u64x2; #[link_name = "llvm.x86.sse2.psll.w"] From d851fe6684e39f2dd8d1f2966f541b3d309a2713 Mon Sep 17 00:00:00 2001 From: usamoi Date: Sat, 3 Jan 2026 21:36:43 +0800 Subject: [PATCH 1821/3801] partially revert https://github.com/rust-lang/rust/commit/8d597aa36528dada3cbd9bcfec889c2da6ecaaac (cherry picked from commit 5e4168b162ba9286161226b315a2d3632f31e804) --- src/tools/miri/src/shims/x86/avx2.rs | 36 ++++++++++++++++++++++++++++ src/tools/miri/src/shims/x86/sse2.rs | 36 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 8fe225c494d5..16d8235f8dbc 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -245,6 +245,42 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { shift_simd_by_scalar(this, left, right, which, dest)?; } + // Used to implement the _mm256_madd_epi16 function. + // Multiplies packed signed 16-bit integers in `left` and `right`, producing + // intermediate signed 32-bit integers. Horizontally add adjacent pairs of + // intermediate 32-bit integers, and pack the results in `dest`. + "pmadd.wd" => { + let [left, right] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + let (left, left_len) = this.project_to_simd(left)?; + let (right, right_len) = this.project_to_simd(right)?; + let (dest, dest_len) = this.project_to_simd(dest)?; + + assert_eq!(left_len, right_len); + assert_eq!(dest_len.strict_mul(2), left_len); + + for i in 0..dest_len { + let j1 = i.strict_mul(2); + let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; + let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; + + let j2 = j1.strict_add(1); + let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; + let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; + + let dest = this.project_index(&dest, i)?; + + // Multiplications are i16*i16->i32, which will not overflow. + let mul1 = i32::from(left1).strict_mul(right1.into()); + let mul2 = i32::from(left2).strict_mul(right2.into()); + // However, this addition can overflow in the most extreme case + // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 + let res = mul1.wrapping_add(mul2); + + this.write_scalar(Scalar::from_i32(res), &dest)?; + } + } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn) diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 838981390307..3fbab9ba789e 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -278,6 +278,42 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?; } } + // Used to implement the _mm_madd_epi16 function. + // Multiplies packed signed 16-bit integers in `left` and `right`, producing + // intermediate signed 32-bit integers. Horizontally add adjacent pairs of + // intermediate 32-bit integers, and pack the results in `dest`. + "pmadd.wd" => { + let [left, right] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + let (left, left_len) = this.project_to_simd(left)?; + let (right, right_len) = this.project_to_simd(right)?; + let (dest, dest_len) = this.project_to_simd(dest)?; + + assert_eq!(left_len, right_len); + assert_eq!(dest_len.strict_mul(2), left_len); + + for i in 0..dest_len { + let j1 = i.strict_mul(2); + let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; + let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; + + let j2 = j1.strict_add(1); + let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; + let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; + + let dest = this.project_index(&dest, i)?; + + // Multiplications are i16*i16->i32, which will not overflow. + let mul1 = i32::from(left1).strict_mul(right1.into()); + let mul2 = i32::from(left2).strict_mul(right2.into()); + // However, this addition can overflow in the most extreme case + // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 + let res = mul1.wrapping_add(mul2); + + this.write_scalar(Scalar::from_i32(res), &dest)?; + } + } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn) From 3c136cc9e18c0f0bb848ff0a147aeb8ffa4ce20d Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Fri, 9 Jan 2026 00:40:31 +0000 Subject: [PATCH 1822/3801] Fix broken documentation links to SipHash The documentation of `SipHasher` previously linked to a page about SipHash on https://131002.net, a domain registered to Jean-Philippe Aumasson, one of the co-authors of the original SipHash paper (alongside Daniel J Bernstein). That domain now redirects to another of Mr Aumasson's domains, https://www.aumasson.jp, but which does not host a similar page dedicated to SipHash. Instead, his site links to a GitHub repository containing a C implementation together with links to the original research paper. Mr Bernstein's own site, https://cr.yp.to, only hosts a copy of the research paper. Therefore the GitHub repository appears to be the most official and complete reference to which we can link. --- library/core/src/hash/sip.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs index 780e522c48eb..4f2e8a22d180 100644 --- a/library/core/src/hash/sip.rs +++ b/library/core/src/hash/sip.rs @@ -10,7 +10,7 @@ use crate::{cmp, ptr}; /// This is currently the default hashing function used by standard library /// (e.g., `collections::HashMap` uses it by default). /// -/// See: +/// See: #[unstable(feature = "hashmap_internals", issue = "none")] #[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")] #[derive(Debug, Clone, Default)] @@ -21,7 +21,7 @@ pub struct SipHasher13 { /// An implementation of SipHash 2-4. /// -/// See: +/// See: #[unstable(feature = "hashmap_internals", issue = "none")] #[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")] #[derive(Debug, Clone, Default)] @@ -31,7 +31,7 @@ struct SipHasher24 { /// An implementation of SipHash 2-4. /// -/// See: +/// See: /// /// SipHash is a general-purpose hashing function: it runs at a good /// speed (competitive with Spooky and City) and permits strong _keyed_ From 5932078c79d7171d23dcf892e129ef5154410b62 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Mon, 22 Dec 2025 04:31:14 -0800 Subject: [PATCH 1823/3801] =?UTF-8?q?Stop=20emitting=20UbChecks=20on=20eve?= =?UTF-8?q?ry=20Vec=E2=86=92Slice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spotted this in PR148766's test changes. It doesn't seem like this ubcheck would catch anything useful; let's see if skipping it helps perf. --- library/alloc/src/vec/mod.rs | 12 +- library/core/src/slice/cmp.rs | 13 +- ...ng_operand.test.GVN.64bit.panic-abort.diff | 22 +- ..._conditions.JumpThreading.panic-abort.diff | 458 +++++------------- ...conditions.JumpThreading.panic-unwind.diff | 458 +++++------------- ...ace.PreCodegen.after.64bit.panic-abort.mir | 26 +- ...d_constant.main.GVN.64bit.panic-abort.diff | 72 ++- ..._to_slice.PreCodegen.after.panic-abort.mir | 33 +- ...to_slice.PreCodegen.after.panic-unwind.mir | 33 +- 9 files changed, 310 insertions(+), 817 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index d3da7efe4ddf..379e964f0a0c 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1747,7 +1747,11 @@ impl Vec { // * We only construct `&mut` references to `self.buf` through `&mut self` methods; borrow- // check ensures that it is not possible to mutably alias `self.buf` within the // returned lifetime. - unsafe { slice::from_raw_parts(self.as_ptr(), self.len) } + unsafe { + // normally this would use `slice::from_raw_parts`, but it's + // instantiated often enough that avoiding the UB check is worth it + &*core::intrinsics::aggregate_raw_ptr::<*const [T], _, _>(self.as_ptr(), self.len) + } } /// Extracts a mutable slice of the entire vector. @@ -1779,7 +1783,11 @@ impl Vec { // * We only construct references to `self.buf` through `&self` and `&mut self` methods; // borrow-check ensures that it is not possible to construct a reference to `self.buf` // within the returned lifetime. - unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } + unsafe { + // normally this would use `slice::from_raw_parts_mut`, but it's + // instantiated often enough that avoiding the UB check is worth it + &mut *core::intrinsics::aggregate_raw_ptr::<*mut [T], _, _>(self.as_mut_ptr(), self.len) + } } /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index fd1ca23fb79c..dfc0b565195e 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -13,13 +13,14 @@ impl const PartialEq<[U]> for [T] where T: [const] PartialEq, { + // It's not worth trying to inline the loops underneath here *in MIR*, + // and preventing it encourages more useful inlining upstream, + // such as in `::eq`. + // The codegen backend can still inline it later if needed. + #[rustc_no_mir_inline] fn eq(&self, other: &[U]) -> bool { SlicePartialEq::equal(self, other) } - - fn ne(&self, other: &[U]) -> bool { - SlicePartialEq::not_equal(self, other) - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -99,10 +100,6 @@ impl PartialOrd for [T] { #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const trait SlicePartialEq { fn equal(&self, other: &[B]) -> bool; - - fn not_equal(&self, other: &[B]) -> bool { - !self.equal(other) - } } // Generic slice equality diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 408ff60712e1..1b75a2bcba8b 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -26,12 +26,12 @@ scope 4 { debug _x => _8; } - scope 18 (inlined foo) { + scope 19 (inlined foo) { let mut _27: *const [()]; } } - scope 16 (inlined slice_from_raw_parts::<()>) { - scope 17 (inlined std::ptr::from_raw_parts::<[()], ()>) { + scope 17 (inlined slice_from_raw_parts::<()>) { + scope 18 (inlined std::ptr::from_raw_parts::<[()], ()>) { } } } @@ -49,19 +49,21 @@ scope 7 { let _21: std::ptr::NonNull<[u8]>; scope 8 { - scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) { - scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) { - scope 13 (inlined NonNull::<[u8]>::cast::) { + scope 12 (inlined NonNull::<[u8]>::as_mut_ptr) { + scope 13 (inlined NonNull::<[u8]>::as_non_null_ptr) { + scope 14 (inlined NonNull::<[u8]>::cast::) { let mut _25: *mut [u8]; - scope 14 (inlined NonNull::<[u8]>::as_ptr) { + scope 15 (inlined NonNull::<[u8]>::as_ptr) { } } } - scope 15 (inlined NonNull::::as_ptr) { + scope 16 (inlined NonNull::::as_ptr) { } } } scope 10 (inlined ::allocate) { + scope 11 (inlined std::alloc::Global::alloc_impl) { + } } } scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) { @@ -192,8 +194,8 @@ + _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; StorageDead(_24); StorageLive(_19); -- _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _18, const false) -> [return: bb7, unwind unreachable]; -+ _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; +- _19 = std::alloc::Global::alloc_impl_runtime(copy _18, const false) -> [return: bb7, unwind unreachable]; ++ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; } bb7: { diff --git a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff index 8777ac426d78..0875d437296d 100644 --- a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff @@ -48,8 +48,8 @@ let _29: &str; scope 7 (inlined String::as_str) { let _30: &[u8]; - let mut _31: &std::vec::Vec; scope 8 (inlined Vec::::as_slice) { + let _31: *const [u8]; let mut _32: *const u8; let mut _33: usize; scope 9 (inlined Vec::::as_ptr) { @@ -71,161 +71,83 @@ } } } - scope 18 (inlined #[track_caller] std::slice::from_raw_parts::<'_, u8>) { - let _35: (); - let mut _36: *mut (); - let _37: *const [u8]; - scope 19 (inlined ub_checks::check_language_ub) { - scope 20 (inlined ub_checks::check_language_ub::runtime) { - } - } - scope 21 (inlined std::mem::size_of::) { - } - scope 22 (inlined std::mem::align_of::) { - } - scope 23 (inlined slice_from_raw_parts::) { - scope 24 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - } - } - } } - scope 25 (inlined from_utf8_unchecked) { + scope 18 (inlined from_utf8_unchecked) { } } - scope 26 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 19 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 27 (inlined #[track_caller] core::str::traits:: for str>::index) { - scope 28 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 20 (inlined #[track_caller] core::str::traits:: for str>::index) { + scope 21 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 29 (inlined core::str::traits::::eq) { - let mut _38: &&[u8]; - let _39: &[u8]; - let mut _40: &&[u8]; - let _41: &[u8]; - scope 30 (inlined core::str::::as_bytes) { + scope 22 (inlined core::str::traits::::eq) { + let mut _35: &&[u8]; + let _36: &[u8]; + let mut _37: &&[u8]; + let _38: &[u8]; + scope 23 (inlined core::str::::as_bytes) { } - scope 31 (inlined core::str::::as_bytes) { + scope 24 (inlined core::str::::as_bytes) { } - scope 32 (inlined std::cmp::impls::::eq) { - scope 33 (inlined core::slice::cmp::::eq) { - scope 34 (inlined <[u8] as core::slice::cmp::SlicePartialEq>::equal) { - let mut _42: bool; - let mut _43: usize; - let mut _44: usize; - let _45: usize; - let mut _46: i32; - let mut _47: *const u8; - let mut _48: *const u8; - scope 35 { - scope 37 (inlined core::slice::::as_ptr) { - let mut _50: *const [u8]; - } - scope 38 (inlined core::slice::::as_ptr) { - let mut _51: *const [u8]; - } - } - scope 36 (inlined std::mem::size_of_val::<[u8]>) { - let mut _49: *const [u8]; - } - } - } + scope 25 (inlined std::cmp::impls::::eq) { } } } } - scope 39 (inlined std::cmp::impls:: for &String>::eq) { - let mut _52: &std::string::String; - let mut _53: &str; - scope 40 (inlined >::eq) { - scope 41 (inlined #[track_caller] >::index) { - let _54: &str; - scope 42 (inlined String::as_str) { - let _55: &[u8]; - let mut _56: &std::vec::Vec; - scope 43 (inlined Vec::::as_slice) { - let mut _57: *const u8; - let mut _58: usize; - scope 44 (inlined Vec::::as_ptr) { - scope 45 (inlined alloc::raw_vec::RawVec::::ptr) { - scope 46 (inlined alloc::raw_vec::RawVecInner::ptr::) { - scope 47 (inlined alloc::raw_vec::RawVecInner::non_null::) { - let mut _59: std::ptr::NonNull; - scope 48 (inlined Unique::::cast::) { - scope 49 (inlined NonNull::::cast::) { - scope 50 (inlined NonNull::::as_ptr) { + scope 26 (inlined std::cmp::impls:: for &String>::eq) { + let mut _39: &std::string::String; + let mut _40: &str; + scope 27 (inlined >::eq) { + scope 28 (inlined #[track_caller] >::index) { + let _41: &str; + scope 29 (inlined String::as_str) { + let _42: &[u8]; + scope 30 (inlined Vec::::as_slice) { + let _43: *const [u8]; + let mut _44: *const u8; + let mut _45: usize; + scope 31 (inlined Vec::::as_ptr) { + scope 32 (inlined alloc::raw_vec::RawVec::::ptr) { + scope 33 (inlined alloc::raw_vec::RawVecInner::ptr::) { + scope 34 (inlined alloc::raw_vec::RawVecInner::non_null::) { + let mut _46: std::ptr::NonNull; + scope 35 (inlined Unique::::cast::) { + scope 36 (inlined NonNull::::cast::) { + scope 37 (inlined NonNull::::as_ptr) { } } } - scope 51 (inlined Unique::::as_non_null_ptr) { + scope 38 (inlined Unique::::as_non_null_ptr) { } } - scope 52 (inlined NonNull::::as_ptr) { + scope 39 (inlined NonNull::::as_ptr) { } } } } - scope 53 (inlined #[track_caller] std::slice::from_raw_parts::<'_, u8>) { - let _60: (); - let mut _61: *mut (); - let _62: *const [u8]; - scope 54 (inlined ub_checks::check_language_ub) { - scope 55 (inlined ub_checks::check_language_ub::runtime) { - } - } - scope 56 (inlined std::mem::size_of::) { - } - scope 57 (inlined std::mem::align_of::) { - } - scope 58 (inlined slice_from_raw_parts::) { - scope 59 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - } - } - } } - scope 60 (inlined from_utf8_unchecked) { + scope 40 (inlined from_utf8_unchecked) { } } - scope 61 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 41 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 62 (inlined #[track_caller] core::str::traits:: for str>::index) { - scope 63 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 42 (inlined #[track_caller] core::str::traits:: for str>::index) { + scope 43 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 64 (inlined core::str::traits::::eq) { - let mut _63: &&[u8]; - let _64: &[u8]; - let mut _65: &&[u8]; - let _66: &[u8]; - scope 65 (inlined core::str::::as_bytes) { + scope 44 (inlined core::str::traits::::eq) { + let mut _47: &&[u8]; + let _48: &[u8]; + let mut _49: &&[u8]; + let _50: &[u8]; + scope 45 (inlined core::str::::as_bytes) { } - scope 66 (inlined core::str::::as_bytes) { + scope 46 (inlined core::str::::as_bytes) { } - scope 67 (inlined std::cmp::impls::::eq) { - scope 68 (inlined core::slice::cmp::::eq) { - scope 69 (inlined <[u8] as core::slice::cmp::SlicePartialEq>::equal) { - let mut _67: bool; - let mut _68: usize; - let mut _69: usize; - let _70: usize; - let mut _71: i32; - let mut _72: *const u8; - let mut _73: *const u8; - scope 70 { - scope 72 (inlined core::slice::::as_ptr) { - let mut _75: *const [u8]; - } - scope 73 (inlined core::slice::::as_ptr) { - let mut _76: *const [u8]; - } - } - scope 71 (inlined std::mem::size_of_val::<[u8]>) { - let mut _74: *const [u8]; - } - } - } + scope 47 (inlined std::cmp::impls::::eq) { } } } @@ -253,7 +175,7 @@ bb3: { _1 = chained_conditions::BacktraceStyle::Off; - goto -> bb18; -+ goto -> bb37; ++ goto -> bb23; } bb4: { @@ -272,15 +194,27 @@ _27 = copy (*_8); _28 = copy (*_10); StorageLive(_29); - StorageLive(_35); StorageLive(_30); - StorageLive(_34); + StorageLive(_31); StorageLive(_32); + StorageLive(_34); _34 = copy ((((((*_27).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); _32 = copy _34 as *const u8 (Transmute); + StorageDead(_34); StorageLive(_33); _33 = copy (((*_27).0: std::vec::Vec).1: usize); - switchInt(UbChecks) -> [0: bb21, otherwise: bb19]; + _31 = *const [u8] from (copy _32, move _33); + StorageDead(_33); + StorageDead(_32); + _30 = &(*_31); + StorageDead(_31); + _29 = copy _30 as &str (Transmute); + StorageDead(_30); + StorageLive(_36); + StorageLive(_38); + _36 = copy _29 as &[u8] (Transmute); + _38 = copy _28 as &[u8] (Transmute); + _7 = <[u8] as PartialEq>::eq(move _36, move _38) -> [return: bb19, unwind unreachable]; } bb5: { @@ -311,27 +245,39 @@ StorageLive(_17); _20 = const chained_conditions::promoted[0]; _17 = &(*_20); - StorageLive(_52); - StorageLive(_53); - _52 = copy (*_15); - _53 = copy (*_17); - StorageLive(_54); - StorageLive(_60); - StorageLive(_55); - StorageLive(_59); - StorageLive(_57); - _59 = copy ((((((*_52).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); - _57 = copy _59 as *const u8 (Transmute); - StorageLive(_58); - _58 = copy (((*_52).0: std::vec::Vec).1: usize); - switchInt(UbChecks) -> [0: bb29, otherwise: bb27]; + StorageLive(_39); + StorageLive(_40); + _39 = copy (*_15); + _40 = copy (*_17); + StorageLive(_41); + StorageLive(_42); + StorageLive(_43); + StorageLive(_44); + StorageLive(_46); + _46 = copy ((((((*_39).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); + _44 = copy _46 as *const u8 (Transmute); + StorageDead(_46); + StorageLive(_45); + _45 = copy (((*_39).0: std::vec::Vec).1: usize); + _43 = *const [u8] from (copy _44, move _45); + StorageDead(_45); + StorageDead(_44); + _42 = &(*_43); + StorageDead(_43); + _41 = copy _42 as &str (Transmute); + StorageDead(_42); + StorageLive(_48); + StorageLive(_50); + _48 = copy _41 as &[u8] (Transmute); + _50 = copy _40 as &[u8] (Transmute); + _14 = <[u8] as PartialEq>::eq(move _48, move _50) -> [return: bb20, unwind unreachable]; } bb7: { StorageDead(_5); StorageDead(_6); - goto -> bb18; -+ goto -> bb39; ++ goto -> bb21; } bb8: { @@ -354,14 +300,14 @@ StorageDead(_13); _1 = chained_conditions::BacktraceStyle::Short; - goto -> bb18; -+ goto -> bb37; ++ goto -> bb23; } bb10: { StorageDead(_12); StorageDead(_13); - goto -> bb18; -+ goto -> bb39; ++ goto -> bb21; } bb11: { @@ -406,223 +352,39 @@ } bb19: { - StorageLive(_36); - _36 = copy _34 as *mut () (Transmute); - _35 = std::slice::from_raw_parts::precondition_check(move _36, const ::SIZE, const ::ALIGN, copy _33) -> [return: bb20, unwind unreachable]; - } - - bb20: { + StorageDead(_38); StorageDead(_36); - goto -> bb21; - } - - bb21: { - StorageLive(_37); - _37 = *const [u8] from (copy _32, copy _33); - _30 = &(*_37); - StorageDead(_37); - StorageDead(_33); - StorageDead(_32); - StorageDead(_34); - _29 = copy _30 as &str (Transmute); - StorageDead(_30); - StorageLive(_39); - StorageLive(_41); - _39 = copy _29 as &[u8] (Transmute); - _41 = copy _28 as &[u8] (Transmute); - StorageLive(_45); - StorageLive(_50); - StorageLive(_51); - StorageLive(_42); - StorageLive(_43); - _43 = PtrMetadata(copy _39); - StorageLive(_44); - _44 = PtrMetadata(copy _41); - _42 = Ne(move _43, move _44); - switchInt(move _42) -> [0: bb24, otherwise: bb23]; - } - - bb22: { - StorageDead(_51); - StorageDead(_50); - StorageDead(_45); - StorageDead(_41); - StorageDead(_39); - StorageDead(_35); StorageDead(_29); StorageDead(_28); StorageDead(_27); switchInt(move _7) -> [0: bb6, otherwise: bb5]; } - bb23: { - StorageDead(_44); - StorageDead(_43); - _7 = const false; - StorageDead(_42); -- goto -> bb22; -+ goto -> bb35; - } - - bb24: { - StorageDead(_44); - StorageDead(_43); - StorageDead(_42); - StorageLive(_49); - _49 = &raw const (*_39); - _45 = std::intrinsics::size_of_val::<[u8]>(move _49) -> [return: bb26, unwind unreachable]; - } - - bb25: { + bb20: { + StorageDead(_50); StorageDead(_48); - StorageDead(_47); - _7 = Eq(move _46, const 0_i32); - StorageDead(_46); - goto -> bb22; - } - - bb26: { - StorageDead(_49); - StorageLive(_46); - StorageLive(_47); - _50 = &raw const (*_39); - _47 = copy _50 as *const u8 (PtrToPtr); - StorageLive(_48); - _51 = &raw const (*_41); - _48 = copy _51 as *const u8 (PtrToPtr); - _46 = compare_bytes(move _47, move _48, move _45) -> [return: bb25, unwind unreachable]; - } - - bb27: { - StorageLive(_61); - _61 = copy _59 as *mut () (Transmute); - _60 = std::slice::from_raw_parts::precondition_check(move _61, const ::SIZE, const ::ALIGN, copy _58) -> [return: bb28, unwind unreachable]; - } - - bb28: { - StorageDead(_61); - goto -> bb29; - } - - bb29: { - StorageLive(_62); - _62 = *const [u8] from (copy _57, copy _58); - _55 = &(*_62); - StorageDead(_62); - StorageDead(_58); - StorageDead(_57); - StorageDead(_59); - _54 = copy _55 as &str (Transmute); - StorageDead(_55); - StorageLive(_64); - StorageLive(_66); - _64 = copy _54 as &[u8] (Transmute); - _66 = copy _53 as &[u8] (Transmute); - StorageLive(_70); - StorageLive(_75); - StorageLive(_76); - StorageLive(_67); - StorageLive(_68); - _68 = PtrMetadata(copy _64); - StorageLive(_69); - _69 = PtrMetadata(copy _66); - _67 = Ne(move _68, move _69); - switchInt(move _67) -> [0: bb32, otherwise: bb31]; - } - - bb30: { - StorageDead(_76); - StorageDead(_75); - StorageDead(_70); - StorageDead(_66); - StorageDead(_64); - StorageDead(_60); - StorageDead(_54); - StorageDead(_53); - StorageDead(_52); + StorageDead(_41); + StorageDead(_40); + StorageDead(_39); switchInt(move _14) -> [0: bb9, otherwise: bb8]; - } - - bb31: { - StorageDead(_69); - StorageDead(_68); - _14 = const false; - StorageDead(_67); -- goto -> bb30; -+ goto -> bb36; - } - - bb32: { - StorageDead(_69); - StorageDead(_68); - StorageDead(_67); - StorageLive(_74); - _74 = &raw const (*_64); - _70 = std::intrinsics::size_of_val::<[u8]>(move _74) -> [return: bb34, unwind unreachable]; - } - - bb33: { - StorageDead(_73); - StorageDead(_72); - _14 = Eq(move _71, const 0_i32); - StorageDead(_71); - goto -> bb30; - } - - bb34: { - StorageDead(_74); - StorageLive(_71); - StorageLive(_72); - _75 = &raw const (*_64); - _72 = copy _75 as *const u8 (PtrToPtr); - StorageLive(_73); - _76 = &raw const (*_66); - _73 = copy _76 as *const u8 (PtrToPtr); - _71 = compare_bytes(move _72, move _73, move _70) -> [return: bb33, unwind unreachable]; + } + -+ bb35: { -+ StorageDead(_51); -+ StorageDead(_50); -+ StorageDead(_45); -+ StorageDead(_41); -+ StorageDead(_39); -+ StorageDead(_35); -+ StorageDead(_29); -+ StorageDead(_28); -+ StorageDead(_27); -+ goto -> bb6; -+ } -+ -+ bb36: { -+ StorageDead(_76); -+ StorageDead(_75); -+ StorageDead(_70); -+ StorageDead(_66); -+ StorageDead(_64); -+ StorageDead(_60); -+ StorageDead(_54); -+ StorageDead(_53); -+ StorageDead(_52); -+ goto -> bb9; -+ } -+ -+ bb37: { ++ bb21: { + _24 = discriminant(_2); -+ switchInt(move _24) -> [1: bb38, otherwise: bb15]; ++ switchInt(move _24) -> [1: bb22, otherwise: bb15]; + } + -+ bb38: { -+ goto -> bb17; -+ } -+ -+ bb39: { -+ _24 = discriminant(_2); -+ switchInt(move _24) -> [1: bb40, otherwise: bb15]; -+ } -+ -+ bb40: { ++ bb22: { + goto -> bb15; ++ } ++ ++ bb23: { ++ _24 = discriminant(_2); ++ switchInt(move _24) -> [1: bb24, otherwise: bb15]; ++ } ++ ++ bb24: { ++ goto -> bb17; } } diff --git a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff index 822d33c89391..b942eeed37e0 100644 --- a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff @@ -48,8 +48,8 @@ let _29: &str; scope 7 (inlined String::as_str) { let _30: &[u8]; - let mut _31: &std::vec::Vec; scope 8 (inlined Vec::::as_slice) { + let _31: *const [u8]; let mut _32: *const u8; let mut _33: usize; scope 9 (inlined Vec::::as_ptr) { @@ -71,161 +71,83 @@ } } } - scope 18 (inlined #[track_caller] std::slice::from_raw_parts::<'_, u8>) { - let _35: (); - let mut _36: *mut (); - let _37: *const [u8]; - scope 19 (inlined ub_checks::check_language_ub) { - scope 20 (inlined ub_checks::check_language_ub::runtime) { - } - } - scope 21 (inlined std::mem::size_of::) { - } - scope 22 (inlined std::mem::align_of::) { - } - scope 23 (inlined slice_from_raw_parts::) { - scope 24 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - } - } - } } - scope 25 (inlined from_utf8_unchecked) { + scope 18 (inlined from_utf8_unchecked) { } } - scope 26 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 19 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 27 (inlined #[track_caller] core::str::traits:: for str>::index) { - scope 28 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 20 (inlined #[track_caller] core::str::traits:: for str>::index) { + scope 21 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 29 (inlined core::str::traits::::eq) { - let mut _38: &&[u8]; - let _39: &[u8]; - let mut _40: &&[u8]; - let _41: &[u8]; - scope 30 (inlined core::str::::as_bytes) { + scope 22 (inlined core::str::traits::::eq) { + let mut _35: &&[u8]; + let _36: &[u8]; + let mut _37: &&[u8]; + let _38: &[u8]; + scope 23 (inlined core::str::::as_bytes) { } - scope 31 (inlined core::str::::as_bytes) { + scope 24 (inlined core::str::::as_bytes) { } - scope 32 (inlined std::cmp::impls::::eq) { - scope 33 (inlined core::slice::cmp::::eq) { - scope 34 (inlined <[u8] as core::slice::cmp::SlicePartialEq>::equal) { - let mut _42: bool; - let mut _43: usize; - let mut _44: usize; - let _45: usize; - let mut _46: i32; - let mut _47: *const u8; - let mut _48: *const u8; - scope 35 { - scope 37 (inlined core::slice::::as_ptr) { - let mut _50: *const [u8]; - } - scope 38 (inlined core::slice::::as_ptr) { - let mut _51: *const [u8]; - } - } - scope 36 (inlined std::mem::size_of_val::<[u8]>) { - let mut _49: *const [u8]; - } - } - } + scope 25 (inlined std::cmp::impls::::eq) { } } } } - scope 39 (inlined std::cmp::impls:: for &String>::eq) { - let mut _52: &std::string::String; - let mut _53: &str; - scope 40 (inlined >::eq) { - scope 41 (inlined #[track_caller] >::index) { - let _54: &str; - scope 42 (inlined String::as_str) { - let _55: &[u8]; - let mut _56: &std::vec::Vec; - scope 43 (inlined Vec::::as_slice) { - let mut _57: *const u8; - let mut _58: usize; - scope 44 (inlined Vec::::as_ptr) { - scope 45 (inlined alloc::raw_vec::RawVec::::ptr) { - scope 46 (inlined alloc::raw_vec::RawVecInner::ptr::) { - scope 47 (inlined alloc::raw_vec::RawVecInner::non_null::) { - let mut _59: std::ptr::NonNull; - scope 48 (inlined Unique::::cast::) { - scope 49 (inlined NonNull::::cast::) { - scope 50 (inlined NonNull::::as_ptr) { + scope 26 (inlined std::cmp::impls:: for &String>::eq) { + let mut _39: &std::string::String; + let mut _40: &str; + scope 27 (inlined >::eq) { + scope 28 (inlined #[track_caller] >::index) { + let _41: &str; + scope 29 (inlined String::as_str) { + let _42: &[u8]; + scope 30 (inlined Vec::::as_slice) { + let _43: *const [u8]; + let mut _44: *const u8; + let mut _45: usize; + scope 31 (inlined Vec::::as_ptr) { + scope 32 (inlined alloc::raw_vec::RawVec::::ptr) { + scope 33 (inlined alloc::raw_vec::RawVecInner::ptr::) { + scope 34 (inlined alloc::raw_vec::RawVecInner::non_null::) { + let mut _46: std::ptr::NonNull; + scope 35 (inlined Unique::::cast::) { + scope 36 (inlined NonNull::::cast::) { + scope 37 (inlined NonNull::::as_ptr) { } } } - scope 51 (inlined Unique::::as_non_null_ptr) { + scope 38 (inlined Unique::::as_non_null_ptr) { } } - scope 52 (inlined NonNull::::as_ptr) { + scope 39 (inlined NonNull::::as_ptr) { } } } } - scope 53 (inlined #[track_caller] std::slice::from_raw_parts::<'_, u8>) { - let _60: (); - let mut _61: *mut (); - let _62: *const [u8]; - scope 54 (inlined ub_checks::check_language_ub) { - scope 55 (inlined ub_checks::check_language_ub::runtime) { - } - } - scope 56 (inlined std::mem::size_of::) { - } - scope 57 (inlined std::mem::align_of::) { - } - scope 58 (inlined slice_from_raw_parts::) { - scope 59 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - } - } - } } - scope 60 (inlined from_utf8_unchecked) { + scope 40 (inlined from_utf8_unchecked) { } } - scope 61 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 41 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 62 (inlined #[track_caller] core::str::traits:: for str>::index) { - scope 63 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 42 (inlined #[track_caller] core::str::traits:: for str>::index) { + scope 43 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 64 (inlined core::str::traits::::eq) { - let mut _63: &&[u8]; - let _64: &[u8]; - let mut _65: &&[u8]; - let _66: &[u8]; - scope 65 (inlined core::str::::as_bytes) { + scope 44 (inlined core::str::traits::::eq) { + let mut _47: &&[u8]; + let _48: &[u8]; + let mut _49: &&[u8]; + let _50: &[u8]; + scope 45 (inlined core::str::::as_bytes) { } - scope 66 (inlined core::str::::as_bytes) { + scope 46 (inlined core::str::::as_bytes) { } - scope 67 (inlined std::cmp::impls::::eq) { - scope 68 (inlined core::slice::cmp::::eq) { - scope 69 (inlined <[u8] as core::slice::cmp::SlicePartialEq>::equal) { - let mut _67: bool; - let mut _68: usize; - let mut _69: usize; - let _70: usize; - let mut _71: i32; - let mut _72: *const u8; - let mut _73: *const u8; - scope 70 { - scope 72 (inlined core::slice::::as_ptr) { - let mut _75: *const [u8]; - } - scope 73 (inlined core::slice::::as_ptr) { - let mut _76: *const [u8]; - } - } - scope 71 (inlined std::mem::size_of_val::<[u8]>) { - let mut _74: *const [u8]; - } - } - } + scope 47 (inlined std::cmp::impls::::eq) { } } } @@ -253,7 +175,7 @@ bb3: { _1 = chained_conditions::BacktraceStyle::Off; - goto -> bb19; -+ goto -> bb41; ++ goto -> bb27; } bb4: { @@ -272,15 +194,27 @@ _27 = copy (*_8); _28 = copy (*_10); StorageLive(_29); - StorageLive(_35); StorageLive(_30); - StorageLive(_34); + StorageLive(_31); StorageLive(_32); + StorageLive(_34); _34 = copy ((((((*_27).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); _32 = copy _34 as *const u8 (Transmute); + StorageDead(_34); StorageLive(_33); _33 = copy (((*_27).0: std::vec::Vec).1: usize); - switchInt(UbChecks) -> [0: bb25, otherwise: bb23]; + _31 = *const [u8] from (copy _32, move _33); + StorageDead(_33); + StorageDead(_32); + _30 = &(*_31); + StorageDead(_31); + _29 = copy _30 as &str (Transmute); + StorageDead(_30); + StorageLive(_36); + StorageLive(_38); + _36 = copy _29 as &[u8] (Transmute); + _38 = copy _28 as &[u8] (Transmute); + _7 = <[u8] as PartialEq>::eq(move _36, move _38) -> [return: bb23, unwind: bb22]; } bb5: { @@ -311,27 +245,39 @@ StorageLive(_17); _20 = const chained_conditions::promoted[0]; _17 = &(*_20); - StorageLive(_52); - StorageLive(_53); - _52 = copy (*_15); - _53 = copy (*_17); - StorageLive(_54); - StorageLive(_60); - StorageLive(_55); - StorageLive(_59); - StorageLive(_57); - _59 = copy ((((((*_52).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); - _57 = copy _59 as *const u8 (Transmute); - StorageLive(_58); - _58 = copy (((*_52).0: std::vec::Vec).1: usize); - switchInt(UbChecks) -> [0: bb33, otherwise: bb31]; + StorageLive(_39); + StorageLive(_40); + _39 = copy (*_15); + _40 = copy (*_17); + StorageLive(_41); + StorageLive(_42); + StorageLive(_43); + StorageLive(_44); + StorageLive(_46); + _46 = copy ((((((*_39).0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); + _44 = copy _46 as *const u8 (Transmute); + StorageDead(_46); + StorageLive(_45); + _45 = copy (((*_39).0: std::vec::Vec).1: usize); + _43 = *const [u8] from (copy _44, move _45); + StorageDead(_45); + StorageDead(_44); + _42 = &(*_43); + StorageDead(_43); + _41 = copy _42 as &str (Transmute); + StorageDead(_42); + StorageLive(_48); + StorageLive(_50); + _48 = copy _41 as &[u8] (Transmute); + _50 = copy _40 as &[u8] (Transmute); + _14 = <[u8] as PartialEq>::eq(move _48, move _50) -> [return: bb24, unwind: bb22]; } bb7: { StorageDead(_5); StorageDead(_6); - goto -> bb19; -+ goto -> bb43; ++ goto -> bb25; } bb8: { @@ -354,14 +300,14 @@ StorageDead(_13); _1 = chained_conditions::BacktraceStyle::Short; - goto -> bb19; -+ goto -> bb41; ++ goto -> bb27; } bb10: { StorageDead(_12); StorageDead(_13); - goto -> bb19; -+ goto -> bb43; ++ goto -> bb25; } bb11: { @@ -423,223 +369,39 @@ } bb23: { - StorageLive(_36); - _36 = copy _34 as *mut () (Transmute); - _35 = std::slice::from_raw_parts::precondition_check(move _36, const ::SIZE, const ::ALIGN, copy _33) -> [return: bb24, unwind unreachable]; - } - - bb24: { + StorageDead(_38); StorageDead(_36); - goto -> bb25; - } - - bb25: { - StorageLive(_37); - _37 = *const [u8] from (copy _32, copy _33); - _30 = &(*_37); - StorageDead(_37); - StorageDead(_33); - StorageDead(_32); - StorageDead(_34); - _29 = copy _30 as &str (Transmute); - StorageDead(_30); - StorageLive(_39); - StorageLive(_41); - _39 = copy _29 as &[u8] (Transmute); - _41 = copy _28 as &[u8] (Transmute); - StorageLive(_45); - StorageLive(_50); - StorageLive(_51); - StorageLive(_42); - StorageLive(_43); - _43 = PtrMetadata(copy _39); - StorageLive(_44); - _44 = PtrMetadata(copy _41); - _42 = Ne(move _43, move _44); - switchInt(move _42) -> [0: bb28, otherwise: bb27]; - } - - bb26: { - StorageDead(_51); - StorageDead(_50); - StorageDead(_45); - StorageDead(_41); - StorageDead(_39); - StorageDead(_35); StorageDead(_29); StorageDead(_28); StorageDead(_27); switchInt(move _7) -> [0: bb6, otherwise: bb5]; } - bb27: { - StorageDead(_44); - StorageDead(_43); - _7 = const false; - StorageDead(_42); -- goto -> bb26; -+ goto -> bb39; - } - - bb28: { - StorageDead(_44); - StorageDead(_43); - StorageDead(_42); - StorageLive(_49); - _49 = &raw const (*_39); - _45 = std::intrinsics::size_of_val::<[u8]>(move _49) -> [return: bb30, unwind unreachable]; - } - - bb29: { + bb24: { + StorageDead(_50); StorageDead(_48); - StorageDead(_47); - _7 = Eq(move _46, const 0_i32); - StorageDead(_46); - goto -> bb26; - } - - bb30: { - StorageDead(_49); - StorageLive(_46); - StorageLive(_47); - _50 = &raw const (*_39); - _47 = copy _50 as *const u8 (PtrToPtr); - StorageLive(_48); - _51 = &raw const (*_41); - _48 = copy _51 as *const u8 (PtrToPtr); - _46 = compare_bytes(move _47, move _48, move _45) -> [return: bb29, unwind unreachable]; - } - - bb31: { - StorageLive(_61); - _61 = copy _59 as *mut () (Transmute); - _60 = std::slice::from_raw_parts::precondition_check(move _61, const ::SIZE, const ::ALIGN, copy _58) -> [return: bb32, unwind unreachable]; - } - - bb32: { - StorageDead(_61); - goto -> bb33; - } - - bb33: { - StorageLive(_62); - _62 = *const [u8] from (copy _57, copy _58); - _55 = &(*_62); - StorageDead(_62); - StorageDead(_58); - StorageDead(_57); - StorageDead(_59); - _54 = copy _55 as &str (Transmute); - StorageDead(_55); - StorageLive(_64); - StorageLive(_66); - _64 = copy _54 as &[u8] (Transmute); - _66 = copy _53 as &[u8] (Transmute); - StorageLive(_70); - StorageLive(_75); - StorageLive(_76); - StorageLive(_67); - StorageLive(_68); - _68 = PtrMetadata(copy _64); - StorageLive(_69); - _69 = PtrMetadata(copy _66); - _67 = Ne(move _68, move _69); - switchInt(move _67) -> [0: bb36, otherwise: bb35]; - } - - bb34: { - StorageDead(_76); - StorageDead(_75); - StorageDead(_70); - StorageDead(_66); - StorageDead(_64); - StorageDead(_60); - StorageDead(_54); - StorageDead(_53); - StorageDead(_52); + StorageDead(_41); + StorageDead(_40); + StorageDead(_39); switchInt(move _14) -> [0: bb9, otherwise: bb8]; - } - - bb35: { - StorageDead(_69); - StorageDead(_68); - _14 = const false; - StorageDead(_67); -- goto -> bb34; -+ goto -> bb40; - } - - bb36: { - StorageDead(_69); - StorageDead(_68); - StorageDead(_67); - StorageLive(_74); - _74 = &raw const (*_64); - _70 = std::intrinsics::size_of_val::<[u8]>(move _74) -> [return: bb38, unwind unreachable]; - } - - bb37: { - StorageDead(_73); - StorageDead(_72); - _14 = Eq(move _71, const 0_i32); - StorageDead(_71); - goto -> bb34; - } - - bb38: { - StorageDead(_74); - StorageLive(_71); - StorageLive(_72); - _75 = &raw const (*_64); - _72 = copy _75 as *const u8 (PtrToPtr); - StorageLive(_73); - _76 = &raw const (*_66); - _73 = copy _76 as *const u8 (PtrToPtr); - _71 = compare_bytes(move _72, move _73, move _70) -> [return: bb37, unwind unreachable]; + } + -+ bb39: { -+ StorageDead(_51); -+ StorageDead(_50); -+ StorageDead(_45); -+ StorageDead(_41); -+ StorageDead(_39); -+ StorageDead(_35); -+ StorageDead(_29); -+ StorageDead(_28); -+ StorageDead(_27); -+ goto -> bb6; -+ } -+ -+ bb40: { -+ StorageDead(_76); -+ StorageDead(_75); -+ StorageDead(_70); -+ StorageDead(_66); -+ StorageDead(_64); -+ StorageDead(_60); -+ StorageDead(_54); -+ StorageDead(_53); -+ StorageDead(_52); -+ goto -> bb9; -+ } -+ -+ bb41: { ++ bb25: { + _24 = discriminant(_2); -+ switchInt(move _24) -> [1: bb42, otherwise: bb16]; ++ switchInt(move _24) -> [1: bb26, otherwise: bb16]; + } + -+ bb42: { -+ goto -> bb18; -+ } -+ -+ bb43: { -+ _24 = discriminant(_2); -+ switchInt(move _24) -> [1: bb44, otherwise: bb16]; -+ } -+ -+ bb44: { ++ bb26: { + goto -> bb16; ++ } ++ ++ bb27: { ++ _24 = discriminant(_2); ++ switchInt(move _24) -> [1: bb28, otherwise: bb16]; ++ } ++ ++ bb28: { ++ goto -> bb18; } } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir index 791d6b71a6f7..013361d1d2fb 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir @@ -25,17 +25,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } scope 18 (inlined ::deallocate) { - let mut _9: *mut u8; - scope 19 (inlined Layout::size) { - } - scope 20 (inlined NonNull::::as_ptr) { - } - scope 21 (inlined std::alloc::dealloc) { - let mut _10: usize; - scope 22 (inlined Layout::size) { - } - scope 23 (inlined Layout::align) { - scope 24 (inlined std::ptr::Alignment::as_usize) { + scope 19 (inlined std::alloc::Global::deallocate_impl) { + scope 20 (inlined std::alloc::Global::deallocate_impl_runtime) { + let mut _9: *mut u8; + scope 21 (inlined Layout::size) { + } + scope 22 (inlined NonNull::::as_ptr) { + } + scope 23 (inlined std::alloc::dealloc) { + let mut _10: usize; + scope 24 (inlined Layout::size) { + } + scope 25 (inlined Layout::align) { + scope 26 (inlined std::ptr::Alignment::as_usize) { + } + } } } } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff index 1dbe9394e709..b45a0f4a9bdd 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff @@ -9,33 +9,33 @@ let mut _4: *mut [u8]; let mut _5: std::ptr::NonNull<[u8]>; let mut _6: std::result::Result, std::alloc::AllocError>; - let mut _7: &std::alloc::Global; - let mut _8: std::alloc::Layout; + let mut _7: std::alloc::Layout; scope 1 { debug layout => _1; - let mut _9: &std::alloc::Global; scope 2 { debug ptr => _3; } scope 5 (inlined ::allocate) { - } - scope 6 (inlined #[track_caller] Result::, std::alloc::AllocError>::unwrap) { - let mut _12: isize; - let _13: std::alloc::AllocError; - let mut _14: !; - let mut _15: &dyn std::fmt::Debug; - let _16: &std::alloc::AllocError; - scope 7 { + scope 6 (inlined std::alloc::Global::alloc_impl) { } + } + scope 7 (inlined #[track_caller] Result::, std::alloc::AllocError>::unwrap) { + let mut _10: isize; + let _11: std::alloc::AllocError; + let mut _12: !; + let mut _13: &dyn std::fmt::Debug; + let _14: &std::alloc::AllocError; scope 8 { } + scope 9 { + } } - scope 9 (inlined NonNull::<[u8]>::as_ptr) { + scope 10 (inlined NonNull::<[u8]>::as_ptr) { } } scope 3 (inlined #[track_caller] Option::::unwrap) { - let mut _10: isize; - let mut _11: !; + let mut _8: isize; + let mut _9: !; scope 4 { } } @@ -46,10 +46,10 @@ StorageLive(_2); - _2 = Option::::None; + _2 = const Option::::None; - StorageLive(_10); -- _10 = discriminant(_2); -- switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb1]; -+ _10 = const 0_isize; + StorageLive(_8); +- _8 = discriminant(_2); +- switchInt(move _8) -> [0: bb2, 1: bb3, otherwise: bb1]; ++ _8 = const 0_isize; + switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb1]; } @@ -58,48 +58,44 @@ } bb2: { - _11 = option::unwrap_failed() -> unwind unreachable; + _9 = option::unwrap_failed() -> unwind unreachable; } bb3: { - _1 = move ((_2 as Some).0: std::alloc::Layout); + _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; - StorageDead(_10); + StorageDead(_8); StorageDead(_2); StorageLive(_3); StorageLive(_4); StorageLive(_5); StorageLive(_6); StorageLive(_7); - _9 = const main::promoted[0]; - _7 = copy _9; - StorageLive(_8); -- _8 = copy _1; -- _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind unreachable]; -+ _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; -+ _6 = std::alloc::Global::alloc_impl(copy _9, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable]; +- _7 = copy _1; +- _6 = std::alloc::Global::alloc_impl_runtime(move _7, const false) -> [return: bb4, unwind unreachable]; ++ _7 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}; ++ _6 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_8); StorageDead(_7); - StorageLive(_12); - StorageLive(_16); - _12 = discriminant(_6); - switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1]; + StorageLive(_10); + StorageLive(_14); + _10 = discriminant(_6); + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb1]; } bb5: { - StorageLive(_15); - _16 = &_13; - _15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit)); - _14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable; + StorageLive(_13); + _14 = &_11; + _13 = copy _14 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit)); + _12 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _13) -> unwind unreachable; } bb6: { _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>); - StorageDead(_16); - StorageDead(_12); + StorageDead(_14); + StorageDead(_10); StorageDead(_6); _4 = copy _5 as *mut [u8] (Transmute); StorageDead(_5); diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir index 2eee8a97db0d..8308ecbad716 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir @@ -9,6 +9,7 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { debug self => _1; let mut _3: *const u8; let mut _4: usize; + let _5: *const [u8]; scope 3 (inlined Vec::::as_ptr) { debug self => _1; scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { @@ -29,43 +30,23 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } } } - scope 12 (inlined #[track_caller] std::slice::from_raw_parts::<'_, u8>) { - debug data => _3; - debug len => _4; - let _5: *const [u8]; - scope 13 (inlined core::ub_checks::check_language_ub) { - scope 14 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - scope 15 (inlined std::mem::size_of::) { - } - scope 16 (inlined std::mem::align_of::) { - } - scope 17 (inlined slice_from_raw_parts::) { - debug data => _3; - debug len => _4; - scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - debug data_pointer => _3; - } - } - } } } bb0: { - StorageLive(_2); + StorageLive(_5); StorageLive(_3); + StorageLive(_2); _2 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); _3 = copy _2 as *const u8 (Transmute); + StorageDead(_2); StorageLive(_4); _4 = copy ((*_1).1: usize); - StorageLive(_5); - _5 = *const [u8] from (copy _3, copy _4); - _0 = &(*_5); - StorageDead(_5); + _5 = *const [u8] from (copy _3, move _4); StorageDead(_4); StorageDead(_3); - StorageDead(_2); + _0 = &(*_5); + StorageDead(_5); return; } } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir index 2eee8a97db0d..8308ecbad716 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir @@ -9,6 +9,7 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { debug self => _1; let mut _3: *const u8; let mut _4: usize; + let _5: *const [u8]; scope 3 (inlined Vec::::as_ptr) { debug self => _1; scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { @@ -29,43 +30,23 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { } } } - scope 12 (inlined #[track_caller] std::slice::from_raw_parts::<'_, u8>) { - debug data => _3; - debug len => _4; - let _5: *const [u8]; - scope 13 (inlined core::ub_checks::check_language_ub) { - scope 14 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - scope 15 (inlined std::mem::size_of::) { - } - scope 16 (inlined std::mem::align_of::) { - } - scope 17 (inlined slice_from_raw_parts::) { - debug data => _3; - debug len => _4; - scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { - debug data_pointer => _3; - } - } - } } } bb0: { - StorageLive(_2); + StorageLive(_5); StorageLive(_3); + StorageLive(_2); _2 = copy (((((*_1).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); _3 = copy _2 as *const u8 (Transmute); + StorageDead(_2); StorageLive(_4); _4 = copy ((*_1).1: usize); - StorageLive(_5); - _5 = *const [u8] from (copy _3, copy _4); - _0 = &(*_5); - StorageDead(_5); + _5 = *const [u8] from (copy _3, move _4); StorageDead(_4); StorageDead(_3); - StorageDead(_2); + _0 = &(*_5); + StorageDead(_5); return; } } From c48df5dcf189c730edc2eb1cf93117af584cceee Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 23 Dec 2025 22:42:03 -0800 Subject: [PATCH 1824/3801] Move the `rustc_no_mir_inline` down a level --- library/core/src/slice/cmp.rs | 21 ++++++-- ..._conditions.JumpThreading.panic-abort.diff | 52 ++++++++++--------- ...conditions.JumpThreading.panic-unwind.diff | 52 ++++++++++--------- 3 files changed, 72 insertions(+), 53 deletions(-) diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index dfc0b565195e..c3ff928a3277 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -13,11 +13,7 @@ impl const PartialEq<[U]> for [T] where T: [const] PartialEq, { - // It's not worth trying to inline the loops underneath here *in MIR*, - // and preventing it encourages more useful inlining upstream, - // such as in `::eq`. - // The codegen backend can still inline it later if needed. - #[rustc_no_mir_inline] + #[inline] fn eq(&self, other: &[U]) -> bool { SlicePartialEq::equal(self, other) } @@ -108,6 +104,11 @@ impl const SlicePartialEq for [A] where A: [const] PartialEq, { + // It's not worth trying to inline the loops underneath here *in MIR*, + // and preventing it encourages more useful inlining upstream, + // such as in `::eq`. + // The codegen backend can still inline it later if needed. + #[rustc_no_mir_inline] default fn equal(&self, other: &[B]) -> bool { if self.len() != other.len() { return false; @@ -137,6 +138,16 @@ impl const SlicePartialEq for [A] where A: [const] BytewiseEq, { + // This is usually a pretty good backend inlining candidate because the + // intrinsic tends to just be `memcmp`. However, as of 2025-12 letting + // MIR inline this makes reuse worse because it means that, for example, + // `String::eq` doesn't inline, whereas by keeping this from inling all + // the wrappers until the call to this disappear. If the heuristics have + // changed and this is no longer fruitful, though, please do remove it. + // In the mean time, it's fine to not inline it in MIR because the backend + // will still inline it if it things it's important to do so. + #[rustc_no_mir_inline] + #[inline] fn equal(&self, other: &[B]) -> bool { if self.len() != other.len() { return false; diff --git a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff index 0875d437296d..3cf28f4b60af 100644 --- a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff @@ -92,62 +92,66 @@ scope 24 (inlined core::str::::as_bytes) { } scope 25 (inlined std::cmp::impls::::eq) { + scope 26 (inlined core::slice::cmp::::eq) { + } } } } } - scope 26 (inlined std::cmp::impls:: for &String>::eq) { + scope 27 (inlined std::cmp::impls:: for &String>::eq) { let mut _39: &std::string::String; let mut _40: &str; - scope 27 (inlined >::eq) { - scope 28 (inlined #[track_caller] >::index) { + scope 28 (inlined >::eq) { + scope 29 (inlined #[track_caller] >::index) { let _41: &str; - scope 29 (inlined String::as_str) { + scope 30 (inlined String::as_str) { let _42: &[u8]; - scope 30 (inlined Vec::::as_slice) { + scope 31 (inlined Vec::::as_slice) { let _43: *const [u8]; let mut _44: *const u8; let mut _45: usize; - scope 31 (inlined Vec::::as_ptr) { - scope 32 (inlined alloc::raw_vec::RawVec::::ptr) { - scope 33 (inlined alloc::raw_vec::RawVecInner::ptr::) { - scope 34 (inlined alloc::raw_vec::RawVecInner::non_null::) { + scope 32 (inlined Vec::::as_ptr) { + scope 33 (inlined alloc::raw_vec::RawVec::::ptr) { + scope 34 (inlined alloc::raw_vec::RawVecInner::ptr::) { + scope 35 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _46: std::ptr::NonNull; - scope 35 (inlined Unique::::cast::) { - scope 36 (inlined NonNull::::cast::) { - scope 37 (inlined NonNull::::as_ptr) { + scope 36 (inlined Unique::::cast::) { + scope 37 (inlined NonNull::::cast::) { + scope 38 (inlined NonNull::::as_ptr) { } } } - scope 38 (inlined Unique::::as_non_null_ptr) { + scope 39 (inlined Unique::::as_non_null_ptr) { } } - scope 39 (inlined NonNull::::as_ptr) { + scope 40 (inlined NonNull::::as_ptr) { } } } } } - scope 40 (inlined from_utf8_unchecked) { + scope 41 (inlined from_utf8_unchecked) { } } - scope 41 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 42 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 42 (inlined #[track_caller] core::str::traits:: for str>::index) { - scope 43 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 43 (inlined #[track_caller] core::str::traits:: for str>::index) { + scope 44 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 44 (inlined core::str::traits::::eq) { + scope 45 (inlined core::str::traits::::eq) { let mut _47: &&[u8]; let _48: &[u8]; let mut _49: &&[u8]; let _50: &[u8]; - scope 45 (inlined core::str::::as_bytes) { - } scope 46 (inlined core::str::::as_bytes) { } - scope 47 (inlined std::cmp::impls::::eq) { + scope 47 (inlined core::str::::as_bytes) { + } + scope 48 (inlined std::cmp::impls::::eq) { + scope 49 (inlined core::slice::cmp::::eq) { + } } } } @@ -214,7 +218,7 @@ StorageLive(_38); _36 = copy _29 as &[u8] (Transmute); _38 = copy _28 as &[u8] (Transmute); - _7 = <[u8] as PartialEq>::eq(move _36, move _38) -> [return: bb19, unwind unreachable]; + _7 = <[u8] as core::slice::cmp::SlicePartialEq>::equal(move _36, move _38) -> [return: bb19, unwind unreachable]; } bb5: { @@ -270,7 +274,7 @@ StorageLive(_50); _48 = copy _41 as &[u8] (Transmute); _50 = copy _40 as &[u8] (Transmute); - _14 = <[u8] as PartialEq>::eq(move _48, move _50) -> [return: bb20, unwind unreachable]; + _14 = <[u8] as core::slice::cmp::SlicePartialEq>::equal(move _48, move _50) -> [return: bb20, unwind unreachable]; } bb7: { diff --git a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff index b942eeed37e0..2f0d83f92792 100644 --- a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff @@ -92,62 +92,66 @@ scope 24 (inlined core::str::::as_bytes) { } scope 25 (inlined std::cmp::impls::::eq) { + scope 26 (inlined core::slice::cmp::::eq) { + } } } } } - scope 26 (inlined std::cmp::impls:: for &String>::eq) { + scope 27 (inlined std::cmp::impls:: for &String>::eq) { let mut _39: &std::string::String; let mut _40: &str; - scope 27 (inlined >::eq) { - scope 28 (inlined #[track_caller] >::index) { + scope 28 (inlined >::eq) { + scope 29 (inlined #[track_caller] >::index) { let _41: &str; - scope 29 (inlined String::as_str) { + scope 30 (inlined String::as_str) { let _42: &[u8]; - scope 30 (inlined Vec::::as_slice) { + scope 31 (inlined Vec::::as_slice) { let _43: *const [u8]; let mut _44: *const u8; let mut _45: usize; - scope 31 (inlined Vec::::as_ptr) { - scope 32 (inlined alloc::raw_vec::RawVec::::ptr) { - scope 33 (inlined alloc::raw_vec::RawVecInner::ptr::) { - scope 34 (inlined alloc::raw_vec::RawVecInner::non_null::) { + scope 32 (inlined Vec::::as_ptr) { + scope 33 (inlined alloc::raw_vec::RawVec::::ptr) { + scope 34 (inlined alloc::raw_vec::RawVecInner::ptr::) { + scope 35 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _46: std::ptr::NonNull; - scope 35 (inlined Unique::::cast::) { - scope 36 (inlined NonNull::::cast::) { - scope 37 (inlined NonNull::::as_ptr) { + scope 36 (inlined Unique::::cast::) { + scope 37 (inlined NonNull::::cast::) { + scope 38 (inlined NonNull::::as_ptr) { } } } - scope 38 (inlined Unique::::as_non_null_ptr) { + scope 39 (inlined Unique::::as_non_null_ptr) { } } - scope 39 (inlined NonNull::::as_ptr) { + scope 40 (inlined NonNull::::as_ptr) { } } } } } - scope 40 (inlined from_utf8_unchecked) { + scope 41 (inlined from_utf8_unchecked) { } } - scope 41 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 42 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 42 (inlined #[track_caller] core::str::traits:: for str>::index) { - scope 43 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { + scope 43 (inlined #[track_caller] core::str::traits:: for str>::index) { + scope 44 (inlined #[track_caller] core::str::traits:: for RangeFull>::index) { } } - scope 44 (inlined core::str::traits::::eq) { + scope 45 (inlined core::str::traits::::eq) { let mut _47: &&[u8]; let _48: &[u8]; let mut _49: &&[u8]; let _50: &[u8]; - scope 45 (inlined core::str::::as_bytes) { - } scope 46 (inlined core::str::::as_bytes) { } - scope 47 (inlined std::cmp::impls::::eq) { + scope 47 (inlined core::str::::as_bytes) { + } + scope 48 (inlined std::cmp::impls::::eq) { + scope 49 (inlined core::slice::cmp::::eq) { + } } } } @@ -214,7 +218,7 @@ StorageLive(_38); _36 = copy _29 as &[u8] (Transmute); _38 = copy _28 as &[u8] (Transmute); - _7 = <[u8] as PartialEq>::eq(move _36, move _38) -> [return: bb23, unwind: bb22]; + _7 = <[u8] as core::slice::cmp::SlicePartialEq>::equal(move _36, move _38) -> [return: bb23, unwind: bb22]; } bb5: { @@ -270,7 +274,7 @@ StorageLive(_50); _48 = copy _41 as &[u8] (Transmute); _50 = copy _40 as &[u8] (Transmute); - _14 = <[u8] as PartialEq>::eq(move _48, move _50) -> [return: bb24, unwind: bb22]; + _14 = <[u8] as core::slice::cmp::SlicePartialEq>::equal(move _48, move _50) -> [return: bb24, unwind: bb22]; } bb7: { From 26be33ae18b2aaa376eba9e755b54bc11e104a7b Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Thu, 8 Jan 2026 15:07:24 +0800 Subject: [PATCH 1825/3801] Fix not disable string escape highlights Example --- with config `strings: false` ```rust fn main() { format_args!("foo\nbar\invalid"); } ``` **Before this PR** ```rust fn main() { format_args!("foo\nbar\invalid"); // ^^ EscapeSequence // ^^ InvalidEscapeSequence } ``` **After this PR** ```rust fn main() { format_args!("foo\nbar\invalid"); } ``` --- .../crates/ide/src/syntax_highlighting.rs | 16 ++++--- .../ide/src/syntax_highlighting/escape.rs | 43 ++++++++++++----- .../ide/src/syntax_highlighting/highlights.rs | 8 +++- .../test_data/highlight_strings_disabled.html | 47 +++++++++++++++++++ .../ide/src/syntax_highlighting/tests.rs | 17 +++++++ 5 files changed, 113 insertions(+), 18 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings_disabled.html diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs index e7c5f95a250e..e64fd6488f2a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs @@ -513,21 +513,21 @@ fn string_injections( ); if !string.is_raw() { - highlight_escape_string(hl, &string); + highlight_escape_string(hl, config, &string); } } } else if let Some(byte_string) = ast::ByteString::cast(token.clone()) { if !byte_string.is_raw() { - highlight_escape_string(hl, &byte_string); + highlight_escape_string(hl, config, &byte_string); } } else if let Some(c_string) = ast::CString::cast(token.clone()) { if !c_string.is_raw() { - highlight_escape_string(hl, &c_string); + highlight_escape_string(hl, config, &c_string); } } else if let Some(char) = ast::Char::cast(token.clone()) { - highlight_escape_char(hl, &char) + highlight_escape_char(hl, config, &char) } else if let Some(byte) = ast::Byte::cast(token) { - highlight_escape_byte(hl, &byte) + highlight_escape_byte(hl, config, &byte) } ControlFlow::Continue(()) } @@ -586,7 +586,11 @@ fn descend_token( fn filter_by_config(highlight: &mut Highlight, config: &HighlightConfig<'_>) -> bool { match &mut highlight.tag { - HlTag::StringLiteral if !config.strings => return false, + HlTag::StringLiteral | HlTag::EscapeSequence | HlTag::InvalidEscapeSequence + if !config.strings => + { + return false; + } HlTag::Comment if !config.comments => return false, // If punctuation is disabled, make the macro bang part of the macro call again. tag @ HlTag::Punctuation(HlPunct::MacroBang) => { diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs index 094f88f3a864..4da69cc43d9e 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs @@ -1,10 +1,14 @@ //! Syntax highlighting for escape sequences use crate::syntax_highlighting::highlights::Highlights; -use crate::{HlRange, HlTag}; +use crate::{HighlightConfig, HlRange, HlTag}; use syntax::ast::{Byte, Char, IsString}; use syntax::{AstToken, TextRange, TextSize}; -pub(super) fn highlight_escape_string(stack: &mut Highlights, string: &T) { +pub(super) fn highlight_escape_string( + stack: &mut Highlights, + config: &HighlightConfig<'_>, + string: &T, +) { let text = string.text(); let start = string.syntax().text_range().start(); string.escaped_char_ranges(&mut |piece_range, char| { @@ -13,16 +17,23 @@ pub(super) fn highlight_escape_string(stack: &mut Highlights, strin Ok(_) => HlTag::EscapeSequence, Err(_) => HlTag::InvalidEscapeSequence, }; - stack.add(HlRange { - range: piece_range + start, - highlight: highlight.into(), - binding_hash: None, - }); + stack.add_with( + config, + HlRange { + range: piece_range + start, + highlight: highlight.into(), + binding_hash: None, + }, + ); } }); } -pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char) { +pub(super) fn highlight_escape_char( + stack: &mut Highlights, + config: &HighlightConfig<'_>, + char: &Char, +) { if char.value().is_err() { // We do not emit invalid escapes highlighting here. The lexer would likely be in a bad // state and this token contains junk, since `'` is not a reliable delimiter (consider @@ -43,10 +54,17 @@ pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char) { char.syntax().text_range().start() + TextSize::from(1), TextSize::from(text.len() as u32), ); - stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) + stack.add_with( + config, + HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }, + ) } -pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte) { +pub(super) fn highlight_escape_byte( + stack: &mut Highlights, + config: &HighlightConfig<'_>, + byte: &Byte, +) { if byte.value().is_err() { // See `highlight_escape_char` for why no error highlighting here. return; @@ -65,5 +83,8 @@ pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte) { byte.syntax().text_range().start() + TextSize::from(2), TextSize::from(text.len() as u32), ); - stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) + stack.add_with( + config, + HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }, + ) } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlights.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlights.rs index 340290eafedb..6fe4d0844338 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlights.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlights.rs @@ -4,7 +4,7 @@ use std::iter; use stdx::equal_range_by; use syntax::TextRange; -use crate::{HlRange, HlTag}; +use crate::{HighlightConfig, HlRange, HlTag}; pub(super) struct Highlights { root: Node, @@ -26,6 +26,12 @@ impl Highlights { self.root.add(hl_range); } + pub(super) fn add_with(&mut self, config: &HighlightConfig<'_>, mut hl_range: HlRange) { + if super::filter_by_config(&mut hl_range.highlight, config) { + self.root.add(hl_range); + } + } + pub(super) fn to_vec(&self) -> Vec { let mut res = Vec::new(); self.root.flatten(&mut res); diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings_disabled.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings_disabled.html new file mode 100644 index 000000000000..344d0c2ff03b --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings_disabled.html @@ -0,0 +1,47 @@ + + +
    fn main() {
    +    format_args!("foo\nbar");
    +    format_args!("foo\invalid");
    +}
    \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index 89a5e434f90c..8b529cf10f7f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -1498,6 +1498,23 @@ fn main() { ); } +#[test] +fn test_strings_highlighting_disabled() { + // Test that comments are not highlighted when disabled + check_highlighting_with_config( + r#" +//- minicore: fmt +fn main() { + format_args!("foo\nbar"); + format_args!("foo\invalid"); +} +"#, + HighlightConfig { strings: false, ..HL_CONFIG }, + expect_file!["./test_data/highlight_strings_disabled.html"], + false, + ); +} + #[test] fn regression_20952() { check_highlighting( From 45e0fbf7c5ffa5b8d36f9708e3a735908c6f28b4 Mon Sep 17 00:00:00 2001 From: tison Date: Fri, 9 Jan 2026 09:58:08 +0800 Subject: [PATCH 1826/3801] Implement partial_sort_unstable for slice Signed-off-by: tison Co-Authored-By: Orson Peters Signed-off-by: tison --- library/alloctests/tests/lib.rs | 2 + library/alloctests/tests/sort/mod.rs | 1 + library/alloctests/tests/sort/partial.rs | 84 ++++++++ library/core/src/slice/mod.rs | 213 ++++++++++++++++++++ library/core/src/slice/sort/unstable/mod.rs | 57 +++++- 5 files changed, 355 insertions(+), 2 deletions(-) create mode 100644 library/alloctests/tests/sort/partial.rs diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 34c65bf787c8..36eb0c3fa2c7 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -20,6 +20,8 @@ #![feature(binary_heap_into_iter_sorted)] #![feature(binary_heap_drain_sorted)] #![feature(slice_ptr_get)] +#![feature(slice_range)] +#![feature(slice_partial_sort_unstable)] #![feature(inplace_iteration)] #![feature(iter_advance_by)] #![feature(iter_next_chunk)] diff --git a/library/alloctests/tests/sort/mod.rs b/library/alloctests/tests/sort/mod.rs index 0e2494ca9d34..e2e141a02b59 100644 --- a/library/alloctests/tests/sort/mod.rs +++ b/library/alloctests/tests/sort/mod.rs @@ -12,6 +12,7 @@ pub trait Sort { mod ffi_types; mod known_good_stable_sort; +mod partial; mod patterns; mod tests; mod zipf; diff --git a/library/alloctests/tests/sort/partial.rs b/library/alloctests/tests/sort/partial.rs new file mode 100644 index 000000000000..c7248990c70c --- /dev/null +++ b/library/alloctests/tests/sort/partial.rs @@ -0,0 +1,84 @@ +use std::fmt::Debug; +use std::ops::{Range, RangeBounds}; +use std::slice; + +use super::patterns; + +fn check_is_partial_sorted>(v: &mut [T], range: R) { + let Range { start, end } = slice::range(range, ..v.len()); + v.partial_sort_unstable(start..end); + + let max_before = v[..start].iter().max().into_iter(); + let sorted_range = v[start..end].into_iter(); + let min_after = v[end..].iter().min().into_iter(); + let seq = max_before.chain(sorted_range).chain(min_after); + assert!(seq.is_sorted()); +} + +fn check_is_partial_sorted_ranges(v: &[T]) { + let len = v.len(); + + check_is_partial_sorted::(&mut v.to_vec(), ..); + check_is_partial_sorted::(&mut v.to_vec(), 0..0); + check_is_partial_sorted::(&mut v.to_vec(), len..len); + + if len > 0 { + check_is_partial_sorted::(&mut v.to_vec(), len - 1..len - 1); + check_is_partial_sorted::(&mut v.to_vec(), 0..1); + check_is_partial_sorted::(&mut v.to_vec(), len - 1..len); + + for mid in 1..len { + check_is_partial_sorted::(&mut v.to_vec(), 0..mid); + check_is_partial_sorted::(&mut v.to_vec(), mid..len); + check_is_partial_sorted::(&mut v.to_vec(), mid..mid); + check_is_partial_sorted::(&mut v.to_vec(), mid - 1..mid + 1); + check_is_partial_sorted::(&mut v.to_vec(), mid - 1..mid); + check_is_partial_sorted::(&mut v.to_vec(), mid..mid + 1); + } + + let quarters = [0, len / 4, len / 2, (3 * len) / 4, len]; + for &start in &quarters { + for &end in &quarters { + if start < end { + check_is_partial_sorted::(&mut v.to_vec(), start..end); + } + } + } + } +} + +#[test] +fn basic_impl() { + check_is_partial_sorted::(&mut [], ..); + check_is_partial_sorted::<(), _>(&mut [], ..); + check_is_partial_sorted::<(), _>(&mut [()], ..); + check_is_partial_sorted::<(), _>(&mut [(), ()], ..); + check_is_partial_sorted::<(), _>(&mut [(), (), ()], ..); + check_is_partial_sorted::(&mut [], ..); + + check_is_partial_sorted::(&mut [77], ..); + check_is_partial_sorted::(&mut [2, 3], ..); + check_is_partial_sorted::(&mut [2, 3, 6], ..); + check_is_partial_sorted::(&mut [2, 3, 99, 6], ..); + check_is_partial_sorted::(&mut [2, 7709, 400, 90932], ..); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], ..); + + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 0..0); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 0..1); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 0..5); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 0..7); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 7..7); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 6..7); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 5..7); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 5..5); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 4..5); + check_is_partial_sorted::(&mut [15, -1, 3, -1, -3, -1, 7], 4..6); +} + +#[test] +fn random_patterns() { + check_is_partial_sorted_ranges(&patterns::random(10)); + check_is_partial_sorted_ranges(&patterns::random(50)); + check_is_partial_sorted_ranges(&patterns::random(100)); + check_is_partial_sorted_ranges(&patterns::random(1000)); +} diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 889fd4cd65df..762921a85fc6 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3244,6 +3244,219 @@ impl [T] { sort::unstable::sort(self, &mut |a, b| f(a).lt(&f(b))); } + /// Partially sorts the slice in ascending order **without** preserving the initial order of equal elements. + /// + /// Upon completion, for the specified range `start..end`, it's guaranteed that: + /// + /// 1. Every element in `self[..start]` is smaller than or equal to + /// 2. Every element in `self[start..end]`, which is sorted, and smaller than or equal to + /// 3. Every element in `self[end..]`. + /// + /// This partial sort is unstable, meaning it may reorder equal elements in the specified range. + /// It may reorder elements outside the specified range as well, but the guarantees above still hold. + /// + /// This partial sort is in-place (i.e., does not allocate), and *O*(*n* + *k* \* log(*k*)) worst-case, + /// where *n* is the length of the slice and *k* is the length of the specified range. + /// + /// See the documentation of [`sort_unstable`] for implementation notes. + /// + /// # Panics + /// + /// May panic if the implementation of [`Ord`] for `T` does not implement a total order, or if + /// the [`Ord`] implementation panics, or if the specified range is out of bounds. + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_partial_sort_unstable)] + /// + /// let mut v = [4, -5, 1, -3, 2]; + /// + /// // empty range at the beginning, nothing changed + /// v.partial_sort_unstable(0..0); + /// assert_eq!(v, [4, -5, 1, -3, 2]); + /// + /// // empty range in the middle, partitioning the slice + /// v.partial_sort_unstable(2..2); + /// for i in 0..2 { + /// assert!(v[i] <= v[2]); + /// } + /// for i in 3..v.len() { + /// assert!(v[2] <= v[i]); + /// } + /// + /// // single element range, same as select_nth_unstable + /// v.partial_sort_unstable(2..3); + /// for i in 0..2 { + /// assert!(v[i] <= v[2]); + /// } + /// for i in 3..v.len() { + /// assert!(v[2] <= v[i]); + /// } + /// + /// // partial sort a subrange + /// v.partial_sort_unstable(1..4); + /// assert_eq!(&v[1..4], [-3, 1, 2]); + /// + /// // partial sort the whole range, same as sort_unstable + /// v.partial_sort_unstable(..); + /// assert_eq!(v, [-5, -3, 1, 2, 4]); + /// ``` + /// + /// [`sort_unstable`]: slice::sort_unstable + #[unstable(feature = "slice_partial_sort_unstable", issue = "149046")] + #[inline] + pub fn partial_sort_unstable(&mut self, range: R) + where + T: Ord, + R: RangeBounds, + { + sort::unstable::partial_sort(self, range, T::lt); + } + + /// Partially sorts the slice in ascending order with a comparison function, **without** + /// preserving the initial order of equal elements. + /// + /// Upon completion, for the specified range `start..end`, it's guaranteed that: + /// + /// 1. Every element in `self[..start]` is smaller than or equal to + /// 2. Every element in `self[start..end]`, which is sorted, and smaller than or equal to + /// 3. Every element in `self[end..]`. + /// + /// This partial sort is unstable, meaning it may reorder equal elements in the specified range. + /// It may reorder elements outside the specified range as well, but the guarantees above still hold. + /// + /// This partial sort is in-place (i.e., does not allocate), and *O*(*n* + *k* \* log(*k*)) worst-case, + /// where *n* is the length of the slice and *k* is the length of the specified range. + /// + /// See the documentation of [`sort_unstable_by`] for implementation notes. + /// + /// # Panics + /// + /// May panic if the `compare` does not implement a total order, or if + /// the `compare` itself panics, or if the specified range is out of bounds. + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_partial_sort_unstable)] + /// + /// let mut v = [4, -5, 1, -3, 2]; + /// + /// // empty range at the beginning, nothing changed + /// v.partial_sort_unstable_by(0..0, |a, b| b.cmp(a)); + /// assert_eq!(v, [4, -5, 1, -3, 2]); + /// + /// // empty range in the middle, partitioning the slice + /// v.partial_sort_unstable_by(2..2, |a, b| b.cmp(a)); + /// for i in 0..2 { + /// assert!(v[i] >= v[2]); + /// } + /// for i in 3..v.len() { + /// assert!(v[2] >= v[i]); + /// } + /// + /// // single element range, same as select_nth_unstable + /// v.partial_sort_unstable_by(2..3, |a, b| b.cmp(a)); + /// for i in 0..2 { + /// assert!(v[i] >= v[2]); + /// } + /// for i in 3..v.len() { + /// assert!(v[2] >= v[i]); + /// } + /// + /// // partial sort a subrange + /// v.partial_sort_unstable_by(1..4, |a, b| b.cmp(a)); + /// assert_eq!(&v[1..4], [2, 1, -3]); + /// + /// // partial sort the whole range, same as sort_unstable + /// v.partial_sort_unstable_by(.., |a, b| b.cmp(a)); + /// assert_eq!(v, [4, 2, 1, -3, -5]); + /// ``` + /// + /// [`sort_unstable_by`]: slice::sort_unstable_by + #[unstable(feature = "slice_partial_sort_unstable", issue = "149046")] + #[inline] + pub fn partial_sort_unstable_by(&mut self, range: R, mut compare: F) + where + F: FnMut(&T, &T) -> Ordering, + R: RangeBounds, + { + sort::unstable::partial_sort(self, range, |a, b| compare(a, b) == Less); + } + + /// Partially sorts the slice in ascending order with a key extraction function, **without** + /// preserving the initial order of equal elements. + /// + /// Upon completion, for the specified range `start..end`, it's guaranteed that: + /// + /// 1. Every element in `self[..start]` is smaller than or equal to + /// 2. Every element in `self[start..end]`, which is sorted, and smaller than or equal to + /// 3. Every element in `self[end..]`. + /// + /// This partial sort is unstable, meaning it may reorder equal elements in the specified range. + /// It may reorder elements outside the specified range as well, but the guarantees above still hold. + /// + /// This partial sort is in-place (i.e., does not allocate), and *O*(*n* + *k* \* log(*k*)) worst-case, + /// where *n* is the length of the slice and *k* is the length of the specified range. + /// + /// See the documentation of [`sort_unstable_by_key`] for implementation notes. + /// + /// # Panics + /// + /// May panic if the implementation of [`Ord`] for `K` does not implement a total order, or if + /// the [`Ord`] implementation panics, or if the specified range is out of bounds. + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_partial_sort_unstable)] + /// + /// let mut v = [4i32, -5, 1, -3, 2]; + /// + /// // empty range at the beginning, nothing changed + /// v.partial_sort_unstable_by_key(0..0, |k| k.abs()); + /// assert_eq!(v, [4, -5, 1, -3, 2]); + /// + /// // empty range in the middle, partitioning the slice + /// v.partial_sort_unstable_by_key(2..2, |k| k.abs()); + /// for i in 0..2 { + /// assert!(v[i].abs() <= v[2].abs()); + /// } + /// for i in 3..v.len() { + /// assert!(v[2].abs() <= v[i].abs()); + /// } + /// + /// // single element range, same as select_nth_unstable + /// v.partial_sort_unstable_by_key(2..3, |k| k.abs()); + /// for i in 0..2 { + /// assert!(v[i].abs() <= v[2].abs()); + /// } + /// for i in 3..v.len() { + /// assert!(v[2].abs() <= v[i].abs()); + /// } + /// + /// // partial sort a subrange + /// v.partial_sort_unstable_by_key(1..4, |k| k.abs()); + /// assert_eq!(&v[1..4], [2, -3, 4]); + /// + /// // partial sort the whole range, same as sort_unstable + /// v.partial_sort_unstable_by_key(.., |k| k.abs()); + /// assert_eq!(v, [1, 2, -3, 4, -5]); + /// ``` + /// + /// [`sort_unstable_by_key`]: slice::sort_unstable_by_key + #[unstable(feature = "slice_partial_sort_unstable", issue = "149046")] + #[inline] + pub fn partial_sort_unstable_by_key(&mut self, range: R, mut f: F) + where + F: FnMut(&T) -> K, + K: Ord, + R: RangeBounds, + { + sort::unstable::partial_sort(self, range, |a, b| f(a).lt(&f(b))); + } + /// Reorders the slice such that the element at `index` is at a sort-order position. All /// elements before `index` will be `<=` to this value, and all elements after will be `>=` to /// it. diff --git a/library/core/src/slice/sort/unstable/mod.rs b/library/core/src/slice/sort/unstable/mod.rs index d4df8d3a264d..7ca95a3b1b19 100644 --- a/library/core/src/slice/sort/unstable/mod.rs +++ b/library/core/src/slice/sort/unstable/mod.rs @@ -1,11 +1,13 @@ //! This module contains the entry points for `slice::sort_unstable`. use crate::mem::SizedTypeProperties; +use crate::ops::{Range, RangeBounds}; +use crate::slice::sort::select::partition_at_index; #[cfg(not(any(feature = "optimize_for_size", target_pointer_width = "16")))] use crate::slice::sort::shared::find_existing_run; #[cfg(not(any(feature = "optimize_for_size", target_pointer_width = "16")))] use crate::slice::sort::shared::smallsort::insertion_sort_shift_left; -use crate::{cfg_select, intrinsics}; +use crate::{cfg_select, intrinsics, slice}; pub(crate) mod heapsort; pub(crate) mod quicksort; @@ -17,7 +19,10 @@ pub(crate) mod quicksort; /// Upholds all safety properties outlined here: /// #[inline(always)] -pub fn sort bool>(v: &mut [T], is_less: &mut F) { +pub fn sort(v: &mut [T], is_less: &mut F) +where + F: FnMut(&T, &T) -> bool, +{ // Arrays of zero-sized types are always all-equal, and thus sorted. if T::IS_ZST { return; @@ -52,6 +57,54 @@ pub fn sort bool>(v: &mut [T], is_less: &mut F) { } } +/// Unstable partial sort the range `start..end`, after which it's guaranteed that: +/// +/// 1. Every element in `v[..start]` is smaller than or equal to +/// 2. Every element in `v[start..end]`, which is sorted, and smaller than or equal to +/// 3. Every element in `v[end..]`. +#[inline] +pub fn partial_sort(v: &mut [T], range: R, mut is_less: F) +where + F: FnMut(&T, &T) -> bool, + R: RangeBounds, +{ + // Arrays of zero-sized types are always all-equal, and thus sorted. + if T::IS_ZST { + return; + } + + let len = v.len(); + let Range { start, end } = slice::range(range, ..len); + + if end - start <= 1 { + // Empty range or single element. This case can be resolved in at most + // single partition_at_index call, without further sorting. + + if end == 0 || start == len { + // Do nothing if it is an empty range at start or end: all guarantees + // are already upheld. + return; + } + + partition_at_index(v, start, &mut is_less); + return; + } + + // A heuristic factor to decide whether to partition the slice or not. + // If the range bound is close to the edges of the slice, it's not worth + // partitioning first. + const PARTITION_THRESHOLD: usize = 8; + let mut v = v; + if end + PARTITION_THRESHOLD <= len { + v = partition_at_index(v, end - 1, &mut is_less).0; + } + if start >= PARTITION_THRESHOLD { + v = partition_at_index(v, start, &mut is_less).2; + } + + sort(v, &mut is_less); +} + /// See [`sort`] /// /// Deliberately don't inline the main sorting routine entrypoint to ensure the From 35ad1705ed646aa866f8cadee364cbec05ee66cd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 6 Jan 2026 12:09:02 +1100 Subject: [PATCH 1827/3801] Optimize canonicalizer flag checks. The most important change here relates to type folding: we now check the flags up front, instead of doing it in `inner_fold_ty` after checking the cache and doing a match. This is a small perf win, and matches other similar folders (e.g. `CanonicalInstantiator`). Likewise for const folding, we now check the flags first. (There is no cache for const folding.) Elsewhere we don't check flags before folding a predicate (unnecessary, because `fold_predicate` already checks the flags itself before doing anything else), and invert the flag checks in a couple of methods to match the standard order. --- .../src/canonical/canonicalizer.rs | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index 9162284422d0..22695da5a4d7 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -109,6 +109,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { let (max_universe, variables) = canonicalizer.finalize(); Canonical { max_universe, variables, value } } + fn canonicalize_param_env( delegate: &'a D, variables: &'a mut Vec, @@ -215,16 +216,12 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { }; let predicate = input.goal.predicate; - let predicate = if predicate.has_type_flags(NEEDS_CANONICAL) { - predicate.fold_with(&mut rest_canonicalizer) - } else { - predicate - }; + let predicate = predicate.fold_with(&mut rest_canonicalizer); let goal = Goal { param_env, predicate }; let predefined_opaques_in_body = input.predefined_opaques_in_body; let predefined_opaques_in_body = - if input.predefined_opaques_in_body.has_type_flags(NEEDS_CANONICAL) { + if predefined_opaques_in_body.has_type_flags(NEEDS_CANONICAL) { predefined_opaques_in_body.fold_with(&mut rest_canonicalizer) } else { predefined_opaques_in_body @@ -391,11 +388,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { | ty::Alias(_, _) | ty::Bound(_, _) | ty::Error(_) => { - return if t.has_type_flags(NEEDS_CANONICAL) { - ensure_sufficient_stack(|| t.super_fold_with(self)) - } else { - t - }; + return ensure_sufficient_stack(|| t.super_fold_with(self)); } }; @@ -477,7 +470,9 @@ impl, I: Interner> TypeFolder for Canonicaliz } fn fold_ty(&mut self, t: I::Ty) -> I::Ty { - if let Some(&ty) = self.cache.get(&t) { + if !t.flags().intersects(NEEDS_CANONICAL) { + t + } else if let Some(&ty) = self.cache.get(&t) { ty } else { let res = self.inner_fold_ty(t); @@ -488,6 +483,10 @@ impl, I: Interner> TypeFolder for Canonicaliz } fn fold_const(&mut self, c: I::Const) -> I::Const { + if !c.flags().intersects(NEEDS_CANONICAL) { + return c; + } + let kind = match c.kind() { ty::ConstKind::Infer(i) => match i { ty::InferConst::Var(vid) => { @@ -527,9 +526,7 @@ impl, I: Interner> TypeFolder for Canonicaliz | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) - | ty::ConstKind::Expr(_) => { - return if c.has_type_flags(NEEDS_CANONICAL) { c.super_fold_with(self) } else { c }; - } + | ty::ConstKind::Expr(_) => return c.super_fold_with(self), }; let var = self.get_or_insert_bound_var(c, kind); @@ -538,7 +535,7 @@ impl, I: Interner> TypeFolder for Canonicaliz } fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { - if p.flags().intersects(NEEDS_CANONICAL) { p.super_fold_with(self) } else { p } + if !p.flags().intersects(NEEDS_CANONICAL) { p } else { p.super_fold_with(self) } } fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses { @@ -549,6 +546,6 @@ impl, I: Interner> TypeFolder for Canonicaliz panic!("erasing 'static in env") } } - if c.flags().intersects(NEEDS_CANONICAL) { c.super_fold_with(self) } else { c } + if !c.flags().intersects(NEEDS_CANONICAL) { c } else { c.super_fold_with(self) } } } From 484ea769d3db73b912ef05367ade53fee874e023 Mon Sep 17 00:00:00 2001 From: paradoxicalguy Date: Wed, 31 Dec 2025 06:49:53 +0000 Subject: [PATCH 1828/3801] adding minicore to test file to avoid duplicating lang error --- tests/assembly-llvm/rust-abi-arg-attr.rs | 42 ++---------------------- tests/auxiliary/minicore.rs | 18 ++++++++++ 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/tests/assembly-llvm/rust-abi-arg-attr.rs b/tests/assembly-llvm/rust-abi-arg-attr.rs index 4f3673ccfc3b..2d13feb021ba 100644 --- a/tests/assembly-llvm/rust-abi-arg-attr.rs +++ b/tests/assembly-llvm/rust-abi-arg-attr.rs @@ -1,3 +1,4 @@ +//@ add-minicore //@ assembly-output: emit-asm //@ revisions: riscv64 riscv64-zbb loongarch64 //@ compile-flags: -C opt-level=3 @@ -14,45 +15,8 @@ #![no_std] #![no_core] // FIXME: Migrate these code after PR #130693 is landed. - -#[lang = "pointee_sized"] -pub trait PointeeSized {} - -#[lang = "meta_sized"] -pub trait MetaSized: PointeeSized {} - -#[lang = "sized"] -pub trait Sized: MetaSized {} - -#[lang = "copy"] -trait Copy {} - -impl Copy for i8 {} -impl Copy for u32 {} -impl Copy for i32 {} - -#[lang = "neg"] -trait Neg { - type Output; - - fn neg(self) -> Self::Output; -} - -impl Neg for i8 { - type Output = i8; - - fn neg(self) -> Self::Output { - -self - } -} - -#[lang = "Ordering"] -#[repr(i8)] -enum Ordering { - Less = -1, - Equal = 0, - Greater = 1, -} +extern crate minicore; +use minicore::*; #[rustc_intrinsic] fn three_way_compare(lhs: T, rhs: T) -> Ordering; diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 288a5b50dd5e..d349262b2559 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -210,6 +210,14 @@ impl Neg for isize { } } +impl Neg for i8 { + type Output = i8; + + fn neg(self) -> i8 { + loop {} + } +} + #[lang = "sync"] trait Sync {} impl_marker_trait!( @@ -280,6 +288,16 @@ pub enum c_void { __variant2, } +#[lang = "Ordering"] +#[repr(i8)] +pub enum Ordering { + Less = -1, + Equal = 0, + Greater = 1, +} + +impl Copy for Ordering {} + #[lang = "const_param_ty"] #[diagnostic::on_unimplemented(message = "`{Self}` can't be used as a const parameter type")] pub trait ConstParamTy_ {} From a97825c3f3afd60746a018628a70eea68b7890ff Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 6 Jan 2026 21:14:57 -0500 Subject: [PATCH 1829/3801] Update cargo submodule --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index b54051b15052..8c133afcd5e0 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit b54051b1505281ec7a45a250140a0ff25d33f319 +Subproject commit 8c133afcd5e0d69932fe11f5907683723f8d361d From 48ccb1f187d56a4d8626421575a47898112412b9 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 9 Jan 2026 12:57:39 +0800 Subject: [PATCH 1830/3801] Retire outdated stage0 std remarks Co-authored-by: Deadbeef --- .../src/building/new-target.md | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md index 436aec8ee265..8465a1388870 100644 --- a/src/doc/rustc-dev-guide/src/building/new-target.md +++ b/src/doc/rustc-dev-guide/src/building/new-target.md @@ -80,32 +80,12 @@ will then add a corresponding file for your new target containing a Look for existing targets to use as examples. -After adding your target to the `rustc_target` crate you may want to add -`core`, `std`, ... with support for your new target. In that case you will -probably need access to some `target_*` cfg. Unfortunately when building with -stage0 (a precompiled compiler), you'll get an error that the target cfg is -unexpected because stage0 doesn't know about the new target specification and -we pass `--check-cfg` in order to tell it to check. - -To fix the errors you will need to manually add the unexpected value to the -different `Cargo.toml` in `library/{std,alloc,core}/Cargo.toml`. Here is an -example for adding `NEW_TARGET_ARCH` as `target_arch`: - -*`library/std/Cargo.toml`*: -```diff - [lints.rust.unexpected_cfgs] - level = "warn" - check-cfg = [ - 'cfg(bootstrap)', -- 'cfg(target_arch, values("xtensa"))', -+ # #[cfg(bootstrap)] NEW_TARGET_ARCH -+ 'cfg(target_arch, values("xtensa", "NEW_TARGET_ARCH"))', -``` - -To use this target in bootstrap, we need to explicitly add the target triple to the `STAGE0_MISSING_TARGETS` -list in `src/bootstrap/src/core/sanity.rs`. This is necessary because the default compiler bootstrap uses does -not recognize the new target we just added. Therefore, it should be added to `STAGE0_MISSING_TARGETS` so that the -bootstrap is aware that this target is not yet supported by the stage0 compiler. +To use this target in bootstrap, we need to explicitly add the target triple to +the `STAGE0_MISSING_TARGETS` list in `src/bootstrap/src/core/sanity.rs`. This +is necessary because the default bootstrap compiler (typically a beta compiler) +does not recognize the new target we just added. Therefore, it should be added to +`STAGE0_MISSING_TARGETS` so that the bootstrap is aware that this target is not +yet supported by the stage0 compiler. ```diff const STAGE0_MISSING_TARGETS: &[&str] = &[ From 97fc739602cb8e0800734a86bb40331e1bb73f20 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Fri, 9 Jan 2026 10:31:18 +0530 Subject: [PATCH 1831/3801] std: sys: fs: uefi: Implement File::tell - Just a call to get_position - Tested with OVMF on QEMU Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index b1e5f33b1b22..3b10986f17f9 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -364,7 +364,7 @@ impl File { } pub fn tell(&self) -> io::Result { - unsupported() + self.0.position() } pub fn duplicate(&self) -> io::Result { @@ -734,6 +734,14 @@ mod uefi_fs { if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } + pub(crate) fn position(&self) -> io::Result { + let file_ptr = self.protocol.as_ptr(); + let mut pos = 0; + + let r = unsafe { ((*file_ptr).get_position)(file_ptr, &mut pos) }; + if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(pos) } + } + pub(crate) fn delete(self) -> io::Result<()> { let file_ptr = self.protocol.as_ptr(); let r = unsafe { ((*file_ptr).delete)(file_ptr) }; From 0495a7347454772a93be512cd5de7118d407a0f8 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 7 Jan 2026 13:04:10 +1100 Subject: [PATCH 1832/3801] Prepare for `thir::Pat` nodes having multiple user-type ascriptions --- .../src/builder/matches/mod.rs | 41 ++++++++++--------- .../src/builder/matches/user_ty.rs | 29 ++++++++----- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 9080e2ba801b..aaca6936dcd2 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -879,6 +879,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &ProjectedUserTypesNode<'_>, ), ) { + // Ascriptions correspond to user-written types like `let A::<'a>(_): A<'static> = ...;`. + // + // Caution: Pushing user types here is load-bearing even for + // patterns containing no bindings, to ensure that the type ends + // up represented in MIR _somewhere_. + let user_tys = match pattern.kind { + PatKind::AscribeUserType { ref ascription, .. } => { + let base_user_tys = std::iter::once(ascription) + .map(|thir::Ascription { annotation, variance: _ }| { + // Note that the variance doesn't apply here, as we are tracking the effect + // of user types on any bindings contained with subpattern. + self.canonical_user_type_annotations.push(annotation.clone()) + }) + .collect(); + &user_tys.push_user_types(base_user_tys) + } + _ => user_tys, + }; + // Avoid having to write the full method name at each recursive call. let visit_subpat = |this: &mut Self, subpat, user_tys: &_, f: &mut _| { this.visit_primary_bindings_special(subpat, user_tys, f) @@ -924,25 +943,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { visit_subpat(self, subpattern, &ProjectedUserTypesNode::None, f); } - PatKind::AscribeUserType { - ref subpattern, - ascription: thir::Ascription { ref annotation, variance: _ }, - } => { - // This corresponds to something like - // - // ``` - // let A::<'a>(_): A<'static> = ...; - // ``` - // - // Note that the variance doesn't apply here, as we are tracking the effect - // of `user_ty` on any bindings contained with subpattern. - - // Caution: Pushing this user type here is load-bearing even for - // patterns containing no bindings, to ensure that the type ends - // up represented in MIR _somewhere_. - let base_user_ty = self.canonical_user_type_annotations.push(annotation.clone()); - let subpattern_user_tys = user_tys.push_user_type(base_user_ty); - visit_subpat(self, subpattern, &subpattern_user_tys, f) + PatKind::AscribeUserType { ref subpattern, ascription: _ } => { + // The ascription was already handled above, so just recurse to the subpattern. + visit_subpat(self, subpattern, user_tys, f) } PatKind::ExpandedConstant { ref subpattern, .. } => { diff --git a/compiler/rustc_mir_build/src/builder/matches/user_ty.rs b/compiler/rustc_mir_build/src/builder/matches/user_ty.rs index df9f93ac328a..2dcfd3772902 100644 --- a/compiler/rustc_mir_build/src/builder/matches/user_ty.rs +++ b/compiler/rustc_mir_build/src/builder/matches/user_ty.rs @@ -8,15 +8,20 @@ use std::assert_matches::assert_matches; use std::iter; use rustc_abi::{FieldIdx, VariantIdx}; +use rustc_data_structures::smallvec::SmallVec; use rustc_middle::mir::{ProjectionElem, UserTypeProjection, UserTypeProjections}; use rustc_middle::ty::{AdtDef, UserTypeAnnotationIndex}; use rustc_span::Symbol; +/// A single `thir::Pat` node should almost never have more than 0-2 user types. +/// We can store up to 4 inline in the same size as an ordinary `Vec`. +pub(crate) type UserTypeIndices = SmallVec<[UserTypeAnnotationIndex; 4]>; + /// One of a list of "operations" that can be used to lazily build projections /// of user-specified types. -#[derive(Clone, Debug)] +#[derive(Debug)] pub(crate) enum ProjectedUserTypesOp { - PushUserType { base: UserTypeAnnotationIndex }, + PushUserTypes { base_types: UserTypeIndices }, Index, Subslice { from: u64, to: u64 }, @@ -32,9 +37,10 @@ pub(crate) enum ProjectedUserTypesNode<'a> { } impl<'a> ProjectedUserTypesNode<'a> { - pub(crate) fn push_user_type(&'a self, base: UserTypeAnnotationIndex) -> Self { - // Pushing a base user type always causes the chain to become non-empty. - Self::Chain { parent: self, op: ProjectedUserTypesOp::PushUserType { base } } + pub(crate) fn push_user_types(&'a self, base_types: UserTypeIndices) -> Self { + assert!(!base_types.is_empty()); + // Pushing one or more base user types always causes the chain to become non-empty. + Self::Chain { parent: self, op: ProjectedUserTypesOp::PushUserTypes { base_types } } } /// Push another projection op onto the chain, but only if it is already non-empty. @@ -94,16 +100,19 @@ impl<'a> ProjectedUserTypesNode<'a> { return None; } - let ops_reversed = self.iter_ops_reversed().cloned().collect::>(); + let ops_reversed = self.iter_ops_reversed().collect::>(); // The "first" op should always be `PushUserType`. // Other projections are only added if there is at least one user type. - assert_matches!(ops_reversed.last(), Some(ProjectedUserTypesOp::PushUserType { .. })); + assert_matches!(ops_reversed.last(), Some(ProjectedUserTypesOp::PushUserTypes { .. })); let mut projections = vec![]; for op in ops_reversed.into_iter().rev() { - match op { - ProjectedUserTypesOp::PushUserType { base } => { - projections.push(UserTypeProjection { base, projs: vec![] }) + match *op { + ProjectedUserTypesOp::PushUserTypes { ref base_types } => { + assert!(!base_types.is_empty()); + for &base in base_types { + projections.push(UserTypeProjection { base, projs: vec![] }) + } } ProjectedUserTypesOp::Index => { From f85b898c45bccef0142485d0d092ab66688b4641 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 6 Jan 2026 14:34:55 +1100 Subject: [PATCH 1833/3801] Prefer to return `Box` instead of `thir::PatKind` This will allow extra data to be attached to the `Pat` before it is returned. --- .../src/thir/pattern/const_to_pat.rs | 14 ++- .../rustc_mir_build/src/thir/pattern/mod.rs | 96 ++++++++++++------- 2 files changed, 69 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 2da9a43f71d8..76b742aa6e45 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -174,10 +174,10 @@ impl<'tcx> ConstToPat<'tcx> { } }; - // Convert the valtree to a const. - let inlined_const_as_pat = self.valtree_to_pat(valtree, ty); + // Lower the valtree to a THIR pattern. + let mut thir_pat = self.valtree_to_pat(valtree, ty); - if !inlined_const_as_pat.references_error() { + if !thir_pat.references_error() { // Always check for `PartialEq` if we had no other errors yet. if !type_has_partial_eq_impl(self.tcx, typing_env, ty).has_impl { let mut err = self.tcx.dcx().create_err(TypeNotPartialEq { span: self.span, ty }); @@ -188,8 +188,12 @@ impl<'tcx> ConstToPat<'tcx> { // Wrap the pattern in a marker node to indicate that it is the result of lowering a // constant. This is used for diagnostics. - let kind = PatKind::ExpandedConstant { subpattern: inlined_const_as_pat, def_id: uv.def }; - Box::new(Pat { kind, ty, span: self.span }) + thir_pat = Box::new(Pat { + ty: thir_pat.ty, + span: thir_pat.span, + kind: PatKind::ExpandedConstant { def_id: uv.def, subpattern: thir_pat }, + }); + thir_pat } fn field_pats( diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 4128508955cb..01986d946d45 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -167,9 +167,10 @@ impl<'tcx> PatCtxt<'tcx> { // Return None in that case; the caller will use NegInfinity or PosInfinity instead. let Some(expr) = expr else { return Ok(None) }; - // Lower the endpoint into a temporary `PatKind` that will then be + // Lower the endpoint into a temporary `thir::Pat` that will then be // deconstructed to obtain the constant value and other data. - let mut kind: PatKind<'tcx> = self.lower_pat_expr(pat, expr); + let endpoint_pat: Box> = self.lower_pat_expr(pat, expr); + let box Pat { mut kind, .. } = endpoint_pat; // Unpeel any ascription or inline-const wrapper nodes. loop { @@ -250,7 +251,7 @@ impl<'tcx> PatCtxt<'tcx> { lo_expr: Option<&'tcx hir::PatExpr<'tcx>>, hi_expr: Option<&'tcx hir::PatExpr<'tcx>>, end: RangeEnd, - ) -> Result, ErrorGuaranteed> { + ) -> Result>, ErrorGuaranteed> { let ty = self.typeck_results.node_type(pat.hir_id); let span = pat.span; @@ -306,27 +307,34 @@ impl<'tcx> PatCtxt<'tcx> { return Err(e); } } + let mut thir_pat = Box::new(Pat { ty, span, kind }); // If we are handling a range with associated constants (e.g. // `Foo::<'a>::A..=Foo::B`), we need to put the ascriptions for the associated // constants somewhere. Have them on the range pattern. for ascription in ascriptions { - let subpattern = Box::new(Pat { span, ty, kind }); - kind = PatKind::AscribeUserType { ascription, subpattern }; + thir_pat = Box::new(Pat { + ty, + span, + kind: PatKind::AscribeUserType { ascription, subpattern: thir_pat }, + }); } // `PatKind::ExpandedConstant` wrappers from range endpoints used to // also be preserved here, but that was only needed for unsafeck of // inline `const { .. }` patterns, which were removed by // . - Ok(kind) + Ok(thir_pat) } #[instrument(skip(self), level = "debug")] fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box> { - let mut ty = self.typeck_results.node_type(pat.hir_id); - let mut span = pat.span; + let ty = self.typeck_results.node_type(pat.hir_id); + let span = pat.span; + // Some of these match arms return a `Box` early, while others + // evaluate to a `PatKind` that will become a `Box` at the end of + // this function. let kind = match pat.kind { hir::PatKind::Missing => PatKind::Missing, @@ -334,10 +342,13 @@ impl<'tcx> PatCtxt<'tcx> { hir::PatKind::Never => PatKind::Never, - hir::PatKind::Expr(value) => self.lower_pat_expr(pat, value), + hir::PatKind::Expr(value) => return self.lower_pat_expr(pat, value), hir::PatKind::Range(lo_expr, hi_expr, end) => { - self.lower_pattern_range(pat, lo_expr, hi_expr, end).unwrap_or_else(PatKind::Error) + match self.lower_pattern_range(pat, lo_expr, hi_expr, end) { + Ok(thir_pat) => return thir_pat, + Err(e) => PatKind::Error(e), + } } hir::PatKind::Deref(subpattern) => { @@ -360,7 +371,7 @@ impl<'tcx> PatCtxt<'tcx> { }, hir::PatKind::Slice(prefix, slice, suffix) => { - self.slice_or_array_pattern(pat, prefix, slice, suffix) + return self.slice_or_array_pattern(pat, prefix, slice, suffix); } hir::PatKind::Tuple(pats, ddpos) => { @@ -372,8 +383,9 @@ impl<'tcx> PatCtxt<'tcx> { } hir::PatKind::Binding(explicit_ba, id, ident, sub) => { + let mut thir_pat_span = span; if let Some(ident_span) = ident.span.find_ancestor_inside(span) { - span = span.with_hi(ident_span.hi()); + thir_pat_span = span.with_hi(ident_span.hi()); } let mode = *self @@ -389,22 +401,23 @@ impl<'tcx> PatCtxt<'tcx> { // A ref x pattern is the same node used for x, and as such it has // x's type, which is &T, where we want T (the type being matched). let var_ty = ty; + let mut thir_pat_ty = ty; if let hir::ByRef::Yes(pinnedness, _) = mode.0 { match pinnedness { hir::Pinnedness::Pinned if let Some(pty) = ty.pinned_ty() && let &ty::Ref(_, rty, _) = pty.kind() => { - ty = rty; + thir_pat_ty = rty; } hir::Pinnedness::Not if let &ty::Ref(_, rty, _) = ty.kind() => { - ty = rty; + thir_pat_ty = rty; } _ => bug!("`ref {}` has wrong type {}", ident, ty), } }; - PatKind::Binding { + let kind = PatKind::Binding { mode, name: ident.name, var: LocalVarId(id), @@ -412,7 +425,10 @@ impl<'tcx> PatCtxt<'tcx> { subpattern: self.lower_opt_pattern(sub), is_primary: id == pat.hir_id, is_shorthand: false, - } + }; + // We might have modified the type or span, so use the modified + // values in the THIR pattern node. + return Box::new(Pat { ty: thir_pat_ty, span: thir_pat_span, kind }); } hir::PatKind::TupleStruct(ref qpath, pats, ddpos) => { @@ -422,7 +438,7 @@ impl<'tcx> PatCtxt<'tcx> { }; let variant_def = adt_def.variant_of_res(res); let subpatterns = self.lower_tuple_subpats(pats, variant_def.fields.len(), ddpos); - self.lower_variant_or_leaf(pat, None, res, subpatterns) + return self.lower_variant_or_leaf(pat, None, res, subpatterns); } hir::PatKind::Struct(ref qpath, fields, _) => { @@ -439,7 +455,7 @@ impl<'tcx> PatCtxt<'tcx> { }) .collect(); - self.lower_variant_or_leaf(pat, None, res, subpatterns) + return self.lower_variant_or_leaf(pat, None, res, subpatterns); } hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) }, @@ -450,6 +466,8 @@ impl<'tcx> PatCtxt<'tcx> { hir::PatKind::Err(guar) => PatKind::Error(guar), }; + // For pattern kinds that haven't already returned, create a `thir::Pat` + // with the HIR pattern node's type and span. Box::new(Pat { span, ty, kind }) } @@ -482,13 +500,14 @@ impl<'tcx> PatCtxt<'tcx> { prefix: &'tcx [hir::Pat<'tcx>], slice: Option<&'tcx hir::Pat<'tcx>>, suffix: &'tcx [hir::Pat<'tcx>], - ) -> PatKind<'tcx> { + ) -> Box> { let ty = self.typeck_results.node_type(pat.hir_id); + let span = pat.span; let prefix = self.lower_patterns(prefix); let slice = self.lower_opt_pattern(slice); let suffix = self.lower_patterns(suffix); - match ty.kind() { + let kind = match ty.kind() { // Matching a slice, `[T]`. ty::Slice(..) => PatKind::Slice { prefix, slice, suffix }, // Fixed-length array, `[T; len]`. @@ -499,8 +518,9 @@ impl<'tcx> PatCtxt<'tcx> { assert!(len >= prefix.len() as u64 + suffix.len() as u64); PatKind::Array { prefix, slice, suffix } } - _ => span_bug!(pat.span, "bad slice pattern type {ty:?}"), - } + _ => span_bug!(span, "bad slice pattern type {ty:?}"), + }; + Box::new(Pat { ty, span, kind }) } fn lower_variant_or_leaf( @@ -509,7 +529,7 @@ impl<'tcx> PatCtxt<'tcx> { expr: Option<&'tcx hir::PatExpr<'tcx>>, res: Res, subpatterns: Vec>, - ) -> PatKind<'tcx> { + ) -> Box> { // Check whether the caller should have provided an `expr` for this pattern kind. assert_matches!( (pat.kind, expr), @@ -533,7 +553,7 @@ impl<'tcx> PatCtxt<'tcx> { res => res, }; - let mut kind = match res { + let kind = match res { Res::Def(DefKind::Variant, variant_id) => { let enum_id = self.tcx.parent(variant_id); let adt_def = self.tcx.adt_def(enum_id); @@ -542,7 +562,7 @@ impl<'tcx> PatCtxt<'tcx> { ty::Adt(_, args) | ty::FnDef(_, args) => args, ty::Error(e) => { // Avoid ICE (#50585) - return PatKind::Error(*e); + return Box::new(Pat { ty, span, kind: PatKind::Error(*e) }); } _ => bug!("inappropriate type for def: {:?}", ty), }; @@ -583,21 +603,26 @@ impl<'tcx> PatCtxt<'tcx> { PatKind::Error(e) } }; + let mut thir_pat = Box::new(Pat { ty, span, kind }); if let Some(user_ty) = self.user_args_applied_to_ty_of_hir_id(hir_id) { - debug!("lower_variant_or_leaf: kind={:?} user_ty={:?} span={:?}", kind, user_ty, span); + debug!(?thir_pat, ?user_ty, ?span, "lower_variant_or_leaf: applying ascription"); let annotation = CanonicalUserTypeAnnotation { user_ty: Box::new(user_ty), span, inferred_ty: self.typeck_results.node_type(hir_id), }; - kind = PatKind::AscribeUserType { - subpattern: Box::new(Pat { span, ty, kind }), - ascription: Ascription { annotation, variance: ty::Covariant }, - }; + thir_pat = Box::new(Pat { + ty, + span, + kind: PatKind::AscribeUserType { + subpattern: thir_pat, + ascription: Ascription { annotation, variance: ty::Covariant }, + }, + }); } - kind + thir_pat } fn user_args_applied_to_ty_of_hir_id( @@ -632,8 +657,7 @@ impl<'tcx> PatCtxt<'tcx> { _ => { // The path isn't the name of a constant, so it must actually // be a unit struct or unit variant (e.g. `Option::None`). - let kind = self.lower_variant_or_leaf(pat, Some(expr), res, vec![]); - return Box::new(Pat { span, ty, kind }); + return self.lower_variant_or_leaf(pat, Some(expr), res, vec![]); } }; @@ -674,10 +698,10 @@ impl<'tcx> PatCtxt<'tcx> { &mut self, pat: &'tcx hir::Pat<'tcx>, // Pattern that directly contains `expr` expr: &'tcx hir::PatExpr<'tcx>, - ) -> PatKind<'tcx> { + ) -> Box> { assert_matches!(pat.kind, hir::PatKind::Expr(..) | hir::PatKind::Range(..)); match &expr.kind { - hir::PatExprKind::Path(qpath) => self.lower_path(pat, expr, qpath).kind, + hir::PatExprKind::Path(qpath) => self.lower_path(pat, expr, qpath), hir::PatExprKind::Lit { lit, negated } => { // We handle byte string literal patterns by using the pattern's type instead of the // literal's type in `const_to_pat`: if the literal `b"..."` matches on a slice reference, @@ -691,7 +715,7 @@ impl<'tcx> PatCtxt<'tcx> { let pat_ty = self.typeck_results.node_type(pat.hir_id); let lit_input = LitToConstInput { lit: lit.node, ty: pat_ty, neg: *negated }; let constant = self.tcx.at(expr.span).lit_to_const(lit_input); - self.const_to_pat(constant, pat_ty, expr.hir_id, lit.span).kind + self.const_to_pat(constant, pat_ty, expr.hir_id, lit.span) } } } From bd7704830331f0feb1fd8b43e18fd535663acadb Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 6 Jan 2026 18:20:31 +1100 Subject: [PATCH 1834/3801] Initial plumbing for `thir::PatExtra` --- compiler/rustc_middle/src/thir.rs | 18 +++++++- compiler/rustc_middle/src/thir/visit.rs | 2 +- .../src/thir/pattern/const_to_pat.rs | 5 ++- .../rustc_mir_build/src/thir/pattern/mod.rs | 24 +++++++---- compiler/rustc_mir_build/src/thir/print.rs | 42 ++++++++++++++++++- 5 files changed, 78 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 3683c1cfb7dd..3ddb5a1523d0 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -643,10 +643,26 @@ pub struct FieldPat<'tcx> { pub pattern: Pat<'tcx>, } +/// Additional per-node data that is not present on most THIR pattern nodes. +#[derive(Clone, Debug, Default, HashStable, TypeVisitable)] +pub struct PatExtra<'tcx> { + /// If present, this node represents a named constant that was lowered to + /// a pattern using `const_to_pat`. + /// + /// This is used by some diagnostics for non-exhaustive matches, to map + /// the pattern node back to the `DefId` of its original constant. + pub expanded_const: Option, + + /// User-written types that must be preserved into MIR so that they can be + /// checked. + pub ascriptions: Vec>, +} + #[derive(Clone, Debug, HashStable, TypeVisitable)] pub struct Pat<'tcx> { pub ty: Ty<'tcx>, pub span: Span, + pub extra: Option>>, pub kind: PatKind<'tcx>, } @@ -1119,7 +1135,7 @@ mod size_asserts { static_assert_size!(Block, 48); static_assert_size!(Expr<'_>, 64); static_assert_size!(ExprKind<'_>, 40); - static_assert_size!(Pat<'_>, 64); + static_assert_size!(Pat<'_>, 72); static_assert_size!(PatKind<'_>, 48); static_assert_size!(Stmt<'_>, 48); static_assert_size!(StmtKind<'_>, 48); diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index d792bbe60c88..e0c044220b81 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -259,7 +259,7 @@ pub(crate) fn for_each_immediate_subpat<'a, 'tcx>( pat: &'a Pat<'tcx>, mut callback: impl FnMut(&'a Pat<'tcx>), ) { - let Pat { kind, ty: _, span: _ } = pat; + let Pat { kind, ty: _, span: _, extra: _ } = pat; match kind { PatKind::Missing | PatKind::Wild diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 76b742aa6e45..98faf0ab613f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -90,7 +90,7 @@ impl<'tcx> ConstToPat<'tcx> { ); } } - Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()) }) + Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()), extra: None }) } fn unevaluated_to_pat( @@ -192,6 +192,7 @@ impl<'tcx> ConstToPat<'tcx> { ty: thir_pat.ty, span: thir_pat.span, kind: PatKind::ExpandedConstant { def_id: uv.def, subpattern: thir_pat }, + extra: None, }); thir_pat } @@ -355,7 +356,7 @@ impl<'tcx> ConstToPat<'tcx> { } }; - Box::new(Pat { span, ty, kind }) + Box::new(Pat { span, ty, kind, extra: None }) } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 01986d946d45..9c39a934c7ee 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -78,6 +78,7 @@ pub(super) fn pat_from_hir<'tcx>( ascription: Ascription { annotation, variance: ty::Covariant }, subpattern: thir_pat, }, + extra: None, }); } @@ -142,7 +143,7 @@ impl<'tcx> PatCtxt<'tcx> { } PatAdjust::PinDeref => PatKind::Deref { subpattern: thir_pat }, }; - Box::new(Pat { span, ty: adjust.source, kind }) + Box::new(Pat { span, ty: adjust.source, kind, extra: None }) }); if let Some(s) = &mut self.rust_2024_migration @@ -307,7 +308,7 @@ impl<'tcx> PatCtxt<'tcx> { return Err(e); } } - let mut thir_pat = Box::new(Pat { ty, span, kind }); + let mut thir_pat = Box::new(Pat { ty, span, kind, extra: None }); // If we are handling a range with associated constants (e.g. // `Foo::<'a>::A..=Foo::B`), we need to put the ascriptions for the associated @@ -317,6 +318,7 @@ impl<'tcx> PatCtxt<'tcx> { ty, span, kind: PatKind::AscribeUserType { ascription, subpattern: thir_pat }, + extra: None, }); } // `PatKind::ExpandedConstant` wrappers from range endpoints used to @@ -428,7 +430,7 @@ impl<'tcx> PatCtxt<'tcx> { }; // We might have modified the type or span, so use the modified // values in the THIR pattern node. - return Box::new(Pat { ty: thir_pat_ty, span: thir_pat_span, kind }); + return Box::new(Pat { ty: thir_pat_ty, span: thir_pat_span, kind, extra: None }); } hir::PatKind::TupleStruct(ref qpath, pats, ddpos) => { @@ -468,7 +470,7 @@ impl<'tcx> PatCtxt<'tcx> { // For pattern kinds that haven't already returned, create a `thir::Pat` // with the HIR pattern node's type and span. - Box::new(Pat { span, ty, kind }) + Box::new(Pat { span, ty, kind, extra: None }) } fn lower_tuple_subpats( @@ -520,7 +522,7 @@ impl<'tcx> PatCtxt<'tcx> { } _ => span_bug!(span, "bad slice pattern type {ty:?}"), }; - Box::new(Pat { ty, span, kind }) + Box::new(Pat { ty, span, kind, extra: None }) } fn lower_variant_or_leaf( @@ -562,7 +564,12 @@ impl<'tcx> PatCtxt<'tcx> { ty::Adt(_, args) | ty::FnDef(_, args) => args, ty::Error(e) => { // Avoid ICE (#50585) - return Box::new(Pat { ty, span, kind: PatKind::Error(*e) }); + return Box::new(Pat { + ty, + span, + kind: PatKind::Error(*e), + extra: None, + }); } _ => bug!("inappropriate type for def: {:?}", ty), }; @@ -603,7 +610,7 @@ impl<'tcx> PatCtxt<'tcx> { PatKind::Error(e) } }; - let mut thir_pat = Box::new(Pat { ty, span, kind }); + let mut thir_pat = Box::new(Pat { ty, span, kind, extra: None }); if let Some(user_ty) = self.user_args_applied_to_ty_of_hir_id(hir_id) { debug!(?thir_pat, ?user_ty, ?span, "lower_variant_or_leaf: applying ascription"); @@ -619,6 +626,7 @@ impl<'tcx> PatCtxt<'tcx> { subpattern: thir_pat, ascription: Ascription { annotation, variance: ty::Covariant }, }, + extra: None, }); } @@ -685,7 +693,7 @@ impl<'tcx> PatCtxt<'tcx> { variance: ty::Contravariant, }, }; - pattern = Box::new(Pat { span, kind, ty }); + pattern = Box::new(Pat { span, kind, ty, extra: None }); } pattern diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 5a2d6cfef1cc..d735ef2134ab 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -73,6 +73,24 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { self.fmt } + fn print_list( + &mut self, + label: &str, + list: &[T], + depth_lvl: usize, + print_fn: impl Fn(&mut Self, &T, usize), + ) { + if list.is_empty() { + print_indented!(self, format_args!("{label}: []"), depth_lvl); + } else { + print_indented!(self, format_args!("{label}: ["), depth_lvl); + for item in list { + print_fn(self, item, depth_lvl + 1) + } + print_indented!(self, "]", depth_lvl); + } + } + fn print_param(&mut self, param: &Param<'tcx>, depth_lvl: usize) { let Param { pat, ty, ty_span, self_kind, hir_id } = param; @@ -663,15 +681,37 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { } fn print_pat(&mut self, pat: &Pat<'tcx>, depth_lvl: usize) { - let &Pat { ty, span, ref kind } = pat; + let &Pat { ty, span, ref kind, ref extra } = pat; print_indented!(self, "Pat: {", depth_lvl); print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1); print_indented!(self, format!("span: {:?}", span), depth_lvl + 1); + self.print_pat_extra(extra.as_deref(), depth_lvl + 1); self.print_pat_kind(kind, depth_lvl + 1); print_indented!(self, "}", depth_lvl); } + fn print_pat_extra(&mut self, extra: Option<&PatExtra<'tcx>>, depth_lvl: usize) { + let Some(extra) = extra else { + // Skip printing in the common case of a pattern node with no extra data. + return; + }; + + let PatExtra { expanded_const, ascriptions } = extra; + + print_indented!(self, "extra: PatExtra {", depth_lvl); + print_indented!(self, format_args!("expanded_const: {expanded_const:?}"), depth_lvl + 1); + self.print_list( + "ascriptions", + ascriptions, + depth_lvl + 1, + |this, ascription, depth_lvl| { + print_indented!(this, format_args!("{ascription:?}"), depth_lvl); + }, + ); + print_indented!(self, "}", depth_lvl); + } + fn print_pat_kind(&mut self, pat_kind: &PatKind<'tcx>, depth_lvl: usize) { print_indented!(self, "kind: PatKind {", depth_lvl); From 8516c64115ce3689e66a2ab95de77f978f7398b6 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 6 Jan 2026 18:30:20 +1100 Subject: [PATCH 1835/3801] Replace `AscribeUserType` and `ExpandedConstant` with per-node data --- compiler/rustc_middle/src/thir.rs | 20 ----- compiler/rustc_middle/src/thir/visit.rs | 6 +- .../src/builder/custom/parse.rs | 24 ++---- .../src/builder/custom/parse/instruction.rs | 5 -- .../src/builder/matches/match_pair.rs | 41 ++++------ .../src/builder/matches/mod.rs | 67 ++++------------ .../rustc_mir_build/src/check_unsafety.rs | 2 - .../src/thir/pattern/check_match.rs | 13 +--- .../src/thir/pattern/const_to_pat.rs | 9 +-- .../rustc_mir_build/src/thir/pattern/mod.rs | 76 ++++++------------- compiler/rustc_mir_build/src/thir/print.rs | 14 ---- compiler/rustc_pattern_analysis/src/rustc.rs | 2 - 12 files changed, 68 insertions(+), 211 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 3ddb5a1523d0..e538c2182924 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -778,11 +778,6 @@ pub enum PatKind<'tcx> { /// A wildcard pattern: `_`. Wild, - AscribeUserType { - ascription: Ascription<'tcx>, - subpattern: Box>, - }, - /// `x`, `ref x`, `x @ P`, etc. Binding { name: Symbol, @@ -847,21 +842,6 @@ pub enum PatKind<'tcx> { value: ty::Value<'tcx>, }, - /// Wrapper node representing a named constant that was lowered to a pattern - /// using `const_to_pat`. - /// - /// This is used by some diagnostics for non-exhaustive matches, to map - /// the pattern node back to the `DefId` of its original constant. - /// - /// FIXME(#150498): Can we make this an `Option` field on `Pat` - /// instead, so that non-diagnostic code can ignore it more easily? - ExpandedConstant { - /// [DefId] of the constant item. - def_id: DefId, - /// The pattern that the constant lowered to. - subpattern: Box>, - }, - Range(Arc>), /// Matches against a slice, checking the length and extracting elements. diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index e0c044220b81..b611b23e5261 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -269,11 +269,9 @@ pub(crate) fn for_each_immediate_subpat<'a, 'tcx>( | PatKind::Never | PatKind::Error(_) => {} - PatKind::AscribeUserType { subpattern, .. } - | PatKind::Binding { subpattern: Some(subpattern), .. } + PatKind::Binding { subpattern: Some(subpattern), .. } | PatKind::Deref { subpattern } - | PatKind::DerefPattern { subpattern, .. } - | PatKind::ExpandedConstant { subpattern, .. } => callback(subpattern), + | PatKind::DerefPattern { subpattern, .. } => callback(subpattern), PatKind::Variant { subpatterns, .. } | PatKind::Leaf { subpatterns } => { for field_pat in subpatterns { diff --git a/compiler/rustc_mir_build/src/builder/custom/parse.rs b/compiler/rustc_mir_build/src/builder/custom/parse.rs index c6ef362c6ea5..3ae4b1fadee9 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse.rs @@ -287,22 +287,14 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { self.parse_var(pattern) } - fn parse_var(&mut self, mut pat: &Pat<'tcx>) -> PResult<(LocalVarId, Ty<'tcx>, Span)> { - // Make sure we throw out any `AscribeUserType` we find - loop { - match &pat.kind { - PatKind::Binding { var, ty, .. } => break Ok((*var, *ty, pat.span)), - PatKind::AscribeUserType { subpattern, .. } => { - pat = subpattern; - } - _ => { - break Err(ParseError { - span: pat.span, - item_description: format!("{:?}", pat.kind), - expected: "local".to_string(), - }); - } - } + fn parse_var(&mut self, pat: &Pat<'tcx>) -> PResult<(LocalVarId, Ty<'tcx>, Span)> { + match &pat.kind { + PatKind::Binding { var, ty, .. } => Ok((*var, *ty, pat.span)), + _ => Err(ParseError { + span: pat.span, + item_description: format!("{:?}", pat.kind), + expected: "local".to_string(), + }), } } diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index ddaa61c6cc91..13082d408ec0 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -144,11 +144,6 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { let arm = &self.thir[*arm]; let value = match arm.pattern.kind { PatKind::Constant { value } => value, - PatKind::ExpandedConstant { ref subpattern, def_id: _ } - if let PatKind::Constant { value } = subpattern.kind => - { - value - } _ => { return Err(ParseError { span: arm.pattern.span, diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index f0114c2193c3..8cee3ff27e8f 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -133,6 +133,20 @@ impl<'tcx> MatchPairTree<'tcx> { } let place = place_builder.try_to_place(cx); + + // Apply any type ascriptions to the value at `match_pair.place`. + if let Some(place) = place + && let Some(extra) = &pattern.extra + { + for &Ascription { ref annotation, variance } in &extra.ascriptions { + extra_data.ascriptions.push(super::Ascription { + source: place, + annotation: annotation.clone(), + variance, + }); + } + } + let mut subpairs = Vec::new(); let testable_case = match pattern.kind { PatKind::Missing | PatKind::Wild | PatKind::Error(_) => None, @@ -195,28 +209,6 @@ impl<'tcx> MatchPairTree<'tcx> { Some(TestableCase::Constant { value, kind: const_kind }) } - PatKind::AscribeUserType { - ascription: Ascription { ref annotation, variance }, - ref subpattern, - .. - } => { - MatchPairTree::for_pattern( - place_builder, - subpattern, - cx, - &mut subpairs, - extra_data, - ); - - // Apply the type ascription to the value at `match_pair.place` - if let Some(source) = place { - let annotation = annotation.clone(); - extra_data.ascriptions.push(super::Ascription { source, annotation, variance }); - } - - None - } - PatKind::Binding { mode, var, is_shorthand, ref subpattern, .. } => { // In order to please the borrow checker, when lowering a pattern // like `x @ subpat` we must establish any bindings in `subpat` @@ -263,11 +255,6 @@ impl<'tcx> MatchPairTree<'tcx> { None } - PatKind::ExpandedConstant { subpattern: ref pattern, .. } => { - MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data); - None - } - PatKind::Array { ref prefix, ref slice, ref suffix } => { cx.prefix_slice_suffix( &mut subpairs, diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index aaca6936dcd2..590316a47554 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -576,7 +576,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { initializer_id: ExprId, ) -> BlockAnd<()> { match irrefutable_pat.kind { - // Optimize the case of `let x = ...` to write directly into `x` + // Optimize `let x = ...` and `let x: T = ...` to write directly into `x`, + // and then require that `T == typeof(x)` if present. PatKind::Binding { mode: BindingMode(ByRef::No, _), var, subpattern: None, .. } => { let place = self.storage_live_binding( block, @@ -592,43 +593,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_info = self.source_info(irrefutable_pat.span); self.cfg.push_fake_read(block, source_info, FakeReadCause::ForLet(None), place); - self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard); - block.unit() - } + let ascriptions: &[_] = + try { irrefutable_pat.extra.as_deref()?.ascriptions.as_slice() } + .unwrap_or_default(); + for thir::Ascription { annotation, variance: _ } in ascriptions { + let ty_source_info = self.source_info(annotation.span); - // Optimize the case of `let x: T = ...` to write directly - // into `x` and then require that `T == typeof(x)`. - PatKind::AscribeUserType { - ref subpattern, - ascription: thir::Ascription { ref annotation, variance: _ }, - } if let PatKind::Binding { - mode: BindingMode(ByRef::No, _), - var, - subpattern: None, - .. - } = subpattern.kind => - { - let place = self.storage_live_binding( - block, - var, - irrefutable_pat.span, - false, - OutsideGuard, - ScheduleDrops::Yes, - ); - block = self.expr_into_dest(place, block, initializer_id).into_block(); - - // Inject a fake read, see comments on `FakeReadCause::ForLet`. - let pattern_source_info = self.source_info(irrefutable_pat.span); - let cause_let = FakeReadCause::ForLet(None); - self.cfg.push_fake_read(block, pattern_source_info, cause_let, place); - - let ty_source_info = self.source_info(annotation.span); - - let base = self.canonical_user_type_annotations.push(annotation.clone()); - self.cfg.push( - block, - Statement::new( + let base = self.canonical_user_type_annotations.push(annotation.clone()); + let stmt = Statement::new( ty_source_info, StatementKind::AscribeUserType( Box::new((place, UserTypeProjection { base, projs: Vec::new() })), @@ -648,8 +620,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // ``. ty::Invariant, ), - ), - ); + ); + self.cfg.push(block, stmt); + } self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard); block.unit() @@ -884,9 +857,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Caution: Pushing user types here is load-bearing even for // patterns containing no bindings, to ensure that the type ends // up represented in MIR _somewhere_. - let user_tys = match pattern.kind { - PatKind::AscribeUserType { ref ascription, .. } => { - let base_user_tys = std::iter::once(ascription) + let user_tys = match pattern.extra.as_deref() { + Some(PatExtra { ascriptions, .. }) if !ascriptions.is_empty() => { + let base_user_tys = ascriptions + .iter() .map(|thir::Ascription { annotation, variance: _ }| { // Note that the variance doesn't apply here, as we are tracking the effect // of user types on any bindings contained with subpattern. @@ -943,15 +917,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { visit_subpat(self, subpattern, &ProjectedUserTypesNode::None, f); } - PatKind::AscribeUserType { ref subpattern, ascription: _ } => { - // The ascription was already handled above, so just recurse to the subpattern. - visit_subpat(self, subpattern, user_tys, f) - } - - PatKind::ExpandedConstant { ref subpattern, .. } => { - visit_subpat(self, subpattern, user_tys, f) - } - PatKind::Leaf { ref subpatterns } => { for subpattern in subpatterns { let subpattern_user_tys = user_tys.leaf(subpattern.field); diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 4f03e3d965c6..68b8a842a2a6 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -342,8 +342,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { PatKind::Wild | // these just wrap other patterns, which we recurse on below. PatKind::Or { .. } | - PatKind::ExpandedConstant { .. } | - PatKind::AscribeUserType { .. } | PatKind::Error(_) => {} } }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index bf480cf601ee..d9a06de32bb0 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -680,20 +680,13 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let mut interpreted_as_const = None; let mut interpreted_as_const_sugg = None; - // These next few matches want to peek through `AscribeUserType` to see - // the underlying pattern. - let mut unpeeled_pat = pat; - while let PatKind::AscribeUserType { ref subpattern, .. } = unpeeled_pat.kind { - unpeeled_pat = subpattern; - } - - if let Some(def_id) = is_const_pat_that_looks_like_binding(self.tcx, unpeeled_pat) { + if let Some(def_id) = is_const_pat_that_looks_like_binding(self.tcx, pat) { let span = self.tcx.def_span(def_id); let variable = self.tcx.item_name(def_id).to_string(); // When we encounter a constant as the binding name, point at the `const` definition. interpreted_as_const = Some(InterpretedAsConst { span, variable: variable.clone() }); interpreted_as_const_sugg = Some(InterpretedAsConstSugg { span: pat.span, variable }); - } else if let PatKind::Constant { .. } = unpeeled_pat.kind + } else if let PatKind::Constant { .. } = pat.kind && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span) { // If the pattern to match is an integer literal: @@ -1213,7 +1206,7 @@ fn is_const_pat_that_looks_like_binding<'tcx>(tcx: TyCtxt<'tcx>, pat: &Pat<'tcx> // The pattern must be a named constant, and the name that appears in // the pattern's source text must resemble a plain identifier without any // `::` namespace separators or other non-identifier characters. - if let PatKind::ExpandedConstant { def_id, .. } = pat.kind + if let Some(def_id) = try { pat.extra.as_deref()?.expanded_const? } && matches!(tcx.def_kind(def_id), DefKind::Const) && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(pat.span) && snippet.chars().all(|c| c.is_alphanumeric() || c == '_') diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 98faf0ab613f..02409d2bae9f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -186,14 +186,9 @@ impl<'tcx> ConstToPat<'tcx> { } } - // Wrap the pattern in a marker node to indicate that it is the result of lowering a + // Mark the pattern to indicate that it is the result of lowering a named // constant. This is used for diagnostics. - thir_pat = Box::new(Pat { - ty: thir_pat.ty, - span: thir_pat.span, - kind: PatKind::ExpandedConstant { def_id: uv.def, subpattern: thir_pat }, - extra: None, - }); + thir_pat.extra.get_or_insert_default().expanded_const = Some(uv.def); thir_pat } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 9c39a934c7ee..650650cbaac9 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -71,15 +71,11 @@ pub(super) fn pat_from_hir<'tcx>( span: let_stmt_type.span, inferred_ty: typeck_results.node_type(let_stmt_type.hir_id), }; - thir_pat = Box::new(Pat { - ty: thir_pat.ty, - span: thir_pat.span, - kind: PatKind::AscribeUserType { - ascription: Ascription { annotation, variance: ty::Covariant }, - subpattern: thir_pat, - }, - extra: None, - }); + thir_pat + .extra + .get_or_insert_default() + .ascriptions + .push(Ascription { annotation, variance: ty::Covariant }); } if let Some(m) = pcx.rust_2024_migration { @@ -171,23 +167,11 @@ impl<'tcx> PatCtxt<'tcx> { // Lower the endpoint into a temporary `thir::Pat` that will then be // deconstructed to obtain the constant value and other data. let endpoint_pat: Box> = self.lower_pat_expr(pat, expr); - let box Pat { mut kind, .. } = endpoint_pat; + let box Pat { ref kind, extra, .. } = endpoint_pat; - // Unpeel any ascription or inline-const wrapper nodes. - loop { - match kind { - PatKind::AscribeUserType { ascription, subpattern } => { - ascriptions.push(ascription); - kind = subpattern.kind; - } - PatKind::ExpandedConstant { def_id: _, subpattern } => { - // Expanded-constant nodes are currently only needed by - // diagnostics that don't apply to range patterns, so we - // can just discard them here. - kind = subpattern.kind; - } - _ => break, - } + // Preserve any ascriptions from endpoint constants. + if let Some(extra) = extra { + ascriptions.extend(extra.ascriptions); } // The unpeeled kind should now be a constant, giving us the endpoint value. @@ -313,15 +297,8 @@ impl<'tcx> PatCtxt<'tcx> { // If we are handling a range with associated constants (e.g. // `Foo::<'a>::A..=Foo::B`), we need to put the ascriptions for the associated // constants somewhere. Have them on the range pattern. - for ascription in ascriptions { - thir_pat = Box::new(Pat { - ty, - span, - kind: PatKind::AscribeUserType { ascription, subpattern: thir_pat }, - extra: None, - }); - } - // `PatKind::ExpandedConstant` wrappers from range endpoints used to + thir_pat.extra.get_or_insert_default().ascriptions.extend(ascriptions); + // IDs of expanded constants from range endpoints used to // also be preserved here, but that was only needed for unsafeck of // inline `const { .. }` patterns, which were removed by // . @@ -619,15 +596,11 @@ impl<'tcx> PatCtxt<'tcx> { span, inferred_ty: self.typeck_results.node_type(hir_id), }; - thir_pat = Box::new(Pat { - ty, - span, - kind: PatKind::AscribeUserType { - subpattern: thir_pat, - ascription: Ascription { annotation, variance: ty::Covariant }, - }, - extra: None, - }); + thir_pat + .extra + .get_or_insert_default() + .ascriptions + .push(Ascription { annotation, variance: ty::Covariant }); } thir_pat @@ -684,16 +657,13 @@ impl<'tcx> PatCtxt<'tcx> { span, inferred_ty: self.typeck_results.node_type(id), }; - let kind = PatKind::AscribeUserType { - subpattern: pattern, - ascription: Ascription { - annotation, - // Note that we use `Contravariant` here. See the - // `variance` field documentation for details. - variance: ty::Contravariant, - }, - }; - pattern = Box::new(Pat { span, kind, ty, extra: None }); + // Note that we use `Contravariant` here. See the + // `variance` field documentation for details. + pattern + .extra + .get_or_insert_default() + .ascriptions + .push(Ascription { annotation, variance: ty::Contravariant }); } pattern diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index d735ef2134ab..e12909305961 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -725,13 +725,6 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { PatKind::Never => { print_indented!(self, "Never", depth_lvl + 1); } - PatKind::AscribeUserType { ascription, subpattern } => { - print_indented!(self, "AscribeUserType: {", depth_lvl + 1); - print_indented!(self, format!("ascription: {:?}", ascription), depth_lvl + 2); - print_indented!(self, "subpattern: ", depth_lvl + 2); - self.print_pat(subpattern, depth_lvl + 3); - print_indented!(self, "}", depth_lvl + 1); - } PatKind::Binding { name, mode, var, ty, subpattern, is_primary, is_shorthand } => { print_indented!(self, "Binding {", depth_lvl + 1); print_indented!(self, format!("name: {:?}", name), depth_lvl + 2); @@ -796,13 +789,6 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, format!("value: {}", value), depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); } - PatKind::ExpandedConstant { def_id, subpattern } => { - print_indented!(self, "ExpandedConstant {", depth_lvl + 1); - print_indented!(self, format!("def_id: {def_id:?}"), depth_lvl + 2); - print_indented!(self, "subpattern:", depth_lvl + 2); - self.print_pat(subpattern, depth_lvl + 2); - print_indented!(self, "}", depth_lvl + 1); - } PatKind::Range(pat_range) => { print_indented!(self, format!("Range ( {:?} )", pat_range), depth_lvl + 1); } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index d66c303b1726..721635ed48ff 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -462,8 +462,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let arity; let fields: Vec<_>; match &pat.kind { - PatKind::AscribeUserType { subpattern, .. } - | PatKind::ExpandedConstant { subpattern, .. } => return self.lower_pat(subpattern), PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat), PatKind::Missing | PatKind::Binding { subpattern: None, .. } | PatKind::Wild => { ctor = Wildcard; From 561b59255c7f9a9b6893a06b261ab08c4343b81e Mon Sep 17 00:00:00 2001 From: andjsrk Date: Fri, 9 Jan 2026 15:45:05 +0900 Subject: [PATCH 1836/3801] add test for binary ops --- ...can-have-side-effects-consider-operands.rs | 23 +++++++++++++++++++ ...have-side-effects-consider-operands.stderr | 13 +++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/ui/binop/can-have-side-effects-consider-operands.rs create mode 100644 tests/ui/binop/can-have-side-effects-consider-operands.stderr diff --git a/tests/ui/binop/can-have-side-effects-consider-operands.rs b/tests/ui/binop/can-have-side-effects-consider-operands.rs new file mode 100644 index 000000000000..34eeb11c6add --- /dev/null +++ b/tests/ui/binop/can-have-side-effects-consider-operands.rs @@ -0,0 +1,23 @@ +//@ check-pass + +#![allow(unused)] + +// Test if `Expr::can_have_side_effects` considers operands of binary operators. + +fn drop_repeat_in_arm_body() { + // Built-in lint `dropping_copy_types` relies on `Expr::can_have_side_effects` + // (See rust-clippy#9482 and rust#113231) + + match () { + () => drop(5 % 3), // No side effects + //~^ WARNING calls to `std::mem::drop` with a value that implements `Copy` does nothing + } + match () { + () => drop(5 % calls_are_considered_side_effects()), // Definitely has side effects + } +} +fn calls_are_considered_side_effects() -> i32 { + 3 +} + +fn main() {} diff --git a/tests/ui/binop/can-have-side-effects-consider-operands.stderr b/tests/ui/binop/can-have-side-effects-consider-operands.stderr new file mode 100644 index 000000000000..ef3fc6b4be7e --- /dev/null +++ b/tests/ui/binop/can-have-side-effects-consider-operands.stderr @@ -0,0 +1,13 @@ +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/can-have-side-effects-consider-operands.rs:12:15 + | +LL | () => drop(5 % 3), // No side effects + | ^^^^^-----^ + | | + | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result + = note: `#[warn(dropping_copy_types)]` on by default + +warning: 1 warning emitted + From 7d0b1e144917b46d3e2b5c18ef6d434b098dab08 Mon Sep 17 00:00:00 2001 From: Coca Date: Fri, 2 Jan 2026 20:59:22 +0000 Subject: [PATCH 1837/3801] `transmuting_null`: Add checks for `without_provenance` and `without_provenance_mut` Currently `without_provenance`/`without_provenance_mut` do not have a `rustc_diagnostic_item` so this change is dependent on them being added before being ready to be used. changelog: [`transmuting_null`]: now checks for [`ptr::without_provenance`](https://doc.rust-lang.org/core/ptr/fn.without_provenance.html) and [`ptr::without_provenance_mut`](https://doc.rust-lang.org/core/ptr/fn.without_provenance_mut.html) which create null pointers --- clippy_lints/src/transmute/transmuting_null.rs | 12 ++++++++++++ tests/ui/transmuting_null.rs | 11 +++++++++++ tests/ui/transmuting_null.stderr | 14 +++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/transmute/transmuting_null.rs b/clippy_lints/src/transmute/transmuting_null.rs index 3f435f255d91..4f06d98703f6 100644 --- a/clippy_lints/src/transmute/transmuting_null.rs +++ b/clippy_lints/src/transmute/transmuting_null.rs @@ -42,6 +42,18 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t return true; } + // Catching: + // `std::mem::transmute(std::ptr::without_provenance::(0))` + // `std::mem::transmute(std::ptr::without_provenance_mut::(0))` + if let ExprKind::Call(func1, [arg1]) = arg.kind + && (func1.basic_res().is_diag_item(cx, sym::ptr_without_provenance) + || func1.basic_res().is_diag_item(cx, sym::ptr_without_provenance_mut)) + && is_integer_const(cx, arg1, 0) + { + span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG); + return true; + } + // Catching: // `std::mem::transmute({ 0 as *const u64 })` and similar const blocks if let ExprKind::Block(block, _) = arg.kind diff --git a/tests/ui/transmuting_null.rs b/tests/ui/transmuting_null.rs index 00aa35dff803..efa4c5cfdc2d 100644 --- a/tests/ui/transmuting_null.rs +++ b/tests/ui/transmuting_null.rs @@ -47,9 +47,20 @@ fn transumute_single_expr_blocks() { } } +fn transmute_pointer_creators() { + unsafe { + let _: &u64 = std::mem::transmute(std::ptr::without_provenance::(0)); + //~^ transmuting_null + + let _: &u64 = std::mem::transmute(std::ptr::without_provenance_mut::(0)); + //~^ transmuting_null + } +} + fn main() { one_liners(); transmute_const(); transmute_const_int(); transumute_single_expr_blocks(); + transmute_pointer_creators(); } diff --git a/tests/ui/transmuting_null.stderr b/tests/ui/transmuting_null.stderr index e1de391813bd..3c6c28f31d0d 100644 --- a/tests/ui/transmuting_null.stderr +++ b/tests/ui/transmuting_null.stderr @@ -37,5 +37,17 @@ error: transmuting a known null pointer into a reference LL | let _: &u64 = std::mem::transmute(const { u64::MIN as *const u64 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error: transmuting a known null pointer into a reference + --> tests/ui/transmuting_null.rs:52:23 + | +LL | let _: &u64 = std::mem::transmute(std::ptr::without_provenance::(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmuting a known null pointer into a reference + --> tests/ui/transmuting_null.rs:55:23 + | +LL | let _: &u64 = std::mem::transmute(std::ptr::without_provenance_mut::(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors From 7e433ebe7e7b6d3749ec1aed039ab4408d4ad051 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Fri, 9 Jan 2026 04:08:45 +0100 Subject: [PATCH 1838/3801] [miri] make closing stdio file descriptions noops std supports redirecting stdio file descriptors. --- src/tools/miri/src/shims/files.rs | 36 +++++++++++++++++++ .../tests/fail-dep/libc/fs/close_stdout.rs | 10 ------ .../fail-dep/libc/fs/close_stdout.stderr | 12 ------- src/tools/miri/tests/pass-dep/libc/libc-fs.rs | 9 +++++ 4 files changed, 45 insertions(+), 22 deletions(-) delete mode 100644 src/tools/miri/tests/fail-dep/libc/fs/close_stdout.rs delete mode 100644 src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr diff --git a/src/tools/miri/src/shims/files.rs b/src/tools/miri/src/shims/files.rs index f86933029341..694a5922b799 100644 --- a/src/tools/miri/src/shims/files.rs +++ b/src/tools/miri/src/shims/files.rs @@ -249,6 +249,15 @@ impl FileDescription for io::Stdin { finish.call(ecx, result) } + fn destroy<'tcx>( + self, + _self_id: FdId, + _communicate_allowed: bool, + _ecx: &mut MiriInterpCx<'tcx>, + ) -> InterpResult<'tcx, io::Result<()>> { + interp_ok(Ok(())) + } + fn is_tty(&self, communicate_allowed: bool) -> bool { communicate_allowed && self.is_terminal() } @@ -279,6 +288,15 @@ impl FileDescription for io::Stdout { finish.call(ecx, result) } + fn destroy<'tcx>( + self, + _self_id: FdId, + _communicate_allowed: bool, + _ecx: &mut MiriInterpCx<'tcx>, + ) -> InterpResult<'tcx, io::Result<()>> { + interp_ok(Ok(())) + } + fn is_tty(&self, communicate_allowed: bool) -> bool { communicate_allowed && self.is_terminal() } @@ -289,6 +307,15 @@ impl FileDescription for io::Stderr { "stderr" } + fn destroy<'tcx>( + self, + _self_id: FdId, + _communicate_allowed: bool, + _ecx: &mut MiriInterpCx<'tcx>, + ) -> InterpResult<'tcx, io::Result<()>> { + interp_ok(Ok(())) + } + fn write<'tcx>( self: FileDescriptionRef, _communicate_allowed: bool, @@ -436,6 +463,15 @@ impl FileDescription for NullOutput { // We just don't write anything, but report to the user that we did. finish.call(ecx, Ok(len)) } + + fn destroy<'tcx>( + self, + _self_id: FdId, + _communicate_allowed: bool, + _ecx: &mut MiriInterpCx<'tcx>, + ) -> InterpResult<'tcx, io::Result<()>> { + interp_ok(Ok(())) + } } /// Internal type of a file-descriptor - this is what [`FdTable`] expects diff --git a/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.rs b/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.rs deleted file mode 100644 index 7911133f548f..000000000000 --- a/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ignore-target: windows # No libc IO on Windows -//@compile-flags: -Zmiri-disable-isolation - -// FIXME: standard handles cannot be closed (https://github.com/rust-lang/rust/issues/40032) - -fn main() { - unsafe { - libc::close(1); //~ ERROR: cannot close stdout - } -} diff --git a/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr b/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr deleted file mode 100644 index 84973ac020de..000000000000 --- a/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error: unsupported operation: cannot close stdout - --> tests/fail-dep/libc/fs/close_stdout.rs:LL:CC - | -LL | libc::close(1); - | ^^^^^^^^^^^^^^ 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 - -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-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs index 99685d6d976b..8c860b5db7ba 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs @@ -48,6 +48,7 @@ fn main() { test_nofollow_not_symlink(); #[cfg(target_os = "macos")] test_ioctl(); + test_close_stdout(); } fn test_file_open_unix_allow_two_args() { @@ -579,3 +580,11 @@ fn test_ioctl() { assert_eq!(libc::ioctl(fd, libc::FIOCLEX), 0); } } + +fn test_close_stdout() { + // This is std library UB, but that's not relevant since we're + // only interacting with libc here. + unsafe { + libc::close(1); + } +} From 3c8265a29f3354edfe03b7bd326c68e4decc2a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 19 Dec 2025 14:59:22 +0100 Subject: [PATCH 1839/3801] add test for 149981 --- tests/ui/eii/duplicate/eii_conflict_with_macro.rs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/ui/eii/duplicate/eii_conflict_with_macro.rs diff --git a/tests/ui/eii/duplicate/eii_conflict_with_macro.rs b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs new file mode 100644 index 000000000000..4012ea268799 --- /dev/null +++ b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs @@ -0,0 +1,6 @@ +//@ compile-flags: --crate-type rlib +#![feature(extern_item_impls)] + +macro_rules! foo_impl {} +#[eii] +fn foo_impl() {} From 5e5c724194594c9af85d6678aef90ebc4a3428b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 19 Dec 2025 18:24:15 +0100 Subject: [PATCH 1840/3801] turn panics into `span_delayed_bug` to make sure this pattern doesn't go unnoticed --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 11 +++++++--- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +--- compiler/rustc_metadata/src/eii.rs | 20 +++++++++++++++---- .../eii/duplicate/eii_conflict_with_macro.rs | 2 +- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 74f4662118b6..2ad5792de3c0 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -285,11 +285,16 @@ fn process_builtin_attrs( } AttributeKind::EiiImpls(impls) => { for i in impls { - let extern_item = find_attr!( + let Some(extern_item) = find_attr!( tcx.get_all_attrs(i.eii_macro), AttributeKind::EiiExternTarget(target) => target.eii_extern_target - ) - .expect("eii should have declaration macro with extern target attribute"); + ) else { + tcx.dcx().span_delayed_bug( + i.span, + "resolved to something that's not an EII", + ); + continue; + }; // this is to prevent a bug where a single crate defines both the default and explicit implementation // for an EII. In that case, both of them may be part of the same final object file. I'm not 100% sure diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 725294dfd377..8cc3fab128e2 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1213,9 +1213,7 @@ fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) { *span, ); } else { - panic!( - "EII impl macro {eii_macro:?} did not have an eii extern target attribute pointing to a foreign function" - ) + tcx.dcx().span_delayed_bug(*span, "resolved to something that's not an EII"); } } } diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs index 5558ff930851..3f60f528776f 100644 --- a/compiler/rustc_metadata/src/eii.rs +++ b/compiler/rustc_metadata/src/eii.rs @@ -1,4 +1,5 @@ use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::indexmap::map::Entry; use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl}; use rustc_hir::def_id::DefId; use rustc_hir::find_attr; @@ -28,11 +29,22 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap for i in find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiImpls(e) => e).into_iter().flatten() { - eiis.entry(i.eii_macro) - .or_insert_with(|| { + let registered_impls = match eiis.entry(i.eii_macro) { + Entry::Occupied(o) => &mut o.into_mut().1, + Entry::Vacant(v) => { // find the decl for this one if it wasn't in yet (maybe it's from the local crate? not very useful but not illegal) - (find_attr!(tcx.get_all_attrs(i.eii_macro), AttributeKind::EiiExternTarget(d) => *d).unwrap(), Default::default()) - }).1.insert(id.into(), *i); + let Some(decl) = find_attr!(tcx.get_all_attrs(i.eii_macro), AttributeKind::EiiExternTarget(d) => *d) + else { + // skip if it doesn't have eii_extern_target (if we resolved to another macro that's not an EII) + tcx.dcx() + .span_delayed_bug(i.span, "resolved to something that's not an EII"); + continue; + }; + &mut v.insert((decl, Default::default())).1 + } + }; + + registered_impls.insert(id.into(), *i); } // if we find a new declaration, add it to the list without a known implementation diff --git a/tests/ui/eii/duplicate/eii_conflict_with_macro.rs b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs index 4012ea268799..deee2346552f 100644 --- a/tests/ui/eii/duplicate/eii_conflict_with_macro.rs +++ b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs @@ -1,6 +1,6 @@ //@ compile-flags: --crate-type rlib #![feature(extern_item_impls)] -macro_rules! foo_impl {} +macro_rules! foo_impl { () => {} } #[eii] fn foo_impl() {} From e3cff18370d167b3e03eec8d31bf2f38709b7fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 8 Jan 2026 16:15:41 +0100 Subject: [PATCH 1841/3801] dont resolve defaults anymore, store foreign item defid instead of macro --- compiler/rustc_ast/src/ast.rs | 13 +++ compiler/rustc_ast_lowering/src/item.rs | 96 +++++++++++-------- compiler/rustc_builtin_macros/src/eii.rs | 8 ++ .../rustc_codegen_ssa/src/codegen_attrs.rs | 31 +++--- .../rustc_hir/src/attrs/data_structures.rs | 17 +++- .../src/check/compare_eii.rs | 12 +-- .../rustc_hir_analysis/src/check/wfcheck.rs | 35 +++---- compiler/rustc_metadata/src/eii.rs | 24 +++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 11 ++- compiler/rustc_passes/src/check_attr.rs | 16 +++- compiler/rustc_passes/src/eii.rs | 9 +- compiler/rustc_resolve/src/late.rs | 16 +++- 12 files changed, 188 insertions(+), 100 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index d4407dbf7be7..6d3cea95e77d 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3813,6 +3813,19 @@ pub struct Fn { pub struct EiiImpl { pub node_id: NodeId, pub eii_macro_path: Path, + /// This field is an implementation detail that prevents a lot of bugs. + /// See for an example. + /// + /// The problem is, that if we generate a declaration *together* with its default, + /// we generate both a declaration and an implementation. The generated implementation + /// uses the same mechanism to register itself as a user-defined implementation would, + /// despite being invisible to users. What does happen is a name resolution step. + /// The invisible default implementation has to find the declaration. + /// Both are generated at the same time, so we can skip that name resolution step. + /// + /// This field is that shortcut: we prefill the extern target to skip a name resolution step, + /// making sure it never fails. It'd be awful UX if we fail name resolution in code invisible to the user. + pub known_eii_macro_resolution: Option, pub impl_safety: Safety, pub span: Span, pub inner_span: Span, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index f8b98a5ece40..4b7995aa079e 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -2,7 +2,7 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err}; -use rustc_hir::attrs::{AttributeKind, EiiDecl}; +use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImplResolution}; use rustc_hir::def::{DefKind, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::{ @@ -134,6 +134,55 @@ impl<'hir> LoweringContext<'_, 'hir> { } } + fn lower_eii_extern_target( + &mut self, + id: NodeId, + EiiExternTarget { extern_item_path, impl_unsafe, span }: &EiiExternTarget, + ) -> Option { + self.lower_path_simple_eii(id, extern_item_path).map(|did| EiiDecl { + eii_extern_target: did, + impl_unsafe: *impl_unsafe, + span: self.lower_span(*span), + }) + } + + fn lower_eii_impl( + &mut self, + EiiImpl { + node_id, + eii_macro_path, + impl_safety, + span, + inner_span, + is_default, + known_eii_macro_resolution, + }: &EiiImpl, + ) -> hir::attrs::EiiImpl { + let resolution = if let Some(target) = known_eii_macro_resolution + && let Some(decl) = self.lower_eii_extern_target(*node_id, target) + { + EiiImplResolution::Known( + decl, + // the expect is ok here since we always generate this path in the eii macro. + eii_macro_path.segments.last().expect("at least one segment").ident.name, + ) + } else if let Some(macro_did) = self.lower_path_simple_eii(*node_id, eii_macro_path) { + EiiImplResolution::Macro(macro_did) + } else { + EiiImplResolution::Error( + self.dcx().span_delayed_bug(*span, "eii never resolved without errors given"), + ) + }; + + hir::attrs::EiiImpl { + span: self.lower_span(*span), + inner_span: self.lower_span(*inner_span), + impl_marked_unsafe: self.lower_safety(*impl_safety, hir::Safety::Safe).is_unsafe(), + is_default: *is_default, + resolution, + } + } + fn generate_extra_attrs_for_item_kind( &mut self, id: NodeId, @@ -143,49 +192,14 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Fn(box Fn { eii_impls, .. }) if eii_impls.is_empty() => Vec::new(), ItemKind::Fn(box Fn { eii_impls, .. }) => { vec![hir::Attribute::Parsed(AttributeKind::EiiImpls( - eii_impls - .iter() - .flat_map( - |EiiImpl { - node_id, - eii_macro_path, - impl_safety, - span, - inner_span, - is_default, - }| { - self.lower_path_simple_eii(*node_id, eii_macro_path).map(|did| { - hir::attrs::EiiImpl { - eii_macro: did, - span: self.lower_span(*span), - inner_span: self.lower_span(*inner_span), - impl_marked_unsafe: self - .lower_safety(*impl_safety, hir::Safety::Safe) - .is_unsafe(), - is_default: *is_default, - } - }) - }, - ) - .collect(), + eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(), ))] } - ItemKind::MacroDef( - _, - MacroDef { - eii_extern_target: Some(EiiExternTarget { extern_item_path, impl_unsafe, span }), - .. - }, - ) => self - .lower_path_simple_eii(id, extern_item_path) - .map(|did| { - vec![hir::Attribute::Parsed(AttributeKind::EiiExternTarget(EiiDecl { - eii_extern_target: did, - impl_unsafe: *impl_unsafe, - span: self.lower_span(*span), - }))] - }) + ItemKind::MacroDef(_, MacroDef { eii_extern_target: Some(target), .. }) => self + .lower_eii_extern_target(id, target) + .map(|decl| vec![hir::Attribute::Parsed(AttributeKind::EiiExternTarget(decl))]) .unwrap_or_default(), + ItemKind::ExternCrate(..) | ItemKind::Use(..) | ItemKind::Static(..) diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 9049639925dd..5105cdacd186 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -116,6 +116,7 @@ fn eii_( macro_name, eii_attr_span, item_span, + foreign_item_name, ))) } @@ -192,6 +193,7 @@ fn generate_default_impl( macro_name: Ident, eii_attr_span: Span, item_span: Span, + foreign_item_name: Ident, ) -> ast::Item { // FIXME: re-add some original attrs let attrs = ThinVec::new(); @@ -208,6 +210,11 @@ fn generate_default_impl( }, span: eii_attr_span, is_default: true, + known_eii_macro_resolution: Some(ast::EiiExternTarget { + extern_item_path: ast::Path::from_ident(foreign_item_name), + impl_unsafe, + span: item_span, + }), }); ast::Item { @@ -508,6 +515,7 @@ pub(crate) fn eii_shared_macro( impl_safety: meta_item.unsafety, span, is_default, + known_eii_macro_resolution: None, }); vec![item] diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 2ad5792de3c0..8b8abfeb6a4f 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -3,7 +3,9 @@ use std::str::FromStr; use rustc_abi::{Align, ExternAbi}; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr}; -use rustc_hir::attrs::{AttributeKind, InlineAttr, Linkage, RtsanSetting, UsedBy}; +use rustc_hir::attrs::{ + AttributeKind, EiiImplResolution, InlineAttr, Linkage, RtsanSetting, UsedBy, +}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items}; @@ -285,15 +287,22 @@ fn process_builtin_attrs( } AttributeKind::EiiImpls(impls) => { for i in impls { - let Some(extern_item) = find_attr!( - tcx.get_all_attrs(i.eii_macro), - AttributeKind::EiiExternTarget(target) => target.eii_extern_target - ) else { - tcx.dcx().span_delayed_bug( - i.span, - "resolved to something that's not an EII", - ); - continue; + let extern_item = match i.resolution { + EiiImplResolution::Macro(def_id) => { + let Some(extern_item) = find_attr!( + tcx.get_all_attrs(def_id), + AttributeKind::EiiExternTarget(target) => target.eii_extern_target + ) else { + tcx.dcx().span_delayed_bug( + i.span, + "resolved to something that's not an EII", + ); + continue; + }; + extern_item + } + EiiImplResolution::Known(decl, _) => decl.eii_extern_target, + EiiImplResolution::Error(_eg) => continue, }; // this is to prevent a bug where a single crate defines both the default and explicit implementation @@ -307,7 +316,7 @@ fn process_builtin_attrs( // iterate over all implementations *in the current crate* // (this is ok since we generate codegen fn attrs in the local crate) // if any of them is *not default* then don't emit the alias. - && tcx.externally_implementable_items(LOCAL_CRATE).get(&i.eii_macro).expect("at least one").1.iter().any(|(_, imp)| !imp.is_default) + && tcx.externally_implementable_items(LOCAL_CRATE).get(&extern_item).expect("at least one").1.iter().any(|(_, imp)| !imp.is_default) { continue; } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index fa8998f0546d..5b2d73faef19 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -11,7 +11,7 @@ use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute}; use rustc_span::def_id::DefId; use rustc_span::hygiene::Transparency; -use rustc_span::{Ident, Span, Symbol}; +use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; pub use rustc_target::spec::SanitizerSet; use thin_vec::ThinVec; @@ -19,9 +19,22 @@ use crate::attrs::pretty_printing::PrintAttribute; use crate::limit::Limit; use crate::{DefaultBodyStability, PartialConstStability, RustcVersion, Stability}; +#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub enum EiiImplResolution { + /// Usually, finding the extern item that an EII implementation implements means finding + /// the defid of the associated attribute macro, and looking at *its* attributes to find + /// what foreign item its associated with. + Macro(DefId), + /// Sometimes though, we already know statically and can skip some name resolution. + /// Stored together with the eii's name for diagnostics. + Known(EiiDecl, Symbol), + /// For when resolution failed, but we want to continue compilation + Error(ErrorGuaranteed), +} + #[derive(Copy, Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] pub struct EiiImpl { - pub eii_macro: DefId, + pub resolution: EiiImplResolution, pub impl_marked_unsafe: bool, pub span: Span, pub inner_span: Span, diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs index 4e7f47a92108..d8afee9aafc9 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs @@ -32,21 +32,21 @@ use crate::errors::{EiiWithGenerics, LifetimesOrBoundsMismatchOnEii}; pub(crate) fn compare_eii_function_types<'tcx>( tcx: TyCtxt<'tcx>, external_impl: LocalDefId, - declaration: DefId, + foreign_item: DefId, eii_name: Symbol, eii_attr_span: Span, ) -> Result<(), ErrorGuaranteed> { - check_is_structurally_compatible(tcx, external_impl, declaration, eii_name, eii_attr_span)?; + check_is_structurally_compatible(tcx, external_impl, foreign_item, eii_name, eii_attr_span)?; let external_impl_span = tcx.def_span(external_impl); let cause = ObligationCause::new( external_impl_span, external_impl, - ObligationCauseCode::CompareEii { external_impl, declaration }, + ObligationCauseCode::CompareEii { external_impl, declaration: foreign_item }, ); // FIXME(eii): even if we don't support generic functions, we should support explicit outlive bounds here - let param_env = tcx.param_env(declaration); + let param_env = tcx.param_env(foreign_item); let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(infcx); @@ -62,7 +62,7 @@ pub(crate) fn compare_eii_function_types<'tcx>( let mut wf_tys = FxIndexSet::default(); let norm_cause = ObligationCause::misc(external_impl_span, external_impl); - let declaration_sig = tcx.fn_sig(declaration).instantiate_identity(); + let declaration_sig = tcx.fn_sig(foreign_item).instantiate_identity(); let declaration_sig = tcx.liberate_late_bound_regions(external_impl.into(), declaration_sig); debug!(?declaration_sig); @@ -103,7 +103,7 @@ pub(crate) fn compare_eii_function_types<'tcx>( cause, param_env, terr, - (declaration, declaration_sig), + (foreign_item, declaration_sig), (external_impl, external_impl_sig), eii_attr_span, eii_name, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 8cc3fab128e2..cefd8c8f1443 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -6,7 +6,7 @@ use rustc_abi::{ExternAbi, ScalableElt}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; -use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl}; +use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl, EiiImplResolution}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; @@ -1196,25 +1196,28 @@ fn check_item_fn( fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) { // does the function have an EiiImpl attribute? that contains the defid of a *macro* // that was used to mark the implementation. This is a two step process. - for EiiImpl { eii_macro, span, .. } in + for EiiImpl { resolution, span, .. } in find_attr!(tcx.get_all_attrs(def_id), AttributeKind::EiiImpls(impls) => impls) .into_iter() .flatten() { - // we expect this macro to have the `EiiMacroFor` attribute, that points to a function - // signature that we'd like to compare the function we're currently checking with - if let Some(eii_extern_target) = find_attr!(tcx.get_all_attrs(*eii_macro), AttributeKind::EiiExternTarget(EiiDecl {eii_extern_target, ..}) => *eii_extern_target) - { - let _ = compare_eii_function_types( - tcx, - def_id, - eii_extern_target, - tcx.item_name(*eii_macro), - *span, - ); - } else { - tcx.dcx().span_delayed_bug(*span, "resolved to something that's not an EII"); - } + let (foreign_item, name) = match resolution { + EiiImplResolution::Macro(def_id) => { + // we expect this macro to have the `EiiMacroFor` attribute, that points to a function + // signature that we'd like to compare the function we're currently checking with + if let Some(foreign_item) = find_attr!(tcx.get_all_attrs(*def_id), AttributeKind::EiiExternTarget(EiiDecl {eii_extern_target: t, ..}) => *t) + { + (foreign_item, tcx.item_name(*def_id)) + } else { + tcx.dcx().span_delayed_bug(*span, "resolved to something that's not an EII"); + continue; + } + } + EiiImplResolution::Known(decl, name) => (decl.eii_extern_target, *name), + EiiImplResolution::Error(_eg) => continue, + }; + + let _ = compare_eii_function_types(tcx, def_id, foreign_item, name, *span); } } diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs index 3f60f528776f..425de9e62e50 100644 --- a/compiler/rustc_metadata/src/eii.rs +++ b/compiler/rustc_metadata/src/eii.rs @@ -1,6 +1,5 @@ use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::indexmap::map::Entry; -use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl}; +use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl, EiiImplResolution}; use rustc_hir::def_id::DefId; use rustc_hir::find_attr; use rustc_middle::query::LocalCrate; @@ -10,7 +9,7 @@ use rustc_middle::ty::TyCtxt; pub(crate) type EiiMapEncodedKeyValue = (DefId, (EiiDecl, Vec<(DefId, EiiImpl)>)); pub(crate) type EiiMap = FxIndexMap< - DefId, // the defid of the macro that declared the eii + DefId, // the defid of the foreign item associated with the eii ( // the corresponding declaration EiiDecl, @@ -29,29 +28,34 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap for i in find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiImpls(e) => e).into_iter().flatten() { - let registered_impls = match eiis.entry(i.eii_macro) { - Entry::Occupied(o) => &mut o.into_mut().1, - Entry::Vacant(v) => { + let decl = match i.resolution { + EiiImplResolution::Macro(macro_defid) => { // find the decl for this one if it wasn't in yet (maybe it's from the local crate? not very useful but not illegal) - let Some(decl) = find_attr!(tcx.get_all_attrs(i.eii_macro), AttributeKind::EiiExternTarget(d) => *d) + let Some(decl) = find_attr!(tcx.get_all_attrs(macro_defid), AttributeKind::EiiExternTarget(d) => *d) else { // skip if it doesn't have eii_extern_target (if we resolved to another macro that's not an EII) tcx.dcx() .span_delayed_bug(i.span, "resolved to something that's not an EII"); continue; }; - &mut v.insert((decl, Default::default())).1 + decl } + EiiImplResolution::Known(decl, _) => decl, + EiiImplResolution::Error(_eg) => continue, }; - registered_impls.insert(id.into(), *i); + // FIXME(eii) remove extern target from encoded decl + eiis.entry(decl.eii_extern_target) + .or_insert_with(|| (decl, Default::default())) + .1 + .insert(id.into(), *i); } // if we find a new declaration, add it to the list without a known implementation if let Some(decl) = find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiExternTarget(d) => *d) { - eiis.entry(id.into()).or_insert((decl, Default::default())); + eiis.entry(decl.eii_extern_target).or_insert((decl, Default::default())); } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index c85327dc3db1..eedb88783ec0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1657,9 +1657,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { empty_proc_macro!(self); let externally_implementable_items = self.tcx.externally_implementable_items(LOCAL_CRATE); - self.lazy_array(externally_implementable_items.iter().map(|(decl_did, (decl, impls))| { - (*decl_did, (decl.clone(), impls.iter().map(|(impl_did, i)| (*impl_did, *i)).collect())) - })) + self.lazy_array(externally_implementable_items.iter().map( + |(foreign_item, (decl, impls))| { + ( + *foreign_item, + (decl.clone(), impls.iter().map(|(impl_did, i)| (*impl_did, *i)).collect()), + ) + }, + )) } #[instrument(level = "trace", skip(self))] diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index f1cbb72554d2..5b3bdc07ec94 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -21,8 +21,8 @@ use rustc_feature::{ BuiltinAttribute, }; use rustc_hir::attrs::{ - AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, InlineAttr, MirDialect, MirPhase, - ReprAttr, SanitizerSet, + AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, InlineAttr, + MirDialect, MirPhase, ReprAttr, SanitizerSet, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalModDefId; @@ -506,7 +506,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } fn check_eii_impl(&self, impls: &[EiiImpl], target: Target) { - for EiiImpl { span, inner_span, eii_macro, impl_marked_unsafe, is_default: _ } in impls { + for EiiImpl { span, inner_span, resolution, impl_marked_unsafe, is_default: _ } in impls { match target { Target::Fn => {} _ => { @@ -514,7 +514,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - if find_attr!(self.tcx.get_all_attrs(*eii_macro), AttributeKind::EiiExternTarget(EiiDecl { impl_unsafe, .. }) if *impl_unsafe) + if let EiiImplResolution::Macro(eii_macro) = resolution + && find_attr!(self.tcx.get_all_attrs(*eii_macro), AttributeKind::EiiExternTarget(EiiDecl { impl_unsafe, .. }) if *impl_unsafe) && !impl_marked_unsafe { self.dcx().emit_err(errors::EiiImplRequiresUnsafe { @@ -758,9 +759,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Some(impls) = find_attr!(attrs, AttributeKind::EiiImpls(impls) => impls) { let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap(); for i in impls { + let name = match i.resolution { + EiiImplResolution::Macro(def_id) => self.tcx.item_name(def_id), + EiiImplResolution::Known(_, name) => name, + EiiImplResolution::Error(_eg) => continue, + }; self.dcx().emit_err(errors::EiiWithTrackCaller { attr_span, - name: self.tcx.item_name(i.eii_macro), + name, sig_span: sig.span, }); } diff --git a/compiler/rustc_passes/src/eii.rs b/compiler/rustc_passes/src/eii.rs index ab3f9f0d2182..7d6edb694d4b 100644 --- a/compiler/rustc_passes/src/eii.rs +++ b/compiler/rustc_passes/src/eii.rs @@ -81,7 +81,7 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): } // now we have all eiis! For each of them, choose one we want to actually generate. - for (decl_did, FoundEii { decl, decl_crate, impls }) in eiis { + for (foreign_item, FoundEii { decl, decl_crate, impls }) in eiis { let mut default_impls = Vec::new(); let mut explicit_impls = Vec::new(); @@ -97,7 +97,7 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): // is instantly an error. if explicit_impls.len() > 1 { tcx.dcx().emit_err(DuplicateEiiImpls { - name: tcx.item_name(decl_did), + name: tcx.item_name(foreign_item), first_span: tcx.def_span(explicit_impls[0].0), first_crate: tcx.crate_name(explicit_impls[0].1), second_span: tcx.def_span(explicit_impls[1].0), @@ -116,7 +116,7 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): } if default_impls.len() > 1 { - let decl_span = tcx.def_ident_span(decl_did).unwrap(); + let decl_span = tcx.def_ident_span(foreign_item).unwrap(); tcx.dcx().span_delayed_bug(decl_span, "multiple not supported right now"); } @@ -139,7 +139,8 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): tcx.dcx().emit_err(EiiWithoutImpl { current_crate_name: tcx.crate_name(LOCAL_CRATE), decl_crate_name: tcx.crate_name(decl_crate), - name: tcx.item_name(decl_did), + // FIXME: shouldn't call `item_name` + name: tcx.item_name(foreign_item), span: decl.span, help: (), }); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b4941a6f5b99..f64bd4a1aa19 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1069,8 +1069,20 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc debug!("(resolving function) entering function"); if let FnKind::Fn(_, _, f) = fn_kind { - for EiiImpl { node_id, eii_macro_path, .. } in &f.eii_impls { - self.smart_resolve_path(*node_id, &None, &eii_macro_path, PathSource::Macro); + for EiiImpl { node_id, eii_macro_path, known_eii_macro_resolution, .. } in &f.eii_impls + { + // See docs on the `known_eii_macro_resolution` field: + // if we already know the resolution statically, don't bother resolving it. + if let Some(target) = known_eii_macro_resolution { + self.smart_resolve_path( + *node_id, + &None, + &target.extern_item_path, + PathSource::Expr(None), + ); + } else { + self.smart_resolve_path(*node_id, &None, &eii_macro_path, PathSource::Macro); + } } } From 5ddda0c37bae5d6867d04ed5be5dae5729df7bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 8 Jan 2026 16:43:24 +0100 Subject: [PATCH 1842/3801] fix up diagnostics referring to the right items --- compiler/rustc_ast/src/ast.rs | 3 +-- compiler/rustc_ast_lowering/src/item.rs | 21 ++++++++++--------- compiler/rustc_builtin_macros/src/eii.rs | 8 +------ .../rustc_codegen_ssa/src/codegen_attrs.rs | 2 +- .../rustc_hir/src/attrs/data_structures.rs | 4 ++-- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_metadata/src/eii.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_passes/src/eii.rs | 8 ++++--- compiler/rustc_resolve/src/late.rs | 2 +- tests/ui/eii/privacy2.stderr | 8 +++---- 11 files changed, 29 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 6d3cea95e77d..fb2ccefe12a1 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2117,10 +2117,9 @@ pub struct MacroDef { #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)] pub struct EiiExternTarget { - /// path to the extern item we're targetting + /// path to the extern item we're targeting pub extern_item_path: Path, pub impl_unsafe: bool, - pub span: Span, } #[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)] diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 4b7995aa079e..3a7308ef7c97 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -137,12 +137,13 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_eii_extern_target( &mut self, id: NodeId, - EiiExternTarget { extern_item_path, impl_unsafe, span }: &EiiExternTarget, + eii_name: Ident, + EiiExternTarget { extern_item_path, impl_unsafe }: &EiiExternTarget, ) -> Option { self.lower_path_simple_eii(id, extern_item_path).map(|did| EiiDecl { eii_extern_target: did, impl_unsafe: *impl_unsafe, - span: self.lower_span(*span), + name: eii_name, }) } @@ -159,13 +160,13 @@ impl<'hir> LoweringContext<'_, 'hir> { }: &EiiImpl, ) -> hir::attrs::EiiImpl { let resolution = if let Some(target) = known_eii_macro_resolution - && let Some(decl) = self.lower_eii_extern_target(*node_id, target) - { - EiiImplResolution::Known( - decl, + && let Some(decl) = self.lower_eii_extern_target( + *node_id, // the expect is ok here since we always generate this path in the eii macro. - eii_macro_path.segments.last().expect("at least one segment").ident.name, - ) + eii_macro_path.segments.last().expect("at least one segment").ident, + target, + ) { + EiiImplResolution::Known(decl) } else if let Some(macro_did) = self.lower_path_simple_eii(*node_id, eii_macro_path) { EiiImplResolution::Macro(macro_did) } else { @@ -195,8 +196,8 @@ impl<'hir> LoweringContext<'_, 'hir> { eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(), ))] } - ItemKind::MacroDef(_, MacroDef { eii_extern_target: Some(target), .. }) => self - .lower_eii_extern_target(id, target) + ItemKind::MacroDef(name, MacroDef { eii_extern_target: Some(target), .. }) => self + .lower_eii_extern_target(id, *name, target) .map(|decl| vec![hir::Attribute::Parsed(AttributeKind::EiiExternTarget(decl))]) .unwrap_or_default(), diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 5105cdacd186..ff24eba217df 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -103,8 +103,6 @@ fn eii_( // span of the declaring item without attributes let item_span = func.sig.span; - // span of the eii attribute and the item below it, i.e. the full declaration - let decl_span = eii_attr_span.to(item_span); let foreign_item_name = func.ident; let mut return_items = Vec::new(); @@ -134,7 +132,6 @@ fn eii_( macro_name, foreign_item_name, impl_unsafe, - decl_span, ))); return_items.into_iter().map(wrap_item).collect() @@ -213,7 +210,6 @@ fn generate_default_impl( known_eii_macro_resolution: Some(ast::EiiExternTarget { extern_item_path: ast::Path::from_ident(foreign_item_name), impl_unsafe, - span: item_span, }), }); @@ -359,7 +355,6 @@ fn generate_attribute_macro_to_implement( macro_name: Ident, foreign_item_name: Ident, impl_unsafe: bool, - decl_span: Span, ) -> ast::Item { let mut macro_attrs = ThinVec::new(); @@ -401,7 +396,6 @@ fn generate_attribute_macro_to_implement( eii_extern_target: Some(ast::EiiExternTarget { extern_item_path: ast::Path::from_ident(foreign_item_name), impl_unsafe, - span: decl_span, }), }, ), @@ -458,7 +452,7 @@ pub(crate) fn eii_extern_target( false }; - d.eii_extern_target = Some(EiiExternTarget { extern_item_path, impl_unsafe, span }); + d.eii_extern_target = Some(EiiExternTarget { extern_item_path, impl_unsafe }); // Return the original item and the new methods. vec![item] diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 8b8abfeb6a4f..7dda824e2b18 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -301,7 +301,7 @@ fn process_builtin_attrs( }; extern_item } - EiiImplResolution::Known(decl, _) => decl.eii_extern_target, + EiiImplResolution::Known(decl) => decl.eii_extern_target, EiiImplResolution::Error(_eg) => continue, }; diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 5b2d73faef19..23201eff455f 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -27,7 +27,7 @@ pub enum EiiImplResolution { Macro(DefId), /// Sometimes though, we already know statically and can skip some name resolution. /// Stored together with the eii's name for diagnostics. - Known(EiiDecl, Symbol), + Known(EiiDecl), /// For when resolution failed, but we want to continue compilation Error(ErrorGuaranteed), } @@ -46,7 +46,7 @@ pub struct EiiDecl { pub eii_extern_target: DefId, /// whether or not it is unsafe to implement this EII pub impl_unsafe: bool, - pub span: Span, + pub name: Ident, } #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)] diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index cefd8c8f1443..7ec4110f80b9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1213,7 +1213,7 @@ fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) { continue; } } - EiiImplResolution::Known(decl, name) => (decl.eii_extern_target, *name), + EiiImplResolution::Known(decl) => (decl.eii_extern_target, decl.name.name), EiiImplResolution::Error(_eg) => continue, }; diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs index 425de9e62e50..b06ac8481397 100644 --- a/compiler/rustc_metadata/src/eii.rs +++ b/compiler/rustc_metadata/src/eii.rs @@ -40,7 +40,7 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap }; decl } - EiiImplResolution::Known(decl, _) => decl, + EiiImplResolution::Known(decl) => decl, EiiImplResolution::Error(_eg) => continue, }; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5b3bdc07ec94..2d3c5c7e48a0 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -761,7 +761,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for i in impls { let name = match i.resolution { EiiImplResolution::Macro(def_id) => self.tcx.item_name(def_id), - EiiImplResolution::Known(_, name) => name, + EiiImplResolution::Known(decl) => decl.name.name, EiiImplResolution::Error(_eg) => continue, }; self.dcx().emit_err(errors::EiiWithTrackCaller { diff --git a/compiler/rustc_passes/src/eii.rs b/compiler/rustc_passes/src/eii.rs index 7d6edb694d4b..7c2c98920623 100644 --- a/compiler/rustc_passes/src/eii.rs +++ b/compiler/rustc_passes/src/eii.rs @@ -80,6 +80,8 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): } } + println!("{eiis:#?}"); + // now we have all eiis! For each of them, choose one we want to actually generate. for (foreign_item, FoundEii { decl, decl_crate, impls }) in eiis { let mut default_impls = Vec::new(); @@ -97,7 +99,7 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): // is instantly an error. if explicit_impls.len() > 1 { tcx.dcx().emit_err(DuplicateEiiImpls { - name: tcx.item_name(foreign_item), + name: decl.name.name, first_span: tcx.def_span(explicit_impls[0].0), first_crate: tcx.crate_name(explicit_impls[0].1), second_span: tcx.def_span(explicit_impls[1].0), @@ -140,8 +142,8 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): current_crate_name: tcx.crate_name(LOCAL_CRATE), decl_crate_name: tcx.crate_name(decl_crate), // FIXME: shouldn't call `item_name` - name: tcx.item_name(foreign_item), - span: decl.span, + name: decl.name.name, + span: decl.name.span, help: (), }); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f64bd4a1aa19..32cf57af2e7f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2929,7 +2929,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.parent_scope.macro_rules = self.r.macro_rules_scopes[&def_id]; } - if let Some(EiiExternTarget { extern_item_path, impl_unsafe: _, span: _ }) = + if let Some(EiiExternTarget { extern_item_path, impl_unsafe: _ }) = ¯o_def.eii_extern_target { self.smart_resolve_path( diff --git a/tests/ui/eii/privacy2.stderr b/tests/ui/eii/privacy2.stderr index 0d44604567e4..903285d4d1e3 100644 --- a/tests/ui/eii/privacy2.stderr +++ b/tests/ui/eii/privacy2.stderr @@ -17,18 +17,18 @@ LL | fn decl1(x: u64); | ^^^^^^^^^^^^^^^^^ error: `#[eii2]` required, but not found - --> $DIR/auxiliary/codegen3.rs:9:1 + --> $DIR/auxiliary/codegen3.rs:9:7 | LL | #[eii(eii2)] - | ^^^^^^^^^^^^ expected because `#[eii2]` was declared here in crate `codegen3` + | ^^^^ expected because `#[eii2]` was declared here in crate `codegen3` | = help: expected at least one implementation in crate `privacy2` or any of its dependencies error: `#[eii3]` required, but not found - --> $DIR/auxiliary/codegen3.rs:13:5 + --> $DIR/auxiliary/codegen3.rs:13:11 | LL | #[eii(eii3)] - | ^^^^^^^^^^^^ expected because `#[eii3]` was declared here in crate `codegen3` + | ^^^^ expected because `#[eii3]` was declared here in crate `codegen3` | = help: expected at least one implementation in crate `privacy2` or any of its dependencies From 52b3ac476c78224a1d35d3857d24413fdfb89138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 8 Jan 2026 18:43:16 +0100 Subject: [PATCH 1843/3801] trick with super imports that fixes nameres in anonymous modules --- compiler/rustc_builtin_macros/src/eii.rs | 71 ++++++++++++++++++++++-- compiler/rustc_passes/src/eii.rs | 2 - 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index ff24eba217df..2d67608609e3 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -109,6 +109,7 @@ fn eii_( if func.body.is_some() { return_items.push(Box::new(generate_default_impl( + ecx, &func, impl_unsafe, macro_name, @@ -185,6 +186,7 @@ fn filter_attrs_for_multiple_eii_attr( } fn generate_default_impl( + ecx: &mut ExtCtxt<'_>, func: &ast::Fn, impl_unsafe: bool, macro_name: Ident, @@ -208,7 +210,18 @@ fn generate_default_impl( span: eii_attr_span, is_default: true, known_eii_macro_resolution: Some(ast::EiiExternTarget { - extern_item_path: ast::Path::from_ident(foreign_item_name), + extern_item_path: ast::Path { + span: foreign_item_name.span, + segments: thin_vec![ + ast::PathSegment { + ident: Ident::from_str_and_span("super", foreign_item_name.span,), + id: DUMMY_NODE_ID, + args: None + }, + ast::PathSegment { ident: foreign_item_name, id: DUMMY_NODE_ID, args: None }, + ], + tokens: None, + }, impl_unsafe, }), }); @@ -239,18 +252,66 @@ fn generate_default_impl( stmts: thin_vec![ast::Stmt { id: DUMMY_NODE_ID, kind: ast::StmtKind::Item(Box::new(ast::Item { - attrs, + attrs: ThinVec::new(), id: DUMMY_NODE_ID, span: item_span, vis: ast::Visibility { - span: eii_attr_span, + span: item_span, kind: ast::VisibilityKind::Inherited, tokens: None }, - kind: ItemKind::Fn(Box::new(default_func)), + kind: ItemKind::Mod( + ast::Safety::Default, + Ident::from_str_and_span("dflt", item_span), + ast::ModKind::Loaded( + thin_vec![ + Box::new(ast::Item { + attrs: thin_vec![ecx.attr_nested_word( + sym::allow, + sym::unused_imports, + item_span + ),], + id: DUMMY_NODE_ID, + span: item_span, + vis: ast::Visibility { + span: eii_attr_span, + kind: ast::VisibilityKind::Inherited, + tokens: None + }, + kind: ItemKind::Use(ast::UseTree { + prefix: ast::Path::from_ident( + Ident::from_str_and_span( + "super", item_span, + ) + ), + kind: ast::UseTreeKind::Glob, + span: item_span, + }), + tokens: None, + }), + Box::new(ast::Item { + attrs, + id: DUMMY_NODE_ID, + span: item_span, + vis: ast::Visibility { + span: eii_attr_span, + kind: ast::VisibilityKind::Inherited, + tokens: None + }, + kind: ItemKind::Fn(Box::new(default_func)), + tokens: None, + }), + ], + ast::Inline::Yes, + ast::ModSpans { + inner_span: item_span, + inject_use_span: item_span, + } + ) + ), tokens: None, })), - span: eii_attr_span + span: eii_attr_span, }], id: DUMMY_NODE_ID, rules: ast::BlockCheckMode::Default, diff --git a/compiler/rustc_passes/src/eii.rs b/compiler/rustc_passes/src/eii.rs index 7c2c98920623..f3e84665f21d 100644 --- a/compiler/rustc_passes/src/eii.rs +++ b/compiler/rustc_passes/src/eii.rs @@ -80,8 +80,6 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): } } - println!("{eiis:#?}"); - // now we have all eiis! For each of them, choose one we want to actually generate. for (foreign_item, FoundEii { decl, decl_crate, impls }) in eiis { let mut default_impls = Vec::new(); From 7791bc22133cce1693b364f76e99416b50f4d348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 8 Jan 2026 18:44:56 +0100 Subject: [PATCH 1844/3801] mark ICE regression test as fixed --- tests/ui/eii/duplicate/eii_conflict_with_macro.rs | 1 + tests/ui/eii/privacy2.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/ui/eii/duplicate/eii_conflict_with_macro.rs b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs index deee2346552f..d8118f8417a0 100644 --- a/tests/ui/eii/duplicate/eii_conflict_with_macro.rs +++ b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs @@ -1,4 +1,5 @@ //@ compile-flags: --crate-type rlib +//@ build-pass #![feature(extern_item_impls)] macro_rules! foo_impl { () => {} } diff --git a/tests/ui/eii/privacy2.rs b/tests/ui/eii/privacy2.rs index a4ae188bd0ec..a0bc26ef629b 100644 --- a/tests/ui/eii/privacy2.rs +++ b/tests/ui/eii/privacy2.rs @@ -1,5 +1,5 @@ //@ aux-build:codegen3.rs -// Tests whether name resulution respects privacy properly. +// Tests whether name resolution respects privacy properly. #![feature(extern_item_impls)] extern crate codegen3 as codegen; From 025ac8f512f8c90e4ba02d69e98851e7a4bdb999 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Fri, 9 Jan 2026 08:37:01 +0000 Subject: [PATCH 1845/3801] The aarch64-unknown-none target requires NEON, so the docs were wrong. --- src/doc/rustc/src/platform-support/aarch64-unknown-none.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-none.md b/src/doc/rustc/src/platform-support/aarch64-unknown-none.md index 3d776677d23e..5d1201bbf426 100644 --- a/src/doc/rustc/src/platform-support/aarch64-unknown-none.md +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-none.md @@ -29,14 +29,15 @@ You may prefer the `-softfloat` target when writing a kernel or interfacing with pre-compiled binaries that use the soft-float ABI. When using the hardfloat targets, the minimum floating-point features assumed -are those of the `fp-armv8`, which excludes NEON SIMD support. If your +are [`FEAT_AdvSIMD`][feat-advsimd], which means NEON SIMD support. If your processor supports a different set of floating-point features than the default -expectations of `fp-armv8`, then these should also be enabled or disabled as -needed with `-C target-feature=(+/-)`. It is also possible to tell Rust (or +expectations of `FEAT_AdvSIMD`, then these should also be enabled or disabled +as needed with `-C target-feature=(+/-)`. It is also possible to tell Rust (or LLVM) that you have a specific model of Arm processor, using the [`-Ctarget-cpu`][target-cpu] option. Doing so may change the default set of target-features enabled. +[feat-advsimd]: https://developer.arm.com/documentation/109697/2025_12/Feature-descriptions/The-Armv8-0-architecture-extension?lang=en [target-cpu]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-cpu [target-feature]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-feature From 6a9dae4f3e679c298c6d6ad83f65d2d9c51a02f0 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 9 Jan 2026 10:37:00 +0100 Subject: [PATCH 1846/3801] Merge commit '500e0ff18726cd44b23004a02fc1b99f52c11ab1' into clippy-subtree-update --- COPYRIGHT | 2 +- Cargo.toml | 2 +- LICENSE-APACHE | 2 +- LICENSE-MIT | 2 +- README.md | 2 +- clippy_lints/src/attrs/allow_attributes.rs | 9 +- clippy_lints/src/attrs/mod.rs | 6 +- .../src/attrs/should_panic_without_expect.rs | 2 +- clippy_lints/src/bool_assert_comparison.rs | 33 +++-- clippy_lints/src/booleans.rs | 3 +- clippy_lints/src/cargo/mod.rs | 2 +- clippy_lints/src/cfg_not_test.rs | 13 +- clippy_lints/src/checked_conversions.rs | 5 +- .../src/derive/derive_ord_xor_partial_ord.rs | 9 +- clippy_lints/src/derive/mod.rs | 2 +- .../src/doc/include_in_doc_without_cfg.rs | 2 +- clippy_lints/src/doc/mod.rs | 10 +- clippy_lints/src/double_parens.rs | 2 + clippy_lints/src/implicit_saturating_sub.rs | 27 +++- clippy_lints/src/incompatible_msrv.rs | 10 +- clippy_lints/src/inherent_impl.rs | 23 ++- clippy_lints/src/large_include_file.rs | 2 +- clippy_lints/src/large_stack_arrays.rs | 9 ++ clippy_lints/src/loops/for_kv_map.rs | 24 +++- clippy_lints/src/loops/mod.rs | 2 +- clippy_lints/src/loops/never_loop.rs | 4 +- clippy_lints/src/manual_ignore_case_cmp.rs | 10 +- clippy_lints/src/manual_ilog2.rs | 4 +- clippy_lints/src/matches/manual_ok_err.rs | 2 +- clippy_lints/src/matches/match_as_ref.rs | 5 +- clippy_lints/src/matches/match_bool.rs | 96 ++++++------- .../src/matches/redundant_pattern_match.rs | 23 ++- clippy_lints/src/methods/is_empty.rs | 5 +- clippy_lints/src/methods/iter_kv_map.rs | 7 +- clippy_lints/src/methods/unnecessary_fold.rs | 111 +++++++++----- .../src/methods/unnecessary_to_owned.rs | 22 +-- .../src/missing_enforced_import_rename.rs | 3 +- clippy_lints/src/multiple_bound_locations.rs | 2 +- clippy_lints/src/mutex_atomic.rs | 2 +- clippy_lints/src/needless_bool.rs | 6 +- clippy_lints/src/needless_for_each.rs | 125 +++++++++------- clippy_lints/src/new_without_default.rs | 36 +++-- clippy_lints/src/operators/cmp_owned.rs | 58 +++----- clippy_lints/src/operators/manual_div_ceil.rs | 127 +++++++++------- .../src/operators/manual_is_multiple_of.rs | 4 +- clippy_lints/src/question_mark.rs | 7 +- clippy_lints/src/single_range_in_vec_init.rs | 2 +- clippy_lints/src/strings.rs | 8 +- clippy_lints/src/strlen_on_c_strings.rs | 4 +- .../src/transmute/transmuting_null.rs | 20 ++- clippy_lints/src/useless_conversion.rs | 14 +- clippy_lints/src/utils/author.rs | 1 - .../src/lint_without_lint_pass.rs | 4 +- clippy_utils/README.md | 4 +- clippy_utils/src/ast_utils/mod.rs | 4 +- clippy_utils/src/attrs.rs | 6 +- clippy_utils/src/consts.rs | 8 +- clippy_utils/src/hir_utils.rs | 4 +- clippy_utils/src/lib.rs | 29 +++- clippy_utils/src/res.rs | 4 +- clippy_utils/src/sugg.rs | 2 +- clippy_utils/src/sym.rs | 1 + rust-toolchain.toml | 2 +- rustc_tools_util/README.md | 2 +- .../clippy.toml | 3 +- .../conf_missing_enforced_import_rename.fixed | 1 + .../conf_missing_enforced_import_rename.rs | 1 + ...conf_missing_enforced_import_rename.stderr | 2 +- tests/ui/bool_assert_comparison.fixed | 13 ++ tests/ui/bool_assert_comparison.rs | 13 ++ tests/ui/bool_assert_comparison.stderr | 26 +++- tests/ui/checked_conversions.fixed | 16 +++ tests/ui/checked_conversions.rs | 16 +++ tests/ui/checked_conversions.stderr | 42 +++--- tests/ui/cmp_owned/with_suggestion.fixed | 29 ++++ tests/ui/cmp_owned/with_suggestion.rs | 29 ++++ tests/ui/cmp_owned/with_suggestion.stderr | 8 +- tests/ui/derive_ord_xor_partial_ord.rs | 14 ++ tests/ui/double_parens.fixed | 16 +++ tests/ui/double_parens.rs | 16 +++ tests/ui/for_kv_map.fixed | 17 +++ tests/ui/for_kv_map.rs | 17 +++ tests/ui/for_kv_map.stderr | 14 +- tests/ui/impl.rs | 42 +++++- tests/ui/impl.stderr | 90 ++++++++++-- tests/ui/implicit_saturating_sub.fixed | 8 ++ tests/ui/implicit_saturating_sub.rs | 8 ++ tests/ui/implicit_saturating_sub.stderr | 8 +- tests/ui/iter_kv_map.fixed | 6 + tests/ui/iter_kv_map.rs | 6 + tests/ui/iter_kv_map.stderr | 8 +- tests/ui/manual_div_ceil.fixed | 29 ++++ tests/ui/manual_div_ceil.rs | 29 ++++ tests/ui/manual_div_ceil.stderr | 20 ++- tests/ui/manual_div_ceil_with_feature.fixed | 29 ++++ tests/ui/manual_div_ceil_with_feature.rs | 29 ++++ tests/ui/manual_div_ceil_with_feature.stderr | 20 ++- tests/ui/manual_ignore_case_cmp.fixed | 20 +++ tests/ui/manual_ignore_case_cmp.rs | 20 +++ tests/ui/manual_ignore_case_cmp.stderr | 26 +++- tests/ui/manual_ilog2.fixed | 17 +++ tests/ui/manual_ilog2.rs | 17 +++ tests/ui/manual_ilog2.stderr | 14 +- tests/ui/manual_is_multiple_of.fixed | 16 +++ tests/ui/manual_is_multiple_of.rs | 16 +++ tests/ui/manual_is_multiple_of.stderr | 8 +- tests/ui/manual_ok_err.fixed | 10 ++ tests/ui/manual_ok_err.rs | 14 ++ tests/ui/manual_ok_err.stderr | 13 +- tests/ui/match_as_ref.fixed | 10 ++ tests/ui/match_as_ref.rs | 14 ++ tests/ui/match_as_ref.stderr | 23 ++- tests/ui/match_bool.fixed | 11 ++ tests/ui/match_bool.rs | 15 ++ tests/ui/match_bool.stderr | 12 +- tests/ui/mutex_atomic.fixed | 12 ++ tests/ui/mutex_atomic.rs | 12 ++ tests/ui/mutex_atomic.stderr | 10 +- tests/ui/needless_bool_assign.fixed | 19 +++ tests/ui/needless_bool_assign.rs | 23 +++ tests/ui/needless_bool_assign.stderr | 12 +- tests/ui/needless_for_each_fixable.fixed | 8 ++ tests/ui/needless_for_each_fixable.rs | 8 ++ tests/ui/needless_for_each_fixable.stderr | 19 ++- tests/ui/never_loop_iterator_reduction.rs | 9 +- tests/ui/never_loop_iterator_reduction.stderr | 2 +- tests/ui/new_without_default.fixed | 55 +++++++ tests/ui/new_without_default.rs | 36 +++++ tests/ui/new_without_default.stderr | 55 ++++++- tests/ui/question_mark.fixed | 17 ++- tests/ui/question_mark.rs | 22 ++- tests/ui/question_mark.stderr | 19 ++- .../redundant_pattern_matching_option.fixed | 13 ++ tests/ui/redundant_pattern_matching_option.rs | 13 ++ .../redundant_pattern_matching_option.stderr | 14 +- .../redundant_pattern_matching_result.fixed | 20 +++ tests/ui/redundant_pattern_matching_result.rs | 24 ++++ .../redundant_pattern_matching_result.stderr | 19 ++- .../ui/single_range_in_vec_init_unfixable.rs | 12 ++ .../single_range_in_vec_init_unfixable.stderr | 16 +++ tests/ui/str_to_string.fixed | 14 ++ tests/ui/str_to_string.rs | 14 ++ tests/ui/str_to_string.stderr | 8 +- tests/ui/string_from_utf8_as_bytes.fixed | 10 ++ tests/ui/string_from_utf8_as_bytes.rs | 10 ++ tests/ui/string_from_utf8_as_bytes.stderr | 10 +- tests/ui/transmuting_null.rs | 11 ++ tests/ui/transmuting_null.stderr | 14 +- tests/ui/unnecessary_fold.fixed | 11 ++ tests/ui/unnecessary_fold.rs | 11 ++ tests/ui/unnecessary_fold.stderr | 17 ++- tests/ui/unnecessary_to_owned.fixed | 9 ++ tests/ui/unnecessary_to_owned.rs | 9 ++ tests/ui/unnecessary_to_owned.stderr | 8 +- tests/ui/useless_conversion.fixed | 10 ++ tests/ui/useless_conversion.rs | 10 ++ tests/ui/useless_conversion.stderr | 135 ++++++++++-------- triagebot.toml | 1 - 158 files changed, 2147 insertions(+), 518 deletions(-) create mode 100644 tests/ui/single_range_in_vec_init_unfixable.rs create mode 100644 tests/ui/single_range_in_vec_init_unfixable.stderr diff --git a/COPYRIGHT b/COPYRIGHT index f402dcf465a3..d3b4c9e5fb2c 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,6 +1,6 @@ // REUSE-IgnoreStart -Copyright 2014-2025 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/Cargo.toml b/Cargo.toml index 67078adea2b4..7379dcbb7b37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ walkdir = "2.3" filetime = "0.2.9" itertools = "0.12" pulldown-cmark = { version = "0.11", default-features = false, features = ["html"] } -askama = { version = "0.14", default-features = false, features = ["alloc", "config", "derive"] } +askama = { version = "0.15", default-features = false, features = ["alloc", "config", "derive"] } [dev-dependencies.toml] version = "0.9.7" diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 9990a0cec474..773ae298cc19 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work. same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright 2014-2025 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/LICENSE-MIT b/LICENSE-MIT index 5d6e36ef6bfc..9549420685cc 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2014-2025 The Rust Project Developers +Copyright (c) The Rust Project Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/README.md b/README.md index 78498c73ae78..8bccd040c1f9 100644 --- a/README.md +++ b/README.md @@ -277,7 +277,7 @@ If you want to contribute to Clippy, you can find more information in [CONTRIBUT -Copyright 2014-2025 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/clippy_lints/src/attrs/allow_attributes.rs b/clippy_lints/src/attrs/allow_attributes.rs index 84b65d3185e3..0235b130b6c0 100644 --- a/clippy_lints/src/attrs/allow_attributes.rs +++ b/clippy_lints/src/attrs/allow_attributes.rs @@ -1,10 +1,10 @@ use super::ALLOW_ATTRIBUTES; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_from_proc_macro; +use rustc_ast::attr::AttributeExt; use rustc_ast::{AttrStyle, Attribute}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, LintContext}; -use rustc_ast::attr::AttributeExt; // Separate each crate's features. pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) { @@ -15,12 +15,7 @@ pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) { { #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] span_lint_and_then(cx, ALLOW_ATTRIBUTES, path_span, "#[allow] attribute found", |diag| { - diag.span_suggestion( - path_span, - "replace it with", - "expect", - Applicability::MachineApplicable, - ); + diag.span_suggestion(path_span, "replace it with", "expect", Applicability::MachineApplicable); }); } } diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index 366f5873a1aa..42c321df61c1 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -16,7 +16,7 @@ mod utils; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::msrvs::{self, Msrv, MsrvStack}; -use rustc_ast::{self as ast, AttrArgs, AttrKind, Attribute, MetaItemInner, MetaItemKind, AttrItemKind}; +use rustc_ast::{self as ast, AttrArgs, AttrItemKind, AttrKind, Attribute, MetaItemInner, MetaItemKind}; use rustc_hir::{ImplItem, Item, ItemKind, TraitItem}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc_session::impl_lint_pass; @@ -604,7 +604,9 @@ impl EarlyLintPass for PostExpansionEarlyAttributes { if attr.has_name(sym::ignore) && match &attr.kind { - AttrKind::Normal(normal_attr) => !matches!(normal_attr.item.args, AttrItemKind::Unparsed(AttrArgs::Eq { .. })), + AttrKind::Normal(normal_attr) => { + !matches!(normal_attr.item.args, AttrItemKind::Unparsed(AttrArgs::Eq { .. })) + }, AttrKind::DocComment(..) => true, } { diff --git a/clippy_lints/src/attrs/should_panic_without_expect.rs b/clippy_lints/src/attrs/should_panic_without_expect.rs index b854a3070bef..1a9abd88a46a 100644 --- a/clippy_lints/src/attrs/should_panic_without_expect.rs +++ b/clippy_lints/src/attrs/should_panic_without_expect.rs @@ -2,7 +2,7 @@ use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT}; use clippy_utils::diagnostics::span_lint_and_sugg; use rustc_ast::token::{Token, TokenKind}; use rustc_ast::tokenstream::TokenTree; -use rustc_ast::{AttrArgs, AttrKind, AttrItemKind}; +use rustc_ast::{AttrArgs, AttrItemKind, AttrKind}; use rustc_errors::Applicability; use rustc_lint::EarlyContext; use rustc_span::sym; diff --git a/clippy_lints/src/bool_assert_comparison.rs b/clippy_lints/src/bool_assert_comparison.rs index f31b67f470f9..165941a859f7 100644 --- a/clippy_lints/src/bool_assert_comparison.rs +++ b/clippy_lints/src/bool_assert_comparison.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::{find_assert_eq_args, root_macro_call_first_node}; +use clippy_utils::source::walk_span_to_context; use clippy_utils::sugg::Sugg; use clippy_utils::sym; use clippy_utils::ty::{implements_trait, is_copy}; @@ -130,22 +131,24 @@ impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison { let mut suggestions = vec![(name_span, non_eq_mac.to_string()), (lit_span, String::new())]; - if let Some(sugg) = Sugg::hir_opt(cx, non_lit_expr) { - let sugg = if bool_value ^ eq_macro { - !sugg.maybe_paren() - } else if ty::Bool == *non_lit_ty.kind() { - sugg - } else { - !!sugg.maybe_paren() - }; - suggestions.push((non_lit_expr.span, sugg.to_string())); + let mut applicability = Applicability::MachineApplicable; + let sugg = Sugg::hir_with_context(cx, non_lit_expr, macro_call.span.ctxt(), "..", &mut applicability); + let sugg = if bool_value ^ eq_macro { + !sugg.maybe_paren() + } else if ty::Bool == *non_lit_ty.kind() { + sugg + } else { + !!sugg.maybe_paren() + }; + let non_lit_expr_span = + walk_span_to_context(non_lit_expr.span, macro_call.span.ctxt()).unwrap_or(non_lit_expr.span); + suggestions.push((non_lit_expr_span, sugg.to_string())); - diag.multipart_suggestion( - format!("replace it with `{non_eq_mac}!(..)`"), - suggestions, - Applicability::MachineApplicable, - ); - } + diag.multipart_suggestion( + format!("replace it with `{non_eq_mac}!(..)`"), + suggestions, + applicability, + ); }, ); } diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index a04a56d72bc0..0bd459d8b021 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -15,6 +15,7 @@ use rustc_lint::{LateContext, LateLintPass, Level}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, Symbol, SyntaxContext}; +use std::fmt::Write as _; declare_clippy_lint! { /// ### What it does @@ -356,7 +357,7 @@ impl SuggestContext<'_, '_, '_> { if app != Applicability::MachineApplicable { return None; } - self.output.push_str(&(!snip).to_string()); + let _cannot_fail = write!(&mut self.output, "{}", &(!snip)); } }, True | False | Not(_) => { diff --git a/clippy_lints/src/cargo/mod.rs b/clippy_lints/src/cargo/mod.rs index 60371dcd7715..08d92adbacef 100644 --- a/clippy_lints/src/cargo/mod.rs +++ b/clippy_lints/src/cargo/mod.rs @@ -132,7 +132,7 @@ declare_clippy_lint! { /// Because this can be caused purely by the dependencies /// themselves, it's not always possible to fix this issue. /// In those cases, you can allow that specific crate using - /// the `allowed_duplicate_crates` configuration option. + /// the `allowed-duplicate-crates` configuration option. /// /// ### Example /// ```toml diff --git a/clippy_lints/src/cfg_not_test.rs b/clippy_lints/src/cfg_not_test.rs index ec543d02c9dd..88d07be0d4d4 100644 --- a/clippy_lints/src/cfg_not_test.rs +++ b/clippy_lints/src/cfg_not_test.rs @@ -1,10 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_then; +use rustc_ast::attr::data_structures::CfgEntry; +use rustc_ast::{AttrItemKind, EarlyParsedAttribute}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; -use rustc_ast::AttrItemKind; -use rustc_ast::EarlyParsedAttribute; use rustc_span::sym; -use rustc_ast::attr::data_structures::CfgEntry; declare_clippy_lint! { /// ### What it does @@ -40,7 +39,7 @@ impl EarlyLintPass for CfgNotTest { unreachable!() }; - if contains_not_test(&cfg, false) { + if contains_not_test(cfg, false) { span_lint_and_then( cx, CFG_NOT_TEST, @@ -58,11 +57,9 @@ impl EarlyLintPass for CfgNotTest { fn contains_not_test(cfg: &CfgEntry, not: bool) -> bool { match cfg { - CfgEntry::All(subs, _) | CfgEntry::Any(subs, _) => subs.iter().any(|item| { - contains_not_test(item, not) - }), + CfgEntry::All(subs, _) | CfgEntry::Any(subs, _) => subs.iter().any(|item| contains_not_test(item, not)), CfgEntry::Not(sub, _) => contains_not_test(sub, !not), CfgEntry::NameValue { name: sym::test, .. } => not, - _ => false + _ => false, } } diff --git a/clippy_lints/src/checked_conversions.rs b/clippy_lints/src/checked_conversions.rs index 9b3822f9d8f0..8303897d1294 100644 --- a/clippy_lints/src/checked_conversions.rs +++ b/clippy_lints/src/checked_conversions.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal, sym}; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, TyKind}; @@ -80,7 +80,8 @@ impl LateLintPass<'_> for CheckedConversions { && self.msrv.meets(cx, msrvs::TRY_FROM) { let mut applicability = Applicability::MachineApplicable; - let snippet = snippet_with_applicability(cx, cv.expr_to_cast.span, "_", &mut applicability); + let (snippet, _) = + snippet_with_context(cx, cv.expr_to_cast.span, item.span.ctxt(), "_", &mut applicability); span_lint_and_sugg( cx, CHECKED_CONVERSIONS, diff --git a/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs b/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs index 2bd5e2cbfb1a..316d800a70c9 100644 --- a/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs +++ b/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs @@ -1,15 +1,16 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; +use clippy_utils::fulfill_or_allowed; use rustc_hir::{self as hir, HirId}; use rustc_lint::LateContext; use rustc_middle::ty::Ty; -use rustc_span::{Span, sym}; +use rustc_span::sym; use super::DERIVE_ORD_XOR_PARTIAL_ORD; /// Implementation of the `DERIVE_ORD_XOR_PARTIAL_ORD` lint. pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, - span: Span, + item: &hir::Item<'_>, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>, adt_hir_id: HirId, @@ -19,6 +20,8 @@ pub(super) fn check<'tcx>( && let Some(partial_ord_trait_def_id) = cx.tcx.lang_items().partial_ord_trait() && let Some(def_id) = &trait_ref.trait_def_id() && *def_id == ord_trait_def_id + && let item_hir_id = cx.tcx.local_def_id_to_hir_id(item.owner_id) + && !fulfill_or_allowed(cx, DERIVE_ORD_XOR_PARTIAL_ORD, [adt_hir_id]) { // Look for the PartialOrd implementations for `ty` cx.tcx.for_each_relevant_impl(partial_ord_trait_def_id, ty, |impl_id| { @@ -39,7 +42,7 @@ pub(super) fn check<'tcx>( "you are deriving `Ord` but have implemented `PartialOrd` explicitly" }; - span_lint_hir_and_then(cx, DERIVE_ORD_XOR_PARTIAL_ORD, adt_hir_id, span, mess, |diag| { + span_lint_hir_and_then(cx, DERIVE_ORD_XOR_PARTIAL_ORD, item_hir_id, item.span, mess, |diag| { if let Some(local_def_id) = impl_id.as_local() { let hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id); diag.span_note(cx.tcx.hir_span(hir_id), "`PartialOrd` implemented here"); diff --git a/clippy_lints/src/derive/mod.rs b/clippy_lints/src/derive/mod.rs index eafe7c4bb9f2..86614201c406 100644 --- a/clippy_lints/src/derive/mod.rs +++ b/clippy_lints/src/derive/mod.rs @@ -208,7 +208,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive { let is_automatically_derived = cx.tcx.is_automatically_derived(item.owner_id.to_def_id()); derived_hash_with_manual_eq::check(cx, item.span, trait_ref, ty, adt_hir_id, is_automatically_derived); - derive_ord_xor_partial_ord::check(cx, item.span, trait_ref, ty, adt_hir_id, is_automatically_derived); + derive_ord_xor_partial_ord::check(cx, item, trait_ref, ty, adt_hir_id, is_automatically_derived); if is_automatically_derived { unsafe_derive_deserialize::check(cx, item, trait_ref, ty, adt_hir_id); diff --git a/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/clippy_lints/src/doc/include_in_doc_without_cfg.rs index f8e9e870f629..6c800f47b68a 100644 --- a/clippy_lints/src/doc/include_in_doc_without_cfg.rs +++ b/clippy_lints/src/doc/include_in_doc_without_cfg.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_opt; -use rustc_ast::{AttrArgs, AttrKind, AttrStyle, Attribute, AttrItemKind}; +use rustc_ast::{AttrArgs, AttrItemKind, AttrKind, AttrStyle, Attribute}; use rustc_errors::Applicability; use rustc_lint::EarlyContext; diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index b11b2f8392c1..2b41275ee3a4 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -869,10 +869,12 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ }), true, ); - let mut doc = fragments.iter().fold(String::new(), |mut acc, fragment| { - add_doc_fragment(&mut acc, fragment); - acc - }); + + let mut doc = String::with_capacity(fragments.iter().map(|frag| frag.doc.as_str().len() + 1).sum()); + + for fragment in &fragments { + add_doc_fragment(&mut doc, fragment); + } doc.pop(); if doc.trim().is_empty() { diff --git a/clippy_lints/src/double_parens.rs b/clippy_lints/src/double_parens.rs index 8defbeeaa5f2..351d29d87432 100644 --- a/clippy_lints/src/double_parens.rs +++ b/clippy_lints/src/double_parens.rs @@ -114,6 +114,8 @@ fn check_source(cx: &EarlyContext<'_>, inner: &Expr) -> bool { && inner.starts_with('(') && inner.ends_with(')') && outer_after_inner.trim_start().starts_with(')') + // Don't lint macro repetition patterns like `($($result),*)` where parens are necessary + && !inner.trim_start_matches('(').trim_start().starts_with("$(") { true } else { diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs index 7b6f8729cb75..516f9e3aa60c 100644 --- a/clippy_lints/src/implicit_saturating_sub.rs +++ b/clippy_lints/src/implicit_saturating_sub.rs @@ -1,9 +1,13 @@ +use std::borrow::Cow; + use clippy_config::Conf; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::{Sugg, make_binop}; use clippy_utils::{ - SpanlessEq, eq_expr_value, higher, is_in_const_context, is_integer_literal, peel_blocks, peel_blocks_with_stmt, sym, + SpanlessEq, eq_expr_value, higher, is_in_const_context, is_integer_literal, is_integer_literal_untyped, + peel_blocks, peel_blocks_with_stmt, sym, }; use rustc_ast::ast::LitKind; use rustc_data_structures::packed::Pu128; @@ -238,10 +242,21 @@ fn check_subtraction( if eq_expr_value(cx, left, big_expr) && eq_expr_value(cx, right, little_expr) { // This part of the condition is voluntarily split from the one before to ensure that // if `snippet_opt` fails, it won't try the next conditions. - if (!is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST)) - && let Some(big_expr_sugg) = Sugg::hir_opt(cx, big_expr).map(Sugg::maybe_paren) - && let Some(little_expr_sugg) = Sugg::hir_opt(cx, little_expr) - { + if !is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST) { + let mut applicability = Applicability::MachineApplicable; + let big_expr_sugg = (if is_integer_literal_untyped(big_expr) { + let get_snippet = |span: Span| { + let snippet = snippet_with_applicability(cx, span, "..", &mut applicability); + let big_expr_ty = cx.typeck_results().expr_ty(big_expr); + Cow::Owned(format!("{snippet}_{big_expr_ty}")) + }; + Sugg::hir_from_snippet(cx, big_expr, get_snippet) + } else { + Sugg::hir_with_applicability(cx, big_expr, "..", &mut applicability) + }) + .maybe_paren(); + let little_expr_sugg = Sugg::hir_with_applicability(cx, little_expr, "..", &mut applicability); + let sugg = format!( "{}{big_expr_sugg}.saturating_sub({little_expr_sugg}){}", if is_composited { "{ " } else { "" }, @@ -254,7 +269,7 @@ fn check_subtraction( "manual arithmetic check found", "replace it with", sugg, - Applicability::MachineApplicable, + applicability, ); } } else if eq_expr_value(cx, left, little_expr) diff --git a/clippy_lints/src/incompatible_msrv.rs b/clippy_lints/src/incompatible_msrv.rs index e0149a23fccf..8d538ff1acba 100644 --- a/clippy_lints/src/incompatible_msrv.rs +++ b/clippy_lints/src/incompatible_msrv.rs @@ -3,14 +3,13 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::Msrv; use clippy_utils::{is_in_const_context, is_in_test, sym}; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, HirId, RustcVersion, StabilityLevel, StableSince}; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, HirId, RustcVersion, StabilityLevel, StableSince, find_attr}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::{ExpnKind, Span}; -use rustc_hir::attrs::AttributeKind; -use rustc_hir::find_attr; declare_clippy_lint! { /// ### What it does @@ -270,6 +269,9 @@ impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv { /// attribute. fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool { cx.tcx.hir_parent_id_iter(hir_id).any(|id| { - find_attr!(cx.tcx.hir_attrs(id), AttributeKind::CfgTrace(..) | AttributeKind::CfgAttrTrace) + find_attr!( + cx.tcx.hir_attrs(id), + AttributeKind::CfgTrace(..) | AttributeKind::CfgAttrTrace + ) }) } diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs index f59c7615d745..14928a1be13b 100644 --- a/clippy_lints/src/inherent_impl.rs +++ b/clippy_lints/src/inherent_impl.rs @@ -101,7 +101,21 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { InherentImplLintScope::Crate => Criterion::Crate, }; let is_test = is_cfg_test(cx.tcx, hir_id) || is_in_cfg_test(cx.tcx, hir_id); - match type_map.entry((impl_ty, criterion, is_test)) { + let predicates = { + // Gets the predicates (bounds) for the given impl block, + // sorted for consistent comparison to allow distinguishing between impl blocks + // with different generic bounds. + let mut predicates = cx + .tcx + .predicates_of(impl_id) + .predicates + .iter() + .map(|(clause, _)| *clause) + .collect::>(); + predicates.sort_by_key(|c| format!("{c:?}")); + predicates + }; + match type_map.entry((impl_ty, predicates, criterion, is_test)) { Entry::Vacant(e) => { // Store the id for the first impl block of this type. The span is retrieved lazily. e.insert(IdOrSpan::Id(impl_id)); @@ -152,15 +166,12 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { fn get_impl_span(cx: &LateContext<'_>, id: LocalDefId) -> Option { let id = cx.tcx.local_def_id_to_hir_id(id); if let Node::Item(&Item { - kind: ItemKind::Impl(impl_item), + kind: ItemKind::Impl(_), span, .. }) = cx.tcx.hir_node(id) { - (!span.from_expansion() - && impl_item.generics.params.is_empty() - && !fulfill_or_allowed(cx, MULTIPLE_INHERENT_IMPL, [id])) - .then_some(span) + (!span.from_expansion() && !fulfill_or_allowed(cx, MULTIPLE_INHERENT_IMPL, [id])).then_some(span) } else { None } diff --git a/clippy_lints/src/large_include_file.rs b/clippy_lints/src/large_include_file.rs index 5c37747b8c9b..d77e0beeaf4c 100644 --- a/clippy_lints/src/large_include_file.rs +++ b/clippy_lints/src/large_include_file.rs @@ -3,7 +3,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::snippet_opt; -use rustc_ast::{AttrArgs, AttrKind, Attribute, LitKind}; +use rustc_ast::{AttrArgs, AttrItemKind, AttrKind, Attribute, LitKind}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc_session::impl_lint_pass; diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index 261b03abba17..32c23a2d0362 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -94,6 +94,15 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { }) && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size) { + // libtest might generate a large array containing the test cases, and no span will be associated + // to it. In this case it is better not to complain. + // + // Note that this condition is not checked explicitly by a unit test. Do not remove it without + // ensuring that stays fixed. + if expr.span.is_dummy() { + return; + } + span_lint_and_then( cx, LARGE_STACK_ARRAYS, diff --git a/clippy_lints/src/loops/for_kv_map.rs b/clippy_lints/src/loops/for_kv_map.rs index 39b2391c98ec..7fb8e51377a2 100644 --- a/clippy_lints/src/loops/for_kv_map.rs +++ b/clippy_lints/src/loops/for_kv_map.rs @@ -1,16 +1,22 @@ use super::FOR_KV_MAP; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeDef; -use clippy_utils::source::snippet; +use clippy_utils::source::{snippet_with_applicability, walk_span_to_context}; use clippy_utils::{pat_is_wild, sugg}; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::sym; +use rustc_span::{Span, sym}; /// Checks for the `FOR_KV_MAP` lint. -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>) { +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + pat: &'tcx Pat<'_>, + arg: &'tcx Expr<'_>, + body: &'tcx Expr<'_>, + span: Span, +) { let pat_span = pat.span; if let PatKind::Tuple(pat, _) = pat.kind @@ -34,21 +40,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx _ => arg, }; - if matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) { + if matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) + && let Some(arg_span) = walk_span_to_context(arg_span, span.ctxt()) + { span_lint_and_then( cx, FOR_KV_MAP, arg_span, format!("you seem to want to iterate on a map's {kind}s"), |diag| { - let map = sugg::Sugg::hir(cx, arg, "map"); + let mut applicability = Applicability::MachineApplicable; + let map = sugg::Sugg::hir_with_context(cx, arg, span.ctxt(), "map", &mut applicability); + let pat = snippet_with_applicability(cx, new_pat_span, kind, &mut applicability); diag.multipart_suggestion( "use the corresponding method", vec![ - (pat_span, snippet(cx, new_pat_span, kind).into_owned()), + (pat_span, pat.to_string()), (arg_span, format!("{}.{kind}s{mutbl}()", map.maybe_paren())), ], - Applicability::MachineApplicable, + applicability, ); }, ); diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index ddc783069385..83574cab6b67 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -943,7 +943,7 @@ impl Loops { explicit_counter_loop::check(cx, pat, arg, body, expr, label); } self.check_for_loop_arg(cx, pat, arg); - for_kv_map::check(cx, pat, arg, body); + for_kv_map::check(cx, pat, arg, body, span); mut_range_bound::check(cx, arg, body); single_element_loop::check(cx, pat, arg, body, expr); same_item_push::check(cx, pat, arg, body, expr, self.msrv); diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index a037af3433c3..e7b9b1cd3881 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -4,8 +4,8 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::ForLoop; use clippy_utils::macros::root_macro_call_first_node; use clippy_utils::source::{snippet, snippet_with_context}; -use clippy_utils::sym; use clippy_utils::visitors::{Descend, for_each_expr_without_closures}; +use clippy_utils::{contains_return, sym}; use rustc_errors::Applicability; use rustc_hir::{ Block, Closure, Destination, Expr, ExprKind, HirId, InlineAsm, InlineAsmOperand, Node, Pat, Stmt, StmtKind, @@ -82,7 +82,7 @@ pub(super) fn check_iterator_reduction<'tcx>( ) { let closure_body = cx.tcx.hir_body(closure.body).value; let body_ty = cx.typeck_results().expr_ty(closure_body); - if body_ty.is_never() { + if body_ty.is_never() && !contains_return(closure_body) { span_lint_and_then( cx, NEVER_LOOP, diff --git a/clippy_lints/src/manual_ignore_case_cmp.rs b/clippy_lints/src/manual_ignore_case_cmp.rs index 25057b4aeaa2..1c20a8f81efb 100644 --- a/clippy_lints/src/manual_ignore_case_cmp.rs +++ b/clippy_lints/src/manual_ignore_case_cmp.rs @@ -1,7 +1,7 @@ use crate::manual_ignore_case_cmp::MatchType::{Literal, ToAscii}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeDef; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sym; use rustc_ast::LitKind; use rustc_errors::Applicability; @@ -111,14 +111,12 @@ impl LateLintPass<'_> for ManualIgnoreCaseCmp { "manual case-insensitive ASCII comparison", |diag| { let mut app = Applicability::MachineApplicable; + let (left_snip, _) = snippet_with_context(cx, left_span, expr.span.ctxt(), "..", &mut app); + let (right_snip, _) = snippet_with_context(cx, right_span, expr.span.ctxt(), "..", &mut app); diag.span_suggestion_verbose( expr.span, "consider using `.eq_ignore_ascii_case()` instead", - format!( - "{neg}{}.eq_ignore_ascii_case({deref}{})", - snippet_with_applicability(cx, left_span, "_", &mut app), - snippet_with_applicability(cx, right_span, "_", &mut app) - ), + format!("{neg}{left_snip}.eq_ignore_ascii_case({deref}{right_snip})"), app, ); }, diff --git a/clippy_lints/src/manual_ilog2.rs b/clippy_lints/src/manual_ilog2.rs index 1c61db530606..4b411a60f3bf 100644 --- a/clippy_lints/src/manual_ilog2.rs +++ b/clippy_lints/src/manual_ilog2.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::{is_from_proc_macro, sym}; use rustc_ast::LitKind; use rustc_data_structures::packed::Pu128; @@ -102,7 +102,7 @@ impl LateLintPass<'_> for ManualIlog2 { fn emit(cx: &LateContext<'_>, recv: &Expr<'_>, full_expr: &Expr<'_>) { let mut app = Applicability::MachineApplicable; - let recv = snippet_with_applicability(cx, recv.span, "_", &mut app); + let (recv, _) = snippet_with_context(cx, recv.span, full_expr.span.ctxt(), "_", &mut app); span_lint_and_sugg( cx, MANUAL_ILOG2, diff --git a/clippy_lints/src/matches/manual_ok_err.rs b/clippy_lints/src/matches/manual_ok_err.rs index c35c3d1f62e6..1fc8bb9acce2 100644 --- a/clippy_lints/src/matches/manual_ok_err.rs +++ b/clippy_lints/src/matches/manual_ok_err.rs @@ -135,7 +135,7 @@ fn apply_lint(cx: &LateContext<'_>, expr: &Expr<'_>, scrutinee: &Expr<'_>, is_ok } else { Applicability::MachineApplicable }; - let scrut = Sugg::hir_with_applicability(cx, scrutinee, "..", &mut app).maybe_paren(); + let scrut = Sugg::hir_with_context(cx, scrutinee, expr.span.ctxt(), "..", &mut app).maybe_paren(); let scrutinee_ty = cx.typeck_results().expr_ty(scrutinee); let (_, _, mutability) = peel_and_count_ty_refs(scrutinee_ty); diff --git a/clippy_lints/src/matches/match_as_ref.rs b/clippy_lints/src/matches/match_as_ref.rs index 795355f25f9e..12fe44ef2f13 100644 --- a/clippy_lints/src/matches/match_as_ref.rs +++ b/clippy_lints/src/matches/match_as_ref.rs @@ -46,6 +46,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: let cast = if input_ty == output_ty { "" } else { ".map(|x| x as _)" }; let mut applicability = Applicability::MachineApplicable; + let ctxt = expr.span.ctxt(); span_lint_and_then( cx, MATCH_AS_REF, @@ -59,7 +60,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: "use `Option::as_ref()`", format!( "{}.as_ref(){cast}", - Sugg::hir_with_applicability(cx, ex, "_", &mut applicability).maybe_paren(), + Sugg::hir_with_context(cx, ex, ctxt, "_", &mut applicability).maybe_paren(), ), applicability, ); @@ -69,7 +70,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: format!("use `Option::{method}()` directly"), format!( "{}.{method}(){cast}", - Sugg::hir_with_applicability(cx, ex, "_", &mut applicability).maybe_paren(), + Sugg::hir_with_context(cx, ex, ctxt, "_", &mut applicability).maybe_paren(), ), applicability, ); diff --git a/clippy_lints/src/matches/match_bool.rs b/clippy_lints/src/matches/match_bool.rs index a2c8741f4f74..3e76231b6ef1 100644 --- a/clippy_lints/src/matches/match_bool.rs +++ b/clippy_lints/src/matches/match_bool.rs @@ -16,6 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>] && arms .iter() .all(|arm| arm.pat.walk_short(|p| !matches!(p.kind, PatKind::Binding(..)))) + && arms.len() == 2 { span_lint_and_then( cx, @@ -23,59 +24,58 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>] expr.span, "`match` on a boolean expression", move |diag| { - if arms.len() == 2 { - let mut app = Applicability::MachineApplicable; - let test_sugg = if let PatKind::Expr(arm_bool) = arms[0].pat.kind { - let test = Sugg::hir_with_applicability(cx, scrutinee, "_", &mut app); - if let PatExprKind::Lit { lit, .. } = arm_bool.kind { - match &lit.node { - LitKind::Bool(true) => Some(test), - LitKind::Bool(false) => Some(!test), - _ => None, - } - .map(|test| { - if let Some(guard) = &arms[0] - .guard - .map(|g| Sugg::hir_with_applicability(cx, g, "_", &mut app)) - { - test.and(guard) - } else { - test - } - }) - } else { - None + let mut app = Applicability::MachineApplicable; + let ctxt = expr.span.ctxt(); + let test_sugg = if let PatKind::Expr(arm_bool) = arms[0].pat.kind { + let test = Sugg::hir_with_context(cx, scrutinee, ctxt, "_", &mut app); + if let PatExprKind::Lit { lit, .. } = arm_bool.kind { + match &lit.node { + LitKind::Bool(true) => Some(test), + LitKind::Bool(false) => Some(!test), + _ => None, } + .map(|test| { + if let Some(guard) = &arms[0] + .guard + .map(|g| Sugg::hir_with_context(cx, g, ctxt, "_", &mut app)) + { + test.and(guard) + } else { + test + } + }) } else { None + } + } else { + None + }; + + if let Some(test_sugg) = test_sugg { + let ctxt = expr.span.ctxt(); + let (true_expr, false_expr) = (arms[0].body, arms[1].body); + let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) { + (false, false) => Some(format!( + "if {} {} else {}", + test_sugg, + expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app), + expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) + )), + (false, true) => Some(format!( + "if {} {}", + test_sugg, + expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app) + )), + (true, false) => Some(format!( + "if {} {}", + !test_sugg, + expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) + )), + (true, true) => None, }; - if let Some(test_sugg) = test_sugg { - let ctxt = expr.span.ctxt(); - let (true_expr, false_expr) = (arms[0].body, arms[1].body); - let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) { - (false, false) => Some(format!( - "if {} {} else {}", - test_sugg, - expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app), - expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) - )), - (false, true) => Some(format!( - "if {} {}", - test_sugg, - expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app) - )), - (true, false) => Some(format!( - "if {} {}", - !test_sugg, - expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) - )), - (true, true) => None, - }; - - if let Some(sugg) = sugg { - diag.span_suggestion(expr.span, "consider using an `if`/`else` expression", sugg, app); - } + if let Some(sugg) = sugg { + diag.span_suggestion(expr.span, "consider using an `if`/`else` expression", sugg, app); } } }, diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index bc3783750e5c..bf0c0c4aec3c 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -1,7 +1,6 @@ use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; -use clippy_utils::source::walk_span_to_context; use clippy_utils::sugg::{Sugg, make_unop}; use clippy_utils::ty::needs_ordered_drop; use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr_without_closures}; @@ -25,7 +24,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { .. }) = higher::WhileLet::hir(expr) { - find_method_sugg_for_if_let(cx, expr, let_pat, let_expr, "while", false); + find_method_sugg_for_if_let(cx, expr, let_pat, let_expr, "while", false, let_span); find_if_let_true(cx, let_pat, let_expr, let_span); } } @@ -39,7 +38,7 @@ pub(super) fn check_if_let<'tcx>( let_span: Span, ) { find_if_let_true(cx, pat, scrutinee, let_span); - find_method_sugg_for_if_let(cx, expr, pat, scrutinee, "if", has_else); + find_method_sugg_for_if_let(cx, expr, pat, scrutinee, "if", has_else, let_span); } /// Looks for: @@ -182,6 +181,7 @@ fn find_method_sugg_for_if_let<'tcx>( let_expr: &'tcx Expr<'_>, keyword: &'static str, has_else: bool, + let_span: Span, ) { // also look inside refs // if we have &None for example, peel it so we can detect "if let None = x" @@ -239,15 +239,9 @@ fn find_method_sugg_for_if_let<'tcx>( let expr_span = expr.span; let ctxt = expr.span.ctxt(); - // if/while let ... = ... { ... } - // ^^^ - let Some(res_span) = walk_span_to_context(result_expr.span.source_callsite(), ctxt) else { - return; - }; - // if/while let ... = ... { ... } // ^^^^^^^^^^^^^^^^^^^^^^ - let span = expr_span.until(res_span.shrink_to_hi()); + let span = expr_span.until(let_span.shrink_to_hi()); let mut app = if needs_drop { Applicability::MaybeIncorrect @@ -273,13 +267,14 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op if let Ok(arms) = arms.try_into() // TODO: use `slice::as_array` once stabilized && let Some((good_method, maybe_guard)) = found_good_method(cx, arms) { - let span = is_expn_of(expr.span, sym::matches).unwrap_or(expr.span.to(op.span)); + let expr_span = is_expn_of(expr.span, sym::matches).unwrap_or(expr.span); + let result_expr = match &op.kind { ExprKind::AddrOf(_, _, borrowed) => borrowed, _ => op, }; let mut app = Applicability::MachineApplicable; - let receiver_sugg = Sugg::hir_with_applicability(cx, result_expr, "_", &mut app).maybe_paren(); + let receiver_sugg = Sugg::hir_with_context(cx, result_expr, expr_span.ctxt(), "_", &mut app).maybe_paren(); let mut sugg = format!("{receiver_sugg}.{good_method}"); if let Some(guard) = maybe_guard { @@ -302,14 +297,14 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op return; } - let guard = Sugg::hir(cx, guard, ".."); + let guard = Sugg::hir_with_context(cx, guard, expr_span.ctxt(), "..", &mut app); let _ = write!(sugg, " && {}", guard.maybe_paren()); } span_lint_and_sugg( cx, REDUNDANT_PATTERN_MATCHING, - span, + expr_span, format!("redundant pattern matching, consider using `{good_method}`"), "try", sugg, diff --git a/clippy_lints/src/methods/is_empty.rs b/clippy_lints/src/methods/is_empty.rs index 834456ff6668..8135c67d0d78 100644 --- a/clippy_lints/src/methods/is_empty.rs +++ b/clippy_lints/src/methods/is_empty.rs @@ -3,10 +3,9 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::macros::{is_assert_macro, root_macro_call}; use clippy_utils::res::MaybeResPath; use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context}; -use rustc_hir::{Expr, HirId}; -use rustc_lint::{LateContext, LintContext}; use rustc_hir::attrs::AttributeKind; -use rustc_hir::find_attr; +use rustc_hir::{Expr, HirId, find_attr}; +use rustc_lint::{LateContext, LintContext}; use super::CONST_IS_EMPTY; diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index 16db8663941e..366bfaed73d4 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -2,7 +2,7 @@ use super::ITER_KV_MAP; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeDef; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::{pat_is_wild, sym}; use rustc_hir::{Body, Expr, ExprKind, PatKind}; use rustc_lint::LateContext; @@ -58,6 +58,8 @@ pub(super) fn check<'tcx>( applicability, ); } else { + let (body_snippet, _) = + snippet_with_context(cx, body_expr.span, expr.span.ctxt(), "..", &mut applicability); span_lint_and_sugg( cx, ITER_KV_MAP, @@ -65,9 +67,8 @@ pub(super) fn check<'tcx>( format!("iterating on a map's {replacement_kind}s"), "try", format!( - "{recv_snippet}.{into_prefix}{replacement_kind}s().map(|{}{bound_ident}| {})", + "{recv_snippet}.{into_prefix}{replacement_kind}s().map(|{}{bound_ident}| {body_snippet})", annotation.prefix_str(), - snippet_with_applicability(cx, body_expr.span, "/* body */", &mut applicability) ), applicability, ); diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index 9dae6fbb48dd..c3f031edff2e 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -1,10 +1,10 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath, MaybeTypeckRes}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_blocks, strip_pat_refs}; use rustc_ast::ast; use rustc_data_structures::packed::Pu128; -use rustc_errors::Applicability; +use rustc_errors::{Applicability, Diag}; use rustc_hir as hir; use rustc_hir::PatKind; use rustc_hir::def::{DefKind, Res}; @@ -59,6 +59,34 @@ struct Replacement { method_name: &'static str, has_args: bool, has_generic_return: bool, + is_short_circuiting: bool, +} + +impl Replacement { + fn default_applicability(&self) -> Applicability { + if self.is_short_circuiting { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable + } + } + + fn maybe_add_note(&self, diag: &mut Diag<'_, ()>) { + if self.is_short_circuiting { + diag.note(format!( + "the `{}` method is short circuiting and may change the program semantics if the iterator has side effects", + self.method_name + )); + } + } + + fn maybe_turbofish(&self, ty: Ty<'_>) -> String { + if self.has_generic_return { + format!("::<{ty}>") + } else { + String::new() + } + } } fn check_fold_with_op( @@ -86,32 +114,30 @@ fn check_fold_with_op( && left_expr.res_local_id() == Some(first_arg_id) && (replacement.has_args || right_expr.res_local_id() == Some(second_arg_id)) { - let mut applicability = Applicability::MachineApplicable; - - let turbofish = if replacement.has_generic_return { - format!("::<{}>", cx.typeck_results().expr_ty_adjusted(right_expr).peel_refs()) - } else { - String::new() - }; - - let sugg = if replacement.has_args { - format!( - "{method}{turbofish}(|{second_arg_ident}| {r})", - method = replacement.method_name, - r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), - ) - } else { - format!("{method}{turbofish}()", method = replacement.method_name) - }; - - span_lint_and_sugg( + let span = fold_span.with_hi(expr.span.hi()); + span_lint_and_then( cx, UNNECESSARY_FOLD, - fold_span.with_hi(expr.span.hi()), + span, "this `.fold` can be written more succinctly using another method", - "try", - sugg, - applicability, + |diag| { + let mut applicability = replacement.default_applicability(); + let turbofish = + replacement.maybe_turbofish(cx.typeck_results().expr_ty_adjusted(right_expr).peel_refs()); + let (r_snippet, _) = + snippet_with_context(cx, right_expr.span, expr.span.ctxt(), "EXPR", &mut applicability); + let sugg = if replacement.has_args { + format!( + "{method}{turbofish}(|{second_arg_ident}| {r_snippet})", + method = replacement.method_name, + ) + } else { + format!("{method}{turbofish}()", method = replacement.method_name) + }; + + diag.span_suggestion(span, "try", sugg, applicability); + replacement.maybe_add_note(diag); + }, ); return true; } @@ -131,22 +157,25 @@ fn check_fold_with_method( // Check if the function belongs to the operator && cx.tcx.is_diagnostic_item(method, fn_did) { - let applicability = Applicability::MachineApplicable; - - let turbofish = if replacement.has_generic_return { - format!("::<{}>", cx.typeck_results().expr_ty(expr)) - } else { - String::new() - }; - - span_lint_and_sugg( + let span = fold_span.with_hi(expr.span.hi()); + span_lint_and_then( cx, UNNECESSARY_FOLD, - fold_span.with_hi(expr.span.hi()), + span, "this `.fold` can be written more succinctly using another method", - "try", - format!("{method}{turbofish}()", method = replacement.method_name), - applicability, + |diag| { + diag.span_suggestion( + span, + "try", + format!( + "{method}{turbofish}()", + method = replacement.method_name, + turbofish = replacement.maybe_turbofish(cx.typeck_results().expr_ty(expr)) + ), + replacement.default_applicability(), + ); + replacement.maybe_add_note(diag); + }, ); } } @@ -171,6 +200,7 @@ pub(super) fn check<'tcx>( method_name: "any", has_args: true, has_generic_return: false, + is_short_circuiting: true, }; check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Or, replacement); }, @@ -179,6 +209,7 @@ pub(super) fn check<'tcx>( method_name: "all", has_args: true, has_generic_return: false, + is_short_circuiting: true, }; check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, replacement); }, @@ -187,6 +218,7 @@ pub(super) fn check<'tcx>( method_name: "sum", has_args: false, has_generic_return: needs_turbofish(cx, expr), + is_short_circuiting: false, }; if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Add, replacement) { check_fold_with_method(cx, expr, acc, fold_span, sym::add, replacement); @@ -197,6 +229,7 @@ pub(super) fn check<'tcx>( method_name: "product", has_args: false, has_generic_return: needs_turbofish(cx, expr), + is_short_circuiting: false, }; if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, replacement) { check_fold_with_method(cx, expr, acc, fold_span, sym::mul, replacement); diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index a6a39cb6ab30..74e8dbc15a6c 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -3,7 +3,7 @@ use super::unnecessary_iter_cloned::{self, is_into_iter}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeDef; -use clippy_utils::source::{SpanRangeExt, snippet}; +use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_context}; use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, peel_and_count_ty_refs}; use clippy_utils::visitors::find_all_ret_expressions; use clippy_utils::{fn_def_id, get_parent_expr, is_expr_temporary_value, return_ty, sym}; @@ -131,8 +131,10 @@ fn check_addr_of_expr( && (*referent_ty != receiver_ty || (matches!(referent_ty.kind(), ty::Array(..)) && is_copy(cx, *referent_ty)) || is_cow_into_owned(cx, method_name, method_parent_id)) - && let Some(receiver_snippet) = receiver.span.get_source_text(cx) { + let mut applicability = Applicability::MachineApplicable; + let (receiver_snippet, _) = snippet_with_context(cx, receiver.span, expr.span.ctxt(), "..", &mut applicability); + if receiver_ty == target_ty && n_target_refs >= n_receiver_refs { span_lint_and_sugg( cx, @@ -145,7 +147,7 @@ fn check_addr_of_expr( "", width = n_target_refs - n_receiver_refs ), - Applicability::MachineApplicable, + applicability, ); return true; } @@ -165,8 +167,8 @@ fn check_addr_of_expr( parent.span, format!("unnecessary use of `{method_name}`"), "use", - receiver_snippet.to_owned(), - Applicability::MachineApplicable, + receiver_snippet.to_string(), + applicability, ); } else { span_lint_and_sugg( @@ -176,7 +178,7 @@ fn check_addr_of_expr( format!("unnecessary use of `{method_name}`"), "remove this", String::new(), - Applicability::MachineApplicable, + applicability, ); } return true; @@ -191,7 +193,7 @@ fn check_addr_of_expr( format!("unnecessary use of `{method_name}`"), "use", format!("{receiver_snippet}.as_ref()"), - Applicability::MachineApplicable, + applicability, ); return true; } @@ -409,8 +411,10 @@ fn check_other_call_arg<'tcx>( None } && can_change_type(cx, maybe_arg, receiver_ty) - && let Some(receiver_snippet) = receiver.span.get_source_text(cx) { + let mut applicability = Applicability::MachineApplicable; + let (receiver_snippet, _) = snippet_with_context(cx, receiver.span, expr.span.ctxt(), "..", &mut applicability); + span_lint_and_sugg( cx, UNNECESSARY_TO_OWNED, @@ -418,7 +422,7 @@ fn check_other_call_arg<'tcx>( format!("unnecessary use of `{method_name}`"), "use", format!("{:&>n_refs$}{receiver_snippet}", ""), - Applicability::MachineApplicable, + applicability, ); return true; } diff --git a/clippy_lints/src/missing_enforced_import_rename.rs b/clippy_lints/src/missing_enforced_import_rename.rs index eeea6dfd5f4b..5dd38cf059c2 100644 --- a/clippy_lints/src/missing_enforced_import_rename.rs +++ b/clippy_lints/src/missing_enforced_import_rename.rs @@ -82,7 +82,8 @@ impl LateLintPass<'_> for ImportRename { && let Some(import) = match snip.split_once(" as ") { None => Some(snip.as_str()), Some((import, rename)) => { - if rename.trim() == name.as_str() { + let trimmed_rename = rename.trim(); + if trimmed_rename == "_" || trimmed_rename == name.as_str() { None } else { Some(import.trim()) diff --git a/clippy_lints/src/multiple_bound_locations.rs b/clippy_lints/src/multiple_bound_locations.rs index 741f38f97560..5b6b4f112455 100644 --- a/clippy_lints/src/multiple_bound_locations.rs +++ b/clippy_lints/src/multiple_bound_locations.rs @@ -31,7 +31,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.78.0"] pub MULTIPLE_BOUND_LOCATIONS, - suspicious, + style, "defining generic bounds in multiple locations" } diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index 2fef8404f824..ad44d65b4d66 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -143,7 +143,7 @@ fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, ty_ascription: &T && new.ident.name == sym::new { let mut applicability = Applicability::MaybeIncorrect; - let arg = Sugg::hir_with_applicability(cx, arg, "_", &mut applicability); + let arg = Sugg::hir_with_context(cx, arg, expr.span.ctxt(), "_", &mut applicability); let mut suggs = vec![(expr.span, format!("std::sync::atomic::{atomic_name}::new({arg})"))]; match ty_ascription { TypeAscriptionKind::Required(ty_ascription) => { diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 854e927aa2f7..6b5db9dcf3e2 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::{ SpanlessEq, get_parent_expr, higher, is_block_like, is_else_clause, is_parent_stmt, is_receiver_of_method_call, @@ -171,8 +171,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool { && SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) { let mut applicability = Applicability::MachineApplicable; - let cond = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability); - let lhs = snippet_with_applicability(cx, lhs_a.span, "..", &mut applicability); + let cond = Sugg::hir_with_context(cx, cond, e.span.ctxt(), "..", &mut applicability); + let (lhs, _) = snippet_with_context(cx, lhs_a.span, e.span.ctxt(), "..", &mut applicability); let mut sugg = if a == b { format!("{cond}; {lhs} = {a:?};") } else { diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs index d03188f1d39b..55a5a16c0099 100644 --- a/clippy_lints/src/needless_for_each.rs +++ b/clippy_lints/src/needless_for_each.rs @@ -56,8 +56,20 @@ declare_lint_pass!(NeedlessForEach => [NEEDLESS_FOR_EACH]); impl<'tcx> LateLintPass<'tcx> for NeedlessForEach { fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { - if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind - && let ExprKind::MethodCall(method_name, for_each_recv, [for_each_arg], _) = expr.kind + if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind { + check_expr(cx, expr, stmt.span); + } + } + + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) { + if let Some(expr) = block.expr { + check_expr(cx, expr, expr.span); + } + } +} + +fn check_expr(cx: &LateContext<'_>, expr: &Expr<'_>, outer_span: Span) { + if let ExprKind::MethodCall(method_name, for_each_recv, [for_each_arg], _) = expr.kind && let ExprKind::MethodCall(_, iter_recv, [], _) = for_each_recv.kind // Skip the lint if the call chain is too long. e.g. `v.field.iter().for_each()` or // `v.foo().iter().for_each()` must be skipped. @@ -76,69 +88,74 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach { // Skip the lint if the body is not safe, so as not to suggest `for … in … unsafe {}` // and suggesting `for … in … { unsafe { } }` is a little ugly. && !matches!(body.value.kind, ExprKind::Block(Block { rules: BlockCheckMode::UnsafeBlock(_), .. }, ..)) + { + let mut applicability = Applicability::MachineApplicable; + + // If any closure parameter has an explicit type specified, applying the lint would necessarily + // remove that specification, possibly breaking type inference + if fn_decl + .inputs + .iter() + .any(|input| matches!(input.kind, TyKind::Infer(..))) { - let mut applicability = Applicability::MachineApplicable; + applicability = Applicability::MaybeIncorrect; + } - // If any closure parameter has an explicit type specified, applying the lint would necessarily - // remove that specification, possibly breaking type inference - if fn_decl - .inputs - .iter() - .any(|input| matches!(input.kind, TyKind::Infer(..))) - { - applicability = Applicability::MaybeIncorrect; - } + let mut ret_collector = RetCollector::default(); + ret_collector.visit_expr(body.value); - let mut ret_collector = RetCollector::default(); - ret_collector.visit_expr(body.value); + // Skip the lint if `return` is used in `Loop` in order not to suggest using `'label`. + if ret_collector.ret_in_loop { + return; + } - // Skip the lint if `return` is used in `Loop` in order not to suggest using `'label`. - if ret_collector.ret_in_loop { - return; - } + let ret_suggs = if ret_collector.spans.is_empty() { + None + } else { + applicability = Applicability::MaybeIncorrect; + Some( + ret_collector + .spans + .into_iter() + .map(|span| (span, "continue".to_string())) + .collect(), + ) + }; - let ret_suggs = if ret_collector.spans.is_empty() { - None + let body_param_sugg = snippet_with_applicability(cx, body.params[0].pat.span, "..", &mut applicability); + let for_each_rev_sugg = snippet_with_applicability(cx, for_each_recv.span, "..", &mut applicability); + let (body_value_sugg, is_macro_call) = + snippet_with_context(cx, body.value.span, for_each_recv.span.ctxt(), "..", &mut applicability); + + let sugg = format!( + "for {} in {} {}", + body_param_sugg, + for_each_rev_sugg, + if is_macro_call { + format!("{{ {body_value_sugg}; }}") } else { - applicability = Applicability::MaybeIncorrect; - Some( - ret_collector - .spans - .into_iter() - .map(|span| (span, "continue".to_string())) - .collect(), - ) - }; - - let body_param_sugg = snippet_with_applicability(cx, body.params[0].pat.span, "..", &mut applicability); - let for_each_rev_sugg = snippet_with_applicability(cx, for_each_recv.span, "..", &mut applicability); - let (body_value_sugg, is_macro_call) = - snippet_with_context(cx, body.value.span, for_each_recv.span.ctxt(), "..", &mut applicability); - - let sugg = format!( - "for {} in {} {}", - body_param_sugg, - for_each_rev_sugg, - if is_macro_call { - format!("{{ {body_value_sugg}; }}") - } else { - match body.value.kind { - ExprKind::Block(block, _) if is_let_desugar(block) => { - format!("{{ {body_value_sugg} }}") - }, - ExprKind::Block(_, _) => body_value_sugg.to_string(), - _ => format!("{{ {body_value_sugg}; }}"), - } + match body.value.kind { + ExprKind::Block(block, _) if is_let_desugar(block) => { + format!("{{ {body_value_sugg} }}") + }, + ExprKind::Block(_, _) => body_value_sugg.to_string(), + _ => format!("{{ {body_value_sugg}; }}"), } - ); + } + ); - span_lint_and_then(cx, NEEDLESS_FOR_EACH, stmt.span, "needless use of `for_each`", |diag| { - diag.span_suggestion(stmt.span, "try", sugg, applicability); + span_lint_and_then( + cx, + NEEDLESS_FOR_EACH, + outer_span, + "needless use of `for_each`", + |diag| { + diag.span_suggestion(outer_span, "try", sugg, applicability); if let Some(ret_suggs) = ret_suggs { diag.multipart_suggestion("...and replace `return` with `continue`", ret_suggs, applicability); } - }); - } + }, + ); } } diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index 67493d54b552..e151c06c6c20 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -1,16 +1,15 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::return_ty; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability}; use clippy_utils::sugg::DiagExt; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_hir::HirIdSet; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{Attribute, HirIdSet}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::AssocKind; use rustc_session::impl_lint_pass; use rustc_span::sym; -use rustc_hir::Attribute; -use rustc_hir::attrs::AttributeKind; declare_clippy_lint! { /// ### What it does @@ -59,6 +58,7 @@ pub struct NewWithoutDefault { impl_lint_pass!(NewWithoutDefault => [NEW_WITHOUT_DEFAULT]); impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { + #[expect(clippy::too_many_lines)] fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { let hir::ItemKind::Impl(hir::Impl { of_trait: None, @@ -139,16 +139,34 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { sugg.push_str(&snippet_with_applicability(cx.sess(), *attr_span, "_", &mut app)); sugg.push('\n'); } - } sugg }; let generics_sugg = snippet_with_applicability(cx, generics.span, "", &mut app); let where_clause_sugg = if generics.has_where_clause_predicates { - format!( - "\n{}\n", - snippet_with_applicability(cx, generics.where_clause_span, "", &mut app) - ) + let where_clause_sugg = + snippet_with_applicability(cx, generics.where_clause_span, "", &mut app).to_string(); + let mut where_clause_sugg = reindent_multiline(&where_clause_sugg, true, Some(4)); + if impl_item.generics.has_where_clause_predicates { + if !where_clause_sugg.ends_with(',') { + where_clause_sugg.push(','); + } + + let additional_where_preds = + snippet_with_applicability(cx, impl_item.generics.where_clause_span, "", &mut app); + let ident = indent_of(cx, generics.where_clause_span).unwrap_or(0); + // Remove the leading `where ` keyword + let additional_where_preds = additional_where_preds.trim_start_matches("where").trim_start(); + where_clause_sugg.push('\n'); + where_clause_sugg.extend(std::iter::repeat_n(' ', ident)); + where_clause_sugg.push_str(additional_where_preds); + } + format!("\n{where_clause_sugg}\n") + } else if impl_item.generics.has_where_clause_predicates { + let where_clause_sugg = + snippet_with_applicability(cx, impl_item.generics.where_clause_span, "", &mut app); + let where_clause_sugg = reindent_multiline(&where_clause_sugg, true, Some(4)); + format!("\n{}\n", where_clause_sugg.trim_start()) } else { String::new() }; diff --git a/clippy_lints/src/operators/cmp_owned.rs b/clippy_lints/src/operators/cmp_owned.rs index 05358de5b348..39097833a6c5 100644 --- a/clippy_lints/src/operators/cmp_owned.rs +++ b/clippy_lints/src/operators/cmp_owned.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeQPath; -use clippy_utils::source::snippet; +use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{implements_trait, is_copy}; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; @@ -94,51 +94,37 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) return; } - let arg_snip = snippet(cx, arg_span, ".."); - let expr_snip; - let eq_impl; - if with_deref.is_implemented() && !arg_ty.peel_refs().is_str() { - expr_snip = format!("*{arg_snip}"); - eq_impl = with_deref; + let mut applicability = Applicability::MachineApplicable; + let (arg_snip, _) = snippet_with_context(cx, arg_span, expr.span.ctxt(), "..", &mut applicability); + let (expr_snip, eq_impl) = if with_deref.is_implemented() && !arg_ty.peel_refs().is_str() { + (format!("*{arg_snip}"), with_deref) } else { - expr_snip = arg_snip.to_string(); - eq_impl = without_deref; - } + (arg_snip.to_string(), without_deref) + }; - let span; - let hint; - if (eq_impl.ty_eq_other && left) || (eq_impl.other_eq_ty && !left) { - span = expr.span; - hint = expr_snip; + let (span, hint) = if (eq_impl.ty_eq_other && left) || (eq_impl.other_eq_ty && !left) { + (expr.span, expr_snip) } else { - span = expr.span.to(other.span); + let span = expr.span.to(other.span); let cmp_span = if other.span < expr.span { other.span.between(expr.span) } else { expr.span.between(other.span) }; - if eq_impl.ty_eq_other { - hint = format!( - "{expr_snip}{}{}", - snippet(cx, cmp_span, ".."), - snippet(cx, other.span, "..") - ); - } else { - hint = format!( - "{}{}{expr_snip}", - snippet(cx, other.span, ".."), - snippet(cx, cmp_span, "..") - ); - } - } - diag.span_suggestion( - span, - "try", - hint, - Applicability::MachineApplicable, // snippet - ); + let (cmp_snippet, _) = snippet_with_context(cx, cmp_span, expr.span.ctxt(), "..", &mut applicability); + let (other_snippet, _) = + snippet_with_context(cx, other.span, expr.span.ctxt(), "..", &mut applicability); + + if eq_impl.ty_eq_other { + (span, format!("{expr_snip}{cmp_snippet}{other_snippet}")) + } else { + (span, format!("{other_snippet}{cmp_snippet}{expr_snip}")) + } + }; + + diag.span_suggestion(span, "try", hint, applicability); }, ); } diff --git a/clippy_lints/src/operators/manual_div_ceil.rs b/clippy_lints/src/operators/manual_div_ceil.rs index 98aa47421537..5ed923d719bc 100644 --- a/clippy_lints/src/operators/manual_div_ceil.rs +++ b/clippy_lints/src/operators/manual_div_ceil.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::res::{MaybeDef, MaybeQPath}; use clippy_utils::sugg::{Sugg, has_enclosing_paren}; use clippy_utils::{SpanlessEq, sym}; use rustc_ast::{BinOpKind, LitIntType, LitKind, UnOp}; @@ -7,7 +8,7 @@ use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; -use rustc_middle::ty::{self}; +use rustc_middle::ty::{self, Ty}; use rustc_span::source_map::Spanned; use super::MANUAL_DIV_CEIL; @@ -16,59 +17,84 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, op: BinOpKind, lhs: & let mut applicability = Applicability::MachineApplicable; if op == BinOpKind::Div - && check_int_ty_and_feature(cx, lhs) - && check_int_ty_and_feature(cx, rhs) - && let ExprKind::Binary(inner_op, inner_lhs, inner_rhs) = lhs.kind + && check_int_ty_and_feature(cx, cx.typeck_results().expr_ty(lhs)) + && check_int_ty_and_feature(cx, cx.typeck_results().expr_ty(rhs)) && msrv.meets(cx, msrvs::DIV_CEIL) { - // (x + (y - 1)) / y - if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind - && inner_op.node == BinOpKind::Add - && sub_op.node == BinOpKind::Sub - && check_literal(sub_rhs) - && check_eq_expr(cx, sub_lhs, rhs) - { - build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); - return; - } + match lhs.kind { + ExprKind::Binary(inner_op, inner_lhs, inner_rhs) => { + // (x + (y - 1)) / y + if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind + && inner_op.node == BinOpKind::Add + && sub_op.node == BinOpKind::Sub + && check_literal(sub_rhs) + && check_eq_expr(cx, sub_lhs, rhs) + { + build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); + return; + } - // ((y - 1) + x) / y - if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_lhs.kind - && inner_op.node == BinOpKind::Add - && sub_op.node == BinOpKind::Sub - && check_literal(sub_rhs) - && check_eq_expr(cx, sub_lhs, rhs) - { - build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability); - return; - } + // ((y - 1) + x) / y + if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_lhs.kind + && inner_op.node == BinOpKind::Add + && sub_op.node == BinOpKind::Sub + && check_literal(sub_rhs) + && check_eq_expr(cx, sub_lhs, rhs) + { + build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability); + return; + } - // (x + y - 1) / y - if let ExprKind::Binary(add_op, add_lhs, add_rhs) = inner_lhs.kind - && inner_op.node == BinOpKind::Sub - && add_op.node == BinOpKind::Add - && check_literal(inner_rhs) - && check_eq_expr(cx, add_rhs, rhs) - { - build_suggestion(cx, expr, add_lhs, rhs, &mut applicability); - } + // (x + y - 1) / y + if let ExprKind::Binary(add_op, add_lhs, add_rhs) = inner_lhs.kind + && inner_op.node == BinOpKind::Sub + && add_op.node == BinOpKind::Add + && check_literal(inner_rhs) + && check_eq_expr(cx, add_rhs, rhs) + { + build_suggestion(cx, expr, add_lhs, rhs, &mut applicability); + } - // (x + (Y - 1)) / Y - if inner_op.node == BinOpKind::Add && differ_by_one(inner_rhs, rhs) { - build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); - } + // (x + (Y - 1)) / Y + if inner_op.node == BinOpKind::Add && differ_by_one(inner_rhs, rhs) { + build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); + } - // ((Y - 1) + x) / Y - if inner_op.node == BinOpKind::Add && differ_by_one(inner_lhs, rhs) { - build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability); - } + // ((Y - 1) + x) / Y + if inner_op.node == BinOpKind::Add && differ_by_one(inner_lhs, rhs) { + build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability); + } - // (x - (-Y - 1)) / Y - if inner_op.node == BinOpKind::Sub - && let ExprKind::Unary(UnOp::Neg, abs_div_rhs) = rhs.kind - && differ_by_one(abs_div_rhs, inner_rhs) - { - build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); + // (x - (-Y - 1)) / Y + if inner_op.node == BinOpKind::Sub + && let ExprKind::Unary(UnOp::Neg, abs_div_rhs) = rhs.kind + && differ_by_one(abs_div_rhs, inner_rhs) + { + build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability); + } + }, + ExprKind::MethodCall(method, receiver, [next_multiple_of_arg], _) => { + // x.next_multiple_of(Y) / Y + if method.ident.name == sym::next_multiple_of + && check_int_ty(cx.typeck_results().expr_ty(receiver)) + && check_eq_expr(cx, next_multiple_of_arg, rhs) + { + build_suggestion(cx, expr, receiver, rhs, &mut applicability); + } + }, + ExprKind::Call(callee, [receiver, next_multiple_of_arg]) => { + // int_type::next_multiple_of(x, Y) / Y + if let Some(impl_ty_binder) = callee + .ty_rel_def_if_named(cx, sym::next_multiple_of) + .assoc_fn_parent(cx) + .opt_impl_ty(cx) + && check_int_ty(impl_ty_binder.skip_binder()) + && check_eq_expr(cx, next_multiple_of_arg, rhs) + { + build_suggestion(cx, expr, receiver, rhs, &mut applicability); + } + }, + _ => (), } } } @@ -91,8 +117,11 @@ fn differ_by_one(small_expr: &Expr<'_>, large_expr: &Expr<'_>) -> bool { } } -fn check_int_ty_and_feature(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - let expr_ty = cx.typeck_results().expr_ty(expr); +fn check_int_ty(expr_ty: Ty<'_>) -> bool { + matches!(expr_ty.peel_refs().kind(), ty::Int(_) | ty::Uint(_)) +} + +fn check_int_ty_and_feature(cx: &LateContext<'_>, expr_ty: Ty<'_>) -> bool { match expr_ty.peel_refs().kind() { ty::Uint(_) => true, ty::Int(_) => cx.tcx.features().enabled(sym::int_roundings), diff --git a/clippy_lints/src/operators/manual_is_multiple_of.rs b/clippy_lints/src/operators/manual_is_multiple_of.rs index 0b9bd4fb6d32..291d81097b51 100644 --- a/clippy_lints/src/operators/manual_is_multiple_of.rs +++ b/clippy_lints/src/operators/manual_is_multiple_of.rs @@ -35,7 +35,7 @@ pub(super) fn check<'tcx>( { let mut app = Applicability::MachineApplicable; let divisor = deref_sugg( - Sugg::hir_with_applicability(cx, operand_right, "_", &mut app), + Sugg::hir_with_context(cx, operand_right, expr.span.ctxt(), "_", &mut app), cx.typeck_results().expr_ty_adjusted(operand_right), ); span_lint_and_sugg( @@ -47,7 +47,7 @@ pub(super) fn check<'tcx>( format!( "{}{}.is_multiple_of({divisor})", if op == BinOpKind::Eq { "" } else { "!" }, - Sugg::hir_with_applicability(cx, operand_left, "_", &mut app).maybe_paren() + Sugg::hir_with_context(cx, operand_left, expr.span.ctxt(), "_", &mut app).maybe_paren() ), app, ); diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index 59d31f782bc3..e5fb3c0fa431 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -5,7 +5,7 @@ use clippy_config::types::MatchLintBehaviour; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{implements_trait, is_copy}; use clippy_utils::usage::local_used_after_expr; @@ -147,7 +147,8 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) { && !span_contains_cfg(cx, els.span) { let mut applicability = Applicability::MaybeIncorrect; - let init_expr_str = Sugg::hir_with_applicability(cx, init_expr, "..", &mut applicability).maybe_paren(); + let init_expr_str = + Sugg::hir_with_context(cx, init_expr, stmt.span.ctxt(), "..", &mut applicability).maybe_paren(); // Take care when binding is `ref` let sugg = if let PatKind::Binding( BindingMode(ByRef::Yes(_, ref_mutability), binding_mutability), @@ -295,7 +296,7 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex && (is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block)) { let mut applicability = Applicability::MachineApplicable; - let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability); + let receiver_str = snippet_with_context(cx, caller.span, expr.span.ctxt(), "..", &mut applicability).0; let by_ref = !cx.type_is_copy_modulo_regions(caller_ty) && !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)); let sugg = if let Some(else_inner) = r#else { diff --git a/clippy_lints/src/single_range_in_vec_init.rs b/clippy_lints/src/single_range_in_vec_init.rs index 92d1b112198f..e4906eb0c777 100644 --- a/clippy_lints/src/single_range_in_vec_init.rs +++ b/clippy_lints/src/single_range_in_vec_init.rs @@ -98,7 +98,7 @@ impl LateLintPass<'_> for SingleRangeInVecInit { && snippet.starts_with(suggested_type.starts_with()) && snippet.ends_with(suggested_type.ends_with()) { - let mut applicability = Applicability::MachineApplicable; + let mut applicability = Applicability::MaybeIncorrect; let (start_snippet, _) = snippet_with_context(cx, start.expr.span, span.ctxt(), "..", &mut applicability); let (end_snippet, _) = snippet_with_context(cx, end.expr.span, span.ctxt(), "..", &mut applicability); diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 1d0efa46a14c..c0be724bcdee 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::res::{MaybeDef, MaybeQPath}; -use clippy_utils::source::{snippet, snippet_with_applicability}; +use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context}; use clippy_utils::{ SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, method_calls, peel_blocks, sym, }; @@ -273,6 +273,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { let string_expression = &expressions[0].0; let snippet_app = snippet_with_applicability(cx, string_expression.span, "..", &mut applicability); + let (right_snip, _) = snippet_with_context(cx, right.span, e.span.ctxt(), "..", &mut applicability); span_lint_and_sugg( cx, @@ -280,7 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { e.span, "calling a slice of `as_bytes()` with `from_utf8` should be not necessary", "try", - format!("Some(&{snippet_app}[{}])", snippet(cx, right.span, "..")), + format!("Some(&{snippet_app}[{right_snip}])"), applicability, ); } @@ -404,7 +405,8 @@ impl<'tcx> LateLintPass<'tcx> for StrToString { "`to_string()` called on a `&str`", |diag| { let mut applicability = Applicability::MachineApplicable; - let snippet = snippet_with_applicability(cx, self_arg.span, "..", &mut applicability); + let (snippet, _) = + snippet_with_context(cx, self_arg.span, expr.span.ctxt(), "..", &mut applicability); diag.span_suggestion(expr.span, "try", format!("{snippet}.to_owned()"), applicability); }, ); diff --git a/clippy_lints/src/strlen_on_c_strings.rs b/clippy_lints/src/strlen_on_c_strings.rs index 58d692db5029..0d50bd547652 100644 --- a/clippy_lints/src/strlen_on_c_strings.rs +++ b/clippy_lints/src/strlen_on_c_strings.rs @@ -14,8 +14,8 @@ declare_clippy_lint! { /// and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead. /// /// ### Why is this bad? - /// This avoids calling an unsafe `libc` function. - /// Currently, it also avoids calculating the length. + /// libc::strlen is an unsafe function, which we don't need to call + /// if all we want to know is the length of the c-string. /// /// ### Example /// ```rust, ignore diff --git a/clippy_lints/src/transmute/transmuting_null.rs b/clippy_lints/src/transmute/transmuting_null.rs index 31e770f421e1..3f435f255d91 100644 --- a/clippy_lints/src/transmute/transmuting_null.rs +++ b/clippy_lints/src/transmute/transmuting_null.rs @@ -2,7 +2,7 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_integer_const; use clippy_utils::res::{MaybeDef, MaybeResPath}; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::{ConstBlock, Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty::Ty; use rustc_span::symbol::sym; @@ -42,5 +42,23 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t return true; } + // Catching: + // `std::mem::transmute({ 0 as *const u64 })` and similar const blocks + if let ExprKind::Block(block, _) = arg.kind + && block.stmts.is_empty() + && let Some(inner) = block.expr + { + // Run again with the inner expression + return check(cx, expr, inner, to_ty); + } + + // Catching: + // `std::mem::transmute(const { u64::MIN as *const u64 });` + if let ExprKind::ConstBlock(ConstBlock { body, .. }) = arg.kind { + // Strip out the const and run again + let block = cx.tcx.hir_body(body).value; + return check(cx, expr, block, to_ty); + } + false } diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index c06313d1a4c4..423301edfe83 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -456,13 +456,25 @@ fn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>) fn adjustments(cx: &LateContext<'_>, expr: &Expr<'_>) -> String { let mut prefix = String::new(); - for adj in cx.typeck_results().expr_adjustments(expr) { + + let adjustments = cx.typeck_results().expr_adjustments(expr); + + let [.., last] = adjustments else { return prefix }; + let target = last.target; + + for adj in adjustments { match adj.kind { Adjust::Deref(_) => prefix = format!("*{prefix}"), Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })) => prefix = format!("&mut {prefix}"), Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)) => prefix = format!("&{prefix}"), _ => {}, } + + // Stop once we reach the final target type. + // This prevents over-adjusting (e.g. suggesting &**y instead of *y). + if adj.target == target { + break; + } } prefix } diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 7a54ba7a8fe1..58b153f06545 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -321,7 +321,6 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), - ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), ConstArgKind::Literal(..) => chain!(self, "let ConstArgKind::Literal(..) = {const_arg}.kind") diff --git a/clippy_lints_internal/src/lint_without_lint_pass.rs b/clippy_lints_internal/src/lint_without_lint_pass.rs index fda65bc84eda..f56b6f31550b 100644 --- a/clippy_lints_internal/src/lint_without_lint_pass.rs +++ b/clippy_lints_internal/src/lint_without_lint_pass.rs @@ -250,8 +250,8 @@ pub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item< if let hir::Attribute::Unparsed(attr_kind) = &attr // Identify attribute && let [tool_name, attr_name] = &attr_kind.path.segments[..] - && tool_name.name == sym::clippy - && attr_name.name == sym::version + && tool_name == &sym::clippy + && attr_name == &sym::version && let Some(version) = attr.value_str() { Some(version) diff --git a/clippy_utils/README.md b/clippy_utils/README.md index 01257c1a3059..ecd36b157571 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-12-25 +nightly-2026-01-08 ``` @@ -30,7 +30,7 @@ Function signatures can change or be removed without replacement without any pri -Copyright 2014-2025 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 <[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index 618719286e8f..cf8716398efb 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -976,7 +976,9 @@ pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool { l.style == r.style && match (&l.kind, &r.kind) { (DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2, - (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_attr_item_kind(&l.item.args, &r.item.args), + (Normal(l), Normal(r)) => { + eq_path(&l.item.path, &r.item.path) && eq_attr_item_kind(&l.item.args, &r.item.args) + }, _ => false, } } diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs index 87fdd755908b..32f6cb4fd5e9 100644 --- a/clippy_utils/src/attrs.rs +++ b/clippy_utils/src/attrs.rs @@ -23,7 +23,9 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( if let [clippy, segment2] = &*attr.path() && *clippy == sym::clippy { - let path_span = attr.path_span().expect("Clippy attributes are unparsed and have a span"); + let path_span = attr + .path_span() + .expect("Clippy attributes are unparsed and have a span"); let new_name = match *segment2 { sym::cyclomatic_complexity => Some("cognitive_complexity"), sym::author @@ -48,7 +50,7 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( .with_span_suggestion( path_span, "consider using", - format!("clippy::{}", new_name), + format!("clippy::{new_name}"), Applicability::MachineApplicable, ) .emit(); diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 5f4b87590dc1..334cc6bb5d55 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1140,9 +1140,11 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Struct(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) | ConstArgKind::Literal(..) => { - None - }, + ConstArgKind::Struct(..) + | ConstArgKind::TupleCall(..) + | ConstArgKind::Path(_) + | ConstArgKind::Error(..) + | ConstArgKind::Infer(..) => None, }, } } diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index b4e483ea8072..73b1cbb21548 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -675,7 +675,7 @@ impl HirEqInterExpr<'_, '_, '_> { .iter() .zip(*inits_b) .all(|(init_a, init_b)| self.eq_const_arg(init_a.expr, init_b.expr)) - } + }, (ConstArgKind::TupleCall(path_a, args_a), ConstArgKind::TupleCall(path_b, args_b)) => { self.eq_qpath(path_a, path_b) && args_a @@ -688,7 +688,7 @@ impl HirEqInterExpr<'_, '_, '_> { .iter() .zip(*args_b) .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) - } + }, (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => { kind_l == kind_r }, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 38e1542cd758..2a620e917228 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -90,13 +90,13 @@ use std::sync::{Mutex, MutexGuard, OnceLock}; use itertools::Itertools; use rustc_abi::Integer; use rustc_ast::ast::{self, LitKind, RangeLimits}; -use rustc_ast::join_path_syms; +use rustc_ast::{LitIntType, join_path_syms}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexmap; use rustc_data_structures::packed::Pu128; use rustc_data_structures::unhash::UnindexMap; use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk}; -use rustc_hir::attrs::AttributeKind; +use rustc_hir::attrs::{AttributeKind, CfgEntry}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::definitions::{DefPath, DefPathData}; @@ -121,7 +121,6 @@ use rustc_middle::ty::{ self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, GenericArgKind, GenericArgsRef, IntTy, Ty, TyCtxt, TypeFlags, TypeVisitableExt, UintTy, UpvarCapture, }; -use rustc_hir::attrs::CfgEntry; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{Ident, Symbol, kw}; @@ -1386,6 +1385,17 @@ pub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool { false } +/// Checks whether the given expression is an untyped integer literal. +pub fn is_integer_literal_untyped(expr: &Expr<'_>) -> bool { + if let ExprKind::Lit(spanned) = expr.kind + && let LitKind::Int(_, suffix) = spanned.node + { + return suffix == LitIntType::Unsuffixed; + } + + false +} + /// Checks whether the given expression is a constant literal of the given value. pub fn is_float_literal(expr: &Expr<'_>, value: f64) -> bool { if let ExprKind::Lit(spanned) = expr.kind @@ -2403,7 +2413,10 @@ pub fn is_test_function(tcx: TyCtxt<'_>, fn_def_id: LocalDefId) -> bool { /// use [`is_in_cfg_test`] pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { if let Some(cfgs) = find_attr!(tcx.hir_attrs(id), AttributeKind::CfgTrace(cfgs) => cfgs) - && cfgs.iter().any(|(cfg, _)| { matches!(cfg, CfgEntry::NameValue { name: sym::test, ..})}) { + && cfgs + .iter() + .any(|(cfg, _)| matches!(cfg, CfgEntry::NameValue { name: sym::test, .. })) + { true } else { false @@ -2423,9 +2436,11 @@ pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied. pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { find_attr!(tcx.get_all_attrs(def_id), AttributeKind::CfgTrace(..)) - || find_attr!(tcx - .hir_parent_iter(tcx.local_def_id_to_hir_id(def_id)) - .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)), AttributeKind::CfgTrace(..)) + || find_attr!( + tcx.hir_parent_iter(tcx.local_def_id_to_hir_id(def_id)) + .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)), + AttributeKind::CfgTrace(..) + ) } /// Walks up the HIR tree from the given expression in an attempt to find where the value is diff --git a/clippy_utils/src/res.rs b/clippy_utils/src/res.rs index a3efece7d224..e890a73620a5 100644 --- a/clippy_utils/src/res.rs +++ b/clippy_utils/src/res.rs @@ -301,7 +301,7 @@ impl<'tcx> MaybeQPath<'tcx> for &'tcx PatExpr<'_> { fn opt_qpath(self) -> Option> { match &self.kind { PatExprKind::Path(qpath) => Some((qpath, self.hir_id)), - _ => None, + PatExprKind::Lit { .. } => None, } } } @@ -419,7 +419,7 @@ impl<'a> MaybeResPath<'a> for &PatExpr<'a> { fn opt_res_path(self) -> OptResPath<'a> { match &self.kind { PatExprKind::Path(qpath) => qpath.opt_res_path(), - _ => (None, None), + PatExprKind::Lit { .. } => (None, None), } } } diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 2ef2afb45071..3ade38bea8ed 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -127,7 +127,7 @@ impl<'a> Sugg<'a> { /// Generate a suggestion for an expression with the given snippet. This is used by the `hir_*` /// function variants of `Sugg`, since these use different snippet functions. - fn hir_from_snippet( + pub fn hir_from_snippet( cx: &LateContext<'_>, expr: &hir::Expr<'_>, mut get_snippet: impl FnMut(Span) -> Cow<'a, str>, diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index a0d2e8673fe6..5357a0941d32 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -248,6 +248,7 @@ generate! { next_back, next_if, next_if_eq, + next_multiple_of, next_tuple, nth, ok, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index dbec79e111fb..0755e1d29c69 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-12-25" +channel = "nightly-2026-01-08" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" diff --git a/rustc_tools_util/README.md b/rustc_tools_util/README.md index f47a4c69c2c3..45d2844ad00b 100644 --- a/rustc_tools_util/README.md +++ b/rustc_tools_util/README.md @@ -51,7 +51,7 @@ The changelog for `rustc_tools_util` is available under: -Copyright 2014-2025 The Rust Project Developers +Copyright (c) The Rust Project Contributors Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/tests/ui-toml/missing_enforced_import_rename/clippy.toml b/tests/ui-toml/missing_enforced_import_rename/clippy.toml index 05ba822874d5..11af5b0a3306 100644 --- a/tests/ui-toml/missing_enforced_import_rename/clippy.toml +++ b/tests/ui-toml/missing_enforced_import_rename/clippy.toml @@ -6,5 +6,6 @@ enforced-import-renames = [ { path = "std::clone", rename = "foo" }, { path = "std::thread::sleep", rename = "thread_sleep" }, { path = "std::any::type_name", rename = "ident" }, - { path = "std::sync::Mutex", rename = "StdMutie" } + { path = "std::sync::Mutex", rename = "StdMutie" }, + { path = "std::io::Write", rename = "to_test_rename_as_underscore" } ] diff --git a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed index 3e882f496985..c96df2884b8d 100644 --- a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed +++ b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed @@ -15,6 +15,7 @@ use std::{ sync :: Mutex as StdMutie, //~^ missing_enforced_import_renames }; +use std::io::Write as _; fn main() { use std::collections::BTreeMap as Map; diff --git a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs index 32255af5117f..662e89157675 100644 --- a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs +++ b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs @@ -15,6 +15,7 @@ use std::{ sync :: Mutex, //~^ missing_enforced_import_renames }; +use std::io::Write as _; fn main() { use std::collections::BTreeMap as OopsWrongRename; diff --git a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr index 982b144eb872..139331d17619 100644 --- a/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr +++ b/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr @@ -32,7 +32,7 @@ LL | sync :: Mutex, | ^^^^^^^^^^^^^ help: try: `sync :: Mutex as StdMutie` error: this import should be renamed - --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:20:5 + --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:21:5 | LL | use std::collections::BTreeMap as OopsWrongRename; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `use std::collections::BTreeMap as Map` diff --git a/tests/ui/bool_assert_comparison.fixed b/tests/ui/bool_assert_comparison.fixed index ec76abbef05a..cd390ce0db9d 100644 --- a/tests/ui/bool_assert_comparison.fixed +++ b/tests/ui/bool_assert_comparison.fixed @@ -216,3 +216,16 @@ fn main() { assert!(!(b + b)); //~^ bool_assert_comparison } + +fn issue16279() { + macro_rules! is_empty { + ($x:expr) => { + $x.is_empty() + }; + } + + assert!(!is_empty!("a")); + //~^ bool_assert_comparison + assert!(is_empty!("")); + //~^ bool_assert_comparison +} diff --git a/tests/ui/bool_assert_comparison.rs b/tests/ui/bool_assert_comparison.rs index 40824a23c82e..b2ea5b6ea540 100644 --- a/tests/ui/bool_assert_comparison.rs +++ b/tests/ui/bool_assert_comparison.rs @@ -216,3 +216,16 @@ fn main() { assert_eq!(b + b, false); //~^ bool_assert_comparison } + +fn issue16279() { + macro_rules! is_empty { + ($x:expr) => { + $x.is_empty() + }; + } + + assert_eq!(is_empty!("a"), false); + //~^ bool_assert_comparison + assert_eq!(is_empty!(""), true); + //~^ bool_assert_comparison +} diff --git a/tests/ui/bool_assert_comparison.stderr b/tests/ui/bool_assert_comparison.stderr index 72aa6303a202..b4e8fcf09bb6 100644 --- a/tests/ui/bool_assert_comparison.stderr +++ b/tests/ui/bool_assert_comparison.stderr @@ -444,5 +444,29 @@ LL - assert_eq!(b + b, false); LL + assert!(!(b + b)); | -error: aborting due to 37 previous errors +error: used `assert_eq!` with a literal bool + --> tests/ui/bool_assert_comparison.rs:227:5 + | +LL | assert_eq!(is_empty!("a"), false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(is_empty!("a"), false); +LL + assert!(!is_empty!("a")); + | + +error: used `assert_eq!` with a literal bool + --> tests/ui/bool_assert_comparison.rs:229:5 + | +LL | assert_eq!(is_empty!(""), true); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with `assert!(..)` + | +LL - assert_eq!(is_empty!(""), true); +LL + assert!(is_empty!("")); + | + +error: aborting due to 39 previous errors diff --git a/tests/ui/checked_conversions.fixed b/tests/ui/checked_conversions.fixed index 6175275ef047..2309a053146f 100644 --- a/tests/ui/checked_conversions.fixed +++ b/tests/ui/checked_conversions.fixed @@ -1,6 +1,7 @@ #![allow( clippy::cast_lossless, clippy::legacy_numeric_constants, + clippy::no_effect, unused, // Int::max_value will be deprecated in the future deprecated, @@ -105,4 +106,19 @@ fn msrv_1_34() { //~^ checked_conversions } +fn issue16293() { + struct Outer { + inner: u32, + } + let outer = Outer { inner: 42 }; + macro_rules! dot_inner { + ($obj:expr) => { + $obj.inner + }; + } + + i32::try_from(dot_inner!(outer)).is_ok(); + //~^ checked_conversions +} + fn main() {} diff --git a/tests/ui/checked_conversions.rs b/tests/ui/checked_conversions.rs index 9ed0e8f660d0..dabb552eba27 100644 --- a/tests/ui/checked_conversions.rs +++ b/tests/ui/checked_conversions.rs @@ -1,6 +1,7 @@ #![allow( clippy::cast_lossless, clippy::legacy_numeric_constants, + clippy::no_effect, unused, // Int::max_value will be deprecated in the future deprecated, @@ -105,4 +106,19 @@ fn msrv_1_34() { //~^ checked_conversions } +fn issue16293() { + struct Outer { + inner: u32, + } + let outer = Outer { inner: 42 }; + macro_rules! dot_inner { + ($obj:expr) => { + $obj.inner + }; + } + + dot_inner!(outer) <= i32::MAX as u32; + //~^ checked_conversions +} + fn main() {} diff --git a/tests/ui/checked_conversions.stderr b/tests/ui/checked_conversions.stderr index 624876dacb26..6018dacace39 100644 --- a/tests/ui/checked_conversions.stderr +++ b/tests/ui/checked_conversions.stderr @@ -1,5 +1,5 @@ error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:15:13 + --> tests/ui/checked_conversions.rs:16:13 | LL | let _ = value <= (u32::max_value() as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` @@ -8,100 +8,106 @@ LL | let _ = value <= (u32::max_value() as i64) && value >= 0; = help: to override `-D warnings` add `#[allow(clippy::checked_conversions)]` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:17:13 + --> tests/ui/checked_conversions.rs:18:13 | LL | let _ = value <= (u32::MAX as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:22:13 + --> tests/ui/checked_conversions.rs:23:13 | LL | let _ = value <= i64::from(u16::max_value()) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:24:13 + --> tests/ui/checked_conversions.rs:25:13 | LL | let _ = value <= i64::from(u16::MAX) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:29:13 + --> tests/ui/checked_conversions.rs:30:13 | LL | let _ = value <= (u8::max_value() as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:31:13 + --> tests/ui/checked_conversions.rs:32:13 | LL | let _ = value <= (u8::MAX as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:38:13 + --> tests/ui/checked_conversions.rs:39:13 | LL | let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:40:13 + --> tests/ui/checked_conversions.rs:41:13 | LL | let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:45:13 + --> tests/ui/checked_conversions.rs:46:13 | LL | let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:47:13 + --> tests/ui/checked_conversions.rs:48:13 | LL | let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:54:13 + --> tests/ui/checked_conversions.rs:55:13 | LL | let _ = value <= i32::max_value() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:56:13 + --> tests/ui/checked_conversions.rs:57:13 | LL | let _ = value <= i32::MAX as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:61:13 + --> tests/ui/checked_conversions.rs:62:13 | LL | let _ = value <= isize::max_value() as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:63:13 + --> tests/ui/checked_conversions.rs:64:13 | LL | let _ = value <= isize::MAX as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:68:13 + --> tests/ui/checked_conversions.rs:69:13 | LL | let _ = value <= u16::max_value() as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:70:13 + --> tests/ui/checked_conversions.rs:71:13 | LL | let _ = value <= u16::MAX as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:104:13 + --> tests/ui/checked_conversions.rs:105:13 | LL | let _ = value <= (u32::max_value() as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` -error: aborting due to 17 previous errors +error: checked cast can be simplified + --> tests/ui/checked_conversions.rs:120:5 + | +LL | dot_inner!(outer) <= i32::MAX as u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(dot_inner!(outer)).is_ok()` + +error: aborting due to 18 previous errors diff --git a/tests/ui/cmp_owned/with_suggestion.fixed b/tests/ui/cmp_owned/with_suggestion.fixed index 85d0991bef05..4c3b13b30043 100644 --- a/tests/ui/cmp_owned/with_suggestion.fixed +++ b/tests/ui/cmp_owned/with_suggestion.fixed @@ -83,3 +83,32 @@ fn issue_8103() { let _ = foo1 == foo2; //~^ cmp_owned } + +macro_rules! issue16322_macro_generator { + ($locale:ident) => { + mod $locale { + macro_rules! _make { + ($token:tt) => { + stringify!($token) + }; + } + + pub(crate) use _make; + } + + macro_rules! t { + ($token:tt) => { + crate::$locale::_make!($token) + }; + } + }; +} + +issue16322_macro_generator!(de); + +fn issue16322(item: String) { + if item == t!(frohes_neu_Jahr) { + //~^ cmp_owned + println!("Ja!"); + } +} diff --git a/tests/ui/cmp_owned/with_suggestion.rs b/tests/ui/cmp_owned/with_suggestion.rs index 2393757d76f2..a9d7509feaaf 100644 --- a/tests/ui/cmp_owned/with_suggestion.rs +++ b/tests/ui/cmp_owned/with_suggestion.rs @@ -83,3 +83,32 @@ fn issue_8103() { let _ = foo1 == foo2.to_owned(); //~^ cmp_owned } + +macro_rules! issue16322_macro_generator { + ($locale:ident) => { + mod $locale { + macro_rules! _make { + ($token:tt) => { + stringify!($token) + }; + } + + pub(crate) use _make; + } + + macro_rules! t { + ($token:tt) => { + crate::$locale::_make!($token) + }; + } + }; +} + +issue16322_macro_generator!(de); + +fn issue16322(item: String) { + if item == t!(frohes_neu_Jahr).to_string() { + //~^ cmp_owned + println!("Ja!"); + } +} diff --git a/tests/ui/cmp_owned/with_suggestion.stderr b/tests/ui/cmp_owned/with_suggestion.stderr index dd9ffa70897a..66544ce0c217 100644 --- a/tests/ui/cmp_owned/with_suggestion.stderr +++ b/tests/ui/cmp_owned/with_suggestion.stderr @@ -49,5 +49,11 @@ error: this creates an owned instance just for comparison LL | let _ = foo1 == foo2.to_owned(); | ^^^^^^^^^^^^^^^ help: try: `foo2` -error: aborting due to 8 previous errors +error: this creates an owned instance just for comparison + --> tests/ui/cmp_owned/with_suggestion.rs:110:16 + | +LL | if item == t!(frohes_neu_Jahr).to_string() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t!(frohes_neu_Jahr)` + +error: aborting due to 9 previous errors diff --git a/tests/ui/derive_ord_xor_partial_ord.rs b/tests/ui/derive_ord_xor_partial_ord.rs index b4bb24b0d2fe..386ab39401c5 100644 --- a/tests/ui/derive_ord_xor_partial_ord.rs +++ b/tests/ui/derive_ord_xor_partial_ord.rs @@ -91,3 +91,17 @@ mod issue15708 { } } } + +mod issue16298 { + #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] + struct Normalized(S); + + impl Eq for Normalized {} + + #[expect(clippy::derive_ord_xor_partial_ord)] + impl Ord for Normalized { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.partial_cmp(other).unwrap() + } + } +} diff --git a/tests/ui/double_parens.fixed b/tests/ui/double_parens.fixed index 024af6840132..ef7838491f8f 100644 --- a/tests/ui/double_parens.fixed +++ b/tests/ui/double_parens.fixed @@ -161,4 +161,20 @@ fn issue15940() { pub struct Person; } +fn issue16224() { + fn test() -> i32 { 42 } + + macro_rules! call { + ($matcher:pat $(=> $result:expr)?) => { + match test() { + $matcher => Result::Ok(($($result),*)), + _ => Result::Err("No match".to_string()), + } + }; + } + + let _: Result<(), String> = call!(_); + let _: Result = call!(_ => 42); +} + fn main() {} diff --git a/tests/ui/double_parens.rs b/tests/ui/double_parens.rs index 8a76f2837f35..07eafdf69575 100644 --- a/tests/ui/double_parens.rs +++ b/tests/ui/double_parens.rs @@ -161,4 +161,20 @@ fn issue15940() { pub struct Person; } +fn issue16224() { + fn test() -> i32 { 42 } + + macro_rules! call { + ($matcher:pat $(=> $result:expr)?) => { + match test() { + $matcher => Result::Ok(($($result),*)), + _ => Result::Err("No match".to_string()), + } + }; + } + + let _: Result<(), String> = call!(_); + let _: Result = call!(_ => 42); +} + fn main() {} diff --git a/tests/ui/for_kv_map.fixed b/tests/ui/for_kv_map.fixed index 2a68b7443fbf..6ec4cb01ffd1 100644 --- a/tests/ui/for_kv_map.fixed +++ b/tests/ui/for_kv_map.fixed @@ -69,3 +69,20 @@ fn main() { let _v = v; } } + +fn wrongly_unmangled_macros() { + use std::collections::HashMap; + + macro_rules! test_map { + ($val:expr) => { + &*$val + }; + } + + let m: HashMap = HashMap::new(); + let wrapped = Rc::new(m); + for v in test_map!(wrapped).values() { + //~^ for_kv_map + let _v = v; + } +} diff --git a/tests/ui/for_kv_map.rs b/tests/ui/for_kv_map.rs index 485a97815e3c..19e907ff10a6 100644 --- a/tests/ui/for_kv_map.rs +++ b/tests/ui/for_kv_map.rs @@ -69,3 +69,20 @@ fn main() { let _v = v; } } + +fn wrongly_unmangled_macros() { + use std::collections::HashMap; + + macro_rules! test_map { + ($val:expr) => { + &*$val + }; + } + + let m: HashMap = HashMap::new(); + let wrapped = Rc::new(m); + for (_, v) in test_map!(wrapped) { + //~^ for_kv_map + let _v = v; + } +} diff --git a/tests/ui/for_kv_map.stderr b/tests/ui/for_kv_map.stderr index 0bd474a10682..5436592f2ab6 100644 --- a/tests/ui/for_kv_map.stderr +++ b/tests/ui/for_kv_map.stderr @@ -72,5 +72,17 @@ LL - 'label: for (k, _value) in rm { LL + 'label: for k in rm.keys() { | -error: aborting due to 6 previous errors +error: you seem to want to iterate on a map's values + --> tests/ui/for_kv_map.rs:84:19 + | +LL | for (_, v) in test_map!(wrapped) { + | ^^^^^^^^^^^^^^^^^^ + | +help: use the corresponding method + | +LL - for (_, v) in test_map!(wrapped) { +LL + for v in test_map!(wrapped).values() { + | + +error: aborting due to 7 previous errors diff --git a/tests/ui/impl.rs b/tests/ui/impl.rs index e6044cc50781..75761a34c86e 100644 --- a/tests/ui/impl.rs +++ b/tests/ui/impl.rs @@ -14,6 +14,7 @@ impl MyStruct { } impl<'a> MyStruct { + //~^ multiple_inherent_impl fn lifetimed() {} } @@ -90,10 +91,12 @@ struct Lifetime<'s> { } impl Lifetime<'_> {} -impl Lifetime<'_> {} // false negative +impl Lifetime<'_> {} +//~^ multiple_inherent_impl impl<'a> Lifetime<'a> {} -impl<'a> Lifetime<'a> {} // false negative +impl<'a> Lifetime<'a> {} +//~^ multiple_inherent_impl impl<'b> Lifetime<'b> {} // false negative? @@ -104,6 +107,39 @@ struct Generic { } impl Generic {} -impl Generic {} // false negative +impl Generic {} +//~^ multiple_inherent_impl + +use std::fmt::Debug; + +#[derive(Debug)] +struct GenericWithBounds(T); + +impl GenericWithBounds { + fn make_one(_one: T) -> Self { + todo!() + } +} + +impl GenericWithBounds { + //~^ multiple_inherent_impl + fn make_two(_two: T) -> Self { + todo!() + } +} + +struct MultipleTraitBounds(T); + +impl MultipleTraitBounds { + fn debug_fn() {} +} + +impl MultipleTraitBounds { + fn clone_fn() {} +} + +impl MultipleTraitBounds { + fn debug_clone_fn() {} +} fn main() {} diff --git a/tests/ui/impl.stderr b/tests/ui/impl.stderr index 93d4b3998f90..9c4aaf183d70 100644 --- a/tests/ui/impl.stderr +++ b/tests/ui/impl.stderr @@ -19,7 +19,24 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::multiple_inherent_impl)]` error: multiple implementations of this structure - --> tests/ui/impl.rs:26:5 + --> tests/ui/impl.rs:16:1 + | +LL | / impl<'a> MyStruct { +LL | | +LL | | fn lifetimed() {} +LL | | } + | |_^ + | +note: first implementation here + --> tests/ui/impl.rs:6:1 + | +LL | / impl MyStruct { +LL | | fn first() {} +LL | | } + | |_^ + +error: multiple implementations of this structure + --> tests/ui/impl.rs:27:5 | LL | / impl super::MyStruct { LL | | @@ -37,7 +54,7 @@ LL | | } | |_^ error: multiple implementations of this structure - --> tests/ui/impl.rs:48:1 + --> tests/ui/impl.rs:49:1 | LL | / impl WithArgs { LL | | @@ -47,7 +64,7 @@ LL | | } | |_^ | note: first implementation here - --> tests/ui/impl.rs:45:1 + --> tests/ui/impl.rs:46:1 | LL | / impl WithArgs { LL | | fn f2() {} @@ -55,28 +72,85 @@ LL | | } | |_^ error: multiple implementations of this structure - --> tests/ui/impl.rs:71:1 + --> tests/ui/impl.rs:72:1 | LL | impl OneAllowedImpl {} | ^^^^^^^^^^^^^^^^^^^^^^ | note: first implementation here - --> tests/ui/impl.rs:68:1 + --> tests/ui/impl.rs:69:1 | LL | impl OneAllowedImpl {} | ^^^^^^^^^^^^^^^^^^^^^^ error: multiple implementations of this structure - --> tests/ui/impl.rs:84:1 + --> tests/ui/impl.rs:85:1 | LL | impl OneExpected {} | ^^^^^^^^^^^^^^^^^^^ | note: first implementation here - --> tests/ui/impl.rs:81:1 + --> tests/ui/impl.rs:82:1 | LL | impl OneExpected {} | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: multiple implementations of this structure + --> tests/ui/impl.rs:94:1 + | +LL | impl Lifetime<'_> {} + | ^^^^^^^^^^^^^^^^^^^^ + | +note: first implementation here + --> tests/ui/impl.rs:93:1 + | +LL | impl Lifetime<'_> {} + | ^^^^^^^^^^^^^^^^^^^^ + +error: multiple implementations of this structure + --> tests/ui/impl.rs:98:1 + | +LL | impl<'a> Lifetime<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first implementation here + --> tests/ui/impl.rs:97:1 + | +LL | impl<'a> Lifetime<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: multiple implementations of this structure + --> tests/ui/impl.rs:110:1 + | +LL | impl Generic {} + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: first implementation here + --> tests/ui/impl.rs:109:1 + | +LL | impl Generic {} + | ^^^^^^^^^^^^^^^^^^^^^ + +error: multiple implementations of this structure + --> tests/ui/impl.rs:124:1 + | +LL | / impl GenericWithBounds { +LL | | +LL | | fn make_two(_two: T) -> Self { +LL | | todo!() +LL | | } +LL | | } + | |_^ + | +note: first implementation here + --> tests/ui/impl.rs:118:1 + | +LL | / impl GenericWithBounds { +LL | | fn make_one(_one: T) -> Self { +LL | | todo!() +LL | | } +LL | | } + | |_^ + +error: aborting due to 10 previous errors diff --git a/tests/ui/implicit_saturating_sub.fixed b/tests/ui/implicit_saturating_sub.fixed index 1aab6c54407e..22e59bbd2705 100644 --- a/tests/ui/implicit_saturating_sub.fixed +++ b/tests/ui/implicit_saturating_sub.fixed @@ -252,3 +252,11 @@ fn arbitrary_expression() { 0 }; } + +fn issue16307() { + let x: u8 = 100; + let y = 100_u8.saturating_sub(x); + //~^ implicit_saturating_sub + + println!("{y}"); +} diff --git a/tests/ui/implicit_saturating_sub.rs b/tests/ui/implicit_saturating_sub.rs index 7ca57a2902db..7fa19f0c8ad2 100644 --- a/tests/ui/implicit_saturating_sub.rs +++ b/tests/ui/implicit_saturating_sub.rs @@ -326,3 +326,11 @@ fn arbitrary_expression() { 0 }; } + +fn issue16307() { + let x: u8 = 100; + let y = if x >= 100 { 0 } else { 100 - x }; + //~^ implicit_saturating_sub + + println!("{y}"); +} diff --git a/tests/ui/implicit_saturating_sub.stderr b/tests/ui/implicit_saturating_sub.stderr index 0c225856fd07..2f3d2ba787e8 100644 --- a/tests/ui/implicit_saturating_sub.stderr +++ b/tests/ui/implicit_saturating_sub.stderr @@ -238,5 +238,11 @@ error: manual arithmetic check found LL | let _ = if a < b * 2 { 0 } else { a - b * 2 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b * 2)` -error: aborting due to 27 previous errors +error: manual arithmetic check found + --> tests/ui/implicit_saturating_sub.rs:332:13 + | +LL | let y = if x >= 100 { 0 } else { 100 - x }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `100_u8.saturating_sub(x)` + +error: aborting due to 28 previous errors diff --git a/tests/ui/iter_kv_map.fixed b/tests/ui/iter_kv_map.fixed index b18dda358877..189d76bc9431 100644 --- a/tests/ui/iter_kv_map.fixed +++ b/tests/ui/iter_kv_map.fixed @@ -189,3 +189,9 @@ fn issue14595() { let _ = map.as_ref().values().copied().collect::>(); //~^ iter_kv_map } + +fn issue16340() { + let hm: HashMap<&str, &str> = HashMap::new(); + let _ = hm.keys().map(|key| vec![key]); + //~^ iter_kv_map +} diff --git a/tests/ui/iter_kv_map.rs b/tests/ui/iter_kv_map.rs index 729e4e8a266c..cfc303447004 100644 --- a/tests/ui/iter_kv_map.rs +++ b/tests/ui/iter_kv_map.rs @@ -193,3 +193,9 @@ fn issue14595() { let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::>(); //~^ iter_kv_map } + +fn issue16340() { + let hm: HashMap<&str, &str> = HashMap::new(); + let _ = hm.iter().map(|(key, _)| vec![key]); + //~^ iter_kv_map +} diff --git a/tests/ui/iter_kv_map.stderr b/tests/ui/iter_kv_map.stderr index 8f73541f5033..866e69ea1922 100644 --- a/tests/ui/iter_kv_map.stderr +++ b/tests/ui/iter_kv_map.stderr @@ -269,5 +269,11 @@ error: iterating on a map's values LL | let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.as_ref().values()` -error: aborting due to 39 previous errors +error: iterating on a map's keys + --> tests/ui/iter_kv_map.rs:199:13 + | +LL | let _ = hm.iter().map(|(key, _)| vec![key]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hm.keys().map(|key| vec![key])` + +error: aborting due to 40 previous errors diff --git a/tests/ui/manual_div_ceil.fixed b/tests/ui/manual_div_ceil.fixed index cd91be87ec17..8ffd107dd42e 100644 --- a/tests/ui/manual_div_ceil.fixed +++ b/tests/ui/manual_div_ceil.fixed @@ -105,3 +105,32 @@ fn issue_15705(size: u64, c: &u64) { let _ = size.div_ceil(*c); //~^ manual_div_ceil } + +struct MyStruct(u32); +impl MyStruct { + // Method matching name on different type should not trigger lint + fn next_multiple_of(self, y: u32) -> u32 { + self.0.next_multiple_of(y) + } +} + +fn issue_16219() { + let x = 33u32; + + // Lint. + let _ = x.div_ceil(8); + //~^ manual_div_ceil + let _ = x.div_ceil(8); + //~^ manual_div_ceil + + let y = &x; + let _ = y.div_ceil(8); + //~^ manual_div_ceil + + // No lint. + let _ = x.next_multiple_of(8) / 7; + let _ = x.next_multiple_of(7) / 8; + + let z = MyStruct(x); + let _ = z.next_multiple_of(8) / 8; +} diff --git a/tests/ui/manual_div_ceil.rs b/tests/ui/manual_div_ceil.rs index 9899c7d775c2..859fb5a13c44 100644 --- a/tests/ui/manual_div_ceil.rs +++ b/tests/ui/manual_div_ceil.rs @@ -105,3 +105,32 @@ fn issue_15705(size: u64, c: &u64) { let _ = (size + c - 1) / c; //~^ manual_div_ceil } + +struct MyStruct(u32); +impl MyStruct { + // Method matching name on different type should not trigger lint + fn next_multiple_of(self, y: u32) -> u32 { + self.0.next_multiple_of(y) + } +} + +fn issue_16219() { + let x = 33u32; + + // Lint. + let _ = x.next_multiple_of(8) / 8; + //~^ manual_div_ceil + let _ = u32::next_multiple_of(x, 8) / 8; + //~^ manual_div_ceil + + let y = &x; + let _ = y.next_multiple_of(8) / 8; + //~^ manual_div_ceil + + // No lint. + let _ = x.next_multiple_of(8) / 7; + let _ = x.next_multiple_of(7) / 8; + + let z = MyStruct(x); + let _ = z.next_multiple_of(8) / 8; +} diff --git a/tests/ui/manual_div_ceil.stderr b/tests/ui/manual_div_ceil.stderr index 44de3ba99be7..0efc114c7078 100644 --- a/tests/ui/manual_div_ceil.stderr +++ b/tests/ui/manual_div_ceil.stderr @@ -131,5 +131,23 @@ error: manually reimplementing `div_ceil` LL | let _ = (size + c - 1) / c; | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `size.div_ceil(*c)` -error: aborting due to 20 previous errors +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:121:13 + | +LL | let _ = x.next_multiple_of(8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:123:13 + | +LL | let _ = u32::next_multiple_of(x, 8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:127:13 + | +LL | let _ = y.next_multiple_of(8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(8)` + +error: aborting due to 23 previous errors diff --git a/tests/ui/manual_div_ceil_with_feature.fixed b/tests/ui/manual_div_ceil_with_feature.fixed index f55999c5ad08..d77b8bc28986 100644 --- a/tests/ui/manual_div_ceil_with_feature.fixed +++ b/tests/ui/manual_div_ceil_with_feature.fixed @@ -84,3 +84,32 @@ fn issue_13950() { let _ = y.div_ceil(-7); //~^ manual_div_ceil } + +struct MyStruct(i32); +impl MyStruct { + // Method matching name on different type should not trigger lint + fn next_multiple_of(self, y: i32) -> i32 { + self.0.next_multiple_of(y) + } +} + +fn issue_16219() { + let x = 33i32; + + // Lint. + let _ = x.div_ceil(8); + //~^ manual_div_ceil + let _ = x.div_ceil(8); + //~^ manual_div_ceil + + let y = &x; + let _ = y.div_ceil(8); + //~^ manual_div_ceil + + // No lint. + let _ = x.next_multiple_of(8) / 7; + let _ = x.next_multiple_of(7) / 8; + + let z = MyStruct(x); + let _ = z.next_multiple_of(8) / 8; +} diff --git a/tests/ui/manual_div_ceil_with_feature.rs b/tests/ui/manual_div_ceil_with_feature.rs index 8a895f634cb4..5b9a4d9156a7 100644 --- a/tests/ui/manual_div_ceil_with_feature.rs +++ b/tests/ui/manual_div_ceil_with_feature.rs @@ -84,3 +84,32 @@ fn issue_13950() { let _ = (y - 8) / -7; //~^ manual_div_ceil } + +struct MyStruct(i32); +impl MyStruct { + // Method matching name on different type should not trigger lint + fn next_multiple_of(self, y: i32) -> i32 { + self.0.next_multiple_of(y) + } +} + +fn issue_16219() { + let x = 33i32; + + // Lint. + let _ = x.next_multiple_of(8) / 8; + //~^ manual_div_ceil + let _ = i32::next_multiple_of(x, 8) / 8; + //~^ manual_div_ceil + + let y = &x; + let _ = y.next_multiple_of(8) / 8; + //~^ manual_div_ceil + + // No lint. + let _ = x.next_multiple_of(8) / 7; + let _ = x.next_multiple_of(7) / 8; + + let z = MyStruct(x); + let _ = z.next_multiple_of(8) / 8; +} diff --git a/tests/ui/manual_div_ceil_with_feature.stderr b/tests/ui/manual_div_ceil_with_feature.stderr index e1160d962996..c5fa15112a87 100644 --- a/tests/ui/manual_div_ceil_with_feature.stderr +++ b/tests/ui/manual_div_ceil_with_feature.stderr @@ -139,5 +139,23 @@ error: manually reimplementing `div_ceil` LL | let _ = (y - 8) / -7; | ^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)` -error: aborting due to 23 previous errors +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:100:13 + | +LL | let _ = x.next_multiple_of(8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:102:13 + | +LL | let _ = i32::next_multiple_of(x, 8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:106:13 + | +LL | let _ = y.next_multiple_of(8) / 8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(8)` + +error: aborting due to 26 previous errors diff --git a/tests/ui/manual_ignore_case_cmp.fixed b/tests/ui/manual_ignore_case_cmp.fixed index cd7adc20b127..f0e413aaec0d 100644 --- a/tests/ui/manual_ignore_case_cmp.fixed +++ b/tests/ui/manual_ignore_case_cmp.fixed @@ -160,3 +160,23 @@ fn ref_osstring(a: OsString, b: &OsString) { b.eq_ignore_ascii_case(a); //~^ manual_ignore_case_cmp } + +fn wrongly_unmangled_macros(a: &str, b: &str) -> bool { + struct S<'a> { + inner: &'a str, + } + + let a = S { inner: a }; + let b = S { inner: b }; + + macro_rules! dot_inner { + ($s:expr) => { + $s.inner + }; + } + + dot_inner!(a).eq_ignore_ascii_case(dot_inner!(b)) + //~^ manual_ignore_case_cmp + || dot_inner!(a).eq_ignore_ascii_case("abc") + //~^ manual_ignore_case_cmp +} diff --git a/tests/ui/manual_ignore_case_cmp.rs b/tests/ui/manual_ignore_case_cmp.rs index 85f6719827c9..9802e87cd233 100644 --- a/tests/ui/manual_ignore_case_cmp.rs +++ b/tests/ui/manual_ignore_case_cmp.rs @@ -160,3 +160,23 @@ fn ref_osstring(a: OsString, b: &OsString) { b.to_ascii_lowercase() == a.to_ascii_lowercase(); //~^ manual_ignore_case_cmp } + +fn wrongly_unmangled_macros(a: &str, b: &str) -> bool { + struct S<'a> { + inner: &'a str, + } + + let a = S { inner: a }; + let b = S { inner: b }; + + macro_rules! dot_inner { + ($s:expr) => { + $s.inner + }; + } + + dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase() + //~^ manual_ignore_case_cmp + || dot_inner!(a).to_ascii_lowercase() == "abc" + //~^ manual_ignore_case_cmp +} diff --git a/tests/ui/manual_ignore_case_cmp.stderr b/tests/ui/manual_ignore_case_cmp.stderr index fa7fadd91076..2f698e076ed3 100644 --- a/tests/ui/manual_ignore_case_cmp.stderr +++ b/tests/ui/manual_ignore_case_cmp.stderr @@ -588,5 +588,29 @@ LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); LL + b.eq_ignore_ascii_case(a); | -error: aborting due to 49 previous errors +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:178:5 + | +LL | dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL - dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase() +LL + dot_inner!(a).eq_ignore_ascii_case(dot_inner!(b)) + | + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:180:12 + | +LL | || dot_inner!(a).to_ascii_lowercase() == "abc" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL - || dot_inner!(a).to_ascii_lowercase() == "abc" +LL + || dot_inner!(a).eq_ignore_ascii_case("abc") + | + +error: aborting due to 51 previous errors diff --git a/tests/ui/manual_ilog2.fixed b/tests/ui/manual_ilog2.fixed index a0f6d9392c30..ea86fc927c7c 100644 --- a/tests/ui/manual_ilog2.fixed +++ b/tests/ui/manual_ilog2.fixed @@ -30,3 +30,20 @@ fn foo(a: u32, b: u64) { external!($a.ilog(2)); with_span!(span; a.ilog(2)); } + +fn wrongly_unmangled_macros() { + struct S { + inner: u32, + } + + let x = S { inner: 42 }; + macro_rules! access { + ($s:expr) => { + $s.inner + }; + } + let log = access!(x).ilog2(); + //~^ manual_ilog2 + let log = access!(x).ilog2(); + //~^ manual_ilog2 +} diff --git a/tests/ui/manual_ilog2.rs b/tests/ui/manual_ilog2.rs index bd4b5d9d3c0d..8cb0e12d7361 100644 --- a/tests/ui/manual_ilog2.rs +++ b/tests/ui/manual_ilog2.rs @@ -30,3 +30,20 @@ fn foo(a: u32, b: u64) { external!($a.ilog(2)); with_span!(span; a.ilog(2)); } + +fn wrongly_unmangled_macros() { + struct S { + inner: u32, + } + + let x = S { inner: 42 }; + macro_rules! access { + ($s:expr) => { + $s.inner + }; + } + let log = 31 - access!(x).leading_zeros(); + //~^ manual_ilog2 + let log = access!(x).ilog(2); + //~^ manual_ilog2 +} diff --git a/tests/ui/manual_ilog2.stderr b/tests/ui/manual_ilog2.stderr index 7c9694f35330..d0ef8378081a 100644 --- a/tests/ui/manual_ilog2.stderr +++ b/tests/ui/manual_ilog2.stderr @@ -19,5 +19,17 @@ error: manually reimplementing `ilog2` LL | 63 - b.leading_zeros(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `b.ilog2()` -error: aborting due to 3 previous errors +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:45:15 + | +LL | let log = 31 - access!(x).leading_zeros(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `access!(x).ilog2()` + +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:47:15 + | +LL | let log = access!(x).ilog(2); + | ^^^^^^^^^^^^^^^^^^ help: try: `access!(x).ilog2()` + +error: aborting due to 5 previous errors diff --git a/tests/ui/manual_is_multiple_of.fixed b/tests/ui/manual_is_multiple_of.fixed index 03f75e725ed5..82e0684e5e57 100644 --- a/tests/ui/manual_is_multiple_of.fixed +++ b/tests/ui/manual_is_multiple_of.fixed @@ -101,3 +101,19 @@ mod issue15103 { (1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum() } } + +fn wrongly_unmangled_macros(a: u32, b: u32) { + struct Wrapper(u32); + let a = Wrapper(a); + let b = Wrapper(b); + macro_rules! dot_0 { + ($x:expr) => { + $x.0 + }; + } + + if dot_0!(a).is_multiple_of(dot_0!(b)) { + //~^ manual_is_multiple_of + todo!() + } +} diff --git a/tests/ui/manual_is_multiple_of.rs b/tests/ui/manual_is_multiple_of.rs index 7b6fa64c843d..82a492e24092 100644 --- a/tests/ui/manual_is_multiple_of.rs +++ b/tests/ui/manual_is_multiple_of.rs @@ -101,3 +101,19 @@ mod issue15103 { (1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum() } } + +fn wrongly_unmangled_macros(a: u32, b: u32) { + struct Wrapper(u32); + let a = Wrapper(a); + let b = Wrapper(b); + macro_rules! dot_0 { + ($x:expr) => { + $x.0 + }; + } + + if dot_0!(a) % dot_0!(b) == 0 { + //~^ manual_is_multiple_of + todo!() + } +} diff --git a/tests/ui/manual_is_multiple_of.stderr b/tests/ui/manual_is_multiple_of.stderr index 8523599ec402..3aba869c9111 100644 --- a/tests/ui/manual_is_multiple_of.stderr +++ b/tests/ui/manual_is_multiple_of.stderr @@ -67,5 +67,11 @@ error: manual implementation of `.is_multiple_of()` LL | let d = |n: u32| -> u32 { (1..=n / 2).filter(|i| n % i == 0).sum() }; | ^^^^^^^^^^ help: replace with: `n.is_multiple_of(*i)` -error: aborting due to 11 previous errors +error: manual implementation of `.is_multiple_of()` + --> tests/ui/manual_is_multiple_of.rs:115:8 + | +LL | if dot_0!(a) % dot_0!(b) == 0 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `dot_0!(a).is_multiple_of(dot_0!(b))` + +error: aborting due to 12 previous errors diff --git a/tests/ui/manual_ok_err.fixed b/tests/ui/manual_ok_err.fixed index 9b70ce0df43a..e22f91a0155f 100644 --- a/tests/ui/manual_ok_err.fixed +++ b/tests/ui/manual_ok_err.fixed @@ -127,3 +127,13 @@ mod issue15051 { result_with_ref_mut(x).as_mut().ok() } } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Ok::($val) + }; + } + + let _ = test_expr!(42).ok(); +} diff --git a/tests/ui/manual_ok_err.rs b/tests/ui/manual_ok_err.rs index dee904638245..c1355f0d4096 100644 --- a/tests/ui/manual_ok_err.rs +++ b/tests/ui/manual_ok_err.rs @@ -177,3 +177,17 @@ mod issue15051 { } } } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Ok::($val) + }; + } + + let _ = match test_expr!(42) { + //~^ manual_ok_err + Ok(v) => Some(v), + Err(_) => None, + }; +} diff --git a/tests/ui/manual_ok_err.stderr b/tests/ui/manual_ok_err.stderr index 448fbffc0509..0c2ed368eb97 100644 --- a/tests/ui/manual_ok_err.stderr +++ b/tests/ui/manual_ok_err.stderr @@ -141,5 +141,16 @@ LL | | Err(_) => None, LL | | } | |_________^ help: replace with: `result_with_ref_mut(x).as_mut().ok()` -error: aborting due to 12 previous errors +error: manual implementation of `ok` + --> tests/ui/manual_ok_err.rs:188:13 + | +LL | let _ = match test_expr!(42) { + | _____________^ +LL | | +LL | | Ok(v) => Some(v), +LL | | Err(_) => None, +LL | | }; + | |_____^ help: replace with: `test_expr!(42).ok()` + +error: aborting due to 13 previous errors diff --git a/tests/ui/match_as_ref.fixed b/tests/ui/match_as_ref.fixed index 09a6ed169390..b1b8ffb885f5 100644 --- a/tests/ui/match_as_ref.fixed +++ b/tests/ui/match_as_ref.fixed @@ -90,3 +90,13 @@ fn issue15932() { let _: Option<&dyn std::fmt::Debug> = Some(0).as_ref().map(|x| x as _); } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Some($val) + }; + } + + let _: Option<&u32> = test_expr!(42).as_ref(); +} diff --git a/tests/ui/match_as_ref.rs b/tests/ui/match_as_ref.rs index 347b6d186887..3113167957d4 100644 --- a/tests/ui/match_as_ref.rs +++ b/tests/ui/match_as_ref.rs @@ -114,3 +114,17 @@ fn issue15932() { Some(ref mut v) => Some(v), }; } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Some($val) + }; + } + + let _: Option<&u32> = match test_expr!(42) { + //~^ match_as_ref + None => None, + Some(ref v) => Some(v), + }; +} diff --git a/tests/ui/match_as_ref.stderr b/tests/ui/match_as_ref.stderr index df06e358f296..3eab499fe409 100644 --- a/tests/ui/match_as_ref.stderr +++ b/tests/ui/match_as_ref.stderr @@ -127,5 +127,26 @@ LL - }; LL + let _: Option<&dyn std::fmt::Debug> = Some(0).as_ref().map(|x| x as _); | -error: aborting due to 6 previous errors +error: manual implementation of `Option::as_ref` + --> tests/ui/match_as_ref.rs:125:27 + | +LL | let _: Option<&u32> = match test_expr!(42) { + | ___________________________^ +LL | | +LL | | None => None, +LL | | Some(ref v) => Some(v), +LL | | }; + | |_____^ + | +help: use `Option::as_ref()` directly + | +LL - let _: Option<&u32> = match test_expr!(42) { +LL - +LL - None => None, +LL - Some(ref v) => Some(v), +LL - }; +LL + let _: Option<&u32> = test_expr!(42).as_ref(); + | + +error: aborting due to 7 previous errors diff --git a/tests/ui/match_bool.fixed b/tests/ui/match_bool.fixed index 876ae935afde..3d5d0a0d532c 100644 --- a/tests/ui/match_bool.fixed +++ b/tests/ui/match_bool.fixed @@ -74,4 +74,15 @@ fn issue15351() { } } +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + ($val + 1) > 0 + }; + } + + let x = 5; + if test_expr!(x) { 1 } else { 0 }; +} + fn main() {} diff --git a/tests/ui/match_bool.rs b/tests/ui/match_bool.rs index a134ad8346e2..4db0aedf3260 100644 --- a/tests/ui/match_bool.rs +++ b/tests/ui/match_bool.rs @@ -126,4 +126,19 @@ fn issue15351() { } } +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + ($val + 1) > 0 + }; + } + + let x = 5; + match test_expr!(x) { + //~^ match_bool + true => 1, + false => 0, + }; +} + fn main() {} diff --git a/tests/ui/match_bool.stderr b/tests/ui/match_bool.stderr index c05742e56339..223acd17aead 100644 --- a/tests/ui/match_bool.stderr +++ b/tests/ui/match_bool.stderr @@ -183,5 +183,15 @@ LL + break 'a; LL + } } | -error: aborting due to 13 previous errors +error: `match` on a boolean expression + --> tests/ui/match_bool.rs:137:5 + | +LL | / match test_expr!(x) { +LL | | +LL | | true => 1, +LL | | false => 0, +LL | | }; + | |_____^ help: consider using an `if`/`else` expression: `if test_expr!(x) { 1 } else { 0 }` + +error: aborting due to 14 previous errors diff --git a/tests/ui/mutex_atomic.fixed b/tests/ui/mutex_atomic.fixed index e4218726019f..dc05d8a2c61f 100644 --- a/tests/ui/mutex_atomic.fixed +++ b/tests/ui/mutex_atomic.fixed @@ -65,3 +65,15 @@ fn issue13378() { let (funky_mtx) = std::sync::atomic::AtomicU64::new(0); //~^ mutex_integer } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + ($val > 0 && true) + }; + } + + let _ = std::sync::atomic::AtomicBool::new(test_expr!(1)); + //~^ mutex_atomic + // The suggestion should preserve the macro call: `AtomicBool::new(test_expr!(true))` +} diff --git a/tests/ui/mutex_atomic.rs b/tests/ui/mutex_atomic.rs index 95f2b135903f..33745f8fc5e1 100644 --- a/tests/ui/mutex_atomic.rs +++ b/tests/ui/mutex_atomic.rs @@ -65,3 +65,15 @@ fn issue13378() { let (funky_mtx): Mutex = Mutex::new(0); //~^ mutex_integer } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + ($val > 0 && true) + }; + } + + let _ = Mutex::new(test_expr!(1)); + //~^ mutex_atomic + // The suggestion should preserve the macro call: `AtomicBool::new(test_expr!(true))` +} diff --git a/tests/ui/mutex_atomic.stderr b/tests/ui/mutex_atomic.stderr index 0afc6d541dea..56d94035583c 100644 --- a/tests/ui/mutex_atomic.stderr +++ b/tests/ui/mutex_atomic.stderr @@ -130,5 +130,13 @@ LL - let (funky_mtx): Mutex = Mutex::new(0); LL + let (funky_mtx) = std::sync::atomic::AtomicU64::new(0); | -error: aborting due to 14 previous errors +error: using a `Mutex` where an atomic would do + --> tests/ui/mutex_atomic.rs:76:13 + | +LL | let _ = Mutex::new(test_expr!(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::sync::atomic::AtomicBool::new(test_expr!(1))` + | + = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>` + +error: aborting due to 15 previous errors diff --git a/tests/ui/needless_bool_assign.fixed b/tests/ui/needless_bool_assign.fixed index d6fab4c51b53..8fd572038140 100644 --- a/tests/ui/needless_bool_assign.fixed +++ b/tests/ui/needless_bool_assign.fixed @@ -42,3 +42,22 @@ fn issue15063(x: bool, y: bool) { } else { z = x || y; } //~^^^^^ needless_bool_assign } + +fn wrongly_unmangled_macros(must_keep: fn(usize, usize) -> bool, x: usize, y: usize) { + struct Wrapper(T); + let mut skip = Wrapper(false); + + macro_rules! invoke { + ($func:expr, $a:expr, $b:expr) => { + $func($a, $b) + }; + } + macro_rules! dot_0 { + ($w:expr) => { + $w.0 + }; + } + + dot_0!(skip) = !invoke!(must_keep, x, y); + //~^^^^^ needless_bool_assign +} diff --git a/tests/ui/needless_bool_assign.rs b/tests/ui/needless_bool_assign.rs index c504f61f4dd1..4721ab433b32 100644 --- a/tests/ui/needless_bool_assign.rs +++ b/tests/ui/needless_bool_assign.rs @@ -58,3 +58,26 @@ fn issue15063(x: bool, y: bool) { } //~^^^^^ needless_bool_assign } + +fn wrongly_unmangled_macros(must_keep: fn(usize, usize) -> bool, x: usize, y: usize) { + struct Wrapper(T); + let mut skip = Wrapper(false); + + macro_rules! invoke { + ($func:expr, $a:expr, $b:expr) => { + $func($a, $b) + }; + } + macro_rules! dot_0 { + ($w:expr) => { + $w.0 + }; + } + + if invoke!(must_keep, x, y) { + dot_0!(skip) = false; + } else { + dot_0!(skip) = true; + } + //~^^^^^ needless_bool_assign +} diff --git a/tests/ui/needless_bool_assign.stderr b/tests/ui/needless_bool_assign.stderr index 1d09b8b25a09..34ff782f34a3 100644 --- a/tests/ui/needless_bool_assign.stderr +++ b/tests/ui/needless_bool_assign.stderr @@ -62,5 +62,15 @@ LL | | z = false; LL | | } | |_____^ help: you can reduce it to: `{ z = x || y; }` -error: aborting due to 5 previous errors +error: this if-then-else expression assigns a bool literal + --> tests/ui/needless_bool_assign.rs:77:5 + | +LL | / if invoke!(must_keep, x, y) { +LL | | dot_0!(skip) = false; +LL | | } else { +LL | | dot_0!(skip) = true; +LL | | } + | |_____^ help: you can reduce it to: `dot_0!(skip) = !invoke!(must_keep, x, y);` + +error: aborting due to 6 previous errors diff --git a/tests/ui/needless_for_each_fixable.fixed b/tests/ui/needless_for_each_fixable.fixed index a6d64d9afc1a..19b34f42af24 100644 --- a/tests/ui/needless_for_each_fixable.fixed +++ b/tests/ui/needless_for_each_fixable.fixed @@ -149,3 +149,11 @@ fn issue15256() { for v in vec.iter() { println!("{v}"); } //~^ needless_for_each } + +fn issue16294() { + let vec: Vec = Vec::new(); + for elem in vec.iter() { + //~^ needless_for_each + println!("{elem}"); + } +} diff --git a/tests/ui/needless_for_each_fixable.rs b/tests/ui/needless_for_each_fixable.rs index 7e74d2b428fd..f04e2555a370 100644 --- a/tests/ui/needless_for_each_fixable.rs +++ b/tests/ui/needless_for_each_fixable.rs @@ -149,3 +149,11 @@ fn issue15256() { vec.iter().for_each(|v| println!("{v}")); //~^ needless_for_each } + +fn issue16294() { + let vec: Vec = Vec::new(); + vec.iter().for_each(|elem| { + //~^ needless_for_each + println!("{elem}"); + }) +} diff --git a/tests/ui/needless_for_each_fixable.stderr b/tests/ui/needless_for_each_fixable.stderr index 204cfa36b022..121669d15072 100644 --- a/tests/ui/needless_for_each_fixable.stderr +++ b/tests/ui/needless_for_each_fixable.stderr @@ -154,5 +154,22 @@ error: needless use of `for_each` LL | vec.iter().for_each(|v| println!("{v}")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in vec.iter() { println!("{v}"); }` -error: aborting due to 11 previous errors +error: needless use of `for_each` + --> tests/ui/needless_for_each_fixable.rs:155:5 + | +LL | / vec.iter().for_each(|elem| { +LL | | +LL | | println!("{elem}"); +LL | | }) + | |______^ + | +help: try + | +LL ~ for elem in vec.iter() { +LL + +LL + println!("{elem}"); +LL + } + | + +error: aborting due to 12 previous errors diff --git a/tests/ui/never_loop_iterator_reduction.rs b/tests/ui/never_loop_iterator_reduction.rs index 6b07b91db29a..27f1766b841d 100644 --- a/tests/ui/never_loop_iterator_reduction.rs +++ b/tests/ui/never_loop_iterator_reduction.rs @@ -1,8 +1,9 @@ //@no-rustfix #![warn(clippy::never_loop)] +#![expect(clippy::needless_return)] fn main() { - // diverging closure: should trigger + // diverging closure with no `return`: should trigger [0, 1].into_iter().for_each(|x| { //~^ never_loop @@ -14,4 +15,10 @@ fn main() { [0, 1].into_iter().for_each(|x| { let _ = x + 1; }); + + // `return` should NOT trigger even though it is diverging + [0, 1].into_iter().for_each(|x| { + println!("x = {x}"); + return; + }); } diff --git a/tests/ui/never_loop_iterator_reduction.stderr b/tests/ui/never_loop_iterator_reduction.stderr index b76ee283146c..92483c85432d 100644 --- a/tests/ui/never_loop_iterator_reduction.stderr +++ b/tests/ui/never_loop_iterator_reduction.stderr @@ -1,5 +1,5 @@ error: this iterator reduction never loops (closure always diverges) - --> tests/ui/never_loop_iterator_reduction.rs:6:5 + --> tests/ui/never_loop_iterator_reduction.rs:7:5 | LL | / [0, 1].into_iter().for_each(|x| { LL | | diff --git a/tests/ui/new_without_default.fixed b/tests/ui/new_without_default.fixed index 9a5e90b48065..f6591820feeb 100644 --- a/tests/ui/new_without_default.fixed +++ b/tests/ui/new_without_default.fixed @@ -409,3 +409,58 @@ mod issue15778 { } } } + +pub mod issue16255 { + use std::fmt::Display; + use std::marker::PhantomData; + + pub struct Foo { + marker: PhantomData, + } + + impl Default for Foo + where + T: Display, + T: Clone, + { + fn default() -> Self { + Self::new() + } + } + + impl Foo + where + T: Display, + { + pub fn new() -> Self + //~^ new_without_default + where + T: Clone, + { + Self { marker: PhantomData } + } + } + + pub struct Bar { + marker: PhantomData, + } + + impl Default for Bar + where + T: Clone, + { + fn default() -> Self { + Self::new() + } + } + + impl Bar { + pub fn new() -> Self + //~^ new_without_default + where + T: Clone, + { + Self { marker: PhantomData } + } + } +} diff --git a/tests/ui/new_without_default.rs b/tests/ui/new_without_default.rs index f7466aa32189..d3447f2e16b2 100644 --- a/tests/ui/new_without_default.rs +++ b/tests/ui/new_without_default.rs @@ -324,3 +324,39 @@ mod issue15778 { } } } + +pub mod issue16255 { + use std::fmt::Display; + use std::marker::PhantomData; + + pub struct Foo { + marker: PhantomData, + } + + impl Foo + where + T: Display, + { + pub fn new() -> Self + //~^ new_without_default + where + T: Clone, + { + Self { marker: PhantomData } + } + } + + pub struct Bar { + marker: PhantomData, + } + + impl Bar { + pub fn new() -> Self + //~^ new_without_default + where + T: Clone, + { + Self { marker: PhantomData } + } + } +} diff --git a/tests/ui/new_without_default.stderr b/tests/ui/new_without_default.stderr index 0593dbb00fb6..6c0f73d13185 100644 --- a/tests/ui/new_without_default.stderr +++ b/tests/ui/new_without_default.stderr @@ -250,5 +250,58 @@ LL + } LL + } | -error: aborting due to 13 previous errors +error: you should consider adding a `Default` implementation for `Foo` + --> tests/ui/new_without_default.rs:340:9 + | +LL | / pub fn new() -> Self +LL | | +LL | | where +LL | | T: Clone, +LL | | { +LL | | Self { marker: PhantomData } +LL | | } + | |_________^ + | +help: try adding this + | +LL ~ impl Default for Foo +LL + where +LL + T: Display, +LL + T: Clone, +LL + { +LL + fn default() -> Self { +LL + Self::new() +LL + } +LL + } +LL + +LL ~ impl Foo + | + +error: you should consider adding a `Default` implementation for `Bar` + --> tests/ui/new_without_default.rs:354:9 + | +LL | / pub fn new() -> Self +LL | | +LL | | where +LL | | T: Clone, +LL | | { +LL | | Self { marker: PhantomData } +LL | | } + | |_________^ + | +help: try adding this + | +LL ~ impl Default for Bar +LL + where +LL + T: Clone, +LL + { +LL + fn default() -> Self { +LL + Self::new() +LL + } +LL + } +LL + +LL ~ impl Bar { + | + +error: aborting due to 15 previous errors diff --git a/tests/ui/question_mark.fixed b/tests/ui/question_mark.fixed index 2c5ee0245038..b8072932c4ea 100644 --- a/tests/ui/question_mark.fixed +++ b/tests/ui/question_mark.fixed @@ -1,5 +1,5 @@ #![feature(try_blocks)] -#![allow(clippy::unnecessary_wraps)] +#![allow(clippy::unnecessary_wraps, clippy::no_effect)] use std::sync::MutexGuard; @@ -500,3 +500,18 @@ mod issue14894 { Ok(()) } } + +fn wrongly_unmangled_macros() -> Option { + macro_rules! test_expr { + ($val:expr) => { + Some($val) + }; + } + + let x = test_expr!(42)?; + //~^^^ question_mark + Some(x); + + test_expr!(42)?; + test_expr!(42) +} diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs index b9ff9d1565b2..b320dcd4b0bc 100644 --- a/tests/ui/question_mark.rs +++ b/tests/ui/question_mark.rs @@ -1,5 +1,5 @@ #![feature(try_blocks)] -#![allow(clippy::unnecessary_wraps)] +#![allow(clippy::unnecessary_wraps, clippy::no_effect)] use std::sync::MutexGuard; @@ -615,3 +615,23 @@ mod issue14894 { Ok(()) } } + +fn wrongly_unmangled_macros() -> Option { + macro_rules! test_expr { + ($val:expr) => { + Some($val) + }; + } + + let Some(x) = test_expr!(42) else { + return None; + }; + //~^^^ question_mark + Some(x); + + if test_expr!(42).is_none() { + //~^ question_mark + return None; + } + test_expr!(42) +} diff --git a/tests/ui/question_mark.stderr b/tests/ui/question_mark.stderr index 9b2896328e66..d645c8830adc 100644 --- a/tests/ui/question_mark.stderr +++ b/tests/ui/question_mark.stderr @@ -333,5 +333,22 @@ LL | | return Err(reason); LL | | } | |_________^ help: replace it with: `result?;` -error: aborting due to 35 previous errors +error: this `let...else` may be rewritten with the `?` operator + --> tests/ui/question_mark.rs:626:5 + | +LL | / let Some(x) = test_expr!(42) else { +LL | | return None; +LL | | }; + | |______^ help: replace it with: `let x = test_expr!(42)?;` + +error: this block may be rewritten with the `?` operator + --> tests/ui/question_mark.rs:632:5 + | +LL | / if test_expr!(42).is_none() { +LL | | +LL | | return None; +LL | | } + | |_____^ help: replace it with: `test_expr!(42)?;` + +error: aborting due to 37 previous errors diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed index 08903ef7fdda..b44009446640 100644 --- a/tests/ui/redundant_pattern_matching_option.fixed +++ b/tests/ui/redundant_pattern_matching_option.fixed @@ -195,3 +195,16 @@ fn issue16045() { } } } + +fn issue14989() { + macro_rules! x { + () => { + None:: + }; + } + + if x! {}.is_some() {}; + //~^ redundant_pattern_matching + while x! {}.is_some() {} + //~^ redundant_pattern_matching +} diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs index 95eff3f9ebf9..c13cf993e786 100644 --- a/tests/ui/redundant_pattern_matching_option.rs +++ b/tests/ui/redundant_pattern_matching_option.rs @@ -231,3 +231,16 @@ fn issue16045() { } } } + +fn issue14989() { + macro_rules! x { + () => { + None:: + }; + } + + if let Some(_) = (x! {}) {}; + //~^ redundant_pattern_matching + while let Some(_) = (x! {}) {} + //~^ redundant_pattern_matching +} diff --git a/tests/ui/redundant_pattern_matching_option.stderr b/tests/ui/redundant_pattern_matching_option.stderr index 6fd0c5a6f859..5c9edfd4c50a 100644 --- a/tests/ui/redundant_pattern_matching_option.stderr +++ b/tests/ui/redundant_pattern_matching_option.stderr @@ -236,5 +236,17 @@ error: redundant pattern matching, consider using `is_some()` LL | if let Some(_) = x.await { | -------^^^^^^^---------- help: try: `if x.await.is_some()` -error: aborting due to 33 previous errors +error: redundant pattern matching, consider using `is_some()` + --> tests/ui/redundant_pattern_matching_option.rs:242:12 + | +LL | if let Some(_) = (x! {}) {}; + | -------^^^^^^^---------- help: try: `if x! {}.is_some()` + +error: redundant pattern matching, consider using `is_some()` + --> tests/ui/redundant_pattern_matching_option.rs:244:15 + | +LL | while let Some(_) = (x! {}) {} + | ----------^^^^^^^---------- help: try: `while x! {}.is_some()` + +error: aborting due to 35 previous errors diff --git a/tests/ui/redundant_pattern_matching_result.fixed b/tests/ui/redundant_pattern_matching_result.fixed index 261d82fc35c8..8754d71aa629 100644 --- a/tests/ui/redundant_pattern_matching_result.fixed +++ b/tests/ui/redundant_pattern_matching_result.fixed @@ -165,3 +165,23 @@ fn issue10803() { // Don't lint let _ = matches!(x, Err(16)); } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Ok::($val) + }; + } + + let _ = test_expr!(42).is_ok(); + + macro_rules! test_guard { + ($val:expr) => { + ($val + 1) > 0 + }; + } + + let x: Result = Ok(42); + let _ = x.is_ok() && test_guard!(42); + //~^ redundant_pattern_matching +} diff --git a/tests/ui/redundant_pattern_matching_result.rs b/tests/ui/redundant_pattern_matching_result.rs index 6cae4cc4b6b0..b83b02588fb6 100644 --- a/tests/ui/redundant_pattern_matching_result.rs +++ b/tests/ui/redundant_pattern_matching_result.rs @@ -205,3 +205,27 @@ fn issue10803() { // Don't lint let _ = matches!(x, Err(16)); } + +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($val:expr) => { + Ok::($val) + }; + } + + let _ = match test_expr!(42) { + //~^ redundant_pattern_matching + Ok(_) => true, + Err(_) => false, + }; + + macro_rules! test_guard { + ($val:expr) => { + ($val + 1) > 0 + }; + } + + let x: Result = Ok(42); + let _ = matches!(x, Ok(_) if test_guard!(42)); + //~^ redundant_pattern_matching +} diff --git a/tests/ui/redundant_pattern_matching_result.stderr b/tests/ui/redundant_pattern_matching_result.stderr index 7e7d27d07a7f..dda203b753c3 100644 --- a/tests/ui/redundant_pattern_matching_result.stderr +++ b/tests/ui/redundant_pattern_matching_result.stderr @@ -209,5 +209,22 @@ error: redundant pattern matching, consider using `is_err()` LL | let _ = matches!(x, Err(_)); | ^^^^^^^^^^^^^^^^^^^ help: try: `x.is_err()` -error: aborting due to 28 previous errors +error: redundant pattern matching, consider using `is_ok()` + --> tests/ui/redundant_pattern_matching_result.rs:216:13 + | +LL | let _ = match test_expr!(42) { + | _____________^ +LL | | +LL | | Ok(_) => true, +LL | | Err(_) => false, +LL | | }; + | |_____^ help: try: `test_expr!(42).is_ok()` + +error: redundant pattern matching, consider using `is_ok()` + --> tests/ui/redundant_pattern_matching_result.rs:229:13 + | +LL | let _ = matches!(x, Ok(_) if test_guard!(42)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_ok() && test_guard!(42)` + +error: aborting due to 30 previous errors diff --git a/tests/ui/single_range_in_vec_init_unfixable.rs b/tests/ui/single_range_in_vec_init_unfixable.rs new file mode 100644 index 000000000000..33378b386f34 --- /dev/null +++ b/tests/ui/single_range_in_vec_init_unfixable.rs @@ -0,0 +1,12 @@ +//@no-rustfix +#![warn(clippy::single_range_in_vec_init)] + +use std::ops::Range; + +fn issue16306(v: &[i32]) { + fn takes_range_slice(_: &[Range]) {} + + let len = v.len(); + takes_range_slice(&[0..len as i64]); + //~^ single_range_in_vec_init +} diff --git a/tests/ui/single_range_in_vec_init_unfixable.stderr b/tests/ui/single_range_in_vec_init_unfixable.stderr new file mode 100644 index 000000000000..b10af21ed21c --- /dev/null +++ b/tests/ui/single_range_in_vec_init_unfixable.stderr @@ -0,0 +1,16 @@ +error: an array of `Range` that is only one element + --> tests/ui/single_range_in_vec_init_unfixable.rs:10:24 + | +LL | takes_range_slice(&[0..len as i64]); + | ^^^^^^^^^^^^^^^ + | + = note: `-D clippy::single-range-in-vec-init` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::single_range_in_vec_init)]` +help: if you wanted a `Vec` that contains the entire range, try + | +LL - takes_range_slice(&[0..len as i64]); +LL + takes_range_slice(&(0..len as i64).collect::>()); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/str_to_string.fixed b/tests/ui/str_to_string.fixed index 2941c4dbd33d..8713c4f9bc86 100644 --- a/tests/ui/str_to_string.fixed +++ b/tests/ui/str_to_string.fixed @@ -8,3 +8,17 @@ fn main() { msg.to_owned(); //~^ str_to_string } + +fn issue16271(key: &[u8]) { + macro_rules! t { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + } + }; + } + + let _value = t!(str::from_utf8(key)).to_owned(); + //~^ str_to_string +} diff --git a/tests/ui/str_to_string.rs b/tests/ui/str_to_string.rs index 4c4d2bb18062..b81759e1037b 100644 --- a/tests/ui/str_to_string.rs +++ b/tests/ui/str_to_string.rs @@ -8,3 +8,17 @@ fn main() { msg.to_string(); //~^ str_to_string } + +fn issue16271(key: &[u8]) { + macro_rules! t { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + } + }; + } + + let _value = t!(str::from_utf8(key)).to_string(); + //~^ str_to_string +} diff --git a/tests/ui/str_to_string.stderr b/tests/ui/str_to_string.stderr index cb7b6b48843a..c0a38c8ebe46 100644 --- a/tests/ui/str_to_string.stderr +++ b/tests/ui/str_to_string.stderr @@ -13,5 +13,11 @@ error: `to_string()` called on a `&str` LL | msg.to_string(); | ^^^^^^^^^^^^^^^ help: try: `msg.to_owned()` -error: aborting due to 2 previous errors +error: `to_string()` called on a `&str` + --> tests/ui/str_to_string.rs:22:18 + | +LL | let _value = t!(str::from_utf8(key)).to_string(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t!(str::from_utf8(key)).to_owned()` + +error: aborting due to 3 previous errors diff --git a/tests/ui/string_from_utf8_as_bytes.fixed b/tests/ui/string_from_utf8_as_bytes.fixed index 193217114d88..98fa3a4fcf70 100644 --- a/tests/ui/string_from_utf8_as_bytes.fixed +++ b/tests/ui/string_from_utf8_as_bytes.fixed @@ -1,6 +1,16 @@ #![warn(clippy::string_from_utf8_as_bytes)] +macro_rules! test_range { + ($start:expr, $end:expr) => { + $start..$end + }; +} + fn main() { let _ = Some(&"Hello World!"[6..11]); //~^ string_from_utf8_as_bytes + + let s = "Hello World!"; + let _ = Some(&s[test_range!(6, 11)]); + //~^ string_from_utf8_as_bytes } diff --git a/tests/ui/string_from_utf8_as_bytes.rs b/tests/ui/string_from_utf8_as_bytes.rs index 49beb19ee40f..6354d5376ad6 100644 --- a/tests/ui/string_from_utf8_as_bytes.rs +++ b/tests/ui/string_from_utf8_as_bytes.rs @@ -1,6 +1,16 @@ #![warn(clippy::string_from_utf8_as_bytes)] +macro_rules! test_range { + ($start:expr, $end:expr) => { + $start..$end + }; +} + fn main() { let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]); //~^ string_from_utf8_as_bytes + + let s = "Hello World!"; + let _ = std::str::from_utf8(&s.as_bytes()[test_range!(6, 11)]); + //~^ string_from_utf8_as_bytes } diff --git a/tests/ui/string_from_utf8_as_bytes.stderr b/tests/ui/string_from_utf8_as_bytes.stderr index 99c8d8ae4eab..bba9ec0caf19 100644 --- a/tests/ui/string_from_utf8_as_bytes.stderr +++ b/tests/ui/string_from_utf8_as_bytes.stderr @@ -1,5 +1,5 @@ error: calling a slice of `as_bytes()` with `from_utf8` should be not necessary - --> tests/ui/string_from_utf8_as_bytes.rs:4:13 + --> tests/ui/string_from_utf8_as_bytes.rs:10:13 | LL | let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&"Hello World!"[6..11])` @@ -7,5 +7,11 @@ LL | let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]); = note: `-D clippy::string-from-utf8-as-bytes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::string_from_utf8_as_bytes)]` -error: aborting due to 1 previous error +error: calling a slice of `as_bytes()` with `from_utf8` should be not necessary + --> tests/ui/string_from_utf8_as_bytes.rs:14:13 + | +LL | let _ = std::str::from_utf8(&s.as_bytes()[test_range!(6, 11)]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&s[test_range!(6, 11)])` + +error: aborting due to 2 previous errors diff --git a/tests/ui/transmuting_null.rs b/tests/ui/transmuting_null.rs index 0d3b26673452..00aa35dff803 100644 --- a/tests/ui/transmuting_null.rs +++ b/tests/ui/transmuting_null.rs @@ -37,8 +37,19 @@ fn transmute_const_int() { } } +fn transumute_single_expr_blocks() { + unsafe { + let _: &u64 = std::mem::transmute({ 0 as *const u64 }); + //~^ transmuting_null + + let _: &u64 = std::mem::transmute(const { u64::MIN as *const u64 }); + //~^ transmuting_null + } +} + fn main() { one_liners(); transmute_const(); transmute_const_int(); + transumute_single_expr_blocks(); } diff --git a/tests/ui/transmuting_null.stderr b/tests/ui/transmuting_null.stderr index ed7c3396a243..e1de391813bd 100644 --- a/tests/ui/transmuting_null.stderr +++ b/tests/ui/transmuting_null.stderr @@ -25,5 +25,17 @@ error: transmuting a known null pointer into a reference LL | let _: &u64 = std::mem::transmute(u64::MIN as *const u64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: transmuting a known null pointer into a reference + --> tests/ui/transmuting_null.rs:42:23 + | +LL | let _: &u64 = std::mem::transmute({ 0 as *const u64 }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmuting a known null pointer into a reference + --> tests/ui/transmuting_null.rs:45:23 + | +LL | let _: &u64 = std::mem::transmute(const { u64::MIN as *const u64 }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors diff --git a/tests/ui/unnecessary_fold.fixed b/tests/ui/unnecessary_fold.fixed index c3eeafbc39cd..d51359349cb9 100644 --- a/tests/ui/unnecessary_fold.fixed +++ b/tests/ui/unnecessary_fold.fixed @@ -178,4 +178,15 @@ fn issue10000() { } } +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($e:expr) => { + ($e + 1) > 2 + }; + } + + let _ = (0..3).any(|x| test_expr!(x)); + //~^ unnecessary_fold +} + fn main() {} diff --git a/tests/ui/unnecessary_fold.rs b/tests/ui/unnecessary_fold.rs index 6ab41a942625..c6eb7157ab12 100644 --- a/tests/ui/unnecessary_fold.rs +++ b/tests/ui/unnecessary_fold.rs @@ -178,4 +178,15 @@ fn issue10000() { } } +fn wrongly_unmangled_macros() { + macro_rules! test_expr { + ($e:expr) => { + ($e + 1) > 2 + }; + } + + let _ = (0..3).fold(false, |acc: bool, x| acc || test_expr!(x)); + //~^ unnecessary_fold +} + fn main() {} diff --git a/tests/ui/unnecessary_fold.stderr b/tests/ui/unnecessary_fold.stderr index bb8aa7e18d34..560427a681a9 100644 --- a/tests/ui/unnecessary_fold.stderr +++ b/tests/ui/unnecessary_fold.stderr @@ -4,6 +4,7 @@ error: this `.fold` can be written more succinctly using another method LL | let _ = (0..3).fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` | + = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects = note: `-D clippy::unnecessary-fold` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fold)]` @@ -21,6 +22,8 @@ error: this `.fold` can be written more succinctly using another method | LL | let _ = (0..3).fold(true, |acc, x| acc && x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `all(|x| x > 2)` + | + = note: the `all` method is short circuiting and may change the program semantics if the iterator has side effects error: this `.fold` can be written more succinctly using another method --> tests/ui/unnecessary_fold.rs:24:25 @@ -63,12 +66,16 @@ error: this `.fold` can be written more succinctly using another method | LL | let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` + | + = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects error: this `.fold` can be written more succinctly using another method --> tests/ui/unnecessary_fold.rs:110:10 | LL | .fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` + | + = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects error: this `.fold` can be written more succinctly using another method --> tests/ui/unnecessary_fold.rs:123:33 @@ -196,5 +203,13 @@ error: this `.fold` can be written more succinctly using another method LL | (0..3).fold(1, |acc, x| acc * x) | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` -error: aborting due to 32 previous errors +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:188:20 + | +LL | let _ = (0..3).fold(false, |acc: bool, x| acc || test_expr!(x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| test_expr!(x))` + | + = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects + +error: aborting due to 33 previous errors diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed index 316eac0b58b7..590359bc1ad2 100644 --- a/tests/ui/unnecessary_to_owned.fixed +++ b/tests/ui/unnecessary_to_owned.fixed @@ -681,3 +681,12 @@ fn issue14833() { let mut s = HashSet::<&String>::new(); s.remove(&"hello".to_owned()); } + +#[allow(clippy::redundant_clone)] +fn issue16351() { + fn take(_: impl AsRef) {} + + let dot = "."; + take(&format!("ouch{dot}")); + //~^ unnecessary_to_owned +} diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs index f2dbd1db3c9f..d1e3e6497c0a 100644 --- a/tests/ui/unnecessary_to_owned.rs +++ b/tests/ui/unnecessary_to_owned.rs @@ -681,3 +681,12 @@ fn issue14833() { let mut s = HashSet::<&String>::new(); s.remove(&"hello".to_owned()); } + +#[allow(clippy::redundant_clone)] +fn issue16351() { + fn take(_: impl AsRef) {} + + let dot = "."; + take(format!("ouch{dot}").to_string()); + //~^ unnecessary_to_owned +} diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr index 6c52be839301..50e3d5eb2195 100644 --- a/tests/ui/unnecessary_to_owned.stderr +++ b/tests/ui/unnecessary_to_owned.stderr @@ -550,5 +550,11 @@ error: unnecessary use of `to_vec` LL | s.remove(&(&["b"]).to_vec()); | ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()` -error: aborting due to 82 previous errors +error: unnecessary use of `to_string` + --> tests/ui/unnecessary_to_owned.rs:690:10 + | +LL | take(format!("ouch{dot}").to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `&format!("ouch{dot}")` + +error: aborting due to 83 previous errors diff --git a/tests/ui/useless_conversion.fixed b/tests/ui/useless_conversion.fixed index adf5e58d9a1a..4832e922fa8e 100644 --- a/tests/ui/useless_conversion.fixed +++ b/tests/ui/useless_conversion.fixed @@ -1,4 +1,5 @@ #![deny(clippy::useless_conversion)] +#![allow(clippy::into_iter_on_ref)] #![allow(clippy::needless_ifs, clippy::unnecessary_wraps, unused)] // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint #![allow(static_mut_refs)] @@ -131,6 +132,15 @@ fn main() { dont_lint_into_iter_on_copy_iter(); dont_lint_into_iter_on_static_copy_iter(); + { + // triggers the IntoIterator trait + fn consume(_: impl IntoIterator) {} + + // Should suggest `*items` instead of `&**items` + let items = &&[1, 2, 3]; + consume(*items); //~ useless_conversion + } + let _: String = "foo".into(); let _: String = From::from("foo"); let _ = String::from("foo"); diff --git a/tests/ui/useless_conversion.rs b/tests/ui/useless_conversion.rs index d95fe49e2e2b..6ef1f93a5606 100644 --- a/tests/ui/useless_conversion.rs +++ b/tests/ui/useless_conversion.rs @@ -1,4 +1,5 @@ #![deny(clippy::useless_conversion)] +#![allow(clippy::into_iter_on_ref)] #![allow(clippy::needless_ifs, clippy::unnecessary_wraps, unused)] // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint #![allow(static_mut_refs)] @@ -131,6 +132,15 @@ fn main() { dont_lint_into_iter_on_copy_iter(); dont_lint_into_iter_on_static_copy_iter(); + { + // triggers the IntoIterator trait + fn consume(_: impl IntoIterator) {} + + // Should suggest `*items` instead of `&**items` + let items = &&[1, 2, 3]; + consume(items.into_iter()); //~ useless_conversion + } + let _: String = "foo".into(); let _: String = From::from("foo"); let _ = String::from("foo"); diff --git a/tests/ui/useless_conversion.stderr b/tests/ui/useless_conversion.stderr index 052c664f6f2e..d28b7a5cbfb6 100644 --- a/tests/ui/useless_conversion.stderr +++ b/tests/ui/useless_conversion.stderr @@ -1,5 +1,5 @@ error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion.rs:9:13 + --> tests/ui/useless_conversion.rs:10:13 | LL | let _ = T::from(val); | ^^^^^^^^^^^^ help: consider removing `T::from()`: `val` @@ -11,115 +11,132 @@ LL | #![deny(clippy::useless_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion.rs:11:5 + --> tests/ui/useless_conversion.rs:12:5 | LL | val.into() | ^^^^^^^^^^ help: consider removing `.into()`: `val` error: useless conversion to the same type: `i32` - --> tests/ui/useless_conversion.rs:24:22 + --> tests/ui/useless_conversion.rs:25:22 | LL | let _: i32 = 0i32.into(); | ^^^^^^^^^^^ help: consider removing `.into()`: `0i32` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:55:22 + --> tests/ui/useless_conversion.rs:56:22 | LL | if Some("ok") == lines.into_iter().next() {} | ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:61:21 + --> tests/ui/useless_conversion.rs:62:21 | LL | let mut lines = text.lines().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:68:22 + --> tests/ui/useless_conversion.rs:69:22 | LL | if Some("ok") == text.lines().into_iter().next() {} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()` error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:75:13 + --> tests/ui/useless_conversion.rs:76:13 | LL | let _ = NUMBERS.into_iter().next(); | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:81:17 + --> tests/ui/useless_conversion.rs:82:17 | LL | let mut n = NUMBERS.into_iter(); | ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS` +error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` + --> tests/ui/useless_conversion.rs:141:17 + | +LL | consume(items.into_iter()); + | ^^^^^^^^^^^^^^^^^ + | +note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` + --> tests/ui/useless_conversion.rs:137:28 + | +LL | fn consume(_: impl IntoIterator) {} + | ^^^^^^^^^^^^ +help: consider removing the `.into_iter()` + | +LL - consume(items.into_iter()); +LL + consume(*items); + | + error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:144:21 + --> tests/ui/useless_conversion.rs:154:21 | LL | let _: String = "foo".to_string().into(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:146:21 + --> tests/ui/useless_conversion.rs:156:21 | LL | let _: String = From::from("foo".to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:148:13 + --> tests/ui/useless_conversion.rs:158:13 | LL | let _ = String::from("foo".to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:150:13 + --> tests/ui/useless_conversion.rs:160:13 | LL | let _ = String::from(format!("A: {:04}", 123)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)` error: useless conversion to the same type: `std::str::Lines<'_>` - --> tests/ui/useless_conversion.rs:152:13 + --> tests/ui/useless_conversion.rs:162:13 | LL | let _ = "".lines().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()` error: useless conversion to the same type: `std::vec::IntoIter` - --> tests/ui/useless_conversion.rs:154:13 + --> tests/ui/useless_conversion.rs:164:13 | LL | let _ = vec![1, 2, 3].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion.rs:156:21 + --> tests/ui/useless_conversion.rs:166:21 | LL | let _: String = format!("Hello {}", "world").into(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")` error: useless conversion to the same type: `i32` - --> tests/ui/useless_conversion.rs:162:13 + --> tests/ui/useless_conversion.rs:172:13 | LL | let _ = i32::from(a + b) * 3; | ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)` error: useless conversion to the same type: `Foo<'a'>` - --> tests/ui/useless_conversion.rs:169:23 + --> tests/ui/useless_conversion.rs:179:23 | LL | let _: Foo<'a'> = s2.into(); | ^^^^^^^^^ help: consider removing `.into()`: `s2` error: useless conversion to the same type: `Foo<'a'>` - --> tests/ui/useless_conversion.rs:172:13 + --> tests/ui/useless_conversion.rs:182:13 | LL | let _ = Foo::<'a'>::from(s3); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3` error: useless conversion to the same type: `std::vec::IntoIter>` - --> tests/ui/useless_conversion.rs:175:13 + --> tests/ui/useless_conversion.rs:185:13 | LL | let _ = vec![s4, s4, s4].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:208:7 + --> tests/ui/useless_conversion.rs:218:7 | LL | b(vec![1, 2].into_iter()); | ^^^^^^^^^^------------ @@ -127,13 +144,13 @@ LL | b(vec![1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:198:13 + --> tests/ui/useless_conversion.rs:208:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:210:7 + --> tests/ui/useless_conversion.rs:220:7 | LL | c(vec![1, 2].into_iter()); | ^^^^^^^^^^------------ @@ -141,13 +158,13 @@ LL | c(vec![1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:199:18 + --> tests/ui/useless_conversion.rs:209:18 | LL | fn c(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:212:7 + --> tests/ui/useless_conversion.rs:222:7 | LL | d(vec![1, 2].into_iter()); | ^^^^^^^^^^------------ @@ -155,13 +172,13 @@ LL | d(vec![1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:202:12 + --> tests/ui/useless_conversion.rs:212:12 | LL | T: IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:216:7 + --> tests/ui/useless_conversion.rs:226:7 | LL | b(vec![1, 2].into_iter().into_iter()); | ^^^^^^^^^^------------------------ @@ -169,13 +186,13 @@ LL | b(vec![1, 2].into_iter().into_iter()); | help: consider removing the `.into_iter()`s | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:198:13 + --> tests/ui/useless_conversion.rs:208:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:218:7 + --> tests/ui/useless_conversion.rs:228:7 | LL | b(vec![1, 2].into_iter().into_iter().into_iter()); | ^^^^^^^^^^------------------------------------ @@ -183,13 +200,13 @@ LL | b(vec![1, 2].into_iter().into_iter().into_iter()); | help: consider removing the `.into_iter()`s | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:198:13 + --> tests/ui/useless_conversion.rs:208:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:265:24 + --> tests/ui/useless_conversion.rs:275:24 | LL | foo2::([1, 2, 3].into_iter()); | ^^^^^^^^^------------ @@ -197,13 +214,13 @@ LL | foo2::([1, 2, 3].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:244:12 + --> tests/ui/useless_conversion.rs:254:12 | LL | I: IntoIterator + Helper, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:274:14 + --> tests/ui/useless_conversion.rs:284:14 | LL | foo3([1, 2, 3].into_iter()); | ^^^^^^^^^------------ @@ -211,13 +228,13 @@ LL | foo3([1, 2, 3].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:253:12 + --> tests/ui/useless_conversion.rs:263:12 | LL | I: IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:284:16 + --> tests/ui/useless_conversion.rs:294:16 | LL | S1.foo([1, 2].into_iter()); | ^^^^^^------------ @@ -225,13 +242,13 @@ LL | S1.foo([1, 2].into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:281:27 + --> tests/ui/useless_conversion.rs:291:27 | LL | pub fn foo(&self, _: I) {} | ^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:304:44 + --> tests/ui/useless_conversion.rs:314:44 | LL | v0.into_iter().interleave_shortest(v1.into_iter()); | ^^------------ @@ -239,67 +256,67 @@ LL | v0.into_iter().interleave_shortest(v1.into_iter()); | help: consider removing the `.into_iter()` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:291:20 + --> tests/ui/useless_conversion.rs:301:20 | LL | J: IntoIterator, | ^^^^^^^^^^^^ error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:332:58 + --> tests/ui/useless_conversion.rs:342:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map(Into::into); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `std::io::Error` - --> tests/ui/useless_conversion.rs:335:58 + --> tests/ui/useless_conversion.rs:345:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map_err(Into::into); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:338:58 + --> tests/ui/useless_conversion.rs:348:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map(From::from); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `std::io::Error` - --> tests/ui/useless_conversion.rs:341:58 + --> tests/ui/useless_conversion.rs:351:58 | LL | let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from); | ^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:345:31 + --> tests/ui/useless_conversion.rs:355:31 | LL | let _: ControlFlow<()> = c.map_break(Into::into); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `()` - --> tests/ui/useless_conversion.rs:349:31 + --> tests/ui/useless_conversion.rs:359:31 | LL | let _: ControlFlow<()> = c.map_continue(Into::into); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `u32` - --> tests/ui/useless_conversion.rs:363:41 + --> tests/ui/useless_conversion.rs:373:41 | LL | let _: Vec = [1u32].into_iter().map(Into::into).collect(); | ^^^^^^^^^^^^^^^^ help: consider removing error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion.rs:374:18 + --> tests/ui/useless_conversion.rs:384:18 | LL | x.into_iter().map(Into::into).collect() | ^^^^^^^^^^^^^^^^ help: consider removing error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:390:29 + --> tests/ui/useless_conversion.rs:400:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -310,13 +327,13 @@ LL + takes_into_iter(&self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:398:29 + --> tests/ui/useless_conversion.rs:408:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -327,13 +344,13 @@ LL + takes_into_iter(&mut self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:407:29 + --> tests/ui/useless_conversion.rs:417:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -344,13 +361,13 @@ LL + takes_into_iter(*self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:416:29 + --> tests/ui/useless_conversion.rs:426:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -361,13 +378,13 @@ LL + takes_into_iter(&*self.my_field); | error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> tests/ui/useless_conversion.rs:425:29 + --> tests/ui/useless_conversion.rs:435:29 | LL | takes_into_iter(self.my_field.into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> tests/ui/useless_conversion.rs:379:32 + --> tests/ui/useless_conversion.rs:389:32 | LL | fn takes_into_iter(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -378,22 +395,22 @@ LL + takes_into_iter(&mut *self.my_field); | error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:440:5 + --> tests/ui/useless_conversion.rs:450:5 | LL | R.into_iter().for_each(|_x| {}); | ^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `R` error: useless conversion to the same type: `std::ops::Range` - --> tests/ui/useless_conversion.rs:442:13 + --> tests/ui/useless_conversion.rs:452:13 | LL | let _ = R.into_iter().map(|_x| 0); | ^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `R` error: useless conversion to the same type: `std::slice::Iter<'_, i32>` - --> tests/ui/useless_conversion.rs:453:14 + --> tests/ui/useless_conversion.rs:463:14 | LL | for _ in mac!(iter [1, 2]).into_iter() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `mac!(iter [1, 2])` -error: aborting due to 44 previous errors +error: aborting due to 45 previous errors diff --git a/triagebot.toml b/triagebot.toml index 5f637205fa65..09dec7675e7e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -63,7 +63,6 @@ users_on_vacation = [ "Alexendoo", "y21", "blyxyas", - "samueltardieu", ] [assign.owners] From a3690a2d25d564df5b86742a5be3bb0799a27926 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 8 Jan 2026 19:08:01 +0100 Subject: [PATCH 1847/3801] Make Clippy compile with `ConstArgKind::Tup()` --- src/tools/clippy/clippy_lints/src/large_include_file.rs | 1 - src/tools/clippy/clippy_lints/src/utils/author.rs | 1 + src/tools/clippy/clippy_utils/src/consts.rs | 1 + src/tools/clippy/clippy_utils/src/hir_utils.rs | 8 ++++++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs index d77e0beeaf4c..54599499515e 100644 --- a/src/tools/clippy/clippy_lints/src/large_include_file.rs +++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs @@ -1,4 +1,3 @@ -use rustc_ast::AttrItemKind; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::root_macro_call_first_node; diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 58b153f06545..acea701b2e83 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -323,6 +323,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), + ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), ConstArgKind::Literal(..) => chain!(self, "let ConstArgKind::Literal(..) = {const_arg}.kind") } } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 334cc6bb5d55..e4f76cf4ed57 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1141,6 +1141,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), ConstArgKind::Struct(..) + | ConstArgKind::Tup(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 73b1cbb21548..82a12fc51c9a 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -666,6 +666,8 @@ impl HirEqInterExpr<'_, '_, '_> { } match (&left.kind, &right.kind) { + (ConstArgKind::Tup(l_t), ConstArgKind::Tup(r_t)) => + l_t.len() == r_t.len() && l_t.iter().zip(*r_t).all(|(l_c, r_c)| self.eq_const_arg(*l_c, *r_c)), (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true, @@ -695,6 +697,7 @@ impl HirEqInterExpr<'_, '_, '_> { // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) + | ConstArgKind::Tup(..) | ConstArgKind::Anon(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) @@ -1561,6 +1564,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { fn hash_const_arg(&mut self, const_arg: &ConstArg<'_>) { match &const_arg.kind { + ConstArgKind::Tup(tup) => { + for arg in *tup { + self.hash_const_arg(*arg); + } + }, ConstArgKind::Path(path) => self.hash_qpath(path), ConstArgKind::Anon(anon) => self.hash_body(anon.body), ConstArgKind::Struct(path, inits) => { From 7c3cc4f3ef6d936a11f19857984b06baa1a04d10 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 8 Jan 2026 19:08:01 +0100 Subject: [PATCH 1848/3801] Make Clippy compile with `ConstArgKind::Tup()` --- clippy_lints/src/large_include_file.rs | 1 - clippy_lints/src/utils/author.rs | 1 + clippy_utils/src/consts.rs | 1 + clippy_utils/src/hir_utils.rs | 8 ++++++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/large_include_file.rs b/clippy_lints/src/large_include_file.rs index d77e0beeaf4c..54599499515e 100644 --- a/clippy_lints/src/large_include_file.rs +++ b/clippy_lints/src/large_include_file.rs @@ -1,4 +1,3 @@ -use rustc_ast::AttrItemKind; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::root_macro_call_first_node; diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 58b153f06545..acea701b2e83 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -323,6 +323,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), + ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), ConstArgKind::Literal(..) => chain!(self, "let ConstArgKind::Literal(..) = {const_arg}.kind") } } diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 334cc6bb5d55..e4f76cf4ed57 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1141,6 +1141,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), ConstArgKind::Struct(..) + | ConstArgKind::Tup(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 73b1cbb21548..82a12fc51c9a 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -666,6 +666,8 @@ impl HirEqInterExpr<'_, '_, '_> { } match (&left.kind, &right.kind) { + (ConstArgKind::Tup(l_t), ConstArgKind::Tup(r_t)) => + l_t.len() == r_t.len() && l_t.iter().zip(*r_t).all(|(l_c, r_c)| self.eq_const_arg(*l_c, *r_c)), (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true, @@ -695,6 +697,7 @@ impl HirEqInterExpr<'_, '_, '_> { // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) + | ConstArgKind::Tup(..) | ConstArgKind::Anon(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Tup(..) @@ -1561,6 +1564,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { fn hash_const_arg(&mut self, const_arg: &ConstArg<'_>) { match &const_arg.kind { + ConstArgKind::Tup(tup) => { + for arg in *tup { + self.hash_const_arg(*arg); + } + }, ConstArgKind::Path(path) => self.hash_qpath(path), ConstArgKind::Anon(anon) => self.hash_body(anon.body), ConstArgKind::Struct(path, inits) => { From d28379895b67641408adad95dc69d1e45f1a8a1b Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 9 Jan 2026 10:39:33 +0100 Subject: [PATCH 1849/3801] Update Cargo.lock --- Cargo.lock | 52 +++++----------------------------------------------- 1 file changed, 5 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1bf48f704ab..9c791babc399 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,19 +182,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "askama" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4" -dependencies = [ - "askama_derive 0.14.0", - "itoa", - "percent-encoding", - "serde", - "serde_json", -] - [[package]] name = "askama" version = "0.15.1" @@ -208,30 +195,13 @@ dependencies = [ "serde_json", ] -[[package]] -name = "askama_derive" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f" -dependencies = [ - "askama_parser 0.14.0", - "basic-toml", - "memchr", - "proc-macro2", - "quote", - "rustc-hash 2.1.1", - "serde", - "serde_derive", - "syn 2.0.110", -] - [[package]] name = "askama_derive" version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ba5e7259a1580c61571e3116ebaaa01e3c001b2132b17c4cc5c70780ca3e994" dependencies = [ - "askama_parser 0.15.1", + "askama_parser", "basic-toml", "memchr", "proc-macro2", @@ -248,19 +218,7 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "236ce20b77cb13506eaf5024899f4af6e12e8825f390bd943c4c37fd8f322e46" dependencies = [ - "askama_derive 0.15.1", -] - -[[package]] -name = "askama_parser" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358" -dependencies = [ - "memchr", - "serde", - "serde_derive", - "winnow 0.7.13", + "askama_derive", ] [[package]] @@ -675,7 +633,7 @@ name = "clippy" version = "0.1.94" dependencies = [ "anstream", - "askama 0.14.0", + "askama", "cargo_metadata 0.18.1", "clippy_config", "clippy_lints", @@ -1566,7 +1524,7 @@ name = "generate-copyright" version = "0.1.0" dependencies = [ "anyhow", - "askama 0.15.1", + "askama", "cargo_metadata 0.21.0", "serde", "serde_json", @@ -4913,7 +4871,7 @@ name = "rustdoc" version = "0.0.0" dependencies = [ "arrayvec", - "askama 0.15.1", + "askama", "base64", "expect-test", "indexmap", From 91d4e40e0220cfe7a498f416499adf3ffd6e5c38 Mon Sep 17 00:00:00 2001 From: Flakebi Date: Fri, 9 Jan 2026 10:41:37 +0100 Subject: [PATCH 1850/3801] Add amdgpu_dispatch_ptr intrinsic Add a rustc intrinsic `amdgpu_dispatch_ptr` to access the kernel dispatch packet on amdgpu. The HSA kernel dispatch packet contains important information like the launch size and workgroup size. The Rust intrinsic lowers to the `llvm.amdgcn.dispatch.ptr` LLVM intrinsic, which returns a `ptr addrspace(4)`, plus an addrspacecast to `addrspace(0)`, so it can be returned as a Rust reference. The returned pointer/reference is valid for the whole program lifetime, and is therefore `'static`. The return type of the intrinsic (`*const ()`) does not mention the struct so that rustc does not need to know the exact struct type. An alternative would be to define the struct as lang item or add a generic argument to the function. Short version: ```rust #[cfg(target_arch = "amdgpu")] pub fn amdgpu_dispatch_ptr() -> *const (); ``` --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 6 +++++ .../rustc_codegen_ssa/src/mir/intrinsic.rs | 1 + .../rustc_hir_analysis/src/check/intrinsic.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + library/core/src/intrinsics/gpu.rs | 23 ++++++++++++++++ library/core/src/intrinsics/mod.rs | 1 + tests/codegen-llvm/amdgpu-dispatch-ptr.rs | 27 +++++++++++++++++++ 7 files changed, 61 insertions(+) create mode 100644 library/core/src/intrinsics/gpu.rs create mode 100644 tests/codegen-llvm/amdgpu-dispatch-ptr.rs diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index b4057eea735e..8803963f4bd3 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -560,6 +560,12 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { return Ok(()); } + sym::amdgpu_dispatch_ptr => { + let val = self.call_intrinsic("llvm.amdgcn.dispatch.ptr", &[], &[]); + // Relying on `LLVMBuildPointerCast` to produce an addrspacecast + self.pointercast(val, self.type_ptr()) + } + _ if name.as_str().starts_with("simd_") => { // Unpack non-power-of-2 #[repr(packed, simd)] arguments. // This gives them the expected layout of a regular #[repr(simd)] vector. diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index f4fae40d8828..f5ee9406f4bf 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -112,6 +112,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | sym::unreachable | sym::cold_path | sym::breakpoint + | sym::amdgpu_dispatch_ptr | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid | sym::assert_inhabited diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 4e8333f678b6..d4c4a73e64a2 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -70,6 +70,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::add_with_overflow | sym::aggregate_raw_ptr | sym::align_of + | sym::amdgpu_dispatch_ptr | sym::assert_inhabited | sym::assert_mem_uninitialized_valid | sym::assert_zero_valid @@ -285,6 +286,7 @@ pub(crate) fn check_intrinsic_type( let (n_tps, n_cts, inputs, output) = match intrinsic_name { sym::autodiff => (4, 0, vec![param(0), param(1), param(2)], param(3)), sym::abort => (0, 0, vec![], tcx.types.never), + sym::amdgpu_dispatch_ptr => (0, 0, vec![], Ty::new_imm_ptr(tcx, tcx.types.unit)), sym::unreachable => (0, 0, vec![], tcx.types.never), sym::breakpoint => (0, 0, vec![], tcx.types.unit), sym::size_of | sym::align_of | sym::variant_count => (1, 0, vec![], tcx.types.usize), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 72709753b1df..676e9a9ae042 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -454,6 +454,7 @@ symbols! { alu32, always, amdgpu, + amdgpu_dispatch_ptr, analysis, and, and_then, diff --git a/library/core/src/intrinsics/gpu.rs b/library/core/src/intrinsics/gpu.rs new file mode 100644 index 000000000000..9e7624841d0c --- /dev/null +++ b/library/core/src/intrinsics/gpu.rs @@ -0,0 +1,23 @@ +//! Intrinsics for GPU targets. +//! +//! Intrinsics in this module are intended for use on GPU targets. +//! They can be target specific but in general GPU targets are similar. + +#![unstable(feature = "gpu_intrinsics", issue = "none")] + +/// Returns a pointer to the HSA kernel dispatch packet. +/// +/// A `gpu-kernel` on amdgpu is always launched through a kernel dispatch packet. +/// The dispatch packet contains the workgroup size, launch size and other data. +/// The content is defined by the [HSA Platform System Architecture Specification], +/// which is implemented e.g. in AMD's [hsa.h]. +/// The intrinsic returns a unit pointer so that rustc does not need to know the packet struct. +/// The pointer is valid for the whole lifetime of the program. +/// +/// [HSA Platform System Architecture Specification]: https://hsafoundation.com/wp-content/uploads/2021/02/HSA-SysArch-1.2.pdf +/// [hsa.h]: https://github.com/ROCm/rocm-systems/blob/rocm-7.1.0/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa.h#L2959 +#[rustc_nounwind] +#[rustc_intrinsic] +#[cfg(target_arch = "amdgpu")] +#[must_use = "returns a pointer that does nothing unless used"] +pub fn amdgpu_dispatch_ptr() -> *const (); diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index d46d3ed9d513..0c26aba8618e 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -60,6 +60,7 @@ use crate::{mem, ptr}; mod bounds; pub mod fallback; +pub mod gpu; pub mod mir; pub mod simd; diff --git a/tests/codegen-llvm/amdgpu-dispatch-ptr.rs b/tests/codegen-llvm/amdgpu-dispatch-ptr.rs new file mode 100644 index 000000000000..00bde96c3d59 --- /dev/null +++ b/tests/codegen-llvm/amdgpu-dispatch-ptr.rs @@ -0,0 +1,27 @@ +// Tests the amdgpu_dispatch_ptr intrinsic. + +//@ compile-flags: --crate-type=rlib --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 +//@ needs-llvm-components: amdgpu +//@ add-minicore +#![feature(intrinsics, no_core, rustc_attrs)] +#![no_core] + +extern crate minicore; + +pub struct DispatchPacket { + pub header: u16, + pub setup: u16, + pub workgroup_size_x: u16, // and more +} + +#[rustc_intrinsic] +#[rustc_nounwind] +fn amdgpu_dispatch_ptr() -> *const (); + +// CHECK-LABEL: @get_dispatch_data +// CHECK: %[[ORIG_PTR:[^ ]+]] = {{(tail )?}}call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() +// CHECK-NEXT: %[[PTR:[^ ]+]] = addrspacecast ptr addrspace(4) %[[ORIG_PTR]] to ptr +#[unsafe(no_mangle)] +pub fn get_dispatch_data() -> &'static DispatchPacket { + unsafe { &*(amdgpu_dispatch_ptr() as *const _) } +} From b9ae4f7bf7dc4f4a7c8a8cc934522093d6868bf7 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 9 Jan 2026 08:55:02 +0100 Subject: [PATCH 1851/3801] rustdoc_json: Remove one call to `std::mem::take` in `after_krate`. This patch removes one call to `std::mem::take` to save two `memcpy`s: `JsonRenderer::index` can be quite large as noted https://github.com/rust-lang/rust/pull/142335. `self.index` can be passed directly to `types::Crate`. This removal makes `self` immutable. The private `serialize_and_write` method is moved as a function: the `self` argument is replaced by `sess: &Session`. This `&Session` was fetched earlier in `after_krate` in all cases. This change allows to call `serialize_and_write` after `output_crate` is created, without having a conflict around the move of `self`: the borrow checker is now happy. --- src/librustdoc/json/mod.rs | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 37d456ae796b..a201f661d9f7 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -104,22 +104,6 @@ impl<'tcx> JsonRenderer<'tcx> { }) .unwrap_or_default() } - - fn serialize_and_write( - &self, - output_crate: types::Crate, - mut writer: BufWriter, - path: &str, - ) -> Result<(), Error> { - self.sess().time("rustdoc_json_serialize_and_write", || { - try_err!( - serde_json::ser::to_writer(&mut writer, &output_crate).map_err(|e| e.to_string()), - path - ); - try_err!(writer.flush(), path); - Ok(()) - }) - } } impl<'tcx> JsonRenderer<'tcx> { @@ -252,26 +236,23 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { unreachable!("RUN_ON_MODULE = false, should never call mod_item_in") } - fn after_krate(mut self) -> Result<(), Error> { + fn after_krate(self) -> Result<(), Error> { debug!("Done with crate"); let e = ExternalCrate { crate_num: LOCAL_CRATE }; - - // We've finished using the index, and don't want to clone it, because it is big. - let index = std::mem::take(&mut self.index); + let sess = self.sess(); // Note that tcx.rust_target_features is inappropriate here because rustdoc tries to run for // multiple targets: https://github.com/rust-lang/rust/pull/137632 // // We want to describe a single target, so pass tcx.sess rather than tcx. - let target = conversions::target(self.tcx.sess); + let target = conversions::target(sess); debug!("Constructing Output"); let output_crate = types::Crate { root: self.id_from_item_default(e.def_id().into()), crate_version: self.cache.crate_version.clone(), includes_private: self.cache.document_private, - index, paths: self .cache .paths @@ -313,6 +294,8 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .collect(), + // Be careful to not clone the `index`, it is big. + index: self.index, target, format_version: types::FORMAT_VERSION, }; @@ -323,17 +306,34 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { p.push(output_crate.index.get(&output_crate.root).unwrap().name.clone().unwrap()); p.set_extension("json"); - self.serialize_and_write( + serialize_and_write( + sess, output_crate, try_err!(File::create_buffered(&p), p), &p.display().to_string(), ) } else { - self.serialize_and_write(output_crate, BufWriter::new(stdout().lock()), "") + serialize_and_write(sess, output_crate, BufWriter::new(stdout().lock()), "") } } } +fn serialize_and_write( + sess: &Session, + output_crate: types::Crate, + mut writer: BufWriter, + path: &str, +) -> Result<(), Error> { + sess.time("rustdoc_json_serialize_and_write", || { + try_err!( + serde_json::ser::to_writer(&mut writer, &output_crate).map_err(|e| e.to_string()), + path + ); + try_err!(writer.flush(), path); + Ok(()) + }) +} + // Some nodes are used a lot. Make sure they don't unintentionally get bigger. // // These assertions are here, not in `src/rustdoc-json-types/lib.rs` where the types are defined, From 330358a197e1a6df060a19ccb3b69f29006ba395 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 9 Jan 2026 11:59:23 +0100 Subject: [PATCH 1852/3801] Further Clippy fixes for Tup/Literal ConstArgKind --- src/tools/clippy/clippy_utils/src/consts.rs | 1 + .../clippy/clippy_utils/src/hir_utils.rs | 23 ++++--------------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index e4f76cf4ed57..538f1fd2628c 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1142,6 +1142,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), ConstArgKind::Struct(..) | ConstArgKind::Tup(..) + | ConstArgKind::Literal(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 82a12fc51c9a..0bb641568879 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -666,8 +666,9 @@ impl HirEqInterExpr<'_, '_, '_> { } match (&left.kind, &right.kind) { - (ConstArgKind::Tup(l_t), ConstArgKind::Tup(r_t)) => - l_t.len() == r_t.len() && l_t.iter().zip(*r_t).all(|(l_c, r_c)| self.eq_const_arg(*l_c, *r_c)), + (ConstArgKind::Tup(l_t), ConstArgKind::Tup(r_t)) => { + l_t.len() == r_t.len() && l_t.iter().zip(*r_t).all(|(l_c, r_c)| self.eq_const_arg(*l_c, *r_c)) + }, (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true, @@ -684,23 +685,14 @@ impl HirEqInterExpr<'_, '_, '_> { .iter() .zip(*args_b) .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) - } - (ConstArgKind::Tup(args_a), ConstArgKind::Tup(args_b)) => { - args_a - .iter() - .zip(*args_b) - .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) - }, - (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => { - kind_l == kind_r }, + (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => kind_l == kind_r, // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) | ConstArgKind::Tup(..) | ConstArgKind::Anon(..) | ConstArgKind::TupleCall(..) - | ConstArgKind::Tup(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Literal(..) @@ -1583,13 +1575,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(arg); } }, - ConstArgKind::Tup(args) => { - for arg in *args { - self.hash_const_arg(arg); - } - }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, - ConstArgKind::Literal(lit) => lit.hash(&mut self.s) + ConstArgKind::Literal(lit) => lit.hash(&mut self.s), } } From 697e9e2aacecaa6a610ab310b9af54a732903d21 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 9 Jan 2026 11:59:23 +0100 Subject: [PATCH 1853/3801] Further Clippy fixes for Tup/Literal ConstArgKind --- clippy_utils/src/consts.rs | 1 + clippy_utils/src/hir_utils.rs | 23 +++++------------------ 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index e4f76cf4ed57..538f1fd2628c 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1142,6 +1142,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), ConstArgKind::Struct(..) | ConstArgKind::Tup(..) + | ConstArgKind::Literal(..) | ConstArgKind::TupleCall(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 82a12fc51c9a..0bb641568879 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -666,8 +666,9 @@ impl HirEqInterExpr<'_, '_, '_> { } match (&left.kind, &right.kind) { - (ConstArgKind::Tup(l_t), ConstArgKind::Tup(r_t)) => - l_t.len() == r_t.len() && l_t.iter().zip(*r_t).all(|(l_c, r_c)| self.eq_const_arg(*l_c, *r_c)), + (ConstArgKind::Tup(l_t), ConstArgKind::Tup(r_t)) => { + l_t.len() == r_t.len() && l_t.iter().zip(*r_t).all(|(l_c, r_c)| self.eq_const_arg(*l_c, *r_c)) + }, (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true, @@ -684,23 +685,14 @@ impl HirEqInterExpr<'_, '_, '_> { .iter() .zip(*args_b) .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) - } - (ConstArgKind::Tup(args_a), ConstArgKind::Tup(args_b)) => { - args_a - .iter() - .zip(*args_b) - .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) - }, - (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => { - kind_l == kind_r }, + (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => kind_l == kind_r, // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) | ConstArgKind::Tup(..) | ConstArgKind::Anon(..) | ConstArgKind::TupleCall(..) - | ConstArgKind::Tup(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Literal(..) @@ -1583,13 +1575,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(arg); } }, - ConstArgKind::Tup(args) => { - for arg in *args { - self.hash_const_arg(arg); - } - }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, - ConstArgKind::Literal(lit) => lit.hash(&mut self.s) + ConstArgKind::Literal(lit) => lit.hash(&mut self.s), } } From e80fbd4bca604211f810fc207f33089730a3e9e1 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 9 Jan 2026 13:47:13 +0200 Subject: [PATCH 1854/3801] Fix lifetimes len diagnostics for fn pointers --- .../rust-analyzer/crates/hir-ty/src/lower.rs | 51 ++++++++++--------- .../crates/hir-ty/src/lower/path.rs | 8 +-- .../src/handlers/missing_lifetime.rs | 15 ++++++ 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index a97d7687162e..9befca11b3e5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -27,8 +27,8 @@ use hir_def::{ resolver::{HasResolver, LifetimeNs, Resolver, TypeNs, ValueNs}, signatures::{FunctionSignature, TraitFlags, TypeAliasFlags}, type_ref::{ - ConstRef, LifetimeRefId, PathId, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, - TypeRef, TypeRefId, + ConstRef, FnType, LifetimeRefId, PathId, TraitBoundModifier, TraitRef as HirTraitRef, + TypeBound, TypeRef, TypeRefId, }, }; use hir_expand::name::Name; @@ -98,7 +98,7 @@ impl ImplTraitLoweringState { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub enum LifetimeElisionKind<'db> { /// Create a new anonymous lifetime parameter and reference it. /// @@ -437,26 +437,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { Ty::new_ref(interner, lifetime, inner_ty, lower_mutability(ref_.mutability)) } TypeRef::Placeholder => Ty::new_error(interner, ErrorGuaranteed), - TypeRef::Fn(fn_) => { - let substs = self.with_shifted_in( - DebruijnIndex::from_u32(1), - |ctx: &mut TyLoweringContext<'_, '_>| { - Tys::new_from_iter( - interner, - fn_.params.iter().map(|&(_, tr)| ctx.lower_ty(tr)), - ) - }, - ); - Ty::new_fn_ptr( - interner, - Binder::dummy(FnSig { - abi: fn_.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol), - safety: if fn_.is_unsafe { Safety::Unsafe } else { Safety::Safe }, - c_variadic: fn_.is_varargs, - inputs_and_output: substs, - }), - ) - } + TypeRef::Fn(fn_) => self.lower_fn_ptr(fn_), TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds), TypeRef::ImplTrait(bounds) => { match self.impl_trait_mode.mode { @@ -517,6 +498,30 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { (ty, res) } + fn lower_fn_ptr(&mut self, fn_: &FnType) -> Ty<'db> { + let interner = self.interner; + let (params, ret_ty) = fn_.split_params_and_ret(); + let old_lifetime_elision = self.lifetime_elision; + let mut args = Vec::with_capacity(fn_.params.len()); + self.with_shifted_in(DebruijnIndex::from_u32(1), |ctx: &mut TyLoweringContext<'_, '_>| { + ctx.lifetime_elision = + LifetimeElisionKind::AnonymousCreateParameter { report_in_path: false }; + args.extend(params.iter().map(|&(_, tr)| ctx.lower_ty(tr))); + ctx.lifetime_elision = LifetimeElisionKind::for_fn_ret(interner); + args.push(ctx.lower_ty(ret_ty)); + }); + self.lifetime_elision = old_lifetime_elision; + Ty::new_fn_ptr( + interner, + Binder::dummy(FnSig { + abi: fn_.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol), + safety: if fn_.is_unsafe { Safety::Unsafe } else { Safety::Safe }, + c_variadic: fn_.is_varargs, + inputs_and_output: Tys::new_from_slice(&args), + }), + ) + } + /// This is only for `generic_predicates_for_param`, where we can't just /// lower the self types of the predicates since that could lead to cycles. /// So we just check here if the `type_ref` resolves to a generic param, and which. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index b77aeab62d15..f3d0de12275e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs @@ -599,7 +599,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { explicit_self_ty: Option>, lowering_assoc_type_generics: bool, ) -> GenericArgs<'db> { - let old_lifetime_elision = self.ctx.lifetime_elision.clone(); + let old_lifetime_elision = self.ctx.lifetime_elision; if let Some(args) = self.current_or_prev_segment.args_and_bindings && args.parenthesized != GenericArgsParentheses::No @@ -640,7 +640,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { explicit_self_ty, PathGenericsSource::Segment(self.current_segment_u32()), lowering_assoc_type_generics, - self.ctx.lifetime_elision.clone(), + self.ctx.lifetime_elision, ); self.ctx.lifetime_elision = old_lifetime_elision; result @@ -884,7 +884,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { assoc_type: binding_idx as u32, }, false, - this.ctx.lifetime_elision.clone(), + this.ctx.lifetime_elision, ) }); let args = GenericArgs::new_from_iter( @@ -902,7 +902,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { // `Fn()`-style generics are elided like functions. This is `Output` (we lower to it in hir-def). LifetimeElisionKind::for_fn_ret(self.ctx.interner) } else { - self.ctx.lifetime_elision.clone() + self.ctx.lifetime_elision }; self.with_lifetime_elision(lifetime_elision, |this| { match (&this.ctx.store[type_ref], this.ctx.impl_trait_mode.mode) { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_lifetime.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_lifetime.rs index b07f9e68f634..5cb710b66b5f 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_lifetime.rs @@ -100,4 +100,19 @@ fn foo WithLifetime>() {} "#, ); } + + #[test] + fn regression_21430() { + check_diagnostics( + r#" +struct S { + f: fn(A<()>), +} + +struct A<'a, T> { + a: &'a T, +} + "#, + ); + } } From e52695c3fca6f9b973c98103407d83d1c963cbdf Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Fri, 9 Jan 2026 11:58:16 +0000 Subject: [PATCH 1855/3801] internal: Include private definitions in generated rustdoc rust-analyzer has handy prebuilt `cargo doc` output at https://rust-lang.github.io/rust-analyzer/ide/ However, it doesn't include private definitions, which makes it less useful when trying to learn unfamiliar parts of the codebase. Instead, pass `--document-private-items` so the HTML includes information on private types and modules too. rustdoc renders these with a padlock icon, so it's still clear that they're private. This change also exposes some more rustdoc warnings, which I've fixed. --- src/tools/rust-analyzer/.github/workflows/rustdoc.yaml | 2 +- src/tools/rust-analyzer/crates/hir-def/src/nameres.rs | 2 +- .../crates/hir-expand/src/builtin/attr_macro.rs | 2 +- .../rust-analyzer/crates/hir-expand/src/cfg_process.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/infer/closure.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/method_resolution.rs | 4 ++-- .../crates/hir-ty/src/method_resolution/probe.rs | 2 +- .../crates/hir-ty/src/next_solver/infer/mod.rs | 2 +- src/tools/rust-analyzer/crates/hir/src/term_search.rs | 2 +- .../crates/ide-assists/src/handlers/inline_type_alias.rs | 6 +++++- .../rust-analyzer/crates/ide-completion/src/context.rs | 2 +- src/tools/rust-analyzer/crates/parser/src/grammar.rs | 2 +- .../crates/project-model/src/cargo_workspace.rs | 2 +- .../crates/rust-analyzer/src/config/patch_old_style.rs | 2 +- .../rust-analyzer/crates/rust-analyzer/src/discover.rs | 4 ++-- .../crates/rust-analyzer/src/global_state.rs | 2 +- .../crates/rust-analyzer/src/handlers/dispatch.rs | 6 +++--- .../rust-analyzer/crates/rust-analyzer/src/task_pool.rs | 2 +- src/tools/rust-analyzer/crates/span/src/hygiene.rs | 8 ++++---- .../crates/syntax/src/syntax_editor/mapping.rs | 2 +- src/tools/rust-analyzer/lib/line-index/src/lib.rs | 2 +- 21 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml b/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml index 9cc18fc69ede..0cc7ce77ddb6 100644 --- a/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml +++ b/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml @@ -24,7 +24,7 @@ jobs: run: rustup update --no-self-update stable - name: Build Documentation - run: cargo doc --all --no-deps + run: cargo doc --all --no-deps --document-private-items - name: Deploy Docs uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 150372f1a0d9..1e3ea50c5a0f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -216,7 +216,7 @@ struct DefMapCrateData { registered_tools: Vec, /// Unstable features of Rust enabled with `#![feature(A, B)]`. unstable_features: FxHashSet, - /// #[rustc_coherence_is_core] + /// `#[rustc_coherence_is_core]` rustc_coherence_is_core: bool, no_core: bool, no_std: bool, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs index 06b9b5418e37..c94663ca0cbc 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs @@ -115,7 +115,7 @@ fn dummy_gate_test_expand( /// wasting a lot of memory, and it would also require some way to use a path in a way that makes it /// always resolve as a derive without nameres recollecting them. /// So this hacky approach is a lot more friendly for us, though it does require a bit of support in -/// [`hir::Semantics`] to make this work. +/// hir::Semantics to make this work. fn derive_expand( db: &dyn ExpandDatabase, id: MacroCallId, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs index a0de36548e9f..ccef9168ac3a 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs @@ -1,4 +1,4 @@ -//! Processes out #[cfg] and #[cfg_attr] attributes from the input for the derive macro +//! Processes out `#[cfg]` and `#[cfg_attr]` attributes from the input for the derive macro use std::{cell::OnceCell, ops::ControlFlow}; use ::tt::TextRange; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index d1391ad24e4d..ce99016470c1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -466,7 +466,7 @@ impl<'db> InferenceContext<'_, 'db> { } /// Given an `FnOnce::Output` or `AsyncFn::Output` projection, extract the args - /// and return type to infer a [`ty::PolyFnSig`] for the closure. + /// and return type to infer a `PolyFnSig` for the closure. fn extract_sig_from_projection( &self, projection: PolyProjectionPredicate<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index e4681b464fec..ad4d79e68a9f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -206,11 +206,11 @@ impl<'a, 'db> InferenceContext<'a, 'db> { } } -/// Used by [FnCtxt::lookup_method_for_operator] with `-Znext-solver`. +/// Used by `FnCtxt::lookup_method_for_operator` with `-Znext-solver`. /// /// With `AsRigid` we error on `impl Opaque: NotInItemBounds` while /// `AsInfer` just treats it as ambiguous and succeeds. This is necessary -/// as we want [FnCtxt::check_expr_call] to treat not-yet-defined opaque +/// as we want `FnCtxt::check_expr_call` to treat not-yet-defined opaque /// types as rigid to support `impl Deref` and /// `Box`. /// diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs index 4a7c7d93539e..42a590e8b4cb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs @@ -1740,7 +1740,7 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { /// We want to only accept trait methods if they were hold even if the /// opaque types were rigid. To handle this, we both check that for trait /// candidates the goal were to hold even when treating opaques as rigid, - /// see [OpaqueTypesJank](rustc_trait_selection::solve::OpaqueTypesJank). + /// see `rustc_trait_selection::solve::OpaqueTypesJank`. /// /// We also check that all opaque types encountered as self types in the /// autoderef chain don't get constrained when applying the candidate. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs index 7d291f7ddbed..21baacb11693 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/mod.rs @@ -140,7 +140,7 @@ pub struct InferCtxtInner<'db> { /// /// Before running `resolve_regions_and_report_errors`, the creator /// of the inference context is expected to invoke - /// [`InferCtxt::process_registered_region_obligations`] + /// `InferCtxt::process_registered_region_obligations` /// for each body-id in this map, which will process the /// obligations within. This is expected to be done 'late enough' /// that all type inference variables have been bound and so forth. diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search.rs b/src/tools/rust-analyzer/crates/hir/src/term_search.rs index e4089218305c..f2dc1ce798ad 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search.rs @@ -172,7 +172,7 @@ impl<'db> LookupTable<'db> { /// Insert new type trees for type /// /// Note that the types have to be the same, unification is not enough as unification is not - /// transitive. For example Vec and FxHashSet both unify with Iterator, + /// transitive. For example `Vec` and `FxHashSet` both unify with `Iterator`, /// but they clearly do not unify themselves. fn insert(&mut self, ty: Type<'db>, exprs: impl Iterator>) { match self.data.get_mut(&ty) { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs index ae8d130df23c..c7a48f3261a9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -290,19 +290,23 @@ impl ConstAndTypeMap { /// ^ alias generic params /// let a: A<100>; /// ^ instance generic args -/// ``` /// /// generic['a] = '_ due to omission /// generic[N] = 100 due to the instance arg /// generic[T] = u64 due to the default param +/// ``` /// /// 2. Copy the concrete type and substitute in each found mapping: /// +/// ```ignore /// &'_ [u64; 100] +/// ``` /// /// 3. Remove wildcard lifetimes entirely: /// +/// ```ignore /// &[u64; 100] +/// ``` fn create_replacement( lifetime_map: &LifetimeMap, const_and_type_map: &ConstAndTypeMap, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index d116f665adbd..cab8bced88df 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs @@ -628,7 +628,7 @@ impl CompletionContext<'_> { } /// A version of [`SemanticsScope::process_all_names`] that filters out `#[doc(hidden)]` items and - /// passes all doc-aliases along, to funnel it into [`Completions::add_path_resolution`]. + /// passes all doc-aliases along, to funnel it into `Completions::add_path_resolution`. pub(crate) fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef, Vec)) { let _p = tracing::info_span!("CompletionContext::process_all_names").entered(); self.scope.process_all_names(&mut |name, def| { diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar.rs b/src/tools/rust-analyzer/crates/parser/src/grammar.rs index bf8430294110..e481bbe9bc4a 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar.rs @@ -6,7 +6,7 @@ //! each submodule starts with `use super::*` import and exports //! "public" productions via `pub(super)`. //! -//! See docs for [`Parser`](super::parser::Parser) to learn about API, +//! See docs for [`Parser`] to learn about API, //! available to the grammar, and see docs for [`Event`](super::event::Event) //! to learn how this actually manages to produce parse trees. //! diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 6e1a3f37ff1c..483ab2845045 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -640,7 +640,7 @@ impl FetchMetadata { /// Builds a command to fetch metadata for the given `cargo_toml` manifest. /// /// Performs a lightweight pre-fetch using the `--no-deps` option, - /// available via [`FetchMetadata::no_deps_metadata`], to gather basic + /// available via `FetchMetadata::no_deps_metadata`, to gather basic /// information such as the `target-dir`. /// /// The provided sysroot is used to set the `RUSTUP_TOOLCHAIN` diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs index 389bb7848c01..5dc463eccce4 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs @@ -3,7 +3,7 @@ use serde_json::{Value, json}; /// This function patches the json config to the new expected keys. /// That is we try to load old known config keys here and convert them to the new ones. -/// See https://github.com/rust-lang/rust-analyzer/pull/12010 +/// See /// /// We already have an alias system for simple cases, but if we make structural changes /// the alias infra fails down. diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs index 4aef5b0b7f3d..f129f156a030 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs @@ -42,7 +42,7 @@ impl DiscoverCommand { Self { sender, command } } - /// Spawn the command inside [Discover] and report progress, if any. + /// Spawn the command inside `DiscoverCommand` and report progress, if any. pub(crate) fn spawn( &self, discover_arg: DiscoverArgument, @@ -73,7 +73,7 @@ impl DiscoverCommand { } } -/// A handle to a spawned [Discover]. +/// A handle to a spawned `DiscoverCommand`. #[derive(Debug)] pub(crate) struct DiscoverHandle { pub(crate) handle: CommandHandle, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 39b4aaa64738..afd4162de622 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -188,7 +188,7 @@ pub(crate) struct GlobalState { /// been called. pub(crate) deferred_task_queue: DeferredTaskQueue, - /// HACK: Workaround for https://github.com/rust-lang/rust-analyzer/issues/19709 + /// HACK: Workaround for /// This is marked true if we failed to load a crate root file at crate graph creation, /// which will usually end up causing a bunch of incorrect diagnostics on startup. pub(crate) incomplete_crate_graph: bool, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs index 10bbb0bb31d9..90deae2d902e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs @@ -101,7 +101,7 @@ impl RequestDispatcher<'_> { } /// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not - /// ready this will return a default constructed [`R::Result`]. + /// ready this will return a default constructed `R::Result`. pub(crate) fn on( &mut self, f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result, @@ -128,7 +128,7 @@ impl RequestDispatcher<'_> { } /// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not - /// ready this will return a `default` constructed [`R::Result`]. + /// ready this will return a `default` constructed `R::Result`. pub(crate) fn on_with_vfs_default( &mut self, f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result, @@ -176,7 +176,7 @@ impl RequestDispatcher<'_> { } /// Dispatches a latency-sensitive request onto the thread pool. When the VFS is marked not - /// ready this will return a default constructed [`R::Result`]. + /// ready this will return a default constructed `R::Result`. pub(crate) fn on_latency_sensitive( &mut self, f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs index 8b8876b801cf..104cd3d2eae9 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs @@ -52,7 +52,7 @@ impl TaskPool { /// `DeferredTaskQueue` holds deferred tasks. /// /// These are tasks that must be run after -/// [`GlobalState::process_changes`] has been called. +/// `GlobalState::process_changes` has been called. pub(crate) struct DeferredTaskQueue { pub(crate) sender: crossbeam_channel::Sender, pub(crate) receiver: crossbeam_channel::Receiver, diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index ea4f4c5efb42..92bf892ea529 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -8,9 +8,9 @@ //! //! # The Expansion Order Hierarchy //! -//! `ExpnData` in rustc, rust-analyzer's version is [`MacroCallLoc`]. Traversing the hierarchy -//! upwards can be achieved by walking up [`MacroCallLoc::kind`]'s contained file id, as -//! [`MacroFile`]s are interned [`MacroCallLoc`]s. +//! `ExpnData` in rustc, rust-analyzer's version is `MacroCallLoc`. Traversing the hierarchy +//! upwards can be achieved by walking up `MacroCallLoc::kind`'s contained file id, as +//! `MacroFile`s are interned `MacroCallLoc`s. //! //! # The Macro Definition Hierarchy //! @@ -18,7 +18,7 @@ //! //! # The Call-site Hierarchy //! -//! `ExpnData::call_site` in rustc, [`MacroCallLoc::call_site`] in rust-analyzer. +//! `ExpnData::call_site` in rustc, `MacroCallLoc::call_site` in rust-analyzer. use crate::Edition; use std::fmt; diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs index 1eaef03197c5..6257bf4e572e 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs @@ -1,6 +1,6 @@ //! Maps syntax elements through disjoint syntax nodes. //! -//! [`SyntaxMappingBuilder`] should be used to create mappings to add to a [`SyntaxEditor`] +//! [`SyntaxMappingBuilder`] should be used to create mappings to add to a `SyntaxEditor` use itertools::Itertools; use rustc_hash::FxHashMap; diff --git a/src/tools/rust-analyzer/lib/line-index/src/lib.rs b/src/tools/rust-analyzer/lib/line-index/src/lib.rs index 905da330e64b..d5f0584d988f 100644 --- a/src/tools/rust-analyzer/lib/line-index/src/lib.rs +++ b/src/tools/rust-analyzer/lib/line-index/src/lib.rs @@ -207,7 +207,7 @@ impl LineIndex { } } -/// This is adapted from the rustc_span crate, https://github.com/rust-lang/rust/blob/de59844c98f7925242a798a72c59dc3610dd0e2c/compiler/rustc_span/src/analyze_source_file.rs +/// This is adapted from the rustc_span crate, fn analyze_source_file(src: &str) -> (Vec, IntMap>) { assert!(src.len() < !0u32 as usize); let mut lines = vec![]; From fb296d7a04ba42e723aa082d4ef9f96105dd1da0 Mon Sep 17 00:00:00 2001 From: Asger Hautop Drewsen Date: Fri, 9 Jan 2026 12:52:25 +0100 Subject: [PATCH 1856/3801] Use f64 NaN in documentation instead of sqrt(-1.0) --- library/core/src/cmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index feb9c4319604..d61e1071db8b 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1186,7 +1186,7 @@ pub macro Ord($item:item) { /// every `a`. This isn't always the case for types that implement `PartialOrd`, for example: /// /// ``` -/// let a = f64::sqrt(-1.0); +/// let a = f64::NAN; /// assert_eq!(a <= a, false); /// ``` /// From 87d716701e83e39a0c9416ca1c54e14b66202260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 9 Jan 2026 14:35:15 +0100 Subject: [PATCH 1857/3801] Reenable GCC CI download --- src/ci/run.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index 425ad38a6655..b486f0525f40 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -187,9 +187,8 @@ else RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.static-libstdcpp" fi - # Download GCC from CI on test builders (temporarily disabled because the CI gcc component - # was renamed). - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set gcc.download-ci-gcc=false" + # Download GCC from CI on test builders + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set gcc.download-ci-gcc=true" # download-rustc seems to be broken on CI after the stage0 redesign # Disable it until these issues are debugged and resolved From 58a9fdded8b4f38dfb88da3793bf5750bb136ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 9 Jan 2026 14:36:24 +0100 Subject: [PATCH 1858/3801] Bump `download-ci-gcc-stamp` --- src/bootstrap/download-ci-gcc-stamp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/download-ci-gcc-stamp b/src/bootstrap/download-ci-gcc-stamp index bbe26afc9526..ec8d0fa3135d 100644 --- a/src/bootstrap/download-ci-gcc-stamp +++ b/src/bootstrap/download-ci-gcc-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-gcc` configuration download a new version of GCC from CI, even if the GCC submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/138051 +Last change is for: https://github.com/rust-lang/rust/pull/150873 From 5af08c0c28c97f03e2d89356cfd6d569dd18d24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 9 Jan 2026 14:40:54 +0100 Subject: [PATCH 1859/3801] Ignore `rustc-src-gpl` in fast try builds --- src/tools/opt-dist/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index b17cfb567e5b..b52dab001ef5 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -450,6 +450,7 @@ fn main() -> anyhow::Result<()> { "rust-docs-json", "rust-analyzer", "rustc-src", + "rustc-src-gpl", "extended", "clippy", "miri", From 998a5ac623d9879cfba667d6220a8f7d228845e8 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 9 Jan 2026 15:55:45 +0200 Subject: [PATCH 1860/3801] Remove code made redundant by method resolution rewrite Its job is now done elsewhere, and it's also wrong (not accounting for autoderef) --- .../crates/hir-ty/src/infer/expr.rs | 12 ++-- .../crates/hir-ty/src/tests/regression.rs | 55 +++++++++++++--- .../crates/hir-ty/src/tests/traits.rs | 66 +++++++++++-------- 3 files changed, 88 insertions(+), 45 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 226e9f5cd667..62339779a562 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -1704,7 +1704,7 @@ impl<'db> InferenceContext<'_, 'db> { }); match resolved { Ok((func, _is_visible)) => { - self.check_method_call(tgt_expr, &[], func.sig, receiver_ty, expected) + self.check_method_call(tgt_expr, &[], func.sig, expected) } Err(_) => self.err_ty(), } @@ -1844,7 +1844,7 @@ impl<'db> InferenceContext<'_, 'db> { item: func.def_id.into(), }) } - self.check_method_call(tgt_expr, args, func.sig, receiver_ty, expected) + self.check_method_call(tgt_expr, args, func.sig, expected) } // Failed to resolve, report diagnostic and try to resolve as call to field access or // assoc function @@ -1934,16 +1934,14 @@ impl<'db> InferenceContext<'_, 'db> { tgt_expr: ExprId, args: &[ExprId], sig: FnSig<'db>, - receiver_ty: Ty<'db>, expected: &Expectation<'db>, ) -> Ty<'db> { - let (formal_receiver_ty, param_tys) = if !sig.inputs_and_output.inputs().is_empty() { - (sig.inputs_and_output.as_slice()[0], &sig.inputs_and_output.inputs()[1..]) + let param_tys = if !sig.inputs_and_output.inputs().is_empty() { + &sig.inputs_and_output.inputs()[1..] } else { - (self.types.types.error, &[] as _) + &[] }; let ret_ty = sig.output(); - self.table.unify(formal_receiver_ty, receiver_ty); self.check_call_arguments(tgt_expr, param_tys, ret_ty, expected, args, &[], sig.c_variadic); ret_ty diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index c805f030446c..df49d7999fee 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -891,13 +891,14 @@ use core::ops::Deref; struct BufWriter {} -struct Mutex {} -struct MutexGuard<'a, T> {} +struct Mutex(T); +struct MutexGuard<'a, T>(&'a T); impl Mutex { fn lock(&self) -> MutexGuard<'_, T> {} } impl<'a, T: 'a> Deref for MutexGuard<'a, T> { type Target = T; + fn deref(&self) -> &Self::Target { loop {} } } fn flush(&self) { let w: &Mutex; @@ -905,14 +906,18 @@ fn flush(&self) { } "#, expect![[r#" - 123..127 'self': &'? Mutex - 150..152 '{}': MutexGuard<'?, T> - 234..238 'self': &'? {unknown} - 240..290 '{ ...()); }': () - 250..251 'w': &'? Mutex - 276..287 '*(w.lock())': BufWriter - 278..279 'w': &'? Mutex - 278..286 'w.lock()': MutexGuard<'?, BufWriter> + 129..133 'self': &'? Mutex + 156..158 '{}': MutexGuard<'?, T> + 242..246 'self': &'? MutexGuard<'a, T> + 265..276 '{ loop {} }': &'? T + 267..274 'loop {}': ! + 272..274 '{}': () + 289..293 'self': &'? {unknown} + 295..345 '{ ...()); }': () + 305..306 'w': &'? Mutex + 331..342 '*(w.lock())': BufWriter + 333..334 'w': &'? Mutex + 333..341 'w.lock()': MutexGuard<'?, BufWriter> "#]], ); } @@ -2563,3 +2568,33 @@ fn main() { "#, ); } + +#[test] +fn regression_21429() { + check_no_mismatches( + r#" +trait DatabaseLike { + type ForeignKey: ForeignKeyLike; +} + +trait ForeignKeyLike { + type DB: DatabaseLike; + + fn host_columns(&self, database: &Self::DB); +} + +trait ColumnLike { + type DB: DatabaseLike; + + fn foo() -> &&<::DB as DatabaseLike>::ForeignKey { + loop {} + } + + fn foreign_keys(&self, database: &Self::DB) { + let fk = Self::foo(); + fk.host_columns(database); + } +} + "#, + ); +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index 38591f486e97..b825a0a8f0e5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -429,7 +429,7 @@ fn associated_type_shorthand_from_method_bound() { trait Iterable { type Item; } -struct S; +struct S(T); impl S { fn foo(self) -> T::Item where T: Iterable { loop {} } } @@ -1103,40 +1103,50 @@ fn test() { fn argument_impl_trait_type_args_2() { check_infer_with_mismatches( r#" -//- minicore: sized +//- minicore: sized, phantom_data +use core::marker::PhantomData; + trait Trait {} struct S; impl Trait for S {} -struct F; +struct F(PhantomData); impl F { fn foo(self, x: impl Trait) -> (T, U) { loop {} } } fn test() { - F.foo(S); - F::.foo(S); - F::.foo::(S); - F::.foo::(S); // extraneous argument should be ignored + F(PhantomData).foo(S); + F::(PhantomData).foo(S); + F::(PhantomData).foo::(S); + F::(PhantomData).foo::(S); // extraneous argument should be ignored }"#, expect![[r#" - 87..91 'self': F - 93..94 'x': impl Trait - 118..129 '{ loop {} }': (T, U) - 120..127 'loop {}': ! - 125..127 '{}': () - 143..283 '{ ...ored }': () - 149..150 'F': F<{unknown}> - 149..157 'F.foo(S)': ({unknown}, {unknown}) - 155..156 'S': S - 163..171 'F::': F - 163..178 'F::.foo(S)': (u32, {unknown}) - 176..177 'S': S - 184..192 'F::': F - 184..206 'F::(S)': (u32, i32) - 204..205 'S': S - 212..220 'F::': F - 212..239 'F::(S)': (u32, i32) - 237..238 'S': S + 135..139 'self': F + 141..142 'x': impl Trait + 166..177 '{ loop {} }': (T, U) + 168..175 'loop {}': ! + 173..175 '{}': () + 191..383 '{ ...ored }': () + 197..198 'F': fn F<{unknown}>(PhantomData<{unknown}>) -> F<{unknown}> + 197..211 'F(PhantomData)': F<{unknown}> + 197..218 'F(Phan...foo(S)': ({unknown}, {unknown}) + 199..210 'PhantomData': PhantomData<{unknown}> + 216..217 'S': S + 224..232 'F::': fn F(PhantomData) -> F + 224..245 'F:: + 224..252 'F:: + 250..251 'S': S + 258..266 'F::': fn F(PhantomData) -> F + 258..279 'F:: + 258..293 'F::(S)': (u32, i32) + 267..278 'PhantomData': PhantomData + 291..292 'S': S + 299..307 'F::': fn F(PhantomData) -> F + 299..320 'F:: + 299..339 'F::(S)': (u32, i32) + 308..319 'PhantomData': PhantomData + 337..338 'S': S "#]], ); } @@ -4012,7 +4022,7 @@ fn f() { fn dyn_map() { check_types( r#" -pub struct Key {} +pub struct Key(K, V, P); pub trait Policy { type K; @@ -4024,7 +4034,7 @@ impl Policy for (K, V) { type V = V; } -pub struct KeyMap {} +pub struct KeyMap(KEY); impl KeyMap> { pub fn get(&self, key: &P::K) -> P::V { @@ -5023,7 +5033,7 @@ fn main() { 278..280 '{}': () 290..291 '_': Box + '?> 294..298 'iter': Box + 'static> - 294..310 'iter.i...iter()': Box + 'static> + 294..310 'iter.i...iter()': Box + '?> 152..156 'self': &'? mut Box 177..208 '{ ... }': Option<::Item> 191..198 'loop {}': ! From 01e8f14867ec14591aa73269c8744cbbe9f69645 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 9 Jan 2026 15:03:33 +0100 Subject: [PATCH 1861/3801] Mention that `rustc_codegen_gcc` is a subtree in `rustc-dev-guide` --- src/doc/rustc-dev-guide/src/external-repos.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md index d2b4e791df0e..c43c1f680acf 100644 --- a/src/doc/rustc-dev-guide/src/external-repos.md +++ b/src/doc/rustc-dev-guide/src/external-repos.md @@ -22,6 +22,7 @@ The following external projects are managed using some form of a `subtree`: * [rustfmt](https://github.com/rust-lang/rustfmt) * [rust-analyzer](https://github.com/rust-lang/rust-analyzer) * [rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift) +* [rustc_codegen_gcc](https://github.com/rust-lang/rustc_codegen_gcc) * [rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide) * [compiler-builtins](https://github.com/rust-lang/compiler-builtins) * [stdarch](https://github.com/rust-lang/stdarch) @@ -40,6 +41,7 @@ implement a new tool feature or test, that should happen in one collective rustc * `portable-simd` ([sync script](https://github.com/rust-lang/portable-simd/blob/master/subtree-sync.sh)) * `rustfmt` * `rustc_codegen_cranelift` ([sync script](https://github.com/rust-lang/rustc_codegen_cranelift/blob/113af154d459e41b3dc2c5d7d878e3d3a8f33c69/scripts/rustup.sh#L7)) + * `rustc_codegen_gcc` ([sync guide](https://github.com/rust-lang/rustc_codegen_gcc/blob/master/doc/subtree.md)) * Using the [josh](#synchronizing-a-josh-subtree) tool * `miri` * `rust-analyzer` From 47f28fc71e03e968fc3bcdab8d3a2155698fa36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 9 Jan 2026 14:54:59 +0100 Subject: [PATCH 1862/3801] Refactor artifact keep mode in bootstrap --- src/bootstrap/src/core/build_steps/check.rs | 51 ++++++++++-- src/bootstrap/src/core/build_steps/clippy.rs | 15 ++-- src/bootstrap/src/core/build_steps/compile.rs | 77 +++++++++++-------- src/bootstrap/src/core/build_steps/test.rs | 5 +- 4 files changed, 97 insertions(+), 51 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 7da2551c76fe..f983c59f9bf8 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -4,7 +4,8 @@ use std::fs; use std::path::{Path, PathBuf}; use crate::core::build_steps::compile::{ - add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make, + ArtifactKeepMode, add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, + std_crates_for_run_make, }; use crate::core::build_steps::tool; use crate::core::build_steps::tool::{ @@ -111,8 +112,7 @@ impl Step for Std { builder.config.free_args.clone(), &check_stamp, vec![], - true, - false, + ArtifactKeepMode::OnlyRmeta, ); drop(_guard); @@ -148,7 +148,14 @@ impl Step for Std { build_compiler, target, ); - run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); + run_cargo( + builder, + cargo, + builder.config.free_args.clone(), + &stamp, + vec![], + ArtifactKeepMode::OnlyRmeta, + ); check_stamp } @@ -368,7 +375,14 @@ impl Step for Rustc { let stamp = build_stamp::librustc_stamp(builder, build_compiler, target).with_prefix("check"); - run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); + run_cargo( + builder, + cargo, + builder.config.free_args.clone(), + &stamp, + vec![], + ArtifactKeepMode::OnlyRmeta, + ); stamp } @@ -568,7 +582,14 @@ impl Step for CraneliftCodegenBackend { ) .with_prefix("check"); - run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); + run_cargo( + builder, + cargo, + builder.config.free_args.clone(), + &stamp, + vec![], + ArtifactKeepMode::OnlyRmeta, + ); } fn metadata(&self) -> Option { @@ -639,7 +660,14 @@ impl Step for GccCodegenBackend { ) .with_prefix("check"); - run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); + run_cargo( + builder, + cargo, + builder.config.free_args.clone(), + &stamp, + vec![], + ArtifactKeepMode::OnlyRmeta, + ); } fn metadata(&self) -> Option { @@ -777,7 +805,14 @@ fn run_tool_check_step( .with_prefix(&format!("{display_name}-check")); let _guard = builder.msg(builder.kind, display_name, mode, build_compiler, target); - run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); + run_cargo( + builder, + cargo, + builder.config.free_args.clone(), + &stamp, + vec![], + ArtifactKeepMode::OnlyRmeta, + ); } tool_check_step!(Rustdoc { diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index 085c2d952e30..9e5bfd2e60e9 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -15,7 +15,7 @@ use build_helper::exit; -use super::compile::{run_cargo, rustc_cargo, std_cargo}; +use super::compile::{ArtifactKeepMode, run_cargo, rustc_cargo, std_cargo}; use super::tool::{SourceType, prepare_tool_cargo}; use crate::builder::{Builder, ShouldRun}; use crate::core::build_steps::check::{CompilerForCheck, prepare_compiler_for_check}; @@ -214,8 +214,7 @@ impl Step for Std { lint_args(builder, &self.config, IGNORED_RULES_FOR_STD_AND_RUSTC), &build_stamp::libstd_stamp(builder, build_compiler, target), vec![], - true, - false, + ArtifactKeepMode::OnlyRmeta, ); } @@ -309,8 +308,7 @@ impl Step for Rustc { lint_args(builder, &self.config, IGNORED_RULES_FOR_STD_AND_RUSTC), &build_stamp::librustc_stamp(builder, build_compiler, target), vec![], - true, - false, + ArtifactKeepMode::OnlyRmeta, ); } @@ -380,7 +378,7 @@ impl Step for CodegenGcc { .with_prefix("rustc_codegen_gcc-check"); let args = lint_args(builder, &self.config, &[]); - run_cargo(builder, cargo, args.clone(), &stamp, vec![], true, false); + run_cargo(builder, cargo, args.clone(), &stamp, vec![], ArtifactKeepMode::OnlyRmeta); // Same but we disable the features enabled by default. let mut cargo = prepare_tool_cargo( @@ -396,7 +394,7 @@ impl Step for CodegenGcc { self.build_compiler.configure_cargo(&mut cargo); println!("Now running clippy on `rustc_codegen_gcc` with `--no-default-features`"); cargo.arg("--no-default-features"); - run_cargo(builder, cargo, args, &stamp, vec![], true, false); + run_cargo(builder, cargo, args, &stamp, vec![], ArtifactKeepMode::OnlyRmeta); } fn metadata(&self) -> Option { @@ -478,8 +476,7 @@ macro_rules! lint_any { lint_args(builder, &self.config, &[]), &stamp, vec![], - true, - false, + ArtifactKeepMode::OnlyRmeta ); } diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 02be3f2cc735..2808c29cc6c0 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -296,8 +296,11 @@ impl Step for Std { vec![], &stamp, target_deps, - self.is_for_mir_opt_tests, // is_check - false, + if self.is_for_mir_opt_tests { + ArtifactKeepMode::OnlyRmeta + } else { + ArtifactKeepMode::OnlyRlib + }, ); builder.ensure(StdLink::from_std( @@ -1167,14 +1170,28 @@ impl Step for Rustc { target, ); let stamp = build_stamp::librustc_stamp(builder, build_compiler, target); + run_cargo( builder, cargo, vec![], &stamp, vec![], - false, - true, // Only ship rustc_driver.so and .rmeta files, not all intermediate .rlib files. + ArtifactKeepMode::Custom(Box::new(|filename| { + if filename.contains("jemalloc_sys") + || filename.contains("rustc_public_bridge") + || filename.contains("rustc_public") + { + // jemalloc_sys and rustc_public_bridge are not linked into librustc_driver.so, + // so we need to distribute them as rlib to be able to use them. + filename.ends_with(".rlib") + } else { + // Distribute the rest of the rustc crates as rmeta files only to reduce + // the tarball sizes by about 50%. The object files are linked into + // librustc_driver.so, so it is still possible to link against them. + filename.ends_with(".rmeta") + } + })), ); let target_root_dir = stamp.path().parent().unwrap(); @@ -1714,7 +1731,7 @@ impl Step for GccCodegenBackend { let _guard = builder.msg(Kind::Build, "codegen backend gcc", Mode::Codegen, build_compiler, host); - let files = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false); + let files = run_cargo(builder, cargo, vec![], &stamp, vec![], ArtifactKeepMode::OnlyRlib); GccCodegenBackendOutput { stamp: write_codegen_backend_stamp(stamp, files, builder.config.dry_run()), @@ -1790,7 +1807,7 @@ impl Step for CraneliftCodegenBackend { build_compiler, target, ); - let files = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false); + let files = run_cargo(builder, cargo, vec![], &stamp, vec![], ArtifactKeepMode::OnlyRlib); write_codegen_backend_stamp(stamp, files, builder.config.dry_run()) } @@ -2620,14 +2637,26 @@ pub fn add_to_sysroot( } } +/// Specifies which rlib/rmeta artifacts outputted by Cargo should be put into the resulting +/// build stamp, and thus be included in dist archives and copied into sysroots by default. +/// Note that some kinds of artifacts are copied automatically (e.g. native libraries). +pub enum ArtifactKeepMode { + /// Only keep .rlib files, ignore .rmeta files + OnlyRlib, + /// Only keep .rmeta files, ignore .rlib files + OnlyRmeta, + /// Custom logic for keeping an artifact + /// It receives the filename of an artifact, and returns true if it should be kept. + Custom(Box bool>), +} + pub fn run_cargo( builder: &Builder<'_>, cargo: Cargo, tail_args: Vec, stamp: &BuildStamp, additional_target_deps: Vec<(PathBuf, DependencyType)>, - is_check: bool, - rlib_only_metadata: bool, + artifact_keep_mode: ArtifactKeepMode, ) -> Vec { // `target_root_dir` looks like $dir/$target/release let target_root_dir = stamp.path().parent().unwrap(); @@ -2661,36 +2690,20 @@ pub fn run_cargo( }; for filename in filenames_vec { // Skip files like executables - let mut keep = false; - if filename.ends_with(".lib") + let keep = if filename.ends_with(".lib") || filename.ends_with(".a") || is_debug_info(&filename) || is_dylib(Path::new(&*filename)) { // Always keep native libraries, rust dylibs and debuginfo - keep = true; - } - if is_check && filename.ends_with(".rmeta") { - // During check builds we need to keep crate metadata - keep = true; - } else if rlib_only_metadata { - if filename.contains("jemalloc_sys") - || filename.contains("rustc_public_bridge") - || filename.contains("rustc_public") - { - // jemalloc_sys and rustc_public_bridge are not linked into librustc_driver.so, - // so we need to distribute them as rlib to be able to use them. - keep |= filename.ends_with(".rlib"); - } else { - // Distribute the rest of the rustc crates as rmeta files only to reduce - // the tarball sizes by about 50%. The object files are linked into - // librustc_driver.so, so it is still possible to link against them. - keep |= filename.ends_with(".rmeta"); - } + true } else { - // In all other cases keep all rlibs - keep |= filename.ends_with(".rlib"); - } + match &artifact_keep_mode { + ArtifactKeepMode::OnlyRlib => filename.ends_with(".rlib"), + ArtifactKeepMode::OnlyRmeta => filename.ends_with(".rmeta"), + ArtifactKeepMode::Custom(func) => func(&filename), + } + }; if !keep { continue; diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 7d7cfccf54e6..f3a1c6b0e3dd 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -14,7 +14,7 @@ use std::{env, fs, iter}; use build_helper::exit; -use crate::core::build_steps::compile::{Std, run_cargo}; +use crate::core::build_steps::compile::{ArtifactKeepMode, Std, run_cargo}; use crate::core::build_steps::doc::{DocumentationFormat, prepare_doc_compiler}; use crate::core::build_steps::gcc::{Gcc, GccTargetPair, add_cg_gcc_cargo_flags}; use crate::core::build_steps::llvm::get_llvm_version; @@ -2587,7 +2587,8 @@ impl BookTest { let stamp = BuildStamp::new(&builder.cargo_out(test_compiler, mode, target)) .with_prefix(PathBuf::from(dep).file_name().and_then(|v| v.to_str()).unwrap()); - let output_paths = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false); + let output_paths = + run_cargo(builder, cargo, vec![], &stamp, vec![], ArtifactKeepMode::OnlyRlib); let directories = output_paths .into_iter() .filter_map(|p| p.parent().map(ToOwned::to_owned)) From b022edce934b2fb939f876ccb78c1fb8b5bd6349 Mon Sep 17 00:00:00 2001 From: Wonko Date: Fri, 9 Jan 2026 15:17:06 +0100 Subject: [PATCH 1863/3801] add test for unstacking cognitive_complexity= attribute --- tests/ui/cognitive_complexity.rs | 25 +++++++++++++++++++++++++ tests/ui/cognitive_complexity.stderr | 18 +++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/tests/ui/cognitive_complexity.rs b/tests/ui/cognitive_complexity.rs index 8080c6775e0b..3945028f8271 100644 --- a/tests/ui/cognitive_complexity.rs +++ b/tests/ui/cognitive_complexity.rs @@ -472,3 +472,28 @@ mod issue14422 { return; } } + +#[clippy::cognitive_complexity = "1"] +mod attribute_stacking { + fn bad() { + //~^ cognitive_complexity + if true { + println!("a"); + } + } + + #[clippy::cognitive_complexity = "2"] + fn ok() { + if true { + println!("a"); + } + } + + // should revert to cognitive_complexity = "1" + fn bad_again() { + //~^ cognitive_complexity + if true { + println!("a"); + } + } +} diff --git a/tests/ui/cognitive_complexity.stderr b/tests/ui/cognitive_complexity.stderr index 67ef4e5655bd..e5f54a37229d 100644 --- a/tests/ui/cognitive_complexity.stderr +++ b/tests/ui/cognitive_complexity.stderr @@ -176,5 +176,21 @@ LL | fn bar() { | = help: you could split it up into multiple smaller functions -error: aborting due to 22 previous errors +error: the function has a cognitive complexity of (2/1) + --> tests/ui/cognitive_complexity.rs:478:8 + | +LL | fn bad() { + | ^^^ + | + = help: you could split it up into multiple smaller functions + +error: the function has a cognitive complexity of (2/1) + --> tests/ui/cognitive_complexity.rs:493:8 + | +LL | fn bad_again() { + | ^^^^^^^^^ + | + = help: you could split it up into multiple smaller functions + +error: aborting due to 24 previous errors From 13b82eb615c68c71baf85ea8dcfbcab51a1dce1a Mon Sep 17 00:00:00 2001 From: Wonko Date: Fri, 9 Jan 2026 13:43:55 +0100 Subject: [PATCH 1864/3801] Fix LimitStack::pop_attrs in release mode The `LimitStack::pop_attrs` function used to pop from the stack in `debug_assert_eq!` and check the value. The `pop` operation was therefore only executed in debug builds, leading to an unbalanced stack in release builds when attributes were present. This change ensures the `pop` operation is always executed, by moving it out of the debug-only assertion. The assertion is kept for debug builds. changelog: fix unbalanced stack in attributes --- clippy_utils/src/attrs.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs index 32f6cb4fd5e9..56490cfc8b65 100644 --- a/clippy_utils/src/attrs.rs +++ b/clippy_utils/src/attrs.rs @@ -159,7 +159,10 @@ impl LimitStack { } pub fn pop_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: Symbol) { let stack = &mut self.stack; - parse_attrs(sess, attrs, name, |val| debug_assert_eq!(stack.pop(), Some(val))); + parse_attrs(sess, attrs, name, |val| { + let popped = stack.pop(); + debug_assert_eq!(popped, Some(val)); + }); } } From e0324b527e2ca5976adb9d813df9e271f3402867 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 9 Jan 2026 14:44:51 +0000 Subject: [PATCH 1865/3801] Emit an error for linking staticlibs on BPF Rather than panicking. --- compiler/rustc_codegen_ssa/messages.ftl | 2 ++ compiler/rustc_codegen_ssa/src/back/linker.rs | 2 +- compiler/rustc_codegen_ssa/src/errors.rs | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 1d87dc5da8d2..4875f309cca5 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -10,6 +10,8 @@ codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$erro codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty +codegen_ssa_bpf_staticlib_not_supported = linking static libraries is not supported for BPF + codegen_ssa_cgu_not_recorded = CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index b47652092ed5..637d54dd06c6 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -2075,7 +2075,7 @@ impl<'a> Linker for BpfLinker<'a> { } fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) { - panic!("staticlibs not supported") + self.sess.dcx().emit_fatal(errors::BpfStaticlibNotSupported) } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 95306c140895..f57c37ca7929 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -713,6 +713,10 @@ pub struct UnknownArchiveKind<'a> { pub kind: &'a str, } +#[derive(Diagnostic)] +#[diag(codegen_ssa_bpf_staticlib_not_supported)] +pub(crate) struct BpfStaticlibNotSupported; + #[derive(Diagnostic)] #[diag(codegen_ssa_multiple_main_functions)] #[help] From 90c84d0aaea127743b248552c8ab793f5c0f9429 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 9 Jan 2026 14:45:25 +0000 Subject: [PATCH 1866/3801] Reduce visibility of some errors --- compiler/rustc_codegen_ssa/src/back/archive.rs | 7 ++++--- compiler/rustc_codegen_ssa/src/errors.rs | 8 +++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 93f6cb3b87e6..3f12e857391b 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -22,10 +22,11 @@ use tracing::trace; use super::metadata::{create_compressed_metadata_file, search_for_section}; use crate::common; -// Re-exporting for rustc_codegen_llvm::back::archive -pub use crate::errors::{ArchiveBuildFailure, ExtractBundledLibsError, UnknownArchiveKind}; +// Public for ArchiveBuilderBuilder::extract_bundled_libs +pub use crate::errors::ExtractBundledLibsError; use crate::errors::{ - DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile, + ArchiveBuildFailure, DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, + ErrorWritingDEFFile, UnknownArchiveKind, }; /// An item to be included in an import library. diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index f57c37ca7929..39727685aec1 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -661,7 +661,7 @@ pub(crate) struct RlibArchiveBuildFailure { } #[derive(Diagnostic)] -// Public for rustc_codegen_llvm::back::archive +// Public for ArchiveBuilderBuilder::extract_bundled_libs pub enum ExtractBundledLibsError<'a> { #[diag(codegen_ssa_extract_bundled_libs_open_file)] OpenFile { rlib: &'a Path, error: Box }, @@ -700,16 +700,14 @@ pub(crate) struct UnsupportedLinkSelfContained; #[derive(Diagnostic)] #[diag(codegen_ssa_archive_build_failure)] -// Public for rustc_codegen_llvm::back::archive -pub struct ArchiveBuildFailure { +pub(crate) struct ArchiveBuildFailure { pub path: PathBuf, pub error: std::io::Error, } #[derive(Diagnostic)] #[diag(codegen_ssa_unknown_archive_kind)] -// Public for rustc_codegen_llvm::back::archive -pub struct UnknownArchiveKind<'a> { +pub(crate) struct UnknownArchiveKind<'a> { pub kind: &'a str, } From 2cde8d967a7b5b6dbec30cd18d8f7417e4e22d33 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 9 Jan 2026 09:44:39 -0500 Subject: [PATCH 1867/3801] Fix std::fs::copy on WASI by setting proper OpenOptions flags When PR #147572 switched WASI to use Unix-style filesystem APIs, the open_to_and_set_permissions function for WASI was implemented to call OpenOptions::new().open() without setting any access mode flags. This causes std::fs::copy to fail with the error: "must specify at least one of read, write, or append access" The fix is to explicitly set .write(true), .create(true), and .truncate(true) on the OpenOptions, matching the behavior of the non-WASI Unix implementation but without the permission handling that WASI doesn't support. Minimal reproduction: fn main() { std::fs::write("/src.txt", b"test").unwrap(); match std::fs::copy("/src.txt", "/dst.txt") { Ok(_) => println!("PASS: fs::copy works!"), Err(e) => println!("FAIL: {}", e), } } # Compile and run: rustc +nightly --target wasm32-wasip2 test.rs -o test.wasm wasmtime -S cli --dir . test.wasm # Before fix: FAIL: must specify at least one of read, write, or append access # After fix: PASS: fs::copy works! Note: The existing test library/std/src/fs/tests.rs::copy_file_ok would have caught this regression if the std test suite ran on WASI targets. Currently std tests don't compile for wasm32-wasip2 due to Unix-specific test code in library/std/src/sys/fd/unix/tests.rs. Fixes the regression introduced in nightly-2025-12-10. --- library/std/src/sys/fs/unix.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 327b0eb7468a..02f733c6e4c1 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -2296,7 +2296,11 @@ fn open_to_and_set_permissions( _reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; - let writer = OpenOptions::new().open(to)?; + let writer = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(to)?; let writer_metadata = writer.metadata()?; Ok((writer, writer_metadata)) } From 0946c867a86cf3c830dbbd7073d8df7f71b3149b Mon Sep 17 00:00:00 2001 From: Sebastian Bernauer Date: Wed, 17 Dec 2025 16:12:22 +0100 Subject: [PATCH 1868/3801] Add new `duration_suboptimal_units` lint --- CHANGELOG.md | 1 + clippy_dev/src/serve.rs | 2 +- clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/duration_suboptimal_units.rs | 204 ++++++++++++++++++ clippy_lints/src/lib.rs | 6 +- clippy_utils/src/msrvs.rs | 6 +- clippy_utils/src/sym.rs | 9 + tests/ui/duration_suboptimal_units.fixed | 91 ++++++++ tests/ui/duration_suboptimal_units.rs | 91 ++++++++ tests/ui/duration_suboptimal_units.stderr | 152 +++++++++++++ ...duration_suboptimal_units_days_weeks.fixed | 17 ++ .../duration_suboptimal_units_days_weeks.rs | 17 ++ ...uration_suboptimal_units_days_weeks.stderr | 40 ++++ 13 files changed, 633 insertions(+), 4 deletions(-) create mode 100644 clippy_lints/src/duration_suboptimal_units.rs create mode 100644 tests/ui/duration_suboptimal_units.fixed create mode 100644 tests/ui/duration_suboptimal_units.rs create mode 100644 tests/ui/duration_suboptimal_units.stderr create mode 100644 tests/ui/duration_suboptimal_units_days_weeks.fixed create mode 100644 tests/ui/duration_suboptimal_units_days_weeks.rs create mode 100644 tests/ui/duration_suboptimal_units_days_weeks.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 91d793489be2..4cda8003b05c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6406,6 +6406,7 @@ Released 2018-09-13 [`duplicate_mod`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_mod [`duplicate_underscore_argument`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_underscore_argument [`duplicated_attributes`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicated_attributes +[`duration_suboptimal_units`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_suboptimal_units [`duration_subsec`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_subsec [`eager_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#eager_transmute [`elidable_lifetime_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#elidable_lifetime_names diff --git a/clippy_dev/src/serve.rs b/clippy_dev/src/serve.rs index d9e018133813..b99289672420 100644 --- a/clippy_dev/src/serve.rs +++ b/clippy_dev/src/serve.rs @@ -54,7 +54,7 @@ pub fn run(port: u16, lint: Option) -> ! { } // Delay to avoid updating the metadata too aggressively. - thread::sleep(Duration::from_millis(1000)); + thread::sleep(Duration::from_secs(1)); } } diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 6b68940c6423..ef9da84c4407 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -135,6 +135,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::drop_forget_ref::FORGET_NON_DROP_INFO, crate::drop_forget_ref::MEM_FORGET_INFO, crate::duplicate_mod::DUPLICATE_MOD_INFO, + crate::duration_suboptimal_units::DURATION_SUBOPTIMAL_UNITS_INFO, crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO, crate::empty_drop::EMPTY_DROP_INFO, crate::empty_enums::EMPTY_ENUMS_INFO, diff --git a/clippy_lints/src/duration_suboptimal_units.rs b/clippy_lints/src/duration_suboptimal_units.rs new file mode 100644 index 000000000000..8140585b70d3 --- /dev/null +++ b/clippy_lints/src/duration_suboptimal_units.rs @@ -0,0 +1,204 @@ +use std::ops::ControlFlow; + +use clippy_config::Conf; +use clippy_utils::consts::{ConstEvalCtxt, Constant}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::res::MaybeDef; +use clippy_utils::sym; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, QPath, RustcVersion}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::ty::TyCtxt; +use rustc_session::impl_lint_pass; +use rustc_span::Symbol; + +declare_clippy_lint! { + /// ### What it does + /// + /// Checks for instances where a `std::time::Duration` is constructed using a smaller time unit + /// when the value could be expressed more clearly using a larger unit. + /// + /// ### Why is this bad? + /// + /// Using a smaller unit for a duration that is evenly divisible by a larger unit reduces + /// readability. Readers have to mentally convert values, which can be error-prone and makes + /// the code less clear. + /// + /// ### Example + /// ``` + /// use std::time::Duration; + /// + /// let dur = Duration::from_millis(5_000); + /// let dur = Duration::from_secs(180); + /// let dur = Duration::from_mins(10 * 60); + /// ``` + /// + /// Use instead: + /// ``` + /// use std::time::Duration; + /// + /// let dur = Duration::from_secs(5); + /// let dur = Duration::from_mins(3); + /// let dur = Duration::from_hours(10); + /// ``` + #[clippy::version = "1.95.0"] + pub DURATION_SUBOPTIMAL_UNITS, + pedantic, + "constructing a `Duration` using a smaller unit when a larger unit would be more readable" +} + +impl_lint_pass!(DurationSuboptimalUnits => [DURATION_SUBOPTIMAL_UNITS]); + +pub struct DurationSuboptimalUnits { + msrv: Msrv, + units: Vec, +} + +impl DurationSuboptimalUnits { + pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self { + // The order of the units matters, as they are walked top to bottom + let mut units = UNITS.to_vec(); + if tcx.features().enabled(sym::duration_constructors) { + units.extend(EXTENDED_UNITS); + } + Self { msrv: conf.msrv, units } + } +} + +impl LateLintPass<'_> for DurationSuboptimalUnits { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) { + if !expr.span.in_external_macro(cx.sess().source_map()) + // Check if a function on std::time::Duration is called + && let ExprKind::Call(func, [arg]) = expr.kind + && let ExprKind::Path(QPath::TypeRelative(func_ty, func_name)) = func.kind + && cx + .typeck_results() + .node_type(func_ty.hir_id) + .is_diag_item(cx, sym::Duration) + // We intentionally don't want to evaluate referenced constants, as we don't want to + // recommend a literal value over using constants: + // + // let dur = Duration::from_secs(SIXTY); + // ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::from_mins(1)` + && let Some(Constant::Int(value)) = ConstEvalCtxt::new(cx).eval_local(arg, expr.span.ctxt()) + && let value = u64::try_from(value).expect("All Duration::from_ constructors take a u64") + // There is no need to promote e.g. 0 seconds to 0 hours + && value != 0 + && let Some((promoted_constructor, promoted_value)) = self.promote(cx, func_name.ident.name, value) + { + span_lint_and_then( + cx, + DURATION_SUBOPTIMAL_UNITS, + expr.span, + "constructing a `Duration` using a smaller unit when a larger unit would be more readable", + |diag| { + let suggestions = vec![ + (func_name.ident.span, promoted_constructor.to_string()), + (arg.span, promoted_value.to_string()), + ]; + diag.multipart_suggestion_verbose( + format!("try using {promoted_constructor}"), + suggestions, + Applicability::MachineApplicable, + ); + }, + ); + } + } +} + +impl DurationSuboptimalUnits { + /// Tries to promote the given constructor and value to a bigger time unit and returns the + /// promoted constructor name and value. + /// + /// Returns [`None`] in case no promotion could be done. + fn promote(&self, cx: &LateContext<'_>, constructor_name: Symbol, value: u64) -> Option<(Symbol, u64)> { + let (best_unit, best_value) = self + .units + .iter() + .skip_while(|unit| unit.constructor_name != constructor_name) + .skip(1) + .try_fold( + (constructor_name, value), + |(current_unit, current_value), bigger_unit| { + if let Some(bigger_value) = current_value.div_exact(u64::from(bigger_unit.factor)) + && bigger_unit.stable_since.is_none_or(|v| self.msrv.meets(cx, v)) + { + ControlFlow::Continue((bigger_unit.constructor_name, bigger_value)) + } else { + // We have to break early, as we can't skip versions, as they are needed to + // correctly calculate the promoted value. + ControlFlow::Break((current_unit, current_value)) + } + }, + ) + .into_value(); + (best_unit != constructor_name).then_some((best_unit, best_value)) + } +} + +#[derive(Clone, Copy)] +struct Unit { + /// Name of the constructor on [`Duration`](std::time::Duration) to construct it from the given + /// unit, e.g. [`Duration::from_secs`](std::time::Duration::from_secs) + constructor_name: Symbol, + + /// The increase factor over the previous (smaller) unit + factor: u16, + + /// In what rustc version stable support for this constructor was added. + /// We do not need to track the version stable support in const contexts was added, as the const + /// stabilization was done in an ascending order of the time unites, so it's always valid to + /// promote a const constructor. + stable_since: Option, +} + +/// Time unit constructors available on stable. The order matters! +const UNITS: [Unit; 6] = [ + Unit { + constructor_name: sym::from_nanos, + // The value doesn't matter, as there is no previous unit + factor: 0, + stable_since: Some(msrvs::DURATION_FROM_NANOS_MICROS), + }, + Unit { + constructor_name: sym::from_micros, + factor: 1_000, + stable_since: Some(msrvs::DURATION_FROM_NANOS_MICROS), + }, + Unit { + constructor_name: sym::from_millis, + factor: 1_000, + stable_since: Some(msrvs::DURATION_FROM_MILLIS_SECS), + }, + Unit { + constructor_name: sym::from_secs, + factor: 1_000, + stable_since: Some(msrvs::DURATION_FROM_MILLIS_SECS), + }, + Unit { + constructor_name: sym::from_mins, + factor: 60, + stable_since: Some(msrvs::DURATION_FROM_MINUTES_HOURS), + }, + Unit { + constructor_name: sym::from_hours, + factor: 60, + stable_since: Some(msrvs::DURATION_FROM_MINUTES_HOURS), + }, +]; + +/// Time unit constructors behind the `duration_constructors` feature. The order matters! +const EXTENDED_UNITS: [Unit; 2] = [ + Unit { + constructor_name: sym::from_days, + factor: 24, + stable_since: None, + }, + Unit { + constructor_name: sym::from_weeks, + factor: 7, + stable_since: None, + }, +]; diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index a957afdb1910..ef2461f8b097 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1,11 +1,13 @@ #![cfg_attr(bootstrap, feature(array_windows))] #![feature(box_patterns)] -#![feature(macro_metavar_expr_concat)] +#![feature(control_flow_into_value)] +#![feature(exact_div)] #![feature(f128)] #![feature(f16)] #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(iter_partition_in_place)] +#![feature(macro_metavar_expr_concat)] #![feature(never_type)] #![feature(rustc_private)] #![feature(stmt_expr_attributes)] @@ -113,6 +115,7 @@ mod doc; mod double_parens; mod drop_forget_ref; mod duplicate_mod; +mod duration_suboptimal_units; mod else_if_without_else; mod empty_drop; mod empty_enums; @@ -857,6 +860,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(|_| Box::::default()), Box::new(move |_| Box::new(manual_ilog2::ManualIlog2::new(conf))), Box::new(|_| Box::new(same_length_and_capacity::SameLengthAndCapacity)), + Box::new(move |tcx| Box::new(duration_suboptimal_units::DurationSuboptimalUnits::new(tcx, conf))), // add late passes here, used by `cargo dev new_lint` ]; store.late_passes.extend(late_lints); diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 4a7fa3472cae..14cfb5a88283 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -23,6 +23,7 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { + 1,91,0 { DURATION_FROM_MINUTES_HOURS } 1,88,0 { LET_CHAINS } 1,87,0 { OS_STR_DISPLAY, INT_MIDPOINT, CONST_CHAR_IS_DIGIT, UNSIGNED_IS_MULTIPLE_OF, INTEGER_SIGN_CAST } 1,85,0 { UINT_FLOAT_MIDPOINT, CONST_SIZE_OF_VAL } @@ -69,12 +70,12 @@ msrv_aliases! { 1,35,0 { OPTION_COPIED, RANGE_CONTAINS } 1,34,0 { TRY_FROM } 1,33,0 { UNDERSCORE_IMPORTS } - 1,32,0 { CONST_IS_POWER_OF_TWO } + 1,32,0 { CONST_IS_POWER_OF_TWO, CONST_DURATION_FROM_NANOS_MICROS_MILLIS_SECS } 1,31,0 { OPTION_REPLACE } 1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES } 1,29,0 { ITER_FLATTEN } 1,28,0 { FROM_BOOL, REPEAT_WITH, SLICE_FROM_REF } - 1,27,0 { ITERATOR_TRY_FOLD, DOUBLE_ENDED_ITERATOR_RFIND } + 1,27,0 { ITERATOR_TRY_FOLD, DOUBLE_ENDED_ITERATOR_RFIND, DURATION_FROM_NANOS_MICROS } 1,26,0 { RANGE_INCLUSIVE, STRING_RETAIN, POINTER_ADD_SUB_METHODS } 1,24,0 { IS_ASCII_DIGIT, PTR_NULL } 1,18,0 { HASH_MAP_RETAIN, HASH_SET_RETAIN } @@ -82,6 +83,7 @@ msrv_aliases! { 1,16,0 { STR_REPEAT, RESULT_UNWRAP_OR_DEFAULT } 1,15,0 { MAYBE_BOUND_IN_WHERE } 1,13,0 { QUESTION_MARK_OPERATOR } + 1,3,0 { DURATION_FROM_MILLIS_SECS } } /// `#[clippy::msrv]` attributes are rarely used outside of Clippy's test suite, as a basic diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index a0d2e8673fe6..f11af159bc2e 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -140,6 +140,7 @@ generate! { disallowed_types, drain, dump, + duration_constructors, ends_with, enum_glob_use, enumerate, @@ -164,12 +165,20 @@ generate! { from_be_bytes, from_bytes_with_nul, from_bytes_with_nul_unchecked, + from_days, + from_hours, from_le_bytes, + from_micros, + from_millis, + from_mins, + from_nanos, from_ne_bytes, from_ptr, from_raw, from_raw_parts, + from_secs, from_str_radix, + from_weeks, fs, fuse, futures_util, diff --git a/tests/ui/duration_suboptimal_units.fixed b/tests/ui/duration_suboptimal_units.fixed new file mode 100644 index 000000000000..98c4b6e965ba --- /dev/null +++ b/tests/ui/duration_suboptimal_units.fixed @@ -0,0 +1,91 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::duration_suboptimal_units)] + +use std::time::Duration; + +const SIXTY: u64 = 60; + +macro_rules! mac { + (slow_rythm) => { + 3600 + }; + (duration) => { + Duration::from_mins(5) + //~^ duration_suboptimal_units + }; + (arg => $e:expr) => { + Duration::from_secs($e) + }; +} + +fn main() { + let dur = Duration::from_secs(0); + let dur = Duration::from_secs(42); + let dur = Duration::from_hours(3); + + let dur = Duration::from_mins(1); + //~^ duration_suboptimal_units + let dur = Duration::from_mins(3); + //~^ duration_suboptimal_units + let dur = Duration::from_mins(10); + //~^ duration_suboptimal_units + let dur = Duration::from_hours(24); + //~^ duration_suboptimal_units + let dur = Duration::from_secs(5); + //~^ duration_suboptimal_units + let dur = Duration::from_hours(13); + //~^ duration_suboptimal_units + + // Constants are intentionally not resolved, as we don't want to recommend a literal value over + // using constants. + let dur = Duration::from_secs(SIXTY); + // Technically it would be nice to use Duration::from_mins(SIXTY) here, but that is a follow-up + let dur = Duration::from_secs(SIXTY * 60); + + const { + let dur = Duration::from_secs(0); + let dur = Duration::from_secs(5); + //~^ duration_suboptimal_units + let dur = Duration::from_mins(3); + //~^ duration_suboptimal_units + let dur = Duration::from_hours(24); + //~^ duration_suboptimal_units + + let dur = Duration::from_secs(SIXTY); + } + + // Qualified Durations must be kept + std::time::Duration::from_mins(1); + //~^ duration_suboptimal_units + + // We lint in normal macros + assert_eq!(Duration::from_hours(1), Duration::from_mins(6)); + //~^ duration_suboptimal_units + + // We lint in normal macros (marker is in macro itself) + let dur = mac!(duration); + + // We don't lint in macros if duration comes from outside + let dur = mac!(arg => 3600); + + // We don't lint in external macros + let dur = proc_macros::external! { Duration::from_secs(3_600) }; + + // We don't lint values coming from macros + let dur = Duration::from_secs(mac!(slow_rythm)); +} + +mod my_duration { + struct Duration {} + + impl Duration { + pub const fn from_secs(_secs: u64) -> Self { + Self {} + } + } + + fn test() { + // Only suggest the change for std::time::Duration, not for other Duration structs + let dur = Duration::from_secs(60); + } +} diff --git a/tests/ui/duration_suboptimal_units.rs b/tests/ui/duration_suboptimal_units.rs new file mode 100644 index 000000000000..c4f33a9f92e0 --- /dev/null +++ b/tests/ui/duration_suboptimal_units.rs @@ -0,0 +1,91 @@ +//@aux-build:proc_macros.rs +#![warn(clippy::duration_suboptimal_units)] + +use std::time::Duration; + +const SIXTY: u64 = 60; + +macro_rules! mac { + (slow_rythm) => { + 3600 + }; + (duration) => { + Duration::from_secs(300) + //~^ duration_suboptimal_units + }; + (arg => $e:expr) => { + Duration::from_secs($e) + }; +} + +fn main() { + let dur = Duration::from_secs(0); + let dur = Duration::from_secs(42); + let dur = Duration::from_hours(3); + + let dur = Duration::from_secs(60); + //~^ duration_suboptimal_units + let dur = Duration::from_secs(180); + //~^ duration_suboptimal_units + let dur = Duration::from_secs(10 * 60); + //~^ duration_suboptimal_units + let dur = Duration::from_mins(24 * 60); + //~^ duration_suboptimal_units + let dur = Duration::from_millis(5_000); + //~^ duration_suboptimal_units + let dur = Duration::from_nanos(13 * 60 * 60 * 1_000 * 1_000 * 1_000); + //~^ duration_suboptimal_units + + // Constants are intentionally not resolved, as we don't want to recommend a literal value over + // using constants. + let dur = Duration::from_secs(SIXTY); + // Technically it would be nice to use Duration::from_mins(SIXTY) here, but that is a follow-up + let dur = Duration::from_secs(SIXTY * 60); + + const { + let dur = Duration::from_secs(0); + let dur = Duration::from_millis(5_000); + //~^ duration_suboptimal_units + let dur = Duration::from_secs(180); + //~^ duration_suboptimal_units + let dur = Duration::from_mins(24 * 60); + //~^ duration_suboptimal_units + + let dur = Duration::from_secs(SIXTY); + } + + // Qualified Durations must be kept + std::time::Duration::from_secs(60); + //~^ duration_suboptimal_units + + // We lint in normal macros + assert_eq!(Duration::from_secs(3_600), Duration::from_mins(6)); + //~^ duration_suboptimal_units + + // We lint in normal macros (marker is in macro itself) + let dur = mac!(duration); + + // We don't lint in macros if duration comes from outside + let dur = mac!(arg => 3600); + + // We don't lint in external macros + let dur = proc_macros::external! { Duration::from_secs(3_600) }; + + // We don't lint values coming from macros + let dur = Duration::from_secs(mac!(slow_rythm)); +} + +mod my_duration { + struct Duration {} + + impl Duration { + pub const fn from_secs(_secs: u64) -> Self { + Self {} + } + } + + fn test() { + // Only suggest the change for std::time::Duration, not for other Duration structs + let dur = Duration::from_secs(60); + } +} diff --git a/tests/ui/duration_suboptimal_units.stderr b/tests/ui/duration_suboptimal_units.stderr new file mode 100644 index 000000000000..f129dbade8dc --- /dev/null +++ b/tests/ui/duration_suboptimal_units.stderr @@ -0,0 +1,152 @@ +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:26:15 + | +LL | let dur = Duration::from_secs(60); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::duration-suboptimal-units` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::duration_suboptimal_units)]` +help: try using from_mins + | +LL - let dur = Duration::from_secs(60); +LL + let dur = Duration::from_mins(1); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:28:15 + | +LL | let dur = Duration::from_secs(180); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_mins + | +LL - let dur = Duration::from_secs(180); +LL + let dur = Duration::from_mins(3); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:30:15 + | +LL | let dur = Duration::from_secs(10 * 60); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_mins + | +LL - let dur = Duration::from_secs(10 * 60); +LL + let dur = Duration::from_mins(10); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:32:15 + | +LL | let dur = Duration::from_mins(24 * 60); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_hours + | +LL - let dur = Duration::from_mins(24 * 60); +LL + let dur = Duration::from_hours(24); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:34:15 + | +LL | let dur = Duration::from_millis(5_000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_secs + | +LL - let dur = Duration::from_millis(5_000); +LL + let dur = Duration::from_secs(5); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:36:15 + | +LL | let dur = Duration::from_nanos(13 * 60 * 60 * 1_000 * 1_000 * 1_000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_hours + | +LL - let dur = Duration::from_nanos(13 * 60 * 60 * 1_000 * 1_000 * 1_000); +LL + let dur = Duration::from_hours(13); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:47:19 + | +LL | let dur = Duration::from_millis(5_000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_secs + | +LL - let dur = Duration::from_millis(5_000); +LL + let dur = Duration::from_secs(5); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:49:19 + | +LL | let dur = Duration::from_secs(180); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_mins + | +LL - let dur = Duration::from_secs(180); +LL + let dur = Duration::from_mins(3); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:51:19 + | +LL | let dur = Duration::from_mins(24 * 60); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_hours + | +LL - let dur = Duration::from_mins(24 * 60); +LL + let dur = Duration::from_hours(24); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:58:5 + | +LL | std::time::Duration::from_secs(60); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_mins + | +LL - std::time::Duration::from_secs(60); +LL + std::time::Duration::from_mins(1); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:62:16 + | +LL | assert_eq!(Duration::from_secs(3_600), Duration::from_mins(6)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_hours + | +LL - assert_eq!(Duration::from_secs(3_600), Duration::from_mins(6)); +LL + assert_eq!(Duration::from_hours(1), Duration::from_mins(6)); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units.rs:13:9 + | +LL | Duration::from_secs(300) + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | let dur = mac!(duration); + | -------------- in this macro invocation + | + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) +help: try using from_mins + | +LL - Duration::from_secs(300) +LL + Duration::from_mins(5) + | + +error: aborting due to 12 previous errors + diff --git a/tests/ui/duration_suboptimal_units_days_weeks.fixed b/tests/ui/duration_suboptimal_units_days_weeks.fixed new file mode 100644 index 000000000000..b0abcbb7bf03 --- /dev/null +++ b/tests/ui/duration_suboptimal_units_days_weeks.fixed @@ -0,0 +1,17 @@ +#![warn(clippy::duration_suboptimal_units)] +// The duration_constructors feature enables `Duration::from_days` and `Duration::from_weeks`, so we +// should suggest them +#![feature(duration_constructors)] + +use std::time::Duration; + +fn main() { + let dur = Duration::from_mins(1); + //~^ duration_suboptimal_units + + let dur = Duration::from_days(1); + //~^ duration_suboptimal_units + + let dur = Duration::from_weeks(13); + //~^ duration_suboptimal_units +} diff --git a/tests/ui/duration_suboptimal_units_days_weeks.rs b/tests/ui/duration_suboptimal_units_days_weeks.rs new file mode 100644 index 000000000000..663476905c0f --- /dev/null +++ b/tests/ui/duration_suboptimal_units_days_weeks.rs @@ -0,0 +1,17 @@ +#![warn(clippy::duration_suboptimal_units)] +// The duration_constructors feature enables `Duration::from_days` and `Duration::from_weeks`, so we +// should suggest them +#![feature(duration_constructors)] + +use std::time::Duration; + +fn main() { + let dur = Duration::from_secs(60); + //~^ duration_suboptimal_units + + let dur = Duration::from_hours(24); + //~^ duration_suboptimal_units + + let dur = Duration::from_nanos(13 * 7 * 24 * 60 * 60 * 1_000 * 1_000 * 1_000); + //~^ duration_suboptimal_units +} diff --git a/tests/ui/duration_suboptimal_units_days_weeks.stderr b/tests/ui/duration_suboptimal_units_days_weeks.stderr new file mode 100644 index 000000000000..98325358bfa6 --- /dev/null +++ b/tests/ui/duration_suboptimal_units_days_weeks.stderr @@ -0,0 +1,40 @@ +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units_days_weeks.rs:9:15 + | +LL | let dur = Duration::from_secs(60); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::duration-suboptimal-units` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::duration_suboptimal_units)]` +help: try using from_mins + | +LL - let dur = Duration::from_secs(60); +LL + let dur = Duration::from_mins(1); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units_days_weeks.rs:12:15 + | +LL | let dur = Duration::from_hours(24); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_days + | +LL - let dur = Duration::from_hours(24); +LL + let dur = Duration::from_days(1); + | + +error: constructing a `Duration` using a smaller unit when a larger unit would be more readable + --> tests/ui/duration_suboptimal_units_days_weeks.rs:15:15 + | +LL | let dur = Duration::from_nanos(13 * 7 * 24 * 60 * 60 * 1_000 * 1_000 * 1_000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try using from_weeks + | +LL - let dur = Duration::from_nanos(13 * 7 * 24 * 60 * 60 * 1_000 * 1_000 * 1_000); +LL + let dur = Duration::from_weeks(13); + | + +error: aborting due to 3 previous errors + From 642663596d87863521b708b9eabb5f7e63446600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 9 Jan 2026 17:00:49 +0100 Subject: [PATCH 1869/3801] Fix unpacking of gcc-dev component --- src/bootstrap/src/core/download.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 43efdcd7db17..074404b4cdf3 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -396,7 +396,7 @@ impl Config { "; self.download_file(&format!("{base}/{gcc_sha}/{filename}"), &tarball, help_on_error); } - self.unpack(&tarball, root_dir, "gcc"); + self.unpack(&tarball, root_dir, "gcc-dev"); } } From 2a3932295e9ac167f8cd09dc08e86c46e94dbb50 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Fri, 9 Jan 2026 16:15:39 +0000 Subject: [PATCH 1870/3801] Supress unused_parens lint for guard patterns --- compiler/rustc_lint/src/unused.rs | 2 ++ .../parens-around-guard-patterns-not-unused.rs | 13 +++++++++++++ tests/ui/reachable/guard_read_for_never.rs | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/ui/lint/unused/unused_parens/parens-around-guard-patterns-not-unused.rs diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 0ba54e3829f5..506a16355e22 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1190,6 +1190,8 @@ impl UnusedParens { // `&(a..=b)`, there is a recursive `check_pat` on `a` and `b`, but we will assume // that if there are unnecessary parens they serve a purpose of readability. PatKind::Range(..) => return, + // Parentheses may be necessary to disambiguate precedence in guard patterns. + PatKind::Guard(..) => return, // Avoid `p0 | .. | pn` if we should. PatKind::Or(..) if avoid_or => return, // Avoid `mut x` and `mut x @ p` if we should: diff --git a/tests/ui/lint/unused/unused_parens/parens-around-guard-patterns-not-unused.rs b/tests/ui/lint/unused/unused_parens/parens-around-guard-patterns-not-unused.rs new file mode 100644 index 000000000000..d5b8365ee612 --- /dev/null +++ b/tests/ui/lint/unused/unused_parens/parens-around-guard-patterns-not-unused.rs @@ -0,0 +1,13 @@ +//! Guard patterns require parentheses to disambiguate precedence +//! +//! Regression test for https://github.com/rust-lang/rust/issues/149594 + +//@ check-pass + +#![feature(guard_patterns)] +#![expect(incomplete_features)] +#![warn(unused_parens)] + +fn main() { + let (_ if false) = (); +} diff --git a/tests/ui/reachable/guard_read_for_never.rs b/tests/ui/reachable/guard_read_for_never.rs index 7061da635301..763dfd354b58 100644 --- a/tests/ui/reachable/guard_read_for_never.rs +++ b/tests/ui/reachable/guard_read_for_never.rs @@ -2,7 +2,7 @@ // //@ check-pass #![feature(guard_patterns, never_type)] -#![expect(incomplete_features, unused_parens)] +#![expect(incomplete_features)] #![deny(unreachable_code)] fn main() { From e275c2371649d145e4cfafc16b1b02ef37593e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 9 Jan 2026 17:46:49 +0100 Subject: [PATCH 1871/3801] Update bors email in CI postprocessing step --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb6bc325a3bb..8963039dd50b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -289,7 +289,7 @@ jobs: fi # Get closest bors merge commit - PARENT_COMMIT=`git rev-list --author='bors ' -n1 --first-parent HEAD^1` + PARENT_COMMIT=`git rev-list --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` ./build/citool/debug/citool postprocess-metrics \ --job-name ${CI_JOB_NAME} \ From 43c1db7d5676ce023f873871cbf6b2c61f1e362d Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Fri, 9 Jan 2026 11:51:59 -0500 Subject: [PATCH 1872/3801] Run clippy --- library/std/src/sys/fs/unix.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 02f733c6e4c1..bb2ee6ae10ed 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -2296,11 +2296,7 @@ fn open_to_and_set_permissions( _reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; - let writer = OpenOptions::new() - .write(true) - .create(true) - .truncate(true) - .open(to)?; + let writer = OpenOptions::new().write(true).create(true).truncate(true).open(to)?; let writer_metadata = writer.metadata()?; Ok((writer, writer_metadata)) } From fd59b32f8bf0a14451b390b4a7904c63252a56ad Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Fri, 9 Jan 2026 10:40:25 +0530 Subject: [PATCH 1873/3801] std: sys: fs: uefi: Implement File::read Tested using OVMF on QEMU. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index b1e5f33b1b22..e12c7fb397d8 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -320,8 +320,8 @@ impl File { self.0.set_file_info(file_info) } - pub fn read(&self, _buf: &mut [u8]) -> io::Result { - unsupported() + pub fn read(&self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { @@ -666,6 +666,19 @@ mod uefi_fs { Ok(p) } + pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result { + let file_ptr = self.protocol.as_ptr(); + let mut buf_size = buf.len(); + + let r = unsafe { ((*file_ptr).read)(file_ptr, &mut buf_size, buf.as_mut_ptr().cast()) }; + + if buf_size == 0 && r.is_error() { + Err(io::Error::from_raw_os_error(r.as_usize())) + } else { + Ok(buf_size) + } + } + pub(crate) fn read_dir_entry(&self) -> io::Result>> { let file_ptr = self.protocol.as_ptr(); let mut buf_size = 0; From f6f901fa6d2f27a6a309505c9d56a7cb81dd2453 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Fri, 9 Jan 2026 12:24:02 +0530 Subject: [PATCH 1874/3801] std: sys: fs: uefi: Implement File::{flush, *sync} - Make flush a noop since it is only for buffered writers. - Also forward fsync to datasync. UEFI does not have anything separate for metadata sync. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index b1e5f33b1b22..3fec1ee9ae13 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -285,11 +285,11 @@ impl File { } pub fn fsync(&self) -> io::Result<()> { - unsupported() + self.datasync() } pub fn datasync(&self) -> io::Result<()> { - unsupported() + self.0.flush() } pub fn lock(&self) -> io::Result<()> { @@ -348,8 +348,9 @@ impl File { false } + // Write::flush is only meant for buffered writers. So should be noop for unbuffered files. pub fn flush(&self) -> io::Result<()> { - unsupported() + Ok(()) } pub fn seek(&self, _pos: SeekFrom) -> io::Result { @@ -744,6 +745,12 @@ mod uefi_fs { if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } + pub(crate) fn flush(&self) -> io::Result<()> { + let file_ptr = self.protocol.as_ptr(); + let r = unsafe { ((*file_ptr).flush)(file_ptr) }; + if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } + } + pub(crate) fn path(&self) -> &Path { &self.path } From bcf059c81eb056c39cb03958feb6baea289690b4 Mon Sep 17 00:00:00 2001 From: cry-inc Date: Fri, 9 Jan 2026 18:23:37 +0100 Subject: [PATCH 1875/3801] Fix issue with ignore attribute for tests where the attribute has a value with the reason --- src/tools/rust-analyzer/crates/hir-def/src/attrs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs index 83df11f2d2a4..0b8f65687218 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs @@ -135,6 +135,7 @@ fn match_attr_flags(attr_flags: &mut AttrFlags, attr: Meta) -> ControlFlow match name.text() { "deprecated" => attr_flags.insert(AttrFlags::IS_DEPRECATED), + "ignore" => attr_flags.insert(AttrFlags::IS_IGNORE), "lang" => attr_flags.insert(AttrFlags::LANG_ITEM), "path" => attr_flags.insert(AttrFlags::HAS_PATH), "unstable" => attr_flags.insert(AttrFlags::IS_UNSTABLE), From efcf90104e7dda1984255582813d97f4da9349f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 23 Dec 2025 14:16:25 +0100 Subject: [PATCH 1876/3801] Update bors configuration (cherry picked from commit 75f53dd70e23b09e2557ca7c73bcaa22b9d1a8ba) --- rust-bors.toml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/rust-bors.toml b/rust-bors.toml index e813c6c4b116..996b50b2ea27 100644 --- a/rust-bors.toml +++ b/rust-bors.toml @@ -25,3 +25,42 @@ labels_blocking_approval = [ "S-waiting-on-t-rustdoc-frontend", "S-waiting-on-t-clippy" ] + +# If CI runs quicker than this duration, consider it to be a failure +min_ci_time = 600 + +[labels] +approved = [ + "+S-waiting-on-bors", + "-S-blocked", + "-S-waiting-on-author", + "-S-waiting-on-crater", + "-S-waiting-on-review", + "-S-waiting-on-team" +] +unapproved = [ + "+S-waiting-on-author", + "-S-blocked", + "-S-waiting-on-bors", + "-S-waiting-on-crater", + "-S-waiting-on-review", + "-S-waiting-on-team" +] +try_failed = [ + "+S-waiting-on-author", + "-S-waiting-on-review", + "-S-waiting-on-crater" +] +auto_build_succeeded = ["+merged-by-bors"] +auto_build_failed = [ + "+S-waiting-on-review", + "-S-blocked", + "-S-waiting-on-bors", + "-S-waiting-on-author", + "-S-waiting-on-crater", + "-S-waiting-on-team" +] + +# Flip this two once new bors is used for actual merges on this repository +merge_queue_enabled = false +report_merge_conflicts = true From af53cfa8829f29942c872d87bd3d0aef7038b1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 23 Dec 2025 15:47:03 +0100 Subject: [PATCH 1877/3801] Add support for `automation/bors/auto` merge branch (cherry picked from commit bbf4ec3b0fd31a813208791dcce4264ed6bdbae3) --- .github/workflows/ci.yml | 7 ++++--- src/ci/citool/src/main.rs | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05aa600e649e..bb6bc325a3bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,7 @@ on: - try - try-perf - automation/bors/try + - automation/bors/auto pull_request: branches: - "**" @@ -56,7 +57,7 @@ jobs: - name: Test citool # Only test citool on the auto branch, to reduce latency of the calculate matrix job # on PR/try builds. - if: ${{ github.ref == 'refs/heads/auto' }} + if: ${{ github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto' }} run: | cd src/ci/citool CARGO_INCREMENTAL=0 cargo test @@ -79,7 +80,7 @@ jobs: # access the environment. # # We only enable the environment for the rust-lang/rust repository, so that CI works on forks. - environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto')) && 'bors') || '' }} + environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} env: CI_JOB_NAME: ${{ matrix.name }} CI_JOB_DOC_URL: ${{ matrix.doc_url }} @@ -313,7 +314,7 @@ jobs: needs: [ calculate_matrix, job ] # !cancelled() executes the job regardless of whether the previous jobs passed or failed if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }} - environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto')) && 'bors') || '' }} + environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} steps: - name: checkout the source code uses: actions/checkout@v5 diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 4fe9cee900ca..d7b491d38f41 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -46,7 +46,9 @@ impl GitHubContext { let patterns = if !patterns.is_empty() { Some(patterns) } else { None }; Some(RunType::TryJob { job_patterns: patterns }) } - ("push", "refs/heads/auto") => Some(RunType::AutoJob), + ("push", "refs/heads/auto" | "refs/heads/automation/bors/auto") => { + Some(RunType::AutoJob) + } ("push", "refs/heads/main") => Some(RunType::MainJob), _ => None, } From 2827b1b83d3df46ebaf2e6bee798a108bf212b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 7 Jan 2026 12:55:38 +0100 Subject: [PATCH 1878/3801] Make verify-channel.sh script compatible with new bors (cherry picked from commit 6f7313e8adaec57196cec3d368cac8dd5fbf3d99) --- src/ci/scripts/verify-channel.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/scripts/verify-channel.sh b/src/ci/scripts/verify-channel.sh index 9a9e713243d7..cac8ba332ed1 100755 --- a/src/ci/scripts/verify-channel.sh +++ b/src/ci/scripts/verify-channel.sh @@ -8,7 +8,8 @@ IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" -if isCiBranch auto || isCiBranch try || isCiBranch try-perf || isCiBranch automation/bors/try; then +if isCiBranch auto || isCiBranch try || isCiBranch try-perf || \ + isCiBranch automation/bors/try || isCiBranch automation/bors/auto; then echo "channel verification is only executed on PR builds" exit fi From 05448c2b8d235673452dba288887a69a8b10e827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 7 Jan 2026 22:45:41 +0100 Subject: [PATCH 1879/3801] Update bors e-mail lookup (cherry picked from commit 138cc27f490aac4f98325a27853c3b0d7d25ae77) --- .github/workflows/post-merge.yml | 2 +- src/build_helper/src/git.rs | 24 ++++++++++++++++++++++-- src/stage0 | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index d38cc0e8a17f..51e0a40d46f2 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -29,7 +29,7 @@ jobs: sleep 60 # Get closest bors merge commit - PARENT_COMMIT=`git rev-list --author='bors ' -n1 --first-parent HEAD^1` + PARENT_COMMIT=`git rev-list --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` echo "Parent: ${PARENT_COMMIT}" # Find PR for the current commit diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 42d9b00f004a..1fdc2ddb4cfc 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -152,6 +152,14 @@ pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool { }) } +const LEGACY_BORS_EMAIL: &str = "bors@rust-lang.org"; + +/// Escape characters from the git user e-mail, so that git commands do not interpret it as regex +/// special characters. +fn escape_email_git_regex(text: &str) -> String { + text.replace("[", "\\[").replace("]", "\\]").replace(".", "\\.") +} + /// Returns the latest upstream commit that modified `target_paths`, or `None` if no such commit /// was found. fn get_latest_upstream_commit_that_modified_files( @@ -182,9 +190,15 @@ fn get_latest_upstream_commit_that_modified_files( "-n1", &upstream, "--author", - git_config.git_merge_commit_email, + &escape_email_git_regex(git_config.git_merge_commit_email), ]); + // Also search for legacy bors account, before we accrue enough commits to + // have changes to all relevant file paths done by new bors. + if git_config.git_merge_commit_email != LEGACY_BORS_EMAIL { + git.args(["--author", LEGACY_BORS_EMAIL]); + } + if !target_paths.is_empty() { git.arg("--").args(target_paths); } @@ -229,11 +243,17 @@ pub fn get_closest_upstream_commit( git.args([ "rev-list", "--author-date-order", - &format!("--author={}", config.git_merge_commit_email), + &format!("--author={}", &escape_email_git_regex(config.git_merge_commit_email),), "-n1", base, ]); + // Also search for legacy bors account, before we accrue enough commits to + // have changes to all relevant file paths done by new bors. + if config.git_merge_commit_email != LEGACY_BORS_EMAIL { + git.args(["--author", LEGACY_BORS_EMAIL]); + } + let output = output_result(&mut git)?.trim().to_owned(); if output.is_empty() { Ok(None) } else { Ok(Some(output)) } } diff --git a/src/stage0 b/src/stage0 index ea0fe3bf84c4..0686ddef7d95 100644 --- a/src/stage0 +++ b/src/stage0 @@ -1,7 +1,7 @@ dist_server=https://static.rust-lang.org artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt -git_merge_commit_email=bors@rust-lang.org +git_merge_commit_email=122020455+rust-bors[bot]@users.noreply.github.com nightly_branch=main # The configuration above this comment is editable, and can be changed From 4dc996fa0fd37f46ffe0327391e3f6b193dc925b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 7 Jan 2026 22:50:35 +0100 Subject: [PATCH 1880/3801] Remove unused environment variable Its last use was removed in https://github.com/rust-lang/rust/pull/142827. (cherry picked from commit f2d0d52c2fe5c6719480b422578038000fcfa00a) --- src/ci/docker/run.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 044f5a8fff32..691b8b8deb81 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -312,16 +312,6 @@ else command=(/checkout/src/ci/run.sh) fi -if isCI; then - # Get some needed information for $BASE_COMMIT - # - # This command gets the last merge commit which we'll use as base to list - # deleted files since then. - BASE_COMMIT="$(git log --author=bors@rust-lang.org -n 2 --pretty=format:%H | tail -n 1)" -else - BASE_COMMIT="" -fi - SUMMARY_FILE=github-summary.md touch $objdir/${SUMMARY_FILE} @@ -359,7 +349,6 @@ docker \ --env RUST_CI_OVERRIDE_RELEASE_CHANNEL \ --env CI_JOB_NAME="${CI_JOB_NAME-$image}" \ --env CI_JOB_DOC_URL="${CI_JOB_DOC_URL}" \ - --env BASE_COMMIT="$BASE_COMMIT" \ --env DIST_TRY_BUILD \ --env PR_CI_JOB \ --env OBJDIR_ON_HOST="$objdir" \ From 6f12b86e9c0703114d3496abf3d7e93f080c6d5e Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 8 Jan 2026 19:41:35 +0100 Subject: [PATCH 1881/3801] s390x: support `f16` and `f16x8` in inline assembly --- compiler/rustc_target/src/asm/s390x.rs | 6 +-- tests/assembly-llvm/asm/s390x-types.rs | 46 ++++++++++++++++++- .../ui/asm/s390x/bad-reg.s390x_vector.stderr | 6 +-- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index 410590b722b1..37176c0d73ea 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -42,13 +42,13 @@ impl S390xInlineAsmRegClass { ) -> &'static [(InlineAsmType, Option)] { match self { Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; }, - Self::freg => types! { _: F32, F64; }, + Self::freg => types! { _: F16, F32, F64; }, Self::vreg => { if allow_experimental_reg { // non-clobber-only vector register support is unstable. types! { - vector: I32, F32, I64, F64, I128, F128, - VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2); + vector: I32, F16, F32, I64, F64, I128, F128, + VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2); } } else { &[] diff --git a/tests/assembly-llvm/asm/s390x-types.rs b/tests/assembly-llvm/asm/s390x-types.rs index 24db91bf7772..10e2966ace0a 100644 --- a/tests/assembly-llvm/asm/s390x-types.rs +++ b/tests/assembly-llvm/asm/s390x-types.rs @@ -6,8 +6,9 @@ //@[s390x_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector //@[s390x_vector] needs-llvm-components: systemz //@ compile-flags: -Zmerge-functions=disabled +//@ min-llvm-version: 21 -#![feature(no_core, repr_simd, f128)] +#![feature(no_core, repr_simd, f16, f128)] #![cfg_attr(s390x_vector, feature(asm_experimental_reg))] #![crate_type = "rlib"] #![no_core] @@ -27,6 +28,8 @@ pub struct i32x4([i32; 4]); #[repr(simd)] pub struct i64x2([i64; 2]); #[repr(simd)] +pub struct f16x8([f16; 8]); +#[repr(simd)] pub struct f32x4([f32; 4]); #[repr(simd)] pub struct f64x2([f64; 2]); @@ -35,6 +38,7 @@ impl Copy for i8x16 {} impl Copy for i16x8 {} impl Copy for i32x4 {} impl Copy for i64x2 {} +impl Copy for f16x8 {} impl Copy for f32x4 {} impl Copy for f64x2 {} @@ -127,6 +131,12 @@ check!(reg_i32_addr, i32, reg_addr, "lgr"); // CHECK: #NO_APP check!(reg_i64_addr, i64, reg_addr, "lgr"); +// CHECK-LABEL: reg_f16: +// CHECK: #APP +// CHECK: ler %f{{[0-9]+}}, %f{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_f16, f16, freg, "ler"); + // CHECK-LABEL: reg_f32: // CHECK: #APP // CHECK: ler %f{{[0-9]+}}, %f{{[0-9]+}} @@ -173,6 +183,13 @@ check!(vreg_i32x4, i32x4, vreg, "vlr"); #[cfg(s390x_vector)] check!(vreg_i64x2, i64x2, vreg, "vlr"); +// s390x_vector-LABEL: vreg_f16x8: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_f16x8, f16x8, vreg, "vlr"); + // s390x_vector-LABEL: vreg_f32x4: // s390x_vector: #APP // s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} @@ -208,6 +225,13 @@ check!(vreg_i64, i64, vreg, "vlr"); #[cfg(s390x_vector)] check!(vreg_i128, i128, vreg, "vlr"); +// s390x_vector-LABEL: vreg_f16: +// s390x_vector: #APP +// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check!(vreg_f16, f16, vreg, "vlr"); + // s390x_vector-LABEL: vreg_f32: // s390x_vector: #APP // s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}} @@ -253,6 +277,12 @@ check_reg!(r0_i32, i32, "r0", "lr"); // CHECK: #NO_APP check_reg!(r0_i64, i64, "r0", "lr"); +// CHECK-LABEL: f0_f16: +// CHECK: #APP +// CHECK: ler %f0, %f0 +// CHECK: #NO_APP +check_reg!(f0_f16, f16, "f0", "ler"); + // CHECK-LABEL: f0_f32: // CHECK: #APP // CHECK: ler %f0, %f0 @@ -293,6 +323,13 @@ check_reg!(v0_i32x4, i32x4, "v0", "vlr"); #[cfg(s390x_vector)] check_reg!(v0_i64x2, i64x2, "v0", "vlr"); +// s390x_vector-LABEL: v0_f16x8: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_f16x8, f16x8, "v0", "vlr"); + // s390x_vector-LABEL: v0_f32x4: // s390x_vector: #APP // s390x_vector: vlr %v0, %v0 @@ -328,6 +365,13 @@ check_reg!(v0_i64, i64, "v0", "vlr"); #[cfg(s390x_vector)] check_reg!(v0_i128, i128, "v0", "vlr"); +// s390x_vector-LABEL: v0_f16: +// s390x_vector: #APP +// s390x_vector: vlr %v0, %v0 +// s390x_vector: #NO_APP +#[cfg(s390x_vector)] +check_reg!(v0_f16, f16, "v0", "vlr"); + // s390x_vector-LABEL: v0_f32: // s390x_vector: #APP // s390x_vector: vlr %v0, %v0 diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr index 897f872ae72a..8e2da4dcc2a4 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr @@ -282,7 +282,7 @@ error: type `u8` cannot be used with this register class LL | asm!("", in("v0") b); | ^ | - = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `u8` cannot be used with this register class --> $DIR/bad-reg.rs:95:28 @@ -290,7 +290,7 @@ error: type `u8` cannot be used with this register class LL | asm!("", out("v0") b); | ^ | - = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `u8` cannot be used with this register class --> $DIR/bad-reg.rs:108:35 @@ -298,7 +298,7 @@ error: type `u8` cannot be used with this register class LL | asm!("/* {} */", in(vreg) b); | ^ | - = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:120:27 From 0401e792f470e1cb776c522da1fb4da47541b508 Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Fri, 9 Jan 2026 13:49:17 -0500 Subject: [PATCH 1882/3801] Fix a trivial typo --- compiler/rustc_span/src/def_id.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 484e626d4638..a0ccf8d7e798 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -81,7 +81,7 @@ impl fmt::Display for CrateNum { /// because it depends on the set of crates in the entire crate graph of a /// compilation session. Again, using the same crate with a different version /// number would fix the issue with a high probability -- but that might be -/// easier said then done if the crates in questions are dependencies of +/// easier said than done if the crates in questions are dependencies of /// third-party crates. /// /// That being said, given a high quality hash function, the collision From f73e504eea0a2cdd90fa1e27b8faa1ffd93ed370 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 9 Jan 2026 20:20:35 +0100 Subject: [PATCH 1883/3801] fix(useless_conversion): respect reduced applicability --- clippy_lints/src/useless_conversion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index 423301edfe83..4ce132e9e3ab 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -365,7 +365,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { format!("useless conversion to the same type: `{b}`"), "consider removing `.into_iter()`", sugg, - Applicability::MachineApplicable, // snippet + applicability, ); } } From f9c71df88ab864536d07a3a98341d3200aae7603 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 9 Jan 2026 17:40:28 +0100 Subject: [PATCH 1884/3801] Improve span for "unresolved intra doc link" on `deprecated` attribute --- compiler/rustc_ast/src/attr/mod.rs | 8 +++---- .../src/attributes/deprecation.rs | 22 ++++++++++++------- compiler/rustc_attr_parsing/src/parser.rs | 7 ++++++ .../rustc_hir/src/attrs/data_structures.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_middle/src/middle/stability.rs | 4 ++-- src/librustdoc/clean/types.rs | 6 ++--- tests/rustdoc-ui/intra-doc/deprecated.stderr | 12 +++++----- tests/ui/unpretty/deprecated-attr.stdout | 8 +++---- 9 files changed, 42 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 0a2a34d932f6..b9411a3269a5 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -235,14 +235,14 @@ impl AttributeExt for Attribute { } } - fn deprecation_note(&self) -> Option { + fn deprecation_note(&self) -> Option { match &self.kind { AttrKind::Normal(normal) if normal.item.path == sym::deprecated => { let meta = &normal.item; // #[deprecated = "..."] if let Some(s) = meta.value_str() { - return Some(s); + return Some(Ident { name: s, span: meta.span() }); } // #[deprecated(note = "...")] @@ -252,7 +252,7 @@ impl AttributeExt for Attribute { && mi.path == sym::note && let Some(s) = mi.value_str() { - return Some(s); + return Some(Ident { name: s, span: mi.span }); } } } @@ -905,7 +905,7 @@ pub trait AttributeExt: Debug { /// Returns the deprecation note if this is deprecation attribute. /// * `#[deprecated = "note"]` returns `Some("note")`. /// * `#[deprecated(note = "note", ...)]` returns `Some("note")`. - fn deprecation_note(&self) -> Option; + fn deprecation_note(&self) -> Option; fn is_proc_macro_attr(&self) -> bool { [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs index 2d79e3a103d6..e01377d247bb 100644 --- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs +++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs @@ -13,14 +13,14 @@ fn get( name: Symbol, param_span: Span, arg: &ArgParser, - item: &Option, -) -> Option { + item: Option, +) -> Option { if item.is_some() { cx.duplicate_key(param_span, name); return None; } if let Some(v) = arg.name_value() { - if let Some(value_str) = v.value_as_str() { + if let Some(value_str) = v.value_as_ident() { Some(value_str) } else { cx.expected_string_literal(v.value_span, Some(&v.value_as_lit())); @@ -72,7 +72,7 @@ impl SingleAttributeParser for DeprecationParser { let features = cx.features(); let mut since = None; - let mut note = None; + let mut note: Option = None; let mut suggestion = None; let is_rustc = features.staged_api(); @@ -92,10 +92,16 @@ impl SingleAttributeParser for DeprecationParser { match ident_name { Some(name @ sym::since) => { - since = Some(get(cx, name, param.span(), param.args(), &since)?); + since = Some(get(cx, name, param.span(), param.args(), since)?.name); } Some(name @ sym::note) => { - note = Some(get(cx, name, param.span(), param.args(), ¬e)?); + note = Some(get( + cx, + name, + param.span(), + param.args(), + note.map(|ident| ident.name), + )?); } Some(name @ sym::suggestion) => { if !features.deprecated_suggestion() { @@ -107,7 +113,7 @@ impl SingleAttributeParser for DeprecationParser { } suggestion = - Some(get(cx, name, param.span(), param.args(), &suggestion)?); + Some(get(cx, name, param.span(), param.args(), suggestion)?.name); } _ => { cx.expected_specific_argument( @@ -124,7 +130,7 @@ impl SingleAttributeParser for DeprecationParser { } } ArgParser::NameValue(v) => { - let Some(value) = v.value_as_str() else { + let Some(value) = v.value_as_ident() else { cx.expected_string_literal(v.value_span, Some(v.value_as_lit())); return None; }; diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index d79579fdf0b7..68265649d182 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -322,6 +322,13 @@ impl NameValueParser { self.value_as_lit().kind.str() } + /// If the value is a string literal, it will return its value associated with its span (an + /// `Ident` in short). + pub fn value_as_ident(&self) -> Option { + let meta_item = self.value_as_lit(); + meta_item.kind.str().map(|name| Ident { name, span: meta_item.span }) + } + pub fn args_span(&self) -> Span { self.eq_span.to(self.value_span) } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index fa8998f0546d..7c2700cea058 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -123,7 +123,7 @@ pub enum IntType { pub struct Deprecation { pub since: DeprecatedSince, /// The note to issue a reason. - pub note: Option, + pub note: Option, /// A text snippet used to completely replace any use of the deprecated item in an expression. /// /// This is currently unstable. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2fb6daf6469b..1b59d76be68c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1402,7 +1402,7 @@ impl AttributeExt for Attribute { } #[inline] - fn deprecation_note(&self) -> Option { + fn deprecation_note(&self) -> Option { match &self { Attribute::Parsed(AttributeKind::Deprecation { deprecation, .. }) => deprecation.note, _ => None, diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 18520089e3ea..63bbd1a0b854 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -185,7 +185,7 @@ pub fn early_report_macro_deprecation( let diag = BuiltinLintDiag::DeprecatedMacro { suggestion: depr.suggestion, suggestion_span: span, - note: depr.note, + note: depr.note.map(|ident| ident.name), path, since_kind: deprecated_since_kind(is_in_effect, depr.since), }; @@ -228,7 +228,7 @@ fn late_report_deprecation( }), kind: def_kind.to_owned(), path: def_path, - note: depr.note, + note: depr.note.map(|ident| ident.name), since_kind: deprecated_since_kind(is_in_effect, depr.since), }; tcx.emit_node_span_lint(lint, hir_id, method_span, diag); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c3bafd3db13a..c2e63f475bec 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -26,7 +26,7 @@ use rustc_resolve::rustdoc::{ use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Symbol, kw, sym}; -use rustc_span::{DUMMY_SP, FileName, Loc, RemapPathScopeComponents}; +use rustc_span::{DUMMY_SP, FileName, Ident, Loc, RemapPathScopeComponents}; use tracing::{debug, trace}; use {rustc_ast as ast, rustc_hir as hir}; @@ -418,7 +418,7 @@ impl Item { { Some(Deprecation { since: DeprecatedSince::Unspecified, - note: Some(note), + note: Some(Ident { name: note, span: DUMMY_SP }), suggestion: None, }) } else { @@ -455,7 +455,7 @@ impl Item { .attrs .other_attrs .iter() - .filter_map(|attr| attr.deprecation_note().map(|_| attr.span())); + .filter_map(|attr| attr.deprecation_note().map(|note| note.span)); span_of_fragments(&self.attrs.doc_strings) .into_iter() diff --git a/tests/rustdoc-ui/intra-doc/deprecated.stderr b/tests/rustdoc-ui/intra-doc/deprecated.stderr index 9bd64544eef8..85290c334626 100644 --- a/tests/rustdoc-ui/intra-doc/deprecated.stderr +++ b/tests/rustdoc-ui/intra-doc/deprecated.stderr @@ -1,8 +1,8 @@ error: unresolved link to `TypeAlias::hoge` - --> $DIR/deprecated.rs:3:1 + --> $DIR/deprecated.rs:3:16 | LL | #[deprecated = "[broken cross-reference](TypeAlias::hoge)"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: @@ -16,10 +16,10 @@ LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unresolved link to `TypeAlias::hoge` - --> $DIR/deprecated.rs:6:1 + --> $DIR/deprecated.rs:6:38 | LL | #[deprecated(since = "0.0.0", note = "[broken cross-reference](TypeAlias::hoge)")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: @@ -28,10 +28,10 @@ LL | #[deprecated(since = "0.0.0", note = "[broken cross-reference](TypeAlias::h = note: no item named `TypeAlias` in scope error: unresolved link to `TypeAlias::hoge` - --> $DIR/deprecated.rs:9:1 + --> $DIR/deprecated.rs:9:21 | LL | #[deprecated(note = "[broken cross-reference](TypeAlias::hoge)", since = "0.0.0")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout index 26cc74c11604..976598b0bfa3 100644 --- a/tests/ui/unpretty/deprecated-attr.stdout +++ b/tests/ui/unpretty/deprecated-attr.stdout @@ -10,19 +10,19 @@ use ::std::prelude::rust_2015::*; struct PlainDeprecated; #[attr = Deprecation {deprecation: Deprecation {since: Unspecified, -note: "here's why this is deprecated"}}] +note: here's why this is deprecated#0}}] struct DirectNote; #[attr = Deprecation {deprecation: Deprecation {since: Unspecified, -note: "here's why this is deprecated"}}] +note: here's why this is deprecated#0}}] struct ExplicitNote; #[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"), -note: "here's why this is deprecated"}}] +note: here's why this is deprecated#0}}] struct SinceAndNote; #[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"), -note: "here's why this is deprecated"}}] +note: here's why this is deprecated#0}}] struct FlippedOrder; fn f() { From 9d2ce878106ab85b2b098358ccd094a0cf7415c3 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 9 Jan 2026 20:42:01 +0100 Subject: [PATCH 1885/3801] Don't check `[mentions]` paths in submodules from tidy --- src/tools/tidy/src/triagebot.rs | 38 +++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/triagebot.rs b/src/tools/tidy/src/triagebot.rs index 59cd9d80b07a..a74d980cfcb7 100644 --- a/src/tools/tidy/src/triagebot.rs +++ b/src/tools/tidy/src/triagebot.rs @@ -2,11 +2,22 @@ use std::collections::HashSet; use std::path::Path; +use std::sync::LazyLock; use toml::Value; use crate::diagnostics::TidyCtx; +static SUBMODULES: LazyLock> = LazyLock::new(|| { + // WORKSPACES doesn't list all submodules but it's contains the main at least + crate::deps::WORKSPACES + .iter() + .map(|ws| ws.submodules.iter()) + .flatten() + .map(|p| Path::new(p)) + .collect() +}); + pub fn check(path: &Path, tidy_ctx: TidyCtx) { let mut check = tidy_ctx.start_check("triagebot"); let triagebot_path = path.join("triagebot.toml"); @@ -39,8 +50,13 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) { if !full_path.exists() { // The full-path doesn't exists, maybe it's a glob, let's add it to the glob set builder // to be checked against all the file and directories in the repository. - builder.add(globset::Glob::new(&format!("{clean_path}*")).unwrap()); + let trimmed_path = clean_path.trim_end_matches('/'); + builder.add(globset::Glob::new(&format!("{trimmed_path}{{,/*}}")).unwrap()); glob_entries.push(clean_path.to_string()); + } else if is_in_submodule(Path::new(clean_path)) { + check.error(format!( + "triagebot.toml [mentions.*] '{clean_path}' cannot match inside a submodule" + )); } } @@ -49,8 +65,18 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) { let mut found = HashSet::new(); let mut matches = Vec::new(); + let cloned_path = path.to_path_buf(); + // Walk the entire repository and match any entry against the remaining paths - for entry in ignore::WalkBuilder::new(path).build().flatten() { + for entry in ignore::WalkBuilder::new(&path) + .filter_entry(move |entry| { + // Ignore entries inside submodules as triagebot cannot detect them + let entry_path = entry.path().strip_prefix(&cloned_path).unwrap(); + is_not_in_submodule(entry_path) + }) + .build() + .flatten() + { // Strip the prefix as mentions entries are always relative to the repo let entry_path = entry.path().strip_prefix(path).unwrap(); @@ -126,3 +152,11 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) { } } } + +fn is_not_in_submodule(path: &Path) -> bool { + SUBMODULES.contains(&path) || !SUBMODULES.iter().any(|p| path.starts_with(*p)) +} + +fn is_in_submodule(path: &Path) -> bool { + !SUBMODULES.contains(&path) && SUBMODULES.iter().any(|p| path.starts_with(*p)) +} From 8e61f0de27b038e6bdb245e192aa2ae48c677523 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 9 Jan 2026 22:47:59 +0200 Subject: [PATCH 1886/3801] cg_llvm: add a pause to make comment less confusing --- compiler/rustc_codegen_llvm/src/mono_item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 3ce28612ddfc..54ba671b09bc 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -153,7 +153,7 @@ impl CodegenCx<'_, '_> { return false; } - // With pie relocation model calls of functions defined in the translation + // With pie relocation model, calls of functions defined in the translation // unit can use copy relocations. if self.tcx.sess.relocation_model() == RelocModel::Pie && !is_declaration { return true; From 229673ac85ef40dca4f2bbcb984cfd4d50a9b02d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 9 Jan 2026 22:49:32 +0200 Subject: [PATCH 1887/3801] make sentence more simple --- compiler/rustc_codegen_llvm/src/mono_item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 54ba671b09bc..1878f4043ee8 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -111,7 +111,7 @@ impl CodegenCx<'_, '_> { } } - /// Whether a definition or declaration can be assumed to be local to a group of + /// A definition or declaration can be assumed to be local to a group of /// libraries that form a single DSO or executable. /// Marks the local as DSO if so. pub(crate) fn assume_dso_local(&self, llval: &llvm::Value, is_declaration: bool) -> bool { From 3ec7666a2ac99ccfa9de268a89d855ceb380024c Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 9 Jan 2026 20:43:26 +0100 Subject: [PATCH 1888/3801] clean-up --- clippy_lints/src/int_plus_one.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs index 67ce57de254d..540f9bb1e260 100644 --- a/clippy_lints/src/int_plus_one.rs +++ b/clippy_lints/src/int_plus_one.rs @@ -100,7 +100,7 @@ impl IntPlusOne { _ => None, } }, - // case where `... >= y - 1` or `... >= -1 + y` + // case where `... <= y - 1` or `... <= -1 + y` (BinOpKind::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => { match (rhskind.node, &rhslhs.kind, &rhsrhs.kind) { // `-1 + y` @@ -156,11 +156,11 @@ impl IntPlusOne { } impl EarlyLintPass for IntPlusOne { - fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) { - if let ExprKind::Binary(ref kind, ref lhs, ref rhs) = item.kind + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { + if let ExprKind::Binary(kind, lhs, rhs) = &expr.kind && let Some(rec) = Self::check_binop(cx, kind.node, lhs, rhs) { - Self::emit_warning(cx, item, rec); + Self::emit_warning(cx, expr, rec); } } } From 0180ec4d5d9e47b1b36bf33d783ac72600c4abd4 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 9 Jan 2026 22:38:08 +0100 Subject: [PATCH 1889/3801] fix: negative literals are not literals --- clippy_lints/src/int_plus_one.rs | 67 ++++++++++++++++++-------------- tests/ui/int_plus_one.fixed | 16 ++++---- tests/ui/int_plus_one.rs | 16 ++++---- tests/ui/int_plus_one.stderr | 26 ++++++++++++- 4 files changed, 78 insertions(+), 47 deletions(-) diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs index 540f9bb1e260..c25821751b3f 100644 --- a/clippy_lints/src/int_plus_one.rs +++ b/clippy_lints/src/int_plus_one.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::SpanRangeExt; -use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind}; -use rustc_ast::token; +use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind, UnOp}; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; @@ -50,25 +50,36 @@ enum Side { } impl IntPlusOne { - #[expect(clippy::cast_sign_loss)] - fn check_lit(token_lit: token::Lit, target_value: i128) -> bool { - if let Ok(LitKind::Int(value, ..)) = LitKind::from_token_lit(token_lit) { - return value == (target_value as u128); + fn is_one(expr: &Expr) -> bool { + if let ExprKind::Lit(token_lit) = expr.kind + && let Ok(LitKind::Int(Pu128(1), ..)) = LitKind::from_token_lit(token_lit) + { + return true; } false } + fn is_neg_one(expr: &Expr) -> bool { + if let ExprKind::Unary(UnOp::Neg, expr) = &expr.kind + && Self::is_one(expr) + { + true + } else { + false + } + } + fn check_binop(cx: &EarlyContext<'_>, binop: BinOpKind, lhs: &Expr, rhs: &Expr) -> Option { match (binop, &lhs.kind, &rhs.kind) { // case where `x - 1 >= ...` or `-1 + x >= ...` (BinOpKind::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => { - match (lhskind.node, &lhslhs.kind, &lhsrhs.kind) { + match lhskind.node { // `-1 + x` - (BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(*lit, -1) => { + BinOpKind::Add if Self::is_neg_one(lhslhs) => { Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs) }, // `x - 1` - (BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => { + BinOpKind::Sub if Self::is_one(lhsrhs) => { Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs) }, _ => None, @@ -76,39 +87,35 @@ impl IntPlusOne { }, // case where `... >= y + 1` or `... >= 1 + y` (BinOpKind::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => { - match (&rhslhs.kind, &rhsrhs.kind) { - // `y + 1` and `1 + y` - (ExprKind::Lit(lit), _) if Self::check_lit(*lit, 1) => { - Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs) - }, - (_, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => { - Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs) - }, - _ => None, + // `y + 1` and `1 + y` + if Self::is_one(rhslhs) { + Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs) + } else if Self::is_one(rhsrhs) { + Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs) + } else { + None } }, // case where `x + 1 <= ...` or `1 + x <= ...` (BinOpKind::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => { - match (&lhslhs.kind, &lhsrhs.kind) { - // `1 + x` and `x + 1` - (ExprKind::Lit(lit), _) if Self::check_lit(*lit, 1) => { - Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs) - }, - (_, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => { - Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs) - }, - _ => None, + // `1 + x` and `x + 1` + if Self::is_one(lhslhs) { + Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs) + } else if Self::is_one(lhsrhs) { + Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs) + } else { + None } }, // case where `... <= y - 1` or `... <= -1 + y` (BinOpKind::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => { - match (rhskind.node, &rhslhs.kind, &rhsrhs.kind) { + match rhskind.node { // `-1 + y` - (BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(*lit, -1) => { + BinOpKind::Add if Self::is_neg_one(rhslhs) => { Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs) }, // `y - 1` - (BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => { + BinOpKind::Sub if Self::is_one(rhsrhs) => { Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs) }, _ => None, diff --git a/tests/ui/int_plus_one.fixed b/tests/ui/int_plus_one.fixed index a1aba6bf7f64..cdd19515e9a7 100644 --- a/tests/ui/int_plus_one.fixed +++ b/tests/ui/int_plus_one.fixed @@ -4,15 +4,15 @@ fn main() { let x = 1i32; let y = 0i32; - let _ = x > y; - //~^ int_plus_one - let _ = y < x; - //~^ int_plus_one + let _ = x > y; //~ int_plus_one + let _ = x > y; //~ int_plus_one + let _ = y < x; //~ int_plus_one + let _ = y < x; //~ int_plus_one - let _ = x > y; - //~^ int_plus_one - let _ = y < x; - //~^ int_plus_one + let _ = x > y; //~ int_plus_one + let _ = x > y; //~ int_plus_one + let _ = y < x; //~ int_plus_one + let _ = y < x; //~ int_plus_one let _ = x > y; // should be ok let _ = y < x; // should be ok diff --git a/tests/ui/int_plus_one.rs b/tests/ui/int_plus_one.rs index f804fc9047de..8d7d2e8982d8 100644 --- a/tests/ui/int_plus_one.rs +++ b/tests/ui/int_plus_one.rs @@ -4,15 +4,15 @@ fn main() { let x = 1i32; let y = 0i32; - let _ = x >= y + 1; - //~^ int_plus_one - let _ = y + 1 <= x; - //~^ int_plus_one + let _ = x >= y + 1; //~ int_plus_one + let _ = x >= 1 + y; //~ int_plus_one + let _ = y + 1 <= x; //~ int_plus_one + let _ = 1 + y <= x; //~ int_plus_one - let _ = x - 1 >= y; - //~^ int_plus_one - let _ = y <= x - 1; - //~^ int_plus_one + let _ = x - 1 >= y; //~ int_plus_one + let _ = -1 + x >= y; //~ int_plus_one + let _ = y <= x - 1; //~ int_plus_one + let _ = y <= -1 + x; //~ int_plus_one let _ = x > y; // should be ok let _ = y < x; // should be ok diff --git a/tests/ui/int_plus_one.stderr b/tests/ui/int_plus_one.stderr index 052706028141..8bdff5680bdc 100644 --- a/tests/ui/int_plus_one.stderr +++ b/tests/ui/int_plus_one.stderr @@ -7,23 +7,47 @@ LL | let _ = x >= y + 1; = note: `-D clippy::int-plus-one` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::int_plus_one)]` +error: unnecessary `>= y + 1` or `x - 1 >=` + --> tests/ui/int_plus_one.rs:8:13 + | +LL | let _ = x >= 1 + y; + | ^^^^^^^^^^ help: change it to: `x > y` + error: unnecessary `>= y + 1` or `x - 1 >=` --> tests/ui/int_plus_one.rs:9:13 | LL | let _ = y + 1 <= x; | ^^^^^^^^^^ help: change it to: `y < x` +error: unnecessary `>= y + 1` or `x - 1 >=` + --> tests/ui/int_plus_one.rs:10:13 + | +LL | let _ = 1 + y <= x; + | ^^^^^^^^^^ help: change it to: `y < x` + error: unnecessary `>= y + 1` or `x - 1 >=` --> tests/ui/int_plus_one.rs:12:13 | LL | let _ = x - 1 >= y; | ^^^^^^^^^^ help: change it to: `x > y` +error: unnecessary `>= y + 1` or `x - 1 >=` + --> tests/ui/int_plus_one.rs:13:13 + | +LL | let _ = -1 + x >= y; + | ^^^^^^^^^^^ help: change it to: `x > y` + error: unnecessary `>= y + 1` or `x - 1 >=` --> tests/ui/int_plus_one.rs:14:13 | LL | let _ = y <= x - 1; | ^^^^^^^^^^ help: change it to: `y < x` -error: aborting due to 4 previous errors +error: unnecessary `>= y + 1` or `x - 1 >=` + --> tests/ui/int_plus_one.rs:15:13 + | +LL | let _ = y <= -1 + x; + | ^^^^^^^^^^^ help: change it to: `y < x` + +error: aborting due to 8 previous errors From df65d1a6a8509f9167078aab372f59ac7762af6c Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 9 Jan 2026 20:39:42 +0100 Subject: [PATCH 1890/3801] introduce `LeOrGe` removes the need for a wildcard match --- clippy_lints/src/int_plus_one.rs | 63 ++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs index c25821751b3f..8143dbad79e8 100644 --- a/clippy_lints/src/int_plus_one.rs +++ b/clippy_lints/src/int_plus_one.rs @@ -35,11 +35,11 @@ declare_clippy_lint! { declare_lint_pass!(IntPlusOne => [INT_PLUS_ONE]); // cases: -// BinOpKind::Ge +// LeOrGe::Ge // x >= y + 1 // x - 1 >= y // -// BinOpKind::Le +// LeOrGe::Le // x + 1 <= y // x <= y - 1 @@ -49,6 +49,23 @@ enum Side { Rhs, } +#[derive(Copy, Clone)] +enum LeOrGe { + Le, + Ge, +} + +impl TryFrom for LeOrGe { + type Error = (); + fn try_from(value: BinOpKind) -> Result { + match value { + BinOpKind::Le => Ok(Self::Le), + BinOpKind::Ge => Ok(Self::Ge), + _ => Err(()), + } + } +} + impl IntPlusOne { fn is_one(expr: &Expr) -> bool { if let ExprKind::Lit(token_lit) = expr.kind @@ -69,54 +86,54 @@ impl IntPlusOne { } } - fn check_binop(cx: &EarlyContext<'_>, binop: BinOpKind, lhs: &Expr, rhs: &Expr) -> Option { - match (binop, &lhs.kind, &rhs.kind) { + fn check_binop(cx: &EarlyContext<'_>, le_or_ge: LeOrGe, lhs: &Expr, rhs: &Expr) -> Option { + match (le_or_ge, &lhs.kind, &rhs.kind) { // case where `x - 1 >= ...` or `-1 + x >= ...` - (BinOpKind::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => { + (LeOrGe::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => { match lhskind.node { // `-1 + x` BinOpKind::Add if Self::is_neg_one(lhslhs) => { - Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs) + Self::generate_recommendation(cx, le_or_ge, lhsrhs, rhs, Side::Lhs) }, // `x - 1` BinOpKind::Sub if Self::is_one(lhsrhs) => { - Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs) + Self::generate_recommendation(cx, le_or_ge, lhslhs, rhs, Side::Lhs) }, _ => None, } }, // case where `... >= y + 1` or `... >= 1 + y` - (BinOpKind::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => { + (LeOrGe::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => { // `y + 1` and `1 + y` if Self::is_one(rhslhs) { - Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs) + Self::generate_recommendation(cx, le_or_ge, rhsrhs, lhs, Side::Rhs) } else if Self::is_one(rhsrhs) { - Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs) + Self::generate_recommendation(cx, le_or_ge, rhslhs, lhs, Side::Rhs) } else { None } }, // case where `x + 1 <= ...` or `1 + x <= ...` - (BinOpKind::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => { + (LeOrGe::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => { // `1 + x` and `x + 1` if Self::is_one(lhslhs) { - Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs) + Self::generate_recommendation(cx, le_or_ge, lhsrhs, rhs, Side::Lhs) } else if Self::is_one(lhsrhs) { - Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs) + Self::generate_recommendation(cx, le_or_ge, lhslhs, rhs, Side::Lhs) } else { None } }, // case where `... <= y - 1` or `... <= -1 + y` - (BinOpKind::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => { + (LeOrGe::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => { match rhskind.node { // `-1 + y` BinOpKind::Add if Self::is_neg_one(rhslhs) => { - Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs) + Self::generate_recommendation(cx, le_or_ge, rhsrhs, lhs, Side::Rhs) }, // `y - 1` BinOpKind::Sub if Self::is_one(rhsrhs) => { - Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs) + Self::generate_recommendation(cx, le_or_ge, rhslhs, lhs, Side::Rhs) }, _ => None, } @@ -127,15 +144,14 @@ impl IntPlusOne { fn generate_recommendation( cx: &EarlyContext<'_>, - binop: BinOpKind, + le_or_ge: LeOrGe, node: &Expr, other_side: &Expr, side: Side, ) -> Option { - let binop_string = match binop { - BinOpKind::Ge => ">", - BinOpKind::Le => "<", - _ => return None, + let binop_string = match le_or_ge { + LeOrGe::Ge => ">", + LeOrGe::Le => "<", }; if let Some(snippet) = node.span.get_source_text(cx) && let Some(other_side_snippet) = other_side.span.get_source_text(cx) @@ -164,8 +180,9 @@ impl IntPlusOne { impl EarlyLintPass for IntPlusOne { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { - if let ExprKind::Binary(kind, lhs, rhs) = &expr.kind - && let Some(rec) = Self::check_binop(cx, kind.node, lhs, rhs) + if let ExprKind::Binary(binop, lhs, rhs) = &expr.kind + && let Ok(le_or_ge) = LeOrGe::try_from(binop.node) + && let Some(rec) = Self::check_binop(cx, le_or_ge, lhs, rhs) { Self::emit_warning(cx, expr, rec); } From d554092c27f0ad5cf8dc013b4fbcbd7853c40c0c Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 9 Jan 2026 21:01:55 +0100 Subject: [PATCH 1891/3801] get rid of `Side` --- clippy_lints/src/int_plus_one.rs | 33 +++++++++----------------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs index 8143dbad79e8..97b7afb61d86 100644 --- a/clippy_lints/src/int_plus_one.rs +++ b/clippy_lints/src/int_plus_one.rs @@ -43,12 +43,6 @@ declare_lint_pass!(IntPlusOne => [INT_PLUS_ONE]); // x + 1 <= y // x <= y - 1 -#[derive(Copy, Clone)] -enum Side { - Lhs, - Rhs, -} - #[derive(Copy, Clone)] enum LeOrGe { Le, @@ -93,12 +87,10 @@ impl IntPlusOne { match lhskind.node { // `-1 + x` BinOpKind::Add if Self::is_neg_one(lhslhs) => { - Self::generate_recommendation(cx, le_or_ge, lhsrhs, rhs, Side::Lhs) + Self::generate_recommendation(cx, le_or_ge, lhsrhs, rhs) }, // `x - 1` - BinOpKind::Sub if Self::is_one(lhsrhs) => { - Self::generate_recommendation(cx, le_or_ge, lhslhs, rhs, Side::Lhs) - }, + BinOpKind::Sub if Self::is_one(lhsrhs) => Self::generate_recommendation(cx, le_or_ge, lhslhs, rhs), _ => None, } }, @@ -106,9 +98,9 @@ impl IntPlusOne { (LeOrGe::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => { // `y + 1` and `1 + y` if Self::is_one(rhslhs) { - Self::generate_recommendation(cx, le_or_ge, rhsrhs, lhs, Side::Rhs) + Self::generate_recommendation(cx, le_or_ge, lhs, rhsrhs) } else if Self::is_one(rhsrhs) { - Self::generate_recommendation(cx, le_or_ge, rhslhs, lhs, Side::Rhs) + Self::generate_recommendation(cx, le_or_ge, lhs, rhslhs) } else { None } @@ -117,9 +109,9 @@ impl IntPlusOne { (LeOrGe::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => { // `1 + x` and `x + 1` if Self::is_one(lhslhs) { - Self::generate_recommendation(cx, le_or_ge, lhsrhs, rhs, Side::Lhs) + Self::generate_recommendation(cx, le_or_ge, lhsrhs, rhs) } else if Self::is_one(lhsrhs) { - Self::generate_recommendation(cx, le_or_ge, lhslhs, rhs, Side::Lhs) + Self::generate_recommendation(cx, le_or_ge, lhslhs, rhs) } else { None } @@ -129,12 +121,10 @@ impl IntPlusOne { match rhskind.node { // `-1 + y` BinOpKind::Add if Self::is_neg_one(rhslhs) => { - Self::generate_recommendation(cx, le_or_ge, rhsrhs, lhs, Side::Rhs) + Self::generate_recommendation(cx, le_or_ge, lhs, rhsrhs) }, // `y - 1` - BinOpKind::Sub if Self::is_one(rhsrhs) => { - Self::generate_recommendation(cx, le_or_ge, rhslhs, lhs, Side::Rhs) - }, + BinOpKind::Sub if Self::is_one(rhsrhs) => Self::generate_recommendation(cx, le_or_ge, lhs, rhslhs), _ => None, } }, @@ -147,7 +137,6 @@ impl IntPlusOne { le_or_ge: LeOrGe, node: &Expr, other_side: &Expr, - side: Side, ) -> Option { let binop_string = match le_or_ge { LeOrGe::Ge => ">", @@ -156,11 +145,7 @@ impl IntPlusOne { if let Some(snippet) = node.span.get_source_text(cx) && let Some(other_side_snippet) = other_side.span.get_source_text(cx) { - let rec = match side { - Side::Lhs => Some(format!("{snippet} {binop_string} {other_side_snippet}")), - Side::Rhs => Some(format!("{other_side_snippet} {binop_string} {snippet}")), - }; - return rec; + return Some(format!("{snippet} {binop_string} {other_side_snippet}")); } None } From ccaa2fa9841447092bfe96111629747a27fa419a Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 9 Jan 2026 20:30:20 +0100 Subject: [PATCH 1892/3801] fix: respect reduced applicability By building the whole suggestion in `emit_suggestion`, we avoid the need to thread `Applicability` through `check_binop` into `generate_suggestion` --- clippy_lints/src/int_plus_one.rs | 69 +++++++++++++------------------- 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs index 97b7afb61d86..b82ca0205a9f 100644 --- a/clippy_lints/src/int_plus_one.rs +++ b/clippy_lints/src/int_plus_one.rs @@ -1,5 +1,5 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::SpanRangeExt; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::sugg; use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind, UnOp}; use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; @@ -80,17 +80,15 @@ impl IntPlusOne { } } - fn check_binop(cx: &EarlyContext<'_>, le_or_ge: LeOrGe, lhs: &Expr, rhs: &Expr) -> Option { + fn check_binop<'tcx>(le_or_ge: LeOrGe, lhs: &'tcx Expr, rhs: &'tcx Expr) -> Option<(&'tcx Expr, &'tcx Expr)> { match (le_or_ge, &lhs.kind, &rhs.kind) { // case where `x - 1 >= ...` or `-1 + x >= ...` (LeOrGe::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => { match lhskind.node { // `-1 + x` - BinOpKind::Add if Self::is_neg_one(lhslhs) => { - Self::generate_recommendation(cx, le_or_ge, lhsrhs, rhs) - }, + BinOpKind::Add if Self::is_neg_one(lhslhs) => Some((lhsrhs, rhs)), // `x - 1` - BinOpKind::Sub if Self::is_one(lhsrhs) => Self::generate_recommendation(cx, le_or_ge, lhslhs, rhs), + BinOpKind::Sub if Self::is_one(lhsrhs) => Some((lhslhs, rhs)), _ => None, } }, @@ -98,9 +96,9 @@ impl IntPlusOne { (LeOrGe::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => { // `y + 1` and `1 + y` if Self::is_one(rhslhs) { - Self::generate_recommendation(cx, le_or_ge, lhs, rhsrhs) + Some((lhs, rhsrhs)) } else if Self::is_one(rhsrhs) { - Self::generate_recommendation(cx, le_or_ge, lhs, rhslhs) + Some((lhs, rhslhs)) } else { None } @@ -109,9 +107,9 @@ impl IntPlusOne { (LeOrGe::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => { // `1 + x` and `x + 1` if Self::is_one(lhslhs) { - Self::generate_recommendation(cx, le_or_ge, lhsrhs, rhs) + Some((lhsrhs, rhs)) } else if Self::is_one(lhsrhs) { - Self::generate_recommendation(cx, le_or_ge, lhslhs, rhs) + Some((lhslhs, rhs)) } else { None } @@ -120,11 +118,9 @@ impl IntPlusOne { (LeOrGe::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => { match rhskind.node { // `-1 + y` - BinOpKind::Add if Self::is_neg_one(rhslhs) => { - Self::generate_recommendation(cx, le_or_ge, lhs, rhsrhs) - }, + BinOpKind::Add if Self::is_neg_one(rhslhs) => Some((lhs, rhsrhs)), // `y - 1` - BinOpKind::Sub if Self::is_one(rhsrhs) => Self::generate_recommendation(cx, le_or_ge, lhs, rhslhs), + BinOpKind::Sub if Self::is_one(rhsrhs) => Some((lhs, rhslhs)), _ => None, } }, @@ -132,33 +128,24 @@ impl IntPlusOne { } } - fn generate_recommendation( - cx: &EarlyContext<'_>, - le_or_ge: LeOrGe, - node: &Expr, - other_side: &Expr, - ) -> Option { - let binop_string = match le_or_ge { - LeOrGe::Ge => ">", - LeOrGe::Le => "<", - }; - if let Some(snippet) = node.span.get_source_text(cx) - && let Some(other_side_snippet) = other_side.span.get_source_text(cx) - { - return Some(format!("{snippet} {binop_string} {other_side_snippet}")); - } - None - } - - fn emit_warning(cx: &EarlyContext<'_>, block: &Expr, recommendation: String) { - span_lint_and_sugg( + fn emit_warning(cx: &EarlyContext<'_>, expr: &Expr, new_lhs: &Expr, le_or_ge: LeOrGe, new_rhs: &Expr) { + span_lint_and_then( cx, INT_PLUS_ONE, - block.span, + expr.span, "unnecessary `>= y + 1` or `x - 1 >=`", - "change it to", - recommendation, - Applicability::MachineApplicable, // snippet + |diag| { + let mut app = Applicability::MachineApplicable; + let ctxt = expr.span.ctxt(); + let new_lhs = sugg::Sugg::ast(cx, new_lhs, "_", ctxt, &mut app); + let new_rhs = sugg::Sugg::ast(cx, new_rhs, "_", ctxt, &mut app); + let new_binop = match le_or_ge { + LeOrGe::Ge => BinOpKind::Gt, + LeOrGe::Le => BinOpKind::Lt, + }; + let rec = sugg::make_binop(new_binop, &new_lhs, &new_rhs); + diag.span_suggestion(expr.span, "change it to", rec, app); + }, ); } } @@ -167,9 +154,9 @@ impl EarlyLintPass for IntPlusOne { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { if let ExprKind::Binary(binop, lhs, rhs) = &expr.kind && let Ok(le_or_ge) = LeOrGe::try_from(binop.node) - && let Some(rec) = Self::check_binop(cx, le_or_ge, lhs, rhs) + && let Some((new_lhs, new_rhs)) = Self::check_binop(le_or_ge, lhs, rhs) { - Self::emit_warning(cx, expr, rec); + Self::emit_warning(cx, expr, new_lhs, le_or_ge, new_rhs); } } } From ea591b55f43483bacb2e8b2b1cb9f6c7aa999d7e Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Fri, 9 Jan 2026 23:15:06 +0100 Subject: [PATCH 1893/3801] fix `clippy_utils::std_or_core(_)` --- clippy_utils/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 2a620e917228..33f5f5c8873d 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -2031,12 +2031,12 @@ pub fn is_expr_temporary_value(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { } pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> { - if !is_no_std_crate(cx) { - Some("std") - } else if !is_no_core_crate(cx) { + if is_no_core_crate(cx) { + None + } else if is_no_std_crate(cx) { Some("core") } else { - None + Some("std") } } From f982bc6a2dd661dd5713a39e96d469c6309f3b2e Mon Sep 17 00:00:00 2001 From: Keith-Cancel Date: Thu, 8 Jan 2026 01:24:13 -0800 Subject: [PATCH 1894/3801] Fix ICE: can't type-check body of DefId, since type_consts don't have a body. Handling for inherent associated consts is missing elsewhere, remove so it can be handled later in that handling. Diagnostic not always be emitted on associated constant Add a test case and Fix for a different ICE I encountered. I noticed when trying various permuations of the test case code to see if I could find anymore ICEs. I did, but not one that I expected. So in the instances of the a named const not having any args, insantiate it directly. Since it is likely an inherent assocaiated const. Added tests. Centralize the is_type_const() logic. I also noticed basically the exact same check in other part the code. Const blocks can't be a type_const, therefore this check is uneeded. Fix comment spelling error. get_all_attrs is not valid to call for all DefIds it seems. Make sure that if the type is omitted for a type_const that we don't ICE. Co-Authored-By: Boxy --- .../src/check_consts/qualifs.rs | 12 +++------ .../rustc_hir_analysis/src/collect/type_of.rs | 17 +++++++++++- compiler/rustc_middle/src/ty/context.rs | 6 +++++ .../src/builder/expr/as_constant.rs | 10 ++++++- .../mgca/type_const-array-return.rs | 26 +++++++++++++++++++ .../type_const-inherent-const-omitted-type.rs | 12 +++++++++ ...e_const-inherent-const-omitted-type.stderr | 13 ++++++++++ .../type_const-only-in-impl-omitted-type.rs | 22 ++++++++++++++++ ...ype_const-only-in-impl-omitted-type.stderr | 16 ++++++++++++ .../mgca/type_const-recursive.rs | 8 ++++++ .../mgca/type_const-recursive.stderr | 11 ++++++++ .../ui/const-generics/mgca/type_const-use.rs | 13 ++++++++++ 12 files changed, 155 insertions(+), 11 deletions(-) create mode 100644 tests/ui/const-generics/mgca/type_const-array-return.rs create mode 100644 tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs create mode 100644 tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr create mode 100644 tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs create mode 100644 tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr create mode 100644 tests/ui/const-generics/mgca/type_const-recursive.rs create mode 100644 tests/ui/const-generics/mgca/type_const-recursive.stderr create mode 100644 tests/ui/const-generics/mgca/type_const-use.rs diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 113e0d66c48a..02615e3bbc18 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -6,9 +6,7 @@ // having basically only two use-cases that act in different ways. use rustc_errors::ErrorGuaranteed; -use rustc_hir::attrs::AttributeKind; -use rustc_hir::def::DefKind; -use rustc_hir::{LangItem, find_attr}; +use rustc_hir::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::*; use rustc_middle::ty::{self, AdtDef, Ty}; @@ -366,14 +364,10 @@ where // check performed after the promotion. Verify that with an assertion. assert!(promoted.is_none() || Q::ALLOW_PROMOTED); - // Avoid looking at attrs of anon consts as that will ICE - let is_type_const_item = - matches!(cx.tcx.def_kind(def), DefKind::Const | DefKind::AssocConst) - && find_attr!(cx.tcx.get_all_attrs(def), AttributeKind::TypeConst(_)); - // Don't peak inside trait associated constants, also `#[type_const] const` items // don't have bodies so there's nothing to look at - if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() && !is_type_const_item { + if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() && !cx.tcx.is_type_const(def) + { let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def); if !Q::in_qualifs(&qualifs) { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index aa0e5c7fd710..910176a0689c 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -420,7 +420,22 @@ fn infer_placeholder_type<'tcx>( kind: &'static str, ) -> Ty<'tcx> { let tcx = cx.tcx(); - let ty = tcx.typeck(def_id).node_type(hir_id); + // If the type is omitted on a #[type_const] we can't run + // type check on since that requires the const have a body + // which type_consts don't. + let ty = if tcx.is_type_const(def_id.to_def_id()) { + if let Some(trait_item_def_id) = tcx.trait_item_of(def_id.to_def_id()) { + tcx.type_of(trait_item_def_id).instantiate_identity() + } else { + Ty::new_error_with_message( + tcx, + ty_span, + "constant with #[type_const] requires an explicit type", + ) + } + } else { + tcx.typeck(def_id).node_type(hir_id) + }; // If this came from a free `const` or `static mut?` item, // then the user may have written e.g. `const A = 42;`. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a2f4714d1b2c..a3eec72214c0 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1891,6 +1891,12 @@ impl<'tcx> TyCtxt<'tcx> { self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace) } + /// Check if the given `def_id` is a const with the `#[type_const]` attribute. + pub fn is_type_const(self, def_id: DefId) -> bool { + matches!(self.def_kind(def_id), DefKind::Const | DefKind::AssocConst) + && find_attr!(self.get_all_attrs(def_id), AttributeKind::TypeConst(_)) + } + /// Returns the movability of the coroutine of `def_id`, or panics /// if given a `def_id` that is not a coroutine. pub fn coroutine_movability(self, def_id: DefId) -> hir::Movability { diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 186fde4883df..1772d66f5285 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -1,7 +1,7 @@ //! See docs in build/expr/mod.rs use rustc_abi::Size; -use rustc_ast as ast; +use rustc_ast::{self as ast}; use rustc_hir::LangItem; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, LitToConstInput, Scalar}; use rustc_middle::mir::*; @@ -47,6 +47,7 @@ pub(crate) fn as_constant_inner<'tcx>( tcx: TyCtxt<'tcx>, ) -> ConstOperand<'tcx> { let Expr { ty, temp_scope_id: _, span, ref kind } = *expr; + match *kind { ExprKind::Literal { lit, neg } => { let const_ = lit_to_mir_constant(tcx, LitToConstInput { lit: lit.node, ty, neg }); @@ -69,6 +70,13 @@ pub(crate) fn as_constant_inner<'tcx>( } ExprKind::NamedConst { def_id, args, ref user_ty } => { let user_ty = user_ty.as_ref().and_then(push_cuta); + if tcx.is_type_const(def_id) { + let uneval = ty::UnevaluatedConst::new(def_id, args); + let ct = ty::Const::new_unevaluated(tcx, uneval); + + let const_ = Const::Ty(ty, ct); + return ConstOperand { span, user_ty, const_ }; + } let uneval = mir::UnevaluatedConst::new(def_id, args); let const_ = Const::Unevaluated(uneval, ty); diff --git a/tests/ui/const-generics/mgca/type_const-array-return.rs b/tests/ui/const-generics/mgca/type_const-array-return.rs new file mode 100644 index 000000000000..5375e4fded6d --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-array-return.rs @@ -0,0 +1,26 @@ +//@ check-pass +// This test should compile without an ICE. +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +pub struct A; + +pub trait Array { + #[type_const] + const LEN: usize; + fn arr() -> [u8; Self::LEN]; +} + +impl Array for A { + #[type_const] + const LEN: usize = 4; + + #[allow(unused_braces)] + fn arr() -> [u8; const { Self::LEN }] { + return [0u8; const { Self::LEN }]; + } +} + +fn main() { + let _ = A::arr(); +} diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs new file mode 100644 index 000000000000..b2c734098009 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs @@ -0,0 +1,12 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +struct A; + +impl A { + #[type_const] + const B = 4; + //~^ ERROR: missing type for `const` item +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr new file mode 100644 index 000000000000..b44e47cd7e61 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr @@ -0,0 +1,13 @@ +error: missing type for `const` item + --> $DIR/type_const-inherent-const-omitted-type.rs:8:12 + | +LL | const B = 4; + | ^ + | +help: provide a type for the item + | +LL | const B: = 4; + | ++++++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs new file mode 100644 index 000000000000..ab613859aa5c --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs @@ -0,0 +1,22 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +trait BadTr { + const NUM: usize; +} + +struct GoodS; + +impl BadTr for GoodS { + #[type_const] + const NUM: = 84; + //~^ ERROR: missing type for `const` item + +} + +fn accept_bad_tr>(_x: &T) {} +//~^ ERROR use of trait associated const without `#[type_const]` + +fn main() { + accept_bad_tr::<84, _>(&GoodS); +} diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr new file mode 100644 index 000000000000..16f312454ed2 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr @@ -0,0 +1,16 @@ +error: missing type for `const` item + --> $DIR/type_const-only-in-impl-omitted-type.rs:12:15 + | +LL | const NUM: = 84; + | ^ help: provide a type for the associated constant: `usize` + +error: use of trait associated const without `#[type_const]` + --> $DIR/type_const-only-in-impl-omitted-type.rs:17:43 + | +LL | fn accept_bad_tr>(_x: &T) {} + | ^^^^^^^^^^^ + | + = note: the declaration in the trait must be marked with `#[type_const]` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/type_const-recursive.rs b/tests/ui/const-generics/mgca/type_const-recursive.rs new file mode 100644 index 000000000000..15e49f747ed6 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-recursive.rs @@ -0,0 +1,8 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +#[type_const] +const A: u8 = A; +//~^ ERROR: overflow normalizing the unevaluated constant `A` [E0275] + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-recursive.stderr b/tests/ui/const-generics/mgca/type_const-recursive.stderr new file mode 100644 index 000000000000..947319ec7eda --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-recursive.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow normalizing the unevaluated constant `A` + --> $DIR/type_const-recursive.rs:5:1 + | +LL | const A: u8 = A; + | ^^^^^^^^^^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/const-generics/mgca/type_const-use.rs b/tests/ui/const-generics/mgca/type_const-use.rs new file mode 100644 index 000000000000..04362cd28538 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-use.rs @@ -0,0 +1,13 @@ +//@ check-pass +// This test should compile without an ICE. +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +#[type_const] +const CONST: usize = 1; + +fn uses_const() { + CONST; +} + +fn main() {} From 9156b540aa35820a87c377b780e6058fe5dface9 Mon Sep 17 00:00:00 2001 From: Guilherme Luiz Date: Fri, 9 Jan 2026 19:33:18 -0300 Subject: [PATCH 1895/3801] =?UTF-8?q?Update=20to=5Fuppercase=20docs=20to?= =?UTF-8?q?=20avoid=20=C3=9F->SS=20example?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/core/src/char/methods.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 89cb06972392..c30edeed580a 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1147,7 +1147,7 @@ impl char { /// As an iterator: /// /// ``` - /// for c in 'ß'.to_uppercase() { + /// for c in 'ffi'.to_uppercase() { /// print!("{c}"); /// } /// println!(); @@ -1156,13 +1156,13 @@ impl char { /// Using `println!` directly: /// /// ``` - /// println!("{}", 'ß'.to_uppercase()); + /// println!("{}", 'ffi'.to_uppercase()); /// ``` /// /// Both are equivalent to: /// /// ``` - /// println!("SS"); + /// println!("FFI"); /// ``` /// /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string): @@ -1171,7 +1171,7 @@ impl char { /// assert_eq!('c'.to_uppercase().to_string(), "C"); /// /// // Sometimes the result is more than one character: - /// assert_eq!('ß'.to_uppercase().to_string(), "SS"); + /// assert_eq!('ffi'.to_uppercase().to_string(), "FFI"); /// /// // Characters that do not have both uppercase and lowercase /// // convert into themselves. From 3f51a315e0668ff1c72459a08dfc42780032918c Mon Sep 17 00:00:00 2001 From: Paul Mabileau Date: Fri, 9 Jan 2026 21:20:39 +0100 Subject: [PATCH 1896/3801] Fix(lib/win/net): Remove hostname support under Win7 `GetHostNameW` is not available under Windows 7, leading to dynamic linking failures upon program executions. For now, as it is still unstable, this therefore appropriately cfg-gates the feature in order to mark the Win7 as unsupported with regards to this particular feature. Porting the functionality for Windows 7 would require changing the underlying system call and so more work for the immediate need. Signed-off-by: Paul Mabileau --- library/std/src/net/hostname.rs | 8 ++++---- library/std/src/sys/net/hostname/mod.rs | 3 ++- library/std/src/sys/pal/windows/c.rs | 4 ++++ library/std/src/sys/pal/windows/c/bindings.txt | 1 - library/std/src/sys/pal/windows/c/windows_sys.rs | 1 - 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/library/std/src/net/hostname.rs b/library/std/src/net/hostname.rs index b1010cec6005..4042496d534f 100644 --- a/library/std/src/net/hostname.rs +++ b/library/std/src/net/hostname.rs @@ -8,10 +8,10 @@ use crate::ffi::OsString; /// /// # Underlying system calls /// -/// | Platform | System call | -/// |----------|---------------------------------------------------------------------------------------------------------| -/// | UNIX | [`gethostname`](https://www.man7.org/linux/man-pages/man2/gethostname.2.html) | -/// | Windows | [`GetHostNameW`](https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-gethostnamew) | +/// | Platform | System call | +/// |--------------|---------------------------------------------------------------------------------------------------------| +/// | UNIX | [`gethostname`](https://www.man7.org/linux/man-pages/man2/gethostname.2.html) | +/// | Windows (8+) | [`GetHostNameW`](https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-gethostnamew) | /// /// Note that platform-specific behavior [may change in the future][changes]. /// diff --git a/library/std/src/sys/net/hostname/mod.rs b/library/std/src/sys/net/hostname/mod.rs index 8ffe4894d718..65fcd6bfb00d 100644 --- a/library/std/src/sys/net/hostname/mod.rs +++ b/library/std/src/sys/net/hostname/mod.rs @@ -3,7 +3,8 @@ cfg_select! { mod unix; pub use unix::hostname; } - target_os = "windows" => { + // `GetHostNameW` is only available starting with Windows 8. + all(target_os = "windows", not(target_vendor = "win7")) => { mod windows; pub use windows::hostname; } diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 25c1a82cc426..0f54f80d72ee 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -237,3 +237,7 @@ cfg_select! { } _ => {} } + +// Only available starting with Windows 8. +#[cfg(not(target_vendor = "win7"))] +windows_targets::link!("ws2_32.dll" "system" fn GetHostNameW(name : PWSTR, namelen : i32) -> i32); diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt index 9009aa09f48e..12babcb84ccf 100644 --- a/library/std/src/sys/pal/windows/c/bindings.txt +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -2170,7 +2170,6 @@ GetFileType GETFINALPATHNAMEBYHANDLE_FLAGS GetFinalPathNameByHandleW GetFullPathNameW -GetHostNameW GetLastError GetModuleFileNameW GetModuleHandleA diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index 98f277b33780..edc9d2d11f7c 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -49,7 +49,6 @@ windows_targets::link!("kernel32.dll" "system" fn GetFileSizeEx(hfile : HANDLE, windows_targets::link!("kernel32.dll" "system" fn GetFileType(hfile : HANDLE) -> FILE_TYPE); windows_targets::link!("kernel32.dll" "system" fn GetFinalPathNameByHandleW(hfile : HANDLE, lpszfilepath : PWSTR, cchfilepath : u32, dwflags : GETFINALPATHNAMEBYHANDLE_FLAGS) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetFullPathNameW(lpfilename : PCWSTR, nbufferlength : u32, lpbuffer : PWSTR, lpfilepart : *mut PWSTR) -> u32); -windows_targets::link!("ws2_32.dll" "system" fn GetHostNameW(name : PWSTR, namelen : i32) -> i32); windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> WIN32_ERROR); windows_targets::link!("kernel32.dll" "system" fn GetModuleFileNameW(hmodule : HMODULE, lpfilename : PWSTR, nsize : u32) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleA(lpmodulename : PCSTR) -> HMODULE); From 07fa70e104647b4b9b4ad9ba93bfaaba4ed5bcdf Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 9 Jan 2026 19:15:49 -0600 Subject: [PATCH 1897/3801] llvm: Update `reliable_f16` configuration for LLVM22 Since yesterday, the LLVM `main` branch should have working `f16` on all platforms that Rust supports; this will be LLVM version 22, so update how `cfg(target_has_reliable_f16)` is set to reflect this. Within the rust-lang organization, this currently has no effect. The goal is to start catching problems as early as possible in external CI that runs top-of-tree rust against top-of-tree LLVM, and once testing for the rust-lang bump to LLVM 22 starts. Hopefully this will mean that we can fix any problems that show up before the bump actually happens, meaning `f16` will be about ready for stabilization at that point (with some considerations for the GCC patch at [1] propagating). References: * https://github.com/llvm/llvm-project/commit/919021b0df8c91417784bfd84a6ad4869a0d2206 * https://github.com/llvm/llvm-project/commit/054ee2f8706b582859fcf96d1771aa68c37d9e6a * https://github.com/llvm/llvm-project/commit/db26ce5c5572a1a54ce307c762689ab63e5c5485 * https://github.com/llvm/llvm-project/commit/549d7c4f35a99598a269004ee13b237d2565b5ec * https://github.com/llvm/llvm-project/commit/4903c6260cbd781881906007f9c82aceb71fd7c7 [1]: https://github.com/gcc-mirror/gcc/commit/8b6a18ecaf44553230b90bf28adfb9fe9c9d5ab9 --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 9b08f4e9869c..63f820dc2918 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -379,19 +379,19 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { { false } - // Unsupported - (Arch::Arm64EC, _) => false, + // Unsupported (fixed in llvm22) + (Arch::Arm64EC, _) if major < 22 => false, // Selection failure (fixed in llvm21) (Arch::S390x, _) if major < 21 => false, // MinGW ABI bugs (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, // Infinite recursion - (Arch::CSky, _) => false, + (Arch::CSky, _) if major < 22 => false, // (fixed in llvm22) (Arch::Hexagon, _) if major < 21 => false, // (fixed in llvm21) (Arch::LoongArch32 | Arch::LoongArch64, _) if major < 21 => false, // (fixed in llvm21) - (Arch::PowerPC | Arch::PowerPC64, _) => false, - (Arch::Sparc | Arch::Sparc64, _) => false, - (Arch::Wasm32 | Arch::Wasm64, _) => false, + (Arch::PowerPC | Arch::PowerPC64, _) if major < 22 => false, // (fixed in llvm22) + (Arch::Sparc | Arch::Sparc64, _) if major < 22 => false, // (fixed in llvm22) + (Arch::Wasm32 | Arch::Wasm64, _) if major < 22 => false, // (fixed in llvm22) // `f16` support only requires that symbols converting to and from `f32` are available. We // provide these in `compiler-builtins`, so `f16` should be available on all platforms that // do not have other ABI issues or LLVM crashes. From fc06a57a786de3efc723c9c00085f481157b72df Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Wed, 7 Jan 2026 19:47:02 +0900 Subject: [PATCH 1898/3801] Introduce hir::ConstArgKind::Array --- compiler/rustc_ast_lowering/src/lib.rs | 19 +++++++++++++++++++ compiler/rustc_hir/src/hir.rs | 8 ++++++++ compiler/rustc_hir/src/intravisit.rs | 6 ++++++ .../src/hir_ty_lowering/mod.rs | 3 +++ compiler/rustc_hir_pretty/src/lib.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + compiler/rustc_resolve/src/def_collector.rs | 2 +- src/librustdoc/clean/mod.rs | 3 +++ 8 files changed, 42 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 42eb8673f30c..de403a262879 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2517,6 +2517,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span, } } + ExprKind::Array(elements) => { + let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| { + let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind { + let def_id = self.local_def_id(anon_const.id); + assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id)); + self.lower_anon_const_to_const_arg(anon_const) + } else { + self.lower_expr_to_const_arg_direct(element) + }; + &*self.arena.alloc(const_arg) + })); + let array_expr = self.arena.alloc(hir::ConstArgArrayExpr { + span: self.lower_span(expr.span), + elems: lowered_elems, + }); + + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Array(array_expr) } + } ExprKind::Underscore => ConstArg { hir_id: self.lower_node_id(expr.id), kind: hir::ConstArgKind::Infer(()), @@ -2532,6 +2550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | ExprKind::Struct(..) | ExprKind::Call(..) | ExprKind::Tup(..) + | ExprKind::Array(..) ) { return self.lower_expr_to_const_arg_direct(expr); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2fb6daf6469b..055df9c2a085 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -513,6 +513,8 @@ pub enum ConstArgKind<'hir, Unambig = ()> { Struct(QPath<'hir>, &'hir [&'hir ConstArgExprField<'hir>]), /// Tuple constructor variant TupleCall(QPath<'hir>, &'hir [&'hir ConstArg<'hir>]), + /// Array literal argument + Array(&'hir ConstArgArrayExpr<'hir>), /// Error const Error(ErrorGuaranteed), /// This variant is not always used to represent inference consts, sometimes @@ -529,6 +531,12 @@ pub struct ConstArgExprField<'hir> { pub expr: &'hir ConstArg<'hir>, } +#[derive(Clone, Copy, Debug, HashStable_Generic)] +pub struct ConstArgArrayExpr<'hir> { + pub span: Span, + pub elems: &'hir [&'hir ConstArg<'hir>], +} + #[derive(Clone, Copy, Debug, HashStable_Generic)] pub struct InferArg { #[stable_hasher(ignore)] diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index e5e6fc7b1d8d..d1b75325af26 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1101,6 +1101,12 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( } V::Result::output() } + ConstArgKind::Array(array_expr) => { + for arg in array_expr.elems { + try_visit!(visitor.visit_const_arg_unambig(*arg)); + } + V::Result::output() + } ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important 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 1dd9bff42575..42893906a386 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2389,6 +2389,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::ConstArgKind::TupleCall(qpath, args) => { self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span) } + hir::ConstArgKind::Array(_array_expr) => { + span_bug!(const_arg.span(), "lowering `{:?}` is not yet implemented", const_arg) + } hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span), hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e), diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 37fa18c00887..e0e9fe775853 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1153,6 +1153,7 @@ impl<'a> State<'a> { } ConstArgKind::Struct(qpath, fields) => self.print_const_struct(qpath, fields), ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args), + ConstArgKind::Array(..) => self.word("/* ARRAY EXPR */"), ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), ConstArgKind::Anon(anon) => self.print_anon_const(anon), ConstArgKind::Error(_) => self.word("/*ERROR*/"), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index c85327dc3db1..fd0fcb18bfe1 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1441,6 +1441,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Skip encoding defs for these as they should not have had a `DefId` created hir::ConstArgKind::Error(..) | hir::ConstArgKind::Struct(..) + | hir::ConstArgKind::Array(..) | hir::ConstArgKind::TupleCall(..) | hir::ConstArgKind::Tup(..) | hir::ConstArgKind::Path(..) diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index b392b7747b55..ea5640ecc1fa 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -419,7 +419,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // Avoid overwriting `const_arg_context` as we may want to treat const blocks // as being anon consts if we are inside a const argument. - ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) => { + ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) | ExprKind::Array(..) => { return visit::walk_expr(self, expr); } // FIXME(mgca): we may want to handle block labels in some manner diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 817eda4c52ec..c8e38330b82c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -329,6 +329,8 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind hir::ConstArgKind::Tup(..) => { // FIXME(mgca): proper printing :3 ConstantKind::Path { path: "/* TUPLE EXPR */".to_string().into() } + hir::ConstArgKind::Array(..) => { + ConstantKind::Path { path: "/* ARRAY EXPR */".to_string().into() } } hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer, @@ -1818,6 +1820,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T | hir::ConstArgKind::Path(..) | hir::ConstArgKind::TupleCall(..) | hir::ConstArgKind::Tup(..) + | hir::ConstArgKind::Array(..) | hir::ConstArgKind::Literal(..) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); print_const(cx, ct) From 618b0b5464b8c078fbfaea3f3181d7248072a183 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Thu, 8 Jan 2026 10:35:52 +0900 Subject: [PATCH 1899/3801] Lower hir::ConstArgKind::Array to a ValTree --- compiler/rustc_ast_lowering/src/lib.rs | 6 +++- .../src/hir_ty_lowering/mod.rs | 34 +++++++++++++++++-- src/librustdoc/clean/mod.rs | 1 + tests/ui/const-generics/mgca/array-expr.rs | 24 +++++++++++++ .../ui/const-generics/mgca/array-expr.stderr | 14 ++++++++ 5 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 tests/ui/const-generics/mgca/array-expr.rs create mode 100644 tests/ui/const-generics/mgca/array-expr.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index de403a262879..350fa04ab3bd 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2533,7 +2533,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { elems: lowered_elems, }); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Array(array_expr) } + ConstArg { + hir_id: self.next_id(), + kind: hir::ConstArgKind::Array(array_expr), + span, + } } ExprKind::Underscore => ConstArg { hir_id: self.lower_node_id(expr.id), 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 42893906a386..6f44a728242d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2389,9 +2389,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::ConstArgKind::TupleCall(qpath, args) => { self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span) } - hir::ConstArgKind::Array(_array_expr) => { - span_bug!(const_arg.span(), "lowering `{:?}` is not yet implemented", const_arg) - } + hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, feed), hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span), hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e), @@ -2405,6 +2403,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + fn lower_const_arg_array( + &self, + array_expr: &'tcx hir::ConstArgArrayExpr<'tcx>, + feed: FeedConstTy<'tcx>, + ) -> Const<'tcx> { + let tcx = self.tcx(); + + let FeedConstTy::WithTy(ty) = feed else { + return Const::new_error_with_message(tcx, array_expr.span, "unsupported const array"); + }; + + let ty::Array(elem_ty, _) = ty.kind() else { + return Const::new_error_with_message( + tcx, + array_expr.span, + "const array must have an array type", + ); + }; + + let elems = array_expr + .elems + .iter() + .map(|elem| self.lower_const_arg(elem, FeedConstTy::WithTy(*elem_ty))) + .collect::>(); + + let valtree = ty::ValTree::from_branches(tcx, elems); + + ty::Const::new_value(tcx, valtree, ty) + } + fn lower_const_arg_tuple_call( &self, hir_id: HirId, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c8e38330b82c..597a85f39769 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -329,6 +329,7 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind hir::ConstArgKind::Tup(..) => { // FIXME(mgca): proper printing :3 ConstantKind::Path { path: "/* TUPLE EXPR */".to_string().into() } + } hir::ConstArgKind::Array(..) => { ConstantKind::Path { path: "/* ARRAY EXPR */".to_string().into() } } diff --git a/tests/ui/const-generics/mgca/array-expr.rs b/tests/ui/const-generics/mgca/array-expr.rs new file mode 100644 index 000000000000..099fee7ecd03 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr.rs @@ -0,0 +1,24 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] + +fn takes_array() {} + +fn generic_caller() { + takes_array::<{ [N, N2, N] }>(); // ok + + takes_array::<{ [N, N2, const { 1 }] }>(); // ok + + takes_array::<{ [N, N2, const { 1 + 1 }] }>(); // ok + + takes_array::<{ [N, N2, 1] }>(); // ok + + takes_array::<{ [1, 1u32, 1_u32] }>(); // ok + + takes_array::<{ [N, N2, 1 + 1] }>(); // not implemented + //~^ ERROR complex const arguments must be placed inside of a `const` block + + takes_array::<{ [N; 3] }>(); // not implemented + //~^ ERROR complex const arguments must be placed inside of a `const` block +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr.stderr b/tests/ui/const-generics/mgca/array-expr.stderr new file mode 100644 index 000000000000..0dda791c2e10 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr.stderr @@ -0,0 +1,14 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr.rs:17:29 + | +LL | takes_array::<{ [N, N2, 1 + 1] }>(); // not implemented + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr.rs:20:19 + | +LL | takes_array::<{ [N; 3] }>(); // not implemented + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 522be7f1c0430cd7201b1f75ec72cb473099835c Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Thu, 8 Jan 2026 12:19:43 +0900 Subject: [PATCH 1900/3801] Fix clippy --- src/tools/clippy/clippy_lints/src/utils/author.rs | 1 + src/tools/clippy/clippy_utils/src/consts.rs | 1 + src/tools/clippy/clippy_utils/src/hir_utils.rs | 11 +++++++++++ 3 files changed, 13 insertions(+) diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index acea701b2e83..8243077cab89 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -321,6 +321,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), + ConstArgKind::Array(..) => chain!(self, "let ConstArgKind::Array(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 538f1fd2628c..e2ada37d53b3 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1144,6 +1144,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx | ConstArgKind::Tup(..) | ConstArgKind::Literal(..) | ConstArgKind::TupleCall(..) + | ConstArgKind::Array(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 0bb641568879..c7bb3a064a09 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -687,6 +687,11 @@ impl HirEqInterExpr<'_, '_, '_> { .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) }, (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => kind_l == kind_r, + (ConstArgKind::Array(l_arr), ConstArgKind::Array(r_arr)) => { + l_arr.elems.len() == r_arr.elems.len() + && l_arr.elems.iter().zip(r_arr.elems.iter()) + .all(|(l_elem, r_elem)| self.eq_const_arg(l_elem, r_elem)) + } // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) @@ -696,6 +701,7 @@ impl HirEqInterExpr<'_, '_, '_> { | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Literal(..) + | ConstArgKind::Array(..) | ConstArgKind::Error(..), _, ) => false, @@ -1575,6 +1581,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(arg); } }, + ConstArgKind::Array(array_expr) => { + for elem in array_expr.elems { + self.hash_const_arg(elem); + } + }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, ConstArgKind::Literal(lit) => lit.hash(&mut self.s), } From f4a6e4f0d94670e162370c2a495b0f1a8bb43262 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Thu, 8 Jan 2026 12:19:43 +0900 Subject: [PATCH 1901/3801] Fix clippy --- clippy_lints/src/utils/author.rs | 1 + clippy_utils/src/consts.rs | 1 + clippy_utils/src/hir_utils.rs | 11 +++++++++++ 3 files changed, 13 insertions(+) diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index acea701b2e83..8243077cab89 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -321,6 +321,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), ConstArgKind::TupleCall(..) => chain!(self, "let ConstArgKind::TupleCall(..) = {const_arg}.kind"), + ConstArgKind::Array(..) => chain!(self, "let ConstArgKind::Array(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 538f1fd2628c..e2ada37d53b3 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1144,6 +1144,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx | ConstArgKind::Tup(..) | ConstArgKind::Literal(..) | ConstArgKind::TupleCall(..) + | ConstArgKind::Array(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 0bb641568879..c7bb3a064a09 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -687,6 +687,11 @@ impl HirEqInterExpr<'_, '_, '_> { .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) }, (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => kind_l == kind_r, + (ConstArgKind::Array(l_arr), ConstArgKind::Array(r_arr)) => { + l_arr.elems.len() == r_arr.elems.len() + && l_arr.elems.iter().zip(r_arr.elems.iter()) + .all(|(l_elem, r_elem)| self.eq_const_arg(l_elem, r_elem)) + } // Use explicit match for now since ConstArg is undergoing flux. ( ConstArgKind::Path(..) @@ -696,6 +701,7 @@ impl HirEqInterExpr<'_, '_, '_> { | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) | ConstArgKind::Literal(..) + | ConstArgKind::Array(..) | ConstArgKind::Error(..), _, ) => false, @@ -1575,6 +1581,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_const_arg(arg); } }, + ConstArgKind::Array(array_expr) => { + for elem in array_expr.elems { + self.hash_const_arg(elem); + } + }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, ConstArgKind::Literal(lit) => lit.hash(&mut self.s), } From f2f45ffddd584377b36e1da628b79d05d538a2a4 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Fri, 9 Jan 2026 14:13:41 +0900 Subject: [PATCH 1902/3801] Add mGCA array expression tests --- .../const-generics/mgca/array-expr-complex.rs | 16 ++++++++++++ .../mgca/array-expr-complex.stderr | 20 +++++++++++++++ .../const-generics/mgca/array-expr-empty.rs | 9 +++++++ .../mgca/array-expr-empty.stderr | 8 ++++++ .../const-generics/mgca/array-expr-simple.rs | 25 +++++++++++++++++++ .../mgca/array-expr-with-assoc-const.rs | 18 +++++++++++++ .../mgca/array-expr-with-macro.rs | 18 +++++++++++++ .../mgca/array-expr-with-struct.rs | 20 +++++++++++++++ .../mgca/array-expr-with-tuple.rs | 13 ++++++++++ tests/ui/const-generics/mgca/array-expr.rs | 24 ------------------ .../ui/const-generics/mgca/array-expr.stderr | 14 ----------- 11 files changed, 147 insertions(+), 38 deletions(-) create mode 100644 tests/ui/const-generics/mgca/array-expr-complex.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-complex.stderr create mode 100644 tests/ui/const-generics/mgca/array-expr-empty.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-empty.stderr create mode 100644 tests/ui/const-generics/mgca/array-expr-simple.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-with-macro.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-with-struct.rs create mode 100644 tests/ui/const-generics/mgca/array-expr-with-tuple.rs delete mode 100644 tests/ui/const-generics/mgca/array-expr.rs delete mode 100644 tests/ui/const-generics/mgca/array-expr.stderr diff --git a/tests/ui/const-generics/mgca/array-expr-complex.rs b/tests/ui/const-generics/mgca/array-expr-complex.rs new file mode 100644 index 000000000000..3e8320bc94de --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-complex.rs @@ -0,0 +1,16 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] + +fn takes_array() {} + +fn generic_caller() { + // not supported yet + takes_array::<{ [1, 2, 1 + 2] }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + takes_array::<{ [X; 3] }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + takes_array::<{ [0; Y] }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-complex.stderr b/tests/ui/const-generics/mgca/array-expr-complex.stderr new file mode 100644 index 000000000000..beac1aa232f2 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-complex.stderr @@ -0,0 +1,20 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr-complex.rs:8:28 + | +LL | takes_array::<{ [1, 2, 1 + 2] }>(); + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr-complex.rs:10:19 + | +LL | takes_array::<{ [X; 3] }>(); + | ^^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr-complex.rs:12:19 + | +LL | takes_array::<{ [0; Y] }>(); + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/const-generics/mgca/array-expr-empty.rs b/tests/ui/const-generics/mgca/array-expr-empty.rs new file mode 100644 index 000000000000..d37c6f2fcfe3 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-empty.rs @@ -0,0 +1,9 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +fn takes_empty_array() {} +//~^ ERROR: expected type, found `]` + +fn main() { + takes_empty_array::<{ [] }>(); +} diff --git a/tests/ui/const-generics/mgca/array-expr-empty.stderr b/tests/ui/const-generics/mgca/array-expr-empty.stderr new file mode 100644 index 000000000000..91340e621acb --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-empty.stderr @@ -0,0 +1,8 @@ +error: expected type, found `]` + --> $DIR/array-expr-empty.rs:4:32 + | +LL | fn takes_empty_array() {} + | ^ expected type + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/array-expr-simple.rs b/tests/ui/const-generics/mgca/array-expr-simple.rs new file mode 100644 index 000000000000..44feeccb4f9f --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-simple.rs @@ -0,0 +1,25 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] +#![allow(dead_code)] + +fn takes_array_u32() {} +fn takes_array_bool() {} +fn takes_nested_array() {} +fn takes_empty_array() {} + +fn generic_caller() { + takes_array_u32::<{ [X, Y, X] }>(); + takes_array_u32::<{ [X, Y, const { 1 }] }>(); + takes_array_u32::<{ [X, Y, const { 1 + 1 }] }>(); + takes_array_u32::<{ [2_002, 2u32, 1_u32] }>(); + + takes_array_bool::<{ [true, false] }>(); + + takes_nested_array::<{ [[X, Y], [3, 4]] }>(); + takes_nested_array::<{ [[1u32, 2_u32], [const { 3 }, 4]] }>(); + + takes_empty_array::<{ [] }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs b/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs new file mode 100644 index 000000000000..47ecbfa6b7e1 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs @@ -0,0 +1,18 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] +#![allow(dead_code)] + +fn takes_array() {} + +trait Trait { + #[type_const] + const ASSOC: u32; +} + +fn generic_caller() { + takes_array::<{ [T::ASSOC, N, T::ASSOC] }>(); + takes_array::<{ [1_u32, T::ASSOC, 2] }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-macro.rs b/tests/ui/const-generics/mgca/array-expr-with-macro.rs new file mode 100644 index 000000000000..aef5acc1c803 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-macro.rs @@ -0,0 +1,18 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] +#![allow(dead_code)] + +macro_rules! make_array { + ($n:expr, $m:expr, $p:expr) => { + [N, $m, $p] + }; +} + +fn takes_array() {} + +fn generic_caller() { + takes_array::<{ make_array!(N, 2, 3) }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-struct.rs b/tests/ui/const-generics/mgca/array-expr-with-struct.rs new file mode 100644 index 000000000000..883af57e918e --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-struct.rs @@ -0,0 +1,20 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct Container { + values: [u32; 3], +} + +fn takes_container() {} + +fn generic_caller() { + takes_container::<{ Container { values: [N, M, 1] } }>(); + takes_container::<{ Container { values: [1, 2, 3] } }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-tuple.rs b/tests/ui/const-generics/mgca/array-expr-with-tuple.rs new file mode 100644 index 000000000000..004663dcefab --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-tuple.rs @@ -0,0 +1,13 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +fn takes_tuple() {} + +fn generic_caller() { + takes_tuple::<{ ([N, M], 5, [M, N]) }>(); + takes_tuple::<{ ([1, 2], 3, [4, 5]) }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr.rs b/tests/ui/const-generics/mgca/array-expr.rs deleted file mode 100644 index 099fee7ecd03..000000000000 --- a/tests/ui/const-generics/mgca/array-expr.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![expect(incomplete_features)] -#![feature(min_generic_const_args, adt_const_params)] - -fn takes_array() {} - -fn generic_caller() { - takes_array::<{ [N, N2, N] }>(); // ok - - takes_array::<{ [N, N2, const { 1 }] }>(); // ok - - takes_array::<{ [N, N2, const { 1 + 1 }] }>(); // ok - - takes_array::<{ [N, N2, 1] }>(); // ok - - takes_array::<{ [1, 1u32, 1_u32] }>(); // ok - - takes_array::<{ [N, N2, 1 + 1] }>(); // not implemented - //~^ ERROR complex const arguments must be placed inside of a `const` block - - takes_array::<{ [N; 3] }>(); // not implemented - //~^ ERROR complex const arguments must be placed inside of a `const` block -} - -fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr.stderr b/tests/ui/const-generics/mgca/array-expr.stderr deleted file mode 100644 index 0dda791c2e10..000000000000 --- a/tests/ui/const-generics/mgca/array-expr.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: complex const arguments must be placed inside of a `const` block - --> $DIR/array-expr.rs:17:29 - | -LL | takes_array::<{ [N, N2, 1 + 1] }>(); // not implemented - | ^^^^^ - -error: complex const arguments must be placed inside of a `const` block - --> $DIR/array-expr.rs:20:19 - | -LL | takes_array::<{ [N; 3] }>(); // not implemented - | ^^^^^^^^^^ - -error: aborting due to 2 previous errors - From ccc86f222830386e90b898deb13cbf2314a5fec8 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Fri, 9 Jan 2026 09:32:20 +0530 Subject: [PATCH 1903/3801] std: sys: fs: uefi: Implement File::write Tested using OVMF on QEMU. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index b1e5f33b1b22..95c1b437c057 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -336,8 +336,8 @@ impl File { crate::io::default_read_buf(|buf| self.read(buf), cursor) } - pub fn write(&self, _buf: &[u8]) -> io::Result { - unsupported() + pub fn write(&self, buf: &[u8]) -> io::Result { + self.0.write(buf) } pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { @@ -692,6 +692,25 @@ mod uefi_fs { } } + pub(crate) fn write(&self, buf: &[u8]) -> io::Result { + let file_ptr = self.protocol.as_ptr(); + let mut buf_size = buf.len(); + + let r = unsafe { + ((*file_ptr).write)( + file_ptr, + &mut buf_size, + buf.as_ptr().cast::().cast_mut(), + ) + }; + + if buf_size == 0 && r.is_error() { + Err(io::Error::from_raw_os_error(r.as_usize())) + } else { + Ok(buf_size) + } + } + pub(crate) fn file_info(&self) -> io::Result> { let file_ptr = self.protocol.as_ptr(); let mut info_id = file::INFO_ID; From 7c7cf45dcf6f84937faddf18f55b625f76012a3c Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Fri, 9 Jan 2026 12:48:19 +0000 Subject: [PATCH 1904/3801] Don't special-case `while` block type mismatch 67ea84d erroneously added this special-case when introducing `DesugaringKind::WhileLoop`. It had the unintended effect of emitting erroneous diagnostics in certain `while` blocks. --- compiler/rustc_hir_typeck/src/coercion.rs | 9 ++++----- .../block-result/block-must-not-have-result-while.stderr | 8 ++------ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 5e1e567d103e..52ea6cdeaa0e 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -54,7 +54,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; -use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span}; +use rustc_span::{BytePos, DUMMY_SP, Span}; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::solve::inspect::{self, InferCtxtProofTreeExt, ProofTreeVisitor}; use rustc_trait_selection::solve::{Certainty, Goal, NoSolution}; @@ -1828,10 +1828,9 @@ impl<'tcx> CoerceMany<'tcx> { // If the block is from an external macro or try (`?`) desugaring, then // do not suggest adding a semicolon, because there's nowhere to put it. // See issues #81943 and #87051. - && matches!( - cond_expr.span.desugaring_kind(), - None | Some(DesugaringKind::WhileLoop) - ) + // Similarly, if the block is from a loop desugaring, then also do not + // suggest adding a semicolon. See issue #150850. + && cond_expr.span.desugaring_kind().is_none() && !cond_expr.span.in_external_macro(fcx.tcx.sess.source_map()) && !matches!( cond_expr.kind, diff --git a/tests/ui/block-result/block-must-not-have-result-while.stderr b/tests/ui/block-result/block-must-not-have-result-while.stderr index 0b9941ea96ef..d8e854c9b9ba 100644 --- a/tests/ui/block-result/block-must-not-have-result-while.stderr +++ b/tests/ui/block-result/block-must-not-have-result-while.stderr @@ -9,12 +9,8 @@ LL | while true { error[E0308]: mismatched types --> $DIR/block-must-not-have-result-while.rs:5:9 | -LL | / while true { -LL | | true - | | ^^^^ expected `()`, found `bool` -LL | | -LL | | } - | |_____- expected this to be `()` +LL | true + | ^^^^ expected `()`, found `bool` error: aborting due to 1 previous error; 1 warning emitted From 5674be29fa5819cf5d1578f5a53f7a9603a38d90 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Fri, 9 Jan 2026 12:04:23 +0000 Subject: [PATCH 1905/3801] Don't suggest breaking with value from `for` or `while` loops --- .../src/fn_ctxt/suggestions.rs | 22 ++++++---- ...nt-suggest-break-from-unbreakable-loops.rs | 39 +++++++++++++++++ ...uggest-break-from-unbreakable-loops.stderr | 42 +++++++++++++++++++ 3 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.rs create mode 100644 tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index d51b052e0d1b..3e4c194147f9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -10,8 +10,8 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::lang_items::LangItem; use rustc_hir::{ self as hir, Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, - GenericBound, HirId, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind, TyKind, - WherePredicateKind, expr_needs_parens, is_range_literal, + GenericBound, HirId, LoopSource, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind, + TyKind, WherePredicateKind, expr_needs_parens, is_range_literal, }; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_hir_analysis::suggest_impl_trait; @@ -1170,15 +1170,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let found = self.resolve_vars_if_possible(found); - let in_loop = self.is_loop(id) - || self - .tcx + let innermost_loop = if self.is_loop(id) { + Some(self.tcx.hir_node(id)) + } else { + self.tcx .hir_parent_iter(id) .take_while(|(_, node)| { // look at parents until we find the first body owner node.body_id().is_none() }) - .any(|(parent_id, _)| self.is_loop(parent_id)); + .find_map(|(parent_id, node)| self.is_loop(parent_id).then_some(node)) + }; + let can_break_with_value = innermost_loop.is_some_and(|node| { + matches!( + node, + Node::Expr(Expr { kind: ExprKind::Loop(_, _, LoopSource::Loop, ..), .. }) + ) + }); let in_local_statement = self.is_local_statement(id) || self @@ -1186,7 +1194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .hir_parent_iter(id) .any(|(parent_id, _)| self.is_local_statement(parent_id)); - if in_loop && in_local_statement { + if can_break_with_value && in_local_statement { err.multipart_suggestion( "you might have meant to break the loop with this value", vec![ diff --git a/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.rs b/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.rs new file mode 100644 index 000000000000..69b57486138d --- /dev/null +++ b/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.rs @@ -0,0 +1,39 @@ +//! Don't suggest breaking with value from `for` or `while` loops +//! +//! Regression test for https://github.com/rust-lang/rust/issues/150850 + +fn returns_i32() -> i32 { 0 } + +fn suggest_breaking_from_loop() { + let _ = loop { + returns_i32() //~ ERROR mismatched types + //~^ SUGGESTION ; + //~| SUGGESTION break + }; +} + +fn dont_suggest_breaking_from_for() { + let _ = for _ in 0.. { + returns_i32() //~ ERROR mismatched types + //~^ SUGGESTION ; + }; +} + +fn dont_suggest_breaking_from_while() { + let cond = true; + let _ = while cond { + returns_i32() //~ ERROR mismatched types + //~^ SUGGESTION ; + }; +} + +fn dont_suggest_breaking_from_for_nested_in_loop() { + let _ = loop { + for _ in 0.. { + returns_i32() //~ ERROR mismatched types + //~^ SUGGESTION ; + } + }; +} + +fn main() {} diff --git a/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.stderr b/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.stderr new file mode 100644 index 000000000000..880cc53f9a7c --- /dev/null +++ b/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.stderr @@ -0,0 +1,42 @@ +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-from-unbreakable-loops.rs:9:9 + | +LL | returns_i32() + | ^^^^^^^^^^^^^ expected `()`, found `i32` + | +help: consider using a semicolon here + | +LL | returns_i32(); + | + +help: you might have meant to break the loop with this value + | +LL | break returns_i32(); + | +++++ + + +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-from-unbreakable-loops.rs:17:9 + | +LL | returns_i32() + | ^^^^^^^^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `i32` + +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-from-unbreakable-loops.rs:25:9 + | +LL | returns_i32() + | ^^^^^^^^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `i32` + +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-from-unbreakable-loops.rs:33:13 + | +LL | returns_i32() + | ^^^^^^^^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `i32` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From 14c6e602f423e01082367954fb0ea19f2b177ba0 Mon Sep 17 00:00:00 2001 From: oncecelll Date: Sat, 10 Jan 2026 13:25:31 +0800 Subject: [PATCH 1906/3801] Add missing documentation for globs feature Signed-off-by: oncecelll --- compiler/rustc_feature/src/accepted.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 13c1f2219bed..43032bf938c0 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -235,7 +235,7 @@ declare_features! ( (accepted, generic_param_attrs, "1.27.0", Some(48848)), /// Allows the `#[global_allocator]` attribute. (accepted, global_allocator, "1.28.0", Some(27389)), - // FIXME: explain `globs`. + /// Allows globs imports (`use module::*;`) to import all public items from a module. (accepted, globs, "1.0.0", None), /// Allows using `..=X` as a pattern. (accepted, half_open_range_patterns, "1.66.0", Some(67264)), From a0df7b2ad5c94f97a30d04008059e9dcfd1492a2 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 10 Jan 2026 09:34:44 +0100 Subject: [PATCH 1907/3801] compiler: Forward attributes to eii-expanded macros Otherwise you get errors like these if you have an Externally Implementable Item defined in std: error: attribute macro has missing stability attribute --> library/std/src/io/mod.rs:2269:1 | 2269 | #[eii(on_broken_pipe)] | ^^^^^^^^^^^^^^^^^^^^-- | | | in this attribute macro expansion | ::: library/core/src/macros/mod.rs:1899:5 | 1899 | pub macro eii($item:item) { | ------------- in this expansion of `#[eii]` Or (fatal) warnings like these: warning: missing documentation for an attribute macro --> library/std/src/io/mod.rs:2269:1 --- compiler/rustc_builtin_macros/src/eii.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 2d67608609e3..0ebd3dc826d4 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -133,6 +133,7 @@ fn eii_( macro_name, foreign_item_name, impl_unsafe, + &attrs_from_decl, ))); return_items.into_iter().map(wrap_item).collect() @@ -416,9 +417,14 @@ fn generate_attribute_macro_to_implement( macro_name: Ident, foreign_item_name: Ident, impl_unsafe: bool, + attrs_from_decl: &[Attribute], ) -> ast::Item { let mut macro_attrs = ThinVec::new(); + // To avoid e.g. `error: attribute macro has missing stability attribute` + // errors for eii's in std. + macro_attrs.extend_from_slice(attrs_from_decl); + // #[builtin_macro(eii_shared_macro)] macro_attrs.push(ecx.attr_nested_word(sym::rustc_builtin_macro, sym::eii_shared_macro, span)); From 9b811544f211639c4e828e5bbe3497167ff40723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 10 Jan 2026 11:10:31 +0100 Subject: [PATCH 1908/3801] once again reorganize the EII tests a bit --- .../auxiliary/{codegen1.rs => other_crate_privacy1.rs} | 0 .../auxiliary/{codegen3.rs => other_crate_privacy2.rs} | 0 tests/ui/eii/{ => duplicate}/multiple_decls.rs | 0 tests/ui/eii/{ => duplicate}/multiple_decls.stderr | 0 tests/ui/eii/{ => duplicate}/multiple_impls.rs | 0 tests/ui/eii/{ => duplicate}/multiple_impls.run.stdout | 0 .../auxiliary/codegen_cross_crate_other_crate.rs} | 0 tests/ui/eii/{ => linking}/codegen_cross_crate.rs | 4 ++-- .../eii/{ => linking}/codegen_cross_crate.run.stdout | 0 tests/ui/eii/{ => linking}/codegen_single_crate.rs | 0 .../eii/{ => linking}/codegen_single_crate.run.stdout | 0 tests/ui/eii/{ => linking}/same-symbol.rs | 0 tests/ui/eii/{ => linking}/same-symbol.run.stdout | 0 tests/ui/eii/privacy1.rs | 6 +++--- tests/ui/eii/privacy2.rs | 4 ++-- tests/ui/eii/privacy2.stderr | 10 +++++----- .../auxiliary/cross_crate_eii_declaration.rs | 0 .../cross_crate_type_ok.rs} | 0 .../ui/eii/{ => type_checking}/cross_crate_wrong_ty.rs | 0 .../{ => type_checking}/cross_crate_wrong_ty.stderr | 0 20 files changed, 12 insertions(+), 12 deletions(-) rename tests/ui/eii/auxiliary/{codegen1.rs => other_crate_privacy1.rs} (100%) rename tests/ui/eii/auxiliary/{codegen3.rs => other_crate_privacy2.rs} (100%) rename tests/ui/eii/{ => duplicate}/multiple_decls.rs (100%) rename tests/ui/eii/{ => duplicate}/multiple_decls.stderr (100%) rename tests/ui/eii/{ => duplicate}/multiple_impls.rs (100%) rename tests/ui/eii/{ => duplicate}/multiple_impls.run.stdout (100%) rename tests/ui/eii/{auxiliary/codegen2.rs => linking/auxiliary/codegen_cross_crate_other_crate.rs} (100%) rename tests/ui/eii/{ => linking}/codegen_cross_crate.rs (82%) rename tests/ui/eii/{ => linking}/codegen_cross_crate.run.stdout (100%) rename tests/ui/eii/{ => linking}/codegen_single_crate.rs (100%) rename tests/ui/eii/{ => linking}/codegen_single_crate.run.stdout (100%) rename tests/ui/eii/{ => linking}/same-symbol.rs (100%) rename tests/ui/eii/{ => linking}/same-symbol.run.stdout (100%) rename tests/ui/eii/{ => type_checking}/auxiliary/cross_crate_eii_declaration.rs (100%) rename tests/ui/eii/{cross_crate.rs => type_checking/cross_crate_type_ok.rs} (100%) rename tests/ui/eii/{ => type_checking}/cross_crate_wrong_ty.rs (100%) rename tests/ui/eii/{ => type_checking}/cross_crate_wrong_ty.stderr (100%) diff --git a/tests/ui/eii/auxiliary/codegen1.rs b/tests/ui/eii/auxiliary/other_crate_privacy1.rs similarity index 100% rename from tests/ui/eii/auxiliary/codegen1.rs rename to tests/ui/eii/auxiliary/other_crate_privacy1.rs diff --git a/tests/ui/eii/auxiliary/codegen3.rs b/tests/ui/eii/auxiliary/other_crate_privacy2.rs similarity index 100% rename from tests/ui/eii/auxiliary/codegen3.rs rename to tests/ui/eii/auxiliary/other_crate_privacy2.rs diff --git a/tests/ui/eii/multiple_decls.rs b/tests/ui/eii/duplicate/multiple_decls.rs similarity index 100% rename from tests/ui/eii/multiple_decls.rs rename to tests/ui/eii/duplicate/multiple_decls.rs diff --git a/tests/ui/eii/multiple_decls.stderr b/tests/ui/eii/duplicate/multiple_decls.stderr similarity index 100% rename from tests/ui/eii/multiple_decls.stderr rename to tests/ui/eii/duplicate/multiple_decls.stderr diff --git a/tests/ui/eii/multiple_impls.rs b/tests/ui/eii/duplicate/multiple_impls.rs similarity index 100% rename from tests/ui/eii/multiple_impls.rs rename to tests/ui/eii/duplicate/multiple_impls.rs diff --git a/tests/ui/eii/multiple_impls.run.stdout b/tests/ui/eii/duplicate/multiple_impls.run.stdout similarity index 100% rename from tests/ui/eii/multiple_impls.run.stdout rename to tests/ui/eii/duplicate/multiple_impls.run.stdout diff --git a/tests/ui/eii/auxiliary/codegen2.rs b/tests/ui/eii/linking/auxiliary/codegen_cross_crate_other_crate.rs similarity index 100% rename from tests/ui/eii/auxiliary/codegen2.rs rename to tests/ui/eii/linking/auxiliary/codegen_cross_crate_other_crate.rs diff --git a/tests/ui/eii/codegen_cross_crate.rs b/tests/ui/eii/linking/codegen_cross_crate.rs similarity index 82% rename from tests/ui/eii/codegen_cross_crate.rs rename to tests/ui/eii/linking/codegen_cross_crate.rs index a1fa617491bd..4016712e7504 100644 --- a/tests/ui/eii/codegen_cross_crate.rs +++ b/tests/ui/eii/linking/codegen_cross_crate.rs @@ -1,6 +1,6 @@ //@ run-pass //@ check-run-results -//@ aux-build: codegen2.rs +//@ aux-build: codegen_cross_crate_other_crate.rs //@ compile-flags: -O //@ ignore-backends: gcc // FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 @@ -8,7 +8,7 @@ // Tests whether calling EIIs works with the declaration in another crate. #![feature(extern_item_impls)] -extern crate codegen2 as codegen; +extern crate codegen_cross_crate_other_crate as codegen; #[codegen::eii1] fn eii1_impl(x: u64) { diff --git a/tests/ui/eii/codegen_cross_crate.run.stdout b/tests/ui/eii/linking/codegen_cross_crate.run.stdout similarity index 100% rename from tests/ui/eii/codegen_cross_crate.run.stdout rename to tests/ui/eii/linking/codegen_cross_crate.run.stdout diff --git a/tests/ui/eii/codegen_single_crate.rs b/tests/ui/eii/linking/codegen_single_crate.rs similarity index 100% rename from tests/ui/eii/codegen_single_crate.rs rename to tests/ui/eii/linking/codegen_single_crate.rs diff --git a/tests/ui/eii/codegen_single_crate.run.stdout b/tests/ui/eii/linking/codegen_single_crate.run.stdout similarity index 100% rename from tests/ui/eii/codegen_single_crate.run.stdout rename to tests/ui/eii/linking/codegen_single_crate.run.stdout diff --git a/tests/ui/eii/same-symbol.rs b/tests/ui/eii/linking/same-symbol.rs similarity index 100% rename from tests/ui/eii/same-symbol.rs rename to tests/ui/eii/linking/same-symbol.rs diff --git a/tests/ui/eii/same-symbol.run.stdout b/tests/ui/eii/linking/same-symbol.run.stdout similarity index 100% rename from tests/ui/eii/same-symbol.run.stdout rename to tests/ui/eii/linking/same-symbol.run.stdout diff --git a/tests/ui/eii/privacy1.rs b/tests/ui/eii/privacy1.rs index b5bbf68bfdaf..72aec83d2cee 100644 --- a/tests/ui/eii/privacy1.rs +++ b/tests/ui/eii/privacy1.rs @@ -1,13 +1,13 @@ //@ run-pass //@ check-run-results -//@ aux-build: codegen1.rs +//@ aux-build: other_crate_privacy1.rs //@ ignore-backends: gcc -// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418 //@ ignore-windows // Tests whether re-exports work. #![feature(extern_item_impls)] -extern crate codegen1 as codegen; +extern crate other_crate_privacy1 as codegen; #[codegen::eii1] fn eii1_impl(x: u64) { diff --git a/tests/ui/eii/privacy2.rs b/tests/ui/eii/privacy2.rs index a0bc26ef629b..e3f1f8c863da 100644 --- a/tests/ui/eii/privacy2.rs +++ b/tests/ui/eii/privacy2.rs @@ -1,8 +1,8 @@ -//@ aux-build:codegen3.rs +//@ aux-build:other_crate_privacy2.rs // Tests whether name resolution respects privacy properly. #![feature(extern_item_impls)] -extern crate codegen3 as codegen; +extern crate other_crate_privacy2 as codegen; // has a span but in the other crate //~? ERROR `#[eii2]` required, but not found diff --git a/tests/ui/eii/privacy2.stderr b/tests/ui/eii/privacy2.stderr index 903285d4d1e3..9f4fd6a071c9 100644 --- a/tests/ui/eii/privacy2.stderr +++ b/tests/ui/eii/privacy2.stderr @@ -11,24 +11,24 @@ LL | codegen::decl1(42); | ^^^^^ private function | note: the function `decl1` is defined here - --> $DIR/auxiliary/codegen3.rs:7:1 + --> $DIR/auxiliary/other_crate_privacy2.rs:7:1 | LL | fn decl1(x: u64); | ^^^^^^^^^^^^^^^^^ error: `#[eii2]` required, but not found - --> $DIR/auxiliary/codegen3.rs:9:7 + --> $DIR/auxiliary/other_crate_privacy2.rs:9:7 | LL | #[eii(eii2)] - | ^^^^ expected because `#[eii2]` was declared here in crate `codegen3` + | ^^^^ expected because `#[eii2]` was declared here in crate `other_crate_privacy2` | = help: expected at least one implementation in crate `privacy2` or any of its dependencies error: `#[eii3]` required, but not found - --> $DIR/auxiliary/codegen3.rs:13:11 + --> $DIR/auxiliary/other_crate_privacy2.rs:13:11 | LL | #[eii(eii3)] - | ^^^^ expected because `#[eii3]` was declared here in crate `codegen3` + | ^^^^ expected because `#[eii3]` was declared here in crate `other_crate_privacy2` | = help: expected at least one implementation in crate `privacy2` or any of its dependencies diff --git a/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs b/tests/ui/eii/type_checking/auxiliary/cross_crate_eii_declaration.rs similarity index 100% rename from tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs rename to tests/ui/eii/type_checking/auxiliary/cross_crate_eii_declaration.rs diff --git a/tests/ui/eii/cross_crate.rs b/tests/ui/eii/type_checking/cross_crate_type_ok.rs similarity index 100% rename from tests/ui/eii/cross_crate.rs rename to tests/ui/eii/type_checking/cross_crate_type_ok.rs diff --git a/tests/ui/eii/cross_crate_wrong_ty.rs b/tests/ui/eii/type_checking/cross_crate_wrong_ty.rs similarity index 100% rename from tests/ui/eii/cross_crate_wrong_ty.rs rename to tests/ui/eii/type_checking/cross_crate_wrong_ty.rs diff --git a/tests/ui/eii/cross_crate_wrong_ty.stderr b/tests/ui/eii/type_checking/cross_crate_wrong_ty.stderr similarity index 100% rename from tests/ui/eii/cross_crate_wrong_ty.stderr rename to tests/ui/eii/type_checking/cross_crate_wrong_ty.stderr From c87bb01b9e8bc2419f95bba7f06f1ccee0cabca5 Mon Sep 17 00:00:00 2001 From: Aliaksei Semianiuk Date: Sat, 10 Jan 2026 15:34:41 +0500 Subject: [PATCH 1909/3801] Changelog for Clippy 1.93 --- CHANGELOG.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cda8003b05c..afefd436aada 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,66 @@ document. ## Unreleased / Beta / In Rust Nightly -[d9fb15c...master](https://github.com/rust-lang/rust-clippy/compare/d9fb15c...master) +[92b4b68...master](https://github.com/rust-lang/rust-clippy/compare/92b4b68...master) + +## Rust 1.93 + +Current stable, released 2026-01-22 + +[View all 96 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-10-17T15%3A48%3A11Z..2025-11-28T19%3A22%3A54Z+base%3Amaster) + +### New Lints + +* Added [`doc_paragraphs_missing_punctuation`] to `restriction` + [#15758](https://github.com/rust-lang/rust-clippy/pull/15758) + +### Moves and Deprecations + +* Renamed [`needless_if`] to [`needless_ifs`] + [#15961](https://github.com/rust-lang/rust-clippy/pull/15961) +* Renamed [`empty_enum`] to [`empty_enums`] + [#15912](https://github.com/rust-lang/rust-clippy/pull/15912) + +### Enhancements + +* [`result_large_err`] added `large_error_ignored` configuration + [#15697](https://github.com/rust-lang/rust-clippy/pull/15697) +* [`explicit_deref_methods`] don't lint in `impl Deref(Mut)` + [#16113](https://github.com/rust-lang/rust-clippy/pull/16113) +* [`missing_docs_in_private_items`] don't lint items in bodies and automatically derived impls; + better detect when things are accessible from the crate root; lint unnameable items which are + accessible outside the crate + [#14741](https://github.com/rust-lang/rust-clippy/pull/14741) +* [`unnecessary_unwrap`] and [`panicking_unwrap`] lint field accesses + [#15949](https://github.com/rust-lang/rust-clippy/pull/15949) +* [`ok_expect`] add autofix + [#15867](https://github.com/rust-lang/rust-clippy/pull/15867) +* [`let_and_return`] disallow _any_ text between let and return + [#16006](https://github.com/rust-lang/rust-clippy/pull/16006) +* [`needless_collect`] extend to lint more cases + [#14361](https://github.com/rust-lang/rust-clippy/pull/14361) +* [`needless_doctest_main`] and [`test_attr_in_doctest`] now handle whitespace in language tags + [#15967](https://github.com/rust-lang/rust-clippy/pull/15967) +* [`search_is_some`] now fixes code spanning multiple lines + [#15902](https://github.com/rust-lang/rust-clippy/pull/15902) +* [`unnecessary_find_map`] and [`unnecessary_filter_map`] make diagnostic spans more precise + [#15929](https://github.com/rust-lang/rust-clippy/pull/15929) +* [`precedence`] warn about ambiguity when a closure is used as a method call receiver + [#14421](https://github.com/rust-lang/rust-clippy/pull/14421) +* [`match_as_ref`] suggest `as_ref` when the reference needs to be cast; improve diagnostics + [#15934](https://github.com/rust-lang/rust-clippy/pull/15934) + [#15928](https://github.com/rust-lang/rust-clippy/pull/15928) + +### False Positive Fixes + +* [`single_range_in_vec_init`] fix FP for explicit `Range` + [#16043](https://github.com/rust-lang/rust-clippy/pull/16043) +* [`mod_module_files`] fix false positive for integration tests in workspace crates + [#16048](https://github.com/rust-lang/rust-clippy/pull/16048) +* [`replace_box`] fix FP when the box is moved + [#15984](https://github.com/rust-lang/rust-clippy/pull/15984) +* [`len_zero`] fix FP on unstable methods + [#15894](https://github.com/rust-lang/rust-clippy/pull/15894) ## Rust 1.92 From c825a504ab7d284610adf43d496fbfe899ed90aa Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 10 Jan 2026 09:51:42 +0100 Subject: [PATCH 1910/3801] Cleanup --- .../rust-analyzer/crates/hir/src/symbols.rs | 145 +++--- .../crates/ide-db/src/symbol_index.rs | 185 ++------ .../ide-db/src/test_data/test_doc_alias.txt | 112 +++-- .../test_symbol_index_collection.txt | 424 +++++++++++------- .../test_symbols_exclude_imports.txt | 12 +- .../test_data/test_symbols_with_imports.txt | 24 +- .../crates/ide/src/navigation_target.rs | 4 +- .../crates/mbe/src/expander/matcher.rs | 5 +- .../rust-analyzer/tests/slow-tests/main.rs | 44 +- .../rust-analyzer/crates/syntax/src/ptr.rs | 2 +- 10 files changed, 507 insertions(+), 450 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index 544c759ed3a7..f9002f31fd15 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -21,12 +21,9 @@ use hir_ty::{ }; use intern::Symbol; use rustc_hash::FxHashMap; -use syntax::{ - AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, ToSmolStr, - ast::{HasModuleItem, HasName}, -}; +use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, ToSmolStr, ast::HasName}; -use crate::{Crate, HasCrate, Module, ModuleDef, Semantics}; +use crate::{HasCrate, Module, ModuleDef, Semantics}; /// The actual data that is stored in the index. It should be as compact as /// possible. @@ -44,14 +41,14 @@ pub struct FileSymbol<'db> { _marker: PhantomData<&'db ()>, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct DeclarationLocation { /// The file id for both the `ptr` and `name_ptr`. pub hir_file_id: HirFileId, /// This points to the whole syntax node of the declaration. pub ptr: SyntaxNodePtr, /// This points to the [`syntax::ast::Name`] identifier of the declaration. - pub name_ptr: AstPtr>, + pub name_ptr: Option>>, } impl DeclarationLocation { @@ -61,70 +58,6 @@ impl DeclarationLocation { } } -impl<'db> FileSymbol<'db> { - /// Create a `FileSymbol` representing a crate's root module. - /// This is used for crate search queries like `::` or `::foo`. - pub fn for_crate_root(db: &'db dyn HirDatabase, krate: Crate) -> Option> { - let display_name = krate.display_name(db)?; - let crate_name = display_name.crate_name(); - let root_module = krate.root_module(db); - let def_map = crate_def_map(db, krate.into()); - let module_data = &def_map[root_module.into()]; - - // Get the definition source (the source file for crate roots) - let definition = module_data.origin.definition_source(db); - let hir_file_id = definition.file_id; - - // For a crate root, the "declaration" is the source file itself - // We use the entire file's syntax node as the location - let syntax_node = definition.value.node(); - let ptr = SyntaxNodePtr::new(&syntax_node); - - // For the name, we need to create a synthetic name pointer. - // We'll use the first token of the file as a placeholder since crate roots - // don't have an explicit name in the source. - // We create a name_ptr pointing to the start of the file. - let name_ptr = match &definition.value { - crate::ModuleSource::SourceFile(sf) => { - // Try to find the first item with a name as a reasonable location for focus - // This is a bit of a hack but works for navigation purposes - let first_item: Option = sf.items().next(); - if let Some(item) = first_item { - if let Some(name) = item.syntax().children().find_map(syntax::ast::Name::cast) { - AstPtr::new(&name).wrap_left() - } else { - // No name found, try to use a NameRef instead - if let Some(name_ref) = - item.syntax().descendants().find_map(syntax::ast::NameRef::cast) - { - AstPtr::new(&name_ref).wrap_right() - } else { - return None; - } - } - } else { - return None; - } - } - _ => return None, - }; - - let loc = DeclarationLocation { hir_file_id, ptr, name_ptr }; - - Some(FileSymbol { - name: Symbol::intern(crate_name.as_str()), - def: ModuleDef::Module(root_module), - loc, - container_name: None, - is_alias: false, - is_assoc: false, - is_import: false, - do_not_complete: Complete::Yes, - _marker: PhantomData, - }) - } -} - /// Represents an outstanding module that the symbol collector must collect symbols from. #[derive(Debug)] struct SymbolCollectorWork { @@ -167,6 +100,11 @@ impl<'a> SymbolCollector<'a> { let _p = tracing::info_span!("SymbolCollector::collect", ?module).entered(); tracing::info!(?module, "SymbolCollector::collect"); + // If this is a crate root module, add a symbol for the crate itself + if module.is_crate_root(self.db) { + self.push_crate_root(module); + } + // The initial work is the root module we're collecting, additional work will // be populated as we traverse the module's definitions. self.work.push(SymbolCollectorWork { module_id: module.into(), parent: None }); @@ -176,6 +114,51 @@ impl<'a> SymbolCollector<'a> { } } + /// Push a symbol for a crate's root module. + /// This allows crate roots to appear in the symbol index for queries like `::` or `::foo`. + fn push_crate_root(&mut self, module: Module) { + let krate = module.krate(self.db); + let Some(display_name) = krate.display_name(self.db) else { return }; + let crate_name = display_name.crate_name(); + let canonical_name = display_name.canonical_name(); + + let def_map = crate_def_map(self.db, krate.into()); + let module_data = &def_map[def_map.crate_root(self.db)]; + + let definition = module_data.origin.definition_source(self.db); + let hir_file_id = definition.file_id; + let syntax_node = definition.value.node(); + let ptr = SyntaxNodePtr::new(&syntax_node); + + let loc = DeclarationLocation { hir_file_id, ptr, name_ptr: None }; + + self.symbols.insert(FileSymbol { + name: crate_name.symbol().clone(), + def: ModuleDef::Module(module), + loc, + container_name: None, + is_alias: false, + is_assoc: false, + is_import: false, + do_not_complete: Complete::Yes, + _marker: PhantomData, + }); + + if canonical_name != crate_name.symbol() { + self.symbols.insert(FileSymbol { + name: canonical_name.clone(), + def: ModuleDef::Module(module), + loc, + container_name: None, + is_alias: false, + is_assoc: false, + is_import: false, + do_not_complete: Complete::Yes, + _marker: PhantomData, + }); + } + } + pub fn finish(self) -> Box<[FileSymbol<'a>]> { self.symbols.into_iter().collect() } @@ -277,7 +260,7 @@ impl<'a> SymbolCollector<'a> { let dec_loc = DeclarationLocation { hir_file_id: source.file_id, ptr: SyntaxNodePtr::new(use_tree_src.syntax()), - name_ptr: AstPtr::new(&name_syntax), + name_ptr: Some(AstPtr::new(&name_syntax)), }; this.symbols.insert(FileSymbol { name: name.symbol().clone(), @@ -312,7 +295,7 @@ impl<'a> SymbolCollector<'a> { let dec_loc = DeclarationLocation { hir_file_id: source.file_id, ptr: SyntaxNodePtr::new(source.value.syntax()), - name_ptr: AstPtr::new(&name_syntax), + name_ptr: Some(AstPtr::new(&name_syntax)), }; this.symbols.insert(FileSymbol { name: name.symbol().clone(), @@ -477,10 +460,10 @@ impl<'a> SymbolCollector<'a> { let source = loc.source(self.db); let Some(name_node) = source.value.name() else { return Complete::Yes }; let def = ModuleDef::from(id.into()); - let dec_loc = DeclarationLocation { + let loc = DeclarationLocation { hir_file_id: source.file_id, ptr: SyntaxNodePtr::new(source.value.syntax()), - name_ptr: AstPtr::new(&name_node).wrap_left(), + name_ptr: Some(AstPtr::new(&name_node).wrap_left()), }; let mut do_not_complete = Complete::Yes; @@ -495,7 +478,7 @@ impl<'a> SymbolCollector<'a> { self.symbols.insert(FileSymbol { name: alias.clone(), def, - loc: dec_loc.clone(), + loc, container_name: self.current_container_name.clone(), is_alias: true, is_assoc, @@ -510,7 +493,7 @@ impl<'a> SymbolCollector<'a> { name: name.symbol().clone(), def, container_name: self.current_container_name.clone(), - loc: dec_loc, + loc, is_alias: false, is_assoc, is_import: false, @@ -527,10 +510,10 @@ impl<'a> SymbolCollector<'a> { let Some(declaration) = module_data.origin.declaration() else { return }; let module = declaration.to_node(self.db); let Some(name_node) = module.name() else { return }; - let dec_loc = DeclarationLocation { + let loc = DeclarationLocation { hir_file_id: declaration.file_id, ptr: SyntaxNodePtr::new(module.syntax()), - name_ptr: AstPtr::new(&name_node).wrap_left(), + name_ptr: Some(AstPtr::new(&name_node).wrap_left()), }; let def = ModuleDef::Module(module_id.into()); @@ -543,7 +526,7 @@ impl<'a> SymbolCollector<'a> { self.symbols.insert(FileSymbol { name: alias.clone(), def, - loc: dec_loc.clone(), + loc, container_name: self.current_container_name.clone(), is_alias: true, is_assoc: false, @@ -558,7 +541,7 @@ impl<'a> SymbolCollector<'a> { name: name.symbol().clone(), def: ModuleDef::Module(module_id.into()), container_name: self.current_container_name.clone(), - loc: dec_loc, + loc, is_alias: false, is_assoc: false, is_import: false, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index ca0d5ec1e5e6..05c3f360fa87 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -129,58 +129,19 @@ impl Query { /// - `anchor_to_crate`: Whether the first segment must be a crate name fn parse_path_query(query: &str) -> (Vec, String, bool) { // Check for leading :: (absolute path / crate search) - let anchor_to_crate = query.starts_with("::"); - let query = if anchor_to_crate { &query[2..] } else { query }; - - // Handle sole "::" - return all crates - if query.is_empty() && anchor_to_crate { - return (vec![], String::new(), true); - } - - // Check for trailing :: (module browsing - returns all items in module) - let return_all_in_module = query.ends_with("::"); - let query = if return_all_in_module { query.trim_end_matches("::") } else { query }; - - if !query.contains("::") { - // No path separator - single segment - if anchor_to_crate && !return_all_in_module { - // "::foo" - fuzzy search crate names only - return (vec![], query.to_string(), true); - } - if return_all_in_module { - // "foo::" - browse all items in module "foo" - // path_filter = ["foo"], query = "", anchor_to_crate = false/true - return (vec![query.to_string()], String::new(), anchor_to_crate); - } - // Plain "foo" - normal fuzzy search - return (vec![], query.to_string(), false); - } - - // Filter out empty segments (e.g., "foo::::bar" -> "foo::bar") - let segments: Vec<&str> = query.split("::").filter(|s| !s.is_empty()).collect(); - - if segments.is_empty() { - return (vec![], String::new(), anchor_to_crate); - } - - let path: Vec = - segments[..segments.len() - 1].iter().map(|s| s.to_string()).collect(); - let item = if return_all_in_module { - // All segments go to path, item is empty - let mut path = path; - path.push(segments.last().unwrap().to_string()); - return (path, String::new(), anchor_to_crate); - } else { - segments.last().unwrap_or(&"").to_string() + let (query, anchor_to_crate) = match query.strip_prefix("::") { + Some(q) => (q, true), + None => (query, false), }; - (path, item, anchor_to_crate) - } + let Some((prefix, query)) = query.rsplit_once("::") else { + return (vec![], query.to_owned(), anchor_to_crate); + }; - /// Returns true if this query should return all items in a module - /// (i.e., the original query ended with `::`) - fn is_module_browsing(&self) -> bool { - self.query.is_empty() && !self.path_filter.is_empty() + let prefix: Vec<_> = + prefix.split("::").filter(|s| !s.is_empty()).map(ToOwned::to_owned).collect(); + + (prefix, query.to_owned(), anchor_to_crate) } /// Returns true if this query is searching for crates @@ -245,11 +206,14 @@ pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex<'_ // That is, `#` switches from "types" to all symbols, `*` switches from the current // workspace to dependencies. // -// Note that filtering does not currently work in VSCode due to the editor never -// sending the special symbols to the language server. Instead, you can configure -// the filtering via the `rust-analyzer.workspace.symbol.search.scope` and -// `rust-analyzer.workspace.symbol.search.kind` settings. Symbols prefixed -// with `__` are hidden from the search results unless configured otherwise. +// This also supports general Rust path syntax with the usual rules. +// +// Note that paths do not currently work in VSCode due to the editor never +// sending the special symbols to the language server. Some other editors might not support the # or +// * search either, instead, you can configure the filtering via the +// `rust-analyzer.workspace.symbol.search.scope` and `rust-analyzer.workspace.symbol.search.kind` +// settings. Symbols prefixed with `__` are hidden from the search results unless configured +// otherwise. // // | Editor | Shortcut | // |---------|-----------| @@ -257,12 +221,11 @@ pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex<'_ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> { let _p = tracing::info_span!("world_symbols", query = ?query.query).entered(); - // Handle special case: "::" alone or "::foo" for crate search if query.is_crate_search() { return search_crates(db, &query); } - // If we have a path filter, resolve it to target modules first + // If we have a path filter, resolve it to target modules let indices: Vec<_> = if !query.path_filter.is_empty() { let target_modules = resolve_path_to_modules( db, @@ -272,13 +235,11 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> { ); if target_modules.is_empty() { - return vec![]; // Path doesn't resolve to any module + return vec![]; } - // Get symbol indices only for the resolved modules target_modules.iter().map(|&module| SymbolIndex::module_symbols(db, module)).collect() } else if query.libs { - // Original behavior for non-path queries searching libs LibraryRoots::get(db) .roots(db) .par_iter() @@ -289,7 +250,6 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> { .map(|&root| SymbolIndex::library_symbols(db, root)) .collect() } else { - // Original behavior for non-path queries searching local crates let mut crates = Vec::new(); for &root in LocalRoots::get(db).roots(db).iter() { @@ -303,23 +263,11 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> { let mut res = vec![]; - // For module browsing (empty query, non-empty path_filter), return all symbols - if query.is_module_browsing() { - for index in &indices { - for symbol in index.symbols.iter() { - // Apply existing filters (only_types, assoc_mode, exclude_imports, etc.) - if query.matches_symbol_filters(symbol) { - res.push(symbol.clone()); - } - } - } - } else { - // Normal search: use FST to match item name - query.search::<()>(&indices, |f| { - res.push(f.clone()); - ControlFlow::Continue(()) - }); - } + // Normal search: use FST to match item name + query.search::<()>(&indices, |f| { + res.push(f.clone()); + ControlFlow::Continue(()) + }); res } @@ -341,9 +289,15 @@ fn search_crates<'db>(db: &'db RootDatabase, query: &Query) -> Vec) -> bool { - // Check only_types filter - if self.only_types - && !matches!( - symbol.def, - hir::ModuleDef::Adt(..) - | hir::ModuleDef::TypeAlias(..) - | hir::ModuleDef::BuiltinType(..) - | hir::ModuleDef::Trait(..) - ) - { - return false; - } - - // Check assoc_mode filter - if !self.matches_assoc_mode(symbol.is_assoc) { - return false; - } - - // Check exclude_imports filter - if self.exclude_imports && symbol.is_import { - return false; - } - - // Check underscore prefix - let ignore_underscore_prefixed = !self.query.starts_with("__"); - if ignore_underscore_prefixed && symbol.name.as_str().starts_with("__") { - return false; - } - - true - } } #[cfg(test)] @@ -939,34 +858,6 @@ pub struct Foo; assert!(!anchor); } - #[test] - fn test_query_modes() { - // Test is_module_browsing - let query = Query::new("foo::".to_owned()); - assert!(query.is_module_browsing()); - assert!(!query.is_crate_search()); - - // Test is_crate_search with sole :: - let query = Query::new("::".to_owned()); - assert!(!query.is_module_browsing()); - assert!(query.is_crate_search()); - - // Test is_crate_search with ::foo - let query = Query::new("::foo".to_owned()); - assert!(!query.is_module_browsing()); - assert!(query.is_crate_search()); - - // Normal query should be neither - let query = Query::new("foo".to_owned()); - assert!(!query.is_module_browsing()); - assert!(!query.is_crate_search()); - - // Path query should be neither - let query = Query::new("foo::bar".to_owned()); - assert!(!query.is_module_browsing()); - assert!(!query.is_crate_search()); - } - #[test] fn test_path_search() { let (mut db, _) = RootDatabase::with_many_files( diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt index 5783d97564d0..71680699b739 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt @@ -27,11 +27,13 @@ kind: STRUCT, range: 83..119, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 109..118, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 109..118, + }, + ), ), }, container_name: None, @@ -62,11 +64,13 @@ kind: STRUCT, range: 0..81, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 74..80, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 74..80, + }, + ), ), }, container_name: None, @@ -97,11 +101,13 @@ kind: STRUCT, range: 0..81, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 74..80, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 74..80, + }, + ), ), }, container_name: None, @@ -132,11 +138,13 @@ kind: STRUCT, range: 0..81, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 74..80, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 74..80, + }, + ), ), }, container_name: None, @@ -146,6 +154,34 @@ do_not_complete: Yes, _marker: PhantomData<&()>, }, + FileSymbol { + name: "ra_test_fixture", + def: Module( + Module { + id: ModuleIdLt { + [salsa id]: Id(3800), + }, + }, + ), + loc: DeclarationLocation { + hir_file_id: FileId( + EditionedFileId( + Id(3000), + ), + ), + ptr: SyntaxNodePtr { + kind: SOURCE_FILE, + range: 0..128, + }, + name_ptr: None, + }, + container_name: None, + is_alias: false, + is_assoc: false, + is_import: false, + do_not_complete: Yes, + _marker: PhantomData<&()>, + }, FileSymbol { name: "s1", def: Adt( @@ -167,11 +203,13 @@ kind: STRUCT, range: 0..81, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 74..80, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 74..80, + }, + ), ), }, container_name: None, @@ -202,11 +240,13 @@ kind: STRUCT, range: 83..119, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 109..118, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 109..118, + }, + ), ), }, container_name: None, @@ -237,11 +277,13 @@ kind: STRUCT, range: 0..81, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 74..80, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 74..80, + }, + ), ), }, container_name: None, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 7692a7d61abf..2d62a56fe22d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -25,11 +25,13 @@ kind: VARIANT, range: 201..202, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 201..202, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 201..202, + }, + ), ), }, container_name: Some( @@ -60,11 +62,13 @@ kind: TYPE_ALIAS, range: 470..490, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 475..480, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 475..480, + }, + ), ), }, container_name: None, @@ -93,11 +97,13 @@ kind: VARIANT, range: 204..205, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 204..205, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 204..205, + }, + ), ), }, container_name: Some( @@ -128,11 +134,13 @@ kind: CONST, range: 413..434, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 419..424, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 419..424, + }, + ), ), }, container_name: None, @@ -161,11 +169,13 @@ kind: CONST, range: 593..665, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 599..615, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 599..615, + }, + ), ), }, container_name: None, @@ -196,11 +206,13 @@ kind: ENUM, range: 185..207, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 190..194, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 190..194, + }, + ), ), }, container_name: None, @@ -231,11 +243,13 @@ kind: USE_TREE, range: 727..749, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 736..749, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 736..749, + }, + ), ), }, container_name: None, @@ -266,11 +280,13 @@ kind: MACRO_DEF, range: 153..168, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 159..164, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 159..164, + }, + ), ), }, container_name: None, @@ -299,11 +315,13 @@ kind: STATIC, range: 435..469, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 442..448, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 442..448, + }, + ), ), }, container_name: None, @@ -334,11 +352,13 @@ kind: STRUCT, range: 170..184, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 177..183, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 177..183, + }, + ), ), }, container_name: None, @@ -369,11 +389,13 @@ kind: STRUCT, range: 0..22, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 6..21, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 6..21, + }, + ), ), }, container_name: None, @@ -404,11 +426,13 @@ kind: STRUCT, range: 391..409, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 398..408, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 398..408, + }, + ), ), }, container_name: Some( @@ -441,11 +465,13 @@ kind: STRUCT, range: 628..654, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 635..653, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 635..653, + }, + ), ), }, container_name: Some( @@ -478,11 +504,13 @@ kind: STRUCT, range: 552..580, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 559..579, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 559..579, + }, + ), ), }, container_name: None, @@ -513,11 +541,13 @@ kind: STRUCT, range: 261..279, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 268..275, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 268..275, + }, + ), ), }, container_name: None, @@ -546,11 +576,13 @@ kind: TRAIT, range: 334..373, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 340..345, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 340..345, + }, + ), ), }, container_name: None, @@ -581,11 +613,13 @@ kind: USE_TREE, range: 755..769, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 764..769, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 764..769, + }, + ), ), }, container_name: None, @@ -616,11 +650,13 @@ kind: UNION, range: 208..222, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 214..219, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 214..219, + }, + ), ), }, container_name: None, @@ -649,11 +685,13 @@ kind: MODULE, range: 492..530, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 496..501, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 496..501, + }, + ), ), }, container_name: None, @@ -682,11 +720,13 @@ kind: MODULE, range: 667..677, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 671..676, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 671..676, + }, + ), ), }, container_name: None, @@ -717,11 +757,13 @@ kind: MACRO_RULES, range: 51..131, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 64..77, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 64..77, + }, + ), ), }, container_name: None, @@ -750,11 +792,13 @@ kind: FN, range: 307..330, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 310..325, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 310..325, + }, + ), ), }, container_name: Some( @@ -785,11 +829,13 @@ kind: FN, range: 242..257, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 245..252, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 245..252, + }, + ), ), }, container_name: Some( @@ -822,11 +868,13 @@ kind: MACRO_RULES, range: 1..48, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 14..31, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 14..31, + }, + ), ), }, container_name: None, @@ -855,11 +903,13 @@ kind: FN, range: 375..411, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 378..382, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 378..382, + }, + ), ), }, container_name: None, @@ -869,6 +919,34 @@ do_not_complete: Yes, _marker: PhantomData<&()>, }, + FileSymbol { + name: "ra_test_fixture", + def: Module( + Module { + id: ModuleIdLt { + [salsa id]: Id(3800), + }, + }, + ), + loc: DeclarationLocation { + hir_file_id: FileId( + EditionedFileId( + Id(3000), + ), + ), + ptr: SyntaxNodePtr { + kind: SOURCE_FILE, + range: 0..793, + }, + name_ptr: None, + }, + container_name: None, + is_alias: false, + is_assoc: false, + is_import: false, + do_not_complete: Yes, + _marker: PhantomData<&()>, + }, FileSymbol { name: "really_define_struct", def: Macro( @@ -890,11 +968,13 @@ kind: USE_TREE, range: 684..721, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 701..721, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 701..721, + }, + ), ), }, container_name: None, @@ -923,11 +1003,13 @@ kind: FN, range: 352..371, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 355..363, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 355..363, + }, + ), ), }, container_name: Some( @@ -969,11 +1051,13 @@ kind: STRUCT, range: 508..528, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 515..527, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 515..527, + }, + ), ), }, container_name: None, @@ -1011,11 +1095,13 @@ kind: USE_TREE, range: 141..173, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 157..173, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 157..173, + }, + ), ), }, container_name: None, @@ -1046,11 +1132,13 @@ kind: USE_TREE, range: 141..173, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 157..173, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 157..173, + }, + ), ), }, container_name: None, @@ -1081,11 +1169,13 @@ kind: STRUCT, range: 0..20, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 7..19, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 7..19, + }, + ), ), }, container_name: None, @@ -1116,11 +1206,13 @@ kind: USE_TREE, range: 35..69, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 51..69, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 51..69, + }, + ), ), }, container_name: None, @@ -1151,11 +1243,13 @@ kind: USE_TREE, range: 85..125, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 115..125, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 115..125, + }, + ), ), }, container_name: None, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt index 6f5f8f889c7d..87f0c7d9a817 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt @@ -20,11 +20,13 @@ kind: STRUCT, range: 0..15, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 11..14, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 11..14, + }, + ), ), }, container_name: None, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt index 5d3fe4d2658d..e96aa889ba06 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt @@ -20,11 +20,13 @@ kind: STRUCT, range: 0..15, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME, - range: 11..14, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 11..14, + }, + ), ), }, container_name: None, @@ -55,11 +57,13 @@ kind: USE_TREE, range: 17..25, }, - name_ptr: AstPtr( - SyntaxNodePtr { - kind: NAME_REF, - range: 22..25, - }, + name_ptr: Some( + AstPtr( + SyntaxNodePtr { + kind: NAME_REF, + range: 22..25, + }, + ), ), }, container_name: None, diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index a271cac6fcd0..047df309eca6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -19,7 +19,7 @@ use ide_db::{ }; use stdx::never; use syntax::{ - AstNode, SyntaxNode, TextRange, + AstNode, AstPtr, SyntaxNode, TextRange, ast::{self, HasName}, }; @@ -253,7 +253,7 @@ impl<'db> TryToNav for FileSymbol<'db> { db, self.loc.hir_file_id, self.loc.ptr.text_range(), - Some(self.loc.name_ptr.text_range()), + self.loc.name_ptr.map(AstPtr::text_range), ) .map(|(FileRange { file_id, range: full_range }, focus_range)| { NavigationTarget { diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs index 8f6627a60fe6..fe01fb1f1063 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs @@ -414,8 +414,9 @@ fn match_loop_inner<'t>( } // Check if we need a separator. - if item.sep.is_some() && !item.sep_matched { - let sep = item.sep.as_ref().unwrap(); + if let Some(sep) = &item.sep + && !item.sep_matched + { let mut fork = src.clone(); if expect_separator(&mut fork, sep) { // HACK: here we use `meta_result` to pass `TtIter` back to caller because diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index eb1b8c5dd0e6..9f3c6742d651 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -1447,7 +1447,27 @@ foo = { path = "../foo" } .server() .wait_until_workspace_is_loaded(); - server.request::(Default::default(), json!([])); + server.request::( + Default::default(), + json!([ + { + "name": "bar", + "kind": 2, + "location": { + "uri": "file:///[..]bar/src/lib.rs", + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + } + } + }]), + ); let server = Project::with_fixture( r#" @@ -1486,7 +1506,27 @@ version = "0.0.0" .server() .wait_until_workspace_is_loaded(); - server.request::(Default::default(), json!([])); + server.request::( + Default::default(), + json!([ + { + "name": "baz", + "kind": 2, + "location": { + "uri": "file:///[..]baz/src/lib.rs", + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + } + } + }]), + ); } #[test] diff --git a/src/tools/rust-analyzer/crates/syntax/src/ptr.rs b/src/tools/rust-analyzer/crates/syntax/src/ptr.rs index 34c07598d200..c4979b8e3ae8 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ptr.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ptr.rs @@ -68,7 +68,7 @@ impl AstPtr { self.raw } - pub fn text_range(&self) -> TextRange { + pub fn text_range(self) -> TextRange { self.raw.text_range() } From 539e85500854f987f4b1b9003042b20b54e81a89 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 10 Jan 2026 21:18:01 +1100 Subject: [PATCH 1911/3801] Use a hook to decouple `rustc_mir_transform` from `rustc_mir_build` --- Cargo.lock | 1 - compiler/rustc_middle/src/hooks/mod.rs | 5 +++++ compiler/rustc_mir_build/src/builder/mod.rs | 8 +++++--- compiler/rustc_mir_build/src/lib.rs | 3 ++- compiler/rustc_mir_transform/Cargo.toml | 1 - compiler/rustc_mir_transform/src/lib.rs | 6 ++++-- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c791babc399..bf28939ac87b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4360,7 +4360,6 @@ dependencies = [ "rustc_infer", "rustc_macros", "rustc_middle", - "rustc_mir_build", "rustc_mir_dataflow", "rustc_session", "rustc_span", diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index dc6a3334a4c8..c926604a4195 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -102,6 +102,11 @@ declare_hooks! { /// Ensure the given scalar is valid for the given type. /// This checks non-recursive runtime validity. hook validate_scalar_in_layout(scalar: crate::ty::ScalarInt, ty: Ty<'tcx>) -> bool; + + /// **Do not call this directly; call the `mir_built` query instead.** + /// + /// Creates the MIR for a given `DefId`, including unreachable code. + hook build_mir_inner_impl(def: LocalDefId) -> mir::Body<'tcx>; } #[cold] diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 40f1fe0d5d11..75c6df842b50 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -64,9 +64,11 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( .collect() } -/// Create the MIR for a given `DefId`, including unreachable code. Do not call -/// this directly; instead use the cached version via `mir_built`. -pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> { +/// Create the MIR for a given `DefId`, including unreachable code. +/// +/// This is the implementation of hook `build_mir_inner_impl`, which should only +/// be called by the query `mir_built`. +pub(crate) fn build_mir_inner_impl<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> { tcx.ensure_done().thir_abstract_const(def); if let Err(e) = tcx.ensure_ok().check_match(def) { return construct_error(tcx, def, e); diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 8c7003b77876..410ea791ac5c 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -12,7 +12,7 @@ // The `builder` module used to be named `build`, but that was causing GitHub's // "Go to file" feature to silently ignore all files in the module, probably // because it assumes that "build" is a build-output directory. See #134365. -pub mod builder; +mod builder; mod check_tail_calls; mod check_unsafety; mod errors; @@ -30,4 +30,5 @@ pub fn provide(providers: &mut Providers) { providers.check_unsafety = check_unsafety::check_unsafety; providers.check_tail_calls = check_tail_calls::check_tail_calls; providers.thir_body = thir::cx::thir_body; + providers.hooks.build_mir_inner_impl = builder::build_mir_inner_impl; } diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index 511c1960e40b..6df7a869ca28 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -20,7 +20,6 @@ rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } -rustc_mir_build = { path = "../rustc_mir_build" } rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 701d7ff854a7..c78b0adaf6f1 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -30,7 +30,6 @@ use rustc_middle::mir::{ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_middle::util::Providers; use rustc_middle::{bug, query, span_bug}; -use rustc_mir_build::builder::build_mir; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, sym}; use tracing::debug; @@ -378,8 +377,11 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { validator.qualifs_in_return_place() } +/// Implementation of the `mir_built` query. fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal> { - let mut body = build_mir(tcx, def); + // Delegate to the main MIR building code in the `rustc_mir_build` crate. + // This is the one place that is allowed to call `build_mir_inner_impl`. + let mut body = tcx.build_mir_inner_impl(def); // Identifying trivial consts based on their mir_built is easy, but a little wasteful. // Trying to push this logic earlier in the compiler and never even produce the Body would From 00ad6714064e0003d04731933be62636a19c9400 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 10 Jan 2026 13:00:07 +0100 Subject: [PATCH 1912/3801] Subscribe myself to attr parsing --- triagebot.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 59c5e5f24330..3007ec765e00 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1358,11 +1358,11 @@ message = "The rustc-dev-guide subtree was changed. If this PR *only* touches th cc = ["@BoxyUwU", "@jieyouxu", "@kobzol", "@tshepang"] [mentions."compiler/rustc_passes/src/check_attr.rs"] -cc = ["@jdonszelmann"] +cc = ["@jdonszelmann", "@JonathanBrouwer"] [mentions."compiler/rustc_attr_parsing"] -cc = ["@jdonszelmann"] +cc = ["@jdonszelmann", "@JonathanBrouwer"] [mentions."compiler/rustc_hir/src/attrs"] -cc = ["@jdonszelmann"] +cc = ["@jdonszelmann", "@JonathanBrouwer"] [mentions."src/tools/enzyme"] cc = ["@ZuseZ4"] From 1caf7b222859c6de1b6fce064e32d3fdc50048c5 Mon Sep 17 00:00:00 2001 From: Lofty Inclination Date: Sat, 10 Jan 2026 12:54:50 +0000 Subject: [PATCH 1913/3801] Add miri specific shims for managing threads in no_std projects --- src/tools/miri/src/shims/foreign_items.rs | 36 ++++++++++++++++++- src/tools/miri/src/shims/sig.rs | 1 + .../concurrency/miri_thread_join_spawned.rs | 28 +++++++++++++++ src/tools/miri/tests/pass/miri-alloc.rs | 10 +++--- src/tools/miri/tests/utils/miri_extern.rs | 13 +++++++ 5 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 src/tools/miri/tests/pass/concurrency/miri_thread_join_spawned.rs diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 571f5efc9739..4c25caf56446 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -2,7 +2,7 @@ use std::collections::hash_map::Entry; use std::io::Write; use std::path::Path; -use rustc_abi::{Align, CanonAbi, Size}; +use rustc_abi::{Align, CanonAbi, ExternAbi, Size}; use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_data_structures::either::Either; use rustc_hir::attrs::Linkage; @@ -435,6 +435,40 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Return value: 0 on success, otherwise the size it would have needed. this.write_int(if success { 0 } else { needed_size }, dest)?; } + "miri_thread_spawn" => { + // FIXME: `check_shim_sig` does not work with function pointers. + let [start_routine, func_arg] = + this.check_shim_sig_lenient(abi, CanonAbi::Rust, link_name, args)?; + let start_routine = this.read_pointer(start_routine)?; + let func_arg = this.read_immediate(func_arg)?; + + this.start_regular_thread( + Some(dest.clone()), + start_routine, + ExternAbi::Rust, + func_arg, + this.machine.layouts.unit, + )?; + } + "miri_thread_join" => { + let [thread_id] = this.check_shim_sig( + shim_sig!(extern "Rust" fn(usize) -> bool), + link_name, + abi, + args, + )?; + + let thread = this.read_target_usize(thread_id)?; + if let Ok(thread) = this.thread_id_try_from(thread) { + this.join_thread_exclusive( + thread, + /* success_retval */ Scalar::from_bool(true), + dest, + )?; + } else { + this.write_scalar(Scalar::from_bool(false), dest)?; + } + } // Hint that a loop is spinning indefinitely. "miri_spin_loop" => { let [] = this.check_shim_sig_lenient(abi, CanonAbi::Rust, link_name, args)?; diff --git a/src/tools/miri/src/shims/sig.rs b/src/tools/miri/src/shims/sig.rs index e88cc66b6ea5..4e4b1bc2b9fe 100644 --- a/src/tools/miri/src/shims/sig.rs +++ b/src/tools/miri/src/shims/sig.rs @@ -57,6 +57,7 @@ macro_rules! shim_sig_arg { "u128" => $this.tcx.types.u128, "usize" => $this.tcx.types.usize, "()" => $this.tcx.types.unit, + "bool" => $this.tcx.types.bool, "*const _" => $this.machine.layouts.const_raw_ptr.ty, "*mut _" => $this.machine.layouts.mut_raw_ptr.ty, ty if let Some(win_ty) = ty.strip_prefix("winapi::") => diff --git a/src/tools/miri/tests/pass/concurrency/miri_thread_join_spawned.rs b/src/tools/miri/tests/pass/concurrency/miri_thread_join_spawned.rs new file mode 100644 index 000000000000..5b78068b6853 --- /dev/null +++ b/src/tools/miri/tests/pass/concurrency/miri_thread_join_spawned.rs @@ -0,0 +1,28 @@ +#![no_std] +#![no_main] +//@compile-flags: -Cpanic=abort +//@ignore-target: windows # no-std not supported on Windows + +#[path = "../../utils/mod.no_std.rs"] +mod utils; + +extern "Rust" fn thread_start(_null: *mut ()) { + unsafe { + utils::miri_spin_loop(); + utils::miri_spin_loop(); + } +} + +#[no_mangle] +fn miri_start(_argc: isize, _argv: *const *const u8) -> isize { + unsafe { + let thread_id = utils::miri_thread_spawn(thread_start, core::ptr::null_mut()); + assert_eq!(utils::miri_thread_join(thread_id), true); + } + 0 +} + +#[panic_handler] +fn panic_handler(_: &core::panic::PanicInfo) -> ! { + loop {} +} diff --git a/src/tools/miri/tests/pass/miri-alloc.rs b/src/tools/miri/tests/pass/miri-alloc.rs index 20269d8ced03..7469e29a8c96 100644 --- a/src/tools/miri/tests/pass/miri-alloc.rs +++ b/src/tools/miri/tests/pass/miri-alloc.rs @@ -6,17 +6,15 @@ // windows linker section, we can run this test on windows again. //@ignore-target: windows # no-std not supported on Windows -extern "Rust" { - fn miri_alloc(size: usize, align: usize) -> *mut u8; - fn miri_dealloc(ptr: *mut u8, size: usize, align: usize); -} +#[path = "../utils/mod.no_std.rs"] +mod utils; #[no_mangle] fn miri_start(_argc: isize, _argv: *const *const u8) -> isize { unsafe { - let ptr = miri_alloc(123, 1); + let ptr = utils::miri_alloc(123, 1); core::ptr::write_bytes(ptr, 0u8, 123); - miri_dealloc(ptr, 123, 1); + utils::miri_dealloc(ptr, 123, 1); } 0 } diff --git a/src/tools/miri/tests/utils/miri_extern.rs b/src/tools/miri/tests/utils/miri_extern.rs index bd01866dc34c..e9cde20412f4 100644 --- a/src/tools/miri/tests/utils/miri_extern.rs +++ b/src/tools/miri/tests/utils/miri_extern.rs @@ -156,6 +156,19 @@ extern "Rust" { /// Blocks the current execution if the argument is false pub fn miri_genmc_assume(condition: bool); + /// Miri-provided extern function to spawn a new thread in the interpreter. + /// + /// Returns the thread id. + /// + /// This is useful when no fundamental way of spawning threads is available, e.g. when using + /// `no_std`. + pub fn miri_thread_spawn(t: extern "Rust" fn(*mut ()), data: *mut ()) -> usize; + + /// Miri-provided extern function to join a thread that was spawned by Miri. + pub fn miri_thread_join(thread_id: usize) -> bool; + /// Indicate to Miri that this thread is busy-waiting in a spin loop. + /// + /// As far as Miri is concerned, this is equivalent to `yield_now`. pub fn miri_spin_loop(); } From 9eb4d7c56ebf768576183e5c5fd3e8159520dd22 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Sat, 10 Jan 2026 13:58:47 +0100 Subject: [PATCH 1914/3801] remove `no-rustfix` the suggestions are no longer overlapping?.. --- tests/ui/suspicious_to_owned.1.fixed | 73 ++++++++++++++++++++++++++++ tests/ui/suspicious_to_owned.2.fixed | 73 ++++++++++++++++++++++++++++ tests/ui/suspicious_to_owned.rs | 1 - tests/ui/suspicious_to_owned.stderr | 12 ++--- 4 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 tests/ui/suspicious_to_owned.1.fixed create mode 100644 tests/ui/suspicious_to_owned.2.fixed diff --git a/tests/ui/suspicious_to_owned.1.fixed b/tests/ui/suspicious_to_owned.1.fixed new file mode 100644 index 000000000000..6fd536a38ed1 --- /dev/null +++ b/tests/ui/suspicious_to_owned.1.fixed @@ -0,0 +1,73 @@ +#![warn(clippy::suspicious_to_owned)] +#![warn(clippy::implicit_clone)] +#![allow(clippy::redundant_clone)] +use std::borrow::Cow; +use std::ffi::{CStr, c_char}; + +fn main() { + let moo = "Moooo"; + let c_moo = b"Moooo\0"; + let c_moo_ptr = c_moo.as_ptr() as *const c_char; + let moos = ['M', 'o', 'o']; + let moos_vec = moos.to_vec(); + + // we expect this to be linted + let cow = Cow::Borrowed(moo); + let _ = cow.into_owned(); + //~^ suspicious_to_owned + + // we expect no lints for this + let cow = Cow::Borrowed(moo); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(moo); + let _ = cow.clone(); + + // we expect this to be linted + let cow = Cow::Borrowed(&moos); + let _ = cow.into_owned(); + //~^ suspicious_to_owned + + // we expect no lints for this + let cow = Cow::Borrowed(&moos); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(&moos); + let _ = cow.clone(); + + // we expect this to be linted + let cow = Cow::Borrowed(&moos_vec); + let _ = cow.into_owned(); + //~^ suspicious_to_owned + + // we expect no lints for this + let cow = Cow::Borrowed(&moos_vec); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(&moos_vec); + let _ = cow.clone(); + + // we expect this to be linted + let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); + let _ = cow.into_owned(); + //~^ suspicious_to_owned + + // we expect no lints for this + let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); + let _ = cow.clone(); + + // we expect no lints for these + let _ = moo.to_owned(); + let _ = c_moo.to_owned(); + let _ = moos.to_owned(); + + // we expect implicit_clone lints for these + let _ = String::from(moo).clone(); + //~^ implicit_clone + + let _ = moos_vec.clone(); + //~^ implicit_clone +} diff --git a/tests/ui/suspicious_to_owned.2.fixed b/tests/ui/suspicious_to_owned.2.fixed new file mode 100644 index 000000000000..841adf8ea274 --- /dev/null +++ b/tests/ui/suspicious_to_owned.2.fixed @@ -0,0 +1,73 @@ +#![warn(clippy::suspicious_to_owned)] +#![warn(clippy::implicit_clone)] +#![allow(clippy::redundant_clone)] +use std::borrow::Cow; +use std::ffi::{CStr, c_char}; + +fn main() { + let moo = "Moooo"; + let c_moo = b"Moooo\0"; + let c_moo_ptr = c_moo.as_ptr() as *const c_char; + let moos = ['M', 'o', 'o']; + let moos_vec = moos.to_vec(); + + // we expect this to be linted + let cow = Cow::Borrowed(moo); + let _ = cow.clone(); + //~^ suspicious_to_owned + + // we expect no lints for this + let cow = Cow::Borrowed(moo); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(moo); + let _ = cow.clone(); + + // we expect this to be linted + let cow = Cow::Borrowed(&moos); + let _ = cow.clone(); + //~^ suspicious_to_owned + + // we expect no lints for this + let cow = Cow::Borrowed(&moos); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(&moos); + let _ = cow.clone(); + + // we expect this to be linted + let cow = Cow::Borrowed(&moos_vec); + let _ = cow.clone(); + //~^ suspicious_to_owned + + // we expect no lints for this + let cow = Cow::Borrowed(&moos_vec); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = Cow::Borrowed(&moos_vec); + let _ = cow.clone(); + + // we expect this to be linted + let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); + let _ = cow.clone(); + //~^ suspicious_to_owned + + // we expect no lints for this + let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); + let _ = cow.into_owned(); + // we expect no lints for this + let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy(); + let _ = cow.clone(); + + // we expect no lints for these + let _ = moo.to_owned(); + let _ = c_moo.to_owned(); + let _ = moos.to_owned(); + + // we expect implicit_clone lints for these + let _ = String::from(moo).clone(); + //~^ implicit_clone + + let _ = moos_vec.clone(); + //~^ implicit_clone +} diff --git a/tests/ui/suspicious_to_owned.rs b/tests/ui/suspicious_to_owned.rs index 2eec05ccaf4c..f59b3fd6ed0c 100644 --- a/tests/ui/suspicious_to_owned.rs +++ b/tests/ui/suspicious_to_owned.rs @@ -1,4 +1,3 @@ -//@no-rustfix: overlapping suggestions #![warn(clippy::suspicious_to_owned)] #![warn(clippy::implicit_clone)] #![allow(clippy::redundant_clone)] diff --git a/tests/ui/suspicious_to_owned.stderr b/tests/ui/suspicious_to_owned.stderr index f90bea5fb8ff..1e631d4d4a14 100644 --- a/tests/ui/suspicious_to_owned.stderr +++ b/tests/ui/suspicious_to_owned.stderr @@ -1,5 +1,5 @@ error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned - --> tests/ui/suspicious_to_owned.rs:17:13 + --> tests/ui/suspicious_to_owned.rs:16:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL + let _ = cow.clone(); | error: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cause the Cow<'_, [char; 3]> contents to become owned - --> tests/ui/suspicious_to_owned.rs:29:13 + --> tests/ui/suspicious_to_owned.rs:28:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL + let _ = cow.clone(); | error: this `to_owned` call clones the Cow<'_, Vec> itself and does not cause the Cow<'_, Vec> contents to become owned - --> tests/ui/suspicious_to_owned.rs:41:13 + --> tests/ui/suspicious_to_owned.rs:40:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + let _ = cow.clone(); | error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned - --> tests/ui/suspicious_to_owned.rs:53:13 + --> tests/ui/suspicious_to_owned.rs:52:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL + let _ = cow.clone(); | error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type - --> tests/ui/suspicious_to_owned.rs:69:13 + --> tests/ui/suspicious_to_owned.rs:68:13 | LL | let _ = String::from(moo).to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::from(moo).clone()` @@ -74,7 +74,7 @@ LL | let _ = String::from(moo).to_owned(); = help: to override `-D warnings` add `#[allow(clippy::implicit_clone)]` error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type - --> tests/ui/suspicious_to_owned.rs:72:13 + --> tests/ui/suspicious_to_owned.rs:71:13 | LL | let _ = moos_vec.to_owned(); | ^^^^^^^^^^^^^^^^^^^ help: consider using: `moos_vec.clone()` From f228056c644969488958f01cb88a89f0a93f642d Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Sat, 10 Jan 2026 13:51:44 +0100 Subject: [PATCH 1915/3801] improve lint messages - only mention the type once - put types in backticks - only highlight the method name in the suggestion - removes the need for a snippet - makes for finer diffs (seen through `cargo dev lint`) --- clippy_lints/src/methods/mod.rs | 2 +- .../src/methods/suspicious_to_owned.rs | 23 +++++++----------- tests/ui/suspicious_to_owned.stderr | 24 +++++++++---------- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 248a147cfd77..d483496549fd 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -5576,7 +5576,7 @@ impl Methods { unnecessary_fallible_conversions::check_method(cx, expr); }, (sym::to_owned, []) => { - if !suspicious_to_owned::check(cx, expr, recv) { + if !suspicious_to_owned::check(cx, expr, span) { implicit_clone::check(cx, name, expr, recv); } }, diff --git a/clippy_lints/src/methods/suspicious_to_owned.rs b/clippy_lints/src/methods/suspicious_to_owned.rs index bcd1f11931fc..e9a5104eb3b4 100644 --- a/clippy_lints/src/methods/suspicious_to_owned.rs +++ b/clippy_lints/src/methods/suspicious_to_owned.rs @@ -1,15 +1,14 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeDef; -use clippy_utils::source::snippet_with_context; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_middle::ty::print::with_forced_trimmed_paths; -use rustc_span::sym; +use rustc_span::{Span, sym}; use super::SUSPICIOUS_TO_OWNED; -pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) -> bool { +pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_span: Span) -> bool { if cx .typeck_results() .type_dependent_def_id(expr.hir_id) @@ -18,28 +17,22 @@ pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) - && let input_type = cx.typeck_results().expr_ty(expr) && input_type.is_diag_item(cx, sym::Cow) { - let mut app = Applicability::MaybeIncorrect; - let recv_snip = snippet_with_context(cx, recv.span, expr.span.ctxt(), "..", &mut app).0; + let app = Applicability::MaybeIncorrect; span_lint_and_then( cx, SUSPICIOUS_TO_OWNED, expr.span, with_forced_trimmed_paths!(format!( - "this `to_owned` call clones the {input_type} itself and does not cause the {input_type} contents to become owned" + "this `to_owned` call clones the `{input_type}` itself and does not cause its contents to become owned" )), |diag| { diag.span_suggestion( - expr.span, - "depending on intent, either make the Cow an Owned variant", - format!("{recv_snip}.into_owned()"), - app, - ); - diag.span_suggestion( - expr.span, - "or clone the Cow itself", - format!("{recv_snip}.clone()"), + method_span, + "depending on intent, either make the `Cow` an `Owned` variant", + "into_owned".to_string(), app, ); + diag.span_suggestion(method_span, "or clone the `Cow` itself", "clone".to_string(), app); }, ); return true; diff --git a/tests/ui/suspicious_to_owned.stderr b/tests/ui/suspicious_to_owned.stderr index 1e631d4d4a14..5fda1ed1cc9c 100644 --- a/tests/ui/suspicious_to_owned.stderr +++ b/tests/ui/suspicious_to_owned.stderr @@ -1,4 +1,4 @@ -error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned +error: this `to_owned` call clones the `Cow<'_, str>` itself and does not cause its contents to become owned --> tests/ui/suspicious_to_owned.rs:16:13 | LL | let _ = cow.to_owned(); @@ -6,59 +6,59 @@ LL | let _ = cow.to_owned(); | = note: `-D clippy::suspicious-to-owned` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::suspicious_to_owned)]` -help: depending on intent, either make the Cow an Owned variant +help: depending on intent, either make the `Cow` an `Owned` variant | LL | let _ = cow.into_owned(); | ++ -help: or clone the Cow itself +help: or clone the `Cow` itself | LL - let _ = cow.to_owned(); LL + let _ = cow.clone(); | -error: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cause the Cow<'_, [char; 3]> contents to become owned +error: this `to_owned` call clones the `Cow<'_, [char; 3]>` itself and does not cause its contents to become owned --> tests/ui/suspicious_to_owned.rs:28:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ | -help: depending on intent, either make the Cow an Owned variant +help: depending on intent, either make the `Cow` an `Owned` variant | LL | let _ = cow.into_owned(); | ++ -help: or clone the Cow itself +help: or clone the `Cow` itself | LL - let _ = cow.to_owned(); LL + let _ = cow.clone(); | -error: this `to_owned` call clones the Cow<'_, Vec> itself and does not cause the Cow<'_, Vec> contents to become owned +error: this `to_owned` call clones the `Cow<'_, Vec>` itself and does not cause its contents to become owned --> tests/ui/suspicious_to_owned.rs:40:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ | -help: depending on intent, either make the Cow an Owned variant +help: depending on intent, either make the `Cow` an `Owned` variant | LL | let _ = cow.into_owned(); | ++ -help: or clone the Cow itself +help: or clone the `Cow` itself | LL - let _ = cow.to_owned(); LL + let _ = cow.clone(); | -error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned +error: this `to_owned` call clones the `Cow<'_, str>` itself and does not cause its contents to become owned --> tests/ui/suspicious_to_owned.rs:52:13 | LL | let _ = cow.to_owned(); | ^^^^^^^^^^^^^^ | -help: depending on intent, either make the Cow an Owned variant +help: depending on intent, either make the `Cow` an `Owned` variant | LL | let _ = cow.into_owned(); | ++ -help: or clone the Cow itself +help: or clone the `Cow` itself | LL - let _ = cow.to_owned(); LL + let _ = cow.clone(); From bd31b9d3bcd430a4236162d6b8e87661b8904964 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Jan 2026 14:22:48 +0100 Subject: [PATCH 1916/3801] use io::Result for read/write helpers, and add read_until_eof_into_slice --- .../tests/pass-dep/libc/libc-socketpair.rs | 11 ++--- src/tools/miri/tests/utils/libc.rs | 46 +++++++++---------- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs index 2031149aaf4f..20424fc86dc2 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs @@ -62,14 +62,11 @@ fn test_socketpair() { errno_check(unsafe { libc::close(fds[0]) }); // Reading the other end should return that data, then EOF. let mut buf: [u8; 5] = [0; 5]; - read_all_into_slice(fds[1], &mut buf[0..3]).unwrap(); - assert_eq!(&buf[0..3], data); - let res = read_into_slice(fds[1], &mut buf[3..5]).unwrap().0.len(); - assert_eq!(res, 0); // 0-sized read: EOF. + let (res, _) = read_until_eof_into_slice(fds[1], &mut buf).unwrap(); + assert_eq!(res, data); // Writing the other end should emit EPIPE. - let res = write_all_from_slice(fds[1], &mut buf); - assert_eq!(res, Err(-1)); - assert_eq!(std::io::Error::last_os_error().raw_os_error(), Some(libc::EPIPE)); + let err = write_all_from_slice(fds[1], &mut buf).unwrap_err(); + assert_eq!(err.raw_os_error(), Some(libc::EPIPE)); } fn test_socketpair_threaded() { diff --git a/src/tools/miri/tests/utils/libc.rs b/src/tools/miri/tests/utils/libc.rs index 0765bacb6bd8..4e9a94718c38 100644 --- a/src/tools/miri/tests/utils/libc.rs +++ b/src/tools/miri/tests/utils/libc.rs @@ -40,21 +40,17 @@ pub unsafe fn read_all( return read_so_far as libc::ssize_t; } -/// Try to fill the given slice by reading from `fd`. Error if that many bytes could not be read. +/// Try to fill the given slice by reading from `fd`. Panic if that many bytes could not be read. #[track_caller] -pub fn read_all_into_slice(fd: libc::c_int, buf: &mut [u8]) -> Result<(), libc::ssize_t> { - let res = unsafe { read_all(fd, buf.as_mut_ptr().cast(), buf.len()) }; - if res >= 0 { - assert_eq!(res as usize, buf.len()); - Ok(()) - } else { - Err(res) - } +pub fn read_all_into_slice(fd: libc::c_int, buf: &mut [u8]) -> io::Result<()> { + let res = errno_result(unsafe { read_all(fd, buf.as_mut_ptr().cast(), buf.len()) })?; + assert_eq!(res as usize, buf.len()); + Ok(()) } /// Read exactly `N` bytes from `fd`. Error if that many bytes could not be read. #[track_caller] -pub fn read_all_into_array(fd: libc::c_int) -> Result<[u8; N], libc::ssize_t> { +pub fn read_all_into_array(fd: libc::c_int) -> io::Result<[u8; N]> { let mut buf = [0; N]; read_all_into_slice(fd, &mut buf)?; Ok(buf) @@ -63,12 +59,20 @@ pub fn read_all_into_array(fd: libc::c_int) -> Result<[u8; N], l /// Do a single read from `fd` and return the part of the buffer that was written into, /// and the rest. #[track_caller] -pub fn read_into_slice( +pub fn read_into_slice(fd: libc::c_int, buf: &mut [u8]) -> io::Result<(&mut [u8], &mut [u8])> { + let res = errno_result(unsafe { libc::read(fd, buf.as_mut_ptr().cast(), buf.len()) })?; + Ok(buf.split_at_mut(res as usize)) +} + +/// Read from `fd` until we get EOF and return the part of the buffer that was written into, +/// and the rest. +#[track_caller] +pub fn read_until_eof_into_slice( fd: libc::c_int, buf: &mut [u8], -) -> Result<(&mut [u8], &mut [u8]), libc::ssize_t> { - let res = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), buf.len()) }; - if res >= 0 { Ok(buf.split_at_mut(res as usize)) } else { Err(res) } +) -> io::Result<(&mut [u8], &mut [u8])> { + let res = errno_result(unsafe { read_all(fd, buf.as_mut_ptr().cast(), buf.len()) })?; + Ok(buf.split_at_mut(res as usize)) } pub unsafe fn write_all( @@ -89,16 +93,12 @@ pub unsafe fn write_all( return written_so_far as libc::ssize_t; } -/// Write the entire `buf` to `fd`. Error if not all bytes could be written. +/// Write the entire `buf` to `fd`. Panic if not all bytes could be written. #[track_caller] -pub fn write_all_from_slice(fd: libc::c_int, buf: &[u8]) -> Result<(), libc::ssize_t> { - let res = unsafe { write_all(fd, buf.as_ptr().cast(), buf.len()) }; - if res >= 0 { - assert_eq!(res as usize, buf.len()); - Ok(()) - } else { - Err(res) - } +pub fn write_all_from_slice(fd: libc::c_int, buf: &[u8]) -> io::Result<()> { + let res = errno_result(unsafe { write_all(fd, buf.as_ptr().cast(), buf.len()) })?; + assert_eq!(res as usize, buf.len()); + Ok(()) } #[cfg(any(target_os = "linux", target_os = "android", target_os = "illumos"))] From da0dda15036e486778afee422ab8603cc6d1334e Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 10 Jan 2026 14:21:46 +0100 Subject: [PATCH 1917/3801] Remove special case for `AllowedTargets::CrateLevel` --- .../src/attributes/crate_level.rs | 18 ++++++------ compiler/rustc_attr_parsing/src/context.rs | 14 ++-------- .../rustc_attr_parsing/src/target_checking.rs | 28 ++++++------------- 3 files changed, 19 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 01c503357fc7..5604fbd25edc 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -9,7 +9,7 @@ impl SingleAttributeParser for CrateNameParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(n) = args else { @@ -33,7 +33,7 @@ impl SingleAttributeParser for RecursionLimitParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(nv) = args else { @@ -56,7 +56,7 @@ impl SingleAttributeParser for MoveSizeLimitParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(nv) = args else { @@ -79,7 +79,7 @@ impl SingleAttributeParser for TypeLengthLimitParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(nv) = args else { @@ -102,7 +102,7 @@ impl SingleAttributeParser for PatternComplexityLimitParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let ArgParser::NameValue(nv) = args else { @@ -123,7 +123,7 @@ pub(crate) struct NoCoreParser; impl NoArgsAttributeParser for NoCoreParser { const PATH: &[Symbol] = &[sym::no_core]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore; } @@ -132,7 +132,7 @@ pub(crate) struct NoStdParser; impl NoArgsAttributeParser for NoStdParser { const PATH: &[Symbol] = &[sym::no_std]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd; } @@ -141,7 +141,7 @@ pub(crate) struct RustcCoherenceIsCoreParser; impl NoArgsAttributeParser for RustcCoherenceIsCoreParser { const PATH: &[Symbol] = &[sym::rustc_coherence_is_core]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoherenceIsCore; } @@ -151,7 +151,7 @@ impl SingleAttributeParser for WindowsSubsystemParser { const PATH: &[Symbol] = &[sym::windows_subsystem]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute"); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index b85bb6c6c89d..527e3f567cf3 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -4,12 +4,12 @@ use std::ops::{Deref, DerefMut}; use std::sync::LazyLock; use private::Sealed; -use rustc_ast::{AttrStyle, CRATE_NODE_ID, MetaItemLit, NodeId}; +use rustc_ast::{AttrStyle, MetaItemLit, NodeId}; use rustc_errors::{Diag, Diagnostic, Level}; use rustc_feature::{AttrSuggestionStyle, AttributeTemplate}; use rustc_hir::attrs::AttributeKind; use rustc_hir::lints::{AttributeLint, AttributeLintKind}; -use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId}; +use rustc_hir::{AttrPath, HirId}; use rustc_session::Session; use rustc_session::lint::{Lint, LintId}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; @@ -303,8 +303,6 @@ pub trait Stage: Sized + 'static + Sealed { ) -> ErrorGuaranteed; fn should_emit(&self) -> ShouldEmit; - - fn id_is_crate_root(id: Self::Id) -> bool; } // allow because it's a sealed trait @@ -326,10 +324,6 @@ impl Stage for Early { fn should_emit(&self) -> ShouldEmit { self.emit_errors } - - fn id_is_crate_root(id: Self::Id) -> bool { - id == CRATE_NODE_ID - } } // allow because it's a sealed trait @@ -351,10 +345,6 @@ impl Stage for Late { fn should_emit(&self) -> ShouldEmit { ShouldEmit::ErrorsAndLints } - - fn id_is_crate_root(id: Self::Id) -> bool { - id == CRATE_HIR_ID - } } /// used when parsing attributes for miscellaneous things *before* ast lowering diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index 88fa3e436292..52c2d10f4797 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -15,11 +15,6 @@ use crate::session_diagnostics::InvalidTarget; pub(crate) enum AllowedTargets { AllowList(&'static [Policy]), AllowListWarnRest(&'static [Policy]), - /// Special, and not the same as `AllowList(&[Allow(Target::Crate)])`. - /// For crate-level attributes we emit a specific set of lints to warn - /// people about accidentally not using them on the crate. - /// Only use this for attributes that are *exclusively* valid at the crate level. - CrateLevel, } pub(crate) enum AllowedResult { @@ -53,7 +48,6 @@ impl AllowedTargets { AllowedResult::Warn } } - AllowedTargets::CrateLevel => AllowedResult::Allowed, } } @@ -61,7 +55,6 @@ impl AllowedTargets { match self { AllowedTargets::AllowList(list) => list, AllowedTargets::AllowListWarnRest(list) => list, - AllowedTargets::CrateLevel => ALL_TARGETS, } .iter() .filter_map(|target| match target { @@ -95,7 +88,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { target: Target, cx: &mut AcceptContext<'_, 'sess, S>, ) { - Self::check_type(matches!(allowed_targets, AllowedTargets::CrateLevel), target, cx); + if allowed_targets.allowed_targets() == &[Target::Crate] { + Self::check_crate_level(target, cx); + return; + } match allowed_targets.is_allowed(target) { AllowedResult::Allowed => {} @@ -149,18 +145,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { } } - pub(crate) fn check_type( - crate_level: bool, - target: Target, - cx: &mut AcceptContext<'_, 'sess, S>, - ) { - let is_crate_root = S::id_is_crate_root(cx.target_id); - - if is_crate_root { - return; - } - - if !crate_level { + pub(crate) fn check_crate_level(target: Target, cx: &mut AcceptContext<'_, 'sess, S>) { + // For crate-level attributes we emit a specific set of lints to warn + // people about accidentally not using them on the crate. + if target == Target::Crate { return; } From 2b597f599e857a5718f16ca70c676447a5b4e68e Mon Sep 17 00:00:00 2001 From: Fabio Almeida Date: Sat, 10 Jan 2026 14:31:37 +0000 Subject: [PATCH 1918/3801] feat: invisible character help string --- compiler/rustc_parse/messages.ftl | 1 + compiler/rustc_parse/src/errors.rs | 6 ++++++ compiler/rustc_parse/src/lexer/mod.rs | 5 +++++ tests/ui/lexer/lex-invisible-characters.rs | 6 ++++++ tests/ui/lexer/lex-invisible-characters.stderr | 10 ++++++++++ 5 files changed, 28 insertions(+) create mode 100644 tests/ui/lexer/lex-invisible-characters.rs create mode 100644 tests/ui/lexer/lex-invisible-characters.stderr diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 747895c80469..1331d99c01ea 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -967,6 +967,7 @@ parse_unknown_start_of_token = unknown start of token: {$escaped} .sugg_quotes = Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '{$ascii_str}' ({$ascii_name}), but are not .sugg_other = Unicode character '{$ch}' ({$u_name}) looks like '{$ascii_str}' ({$ascii_name}), but it is not .help_null = source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used + .help_invisible_char = invisible characters like '{$escaped}' are not usually visible in text editors .note_repeats = character appears {$repeats -> [one] once more *[other] {$repeats} more times diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 3b72c9802afd..60e4a240c85e 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2369,6 +2369,8 @@ pub(crate) struct UnknownTokenStart { pub null: Option, #[subdiagnostic] pub repeat: Option, + #[subdiagnostic] + pub invisible: Option, } #[derive(Subdiagnostic)] @@ -2409,6 +2411,10 @@ pub(crate) struct UnknownTokenRepeat { pub repeats: usize, } +#[derive(Subdiagnostic)] +#[help(parse_help_invisible_char)] +pub(crate) struct InvisibleCharacter; + #[derive(Subdiagnostic)] #[help(parse_help_null)] pub(crate) struct UnknownTokenNull; diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 94ae35c19582..7c969dd7f9f4 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -36,6 +36,10 @@ use unescape_error_reporting::{emit_unescape_error, escaped_char}; #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(rustc_lexer::Token, 12); +const INVISIBLE_CHARACTERS: [char; 8] = [ + '\u{200b}', '\u{200c}', '\u{2060}', '\u{2061}', '\u{2062}', '\u{00ad}', '\u{034f}', '\u{061c}', +]; + #[derive(Clone, Debug)] pub(crate) struct UnmatchedDelim { pub found_delim: Option, @@ -456,6 +460,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { escaped: escaped_char(c), sugg, null: if c == '\x00' { Some(errors::UnknownTokenNull) } else { None }, + invisible: if INVISIBLE_CHARACTERS.contains(&c) { Some(errors::InvisibleCharacter) } else { None }, repeat: if repeats > 0 { swallow_next_invalid = repeats; Some(errors::UnknownTokenRepeat { repeats }) diff --git a/tests/ui/lexer/lex-invisible-characters.rs b/tests/ui/lexer/lex-invisible-characters.rs new file mode 100644 index 000000000000..2db72b8475dc --- /dev/null +++ b/tests/ui/lexer/lex-invisible-characters.rs @@ -0,0 +1,6 @@ +// Provide extra help when a user has an invisible character in their code + +fn main​() { + //~^ ERROR unknown start of token: \u{200b} + //~| HELP invisible characters like '\u{200b}' are not usually visible in text editors +} diff --git a/tests/ui/lexer/lex-invisible-characters.stderr b/tests/ui/lexer/lex-invisible-characters.stderr new file mode 100644 index 000000000000..ddac0f4e9325 --- /dev/null +++ b/tests/ui/lexer/lex-invisible-characters.stderr @@ -0,0 +1,10 @@ +error: unknown start of token: \u{200b} + --> $DIR/lex-invisible-characters.rs:3:8 + | +LL | fn main​() { + | ^ + | + = help: invisible characters like '\u{200b}' are not usually visible in text editors + +error: aborting due to 1 previous error + From 03ad5b07ee3aae10cfb9d70c9ff75ef3b9570e01 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Jan 2026 15:40:04 +0100 Subject: [PATCH 1919/3801] readme: clarify 'single-threaded interpreter' --- src/tools/miri/README.md | 3 ++- src/tools/miri/src/bin/miri.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index d5ef9c767414..925b85f58766 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -228,7 +228,8 @@ and macOS targets are usually on par. Windows is supported less well. ### Running tests in parallel -Though it implements Rust threading, Miri itself is a single-threaded interpreter. +Though it implements Rust threading, Miri itself is a single-threaded interpreter +(it works like a multi-threaded OS on a single-core CPU). This means that when running `cargo miri test`, you will probably see a dramatic increase in the amount of time it takes to run your whole test suite due to the inherent interpreter slowdown and a loss of parallelism. diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 19fbf90246c9..55c1fa203eb9 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -710,7 +710,7 @@ fn main() { if !miri_config.native_lib.is_empty() && miri_config.provenance_mode == ProvenanceMode::Strict { fatal_error!("strict provenance is not compatible with calling native functions"); } - // Native calls and many-seeds are an "intersting" combination. + // Native calls and many-seeds are an "interesting" combination. if !miri_config.native_lib.is_empty() && many_seeds.is_some() { eprintln!( "warning: `-Zmiri-many-seeds` runs multiple instances of the program in the same address space, \ From 4e18f1dad2be32a53a43840a39cab9457262d1c1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 10 Jan 2026 14:53:22 +0100 Subject: [PATCH 1920/3801] Abstract proc-macro-srv input and output away --- .../proc-macro-api/src/legacy_protocol.rs | 4 +- .../proc-macro-api/src/legacy_protocol/msg.rs | 4 +- .../crates/proc-macro-api/src/lib.rs | 41 +++++- .../crates/proc-macro-api/src/process.rs | 138 +++++++++++++----- .../crates/proc-macro-srv-cli/src/main.rs | 12 +- .../proc-macro-srv-cli/src/main_loop.rs | 72 +++++---- 6 files changed, 193 insertions(+), 78 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs index 22a7d9868e21..4524d1b66bfe 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs @@ -162,11 +162,11 @@ fn send_request( req: Request, buf: &mut P::Buf, ) -> Result, ServerError> { - req.write::<_, P>(&mut writer).map_err(|err| ServerError { + req.write::

    (&mut writer).map_err(|err| ServerError { message: "failed to write request".into(), io: Some(Arc::new(err)), })?; - let res = Response::read::<_, P>(&mut reader, buf).map_err(|err| ServerError { + let res = Response::read::

    (&mut reader, buf).map_err(|err| ServerError { message: "failed to read response".into(), io: Some(Arc::new(err)), })?; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs index 4146b619ec0c..1b6590693354 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs @@ -155,13 +155,13 @@ impl ExpnGlobals { } pub trait Message: serde::Serialize + DeserializeOwned { - fn read(inp: &mut R, buf: &mut C::Buf) -> io::Result> { + fn read(inp: &mut dyn BufRead, buf: &mut C::Buf) -> io::Result> { Ok(match C::read(inp, buf)? { None => None, Some(buf) => Some(C::decode(buf)?), }) } - fn write(self, out: &mut W) -> io::Result<()> { + fn write(self, out: &mut dyn Write) -> io::Result<()> { let value = C::encode(&self)?; C::write(out, &value) } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index f5fcc99f14a3..98ee6817c2d2 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -18,7 +18,7 @@ extern crate rustc_driver as _; pub mod bidirectional_protocol; pub mod legacy_protocol; -mod process; +pub mod process; pub mod transport; use paths::{AbsPath, AbsPathBuf}; @@ -44,6 +44,25 @@ pub mod version { pub const CURRENT_API_VERSION: u32 = HASHED_AST_ID; } +#[derive(Copy, Clone)] +pub enum ProtocolFormat { + JsonLegacy, + PostcardLegacy, + BidirectionalPostcardPrototype, +} + +impl fmt::Display for ProtocolFormat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ProtocolFormat::JsonLegacy => write!(f, "json-legacy"), + ProtocolFormat::PostcardLegacy => write!(f, "postcard-legacy"), + ProtocolFormat::BidirectionalPostcardPrototype => { + write!(f, "bidirectional-postcard-prototype") + } + } + } +} + /// Represents different kinds of procedural macros that can be expanded by the external server. #[derive(Copy, Clone, Eq, PartialEq, Debug, serde_derive::Serialize, serde_derive::Deserialize)] pub enum ProcMacroKind { @@ -132,7 +151,25 @@ impl ProcMacroClient { > + Clone, version: Option<&Version>, ) -> io::Result { - let process = ProcMacroServerProcess::run(process_path, env, version)?; + let process = ProcMacroServerProcess::spawn(process_path, env, version)?; + Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() }) + } + + /// Invokes `spawn` and returns a client connected to the resulting read and write handles. + /// + /// The `process_path` is used for `Self::server_path`. This function is mainly used for testing. + pub fn with_io_channels( + process_path: &AbsPath, + spawn: impl Fn( + Option, + ) -> io::Result<( + Box, + Box, + Box, + )>, + version: Option<&Version>, + ) -> io::Result { + let process = ProcMacroServerProcess::run(spawn, version, || "".to_owned())?; Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() }) } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index f6a656e3ce3a..4f8762158790 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -13,14 +13,13 @@ use span::Span; use stdx::JodChild; use crate::{ - Codec, ProcMacro, ProcMacroKind, ServerError, + Codec, ProcMacro, ProcMacroKind, ProtocolFormat, ServerError, bidirectional_protocol::{self, SubCallback, msg::BidirectionalMessage, reject_subrequests}, legacy_protocol::{self, SpanMode}, version, }; /// Represents a process handling proc-macro communication. -#[derive(Debug)] pub(crate) struct ProcMacroServerProcess { /// The state of the proc-macro server process, the protocol is currently strictly sequential /// hence the lock on the state. @@ -31,6 +30,16 @@ pub(crate) struct ProcMacroServerProcess { exited: OnceLock>, } +impl std::fmt::Debug for ProcMacroServerProcess { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ProcMacroServerProcess") + .field("version", &self.version) + .field("protocol", &self.protocol) + .field("exited", &self.exited) + .finish() + } +} + #[derive(Debug, Clone)] pub(crate) enum Protocol { LegacyJson { mode: SpanMode }, @@ -38,22 +47,83 @@ pub(crate) enum Protocol { BidirectionalPostcardPrototype { mode: SpanMode }, } +pub trait ProcessExit: Send + Sync { + fn exit_err(&mut self) -> Option; +} + +impl ProcessExit for Process { + fn exit_err(&mut self) -> Option { + match self.child.try_wait() { + Ok(None) | Err(_) => None, + Ok(Some(status)) => { + let mut msg = String::new(); + if !status.success() + && let Some(stderr) = self.child.stderr.as_mut() + { + _ = stderr.read_to_string(&mut msg); + } + Some(ServerError { + message: format!( + "proc-macro server exited with {status}{}{msg}", + if msg.is_empty() { "" } else { ": " } + ), + io: None, + }) + } + } + } +} + /// Maintains the state of the proc-macro server process. -#[derive(Debug)] struct ProcessSrvState { - process: Process, - stdin: ChildStdin, - stdout: BufReader, + process: Box, + stdin: Box, + stdout: Box, } impl ProcMacroServerProcess { /// Starts the proc-macro server and performs a version check - pub(crate) fn run<'a>( + pub(crate) fn spawn<'a>( process_path: &AbsPath, env: impl IntoIterator< Item = (impl AsRef, &'a Option>), > + Clone, version: Option<&Version>, + ) -> io::Result { + Self::run( + |format| { + let mut process = Process::run( + process_path, + env.clone(), + format.map(|format| format.to_string()).as_deref(), + )?; + let (stdin, stdout) = process.stdio().expect("couldn't access child stdio"); + + Ok((Box::new(process), Box::new(stdin), Box::new(stdout))) + }, + version, + || { + #[expect(clippy::disallowed_methods)] + Command::new(process_path) + .arg("--version") + .output() + .map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned()) + .unwrap_or_else(|_| "unknown version".to_owned()) + }, + ) + } + + /// Invokes `spawn` and performs a version check. + pub(crate) fn run( + spawn: impl Fn( + Option, + ) -> io::Result<( + Box, + Box, + Box, + )>, + version: Option<&Version>, + binary_server_version: impl Fn() -> String, ) -> io::Result { const VERSION: Version = Version::new(1, 93, 0); // we do `>` for nightly as this started working in the middle of the 1.93 nightly release, so we dont want to break on half of the nightlies @@ -65,27 +135,33 @@ impl ProcMacroServerProcess { && has_working_format_flag { &[ - ( - Some("bidirectional-postcard-prototype"), - Protocol::BidirectionalPostcardPrototype { mode: SpanMode::Id }, - ), - (Some("postcard-legacy"), Protocol::LegacyPostcard { mode: SpanMode::Id }), - (Some("json-legacy"), Protocol::LegacyJson { mode: SpanMode::Id }), + Some(ProtocolFormat::BidirectionalPostcardPrototype), + Some(ProtocolFormat::PostcardLegacy), + Some(ProtocolFormat::JsonLegacy), ] } else { - &[(None, Protocol::LegacyJson { mode: SpanMode::Id })] + &[None] }; let mut err = None; - for &(format, ref protocol) in formats { + for &format in formats { let create_srv = || { - let mut process = Process::run(process_path, env.clone(), format)?; - let (stdin, stdout) = process.stdio().expect("couldn't access child stdio"); + let (process, stdin, stdout) = spawn(format)?; io::Result::Ok(ProcMacroServerProcess { state: Mutex::new(ProcessSrvState { process, stdin, stdout }), version: 0, - protocol: protocol.clone(), + protocol: match format { + Some(ProtocolFormat::BidirectionalPostcardPrototype) => { + Protocol::BidirectionalPostcardPrototype { mode: SpanMode::Id } + } + Some(ProtocolFormat::PostcardLegacy) => { + Protocol::LegacyPostcard { mode: SpanMode::Id } + } + Some(ProtocolFormat::JsonLegacy) | None => { + Protocol::LegacyJson { mode: SpanMode::Id } + } + }, exited: OnceLock::new(), }) }; @@ -93,12 +169,7 @@ impl ProcMacroServerProcess { tracing::info!("sending proc-macro server version check"); match srv.version_check(Some(&mut reject_subrequests)) { Ok(v) if v > version::CURRENT_API_VERSION => { - #[allow(clippy::disallowed_methods)] - let process_version = Command::new(process_path) - .arg("--version") - .output() - .map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned()) - .unwrap_or_else(|_| "unknown version".to_owned()); + let process_version = binary_server_version(); err = Some(io::Error::other(format!( "Your installed proc-macro server is too new for your rust-analyzer. API version: {}, server version: {process_version}. \ This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain.", @@ -275,22 +346,9 @@ impl ProcMacroServerProcess { f(&mut state.stdin, &mut state.stdout, &mut buf).map_err(|e| { if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) { - match state.process.child.try_wait() { - Ok(None) | Err(_) => e, - Ok(Some(status)) => { - let mut msg = String::new(); - if !status.success() - && let Some(stderr) = state.process.child.stderr.as_mut() - { - _ = stderr.read_to_string(&mut msg); - } - let server_error = ServerError { - message: format!( - "proc-macro server exited with {status}{}{msg}", - if msg.is_empty() { "" } else { ": " } - ), - io: None, - }; + match state.process.exit_err() { + None => e, + Some(server_error) => { self.exited.get_or_init(|| AssertUnwindSafe(server_error)).0.clone() } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index bdfdb50002e1..189a1eea5c19 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -45,7 +45,11 @@ fn main() -> std::io::Result<()> { } let &format = matches.get_one::("format").expect("format value should always be present"); - run(format) + + let mut stdin = std::io::BufReader::new(std::io::stdin()); + let mut stdout = std::io::stdout(); + + run(&mut stdin, &mut stdout, format) } #[derive(Copy, Clone)] @@ -88,7 +92,11 @@ impl ValueEnum for ProtocolFormat { } #[cfg(not(feature = "sysroot-abi"))] -fn run(_: ProtocolFormat) -> std::io::Result<()> { +fn run( + _: &mut std::io::BufReader, + _: &mut std::io::Stdout, + _: ProtocolFormat, +) -> std::io::Result<()> { Err(std::io::Error::new( std::io::ErrorKind::Unsupported, "proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 22536a4e52b1..0c651d22b41b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -6,7 +6,7 @@ use proc_macro_api::{ transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; -use std::io; +use std::io::{self, BufRead, Write}; use legacy::Message; @@ -32,15 +32,24 @@ impl legacy::SpanTransformer for SpanTrans { } } -pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> { +pub(crate) fn run( + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), + format: ProtocolFormat, +) -> io::Result<()> { match format { - ProtocolFormat::JsonLegacy => run_::(), - ProtocolFormat::PostcardLegacy => run_::(), - ProtocolFormat::BidirectionalPostcardPrototype => run_new::(), + ProtocolFormat::JsonLegacy => run_old::(stdin, stdout), + ProtocolFormat::PostcardLegacy => run_old::(stdin, stdout), + ProtocolFormat::BidirectionalPostcardPrototype => { + run_new::(stdin, stdout) + } } } -fn run_new() -> io::Result<()> { +fn run_new( + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), +) -> io::Result<()> { fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind { match kind { proc_macro_srv::ProcMacroKind::CustomDerive => { @@ -52,8 +61,6 @@ fn run_new() -> io::Result<()> { } let mut buf = C::Buf::default(); - let mut stdin = io::stdin(); - let mut stdout = io::stdout(); let env_snapshot = EnvSnapshot::default(); let srv = proc_macro_srv::ProcMacroSrv::new(&env_snapshot); @@ -61,8 +68,7 @@ fn run_new() -> io::Result<()> { let mut span_mode = legacy::SpanMode::Id; 'outer: loop { - let req_opt = - bidirectional::BidirectionalMessage::read::<_, C>(&mut stdin.lock(), &mut buf)?; + let req_opt = bidirectional::BidirectionalMessage::read::(stdin, &mut buf)?; let Some(req) = req_opt else { break 'outer; }; @@ -77,22 +83,22 @@ fn run_new() -> io::Result<()> { .collect() }); - send_response::(&stdout, bidirectional::Response::ListMacros(res))?; + send_response::(stdout, bidirectional::Response::ListMacros(res))?; } bidirectional::Request::ApiVersionCheck {} => { send_response::( - &stdout, + stdout, bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), )?; } bidirectional::Request::SetConfig(config) => { span_mode = config.span_mode; - send_response::(&stdout, bidirectional::Response::SetConfig(config))?; + send_response::(stdout, bidirectional::Response::SetConfig(config))?; } bidirectional::Request::ExpandMacro(task) => { - handle_expand::(&srv, &mut stdin, &mut stdout, &mut buf, span_mode, *task)?; + handle_expand::(&srv, stdin, stdout, &mut buf, span_mode, *task)?; } }, _ => continue, @@ -104,8 +110,8 @@ fn run_new() -> io::Result<()> { fn handle_expand( srv: &proc_macro_srv::ProcMacroSrv<'_>, - stdin: &io::Stdin, - stdout: &io::Stdout, + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), buf: &mut C::Buf, span_mode: legacy::SpanMode, task: bidirectional::ExpandMacro, @@ -118,7 +124,7 @@ fn handle_expand( fn handle_expand_id( srv: &proc_macro_srv::ProcMacroSrv<'_>, - stdout: &io::Stdout, + stdout: &mut dyn Write, task: bidirectional::ExpandMacro, ) -> io::Result<()> { let bidirectional::ExpandMacro { lib, env, current_dir, data } = task; @@ -157,12 +163,12 @@ fn handle_expand_id( }) .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); - send_response::(&stdout, bidirectional::Response::ExpandMacro(res)) + send_response::(stdout, bidirectional::Response::ExpandMacro(res)) } struct ProcMacroClientHandle<'a, C: Codec> { - stdin: &'a io::Stdin, - stdout: &'a io::Stdout, + stdin: &'a mut (dyn BufRead + Send + Sync), + stdout: &'a mut (dyn Write + Send + Sync), buf: &'a mut C::Buf, } @@ -173,11 +179,11 @@ impl<'a, C: Codec> ProcMacroClientHandle<'a, C> { ) -> Option { let msg = bidirectional::BidirectionalMessage::SubRequest(req); - if msg.write::<_, C>(&mut self.stdout.lock()).is_err() { + if msg.write::(&mut *self.stdout).is_err() { return None; } - match bidirectional::BidirectionalMessage::read::<_, C>(&mut self.stdin.lock(), self.buf) { + match bidirectional::BidirectionalMessage::read::(&mut *self.stdin, self.buf) { Ok(Some(msg)) => Some(msg), _ => None, } @@ -238,8 +244,8 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl fn handle_expand_ra( srv: &proc_macro_srv::ProcMacroSrv<'_>, - stdin: &io::Stdin, - stdout: &io::Stdout, + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), buf: &mut C::Buf, task: bidirectional::ExpandMacro, ) -> io::Result<()> { @@ -301,10 +307,13 @@ fn handle_expand_ra( .map(|(tree, span_data_table)| bidirectional::ExpandMacroExtended { tree, span_data_table }) .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); - send_response::(&stdout, bidirectional::Response::ExpandMacroExtended(res)) + send_response::(stdout, bidirectional::Response::ExpandMacroExtended(res)) } -fn run_() -> io::Result<()> { +fn run_old( + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), +) -> io::Result<()> { fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind { match kind { proc_macro_srv::ProcMacroKind::CustomDerive => { @@ -316,8 +325,8 @@ fn run_() -> io::Result<()> { } let mut buf = C::Buf::default(); - let mut read_request = || legacy::Request::read::<_, C>(&mut io::stdin().lock(), &mut buf); - let write_response = |msg: legacy::Response| msg.write::<_, C>(&mut io::stdout().lock()); + let mut read_request = || legacy::Request::read::(stdin, &mut buf); + let mut write_response = |msg: legacy::Response| msg.write::(stdout); let env = EnvSnapshot::default(); let srv = proc_macro_srv::ProcMacroSrv::new(&env); @@ -446,7 +455,10 @@ fn run_() -> io::Result<()> { Ok(()) } -fn send_response(stdout: &io::Stdout, resp: bidirectional::Response) -> io::Result<()> { +fn send_response( + stdout: &mut dyn Write, + resp: bidirectional::Response, +) -> io::Result<()> { let resp = bidirectional::BidirectionalMessage::Response(resp); - resp.write::<_, C>(&mut stdout.lock()) + resp.write::(stdout) } From 27fef0ccbe56e9e4494d19780cdd7c41660d764d Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 10 Jan 2026 16:01:09 +0100 Subject: [PATCH 1921/3801] internal: Landing integration test infra for proc-macro-srv-cli --- src/tools/rust-analyzer/Cargo.lock | 6 + .../crates/proc-macro-api/src/lib.rs | 6 +- .../crates/proc-macro-srv-cli/Cargo.toml | 14 ++ .../crates/proc-macro-srv-cli/src/lib.rs | 6 + .../crates/proc-macro-srv-cli/src/main.rs | 43 ++-- .../proc-macro-srv-cli/src/main_loop.rs | 5 +- .../proc-macro-srv-cli/tests/common/utils.rs | 213 +++++++++++++++++ .../proc-macro-srv-cli/tests/legacy_json.rs | 224 ++++++++++++++++++ 8 files changed, 494 insertions(+), 23 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/lib.rs create mode 100644 src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs create mode 100644 src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 5bdde7c7c3e6..d6c6250e13dc 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1879,9 +1879,15 @@ name = "proc-macro-srv-cli" version = "0.0.0" dependencies = [ "clap", + "expect-test", + "intern", + "paths", "postcard", "proc-macro-api", "proc-macro-srv", + "proc-macro-test", + "span", + "tt", ] [[package]] diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 98ee6817c2d2..822809943a36 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -44,10 +44,14 @@ pub mod version { pub const CURRENT_API_VERSION: u32 = HASHED_AST_ID; } -#[derive(Copy, Clone)] +/// Protocol format for communication between client and server. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum ProtocolFormat { + /// JSON-based legacy protocol (newline-delimited JSON). JsonLegacy, + /// Postcard-based legacy protocol (COBS-encoded postcard). PostcardLegacy, + /// Bidirectional postcard protocol with sub-request support. BidirectionalPostcardPrototype, } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml index 6b2db0b269d5..a25e3b64ad42 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml @@ -10,12 +10,26 @@ license.workspace = true rust-version.workspace = true publish = false +[lib] +doctest = false + [dependencies] proc-macro-srv.workspace = true proc-macro-api.workspace = true postcard.workspace = true clap = {version = "4.5.42", default-features = false, features = ["std"]} +[dev-dependencies] +expect-test.workspace = true +paths.workspace = true +# span = {workspace = true, default-features = false} does not work +span = { path = "../span", default-features = false} +tt.workspace = true +intern.workspace = true + +# used as proc macro test target +proc-macro-test.path = "../proc-macro-srv/proc-macro-test" + [features] default = [] # default = ["sysroot-abi"] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/lib.rs new file mode 100644 index 000000000000..9e6f03bf4604 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/lib.rs @@ -0,0 +1,6 @@ +//! Library interface for `proc-macro-srv-cli`. +//! +//! This module exposes the server main loop and protocol format for integration testing. + +#[cfg(feature = "sysroot-abi")] +pub mod main_loop; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index 189a1eea5c19..a246d4d3f28f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -9,11 +9,11 @@ extern crate rustc_driver as _; mod version; -#[cfg(feature = "sysroot-abi")] -mod main_loop; use clap::{Command, ValueEnum}; +use proc_macro_api::ProtocolFormat; + #[cfg(feature = "sysroot-abi")] -use main_loop::run; +use proc_macro_srv_cli::main_loop::run; fn main() -> std::io::Result<()> { let v = std::env::var("RUST_ANALYZER_INTERNALS_DO_NOT_USE"); @@ -32,7 +32,7 @@ fn main() -> std::io::Result<()> { .long("format") .action(clap::ArgAction::Set) .default_value("json-legacy") - .value_parser(clap::builder::EnumValueParser::::new()), + .value_parser(clap::builder::EnumValueParser::::new()), clap::Arg::new("version") .long("version") .action(clap::ArgAction::SetTrue) @@ -43,33 +43,37 @@ fn main() -> std::io::Result<()> { println!("rust-analyzer-proc-macro-srv {}", version::version()); return Ok(()); } - let &format = - matches.get_one::("format").expect("format value should always be present"); + let &format = matches + .get_one::("format") + .expect("format value should always be present"); let mut stdin = std::io::BufReader::new(std::io::stdin()); let mut stdout = std::io::stdout(); - run(&mut stdin, &mut stdout, format) + run(&mut stdin, &mut stdout, format.into()) } +/// Wrapper for CLI argument parsing that implements `ValueEnum`. #[derive(Copy, Clone)] -enum ProtocolFormat { - JsonLegacy, - PostcardLegacy, - BidirectionalPostcardPrototype, +struct ProtocolFormatArg(ProtocolFormat); + +impl From for ProtocolFormat { + fn from(arg: ProtocolFormatArg) -> Self { + arg.0 + } } -impl ValueEnum for ProtocolFormat { +impl ValueEnum for ProtocolFormatArg { fn value_variants<'a>() -> &'a [Self] { &[ - ProtocolFormat::JsonLegacy, - ProtocolFormat::PostcardLegacy, - ProtocolFormat::BidirectionalPostcardPrototype, + ProtocolFormatArg(ProtocolFormat::JsonLegacy), + ProtocolFormatArg(ProtocolFormat::PostcardLegacy), + ProtocolFormatArg(ProtocolFormat::BidirectionalPostcardPrototype), ] } fn to_possible_value(&self) -> Option { - match self { + match self.0 { ProtocolFormat::JsonLegacy => Some(clap::builder::PossibleValue::new("json-legacy")), ProtocolFormat::PostcardLegacy => { Some(clap::builder::PossibleValue::new("postcard-legacy")) @@ -79,12 +83,13 @@ impl ValueEnum for ProtocolFormat { } } } + fn from_str(input: &str, _ignore_case: bool) -> Result { match input { - "json-legacy" => Ok(ProtocolFormat::JsonLegacy), - "postcard-legacy" => Ok(ProtocolFormat::PostcardLegacy), + "json-legacy" => Ok(ProtocolFormatArg(ProtocolFormat::JsonLegacy)), + "postcard-legacy" => Ok(ProtocolFormatArg(ProtocolFormat::PostcardLegacy)), "bidirectional-postcard-prototype" => { - Ok(ProtocolFormat::BidirectionalPostcardPrototype) + Ok(ProtocolFormatArg(ProtocolFormat::BidirectionalPostcardPrototype)) } _ => Err(format!("unknown protocol format: {input}")), } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 0c651d22b41b..b927eea46b58 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -1,6 +1,6 @@ //! The main loop of the proc-macro server. use proc_macro_api::{ - Codec, + Codec, ProtocolFormat, bidirectional_protocol::msg as bidirectional, legacy_protocol::msg as legacy, transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, @@ -12,7 +12,6 @@ use legacy::Message; use proc_macro_srv::{EnvSnapshot, SpanId}; -use crate::ProtocolFormat; struct SpanTrans; impl legacy::SpanTransformer for SpanTrans { @@ -32,7 +31,7 @@ impl legacy::SpanTransformer for SpanTrans { } } -pub(crate) fn run( +pub fn run( stdin: &mut (dyn BufRead + Send + Sync), stdout: &mut (dyn Write + Send + Sync), format: ProtocolFormat, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs new file mode 100644 index 000000000000..722e92eec7e5 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs @@ -0,0 +1,213 @@ +use std::{ + collections::VecDeque, + io::{self, BufRead, Read, Write}, + sync::{Arc, Condvar, Mutex}, + thread, +}; + +use paths::Utf8PathBuf; +use proc_macro_api::{ + legacy_protocol::msg::{FlatTree, Message, Request, Response, SpanDataIndexMap}, + transport::codec::json::JsonProtocol, +}; +use span::{Edition, EditionedFileId, FileId, Span, SpanAnchor, SyntaxContext, TextRange}; +use tt::{Delimiter, DelimiterKind, TopSubtreeBuilder}; + +/// Shared state for an in-memory byte channel. +#[derive(Default)] +struct ChannelState { + buffer: VecDeque, + closed: bool, +} + +type InMemoryChannel = Arc<(Mutex, Condvar)>; + +/// Writer end of an in-memory channel. +pub(crate) struct ChannelWriter { + state: InMemoryChannel, +} + +impl Write for ChannelWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + if state.closed { + return Err(io::Error::new(io::ErrorKind::BrokenPipe, "channel closed")); + } + state.buffer.extend(buf); + cvar.notify_all(); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Drop for ChannelWriter { + fn drop(&mut self) { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + state.closed = true; + cvar.notify_all(); + } +} + +/// Reader end of an in-memory channel. +pub(crate) struct ChannelReader { + state: InMemoryChannel, + internal_buf: Vec, +} + +impl Read for ChannelReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + + while state.buffer.is_empty() && !state.closed { + state = cvar.wait(state).unwrap(); + } + + if state.buffer.is_empty() && state.closed { + return Ok(0); + } + + let to_read = buf.len().min(state.buffer.len()); + for (dst, src) in buf.iter_mut().zip(state.buffer.drain(..to_read)) { + *dst = src; + } + Ok(to_read) + } +} + +impl BufRead for ChannelReader { + fn fill_buf(&mut self) -> io::Result<&[u8]> { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + + while state.buffer.is_empty() && !state.closed { + state = cvar.wait(state).unwrap(); + } + + self.internal_buf.clear(); + self.internal_buf.extend(&state.buffer); + Ok(&self.internal_buf) + } + + fn consume(&mut self, amt: usize) { + let (lock, _) = &*self.state; + let mut state = lock.lock().unwrap(); + let to_drain = amt.min(state.buffer.len()); + drop(state.buffer.drain(..to_drain)); + } +} + +/// Creates a connected pair of channels for bidirectional communication. +fn create_channel_pair() -> (ChannelWriter, ChannelReader, ChannelWriter, ChannelReader) { + // Channel for client -> server communication + let client_to_server = Arc::new(( + Mutex::new(ChannelState { buffer: VecDeque::new(), closed: false }), + Condvar::new(), + )); + let client_writer = ChannelWriter { state: client_to_server.clone() }; + let server_reader = ChannelReader { state: client_to_server, internal_buf: Vec::new() }; + + // Channel for server -> client communication + let server_to_client = Arc::new(( + Mutex::new(ChannelState { buffer: VecDeque::new(), closed: false }), + Condvar::new(), + )); + + let server_writer = ChannelWriter { state: server_to_client.clone() }; + let client_reader = ChannelReader { state: server_to_client, internal_buf: Vec::new() }; + + (client_writer, client_reader, server_writer, server_reader) +} + +pub(crate) fn proc_macro_test_dylib_path() -> Utf8PathBuf { + let path = proc_macro_test::PROC_MACRO_TEST_LOCATION; + if path.is_empty() { + panic!("proc-macro-test dylib not available (requires nightly toolchain)"); + } + path.into() +} + +/// Runs a test with the server in a background thread. +pub(crate) fn with_server(test_fn: F) -> R +where + F: FnOnce(&mut dyn Write, &mut dyn BufRead) -> R, +{ + let (mut client_writer, mut client_reader, mut server_writer, mut server_reader) = + create_channel_pair(); + + let server_handle = thread::spawn(move || { + proc_macro_srv_cli::main_loop::run( + &mut server_reader, + &mut server_writer, + proc_macro_api::ProtocolFormat::JsonLegacy, + ) + }); + + let result = test_fn(&mut client_writer, &mut client_reader); + + // Close the client writer to signal the server to stop + drop(client_writer); + + // Wait for server to finish + match server_handle.join() { + Ok(Ok(())) => {} + Ok(Err(e)) => { + // IO error from server is expected when client disconnects + if matches!( + e.kind(), + io::ErrorKind::BrokenPipe + | io::ErrorKind::UnexpectedEof + | io::ErrorKind::InvalidData + ) { + panic!("Server error: {e}"); + } + } + Err(e) => std::panic::resume_unwind(e), + } + + result +} + +/// Sends a request and reads the response using JSON protocol. +pub(crate) fn request( + writer: &mut dyn Write, + reader: &mut dyn BufRead, + request: Request, +) -> Response { + request.write::(writer).expect("failed to write request"); + + let mut buf = String::new(); + Response::read::(reader, &mut buf) + .expect("failed to read response") + .expect("no response received") +} + +/// Creates a simple empty token tree suitable for testing. +pub(crate) fn create_empty_token_tree( + version: u32, + span_data_table: &mut SpanDataIndexMap, +) -> FlatTree { + let anchor = SpanAnchor { + file_id: EditionedFileId::new(FileId::from_raw(0), Edition::CURRENT), + ast_id: span::ROOT_ERASED_FILE_AST_ID, + }; + let span = Span { + range: TextRange::empty(0.into()), + anchor, + ctx: SyntaxContext::root(Edition::CURRENT), + }; + + let builder = TopSubtreeBuilder::new(Delimiter { + open: span, + close: span, + kind: DelimiterKind::Invisible, + }); + let tt = builder.build(); + + FlatTree::from_subtree(tt.view(), version, span_data_table) +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs new file mode 100644 index 000000000000..1fa886219a8a --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs @@ -0,0 +1,224 @@ +//! Integration tests for the proc-macro-srv-cli main loop. +//! +//! These tests exercise the full client-server RPC procedure using in-memory +//! channels without needing to spawn the actual server and client processes. + +#![cfg(feature = "sysroot-abi")] + +mod common { + pub(crate) mod utils; +} + +use common::utils::{create_empty_token_tree, proc_macro_test_dylib_path, request, with_server}; +use expect_test::expect; +use proc_macro_api::{ + legacy_protocol::msg::{ + ExpandMacro, ExpandMacroData, ExpnGlobals, PanicMessage, Request, Response, ServerConfig, + SpanDataIndexMap, SpanMode, + }, + version::CURRENT_API_VERSION, +}; + +#[test] +fn test_version_check() { + with_server(|writer, reader| { + let response = request(writer, reader, Request::ApiVersionCheck {}); + + match response { + Response::ApiVersionCheck(version) => { + assert_eq!(version, CURRENT_API_VERSION); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_list_macros() { + with_server(|writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + let response = request(writer, reader, Request::ListMacros { dylib_path }); + + let Response::ListMacros(Ok(macros)) = response else { + panic!("expected successful ListMacros response"); + }; + + let mut macro_list: Vec<_> = + macros.iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect(); + macro_list.sort(); + let macro_list_str = macro_list.join("\n"); + + expect![[r#" + DeriveEmpty [CustomDerive] + DeriveError [CustomDerive] + DerivePanic [CustomDerive] + DeriveReemit [CustomDerive] + attr_error [Attr] + attr_noop [Attr] + attr_panic [Attr] + fn_like_clone_tokens [Bang] + fn_like_error [Bang] + fn_like_mk_idents [Bang] + fn_like_mk_literals [Bang] + fn_like_noop [Bang] + fn_like_panic [Bang] + fn_like_span_join [Bang] + fn_like_span_line_column [Bang] + fn_like_span_ops [Bang]"#]] + .assert_eq(¯o_list_str); + }); +} + +#[test] +fn test_list_macros_invalid_path() { + with_server(|writer, reader| { + let response = request( + writer, + reader, + Request::ListMacros { dylib_path: "/nonexistent/path/to/dylib.so".into() }, + ); + + match response { + Response::ListMacros(Err(e)) => assert!( + e.starts_with("Cannot create expander for /nonexistent/path/to/dylib.so"), + "{e}" + ), + other => panic!("expected error response, got: {other:?}"), + } + }); +} + +#[test] +fn test_set_config() { + with_server(|writer, reader| { + let config = ServerConfig { span_mode: SpanMode::Id }; + let response = request(writer, reader, Request::SetConfig(config)); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::Id); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_set_config_rust_analyzer_mode() { + with_server(|writer, reader| { + let config = ServerConfig { span_mode: SpanMode::RustAnalyzer }; + let response = request(writer, reader, Request::SetConfig(config)); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::RustAnalyzer); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_expand_macro_panic() { + with_server(|writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let version_response = request(writer, reader, Request::ApiVersionCheck {}); + let Response::ApiVersionCheck(version) = version_response else { + panic!("expected version check response"); + }; + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = create_empty_token_tree(version, &mut span_data_table); + + let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "fn_like_panic".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { + serialize: version >= 3, + def_site: 0, + call_site: 0, + mixed_site: 0, + }, + span_data_table: vec![], + }, + })); + + let response = request(writer, reader, expand_request); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + assert!(msg.contains("fn_like_panic"), "panic message should mention the macro"); + } + Response::ExpandMacro(Ok(_)) => { + panic!("expected panic, but macro succeeded"); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_basic_call_flow() { + with_server(|writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let response1 = request(writer, reader, Request::ApiVersionCheck {}); + assert!(matches!(response1, Response::ApiVersionCheck(_))); + + let response2 = + request(writer, reader, Request::SetConfig(ServerConfig { span_mode: SpanMode::Id })); + assert!(matches!(response2, Response::SetConfig(_))); + + let response3 = + request(writer, reader, Request::ListMacros { dylib_path: dylib_path.clone() }); + assert!(matches!(response3, Response::ListMacros(Ok(_)))); + }); +} + +#[test] +fn test_expand_nonexistent_macro() { + with_server(|writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let version_response = request(writer, reader, Request::ApiVersionCheck {}); + let Response::ApiVersionCheck(version) = version_response else { + panic!("expected version check response"); + }; + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = create_empty_token_tree(version, &mut span_data_table); + + let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "NonexistentMacro".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { + serialize: version >= 3, + def_site: 0, + call_site: 0, + mixed_site: 0, + }, + span_data_table: vec![], + }, + })); + + let response = request(writer, reader, expand_request); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + expect!["proc-macro `NonexistentMacro` is missing"].assert_eq(&msg) + } + other => panic!("expected error for nonexistent macro, got: {other:?}"), + } + }); +} From 8332887f36091d9c6c8b2faefdb33dcaa1743e32 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 10 Jan 2026 11:04:54 -0500 Subject: [PATCH 1922/3801] Update cargo submodule --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 8c133afcd5e0..6d1bd93c47f0 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 8c133afcd5e0d69932fe11f5907683723f8d361d +Subproject commit 6d1bd93c47f059ec1344cb31e68a2fb284cbc6b1 From 6878e73d26af87e01c1c289c77f1448fa3c3e76f Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sat, 10 Jan 2026 11:59:33 +0530 Subject: [PATCH 1923/3801] std: sys: fs: uefi: Implement File::seek - Tested using OVMF on QEMU. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index fcf21d9e9731..23de7adfabc6 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -352,8 +352,24 @@ impl File { unsupported() } - pub fn seek(&self, _pos: SeekFrom) -> io::Result { - unsupported() + pub fn seek(&self, pos: SeekFrom) -> io::Result { + const NEG_OFF_ERR: io::Error = + io::const_error!(io::ErrorKind::InvalidInput, "cannot seek to negative offset."); + + let off = match pos { + SeekFrom::Start(p) => p, + SeekFrom::End(p) => { + // Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file. + if p == 0 { + 0xFFFFFFFFFFFFFFFF + } else { + self.file_attr()?.size().checked_add_signed(p).ok_or(NEG_OFF_ERR)? + } + } + SeekFrom::Current(p) => self.tell()?.checked_add_signed(p).ok_or(NEG_OFF_ERR)?, + }; + + self.0.set_position(off).map(|_| off) } pub fn size(&self) -> Option> { @@ -755,6 +771,12 @@ mod uefi_fs { if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(pos) } } + pub(crate) fn set_position(&self, pos: u64) -> io::Result<()> { + let file_ptr = self.protocol.as_ptr(); + let r = unsafe { ((*file_ptr).set_position)(file_ptr, pos) }; + if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } + } + pub(crate) fn delete(self) -> io::Result<()> { let file_ptr = self.protocol.as_ptr(); let r = unsafe { ((*file_ptr).delete)(file_ptr) }; From 767291606e7071e6e13e56f2eb4e620e688fbc9e Mon Sep 17 00:00:00 2001 From: kirk Date: Sat, 27 Dec 2025 16:43:10 +0000 Subject: [PATCH 1924/3801] Remove mentions of debootstrap and chroots from the m68k-unknown-none-elf platform support doc --- .../platform-support/m68k-unknown-none-elf.md | 36 +------------------ 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md b/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md index e390ba0aee96..ed13886fe935 100644 --- a/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md @@ -29,40 +29,6 @@ binaries: # apt install qemu-user-static ``` -To run more complex programs, it will be necessary to set up a Debian/m68k chroot with -the help of the command `debootstrap`: - -```text -# apt install debootstrap debian-ports-archive-keyring -# debootstrap --keyring=/usr/share/keyrings/debian-ports-archive-keyring.gpg --arch=m68k unstable debian-68k http://ftp.ports.debian.org/debian-ports -``` - -This chroot can then seamlessly entered using the normal `chroot` command thanks to -QEMU user emulation: - -```text -# chroot /path/to/debian-68k -``` - -To get started with native builds, which are currently untested, a native Debian/m68k -system can be installed either on real hardware such as 68k-based Commodore Amiga or -Atari systems or emulated environments such as QEMU version 4.2 or newer or ARAnyM. - -ISO images for installation are provided by the Debian Ports team and can be obtained -from the Debian CD image server available at: - -[https://cdimage.debian.org/cdimage/ports/current](https://cdimage.debian.org/cdimage/ports/current/) - -Documentation for Debian/m68k is available on the Debian Wiki at: - -[https://wiki.debian.org/M68k](https://wiki.debian.org/M68k) - -Support is available either through the `debian-68k` mailing list: - -[https://lists.debian.org/debian-68k/](https://lists.debian.org/debian-68k/) - -or the `#debian-68k` IRC channel on OFTC network. - ## Building At least llvm version `19.1.5` is required to build `core` and `alloc` for this target, and currently the gnu linker is required, as `lld` has no support for the `m68k` architecture @@ -105,4 +71,4 @@ Very simple programs can be run using the `qemu-m68k-static` program: qemu-m68k-static your-code ``` -For more complex applications, a chroot or native m68k system is required for testing. +For more complex applications, a native (or emulated) m68k system is required for testing. From ab1caae91203e9aa976fe2eb9faba3d013d812ad Mon Sep 17 00:00:00 2001 From: kirk Date: Sun, 28 Dec 2025 17:58:52 +0000 Subject: [PATCH 1925/3801] move sentence about gnu ld from 'Building' to 'Requirements' section --- src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md b/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md index ed13886fe935..0a9bdc7e1c98 100644 --- a/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/m68k-unknown-none-elf.md @@ -12,6 +12,7 @@ Bare metal Motorola 680x0 This target requires an m68k build environment for cross-compilation which is available on Debian, Debian-based systems, openSUSE, and other distributions. +The gnu linker is currently required, as `lld` has no support for the `m68k` architecture On Debian-based systems, it should be sufficient to install a g++ cross-compiler for the m68k architecture which will automatically pull in additional dependencies such as @@ -31,7 +32,7 @@ binaries: ## Building -At least llvm version `19.1.5` is required to build `core` and `alloc` for this target, and currently the gnu linker is required, as `lld` has no support for the `m68k` architecture +At least llvm version `19.1.5` is required to build `core` and `alloc` for this target. ## Cross-compilation From c10f0dd1947645259a7e1e9f436956aea73d1cdf Mon Sep 17 00:00:00 2001 From: Guilherme Luiz Date: Sat, 10 Jan 2026 14:09:21 -0300 Subject: [PATCH 1926/3801] =?UTF-8?q?Add=20comment=20to=20clarify=20that?= =?UTF-8?q?=20'=EF=AC=83'=20is=20a=20single=20Unicode=20code=20point=20map?= =?UTF-8?q?ping=20to=20FFI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 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 c30edeed580a..0acb3e964f54 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1143,6 +1143,7 @@ impl char { /// [Unicode Standard]: https://www.unicode.org/versions/latest/ /// /// # Examples + /// `'ffi'` (U+FB03) is a single Unicode code point (a ligature) that maps to "FFI" in uppercase. /// /// As an iterator: /// From e4dd9475234017adeda572d02320876f98e26775 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Sat, 10 Jan 2026 19:57:28 +0100 Subject: [PATCH 1927/3801] introduce `Self::as_x_{plus,minus}_one` reduces duplication --- clippy_lints/src/int_plus_one.rs | 91 +++++++++++++++----------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs index b82ca0205a9f..f8184b30f400 100644 --- a/clippy_lints/src/int_plus_one.rs +++ b/clippy_lints/src/int_plus_one.rs @@ -63,7 +63,7 @@ impl TryFrom for LeOrGe { impl IntPlusOne { fn is_one(expr: &Expr) -> bool { if let ExprKind::Lit(token_lit) = expr.kind - && let Ok(LitKind::Int(Pu128(1), ..)) = LitKind::from_token_lit(token_lit) + && matches!(LitKind::from_token_lit(token_lit), Ok(LitKind::Int(Pu128(1), ..))) { return true; } @@ -71,60 +71,57 @@ impl IntPlusOne { } fn is_neg_one(expr: &Expr) -> bool { - if let ExprKind::Unary(UnOp::Neg, expr) = &expr.kind - && Self::is_one(expr) - { - true + if let ExprKind::Unary(UnOp::Neg, expr) = &expr.kind { + Self::is_one(expr) } else { false } } + /// Checks whether `expr` is `x + 1` or `1 + x`, and if so, returns `x` + fn as_x_plus_one(expr: &Expr) -> Option<&Expr> { + if let ExprKind::Binary(op, lhs, rhs) = &expr.kind + && op.node == BinOpKind::Add + { + if Self::is_one(rhs) { + // x + 1 + return Some(lhs); + } else if Self::is_one(lhs) { + // 1 + x + return Some(rhs); + } + } + None + } + + /// Checks whether `expr` is `x - 1` or `-1 + x`, and if so, returns `x` + fn as_x_minus_one(expr: &Expr) -> Option<&Expr> { + if let ExprKind::Binary(op, lhs, rhs) = &expr.kind { + if op.node == BinOpKind::Sub && Self::is_one(rhs) { + // x - 1 + return Some(lhs); + } else if op.node == BinOpKind::Add && Self::is_neg_one(lhs) { + // -1 + x + return Some(rhs); + } + } + None + } + fn check_binop<'tcx>(le_or_ge: LeOrGe, lhs: &'tcx Expr, rhs: &'tcx Expr) -> Option<(&'tcx Expr, &'tcx Expr)> { - match (le_or_ge, &lhs.kind, &rhs.kind) { - // case where `x - 1 >= ...` or `-1 + x >= ...` - (LeOrGe::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => { - match lhskind.node { - // `-1 + x` - BinOpKind::Add if Self::is_neg_one(lhslhs) => Some((lhsrhs, rhs)), - // `x - 1` - BinOpKind::Sub if Self::is_one(lhsrhs) => Some((lhslhs, rhs)), - _ => None, - } + match le_or_ge { + LeOrGe::Ge => { + // case where `x - 1 >= ...` or `-1 + x >= ...` + (Self::as_x_minus_one(lhs).map(|new_lhs| (new_lhs, rhs))) + // case where `... >= y + 1` or `... >= 1 + y` + .or_else(|| Self::as_x_plus_one(rhs).map(|new_rhs| (lhs, new_rhs))) }, - // case where `... >= y + 1` or `... >= 1 + y` - (LeOrGe::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => { - // `y + 1` and `1 + y` - if Self::is_one(rhslhs) { - Some((lhs, rhsrhs)) - } else if Self::is_one(rhsrhs) { - Some((lhs, rhslhs)) - } else { - None - } + LeOrGe::Le => { + // case where `x + 1 <= ...` or `1 + x <= ...` + (Self::as_x_plus_one(lhs).map(|new_lhs| (new_lhs, rhs))) + // case where `... <= y - 1` or `... <= -1 + y` + .or_else(|| Self::as_x_minus_one(rhs).map(|new_rhs| (lhs, new_rhs))) }, - // case where `x + 1 <= ...` or `1 + x <= ...` - (LeOrGe::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => { - // `1 + x` and `x + 1` - if Self::is_one(lhslhs) { - Some((lhsrhs, rhs)) - } else if Self::is_one(lhsrhs) { - Some((lhslhs, rhs)) - } else { - None - } - }, - // case where `... <= y - 1` or `... <= -1 + y` - (LeOrGe::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => { - match rhskind.node { - // `-1 + y` - BinOpKind::Add if Self::is_neg_one(rhslhs) => Some((lhs, rhsrhs)), - // `y - 1` - BinOpKind::Sub if Self::is_one(rhsrhs) => Some((lhs, rhslhs)), - _ => None, - } - }, - _ => None, } } From 306254b40e83189ae65fdda6501b1523d8c19c03 Mon Sep 17 00:00:00 2001 From: relaxcn Date: Sun, 11 Jan 2026 03:51:36 +0800 Subject: [PATCH 1928/3801] improve the doc of `doc_paragraphs_missing_punctuation` --- clippy_lints/src/doc/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 2b41275ee3a4..ecf7acbd7ce6 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -692,6 +692,12 @@ declare_clippy_lint! { /// /// /// /// It was chosen by a fair dice roll. /// ``` + /// + /// ### Terminal punctuation marks + /// This lint treats these characters as end markers: '.', '?', '!', '…' and ':'. + /// + /// The colon is not exactly a terminal punctuation mark, but this is required for paragraphs that + /// introduce a table or a list for example. #[clippy::version = "1.93.0"] pub DOC_PARAGRAPHS_MISSING_PUNCTUATION, restriction, From 5ee964049a9f0808bc0729fad79be446a2a987cb Mon Sep 17 00:00:00 2001 From: dianqk Date: Sat, 10 Jan 2026 18:34:02 +0800 Subject: [PATCH 1929/3801] Add FileCheck to if_condition_int.rs --- ...t_opt_bool.SimplifyComparisonIntegral.diff | 2 +- ...opt_floats.SimplifyComparisonIntegral.diff | 2 +- ...comparison.SimplifyComparisonIntegral.diff | 18 ++--- ...t.opt_char.SimplifyComparisonIntegral.diff | 4 +- ...int.opt_i8.SimplifyComparisonIntegral.diff | 4 +- ...ltiple_ifs.SimplifyComparisonIntegral.diff | 8 +- ...t_negative.SimplifyComparisonIntegral.diff | 4 +- ...nt.opt_u32.SimplifyComparisonIntegral.diff | 4 +- tests/mir-opt/if_condition_int.rs | 76 ++++++++++++++++--- 9 files changed, 88 insertions(+), 34 deletions(-) diff --git a/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff index 2350faa05d3f..f2d527326592 100644 --- a/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + switchInt(copy _1) -> [0: bb2, otherwise: bb1]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff index 94570017730d..c72a58a145f4 100644 --- a/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff @@ -11,7 +11,7 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; - _2 = Eq(move _3, const -42f32); + _2 = Eq(copy _1, const -42f32); switchInt(move _2) -> [0: bb2, otherwise: bb1]; } diff --git a/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff index d19b4148405e..29d57722355b 100644 --- a/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff @@ -15,23 +15,20 @@ } bb0: { - StorageLive(_2); + nop; StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 17_i8); -- StorageDead(_3); + _2 = Eq(copy _1, const 17_i8); + StorageDead(_3); - switchInt(copy _2) -> [0: bb2, otherwise: bb1]; -+ _2 = Eq(copy _3, const 17_i8); -+ nop; -+ switchInt(move _3) -> [17: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [17: bb1, otherwise: bb2]; } bb1: { -+ StorageDead(_3); StorageLive(_6); StorageLive(_7); _7 = copy _2; - _6 = move _7 as i32 (IntToInt); + _6 = copy _2 as i32 (IntToInt); StorageDead(_7); _0 = Add(const 100_i32, move _6); StorageDead(_6); @@ -39,11 +36,10 @@ } bb2: { -+ StorageDead(_3); StorageLive(_4); StorageLive(_5); _5 = copy _2; - _4 = move _5 as i32 (IntToInt); + _4 = copy _2 as i32 (IntToInt); StorageDead(_5); _0 = Add(const 10_i32, move _4); StorageDead(_4); @@ -51,7 +47,7 @@ } bb3: { - StorageDead(_2); + nop; return; } } diff --git a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff index e47b7e522598..37b41c2aa5ab 100644 --- a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff @@ -11,10 +11,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 'x'); +- _2 = Eq(copy _1, const 'x'); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [120: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [120: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff index b6cdc6af8bf4..c92a606090e4 100644 --- a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff @@ -11,10 +11,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 42_i8); +- _2 = Eq(copy _1, const 42_i8); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [42: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff index 31745ac732a2..a73670323b1f 100644 --- a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff @@ -13,10 +13,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 42_u32); +- _2 = Eq(copy _1, const 42_u32); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [42: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; } bb1: { @@ -30,10 +30,10 @@ StorageLive(_4); StorageLive(_5); _5 = copy _1; -- _4 = Ne(move _5, const 21_u32); +- _4 = Ne(copy _1, const 21_u32); - switchInt(move _4) -> [0: bb4, otherwise: bb3]; + nop; -+ switchInt(move _5) -> [21: bb4, otherwise: bb3]; ++ switchInt(move _1) -> [21: bb4, otherwise: bb3]; } bb3: { diff --git a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff index d747985f6e13..36145ab02bea 100644 --- a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff @@ -11,10 +11,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const -42_i32); +- _2 = Eq(copy _1, const -42_i32); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [4294967254: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [4294967254: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff index 1d6809a9438a..2cc4a8b76973 100644 --- a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff @@ -11,10 +11,10 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; -- _2 = Eq(move _3, const 42_u32); +- _2 = Eq(copy _1, const 42_u32); - switchInt(move _2) -> [0: bb2, otherwise: bb1]; + nop; -+ switchInt(move _3) -> [42: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; } bb1: { diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs index 4cc2c2b90210..24ef6b85529e 100644 --- a/tests/mir-opt/if_condition_int.rs +++ b/tests/mir-opt/if_condition_int.rs @@ -1,36 +1,76 @@ -// skip-filecheck //@ test-mir-pass: SimplifyComparisonIntegral -// EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.opt_i8.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff -// EMIT_MIR if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff +// GVN simplifies FileCheck. +//@ compile-flags: -Zmir-enable-passes=+GVN +// EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff fn opt_u32(x: u32) -> u32 { + // CHECK-LABEL: fn opt_u32( + // FIXME: This should be copy. + // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x == 42 { 0 } else { 1 } } +// EMIT_MIR if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff // don't opt: it is already optimal to switch on the bool fn dont_opt_bool(x: bool) -> u32 { + // CHECK-LABEL: fn dont_opt_bool( + // CHECK: switchInt(copy _1) -> [0: [[BB2:bb.*]], otherwise: [[BB1:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x { 0 } else { 1 } } +// EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff fn opt_char(x: char) -> u32 { + // CHECK-LABEL: fn opt_char( + // CHECK: switchInt(move _1) -> [120: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x == 'x' { 0 } else { 1 } } +// EMIT_MIR if_condition_int.opt_i8.SimplifyComparisonIntegral.diff fn opt_i8(x: i8) -> u32 { + // CHECK-LABEL: fn opt_i8( + // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x == 42 { 0 } else { 1 } } +// EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff fn opt_negative(x: i32) -> u32 { + // CHECK-LABEL: fn opt_negative( + // CHECK: switchInt(move _1) -> [4294967254: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_u32; if x == -42 { 0 } else { 1 } } +// EMIT_MIR if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff fn opt_multiple_ifs(x: u32) -> u32 { + // CHECK-LABEL: fn opt_multiple_ifs( + // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_u32; + // CHECK: [[BB2]]: + // CHECK: switchInt(move _1) -> [21: [[BB4:bb.*]], otherwise: [[BB3:bb.*]]]; + // CHECK: [[BB3]]: + // CHECK: _0 = const 1_u32; + // CHECK: [[BB4]]: + // CHECK: _0 = const 2_u32; if x == 42 { 0 } else if x != 21 { @@ -40,8 +80,18 @@ fn opt_multiple_ifs(x: u32) -> u32 { } } +// EMIT_MIR if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff // test that we optimize, but do not remove the b statement, as that is used later on fn dont_remove_comparison(a: i8) -> i32 { + // CHECK-LABEL: fn dont_remove_comparison( + // CHECK: [[b:_.*]] = Eq(copy _1, const 17_i8); + // CHECK: switchInt(move _1) -> [17: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: [[cast_1:_.*]] = copy [[b]] as i32 (IntToInt); + // CHECK: _0 = Add(const 100_i32, move [[cast_1]]); + // CHECK: [[BB2]]: + // CHECK: [[cast_2:_.*]] = copy [[b]] as i32 (IntToInt); + // CHECK: _0 = Add(const 10_i32, move [[cast_2]]); let b = a == 17; match b { false => 10 + b as i32, @@ -49,8 +99,16 @@ fn dont_remove_comparison(a: i8) -> i32 { } } +// EMIT_MIR if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff // test that we do not optimize on floats fn dont_opt_floats(a: f32) -> i32 { + // CHECK-LABEL: fn dont_opt_floats( + // CHECK: [[cmp:_.*]] = Eq(copy _1, const -42f32); + // CHECK: switchInt(move [[cmp]]) -> [0: [[BB2:bb.*]], otherwise: [[BB1:bb.*]]]; + // CHECK: [[BB1]]: + // CHECK: _0 = const 0_i32; + // CHECK: [[BB2]]: + // CHECK: _0 = const 1_i32; if a == -42.0 { 0 } else { 1 } } From 528fd2a33057644dd3aca50d04a626e4b1527948 Mon Sep 17 00:00:00 2001 From: dianqk Date: Sat, 10 Jan 2026 18:45:33 +0800 Subject: [PATCH 1930/3801] Add miscompiled test cases --- ...on_ssa_cmp.SimplifyComparisonIntegral.diff | 25 ++++++ ..._ssa_place.SimplifyComparisonIntegral.diff | 25 ++++++ ...ssa_switch.SimplifyComparisonIntegral.diff | 25 ++++++ tests/mir-opt/if_condition_int.rs | 81 +++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff create mode 100644 tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff create mode 100644 tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000000..d0983c660623 --- /dev/null +++ b/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff @@ -0,0 +1,25 @@ +- // MIR for `on_non_ssa_cmp` before SimplifyComparisonIntegral ++ // MIR for `on_non_ssa_cmp` after SimplifyComparisonIntegral + + fn on_non_ssa_cmp(_1: u64) -> i32 { + let mut _0: i32; + let mut _2: bool; + + bb0: { + _2 = Eq(copy _1, const 42_u64); + _1 = const 43_u64; +- switchInt(copy _2) -> [1: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; + } + + bb1: { + _0 = const 0_i32; + return; + } + + bb2: { + _0 = const 1_i32; + return; + } + } + diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000000..0c6c8dca4753 --- /dev/null +++ b/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff @@ -0,0 +1,25 @@ +- // MIR for `on_non_ssa_place` before SimplifyComparisonIntegral ++ // MIR for `on_non_ssa_place` after SimplifyComparisonIntegral + + fn on_non_ssa_place(_1: [u64; 10], _2: usize) -> i32 { + let mut _0: i32; + let mut _3: bool; + + bb0: { + _3 = Eq(copy _1[_2], const 42_u64); + _2 = const 10_usize; +- switchInt(copy _3) -> [1: bb1, otherwise: bb2]; ++ switchInt(move _1[_2]) -> [42: bb1, otherwise: bb2]; + } + + bb1: { + _0 = const 0_i32; + return; + } + + bb2: { + _0 = const 1_i32; + return; + } + } + diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff new file mode 100644 index 000000000000..b1b1ab2c2205 --- /dev/null +++ b/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff @@ -0,0 +1,25 @@ +- // MIR for `on_non_ssa_switch` before SimplifyComparisonIntegral ++ // MIR for `on_non_ssa_switch` after SimplifyComparisonIntegral + + fn on_non_ssa_switch(_1: u64) -> i32 { + let mut _0: i32; + let mut _2: bool; + + bb0: { + _2 = Eq(copy _1, const 42_u64); + _2 = const false; +- switchInt(copy _2) -> [1: bb1, otherwise: bb2]; ++ switchInt(move _1) -> [42: bb1, otherwise: bb2]; + } + + bb1: { + _0 = const 0_i32; + return; + } + + bb2: { + _0 = const 1_i32; + return; + } + } + diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs index 24ef6b85529e..ba901f6b9b15 100644 --- a/tests/mir-opt/if_condition_int.rs +++ b/tests/mir-opt/if_condition_int.rs @@ -2,6 +2,11 @@ // GVN simplifies FileCheck. //@ compile-flags: -Zmir-enable-passes=+GVN +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + // EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff fn opt_u32(x: u32) -> u32 { // CHECK-LABEL: fn opt_u32( @@ -112,6 +117,81 @@ fn dont_opt_floats(a: f32) -> i32 { if a == -42.0 { 0 } else { 1 } } +// EMIT_MIR if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff +#[custom_mir(dialect = "runtime")] +pub fn on_non_ssa_switch(mut v: u64) -> i32 { + mir! { + let a: bool; + { + a = v == 42; + a = false; + match a { + true => bb1, + _ => bb2, + } + + } + bb1 = { + RET = 0; + Return() + } + bb2 = { + RET = 1; + Return() + } + } +} + +// EMIT_MIR if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff +#[custom_mir(dialect = "runtime")] +pub fn on_non_ssa_cmp(mut v: u64) -> i32 { + mir! { + let a: bool; + { + a = v == 42; + v = 43; + match a { + true => bb1, + _ => bb2, + } + + } + bb1 = { + RET = 0; + Return() + } + bb2 = { + RET = 1; + Return() + } + } +} + +// EMIT_MIR if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff +#[custom_mir(dialect = "runtime")] +pub fn on_non_ssa_place(mut v: [u64; 10], mut i: usize) -> i32 { + mir! { + let a: bool; + { + a = v[i] == 42; + i = 10; + match a { + true => bb1, + _ => bb2, + } + + } + bb1 = { + RET = 0; + Return() + } + bb2 = { + RET = 1; + Return() + } + } +} + fn main() { opt_u32(0); opt_char('0'); @@ -121,4 +201,5 @@ fn main() { opt_multiple_ifs(0); dont_remove_comparison(11); dont_opt_floats(1.0); + on_non_ssa_switch(42); } From 76fcac23713815f214aba8d4751986d771f7f131 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sat, 10 Jan 2026 23:40:22 +0100 Subject: [PATCH 1931/3801] Port `#[rustc_has_incoherent_inherent_impls]` to attribute parser --- .../src/attributes/rustc_internal.rs | 15 +++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 13 +++++++------ compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../src/coherence/inherent_impls.rs | 7 +++++-- compiler/rustc_middle/src/ty/trait_def.rs | 6 +++--- compiler/rustc_passes/messages.ftl | 4 ---- compiler/rustc_passes/src/check_attr.rs | 15 +-------------- compiler/rustc_passes/src/errors.rs | 9 --------- 9 files changed, 35 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 922a5bd297ac..834b1d988cb4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -305,3 +305,18 @@ impl SingleAttributeParser for RustcScalableVectorParser { Some(AttributeKind::RustcScalableVector { element_count: Some(n), span: cx.attr_span }) } } + +pub(crate) struct RustcHasIncoherentInherentImplsParser; + +impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParser { + const PATH: &[Symbol] = &[sym::rustc_has_incoherent_inherent_impls]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Trait), + Allow(Target::Struct), + Allow(Target::Enum), + Allow(Target::Union), + Allow(Target::ForeignTy), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHasIncoherentInherentImpls; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index b85bb6c6c89d..513e6ad72b56 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -62,12 +62,12 @@ use crate::attributes::proc_macro_attrs::{ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ - RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, - RustcLintOptTyParser, RustcLintQueryInstabilityParser, - RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser, - RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, - RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, + RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser, + RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser, + RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, + RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, + RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser, + RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; @@ -264,6 +264,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 23201eff455f..c791f54902d1 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -880,6 +880,9 @@ pub enum AttributeKind { /// Represents `#[rustc_coherence_is_core]` RustcCoherenceIsCore(Span), + /// Represents `#[rustc_has_incoherent_inherent_impls]` + RustcHasIncoherentInherentImpls, + /// Represents `#[rustc_layout_scalar_valid_range_end]`. RustcLayoutScalarValidRangeEnd(Box, Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 3efa876ed6a9..4e1e9a074e66 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -95,6 +95,7 @@ impl AttributeKind { Repr { .. } => No, RustcBuiltinMacro { .. } => Yes, RustcCoherenceIsCore(..) => No, + RustcHasIncoherentInherentImpls => Yes, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 984a812246eb..fe47f3258846 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -15,7 +15,7 @@ use rustc_hir::find_attr; use rustc_middle::bug; use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams, simplify_type}; use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; -use rustc_span::{ErrorGuaranteed, sym}; +use rustc_span::ErrorGuaranteed; use crate::errors; @@ -79,7 +79,10 @@ impl<'tcx> InherentCollect<'tcx> { } if self.tcx.features().rustc_attrs() { - if !self.tcx.has_attr(ty_def_id, sym::rustc_has_incoherent_inherent_impls) { + if !find_attr!( + self.tcx.get_all_attrs(ty_def_id), + AttributeKind::RustcHasIncoherentInherentImpls + ) { let impl_span = self.tcx.def_span(impl_def_id); return Err(self.tcx.dcx().emit_err(errors::InherentTyOutside { span: impl_span })); } diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 691cb43b724a..2f6b38a619d2 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -2,11 +2,11 @@ use std::iter; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; -use rustc_hir as hir; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::{self as hir, find_attr}; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::symbol::sym; use tracing::debug; use crate::query::LocalCrate; @@ -241,7 +241,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait /// Query provider for `incoherent_impls`. pub(super) fn incoherent_impls_provider(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] { if let Some(def_id) = simp.def() - && !tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) + && !find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcHasIncoherentInherentImpls) { return &[]; } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 94996c0adb47..ba44aa3a35ab 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -244,10 +244,6 @@ passes_function_not_have_default_implementation = function doesn't have a defaul passes_functions_names_duplicated = functions names are duplicated .note = all `#[rustc_must_implement_one_of]` arguments must be unique -passes_has_incoherent_inherent_impl = - `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits - .label = only adts, extern types and traits are supported - passes_ignored_derived_impls = `{$name}` has {$trait_list_len -> [one] a derived impl diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2d3c5c7e48a0..360feacac0e9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -306,6 +306,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::CfgAttrTrace | AttributeKind::ThreadLocal | AttributeKind::CfiEncoding { .. } + | AttributeKind::RustcHasIncoherentInherentImpls ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -325,9 +326,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), - [sym::rustc_has_incoherent_inherent_impls, ..] => { - self.check_has_incoherent_inherent_impls(attr, span, target) - } [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => { self.check_autodiff(hir_id, attr, span, target) } @@ -1164,17 +1162,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_has_incoherent_inherent_impls(&self, attr: &Attribute, span: Span, target: Target) { - match target { - Target::Trait | Target::Struct | Target::Enum | Target::Union | Target::ForeignTy => {} - _ => { - self.tcx - .dcx() - .emit_err(errors::HasIncoherentInherentImpl { attr_span: attr.span(), span }); - } - } - } - fn check_ffi_pure(&self, attr_span: Span, attrs: &[Attribute]) { if find_attr!(attrs, AttributeKind::FfiConst(_)) { // `#[ffi_const]` functions cannot be `#[ffi_pure]` diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index af5cb29b83d0..14555765e423 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -187,15 +187,6 @@ pub(crate) struct DocAttrNotCrateLevel<'a> { pub attr_name: &'a str, } -#[derive(Diagnostic)] -#[diag(passes_has_incoherent_inherent_impl)] -pub(crate) struct HasIncoherentInherentImpl { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(passes_both_ffi_const_and_pure, code = E0757)] pub(crate) struct BothFfiConstAndPure { From 50813939e4d21a90cef22f42d4fb2d32600f2910 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 11 Jan 2026 12:04:46 +1100 Subject: [PATCH 1932/3801] Don't run the longer partial-sort tests under Miri --- library/alloctests/tests/sort/partial.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/alloctests/tests/sort/partial.rs b/library/alloctests/tests/sort/partial.rs index c7248990c70c..679841b91e8d 100644 --- a/library/alloctests/tests/sort/partial.rs +++ b/library/alloctests/tests/sort/partial.rs @@ -79,6 +79,10 @@ fn basic_impl() { fn random_patterns() { check_is_partial_sorted_ranges(&patterns::random(10)); check_is_partial_sorted_ranges(&patterns::random(50)); - check_is_partial_sorted_ranges(&patterns::random(100)); - check_is_partial_sorted_ranges(&patterns::random(1000)); + + // Longer tests would take hours to run under Miri. + if !cfg!(miri) { + check_is_partial_sorted_ranges(&patterns::random(100)); + check_is_partial_sorted_ranges(&patterns::random(1000)); + } } From 9e0a27cfa9a35e35a9065a2802a9b1620639845d Mon Sep 17 00:00:00 2001 From: mu001999 Date: Fri, 9 Jan 2026 19:31:53 +0800 Subject: [PATCH 1933/3801] Emit error instead of delayed bug when meeting mismatch type for const tuple --- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 5 +++-- .../const-generics/mgca/tuple_expr_arg_mismatch_type.rs | 8 ++++++++ .../mgca/tuple_expr_arg_mismatch_type.stderr | 8 ++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs create mode 100644 tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr 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 1dd9bff42575..f3b4e7a9072c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2502,11 +2502,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); let FeedConstTy::WithTy(ty) = feed else { - return Const::new_error_with_message(tcx, span, "unsupported const tuple"); + return Const::new_error_with_message(tcx, span, "const tuple lack type information"); }; let ty::Tuple(tys) = ty.kind() else { - return Const::new_error_with_message(tcx, span, "const tuple must have a tuple type"); + let e = tcx.dcx().span_err(span, format!("expected {}, found const tuple", ty)); + return Const::new_error(tcx, e); }; let exprs = exprs diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs new file mode 100644 index 000000000000..02807dfc302e --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs @@ -0,0 +1,8 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +pub fn takes_nested_tuple() { + takes_nested_tuple::<{ () }> //~ ERROR expected u32, found const tuple +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr new file mode 100644 index 000000000000..ad6db9e12373 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr @@ -0,0 +1,8 @@ +error: expected u32, found const tuple + --> $DIR/tuple_expr_arg_mismatch_type.rs:5:28 + | +LL | takes_nested_tuple::<{ () }> + | ^^ + +error: aborting due to 1 previous error + From 8ca1c9eb8fb16c97892a9628a6f94466d54ba24a Mon Sep 17 00:00:00 2001 From: mu001999 Date: Fri, 9 Jan 2026 19:32:23 +0800 Subject: [PATCH 1934/3801] Rename tests for const tuple properly --- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 +- ...rg_tuple_expr_complex.rs => tuple_expr_arg_complex.rs} | 0 ..._expr_complex.stderr => tuple_expr_arg_complex.stderr} | 8 ++++---- .../const-generics/mgca/tuple_expr_arg_mismatch_type.rs | 2 +- .../mgca/tuple_expr_arg_mismatch_type.stderr | 2 +- ..._arg_tuple_expr_simple.rs => tuple_expr_arg_simple.rs} | 0 6 files changed, 7 insertions(+), 7 deletions(-) rename tests/ui/const-generics/mgca/{adt_expr_arg_tuple_expr_complex.rs => tuple_expr_arg_complex.rs} (100%) rename tests/ui/const-generics/mgca/{adt_expr_arg_tuple_expr_complex.stderr => tuple_expr_arg_complex.stderr} (77%) rename tests/ui/const-generics/mgca/{adt_expr_arg_tuple_expr_simple.rs => tuple_expr_arg_simple.rs} (100%) 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 f3b4e7a9072c..4f610d2512a4 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2506,7 +2506,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; let ty::Tuple(tys) = ty.kind() else { - let e = tcx.dcx().span_err(span, format!("expected {}, found const tuple", ty)); + let e = tcx.dcx().span_err(span, format!("expected `{}`, found const tuple", ty)); return Const::new_error(tcx, e); }; diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs similarity index 100% rename from tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.rs rename to tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr similarity index 77% rename from tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr rename to tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr index dbc64a1bf59d..b294e1032ce8 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_complex.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr @@ -1,23 +1,23 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/adt_expr_arg_tuple_expr_complex.rs:13:25 + --> $DIR/tuple_expr_arg_complex.rs:13:25 | LL | takes_tuple::<{ (N, N + 1) }>(); | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/adt_expr_arg_tuple_expr_complex.rs:14:25 + --> $DIR/tuple_expr_arg_complex.rs:14:25 | LL | takes_tuple::<{ (N, T::ASSOC + 1) }>(); | ^^^^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/adt_expr_arg_tuple_expr_complex.rs:16:36 + --> $DIR/tuple_expr_arg_complex.rs:16:36 | LL | takes_nested_tuple::<{ (N, (N, N + 1)) }>(); | ^^^^^ error: generic parameters may not be used in const operations - --> $DIR/adt_expr_arg_tuple_expr_complex.rs:17:44 + --> $DIR/tuple_expr_arg_complex.rs:17:44 | LL | takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); | ^ diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs index 02807dfc302e..95acd66074f6 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs @@ -2,7 +2,7 @@ #![expect(incomplete_features)] pub fn takes_nested_tuple() { - takes_nested_tuple::<{ () }> //~ ERROR expected u32, found const tuple + takes_nested_tuple::<{ () }> //~ ERROR expected `u32`, found const tuple } fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr index ad6db9e12373..dfbd294951fd 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr @@ -1,4 +1,4 @@ -error: expected u32, found const tuple +error: expected `u32`, found const tuple --> $DIR/tuple_expr_arg_mismatch_type.rs:5:28 | LL | takes_nested_tuple::<{ () }> diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_simple.rs similarity index 100% rename from tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_simple.rs rename to tests/ui/const-generics/mgca/tuple_expr_arg_simple.rs From e40bd1cf6ece4bf9a2fb05474a20cd399694be93 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 11 Jan 2026 15:06:38 +0800 Subject: [PATCH 1935/3801] Add inherit attributes for extract_function assist Example --- ```rust #[cfg(test)] fn foo() { foo($01 + 1$0); } ``` **Before this PR** ```rust #[cfg(test)] fn foo() { foo(fun_name()); } fn $0fun_name() -> i32 { 1 + 1 } ``` **After this PR** ```rust #[cfg(test)] fn foo() { foo(fun_name()); } #[cfg(test)] fn $0fun_name() -> i32 { 1 + 1 } ``` --- .../src/handlers/extract_function.rs | 69 ++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 231df9b5b3e1..294e5f7da8b3 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -25,7 +25,7 @@ use syntax::{ SyntaxKind::{self, COMMENT}, SyntaxNode, SyntaxToken, T, TextRange, TextSize, TokenAtOffset, WalkEvent, ast::{ - self, AstNode, AstToken, HasGenericParams, HasName, edit::IndentLevel, + self, AstNode, AstToken, HasAttrs, HasGenericParams, HasName, edit::IndentLevel, edit_in_place::Indent, }, match_ast, ted, @@ -375,6 +375,7 @@ struct ContainerInfo<'db> { ret_type: Option>, generic_param_lists: Vec, where_clauses: Vec, + attrs: Vec, edition: Edition, } @@ -911,6 +912,7 @@ impl FunctionBody { let parents = generic_parents(&parent); let generic_param_lists = parents.iter().filter_map(|it| it.generic_param_list()).collect(); let where_clauses = parents.iter().filter_map(|it| it.where_clause()).collect(); + let attrs = parents.iter().flat_map(|it| it.attrs()).filter(is_inherit_attr).collect(); Some(( ContainerInfo { @@ -919,6 +921,7 @@ impl FunctionBody { ret_type: ty, generic_param_lists, where_clauses, + attrs, edition, }, contains_tail_expr, @@ -1103,6 +1106,14 @@ impl GenericParent { GenericParent::Trait(trait_) => trait_.where_clause(), } } + + fn attrs(&self) -> impl Iterator { + match self { + GenericParent::Fn(fn_) => fn_.attrs(), + GenericParent::Impl(impl_) => impl_.attrs(), + GenericParent::Trait(trait_) => trait_.attrs(), + } + } } /// Search `parent`'s ancestors for items with potentially applicable generic parameters @@ -1578,7 +1589,7 @@ fn format_function( let (generic_params, where_clause) = make_generic_params_and_where_clause(ctx, fun); make::fn_( - None, + fun.mods.attrs.clone(), None, fun_name, generic_params, @@ -1958,6 +1969,11 @@ fn format_type(ty: &hir::Type<'_>, ctx: &AssistContext<'_>, module: hir::Module) ty.display_source_code(ctx.db(), module.into(), true).ok().unwrap_or_else(|| "_".to_owned()) } +fn is_inherit_attr(attr: &ast::Attr) -> bool { + let Some(name) = attr.simple_name() else { return false }; + matches!(name.as_str(), "track_caller" | "cfg") +} + fn make_ty(ty: &hir::Type<'_>, ctx: &AssistContext<'_>, module: hir::Module) -> ast::Type { let ty_str = format_type(ty, ctx, module); make::ty(&ty_str) @@ -6372,6 +6388,55 @@ fn foo() { fn $0fun_name(mut a: i32, mut b: i32) { (a, b) = (b, a); } +"#, + ); + } + + #[test] + fn with_cfg_attr() { + check_assist( + extract_function, + r#" +//- /main.rs crate:main cfg:test +#[cfg(test)] +fn foo() { + foo($01 + 1$0); +} +"#, + r#" +#[cfg(test)] +fn foo() { + foo(fun_name()); +} + +#[cfg(test)] +fn $0fun_name() -> i32 { + 1 + 1 +} +"#, + ); + } + + #[test] + fn with_track_caller() { + check_assist( + extract_function, + r#" +#[track_caller] +fn foo() { + foo($01 + 1$0); +} +"#, + r#" +#[track_caller] +fn foo() { + foo(fun_name()); +} + +#[track_caller] +fn $0fun_name() -> i32 { + 1 + 1 +} "#, ); } From bd8c67c75ac1890c2cb9c31f658e0907cd50dab4 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sun, 11 Jan 2026 12:38:20 +0530 Subject: [PATCH 1936/3801] std: sys: fs: uefi: Implement copy - Using the implementation from sys::fs::common since ther is no built-in copy implementation in UEFI. - Tested with OVMF on QEMU. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index c416419bd008..b6bc14efdfb4 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -6,7 +6,7 @@ use crate::fs::TryLockError; use crate::hash::Hash; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::path::{Path, PathBuf}; -pub use crate::sys::fs::common::{Dir, remove_dir_all}; +pub use crate::sys::fs::common::{Dir, copy, remove_dir_all}; use crate::sys::pal::{helpers, unsupported}; use crate::sys::time::SystemTime; @@ -524,10 +524,6 @@ pub fn canonicalize(p: &Path) -> io::Result { crate::path::absolute(p) } -pub fn copy(_from: &Path, _to: &Path) -> io::Result { - unsupported() -} - fn set_perm_inner(f: &uefi_fs::File, perm: FilePermissions) -> io::Result<()> { let mut file_info = f.file_info()?; From ea93fb548c7c6e838b35893f3f9cc2ed3011aaea Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 11 Jan 2026 16:30:38 +0800 Subject: [PATCH 1937/3801] Underscore-prefixed bindings are explicitly allowed to be unused --- compiler/rustc_mir_transform/src/liveness.rs | 5 ++++ .../unused/underscore-capture-issue-149889.rs | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 tests/ui/lint/unused/underscore-capture-issue-149889.rs diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 1d1ba455a81e..a5a2fcd71a9a 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -1086,6 +1086,11 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> { let Some((name, decl_span)) = self.checked_places.names[index] else { continue }; + // By convention, underscore-prefixed bindings are explicitly allowed to be unused. + if name.as_str().starts_with('_') { + continue; + } + let is_maybe_drop_guard = maybe_drop_guard( tcx, self.typing_env, diff --git a/tests/ui/lint/unused/underscore-capture-issue-149889.rs b/tests/ui/lint/unused/underscore-capture-issue-149889.rs new file mode 100644 index 000000000000..3fbaf2588516 --- /dev/null +++ b/tests/ui/lint/unused/underscore-capture-issue-149889.rs @@ -0,0 +1,29 @@ +//@ check-pass +#![deny(unused_assignments)] + +fn lock() -> impl Drop { + struct Handle; + + impl Drop for Handle { + fn drop(&mut self) {} + } + + Handle +} + +fn bar(_f: impl FnMut(bool)) {} + +pub fn foo() { + let mut _handle = None; + bar(move |l| { + if l { + _handle = Some(lock()); + } else { + _handle = None; + } + }) +} + +fn main() { + foo(); +} From faea581d45ce89968064788c43fa45524c10c89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 11 Jan 2026 10:35:13 +0100 Subject: [PATCH 1938/3801] Remove references to bors2 --- src/ci/github-actions/jobs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 9acad5c06b21..7411b394b94a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -152,8 +152,8 @@ try: - <<: *job-dist-x86_64-linux # Jobs that only run when explicitly invoked in one of the following ways: -# - comment `@bors2 try jobs=` -# - `try-job: ` in the PR description and comment `@bors try` or `@bors2 try`. +# - comment `@bors try jobs=` +# - `try-job: ` in the PR description and comment `@bors try`. optional: # This job is used just to test optional jobs. # It will be replaced by tier 2 and tier 3 jobs in the future. From 8150413bf5c1327c0a58b544662b50e5ef4bedc2 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 7 Jan 2026 17:19:33 +0530 Subject: [PATCH 1939/3801] add byte range subrequest/response --- .../crates/proc-macro-api/src/bidirectional_protocol/msg.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 0e3b700dcc5a..57e7b1ee8f68 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -1,5 +1,7 @@ //! Bidirectional protocol messages +use std::ops::Range; + use paths::Utf8PathBuf; use serde::{Deserialize, Serialize}; @@ -14,6 +16,7 @@ pub enum SubRequest { SourceText { file_id: u32, ast_id: u32, start: u32, end: u32 }, LocalFilePath { file_id: u32 }, LineColumn { file_id: u32, ast_id: u32, offset: u32 }, + ByteRange { file_id: u32, ast_id: u32, start: u32, end: u32 }, } #[derive(Debug, Serialize, Deserialize)] @@ -32,6 +35,9 @@ pub enum SubResponse { line: u32, column: u32, }, + ByteRangeResult { + range: Range, + }, } #[derive(Debug, Serialize, Deserialize)] From e909b4b28286d914c1d67f12f419cf1ed88daa8d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 7 Jan 2026 17:20:06 +0530 Subject: [PATCH 1940/3801] update proc-macro-srv to include byte-range --- src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs | 3 +++ .../proc-macro-srv/src/server_impl/rust_analyzer_span.rs | 5 ++++- .../rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index c1ef49a7176b..ac9f89352c2b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -41,6 +41,7 @@ use std::{ env, ffi::OsString, fs, + ops::Range, path::{Path, PathBuf}, sync::{Arc, Mutex, PoisonError}, thread, @@ -100,6 +101,8 @@ pub trait ProcMacroClientInterface { fn local_file(&mut self, file_id: span::FileId) -> Option; /// Line and column are 1-based. fn line_column(&mut self, span: Span) -> Option<(u32, u32)>; + + fn byte_range(&mut self, span: Span) -> Range; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 3a25391b573b..9946608247c3 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -162,7 +162,10 @@ impl server::Span for RaSpanServer<'_> { span } fn byte_range(&mut self, span: Self::Span) -> Range { - // FIXME requires db to resolve the ast id, THIS IS NOT INCREMENTAL + if let Some(cb) = self.callback.as_mut() { + return cb.byte_range(span); + } + Range { start: span.range.start().into(), end: span.range.end().into() } } fn join(&mut self, first: Self::Span, second: Self::Span) -> Option { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs index 81ff1965d68b..b7c5c4fdd21f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs @@ -4,6 +4,7 @@ use expect_test::Expect; use span::{ EditionedFileId, FileId, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext, TextRange, }; +use std::ops::Range; use crate::{ EnvSnapshot, ProcMacroClientInterface, ProcMacroSrv, SpanId, dylib, proc_macro_test_dylib_path, @@ -137,6 +138,10 @@ impl ProcMacroClientInterface for MockCallback<'_> { // proc_macro uses 1-based line/column Some((line_col.line as u32 + 1, line_col.col as u32 + 1)) } + + fn byte_range(&mut self, span: Span) -> Range { + Range { start: span.range.start().into(), end: span.range.end().into() } + } } pub fn assert_expand_with_callback( From e68a654dca8b43e4f430485249fdef00ed9d85a7 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 7 Jan 2026 17:20:37 +0530 Subject: [PATCH 1941/3801] add byte range to main loop and direct the request via callback and define the callback on client side --- .../crates/load-cargo/src/lib.rs | 10 ++++++++++ .../proc-macro-srv-cli/src/main_loop.rs | 19 ++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 33468a5003c3..904f704221cf 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -591,6 +591,16 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::FilePathResult { name }) } + SubRequest::ByteRange { file_id, ast_id, start, end } => { + let range = resolve_sub_span( + db, + file_id, + ast_id, + TextRange::new(TextSize::from(start), TextSize::from(end)), + ); + + Ok(SubResponse::ByteRangeResult { range: range.range.into() }) + } }; match self.0.expand( subtree.view(), diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 0c651d22b41b..e35f832716dd 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -6,7 +6,7 @@ use proc_macro_api::{ transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; -use std::io::{self, BufRead, Write}; +use std::{io, ops::Range}; use legacy::Message; @@ -240,6 +240,23 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl _ => None, } } + + fn byte_range( + &mut self, + proc_macro_srv::span::Span { range, anchor, ctx: _ }: proc_macro_srv::span::Span, + ) -> Range { + match self.roundtrip(bidirectional::SubRequest::ByteRange { + file_id: anchor.file_id.as_u32(), + ast_id: anchor.ast_id.into_raw(), + start: range.start().into(), + end: range.end().into(), + }) { + Some(bidirectional::BidirectionalMessage::SubResponse( + bidirectional::SubResponse::ByteRangeResult { range }, + )) => range, + _ => Range { start: range.start().into(), end: range.end().into() }, + } + } } fn handle_expand_ra( From 78d243c751e420c38c3a92f707aae78bafc8ad1e Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 8 Jan 2026 22:43:03 +0530 Subject: [PATCH 1942/3801] add comment on incrementality of subrequest --- src/tools/rust-analyzer/crates/load-cargo/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 904f704221cf..8342492a33a4 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -553,6 +553,7 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::LocalFilePathResult { name }) } + // Not incremental: requires full file text. SubRequest::SourceText { file_id, ast_id, start, end } => { let range = resolve_sub_span( db, @@ -567,6 +568,7 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::SourceTextResult { text }) } + // Not incremental: requires building line index. SubRequest::LineColumn { file_id, ast_id, offset } => { let range = resolve_sub_span(db, file_id, ast_id, TextRange::empty(TextSize::from(offset))); @@ -591,6 +593,7 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::FilePathResult { name }) } + // Not incremental: requires global span resolution. SubRequest::ByteRange { file_id, ast_id, start, end } => { let range = resolve_sub_span( db, From 47b987eccb7c2defece8f053c197836784baf421 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 11 Jan 2026 10:15:05 +0100 Subject: [PATCH 1943/3801] Do not show spans from external crates in `missing_trait_methods` Pointing to the missing method definition in external crates will use paths which depend on the system, and even on the Rust compiler version used when the iterator is defined in the standard library. When the trait being implemented and whose method is missing is external, point only to the trait implementation. The user will be able to figure out, or even navigate using their IDE, to the proper definition. As a side-effect, this will remove a large lintcheck churn at every Rustup for this lint. --- clippy_lints/src/missing_trait_methods.rs | 10 +++++++++- tests/ui/missing_trait_methods.rs | 7 +++++++ tests/ui/missing_trait_methods.stderr | 10 +++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/missing_trait_methods.rs b/clippy_lints/src/missing_trait_methods.rs index 8e9400e9d583..7a791f949943 100644 --- a/clippy_lints/src/missing_trait_methods.rs +++ b/clippy_lints/src/missing_trait_methods.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_lint_allowed; use clippy_utils::macros::span_is_local; +use clippy_utils::source::snippet_opt; use rustc_hir::def_id::DefIdSet; use rustc_hir::{Impl, Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -84,7 +85,14 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods { cx.tcx.def_span(item.owner_id), format!("missing trait method provided by default: `{}`", assoc.name()), |diag| { - diag.span_help(cx.tcx.def_span(assoc.def_id), "implement the method"); + if assoc.def_id.is_local() { + diag.span_help(cx.tcx.def_span(assoc.def_id), "implement the method"); + } else if let Some(snippet) = snippet_opt(cx, of_trait.trait_ref.path.span) { + diag.help(format!( + "implement the missing `{}` method of the `{snippet}` trait", + assoc.name(), + )); + } }, ); } diff --git a/tests/ui/missing_trait_methods.rs b/tests/ui/missing_trait_methods.rs index 7af186ba3322..67070a299951 100644 --- a/tests/ui/missing_trait_methods.rs +++ b/tests/ui/missing_trait_methods.rs @@ -62,3 +62,10 @@ impl MissingMultiple for Partial {} //~| missing_trait_methods fn main() {} + +//~v missing_trait_methods +impl PartialEq for Partial { + fn eq(&self, other: &Partial) -> bool { + todo!() + } +} diff --git a/tests/ui/missing_trait_methods.stderr b/tests/ui/missing_trait_methods.stderr index d9fb8951ab3d..e5155ad587cb 100644 --- a/tests/ui/missing_trait_methods.stderr +++ b/tests/ui/missing_trait_methods.stderr @@ -60,5 +60,13 @@ help: implement the method LL | fn three() {} | ^^^^^^^^^^ -error: aborting due to 5 previous errors +error: missing trait method provided by default: `ne` + --> tests/ui/missing_trait_methods.rs:67:1 + | +LL | impl PartialEq for Partial { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: implement the missing `ne` method of the `PartialEq` trait + +error: aborting due to 6 previous errors From b5dd72d2921500c9d9e15f074e1d831adcaa3dee Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 10 Jan 2026 23:06:07 +0100 Subject: [PATCH 1944/3801] Port `#[collapse_debuginfo]` to the new attribute parsing system --- .../src/attributes/macro_attrs.rs | 45 ++++++++++++++++- compiler/rustc_attr_parsing/src/context.rs | 4 +- compiler/rustc_expand/messages.ftl | 3 -- compiler/rustc_expand/src/base.rs | 49 +++++-------------- compiler/rustc_expand/src/errors.rs | 7 --- .../rustc_hir/src/attrs/data_structures.rs | 23 +++++++++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_interface/src/tests.rs | 14 +++--- compiler/rustc_passes/messages.ftl | 4 -- compiler/rustc_passes/src/check_attr.rs | 14 +----- compiler/rustc_passes/src/errors.rs | 9 ---- compiler/rustc_session/src/config.rs | 33 +++---------- compiler/rustc_session/src/options.rs | 1 + 13 files changed, 98 insertions(+), 109 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 0f1ab02fca25..d37915b1b80b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -1,4 +1,4 @@ -use rustc_hir::attrs::MacroUseArgs; +use rustc_hir::attrs::{CollapseMacroDebuginfo, MacroUseArgs}; use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS; use super::prelude::*; @@ -163,3 +163,46 @@ impl SingleAttributeParser for MacroExportParser { Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros }) } } + +pub(crate) struct CollapseDebugInfoParser; + +impl SingleAttributeParser for CollapseDebugInfoParser { + const PATH: &[Symbol] = &[sym::collapse_debuginfo]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!( + List: &["no", "external", "yes"], + "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute" + ); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(list) = args.list() else { + cx.expected_list(cx.attr_span, args); + return None; + }; + let Some(single) = list.single() else { + cx.expected_single_argument(list.span); + return None; + }; + let Some(mi) = single.meta_item() else { + cx.unexpected_literal(single.span()); + return None; + }; + if let Err(err) = mi.args().no_args() { + cx.expected_no_args(err); + } + let path = mi.path().word_sym(); + let info = match path { + Some(sym::yes) => CollapseMacroDebuginfo::Yes, + Some(sym::no) => CollapseMacroDebuginfo::No, + Some(sym::external) => CollapseMacroDebuginfo::External, + _ => { + cx.expected_specific_argument(mi.span(), &[sym::yes, sym::no, sym::external]); + return None; + } + }; + + Some(AttributeKind::CollapseDebugInfo(info)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index b85bb6c6c89d..114dacd8c795 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -48,7 +48,8 @@ use crate::attributes::lint_helpers::{ }; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::macro_attrs::{ - AllowInternalUnsafeParser, MacroEscapeParser, MacroExportParser, MacroUseParser, + AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser, + MacroUseParser, }; use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; @@ -191,6 +192,7 @@ attribute_parsers!( // tidy-alphabetical-start Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index 6c23320a1b11..851d78e0b105 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -5,9 +5,6 @@ expand_attributes_on_expressions_experimental = expand_cfg_attr_no_attributes = `#[cfg_attr]` does not expand to any attributes -expand_collapse_debuginfo_illegal = - illegal value for attribute #[collapse_debuginfo(no|external|yes)] - expand_count_repetition_misplaced = `count` can not be placed inside the innermost repetition diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 946f17943fe3..bf653fac5253 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -6,7 +6,7 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::Arc; -use rustc_ast::attr::{AttributeExt, MarkedAttrs}; +use rustc_ast::attr::MarkedAttrs; use rustc_ast::token::MetaVarKind; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{AssocCtxt, Visitor}; @@ -16,7 +16,7 @@ use rustc_data_structures::sync; use rustc_errors::{BufferedEarlyLint, DiagCtxtHandle, ErrorGuaranteed, PResult}; use rustc_feature::Features; use rustc_hir as hir; -use rustc_hir::attrs::{AttributeKind, CfgEntry, Deprecation}; +use rustc_hir::attrs::{AttributeKind, CfgEntry, CollapseMacroDebuginfo, Deprecation}; use rustc_hir::def::MacroKinds; use rustc_hir::limit::Limit; use rustc_hir::{Stability, find_attr}; @@ -24,7 +24,6 @@ use rustc_lint_defs::RegisteredTools; use rustc_parse::MACRO_ARGUMENTS; use rustc_parse::parser::{ForceCollect, Parser}; use rustc_session::Session; -use rustc_session::config::CollapseMacroDebuginfo; use rustc_session::parse::ParseSess; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; @@ -34,7 +33,6 @@ use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; -use crate::base::ast::MetaItemInner; use crate::errors; use crate::expand::{self, AstFragment, Invocation}; use crate::mbe::macro_rules::ParserAnyMacro; @@ -887,25 +885,6 @@ impl SyntaxExtension { } } - fn collapse_debuginfo_by_name( - attr: &impl AttributeExt, - ) -> Result { - let list = attr.meta_item_list(); - let Some([MetaItemInner::MetaItem(item)]) = list.as_deref() else { - return Err(attr.span()); - }; - if !item.is_word() { - return Err(item.span); - } - - match item.name() { - Some(sym::no) => Ok(CollapseMacroDebuginfo::No), - Some(sym::external) => Ok(CollapseMacroDebuginfo::External), - Some(sym::yes) => Ok(CollapseMacroDebuginfo::Yes), - _ => Err(item.path.span), - } - } - /// if-ext - if macro from different crate (related to callsite code) /// | cmd \ attr | no | (unspecified) | external | yes | /// | no | no | no | no | no | @@ -914,21 +893,15 @@ impl SyntaxExtension { /// | yes | yes | yes | yes | yes | fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool { let flag = sess.opts.cg.collapse_macro_debuginfo; - let attr = ast::attr::find_by_name(attrs, sym::collapse_debuginfo) - .and_then(|attr| { - Self::collapse_debuginfo_by_name(attr) - .map_err(|span| { - sess.dcx().emit_err(errors::CollapseMacroDebuginfoIllegal { span }) - }) - .ok() - }) - .unwrap_or_else(|| { - if find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) { - CollapseMacroDebuginfo::Yes - } else { - CollapseMacroDebuginfo::Unspecified - } - }); + let attr = + if let Some(info) = find_attr!(attrs, AttributeKind::CollapseDebugInfo(info) => info) { + info.clone() + } else if find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) { + CollapseMacroDebuginfo::Yes + } else { + CollapseMacroDebuginfo::Unspecified + }; + #[rustfmt::skip] let collapse_table = [ [false, false, false, false], diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 6bae16b3bba1..9f9764e060d1 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -78,13 +78,6 @@ pub(crate) struct ResolveRelativePath { pub path: String, } -#[derive(Diagnostic)] -#[diag(expand_collapse_debuginfo_illegal)] -pub(crate) struct CollapseMacroDebuginfoIllegal { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(expand_macro_const_stability)] pub(crate) struct MacroConstStability { diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 23201eff455f..25d6950c823d 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -568,6 +568,26 @@ impl rustc_serialize::Encodable for DocAttribute } } +/// How to perform collapse macros debug info +/// if-ext - if macro from different crate (related to callsite code) +/// | cmd \ attr | no | (unspecified) | external | yes | +/// | no | no | no | no | no | +/// | (unspecified) | no | no | if-ext | yes | +/// | external | no | if-ext | if-ext | yes | +/// | yes | yes | yes | yes | yes | +#[derive(Copy, Clone, Debug, Hash, PartialEq)] +#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub enum CollapseMacroDebuginfo { + /// Don't collapse debuginfo for the macro + No = 0, + /// Unspecified value + Unspecified = 1, + /// Collapse debuginfo if the macro comes from a different crate + External = 2, + /// Collapse debuginfo for the macro + Yes = 3, +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -664,6 +684,9 @@ pub enum AttributeKind { /// Represents `#[cold]`. Cold(Span), + /// Represents `#[collapse_debuginfo]`. + CollapseDebugInfo(CollapseMacroDebuginfo), + /// Represents `#[rustc_confusables]`. Confusables { symbols: ThinVec, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 3efa876ed6a9..aa042ac10be4 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -31,6 +31,7 @@ impl AttributeKind { CfiEncoding { .. } => Yes, Coinductive(..) => No, Cold(..) => No, + CollapseDebugInfo(..) => Yes, Confusables { .. } => Yes, ConstContinue(..) => No, ConstStability { .. } => Yes, diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d075f94ef850..a78b0e8e1ed8 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -8,14 +8,14 @@ use rustc_abi::Align; use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, registry}; -use rustc_hir::attrs::NativeLibKind; +use rustc_hir::attrs::{CollapseMacroDebuginfo, NativeLibKind}; use rustc_session::config::{ - AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel, - CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, - Externs, FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, - InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, - NextSolverConfig, Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, - Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, + AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CoverageLevel, CoverageOptions, + DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, + FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, + LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig, + Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, + PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options, rustc_optgroups, }; diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 94996c0adb47..9257802d6194 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -55,10 +55,6 @@ passes_change_fields_to_be_of_unit_type = *[other] fields } -passes_collapse_debuginfo = - `collapse_debuginfo` attribute should be applied to macro definitions - .label = not a macro definition - passes_const_continue_attr = `#[const_continue]` should be applied to a break expression .label = not a break expression diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2d3c5c7e48a0..96bd976e5f6a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -229,6 +229,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect | AttributeKind::MacroTransparency(_) + | AttributeKind::CollapseDebugInfo(..) | AttributeKind::CfgTrace(..) | AttributeKind::Pointee(..) | AttributeKind::Dummy @@ -323,7 +324,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), - [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), [sym::rustc_has_incoherent_inherent_impls, ..] => { self.check_has_incoherent_inherent_impls(attr, span, target) @@ -718,18 +718,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } } - /// Checks if `#[collapse_debuginfo]` is applied to a macro. - fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target) { - match target { - Target::MacroDef => {} - _ => { - self.tcx.dcx().emit_err(errors::CollapseDebuginfo { - attr_span: attr.span(), - defn_span: span, - }); - } - } - } /// Checks if a `#[track_caller]` is applied to a function. fn check_track_caller( diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index af5cb29b83d0..382eab805354 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -384,15 +384,6 @@ pub(crate) struct UnusedMultiple { pub name: Symbol, } -#[derive(Diagnostic)] -#[diag(passes_collapse_debuginfo)] -pub(crate) struct CollapseDebuginfo { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - #[derive(LintDiagnostic)] #[diag(passes_deprecated_annotation_has_no_effect)] pub(crate) struct DeprecatedAnnotationHasNoEffect { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8c492fcf8f15..f0dc5b9ac48c 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3065,6 +3065,7 @@ pub(crate) mod dep_tracking { use rustc_errors::LanguageIdentifier; use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; + use rustc_hir::attrs::CollapseMacroDebuginfo; use rustc_span::edition::Edition; use rustc_span::{RealFileName, RemapPathScopeComponents}; use rustc_target::spec::{ @@ -3074,13 +3075,12 @@ pub(crate) mod dep_tracking { }; use super::{ - AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, - CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, - FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, - LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, - OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, - SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, - WasiExecModel, + AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions, + CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn, + InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, + LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType, + OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm, + SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; @@ -3299,25 +3299,6 @@ pub enum ProcMacroExecutionStrategy { CrossThread, } -/// How to perform collapse macros debug info -/// if-ext - if macro from different crate (related to callsite code) -/// | cmd \ attr | no | (unspecified) | external | yes | -/// | no | no | no | no | no | -/// | (unspecified) | no | no | if-ext | yes | -/// | external | no | if-ext | if-ext | yes | -/// | yes | yes | yes | yes | yes | -#[derive(Clone, Copy, PartialEq, Hash, Debug)] -pub enum CollapseMacroDebuginfo { - /// Don't collapse debuginfo for the macro - No = 0, - /// Unspecified value - Unspecified = 1, - /// Collapse debuginfo if the macro comes from a different crate - External = 2, - /// Collapse debuginfo for the macro - Yes = 3, -} - /// Which format to use for `-Z dump-mono-stats` #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum DumpMonoStatsFormat { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 21fa3321a30a..99ab13403812 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -10,6 +10,7 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_errors::{ColorConfig, LanguageIdentifier, TerminalUrl}; use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; +use rustc_hir::attrs::CollapseMacroDebuginfo; use rustc_macros::{BlobDecodable, Encodable}; use rustc_span::edition::Edition; use rustc_span::{RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm}; From f0da7832b7956c29596c64a3a09e3e556a870d4a Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 10 Jan 2026 23:07:20 +0100 Subject: [PATCH 1945/3801] Update uitests --- .../attributes/collapse-debuginfo-invalid.rs | 44 ++-- .../collapse-debuginfo-invalid.stderr | 223 +++++++----------- 2 files changed, 112 insertions(+), 155 deletions(-) diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.rs b/tests/ui/attributes/collapse-debuginfo-invalid.rs index ccf11df2eb0d..e467c72f52c0 100644 --- a/tests/ui/attributes/collapse-debuginfo-invalid.rs +++ b/tests/ui/attributes/collapse-debuginfo-invalid.rs @@ -5,80 +5,80 @@ // Test that the `#[collapse_debuginfo]` attribute can only be used on macro definitions. #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on extern crate std; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on use std::collections::HashMap; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on static FOO: u32 = 3; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on const BAR: u32 = 3; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on fn foo() { let _ = #[collapse_debuginfo(yes)] || { }; - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on let _ = 3; let _ = #[collapse_debuginfo(yes)] 3; - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on match (3, 4) { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on _ => (), } } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on mod bar { } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on type Map = HashMap; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on enum Foo { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on Variant, } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on struct Bar { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on field: u32, } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on union Qux { a: u32, b: u16 } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on trait Foobar { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on type Bar; } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on type AFoobar = impl Foobar; impl Foobar for Bar { @@ -91,14 +91,14 @@ fn constraining() -> AFoobar { } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on impl Bar { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on const FOO: u32 = 3; #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on fn bar(&self) {} } diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.stderr b/tests/ui/attributes/collapse-debuginfo-invalid.stderr index 081e4445a869..d66e334c993c 100644 --- a/tests/ui/attributes/collapse-debuginfo-invalid.stderr +++ b/tests/ui/attributes/collapse-debuginfo-invalid.stderr @@ -1,221 +1,178 @@ -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on extern crates --> $DIR/collapse-debuginfo-invalid.rs:7:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | extern crate std; - | ----------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on use statements --> $DIR/collapse-debuginfo-invalid.rs:11:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | use std::collections::HashMap; - | ------------------------------ not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on statics --> $DIR/collapse-debuginfo-invalid.rs:15:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | static FOO: u32 = 3; - | -------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on constants --> $DIR/collapse-debuginfo-invalid.rs:19:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | const BAR: u32 = 3; - | ------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on functions --> $DIR/collapse-debuginfo-invalid.rs:23:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / fn foo() { -LL | | let _ = #[collapse_debuginfo(yes)] || { }; -LL | | -LL | | #[collapse_debuginfo(yes)] -... | -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on closures --> $DIR/collapse-debuginfo-invalid.rs:26:13 | LL | let _ = #[collapse_debuginfo(yes)] || { }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on statements --> $DIR/collapse-debuginfo-invalid.rs:28:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | let _ = 3; - | ---------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on expressions --> $DIR/collapse-debuginfo-invalid.rs:31:13 | LL | let _ = #[collapse_debuginfo(yes)] 3; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - not a macro definition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on match arms --> $DIR/collapse-debuginfo-invalid.rs:34:9 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | _ => (), - | ------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on modules --> $DIR/collapse-debuginfo-invalid.rs:40:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / mod bar { -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on type aliases --> $DIR/collapse-debuginfo-invalid.rs:45:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | type Map = HashMap; - | ----------------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on enums --> $DIR/collapse-debuginfo-invalid.rs:49:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / enum Foo { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | Variant, -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on enum variants --> $DIR/collapse-debuginfo-invalid.rs:52:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | Variant, - | ------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on structs --> $DIR/collapse-debuginfo-invalid.rs:57:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / struct Bar { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | field: u32, -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on struct fields --> $DIR/collapse-debuginfo-invalid.rs:60:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | field: u32, - | ---------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on unions --> $DIR/collapse-debuginfo-invalid.rs:65:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / union Qux { -LL | | a: u32, -LL | | b: u16 -LL | | } - | |_- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:72:1 - | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / trait Foobar { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | type Bar; -LL | | } - | |_- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:80:1 - | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | type AFoobar = impl Foobar; - | --------------------------- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:93:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / impl Bar { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | const FOO: u32 = 3; -... | -LL | | fn bar(&self) {} -LL | | } - | |_- not a macro definition + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on traits + --> $DIR/collapse-debuginfo-invalid.rs:72:1 + | +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on associated types --> $DIR/collapse-debuginfo-invalid.rs:75:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | type Bar; - | --------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on type aliases + --> $DIR/collapse-debuginfo-invalid.rs:80:1 + | +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on inherent impl blocks + --> $DIR/collapse-debuginfo-invalid.rs:93:1 + | +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on associated consts --> $DIR/collapse-debuginfo-invalid.rs:96:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | const FOO: u32 = 3; - | ------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on inherent methods --> $DIR/collapse-debuginfo-invalid.rs:100:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | fn bar(&self) {} - | ---------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs error: aborting due to 22 previous errors From d30f7c9f7c8c375c2b806b770dd11f3d481979e9 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 11 Jan 2026 15:51:33 +0530 Subject: [PATCH 1946/3801] add write read imports --- .../rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index e35f832716dd..3beaeb0697ec 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -6,7 +6,10 @@ use proc_macro_api::{ transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; -use std::{io, ops::Range}; +use std::{ + io::{self, BufRead, Write}, + ops::Range, +}; use legacy::Message; From cf580b8e2b23fd0c51935664678227d2ba10127f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 11 Jan 2026 10:38:58 +0100 Subject: [PATCH 1947/3801] Revert bors email to the original homu one --- src/build_helper/src/git.rs | 19 ++++++++++--------- src/stage0 | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 1fdc2ddb4cfc..330fb465de42 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -152,7 +152,10 @@ pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool { }) } -const LEGACY_BORS_EMAIL: &str = "bors@rust-lang.org"; +// Temporary e-mail used by new bors for merge commits for a few days, until it learned how to reuse +// the original homu e-mail +// FIXME: remove in Q2 2026 +const TEMPORARY_BORS_EMAIL: &str = "122020455+rust-bors[bot]@users.noreply.github.com"; /// Escape characters from the git user e-mail, so that git commands do not interpret it as regex /// special characters. @@ -193,10 +196,9 @@ fn get_latest_upstream_commit_that_modified_files( &escape_email_git_regex(git_config.git_merge_commit_email), ]); - // Also search for legacy bors account, before we accrue enough commits to - // have changes to all relevant file paths done by new bors. - if git_config.git_merge_commit_email != LEGACY_BORS_EMAIL { - git.args(["--author", LEGACY_BORS_EMAIL]); + // Also search for temporary bors account + if git_config.git_merge_commit_email != TEMPORARY_BORS_EMAIL { + git.args(["--author", &escape_email_git_regex(TEMPORARY_BORS_EMAIL)]); } if !target_paths.is_empty() { @@ -248,10 +250,9 @@ pub fn get_closest_upstream_commit( base, ]); - // Also search for legacy bors account, before we accrue enough commits to - // have changes to all relevant file paths done by new bors. - if config.git_merge_commit_email != LEGACY_BORS_EMAIL { - git.args(["--author", LEGACY_BORS_EMAIL]); + // Also search for temporary bors account + if config.git_merge_commit_email != TEMPORARY_BORS_EMAIL { + git.args(["--author", &escape_email_git_regex(TEMPORARY_BORS_EMAIL)]); } let output = output_result(&mut git)?.trim().to_owned(); diff --git a/src/stage0 b/src/stage0 index 226f1d6f645e..66b652a844f3 100644 --- a/src/stage0 +++ b/src/stage0 @@ -1,7 +1,7 @@ dist_server=https://static.rust-lang.org artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt -git_merge_commit_email=122020455+rust-bors[bot]@users.noreply.github.com +git_merge_commit_email=bors@rust-lang.org nightly_branch=main # The configuration above this comment is editable, and can be changed From ad713ab666f97dcc4585aaad0344493926f9c4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 11 Jan 2026 10:40:40 +0100 Subject: [PATCH 1948/3801] Use both bors e-mails for CI postprocessing git lookup --- .github/workflows/ci.yml | 2 +- .github/workflows/post-merge.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8963039dd50b..2458eb5fafb1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -289,7 +289,7 @@ jobs: fi # Get closest bors merge commit - PARENT_COMMIT=`git rev-list --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` + PARENT_COMMIT=`git rev-list --author='bors@rust-lang.org' --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` ./build/citool/debug/citool postprocess-metrics \ --job-name ${CI_JOB_NAME} \ diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 51e0a40d46f2..c3d9217a645b 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -29,7 +29,7 @@ jobs: sleep 60 # Get closest bors merge commit - PARENT_COMMIT=`git rev-list --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` + PARENT_COMMIT=`git rev-list --author='bors@rust-lang.org' --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` echo "Parent: ${PARENT_COMMIT}" # Find PR for the current commit From d772c3d99d41d1f44a23ab5256e2fbf62b589b03 Mon Sep 17 00:00:00 2001 From: Tristan Guichaoua Date: Sun, 11 Jan 2026 12:05:49 +0100 Subject: [PATCH 1949/3801] add freeze file times on Windows --- library/std/src/os/windows/fs.rs | 22 ++++++++++++++++++++++ library/std/src/sys/fs/windows.rs | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs index b445f368aeb1..95a4ea53ce1e 100644 --- a/library/std/src/os/windows/fs.rs +++ b/library/std/src/os/windows/fs.rs @@ -305,6 +305,18 @@ pub trait OpenOptionsExt { /// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level #[stable(feature = "open_options_ext", since = "1.10.0")] fn security_qos_flags(&mut self, flags: u32) -> &mut Self; + + /// If set to `true`, prevent the "last access time" of the file from being changed. + /// + /// Default to `false`. + #[unstable(feature = "windows_freeze_file_times", issue = "149715")] + fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self; + + /// If set to `true`, prevent the "last write time" of the file from being changed. + /// + /// Default to `false`. + #[unstable(feature = "windows_freeze_file_times", issue = "149715")] + fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self; } #[stable(feature = "open_options_ext", since = "1.10.0")] @@ -333,6 +345,16 @@ impl OpenOptionsExt for OpenOptions { self.as_inner_mut().security_qos_flags(flags); self } + + fn freeze_last_access_time(&mut self, freeze: bool) -> &mut Self { + self.as_inner_mut().freeze_last_access_time(freeze); + self + } + + fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self { + self.as_inner_mut().freeze_last_write_time(freeze); + self + } } /// Windows-specific extensions to [`fs::Metadata`]. diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index f2d325da35c7..e214284a03a7 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -81,6 +81,8 @@ pub struct OpenOptions { share_mode: u32, security_qos_flags: u32, inherit_handle: bool, + freeze_last_access_time: bool, + freeze_last_write_time: bool, } #[derive(Clone, PartialEq, Eq, Debug)] @@ -204,6 +206,8 @@ impl OpenOptions { attributes: 0, security_qos_flags: 0, inherit_handle: false, + freeze_last_access_time: false, + freeze_last_write_time: false, } } @@ -246,6 +250,12 @@ impl OpenOptions { pub fn inherit_handle(&mut self, inherit: bool) { self.inherit_handle = inherit; } + pub fn freeze_last_access_time(&mut self, freeze: bool) { + self.freeze_last_access_time = freeze; + } + pub fn freeze_last_write_time(&mut self, freeze: bool) { + self.freeze_last_write_time = freeze; + } fn get_access_mode(&self) -> io::Result { match (self.read, self.write, self.append, self.access_mode) { @@ -343,6 +353,18 @@ impl File { }; let handle = unsafe { HandleOrInvalid::from_raw_handle(handle) }; if let Ok(handle) = OwnedHandle::try_from(handle) { + if opts.freeze_last_access_time || opts.freeze_last_write_time { + let file_time = + c::FILETIME { dwLowDateTime: 0xFFFFFFFF, dwHighDateTime: 0xFFFFFFFF }; + cvt(unsafe { + c::SetFileTime( + handle.as_raw_handle(), + core::ptr::null(), + if opts.freeze_last_access_time { &file_time } else { core::ptr::null() }, + if opts.freeze_last_write_time { &file_time } else { core::ptr::null() }, + ) + })?; + } // Manual truncation. See #115745. if opts.truncate && creation == c::OPEN_ALWAYS From 6153fa0f88befd0f1c925a582b630b7412964aba Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 11 Jan 2026 12:12:41 +0100 Subject: [PATCH 1950/3801] Fix that `cfg` attribute was incorrectly not a parsed attribute --- compiler/rustc_attr_parsing/src/interface.rs | 12 +++++++++++- compiler/rustc_passes/src/check_attr.rs | 2 -- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index e38fffa6587c..7602e3c4598a 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -442,7 +442,17 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { /// Returns whether there is a parser for an attribute with this name pub fn is_parsed_attribute(path: &[Symbol]) -> bool { - Late::parsers().accepters.contains_key(path) || EARLY_PARSED_ATTRIBUTES.contains(&path) + /// The list of attributes that are parsed attributes, + /// even though they don't have a parser in `Late::parsers()` + const SPECIAL_ATTRIBUTES: &[&[Symbol]] = &[ + // Cfg attrs are removed after being early-parsed, so don't need to be in the parser list + &[sym::cfg], + &[sym::cfg_attr], + ]; + + Late::parsers().accepters.contains_key(path) + || EARLY_PARSED_ATTRIBUTES.contains(&path) + || SPECIAL_ATTRIBUTES.contains(&path) } fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2d3c5c7e48a0..75a30497b228 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -338,8 +338,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::warn | sym::deny | sym::forbid - | sym::cfg - | sym::cfg_attr // need to be fixed | sym::patchable_function_entry // FIXME(patchable_function_entry) | sym::deprecated_safe // FIXME(deprecated_safe) From eac7bda659dd0e9a6e4c3bacdeb2df026050fbea Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 11 Jan 2026 12:56:00 +0100 Subject: [PATCH 1951/3801] Completely list all unparsed attributes --- compiler/rustc_passes/src/check_attr.rs | 62 +++++++++++++++++++++---- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 75a30497b228..2ef6fdf1568b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -346,7 +346,54 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::panic_handler | sym::lang | sym::needs_allocator - | sym::default_lib_allocator, + | sym::default_lib_allocator + | sym::rustc_diagnostic_item + | sym::rustc_no_mir_inline + | sym::rustc_insignificant_dtor + | sym::rustc_nonnull_optimization_guaranteed + | sym::rustc_intrinsic + | sym::rustc_inherit_overflow_checks + | sym::rustc_intrinsic_const_stable_indirect + | sym::rustc_trivial_field_reads + | sym::rustc_on_unimplemented + | sym::rustc_do_not_const_check + | sym::rustc_reservation_impl + | sym::rustc_doc_primitive + | sym::rustc_allocator + | sym::rustc_deallocator + | sym::rustc_reallocator + | sym::rustc_conversion_suggestion + | sym::rustc_allocator_zeroed + | sym::rustc_allocator_zeroed_variant + | sym::rustc_deprecated_safe_2024 + | sym::rustc_test_marker + | sym::rustc_abi + | sym::rustc_layout + | sym::rustc_proc_macro_decls + | sym::rustc_dump_def_parents + | sym::rustc_never_type_options + | sym::rustc_autodiff + | sym::rustc_capture_analysis + | sym::rustc_regions + | sym::rustc_strict_coherence + | sym::rustc_dump_predicates + | sym::rustc_variance + | sym::rustc_variance_of_opaques + | sym::rustc_hidden_type_of_opaques + | sym::rustc_mir + | sym::rustc_dump_user_args + | sym::rustc_effective_visibility + | sym::rustc_outlives + | sym::rustc_symbol_name + | sym::rustc_evaluate_where_clauses + | sym::rustc_dump_vtable + | sym::rustc_delayed_bug_from_inside_query + | sym::rustc_dump_item_bounds + | sym::rustc_def_path + | sym::rustc_partition_reused + | sym::rustc_partition_codegened + | sym::rustc_expected_cgu_reuse + | sym::rustc_nounwind, .. ] => {} [name, rest@..] => { @@ -361,15 +408,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { continue } - // FIXME: differentiate between unstable and internal attributes just - // like we do with features instead of just accepting `rustc_` - // attributes by name. That should allow trimming the above list, too. - if !name.as_str().starts_with("rustc_") { - span_bug!( - attr.span(), - "builtin attribute {name:?} not handled by `CheckAttrVisitor`" - ) - } + span_bug!( + attr.span(), + "builtin attribute {name:?} not handled by `CheckAttrVisitor`" + ) } None => (), } From d993bd1bb133f3d129aba5ae027acefd92f26acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 8 Jan 2026 19:16:57 +0100 Subject: [PATCH 1952/3801] improve eii macro by using ecx methods --- compiler/rustc_builtin_macros/src/eii.rs | 214 +++++++++-------------- 1 file changed, 78 insertions(+), 136 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 0ebd3dc826d4..a5009b3bfa52 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -108,7 +108,7 @@ fn eii_( let mut return_items = Vec::new(); if func.body.is_some() { - return_items.push(Box::new(generate_default_impl( + return_items.push(generate_default_impl( ecx, &func, impl_unsafe, @@ -116,25 +116,25 @@ fn eii_( eii_attr_span, item_span, foreign_item_name, - ))) + )) } - return_items.push(Box::new(generate_foreign_item( + return_items.push(generate_foreign_item( ecx, eii_attr_span, item_span, func, vis, &attrs_from_decl, - ))); - return_items.push(Box::new(generate_attribute_macro_to_implement( + )); + return_items.push(generate_attribute_macro_to_implement( ecx, eii_attr_span, macro_name, foreign_item_name, impl_unsafe, &attrs_from_decl, - ))); + )); return_items.into_iter().map(wrap_item).collect() } @@ -194,7 +194,7 @@ fn generate_default_impl( eii_attr_span: Span, item_span: Span, foreign_item_name: Ident, -) -> ast::Item { +) -> Box { // FIXME: re-add some original attrs let attrs = ThinVec::new(); @@ -211,124 +211,72 @@ fn generate_default_impl( span: eii_attr_span, is_default: true, known_eii_macro_resolution: Some(ast::EiiExternTarget { - extern_item_path: ast::Path { - span: foreign_item_name.span, - segments: thin_vec![ - ast::PathSegment { - ident: Ident::from_str_and_span("super", foreign_item_name.span,), - id: DUMMY_NODE_ID, - args: None - }, - ast::PathSegment { ident: foreign_item_name, id: DUMMY_NODE_ID, args: None }, - ], - tokens: None, - }, + extern_item_path: ecx.path( + foreign_item_name.span, + // prefix super to escape the `dflt` module generated below + vec![Ident::from_str_and_span("super", foreign_item_name.span), foreign_item_name], + ), impl_unsafe, }), }); - ast::Item { - attrs: ThinVec::new(), - id: ast::DUMMY_NODE_ID, - span: eii_attr_span, - vis: ast::Visibility { - span: eii_attr_span, - kind: ast::VisibilityKind::Inherited, - tokens: None, - }, - kind: ast::ItemKind::Const(Box::new(ast::ConstItem { - ident: Ident { name: kw::Underscore, span: eii_attr_span }, - defaultness: ast::Defaultness::Final, - generics: ast::Generics::default(), - ty: Box::new(ast::Ty { - id: DUMMY_NODE_ID, - kind: ast::TyKind::Tup(ThinVec::new()), - span: eii_attr_span, - tokens: None, - }), - rhs: Some(ast::ConstItemRhs::Body(Box::new(ast::Expr { - id: DUMMY_NODE_ID, - kind: ast::ExprKind::Block( - Box::new(ast::Block { - stmts: thin_vec![ast::Stmt { - id: DUMMY_NODE_ID, - kind: ast::StmtKind::Item(Box::new(ast::Item { - attrs: ThinVec::new(), - id: DUMMY_NODE_ID, - span: item_span, - vis: ast::Visibility { - span: item_span, - kind: ast::VisibilityKind::Inherited, - tokens: None - }, - kind: ItemKind::Mod( - ast::Safety::Default, - Ident::from_str_and_span("dflt", item_span), - ast::ModKind::Loaded( - thin_vec![ - Box::new(ast::Item { - attrs: thin_vec![ecx.attr_nested_word( - sym::allow, - sym::unused_imports, - item_span - ),], - id: DUMMY_NODE_ID, - span: item_span, - vis: ast::Visibility { - span: eii_attr_span, - kind: ast::VisibilityKind::Inherited, - tokens: None - }, - kind: ItemKind::Use(ast::UseTree { - prefix: ast::Path::from_ident( - Ident::from_str_and_span( - "super", item_span, - ) - ), - kind: ast::UseTreeKind::Glob, - span: item_span, - }), - tokens: None, - }), - Box::new(ast::Item { - attrs, - id: DUMMY_NODE_ID, - span: item_span, - vis: ast::Visibility { - span: eii_attr_span, - kind: ast::VisibilityKind::Inherited, - tokens: None - }, - kind: ItemKind::Fn(Box::new(default_func)), - tokens: None, - }), - ], - ast::Inline::Yes, - ast::ModSpans { - inner_span: item_span, - inject_use_span: item_span, - } - ) - ), - tokens: None, - })), - span: eii_attr_span, - }], - id: DUMMY_NODE_ID, - rules: ast::BlockCheckMode::Default, - span: eii_attr_span, - tokens: None, - }), - None, + let item_mod = |span: Span, name: Ident, items: ThinVec>| { + ecx.item( + item_span, + ThinVec::new(), + ItemKind::Mod( + ast::Safety::Default, + name, + ast::ModKind::Loaded( + items, + ast::Inline::Yes, + ast::ModSpans { inner_span: span, inject_use_span: span }, ), - span: eii_attr_span, - attrs: ThinVec::new(), - tokens: None, - }))), - define_opaque: None, - })), - tokens: None, - } + ), + ) + }; + + let anon_mod = |span: Span, stmts: ThinVec| { + let unit = ecx.ty(item_span, ast::TyKind::Tup(ThinVec::new())); + let underscore = Ident::new(kw::Underscore, item_span); + ecx.item_const( + span, + underscore, + unit, + ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))), + ) + }; + + // const _: () = { + // mod dflt { + // use super::*; + // + // } + // } + anon_mod( + item_span, + thin_vec![ecx.stmt_item( + item_span, + item_mod( + item_span, + Ident::from_str_and_span("dflt", item_span), + thin_vec![ + ecx.item( + item_span, + thin_vec![ecx.attr_nested_word(sym::allow, sym::unused_imports, item_span)], + ItemKind::Use(ast::UseTree { + prefix: ast::Path::from_ident(Ident::from_str_and_span( + "super", item_span, + )), + kind: ast::UseTreeKind::Glob, + span: item_span, + }) + ), + ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func))) + ] + ) + ),], + ) } /// Generates a foreign item, like @@ -343,7 +291,7 @@ fn generate_foreign_item( mut func: ast::Fn, vis: Visibility, attrs_from_decl: &[Attribute], -) -> ast::Item { +) -> Box { let mut foreign_item_attrs = ThinVec::new(); foreign_item_attrs.extend_from_slice(attrs_from_decl); @@ -375,16 +323,10 @@ fn generate_foreign_item( func.sig.header.safety = ast::Safety::Safe(func.sig.span); } - ast::Item { - attrs: ast::AttrVec::default(), - id: ast::DUMMY_NODE_ID, - span: eii_attr_span, - vis: ast::Visibility { - span: eii_attr_span, - kind: ast::VisibilityKind::Inherited, - tokens: None, - }, - kind: ast::ItemKind::ForeignMod(ast::ForeignMod { + ecx.item( + eii_attr_span, + ThinVec::new(), + ast::ItemKind::ForeignMod(ast::ForeignMod { extern_span: eii_attr_span, safety: ast::Safety::Unsafe(eii_attr_span), abi, @@ -397,8 +339,7 @@ fn generate_foreign_item( tokens: None, })]), }), - tokens: None, - } + ) } /// Generate a stub macro (a bit like in core) that will roughly look like: @@ -418,7 +359,7 @@ fn generate_attribute_macro_to_implement( foreign_item_name: Ident, impl_unsafe: bool, attrs_from_decl: &[Attribute], -) -> ast::Item { +) -> Box { let mut macro_attrs = ThinVec::new(); // To avoid e.g. `error: attribute macro has missing stability attribute` @@ -428,7 +369,8 @@ fn generate_attribute_macro_to_implement( // #[builtin_macro(eii_shared_macro)] macro_attrs.push(ecx.attr_nested_word(sym::rustc_builtin_macro, sym::eii_shared_macro, span)); - ast::Item { + // cant use ecx methods here to construct item since we need it to be public + Box::new(ast::Item { attrs: macro_attrs, id: ast::DUMMY_NODE_ID, span, @@ -467,7 +409,7 @@ fn generate_attribute_macro_to_implement( }, ), tokens: None, - } + }) } pub(crate) fn eii_extern_target( From c7c5adbe6452c1c904fbe6b6bb3fdd0ed7671a55 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 11 Jan 2026 07:00:54 -0600 Subject: [PATCH 1953/3801] compiler-builtins: Remove the no-f16-f128 feature This option was used to gate `f16` and `f128` when support across backends and targets was inconsistent. We now have the rustc builtin cfg `target_has_reliable{f16,f128}` which has taken over this usecase. Remove no-f16-f128 since it is now unused and redundant. --- library/alloc/Cargo.toml | 1 - library/compiler-builtins/builtins-shim/Cargo.toml | 4 ---- library/compiler-builtins/builtins-test/Cargo.toml | 1 - library/compiler-builtins/ci/run.sh | 4 ---- library/compiler-builtins/compiler-builtins/Cargo.toml | 4 ---- library/compiler-builtins/compiler-builtins/configure.rs | 7 ++----- library/compiler-builtins/libm/configure.rs | 7 ++----- library/std/Cargo.toml | 1 - library/sysroot/Cargo.toml | 1 - 9 files changed, 4 insertions(+), 26 deletions(-) diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index fb1f8c86dbfd..541257b6cda6 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -21,7 +21,6 @@ compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features [features] compiler-builtins-mem = ['compiler_builtins/mem'] compiler-builtins-c = ["compiler_builtins/c"] -compiler-builtins-no-f16-f128 = ["compiler_builtins/no-f16-f128"] # Choose algorithms that are optimized for binary size instead of runtime performance optimize_for_size = ["core/optimize_for_size"] diff --git a/library/compiler-builtins/builtins-shim/Cargo.toml b/library/compiler-builtins/builtins-shim/Cargo.toml index ac77224f5ce1..746d5b21dc3f 100644 --- a/library/compiler-builtins/builtins-shim/Cargo.toml +++ b/library/compiler-builtins/builtins-shim/Cargo.toml @@ -47,10 +47,6 @@ c = ["dep:cc"] # the generic versions on all platforms. no-asm = [] -# Workaround for codegen backends which haven't yet implemented `f16` and -# `f128` support. Disabled any intrinsics which use those types. -no-f16-f128 = [] - # Flag this library as the unstable compiler-builtins lib compiler-builtins = [] diff --git a/library/compiler-builtins/builtins-test/Cargo.toml b/library/compiler-builtins/builtins-test/Cargo.toml index 9346ea65420b..550f736a76db 100644 --- a/library/compiler-builtins/builtins-test/Cargo.toml +++ b/library/compiler-builtins/builtins-test/Cargo.toml @@ -33,7 +33,6 @@ utest-macros = { git = "https://github.com/japaric/utest" } default = ["mangled-names"] c = ["compiler_builtins/c"] no-asm = ["compiler_builtins/no-asm"] -no-f16-f128 = ["compiler_builtins/no-f16-f128"] mem = ["compiler_builtins/mem"] mangled-names = ["compiler_builtins/mangled-names"] # Skip tests that rely on f128 symbols being available on the system diff --git a/library/compiler-builtins/ci/run.sh b/library/compiler-builtins/ci/run.sh index bc94d42fe837..0c07b32c74b9 100755 --- a/library/compiler-builtins/ci/run.sh +++ b/library/compiler-builtins/ci/run.sh @@ -36,8 +36,6 @@ else "${test_builtins[@]}" --features c --release "${test_builtins[@]}" --features no-asm "${test_builtins[@]}" --features no-asm --release - "${test_builtins[@]}" --features no-f16-f128 - "${test_builtins[@]}" --features no-f16-f128 --release "${test_builtins[@]}" --benches "${test_builtins[@]}" --benches --release @@ -63,8 +61,6 @@ symcheck+=(-- build-and-check) "${symcheck[@]}" "$target" -- -p compiler_builtins --features c --release "${symcheck[@]}" "$target" -- -p compiler_builtins --features no-asm "${symcheck[@]}" "$target" -- -p compiler_builtins --features no-asm --release -"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-f16-f128 -"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-f16-f128 --release run_intrinsics_test() { build_args=(--verbose --manifest-path builtins-test-intrinsics/Cargo.toml) diff --git a/library/compiler-builtins/compiler-builtins/Cargo.toml b/library/compiler-builtins/compiler-builtins/Cargo.toml index 0845861dcfe3..496dde2d4cf2 100644 --- a/library/compiler-builtins/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/compiler-builtins/Cargo.toml @@ -45,10 +45,6 @@ c = ["dep:cc"] # the generic versions on all platforms. no-asm = [] -# Workaround for codegen backends which haven't yet implemented `f16` and -# `f128` support. Disabled any intrinsics which use those types. -no-f16-f128 = [] - # Flag this library as the unstable compiler-builtins lib compiler-builtins = [] diff --git a/library/compiler-builtins/compiler-builtins/configure.rs b/library/compiler-builtins/compiler-builtins/configure.rs index 79e238abc0f6..f16da6b58f81 100644 --- a/library/compiler-builtins/compiler-builtins/configure.rs +++ b/library/compiler-builtins/compiler-builtins/configure.rs @@ -95,16 +95,13 @@ pub fn configure_aliases(target: &Target) { * * https://github.com/rust-lang/rustc_codegen_cranelift/blob/c713ffab3c6e28ab4b4dd4e392330f786ea657ad/src/lib.rs#L196-L226 */ - // If the feature is set, disable both of these types. - let no_f16_f128 = target.cargo_features.iter().any(|s| s == "no-f16-f128"); - println!("cargo::rustc-check-cfg=cfg(f16_enabled)"); - if target.reliable_f16 && !no_f16_f128 { + if target.reliable_f16 { println!("cargo::rustc-cfg=f16_enabled"); } println!("cargo::rustc-check-cfg=cfg(f128_enabled)"); - if target.reliable_f128 && !no_f16_f128 { + if target.reliable_f128 { println!("cargo::rustc-cfg=f128_enabled"); } } diff --git a/library/compiler-builtins/libm/configure.rs b/library/compiler-builtins/libm/configure.rs index 857a30229716..ee65a3a8d624 100644 --- a/library/compiler-builtins/libm/configure.rs +++ b/library/compiler-builtins/libm/configure.rs @@ -143,16 +143,13 @@ fn emit_f16_f128_cfg(cfg: &Config) { /* See the compiler-builtins configure file for info about the meaning of these options */ - // If the feature is set, disable both of these types. - let no_f16_f128 = cfg.cargo_features.iter().any(|s| s == "no-f16-f128"); - println!("cargo:rustc-check-cfg=cfg(f16_enabled)"); - if cfg.reliable_f16 && !no_f16_f128 { + if cfg.reliable_f16 { println!("cargo:rustc-cfg=f16_enabled"); } println!("cargo:rustc-check-cfg=cfg(f128_enabled)"); - if cfg.reliable_f128 && !no_f16_f128 { + if cfg.reliable_f128 { println!("cargo:rustc-cfg=f128_enabled"); } } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 5c9ae52d9e6c..b6683a2ae9ec 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -115,7 +115,6 @@ backtrace-trace-only = [] panic-unwind = ["dep:panic_unwind"] compiler-builtins-c = ["alloc/compiler-builtins-c"] compiler-builtins-mem = ["alloc/compiler-builtins-mem"] -compiler-builtins-no-f16-f128 = ["alloc/compiler-builtins-no-f16-f128"] llvm-libunwind = ["unwind/llvm-libunwind"] system-llvm-libunwind = ["unwind/system-llvm-libunwind"] diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index a18868082916..b2069ef6a613 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -25,7 +25,6 @@ backtrace = ["std/backtrace"] backtrace-trace-only = ["std/backtrace-trace-only"] compiler-builtins-c = ["std/compiler-builtins-c"] compiler-builtins-mem = ["std/compiler-builtins-mem"] -compiler-builtins-no-f16-f128 = ["std/compiler-builtins-no-f16-f128"] debug_refcell = ["std/debug_refcell"] llvm-libunwind = ["std/llvm-libunwind"] system-llvm-libunwind = ["std/system-llvm-libunwind"] From e21256031782bdb355f3ff2e4ed126360b9cc7ab Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 9 Nov 2025 23:17:09 +0300 Subject: [PATCH 1954/3801] Stabilize `alloc_layout_extra` --- ...sroot_tests-128bit-atomic-operations.patch | 3 +- library/alloc/src/alloc.rs | 6 +- library/alloc/src/boxed.rs | 2 +- library/alloc/src/boxed/thin.rs | 4 +- library/alloc/src/lib.rs | 1 - library/alloc/src/rc.rs | 8 +-- library/alloc/src/sync.rs | 8 +-- library/alloctests/lib.rs | 1 - library/alloctests/tests/boxed.rs | 2 +- library/alloctests/tests/lib.rs | 1 - library/core/src/alloc/layout.rs | 65 +++++++++++-------- library/coretests/tests/alloc.rs | 2 +- library/coretests/tests/lib.rs | 1 - library/std/src/alloc.rs | 4 +- library/std/src/lib.rs | 1 - 15 files changed, 58 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch index f3d1d5c43ea1..6ed0b17f679c 100644 --- a/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch +++ b/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch @@ -14,11 +14,10 @@ diff --git a/coretests/tests/lib.rs b/coretests/tests/lib.rs index 1e336bf..35e6f54 100644 --- a/coretests/tests/lib.rs +++ b/coretests/tests/lib.rs -@@ -2,5 +2,4 @@ +@@ -2,4 +2,3 @@ // tidy-alphabetical-start -#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_select))] - #![feature(alloc_layout_extra)] #![feature(array_ptr_get)] diff --git a/coretests/tests/atomic.rs b/coretests/tests/atomic.rs index b735957..ea728b6 100644 diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 5dd828bd54e1..cd1c2ea8fcd1 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -184,7 +184,7 @@ impl Global { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces fn alloc_impl_runtime(layout: Layout, zeroed: bool) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), + 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), // SAFETY: `layout` is non-zero in size, size => unsafe { let raw_ptr = if zeroed { alloc_zeroed(layout) } else { alloc(layout) }; @@ -277,7 +277,7 @@ impl Global { // SAFETY: conditions must be upheld by the caller 0 => unsafe { self.deallocate(ptr, old_layout); - Ok(NonNull::slice_from_raw_parts(new_layout.dangling(), 0)) + Ok(NonNull::slice_from_raw_parts(new_layout.dangling_ptr(), 0)) }, // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller @@ -368,7 +368,7 @@ impl Global { #[rustc_const_unstable(feature = "const_heap", issue = "79597")] const fn alloc_impl_const(layout: Layout, zeroed: bool) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), + 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), // SAFETY: `layout` is non-zero in size, size => unsafe { let raw_ptr = core::intrinsics::const_allocate(layout.size(), layout.align()); diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 60758551cc04..eb741c9211f2 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -834,7 +834,7 @@ impl Box { } let layout = Layout::for_value::(src); let (ptr, guard) = if layout.size() == 0 { - (layout.dangling(), None) + (layout.dangling_ptr(), None) } else { // Safety: layout is non-zero-sized let ptr = alloc.allocate(layout)?.cast(); diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index 1cce36606d2c..b50810b8d923 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -245,7 +245,7 @@ impl WithHeader { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST); - layout.dangling() + layout.dangling_ptr() } else { let ptr = alloc::alloc(layout); if ptr.is_null() { @@ -282,7 +282,7 @@ impl WithHeader { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. debug_assert!(value_offset == 0 && size_of::() == 0 && size_of::() == 0); - layout.dangling() + layout.dangling_ptr() } else { let ptr = alloc::alloc(layout); if ptr.is_null() { diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 3ca9f3ae0bc9..f7167650635d 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -86,7 +86,6 @@ // Library features: // tidy-alphabetical-start #![cfg_attr(not(no_global_oom_handling), feature(string_replace_in_place))] -#![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_into_iter_constructors)] #![feature(ascii_char)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 8a72748668cc..f58ebd488d7c 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -261,7 +261,7 @@ use core::panic::{RefUnwindSafe, UnwindSafe}; #[cfg(not(no_global_oom_handling))] use core::pin::Pin; use core::pin::PinCoerceUnsized; -use core::ptr::{self, NonNull, drop_in_place}; +use core::ptr::{self, Alignment, NonNull, drop_in_place}; #[cfg(not(no_global_oom_handling))] use core::slice::from_raw_parts_mut; use core::{borrow, fmt, hint}; @@ -3847,11 +3847,11 @@ unsafe fn data_offset(ptr: *const T) -> usize { // and extern types, the input safety requirement is currently enough to // satisfy the requirements of align_of_val_raw; this is an implementation // detail of the language that must not be relied upon outside of std. - unsafe { data_offset_align(align_of_val_raw(ptr)) } + unsafe { data_offset_align(Alignment::new_unchecked(align_of_val_raw(ptr))) } } #[inline] -fn data_offset_align(align: usize) -> usize { +fn data_offset_align(align: Alignment) -> usize { let layout = Layout::new::>(); layout.size() + layout.padding_needed_for(align) } @@ -4478,7 +4478,7 @@ impl UniqueRcUninit { /// Returns the pointer to be written into to initialize the [`Rc`]. fn data_ptr(&mut self) -> *mut T { - let offset = data_offset_align(self.layout_for_value.align()); + let offset = data_offset_align(self.layout_for_value.alignment()); unsafe { self.ptr.as_ptr().byte_add(offset) as *mut T } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 4180fe91cb55..fc44a468c8a4 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -26,7 +26,7 @@ use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Lega use core::ops::{Residual, Try}; use core::panic::{RefUnwindSafe, UnwindSafe}; use core::pin::{Pin, PinCoerceUnsized}; -use core::ptr::{self, NonNull}; +use core::ptr::{self, Alignment, NonNull}; #[cfg(not(no_global_oom_handling))] use core::slice::from_raw_parts_mut; use core::sync::atomic::Ordering::{Acquire, Relaxed, Release}; @@ -4208,11 +4208,11 @@ unsafe fn data_offset(ptr: *const T) -> usize { // and extern types, the input safety requirement is currently enough to // satisfy the requirements of align_of_val_raw; this is an implementation // detail of the language that must not be relied upon outside of std. - unsafe { data_offset_align(align_of_val_raw(ptr)) } + unsafe { data_offset_align(Alignment::new_unchecked(align_of_val_raw(ptr))) } } #[inline] -fn data_offset_align(align: usize) -> usize { +fn data_offset_align(align: Alignment) -> usize { let layout = Layout::new::>(); layout.size() + layout.padding_needed_for(align) } @@ -4258,7 +4258,7 @@ impl UniqueArcUninit { /// Returns the pointer to be written into to initialize the [`Arc`]. fn data_ptr(&mut self) -> *mut T { - let offset = data_offset_align(self.layout_for_value.align()); + let offset = data_offset_align(self.layout_for_value.alignment()); unsafe { self.ptr.as_ptr().byte_add(offset) as *mut T } } diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index b85fc8eb9970..32a876cdc5f7 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -14,7 +14,6 @@ // // Library features: // tidy-alphabetical-start -#![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_into_iter_constructors)] #![feature(assert_matches)] diff --git a/library/alloctests/tests/boxed.rs b/library/alloctests/tests/boxed.rs index 94389cf2de93..83fd1ef7449a 100644 --- a/library/alloctests/tests/boxed.rs +++ b/library/alloctests/tests/boxed.rs @@ -104,7 +104,7 @@ pub struct ConstAllocator; unsafe impl Allocator for ConstAllocator { fn allocate(&self, layout: Layout) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), + 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), _ => unsafe { let ptr = core::intrinsics::const_allocate(layout.size(), layout.align()); Ok(NonNull::new_unchecked(ptr as *mut [u8; 0] as *mut [u8])) diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index c7fdc2054f71..2926248edbf5 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -1,5 +1,4 @@ #![feature(allocator_api)] -#![feature(alloc_layout_extra)] #![feature(const_heap)] #![feature(deque_extend_front)] #![feature(iter_array_chunks)] diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index a4e25b8734a9..3a2111350a4e 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -217,10 +217,11 @@ impl Layout { /// be that of a valid pointer, which means this must not be used /// as a "not yet initialized" sentinel value. /// Types that lazily allocate must track initialization by some other means. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline] - pub const fn dangling(&self) -> NonNull { + pub const fn dangling_ptr(&self) -> NonNull { NonNull::without_provenance(self.align.as_nonzero()) } @@ -250,29 +251,23 @@ impl Layout { } /// Returns the amount of padding we must insert after `self` - /// to ensure that the following address will satisfy `align` - /// (measured in bytes). + /// to ensure that the following address will satisfy `alignment`. /// - /// e.g., if `self.size()` is 9, then `self.padding_needed_for(4)` + /// e.g., if `self.size()` is 9, then `self.padding_needed_for(alignment4)` + /// (where `alignment4.as_usize() == 4`) /// returns 3, because that is the minimum number of bytes of /// padding required to get a 4-aligned address (assuming that the /// corresponding memory block starts at a 4-aligned address). /// - /// The return value of this function has no meaning if `align` is - /// not a power-of-two. - /// - /// Note that the utility of the returned value requires `align` + /// Note that the utility of the returned value requires `alignment` /// to be less than or equal to the alignment of the starting /// address for the whole allocated block of memory. One way to - /// satisfy this constraint is to ensure `align <= self.align()`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[must_use = "this returns the padding needed, \ - without modifying the `Layout`"] + /// satisfy this constraint is to ensure `alignment.as_usize() <= self.align()`. + #[unstable(feature = "ptr_alignment_type", issue = "102070")] + #[must_use = "this returns the padding needed, without modifying the `Layout`"] #[inline] - pub const fn padding_needed_for(&self, align: usize) -> usize { - // FIXME: Can we just change the type on this to `Alignment`? - let Some(align) = Alignment::new(align) else { return usize::MAX }; - let len_rounded_up = self.size_rounded_up_to_custom_align(align); + pub const fn padding_needed_for(&self, alignment: Alignment) -> usize { + let len_rounded_up = self.size_rounded_up_to_custom_align(alignment); // SAFETY: Cannot overflow because the rounded-up value is never less unsafe { unchecked_sub(len_rounded_up, self.size) } } @@ -335,6 +330,8 @@ impl Layout { /// layout of the array and `offs` is the distance between the start /// of each element in the array. /// + /// Does not include padding after the trailing element. + /// /// (That distance between elements is sometimes known as "stride".) /// /// On arithmetic overflow, returns `LayoutError`. @@ -342,7 +339,6 @@ impl Layout { /// # Examples /// /// ``` - /// #![feature(alloc_layout_extra)] /// use std::alloc::Layout; /// /// // All rust types have a size that's a multiple of their alignment. @@ -353,17 +349,32 @@ impl Layout { /// // But you can manually make layouts which don't meet that rule. /// let padding_needed = Layout::from_size_align(6, 4).unwrap(); /// let repeated = padding_needed.repeat(3).unwrap(); - /// assert_eq!(repeated, (Layout::from_size_align(24, 4).unwrap(), 8)); + /// assert_eq!(repeated, (Layout::from_size_align(22, 4).unwrap(), 8)); + /// + /// // Repeating an element zero times has zero size, but keeps the alignment (like `[T; 0]`) + /// let repeated = normal.repeat(0).unwrap(); + /// assert_eq!(repeated, (Layout::from_size_align(0, 4).unwrap(), 12)); + /// let repeated = padding_needed.repeat(0).unwrap(); + /// assert_eq!(repeated, (Layout::from_size_align(0, 4).unwrap(), 8)); /// ``` - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { + // FIXME(const-hack): the following could be way shorter with `?` let padded = self.pad_to_align(); - if let Ok(repeated) = padded.repeat_packed(n) { - Ok((repeated, padded.size())) + let Ok(result) = (if let Some(k) = n.checked_sub(1) { + let Ok(repeated) = padded.repeat_packed(k) else { + return Err(LayoutError); + }; + repeated.extend_packed(*self) } else { - Err(LayoutError) - } + debug_assert!(n == 0); + self.repeat_packed(0) + }) else { + return Err(LayoutError); + }; + Ok((result, padded.size())) } /// Creates a layout describing the record for `self` followed by @@ -443,7 +454,8 @@ impl Layout { /// aligned. /// /// On arithmetic overflow, returns `LayoutError`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn repeat_packed(&self, n: usize) -> Result { if let Some(size) = self.size.checked_mul(n) { @@ -460,7 +472,8 @@ impl Layout { /// and is not incorporated *at all* into the resulting layout. /// /// On arithmetic overflow, returns `LayoutError`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn extend_packed(&self, next: Self) -> Result { // SAFETY: each `size` is at most `isize::MAX == usize::MAX/2`, so the diff --git a/library/coretests/tests/alloc.rs b/library/coretests/tests/alloc.rs index a4af6fd32a11..aac1d60ce32c 100644 --- a/library/coretests/tests/alloc.rs +++ b/library/coretests/tests/alloc.rs @@ -6,7 +6,7 @@ fn const_unchecked_layout() { const SIZE: usize = 0x2000; const ALIGN: usize = 0x1000; const LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(SIZE, ALIGN) }; - const DANGLING: NonNull = LAYOUT.dangling(); + const DANGLING: NonNull = LAYOUT.dangling_ptr(); assert_eq!(LAYOUT.size(), SIZE); assert_eq!(LAYOUT.align(), ALIGN); assert_eq!(Some(DANGLING), NonNull::new(ptr::without_provenance_mut(ALIGN))); diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index b28e7338859c..4974f52cd9df 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -1,7 +1,6 @@ // tidy-alphabetical-start #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_select))] -#![feature(alloc_layout_extra)] #![feature(array_ptr_get)] #![feature(array_try_from_fn)] #![feature(array_try_map)] diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index f0d2b913bbbb..ed0322e2cf5d 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -142,7 +142,7 @@ impl System { #[inline] fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), + 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), // SAFETY: `layout` is non-zero in size, size => unsafe { let raw_ptr = if zeroed { @@ -266,7 +266,7 @@ unsafe impl Allocator for System { // SAFETY: conditions must be upheld by the caller 0 => unsafe { Allocator::deallocate(self, ptr, old_layout); - Ok(NonNull::slice_from_raw_parts(new_layout.dangling(), 0)) + Ok(NonNull::slice_from_raw_parts(new_layout.dangling_ptr(), 0)) }, // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index f5b9f69a5f9f..4f48f23f44b8 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -367,7 +367,6 @@ // // Library features (alloc): // tidy-alphabetical-start -#![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(clone_from_ref)] #![feature(get_mut_unchecked)] From 33f0f80c1ac9dd1df22082cce77e7eedbb30b4f1 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 11 Jan 2026 21:33:57 +0530 Subject: [PATCH 1955/3801] add make corresponding constructor methods in SyntaxFactory --- .../src/ast/syntax_factory/constructors.rs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 7cf9e2bf14f9..5fe419ad4eb7 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -1578,6 +1578,44 @@ impl SyntaxFactory { pub fn ident(&self, text: &str) -> SyntaxToken { make::tokens::ident(text) } + + pub fn mut_self_param(&self) -> ast::SelfParam { + let ast = make::mut_self_param().clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn ret_type(&self, ty: ast::Type) -> ast::RetType { + let ast = make::ret_type(ty.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + ast + } + + pub fn ty_ref(&self, ty: ast::Type, is_mut: bool) -> ast::Type { + let ast = make::ty_ref(ty.clone(), is_mut).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + match &ast { + ast::Type::RefType(ref_ty) => { + builder.map_node(ty.syntax().clone(), ref_ty.ty().unwrap().syntax().clone()); + } + _ => unreachable!(), + } + builder.finish(&mut mapping); + } + ast + } } // `ext` constructors From 16d74e7b90fc5fe2aaa23377bf51093f0295910b Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 11 Jan 2026 21:34:44 +0530 Subject: [PATCH 1956/3801] migrate generate_mut_trait_impl to new SyntaxEditor --- .../src/handlers/generate_mut_trait_impl.rs | 191 +++++++++++------- 1 file changed, 121 insertions(+), 70 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs index ae1ae24d1ec1..53f6f4883f4d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs @@ -1,8 +1,8 @@ use ide_db::{famous_defs::FamousDefs, traits::resolve_target_trait}; use syntax::{ - AstNode, T, - ast::{self, edit_in_place::Indent, make}, - ted, + AstNode, SyntaxElement, SyntaxNode, T, + ast::{self, edit::AstNodeEdit, edit_in_place::Indent, syntax_factory::SyntaxFactory}, + syntax_editor::{Element, Position, SyntaxEditor}, }; use crate::{AssistContext, AssistId, Assists}; @@ -45,12 +45,13 @@ use crate::{AssistContext, AssistId, Assists}; // } // ``` pub(crate) fn generate_mut_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let impl_def = ctx.find_node_at_offset::()?.clone_for_update(); - let indent = impl_def.indent_level(); + let impl_def = ctx.find_node_at_offset::()?; + let indent = Indent::indent_level(&impl_def); let ast::Type::PathType(path) = impl_def.trait_()? else { return None; }; + let trait_name = path.path()?.segment()?.name_ref()?; let scope = ctx.sema.scope(impl_def.trait_()?.syntax())?; @@ -59,75 +60,133 @@ pub(crate) fn generate_mut_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_> let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?; let trait_new = get_trait_mut(&trait_, famous)?; - // Index -> IndexMut - ted::replace(trait_name.syntax(), make::name_ref(trait_new).clone_for_update().syntax()); - - // index -> index_mut - let (trait_method_name, new_trait_method_name) = impl_def - .syntax() - .descendants() - .filter_map(ast::Name::cast) - .find_map(process_method_name)?; - ted::replace( - trait_method_name.syntax(), - make::name(new_trait_method_name).clone_for_update().syntax(), - ); - - if let Some(type_alias) = impl_def.syntax().descendants().find_map(ast::TypeAlias::cast) { - ted::remove(type_alias.syntax()); - } - - // &self -> &mut self - let mut_self_param = make::mut_self_param(); - let self_param: ast::SelfParam = - impl_def.syntax().descendants().find_map(ast::SelfParam::cast)?; - ted::replace(self_param.syntax(), mut_self_param.clone_for_update().syntax()); - - // &Self::Output -> &mut Self::Output - let ret_type = impl_def.syntax().descendants().find_map(ast::RetType::cast)?; - let new_ret_type = process_ret_type(&ret_type)?; - ted::replace(ret_type.syntax(), make::ret_type(new_ret_type).clone_for_update().syntax()); - - let fn_ = impl_def.assoc_item_list()?.assoc_items().find_map(|it| match it { - ast::AssocItem::Fn(f) => Some(f), - _ => None, - })?; - let _ = process_ref_mut(&fn_); - - let assoc_list = make::assoc_item_list(None).clone_for_update(); - ted::replace(impl_def.assoc_item_list()?.syntax(), assoc_list.syntax()); - impl_def.get_or_create_assoc_item_list().add_item(syntax::ast::AssocItem::Fn(fn_)); - let target = impl_def.syntax().text_range(); + acc.add( AssistId::generate("generate_mut_trait_impl"), format!("Generate `{trait_new}` impl from this `{trait_name}` trait"), target, |edit| { - edit.insert( - target.start(), - if ctx.config.snippet_cap.is_some() { - format!("$0{impl_def}\n\n{indent}") - } else { - format!("{impl_def}\n\n{indent}") - }, + let impl_clone = impl_def.reset_indent().clone_subtree(); + let mut editor = SyntaxEditor::new(impl_clone.syntax().clone()); + let factory = SyntaxFactory::without_mappings(); + + apply_generate_mut_impl(&mut editor, &factory, &impl_clone, trait_new); + + let new_root = editor.finish(); + let new_root = new_root.new_root(); + + let new_impl = ast::Impl::cast(new_root.clone()).unwrap(); + + Indent::indent(&new_impl, indent); + + let mut editor = edit.make_editor(impl_def.syntax()); + editor.insert_all( + Position::before(impl_def.syntax()), + vec![ + new_impl.syntax().syntax_element(), + factory.whitespace(&format!("\n\n{indent}")).syntax_element(), + ], ); + + if let Some(cap) = ctx.config.snippet_cap { + let tabstop_before = edit.make_tabstop_before(cap); + editor.add_annotation(new_impl.syntax(), tabstop_before); + } + + edit.add_file_edits(ctx.vfs_file_id(), editor); }, ) } -fn process_ref_mut(fn_: &ast::Fn) -> Option<()> { - let expr = fn_.body()?.tail_expr()?; - match &expr { - ast::Expr::RefExpr(ref_expr) if ref_expr.mut_token().is_none() => { - ted::insert_all_raw( - ted::Position::after(ref_expr.amp_token()?), - vec![make::token(T![mut]).into(), make::tokens::whitespace(" ").into()], - ); - } - _ => {} +fn delete_with_trivia(editor: &mut SyntaxEditor, node: &SyntaxNode) { + let mut end: SyntaxElement = node.clone().into(); + + if let Some(next) = node.next_sibling_or_token() + && let SyntaxElement::Token(tok) = &next + && tok.kind().is_trivia() + { + end = next.clone(); } - None + + editor.delete_all(node.clone().into()..=end); +} + +fn apply_generate_mut_impl( + editor: &mut SyntaxEditor, + factory: &SyntaxFactory, + impl_def: &ast::Impl, + trait_new: &str, +) -> Option<()> { + let path = + impl_def.trait_().and_then(|t| t.syntax().descendants().find_map(ast::Path::cast))?; + let seg = path.segment()?; + let name_ref = seg.name_ref()?; + + let new_name_ref = factory.name_ref(trait_new); + editor.replace(name_ref.syntax(), new_name_ref.syntax()); + + if let Some((name, new_name)) = + impl_def.syntax().descendants().filter_map(ast::Name::cast).find_map(process_method_name) + { + let new_name_node = factory.name(new_name); + editor.replace(name.syntax(), new_name_node.syntax()); + } + + if let Some(type_alias) = impl_def.syntax().descendants().find_map(ast::TypeAlias::cast) { + delete_with_trivia(editor, type_alias.syntax()); + } + + if let Some(self_param) = impl_def.syntax().descendants().find_map(ast::SelfParam::cast) { + let mut_self = factory.mut_self_param(); + editor.replace(self_param.syntax(), mut_self.syntax()); + } + + if let Some(ret_type) = impl_def.syntax().descendants().find_map(ast::RetType::cast) + && let Some(new_ty) = process_ret_type(factory, &ret_type) + { + let new_ret = factory.ret_type(new_ty); + editor.replace(ret_type.syntax(), new_ret.syntax()) + } + + if let Some(fn_) = impl_def.assoc_item_list().and_then(|l| { + l.assoc_items().find_map(|it| match it { + ast::AssocItem::Fn(f) => Some(f), + _ => None, + }) + }) { + process_ref_mut(editor, factory, &fn_); + } + + Some(()) +} + +fn process_ref_mut(editor: &mut SyntaxEditor, factory: &SyntaxFactory, fn_: &ast::Fn) { + let Some(expr) = fn_.body().and_then(|b| b.tail_expr()) else { return }; + + let ast::Expr::RefExpr(ref_expr) = expr else { return }; + + if ref_expr.mut_token().is_some() { + return; + } + + let Some(amp) = ref_expr.amp_token() else { return }; + + let mut_kw = factory.token(T![mut]); + let space = factory.whitespace(" "); + + editor.insert(Position::after(amp.clone()), space.syntax_element()); + editor.insert(Position::after(amp), mut_kw.syntax_element()); +} + +fn process_ret_type(factory: &SyntaxFactory, ref_ty: &ast::RetType) -> Option { + let ty = ref_ty.ty()?; + let ast::Type::RefType(ref_type) = ty else { + return None; + }; + + let inner = ref_type.ty()?; + Some(factory.ty_ref(inner, true)) } fn get_trait_mut(apply_trait: &hir::Trait, famous: FamousDefs<'_, '_>) -> Option<&'static str> { @@ -158,14 +217,6 @@ fn process_method_name(name: ast::Name) -> Option<(ast::Name, &'static str)> { Some((name, new_name)) } -fn process_ret_type(ref_ty: &ast::RetType) -> Option { - let ty = ref_ty.ty()?; - let ast::Type::RefType(ref_type) = ty else { - return None; - }; - Some(make::ty_ref(ref_type.ty()?, true)) -} - #[cfg(test)] mod tests { use crate::{ From ef1e4e65b7c76bd03fa82bbbc42393712af05f81 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 10 Jan 2026 15:54:09 +0100 Subject: [PATCH 1957/3801] Move checks from `check_doc_attrs` directly into `rustc_attr_parsing` --- compiler/rustc_attr_parsing/messages.ftl | 3 + .../rustc_attr_parsing/src/attributes/doc.rs | 119 ++++++++++++++---- compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_attr_parsing/src/interface.rs | 3 + .../src/session_diagnostics.rs | 8 ++ compiler/rustc_lint/messages.ftl | 5 + compiler/rustc_lint/src/early/diagnostics.rs | 2 + compiler/rustc_lint/src/lints.rs | 5 + compiler/rustc_lint_defs/src/lib.rs | 1 + compiler/rustc_passes/messages.ftl | 8 -- compiler/rustc_passes/src/check_attr.rs | 87 ++++--------- compiler/rustc_passes/src/errors.rs | 13 -- .../lints/invalid-crate-level-lint.rs | 13 ++ .../lints/invalid-crate-level-lint.stderr | 27 ++++ tests/rustdoc-ui/lints/invalid-doc-attr.rs | 7 -- .../rustdoc-ui/lints/invalid-doc-attr.stderr | 38 ++---- tests/ui/rustdoc/doc-alias-crate-level.stderr | 12 +- tests/ui/rustdoc/doc_keyword.stderr | 12 +- 18 files changed, 204 insertions(+), 160 deletions(-) create mode 100644 tests/rustdoc-ui/lints/invalid-crate-level-lint.rs create mode 100644 tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 36213e68a52b..4b4358ab0a9c 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -23,6 +23,9 @@ attr_parsing_doc_alias_malformed = attr_parsing_doc_alias_start_end = {$attr_str} cannot start or end with ' ' +attr_parsing_doc_attr_not_crate_level = + `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute + attr_parsing_doc_attribute_not_attribute = nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]` .help = only existing builtin attributes are allowed in core/std diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 16dbb04b48eb..6cc4ac35eadb 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -1,5 +1,6 @@ use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit}; use rustc_feature::template; +use rustc_hir::Target; use rustc_hir::attrs::{ AttributeKind, CfgEntry, CfgHideShow, CfgInfo, DocAttribute, DocInline, HideOrShow, }; @@ -12,8 +13,8 @@ use super::{AcceptMapping, AttributeParser}; use crate::context::{AcceptContext, FinalizeContext, Stage}; use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, OwnedPathParser}; use crate::session_diagnostics::{ - DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttributeNotAttribute, - DocKeywordNotKeyword, + DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttrNotCrateLevel, + DocAttributeNotAttribute, DocKeywordNotKeyword, }; fn check_keyword(cx: &mut AcceptContext<'_, '_, S>, keyword: Symbol, span: Span) -> bool { @@ -43,16 +44,39 @@ fn check_attribute( false } -fn parse_keyword_and_attribute( +/// Checks that an attribute is *not* used at the crate level. Returns `true` if valid. +fn check_attr_not_crate_level( + cx: &mut AcceptContext<'_, '_, S>, + span: Span, + attr_name: Symbol, +) -> bool { + if cx.shared.target.is_some_and(|target| target == Target::Crate) { + cx.emit_err(DocAttrNotCrateLevel { span, attr_name }); + return false; + } + true +} + +/// Checks that an attribute is used at the crate level. Returns `true` if valid. +fn check_attr_crate_level(cx: &mut AcceptContext<'_, '_, S>, span: Span) -> bool { + if cx.shared.target.is_some_and(|target| target != Target::Crate) { + cx.emit_lint( + rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, + AttributeLintKind::AttrCrateLevelOnly, + span, + ); + return false; + } + true +} + +fn parse_keyword_and_attribute( cx: &mut AcceptContext<'_, '_, S>, path: &OwnedPathParser, args: &ArgParser, attr_value: &mut Option<(Symbol, Span)>, - callback: F, -) where - S: Stage, - F: FnOnce(&mut AcceptContext<'_, '_, S>, Symbol, Span) -> bool, -{ + attr_name: Symbol, +) { let Some(nv) = args.name_value() else { cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); return; @@ -63,16 +87,26 @@ fn parse_keyword_and_attribute( return; }; - if !callback(cx, value, nv.value_span) { + let ret = if attr_name == sym::keyword { + check_keyword(cx, value, nv.value_span) + } else { + check_attribute(cx, value, nv.value_span) + }; + if !ret { return; } + let span = path.span(); if attr_value.is_some() { - cx.duplicate_key(path.span(), path.word_sym().unwrap()); + cx.duplicate_key(span, path.word_sym().unwrap()); return; } - *attr_value = Some((value, path.span())); + if !check_attr_not_crate_level(cx, span, attr_name) { + return; + } + + *attr_value = Some((value, span)); } #[derive(Default, Debug)] @@ -102,6 +136,10 @@ impl DocParser { return; } + if !check_attr_crate_level(cx, path.span()) { + return; + } + self.attribute.no_crate_inject = Some(path.span()) } Some(sym::attr) => { @@ -155,6 +193,9 @@ impl DocParser { cx.emit_err(DocAliasStartEnd { span, attr_str }); return; } + if !check_attr_not_crate_level(cx, span, sym::alias) { + return; + } if let Some(first_definition) = self.attribute.aliases.get(&alias).copied() { cx.emit_lint( @@ -366,7 +407,33 @@ impl DocParser { self.attribute.$ident = Some(path.span()); }}; } - macro_rules! string_arg { + macro_rules! no_args_and_not_crate_level { + ($ident: ident) => {{ + if let Err(span) = args.no_args() { + cx.expected_no_args(span); + return; + } + let span = path.span(); + if !check_attr_not_crate_level(cx, span, sym::$ident) { + return; + } + self.attribute.$ident = Some(span); + }}; + } + macro_rules! no_args_and_crate_level { + ($ident: ident) => {{ + if let Err(span) = args.no_args() { + cx.expected_no_args(span); + return; + } + let span = path.span(); + if !check_attr_crate_level(cx, span) { + return; + } + self.attribute.$ident = Some(span); + }}; + } + macro_rules! string_arg_and_crate_level { ($ident: ident) => {{ let Some(nv) = args.name_value() else { cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym()); @@ -378,6 +445,10 @@ impl DocParser { return; }; + if !check_attr_crate_level(cx, path.span()) { + return; + } + // FIXME: It's errorring when the attribute is passed multiple times on the command // line. // The right fix for this would be to only check this rule if the attribute is @@ -394,12 +465,14 @@ impl DocParser { match path.word_sym() { Some(sym::alias) => self.parse_alias(cx, path, args), Some(sym::hidden) => no_args!(hidden), - Some(sym::html_favicon_url) => string_arg!(html_favicon_url), - Some(sym::html_logo_url) => string_arg!(html_logo_url), - Some(sym::html_no_source) => no_args!(html_no_source), - Some(sym::html_playground_url) => string_arg!(html_playground_url), - Some(sym::html_root_url) => string_arg!(html_root_url), - Some(sym::issue_tracker_base_url) => string_arg!(issue_tracker_base_url), + Some(sym::html_favicon_url) => string_arg_and_crate_level!(html_favicon_url), + Some(sym::html_logo_url) => string_arg_and_crate_level!(html_logo_url), + Some(sym::html_no_source) => no_args_and_crate_level!(html_no_source), + Some(sym::html_playground_url) => string_arg_and_crate_level!(html_playground_url), + Some(sym::html_root_url) => string_arg_and_crate_level!(html_root_url), + Some(sym::issue_tracker_base_url) => { + string_arg_and_crate_level!(issue_tracker_base_url) + } Some(sym::inline) => self.parse_inline(cx, path, args, DocInline::Inline), Some(sym::no_inline) => self.parse_inline(cx, path, args, DocInline::NoInline), Some(sym::masked) => no_args!(masked), @@ -410,18 +483,18 @@ impl DocParser { path, args, &mut self.attribute.keyword, - check_keyword, + sym::keyword, ), Some(sym::attribute) => parse_keyword_and_attribute( cx, path, args, &mut self.attribute.attribute, - check_attribute, + sym::attribute, ), - Some(sym::fake_variadic) => no_args!(fake_variadic), - Some(sym::search_unbox) => no_args!(search_unbox), - Some(sym::rust_logo) => no_args!(rust_logo), + Some(sym::fake_variadic) => no_args_and_not_crate_level!(fake_variadic), + Some(sym::search_unbox) => no_args_and_not_crate_level!(search_unbox), + Some(sym::rust_logo) => no_args_and_crate_level!(rust_logo), Some(sym::auto_cfg) => self.parse_auto_cfg(cx, path, args), Some(sym::test) => { let Some(list) = args.list() else { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 732bf111b256..2e7804e51d81 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -653,6 +653,7 @@ pub struct SharedContext<'p, 'sess, S: Stage> { pub(crate) target_span: Span, /// The id ([`NodeId`] if `S` is `Early`, [`HirId`] if `S` is `Late`) of the syntactical component this attribute was applied to pub(crate) target_id: S::Id, + pub(crate) target: Option, pub(crate) emit_lint: &'p mut dyn FnMut(AttributeLint), } diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index e38fffa6587c..d87fc3855954 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -218,6 +218,7 @@ impl<'sess> AttributeParser<'sess, Early> { cx: &mut parser, target_span, target_id: target_node_id, + target: None, emit_lint: &mut emit_lint, }, attr_span, @@ -378,6 +379,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { cx: self, target_span, target_id, + target: Some(target), emit_lint: &mut emit_lint, }, attr_span, @@ -429,6 +431,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { cx: self, target_span, target_id, + target: Some(target), emit_lint: &mut emit_lint, }, all_attrs: &attr_paths, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 20d00a82cadb..85e7891b1e64 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -47,6 +47,14 @@ pub(crate) struct DocAliasStartEnd<'a> { pub attr_str: &'a str, } +#[derive(Diagnostic)] +#[diag(attr_parsing_doc_attr_not_crate_level)] +pub(crate) struct DocAttrNotCrateLevel { + #[primary_span] + pub span: Span, + pub attr_name: Symbol, +} + #[derive(Diagnostic)] #[diag(attr_parsing_doc_keyword_not_keyword)] #[help] diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index b49b090272d4..9b0b1abc91df 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -40,6 +40,11 @@ lint_atomic_ordering_load = atomic loads cannot have `Release` or `AcqRel` order lint_atomic_ordering_store = atomic stores cannot have `Acquire` or `AcqRel` ordering .help = consider using ordering modes `Release`, `SeqCst` or `Relaxed` +lint_attr_crate_level = + this attribute can only be applied at the crate level + .suggestion = to apply to the crate, use an inner attribute + .note = read for more information + lint_bad_attribute_argument = bad attribute argument lint_bad_opt_access = {$msg} diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index f622de7f84d9..5745f0d4edde 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -417,5 +417,7 @@ pub fn decorate_attribute_lint( } &AttributeLintKind::DocTestLiteral => lints::DocTestLiteral.decorate_lint(diag), + + &AttributeLintKind::AttrCrateLevelOnly => lints::AttrCrateLevelOnly.decorate_lint(diag), } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 841b11c99687..33e9375ec71b 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3312,3 +3312,8 @@ pub(crate) struct DocTestUnknown { #[derive(LintDiagnostic)] #[diag(lint_doc_test_literal)] pub(crate) struct DocTestLiteral; + +#[derive(LintDiagnostic)] +#[diag(lint_attr_crate_level)] +#[note] +pub(crate) struct AttrCrateLevelOnly; diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 7b41cfbb43ef..c8713b23633f 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -820,6 +820,7 @@ pub enum AttributeLintKind { name: Symbol, }, DocTestLiteral, + AttrCrateLevelOnly, } pub type RegisteredTools = FxIndexSet; diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index ba44aa3a35ab..d8e5574efc91 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -29,11 +29,6 @@ passes_attr_application_struct_union = attribute should be applied to a struct or union .label = not a struct or union -passes_attr_crate_level = - this attribute can only be applied at the crate level - .suggestion = to apply to the crate, use an inner attribute - .note = read for more information - passes_autodiff_attr = `#[autodiff]` should be applied to a function .label = not a function @@ -112,9 +107,6 @@ passes_doc_alias_bad_location = passes_doc_alias_not_an_alias = `#[doc(alias = "{$attr_str}"]` is the same as the item's name -passes_doc_attr_not_crate_level = - `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute - passes_doc_fake_variadic_not_valid = `#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 360feacac0e9..512322f9e933 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1034,29 +1034,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks that an attribute is *not* used at the crate level. Returns `true` if valid. - fn check_attr_not_crate_level(&self, span: Span, hir_id: HirId, attr_name: &str) -> bool { - if CRATE_HIR_ID == hir_id { - self.dcx().emit_err(errors::DocAttrNotCrateLevel { span, attr_name }); - return false; - } - true - } - - /// Checks that an attribute is used at the crate level. Returns `true` if valid. - fn check_attr_crate_level(&self, span: Span, hir_id: HirId) -> bool { - if hir_id != CRATE_HIR_ID { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - span, - errors::AttrCrateLevelOnly {}, - ); - return false; - } - true - } - /// Runs various checks on `#[doc]` attributes. /// /// `specified_inline` should be initialized to `None` and kept for the scope @@ -1072,9 +1049,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { inline, // FIXME: currently unchecked cfg: _, - // already check in attr_parsing + // already checked in attr_parsing auto_cfg: _, - // already check in attr_parsing + // already checked in attr_parsing auto_cfg_change: _, fake_variadic, keyword, @@ -1082,70 +1059,48 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // FIXME: currently unchecked notable_trait: _, search_unbox, - html_favicon_url, - html_logo_url, - html_playground_url, - html_root_url, - html_no_source, - issue_tracker_base_url, + // already checked in attr_parsing + html_favicon_url: _, + // already checked in attr_parsing + html_logo_url: _, + // already checked in attr_parsing + html_playground_url: _, + // already checked in attr_parsing + html_root_url: _, + // already checked in attr_parsing + html_no_source: _, + // already checked in attr_parsing + issue_tracker_base_url: _, rust_logo, // allowed anywhere test_attrs: _, - no_crate_inject, + // already checked in attr_parsing + no_crate_inject: _, attribute, } = attr; for (alias, span) in aliases { - if self.check_attr_not_crate_level(*span, hir_id, "alias") { - self.check_doc_alias_value(*span, hir_id, target, *alias); - } + self.check_doc_alias_value(*span, hir_id, target, *alias); } - if let Some((_, span)) = keyword - && self.check_attr_not_crate_level(*span, hir_id, "keyword") - { + if let Some((_, span)) = keyword { self.check_doc_keyword_and_attribute(*span, hir_id, "keyword"); } - if let Some((_, span)) = attribute - && self.check_attr_not_crate_level(*span, hir_id, "attribute") - { + if let Some((_, span)) = attribute { self.check_doc_keyword_and_attribute(*span, hir_id, "attribute"); } - if let Some(span) = fake_variadic - && self.check_attr_not_crate_level(*span, hir_id, "fake_variadic") - { + if let Some(span) = fake_variadic { self.check_doc_fake_variadic(*span, hir_id); } - if let Some(span) = search_unbox - && self.check_attr_not_crate_level(*span, hir_id, "search_unbox") - { + if let Some(span) = search_unbox { self.check_doc_search_unbox(*span, hir_id); } - for i in [ - html_favicon_url, - html_logo_url, - html_playground_url, - issue_tracker_base_url, - html_root_url, - ] { - if let Some((_, span)) = i { - self.check_attr_crate_level(*span, hir_id); - } - } - - for i in [html_no_source, no_crate_inject] { - if let Some(span) = i { - self.check_attr_crate_level(*span, hir_id); - } - } - self.check_doc_inline(hir_id, target, inline); if let Some(span) = rust_logo - && self.check_attr_crate_level(*span, hir_id) && !self.tcx.features().rustdoc_internals() { feature_err( diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 14555765e423..c1b5988cc7f6 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -179,14 +179,6 @@ pub(crate) struct DocMaskedNotExternCrateSelf { pub item_span: Span, } -#[derive(Diagnostic)] -#[diag(passes_doc_attr_not_crate_level)] -pub(crate) struct DocAttrNotCrateLevel<'a> { - #[primary_span] - pub span: Span, - pub attr_name: &'a str, -} - #[derive(Diagnostic)] #[diag(passes_both_ffi_const_and_pure, code = E0757)] pub(crate) struct BothFfiConstAndPure { @@ -1104,11 +1096,6 @@ pub(crate) struct UnnecessaryPartialStableFeature { #[note] pub(crate) struct IneffectiveUnstableImpl; -#[derive(LintDiagnostic)] -#[diag(passes_attr_crate_level)] -#[note] -pub(crate) struct AttrCrateLevelOnly {} - /// "sanitize attribute not allowed here" #[derive(Diagnostic)] #[diag(passes_sanitize_attribute_not_allowed)] diff --git a/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs b/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs new file mode 100644 index 000000000000..275e20e80a17 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs @@ -0,0 +1,13 @@ +#![crate_type = "lib"] + +#[doc(test(no_crate_inject))] +//~^ ERROR can only be applied at the crate level + +pub mod bar { + #![doc(test(no_crate_inject))] + //~^ ERROR can only be applied at the crate level + + #[doc(test(no_crate_inject))] + //~^ ERROR can only be applied at the crate level + fn foo() {} +} diff --git a/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr b/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr new file mode 100644 index 000000000000..fdb95e7de41c --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr @@ -0,0 +1,27 @@ +error: this attribute can only be applied at the crate level + --> $DIR/invalid-crate-level-lint.rs:3:12 + | +LL | #[doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ + | + = note: read for more information + = note: `#[deny(invalid_doc_attributes)]` on by default + +error: this attribute can only be applied at the crate level + --> $DIR/invalid-crate-level-lint.rs:7:17 + | +LL | #![doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ + | + = note: read for more information + +error: this attribute can only be applied at the crate level + --> $DIR/invalid-crate-level-lint.rs:10:16 + | +LL | #[doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ + | + = note: read for more information + +error: aborting due to 3 previous errors + diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.rs b/tests/rustdoc-ui/lints/invalid-doc-attr.rs index a8c42b8fd79c..169d092d7e17 100644 --- a/tests/rustdoc-ui/lints/invalid-doc-attr.rs +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.rs @@ -4,18 +4,11 @@ #![doc(masked)] //~^ ERROR this attribute can only be applied to an `extern crate` item -#[doc(test(no_crate_inject))] -//~^ ERROR can only be applied at the crate level #[doc(inline)] //~^ ERROR can only be applied to a `use` item pub fn foo() {} pub mod bar { - #![doc(test(no_crate_inject))] - //~^ ERROR can only be applied at the crate level - - #[doc(test(no_crate_inject))] - //~^ ERROR can only be applied at the crate level #[doc(inline)] //~^ ERROR can only be applied to a `use` item pub fn baz() {} diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr index 82e1b62b57a6..e431b8df2263 100644 --- a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr @@ -1,14 +1,5 @@ -error: this attribute can only be applied at the crate level - --> $DIR/invalid-doc-attr.rs:7:12 - | -LL | #[doc(test(no_crate_inject))] - | ^^^^^^^^^^^^^^^ - | - = note: read for more information - = note: `#[deny(invalid_doc_attributes)]` on by default - error: this attribute can only be applied to a `use` item - --> $DIR/invalid-doc-attr.rs:9:7 + --> $DIR/invalid-doc-attr.rs:7:7 | LL | #[doc(inline)] | ^^^^^^ only applicable on `use` items @@ -17,17 +8,10 @@ LL | pub fn foo() {} | ------------ not a `use` item | = note: read for more information - -error: this attribute can only be applied at the crate level - --> $DIR/invalid-doc-attr.rs:14:17 - | -LL | #![doc(test(no_crate_inject))] - | ^^^^^^^^^^^^^^^ - | - = note: read for more information + = note: `#[deny(invalid_doc_attributes)]` on by default error: conflicting doc inlining attributes - --> $DIR/invalid-doc-attr.rs:24:7 + --> $DIR/invalid-doc-attr.rs:17:7 | LL | #[doc(inline)] | ^^^^^^ this attribute... @@ -37,7 +21,7 @@ LL | #[doc(no_inline)] = help: remove one of the conflicting attributes error: this attribute can only be applied to an `extern crate` item - --> $DIR/invalid-doc-attr.rs:30:7 + --> $DIR/invalid-doc-attr.rs:23:7 | LL | #[doc(masked)] | ^^^^^^ only applicable on `extern crate` items @@ -48,7 +32,7 @@ LL | pub struct Masked; = note: read for more information error: this attribute cannot be applied to an `extern crate self` item - --> $DIR/invalid-doc-attr.rs:34:7 + --> $DIR/invalid-doc-attr.rs:27:7 | LL | #[doc(masked)] | ^^^^^^ not applicable on `extern crate self` items @@ -70,16 +54,8 @@ LL | | pub extern crate self as reexport; | = note: read for more information -error: this attribute can only be applied at the crate level - --> $DIR/invalid-doc-attr.rs:17:16 - | -LL | #[doc(test(no_crate_inject))] - | ^^^^^^^^^^^^^^^ - | - = note: read for more information - error: this attribute can only be applied to a `use` item - --> $DIR/invalid-doc-attr.rs:19:11 + --> $DIR/invalid-doc-attr.rs:12:11 | LL | #[doc(inline)] | ^^^^^^ only applicable on `use` items @@ -89,5 +65,5 @@ LL | pub fn baz() {} | = note: read for more information -error: aborting due to 9 previous errors +error: aborting due to 6 previous errors diff --git a/tests/ui/rustdoc/doc-alias-crate-level.stderr b/tests/ui/rustdoc/doc-alias-crate-level.stderr index a40e31714f14..1d10446a4e7c 100644 --- a/tests/ui/rustdoc/doc-alias-crate-level.stderr +++ b/tests/ui/rustdoc/doc-alias-crate-level.stderr @@ -1,14 +1,14 @@ -error: '\'' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/doc-alias-crate-level.rs:7:15 - | -LL | #[doc(alias = "shouldn't work!")] - | ^^^^^^^^^^^^^^^^^ - error: `#![doc(alias = "...")]` isn't allowed as a crate-level attribute --> $DIR/doc-alias-crate-level.rs:5:16 | LL | #![doc(alias = "not working!")] | ^^^^^^^^^^^^^^ +error: '\'' character isn't allowed in `#[doc(alias = "...")]` + --> $DIR/doc-alias-crate-level.rs:7:15 + | +LL | #[doc(alias = "shouldn't work!")] + | ^^^^^^^^^^^^^^^^^ + error: aborting due to 2 previous errors diff --git a/tests/ui/rustdoc/doc_keyword.stderr b/tests/ui/rustdoc/doc_keyword.stderr index 56da4b00724a..c8038cbf0196 100644 --- a/tests/ui/rustdoc/doc_keyword.stderr +++ b/tests/ui/rustdoc/doc_keyword.stderr @@ -1,3 +1,9 @@ +error: `#![doc(keyword = "...")]` isn't allowed as a crate-level attribute + --> $DIR/doc_keyword.rs:4:8 + | +LL | #![doc(keyword = "match")] + | ^^^^^^^ + error: nonexistent keyword `tadam` used in `#[doc(keyword = "...")]` --> $DIR/doc_keyword.rs:22:17 | @@ -24,11 +30,5 @@ error: `#[doc(keyword = "...")]` should be used on modules LL | #[doc(keyword = "match")] | ^^^^^^^ -error: `#![doc(keyword = "...")]` isn't allowed as a crate-level attribute - --> $DIR/doc_keyword.rs:4:8 - | -LL | #![doc(keyword = "match")] - | ^^^^^^^ - error: aborting due to 5 previous errors From 76ad528d32db21abca9d9f55c5abc8666d4a2afe Mon Sep 17 00:00:00 2001 From: Usman Akinyemi Date: Sun, 11 Jan 2026 04:49:50 +0530 Subject: [PATCH 1958/3801] rustc_parse_format: improve diagnostics for unsupported python numeric grouping Detect Python-style numeric grouping syntax in format strings (e.g. `{x:,}`) and emit a clear diagnostic explaining that it is not supported in Rust. This helps users coming from Python understand the error without exposing the full set of valid Rust format specifiers. Signed-off-by: Usman Akinyemi --- compiler/rustc_parse_format/src/lib.rs | 22 ++++++++++++++++++++++ tests/ui/fmt/format-string-error-2.rs | 2 ++ tests/ui/fmt/format-string-error-2.stderr | 12 +++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 143fd0c4436c..490af1257760 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -461,6 +461,7 @@ impl<'input> Parser<'input> { ('?', '}') => self.missing_colon_before_debug_formatter(), ('?', _) => self.suggest_format_debug(), ('<' | '^' | '>', _) => self.suggest_format_align(c), + (',', _) => self.suggest_unsupported_python_numeric_grouping(), _ => self.suggest_positional_arg_instead_of_captured_arg(arg), } } @@ -934,6 +935,27 @@ impl<'input> Parser<'input> { } } } + + fn suggest_unsupported_python_numeric_grouping(&mut self) { + if let Some((range, _)) = self.consume_pos(',') { + self.errors.insert( + 0, + ParseError { + description: + "python's numeric grouping `,` is not supported in rust format strings" + .to_owned(), + note: Some(format!("to print `{{`, you can escape it using `{{{{`",)), + label: "expected `}`".to_owned(), + span: range, + secondary_label: self + .last_open_brace + .clone() + .map(|sp| ("because of this opening brace".to_owned(), sp)), + suggestion: Suggestion::None, + }, + ); + } + } } // Assert a reasonable size for `Piece` diff --git a/tests/ui/fmt/format-string-error-2.rs b/tests/ui/fmt/format-string-error-2.rs index e14a4064aa83..63d65023eb78 100644 --- a/tests/ui/fmt/format-string-error-2.rs +++ b/tests/ui/fmt/format-string-error-2.rs @@ -86,4 +86,6 @@ raw { \n println!("{x?}, world!",); //~^ ERROR invalid format string: expected `}`, found `?` + println!("{x,}, world!",); + //~^ ERROR invalid format string: python's numeric grouping `,` is not supported in rust format strings } diff --git a/tests/ui/fmt/format-string-error-2.stderr b/tests/ui/fmt/format-string-error-2.stderr index b117fb57cf07..e7fbc2e81fc6 100644 --- a/tests/ui/fmt/format-string-error-2.stderr +++ b/tests/ui/fmt/format-string-error-2.stderr @@ -188,5 +188,15 @@ LL | println!("{x?}, world!",); | = note: to print `{`, you can escape it using `{{` -error: aborting due to 19 previous errors +error: invalid format string: python's numeric grouping `,` is not supported in rust format strings + --> $DIR/format-string-error-2.rs:89:17 + | +LL | println!("{x,}, world!",); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: to print `{`, you can escape it using `{{` + +error: aborting due to 20 previous errors From 8d1d88bfc4768a43c845d3de04e1ace4e9d0c1a3 Mon Sep 17 00:00:00 2001 From: vsriram Date: Mon, 12 Jan 2026 00:07:07 +0530 Subject: [PATCH 1959/3801] ui: add test for normalizing const projections with assoc const equality --- .../normalization-via-param-env.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs diff --git a/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs b/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs new file mode 100644 index 000000000000..c7bb5bccedb3 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs @@ -0,0 +1,18 @@ +//@ check-pass +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +// Regression test for normalizing const projections +// with associated const equality bounds. + +trait Trait { + #[type_const] + const C: usize; +} + +fn f>() { + // This must normalize ::C to 1 + let _: [(); T::C] = [()]; +} + +fn main() {} From 8a71deb28275b847492208a325db589f2c222a49 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Thu, 8 Jan 2026 23:26:12 +0100 Subject: [PATCH 1960/3801] add `manual_take` lint --- CHANGELOG.md | 1 + book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + clippy_lints/src/manual_take.rs | 114 +++++++++++++++++++++++++++++ tests/ui/manual_take.fixed | 57 +++++++++++++++ tests/ui/manual_take.rs | 69 +++++++++++++++++ tests/ui/manual_take.stderr | 53 ++++++++++++++ tests/ui/manual_take_nocore.rs | 37 ++++++++++ tests/ui/manual_take_nocore.stderr | 0 tests/ui/manual_take_nostd.fixed | 10 +++ tests/ui/manual_take_nostd.rs | 22 ++++++ tests/ui/manual_take_nostd.stderr | 54 ++++++++++++++ 14 files changed, 422 insertions(+) create mode 100644 clippy_lints/src/manual_take.rs create mode 100644 tests/ui/manual_take.fixed create mode 100644 tests/ui/manual_take.rs create mode 100644 tests/ui/manual_take.stderr create mode 100644 tests/ui/manual_take_nocore.rs create mode 100644 tests/ui/manual_take_nocore.stderr create mode 100644 tests/ui/manual_take_nostd.fixed create mode 100644 tests/ui/manual_take_nostd.rs create mode 100644 tests/ui/manual_take_nostd.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cda8003b05c..b5172267fcaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6653,6 +6653,7 @@ Released 2018-09-13 [`manual_string_new`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_string_new [`manual_strip`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip [`manual_swap`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_swap +[`manual_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_take [`manual_try_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold [`manual_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or [`manual_unwrap_or_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or_default diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index a1c079898594..f81dd421f59b 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -905,6 +905,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once) * [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat) * [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip) +* [`manual_take`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_take) * [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold) * [`map_clone`](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone) * [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index e1d7c1d88eb9..849d9a613d80 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -780,6 +780,7 @@ define_Conf! { manual_split_once, manual_str_repeat, manual_strip, + manual_take, manual_try_fold, map_clone, map_unwrap_or, diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index ef9da84c4407..549fc64d50e2 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -316,6 +316,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::manual_slice_size_calculation::MANUAL_SLICE_SIZE_CALCULATION_INFO, crate::manual_string_new::MANUAL_STRING_NEW_INFO, crate::manual_strip::MANUAL_STRIP_INFO, + crate::manual_take::MANUAL_TAKE_INFO, crate::map_unit_fn::OPTION_MAP_UNIT_FN_INFO, crate::map_unit_fn::RESULT_MAP_UNIT_FN_INFO, crate::match_result_ok::MATCH_RESULT_OK_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index ef2461f8b097..eccff4789a20 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -219,6 +219,7 @@ mod manual_rotate; mod manual_slice_size_calculation; mod manual_string_new; mod manual_strip; +mod manual_take; mod map_unit_fn; mod match_result_ok; mod matches; @@ -861,6 +862,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(move |_| Box::new(manual_ilog2::ManualIlog2::new(conf))), Box::new(|_| Box::new(same_length_and_capacity::SameLengthAndCapacity)), Box::new(move |tcx| Box::new(duration_suboptimal_units::DurationSuboptimalUnits::new(tcx, conf))), + Box::new(move |_| Box::new(manual_take::ManualTake::new(conf))), // add late passes here, used by `cargo dev new_lint` ]; store.late_passes.extend(late_lints); diff --git a/clippy_lints/src/manual_take.rs b/clippy_lints/src/manual_take.rs new file mode 100644 index 000000000000..8e74d04c4556 --- /dev/null +++ b/clippy_lints/src/manual_take.rs @@ -0,0 +1,114 @@ +use clippy_config::Conf; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{MEM_TAKE, Msrv}; +use clippy_utils::source::snippet_with_context; +use rustc_ast::LitKind; +use rustc_errors::Applicability; +use rustc_hir::{Block, Expr, ExprKind, StmtKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_session::impl_lint_pass; + +declare_clippy_lint! { + /// ### What it does + /// Detects manual re-implementations of `std::mem::take`. + /// + /// ### Why is this bad? + /// Because the function call is shorter and easier to read. + /// + /// ### Known issues + /// Currently the lint only detects cases involving `bool`s. + /// + /// ### Example + /// ```no_run + /// let mut x = true; + /// let _ = if x { + /// x = false; + /// true + /// } else { + /// false + /// }; + /// ``` + /// Use instead: + /// ```no_run + /// let mut x = true; + /// let _ = std::mem::take(&mut x); + /// ``` + #[clippy::version = "1.94.0"] + pub MANUAL_TAKE, + complexity, + "manual `mem::take` implementation" +} +pub struct ManualTake { + msrv: Msrv, +} + +impl ManualTake { + pub fn new(conf: &'static Conf) -> Self { + Self { msrv: conf.msrv } + } +} + +impl_lint_pass!(ManualTake => [MANUAL_TAKE]); + +impl LateLintPass<'_> for ManualTake { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + if let ExprKind::If(cond, then, Some(otherwise)) = expr.kind + && let ExprKind::Path(_) = cond.kind + && let ExprKind::Block( + Block { + stmts: [stmt], + expr: Some(then_expr), + .. + }, + .., + ) = then.kind + && let ExprKind::Block( + Block { + stmts: [], + expr: Some(else_expr), + .. + }, + .., + ) = otherwise.kind + && let StmtKind::Semi(assignment) = stmt.kind + && let ExprKind::Assign(mut_c, possible_false, _) = assignment.kind + && let ExprKind::Path(_) = mut_c.kind + && !expr.span.in_external_macro(cx.sess().source_map()) + && let Some(std_or_core) = clippy_utils::std_or_core(cx) + && self.msrv.meets(cx, MEM_TAKE) + && clippy_utils::SpanlessEq::new(cx).eq_expr(cond, mut_c) + && Some(false) == as_const_bool(possible_false) + && let Some(then_bool) = as_const_bool(then_expr) + && let Some(else_bool) = as_const_bool(else_expr) + && then_bool != else_bool + { + span_lint_and_then( + cx, + MANUAL_TAKE, + expr.span, + "manual implementation of `mem::take`", + |diag| { + let mut app = Applicability::MachineApplicable; + let negate = if then_bool { "" } else { "!" }; + let taken = snippet_with_context(cx, cond.span, expr.span.ctxt(), "_", &mut app).0; + diag.span_suggestion_verbose( + expr.span, + "use", + format!("{negate}{std_or_core}::mem::take(&mut {taken})"), + app, + ); + }, + ); + } + } +} + +fn as_const_bool(e: &Expr<'_>) -> Option { + if let ExprKind::Lit(lit) = e.kind + && let LitKind::Bool(b) = lit.node + { + Some(b) + } else { + None + } +} diff --git a/tests/ui/manual_take.fixed b/tests/ui/manual_take.fixed new file mode 100644 index 000000000000..5891bd49c81c --- /dev/null +++ b/tests/ui/manual_take.fixed @@ -0,0 +1,57 @@ +#![warn(clippy::manual_take)] + +fn main() { + msrv_1_39(); + msrv_1_40(); + let mut x = true; + let mut y = false; + + let _lint_negated = !std::mem::take(&mut x); + + let _ = if x { + y = false; + true + } else { + false + }; + + let _ = if x { + x = true; + true + } else { + false + }; + + let _ = if x { + x = false; + y = true; + false + } else { + true + }; + + let _ = if x { + x = false; + false + } else { + y = true; + true + }; +} + +#[clippy::msrv = "1.39.0"] +fn msrv_1_39() -> bool { + let mut x = true; + if x { + x = false; + true + } else { + false + } +} + +#[clippy::msrv = "1.40.0"] +fn msrv_1_40() -> bool { + let mut x = true; + std::mem::take(&mut x) +} diff --git a/tests/ui/manual_take.rs b/tests/ui/manual_take.rs new file mode 100644 index 000000000000..89903fcb2416 --- /dev/null +++ b/tests/ui/manual_take.rs @@ -0,0 +1,69 @@ +#![warn(clippy::manual_take)] + +fn main() { + msrv_1_39(); + msrv_1_40(); + let mut x = true; + let mut y = false; + + let _lint_negated = if x { + //~^ manual_take + x = false; + false + } else { + true + }; + + let _ = if x { + y = false; + true + } else { + false + }; + + let _ = if x { + x = true; + true + } else { + false + }; + + let _ = if x { + x = false; + y = true; + false + } else { + true + }; + + let _ = if x { + x = false; + false + } else { + y = true; + true + }; +} + +#[clippy::msrv = "1.39.0"] +fn msrv_1_39() -> bool { + let mut x = true; + if x { + x = false; + true + } else { + false + } +} + +#[clippy::msrv = "1.40.0"] +fn msrv_1_40() -> bool { + let mut x = true; + if x { + //~^ manual_take + x = false; + true + } else { + false + } +} diff --git a/tests/ui/manual_take.stderr b/tests/ui/manual_take.stderr new file mode 100644 index 000000000000..69ba7778a275 --- /dev/null +++ b/tests/ui/manual_take.stderr @@ -0,0 +1,53 @@ +error: manual implementation of `mem::take` + --> tests/ui/manual_take.rs:9:25 + | +LL | let _lint_negated = if x { + | _________________________^ +LL | | +LL | | x = false; +LL | | false +LL | | } else { +LL | | true +LL | | }; + | |_____^ + | + = note: `-D clippy::manual-take` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_take)]` +help: use + | +LL - let _lint_negated = if x { +LL - +LL - x = false; +LL - false +LL - } else { +LL - true +LL - }; +LL + let _lint_negated = !std::mem::take(&mut x); + | + +error: manual implementation of `mem::take` + --> tests/ui/manual_take.rs:62:5 + | +LL | / if x { +LL | | +LL | | x = false; +LL | | true +LL | | } else { +LL | | false +LL | | } + | |_____^ + | +help: use + | +LL - if x { +LL - +LL - x = false; +LL - true +LL - } else { +LL - false +LL - } +LL + std::mem::take(&mut x) + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/manual_take_nocore.rs b/tests/ui/manual_take_nocore.rs new file mode 100644 index 000000000000..ef4f23395028 --- /dev/null +++ b/tests/ui/manual_take_nocore.rs @@ -0,0 +1,37 @@ +//@ check-pass +#![feature(no_core, lang_items)] +#![no_core] +#![allow(clippy::missing_safety_doc)] +#![warn(clippy::manual_take)] + +#[link(name = "c")] +unsafe extern "C" {} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} +#[lang = "copy"] +pub trait Copy {} +#[lang = "freeze"] +pub unsafe trait Freeze {} + +#[lang = "start"] +fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + 0 +} + +fn main() { + let mut x = true; + // this should not lint because we don't have std nor core + let _manual_take = if x { + x = false; + true + } else { + false + }; +} diff --git a/tests/ui/manual_take_nocore.stderr b/tests/ui/manual_take_nocore.stderr new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/ui/manual_take_nostd.fixed b/tests/ui/manual_take_nostd.fixed new file mode 100644 index 000000000000..123c5a91998c --- /dev/null +++ b/tests/ui/manual_take_nostd.fixed @@ -0,0 +1,10 @@ +#![no_std] +#![warn(clippy::manual_take)] + +pub fn manual_mem_take_should_reference_core() { + let mut x = true; + + let _lint_negated = !core::mem::take(&mut x); + + let _lint = core::mem::take(&mut x); +} diff --git a/tests/ui/manual_take_nostd.rs b/tests/ui/manual_take_nostd.rs new file mode 100644 index 000000000000..0df352477b74 --- /dev/null +++ b/tests/ui/manual_take_nostd.rs @@ -0,0 +1,22 @@ +#![no_std] +#![warn(clippy::manual_take)] + +pub fn manual_mem_take_should_reference_core() { + let mut x = true; + + let _lint_negated = if x { + //~^ manual_take + x = false; + false + } else { + true + }; + + let _lint = if x { + //~^ manual_take + x = false; + true + } else { + false + }; +} diff --git a/tests/ui/manual_take_nostd.stderr b/tests/ui/manual_take_nostd.stderr new file mode 100644 index 000000000000..71a5066e4db3 --- /dev/null +++ b/tests/ui/manual_take_nostd.stderr @@ -0,0 +1,54 @@ +error: manual implementation of `mem::take` + --> tests/ui/manual_take_nostd.rs:7:25 + | +LL | let _lint_negated = if x { + | _________________________^ +LL | | +LL | | x = false; +LL | | false +LL | | } else { +LL | | true +LL | | }; + | |_____^ + | + = note: `-D clippy::manual-take` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_take)]` +help: use + | +LL - let _lint_negated = if x { +LL - +LL - x = false; +LL - false +LL - } else { +LL - true +LL - }; +LL + let _lint_negated = !core::mem::take(&mut x); + | + +error: manual implementation of `mem::take` + --> tests/ui/manual_take_nostd.rs:15:17 + | +LL | let _lint = if x { + | _________________^ +LL | | +LL | | x = false; +LL | | true +LL | | } else { +LL | | false +LL | | }; + | |_____^ + | +help: use + | +LL - let _lint = if x { +LL - +LL - x = false; +LL - true +LL - } else { +LL - false +LL - }; +LL + let _lint = core::mem::take(&mut x); + | + +error: aborting due to 2 previous errors + From d0204a399a7f3a2d9c5ea4d2d2c897ce0536b5eb Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 11 Jan 2026 21:10:17 +0100 Subject: [PATCH 1961/3801] remove `impl Neg` on s390x/powerpc vector types For other targets we don't have such instances. We specifically decided agains implementing arithmetic operators on these low-level vector types --- .../crates/core_arch/src/powerpc/altivec.rs | 51 +++++++++++++++--- .../crates/core_arch/src/powerpc/macros.rs | 14 ----- .../crates/core_arch/src/s390x/macros.rs | 14 ----- .../crates/core_arch/src/s390x/vector.rs | 54 ++++++++++++++++--- 4 files changed, 91 insertions(+), 42 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs index 37b557c3b2af..c1881da08f86 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs @@ -364,15 +364,46 @@ unsafe extern "C" { fn vrfin(a: vector_float) -> vector_float; } -impl_neg! { i8x16 : 0 } -impl_neg! { i16x8 : 0 } -impl_neg! { i32x4 : 0 } -impl_neg! { f32x4 : 0f32 } - #[macro_use] mod sealed { use super::*; + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + pub trait VectorNeg { + unsafe fn vec_neg(self) -> Self; + } + + macro_rules! impl_neg { + ($($v:ty)*) => { + $( + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + impl VectorNeg for $v { + #[inline] + #[target_feature(enable = "altivec")] + unsafe fn vec_neg(self) -> Self { + simd_neg(self) + } + } + )* + } + } + + impl_neg! { + vector_signed_char + vector_unsigned_char + vector_bool_char + + vector_signed_short + vector_unsigned_short + vector_bool_short + + vector_signed_int + vector_unsigned_int + vector_bool_int + + vector_float + } + #[unstable(feature = "stdarch_powerpc", issue = "111145")] pub trait VectorInsert { type Scalar; @@ -1378,7 +1409,7 @@ mod sealed { #[inline] #[target_feature(enable = "altivec")] unsafe fn $name(v: s_t_l!($ty)) -> s_t_l!($ty) { - v.vec_max(-v) + v.vec_max(simd_neg(v)) } impl_vec_trait! { [VectorAbs vec_abs] $name (s_t_l!($ty)) } @@ -4030,6 +4061,14 @@ pub unsafe fn vec_mfvscr() -> vector_unsigned_short { mfvscr() } +/// Vector Negate +#[inline] +#[target_feature(enable = "altivec")] +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +pub unsafe fn vec_neg(a: T) -> T { + a.vec_neg() +} + /// Vector add. #[inline] #[target_feature(enable = "altivec")] diff --git a/library/stdarch/crates/core_arch/src/powerpc/macros.rs b/library/stdarch/crates/core_arch/src/powerpc/macros.rs index 6097ca31adc9..f697d4d25748 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/macros.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/macros.rs @@ -274,20 +274,6 @@ macro_rules! t_b { }; } -macro_rules! impl_neg { - ($s: ident : $zero: expr) => { - #[unstable(feature = "stdarch_powerpc", issue = "111145")] - impl crate::ops::Neg for s_t_l!($s) { - type Output = s_t_l!($s); - #[inline] - fn neg(self) -> Self::Output { - unsafe { simd_neg(self) } - } - } - }; -} - -pub(crate) use impl_neg; pub(crate) use impl_vec_trait; pub(crate) use s_t_l; pub(crate) use t_b; diff --git a/library/stdarch/crates/core_arch/src/s390x/macros.rs b/library/stdarch/crates/core_arch/src/s390x/macros.rs index b72560396c43..c47f242948df 100644 --- a/library/stdarch/crates/core_arch/src/s390x/macros.rs +++ b/library/stdarch/crates/core_arch/src/s390x/macros.rs @@ -431,20 +431,6 @@ macro_rules! t_b { }; } -macro_rules! impl_neg { - ($s: ident : $zero: expr) => { - #[unstable(feature = "stdarch_s390x", issue = "135681")] - impl crate::ops::Neg for s_t_l!($s) { - type Output = s_t_l!($s); - #[inline] - fn neg(self) -> Self::Output { - unsafe { simd_neg(self) } - } - } - }; -} - -pub(crate) use impl_neg; pub(crate) use impl_vec_trait; pub(crate) use l_t_t; pub(crate) use s_t_l; diff --git a/library/stdarch/crates/core_arch/src/s390x/vector.rs b/library/stdarch/crates/core_arch/src/s390x/vector.rs index d63f37eeb9a8..97bfa32f17ad 100644 --- a/library/stdarch/crates/core_arch/src/s390x/vector.rs +++ b/library/stdarch/crates/core_arch/src/s390x/vector.rs @@ -283,13 +283,6 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vfenezfs"] fn vfenezfs(a: i32x4, b: i32x4) -> PackedTuple; } -impl_neg! { i8x16 : 0 } -impl_neg! { i16x8 : 0 } -impl_neg! { i32x4 : 0 } -impl_neg! { i64x2 : 0 } -impl_neg! { f32x4 : 0f32 } -impl_neg! { f64x2 : 0f64 } - #[repr(simd)] struct ShuffleMask([u32; N]); @@ -437,6 +430,43 @@ enum FindImm { mod sealed { use super::*; + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorNeg { + unsafe fn vec_neg(self) -> Self; + } + + macro_rules! impl_neg { + ($($v:ty)*) => { + $( + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorNeg for $v { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_neg(self) -> Self { + simd_neg(self) + } + } + )* + } + } + + impl_neg! { + vector_signed_char + vector_unsigned_char + + vector_signed_short + vector_unsigned_short + + vector_signed_int + vector_unsigned_int + + vector_signed_long_long + vector_unsigned_long_long + + vector_float + vector_double + } + #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorAdd { type Result; @@ -759,7 +789,7 @@ mod sealed { #[inline] #[target_feature(enable = "vector")] unsafe fn $name(v: s_t_l!($ty)) -> s_t_l!($ty) { - v.vec_max(-v) + v.vec_max(simd_neg(v)) } impl_vec_trait! { [VectorAbs vec_abs] $name (s_t_l!($ty)) } @@ -4053,6 +4083,14 @@ unsafe fn __lcbb(ptr: *const u8) -> u32 { lcbb(ptr, const { validate_block_boundary(BLOCK_BOUNDARY) }) } +/// Vector Negate +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_neg(a: T) -> T { + a.vec_neg() +} + /// Vector Add #[inline] #[target_feature(enable = "vector")] From 2ae298711f92a79ea5bc59479846bfeea49481ef Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 9 Jan 2026 10:42:48 +1100 Subject: [PATCH 1962/3801] Replace two `BottomUpFolder`s with `fold_regions`. Because these folders only change regions. Note: `BottomUpFolder` folds all regions, while `fold_regions` skips some bound regions. But that's ok because these two folders only modify `ReVar`s. --- .../src/interpret/intrinsics.rs | 11 +++-------- compiler/rustc_hir_analysis/src/check/check.rs | 17 ++++++----------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 94832c0c2577..fe1dd1b6eb35 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -13,7 +13,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint}; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt}; use rustc_middle::{bug, span_bug, ty}; use rustc_span::{Symbol, sym}; use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; @@ -243,13 +243,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ocx.register_obligations(preds.iter().map(|pred: PolyExistentialPredicate<'_>| { let pred = pred.with_self_ty(tcx, tp_ty); // Lifetimes can only be 'static because of the bound on T - let pred = pred.fold_with(&mut ty::BottomUpFolder { - tcx, - ty_op: |ty| ty, - lt_op: |lt| { - if lt == tcx.lifetimes.re_erased { tcx.lifetimes.re_static } else { lt } - }, - ct_op: |ct| ct, + let pred = ty::fold_regions(tcx, pred, |r, _| { + if r == tcx.lifetimes.re_erased { tcx.lifetimes.re_static } else { r } }); Obligation::new(tcx, ObligationCause::dummy(), param_env, pred) })); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index ad66003a6bf9..4664bfcce853 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -508,23 +508,18 @@ fn sanity_check_found_hidden_type<'tcx>( return Ok(()); } } - let strip_vars = |ty: Ty<'tcx>| { - ty.fold_with(&mut BottomUpFolder { - tcx, - ty_op: |t| t, - ct_op: |c| c, - lt_op: |l| match l.kind() { - RegionKind::ReVar(_) => tcx.lifetimes.re_erased, - _ => l, - }, + let erase_re_vars = |ty: Ty<'tcx>| { + fold_regions(tcx, ty, |r, _| match r.kind() { + RegionKind::ReVar(_) => tcx.lifetimes.re_erased, + _ => r, }) }; // Closures frequently end up containing erased lifetimes in their final representation. // These correspond to lifetime variables that never got resolved, so we patch this up here. - ty.ty = strip_vars(ty.ty); + ty.ty = erase_re_vars(ty.ty); // Get the hidden type. let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args); - let hidden_ty = strip_vars(hidden_ty); + let hidden_ty = erase_re_vars(hidden_ty); // If the hidden types differ, emit a type mismatch diagnostic. if hidden_ty == ty.ty { From 71d1b2ca7fe64242d1f5a2a96da7a32b78bbcc9b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 9 Jan 2026 13:09:14 +1100 Subject: [PATCH 1963/3801] Whitespace fixes. --- compiler/rustc_type_ir/src/flags.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 2c1fc7decc3e..8b057e5866cd 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -74,7 +74,7 @@ bitflags::bitflags! { /// Does this have `Projection`? const HAS_TY_PROJECTION = 1 << 10; /// Does this have `Free` aliases? - const HAS_TY_FREE_ALIAS = 1 << 11; + const HAS_TY_FREE_ALIAS = 1 << 11; /// Does this have `Opaque`? const HAS_TY_OPAQUE = 1 << 12; /// Does this have `Inherent`? @@ -135,7 +135,7 @@ bitflags::bitflags! { const HAS_TY_CORO = 1 << 24; /// Does this have have a `Bound(BoundVarIndexKind::Canonical, _)`? - const HAS_CANONICAL_BOUND = 1 << 25; + const HAS_CANONICAL_BOUND = 1 << 25; } } From 02e0879c5d7eb637bcb4df78f247fe23abd10e6a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 9 Jan 2026 13:01:45 +1100 Subject: [PATCH 1964/3801] Remove redundant call to `erase_and_anonymize_regions`. The exact same call appears earlier in this function. --- compiler/rustc_ty_utils/src/instance.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 23bbd9ca6d63..cbe15eb54787 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -222,8 +222,6 @@ fn resolve_associated_item<'tcx>( return Err(guar); } - let args = tcx.erase_and_anonymize_regions(args); - // We check that the impl item is compatible with the trait item // because otherwise we may ICE in const eval due to type mismatches, // signature incompatibilities, etc. From 5e510929c65c1340f024311ba5aed9ff57443c54 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 9 Jan 2026 13:34:08 +1100 Subject: [PATCH 1965/3801] Remove useless call to `erase_and_anonymize_regions`. The only thing we do with the result is consult the `.def_id` field, which is unaffected by `erase_and_anonymize_regions`. --- compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index dc941cb41c56..e11ed796887a 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1520,7 +1520,6 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( // Unwrap potential addrspacecast let vtable = find_vtable_behind_cast(vtable); let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty); - let trait_ref_self = cx.tcx.erase_and_anonymize_regions(trait_ref_self); let trait_def_id = trait_ref_self.def_id; let trait_vis = cx.tcx.visibility(trait_def_id); From 46d8c2beebf0d3c527eaecc836bff61478fc300b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 9 Jan 2026 15:42:37 +1100 Subject: [PATCH 1966/3801] Clean up `src`/`dst` transmute mess. - Remove the vacuous `Types`, which provides extremely little value. - Make sure `src` comes before `dst` in all transmute-related functions. (Currently it's a mix: sometimes `src` is first, sometimes it is second`.) --- .../rustc_next_trait_solver/src/delegate.rs | 2 +- .../src/solve/eval_ctxt/mod.rs | 2 +- .../traits/fulfillment_errors.rs | 7 +------ .../src/solve/delegate.rs | 6 ++---- .../src/traits/select/confirmation.rs | 3 +-- compiler/rustc_transmute/src/lib.rs | 18 ++++-------------- .../crates/hir-ty/src/next_solver/solver.rs | 2 +- 7 files changed, 11 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 41c2e5f60ec3..9d5aa8bc124b 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -86,8 +86,8 @@ pub trait SolverDelegate: Deref + Sized { fn is_transmutable( &self, - dst: ::Ty, src: ::Ty, + dst: ::Ty, assume: ::Const, ) -> Result; } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 8d0a3ac94d5a..3ab42d64f2ff 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -1170,8 +1170,8 @@ where pub(super) fn is_transmutable( &mut self, - dst: I::Ty, src: I::Ty, + dst: I::Ty, assume: I::Const, ) -> Result { self.delegate.is_transmutable(dst, src, assume) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 0f021946e06a..8762607edf5d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2781,11 +2781,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx.instantiate_bound_regions_with_erased(trait_pred), ); - let src_and_dst = rustc_transmute::Types { - dst: trait_pred.trait_ref.args.type_at(0), - src: trait_pred.trait_ref.args.type_at(1), - }; - let ocx = ObligationCtxt::new(self); let Ok(assume) = ocx.structurally_normalize_const( &obligation.cause, @@ -2812,7 +2807,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`"); match rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx) - .is_transmutable(src_and_dst, assume) + .is_transmutable(src, dst, assume) { Answer::No(reason) => { let safe_transmute_explanation = match reason { diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index b6bdf1067a35..62572694de32 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -294,8 +294,8 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< // register candidates. We probably need to register >1 since we may have an OR of ANDs. fn is_transmutable( &self, - dst: Ty<'tcx>, src: Ty<'tcx>, + dst: Ty<'tcx>, assume: ty::Const<'tcx>, ) -> Result { // Erase regions because we compute layouts in `rustc_transmute`, @@ -307,9 +307,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< }; // FIXME(transmutability): This really should be returning nested goals for `Answer::If*` - match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx) - .is_transmutable(rustc_transmute::Types { src, dst }, assume) - { + match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx).is_transmutable(src, dst, assume) { rustc_transmute::Answer::Yes => Ok(Certainty::Yes), rustc_transmute::Answer::No(_) | rustc_transmute::Answer::If(_) => Err(NoSolution), } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 20a8842f2e8e..4f65b30775ed 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -365,8 +365,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?src, ?dst); let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx); - let maybe_transmutable = - transmute_env.is_transmutable(rustc_transmute::Types { dst, src }, assume); + let maybe_transmutable = transmute_env.is_transmutable(src, dst, assume); let fully_flattened = match maybe_transmutable { Answer::No(_) => Err(SelectionError::Unimplemented)?, diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 08ae561c972c..732881f12d2c 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -93,15 +93,6 @@ mod rustc { use super::*; - /// The source and destination types of a transmutation. - #[derive(Debug, Clone, Copy)] - pub struct Types<'tcx> { - /// The source type. - pub src: Ty<'tcx>, - /// The destination type. - pub dst: Ty<'tcx>, - } - pub struct TransmuteTypeEnv<'tcx> { tcx: TyCtxt<'tcx>, } @@ -113,13 +104,12 @@ mod rustc { pub fn is_transmutable( &mut self, - types: Types<'tcx>, + src: Ty<'tcx>, + dst: Ty<'tcx>, assume: crate::Assume, ) -> crate::Answer, Ty<'tcx>> { - crate::maybe_transmutable::MaybeTransmutableQuery::new( - types.src, types.dst, assume, self.tcx, - ) - .answer() + crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, self.tcx) + .answer() } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs index 21fbd64dd066..15d6e2e4516e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs @@ -232,8 +232,8 @@ impl<'db> SolverDelegate for SolverContext<'db> { fn is_transmutable( &self, - _dst: Ty<'db>, _src: Ty<'db>, + _dst: Ty<'db>, _assume: ::Const, ) -> Result { // It's better to return some value while not fully implement From e7036b136f44f9e385d794a783f6f66816f32ec0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 9 Jan 2026 10:45:26 +1100 Subject: [PATCH 1967/3801] clippy: remove `ty_has_erased_regions`. It duplicates `has_erased_regions` from the compiler. --- .../matches/significant_drop_in_scrutinee.rs | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index bac35e7f8c70..14d265bfdad8 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -12,7 +12,7 @@ use rustc_errors::{Applicability, Diag}; use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_hir::{Arm, Expr, ExprKind, MatchSource}; use rustc_lint::{LateContext, LintContext}; -use rustc_middle::ty::{GenericArgKind, Region, RegionKind, Ty, TyCtxt, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{GenericArgKind, RegionKind, Ty, TypeVisitableExt}; use rustc_span::Span; use super::SIGNIFICANT_DROP_IN_SCRUTINEE; @@ -303,13 +303,13 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> { if self.sig_drop_holder != SigDropHolder::None { let parent_ty = self.cx.typeck_results().expr_ty(parent_expr); - if !ty_has_erased_regions(parent_ty) && !parent_expr.is_syntactic_place_expr() { + if !parent_ty.has_erased_regions() && !parent_expr.is_syntactic_place_expr() { self.replace_current_sig_drop(parent_expr.span, parent_ty.is_unit(), 0); self.sig_drop_holder = SigDropHolder::Moved; } let (peel_ref_ty, peel_ref_times) = ty_peel_refs(parent_ty); - if !ty_has_erased_regions(peel_ref_ty) && is_copy(self.cx, peel_ref_ty) { + if !peel_ref_ty.has_erased_regions() && is_copy(self.cx, peel_ref_ty) { self.replace_current_sig_drop(parent_expr.span, peel_ref_ty.is_unit(), peel_ref_times); self.sig_drop_holder = SigDropHolder::Moved; } @@ -399,24 +399,6 @@ fn ty_peel_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) { (ty, n) } -fn ty_has_erased_regions(ty: Ty<'_>) -> bool { - struct V; - - impl<'tcx> TypeVisitor> for V { - type Result = ControlFlow<()>; - - fn visit_region(&mut self, region: Region<'tcx>) -> Self::Result { - if region.is_erased() { - ControlFlow::Break(()) - } else { - ControlFlow::Continue(()) - } - } - } - - ty.visit_with(&mut V).is_break() -} - impl<'tcx> Visitor<'tcx> for SigDropHelper<'_, 'tcx> { fn visit_expr(&mut self, ex: &'tcx Expr<'_>) { // We've emitted a lint on some neighborhood expression. That lint will suggest to move out the From d419bddb96f8177a3d8a7cb3c4df15902a24028a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 9 Jan 2026 10:45:26 +1100 Subject: [PATCH 1968/3801] clippy: remove `ty_has_erased_regions`. It duplicates `has_erased_regions` from the compiler. --- .../matches/significant_drop_in_scrutinee.rs | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index bac35e7f8c70..14d265bfdad8 100644 --- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -12,7 +12,7 @@ use rustc_errors::{Applicability, Diag}; use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_hir::{Arm, Expr, ExprKind, MatchSource}; use rustc_lint::{LateContext, LintContext}; -use rustc_middle::ty::{GenericArgKind, Region, RegionKind, Ty, TyCtxt, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{GenericArgKind, RegionKind, Ty, TypeVisitableExt}; use rustc_span::Span; use super::SIGNIFICANT_DROP_IN_SCRUTINEE; @@ -303,13 +303,13 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> { if self.sig_drop_holder != SigDropHolder::None { let parent_ty = self.cx.typeck_results().expr_ty(parent_expr); - if !ty_has_erased_regions(parent_ty) && !parent_expr.is_syntactic_place_expr() { + if !parent_ty.has_erased_regions() && !parent_expr.is_syntactic_place_expr() { self.replace_current_sig_drop(parent_expr.span, parent_ty.is_unit(), 0); self.sig_drop_holder = SigDropHolder::Moved; } let (peel_ref_ty, peel_ref_times) = ty_peel_refs(parent_ty); - if !ty_has_erased_regions(peel_ref_ty) && is_copy(self.cx, peel_ref_ty) { + if !peel_ref_ty.has_erased_regions() && is_copy(self.cx, peel_ref_ty) { self.replace_current_sig_drop(parent_expr.span, peel_ref_ty.is_unit(), peel_ref_times); self.sig_drop_holder = SigDropHolder::Moved; } @@ -399,24 +399,6 @@ fn ty_peel_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) { (ty, n) } -fn ty_has_erased_regions(ty: Ty<'_>) -> bool { - struct V; - - impl<'tcx> TypeVisitor> for V { - type Result = ControlFlow<()>; - - fn visit_region(&mut self, region: Region<'tcx>) -> Self::Result { - if region.is_erased() { - ControlFlow::Break(()) - } else { - ControlFlow::Continue(()) - } - } - } - - ty.visit_with(&mut V).is_break() -} - impl<'tcx> Visitor<'tcx> for SigDropHelper<'_, 'tcx> { fn visit_expr(&mut self, ex: &'tcx Expr<'_>) { // We've emitted a lint on some neighborhood expression. That lint will suggest to move out the From e555d2c44b6b4a4ec8ac220aa972d18cac87e662 Mon Sep 17 00:00:00 2001 From: Asuna Date: Sun, 11 Jan 2026 23:34:36 +0100 Subject: [PATCH 1969/3801] Use updated indexes to build reverse map for delegation generics --- compiler/rustc_hir_analysis/src/delegation.rs | 6 +++--- tests/ui/delegation/ice-issue-150673.rs | 21 +++++++++++++++++++ tests/ui/delegation/ice-issue-150673.stderr | 19 +++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 tests/ui/delegation/ice-issue-150673.rs create mode 100644 tests/ui/delegation/ice-issue-150673.stderr diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 4ab13140bf9c..cf0533c39e73 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -135,9 +135,6 @@ fn build_generics<'tcx>( // } own_params.sort_by_key(|key| key.kind.is_ty_or_const()); - let param_def_id_to_index = - own_params.iter().map(|param| (param.def_id, param.index)).collect(); - let (parent_count, has_self) = if let Some(def_id) = parent { let parent_generics = tcx.generics_of(def_id); let parent_kind = tcx.def_kind(def_id); @@ -162,6 +159,9 @@ fn build_generics<'tcx>( } } + let param_def_id_to_index = + own_params.iter().map(|param| (param.def_id, param.index)).collect(); + ty::Generics { parent, parent_count, diff --git a/tests/ui/delegation/ice-issue-150673.rs b/tests/ui/delegation/ice-issue-150673.rs new file mode 100644 index 000000000000..7f041d3ce257 --- /dev/null +++ b/tests/ui/delegation/ice-issue-150673.rs @@ -0,0 +1,21 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse { + pub fn foo() -> T { + unimplemented!() + } +} + +struct S(T); + +trait Trait { + reuse to_reuse::foo; +} + +impl Trait for S { +//~^ ERROR: missing generics for struct `S` + reuse Trait::foo; +} + +fn main() {} diff --git a/tests/ui/delegation/ice-issue-150673.stderr b/tests/ui/delegation/ice-issue-150673.stderr new file mode 100644 index 000000000000..fc817b07770e --- /dev/null +++ b/tests/ui/delegation/ice-issue-150673.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for struct `S` + --> $DIR/ice-issue-150673.rs:16:16 + | +LL | impl Trait for S { + | ^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `T` + --> $DIR/ice-issue-150673.rs:10:8 + | +LL | struct S(T); + | ^ - +help: add missing generic argument + | +LL | impl Trait for S { + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. From 63481058f77a3324ac629fabc3208837f4353188 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sun, 11 Jan 2026 19:57:21 -0500 Subject: [PATCH 1970/3801] std: Fix size returned by UEFI tcp4 read operations The read and read_vectored methods were returning the length of the input buffer, rather than the number of bytes actually read. Fix by changing read_inner to return the correct value, and have both read and read_vectored return that. --- library/std/src/sys/net/connection/uefi/tcp4.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs index 00c93384e5f6..ac38dd901e4d 100644 --- a/library/std/src/sys/net/connection/uefi/tcp4.rs +++ b/library/std/src/sys/net/connection/uefi/tcp4.rs @@ -248,7 +248,7 @@ impl Tcp4 { fragment_table: [fragment], }; - self.read_inner((&raw mut rx_data).cast(), timeout).map(|_| data_len as usize) + self.read_inner((&raw mut rx_data).cast(), timeout) } pub(crate) fn read_vectored( @@ -288,14 +288,14 @@ impl Tcp4 { ); }; - self.read_inner(rx_data.as_mut_ptr(), timeout).map(|_| data_length as usize) + self.read_inner(rx_data.as_mut_ptr(), timeout) } pub(crate) fn read_inner( &self, rx_data: *mut tcp4::ReceiveData, timeout: Option, - ) -> io::Result<()> { + ) -> io::Result { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -313,7 +313,8 @@ impl Tcp4 { if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) } else { - Ok(()) + let data_length = unsafe { (*rx_data).data_length }; + Ok(data_length as usize) } } From e6071522dba3032c5e51c6975694956ba000100a Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 10 Jan 2026 14:21:33 +0100 Subject: [PATCH 1971/3801] mark rust_dealloc as captures(address) Co-authored-by: Ralf Jung --- compiler/rustc_codegen_llvm/src/attributes.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index a25ce9e5a90a..bf6bb81b53b0 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -517,7 +517,16 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( to_add.push(llvm::CreateAllocKindAttr(cx.llcx, AllocKindFlags::Free)); // applies to argument place instead of function place let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx); - attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]); + let attrs: &[_] = if llvm_util::get_version() >= (21, 0, 0) { + // "Does not capture provenance" means "if the function call stashes the pointer somewhere, + // accessing that pointer after the function returns is UB". That is definitely the case here since + // freeing will destroy the provenance. + let captures_addr = AttributeKind::CapturesAddress.create_attr(cx.llcx); + &[allocated_pointer, captures_addr] + } else { + &[allocated_pointer] + }; + attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), attrs); } if let Some(align) = codegen_fn_attrs.alignment { llvm::set_alignment(llfn, align); From 468eb45b3f3e106735327748308f7e04e942fe40 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 29 Sep 2024 00:27:50 +0200 Subject: [PATCH 1972/3801] avoid phi node for pointers flowing into Vec appends --- library/alloc/src/slice.rs | 8 +++-- library/alloc/src/vec/mod.rs | 6 +++- .../lib-optimizations/append-elements.rs | 30 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 tests/codegen-llvm/lib-optimizations/append-elements.rs diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index e7d0fc3454ee..58abf4bd6571 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -448,9 +448,11 @@ impl [T] { // SAFETY: // allocated above with the capacity of `s`, and initialize to `s.len()` in // ptr::copy_to_non_overlapping below. - unsafe { - s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len()); - v.set_len(s.len()); + if s.len() > 0 { + unsafe { + s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len()); + v.set_len(s.len()); + } } v } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 379e964f0a0c..ac86399df7ab 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2818,7 +2818,11 @@ impl Vec { let count = other.len(); self.reserve(count); let len = self.len(); - unsafe { ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) }; + if count > 0 { + unsafe { + ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) + }; + } self.len += count; } diff --git a/tests/codegen-llvm/lib-optimizations/append-elements.rs b/tests/codegen-llvm/lib-optimizations/append-elements.rs new file mode 100644 index 000000000000..8ee520a131f0 --- /dev/null +++ b/tests/codegen-llvm/lib-optimizations/append-elements.rs @@ -0,0 +1,30 @@ +//@ compile-flags: -O -Zmerge-functions=disabled +//@ min-llvm-version: 21 +#![crate_type = "lib"] + +//! Check that a temporary intermediate allocations can eliminated and replaced +//! with memcpy forwarding. +//! This requires Vec code to be structured in a way that avoids phi nodes from the +//! zero-capacity length flowing into the memcpy arguments. + +// CHECK-LABEL: @vec_append_with_temp_alloc +#[no_mangle] +pub fn vec_append_with_temp_alloc(dst: &mut Vec, src: &[u8]) { + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.*}}%dst.i{{.*}}%src.0 + // CHECK-NOT: call void @llvm.memcpy + let temp = src.to_vec(); + dst.extend(&temp); + // CHECK: ret +} + +// CHECK-LABEL: @string_append_with_temp_alloc +#[no_mangle] +pub fn string_append_with_temp_alloc(dst: &mut String, src: &str) { + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.*}}%dst.i{{.*}}%src.0 + // CHECK-NOT: call void @llvm.memcpy + let temp = src.to_string(); + dst.push_str(&temp); + // CHECK: ret +} From 2d2d3b0a6bb9bc88f795002e1da70e4181254d34 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sun, 11 Jan 2026 23:21:38 -0500 Subject: [PATCH 1973/3801] remote-test-server: Fix header in batch mode In https://github.com/rust-lang/rust/pull/119999, the length field of the header was changed from 4 bytes to 8. One of the headers in `batch_copy` was missed though, so it sends the wrong size. Fix by switching to `create_header` in that spot too. --- src/tools/remote-test-server/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index bfe8f54937f6..48b0d83e8d82 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -387,7 +387,7 @@ fn batch_copy(buf: &[u8], which: u8, dst: &Mutex) { if n > 0 { t!(dst.write_all(buf)); // Marking buf finished - t!(dst.write_all(&[which, 0, 0, 0, 0,])); + t!(dst.write_all(&create_header(which, 0))); } } From 594ca4b1bc47588a851265d51a5db05ed2f080b2 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 12 Jan 2026 04:26:31 +0000 Subject: [PATCH 1974/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 44a5b55557c26353f388400d7da95527256fe260. --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 4b08b0884ca8..b53a66c66751 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -548e586795f6b6fe089d8329aa5edbf0f5202646 +44a5b55557c26353f388400d7da95527256fe260 From 80acef153ffa6ecc4c9458b8a1169b10d7d750c7 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 12 Jan 2026 04:26:43 +0000 Subject: [PATCH 1975/3801] Format code --- src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs | 4 +++- src/tools/rust-analyzer/crates/span/src/hygiene.rs | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index d10e122a5deb..172641227599 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs @@ -101,7 +101,9 @@ impl DeclarativeMacroExpander { match &*value { "transparent" => ControlFlow::Break(Transparency::Transparent), // "semitransparent" is for old rustc versions. - "semiopaque" | "semitransparent" => ControlFlow::Break(Transparency::SemiOpaque), + "semiopaque" | "semitransparent" => { + ControlFlow::Break(Transparency::SemiOpaque) + } "opaque" => ControlFlow::Break(Transparency::Opaque), _ => ControlFlow::Continue(()), } diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index 9904c562a740..fe05ef946518 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -241,9 +241,7 @@ const _: () = { edition: zalsa_::interned::Lookup::into_owned(data.2), parent: zalsa_::interned::Lookup::into_owned(data.3), opaque: opaque(zalsa_::FromId::from_id(id)), - opaque_and_semiopaque: opaque_and_semiopaque( - zalsa_::FromId::from_id(id), - ), + opaque_and_semiopaque: opaque_and_semiopaque(zalsa_::FromId::from_id(id)), }, ) } From e20d903c1c43a4fb288dc75fc332a6fe39073b9a Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 12 Jan 2026 04:29:24 +0000 Subject: [PATCH 1976/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 44a5b55557c26353f388400d7da95527256fe260. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 7b444a9ef5f1..b53a66c66751 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -85c8ff69cb3efd950395cc444a54bbbdad668865 +44a5b55557c26353f388400d7da95527256fe260 From 199aa6813eb08b32abca02745f1fb331813bb044 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 12 Jan 2026 05:04:54 +0000 Subject: [PATCH 1977/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 44a5b55557c26353f388400d7da95527256fe260. --- 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 c44422d758c5..b53a66c66751 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -f57b9e6f565a1847e83a63f3e90faa3870536c1f +44a5b55557c26353f388400d7da95527256fe260 From 294a0afd655f22f98201c5e34e9f3b57e42a537c Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 12 Jan 2026 08:51:42 +0200 Subject: [PATCH 1978/3801] Disable `unused_variables` and `unused_mut` warnings They suffer from an unacceptable amount of false positives after #21209. Another option to disable them is to include them in `rust-analyzer.diagnostics.disable` by default, but that will mean users could override that. --- .../src/handlers/mutability_errors.rs | 24 ++++++----- .../src/handlers/unused_variables.rs | 42 ++++++++++--------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs index 2887a32825db..e3cfbdfb515f 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs @@ -1,3 +1,5 @@ +#![expect(unused, reason = "diagnostics is temporarily disabled due to too many false positives")] + use hir::db::ExpandDatabase; use ide_db::source_change::SourceChange; use ide_db::text_edit::TextEdit; @@ -88,16 +90,17 @@ pub(crate) fn unused_mut(ctx: &DiagnosticsContext<'_>, d: &hir::UnusedMut) -> Op )]) })(); let ast = d.local.primary_source(ctx.sema.db).syntax_ptr(); - Some( - Diagnostic::new_with_syntax_node_ptr( - ctx, - DiagnosticCode::RustcLint("unused_mut"), - "variable does not need to be mutable", - ast, - ) - // Not supporting `#[allow(unused_mut)]` in proc macros leads to false positive, hence not stable. - .with_fixes(fixes), - ) + // Some( + // Diagnostic::new_with_syntax_node_ptr( + // ctx, + // DiagnosticCode::RustcLint("unused_mut"), + // "variable does not need to be mutable", + // ast, + // ) + // // Not supporting `#[allow(unused_mut)]` in proc macros leads to false positive, hence not stable. + // .with_fixes(fixes), + // ) + None } pub(super) fn token(parent: &SyntaxNode, kind: SyntaxKind) -> Option { @@ -105,6 +108,7 @@ pub(super) fn token(parent: &SyntaxNode, kind: SyntaxKind) -> Option Date: Sat, 10 Jan 2026 11:26:20 +0100 Subject: [PATCH 1979/3801] rename eii-extern-target --- compiler/rustc_ast/src/ast.rs | 16 +++--- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 35 ++++++------ compiler/rustc_ast_pretty/src/pprust/state.rs | 8 +-- compiler/rustc_builtin_macros/messages.ftl | 6 +-- compiler/rustc_builtin_macros/src/eii.rs | 20 +++---- compiler/rustc_builtin_macros/src/errors.rs | 6 +-- compiler/rustc_builtin_macros/src/lib.rs | 2 +- .../rustc_codegen_ssa/src/codegen_attrs.rs | 10 ++-- .../rustc_hir/src/attrs/data_structures.rs | 6 +-- .../rustc_hir/src/attrs/encode_cross_crate.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- compiler/rustc_metadata/src/eii.rs | 10 ++-- compiler/rustc_metadata/src/rmeta/decoder.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 4 +- compiler/rustc_passes/src/check_attr.rs | 4 +- compiler/rustc_resolve/src/late.rs | 6 +-- compiler/rustc_span/src/symbol.rs | 2 +- library/core/src/macros/mod.rs | 2 +- library/core/src/prelude/v1.rs | 2 +- library/std/src/prelude/v1.rs | 2 +- tests/ui/eii/errors.rs | 18 +++---- tests/ui/eii/errors.stderr | 54 +++++++++---------- .../auxiliary/cross_crate_eii_declaration.rs | 2 +- tests/ui/eii/type_checking/subtype_1.rs | 2 +- tests/ui/eii/type_checking/subtype_2.rs | 2 +- tests/ui/eii/type_checking/subtype_3.rs | 2 +- tests/ui/eii/type_checking/subtype_4.rs | 2 +- tests/ui/eii/type_checking/wrong_ret_ty.rs | 2 +- tests/ui/eii/type_checking/wrong_ty.rs | 2 +- tests/ui/eii/type_checking/wrong_ty_2.rs | 2 +- tests/ui/eii/unsafe_impl_err.rs | 2 +- tests/ui/eii/unsafe_impl_ok.rs | 2 +- .../feature-gate-eii-internals.rs | 2 +- .../feature-gate-eii-internals.stderr | 4 +- 35 files changed, 124 insertions(+), 125 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fb2ccefe12a1..a4a80475ba73 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2109,16 +2109,18 @@ pub struct MacroDef { /// `true` if macro was defined with `macro_rules`. pub macro_rules: bool, - /// If this is a macro used for externally implementable items, - /// it refers to an extern item which is its "target". This requires - /// name resolution so can't just be an attribute, so we store it in this field. - pub eii_extern_target: Option, + /// Corresponds to `#[eii_declaration(...)]`. + /// `#[eii_declaration(...)]` is a built-in attribute macro, not a built-in attribute, + /// because we require some name resolution to occur in the parameters of this attribute. + /// Name resolution isn't possible in attributes otherwise, so we encode it in the AST. + /// During ast lowering, we turn it back into an attribute again + pub eii_declaration: Option, } #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)] -pub struct EiiExternTarget { +pub struct EiiDecl { /// path to the extern item we're targeting - pub extern_item_path: Path, + pub foreign_item: Path, pub impl_unsafe: bool, } @@ -3824,7 +3826,7 @@ pub struct EiiImpl { /// /// This field is that shortcut: we prefill the extern target to skip a name resolution step, /// making sure it never fails. It'd be awful UX if we fail name resolution in code invisible to the user. - pub known_eii_macro_resolution: Option, + pub known_eii_macro_resolution: Option, pub impl_safety: Safety, pub span: Span, pub inner_span: Span, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 83b751fbde90..f7b8b9da3241 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -489,7 +489,7 @@ macro_rules! common_visitor_and_walkers { WhereEqPredicate, WhereRegionPredicate, YieldKind, - EiiExternTarget, + EiiDecl, EiiImpl, ); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 3a7308ef7c97..c8ebfb96b558 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -2,7 +2,7 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err}; -use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImplResolution}; +use rustc_hir::attrs::{AttributeKind, EiiImplResolution}; use rustc_hir::def::{DefKind, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::{ @@ -134,16 +134,16 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn lower_eii_extern_target( + fn lower_eii_decl( &mut self, id: NodeId, - eii_name: Ident, - EiiExternTarget { extern_item_path, impl_unsafe }: &EiiExternTarget, - ) -> Option { - self.lower_path_simple_eii(id, extern_item_path).map(|did| EiiDecl { - eii_extern_target: did, + name: Ident, + EiiDecl { foreign_item, impl_unsafe }: &EiiDecl, + ) -> Option { + self.lower_path_simple_eii(id, foreign_item).map(|did| hir::attrs::EiiDecl { + foreign_item: did, impl_unsafe: *impl_unsafe, - name: eii_name, + name, }) } @@ -160,7 +160,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }: &EiiImpl, ) -> hir::attrs::EiiImpl { let resolution = if let Some(target) = known_eii_macro_resolution - && let Some(decl) = self.lower_eii_extern_target( + && let Some(decl) = self.lower_eii_decl( *node_id, // the expect is ok here since we always generate this path in the eii macro. eii_macro_path.segments.last().expect("at least one segment").ident, @@ -196,9 +196,9 @@ impl<'hir> LoweringContext<'_, 'hir> { eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(), ))] } - ItemKind::MacroDef(name, MacroDef { eii_extern_target: Some(target), .. }) => self - .lower_eii_extern_target(id, *name, target) - .map(|decl| vec![hir::Attribute::Parsed(AttributeKind::EiiExternTarget(decl))]) + ItemKind::MacroDef(name, MacroDef { eii_declaration: Some(target), .. }) => self + .lower_eii_decl(id, *name, target) + .map(|decl| vec![hir::Attribute::Parsed(AttributeKind::EiiDeclaration(decl))]) .unwrap_or_default(), ItemKind::ExternCrate(..) @@ -242,10 +242,7 @@ impl<'hir> LoweringContext<'_, 'hir> { vis_span, span: self.lower_span(i.span), has_delayed_lints: !self.delayed_lints.is_empty(), - eii: find_attr!( - attrs, - AttributeKind::EiiImpls(..) | AttributeKind::EiiExternTarget(..) - ), + eii: find_attr!(attrs, AttributeKind::EiiImpls(..) | AttributeKind::EiiDeclaration(..)), }; self.arena.alloc(item) } @@ -539,7 +536,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::TraitAlias(constness, ident, generics, bounds) } - ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_extern_target: _ }) => { + ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_declaration: _ }) => { let ident = self.lower_ident(*ident); let body = Box::new(self.lower_delim_args(body)); let def_id = self.local_def_id(id); @@ -553,7 +550,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules, - eii_extern_target: None, + eii_declaration: None, }); hir::ItemKind::Macro(ident, macro_def, macro_kinds) } @@ -693,7 +690,7 @@ impl<'hir> LoweringContext<'_, 'hir> { has_delayed_lints: !this.delayed_lints.is_empty(), eii: find_attr!( attrs, - AttributeKind::EiiImpls(..) | AttributeKind::EiiExternTarget(..) + AttributeKind::EiiImpls(..) | AttributeKind::EiiDeclaration(..) ), }; hir::OwnerNode::Item(this.arena.alloc(item)) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 0cf0eae821e9..e50e31c226fd 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -865,10 +865,10 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere sp: Span, print_visibility: impl FnOnce(&mut Self), ) { - if let Some(eii_extern_target) = ¯o_def.eii_extern_target { - self.word("#[eii_extern_target("); - self.print_path(&eii_extern_target.extern_item_path, false, 0); - if eii_extern_target.impl_unsafe { + if let Some(eii_decl) = ¯o_def.eii_declaration { + self.word("#[eii_declaration("); + self.print_path(&eii_decl.foreign_item, false, 0); + if eii_decl.impl_unsafe { self.word(","); self.space(); self.word("unsafe"); diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index e4fded0cb01e..1501bd6c73e2 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -151,9 +151,9 @@ builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept builtin_macros_duplicate_macro_attribute = duplicated attribute -builtin_macros_eii_extern_target_expected_list = `#[eii_extern_target(...)]` expects a list of one or two elements -builtin_macros_eii_extern_target_expected_macro = `#[eii_extern_target(...)]` is only valid on macros -builtin_macros_eii_extern_target_expected_unsafe = expected this argument to be "unsafe" +builtin_macros_eii_declaration_expected_list = `#[eii_declaration(...)]` expects a list of one or two elements +builtin_macros_eii_declaration_expected_macro = `#[eii_declaration(...)]` is only valid on macros +builtin_macros_eii_declaration_expected_unsafe = expected this argument to be "unsafe" .note = the second argument is optional builtin_macros_eii_only_once = `#[{$name}]` can only be specified once diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index a5009b3bfa52..e8aeb8090bf4 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -1,7 +1,7 @@ use rustc_ast::token::{Delimiter, TokenKind}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::{ - Attribute, DUMMY_NODE_ID, EiiExternTarget, EiiImpl, ItemKind, MetaItem, Path, Stmt, StmtKind, + Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Path, Stmt, StmtKind, Visibility, ast, }; use rustc_ast_pretty::pprust::path_to_string; @@ -30,7 +30,7 @@ use crate::errors::{ /// } /// /// #[rustc_builtin_macro(eii_shared_macro)] -/// #[eii_extern_target(panic_handler)] +/// #[eii_declaration(panic_handler)] /// macro panic_handler() {} /// ``` pub(crate) fn eii( @@ -210,8 +210,8 @@ fn generate_default_impl( }, span: eii_attr_span, is_default: true, - known_eii_macro_resolution: Some(ast::EiiExternTarget { - extern_item_path: ecx.path( + known_eii_macro_resolution: Some(ast::EiiDecl { + foreign_item: ecx.path( foreign_item_name.span, // prefix super to escape the `dflt` module generated below vec![Ident::from_str_and_span("super", foreign_item_name.span), foreign_item_name], @@ -349,7 +349,7 @@ fn generate_foreign_item( /// // This attribute tells the compiler that /// #[builtin_macro(eii_shared_macro)] /// // the metadata to link this macro to the generated foreign item. -/// #[eii_extern_target()] +/// #[eii_declaration()] /// macro macro_name { () => {} } /// ``` fn generate_attribute_macro_to_implement( @@ -401,9 +401,9 @@ fn generate_attribute_macro_to_implement( ]), }), macro_rules: false, - // #[eii_extern_target(foreign_item_ident)] - eii_extern_target: Some(ast::EiiExternTarget { - extern_item_path: ast::Path::from_ident(foreign_item_name), + // #[eii_declaration(foreign_item_ident)] + eii_declaration: Some(ast::EiiDecl { + foreign_item: ast::Path::from_ident(foreign_item_name), impl_unsafe, }), }, @@ -412,7 +412,7 @@ fn generate_attribute_macro_to_implement( }) } -pub(crate) fn eii_extern_target( +pub(crate) fn eii_declaration( ecx: &mut ExtCtxt<'_>, span: Span, meta_item: &ast::MetaItem, @@ -461,7 +461,7 @@ pub(crate) fn eii_extern_target( false }; - d.eii_extern_target = Some(EiiExternTarget { extern_item_path, impl_unsafe }); + d.eii_declaration = Some(EiiDecl { foreign_item: extern_item_path, impl_unsafe }); // Return the original item and the new methods. vec![item] diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index e673ad3f8a64..5d4c4e340fa1 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -1010,21 +1010,21 @@ pub(crate) struct CfgSelectUnreachable { } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_extern_target_expected_macro)] +#[diag(builtin_macros_eii_declaration_expected_macro)] pub(crate) struct EiiExternTargetExpectedMacro { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_extern_target_expected_list)] +#[diag(builtin_macros_eii_declaration_expected_list)] pub(crate) struct EiiExternTargetExpectedList { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_eii_extern_target_expected_unsafe)] +#[diag(builtin_macros_eii_declaration_expected_unsafe)] pub(crate) struct EiiExternTargetExpectedUnsafe { #[primary_span] #[note] diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 89ac8db76063..e1c5a4f85c1b 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -119,7 +119,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { derive: derive::Expander { is_const: false }, derive_const: derive::Expander { is_const: true }, eii: eii::eii, - eii_extern_target: eii::eii_extern_target, + eii_declaration: eii::eii_declaration, eii_shared_macro: eii::eii_shared_macro, global_allocator: global_allocator::expand, test: test::expand_test, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 7dda824e2b18..db150faea86d 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -287,11 +287,11 @@ fn process_builtin_attrs( } AttributeKind::EiiImpls(impls) => { for i in impls { - let extern_item = match i.resolution { + let foreign_item = match i.resolution { EiiImplResolution::Macro(def_id) => { let Some(extern_item) = find_attr!( tcx.get_all_attrs(def_id), - AttributeKind::EiiExternTarget(target) => target.eii_extern_target + AttributeKind::EiiDeclaration(target) => target.foreign_item ) else { tcx.dcx().span_delayed_bug( i.span, @@ -301,7 +301,7 @@ fn process_builtin_attrs( }; extern_item } - EiiImplResolution::Known(decl) => decl.eii_extern_target, + EiiImplResolution::Known(decl) => decl.foreign_item, EiiImplResolution::Error(_eg) => continue, }; @@ -316,13 +316,13 @@ fn process_builtin_attrs( // iterate over all implementations *in the current crate* // (this is ok since we generate codegen fn attrs in the local crate) // if any of them is *not default* then don't emit the alias. - && tcx.externally_implementable_items(LOCAL_CRATE).get(&extern_item).expect("at least one").1.iter().any(|(_, imp)| !imp.is_default) + && tcx.externally_implementable_items(LOCAL_CRATE).get(&foreign_item).expect("at least one").1.iter().any(|(_, imp)| !imp.is_default) { continue; } codegen_fn_attrs.foreign_item_symbol_aliases.push(( - extern_item, + foreign_item, if i.is_default { Linkage::LinkOnceAny } else { Linkage::External }, Visibility::Default, )); diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index a5ecfa45fb40..c6c50bb793f8 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -43,7 +43,7 @@ pub struct EiiImpl { #[derive(Copy, Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] pub struct EiiDecl { - pub eii_extern_target: DefId, + pub foreign_item: DefId, /// whether or not it is unsafe to implement this EII pub impl_unsafe: bool, pub name: Ident, @@ -744,10 +744,10 @@ pub enum AttributeKind { Dummy, /// Implementation detail of `#[eii]` - EiiExternItem, + EiiDeclaration(EiiDecl), /// Implementation detail of `#[eii]` - EiiExternTarget(EiiDecl), + EiiExternItem, /// Implementation detail of `#[eii]` EiiImpls(ThinVec), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index efdb4f2f22b2..d854cc34c0f3 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -47,8 +47,8 @@ impl AttributeKind { Doc(_) => Yes, DocComment { .. } => Yes, Dummy => No, + EiiDeclaration(_) => Yes, EiiExternItem => No, - EiiExternTarget(_) => Yes, EiiImpls(..) => No, ExportName { .. } => Yes, ExportStable => No, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 7ec4110f80b9..cfc7e57cc14e 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1205,7 +1205,7 @@ fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) { EiiImplResolution::Macro(def_id) => { // we expect this macro to have the `EiiMacroFor` attribute, that points to a function // signature that we'd like to compare the function we're currently checking with - if let Some(foreign_item) = find_attr!(tcx.get_all_attrs(*def_id), AttributeKind::EiiExternTarget(EiiDecl {eii_extern_target: t, ..}) => *t) + if let Some(foreign_item) = find_attr!(tcx.get_all_attrs(*def_id), AttributeKind::EiiDeclaration(EiiDecl {foreign_item: t, ..}) => *t) { (foreign_item, tcx.item_name(*def_id)) } else { @@ -1213,7 +1213,7 @@ fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) { continue; } } - EiiImplResolution::Known(decl) => (decl.eii_extern_target, decl.name.name), + EiiImplResolution::Known(decl) => (decl.foreign_item, decl.name.name), EiiImplResolution::Error(_eg) => continue, }; diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs index b06ac8481397..42497a82ef8c 100644 --- a/compiler/rustc_metadata/src/eii.rs +++ b/compiler/rustc_metadata/src/eii.rs @@ -31,9 +31,9 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap let decl = match i.resolution { EiiImplResolution::Macro(macro_defid) => { // find the decl for this one if it wasn't in yet (maybe it's from the local crate? not very useful but not illegal) - let Some(decl) = find_attr!(tcx.get_all_attrs(macro_defid), AttributeKind::EiiExternTarget(d) => *d) + let Some(decl) = find_attr!(tcx.get_all_attrs(macro_defid), AttributeKind::EiiDeclaration(d) => *d) else { - // skip if it doesn't have eii_extern_target (if we resolved to another macro that's not an EII) + // skip if it doesn't have eii_declaration (if we resolved to another macro that's not an EII) tcx.dcx() .span_delayed_bug(i.span, "resolved to something that's not an EII"); continue; @@ -45,7 +45,7 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap }; // FIXME(eii) remove extern target from encoded decl - eiis.entry(decl.eii_extern_target) + eiis.entry(decl.foreign_item) .or_insert_with(|| (decl, Default::default())) .1 .insert(id.into(), *i); @@ -53,9 +53,9 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap // if we find a new declaration, add it to the list without a known implementation if let Some(decl) = - find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiExternTarget(d) => *d) + find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiDeclaration(d) => *d) { - eiis.entry(decl.eii_extern_target).or_insert((decl, Default::default())); + eiis.entry(decl.foreign_item).or_insert((decl, Default::default())); } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index f8610f0c5b03..c7423386a771 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1536,7 +1536,7 @@ impl<'a> CrateMetadataRef<'a> { .get((self, tcx), id) .unwrap() .decode((self, tcx)); - ast::MacroDef { macro_rules, body: Box::new(body), eii_extern_target: None } + ast::MacroDef { macro_rules, body: Box::new(body), eii_declaration: None } } _ => bug!(), } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 26f60c96aed6..cdcdaa342a5d 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2283,7 +2283,7 @@ impl<'a> Parser<'a> { self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span)); Ok(ItemKind::MacroDef( ident, - ast::MacroDef { body, macro_rules: false, eii_extern_target: None }, + ast::MacroDef { body, macro_rules: false, eii_declaration: None }, )) } @@ -2333,7 +2333,7 @@ impl<'a> Parser<'a> { Ok(ItemKind::MacroDef( ident, - ast::MacroDef { body, macro_rules: true, eii_extern_target: None }, + ast::MacroDef { body, macro_rules: true, eii_declaration: None }, )) } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 717a0e54d0c6..beae0efa927f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -224,7 +224,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_rustc_must_implement_one_of(*attr_span, fn_names, hir_id,target) }, Attribute::Parsed( - AttributeKind::EiiExternTarget { .. } + AttributeKind::EiiDeclaration { .. } | AttributeKind::EiiExternItem | AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect @@ -553,7 +553,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } if let EiiImplResolution::Macro(eii_macro) = resolution - && find_attr!(self.tcx.get_all_attrs(*eii_macro), AttributeKind::EiiExternTarget(EiiDecl { impl_unsafe, .. }) if *impl_unsafe) + && find_attr!(self.tcx.get_all_attrs(*eii_macro), AttributeKind::EiiDeclaration(EiiDecl { impl_unsafe, .. }) if *impl_unsafe) && !impl_marked_unsafe { self.dcx().emit_err(errors::EiiImplRequiresUnsafe { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 4d2ba73c9cab..6d0097631772 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1079,7 +1079,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc self.smart_resolve_path( *node_id, &None, - &target.extern_item_path, + &target.foreign_item, PathSource::Expr(None), ); } else { @@ -2931,8 +2931,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.parent_scope.macro_rules = self.r.macro_rules_scopes[&def_id]; } - if let Some(EiiExternTarget { extern_item_path, impl_unsafe: _ }) = - ¯o_def.eii_extern_target + if let Some(EiiDecl { foreign_item: extern_item_path, impl_unsafe: _ }) = + ¯o_def.eii_declaration { self.smart_resolve_path( item.id, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b473d36a45fc..d5a46bc02f1a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -935,7 +935,7 @@ symbols! { eh_catch_typeinfo, eh_personality, eii, - eii_extern_target, + eii_declaration, eii_impl, eii_internals, eii_shared_macro, diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 338c5688bf10..a437a4795481 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1912,7 +1912,7 @@ pub(crate) mod builtin { /// Impl detail of EII #[unstable(feature = "eii_internals", issue = "none")] #[rustc_builtin_macro] - pub macro eii_extern_target($item:item) { + pub macro eii_declaration($item:item) { /* compiler built-in */ } } diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index a5d9a5352dfc..7e0a84df5118 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -122,4 +122,4 @@ pub use crate::macros::builtin::define_opaque; pub use crate::macros::builtin::{eii, unsafe_eii}; #[unstable(feature = "eii_internals", issue = "none")] -pub use crate::macros::builtin::eii_extern_target; +pub use crate::macros::builtin::eii_declaration; diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 63f75ea8a881..0f0841379b29 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -114,7 +114,7 @@ pub use core::prelude::v1::define_opaque; pub use core::prelude::v1::{eii, unsafe_eii}; #[unstable(feature = "eii_internals", issue = "none")] -pub use core::prelude::v1::eii_extern_target; +pub use core::prelude::v1::eii_declaration; // The file so far is equivalent to core/src/prelude/v1.rs. It is duplicated // rather than glob imported because we want docs to show these re-exports as diff --git a/tests/ui/eii/errors.rs b/tests/ui/eii/errors.rs index d59850a7d5f5..5fcf33336b40 100644 --- a/tests/ui/eii/errors.rs +++ b/tests/ui/eii/errors.rs @@ -5,19 +5,19 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar)] //~ ERROR `#[eii_extern_target(...)]` is only valid on macros +#[eii_declaration(bar)] //~ ERROR `#[eii_declaration(...)]` is only valid on macros fn hello() { - #[eii_extern_target(bar)] //~ ERROR `#[eii_extern_target(...)]` is only valid on macros + #[eii_declaration(bar)] //~ ERROR `#[eii_declaration(...)]` is only valid on macros let x = 3 + 3; } -#[eii_extern_target] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements -#[eii_extern_target()] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements -#[eii_extern_target(bar, hello)] //~ ERROR expected this argument to be "unsafe" -#[eii_extern_target(bar, "unsafe", hello)] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements -#[eii_extern_target(bar, hello, "unsafe")] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements -#[eii_extern_target = "unsafe"] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements -#[eii_extern_target(bar)] +#[eii_declaration] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration()] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration(bar, hello)] //~ ERROR expected this argument to be "unsafe" +#[eii_declaration(bar, "unsafe", hello)] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration(bar, hello, "unsafe")] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration = "unsafe"] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration(bar)] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/eii/errors.stderr b/tests/ui/eii/errors.stderr index c3b51421f295..c7eb96a9c219 100644 --- a/tests/ui/eii/errors.stderr +++ b/tests/ui/eii/errors.stderr @@ -1,56 +1,56 @@ -error: `#[eii_extern_target(...)]` is only valid on macros +error: `#[eii_declaration(...)]` is only valid on macros --> $DIR/errors.rs:8:1 | -LL | #[eii_extern_target(bar)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_declaration(bar)] + | ^^^^^^^^^^^^^^^^^^^^^^^ -error: `#[eii_extern_target(...)]` is only valid on macros +error: `#[eii_declaration(...)]` is only valid on macros --> $DIR/errors.rs:10:5 | -LL | #[eii_extern_target(bar)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_declaration(bar)] + | ^^^^^^^^^^^^^^^^^^^^^^^ -error: `#[eii_extern_target(...)]` expects a list of one or two elements +error: `#[eii_declaration(...)]` expects a list of one or two elements --> $DIR/errors.rs:14:1 | -LL | #[eii_extern_target] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_declaration] + | ^^^^^^^^^^^^^^^^^^ -error: `#[eii_extern_target(...)]` expects a list of one or two elements +error: `#[eii_declaration(...)]` expects a list of one or two elements --> $DIR/errors.rs:15:1 | -LL | #[eii_extern_target()] - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_declaration()] + | ^^^^^^^^^^^^^^^^^^^^ error: expected this argument to be "unsafe" - --> $DIR/errors.rs:16:26 + --> $DIR/errors.rs:16:24 | -LL | #[eii_extern_target(bar, hello)] - | ^^^^^ +LL | #[eii_declaration(bar, hello)] + | ^^^^^ | note: the second argument is optional - --> $DIR/errors.rs:16:26 + --> $DIR/errors.rs:16:24 | -LL | #[eii_extern_target(bar, hello)] - | ^^^^^ +LL | #[eii_declaration(bar, hello)] + | ^^^^^ -error: `#[eii_extern_target(...)]` expects a list of one or two elements +error: `#[eii_declaration(...)]` expects a list of one or two elements --> $DIR/errors.rs:17:1 | -LL | #[eii_extern_target(bar, "unsafe", hello)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_declaration(bar, "unsafe", hello)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `#[eii_extern_target(...)]` expects a list of one or two elements +error: `#[eii_declaration(...)]` expects a list of one or two elements --> $DIR/errors.rs:18:1 | -LL | #[eii_extern_target(bar, hello, "unsafe")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_declaration(bar, hello, "unsafe")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `#[eii_extern_target(...)]` expects a list of one or two elements +error: `#[eii_declaration(...)]` expects a list of one or two elements --> $DIR/errors.rs:19:1 | -LL | #[eii_extern_target = "unsafe"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_declaration = "unsafe"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[foo]` is only valid on functions --> $DIR/errors.rs:28:1 diff --git a/tests/ui/eii/type_checking/auxiliary/cross_crate_eii_declaration.rs b/tests/ui/eii/type_checking/auxiliary/cross_crate_eii_declaration.rs index 40d0222082d5..95ae5d923b60 100644 --- a/tests/ui/eii/type_checking/auxiliary/cross_crate_eii_declaration.rs +++ b/tests/ui/eii/type_checking/auxiliary/cross_crate_eii_declaration.rs @@ -5,7 +5,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar)] +#[eii_declaration(bar)] #[rustc_builtin_macro(eii_shared_macro)] pub macro foo() {} diff --git a/tests/ui/eii/type_checking/subtype_1.rs b/tests/ui/eii/type_checking/subtype_1.rs index dfb998aa6f66..d853bc4e7e3d 100644 --- a/tests/ui/eii/type_checking/subtype_1.rs +++ b/tests/ui/eii/type_checking/subtype_1.rs @@ -6,7 +6,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar)] +#[eii_declaration(bar)] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/eii/type_checking/subtype_2.rs b/tests/ui/eii/type_checking/subtype_2.rs index 5f0c5553fccc..d2b2eb073de2 100644 --- a/tests/ui/eii/type_checking/subtype_2.rs +++ b/tests/ui/eii/type_checking/subtype_2.rs @@ -6,7 +6,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar)] +#[eii_declaration(bar)] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/eii/type_checking/subtype_3.rs b/tests/ui/eii/type_checking/subtype_3.rs index 269bc84df744..458bacf4a772 100644 --- a/tests/ui/eii/type_checking/subtype_3.rs +++ b/tests/ui/eii/type_checking/subtype_3.rs @@ -7,7 +7,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar)] +#[eii_declaration(bar)] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/eii/type_checking/subtype_4.rs b/tests/ui/eii/type_checking/subtype_4.rs index e9194df7584c..6f1e4253dd73 100644 --- a/tests/ui/eii/type_checking/subtype_4.rs +++ b/tests/ui/eii/type_checking/subtype_4.rs @@ -7,7 +7,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar)] +#[eii_declaration(bar)] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/eii/type_checking/wrong_ret_ty.rs b/tests/ui/eii/type_checking/wrong_ret_ty.rs index 5fe7d2f8bb62..8ee81a4f2465 100644 --- a/tests/ui/eii/type_checking/wrong_ret_ty.rs +++ b/tests/ui/eii/type_checking/wrong_ret_ty.rs @@ -5,7 +5,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar)] +#[eii_declaration(bar)] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/eii/type_checking/wrong_ty.rs b/tests/ui/eii/type_checking/wrong_ty.rs index ebb756f6a314..625af6e11dbf 100644 --- a/tests/ui/eii/type_checking/wrong_ty.rs +++ b/tests/ui/eii/type_checking/wrong_ty.rs @@ -5,7 +5,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar)] +#[eii_declaration(bar)] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/eii/type_checking/wrong_ty_2.rs b/tests/ui/eii/type_checking/wrong_ty_2.rs index d55f405bf157..2e477b5b6fcc 100644 --- a/tests/ui/eii/type_checking/wrong_ty_2.rs +++ b/tests/ui/eii/type_checking/wrong_ty_2.rs @@ -5,7 +5,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar)] +#[eii_declaration(bar)] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/eii/unsafe_impl_err.rs b/tests/ui/eii/unsafe_impl_err.rs index 6af7e9724e15..a6d24c47ae21 100644 --- a/tests/ui/eii/unsafe_impl_err.rs +++ b/tests/ui/eii/unsafe_impl_err.rs @@ -5,7 +5,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar, "unsafe")] +#[eii_declaration(bar, "unsafe")] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/eii/unsafe_impl_ok.rs b/tests/ui/eii/unsafe_impl_ok.rs index 268c5bc16fd8..1af6d63eb7cf 100644 --- a/tests/ui/eii/unsafe_impl_ok.rs +++ b/tests/ui/eii/unsafe_impl_ok.rs @@ -7,7 +7,7 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_extern_target(bar, "unsafe")] +#[eii_declaration(bar, "unsafe")] #[rustc_builtin_macro(eii_shared_macro)] macro foo() {} diff --git a/tests/ui/feature-gates/feature-gate-eii-internals.rs b/tests/ui/feature-gates/feature-gate-eii-internals.rs index b70e007ed798..96699f2905b6 100644 --- a/tests/ui/feature-gates/feature-gate-eii-internals.rs +++ b/tests/ui/feature-gates/feature-gate-eii-internals.rs @@ -2,7 +2,7 @@ #![feature(decl_macro)] #![feature(rustc_attrs)] -#[eii_extern_target(bar)] //~ ERROR use of unstable library feature `eii_internals` +#[eii_declaration(bar)] //~ ERROR use of unstable library feature `eii_internals` #[rustc_builtin_macro(eii_macro)] macro foo() {} //~ ERROR: cannot find a built-in macro with name `foo` diff --git a/tests/ui/feature-gates/feature-gate-eii-internals.stderr b/tests/ui/feature-gates/feature-gate-eii-internals.stderr index f08f0a5e65b3..78aa49ebab1c 100644 --- a/tests/ui/feature-gates/feature-gate-eii-internals.stderr +++ b/tests/ui/feature-gates/feature-gate-eii-internals.stderr @@ -1,8 +1,8 @@ error[E0658]: use of unstable library feature `eii_internals` --> $DIR/feature-gate-eii-internals.rs:5:3 | -LL | #[eii_extern_target(bar)] - | ^^^^^^^^^^^^^^^^^ +LL | #[eii_declaration(bar)] + | ^^^^^^^^^^^^^^^ | = help: add `#![feature(eii_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date From 6d0f23adad84c37863de550a878f84dd9e3bb1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 10 Jan 2026 11:26:20 +0100 Subject: [PATCH 1980/3801] rename extern item to foreign item --- .../rustc_attr_parsing/src/attributes/codegen_attrs.rs | 8 ++++---- compiler/rustc_attr_parsing/src/context.rs | 4 ++-- compiler/rustc_builtin_macros/src/eii.rs | 4 ++-- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 2 +- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- compiler/rustc_hir/src/attrs/data_structures.rs | 2 +- compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index c68c66b27185..5bbaeda18df3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -709,11 +709,11 @@ impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisPa const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis; } -pub(crate) struct EiiExternItemParser; +pub(crate) struct EiiForeignItemParser; -impl NoArgsAttributeParser for EiiExternItemParser { - const PATH: &[Symbol] = &[sym::rustc_eii_extern_item]; +impl NoArgsAttributeParser for EiiForeignItemParser { + const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); - const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::EiiExternItem; + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::EiiForeignItem; } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 835bf8ae5c9c..00921cf54cd8 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -21,7 +21,7 @@ use crate::attributes::allow_unstable::{ use crate::attributes::body::CoroutineParser; use crate::attributes::cfi_encoding::CfiEncodingParser; use crate::attributes::codegen_attrs::{ - ColdParser, CoverageParser, EiiExternItemParser, ExportNameParser, ForceTargetFeatureParser, + ColdParser, CoverageParser, EiiForeignItemParser, ExportNameParser, ForceTargetFeatureParser, NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser, RustcPassIndirectlyInNonRusticAbisParser, SanitizeParser, TargetFeatureParser, ThreadLocalParser, TrackCallerParser, UsedParser, @@ -243,7 +243,7 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index e8aeb8090bf4..cec7599d68e9 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -295,9 +295,9 @@ fn generate_foreign_item( let mut foreign_item_attrs = ThinVec::new(); foreign_item_attrs.extend_from_slice(attrs_from_decl); - // Add the rustc_eii_extern_item on the foreign item. Usually, foreign items are mangled. + // Add the rustc_eii_foreign_item on the foreign item. Usually, foreign items are mangled. // This attribute makes sure that we later know that this foreign item's symbol should not be. - foreign_item_attrs.push(ecx.attr_word(sym::rustc_eii_extern_item, eii_attr_span)); + foreign_item_attrs.push(ecx.attr_word(sym::rustc_eii_foreign_item, eii_attr_span)); let abi = match func.sig.header.ext { // extern "X" fn => extern "X" {} diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index db150faea86d..fa02c5c51f7c 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -282,7 +282,7 @@ fn process_builtin_attrs( AttributeKind::ObjcSelector { methname, .. } => { codegen_fn_attrs.objc_selector = Some(*methname); } - AttributeKind::EiiExternItem => { + AttributeKind::EiiForeignItem => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM; } AttributeKind::EiiImpls(impls) => { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index a7e8515e415f..22753adb4c99 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -962,7 +962,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint", ), gated!( - rustc_eii_extern_item, Normal, template!(Word), + rustc_eii_foreign_item, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, eii_internals, "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ), diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index c6c50bb793f8..15a668bd9199 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -747,7 +747,7 @@ pub enum AttributeKind { EiiDeclaration(EiiDecl), /// Implementation detail of `#[eii]` - EiiExternItem, + EiiForeignItem, /// Implementation detail of `#[eii]` EiiImpls(ThinVec), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index d854cc34c0f3..233aee54adbb 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -48,7 +48,7 @@ impl AttributeKind { DocComment { .. } => Yes, Dummy => No, EiiDeclaration(_) => Yes, - EiiExternItem => No, + EiiForeignItem => No, EiiImpls(..) => No, ExportName { .. } => Yes, ExportStable => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index beae0efa927f..1d48785169d7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -225,7 +225,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }, Attribute::Parsed( AttributeKind::EiiDeclaration { .. } - | AttributeKind::EiiExternItem + | AttributeKind::EiiForeignItem | AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect | AttributeKind::MacroTransparency(_) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d5a46bc02f1a..f56c3421ce0f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1951,7 +1951,7 @@ symbols! { rustc_dump_user_args, rustc_dump_vtable, rustc_effective_visibility, - rustc_eii_extern_item, + rustc_eii_foreign_item, rustc_evaluate_where_clauses, rustc_expected_cgu_reuse, rustc_force_inline, From 19aae35b08d64c2ac4bcd5b888b6812fc803ab3f Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 12 Jan 2026 08:36:32 +0100 Subject: [PATCH 1981/3801] Create a new `SymbolKind::CrateRoot` --- .../src/completions/extern_crate.rs | 6 +++--- .../crates/ide-completion/src/item.rs | 1 + .../rust-analyzer/crates/ide-db/src/lib.rs | 8 ++++--- .../crates/ide/src/navigation_target.rs | 13 ++++-------- .../crates/ide/src/references.rs | 2 +- .../rust-analyzer/crates/ide/src/runnables.rs | 8 +++---- .../ide/src/syntax_highlighting/highlight.rs | 21 +++++++++---------- .../ide/src/syntax_highlighting/inject.rs | 12 +++++------ .../ide/src/syntax_highlighting/tags.rs | 1 + .../test_data/highlight_asm.html | 8 +++---- .../test_data/highlight_attributes.html | 2 +- .../test_data/highlight_crate_root.html | 16 +++++++------- .../test_data/highlight_default_library.html | 2 +- .../test_data/highlight_deprecated.html | 4 ++-- .../test_data/highlight_doctest.html | 6 +++--- .../test_data/highlight_extern_crate.html | 14 ++++++------- .../test_data/highlight_general.html | 12 +++++------ .../test_data/highlight_injection_2.html | 2 +- .../test_data/highlight_issue_18089.html | 2 +- .../test_data/highlight_keywords_2015.html | 8 +++---- .../test_data/highlight_keywords_2018.html | 8 +++---- .../test_data/highlight_keywords_2021.html | 8 +++---- .../test_data/highlight_keywords_2024.html | 8 +++---- .../test_data/highlight_keywords_macros.html | 4 ++-- .../test_data/highlight_macros.html | 2 +- .../test_data/highlight_strings.html | 2 +- .../test_data/highlight_unsafe.html | 4 ++-- .../crates/rust-analyzer/src/lsp/to_proto.rs | 8 ++++++- 28 files changed, 98 insertions(+), 94 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs index 71a3e4eb4ed6..91202e8b32fc 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs @@ -17,7 +17,7 @@ pub(crate) fn complete_extern_crate(acc: &mut Completions, ctx: &CompletionConte } let mut item = CompletionItem::new( - CompletionItemKind::SymbolKind(SymbolKind::Module), + CompletionItemKind::SymbolKind(SymbolKind::CrateRoot), ctx.source_range(), name.display_no_db(ctx.edition).to_smolstr(), ctx.edition, @@ -48,7 +48,7 @@ mod other_mod {} let completion_list = completion_list_no_kw(case); - assert_eq!("md other_crate_a\n".to_owned(), completion_list); + assert_eq!("cr other_crate_a\n".to_owned(), completion_list); } #[test] @@ -68,6 +68,6 @@ mod other_mod {} let completion_list = completion_list_no_kw(case); - assert_eq!("md other_crate_a\n".to_owned(), completion_list); + assert_eq!("cr other_crate_a\n".to_owned(), completion_list); } } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs index 71d32da74710..1a9139d8553b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs @@ -381,6 +381,7 @@ impl CompletionItemKind { SymbolKind::BuiltinAttr => "ba", SymbolKind::Const => "ct", SymbolKind::ConstParam => "cp", + SymbolKind::CrateRoot => "cr", SymbolKind::Derive => "de", SymbolKind::DeriveHelper => "dh", SymbolKind::Enum => "en", diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 413b58bf7980..023b32b36195 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -65,7 +65,7 @@ use base_db::{ }; use hir::{ FilePositionWrapper, FileRangeWrapper, - db::{DefDatabase, ExpandDatabase}, + db::{DefDatabase, ExpandDatabase, HirDatabase}, }; use triomphe::Arc; @@ -269,6 +269,7 @@ pub enum SymbolKind { BuiltinAttr, Const, ConstParam, + CrateRoot, Derive, DeriveHelper, Enum, @@ -307,14 +308,15 @@ impl From for SymbolKind { } } -impl From for SymbolKind { - fn from(it: hir::ModuleDef) -> Self { +impl SymbolKind { + pub fn from_module_def(db: &dyn HirDatabase, it: hir::ModuleDef) -> Self { match it { hir::ModuleDef::Const(..) => SymbolKind::Const, hir::ModuleDef::Variant(..) => SymbolKind::Variant, hir::ModuleDef::Function(..) => SymbolKind::Function, hir::ModuleDef::Macro(mac) if mac.is_proc_macro() => SymbolKind::ProcMacro, hir::ModuleDef::Macro(..) => SymbolKind::Macro, + hir::ModuleDef::Module(m) if m.is_crate_root(db) => SymbolKind::CrateRoot, hir::ModuleDef::Module(..) => SymbolKind::Module, hir::ModuleDef::Static(..) => SymbolKind::Static, hir::ModuleDef::Adt(hir::Adt::Struct(..)) => SymbolKind::Struct, diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index 047df309eca6..185df92e2d39 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -264,7 +264,7 @@ impl<'db> TryToNav for FileSymbol<'db> { .flatten() .map_or_else(|| self.name.clone(), |it| it.symbol().clone()), alias: self.is_alias.then(|| self.name.clone()), - kind: Some(self.def.into()), + kind: Some(SymbolKind::from_module_def(db, self.def)), full_range, focus_range, container_name: self.container_name.clone(), @@ -480,16 +480,11 @@ impl ToNav for hir::Module { ModuleSource::Module(node) => (node.syntax(), node.name()), ModuleSource::BlockExpr(node) => (node.syntax(), None), }; + let kind = if self.is_crate_root(db) { SymbolKind::CrateRoot } else { SymbolKind::Module }; orig_range_with_focus(db, file_id, syntax, focus).map( |(FileRange { file_id, range: full_range }, focus_range)| { - NavigationTarget::from_syntax( - file_id, - name.clone(), - focus_range, - full_range, - SymbolKind::Module, - ) + NavigationTarget::from_syntax(file_id, name.clone(), focus_range, full_range, kind) }, ) } @@ -549,7 +544,7 @@ impl TryToNav for hir::ExternCrateDecl { self.alias_or_name(db).unwrap_or_else(|| self.name(db)).symbol().clone(), focus_range, full_range, - SymbolKind::Module, + SymbolKind::CrateRoot, ); res.docs = self.docs(db).map(Documentation::into_owned); diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs index 4918fe4ff9a4..5443021988d4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/references.rs +++ b/src/tools/rust-analyzer/crates/ide/src/references.rs @@ -1079,7 +1079,7 @@ use self$0; use self$0; "#, expect![[r#" - _ Module FileId(0) 0..10 + _ CrateRoot FileId(0) 0..10 FileId(0) 4..8 import "#]], diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index 6cec91250351..42efa7142b50 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -815,7 +815,7 @@ mod not_a_root { "#, expect![[r#" [ - "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..331, name: \"_\", kind: Module })", + "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..331, name: \"_\", kind: CrateRoot })", "(Bin, NavigationTarget { file_id: FileId(0), full_range: 1..13, focus_range: 4..8, name: \"main\", kind: Function })", "(Bin, NavigationTarget { file_id: FileId(0), full_range: 15..76, focus_range: 42..71, name: \"__cortex_m_rt_main_trampoline\", kind: Function })", "(Bin, NavigationTarget { file_id: FileId(0), full_range: 78..154, focus_range: 113..149, name: \"__cortex_m_rt_main_trampoline_unsafe\", kind: Function })", @@ -1136,7 +1136,7 @@ fn test_foo1() {} "#, expect![[r#" [ - "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..51, name: \"_\", kind: Module })", + "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..51, name: \"_\", kind: CrateRoot })", "(Test, NavigationTarget { file_id: FileId(0), full_range: 1..50, focus_range: 36..45, name: \"test_foo1\", kind: Function }, Atom(KeyValue { key: \"feature\", value: \"foo\" }))", ] "#]], @@ -1155,7 +1155,7 @@ fn test_foo1() {} "#, expect![[r#" [ - "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..73, name: \"_\", kind: Module })", + "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..73, name: \"_\", kind: CrateRoot })", "(Test, NavigationTarget { file_id: FileId(0), full_range: 1..72, focus_range: 58..67, name: \"test_foo1\", kind: Function }, All([Atom(KeyValue { key: \"feature\", value: \"foo\" }), Atom(KeyValue { key: \"feature\", value: \"bar\" })]))", ] "#]], @@ -1234,7 +1234,7 @@ generate_main!(); "#, expect![[r#" [ - "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..345, name: \"_\", kind: Module })", + "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..345, name: \"_\", kind: CrateRoot })", "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 282..312, focus_range: 286..291, name: \"tests\", kind: Module, description: \"mod tests\" })", "(Test, NavigationTarget { file_id: FileId(0), full_range: 298..307, name: \"foo_test\", kind: Function })", "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 313..323, name: \"tests2\", kind: Module, description: \"mod tests2\" }, true)", diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs index 044fd3f5ac9a..3795d3d4146d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs @@ -399,7 +399,7 @@ fn highlight_name_ref( highlight_def(sema, krate, field_ref.into(), edition, true) } NameRefClass::ExternCrateShorthand { decl, krate: resolved_krate } => { - let mut h = HlTag::Symbol(SymbolKind::Module).into(); + let mut h = HlTag::Symbol(SymbolKind::CrateRoot).into(); if krate.as_ref().is_some_and(|krate| resolved_krate != *krate) { h |= HlMod::Library; @@ -417,7 +417,6 @@ fn highlight_name_ref( if is_deprecated { h |= HlMod::Deprecated; } - h |= HlMod::CrateRoot; h } }; @@ -496,15 +495,15 @@ pub(super) fn highlight_def( } Definition::TupleField(_) => (Highlight::new(HlTag::Symbol(SymbolKind::Field)), None), Definition::Crate(krate) => ( - Highlight::new(HlTag::Symbol(SymbolKind::Module)) | HlMod::CrateRoot, + Highlight::new(HlTag::Symbol(SymbolKind::CrateRoot)).into(), Some(krate.attrs(sema.db)), ), Definition::Module(module) => { - let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module)); - if module.is_crate_root(db) { - h |= HlMod::CrateRoot; - } - + let h = Highlight::new(HlTag::Symbol(if module.is_crate_root(db) { + SymbolKind::CrateRoot + } else { + SymbolKind::Module + })); (h, Some(module.attrs(sema.db))) } Definition::Function(func) => { @@ -662,8 +661,7 @@ pub(super) fn highlight_def( (h, None) } Definition::ExternCrateDecl(extern_crate) => { - let mut highlight = - Highlight::new(HlTag::Symbol(SymbolKind::Module)) | HlMod::CrateRoot; + let mut highlight = Highlight::new(HlTag::Symbol(SymbolKind::CrateRoot)).into(); if extern_crate.alias(db).is_none() { highlight |= HlMod::Library; } @@ -805,6 +803,7 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight { TYPE_PARAM => SymbolKind::TypeParam, RECORD_FIELD => SymbolKind::Field, MODULE => SymbolKind::Module, + EXTERN_CRATE => SymbolKind::CrateRoot, FN => SymbolKind::Function, CONST => SymbolKind::Const, STATIC => SymbolKind::Static, @@ -835,7 +834,7 @@ fn highlight_name_ref_by_syntax( }; match parent.kind() { - EXTERN_CRATE => HlTag::Symbol(SymbolKind::Module) | HlMod::CrateRoot, + EXTERN_CRATE => HlTag::Symbol(SymbolKind::CrateRoot).into(), METHOD_CALL_EXPR => ast::MethodCallExpr::cast(parent) .and_then(|it| highlight_method_call(sema, krate, &it, is_unsafe_node)) .unwrap_or_else(|| SymbolKind::Method.into()), diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs index 26d2bb5e0288..291333f09cf8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs @@ -1,6 +1,6 @@ //! "Recursive" Syntax highlighting for code in doctests and fixtures. -use hir::{EditionedFileId, HirFileId, InFile, Semantics}; +use hir::{EditionedFileId, HirFileId, InFile, Semantics, db::HirDatabase}; use ide_db::{ SymbolKind, defs::Definition, documentation::Documentation, range_mapper::RangeMapper, rust_doc::is_rust_fence, @@ -109,7 +109,7 @@ pub(super) fn doc_comment( .for_each(|(range, def)| { hl.add(HlRange { range, - highlight: module_def_to_hl_tag(def) + highlight: module_def_to_hl_tag(sema.db, def) | HlMod::Documentation | HlMod::Injected | HlMod::IntraDocLink, @@ -200,11 +200,11 @@ pub(super) fn doc_comment( } } -fn module_def_to_hl_tag(def: Definition) -> HlTag { +fn module_def_to_hl_tag(db: &dyn HirDatabase, def: Definition) -> HlTag { let symbol = match def { - Definition::Module(_) | Definition::Crate(_) | Definition::ExternCrateDecl(_) => { - SymbolKind::Module - } + Definition::Crate(_) | Definition::ExternCrateDecl(_) => SymbolKind::CrateRoot, + Definition::Module(m) if m.is_crate_root(db) => SymbolKind::CrateRoot, + Definition::Module(_) => SymbolKind::Module, Definition::Function(_) => SymbolKind::Function, Definition::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct, Definition::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum, diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs index ca3c3e3aaace..0c64d3de1012 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tags.rs @@ -144,6 +144,7 @@ impl HlTag { SymbolKind::BuiltinAttr => "builtin_attr", SymbolKind::Const => "constant", SymbolKind::ConstParam => "const_param", + SymbolKind::CrateRoot => "crate_root", SymbolKind::Derive => "derive", SymbolKind::DeriveHelper => "derive_helper", SymbolKind::Enum => "enum", diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html index 100fdd2155a4..1228849c5bfd 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html @@ -45,7 +45,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd unsafe { let foo = 1; let mut o = 0; - core::arch::asm!( + core::arch::asm!( "%input = OpLoad _ {0}", concat!("%result = ", "bar", " _ %input"), "OpStore {1} %result", @@ -54,7 +54,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd ); let thread_id: usize; - core::arch::asm!(" + core::arch::asm!(" mov {0}, gs:[0x30] mov {0}, [{0}+0x48] ", out(reg) thread_id, options(pure, readonly, nostack)); @@ -64,7 +64,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd static VirtualFree: usize; const OffPtr: usize; const OffFn: usize; - core::arch::asm!(" + core::arch::asm!(" push {free_type} push {free_size} push {base} @@ -97,7 +97,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd // Ensure thumb mode is set. let rv = (rv as u32) | 1; let msp = msp as u32; - core::arch::asm!( + core::arch::asm!( "mrs {tmp}, CONTROL", "bics {tmp}, {spsel}", "msr CONTROL, {tmp}", diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html index b151ff42fc39..fa7f7b1cbafb 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html @@ -43,7 +43,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd

    #[allow(dead_code)]
     #[rustfmt::skip]
    -#[proc_macros::identity]
    +#[proc_macros::identity]
     #[derive(Default)]
     /// This is a doc comment
     // This is a normal comment
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html
    index a6e6b16bead5..0b32cedca5d8 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html
    @@ -41,25 +41,25 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
     .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
     
    -
    extern crate foo;
    -use core::iter;
    +
    extern crate foo;
    +use core::iter;
     
     pub const NINETY_TWO: u8 = 92;
     
    -use foo as foooo;
    +use foo as foooo;
     
    -pub(crate) fn main() {
    +pub(crate) fn main() {
         let baz = iter::repeat(92);
     }
     
     mod bar {
    -    pub(in super) const FORTY_TWO: u8 = 42;
    +    pub(in super) const FORTY_TWO: u8 = 42;
     
         mod baz {
    -        use super::super::NINETY_TWO;
    -        use crate::foooo::Point;
    +        use super::super::NINETY_TWO;
    +        use crate::foooo::Point;
     
    -        pub(in super::super) const TWENTY_NINE: u8 = 29;
    +        pub(in super::super) const TWENTY_NINE: u8 = 29;
         }
     }
     
    \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html index 2f4a2004f1de..29f78959a54f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html @@ -41,7 +41,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
    use core::iter;
    +
    use core::iter;
     
     fn main() {
         let foo = Some(92);
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html
    index 41d3dff8ed9e..5287affbfc5c 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html
    @@ -42,8 +42,8 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
     
     
    #![deprecated]
    -use crate as _;
    -extern crate bar;
    +use crate as _;
    +extern crate bar;
     #[deprecated]
     macro_rules! macro_ {
         () => {};
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
    index b5c3df6ee447..ce9ec7431a97 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
    @@ -48,9 +48,9 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     
     //! Syntactic name ref highlighting testing
     //! ```rust
    -//! extern crate self;
    -//! extern crate other as otter;
    -//! extern crate core;
    +//! extern crate self;
    +//! extern crate other as otter;
    +//! extern crate core;
     //! trait T { type Assoc; }
     //! fn f<Arg>() -> use<Arg> where (): T<Assoc = ()> {}
     //! ```
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
    index 3a4518236883..8f7cbddd7ffb 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
    @@ -41,12 +41,12 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
     .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
     
    -
    extern crate self as this;
    -extern crate std;
    -extern crate alloc as abc;
    -extern crate unresolved as definitely_unresolved;
    +
    extern crate self as this;
    +extern crate std;
    +extern crate alloc as abc;
    +extern crate unresolved as definitely_unresolved;
     extern crate unresolved as _;
    -extern crate test as opt_in_crate;
    -extern crate test as _;
    -extern crate proc_macro;
    +extern crate test as opt_in_crate;
    +extern crate test as _;
    +extern crate proc_macro;
     
    \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index fd652f444ffd..c6dbc435c0e8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html @@ -72,7 +72,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } } -use self::FooCopy::{self as BarCopy}; +use self::FooCopy::{self as BarCopy}; #[derive(Copy)] struct FooCopy { @@ -110,7 +110,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd FOO } -use core::ops::Fn; +use core::ops::Fn; fn baz<F: Fn() -> ()>(f: F) { f() } @@ -184,15 +184,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } fn use_foo_items() { - let bob = foo::Person { + let bob = foo::Person { name: "Bob", - age: foo::consts::NUMBER, + age: foo::consts::NUMBER, }; - let control_flow = foo::identity(foo::ControlFlow::Continue); + let control_flow = foo::identity(foo::ControlFlow::Continue); if control_flow.should_die() { - foo::die!(); + foo::die!(); } } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html index 5a5d9bd1f909..391a46f706c8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html @@ -47,7 +47,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd fixture(r#" @@- /main.rs crate:main deps:other_crate fn test() { - let x = other_crate::foo::S::thing(); + let x = other_crate::foo::S::thing(); x; } //^ i128 diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html index b28818e679ff..fccf34083d7f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html @@ -45,5 +45,5 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd template!(template); } -#[proc_macros::issue_18089] +#[proc_macros::issue_18089] fn template() {}
    \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html index d2a53b2ff9e1..6366cba1bd03 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html @@ -41,12 +41,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
    extern crate self;
    +
    extern crate self;
     
    -use crate;
    -use self;
    +use crate;
    +use self;
     mod __ {
    -    use super::*;
    +    use super::*;
     }
     
     macro_rules! void {
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
    index d309b4723238..a89e8190832e 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
    @@ -41,12 +41,12 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
     .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
     
    -
    extern crate self;
    +
    extern crate self;
     
    -use crate;
    -use self;
    +use crate;
    +use self;
     mod __ {
    -    use super::*;
    +    use super::*;
     }
     
     macro_rules! void {
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
    index d309b4723238..a89e8190832e 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
    @@ -41,12 +41,12 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
     .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
     
    -
    extern crate self;
    +
    extern crate self;
     
    -use crate;
    -use self;
    +use crate;
    +use self;
     mod __ {
    -    use super::*;
    +    use super::*;
     }
     
     macro_rules! void {
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
    index 575c9a6b0aca..aa1500b8f85b 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
    @@ -41,12 +41,12 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
     .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
     
    -
    extern crate self;
    +
    extern crate self;
     
    -use crate;
    -use self;
    +use crate;
    +use self;
     mod __ {
    -    use super::*;
    +    use super::*;
     }
     
     macro_rules! void {
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
    index caf66ace7a68..484afd81ead2 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
    @@ -41,6 +41,6 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
     .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
     
    -
    lib2015::void_2015!(try async await gen);
    -lib2024::void_2024!(try async await gen);
    +
    lib2015::void_2015!(try async await gen);
    +lib2024::void_2024!(try async await gen);
     
    \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html index b63d5cedc825..59612634fda3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html @@ -41,7 +41,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
    use proc_macros::{mirror, identity, DeriveIdentity};
    +
    use proc_macros::{mirror, identity, DeriveIdentity};
     
     mirror! {
         {
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
    index e178782c79c4..4e3822c3d31f 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
    @@ -165,7 +165,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
         toho!("{}fmt", 0);
         let i: u64 = 3;
         let o: u64;
    -    core::arch::asm!(
    +    core::arch::asm!(
             "mov {0}, {1}",
             "add {0}, 5",
             out(reg) o,
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
    index 93513f5b575d..008987d409ad 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
    @@ -91,7 +91,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     
             // unsafe fn and method calls
             unsafe_fn();
    -        self::unsafe_fn();
    +        self::unsafe_fn();
             (unsafe_fn as unsafe fn())();
             Struct { field: 0 }.unsafe_method();
     
    @@ -120,7 +120,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
             &EXTERN_STATIC;
             &raw const EXTERN_STATIC;
     
    -        core::arch::asm!(
    +        core::arch::asm!(
                 "push {base}",
                 base = const 0
             );
    diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
    index 6f0f57725fc7..e5b983dcbf85 100644
    --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
    +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
    @@ -70,6 +70,7 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind {
             | SymbolKind::Attribute
             | SymbolKind::Derive
             | SymbolKind::DeriveHelper => lsp_types::SymbolKind::FUNCTION,
    +        SymbolKind::CrateRoot => lsp_types::SymbolKind::PACKAGE,
             SymbolKind::Module | SymbolKind::ToolModule => lsp_types::SymbolKind::MODULE,
             SymbolKind::TypeAlias | SymbolKind::TypeParam | SymbolKind::SelfType => {
                 lsp_types::SymbolKind::TYPE_PARAMETER
    @@ -141,6 +142,7 @@ pub(crate) fn completion_item_kind(
                 SymbolKind::Method => lsp_types::CompletionItemKind::METHOD,
                 SymbolKind::Const => lsp_types::CompletionItemKind::CONSTANT,
                 SymbolKind::ConstParam => lsp_types::CompletionItemKind::TYPE_PARAMETER,
    +            SymbolKind::CrateRoot => lsp_types::CompletionItemKind::MODULE,
                 SymbolKind::Derive => lsp_types::CompletionItemKind::FUNCTION,
                 SymbolKind::DeriveHelper => lsp_types::CompletionItemKind::FUNCTION,
                 SymbolKind::Enum => lsp_types::CompletionItemKind::ENUM,
    @@ -803,11 +805,16 @@ fn semantic_token_type_and_modifiers(
     ) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) {
         use semantic_tokens::{modifiers as mods, types};
     
    +    let mut mods = semantic_tokens::ModifierSet::default();
         let ty = match highlight.tag {
             HlTag::Symbol(symbol) => match symbol {
                 SymbolKind::Attribute => types::DECORATOR,
                 SymbolKind::Derive => types::DERIVE,
                 SymbolKind::DeriveHelper => types::DERIVE_HELPER,
    +            SymbolKind::CrateRoot => {
    +                mods |= mods::CRATE_ROOT;
    +                types::NAMESPACE
    +            }
                 SymbolKind::Module => types::NAMESPACE,
                 SymbolKind::Impl => types::TYPE_ALIAS,
                 SymbolKind::Field => types::PROPERTY,
    @@ -870,7 +877,6 @@ fn semantic_token_type_and_modifiers(
             },
         };
     
    -    let mut mods = semantic_tokens::ModifierSet::default();
         for modifier in highlight.mods.iter() {
             let modifier = match modifier {
                 HlMod::Associated => mods::ASSOCIATED,
    
    From b327e309b9dba5f3fadc3fc9d2b3bc0ca9e1b747 Mon Sep 17 00:00:00 2001
    From: Leon Schuermann 
    Date: Mon, 12 Jan 2026 03:16:27 -0500
    Subject: [PATCH 1982/3801] core: ptr: split_at_mut: fix typo in safety doc
    
    Removes the double subject "it" in the safety documentation of
    `core::ptr::split_at_mut` for raw slice pointers, as it does not refer
    to anything.
    
    Reported-by: Johnathan Van Why 
    ---
     library/core/src/ptr/mut_ptr.rs | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
    index 8976154c61db..11e0a83bd7ec 100644
    --- a/library/core/src/ptr/mut_ptr.rs
    +++ b/library/core/src/ptr/mut_ptr.rs
    @@ -1742,7 +1742,7 @@ impl *mut [T] {
         /// that is at least `mid * size_of::()` bytes long. Not upholding these
         /// requirements is *[undefined behavior]* even if the resulting pointers are not used.
         ///
    -    /// Since `len` being in-bounds it is not a safety invariant of `*mut [T]` the
    +    /// Since `len` being in-bounds is not a safety invariant of `*mut [T]` the
         /// safety requirements of this method are the same as for [`split_at_mut_unchecked`].
         /// The explicit bounds check is only as useful as `len` is correct.
         ///
    
    From 5f6d3852ee494e167eaa8128b1d5f81a0f03234d Mon Sep 17 00:00:00 2001
    From: Lukas Wirth 
    Date: Mon, 12 Jan 2026 08:46:20 +0100
    Subject: [PATCH 1983/3801] Fix crate root search in world symbols duplicating
     root entries
    
    ---
     .../rust-analyzer/crates/hir/src/symbols.rs   |  15 +--
     .../crates/ide-db/src/items_locator.rs        |   4 +-
     .../crates/ide-db/src/symbol_index.rs         | 102 +++++++++---------
     .../ide-db/src/test_data/test_doc_alias.txt   |  28 -----
     .../test_symbol_index_collection.txt          |  28 -----
     .../ide/src/syntax_highlighting/highlight.rs  |   9 +-
     .../rust-analyzer/tests/slow-tests/main.rs    |   4 +-
     7 files changed, 67 insertions(+), 123 deletions(-)
    
    diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
    index f9002f31fd15..4461659f5c4e 100644
    --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs
    +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
    @@ -23,7 +23,7 @@ use intern::Symbol;
     use rustc_hash::FxHashMap;
     use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, ToSmolStr, ast::HasName};
     
    -use crate::{HasCrate, Module, ModuleDef, Semantics};
    +use crate::{Crate, HasCrate, Module, ModuleDef, Semantics};
     
     /// The actual data that is stored in the index. It should be as compact as
     /// possible.
    @@ -100,11 +100,6 @@ impl<'a> SymbolCollector<'a> {
             let _p = tracing::info_span!("SymbolCollector::collect", ?module).entered();
             tracing::info!(?module, "SymbolCollector::collect");
     
    -        // If this is a crate root module, add a symbol for the crate itself
    -        if module.is_crate_root(self.db) {
    -            self.push_crate_root(module);
    -        }
    -
             // The initial work is the root module we're collecting, additional work will
             // be populated as we traverse the module's definitions.
             self.work.push(SymbolCollectorWork { module_id: module.into(), parent: None });
    @@ -116,8 +111,7 @@ impl<'a> SymbolCollector<'a> {
     
         /// Push a symbol for a crate's root module.
         /// This allows crate roots to appear in the symbol index for queries like `::` or `::foo`.
    -    fn push_crate_root(&mut self, module: Module) {
    -        let krate = module.krate(self.db);
    +    pub fn push_crate_root(&mut self, krate: Crate) {
             let Some(display_name) = krate.display_name(self.db) else { return };
             let crate_name = display_name.crate_name();
             let canonical_name = display_name.canonical_name();
    @@ -131,10 +125,11 @@ impl<'a> SymbolCollector<'a> {
             let ptr = SyntaxNodePtr::new(&syntax_node);
     
             let loc = DeclarationLocation { hir_file_id, ptr, name_ptr: None };
    +        let root_module = krate.root_module(self.db);
     
             self.symbols.insert(FileSymbol {
                 name: crate_name.symbol().clone(),
    -            def: ModuleDef::Module(module),
    +            def: ModuleDef::Module(root_module),
                 loc,
                 container_name: None,
                 is_alias: false,
    @@ -147,7 +142,7 @@ impl<'a> SymbolCollector<'a> {
             if canonical_name != crate_name.symbol() {
                 self.symbols.insert(FileSymbol {
                     name: canonical_name.clone(),
    -                def: ModuleDef::Module(module),
    +                def: ModuleDef::Module(root_module),
                     loc,
                     container_name: None,
                     is_alias: false,
    diff --git a/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs b/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs
    index 0d305530d925..af0c69c6856d 100644
    --- a/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs
    +++ b/src/tools/rust-analyzer/crates/ide-db/src/items_locator.rs
    @@ -110,7 +110,7 @@ pub fn items_with_name_in_module(
                 local_query
             }
         };
    -    local_query.search(&[SymbolIndex::module_symbols(db, module)], |local_candidate| {
    +    local_query.search(db, &[SymbolIndex::module_symbols(db, module)], |local_candidate| {
             cb(match local_candidate.def {
                 hir::ModuleDef::Macro(macro_def) => ItemInNs::Macros(macro_def),
                 def => ItemInNs::from(def),
    @@ -140,7 +140,7 @@ fn find_items(
     
         // Query the local crate using the symbol index.
         let mut local_results = Vec::new();
    -    local_query.search(&symbol_index::crate_symbols(db, krate), |local_candidate| {
    +    local_query.search(db, &symbol_index::crate_symbols(db, krate), |local_candidate| {
             let def = match local_candidate.def {
                 hir::ModuleDef::Macro(macro_def) => ItemInNs::Macros(macro_def),
                 def => ItemInNs::from(def),
    diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
    index 05c3f360fa87..c95b541748ec 100644
    --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
    +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
    @@ -218,15 +218,18 @@ pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex<'_
     // | Editor  | Shortcut |
     // |---------|-----------|
     // | VS Code | Ctrl+T
    -pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> {
    +pub fn world_symbols(db: &RootDatabase, mut query: Query) -> Vec> {
         let _p = tracing::info_span!("world_symbols", query = ?query.query).entered();
     
    -    if query.is_crate_search() {
    -        return search_crates(db, &query);
    -    }
    -
    -    // If we have a path filter, resolve it to target modules
    -    let indices: Vec<_> = if !query.path_filter.is_empty() {
    +    // Search for crates by name (handles "::" and "::foo" queries)
    +    let indices: Vec<_> = if query.is_crate_search() {
    +        query.only_types = false;
    +        query.libs = true;
    +        vec![SymbolIndex::extern_prelude_symbols(db)]
    +        // If we have a path filter, resolve it to target modules
    +    } else if !query.path_filter.is_empty() {
    +        query.only_types = false;
    +        query.libs = true;
             let target_modules = resolve_path_to_modules(
                 db,
                 &query.path_filter,
    @@ -258,13 +261,17 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> {
             crates
                 .par_iter()
                 .for_each_with(db.clone(), |snap, &krate| _ = crate_symbols(snap, krate.into()));
    -        crates.into_iter().flat_map(|krate| Vec::from(crate_symbols(db, krate.into()))).collect()
    +        crates
    +            .into_iter()
    +            .flat_map(|krate| Vec::from(crate_symbols(db, krate.into())))
    +            .chain(std::iter::once(SymbolIndex::extern_prelude_symbols(db)))
    +            .collect()
         };
     
         let mut res = vec![];
     
         // Normal search: use FST to match item name
    -    query.search::<()>(&indices, |f| {
    +    query.search::<()>(db, &indices, |f| {
             res.push(f.clone());
             ControlFlow::Continue(())
         });
    @@ -272,39 +279,6 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> {
         res
     }
     
    -/// Search for crates by name (handles "::" and "::foo" queries)
    -fn search_crates<'db>(db: &'db RootDatabase, query: &Query) -> Vec> {
    -    let mut res = vec![];
    -
    -    for krate in Crate::all(db) {
    -        let Some(display_name) = krate.display_name(db) else { continue };
    -        let crate_name = display_name.crate_name().as_str();
    -
    -        // If query is empty (sole "::"), return all crates
    -        // Otherwise, fuzzy match the crate name
    -        let matches = if query.query.is_empty() {
    -            true
    -        } else {
    -            query.mode.check(&query.query, query.case_sensitive, crate_name)
    -        };
    -
    -        if matches {
    -            // Get the crate root module's symbol index and find the root module symbol
    -            let root_module = krate.root_module(db);
    -            let index = SymbolIndex::module_symbols(db, root_module);
    -            // Find the module symbol itself (representing the crate)
    -            for symbol in index.symbols.iter() {
    -                if matches!(symbol.def, hir::ModuleDef::Module(m) if m == root_module) {
    -                    res.push(symbol.clone());
    -                    break;
    -                }
    -            }
    -        }
    -    }
    -
    -    res
    -}
    -
     /// Resolve a path filter to the target module(s) it points to.
     /// Returns the modules whose symbol indices should be searched.
     ///
    @@ -452,6 +426,33 @@ impl<'db> SymbolIndex<'db> {
     
             module_symbols(db, InternedModuleId::new(db, hir::ModuleId::from(module)))
         }
    +
    +    /// The symbol index for all extern prelude crates.
    +    pub fn extern_prelude_symbols(db: &dyn HirDatabase) -> &SymbolIndex<'_> {
    +        #[salsa::tracked(returns(ref))]
    +        fn extern_prelude_symbols<'db>(db: &'db dyn HirDatabase) -> SymbolIndex<'db> {
    +            let _p = tracing::info_span!("extern_prelude_symbols").entered();
    +
    +            // We call this without attaching because this runs in parallel, so we need to attach here.
    +            hir::attach_db(db, || {
    +                let mut collector = SymbolCollector::new(db, false);
    +
    +                for krate in Crate::all(db) {
    +                    if krate
    +                        .display_name(db)
    +                        .is_none_or(|name| name.canonical_name().as_str() == "build-script-build")
    +                    {
    +                        continue;
    +                    }
    +                    collector.push_crate_root(krate);
    +                }
    +
    +                SymbolIndex::new(collector.finish())
    +            })
    +        }
    +
    +        extern_prelude_symbols(db)
    +    }
     }
     
     impl fmt::Debug for SymbolIndex<'_> {
    @@ -555,6 +556,7 @@ impl Query {
         /// Search symbols in the given indices.
         pub(crate) fn search<'db, T>(
             &self,
    +        db: &'db RootDatabase,
             indices: &[&'db SymbolIndex<'db>],
             cb: impl FnMut(&'db FileSymbol<'db>) -> ControlFlow,
         ) -> Option {
    @@ -568,7 +570,7 @@ impl Query {
                     for index in indices.iter() {
                         op = op.add(index.map.search(&automaton));
                     }
    -                self.search_maps(indices, op.union(), cb)
    +                self.search_maps(db, indices, op.union(), cb)
                 }
                 SearchMode::Fuzzy => {
                     let automaton = fst::automaton::Subsequence::new(&self.lowercased);
    @@ -576,7 +578,7 @@ impl Query {
                     for index in indices.iter() {
                         op = op.add(index.map.search(&automaton));
                     }
    -                self.search_maps(indices, op.union(), cb)
    +                self.search_maps(db, indices, op.union(), cb)
                 }
                 SearchMode::Prefix => {
                     let automaton = fst::automaton::Str::new(&self.lowercased).starts_with();
    @@ -584,13 +586,14 @@ impl Query {
                     for index in indices.iter() {
                         op = op.add(index.map.search(&automaton));
                     }
    -                self.search_maps(indices, op.union(), cb)
    +                self.search_maps(db, indices, op.union(), cb)
                 }
             }
         }
     
         fn search_maps<'db, T>(
             &self,
    +        db: &'db RootDatabase,
             indices: &[&'db SymbolIndex<'db>],
             mut stream: fst::map::Union<'_>,
             mut cb: impl FnMut(&'db FileSymbol<'db>) -> ControlFlow,
    @@ -598,18 +601,21 @@ impl Query {
             let ignore_underscore_prefixed = !self.query.starts_with("__");
             while let Some((_, indexed_values)) = stream.next() {
                 for &IndexedValue { index, value } in indexed_values {
    -                let symbol_index = &indices[index];
    +                let symbol_index = indices[index];
                     let (start, end) = SymbolIndex::map_value_to_range(value);
     
                     for symbol in &symbol_index.symbols[start..end] {
                         let non_type_for_type_only_query = self.only_types
    -                        && !matches!(
    +                        && !(matches!(
                                 symbol.def,
                                 hir::ModuleDef::Adt(..)
                                     | hir::ModuleDef::TypeAlias(..)
                                     | hir::ModuleDef::BuiltinType(..)
                                     | hir::ModuleDef::Trait(..)
    -                        );
    +                        ) || matches!(
    +                            symbol.def,
    +                            hir::ModuleDef::Module(module) if module.is_crate_root(db)
    +                        ));
                         if non_type_for_type_only_query || !self.matches_assoc_mode(symbol.is_assoc) {
                             continue;
                         }
    diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt
    index 71680699b739..0c28c312f83b 100644
    --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt
    +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt
    @@ -154,34 +154,6 @@
                     do_not_complete: Yes,
                     _marker: PhantomData<&()>,
                 },
    -            FileSymbol {
    -                name: "ra_test_fixture",
    -                def: Module(
    -                    Module {
    -                        id: ModuleIdLt {
    -                            [salsa id]: Id(3800),
    -                        },
    -                    },
    -                ),
    -                loc: DeclarationLocation {
    -                    hir_file_id: FileId(
    -                        EditionedFileId(
    -                            Id(3000),
    -                        ),
    -                    ),
    -                    ptr: SyntaxNodePtr {
    -                        kind: SOURCE_FILE,
    -                        range: 0..128,
    -                    },
    -                    name_ptr: None,
    -                },
    -                container_name: None,
    -                is_alias: false,
    -                is_assoc: false,
    -                is_import: false,
    -                do_not_complete: Yes,
    -                _marker: PhantomData<&()>,
    -            },
                 FileSymbol {
                     name: "s1",
                     def: Adt(
    diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
    index 2d62a56fe22d..4b588572d328 100644
    --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
    +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
    @@ -919,34 +919,6 @@
                     do_not_complete: Yes,
                     _marker: PhantomData<&()>,
                 },
    -            FileSymbol {
    -                name: "ra_test_fixture",
    -                def: Module(
    -                    Module {
    -                        id: ModuleIdLt {
    -                            [salsa id]: Id(3800),
    -                        },
    -                    },
    -                ),
    -                loc: DeclarationLocation {
    -                    hir_file_id: FileId(
    -                        EditionedFileId(
    -                            Id(3000),
    -                        ),
    -                    ),
    -                    ptr: SyntaxNodePtr {
    -                        kind: SOURCE_FILE,
    -                        range: 0..793,
    -                    },
    -                    name_ptr: None,
    -                },
    -                container_name: None,
    -                is_alias: false,
    -                is_assoc: false,
    -                is_import: false,
    -                do_not_complete: Yes,
    -                _marker: PhantomData<&()>,
    -            },
                 FileSymbol {
                     name: "really_define_struct",
                     def: Macro(
    diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
    index 3795d3d4146d..dcc9a8c0d5f7 100644
    --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
    +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
    @@ -494,10 +494,9 @@ pub(super) fn highlight_def(
                 (Highlight::new(HlTag::Symbol(SymbolKind::Field)), Some(field.attrs(sema.db)))
             }
             Definition::TupleField(_) => (Highlight::new(HlTag::Symbol(SymbolKind::Field)), None),
    -        Definition::Crate(krate) => (
    -            Highlight::new(HlTag::Symbol(SymbolKind::CrateRoot)).into(),
    -            Some(krate.attrs(sema.db)),
    -        ),
    +        Definition::Crate(krate) => {
    +            (Highlight::new(HlTag::Symbol(SymbolKind::CrateRoot)), Some(krate.attrs(sema.db)))
    +        }
             Definition::Module(module) => {
                 let h = Highlight::new(HlTag::Symbol(if module.is_crate_root(db) {
                     SymbolKind::CrateRoot
    @@ -661,7 +660,7 @@ pub(super) fn highlight_def(
                 (h, None)
             }
             Definition::ExternCrateDecl(extern_crate) => {
    -            let mut highlight = Highlight::new(HlTag::Symbol(SymbolKind::CrateRoot)).into();
    +            let mut highlight = Highlight::new(HlTag::Symbol(SymbolKind::CrateRoot));
                 if extern_crate.alias(db).is_none() {
                     highlight |= HlMod::Library;
                 }
    diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
    index 9f3c6742d651..b4a7b44d165a 100644
    --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
    +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
    @@ -1452,7 +1452,7 @@ foo = { path = "../foo" }
             json!([
             {
               "name": "bar",
    -          "kind": 2,
    +          "kind": 4,
               "location": {
                 "uri": "file:///[..]bar/src/lib.rs",
                 "range": {
    @@ -1511,7 +1511,7 @@ version = "0.0.0"
             json!([
             {
               "name": "baz",
    -          "kind": 2,
    +          "kind": 4,
               "location": {
                 "uri": "file:///[..]baz/src/lib.rs",
                 "range": {
    
    From 3ca709c7450317aa465e5193965e31204b39cb04 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= 
    Date: Mon, 12 Jan 2026 09:57:05 +0100
    Subject: [PATCH 1984/3801] Remove `S-waiting-on-bors` after a PR is merged
    
    ---
     rust-bors.toml | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/rust-bors.toml b/rust-bors.toml
    index 0d59918e3f77..ad1100fd2421 100644
    --- a/rust-bors.toml
    +++ b/rust-bors.toml
    @@ -55,7 +55,8 @@ try_failed = [
         "-S-waiting-on-crater"
     ]
     auto_build_succeeded = [
    -    "+merged-by-bors"
    +    "+merged-by-bors",
    +    "-S-waiting-on-bors"
     ]
     auto_build_failed = [
         "+S-waiting-on-review",
    
    From 284d1361e4cffeaafad6c5d9c31acf823cc4a43f Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= 
    Date: Mon, 25 Aug 2025 16:21:17 +0200
    Subject: [PATCH 1985/3801] Dogfood `-Zno-embed-metadata` for the standard
     library
    
    ---
     src/bootstrap/src/core/build_steps/compile.rs          | 10 +++++++++-
     src/bootstrap/src/core/builder/cargo.rs                |  4 ++++
     tests/ui/error-codes/E0152-duplicate-lang-items.rs     |  2 +-
     tests/ui/error-codes/E0152-duplicate-lang-items.stderr |  2 +-
     tests/ui/error-codes/E0152.rs                          |  2 +-
     tests/ui/error-codes/E0152.stderr                      |  2 +-
     tests/ui/lang-items/duplicate.rs                       |  2 +-
     tests/ui/lang-items/duplicate.stderr                   |  2 +-
     tests/ui/panic-handler/panic-handler-std.rs            |  2 +-
     tests/ui/panic-handler/panic-handler-std.stderr        |  2 +-
     10 files changed, 21 insertions(+), 9 deletions(-)
    
    diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
    index 2808c29cc6c0..4b13776bcf39 100644
    --- a/src/bootstrap/src/core/build_steps/compile.rs
    +++ b/src/bootstrap/src/core/build_steps/compile.rs
    @@ -299,7 +299,8 @@ impl Step for Std {
                 if self.is_for_mir_opt_tests {
                     ArtifactKeepMode::OnlyRmeta
                 } else {
    -                ArtifactKeepMode::OnlyRlib
    +                // We use -Zno-embed-metadata for the standard library
    +                ArtifactKeepMode::BothRlibAndRmeta
                 },
             );
     
    @@ -2645,6 +2646,10 @@ pub enum ArtifactKeepMode {
         OnlyRlib,
         /// Only keep .rmeta files, ignore .rlib files
         OnlyRmeta,
    +    /// Keep both .rlib and .rmeta files.
    +    /// This is essentially only useful when using `-Zno-embed-metadata`, in which case both the
    +    /// .rlib and .rmeta files are needed for compilation/linking.
    +    BothRlibAndRmeta,
         /// Custom logic for keeping an artifact
         /// It receives the filename of an artifact, and returns true if it should be kept.
         Custom(Box bool>),
    @@ -2701,6 +2706,9 @@ pub fn run_cargo(
                     match &artifact_keep_mode {
                         ArtifactKeepMode::OnlyRlib => filename.ends_with(".rlib"),
                         ArtifactKeepMode::OnlyRmeta => filename.ends_with(".rmeta"),
    +                    ArtifactKeepMode::BothRlibAndRmeta => {
    +                        filename.ends_with(".rmeta") || filename.ends_with(".rlib")
    +                    }
                         ArtifactKeepMode::Custom(func) => func(&filename),
                     }
                 };
    diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
    index b95533e11202..dda0b40cb69e 100644
    --- a/src/bootstrap/src/core/builder/cargo.rs
    +++ b/src/bootstrap/src/core/builder/cargo.rs
    @@ -1095,6 +1095,10 @@ impl Builder<'_> {
             // Enable usage of unstable features
             cargo.env("RUSTC_BOOTSTRAP", "1");
     
    +        if matches!(mode, Mode::Std) {
    +            cargo.arg("-Zno-embed-metadata");
    +        }
    +
             if self.config.dump_bootstrap_shims {
                 prepare_behaviour_dump_dir(self.build);
     
    diff --git a/tests/ui/error-codes/E0152-duplicate-lang-items.rs b/tests/ui/error-codes/E0152-duplicate-lang-items.rs
    index f707b72f9b2b..4b243205dc48 100644
    --- a/tests/ui/error-codes/E0152-duplicate-lang-items.rs
    +++ b/tests/ui/error-codes/E0152-duplicate-lang-items.rs
    @@ -3,7 +3,7 @@
     //!
     //! Issue: 
     
    -//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib"
    +//@ normalize-stderr: "loaded from .*libstd-.*.rmeta" -> "loaded from SYSROOT/libstd-*.rmeta"
     //@ dont-require-annotations: NOTE
     
     #![feature(lang_items)]
    diff --git a/tests/ui/error-codes/E0152-duplicate-lang-items.stderr b/tests/ui/error-codes/E0152-duplicate-lang-items.stderr
    index 2fe0d18fc2f4..55d5206b42ce 100644
    --- a/tests/ui/error-codes/E0152-duplicate-lang-items.stderr
    +++ b/tests/ui/error-codes/E0152-duplicate-lang-items.stderr
    @@ -9,7 +9,7 @@ LL | | }
        | |_^
        |
        = note: the lang item is first defined in crate `std` (which `E0152_duplicate_lang_items` depends on)
    -   = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
    +   = note: first definition in `std` loaded from SYSROOT/libstd-*.rmeta
        = note: second definition in the local crate (`E0152_duplicate_lang_items`)
     
     error: aborting due to 1 previous error
    diff --git a/tests/ui/error-codes/E0152.rs b/tests/ui/error-codes/E0152.rs
    index 565e92baf02e..53c7c027eff3 100644
    --- a/tests/ui/error-codes/E0152.rs
    +++ b/tests/ui/error-codes/E0152.rs
    @@ -1,4 +1,4 @@
    -//@ normalize-stderr: "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib"
    +//@ normalize-stderr: "loaded from .*liballoc-.*.rmeta" -> "loaded from SYSROOT/liballoc-*.rmeta"
     #![feature(lang_items)]
     
     #[lang = "owned_box"]
    diff --git a/tests/ui/error-codes/E0152.stderr b/tests/ui/error-codes/E0152.stderr
    index dbea7e6d27fb..73df5803e839 100644
    --- a/tests/ui/error-codes/E0152.stderr
    +++ b/tests/ui/error-codes/E0152.stderr
    @@ -5,7 +5,7 @@ LL | struct Foo(T);
        | ^^^^^^^^^^^^^^^^^
        |
        = note: the lang item is first defined in crate `alloc` (which `std` depends on)
    -   = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib
    +   = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rmeta
        = note: second definition in the local crate (`E0152`)
     
     error: aborting due to 1 previous error
    diff --git a/tests/ui/lang-items/duplicate.rs b/tests/ui/lang-items/duplicate.rs
    index 4594e9456a4c..bab952fc9ad1 100644
    --- a/tests/ui/lang-items/duplicate.rs
    +++ b/tests/ui/lang-items/duplicate.rs
    @@ -1,4 +1,4 @@
    -//@ normalize-stderr: "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib"
    +//@ normalize-stderr: "loaded from .*libcore-.*.rmeta" -> "loaded from SYSROOT/libcore-*.rmeta"
     #![feature(lang_items)]
     
     #[lang = "sized"]
    diff --git a/tests/ui/lang-items/duplicate.stderr b/tests/ui/lang-items/duplicate.stderr
    index aaa8f5e605af..5639bcc838d8 100644
    --- a/tests/ui/lang-items/duplicate.stderr
    +++ b/tests/ui/lang-items/duplicate.stderr
    @@ -5,7 +5,7 @@ LL | trait Sized {}
        | ^^^^^^^^^^^^^^
        |
        = note: the lang item is first defined in crate `core` (which `std` depends on)
    -   = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib
    +   = note: first definition in `core` loaded from SYSROOT/libcore-*.rmeta
        = note: second definition in the local crate (`duplicate`)
     
     error: aborting due to 1 previous error
    diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs
    index f6a4b60461ce..4d4e20037aaa 100644
    --- a/tests/ui/panic-handler/panic-handler-std.rs
    +++ b/tests/ui/panic-handler/panic-handler-std.rs
    @@ -1,4 +1,4 @@
    -//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib"
    +//@ normalize-stderr: "loaded from .*libstd-.*.rmeta" -> "loaded from SYSROOT/libstd-*.rmeta"
     
     extern crate core;
     
    diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr
    index 48c216ce27ec..3c4426782233 100644
    --- a/tests/ui/panic-handler/panic-handler-std.stderr
    +++ b/tests/ui/panic-handler/panic-handler-std.stderr
    @@ -7,7 +7,7 @@ LL | | }
        | |_^
        |
        = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on)
    -   = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
    +   = note: first definition in `std` loaded from SYSROOT/libstd-*.rmeta
        = note: second definition in the local crate (`panic_handler_std`)
     
     error: aborting due to 1 previous error
    
    From e03cb1f0a6d99d0874a4f88066d6217dfcd22d8b Mon Sep 17 00:00:00 2001
    From: Akshit Gaur <119689115+akshitgaur2005@users.noreply.github.com>
    Date: Fri, 2 Jan 2026 14:52:50 +0530
    Subject: [PATCH 1986/3801] run-make-support: resolve .rmeta companion for
     .rlib stubs
    
    Add .rmeta resolution for run-make/sysroot-crates-are-unstable test
    ---
     .../sysroot-crates-are-unstable/rmake.rs       | 18 +++++++++++-------
     1 file changed, 11 insertions(+), 7 deletions(-)
    
    diff --git a/tests/run-make/sysroot-crates-are-unstable/rmake.rs b/tests/run-make/sysroot-crates-are-unstable/rmake.rs
    index 623b9650771c..3b75e4d90d96 100644
    --- a/tests/run-make/sysroot-crates-are-unstable/rmake.rs
    +++ b/tests/run-make/sysroot-crates-are-unstable/rmake.rs
    @@ -28,13 +28,17 @@ fn check_crate_is_unstable(cr: &Crate) {
     
         print!("- Verifying that sysroot crate '{name}' is an unstable crate ...");
     
    -    // Trying to use this crate from a user program should fail.
    -    let output = rustc()
    -        .crate_type("rlib")
    -        .extern_(name, path)
    -        .input("-")
    -        .stdin_buf(format!("extern crate {name};"))
    -        .run_fail();
    +    // Checking if rmeta path exists
    +    let rmeta_path = path.with_extension("rmeta");
    +
    +    let mut cmd = rustc();
    +    cmd.crate_type("rlib").extern_(name, path); // Pass the rlib
    +
    +    if rmeta_path.exists() {
    +        cmd.extern_(name, &rmeta_path);
    +    }
    +
    +    let output = cmd.input("-").stdin_buf(format!("extern crate {name};")).run_fail();
     
         // Make sure it failed for the intended reason, not some other reason.
         // (The actual feature required varies between crates.)
    
    From 6ca950136de7abd91cc1820b5a7f7109fe568016 Mon Sep 17 00:00:00 2001
    From: Hans Wennborg 
    Date: Mon, 12 Jan 2026 11:03:04 +0100
    Subject: [PATCH 1987/3801] Relax test expectation for
     @__llvm_profile_runtime_user
    
    After https://github.com/llvm/llvm-project/pull/174174 it has profile
    info marking it cold.
    ---
     tests/codegen-llvm/instrument-coverage/testprog.rs | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/codegen-llvm/instrument-coverage/testprog.rs b/tests/codegen-llvm/instrument-coverage/testprog.rs
    index 9e918499d577..ef61ede6de8e 100644
    --- a/tests/codegen-llvm/instrument-coverage/testprog.rs
    +++ b/tests/codegen-llvm/instrument-coverage/testprog.rs
    @@ -109,7 +109,7 @@ fn main() {
     
     // CHECK:        declare void @llvm.instrprof.increment(ptr, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]
     
    -// WIN:          define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat {
    +// WIN:          define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat {{.*}}{
     // WIN-NEXT:     %1 = load i32, ptr @__llvm_profile_runtime
     // WIN-NEXT:     ret i32 %1
     // WIN-NEXT:     }
    
    From ac80ccec5f5999e7251474380661be5a84e56683 Mon Sep 17 00:00:00 2001
    From: dianqk 
    Date: Sat, 10 Jan 2026 20:10:18 +0800
    Subject: [PATCH 1988/3801] Only use SSA locals in SimplifyComparisonIntegral
    
    ---
     compiler/rustc_middle/src/mir/statement.rs    |  6 ++++
     .../src/simplify_comparison_integral.rs       | 31 ++++++++++++-------
     ...on_ssa_cmp.SimplifyComparisonIntegral.diff |  3 +-
     ..._ssa_place.SimplifyComparisonIntegral.diff |  3 +-
     ...ssa_switch.SimplifyComparisonIntegral.diff |  3 +-
     tests/mir-opt/if_condition_int.rs             | 24 ++++++++++++++
     6 files changed, 52 insertions(+), 18 deletions(-)
    
    diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
    index c1f8c46baddb..adaac3d7ffc2 100644
    --- a/compiler/rustc_middle/src/mir/statement.rs
    +++ b/compiler/rustc_middle/src/mir/statement.rs
    @@ -374,6 +374,12 @@ impl<'tcx> Place<'tcx> {
             self.projection.iter().any(|elem| elem.is_indirect())
         }
     
    +    /// Returns `true` if the `Place` always refers to the same memory region
    +    /// whatever the state of the program.
    +    pub fn is_stable_offset(&self) -> bool {
    +        self.projection.iter().all(|elem| elem.is_stable_offset())
    +    }
    +
         /// Returns `true` if this `Place`'s first projection is `Deref`.
         ///
         /// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
    diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
    index 2643d78990e5..53a796b1179a 100644
    --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
    +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
    @@ -9,6 +9,8 @@ use rustc_middle::mir::{
     use rustc_middle::ty::{Ty, TyCtxt};
     use tracing::trace;
     
    +use crate::ssa::SsaLocals;
    +
     /// Pass to convert `if` conditions on integrals into switches on the integral.
     /// For an example, it turns something like
     ///
    @@ -33,11 +35,12 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
         fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             trace!("Running SimplifyComparisonIntegral on {:?}", body.source);
     
    +        let typing_env = body.typing_env(tcx);
    +        let ssa = SsaLocals::new(tcx, body, typing_env);
             let helper = OptimizationFinder { body };
    -        let opts = helper.find_optimizations();
    +        let opts = helper.find_optimizations(&ssa);
             let mut storage_deads_to_insert = vec![];
             let mut storage_deads_to_remove: Vec<(usize, BasicBlock)> = vec![];
    -        let typing_env = body.typing_env(tcx);
             for opt in opts {
                 trace!("SUCCESS: Applying {:?}", opt);
                 // replace terminator with a switchInt that switches on the integer directly
    @@ -154,19 +157,18 @@ struct OptimizationFinder<'a, 'tcx> {
     }
     
     impl<'tcx> OptimizationFinder<'_, 'tcx> {
    -    fn find_optimizations(&self) -> Vec> {
    +    fn find_optimizations(&self, ssa: &SsaLocals) -> Vec> {
             self.body
                 .basic_blocks
                 .iter_enumerated()
                 .filter_map(|(bb_idx, bb)| {
                     // find switch
    -                let (place_switched_on, targets, place_switched_on_moved) =
    -                    match &bb.terminator().kind {
    -                        rustc_middle::mir::TerminatorKind::SwitchInt { discr, targets, .. } => {
    -                            Some((discr.place()?, targets, discr.is_move()))
    -                        }
    -                        _ => None,
    -                    }?;
    +                let (discr, targets) = bb.terminator().kind.as_switch()?;
    +                let place_switched_on = discr.place()?;
    +                // Make sure that the place is not modified.
    +                if !ssa.is_ssa(place_switched_on.local) || !place_switched_on.is_stable_offset() {
    +                    return None;
    +                }
     
                     // find the statement that assigns the place being switched on
                     bb.statements.iter().enumerate().rev().find_map(|(stmt_idx, stmt)| {
    @@ -180,12 +182,12 @@ impl<'tcx> OptimizationFinder<'_, 'tcx> {
                                         box (left, right),
                                     ) => {
                                         let (branch_value_scalar, branch_value_ty, to_switch_on) =
    -                                        find_branch_value_info(left, right)?;
    +                                        find_branch_value_info(left, right, ssa)?;
     
                                         Some(OptimizationInfo {
                                             bin_op_stmt_idx: stmt_idx,
                                             bb_idx,
    -                                        can_remove_bin_op_stmt: place_switched_on_moved,
    +                                        can_remove_bin_op_stmt: discr.is_move(),
                                             to_switch_on,
                                             branch_value_scalar,
                                             branch_value_ty,
    @@ -207,6 +209,7 @@ impl<'tcx> OptimizationFinder<'_, 'tcx> {
     fn find_branch_value_info<'tcx>(
         left: &Operand<'tcx>,
         right: &Operand<'tcx>,
    +    ssa: &SsaLocals,
     ) -> Option<(Scalar, Ty<'tcx>, Place<'tcx>)> {
         // check that either left or right is a constant.
         // if any are, we can use the other to switch on, and the constant as a value in a switch
    @@ -214,6 +217,10 @@ fn find_branch_value_info<'tcx>(
         match (left, right) {
             (Constant(branch_value), Copy(to_switch_on) | Move(to_switch_on))
             | (Copy(to_switch_on) | Move(to_switch_on), Constant(branch_value)) => {
    +            // Make sure that the place is not modified.
    +            if !ssa.is_ssa(to_switch_on.local) || !to_switch_on.is_stable_offset() {
    +                return None;
    +            }
                 let branch_value_ty = branch_value.const_.ty();
                 // we only want to apply this optimization if we are matching on integrals (and chars),
                 // as it is not possible to switch on floats
    diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff
    index d0983c660623..ce5a2bf172a9 100644
    --- a/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff
    +++ b/tests/mir-opt/if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff
    @@ -8,8 +8,7 @@
           bb0: {
               _2 = Eq(copy _1, const 42_u64);
               _1 = const 43_u64;
    --         switchInt(copy _2) -> [1: bb1, otherwise: bb2];
    -+         switchInt(move _1) -> [42: bb1, otherwise: bb2];
    +          switchInt(copy _2) -> [1: bb1, otherwise: bb2];
           }
       
           bb1: {
    diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff
    index 0c6c8dca4753..7ad0a87f1cdd 100644
    --- a/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff
    +++ b/tests/mir-opt/if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff
    @@ -8,8 +8,7 @@
           bb0: {
               _3 = Eq(copy _1[_2], const 42_u64);
               _2 = const 10_usize;
    --         switchInt(copy _3) -> [1: bb1, otherwise: bb2];
    -+         switchInt(move _1[_2]) -> [42: bb1, otherwise: bb2];
    +          switchInt(copy _3) -> [1: bb1, otherwise: bb2];
           }
       
           bb1: {
    diff --git a/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff
    index b1b1ab2c2205..e2dc97f76b5c 100644
    --- a/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff
    +++ b/tests/mir-opt/if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff
    @@ -8,8 +8,7 @@
           bb0: {
               _2 = Eq(copy _1, const 42_u64);
               _2 = const false;
    --         switchInt(copy _2) -> [1: bb1, otherwise: bb2];
    -+         switchInt(move _1) -> [42: bb1, otherwise: bb2];
    +          switchInt(copy _2) -> [1: bb1, otherwise: bb2];
           }
       
           bb1: {
    diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs
    index ba901f6b9b15..b49f8768253a 100644
    --- a/tests/mir-opt/if_condition_int.rs
    +++ b/tests/mir-opt/if_condition_int.rs
    @@ -120,6 +120,14 @@ fn dont_opt_floats(a: f32) -> i32 {
     // EMIT_MIR if_condition_int.on_non_ssa_switch.SimplifyComparisonIntegral.diff
     #[custom_mir(dialect = "runtime")]
     pub fn on_non_ssa_switch(mut v: u64) -> i32 {
    +    // CHECK-LABEL: fn on_non_ssa_switch(
    +    // CHECK: [[cmp:_.*]] = Eq(copy _1, const 42_u64);
    +    // CHECK: [[cmp]] = const false;
    +    // CHECK: switchInt(copy [[cmp]]) -> [1: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
    +    // CHECK: [[BB1]]:
    +    // CHECK: _0 = const 0_i32;
    +    // CHECK: [[BB2]]:
    +    // CHECK: _0 = const 1_i32;
         mir! {
             let a: bool;
             {
    @@ -145,6 +153,14 @@ pub fn on_non_ssa_switch(mut v: u64) -> i32 {
     // EMIT_MIR if_condition_int.on_non_ssa_cmp.SimplifyComparisonIntegral.diff
     #[custom_mir(dialect = "runtime")]
     pub fn on_non_ssa_cmp(mut v: u64) -> i32 {
    +    // CHECK-LABEL: fn on_non_ssa_cmp(
    +    // CHECK: [[cmp:_.*]] = Eq(copy _1, const 42_u64);
    +    // CHECK: _1 = const 43_u64;
    +    // CHECK: switchInt(copy [[cmp]]) -> [1: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
    +    // CHECK: [[BB1]]:
    +    // CHECK: _0 = const 0_i32;
    +    // CHECK: [[BB2]]:
    +    // CHECK: _0 = const 1_i32;
         mir! {
             let a: bool;
             {
    @@ -170,6 +186,14 @@ pub fn on_non_ssa_cmp(mut v: u64) -> i32 {
     // EMIT_MIR if_condition_int.on_non_ssa_place.SimplifyComparisonIntegral.diff
     #[custom_mir(dialect = "runtime")]
     pub fn on_non_ssa_place(mut v: [u64; 10], mut i: usize) -> i32 {
    +    // CHECK-LABEL: fn on_non_ssa_place(
    +    // CHECK: [[cmp:_.*]] = Eq(copy _1[_2], const 42_u64);
    +    // CHECK: _2 = const 10_usize;
    +    // CHECK: switchInt(copy [[cmp]]) -> [1: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
    +    // CHECK: [[BB1]]:
    +    // CHECK: _0 = const 0_i32;
    +    // CHECK: [[BB2]]:
    +    // CHECK: _0 = const 1_i32;
         mir! {
             let a: bool;
             {
    
    From 37f83fb11d187aea102340b1be20f3f65c4c2cac Mon Sep 17 00:00:00 2001
    From: dianqk 
    Date: Sat, 10 Jan 2026 20:27:08 +0800
    Subject: [PATCH 1989/3801] Use Copy in the SwitchInt terminator
    
    Move can be used only when both the compared operand and the operand on switch are move operands.
    This commit directly changes to Copy, because I don't know if Move has beneficial.
    ---
     .../src/simplify_comparison_integral.rs           |  2 +-
     ..._exponential_common.GVN.32bit.panic-abort.diff |  2 +-
     ...exponential_common.GVN.32bit.panic-unwind.diff |  2 +-
     ..._exponential_common.GVN.64bit.panic-abort.diff |  2 +-
     ...exponential_common.GVN.64bit.panic-unwind.diff |  2 +-
     ...ove_comparison.SimplifyComparisonIntegral.diff |  2 +-
     ...n_int.opt_char.SimplifyComparisonIntegral.diff |  2 +-
     ...ion_int.opt_i8.SimplifyComparisonIntegral.diff |  2 +-
     ...t_multiple_ifs.SimplifyComparisonIntegral.diff |  4 ++--
     ...t.opt_negative.SimplifyComparisonIntegral.diff |  2 +-
     ...on_int.opt_u32.SimplifyComparisonIntegral.diff |  2 +-
     tests/mir-opt/if_condition_int.rs                 | 15 +++++++--------
     ...o_digit.PreCodegen.after.32bit.panic-abort.mir |  2 +-
     ..._digit.PreCodegen.after.32bit.panic-unwind.mir |  2 +-
     ...o_digit.PreCodegen.after.64bit.panic-abort.mir |  2 +-
     ..._digit.PreCodegen.after.64bit.panic-unwind.mir |  2 +-
     16 files changed, 23 insertions(+), 24 deletions(-)
    
    diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
    index 53a796b1179a..b7445a0f7c2e 100644
    --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
    +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
    @@ -135,7 +135,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
     
                 let terminator = bb.terminator_mut();
                 terminator.kind =
    -                TerminatorKind::SwitchInt { discr: Operand::Move(opt.to_switch_on), targets };
    +                TerminatorKind::SwitchInt { discr: Operand::Copy(opt.to_switch_on), targets };
             }
     
             for (idx, bb_idx) in storage_deads_to_remove {
    diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff
    index 6baa902b6f4b..2b77aa380a0f 100644
    --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff
    +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff
    @@ -74,7 +74,7 @@
               _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
               _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
               StorageDead(_23);
    -          switchInt(move _22) -> [0: bb10, otherwise: bb11];
    +          switchInt(copy _22) -> [0: bb10, otherwise: bb11];
           }
       
           bb4: {
    diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff
    index 36540e038654..ba6d2f3e155c 100644
    --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff
    +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff
    @@ -74,7 +74,7 @@
               _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
               _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
               StorageDead(_23);
    -          switchInt(move _22) -> [0: bb10, otherwise: bb11];
    +          switchInt(copy _22) -> [0: bb10, otherwise: bb11];
           }
       
           bb4: {
    diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff
    index 41c350f3eaeb..bf6d9d864d57 100644
    --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff
    +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff
    @@ -74,7 +74,7 @@
               _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
               _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
               StorageDead(_23);
    -          switchInt(move _22) -> [0: bb10, otherwise: bb11];
    +          switchInt(copy _22) -> [0: bb10, otherwise: bb11];
           }
       
           bb4: {
    diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff
    index b839bf81eaf4..01c87fd5317a 100644
    --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff
    +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff
    @@ -74,7 +74,7 @@
               _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32);
               _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG);
               StorageDead(_23);
    -          switchInt(move _22) -> [0: bb10, otherwise: bb11];
    +          switchInt(copy _22) -> [0: bb10, otherwise: bb11];
           }
       
           bb4: {
    diff --git a/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
    index 29d57722355b..f5f2e0317ead 100644
    --- a/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
    +++ b/tests/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
    @@ -21,7 +21,7 @@
               _2 = Eq(copy _1, const 17_i8);
               StorageDead(_3);
     -         switchInt(copy _2) -> [0: bb2, otherwise: bb1];
    -+         switchInt(move _1) -> [17: bb1, otherwise: bb2];
    ++         switchInt(copy _1) -> [17: bb1, otherwise: bb2];
           }
       
           bb1: {
    diff --git a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
    index 37b41c2aa5ab..22f6443a6c0f 100644
    --- a/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
    +++ b/tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
    @@ -14,7 +14,7 @@
     -         _2 = Eq(copy _1, const 'x');
     -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
     +         nop;
    -+         switchInt(move _1) -> [120: bb1, otherwise: bb2];
    ++         switchInt(copy _1) -> [120: bb1, otherwise: bb2];
           }
       
           bb1: {
    diff --git a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
    index c92a606090e4..d5c48fd04ca6 100644
    --- a/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
    +++ b/tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
    @@ -14,7 +14,7 @@
     -         _2 = Eq(copy _1, const 42_i8);
     -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
     +         nop;
    -+         switchInt(move _1) -> [42: bb1, otherwise: bb2];
    ++         switchInt(copy _1) -> [42: bb1, otherwise: bb2];
           }
       
           bb1: {
    diff --git a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
    index a73670323b1f..84d62b813607 100644
    --- a/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
    +++ b/tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
    @@ -16,7 +16,7 @@
     -         _2 = Eq(copy _1, const 42_u32);
     -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
     +         nop;
    -+         switchInt(move _1) -> [42: bb1, otherwise: bb2];
    ++         switchInt(copy _1) -> [42: bb1, otherwise: bb2];
           }
       
           bb1: {
    @@ -33,7 +33,7 @@
     -         _4 = Ne(copy _1, const 21_u32);
     -         switchInt(move _4) -> [0: bb4, otherwise: bb3];
     +         nop;
    -+         switchInt(move _1) -> [21: bb4, otherwise: bb3];
    ++         switchInt(copy _1) -> [21: bb4, otherwise: bb3];
           }
       
           bb3: {
    diff --git a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
    index 36145ab02bea..a1cbaff796b3 100644
    --- a/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
    +++ b/tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
    @@ -14,7 +14,7 @@
     -         _2 = Eq(copy _1, const -42_i32);
     -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
     +         nop;
    -+         switchInt(move _1) -> [4294967254: bb1, otherwise: bb2];
    ++         switchInt(copy _1) -> [4294967254: bb1, otherwise: bb2];
           }
       
           bb1: {
    diff --git a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
    index 2cc4a8b76973..8101de8cbf38 100644
    --- a/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
    +++ b/tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
    @@ -14,7 +14,7 @@
     -         _2 = Eq(copy _1, const 42_u32);
     -         switchInt(move _2) -> [0: bb2, otherwise: bb1];
     +         nop;
    -+         switchInt(move _1) -> [42: bb1, otherwise: bb2];
    ++         switchInt(copy _1) -> [42: bb1, otherwise: bb2];
           }
       
           bb1: {
    diff --git a/tests/mir-opt/if_condition_int.rs b/tests/mir-opt/if_condition_int.rs
    index b49f8768253a..5e0961da3cce 100644
    --- a/tests/mir-opt/if_condition_int.rs
    +++ b/tests/mir-opt/if_condition_int.rs
    @@ -10,8 +10,7 @@ use core::intrinsics::mir::*;
     // EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
     fn opt_u32(x: u32) -> u32 {
         // CHECK-LABEL: fn opt_u32(
    -    // FIXME: This should be copy.
    -    // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
    +    // CHECK: switchInt(copy _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
         // CHECK: [[BB1]]:
         // CHECK: _0 = const 0_u32;
         // CHECK: [[BB2]]:
    @@ -34,7 +33,7 @@ fn dont_opt_bool(x: bool) -> u32 {
     // EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff
     fn opt_char(x: char) -> u32 {
         // CHECK-LABEL: fn opt_char(
    -    // CHECK: switchInt(move _1) -> [120: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
    +    // CHECK: switchInt(copy _1) -> [120: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
         // CHECK: [[BB1]]:
         // CHECK: _0 = const 0_u32;
         // CHECK: [[BB2]]:
    @@ -45,7 +44,7 @@ fn opt_char(x: char) -> u32 {
     // EMIT_MIR if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
     fn opt_i8(x: i8) -> u32 {
         // CHECK-LABEL: fn opt_i8(
    -    // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
    +    // CHECK: switchInt(copy _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
         // CHECK: [[BB1]]:
         // CHECK: _0 = const 0_u32;
         // CHECK: [[BB2]]:
    @@ -56,7 +55,7 @@ fn opt_i8(x: i8) -> u32 {
     // EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
     fn opt_negative(x: i32) -> u32 {
         // CHECK-LABEL: fn opt_negative(
    -    // CHECK: switchInt(move _1) -> [4294967254: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
    +    // CHECK: switchInt(copy _1) -> [4294967254: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
         // CHECK: [[BB1]]:
         // CHECK: _0 = const 0_u32;
         // CHECK: [[BB2]]:
    @@ -67,11 +66,11 @@ fn opt_negative(x: i32) -> u32 {
     // EMIT_MIR if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
     fn opt_multiple_ifs(x: u32) -> u32 {
         // CHECK-LABEL: fn opt_multiple_ifs(
    -    // CHECK: switchInt(move _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
    +    // CHECK: switchInt(copy _1) -> [42: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
         // CHECK: [[BB1]]:
         // CHECK: _0 = const 0_u32;
         // CHECK: [[BB2]]:
    -    // CHECK: switchInt(move _1) -> [21: [[BB4:bb.*]], otherwise: [[BB3:bb.*]]];
    +    // CHECK: switchInt(copy _1) -> [21: [[BB4:bb.*]], otherwise: [[BB3:bb.*]]];
         // CHECK: [[BB3]]:
         // CHECK: _0 = const 1_u32;
         // CHECK: [[BB4]]:
    @@ -90,7 +89,7 @@ fn opt_multiple_ifs(x: u32) -> u32 {
     fn dont_remove_comparison(a: i8) -> i32 {
         // CHECK-LABEL: fn dont_remove_comparison(
         // CHECK: [[b:_.*]] = Eq(copy _1, const 17_i8);
    -    // CHECK: switchInt(move _1) -> [17: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
    +    // CHECK: switchInt(copy _1) -> [17: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
         // CHECK: [[BB1]]:
         // CHECK: [[cast_1:_.*]] = copy [[b]] as i32 (IntToInt);
         // CHECK: _0 = Add(const 100_i32, move [[cast_1]]);
    diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir
    index b5c23822162c..f3c83f62edf6 100644
    --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir
    +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir
    @@ -28,7 +28,7 @@ fn num_to_digit(_1: char) -> u32 {
             StorageLive(_3);
             _3 = discriminant(_2);
             StorageDead(_2);
    -        switchInt(move _3) -> [1: bb2, otherwise: bb7];
    +        switchInt(copy _3) -> [1: bb2, otherwise: bb7];
         }
     
         bb2: {
    diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir
    index f22b8835735d..0e55df24cc57 100644
    --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir
    +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir
    @@ -28,7 +28,7 @@ fn num_to_digit(_1: char) -> u32 {
             StorageLive(_3);
             _3 = discriminant(_2);
             StorageDead(_2);
    -        switchInt(move _3) -> [1: bb2, otherwise: bb7];
    +        switchInt(copy _3) -> [1: bb2, otherwise: bb7];
         }
     
         bb2: {
    diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir
    index b5c23822162c..f3c83f62edf6 100644
    --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir
    +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir
    @@ -28,7 +28,7 @@ fn num_to_digit(_1: char) -> u32 {
             StorageLive(_3);
             _3 = discriminant(_2);
             StorageDead(_2);
    -        switchInt(move _3) -> [1: bb2, otherwise: bb7];
    +        switchInt(copy _3) -> [1: bb2, otherwise: bb7];
         }
     
         bb2: {
    diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir
    index f22b8835735d..0e55df24cc57 100644
    --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir
    +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir
    @@ -28,7 +28,7 @@ fn num_to_digit(_1: char) -> u32 {
             StorageLive(_3);
             _3 = discriminant(_2);
             StorageDead(_2);
    -        switchInt(move _3) -> [1: bb2, otherwise: bb7];
    +        switchInt(copy _3) -> [1: bb2, otherwise: bb7];
         }
     
         bb2: {
    
    From 3b1756fbf56fcfede8ac2c1d877ddd1e8a88be8c Mon Sep 17 00:00:00 2001
    From: dianqk 
    Date: Sun, 11 Jan 2026 18:10:05 +0800
    Subject: [PATCH 1990/3801] Run SimplifyComparisonIntegral with opt-level 2
    
    ---
     .../rustc_mir_transform/src/simplify_comparison_integral.rs     | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
    index b7445a0f7c2e..58b5e45672a2 100644
    --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
    +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
    @@ -29,7 +29,7 @@ pub(super) struct SimplifyComparisonIntegral;
     
     impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
         fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
    -        sess.mir_opt_level() > 0
    +        sess.mir_opt_level() > 1
         }
     
         fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
    
    From 756e1bac6e1939dcd80125934fc6409846f02dac Mon Sep 17 00:00:00 2001
    From: Jason Newcomb 
    Date: Sat, 11 Oct 2025 23:48:20 -0400
    Subject: [PATCH 1991/3801] `clippy_dev`: Move lint uplifting into its own
     command.
    
    ---
     clippy_dev/src/deprecate_lint.rs | 54 ++++++++++++++++++++++++++++-
     clippy_dev/src/main.rs           | 36 +++++++++-----------
     clippy_dev/src/rename_lint.rs    | 58 +++++---------------------------
     3 files changed, 78 insertions(+), 70 deletions(-)
    
    diff --git a/clippy_dev/src/deprecate_lint.rs b/clippy_dev/src/deprecate_lint.rs
    index 0401cfda7080..bee7508dabb9 100644
    --- a/clippy_dev/src/deprecate_lint.rs
    +++ b/clippy_dev/src/deprecate_lint.rs
    @@ -1,4 +1,4 @@
    -use crate::parse::{DeprecatedLint, Lint, ParseCx};
    +use crate::parse::{DeprecatedLint, Lint, ParseCx, RenamedLint};
     use crate::update_lints::generate_lint_files;
     use crate::utils::{UpdateMode, Version};
     use std::ffi::OsStr;
    @@ -61,6 +61,58 @@ pub fn deprecate<'cx>(cx: ParseCx<'cx>, clippy_version: Version, name: &'cx str,
         }
     }
     
    +pub fn uplift<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'env str, new_name: &'env str) {
    +    let mut lints = cx.find_lint_decls();
    +    let (deprecated_lints, mut renamed_lints) = cx.read_deprecated_lints();
    +
    +    let Some(lint) = lints.iter().find(|l| l.name == old_name) else {
    +        eprintln!("error: failed to find lint `{old_name}`");
    +        return;
    +    };
    +
    +    let old_name_prefixed = cx.str_buf.with(|buf| {
    +        buf.extend(["clippy::", old_name]);
    +        cx.arena.alloc_str(buf)
    +    });
    +    for lint in &mut renamed_lints {
    +        if lint.new_name == old_name_prefixed {
    +            lint.new_name = new_name;
    +        }
    +    }
    +    match renamed_lints.binary_search_by(|x| x.old_name.cmp(old_name_prefixed)) {
    +        Ok(_) => {
    +            println!("`{old_name}` is already deprecated");
    +            return;
    +        },
    +        Err(idx) => renamed_lints.insert(
    +            idx,
    +            RenamedLint {
    +                old_name: old_name_prefixed,
    +                new_name,
    +                version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
    +            },
    +        ),
    +    }
    +
    +    let mod_path = {
    +        let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
    +        if mod_path.is_dir() {
    +            mod_path = mod_path.join("mod");
    +        }
    +
    +        mod_path.set_extension("rs");
    +        mod_path
    +    };
    +
    +    if remove_lint_declaration(old_name, &mod_path, &mut lints).unwrap_or(false) {
    +        generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
    +        println!("info: `{old_name}` has successfully been uplifted");
    +        println!("note: you must run `cargo uitest` to update the test results");
    +    } else {
    +        eprintln!("error: lint not found");
    +    }
    +}
    +
     fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec>) -> io::Result {
         fn remove_lint(name: &str, lints: &mut Vec>) {
             lints.iter().position(|l| l.name == name).map(|pos| lints.remove(pos));
    diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs
    index 392c3aabf193..9571dfde1877 100644
    --- a/clippy_dev/src/main.rs
    +++ b/clippy_dev/src/main.rs
    @@ -74,18 +74,11 @@ fn main() {
             },
             DevCommand::Serve { port, lint } => serve::run(port, lint),
             DevCommand::Lint { path, edition, args } => lint::run(&path, &edition, args.iter()),
    -        DevCommand::RenameLint {
    -            old_name,
    -            new_name,
    -            uplift,
    -        } => new_parse_cx(|cx| {
    -            rename_lint::rename(
    -                cx,
    -                clippy.version,
    -                &old_name,
    -                new_name.as_ref().unwrap_or(&old_name),
    -                uplift,
    -            );
    +        DevCommand::RenameLint { old_name, new_name } => new_parse_cx(|cx| {
    +            rename_lint::rename(cx, clippy.version, &old_name, &new_name);
    +        }),
    +        DevCommand::Uplift { old_name, new_name } => new_parse_cx(|cx| {
    +            deprecate_lint::uplift(cx, clippy.version, &old_name, new_name.as_deref().unwrap_or(&old_name));
             }),
             DevCommand::Deprecate { name, reason } => {
                 new_parse_cx(|cx| deprecate_lint::deprecate(cx, clippy.version, &name, &reason));
    @@ -243,15 +236,9 @@ enum DevCommand {
             /// The name of the lint to rename
             #[arg(value_parser = lint_name)]
             old_name: String,
    -        #[arg(
    -            required_unless_present = "uplift",
    -            value_parser = lint_name,
    -        )]
    +        #[arg(value_parser = lint_name)]
             /// The new name of the lint
    -        new_name: Option,
    -        #[arg(long)]
    -        /// This lint will be uplifted into rustc
    -        uplift: bool,
    +        new_name: String,
         },
         /// Deprecate the given lint
         Deprecate {
    @@ -266,6 +253,15 @@ enum DevCommand {
         Sync(SyncCommand),
         /// Manage Clippy releases
         Release(ReleaseCommand),
    +    /// Marks a lint as uplifted into rustc and removes its code
    +    Uplift {
    +        /// The name of the lint to uplift
    +        #[arg(value_parser = lint_name)]
    +        old_name: String,
    +        /// The name of the lint in rustc
    +        #[arg(value_parser = lint_name)]
    +        new_name: Option,
    +    },
     }
     
     #[derive(Args)]
    diff --git a/clippy_dev/src/rename_lint.rs b/clippy_dev/src/rename_lint.rs
    index 8e30eb7ce95b..9be4f2bdc970 100644
    --- a/clippy_dev/src/rename_lint.rs
    +++ b/clippy_dev/src/rename_lint.rs
    @@ -25,8 +25,7 @@ use std::path::Path;
     /// * If either lint name has a prefix
     /// * If `old_name` doesn't name an existing lint.
     /// * If `old_name` names a deprecated or renamed lint.
    -#[expect(clippy::too_many_lines)]
    -pub fn rename<'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'cx str, new_name: &'cx str, uplift: bool) {
    +pub fn rename<'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'cx str, new_name: &'cx str) {
         let mut updater = FileUpdater::default();
         let mut lints = cx.find_lint_decls();
         let (deprecated_lints, mut renamed_lints) = cx.read_deprecated_lints();
    @@ -34,20 +33,15 @@ pub fn rename<'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'cx str
         let Ok(lint_idx) = lints.binary_search_by(|x| x.name.cmp(old_name)) else {
             panic!("could not find lint `{old_name}`");
         };
    -    let lint = &lints[lint_idx];
     
         let old_name_prefixed = cx.str_buf.with(|buf| {
             buf.extend(["clippy::", old_name]);
             cx.arena.alloc_str(buf)
         });
    -    let new_name_prefixed = if uplift {
    -        new_name
    -    } else {
    -        cx.str_buf.with(|buf| {
    -            buf.extend(["clippy::", new_name]);
    -            cx.arena.alloc_str(buf)
    -        })
    -    };
    +    let new_name_prefixed = cx.str_buf.with(|buf| {
    +        buf.extend(["clippy::", new_name]);
    +        cx.arena.alloc_str(buf)
    +    });
     
         for lint in &mut renamed_lints {
             if lint.new_name == old_name_prefixed {
    @@ -77,31 +71,7 @@ pub fn rename<'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'cx str
         let change_prefixed_tests = lints.get(lint_idx + 1).is_none_or(|l| !l.name.starts_with(old_name));
     
         let mut mod_edit = ModEdit::None;
    -    if uplift {
    -        let is_unique_mod = lints[..lint_idx].iter().any(|l| l.module == lint.module)
    -            || lints[lint_idx + 1..].iter().any(|l| l.module == lint.module);
    -        if is_unique_mod {
    -            if delete_file_if_exists(lint.path.as_ref()) {
    -                mod_edit = ModEdit::Delete;
    -            }
    -        } else {
    -            updater.update_file(&lint.path, &mut |_, src, dst| -> UpdateStatus {
    -                let mut start = &src[..lint.declaration_range.start];
    -                if start.ends_with("\n\n") {
    -                    start = &start[..start.len() - 1];
    -                }
    -                let mut end = &src[lint.declaration_range.end..];
    -                if end.starts_with("\n\n") {
    -                    end = &end[1..];
    -                }
    -                dst.push_str(start);
    -                dst.push_str(end);
    -                UpdateStatus::Changed
    -            });
    -        }
    -        delete_test_files(old_name, change_prefixed_tests);
    -        lints.remove(lint_idx);
    -    } else if lints.binary_search_by(|x| x.name.cmp(new_name)).is_err() {
    +    if lints.binary_search_by(|x| x.name.cmp(new_name)).is_err() {
             let lint = &mut lints[lint_idx];
             if lint.module.ends_with(old_name)
                 && lint
    @@ -139,19 +109,9 @@ pub fn rename<'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'cx str
         }
         generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
     
    -    if uplift {
    -        println!("Uplifted `clippy::{old_name}` as `{new_name}`");
    -        if matches!(mod_edit, ModEdit::None) {
    -            println!("Only the rename has been registered, the code will need to be edited manually");
    -        } else {
    -            println!("All the lint's code has been deleted");
    -            println!("Make sure to inspect the results as some things may have been missed");
    -        }
    -    } else {
    -        println!("Renamed `clippy::{old_name}` to `clippy::{new_name}`");
    -        println!("All code referencing the old name has been updated");
    -        println!("Make sure to inspect the results as some things may have been missed");
    -    }
    +    println!("Renamed `clippy::{old_name}` to `clippy::{new_name}`");
    +    println!("All code referencing the old name has been updated");
    +    println!("Make sure to inspect the results as some things may have been missed");
         println!("note: `cargo uibless` still needs to be run to update the test results");
     }
     
    
    From d9fa6d95151ff267094da06781ef655dd0f693dd Mon Sep 17 00:00:00 2001
    From: Jason Newcomb 
    Date: Sun, 12 Oct 2025 14:43:21 -0400
    Subject: [PATCH 1992/3801] `clippy_dev`: Rename `deprecate_lint` module to
     `edit_lints`.
    
    ---
     clippy_dev/src/edit_lints.rs | 213 +++++++++++++++++++++++++++++++++++
     clippy_dev/src/lib.rs        |   2 +-
     clippy_dev/src/main.rs       |   8 +-
     3 files changed, 218 insertions(+), 5 deletions(-)
     create mode 100644 clippy_dev/src/edit_lints.rs
    
    diff --git a/clippy_dev/src/edit_lints.rs b/clippy_dev/src/edit_lints.rs
    new file mode 100644
    index 000000000000..573bd1e44535
    --- /dev/null
    +++ b/clippy_dev/src/edit_lints.rs
    @@ -0,0 +1,213 @@
    +use crate::parse::{DeprecatedLint, Lint, ParseCx, RenamedLint};
    +use crate::update_lints::generate_lint_files;
    +use crate::utils::{UpdateMode, Version};
    +use std::ffi::OsStr;
    +use std::path::{Path, PathBuf};
    +use std::{fs, io};
    +
    +/// Runs the `deprecate` command
    +///
    +/// This does the following:
    +/// * Adds an entry to `deprecated_lints.rs`.
    +/// * Removes the lint declaration (and the entire file if applicable)
    +///
    +/// # Panics
    +///
    +/// If a file path could not read from or written to
    +pub fn deprecate<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, name: &'env str, reason: &'env str) {
    +    let mut lints = cx.find_lint_decls();
    +    let (mut deprecated_lints, renamed_lints) = cx.read_deprecated_lints();
    +
    +    let Some(lint) = lints.iter().find(|l| l.name == name) else {
    +        eprintln!("error: failed to find lint `{name}`");
    +        return;
    +    };
    +
    +    let prefixed_name = cx.str_buf.with(|buf| {
    +        buf.extend(["clippy::", name]);
    +        cx.arena.alloc_str(buf)
    +    });
    +    match deprecated_lints.binary_search_by(|x| x.name.cmp(prefixed_name)) {
    +        Ok(_) => {
    +            println!("`{name}` is already deprecated");
    +            return;
    +        },
    +        Err(idx) => deprecated_lints.insert(
    +            idx,
    +            DeprecatedLint {
    +                name: prefixed_name,
    +                reason,
    +                version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
    +            },
    +        ),
    +    }
    +
    +    let mod_path = {
    +        let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
    +        if mod_path.is_dir() {
    +            mod_path = mod_path.join("mod");
    +        }
    +
    +        mod_path.set_extension("rs");
    +        mod_path
    +    };
    +
    +    if remove_lint_declaration(name, &mod_path, &mut lints).unwrap_or(false) {
    +        generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
    +        println!("info: `{name}` has successfully been deprecated");
    +        println!("note: you must run `cargo uitest` to update the test results");
    +    } else {
    +        eprintln!("error: lint not found");
    +    }
    +}
    +
    +pub fn uplift<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'env str, new_name: &'env str) {
    +    let mut lints = cx.find_lint_decls();
    +    let (deprecated_lints, mut renamed_lints) = cx.read_deprecated_lints();
    +
    +    let Some(lint) = lints.iter().find(|l| l.name == old_name) else {
    +        eprintln!("error: failed to find lint `{old_name}`");
    +        return;
    +    };
    +
    +    let old_name_prefixed = cx.str_buf.with(|buf| {
    +        buf.extend(["clippy::", old_name]);
    +        cx.arena.alloc_str(buf)
    +    });
    +    for lint in &mut renamed_lints {
    +        if lint.new_name == old_name_prefixed {
    +            lint.new_name = new_name;
    +        }
    +    }
    +    match renamed_lints.binary_search_by(|x| x.old_name.cmp(old_name_prefixed)) {
    +        Ok(_) => {
    +            println!("`{old_name}` is already deprecated");
    +            return;
    +        },
    +        Err(idx) => renamed_lints.insert(
    +            idx,
    +            RenamedLint {
    +                old_name: old_name_prefixed,
    +                new_name,
    +                version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
    +            },
    +        ),
    +    }
    +
    +    let mod_path = {
    +        let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
    +        if mod_path.is_dir() {
    +            mod_path = mod_path.join("mod");
    +        }
    +
    +        mod_path.set_extension("rs");
    +        mod_path
    +    };
    +
    +    if remove_lint_declaration(old_name, &mod_path, &mut lints).unwrap_or(false) {
    +        generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
    +        println!("info: `{old_name}` has successfully been uplifted");
    +        println!("note: you must run `cargo uitest` to update the test results");
    +    } else {
    +        eprintln!("error: lint not found");
    +    }
    +}
    +
    +fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec>) -> io::Result {
    +    fn remove_lint(name: &str, lints: &mut Vec>) {
    +        lints.iter().position(|l| l.name == name).map(|pos| lints.remove(pos));
    +    }
    +
    +    fn remove_test_assets(name: &str) {
    +        let test_file_stem = format!("tests/ui/{name}");
    +        let path = Path::new(&test_file_stem);
    +
    +        // Some lints have their own directories, delete them
    +        if path.is_dir() {
    +            let _ = fs::remove_dir_all(path);
    +            return;
    +        }
    +
    +        // Remove all related test files
    +        let _ = fs::remove_file(path.with_extension("rs"));
    +        let _ = fs::remove_file(path.with_extension("stderr"));
    +        let _ = fs::remove_file(path.with_extension("fixed"));
    +    }
    +
    +    fn remove_impl_lint_pass(lint_name_upper: &str, content: &mut String) {
    +        let impl_lint_pass_start = content.find("impl_lint_pass!").unwrap_or_else(|| {
    +            content
    +                .find("declare_lint_pass!")
    +                .unwrap_or_else(|| panic!("failed to find `impl_lint_pass`"))
    +        });
    +        let mut impl_lint_pass_end = content[impl_lint_pass_start..]
    +            .find(']')
    +            .expect("failed to find `impl_lint_pass` terminator");
    +
    +        impl_lint_pass_end += impl_lint_pass_start;
    +        if let Some(lint_name_pos) = content[impl_lint_pass_start..impl_lint_pass_end].find(lint_name_upper) {
    +            let mut lint_name_end = impl_lint_pass_start + (lint_name_pos + lint_name_upper.len());
    +            for c in content[lint_name_end..impl_lint_pass_end].chars() {
    +                // Remove trailing whitespace
    +                if c == ',' || c.is_whitespace() {
    +                    lint_name_end += 1;
    +                } else {
    +                    break;
    +                }
    +            }
    +
    +            content.replace_range(impl_lint_pass_start + lint_name_pos..lint_name_end, "");
    +        }
    +    }
    +
    +    if path.exists()
    +        && let Some(lint) = lints.iter().find(|l| l.name == name)
    +    {
    +        if lint.module == name {
    +            // The lint name is the same as the file, we can just delete the entire file
    +            fs::remove_file(path)?;
    +        } else {
    +            // We can't delete the entire file, just remove the declaration
    +
    +            if let Some(Some("mod.rs")) = path.file_name().map(OsStr::to_str) {
    +                // Remove clippy_lints/src/some_mod/some_lint.rs
    +                let mut lint_mod_path = path.to_path_buf();
    +                lint_mod_path.set_file_name(name);
    +                lint_mod_path.set_extension("rs");
    +
    +                let _ = fs::remove_file(lint_mod_path);
    +            }
    +
    +            let mut content =
    +                fs::read_to_string(path).unwrap_or_else(|_| panic!("failed to read `{}`", path.to_string_lossy()));
    +
    +            eprintln!(
    +                "warn: you will have to manually remove any code related to `{name}` from `{}`",
    +                path.display()
    +            );
    +
    +            assert!(
    +                content[lint.declaration_range].contains(&name.to_uppercase()),
    +                "error: `{}` does not contain lint `{}`'s declaration",
    +                path.display(),
    +                lint.name
    +            );
    +
    +            // Remove lint declaration (declare_clippy_lint!)
    +            content.replace_range(lint.declaration_range, "");
    +
    +            // Remove the module declaration (mod xyz;)
    +            let mod_decl = format!("\nmod {name};");
    +            content = content.replacen(&mod_decl, "", 1);
    +
    +            remove_impl_lint_pass(&lint.name.to_uppercase(), &mut content);
    +            fs::write(path, content).unwrap_or_else(|_| panic!("failed to write to `{}`", path.to_string_lossy()));
    +        }
    +
    +        remove_test_assets(name);
    +        remove_lint(name, lints);
    +        return Ok(true);
    +    }
    +
    +    Ok(false)
    +}
    diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
    index cd103908be03..db9b230f6e59 100644
    --- a/clippy_dev/src/lib.rs
    +++ b/clippy_dev/src/lib.rs
    @@ -23,8 +23,8 @@ extern crate rustc_arena;
     extern crate rustc_driver;
     extern crate rustc_lexer;
     
    -pub mod deprecate_lint;
     pub mod dogfood;
    +pub mod edit_lints;
     pub mod fmt;
     pub mod lint;
     pub mod new_lint;
    diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs
    index 9571dfde1877..e4e19a100c6e 100644
    --- a/clippy_dev/src/main.rs
    +++ b/clippy_dev/src/main.rs
    @@ -4,8 +4,8 @@
     
     use clap::{Args, Parser, Subcommand};
     use clippy_dev::{
    -    ClippyInfo, UpdateMode, deprecate_lint, dogfood, fmt, lint, new_lint, new_parse_cx, release, rename_lint, serve,
    -    setup, sync, update_lints,
    +    ClippyInfo, UpdateMode, dogfood, edit_lints, fmt, lint, new_lint, new_parse_cx, release, rename_lint, serve, setup,
    +    sync, update_lints,
     };
     use std::env;
     
    @@ -78,10 +78,10 @@ fn main() {
                 rename_lint::rename(cx, clippy.version, &old_name, &new_name);
             }),
             DevCommand::Uplift { old_name, new_name } => new_parse_cx(|cx| {
    -            deprecate_lint::uplift(cx, clippy.version, &old_name, new_name.as_deref().unwrap_or(&old_name));
    +            edit_lints::uplift(cx, clippy.version, &old_name, new_name.as_deref().unwrap_or(&old_name));
             }),
             DevCommand::Deprecate { name, reason } => {
    -            new_parse_cx(|cx| deprecate_lint::deprecate(cx, clippy.version, &name, &reason));
    +            new_parse_cx(|cx| edit_lints::deprecate(cx, clippy.version, &name, &reason));
             },
             DevCommand::Sync(SyncCommand { subcommand }) => match subcommand {
                 SyncSubcommand::UpdateNightly => sync::update_nightly(),
    
    From 8d4e435f492a54c14c8620ef665cdec4710abd19 Mon Sep 17 00:00:00 2001
    From: Jason Newcomb 
    Date: Sun, 12 Oct 2025 14:44:25 -0400
    Subject: [PATCH 1993/3801] `clippy_dev`: Move `rename_lint` command to
     `edit_lints` module.
    
    ---
     clippy_dev/src/edit_lints.rs  | 351 ++++++++++++++++++++++++++++++++-
     clippy_dev/src/lib.rs         |   1 -
     clippy_dev/src/main.rs        |   6 +-
     clippy_dev/src/rename_lint.rs | 353 ----------------------------------
     4 files changed, 352 insertions(+), 359 deletions(-)
     delete mode 100644 clippy_dev/src/rename_lint.rs
    
    diff --git a/clippy_dev/src/edit_lints.rs b/clippy_dev/src/edit_lints.rs
    index 573bd1e44535..8a5ba26fd215 100644
    --- a/clippy_dev/src/edit_lints.rs
    +++ b/clippy_dev/src/edit_lints.rs
    @@ -1,7 +1,12 @@
    +use crate::parse::cursor::{self, Capture, Cursor};
     use crate::parse::{DeprecatedLint, Lint, ParseCx, RenamedLint};
     use crate::update_lints::generate_lint_files;
    -use crate::utils::{UpdateMode, Version};
    -use std::ffi::OsStr;
    +use crate::utils::{
    +    ErrAction, FileUpdater, UpdateMode, UpdateStatus, Version, delete_dir_if_exists, delete_file_if_exists,
    +    expect_action, try_rename_dir, try_rename_file, walk_dir_no_dot_or_target,
    +};
    +use rustc_lexer::TokenKind;
    +use std::ffi::{OsStr, OsString};
     use std::path::{Path, PathBuf};
     use std::{fs, io};
     
    @@ -113,6 +118,111 @@ pub fn uplift<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
         }
     }
     
    +/// Runs the `rename_lint` command.
    +///
    +/// This does the following:
    +/// * Adds an entry to `renamed_lints.rs`.
    +/// * Renames all lint attributes to the new name (e.g. `#[allow(clippy::lint_name)]`).
    +/// * Renames the lint struct to the new name.
    +/// * Renames the module containing the lint struct to the new name if it shares a name with the
    +///   lint.
    +///
    +/// # Panics
    +/// Panics for the following conditions:
    +/// * If a file path could not read from or then written to
    +/// * If either lint name has a prefix
    +/// * If `old_name` doesn't name an existing lint.
    +/// * If `old_name` names a deprecated or renamed lint.
    +pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'env str, new_name: &'env str) {
    +    let mut updater = FileUpdater::default();
    +    let mut lints = cx.find_lint_decls();
    +    let (deprecated_lints, mut renamed_lints) = cx.read_deprecated_lints();
    +
    +    let Ok(lint_idx) = lints.binary_search_by(|x| x.name.cmp(old_name)) else {
    +        panic!("could not find lint `{old_name}`");
    +    };
    +
    +    let old_name_prefixed = cx.str_buf.with(|buf| {
    +        buf.extend(["clippy::", old_name]);
    +        cx.arena.alloc_str(buf)
    +    });
    +    let new_name_prefixed = cx.str_buf.with(|buf| {
    +        buf.extend(["clippy::", new_name]);
    +        cx.arena.alloc_str(buf)
    +    });
    +
    +    for lint in &mut renamed_lints {
    +        if lint.new_name == old_name_prefixed {
    +            lint.new_name = new_name_prefixed;
    +        }
    +    }
    +    match renamed_lints.binary_search_by(|x| x.old_name.cmp(old_name_prefixed)) {
    +        Ok(_) => {
    +            println!("`{old_name}` already has a rename registered");
    +            return;
    +        },
    +        Err(idx) => {
    +            renamed_lints.insert(
    +                idx,
    +                RenamedLint {
    +                    old_name: old_name_prefixed,
    +                    new_name: new_name_prefixed,
    +                    version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
    +                },
    +            );
    +        },
    +    }
    +
    +    // Some tests are named `lint_name_suffix` which should also be renamed,
    +    // but we can't do that if the renamed lint's name overlaps with another
    +    // lint. e.g. renaming 'foo' to 'bar' when a lint 'foo_bar' also exists.
    +    let change_prefixed_tests = lints.get(lint_idx + 1).is_none_or(|l| !l.name.starts_with(old_name));
    +
    +    let mut mod_edit = ModEdit::None;
    +    if lints.binary_search_by(|x| x.name.cmp(new_name)).is_err() {
    +        let lint = &mut lints[lint_idx];
    +        if lint.module.ends_with(old_name)
    +            && lint
    +                .path
    +                .file_stem()
    +                .is_some_and(|x| x.as_encoded_bytes() == old_name.as_bytes())
    +        {
    +            let mut new_path = lint.path.with_file_name(new_name).into_os_string();
    +            new_path.push(".rs");
    +            if try_rename_file(lint.path.as_ref(), new_path.as_ref()) {
    +                mod_edit = ModEdit::Rename;
    +            }
    +
    +            lint.module = cx.str_buf.with(|buf| {
    +                buf.push_str(&lint.module[..lint.module.len() - old_name.len()]);
    +                buf.push_str(new_name);
    +                cx.arena.alloc_str(buf)
    +            });
    +        }
    +        rename_test_files(old_name, new_name, change_prefixed_tests);
    +        lints[lint_idx].name = new_name;
    +        lints.sort_by(|lhs, rhs| lhs.name.cmp(rhs.name));
    +    } else {
    +        println!("Renamed `clippy::{old_name}` to `clippy::{new_name}`");
    +        println!("Since `{new_name}` already exists the existing code has not been changed");
    +        return;
    +    }
    +
    +    let mut update_fn = file_update_fn(old_name, new_name, mod_edit);
    +    for e in walk_dir_no_dot_or_target(".") {
    +        let e = expect_action(e, ErrAction::Read, ".");
    +        if e.path().as_os_str().as_encoded_bytes().ends_with(b".rs") {
    +            updater.update_file(e.path(), &mut update_fn);
    +        }
    +    }
    +    generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
    +
    +    println!("Renamed `clippy::{old_name}` to `clippy::{new_name}`");
    +    println!("All code referencing the old name has been updated");
    +    println!("Make sure to inspect the results as some things may have been missed");
    +    println!("note: `cargo uibless` still needs to be run to update the test results");
    +}
    +
     fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec>) -> io::Result {
         fn remove_lint(name: &str, lints: &mut Vec>) {
             lints.iter().position(|l| l.name == name).map(|pos| lints.remove(pos));
    @@ -211,3 +321,240 @@ fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec>) -
     
         Ok(false)
     }
    +
    +#[derive(Clone, Copy)]
    +enum ModEdit {
    +    None,
    +    Delete,
    +    Rename,
    +}
    +
    +fn collect_ui_test_names(lint: &str, rename_prefixed: bool, dst: &mut Vec<(OsString, bool)>) {
    +    for e in fs::read_dir("tests/ui").expect("error reading `tests/ui`") {
    +        let e = e.expect("error reading `tests/ui`");
    +        let name = e.file_name();
    +        if let Some((name_only, _)) = name.as_encoded_bytes().split_once(|&x| x == b'.') {
    +            if name_only.starts_with(lint.as_bytes()) && (rename_prefixed || name_only.len() == lint.len()) {
    +                dst.push((name, true));
    +            }
    +        } else if name.as_encoded_bytes().starts_with(lint.as_bytes()) && (rename_prefixed || name.len() == lint.len())
    +        {
    +            dst.push((name, false));
    +        }
    +    }
    +}
    +
    +fn collect_ui_toml_test_names(lint: &str, rename_prefixed: bool, dst: &mut Vec<(OsString, bool)>) {
    +    if rename_prefixed {
    +        for e in fs::read_dir("tests/ui-toml").expect("error reading `tests/ui-toml`") {
    +            let e = e.expect("error reading `tests/ui-toml`");
    +            let name = e.file_name();
    +            if name.as_encoded_bytes().starts_with(lint.as_bytes()) && e.file_type().is_ok_and(|ty| ty.is_dir()) {
    +                dst.push((name, false));
    +            }
    +        }
    +    } else {
    +        dst.push((lint.into(), false));
    +    }
    +}
    +
    +/// Renames all test files for the given lint.
    +///
    +/// If `rename_prefixed` is `true` this will also rename tests which have the lint name as a prefix.
    +fn rename_test_files(old_name: &str, new_name: &str, rename_prefixed: bool) {
    +    let mut tests = Vec::new();
    +
    +    let mut old_buf = OsString::from("tests/ui/");
    +    let mut new_buf = OsString::from("tests/ui/");
    +    collect_ui_test_names(old_name, rename_prefixed, &mut tests);
    +    for &(ref name, is_file) in &tests {
    +        old_buf.push(name);
    +        new_buf.extend([new_name.as_ref(), name.slice_encoded_bytes(old_name.len()..)]);
    +        if is_file {
    +            try_rename_file(old_buf.as_ref(), new_buf.as_ref());
    +        } else {
    +            try_rename_dir(old_buf.as_ref(), new_buf.as_ref());
    +        }
    +        old_buf.truncate("tests/ui/".len());
    +        new_buf.truncate("tests/ui/".len());
    +    }
    +
    +    tests.clear();
    +    old_buf.truncate("tests/ui".len());
    +    new_buf.truncate("tests/ui".len());
    +    old_buf.push("-toml/");
    +    new_buf.push("-toml/");
    +    collect_ui_toml_test_names(old_name, rename_prefixed, &mut tests);
    +    for (name, _) in &tests {
    +        old_buf.push(name);
    +        new_buf.extend([new_name.as_ref(), name.slice_encoded_bytes(old_name.len()..)]);
    +        try_rename_dir(old_buf.as_ref(), new_buf.as_ref());
    +        old_buf.truncate("tests/ui/".len());
    +        new_buf.truncate("tests/ui/".len());
    +    }
    +}
    +
    +fn delete_test_files(lint: &str, rename_prefixed: bool) {
    +    let mut tests = Vec::new();
    +
    +    let mut buf = OsString::from("tests/ui/");
    +    collect_ui_test_names(lint, rename_prefixed, &mut tests);
    +    for &(ref name, is_file) in &tests {
    +        buf.push(name);
    +        if is_file {
    +            delete_file_if_exists(buf.as_ref());
    +        } else {
    +            delete_dir_if_exists(buf.as_ref());
    +        }
    +        buf.truncate("tests/ui/".len());
    +    }
    +
    +    buf.truncate("tests/ui".len());
    +    buf.push("-toml/");
    +
    +    tests.clear();
    +    collect_ui_toml_test_names(lint, rename_prefixed, &mut tests);
    +    for (name, _) in &tests {
    +        buf.push(name);
    +        delete_dir_if_exists(buf.as_ref());
    +        buf.truncate("tests/ui/".len());
    +    }
    +}
    +
    +fn snake_to_pascal(s: &str) -> String {
    +    let mut dst = Vec::with_capacity(s.len());
    +    let mut iter = s.bytes();
    +    || -> Option<()> {
    +        dst.push(iter.next()?.to_ascii_uppercase());
    +        while let Some(c) = iter.next() {
    +            if c == b'_' {
    +                dst.push(iter.next()?.to_ascii_uppercase());
    +            } else {
    +                dst.push(c);
    +            }
    +        }
    +        Some(())
    +    }();
    +    String::from_utf8(dst).unwrap()
    +}
    +
    +#[expect(clippy::too_many_lines)]
    +fn file_update_fn<'a, 'b>(
    +    old_name: &'a str,
    +    new_name: &'b str,
    +    mod_edit: ModEdit,
    +) -> impl use<'a, 'b> + FnMut(&Path, &str, &mut String) -> UpdateStatus {
    +    let old_name_pascal = snake_to_pascal(old_name);
    +    let new_name_pascal = snake_to_pascal(new_name);
    +    let old_name_upper = old_name.to_ascii_uppercase();
    +    let new_name_upper = new_name.to_ascii_uppercase();
    +    move |_, src, dst| {
    +        let mut copy_pos = 0u32;
    +        let mut changed = false;
    +        let mut cursor = Cursor::new(src);
    +        let mut captures = [Capture::EMPTY];
    +        loop {
    +            match cursor.peek() {
    +                TokenKind::Eof => break,
    +                TokenKind::Ident => {
    +                    let match_start = cursor.pos();
    +                    let text = cursor.peek_text();
    +                    cursor.step();
    +                    match text {
    +                        // clippy::line_name or clippy::lint-name
    +                        "clippy" => {
    +                            if cursor.match_all(&[cursor::Pat::DoubleColon, cursor::Pat::CaptureIdent], &mut captures)
    +                                && cursor.get_text(captures[0]) == old_name
    +                            {
    +                                dst.push_str(&src[copy_pos as usize..captures[0].pos as usize]);
    +                                dst.push_str(new_name);
    +                                copy_pos = cursor.pos();
    +                                changed = true;
    +                            }
    +                        },
    +                        // mod lint_name
    +                        "mod" => {
    +                            if !matches!(mod_edit, ModEdit::None)
    +                                && let Some(pos) = cursor.find_ident(old_name)
    +                            {
    +                                match mod_edit {
    +                                    ModEdit::Rename => {
    +                                        dst.push_str(&src[copy_pos as usize..pos as usize]);
    +                                        dst.push_str(new_name);
    +                                        copy_pos = cursor.pos();
    +                                        changed = true;
    +                                    },
    +                                    ModEdit::Delete if cursor.match_pat(cursor::Pat::Semi) => {
    +                                        let mut start = &src[copy_pos as usize..match_start as usize];
    +                                        if start.ends_with("\n\n") {
    +                                            start = &start[..start.len() - 1];
    +                                        }
    +                                        dst.push_str(start);
    +                                        copy_pos = cursor.pos();
    +                                        if src[copy_pos as usize..].starts_with("\n\n") {
    +                                            copy_pos += 1;
    +                                        }
    +                                        changed = true;
    +                                    },
    +                                    ModEdit::Delete | ModEdit::None => {},
    +                                }
    +                            }
    +                        },
    +                        // lint_name::
    +                        name if matches!(mod_edit, ModEdit::Rename) && name == old_name => {
    +                            let name_end = cursor.pos();
    +                            if cursor.match_pat(cursor::Pat::DoubleColon) {
    +                                dst.push_str(&src[copy_pos as usize..match_start as usize]);
    +                                dst.push_str(new_name);
    +                                copy_pos = name_end;
    +                                changed = true;
    +                            }
    +                        },
    +                        // LINT_NAME or LintName
    +                        name => {
    +                            let replacement = if name == old_name_upper {
    +                                &new_name_upper
    +                            } else if name == old_name_pascal {
    +                                &new_name_pascal
    +                            } else {
    +                                continue;
    +                            };
    +                            dst.push_str(&src[copy_pos as usize..match_start as usize]);
    +                            dst.push_str(replacement);
    +                            copy_pos = cursor.pos();
    +                            changed = true;
    +                        },
    +                    }
    +                },
    +                // //~ lint_name
    +                TokenKind::LineComment { doc_style: None } => {
    +                    let text = cursor.peek_text();
    +                    if text.starts_with("//~")
    +                        && let Some(text) = text.strip_suffix(old_name)
    +                        && !text.ends_with(|c| matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9' | '_'))
    +                    {
    +                        dst.push_str(&src[copy_pos as usize..cursor.pos() as usize + text.len()]);
    +                        dst.push_str(new_name);
    +                        copy_pos = cursor.pos() + cursor.peek_len();
    +                        changed = true;
    +                    }
    +                    cursor.step();
    +                },
    +                // ::lint_name
    +                TokenKind::Colon
    +                    if cursor.match_all(&[cursor::Pat::DoubleColon, cursor::Pat::CaptureIdent], &mut captures)
    +                        && cursor.get_text(captures[0]) == old_name =>
    +                {
    +                    dst.push_str(&src[copy_pos as usize..captures[0].pos as usize]);
    +                    dst.push_str(new_name);
    +                    copy_pos = cursor.pos();
    +                    changed = true;
    +                },
    +                _ => cursor.step(),
    +            }
    +        }
    +
    +        dst.push_str(&src[copy_pos as usize..]);
    +        UpdateStatus::from_changed(changed)
    +    }
    +}
    diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
    index db9b230f6e59..69309403c8d0 100644
    --- a/clippy_dev/src/lib.rs
    +++ b/clippy_dev/src/lib.rs
    @@ -29,7 +29,6 @@ pub mod fmt;
     pub mod lint;
     pub mod new_lint;
     pub mod release;
    -pub mod rename_lint;
     pub mod serve;
     pub mod setup;
     pub mod sync;
    diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs
    index e4e19a100c6e..8dc2290df8e4 100644
    --- a/clippy_dev/src/main.rs
    +++ b/clippy_dev/src/main.rs
    @@ -4,8 +4,8 @@
     
     use clap::{Args, Parser, Subcommand};
     use clippy_dev::{
    -    ClippyInfo, UpdateMode, dogfood, edit_lints, fmt, lint, new_lint, new_parse_cx, release, rename_lint, serve, setup,
    -    sync, update_lints,
    +    ClippyInfo, UpdateMode, dogfood, edit_lints, fmt, lint, new_lint, new_parse_cx, release, serve, setup, sync,
    +    update_lints,
     };
     use std::env;
     
    @@ -75,7 +75,7 @@ fn main() {
             DevCommand::Serve { port, lint } => serve::run(port, lint),
             DevCommand::Lint { path, edition, args } => lint::run(&path, &edition, args.iter()),
             DevCommand::RenameLint { old_name, new_name } => new_parse_cx(|cx| {
    -            rename_lint::rename(cx, clippy.version, &old_name, &new_name);
    +            edit_lints::rename(cx, clippy.version, &old_name, &new_name);
             }),
             DevCommand::Uplift { old_name, new_name } => new_parse_cx(|cx| {
                 edit_lints::uplift(cx, clippy.version, &old_name, new_name.as_deref().unwrap_or(&old_name));
    diff --git a/clippy_dev/src/rename_lint.rs b/clippy_dev/src/rename_lint.rs
    deleted file mode 100644
    index 9be4f2bdc970..000000000000
    --- a/clippy_dev/src/rename_lint.rs
    +++ /dev/null
    @@ -1,353 +0,0 @@
    -use crate::parse::cursor::{self, Capture, Cursor};
    -use crate::parse::{ParseCx, RenamedLint};
    -use crate::update_lints::generate_lint_files;
    -use crate::utils::{
    -    ErrAction, FileUpdater, UpdateMode, UpdateStatus, Version, delete_dir_if_exists, delete_file_if_exists,
    -    expect_action, try_rename_dir, try_rename_file, walk_dir_no_dot_or_target,
    -};
    -use rustc_lexer::TokenKind;
    -use std::ffi::OsString;
    -use std::fs;
    -use std::path::Path;
    -
    -/// Runs the `rename_lint` command.
    -///
    -/// This does the following:
    -/// * Adds an entry to `renamed_lints.rs`.
    -/// * Renames all lint attributes to the new name (e.g. `#[allow(clippy::lint_name)]`).
    -/// * Renames the lint struct to the new name.
    -/// * Renames the module containing the lint struct to the new name if it shares a name with the
    -///   lint.
    -///
    -/// # Panics
    -/// Panics for the following conditions:
    -/// * If a file path could not read from or then written to
    -/// * If either lint name has a prefix
    -/// * If `old_name` doesn't name an existing lint.
    -/// * If `old_name` names a deprecated or renamed lint.
    -pub fn rename<'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'cx str, new_name: &'cx str) {
    -    let mut updater = FileUpdater::default();
    -    let mut lints = cx.find_lint_decls();
    -    let (deprecated_lints, mut renamed_lints) = cx.read_deprecated_lints();
    -
    -    let Ok(lint_idx) = lints.binary_search_by(|x| x.name.cmp(old_name)) else {
    -        panic!("could not find lint `{old_name}`");
    -    };
    -
    -    let old_name_prefixed = cx.str_buf.with(|buf| {
    -        buf.extend(["clippy::", old_name]);
    -        cx.arena.alloc_str(buf)
    -    });
    -    let new_name_prefixed = cx.str_buf.with(|buf| {
    -        buf.extend(["clippy::", new_name]);
    -        cx.arena.alloc_str(buf)
    -    });
    -
    -    for lint in &mut renamed_lints {
    -        if lint.new_name == old_name_prefixed {
    -            lint.new_name = new_name_prefixed;
    -        }
    -    }
    -    match renamed_lints.binary_search_by(|x| x.old_name.cmp(old_name_prefixed)) {
    -        Ok(_) => {
    -            println!("`{old_name}` already has a rename registered");
    -            return;
    -        },
    -        Err(idx) => {
    -            renamed_lints.insert(
    -                idx,
    -                RenamedLint {
    -                    old_name: old_name_prefixed,
    -                    new_name: new_name_prefixed,
    -                    version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),
    -                },
    -            );
    -        },
    -    }
    -
    -    // Some tests are named `lint_name_suffix` which should also be renamed,
    -    // but we can't do that if the renamed lint's name overlaps with another
    -    // lint. e.g. renaming 'foo' to 'bar' when a lint 'foo_bar' also exists.
    -    let change_prefixed_tests = lints.get(lint_idx + 1).is_none_or(|l| !l.name.starts_with(old_name));
    -
    -    let mut mod_edit = ModEdit::None;
    -    if lints.binary_search_by(|x| x.name.cmp(new_name)).is_err() {
    -        let lint = &mut lints[lint_idx];
    -        if lint.module.ends_with(old_name)
    -            && lint
    -                .path
    -                .file_stem()
    -                .is_some_and(|x| x.as_encoded_bytes() == old_name.as_bytes())
    -        {
    -            let mut new_path = lint.path.with_file_name(new_name).into_os_string();
    -            new_path.push(".rs");
    -            if try_rename_file(lint.path.as_ref(), new_path.as_ref()) {
    -                mod_edit = ModEdit::Rename;
    -            }
    -
    -            lint.module = cx.str_buf.with(|buf| {
    -                buf.push_str(&lint.module[..lint.module.len() - old_name.len()]);
    -                buf.push_str(new_name);
    -                cx.arena.alloc_str(buf)
    -            });
    -        }
    -        rename_test_files(old_name, new_name, change_prefixed_tests);
    -        lints[lint_idx].name = new_name;
    -        lints.sort_by(|lhs, rhs| lhs.name.cmp(rhs.name));
    -    } else {
    -        println!("Renamed `clippy::{old_name}` to `clippy::{new_name}`");
    -        println!("Since `{new_name}` already exists the existing code has not been changed");
    -        return;
    -    }
    -
    -    let mut update_fn = file_update_fn(old_name, new_name, mod_edit);
    -    for e in walk_dir_no_dot_or_target(".") {
    -        let e = expect_action(e, ErrAction::Read, ".");
    -        if e.path().as_os_str().as_encoded_bytes().ends_with(b".rs") {
    -            updater.update_file(e.path(), &mut update_fn);
    -        }
    -    }
    -    generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
    -
    -    println!("Renamed `clippy::{old_name}` to `clippy::{new_name}`");
    -    println!("All code referencing the old name has been updated");
    -    println!("Make sure to inspect the results as some things may have been missed");
    -    println!("note: `cargo uibless` still needs to be run to update the test results");
    -}
    -
    -#[derive(Clone, Copy)]
    -enum ModEdit {
    -    None,
    -    Delete,
    -    Rename,
    -}
    -
    -fn collect_ui_test_names(lint: &str, rename_prefixed: bool, dst: &mut Vec<(OsString, bool)>) {
    -    for e in fs::read_dir("tests/ui").expect("error reading `tests/ui`") {
    -        let e = e.expect("error reading `tests/ui`");
    -        let name = e.file_name();
    -        if let Some((name_only, _)) = name.as_encoded_bytes().split_once(|&x| x == b'.') {
    -            if name_only.starts_with(lint.as_bytes()) && (rename_prefixed || name_only.len() == lint.len()) {
    -                dst.push((name, true));
    -            }
    -        } else if name.as_encoded_bytes().starts_with(lint.as_bytes()) && (rename_prefixed || name.len() == lint.len())
    -        {
    -            dst.push((name, false));
    -        }
    -    }
    -}
    -
    -fn collect_ui_toml_test_names(lint: &str, rename_prefixed: bool, dst: &mut Vec<(OsString, bool)>) {
    -    if rename_prefixed {
    -        for e in fs::read_dir("tests/ui-toml").expect("error reading `tests/ui-toml`") {
    -            let e = e.expect("error reading `tests/ui-toml`");
    -            let name = e.file_name();
    -            if name.as_encoded_bytes().starts_with(lint.as_bytes()) && e.file_type().is_ok_and(|ty| ty.is_dir()) {
    -                dst.push((name, false));
    -            }
    -        }
    -    } else {
    -        dst.push((lint.into(), false));
    -    }
    -}
    -
    -/// Renames all test files for the given lint.
    -///
    -/// If `rename_prefixed` is `true` this will also rename tests which have the lint name as a prefix.
    -fn rename_test_files(old_name: &str, new_name: &str, rename_prefixed: bool) {
    -    let mut tests = Vec::new();
    -
    -    let mut old_buf = OsString::from("tests/ui/");
    -    let mut new_buf = OsString::from("tests/ui/");
    -    collect_ui_test_names(old_name, rename_prefixed, &mut tests);
    -    for &(ref name, is_file) in &tests {
    -        old_buf.push(name);
    -        new_buf.extend([new_name.as_ref(), name.slice_encoded_bytes(old_name.len()..)]);
    -        if is_file {
    -            try_rename_file(old_buf.as_ref(), new_buf.as_ref());
    -        } else {
    -            try_rename_dir(old_buf.as_ref(), new_buf.as_ref());
    -        }
    -        old_buf.truncate("tests/ui/".len());
    -        new_buf.truncate("tests/ui/".len());
    -    }
    -
    -    tests.clear();
    -    old_buf.truncate("tests/ui".len());
    -    new_buf.truncate("tests/ui".len());
    -    old_buf.push("-toml/");
    -    new_buf.push("-toml/");
    -    collect_ui_toml_test_names(old_name, rename_prefixed, &mut tests);
    -    for (name, _) in &tests {
    -        old_buf.push(name);
    -        new_buf.extend([new_name.as_ref(), name.slice_encoded_bytes(old_name.len()..)]);
    -        try_rename_dir(old_buf.as_ref(), new_buf.as_ref());
    -        old_buf.truncate("tests/ui/".len());
    -        new_buf.truncate("tests/ui/".len());
    -    }
    -}
    -
    -fn delete_test_files(lint: &str, rename_prefixed: bool) {
    -    let mut tests = Vec::new();
    -
    -    let mut buf = OsString::from("tests/ui/");
    -    collect_ui_test_names(lint, rename_prefixed, &mut tests);
    -    for &(ref name, is_file) in &tests {
    -        buf.push(name);
    -        if is_file {
    -            delete_file_if_exists(buf.as_ref());
    -        } else {
    -            delete_dir_if_exists(buf.as_ref());
    -        }
    -        buf.truncate("tests/ui/".len());
    -    }
    -
    -    buf.truncate("tests/ui".len());
    -    buf.push("-toml/");
    -
    -    tests.clear();
    -    collect_ui_toml_test_names(lint, rename_prefixed, &mut tests);
    -    for (name, _) in &tests {
    -        buf.push(name);
    -        delete_dir_if_exists(buf.as_ref());
    -        buf.truncate("tests/ui/".len());
    -    }
    -}
    -
    -fn snake_to_pascal(s: &str) -> String {
    -    let mut dst = Vec::with_capacity(s.len());
    -    let mut iter = s.bytes();
    -    || -> Option<()> {
    -        dst.push(iter.next()?.to_ascii_uppercase());
    -        while let Some(c) = iter.next() {
    -            if c == b'_' {
    -                dst.push(iter.next()?.to_ascii_uppercase());
    -            } else {
    -                dst.push(c);
    -            }
    -        }
    -        Some(())
    -    }();
    -    String::from_utf8(dst).unwrap()
    -}
    -
    -#[expect(clippy::too_many_lines)]
    -fn file_update_fn<'a, 'b>(
    -    old_name: &'a str,
    -    new_name: &'b str,
    -    mod_edit: ModEdit,
    -) -> impl use<'a, 'b> + FnMut(&Path, &str, &mut String) -> UpdateStatus {
    -    let old_name_pascal = snake_to_pascal(old_name);
    -    let new_name_pascal = snake_to_pascal(new_name);
    -    let old_name_upper = old_name.to_ascii_uppercase();
    -    let new_name_upper = new_name.to_ascii_uppercase();
    -    move |_, src, dst| {
    -        let mut copy_pos = 0u32;
    -        let mut changed = false;
    -        let mut cursor = Cursor::new(src);
    -        let mut captures = [Capture::EMPTY];
    -        loop {
    -            match cursor.peek() {
    -                TokenKind::Eof => break,
    -                TokenKind::Ident => {
    -                    let match_start = cursor.pos();
    -                    let text = cursor.peek_text();
    -                    cursor.step();
    -                    match text {
    -                        // clippy::line_name or clippy::lint-name
    -                        "clippy" => {
    -                            if cursor.match_all(&[cursor::Pat::DoubleColon, cursor::Pat::CaptureIdent], &mut captures)
    -                                && cursor.get_text(captures[0]) == old_name
    -                            {
    -                                dst.push_str(&src[copy_pos as usize..captures[0].pos as usize]);
    -                                dst.push_str(new_name);
    -                                copy_pos = cursor.pos();
    -                                changed = true;
    -                            }
    -                        },
    -                        // mod lint_name
    -                        "mod" => {
    -                            if !matches!(mod_edit, ModEdit::None)
    -                                && let Some(pos) = cursor.find_ident(old_name)
    -                            {
    -                                match mod_edit {
    -                                    ModEdit::Rename => {
    -                                        dst.push_str(&src[copy_pos as usize..pos as usize]);
    -                                        dst.push_str(new_name);
    -                                        copy_pos = cursor.pos();
    -                                        changed = true;
    -                                    },
    -                                    ModEdit::Delete if cursor.match_pat(cursor::Pat::Semi) => {
    -                                        let mut start = &src[copy_pos as usize..match_start as usize];
    -                                        if start.ends_with("\n\n") {
    -                                            start = &start[..start.len() - 1];
    -                                        }
    -                                        dst.push_str(start);
    -                                        copy_pos = cursor.pos();
    -                                        if src[copy_pos as usize..].starts_with("\n\n") {
    -                                            copy_pos += 1;
    -                                        }
    -                                        changed = true;
    -                                    },
    -                                    ModEdit::Delete | ModEdit::None => {},
    -                                }
    -                            }
    -                        },
    -                        // lint_name::
    -                        name if matches!(mod_edit, ModEdit::Rename) && name == old_name => {
    -                            let name_end = cursor.pos();
    -                            if cursor.match_pat(cursor::Pat::DoubleColon) {
    -                                dst.push_str(&src[copy_pos as usize..match_start as usize]);
    -                                dst.push_str(new_name);
    -                                copy_pos = name_end;
    -                                changed = true;
    -                            }
    -                        },
    -                        // LINT_NAME or LintName
    -                        name => {
    -                            let replacement = if name == old_name_upper {
    -                                &new_name_upper
    -                            } else if name == old_name_pascal {
    -                                &new_name_pascal
    -                            } else {
    -                                continue;
    -                            };
    -                            dst.push_str(&src[copy_pos as usize..match_start as usize]);
    -                            dst.push_str(replacement);
    -                            copy_pos = cursor.pos();
    -                            changed = true;
    -                        },
    -                    }
    -                },
    -                // //~ lint_name
    -                TokenKind::LineComment { doc_style: None } => {
    -                    let text = cursor.peek_text();
    -                    if text.starts_with("//~")
    -                        && let Some(text) = text.strip_suffix(old_name)
    -                        && !text.ends_with(|c| matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9' | '_'))
    -                    {
    -                        dst.push_str(&src[copy_pos as usize..cursor.pos() as usize + text.len()]);
    -                        dst.push_str(new_name);
    -                        copy_pos = cursor.pos() + cursor.peek_len();
    -                        changed = true;
    -                    }
    -                    cursor.step();
    -                },
    -                // ::lint_name
    -                TokenKind::Colon
    -                    if cursor.match_all(&[cursor::Pat::DoubleColon, cursor::Pat::CaptureIdent], &mut captures)
    -                        && cursor.get_text(captures[0]) == old_name =>
    -                {
    -                    dst.push_str(&src[copy_pos as usize..captures[0].pos as usize]);
    -                    dst.push_str(new_name);
    -                    copy_pos = cursor.pos();
    -                    changed = true;
    -                },
    -                _ => cursor.step(),
    -            }
    -        }
    -
    -        dst.push_str(&src[copy_pos as usize..]);
    -        UpdateStatus::from_changed(changed)
    -    }
    -}
    
    From 31db6aa5b24d9bf1751bf1017450abd4158bc06d Mon Sep 17 00:00:00 2001
    From: Jason Newcomb 
    Date: Sun, 12 Oct 2025 22:42:33 -0400
    Subject: [PATCH 1994/3801] `clippy_dev`: When renaming a lint better handle
     the case where the renamed lint is a prefix of another lint name.
    
    ---
     clippy_dev/src/edit_lints.rs | 79 ++++++++++++++++++++----------------
     1 file changed, 43 insertions(+), 36 deletions(-)
    
    diff --git a/clippy_dev/src/edit_lints.rs b/clippy_dev/src/edit_lints.rs
    index 8a5ba26fd215..14dd8b21df9a 100644
    --- a/clippy_dev/src/edit_lints.rs
    +++ b/clippy_dev/src/edit_lints.rs
    @@ -173,11 +173,6 @@ pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
             },
         }
     
    -    // Some tests are named `lint_name_suffix` which should also be renamed,
    -    // but we can't do that if the renamed lint's name overlaps with another
    -    // lint. e.g. renaming 'foo' to 'bar' when a lint 'foo_bar' also exists.
    -    let change_prefixed_tests = lints.get(lint_idx + 1).is_none_or(|l| !l.name.starts_with(old_name));
    -
         let mut mod_edit = ModEdit::None;
         if lints.binary_search_by(|x| x.name.cmp(new_name)).is_err() {
             let lint = &mut lints[lint_idx];
    @@ -199,7 +194,16 @@ pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
                     cx.arena.alloc_str(buf)
                 });
             }
    -        rename_test_files(old_name, new_name, change_prefixed_tests);
    +
    +        rename_test_files(
    +            old_name,
    +            new_name,
    +            &lints[lint_idx + 1..]
    +                .iter()
    +                .map(|l| l.name)
    +                .take_while(|&n| n.starts_with(old_name))
    +                .collect::>(),
    +        );
             lints[lint_idx].name = new_name;
             lints.sort_by(|lhs, rhs| lhs.name.cmp(rhs.name));
         } else {
    @@ -329,44 +333,45 @@ enum ModEdit {
         Rename,
     }
     
    -fn collect_ui_test_names(lint: &str, rename_prefixed: bool, dst: &mut Vec<(OsString, bool)>) {
    +fn collect_ui_test_names(lint: &str, ignored_prefixes: &[&str], dst: &mut Vec<(OsString, bool)>) {
         for e in fs::read_dir("tests/ui").expect("error reading `tests/ui`") {
             let e = e.expect("error reading `tests/ui`");
             let name = e.file_name();
    -        if let Some((name_only, _)) = name.as_encoded_bytes().split_once(|&x| x == b'.') {
    -            if name_only.starts_with(lint.as_bytes()) && (rename_prefixed || name_only.len() == lint.len()) {
    -                dst.push((name, true));
    -            }
    -        } else if name.as_encoded_bytes().starts_with(lint.as_bytes()) && (rename_prefixed || name.len() == lint.len())
    +        if name.as_encoded_bytes().starts_with(lint.as_bytes())
    +            && !ignored_prefixes
    +                .iter()
    +                .any(|&pre| name.as_encoded_bytes().starts_with(pre.as_bytes()))
    +            && let Ok(ty) = e.file_type()
    +            && (ty.is_file() || ty.is_dir())
    +        {
    +            dst.push((name, ty.is_file()));
    +        }
    +    }
    +}
    +
    +fn collect_ui_toml_test_names(lint: &str, ignored_prefixes: &[&str], dst: &mut Vec<(OsString, bool)>) {
    +    for e in fs::read_dir("tests/ui-toml").expect("error reading `tests/ui-toml`") {
    +        let e = e.expect("error reading `tests/ui-toml`");
    +        let name = e.file_name();
    +        if name.as_encoded_bytes().starts_with(lint.as_bytes())
    +            && !ignored_prefixes
    +                .iter()
    +                .any(|&pre| name.as_encoded_bytes().starts_with(pre.as_bytes()))
    +            && e.file_type().is_ok_and(|ty| ty.is_dir())
             {
                 dst.push((name, false));
             }
         }
     }
     
    -fn collect_ui_toml_test_names(lint: &str, rename_prefixed: bool, dst: &mut Vec<(OsString, bool)>) {
    -    if rename_prefixed {
    -        for e in fs::read_dir("tests/ui-toml").expect("error reading `tests/ui-toml`") {
    -            let e = e.expect("error reading `tests/ui-toml`");
    -            let name = e.file_name();
    -            if name.as_encoded_bytes().starts_with(lint.as_bytes()) && e.file_type().is_ok_and(|ty| ty.is_dir()) {
    -                dst.push((name, false));
    -            }
    -        }
    -    } else {
    -        dst.push((lint.into(), false));
    -    }
    -}
    -
    -/// Renames all test files for the given lint.
    -///
    -/// If `rename_prefixed` is `true` this will also rename tests which have the lint name as a prefix.
    -fn rename_test_files(old_name: &str, new_name: &str, rename_prefixed: bool) {
    -    let mut tests = Vec::new();
    +/// Renames all test files for the given lint where the file name does not start with any
    +/// of the given prefixes.
    +fn rename_test_files(old_name: &str, new_name: &str, ignored_prefixes: &[&str]) {
    +    let mut tests: Vec<(OsString, bool)> = Vec::new();
     
         let mut old_buf = OsString::from("tests/ui/");
         let mut new_buf = OsString::from("tests/ui/");
    -    collect_ui_test_names(old_name, rename_prefixed, &mut tests);
    +    collect_ui_test_names(old_name, ignored_prefixes, &mut tests);
         for &(ref name, is_file) in &tests {
             old_buf.push(name);
             new_buf.extend([new_name.as_ref(), name.slice_encoded_bytes(old_name.len()..)]);
    @@ -384,7 +389,7 @@ fn rename_test_files(old_name: &str, new_name: &str, rename_prefixed: bool) {
         new_buf.truncate("tests/ui".len());
         old_buf.push("-toml/");
         new_buf.push("-toml/");
    -    collect_ui_toml_test_names(old_name, rename_prefixed, &mut tests);
    +    collect_ui_toml_test_names(old_name, ignored_prefixes, &mut tests);
         for (name, _) in &tests {
             old_buf.push(name);
             new_buf.extend([new_name.as_ref(), name.slice_encoded_bytes(old_name.len()..)]);
    @@ -394,11 +399,13 @@ fn rename_test_files(old_name: &str, new_name: &str, rename_prefixed: bool) {
         }
     }
     
    -fn delete_test_files(lint: &str, rename_prefixed: bool) {
    +/// Deletes all test files for the given lint where the file name does not start with any
    +/// of the given prefixes.
    +fn delete_test_files(lint: &str, ignored_prefixes: &[&str]) {
         let mut tests = Vec::new();
     
         let mut buf = OsString::from("tests/ui/");
    -    collect_ui_test_names(lint, rename_prefixed, &mut tests);
    +    collect_ui_test_names(lint, ignored_prefixes, &mut tests);
         for &(ref name, is_file) in &tests {
             buf.push(name);
             if is_file {
    @@ -413,7 +420,7 @@ fn delete_test_files(lint: &str, rename_prefixed: bool) {
         buf.push("-toml/");
     
         tests.clear();
    -    collect_ui_toml_test_names(lint, rename_prefixed, &mut tests);
    +    collect_ui_toml_test_names(lint, ignored_prefixes, &mut tests);
         for (name, _) in &tests {
             buf.push(name);
             delete_dir_if_exists(buf.as_ref());
    
    From 5e8d1b541c3e89587e8b07cd75208ea5e029af6a Mon Sep 17 00:00:00 2001
    From: Jason Newcomb 
    Date: Mon, 13 Oct 2025 17:31:51 -0400
    Subject: [PATCH 1995/3801] `clippy_dev`: Re-enable deleting the module
     declaration on deprecation and uplifting.
    
    ---
     clippy_dev/src/edit_lints.rs   | 273 ++++++++++++---------------------
     clippy_dev/src/parse/cursor.rs |  16 ++
     2 files changed, 117 insertions(+), 172 deletions(-)
    
    diff --git a/clippy_dev/src/edit_lints.rs b/clippy_dev/src/edit_lints.rs
    index 14dd8b21df9a..fb1c1458c50c 100644
    --- a/clippy_dev/src/edit_lints.rs
    +++ b/clippy_dev/src/edit_lints.rs
    @@ -6,9 +6,9 @@ use crate::utils::{
         expect_action, try_rename_dir, try_rename_file, walk_dir_no_dot_or_target,
     };
     use rustc_lexer::TokenKind;
    -use std::ffi::{OsStr, OsString};
    -use std::path::{Path, PathBuf};
    -use std::{fs, io};
    +use std::ffi::OsString;
    +use std::fs;
    +use std::path::Path;
     
     /// Runs the `deprecate` command
     ///
    @@ -23,7 +23,7 @@ pub fn deprecate<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, name
         let mut lints = cx.find_lint_decls();
         let (mut deprecated_lints, renamed_lints) = cx.read_deprecated_lints();
     
    -    let Some(lint) = lints.iter().find(|l| l.name == name) else {
    +    let Some(lint_idx) = lints.iter().position(|l| l.name == name) else {
             eprintln!("error: failed to find lint `{name}`");
             return;
         };
    @@ -47,30 +47,17 @@ pub fn deprecate<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, name
             ),
         }
     
    -    let mod_path = {
    -        let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
    -        if mod_path.is_dir() {
    -            mod_path = mod_path.join("mod");
    -        }
    -
    -        mod_path.set_extension("rs");
    -        mod_path
    -    };
    -
    -    if remove_lint_declaration(name, &mod_path, &mut lints).unwrap_or(false) {
    -        generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
    -        println!("info: `{name}` has successfully been deprecated");
    -        println!("note: you must run `cargo uitest` to update the test results");
    -    } else {
    -        eprintln!("error: lint not found");
    -    }
    +    remove_lint_declaration(lint_idx, &mut lints, &mut FileUpdater::default());
    +    generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
    +    println!("info: `{name}` has successfully been deprecated");
    +    println!("note: you must run `cargo uitest` to update the test results");
     }
     
     pub fn uplift<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'env str, new_name: &'env str) {
         let mut lints = cx.find_lint_decls();
         let (deprecated_lints, mut renamed_lints) = cx.read_deprecated_lints();
     
    -    let Some(lint) = lints.iter().find(|l| l.name == old_name) else {
    +    let Some(lint_idx) = lints.iter().position(|l| l.name == old_name) else {
             eprintln!("error: failed to find lint `{old_name}`");
             return;
         };
    @@ -99,23 +86,18 @@ pub fn uplift<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
             ),
         }
     
    -    let mod_path = {
    -        let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));
    -        if mod_path.is_dir() {
    -            mod_path = mod_path.join("mod");
    +    let mut updater = FileUpdater::default();
    +    let remove_mod = remove_lint_declaration(lint_idx, &mut lints, &mut updater);
    +    let mut update_fn = uplift_update_fn(old_name, new_name, remove_mod);
    +    for e in walk_dir_no_dot_or_target(".") {
    +        let e = expect_action(e, ErrAction::Read, ".");
    +        if e.path().as_os_str().as_encoded_bytes().ends_with(b".rs") {
    +            updater.update_file(e.path(), &mut update_fn);
             }
    -
    -        mod_path.set_extension("rs");
    -        mod_path
    -    };
    -
    -    if remove_lint_declaration(old_name, &mod_path, &mut lints).unwrap_or(false) {
    -        generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
    -        println!("info: `{old_name}` has successfully been uplifted");
    -        println!("note: you must run `cargo uitest` to update the test results");
    -    } else {
    -        eprintln!("error: lint not found");
         }
    +    generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);
    +    println!("info: `{old_name}` has successfully been uplifted as `{new_name}`");
    +    println!("note: you must run `cargo uitest` to update the test results");
     }
     
     /// Runs the `rename_lint` command.
    @@ -173,7 +155,7 @@ pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
             },
         }
     
    -    let mut mod_edit = ModEdit::None;
    +    let mut rename_mod = false;
         if lints.binary_search_by(|x| x.name.cmp(new_name)).is_err() {
             let lint = &mut lints[lint_idx];
             if lint.module.ends_with(old_name)
    @@ -185,7 +167,7 @@ pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
                 let mut new_path = lint.path.with_file_name(new_name).into_os_string();
                 new_path.push(".rs");
                 if try_rename_file(lint.path.as_ref(), new_path.as_ref()) {
    -                mod_edit = ModEdit::Rename;
    +                rename_mod = true;
                 }
     
                 lint.module = cx.str_buf.with(|buf| {
    @@ -212,7 +194,7 @@ pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
             return;
         }
     
    -    let mut update_fn = file_update_fn(old_name, new_name, mod_edit);
    +    let mut update_fn = rename_update_fn(old_name, new_name, rename_mod);
         for e in walk_dir_no_dot_or_target(".") {
             let e = expect_action(e, ErrAction::Read, ".");
             if e.path().as_os_str().as_encoded_bytes().ends_with(b".rs") {
    @@ -227,110 +209,38 @@ pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
         println!("note: `cargo uibless` still needs to be run to update the test results");
     }
     
    -fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec>) -> io::Result {
    -    fn remove_lint(name: &str, lints: &mut Vec>) {
    -        lints.iter().position(|l| l.name == name).map(|pos| lints.remove(pos));
    -    }
    -
    -    fn remove_test_assets(name: &str) {
    -        let test_file_stem = format!("tests/ui/{name}");
    -        let path = Path::new(&test_file_stem);
    -
    -        // Some lints have their own directories, delete them
    -        if path.is_dir() {
    -            let _ = fs::remove_dir_all(path);
    -            return;
    -        }
    -
    -        // Remove all related test files
    -        let _ = fs::remove_file(path.with_extension("rs"));
    -        let _ = fs::remove_file(path.with_extension("stderr"));
    -        let _ = fs::remove_file(path.with_extension("fixed"));
    -    }
    -
    -    fn remove_impl_lint_pass(lint_name_upper: &str, content: &mut String) {
    -        let impl_lint_pass_start = content.find("impl_lint_pass!").unwrap_or_else(|| {
    -            content
    -                .find("declare_lint_pass!")
    -                .unwrap_or_else(|| panic!("failed to find `impl_lint_pass`"))
    +/// Removes a lint's declaration and test files. Returns whether the module containing the
    +/// lint was deleted.
    +fn remove_lint_declaration(lint_idx: usize, lints: &mut Vec>, updater: &mut FileUpdater) -> bool {
    +    let lint = lints.remove(lint_idx);
    +    let delete_mod = if lints.iter().all(|l| l.module != lint.module) {
    +        delete_file_if_exists(lint.path.as_ref())
    +    } else {
    +        updater.update_file(&lint.path, &mut |_, src, dst| -> UpdateStatus {
    +            let mut start = &src[..lint.declaration_range.start];
    +            if start.ends_with("\n\n") {
    +                start = &start[..start.len() - 1];
    +            }
    +            let mut end = &src[lint.declaration_range.end..];
    +            if end.starts_with("\n\n") {
    +                end = &end[1..];
    +            }
    +            dst.push_str(start);
    +            dst.push_str(end);
    +            UpdateStatus::Changed
             });
    -        let mut impl_lint_pass_end = content[impl_lint_pass_start..]
    -            .find(']')
    -            .expect("failed to find `impl_lint_pass` terminator");
    +        false
    +    };
    +    delete_test_files(
    +        lint.name,
    +        &lints[lint_idx..]
    +            .iter()
    +            .map(|l| l.name)
    +            .take_while(|&n| n.starts_with(lint.name))
    +            .collect::>(),
    +    );
     
    -        impl_lint_pass_end += impl_lint_pass_start;
    -        if let Some(lint_name_pos) = content[impl_lint_pass_start..impl_lint_pass_end].find(lint_name_upper) {
    -            let mut lint_name_end = impl_lint_pass_start + (lint_name_pos + lint_name_upper.len());
    -            for c in content[lint_name_end..impl_lint_pass_end].chars() {
    -                // Remove trailing whitespace
    -                if c == ',' || c.is_whitespace() {
    -                    lint_name_end += 1;
    -                } else {
    -                    break;
    -                }
    -            }
    -
    -            content.replace_range(impl_lint_pass_start + lint_name_pos..lint_name_end, "");
    -        }
    -    }
    -
    -    if path.exists()
    -        && let Some(lint) = lints.iter().find(|l| l.name == name)
    -    {
    -        if lint.module == name {
    -            // The lint name is the same as the file, we can just delete the entire file
    -            fs::remove_file(path)?;
    -        } else {
    -            // We can't delete the entire file, just remove the declaration
    -
    -            if let Some(Some("mod.rs")) = path.file_name().map(OsStr::to_str) {
    -                // Remove clippy_lints/src/some_mod/some_lint.rs
    -                let mut lint_mod_path = path.to_path_buf();
    -                lint_mod_path.set_file_name(name);
    -                lint_mod_path.set_extension("rs");
    -
    -                let _ = fs::remove_file(lint_mod_path);
    -            }
    -
    -            let mut content =
    -                fs::read_to_string(path).unwrap_or_else(|_| panic!("failed to read `{}`", path.to_string_lossy()));
    -
    -            eprintln!(
    -                "warn: you will have to manually remove any code related to `{name}` from `{}`",
    -                path.display()
    -            );
    -
    -            assert!(
    -                content[lint.declaration_range].contains(&name.to_uppercase()),
    -                "error: `{}` does not contain lint `{}`'s declaration",
    -                path.display(),
    -                lint.name
    -            );
    -
    -            // Remove lint declaration (declare_clippy_lint!)
    -            content.replace_range(lint.declaration_range, "");
    -
    -            // Remove the module declaration (mod xyz;)
    -            let mod_decl = format!("\nmod {name};");
    -            content = content.replacen(&mod_decl, "", 1);
    -
    -            remove_impl_lint_pass(&lint.name.to_uppercase(), &mut content);
    -            fs::write(path, content).unwrap_or_else(|_| panic!("failed to write to `{}`", path.to_string_lossy()));
    -        }
    -
    -        remove_test_assets(name);
    -        remove_lint(name, lints);
    -        return Ok(true);
    -    }
    -
    -    Ok(false)
    -}
    -
    -#[derive(Clone, Copy)]
    -enum ModEdit {
    -    None,
    -    Delete,
    -    Rename,
    +    delete_mod
     }
     
     fn collect_ui_test_names(lint: &str, ignored_prefixes: &[&str], dst: &mut Vec<(OsString, bool)>) {
    @@ -445,12 +355,50 @@ fn snake_to_pascal(s: &str) -> String {
         String::from_utf8(dst).unwrap()
     }
     
    -#[expect(clippy::too_many_lines)]
    -fn file_update_fn<'a, 'b>(
    +/// Creates an update function which replaces all instances of `clippy::old_name` with
    +/// `new_name`.
    +fn uplift_update_fn<'a>(
         old_name: &'a str,
    -    new_name: &'b str,
    -    mod_edit: ModEdit,
    -) -> impl use<'a, 'b> + FnMut(&Path, &str, &mut String) -> UpdateStatus {
    +    new_name: &'a str,
    +    remove_mod: bool,
    +) -> impl use<'a> + FnMut(&Path, &str, &mut String) -> UpdateStatus {
    +    move |_, src, dst| {
    +        let mut copy_pos = 0u32;
    +        let mut changed = false;
    +        let mut cursor = Cursor::new(src);
    +        while let Some(ident) = cursor.find_any_ident() {
    +            match cursor.get_text(ident) {
    +                "mod"
    +                    if remove_mod && cursor.match_all(&[cursor::Pat::Ident(old_name), cursor::Pat::Semi], &mut []) =>
    +                {
    +                    dst.push_str(&src[copy_pos as usize..ident.pos as usize]);
    +                    dst.push_str(new_name);
    +                    copy_pos = cursor.pos();
    +                    if src[copy_pos as usize..].starts_with('\n') {
    +                        copy_pos += 1;
    +                    }
    +                    changed = true;
    +                },
    +                "clippy" if cursor.match_all(&[cursor::Pat::DoubleColon, cursor::Pat::Ident(old_name)], &mut []) => {
    +                    dst.push_str(&src[copy_pos as usize..ident.pos as usize]);
    +                    dst.push_str(new_name);
    +                    copy_pos = cursor.pos();
    +                    changed = true;
    +                },
    +
    +                _ => {},
    +            }
    +        }
    +        dst.push_str(&src[copy_pos as usize..]);
    +        UpdateStatus::from_changed(changed)
    +    }
    +}
    +
    +fn rename_update_fn<'a>(
    +    old_name: &'a str,
    +    new_name: &'a str,
    +    rename_mod: bool,
    +) -> impl use<'a> + FnMut(&Path, &str, &mut String) -> UpdateStatus {
         let old_name_pascal = snake_to_pascal(old_name);
         let new_name_pascal = snake_to_pascal(new_name);
         let old_name_upper = old_name.to_ascii_uppercase();
    @@ -481,34 +429,15 @@ fn file_update_fn<'a, 'b>(
                             },
                             // mod lint_name
                             "mod" => {
    -                            if !matches!(mod_edit, ModEdit::None)
    -                                && let Some(pos) = cursor.find_ident(old_name)
    -                            {
    -                                match mod_edit {
    -                                    ModEdit::Rename => {
    -                                        dst.push_str(&src[copy_pos as usize..pos as usize]);
    -                                        dst.push_str(new_name);
    -                                        copy_pos = cursor.pos();
    -                                        changed = true;
    -                                    },
    -                                    ModEdit::Delete if cursor.match_pat(cursor::Pat::Semi) => {
    -                                        let mut start = &src[copy_pos as usize..match_start as usize];
    -                                        if start.ends_with("\n\n") {
    -                                            start = &start[..start.len() - 1];
    -                                        }
    -                                        dst.push_str(start);
    -                                        copy_pos = cursor.pos();
    -                                        if src[copy_pos as usize..].starts_with("\n\n") {
    -                                            copy_pos += 1;
    -                                        }
    -                                        changed = true;
    -                                    },
    -                                    ModEdit::Delete | ModEdit::None => {},
    -                                }
    +                            if rename_mod && let Some(pos) = cursor.match_ident(old_name) {
    +                                dst.push_str(&src[copy_pos as usize..pos as usize]);
    +                                dst.push_str(new_name);
    +                                copy_pos = cursor.pos();
    +                                changed = true;
                                 }
                             },
                             // lint_name::
    -                        name if matches!(mod_edit, ModEdit::Rename) && name == old_name => {
    +                        name if rename_mod && name == old_name => {
                                 let name_end = cursor.pos();
                                 if cursor.match_pat(cursor::Pat::DoubleColon) {
                                     dst.push_str(&src[copy_pos as usize..match_start as usize]);
    diff --git a/clippy_dev/src/parse/cursor.rs b/clippy_dev/src/parse/cursor.rs
    index 6dc003f326de..2c142af4883a 100644
    --- a/clippy_dev/src/parse/cursor.rs
    +++ b/clippy_dev/src/parse/cursor.rs
    @@ -219,6 +219,22 @@ impl<'txt> Cursor<'txt> {
             }
         }
     
    +    /// Consume the returns the position of the next non-whitespace token if it's an
    +    /// identifier. Returns `None` otherwise.
    +    pub fn match_ident(&mut self, s: &str) -> Option {
    +        loop {
    +            match self.next_token.kind {
    +                TokenKind::Ident if s == self.peek_text() => {
    +                    let pos = self.pos;
    +                    self.step();
    +                    return Some(pos);
    +                },
    +                TokenKind::Whitespace => self.step(),
    +                _ => return None,
    +            }
    +        }
    +    }
    +
         /// Continually attempt to match the pattern on subsequent tokens until a match is
         /// found. Returns whether the pattern was successfully matched.
         ///
    
    From 55f6901e967dda86ac15cf836777f1b32855feb7 Mon Sep 17 00:00:00 2001
    From: Wilfred Hughes 
    Date: Mon, 29 Dec 2025 03:23:48 -0800
    Subject: [PATCH 1996/3801] Fix lowering with supertrait predicates
    
    Previously both valid and invalid Rust code could crash r-a due to a
    cyclic query during lowering.
    ---
     .../rust-analyzer/crates/hir-ty/src/lower.rs  | 38 +++++++++++----
     .../crates/hir-ty/src/tests/regression.rs     | 48 +++++++++++++++++++
     2 files changed, 78 insertions(+), 8 deletions(-)
    
    diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
    index 9befca11b3e5..5789bf02a42e 100644
    --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
    +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
    @@ -53,7 +53,7 @@ use tracing::debug;
     use triomphe::{Arc, ThinArc};
     
     use crate::{
    -    FnAbi, ImplTraitId, TyLoweringDiagnostic, TyLoweringDiagnosticKind,
    +    FnAbi, ImplTraitId, TyLoweringDiagnostic, TyLoweringDiagnosticKind, all_super_traits,
         consteval::intern_const_ref,
         db::{HirDatabase, InternedOpaqueTyId},
         generics::{Generics, generics, trait_self_param_idx},
    @@ -1624,11 +1624,16 @@ pub(crate) fn field_types_with_diagnostics_query<'db>(
         (res, create_diagnostics(ctx.diagnostics))
     }
     
    +/// Predicates for `param_id` of the form `P: SomeTrait`. If
    +/// `assoc_name` is provided, only return predicates referencing traits
    +/// that have an associated type of that name.
    +///
     /// This query exists only to be used when resolving short-hand associated types
     /// like `T::Item`.
     ///
     /// See the analogous query in rustc and its comment:
     /// 
    +///
     /// This is a query mostly to handle cycles somewhat gracefully; e.g. the
     /// following bounds are disallowed: `T: Foo, U: Foo`, but
     /// these are fine: `T: Foo, U: Foo<()>`.
    @@ -1652,7 +1657,7 @@ pub(crate) fn generic_predicates_for_param<'db>(
         );
     
         // we have to filter out all other predicates *first*, before attempting to lower them
    -    let predicate = |pred: &_, ctx: &mut TyLoweringContext<'_, '_>| match pred {
    +    let has_relevant_bound = |pred: &_, ctx: &mut TyLoweringContext<'_, '_>| match pred {
             WherePredicate::ForLifetime { target, bound, .. }
             | WherePredicate::TypeBound { target, bound, .. } => {
                 let invalid_target = { ctx.lower_ty_only_param(*target) != Some(param_id) };
    @@ -1700,11 +1705,7 @@ pub(crate) fn generic_predicates_for_param<'db>(
                             return false;
                         };
     
    -                    rustc_type_ir::elaborate::supertrait_def_ids(interner, tr.into()).any(|tr| {
    -                        tr.0.trait_items(db).items.iter().any(|(name, item)| {
    -                            matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
    -                        })
    -                    })
    +                    trait_or_supertrait_has_assoc_type(db, tr, assoc_name)
                     }
                     TypeBound::Use(_) | TypeBound::Lifetime(_) | TypeBound::Error => false,
                 }
    @@ -1717,7 +1718,7 @@ pub(crate) fn generic_predicates_for_param<'db>(
         {
             ctx.store = maybe_parent_generics.store();
             for pred in maybe_parent_generics.where_predicates() {
    -            if predicate(pred, &mut ctx) {
    +            if has_relevant_bound(pred, &mut ctx) {
                     predicates.extend(
                         ctx.lower_where_predicate(
                             pred,
    @@ -1757,6 +1758,27 @@ pub(crate) fn generic_predicates_for_param_cycle_result(
         StoredEarlyBinder::bind(Clauses::empty(DbInterner::new_no_crate(db)).store())
     }
     
    +/// Check if this trait or any of its supertraits define an associated
    +/// type with the given name.
    +fn trait_or_supertrait_has_assoc_type(
    +    db: &dyn HirDatabase,
    +    tr: TraitId,
    +    assoc_name: &Name,
    +) -> bool {
    +    for trait_id in all_super_traits(db, tr) {
    +        if trait_id
    +            .trait_items(db)
    +            .items
    +            .iter()
    +            .any(|(name, item)| matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name)
    +        {
    +            return true;
    +        }
    +    }
    +
    +    false
    +}
    +
     #[inline]
     pub(crate) fn type_alias_bounds<'db>(
         db: &'db dyn HirDatabase,
    diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
    index df49d7999fee..a04c46f8eabd 100644
    --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
    +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
    @@ -2598,3 +2598,51 @@ trait ColumnLike {
         "#,
         );
     }
    +
    +#[test]
    +fn issue_21006_generic_predicates_for_param_supertrait_cycle() {
    +    check_no_mismatches(
    +        r#"
    +trait VCipherSuite {}
    +
    +trait CipherSuite
    +where
    +    OprfHash: Hash,
    +{
    +}
    +
    +type Bar = ::Hash;
    +
    +type OprfHash = ::Hash;
    +
    +impl Foo {
    +    fn seal() {}
    +}
    +        "#,
    +    );
    +}
    +
    +#[test]
    +fn issue_21006_self_assoc_trait() {
    +    check_types(
    +        r#"
    +trait Baz {
    +    fn baz(&self);
    +}
    +
    +trait Foo {
    +    type Assoc;
    +}
    +
    +trait Bar: Foo
    +where
    +    Self::Assoc: Baz,
    +{
    +    fn bar(v: Self::Assoc) {
    +        let _ = v.baz();
    +        //  ^ ()
    +    }
    +}
    +        "#,
    +    );
    +}
    
    From 2e556c490b67a4ea09cb39285b753bfc06a13604 Mon Sep 17 00:00:00 2001
    From: Ada Alakbarova 
    Date: Sat, 10 Jan 2026 15:31:52 +0100
    Subject: [PATCH 1997/3801] fix(unnecessary_map_or): respect reduced
     applicability
    
    ---
     clippy_lints/src/methods/unnecessary_map_or.rs | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/clippy_lints/src/methods/unnecessary_map_or.rs b/clippy_lints/src/methods/unnecessary_map_or.rs
    index 0c01be4b1875..7377b43571ce 100644
    --- a/clippy_lints/src/methods/unnecessary_map_or.rs
    +++ b/clippy_lints/src/methods/unnecessary_map_or.rs
    @@ -97,12 +97,12 @@ pub(super) fn check<'a>(
             // being converted to `Some(5) == Some(5).then(|| 1)` isn't
             // the same thing
     
    +        let mut app = Applicability::MachineApplicable;
             let inner_non_binding = Sugg::NonParen(Cow::Owned(format!(
                 "{wrap}({})",
    -            Sugg::hir(cx, non_binding_location, "")
    +            Sugg::hir_with_applicability(cx, non_binding_location, "", &mut app)
             )));
     
    -        let mut app = Applicability::MachineApplicable;
             let binop = make_binop(
                 op.node,
                 &Sugg::hir_with_applicability(cx, recv, "..", &mut app),
    
    From c8271c1daffb9f847147f852a6325304269d064e Mon Sep 17 00:00:00 2001
    From: reddevilmidzy 
    Date: Sat, 10 Jan 2026 02:07:15 +0900
    Subject: [PATCH 1998/3801] Added mGCA tests that were resolved
    
    ---
     .../mgca/assoc-const-projection-in-bound.rs   | 27 ++++++++++++++++
     .../mgca/cast-with-type-mismatched.rs         | 14 ++++++++
     .../mgca/cast-with-type-mismatched.stderr     | 20 ++++++++++++
     .../mgca/const-eval-with-invalid-args.rs      | 26 +++++++++++++++
     .../mgca/const-eval-with-invalid-args.stderr  | 32 +++++++++++++++++++
     .../recursive-self-referencing-const-param.rs | 11 +++++++
     ...ursive-self-referencing-const-param.stderr | 23 +++++++++++++
     .../mgca/size-of-generic-ptr-in-array-len.rs  | 10 ++++++
     .../size-of-generic-ptr-in-array-len.stderr   |  8 +++++
     9 files changed, 171 insertions(+)
     create mode 100644 tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs
     create mode 100644 tests/ui/const-generics/mgca/cast-with-type-mismatched.rs
     create mode 100644 tests/ui/const-generics/mgca/cast-with-type-mismatched.stderr
     create mode 100644 tests/ui/const-generics/mgca/const-eval-with-invalid-args.rs
     create mode 100644 tests/ui/const-generics/mgca/const-eval-with-invalid-args.stderr
     create mode 100644 tests/ui/const-generics/mgca/recursive-self-referencing-const-param.rs
     create mode 100644 tests/ui/const-generics/mgca/recursive-self-referencing-const-param.stderr
     create mode 100644 tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs
     create mode 100644 tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr
    
    diff --git a/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs b/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs
    new file mode 100644
    index 000000000000..460e14359483
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs
    @@ -0,0 +1,27 @@
    +//! regression test for 
    +//@ run-pass
    +#![expect(incomplete_features)]
    +#![feature(min_generic_const_args)]
    +#![allow(dead_code)]
    +
    +trait Abc {}
    +
    +trait A {
    +    #[type_const]
    +    const VALUE: usize;
    +}
    +
    +impl A for T {
    +    #[type_const]
    +    const VALUE: usize = 0;
    +}
    +
    +trait S {}
    +
    +trait Handler
    +where
    +    (): S<{ ::VALUE }>,
    +{
    +}
    +
    +fn main() {}
    diff --git a/tests/ui/const-generics/mgca/cast-with-type-mismatched.rs b/tests/ui/const-generics/mgca/cast-with-type-mismatched.rs
    new file mode 100644
    index 000000000000..1f499c222e7f
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/cast-with-type-mismatched.rs
    @@ -0,0 +1,14 @@
    +//! regression test for 
    +#![expect(incomplete_features)]
    +#![feature(generic_const_exprs)]
    +#![feature(min_generic_const_args)]
    +
    +fn foo(a: [(); N as usize]) {}
    +//~^ ERROR: complex const arguments must be placed inside of a `const` block
    +
    +const C: f32 = 1.0;
    +
    +fn main() {
    +    foo::([]);
    +    //~^ ERROR: the constant `C` is not of type `u32`
    +}
    diff --git a/tests/ui/const-generics/mgca/cast-with-type-mismatched.stderr b/tests/ui/const-generics/mgca/cast-with-type-mismatched.stderr
    new file mode 100644
    index 000000000000..7e1b21138ec8
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/cast-with-type-mismatched.stderr
    @@ -0,0 +1,20 @@
    +error: complex const arguments must be placed inside of a `const` block
    +  --> $DIR/cast-with-type-mismatched.rs:6:30
    +   |
    +LL | fn foo(a: [(); N as usize]) {}
    +   |                              ^^^^^^^^^^
    +
    +error: the constant `C` is not of type `u32`
    +  --> $DIR/cast-with-type-mismatched.rs:12:11
    +   |
    +LL |     foo::([]);
    +   |           ^ expected `u32`, found `f32`
    +   |
    +note: required by a const generic parameter in `foo`
    +  --> $DIR/cast-with-type-mismatched.rs:6:8
    +   |
    +LL | fn foo(a: [(); N as usize]) {}
    +   |        ^^^^^^^^^^^^ required by this const generic parameter in `foo`
    +
    +error: aborting due to 2 previous errors
    +
    diff --git a/tests/ui/const-generics/mgca/const-eval-with-invalid-args.rs b/tests/ui/const-generics/mgca/const-eval-with-invalid-args.rs
    new file mode 100644
    index 000000000000..3bf951e0c212
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/const-eval-with-invalid-args.rs
    @@ -0,0 +1,26 @@
    +//! regression test for 
    +#![expect(incomplete_features)]
    +#![feature(generic_const_exprs)]
    +#![feature(min_generic_const_args)]
    +
    +// The previous ICE was an "invalid field access on immediate".
    +// If we remove `val: i32` from the field, another ICE occurs.
    +// "assertion `left == right` failed: invalid field type in
    +// Immediate::offset: scalar value has wrong size"
    +struct A {
    +    arr: usize,
    +    val: i32,
    +}
    +
    +struct B {
    +    //~^ ERROR: `A` is forbidden as the type of a const generic parameter
    +    arr: [u8; N.arr],
    +    //~^ ERROR: complex const arguments must be placed inside of a `const` block
    +}
    +
    +const C: u32 = 1;
    +fn main() {
    +    let b = B:: {arr: [1]};
    +    //~^ ERROR: the constant `C` is not of type `A`
    +    let _ = b.arr.len();
    +}
    diff --git a/tests/ui/const-generics/mgca/const-eval-with-invalid-args.stderr b/tests/ui/const-generics/mgca/const-eval-with-invalid-args.stderr
    new file mode 100644
    index 000000000000..a226718ccf1b
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/const-eval-with-invalid-args.stderr
    @@ -0,0 +1,32 @@
    +error: complex const arguments must be placed inside of a `const` block
    +  --> $DIR/const-eval-with-invalid-args.rs:17:15
    +   |
    +LL |     arr: [u8; N.arr],
    +   |               ^^^^^
    +
    +error: `A` is forbidden as the type of a const generic parameter
    +  --> $DIR/const-eval-with-invalid-args.rs:15:19
    +   |
    +LL | struct B {
    +   |                   ^
    +   |
    +   = note: the only supported types are integers, `bool`, and `char`
    +help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
    +   |
    +LL + #![feature(adt_const_params)]
    +   |
    +
    +error: the constant `C` is not of type `A`
    +  --> $DIR/const-eval-with-invalid-args.rs:23:17
    +   |
    +LL |     let b = B:: {arr: [1]};
    +   |                 ^ expected `A`, found `u32`
    +   |
    +note: required by a const generic parameter in `B`
    +  --> $DIR/const-eval-with-invalid-args.rs:15:10
    +   |
    +LL | struct B {
    +   |          ^^^^^^^^^^ required by this const generic parameter in `B`
    +
    +error: aborting due to 3 previous errors
    +
    diff --git a/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.rs b/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.rs
    new file mode 100644
    index 000000000000..37dcc58ff468
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.rs
    @@ -0,0 +1,11 @@
    +//! regression test for 
    +#![expect(incomplete_features)]
    +#![feature(generic_const_exprs)]
    +#![feature(min_generic_const_args)]
    +
    +fn identity }>() }>>();
    +//~^ ERROR: free function without a body
    +//~| ERROR: expected type, found function `identity`
    +//~| ERROR: complex const arguments must be placed inside of a `const` block
    +
    +fn main() {}
    diff --git a/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.stderr b/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.stderr
    new file mode 100644
    index 000000000000..d1899c476ec6
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.stderr
    @@ -0,0 +1,23 @@
    +error: free function without a body
    +  --> $DIR/recursive-self-referencing-const-param.rs:6:1
    +   |
    +LL | fn identity }>() }>>();
    +   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
    +   |                                                                       |
    +   |                                                                       help: provide a definition for the function: `{  }`
    +
    +error[E0573]: expected type, found function `identity`
    +  --> $DIR/recursive-self-referencing-const-param.rs:6:22
    +   |
    +LL | fn identity }>() }>>();
    +   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type
    +
    +error: complex const arguments must be placed inside of a `const` block
    +  --> $DIR/recursive-self-referencing-const-param.rs:6:57
    +   |
    +LL | fn identity }>() }>>();
    +   |                                                         ^^
    +
    +error: aborting due to 3 previous errors
    +
    +For more information about this error, try `rustc --explain E0573`.
    diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs
    new file mode 100644
    index 000000000000..2a7c23929845
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs
    @@ -0,0 +1,10 @@
    +//! regression test for 
    +#![expect(incomplete_features)]
    +#![feature(min_generic_const_args)]
    +
    +fn foo() {
    +    [0; size_of::<*mut T>()];
    +    //~^ ERROR: tuple constructor with invalid base path
    +}
    +
    +fn main() {}
    diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr
    new file mode 100644
    index 000000000000..dcdc56a1cf47
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr
    @@ -0,0 +1,8 @@
    +error: tuple constructor with invalid base path
    +  --> $DIR/size-of-generic-ptr-in-array-len.rs:6:9
    +   |
    +LL |     [0; size_of::<*mut T>()];
    +   |         ^^^^^^^^^^^^^^^^^^^
    +
    +error: aborting due to 1 previous error
    +
    
    From c451e9bac648c9c6adcdbd9b4aa6067e38b606cb Mon Sep 17 00:00:00 2001
    From: bjorn3 
    Date: Sun, 19 Sep 2021 15:18:05 +0200
    Subject: [PATCH 1999/3801] Remove a workaround for a bug
    
    I don't think it is necessary anymore. As I understand it from issue
    39504 the original problem was that rustbuild changed a hardlink in the
    cargo build dir to point to copy in the sysroot while cargo may have
    hardlinked it to the original first. I don't think this happens anymore
    and as such this workaround is no longer necessary.
    ---
     compiler/rustc_metadata/src/locator.rs | 29 --------------------------
     1 file changed, 29 deletions(-)
    
    diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
    index 6c30ce0ddb3d..004d73da8cbd 100644
    --- a/compiler/rustc_metadata/src/locator.rs
    +++ b/compiler/rustc_metadata/src/locator.rs
    @@ -242,7 +242,6 @@ use crate::rmeta::{METADATA_HEADER, MetadataBlob, rustc_version};
     pub(crate) struct CrateLocator<'a> {
         // Immutable per-session configuration.
         only_needs_metadata: bool,
    -    sysroot: &'a Path,
         metadata_loader: &'a dyn MetadataLoader,
         cfg_version: &'static str,
     
    @@ -318,7 +317,6 @@ impl<'a> CrateLocator<'a> {
     
             CrateLocator {
                 only_needs_metadata,
    -            sysroot: sess.opts.sysroot.path(),
                 metadata_loader,
                 cfg_version: sess.cfg_version,
                 crate_name,
    @@ -670,33 +668,6 @@ impl<'a> CrateLocator<'a> {
                     continue;
                 }
     
    -            // Ok so at this point we've determined that `(lib, kind)` above is
    -            // a candidate crate to load, and that `slot` is either none (this
    -            // is the first crate of its kind) or if some the previous path has
    -            // the exact same hash (e.g., it's the exact same crate).
    -            //
    -            // In principle these two candidate crates are exactly the same so
    -            // we can choose either of them to link. As a stupidly gross hack,
    -            // however, we favor crate in the sysroot.
    -            //
    -            // You can find more info in rust-lang/rust#39518 and various linked
    -            // issues, but the general gist is that during testing libstd the
    -            // compilers has two candidates to choose from: one in the sysroot
    -            // and one in the deps folder. These two crates are the exact same
    -            // crate but if the compiler chooses the one in the deps folder
    -            // it'll cause spurious errors on Windows.
    -            //
    -            // As a result, we favor the sysroot crate here. Note that the
    -            // candidates are all canonicalized, so we canonicalize the sysroot
    -            // as well.
    -            if let Some(prev) = &ret {
    -                let sysroot = self.sysroot;
    -                let sysroot = try_canonicalize(sysroot).unwrap_or_else(|_| sysroot.to_path_buf());
    -                if prev.starts_with(&sysroot) {
    -                    continue;
    -                }
    -            }
    -
                 // We error eagerly here. If we're locating a rlib, then in theory the full metadata
                 // could still be in a (later resolved) dylib. In practice, if the rlib and dylib
                 // were produced in a way where one has full metadata and the other hasn't, it would
    
    From 01ebc285e1300de9f43a02b80a5bc408dab7bb3c Mon Sep 17 00:00:00 2001
    From: Alex Butler 
    Date: Mon, 12 Jan 2026 12:28:17 +0000
    Subject: [PATCH 2000/3801] smol_str: update changelog 0.3.5
    
    ---
     src/tools/rust-analyzer/lib/smol_str/CHANGELOG.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/tools/rust-analyzer/lib/smol_str/CHANGELOG.md b/src/tools/rust-analyzer/lib/smol_str/CHANGELOG.md
    index b7da6d18a440..4aa25fa13446 100644
    --- a/src/tools/rust-analyzer/lib/smol_str/CHANGELOG.md
    +++ b/src/tools/rust-analyzer/lib/smol_str/CHANGELOG.md
    @@ -1,6 +1,6 @@
     # Changelog
     
    -## Unreleased
    +## 0.3.5 - 2026-01-08
     - Optimise `SmolStr::clone` 4-5x speedup inline, 0.5x heap (slow down).
     
     ## 0.3.4 - 2025-10-23
    
    From c20e6a12269678cf4012b5962ccfb73db18c940f Mon Sep 17 00:00:00 2001
    From: A4-Tacks 
    Date: Mon, 12 Jan 2026 20:26:24 +0800
    Subject: [PATCH 2001/3801] Fix not complete `mut` and `raw` in `&x.foo()`
    
    Example
    ---
    ```rust
    fn main() {
        let _ = &$0x.foo();
    }
    ```
    
    **Before this PR**
    
    ```rust
    ...
    kw loop
    kw match
    kw return
    kw self::
    ...
    ```
    
    **After this PR**
    
    ```rust
    ...
    kw loop
    kw match
    kw mut
    kw raw
    kw return
    kw self::
    ...
    ```
    ---
     .../ide-completion/src/context/analysis.rs    | 10 ++++----
     .../ide-completion/src/tests/expression.rs    | 25 ++++++++++++++++++-
     2 files changed, 29 insertions(+), 6 deletions(-)
    
    diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
    index 65bae5b66e17..0db93b0837cd 100644
    --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
    +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
    @@ -1305,14 +1305,14 @@ fn classify_name_ref<'db>(
     
         let make_path_kind_expr = |expr: ast::Expr| {
             let it = expr.syntax();
    +        let prev_token = iter::successors(it.first_token(), |it| it.prev_token())
    +            .skip(1)
    +            .find(|it| !it.kind().is_trivia());
             let in_block_expr = is_in_block(it);
             let (in_loop_body, innermost_breakable) = is_in_breakable(it).unzip();
             let after_if_expr = is_after_if_expr(it.clone());
    -        let ref_expr_parent =
    -            path.as_single_name_ref().and_then(|_| it.parent()).and_then(ast::RefExpr::cast);
    -        let after_amp = non_trivia_sibling(it.clone().into(), Direction::Prev)
    -            .map(|it| it.kind() == SyntaxKind::AMP)
    -            .unwrap_or(false);
    +        let after_amp = prev_token.as_ref().is_some_and(|it| it.kind() == SyntaxKind::AMP);
    +        let ref_expr_parent = prev_token.and_then(|it| it.parent()).and_then(ast::RefExpr::cast);
             let (innermost_ret_ty, self_param) = {
                 let find_ret_ty = |it: SyntaxNode| {
                     if let Some(item) = ast::Item::cast(it.clone()) {
    diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
    index 78f003dd210b..ff005a29218b 100644
    --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
    +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs
    @@ -706,7 +706,30 @@ fn completes_after_ref_expr() {
                 kw while
                 kw while let
             "#]],
    -    )
    +    );
    +    check(
    +        r#"fn main() { let _ = &$0x.foo() }"#,
    +        expect![[r#"
    +            fn main() fn()
    +            bt u32     u32
    +            kw const
    +            kw crate::
    +            kw false
    +            kw for
    +            kw if
    +            kw if let
    +            kw loop
    +            kw match
    +            kw mut
    +            kw raw
    +            kw return
    +            kw self::
    +            kw true
    +            kw unsafe
    +            kw while
    +            kw while let
    +        "#]],
    +    );
     }
     
     #[test]
    
    From 6fa61dfd995fee8ec2f766964899b55c6f304fa1 Mon Sep 17 00:00:00 2001
    From: Samuel Tardieu 
    Date: Sun, 11 Jan 2026 09:06:44 +0100
    Subject: [PATCH 2002/3801] Do not ignore statements before a `break` when
     simplifying loop
    
    The previous tests ignored statements in a block and only looked at the
    final expression to determine if the block was made of a single `break`.
    ---
     clippy_lints/src/loops/while_let_loop.rs | 30 ++++++++++++++----------
     tests/ui/while_let_loop.rs               | 21 +++++++++++++++++
     2 files changed, 39 insertions(+), 12 deletions(-)
    
    diff --git a/clippy_lints/src/loops/while_let_loop.rs b/clippy_lints/src/loops/while_let_loop.rs
    index d4285db0abfc..e2ea24c39980 100644
    --- a/clippy_lints/src/loops/while_let_loop.rs
    +++ b/clippy_lints/src/loops/while_let_loop.rs
    @@ -40,7 +40,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_blo
                 let_info,
                 Some(if_let.if_then),
             );
    -    } else if els.and_then(|x| x.expr).is_some_and(is_simple_break_expr)
    +    } else if els.is_some_and(is_simple_break_block)
             && let Some((pat, _)) = let_info
         {
             could_be_while_let(cx, expr, pat, init, has_trailing_exprs, let_info, None);
    @@ -61,17 +61,23 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_blo
         }
     }
     
    -/// Returns `true` if expr contains a single break expression without a label or sub-expression,
    -/// possibly embedded in blocks.
    -fn is_simple_break_expr(e: &Expr<'_>) -> bool {
    -    if let ExprKind::Block(b, _) = e.kind {
    -        match (b.stmts, b.expr) {
    -            ([s], None) => matches!(s.kind, StmtKind::Expr(e) | StmtKind::Semi(e) if is_simple_break_expr(e)),
    -            ([], Some(e)) => is_simple_break_expr(e),
    -            _ => false,
    -        }
    -    } else {
    -        matches!(e.kind, ExprKind::Break(dest, None) if dest.label.is_none())
    +/// Checks if `block` contains a single unlabeled `break` expression or statement, possibly embedded
    +/// inside other blocks.
    +fn is_simple_break_block(block: &Block<'_>) -> bool {
    +    match (block.stmts, block.expr) {
    +        ([s], None) => matches!(s.kind, StmtKind::Expr(e) | StmtKind::Semi(e) if is_simple_break_expr(e)),
    +        ([], Some(e)) => is_simple_break_expr(e),
    +        _ => false,
    +    }
    +}
    +
    +/// Checks if `expr` contains a single unlabeled `break` expression or statement, possibly embedded
    +/// inside other blocks.
    +fn is_simple_break_expr(expr: &Expr<'_>) -> bool {
    +    match expr.kind {
    +        ExprKind::Block(b, _) => is_simple_break_block(b),
    +        ExprKind::Break(dest, None) => dest.label.is_none(),
    +        _ => false,
         }
     }
     
    diff --git a/tests/ui/while_let_loop.rs b/tests/ui/while_let_loop.rs
    index f28c504742fd..b5a362669ce2 100644
    --- a/tests/ui/while_let_loop.rs
    +++ b/tests/ui/while_let_loop.rs
    @@ -253,3 +253,24 @@ fn let_assign() {
             }
         }
     }
    +
    +fn issue16378() {
    +    // This does not lint today because of the extra statement(s)
    +    // before the `break`.
    +    // TODO: When the `break` statement/expr in the `let`/`else` is the
    +    // only way to leave the loop, the lint could trigger and move
    +    // the statements preceeding the `break` after the loop, as in:
    +    // ```rust
    +    // while let Some(x) = std::hint::black_box(None::) {
    +    //     println!("x = {x}");
    +    // }
    +    // println!("fail");
    +    // ```
    +    loop {
    +        let Some(x) = std::hint::black_box(None::) else {
    +            println!("fail");
    +            break;
    +        };
    +        println!("x = {x}");
    +    }
    +}
    
    From 2b50456eb4b3b5abdb13a36b62a92a268b740d4e Mon Sep 17 00:00:00 2001
    From: Ada Alakbarova 
    Date: Sun, 23 Nov 2025 20:48:47 +0100
    Subject: [PATCH 2003/3801] clean-up `unnecessary_map_or` and
     `manual_is_variant_and`
    
    - manual_is_variant_and: create `Flavor` using a function
      - removes one level of `for`
    ---
     .../src/methods/manual_is_variant_and.rs      | 129 ++++++++++--------
     clippy_lints/src/methods/mod.rs               |   5 +-
     .../src/methods/unnecessary_map_or.rs         |  34 ++---
     tests/ui/unnecessary_map_or.fixed             |   2 +-
     tests/ui/unnecessary_map_or.rs                |   2 +-
     tests/ui/unnecessary_map_or.stderr            |  38 +++---
     6 files changed, 111 insertions(+), 99 deletions(-)
    
    diff --git a/clippy_lints/src/methods/manual_is_variant_and.rs b/clippy_lints/src/methods/manual_is_variant_and.rs
    index 8f65858987b9..5ce9d364cdd8 100644
    --- a/clippy_lints/src/methods/manual_is_variant_and.rs
    +++ b/clippy_lints/src/methods/manual_is_variant_and.rs
    @@ -1,12 +1,13 @@
    -use clippy_utils::diagnostics::span_lint_and_sugg;
    +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
     use clippy_utils::msrvs::{self, Msrv};
     use clippy_utils::res::MaybeDef;
    -use clippy_utils::source::{snippet, snippet_with_applicability};
    +use clippy_utils::source::snippet_with_applicability;
     use clippy_utils::sugg::Sugg;
     use clippy_utils::{get_parent_expr, sym};
     use rustc_ast::LitKind;
     use rustc_errors::Applicability;
     use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
    +use rustc_hir::def_id::DefId;
     use rustc_hir::{BinOpKind, Closure, Expr, ExprKind, QPath};
     use rustc_lint::LateContext;
     use rustc_middle::ty;
    @@ -14,7 +15,37 @@ use rustc_span::{Span, Symbol};
     
     use super::MANUAL_IS_VARIANT_AND;
     
    -pub(super) fn check(
    +#[derive(Clone, Copy, PartialEq)]
    +enum Flavor {
    +    Option,
    +    Result,
    +}
    +
    +impl Flavor {
    +    fn new(cx: &LateContext<'_>, def_id: DefId) -> Option {
    +        match cx.tcx.get_diagnostic_name(def_id)? {
    +            sym::Option => Some(Self::Option),
    +            sym::Result => Some(Self::Result),
    +            _ => None,
    +        }
    +    }
    +
    +    const fn diag_sym(self) -> Symbol {
    +        match self {
    +            Self::Option => sym::Option,
    +            Self::Result => sym::Result,
    +        }
    +    }
    +
    +    const fn positive_variant_name(self) -> Symbol {
    +        match self {
    +            Self::Option => sym::Some,
    +            Self::Result => sym::Ok,
    +        }
    +    }
    +}
    +
    +pub(super) fn check_map_unwrap_or_default(
         cx: &LateContext<'_>,
         expr: &Expr<'_>,
         map_recv: &Expr<'_>,
    @@ -30,11 +61,13 @@ pub(super) fn check(
         }
     
         // 2. the caller of `map()` is neither `Option` nor `Result`
    -    let is_option = cx.typeck_results().expr_ty(map_recv).is_diag_item(cx, sym::Option);
    -    let is_result = cx.typeck_results().expr_ty(map_recv).is_diag_item(cx, sym::Result);
    -    if !is_option && !is_result {
    +    let Some(flavor) = (cx.typeck_results())
    +        .expr_ty(map_recv)
    +        .opt_def_id()
    +        .and_then(|did| Flavor::new(cx, did))
    +    else {
             return;
    -    }
    +    };
     
         // 3. the caller of `unwrap_or_default` is neither `Option` nor `Result`
         if !cx.typeck_results().expr_ty(expr).is_bool() {
    @@ -46,44 +79,23 @@ pub(super) fn check(
             return;
         }
     
    -    let lint_msg = if is_option {
    -        "called `map().unwrap_or_default()` on an `Option` value"
    -    } else {
    -        "called `map().unwrap_or_default()` on a `Result` value"
    +    let lint_span = expr.span.with_lo(map_span.lo());
    +    let lint_msg = match flavor {
    +        Flavor::Option => "called `map().unwrap_or_default()` on an `Option` value",
    +        Flavor::Result => "called `map().unwrap_or_default()` on a `Result` value",
         };
    -    let suggestion = if is_option { "is_some_and" } else { "is_ok_and" };
     
    -    span_lint_and_sugg(
    -        cx,
    -        MANUAL_IS_VARIANT_AND,
    -        expr.span.with_lo(map_span.lo()),
    -        lint_msg,
    -        "use",
    -        format!("{}({})", suggestion, snippet(cx, map_arg.span, "..")),
    -        Applicability::MachineApplicable,
    -    );
    -}
    +    span_lint_and_then(cx, MANUAL_IS_VARIANT_AND, lint_span, lint_msg, |diag| {
    +        let method = match flavor {
    +            Flavor::Option => "is_some_and",
    +            Flavor::Result => "is_ok_and",
    +        };
     
    -#[derive(Clone, Copy, PartialEq)]
    -enum Flavor {
    -    Option,
    -    Result,
    -}
    +        let mut app = Applicability::MachineApplicable;
    +        let map_arg_snippet = snippet_with_applicability(cx, map_arg.span, "_", &mut app);
     
    -impl Flavor {
    -    const fn symbol(self) -> Symbol {
    -        match self {
    -            Self::Option => sym::Option,
    -            Self::Result => sym::Result,
    -        }
    -    }
    -
    -    const fn positive(self) -> Symbol {
    -        match self {
    -            Self::Option => sym::Some,
    -            Self::Result => sym::Ok,
    -        }
    -    }
    +        diag.span_suggestion(lint_span, "use", format!("{method}({map_arg_snippet})"), app);
    +    });
     }
     
     #[derive(Clone, Copy, PartialEq)]
    @@ -178,7 +190,7 @@ fn emit_lint<'tcx>(
             cx,
             MANUAL_IS_VARIANT_AND,
             span,
    -        format!("called `.map() {op} {pos}()`", pos = flavor.positive(),),
    +        format!("called `.map() {op} {pos}()`", pos = flavor.positive_variant_name()),
             "use",
             format!(
                 "{inversion}{recv}.{method}({body})",
    @@ -195,24 +207,23 @@ pub(super) fn check_map(cx: &LateContext<'_>, expr: &Expr<'_>) {
             && op.span.eq_ctxt(expr.span)
             && let Ok(op) = Op::try_from(op.node)
         {
    -        // Check `left` and `right` expression in any order, and for `Option` and `Result`
    +        // Check `left` and `right` expression in any order
             for (expr1, expr2) in [(left, right), (right, left)] {
    -            for flavor in [Flavor::Option, Flavor::Result] {
    -                if let ExprKind::Call(call, [arg]) = expr1.kind
    -                    && let ExprKind::Lit(lit) = arg.kind
    -                    && let LitKind::Bool(bool_cst) = lit.node
    -                    && let ExprKind::Path(QPath::Resolved(_, path)) = call.kind
    -                    && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), _) = path.res
    -                    && let ty = cx.typeck_results().expr_ty(expr1)
    -                    && let ty::Adt(adt, args) = ty.kind()
    -                    && cx.tcx.is_diagnostic_item(flavor.symbol(), adt.did())
    -                    && args.type_at(0).is_bool()
    -                    && let ExprKind::MethodCall(_, recv, [map_expr], _) = expr2.kind
    -                    && cx.typeck_results().expr_ty(recv).is_diag_item(cx, flavor.symbol())
    -                    && let Ok(map_func) = MapFunc::try_from(map_expr)
    -                {
    -                    return emit_lint(cx, parent_expr.span, op, flavor, bool_cst, map_func, recv);
    -                }
    +            if let ExprKind::Call(call, [arg]) = expr1.kind
    +                && let ExprKind::Lit(lit) = arg.kind
    +                && let LitKind::Bool(bool_cst) = lit.node
    +                && let ExprKind::Path(QPath::Resolved(_, path)) = call.kind
    +                && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), _) = path.res
    +                && let ExprKind::MethodCall(_, recv, [map_expr], _) = expr2.kind
    +                && let ty = cx.typeck_results().expr_ty(expr1)
    +                && let ty::Adt(adt, args) = ty.kind()
    +                && let Some(flavor) = Flavor::new(cx, adt.did())
    +                && args.type_at(0).is_bool()
    +                && cx.typeck_results().expr_ty(recv).is_diag_item(cx, flavor.diag_sym())
    +                && let Ok(map_func) = MapFunc::try_from(map_expr)
    +            {
    +                emit_lint(cx, parent_expr.span, op, flavor, bool_cst, map_func, recv);
    +                return;
                 }
             }
         }
    diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
    index ee0cd95a5021..659a704a1ecb 100644
    --- a/clippy_lints/src/methods/mod.rs
    +++ b/clippy_lints/src/methods/mod.rs
    @@ -3933,7 +3933,8 @@ declare_clippy_lint! {
     
     declare_clippy_lint! {
         /// ### What it does
    -    /// Checks for usage of `option.map(f).unwrap_or_default()` and `result.map(f).unwrap_or_default()` where f is a function or closure that returns the `bool` type.
    +    /// Checks for usage of `option.map(f).unwrap_or_default()` and `result.map(f).unwrap_or_default()` where `f` is a function or closure that returns the `bool` type.
    +    ///
         /// Also checks for equality comparisons like `option.map(f) == Some(true)` and `result.map(f) == Ok(true)`.
         ///
         /// ### Why is this bad?
    @@ -5629,7 +5630,7 @@ impl Methods {
                                 manual_saturating_arithmetic::check_sub_unwrap_or_default(cx, expr, lhs, rhs);
                             },
                             Some((sym::map, m_recv, [arg], span, _)) => {
    -                            manual_is_variant_and::check(cx, expr, m_recv, arg, span, self.msrv);
    +                            manual_is_variant_and::check_map_unwrap_or_default(cx, expr, m_recv, arg, span, self.msrv);
                             },
                             Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => {
                                 obfuscated_if_else::check(
    diff --git a/clippy_lints/src/methods/unnecessary_map_or.rs b/clippy_lints/src/methods/unnecessary_map_or.rs
    index 7377b43571ce..21e112360aaf 100644
    --- a/clippy_lints/src/methods/unnecessary_map_or.rs
    +++ b/clippy_lints/src/methods/unnecessary_map_or.rs
    @@ -8,7 +8,7 @@ use clippy_utils::sugg::{Sugg, make_binop};
     use clippy_utils::ty::{implements_trait, is_copy};
     use clippy_utils::visitors::is_local_used;
     use clippy_utils::{get_parent_expr, is_from_proc_macro};
    -use rustc_ast::LitKind::Bool;
    +use rustc_ast::LitKind;
     use rustc_errors::Applicability;
     use rustc_hir::{BinOpKind, Expr, ExprKind, PatKind};
     use rustc_lint::LateContext;
    @@ -48,13 +48,14 @@ pub(super) fn check<'a>(
         let ExprKind::Lit(def_kind) = def.kind else {
             return;
         };
    -
    -    let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
    -
    -    let Bool(def_bool) = def_kind.node else {
    +    let LitKind::Bool(def_bool) = def_kind.node else {
             return;
         };
     
    +    let typeck = cx.typeck_results();
    +
    +    let recv_ty = typeck.expr_ty_adjusted(recv);
    +
         let variant = match recv_ty.opt_diag_name(cx) {
             Some(sym::Option) => Variant::Some,
             Some(sym::Result) => Variant::Ok,
    @@ -63,12 +64,12 @@ pub(super) fn check<'a>(
     
         let ext_def_span = def.span.until(map.span);
     
    -    let (sugg, method, applicability) = if cx.typeck_results().expr_adjustments(recv).is_empty()
    +    let (sugg, method, applicability): (_, Cow<'_, _>, _) = if typeck.expr_adjustments(recv).is_empty()
                 && let ExprKind::Closure(map_closure) = map.kind
                 && let closure_body = cx.tcx.hir_body(map_closure.body)
                 && let closure_body_value = closure_body.value.peel_blocks()
                 && let ExprKind::Binary(op, l, r) = closure_body_value.kind
    -            && let Some(param) = closure_body.params.first()
    +            && let [param] = closure_body.params
                 && let PatKind::Binding(_, hir_id, _, _) = param.pat.kind
                 // checking that map_or is one of the following:
                 // .map_or(false, |x| x == y)
    @@ -78,14 +79,13 @@ pub(super) fn check<'a>(
                 && ((BinOpKind::Eq == op.node && !def_bool) || (BinOpKind::Ne == op.node && def_bool))
                 && let non_binding_location = if l.res_local_id() == Some(hir_id) { r } else { l }
                 && switch_to_eager_eval(cx, non_binding_location)
    -            // if its both then that's a strange edge case and
    +            // if it's both then that's a strange edge case and
                 // we can just ignore it, since by default clippy will error on this
                 && (l.res_local_id() == Some(hir_id)) != (r.res_local_id() == Some(hir_id))
                 && !is_local_used(cx, non_binding_location, hir_id)
    -            && let typeck_results = cx.typeck_results()
    -            && let l_ty = typeck_results.expr_ty(l)
    -            && l_ty == typeck_results.expr_ty(r)
    -            && let Some(partial_eq) = cx.tcx.get_diagnostic_item(sym::PartialEq)
    +            && let l_ty = typeck.expr_ty(l)
    +            && l_ty == typeck.expr_ty(r)
    +            && let Some(partial_eq) = cx.tcx.lang_items().eq_trait()
                 && implements_trait(cx, recv_ty, partial_eq, &[recv_ty.into()])
                 && is_copy(cx, l_ty)
         {
    @@ -126,18 +126,18 @@ pub(super) fn check<'a>(
             }
             .into_string();
     
    -        (vec![(expr.span, sugg)], "a standard comparison", app)
    +        (vec![(expr.span, sugg)], "a standard comparison".into(), app)
         } else if !def_bool && msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) {
             let suggested_name = variant.method_name();
             (
    -            vec![(method_span, suggested_name.into()), (ext_def_span, String::default())],
    -            suggested_name,
    +            vec![(method_span, suggested_name.into()), (ext_def_span, String::new())],
    +            format!("`{suggested_name}`").into(),
                 Applicability::MachineApplicable,
             )
         } else if def_bool && matches!(variant, Variant::Some) && msrv.meets(cx, msrvs::IS_NONE_OR) {
             (
    -            vec![(method_span, "is_none_or".into()), (ext_def_span, String::default())],
    -            "is_none_or",
    +            vec![(method_span, "is_none_or".into()), (ext_def_span, String::new())],
    +            "`is_none_or`".into(),
                 Applicability::MachineApplicable,
             )
         } else {
    diff --git a/tests/ui/unnecessary_map_or.fixed b/tests/ui/unnecessary_map_or.fixed
    index 10552431d65d..52c114339292 100644
    --- a/tests/ui/unnecessary_map_or.fixed
    +++ b/tests/ui/unnecessary_map_or.fixed
    @@ -70,7 +70,7 @@ fn main() {
         let _ = r.is_ok_and(|x| x == 7);
         //~^ unnecessary_map_or
     
    -    // lint constructs that are not comparaisons as well
    +    // lint constructs that are not comparisons as well
         let func = |_x| true;
         let r: Result = Ok(3);
         let _ = r.is_ok_and(func);
    diff --git a/tests/ui/unnecessary_map_or.rs b/tests/ui/unnecessary_map_or.rs
    index 4b406ec2998b..dd2e1a569469 100644
    --- a/tests/ui/unnecessary_map_or.rs
    +++ b/tests/ui/unnecessary_map_or.rs
    @@ -74,7 +74,7 @@ fn main() {
         let _ = r.map_or(false, |x| x == 7);
         //~^ unnecessary_map_or
     
    -    // lint constructs that are not comparaisons as well
    +    // lint constructs that are not comparisons as well
         let func = |_x| true;
         let r: Result = Ok(3);
         let _ = r.map_or(false, func);
    diff --git a/tests/ui/unnecessary_map_or.stderr b/tests/ui/unnecessary_map_or.stderr
    index b8a22346c378..d11e7179f921 100644
    --- a/tests/ui/unnecessary_map_or.stderr
    +++ b/tests/ui/unnecessary_map_or.stderr
    @@ -56,7 +56,7 @@ LL | |         6 >= 5
     LL | |     });
        | |______^
        |
    -help: use is_some_and instead
    +help: use `is_some_and` instead
        |
     LL -     let _ = Some(5).map_or(false, |n| {
     LL +     let _ = Some(5).is_some_and(|n| {
    @@ -68,7 +68,7 @@ error: this `map_or` can be simplified
     LL |     let _ = Some(vec![5]).map_or(false, |n| n == [5]);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_some_and instead
    +help: use `is_some_and` instead
        |
     LL -     let _ = Some(vec![5]).map_or(false, |n| n == [5]);
     LL +     let _ = Some(vec![5]).is_some_and(|n| n == [5]);
    @@ -80,7 +80,7 @@ error: this `map_or` can be simplified
     LL |     let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_some_and instead
    +help: use `is_some_and` instead
        |
     LL -     let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);
     LL +     let _ = Some(vec![1]).is_some_and(|n| vec![2] == n);
    @@ -92,7 +92,7 @@ error: this `map_or` can be simplified
     LL |     let _ = Some(5).map_or(false, |n| n == n);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_some_and instead
    +help: use `is_some_and` instead
        |
     LL -     let _ = Some(5).map_or(false, |n| n == n);
     LL +     let _ = Some(5).is_some_and(|n| n == n);
    @@ -104,7 +104,7 @@ error: this `map_or` can be simplified
     LL |     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_some_and instead
    +help: use `is_some_and` instead
        |
     LL -     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
     LL +     let _ = Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 });
    @@ -116,7 +116,7 @@ error: this `map_or` can be simplified
     LL |     let _ = Ok::, i32>(vec![5]).map_or(false, |n| n == [5]);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_ok_and instead
    +help: use `is_ok_and` instead
        |
     LL -     let _ = Ok::, i32>(vec![5]).map_or(false, |n| n == [5]);
     LL +     let _ = Ok::, i32>(vec![5]).is_ok_and(|n| n == [5]);
    @@ -152,7 +152,7 @@ error: this `map_or` can be simplified
     LL |     let _ = Some(5).map_or(true, |n| n == 5);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_none_or instead
    +help: use `is_none_or` instead
        |
     LL -     let _ = Some(5).map_or(true, |n| n == 5);
     LL +     let _ = Some(5).is_none_or(|n| n == 5);
    @@ -164,7 +164,7 @@ error: this `map_or` can be simplified
     LL |     let _ = Some(5).map_or(true, |n| 5 == n);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_none_or instead
    +help: use `is_none_or` instead
        |
     LL -     let _ = Some(5).map_or(true, |n| 5 == n);
     LL +     let _ = Some(5).is_none_or(|n| 5 == n);
    @@ -212,7 +212,7 @@ error: this `map_or` can be simplified
     LL |     let _ = r.map_or(false, |x| x == 7);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_ok_and instead
    +help: use `is_ok_and` instead
        |
     LL -     let _ = r.map_or(false, |x| x == 7);
     LL +     let _ = r.is_ok_and(|x| x == 7);
    @@ -224,7 +224,7 @@ error: this `map_or` can be simplified
     LL |     let _ = r.map_or(false, func);
        |             ^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_ok_and instead
    +help: use `is_ok_and` instead
        |
     LL -     let _ = r.map_or(false, func);
     LL +     let _ = r.is_ok_and(func);
    @@ -236,7 +236,7 @@ error: this `map_or` can be simplified
     LL |     let _ = Some(5).map_or(false, func);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_some_and instead
    +help: use `is_some_and` instead
        |
     LL -     let _ = Some(5).map_or(false, func);
     LL +     let _ = Some(5).is_some_and(func);
    @@ -248,7 +248,7 @@ error: this `map_or` can be simplified
     LL |     let _ = Some(5).map_or(true, func);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_none_or instead
    +help: use `is_none_or` instead
        |
     LL -     let _ = Some(5).map_or(true, func);
     LL +     let _ = Some(5).is_none_or(func);
    @@ -272,7 +272,7 @@ error: this `map_or` can be simplified
     LL |     o.map_or(true, |n| n > 5) || (o as &Option).map_or(true, |n| n < 5)
        |     ^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_none_or instead
    +help: use `is_none_or` instead
        |
     LL -     o.map_or(true, |n| n > 5) || (o as &Option).map_or(true, |n| n < 5)
     LL +     o.is_none_or(|n| n > 5) || (o as &Option).map_or(true, |n| n < 5)
    @@ -284,7 +284,7 @@ error: this `map_or` can be simplified
     LL |     o.map_or(true, |n| n > 5) || (o as &Option).map_or(true, |n| n < 5)
        |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_none_or instead
    +help: use `is_none_or` instead
        |
     LL -     o.map_or(true, |n| n > 5) || (o as &Option).map_or(true, |n| n < 5)
     LL +     o.map_or(true, |n| n > 5) || (o as &Option).is_none_or(|n| n < 5)
    @@ -296,7 +296,7 @@ error: this `map_or` can be simplified
     LL |     o.map_or(true, |n| n > 5)
        |     ^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_none_or instead
    +help: use `is_none_or` instead
        |
     LL -     o.map_or(true, |n| n > 5)
     LL +     o.is_none_or(|n| n > 5)
    @@ -308,7 +308,7 @@ error: this `map_or` can be simplified
     LL |     let x = a.map_or(false, |a| a == *s);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_some_and instead
    +help: use `is_some_and` instead
        |
     LL -     let x = a.map_or(false, |a| a == *s);
     LL +     let x = a.is_some_and(|a| a == *s);
    @@ -320,7 +320,7 @@ error: this `map_or` can be simplified
     LL |     let y = b.map_or(true, |b| b == *s);
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_none_or instead
    +help: use `is_none_or` instead
        |
     LL -     let y = b.map_or(true, |b| b == *s);
     LL +     let y = b.is_none_or(|b| b == *s);
    @@ -356,7 +356,7 @@ error: this `map_or` can be simplified
     LL |     _ = s.lock().unwrap().map_or(false, |s| s == "foo");
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_some_and instead
    +help: use `is_some_and` instead
        |
     LL -     _ = s.lock().unwrap().map_or(false, |s| s == "foo");
     LL +     _ = s.lock().unwrap().is_some_and(|s| s == "foo");
    @@ -368,7 +368,7 @@ error: this `map_or` can be simplified
     LL |     _ = s.map_or(false, |s| s == "foo");
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
    -help: use is_some_and instead
    +help: use `is_some_and` instead
        |
     LL -     _ = s.map_or(false, |s| s == "foo");
     LL +     _ = s.is_some_and(|s| s == "foo");
    
    From 62e777ca76c62d34993dbf576957a6a9e224f034 Mon Sep 17 00:00:00 2001
    From: Roberto Aloi 
    Date: Mon, 12 Jan 2026 14:11:12 +0100
    Subject: [PATCH 2004/3801] Fix overlapping cfg attributes for
     wasm32-unknown-emscripten target
    
    ---
     src/tools/rust-analyzer/crates/stdx/src/process.rs | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/tools/rust-analyzer/crates/stdx/src/process.rs b/src/tools/rust-analyzer/crates/stdx/src/process.rs
    index 2efeed45e44e..7c4ae978b04a 100644
    --- a/src/tools/rust-analyzer/crates/stdx/src/process.rs
    +++ b/src/tools/rust-analyzer/crates/stdx/src/process.rs
    @@ -76,7 +76,7 @@ pub fn spawn_with_streaming_output(
         Ok(Output { status, stdout, stderr })
     }
     
    -#[cfg(unix)]
    +#[cfg(all(unix, not(target_arch = "wasm32")))]
     mod imp {
         use std::{
             io::{self, prelude::*},
    
    From 41939ae3b31848a9d854c25ce2c1973de5e64e6c Mon Sep 17 00:00:00 2001
    From: Ralf Jung 
    Date: Mon, 12 Jan 2026 11:48:16 +0100
    Subject: [PATCH 2005/3801] test closing std streams separately, and in two
     configurations
    
    ---
     .../miri/tests/pass-dep/libc/close-std-streams.rs   | 13 +++++++++++++
     src/tools/miri/tests/pass-dep/libc/libc-fs.rs       | 11 +----------
     2 files changed, 14 insertions(+), 10 deletions(-)
     create mode 100644 src/tools/miri/tests/pass-dep/libc/close-std-streams.rs
    
    diff --git a/src/tools/miri/tests/pass-dep/libc/close-std-streams.rs b/src/tools/miri/tests/pass-dep/libc/close-std-streams.rs
    new file mode 100644
    index 000000000000..cc30d9557fc6
    --- /dev/null
    +++ b/src/tools/miri/tests/pass-dep/libc/close-std-streams.rs
    @@ -0,0 +1,13 @@
    +//@ignore-target: windows # no libc
    +//@ revisions: default null
    +//@[null] compile-flags: -Zmiri-mute-stdout-stderr
    +
    +fn main() {
    +    // This is std library UB, but that's not relevant since we're
    +    // only interacting with libc here.
    +    unsafe {
    +        libc::close(0);
    +        libc::close(1);
    +        libc::close(2);
    +    }
    +}
    diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
    index 8c860b5db7ba..00d5f7d97e28 100644
    --- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
    +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
    @@ -1,4 +1,4 @@
    -//@ignore-target: windows # File handling is not implemented yet
    +//@ignore-target: windows # no libc
     //@compile-flags: -Zmiri-disable-isolation
     
     #![feature(io_error_more)]
    @@ -48,7 +48,6 @@ fn main() {
         test_nofollow_not_symlink();
         #[cfg(target_os = "macos")]
         test_ioctl();
    -    test_close_stdout();
     }
     
     fn test_file_open_unix_allow_two_args() {
    @@ -580,11 +579,3 @@ fn test_ioctl() {
             assert_eq!(libc::ioctl(fd, libc::FIOCLEX), 0);
         }
     }
    -
    -fn test_close_stdout() {
    -    // This is std library UB, but that's not relevant since we're
    -    // only interacting with libc here.
    -    unsafe {
    -        libc::close(1);
    -    }
    -}
    
    From 90b32e731b7899adf31067716883cbf483b6f72f Mon Sep 17 00:00:00 2001
    From: Tobias Bucher 
    Date: Mon, 12 Jan 2026 14:56:04 +0100
    Subject: [PATCH 2006/3801] Fix typo in `MaybeUninit` docs
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    –- → – (extra ASCII minus after endash)
    
    Introduced in https://github.com/rust-lang/rust/pull/140463 (11627f00c0599c5d033b3e38e3196786537c439b).
    ---
     library/core/src/mem/maybe_uninit.rs | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
    index e0001153a6e7..320eb97f83a4 100644
    --- a/library/core/src/mem/maybe_uninit.rs
    +++ b/library/core/src/mem/maybe_uninit.rs
    @@ -256,7 +256,7 @@ use crate::{fmt, intrinsics, ptr, slice};
     ///
     /// # Validity
     ///
    -/// `MaybeUninit` has no validity requirements –- any sequence of [bytes] of
    +/// `MaybeUninit` has no validity requirements – any sequence of [bytes] of
     /// the appropriate length, initialized or uninitialized, are a valid
     /// representation.
     ///
    
    From 50b60aaff331e6d938c18ee6d2f08691b36db9d0 Mon Sep 17 00:00:00 2001
    From: Ayush Singh 
    Date: Mon, 12 Jan 2026 11:31:20 +0530
    Subject: [PATCH 2007/3801] std: sys: net: uefi: Make TcpStream Send
    
    - Since UEFI has no threads, this should be safe.
    - Makes compiling remote-test-server simpler.
    
    Signed-off-by: Ayush Singh 
    ---
     library/std/src/sys/net/connection/uefi/tcp.rs | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs
    index 3e79aa049187..1e58db0d7046 100644
    --- a/library/std/src/sys/net/connection/uefi/tcp.rs
    +++ b/library/std/src/sys/net/connection/uefi/tcp.rs
    @@ -9,6 +9,9 @@ pub(crate) enum Tcp {
         V4(tcp4::Tcp4),
     }
     
    +// SAFETY: UEFI has no threads.
    +unsafe impl Send for Tcp {}
    +
     impl Tcp {
         pub(crate) fn connect(addr: &SocketAddr, timeout: Option) -> io::Result {
             match addr {
    
    From d2e8aaa42fd3a2107fecbfc700863469909fc996 Mon Sep 17 00:00:00 2001
    From: joboet 
    Date: Mon, 12 Jan 2026 17:16:49 +0100
    Subject: [PATCH 2008/3801] std: use `ByteStr`'s `Display` for `OsStr`
    
    ---
     library/std/src/sys/os_str/bytes.rs | 22 ++--------------------
     1 file changed, 2 insertions(+), 20 deletions(-)
    
    diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs
    index 7ba6c46eaef4..5482663ef007 100644
    --- a/library/std/src/sys/os_str/bytes.rs
    +++ b/library/std/src/sys/os_str/bytes.rs
    @@ -4,8 +4,8 @@
     use core::clone::CloneToUninit;
     
     use crate::borrow::Cow;
    +use crate::bstr::ByteStr;
     use crate::collections::TryReserveError;
    -use crate::fmt::Write;
     use crate::rc::Rc;
     use crate::sync::Arc;
     use crate::sys::{AsInner, FromInner, IntoInner};
    @@ -64,25 +64,7 @@ impl fmt::Debug for Slice {
     
     impl fmt::Display for Slice {
         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    -        // If we're the empty string then our iterator won't actually yield
    -        // anything, so perform the formatting manually
    -        if self.inner.is_empty() {
    -            return "".fmt(f);
    -        }
    -
    -        for chunk in self.inner.utf8_chunks() {
    -            let valid = chunk.valid();
    -            // If we successfully decoded the whole chunk as a valid string then
    -            // we can return a direct formatting of the string which will also
    -            // respect various formatting flags if possible.
    -            if chunk.invalid().is_empty() {
    -                return valid.fmt(f);
    -            }
    -
    -            f.write_str(valid)?;
    -            f.write_char(char::REPLACEMENT_CHARACTER)?;
    -        }
    -        Ok(())
    +        fmt::Display::fmt(ByteStr::new(&self.inner), f)
         }
     }
     
    
    From 3badf708c41402254349861d1a49cd3d9e128e99 Mon Sep 17 00:00:00 2001
    From: Dmitry Marakasov 
    Date: Mon, 8 Dec 2025 18:22:33 +0300
    Subject: [PATCH 2009/3801] Mention an extra argument required to check tests
    
    Add a note to tests-related lint descriptions that clippy needs to be
    run with e.g. `--tests` argument to actually check tests, which is not
    quite obvious.
    ---
     clippy_lints/src/attrs/mod.rs             | 4 ++++
     clippy_lints/src/redundant_test_prefix.rs | 4 ++++
     2 files changed, 8 insertions(+)
    
    diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs
    index 42c321df61c1..fa2951d91934 100644
    --- a/clippy_lints/src/attrs/mod.rs
    +++ b/clippy_lints/src/attrs/mod.rs
    @@ -468,6 +468,10 @@ declare_clippy_lint! {
         /// #[ignore = "Some good reason"]
         /// fn test() {}
         /// ```
    +    ///
    +    /// ### Note
    +    /// Clippy can only lint compiled code. For this lint to trigger, you must configure `cargo clippy`
    +    /// to include test compilation, for instance, by using flags such as `--tests` or `--all-targets`.
         #[clippy::version = "1.88.0"]
         pub IGNORE_WITHOUT_REASON,
         pedantic,
    diff --git a/clippy_lints/src/redundant_test_prefix.rs b/clippy_lints/src/redundant_test_prefix.rs
    index 84276e321657..602093259eae 100644
    --- a/clippy_lints/src/redundant_test_prefix.rs
    +++ b/clippy_lints/src/redundant_test_prefix.rs
    @@ -47,6 +47,10 @@ declare_clippy_lint! {
         ///   }
         /// }
         /// ```
    +    ///
    +    /// ### Note
    +    /// Clippy can only lint compiled code. For this lint to trigger, you must configure `cargo clippy`
    +    /// to include test compilation, for instance, by using flags such as `--tests` or `--all-targets`.
         #[clippy::version = "1.88.0"]
         pub REDUNDANT_TEST_PREFIX,
         restriction,
    
    From 439da0745347783ed5516caaccf3b96468ff858f Mon Sep 17 00:00:00 2001
    From: rustbot <47979223+rustbot@users.noreply.github.com>
    Date: Mon, 12 Jan 2026 18:01:10 +0100
    Subject: [PATCH 2010/3801] Update books
    
    ---
     src/doc/nomicon         | 2 +-
     src/doc/reference       | 2 +-
     src/doc/rust-by-example | 2 +-
     3 files changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/src/doc/nomicon b/src/doc/nomicon
    index 5b3a9d084cbc..050c002a360f 160000
    --- a/src/doc/nomicon
    +++ b/src/doc/nomicon
    @@ -1 +1 @@
    -Subproject commit 5b3a9d084cbc64e54da87e3eec7c7faae0e48ba9
    +Subproject commit 050c002a360fa45b701ea34feed7a860dc8a41bf
    diff --git a/src/doc/reference b/src/doc/reference
    index 6363385ac4eb..28b5a5441998 160000
    --- a/src/doc/reference
    +++ b/src/doc/reference
    @@ -1 +1 @@
    -Subproject commit 6363385ac4ebe1763f1e6fb2063c0b1db681a072
    +Subproject commit 28b5a54419985f03db5294de5eede71b6665b594
    diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
    index 2e02f22a10e7..8de6ff811315 160000
    --- a/src/doc/rust-by-example
    +++ b/src/doc/rust-by-example
    @@ -1 +1 @@
    -Subproject commit 2e02f22a10e7eeb758e6aba484f13d0f1988a3e5
    +Subproject commit 8de6ff811315ac3a96ebe01d74057382e42ffdee
    
    From 418cff3ec04a836490a71e9853b9fff48847d32e Mon Sep 17 00:00:00 2001
    From: Edvin Bryntesson 
    Date: Sun, 11 Jan 2026 00:23:45 +0100
    Subject: [PATCH 2011/3801] Port `#[must_not_suspend]` to attribute parser
    
    ---
     .../rustc_attr_parsing/src/attributes/mod.rs  |  1 +
     .../src/attributes/must_not_suspend.rs        | 35 +++++++++++++++++++
     compiler/rustc_attr_parsing/src/context.rs    |  3 +-
     .../rustc_hir/src/attrs/data_structures.rs    |  3 ++
     .../rustc_hir/src/attrs/encode_cross_crate.rs |  1 +
     compiler/rustc_mir_transform/src/coroutine.rs | 15 ++++----
     compiler/rustc_mir_transform/src/errors.rs    |  2 +-
     compiler/rustc_passes/messages.ftl            |  4 ---
     compiler/rustc_passes/src/check_attr.rs       | 12 +------
     compiler/rustc_passes/src/errors.rs           |  9 -----
     tests/ui/attributes/malformed-attrs.stderr    | 31 ++++++++--------
     tests/ui/lint/must_not_suspend/other_items.rs |  2 +-
     .../lint/must_not_suspend/other_items.stderr  |  6 ++--
     tests/ui/lint/must_not_suspend/return.rs      |  2 +-
     tests/ui/lint/must_not_suspend/return.stderr  | 12 +++----
     15 files changed, 77 insertions(+), 61 deletions(-)
     create mode 100644 compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs
    
    diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
    index fafac7ea909d..e02d71a26158 100644
    --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
    +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
    @@ -47,6 +47,7 @@ pub(crate) mod link_attrs;
     pub(crate) mod lint_helpers;
     pub(crate) mod loop_match;
     pub(crate) mod macro_attrs;
    +pub(crate) mod must_not_suspend;
     pub(crate) mod must_use;
     pub(crate) mod no_implicit_prelude;
     pub(crate) mod no_link;
    diff --git a/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs b/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs
    new file mode 100644
    index 000000000000..8456ce797758
    --- /dev/null
    +++ b/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs
    @@ -0,0 +1,35 @@
    +use super::prelude::*;
    +
    +pub(crate) struct MustNotSuspendParser;
    +
    +impl SingleAttributeParser for MustNotSuspendParser {
    +    const PATH: &[rustc_span::Symbol] = &[sym::must_not_suspend];
    +    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
    +    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
    +    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
    +        Allow(Target::Struct),
    +        Allow(Target::Enum),
    +        Allow(Target::Union),
    +        Allow(Target::Trait),
    +    ]);
    +    const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]);
    +
    +    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option {
    +        let reason = match args {
    +            ArgParser::NameValue(reason) => match reason.value_as_str() {
    +                Some(val) => Some(val),
    +                None => {
    +                    cx.expected_nv_or_no_args(reason.value_span);
    +                    return None;
    +                }
    +            },
    +            ArgParser::NoArgs => None,
    +            ArgParser::List(list) => {
    +                cx.expected_nv_or_no_args(list.span);
    +                return None;
    +            }
    +        };
    +
    +        Some(AttributeKind::MustNotSupend { reason })
    +    }
    +}
    diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
    index 835bf8ae5c9c..0217b6370408 100644
    --- a/compiler/rustc_attr_parsing/src/context.rs
    +++ b/compiler/rustc_attr_parsing/src/context.rs
    @@ -51,6 +51,7 @@ use crate::attributes::macro_attrs::{
         AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser,
         MacroUseParser,
     };
    +use crate::attributes::must_not_suspend::MustNotSuspendParser;
     use crate::attributes::must_use::MustUseParser;
     use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
     use crate::attributes::no_link::NoLinkParser;
    @@ -89,7 +90,6 @@ use crate::session_diagnostics::{
         AttributeParseError, AttributeParseErrorReason, ParsedDescription,
     };
     use crate::target_checking::AllowedTargets;
    -
     type GroupType = LazyLock>;
     
     pub(super) struct GroupTypeInner {
    @@ -208,6 +208,7 @@ attribute_parsers!(
             Single,
             Single,
             Single,
    +        Single,
             Single,
             Single,
             Single,
    diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
    index a5ecfa45fb40..b3c1974c0031 100644
    --- a/compiler/rustc_hir/src/attrs/data_structures.rs
    +++ b/compiler/rustc_hir/src/attrs/data_structures.rs
    @@ -824,6 +824,9 @@ pub enum AttributeKind {
         /// Represents `#[move_size_limit]`
         MoveSizeLimit { attr_span: Span, limit_span: Span, limit: Limit },
     
    +    /// Represents `#[must_not_suspend]`
    +    MustNotSupend { reason: Option },
    +
         /// Represents `#[must_use]`.
         MustUse {
             span: Span,
    diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    index efdb4f2f22b2..e02e954c94a5 100644
    --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    @@ -71,6 +71,7 @@ impl AttributeKind {
                 Marker(..) => No,
                 MayDangle(..) => No,
                 MoveSizeLimit { .. } => No,
    +            MustNotSupend { .. } => Yes,
                 MustUse { .. } => Yes,
                 Naked(..) => No,
                 NoCore(..) => No,
    diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
    index 7fad380ba5a1..705551c58f32 100644
    --- a/compiler/rustc_mir_transform/src/coroutine.rs
    +++ b/compiler/rustc_mir_transform/src/coroutine.rs
    @@ -64,9 +64,9 @@ use itertools::izip;
     use rustc_abi::{FieldIdx, VariantIdx};
     use rustc_data_structures::fx::FxHashSet;
     use rustc_errors::pluralize;
    -use rustc_hir as hir;
    +use rustc_hir::attrs::AttributeKind;
     use rustc_hir::lang_items::LangItem;
    -use rustc_hir::{CoroutineDesugaring, CoroutineKind};
    +use rustc_hir::{self as hir, CoroutineDesugaring, CoroutineKind, find_attr};
     use rustc_index::bit_set::{BitMatrix, DenseBitSet, GrowableBitSet};
     use rustc_index::{Idx, IndexVec, indexvec};
     use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
    @@ -85,7 +85,6 @@ use rustc_mir_dataflow::{
     };
     use rustc_span::def_id::{DefId, LocalDefId};
     use rustc_span::source_map::dummy_spanned;
    -use rustc_span::symbol::sym;
     use rustc_span::{DUMMY_SP, Span};
     use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
     use rustc_trait_selection::infer::TyCtxtInferExt as _;
    @@ -1989,11 +1988,11 @@ fn check_must_not_suspend_def(
         hir_id: hir::HirId,
         data: SuspendCheckData<'_>,
     ) -> bool {
    -    if let Some(attr) = tcx.get_attr(def_id, sym::must_not_suspend) {
    -        let reason = attr.value_str().map(|s| errors::MustNotSuspendReason {
    -            span: data.source_span,
    -            reason: s.as_str().to_string(),
    -        });
    +    if let Some(reason_str) =
    +        find_attr!(tcx.get_all_attrs(def_id), AttributeKind::MustNotSupend {reason} => reason)
    +    {
    +        let reason =
    +            reason_str.map(|s| errors::MustNotSuspendReason { span: data.source_span, reason: s });
             tcx.emit_node_span_lint(
                 rustc_session::lint::builtin::MUST_NOT_SUSPEND,
                 hir_id,
    diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
    index 21a6c4d653bc..d4c58f7fe05d 100644
    --- a/compiler/rustc_mir_transform/src/errors.rs
    +++ b/compiler/rustc_mir_transform/src/errors.rs
    @@ -323,7 +323,7 @@ impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> {
     pub(crate) struct MustNotSuspendReason {
         #[primary_span]
         pub span: Span,
    -    pub reason: String,
    +    pub reason: Symbol,
     }
     
     #[derive(Diagnostic)]
    diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
    index 39ad541ee85a..9628e6d4efe9 100644
    --- a/compiler/rustc_passes/messages.ftl
    +++ b/compiler/rustc_passes/messages.ftl
    @@ -376,10 +376,6 @@ passes_must_implement_not_function_note = all `#[rustc_must_implement_one_of]` a
     
     passes_must_implement_not_function_span_note = required by this annotation
     
    -passes_must_not_suspend =
    -    `must_not_suspend` attribute should be applied to a struct, enum, union, or trait
    -    .label = is not a struct, enum, union, or trait
    -
     passes_no_main_function =
         `main` function not found in crate `{$crate_name}`
         .here_is_main = here is a function named `main`
    diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
    index 717a0e54d0c6..c9357b99cea2 100644
    --- a/compiler/rustc_passes/src/check_attr.rs
    +++ b/compiler/rustc_passes/src/check_attr.rs
    @@ -308,6 +308,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         | AttributeKind::ThreadLocal
                         | AttributeKind::CfiEncoding { .. }
                         | AttributeKind::RustcHasIncoherentInherentImpls
    +                    | AttributeKind::MustNotSupend { .. }
                     ) => { /* do nothing  */ }
                     Attribute::Unparsed(attr_item) => {
                         style = Some(attr_item.style);
    @@ -325,7 +326,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             | [sym::rustc_dirty, ..]
                             | [sym::rustc_if_this_changed, ..]
                             | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr),
    -                        [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
                             [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => {
                                 self.check_autodiff(hir_id, attr, span, target)
                             }
    @@ -1197,16 +1197,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             }
         }
     
    -    /// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait.
    -    fn check_must_not_suspend(&self, attr: &Attribute, span: Span, target: Target) {
    -        match target {
    -            Target::Struct | Target::Enum | Target::Union | Target::Trait => {}
    -            _ => {
    -                self.dcx().emit_err(errors::MustNotSuspend { attr_span: attr.span(), span });
    -            }
    -        }
    -    }
    -
         /// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
         fn check_may_dangle(&self, hir_id: HirId, attr_span: Span) {
             if let hir::Node::GenericParam(param) = self.tcx.hir_node(hir_id)
    diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
    index ace738c559a4..49b9618ef2af 100644
    --- a/compiler/rustc_passes/src/errors.rs
    +++ b/compiler/rustc_passes/src/errors.rs
    @@ -194,15 +194,6 @@ pub(crate) struct BothFfiConstAndPure {
         pub attr_span: Span,
     }
     
    -#[derive(Diagnostic)]
    -#[diag(passes_must_not_suspend)]
    -pub(crate) struct MustNotSuspend {
    -    #[primary_span]
    -    pub attr_span: Span,
    -    #[label]
    -    pub span: Span,
    -}
    -
     #[derive(LintDiagnostic)]
     #[diag(passes_link)]
     #[warning]
    diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr
    index fd6f34fb45e2..fc644668735e 100644
    --- a/tests/ui/attributes/malformed-attrs.stderr
    +++ b/tests/ui/attributes/malformed-attrs.stderr
    @@ -32,21 +32,6 @@ error: malformed `patchable_function_entry` attribute input
     LL | #[patchable_function_entry]
        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
     
    -error: malformed `must_not_suspend` attribute input
    -  --> $DIR/malformed-attrs.rs:138:1
    -   |
    -LL | #[must_not_suspend()]
    -   | ^^^^^^^^^^^^^^^^^^^^^
    -   |
    -help: the following are the possible correct uses
    -   |
    -LL - #[must_not_suspend()]
    -LL + #[must_not_suspend = "reason"]
    -   |
    -LL - #[must_not_suspend()]
    -LL + #[must_not_suspend]
    -   |
    -
     error: malformed `allow` attribute input
       --> $DIR/malformed-attrs.rs:184:1
        |
    @@ -527,6 +512,22 @@ LL | #[rustc_layout_scalar_valid_range_end]
        | expected this to be a list
        | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]`
     
    +error[E0539]: malformed `must_not_suspend` attribute input
    +  --> $DIR/malformed-attrs.rs:138:1
    +   |
    +LL | #[must_not_suspend()]
    +   | ^^^^^^^^^^^^^^^^^^--^
    +   |                   |
    +   |                   didn't expect a list here
    +   |
    +help: try changing it to one of the following valid forms of the attribute
    +   |
    +LL | #[must_not_suspend(count)]
    +   |                    +++++
    +LL - #[must_not_suspend()]
    +LL + #[must_not_suspend]
    +   |
    +
     error[E0539]: malformed `cfi_encoding` attribute input
       --> $DIR/malformed-attrs.rs:140:1
        |
    diff --git a/tests/ui/lint/must_not_suspend/other_items.rs b/tests/ui/lint/must_not_suspend/other_items.rs
    index 7a42a2bba03b..1c46cce7ed3a 100644
    --- a/tests/ui/lint/must_not_suspend/other_items.rs
    +++ b/tests/ui/lint/must_not_suspend/other_items.rs
    @@ -2,7 +2,7 @@
     #![feature(must_not_suspend)]
     #![deny(must_not_suspend)]
     
    -#[must_not_suspend] //~ ERROR attribute should be
    +#[must_not_suspend] //~ ERROR attribute cannot be used on modules
     mod inner {}
     
     fn main() {}
    diff --git a/tests/ui/lint/must_not_suspend/other_items.stderr b/tests/ui/lint/must_not_suspend/other_items.stderr
    index dff5210b7e47..999a9d2fb3dc 100644
    --- a/tests/ui/lint/must_not_suspend/other_items.stderr
    +++ b/tests/ui/lint/must_not_suspend/other_items.stderr
    @@ -1,10 +1,10 @@
    -error: `must_not_suspend` attribute should be applied to a struct, enum, union, or trait
    +error: `#[must_not_suspend]` attribute cannot be used on modules
       --> $DIR/other_items.rs:5:1
        |
     LL | #[must_not_suspend]
        | ^^^^^^^^^^^^^^^^^^^
    -LL | mod inner {}
    -   | ------------ is not a struct, enum, union, or trait
    +   |
    +   = help: `#[must_not_suspend]` can be applied to data types, traits, and unions
     
     error: aborting due to 1 previous error
     
    diff --git a/tests/ui/lint/must_not_suspend/return.rs b/tests/ui/lint/must_not_suspend/return.rs
    index a04f6a4cfb43..de78ee0f9299 100644
    --- a/tests/ui/lint/must_not_suspend/return.rs
    +++ b/tests/ui/lint/must_not_suspend/return.rs
    @@ -2,7 +2,7 @@
     #![feature(must_not_suspend)]
     #![deny(must_not_suspend)]
     
    -#[must_not_suspend] //~ ERROR attribute should be
    +#[must_not_suspend] //~ ERROR attribute cannot be used on functions
     fn foo() -> i32 {
         0
     }
    diff --git a/tests/ui/lint/must_not_suspend/return.stderr b/tests/ui/lint/must_not_suspend/return.stderr
    index 440f81656862..1a81b1a39f0c 100644
    --- a/tests/ui/lint/must_not_suspend/return.stderr
    +++ b/tests/ui/lint/must_not_suspend/return.stderr
    @@ -1,12 +1,10 @@
    -error: `must_not_suspend` attribute should be applied to a struct, enum, union, or trait
    +error: `#[must_not_suspend]` attribute cannot be used on functions
       --> $DIR/return.rs:5:1
        |
    -LL |   #[must_not_suspend]
    -   |   ^^^^^^^^^^^^^^^^^^^
    -LL | / fn foo() -> i32 {
    -LL | |     0
    -LL | | }
    -   | |_- is not a struct, enum, union, or trait
    +LL | #[must_not_suspend]
    +   | ^^^^^^^^^^^^^^^^^^^
    +   |
    +   = help: `#[must_not_suspend]` can be applied to data types, traits, and unions
     
     error: aborting due to 1 previous error
     
    
    From 78952f6aaa56544d1ab9ce3c18a97e34ea1f390b Mon Sep 17 00:00:00 2001
    From: Jamie Cunliffe 
    Date: Tue, 9 Dec 2025 16:33:40 +0000
    Subject: [PATCH 2012/3801] Mark the neon intrinsics as inline(always).
    
    The inline(always) attribute is now applied to the call site when a
    function has target features enabled so that it can determine that the
    call is safe to inline.
    ---
     .../core_arch/src/aarch64/neon/generated.rs   | 3892 +++++-----
     .../src/arm_shared/neon/generated.rs          | 6530 ++++++++---------
     library/stdarch/crates/core_arch/src/lib.rs   |    1 +
     .../crates/stdarch-gen-arm/src/intrinsic.rs   |    2 +-
     4 files changed, 5213 insertions(+), 5212 deletions(-)
    
    diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
    index 7743e52f4fe1..23b44294aa8f 100644
    --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
    +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
    @@ -14,7 +14,7 @@ use super::*;
     
     #[doc = "CRC32-C single round checksum for quad words (64 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cd)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg_attr(test, assert_instr(crc32cx))]
     #[stable(feature = "stdarch_aarch64_crc32", since = "1.80.0")]
    @@ -30,7 +30,7 @@ pub fn __crc32cd(crc: u32, data: u64) -> u32 {
     }
     #[doc = "CRC32 single round checksum for quad words (64 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg_attr(test, assert_instr(crc32x))]
     #[stable(feature = "stdarch_aarch64_crc32", since = "1.80.0")]
    @@ -46,7 +46,7 @@ pub fn __crc32d(crc: u32, data: u64) -> u32 {
     }
     #[doc = "Floating-point JavaScript convert to signed fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__jcvt)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "jsconv")]
     #[cfg_attr(test, assert_instr(fjcvtzs))]
     #[unstable(feature = "stdarch_aarch64_jscvt", issue = "147555")]
    @@ -62,7 +62,7 @@ pub fn __jcvt(a: f64) -> i32 {
     }
     #[doc = "Signed Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(sabal2))]
    @@ -77,7 +77,7 @@ pub fn vabal_high_s8(a: int16x8_t, b: int8x16_t, c: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(sabal2))]
    @@ -92,7 +92,7 @@ pub fn vabal_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(sabal2))]
    @@ -107,7 +107,7 @@ pub fn vabal_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int64x2_t {
     }
     #[doc = "Unsigned Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uabal2))]
    @@ -121,7 +121,7 @@ pub fn vabal_high_u8(a: uint16x8_t, b: uint8x16_t, c: uint8x16_t) -> uint16x8_t
     }
     #[doc = "Unsigned Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uabal2))]
    @@ -135,7 +135,7 @@ pub fn vabal_high_u16(a: uint32x4_t, b: uint16x8_t, c: uint16x8_t) -> uint32x4_t
     }
     #[doc = "Unsigned Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uabal2))]
    @@ -149,7 +149,7 @@ pub fn vabal_high_u32(a: uint64x2_t, b: uint32x4_t, c: uint32x4_t) -> uint64x2_t
     }
     #[doc = "Absolute difference between the arguments of Floating"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fabd))]
    @@ -165,7 +165,7 @@ pub fn vabd_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Absolute difference between the arguments of Floating"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fabd))]
    @@ -181,7 +181,7 @@ pub fn vabdq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point absolute difference"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fabd))]
    @@ -190,7 +190,7 @@ pub fn vabdd_f64(a: f64, b: f64) -> f64 {
     }
     #[doc = "Floating-point absolute difference"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabds_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fabd))]
    @@ -199,7 +199,7 @@ pub fn vabds_f32(a: f32, b: f32) -> f32 {
     }
     #[doc = "Floating-point absolute difference"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -209,7 +209,7 @@ pub fn vabdh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Signed Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sabdl2))]
    @@ -223,7 +223,7 @@ pub fn vabdl_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sabdl2))]
    @@ -237,7 +237,7 @@ pub fn vabdl_high_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t {
     }
     #[doc = "Signed Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sabdl2))]
    @@ -251,7 +251,7 @@ pub fn vabdl_high_s8(a: int8x16_t, b: int8x16_t) -> int16x8_t {
     }
     #[doc = "Unsigned Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uabdl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -264,7 +264,7 @@ pub fn vabdl_high_u8(a: uint8x16_t, b: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uabdl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -277,7 +277,7 @@ pub fn vabdl_high_u16(a: uint16x8_t, b: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uabdl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -290,7 +290,7 @@ pub fn vabdl_high_u32(a: uint32x4_t, b: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Floating-point absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabs_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fabs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -299,7 +299,7 @@ pub fn vabs_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fabs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -308,7 +308,7 @@ pub fn vabsq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Absolute Value (wrapping)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabs_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(abs))]
    @@ -321,7 +321,7 @@ pub fn vabs_s64(a: int64x1_t) -> int64x1_t {
     }
     #[doc = "Absolute Value (wrapping)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(abs))]
    @@ -334,7 +334,7 @@ pub fn vabsq_s64(a: int64x2_t) -> int64x2_t {
     }
     #[doc = "Absolute Value (wrapping)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(abs))]
    @@ -350,7 +350,7 @@ pub fn vabsd_s64(a: i64) -> i64 {
     }
     #[doc = "Add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -359,7 +359,7 @@ pub fn vaddd_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -368,7 +368,7 @@ pub fn vaddd_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Signed Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(saddlv))]
    @@ -384,7 +384,7 @@ pub fn vaddlv_s16(a: int16x4_t) -> i32 {
     }
     #[doc = "Signed Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(saddlv))]
    @@ -400,7 +400,7 @@ pub fn vaddlvq_s16(a: int16x8_t) -> i32 {
     }
     #[doc = "Signed Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(saddlv))]
    @@ -416,7 +416,7 @@ pub fn vaddlvq_s32(a: int32x4_t) -> i64 {
     }
     #[doc = "Signed Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(saddlp))]
    @@ -432,7 +432,7 @@ pub fn vaddlv_s32(a: int32x2_t) -> i64 {
     }
     #[doc = "Signed Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(saddlv))]
    @@ -448,7 +448,7 @@ pub fn vaddlv_s8(a: int8x8_t) -> i16 {
     }
     #[doc = "Signed Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(saddlv))]
    @@ -464,7 +464,7 @@ pub fn vaddlvq_s8(a: int8x16_t) -> i16 {
     }
     #[doc = "Unsigned Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uaddlv))]
    @@ -480,7 +480,7 @@ pub fn vaddlv_u16(a: uint16x4_t) -> u32 {
     }
     #[doc = "Unsigned Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uaddlv))]
    @@ -496,7 +496,7 @@ pub fn vaddlvq_u16(a: uint16x8_t) -> u32 {
     }
     #[doc = "Unsigned Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uaddlv))]
    @@ -512,7 +512,7 @@ pub fn vaddlvq_u32(a: uint32x4_t) -> u64 {
     }
     #[doc = "Unsigned Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uaddlp))]
    @@ -528,7 +528,7 @@ pub fn vaddlv_u32(a: uint32x2_t) -> u64 {
     }
     #[doc = "Unsigned Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlv_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uaddlv))]
    @@ -544,7 +544,7 @@ pub fn vaddlv_u8(a: uint8x8_t) -> u16 {
     }
     #[doc = "Unsigned Add Long across Vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddlvq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uaddlv))]
    @@ -560,7 +560,7 @@ pub fn vaddlvq_u8(a: uint8x16_t) -> u16 {
     }
     #[doc = "Floating-point add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(faddp))]
    @@ -576,7 +576,7 @@ pub fn vaddv_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Floating-point add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(faddp))]
    @@ -592,7 +592,7 @@ pub fn vaddvq_f32(a: float32x4_t) -> f32 {
     }
     #[doc = "Floating-point add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(faddp))]
    @@ -608,7 +608,7 @@ pub fn vaddvq_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -617,7 +617,7 @@ pub fn vaddv_s32(a: int32x2_t) -> i32 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -626,7 +626,7 @@ pub fn vaddv_s8(a: int8x8_t) -> i8 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -635,7 +635,7 @@ pub fn vaddvq_s8(a: int8x16_t) -> i8 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -644,7 +644,7 @@ pub fn vaddv_s16(a: int16x4_t) -> i16 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -653,7 +653,7 @@ pub fn vaddvq_s16(a: int16x8_t) -> i16 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -662,7 +662,7 @@ pub fn vaddvq_s32(a: int32x4_t) -> i32 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -671,7 +671,7 @@ pub fn vaddv_u32(a: uint32x2_t) -> u32 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -680,7 +680,7 @@ pub fn vaddv_u8(a: uint8x8_t) -> u8 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -689,7 +689,7 @@ pub fn vaddvq_u8(a: uint8x16_t) -> u8 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -698,7 +698,7 @@ pub fn vaddv_u16(a: uint16x4_t) -> u16 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -707,7 +707,7 @@ pub fn vaddvq_u16(a: uint16x8_t) -> u16 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addv))]
    @@ -716,7 +716,7 @@ pub fn vaddvq_u32(a: uint32x4_t) -> u32 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -725,7 +725,7 @@ pub fn vaddvq_s64(a: int64x2_t) -> i64 {
     }
     #[doc = "Add across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -734,7 +734,7 @@ pub fn vaddvq_u64(a: uint64x2_t) -> u64 {
     }
     #[doc = "Multi-vector floating-point absolute maximum"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vamax_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,faminmax")]
     #[cfg_attr(test, assert_instr(nop))]
     #[unstable(feature = "faminmax", issue = "137933")]
    @@ -750,7 +750,7 @@ pub fn vamax_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Multi-vector floating-point absolute maximum"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vamaxq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,faminmax")]
     #[cfg_attr(test, assert_instr(nop))]
     #[unstable(feature = "faminmax", issue = "137933")]
    @@ -766,7 +766,7 @@ pub fn vamaxq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Multi-vector floating-point absolute maximum"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vamaxq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,faminmax")]
     #[cfg_attr(test, assert_instr(nop))]
     #[unstable(feature = "faminmax", issue = "137933")]
    @@ -782,7 +782,7 @@ pub fn vamaxq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Multi-vector floating-point absolute minimum"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vamin_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,faminmax")]
     #[cfg_attr(test, assert_instr(nop))]
     #[unstable(feature = "faminmax", issue = "137933")]
    @@ -798,7 +798,7 @@ pub fn vamin_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Multi-vector floating-point absolute minimum"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaminq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,faminmax")]
     #[cfg_attr(test, assert_instr(nop))]
     #[unstable(feature = "faminmax", issue = "137933")]
    @@ -814,7 +814,7 @@ pub fn vaminq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Multi-vector floating-point absolute minimum"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaminq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,faminmax")]
     #[cfg_attr(test, assert_instr(nop))]
     #[unstable(feature = "faminmax", issue = "137933")]
    @@ -830,7 +830,7 @@ pub fn vaminq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Bit clear and exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(bcax))]
    @@ -846,7 +846,7 @@ pub fn vbcaxq_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
     }
     #[doc = "Bit clear and exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(bcax))]
    @@ -862,7 +862,7 @@ pub fn vbcaxq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
     }
     #[doc = "Bit clear and exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(bcax))]
    @@ -878,7 +878,7 @@ pub fn vbcaxq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
     }
     #[doc = "Bit clear and exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(bcax))]
    @@ -894,7 +894,7 @@ pub fn vbcaxq_s64(a: int64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t {
     }
     #[doc = "Bit clear and exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(bcax))]
    @@ -910,7 +910,7 @@ pub fn vbcaxq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Bit clear and exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(bcax))]
    @@ -926,7 +926,7 @@ pub fn vbcaxq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Bit clear and exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(bcax))]
    @@ -942,7 +942,7 @@ pub fn vbcaxq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Bit clear and exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbcaxq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(bcax))]
    @@ -958,7 +958,7 @@ pub fn vbcaxq_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcadd_rot270_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fcma"))]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -976,7 +976,7 @@ pub fn vcadd_rot270_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot270_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fcma"))]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -994,7 +994,7 @@ pub fn vcaddq_rot270_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcadd_rot270_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcadd))]
    @@ -1010,7 +1010,7 @@ pub fn vcadd_rot270_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot270_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcadd))]
    @@ -1026,7 +1026,7 @@ pub fn vcaddq_rot270_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot270_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcadd))]
    @@ -1042,7 +1042,7 @@ pub fn vcaddq_rot270_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcadd_rot90_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fcma"))]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -1060,7 +1060,7 @@ pub fn vcadd_rot90_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot90_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fcma"))]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -1078,7 +1078,7 @@ pub fn vcaddq_rot90_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcadd_rot90_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcadd))]
    @@ -1094,7 +1094,7 @@ pub fn vcadd_rot90_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot90_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcadd))]
    @@ -1110,7 +1110,7 @@ pub fn vcaddq_rot90_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point complex add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaddq_rot90_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcadd))]
    @@ -1126,7 +1126,7 @@ pub fn vcaddq_rot90_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point absolute compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcage_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1142,7 +1142,7 @@ pub fn vcage_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point absolute compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcageq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1158,7 +1158,7 @@ pub fn vcageq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point absolute compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaged_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1174,7 +1174,7 @@ pub fn vcaged_f64(a: f64, b: f64) -> u64 {
     }
     #[doc = "Floating-point absolute compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcages_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1190,7 +1190,7 @@ pub fn vcages_f32(a: f32, b: f32) -> u32 {
     }
     #[doc = "Floating-point absolute compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcageh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(facge))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -1207,7 +1207,7 @@ pub fn vcageh_f16(a: f16, b: f16) -> u16 {
     }
     #[doc = "Floating-point absolute compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagt_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1223,7 +1223,7 @@ pub fn vcagt_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point absolute compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagtq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1239,7 +1239,7 @@ pub fn vcagtq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point absolute compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagtd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1255,7 +1255,7 @@ pub fn vcagtd_f64(a: f64, b: f64) -> u64 {
     }
     #[doc = "Floating-point absolute compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagts_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1271,7 +1271,7 @@ pub fn vcagts_f32(a: f32, b: f32) -> u32 {
     }
     #[doc = "Floating-point absolute compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagth_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(facgt))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -1288,7 +1288,7 @@ pub fn vcagth_f16(a: f16, b: f16) -> u16 {
     }
     #[doc = "Floating-point absolute compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcale_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1297,7 +1297,7 @@ pub fn vcale_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point absolute compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaleq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1306,7 +1306,7 @@ pub fn vcaleq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point absolute compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaled_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1315,7 +1315,7 @@ pub fn vcaled_f64(a: f64, b: f64) -> u64 {
     }
     #[doc = "Floating-point absolute compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcales_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1324,7 +1324,7 @@ pub fn vcales_f32(a: f32, b: f32) -> u32 {
     }
     #[doc = "Floating-point absolute compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaleh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(facge))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -1334,7 +1334,7 @@ pub fn vcaleh_f16(a: f16, b: f16) -> u16 {
     }
     #[doc = "Floating-point absolute compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcalt_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1343,7 +1343,7 @@ pub fn vcalt_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point absolute compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaltq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1352,7 +1352,7 @@ pub fn vcaltq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point absolute compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaltd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1361,7 +1361,7 @@ pub fn vcaltd_f64(a: f64, b: f64) -> u64 {
     }
     #[doc = "Floating-point absolute compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcalts_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(facgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1370,7 +1370,7 @@ pub fn vcalts_f32(a: f32, b: f32) -> u32 {
     }
     #[doc = "Floating-point absolute compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcalth_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(facgt))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -1380,7 +1380,7 @@ pub fn vcalth_f16(a: f16, b: f16) -> u16 {
     }
     #[doc = "Floating-point compare equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1389,7 +1389,7 @@ pub fn vceq_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1398,7 +1398,7 @@ pub fn vceqq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1407,7 +1407,7 @@ pub fn vceq_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1416,7 +1416,7 @@ pub fn vceqq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1425,7 +1425,7 @@ pub fn vceq_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1434,7 +1434,7 @@ pub fn vceqq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1443,7 +1443,7 @@ pub fn vceq_p64(a: poly64x1_t, b: poly64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1452,7 +1452,7 @@ pub fn vceqq_p64(a: poly64x2_t, b: poly64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point compare equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1461,7 +1461,7 @@ pub fn vceqd_f64(a: f64, b: f64) -> u64 {
     }
     #[doc = "Floating-point compare equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1470,7 +1470,7 @@ pub fn vceqs_f32(a: f32, b: f32) -> u32 {
     }
     #[doc = "Compare bitwise equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1479,7 +1479,7 @@ pub fn vceqd_s64(a: i64, b: i64) -> u64 {
     }
     #[doc = "Compare bitwise equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1488,7 +1488,7 @@ pub fn vceqd_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Floating-point compare equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -1498,7 +1498,7 @@ pub fn vceqh_f16(a: f16, b: f16) -> u16 {
     }
     #[doc = "Floating-point compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmeq))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -1509,7 +1509,7 @@ pub fn vceqz_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmeq))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -1520,7 +1520,7 @@ pub fn vceqzq_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1530,7 +1530,7 @@ pub fn vceqz_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1540,7 +1540,7 @@ pub fn vceqzq_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1550,7 +1550,7 @@ pub fn vceqz_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1560,7 +1560,7 @@ pub fn vceqzq_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1570,7 +1570,7 @@ pub fn vceqz_s8(a: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1580,7 +1580,7 @@ pub fn vceqzq_s8(a: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1590,7 +1590,7 @@ pub fn vceqz_s16(a: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1600,7 +1600,7 @@ pub fn vceqzq_s16(a: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1610,7 +1610,7 @@ pub fn vceqz_s32(a: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1620,7 +1620,7 @@ pub fn vceqzq_s32(a: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1630,7 +1630,7 @@ pub fn vceqz_s64(a: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1640,7 +1640,7 @@ pub fn vceqzq_s64(a: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1650,7 +1650,7 @@ pub fn vceqz_p8(a: poly8x8_t) -> uint8x8_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1660,7 +1660,7 @@ pub fn vceqzq_p8(a: poly8x16_t) -> uint8x16_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1670,7 +1670,7 @@ pub fn vceqz_p64(a: poly64x1_t) -> uint64x1_t {
     }
     #[doc = "Signed compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1680,7 +1680,7 @@ pub fn vceqzq_p64(a: poly64x2_t) -> uint64x2_t {
     }
     #[doc = "Unsigned compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1690,7 +1690,7 @@ pub fn vceqz_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1700,7 +1700,7 @@ pub fn vceqzq_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1710,7 +1710,7 @@ pub fn vceqz_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1720,7 +1720,7 @@ pub fn vceqzq_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1730,7 +1730,7 @@ pub fn vceqz_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1740,7 +1740,7 @@ pub fn vceqzq_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqz_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1750,7 +1750,7 @@ pub fn vceqz_u64(a: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmeq))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1760,7 +1760,7 @@ pub fn vceqzq_u64(a: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1769,7 +1769,7 @@ pub fn vceqzd_s64(a: i64) -> u64 {
     }
     #[doc = "Compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1778,7 +1778,7 @@ pub fn vceqzd_u64(a: u64) -> u64 {
     }
     #[doc = "Floating-point compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -1788,7 +1788,7 @@ pub fn vceqzh_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1797,7 +1797,7 @@ pub fn vceqzs_f32(a: f32) -> u32 {
     }
     #[doc = "Floating-point compare bitwise equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqzd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1806,7 +1806,7 @@ pub fn vceqzd_f64(a: f64) -> u64 {
     }
     #[doc = "Floating-point compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1815,7 +1815,7 @@ pub fn vcge_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1824,7 +1824,7 @@ pub fn vcgeq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare signed greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1833,7 +1833,7 @@ pub fn vcge_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare signed greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1842,7 +1842,7 @@ pub fn vcgeq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare unsigned greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmhs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1851,7 +1851,7 @@ pub fn vcge_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare unsigned greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmhs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1860,7 +1860,7 @@ pub fn vcgeq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcged_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1869,7 +1869,7 @@ pub fn vcged_f64(a: f64, b: f64) -> u64 {
     }
     #[doc = "Floating-point compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcges_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1878,7 +1878,7 @@ pub fn vcges_f32(a: f32, b: f32) -> u32 {
     }
     #[doc = "Compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcged_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1887,7 +1887,7 @@ pub fn vcged_s64(a: i64, b: i64) -> u64 {
     }
     #[doc = "Compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcged_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1896,7 +1896,7 @@ pub fn vcged_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Floating-point compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -1906,7 +1906,7 @@ pub fn vcgeh_f16(a: f16, b: f16) -> u16 {
     }
     #[doc = "Floating-point compare greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1916,7 +1916,7 @@ pub fn vcgez_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1926,7 +1926,7 @@ pub fn vcgezq_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1936,7 +1936,7 @@ pub fn vcgez_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1946,7 +1946,7 @@ pub fn vcgezq_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare signed greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1956,7 +1956,7 @@ pub fn vcgez_s8(a: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare signed greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1966,7 +1966,7 @@ pub fn vcgezq_s8(a: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare signed greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1976,7 +1976,7 @@ pub fn vcgez_s16(a: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare signed greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1986,7 +1986,7 @@ pub fn vcgezq_s16(a: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare signed greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -1996,7 +1996,7 @@ pub fn vcgez_s32(a: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare signed greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2006,7 +2006,7 @@ pub fn vcgezq_s32(a: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare signed greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2016,7 +2016,7 @@ pub fn vcgez_s64(a: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare signed greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2026,7 +2026,7 @@ pub fn vcgezq_s64(a: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point compare greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2035,7 +2035,7 @@ pub fn vcgezd_f64(a: f64) -> u64 {
     }
     #[doc = "Floating-point compare greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2044,7 +2044,7 @@ pub fn vcgezs_f32(a: f32) -> u32 {
     }
     #[doc = "Compare signed greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2053,7 +2053,7 @@ pub fn vcgezd_s64(a: i64) -> u64 {
     }
     #[doc = "Floating-point compare greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -2063,7 +2063,7 @@ pub fn vcgezh_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2072,7 +2072,7 @@ pub fn vcgt_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2081,7 +2081,7 @@ pub fn vcgtq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare signed greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2090,7 +2090,7 @@ pub fn vcgt_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare signed greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2099,7 +2099,7 @@ pub fn vcgtq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare unsigned greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmhi))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2108,7 +2108,7 @@ pub fn vcgt_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare unsigned greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmhi))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2117,7 +2117,7 @@ pub fn vcgtq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2126,7 +2126,7 @@ pub fn vcgtd_f64(a: f64, b: f64) -> u64 {
     }
     #[doc = "Floating-point compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgts_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2135,7 +2135,7 @@ pub fn vcgts_f32(a: f32, b: f32) -> u32 {
     }
     #[doc = "Compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2144,7 +2144,7 @@ pub fn vcgtd_s64(a: i64, b: i64) -> u64 {
     }
     #[doc = "Compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2153,7 +2153,7 @@ pub fn vcgtd_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Floating-point compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgth_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -2163,7 +2163,7 @@ pub fn vcgth_f16(a: f16, b: f16) -> u16 {
     }
     #[doc = "Floating-point compare greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2173,7 +2173,7 @@ pub fn vcgtz_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2183,7 +2183,7 @@ pub fn vcgtzq_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2193,7 +2193,7 @@ pub fn vcgtz_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2203,7 +2203,7 @@ pub fn vcgtzq_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare signed greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2213,7 +2213,7 @@ pub fn vcgtz_s8(a: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare signed greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2223,7 +2223,7 @@ pub fn vcgtzq_s8(a: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare signed greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2233,7 +2233,7 @@ pub fn vcgtz_s16(a: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare signed greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2243,7 +2243,7 @@ pub fn vcgtzq_s16(a: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare signed greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2253,7 +2253,7 @@ pub fn vcgtz_s32(a: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare signed greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2263,7 +2263,7 @@ pub fn vcgtzq_s32(a: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare signed greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2273,7 +2273,7 @@ pub fn vcgtz_s64(a: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare signed greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2283,7 +2283,7 @@ pub fn vcgtzq_s64(a: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point compare greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2292,7 +2292,7 @@ pub fn vcgtzd_f64(a: f64) -> u64 {
     }
     #[doc = "Floating-point compare greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2301,7 +2301,7 @@ pub fn vcgtzs_f32(a: f32) -> u32 {
     }
     #[doc = "Compare signed greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2310,7 +2310,7 @@ pub fn vcgtzd_s64(a: i64) -> u64 {
     }
     #[doc = "Floating-point compare greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -2320,7 +2320,7 @@ pub fn vcgtzh_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2329,7 +2329,7 @@ pub fn vcle_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2338,7 +2338,7 @@ pub fn vcleq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare signed less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2347,7 +2347,7 @@ pub fn vcle_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare signed less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmge))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2356,7 +2356,7 @@ pub fn vcleq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare unsigned less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmhs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2365,7 +2365,7 @@ pub fn vcle_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare unsigned less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmhs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2374,7 +2374,7 @@ pub fn vcleq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcled_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2383,7 +2383,7 @@ pub fn vcled_f64(a: f64, b: f64) -> u64 {
     }
     #[doc = "Floating-point compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcles_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2392,7 +2392,7 @@ pub fn vcles_f32(a: f32, b: f32) -> u32 {
     }
     #[doc = "Compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcled_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2401,7 +2401,7 @@ pub fn vcled_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcled_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2410,7 +2410,7 @@ pub fn vcled_s64(a: i64, b: i64) -> u64 {
     }
     #[doc = "Floating-point compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -2420,7 +2420,7 @@ pub fn vcleh_f16(a: f16, b: f16) -> u16 {
     }
     #[doc = "Floating-point compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2430,7 +2430,7 @@ pub fn vclez_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2440,7 +2440,7 @@ pub fn vclezq_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2450,7 +2450,7 @@ pub fn vclez_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2460,7 +2460,7 @@ pub fn vclezq_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare signed less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2470,7 +2470,7 @@ pub fn vclez_s8(a: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare signed less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2480,7 +2480,7 @@ pub fn vclezq_s8(a: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare signed less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2490,7 +2490,7 @@ pub fn vclez_s16(a: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare signed less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2500,7 +2500,7 @@ pub fn vclezq_s16(a: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare signed less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2510,7 +2510,7 @@ pub fn vclez_s32(a: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare signed less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2520,7 +2520,7 @@ pub fn vclezq_s32(a: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare signed less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2530,7 +2530,7 @@ pub fn vclez_s64(a: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare signed less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmle))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2540,7 +2540,7 @@ pub fn vclezq_s64(a: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2549,7 +2549,7 @@ pub fn vclezd_f64(a: f64) -> u64 {
     }
     #[doc = "Floating-point compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2558,7 +2558,7 @@ pub fn vclezs_f32(a: f32) -> u32 {
     }
     #[doc = "Compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2567,7 +2567,7 @@ pub fn vclezd_s64(a: i64) -> u64 {
     }
     #[doc = "Floating-point compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -2577,7 +2577,7 @@ pub fn vclezh_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2586,7 +2586,7 @@ pub fn vclt_f64(a: float64x1_t, b: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2595,7 +2595,7 @@ pub fn vcltq_f64(a: float64x2_t, b: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare signed less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2604,7 +2604,7 @@ pub fn vclt_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare signed less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmgt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2613,7 +2613,7 @@ pub fn vcltq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare unsigned less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmhi))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2622,7 +2622,7 @@ pub fn vclt_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare unsigned less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmhi))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2631,7 +2631,7 @@ pub fn vcltq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2640,7 +2640,7 @@ pub fn vcltd_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2649,7 +2649,7 @@ pub fn vcltd_s64(a: i64, b: i64) -> u64 {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclth_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -2659,7 +2659,7 @@ pub fn vclth_f16(a: f16, b: f16) -> u16 {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclts_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2668,7 +2668,7 @@ pub fn vclts_f32(a: f32, b: f32) -> u32 {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2677,7 +2677,7 @@ pub fn vcltd_f64(a: f64, b: f64) -> u64 {
     }
     #[doc = "Floating-point compare less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2687,7 +2687,7 @@ pub fn vcltz_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2697,7 +2697,7 @@ pub fn vcltzq_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2707,7 +2707,7 @@ pub fn vcltz_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point compare less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2717,7 +2717,7 @@ pub fn vcltzq_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare signed less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2727,7 +2727,7 @@ pub fn vcltz_s8(a: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare signed less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2737,7 +2737,7 @@ pub fn vcltzq_s8(a: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare signed less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2747,7 +2747,7 @@ pub fn vcltz_s16(a: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare signed less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2757,7 +2757,7 @@ pub fn vcltzq_s16(a: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare signed less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2767,7 +2767,7 @@ pub fn vcltz_s32(a: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare signed less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2777,7 +2777,7 @@ pub fn vcltzq_s32(a: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare signed less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2787,7 +2787,7 @@ pub fn vcltz_s64(a: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Compare signed less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmlt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2797,7 +2797,7 @@ pub fn vcltzq_s64(a: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point compare less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2806,7 +2806,7 @@ pub fn vcltzd_f64(a: f64) -> u64 {
     }
     #[doc = "Floating-point compare less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2815,7 +2815,7 @@ pub fn vcltzs_f32(a: f32) -> u32 {
     }
     #[doc = "Compare less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(asr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -2824,7 +2824,7 @@ pub fn vcltzd_s64(a: i64) -> u64 {
     }
     #[doc = "Floating-point compare less than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcmp))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -2834,7 +2834,7 @@ pub fn vcltzh_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -2852,7 +2852,7 @@ pub fn vcmla_f16(a: float16x4_t, b: float16x4_t, c: float16x4_t) -> float16x4_t
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -2870,7 +2870,7 @@ pub fn vcmlaq_f16(a: float16x8_t, b: float16x8_t, c: float16x8_t) -> float16x8_t
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -2886,7 +2886,7 @@ pub fn vcmla_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float32x2_t
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -2902,7 +2902,7 @@ pub fn vcmlaq_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> float32x4_t
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -2918,7 +2918,7 @@ pub fn vcmlaq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -2947,7 +2947,7 @@ pub fn vcmla_lane_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -2980,7 +2980,7 @@ pub fn vcmlaq_lane_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -2998,7 +2998,7 @@ pub fn vcmla_lane_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3025,7 +3025,7 @@ pub fn vcmlaq_lane_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3054,7 +3054,7 @@ pub fn vcmla_laneq_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3087,7 +3087,7 @@ pub fn vcmlaq_laneq_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3105,7 +3105,7 @@ pub fn vcmla_laneq_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3132,7 +3132,7 @@ pub fn vcmlaq_laneq_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot180_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -3150,7 +3150,7 @@ pub fn vcmla_rot180_f16(a: float16x4_t, b: float16x4_t, c: float16x4_t) -> float
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -3168,7 +3168,7 @@ pub fn vcmlaq_rot180_f16(a: float16x8_t, b: float16x8_t, c: float16x8_t) -> floa
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot180_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -3184,7 +3184,7 @@ pub fn vcmla_rot180_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -3200,7 +3200,7 @@ pub fn vcmlaq_rot180_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> floa
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -3216,7 +3216,7 @@ pub fn vcmlaq_rot180_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> floa
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot180_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3245,7 +3245,7 @@ pub fn vcmla_rot180_lane_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3278,7 +3278,7 @@ pub fn vcmlaq_rot180_lane_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot180_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3296,7 +3296,7 @@ pub fn vcmla_rot180_lane_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3323,7 +3323,7 @@ pub fn vcmlaq_rot180_lane_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot180_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3352,7 +3352,7 @@ pub fn vcmla_rot180_laneq_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3385,7 +3385,7 @@ pub fn vcmlaq_rot180_laneq_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot180_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3403,7 +3403,7 @@ pub fn vcmla_rot180_laneq_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot180_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3430,7 +3430,7 @@ pub fn vcmlaq_rot180_laneq_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot270_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -3448,7 +3448,7 @@ pub fn vcmla_rot270_f16(a: float16x4_t, b: float16x4_t, c: float16x4_t) -> float
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -3466,7 +3466,7 @@ pub fn vcmlaq_rot270_f16(a: float16x8_t, b: float16x8_t, c: float16x8_t) -> floa
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot270_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -3482,7 +3482,7 @@ pub fn vcmla_rot270_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -3498,7 +3498,7 @@ pub fn vcmlaq_rot270_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> floa
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -3514,7 +3514,7 @@ pub fn vcmlaq_rot270_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> floa
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot270_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3543,7 +3543,7 @@ pub fn vcmla_rot270_lane_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3576,7 +3576,7 @@ pub fn vcmlaq_rot270_lane_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot270_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3594,7 +3594,7 @@ pub fn vcmla_rot270_lane_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3621,7 +3621,7 @@ pub fn vcmlaq_rot270_lane_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot270_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3650,7 +3650,7 @@ pub fn vcmla_rot270_laneq_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3683,7 +3683,7 @@ pub fn vcmlaq_rot270_laneq_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot270_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3701,7 +3701,7 @@ pub fn vcmla_rot270_laneq_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot270_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3728,7 +3728,7 @@ pub fn vcmlaq_rot270_laneq_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot90_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -3746,7 +3746,7 @@ pub fn vcmla_rot90_f16(a: float16x4_t, b: float16x4_t, c: float16x4_t) -> float1
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
    @@ -3764,7 +3764,7 @@ pub fn vcmlaq_rot90_f16(a: float16x8_t, b: float16x8_t, c: float16x8_t) -> float
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot90_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -3780,7 +3780,7 @@ pub fn vcmla_rot90_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float3
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -3796,7 +3796,7 @@ pub fn vcmlaq_rot90_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> float
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
     #[cfg_attr(test, assert_instr(fcmla))]
    @@ -3812,7 +3812,7 @@ pub fn vcmlaq_rot90_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot90_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3841,7 +3841,7 @@ pub fn vcmla_rot90_lane_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3874,7 +3874,7 @@ pub fn vcmlaq_rot90_lane_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot90_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3892,7 +3892,7 @@ pub fn vcmla_rot90_lane_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3919,7 +3919,7 @@ pub fn vcmlaq_rot90_lane_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot90_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3948,7 +3948,7 @@ pub fn vcmla_rot90_laneq_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3981,7 +3981,7 @@ pub fn vcmlaq_rot90_laneq_f16(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmla_rot90_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -3999,7 +3999,7 @@ pub fn vcmla_rot90_laneq_f32(
     }
     #[doc = "Floating-point complex multiply accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcmlaq_rot90_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fcma")]
     #[cfg_attr(test, assert_instr(fcmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -4026,7 +4026,7 @@ pub fn vcmlaq_rot90_laneq_f32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4047,7 +4047,7 @@ pub fn vcopy_lane_f32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4071,7 +4071,7 @@ pub fn vcopy_lane_s8(a: int8x8_t, b: int8x8_
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4091,7 +4091,7 @@ pub fn vcopy_lane_s16(a: int16x4_t, b: int16
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4109,7 +4109,7 @@ pub fn vcopy_lane_s32(a: int32x2_t, b: int32
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4133,7 +4133,7 @@ pub fn vcopy_lane_u8(a: uint8x8_t, b: uint8x
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4156,7 +4156,7 @@ pub fn vcopy_lane_u16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4177,7 +4177,7 @@ pub fn vcopy_lane_u32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4201,7 +4201,7 @@ pub fn vcopy_lane_p8(a: poly8x8_t, b: poly8x
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_lane_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4224,7 +4224,7 @@ pub fn vcopy_lane_p16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4246,7 +4246,7 @@ pub fn vcopy_laneq_f32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4272,7 +4272,7 @@ pub fn vcopy_laneq_s8(a: int8x8_t, b: int8x1
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4296,7 +4296,7 @@ pub fn vcopy_laneq_s16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4318,7 +4318,7 @@ pub fn vcopy_laneq_s32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4347,7 +4347,7 @@ pub fn vcopy_laneq_u8(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4371,7 +4371,7 @@ pub fn vcopy_laneq_u16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4393,7 +4393,7 @@ pub fn vcopy_laneq_u32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4422,7 +4422,7 @@ pub fn vcopy_laneq_p8(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopy_laneq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4446,7 +4446,7 @@ pub fn vcopy_laneq_p16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4470,7 +4470,7 @@ pub fn vcopyq_lane_f32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4492,7 +4492,7 @@ pub fn vcopyq_lane_f64(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4514,7 +4514,7 @@ pub fn vcopyq_lane_s64(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4536,7 +4536,7 @@ pub fn vcopyq_lane_u64(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 1, LANE2 = 0))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4558,7 +4558,7 @@ pub fn vcopyq_lane_p64(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4928,7 +4928,7 @@ pub fn vcopyq_lane_s8(a: int8x16_t, b: int8x
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4956,7 +4956,7 @@ pub fn vcopyq_lane_s16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -4980,7 +4980,7 @@ pub fn vcopyq_lane_s32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -5353,7 +5353,7 @@ pub fn vcopyq_lane_u8(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -5381,7 +5381,7 @@ pub fn vcopyq_lane_u16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -5405,7 +5405,7 @@ pub fn vcopyq_lane_u32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -5778,7 +5778,7 @@ pub fn vcopyq_lane_p8(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_lane_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -5806,7 +5806,7 @@ pub fn vcopyq_lane_p16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -5829,7 +5829,7 @@ pub fn vcopyq_laneq_f32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -5850,7 +5850,7 @@ pub fn vcopyq_laneq_f64(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -6221,7 +6221,7 @@ pub fn vcopyq_laneq_s8(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -6248,7 +6248,7 @@ pub fn vcopyq_laneq_s16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -6271,7 +6271,7 @@ pub fn vcopyq_laneq_s32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -6292,7 +6292,7 @@ pub fn vcopyq_laneq_s64(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -6663,7 +6663,7 @@ pub fn vcopyq_laneq_u8(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -6690,7 +6690,7 @@ pub fn vcopyq_laneq_u16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -6713,7 +6713,7 @@ pub fn vcopyq_laneq_u32(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -6734,7 +6734,7 @@ pub fn vcopyq_laneq_u64(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -7105,7 +7105,7 @@ pub fn vcopyq_laneq_p8(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -7132,7 +7132,7 @@ pub fn vcopyq_laneq_p16(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcopyq_laneq_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(mov, LANE1 = 0, LANE2 = 1))]
     #[rustc_legacy_const_generics(1, 3)]
    @@ -7153,7 +7153,7 @@ pub fn vcopyq_laneq_p64(
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7162,7 +7162,7 @@ pub fn vcreate_f64(a: u64) -> float64x1_t {
     }
     #[doc = "Floating-point convert"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtn))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7171,7 +7171,7 @@ pub fn vcvt_f32_f64(a: float64x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point convert to higher precision long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7180,7 +7180,7 @@ pub fn vcvt_f64_f32(a: float32x2_t) -> float64x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(scvtf))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7189,7 +7189,7 @@ pub fn vcvt_f64_s64(a: int64x1_t) -> float64x1_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(scvtf))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7198,7 +7198,7 @@ pub fn vcvtq_f64_s64(a: int64x2_t) -> float64x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ucvtf))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7207,7 +7207,7 @@ pub fn vcvt_f64_u64(a: uint64x1_t) -> float64x1_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ucvtf))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7216,7 +7216,7 @@ pub fn vcvtq_f64_u64(a: uint64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point convert to lower precision"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_high_f16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtn2))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -7226,7 +7226,7 @@ pub fn vcvt_high_f16_f32(a: float16x4_t, b: float32x4_t) -> float16x8_t {
     }
     #[doc = "Floating-point convert to higher precision"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_high_f32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtl2))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -7236,7 +7236,7 @@ pub fn vcvt_high_f32_f16(a: float16x8_t) -> float32x4_t {
     }
     #[doc = "Floating-point convert to lower precision narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_high_f32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtn2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7245,7 +7245,7 @@ pub fn vcvt_high_f32_f64(a: float32x2_t, b: float64x2_t) -> float32x4_t {
     }
     #[doc = "Floating-point convert to higher precision long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_high_f64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7257,7 +7257,7 @@ pub fn vcvt_high_f64_f32(a: float32x4_t) -> float64x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(scvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -7275,7 +7275,7 @@ pub fn vcvt_n_f64_s64(a: int64x1_t) -> float64x1_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(scvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -7293,7 +7293,7 @@ pub fn vcvtq_n_f64_s64(a: int64x2_t) -> float64x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ucvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -7311,7 +7311,7 @@ pub fn vcvt_n_f64_u64(a: uint64x1_t) -> float64x1_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ucvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -7329,7 +7329,7 @@ pub fn vcvtq_n_f64_u64(a: uint64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -7347,7 +7347,7 @@ pub fn vcvt_n_s64_f64(a: float64x1_t) -> int64x1_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -7365,7 +7365,7 @@ pub fn vcvtq_n_s64_f64(a: float64x2_t) -> int64x2_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -7383,7 +7383,7 @@ pub fn vcvt_n_u64_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -7401,7 +7401,7 @@ pub fn vcvtq_n_u64_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point convert to signed fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7417,7 +7417,7 @@ pub fn vcvt_s64_f64(a: float64x1_t) -> int64x1_t {
     }
     #[doc = "Floating-point convert to signed fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7433,7 +7433,7 @@ pub fn vcvtq_s64_f64(a: float64x2_t) -> int64x2_t {
     }
     #[doc = "Floating-point convert to unsigned fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7449,7 +7449,7 @@ pub fn vcvt_u64_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point convert to unsigned fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7465,7 +7465,7 @@ pub fn vcvtq_u64_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -7482,7 +7482,7 @@ pub fn vcvta_s16_f16(a: float16x4_t) -> int16x4_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -7499,7 +7499,7 @@ pub fn vcvtaq_s16_f16(a: float16x8_t) -> int16x8_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7515,7 +7515,7 @@ pub fn vcvta_s32_f32(a: float32x2_t) -> int32x2_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7531,7 +7531,7 @@ pub fn vcvtaq_s32_f32(a: float32x4_t) -> int32x4_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7547,7 +7547,7 @@ pub fn vcvta_s64_f64(a: float64x1_t) -> int64x1_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7563,7 +7563,7 @@ pub fn vcvtaq_s64_f64(a: float64x2_t) -> int64x2_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -7580,7 +7580,7 @@ pub fn vcvta_u16_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -7597,7 +7597,7 @@ pub fn vcvtaq_u16_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7613,7 +7613,7 @@ pub fn vcvta_u32_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7629,7 +7629,7 @@ pub fn vcvtaq_u32_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvta_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7645,7 +7645,7 @@ pub fn vcvta_u64_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtaq_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7661,7 +7661,7 @@ pub fn vcvtaq_u64_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtah_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7671,7 +7671,7 @@ pub fn vcvtah_s16_f16(a: f16) -> i16 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtah_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7688,7 +7688,7 @@ pub fn vcvtah_s32_f16(a: f16) -> i32 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtah_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7705,7 +7705,7 @@ pub fn vcvtah_s64_f16(a: f16) -> i64 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtah_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7715,7 +7715,7 @@ pub fn vcvtah_u16_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtah_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7732,7 +7732,7 @@ pub fn vcvtah_u32_f16(a: f16) -> u32 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtah_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7749,7 +7749,7 @@ pub fn vcvtah_u64_f16(a: f16) -> u64 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtas_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7765,7 +7765,7 @@ pub fn vcvtas_s32_f32(a: f32) -> i32 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtad_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtas))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7781,7 +7781,7 @@ pub fn vcvtad_s64_f64(a: f64) -> i64 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtas_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7797,7 +7797,7 @@ pub fn vcvtas_u32_f32(a: f32) -> u32 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtad_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtau))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7813,7 +7813,7 @@ pub fn vcvtad_u64_f64(a: f64) -> u64 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_f64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(scvtf))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7822,7 +7822,7 @@ pub fn vcvtd_f64_s64(a: i64) -> f64 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(scvtf))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -7831,7 +7831,7 @@ pub fn vcvts_f32_s32(a: i32) -> f32 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(scvtf))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7841,7 +7841,7 @@ pub fn vcvth_f16_s16(a: i16) -> f16 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_f16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(scvtf))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7851,7 +7851,7 @@ pub fn vcvth_f16_s32(a: i32) -> f16 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_f16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(scvtf))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7861,7 +7861,7 @@ pub fn vcvth_f16_s64(a: i64) -> f16 {
     }
     #[doc = "Unsigned fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(ucvtf))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7871,7 +7871,7 @@ pub fn vcvth_f16_u16(a: u16) -> f16 {
     }
     #[doc = "Unsigned fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_f16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(ucvtf))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7881,7 +7881,7 @@ pub fn vcvth_f16_u32(a: u32) -> f16 {
     }
     #[doc = "Unsigned fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_f16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(ucvtf))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -7891,7 +7891,7 @@ pub fn vcvth_f16_u64(a: u64) -> f16 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(scvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -7903,7 +7903,7 @@ pub fn vcvth_n_f16_s16(a: i16) -> f16 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(scvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -7922,7 +7922,7 @@ pub fn vcvth_n_f16_s32(a: i32) -> f16 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(scvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -7941,7 +7941,7 @@ pub fn vcvth_n_f16_s64(a: i64) -> f16 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(ucvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -7953,7 +7953,7 @@ pub fn vcvth_n_f16_u16(a: u16) -> f16 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(ucvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -7972,7 +7972,7 @@ pub fn vcvth_n_f16_u32(a: u32) -> f16 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(ucvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -7991,7 +7991,7 @@ pub fn vcvth_n_f16_u64(a: u64) -> f16 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -8003,7 +8003,7 @@ pub fn vcvth_n_s16_f16(a: f16) -> i16 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -8022,7 +8022,7 @@ pub fn vcvth_n_s32_f16(a: f16) -> i32 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -8041,7 +8041,7 @@ pub fn vcvth_n_s64_f16(a: f16) -> i64 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -8053,7 +8053,7 @@ pub fn vcvth_n_u16_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -8072,7 +8072,7 @@ pub fn vcvth_n_u32_f16(a: f16) -> u32 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -8091,7 +8091,7 @@ pub fn vcvth_n_u64_f16(a: f16) -> u64 {
     }
     #[doc = "Floating-point convert to signed fixed-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzs))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8101,7 +8101,7 @@ pub fn vcvth_s16_f16(a: f16) -> i16 {
     }
     #[doc = "Floating-point convert to signed fixed-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzs))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8111,7 +8111,7 @@ pub fn vcvth_s32_f16(a: f16) -> i32 {
     }
     #[doc = "Floating-point convert to signed fixed-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzs))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8121,7 +8121,7 @@ pub fn vcvth_s64_f16(a: f16) -> i64 {
     }
     #[doc = "Floating-point convert to unsigned fixed-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8131,7 +8131,7 @@ pub fn vcvth_u16_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point convert to unsigned fixed-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8141,7 +8141,7 @@ pub fn vcvth_u32_f16(a: f16) -> u32 {
     }
     #[doc = "Floating-point convert to unsigned fixed-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtzu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8151,7 +8151,7 @@ pub fn vcvth_u64_f16(a: f16) -> u64 {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8168,7 +8168,7 @@ pub fn vcvtm_s16_f16(a: float16x4_t) -> int16x4_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8185,7 +8185,7 @@ pub fn vcvtmq_s16_f16(a: float16x8_t) -> int16x8_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8201,7 +8201,7 @@ pub fn vcvtm_s32_f32(a: float32x2_t) -> int32x2_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8217,7 +8217,7 @@ pub fn vcvtmq_s32_f32(a: float32x4_t) -> int32x4_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8233,7 +8233,7 @@ pub fn vcvtm_s64_f64(a: float64x1_t) -> int64x1_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8249,7 +8249,7 @@ pub fn vcvtmq_s64_f64(a: float64x2_t) -> int64x2_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8266,7 +8266,7 @@ pub fn vcvtm_u16_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8283,7 +8283,7 @@ pub fn vcvtmq_u16_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8299,7 +8299,7 @@ pub fn vcvtm_u32_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8315,7 +8315,7 @@ pub fn vcvtmq_u32_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtm_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8331,7 +8331,7 @@ pub fn vcvtm_u64_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmq_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8347,7 +8347,7 @@ pub fn vcvtmq_u64_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point convert to integer, rounding towards minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmh_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8357,7 +8357,7 @@ pub fn vcvtmh_s16_f16(a: f16) -> i16 {
     }
     #[doc = "Floating-point convert to integer, rounding towards minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmh_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8374,7 +8374,7 @@ pub fn vcvtmh_s32_f16(a: f16) -> i32 {
     }
     #[doc = "Floating-point convert to integer, rounding towards minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmh_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8391,7 +8391,7 @@ pub fn vcvtmh_s64_f16(a: f16) -> i64 {
     }
     #[doc = "Floating-point convert to integer, rounding towards minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmh_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8401,7 +8401,7 @@ pub fn vcvtmh_u16_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding towards minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmh_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8418,7 +8418,7 @@ pub fn vcvtmh_u32_f16(a: f16) -> u32 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding towards minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmh_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8435,7 +8435,7 @@ pub fn vcvtmh_u64_f16(a: f16) -> u64 {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtms_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8451,7 +8451,7 @@ pub fn vcvtms_s32_f32(a: f32) -> i32 {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmd_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtms))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8467,7 +8467,7 @@ pub fn vcvtmd_s64_f64(a: f64) -> i64 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtms_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8483,7 +8483,7 @@ pub fn vcvtms_u32_f32(a: f32) -> u32 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtmd_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtmu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8499,7 +8499,7 @@ pub fn vcvtmd_u64_f64(a: f64) -> u64 {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8516,7 +8516,7 @@ pub fn vcvtn_s16_f16(a: float16x4_t) -> int16x4_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8533,7 +8533,7 @@ pub fn vcvtnq_s16_f16(a: float16x8_t) -> int16x8_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8549,7 +8549,7 @@ pub fn vcvtn_s32_f32(a: float32x2_t) -> int32x2_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8565,7 +8565,7 @@ pub fn vcvtnq_s32_f32(a: float32x4_t) -> int32x4_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8581,7 +8581,7 @@ pub fn vcvtn_s64_f64(a: float64x1_t) -> int64x1_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8597,7 +8597,7 @@ pub fn vcvtnq_s64_f64(a: float64x2_t) -> int64x2_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8614,7 +8614,7 @@ pub fn vcvtn_u16_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8631,7 +8631,7 @@ pub fn vcvtnq_u16_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8647,7 +8647,7 @@ pub fn vcvtn_u32_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8663,7 +8663,7 @@ pub fn vcvtnq_u32_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtn_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8679,7 +8679,7 @@ pub fn vcvtn_u64_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnq_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8695,7 +8695,7 @@ pub fn vcvtnq_u64_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnh_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8705,7 +8705,7 @@ pub fn vcvtnh_s16_f16(a: f16) -> i16 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnh_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8722,7 +8722,7 @@ pub fn vcvtnh_s32_f16(a: f16) -> i32 {
     }
     #[doc = "Floating-point convert to integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnh_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8739,7 +8739,7 @@ pub fn vcvtnh_s64_f16(a: f16) -> i64 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnh_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8749,7 +8749,7 @@ pub fn vcvtnh_u16_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnh_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8766,7 +8766,7 @@ pub fn vcvtnh_u32_f16(a: f16) -> u32 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnh_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -8783,7 +8783,7 @@ pub fn vcvtnh_u64_f16(a: f16) -> u64 {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtns_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8799,7 +8799,7 @@ pub fn vcvtns_s32_f32(a: f32) -> i32 {
     }
     #[doc = "Floating-point convert to signed integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnd_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtns))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8815,7 +8815,7 @@ pub fn vcvtnd_s64_f64(a: f64) -> i64 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtns_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8831,7 +8831,7 @@ pub fn vcvtns_u32_f32(a: f32) -> u32 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtnd_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtnu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8847,7 +8847,7 @@ pub fn vcvtnd_u64_f64(a: f64) -> u64 {
     }
     #[doc = "Floating-point convert to signed integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8864,7 +8864,7 @@ pub fn vcvtp_s16_f16(a: float16x4_t) -> int16x4_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8881,7 +8881,7 @@ pub fn vcvtpq_s16_f16(a: float16x8_t) -> int16x8_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8897,7 +8897,7 @@ pub fn vcvtp_s32_f32(a: float32x2_t) -> int32x2_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8913,7 +8913,7 @@ pub fn vcvtpq_s32_f32(a: float32x4_t) -> int32x4_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8929,7 +8929,7 @@ pub fn vcvtp_s64_f64(a: float64x1_t) -> int64x1_t {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8945,7 +8945,7 @@ pub fn vcvtpq_s64_f64(a: float64x2_t) -> int64x2_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8962,7 +8962,7 @@ pub fn vcvtp_u16_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -8979,7 +8979,7 @@ pub fn vcvtpq_u16_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -8995,7 +8995,7 @@ pub fn vcvtp_u32_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9011,7 +9011,7 @@ pub fn vcvtpq_u32_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtp_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9027,7 +9027,7 @@ pub fn vcvtp_u64_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpq_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9043,7 +9043,7 @@ pub fn vcvtpq_u64_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point convert to integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtph_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -9053,7 +9053,7 @@ pub fn vcvtph_s16_f16(a: f16) -> i16 {
     }
     #[doc = "Floating-point convert to integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtph_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -9070,7 +9070,7 @@ pub fn vcvtph_s32_f16(a: f16) -> i32 {
     }
     #[doc = "Floating-point convert to integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtph_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -9087,7 +9087,7 @@ pub fn vcvtph_s64_f16(a: f16) -> i64 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtph_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -9097,7 +9097,7 @@ pub fn vcvtph_u16_f16(a: f16) -> u16 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtph_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -9114,7 +9114,7 @@ pub fn vcvtph_u32_f16(a: f16) -> u32 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding to plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtph_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -9131,7 +9131,7 @@ pub fn vcvtph_u64_f16(a: f16) -> u64 {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtps_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9147,7 +9147,7 @@ pub fn vcvtps_s32_f32(a: f32) -> i32 {
     }
     #[doc = "Floating-point convert to signed integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpd_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9163,7 +9163,7 @@ pub fn vcvtpd_s64_f64(a: f64) -> i64 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtps_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9179,7 +9179,7 @@ pub fn vcvtps_u32_f32(a: f32) -> u32 {
     }
     #[doc = "Floating-point convert to unsigned integer, rounding toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtpd_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtpu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9195,7 +9195,7 @@ pub fn vcvtpd_u64_f64(a: f64) -> u64 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ucvtf))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9204,7 +9204,7 @@ pub fn vcvts_f32_u32(a: u32) -> f32 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_f64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ucvtf))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9213,7 +9213,7 @@ pub fn vcvtd_f64_u64(a: u64) -> f64 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_n_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(scvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9231,7 +9231,7 @@ pub fn vcvts_n_f32_s32(a: i32) -> f32 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_n_f64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(scvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9249,7 +9249,7 @@ pub fn vcvtd_n_f64_s64(a: i64) -> f64 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_n_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ucvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9267,7 +9267,7 @@ pub fn vcvts_n_f32_u32(a: u32) -> f32 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_n_f64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ucvtf, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9285,7 +9285,7 @@ pub fn vcvtd_n_f64_u64(a: u64) -> f64 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_n_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9303,7 +9303,7 @@ pub fn vcvts_n_s32_f32(a: f32) -> i32 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_n_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9321,7 +9321,7 @@ pub fn vcvtd_n_s64_f64(a: f64) -> i64 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_n_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9339,7 +9339,7 @@ pub fn vcvts_n_u32_f32(a: f32) -> u32 {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_n_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9357,7 +9357,7 @@ pub fn vcvtd_n_u64_f64(a: f64) -> u64 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9366,7 +9366,7 @@ pub fn vcvts_s32_f32(a: f32) -> i32 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzs))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9375,7 +9375,7 @@ pub fn vcvtd_s64_f64(a: f64) -> i64 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvts_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9384,7 +9384,7 @@ pub fn vcvts_u32_f32(a: f32) -> u32 {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtd_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtzu))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9393,7 +9393,7 @@ pub fn vcvtd_u64_f64(a: f64) -> u64 {
     }
     #[doc = "Floating-point convert to lower precision narrow, rounding to odd"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtx_f32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtxn))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9409,7 +9409,7 @@ pub fn vcvtx_f32_f64(a: float64x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point convert to lower precision narrow, rounding to odd"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtx_high_f32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtxn2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9418,7 +9418,7 @@ pub fn vcvtx_high_f32_f64(a: float32x2_t, b: float64x2_t) -> float32x4_t {
     }
     #[doc = "Floating-point convert to lower precision narrow, rounding to odd"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtxd_f32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fcvtxn))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -9427,7 +9427,7 @@ pub fn vcvtxd_f32_f64(a: f64) -> f32 {
     }
     #[doc = "Divide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdiv_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -9437,7 +9437,7 @@ pub fn vdiv_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Divide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdivq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -9447,7 +9447,7 @@ pub fn vdivq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Divide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdiv_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fdiv))]
    @@ -9456,7 +9456,7 @@ pub fn vdiv_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Divide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdivq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fdiv))]
    @@ -9465,7 +9465,7 @@ pub fn vdivq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Divide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdiv_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fdiv))]
    @@ -9474,7 +9474,7 @@ pub fn vdiv_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Divide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdivq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fdiv))]
    @@ -9483,7 +9483,7 @@ pub fn vdivq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Divide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdivh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -9493,7 +9493,7 @@ pub fn vdivh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,dotprod")]
     #[cfg_attr(test, assert_instr(sdot, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -9508,7 +9508,7 @@ pub fn vdot_laneq_s32(a: int32x2_t, b: int8x8_t, c: int8x16_t)
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,dotprod")]
     #[cfg_attr(test, assert_instr(sdot, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -9524,7 +9524,7 @@ pub fn vdotq_laneq_s32(a: int32x4_t, b: int8x16_t, c: int8x16_t
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,dotprod")]
     #[cfg_attr(test, assert_instr(udot, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -9539,7 +9539,7 @@ pub fn vdot_laneq_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x16_
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,dotprod")]
     #[cfg_attr(test, assert_instr(udot, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -9555,7 +9555,7 @@ pub fn vdotq_laneq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x1
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 0))]
     #[rustc_legacy_const_generics(1)]
    @@ -9566,7 +9566,7 @@ pub fn vdup_lane_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 0))]
     #[rustc_legacy_const_generics(1)]
    @@ -9577,7 +9577,7 @@ pub fn vdup_lane_p64(a: poly64x1_t) -> poly64x1_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9588,7 +9588,7 @@ pub fn vdup_laneq_f64(a: float64x2_t) -> float64x1_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9599,7 +9599,7 @@ pub fn vdup_laneq_p64(a: poly64x2_t) -> poly64x1_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_lane_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 4))]
     #[rustc_legacy_const_generics(1)]
    @@ -9610,7 +9610,7 @@ pub fn vdupb_lane_s8(a: int8x8_t) -> i8 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 4))]
     #[rustc_legacy_const_generics(1)]
    @@ -9621,7 +9621,7 @@ pub fn vduph_laneq_s16(a: int16x8_t) -> i16 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_lane_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 4))]
     #[rustc_legacy_const_generics(1)]
    @@ -9632,7 +9632,7 @@ pub fn vdupb_lane_u8(a: uint8x8_t) -> u8 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 4))]
     #[rustc_legacy_const_generics(1)]
    @@ -9643,7 +9643,7 @@ pub fn vduph_laneq_u16(a: uint16x8_t) -> u16 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_lane_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 4))]
     #[rustc_legacy_const_generics(1)]
    @@ -9654,7 +9654,7 @@ pub fn vdupb_lane_p8(a: poly8x8_t) -> p8 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_laneq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 4))]
     #[rustc_legacy_const_generics(1)]
    @@ -9665,7 +9665,7 @@ pub fn vduph_laneq_p16(a: poly16x8_t) -> p16 {
     }
     #[doc = "Extract an element from a vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_laneq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 8))]
     #[rustc_legacy_const_generics(1)]
    @@ -9676,7 +9676,7 @@ pub fn vdupb_laneq_s8(a: int8x16_t) -> i8 {
     }
     #[doc = "Extract an element from a vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_laneq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 8))]
     #[rustc_legacy_const_generics(1)]
    @@ -9687,7 +9687,7 @@ pub fn vdupb_laneq_u8(a: uint8x16_t) -> u8 {
     }
     #[doc = "Extract an element from a vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupb_laneq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 8))]
     #[rustc_legacy_const_generics(1)]
    @@ -9698,7 +9698,7 @@ pub fn vdupb_laneq_p8(a: poly8x16_t) -> p8 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 0))]
     #[rustc_legacy_const_generics(1)]
    @@ -9709,7 +9709,7 @@ pub fn vdupd_lane_f64(a: float64x1_t) -> f64 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_lane_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 0))]
     #[rustc_legacy_const_generics(1)]
    @@ -9720,7 +9720,7 @@ pub fn vdupd_lane_s64(a: int64x1_t) -> i64 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_lane_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 0))]
     #[rustc_legacy_const_generics(1)]
    @@ -9731,7 +9731,7 @@ pub fn vdupd_lane_u64(a: uint64x1_t) -> u64 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(nop, N = 2))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -9743,7 +9743,7 @@ pub fn vduph_lane_f16(a: float16x4_t) -> f16 {
     }
     #[doc = "Extract an element from a vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(nop, N = 4))]
     #[rustc_legacy_const_generics(1)]
     #[target_feature(enable = "neon,fp16")]
    @@ -9755,7 +9755,7 @@ pub fn vduph_laneq_f16(a: float16x8_t) -> f16 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(dup, N = 0))]
     #[rustc_legacy_const_generics(1)]
    @@ -9766,7 +9766,7 @@ pub fn vdupq_lane_f64(a: float64x1_t) -> float64x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(dup, N = 0))]
     #[rustc_legacy_const_generics(1)]
    @@ -9777,7 +9777,7 @@ pub fn vdupq_lane_p64(a: poly64x1_t) -> poly64x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(dup, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9788,7 +9788,7 @@ pub fn vdupq_laneq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(dup, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9799,7 +9799,7 @@ pub fn vdupq_laneq_p64(a: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9810,7 +9810,7 @@ pub fn vdups_lane_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9821,7 +9821,7 @@ pub fn vdupd_laneq_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9832,7 +9832,7 @@ pub fn vdups_lane_s32(a: int32x2_t) -> i32 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_laneq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9843,7 +9843,7 @@ pub fn vdupd_laneq_s64(a: int64x2_t) -> i64 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9854,7 +9854,7 @@ pub fn vdups_lane_u32(a: uint32x2_t) -> u32 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupd_laneq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 1))]
     #[rustc_legacy_const_generics(1)]
    @@ -9865,7 +9865,7 @@ pub fn vdupd_laneq_u64(a: uint64x2_t) -> u64 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9876,7 +9876,7 @@ pub fn vdups_laneq_f32(a: float32x4_t) -> f32 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9887,7 +9887,7 @@ pub fn vduph_lane_s16(a: int16x4_t) -> i16 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9898,7 +9898,7 @@ pub fn vdups_laneq_s32(a: int32x4_t) -> i32 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9909,7 +9909,7 @@ pub fn vduph_lane_u16(a: uint16x4_t) -> u16 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdups_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9920,7 +9920,7 @@ pub fn vdups_laneq_u32(a: uint32x4_t) -> u32 {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vduph_lane_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -9931,7 +9931,7 @@ pub fn vduph_lane_p16(a: poly16x4_t) -> p16 {
     }
     #[doc = "Three-way exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(eor3))]
    @@ -9947,7 +9947,7 @@ pub fn veor3q_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
     }
     #[doc = "Three-way exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(eor3))]
    @@ -9963,7 +9963,7 @@ pub fn veor3q_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
     }
     #[doc = "Three-way exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(eor3))]
    @@ -9979,7 +9979,7 @@ pub fn veor3q_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
     }
     #[doc = "Three-way exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(eor3))]
    @@ -9995,7 +9995,7 @@ pub fn veor3q_s64(a: int64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t {
     }
     #[doc = "Three-way exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(eor3))]
    @@ -10011,7 +10011,7 @@ pub fn veor3q_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Three-way exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(eor3))]
    @@ -10027,7 +10027,7 @@ pub fn veor3q_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Three-way exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(eor3))]
    @@ -10043,7 +10043,7 @@ pub fn veor3q_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Three-way exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor3q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
     #[cfg_attr(test, assert_instr(eor3))]
    @@ -10059,7 +10059,7 @@ pub fn veor3q_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ext, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -10076,7 +10076,7 @@ pub fn vextq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ext, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -10093,7 +10093,7 @@ pub fn vextq_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmadd))]
    @@ -10102,7 +10102,7 @@ pub fn vfma_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10118,7 +10118,7 @@ pub fn vfma_lane_f16(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10134,7 +10134,7 @@ pub fn vfma_laneq_f16(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10150,7 +10150,7 @@ pub fn vfmaq_lane_f16(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10166,7 +10166,7 @@ pub fn vfmaq_laneq_f16(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10181,7 +10181,7 @@ pub fn vfma_lane_f32(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10196,7 +10196,7 @@ pub fn vfma_laneq_f32(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10211,7 +10211,7 @@ pub fn vfmaq_lane_f32(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10226,7 +10226,7 @@ pub fn vfmaq_laneq_f32(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10241,7 +10241,7 @@ pub fn vfmaq_laneq_f64(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10256,7 +10256,7 @@ pub fn vfma_lane_f64(
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10271,7 +10271,7 @@ pub fn vfma_laneq_f64(
     }
     #[doc = "Floating-point fused Multiply-Subtract from accumulator."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -10281,7 +10281,7 @@ pub fn vfma_n_f16(a: float16x4_t, b: float16x4_t, c: f16) -> float16x4_t {
     }
     #[doc = "Floating-point fused Multiply-Subtract from accumulator."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -10291,7 +10291,7 @@ pub fn vfmaq_n_f16(a: float16x8_t, b: float16x8_t, c: f16) -> float16x8_t {
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_n_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmadd))]
    @@ -10300,7 +10300,7 @@ pub fn vfma_n_f64(a: float64x1_t, b: float64x1_t, c: f64) -> float64x1_t {
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmad_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10314,7 +10314,7 @@ pub fn vfmad_lane_f64(a: f64, b: f64, c: float64x1_t) -> f64 {
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmah_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmadd))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -10324,7 +10324,7 @@ pub fn vfmah_f16(a: f16, b: f16, c: f16) -> f16 {
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmah_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10339,7 +10339,7 @@ pub fn vfmah_lane_f16(a: f16, b: f16, v: float16x4_t) -> f16 {
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmah_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10354,7 +10354,7 @@ pub fn vfmah_laneq_f16(a: f16, b: f16, v: float16x8_t) -> f16 {
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmla))]
    @@ -10363,7 +10363,7 @@ pub fn vfmaq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmla, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10378,7 +10378,7 @@ pub fn vfmaq_lane_f64(
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_n_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmla))]
    @@ -10387,7 +10387,7 @@ pub fn vfmaq_n_f64(a: float64x2_t, b: float64x2_t, c: f64) -> float64x2_t {
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmas_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10401,7 +10401,7 @@ pub fn vfmas_lane_f32(a: f32, b: f32, c: float32x2_t) -> f32 {
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmas_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10415,7 +10415,7 @@ pub fn vfmas_laneq_f32(a: f32, b: f32, c: float32x4_t) -> f32 {
     }
     #[doc = "Floating-point fused multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmad_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmadd, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10429,7 +10429,7 @@ pub fn vfmad_laneq_f64(a: f64, b: f64, c: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlal_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -10447,7 +10447,7 @@ pub fn vfmlal_high_f16(r: float32x2_t, a: float16x4_t, b: float16x4_t) -> float3
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlalq_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -10465,7 +10465,7 @@ pub fn vfmlalq_high_f16(r: float32x4_t, a: float16x8_t, b: float16x8_t) -> float
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlal_lane_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlal2, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10482,7 +10482,7 @@ pub fn vfmlal_lane_high_f16(
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlal_laneq_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlal2, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10499,7 +10499,7 @@ pub fn vfmlal_laneq_high_f16(
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlalq_lane_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlal2, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10516,7 +10516,7 @@ pub fn vfmlalq_lane_high_f16(
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlalq_laneq_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlal2, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10533,7 +10533,7 @@ pub fn vfmlalq_laneq_high_f16(
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlal_lane_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlal, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10550,7 +10550,7 @@ pub fn vfmlal_lane_low_f16(
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlal_laneq_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlal, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10567,7 +10567,7 @@ pub fn vfmlal_laneq_low_f16(
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlalq_lane_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlal, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10584,7 +10584,7 @@ pub fn vfmlalq_lane_low_f16(
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlalq_laneq_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlal, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10601,7 +10601,7 @@ pub fn vfmlalq_laneq_low_f16(
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlal_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -10619,7 +10619,7 @@ pub fn vfmlal_low_f16(r: float32x2_t, a: float16x4_t, b: float16x4_t) -> float32
     }
     #[doc = "Floating-point fused Multiply-Add Long to accumulator (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlalq_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -10637,7 +10637,7 @@ pub fn vfmlalq_low_f16(r: float32x4_t, a: float16x8_t, b: float16x8_t) -> float3
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlsl_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -10655,7 +10655,7 @@ pub fn vfmlsl_high_f16(r: float32x2_t, a: float16x4_t, b: float16x4_t) -> float3
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlslq_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -10673,7 +10673,7 @@ pub fn vfmlslq_high_f16(r: float32x4_t, a: float16x8_t, b: float16x8_t) -> float
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlsl_lane_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlsl2, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10690,7 +10690,7 @@ pub fn vfmlsl_lane_high_f16(
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlsl_laneq_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlsl2, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10707,7 +10707,7 @@ pub fn vfmlsl_laneq_high_f16(
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlslq_lane_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlsl2, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10724,7 +10724,7 @@ pub fn vfmlslq_lane_high_f16(
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlslq_laneq_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlsl2, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10741,7 +10741,7 @@ pub fn vfmlslq_laneq_high_f16(
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlsl_lane_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlsl, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10758,7 +10758,7 @@ pub fn vfmlsl_lane_low_f16(
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlsl_laneq_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlsl, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10775,7 +10775,7 @@ pub fn vfmlsl_laneq_low_f16(
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlslq_lane_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlsl, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10792,7 +10792,7 @@ pub fn vfmlslq_lane_low_f16(
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (by element)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlslq_laneq_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmlsl, LANE = 0))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
    @@ -10809,7 +10809,7 @@ pub fn vfmlslq_laneq_low_f16(
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlsl_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -10827,7 +10827,7 @@ pub fn vfmlsl_low_f16(r: float32x2_t, a: float16x4_t, b: float16x4_t) -> float32
     }
     #[doc = "Floating-point fused Multiply-Subtract Long from accumulator (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmlslq_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(not(target_arch = "arm"), target_feature(enable = "fhm"))]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -10845,7 +10845,7 @@ pub fn vfmlslq_low_f16(r: float32x4_t, a: float16x8_t, b: float16x8_t) -> float3
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmsub))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -10857,7 +10857,7 @@ pub fn vfms_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10873,7 +10873,7 @@ pub fn vfms_lane_f16(
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10889,7 +10889,7 @@ pub fn vfms_laneq_f16(
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10905,7 +10905,7 @@ pub fn vfmsq_lane_f16(
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -10921,7 +10921,7 @@ pub fn vfmsq_laneq_f16(
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10936,7 +10936,7 @@ pub fn vfms_lane_f32(
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10951,7 +10951,7 @@ pub fn vfms_laneq_f32(
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10966,7 +10966,7 @@ pub fn vfmsq_lane_f32(
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10981,7 +10981,7 @@ pub fn vfmsq_laneq_f32(
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -10996,7 +10996,7 @@ pub fn vfmsq_laneq_f64(
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -11011,7 +11011,7 @@ pub fn vfms_lane_f64(
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -11026,7 +11026,7 @@ pub fn vfms_laneq_f64(
     }
     #[doc = "Floating-point fused Multiply-Subtract from accumulator."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -11036,7 +11036,7 @@ pub fn vfms_n_f16(a: float16x4_t, b: float16x4_t, c: f16) -> float16x4_t {
     }
     #[doc = "Floating-point fused Multiply-Subtract from accumulator."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -11046,7 +11046,7 @@ pub fn vfmsq_n_f16(a: float16x8_t, b: float16x8_t, c: f16) -> float16x8_t {
     }
     #[doc = "Floating-point fused Multiply-subtract to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_n_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmsub))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11055,7 +11055,7 @@ pub fn vfms_n_f64(a: float64x1_t, b: float64x1_t, c: f64) -> float64x1_t {
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmsub))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -11065,7 +11065,7 @@ pub fn vfmsh_f16(a: f16, b: f16, c: f16) -> f16 {
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsh_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -11080,7 +11080,7 @@ pub fn vfmsh_lane_f16(a: f16, b: f16, v: float16x4_t) -> f16 {
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsh_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
     #[target_feature(enable = "neon,fp16")]
    @@ -11095,7 +11095,7 @@ pub fn vfmsh_laneq_f16(a: f16, b: f16, v: float16x8_t) -> f16 {
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmls))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11107,7 +11107,7 @@ pub fn vfmsq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmls, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -11122,7 +11122,7 @@ pub fn vfmsq_lane_f64(
     }
     #[doc = "Floating-point fused Multiply-subtract to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_n_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmls))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11131,7 +11131,7 @@ pub fn vfmsq_n_f64(a: float64x2_t, b: float64x2_t, c: f64) -> float64x2_t {
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmss_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -11141,7 +11141,7 @@ pub fn vfmss_lane_f32(a: f32, b: f32, c: float32x2_t) -> f32 {
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmss_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -11151,7 +11151,7 @@ pub fn vfmss_laneq_f32(a: f32, b: f32, c: float32x4_t) -> f32 {
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsd_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -11161,7 +11161,7 @@ pub fn vfmsd_lane_f64(a: f64, b: f64, c: float64x1_t) -> f64 {
     }
     #[doc = "Floating-point fused multiply-subtract to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsd_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmsub, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -11173,7 +11173,7 @@ pub fn vfmsd_laneq_f64(a: f64, b: f64, c: float64x2_t) -> f64 {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -11185,7 +11185,7 @@ pub unsafe fn vld1_f16(ptr: *const f16) -> float16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -11197,7 +11197,7 @@ pub unsafe fn vld1q_f16(ptr: *const f16) -> float16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11208,7 +11208,7 @@ pub unsafe fn vld1_f32(ptr: *const f32) -> float32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11219,7 +11219,7 @@ pub unsafe fn vld1q_f32(ptr: *const f32) -> float32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11230,7 +11230,7 @@ pub unsafe fn vld1_f64(ptr: *const f64) -> float64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11241,7 +11241,7 @@ pub unsafe fn vld1q_f64(ptr: *const f64) -> float64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11252,7 +11252,7 @@ pub unsafe fn vld1_s8(ptr: *const i8) -> int8x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11263,7 +11263,7 @@ pub unsafe fn vld1q_s8(ptr: *const i8) -> int8x16_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11274,7 +11274,7 @@ pub unsafe fn vld1_s16(ptr: *const i16) -> int16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11285,7 +11285,7 @@ pub unsafe fn vld1q_s16(ptr: *const i16) -> int16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11296,7 +11296,7 @@ pub unsafe fn vld1_s32(ptr: *const i32) -> int32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11307,7 +11307,7 @@ pub unsafe fn vld1q_s32(ptr: *const i32) -> int32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11318,7 +11318,7 @@ pub unsafe fn vld1_s64(ptr: *const i64) -> int64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11329,7 +11329,7 @@ pub unsafe fn vld1q_s64(ptr: *const i64) -> int64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11340,7 +11340,7 @@ pub unsafe fn vld1_u8(ptr: *const u8) -> uint8x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11351,7 +11351,7 @@ pub unsafe fn vld1q_u8(ptr: *const u8) -> uint8x16_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11362,7 +11362,7 @@ pub unsafe fn vld1_u16(ptr: *const u16) -> uint16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11373,7 +11373,7 @@ pub unsafe fn vld1q_u16(ptr: *const u16) -> uint16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11384,7 +11384,7 @@ pub unsafe fn vld1_u32(ptr: *const u32) -> uint32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11395,7 +11395,7 @@ pub unsafe fn vld1q_u32(ptr: *const u32) -> uint32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11406,7 +11406,7 @@ pub unsafe fn vld1_u64(ptr: *const u64) -> uint64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11417,7 +11417,7 @@ pub unsafe fn vld1q_u64(ptr: *const u64) -> uint64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11428,7 +11428,7 @@ pub unsafe fn vld1_p8(ptr: *const p8) -> poly8x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11439,7 +11439,7 @@ pub unsafe fn vld1q_p8(ptr: *const p8) -> poly8x16_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11450,7 +11450,7 @@ pub unsafe fn vld1_p16(ptr: *const p16) -> poly16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11461,7 +11461,7 @@ pub unsafe fn vld1q_p16(ptr: *const p16) -> poly16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11472,7 +11472,7 @@ pub unsafe fn vld1_p64(ptr: *const p64) -> poly64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ldr))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11483,7 +11483,7 @@ pub unsafe fn vld1q_p64(ptr: *const p64) -> poly64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld1))]
    @@ -11501,7 +11501,7 @@ pub unsafe fn vld1_f64_x2(a: *const f64) -> float64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld1))]
    @@ -11519,7 +11519,7 @@ pub unsafe fn vld1_f64_x3(a: *const f64) -> float64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld1))]
    @@ -11537,7 +11537,7 @@ pub unsafe fn vld1_f64_x4(a: *const f64) -> float64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld1))]
    @@ -11555,7 +11555,7 @@ pub unsafe fn vld1q_f64_x2(a: *const f64) -> float64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld1))]
    @@ -11573,7 +11573,7 @@ pub unsafe fn vld1q_f64_x3(a: *const f64) -> float64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld1))]
    @@ -11591,7 +11591,7 @@ pub unsafe fn vld1q_f64_x4(a: *const f64) -> float64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld2r))]
    @@ -11609,7 +11609,7 @@ pub unsafe fn vld2_dup_f64(a: *const f64) -> float64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld2r))]
    @@ -11627,7 +11627,7 @@ pub unsafe fn vld2q_dup_f64(a: *const f64) -> float64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld2r))]
    @@ -11645,7 +11645,7 @@ pub unsafe fn vld2q_dup_s64(a: *const i64) -> int64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -11663,7 +11663,7 @@ pub unsafe fn vld2_f64(a: *const f64) -> float64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11683,7 +11683,7 @@ pub unsafe fn vld2_lane_f64(a: *const f64, b: float64x1x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11703,7 +11703,7 @@ pub unsafe fn vld2_lane_s64(a: *const i64, b: int64x1x2_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11716,7 +11716,7 @@ pub unsafe fn vld2_lane_p64(a: *const p64, b: poly64x1x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11729,7 +11729,7 @@ pub unsafe fn vld2_lane_u64(a: *const u64, b: uint64x1x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11741,7 +11741,7 @@ pub unsafe fn vld2q_dup_p64(a: *const p64) -> poly64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11756,7 +11756,7 @@ pub unsafe fn vld2q_dup_p64(a: *const p64) -> poly64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11768,7 +11768,7 @@ pub unsafe fn vld2q_dup_u64(a: *const u64) -> uint64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11783,7 +11783,7 @@ pub unsafe fn vld2q_dup_u64(a: *const u64) -> uint64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld2))]
    @@ -11801,7 +11801,7 @@ pub unsafe fn vld2q_f64(a: *const f64) -> float64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld2))]
    @@ -11819,7 +11819,7 @@ pub unsafe fn vld2q_s64(a: *const i64) -> int64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11840,7 +11840,7 @@ pub unsafe fn vld2q_lane_f64(a: *const f64, b: float64x2x2_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11860,7 +11860,7 @@ pub unsafe fn vld2q_lane_s8(a: *const i8, b: int8x16x2_t) -> in
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11880,7 +11880,7 @@ pub unsafe fn vld2q_lane_s64(a: *const i64, b: int64x2x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11893,7 +11893,7 @@ pub unsafe fn vld2q_lane_p64(a: *const p64, b: poly64x2x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11906,7 +11906,7 @@ pub unsafe fn vld2q_lane_u8(a: *const u8, b: uint8x16x2_t) -> u
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11919,7 +11919,7 @@ pub unsafe fn vld2q_lane_u64(a: *const u64, b: uint64x2x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -11932,7 +11932,7 @@ pub unsafe fn vld2q_lane_p8(a: *const p8, b: poly8x16x2_t) -> p
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11944,7 +11944,7 @@ pub unsafe fn vld2q_p64(a: *const p64) -> poly64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11959,7 +11959,7 @@ pub unsafe fn vld2q_p64(a: *const p64) -> poly64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11971,7 +11971,7 @@ pub unsafe fn vld2q_u64(a: *const u64) -> uint64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -11986,7 +11986,7 @@ pub unsafe fn vld2q_u64(a: *const u64) -> uint64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld3r))]
    @@ -12004,7 +12004,7 @@ pub unsafe fn vld3_dup_f64(a: *const f64) -> float64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld3r))]
    @@ -12022,7 +12022,7 @@ pub unsafe fn vld3q_dup_f64(a: *const f64) -> float64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld3r))]
    @@ -12040,7 +12040,7 @@ pub unsafe fn vld3q_dup_s64(a: *const i64) -> int64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -12058,7 +12058,7 @@ pub unsafe fn vld3_f64(a: *const f64) -> float64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12084,7 +12084,7 @@ pub unsafe fn vld3_lane_f64(a: *const f64, b: float64x1x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12097,7 +12097,7 @@ pub unsafe fn vld3_lane_p64(a: *const p64, b: poly64x1x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12123,7 +12123,7 @@ pub unsafe fn vld3_lane_s64(a: *const i64, b: int64x1x3_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12136,7 +12136,7 @@ pub unsafe fn vld3_lane_u64(a: *const u64, b: uint64x1x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12148,7 +12148,7 @@ pub unsafe fn vld3q_dup_p64(a: *const p64) -> poly64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12164,7 +12164,7 @@ pub unsafe fn vld3q_dup_p64(a: *const p64) -> poly64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12176,7 +12176,7 @@ pub unsafe fn vld3q_dup_u64(a: *const u64) -> uint64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12192,7 +12192,7 @@ pub unsafe fn vld3q_dup_u64(a: *const u64) -> uint64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld3))]
    @@ -12210,7 +12210,7 @@ pub unsafe fn vld3q_f64(a: *const f64) -> float64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld3))]
    @@ -12228,7 +12228,7 @@ pub unsafe fn vld3q_s64(a: *const i64) -> int64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12254,7 +12254,7 @@ pub unsafe fn vld3q_lane_f64(a: *const f64, b: float64x2x3_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12267,7 +12267,7 @@ pub unsafe fn vld3q_lane_p64(a: *const p64, b: poly64x2x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12293,7 +12293,7 @@ pub unsafe fn vld3q_lane_s8(a: *const i8, b: int8x16x3_t) -> in
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12319,7 +12319,7 @@ pub unsafe fn vld3q_lane_s64(a: *const i64, b: int64x2x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12332,7 +12332,7 @@ pub unsafe fn vld3q_lane_u8(a: *const u8, b: uint8x16x3_t) -> u
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12345,7 +12345,7 @@ pub unsafe fn vld3q_lane_u64(a: *const u64, b: uint64x2x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12358,7 +12358,7 @@ pub unsafe fn vld3q_lane_p8(a: *const p8, b: poly8x16x3_t) -> p
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12370,7 +12370,7 @@ pub unsafe fn vld3q_p64(a: *const p64) -> poly64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12386,7 +12386,7 @@ pub unsafe fn vld3q_p64(a: *const p64) -> poly64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12398,7 +12398,7 @@ pub unsafe fn vld3q_u64(a: *const u64) -> uint64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12414,7 +12414,7 @@ pub unsafe fn vld3q_u64(a: *const u64) -> uint64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4r))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12432,7 +12432,7 @@ pub unsafe fn vld4_dup_f64(a: *const f64) -> float64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4r))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12450,7 +12450,7 @@ pub unsafe fn vld4q_dup_f64(a: *const f64) -> float64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4r))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12468,7 +12468,7 @@ pub unsafe fn vld4q_dup_s64(a: *const i64) -> int64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -12486,7 +12486,7 @@ pub unsafe fn vld4_f64(a: *const f64) -> float64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12513,7 +12513,7 @@ pub unsafe fn vld4_lane_f64(a: *const f64, b: float64x1x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12540,7 +12540,7 @@ pub unsafe fn vld4_lane_s64(a: *const i64, b: int64x1x4_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12553,7 +12553,7 @@ pub unsafe fn vld4_lane_p64(a: *const p64, b: poly64x1x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12566,7 +12566,7 @@ pub unsafe fn vld4_lane_u64(a: *const u64, b: uint64x1x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -12578,7 +12578,7 @@ pub unsafe fn vld4q_dup_p64(a: *const p64) -> poly64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -12595,7 +12595,7 @@ pub unsafe fn vld4q_dup_p64(a: *const p64) -> poly64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -12607,7 +12607,7 @@ pub unsafe fn vld4q_dup_u64(a: *const u64) -> uint64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -12624,7 +12624,7 @@ pub unsafe fn vld4q_dup_u64(a: *const u64) -> uint64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld4))]
    @@ -12642,7 +12642,7 @@ pub unsafe fn vld4q_f64(a: *const f64) -> float64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ld4))]
    @@ -12660,7 +12660,7 @@ pub unsafe fn vld4q_s64(a: *const i64) -> int64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12687,7 +12687,7 @@ pub unsafe fn vld4q_lane_f64(a: *const f64, b: float64x2x4_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12714,7 +12714,7 @@ pub unsafe fn vld4q_lane_s8(a: *const i8, b: int8x16x4_t) -> in
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12741,7 +12741,7 @@ pub unsafe fn vld4q_lane_s64(a: *const i64, b: int64x2x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12754,7 +12754,7 @@ pub unsafe fn vld4q_lane_p64(a: *const p64, b: poly64x2x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12767,7 +12767,7 @@ pub unsafe fn vld4q_lane_u8(a: *const u8, b: uint8x16x4_t) -> u
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12780,7 +12780,7 @@ pub unsafe fn vld4q_lane_u64(a: *const u64, b: uint64x2x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -12793,7 +12793,7 @@ pub unsafe fn vld4q_lane_p8(a: *const p8, b: poly8x16x4_t) -> p
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[target_feature(enable = "neon,aes")]
    @@ -12805,7 +12805,7 @@ pub unsafe fn vld4q_p64(a: *const p64) -> poly64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[target_feature(enable = "neon,aes")]
    @@ -12822,7 +12822,7 @@ pub unsafe fn vld4q_p64(a: *const p64) -> poly64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12834,7 +12834,7 @@ pub unsafe fn vld4q_u64(a: *const u64) -> uint64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -12851,7 +12851,7 @@ pub unsafe fn vld4q_u64(a: *const u64) -> uint64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -12871,7 +12871,7 @@ pub unsafe fn vluti2_lane_s8(a: int8x8_t, b: uint8x8_t) -> int8
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -12891,7 +12891,7 @@ pub unsafe fn vluti2q_lane_s8(a: int8x16_t, b: uint8x8_t) -> in
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -12911,7 +12911,7 @@ pub unsafe fn vluti2_lane_s16(a: int16x4_t, b: uint8x8_t) -> in
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -12931,7 +12931,7 @@ pub unsafe fn vluti2q_lane_s16(a: int16x8_t, b: uint8x8_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -12944,7 +12944,7 @@ pub unsafe fn vluti2_lane_u8(a: uint8x8_t, b: uint8x8_t) -> uin
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -12957,7 +12957,7 @@ pub unsafe fn vluti2q_lane_u8(a: uint8x16_t, b: uint8x8_t) -> u
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -12970,7 +12970,7 @@ pub unsafe fn vluti2_lane_u16(a: uint16x4_t, b: uint8x8_t) -> u
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2q_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -12983,7 +12983,7 @@ pub unsafe fn vluti2q_lane_u16(a: uint16x8_t, b: uint8x8_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -12996,7 +12996,7 @@ pub unsafe fn vluti2_lane_p8(a: poly8x8_t, b: uint8x8_t) -> pol
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13009,7 +13009,7 @@ pub unsafe fn vluti2q_lane_p8(a: poly8x16_t, b: uint8x8_t) -> p
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13022,7 +13022,7 @@ pub unsafe fn vluti2_lane_p16(a: poly16x4_t, b: uint8x8_t) -> p
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti2q_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 1))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13035,7 +13035,7 @@ pub unsafe fn vluti2q_lane_p16(a: poly16x8_t, b: uint8x8_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_lane_f16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut,fp16")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13048,7 +13048,7 @@ pub unsafe fn vluti4q_lane_f16_x2(a: float16x8x2_t, b: uint8x8_
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_lane_u16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13061,7 +13061,7 @@ pub unsafe fn vluti4q_lane_u16_x2(a: uint16x8x2_t, b: uint8x8_t
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_lane_p16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13074,7 +13074,7 @@ pub unsafe fn vluti4q_lane_p16_x2(a: poly16x8x2_t, b: uint8x8_t
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_lane_s16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13094,7 +13094,7 @@ pub unsafe fn vluti4q_lane_s16_x2(a: int16x8x2_t, b: uint8x8_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13114,7 +13114,7 @@ pub unsafe fn vluti4q_lane_s8(a: int8x16_t, b: uint8x8_t) -> in
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13127,7 +13127,7 @@ pub unsafe fn vluti4q_lane_u8(a: uint8x16_t, b: uint8x8_t) -> u
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13140,7 +13140,7 @@ pub unsafe fn vluti4q_lane_p8(a: poly8x16_t, b: uint8x8_t) -> p
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_laneq_f16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut,fp16")]
     #[cfg_attr(test, assert_instr(nop, LANE = 3))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13156,7 +13156,7 @@ pub unsafe fn vluti4q_laneq_f16_x2(
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_laneq_u16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 3))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13169,7 +13169,7 @@ pub unsafe fn vluti4q_laneq_u16_x2(a: uint16x8x2_t, b: uint8x16
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_laneq_p16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 3))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13182,7 +13182,7 @@ pub unsafe fn vluti4q_laneq_p16_x2(a: poly16x8x2_t, b: uint8x16
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_laneq_s16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 3))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13202,7 +13202,7 @@ pub unsafe fn vluti4q_laneq_s16_x2(a: int16x8x2_t, b: uint8x16_
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_laneq_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13222,7 +13222,7 @@ pub unsafe fn vluti4q_laneq_s8(a: int8x16_t, b: uint8x16_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_laneq_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13235,7 +13235,7 @@ pub unsafe fn vluti4q_laneq_u8(a: uint8x16_t, b: uint8x16_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vluti4q_laneq_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,lut")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[unstable(feature = "stdarch_neon_feat_lut", issue = "138050")]
    @@ -13246,7 +13246,7 @@ pub unsafe fn vluti4q_laneq_p8(a: poly8x16_t, b: uint8x16_t) ->
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmax))]
    @@ -13262,7 +13262,7 @@ pub fn vmax_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmax))]
    @@ -13278,7 +13278,7 @@ pub fn vmaxq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13295,7 +13295,7 @@ pub fn vmaxh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Floating-point Maximum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnm_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxnm))]
    @@ -13304,7 +13304,7 @@ pub fn vmaxnm_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point Maximum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxnm))]
    @@ -13313,7 +13313,7 @@ pub fn vmaxnmq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point Maximum Number"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13323,7 +13323,7 @@ pub fn vmaxnmh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Floating-point maximum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmv_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13333,7 +13333,7 @@ pub fn vmaxnmv_f16(a: float16x4_t) -> f16 {
     }
     #[doc = "Floating-point maximum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmvq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13343,7 +13343,7 @@ pub fn vmaxnmvq_f16(a: float16x8_t) -> f16 {
     }
     #[doc = "Floating-point maximum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmv_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxnmp))]
    @@ -13352,7 +13352,7 @@ pub fn vmaxnmv_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Floating-point maximum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmvq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxnmp))]
    @@ -13361,7 +13361,7 @@ pub fn vmaxnmvq_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point maximum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmvq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxnmv))]
    @@ -13370,7 +13370,7 @@ pub fn vmaxnmvq_f32(a: float32x4_t) -> f32 {
     }
     #[doc = "Floating-point maximum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxv_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13387,7 +13387,7 @@ pub fn vmaxv_f16(a: float16x4_t) -> f16 {
     }
     #[doc = "Floating-point maximum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxvq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13404,7 +13404,7 @@ pub fn vmaxvq_f16(a: float16x8_t) -> f16 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxv_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxp))]
    @@ -13420,7 +13420,7 @@ pub fn vmaxv_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxvq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxv))]
    @@ -13436,7 +13436,7 @@ pub fn vmaxvq_f32(a: float32x4_t) -> f32 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxvq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxp))]
    @@ -13452,7 +13452,7 @@ pub fn vmaxvq_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxv_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smaxv))]
    @@ -13461,7 +13461,7 @@ pub fn vmaxv_s8(a: int8x8_t) -> i8 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxvq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smaxv))]
    @@ -13470,7 +13470,7 @@ pub fn vmaxvq_s8(a: int8x16_t) -> i8 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxv_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smaxv))]
    @@ -13479,7 +13479,7 @@ pub fn vmaxv_s16(a: int16x4_t) -> i16 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxvq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smaxv))]
    @@ -13488,7 +13488,7 @@ pub fn vmaxvq_s16(a: int16x8_t) -> i16 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxv_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smaxp))]
    @@ -13497,7 +13497,7 @@ pub fn vmaxv_s32(a: int32x2_t) -> i32 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxvq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smaxv))]
    @@ -13506,7 +13506,7 @@ pub fn vmaxvq_s32(a: int32x4_t) -> i32 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxv_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umaxv))]
    @@ -13515,7 +13515,7 @@ pub fn vmaxv_u8(a: uint8x8_t) -> u8 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxvq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umaxv))]
    @@ -13524,7 +13524,7 @@ pub fn vmaxvq_u8(a: uint8x16_t) -> u8 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxv_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umaxv))]
    @@ -13533,7 +13533,7 @@ pub fn vmaxv_u16(a: uint16x4_t) -> u16 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxvq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umaxv))]
    @@ -13542,7 +13542,7 @@ pub fn vmaxvq_u16(a: uint16x8_t) -> u16 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxv_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umaxp))]
    @@ -13551,7 +13551,7 @@ pub fn vmaxv_u32(a: uint32x2_t) -> u32 {
     }
     #[doc = "Horizontal vector max."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxvq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umaxv))]
    @@ -13560,7 +13560,7 @@ pub fn vmaxvq_u32(a: uint32x4_t) -> u32 {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmin))]
    @@ -13576,7 +13576,7 @@ pub fn vmin_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmin))]
    @@ -13592,7 +13592,7 @@ pub fn vminq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13609,7 +13609,7 @@ pub fn vminh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Floating-point Minimum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnm_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fminnm))]
    @@ -13618,7 +13618,7 @@ pub fn vminnm_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point Minimum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fminnm))]
    @@ -13627,7 +13627,7 @@ pub fn vminnmq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point Minimum Number"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13637,7 +13637,7 @@ pub fn vminnmh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Floating-point minimum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmv_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13647,7 +13647,7 @@ pub fn vminnmv_f16(a: float16x4_t) -> f16 {
     }
     #[doc = "Floating-point minimum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmvq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13657,7 +13657,7 @@ pub fn vminnmvq_f16(a: float16x8_t) -> f16 {
     }
     #[doc = "Floating-point minimum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmv_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fminnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -13666,7 +13666,7 @@ pub fn vminnmv_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Floating-point minimum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmvq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fminnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -13675,7 +13675,7 @@ pub fn vminnmvq_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point minimum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmvq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fminnmv))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -13684,7 +13684,7 @@ pub fn vminnmvq_f32(a: float32x4_t) -> f32 {
     }
     #[doc = "Floating-point minimum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminv_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13701,7 +13701,7 @@ pub fn vminv_f16(a: float16x4_t) -> f16 {
     }
     #[doc = "Floating-point minimum number across vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminvq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -13718,7 +13718,7 @@ pub fn vminvq_f16(a: float16x8_t) -> f16 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminv_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fminp))]
    @@ -13734,7 +13734,7 @@ pub fn vminv_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminvq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fminv))]
    @@ -13750,7 +13750,7 @@ pub fn vminvq_f32(a: float32x4_t) -> f32 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminvq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fminp))]
    @@ -13766,7 +13766,7 @@ pub fn vminvq_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminv_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sminv))]
    @@ -13775,7 +13775,7 @@ pub fn vminv_s8(a: int8x8_t) -> i8 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminvq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sminv))]
    @@ -13784,7 +13784,7 @@ pub fn vminvq_s8(a: int8x16_t) -> i8 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminv_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sminv))]
    @@ -13793,7 +13793,7 @@ pub fn vminv_s16(a: int16x4_t) -> i16 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminvq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sminv))]
    @@ -13802,7 +13802,7 @@ pub fn vminvq_s16(a: int16x8_t) -> i16 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminv_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sminp))]
    @@ -13811,7 +13811,7 @@ pub fn vminv_s32(a: int32x2_t) -> i32 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminvq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sminv))]
    @@ -13820,7 +13820,7 @@ pub fn vminvq_s32(a: int32x4_t) -> i32 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminv_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uminv))]
    @@ -13829,7 +13829,7 @@ pub fn vminv_u8(a: uint8x8_t) -> u8 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminvq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uminv))]
    @@ -13838,7 +13838,7 @@ pub fn vminvq_u8(a: uint8x16_t) -> u8 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminv_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uminv))]
    @@ -13847,7 +13847,7 @@ pub fn vminv_u16(a: uint16x4_t) -> u16 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminvq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uminv))]
    @@ -13856,7 +13856,7 @@ pub fn vminvq_u16(a: uint16x8_t) -> u16 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminv_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uminp))]
    @@ -13865,7 +13865,7 @@ pub fn vminv_u32(a: uint32x2_t) -> u32 {
     }
     #[doc = "Horizontal vector min."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminvq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uminv))]
    @@ -13874,7 +13874,7 @@ pub fn vminvq_u32(a: uint32x4_t) -> u32 {
     }
     #[doc = "Floating-point multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -13883,7 +13883,7 @@ pub fn vmla_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -13892,7 +13892,7 @@ pub fn vmlaq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlal2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -13922,7 +13922,7 @@ pub fn vmlal_high_lane_s16(a: int32x4_t, b: int16x8_t, c: int16
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlal2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -13956,7 +13956,7 @@ pub fn vmlal_high_laneq_s16(
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlal2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -13973,7 +13973,7 @@ pub fn vmlal_high_lane_s32(a: int64x2_t, b: int32x4_t, c: int32
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlal2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -13994,7 +13994,7 @@ pub fn vmlal_high_laneq_s32(
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlal2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14028,7 +14028,7 @@ pub fn vmlal_high_lane_u16(
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlal2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14062,7 +14062,7 @@ pub fn vmlal_high_laneq_u16(
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlal2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14083,7 +14083,7 @@ pub fn vmlal_high_lane_u32(
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlal2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14104,7 +14104,7 @@ pub fn vmlal_high_laneq_u32(
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14113,7 +14113,7 @@ pub fn vmlal_high_n_s16(a: int32x4_t, b: int16x8_t, c: i16) -> int32x4_t {
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14122,7 +14122,7 @@ pub fn vmlal_high_n_s32(a: int64x2_t, b: int32x4_t, c: i32) -> int64x2_t {
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14131,7 +14131,7 @@ pub fn vmlal_high_n_u16(a: uint32x4_t, b: uint16x8_t, c: u16) -> uint32x4_t {
     }
     #[doc = "Multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14140,7 +14140,7 @@ pub fn vmlal_high_n_u32(a: uint64x2_t, b: uint32x4_t, c: u32) -> uint64x2_t {
     }
     #[doc = "Signed multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14153,7 +14153,7 @@ pub fn vmlal_high_s8(a: int16x8_t, b: int8x16_t, c: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14166,7 +14166,7 @@ pub fn vmlal_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14179,7 +14179,7 @@ pub fn vmlal_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int64x2_t {
     }
     #[doc = "Unsigned multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14192,7 +14192,7 @@ pub fn vmlal_high_u8(a: uint16x8_t, b: uint8x16_t, c: uint8x16_t) -> uint16x8_t
     }
     #[doc = "Unsigned multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14205,7 +14205,7 @@ pub fn vmlal_high_u16(a: uint32x4_t, b: uint16x8_t, c: uint16x8_t) -> uint32x4_t
     }
     #[doc = "Unsigned multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14218,7 +14218,7 @@ pub fn vmlal_high_u32(a: uint64x2_t, b: uint32x4_t, c: uint32x4_t) -> uint64x2_t
     }
     #[doc = "Floating-point multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14227,7 +14227,7 @@ pub fn vmls_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14236,7 +14236,7 @@ pub fn vmlsq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlsl2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14266,7 +14266,7 @@ pub fn vmlsl_high_lane_s16(a: int32x4_t, b: int16x8_t, c: int16
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlsl2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14300,7 +14300,7 @@ pub fn vmlsl_high_laneq_s16(
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlsl2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14317,7 +14317,7 @@ pub fn vmlsl_high_lane_s32(a: int64x2_t, b: int32x4_t, c: int32
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlsl2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14338,7 +14338,7 @@ pub fn vmlsl_high_laneq_s32(
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlsl2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14372,7 +14372,7 @@ pub fn vmlsl_high_lane_u16(
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlsl2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14406,7 +14406,7 @@ pub fn vmlsl_high_laneq_u16(
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlsl2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14427,7 +14427,7 @@ pub fn vmlsl_high_lane_u32(
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlsl2, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -14448,7 +14448,7 @@ pub fn vmlsl_high_laneq_u32(
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14457,7 +14457,7 @@ pub fn vmlsl_high_n_s16(a: int32x4_t, b: int16x8_t, c: i16) -> int32x4_t {
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14466,7 +14466,7 @@ pub fn vmlsl_high_n_s32(a: int64x2_t, b: int32x4_t, c: i32) -> int64x2_t {
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14475,7 +14475,7 @@ pub fn vmlsl_high_n_u16(a: uint32x4_t, b: uint16x8_t, c: u16) -> uint32x4_t {
     }
     #[doc = "Multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14484,7 +14484,7 @@ pub fn vmlsl_high_n_u32(a: uint64x2_t, b: uint32x4_t, c: u32) -> uint64x2_t {
     }
     #[doc = "Signed multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14497,7 +14497,7 @@ pub fn vmlsl_high_s8(a: int16x8_t, b: int8x16_t, c: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14510,7 +14510,7 @@ pub fn vmlsl_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14523,7 +14523,7 @@ pub fn vmlsl_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int64x2_t {
     }
     #[doc = "Unsigned multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14536,7 +14536,7 @@ pub fn vmlsl_high_u8(a: uint16x8_t, b: uint8x16_t, c: uint8x16_t) -> uint16x8_t
     }
     #[doc = "Unsigned multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14549,7 +14549,7 @@ pub fn vmlsl_high_u16(a: uint32x4_t, b: uint16x8_t, c: uint16x8_t) -> uint32x4_t
     }
     #[doc = "Unsigned multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14562,7 +14562,7 @@ pub fn vmlsl_high_u32(a: uint64x2_t, b: uint32x4_t, c: uint32x4_t) -> uint64x2_t
     }
     #[doc = "Vector move"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sxtl2))]
    @@ -14574,7 +14574,7 @@ pub fn vmovl_high_s8(a: int8x16_t) -> int16x8_t {
     }
     #[doc = "Vector move"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sxtl2))]
    @@ -14586,7 +14586,7 @@ pub fn vmovl_high_s16(a: int16x8_t) -> int32x4_t {
     }
     #[doc = "Vector move"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sxtl2))]
    @@ -14598,7 +14598,7 @@ pub fn vmovl_high_s32(a: int32x4_t) -> int64x2_t {
     }
     #[doc = "Vector move"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uxtl2))]
    @@ -14610,7 +14610,7 @@ pub fn vmovl_high_u8(a: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Vector move"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uxtl2))]
    @@ -14622,7 +14622,7 @@ pub fn vmovl_high_u16(a: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Vector move"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uxtl2))]
    @@ -14634,7 +14634,7 @@ pub fn vmovl_high_u32(a: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(xtn2))]
    @@ -14646,7 +14646,7 @@ pub fn vmovn_high_s16(a: int8x8_t, b: int16x8_t) -> int8x16_t {
     }
     #[doc = "Extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(xtn2))]
    @@ -14658,7 +14658,7 @@ pub fn vmovn_high_s32(a: int16x4_t, b: int32x4_t) -> int16x8_t {
     }
     #[doc = "Extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(xtn2))]
    @@ -14670,7 +14670,7 @@ pub fn vmovn_high_s64(a: int32x2_t, b: int64x2_t) -> int32x4_t {
     }
     #[doc = "Extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(xtn2))]
    @@ -14682,7 +14682,7 @@ pub fn vmovn_high_u16(a: uint8x8_t, b: uint16x8_t) -> uint8x16_t {
     }
     #[doc = "Extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(xtn2))]
    @@ -14694,7 +14694,7 @@ pub fn vmovn_high_u32(a: uint16x4_t, b: uint32x4_t) -> uint16x8_t {
     }
     #[doc = "Extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_high_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(xtn2))]
    @@ -14706,7 +14706,7 @@ pub fn vmovn_high_u64(a: uint32x2_t, b: uint64x2_t) -> uint32x4_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmul))]
    @@ -14715,7 +14715,7 @@ pub fn vmul_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmul))]
    @@ -14724,7 +14724,7 @@ pub fn vmulq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -14735,7 +14735,7 @@ pub fn vmul_lane_f64(a: float64x1_t, b: float64x1_t) -> float64
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -14752,7 +14752,7 @@ pub fn vmul_laneq_f16(a: float16x4_t, b: float16x8_t) -> float1
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -14782,7 +14782,7 @@ pub fn vmulq_laneq_f16(a: float16x8_t, b: float16x8_t) -> float
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -14793,7 +14793,7 @@ pub fn vmul_laneq_f64(a: float64x1_t, b: float64x2_t) -> float6
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14802,7 +14802,7 @@ pub fn vmul_n_f64(a: float64x1_t, b: f64) -> float64x1_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -14811,7 +14811,7 @@ pub fn vmulq_n_f64(a: float64x2_t, b: f64) -> float64x2_t {
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuld_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -14825,7 +14825,7 @@ pub fn vmuld_lane_f64(a: f64, b: float64x1_t) -> f64 {
     }
     #[doc = "Add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -14835,7 +14835,7 @@ pub fn vmulh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulh_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -14850,7 +14850,7 @@ pub fn vmulh_lane_f16(a: f16, b: float16x4_t) -> f16 {
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulh_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -14865,7 +14865,7 @@ pub fn vmulh_laneq_f16(a: f16, b: float16x8_t) -> f16 {
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smull2, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -14894,7 +14894,7 @@ pub fn vmull_high_lane_s16(a: int16x8_t, b: int16x4_t) -> int32
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smull2, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -14923,7 +14923,7 @@ pub fn vmull_high_laneq_s16(a: int16x8_t, b: int16x8_t) -> int3
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smull2, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -14939,7 +14939,7 @@ pub fn vmull_high_lane_s32(a: int32x4_t, b: int32x2_t) -> int64
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smull2, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -14955,7 +14955,7 @@ pub fn vmull_high_laneq_s32(a: int32x4_t, b: int32x4_t) -> int6
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umull2, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -14984,7 +14984,7 @@ pub fn vmull_high_lane_u16(a: uint16x8_t, b: uint16x4_t) -> uin
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umull2, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -15013,7 +15013,7 @@ pub fn vmull_high_laneq_u16(a: uint16x8_t, b: uint16x8_t) -> ui
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umull2, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -15029,7 +15029,7 @@ pub fn vmull_high_lane_u32(a: uint32x4_t, b: uint32x2_t) -> uin
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umull2, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -15045,7 +15045,7 @@ pub fn vmull_high_laneq_u32(a: uint32x4_t, b: uint32x4_t) -> ui
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smull2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15054,7 +15054,7 @@ pub fn vmull_high_n_s16(a: int16x8_t, b: i16) -> int32x4_t {
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(smull2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15063,7 +15063,7 @@ pub fn vmull_high_n_s32(a: int32x4_t, b: i32) -> int64x2_t {
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umull2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15072,7 +15072,7 @@ pub fn vmull_high_n_u16(a: uint16x8_t, b: u16) -> uint32x4_t {
     }
     #[doc = "Multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(umull2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15081,7 +15081,7 @@ pub fn vmull_high_n_u32(a: uint32x4_t, b: u32) -> uint64x2_t {
     }
     #[doc = "Polynomial multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(pmull2))]
    @@ -15090,7 +15090,7 @@ pub fn vmull_high_p64(a: poly64x2_t, b: poly64x2_t) -> p128 {
     }
     #[doc = "Polynomial multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(pmull2))]
    @@ -15103,7 +15103,7 @@ pub fn vmull_high_p8(a: poly8x16_t, b: poly8x16_t) -> poly16x8_t {
     }
     #[doc = "Signed multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smull2))]
    @@ -15116,7 +15116,7 @@ pub fn vmull_high_s8(a: int8x16_t, b: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smull2))]
    @@ -15129,7 +15129,7 @@ pub fn vmull_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smull2))]
    @@ -15142,7 +15142,7 @@ pub fn vmull_high_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t {
     }
     #[doc = "Unsigned multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umull2))]
    @@ -15155,7 +15155,7 @@ pub fn vmull_high_u8(a: uint8x16_t, b: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Unsigned multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umull2))]
    @@ -15168,7 +15168,7 @@ pub fn vmull_high_u16(a: uint16x8_t, b: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Unsigned multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umull2))]
    @@ -15181,7 +15181,7 @@ pub fn vmull_high_u32(a: uint32x4_t, b: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Polynomial multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(pmull))]
    @@ -15197,7 +15197,7 @@ pub fn vmull_p64(a: p64, b: p64) -> p128 {
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15208,7 +15208,7 @@ pub fn vmulq_lane_f64(a: float64x2_t, b: float64x1_t) -> float6
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15219,7 +15219,7 @@ pub fn vmulq_laneq_f64(a: float64x2_t, b: float64x2_t) -> float
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuls_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15233,7 +15233,7 @@ pub fn vmuls_lane_f32(a: f32, b: float32x2_t) -> f32 {
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuls_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15247,7 +15247,7 @@ pub fn vmuls_laneq_f32(a: f32, b: float32x4_t) -> f32 {
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuld_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmul, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15261,7 +15261,7 @@ pub fn vmuld_laneq_f64(a: f64, b: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -15278,7 +15278,7 @@ pub fn vmulx_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -15295,7 +15295,7 @@ pub fn vmulxq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmulx))]
    @@ -15311,7 +15311,7 @@ pub fn vmulx_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmulx))]
    @@ -15327,7 +15327,7 @@ pub fn vmulxq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmulx))]
    @@ -15343,7 +15343,7 @@ pub fn vmulx_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmulx))]
    @@ -15359,7 +15359,7 @@ pub fn vmulxq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -15376,7 +15376,7 @@ pub fn vmulx_lane_f16(a: float16x4_t, b: float16x4_t) -> float1
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -15393,7 +15393,7 @@ pub fn vmulx_laneq_f16(a: float16x4_t, b: float16x8_t) -> float
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -15423,7 +15423,7 @@ pub fn vmulxq_lane_f16(a: float16x8_t, b: float16x4_t) -> float
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -15453,7 +15453,7 @@ pub fn vmulxq_laneq_f16(a: float16x8_t, b: float16x8_t) -> floa
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15464,7 +15464,7 @@ pub fn vmulx_lane_f32(a: float32x2_t, b: float32x2_t) -> float3
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15475,7 +15475,7 @@ pub fn vmulx_laneq_f32(a: float32x2_t, b: float32x4_t) -> float
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15491,7 +15491,7 @@ pub fn vmulxq_lane_f32(a: float32x4_t, b: float32x2_t) -> float
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15507,7 +15507,7 @@ pub fn vmulxq_laneq_f32(a: float32x4_t, b: float32x4_t) -> floa
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15518,7 +15518,7 @@ pub fn vmulxq_laneq_f64(a: float64x2_t, b: float64x2_t) -> floa
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15529,7 +15529,7 @@ pub fn vmulx_lane_f64(a: float64x1_t, b: float64x1_t) -> float6
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15540,7 +15540,7 @@ pub fn vmulx_laneq_f64(a: float64x1_t, b: float64x2_t) -> float
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmulx))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -15550,7 +15550,7 @@ pub fn vmulx_n_f16(a: float16x4_t, b: f16) -> float16x4_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmulx))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -15560,7 +15560,7 @@ pub fn vmulxq_n_f16(a: float16x8_t, b: f16) -> float16x8_t {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmulx))]
    @@ -15576,7 +15576,7 @@ pub fn vmulxd_f64(a: f64, b: f64) -> f64 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmulx))]
    @@ -15592,7 +15592,7 @@ pub fn vmulxs_f32(a: f32, b: f32) -> f32 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxd_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15603,7 +15603,7 @@ pub fn vmulxd_lane_f64(a: f64, b: float64x1_t) -> f64 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxd_laneq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15614,7 +15614,7 @@ pub fn vmulxd_laneq_f64(a: f64, b: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxs_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15625,7 +15625,7 @@ pub fn vmulxs_lane_f32(a: f32, b: float32x2_t) -> f32 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxs_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15636,7 +15636,7 @@ pub fn vmulxs_laneq_f32(a: f32, b: float32x4_t) -> f32 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -15653,7 +15653,7 @@ pub fn vmulxh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxh_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -15665,7 +15665,7 @@ pub fn vmulxh_lane_f16(a: f16, b: float16x4_t) -> f16 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxh_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
     #[target_feature(enable = "neon,fp16")]
    @@ -15677,7 +15677,7 @@ pub fn vmulxh_laneq_f16(a: f16, b: float16x8_t) -> f16 {
     }
     #[doc = "Floating-point multiply extended"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmulx, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -15688,7 +15688,7 @@ pub fn vmulxq_lane_f64(a: float64x2_t, b: float64x1_t) -> float
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fneg))]
    @@ -15697,7 +15697,7 @@ pub fn vneg_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fneg))]
    @@ -15706,7 +15706,7 @@ pub fn vnegq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(neg))]
    @@ -15715,7 +15715,7 @@ pub fn vneg_s64(a: int64x1_t) -> int64x1_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(neg))]
    @@ -15724,7 +15724,7 @@ pub fn vnegq_s64(a: int64x2_t) -> int64x2_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(neg))]
    @@ -15733,7 +15733,7 @@ pub fn vnegd_s64(a: i64) -> i64 {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -15743,7 +15743,7 @@ pub fn vnegh_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -15756,7 +15756,7 @@ pub fn vpaddd_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadds_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -15769,7 +15769,7 @@ pub fn vpadds_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -15778,7 +15778,7 @@ pub fn vpaddd_s64(a: int64x2_t) -> i64 {
     }
     #[doc = "Add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -15787,7 +15787,7 @@ pub fn vpaddd_u64(a: uint64x2_t) -> u64 {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -15804,7 +15804,7 @@ pub fn vpaddq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(faddp))]
    @@ -15820,7 +15820,7 @@ pub fn vpaddq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(faddp))]
    @@ -15836,7 +15836,7 @@ pub fn vpaddq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -15852,7 +15852,7 @@ pub fn vpaddq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -15868,7 +15868,7 @@ pub fn vpaddq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -15884,7 +15884,7 @@ pub fn vpaddq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(addp))]
    @@ -15900,7 +15900,7 @@ pub fn vpaddq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15910,7 +15910,7 @@ pub fn vpaddq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15931,7 +15931,7 @@ pub fn vpaddq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15941,7 +15941,7 @@ pub fn vpaddq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15956,7 +15956,7 @@ pub fn vpaddq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15966,7 +15966,7 @@ pub fn vpaddq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15981,7 +15981,7 @@ pub fn vpaddq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -15991,7 +15991,7 @@ pub fn vpaddq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Add Pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16006,7 +16006,7 @@ pub fn vpaddq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmax_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -16023,7 +16023,7 @@ pub fn vpmax_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -16040,7 +16040,7 @@ pub fn vpmaxq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnm_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -16057,7 +16057,7 @@ pub fn vpmaxnm_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnmq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -16074,7 +16074,7 @@ pub fn vpmaxnmq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point Maximum Number Pairwise (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnm_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmaxnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16090,7 +16090,7 @@ pub fn vpmaxnm_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point Maximum Number Pairwise (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnmq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmaxnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16106,7 +16106,7 @@ pub fn vpmaxnmq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point Maximum Number Pairwise (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnmq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmaxnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16122,7 +16122,7 @@ pub fn vpmaxnmq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point maximum number pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnmqd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmaxnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16138,7 +16138,7 @@ pub fn vpmaxnmqd_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point maximum number pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxnms_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fmaxnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16154,7 +16154,7 @@ pub fn vpmaxnms_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxp))]
    @@ -16170,7 +16170,7 @@ pub fn vpmaxq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxp))]
    @@ -16186,7 +16186,7 @@ pub fn vpmaxq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smaxp))]
    @@ -16202,7 +16202,7 @@ pub fn vpmaxq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smaxp))]
    @@ -16218,7 +16218,7 @@ pub fn vpmaxq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(smaxp))]
    @@ -16234,7 +16234,7 @@ pub fn vpmaxq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umaxp))]
    @@ -16250,7 +16250,7 @@ pub fn vpmaxq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umaxp))]
    @@ -16266,7 +16266,7 @@ pub fn vpmaxq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(umaxp))]
    @@ -16282,7 +16282,7 @@ pub fn vpmaxq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point maximum pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxqd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxp))]
    @@ -16298,7 +16298,7 @@ pub fn vpmaxqd_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point maximum pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fmaxp))]
    @@ -16314,7 +16314,7 @@ pub fn vpmaxs_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmin_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -16331,7 +16331,7 @@ pub fn vpmin_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -16348,7 +16348,7 @@ pub fn vpminq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnm_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -16365,7 +16365,7 @@ pub fn vpminnm_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnmq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -16382,7 +16382,7 @@ pub fn vpminnmq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point Minimum Number Pairwise (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnm_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fminnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16398,7 +16398,7 @@ pub fn vpminnm_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point Minimum Number Pairwise (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnmq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fminnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16414,7 +16414,7 @@ pub fn vpminnmq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point Minimum Number Pairwise (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnmq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fminnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16430,7 +16430,7 @@ pub fn vpminnmq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point minimum number pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnmqd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fminnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16446,7 +16446,7 @@ pub fn vpminnmqd_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point minimum number pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminnms_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fminnmp))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16462,7 +16462,7 @@ pub fn vpminnms_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fminp))]
    @@ -16478,7 +16478,7 @@ pub fn vpminq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fminp))]
    @@ -16494,7 +16494,7 @@ pub fn vpminq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sminp))]
    @@ -16510,7 +16510,7 @@ pub fn vpminq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sminp))]
    @@ -16526,7 +16526,7 @@ pub fn vpminq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sminp))]
    @@ -16542,7 +16542,7 @@ pub fn vpminq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uminp))]
    @@ -16558,7 +16558,7 @@ pub fn vpminq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uminp))]
    @@ -16574,7 +16574,7 @@ pub fn vpminq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uminp))]
    @@ -16590,7 +16590,7 @@ pub fn vpminq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point minimum pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpminqd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fminp))]
    @@ -16606,7 +16606,7 @@ pub fn vpminqd_f64(a: float64x2_t) -> f64 {
     }
     #[doc = "Floating-point minimum pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmins_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fminp))]
    @@ -16622,7 +16622,7 @@ pub fn vpmins_f32(a: float32x2_t) -> f32 {
     }
     #[doc = "Signed saturating Absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabs_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(sqabs))]
    @@ -16638,7 +16638,7 @@ pub fn vqabs_s64(a: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed saturating Absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(sqabs))]
    @@ -16654,7 +16654,7 @@ pub fn vqabsq_s64(a: int64x2_t) -> int64x2_t {
     }
     #[doc = "Signed saturating absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsb_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(sqabs))]
    @@ -16663,7 +16663,7 @@ pub fn vqabsb_s8(a: i8) -> i8 {
     }
     #[doc = "Signed saturating absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(sqabs))]
    @@ -16672,7 +16672,7 @@ pub fn vqabsh_s16(a: i16) -> i16 {
     }
     #[doc = "Signed saturating absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabss_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(sqabs))]
    @@ -16688,7 +16688,7 @@ pub fn vqabss_s32(a: i32) -> i32 {
     }
     #[doc = "Signed saturating absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(sqabs))]
    @@ -16704,7 +16704,7 @@ pub fn vqabsd_s64(a: i64) -> i64 {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddb_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqadd))]
    @@ -16715,7 +16715,7 @@ pub fn vqaddb_s8(a: i8, b: i8) -> i8 {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqadd))]
    @@ -16726,7 +16726,7 @@ pub fn vqaddh_s16(a: i16, b: i16) -> i16 {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddb_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uqadd))]
    @@ -16737,7 +16737,7 @@ pub fn vqaddb_u8(a: u8, b: u8) -> u8 {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddh_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uqadd))]
    @@ -16748,7 +16748,7 @@ pub fn vqaddh_u16(a: u16, b: u16) -> u16 {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadds_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqadd))]
    @@ -16764,7 +16764,7 @@ pub fn vqadds_s32(a: i32, b: i32) -> i32 {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqadd))]
    @@ -16780,7 +16780,7 @@ pub fn vqaddd_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadds_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uqadd))]
    @@ -16796,7 +16796,7 @@ pub fn vqadds_u32(a: u32, b: u32) -> u32 {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uqadd))]
    @@ -16812,7 +16812,7 @@ pub fn vqaddd_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal2, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -16823,7 +16823,7 @@ pub fn vqdmlal_high_lane_s16(a: int32x4_t, b: int16x8_t, c: int16x
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal2, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -16834,7 +16834,7 @@ pub fn vqdmlal_high_laneq_s16(a: int32x4_t, b: int16x8_t, c: int16
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal2, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -16845,7 +16845,7 @@ pub fn vqdmlal_high_lane_s32(a: int64x2_t, b: int32x4_t, c: int32x
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal2, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -16856,7 +16856,7 @@ pub fn vqdmlal_high_laneq_s32(a: int64x2_t, b: int32x4_t, c: int32
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16865,7 +16865,7 @@ pub fn vqdmlal_high_n_s16(a: int32x4_t, b: int16x8_t, c: i16) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16874,7 +16874,7 @@ pub fn vqdmlal_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16883,7 +16883,7 @@ pub fn vqdmlal_high_n_s32(a: int64x2_t, b: int32x4_t, c: i32) -> int64x2_t {
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16892,7 +16892,7 @@ pub fn vqdmlal_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int64x2_t {
     }
     #[doc = "Vector widening saturating doubling multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal, N = 2))]
     #[rustc_legacy_const_generics(3)]
    @@ -16903,7 +16903,7 @@ pub fn vqdmlal_laneq_s16(a: int32x4_t, b: int16x4_t, c: int16x8_t)
     }
     #[doc = "Vector widening saturating doubling multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -16914,7 +16914,7 @@ pub fn vqdmlal_laneq_s32(a: int64x2_t, b: int32x2_t, c: int32x4_t)
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlalh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -16925,7 +16925,7 @@ pub fn vqdmlalh_lane_s16(a: i32, b: i16, c: int16x4_t) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlalh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -16936,7 +16936,7 @@ pub fn vqdmlalh_laneq_s16(a: i32, b: i16, c: int16x8_t) -> i32
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlals_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -16947,7 +16947,7 @@ pub fn vqdmlals_lane_s32(a: i64, b: i32, c: int32x2_t) -> i64 {
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlals_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -16958,7 +16958,7 @@ pub fn vqdmlals_laneq_s32(a: i64, b: i32, c: int32x4_t) -> i64
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlalh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16968,7 +16968,7 @@ pub fn vqdmlalh_s16(a: i32, b: i16, c: i16) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlals_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlal))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -16978,7 +16978,7 @@ pub fn vqdmlals_s32(a: i64, b: i32, c: i32) -> i64 {
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl2, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -16989,7 +16989,7 @@ pub fn vqdmlsl_high_lane_s16(a: int32x4_t, b: int16x8_t, c: int16x
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl2, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17000,7 +17000,7 @@ pub fn vqdmlsl_high_laneq_s16(a: int32x4_t, b: int16x8_t, c: int16
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl2, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17011,7 +17011,7 @@ pub fn vqdmlsl_high_lane_s32(a: int64x2_t, b: int32x4_t, c: int32x
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl2, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17022,7 +17022,7 @@ pub fn vqdmlsl_high_laneq_s32(a: int64x2_t, b: int32x4_t, c: int32
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17031,7 +17031,7 @@ pub fn vqdmlsl_high_n_s16(a: int32x4_t, b: int16x8_t, c: i16) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17040,7 +17040,7 @@ pub fn vqdmlsl_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17049,7 +17049,7 @@ pub fn vqdmlsl_high_n_s32(a: int64x2_t, b: int32x4_t, c: i32) -> int64x2_t {
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17058,7 +17058,7 @@ pub fn vqdmlsl_high_s32(a: int64x2_t, b: int32x4_t, c: int32x4_t) -> int64x2_t {
     }
     #[doc = "Vector widening saturating doubling multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl, N = 2))]
     #[rustc_legacy_const_generics(3)]
    @@ -17069,7 +17069,7 @@ pub fn vqdmlsl_laneq_s16(a: int32x4_t, b: int16x4_t, c: int16x8_t)
     }
     #[doc = "Vector widening saturating doubling multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl, N = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17080,7 +17080,7 @@ pub fn vqdmlsl_laneq_s32(a: int64x2_t, b: int32x2_t, c: int32x4_t)
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlslh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -17091,7 +17091,7 @@ pub fn vqdmlslh_lane_s16(a: i32, b: i16, c: int16x4_t) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlslh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -17102,7 +17102,7 @@ pub fn vqdmlslh_laneq_s16(a: i32, b: i16, c: int16x8_t) -> i32
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsls_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -17113,7 +17113,7 @@ pub fn vqdmlsls_lane_s32(a: i64, b: i32, c: int32x2_t) -> i64 {
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsls_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl, LANE = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -17124,7 +17124,7 @@ pub fn vqdmlsls_laneq_s32(a: i64, b: i32, c: int32x4_t) -> i64
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlslh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17134,7 +17134,7 @@ pub fn vqdmlslh_s16(a: i32, b: i16, c: i16) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsls_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmlsl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17144,7 +17144,7 @@ pub fn vqdmlsls_s32(a: i64, b: i32, c: i32) -> i64 {
     }
     #[doc = "Vector saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -17155,7 +17155,7 @@ pub fn vqdmulh_lane_s16(a: int16x4_t, b: int16x4_t) -> int16x4_
     }
     #[doc = "Vector saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -17166,7 +17166,7 @@ pub fn vqdmulhq_lane_s16(a: int16x8_t, b: int16x4_t) -> int16x8
     }
     #[doc = "Vector saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -17177,7 +17177,7 @@ pub fn vqdmulh_lane_s32(a: int32x2_t, b: int32x2_t) -> int32x2_
     }
     #[doc = "Vector saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -17188,7 +17188,7 @@ pub fn vqdmulhq_lane_s32(a: int32x4_t, b: int32x2_t) -> int32x4
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -17202,7 +17202,7 @@ pub fn vqdmulhh_lane_s16(a: i16, b: int16x4_t) -> i16 {
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -17216,7 +17216,7 @@ pub fn vqdmulhh_laneq_s16(a: i16, b: int16x8_t) -> i16 {
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17227,7 +17227,7 @@ pub fn vqdmulhh_s16(a: i16, b: i16) -> i16 {
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhs_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17238,7 +17238,7 @@ pub fn vqdmulhs_s32(a: i32, b: i32) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhs_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -17252,7 +17252,7 @@ pub fn vqdmulhs_lane_s32(a: i32, b: int32x2_t) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhs_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmulh, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -17266,7 +17266,7 @@ pub fn vqdmulhs_laneq_s32(a: i32, b: int32x4_t) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -17281,7 +17281,7 @@ pub fn vqdmull_high_lane_s16(a: int16x8_t, b: int16x4_t) -> int32x
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -17296,7 +17296,7 @@ pub fn vqdmull_high_laneq_s32(a: int32x4_t, b: int32x4_t) -> int64
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull2, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -17311,7 +17311,7 @@ pub fn vqdmull_high_lane_s32(a: int32x4_t, b: int32x2_t) -> int64x
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull2, N = 4))]
     #[rustc_legacy_const_generics(2)]
    @@ -17326,7 +17326,7 @@ pub fn vqdmull_high_laneq_s16(a: int16x8_t, b: int16x8_t) -> int32
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17339,7 +17339,7 @@ pub fn vqdmull_high_n_s16(a: int16x8_t, b: i16) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17352,7 +17352,7 @@ pub fn vqdmull_high_n_s32(a: int32x4_t, b: i32) -> int64x2_t {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17365,7 +17365,7 @@ pub fn vqdmull_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17378,7 +17378,7 @@ pub fn vqdmull_high_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t {
     }
     #[doc = "Vector saturating doubling long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull, N = 4))]
     #[rustc_legacy_const_generics(2)]
    @@ -17392,7 +17392,7 @@ pub fn vqdmull_laneq_s16(a: int16x4_t, b: int16x8_t) -> int32x4_t
     }
     #[doc = "Vector saturating doubling long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -17406,7 +17406,7 @@ pub fn vqdmull_laneq_s32(a: int32x2_t, b: int32x4_t) -> int64x2_t
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmullh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -17420,7 +17420,7 @@ pub fn vqdmullh_lane_s16(a: i16, b: int16x4_t) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulls_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -17434,7 +17434,7 @@ pub fn vqdmulls_laneq_s32(a: i32, b: int32x4_t) -> i64 {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmullh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull, N = 4))]
     #[rustc_legacy_const_generics(2)]
    @@ -17448,7 +17448,7 @@ pub fn vqdmullh_laneq_s16(a: i16, b: int16x8_t) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmullh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17459,7 +17459,7 @@ pub fn vqdmullh_s16(a: i16, b: i16) -> i32 {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulls_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -17473,7 +17473,7 @@ pub fn vqdmulls_lane_s32(a: i32, b: int32x2_t) -> i64 {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulls_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqdmull))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17489,7 +17489,7 @@ pub fn vqdmulls_s32(a: i32, b: i32) -> i64 {
     }
     #[doc = "Signed saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtn2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17504,7 +17504,7 @@ pub fn vqmovn_high_s16(a: int8x8_t, b: int16x8_t) -> int8x16_t {
     }
     #[doc = "Signed saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtn2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17513,7 +17513,7 @@ pub fn vqmovn_high_s32(a: int16x4_t, b: int32x4_t) -> int16x8_t {
     }
     #[doc = "Signed saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtn2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17522,7 +17522,7 @@ pub fn vqmovn_high_s64(a: int32x2_t, b: int64x2_t) -> int32x4_t {
     }
     #[doc = "Signed saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqxtn2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17537,7 +17537,7 @@ pub fn vqmovn_high_u16(a: uint8x8_t, b: uint16x8_t) -> uint8x16_t {
     }
     #[doc = "Signed saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqxtn2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17546,7 +17546,7 @@ pub fn vqmovn_high_u32(a: uint16x4_t, b: uint32x4_t) -> uint16x8_t {
     }
     #[doc = "Signed saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_high_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqxtn2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17555,7 +17555,7 @@ pub fn vqmovn_high_u64(a: uint32x2_t, b: uint64x2_t) -> uint32x4_t {
     }
     #[doc = "Saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovnd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtn))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17571,7 +17571,7 @@ pub fn vqmovnd_s64(a: i64) -> i32 {
     }
     #[doc = "Saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovnd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqxtn))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17587,7 +17587,7 @@ pub fn vqmovnd_u64(a: u64) -> u32 {
     }
     #[doc = "Saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovnh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtn))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17596,7 +17596,7 @@ pub fn vqmovnh_s16(a: i16) -> i8 {
     }
     #[doc = "Saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovns_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtn))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17605,7 +17605,7 @@ pub fn vqmovns_s32(a: i32) -> i16 {
     }
     #[doc = "Saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovnh_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqxtn))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17614,7 +17614,7 @@ pub fn vqmovnh_u16(a: u16) -> u8 {
     }
     #[doc = "Saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovns_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqxtn))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17623,7 +17623,7 @@ pub fn vqmovns_u32(a: u32) -> u16 {
     }
     #[doc = "Signed saturating extract unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtun2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17638,7 +17638,7 @@ pub fn vqmovun_high_s16(a: uint8x8_t, b: int16x8_t) -> uint8x16_t {
     }
     #[doc = "Signed saturating extract unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtun2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17647,7 +17647,7 @@ pub fn vqmovun_high_s32(a: uint16x4_t, b: int32x4_t) -> uint16x8_t {
     }
     #[doc = "Signed saturating extract unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_high_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtun2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17656,7 +17656,7 @@ pub fn vqmovun_high_s64(a: uint32x2_t, b: int64x2_t) -> uint32x4_t {
     }
     #[doc = "Signed saturating extract unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovunh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtun))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17665,7 +17665,7 @@ pub fn vqmovunh_s16(a: i16) -> u8 {
     }
     #[doc = "Signed saturating extract unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovuns_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtun))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17674,7 +17674,7 @@ pub fn vqmovuns_s32(a: i32) -> u16 {
     }
     #[doc = "Signed saturating extract unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovund_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqxtun))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -17683,7 +17683,7 @@ pub fn vqmovund_s64(a: i64) -> u32 {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqneg))]
    @@ -17699,7 +17699,7 @@ pub fn vqneg_s64(a: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqneg))]
    @@ -17715,7 +17715,7 @@ pub fn vqnegq_s64(a: int64x2_t) -> int64x2_t {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegb_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqneg))]
    @@ -17724,7 +17724,7 @@ pub fn vqnegb_s8(a: i8) -> i8 {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqneg))]
    @@ -17733,7 +17733,7 @@ pub fn vqnegh_s16(a: i16) -> i16 {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegs_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqneg))]
    @@ -17742,7 +17742,7 @@ pub fn vqnegs_s32(a: i32) -> i32 {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqneg))]
    @@ -17751,7 +17751,7 @@ pub fn vqnegd_s64(a: i64) -> i64 {
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17766,7 +17766,7 @@ pub fn vqrdmlah_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17780,7 +17780,7 @@ pub fn vqrdmlah_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17795,7 +17795,7 @@ pub fn vqrdmlah_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17809,7 +17809,7 @@ pub fn vqrdmlah_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17836,7 +17836,7 @@ pub fn vqrdmlahq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17851,7 +17851,7 @@ pub fn vqrdmlahq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17878,7 +17878,7 @@ pub fn vqrdmlahq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17893,7 +17893,7 @@ pub fn vqrdmlahq_laneq_s32(a: int32x4_t, b: int32x4_t, c: int32
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -17909,7 +17909,7 @@ pub fn vqrdmlah_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -17925,7 +17925,7 @@ pub fn vqrdmlahq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlah_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -17941,7 +17941,7 @@ pub fn vqrdmlah_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -17957,7 +17957,7 @@ pub fn vqrdmlahq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17968,7 +17968,7 @@ pub fn vqrdmlahh_lane_s16(a: i16, b: i16, c: int16x4_t) -> i16
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17979,7 +17979,7 @@ pub fn vqrdmlahh_laneq_s16(a: i16, b: i16, c: int16x8_t) -> i16
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahs_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -17990,7 +17990,7 @@ pub fn vqrdmlahs_lane_s32(a: i32, b: i32, c: int32x2_t) -> i32
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahs_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18001,7 +18001,7 @@ pub fn vqrdmlahs_laneq_s32(a: i32, b: i32, c: int32x4_t) -> i32
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -18013,7 +18013,7 @@ pub fn vqrdmlahh_s16(a: i16, b: i16, c: i16) -> i16 {
     }
     #[doc = "Signed saturating rounding doubling multiply accumulate returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlahs_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlah))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -18025,7 +18025,7 @@ pub fn vqrdmlahs_s32(a: i32, b: i32, c: i32) -> i32 {
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18040,7 +18040,7 @@ pub fn vqrdmlsh_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18054,7 +18054,7 @@ pub fn vqrdmlsh_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18069,7 +18069,7 @@ pub fn vqrdmlsh_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18083,7 +18083,7 @@ pub fn vqrdmlsh_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18110,7 +18110,7 @@ pub fn vqrdmlshq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18125,7 +18125,7 @@ pub fn vqrdmlshq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18152,7 +18152,7 @@ pub fn vqrdmlshq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18167,7 +18167,7 @@ pub fn vqrdmlshq_laneq_s32(a: int32x4_t, b: int32x4_t, c: int32
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -18183,7 +18183,7 @@ pub fn vqrdmlsh_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -18199,7 +18199,7 @@ pub fn vqrdmlshq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlsh_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -18215,7 +18215,7 @@ pub fn vqrdmlsh_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -18231,7 +18231,7 @@ pub fn vqrdmlshq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18242,7 +18242,7 @@ pub fn vqrdmlshh_lane_s16(a: i16, b: i16, c: int16x4_t) -> i16
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18253,7 +18253,7 @@ pub fn vqrdmlshh_laneq_s16(a: i16, b: i16, c: int16x8_t) -> i16
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshs_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18264,7 +18264,7 @@ pub fn vqrdmlshs_lane_s32(a: i32, b: i32, c: int32x2_t) -> i32
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshs_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh, LANE = 1))]
     #[rustc_legacy_const_generics(3)]
    @@ -18275,7 +18275,7 @@ pub fn vqrdmlshs_laneq_s32(a: i32, b: i32, c: int32x4_t) -> i32
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -18287,7 +18287,7 @@ pub fn vqrdmlshh_s16(a: i16, b: i16, c: i16) -> i16 {
     }
     #[doc = "Signed saturating rounding doubling multiply subtract returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmlshs_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "rdm")]
     #[cfg_attr(test, assert_instr(sqrdmlsh))]
     #[stable(feature = "rdm_intrinsics", since = "1.62.0")]
    @@ -18299,7 +18299,7 @@ pub fn vqrdmlshs_s32(a: i32, b: i32, c: i32) -> i32 {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrdmulh, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -18310,7 +18310,7 @@ pub fn vqrdmulhh_lane_s16(a: i16, b: int16x4_t) -> i16 {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrdmulh, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -18321,7 +18321,7 @@ pub fn vqrdmulhh_laneq_s16(a: i16, b: int16x8_t) -> i16 {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhs_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrdmulh, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -18332,7 +18332,7 @@ pub fn vqrdmulhs_lane_s32(a: i32, b: int32x2_t) -> i32 {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhs_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrdmulh, LANE = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -18343,7 +18343,7 @@ pub fn vqrdmulhs_laneq_s32(a: i32, b: int32x4_t) -> i32 {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrdmulh))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18352,7 +18352,7 @@ pub fn vqrdmulhh_s16(a: i16, b: i16) -> i16 {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhs_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrdmulh))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18361,7 +18361,7 @@ pub fn vqrdmulhs_s32(a: i32, b: i32) -> i32 {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlb_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18372,7 +18372,7 @@ pub fn vqrshlb_s8(a: i8, b: i8) -> i8 {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18383,7 +18383,7 @@ pub fn vqrshlh_s16(a: i16, b: i16) -> i16 {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlb_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18394,7 +18394,7 @@ pub fn vqrshlb_u8(a: u8, b: i8) -> u8 {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlh_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18405,7 +18405,7 @@ pub fn vqrshlh_u16(a: u16, b: i16) -> u16 {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshld_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18421,7 +18421,7 @@ pub fn vqrshld_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshls_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18437,7 +18437,7 @@ pub fn vqrshls_s32(a: i32, b: i32) -> i32 {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshls_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18453,7 +18453,7 @@ pub fn vqrshls_u32(a: u32, b: i32) -> u32 {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshld_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18469,7 +18469,7 @@ pub fn vqrshld_u64(a: u64, b: i64) -> u64 {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18486,7 +18486,7 @@ pub fn vqrshrn_high_n_s16(a: int8x8_t, b: int16x8_t) -> int8x16_t
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18497,7 +18497,7 @@ pub fn vqrshrn_high_n_s32(a: int16x4_t, b: int32x4_t) -> int16x8_t
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18508,7 +18508,7 @@ pub fn vqrshrn_high_n_s64(a: int32x2_t, b: int64x2_t) -> int32x4_t
     }
     #[doc = "Unsigned saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18525,7 +18525,7 @@ pub fn vqrshrn_high_n_u16(a: uint8x8_t, b: uint16x8_t) -> uint8x16
     }
     #[doc = "Unsigned saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18536,7 +18536,7 @@ pub fn vqrshrn_high_n_u32(a: uint16x4_t, b: uint32x4_t) -> uint16x
     }
     #[doc = "Unsigned saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_high_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18547,7 +18547,7 @@ pub fn vqrshrn_high_n_u64(a: uint32x2_t, b: uint64x2_t) -> uint32x
     }
     #[doc = "Unsigned saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrnd_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18559,7 +18559,7 @@ pub fn vqrshrnd_n_u64(a: u64) -> u32 {
     }
     #[doc = "Unsigned saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrnh_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18571,7 +18571,7 @@ pub fn vqrshrnh_n_u16(a: u16) -> u8 {
     }
     #[doc = "Unsigned saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrns_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqrshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18583,7 +18583,7 @@ pub fn vqrshrns_n_u32(a: u32) -> u16 {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrnh_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18595,7 +18595,7 @@ pub fn vqrshrnh_n_s16(a: i16) -> i8 {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrns_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18607,7 +18607,7 @@ pub fn vqrshrns_n_s32(a: i32) -> i16 {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrnd_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18619,7 +18619,7 @@ pub fn vqrshrnd_n_s64(a: i64) -> i32 {
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrun2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18636,7 +18636,7 @@ pub fn vqrshrun_high_n_s16(a: uint8x8_t, b: int16x8_t) -> uint8x16
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrun2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18647,7 +18647,7 @@ pub fn vqrshrun_high_n_s32(a: uint16x4_t, b: int32x4_t) -> uint16x
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_high_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrun2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18658,7 +18658,7 @@ pub fn vqrshrun_high_n_s64(a: uint32x2_t, b: int64x2_t) -> uint32x
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrund_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrun, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18670,7 +18670,7 @@ pub fn vqrshrund_n_s64(a: i64) -> u32 {
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrunh_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrun, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18682,7 +18682,7 @@ pub fn vqrshrunh_n_s16(a: i16) -> u8 {
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshruns_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqrshrun, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18694,7 +18694,7 @@ pub fn vqrshruns_n_s32(a: i32) -> u16 {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlb_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshl, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18705,7 +18705,7 @@ pub fn vqshlb_n_s8(a: i8) -> i8 {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshld_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshl, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18716,7 +18716,7 @@ pub fn vqshld_n_s64(a: i64) -> i64 {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlh_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshl, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18727,7 +18727,7 @@ pub fn vqshlh_n_s16(a: i16) -> i16 {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshls_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshl, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18738,7 +18738,7 @@ pub fn vqshls_n_s32(a: i32) -> i32 {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlb_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshl, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18749,7 +18749,7 @@ pub fn vqshlb_n_u8(a: u8) -> u8 {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshld_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshl, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18760,7 +18760,7 @@ pub fn vqshld_n_u64(a: u64) -> u64 {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlh_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshl, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18771,7 +18771,7 @@ pub fn vqshlh_n_u16(a: u16) -> u16 {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshls_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshl, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18782,7 +18782,7 @@ pub fn vqshls_n_u32(a: u32) -> u32 {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlb_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18792,7 +18792,7 @@ pub fn vqshlb_s8(a: i8, b: i8) -> i8 {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18802,7 +18802,7 @@ pub fn vqshlh_s16(a: i16, b: i16) -> i16 {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshls_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18812,7 +18812,7 @@ pub fn vqshls_s32(a: i32, b: i32) -> i32 {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlb_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18822,7 +18822,7 @@ pub fn vqshlb_u8(a: u8, b: i8) -> u8 {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlh_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18832,7 +18832,7 @@ pub fn vqshlh_u16(a: u16, b: i16) -> u16 {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshls_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18842,7 +18842,7 @@ pub fn vqshls_u32(a: u32, b: i32) -> u32 {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshld_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18858,7 +18858,7 @@ pub fn vqshld_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshld_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -18874,7 +18874,7 @@ pub fn vqshld_u64(a: u64, b: i64) -> u64 {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlub_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18885,7 +18885,7 @@ pub fn vqshlub_n_s8(a: i8) -> u8 {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlud_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18896,7 +18896,7 @@ pub fn vqshlud_n_s64(a: i64) -> u64 {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluh_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18907,7 +18907,7 @@ pub fn vqshluh_n_s16(a: i16) -> u16 {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlus_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -18918,7 +18918,7 @@ pub fn vqshlus_n_s32(a: i32) -> u32 {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18935,7 +18935,7 @@ pub fn vqshrn_high_n_s16(a: int8x8_t, b: int16x8_t) -> int8x16_t {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18946,7 +18946,7 @@ pub fn vqshrn_high_n_s32(a: int16x4_t, b: int32x4_t) -> int16x8_t
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18957,7 +18957,7 @@ pub fn vqshrn_high_n_s64(a: int32x2_t, b: int64x2_t) -> int32x4_t
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18974,7 +18974,7 @@ pub fn vqshrn_high_n_u16(a: uint8x8_t, b: uint16x8_t) -> uint8x16_
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18985,7 +18985,7 @@ pub fn vqshrn_high_n_u32(a: uint16x4_t, b: uint32x4_t) -> uint16x8
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_high_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -18996,7 +18996,7 @@ pub fn vqshrn_high_n_u64(a: uint32x2_t, b: uint64x2_t) -> uint32x4
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrnd_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -19014,7 +19014,7 @@ pub fn vqshrnd_n_s64(a: i64) -> i32 {
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrnd_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -19032,7 +19032,7 @@ pub fn vqshrnd_n_u64(a: u64) -> u32 {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrnh_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -19043,7 +19043,7 @@ pub fn vqshrnh_n_s16(a: i16) -> i8 {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrns_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -19054,7 +19054,7 @@ pub fn vqshrns_n_s32(a: i32) -> i16 {
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrnh_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -19065,7 +19065,7 @@ pub fn vqshrnh_n_u16(a: u16) -> u8 {
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrns_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(uqshrn, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -19076,7 +19076,7 @@ pub fn vqshrns_n_u32(a: u32) -> u16 {
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrun2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -19093,7 +19093,7 @@ pub fn vqshrun_high_n_s16(a: uint8x8_t, b: int16x8_t) -> uint8x16_
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrun2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -19104,7 +19104,7 @@ pub fn vqshrun_high_n_s32(a: uint16x4_t, b: int32x4_t) -> uint16x8
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_high_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrun2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -19115,7 +19115,7 @@ pub fn vqshrun_high_n_s64(a: uint32x2_t, b: int64x2_t) -> uint32x4
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrund_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrun, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -19126,7 +19126,7 @@ pub fn vqshrund_n_s64(a: i64) -> u32 {
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrunh_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrun, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -19137,7 +19137,7 @@ pub fn vqshrunh_n_s16(a: i16) -> u8 {
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshruns_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sqshrun, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -19148,7 +19148,7 @@ pub fn vqshruns_n_s32(a: i32) -> u16 {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubb_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqsub))]
    @@ -19159,7 +19159,7 @@ pub fn vqsubb_s8(a: i8, b: i8) -> i8 {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqsub))]
    @@ -19170,7 +19170,7 @@ pub fn vqsubh_s16(a: i16, b: i16) -> i16 {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubb_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uqsub))]
    @@ -19181,7 +19181,7 @@ pub fn vqsubb_u8(a: u8, b: u8) -> u8 {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubh_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uqsub))]
    @@ -19192,7 +19192,7 @@ pub fn vqsubh_u16(a: u16, b: u16) -> u16 {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubs_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqsub))]
    @@ -19208,7 +19208,7 @@ pub fn vqsubs_s32(a: i32, b: i32) -> i32 {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sqsub))]
    @@ -19224,7 +19224,7 @@ pub fn vqsubd_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubs_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uqsub))]
    @@ -19240,7 +19240,7 @@ pub fn vqsubs_u32(a: u32, b: u32) -> u32 {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(uqsub))]
    @@ -19256,7 +19256,7 @@ pub fn vqsubd_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19272,7 +19272,7 @@ fn vqtbl1(a: int8x16_t, b: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1q)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19288,7 +19288,7 @@ fn vqtbl1q(a: int8x16_t, b: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19297,7 +19297,7 @@ pub fn vqtbl1_s8(a: int8x16_t, b: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19306,7 +19306,7 @@ pub fn vqtbl1q_s8(a: int8x16_t, b: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19315,7 +19315,7 @@ pub fn vqtbl1_u8(a: uint8x16_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19324,7 +19324,7 @@ pub fn vqtbl1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19333,7 +19333,7 @@ pub fn vqtbl1_p8(a: poly8x16_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19342,7 +19342,7 @@ pub fn vqtbl1q_p8(a: poly8x16_t, b: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19358,7 +19358,7 @@ fn vqtbl2(a: int8x16_t, b: int8x16_t, c: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2q)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19374,7 +19374,7 @@ fn vqtbl2q(a: int8x16_t, b: int8x16_t, c: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19383,7 +19383,7 @@ pub fn vqtbl2_s8(a: int8x16x2_t, b: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19392,7 +19392,7 @@ pub fn vqtbl2q_s8(a: int8x16x2_t, b: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19402,7 +19402,7 @@ pub fn vqtbl2_u8(a: uint8x16x2_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19431,7 +19431,7 @@ pub fn vqtbl2_u8(a: uint8x16x2_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19441,7 +19441,7 @@ pub fn vqtbl2q_u8(a: uint8x16x2_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19475,7 +19475,7 @@ pub fn vqtbl2q_u8(a: uint8x16x2_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19485,7 +19485,7 @@ pub fn vqtbl2_p8(a: poly8x16x2_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19514,7 +19514,7 @@ pub fn vqtbl2_p8(a: poly8x16x2_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19524,7 +19524,7 @@ pub fn vqtbl2q_p8(a: poly8x16x2_t, b: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19558,7 +19558,7 @@ pub fn vqtbl2q_p8(a: poly8x16x2_t, b: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19574,7 +19574,7 @@ fn vqtbl3(a: int8x16_t, b: int8x16_t, c: int8x16_t, d: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3q)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19590,7 +19590,7 @@ fn vqtbl3q(a: int8x16_t, b: int8x16_t, c: int8x16_t, d: uint8x16_t) -> int8x16_t
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19599,7 +19599,7 @@ pub fn vqtbl3_s8(a: int8x16x3_t, b: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19608,7 +19608,7 @@ pub fn vqtbl3q_s8(a: int8x16x3_t, b: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19618,7 +19618,7 @@ pub fn vqtbl3_u8(a: uint8x16x3_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19655,7 +19655,7 @@ pub fn vqtbl3_u8(a: uint8x16x3_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19665,7 +19665,7 @@ pub fn vqtbl3q_u8(a: uint8x16x3_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19707,7 +19707,7 @@ pub fn vqtbl3q_u8(a: uint8x16x3_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19717,7 +19717,7 @@ pub fn vqtbl3_p8(a: poly8x16x3_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19754,7 +19754,7 @@ pub fn vqtbl3_p8(a: poly8x16x3_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19764,7 +19764,7 @@ pub fn vqtbl3q_p8(a: poly8x16x3_t, b: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl3q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19806,7 +19806,7 @@ pub fn vqtbl3q_p8(a: poly8x16x3_t, b: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19828,7 +19828,7 @@ fn vqtbl4(a: int8x16_t, b: int8x16_t, c: int8x16_t, d: int8x16_t, e: uint8x8_t)
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4q)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19850,7 +19850,7 @@ fn vqtbl4q(a: int8x16_t, b: int8x16_t, c: int8x16_t, d: int8x16_t, e: uint8x16_t
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19859,7 +19859,7 @@ pub fn vqtbl4_s8(a: int8x16x4_t, b: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -19868,7 +19868,7 @@ pub fn vqtbl4q_s8(a: int8x16x4_t, b: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19886,7 +19886,7 @@ pub fn vqtbl4_u8(a: uint8x16x4_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19935,7 +19935,7 @@ pub fn vqtbl4_u8(a: uint8x16x4_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -19953,7 +19953,7 @@ pub fn vqtbl4q_u8(a: uint8x16x4_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -20007,7 +20007,7 @@ pub fn vqtbl4q_u8(a: uint8x16x4_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -20025,7 +20025,7 @@ pub fn vqtbl4_p8(a: poly8x16x4_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -20074,7 +20074,7 @@ pub fn vqtbl4_p8(a: poly8x16x4_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -20092,7 +20092,7 @@ pub fn vqtbl4q_p8(a: poly8x16x4_t, b: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl4q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -20146,7 +20146,7 @@ pub fn vqtbl4q_p8(a: poly8x16x4_t, b: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20162,7 +20162,7 @@ fn vqtbx1(a: int8x8_t, b: int8x16_t, c: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1q)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20178,7 +20178,7 @@ fn vqtbx1q(a: int8x16_t, b: int8x16_t, c: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20187,7 +20187,7 @@ pub fn vqtbx1_s8(a: int8x8_t, b: int8x16_t, c: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20196,7 +20196,7 @@ pub fn vqtbx1q_s8(a: int8x16_t, b: int8x16_t, c: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20205,7 +20205,7 @@ pub fn vqtbx1_u8(a: uint8x8_t, b: uint8x16_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20214,7 +20214,7 @@ pub fn vqtbx1q_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20223,7 +20223,7 @@ pub fn vqtbx1_p8(a: poly8x8_t, b: poly8x16_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20232,7 +20232,7 @@ pub fn vqtbx1q_p8(a: poly8x16_t, b: poly8x16_t, c: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20248,7 +20248,7 @@ fn vqtbx2(a: int8x8_t, b: int8x16_t, c: int8x16_t, d: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2q)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20264,7 +20264,7 @@ fn vqtbx2q(a: int8x16_t, b: int8x16_t, c: int8x16_t, d: uint8x16_t) -> int8x16_t
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20273,7 +20273,7 @@ pub fn vqtbx2_s8(a: int8x8_t, b: int8x16x2_t, c: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20282,7 +20282,7 @@ pub fn vqtbx2q_s8(a: int8x16_t, b: int8x16x2_t, c: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20292,7 +20292,7 @@ pub fn vqtbx2_u8(a: uint8x8_t, b: uint8x16x2_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20322,7 +20322,7 @@ pub fn vqtbx2_u8(a: uint8x8_t, b: uint8x16x2_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20332,7 +20332,7 @@ pub fn vqtbx2q_u8(a: uint8x16_t, b: uint8x16x2_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20369,7 +20369,7 @@ pub fn vqtbx2q_u8(a: uint8x16_t, b: uint8x16x2_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20379,7 +20379,7 @@ pub fn vqtbx2_p8(a: poly8x8_t, b: poly8x16x2_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20409,7 +20409,7 @@ pub fn vqtbx2_p8(a: poly8x8_t, b: poly8x16x2_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20419,7 +20419,7 @@ pub fn vqtbx2q_p8(a: poly8x16_t, b: poly8x16x2_t, c: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20456,7 +20456,7 @@ pub fn vqtbx2q_p8(a: poly8x16_t, b: poly8x16x2_t, c: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20473,7 +20473,7 @@ fn vqtbx3(a: int8x8_t, b: int8x16_t, c: int8x16_t, d: int8x16_t, e: uint8x8_t) -
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3q)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20495,7 +20495,7 @@ fn vqtbx3q(a: int8x16_t, b: int8x16_t, c: int8x16_t, d: int8x16_t, e: uint8x16_t
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20504,7 +20504,7 @@ pub fn vqtbx3_s8(a: int8x8_t, b: int8x16x3_t, c: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20513,7 +20513,7 @@ pub fn vqtbx3q_s8(a: int8x16_t, b: int8x16x3_t, c: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20531,7 +20531,7 @@ pub fn vqtbx3_u8(a: uint8x8_t, b: uint8x16x3_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20574,7 +20574,7 @@ pub fn vqtbx3_u8(a: uint8x8_t, b: uint8x16x3_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20592,7 +20592,7 @@ pub fn vqtbx3q_u8(a: uint8x16_t, b: uint8x16x3_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20641,7 +20641,7 @@ pub fn vqtbx3q_u8(a: uint8x16_t, b: uint8x16x3_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20659,7 +20659,7 @@ pub fn vqtbx3_p8(a: poly8x8_t, b: poly8x16x3_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20702,7 +20702,7 @@ pub fn vqtbx3_p8(a: poly8x8_t, b: poly8x16x3_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20720,7 +20720,7 @@ pub fn vqtbx3q_p8(a: poly8x16_t, b: poly8x16x3_t, c: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx3q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20769,7 +20769,7 @@ pub fn vqtbx3q_p8(a: poly8x16_t, b: poly8x16x3_t, c: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20799,7 +20799,7 @@ fn vqtbx4(
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4q)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20829,7 +20829,7 @@ fn vqtbx4q(
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20838,7 +20838,7 @@ pub fn vqtbx4_s8(a: int8x8_t, b: int8x16x4_t, c: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20847,7 +20847,7 @@ pub fn vqtbx4q_s8(a: int8x16_t, b: int8x16x4_t, c: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20866,7 +20866,7 @@ pub fn vqtbx4_u8(a: uint8x8_t, b: uint8x16x4_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20917,7 +20917,7 @@ pub fn vqtbx4_u8(a: uint8x8_t, b: uint8x16x4_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20936,7 +20936,7 @@ pub fn vqtbx4q_u8(a: uint8x16_t, b: uint8x16x4_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -20993,7 +20993,7 @@ pub fn vqtbx4q_u8(a: uint8x16_t, b: uint8x16x4_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -21012,7 +21012,7 @@ pub fn vqtbx4_p8(a: poly8x8_t, b: poly8x16x4_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -21063,7 +21063,7 @@ pub fn vqtbx4_p8(a: poly8x8_t, b: poly8x16x4_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -21082,7 +21082,7 @@ pub fn vqtbx4q_p8(a: poly8x16_t, b: poly8x16x4_t, c: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx4q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -21139,7 +21139,7 @@ pub fn vqtbx4q_p8(a: poly8x16_t, b: poly8x16x4_t, c: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Rotate and exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrax1q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[cfg_attr(test, assert_instr(rax1))]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
    @@ -21155,7 +21155,7 @@ pub fn vrax1q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbit_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(rbit))]
    @@ -21164,7 +21164,7 @@ pub fn vrbit_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbitq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(rbit))]
    @@ -21173,7 +21173,7 @@ pub fn vrbitq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbit_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21183,7 +21183,7 @@ pub fn vrbit_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbit_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21197,7 +21197,7 @@ pub fn vrbit_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbitq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21207,7 +21207,7 @@ pub fn vrbitq_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbitq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21226,7 +21226,7 @@ pub fn vrbitq_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbit_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21236,7 +21236,7 @@ pub fn vrbit_p8(a: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbit_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21250,7 +21250,7 @@ pub fn vrbit_p8(a: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbitq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21260,7 +21260,7 @@ pub fn vrbitq_p8(a: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Reverse bit order"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbitq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21279,7 +21279,7 @@ pub fn vrbitq_p8(a: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Reciprocal estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpe_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecpe))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21295,7 +21295,7 @@ pub fn vrecpe_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Reciprocal estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpeq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecpe))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21311,7 +21311,7 @@ pub fn vrecpeq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Reciprocal estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecped_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecpe))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21327,7 +21327,7 @@ pub fn vrecped_f64(a: f64) -> f64 {
     }
     #[doc = "Reciprocal estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpes_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecpe))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21343,7 +21343,7 @@ pub fn vrecpes_f32(a: f32) -> f32 {
     }
     #[doc = "Reciprocal estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpeh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(frecpe))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -21360,7 +21360,7 @@ pub fn vrecpeh_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point reciprocal step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecps_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21376,7 +21376,7 @@ pub fn vrecps_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point reciprocal step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpsq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21392,7 +21392,7 @@ pub fn vrecpsq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point reciprocal step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpsd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21408,7 +21408,7 @@ pub fn vrecpsd_f64(a: f64, b: f64) -> f64 {
     }
     #[doc = "Floating-point reciprocal step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpss_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecps))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21424,7 +21424,7 @@ pub fn vrecpss_f32(a: f32, b: f32) -> f32 {
     }
     #[doc = "Floating-point reciprocal step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpsh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(frecps))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -21441,7 +21441,7 @@ pub fn vrecpsh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Floating-point reciprocal exponent"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpxd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecpx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21457,7 +21457,7 @@ pub fn vrecpxd_f64(a: f64) -> f64 {
     }
     #[doc = "Floating-point reciprocal exponent"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpxs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frecpx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21473,7 +21473,7 @@ pub fn vrecpxs_f32(a: f32) -> f32 {
     }
     #[doc = "Floating-point reciprocal exponent"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpxh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(frecpx))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -21490,7 +21490,7 @@ pub fn vrecpxh_f16(a: f16) -> f16 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -21501,7 +21501,7 @@ pub fn vreinterpret_f64_f16(a: float16x4_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -21513,7 +21513,7 @@ pub fn vreinterpret_f64_f16(a: float16x4_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -21524,7 +21524,7 @@ pub fn vreinterpretq_f64_f16(a: float16x8_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -21539,7 +21539,7 @@ pub fn vreinterpretq_f64_f16(a: float16x8_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -21550,7 +21550,7 @@ pub fn vreinterpret_f16_f64(a: float64x1_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -21564,7 +21564,7 @@ pub fn vreinterpret_f16_f64(a: float64x1_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -21575,7 +21575,7 @@ pub fn vreinterpretq_f16_f64(a: float64x2_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -21590,7 +21590,7 @@ pub fn vreinterpretq_f16_f64(a: float64x2_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21600,7 +21600,7 @@ pub fn vreinterpretq_f64_p128(a: p128) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21613,7 +21613,7 @@ pub fn vreinterpretq_f64_p128(a: p128) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21623,7 +21623,7 @@ pub fn vreinterpret_f64_f32(a: float32x2_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21634,7 +21634,7 @@ pub fn vreinterpret_f64_f32(a: float32x2_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21644,7 +21644,7 @@ pub fn vreinterpret_p64_f32(a: float32x2_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21655,7 +21655,7 @@ pub fn vreinterpret_p64_f32(a: float32x2_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21665,7 +21665,7 @@ pub fn vreinterpretq_f64_f32(a: float32x4_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21679,7 +21679,7 @@ pub fn vreinterpretq_f64_f32(a: float32x4_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21689,7 +21689,7 @@ pub fn vreinterpretq_p64_f32(a: float32x4_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21703,7 +21703,7 @@ pub fn vreinterpretq_p64_f32(a: float32x4_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21713,7 +21713,7 @@ pub fn vreinterpret_f32_f64(a: float64x1_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21726,7 +21726,7 @@ pub fn vreinterpret_f32_f64(a: float64x1_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21736,7 +21736,7 @@ pub fn vreinterpret_s8_f64(a: float64x1_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21749,7 +21749,7 @@ pub fn vreinterpret_s8_f64(a: float64x1_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21759,7 +21759,7 @@ pub fn vreinterpret_s16_f64(a: float64x1_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21772,7 +21772,7 @@ pub fn vreinterpret_s16_f64(a: float64x1_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21782,7 +21782,7 @@ pub fn vreinterpret_s32_f64(a: float64x1_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21795,7 +21795,7 @@ pub fn vreinterpret_s32_f64(a: float64x1_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -21804,7 +21804,7 @@ pub fn vreinterpret_s64_f64(a: float64x1_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21814,7 +21814,7 @@ pub fn vreinterpret_u8_f64(a: float64x1_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21827,7 +21827,7 @@ pub fn vreinterpret_u8_f64(a: float64x1_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21837,7 +21837,7 @@ pub fn vreinterpret_u16_f64(a: float64x1_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21850,7 +21850,7 @@ pub fn vreinterpret_u16_f64(a: float64x1_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21860,7 +21860,7 @@ pub fn vreinterpret_u32_f64(a: float64x1_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21873,7 +21873,7 @@ pub fn vreinterpret_u32_f64(a: float64x1_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -21882,7 +21882,7 @@ pub fn vreinterpret_u64_f64(a: float64x1_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21892,7 +21892,7 @@ pub fn vreinterpret_p8_f64(a: float64x1_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21905,7 +21905,7 @@ pub fn vreinterpret_p8_f64(a: float64x1_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21915,7 +21915,7 @@ pub fn vreinterpret_p16_f64(a: float64x1_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21928,7 +21928,7 @@ pub fn vreinterpret_p16_f64(a: float64x1_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -21937,7 +21937,7 @@ pub fn vreinterpret_p64_f64(a: float64x1_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21947,7 +21947,7 @@ pub fn vreinterpretq_p128_f64(a: float64x2_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21958,7 +21958,7 @@ pub fn vreinterpretq_p128_f64(a: float64x2_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21968,7 +21968,7 @@ pub fn vreinterpretq_f32_f64(a: float64x2_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21982,7 +21982,7 @@ pub fn vreinterpretq_f32_f64(a: float64x2_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21992,7 +21992,7 @@ pub fn vreinterpretq_s8_f64(a: float64x2_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22010,7 +22010,7 @@ pub fn vreinterpretq_s8_f64(a: float64x2_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22020,7 +22020,7 @@ pub fn vreinterpretq_s16_f64(a: float64x2_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22034,7 +22034,7 @@ pub fn vreinterpretq_s16_f64(a: float64x2_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22044,7 +22044,7 @@ pub fn vreinterpretq_s32_f64(a: float64x2_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22058,7 +22058,7 @@ pub fn vreinterpretq_s32_f64(a: float64x2_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22068,7 +22068,7 @@ pub fn vreinterpretq_s64_f64(a: float64x2_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22082,7 +22082,7 @@ pub fn vreinterpretq_s64_f64(a: float64x2_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22092,7 +22092,7 @@ pub fn vreinterpretq_u8_f64(a: float64x2_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22110,7 +22110,7 @@ pub fn vreinterpretq_u8_f64(a: float64x2_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22120,7 +22120,7 @@ pub fn vreinterpretq_u16_f64(a: float64x2_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22134,7 +22134,7 @@ pub fn vreinterpretq_u16_f64(a: float64x2_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22144,7 +22144,7 @@ pub fn vreinterpretq_u32_f64(a: float64x2_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22158,7 +22158,7 @@ pub fn vreinterpretq_u32_f64(a: float64x2_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22168,7 +22168,7 @@ pub fn vreinterpretq_u64_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22182,7 +22182,7 @@ pub fn vreinterpretq_u64_f64(a: float64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22192,7 +22192,7 @@ pub fn vreinterpretq_p8_f64(a: float64x2_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22210,7 +22210,7 @@ pub fn vreinterpretq_p8_f64(a: float64x2_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22220,7 +22220,7 @@ pub fn vreinterpretq_p16_f64(a: float64x2_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22234,7 +22234,7 @@ pub fn vreinterpretq_p16_f64(a: float64x2_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22244,7 +22244,7 @@ pub fn vreinterpretq_p64_f64(a: float64x2_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_f64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22258,7 +22258,7 @@ pub fn vreinterpretq_p64_f64(a: float64x2_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22268,7 +22268,7 @@ pub fn vreinterpret_f64_s8(a: int8x8_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22279,7 +22279,7 @@ pub fn vreinterpret_f64_s8(a: int8x8_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22289,7 +22289,7 @@ pub fn vreinterpretq_f64_s8(a: int8x16_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22304,7 +22304,7 @@ pub fn vreinterpretq_f64_s8(a: int8x16_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22314,7 +22314,7 @@ pub fn vreinterpret_f64_s16(a: int16x4_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22325,7 +22325,7 @@ pub fn vreinterpret_f64_s16(a: int16x4_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22335,7 +22335,7 @@ pub fn vreinterpretq_f64_s16(a: int16x8_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22349,7 +22349,7 @@ pub fn vreinterpretq_f64_s16(a: int16x8_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22359,7 +22359,7 @@ pub fn vreinterpret_f64_s32(a: int32x2_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22370,7 +22370,7 @@ pub fn vreinterpret_f64_s32(a: int32x2_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22380,7 +22380,7 @@ pub fn vreinterpretq_f64_s32(a: int32x4_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22394,7 +22394,7 @@ pub fn vreinterpretq_f64_s32(a: int32x4_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -22403,7 +22403,7 @@ pub fn vreinterpret_f64_s64(a: int64x1_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -22412,7 +22412,7 @@ pub fn vreinterpret_p64_s64(a: int64x1_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22422,7 +22422,7 @@ pub fn vreinterpretq_f64_s64(a: int64x2_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22436,7 +22436,7 @@ pub fn vreinterpretq_f64_s64(a: int64x2_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22446,7 +22446,7 @@ pub fn vreinterpretq_p64_s64(a: int64x2_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22460,7 +22460,7 @@ pub fn vreinterpretq_p64_s64(a: int64x2_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22470,7 +22470,7 @@ pub fn vreinterpret_f64_u8(a: uint8x8_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22481,7 +22481,7 @@ pub fn vreinterpret_f64_u8(a: uint8x8_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22491,7 +22491,7 @@ pub fn vreinterpretq_f64_u8(a: uint8x16_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22506,7 +22506,7 @@ pub fn vreinterpretq_f64_u8(a: uint8x16_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22516,7 +22516,7 @@ pub fn vreinterpret_f64_u16(a: uint16x4_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22527,7 +22527,7 @@ pub fn vreinterpret_f64_u16(a: uint16x4_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22537,7 +22537,7 @@ pub fn vreinterpretq_f64_u16(a: uint16x8_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22551,7 +22551,7 @@ pub fn vreinterpretq_f64_u16(a: uint16x8_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22561,7 +22561,7 @@ pub fn vreinterpret_f64_u32(a: uint32x2_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22572,7 +22572,7 @@ pub fn vreinterpret_f64_u32(a: uint32x2_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22582,7 +22582,7 @@ pub fn vreinterpretq_f64_u32(a: uint32x4_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22596,7 +22596,7 @@ pub fn vreinterpretq_f64_u32(a: uint32x4_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -22605,7 +22605,7 @@ pub fn vreinterpret_f64_u64(a: uint64x1_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -22614,7 +22614,7 @@ pub fn vreinterpret_p64_u64(a: uint64x1_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22624,7 +22624,7 @@ pub fn vreinterpretq_f64_u64(a: uint64x2_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22638,7 +22638,7 @@ pub fn vreinterpretq_f64_u64(a: uint64x2_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22648,7 +22648,7 @@ pub fn vreinterpretq_p64_u64(a: uint64x2_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22662,7 +22662,7 @@ pub fn vreinterpretq_p64_u64(a: uint64x2_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22672,7 +22672,7 @@ pub fn vreinterpret_f64_p8(a: poly8x8_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22683,7 +22683,7 @@ pub fn vreinterpret_f64_p8(a: poly8x8_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22693,7 +22693,7 @@ pub fn vreinterpretq_f64_p8(a: poly8x16_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22708,7 +22708,7 @@ pub fn vreinterpretq_f64_p8(a: poly8x16_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22718,7 +22718,7 @@ pub fn vreinterpret_f64_p16(a: poly16x4_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22729,7 +22729,7 @@ pub fn vreinterpret_f64_p16(a: poly16x4_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22739,7 +22739,7 @@ pub fn vreinterpretq_f64_p16(a: poly16x8_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22753,7 +22753,7 @@ pub fn vreinterpretq_f64_p16(a: poly16x8_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22763,7 +22763,7 @@ pub fn vreinterpret_f32_p64(a: poly64x1_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22776,7 +22776,7 @@ pub fn vreinterpret_f32_p64(a: poly64x1_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -22785,7 +22785,7 @@ pub fn vreinterpret_f64_p64(a: poly64x1_t) -> float64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -22794,7 +22794,7 @@ pub fn vreinterpret_s64_p64(a: poly64x1_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -22803,7 +22803,7 @@ pub fn vreinterpret_u64_p64(a: poly64x1_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22813,7 +22813,7 @@ pub fn vreinterpretq_f32_p64(a: poly64x2_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22827,7 +22827,7 @@ pub fn vreinterpretq_f32_p64(a: poly64x2_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22837,7 +22837,7 @@ pub fn vreinterpretq_f64_p64(a: poly64x2_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22851,7 +22851,7 @@ pub fn vreinterpretq_f64_p64(a: poly64x2_t) -> float64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22861,7 +22861,7 @@ pub fn vreinterpretq_s64_p64(a: poly64x2_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22875,7 +22875,7 @@ pub fn vreinterpretq_s64_p64(a: poly64x2_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22885,7 +22885,7 @@ pub fn vreinterpretq_u64_p64(a: poly64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22899,7 +22899,7 @@ pub fn vreinterpretq_u64_p64(a: poly64x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point round to 32-bit integer, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32x_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint32x))]
    @@ -22915,7 +22915,7 @@ pub fn vrnd32x_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to 32-bit integer, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32xq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint32x))]
    @@ -22931,7 +22931,7 @@ pub fn vrnd32xq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to 32-bit integer, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32xq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint32x))]
    @@ -22947,7 +22947,7 @@ pub fn vrnd32xq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to 32-bit integer, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32x_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint32x))]
    @@ -22963,7 +22963,7 @@ pub fn vrnd32x_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to 32-bit integer toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32z_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint32z))]
    @@ -22979,7 +22979,7 @@ pub fn vrnd32z_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to 32-bit integer toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32zq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint32z))]
    @@ -22995,7 +22995,7 @@ pub fn vrnd32zq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to 32-bit integer toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32zq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint32z))]
    @@ -23011,7 +23011,7 @@ pub fn vrnd32zq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to 32-bit integer toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd32z_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint32z))]
    @@ -23027,7 +23027,7 @@ pub fn vrnd32z_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to 64-bit integer, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64x_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint64x))]
    @@ -23043,7 +23043,7 @@ pub fn vrnd64x_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to 64-bit integer, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64xq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint64x))]
    @@ -23059,7 +23059,7 @@ pub fn vrnd64xq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to 64-bit integer, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64xq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint64x))]
    @@ -23075,7 +23075,7 @@ pub fn vrnd64xq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to 64-bit integer, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64x_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint64x))]
    @@ -23091,7 +23091,7 @@ pub fn vrnd64x_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to 64-bit integer toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64z_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint64z))]
    @@ -23107,7 +23107,7 @@ pub fn vrnd64z_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to 64-bit integer toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64zq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint64z))]
    @@ -23123,7 +23123,7 @@ pub fn vrnd64zq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to 64-bit integer toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64zq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint64z))]
    @@ -23139,7 +23139,7 @@ pub fn vrnd64zq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to 64-bit integer toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd64z_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,frintts")]
     #[unstable(feature = "stdarch_neon_ftts", issue = "117227")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(frint64z))]
    @@ -23155,7 +23155,7 @@ pub fn vrnd64z_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to integral, toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23165,7 +23165,7 @@ pub fn vrnd_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point round to integral, toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23175,7 +23175,7 @@ pub fn vrndq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point round to integral, toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintz))]
    @@ -23184,7 +23184,7 @@ pub fn vrnd_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to integral, toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintz))]
    @@ -23193,7 +23193,7 @@ pub fn vrndq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to integral, toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintz))]
    @@ -23202,7 +23202,7 @@ pub fn vrnd_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to integral, toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintz))]
    @@ -23211,7 +23211,7 @@ pub fn vrndq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnda_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23221,7 +23221,7 @@ pub fn vrnda_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndaq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23231,7 +23231,7 @@ pub fn vrndaq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnda_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frinta))]
    @@ -23240,7 +23240,7 @@ pub fn vrnda_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndaq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frinta))]
    @@ -23249,7 +23249,7 @@ pub fn vrndaq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrnda_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frinta))]
    @@ -23258,7 +23258,7 @@ pub fn vrnda_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndaq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frinta))]
    @@ -23267,7 +23267,7 @@ pub fn vrndaq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndah_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23277,7 +23277,7 @@ pub fn vrndah_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to away"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23287,7 +23287,7 @@ pub fn vrndh_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point round to integral, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndi_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23304,7 +23304,7 @@ pub fn vrndi_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point round to integral, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndiq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23321,7 +23321,7 @@ pub fn vrndiq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point round to integral, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndi_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frinti))]
    @@ -23337,7 +23337,7 @@ pub fn vrndi_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to integral, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndiq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frinti))]
    @@ -23353,7 +23353,7 @@ pub fn vrndiq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to integral, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndi_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frinti))]
    @@ -23369,7 +23369,7 @@ pub fn vrndi_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to integral, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndiq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frinti))]
    @@ -23385,7 +23385,7 @@ pub fn vrndiq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to integral, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndih_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23402,7 +23402,7 @@ pub fn vrndih_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point round to integral, toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndm_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23412,7 +23412,7 @@ pub fn vrndm_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point round to integral, toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndmq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23422,7 +23422,7 @@ pub fn vrndmq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point round to integral, toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndm_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintm))]
    @@ -23431,7 +23431,7 @@ pub fn vrndm_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to integral, toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndmq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintm))]
    @@ -23440,7 +23440,7 @@ pub fn vrndmq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to integral, toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndm_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintm))]
    @@ -23449,7 +23449,7 @@ pub fn vrndm_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to integral, toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndmq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintm))]
    @@ -23458,7 +23458,7 @@ pub fn vrndmq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to integral, toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndmh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23468,7 +23468,7 @@ pub fn vrndmh_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndn_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintn))]
    @@ -23484,7 +23484,7 @@ pub fn vrndn_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndnq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintn))]
    @@ -23500,7 +23500,7 @@ pub fn vrndnq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to integral, toward minus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndnh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23517,7 +23517,7 @@ pub fn vrndnh_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndns_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintn))]
    @@ -23533,7 +23533,7 @@ pub fn vrndns_f32(a: f32) -> f32 {
     }
     #[doc = "Floating-point round to integral, toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndp_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23543,7 +23543,7 @@ pub fn vrndp_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point round to integral, toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndpq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23553,7 +23553,7 @@ pub fn vrndpq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point round to integral, toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndp_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintp))]
    @@ -23562,7 +23562,7 @@ pub fn vrndp_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to integral, toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndpq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintp))]
    @@ -23571,7 +23571,7 @@ pub fn vrndpq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to integral, toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndp_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintp))]
    @@ -23580,7 +23580,7 @@ pub fn vrndp_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to integral, toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndpq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintp))]
    @@ -23589,7 +23589,7 @@ pub fn vrndpq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to integral, toward plus infinity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndph_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23599,7 +23599,7 @@ pub fn vrndph_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point round to integral exact, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23609,7 +23609,7 @@ pub fn vrndx_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point round to integral exact, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23619,7 +23619,7 @@ pub fn vrndxq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point round to integral exact, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintx))]
    @@ -23628,7 +23628,7 @@ pub fn vrndx_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to integral exact, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintx))]
    @@ -23637,7 +23637,7 @@ pub fn vrndxq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point round to integral exact, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintx))]
    @@ -23646,7 +23646,7 @@ pub fn vrndx_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point round to integral exact, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(frintx))]
    @@ -23655,7 +23655,7 @@ pub fn vrndxq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to integral, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -23665,7 +23665,7 @@ pub fn vrndxh_f16(a: f16) -> f16 {
     }
     #[doc = "Signed rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshld_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(srshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23681,7 +23681,7 @@ pub fn vrshld_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Unsigned rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshld_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(urshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23697,7 +23697,7 @@ pub fn vrshld_u64(a: u64, b: i64) -> u64 {
     }
     #[doc = "Signed rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrd_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(srshr, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -23708,7 +23708,7 @@ pub fn vrshrd_n_s64(a: i64) -> i64 {
     }
     #[doc = "Unsigned rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrd_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(urshr, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -23719,7 +23719,7 @@ pub fn vrshrd_n_u64(a: u64) -> u64 {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(rshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -23736,7 +23736,7 @@ pub fn vrshrn_high_n_s16(a: int8x8_t, b: int16x8_t) -> int8x16_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(rshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -23747,7 +23747,7 @@ pub fn vrshrn_high_n_s32(a: int16x4_t, b: int32x4_t) -> int16x8_t
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(rshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -23758,7 +23758,7 @@ pub fn vrshrn_high_n_s64(a: int32x2_t, b: int64x2_t) -> int32x4_t
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(rshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -23775,7 +23775,7 @@ pub fn vrshrn_high_n_u16(a: uint8x8_t, b: uint16x8_t) -> uint8x16_
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(rshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -23786,7 +23786,7 @@ pub fn vrshrn_high_n_u32(a: uint16x4_t, b: uint32x4_t) -> uint16x8
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_high_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(rshrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -23797,7 +23797,7 @@ pub fn vrshrn_high_n_u64(a: uint32x2_t, b: uint64x2_t) -> uint32x4
     }
     #[doc = "Reciprocal square-root estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrte_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frsqrte))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23813,7 +23813,7 @@ pub fn vrsqrte_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Reciprocal square-root estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frsqrte))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23829,7 +23829,7 @@ pub fn vrsqrteq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Reciprocal square-root estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrted_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frsqrte))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23845,7 +23845,7 @@ pub fn vrsqrted_f64(a: f64) -> f64 {
     }
     #[doc = "Reciprocal square-root estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtes_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frsqrte))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23861,7 +23861,7 @@ pub fn vrsqrtes_f32(a: f32) -> f32 {
     }
     #[doc = "Reciprocal square-root estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(frsqrte))]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -23878,7 +23878,7 @@ pub fn vrsqrteh_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point reciprocal square root step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrts_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frsqrts))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23894,7 +23894,7 @@ pub fn vrsqrts_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Floating-point reciprocal square root step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtsq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frsqrts))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23910,7 +23910,7 @@ pub fn vrsqrtsq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point reciprocal square root step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtsd_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frsqrts))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23926,7 +23926,7 @@ pub fn vrsqrtsd_f64(a: f64, b: f64) -> f64 {
     }
     #[doc = "Floating-point reciprocal square root step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtss_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(frsqrts))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -23942,7 +23942,7 @@ pub fn vrsqrtss_f32(a: f32, b: f32) -> f32 {
     }
     #[doc = "Floating-point reciprocal square root step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtsh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(test, assert_instr(frsqrts))]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
    @@ -23959,7 +23959,7 @@ pub fn vrsqrtsh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Signed rounding shift right and accumulate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsrad_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(srshr, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -23971,7 +23971,7 @@ pub fn vrsrad_n_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Unsigned rounding shift right and accumulate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsrad_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(urshr, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -23983,7 +23983,7 @@ pub fn vrsrad_n_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "little")]
     #[cfg_attr(test, assert_instr(rsubhn2))]
    @@ -23994,7 +23994,7 @@ pub fn vrsubhn_high_s16(a: int8x8_t, b: int16x8_t, c: int16x8_t) -> int8x16_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "little")]
     #[cfg_attr(test, assert_instr(rsubhn2))]
    @@ -24005,7 +24005,7 @@ pub fn vrsubhn_high_s32(a: int16x4_t, b: int32x4_t, c: int32x4_t) -> int16x8_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "little")]
     #[cfg_attr(test, assert_instr(rsubhn2))]
    @@ -24016,7 +24016,7 @@ pub fn vrsubhn_high_s64(a: int32x2_t, b: int64x2_t, c: int64x2_t) -> int32x4_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "little")]
     #[cfg_attr(test, assert_instr(rsubhn2))]
    @@ -24027,7 +24027,7 @@ pub fn vrsubhn_high_u16(a: uint8x8_t, b: uint16x8_t, c: uint16x8_t) -> uint8x16_
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "little")]
     #[cfg_attr(test, assert_instr(rsubhn2))]
    @@ -24038,7 +24038,7 @@ pub fn vrsubhn_high_u32(a: uint16x4_t, b: uint32x4_t, c: uint32x4_t) -> uint16x8
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "little")]
     #[cfg_attr(test, assert_instr(rsubhn2))]
    @@ -24049,7 +24049,7 @@ pub fn vrsubhn_high_u64(a: uint32x2_t, b: uint64x2_t, c: uint64x2_t) -> uint32x4
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "big")]
     #[cfg_attr(test, assert_instr(rsubhn))]
    @@ -24060,7 +24060,7 @@ pub fn vrsubhn_high_s16(a: int8x8_t, b: int16x8_t, c: int16x8_t) -> int8x16_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "big")]
     #[cfg_attr(test, assert_instr(rsubhn))]
    @@ -24071,7 +24071,7 @@ pub fn vrsubhn_high_s32(a: int16x4_t, b: int32x4_t, c: int32x4_t) -> int16x8_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "big")]
     #[cfg_attr(test, assert_instr(rsubhn))]
    @@ -24082,7 +24082,7 @@ pub fn vrsubhn_high_s64(a: int32x2_t, b: int64x2_t, c: int64x2_t) -> int32x4_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "big")]
     #[cfg_attr(test, assert_instr(rsubhn))]
    @@ -24093,7 +24093,7 @@ pub fn vrsubhn_high_u16(a: uint8x8_t, b: uint16x8_t, c: uint16x8_t) -> uint8x16_
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "big")]
     #[cfg_attr(test, assert_instr(rsubhn))]
    @@ -24104,7 +24104,7 @@ pub fn vrsubhn_high_u32(a: uint16x4_t, b: uint32x4_t, c: uint32x4_t) -> uint16x8
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_high_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_endian = "big")]
     #[cfg_attr(test, assert_instr(rsubhn))]
    @@ -24115,7 +24115,7 @@ pub fn vrsubhn_high_u64(a: uint32x2_t, b: uint64x2_t, c: uint64x2_t) -> uint32x4
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -24126,7 +24126,7 @@ pub fn vset_lane_f64(a: f64, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -24137,7 +24137,7 @@ pub fn vsetq_lane_f64(a: f64, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "SHA512 hash update part 2"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha512h2q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[cfg_attr(test, assert_instr(sha512h2))]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
    @@ -24153,7 +24153,7 @@ pub fn vsha512h2q_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x2_t
     }
     #[doc = "SHA512 hash update part 1"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha512hq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[cfg_attr(test, assert_instr(sha512h))]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
    @@ -24169,7 +24169,7 @@ pub fn vsha512hq_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x2_t
     }
     #[doc = "SHA512 schedule update 0"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha512su0q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[cfg_attr(test, assert_instr(sha512su0))]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
    @@ -24185,7 +24185,7 @@ pub fn vsha512su0q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "SHA512 schedule update 1"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha512su1q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[cfg_attr(test, assert_instr(sha512su1))]
     #[stable(feature = "stdarch_neon_sha3", since = "1.79.0")]
    @@ -24201,7 +24201,7 @@ pub fn vsha512su1q_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x2_
     }
     #[doc = "Signed Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshld_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sshl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -24210,7 +24210,7 @@ pub fn vshld_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Unsigned Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshld_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ushl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -24219,7 +24219,7 @@ pub fn vshld_u64(a: u64, b: i64) -> u64 {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sshll2, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -24233,7 +24233,7 @@ pub fn vshll_high_n_s8(a: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sshll2, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -24247,7 +24247,7 @@ pub fn vshll_high_n_s16(a: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sshll2, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -24261,7 +24261,7 @@ pub fn vshll_high_n_s32(a: int32x4_t) -> int64x2_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ushll2, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -24275,7 +24275,7 @@ pub fn vshll_high_n_u8(a: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ushll2, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -24289,7 +24289,7 @@ pub fn vshll_high_n_u16(a: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_high_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(ushll2, N = 2))]
     #[rustc_legacy_const_generics(1)]
    @@ -24303,7 +24303,7 @@ pub fn vshll_high_n_u32(a: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(shrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -24320,7 +24320,7 @@ pub fn vshrn_high_n_s16(a: int8x8_t, b: int16x8_t) -> int8x16_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(shrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -24331,7 +24331,7 @@ pub fn vshrn_high_n_s32(a: int16x4_t, b: int32x4_t) -> int16x8_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(shrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -24342,7 +24342,7 @@ pub fn vshrn_high_n_s64(a: int32x2_t, b: int64x2_t) -> int32x4_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(shrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -24359,7 +24359,7 @@ pub fn vshrn_high_n_u16(a: uint8x8_t, b: uint16x8_t) -> uint8x16_t
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(shrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -24370,7 +24370,7 @@ pub fn vshrn_high_n_u32(a: uint16x4_t, b: uint32x4_t) -> uint16x8_
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_high_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(shrn2, N = 2))]
     #[rustc_legacy_const_generics(2)]
    @@ -24381,7 +24381,7 @@ pub fn vshrn_high_n_u64(a: uint32x2_t, b: uint64x2_t) -> uint32x4_
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24399,7 +24399,7 @@ pub fn vsli_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24417,7 +24417,7 @@ pub fn vsliq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24435,7 +24435,7 @@ pub fn vsli_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24453,7 +24453,7 @@ pub fn vsliq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24471,7 +24471,7 @@ pub fn vsli_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24489,7 +24489,7 @@ pub fn vsliq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24507,7 +24507,7 @@ pub fn vsli_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24525,7 +24525,7 @@ pub fn vsliq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24536,7 +24536,7 @@ pub fn vsli_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24547,7 +24547,7 @@ pub fn vsliq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24558,7 +24558,7 @@ pub fn vsli_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24569,7 +24569,7 @@ pub fn vsliq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24580,7 +24580,7 @@ pub fn vsli_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24591,7 +24591,7 @@ pub fn vsliq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24602,7 +24602,7 @@ pub fn vsli_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24613,7 +24613,7 @@ pub fn vsliq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24624,7 +24624,7 @@ pub fn vsli_n_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24635,7 +24635,7 @@ pub fn vsliq_n_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24646,7 +24646,7 @@ pub fn vsli_n_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24657,7 +24657,7 @@ pub fn vsliq_n_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24668,7 +24668,7 @@ pub fn vsli_n_p64(a: poly64x1_t, b: poly64x1_t) -> poly64x1_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(sli, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -24679,7 +24679,7 @@ pub fn vsliq_n_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Shift left and insert"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vslid_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[rustc_legacy_const_generics(2)]
    @@ -24690,7 +24690,7 @@ pub fn vslid_n_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Shift left and insert"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vslid_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[rustc_legacy_const_generics(2)]
    @@ -24701,7 +24701,7 @@ pub fn vslid_n_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "SM3PARTW1"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3partw1q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sm4")]
     #[cfg_attr(test, assert_instr(sm3partw1))]
     #[unstable(feature = "stdarch_neon_sm4", issue = "117226")]
    @@ -24717,7 +24717,7 @@ pub fn vsm3partw1q_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_
     }
     #[doc = "SM3PARTW2"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3partw2q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sm4")]
     #[cfg_attr(test, assert_instr(sm3partw2))]
     #[unstable(feature = "stdarch_neon_sm4", issue = "117226")]
    @@ -24733,7 +24733,7 @@ pub fn vsm3partw2q_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_
     }
     #[doc = "SM3SS1"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3ss1q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sm4")]
     #[cfg_attr(test, assert_instr(sm3ss1))]
     #[unstable(feature = "stdarch_neon_sm4", issue = "117226")]
    @@ -24749,7 +24749,7 @@ pub fn vsm3ss1q_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "SM3TT1A"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3tt1aq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sm4")]
     #[cfg_attr(test, assert_instr(sm3tt1a, IMM2 = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -24767,7 +24767,7 @@ pub fn vsm3tt1aq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_
     }
     #[doc = "SM3TT1B"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3tt1bq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sm4")]
     #[cfg_attr(test, assert_instr(sm3tt1b, IMM2 = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -24785,7 +24785,7 @@ pub fn vsm3tt1bq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_
     }
     #[doc = "SM3TT2A"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3tt2aq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sm4")]
     #[cfg_attr(test, assert_instr(sm3tt2a, IMM2 = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -24803,7 +24803,7 @@ pub fn vsm3tt2aq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_
     }
     #[doc = "SM3TT2B"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm3tt2bq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sm4")]
     #[cfg_attr(test, assert_instr(sm3tt2b, IMM2 = 0))]
     #[rustc_legacy_const_generics(3)]
    @@ -24821,7 +24821,7 @@ pub fn vsm3tt2bq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_
     }
     #[doc = "SM4 key"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm4ekeyq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sm4")]
     #[cfg_attr(test, assert_instr(sm4ekey))]
     #[unstable(feature = "stdarch_neon_sm4", issue = "117226")]
    @@ -24837,7 +24837,7 @@ pub fn vsm4ekeyq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "SM4 encode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsm4eq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sm4")]
     #[cfg_attr(test, assert_instr(sm4e))]
     #[unstable(feature = "stdarch_neon_sm4", issue = "117226")]
    @@ -24853,7 +24853,7 @@ pub fn vsm4eq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned saturating Accumulate of Signed value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqadd_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usqadd))]
    @@ -24869,7 +24869,7 @@ pub fn vsqadd_u8(a: uint8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned saturating Accumulate of Signed value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usqadd))]
    @@ -24885,7 +24885,7 @@ pub fn vsqaddq_u8(a: uint8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned saturating Accumulate of Signed value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqadd_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usqadd))]
    @@ -24901,7 +24901,7 @@ pub fn vsqadd_u16(a: uint16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned saturating Accumulate of Signed value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usqadd))]
    @@ -24917,7 +24917,7 @@ pub fn vsqaddq_u16(a: uint16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned saturating Accumulate of Signed value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqadd_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usqadd))]
    @@ -24933,7 +24933,7 @@ pub fn vsqadd_u32(a: uint32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned saturating Accumulate of Signed value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usqadd))]
    @@ -24949,7 +24949,7 @@ pub fn vsqaddq_u32(a: uint32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned saturating Accumulate of Signed value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqadd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usqadd))]
    @@ -24965,7 +24965,7 @@ pub fn vsqadd_u64(a: uint64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned saturating Accumulate of Signed value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usqadd))]
    @@ -24981,7 +24981,7 @@ pub fn vsqaddq_u64(a: uint64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Unsigned saturating accumulate of signed value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddb_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(usqadd))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -24990,7 +24990,7 @@ pub fn vsqaddb_u8(a: u8, b: i8) -> u8 {
     }
     #[doc = "Unsigned saturating accumulate of signed value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddh_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(usqadd))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -24999,7 +24999,7 @@ pub fn vsqaddh_u16(a: u16, b: i16) -> u16 {
     }
     #[doc = "Unsigned saturating accumulate of signed value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqaddd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(usqadd))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25015,7 +25015,7 @@ pub fn vsqaddd_u64(a: u64, b: i64) -> u64 {
     }
     #[doc = "Unsigned saturating accumulate of signed value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqadds_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(usqadd))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25031,7 +25031,7 @@ pub fn vsqadds_u32(a: u32, b: i32) -> u32 {
     }
     #[doc = "Calculates the square root of each lane."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrt_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fsqrt))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -25041,7 +25041,7 @@ pub fn vsqrt_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Calculates the square root of each lane."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrtq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(test, assert_instr(fsqrt))]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
    @@ -25051,7 +25051,7 @@ pub fn vsqrtq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Calculates the square root of each lane."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrt_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fsqrt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25060,7 +25060,7 @@ pub fn vsqrt_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Calculates the square root of each lane."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrtq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fsqrt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25069,7 +25069,7 @@ pub fn vsqrtq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Calculates the square root of each lane."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrt_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fsqrt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25078,7 +25078,7 @@ pub fn vsqrt_f64(a: float64x1_t) -> float64x1_t {
     }
     #[doc = "Calculates the square root of each lane."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrtq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(fsqrt))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25087,7 +25087,7 @@ pub fn vsqrtq_f64(a: float64x2_t) -> float64x2_t {
     }
     #[doc = "Floating-point round to integral, using current rounding mode"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsqrth_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -25097,7 +25097,7 @@ pub fn vsqrth_f16(a: f16) -> f16 {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25115,7 +25115,7 @@ pub fn vsri_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25133,7 +25133,7 @@ pub fn vsriq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25151,7 +25151,7 @@ pub fn vsri_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25169,7 +25169,7 @@ pub fn vsriq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25187,7 +25187,7 @@ pub fn vsri_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25205,7 +25205,7 @@ pub fn vsriq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25223,7 +25223,7 @@ pub fn vsri_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25241,7 +25241,7 @@ pub fn vsriq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25252,7 +25252,7 @@ pub fn vsri_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25263,7 +25263,7 @@ pub fn vsriq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25274,7 +25274,7 @@ pub fn vsri_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25285,7 +25285,7 @@ pub fn vsriq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25296,7 +25296,7 @@ pub fn vsri_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25307,7 +25307,7 @@ pub fn vsriq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25318,7 +25318,7 @@ pub fn vsri_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25329,7 +25329,7 @@ pub fn vsriq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25340,7 +25340,7 @@ pub fn vsri_n_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25351,7 +25351,7 @@ pub fn vsriq_n_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25362,7 +25362,7 @@ pub fn vsri_n_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25373,7 +25373,7 @@ pub fn vsriq_n_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25384,7 +25384,7 @@ pub fn vsri_n_p64(a: poly64x1_t, b: poly64x1_t) -> poly64x1_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(sri, N = 1))]
     #[rustc_legacy_const_generics(2)]
    @@ -25395,7 +25395,7 @@ pub fn vsriq_n_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Shift right and insert"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsrid_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[rustc_legacy_const_generics(2)]
    @@ -25406,7 +25406,7 @@ pub fn vsrid_n_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Shift right and insert"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsrid_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[rustc_legacy_const_generics(2)]
    @@ -25419,7 +25419,7 @@ pub fn vsrid_n_u64(a: u64, b: u64) -> u64 {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25432,7 +25432,7 @@ pub unsafe fn vst1_f16(ptr: *mut f16, a: float16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25445,7 +25445,7 @@ pub unsafe fn vst1q_f16(ptr: *mut f16, a: float16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25457,7 +25457,7 @@ pub unsafe fn vst1_f32(ptr: *mut f32, a: float32x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25469,7 +25469,7 @@ pub unsafe fn vst1q_f32(ptr: *mut f32, a: float32x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25481,7 +25481,7 @@ pub unsafe fn vst1_f64(ptr: *mut f64, a: float64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25493,7 +25493,7 @@ pub unsafe fn vst1q_f64(ptr: *mut f64, a: float64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25505,7 +25505,7 @@ pub unsafe fn vst1_s8(ptr: *mut i8, a: int8x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25517,7 +25517,7 @@ pub unsafe fn vst1q_s8(ptr: *mut i8, a: int8x16_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25529,7 +25529,7 @@ pub unsafe fn vst1_s16(ptr: *mut i16, a: int16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25541,7 +25541,7 @@ pub unsafe fn vst1q_s16(ptr: *mut i16, a: int16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25553,7 +25553,7 @@ pub unsafe fn vst1_s32(ptr: *mut i32, a: int32x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25565,7 +25565,7 @@ pub unsafe fn vst1q_s32(ptr: *mut i32, a: int32x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25577,7 +25577,7 @@ pub unsafe fn vst1_s64(ptr: *mut i64, a: int64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25589,7 +25589,7 @@ pub unsafe fn vst1q_s64(ptr: *mut i64, a: int64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25601,7 +25601,7 @@ pub unsafe fn vst1_u8(ptr: *mut u8, a: uint8x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25613,7 +25613,7 @@ pub unsafe fn vst1q_u8(ptr: *mut u8, a: uint8x16_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25625,7 +25625,7 @@ pub unsafe fn vst1_u16(ptr: *mut u16, a: uint16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25637,7 +25637,7 @@ pub unsafe fn vst1q_u16(ptr: *mut u16, a: uint16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25649,7 +25649,7 @@ pub unsafe fn vst1_u32(ptr: *mut u32, a: uint32x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25661,7 +25661,7 @@ pub unsafe fn vst1q_u32(ptr: *mut u32, a: uint32x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25673,7 +25673,7 @@ pub unsafe fn vst1_u64(ptr: *mut u64, a: uint64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25685,7 +25685,7 @@ pub unsafe fn vst1q_u64(ptr: *mut u64, a: uint64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25697,7 +25697,7 @@ pub unsafe fn vst1_p8(ptr: *mut p8, a: poly8x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25709,7 +25709,7 @@ pub unsafe fn vst1q_p8(ptr: *mut p8, a: poly8x16_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25721,7 +25721,7 @@ pub unsafe fn vst1_p16(ptr: *mut p16, a: poly16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25733,7 +25733,7 @@ pub unsafe fn vst1q_p16(ptr: *mut p16, a: poly16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25745,7 +25745,7 @@ pub unsafe fn vst1_p64(ptr: *mut p64, a: poly64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(str))]
     #[allow(clippy::cast_ptr_alignment)]
    @@ -25757,7 +25757,7 @@ pub unsafe fn vst1q_p64(ptr: *mut p64, a: poly64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st1))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25775,7 +25775,7 @@ pub unsafe fn vst1_f64_x2(a: *mut f64, b: float64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st1))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25793,7 +25793,7 @@ pub unsafe fn vst1q_f64_x2(a: *mut f64, b: float64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st1))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25811,7 +25811,7 @@ pub unsafe fn vst1_f64_x3(a: *mut f64, b: float64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st1))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25829,7 +25829,7 @@ pub unsafe fn vst1q_f64_x3(a: *mut f64, b: float64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st1))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25853,7 +25853,7 @@ pub unsafe fn vst1_f64_x4(a: *mut f64, b: float64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st1))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -25877,7 +25877,7 @@ pub unsafe fn vst1q_f64_x4(a: *mut f64, b: float64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -25890,7 +25890,7 @@ pub unsafe fn vst1_lane_f64(a: *mut f64, b: float64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(nop, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -25903,7 +25903,7 @@ pub unsafe fn vst1q_lane_f64(a: *mut f64, b: float64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st1))]
    @@ -25921,7 +25921,7 @@ pub unsafe fn vst2_f64(a: *mut f64, b: float64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -25941,7 +25941,7 @@ pub unsafe fn vst2_lane_f64(a: *mut f64, b: float64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -25961,7 +25961,7 @@ pub unsafe fn vst2_lane_s64(a: *mut i64, b: int64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -25974,7 +25974,7 @@ pub unsafe fn vst2_lane_p64(a: *mut p64, b: poly64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -25987,7 +25987,7 @@ pub unsafe fn vst2_lane_u64(a: *mut u64, b: uint64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st2))]
    @@ -26005,7 +26005,7 @@ pub unsafe fn vst2q_f64(a: *mut f64, b: float64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st2))]
    @@ -26023,7 +26023,7 @@ pub unsafe fn vst2q_s64(a: *mut i64, b: int64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26043,7 +26043,7 @@ pub unsafe fn vst2q_lane_f64(a: *mut f64, b: float64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26063,7 +26063,7 @@ pub unsafe fn vst2q_lane_s8(a: *mut i8, b: int8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26083,7 +26083,7 @@ pub unsafe fn vst2q_lane_s64(a: *mut i64, b: int64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26096,7 +26096,7 @@ pub unsafe fn vst2q_lane_p64(a: *mut p64, b: poly64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26109,7 +26109,7 @@ pub unsafe fn vst2q_lane_u8(a: *mut u8, b: uint8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26122,7 +26122,7 @@ pub unsafe fn vst2q_lane_u64(a: *mut u64, b: uint64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st2, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26135,7 +26135,7 @@ pub unsafe fn vst2q_lane_p8(a: *mut p8, b: poly8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(st2))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26146,7 +26146,7 @@ pub unsafe fn vst2q_p64(a: *mut p64, b: poly64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st2))]
    @@ -26157,7 +26157,7 @@ pub unsafe fn vst2q_u64(a: *mut u64, b: uint64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -26175,7 +26175,7 @@ pub unsafe fn vst3_f64(a: *mut f64, b: float64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26195,7 +26195,7 @@ pub unsafe fn vst3_lane_f64(a: *mut f64, b: float64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26215,7 +26215,7 @@ pub unsafe fn vst3_lane_s64(a: *mut i64, b: int64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
    @@ -26228,7 +26228,7 @@ pub unsafe fn vst3_lane_p64(a: *mut p64, b: poly64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
    @@ -26241,7 +26241,7 @@ pub unsafe fn vst3_lane_u64(a: *mut u64, b: uint64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st3))]
    @@ -26259,7 +26259,7 @@ pub unsafe fn vst3q_f64(a: *mut f64, b: float64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st3))]
    @@ -26277,7 +26277,7 @@ pub unsafe fn vst3q_s64(a: *mut i64, b: int64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26297,7 +26297,7 @@ pub unsafe fn vst3q_lane_f64(a: *mut f64, b: float64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26317,7 +26317,7 @@ pub unsafe fn vst3q_lane_s8(a: *mut i8, b: int8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26337,7 +26337,7 @@ pub unsafe fn vst3q_lane_s64(a: *mut i64, b: int64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
    @@ -26350,7 +26350,7 @@ pub unsafe fn vst3q_lane_p64(a: *mut p64, b: poly64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
    @@ -26363,7 +26363,7 @@ pub unsafe fn vst3q_lane_u8(a: *mut u8, b: uint8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
    @@ -26376,7 +26376,7 @@ pub unsafe fn vst3q_lane_u64(a: *mut u64, b: uint64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st3, LANE = 0))]
    @@ -26389,7 +26389,7 @@ pub unsafe fn vst3q_lane_p8(a: *mut p8, b: poly8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(st3))]
    @@ -26400,7 +26400,7 @@ pub unsafe fn vst3q_p64(a: *mut p64, b: poly64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st3))]
    @@ -26411,7 +26411,7 @@ pub unsafe fn vst3q_u64(a: *mut u64, b: uint64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -26429,7 +26429,7 @@ pub unsafe fn vst4_f64(a: *mut f64, b: float64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26456,7 +26456,7 @@ pub unsafe fn vst4_lane_f64(a: *mut f64, b: float64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26483,7 +26483,7 @@ pub unsafe fn vst4_lane_s64(a: *mut i64, b: int64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
    @@ -26496,7 +26496,7 @@ pub unsafe fn vst4_lane_p64(a: *mut p64, b: poly64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
    @@ -26509,7 +26509,7 @@ pub unsafe fn vst4_lane_u64(a: *mut u64, b: uint64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st4))]
    @@ -26527,7 +26527,7 @@ pub unsafe fn vst4q_f64(a: *mut f64, b: float64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st4))]
    @@ -26545,7 +26545,7 @@ pub unsafe fn vst4q_s64(a: *mut i64, b: int64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26572,7 +26572,7 @@ pub unsafe fn vst4q_lane_f64(a: *mut f64, b: float64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26599,7 +26599,7 @@ pub unsafe fn vst4q_lane_s8(a: *mut i8, b: int8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -26626,7 +26626,7 @@ pub unsafe fn vst4q_lane_s64(a: *mut i64, b: int64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
    @@ -26639,7 +26639,7 @@ pub unsafe fn vst4q_lane_p64(a: *mut p64, b: poly64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
    @@ -26652,7 +26652,7 @@ pub unsafe fn vst4q_lane_u8(a: *mut u8, b: uint8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
    @@ -26665,7 +26665,7 @@ pub unsafe fn vst4q_lane_u64(a: *mut u64, b: uint64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st4, LANE = 0))]
    @@ -26678,7 +26678,7 @@ pub unsafe fn vst4q_lane_p8(a: *mut p8, b: poly8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(test, assert_instr(st4))]
    @@ -26689,7 +26689,7 @@ pub unsafe fn vst4q_p64(a: *mut p64, b: poly64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(st4))]
    @@ -26698,7 +26698,7 @@ pub unsafe fn vst4q_u64(a: *mut u64, b: uint64x2x4_t) {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fsub))]
    @@ -26707,7 +26707,7 @@ pub fn vsub_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(fsub))]
    @@ -26716,7 +26716,7 @@ pub fn vsubq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sub))]
    @@ -26725,7 +26725,7 @@ pub fn vsubd_s64(a: i64, b: i64) -> i64 {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(sub))]
    @@ -26734,7 +26734,7 @@ pub fn vsubd_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -26744,7 +26744,7 @@ pub fn vsubh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Signed Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ssubl2))]
    @@ -26759,7 +26759,7 @@ pub fn vsubl_high_s8(a: int8x16_t, b: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ssubl2))]
    @@ -26774,7 +26774,7 @@ pub fn vsubl_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ssubl2))]
    @@ -26789,7 +26789,7 @@ pub fn vsubl_high_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t {
     }
     #[doc = "Unsigned Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usubl2))]
    @@ -26804,7 +26804,7 @@ pub fn vsubl_high_u8(a: uint8x16_t, b: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usubl2))]
    @@ -26819,7 +26819,7 @@ pub fn vsubl_high_u16(a: uint16x8_t, b: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usubl2))]
    @@ -26834,7 +26834,7 @@ pub fn vsubl_high_u32(a: uint32x4_t, b: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Signed Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ssubw2))]
    @@ -26846,7 +26846,7 @@ pub fn vsubw_high_s8(a: int16x8_t, b: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ssubw2))]
    @@ -26858,7 +26858,7 @@ pub fn vsubw_high_s16(a: int32x4_t, b: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(ssubw2))]
    @@ -26870,7 +26870,7 @@ pub fn vsubw_high_s32(a: int64x2_t, b: int32x4_t) -> int64x2_t {
     }
     #[doc = "Unsigned Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usubw2))]
    @@ -26882,7 +26882,7 @@ pub fn vsubw_high_u8(a: uint16x8_t, b: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usubw2))]
    @@ -26894,7 +26894,7 @@ pub fn vsubw_high_u16(a: uint32x4_t, b: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(usubw2))]
    @@ -26906,7 +26906,7 @@ pub fn vsubw_high_u32(a: uint64x2_t, b: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Dot product index form with signed and unsigned integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudot_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(test, assert_instr(sudot, LANE = 3))]
     #[rustc_legacy_const_generics(3)]
    @@ -26921,7 +26921,7 @@ pub fn vsudot_laneq_s32(a: int32x2_t, b: int8x8_t, c: uint8x16_
     }
     #[doc = "Dot product index form with signed and unsigned integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudotq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(test, assert_instr(sudot, LANE = 3))]
     #[rustc_legacy_const_generics(3)]
    @@ -26937,7 +26937,7 @@ pub fn vsudotq_laneq_s32(a: int32x4_t, b: int8x16_t, c: uint8x1
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26950,7 +26950,7 @@ pub fn vtbl1_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26959,7 +26959,7 @@ pub fn vtbl1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26968,7 +26968,7 @@ pub fn vtbl1_p8(a: poly8x8_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26977,7 +26977,7 @@ pub fn vtbl2_s8(a: int8x8x2_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -26987,7 +26987,7 @@ pub fn vtbl2_u8(a: uint8x8x2_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27004,7 +27004,7 @@ pub fn vtbl2_u8(a: uint8x8x2_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27014,7 +27014,7 @@ pub fn vtbl2_p8(a: poly8x8x2_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27031,7 +27031,7 @@ pub fn vtbl2_p8(a: poly8x8x2_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -27044,7 +27044,7 @@ pub fn vtbl3_s8(a: int8x8x3_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27058,7 +27058,7 @@ pub fn vtbl3_u8(a: uint8x8x3_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27080,7 +27080,7 @@ pub fn vtbl3_u8(a: uint8x8x3_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27094,7 +27094,7 @@ pub fn vtbl3_p8(a: poly8x8x3_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27116,7 +27116,7 @@ pub fn vtbl3_p8(a: poly8x8x3_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -27126,7 +27126,7 @@ pub fn vtbl4_s8(a: int8x8x4_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27137,7 +27137,7 @@ pub fn vtbl4_u8(a: uint8x8x4_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27157,7 +27157,7 @@ pub fn vtbl4_u8(a: uint8x8x4_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27168,7 +27168,7 @@ pub fn vtbl4_p8(a: poly8x8x4_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbl))]
    @@ -27188,7 +27188,7 @@ pub fn vtbl4_p8(a: poly8x8x4_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx1_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -27207,7 +27207,7 @@ pub fn vtbx1_s8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -27226,7 +27226,7 @@ pub fn vtbx1_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -27245,7 +27245,7 @@ pub fn vtbx1_p8(a: poly8x8_t, b: poly8x8_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -27254,7 +27254,7 @@ pub fn vtbx2_s8(a: int8x8_t, b: int8x8x2_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27264,7 +27264,7 @@ pub fn vtbx2_u8(a: uint8x8_t, b: uint8x8x2_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27283,7 +27283,7 @@ pub fn vtbx2_u8(a: uint8x8_t, b: uint8x8x2_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27293,7 +27293,7 @@ pub fn vtbx2_p8(a: poly8x8_t, b: poly8x8x2_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27312,7 +27312,7 @@ pub fn vtbx2_p8(a: poly8x8_t, b: poly8x8x2_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -27336,7 +27336,7 @@ pub fn vtbx3_s8(a: int8x8_t, b: int8x8x3_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27356,7 +27356,7 @@ pub fn vtbx3_u8(a: uint8x8_t, b: uint8x8x3_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27383,7 +27383,7 @@ pub fn vtbx3_u8(a: uint8x8_t, b: uint8x8x3_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27403,7 +27403,7 @@ pub fn vtbx3_p8(a: poly8x8_t, b: poly8x8x3_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27430,7 +27430,7 @@ pub fn vtbx3_p8(a: poly8x8_t, b: poly8x8x3_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -27446,7 +27446,7 @@ pub fn vtbx4_s8(a: int8x8_t, b: int8x8x4_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27463,7 +27463,7 @@ pub fn vtbx4_u8(a: uint8x8_t, b: uint8x8x4_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27488,7 +27488,7 @@ pub fn vtbx4_u8(a: uint8x8_t, b: uint8x8x4_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27505,7 +27505,7 @@ pub fn vtbx4_p8(a: poly8x8_t, b: poly8x8x4_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tbx))]
    @@ -27530,7 +27530,7 @@ pub fn vtbx4_p8(a: poly8x8_t, b: poly8x8x4_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -27540,7 +27540,7 @@ pub fn vtrn1_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -27550,7 +27550,7 @@ pub fn vtrn1q_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -27559,7 +27559,7 @@ pub fn vtrn1_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -27568,7 +27568,7 @@ pub fn vtrn1q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -27577,7 +27577,7 @@ pub fn vtrn1_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -27586,7 +27586,7 @@ pub fn vtrn1q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -27595,7 +27595,7 @@ pub fn vtrn1_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -27604,7 +27604,7 @@ pub fn vtrn1q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -27613,7 +27613,7 @@ pub fn vtrn1q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27622,7 +27622,7 @@ pub fn vtrn1q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27631,7 +27631,7 @@ pub fn vtrn1_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27646,7 +27646,7 @@ pub fn vtrn1q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27655,7 +27655,7 @@ pub fn vtrn1_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27664,7 +27664,7 @@ pub fn vtrn1q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27673,7 +27673,7 @@ pub fn vtrn1q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27682,7 +27682,7 @@ pub fn vtrn1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27697,7 +27697,7 @@ pub fn vtrn1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27706,7 +27706,7 @@ pub fn vtrn1_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27715,7 +27715,7 @@ pub fn vtrn1q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27724,7 +27724,7 @@ pub fn vtrn1q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27733,7 +27733,7 @@ pub fn vtrn1_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27748,7 +27748,7 @@ pub fn vtrn1q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27757,7 +27757,7 @@ pub fn vtrn1_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn1))]
    @@ -27766,7 +27766,7 @@ pub fn vtrn1q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -27776,7 +27776,7 @@ pub fn vtrn2_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -27786,7 +27786,7 @@ pub fn vtrn2q_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -27795,7 +27795,7 @@ pub fn vtrn2_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -27804,7 +27804,7 @@ pub fn vtrn2q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -27813,7 +27813,7 @@ pub fn vtrn2_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -27822,7 +27822,7 @@ pub fn vtrn2q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -27831,7 +27831,7 @@ pub fn vtrn2_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -27840,7 +27840,7 @@ pub fn vtrn2q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -27849,7 +27849,7 @@ pub fn vtrn2q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27858,7 +27858,7 @@ pub fn vtrn2q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27867,7 +27867,7 @@ pub fn vtrn2_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27882,7 +27882,7 @@ pub fn vtrn2q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27891,7 +27891,7 @@ pub fn vtrn2_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27900,7 +27900,7 @@ pub fn vtrn2q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27909,7 +27909,7 @@ pub fn vtrn2q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27918,7 +27918,7 @@ pub fn vtrn2_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27933,7 +27933,7 @@ pub fn vtrn2q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27942,7 +27942,7 @@ pub fn vtrn2_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27951,7 +27951,7 @@ pub fn vtrn2q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27960,7 +27960,7 @@ pub fn vtrn2q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27969,7 +27969,7 @@ pub fn vtrn2_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27984,7 +27984,7 @@ pub fn vtrn2q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -27993,7 +27993,7 @@ pub fn vtrn2_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Transpose vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(trn2))]
    @@ -28002,7 +28002,7 @@ pub fn vtrn2q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmtst))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28015,7 +28015,7 @@ pub fn vtst_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmtst))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28028,7 +28028,7 @@ pub fn vtstq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmtst))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28041,7 +28041,7 @@ pub fn vtst_p64(a: poly64x1_t, b: poly64x1_t) -> uint64x1_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmtst))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28054,7 +28054,7 @@ pub fn vtstq_p64(a: poly64x2_t, b: poly64x2_t) -> uint64x2_t {
     }
     #[doc = "Unsigned compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmtst))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28067,7 +28067,7 @@ pub fn vtst_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(cmtst))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28080,7 +28080,7 @@ pub fn vtstq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Compare bitwise test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tst))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28089,7 +28089,7 @@ pub fn vtstd_s64(a: i64, b: i64) -> u64 {
     }
     #[doc = "Compare bitwise test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(tst))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28098,7 +28098,7 @@ pub fn vtstd_u64(a: u64, b: u64) -> u64 {
     }
     #[doc = "Signed saturating Accumulate of Unsigned value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqadd_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(suqadd))]
    @@ -28114,7 +28114,7 @@ pub fn vuqadd_s8(a: int8x8_t, b: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating Accumulate of Unsigned value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(suqadd))]
    @@ -28130,7 +28130,7 @@ pub fn vuqaddq_s8(a: int8x16_t, b: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Signed saturating Accumulate of Unsigned value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqadd_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(suqadd))]
    @@ -28146,7 +28146,7 @@ pub fn vuqadd_s16(a: int16x4_t, b: uint16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating Accumulate of Unsigned value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(suqadd))]
    @@ -28162,7 +28162,7 @@ pub fn vuqaddq_s16(a: int16x8_t, b: uint16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating Accumulate of Unsigned value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqadd_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(suqadd))]
    @@ -28178,7 +28178,7 @@ pub fn vuqadd_s32(a: int32x2_t, b: uint32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating Accumulate of Unsigned value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(suqadd))]
    @@ -28194,7 +28194,7 @@ pub fn vuqaddq_s32(a: int32x4_t, b: uint32x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating Accumulate of Unsigned value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqadd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(suqadd))]
    @@ -28210,7 +28210,7 @@ pub fn vuqadd_s64(a: int64x1_t, b: uint64x1_t) -> int64x1_t {
     }
     #[doc = "Signed saturating Accumulate of Unsigned value."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(test, assert_instr(suqadd))]
    @@ -28226,7 +28226,7 @@ pub fn vuqaddq_s64(a: int64x2_t, b: uint64x2_t) -> int64x2_t {
     }
     #[doc = "Signed saturating accumulate of unsigned value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddb_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(suqadd))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28235,7 +28235,7 @@ pub fn vuqaddb_s8(a: i8, b: u8) -> i8 {
     }
     #[doc = "Signed saturating accumulate of unsigned value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(suqadd))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28244,7 +28244,7 @@ pub fn vuqaddh_s16(a: i16, b: u16) -> i16 {
     }
     #[doc = "Signed saturating accumulate of unsigned value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqaddd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(suqadd))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28260,7 +28260,7 @@ pub fn vuqaddd_s64(a: i64, b: u64) -> i64 {
     }
     #[doc = "Signed saturating accumulate of unsigned value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuqadds_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(test, assert_instr(suqadd))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -28276,7 +28276,7 @@ pub fn vuqadds_s32(a: i32, b: u32) -> i32 {
     }
     #[doc = "Dot product index form with unsigned and signed integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdot_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(test, assert_instr(usdot, LANE = 3))]
     #[rustc_legacy_const_generics(3)]
    @@ -28291,7 +28291,7 @@ pub fn vusdot_laneq_s32(a: int32x2_t, b: uint8x8_t, c: int8x16_
     }
     #[doc = "Dot product index form with unsigned and signed integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdotq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(test, assert_instr(usdot, LANE = 3))]
     #[rustc_legacy_const_generics(3)]
    @@ -28307,7 +28307,7 @@ pub fn vusdotq_laneq_s32(a: int32x4_t, b: uint8x16_t, c: int8x1
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -28317,7 +28317,7 @@ pub fn vuzp1_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -28327,7 +28327,7 @@ pub fn vuzp1q_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28336,7 +28336,7 @@ pub fn vuzp1_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28345,7 +28345,7 @@ pub fn vuzp1q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28354,7 +28354,7 @@ pub fn vuzp1_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28363,7 +28363,7 @@ pub fn vuzp1q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28372,7 +28372,7 @@ pub fn vuzp1_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28381,7 +28381,7 @@ pub fn vuzp1q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28390,7 +28390,7 @@ pub fn vuzp1q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28399,7 +28399,7 @@ pub fn vuzp1q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28408,7 +28408,7 @@ pub fn vuzp1_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28423,7 +28423,7 @@ pub fn vuzp1q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28432,7 +28432,7 @@ pub fn vuzp1_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28441,7 +28441,7 @@ pub fn vuzp1q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28450,7 +28450,7 @@ pub fn vuzp1q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28459,7 +28459,7 @@ pub fn vuzp1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28474,7 +28474,7 @@ pub fn vuzp1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28483,7 +28483,7 @@ pub fn vuzp1_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28492,7 +28492,7 @@ pub fn vuzp1q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28501,7 +28501,7 @@ pub fn vuzp1q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28510,7 +28510,7 @@ pub fn vuzp1_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28525,7 +28525,7 @@ pub fn vuzp1q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28534,7 +28534,7 @@ pub fn vuzp1_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp1q_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp1))]
    @@ -28543,7 +28543,7 @@ pub fn vuzp1q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -28553,7 +28553,7 @@ pub fn vuzp2_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -28563,7 +28563,7 @@ pub fn vuzp2q_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -28572,7 +28572,7 @@ pub fn vuzp2_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -28581,7 +28581,7 @@ pub fn vuzp2q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -28590,7 +28590,7 @@ pub fn vuzp2_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -28599,7 +28599,7 @@ pub fn vuzp2q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -28608,7 +28608,7 @@ pub fn vuzp2_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -28617,7 +28617,7 @@ pub fn vuzp2q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -28626,7 +28626,7 @@ pub fn vuzp2q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28635,7 +28635,7 @@ pub fn vuzp2q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28644,7 +28644,7 @@ pub fn vuzp2_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28659,7 +28659,7 @@ pub fn vuzp2q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28668,7 +28668,7 @@ pub fn vuzp2_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28677,7 +28677,7 @@ pub fn vuzp2q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28686,7 +28686,7 @@ pub fn vuzp2q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28695,7 +28695,7 @@ pub fn vuzp2_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28710,7 +28710,7 @@ pub fn vuzp2q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28719,7 +28719,7 @@ pub fn vuzp2_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28728,7 +28728,7 @@ pub fn vuzp2q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28737,7 +28737,7 @@ pub fn vuzp2q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28746,7 +28746,7 @@ pub fn vuzp2_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28761,7 +28761,7 @@ pub fn vuzp2q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28770,7 +28770,7 @@ pub fn vuzp2_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp2q_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(uzp2))]
    @@ -28779,7 +28779,7 @@ pub fn vuzp2q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Exclusive OR and rotate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vxarq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,sha3")]
     #[cfg_attr(test, assert_instr(xar, IMM6 = 0))]
     #[rustc_legacy_const_generics(2)]
    @@ -28797,7 +28797,7 @@ pub fn vxarq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -28807,7 +28807,7 @@ pub fn vzip1_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -28817,7 +28817,7 @@ pub fn vzip1q_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28826,7 +28826,7 @@ pub fn vzip1_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28835,7 +28835,7 @@ pub fn vzip1q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28844,7 +28844,7 @@ pub fn vzip1q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28853,7 +28853,7 @@ pub fn vzip1_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28868,7 +28868,7 @@ pub fn vzip1q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28877,7 +28877,7 @@ pub fn vzip1_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28886,7 +28886,7 @@ pub fn vzip1q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28895,7 +28895,7 @@ pub fn vzip1_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28904,7 +28904,7 @@ pub fn vzip1q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28913,7 +28913,7 @@ pub fn vzip1q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28922,7 +28922,7 @@ pub fn vzip1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28937,7 +28937,7 @@ pub fn vzip1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28946,7 +28946,7 @@ pub fn vzip1_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28955,7 +28955,7 @@ pub fn vzip1q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28964,7 +28964,7 @@ pub fn vzip1_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28973,7 +28973,7 @@ pub fn vzip1q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28982,7 +28982,7 @@ pub fn vzip1q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -28991,7 +28991,7 @@ pub fn vzip1_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -29006,7 +29006,7 @@ pub fn vzip1q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -29015,7 +29015,7 @@ pub fn vzip1_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -29024,7 +29024,7 @@ pub fn vzip1q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip1q_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip1))]
    @@ -29033,7 +29033,7 @@ pub fn vzip1q_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -29043,7 +29043,7 @@ pub fn vzip2_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[stable(feature = "stdarch_neon_fp16", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(not(target_arch = "arm64ec"))]
    @@ -29053,7 +29053,7 @@ pub fn vzip2q_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29062,7 +29062,7 @@ pub fn vzip2_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29071,7 +29071,7 @@ pub fn vzip2q_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_f64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29080,7 +29080,7 @@ pub fn vzip2q_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29089,7 +29089,7 @@ pub fn vzip2_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29104,7 +29104,7 @@ pub fn vzip2q_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29113,7 +29113,7 @@ pub fn vzip2_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29122,7 +29122,7 @@ pub fn vzip2q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29131,7 +29131,7 @@ pub fn vzip2_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29140,7 +29140,7 @@ pub fn vzip2q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29149,7 +29149,7 @@ pub fn vzip2q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29158,7 +29158,7 @@ pub fn vzip2_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29173,7 +29173,7 @@ pub fn vzip2q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29182,7 +29182,7 @@ pub fn vzip2_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29191,7 +29191,7 @@ pub fn vzip2q_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29200,7 +29200,7 @@ pub fn vzip2_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29209,7 +29209,7 @@ pub fn vzip2q_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29218,7 +29218,7 @@ pub fn vzip2q_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29227,7 +29227,7 @@ pub fn vzip2_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29242,7 +29242,7 @@ pub fn vzip2q_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29251,7 +29251,7 @@ pub fn vzip2_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    @@ -29260,7 +29260,7 @@ pub fn vzip2q_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip2q_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(zip2))]
    diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs
    index 0aeb740efcd0..324ff73f62a1 100644
    --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs
    +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs
    @@ -14,7 +14,7 @@ use super::*;
     
     #[doc = "CRC32 single round checksum for bytes (8 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32b)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(crc32b))]
    @@ -39,7 +39,7 @@ pub fn __crc32b(crc: u32, data: u8) -> u32 {
     }
     #[doc = "CRC32-C single round checksum for bytes (8 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cb)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(crc32cb))]
    @@ -64,7 +64,7 @@ pub fn __crc32cb(crc: u32, data: u8) -> u32 {
     }
     #[doc = "CRC32-C single round checksum for quad words (64 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cd)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(crc32cw))]
    @@ -83,7 +83,7 @@ pub fn __crc32cd(crc: u32, data: u64) -> u32 {
     }
     #[doc = "CRC32-C single round checksum for bytes (16 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32ch)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(crc32ch))]
    @@ -108,7 +108,7 @@ pub fn __crc32ch(crc: u32, data: u16) -> u32 {
     }
     #[doc = "CRC32-C single round checksum for bytes (32 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cw)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(crc32cw))]
    @@ -133,7 +133,7 @@ pub fn __crc32cw(crc: u32, data: u32) -> u32 {
     }
     #[doc = "CRC32 single round checksum for quad words (64 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(crc32w))]
    @@ -152,7 +152,7 @@ pub fn __crc32d(crc: u32, data: u64) -> u32 {
     }
     #[doc = "CRC32 single round checksum for bytes (16 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32h)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(crc32h))]
    @@ -177,7 +177,7 @@ pub fn __crc32h(crc: u32, data: u16) -> u32 {
     }
     #[doc = "CRC32 single round checksum for bytes (32 bits)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32w)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "crc")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(crc32w))]
    @@ -202,7 +202,7 @@ pub fn __crc32w(crc: u32, data: u32) -> u32 {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadal_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -220,7 +220,7 @@ fn priv_vpadal_s8(a: int16x4_t, b: int8x8_t) -> int16x4_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadalq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -238,7 +238,7 @@ fn priv_vpadalq_s8(a: int16x8_t, b: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadal_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -256,7 +256,7 @@ fn priv_vpadal_s16(a: int32x2_t, b: int16x4_t) -> int32x2_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadalq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -274,7 +274,7 @@ fn priv_vpadalq_s16(a: int32x4_t, b: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadal_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -292,7 +292,7 @@ fn priv_vpadal_s32(a: int64x1_t, b: int32x2_t) -> int64x1_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadalq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -310,7 +310,7 @@ fn priv_vpadalq_s32(a: int64x2_t, b: int32x4_t) -> int64x2_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadal_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -328,7 +328,7 @@ fn priv_vpadal_u8(a: uint16x4_t, b: uint8x8_t) -> uint16x4_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadalq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -346,7 +346,7 @@ fn priv_vpadalq_u8(a: uint16x8_t, b: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadal_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -364,7 +364,7 @@ fn priv_vpadal_u16(a: uint32x2_t, b: uint16x4_t) -> uint32x2_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadalq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -382,7 +382,7 @@ fn priv_vpadalq_u16(a: uint32x4_t, b: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadal_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -400,7 +400,7 @@ fn priv_vpadal_u32(a: uint64x1_t, b: uint32x2_t) -> uint64x1_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/priv_vpadalq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -418,7 +418,7 @@ fn priv_vpadalq_u32(a: uint64x2_t, b: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Absolute difference and accumulate (64-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaba_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.s16"))]
    @@ -439,7 +439,7 @@ pub fn vaba_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
     }
     #[doc = "Absolute difference and accumulate (64-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaba_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.s32"))]
    @@ -460,7 +460,7 @@ pub fn vaba_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
     }
     #[doc = "Absolute difference and accumulate (64-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaba_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.s8"))]
    @@ -481,7 +481,7 @@ pub fn vaba_s8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Absolute difference and accumulate (64-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaba_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.u16"))]
    @@ -502,7 +502,7 @@ pub fn vaba_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Absolute difference and accumulate (64-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaba_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.u32"))]
    @@ -523,7 +523,7 @@ pub fn vaba_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Absolute difference and accumulate (64-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaba_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.u8"))]
    @@ -544,7 +544,7 @@ pub fn vaba_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Signed Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabal.s8"))]
    @@ -569,7 +569,7 @@ pub fn vabal_s8(a: int16x8_t, b: int8x8_t, c: int8x8_t) -> int16x8_t {
     }
     #[doc = "Signed Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabal.s16"))]
    @@ -594,7 +594,7 @@ pub fn vabal_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabal.s32"))]
    @@ -619,7 +619,7 @@ pub fn vabal_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabal.u8"))]
    @@ -641,7 +641,7 @@ pub fn vabal_u8(a: uint16x8_t, b: uint8x8_t, c: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabal.u16"))]
    @@ -663,7 +663,7 @@ pub fn vabal_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Absolute difference and Accumulate Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabal_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabal.u32"))]
    @@ -685,7 +685,7 @@ pub fn vabal_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Absolute difference and accumulate (128-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabaq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.s16"))]
    @@ -706,7 +706,7 @@ pub fn vabaq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
     }
     #[doc = "Absolute difference and accumulate (128-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabaq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.s32"))]
    @@ -727,7 +727,7 @@ pub fn vabaq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
     }
     #[doc = "Absolute difference and accumulate (128-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabaq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.s8"))]
    @@ -748,7 +748,7 @@ pub fn vabaq_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
     }
     #[doc = "Absolute difference and accumulate (128-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabaq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.u16"))]
    @@ -769,7 +769,7 @@ pub fn vabaq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Absolute difference and accumulate (128-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabaq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.u32"))]
    @@ -790,7 +790,7 @@ pub fn vabaq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Absolute difference and accumulate (128-bit)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabaq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vaba.u8"))]
    @@ -811,7 +811,7 @@ pub fn vabaq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Absolute difference between the arguments of Floating"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.f16"))]
     #[cfg_attr(
    @@ -841,7 +841,7 @@ pub fn vabd_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Absolute difference between the arguments of Floating"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.f16"))]
     #[cfg_attr(
    @@ -871,7 +871,7 @@ pub fn vabdq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Absolute difference between the arguments of Floating"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.f32"))]
    @@ -900,7 +900,7 @@ pub fn vabd_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Absolute difference between the arguments of Floating"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.f32"))]
    @@ -929,7 +929,7 @@ pub fn vabdq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.s8"))]
    @@ -958,7 +958,7 @@ pub fn vabd_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.s8"))]
    @@ -987,7 +987,7 @@ pub fn vabdq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.s16"))]
    @@ -1016,7 +1016,7 @@ pub fn vabd_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.s16"))]
    @@ -1045,7 +1045,7 @@ pub fn vabdq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.s32"))]
    @@ -1074,7 +1074,7 @@ pub fn vabd_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.s32"))]
    @@ -1103,7 +1103,7 @@ pub fn vabdq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.u8"))]
    @@ -1132,7 +1132,7 @@ pub fn vabd_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.u8"))]
    @@ -1161,7 +1161,7 @@ pub fn vabdq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.u16"))]
    @@ -1190,7 +1190,7 @@ pub fn vabd_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.u16"))]
    @@ -1219,7 +1219,7 @@ pub fn vabdq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabd_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.u32"))]
    @@ -1248,7 +1248,7 @@ pub fn vabd_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Absolute difference between the arguments"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabd.u32"))]
    @@ -1277,7 +1277,7 @@ pub fn vabdq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Signed Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabdl.s8"))]
    @@ -1301,7 +1301,7 @@ pub fn vabdl_s8(a: int8x8_t, b: int8x8_t) -> int16x8_t {
     }
     #[doc = "Signed Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabdl.s16"))]
    @@ -1325,7 +1325,7 @@ pub fn vabdl_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabdl.s32"))]
    @@ -1349,7 +1349,7 @@ pub fn vabdl_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabdl.u8"))]
    @@ -1370,7 +1370,7 @@ pub fn vabdl_u8(a: uint8x8_t, b: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabdl.u16"))]
    @@ -1391,7 +1391,7 @@ pub fn vabdl_u16(a: uint16x4_t, b: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Absolute difference Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabdl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vabdl.u32"))]
    @@ -1412,7 +1412,7 @@ pub fn vabdl_u32(a: uint32x2_t, b: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabs_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
     #[cfg_attr(
    @@ -1434,7 +1434,7 @@ pub fn vabs_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
     #[cfg_attr(
    @@ -1456,7 +1456,7 @@ pub fn vabsq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabs_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
    @@ -1477,7 +1477,7 @@ pub fn vabs_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
    @@ -1498,7 +1498,7 @@ pub fn vabsq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Absolute value (wrapping)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabs_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
    @@ -1523,7 +1523,7 @@ pub fn vabs_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Absolute value (wrapping)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
    @@ -1548,7 +1548,7 @@ pub fn vabsq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Absolute value (wrapping)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabs_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
    @@ -1573,7 +1573,7 @@ pub fn vabs_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Absolute value (wrapping)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
    @@ -1598,7 +1598,7 @@ pub fn vabsq_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Absolute value (wrapping)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabs_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
    @@ -1623,7 +1623,7 @@ pub fn vabs_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Absolute value (wrapping)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
    @@ -1648,7 +1648,7 @@ pub fn vabsq_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Floating-point absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
     #[cfg_attr(
    @@ -1663,7 +1663,7 @@ pub fn vabsh_f16(a: f16) -> f16 {
     }
     #[doc = "Floating-point Add (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vadd.f16"))]
     #[cfg_attr(
    @@ -1685,7 +1685,7 @@ pub fn vadd_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point Add (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vadd.f16"))]
     #[cfg_attr(
    @@ -1707,7 +1707,7 @@ pub fn vaddq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1728,7 +1728,7 @@ pub fn vadd_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1749,7 +1749,7 @@ pub fn vadd_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1770,7 +1770,7 @@ pub fn vadd_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1791,7 +1791,7 @@ pub fn vadd_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1812,7 +1812,7 @@ pub fn vadd_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1833,7 +1833,7 @@ pub fn vadd_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1854,7 +1854,7 @@ pub fn vadd_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1875,7 +1875,7 @@ pub fn vaddq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1896,7 +1896,7 @@ pub fn vaddq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1917,7 +1917,7 @@ pub fn vaddq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1938,7 +1938,7 @@ pub fn vaddq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1959,7 +1959,7 @@ pub fn vaddq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -1980,7 +1980,7 @@ pub fn vaddq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -2001,7 +2001,7 @@ pub fn vaddq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -2022,7 +2022,7 @@ pub fn vaddq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector add."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vadd))]
    @@ -2043,7 +2043,7 @@ pub fn vaddq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Bitwise exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -2064,7 +2064,7 @@ pub fn vadd_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Bitwise exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -2085,7 +2085,7 @@ pub fn vaddq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Bitwise exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -2106,7 +2106,7 @@ pub fn vadd_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Bitwise exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -2127,7 +2127,7 @@ pub fn vaddq_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Bitwise exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vadd_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -2148,7 +2148,7 @@ pub fn vadd_p64(a: poly64x1_t, b: poly64x1_t) -> poly64x1_t {
     }
     #[doc = "Bitwise exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -2169,7 +2169,7 @@ pub fn vaddq_p64(a: poly64x2_t, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "Add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddh_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vadd.f16"))]
     #[cfg_attr(
    @@ -2184,7 +2184,7 @@ pub fn vaddh_f16(a: f16, b: f16) -> f16 {
     }
     #[doc = "Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2208,7 +2208,7 @@ pub fn vaddhn_high_s16(r: int8x8_t, a: int16x8_t, b: int16x8_t) -> int8x16_t {
     }
     #[doc = "Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2232,7 +2232,7 @@ pub fn vaddhn_high_s32(r: int16x4_t, a: int32x4_t, b: int32x4_t) -> int16x8_t {
     }
     #[doc = "Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_high_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2256,7 +2256,7 @@ pub fn vaddhn_high_s64(r: int32x2_t, a: int64x2_t, b: int64x2_t) -> int32x4_t {
     }
     #[doc = "Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2280,7 +2280,7 @@ pub fn vaddhn_high_u16(r: uint8x8_t, a: uint16x8_t, b: uint16x8_t) -> uint8x16_t
     }
     #[doc = "Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2304,7 +2304,7 @@ pub fn vaddhn_high_u32(r: uint16x4_t, a: uint32x4_t, b: uint32x4_t) -> uint16x8_
     }
     #[doc = "Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_high_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2328,7 +2328,7 @@ pub fn vaddhn_high_u64(r: uint32x2_t, a: uint64x2_t, b: uint64x2_t) -> uint32x4_
     }
     #[doc = "Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2349,7 +2349,7 @@ pub fn vaddhn_s16(a: int16x8_t, b: int16x8_t) -> int8x8_t {
     }
     #[doc = "Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2370,7 +2370,7 @@ pub fn vaddhn_s32(a: int32x4_t, b: int32x4_t) -> int16x4_t {
     }
     #[doc = "Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2391,7 +2391,7 @@ pub fn vaddhn_s64(a: int64x2_t, b: int64x2_t) -> int32x2_t {
     }
     #[doc = "Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2412,7 +2412,7 @@ pub fn vaddhn_u16(a: uint16x8_t, b: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2433,7 +2433,7 @@ pub fn vaddhn_u32(a: uint32x4_t, b: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddhn_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddhn))]
    @@ -2454,7 +2454,7 @@ pub fn vaddhn_u64(a: uint64x2_t, b: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Signed Add Long (vector, high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2481,7 +2481,7 @@ pub fn vaddl_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed Add Long (vector, high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2508,7 +2508,7 @@ pub fn vaddl_high_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t {
     }
     #[doc = "Signed Add Long (vector, high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2535,7 +2535,7 @@ pub fn vaddl_high_s8(a: int8x16_t, b: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed Add Long (vector, high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2562,7 +2562,7 @@ pub fn vaddl_high_u16(a: uint16x8_t, b: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Signed Add Long (vector, high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2589,7 +2589,7 @@ pub fn vaddl_high_u32(a: uint32x4_t, b: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Signed Add Long (vector, high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2616,7 +2616,7 @@ pub fn vaddl_high_u8(a: uint8x16_t, b: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Add Long (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2641,7 +2641,7 @@ pub fn vaddl_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t {
     }
     #[doc = "Add Long (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2666,7 +2666,7 @@ pub fn vaddl_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t {
     }
     #[doc = "Add Long (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2691,7 +2691,7 @@ pub fn vaddl_s8(a: int8x8_t, b: int8x8_t) -> int16x8_t {
     }
     #[doc = "Add Long (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2716,7 +2716,7 @@ pub fn vaddl_u16(a: uint16x4_t, b: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Add Long (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2741,7 +2741,7 @@ pub fn vaddl_u32(a: uint32x2_t, b: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Add Long (vector)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddl))]
    @@ -2766,7 +2766,7 @@ pub fn vaddl_u8(a: uint8x8_t, b: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Bitwise exclusive OR"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddq_p128)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -2787,7 +2787,7 @@ pub fn vaddq_p128(a: p128, b: p128) -> p128 {
     }
     #[doc = "Add Wide (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -2812,7 +2812,7 @@ pub fn vaddw_high_s16(a: int32x4_t, b: int16x8_t) -> int32x4_t {
     }
     #[doc = "Add Wide (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -2837,7 +2837,7 @@ pub fn vaddw_high_s32(a: int64x2_t, b: int32x4_t) -> int64x2_t {
     }
     #[doc = "Add Wide (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -2862,7 +2862,7 @@ pub fn vaddw_high_s8(a: int16x8_t, b: int8x16_t) -> int16x8_t {
     }
     #[doc = "Add Wide (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -2887,7 +2887,7 @@ pub fn vaddw_high_u16(a: uint32x4_t, b: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Add Wide (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -2912,7 +2912,7 @@ pub fn vaddw_high_u32(a: uint64x2_t, b: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Add Wide (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -2937,7 +2937,7 @@ pub fn vaddw_high_u8(a: uint16x8_t, b: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Add Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -2961,7 +2961,7 @@ pub fn vaddw_s16(a: int32x4_t, b: int16x4_t) -> int32x4_t {
     }
     #[doc = "Add Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -2985,7 +2985,7 @@ pub fn vaddw_s32(a: int64x2_t, b: int32x2_t) -> int64x2_t {
     }
     #[doc = "Add Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -3009,7 +3009,7 @@ pub fn vaddw_s8(a: int16x8_t, b: int8x8_t) -> int16x8_t {
     }
     #[doc = "Add Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -3033,7 +3033,7 @@ pub fn vaddw_u16(a: uint32x4_t, b: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Add Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -3057,7 +3057,7 @@ pub fn vaddw_u32(a: uint64x2_t, b: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Add Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddw_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vaddw))]
    @@ -3081,7 +3081,7 @@ pub fn vaddw_u8(a: uint16x8_t, b: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "AES single round encryption."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaesdq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(aesd))]
    @@ -3106,7 +3106,7 @@ pub fn vaesdq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "AES single round encryption."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaeseq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(aese))]
    @@ -3131,7 +3131,7 @@ pub fn vaeseq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "AES inverse mix columns."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaesimcq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(aesimc))]
    @@ -3156,7 +3156,7 @@ pub fn vaesimcq_u8(data: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "AES mix columns."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaesmcq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(aesmc))]
    @@ -3181,7 +3181,7 @@ pub fn vaesmcq_u8(data: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3202,7 +3202,7 @@ pub fn vand_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3223,7 +3223,7 @@ pub fn vandq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3244,7 +3244,7 @@ pub fn vand_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3265,7 +3265,7 @@ pub fn vandq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3286,7 +3286,7 @@ pub fn vand_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3307,7 +3307,7 @@ pub fn vandq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3328,7 +3328,7 @@ pub fn vand_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3349,7 +3349,7 @@ pub fn vandq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3370,7 +3370,7 @@ pub fn vand_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3391,7 +3391,7 @@ pub fn vandq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3412,7 +3412,7 @@ pub fn vand_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3433,7 +3433,7 @@ pub fn vandq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3454,7 +3454,7 @@ pub fn vand_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3475,7 +3475,7 @@ pub fn vandq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3496,7 +3496,7 @@ pub fn vand_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Vector bitwise and"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vand))]
    @@ -3517,7 +3517,7 @@ pub fn vandq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbic_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3539,7 +3539,7 @@ pub fn vbic_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbic_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3561,7 +3561,7 @@ pub fn vbic_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbic_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3583,7 +3583,7 @@ pub fn vbic_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbic_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3605,7 +3605,7 @@ pub fn vbic_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbicq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3627,7 +3627,7 @@ pub fn vbicq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbicq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3649,7 +3649,7 @@ pub fn vbicq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbicq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3671,7 +3671,7 @@ pub fn vbicq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbicq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3693,7 +3693,7 @@ pub fn vbicq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbic_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3715,7 +3715,7 @@ pub fn vbic_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbic_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3737,7 +3737,7 @@ pub fn vbic_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbic_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3759,7 +3759,7 @@ pub fn vbic_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbic_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3781,7 +3781,7 @@ pub fn vbic_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbicq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3803,7 +3803,7 @@ pub fn vbicq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbicq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3825,7 +3825,7 @@ pub fn vbicq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbicq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3847,7 +3847,7 @@ pub fn vbicq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector bitwise bit clear."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbicq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbic))]
    @@ -3869,7 +3869,7 @@ pub fn vbicq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -3897,7 +3897,7 @@ pub fn vbsl_f16(a: uint16x4_t, b: float16x4_t, c: float16x4_t) -> float16x4_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -3925,7 +3925,7 @@ pub fn vbslq_f16(a: uint16x8_t, b: float16x8_t, c: float16x8_t) -> float16x8_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -3952,7 +3952,7 @@ pub fn vbsl_f32(a: uint32x2_t, b: float32x2_t, c: float32x2_t) -> float32x2_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -3979,7 +3979,7 @@ pub fn vbsl_p16(a: uint16x4_t, b: poly16x4_t, c: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4006,7 +4006,7 @@ pub fn vbsl_p8(a: uint8x8_t, b: poly8x8_t, c: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4033,7 +4033,7 @@ pub fn vbsl_s16(a: uint16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4060,7 +4060,7 @@ pub fn vbsl_s32(a: uint32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4087,7 +4087,7 @@ pub fn vbsl_s64(a: uint64x1_t, b: int64x1_t, c: int64x1_t) -> int64x1_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4114,7 +4114,7 @@ pub fn vbsl_s8(a: uint8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4141,7 +4141,7 @@ pub fn vbslq_f32(a: uint32x4_t, b: float32x4_t, c: float32x4_t) -> float32x4_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4168,7 +4168,7 @@ pub fn vbslq_p16(a: uint16x8_t, b: poly16x8_t, c: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4195,7 +4195,7 @@ pub fn vbslq_p8(a: uint8x16_t, b: poly8x16_t, c: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4222,7 +4222,7 @@ pub fn vbslq_s16(a: uint16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4249,7 +4249,7 @@ pub fn vbslq_s32(a: uint32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4276,7 +4276,7 @@ pub fn vbslq_s64(a: uint64x2_t, b: int64x2_t, c: int64x2_t) -> int64x2_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4303,7 +4303,7 @@ pub fn vbslq_s8(a: uint8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4330,7 +4330,7 @@ pub fn vbsl_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4357,7 +4357,7 @@ pub fn vbsl_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4384,7 +4384,7 @@ pub fn vbsl_u64(a: uint64x1_t, b: uint64x1_t, c: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbsl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4411,7 +4411,7 @@ pub fn vbsl_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4438,7 +4438,7 @@ pub fn vbslq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4465,7 +4465,7 @@ pub fn vbslq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4492,7 +4492,7 @@ pub fn vbslq_u64(a: uint64x2_t, b: uint64x2_t, c: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Bitwise Select."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbslq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vbsl))]
    @@ -4519,7 +4519,7 @@ pub fn vbslq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Floating-point absolute compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcage_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacge.f16"))]
     #[cfg_attr(
    @@ -4549,7 +4549,7 @@ pub fn vcage_f16(a: float16x4_t, b: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point absolute compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcageq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacge.f16"))]
     #[cfg_attr(
    @@ -4579,7 +4579,7 @@ pub fn vcageq_f16(a: float16x8_t, b: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point absolute compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcage_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacge.f32"))]
    @@ -4608,7 +4608,7 @@ pub fn vcage_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point absolute compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcageq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacge.f32"))]
    @@ -4637,7 +4637,7 @@ pub fn vcageq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point absolute compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagt_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacgt.f16"))]
     #[cfg_attr(
    @@ -4667,7 +4667,7 @@ pub fn vcagt_f16(a: float16x4_t, b: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point absolute compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagtq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacgt.f16"))]
     #[cfg_attr(
    @@ -4697,7 +4697,7 @@ pub fn vcagtq_f16(a: float16x8_t, b: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point absolute compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagt_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacgt.f32"))]
    @@ -4726,7 +4726,7 @@ pub fn vcagt_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point absolute compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcagtq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacgt.f32"))]
    @@ -4755,7 +4755,7 @@ pub fn vcagtq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point absolute compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcale_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacge.f16"))]
     #[cfg_attr(
    @@ -4777,7 +4777,7 @@ pub fn vcale_f16(a: float16x4_t, b: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point absolute compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaleq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacge.f16"))]
     #[cfg_attr(
    @@ -4799,7 +4799,7 @@ pub fn vcaleq_f16(a: float16x8_t, b: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point absolute compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcale_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacge.f32"))]
    @@ -4820,7 +4820,7 @@ pub fn vcale_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point absolute compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaleq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacge.f32"))]
    @@ -4841,7 +4841,7 @@ pub fn vcaleq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point absolute compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcalt_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacgt.f16"))]
     #[cfg_attr(
    @@ -4863,7 +4863,7 @@ pub fn vcalt_f16(a: float16x4_t, b: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point absolute compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaltq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacgt.f16"))]
     #[cfg_attr(
    @@ -4885,7 +4885,7 @@ pub fn vcaltq_f16(a: float16x8_t, b: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point absolute compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcalt_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacgt.f32"))]
    @@ -4906,7 +4906,7 @@ pub fn vcalt_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point absolute compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcaltq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vacgt.f32"))]
    @@ -4927,7 +4927,7 @@ pub fn vcaltq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.f16"))]
     #[cfg_attr(
    @@ -4949,7 +4949,7 @@ pub fn vceq_f16(a: float16x4_t, b: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.f16"))]
     #[cfg_attr(
    @@ -4971,7 +4971,7 @@ pub fn vceqq_f16(a: float16x8_t, b: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point compare equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.f32"))]
    @@ -4992,7 +4992,7 @@ pub fn vceq_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.f32"))]
    @@ -5013,7 +5013,7 @@ pub fn vceqq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i8"))]
    @@ -5034,7 +5034,7 @@ pub fn vceq_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i8"))]
    @@ -5055,7 +5055,7 @@ pub fn vceqq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i16"))]
    @@ -5076,7 +5076,7 @@ pub fn vceq_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i16"))]
    @@ -5097,7 +5097,7 @@ pub fn vceqq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i32"))]
    @@ -5118,7 +5118,7 @@ pub fn vceq_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i32"))]
    @@ -5139,7 +5139,7 @@ pub fn vceqq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i8"))]
    @@ -5160,7 +5160,7 @@ pub fn vceq_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i8"))]
    @@ -5181,7 +5181,7 @@ pub fn vceqq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i16"))]
    @@ -5202,7 +5202,7 @@ pub fn vceq_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i16"))]
    @@ -5223,7 +5223,7 @@ pub fn vceqq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i32"))]
    @@ -5244,7 +5244,7 @@ pub fn vceq_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i32"))]
    @@ -5265,7 +5265,7 @@ pub fn vceqq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i8"))]
    @@ -5286,7 +5286,7 @@ pub fn vceq_p8(a: poly8x8_t, b: poly8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare bitwise Equal (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vceqq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vceq.i8"))]
    @@ -5307,7 +5307,7 @@ pub fn vceqq_p8(a: poly8x16_t, b: poly8x16_t) -> uint8x16_t {
     }
     #[doc = "Floating-point compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f16"))]
     #[cfg_attr(
    @@ -5329,7 +5329,7 @@ pub fn vcge_f16(a: float16x4_t, b: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f16"))]
     #[cfg_attr(
    @@ -5351,7 +5351,7 @@ pub fn vcgeq_f16(a: float16x8_t, b: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f32"))]
    @@ -5372,7 +5372,7 @@ pub fn vcge_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f32"))]
    @@ -5393,7 +5393,7 @@ pub fn vcgeq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare signed greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s8"))]
    @@ -5414,7 +5414,7 @@ pub fn vcge_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare signed greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s8"))]
    @@ -5435,7 +5435,7 @@ pub fn vcgeq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare signed greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s16"))]
    @@ -5456,7 +5456,7 @@ pub fn vcge_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare signed greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s16"))]
    @@ -5477,7 +5477,7 @@ pub fn vcgeq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare signed greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s32"))]
    @@ -5498,7 +5498,7 @@ pub fn vcge_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare signed greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s32"))]
    @@ -5519,7 +5519,7 @@ pub fn vcgeq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare unsigned greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u8"))]
    @@ -5540,7 +5540,7 @@ pub fn vcge_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare unsigned greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u8"))]
    @@ -5561,7 +5561,7 @@ pub fn vcgeq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare unsigned greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u16"))]
    @@ -5582,7 +5582,7 @@ pub fn vcge_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare unsigned greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u16"))]
    @@ -5603,7 +5603,7 @@ pub fn vcgeq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare unsigned greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcge_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u32"))]
    @@ -5624,7 +5624,7 @@ pub fn vcge_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare unsigned greater than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgeq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u32"))]
    @@ -5645,7 +5645,7 @@ pub fn vcgeq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgez_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f16"))]
     #[cfg_attr(
    @@ -5668,7 +5668,7 @@ pub fn vcgez_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare greater than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgezq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f16"))]
     #[cfg_attr(
    @@ -5691,7 +5691,7 @@ pub fn vcgezq_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f16"))]
     #[cfg_attr(
    @@ -5713,7 +5713,7 @@ pub fn vcgt_f16(a: float16x4_t, b: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f16"))]
     #[cfg_attr(
    @@ -5735,7 +5735,7 @@ pub fn vcgtq_f16(a: float16x8_t, b: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f32"))]
    @@ -5756,7 +5756,7 @@ pub fn vcgt_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f32"))]
    @@ -5777,7 +5777,7 @@ pub fn vcgtq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare signed greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s8"))]
    @@ -5798,7 +5798,7 @@ pub fn vcgt_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare signed greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s8"))]
    @@ -5819,7 +5819,7 @@ pub fn vcgtq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare signed greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s16"))]
    @@ -5840,7 +5840,7 @@ pub fn vcgt_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare signed greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s16"))]
    @@ -5861,7 +5861,7 @@ pub fn vcgtq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare signed greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s32"))]
    @@ -5882,7 +5882,7 @@ pub fn vcgt_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare signed greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s32"))]
    @@ -5903,7 +5903,7 @@ pub fn vcgtq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare unsigned greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u8"))]
    @@ -5924,7 +5924,7 @@ pub fn vcgt_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare unsigned greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u8"))]
    @@ -5945,7 +5945,7 @@ pub fn vcgtq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare unsigned greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u16"))]
    @@ -5966,7 +5966,7 @@ pub fn vcgt_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare unsigned greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u16"))]
    @@ -5987,7 +5987,7 @@ pub fn vcgtq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare unsigned greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgt_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u32"))]
    @@ -6008,7 +6008,7 @@ pub fn vcgt_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare unsigned greater than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u32"))]
    @@ -6029,7 +6029,7 @@ pub fn vcgtq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtz_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f16"))]
     #[cfg_attr(
    @@ -6052,7 +6052,7 @@ pub fn vcgtz_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare greater than zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcgtzq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f16"))]
     #[cfg_attr(
    @@ -6075,7 +6075,7 @@ pub fn vcgtzq_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f16"))]
     #[cfg_attr(
    @@ -6097,7 +6097,7 @@ pub fn vcle_f16(a: float16x4_t, b: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f16"))]
     #[cfg_attr(
    @@ -6119,7 +6119,7 @@ pub fn vcleq_f16(a: float16x8_t, b: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f32"))]
    @@ -6140,7 +6140,7 @@ pub fn vcle_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.f32"))]
    @@ -6161,7 +6161,7 @@ pub fn vcleq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare signed less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s8"))]
    @@ -6182,7 +6182,7 @@ pub fn vcle_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare signed less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s8"))]
    @@ -6203,7 +6203,7 @@ pub fn vcleq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare signed less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s16"))]
    @@ -6224,7 +6224,7 @@ pub fn vcle_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare signed less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s16"))]
    @@ -6245,7 +6245,7 @@ pub fn vcleq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare signed less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s32"))]
    @@ -6266,7 +6266,7 @@ pub fn vcle_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare signed less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.s32"))]
    @@ -6287,7 +6287,7 @@ pub fn vcleq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare unsigned less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u8"))]
    @@ -6308,7 +6308,7 @@ pub fn vcle_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare unsigned less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u8"))]
    @@ -6329,7 +6329,7 @@ pub fn vcleq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare unsigned less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u16"))]
    @@ -6350,7 +6350,7 @@ pub fn vcle_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare unsigned less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u16"))]
    @@ -6371,7 +6371,7 @@ pub fn vcleq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare unsigned less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcle_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u32"))]
    @@ -6392,7 +6392,7 @@ pub fn vcle_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare unsigned less than or equal"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcleq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcge.u32"))]
    @@ -6413,7 +6413,7 @@ pub fn vcleq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclez_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcle.f16"))]
     #[cfg_attr(
    @@ -6436,7 +6436,7 @@ pub fn vclez_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare less than or equal to zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclezq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcle.f16"))]
     #[cfg_attr(
    @@ -6459,7 +6459,7 @@ pub fn vclezq_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcls.s8"))]
    @@ -6488,7 +6488,7 @@ pub fn vcls_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcls.s8"))]
    @@ -6517,7 +6517,7 @@ pub fn vclsq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcls.s16"))]
    @@ -6546,7 +6546,7 @@ pub fn vcls_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcls.s16"))]
    @@ -6575,7 +6575,7 @@ pub fn vclsq_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcls.s32"))]
    @@ -6604,7 +6604,7 @@ pub fn vcls_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcls.s32"))]
    @@ -6633,7 +6633,7 @@ pub fn vclsq_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcls))]
    @@ -6654,7 +6654,7 @@ pub fn vcls_u8(a: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcls))]
    @@ -6675,7 +6675,7 @@ pub fn vclsq_u8(a: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcls))]
    @@ -6696,7 +6696,7 @@ pub fn vcls_u16(a: uint16x4_t) -> int16x4_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcls))]
    @@ -6717,7 +6717,7 @@ pub fn vclsq_u16(a: uint16x8_t) -> int16x8_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcls_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcls))]
    @@ -6738,7 +6738,7 @@ pub fn vcls_u32(a: uint32x2_t) -> int32x2_t {
     }
     #[doc = "Count leading sign bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclsq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcls))]
    @@ -6759,7 +6759,7 @@ pub fn vclsq_u32(a: uint32x4_t) -> int32x4_t {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f16"))]
     #[cfg_attr(
    @@ -6781,7 +6781,7 @@ pub fn vclt_f16(a: float16x4_t, b: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f16"))]
     #[cfg_attr(
    @@ -6803,7 +6803,7 @@ pub fn vcltq_f16(a: float16x8_t, b: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f32"))]
    @@ -6824,7 +6824,7 @@ pub fn vclt_f32(a: float32x2_t, b: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.f32"))]
    @@ -6845,7 +6845,7 @@ pub fn vcltq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare signed less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s8"))]
    @@ -6866,7 +6866,7 @@ pub fn vclt_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare signed less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s8"))]
    @@ -6887,7 +6887,7 @@ pub fn vcltq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare signed less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s16"))]
    @@ -6908,7 +6908,7 @@ pub fn vclt_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare signed less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s16"))]
    @@ -6929,7 +6929,7 @@ pub fn vcltq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare signed less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s32"))]
    @@ -6950,7 +6950,7 @@ pub fn vclt_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare signed less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.s32"))]
    @@ -6971,7 +6971,7 @@ pub fn vcltq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Compare unsigned less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u8"))]
    @@ -6992,7 +6992,7 @@ pub fn vclt_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Compare unsigned less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u8"))]
    @@ -7013,7 +7013,7 @@ pub fn vcltq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Compare unsigned less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u16"))]
    @@ -7034,7 +7034,7 @@ pub fn vclt_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Compare unsigned less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u16"))]
    @@ -7055,7 +7055,7 @@ pub fn vcltq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Compare unsigned less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclt_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u32"))]
    @@ -7076,7 +7076,7 @@ pub fn vclt_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Compare unsigned less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcgt.u32"))]
    @@ -7097,7 +7097,7 @@ pub fn vcltq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltz_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vclt.f16"))]
     #[cfg_attr(
    @@ -7120,7 +7120,7 @@ pub fn vcltz_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point compare less than"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcltzq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vclt.f16"))]
     #[cfg_attr(
    @@ -7143,7 +7143,7 @@ pub fn vcltzq_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vclz.i8"))]
    @@ -7164,7 +7164,7 @@ pub fn vclz_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vclz.i8"))]
    @@ -7185,7 +7185,7 @@ pub fn vclzq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vclz.i16"))]
    @@ -7206,7 +7206,7 @@ pub fn vclz_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vclz.i16"))]
    @@ -7227,7 +7227,7 @@ pub fn vclzq_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vclz.i32"))]
    @@ -7248,7 +7248,7 @@ pub fn vclz_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vclz.i32"))]
    @@ -7269,7 +7269,7 @@ pub fn vclzq_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7291,7 +7291,7 @@ pub fn vclz_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7317,7 +7317,7 @@ pub fn vclz_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7339,7 +7339,7 @@ pub fn vclzq_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7365,7 +7365,7 @@ pub fn vclzq_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7387,7 +7387,7 @@ pub fn vclz_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7413,7 +7413,7 @@ pub fn vclz_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7435,7 +7435,7 @@ pub fn vclzq_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7461,7 +7461,7 @@ pub fn vclzq_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7483,7 +7483,7 @@ pub fn vclz_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclz_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7509,7 +7509,7 @@ pub fn vclz_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7531,7 +7531,7 @@ pub fn vclzq_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Count leading zero bits"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vclzq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7562,7 +7562,7 @@ pub fn vclzq_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcnt_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcnt))]
    @@ -7583,7 +7583,7 @@ pub fn vcnt_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcntq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcnt))]
    @@ -7604,7 +7604,7 @@ pub fn vcntq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcnt_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7626,7 +7626,7 @@ pub fn vcnt_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcnt_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7652,7 +7652,7 @@ pub fn vcnt_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcntq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7674,7 +7674,7 @@ pub fn vcntq_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcntq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7705,7 +7705,7 @@ pub fn vcntq_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcnt_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7727,7 +7727,7 @@ pub fn vcnt_p8(a: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcnt_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7753,7 +7753,7 @@ pub fn vcnt_p8(a: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcntq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7775,7 +7775,7 @@ pub fn vcntq_p8(a: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Population count per byte."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcntq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -7806,7 +7806,7 @@ pub fn vcntq_p8(a: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))]
    @@ -7825,7 +7825,7 @@ pub fn vcombine_f16(a: float16x4_t, b: float16x4_t) -> float16x8_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7842,7 +7842,7 @@ pub fn vcombine_f32(a: float32x2_t, b: float32x2_t) -> float32x4_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7859,7 +7859,7 @@ pub fn vcombine_s8(a: int8x8_t, b: int8x8_t) -> int8x16_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7876,7 +7876,7 @@ pub fn vcombine_s16(a: int16x4_t, b: int16x4_t) -> int16x8_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7893,7 +7893,7 @@ pub fn vcombine_s32(a: int32x2_t, b: int32x2_t) -> int32x4_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7910,7 +7910,7 @@ pub fn vcombine_s64(a: int64x1_t, b: int64x1_t) -> int64x2_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7927,7 +7927,7 @@ pub fn vcombine_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x16_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7944,7 +7944,7 @@ pub fn vcombine_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x8_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7961,7 +7961,7 @@ pub fn vcombine_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x4_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7978,7 +7978,7 @@ pub fn vcombine_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x2_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -7995,7 +7995,7 @@ pub fn vcombine_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x16_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -8012,7 +8012,7 @@ pub fn vcombine_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x8_t {
     }
     #[doc = "Join two smaller vectors into a single larger vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -8029,7 +8029,7 @@ pub fn vcombine_p64(a: poly64x1_t, b: poly64x1_t) -> poly64x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8053,7 +8053,7 @@ pub fn vcreate_f16(a: u64) -> float16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8080,7 +8080,7 @@ pub fn vcreate_f16(a: u64) -> float16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8102,7 +8102,7 @@ pub fn vcreate_f32(a: u64) -> float32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8127,7 +8127,7 @@ pub fn vcreate_f32(a: u64) -> float32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8149,7 +8149,7 @@ pub fn vcreate_s8(a: u64) -> int8x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8174,7 +8174,7 @@ pub fn vcreate_s8(a: u64) -> int8x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8196,7 +8196,7 @@ pub fn vcreate_s16(a: u64) -> int16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8221,7 +8221,7 @@ pub fn vcreate_s16(a: u64) -> int16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8243,7 +8243,7 @@ pub fn vcreate_s32(a: u64) -> int32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8268,7 +8268,7 @@ pub fn vcreate_s32(a: u64) -> int32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -8289,7 +8289,7 @@ pub fn vcreate_s64(a: u64) -> int64x1_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8311,7 +8311,7 @@ pub fn vcreate_u8(a: u64) -> uint8x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8336,7 +8336,7 @@ pub fn vcreate_u8(a: u64) -> uint8x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8358,7 +8358,7 @@ pub fn vcreate_u16(a: u64) -> uint16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8383,7 +8383,7 @@ pub fn vcreate_u16(a: u64) -> uint16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8405,7 +8405,7 @@ pub fn vcreate_u32(a: u64) -> uint32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8430,7 +8430,7 @@ pub fn vcreate_u32(a: u64) -> uint32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -8451,7 +8451,7 @@ pub fn vcreate_u64(a: u64) -> uint64x1_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8473,7 +8473,7 @@ pub fn vcreate_p8(a: u64) -> poly8x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8498,7 +8498,7 @@ pub fn vcreate_p8(a: u64) -> poly8x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8520,7 +8520,7 @@ pub fn vcreate_p16(a: u64) -> poly16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -8545,7 +8545,7 @@ pub fn vcreate_p16(a: u64) -> poly16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -8566,7 +8566,7 @@ pub fn vcreate_p64(a: u64) -> poly64x1_t {
     }
     #[doc = "Floating-point convert to lower precision narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -8589,7 +8589,7 @@ pub fn vcvt_f16_f32(a: float32x4_t) -> float16x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
     #[cfg_attr(
    @@ -8611,7 +8611,7 @@ pub fn vcvt_f16_s16(a: int16x4_t) -> float16x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
     #[cfg_attr(
    @@ -8633,7 +8633,7 @@ pub fn vcvtq_f16_s16(a: int16x8_t) -> float16x8_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
     #[cfg_attr(
    @@ -8655,7 +8655,7 @@ pub fn vcvt_f16_u16(a: uint16x4_t) -> float16x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
     #[cfg_attr(
    @@ -8677,7 +8677,7 @@ pub fn vcvtq_f16_u16(a: uint16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point convert to higher precision long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -8700,7 +8700,7 @@ pub fn vcvt_f32_f16(a: float16x4_t) -> float32x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -8721,7 +8721,7 @@ pub fn vcvt_f32_s32(a: int32x2_t) -> float32x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -8742,7 +8742,7 @@ pub fn vcvtq_f32_s32(a: int32x4_t) -> float32x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -8763,7 +8763,7 @@ pub fn vcvt_f32_u32(a: uint32x2_t) -> float32x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -8784,7 +8784,7 @@ pub fn vcvtq_f32_u32(a: uint32x4_t) -> float32x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcvt", N = 1))]
     #[cfg_attr(
    @@ -8819,7 +8819,7 @@ pub fn vcvt_n_f16_s16(a: int16x4_t) -> float16x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcvt", N = 1))]
     #[cfg_attr(
    @@ -8854,7 +8854,7 @@ pub fn vcvtq_n_f16_s16(a: int16x8_t) -> float16x8_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcvt", N = 1))]
     #[cfg_attr(
    @@ -8889,7 +8889,7 @@ pub fn vcvt_n_f16_u16(a: uint16x4_t) -> float16x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcvt", N = 1))]
     #[cfg_attr(
    @@ -8924,7 +8924,7 @@ pub fn vcvtq_n_f16_u16(a: uint16x8_t) -> float16x8_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vcvt, N = 2))]
    @@ -8943,7 +8943,7 @@ pub fn vcvt_n_f32_s32(a: int32x2_t) -> float32x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vcvt, N = 2))]
    @@ -8962,7 +8962,7 @@ pub fn vcvtq_n_f32_s32(a: int32x4_t) -> float32x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(scvtf, N = 2))]
    @@ -8981,7 +8981,7 @@ pub fn vcvt_n_f32_s32(a: int32x2_t) -> float32x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(scvtf, N = 2))]
    @@ -9000,7 +9000,7 @@ pub fn vcvtq_n_f32_s32(a: int32x4_t) -> float32x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vcvt, N = 2))]
    @@ -9019,7 +9019,7 @@ pub fn vcvt_n_f32_u32(a: uint32x2_t) -> float32x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vcvt, N = 2))]
    @@ -9038,7 +9038,7 @@ pub fn vcvtq_n_f32_u32(a: uint32x4_t) -> float32x4_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ucvtf, N = 2))]
    @@ -9057,7 +9057,7 @@ pub fn vcvt_n_f32_u32(a: uint32x2_t) -> float32x2_t {
     }
     #[doc = "Fixed-point convert to floating-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ucvtf, N = 2))]
    @@ -9076,7 +9076,7 @@ pub fn vcvtq_n_f32_u32(a: uint32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point convert to signed fixed-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcvt", N = 1))]
     #[cfg_attr(
    @@ -9111,7 +9111,7 @@ pub fn vcvt_n_s16_f16(a: float16x4_t) -> int16x4_t {
     }
     #[doc = "Floating-point convert to signed fixed-point"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcvt", N = 1))]
     #[cfg_attr(
    @@ -9146,7 +9146,7 @@ pub fn vcvtq_n_s16_f16(a: float16x8_t) -> int16x8_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vcvt, N = 2))]
    @@ -9165,7 +9165,7 @@ pub fn vcvt_n_s32_f32(a: float32x2_t) -> int32x2_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vcvt, N = 2))]
    @@ -9184,7 +9184,7 @@ pub fn vcvtq_n_s32_f32(a: float32x4_t) -> int32x4_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
    @@ -9203,7 +9203,7 @@ pub fn vcvt_n_s32_f32(a: float32x2_t) -> int32x2_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(fcvtzs, N = 2))]
    @@ -9222,7 +9222,7 @@ pub fn vcvtq_n_s32_f32(a: float32x4_t) -> int32x4_t {
     }
     #[doc = "Fixed-point convert to unsigned fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcvt", N = 1))]
     #[cfg_attr(
    @@ -9257,7 +9257,7 @@ pub fn vcvt_n_u16_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Fixed-point convert to unsigned fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vcvt", N = 1))]
     #[cfg_attr(
    @@ -9292,7 +9292,7 @@ pub fn vcvtq_n_u16_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vcvt, N = 2))]
    @@ -9311,7 +9311,7 @@ pub fn vcvt_n_u32_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vcvt, N = 2))]
    @@ -9330,7 +9330,7 @@ pub fn vcvtq_n_u32_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_n_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
    @@ -9349,7 +9349,7 @@ pub fn vcvt_n_u32_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point convert to fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_n_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(fcvtzu, N = 2))]
    @@ -9368,7 +9368,7 @@ pub fn vcvtq_n_u32_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point convert to signed fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
     #[cfg_attr(
    @@ -9390,7 +9390,7 @@ pub fn vcvt_s16_f16(a: float16x4_t) -> int16x4_t {
     }
     #[doc = "Floating-point convert to signed fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
     #[cfg_attr(
    @@ -9412,7 +9412,7 @@ pub fn vcvtq_s16_f16(a: float16x8_t) -> int16x8_t {
     }
     #[doc = "Floating-point convert to signed fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -9441,7 +9441,7 @@ pub fn vcvt_s32_f32(a: float32x2_t) -> int32x2_t {
     }
     #[doc = "Floating-point convert to signed fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -9470,7 +9470,7 @@ pub fn vcvtq_s32_f32(a: float32x4_t) -> int32x4_t {
     }
     #[doc = "Floating-point convert to unsigned fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
     #[cfg_attr(
    @@ -9492,7 +9492,7 @@ pub fn vcvt_u16_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Floating-point convert to unsigned fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
     #[cfg_attr(
    @@ -9514,7 +9514,7 @@ pub fn vcvtq_u16_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Floating-point convert to unsigned fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -9543,7 +9543,7 @@ pub fn vcvt_u32_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Floating-point convert to unsigned fixed-point, rounding toward zero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvtq_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
    @@ -9572,7 +9572,7 @@ pub fn vcvtq_u32_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
    @@ -9600,7 +9600,7 @@ pub fn vdot_lane_s32(a: int32x2_t, b: int8x8_t, c: int8x8_t) ->
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
    @@ -9632,7 +9632,7 @@ pub fn vdot_lane_s32(a: int32x2_t, b: int8x8_t, c: int8x8_t) ->
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
    @@ -9661,7 +9661,7 @@ pub fn vdotq_lane_s32(a: int32x4_t, b: int8x16_t, c: int8x8_t)
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
    @@ -9695,7 +9695,7 @@ pub fn vdotq_lane_s32(a: int32x4_t, b: int8x16_t, c: int8x8_t)
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
    @@ -9723,7 +9723,7 @@ pub fn vdot_lane_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x8_t)
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
    @@ -9755,7 +9755,7 @@ pub fn vdot_lane_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x8_t)
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
    @@ -9784,7 +9784,7 @@ pub fn vdotq_lane_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x8_
     }
     #[doc = "Dot product arithmetic (indexed)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
    @@ -9818,7 +9818,7 @@ pub fn vdotq_lane_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x8_
     }
     #[doc = "Dot product arithmetic (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsdot))]
    @@ -9847,7 +9847,7 @@ pub fn vdot_s32(a: int32x2_t, b: int8x8_t, c: int8x8_t) -> int32x2_t {
     }
     #[doc = "Dot product arithmetic (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsdot))]
    @@ -9876,7 +9876,7 @@ pub fn vdotq_s32(a: int32x4_t, b: int8x16_t, c: int8x16_t) -> int32x4_t {
     }
     #[doc = "Dot product arithmetic (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdot_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vudot))]
    @@ -9905,7 +9905,7 @@ pub fn vdot_u32(a: uint32x2_t, b: uint8x8_t, c: uint8x8_t) -> uint32x2_t {
     }
     #[doc = "Dot product arithmetic (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdotq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,dotprod")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vudot))]
    @@ -9934,7 +9934,7 @@ pub fn vdotq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x16_t) -> uint32x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))]
    @@ -9959,7 +9959,7 @@ pub fn vdup_lane_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))]
    @@ -9990,7 +9990,7 @@ pub fn vdupq_lane_f16(a: float16x4_t) -> float16x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 1))]
    @@ -10013,7 +10013,7 @@ pub fn vdup_lane_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 1))]
    @@ -10036,7 +10036,7 @@ pub fn vdup_lane_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 1))]
    @@ -10059,7 +10059,7 @@ pub fn vdup_lane_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 1))]
    @@ -10082,7 +10082,7 @@ pub fn vdupq_lane_f32(a: float32x2_t) -> float32x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 1))]
    @@ -10105,7 +10105,7 @@ pub fn vdupq_lane_s32(a: int32x2_t) -> int32x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 1))]
    @@ -10128,7 +10128,7 @@ pub fn vdupq_lane_u32(a: uint32x2_t) -> uint32x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))]
    @@ -10151,7 +10151,7 @@ pub fn vdup_lane_p16(a: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))]
    @@ -10174,7 +10174,7 @@ pub fn vdup_lane_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))]
    @@ -10197,7 +10197,7 @@ pub fn vdup_lane_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))]
    @@ -10226,7 +10226,7 @@ pub fn vdupq_lane_p16(a: poly16x4_t) -> poly16x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))]
    @@ -10255,7 +10255,7 @@ pub fn vdupq_lane_s16(a: int16x4_t) -> int16x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))]
    @@ -10284,7 +10284,7 @@ pub fn vdupq_lane_u16(a: uint16x4_t) -> uint16x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 4))]
    @@ -10313,7 +10313,7 @@ pub fn vdup_lane_p8(a: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 4))]
    @@ -10342,7 +10342,7 @@ pub fn vdup_lane_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 4))]
    @@ -10371,7 +10371,7 @@ pub fn vdup_lane_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 4))]
    @@ -10403,7 +10403,7 @@ pub fn vdupq_lane_p8(a: poly8x8_t) -> poly8x16_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 4))]
    @@ -10435,7 +10435,7 @@ pub fn vdupq_lane_s8(a: int8x8_t) -> int8x16_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 4))]
    @@ -10467,7 +10467,7 @@ pub fn vdupq_lane_u8(a: uint8x8_t) -> uint8x16_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, N = 0))]
    @@ -10490,7 +10490,7 @@ pub fn vdup_lane_s64(a: int64x1_t) -> int64x1_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, N = 0))]
    @@ -10513,7 +10513,7 @@ pub fn vdup_lane_u64(a: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))]
    @@ -10538,7 +10538,7 @@ pub fn vdup_laneq_f16(a: float16x8_t) -> float16x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))]
    @@ -10569,7 +10569,7 @@ pub fn vdupq_laneq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 2))]
    @@ -10592,7 +10592,7 @@ pub fn vdup_laneq_f32(a: float32x4_t) -> float32x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 2))]
    @@ -10615,7 +10615,7 @@ pub fn vdup_laneq_s32(a: int32x4_t) -> int32x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 2))]
    @@ -10638,7 +10638,7 @@ pub fn vdup_laneq_u32(a: uint32x4_t) -> uint32x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 2))]
    @@ -10661,7 +10661,7 @@ pub fn vdupq_laneq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 2))]
    @@ -10684,7 +10684,7 @@ pub fn vdupq_laneq_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32", N = 2))]
    @@ -10707,7 +10707,7 @@ pub fn vdupq_laneq_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))]
    @@ -10730,7 +10730,7 @@ pub fn vdup_laneq_p16(a: poly16x8_t) -> poly16x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))]
    @@ -10753,7 +10753,7 @@ pub fn vdup_laneq_s16(a: int16x8_t) -> int16x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))]
    @@ -10776,7 +10776,7 @@ pub fn vdup_laneq_u16(a: uint16x8_t) -> uint16x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))]
    @@ -10805,7 +10805,7 @@ pub fn vdupq_laneq_p16(a: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))]
    @@ -10834,7 +10834,7 @@ pub fn vdupq_laneq_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))]
    @@ -10863,7 +10863,7 @@ pub fn vdupq_laneq_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 8))]
    @@ -10892,7 +10892,7 @@ pub fn vdup_laneq_p8(a: poly8x16_t) -> poly8x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 8))]
    @@ -10921,7 +10921,7 @@ pub fn vdup_laneq_s8(a: int8x16_t) -> int8x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 8))]
    @@ -10950,7 +10950,7 @@ pub fn vdup_laneq_u8(a: uint8x16_t) -> uint8x8_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 8))]
    @@ -10982,7 +10982,7 @@ pub fn vdupq_laneq_p8(a: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 8))]
    @@ -11014,7 +11014,7 @@ pub fn vdupq_laneq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8", N = 8))]
    @@ -11046,7 +11046,7 @@ pub fn vdupq_laneq_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmov, N = 1))]
    @@ -11069,7 +11069,7 @@ pub fn vdup_laneq_s64(a: int64x2_t) -> int64x1_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmov, N = 1))]
    @@ -11092,7 +11092,7 @@ pub fn vdup_laneq_u64(a: uint64x2_t) -> uint64x1_t {
     }
     #[doc = "Create a new vector with all lanes set to a value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -11108,7 +11108,7 @@ pub fn vdup_n_f16(a: f16) -> float16x4_t {
     }
     #[doc = "Create a new vector with all lanes set to a value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -11124,7 +11124,7 @@ pub fn vdupq_n_f16(a: f16) -> float16x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -11145,7 +11145,7 @@ pub fn vdup_n_f32(value: f32) -> float32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -11166,7 +11166,7 @@ pub fn vdup_n_p16(value: p16) -> poly16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -11187,7 +11187,7 @@ pub fn vdup_n_p8(value: p8) -> poly8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -11208,7 +11208,7 @@ pub fn vdup_n_s16(value: i16) -> int16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -11229,7 +11229,7 @@ pub fn vdup_n_s32(value: i32) -> int32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -11250,7 +11250,7 @@ pub fn vdup_n_s64(value: i64) -> int64x1_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -11271,7 +11271,7 @@ pub fn vdup_n_s8(value: i8) -> int8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -11292,7 +11292,7 @@ pub fn vdup_n_u16(value: u16) -> uint16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -11313,7 +11313,7 @@ pub fn vdup_n_u32(value: u32) -> uint32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -11334,7 +11334,7 @@ pub fn vdup_n_u64(value: u64) -> uint64x1_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -11355,7 +11355,7 @@ pub fn vdup_n_u8(value: u8) -> uint8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -11376,7 +11376,7 @@ pub fn vdupq_n_f32(value: f32) -> float32x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -11397,7 +11397,7 @@ pub fn vdupq_n_p16(value: p16) -> poly16x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -11418,7 +11418,7 @@ pub fn vdupq_n_p8(value: p8) -> poly8x16_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -11439,7 +11439,7 @@ pub fn vdupq_n_s16(value: i16) -> int16x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -11460,7 +11460,7 @@ pub fn vdupq_n_s32(value: i32) -> int32x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -11481,7 +11481,7 @@ pub fn vdupq_n_s64(value: i64) -> int64x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -11502,7 +11502,7 @@ pub fn vdupq_n_s8(value: i8) -> int8x16_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -11523,7 +11523,7 @@ pub fn vdupq_n_u16(value: u16) -> uint16x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -11544,7 +11544,7 @@ pub fn vdupq_n_u32(value: u32) -> uint32x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -11565,7 +11565,7 @@ pub fn vdupq_n_u64(value: u64) -> uint64x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -11586,7 +11586,7 @@ pub fn vdupq_n_u8(value: u8) -> uint8x16_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_f32_vfp4)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -11607,7 +11607,7 @@ fn vdup_n_f32_vfp4(value: f32) -> float32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_f32_vfp4)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -11628,7 +11628,7 @@ fn vdupq_n_f32_vfp4(value: f32) -> float32x4_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmov, N = 0))]
    @@ -11651,7 +11651,7 @@ pub fn vdupq_lane_s64(a: int64x1_t) -> int64x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmov, N = 0))]
    @@ -11674,7 +11674,7 @@ pub fn vdupq_lane_u64(a: uint64x1_t) -> uint64x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmov, N = 1))]
    @@ -11697,7 +11697,7 @@ pub fn vdupq_laneq_s64(a: int64x2_t) -> int64x2_t {
     }
     #[doc = "Set all vector lanes to the same value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmov, N = 1))]
    @@ -11720,7 +11720,7 @@ pub fn vdupq_laneq_u64(a: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11741,7 +11741,7 @@ pub fn veor_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11762,7 +11762,7 @@ pub fn veorq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11783,7 +11783,7 @@ pub fn veor_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11804,7 +11804,7 @@ pub fn veorq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11825,7 +11825,7 @@ pub fn veor_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11846,7 +11846,7 @@ pub fn veorq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11867,7 +11867,7 @@ pub fn veor_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11888,7 +11888,7 @@ pub fn veorq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11909,7 +11909,7 @@ pub fn veor_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11930,7 +11930,7 @@ pub fn veorq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11951,7 +11951,7 @@ pub fn veor_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11972,7 +11972,7 @@ pub fn veorq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -11993,7 +11993,7 @@ pub fn veor_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -12014,7 +12014,7 @@ pub fn veorq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -12035,7 +12035,7 @@ pub fn veor_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Vector bitwise exclusive or (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(veor))]
    @@ -12056,7 +12056,7 @@ pub fn veorq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
     #[cfg_attr(
    @@ -12088,7 +12088,7 @@ pub fn vext_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 1))]
    @@ -12117,7 +12117,7 @@ pub fn vext_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 1))]
    @@ -12146,7 +12146,7 @@ pub fn vext_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 1))]
    @@ -12177,7 +12177,7 @@ pub fn vext_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, N = 0))]
    @@ -12202,7 +12202,7 @@ pub unsafe fn vext_s64(a: int64x1_t, _b: int64x1_t) -> int64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, N = 0))]
    @@ -12225,7 +12225,7 @@ pub unsafe fn vext_u64(a: uint64x1_t, _b: uint64x1_t) -> uint64x1_
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
    @@ -12260,7 +12260,7 @@ pub fn vext_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
    @@ -12295,7 +12295,7 @@ pub fn vextq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
    @@ -12330,7 +12330,7 @@ pub fn vext_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
    @@ -12365,7 +12365,7 @@ pub fn vextq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
    @@ -12400,7 +12400,7 @@ pub fn vext_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
    @@ -12435,7 +12435,7 @@ pub fn vextq_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 7))]
     #[cfg_attr(
    @@ -12471,7 +12471,7 @@ pub fn vextq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
    @@ -12502,7 +12502,7 @@ pub fn vextq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
    @@ -12533,7 +12533,7 @@ pub fn vext_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
    @@ -12564,7 +12564,7 @@ pub fn vextq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
    @@ -12595,7 +12595,7 @@ pub fn vext_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
    @@ -12626,7 +12626,7 @@ pub fn vextq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vext_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 3))]
    @@ -12657,7 +12657,7 @@ pub fn vext_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmov, N = 1))]
    @@ -12686,7 +12686,7 @@ pub fn vextq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmov, N = 1))]
    @@ -12715,7 +12715,7 @@ pub fn vextq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 15))]
    @@ -12818,7 +12818,7 @@ pub fn vextq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 15))]
    @@ -12921,7 +12921,7 @@ pub fn vextq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Extract vector from pair of vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vextq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vext.8", N = 15))]
    @@ -13024,7 +13024,7 @@ pub fn vextq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfma))]
     #[cfg_attr(
    @@ -13046,7 +13046,7 @@ pub fn vfma_f16(a: float16x4_t, b: float16x4_t, c: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfma))]
     #[cfg_attr(
    @@ -13068,7 +13068,7 @@ pub fn vfmaq_f16(a: float16x8_t, b: float16x8_t, c: float16x8_t) -> float16x8_t
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfma))]
    @@ -13089,7 +13089,7 @@ pub fn vfma_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfma))]
    @@ -13110,7 +13110,7 @@ pub fn vfmaq_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> float32x4_t
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfma_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfma))]
    @@ -13131,7 +13131,7 @@ pub fn vfma_n_f32(a: float32x2_t, b: float32x2_t, c: f32) -> float32x2_t {
     }
     #[doc = "Floating-point fused Multiply-Add to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmaq_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfma))]
    @@ -13152,7 +13152,7 @@ pub fn vfmaq_n_f32(a: float32x4_t, b: float32x4_t, c: f32) -> float32x4_t {
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -13178,7 +13178,7 @@ pub fn vfms_f16(a: float16x4_t, b: float16x4_t, c: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -13204,7 +13204,7 @@ pub fn vfmsq_f16(a: float16x8_t, b: float16x8_t, c: float16x8_t) -> float16x8_t
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfms))]
    @@ -13228,7 +13228,7 @@ pub fn vfms_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point fused multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfms))]
    @@ -13252,7 +13252,7 @@ pub fn vfmsq_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> float32x4_t
     }
     #[doc = "Floating-point fused Multiply-subtract to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfms_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfms))]
    @@ -13273,7 +13273,7 @@ pub fn vfms_n_f32(a: float32x2_t, b: float32x2_t, c: f32) -> float32x2_t {
     }
     #[doc = "Floating-point fused Multiply-subtract to accumulator(vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmsq_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "vfp4"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vfms))]
    @@ -13294,7 +13294,7 @@ pub fn vfmsq_n_f32(a: float32x4_t, b: float32x4_t, c: f32) -> float32x4_t {
     }
     #[doc = "Duplicate vector element to vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))]
    @@ -13313,7 +13313,7 @@ pub fn vget_high_f16(a: float16x8_t) -> float16x4_t {
     }
     #[doc = "Duplicate vector element to vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))]
    @@ -13332,7 +13332,7 @@ pub fn vget_low_f16(a: float16x8_t) -> float16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13353,7 +13353,7 @@ pub fn vget_high_f32(a: float32x4_t) -> float32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13374,7 +13374,7 @@ pub fn vget_high_p16(a: poly16x8_t) -> poly16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13395,7 +13395,7 @@ pub fn vget_high_p8(a: poly8x16_t) -> poly8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13416,7 +13416,7 @@ pub fn vget_high_s16(a: int16x8_t) -> int16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13437,7 +13437,7 @@ pub fn vget_high_s32(a: int32x4_t) -> int32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13458,7 +13458,7 @@ pub fn vget_high_s8(a: int8x16_t) -> int8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13479,7 +13479,7 @@ pub fn vget_high_u16(a: uint16x8_t) -> uint16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13500,7 +13500,7 @@ pub fn vget_high_u32(a: uint32x4_t) -> uint32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13521,7 +13521,7 @@ pub fn vget_high_u8(a: uint8x16_t) -> uint8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13542,7 +13542,7 @@ pub fn vget_high_s64(a: int64x2_t) -> int64x1_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -13563,7 +13563,7 @@ pub fn vget_high_u64(a: uint64x2_t) -> uint64x1_t {
     }
     #[doc = "Duplicate vector element to scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -13581,7 +13581,7 @@ pub fn vget_lane_f16(a: float16x4_t) -> f16 {
     }
     #[doc = "Duplicate vector element to scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -13599,7 +13599,7 @@ pub fn vgetq_lane_f16(a: float16x8_t) -> f16 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13618,7 +13618,7 @@ pub fn vget_lane_f32(v: float32x2_t) -> f32 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13637,7 +13637,7 @@ pub fn vget_lane_p16(v: poly16x4_t) -> p16 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13656,7 +13656,7 @@ pub fn vget_lane_p8(v: poly8x8_t) -> p8 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13675,7 +13675,7 @@ pub fn vget_lane_s16(v: int16x4_t) -> i16 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13694,7 +13694,7 @@ pub fn vget_lane_s32(v: int32x2_t) -> i32 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13713,7 +13713,7 @@ pub fn vget_lane_s8(v: int8x8_t) -> i8 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13732,7 +13732,7 @@ pub fn vget_lane_u16(v: uint16x4_t) -> u16 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13751,7 +13751,7 @@ pub fn vget_lane_u32(v: uint32x2_t) -> u32 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13770,7 +13770,7 @@ pub fn vget_lane_u8(v: uint8x8_t) -> u8 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13789,7 +13789,7 @@ pub fn vgetq_lane_f32(v: float32x4_t) -> f32 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13808,7 +13808,7 @@ pub fn vgetq_lane_p16(v: poly16x8_t) -> p16 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13827,7 +13827,7 @@ pub fn vgetq_lane_p64(v: poly64x2_t) -> p64 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13846,7 +13846,7 @@ pub fn vgetq_lane_p8(v: poly8x16_t) -> p8 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13865,7 +13865,7 @@ pub fn vgetq_lane_s16(v: int16x8_t) -> i16 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13884,7 +13884,7 @@ pub fn vgetq_lane_s32(v: int32x4_t) -> i32 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13903,7 +13903,7 @@ pub fn vgetq_lane_s64(v: int64x2_t) -> i64 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13922,7 +13922,7 @@ pub fn vgetq_lane_s8(v: int8x16_t) -> i8 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13941,7 +13941,7 @@ pub fn vgetq_lane_u16(v: uint16x8_t) -> u16 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13960,7 +13960,7 @@ pub fn vgetq_lane_u32(v: uint32x4_t) -> u32 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13979,7 +13979,7 @@ pub fn vgetq_lane_u64(v: uint64x2_t) -> u64 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -13998,7 +13998,7 @@ pub fn vgetq_lane_u8(v: uint8x16_t) -> u8 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -14017,7 +14017,7 @@ pub fn vget_lane_p64(v: poly64x1_t) -> p64 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -14036,7 +14036,7 @@ pub fn vget_lane_s64(v: int64x1_t) -> i64 {
     }
     #[doc = "Move vector element to general-purpose register"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(1)]
    @@ -14055,7 +14055,7 @@ pub fn vget_lane_u64(v: uint64x1_t) -> u64 {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14072,7 +14072,7 @@ pub fn vget_low_f32(a: float32x4_t) -> float32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14089,7 +14089,7 @@ pub fn vget_low_p16(a: poly16x8_t) -> poly16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14106,7 +14106,7 @@ pub fn vget_low_p8(a: poly8x16_t) -> poly8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14123,7 +14123,7 @@ pub fn vget_low_s16(a: int16x8_t) -> int16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14140,7 +14140,7 @@ pub fn vget_low_s32(a: int32x4_t) -> int32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14157,7 +14157,7 @@ pub fn vget_low_s8(a: int8x16_t) -> int8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14174,7 +14174,7 @@ pub fn vget_low_u16(a: uint16x8_t) -> uint16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14191,7 +14191,7 @@ pub fn vget_low_u32(a: uint32x4_t) -> uint32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14208,7 +14208,7 @@ pub fn vget_low_u8(a: uint8x16_t) -> uint8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14225,7 +14225,7 @@ pub fn vget_low_s64(a: int64x2_t) -> int64x1_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -14242,7 +14242,7 @@ pub fn vget_low_u64(a: uint64x2_t) -> uint64x1_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.s8"))]
    @@ -14271,7 +14271,7 @@ pub fn vhadd_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.s8"))]
    @@ -14300,7 +14300,7 @@ pub fn vhaddq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.s16"))]
    @@ -14329,7 +14329,7 @@ pub fn vhadd_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.s16"))]
    @@ -14358,7 +14358,7 @@ pub fn vhaddq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.s32"))]
    @@ -14387,7 +14387,7 @@ pub fn vhadd_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.s32"))]
    @@ -14416,7 +14416,7 @@ pub fn vhaddq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.u8"))]
    @@ -14445,7 +14445,7 @@ pub fn vhadd_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.u8"))]
    @@ -14474,7 +14474,7 @@ pub fn vhaddq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.u16"))]
    @@ -14503,7 +14503,7 @@ pub fn vhadd_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.u16"))]
    @@ -14532,7 +14532,7 @@ pub fn vhaddq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhadd_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.u32"))]
    @@ -14561,7 +14561,7 @@ pub fn vhadd_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhaddq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhadd.u32"))]
    @@ -14590,7 +14590,7 @@ pub fn vhaddq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.s16"))]
    @@ -14619,7 +14619,7 @@ pub fn vhsub_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.s16"))]
    @@ -14648,7 +14648,7 @@ pub fn vhsubq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.s32"))]
    @@ -14677,7 +14677,7 @@ pub fn vhsub_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.s32"))]
    @@ -14706,7 +14706,7 @@ pub fn vhsubq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.s8"))]
    @@ -14735,7 +14735,7 @@ pub fn vhsub_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.s8"))]
    @@ -14764,7 +14764,7 @@ pub fn vhsubq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.u8"))]
    @@ -14793,7 +14793,7 @@ pub fn vhsub_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.u8"))]
    @@ -14822,7 +14822,7 @@ pub fn vhsubq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.u16"))]
    @@ -14851,7 +14851,7 @@ pub fn vhsub_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.u16"))]
    @@ -14880,7 +14880,7 @@ pub fn vhsubq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsub_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.u32"))]
    @@ -14909,7 +14909,7 @@ pub fn vhsub_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Signed halving subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vhsubq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vhsub.u32"))]
    @@ -14940,7 +14940,7 @@ pub fn vhsubq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -14959,7 +14959,7 @@ pub unsafe fn vld1_dup_f16(ptr: *const f16) -> float16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -14978,7 +14978,7 @@ pub unsafe fn vld1q_dup_f16(ptr: *const f16) -> float16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))]
    @@ -15001,7 +15001,7 @@ pub unsafe fn vld1_dup_f32(ptr: *const f32) -> float32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))]
    @@ -15024,7 +15024,7 @@ pub unsafe fn vld1_dup_p16(ptr: *const p16) -> poly16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))]
    @@ -15047,7 +15047,7 @@ pub unsafe fn vld1_dup_p8(ptr: *const p8) -> poly8x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))]
    @@ -15070,7 +15070,7 @@ pub unsafe fn vld1_dup_s16(ptr: *const i16) -> int16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))]
    @@ -15093,7 +15093,7 @@ pub unsafe fn vld1_dup_s32(ptr: *const i32) -> int32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))]
    @@ -15116,7 +15116,7 @@ pub unsafe fn vld1_dup_s8(ptr: *const i8) -> int8x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))]
    @@ -15139,7 +15139,7 @@ pub unsafe fn vld1_dup_u16(ptr: *const u16) -> uint16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))]
    @@ -15162,7 +15162,7 @@ pub unsafe fn vld1_dup_u32(ptr: *const u32) -> uint32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))]
    @@ -15185,7 +15185,7 @@ pub unsafe fn vld1_dup_u8(ptr: *const u8) -> uint8x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))]
    @@ -15208,7 +15208,7 @@ pub unsafe fn vld1q_dup_f32(ptr: *const f32) -> float32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))]
    @@ -15231,7 +15231,7 @@ pub unsafe fn vld1q_dup_p16(ptr: *const p16) -> poly16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))]
    @@ -15254,7 +15254,7 @@ pub unsafe fn vld1q_dup_p8(ptr: *const p8) -> poly8x16_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))]
    @@ -15277,7 +15277,7 @@ pub unsafe fn vld1q_dup_s16(ptr: *const i16) -> int16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))]
    @@ -15300,7 +15300,7 @@ pub unsafe fn vld1q_dup_s32(ptr: *const i32) -> int32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vldr"))]
    @@ -15323,7 +15323,7 @@ pub unsafe fn vld1q_dup_s64(ptr: *const i64) -> int64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))]
    @@ -15346,7 +15346,7 @@ pub unsafe fn vld1q_dup_s8(ptr: *const i8) -> int8x16_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.16"))]
    @@ -15369,7 +15369,7 @@ pub unsafe fn vld1q_dup_u16(ptr: *const u16) -> uint16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.32"))]
    @@ -15392,7 +15392,7 @@ pub unsafe fn vld1q_dup_u32(ptr: *const u32) -> uint32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vldr"))]
    @@ -15415,7 +15415,7 @@ pub unsafe fn vld1q_dup_u64(ptr: *const u64) -> uint64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vld1.8"))]
    @@ -15438,7 +15438,7 @@ pub unsafe fn vld1q_dup_u8(ptr: *const u8) -> uint8x16_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))]
    @@ -15470,7 +15470,7 @@ pub unsafe fn vld1_dup_p64(ptr: *const p64) -> poly64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))]
    @@ -15502,7 +15502,7 @@ pub unsafe fn vld1_dup_s64(ptr: *const i64) -> int64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))]
    @@ -15534,7 +15534,7 @@ pub unsafe fn vld1_dup_u64(ptr: *const u64) -> uint64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -15552,7 +15552,7 @@ pub unsafe fn vld1_f16(ptr: *const f16) -> float16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -15571,7 +15571,7 @@ pub unsafe fn vld1_f16(ptr: *const f16) -> float16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -15589,7 +15589,7 @@ pub unsafe fn vld1q_f16(ptr: *const f16) -> float16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -15608,7 +15608,7 @@ pub unsafe fn vld1q_f16(ptr: *const f16) -> float16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -15634,7 +15634,7 @@ pub unsafe fn vld1_f16_x2(a: *const f16) -> float16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -15660,7 +15660,7 @@ pub unsafe fn vld1_f16_x3(a: *const f16) -> float16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -15686,7 +15686,7 @@ pub unsafe fn vld1_f16_x4(a: *const f16) -> float16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -15712,7 +15712,7 @@ pub unsafe fn vld1q_f16_x2(a: *const f16) -> float16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -15738,7 +15738,7 @@ pub unsafe fn vld1q_f16_x3(a: *const f16) -> float16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -15764,7 +15764,7 @@ pub unsafe fn vld1q_f16_x4(a: *const f16) -> float16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15777,7 +15777,7 @@ pub unsafe fn vld1_f32(ptr: *const f32) -> float32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15790,7 +15790,7 @@ pub unsafe fn vld1q_f32(ptr: *const f32) -> float32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15803,7 +15803,7 @@ pub unsafe fn vld1_u8(ptr: *const u8) -> uint8x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15816,7 +15816,7 @@ pub unsafe fn vld1q_u8(ptr: *const u8) -> uint8x16_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15829,7 +15829,7 @@ pub unsafe fn vld1_u16(ptr: *const u16) -> uint16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15842,7 +15842,7 @@ pub unsafe fn vld1q_u16(ptr: *const u16) -> uint16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15855,7 +15855,7 @@ pub unsafe fn vld1_u32(ptr: *const u32) -> uint32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15868,7 +15868,7 @@ pub unsafe fn vld1q_u32(ptr: *const u32) -> uint32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15881,7 +15881,7 @@ pub unsafe fn vld1_u64(ptr: *const u64) -> uint64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15894,7 +15894,7 @@ pub unsafe fn vld1q_u64(ptr: *const u64) -> uint64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15907,7 +15907,7 @@ pub unsafe fn vld1_p8(ptr: *const p8) -> poly8x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15920,7 +15920,7 @@ pub unsafe fn vld1q_p8(ptr: *const p8) -> poly8x16_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15933,7 +15933,7 @@ pub unsafe fn vld1_p16(ptr: *const p16) -> poly16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15946,7 +15946,7 @@ pub unsafe fn vld1q_p16(ptr: *const p16) -> poly16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,aes")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -15959,7 +15959,7 @@ pub unsafe fn vld1q_p64(ptr: *const p64) -> poly64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -15990,7 +15990,7 @@ pub unsafe fn vld1_f32_x2(a: *const f32) -> float32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -16021,7 +16021,7 @@ pub unsafe fn vld1_f32_x3(a: *const f32) -> float32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_f32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -16052,7 +16052,7 @@ pub unsafe fn vld1_f32_x4(a: *const f32) -> float32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -16083,7 +16083,7 @@ pub unsafe fn vld1q_f32_x2(a: *const f32) -> float32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -16114,7 +16114,7 @@ pub unsafe fn vld1q_f32_x3(a: *const f32) -> float32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_f32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -16145,7 +16145,7 @@ pub unsafe fn vld1q_f32_x4(a: *const f32) -> float32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1, LANE = 0))]
    @@ -16165,7 +16165,7 @@ pub unsafe fn vld1_lane_f16(ptr: *const f16, src: float16x4_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1, LANE = 0))]
    @@ -16185,7 +16185,7 @@ pub unsafe fn vld1q_lane_f16(ptr: *const f16, src: float16x8_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16210,7 +16210,7 @@ pub unsafe fn vld1_lane_f32(ptr: *const f32, src: float32x2_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16235,7 +16235,7 @@ pub unsafe fn vld1_lane_p16(ptr: *const p16, src: poly16x4_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16260,7 +16260,7 @@ pub unsafe fn vld1_lane_p8(ptr: *const p8, src: poly8x8_t) -> p
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16285,7 +16285,7 @@ pub unsafe fn vld1_lane_s16(ptr: *const i16, src: int16x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16310,7 +16310,7 @@ pub unsafe fn vld1_lane_s32(ptr: *const i32, src: int32x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16335,7 +16335,7 @@ pub unsafe fn vld1_lane_s64(ptr: *const i64, src: int64x1_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16360,7 +16360,7 @@ pub unsafe fn vld1_lane_s8(ptr: *const i8, src: int8x8_t) -> in
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16385,7 +16385,7 @@ pub unsafe fn vld1_lane_u16(ptr: *const u16, src: uint16x4_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16410,7 +16410,7 @@ pub unsafe fn vld1_lane_u32(ptr: *const u32, src: uint32x2_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16435,7 +16435,7 @@ pub unsafe fn vld1_lane_u64(ptr: *const u64, src: uint64x1_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16460,7 +16460,7 @@ pub unsafe fn vld1_lane_u8(ptr: *const u8, src: uint8x8_t) -> u
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16485,7 +16485,7 @@ pub unsafe fn vld1q_lane_f32(ptr: *const f32, src: float32x4_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16510,7 +16510,7 @@ pub unsafe fn vld1q_lane_p16(ptr: *const p16, src: poly16x8_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16535,7 +16535,7 @@ pub unsafe fn vld1q_lane_p8(ptr: *const p8, src: poly8x16_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16560,7 +16560,7 @@ pub unsafe fn vld1q_lane_s16(ptr: *const i16, src: int16x8_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16585,7 +16585,7 @@ pub unsafe fn vld1q_lane_s32(ptr: *const i32, src: int32x4_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16610,7 +16610,7 @@ pub unsafe fn vld1q_lane_s64(ptr: *const i64, src: int64x2_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16635,7 +16635,7 @@ pub unsafe fn vld1q_lane_s8(ptr: *const i8, src: int8x16_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16660,7 +16660,7 @@ pub unsafe fn vld1q_lane_u16(ptr: *const u16, src: uint16x8_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16685,7 +16685,7 @@ pub unsafe fn vld1q_lane_u32(ptr: *const u32, src: uint32x4_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16710,7 +16710,7 @@ pub unsafe fn vld1q_lane_u64(ptr: *const u64, src: uint64x2_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16735,7 +16735,7 @@ pub unsafe fn vld1q_lane_u8(ptr: *const u8, src: uint8x16_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16760,7 +16760,7 @@ pub unsafe fn vld1_lane_p64(ptr: *const p64, src: poly64x1_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[rustc_legacy_const_generics(2)]
    @@ -16785,7 +16785,7 @@ pub unsafe fn vld1q_lane_p64(ptr: *const p64, src: poly64x2_t)
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,aes")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -16803,7 +16803,7 @@ pub unsafe fn vld1_p64(ptr: *const p64) -> poly64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -16826,7 +16826,7 @@ pub unsafe fn vld1_p64_x2(a: *const p64) -> poly64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -16849,7 +16849,7 @@ pub unsafe fn vld1_p64_x3(a: *const p64) -> poly64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -16872,7 +16872,7 @@ pub unsafe fn vld1_p64_x4(a: *const p64) -> poly64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -16896,7 +16896,7 @@ pub unsafe fn vld1q_p64_x2(a: *const p64) -> poly64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -16923,7 +16923,7 @@ pub unsafe fn vld1q_p64_x2(a: *const p64) -> poly64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -16947,7 +16947,7 @@ pub unsafe fn vld1q_p64_x3(a: *const p64) -> poly64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -16975,7 +16975,7 @@ pub unsafe fn vld1q_p64_x3(a: *const p64) -> poly64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -16999,7 +16999,7 @@ pub unsafe fn vld1q_p64_x4(a: *const p64) -> poly64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -17028,7 +17028,7 @@ pub unsafe fn vld1q_p64_x4(a: *const p64) -> poly64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -17041,7 +17041,7 @@ pub unsafe fn vld1_s8(ptr: *const i8) -> int8x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -17054,7 +17054,7 @@ pub unsafe fn vld1q_s8(ptr: *const i8) -> int8x16_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -17067,7 +17067,7 @@ pub unsafe fn vld1_s16(ptr: *const i16) -> int16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -17080,7 +17080,7 @@ pub unsafe fn vld1q_s16(ptr: *const i16) -> int16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -17093,7 +17093,7 @@ pub unsafe fn vld1_s32(ptr: *const i32) -> int32x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -17106,7 +17106,7 @@ pub unsafe fn vld1q_s32(ptr: *const i32) -> int32x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -17119,7 +17119,7 @@ pub unsafe fn vld1_s64(ptr: *const i64) -> int64x1_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -17132,7 +17132,7 @@ pub unsafe fn vld1q_s64(ptr: *const i64) -> int64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17163,7 +17163,7 @@ pub unsafe fn vld1_s8_x2(a: *const i8) -> int8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17194,7 +17194,7 @@ pub unsafe fn vld1_s8_x3(a: *const i8) -> int8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17225,7 +17225,7 @@ pub unsafe fn vld1_s8_x4(a: *const i8) -> int8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17256,7 +17256,7 @@ pub unsafe fn vld1q_s8_x2(a: *const i8) -> int8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17287,7 +17287,7 @@ pub unsafe fn vld1q_s8_x3(a: *const i8) -> int8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17318,7 +17318,7 @@ pub unsafe fn vld1q_s8_x4(a: *const i8) -> int8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17349,7 +17349,7 @@ pub unsafe fn vld1_s16_x2(a: *const i16) -> int16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17380,7 +17380,7 @@ pub unsafe fn vld1_s16_x3(a: *const i16) -> int16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17411,7 +17411,7 @@ pub unsafe fn vld1_s16_x4(a: *const i16) -> int16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17442,7 +17442,7 @@ pub unsafe fn vld1q_s16_x2(a: *const i16) -> int16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17473,7 +17473,7 @@ pub unsafe fn vld1q_s16_x3(a: *const i16) -> int16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17504,7 +17504,7 @@ pub unsafe fn vld1q_s16_x4(a: *const i16) -> int16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17535,7 +17535,7 @@ pub unsafe fn vld1_s32_x2(a: *const i32) -> int32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17566,7 +17566,7 @@ pub unsafe fn vld1_s32_x3(a: *const i32) -> int32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17597,7 +17597,7 @@ pub unsafe fn vld1_s32_x4(a: *const i32) -> int32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17628,7 +17628,7 @@ pub unsafe fn vld1q_s32_x2(a: *const i32) -> int32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17659,7 +17659,7 @@ pub unsafe fn vld1q_s32_x3(a: *const i32) -> int32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17690,7 +17690,7 @@ pub unsafe fn vld1q_s32_x4(a: *const i32) -> int32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17721,7 +17721,7 @@ pub unsafe fn vld1_s64_x2(a: *const i64) -> int64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17752,7 +17752,7 @@ pub unsafe fn vld1_s64_x3(a: *const i64) -> int64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_s64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17783,7 +17783,7 @@ pub unsafe fn vld1_s64_x4(a: *const i64) -> int64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17814,7 +17814,7 @@ pub unsafe fn vld1q_s64_x2(a: *const i64) -> int64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17845,7 +17845,7 @@ pub unsafe fn vld1q_s64_x3(a: *const i64) -> int64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_s64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -17876,7 +17876,7 @@ pub unsafe fn vld1q_s64_x4(a: *const i64) -> int64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -17900,7 +17900,7 @@ pub unsafe fn vld1_u8_x2(a: *const u8) -> uint8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -17927,7 +17927,7 @@ pub unsafe fn vld1_u8_x2(a: *const u8) -> uint8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -17951,7 +17951,7 @@ pub unsafe fn vld1_u8_x3(a: *const u8) -> uint8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -17979,7 +17979,7 @@ pub unsafe fn vld1_u8_x3(a: *const u8) -> uint8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18003,7 +18003,7 @@ pub unsafe fn vld1_u8_x4(a: *const u8) -> uint8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18032,7 +18032,7 @@ pub unsafe fn vld1_u8_x4(a: *const u8) -> uint8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18056,7 +18056,7 @@ pub unsafe fn vld1q_u8_x2(a: *const u8) -> uint8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18095,7 +18095,7 @@ pub unsafe fn vld1q_u8_x2(a: *const u8) -> uint8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18119,7 +18119,7 @@ pub unsafe fn vld1q_u8_x3(a: *const u8) -> uint8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18165,7 +18165,7 @@ pub unsafe fn vld1q_u8_x3(a: *const u8) -> uint8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18189,7 +18189,7 @@ pub unsafe fn vld1q_u8_x4(a: *const u8) -> uint8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18242,7 +18242,7 @@ pub unsafe fn vld1q_u8_x4(a: *const u8) -> uint8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18266,7 +18266,7 @@ pub unsafe fn vld1_u16_x2(a: *const u16) -> uint16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18293,7 +18293,7 @@ pub unsafe fn vld1_u16_x2(a: *const u16) -> uint16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18317,7 +18317,7 @@ pub unsafe fn vld1_u16_x3(a: *const u16) -> uint16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18345,7 +18345,7 @@ pub unsafe fn vld1_u16_x3(a: *const u16) -> uint16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18369,7 +18369,7 @@ pub unsafe fn vld1_u16_x4(a: *const u16) -> uint16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18398,7 +18398,7 @@ pub unsafe fn vld1_u16_x4(a: *const u16) -> uint16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18422,7 +18422,7 @@ pub unsafe fn vld1q_u16_x2(a: *const u16) -> uint16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18449,7 +18449,7 @@ pub unsafe fn vld1q_u16_x2(a: *const u16) -> uint16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18473,7 +18473,7 @@ pub unsafe fn vld1q_u16_x3(a: *const u16) -> uint16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18501,7 +18501,7 @@ pub unsafe fn vld1q_u16_x3(a: *const u16) -> uint16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18525,7 +18525,7 @@ pub unsafe fn vld1q_u16_x4(a: *const u16) -> uint16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18554,7 +18554,7 @@ pub unsafe fn vld1q_u16_x4(a: *const u16) -> uint16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18578,7 +18578,7 @@ pub unsafe fn vld1_u32_x2(a: *const u32) -> uint32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18605,7 +18605,7 @@ pub unsafe fn vld1_u32_x2(a: *const u32) -> uint32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18629,7 +18629,7 @@ pub unsafe fn vld1_u32_x3(a: *const u32) -> uint32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18657,7 +18657,7 @@ pub unsafe fn vld1_u32_x3(a: *const u32) -> uint32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18681,7 +18681,7 @@ pub unsafe fn vld1_u32_x4(a: *const u32) -> uint32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18710,7 +18710,7 @@ pub unsafe fn vld1_u32_x4(a: *const u32) -> uint32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18734,7 +18734,7 @@ pub unsafe fn vld1q_u32_x2(a: *const u32) -> uint32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18761,7 +18761,7 @@ pub unsafe fn vld1q_u32_x2(a: *const u32) -> uint32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18785,7 +18785,7 @@ pub unsafe fn vld1q_u32_x3(a: *const u32) -> uint32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18813,7 +18813,7 @@ pub unsafe fn vld1q_u32_x3(a: *const u32) -> uint32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18837,7 +18837,7 @@ pub unsafe fn vld1q_u32_x4(a: *const u32) -> uint32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18866,7 +18866,7 @@ pub unsafe fn vld1q_u32_x4(a: *const u32) -> uint32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -18889,7 +18889,7 @@ pub unsafe fn vld1_u64_x2(a: *const u64) -> uint64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -18912,7 +18912,7 @@ pub unsafe fn vld1_u64_x3(a: *const u64) -> uint64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_u64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))]
    @@ -18935,7 +18935,7 @@ pub unsafe fn vld1_u64_x4(a: *const u64) -> uint64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18959,7 +18959,7 @@ pub unsafe fn vld1q_u64_x2(a: *const u64) -> uint64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -18986,7 +18986,7 @@ pub unsafe fn vld1q_u64_x2(a: *const u64) -> uint64x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19010,7 +19010,7 @@ pub unsafe fn vld1q_u64_x3(a: *const u64) -> uint64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19038,7 +19038,7 @@ pub unsafe fn vld1q_u64_x3(a: *const u64) -> uint64x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19062,7 +19062,7 @@ pub unsafe fn vld1q_u64_x4(a: *const u64) -> uint64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_u64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19091,7 +19091,7 @@ pub unsafe fn vld1q_u64_x4(a: *const u64) -> uint64x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19115,7 +19115,7 @@ pub unsafe fn vld1_p8_x2(a: *const p8) -> poly8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19142,7 +19142,7 @@ pub unsafe fn vld1_p8_x2(a: *const p8) -> poly8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19166,7 +19166,7 @@ pub unsafe fn vld1_p8_x3(a: *const p8) -> poly8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19194,7 +19194,7 @@ pub unsafe fn vld1_p8_x3(a: *const p8) -> poly8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19218,7 +19218,7 @@ pub unsafe fn vld1_p8_x4(a: *const p8) -> poly8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19247,7 +19247,7 @@ pub unsafe fn vld1_p8_x4(a: *const p8) -> poly8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19271,7 +19271,7 @@ pub unsafe fn vld1q_p8_x2(a: *const p8) -> poly8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19310,7 +19310,7 @@ pub unsafe fn vld1q_p8_x2(a: *const p8) -> poly8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19334,7 +19334,7 @@ pub unsafe fn vld1q_p8_x3(a: *const p8) -> poly8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19380,7 +19380,7 @@ pub unsafe fn vld1q_p8_x3(a: *const p8) -> poly8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19404,7 +19404,7 @@ pub unsafe fn vld1q_p8_x4(a: *const p8) -> poly8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19457,7 +19457,7 @@ pub unsafe fn vld1q_p8_x4(a: *const p8) -> poly8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19481,7 +19481,7 @@ pub unsafe fn vld1_p16_x2(a: *const p16) -> poly16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19508,7 +19508,7 @@ pub unsafe fn vld1_p16_x2(a: *const p16) -> poly16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19532,7 +19532,7 @@ pub unsafe fn vld1_p16_x3(a: *const p16) -> poly16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19560,7 +19560,7 @@ pub unsafe fn vld1_p16_x3(a: *const p16) -> poly16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19584,7 +19584,7 @@ pub unsafe fn vld1_p16_x4(a: *const p16) -> poly16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1_p16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19613,7 +19613,7 @@ pub unsafe fn vld1_p16_x4(a: *const p16) -> poly16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19637,7 +19637,7 @@ pub unsafe fn vld1q_p16_x2(a: *const p16) -> poly16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19664,7 +19664,7 @@ pub unsafe fn vld1q_p16_x2(a: *const p16) -> poly16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19688,7 +19688,7 @@ pub unsafe fn vld1q_p16_x3(a: *const p16) -> poly16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19716,7 +19716,7 @@ pub unsafe fn vld1q_p16_x3(a: *const p16) -> poly16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19740,7 +19740,7 @@ pub unsafe fn vld1q_p16_x4(a: *const p16) -> poly16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_p16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -19765,7 +19765,7 @@ pub unsafe fn vld1q_p16_x4(a: *const p16) -> poly16x8x4_t {
         ret_val.3 = unsafe { simd_shuffle!(ret_val.3, ret_val.3, [7, 6, 5, 4, 3, 2, 1, 0]) };
         ret_val
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19778,7 +19778,7 @@ unsafe fn vld1_v1i64(a: *const i8) -> int64x1_t {
         }
         _vld1_v1i64(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19791,7 +19791,7 @@ unsafe fn vld1_v2f32(a: *const i8) -> float32x2_t {
         }
         _vld1_v2f32(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19804,7 +19804,7 @@ unsafe fn vld1_v2i32(a: *const i8) -> int32x2_t {
         }
         _vld1_v2i32(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19817,7 +19817,7 @@ unsafe fn vld1_v4i16(a: *const i8) -> int16x4_t {
         }
         _vld1_v4i16(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19830,7 +19830,7 @@ unsafe fn vld1_v8i8(a: *const i8) -> int8x8_t {
         }
         _vld1_v8i8(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19843,7 +19843,7 @@ unsafe fn vld1q_v16i8(a: *const i8) -> int8x16_t {
         }
         _vld1q_v16i8(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19856,7 +19856,7 @@ unsafe fn vld1q_v2i64(a: *const i8) -> int64x2_t {
         }
         _vld1q_v2i64(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19869,7 +19869,7 @@ unsafe fn vld1q_v4f32(a: *const i8) -> float32x4_t {
         }
         _vld1q_v4f32(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19882,7 +19882,7 @@ unsafe fn vld1q_v4i32(a: *const i8) -> int32x4_t {
         }
         _vld1q_v4i32(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[rustc_legacy_const_generics(1)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
    @@ -19895,7 +19895,7 @@ unsafe fn vld1q_v8i16(a: *const i8) -> int16x8_t {
         }
         _vld1q_v8i16(a, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -19909,7 +19909,7 @@ unsafe fn vld1_v4f16(a: *const i8, b: i32) -> float16x4_t {
         }
         _vld1_v4f16(a, b)
     }
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -19927,7 +19927,7 @@ unsafe fn vld1q_v8f16(a: *const i8, b: i32) -> float16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld1q_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vldr))]
    @@ -19951,7 +19951,7 @@ pub unsafe fn vld1q_dup_p64(ptr: *const p64) -> poly64x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
    @@ -19970,7 +19970,7 @@ pub unsafe fn vld2_dup_f16(a: *const f16) -> float16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
    @@ -19989,7 +19989,7 @@ pub unsafe fn vld2q_dup_f16(a: *const f16) -> float16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -20013,7 +20013,7 @@ pub unsafe fn vld2_dup_f16(a: *const f16) -> float16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -20037,7 +20037,7 @@ pub unsafe fn vld2q_dup_f16(a: *const f16) -> float16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -20053,7 +20053,7 @@ pub unsafe fn vld2_dup_f32(a: *const f32) -> float32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -20069,7 +20069,7 @@ pub unsafe fn vld2q_dup_f32(a: *const f32) -> float32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -20085,7 +20085,7 @@ pub unsafe fn vld2_dup_s8(a: *const i8) -> int8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -20101,7 +20101,7 @@ pub unsafe fn vld2q_dup_s8(a: *const i8) -> int8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -20117,7 +20117,7 @@ pub unsafe fn vld2_dup_s16(a: *const i16) -> int16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -20133,7 +20133,7 @@ pub unsafe fn vld2q_dup_s16(a: *const i16) -> int16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -20149,7 +20149,7 @@ pub unsafe fn vld2_dup_s32(a: *const i32) -> int32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -20165,7 +20165,7 @@ pub unsafe fn vld2q_dup_s32(a: *const i32) -> int32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20184,7 +20184,7 @@ pub unsafe fn vld2_dup_f32(a: *const f32) -> float32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20203,7 +20203,7 @@ pub unsafe fn vld2q_dup_f32(a: *const f32) -> float32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20222,7 +20222,7 @@ pub unsafe fn vld2_dup_s8(a: *const i8) -> int8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20241,7 +20241,7 @@ pub unsafe fn vld2q_dup_s8(a: *const i8) -> int8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20260,7 +20260,7 @@ pub unsafe fn vld2_dup_s16(a: *const i16) -> int16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20279,7 +20279,7 @@ pub unsafe fn vld2q_dup_s16(a: *const i16) -> int16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20298,7 +20298,7 @@ pub unsafe fn vld2_dup_s32(a: *const i32) -> int32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20317,7 +20317,7 @@ pub unsafe fn vld2q_dup_s32(a: *const i32) -> int32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -20340,7 +20340,7 @@ pub unsafe fn vld2_dup_p64(a: *const p64) -> poly64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -20356,7 +20356,7 @@ pub unsafe fn vld2_dup_s64(a: *const i64) -> int64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -20375,7 +20375,7 @@ pub unsafe fn vld2_dup_s64(a: *const i64) -> int64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -20398,7 +20398,7 @@ pub unsafe fn vld2_dup_u64(a: *const u64) -> uint64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20422,7 +20422,7 @@ pub unsafe fn vld2_dup_u8(a: *const u8) -> uint8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20449,7 +20449,7 @@ pub unsafe fn vld2_dup_u8(a: *const u8) -> uint8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20473,7 +20473,7 @@ pub unsafe fn vld2q_dup_u8(a: *const u8) -> uint8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20512,7 +20512,7 @@ pub unsafe fn vld2q_dup_u8(a: *const u8) -> uint8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20536,7 +20536,7 @@ pub unsafe fn vld2_dup_u16(a: *const u16) -> uint16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20563,7 +20563,7 @@ pub unsafe fn vld2_dup_u16(a: *const u16) -> uint16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20587,7 +20587,7 @@ pub unsafe fn vld2q_dup_u16(a: *const u16) -> uint16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20614,7 +20614,7 @@ pub unsafe fn vld2q_dup_u16(a: *const u16) -> uint16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20638,7 +20638,7 @@ pub unsafe fn vld2_dup_u32(a: *const u32) -> uint32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20665,7 +20665,7 @@ pub unsafe fn vld2_dup_u32(a: *const u32) -> uint32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20689,7 +20689,7 @@ pub unsafe fn vld2q_dup_u32(a: *const u32) -> uint32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20716,7 +20716,7 @@ pub unsafe fn vld2q_dup_u32(a: *const u32) -> uint32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20740,7 +20740,7 @@ pub unsafe fn vld2_dup_p8(a: *const p8) -> poly8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20767,7 +20767,7 @@ pub unsafe fn vld2_dup_p8(a: *const p8) -> poly8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20791,7 +20791,7 @@ pub unsafe fn vld2q_dup_p8(a: *const p8) -> poly8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20830,7 +20830,7 @@ pub unsafe fn vld2q_dup_p8(a: *const p8) -> poly8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20854,7 +20854,7 @@ pub unsafe fn vld2_dup_p16(a: *const p16) -> poly16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20881,7 +20881,7 @@ pub unsafe fn vld2_dup_p16(a: *const p16) -> poly16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20905,7 +20905,7 @@ pub unsafe fn vld2q_dup_p16(a: *const p16) -> poly16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -20932,7 +20932,7 @@ pub unsafe fn vld2q_dup_p16(a: *const p16) -> poly16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
    @@ -20951,7 +20951,7 @@ pub unsafe fn vld2_f16(a: *const f16) -> float16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
    @@ -20970,7 +20970,7 @@ pub unsafe fn vld2q_f16(a: *const f16) -> float16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -20994,7 +20994,7 @@ pub unsafe fn vld2_f16(a: *const f16) -> float16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -21018,7 +21018,7 @@ pub unsafe fn vld2q_f16(a: *const f16) -> float16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -21034,7 +21034,7 @@ pub unsafe fn vld2_f32(a: *const f32) -> float32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -21050,7 +21050,7 @@ pub unsafe fn vld2q_f32(a: *const f32) -> float32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -21066,7 +21066,7 @@ pub unsafe fn vld2_s8(a: *const i8) -> int8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -21082,7 +21082,7 @@ pub unsafe fn vld2q_s8(a: *const i8) -> int8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -21098,7 +21098,7 @@ pub unsafe fn vld2_s16(a: *const i16) -> int16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -21114,7 +21114,7 @@ pub unsafe fn vld2q_s16(a: *const i16) -> int16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -21130,7 +21130,7 @@ pub unsafe fn vld2_s32(a: *const i32) -> int32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -21146,7 +21146,7 @@ pub unsafe fn vld2q_s32(a: *const i32) -> int32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21165,7 +21165,7 @@ pub unsafe fn vld2_f32(a: *const f32) -> float32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21184,7 +21184,7 @@ pub unsafe fn vld2q_f32(a: *const f32) -> float32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21203,7 +21203,7 @@ pub unsafe fn vld2_s8(a: *const i8) -> int8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21222,7 +21222,7 @@ pub unsafe fn vld2q_s8(a: *const i8) -> int8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21241,7 +21241,7 @@ pub unsafe fn vld2_s16(a: *const i16) -> int16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21260,7 +21260,7 @@ pub unsafe fn vld2q_s16(a: *const i16) -> int16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21279,7 +21279,7 @@ pub unsafe fn vld2_s32(a: *const i32) -> int32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21298,7 +21298,7 @@ pub unsafe fn vld2q_s32(a: *const i32) -> int32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21324,7 +21324,7 @@ pub unsafe fn vld2_lane_f16(a: *const f16, b: float16x4x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21350,7 +21350,7 @@ pub unsafe fn vld2q_lane_f16(a: *const f16, b: float16x8x2_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -21377,7 +21377,7 @@ pub unsafe fn vld2_lane_f16(a: *const f16, b: float16x4x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -21408,7 +21408,7 @@ pub unsafe fn vld2q_lane_f16(a: *const f16, b: float16x8x2_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
    @@ -21429,7 +21429,7 @@ pub unsafe fn vld2_lane_f32(a: *const f32, b: float32x2x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
    @@ -21451,7 +21451,7 @@ pub unsafe fn vld2q_lane_f32(a: *const f32, b: float32x4x2_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
    @@ -21472,7 +21472,7 @@ pub unsafe fn vld2_lane_s8(a: *const i8, b: int8x8x2_t) -> int8
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
    @@ -21493,7 +21493,7 @@ pub unsafe fn vld2_lane_s16(a: *const i16, b: int16x4x2_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
    @@ -21514,7 +21514,7 @@ pub unsafe fn vld2q_lane_s16(a: *const i16, b: int16x8x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
    @@ -21535,7 +21535,7 @@ pub unsafe fn vld2_lane_s32(a: *const i32, b: int32x2x2_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld2, LANE = 0))]
    @@ -21556,7 +21556,7 @@ pub unsafe fn vld2q_lane_s32(a: *const i32, b: int32x4x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld2, LANE = 0))]
    @@ -21580,7 +21580,7 @@ pub unsafe fn vld2_lane_f32(a: *const f32, b: float32x2x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld2, LANE = 0))]
    @@ -21604,7 +21604,7 @@ pub unsafe fn vld2q_lane_f32(a: *const f32, b: float32x4x2_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld2, LANE = 0))]
    @@ -21628,7 +21628,7 @@ pub unsafe fn vld2q_lane_s16(a: *const i16, b: int16x8x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld2, LANE = 0))]
    @@ -21652,7 +21652,7 @@ pub unsafe fn vld2q_lane_s32(a: *const i32, b: int32x4x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld2, LANE = 0))]
    @@ -21671,7 +21671,7 @@ pub unsafe fn vld2_lane_s8(a: *const i8, b: int8x8x2_t) -> int8
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld2, LANE = 0))]
    @@ -21695,7 +21695,7 @@ pub unsafe fn vld2_lane_s16(a: *const i16, b: int16x4x2_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld2, LANE = 0))]
    @@ -21719,7 +21719,7 @@ pub unsafe fn vld2_lane_s32(a: *const i32, b: int32x2x2_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21744,7 +21744,7 @@ pub unsafe fn vld2_lane_u8(a: *const u8, b: uint8x8x2_t) -> uin
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21769,7 +21769,7 @@ pub unsafe fn vld2_lane_u16(a: *const u16, b: uint16x4x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21794,7 +21794,7 @@ pub unsafe fn vld2q_lane_u16(a: *const u16, b: uint16x8x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21819,7 +21819,7 @@ pub unsafe fn vld2_lane_u32(a: *const u32, b: uint32x2x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21844,7 +21844,7 @@ pub unsafe fn vld2q_lane_u32(a: *const u32, b: uint32x4x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21869,7 +21869,7 @@ pub unsafe fn vld2_lane_p8(a: *const p8, b: poly8x8x2_t) -> pol
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21894,7 +21894,7 @@ pub unsafe fn vld2_lane_p16(a: *const p16, b: poly16x4x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))]
    @@ -21919,7 +21919,7 @@ pub unsafe fn vld2q_lane_p16(a: *const p16, b: poly16x8x2_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -21942,7 +21942,7 @@ pub unsafe fn vld2_p64(a: *const p64) -> poly64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -21958,7 +21958,7 @@ pub unsafe fn vld2_s64(a: *const i64) -> int64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -21977,7 +21977,7 @@ pub unsafe fn vld2_s64(a: *const i64) -> int64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -22000,7 +22000,7 @@ pub unsafe fn vld2_u64(a: *const u64) -> uint64x1x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22024,7 +22024,7 @@ pub unsafe fn vld2_u8(a: *const u8) -> uint8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22051,7 +22051,7 @@ pub unsafe fn vld2_u8(a: *const u8) -> uint8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22075,7 +22075,7 @@ pub unsafe fn vld2q_u8(a: *const u8) -> uint8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22114,7 +22114,7 @@ pub unsafe fn vld2q_u8(a: *const u8) -> uint8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22138,7 +22138,7 @@ pub unsafe fn vld2_u16(a: *const u16) -> uint16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22165,7 +22165,7 @@ pub unsafe fn vld2_u16(a: *const u16) -> uint16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22189,7 +22189,7 @@ pub unsafe fn vld2q_u16(a: *const u16) -> uint16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22216,7 +22216,7 @@ pub unsafe fn vld2q_u16(a: *const u16) -> uint16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22240,7 +22240,7 @@ pub unsafe fn vld2_u32(a: *const u32) -> uint32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22267,7 +22267,7 @@ pub unsafe fn vld2_u32(a: *const u32) -> uint32x2x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22291,7 +22291,7 @@ pub unsafe fn vld2q_u32(a: *const u32) -> uint32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22318,7 +22318,7 @@ pub unsafe fn vld2q_u32(a: *const u32) -> uint32x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22342,7 +22342,7 @@ pub unsafe fn vld2_p8(a: *const p8) -> poly8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22369,7 +22369,7 @@ pub unsafe fn vld2_p8(a: *const p8) -> poly8x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22393,7 +22393,7 @@ pub unsafe fn vld2q_p8(a: *const p8) -> poly8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22432,7 +22432,7 @@ pub unsafe fn vld2q_p8(a: *const p8) -> poly8x16x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22456,7 +22456,7 @@ pub unsafe fn vld2_p16(a: *const p16) -> poly16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22483,7 +22483,7 @@ pub unsafe fn vld2_p16(a: *const p16) -> poly16x4x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22507,7 +22507,7 @@ pub unsafe fn vld2q_p16(a: *const p16) -> poly16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld2q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -22534,7 +22534,7 @@ pub unsafe fn vld2q_p16(a: *const p16) -> poly16x8x2_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
    @@ -22553,7 +22553,7 @@ pub unsafe fn vld3_dup_f16(a: *const f16) -> float16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
    @@ -22572,7 +22572,7 @@ pub unsafe fn vld3q_dup_f16(a: *const f16) -> float16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -22596,7 +22596,7 @@ pub unsafe fn vld3_dup_f16(a: *const f16) -> float16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -22620,7 +22620,7 @@ pub unsafe fn vld3q_dup_f16(a: *const f16) -> float16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22639,7 +22639,7 @@ pub unsafe fn vld3_dup_f32(a: *const f32) -> float32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22658,7 +22658,7 @@ pub unsafe fn vld3q_dup_f32(a: *const f32) -> float32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22677,7 +22677,7 @@ pub unsafe fn vld3_dup_s8(a: *const i8) -> int8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22696,7 +22696,7 @@ pub unsafe fn vld3q_dup_s8(a: *const i8) -> int8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22715,7 +22715,7 @@ pub unsafe fn vld3_dup_s16(a: *const i16) -> int16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22734,7 +22734,7 @@ pub unsafe fn vld3q_dup_s16(a: *const i16) -> int16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22753,7 +22753,7 @@ pub unsafe fn vld3_dup_s32(a: *const i32) -> int32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22772,7 +22772,7 @@ pub unsafe fn vld3q_dup_s32(a: *const i32) -> int32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -22791,7 +22791,7 @@ pub unsafe fn vld3_dup_s64(a: *const i64) -> int64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -22807,7 +22807,7 @@ pub unsafe fn vld3_dup_f32(a: *const f32) -> float32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -22823,7 +22823,7 @@ pub unsafe fn vld3q_dup_f32(a: *const f32) -> float32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -22839,7 +22839,7 @@ pub unsafe fn vld3_dup_s8(a: *const i8) -> int8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -22855,7 +22855,7 @@ pub unsafe fn vld3q_dup_s8(a: *const i8) -> int8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -22871,7 +22871,7 @@ pub unsafe fn vld3_dup_s16(a: *const i16) -> int16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -22887,7 +22887,7 @@ pub unsafe fn vld3q_dup_s16(a: *const i16) -> int16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -22903,7 +22903,7 @@ pub unsafe fn vld3_dup_s32(a: *const i32) -> int32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -22919,7 +22919,7 @@ pub unsafe fn vld3q_dup_s32(a: *const i32) -> int32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -22942,7 +22942,7 @@ pub unsafe fn vld3_dup_p64(a: *const p64) -> poly64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -22958,7 +22958,7 @@ pub unsafe fn vld3_dup_s64(a: *const i64) -> int64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -22981,7 +22981,7 @@ pub unsafe fn vld3_dup_u64(a: *const u64) -> uint64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23005,7 +23005,7 @@ pub unsafe fn vld3_dup_u8(a: *const u8) -> uint8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23033,7 +23033,7 @@ pub unsafe fn vld3_dup_u8(a: *const u8) -> uint8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23057,7 +23057,7 @@ pub unsafe fn vld3q_dup_u8(a: *const u8) -> uint8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23103,7 +23103,7 @@ pub unsafe fn vld3q_dup_u8(a: *const u8) -> uint8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23127,7 +23127,7 @@ pub unsafe fn vld3_dup_u16(a: *const u16) -> uint16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23155,7 +23155,7 @@ pub unsafe fn vld3_dup_u16(a: *const u16) -> uint16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23179,7 +23179,7 @@ pub unsafe fn vld3q_dup_u16(a: *const u16) -> uint16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23207,7 +23207,7 @@ pub unsafe fn vld3q_dup_u16(a: *const u16) -> uint16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23231,7 +23231,7 @@ pub unsafe fn vld3_dup_u32(a: *const u32) -> uint32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23259,7 +23259,7 @@ pub unsafe fn vld3_dup_u32(a: *const u32) -> uint32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23283,7 +23283,7 @@ pub unsafe fn vld3q_dup_u32(a: *const u32) -> uint32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23311,7 +23311,7 @@ pub unsafe fn vld3q_dup_u32(a: *const u32) -> uint32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23335,7 +23335,7 @@ pub unsafe fn vld3_dup_p8(a: *const p8) -> poly8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23363,7 +23363,7 @@ pub unsafe fn vld3_dup_p8(a: *const p8) -> poly8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23387,7 +23387,7 @@ pub unsafe fn vld3q_dup_p8(a: *const p8) -> poly8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23433,7 +23433,7 @@ pub unsafe fn vld3q_dup_p8(a: *const p8) -> poly8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23457,7 +23457,7 @@ pub unsafe fn vld3_dup_p16(a: *const p16) -> poly16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23485,7 +23485,7 @@ pub unsafe fn vld3_dup_p16(a: *const p16) -> poly16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23509,7 +23509,7 @@ pub unsafe fn vld3q_dup_p16(a: *const p16) -> poly16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -23537,7 +23537,7 @@ pub unsafe fn vld3q_dup_p16(a: *const p16) -> poly16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
    @@ -23556,7 +23556,7 @@ pub unsafe fn vld3_f16(a: *const f16) -> float16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
    @@ -23575,7 +23575,7 @@ pub unsafe fn vld3q_f16(a: *const f16) -> float16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -23599,7 +23599,7 @@ pub unsafe fn vld3_f16(a: *const f16) -> float16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -23623,7 +23623,7 @@ pub unsafe fn vld3q_f16(a: *const f16) -> float16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg(not(target_arch = "arm"))]
    @@ -23642,7 +23642,7 @@ pub unsafe fn vld3_f32(a: *const f32) -> float32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg(not(target_arch = "arm"))]
    @@ -23661,7 +23661,7 @@ pub unsafe fn vld3q_f32(a: *const f32) -> float32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg(not(target_arch = "arm"))]
    @@ -23680,7 +23680,7 @@ pub unsafe fn vld3_s8(a: *const i8) -> int8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg(not(target_arch = "arm"))]
    @@ -23699,7 +23699,7 @@ pub unsafe fn vld3q_s8(a: *const i8) -> int8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg(not(target_arch = "arm"))]
    @@ -23718,7 +23718,7 @@ pub unsafe fn vld3_s16(a: *const i16) -> int16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg(not(target_arch = "arm"))]
    @@ -23737,7 +23737,7 @@ pub unsafe fn vld3q_s16(a: *const i16) -> int16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg(not(target_arch = "arm"))]
    @@ -23756,7 +23756,7 @@ pub unsafe fn vld3_s32(a: *const i32) -> int32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg(not(target_arch = "arm"))]
    @@ -23775,7 +23775,7 @@ pub unsafe fn vld3q_s32(a: *const i32) -> int32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -23791,7 +23791,7 @@ pub unsafe fn vld3_f32(a: *const f32) -> float32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -23807,7 +23807,7 @@ pub unsafe fn vld3q_f32(a: *const f32) -> float32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -23823,7 +23823,7 @@ pub unsafe fn vld3_s8(a: *const i8) -> int8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -23839,7 +23839,7 @@ pub unsafe fn vld3q_s8(a: *const i8) -> int8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -23855,7 +23855,7 @@ pub unsafe fn vld3_s16(a: *const i16) -> int16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -23871,7 +23871,7 @@ pub unsafe fn vld3q_s16(a: *const i16) -> int16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -23887,7 +23887,7 @@ pub unsafe fn vld3_s32(a: *const i32) -> int32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -23903,7 +23903,7 @@ pub unsafe fn vld3q_s32(a: *const i32) -> int32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -23930,7 +23930,7 @@ pub unsafe fn vld3_lane_f16(a: *const f16, b: float16x4x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -23957,7 +23957,7 @@ pub unsafe fn vld3q_lane_f16(a: *const f16, b: float16x8x3_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -23989,7 +23989,7 @@ pub unsafe fn vld3_lane_f16(a: *const f16, b: float16x4x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
    @@ -24021,7 +24021,7 @@ pub unsafe fn vld3q_lane_f16(a: *const f16, b: float16x8x3_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
    @@ -24048,7 +24048,7 @@ pub unsafe fn vld3_lane_f32(a: *const f32, b: float32x2x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
    @@ -24075,7 +24075,7 @@ pub unsafe fn vld3q_lane_f32(a: *const f32, b: float32x4x3_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld3, LANE = 0))]
    @@ -24100,7 +24100,7 @@ pub unsafe fn vld3_lane_f32(a: *const f32, b: float32x2x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
    @@ -24127,7 +24127,7 @@ pub unsafe fn vld3_lane_s8(a: *const i8, b: int8x8x3_t) -> int8
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
    @@ -24154,7 +24154,7 @@ pub unsafe fn vld3_lane_s16(a: *const i16, b: int16x4x3_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
    @@ -24181,7 +24181,7 @@ pub unsafe fn vld3q_lane_s16(a: *const i16, b: int16x8x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
    @@ -24208,7 +24208,7 @@ pub unsafe fn vld3_lane_s32(a: *const i32, b: int32x2x3_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld3, LANE = 0))]
    @@ -24235,7 +24235,7 @@ pub unsafe fn vld3q_lane_s32(a: *const i32, b: int32x4x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld3, LANE = 0))]
    @@ -24260,7 +24260,7 @@ pub unsafe fn vld3_lane_s8(a: *const i8, b: int8x8x3_t) -> int8
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld3, LANE = 0))]
    @@ -24285,7 +24285,7 @@ pub unsafe fn vld3_lane_s16(a: *const i16, b: int16x4x3_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld3, LANE = 0))]
    @@ -24310,7 +24310,7 @@ pub unsafe fn vld3q_lane_s16(a: *const i16, b: int16x8x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld3, LANE = 0))]
    @@ -24335,7 +24335,7 @@ pub unsafe fn vld3_lane_s32(a: *const i32, b: int32x2x3_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld3, LANE = 0))]
    @@ -24360,7 +24360,7 @@ pub unsafe fn vld3q_lane_s32(a: *const i32, b: int32x4x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -24385,7 +24385,7 @@ pub unsafe fn vld3_lane_u8(a: *const u8, b: uint8x8x3_t) -> uin
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -24410,7 +24410,7 @@ pub unsafe fn vld3_lane_u16(a: *const u16, b: uint16x4x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -24435,7 +24435,7 @@ pub unsafe fn vld3q_lane_u16(a: *const u16, b: uint16x8x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -24460,7 +24460,7 @@ pub unsafe fn vld3_lane_u32(a: *const u32, b: uint32x2x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -24485,7 +24485,7 @@ pub unsafe fn vld3q_lane_u32(a: *const u32, b: uint32x4x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -24510,7 +24510,7 @@ pub unsafe fn vld3_lane_p8(a: *const p8, b: poly8x8x3_t) -> pol
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -24535,7 +24535,7 @@ pub unsafe fn vld3_lane_p16(a: *const p16, b: poly16x4x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))]
    @@ -24560,7 +24560,7 @@ pub unsafe fn vld3q_lane_p16(a: *const p16, b: poly16x8x3_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -24583,7 +24583,7 @@ pub unsafe fn vld3_p64(a: *const p64) -> poly64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
     #[cfg(not(target_arch = "arm"))]
    @@ -24602,7 +24602,7 @@ pub unsafe fn vld3_s64(a: *const i64) -> int64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -24618,7 +24618,7 @@ pub unsafe fn vld3_s64(a: *const i64) -> int64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -24641,7 +24641,7 @@ pub unsafe fn vld3_u64(a: *const u64) -> uint64x1x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24665,7 +24665,7 @@ pub unsafe fn vld3_u8(a: *const u8) -> uint8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24693,7 +24693,7 @@ pub unsafe fn vld3_u8(a: *const u8) -> uint8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24717,7 +24717,7 @@ pub unsafe fn vld3q_u8(a: *const u8) -> uint8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24763,7 +24763,7 @@ pub unsafe fn vld3q_u8(a: *const u8) -> uint8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24787,7 +24787,7 @@ pub unsafe fn vld3_u16(a: *const u16) -> uint16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24815,7 +24815,7 @@ pub unsafe fn vld3_u16(a: *const u16) -> uint16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24839,7 +24839,7 @@ pub unsafe fn vld3q_u16(a: *const u16) -> uint16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24867,7 +24867,7 @@ pub unsafe fn vld3q_u16(a: *const u16) -> uint16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24891,7 +24891,7 @@ pub unsafe fn vld3_u32(a: *const u32) -> uint32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24919,7 +24919,7 @@ pub unsafe fn vld3_u32(a: *const u32) -> uint32x2x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24943,7 +24943,7 @@ pub unsafe fn vld3q_u32(a: *const u32) -> uint32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24971,7 +24971,7 @@ pub unsafe fn vld3q_u32(a: *const u32) -> uint32x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -24995,7 +24995,7 @@ pub unsafe fn vld3_p8(a: *const p8) -> poly8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25023,7 +25023,7 @@ pub unsafe fn vld3_p8(a: *const p8) -> poly8x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25047,7 +25047,7 @@ pub unsafe fn vld3q_p8(a: *const p8) -> poly8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25093,7 +25093,7 @@ pub unsafe fn vld3q_p8(a: *const p8) -> poly8x16x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25117,7 +25117,7 @@ pub unsafe fn vld3_p16(a: *const p16) -> poly16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25145,7 +25145,7 @@ pub unsafe fn vld3_p16(a: *const p16) -> poly16x4x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25169,7 +25169,7 @@ pub unsafe fn vld3q_p16(a: *const p16) -> poly16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25197,7 +25197,7 @@ pub unsafe fn vld3q_p16(a: *const p16) -> poly16x8x3_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld3q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld3, LANE = 0))]
    @@ -25222,7 +25222,7 @@ pub unsafe fn vld3q_lane_f32(a: *const f32, b: float32x4x3_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4))]
    @@ -25240,7 +25240,7 @@ pub unsafe fn vld4_dup_f16(a: *const f16) -> float16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4))]
    @@ -25258,7 +25258,7 @@ pub unsafe fn vld4q_dup_f16(a: *const f16) -> float16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
         all(test, any(target_arch = "aarch64", target_arch = "arm64ec")),
    @@ -25281,7 +25281,7 @@ pub unsafe fn vld4_dup_f16(a: *const f16) -> float16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
         all(test, any(target_arch = "aarch64", target_arch = "arm64ec")),
    @@ -25304,7 +25304,7 @@ pub unsafe fn vld4q_dup_f16(a: *const f16) -> float16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld4))]
    @@ -25320,7 +25320,7 @@ pub unsafe fn vld4_dup_f32(a: *const f32) -> float32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld4))]
    @@ -25336,7 +25336,7 @@ pub unsafe fn vld4q_dup_f32(a: *const f32) -> float32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld4))]
    @@ -25352,7 +25352,7 @@ pub unsafe fn vld4_dup_s8(a: *const i8) -> int8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld4))]
    @@ -25368,7 +25368,7 @@ pub unsafe fn vld4q_dup_s8(a: *const i8) -> int8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld4))]
    @@ -25384,7 +25384,7 @@ pub unsafe fn vld4_dup_s16(a: *const i16) -> int16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld4))]
    @@ -25400,7 +25400,7 @@ pub unsafe fn vld4q_dup_s16(a: *const i16) -> int16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld4))]
    @@ -25416,7 +25416,7 @@ pub unsafe fn vld4_dup_s32(a: *const i32) -> int32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vld4))]
    @@ -25432,7 +25432,7 @@ pub unsafe fn vld4q_dup_s32(a: *const i32) -> int32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -25451,7 +25451,7 @@ pub unsafe fn vld4_dup_f32(a: *const f32) -> float32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -25470,7 +25470,7 @@ pub unsafe fn vld4q_dup_f32(a: *const f32) -> float32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -25489,7 +25489,7 @@ pub unsafe fn vld4_dup_s8(a: *const i8) -> int8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -25508,7 +25508,7 @@ pub unsafe fn vld4q_dup_s8(a: *const i8) -> int8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -25527,7 +25527,7 @@ pub unsafe fn vld4_dup_s16(a: *const i16) -> int16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -25546,7 +25546,7 @@ pub unsafe fn vld4q_dup_s16(a: *const i16) -> int16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -25565,7 +25565,7 @@ pub unsafe fn vld4_dup_s32(a: *const i32) -> int32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -25584,7 +25584,7 @@ pub unsafe fn vld4q_dup_s32(a: *const i32) -> int32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4r))]
    @@ -25603,7 +25603,7 @@ pub unsafe fn vld4_dup_s64(a: *const i64) -> int64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -25626,7 +25626,7 @@ pub unsafe fn vld4_dup_p64(a: *const p64) -> poly64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(nop))]
    @@ -25642,7 +25642,7 @@ pub unsafe fn vld4_dup_s64(a: *const i64) -> int64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -25665,7 +25665,7 @@ pub unsafe fn vld4_dup_u64(a: *const u64) -> uint64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25689,7 +25689,7 @@ pub unsafe fn vld4_dup_u8(a: *const u8) -> uint8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25718,7 +25718,7 @@ pub unsafe fn vld4_dup_u8(a: *const u8) -> uint8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25742,7 +25742,7 @@ pub unsafe fn vld4q_dup_u8(a: *const u8) -> uint8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25795,7 +25795,7 @@ pub unsafe fn vld4q_dup_u8(a: *const u8) -> uint8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25819,7 +25819,7 @@ pub unsafe fn vld4_dup_u16(a: *const u16) -> uint16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25848,7 +25848,7 @@ pub unsafe fn vld4_dup_u16(a: *const u16) -> uint16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25872,7 +25872,7 @@ pub unsafe fn vld4q_dup_u16(a: *const u16) -> uint16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25901,7 +25901,7 @@ pub unsafe fn vld4q_dup_u16(a: *const u16) -> uint16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25925,7 +25925,7 @@ pub unsafe fn vld4_dup_u32(a: *const u32) -> uint32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25954,7 +25954,7 @@ pub unsafe fn vld4_dup_u32(a: *const u32) -> uint32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -25978,7 +25978,7 @@ pub unsafe fn vld4q_dup_u32(a: *const u32) -> uint32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -26007,7 +26007,7 @@ pub unsafe fn vld4q_dup_u32(a: *const u32) -> uint32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -26031,7 +26031,7 @@ pub unsafe fn vld4_dup_p8(a: *const p8) -> poly8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -26060,7 +26060,7 @@ pub unsafe fn vld4_dup_p8(a: *const p8) -> poly8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -26084,7 +26084,7 @@ pub unsafe fn vld4q_dup_p8(a: *const p8) -> poly8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -26137,7 +26137,7 @@ pub unsafe fn vld4q_dup_p8(a: *const p8) -> poly8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -26161,7 +26161,7 @@ pub unsafe fn vld4_dup_p16(a: *const p16) -> poly16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -26190,7 +26190,7 @@ pub unsafe fn vld4_dup_p16(a: *const p16) -> poly16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -26214,7 +26214,7 @@ pub unsafe fn vld4q_dup_p16(a: *const p16) -> poly16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_dup_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -26243,7 +26243,7 @@ pub unsafe fn vld4q_dup_p16(a: *const p16) -> poly16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4))]
    @@ -26261,7 +26261,7 @@ pub unsafe fn vld4_f16(a: *const f16) -> float16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4))]
    @@ -26279,7 +26279,7 @@ pub unsafe fn vld4q_f16(a: *const f16) -> float16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
         all(test, any(target_arch = "aarch64", target_arch = "arm64ec")),
    @@ -26302,7 +26302,7 @@ pub unsafe fn vld4_f16(a: *const f16) -> float16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
         all(test, any(target_arch = "aarch64", target_arch = "arm64ec")),
    @@ -26325,7 +26325,7 @@ pub unsafe fn vld4q_f16(a: *const f16) -> float16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26344,7 +26344,7 @@ pub unsafe fn vld4_f32(a: *const f32) -> float32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26363,7 +26363,7 @@ pub unsafe fn vld4q_f32(a: *const f32) -> float32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26382,7 +26382,7 @@ pub unsafe fn vld4_s8(a: *const i8) -> int8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26401,7 +26401,7 @@ pub unsafe fn vld4q_s8(a: *const i8) -> int8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26420,7 +26420,7 @@ pub unsafe fn vld4_s16(a: *const i16) -> int16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26439,7 +26439,7 @@ pub unsafe fn vld4q_s16(a: *const i16) -> int16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26458,7 +26458,7 @@ pub unsafe fn vld4_s32(a: *const i32) -> int32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -26477,7 +26477,7 @@ pub unsafe fn vld4q_s32(a: *const i32) -> int32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -26493,7 +26493,7 @@ pub unsafe fn vld4_f32(a: *const f32) -> float32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -26509,7 +26509,7 @@ pub unsafe fn vld4q_f32(a: *const f32) -> float32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -26525,7 +26525,7 @@ pub unsafe fn vld4_s8(a: *const i8) -> int8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -26541,7 +26541,7 @@ pub unsafe fn vld4q_s8(a: *const i8) -> int8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -26557,7 +26557,7 @@ pub unsafe fn vld4_s16(a: *const i16) -> int16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -26573,7 +26573,7 @@ pub unsafe fn vld4q_s16(a: *const i16) -> int16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -26589,7 +26589,7 @@ pub unsafe fn vld4_s32(a: *const i32) -> int32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -26605,7 +26605,7 @@ pub unsafe fn vld4q_s32(a: *const i32) -> int32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -26633,7 +26633,7 @@ pub unsafe fn vld4_lane_f16(a: *const f16, b: float16x4x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -26661,7 +26661,7 @@ pub unsafe fn vld4q_lane_f16(a: *const f16, b: float16x8x4_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
         all(test, any(target_arch = "aarch64", target_arch = "arm64ec")),
    @@ -26693,7 +26693,7 @@ pub unsafe fn vld4_lane_f16(a: *const f16, b: float16x4x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(
         all(test, any(target_arch = "aarch64", target_arch = "arm64ec")),
    @@ -26725,7 +26725,7 @@ pub unsafe fn vld4q_lane_f16(a: *const f16, b: float16x8x4_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
    @@ -26753,7 +26753,7 @@ pub unsafe fn vld4_lane_f32(a: *const f32, b: float32x2x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
    @@ -26781,7 +26781,7 @@ pub unsafe fn vld4q_lane_f32(a: *const f32, b: float32x4x4_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
    @@ -26809,7 +26809,7 @@ pub unsafe fn vld4_lane_s8(a: *const i8, b: int8x8x4_t) -> int8
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
    @@ -26837,7 +26837,7 @@ pub unsafe fn vld4_lane_s16(a: *const i16, b: int16x4x4_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
    @@ -26865,7 +26865,7 @@ pub unsafe fn vld4q_lane_s16(a: *const i16, b: int16x8x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
    @@ -26893,7 +26893,7 @@ pub unsafe fn vld4_lane_s32(a: *const i32, b: int32x2x4_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(ld4, LANE = 0))]
    @@ -26921,7 +26921,7 @@ pub unsafe fn vld4q_lane_s32(a: *const i32, b: int32x4x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld4, LANE = 0))]
    @@ -26947,7 +26947,7 @@ pub unsafe fn vld4_lane_f32(a: *const f32, b: float32x2x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld4, LANE = 0))]
    @@ -26973,7 +26973,7 @@ pub unsafe fn vld4q_lane_f32(a: *const f32, b: float32x4x4_t) -
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld4, LANE = 0))]
    @@ -26999,7 +26999,7 @@ pub unsafe fn vld4_lane_s8(a: *const i8, b: int8x8x4_t) -> int8
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld4, LANE = 0))]
    @@ -27025,7 +27025,7 @@ pub unsafe fn vld4_lane_s16(a: *const i16, b: int16x4x4_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld4, LANE = 0))]
    @@ -27051,7 +27051,7 @@ pub unsafe fn vld4q_lane_s16(a: *const i16, b: int16x8x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld4, LANE = 0))]
    @@ -27077,7 +27077,7 @@ pub unsafe fn vld4_lane_s32(a: *const i32, b: int32x2x4_t) -> i
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(test, assert_instr(vld4, LANE = 0))]
    @@ -27103,7 +27103,7 @@ pub unsafe fn vld4q_lane_s32(a: *const i32, b: int32x4x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -27128,7 +27128,7 @@ pub unsafe fn vld4_lane_u8(a: *const u8, b: uint8x8x4_t) -> uin
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -27153,7 +27153,7 @@ pub unsafe fn vld4_lane_u16(a: *const u16, b: uint16x4x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -27178,7 +27178,7 @@ pub unsafe fn vld4q_lane_u16(a: *const u16, b: uint16x8x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -27203,7 +27203,7 @@ pub unsafe fn vld4_lane_u32(a: *const u32, b: uint32x2x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -27228,7 +27228,7 @@ pub unsafe fn vld4q_lane_u32(a: *const u32, b: uint32x4x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -27253,7 +27253,7 @@ pub unsafe fn vld4_lane_p8(a: *const p8, b: poly8x8x4_t) -> pol
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -27278,7 +27278,7 @@ pub unsafe fn vld4_lane_p16(a: *const p16, b: poly16x4x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld4, LANE = 0))]
    @@ -27303,7 +27303,7 @@ pub unsafe fn vld4q_lane_p16(a: *const p16, b: poly16x8x4_t) ->
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -27326,7 +27326,7 @@ pub unsafe fn vld4_p64(a: *const p64) -> poly64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -27345,7 +27345,7 @@ pub unsafe fn vld4_s64(a: *const i64) -> int64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -27361,7 +27361,7 @@ pub unsafe fn vld4_s64(a: *const i64) -> int64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -27384,7 +27384,7 @@ pub unsafe fn vld4_u64(a: *const u64) -> uint64x1x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27408,7 +27408,7 @@ pub unsafe fn vld4_u8(a: *const u8) -> uint8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27437,7 +27437,7 @@ pub unsafe fn vld4_u8(a: *const u8) -> uint8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27461,7 +27461,7 @@ pub unsafe fn vld4q_u8(a: *const u8) -> uint8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27514,7 +27514,7 @@ pub unsafe fn vld4q_u8(a: *const u8) -> uint8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27538,7 +27538,7 @@ pub unsafe fn vld4_u16(a: *const u16) -> uint16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27567,7 +27567,7 @@ pub unsafe fn vld4_u16(a: *const u16) -> uint16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27591,7 +27591,7 @@ pub unsafe fn vld4q_u16(a: *const u16) -> uint16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27620,7 +27620,7 @@ pub unsafe fn vld4q_u16(a: *const u16) -> uint16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27644,7 +27644,7 @@ pub unsafe fn vld4_u32(a: *const u32) -> uint32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27673,7 +27673,7 @@ pub unsafe fn vld4_u32(a: *const u32) -> uint32x2x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27697,7 +27697,7 @@ pub unsafe fn vld4q_u32(a: *const u32) -> uint32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27726,7 +27726,7 @@ pub unsafe fn vld4q_u32(a: *const u32) -> uint32x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27750,7 +27750,7 @@ pub unsafe fn vld4_p8(a: *const p8) -> poly8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27779,7 +27779,7 @@ pub unsafe fn vld4_p8(a: *const p8) -> poly8x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27803,7 +27803,7 @@ pub unsafe fn vld4q_p8(a: *const p8) -> poly8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27856,7 +27856,7 @@ pub unsafe fn vld4q_p8(a: *const p8) -> poly8x16x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27880,7 +27880,7 @@ pub unsafe fn vld4_p16(a: *const p16) -> poly16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27909,7 +27909,7 @@ pub unsafe fn vld4_p16(a: *const p16) -> poly16x4x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27933,7 +27933,7 @@ pub unsafe fn vld4q_p16(a: *const p16) -> poly16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vld4q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -27962,7 +27962,7 @@ pub unsafe fn vld4q_p16(a: *const p16) -> poly16x8x4_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vldrq_p128)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -27983,7 +27983,7 @@ pub unsafe fn vldrq_p128(a: *const p128) -> p128 {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
     #[cfg_attr(
    @@ -28013,7 +28013,7 @@ pub fn vmax_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
     #[cfg_attr(
    @@ -28043,7 +28043,7 @@ pub fn vmaxq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28072,7 +28072,7 @@ pub fn vmax_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28101,7 +28101,7 @@ pub fn vmaxq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28125,7 +28125,7 @@ pub fn vmax_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28149,7 +28149,7 @@ pub fn vmaxq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28173,7 +28173,7 @@ pub fn vmax_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28197,7 +28197,7 @@ pub fn vmaxq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28221,7 +28221,7 @@ pub fn vmax_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28245,7 +28245,7 @@ pub fn vmaxq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28269,7 +28269,7 @@ pub fn vmax_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28293,7 +28293,7 @@ pub fn vmaxq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28317,7 +28317,7 @@ pub fn vmax_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28341,7 +28341,7 @@ pub fn vmaxq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmax_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28365,7 +28365,7 @@ pub fn vmax_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Maximum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmax))]
    @@ -28389,7 +28389,7 @@ pub fn vmaxq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point Maximum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnm_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmaxnm))]
     #[cfg_attr(
    @@ -28411,7 +28411,7 @@ pub fn vmaxnm_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point Maximum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmaxnm))]
     #[cfg_attr(
    @@ -28433,7 +28433,7 @@ pub fn vmaxnmq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point Maximum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnm_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmaxnm))]
    @@ -28454,7 +28454,7 @@ pub fn vmaxnm_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point Maximum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmaxnmq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmaxnm))]
    @@ -28475,7 +28475,7 @@ pub fn vmaxnmq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
     #[cfg_attr(
    @@ -28505,7 +28505,7 @@ pub fn vmin_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
     #[cfg_attr(
    @@ -28535,7 +28535,7 @@ pub fn vminq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28564,7 +28564,7 @@ pub fn vmin_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28593,7 +28593,7 @@ pub fn vminq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28617,7 +28617,7 @@ pub fn vmin_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28641,7 +28641,7 @@ pub fn vminq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28665,7 +28665,7 @@ pub fn vmin_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28689,7 +28689,7 @@ pub fn vminq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28713,7 +28713,7 @@ pub fn vmin_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28737,7 +28737,7 @@ pub fn vminq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28761,7 +28761,7 @@ pub fn vmin_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28785,7 +28785,7 @@ pub fn vminq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28809,7 +28809,7 @@ pub fn vmin_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28833,7 +28833,7 @@ pub fn vminq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmin_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28857,7 +28857,7 @@ pub fn vmin_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Minimum (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmin))]
    @@ -28881,7 +28881,7 @@ pub fn vminq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point Minimum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnm_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vminnm))]
     #[cfg_attr(
    @@ -28903,7 +28903,7 @@ pub fn vminnm_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point Minimum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vminnm))]
     #[cfg_attr(
    @@ -28925,7 +28925,7 @@ pub fn vminnmq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point Minimum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnm_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vminnm))]
    @@ -28946,7 +28946,7 @@ pub fn vminnm_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point Minimum Number (vector)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vminnmq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vminnm))]
    @@ -28967,7 +28967,7 @@ pub fn vminnmq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Floating-point multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.f32"))]
    @@ -28988,7 +28988,7 @@ pub fn vmla_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.f32"))]
    @@ -29009,7 +29009,7 @@ pub fn vmlaq_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> float32x4_t
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.f32", LANE = 1))]
    @@ -29036,7 +29036,7 @@ pub fn vmla_lane_f32(
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.f32", LANE = 1))]
    @@ -29063,7 +29063,7 @@ pub fn vmla_laneq_f32(
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.f32", LANE = 1))]
    @@ -29096,7 +29096,7 @@ pub fn vmlaq_lane_f32(
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.f32", LANE = 1))]
    @@ -29129,7 +29129,7 @@ pub fn vmlaq_laneq_f32(
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16", LANE = 1))]
    @@ -29158,7 +29158,7 @@ pub fn vmla_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t)
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16", LANE = 1))]
    @@ -29187,7 +29187,7 @@ pub fn vmla_lane_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16", LANE = 1))]
    @@ -29216,7 +29216,7 @@ pub fn vmla_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x8_t)
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16", LANE = 1))]
    @@ -29245,7 +29245,7 @@ pub fn vmla_laneq_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x8
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16", LANE = 1))]
    @@ -29287,7 +29287,7 @@ pub fn vmlaq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x4_t)
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16", LANE = 1))]
    @@ -29329,7 +29329,7 @@ pub fn vmlaq_lane_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x4
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16", LANE = 1))]
    @@ -29371,7 +29371,7 @@ pub fn vmlaq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16", LANE = 1))]
    @@ -29413,7 +29413,7 @@ pub fn vmlaq_laneq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32", LANE = 1))]
    @@ -29436,7 +29436,7 @@ pub fn vmla_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t)
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32", LANE = 1))]
    @@ -29459,7 +29459,7 @@ pub fn vmla_lane_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32", LANE = 1))]
    @@ -29482,7 +29482,7 @@ pub fn vmla_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x4_t)
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32", LANE = 1))]
    @@ -29505,7 +29505,7 @@ pub fn vmla_laneq_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x4
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32", LANE = 1))]
    @@ -29534,7 +29534,7 @@ pub fn vmlaq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x2_t)
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32", LANE = 1))]
    @@ -29563,7 +29563,7 @@ pub fn vmlaq_lane_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x2
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32", LANE = 1))]
    @@ -29592,7 +29592,7 @@ pub fn vmlaq_laneq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32", LANE = 1))]
    @@ -29621,7 +29621,7 @@ pub fn vmlaq_laneq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.f32"))]
    @@ -29642,7 +29642,7 @@ pub fn vmla_n_f32(a: float32x2_t, b: float32x2_t, c: f32) -> float32x2_t {
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.f32"))]
    @@ -29663,7 +29663,7 @@ pub fn vmlaq_n_f32(a: float32x4_t, b: float32x4_t, c: f32) -> float32x4_t {
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16"))]
    @@ -29684,7 +29684,7 @@ pub fn vmla_n_s16(a: int16x4_t, b: int16x4_t, c: i16) -> int16x4_t {
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16"))]
    @@ -29705,7 +29705,7 @@ pub fn vmlaq_n_s16(a: int16x8_t, b: int16x8_t, c: i16) -> int16x8_t {
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16"))]
    @@ -29726,7 +29726,7 @@ pub fn vmla_n_u16(a: uint16x4_t, b: uint16x4_t, c: u16) -> uint16x4_t {
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16"))]
    @@ -29747,7 +29747,7 @@ pub fn vmlaq_n_u16(a: uint16x8_t, b: uint16x8_t, c: u16) -> uint16x8_t {
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32"))]
    @@ -29768,7 +29768,7 @@ pub fn vmla_n_s32(a: int32x2_t, b: int32x2_t, c: i32) -> int32x2_t {
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32"))]
    @@ -29789,7 +29789,7 @@ pub fn vmlaq_n_s32(a: int32x4_t, b: int32x4_t, c: i32) -> int32x4_t {
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32"))]
    @@ -29810,7 +29810,7 @@ pub fn vmla_n_u32(a: uint32x2_t, b: uint32x2_t, c: u32) -> uint32x2_t {
     }
     #[doc = "Vector multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32"))]
    @@ -29831,7 +29831,7 @@ pub fn vmlaq_n_u32(a: uint32x4_t, b: uint32x4_t, c: u32) -> uint32x4_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i8"))]
    @@ -29852,7 +29852,7 @@ pub fn vmla_s8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i8"))]
    @@ -29873,7 +29873,7 @@ pub fn vmlaq_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16"))]
    @@ -29894,7 +29894,7 @@ pub fn vmla_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16"))]
    @@ -29915,7 +29915,7 @@ pub fn vmlaq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32"))]
    @@ -29936,7 +29936,7 @@ pub fn vmla_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32"))]
    @@ -29957,7 +29957,7 @@ pub fn vmlaq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i8"))]
    @@ -29978,7 +29978,7 @@ pub fn vmla_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i8"))]
    @@ -29999,7 +29999,7 @@ pub fn vmlaq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16"))]
    @@ -30020,7 +30020,7 @@ pub fn vmla_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i16"))]
    @@ -30041,7 +30041,7 @@ pub fn vmlaq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmla_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32"))]
    @@ -30062,7 +30062,7 @@ pub fn vmla_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Multiply-add to accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlaq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmla.i32"))]
    @@ -30083,7 +30083,7 @@ pub fn vmlaq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.s16", LANE = 1))]
    @@ -30112,7 +30112,7 @@ pub fn vmlal_lane_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t)
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.s16", LANE = 1))]
    @@ -30141,7 +30141,7 @@ pub fn vmlal_laneq_s16(a: int32x4_t, b: int16x4_t, c: int16x8_t
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.s32", LANE = 1))]
    @@ -30164,7 +30164,7 @@ pub fn vmlal_lane_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t)
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.s32", LANE = 1))]
    @@ -30187,7 +30187,7 @@ pub fn vmlal_laneq_s32(a: int64x2_t, b: int32x2_t, c: int32x4_t
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.u16", LANE = 1))]
    @@ -30216,7 +30216,7 @@ pub fn vmlal_lane_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x4
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.u16", LANE = 1))]
    @@ -30245,7 +30245,7 @@ pub fn vmlal_laneq_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.u32", LANE = 1))]
    @@ -30268,7 +30268,7 @@ pub fn vmlal_lane_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x2
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.u32", LANE = 1))]
    @@ -30291,7 +30291,7 @@ pub fn vmlal_laneq_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.s16"))]
    @@ -30312,7 +30312,7 @@ pub fn vmlal_n_s16(a: int32x4_t, b: int16x4_t, c: i16) -> int32x4_t {
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.s32"))]
    @@ -30333,7 +30333,7 @@ pub fn vmlal_n_s32(a: int64x2_t, b: int32x2_t, c: i32) -> int64x2_t {
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.u16"))]
    @@ -30354,7 +30354,7 @@ pub fn vmlal_n_u16(a: uint32x4_t, b: uint16x4_t, c: u16) -> uint32x4_t {
     }
     #[doc = "Vector widening multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.u32"))]
    @@ -30375,7 +30375,7 @@ pub fn vmlal_n_u32(a: uint64x2_t, b: uint32x2_t, c: u32) -> uint64x2_t {
     }
     #[doc = "Signed multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.s8"))]
    @@ -30396,7 +30396,7 @@ pub fn vmlal_s8(a: int16x8_t, b: int8x8_t, c: int8x8_t) -> int16x8_t {
     }
     #[doc = "Signed multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.s16"))]
    @@ -30417,7 +30417,7 @@ pub fn vmlal_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.s32"))]
    @@ -30438,7 +30438,7 @@ pub fn vmlal_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.u8"))]
    @@ -30459,7 +30459,7 @@ pub fn vmlal_u8(a: uint16x8_t, b: uint8x8_t, c: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.u16"))]
    @@ -30480,7 +30480,7 @@ pub fn vmlal_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlal.u32"))]
    @@ -30501,7 +30501,7 @@ pub fn vmlal_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Floating-point multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.f32"))]
    @@ -30522,7 +30522,7 @@ pub fn vmls_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.f32"))]
    @@ -30543,7 +30543,7 @@ pub fn vmlsq_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t) -> float32x4_t
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.f32", LANE = 1))]
    @@ -30570,7 +30570,7 @@ pub fn vmls_lane_f32(
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.f32", LANE = 1))]
    @@ -30597,7 +30597,7 @@ pub fn vmls_laneq_f32(
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.f32", LANE = 1))]
    @@ -30630,7 +30630,7 @@ pub fn vmlsq_lane_f32(
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.f32", LANE = 1))]
    @@ -30663,7 +30663,7 @@ pub fn vmlsq_laneq_f32(
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16", LANE = 1))]
    @@ -30692,7 +30692,7 @@ pub fn vmls_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t)
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16", LANE = 1))]
    @@ -30721,7 +30721,7 @@ pub fn vmls_lane_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16", LANE = 1))]
    @@ -30750,7 +30750,7 @@ pub fn vmls_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x8_t)
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16", LANE = 1))]
    @@ -30779,7 +30779,7 @@ pub fn vmls_laneq_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x8
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16", LANE = 1))]
    @@ -30821,7 +30821,7 @@ pub fn vmlsq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x4_t)
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16", LANE = 1))]
    @@ -30863,7 +30863,7 @@ pub fn vmlsq_lane_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x4
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16", LANE = 1))]
    @@ -30905,7 +30905,7 @@ pub fn vmlsq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16", LANE = 1))]
    @@ -30947,7 +30947,7 @@ pub fn vmlsq_laneq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32", LANE = 1))]
    @@ -30970,7 +30970,7 @@ pub fn vmls_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t)
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32", LANE = 1))]
    @@ -30993,7 +30993,7 @@ pub fn vmls_lane_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32", LANE = 1))]
    @@ -31016,7 +31016,7 @@ pub fn vmls_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x4_t)
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32", LANE = 1))]
    @@ -31039,7 +31039,7 @@ pub fn vmls_laneq_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x4
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32", LANE = 1))]
    @@ -31068,7 +31068,7 @@ pub fn vmlsq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x2_t)
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32", LANE = 1))]
    @@ -31097,7 +31097,7 @@ pub fn vmlsq_lane_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x2
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32", LANE = 1))]
    @@ -31126,7 +31126,7 @@ pub fn vmlsq_laneq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32", LANE = 1))]
    @@ -31155,7 +31155,7 @@ pub fn vmlsq_laneq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.f32"))]
    @@ -31176,7 +31176,7 @@ pub fn vmls_n_f32(a: float32x2_t, b: float32x2_t, c: f32) -> float32x2_t {
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.f32"))]
    @@ -31197,7 +31197,7 @@ pub fn vmlsq_n_f32(a: float32x4_t, b: float32x4_t, c: f32) -> float32x4_t {
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16"))]
    @@ -31218,7 +31218,7 @@ pub fn vmls_n_s16(a: int16x4_t, b: int16x4_t, c: i16) -> int16x4_t {
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16"))]
    @@ -31239,7 +31239,7 @@ pub fn vmlsq_n_s16(a: int16x8_t, b: int16x8_t, c: i16) -> int16x8_t {
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16"))]
    @@ -31260,7 +31260,7 @@ pub fn vmls_n_u16(a: uint16x4_t, b: uint16x4_t, c: u16) -> uint16x4_t {
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16"))]
    @@ -31281,7 +31281,7 @@ pub fn vmlsq_n_u16(a: uint16x8_t, b: uint16x8_t, c: u16) -> uint16x8_t {
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32"))]
    @@ -31302,7 +31302,7 @@ pub fn vmls_n_s32(a: int32x2_t, b: int32x2_t, c: i32) -> int32x2_t {
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32"))]
    @@ -31323,7 +31323,7 @@ pub fn vmlsq_n_s32(a: int32x4_t, b: int32x4_t, c: i32) -> int32x4_t {
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32"))]
    @@ -31344,7 +31344,7 @@ pub fn vmls_n_u32(a: uint32x2_t, b: uint32x2_t, c: u32) -> uint32x2_t {
     }
     #[doc = "Vector multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32"))]
    @@ -31365,7 +31365,7 @@ pub fn vmlsq_n_u32(a: uint32x4_t, b: uint32x4_t, c: u32) -> uint32x4_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i8"))]
    @@ -31386,7 +31386,7 @@ pub fn vmls_s8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i8"))]
    @@ -31407,7 +31407,7 @@ pub fn vmlsq_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t) -> int8x16_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16"))]
    @@ -31428,7 +31428,7 @@ pub fn vmls_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16"))]
    @@ -31449,7 +31449,7 @@ pub fn vmlsq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32"))]
    @@ -31470,7 +31470,7 @@ pub fn vmls_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32"))]
    @@ -31491,7 +31491,7 @@ pub fn vmlsq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i8"))]
    @@ -31512,7 +31512,7 @@ pub fn vmls_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i8"))]
    @@ -31533,7 +31533,7 @@ pub fn vmlsq_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16"))]
    @@ -31554,7 +31554,7 @@ pub fn vmls_u16(a: uint16x4_t, b: uint16x4_t, c: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i16"))]
    @@ -31575,7 +31575,7 @@ pub fn vmlsq_u16(a: uint16x8_t, b: uint16x8_t, c: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmls_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32"))]
    @@ -31596,7 +31596,7 @@ pub fn vmls_u32(a: uint32x2_t, b: uint32x2_t, c: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Multiply-subtract from accumulator"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmls.i32"))]
    @@ -31617,7 +31617,7 @@ pub fn vmlsq_u32(a: uint32x4_t, b: uint32x4_t, c: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.s16", LANE = 1))]
    @@ -31646,7 +31646,7 @@ pub fn vmlsl_lane_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t)
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.s16", LANE = 1))]
    @@ -31675,7 +31675,7 @@ pub fn vmlsl_laneq_s16(a: int32x4_t, b: int16x4_t, c: int16x8_t
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.s32", LANE = 1))]
    @@ -31698,7 +31698,7 @@ pub fn vmlsl_lane_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t)
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.s32", LANE = 1))]
    @@ -31721,7 +31721,7 @@ pub fn vmlsl_laneq_s32(a: int64x2_t, b: int32x2_t, c: int32x4_t
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.u16", LANE = 1))]
    @@ -31750,7 +31750,7 @@ pub fn vmlsl_lane_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x4
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.u16", LANE = 1))]
    @@ -31779,7 +31779,7 @@ pub fn vmlsl_laneq_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.u32", LANE = 1))]
    @@ -31802,7 +31802,7 @@ pub fn vmlsl_lane_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x2
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.u32", LANE = 1))]
    @@ -31825,7 +31825,7 @@ pub fn vmlsl_laneq_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.s16"))]
    @@ -31846,7 +31846,7 @@ pub fn vmlsl_n_s16(a: int32x4_t, b: int16x4_t, c: i16) -> int32x4_t {
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.s32"))]
    @@ -31867,7 +31867,7 @@ pub fn vmlsl_n_s32(a: int64x2_t, b: int32x2_t, c: i32) -> int64x2_t {
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.u16"))]
    @@ -31888,7 +31888,7 @@ pub fn vmlsl_n_u16(a: uint32x4_t, b: uint16x4_t, c: u16) -> uint32x4_t {
     }
     #[doc = "Vector widening multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.u32"))]
    @@ -31909,7 +31909,7 @@ pub fn vmlsl_n_u32(a: uint64x2_t, b: uint32x2_t, c: u32) -> uint64x2_t {
     }
     #[doc = "Signed multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.s8"))]
    @@ -31930,7 +31930,7 @@ pub fn vmlsl_s8(a: int16x8_t, b: int8x8_t, c: int8x8_t) -> int16x8_t {
     }
     #[doc = "Signed multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.s16"))]
    @@ -31951,7 +31951,7 @@ pub fn vmlsl_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.s32"))]
    @@ -31972,7 +31972,7 @@ pub fn vmlsl_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.u8"))]
    @@ -31993,7 +31993,7 @@ pub fn vmlsl_u8(a: uint16x8_t, b: uint8x8_t, c: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.u16"))]
    @@ -32014,7 +32014,7 @@ pub fn vmlsl_u16(a: uint32x4_t, b: uint16x4_t, c: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmlsl.u32"))]
    @@ -32035,7 +32035,7 @@ pub fn vmlsl_u32(a: uint64x2_t, b: uint32x2_t, c: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "8-bit integer matrix multiply-accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmmlaq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -32064,7 +32064,7 @@ pub fn vmmlaq_s32(a: int32x4_t, b: int8x16_t, c: int8x16_t) -> int32x4_t {
     }
     #[doc = "8-bit integer matrix multiply-accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmmlaq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -32093,7 +32093,7 @@ pub fn vmmlaq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x16_t) -> uint32x4_t {
     }
     #[doc = "Duplicate element to vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -32109,7 +32109,7 @@ pub fn vmov_n_f16(a: f16) -> float16x4_t {
     }
     #[doc = "Duplicate element to vector"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -32125,7 +32125,7 @@ pub fn vmovq_n_f16(a: f16) -> float16x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -32146,7 +32146,7 @@ pub fn vmov_n_f32(value: f32) -> float32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -32167,7 +32167,7 @@ pub fn vmov_n_p16(value: p16) -> poly16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -32188,7 +32188,7 @@ pub fn vmov_n_p8(value: p8) -> poly8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -32209,7 +32209,7 @@ pub fn vmov_n_s16(value: i16) -> int16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -32230,7 +32230,7 @@ pub fn vmov_n_s32(value: i32) -> int32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -32251,7 +32251,7 @@ pub fn vmov_n_s64(value: i64) -> int64x1_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -32272,7 +32272,7 @@ pub fn vmov_n_s8(value: i8) -> int8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -32293,7 +32293,7 @@ pub fn vmov_n_u16(value: u16) -> uint16x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -32314,7 +32314,7 @@ pub fn vmov_n_u32(value: u32) -> uint32x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -32335,7 +32335,7 @@ pub fn vmov_n_u64(value: u64) -> uint64x1_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -32356,7 +32356,7 @@ pub fn vmov_n_u8(value: u8) -> uint8x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -32377,7 +32377,7 @@ pub fn vmovq_n_f32(value: f32) -> float32x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -32398,7 +32398,7 @@ pub fn vmovq_n_p16(value: p16) -> poly16x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -32419,7 +32419,7 @@ pub fn vmovq_n_p8(value: p8) -> poly8x16_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -32440,7 +32440,7 @@ pub fn vmovq_n_s16(value: i16) -> int16x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -32461,7 +32461,7 @@ pub fn vmovq_n_s32(value: i32) -> int32x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -32482,7 +32482,7 @@ pub fn vmovq_n_s64(value: i64) -> int64x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -32503,7 +32503,7 @@ pub fn vmovq_n_s8(value: i8) -> int8x16_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))]
    @@ -32524,7 +32524,7 @@ pub fn vmovq_n_u16(value: u16) -> uint16x8_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.32"))]
    @@ -32545,7 +32545,7 @@ pub fn vmovq_n_u32(value: u32) -> uint32x4_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmov"))]
    @@ -32566,7 +32566,7 @@ pub fn vmovq_n_u64(value: u64) -> uint64x2_t {
     }
     #[doc = "Duplicate vector element to vector or scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.8"))]
    @@ -32587,7 +32587,7 @@ pub fn vmovq_n_u8(value: u8) -> uint8x16_t {
     }
     #[doc = "Vector long move."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovl))]
    @@ -32608,7 +32608,7 @@ pub fn vmovl_s16(a: int16x4_t) -> int32x4_t {
     }
     #[doc = "Vector long move."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovl))]
    @@ -32629,7 +32629,7 @@ pub fn vmovl_s32(a: int32x2_t) -> int64x2_t {
     }
     #[doc = "Vector long move."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovl))]
    @@ -32650,7 +32650,7 @@ pub fn vmovl_s8(a: int8x8_t) -> int16x8_t {
     }
     #[doc = "Vector long move."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovl))]
    @@ -32671,7 +32671,7 @@ pub fn vmovl_u16(a: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Vector long move."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovl))]
    @@ -32692,7 +32692,7 @@ pub fn vmovl_u32(a: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Vector long move."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovl))]
    @@ -32713,7 +32713,7 @@ pub fn vmovl_u8(a: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Vector narrow integer."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovn))]
    @@ -32734,7 +32734,7 @@ pub fn vmovn_s16(a: int16x8_t) -> int8x8_t {
     }
     #[doc = "Vector narrow integer."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovn))]
    @@ -32755,7 +32755,7 @@ pub fn vmovn_s32(a: int32x4_t) -> int16x4_t {
     }
     #[doc = "Vector narrow integer."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovn))]
    @@ -32776,7 +32776,7 @@ pub fn vmovn_s64(a: int64x2_t) -> int32x2_t {
     }
     #[doc = "Vector narrow integer."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovn))]
    @@ -32797,7 +32797,7 @@ pub fn vmovn_u16(a: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Vector narrow integer."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovn))]
    @@ -32818,7 +32818,7 @@ pub fn vmovn_u32(a: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Vector narrow integer."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovn_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmovn))]
    @@ -32839,7 +32839,7 @@ pub fn vmovn_u64(a: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.f16"))]
     #[cfg_attr(
    @@ -32861,7 +32861,7 @@ pub fn vmul_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.f16"))]
     #[cfg_attr(
    @@ -32883,7 +32883,7 @@ pub fn vmulq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.f32"))]
    @@ -32904,7 +32904,7 @@ pub fn vmul_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.f32"))]
    @@ -32925,7 +32925,7 @@ pub fn vmulq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
     #[cfg_attr(
    @@ -32954,7 +32954,7 @@ pub fn vmul_lane_f16(a: float16x4_t, v: float16x4_t) -> float16
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
     #[cfg_attr(
    @@ -32996,7 +32996,7 @@ pub fn vmulq_lane_f16(a: float16x8_t, v: float16x4_t) -> float1
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 0))]
    @@ -33019,7 +33019,7 @@ pub fn vmul_lane_f32(a: float32x2_t, b: float32x2_t) -> float32
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 0))]
    @@ -33042,7 +33042,7 @@ pub fn vmul_laneq_f32(a: float32x2_t, b: float32x4_t) -> float3
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 0))]
    @@ -33070,7 +33070,7 @@ pub fn vmulq_lane_f32(a: float32x4_t, b: float32x2_t) -> float3
     }
     #[doc = "Floating-point multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 0))]
    @@ -33098,7 +33098,7 @@ pub fn vmulq_laneq_f32(a: float32x4_t, b: float32x4_t) -> float
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33126,7 +33126,7 @@ pub fn vmul_lane_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33167,7 +33167,7 @@ pub fn vmulq_lane_s16(a: int16x8_t, b: int16x4_t) -> int16x8_t
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33190,7 +33190,7 @@ pub fn vmul_lane_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33218,7 +33218,7 @@ pub fn vmulq_lane_s32(a: int32x4_t, b: int32x2_t) -> int32x4_t
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33246,7 +33246,7 @@ pub fn vmul_lane_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33287,7 +33287,7 @@ pub fn vmulq_lane_u16(a: uint16x8_t, b: uint16x4_t) -> uint16x8
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33310,7 +33310,7 @@ pub fn vmul_lane_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33338,7 +33338,7 @@ pub fn vmulq_lane_u32(a: uint32x4_t, b: uint32x2_t) -> uint32x4
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33366,7 +33366,7 @@ pub fn vmul_laneq_s16(a: int16x4_t, b: int16x8_t) -> int16x4_t
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33407,7 +33407,7 @@ pub fn vmulq_laneq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33430,7 +33430,7 @@ pub fn vmul_laneq_s32(a: int32x2_t, b: int32x4_t) -> int32x2_t
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33458,7 +33458,7 @@ pub fn vmulq_laneq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33486,7 +33486,7 @@ pub fn vmul_laneq_u16(a: uint16x4_t, b: uint16x8_t) -> uint16x4
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33527,7 +33527,7 @@ pub fn vmulq_laneq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33550,7 +33550,7 @@ pub fn vmul_laneq_u32(a: uint32x2_t, b: uint32x4_t) -> uint32x2
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul, LANE = 1))]
    @@ -33578,7 +33578,7 @@ pub fn vmulq_laneq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
     #[cfg_attr(
    @@ -33593,7 +33593,7 @@ pub fn vmul_n_f16(a: float16x4_t, b: f16) -> float16x4_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
     #[cfg_attr(
    @@ -33608,7 +33608,7 @@ pub fn vmulq_n_f16(a: float16x8_t, b: f16) -> float16x8_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33629,7 +33629,7 @@ pub fn vmul_n_f32(a: float32x2_t, b: f32) -> float32x2_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33650,7 +33650,7 @@ pub fn vmulq_n_f32(a: float32x4_t, b: f32) -> float32x4_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33671,7 +33671,7 @@ pub fn vmul_n_s16(a: int16x4_t, b: i16) -> int16x4_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33692,7 +33692,7 @@ pub fn vmulq_n_s16(a: int16x8_t, b: i16) -> int16x8_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33713,7 +33713,7 @@ pub fn vmul_n_s32(a: int32x2_t, b: i32) -> int32x2_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33734,7 +33734,7 @@ pub fn vmulq_n_s32(a: int32x4_t, b: i32) -> int32x4_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33755,7 +33755,7 @@ pub fn vmul_n_u16(a: uint16x4_t, b: u16) -> uint16x4_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33776,7 +33776,7 @@ pub fn vmulq_n_u16(a: uint16x8_t, b: u16) -> uint16x8_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33797,7 +33797,7 @@ pub fn vmul_n_u32(a: uint32x2_t, b: u32) -> uint32x2_t {
     }
     #[doc = "Vector multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33818,7 +33818,7 @@ pub fn vmulq_n_u32(a: uint32x4_t, b: u32) -> uint32x4_t {
     }
     #[doc = "Polynomial multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33847,7 +33847,7 @@ pub fn vmul_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Polynomial multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmul))]
    @@ -33876,7 +33876,7 @@ pub fn vmulq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i16"))]
    @@ -33897,7 +33897,7 @@ pub fn vmul_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i16"))]
    @@ -33918,7 +33918,7 @@ pub fn vmulq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i16"))]
    @@ -33939,7 +33939,7 @@ pub fn vmul_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i16"))]
    @@ -33960,7 +33960,7 @@ pub fn vmulq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i32"))]
    @@ -33981,7 +33981,7 @@ pub fn vmul_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i32"))]
    @@ -34002,7 +34002,7 @@ pub fn vmulq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i32"))]
    @@ -34023,7 +34023,7 @@ pub fn vmul_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i32"))]
    @@ -34044,7 +34044,7 @@ pub fn vmulq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i8"))]
    @@ -34065,7 +34065,7 @@ pub fn vmul_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i8"))]
    @@ -34086,7 +34086,7 @@ pub fn vmulq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i8"))]
    @@ -34107,7 +34107,7 @@ pub fn vmul_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Multiply"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmul.i8"))]
    @@ -34128,7 +34128,7 @@ pub fn vmulq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull, LANE = 1))]
    @@ -34156,7 +34156,7 @@ pub fn vmull_lane_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t
     }
     #[doc = "Vector long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull, LANE = 1))]
    @@ -34184,7 +34184,7 @@ pub fn vmull_laneq_s16(a: int16x4_t, b: int16x8_t) -> int32x4_t
     }
     #[doc = "Vector long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull, LANE = 1))]
    @@ -34207,7 +34207,7 @@ pub fn vmull_lane_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t
     }
     #[doc = "Vector long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull, LANE = 1))]
    @@ -34230,7 +34230,7 @@ pub fn vmull_laneq_s32(a: int32x2_t, b: int32x4_t) -> int64x2_t
     }
     #[doc = "Vector long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull, LANE = 1))]
    @@ -34258,7 +34258,7 @@ pub fn vmull_lane_u16(a: uint16x4_t, b: uint16x4_t) -> uint32x4
     }
     #[doc = "Vector long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_laneq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull, LANE = 1))]
    @@ -34286,7 +34286,7 @@ pub fn vmull_laneq_u16(a: uint16x4_t, b: uint16x8_t) -> uint32x
     }
     #[doc = "Vector long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull, LANE = 1))]
    @@ -34309,7 +34309,7 @@ pub fn vmull_lane_u32(a: uint32x2_t, b: uint32x2_t) -> uint64x2
     }
     #[doc = "Vector long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_laneq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull, LANE = 1))]
    @@ -34332,7 +34332,7 @@ pub fn vmull_laneq_u32(a: uint32x2_t, b: uint32x4_t) -> uint64x
     }
     #[doc = "Vector long multiply with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull))]
    @@ -34353,7 +34353,7 @@ pub fn vmull_n_s16(a: int16x4_t, b: i16) -> int32x4_t {
     }
     #[doc = "Vector long multiply with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull))]
    @@ -34374,7 +34374,7 @@ pub fn vmull_n_s32(a: int32x2_t, b: i32) -> int64x2_t {
     }
     #[doc = "Vector long multiply with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull))]
    @@ -34395,7 +34395,7 @@ pub fn vmull_n_u16(a: uint16x4_t, b: u16) -> uint32x4_t {
     }
     #[doc = "Vector long multiply with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmull))]
    @@ -34416,7 +34416,7 @@ pub fn vmull_n_u32(a: uint32x2_t, b: u32) -> uint64x2_t {
     }
     #[doc = "Polynomial multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmull.p8"))]
    @@ -34445,7 +34445,7 @@ pub fn vmull_p8(a: poly8x8_t, b: poly8x8_t) -> poly16x8_t {
     }
     #[doc = "Signed multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmull.s16"))]
    @@ -34474,7 +34474,7 @@ pub fn vmull_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmull.s32"))]
    @@ -34503,7 +34503,7 @@ pub fn vmull_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t {
     }
     #[doc = "Signed multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmull.s8"))]
    @@ -34532,7 +34532,7 @@ pub fn vmull_s8(a: int8x8_t, b: int8x8_t) -> int16x8_t {
     }
     #[doc = "Unsigned multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmull.u8"))]
    @@ -34561,7 +34561,7 @@ pub fn vmull_u8(a: uint8x8_t, b: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmull.u16"))]
    @@ -34590,7 +34590,7 @@ pub fn vmull_u16(a: uint16x4_t, b: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vmull.u32"))]
    @@ -34619,7 +34619,7 @@ pub fn vmull_u32(a: uint32x2_t, b: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34641,7 +34641,7 @@ pub fn vmvn_p8(a: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34663,7 +34663,7 @@ pub fn vmvn_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34685,7 +34685,7 @@ pub fn vmvn_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34707,7 +34707,7 @@ pub fn vmvn_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34729,7 +34729,7 @@ pub fn vmvn_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34751,7 +34751,7 @@ pub fn vmvn_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34773,7 +34773,7 @@ pub fn vmvn_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34795,7 +34795,7 @@ pub fn vmvnq_p8(a: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34817,7 +34817,7 @@ pub fn vmvnq_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34839,7 +34839,7 @@ pub fn vmvnq_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34861,7 +34861,7 @@ pub fn vmvnq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34883,7 +34883,7 @@ pub fn vmvnq_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34905,7 +34905,7 @@ pub fn vmvnq_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector bitwise not."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vmvn))]
    @@ -34927,7 +34927,7 @@ pub fn vmvnq_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.f16"))]
     #[cfg_attr(
    @@ -34949,7 +34949,7 @@ pub fn vneg_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.f16"))]
     #[cfg_attr(
    @@ -34971,7 +34971,7 @@ pub fn vnegq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.f32"))]
    @@ -34992,7 +34992,7 @@ pub fn vneg_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.f32"))]
    @@ -35013,7 +35013,7 @@ pub fn vnegq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.s8"))]
    @@ -35034,7 +35034,7 @@ pub fn vneg_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.s8"))]
    @@ -35055,7 +35055,7 @@ pub fn vnegq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.s16"))]
    @@ -35076,7 +35076,7 @@ pub fn vneg_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.s16"))]
    @@ -35097,7 +35097,7 @@ pub fn vnegq_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.s32"))]
    @@ -35118,7 +35118,7 @@ pub fn vneg_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vneg.s32"))]
    @@ -35139,7 +35139,7 @@ pub fn vnegq_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35161,7 +35161,7 @@ pub fn vorn_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35183,7 +35183,7 @@ pub fn vorn_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35205,7 +35205,7 @@ pub fn vorn_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35227,7 +35227,7 @@ pub fn vorn_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35249,7 +35249,7 @@ pub fn vornq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35271,7 +35271,7 @@ pub fn vornq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35293,7 +35293,7 @@ pub fn vornq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35315,7 +35315,7 @@ pub fn vornq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35337,7 +35337,7 @@ pub fn vorn_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35359,7 +35359,7 @@ pub fn vorn_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35381,7 +35381,7 @@ pub fn vorn_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35403,7 +35403,7 @@ pub fn vorn_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35425,7 +35425,7 @@ pub fn vornq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35447,7 +35447,7 @@ pub fn vornq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35469,7 +35469,7 @@ pub fn vornq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector bitwise inclusive OR NOT"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorn))]
    @@ -35491,7 +35491,7 @@ pub fn vornq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35512,7 +35512,7 @@ pub fn vorr_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35533,7 +35533,7 @@ pub fn vorrq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35554,7 +35554,7 @@ pub fn vorr_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35575,7 +35575,7 @@ pub fn vorrq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35596,7 +35596,7 @@ pub fn vorr_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35617,7 +35617,7 @@ pub fn vorrq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35638,7 +35638,7 @@ pub fn vorr_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35659,7 +35659,7 @@ pub fn vorrq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35680,7 +35680,7 @@ pub fn vorr_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35701,7 +35701,7 @@ pub fn vorrq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35722,7 +35722,7 @@ pub fn vorr_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35743,7 +35743,7 @@ pub fn vorrq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35764,7 +35764,7 @@ pub fn vorr_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35785,7 +35785,7 @@ pub fn vorrq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35806,7 +35806,7 @@ pub fn vorr_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Vector bitwise or (immediate, inclusive)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -35827,7 +35827,7 @@ pub fn vorrq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadal_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.s8"))]
    @@ -35857,7 +35857,7 @@ pub fn vpadal_s8(a: int16x4_t, b: int8x8_t) -> int16x4_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadalq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.s8"))]
    @@ -35887,7 +35887,7 @@ pub fn vpadalq_s8(a: int16x8_t, b: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadal_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.s16"))]
    @@ -35917,7 +35917,7 @@ pub fn vpadal_s16(a: int32x2_t, b: int16x4_t) -> int32x2_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadalq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.s16"))]
    @@ -35947,7 +35947,7 @@ pub fn vpadalq_s16(a: int32x4_t, b: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadal_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.s32"))]
    @@ -35977,7 +35977,7 @@ pub fn vpadal_s32(a: int64x1_t, b: int32x2_t) -> int64x1_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadalq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.s32"))]
    @@ -36007,7 +36007,7 @@ pub fn vpadalq_s32(a: int64x2_t, b: int32x4_t) -> int64x2_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadal_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.u8"))]
    @@ -36037,7 +36037,7 @@ pub fn vpadal_u8(a: uint16x4_t, b: uint8x8_t) -> uint16x4_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadalq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.u8"))]
    @@ -36067,7 +36067,7 @@ pub fn vpadalq_u8(a: uint16x8_t, b: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadal_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.u16"))]
    @@ -36097,7 +36097,7 @@ pub fn vpadal_u16(a: uint32x2_t, b: uint16x4_t) -> uint32x2_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadalq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.u16"))]
    @@ -36127,7 +36127,7 @@ pub fn vpadalq_u16(a: uint32x4_t, b: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadal_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.u32"))]
    @@ -36157,7 +36157,7 @@ pub fn vpadal_u32(a: uint64x1_t, b: uint32x2_t) -> uint64x1_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadalq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpadal.u32"))]
    @@ -36187,7 +36187,7 @@ pub fn vpadalq_u32(a: uint64x2_t, b: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpadd))]
     #[cfg_attr(
    @@ -36217,7 +36217,7 @@ pub fn vpadd_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point add pairwise"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpadd))]
    @@ -36246,7 +36246,7 @@ pub fn vpadd_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Add pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpadd))]
    @@ -36275,7 +36275,7 @@ pub fn vpadd_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Add pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpadd))]
    @@ -36304,7 +36304,7 @@ pub fn vpadd_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Add pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpadd))]
    @@ -36333,7 +36333,7 @@ pub fn vpadd_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Add pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -36355,7 +36355,7 @@ pub fn vpadd_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Add pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -36382,7 +36382,7 @@ pub fn vpadd_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Add pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -36404,7 +36404,7 @@ pub fn vpadd_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Add pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -36431,7 +36431,7 @@ pub fn vpadd_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Add pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -36453,7 +36453,7 @@ pub fn vpadd_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Add pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpadd_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -36480,7 +36480,7 @@ pub fn vpadd_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.s8"))]
    @@ -36509,7 +36509,7 @@ pub fn vpaddl_s8(a: int8x8_t) -> int16x4_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddlq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.s8"))]
    @@ -36538,7 +36538,7 @@ pub fn vpaddlq_s8(a: int8x16_t) -> int16x8_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.s16"))]
    @@ -36567,7 +36567,7 @@ pub fn vpaddl_s16(a: int16x4_t) -> int32x2_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddlq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.s16"))]
    @@ -36596,7 +36596,7 @@ pub fn vpaddlq_s16(a: int16x8_t) -> int32x4_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.s32"))]
    @@ -36625,7 +36625,7 @@ pub fn vpaddl_s32(a: int32x2_t) -> int64x1_t {
     }
     #[doc = "Signed Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddlq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.s32"))]
    @@ -36654,7 +36654,7 @@ pub fn vpaddlq_s32(a: int32x4_t) -> int64x2_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.u8"))]
    @@ -36683,7 +36683,7 @@ pub fn vpaddl_u8(a: uint8x8_t) -> uint16x4_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddlq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.u8"))]
    @@ -36712,7 +36712,7 @@ pub fn vpaddlq_u8(a: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.u16"))]
    @@ -36741,7 +36741,7 @@ pub fn vpaddl_u16(a: uint16x4_t) -> uint32x2_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddlq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.u16"))]
    @@ -36770,7 +36770,7 @@ pub fn vpaddlq_u16(a: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.u32"))]
    @@ -36799,7 +36799,7 @@ pub fn vpaddl_u32(a: uint32x2_t) -> uint64x1_t {
     }
     #[doc = "Unsigned Add and Accumulate Long Pairwise."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddlq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vpaddl.u32"))]
    @@ -36828,7 +36828,7 @@ pub fn vpaddlq_u32(a: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmax_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmax))]
    @@ -36857,7 +36857,7 @@ pub fn vpmax_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmax_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmax))]
    @@ -36886,7 +36886,7 @@ pub fn vpmax_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmax_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmax))]
    @@ -36915,7 +36915,7 @@ pub fn vpmax_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmax_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmax))]
    @@ -36944,7 +36944,7 @@ pub fn vpmax_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmax_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmax))]
    @@ -36973,7 +36973,7 @@ pub fn vpmax_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmax_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmax))]
    @@ -37002,7 +37002,7 @@ pub fn vpmax_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Folding maximum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmax_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmax))]
    @@ -37031,7 +37031,7 @@ pub fn vpmax_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmin_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmin))]
    @@ -37060,7 +37060,7 @@ pub fn vpmin_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmin_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmin))]
    @@ -37089,7 +37089,7 @@ pub fn vpmin_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmin_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmin))]
    @@ -37118,7 +37118,7 @@ pub fn vpmin_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmin_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmin))]
    @@ -37147,7 +37147,7 @@ pub fn vpmin_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmin_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmin))]
    @@ -37176,7 +37176,7 @@ pub fn vpmin_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmin_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmin))]
    @@ -37205,7 +37205,7 @@ pub fn vpmin_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Folding minimum of adjacent pairs"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmin_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vpmin))]
    @@ -37234,7 +37234,7 @@ pub fn vpmin_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating Absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabs_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqabs.s8"))]
    @@ -37263,7 +37263,7 @@ pub fn vqabs_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating Absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqabs.s8"))]
    @@ -37292,7 +37292,7 @@ pub fn vqabsq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed saturating Absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabs_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqabs.s16"))]
    @@ -37321,7 +37321,7 @@ pub fn vqabs_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating Absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqabs.s16"))]
    @@ -37350,7 +37350,7 @@ pub fn vqabsq_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating Absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabs_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqabs.s32"))]
    @@ -37379,7 +37379,7 @@ pub fn vqabs_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating Absolute value"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqabsq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqabs.s32"))]
    @@ -37408,7 +37408,7 @@ pub fn vqabsq_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.s8"))]
    @@ -37429,7 +37429,7 @@ pub fn vqadd_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.s8"))]
    @@ -37450,7 +37450,7 @@ pub fn vqaddq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.s16"))]
    @@ -37471,7 +37471,7 @@ pub fn vqadd_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.s16"))]
    @@ -37492,7 +37492,7 @@ pub fn vqaddq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.s32"))]
    @@ -37513,7 +37513,7 @@ pub fn vqadd_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.s32"))]
    @@ -37534,7 +37534,7 @@ pub fn vqaddq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.s64"))]
    @@ -37555,7 +37555,7 @@ pub fn vqadd_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.s64"))]
    @@ -37576,7 +37576,7 @@ pub fn vqaddq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.u8"))]
    @@ -37597,7 +37597,7 @@ pub fn vqadd_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.u8"))]
    @@ -37618,7 +37618,7 @@ pub fn vqaddq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.u16"))]
    @@ -37639,7 +37639,7 @@ pub fn vqadd_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.u16"))]
    @@ -37660,7 +37660,7 @@ pub fn vqaddq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.u32"))]
    @@ -37681,7 +37681,7 @@ pub fn vqadd_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.u32"))]
    @@ -37702,7 +37702,7 @@ pub fn vqaddq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqadd_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.u64"))]
    @@ -37723,7 +37723,7 @@ pub fn vqadd_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Saturating add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqaddq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqadd.u64"))]
    @@ -37744,7 +37744,7 @@ pub fn vqaddq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector widening saturating doubling multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlal, N = 2))]
    @@ -37767,7 +37767,7 @@ pub fn vqdmlal_lane_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t)
     }
     #[doc = "Vector widening saturating doubling multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlal, N = 1))]
    @@ -37790,7 +37790,7 @@ pub fn vqdmlal_lane_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t)
     }
     #[doc = "Vector widening saturating doubling multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlal))]
    @@ -37811,7 +37811,7 @@ pub fn vqdmlal_n_s16(a: int32x4_t, b: int16x4_t, c: i16) -> int32x4_t {
     }
     #[doc = "Vector widening saturating doubling multiply accumulate with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlal))]
    @@ -37832,7 +37832,7 @@ pub fn vqdmlal_n_s32(a: int64x2_t, b: int32x2_t, c: i32) -> int64x2_t {
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlal))]
    @@ -37853,7 +37853,7 @@ pub fn vqdmlal_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply-add long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlal_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlal))]
    @@ -37874,7 +37874,7 @@ pub fn vqdmlal_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t {
     }
     #[doc = "Vector widening saturating doubling multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlsl, N = 2))]
    @@ -37897,7 +37897,7 @@ pub fn vqdmlsl_lane_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t)
     }
     #[doc = "Vector widening saturating doubling multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlsl, N = 1))]
    @@ -37920,7 +37920,7 @@ pub fn vqdmlsl_lane_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t)
     }
     #[doc = "Vector widening saturating doubling multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlsl))]
    @@ -37941,7 +37941,7 @@ pub fn vqdmlsl_n_s16(a: int32x4_t, b: int16x4_t, c: i16) -> int32x4_t {
     }
     #[doc = "Vector widening saturating doubling multiply subtract with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlsl))]
    @@ -37962,7 +37962,7 @@ pub fn vqdmlsl_n_s32(a: int64x2_t, b: int32x2_t, c: i32) -> int64x2_t {
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlsl))]
    @@ -37983,7 +37983,7 @@ pub fn vqdmlsl_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply-subtract long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmlsl))]
    @@ -38004,7 +38004,7 @@ pub fn vqdmlsl_s32(a: int64x2_t, b: int32x2_t, c: int32x2_t) -> int64x2_t {
     }
     #[doc = "Vector saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh, LANE = 0))]
    @@ -38027,7 +38027,7 @@ pub fn vqdmulh_laneq_s16(a: int16x4_t, b: int16x8_t) -> int16x4
     }
     #[doc = "Vector saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh, LANE = 0))]
    @@ -38050,7 +38050,7 @@ pub fn vqdmulhq_laneq_s16(a: int16x8_t, b: int16x8_t) -> int16x
     }
     #[doc = "Vector saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh, LANE = 0))]
    @@ -38073,7 +38073,7 @@ pub fn vqdmulh_laneq_s32(a: int32x2_t, b: int32x4_t) -> int32x2
     }
     #[doc = "Vector saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh, LANE = 0))]
    @@ -38096,7 +38096,7 @@ pub fn vqdmulhq_laneq_s32(a: int32x4_t, b: int32x4_t) -> int32x
     }
     #[doc = "Vector saturating doubling multiply high with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh))]
    @@ -38118,7 +38118,7 @@ pub fn vqdmulh_n_s16(a: int16x4_t, b: i16) -> int16x4_t {
     }
     #[doc = "Vector saturating doubling multiply high with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh))]
    @@ -38140,7 +38140,7 @@ pub fn vqdmulhq_n_s16(a: int16x8_t, b: i16) -> int16x8_t {
     }
     #[doc = "Vector saturating doubling multiply high with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh))]
    @@ -38162,7 +38162,7 @@ pub fn vqdmulh_n_s32(a: int32x2_t, b: i32) -> int32x2_t {
     }
     #[doc = "Vector saturating doubling multiply high with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh))]
    @@ -38184,7 +38184,7 @@ pub fn vqdmulhq_n_s32(a: int32x4_t, b: i32) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh))]
    @@ -38213,7 +38213,7 @@ pub fn vqdmulh_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh))]
    @@ -38242,7 +38242,7 @@ pub fn vqdmulhq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh))]
    @@ -38271,7 +38271,7 @@ pub fn vqdmulh_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulhq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmulh))]
    @@ -38300,7 +38300,7 @@ pub fn vqdmulhq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector saturating doubling long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmull, N = 2))]
    @@ -38326,7 +38326,7 @@ pub fn vqdmull_lane_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t {
     }
     #[doc = "Vector saturating doubling long multiply by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmull, N = 1))]
    @@ -38352,7 +38352,7 @@ pub fn vqdmull_lane_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t {
     }
     #[doc = "Vector saturating doubling long multiply with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmull))]
    @@ -38373,7 +38373,7 @@ pub fn vqdmull_n_s16(a: int16x4_t, b: i16) -> int32x4_t {
     }
     #[doc = "Vector saturating doubling long multiply with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmull))]
    @@ -38394,7 +38394,7 @@ pub fn vqdmull_n_s32(a: int32x2_t, b: i32) -> int64x2_t {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmull))]
    @@ -38423,7 +38423,7 @@ pub fn vqdmull_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating doubling multiply long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmull_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqdmull))]
    @@ -38452,7 +38452,7 @@ pub fn vqdmull_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t {
     }
     #[doc = "Signed saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
    @@ -38481,7 +38481,7 @@ pub fn vqmovn_s16(a: int16x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
    @@ -38510,7 +38510,7 @@ pub fn vqmovn_s32(a: int32x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
    @@ -38539,7 +38539,7 @@ pub fn vqmovn_s64(a: int64x2_t) -> int32x2_t {
     }
     #[doc = "Unsigned saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
    @@ -38568,7 +38568,7 @@ pub fn vqmovn_u16(a: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
    @@ -38597,7 +38597,7 @@ pub fn vqmovn_u32(a: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned saturating extract narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovn_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
    @@ -38626,7 +38626,7 @@ pub fn vqmovn_u64(a: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating extract unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovun))]
    @@ -38655,7 +38655,7 @@ pub fn vqmovun_s16(a: int16x8_t) -> uint8x8_t {
     }
     #[doc = "Signed saturating extract unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovun))]
    @@ -38684,7 +38684,7 @@ pub fn vqmovun_s32(a: int32x4_t) -> uint16x4_t {
     }
     #[doc = "Signed saturating extract unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqmovun_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovun))]
    @@ -38713,7 +38713,7 @@ pub fn vqmovun_s64(a: int64x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqneg.s8"))]
    @@ -38742,7 +38742,7 @@ pub fn vqneg_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqneg.s8"))]
    @@ -38771,7 +38771,7 @@ pub fn vqnegq_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqneg.s16"))]
    @@ -38800,7 +38800,7 @@ pub fn vqneg_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqneg.s16"))]
    @@ -38829,7 +38829,7 @@ pub fn vqnegq_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqneg.s32"))]
    @@ -38858,7 +38858,7 @@ pub fn vqneg_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating negate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqneg.s32"))]
    @@ -38887,7 +38887,7 @@ pub fn vqnegq_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Vector rounding saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh, LANE = 1))]
    @@ -38914,7 +38914,7 @@ pub fn vqrdmulh_lane_s16(a: int16x4_t, b: int16x4_t) -> int16x4
     }
     #[doc = "Vector rounding saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh, LANE = 1))]
    @@ -38940,7 +38940,7 @@ pub fn vqrdmulh_lane_s32(a: int32x2_t, b: int32x2_t) -> int32x2
     }
     #[doc = "Vector rounding saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh, LANE = 1))]
    @@ -38967,7 +38967,7 @@ pub fn vqrdmulh_laneq_s16(a: int16x4_t, b: int16x8_t) -> int16x
     }
     #[doc = "Vector rounding saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh, LANE = 1))]
    @@ -38993,7 +38993,7 @@ pub fn vqrdmulh_laneq_s32(a: int32x2_t, b: int32x4_t) -> int32x
     }
     #[doc = "Vector rounding saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh, LANE = 1))]
    @@ -39032,7 +39032,7 @@ pub fn vqrdmulhq_lane_s16(a: int16x8_t, b: int16x4_t) -> int16x
     }
     #[doc = "Vector rounding saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh, LANE = 1))]
    @@ -39059,7 +39059,7 @@ pub fn vqrdmulhq_lane_s32(a: int32x4_t, b: int32x2_t) -> int32x
     }
     #[doc = "Vector rounding saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_laneq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh, LANE = 1))]
    @@ -39098,7 +39098,7 @@ pub fn vqrdmulhq_laneq_s16(a: int16x8_t, b: int16x8_t) -> int16
     }
     #[doc = "Vector rounding saturating doubling multiply high by scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_laneq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh, LANE = 1))]
    @@ -39125,7 +39125,7 @@ pub fn vqrdmulhq_laneq_s32(a: int32x4_t, b: int32x4_t) -> int32
     }
     #[doc = "Vector saturating rounding doubling multiply high with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh))]
    @@ -39146,7 +39146,7 @@ pub fn vqrdmulh_n_s16(a: int16x4_t, b: i16) -> int16x4_t {
     }
     #[doc = "Vector saturating rounding doubling multiply high with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh))]
    @@ -39167,7 +39167,7 @@ pub fn vqrdmulhq_n_s16(a: int16x8_t, b: i16) -> int16x8_t {
     }
     #[doc = "Vector saturating rounding doubling multiply high with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh))]
    @@ -39188,7 +39188,7 @@ pub fn vqrdmulh_n_s32(a: int32x2_t, b: i32) -> int32x2_t {
     }
     #[doc = "Vector saturating rounding doubling multiply high with scalar"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh))]
    @@ -39209,7 +39209,7 @@ pub fn vqrdmulhq_n_s32(a: int32x4_t, b: i32) -> int32x4_t {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh))]
    @@ -39238,7 +39238,7 @@ pub fn vqrdmulh_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh))]
    @@ -39267,7 +39267,7 @@ pub fn vqrdmulhq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulh_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh))]
    @@ -39296,7 +39296,7 @@ pub fn vqrdmulh_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating rounding doubling multiply returning high half"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrdmulhq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrdmulh))]
    @@ -39325,7 +39325,7 @@ pub fn vqrdmulhq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39354,7 +39354,7 @@ pub fn vqrshl_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39383,7 +39383,7 @@ pub fn vqrshlq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39412,7 +39412,7 @@ pub fn vqrshl_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39441,7 +39441,7 @@ pub fn vqrshlq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39470,7 +39470,7 @@ pub fn vqrshl_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39499,7 +39499,7 @@ pub fn vqrshlq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39528,7 +39528,7 @@ pub fn vqrshl_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39557,7 +39557,7 @@ pub fn vqrshlq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39586,7 +39586,7 @@ pub fn vqrshl_u8(a: uint8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39615,7 +39615,7 @@ pub fn vqrshlq_u8(a: uint8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39644,7 +39644,7 @@ pub fn vqrshl_u16(a: uint16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39673,7 +39673,7 @@ pub fn vqrshlq_u16(a: uint16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39702,7 +39702,7 @@ pub fn vqrshl_u32(a: uint32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39731,7 +39731,7 @@ pub fn vqrshlq_u32(a: uint32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshl_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39760,7 +39760,7 @@ pub fn vqrshl_u64(a: uint64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned signed saturating rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshlq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqrshl))]
    @@ -39789,7 +39789,7 @@ pub fn vqrshlq_u64(a: uint64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqrshrn, N = 2))]
    @@ -39805,7 +39805,7 @@ pub fn vqrshrn_n_s16(a: int16x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqrshrn, N = 2))]
    @@ -39821,7 +39821,7 @@ pub fn vqrshrn_n_s32(a: int32x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqrshrn, N = 2))]
    @@ -39837,7 +39837,7 @@ pub fn vqrshrn_n_s64(a: int64x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqrshrn, N = 2))]
    @@ -39856,7 +39856,7 @@ pub fn vqrshrn_n_s16(a: int16x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqrshrn, N = 2))]
    @@ -39875,7 +39875,7 @@ pub fn vqrshrn_n_s32(a: int32x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqrshrn, N = 2))]
    @@ -39894,7 +39894,7 @@ pub fn vqrshrn_n_s64(a: int64x2_t) -> int32x2_t {
     }
     #[doc = "Unsigned signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqrshrn, N = 2))]
    @@ -39920,7 +39920,7 @@ pub fn vqrshrn_n_u16(a: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqrshrn, N = 2))]
    @@ -39941,7 +39941,7 @@ pub fn vqrshrn_n_u32(a: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqrshrn, N = 2))]
    @@ -39957,7 +39957,7 @@ pub fn vqrshrn_n_u64(a: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(uqrshrn, N = 2))]
    @@ -39976,7 +39976,7 @@ pub fn vqrshrn_n_u16(a: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(uqrshrn, N = 2))]
    @@ -39995,7 +39995,7 @@ pub fn vqrshrn_n_u32(a: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned signed saturating rounded shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(uqrshrn, N = 2))]
    @@ -40014,7 +40014,7 @@ pub fn vqrshrn_n_u64(a: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqrshrun, N = 2))]
    @@ -40030,7 +40030,7 @@ pub fn vqrshrun_n_s16(a: int16x8_t) -> uint8x8_t {
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqrshrun, N = 2))]
    @@ -40046,7 +40046,7 @@ pub fn vqrshrun_n_s32(a: int32x4_t) -> uint16x4_t {
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqrshrun, N = 2))]
    @@ -40062,7 +40062,7 @@ pub fn vqrshrun_n_s64(a: int64x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqrshrun, N = 2))]
    @@ -40081,7 +40081,7 @@ pub fn vqrshrun_n_s16(a: int16x8_t) -> uint8x8_t {
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqrshrun, N = 2))]
    @@ -40100,7 +40100,7 @@ pub fn vqrshrun_n_s32(a: int32x4_t) -> uint16x4_t {
     }
     #[doc = "Signed saturating rounded shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrun_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqrshrun, N = 2))]
    @@ -40119,7 +40119,7 @@ pub fn vqrshrun_n_s64(a: int64x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40142,7 +40142,7 @@ pub fn vqshl_n_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40165,7 +40165,7 @@ pub fn vqshlq_n_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40188,7 +40188,7 @@ pub fn vqshl_n_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40211,7 +40211,7 @@ pub fn vqshlq_n_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40234,7 +40234,7 @@ pub fn vqshl_n_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40257,7 +40257,7 @@ pub fn vqshlq_n_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40280,7 +40280,7 @@ pub fn vqshl_n_s64(a: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40303,7 +40303,7 @@ pub fn vqshlq_n_s64(a: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40326,7 +40326,7 @@ pub fn vqshl_n_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40349,7 +40349,7 @@ pub fn vqshlq_n_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40372,7 +40372,7 @@ pub fn vqshl_n_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40395,7 +40395,7 @@ pub fn vqshlq_n_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40418,7 +40418,7 @@ pub fn vqshl_n_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40441,7 +40441,7 @@ pub fn vqshlq_n_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40464,7 +40464,7 @@ pub fn vqshl_n_u64(a: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl, N = 2))]
    @@ -40487,7 +40487,7 @@ pub fn vqshlq_n_u64(a: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40516,7 +40516,7 @@ pub fn vqshl_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40545,7 +40545,7 @@ pub fn vqshlq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40574,7 +40574,7 @@ pub fn vqshl_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40603,7 +40603,7 @@ pub fn vqshlq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40632,7 +40632,7 @@ pub fn vqshl_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40661,7 +40661,7 @@ pub fn vqshlq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40690,7 +40690,7 @@ pub fn vqshl_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40719,7 +40719,7 @@ pub fn vqshlq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40748,7 +40748,7 @@ pub fn vqshl_u8(a: uint8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40777,7 +40777,7 @@ pub fn vqshlq_u8(a: uint8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40806,7 +40806,7 @@ pub fn vqshl_u16(a: uint16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40835,7 +40835,7 @@ pub fn vqshlq_u16(a: uint16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40864,7 +40864,7 @@ pub fn vqshl_u32(a: uint32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40893,7 +40893,7 @@ pub fn vqshlq_u32(a: uint32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshl_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40922,7 +40922,7 @@ pub fn vqshl_u64(a: uint64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned saturating shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqshl))]
    @@ -40951,7 +40951,7 @@ pub fn vqshlq_u64(a: uint64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshlu, N = 2))]
    @@ -40967,7 +40967,7 @@ pub fn vqshlu_n_s8(a: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshlu, N = 2))]
    @@ -40983,7 +40983,7 @@ pub fn vqshluq_n_s8(a: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshlu, N = 2))]
    @@ -40999,7 +40999,7 @@ pub fn vqshlu_n_s16(a: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshlu, N = 2))]
    @@ -41015,7 +41015,7 @@ pub fn vqshluq_n_s16(a: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshlu, N = 2))]
    @@ -41031,7 +41031,7 @@ pub fn vqshlu_n_s32(a: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshlu, N = 2))]
    @@ -41047,7 +41047,7 @@ pub fn vqshluq_n_s32(a: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshlu, N = 2))]
    @@ -41063,7 +41063,7 @@ pub fn vqshlu_n_s64(a: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshlu, N = 2))]
    @@ -41079,7 +41079,7 @@ pub fn vqshluq_n_s64(a: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
    @@ -41098,7 +41098,7 @@ pub fn vqshlu_n_s8(a: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
    @@ -41117,7 +41117,7 @@ pub fn vqshluq_n_s8(a: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
    @@ -41136,7 +41136,7 @@ pub fn vqshlu_n_s16(a: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
    @@ -41155,7 +41155,7 @@ pub fn vqshluq_n_s16(a: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
    @@ -41174,7 +41174,7 @@ pub fn vqshlu_n_s32(a: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
    @@ -41193,7 +41193,7 @@ pub fn vqshluq_n_s32(a: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
    @@ -41212,7 +41212,7 @@ pub fn vqshlu_n_s64(a: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Signed saturating shift left unsigned"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshlu, N = 2))]
    @@ -41231,7 +41231,7 @@ pub fn vqshluq_n_s64(a: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshrn, N = 2))]
    @@ -41247,7 +41247,7 @@ pub fn vqshrn_n_s16(a: int16x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshrn, N = 2))]
    @@ -41263,7 +41263,7 @@ pub fn vqshrn_n_s32(a: int32x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshrn, N = 2))]
    @@ -41279,7 +41279,7 @@ pub fn vqshrn_n_s64(a: int64x2_t) -> int32x2_t {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshrn, N = 2))]
    @@ -41298,7 +41298,7 @@ pub fn vqshrn_n_s16(a: int16x8_t) -> int8x8_t {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshrn, N = 2))]
    @@ -41317,7 +41317,7 @@ pub fn vqshrn_n_s32(a: int32x4_t) -> int16x4_t {
     }
     #[doc = "Signed saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshrn, N = 2))]
    @@ -41336,7 +41336,7 @@ pub fn vqshrn_n_s64(a: int64x2_t) -> int32x2_t {
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshrn, N = 2))]
    @@ -41362,7 +41362,7 @@ pub fn vqshrn_n_u16(a: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshrn, N = 2))]
    @@ -41383,7 +41383,7 @@ pub fn vqshrn_n_u32(a: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshrn, N = 2))]
    @@ -41399,7 +41399,7 @@ pub fn vqshrn_n_u64(a: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(uqshrn, N = 2))]
    @@ -41418,7 +41418,7 @@ pub fn vqshrn_n_u16(a: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(uqshrn, N = 2))]
    @@ -41437,7 +41437,7 @@ pub fn vqshrn_n_u32(a: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned saturating shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(uqshrn, N = 2))]
    @@ -41456,7 +41456,7 @@ pub fn vqshrn_n_u64(a: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshrun, N = 2))]
    @@ -41472,7 +41472,7 @@ pub fn vqshrun_n_s16(a: int16x8_t) -> uint8x8_t {
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshrun, N = 2))]
    @@ -41488,7 +41488,7 @@ pub fn vqshrun_n_s32(a: int32x4_t) -> uint16x4_t {
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vqshrun, N = 2))]
    @@ -41504,7 +41504,7 @@ pub fn vqshrun_n_s64(a: int64x2_t) -> uint32x2_t {
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshrun, N = 2))]
    @@ -41523,7 +41523,7 @@ pub fn vqshrun_n_s16(a: int16x8_t) -> uint8x8_t {
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshrun, N = 2))]
    @@ -41542,7 +41542,7 @@ pub fn vqshrun_n_s32(a: int32x4_t) -> uint16x4_t {
     }
     #[doc = "Signed saturating shift right unsigned narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrun_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(sqshrun, N = 2))]
    @@ -41561,7 +41561,7 @@ pub fn vqshrun_n_s64(a: int64x2_t) -> uint32x2_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.s8"))]
    @@ -41582,7 +41582,7 @@ pub fn vqsub_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.s8"))]
    @@ -41603,7 +41603,7 @@ pub fn vqsubq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.s16"))]
    @@ -41624,7 +41624,7 @@ pub fn vqsub_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.s16"))]
    @@ -41645,7 +41645,7 @@ pub fn vqsubq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.s32"))]
    @@ -41666,7 +41666,7 @@ pub fn vqsub_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.s32"))]
    @@ -41687,7 +41687,7 @@ pub fn vqsubq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.s64"))]
    @@ -41708,7 +41708,7 @@ pub fn vqsub_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.s64"))]
    @@ -41729,7 +41729,7 @@ pub fn vqsubq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.u8"))]
    @@ -41750,7 +41750,7 @@ pub fn vqsub_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.u8"))]
    @@ -41771,7 +41771,7 @@ pub fn vqsubq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.u16"))]
    @@ -41792,7 +41792,7 @@ pub fn vqsub_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.u16"))]
    @@ -41813,7 +41813,7 @@ pub fn vqsubq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.u32"))]
    @@ -41834,7 +41834,7 @@ pub fn vqsub_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.u32"))]
    @@ -41855,7 +41855,7 @@ pub fn vqsubq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsub_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.u64"))]
    @@ -41876,7 +41876,7 @@ pub fn vqsub_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Saturating subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqsubq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vqsub.u64"))]
    @@ -41897,7 +41897,7 @@ pub fn vqsubq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Rounding Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vraddhn.i16"))]
    @@ -41919,7 +41919,7 @@ pub fn vraddhn_high_s16(a: int8x8_t, b: int16x8_t, c: int16x8_t) -> int8x16_t {
     }
     #[doc = "Rounding Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vraddhn.i32"))]
    @@ -41941,7 +41941,7 @@ pub fn vraddhn_high_s32(a: int16x4_t, b: int32x4_t, c: int32x4_t) -> int16x8_t {
     }
     #[doc = "Rounding Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_high_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vraddhn.i64"))]
    @@ -41963,7 +41963,7 @@ pub fn vraddhn_high_s64(a: int32x2_t, b: int64x2_t, c: int64x2_t) -> int32x4_t {
     }
     #[doc = "Rounding Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vraddhn.i16"))]
    @@ -41987,7 +41987,7 @@ pub fn vraddhn_high_u16(a: uint8x8_t, b: uint16x8_t, c: uint16x8_t) -> uint8x16_
     }
     #[doc = "Rounding Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vraddhn.i32"))]
    @@ -42011,7 +42011,7 @@ pub fn vraddhn_high_u32(a: uint16x4_t, b: uint32x4_t, c: uint32x4_t) -> uint16x8
     }
     #[doc = "Rounding Add returning High Narrow (high half)."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_high_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vraddhn.i64"))]
    @@ -42035,7 +42035,7 @@ pub fn vraddhn_high_u64(a: uint32x2_t, b: uint64x2_t, c: uint64x2_t) -> uint32x4
     }
     #[doc = "Rounding Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vraddhn.i16"))]
    @@ -42064,7 +42064,7 @@ pub fn vraddhn_s16(a: int16x8_t, b: int16x8_t) -> int8x8_t {
     }
     #[doc = "Rounding Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vraddhn.i32"))]
    @@ -42093,7 +42093,7 @@ pub fn vraddhn_s32(a: int32x4_t, b: int32x4_t) -> int16x4_t {
     }
     #[doc = "Rounding Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vraddhn.i64"))]
    @@ -42122,7 +42122,7 @@ pub fn vraddhn_s64(a: int64x2_t, b: int64x2_t) -> int32x2_t {
     }
     #[doc = "Rounding Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -42144,7 +42144,7 @@ pub fn vraddhn_u16(a: uint16x8_t, b: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Rounding Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -42171,7 +42171,7 @@ pub fn vraddhn_u16(a: uint16x8_t, b: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Rounding Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -42193,7 +42193,7 @@ pub fn vraddhn_u32(a: uint32x4_t, b: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Rounding Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -42220,7 +42220,7 @@ pub fn vraddhn_u32(a: uint32x4_t, b: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Rounding Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -42242,7 +42242,7 @@ pub fn vraddhn_u64(a: uint64x2_t, b: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Rounding Add returning High Narrow."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vraddhn_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -42269,7 +42269,7 @@ pub fn vraddhn_u64(a: uint64x2_t, b: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Reciprocal estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpe_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecpe))]
     #[cfg_attr(
    @@ -42299,7 +42299,7 @@ pub fn vrecpe_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Reciprocal estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpeq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecpe))]
     #[cfg_attr(
    @@ -42329,7 +42329,7 @@ pub fn vrecpeq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Reciprocal estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpe_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecpe))]
    @@ -42358,7 +42358,7 @@ pub fn vrecpe_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Reciprocal estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpeq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecpe))]
    @@ -42387,7 +42387,7 @@ pub fn vrecpeq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Unsigned reciprocal estimate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpe_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecpe))]
    @@ -42416,7 +42416,7 @@ pub fn vrecpe_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned reciprocal estimate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpeq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecpe))]
    @@ -42445,7 +42445,7 @@ pub fn vrecpeq_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point reciprocal step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecps_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecps))]
     #[cfg_attr(
    @@ -42475,7 +42475,7 @@ pub fn vrecps_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point reciprocal step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpsq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecps))]
     #[cfg_attr(
    @@ -42505,7 +42505,7 @@ pub fn vrecpsq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point reciprocal step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecps_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecps))]
    @@ -42534,7 +42534,7 @@ pub fn vrecps_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point reciprocal step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrecpsq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrecps))]
    @@ -42563,7 +42563,7 @@ pub fn vrecpsq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42586,7 +42586,7 @@ pub fn vreinterpret_f32_f16(a: float16x4_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42613,7 +42613,7 @@ pub fn vreinterpret_f32_f16(a: float16x4_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42636,7 +42636,7 @@ pub fn vreinterpret_s8_f16(a: float16x4_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42663,7 +42663,7 @@ pub fn vreinterpret_s8_f16(a: float16x4_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42686,7 +42686,7 @@ pub fn vreinterpret_s16_f16(a: float16x4_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42713,7 +42713,7 @@ pub fn vreinterpret_s16_f16(a: float16x4_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42736,7 +42736,7 @@ pub fn vreinterpret_s32_f16(a: float16x4_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42763,7 +42763,7 @@ pub fn vreinterpret_s32_f16(a: float16x4_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42786,7 +42786,7 @@ pub fn vreinterpret_s64_f16(a: float16x4_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42810,7 +42810,7 @@ pub fn vreinterpret_s64_f16(a: float16x4_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42833,7 +42833,7 @@ pub fn vreinterpret_u8_f16(a: float16x4_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42860,7 +42860,7 @@ pub fn vreinterpret_u8_f16(a: float16x4_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42883,7 +42883,7 @@ pub fn vreinterpret_u16_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42910,7 +42910,7 @@ pub fn vreinterpret_u16_f16(a: float16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42933,7 +42933,7 @@ pub fn vreinterpret_u32_f16(a: float16x4_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42960,7 +42960,7 @@ pub fn vreinterpret_u32_f16(a: float16x4_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -42983,7 +42983,7 @@ pub fn vreinterpret_u64_f16(a: float16x4_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43007,7 +43007,7 @@ pub fn vreinterpret_u64_f16(a: float16x4_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43030,7 +43030,7 @@ pub fn vreinterpret_p8_f16(a: float16x4_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43057,7 +43057,7 @@ pub fn vreinterpret_p8_f16(a: float16x4_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43080,7 +43080,7 @@ pub fn vreinterpret_p16_f16(a: float16x4_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43107,7 +43107,7 @@ pub fn vreinterpret_p16_f16(a: float16x4_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43130,7 +43130,7 @@ pub fn vreinterpretq_f32_f16(a: float16x8_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43157,7 +43157,7 @@ pub fn vreinterpretq_f32_f16(a: float16x8_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43180,7 +43180,7 @@ pub fn vreinterpretq_s8_f16(a: float16x8_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43211,7 +43211,7 @@ pub fn vreinterpretq_s8_f16(a: float16x8_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43234,7 +43234,7 @@ pub fn vreinterpretq_s16_f16(a: float16x8_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43261,7 +43261,7 @@ pub fn vreinterpretq_s16_f16(a: float16x8_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43284,7 +43284,7 @@ pub fn vreinterpretq_s32_f16(a: float16x8_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43311,7 +43311,7 @@ pub fn vreinterpretq_s32_f16(a: float16x8_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43334,7 +43334,7 @@ pub fn vreinterpretq_s64_f16(a: float16x8_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43361,7 +43361,7 @@ pub fn vreinterpretq_s64_f16(a: float16x8_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43384,7 +43384,7 @@ pub fn vreinterpretq_u8_f16(a: float16x8_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43415,7 +43415,7 @@ pub fn vreinterpretq_u8_f16(a: float16x8_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43438,7 +43438,7 @@ pub fn vreinterpretq_u16_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43465,7 +43465,7 @@ pub fn vreinterpretq_u16_f16(a: float16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43488,7 +43488,7 @@ pub fn vreinterpretq_u32_f16(a: float16x8_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43515,7 +43515,7 @@ pub fn vreinterpretq_u32_f16(a: float16x8_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43538,7 +43538,7 @@ pub fn vreinterpretq_u64_f16(a: float16x8_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43565,7 +43565,7 @@ pub fn vreinterpretq_u64_f16(a: float16x8_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43588,7 +43588,7 @@ pub fn vreinterpretq_p8_f16(a: float16x8_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43619,7 +43619,7 @@ pub fn vreinterpretq_p8_f16(a: float16x8_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43642,7 +43642,7 @@ pub fn vreinterpretq_p16_f16(a: float16x8_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43669,7 +43669,7 @@ pub fn vreinterpretq_p16_f16(a: float16x8_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43692,7 +43692,7 @@ pub fn vreinterpret_f16_f32(a: float32x2_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43719,7 +43719,7 @@ pub fn vreinterpret_f16_f32(a: float32x2_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43742,7 +43742,7 @@ pub fn vreinterpretq_f16_f32(a: float32x4_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43769,7 +43769,7 @@ pub fn vreinterpretq_f16_f32(a: float32x4_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43792,7 +43792,7 @@ pub fn vreinterpret_f16_s8(a: int8x8_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43819,7 +43819,7 @@ pub fn vreinterpret_f16_s8(a: int8x8_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43842,7 +43842,7 @@ pub fn vreinterpretq_f16_s8(a: int8x16_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43870,7 +43870,7 @@ pub fn vreinterpretq_f16_s8(a: int8x16_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43893,7 +43893,7 @@ pub fn vreinterpret_f16_s16(a: int16x4_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43920,7 +43920,7 @@ pub fn vreinterpret_f16_s16(a: int16x4_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43943,7 +43943,7 @@ pub fn vreinterpretq_f16_s16(a: int16x8_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43970,7 +43970,7 @@ pub fn vreinterpretq_f16_s16(a: int16x8_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -43993,7 +43993,7 @@ pub fn vreinterpret_f16_s32(a: int32x2_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44020,7 +44020,7 @@ pub fn vreinterpret_f16_s32(a: int32x2_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44043,7 +44043,7 @@ pub fn vreinterpretq_f16_s32(a: int32x4_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44070,7 +44070,7 @@ pub fn vreinterpretq_f16_s32(a: int32x4_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44093,7 +44093,7 @@ pub fn vreinterpret_f16_s64(a: int64x1_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44119,7 +44119,7 @@ pub fn vreinterpret_f16_s64(a: int64x1_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44142,7 +44142,7 @@ pub fn vreinterpretq_f16_s64(a: int64x2_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44169,7 +44169,7 @@ pub fn vreinterpretq_f16_s64(a: int64x2_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44192,7 +44192,7 @@ pub fn vreinterpret_f16_u8(a: uint8x8_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44219,7 +44219,7 @@ pub fn vreinterpret_f16_u8(a: uint8x8_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44242,7 +44242,7 @@ pub fn vreinterpretq_f16_u8(a: uint8x16_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44270,7 +44270,7 @@ pub fn vreinterpretq_f16_u8(a: uint8x16_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44293,7 +44293,7 @@ pub fn vreinterpret_f16_u16(a: uint16x4_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44320,7 +44320,7 @@ pub fn vreinterpret_f16_u16(a: uint16x4_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44343,7 +44343,7 @@ pub fn vreinterpretq_f16_u16(a: uint16x8_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44370,7 +44370,7 @@ pub fn vreinterpretq_f16_u16(a: uint16x8_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44393,7 +44393,7 @@ pub fn vreinterpret_f16_u32(a: uint32x2_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44420,7 +44420,7 @@ pub fn vreinterpret_f16_u32(a: uint32x2_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44443,7 +44443,7 @@ pub fn vreinterpretq_f16_u32(a: uint32x4_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44470,7 +44470,7 @@ pub fn vreinterpretq_f16_u32(a: uint32x4_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44493,7 +44493,7 @@ pub fn vreinterpret_f16_u64(a: uint64x1_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44519,7 +44519,7 @@ pub fn vreinterpret_f16_u64(a: uint64x1_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44542,7 +44542,7 @@ pub fn vreinterpretq_f16_u64(a: uint64x2_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44569,7 +44569,7 @@ pub fn vreinterpretq_f16_u64(a: uint64x2_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44592,7 +44592,7 @@ pub fn vreinterpret_f16_p8(a: poly8x8_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44619,7 +44619,7 @@ pub fn vreinterpret_f16_p8(a: poly8x8_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44642,7 +44642,7 @@ pub fn vreinterpretq_f16_p8(a: poly8x16_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44670,7 +44670,7 @@ pub fn vreinterpretq_f16_p8(a: poly8x16_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44693,7 +44693,7 @@ pub fn vreinterpret_f16_p16(a: poly16x4_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44720,7 +44720,7 @@ pub fn vreinterpret_f16_p16(a: poly16x4_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44743,7 +44743,7 @@ pub fn vreinterpretq_f16_p16(a: poly16x8_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44770,7 +44770,7 @@ pub fn vreinterpretq_f16_p16(a: poly16x8_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44793,7 +44793,7 @@ pub fn vreinterpretq_f16_p128(a: p128) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44819,7 +44819,7 @@ pub fn vreinterpretq_f16_p128(a: p128) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44842,7 +44842,7 @@ pub fn vreinterpret_p64_f16(a: float16x4_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44866,7 +44866,7 @@ pub fn vreinterpret_p64_f16(a: float16x4_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44889,7 +44889,7 @@ pub fn vreinterpretq_p128_f16(a: float16x8_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44913,7 +44913,7 @@ pub fn vreinterpretq_p128_f16(a: float16x8_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44936,7 +44936,7 @@ pub fn vreinterpretq_p64_f16(a: float16x8_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44963,7 +44963,7 @@ pub fn vreinterpretq_p64_f16(a: float16x8_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -44986,7 +44986,7 @@ pub fn vreinterpret_f16_p64(a: poly64x1_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -45012,7 +45012,7 @@ pub fn vreinterpret_f16_p64(a: poly64x1_t) -> float16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -45035,7 +45035,7 @@ pub fn vreinterpretq_f16_p64(a: poly64x2_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -45062,7 +45062,7 @@ pub fn vreinterpretq_f16_p64(a: poly64x2_t) -> float16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45084,7 +45084,7 @@ pub fn vreinterpretq_f32_p128(a: p128) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45109,7 +45109,7 @@ pub fn vreinterpretq_f32_p128(a: p128) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45131,7 +45131,7 @@ pub fn vreinterpret_s8_f32(a: float32x2_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45157,7 +45157,7 @@ pub fn vreinterpret_s8_f32(a: float32x2_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45179,7 +45179,7 @@ pub fn vreinterpret_s16_f32(a: float32x2_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45205,7 +45205,7 @@ pub fn vreinterpret_s16_f32(a: float32x2_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45227,7 +45227,7 @@ pub fn vreinterpret_s32_f32(a: float32x2_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45253,7 +45253,7 @@ pub fn vreinterpret_s32_f32(a: float32x2_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45275,7 +45275,7 @@ pub fn vreinterpret_s64_f32(a: float32x2_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45298,7 +45298,7 @@ pub fn vreinterpret_s64_f32(a: float32x2_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45320,7 +45320,7 @@ pub fn vreinterpret_u8_f32(a: float32x2_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45346,7 +45346,7 @@ pub fn vreinterpret_u8_f32(a: float32x2_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45368,7 +45368,7 @@ pub fn vreinterpret_u16_f32(a: float32x2_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45394,7 +45394,7 @@ pub fn vreinterpret_u16_f32(a: float32x2_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45416,7 +45416,7 @@ pub fn vreinterpret_u32_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45442,7 +45442,7 @@ pub fn vreinterpret_u32_f32(a: float32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45464,7 +45464,7 @@ pub fn vreinterpret_u64_f32(a: float32x2_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45487,7 +45487,7 @@ pub fn vreinterpret_u64_f32(a: float32x2_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45509,7 +45509,7 @@ pub fn vreinterpret_p8_f32(a: float32x2_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45535,7 +45535,7 @@ pub fn vreinterpret_p8_f32(a: float32x2_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45557,7 +45557,7 @@ pub fn vreinterpret_p16_f32(a: float32x2_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45583,7 +45583,7 @@ pub fn vreinterpret_p16_f32(a: float32x2_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45605,7 +45605,7 @@ pub fn vreinterpretq_p128_f32(a: float32x4_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45628,7 +45628,7 @@ pub fn vreinterpretq_p128_f32(a: float32x4_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45650,7 +45650,7 @@ pub fn vreinterpretq_s8_f32(a: float32x4_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45680,7 +45680,7 @@ pub fn vreinterpretq_s8_f32(a: float32x4_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45702,7 +45702,7 @@ pub fn vreinterpretq_s16_f32(a: float32x4_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45728,7 +45728,7 @@ pub fn vreinterpretq_s16_f32(a: float32x4_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45750,7 +45750,7 @@ pub fn vreinterpretq_s32_f32(a: float32x4_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45776,7 +45776,7 @@ pub fn vreinterpretq_s32_f32(a: float32x4_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45798,7 +45798,7 @@ pub fn vreinterpretq_s64_f32(a: float32x4_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45824,7 +45824,7 @@ pub fn vreinterpretq_s64_f32(a: float32x4_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45846,7 +45846,7 @@ pub fn vreinterpretq_u8_f32(a: float32x4_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45876,7 +45876,7 @@ pub fn vreinterpretq_u8_f32(a: float32x4_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45898,7 +45898,7 @@ pub fn vreinterpretq_u16_f32(a: float32x4_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45924,7 +45924,7 @@ pub fn vreinterpretq_u16_f32(a: float32x4_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45946,7 +45946,7 @@ pub fn vreinterpretq_u32_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45972,7 +45972,7 @@ pub fn vreinterpretq_u32_f32(a: float32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -45994,7 +45994,7 @@ pub fn vreinterpretq_u64_f32(a: float32x4_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46020,7 +46020,7 @@ pub fn vreinterpretq_u64_f32(a: float32x4_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46042,7 +46042,7 @@ pub fn vreinterpretq_p8_f32(a: float32x4_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46072,7 +46072,7 @@ pub fn vreinterpretq_p8_f32(a: float32x4_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46094,7 +46094,7 @@ pub fn vreinterpretq_p16_f32(a: float32x4_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_f32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46120,7 +46120,7 @@ pub fn vreinterpretq_p16_f32(a: float32x4_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46142,7 +46142,7 @@ pub fn vreinterpret_f32_s8(a: int8x8_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46168,7 +46168,7 @@ pub fn vreinterpret_f32_s8(a: int8x8_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46190,7 +46190,7 @@ pub fn vreinterpret_s16_s8(a: int8x8_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46216,7 +46216,7 @@ pub fn vreinterpret_s16_s8(a: int8x8_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46238,7 +46238,7 @@ pub fn vreinterpret_s32_s8(a: int8x8_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46264,7 +46264,7 @@ pub fn vreinterpret_s32_s8(a: int8x8_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46286,7 +46286,7 @@ pub fn vreinterpret_s64_s8(a: int8x8_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46309,7 +46309,7 @@ pub fn vreinterpret_s64_s8(a: int8x8_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46331,7 +46331,7 @@ pub fn vreinterpret_u8_s8(a: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46357,7 +46357,7 @@ pub fn vreinterpret_u8_s8(a: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46379,7 +46379,7 @@ pub fn vreinterpret_u16_s8(a: int8x8_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46405,7 +46405,7 @@ pub fn vreinterpret_u16_s8(a: int8x8_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46427,7 +46427,7 @@ pub fn vreinterpret_u32_s8(a: int8x8_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46453,7 +46453,7 @@ pub fn vreinterpret_u32_s8(a: int8x8_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46475,7 +46475,7 @@ pub fn vreinterpret_u64_s8(a: int8x8_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46498,7 +46498,7 @@ pub fn vreinterpret_u64_s8(a: int8x8_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46520,7 +46520,7 @@ pub fn vreinterpret_p8_s8(a: int8x8_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46546,7 +46546,7 @@ pub fn vreinterpret_p8_s8(a: int8x8_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46568,7 +46568,7 @@ pub fn vreinterpret_p16_s8(a: int8x8_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46594,7 +46594,7 @@ pub fn vreinterpret_p16_s8(a: int8x8_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46616,7 +46616,7 @@ pub fn vreinterpretq_f32_s8(a: int8x16_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46643,7 +46643,7 @@ pub fn vreinterpretq_f32_s8(a: int8x16_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46665,7 +46665,7 @@ pub fn vreinterpretq_s16_s8(a: int8x16_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46692,7 +46692,7 @@ pub fn vreinterpretq_s16_s8(a: int8x16_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46714,7 +46714,7 @@ pub fn vreinterpretq_s32_s8(a: int8x16_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46741,7 +46741,7 @@ pub fn vreinterpretq_s32_s8(a: int8x16_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46763,7 +46763,7 @@ pub fn vreinterpretq_s64_s8(a: int8x16_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46790,7 +46790,7 @@ pub fn vreinterpretq_s64_s8(a: int8x16_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46812,7 +46812,7 @@ pub fn vreinterpretq_u8_s8(a: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46843,7 +46843,7 @@ pub fn vreinterpretq_u8_s8(a: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46865,7 +46865,7 @@ pub fn vreinterpretq_u16_s8(a: int8x16_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46892,7 +46892,7 @@ pub fn vreinterpretq_u16_s8(a: int8x16_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46914,7 +46914,7 @@ pub fn vreinterpretq_u32_s8(a: int8x16_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46941,7 +46941,7 @@ pub fn vreinterpretq_u32_s8(a: int8x16_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46963,7 +46963,7 @@ pub fn vreinterpretq_u64_s8(a: int8x16_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -46990,7 +46990,7 @@ pub fn vreinterpretq_u64_s8(a: int8x16_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47012,7 +47012,7 @@ pub fn vreinterpretq_p8_s8(a: int8x16_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47043,7 +47043,7 @@ pub fn vreinterpretq_p8_s8(a: int8x16_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47065,7 +47065,7 @@ pub fn vreinterpretq_p16_s8(a: int8x16_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47092,7 +47092,7 @@ pub fn vreinterpretq_p16_s8(a: int8x16_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47114,7 +47114,7 @@ pub fn vreinterpret_f32_s16(a: int16x4_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47140,7 +47140,7 @@ pub fn vreinterpret_f32_s16(a: int16x4_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47162,7 +47162,7 @@ pub fn vreinterpret_s8_s16(a: int16x4_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47188,7 +47188,7 @@ pub fn vreinterpret_s8_s16(a: int16x4_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47210,7 +47210,7 @@ pub fn vreinterpret_s32_s16(a: int16x4_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47236,7 +47236,7 @@ pub fn vreinterpret_s32_s16(a: int16x4_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47258,7 +47258,7 @@ pub fn vreinterpret_s64_s16(a: int16x4_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47281,7 +47281,7 @@ pub fn vreinterpret_s64_s16(a: int16x4_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47303,7 +47303,7 @@ pub fn vreinterpret_u8_s16(a: int16x4_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47329,7 +47329,7 @@ pub fn vreinterpret_u8_s16(a: int16x4_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47351,7 +47351,7 @@ pub fn vreinterpret_u16_s16(a: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47377,7 +47377,7 @@ pub fn vreinterpret_u16_s16(a: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47399,7 +47399,7 @@ pub fn vreinterpret_u32_s16(a: int16x4_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47425,7 +47425,7 @@ pub fn vreinterpret_u32_s16(a: int16x4_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47447,7 +47447,7 @@ pub fn vreinterpret_u64_s16(a: int16x4_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47470,7 +47470,7 @@ pub fn vreinterpret_u64_s16(a: int16x4_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47492,7 +47492,7 @@ pub fn vreinterpret_p8_s16(a: int16x4_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47518,7 +47518,7 @@ pub fn vreinterpret_p8_s16(a: int16x4_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47540,7 +47540,7 @@ pub fn vreinterpret_p16_s16(a: int16x4_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47566,7 +47566,7 @@ pub fn vreinterpret_p16_s16(a: int16x4_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47588,7 +47588,7 @@ pub fn vreinterpretq_f32_s16(a: int16x8_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47614,7 +47614,7 @@ pub fn vreinterpretq_f32_s16(a: int16x8_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47636,7 +47636,7 @@ pub fn vreinterpretq_s8_s16(a: int16x8_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47666,7 +47666,7 @@ pub fn vreinterpretq_s8_s16(a: int16x8_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47688,7 +47688,7 @@ pub fn vreinterpretq_s32_s16(a: int16x8_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47714,7 +47714,7 @@ pub fn vreinterpretq_s32_s16(a: int16x8_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47736,7 +47736,7 @@ pub fn vreinterpretq_s64_s16(a: int16x8_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47762,7 +47762,7 @@ pub fn vreinterpretq_s64_s16(a: int16x8_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47784,7 +47784,7 @@ pub fn vreinterpretq_u8_s16(a: int16x8_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47814,7 +47814,7 @@ pub fn vreinterpretq_u8_s16(a: int16x8_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47836,7 +47836,7 @@ pub fn vreinterpretq_u16_s16(a: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47862,7 +47862,7 @@ pub fn vreinterpretq_u16_s16(a: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47884,7 +47884,7 @@ pub fn vreinterpretq_u32_s16(a: int16x8_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47910,7 +47910,7 @@ pub fn vreinterpretq_u32_s16(a: int16x8_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47932,7 +47932,7 @@ pub fn vreinterpretq_u64_s16(a: int16x8_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47958,7 +47958,7 @@ pub fn vreinterpretq_u64_s16(a: int16x8_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -47980,7 +47980,7 @@ pub fn vreinterpretq_p8_s16(a: int16x8_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48010,7 +48010,7 @@ pub fn vreinterpretq_p8_s16(a: int16x8_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48032,7 +48032,7 @@ pub fn vreinterpretq_p16_s16(a: int16x8_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48058,7 +48058,7 @@ pub fn vreinterpretq_p16_s16(a: int16x8_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48080,7 +48080,7 @@ pub fn vreinterpret_f32_s32(a: int32x2_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48106,7 +48106,7 @@ pub fn vreinterpret_f32_s32(a: int32x2_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48128,7 +48128,7 @@ pub fn vreinterpret_s8_s32(a: int32x2_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48154,7 +48154,7 @@ pub fn vreinterpret_s8_s32(a: int32x2_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48176,7 +48176,7 @@ pub fn vreinterpret_s16_s32(a: int32x2_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48202,7 +48202,7 @@ pub fn vreinterpret_s16_s32(a: int32x2_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48224,7 +48224,7 @@ pub fn vreinterpret_s64_s32(a: int32x2_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48247,7 +48247,7 @@ pub fn vreinterpret_s64_s32(a: int32x2_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48269,7 +48269,7 @@ pub fn vreinterpret_u8_s32(a: int32x2_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48295,7 +48295,7 @@ pub fn vreinterpret_u8_s32(a: int32x2_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48317,7 +48317,7 @@ pub fn vreinterpret_u16_s32(a: int32x2_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48343,7 +48343,7 @@ pub fn vreinterpret_u16_s32(a: int32x2_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48365,7 +48365,7 @@ pub fn vreinterpret_u32_s32(a: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48391,7 +48391,7 @@ pub fn vreinterpret_u32_s32(a: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48413,7 +48413,7 @@ pub fn vreinterpret_u64_s32(a: int32x2_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48436,7 +48436,7 @@ pub fn vreinterpret_u64_s32(a: int32x2_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48458,7 +48458,7 @@ pub fn vreinterpret_p8_s32(a: int32x2_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48484,7 +48484,7 @@ pub fn vreinterpret_p8_s32(a: int32x2_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48506,7 +48506,7 @@ pub fn vreinterpret_p16_s32(a: int32x2_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48532,7 +48532,7 @@ pub fn vreinterpret_p16_s32(a: int32x2_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48554,7 +48554,7 @@ pub fn vreinterpretq_f32_s32(a: int32x4_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48580,7 +48580,7 @@ pub fn vreinterpretq_f32_s32(a: int32x4_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48602,7 +48602,7 @@ pub fn vreinterpretq_s8_s32(a: int32x4_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48632,7 +48632,7 @@ pub fn vreinterpretq_s8_s32(a: int32x4_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48654,7 +48654,7 @@ pub fn vreinterpretq_s16_s32(a: int32x4_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48680,7 +48680,7 @@ pub fn vreinterpretq_s16_s32(a: int32x4_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48702,7 +48702,7 @@ pub fn vreinterpretq_s64_s32(a: int32x4_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48728,7 +48728,7 @@ pub fn vreinterpretq_s64_s32(a: int32x4_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48750,7 +48750,7 @@ pub fn vreinterpretq_u8_s32(a: int32x4_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48780,7 +48780,7 @@ pub fn vreinterpretq_u8_s32(a: int32x4_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48802,7 +48802,7 @@ pub fn vreinterpretq_u16_s32(a: int32x4_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48828,7 +48828,7 @@ pub fn vreinterpretq_u16_s32(a: int32x4_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48850,7 +48850,7 @@ pub fn vreinterpretq_u32_s32(a: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48876,7 +48876,7 @@ pub fn vreinterpretq_u32_s32(a: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48898,7 +48898,7 @@ pub fn vreinterpretq_u64_s32(a: int32x4_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48924,7 +48924,7 @@ pub fn vreinterpretq_u64_s32(a: int32x4_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48946,7 +48946,7 @@ pub fn vreinterpretq_p8_s32(a: int32x4_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48976,7 +48976,7 @@ pub fn vreinterpretq_p8_s32(a: int32x4_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -48998,7 +48998,7 @@ pub fn vreinterpretq_p16_s32(a: int32x4_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49024,7 +49024,7 @@ pub fn vreinterpretq_p16_s32(a: int32x4_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49046,7 +49046,7 @@ pub fn vreinterpret_f32_s64(a: int64x1_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49071,7 +49071,7 @@ pub fn vreinterpret_f32_s64(a: int64x1_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49093,7 +49093,7 @@ pub fn vreinterpret_s8_s64(a: int64x1_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49118,7 +49118,7 @@ pub fn vreinterpret_s8_s64(a: int64x1_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49140,7 +49140,7 @@ pub fn vreinterpret_s16_s64(a: int64x1_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49165,7 +49165,7 @@ pub fn vreinterpret_s16_s64(a: int64x1_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49187,7 +49187,7 @@ pub fn vreinterpret_s32_s64(a: int64x1_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49212,7 +49212,7 @@ pub fn vreinterpret_s32_s64(a: int64x1_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49234,7 +49234,7 @@ pub fn vreinterpret_u8_s64(a: int64x1_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49259,7 +49259,7 @@ pub fn vreinterpret_u8_s64(a: int64x1_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49281,7 +49281,7 @@ pub fn vreinterpret_u16_s64(a: int64x1_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49306,7 +49306,7 @@ pub fn vreinterpret_u16_s64(a: int64x1_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49328,7 +49328,7 @@ pub fn vreinterpret_u32_s64(a: int64x1_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49353,7 +49353,7 @@ pub fn vreinterpret_u32_s64(a: int64x1_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -49374,7 +49374,7 @@ pub fn vreinterpret_u64_s64(a: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49396,7 +49396,7 @@ pub fn vreinterpret_p8_s64(a: int64x1_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49421,7 +49421,7 @@ pub fn vreinterpret_p8_s64(a: int64x1_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49443,7 +49443,7 @@ pub fn vreinterpret_p16_s64(a: int64x1_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49468,7 +49468,7 @@ pub fn vreinterpret_p16_s64(a: int64x1_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49490,7 +49490,7 @@ pub fn vreinterpretq_f32_s64(a: int64x2_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49516,7 +49516,7 @@ pub fn vreinterpretq_f32_s64(a: int64x2_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49538,7 +49538,7 @@ pub fn vreinterpretq_s8_s64(a: int64x2_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49568,7 +49568,7 @@ pub fn vreinterpretq_s8_s64(a: int64x2_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49590,7 +49590,7 @@ pub fn vreinterpretq_s16_s64(a: int64x2_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49616,7 +49616,7 @@ pub fn vreinterpretq_s16_s64(a: int64x2_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49638,7 +49638,7 @@ pub fn vreinterpretq_s32_s64(a: int64x2_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49664,7 +49664,7 @@ pub fn vreinterpretq_s32_s64(a: int64x2_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49686,7 +49686,7 @@ pub fn vreinterpretq_u8_s64(a: int64x2_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49716,7 +49716,7 @@ pub fn vreinterpretq_u8_s64(a: int64x2_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49738,7 +49738,7 @@ pub fn vreinterpretq_u16_s64(a: int64x2_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49764,7 +49764,7 @@ pub fn vreinterpretq_u16_s64(a: int64x2_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49786,7 +49786,7 @@ pub fn vreinterpretq_u32_s64(a: int64x2_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49812,7 +49812,7 @@ pub fn vreinterpretq_u32_s64(a: int64x2_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49834,7 +49834,7 @@ pub fn vreinterpretq_u64_s64(a: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49860,7 +49860,7 @@ pub fn vreinterpretq_u64_s64(a: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49882,7 +49882,7 @@ pub fn vreinterpretq_p8_s64(a: int64x2_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49912,7 +49912,7 @@ pub fn vreinterpretq_p8_s64(a: int64x2_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49934,7 +49934,7 @@ pub fn vreinterpretq_p16_s64(a: int64x2_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49960,7 +49960,7 @@ pub fn vreinterpretq_p16_s64(a: int64x2_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -49982,7 +49982,7 @@ pub fn vreinterpret_f32_u8(a: uint8x8_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50008,7 +50008,7 @@ pub fn vreinterpret_f32_u8(a: uint8x8_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50030,7 +50030,7 @@ pub fn vreinterpret_s8_u8(a: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50056,7 +50056,7 @@ pub fn vreinterpret_s8_u8(a: uint8x8_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50078,7 +50078,7 @@ pub fn vreinterpret_s16_u8(a: uint8x8_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50104,7 +50104,7 @@ pub fn vreinterpret_s16_u8(a: uint8x8_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50126,7 +50126,7 @@ pub fn vreinterpret_s32_u8(a: uint8x8_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50152,7 +50152,7 @@ pub fn vreinterpret_s32_u8(a: uint8x8_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50174,7 +50174,7 @@ pub fn vreinterpret_s64_u8(a: uint8x8_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50197,7 +50197,7 @@ pub fn vreinterpret_s64_u8(a: uint8x8_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50219,7 +50219,7 @@ pub fn vreinterpret_u16_u8(a: uint8x8_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50245,7 +50245,7 @@ pub fn vreinterpret_u16_u8(a: uint8x8_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50267,7 +50267,7 @@ pub fn vreinterpret_u32_u8(a: uint8x8_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50293,7 +50293,7 @@ pub fn vreinterpret_u32_u8(a: uint8x8_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50315,7 +50315,7 @@ pub fn vreinterpret_u64_u8(a: uint8x8_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50338,7 +50338,7 @@ pub fn vreinterpret_u64_u8(a: uint8x8_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50360,7 +50360,7 @@ pub fn vreinterpret_p8_u8(a: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50386,7 +50386,7 @@ pub fn vreinterpret_p8_u8(a: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50408,7 +50408,7 @@ pub fn vreinterpret_p16_u8(a: uint8x8_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50434,7 +50434,7 @@ pub fn vreinterpret_p16_u8(a: uint8x8_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50456,7 +50456,7 @@ pub fn vreinterpretq_f32_u8(a: uint8x16_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50483,7 +50483,7 @@ pub fn vreinterpretq_f32_u8(a: uint8x16_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50505,7 +50505,7 @@ pub fn vreinterpretq_s8_u8(a: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50536,7 +50536,7 @@ pub fn vreinterpretq_s8_u8(a: uint8x16_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50558,7 +50558,7 @@ pub fn vreinterpretq_s16_u8(a: uint8x16_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50585,7 +50585,7 @@ pub fn vreinterpretq_s16_u8(a: uint8x16_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50607,7 +50607,7 @@ pub fn vreinterpretq_s32_u8(a: uint8x16_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50634,7 +50634,7 @@ pub fn vreinterpretq_s32_u8(a: uint8x16_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50656,7 +50656,7 @@ pub fn vreinterpretq_s64_u8(a: uint8x16_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50683,7 +50683,7 @@ pub fn vreinterpretq_s64_u8(a: uint8x16_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50705,7 +50705,7 @@ pub fn vreinterpretq_u16_u8(a: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50732,7 +50732,7 @@ pub fn vreinterpretq_u16_u8(a: uint8x16_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50754,7 +50754,7 @@ pub fn vreinterpretq_u32_u8(a: uint8x16_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50781,7 +50781,7 @@ pub fn vreinterpretq_u32_u8(a: uint8x16_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50803,7 +50803,7 @@ pub fn vreinterpretq_u64_u8(a: uint8x16_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50830,7 +50830,7 @@ pub fn vreinterpretq_u64_u8(a: uint8x16_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50852,7 +50852,7 @@ pub fn vreinterpretq_p8_u8(a: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50883,7 +50883,7 @@ pub fn vreinterpretq_p8_u8(a: uint8x16_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50905,7 +50905,7 @@ pub fn vreinterpretq_p16_u8(a: uint8x16_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50932,7 +50932,7 @@ pub fn vreinterpretq_p16_u8(a: uint8x16_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50954,7 +50954,7 @@ pub fn vreinterpret_f32_u16(a: uint16x4_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -50980,7 +50980,7 @@ pub fn vreinterpret_f32_u16(a: uint16x4_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51002,7 +51002,7 @@ pub fn vreinterpret_s8_u16(a: uint16x4_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51028,7 +51028,7 @@ pub fn vreinterpret_s8_u16(a: uint16x4_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51050,7 +51050,7 @@ pub fn vreinterpret_s16_u16(a: uint16x4_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51076,7 +51076,7 @@ pub fn vreinterpret_s16_u16(a: uint16x4_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51098,7 +51098,7 @@ pub fn vreinterpret_s32_u16(a: uint16x4_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51124,7 +51124,7 @@ pub fn vreinterpret_s32_u16(a: uint16x4_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51146,7 +51146,7 @@ pub fn vreinterpret_s64_u16(a: uint16x4_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51169,7 +51169,7 @@ pub fn vreinterpret_s64_u16(a: uint16x4_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51191,7 +51191,7 @@ pub fn vreinterpret_u8_u16(a: uint16x4_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51217,7 +51217,7 @@ pub fn vreinterpret_u8_u16(a: uint16x4_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51239,7 +51239,7 @@ pub fn vreinterpret_u32_u16(a: uint16x4_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51265,7 +51265,7 @@ pub fn vreinterpret_u32_u16(a: uint16x4_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51287,7 +51287,7 @@ pub fn vreinterpret_u64_u16(a: uint16x4_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51310,7 +51310,7 @@ pub fn vreinterpret_u64_u16(a: uint16x4_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51332,7 +51332,7 @@ pub fn vreinterpret_p8_u16(a: uint16x4_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51358,7 +51358,7 @@ pub fn vreinterpret_p8_u16(a: uint16x4_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51380,7 +51380,7 @@ pub fn vreinterpret_p16_u16(a: uint16x4_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51406,7 +51406,7 @@ pub fn vreinterpret_p16_u16(a: uint16x4_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51428,7 +51428,7 @@ pub fn vreinterpretq_f32_u16(a: uint16x8_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51454,7 +51454,7 @@ pub fn vreinterpretq_f32_u16(a: uint16x8_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51476,7 +51476,7 @@ pub fn vreinterpretq_s8_u16(a: uint16x8_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51506,7 +51506,7 @@ pub fn vreinterpretq_s8_u16(a: uint16x8_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51528,7 +51528,7 @@ pub fn vreinterpretq_s16_u16(a: uint16x8_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51554,7 +51554,7 @@ pub fn vreinterpretq_s16_u16(a: uint16x8_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51576,7 +51576,7 @@ pub fn vreinterpretq_s32_u16(a: uint16x8_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51602,7 +51602,7 @@ pub fn vreinterpretq_s32_u16(a: uint16x8_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51624,7 +51624,7 @@ pub fn vreinterpretq_s64_u16(a: uint16x8_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51650,7 +51650,7 @@ pub fn vreinterpretq_s64_u16(a: uint16x8_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51672,7 +51672,7 @@ pub fn vreinterpretq_u8_u16(a: uint16x8_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51702,7 +51702,7 @@ pub fn vreinterpretq_u8_u16(a: uint16x8_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51724,7 +51724,7 @@ pub fn vreinterpretq_u32_u16(a: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51750,7 +51750,7 @@ pub fn vreinterpretq_u32_u16(a: uint16x8_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51772,7 +51772,7 @@ pub fn vreinterpretq_u64_u16(a: uint16x8_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51798,7 +51798,7 @@ pub fn vreinterpretq_u64_u16(a: uint16x8_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51820,7 +51820,7 @@ pub fn vreinterpretq_p8_u16(a: uint16x8_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51850,7 +51850,7 @@ pub fn vreinterpretq_p8_u16(a: uint16x8_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51872,7 +51872,7 @@ pub fn vreinterpretq_p16_u16(a: uint16x8_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51898,7 +51898,7 @@ pub fn vreinterpretq_p16_u16(a: uint16x8_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51920,7 +51920,7 @@ pub fn vreinterpret_f32_u32(a: uint32x2_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51946,7 +51946,7 @@ pub fn vreinterpret_f32_u32(a: uint32x2_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51968,7 +51968,7 @@ pub fn vreinterpret_s8_u32(a: uint32x2_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -51994,7 +51994,7 @@ pub fn vreinterpret_s8_u32(a: uint32x2_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52016,7 +52016,7 @@ pub fn vreinterpret_s16_u32(a: uint32x2_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52042,7 +52042,7 @@ pub fn vreinterpret_s16_u32(a: uint32x2_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52064,7 +52064,7 @@ pub fn vreinterpret_s32_u32(a: uint32x2_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52090,7 +52090,7 @@ pub fn vreinterpret_s32_u32(a: uint32x2_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52112,7 +52112,7 @@ pub fn vreinterpret_s64_u32(a: uint32x2_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52135,7 +52135,7 @@ pub fn vreinterpret_s64_u32(a: uint32x2_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52157,7 +52157,7 @@ pub fn vreinterpret_u8_u32(a: uint32x2_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52183,7 +52183,7 @@ pub fn vreinterpret_u8_u32(a: uint32x2_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52205,7 +52205,7 @@ pub fn vreinterpret_u16_u32(a: uint32x2_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52231,7 +52231,7 @@ pub fn vreinterpret_u16_u32(a: uint32x2_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52253,7 +52253,7 @@ pub fn vreinterpret_u64_u32(a: uint32x2_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52276,7 +52276,7 @@ pub fn vreinterpret_u64_u32(a: uint32x2_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52298,7 +52298,7 @@ pub fn vreinterpret_p8_u32(a: uint32x2_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52324,7 +52324,7 @@ pub fn vreinterpret_p8_u32(a: uint32x2_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52346,7 +52346,7 @@ pub fn vreinterpret_p16_u32(a: uint32x2_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52372,7 +52372,7 @@ pub fn vreinterpret_p16_u32(a: uint32x2_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52394,7 +52394,7 @@ pub fn vreinterpretq_f32_u32(a: uint32x4_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52420,7 +52420,7 @@ pub fn vreinterpretq_f32_u32(a: uint32x4_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52442,7 +52442,7 @@ pub fn vreinterpretq_s8_u32(a: uint32x4_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52472,7 +52472,7 @@ pub fn vreinterpretq_s8_u32(a: uint32x4_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52494,7 +52494,7 @@ pub fn vreinterpretq_s16_u32(a: uint32x4_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52520,7 +52520,7 @@ pub fn vreinterpretq_s16_u32(a: uint32x4_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52542,7 +52542,7 @@ pub fn vreinterpretq_s32_u32(a: uint32x4_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52568,7 +52568,7 @@ pub fn vreinterpretq_s32_u32(a: uint32x4_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52590,7 +52590,7 @@ pub fn vreinterpretq_s64_u32(a: uint32x4_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52616,7 +52616,7 @@ pub fn vreinterpretq_s64_u32(a: uint32x4_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52638,7 +52638,7 @@ pub fn vreinterpretq_u8_u32(a: uint32x4_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52668,7 +52668,7 @@ pub fn vreinterpretq_u8_u32(a: uint32x4_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52690,7 +52690,7 @@ pub fn vreinterpretq_u16_u32(a: uint32x4_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52716,7 +52716,7 @@ pub fn vreinterpretq_u16_u32(a: uint32x4_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52738,7 +52738,7 @@ pub fn vreinterpretq_u64_u32(a: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52764,7 +52764,7 @@ pub fn vreinterpretq_u64_u32(a: uint32x4_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52786,7 +52786,7 @@ pub fn vreinterpretq_p8_u32(a: uint32x4_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52816,7 +52816,7 @@ pub fn vreinterpretq_p8_u32(a: uint32x4_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52838,7 +52838,7 @@ pub fn vreinterpretq_p16_u32(a: uint32x4_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52864,7 +52864,7 @@ pub fn vreinterpretq_p16_u32(a: uint32x4_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52886,7 +52886,7 @@ pub fn vreinterpret_f32_u64(a: uint64x1_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52911,7 +52911,7 @@ pub fn vreinterpret_f32_u64(a: uint64x1_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52933,7 +52933,7 @@ pub fn vreinterpret_s8_u64(a: uint64x1_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52958,7 +52958,7 @@ pub fn vreinterpret_s8_u64(a: uint64x1_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -52980,7 +52980,7 @@ pub fn vreinterpret_s16_u64(a: uint64x1_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53005,7 +53005,7 @@ pub fn vreinterpret_s16_u64(a: uint64x1_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53027,7 +53027,7 @@ pub fn vreinterpret_s32_u64(a: uint64x1_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53052,7 +53052,7 @@ pub fn vreinterpret_s32_u64(a: uint64x1_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -53073,7 +53073,7 @@ pub fn vreinterpret_s64_u64(a: uint64x1_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53095,7 +53095,7 @@ pub fn vreinterpret_u8_u64(a: uint64x1_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53120,7 +53120,7 @@ pub fn vreinterpret_u8_u64(a: uint64x1_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53142,7 +53142,7 @@ pub fn vreinterpret_u16_u64(a: uint64x1_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53167,7 +53167,7 @@ pub fn vreinterpret_u16_u64(a: uint64x1_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53189,7 +53189,7 @@ pub fn vreinterpret_u32_u64(a: uint64x1_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53214,7 +53214,7 @@ pub fn vreinterpret_u32_u64(a: uint64x1_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53236,7 +53236,7 @@ pub fn vreinterpret_p8_u64(a: uint64x1_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53261,7 +53261,7 @@ pub fn vreinterpret_p8_u64(a: uint64x1_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53283,7 +53283,7 @@ pub fn vreinterpret_p16_u64(a: uint64x1_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53308,7 +53308,7 @@ pub fn vreinterpret_p16_u64(a: uint64x1_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53330,7 +53330,7 @@ pub fn vreinterpretq_f32_u64(a: uint64x2_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53356,7 +53356,7 @@ pub fn vreinterpretq_f32_u64(a: uint64x2_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53378,7 +53378,7 @@ pub fn vreinterpretq_s8_u64(a: uint64x2_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53408,7 +53408,7 @@ pub fn vreinterpretq_s8_u64(a: uint64x2_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53430,7 +53430,7 @@ pub fn vreinterpretq_s16_u64(a: uint64x2_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53456,7 +53456,7 @@ pub fn vreinterpretq_s16_u64(a: uint64x2_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53478,7 +53478,7 @@ pub fn vreinterpretq_s32_u64(a: uint64x2_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53504,7 +53504,7 @@ pub fn vreinterpretq_s32_u64(a: uint64x2_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53526,7 +53526,7 @@ pub fn vreinterpretq_s64_u64(a: uint64x2_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53552,7 +53552,7 @@ pub fn vreinterpretq_s64_u64(a: uint64x2_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53574,7 +53574,7 @@ pub fn vreinterpretq_u8_u64(a: uint64x2_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53604,7 +53604,7 @@ pub fn vreinterpretq_u8_u64(a: uint64x2_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53626,7 +53626,7 @@ pub fn vreinterpretq_u16_u64(a: uint64x2_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53652,7 +53652,7 @@ pub fn vreinterpretq_u16_u64(a: uint64x2_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53674,7 +53674,7 @@ pub fn vreinterpretq_u32_u64(a: uint64x2_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53700,7 +53700,7 @@ pub fn vreinterpretq_u32_u64(a: uint64x2_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53722,7 +53722,7 @@ pub fn vreinterpretq_p8_u64(a: uint64x2_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53752,7 +53752,7 @@ pub fn vreinterpretq_p8_u64(a: uint64x2_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53774,7 +53774,7 @@ pub fn vreinterpretq_p16_u64(a: uint64x2_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53800,7 +53800,7 @@ pub fn vreinterpretq_p16_u64(a: uint64x2_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53822,7 +53822,7 @@ pub fn vreinterpret_f32_p8(a: poly8x8_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53848,7 +53848,7 @@ pub fn vreinterpret_f32_p8(a: poly8x8_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53870,7 +53870,7 @@ pub fn vreinterpret_s8_p8(a: poly8x8_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53896,7 +53896,7 @@ pub fn vreinterpret_s8_p8(a: poly8x8_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53918,7 +53918,7 @@ pub fn vreinterpret_s16_p8(a: poly8x8_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53944,7 +53944,7 @@ pub fn vreinterpret_s16_p8(a: poly8x8_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53966,7 +53966,7 @@ pub fn vreinterpret_s32_p8(a: poly8x8_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -53992,7 +53992,7 @@ pub fn vreinterpret_s32_p8(a: poly8x8_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54014,7 +54014,7 @@ pub fn vreinterpret_s64_p8(a: poly8x8_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54037,7 +54037,7 @@ pub fn vreinterpret_s64_p8(a: poly8x8_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54059,7 +54059,7 @@ pub fn vreinterpret_u8_p8(a: poly8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54085,7 +54085,7 @@ pub fn vreinterpret_u8_p8(a: poly8x8_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54107,7 +54107,7 @@ pub fn vreinterpret_u16_p8(a: poly8x8_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54133,7 +54133,7 @@ pub fn vreinterpret_u16_p8(a: poly8x8_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54155,7 +54155,7 @@ pub fn vreinterpret_u32_p8(a: poly8x8_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54181,7 +54181,7 @@ pub fn vreinterpret_u32_p8(a: poly8x8_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54203,7 +54203,7 @@ pub fn vreinterpret_u64_p8(a: poly8x8_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54226,7 +54226,7 @@ pub fn vreinterpret_u64_p8(a: poly8x8_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54248,7 +54248,7 @@ pub fn vreinterpret_p16_p8(a: poly8x8_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54274,7 +54274,7 @@ pub fn vreinterpret_p16_p8(a: poly8x8_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54296,7 +54296,7 @@ pub fn vreinterpretq_f32_p8(a: poly8x16_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54323,7 +54323,7 @@ pub fn vreinterpretq_f32_p8(a: poly8x16_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54345,7 +54345,7 @@ pub fn vreinterpretq_s8_p8(a: poly8x16_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54376,7 +54376,7 @@ pub fn vreinterpretq_s8_p8(a: poly8x16_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54398,7 +54398,7 @@ pub fn vreinterpretq_s16_p8(a: poly8x16_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54425,7 +54425,7 @@ pub fn vreinterpretq_s16_p8(a: poly8x16_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54447,7 +54447,7 @@ pub fn vreinterpretq_s32_p8(a: poly8x16_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54474,7 +54474,7 @@ pub fn vreinterpretq_s32_p8(a: poly8x16_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54496,7 +54496,7 @@ pub fn vreinterpretq_s64_p8(a: poly8x16_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54523,7 +54523,7 @@ pub fn vreinterpretq_s64_p8(a: poly8x16_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54545,7 +54545,7 @@ pub fn vreinterpretq_u8_p8(a: poly8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54576,7 +54576,7 @@ pub fn vreinterpretq_u8_p8(a: poly8x16_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54598,7 +54598,7 @@ pub fn vreinterpretq_u16_p8(a: poly8x16_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54625,7 +54625,7 @@ pub fn vreinterpretq_u16_p8(a: poly8x16_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54647,7 +54647,7 @@ pub fn vreinterpretq_u32_p8(a: poly8x16_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54674,7 +54674,7 @@ pub fn vreinterpretq_u32_p8(a: poly8x16_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54696,7 +54696,7 @@ pub fn vreinterpretq_u64_p8(a: poly8x16_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54723,7 +54723,7 @@ pub fn vreinterpretq_u64_p8(a: poly8x16_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54745,7 +54745,7 @@ pub fn vreinterpretq_p16_p8(a: poly8x16_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54772,7 +54772,7 @@ pub fn vreinterpretq_p16_p8(a: poly8x16_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54794,7 +54794,7 @@ pub fn vreinterpret_f32_p16(a: poly16x4_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54820,7 +54820,7 @@ pub fn vreinterpret_f32_p16(a: poly16x4_t) -> float32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54842,7 +54842,7 @@ pub fn vreinterpret_s8_p16(a: poly16x4_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54868,7 +54868,7 @@ pub fn vreinterpret_s8_p16(a: poly16x4_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54890,7 +54890,7 @@ pub fn vreinterpret_s16_p16(a: poly16x4_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54916,7 +54916,7 @@ pub fn vreinterpret_s16_p16(a: poly16x4_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54938,7 +54938,7 @@ pub fn vreinterpret_s32_p16(a: poly16x4_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54964,7 +54964,7 @@ pub fn vreinterpret_s32_p16(a: poly16x4_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -54986,7 +54986,7 @@ pub fn vreinterpret_s64_p16(a: poly16x4_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55009,7 +55009,7 @@ pub fn vreinterpret_s64_p16(a: poly16x4_t) -> int64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55031,7 +55031,7 @@ pub fn vreinterpret_u8_p16(a: poly16x4_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55057,7 +55057,7 @@ pub fn vreinterpret_u8_p16(a: poly16x4_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55079,7 +55079,7 @@ pub fn vreinterpret_u16_p16(a: poly16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55105,7 +55105,7 @@ pub fn vreinterpret_u16_p16(a: poly16x4_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55127,7 +55127,7 @@ pub fn vreinterpret_u32_p16(a: poly16x4_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55153,7 +55153,7 @@ pub fn vreinterpret_u32_p16(a: poly16x4_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55175,7 +55175,7 @@ pub fn vreinterpret_u64_p16(a: poly16x4_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55198,7 +55198,7 @@ pub fn vreinterpret_u64_p16(a: poly16x4_t) -> uint64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55220,7 +55220,7 @@ pub fn vreinterpret_p8_p16(a: poly16x4_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55246,7 +55246,7 @@ pub fn vreinterpret_p8_p16(a: poly16x4_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55268,7 +55268,7 @@ pub fn vreinterpretq_f32_p16(a: poly16x8_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55294,7 +55294,7 @@ pub fn vreinterpretq_f32_p16(a: poly16x8_t) -> float32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55316,7 +55316,7 @@ pub fn vreinterpretq_s8_p16(a: poly16x8_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55346,7 +55346,7 @@ pub fn vreinterpretq_s8_p16(a: poly16x8_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55368,7 +55368,7 @@ pub fn vreinterpretq_s16_p16(a: poly16x8_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55394,7 +55394,7 @@ pub fn vreinterpretq_s16_p16(a: poly16x8_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55416,7 +55416,7 @@ pub fn vreinterpretq_s32_p16(a: poly16x8_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55442,7 +55442,7 @@ pub fn vreinterpretq_s32_p16(a: poly16x8_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55464,7 +55464,7 @@ pub fn vreinterpretq_s64_p16(a: poly16x8_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55490,7 +55490,7 @@ pub fn vreinterpretq_s64_p16(a: poly16x8_t) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55512,7 +55512,7 @@ pub fn vreinterpretq_u8_p16(a: poly16x8_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55542,7 +55542,7 @@ pub fn vreinterpretq_u8_p16(a: poly16x8_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55564,7 +55564,7 @@ pub fn vreinterpretq_u16_p16(a: poly16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55590,7 +55590,7 @@ pub fn vreinterpretq_u16_p16(a: poly16x8_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55612,7 +55612,7 @@ pub fn vreinterpretq_u32_p16(a: poly16x8_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55638,7 +55638,7 @@ pub fn vreinterpretq_u32_p16(a: poly16x8_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55660,7 +55660,7 @@ pub fn vreinterpretq_u64_p16(a: poly16x8_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55686,7 +55686,7 @@ pub fn vreinterpretq_u64_p16(a: poly16x8_t) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55708,7 +55708,7 @@ pub fn vreinterpretq_p8_p16(a: poly16x8_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -55738,7 +55738,7 @@ pub fn vreinterpretq_p8_p16(a: poly16x8_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55760,7 +55760,7 @@ pub fn vreinterpretq_s8_p128(a: p128) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55789,7 +55789,7 @@ pub fn vreinterpretq_s8_p128(a: p128) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55811,7 +55811,7 @@ pub fn vreinterpretq_s16_p128(a: p128) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55836,7 +55836,7 @@ pub fn vreinterpretq_s16_p128(a: p128) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55858,7 +55858,7 @@ pub fn vreinterpretq_s32_p128(a: p128) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55883,7 +55883,7 @@ pub fn vreinterpretq_s32_p128(a: p128) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55905,7 +55905,7 @@ pub fn vreinterpretq_s64_p128(a: p128) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s64_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55930,7 +55930,7 @@ pub fn vreinterpretq_s64_p128(a: p128) -> int64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55952,7 +55952,7 @@ pub fn vreinterpretq_u8_p128(a: p128) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -55981,7 +55981,7 @@ pub fn vreinterpretq_u8_p128(a: p128) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56003,7 +56003,7 @@ pub fn vreinterpretq_u16_p128(a: p128) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56028,7 +56028,7 @@ pub fn vreinterpretq_u16_p128(a: p128) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56050,7 +56050,7 @@ pub fn vreinterpretq_u32_p128(a: p128) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56075,7 +56075,7 @@ pub fn vreinterpretq_u32_p128(a: p128) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56097,7 +56097,7 @@ pub fn vreinterpretq_u64_p128(a: p128) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u64_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56122,7 +56122,7 @@ pub fn vreinterpretq_u64_p128(a: p128) -> uint64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56144,7 +56144,7 @@ pub fn vreinterpretq_p8_p128(a: p128) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56173,7 +56173,7 @@ pub fn vreinterpretq_p8_p128(a: p128) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56195,7 +56195,7 @@ pub fn vreinterpretq_p16_p128(a: p128) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56220,7 +56220,7 @@ pub fn vreinterpretq_p16_p128(a: p128) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56242,7 +56242,7 @@ pub fn vreinterpretq_p64_p128(a: p128) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_p128)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56267,7 +56267,7 @@ pub fn vreinterpretq_p64_p128(a: p128) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56289,7 +56289,7 @@ pub fn vreinterpret_p64_s8(a: int8x8_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56312,7 +56312,7 @@ pub fn vreinterpret_p64_s8(a: int8x8_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56334,7 +56334,7 @@ pub fn vreinterpretq_p128_s8(a: int8x16_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56358,7 +56358,7 @@ pub fn vreinterpretq_p128_s8(a: int8x16_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56380,7 +56380,7 @@ pub fn vreinterpretq_p64_s8(a: int8x16_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56407,7 +56407,7 @@ pub fn vreinterpretq_p64_s8(a: int8x16_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56429,7 +56429,7 @@ pub fn vreinterpret_p64_s16(a: int16x4_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56452,7 +56452,7 @@ pub fn vreinterpret_p64_s16(a: int16x4_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56474,7 +56474,7 @@ pub fn vreinterpretq_p128_s16(a: int16x8_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56497,7 +56497,7 @@ pub fn vreinterpretq_p128_s16(a: int16x8_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56519,7 +56519,7 @@ pub fn vreinterpretq_p64_s16(a: int16x8_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56545,7 +56545,7 @@ pub fn vreinterpretq_p64_s16(a: int16x8_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56567,7 +56567,7 @@ pub fn vreinterpret_p64_s32(a: int32x2_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56590,7 +56590,7 @@ pub fn vreinterpret_p64_s32(a: int32x2_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56612,7 +56612,7 @@ pub fn vreinterpretq_p128_s32(a: int32x4_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56635,7 +56635,7 @@ pub fn vreinterpretq_p128_s32(a: int32x4_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56657,7 +56657,7 @@ pub fn vreinterpretq_p64_s32(a: int32x4_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56683,7 +56683,7 @@ pub fn vreinterpretq_p64_s32(a: int32x4_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56705,7 +56705,7 @@ pub fn vreinterpretq_p128_s64(a: int64x2_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56728,7 +56728,7 @@ pub fn vreinterpretq_p128_s64(a: int64x2_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56750,7 +56750,7 @@ pub fn vreinterpret_p64_u8(a: uint8x8_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56773,7 +56773,7 @@ pub fn vreinterpret_p64_u8(a: uint8x8_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56795,7 +56795,7 @@ pub fn vreinterpretq_p128_u8(a: uint8x16_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56819,7 +56819,7 @@ pub fn vreinterpretq_p128_u8(a: uint8x16_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56841,7 +56841,7 @@ pub fn vreinterpretq_p64_u8(a: uint8x16_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56868,7 +56868,7 @@ pub fn vreinterpretq_p64_u8(a: uint8x16_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56890,7 +56890,7 @@ pub fn vreinterpret_p64_u16(a: uint16x4_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56913,7 +56913,7 @@ pub fn vreinterpret_p64_u16(a: uint16x4_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56935,7 +56935,7 @@ pub fn vreinterpretq_p128_u16(a: uint16x8_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56958,7 +56958,7 @@ pub fn vreinterpretq_p128_u16(a: uint16x8_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -56980,7 +56980,7 @@ pub fn vreinterpretq_p64_u16(a: uint16x8_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57006,7 +57006,7 @@ pub fn vreinterpretq_p64_u16(a: uint16x8_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57028,7 +57028,7 @@ pub fn vreinterpret_p64_u32(a: uint32x2_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57051,7 +57051,7 @@ pub fn vreinterpret_p64_u32(a: uint32x2_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57073,7 +57073,7 @@ pub fn vreinterpretq_p128_u32(a: uint32x4_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57096,7 +57096,7 @@ pub fn vreinterpretq_p128_u32(a: uint32x4_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57118,7 +57118,7 @@ pub fn vreinterpretq_p64_u32(a: uint32x4_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57144,7 +57144,7 @@ pub fn vreinterpretq_p64_u32(a: uint32x4_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57166,7 +57166,7 @@ pub fn vreinterpretq_p128_u64(a: uint64x2_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57189,7 +57189,7 @@ pub fn vreinterpretq_p128_u64(a: uint64x2_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57211,7 +57211,7 @@ pub fn vreinterpret_p64_p8(a: poly8x8_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57234,7 +57234,7 @@ pub fn vreinterpret_p64_p8(a: poly8x8_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57256,7 +57256,7 @@ pub fn vreinterpretq_p128_p8(a: poly8x16_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57280,7 +57280,7 @@ pub fn vreinterpretq_p128_p8(a: poly8x16_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57302,7 +57302,7 @@ pub fn vreinterpretq_p64_p8(a: poly8x16_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57329,7 +57329,7 @@ pub fn vreinterpretq_p64_p8(a: poly8x16_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57351,7 +57351,7 @@ pub fn vreinterpret_p64_p16(a: poly16x4_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57374,7 +57374,7 @@ pub fn vreinterpret_p64_p16(a: poly16x4_t) -> poly64x1_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57396,7 +57396,7 @@ pub fn vreinterpretq_p128_p16(a: poly16x8_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57419,7 +57419,7 @@ pub fn vreinterpretq_p128_p16(a: poly16x8_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57441,7 +57441,7 @@ pub fn vreinterpretq_p64_p16(a: poly16x8_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57467,7 +57467,7 @@ pub fn vreinterpretq_p64_p16(a: poly16x8_t) -> poly64x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57489,7 +57489,7 @@ pub fn vreinterpret_s8_p64(a: poly64x1_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57514,7 +57514,7 @@ pub fn vreinterpret_s8_p64(a: poly64x1_t) -> int8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57536,7 +57536,7 @@ pub fn vreinterpret_s16_p64(a: poly64x1_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57561,7 +57561,7 @@ pub fn vreinterpret_s16_p64(a: poly64x1_t) -> int16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57583,7 +57583,7 @@ pub fn vreinterpret_s32_p64(a: poly64x1_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_s32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57608,7 +57608,7 @@ pub fn vreinterpret_s32_p64(a: poly64x1_t) -> int32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57630,7 +57630,7 @@ pub fn vreinterpret_u8_p64(a: poly64x1_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57655,7 +57655,7 @@ pub fn vreinterpret_u8_p64(a: poly64x1_t) -> uint8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57677,7 +57677,7 @@ pub fn vreinterpret_u16_p64(a: poly64x1_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57702,7 +57702,7 @@ pub fn vreinterpret_u16_p64(a: poly64x1_t) -> uint16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57724,7 +57724,7 @@ pub fn vreinterpret_u32_p64(a: poly64x1_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_u32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57749,7 +57749,7 @@ pub fn vreinterpret_u32_p64(a: poly64x1_t) -> uint32x2_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57771,7 +57771,7 @@ pub fn vreinterpret_p8_p64(a: poly64x1_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57796,7 +57796,7 @@ pub fn vreinterpret_p8_p64(a: poly64x1_t) -> poly8x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57818,7 +57818,7 @@ pub fn vreinterpret_p16_p64(a: poly64x1_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_p16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57843,7 +57843,7 @@ pub fn vreinterpret_p16_p64(a: poly64x1_t) -> poly16x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57865,7 +57865,7 @@ pub fn vreinterpretq_p128_p64(a: poly64x2_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p128_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57888,7 +57888,7 @@ pub fn vreinterpretq_p128_p64(a: poly64x2_t) -> p128 {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57910,7 +57910,7 @@ pub fn vreinterpretq_s8_p64(a: poly64x2_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57940,7 +57940,7 @@ pub fn vreinterpretq_s8_p64(a: poly64x2_t) -> int8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57962,7 +57962,7 @@ pub fn vreinterpretq_s16_p64(a: poly64x2_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -57988,7 +57988,7 @@ pub fn vreinterpretq_s16_p64(a: poly64x2_t) -> int16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58010,7 +58010,7 @@ pub fn vreinterpretq_s32_p64(a: poly64x2_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_s32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58036,7 +58036,7 @@ pub fn vreinterpretq_s32_p64(a: poly64x2_t) -> int32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58058,7 +58058,7 @@ pub fn vreinterpretq_u8_p64(a: poly64x2_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58088,7 +58088,7 @@ pub fn vreinterpretq_u8_p64(a: poly64x2_t) -> uint8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58110,7 +58110,7 @@ pub fn vreinterpretq_u16_p64(a: poly64x2_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58136,7 +58136,7 @@ pub fn vreinterpretq_u16_p64(a: poly64x2_t) -> uint16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58158,7 +58158,7 @@ pub fn vreinterpretq_u32_p64(a: poly64x2_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_u32_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58184,7 +58184,7 @@ pub fn vreinterpretq_u32_p64(a: poly64x2_t) -> uint32x4_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58206,7 +58206,7 @@ pub fn vreinterpretq_p8_p64(a: poly64x2_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p8_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58236,7 +58236,7 @@ pub fn vreinterpretq_p8_p64(a: poly64x2_t) -> poly8x16_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58258,7 +58258,7 @@ pub fn vreinterpretq_p16_p64(a: poly64x2_t) -> poly16x8_t {
     }
     #[doc = "Vector reinterpret cast operation"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_p16_p64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -58284,7 +58284,7 @@ pub fn vreinterpretq_p16_p64(a: poly64x2_t) -> poly16x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev16_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev16.8"))]
    @@ -58305,7 +58305,7 @@ pub fn vrev16_p8(a: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev16_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev16.8"))]
    @@ -58326,7 +58326,7 @@ pub fn vrev16_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev16_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev16.8"))]
    @@ -58347,7 +58347,7 @@ pub fn vrev16_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev16q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev16.8"))]
    @@ -58368,7 +58368,7 @@ pub fn vrev16q_p8(a: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev16q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev16.8"))]
    @@ -58389,7 +58389,7 @@ pub fn vrev16q_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev16q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev16.8"))]
    @@ -58410,7 +58410,7 @@ pub fn vrev16q_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.16"))]
    @@ -58431,7 +58431,7 @@ pub fn vrev32_p16(a: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.8"))]
    @@ -58452,7 +58452,7 @@ pub fn vrev32_p8(a: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.16"))]
    @@ -58473,7 +58473,7 @@ pub fn vrev32_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.8"))]
    @@ -58494,7 +58494,7 @@ pub fn vrev32_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.16"))]
    @@ -58515,7 +58515,7 @@ pub fn vrev32_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.8"))]
    @@ -58536,7 +58536,7 @@ pub fn vrev32_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32q_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.16"))]
    @@ -58557,7 +58557,7 @@ pub fn vrev32q_p16(a: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.8"))]
    @@ -58578,7 +58578,7 @@ pub fn vrev32q_p8(a: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32q_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.16"))]
    @@ -58599,7 +58599,7 @@ pub fn vrev32q_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.8"))]
    @@ -58620,7 +58620,7 @@ pub fn vrev32q_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32q_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.16"))]
    @@ -58641,7 +58641,7 @@ pub fn vrev32q_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev32.8"))]
    @@ -58662,7 +58662,7 @@ pub fn vrev32q_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.32"))]
    @@ -58683,7 +58683,7 @@ pub fn vrev64_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.16"))]
    @@ -58704,7 +58704,7 @@ pub fn vrev64_p16(a: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.8"))]
    @@ -58725,7 +58725,7 @@ pub fn vrev64_p8(a: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.16"))]
    @@ -58746,7 +58746,7 @@ pub fn vrev64_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.32"))]
    @@ -58767,7 +58767,7 @@ pub fn vrev64_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.8"))]
    @@ -58788,7 +58788,7 @@ pub fn vrev64_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.16"))]
    @@ -58809,7 +58809,7 @@ pub fn vrev64_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.32"))]
    @@ -58830,7 +58830,7 @@ pub fn vrev64_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.8"))]
    @@ -58851,7 +58851,7 @@ pub fn vrev64_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.32"))]
    @@ -58872,7 +58872,7 @@ pub fn vrev64q_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.16"))]
    @@ -58893,7 +58893,7 @@ pub fn vrev64q_p16(a: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.8"))]
    @@ -58914,7 +58914,7 @@ pub fn vrev64q_p8(a: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.16"))]
    @@ -58935,7 +58935,7 @@ pub fn vrev64q_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.32"))]
    @@ -58956,7 +58956,7 @@ pub fn vrev64q_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.8"))]
    @@ -58977,7 +58977,7 @@ pub fn vrev64q_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.16"))]
    @@ -58998,7 +58998,7 @@ pub fn vrev64q_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.32"))]
    @@ -59019,7 +59019,7 @@ pub fn vrev64q_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Reversing vector elements (swap endianness)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrev64.8"))]
    @@ -59040,7 +59040,7 @@ pub fn vrev64q_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Reverse elements in 64-bit doublewords"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrev64))]
     #[cfg_attr(
    @@ -59062,7 +59062,7 @@ pub fn vrev64_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Reverse elements in 64-bit doublewords"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrev64))]
     #[cfg_attr(
    @@ -59084,7 +59084,7 @@ pub fn vrev64q_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.s8"))]
    @@ -59113,7 +59113,7 @@ pub fn vrhadd_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.s8"))]
    @@ -59142,7 +59142,7 @@ pub fn vrhaddq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.s16"))]
    @@ -59171,7 +59171,7 @@ pub fn vrhadd_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.s16"))]
    @@ -59200,7 +59200,7 @@ pub fn vrhaddq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.s32"))]
    @@ -59229,7 +59229,7 @@ pub fn vrhadd_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.s32"))]
    @@ -59258,7 +59258,7 @@ pub fn vrhaddq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.u8"))]
    @@ -59287,7 +59287,7 @@ pub fn vrhadd_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.u8"))]
    @@ -59316,7 +59316,7 @@ pub fn vrhaddq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.u16"))]
    @@ -59345,7 +59345,7 @@ pub fn vrhadd_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.u16"))]
    @@ -59374,7 +59374,7 @@ pub fn vrhaddq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhadd_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.u32"))]
    @@ -59403,7 +59403,7 @@ pub fn vrhadd_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Rounding halving add"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrhaddq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vrhadd.u32"))]
    @@ -59432,7 +59432,7 @@ pub fn vrhaddq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndn_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrintn))]
     #[cfg_attr(
    @@ -59461,7 +59461,7 @@ pub fn vrndn_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndnq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrintn))]
     #[cfg_attr(
    @@ -59490,7 +59490,7 @@ pub fn vrndnq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndn_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrintn))]
    @@ -59518,7 +59518,7 @@ pub fn vrndn_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point round to integral, to nearest with ties to even"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndnq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp-armv8,v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrintn))]
    @@ -59546,7 +59546,7 @@ pub fn vrndnq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Signed rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59575,7 +59575,7 @@ pub fn vrshl_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59604,7 +59604,7 @@ pub fn vrshlq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59633,7 +59633,7 @@ pub fn vrshl_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59662,7 +59662,7 @@ pub fn vrshlq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59691,7 +59691,7 @@ pub fn vrshl_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59720,7 +59720,7 @@ pub fn vrshlq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59749,7 +59749,7 @@ pub fn vrshl_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59778,7 +59778,7 @@ pub fn vrshlq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59807,7 +59807,7 @@ pub fn vrshl_u8(a: uint8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59836,7 +59836,7 @@ pub fn vrshlq_u8(a: uint8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59865,7 +59865,7 @@ pub fn vrshl_u16(a: uint16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59894,7 +59894,7 @@ pub fn vrshlq_u16(a: uint16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59923,7 +59923,7 @@ pub fn vrshl_u32(a: uint32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59952,7 +59952,7 @@ pub fn vrshlq_u32(a: uint32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshl_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -59981,7 +59981,7 @@ pub fn vrshl_u64(a: uint64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned rounding shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshlq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshl))]
    @@ -60010,7 +60010,7 @@ pub fn vrshlq_u64(a: uint64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60033,7 +60033,7 @@ pub fn vrshr_n_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60056,7 +60056,7 @@ pub fn vrshrq_n_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60079,7 +60079,7 @@ pub fn vrshr_n_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60102,7 +60102,7 @@ pub fn vrshrq_n_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60125,7 +60125,7 @@ pub fn vrshr_n_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60148,7 +60148,7 @@ pub fn vrshrq_n_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60171,7 +60171,7 @@ pub fn vrshr_n_s64(a: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60194,7 +60194,7 @@ pub fn vrshrq_n_s64(a: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60217,7 +60217,7 @@ pub fn vrshr_n_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60240,7 +60240,7 @@ pub fn vrshrq_n_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60263,7 +60263,7 @@ pub fn vrshr_n_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60286,7 +60286,7 @@ pub fn vrshrq_n_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60309,7 +60309,7 @@ pub fn vrshr_n_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60332,7 +60332,7 @@ pub fn vrshrq_n_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshr_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60355,7 +60355,7 @@ pub fn vrshr_n_u64(a: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned rounding shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshr, N = 2))]
    @@ -60378,7 +60378,7 @@ pub fn vrshrq_n_u64(a: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vrshrn, N = 2))]
    @@ -60394,7 +60394,7 @@ pub fn vrshrn_n_s16(a: int16x8_t) -> int8x8_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vrshrn, N = 2))]
    @@ -60410,7 +60410,7 @@ pub fn vrshrn_n_s32(a: int32x4_t) -> int16x4_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vrshrn, N = 2))]
    @@ -60426,7 +60426,7 @@ pub fn vrshrn_n_s64(a: int64x2_t) -> int32x2_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(rshrn, N = 2))]
    @@ -60445,7 +60445,7 @@ pub fn vrshrn_n_s16(a: int16x8_t) -> int8x8_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(rshrn, N = 2))]
    @@ -60464,7 +60464,7 @@ pub fn vrshrn_n_s32(a: int32x4_t) -> int16x4_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(rshrn, N = 2))]
    @@ -60483,7 +60483,7 @@ pub fn vrshrn_n_s64(a: int64x2_t) -> int32x2_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshrn, N = 2))]
    @@ -60506,7 +60506,7 @@ pub fn vrshrn_n_u16(a: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshrn, N = 2))]
    @@ -60529,7 +60529,7 @@ pub fn vrshrn_n_u32(a: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Rounding shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshrn_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrshrn, N = 2))]
    @@ -60552,7 +60552,7 @@ pub fn vrshrn_n_u64(a: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Reciprocal square-root estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrte_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrte))]
    @@ -60582,7 +60582,7 @@ pub fn vrsqrte_f16(a: float16x4_t) -> float16x4_t {
     }
     #[doc = "Reciprocal square-root estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrte))]
    @@ -60612,7 +60612,7 @@ pub fn vrsqrteq_f16(a: float16x8_t) -> float16x8_t {
     }
     #[doc = "Reciprocal square-root estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrte_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrte))]
    @@ -60641,7 +60641,7 @@ pub fn vrsqrte_f32(a: float32x2_t) -> float32x2_t {
     }
     #[doc = "Reciprocal square-root estimate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrte))]
    @@ -60670,7 +60670,7 @@ pub fn vrsqrteq_f32(a: float32x4_t) -> float32x4_t {
     }
     #[doc = "Unsigned reciprocal square root estimate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrte_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrte))]
    @@ -60699,7 +60699,7 @@ pub fn vrsqrte_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned reciprocal square root estimate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrte))]
    @@ -60728,7 +60728,7 @@ pub fn vrsqrteq_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Floating-point reciprocal square root step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrts_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrts))]
    @@ -60758,7 +60758,7 @@ pub fn vrsqrts_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Floating-point reciprocal square root step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtsq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,fp16")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrts))]
    @@ -60788,7 +60788,7 @@ pub fn vrsqrtsq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Floating-point reciprocal square root step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrts_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrts))]
    @@ -60817,7 +60817,7 @@ pub fn vrsqrts_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Floating-point reciprocal square root step"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrtsq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsqrts))]
    @@ -60846,7 +60846,7 @@ pub fn vrsqrtsq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Signed rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -60869,7 +60869,7 @@ pub fn vrsra_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -60892,7 +60892,7 @@ pub fn vrsraq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -60915,7 +60915,7 @@ pub fn vrsra_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -60938,7 +60938,7 @@ pub fn vrsraq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -60961,7 +60961,7 @@ pub fn vrsra_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -60984,7 +60984,7 @@ pub fn vrsraq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61007,7 +61007,7 @@ pub fn vrsra_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61030,7 +61030,7 @@ pub fn vrsraq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61053,7 +61053,7 @@ pub fn vrsra_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61076,7 +61076,7 @@ pub fn vrsraq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61099,7 +61099,7 @@ pub fn vrsra_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61122,7 +61122,7 @@ pub fn vrsraq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61145,7 +61145,7 @@ pub fn vrsra_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61168,7 +61168,7 @@ pub fn vrsraq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsra_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61191,7 +61191,7 @@ pub fn vrsra_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned rounding shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsraq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsra, N = 2))]
    @@ -61214,7 +61214,7 @@ pub fn vrsraq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsubhn))]
    @@ -61243,7 +61243,7 @@ pub fn vrsubhn_s16(a: int16x8_t, b: int16x8_t) -> int8x8_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsubhn))]
    @@ -61272,7 +61272,7 @@ pub fn vrsubhn_s32(a: int32x4_t, b: int32x4_t) -> int16x4_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vrsubhn))]
    @@ -61301,7 +61301,7 @@ pub fn vrsubhn_s64(a: int64x2_t, b: int64x2_t) -> int32x2_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -61323,7 +61323,7 @@ pub fn vrsubhn_u16(a: uint16x8_t, b: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -61350,7 +61350,7 @@ pub fn vrsubhn_u16(a: uint16x8_t, b: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -61372,7 +61372,7 @@ pub fn vrsubhn_u32(a: uint32x4_t, b: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -61399,7 +61399,7 @@ pub fn vrsubhn_u32(a: uint32x4_t, b: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -61421,7 +61421,7 @@ pub fn vrsubhn_u64(a: uint64x2_t, b: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Rounding subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsubhn_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -61448,7 +61448,7 @@ pub fn vrsubhn_u64(a: uint64x2_t, b: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
     #[cfg_attr(
    @@ -61465,7 +61465,7 @@ pub fn vset_lane_f16(a: f16, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
     #[cfg_attr(
    @@ -61482,7 +61482,7 @@ pub fn vsetq_lane_f16(a: f16, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61505,7 +61505,7 @@ pub fn vset_lane_f32(a: f32, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61528,7 +61528,7 @@ pub fn vsetq_lane_f32(a: f32, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61551,7 +61551,7 @@ pub fn vset_lane_s8(a: i8, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61574,7 +61574,7 @@ pub fn vsetq_lane_s8(a: i8, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61597,7 +61597,7 @@ pub fn vset_lane_s16(a: i16, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61620,7 +61620,7 @@ pub fn vsetq_lane_s16(a: i16, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61643,7 +61643,7 @@ pub fn vset_lane_s32(a: i32, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61666,7 +61666,7 @@ pub fn vsetq_lane_s32(a: i32, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61689,7 +61689,7 @@ pub fn vsetq_lane_s64(a: i64, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61712,7 +61712,7 @@ pub fn vset_lane_u8(a: u8, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61735,7 +61735,7 @@ pub fn vsetq_lane_u8(a: u8, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61758,7 +61758,7 @@ pub fn vset_lane_u16(a: u16, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61781,7 +61781,7 @@ pub fn vsetq_lane_u16(a: u16, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61804,7 +61804,7 @@ pub fn vset_lane_u32(a: u32, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61827,7 +61827,7 @@ pub fn vsetq_lane_u32(a: u32, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61850,7 +61850,7 @@ pub fn vsetq_lane_u64(a: u64, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61873,7 +61873,7 @@ pub fn vset_lane_p8(a: p8, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61896,7 +61896,7 @@ pub fn vsetq_lane_p8(a: p8, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61919,7 +61919,7 @@ pub fn vset_lane_p16(a: p16, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61942,7 +61942,7 @@ pub fn vsetq_lane_p16(a: p16, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61965,7 +61965,7 @@ pub fn vset_lane_p64(a: p64, b: poly64x1_t) -> poly64x1_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -61988,7 +61988,7 @@ pub fn vset_lane_s64(a: i64, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vset_lane_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -62011,7 +62011,7 @@ pub fn vset_lane_u64(a: u64, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Insert vector element from another vector element"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsetq_lane_p64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -62034,7 +62034,7 @@ pub fn vsetq_lane_p64(a: p64, b: poly64x2_t) -> poly64x2_t {
     }
     #[doc = "SHA1 hash update accelerator, choose."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1cq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha1c))]
    @@ -62059,7 +62059,7 @@ pub fn vsha1cq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32
     }
     #[doc = "SHA1 fixed rotate."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1h_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha1h))]
    @@ -62084,7 +62084,7 @@ pub fn vsha1h_u32(hash_e: u32) -> u32 {
     }
     #[doc = "SHA1 hash update accelerator, majority"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1mq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha1m))]
    @@ -62109,7 +62109,7 @@ pub fn vsha1mq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32
     }
     #[doc = "SHA1 hash update accelerator, parity"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1pq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha1p))]
    @@ -62134,7 +62134,7 @@ pub fn vsha1pq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32
     }
     #[doc = "SHA1 schedule update accelerator, first part."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1su0q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha1su0))]
    @@ -62159,7 +62159,7 @@ pub fn vsha1su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t, w8_11: uint32x4_t) -> u
     }
     #[doc = "SHA1 schedule update accelerator, second part."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha1su1q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha1su1))]
    @@ -62184,7 +62184,7 @@ pub fn vsha1su1q_u32(tw0_3: uint32x4_t, w12_15: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "SHA1 schedule update accelerator, upper part."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha256h2q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha256h2))]
    @@ -62213,7 +62213,7 @@ pub fn vsha256h2q_u32(hash_abcd: uint32x4_t, hash_efgh: uint32x4_t, wk: uint32x4
     }
     #[doc = "SHA1 schedule update accelerator, first part."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha256hq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha256h))]
    @@ -62242,7 +62242,7 @@ pub fn vsha256hq_u32(hash_abcd: uint32x4_t, hash_efgh: uint32x4_t, wk: uint32x4_
     }
     #[doc = "SHA256 schedule update accelerator, first part."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha256su0q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha256su0))]
    @@ -62267,7 +62267,7 @@ pub fn vsha256su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "SHA256 schedule update accelerator, second part."]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsha256su1q_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "sha2")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(test, assert_instr(sha256su1))]
    @@ -62291,7 +62291,7 @@ pub fn vsha256su1q_u32(tw0_3: uint32x4_t, w8_11: uint32x4_t, w12_15: uint32x4_t)
         }
         unsafe { _vsha256su1q_u32(tw0_3, w8_11, w12_15) }
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62304,7 +62304,7 @@ fn vshiftlins_v16i8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
         }
         unsafe { _vshiftlins_v16i8(a, b, const { int8x16_t([N as i8; 16]) }) }
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62317,7 +62317,7 @@ fn vshiftlins_v1i64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
         }
         unsafe { _vshiftlins_v1i64(a, b, const { int64x1_t([N as i64; 1]) }) }
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62330,7 +62330,7 @@ fn vshiftlins_v2i32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
         }
         unsafe { _vshiftlins_v2i32(a, b, const { int32x2_t([N; 2]) }) }
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62343,7 +62343,7 @@ fn vshiftlins_v2i64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
         }
         unsafe { _vshiftlins_v2i64(a, b, const { int64x2_t([N as i64; 2]) }) }
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62356,7 +62356,7 @@ fn vshiftlins_v4i16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
         }
         unsafe { _vshiftlins_v4i16(a, b, const { int16x4_t([N as i16; 4]) }) }
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62369,7 +62369,7 @@ fn vshiftlins_v4i32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
         }
         unsafe { _vshiftlins_v4i32(a, b, const { int32x4_t([N; 4]) }) }
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62382,7 +62382,7 @@ fn vshiftlins_v8i16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
         }
         unsafe { _vshiftlins_v8i16(a, b, const { int16x8_t([N as i16; 8]) }) }
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62397,7 +62397,7 @@ fn vshiftlins_v8i8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v16i8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62412,7 +62412,7 @@ fn vshiftrins_v16i8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v1i64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62427,7 +62427,7 @@ fn vshiftrins_v1i64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v2i32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62442,7 +62442,7 @@ fn vshiftrins_v2i32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v2i64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62457,7 +62457,7 @@ fn vshiftrins_v2i64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v4i16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62472,7 +62472,7 @@ fn vshiftrins_v4i16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v4i32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62487,7 +62487,7 @@ fn vshiftrins_v4i32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v8i16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62502,7 +62502,7 @@ fn vshiftrins_v8i16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshiftrins_v8i8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -62517,7 +62517,7 @@ fn vshiftrins_v8i8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62540,7 +62540,7 @@ pub fn vshl_n_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62563,7 +62563,7 @@ pub fn vshlq_n_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62586,7 +62586,7 @@ pub fn vshl_n_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62609,7 +62609,7 @@ pub fn vshlq_n_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62632,7 +62632,7 @@ pub fn vshl_n_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62655,7 +62655,7 @@ pub fn vshlq_n_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62678,7 +62678,7 @@ pub fn vshl_n_s64(a: int64x1_t) -> int64x1_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62701,7 +62701,7 @@ pub fn vshlq_n_s64(a: int64x2_t) -> int64x2_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62724,7 +62724,7 @@ pub fn vshl_n_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62747,7 +62747,7 @@ pub fn vshlq_n_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62770,7 +62770,7 @@ pub fn vshl_n_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62793,7 +62793,7 @@ pub fn vshlq_n_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62816,7 +62816,7 @@ pub fn vshl_n_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62839,7 +62839,7 @@ pub fn vshlq_n_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62862,7 +62862,7 @@ pub fn vshl_n_u64(a: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl, N = 2))]
    @@ -62885,7 +62885,7 @@ pub fn vshlq_n_u64(a: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -62914,7 +62914,7 @@ pub fn vshl_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -62943,7 +62943,7 @@ pub fn vshlq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -62972,7 +62972,7 @@ pub fn vshl_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63001,7 +63001,7 @@ pub fn vshlq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63030,7 +63030,7 @@ pub fn vshl_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63059,7 +63059,7 @@ pub fn vshlq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63088,7 +63088,7 @@ pub fn vshl_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63117,7 +63117,7 @@ pub fn vshlq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63146,7 +63146,7 @@ pub fn vshl_u8(a: uint8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63175,7 +63175,7 @@ pub fn vshlq_u8(a: uint8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63204,7 +63204,7 @@ pub fn vshl_u16(a: uint16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63233,7 +63233,7 @@ pub fn vshlq_u16(a: uint16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63262,7 +63262,7 @@ pub fn vshl_u32(a: uint32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63291,7 +63291,7 @@ pub fn vshlq_u32(a: uint32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshl_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63320,7 +63320,7 @@ pub fn vshl_u64(a: uint64x1_t, b: int64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned Shift left"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshlq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vshl))]
    @@ -63349,7 +63349,7 @@ pub fn vshlq_u64(a: uint64x2_t, b: int64x2_t) -> uint64x2_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshll.s16", N = 2))]
    @@ -63372,7 +63372,7 @@ pub fn vshll_n_s16(a: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshll.s32", N = 2))]
    @@ -63395,7 +63395,7 @@ pub fn vshll_n_s32(a: int32x2_t) -> int64x2_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshll.s8", N = 2))]
    @@ -63418,7 +63418,7 @@ pub fn vshll_n_s8(a: int8x8_t) -> int16x8_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshll.u16", N = 2))]
    @@ -63441,7 +63441,7 @@ pub fn vshll_n_u16(a: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshll.u32", N = 2))]
    @@ -63464,7 +63464,7 @@ pub fn vshll_n_u32(a: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Signed shift left long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshll_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshll.u8", N = 2))]
    @@ -63487,7 +63487,7 @@ pub fn vshll_n_u8(a: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.s8", N = 2))]
    @@ -63511,7 +63511,7 @@ pub fn vshr_n_s8(a: int8x8_t) -> int8x8_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.s8", N = 2))]
    @@ -63535,7 +63535,7 @@ pub fn vshrq_n_s8(a: int8x16_t) -> int8x16_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.s16", N = 2))]
    @@ -63559,7 +63559,7 @@ pub fn vshr_n_s16(a: int16x4_t) -> int16x4_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.s16", N = 2))]
    @@ -63583,7 +63583,7 @@ pub fn vshrq_n_s16(a: int16x8_t) -> int16x8_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.s32", N = 2))]
    @@ -63607,7 +63607,7 @@ pub fn vshr_n_s32(a: int32x2_t) -> int32x2_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.s32", N = 2))]
    @@ -63631,7 +63631,7 @@ pub fn vshrq_n_s32(a: int32x4_t) -> int32x4_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.s64", N = 2))]
    @@ -63655,7 +63655,7 @@ pub fn vshr_n_s64(a: int64x1_t) -> int64x1_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.s64", N = 2))]
    @@ -63679,7 +63679,7 @@ pub fn vshrq_n_s64(a: int64x2_t) -> int64x2_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.u8", N = 2))]
    @@ -63707,7 +63707,7 @@ pub fn vshr_n_u8(a: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.u8", N = 2))]
    @@ -63735,7 +63735,7 @@ pub fn vshrq_n_u8(a: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.u16", N = 2))]
    @@ -63763,7 +63763,7 @@ pub fn vshr_n_u16(a: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.u16", N = 2))]
    @@ -63791,7 +63791,7 @@ pub fn vshrq_n_u16(a: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.u32", N = 2))]
    @@ -63819,7 +63819,7 @@ pub fn vshr_n_u32(a: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.u32", N = 2))]
    @@ -63847,7 +63847,7 @@ pub fn vshrq_n_u32(a: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshr_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.u64", N = 2))]
    @@ -63875,7 +63875,7 @@ pub fn vshr_n_u64(a: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Shift right"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshr.u64", N = 2))]
    @@ -63903,7 +63903,7 @@ pub fn vshrq_n_u64(a: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshrn.i16", N = 2))]
    @@ -63926,7 +63926,7 @@ pub fn vshrn_n_s16(a: int16x8_t) -> int8x8_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshrn.i32", N = 2))]
    @@ -63949,7 +63949,7 @@ pub fn vshrn_n_s32(a: int32x4_t) -> int16x4_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshrn.i64", N = 2))]
    @@ -63972,7 +63972,7 @@ pub fn vshrn_n_s64(a: int64x2_t) -> int32x2_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshrn.i16", N = 2))]
    @@ -63995,7 +63995,7 @@ pub fn vshrn_n_u16(a: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshrn.i32", N = 2))]
    @@ -64018,7 +64018,7 @@ pub fn vshrn_n_u32(a: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Shift right narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vshrn_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vshrn.i64", N = 2))]
    @@ -64041,7 +64041,7 @@ pub fn vshrn_n_u64(a: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64053,7 +64053,7 @@ pub fn vsli_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64065,7 +64065,7 @@ pub fn vsliq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64077,7 +64077,7 @@ pub fn vsli_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64089,7 +64089,7 @@ pub fn vsliq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64101,7 +64101,7 @@ pub fn vsli_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64113,7 +64113,7 @@ pub fn vsliq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64125,7 +64125,7 @@ pub fn vsli_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64137,7 +64137,7 @@ pub fn vsliq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64149,7 +64149,7 @@ pub fn vsli_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64161,7 +64161,7 @@ pub fn vsliq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64173,7 +64173,7 @@ pub fn vsli_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64185,7 +64185,7 @@ pub fn vsliq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64197,7 +64197,7 @@ pub fn vsli_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64209,7 +64209,7 @@ pub fn vsliq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64221,7 +64221,7 @@ pub fn vsli_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64233,7 +64233,7 @@ pub fn vsliq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64245,7 +64245,7 @@ pub fn vsli_n_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64257,7 +64257,7 @@ pub fn vsliq_n_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsli_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64269,7 +64269,7 @@ pub fn vsli_n_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Shift Left and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsliq_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64281,7 +64281,7 @@ pub fn vsliq_n_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     }
     #[doc = "Signed shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64304,7 +64304,7 @@ pub fn vsra_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Signed shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64327,7 +64327,7 @@ pub fn vsraq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Signed shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64350,7 +64350,7 @@ pub fn vsra_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Signed shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64373,7 +64373,7 @@ pub fn vsraq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Signed shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64396,7 +64396,7 @@ pub fn vsra_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Signed shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64419,7 +64419,7 @@ pub fn vsraq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Signed shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64442,7 +64442,7 @@ pub fn vsra_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Signed shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64465,7 +64465,7 @@ pub fn vsraq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64488,7 +64488,7 @@ pub fn vsra_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64511,7 +64511,7 @@ pub fn vsraq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64534,7 +64534,7 @@ pub fn vsra_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64557,7 +64557,7 @@ pub fn vsraq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64580,7 +64580,7 @@ pub fn vsra_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64603,7 +64603,7 @@ pub fn vsraq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsra_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64626,7 +64626,7 @@ pub fn vsra_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Unsigned shift right and accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsraq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsra, N = 2))]
    @@ -64649,7 +64649,7 @@ pub fn vsraq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64661,7 +64661,7 @@ pub fn vsri_n_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64673,7 +64673,7 @@ pub fn vsriq_n_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64685,7 +64685,7 @@ pub fn vsri_n_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64697,7 +64697,7 @@ pub fn vsriq_n_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64709,7 +64709,7 @@ pub fn vsri_n_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64721,7 +64721,7 @@ pub fn vsriq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64733,7 +64733,7 @@ pub fn vsri_n_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64745,7 +64745,7 @@ pub fn vsriq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64757,7 +64757,7 @@ pub fn vsri_n_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64769,7 +64769,7 @@ pub fn vsriq_n_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64781,7 +64781,7 @@ pub fn vsri_n_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64793,7 +64793,7 @@ pub fn vsriq_n_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64805,7 +64805,7 @@ pub fn vsri_n_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64817,7 +64817,7 @@ pub fn vsriq_n_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64829,7 +64829,7 @@ pub fn vsri_n_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_u64)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64841,7 +64841,7 @@ pub fn vsriq_n_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64853,7 +64853,7 @@ pub fn vsri_n_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64865,7 +64865,7 @@ pub fn vsriq_n_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64877,7 +64877,7 @@ pub fn vsri_n_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4_t {
     }
     #[doc = "Shift Right and Insert (immediate)"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsriq_n_p16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -64891,7 +64891,7 @@ pub fn vsriq_n_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8_t {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[target_feature(enable = "neon,fp16")]
    @@ -64909,7 +64909,7 @@ pub unsafe fn vst1_f16(ptr: *mut f16, a: float16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[target_feature(enable = "neon,fp16")]
    @@ -64927,7 +64927,7 @@ pub unsafe fn vst1q_f16(ptr: *mut f16, a: float16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(vst1))]
    @@ -64945,7 +64945,7 @@ pub unsafe fn vst1_f16_x2(a: *mut f16, b: float16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(vst1))]
    @@ -64963,7 +64963,7 @@ pub unsafe fn vst1q_f16_x2(a: *mut f16, b: float16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
     #[target_feature(enable = "neon,fp16")]
    @@ -64983,7 +64983,7 @@ pub unsafe fn vst1_f16_x2(a: *mut f16, b: float16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
     #[target_feature(enable = "neon,fp16")]
    @@ -65003,7 +65003,7 @@ pub unsafe fn vst1q_f16_x2(a: *mut f16, b: float16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(vst1))]
    @@ -65021,7 +65021,7 @@ pub unsafe fn vst1_f16_x3(a: *mut f16, b: float16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(test, assert_instr(vst1))]
    @@ -65039,7 +65039,7 @@ pub unsafe fn vst1q_f16_x3(a: *mut f16, b: float16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
     #[target_feature(enable = "neon,fp16")]
    @@ -65059,7 +65059,7 @@ pub unsafe fn vst1_f16_x3(a: *mut f16, b: float16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
     #[target_feature(enable = "neon,fp16")]
    @@ -65079,7 +65079,7 @@ pub unsafe fn vst1q_f16_x3(a: *mut f16, b: float16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65104,7 +65104,7 @@ pub unsafe fn vst1_f16_x4(a: *mut f16, b: float16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65129,7 +65129,7 @@ pub unsafe fn vst1q_f16_x4(a: *mut f16, b: float16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
     #[target_feature(enable = "neon,fp16")]
    @@ -65155,7 +65155,7 @@ pub unsafe fn vst1_f16_x4(a: *mut f16, b: float16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
     #[target_feature(enable = "neon,fp16")]
    @@ -65181,7 +65181,7 @@ pub unsafe fn vst1q_f16_x4(a: *mut f16, b: float16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65195,7 +65195,7 @@ pub unsafe fn vst1_f32(ptr: *mut f32, a: float32x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65209,7 +65209,7 @@ pub unsafe fn vst1q_f32(ptr: *mut f32, a: float32x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65223,7 +65223,7 @@ pub unsafe fn vst1_s8(ptr: *mut i8, a: int8x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65237,7 +65237,7 @@ pub unsafe fn vst1q_s8(ptr: *mut i8, a: int8x16_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65251,7 +65251,7 @@ pub unsafe fn vst1_s16(ptr: *mut i16, a: int16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65265,7 +65265,7 @@ pub unsafe fn vst1q_s16(ptr: *mut i16, a: int16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65279,7 +65279,7 @@ pub unsafe fn vst1_s32(ptr: *mut i32, a: int32x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65293,7 +65293,7 @@ pub unsafe fn vst1q_s32(ptr: *mut i32, a: int32x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65307,7 +65307,7 @@ pub unsafe fn vst1_s64(ptr: *mut i64, a: int64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65321,7 +65321,7 @@ pub unsafe fn vst1q_s64(ptr: *mut i64, a: int64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65335,7 +65335,7 @@ pub unsafe fn vst1_u8(ptr: *mut u8, a: uint8x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65349,7 +65349,7 @@ pub unsafe fn vst1q_u8(ptr: *mut u8, a: uint8x16_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65363,7 +65363,7 @@ pub unsafe fn vst1_u16(ptr: *mut u16, a: uint16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65377,7 +65377,7 @@ pub unsafe fn vst1q_u16(ptr: *mut u16, a: uint16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65391,7 +65391,7 @@ pub unsafe fn vst1_u32(ptr: *mut u32, a: uint32x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65405,7 +65405,7 @@ pub unsafe fn vst1q_u32(ptr: *mut u32, a: uint32x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65419,7 +65419,7 @@ pub unsafe fn vst1_u64(ptr: *mut u64, a: uint64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65433,7 +65433,7 @@ pub unsafe fn vst1q_u64(ptr: *mut u64, a: uint64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65447,7 +65447,7 @@ pub unsafe fn vst1_p8(ptr: *mut p8, a: poly8x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65461,7 +65461,7 @@ pub unsafe fn vst1q_p8(ptr: *mut p8, a: poly8x16_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65475,7 +65475,7 @@ pub unsafe fn vst1_p16(ptr: *mut p16, a: poly16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65489,7 +65489,7 @@ pub unsafe fn vst1q_p16(ptr: *mut p16, a: poly16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65503,7 +65503,7 @@ pub unsafe fn vst1_p64(ptr: *mut p64, a: poly64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -65517,7 +65517,7 @@ pub unsafe fn vst1q_p64(ptr: *mut p64, a: poly64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst1))]
    @@ -65533,7 +65533,7 @@ pub unsafe fn vst1_f32_x2(a: *mut f32, b: float32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst1))]
    @@ -65549,7 +65549,7 @@ pub unsafe fn vst1q_f32_x2(a: *mut f32, b: float32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
    @@ -65568,7 +65568,7 @@ pub unsafe fn vst1_f32_x2(a: *mut f32, b: float32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
    @@ -65587,7 +65587,7 @@ pub unsafe fn vst1q_f32_x2(a: *mut f32, b: float32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
    @@ -65606,7 +65606,7 @@ pub unsafe fn vst1_f32_x3(a: *mut f32, b: float32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
    @@ -65625,7 +65625,7 @@ pub unsafe fn vst1q_f32_x3(a: *mut f32, b: float32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -65647,7 +65647,7 @@ pub unsafe fn vst1_f32_x4(a: *mut f32, b: float32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -65669,7 +65669,7 @@ pub unsafe fn vst1q_f32_x4(a: *mut f32, b: float32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_f32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
    @@ -65694,7 +65694,7 @@ pub unsafe fn vst1_f32_x4(a: *mut f32, b: float32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_f32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(test, assert_instr(st1))]
    @@ -65719,7 +65719,7 @@ pub unsafe fn vst1q_f32_x4(a: *mut f32, b: float32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65739,7 +65739,7 @@ pub unsafe fn vst1_lane_f16(a: *mut f16, b: float16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65759,7 +65759,7 @@ pub unsafe fn vst1q_lane_f16(a: *mut f16, b: float16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65784,7 +65784,7 @@ pub unsafe fn vst1_lane_f32(a: *mut f32, b: float32x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65809,7 +65809,7 @@ pub unsafe fn vst1q_lane_f32(a: *mut f32, b: float32x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65834,7 +65834,7 @@ pub unsafe fn vst1_lane_s8(a: *mut i8, b: int8x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65859,7 +65859,7 @@ pub unsafe fn vst1q_lane_s8(a: *mut i8, b: int8x16_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65884,7 +65884,7 @@ pub unsafe fn vst1_lane_s16(a: *mut i16, b: int16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65909,7 +65909,7 @@ pub unsafe fn vst1q_lane_s16(a: *mut i16, b: int16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65934,7 +65934,7 @@ pub unsafe fn vst1_lane_s32(a: *mut i32, b: int32x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65959,7 +65959,7 @@ pub unsafe fn vst1q_lane_s32(a: *mut i32, b: int32x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -65984,7 +65984,7 @@ pub unsafe fn vst1q_lane_s64(a: *mut i64, b: int64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66009,7 +66009,7 @@ pub unsafe fn vst1_lane_u8(a: *mut u8, b: uint8x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66034,7 +66034,7 @@ pub unsafe fn vst1q_lane_u8(a: *mut u8, b: uint8x16_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66059,7 +66059,7 @@ pub unsafe fn vst1_lane_u16(a: *mut u16, b: uint16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66084,7 +66084,7 @@ pub unsafe fn vst1q_lane_u16(a: *mut u16, b: uint16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66109,7 +66109,7 @@ pub unsafe fn vst1_lane_u32(a: *mut u32, b: uint32x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66134,7 +66134,7 @@ pub unsafe fn vst1q_lane_u32(a: *mut u32, b: uint32x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66159,7 +66159,7 @@ pub unsafe fn vst1q_lane_u64(a: *mut u64, b: uint64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66184,7 +66184,7 @@ pub unsafe fn vst1_lane_p8(a: *mut p8, b: poly8x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66209,7 +66209,7 @@ pub unsafe fn vst1q_lane_p8(a: *mut p8, b: poly8x16_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66234,7 +66234,7 @@ pub unsafe fn vst1_lane_p16(a: *mut p16, b: poly16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66259,7 +66259,7 @@ pub unsafe fn vst1q_lane_p16(a: *mut p16, b: poly16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66284,7 +66284,7 @@ pub unsafe fn vst1_lane_p64(a: *mut p64, b: poly64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66309,7 +66309,7 @@ pub unsafe fn vst1_lane_s64(a: *mut i64, b: int64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_lane_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -66334,7 +66334,7 @@ pub unsafe fn vst1_lane_u64(a: *mut u64, b: uint64x1_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -66357,7 +66357,7 @@ pub unsafe fn vst1_p64_x2(a: *mut p64, b: poly64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -66380,7 +66380,7 @@ pub unsafe fn vst1_p64_x3(a: *mut p64, b: poly64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -66403,7 +66403,7 @@ pub unsafe fn vst1_p64_x4(a: *mut p64, b: poly64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -66426,7 +66426,7 @@ pub unsafe fn vst1q_p64_x2(a: *mut p64, b: poly64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -66449,7 +66449,7 @@ pub unsafe fn vst1q_p64_x3(a: *mut p64, b: poly64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -66472,7 +66472,7 @@ pub unsafe fn vst1q_p64_x4(a: *mut p64, b: poly64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66491,7 +66491,7 @@ pub unsafe fn vst1_s8_x2(a: *mut i8, b: int8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66510,7 +66510,7 @@ pub unsafe fn vst1q_s8_x2(a: *mut i8, b: int8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66529,7 +66529,7 @@ pub unsafe fn vst1_s16_x2(a: *mut i16, b: int16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66548,7 +66548,7 @@ pub unsafe fn vst1q_s16_x2(a: *mut i16, b: int16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66567,7 +66567,7 @@ pub unsafe fn vst1_s32_x2(a: *mut i32, b: int32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66586,7 +66586,7 @@ pub unsafe fn vst1q_s32_x2(a: *mut i32, b: int32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66605,7 +66605,7 @@ pub unsafe fn vst1_s64_x2(a: *mut i64, b: int64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66624,7 +66624,7 @@ pub unsafe fn vst1q_s64_x2(a: *mut i64, b: int64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66640,7 +66640,7 @@ pub unsafe fn vst1_s8_x2(a: *mut i8, b: int8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66656,7 +66656,7 @@ pub unsafe fn vst1q_s8_x2(a: *mut i8, b: int8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66672,7 +66672,7 @@ pub unsafe fn vst1_s16_x2(a: *mut i16, b: int16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66688,7 +66688,7 @@ pub unsafe fn vst1q_s16_x2(a: *mut i16, b: int16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66704,7 +66704,7 @@ pub unsafe fn vst1_s32_x2(a: *mut i32, b: int32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66720,7 +66720,7 @@ pub unsafe fn vst1q_s32_x2(a: *mut i32, b: int32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66736,7 +66736,7 @@ pub unsafe fn vst1_s64_x2(a: *mut i64, b: int64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66752,7 +66752,7 @@ pub unsafe fn vst1q_s64_x2(a: *mut i64, b: int64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66771,7 +66771,7 @@ pub unsafe fn vst1_s8_x3(a: *mut i8, b: int8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66790,7 +66790,7 @@ pub unsafe fn vst1q_s8_x3(a: *mut i8, b: int8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66809,7 +66809,7 @@ pub unsafe fn vst1_s16_x3(a: *mut i16, b: int16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66828,7 +66828,7 @@ pub unsafe fn vst1q_s16_x3(a: *mut i16, b: int16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66847,7 +66847,7 @@ pub unsafe fn vst1_s32_x3(a: *mut i32, b: int32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66866,7 +66866,7 @@ pub unsafe fn vst1q_s32_x3(a: *mut i32, b: int32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66885,7 +66885,7 @@ pub unsafe fn vst1_s64_x3(a: *mut i64, b: int64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -66904,7 +66904,7 @@ pub unsafe fn vst1q_s64_x3(a: *mut i64, b: int64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66920,7 +66920,7 @@ pub unsafe fn vst1_s8_x3(a: *mut i8, b: int8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66936,7 +66936,7 @@ pub unsafe fn vst1q_s8_x3(a: *mut i8, b: int8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66952,7 +66952,7 @@ pub unsafe fn vst1_s16_x3(a: *mut i16, b: int16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66968,7 +66968,7 @@ pub unsafe fn vst1q_s16_x3(a: *mut i16, b: int16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -66984,7 +66984,7 @@ pub unsafe fn vst1_s32_x3(a: *mut i32, b: int32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67000,7 +67000,7 @@ pub unsafe fn vst1q_s32_x3(a: *mut i32, b: int32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67016,7 +67016,7 @@ pub unsafe fn vst1_s64_x3(a: *mut i64, b: int64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67032,7 +67032,7 @@ pub unsafe fn vst1q_s64_x3(a: *mut i64, b: int64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -67051,7 +67051,7 @@ pub unsafe fn vst1_s8_x4(a: *mut i8, b: int8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -67070,7 +67070,7 @@ pub unsafe fn vst1q_s8_x4(a: *mut i8, b: int8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -67089,7 +67089,7 @@ pub unsafe fn vst1_s16_x4(a: *mut i16, b: int16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -67108,7 +67108,7 @@ pub unsafe fn vst1q_s16_x4(a: *mut i16, b: int16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -67127,7 +67127,7 @@ pub unsafe fn vst1_s32_x4(a: *mut i32, b: int32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -67146,7 +67146,7 @@ pub unsafe fn vst1q_s32_x4(a: *mut i32, b: int32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -67165,7 +67165,7 @@ pub unsafe fn vst1_s64_x4(a: *mut i64, b: int64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -67184,7 +67184,7 @@ pub unsafe fn vst1q_s64_x4(a: *mut i64, b: int64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67200,7 +67200,7 @@ pub unsafe fn vst1_s8_x4(a: *mut i8, b: int8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67216,7 +67216,7 @@ pub unsafe fn vst1q_s8_x4(a: *mut i8, b: int8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67232,7 +67232,7 @@ pub unsafe fn vst1_s16_x4(a: *mut i16, b: int16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67248,7 +67248,7 @@ pub unsafe fn vst1q_s16_x4(a: *mut i16, b: int16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67264,7 +67264,7 @@ pub unsafe fn vst1_s32_x4(a: *mut i32, b: int32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67280,7 +67280,7 @@ pub unsafe fn vst1q_s32_x4(a: *mut i32, b: int32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_s64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67296,7 +67296,7 @@ pub unsafe fn vst1_s64_x4(a: *mut i64, b: int64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_s64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -67312,7 +67312,7 @@ pub unsafe fn vst1q_s64_x4(a: *mut i64, b: int64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67335,7 +67335,7 @@ pub unsafe fn vst1_u8_x2(a: *mut u8, b: uint8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67358,7 +67358,7 @@ pub unsafe fn vst1_u8_x3(a: *mut u8, b: uint8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67381,7 +67381,7 @@ pub unsafe fn vst1_u8_x4(a: *mut u8, b: uint8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67404,7 +67404,7 @@ pub unsafe fn vst1q_u8_x2(a: *mut u8, b: uint8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67427,7 +67427,7 @@ pub unsafe fn vst1q_u8_x3(a: *mut u8, b: uint8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67450,7 +67450,7 @@ pub unsafe fn vst1q_u8_x4(a: *mut u8, b: uint8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67473,7 +67473,7 @@ pub unsafe fn vst1_u16_x2(a: *mut u16, b: uint16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67496,7 +67496,7 @@ pub unsafe fn vst1_u16_x3(a: *mut u16, b: uint16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67519,7 +67519,7 @@ pub unsafe fn vst1_u16_x4(a: *mut u16, b: uint16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67542,7 +67542,7 @@ pub unsafe fn vst1q_u16_x2(a: *mut u16, b: uint16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67565,7 +67565,7 @@ pub unsafe fn vst1q_u16_x3(a: *mut u16, b: uint16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67588,7 +67588,7 @@ pub unsafe fn vst1q_u16_x4(a: *mut u16, b: uint16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67611,7 +67611,7 @@ pub unsafe fn vst1_u32_x2(a: *mut u32, b: uint32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67634,7 +67634,7 @@ pub unsafe fn vst1_u32_x3(a: *mut u32, b: uint32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67657,7 +67657,7 @@ pub unsafe fn vst1_u32_x4(a: *mut u32, b: uint32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u32_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67680,7 +67680,7 @@ pub unsafe fn vst1q_u32_x2(a: *mut u32, b: uint32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u32_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67703,7 +67703,7 @@ pub unsafe fn vst1q_u32_x3(a: *mut u32, b: uint32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u32_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67726,7 +67726,7 @@ pub unsafe fn vst1q_u32_x4(a: *mut u32, b: uint32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67749,7 +67749,7 @@ pub unsafe fn vst1_u64_x2(a: *mut u64, b: uint64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67772,7 +67772,7 @@ pub unsafe fn vst1_u64_x3(a: *mut u64, b: uint64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_u64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67795,7 +67795,7 @@ pub unsafe fn vst1_u64_x4(a: *mut u64, b: uint64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u64_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67818,7 +67818,7 @@ pub unsafe fn vst1q_u64_x2(a: *mut u64, b: uint64x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u64_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67841,7 +67841,7 @@ pub unsafe fn vst1q_u64_x3(a: *mut u64, b: uint64x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_u64_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67864,7 +67864,7 @@ pub unsafe fn vst1q_u64_x4(a: *mut u64, b: uint64x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67887,7 +67887,7 @@ pub unsafe fn vst1_p8_x2(a: *mut p8, b: poly8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67910,7 +67910,7 @@ pub unsafe fn vst1_p8_x3(a: *mut p8, b: poly8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67933,7 +67933,7 @@ pub unsafe fn vst1_p8_x4(a: *mut p8, b: poly8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p8_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67956,7 +67956,7 @@ pub unsafe fn vst1q_p8_x2(a: *mut p8, b: poly8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p8_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -67979,7 +67979,7 @@ pub unsafe fn vst1q_p8_x3(a: *mut p8, b: poly8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p8_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -68002,7 +68002,7 @@ pub unsafe fn vst1q_p8_x4(a: *mut p8, b: poly8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -68025,7 +68025,7 @@ pub unsafe fn vst1_p16_x2(a: *mut p16, b: poly16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -68048,7 +68048,7 @@ pub unsafe fn vst1_p16_x3(a: *mut p16, b: poly16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_p16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -68071,7 +68071,7 @@ pub unsafe fn vst1_p16_x4(a: *mut p16, b: poly16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p16_x2)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -68094,7 +68094,7 @@ pub unsafe fn vst1q_p16_x2(a: *mut p16, b: poly16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p16_x3)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -68117,7 +68117,7 @@ pub unsafe fn vst1q_p16_x3(a: *mut p16, b: poly16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_p16_x4)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst1))]
    @@ -68136,7 +68136,7 @@ pub unsafe fn vst1q_p16_x3(a: *mut p16, b: poly16x8x3_t) {
     pub unsafe fn vst1q_p16_x4(a: *mut p16, b: poly16x8x4_t) {
         vst1q_s16_x4(transmute(a), transmute(b))
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68150,7 +68150,7 @@ unsafe fn vst1_v1i64(addr: *const i8, val: int64x1_t) {
         }
         _vst1_v1i64(addr, val, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68164,7 +68164,7 @@ unsafe fn vst1_v2f32(addr: *const i8, val: float32x2_t) {
         }
         _vst1_v2f32(addr, val, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68178,7 +68178,7 @@ unsafe fn vst1_v2i32(addr: *const i8, val: int32x2_t) {
         }
         _vst1_v2i32(addr, val, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68192,7 +68192,7 @@ unsafe fn vst1_v4i16(addr: *const i8, val: int16x4_t) {
         }
         _vst1_v4i16(addr, val, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68206,7 +68206,7 @@ unsafe fn vst1_v8i8(addr: *const i8, val: int8x8_t) {
         }
         _vst1_v8i8(addr, val, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68220,7 +68220,7 @@ unsafe fn vst1q_v16i8(addr: *const i8, val: int8x16_t) {
         }
         _vst1q_v16i8(addr, val, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68234,7 +68234,7 @@ unsafe fn vst1q_v2i64(addr: *const i8, val: int64x2_t) {
         }
         _vst1q_v2i64(addr, val, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68248,7 +68248,7 @@ unsafe fn vst1q_v4f32(addr: *const i8, val: float32x4_t) {
         }
         _vst1q_v4f32(addr, val, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68262,7 +68262,7 @@ unsafe fn vst1q_v4i32(addr: *const i8, val: int32x4_t) {
         }
         _vst1q_v4i32(addr, val, ALIGN)
     }
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68280,7 +68280,7 @@ unsafe fn vst1q_v8i16(addr: *const i8, val: int16x8_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1_v4f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[target_feature(enable = "neon,fp16")]
    @@ -68298,7 +68298,7 @@ unsafe fn vst1_v4f16(addr: *const i8, val: float16x4_t, align: i32) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_v8f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[target_feature(enable = "neon,fp16")]
    @@ -68316,7 +68316,7 @@ unsafe fn vst1q_v8f16(addr: *const i8, val: float16x8_t, align: i32) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst1q_lane_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))]
    @@ -68341,7 +68341,7 @@ pub unsafe fn vst1q_lane_p64(a: *mut p64, b: poly64x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))]
    @@ -68362,7 +68362,7 @@ pub unsafe fn vst2_f16(a: *mut f16, b: float16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))]
    @@ -68383,7 +68383,7 @@ pub unsafe fn vst2q_f16(a: *mut f16, b: float16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68402,7 +68402,7 @@ pub unsafe fn vst2_f16(a: *mut f16, b: float16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68421,7 +68421,7 @@ pub unsafe fn vst2q_f16(a: *mut f16, b: float16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -68440,7 +68440,7 @@ pub unsafe fn vst2_f32(a: *mut f32, b: float32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -68459,7 +68459,7 @@ pub unsafe fn vst2q_f32(a: *mut f32, b: float32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -68478,7 +68478,7 @@ pub unsafe fn vst2_s8(a: *mut i8, b: int8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -68497,7 +68497,7 @@ pub unsafe fn vst2q_s8(a: *mut i8, b: int8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -68516,7 +68516,7 @@ pub unsafe fn vst2_s16(a: *mut i16, b: int16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -68535,7 +68535,7 @@ pub unsafe fn vst2q_s16(a: *mut i16, b: int16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -68554,7 +68554,7 @@ pub unsafe fn vst2_s32(a: *mut i32, b: int32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -68573,7 +68573,7 @@ pub unsafe fn vst2q_s32(a: *mut i32, b: int32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -68589,7 +68589,7 @@ pub unsafe fn vst2_f32(a: *mut f32, b: float32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -68605,7 +68605,7 @@ pub unsafe fn vst2q_f32(a: *mut f32, b: float32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -68621,7 +68621,7 @@ pub unsafe fn vst2_s8(a: *mut i8, b: int8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -68637,7 +68637,7 @@ pub unsafe fn vst2q_s8(a: *mut i8, b: int8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -68653,7 +68653,7 @@ pub unsafe fn vst2_s16(a: *mut i16, b: int16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -68669,7 +68669,7 @@ pub unsafe fn vst2q_s16(a: *mut i16, b: int16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -68685,7 +68685,7 @@ pub unsafe fn vst2_s32(a: *mut i32, b: int32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -68701,7 +68701,7 @@ pub unsafe fn vst2q_s32(a: *mut i32, b: int32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -68724,7 +68724,7 @@ pub unsafe fn vst2_lane_f16(a: *mut f16, b: float16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -68747,7 +68747,7 @@ pub unsafe fn vst2q_lane_f16(a: *mut f16, b: float16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68768,7 +68768,7 @@ pub unsafe fn vst2_lane_f16(a: *mut f16, b: float16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -68789,7 +68789,7 @@ pub unsafe fn vst2q_lane_f16(a: *mut f16, b: float16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -68810,7 +68810,7 @@ pub unsafe fn vst2_lane_f32(a: *mut f32, b: float32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -68831,7 +68831,7 @@ pub unsafe fn vst2q_lane_f32(a: *mut f32, b: float32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -68852,7 +68852,7 @@ pub unsafe fn vst2_lane_s8(a: *mut i8, b: int8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -68873,7 +68873,7 @@ pub unsafe fn vst2_lane_s16(a: *mut i16, b: int16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -68894,7 +68894,7 @@ pub unsafe fn vst2q_lane_s16(a: *mut i16, b: int16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -68915,7 +68915,7 @@ pub unsafe fn vst2_lane_s32(a: *mut i32, b: int32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -68936,7 +68936,7 @@ pub unsafe fn vst2q_lane_s32(a: *mut i32, b: int32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst2, LANE = 0))]
    @@ -68954,7 +68954,7 @@ pub unsafe fn vst2_lane_f32(a: *mut f32, b: float32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst2, LANE = 0))]
    @@ -68972,7 +68972,7 @@ pub unsafe fn vst2q_lane_f32(a: *mut f32, b: float32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst2, LANE = 0))]
    @@ -68990,7 +68990,7 @@ pub unsafe fn vst2_lane_s8(a: *mut i8, b: int8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst2, LANE = 0))]
    @@ -69008,7 +69008,7 @@ pub unsafe fn vst2_lane_s16(a: *mut i16, b: int16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst2, LANE = 0))]
    @@ -69026,7 +69026,7 @@ pub unsafe fn vst2q_lane_s16(a: *mut i16, b: int16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst2, LANE = 0))]
    @@ -69044,7 +69044,7 @@ pub unsafe fn vst2_lane_s32(a: *mut i32, b: int32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst2, LANE = 0))]
    @@ -69062,7 +69062,7 @@ pub unsafe fn vst2q_lane_s32(a: *mut i32, b: int32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2, LANE = 0))]
    @@ -69087,7 +69087,7 @@ pub unsafe fn vst2_lane_u8(a: *mut u8, b: uint8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2, LANE = 0))]
    @@ -69112,7 +69112,7 @@ pub unsafe fn vst2_lane_u16(a: *mut u16, b: uint16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2, LANE = 0))]
    @@ -69137,7 +69137,7 @@ pub unsafe fn vst2q_lane_u16(a: *mut u16, b: uint16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2, LANE = 0))]
    @@ -69162,7 +69162,7 @@ pub unsafe fn vst2_lane_u32(a: *mut u32, b: uint32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2, LANE = 0))]
    @@ -69187,7 +69187,7 @@ pub unsafe fn vst2q_lane_u32(a: *mut u32, b: uint32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2, LANE = 0))]
    @@ -69212,7 +69212,7 @@ pub unsafe fn vst2_lane_p8(a: *mut p8, b: poly8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2, LANE = 0))]
    @@ -69237,7 +69237,7 @@ pub unsafe fn vst2_lane_p16(a: *mut p16, b: poly16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2, LANE = 0))]
    @@ -69262,7 +69262,7 @@ pub unsafe fn vst2q_lane_p16(a: *mut p16, b: poly16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -69285,7 +69285,7 @@ pub unsafe fn vst2_p64(a: *mut p64, b: poly64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -69301,7 +69301,7 @@ pub unsafe fn vst2_s64(a: *mut i64, b: int64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -69320,7 +69320,7 @@ pub unsafe fn vst2_s64(a: *mut i64, b: int64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -69343,7 +69343,7 @@ pub unsafe fn vst2_u64(a: *mut u64, b: uint64x1x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69366,7 +69366,7 @@ pub unsafe fn vst2_u8(a: *mut u8, b: uint8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69389,7 +69389,7 @@ pub unsafe fn vst2q_u8(a: *mut u8, b: uint8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69412,7 +69412,7 @@ pub unsafe fn vst2_u16(a: *mut u16, b: uint16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69435,7 +69435,7 @@ pub unsafe fn vst2q_u16(a: *mut u16, b: uint16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69458,7 +69458,7 @@ pub unsafe fn vst2_u32(a: *mut u32, b: uint32x2x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69481,7 +69481,7 @@ pub unsafe fn vst2q_u32(a: *mut u32, b: uint32x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69504,7 +69504,7 @@ pub unsafe fn vst2_p8(a: *mut p8, b: poly8x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69527,7 +69527,7 @@ pub unsafe fn vst2q_p8(a: *mut p8, b: poly8x16x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69550,7 +69550,7 @@ pub unsafe fn vst2_p16(a: *mut p16, b: poly16x4x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst2))]
    @@ -69573,7 +69573,7 @@ pub unsafe fn vst2q_p16(a: *mut p16, b: poly16x8x2_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -69592,7 +69592,7 @@ pub unsafe fn vst3_f16(a: *mut f16, b: float16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -69611,7 +69611,7 @@ pub unsafe fn vst3q_f16(a: *mut f16, b: float16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))]
    @@ -69632,7 +69632,7 @@ pub unsafe fn vst3_f16(a: *mut f16, b: float16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))]
    @@ -69653,7 +69653,7 @@ pub unsafe fn vst3q_f16(a: *mut f16, b: float16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -69669,7 +69669,7 @@ pub unsafe fn vst3_f32(a: *mut f32, b: float32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -69685,7 +69685,7 @@ pub unsafe fn vst3q_f32(a: *mut f32, b: float32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -69701,7 +69701,7 @@ pub unsafe fn vst3_s8(a: *mut i8, b: int8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -69717,7 +69717,7 @@ pub unsafe fn vst3q_s8(a: *mut i8, b: int8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -69733,7 +69733,7 @@ pub unsafe fn vst3_s16(a: *mut i16, b: int16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -69749,7 +69749,7 @@ pub unsafe fn vst3q_s16(a: *mut i16, b: int16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -69765,7 +69765,7 @@ pub unsafe fn vst3_s32(a: *mut i32, b: int32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -69781,7 +69781,7 @@ pub unsafe fn vst3q_s32(a: *mut i32, b: int32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -69800,7 +69800,7 @@ pub unsafe fn vst3_f32(a: *mut f32, b: float32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -69819,7 +69819,7 @@ pub unsafe fn vst3q_f32(a: *mut f32, b: float32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -69838,7 +69838,7 @@ pub unsafe fn vst3_s8(a: *mut i8, b: int8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -69857,7 +69857,7 @@ pub unsafe fn vst3q_s8(a: *mut i8, b: int8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -69876,7 +69876,7 @@ pub unsafe fn vst3_s16(a: *mut i16, b: int16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -69895,7 +69895,7 @@ pub unsafe fn vst3q_s16(a: *mut i16, b: int16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -69914,7 +69914,7 @@ pub unsafe fn vst3_s32(a: *mut i32, b: int32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -69933,7 +69933,7 @@ pub unsafe fn vst3q_s32(a: *mut i32, b: int32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -69961,7 +69961,7 @@ pub unsafe fn vst3_lane_f16(a: *mut f16, b: float16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -69989,7 +69989,7 @@ pub unsafe fn vst3q_lane_f16(a: *mut f16, b: float16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -70012,7 +70012,7 @@ pub unsafe fn vst3_lane_f16(a: *mut f16, b: float16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -70035,7 +70035,7 @@ pub unsafe fn vst3q_lane_f16(a: *mut f16, b: float16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst3, LANE = 0))]
    @@ -70060,7 +70060,7 @@ pub unsafe fn vst3_lane_f32(a: *mut f32, b: float32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst3, LANE = 0))]
    @@ -70085,7 +70085,7 @@ pub unsafe fn vst3q_lane_f32(a: *mut f32, b: float32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst3, LANE = 0))]
    @@ -70103,7 +70103,7 @@ pub unsafe fn vst3_lane_s8(a: *mut i8, b: int8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst3, LANE = 0))]
    @@ -70128,7 +70128,7 @@ pub unsafe fn vst3_lane_s16(a: *mut i16, b: int16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst3, LANE = 0))]
    @@ -70153,7 +70153,7 @@ pub unsafe fn vst3q_lane_s16(a: *mut i16, b: int16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst3, LANE = 0))]
    @@ -70178,7 +70178,7 @@ pub unsafe fn vst3_lane_s32(a: *mut i32, b: int32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst3, LANE = 0))]
    @@ -70203,7 +70203,7 @@ pub unsafe fn vst3q_lane_s32(a: *mut i32, b: int32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -70224,7 +70224,7 @@ pub unsafe fn vst3_lane_f32(a: *mut f32, b: float32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -70245,7 +70245,7 @@ pub unsafe fn vst3q_lane_f32(a: *mut f32, b: float32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -70266,7 +70266,7 @@ pub unsafe fn vst3_lane_s8(a: *mut i8, b: int8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -70287,7 +70287,7 @@ pub unsafe fn vst3_lane_s16(a: *mut i16, b: int16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -70308,7 +70308,7 @@ pub unsafe fn vst3q_lane_s16(a: *mut i16, b: int16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -70329,7 +70329,7 @@ pub unsafe fn vst3_lane_s32(a: *mut i32, b: int32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -70350,7 +70350,7 @@ pub unsafe fn vst3q_lane_s32(a: *mut i32, b: int32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3, LANE = 0))]
    @@ -70375,7 +70375,7 @@ pub unsafe fn vst3_lane_u8(a: *mut u8, b: uint8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3, LANE = 0))]
    @@ -70400,7 +70400,7 @@ pub unsafe fn vst3_lane_u16(a: *mut u16, b: uint16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3, LANE = 0))]
    @@ -70425,7 +70425,7 @@ pub unsafe fn vst3q_lane_u16(a: *mut u16, b: uint16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3, LANE = 0))]
    @@ -70450,7 +70450,7 @@ pub unsafe fn vst3_lane_u32(a: *mut u32, b: uint32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3, LANE = 0))]
    @@ -70475,7 +70475,7 @@ pub unsafe fn vst3q_lane_u32(a: *mut u32, b: uint32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3, LANE = 0))]
    @@ -70500,7 +70500,7 @@ pub unsafe fn vst3_lane_p8(a: *mut p8, b: poly8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3, LANE = 0))]
    @@ -70525,7 +70525,7 @@ pub unsafe fn vst3_lane_p16(a: *mut p16, b: poly16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3, LANE = 0))]
    @@ -70550,7 +70550,7 @@ pub unsafe fn vst3q_lane_p16(a: *mut p16, b: poly16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -70573,7 +70573,7 @@ pub unsafe fn vst3_p64(a: *mut p64, b: poly64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -70592,7 +70592,7 @@ pub unsafe fn vst3_s64(a: *mut i64, b: int64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -70608,7 +70608,7 @@ pub unsafe fn vst3_s64(a: *mut i64, b: int64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -70631,7 +70631,7 @@ pub unsafe fn vst3_u64(a: *mut u64, b: uint64x1x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70654,7 +70654,7 @@ pub unsafe fn vst3_u8(a: *mut u8, b: uint8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70677,7 +70677,7 @@ pub unsafe fn vst3q_u8(a: *mut u8, b: uint8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70700,7 +70700,7 @@ pub unsafe fn vst3_u16(a: *mut u16, b: uint16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70723,7 +70723,7 @@ pub unsafe fn vst3q_u16(a: *mut u16, b: uint16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70746,7 +70746,7 @@ pub unsafe fn vst3_u32(a: *mut u32, b: uint32x2x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70769,7 +70769,7 @@ pub unsafe fn vst3q_u32(a: *mut u32, b: uint32x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70792,7 +70792,7 @@ pub unsafe fn vst3_p8(a: *mut p8, b: poly8x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70815,7 +70815,7 @@ pub unsafe fn vst3q_p8(a: *mut p8, b: poly8x16x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70838,7 +70838,7 @@ pub unsafe fn vst3_p16(a: *mut p16, b: poly16x4x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst3))]
    @@ -70861,7 +70861,7 @@ pub unsafe fn vst3q_p16(a: *mut p16, b: poly16x8x3_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -70887,7 +70887,7 @@ pub unsafe fn vst4_f16(a: *mut f16, b: float16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -70913,7 +70913,7 @@ pub unsafe fn vst4q_f16(a: *mut f16, b: float16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))]
    @@ -70934,7 +70934,7 @@ pub unsafe fn vst4_f16(a: *mut f16, b: float16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))]
    @@ -70955,7 +70955,7 @@ pub unsafe fn vst4q_f16(a: *mut f16, b: float16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -70978,7 +70978,7 @@ pub unsafe fn vst4_f32(a: *mut f32, b: float32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -71001,7 +71001,7 @@ pub unsafe fn vst4q_f32(a: *mut f32, b: float32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -71017,7 +71017,7 @@ pub unsafe fn vst4_s8(a: *mut i8, b: int8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -71040,7 +71040,7 @@ pub unsafe fn vst4q_s8(a: *mut i8, b: int8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -71063,7 +71063,7 @@ pub unsafe fn vst4_s16(a: *mut i16, b: int16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -71086,7 +71086,7 @@ pub unsafe fn vst4q_s16(a: *mut i16, b: int16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -71109,7 +71109,7 @@ pub unsafe fn vst4_s32(a: *mut i32, b: int32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -71132,7 +71132,7 @@ pub unsafe fn vst4q_s32(a: *mut i32, b: int32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -71151,7 +71151,7 @@ pub unsafe fn vst4_f32(a: *mut f32, b: float32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -71170,7 +71170,7 @@ pub unsafe fn vst4q_f32(a: *mut f32, b: float32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -71189,7 +71189,7 @@ pub unsafe fn vst4_s8(a: *mut i8, b: int8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -71208,7 +71208,7 @@ pub unsafe fn vst4q_s8(a: *mut i8, b: int8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -71227,7 +71227,7 @@ pub unsafe fn vst4_s16(a: *mut i16, b: int16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -71246,7 +71246,7 @@ pub unsafe fn vst4q_s16(a: *mut i16, b: int16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -71265,7 +71265,7 @@ pub unsafe fn vst4_s32(a: *mut i32, b: int32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -71284,7 +71284,7 @@ pub unsafe fn vst4q_s32(a: *mut i32, b: int32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -71313,7 +71313,7 @@ pub unsafe fn vst4_lane_f16(a: *mut f16, b: float16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -71342,7 +71342,7 @@ pub unsafe fn vst4q_lane_f16(a: *mut f16, b: float16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -71372,7 +71372,7 @@ pub unsafe fn vst4_lane_f16(a: *mut f16, b: float16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -71402,7 +71402,7 @@ pub unsafe fn vst4q_lane_f16(a: *mut f16, b: float16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst4, LANE = 0))]
    @@ -71428,7 +71428,7 @@ pub unsafe fn vst4_lane_f32(a: *mut f32, b: float32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst4, LANE = 0))]
    @@ -71454,7 +71454,7 @@ pub unsafe fn vst4q_lane_f32(a: *mut f32, b: float32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst4, LANE = 0))]
    @@ -71480,7 +71480,7 @@ pub unsafe fn vst4_lane_s8(a: *mut i8, b: int8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst4, LANE = 0))]
    @@ -71506,7 +71506,7 @@ pub unsafe fn vst4_lane_s16(a: *mut i16, b: int16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst4, LANE = 0))]
    @@ -71532,7 +71532,7 @@ pub unsafe fn vst4q_lane_s16(a: *mut i16, b: int16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst4, LANE = 0))]
    @@ -71558,7 +71558,7 @@ pub unsafe fn vst4_lane_s32(a: *mut i32, b: int32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[cfg_attr(test, assert_instr(vst4, LANE = 0))]
    @@ -71584,7 +71584,7 @@ pub unsafe fn vst4q_lane_s32(a: *mut i32, b: int32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -71612,7 +71612,7 @@ pub unsafe fn vst4_lane_f32(a: *mut f32, b: float32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -71640,7 +71640,7 @@ pub unsafe fn vst4q_lane_f32(a: *mut f32, b: float32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -71661,7 +71661,7 @@ pub unsafe fn vst4_lane_s8(a: *mut i8, b: int8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -71689,7 +71689,7 @@ pub unsafe fn vst4_lane_s16(a: *mut i16, b: int16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -71717,7 +71717,7 @@ pub unsafe fn vst4q_lane_s16(a: *mut i16, b: int16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -71745,7 +71745,7 @@ pub unsafe fn vst4_lane_s32(a: *mut i32, b: int32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_s32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[rustc_legacy_const_generics(2)]
    @@ -71773,7 +71773,7 @@ pub unsafe fn vst4q_lane_s32(a: *mut i32, b: int32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4, LANE = 0))]
    @@ -71798,7 +71798,7 @@ pub unsafe fn vst4_lane_u8(a: *mut u8, b: uint8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4, LANE = 0))]
    @@ -71823,7 +71823,7 @@ pub unsafe fn vst4_lane_u16(a: *mut u16, b: uint16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4, LANE = 0))]
    @@ -71848,7 +71848,7 @@ pub unsafe fn vst4q_lane_u16(a: *mut u16, b: uint16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4, LANE = 0))]
    @@ -71873,7 +71873,7 @@ pub unsafe fn vst4_lane_u32(a: *mut u32, b: uint32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4, LANE = 0))]
    @@ -71898,7 +71898,7 @@ pub unsafe fn vst4q_lane_u32(a: *mut u32, b: uint32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4, LANE = 0))]
    @@ -71923,7 +71923,7 @@ pub unsafe fn vst4_lane_p8(a: *mut p8, b: poly8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4, LANE = 0))]
    @@ -71948,7 +71948,7 @@ pub unsafe fn vst4_lane_p16(a: *mut p16, b: poly16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4, LANE = 0))]
    @@ -71973,7 +71973,7 @@ pub unsafe fn vst4q_lane_p16(a: *mut p16, b: poly16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_p64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[target_feature(enable = "neon,aes")]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -71996,7 +71996,7 @@ pub unsafe fn vst4_p64(a: *mut p64, b: poly64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_arch = "arm")]
     #[target_feature(enable = "neon,v7")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -72019,7 +72019,7 @@ pub unsafe fn vst4_s64(a: *mut i64, b: int64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(not(target_arch = "arm"))]
     #[stable(feature = "neon_intrinsics", since = "1.59.0")]
    @@ -72038,7 +72038,7 @@ pub unsafe fn vst4_s64(a: *mut i64, b: int64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u64)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -72061,7 +72061,7 @@ pub unsafe fn vst4_u64(a: *mut u64, b: uint64x1x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72084,7 +72084,7 @@ pub unsafe fn vst4_u8(a: *mut u8, b: uint8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_u8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72107,7 +72107,7 @@ pub unsafe fn vst4q_u8(a: *mut u8, b: uint8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72130,7 +72130,7 @@ pub unsafe fn vst4_u16(a: *mut u16, b: uint16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_u16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72153,7 +72153,7 @@ pub unsafe fn vst4q_u16(a: *mut u16, b: uint16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72176,7 +72176,7 @@ pub unsafe fn vst4_u32(a: *mut u32, b: uint32x2x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_u32)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72199,7 +72199,7 @@ pub unsafe fn vst4q_u32(a: *mut u32, b: uint32x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72222,7 +72222,7 @@ pub unsafe fn vst4_p8(a: *mut p8, b: poly8x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_p8)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72245,7 +72245,7 @@ pub unsafe fn vst4q_p8(a: *mut p8, b: poly8x16x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72268,7 +72268,7 @@ pub unsafe fn vst4_p16(a: *mut p16, b: poly16x4x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_p16)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vst4))]
    @@ -72291,7 +72291,7 @@ pub unsafe fn vst4q_p16(a: *mut p16, b: poly16x8x4_t) {
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vstrq_p128)"]
     #[doc = "## Safety"]
     #[doc = "  * Neon instrinsic unsafe"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -72312,7 +72312,7 @@ pub unsafe fn vstrq_p128(a: *mut p128, b: p128) {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.f16"))]
     #[cfg_attr(
    @@ -72334,7 +72334,7 @@ pub fn vsub_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.f16"))]
     #[cfg_attr(
    @@ -72356,7 +72356,7 @@ pub fn vsubq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.f32"))]
    @@ -72377,7 +72377,7 @@ pub fn vsub_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.f32"))]
    @@ -72398,7 +72398,7 @@ pub fn vsubq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i16"))]
    @@ -72419,7 +72419,7 @@ pub fn vsub_s16(a: int16x4_t, b: int16x4_t) -> int16x4_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i16"))]
    @@ -72440,7 +72440,7 @@ pub fn vsubq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i16"))]
    @@ -72461,7 +72461,7 @@ pub fn vsub_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i16"))]
    @@ -72482,7 +72482,7 @@ pub fn vsubq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i32"))]
    @@ -72503,7 +72503,7 @@ pub fn vsub_s32(a: int32x2_t, b: int32x2_t) -> int32x2_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i32"))]
    @@ -72524,7 +72524,7 @@ pub fn vsubq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i32"))]
    @@ -72545,7 +72545,7 @@ pub fn vsub_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i32"))]
    @@ -72566,7 +72566,7 @@ pub fn vsubq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i64"))]
    @@ -72587,7 +72587,7 @@ pub fn vsub_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i64"))]
    @@ -72608,7 +72608,7 @@ pub fn vsubq_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i64"))]
    @@ -72629,7 +72629,7 @@ pub fn vsub_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i64"))]
    @@ -72650,7 +72650,7 @@ pub fn vsubq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i8"))]
    @@ -72671,7 +72671,7 @@ pub fn vsub_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i8"))]
    @@ -72692,7 +72692,7 @@ pub fn vsubq_s8(a: int8x16_t, b: int8x16_t) -> int8x16_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsub_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i8"))]
    @@ -72713,7 +72713,7 @@ pub fn vsub_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Subtract"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vsub.i8"))]
    @@ -72734,7 +72734,7 @@ pub fn vsubq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72756,7 +72756,7 @@ pub fn vsubhn_high_s16(a: int8x8_t, b: int16x8_t, c: int16x8_t) -> int8x16_t {
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72778,7 +72778,7 @@ pub fn vsubhn_high_s32(a: int16x4_t, b: int32x4_t, c: int32x4_t) -> int16x8_t {
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72800,7 +72800,7 @@ pub fn vsubhn_high_s64(a: int32x2_t, b: int64x2_t, c: int64x2_t) -> int32x4_t {
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72822,7 +72822,7 @@ pub fn vsubhn_high_u16(a: uint8x8_t, b: uint16x8_t, c: uint16x8_t) -> uint8x16_t
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72844,7 +72844,7 @@ pub fn vsubhn_high_u32(a: uint16x4_t, b: uint32x4_t, c: uint32x4_t) -> uint16x8_
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_high_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72866,7 +72866,7 @@ pub fn vsubhn_high_u64(a: uint32x2_t, b: uint64x2_t, c: uint64x2_t) -> uint32x4_
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72888,7 +72888,7 @@ pub fn vsubhn_s16(a: int16x8_t, b: int16x8_t) -> int8x8_t {
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72910,7 +72910,7 @@ pub fn vsubhn_s32(a: int32x4_t, b: int32x4_t) -> int16x4_t {
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_s64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72932,7 +72932,7 @@ pub fn vsubhn_s64(a: int64x2_t, b: int64x2_t) -> int32x2_t {
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72954,7 +72954,7 @@ pub fn vsubhn_u16(a: uint16x8_t, b: uint16x8_t) -> uint8x8_t {
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72976,7 +72976,7 @@ pub fn vsubhn_u32(a: uint32x4_t, b: uint32x4_t) -> uint16x4_t {
     }
     #[doc = "Subtract returning high narrow"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubhn_u64)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubhn))]
    @@ -72998,7 +72998,7 @@ pub fn vsubhn_u64(a: uint64x2_t, b: uint64x2_t) -> uint32x2_t {
     }
     #[doc = "Signed Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubl))]
    @@ -73023,7 +73023,7 @@ pub fn vsubl_s8(a: int8x8_t, b: int8x8_t) -> int16x8_t {
     }
     #[doc = "Signed Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubl))]
    @@ -73048,7 +73048,7 @@ pub fn vsubl_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubl))]
    @@ -73073,7 +73073,7 @@ pub fn vsubl_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubl))]
    @@ -73098,7 +73098,7 @@ pub fn vsubl_u8(a: uint8x8_t, b: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubl))]
    @@ -73123,7 +73123,7 @@ pub fn vsubl_u16(a: uint16x4_t, b: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Subtract Long"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubl_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubl))]
    @@ -73148,7 +73148,7 @@ pub fn vsubl_u32(a: uint32x2_t, b: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Signed Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubw))]
    @@ -73169,7 +73169,7 @@ pub fn vsubw_s8(a: int16x8_t, b: int8x8_t) -> int16x8_t {
     }
     #[doc = "Signed Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubw))]
    @@ -73190,7 +73190,7 @@ pub fn vsubw_s16(a: int32x4_t, b: int16x4_t) -> int32x4_t {
     }
     #[doc = "Signed Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubw))]
    @@ -73211,7 +73211,7 @@ pub fn vsubw_s32(a: int64x2_t, b: int32x2_t) -> int64x2_t {
     }
     #[doc = "Unsigned Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubw))]
    @@ -73232,7 +73232,7 @@ pub fn vsubw_u8(a: uint16x8_t, b: uint8x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubw))]
    @@ -73253,7 +73253,7 @@ pub fn vsubw_u16(a: uint32x4_t, b: uint16x4_t) -> uint32x4_t {
     }
     #[doc = "Unsigned Subtract Wide"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsubw_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vsubw))]
    @@ -73274,7 +73274,7 @@ pub fn vsubw_u32(a: uint64x2_t, b: uint32x2_t) -> uint64x2_t {
     }
     #[doc = "Dot product index form with signed and unsigned integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudot_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -73302,7 +73302,7 @@ pub fn vsudot_lane_s32(a: int32x2_t, b: int8x8_t, c: uint8x8_t)
     }
     #[doc = "Dot product index form with signed and unsigned integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudot_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -73334,7 +73334,7 @@ pub fn vsudot_lane_s32(a: int32x2_t, b: int8x8_t, c: uint8x8_t)
     }
     #[doc = "Dot product index form with signed and unsigned integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudotq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -73363,7 +73363,7 @@ pub fn vsudotq_lane_s32(a: int32x4_t, b: int8x16_t, c: uint8x8_
     }
     #[doc = "Dot product index form with signed and unsigned integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsudotq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -73397,7 +73397,7 @@ pub fn vsudotq_lane_s32(a: int32x4_t, b: int8x16_t, c: uint8x8_
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -73412,7 +73412,7 @@ fn vtbl1(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -73423,7 +73423,7 @@ pub fn vtbl1_s8(a: int8x8_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73435,7 +73435,7 @@ pub fn vtbl1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73452,7 +73452,7 @@ pub fn vtbl1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73464,7 +73464,7 @@ pub fn vtbl1_p8(a: poly8x8_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73481,7 +73481,7 @@ pub fn vtbl1_p8(a: poly8x8_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -73496,7 +73496,7 @@ fn vtbl2(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -73507,7 +73507,7 @@ pub fn vtbl2_s8(a: int8x8x2_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73519,7 +73519,7 @@ pub fn vtbl2_u8(a: uint8x8x2_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73538,7 +73538,7 @@ pub fn vtbl2_u8(a: uint8x8x2_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73550,7 +73550,7 @@ pub fn vtbl2_p8(a: poly8x8x2_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73569,7 +73569,7 @@ pub fn vtbl2_p8(a: poly8x8x2_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -73584,7 +73584,7 @@ fn vtbl3(a: int8x8_t, b: int8x8_t, c: int8x8_t, d: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -73595,7 +73595,7 @@ pub fn vtbl3_s8(a: int8x8x3_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73614,7 +73614,7 @@ pub fn vtbl3_u8(a: uint8x8x3_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73639,7 +73639,7 @@ pub fn vtbl3_u8(a: uint8x8x3_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73658,7 +73658,7 @@ pub fn vtbl3_p8(a: poly8x8x3_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73683,7 +73683,7 @@ pub fn vtbl3_p8(a: poly8x8x3_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -73698,7 +73698,7 @@ fn vtbl4(a: int8x8_t, b: int8x8_t, c: int8x8_t, d: int8x8_t, e: int8x8_t) -> int
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
    @@ -73709,7 +73709,7 @@ pub fn vtbl4_s8(a: int8x8x4_t, b: int8x8_t) -> int8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73729,7 +73729,7 @@ pub fn vtbl4_u8(a: uint8x8x4_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73756,7 +73756,7 @@ pub fn vtbl4_u8(a: uint8x8x4_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73776,7 +73776,7 @@ pub fn vtbl4_p8(a: poly8x8x4_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon")]
     #[cfg(target_arch = "arm")]
    @@ -73803,7 +73803,7 @@ pub fn vtbl4_p8(a: poly8x8x4_t, b: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx1)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -73817,7 +73817,7 @@ fn vtbx1(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx1_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -73827,7 +73827,7 @@ pub fn vtbx1_s8(a: int8x8_t, b: int8x8_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -73838,7 +73838,7 @@ pub fn vtbx1_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx1_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -73855,7 +73855,7 @@ pub fn vtbx1_u8(a: uint8x8_t, b: uint8x8_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -73866,7 +73866,7 @@ pub fn vtbx1_p8(a: poly8x8_t, b: poly8x8_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx1_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -73883,7 +73883,7 @@ pub fn vtbx1_p8(a: poly8x8_t, b: poly8x8_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -73897,7 +73897,7 @@ fn vtbx2(a: int8x8_t, b: int8x8_t, c: int8x8_t, d: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -73907,7 +73907,7 @@ pub fn vtbx2_s8(a: int8x8_t, b: int8x8x2_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -73925,7 +73925,7 @@ pub fn vtbx2_u8(a: uint8x8_t, b: uint8x8x2_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -73949,7 +73949,7 @@ pub fn vtbx2_u8(a: uint8x8_t, b: uint8x8x2_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -73967,7 +73967,7 @@ pub fn vtbx2_p8(a: poly8x8_t, b: poly8x8x2_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx2_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -73991,7 +73991,7 @@ pub fn vtbx2_p8(a: poly8x8_t, b: poly8x8x2_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -74005,7 +74005,7 @@ fn vtbx3(a: int8x8_t, b: int8x8_t, c: int8x8_t, d: int8x8_t, e: int8x8_t) -> int
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -74015,7 +74015,7 @@ pub fn vtbx3_s8(a: int8x8_t, b: int8x8x3_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74034,7 +74034,7 @@ pub fn vtbx3_u8(a: uint8x8_t, b: uint8x8x3_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74060,7 +74060,7 @@ pub fn vtbx3_u8(a: uint8x8_t, b: uint8x8x3_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74079,7 +74079,7 @@ pub fn vtbx3_p8(a: poly8x8_t, b: poly8x8x3_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx3_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74105,7 +74105,7 @@ pub fn vtbx3_p8(a: poly8x8_t, b: poly8x8x3_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
     #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
    @@ -74126,7 +74126,7 @@ fn vtbx4(a: int8x8_t, b: int8x8_t, c: int8x8_t, d: int8x8_t, e: int8x8_t, f: int
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74146,7 +74146,7 @@ pub fn vtbx4_s8(a: int8x8_t, b: int8x8x4_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_s8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74174,7 +74174,7 @@ pub fn vtbx4_s8(a: int8x8_t, b: int8x8x4_t, c: int8x8_t) -> int8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74194,7 +74194,7 @@ pub fn vtbx4_u8(a: uint8x8_t, b: uint8x8x4_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_u8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74222,7 +74222,7 @@ pub fn vtbx4_u8(a: uint8x8_t, b: uint8x8x4_t, c: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74242,7 +74242,7 @@ pub fn vtbx4_p8(a: poly8x8_t, b: poly8x8x4_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Extended table look-up"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbx4_p8)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,v7")]
     #[cfg(target_arch = "arm")]
    @@ -74270,7 +74270,7 @@ pub fn vtbx4_p8(a: poly8x8_t, b: poly8x8x4_t, c: uint8x8_t) -> poly8x8_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
     #[cfg_attr(
    @@ -74300,7 +74300,7 @@ pub fn vtrn_f16(a: float16x4_t, b: float16x4_t) -> float16x4x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
     #[cfg_attr(
    @@ -74330,7 +74330,7 @@ pub fn vtrnq_f16(a: float16x8_t, b: float16x8_t) -> float16x8x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74359,7 +74359,7 @@ pub fn vtrn_f32(a: float32x2_t, b: float32x2_t) -> float32x2x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74388,7 +74388,7 @@ pub fn vtrn_s32(a: int32x2_t, b: int32x2_t) -> int32x2x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74417,7 +74417,7 @@ pub fn vtrn_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74446,7 +74446,7 @@ pub fn vtrnq_f32(a: float32x4_t, b: float32x4_t) -> float32x4x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74475,7 +74475,7 @@ pub fn vtrn_s8(a: int8x8_t, b: int8x8_t) -> int8x8x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74512,7 +74512,7 @@ pub fn vtrnq_s8(a: int8x16_t, b: int8x16_t) -> int8x16x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74541,7 +74541,7 @@ pub fn vtrn_s16(a: int16x4_t, b: int16x4_t) -> int16x4x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74570,7 +74570,7 @@ pub fn vtrnq_s16(a: int16x8_t, b: int16x8_t) -> int16x8x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74599,7 +74599,7 @@ pub fn vtrnq_s32(a: int32x4_t, b: int32x4_t) -> int32x4x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74628,7 +74628,7 @@ pub fn vtrn_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74665,7 +74665,7 @@ pub fn vtrnq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74694,7 +74694,7 @@ pub fn vtrn_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74723,7 +74723,7 @@ pub fn vtrnq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74752,7 +74752,7 @@ pub fn vtrnq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74781,7 +74781,7 @@ pub fn vtrn_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74818,7 +74818,7 @@ pub fn vtrnq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74847,7 +74847,7 @@ pub fn vtrn_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4x2_t {
     }
     #[doc = "Transpose elements"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -74876,7 +74876,7 @@ pub fn vtrnq_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8x2_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -74901,7 +74901,7 @@ pub fn vtst_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -74926,7 +74926,7 @@ pub fn vtstq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -74951,7 +74951,7 @@ pub fn vtst_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -74976,7 +74976,7 @@ pub fn vtstq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75001,7 +75001,7 @@ pub fn vtst_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75026,7 +75026,7 @@ pub fn vtstq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75051,7 +75051,7 @@ pub fn vtst_p8(a: poly8x8_t, b: poly8x8_t) -> uint8x8_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75076,7 +75076,7 @@ pub fn vtstq_p8(a: poly8x16_t, b: poly8x16_t) -> uint8x16_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75101,7 +75101,7 @@ pub fn vtst_p16(a: poly16x4_t, b: poly16x4_t) -> uint16x4_t {
     }
     #[doc = "Signed compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75126,7 +75126,7 @@ pub fn vtstq_p16(a: poly16x8_t, b: poly16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75151,7 +75151,7 @@ pub fn vtst_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
     }
     #[doc = "Unsigned compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75176,7 +75176,7 @@ pub fn vtstq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
     }
     #[doc = "Unsigned compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75201,7 +75201,7 @@ pub fn vtst_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
     }
     #[doc = "Unsigned compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75226,7 +75226,7 @@ pub fn vtstq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
     }
     #[doc = "Unsigned compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtst_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75251,7 +75251,7 @@ pub fn vtst_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
     }
     #[doc = "Unsigned compare bitwise Test bits nonzero"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtstq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
    @@ -75276,7 +75276,7 @@ pub fn vtstq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
     }
     #[doc = "Dot product index form with unsigned and signed integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdot_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -75304,7 +75304,7 @@ pub fn vusdot_lane_s32(a: int32x2_t, b: uint8x8_t, c: int8x8_t)
     }
     #[doc = "Dot product index form with unsigned and signed integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdot_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -75336,7 +75336,7 @@ pub fn vusdot_lane_s32(a: int32x2_t, b: uint8x8_t, c: int8x8_t)
     }
     #[doc = "Dot product index form with unsigned and signed integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdotq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "little")]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -75365,7 +75365,7 @@ pub fn vusdotq_lane_s32(a: int32x4_t, b: uint8x16_t, c: int8x8_
     }
     #[doc = "Dot product index form with unsigned and signed integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdotq_lane_s32)"]
    -#[inline]
    +#[inline(always)]
     #[cfg(target_endian = "big")]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
    @@ -75399,7 +75399,7 @@ pub fn vusdotq_lane_s32(a: int32x4_t, b: uint8x16_t, c: int8x8_
     }
     #[doc = "Dot product vector form with unsigned and signed integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdot_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vusdot))]
    @@ -75428,7 +75428,7 @@ pub fn vusdot_s32(a: int32x2_t, b: uint8x8_t, c: int8x8_t) -> int32x2_t {
     }
     #[doc = "Dot product vector form with unsigned and signed integers"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusdotq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vusdot))]
    @@ -75457,7 +75457,7 @@ pub fn vusdotq_s32(a: int32x4_t, b: uint8x16_t, c: int8x16_t) -> int32x4_t {
     }
     #[doc = "Unsigned and signed 8-bit integer matrix multiply-accumulate"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vusmmlaq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon,i8mm")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
    @@ -75486,7 +75486,7 @@ pub fn vusmmlaq_s32(a: int32x4_t, b: uint8x16_t, c: int8x16_t) -> int32x4_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
     #[cfg_attr(
    @@ -75516,7 +75516,7 @@ pub fn vuzp_f16(a: float16x4_t, b: float16x4_t) -> float16x4x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
     #[cfg_attr(
    @@ -75546,7 +75546,7 @@ pub fn vuzpq_f16(a: float16x8_t, b: float16x8_t) -> float16x8x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -75575,7 +75575,7 @@ pub fn vuzp_f32(a: float32x2_t, b: float32x2_t) -> float32x2x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -75604,7 +75604,7 @@ pub fn vuzp_s32(a: int32x2_t, b: int32x2_t) -> int32x2x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -75633,7 +75633,7 @@ pub fn vuzp_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75662,7 +75662,7 @@ pub fn vuzpq_f32(a: float32x4_t, b: float32x4_t) -> float32x4x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75691,7 +75691,7 @@ pub fn vuzp_s8(a: int8x8_t, b: int8x8_t) -> int8x8x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75728,7 +75728,7 @@ pub fn vuzpq_s8(a: int8x16_t, b: int8x16_t) -> int8x16x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75757,7 +75757,7 @@ pub fn vuzp_s16(a: int16x4_t, b: int16x4_t) -> int16x4x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75786,7 +75786,7 @@ pub fn vuzpq_s16(a: int16x8_t, b: int16x8_t) -> int16x8x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75815,7 +75815,7 @@ pub fn vuzpq_s32(a: int32x4_t, b: int32x4_t) -> int32x4x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75844,7 +75844,7 @@ pub fn vuzp_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75881,7 +75881,7 @@ pub fn vuzpq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75910,7 +75910,7 @@ pub fn vuzp_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75939,7 +75939,7 @@ pub fn vuzpq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75968,7 +75968,7 @@ pub fn vuzpq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -75997,7 +75997,7 @@ pub fn vuzp_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -76034,7 +76034,7 @@ pub fn vuzpq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzp_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -76063,7 +76063,7 @@ pub fn vuzp_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4x2_t {
     }
     #[doc = "Unzip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vuzpq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vuzp))]
    @@ -76092,7 +76092,7 @@ pub fn vuzpq_p16(a: poly16x8_t, b: poly16x8_t) -> poly16x8x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vzip.16"))]
     #[cfg_attr(
    @@ -76122,7 +76122,7 @@ pub fn vzip_f16(a: float16x4_t, b: float16x4_t) -> float16x4x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_f16)"]
    -#[inline]
    +#[inline(always)]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vzip.16"))]
     #[cfg_attr(
    @@ -76152,7 +76152,7 @@ pub fn vzipq_f16(a: float16x8_t, b: float16x8_t) -> float16x8x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -76181,7 +76181,7 @@ pub fn vzip_f32(a: float32x2_t, b: float32x2_t) -> float32x2x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -76210,7 +76210,7 @@ pub fn vzip_s32(a: int32x2_t, b: int32x2_t) -> int32x2x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtrn))]
    @@ -76239,7 +76239,7 @@ pub fn vzip_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vzip))]
    @@ -76268,7 +76268,7 @@ pub fn vzip_s8(a: int8x8_t, b: int8x8_t) -> int8x8x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vzip))]
    @@ -76297,7 +76297,7 @@ pub fn vzip_s16(a: int16x4_t, b: int16x4_t) -> int16x4x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vzip))]
    @@ -76326,7 +76326,7 @@ pub fn vzip_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vzip))]
    @@ -76355,7 +76355,7 @@ pub fn vzip_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vzip))]
    @@ -76384,7 +76384,7 @@ pub fn vzip_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzip_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vzip))]
    @@ -76413,7 +76413,7 @@ pub fn vzip_p16(a: poly16x4_t, b: poly16x4_t) -> poly16x4x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_f32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -76442,7 +76442,7 @@ pub fn vzipq_f32(a: float32x4_t, b: float32x4_t) -> float32x4x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_s8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -76479,7 +76479,7 @@ pub fn vzipq_s8(a: int8x16_t, b: int8x16_t) -> int8x16x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_s16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -76508,7 +76508,7 @@ pub fn vzipq_s16(a: int16x8_t, b: int16x8_t) -> int16x8x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_s32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -76537,7 +76537,7 @@ pub fn vzipq_s32(a: int32x4_t, b: int32x4_t) -> int32x4x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_u8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -76574,7 +76574,7 @@ pub fn vzipq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_u16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -76603,7 +76603,7 @@ pub fn vzipq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_u32)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -76632,7 +76632,7 @@ pub fn vzipq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_p8)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    @@ -76669,7 +76669,7 @@ pub fn vzipq_p8(a: poly8x16_t, b: poly8x16_t) -> poly8x16x2_t {
     }
     #[doc = "Zip vectors"]
     #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vzipq_p16)"]
    -#[inline]
    +#[inline(always)]
     #[target_feature(enable = "neon")]
     #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
     #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vorr))]
    diff --git a/library/stdarch/crates/core_arch/src/lib.rs b/library/stdarch/crates/core_arch/src/lib.rs
    index d69089b95b0c..3992eaee30fd 100644
    --- a/library/stdarch/crates/core_arch/src/lib.rs
    +++ b/library/stdarch/crates/core_arch/src/lib.rs
    @@ -32,6 +32,7 @@
         x86_amx_intrinsics,
         f16,
         aarch64_unstable_target_feature,
    +    target_feature_inline_always,
         bigint_helper_methods,
         funnel_shifts,
         avx10_target_feature,
    diff --git a/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs b/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs
    index 0cdff6ff6c39..71301c5ba6ce 100644
    --- a/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs
    +++ b/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs
    @@ -1736,7 +1736,7 @@ fn create_tokens(intrinsic: &Intrinsic, endianness: Endianness, tokens: &mut Tok
             );
         }
     
    -    tokens.append_all(quote! { #[inline] });
    +    tokens.append_all(quote! { #[inline(always)] });
     
         match endianness {
             Endianness::Little => tokens.append_all(quote! { #[cfg(target_endian = "little")] }),
    
    From 9a5aa90516602b288de34dd65161d90f2db202a6 Mon Sep 17 00:00:00 2001
    From: Eric Huss 
    Date: Mon, 12 Jan 2026 09:34:11 -0800
    Subject: [PATCH 2013/3801] Add some clarifications and fixes for fmt syntax
    
    This tries to clarify a few things regarding fmt syntax:
    
    - The comment on `Parser::word` seems to be wrong, as that
      underscore-prefixed words are just fine. This was changed in
      https://github.com/rust-lang/rust/pull/66847.
    - I struggled to follow the description of the width argument. It
      referred to a "second argument", but I don't know what second argument
      it is referring to (which is the first?). Either way, I rewrote the
      paragraph to try to be a little more explicit, and to use shorter
      sentences.
    - The description of the precision argument wasn't really clear about
      the distinction of an Nth argument and a named argument. I added
      a sentence to try to emphasize the difference.
    - `IDENTIFIER_OR_KEYWORD` was changed recently in
      https://github.com/rust-lang/reference/pull/2049 to include bare `_`.
      But fmt named arguments are not allowed to be a bare `_`.
    ---
     compiler/rustc_parse_format/src/lib.rs |  2 +-
     library/alloc/src/fmt.rs               | 15 ++++++++++-----
     2 files changed, 11 insertions(+), 6 deletions(-)
    
    diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
    index 86326fc6536c..a687a45480dc 100644
    --- a/compiler/rustc_parse_format/src/lib.rs
    +++ b/compiler/rustc_parse_format/src/lib.rs
    @@ -753,7 +753,7 @@ impl<'input> Parser<'input> {
         }
     
         /// Parses a word starting at the current position. A word is the same as a
    -    /// Rust identifier, except that it can't start with `_` character.
    +    /// Rust identifier or keyword, except that it can't be a bare `_` character.
         fn word(&mut self) -> &'input str {
             let index = self.input_vec_index;
             match self.peek() {
    diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs
    index 3d7c580be8c9..e3ff2ba51aba 100644
    --- a/library/alloc/src/fmt.rs
    +++ b/library/alloc/src/fmt.rs
    @@ -136,9 +136,10 @@
     //! padding specified by fill/alignment will be used to take up the required
     //! space (see below).
     //!
    -//! The value for the width can also be provided as a [`usize`] in the list of
    -//! parameters by adding a postfix `$`, indicating that the second argument is
    -//! a [`usize`] specifying the width.
    +//! The width can also be provided dynamically by referencing another argument
    +//! with a `$` suffix. Use `{:N$}` to reference the Nth positional argument
    +//! (where N is an integer), or `{:name$}` to reference a named argument. The
    +//! referenced argument must be of type [`usize`].
     //!
     //! Referring to an argument with the dollar syntax does not affect the "next
     //! argument" counter, so it's usually a good idea to refer to arguments by
    @@ -236,7 +237,8 @@
     //!
     //! 2. An integer or name followed by dollar sign `.N$`:
     //!
    -//!    use format *argument* `N` (which must be a `usize`) as the precision.
    +//!    use the value of format *argument* `N` (which must be a `usize`) as the precision.
    +//!    An integer refers to a positional argument, and a name refers to a named argument.
     //!
     //! 3. An asterisk `.*`:
     //!
    @@ -363,7 +365,10 @@
     //! - `ws` is any character for which [`char::is_whitespace`] returns `true`, has no semantic
     //!   meaning and is completely optional,
     //! - `integer` is a decimal integer that may contain leading zeroes and must fit into an `usize` and
    -//! - `identifier` is an `IDENTIFIER_OR_KEYWORD` (not an `IDENTIFIER`) as defined by the [Rust language reference](https://doc.rust-lang.org/reference/identifiers.html).
    +//! - `identifier` is an `IDENTIFIER_OR_KEYWORD` (not an `IDENTIFIER`) as
    +//!   defined by the [Rust language
    +//!   reference](https://doc.rust-lang.org/reference/identifiers.html), except
    +//!   for a bare `_`.
     //!
     //! # Formatting traits
     //!
    
    From 573c3097a335148ba58bc9e350a9b2a1f0fd663e Mon Sep 17 00:00:00 2001
    From: Jonathan Brouwer 
    Date: Mon, 12 Jan 2026 18:42:17 +0100
    Subject: [PATCH 2014/3801] Fix perf of `check_crate_level` refactor
    
    ---
     compiler/rustc_attr_parsing/src/target_checking.rs | 7 ++++---
     1 file changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs
    index 52c2d10f4797..79aa06e9475c 100644
    --- a/compiler/rustc_attr_parsing/src/target_checking.rs
    +++ b/compiler/rustc_attr_parsing/src/target_checking.rs
    @@ -10,6 +10,7 @@ use rustc_span::sym;
     use crate::AttributeParser;
     use crate::context::{AcceptContext, Stage};
     use crate::session_diagnostics::InvalidTarget;
    +use crate::target_checking::Policy::Allow;
     
     #[derive(Debug)]
     pub(crate) enum AllowedTargets {
    @@ -88,7 +89,9 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
             target: Target,
             cx: &mut AcceptContext<'_, 'sess, S>,
         ) {
    -        if allowed_targets.allowed_targets() == &[Target::Crate] {
    +        // For crate-level attributes we emit a specific set of lints to warn
    +        // people about accidentally not using them on the crate.
    +        if let &AllowedTargets::AllowList(&[Allow(Target::Crate)]) = allowed_targets {
                 Self::check_crate_level(target, cx);
                 return;
             }
    @@ -146,8 +149,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
         }
     
         pub(crate) fn check_crate_level(target: Target, cx: &mut AcceptContext<'_, 'sess, S>) {
    -        // For crate-level attributes we emit a specific set of lints to warn
    -        // people about accidentally not using them on the crate.
             if target == Target::Crate {
                 return;
             }
    
    From ffe359fe2b61a48b7b0e13dfbdbdbbc1abeab654 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 20:07:26 +0200
    Subject: [PATCH 2015/3801] another corner case
    
    ---
     src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs
    index d41a57d6f747..ebcd472d7012 100644
    --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs
    +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs
    @@ -80,6 +80,7 @@ fn ignore(line: &str, in_code_block: bool) -> bool {
         in_code_block
             || line.to_lowercase().contains("e.g.")
             || line.to_lowercase().contains("n.b.")
    +        || line.contains(" etc.")
             || line.contains("i.e.")
             || line.contains("et. al")
             || line.contains('|')
    @@ -189,6 +190,7 @@ must! be. split?
     ignore | tables
     ignore e.g. and
     ignore i.e. and
    +ignore etc. and
     ignore E.g. too
     - list. entry
      * list. entry
    @@ -212,6 +214,7 @@ split?
     ignore | tables
     ignore e.g. and
     ignore i.e. and
    +ignore etc. and
     ignore E.g. too
     - list.
       entry
    
    From 52a5023e762475c7384c8711489dba916dd7fd3d Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 20:08:03 +0200
    Subject: [PATCH 2016/3801] sembr src/external-repos.md
    
    ---
     src/doc/rustc-dev-guide/src/external-repos.md | 48 +++++++++++--------
     1 file changed, 27 insertions(+), 21 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md
    index c43c1f680acf..3d5a0075389e 100644
    --- a/src/doc/rustc-dev-guide/src/external-repos.md
    +++ b/src/doc/rustc-dev-guide/src/external-repos.md
    @@ -30,8 +30,8 @@ The following external projects are managed using some form of a `subtree`:
     In contrast to `submodule` dependencies
     (see below for those), the `subtree` dependencies are just regular files and directories which can
     be updated in tree. However, if possible, enhancements, bug fixes, etc. specific
    -to these tools should be filed against the tools directly in their respective
    -upstream repositories. The exception is that when rustc changes are required to
    +to these tools should be filed against the tools directly in their respective upstream repositories.
    +The exception is that when rustc changes are required to
     implement a new tool feature or test, that should happen in one collective rustc PR.
     
     `subtree` dependencies are currently managed by two distinct approaches:
    @@ -51,7 +51,9 @@ implement a new tool feature or test, that should happen in one collective rustc
     
     ### Josh subtrees
     
    -The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories. Specific tooling is required to work with josh. We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, described [below](#synchronizing-a-josh-subtree).
    +The [josh] tool is an alternative to git subtrees, which manages git history in a different way and scales better to larger repositories.
    +Specific tooling is required to work with josh.
    +We provide a helper [`rustc-josh-sync`][josh-sync] tool to help with the synchronization, described [below](#synchronizing-a-josh-subtree).
     
     ### Synchronizing a Josh subtree
     
    @@ -69,8 +71,7 @@ changes from the subtree to rust-lang/rust) are performed from the subtree repos
     switch to its repository checkout directory in your terminal).
     
     #### Performing pull
    -1) Checkout a new branch that will be used to create a PR into the subtree
    -2) Run the pull command
    +1) Checkout a new branch that will be used to create a PR into the subtree 2) Run the pull command
         ```
         rustc-josh-sync pull
         ```
    @@ -97,7 +98,8 @@ If you want to migrate a repository dependency from `git subtree` or `git submod
     Periodically the changes made to subtree based dependencies need to be synchronized between this
     repository and the upstream tool repositories.
     
    -Subtree synchronizations are typically handled by the respective tool maintainers. Other users
    +Subtree synchronizations are typically handled by the respective tool maintainers.
    +Other users
     are welcome to submit synchronization PRs, however, in order to do so you will need to modify
     your local git installation and follow a very precise set of instructions.
     These instructions are documented, along with several useful tips and tricks, in the
    @@ -108,8 +110,8 @@ use the correct corresponding subtree directory and remote repository.
     The synchronization process goes in two directions: `subtree push` and `subtree pull`.
     
     A `subtree push` takes all the changes that happened to the copy in this repo and creates commits
    -on the remote repo that match the local changes. Every local
    -commit that touched the subtree causes a commit on the remote repo, but
    +on the remote repo that match the local changes.
    +Every local commit that touched the subtree causes a commit on the remote repo, but
     is modified to move the files from the specified directory to the tool repo root.
     
     A `subtree pull` takes all changes since the last `subtree pull`
    @@ -119,14 +121,17 @@ the tool changes into the specified directory in the Rust repository.
     It is recommended that you always do a push first and get that merged to the default branch of the tool.
     Then, when you do a pull, the merge works without conflicts.
     While it's definitely possible to resolve conflicts during a pull, you may have to redo the conflict
    -resolution if your PR doesn't get merged fast enough and there are new conflicts. Do not try to
    +resolution if your PR doesn't get merged fast enough and there are new conflicts.
    +Do not try to
     rebase the result of a `git subtree pull`, rebasing merge commits is a bad idea in general.
     
     You always need to specify the `-P` prefix to the subtree directory and the corresponding remote
    -repository. If you specify the wrong directory or repository
    +repository.
    +If you specify the wrong directory or repository
     you'll get very fun merges that try to push the wrong directory to the wrong remote repository.
     Luckily you can just abort this without any consequences by throwing away either the pulled commits
    -in rustc or the pushed branch on the remote and try again. It is usually fairly obvious
    +in rustc or the pushed branch on the remote and try again.
    +It is usually fairly obvious
     that this is happening because you suddenly get thousands of commits that want to be synchronized.
     
     [clippy-sync-docs]: https://doc.rust-lang.org/nightly/clippy/development/infrastructure/sync.html
    @@ -140,8 +145,8 @@ repository's root directory!)
     git subtree add -P src/tools/clippy https://github.com/rust-lang/rust-clippy.git master
     ```
     
    -This will create a new commit, which you may not rebase under any circumstances! Delete the commit
    -and redo the operation if you need to rebase.
    +This will create a new commit, which you may not rebase under any circumstances!
    +Delete the commit and redo the operation if you need to rebase.
     
     Now you're done, the `src/tools/clippy` directory behaves as if Clippy were
     part of the rustc monorepo, so no one but you (or others that synchronize
    @@ -149,24 +154,25 @@ subtrees) actually needs to use `git subtree`.
     
     ## External Dependencies (submodules)
     
    -Building Rust will also use external git repositories tracked using [git
    -submodules]. The complete list may be found in the [`.gitmodules`] file. Some
    -of these projects are required (like `stdarch` for the standard library) and
    +Building Rust will also use external git repositories tracked using [git submodules].
    +The complete list may be found in the [`.gitmodules`] file.
    +Some of these projects are required (like `stdarch` for the standard library) and
     some of them are optional (like `src/doc/book`).
     
     Usage of submodules is discussed more in the [Using Git chapter](git.md#git-submodules).
     
     Some of the submodules are allowed to be in a "broken" state where they
     either don't build or their tests don't pass, e.g. the documentation books
    -like [The Rust Reference]. Maintainers of these projects will be notified
    -when the project is in a broken state, and they should fix them as soon
    -as possible. The current status is tracked on the [toolstate website].
    +like [The Rust Reference].
    +Maintainers of these projects will be notified
    +when the project is in a broken state, and they should fix them as soon as possible.
    +The current status is tracked on the [toolstate website].
     More information may be found on the Forge [Toolstate chapter].
     In practice, it is very rare for documentation to have broken toolstate.
     
     Breakage is not allowed in the beta and stable channels, and must be addressed
    -before the PR is merged. They are also not allowed to be broken on `main` in
    -the week leading up to the beta cut.
    +before the PR is merged.
    +They are also not allowed to be broken on `main` in the week leading up to the beta cut.
     
     [git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
     [`.gitmodules`]: https://github.com/rust-lang/rust/blob/HEAD/.gitmodules
    
    From 2204cbd9871e6052d4f7ffcddf0de0bbdeb879ad Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 20:14:36 +0200
    Subject: [PATCH 2017/3801] "in tree" should be "in-tree"
    
    ---
     src/doc/rustc-dev-guide/src/external-repos.md   |  2 +-
     src/doc/rustc-dev-guide/src/tests/directives.md | 10 +++++-----
     2 files changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md
    index 3d5a0075389e..c5e5b40e5a25 100644
    --- a/src/doc/rustc-dev-guide/src/external-repos.md
    +++ b/src/doc/rustc-dev-guide/src/external-repos.md
    @@ -29,7 +29,7 @@ The following external projects are managed using some form of a `subtree`:
     
     In contrast to `submodule` dependencies
     (see below for those), the `subtree` dependencies are just regular files and directories which can
    -be updated in tree. However, if possible, enhancements, bug fixes, etc. specific
    +be updated in-tree. However, if possible, enhancements, bug fixes, etc. specific
     to these tools should be filed against the tools directly in their respective upstream repositories.
     The exception is that when rustc changes are required to
     implement a new tool feature or test, that should happen in one collective rustc PR.
    diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
    index 52e1f09dca0f..83272a769a54 100644
    --- a/src/doc/rustc-dev-guide/src/tests/directives.md
    +++ b/src/doc/rustc-dev-guide/src/tests/directives.md
    @@ -130,7 +130,7 @@ means the test won't be compiled or run.
       main test files but that `compiletest` should not try to build the file itself.
       Please backlink to which main test is actually using the auxiliary file.
     * `ignore-test` always ignores the test. This can be used to temporarily disable
    -  a test if it is currently not working, but you want to keep it in tree to
    +  a test if it is currently not working, but you want to keep it in-tree to
       re-enable it later.
     
     Some examples of `X` in `ignore-X` or `only-X`:
    @@ -211,7 +211,7 @@ settings:
     - `needs-target-std` — ignores if target platform does not have std support.
     - `ignore-backends` — ignores the listed backends, separated by whitespace characters. Please note
       that this directive can be overriden with the `--bypass-ignore-backends=[BACKEND]` command line
    -  flag. 
    +  flag.
     - `needs-backends` — only runs the test if current codegen backend is listed.
     - `needs-offload` — ignores if our LLVM backend was not built with offload support.
     - `needs-enzyme` — ignores if our Enzyme submodule was not built.
    @@ -290,9 +290,9 @@ You can also force `./x test` to use a specific edition by passing the `-- --edi
     However, tests with the `//@ edition` directive will clamp the value passed to the argument.
     For example, if we run `./x test -- --edition=2015`:
     
    -- A test with the `//@ edition: 2018` will run with the 2018 edition. 
    -- A test with the `//@ edition: 2015..2021` will be run with the 2015 edition. 
    -- A test with the `//@ edition: 2018..` will run with the 2018 edition. 
    +- A test with the `//@ edition: 2018` will run with the 2018 edition.
    +- A test with the `//@ edition: 2015..2021` will be run with the 2015 edition.
    +- A test with the `//@ edition: 2018..` will run with the 2018 edition.
     
     ### Rustdoc
     
    
    From c4b05c3883e00eaa7eeec854ded90a9f9576c4fd Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 20:24:28 +0200
    Subject: [PATCH 2018/3801] fix sembr tool limitation
    
    ---
     src/doc/rustc-dev-guide/src/external-repos.md | 9 +++++----
     1 file changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md
    index c5e5b40e5a25..7c8cc3b5d62c 100644
    --- a/src/doc/rustc-dev-guide/src/external-repos.md
    +++ b/src/doc/rustc-dev-guide/src/external-repos.md
    @@ -71,11 +71,12 @@ changes from the subtree to rust-lang/rust) are performed from the subtree repos
     switch to its repository checkout directory in your terminal).
     
     #### Performing pull
    -1) Checkout a new branch that will be used to create a PR into the subtree 2) Run the pull command
    +1. Checkout a new branch that will be used to create a PR into the subtree
    +2. Run the pull command
         ```
         rustc-josh-sync pull
         ```
    -3) Push the branch to your fork and create a PR into the subtree repository
    +3. Push the branch to your fork and create a PR into the subtree repository
         - If you have `gh` CLI installed, `rustc-josh-sync` can create the PR for you.
     
     #### Performing push
    @@ -83,11 +84,11 @@ switch to its repository checkout directory in your terminal).
     > NOTE:
     > Before you proceed, look at some guidance related to Git [on josh-sync README].
     
    -1) Run the push command to create a branch named `` in a `rustc` fork under the `` account
    +1. Run the push command to create a branch named `` in a `rustc` fork under the `` account
         ```
         rustc-josh-sync push  
         ```
    -2) Create a PR from `` into `rust-lang/rust`
    +2. Create a PR from `` into `rust-lang/rust`
     
     ### Creating a new Josh subtree dependency
     
    
    From 9a81699f061c0ec39efda7cb5c959a309ad7f71f Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 20:24:52 +0200
    Subject: [PATCH 2019/3801] use a stronger pause
    
    ---
     src/doc/rustc-dev-guide/src/external-repos.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md
    index 7c8cc3b5d62c..2e32fcfe78c1 100644
    --- a/src/doc/rustc-dev-guide/src/external-repos.md
    +++ b/src/doc/rustc-dev-guide/src/external-repos.md
    @@ -124,7 +124,7 @@ Then, when you do a pull, the merge works without conflicts.
     While it's definitely possible to resolve conflicts during a pull, you may have to redo the conflict
     resolution if your PR doesn't get merged fast enough and there are new conflicts.
     Do not try to
    -rebase the result of a `git subtree pull`, rebasing merge commits is a bad idea in general.
    +rebase the result of a `git subtree pull`; rebasing merge commits is a bad idea in general.
     
     You always need to specify the `-P` prefix to the subtree directory and the corresponding remote
     repository.
    
    From 98e65aa454b6bfc157ca719551e387c20e0367c6 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 20:42:16 +0200
    Subject: [PATCH 2020/3801] handle another numbered list notation
    
    ---
     src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs
    index ebcd472d7012..6f4ce4415f04 100644
    --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs
    +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs
    @@ -27,7 +27,7 @@ static REGEX_SPLIT: LazyLock =
         LazyLock::new(|| Regex::new(r"([^\.\d\-\*]\.|[^r]\?|!)\s").unwrap());
     // list elements, numbered (1.) or not  (- and *)
     static REGEX_LIST_ENTRY: LazyLock =
    -    LazyLock::new(|| Regex::new(r"^\s*(\d\.|\-|\*)\s+").unwrap());
    +    LazyLock::new(|| Regex::new(r"^\s*(\d\.|\-|\*|\d\))\s+").unwrap());
     
     fn main() -> Result<()> {
         let cli = Cli::parse();
    @@ -194,6 +194,7 @@ ignore etc. and
     ignore E.g. too
     - list. entry
      * list. entry
    +  1) list. entry
     ```
     some code. block
     ```
    @@ -220,6 +221,8 @@ ignore E.g. too
       entry
      * list.
        entry
    +  1) list.
    +     entry
     ```
     some code. block
     ```
    
    From 419655be815b3e46b38c2b76dc0818a77f9581f6 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 20:52:54 +0200
    Subject: [PATCH 2021/3801] sembr src/tests/directives.md
    
    ---
     .../rustc-dev-guide/src/tests/directives.md   | 167 ++++++++----------
     1 file changed, 77 insertions(+), 90 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
    index 83272a769a54..0852f300b9be 100644
    --- a/src/doc/rustc-dev-guide/src/tests/directives.md
    +++ b/src/doc/rustc-dev-guide/src/tests/directives.md
    @@ -7,8 +7,8 @@ FIXME(jieyouxu) completely revise this chapter.
     Directives are special comments that tell compiletest how to build and interpret a test.
     They may also appear in `rmake.rs` [run-make tests](compiletest.md#run-make-tests).
     
    -They are normally put after the short comment that explains the point of this
    -test. Compiletest test suites use `//@` to signal that a comment is a directive.
    +They are normally put after the short comment that explains the point of this test.
    +Compiletest test suites use `//@` to signal that a comment is a directive.
     For example, this test uses the `//@ compile-flags` command to specify a custom
     flag to give to rustc when the test is compiled:
     
    @@ -27,15 +27,16 @@ Directives can be standalone (like `//@ run-pass`) or take a value (like `//@
     compile-flags: -C overflow-checks=off`).
     
     Directives are written one directive per line: you cannot write multiple
    -directives on the same line. For example, if you write `//@ only-x86
    -only-windows` then `only-windows` is interpreted as a comment, not a separate
    -directive.
    +directives on the same line.
    +For example, if you write `//@ only-x86
    +only-windows` then `only-windows` is interpreted as a comment, not a separate directive.
     
     ## Listing of compiletest directives
     
    -The following is a list of compiletest directives. Directives are linked to
    -sections that describe the command in more detail if available. This list may
    -not be exhaustive. Directives can generally be found by browsing the
    +The following is a list of compiletest directives.
    +Directives are linked to sections that describe the command in more detail if available.
    +This list may not be exhaustive.
    +Directives can generally be found by browsing the
     `TestProps` structure found in [`directives.rs`] from the compiletest source.
     
     [`directives.rs`]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/compiletest/src/directives.rs
    @@ -65,8 +66,7 @@ See [Building auxiliary crates](compiletest.html#building-auxiliary-crates)
     
     ### Controlling outcome expectations
     
    -See [Controlling pass/fail
    -expectations](ui.md#controlling-passfail-expectations).
    +See [Controlling pass/fail expectations](ui.md#controlling-passfail-expectations).
     
     | Directive                   | Explanation                                 | Supported test suites                     | Possible values |
     |-----------------------------|---------------------------------------------|-------------------------------------------|-----------------|
    @@ -87,8 +87,7 @@ expectations](ui.md#controlling-passfail-expectations).
     ### Controlling output snapshots and normalizations
     
     See [Normalization](ui.md#normalization), [Output
    -comparison](ui.md#output-comparison) and [Rustfix tests](ui.md#rustfix-tests)
    -for more details.
    +comparison](ui.md#output-comparison) and [Rustfix tests](ui.md#rustfix-tests) for more details.
     
     | Directive                         | Explanation                                                                                                              | Supported test suites                        | Possible values                                                                         |
     |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------|----------------------------------------------|-----------------------------------------------------------------------------------------|
    @@ -115,8 +114,8 @@ for more details.
     
     [^check_stdout]: presently  this has a weird quirk
         where the test binary's stdout and stderr gets concatenated and then
    -    `error-pattern`s are matched on this combined output, which is ??? slightly
    -    questionable to say the least.
    +    `error-pattern`s are matched on this combined output, which is ???
    +    slightly questionable to say the least.
     
     ### Controlling when tests are run
     
    @@ -124,14 +123,13 @@ These directives are used to ignore the test in some situations, which
     means the test won't be compiled or run.
     
     * `ignore-X` where `X` is a target detail or other criteria on which to ignore the test (see below)
    -* `only-X` is like `ignore-X`, but will *only* run the test on that target or
    -  stage
    +* `only-X` is like `ignore-X`, but will *only* run the test on that target or stage
     * `ignore-auxiliary` is intended for files that *participate* in one or more other
       main test files but that `compiletest` should not try to build the file itself.
       Please backlink to which main test is actually using the auxiliary file.
    -* `ignore-test` always ignores the test. This can be used to temporarily disable
    -  a test if it is currently not working, but you want to keep it in-tree to
    -  re-enable it later.
    +* `ignore-test` always ignores the test.
    +  This can be used to temporarily disable
    +  a test if it is currently not working, but you want to keep it in-tree to re-enable it later.
     
     Some examples of `X` in `ignore-X` or `only-X`:
     
    @@ -158,16 +156,15 @@ Some examples of `X` in `ignore-X` or `only-X`:
       - This needs to be enabled with `COMPILETEST_ENABLE_DIST_TESTS=1`
     - The `rustc_abi` of the target: e.g. `rustc_abi-x86_64-sse2`
     
    -The following directives will check rustc build settings and target
    -settings:
    +The following directives will check rustc build settings and target settings:
     
     - `needs-asm-support` — ignores if the **host** architecture doesn't have
    -  stable support for `asm!`. For tests that cross-compile to explicit targets
    +  stable support for `asm!`.
    +  For tests that cross-compile to explicit targets
       via `--target`, use `needs-llvm-components` instead to ensure the appropriate
       backend is available.
     - `needs-profiler-runtime` — ignores the test if the profiler runtime was not
    -  enabled for the target
    -  (`build.profiler = true` in rustc's `bootstrap.toml`)
    +  enabled for the target (`build.profiler = true` in rustc's `bootstrap.toml`)
     - `needs-sanitizer-support` — ignores if the sanitizer support was not enabled
       for the target (`sanitizers = true` in rustc's `bootstrap.toml`)
     - `needs-sanitizer-{address,hwaddress,leak,memory,thread}` — ignores if the
    @@ -175,41 +172,36 @@ settings:
       hardware-assisted AddressSanitizer, LeakSanitizer, MemorySanitizer or
       ThreadSanitizer respectively)
     - `needs-run-enabled` — ignores if it is a test that gets executed, and running
    -  has been disabled. Running tests can be disabled with the `x test --run=never`
    -  flag, or running on fuchsia.
    +  has been disabled.
    +  Running tests can be disabled with the `x test --run=never` flag, or running on fuchsia.
     - `needs-unwind` — ignores if the target does not support unwinding
     - `needs-rust-lld` — ignores if the rust lld support is not enabled (`rust.lld =
       true` in `bootstrap.toml`)
     - `needs-threads` — ignores if the target does not have threading support
     - `needs-subprocess`  — ignores if the target does not have subprocess support
    -- `needs-symlink` — ignores if the target does not support symlinks. This can be
    -  the case on Windows if the developer did not enable privileged symlink
    +- `needs-symlink` — ignores if the target does not support symlinks.
    +  This can be the case on Windows if the developer did not enable privileged symlink
       permissions.
    -- `ignore-std-debug-assertions` — ignores if std was built with debug
    -  assertions.
    -- `needs-std-debug-assertions` — ignores if std was not built with debug
    -  assertions.
    -- `ignore-std-remap-debuginfo` — ignores if std was built with remapping of
    -  it's sources.
    -- `needs-std-remap-debugino` — ignores if std was not built with remapping of
    -  it's sources.
    -- `ignore-rustc-debug-assertions` — ignores if rustc was built with debug
    -  assertions.
    -- `needs-rustc-debug-assertions` — ignores if rustc was not built with debug
    -  assertions.
    +- `ignore-std-debug-assertions` — ignores if std was built with debug assertions.
    +- `needs-std-debug-assertions` — ignores if std was not built with debug assertions.
    +- `ignore-std-remap-debuginfo` — ignores if std was built with remapping of it's sources.
    +- `needs-std-remap-debugino` — ignores if std was not built with remapping of it's sources.
    +- `ignore-rustc-debug-assertions` — ignores if rustc was built with debug assertions.
    +- `needs-rustc-debug-assertions` — ignores if rustc was not built with debug assertions.
     - `needs-target-has-atomic` — ignores if target does not have support for all
       specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8,
    -  16, ptr` will only run if it supports the comma-separated list of atomic
    -  widths.
    +  16, ptr` will only run if it supports the comma-separated list of atomic widths.
     - `needs-dynamic-linking` — ignores if target does not support dynamic linking
       (which is orthogonal to it being unable to create `dylib` and `cdylib` crate types)
     - `needs-crate-type` — ignores if target platform does not support one or more
    -  of the comma-delimited list of specified crate types. For example,
    +  of the comma-delimited list of specified crate types.
    +  For example,
       `//@ needs-crate-type: cdylib, proc-macro` will cause the test to be ignored
       on `wasm32-unknown-unknown` target because the target does not support the
       `proc-macro` crate type.
     - `needs-target-std` — ignores if target platform does not have std support.
    -- `ignore-backends` — ignores the listed backends, separated by whitespace characters. Please note
    +- `ignore-backends` — ignores the listed backends, separated by whitespace characters.
    +  Please note
       that this directive can be overriden with the `--bypass-ignore-backends=[BACKEND]` command line
       flag.
     - `needs-backends` — only runs the test if current codegen backend is listed.
    @@ -220,29 +212,23 @@ The following directives will check LLVM support:
     
     - `exact-llvm-major-version: 19` — ignores if the llvm major version does not
       match the specified llvm major version.
    -- `min-llvm-version: 13.0` — ignored if the LLVM version is less than the given
    -  value
    +- `min-llvm-version: 13.0` — ignored if the LLVM version is less than the given value
     - `min-system-llvm-version: 12.0` — ignored if using a system LLVM and its
       version is less than the given value
     - `max-llvm-major-version: 19` — ignored if the LLVM major version is higher
       than the given major version
     - `ignore-llvm-version: 9.0` — ignores a specific LLVM version
    -- `ignore-llvm-version: 7.0 - 9.9.9` — ignores LLVM versions in a range
    -  (inclusive)
    -- `needs-llvm-components: powerpc` — ignores if the specific LLVM component was
    -  not built. Note: The test will fail on CI (when
    -  `COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS` is set) if the component does not
    -  exist.
    +- `ignore-llvm-version: 7.0 - 9.9.9` — ignores LLVM versions in a range (inclusive)
    +- `needs-llvm-components: powerpc` — ignores if the specific LLVM component was not built.
    +  Note: The test will fail on CI (when
    +  `COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS` is set) if the component does not exist.
     - `needs-forced-clang-based-tests` — test is ignored unless the environment
    -  variable `RUSTBUILD_FORCE_CLANG_BASED_TESTS` is set, which enables building
    -  clang alongside LLVM
    +  variable `RUSTBUILD_FORCE_CLANG_BASED_TESTS` is set, which enables building clang alongside LLVM
       - This is only set in two CI jobs ([`x86_64-gnu-debug`] and
    -    [`aarch64-gnu-debug`]), which only runs a
    -    subset of `run-make` tests. Other tests with this directive will not
    -    run at all, which is usually not what you want.
    +    [`aarch64-gnu-debug`]), which only runs a subset of `run-make` tests.
    +    Other tests with this directive will not run at all, which is usually not what you want.
     
    -See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for
    -ignoring debuggers.
    +See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for ignoring debuggers.
     
     [remote testing]: running.md#running-tests-on-a-remote-machine
     [compare modes]: ui.md#compare-modes
    @@ -311,7 +297,8 @@ Asked in
     The test suites [`rustdoc-html`][rustdoc-html-tests], [`rustdoc-js`/`rustdoc-js-std`][rustdoc-js-tests]
     and [`rustdoc-json`][rustdoc-json-tests] each feature an additional set of directives whose basic
     syntax resembles the one of compiletest directives but which are ultimately read and checked by
    -separate tools. For more information, please read their respective chapters as linked above.
    +separate tools.
    +For more information, please read their respective chapters as linked above.
     
     [rustdoc-html-tests]: ../rustdoc-internals/rustdoc-html-test-suite.md
     [rustdoc-js-tests]: ../rustdoc-internals/search.html#testing-the-search-engine
    @@ -327,8 +314,7 @@ See [Pretty-printer](compiletest.md#pretty-printer-tests).
     - [`revisions`](compiletest.md#revisions) — compile multiple times
     -[`forbid-output`](compiletest.md#incremental-tests) — incremental cfail rejects
           output pattern
    -- [`should-ice`](compiletest.md#incremental-tests) — incremental cfail should
    -      ICE
    +- [`should-ice`](compiletest.md#incremental-tests) — incremental cfail should ICE
     - [`reference`] — an annotation linking to a rule in the reference
     - `disable-gdb-pretty-printers` — disable gdb pretty printers for debuginfo tests
     
    @@ -348,40 +334,37 @@ test suites that use those tools:
     
     ### Tidy specific directives
     
    -The following directives control how the [tidy script](../conventions.md#formatting)
    -verifies tests.
    +The following directives control how the [tidy script](../conventions.md#formatting) verifies tests.
     
     - `ignore-tidy-target-specific-tests` disables checking that the appropriate
       LLVM component is required (via a `needs-llvm-components` directive) when a
    -  test is compiled for a specific target (via the `--target` flag in a
    -  `compile-flag` directive).
    +  test is compiled for a specific target (via the `--target` flag in a `compile-flag` directive).
     - [`unused-revision-names`](compiletest.md#ignoring-unused-revision-names) -
           suppress tidy checks for mentioning unknown revision names.
     
     ## Substitutions
     
     Directive values support substituting a few variables which will be replaced
    -with their corresponding value. For example, if you need to pass a compiler flag
    +with their corresponding value.
    +For example, if you need to pass a compiler flag
     with a path to a specific file, something like the following could work:
     
     ```rust,ignore
     //@ compile-flags: --remap-path-prefix={{src-base}}=/the/src
     ```
     
    -Where the sentinel `{{src-base}}` will be replaced with the appropriate path
    -described below:
    +Where the sentinel `{{src-base}}` will be replaced with the appropriate path described below:
     
    -- `{{cwd}}`: The directory where compiletest is run from. This may not be the
    -  root of the checkout, so you should avoid using it where possible.
    +- `{{cwd}}`: The directory where compiletest is run from.
    +  This may not be the root of the checkout, so you should avoid using it where possible.
       - Examples: `/path/to/rust`, `/path/to/build/root`
    -- `{{src-base}}`: The directory where the test is defined. This is equivalent to
    -  `$DIR` for [output normalization].
    +- `{{src-base}}`: The directory where the test is defined.
    +  This is equivalent to `$DIR` for [output normalization].
       - Example: `/path/to/rust/tests/ui/error-codes`
    -- `{{build-base}}`: The base directory where the test's output goes. This is
    -  equivalent to `$TEST_BUILD_DIR` for [output normalization].
    +- `{{build-base}}`: The base directory where the test's output goes.
    +  This is equivalent to `$TEST_BUILD_DIR` for [output normalization].
       - Example: `/path/to/rust/build/x86_64-unknown-linux-gnu/test/ui`
    -- `{{rust-src-base}}`: The sysroot directory where libstd/libcore/... are
    -  located
    +- `{{rust-src-base}}`: The sysroot directory where libstd/libcore/... are located
     - `{{sysroot-base}}`: Path of the sysroot directory used to build the test.
       - Mainly intended for `ui-fulldeps` tests that run the compiler via API.
     - `{{target-linker}}`: Linker that would be passed to `-Clinker` for this test,
    @@ -400,7 +383,8 @@ for an example of a test that uses this substitution.
     ## Adding a directive
     
     One would add a new directive if there is a need to define some test property or
    -behavior on an individual, test-by-test basis. A directive property serves as
    +behavior on an individual, test-by-test basis.
    +A directive property serves as
     the directive's backing store (holds the command's current value) at runtime.
     
     To add a new directive property:
    @@ -420,19 +404,21 @@ declaration block is found in [`src/tools/compiletest/src/common.rs`]).
     `TestProps`'s `load_from()` method will try passing the current line of text to
     each parser, which, in turn typically checks to see if the line begins with a
     particular commented (`//@`) directive such as `//@ must-compile-successfully`
    -or `//@ failure-status`. Whitespace after the comment marker is optional.
    +or `//@ failure-status`.
    +Whitespace after the comment marker is optional.
     
     Parsers will override a given directive property's default value merely by being
     specified in the test file as a directive or by having a parameter value
     specified in the test file, depending on the directive.
     
     Parsers defined in `impl Config` are typically named `parse_`
    -(note kebab-case `` transformed to snake-case
    -``). `impl Config` also defines several 'low-level' parsers
    +(note kebab-case `` transformed to snake-case ``).
    +`impl Config` also defines several 'low-level' parsers
     which make it simple to parse common patterns like simple presence or not
     (`parse_name_directive()`), `directive:parameter(s)`
     (`parse_name_value_directive()`), optional parsing only if a particular `cfg`
    -attribute is defined (`has_cfg_prefix()`) and many more. The low-level parsers
    +attribute is defined (`has_cfg_prefix()`) and many more.
    +The low-level parsers
     are found near the end of the `impl Config` block; be sure to look through them
     and their associated parsers immediately above to see how they are used to avoid
     writing additional parsing code unnecessarily.
    @@ -483,15 +469,16 @@ As a concrete example, here is the implementation for the
     ### Implementing the behavior change
     
     When a test invokes a particular directive, it is expected that some behavior
    -will change as a result. What behavior, obviously, will depend on the purpose of
    -the directive. In the case of `failure-status`, the behavior that changes is
    +will change as a result.
    +What behavior, obviously, will depend on the purpose of the directive.
    +In the case of `failure-status`, the behavior that changes is
     that `compiletest` expects the failure code defined by the directive invoked in
     the test, rather than the default value.
     
     Although specific to `failure-status` (as every directive will have a different
     implementation in order to invoke behavior change) perhaps it is helpful to see
    -the behavior change implementation of one case, simply as an example. To
    -implement `failure-status`, the `check_correct_failure_status()` function found
    +the behavior change implementation of one case, simply as an example.
    +To implement `failure-status`, the `check_correct_failure_status()` function found
     in the `TestCx` implementation block, located in
     [`src/tools/compiletest/src/runtest.rs`], was modified as per below:
     
    @@ -532,10 +519,10 @@ in the `TestCx` implementation block, located in
          }
     ```
     
    -Note the use of `self.props.failure_status` to access the directive property. In
    -tests which do not specify the failure status directive,
    -`self.props.failure_status` will evaluate to the default value of 101 at the
    -time of this writing. But for a test which specifies a directive of, for
    +Note the use of `self.props.failure_status` to access the directive property.
    +In tests which do not specify the failure status directive,
    +`self.props.failure_status` will evaluate to the default value of 101 at the time of this writing.
    +But for a test which specifies a directive of, for
     example, `//@ failure-status: 1`, `self.props.failure_status` will evaluate to
     1, as `parse_failure_status()` will have overridden the `TestProps` default
     value, for that test specifically.
    
    From 6b5a1a51e5f3f1cf1bffb072c4d6ebaa04400744 Mon Sep 17 00:00:00 2001
    From: Guilherme Luiz 
    Date: Mon, 12 Jan 2026 16:39:54 -0300
    Subject: [PATCH 2022/3801] =?UTF-8?q?Switch=20from=20=EF=AC=83=20to=20?=
     =?UTF-8?q?=EF=AC=85=20ligature=20for=20better=20visual=20clarity?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     library/core/src/char/methods.rs | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
    index 0acb3e964f54..87b328c91287 100644
    --- a/library/core/src/char/methods.rs
    +++ b/library/core/src/char/methods.rs
    @@ -1143,12 +1143,12 @@ impl char {
         /// [Unicode Standard]: https://www.unicode.org/versions/latest/
         ///
         /// # Examples
    -    /// `'ffi'` (U+FB03) is a single Unicode code point (a ligature) that maps to "FFI" in uppercase.
    +    /// `'ſt'` (U+FB05) is a single Unicode code point (a ligature) that maps to "ST" in uppercase.
         ///
         /// As an iterator:
         ///
         /// ```
    -    /// for c in 'ffi'.to_uppercase() {
    +    /// for c in 'ſt'.to_uppercase() {
         ///     print!("{c}");
         /// }
         /// println!();
    @@ -1157,13 +1157,13 @@ impl char {
         /// Using `println!` directly:
         ///
         /// ```
    -    /// println!("{}", 'ffi'.to_uppercase());
    +    /// println!("{}", 'ſt'.to_uppercase());
         /// ```
         ///
         /// Both are equivalent to:
         ///
         /// ```
    -    /// println!("FFI");
    +    /// println!("ST");
         /// ```
         ///
         /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
    @@ -1172,7 +1172,7 @@ impl char {
         /// assert_eq!('c'.to_uppercase().to_string(), "C");
         ///
         /// // Sometimes the result is more than one character:
    -    /// assert_eq!('ffi'.to_uppercase().to_string(), "FFI");
    +    /// assert_eq!('ſt'.to_uppercase().to_string(), "ST");
         ///
         /// // Characters that do not have both uppercase and lowercase
         /// // convert into themselves.
    
    From b57c2493339dd2d0dd4a8df6ed7ee81b81e84816 Mon Sep 17 00:00:00 2001
    From: BD103 <59022059+BD103@users.noreply.github.com>
    Date: Mon, 12 Jan 2026 14:42:00 -0500
    Subject: [PATCH 2023/3801] fix: make `Type::of` supported unsized types
    
    ---
     library/core/src/mem/type_info.rs | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs
    index 7938e2b52ed0..6b16bfadc233 100644
    --- a/library/core/src/mem/type_info.rs
    +++ b/library/core/src/mem/type_info.rs
    @@ -31,7 +31,7 @@ impl Type {
         #[unstable(feature = "type_info", issue = "146922")]
         #[rustc_const_unstable(feature = "type_info", issue = "146922")]
         // FIXME(reflection): don't require the 'static bound
    -    pub const fn of() -> Self {
    +    pub const fn of() -> Self {
             const { TypeId::of::().info() }
         }
     }
    
    From 1bde2f4705d351e24eb556604c0da5511a277e15 Mon Sep 17 00:00:00 2001
    From: BD103 <59022059+BD103@users.noreply.github.com>
    Date: Mon, 12 Jan 2026 14:43:21 -0500
    Subject: [PATCH 2024/3801] chore: test `Type::of` on unsized types
    
    I chose to simply extend `dump.rs`, rather than create a new UI test.
    ---
     tests/ui/reflection/dump.rs         | 2 ++
     tests/ui/reflection/dump.run.stdout | 2 ++
     2 files changed, 4 insertions(+)
    
    diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs
    index 3bf4f32b6641..efc3024a84e9 100644
    --- a/tests/ui/reflection/dump.rs
    +++ b/tests/ui/reflection/dump.rs
    @@ -27,4 +27,6 @@ fn main() {
         println!("{:#?}", const { Type::of::<&Unsized>() }.kind);
         println!("{:#?}", const { Type::of::<&str>() }.kind);
         println!("{:#?}", const { Type::of::<&[u8]>() }.kind);
    +    println!("{:#?}", const { Type::of::() }.kind);
    +    println!("{:#?}", const { Type::of::<[u8]>() }.kind);
     }
    diff --git a/tests/ui/reflection/dump.run.stdout b/tests/ui/reflection/dump.run.stdout
    index 71fd80b46658..e9db772e8eba 100644
    --- a/tests/ui/reflection/dump.run.stdout
    +++ b/tests/ui/reflection/dump.run.stdout
    @@ -21,3 +21,5 @@ Other
     Other
     Other
     Other
    +Other
    +Other
    
    From 815407acb45eb42366995bf31b6ecfa9960af28f Mon Sep 17 00:00:00 2001
    From: Ada Alakbarova 
    Date: Mon, 12 Jan 2026 15:41:02 +0100
    Subject: [PATCH 2025/3801] clean-up
    
    early-return earlier, and create suggestion-related things later
    ---
     clippy_lints/src/strlen_on_c_strings.rs | 32 ++++++++++++-------------
     tests/ui/strlen_on_c_strings.fixed      |  3 +--
     tests/ui/strlen_on_c_strings.rs         |  3 +--
     tests/ui/strlen_on_c_strings.stderr     | 28 +++++++++++-----------
     4 files changed, 32 insertions(+), 34 deletions(-)
    
    diff --git a/clippy_lints/src/strlen_on_c_strings.rs b/clippy_lints/src/strlen_on_c_strings.rs
    index 0d50bd547652..2b3e0ce611ff 100644
    --- a/clippy_lints/src/strlen_on_c_strings.rs
    +++ b/clippy_lints/src/strlen_on_c_strings.rs
    @@ -1,4 +1,4 @@
    -use clippy_utils::diagnostics::span_lint_and_sugg;
    +use clippy_utils::diagnostics::span_lint_and_then;
     use clippy_utils::res::MaybeDef;
     use clippy_utils::source::snippet_with_context;
     use clippy_utils::visitors::is_expr_unsafe;
    @@ -48,6 +48,15 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {
                 && !recv.span.from_expansion()
                 && path.ident.name == sym::as_ptr
             {
    +            let ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
    +            let method_name = if ty.is_diag_item(cx, sym::cstring_type) {
    +                "as_bytes"
    +            } else if ty.is_lang_item(cx, LangItem::CStr) {
    +                "to_bytes"
    +            } else {
    +                return;
    +            };
    +
                 let ctxt = expr.span.ctxt();
                 let span = match cx.tcx.parent_hir_node(expr.hir_id) {
                     Node::Block(&Block {
    @@ -58,25 +67,16 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {
                     _ => expr.span,
                 };
     
    -            let ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
    -            let mut app = Applicability::MachineApplicable;
    -            let val_name = snippet_with_context(cx, self_arg.span, ctxt, "..", &mut app).0;
    -            let method_name = if ty.is_diag_item(cx, sym::cstring_type) {
    -                "as_bytes"
    -            } else if ty.is_lang_item(cx, LangItem::CStr) {
    -                "to_bytes"
    -            } else {
    -                return;
    -            };
    -
    -            span_lint_and_sugg(
    +            span_lint_and_then(
                     cx,
                     STRLEN_ON_C_STRINGS,
                     span,
                     "using `libc::strlen` on a `CString` or `CStr` value",
    -                "try",
    -                format!("{val_name}.{method_name}().len()"),
    -                app,
    +                |diag| {
    +                    let mut app = Applicability::MachineApplicable;
    +                    let val_name = snippet_with_context(cx, self_arg.span, ctxt, "_", &mut app).0;
    +                    diag.span_suggestion(span, "use", format!("{val_name}.{method_name}().len()"), app);
    +                },
                 );
             }
         }
    diff --git a/tests/ui/strlen_on_c_strings.fixed b/tests/ui/strlen_on_c_strings.fixed
    index 17c1b541f77c..f52c571c1088 100644
    --- a/tests/ui/strlen_on_c_strings.fixed
    +++ b/tests/ui/strlen_on_c_strings.fixed
    @@ -1,7 +1,6 @@
     #![warn(clippy::strlen_on_c_strings)]
    -#![allow(dead_code, clippy::manual_c_str_literals)]
    +#![allow(clippy::manual_c_str_literals)]
     
    -#[allow(unused)]
     use libc::strlen;
     use std::ffi::{CStr, CString};
     
    diff --git a/tests/ui/strlen_on_c_strings.rs b/tests/ui/strlen_on_c_strings.rs
    index c641422f5df4..39366d08c1a2 100644
    --- a/tests/ui/strlen_on_c_strings.rs
    +++ b/tests/ui/strlen_on_c_strings.rs
    @@ -1,7 +1,6 @@
     #![warn(clippy::strlen_on_c_strings)]
    -#![allow(dead_code, clippy::manual_c_str_literals)]
    +#![allow(clippy::manual_c_str_literals)]
     
    -#[allow(unused)]
     use libc::strlen;
     use std::ffi::{CStr, CString};
     
    diff --git a/tests/ui/strlen_on_c_strings.stderr b/tests/ui/strlen_on_c_strings.stderr
    index 84a93b99ee33..eecce8d97865 100644
    --- a/tests/ui/strlen_on_c_strings.stderr
    +++ b/tests/ui/strlen_on_c_strings.stderr
    @@ -1,47 +1,47 @@
     error: using `libc::strlen` on a `CString` or `CStr` value
    -  --> tests/ui/strlen_on_c_strings.rs:11:13
    +  --> tests/ui/strlen_on_c_strings.rs:10:13
        |
     LL |     let _ = unsafe { libc::strlen(cstring.as_ptr()) };
    -   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstring.as_bytes().len()`
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.as_bytes().len()`
        |
        = note: `-D clippy::strlen-on-c-strings` implied by `-D warnings`
        = help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]`
     
     error: using `libc::strlen` on a `CString` or `CStr` value
    -  --> tests/ui/strlen_on_c_strings.rs:16:13
    +  --> tests/ui/strlen_on_c_strings.rs:15:13
        |
     LL |     let _ = unsafe { libc::strlen(cstr.as_ptr()) };
    -   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()`
     
     error: using `libc::strlen` on a `CString` or `CStr` value
    -  --> tests/ui/strlen_on_c_strings.rs:19:13
    +  --> tests/ui/strlen_on_c_strings.rs:18:13
        |
     LL |     let _ = unsafe { strlen(cstr.as_ptr()) };
    -   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()`
     
     error: using `libc::strlen` on a `CString` or `CStr` value
    -  --> tests/ui/strlen_on_c_strings.rs:23:22
    +  --> tests/ui/strlen_on_c_strings.rs:22:22
        |
     LL |     let _ = unsafe { strlen((*pcstr).as_ptr()) };
    -   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*pcstr).to_bytes().len()`
    +   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `(*pcstr).to_bytes().len()`
     
     error: using `libc::strlen` on a `CString` or `CStr` value
    -  --> tests/ui/strlen_on_c_strings.rs:29:22
    +  --> tests/ui/strlen_on_c_strings.rs:28:22
        |
     LL |     let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) };
    -   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe_identity(cstr).to_bytes().len()`
    +   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe_identity(cstr).to_bytes().len()`
     
     error: using `libc::strlen` on a `CString` or `CStr` value
    -  --> tests/ui/strlen_on_c_strings.rs:31:13
    +  --> tests/ui/strlen_on_c_strings.rs:30:13
        |
     LL |     let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) };
    -   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { unsafe_identity(cstr) }.to_bytes().len()`
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe { unsafe_identity(cstr) }.to_bytes().len()`
     
     error: using `libc::strlen` on a `CString` or `CStr` value
    -  --> tests/ui/strlen_on_c_strings.rs:35:22
    +  --> tests/ui/strlen_on_c_strings.rs:34:22
        |
     LL |     let _ = unsafe { strlen(f(cstr).as_ptr()) };
    -   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `f(cstr).to_bytes().len()`
    +   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `f(cstr).to_bytes().len()`
     
     error: aborting due to 7 previous errors
     
    
    From 7cdfee9de8d7d9c627c4b5be3c5a6e4a7c192d13 Mon Sep 17 00:00:00 2001
    From: Ada Alakbarova 
    Date: Mon, 12 Jan 2026 15:44:20 +0100
    Subject: [PATCH 2026/3801] feat: specify the type
    
    ---
     clippy_lints/src/strlen_on_c_strings.rs |  8 ++++----
     tests/ui/strlen_on_c_strings.fixed      | 14 +++++++-------
     tests/ui/strlen_on_c_strings.rs         | 14 +++++++-------
     tests/ui/strlen_on_c_strings.stderr     | 14 +++++++-------
     4 files changed, 25 insertions(+), 25 deletions(-)
    
    diff --git a/clippy_lints/src/strlen_on_c_strings.rs b/clippy_lints/src/strlen_on_c_strings.rs
    index 2b3e0ce611ff..ec0fc08ea552 100644
    --- a/clippy_lints/src/strlen_on_c_strings.rs
    +++ b/clippy_lints/src/strlen_on_c_strings.rs
    @@ -49,10 +49,10 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {
                 && path.ident.name == sym::as_ptr
             {
                 let ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
    -            let method_name = if ty.is_diag_item(cx, sym::cstring_type) {
    -                "as_bytes"
    +            let (ty_name, method_name) = if ty.is_diag_item(cx, sym::cstring_type) {
    +                ("CString", "as_bytes")
                 } else if ty.is_lang_item(cx, LangItem::CStr) {
    -                "to_bytes"
    +                ("CStr", "to_bytes")
                 } else {
                     return;
                 };
    @@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {
                     cx,
                     STRLEN_ON_C_STRINGS,
                     span,
    -                "using `libc::strlen` on a `CString` or `CStr` value",
    +                format!("using `libc::strlen` on a `{ty_name}` value"),
                     |diag| {
                         let mut app = Applicability::MachineApplicable;
                         let val_name = snippet_with_context(cx, self_arg.span, ctxt, "_", &mut app).0;
    diff --git a/tests/ui/strlen_on_c_strings.fixed b/tests/ui/strlen_on_c_strings.fixed
    index f52c571c1088..68cf1ba2edc5 100644
    --- a/tests/ui/strlen_on_c_strings.fixed
    +++ b/tests/ui/strlen_on_c_strings.fixed
    @@ -8,29 +8,29 @@ fn main() {
         // CString
         let cstring = CString::new("foo").expect("CString::new failed");
         let _ = cstring.as_bytes().len();
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CString` value
     
         // CStr
         let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
         let _ = cstr.to_bytes().len();
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     
         let _ = cstr.to_bytes().len();
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     
         let pcstr: *const &CStr = &cstr;
         let _ = unsafe { (*pcstr).to_bytes().len() };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     
         unsafe fn unsafe_identity(x: T) -> T {
             x
         }
         let _ = unsafe { unsafe_identity(cstr).to_bytes().len() };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
         let _ = unsafe { unsafe_identity(cstr) }.to_bytes().len();
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     
         let f: unsafe fn(_) -> _ = unsafe_identity;
         let _ = unsafe { f(cstr).to_bytes().len() };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     }
    diff --git a/tests/ui/strlen_on_c_strings.rs b/tests/ui/strlen_on_c_strings.rs
    index 39366d08c1a2..6d6eb0b5c152 100644
    --- a/tests/ui/strlen_on_c_strings.rs
    +++ b/tests/ui/strlen_on_c_strings.rs
    @@ -8,29 +8,29 @@ fn main() {
         // CString
         let cstring = CString::new("foo").expect("CString::new failed");
         let _ = unsafe { libc::strlen(cstring.as_ptr()) };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CString` value
     
         // CStr
         let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
         let _ = unsafe { libc::strlen(cstr.as_ptr()) };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     
         let _ = unsafe { strlen(cstr.as_ptr()) };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     
         let pcstr: *const &CStr = &cstr;
         let _ = unsafe { strlen((*pcstr).as_ptr()) };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     
         unsafe fn unsafe_identity(x: T) -> T {
             x
         }
         let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
         let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     
         let f: unsafe fn(_) -> _ = unsafe_identity;
         let _ = unsafe { strlen(f(cstr).as_ptr()) };
    -    //~^ strlen_on_c_strings
    +    //~^ ERROR: using `libc::strlen` on a `CStr` value
     }
    diff --git a/tests/ui/strlen_on_c_strings.stderr b/tests/ui/strlen_on_c_strings.stderr
    index eecce8d97865..f2ccc91aabf1 100644
    --- a/tests/ui/strlen_on_c_strings.stderr
    +++ b/tests/ui/strlen_on_c_strings.stderr
    @@ -1,4 +1,4 @@
    -error: using `libc::strlen` on a `CString` or `CStr` value
    +error: using `libc::strlen` on a `CString` value
       --> tests/ui/strlen_on_c_strings.rs:10:13
        |
     LL |     let _ = unsafe { libc::strlen(cstring.as_ptr()) };
    @@ -7,37 +7,37 @@ LL |     let _ = unsafe { libc::strlen(cstring.as_ptr()) };
        = note: `-D clippy::strlen-on-c-strings` implied by `-D warnings`
        = help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]`
     
    -error: using `libc::strlen` on a `CString` or `CStr` value
    +error: using `libc::strlen` on a `CStr` value
       --> tests/ui/strlen_on_c_strings.rs:15:13
        |
     LL |     let _ = unsafe { libc::strlen(cstr.as_ptr()) };
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()`
     
    -error: using `libc::strlen` on a `CString` or `CStr` value
    +error: using `libc::strlen` on a `CStr` value
       --> tests/ui/strlen_on_c_strings.rs:18:13
        |
     LL |     let _ = unsafe { strlen(cstr.as_ptr()) };
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()`
     
    -error: using `libc::strlen` on a `CString` or `CStr` value
    +error: using `libc::strlen` on a `CStr` value
       --> tests/ui/strlen_on_c_strings.rs:22:22
        |
     LL |     let _ = unsafe { strlen((*pcstr).as_ptr()) };
        |                      ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `(*pcstr).to_bytes().len()`
     
    -error: using `libc::strlen` on a `CString` or `CStr` value
    +error: using `libc::strlen` on a `CStr` value
       --> tests/ui/strlen_on_c_strings.rs:28:22
        |
     LL |     let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) };
        |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe_identity(cstr).to_bytes().len()`
     
    -error: using `libc::strlen` on a `CString` or `CStr` value
    +error: using `libc::strlen` on a `CStr` value
       --> tests/ui/strlen_on_c_strings.rs:30:13
        |
     LL |     let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) };
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe { unsafe_identity(cstr) }.to_bytes().len()`
     
    -error: using `libc::strlen` on a `CString` or `CStr` value
    +error: using `libc::strlen` on a `CStr` value
       --> tests/ui/strlen_on_c_strings.rs:34:22
        |
     LL |     let _ = unsafe { strlen(f(cstr).as_ptr()) };
    
    From 49c86140fb2326ea58655c0fc3e46d52bcacce89 Mon Sep 17 00:00:00 2001
    From: Ada Alakbarova 
    Date: Mon, 12 Jan 2026 17:54:50 +0100
    Subject: [PATCH 2027/3801] feat: also lint types that dereference to `CStr`
    
    For simplicity's sake, this also changes the lint to always suggest
    `to_bytes`, as it is somewhat hard to find out whether a type could
    dereference to `CString` (which is what `as_bytes` would require)
    ---
     clippy_lints/src/strlen_on_c_strings.rs | 19 ++++++++++++-------
     tests/ui/strlen_on_c_strings.fixed      | 14 ++++++++++++--
     tests/ui/strlen_on_c_strings.rs         | 12 +++++++++++-
     tests/ui/strlen_on_c_strings.stderr     | 22 ++++++++++++++++++++--
     4 files changed, 55 insertions(+), 12 deletions(-)
    
    diff --git a/clippy_lints/src/strlen_on_c_strings.rs b/clippy_lints/src/strlen_on_c_strings.rs
    index ec0fc08ea552..5eb160720c52 100644
    --- a/clippy_lints/src/strlen_on_c_strings.rs
    +++ b/clippy_lints/src/strlen_on_c_strings.rs
    @@ -47,14 +47,19 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {
                 && let ExprKind::MethodCall(path, self_arg, [], _) = recv.kind
                 && !recv.span.from_expansion()
                 && path.ident.name == sym::as_ptr
    +            && let typeck = cx.typeck_results()
    +            && typeck
    +                .expr_ty_adjusted(self_arg)
    +                .peel_refs()
    +                .is_lang_item(cx, LangItem::CStr)
             {
    -            let ty = cx.typeck_results().expr_ty(self_arg).peel_refs();
    -            let (ty_name, method_name) = if ty.is_diag_item(cx, sym::cstring_type) {
    -                ("CString", "as_bytes")
    +            let ty = typeck.expr_ty(self_arg).peel_refs();
    +            let ty_kind = if ty.is_diag_item(cx, sym::cstring_type) {
    +                "`CString` value"
                 } else if ty.is_lang_item(cx, LangItem::CStr) {
    -                ("CStr", "to_bytes")
    +                "`CStr` value"
                 } else {
    -                return;
    +                "type that dereferences to `CStr`"
                 };
     
                 let ctxt = expr.span.ctxt();
    @@ -71,11 +76,11 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {
                     cx,
                     STRLEN_ON_C_STRINGS,
                     span,
    -                format!("using `libc::strlen` on a `{ty_name}` value"),
    +                format!("using `libc::strlen` on a {ty_kind}"),
                     |diag| {
                         let mut app = Applicability::MachineApplicable;
                         let val_name = snippet_with_context(cx, self_arg.span, ctxt, "_", &mut app).0;
    -                    diag.span_suggestion(span, "use", format!("{val_name}.{method_name}().len()"), app);
    +                    diag.span_suggestion(span, "use", format!("{val_name}.to_bytes().len()"), app);
                     },
                 );
             }
    diff --git a/tests/ui/strlen_on_c_strings.fixed b/tests/ui/strlen_on_c_strings.fixed
    index 68cf1ba2edc5..33a328af6df4 100644
    --- a/tests/ui/strlen_on_c_strings.fixed
    +++ b/tests/ui/strlen_on_c_strings.fixed
    @@ -1,5 +1,5 @@
     #![warn(clippy::strlen_on_c_strings)]
    -#![allow(clippy::manual_c_str_literals)]
    +#![allow(clippy::manual_c_str_literals, clippy::boxed_local)]
     
     use libc::strlen;
     use std::ffi::{CStr, CString};
    @@ -7,7 +7,7 @@ use std::ffi::{CStr, CString};
     fn main() {
         // CString
         let cstring = CString::new("foo").expect("CString::new failed");
    -    let _ = cstring.as_bytes().len();
    +    let _ = cstring.to_bytes().len();
         //~^ ERROR: using `libc::strlen` on a `CString` value
     
         // CStr
    @@ -34,3 +34,13 @@ fn main() {
         let _ = unsafe { f(cstr).to_bytes().len() };
         //~^ ERROR: using `libc::strlen` on a `CStr` value
     }
    +
    +// make sure we lint types that _adjust_ to `CStr`
    +fn adjusted(box_cstring: Box, box_cstr: Box, arc_cstring: std::sync::Arc) {
    +    let _ = box_cstring.to_bytes().len();
    +    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`
    +    let _ = box_cstr.to_bytes().len();
    +    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`
    +    let _ = arc_cstring.to_bytes().len();
    +    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`
    +}
    diff --git a/tests/ui/strlen_on_c_strings.rs b/tests/ui/strlen_on_c_strings.rs
    index 6d6eb0b5c152..3c11c3a05269 100644
    --- a/tests/ui/strlen_on_c_strings.rs
    +++ b/tests/ui/strlen_on_c_strings.rs
    @@ -1,5 +1,5 @@
     #![warn(clippy::strlen_on_c_strings)]
    -#![allow(clippy::manual_c_str_literals)]
    +#![allow(clippy::manual_c_str_literals, clippy::boxed_local)]
     
     use libc::strlen;
     use std::ffi::{CStr, CString};
    @@ -34,3 +34,13 @@ fn main() {
         let _ = unsafe { strlen(f(cstr).as_ptr()) };
         //~^ ERROR: using `libc::strlen` on a `CStr` value
     }
    +
    +// make sure we lint types that _adjust_ to `CStr`
    +fn adjusted(box_cstring: Box, box_cstr: Box, arc_cstring: std::sync::Arc) {
    +    let _ = unsafe { libc::strlen(box_cstring.as_ptr()) };
    +    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`
    +    let _ = unsafe { libc::strlen(box_cstr.as_ptr()) };
    +    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`
    +    let _ = unsafe { libc::strlen(arc_cstring.as_ptr()) };
    +    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`
    +}
    diff --git a/tests/ui/strlen_on_c_strings.stderr b/tests/ui/strlen_on_c_strings.stderr
    index f2ccc91aabf1..2b059872a2da 100644
    --- a/tests/ui/strlen_on_c_strings.stderr
    +++ b/tests/ui/strlen_on_c_strings.stderr
    @@ -2,7 +2,7 @@ error: using `libc::strlen` on a `CString` value
       --> tests/ui/strlen_on_c_strings.rs:10:13
        |
     LL |     let _ = unsafe { libc::strlen(cstring.as_ptr()) };
    -   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.as_bytes().len()`
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.to_bytes().len()`
        |
        = note: `-D clippy::strlen-on-c-strings` implied by `-D warnings`
        = help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]`
    @@ -43,5 +43,23 @@ error: using `libc::strlen` on a `CStr` value
     LL |     let _ = unsafe { strlen(f(cstr).as_ptr()) };
        |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `f(cstr).to_bytes().len()`
     
    -error: aborting due to 7 previous errors
    +error: using `libc::strlen` on a type that dereferences to `CStr`
    +  --> tests/ui/strlen_on_c_strings.rs:40:13
    +   |
    +LL |     let _ = unsafe { libc::strlen(box_cstring.as_ptr()) };
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `box_cstring.to_bytes().len()`
    +
    +error: using `libc::strlen` on a type that dereferences to `CStr`
    +  --> tests/ui/strlen_on_c_strings.rs:42:13
    +   |
    +LL |     let _ = unsafe { libc::strlen(box_cstr.as_ptr()) };
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `box_cstr.to_bytes().len()`
    +
    +error: using `libc::strlen` on a type that dereferences to `CStr`
    +  --> tests/ui/strlen_on_c_strings.rs:44:13
    +   |
    +LL |     let _ = unsafe { libc::strlen(arc_cstring.as_ptr()) };
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `arc_cstring.to_bytes().len()`
    +
    +error: aborting due to 10 previous errors
     
    
    From e0d9c079ee616f7f6ef6a0b81d9e12962689bfb5 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:06:43 +0200
    Subject: [PATCH 2028/3801] add missing pause
    
    ---
     src/doc/rustc-dev-guide/src/tests/directives.md | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
    index 0852f300b9be..ae341599f15a 100644
    --- a/src/doc/rustc-dev-guide/src/tests/directives.md
    +++ b/src/doc/rustc-dev-guide/src/tests/directives.md
    @@ -28,8 +28,8 @@ compile-flags: -C overflow-checks=off`).
     
     Directives are written one directive per line: you cannot write multiple
     directives on the same line.
    -For example, if you write `//@ only-x86
    -only-windows` then `only-windows` is interpreted as a comment, not a separate directive.
    +For example, if you write `//@ only-x86 only-windows`,
    +then `only-windows` is interpreted as a comment, not a separate directive.
     
     ## Listing of compiletest directives
     
    
    From 31c019139531de6cab03cdf3476c71145b635848 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:10:04 +0200
    Subject: [PATCH 2029/3801] sembr src/building/new-target.md
    
    ---
     .../src/building/new-target.md                | 51 +++++++++----------
     1 file changed, 24 insertions(+), 27 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md
    index 8465a1388870..d0ed787f520a 100644
    --- a/src/doc/rustc-dev-guide/src/building/new-target.md
    +++ b/src/doc/rustc-dev-guide/src/building/new-target.md
    @@ -1,7 +1,7 @@
     # Adding a new target
     
    -These are a set of steps to add support for a new target. There are
    -numerous end states and paths to get there, so not all sections may be
    +These are a set of steps to add support for a new target.
    +There are numerous end states and paths to get there, so not all sections may be
     relevant to your desired goal.
     
     See also the associated documentation in the [target tier policy].
    @@ -11,8 +11,8 @@ See also the associated documentation in the [target tier policy].
     ## Specifying a new LLVM
     
     For very new targets, you may need to use a different fork of LLVM
    -than what is currently shipped with Rust. In that case, navigate to
    -the `src/llvm-project` git submodule (you might need to run `./x
    +than what is currently shipped with Rust.
    +In that case, navigate to the `src/llvm-project` git submodule (you might need to run `./x
     check` at least once so the submodule is updated), check out the
     appropriate commit for your fork, then commit that new submodule
     reference in the main Rust repository.
    @@ -31,11 +31,9 @@ git commit -m 'Use my custom LLVM'
     ### Using pre-built LLVM
     
     If you have a local LLVM checkout that is already built, you may be
    -able to configure Rust to treat your build as the system LLVM to avoid
    -redundant builds.
    +able to configure Rust to treat your build as the system LLVM to avoid redundant builds.
     
    -You can tell Rust to use a pre-built version of LLVM using the `target` section
    -of `bootstrap.toml`:
    +You can tell Rust to use a pre-built version of LLVM using the `target` section of `bootstrap.toml`:
     
     ```toml
     [target.x86_64-unknown-linux-gnu]
    @@ -48,8 +46,8 @@ before, though they may be different from your system:
     - `/usr/bin/llvm-config-8`
     - `/usr/lib/llvm-8/bin/llvm-config`
     
    -Note that you need to have the LLVM `FileCheck` tool installed, which is used
    -for codegen tests. This tool is normally built with LLVM, but if you use your
    +Note that you need to have the LLVM `FileCheck` tool installed, which is used for codegen tests.
    +This tool is normally built with LLVM, but if you use your
     own preinstalled LLVM, you will need to provide `FileCheck` in some other way.
     On Debian-based systems, you can install the `llvm-N-tools` package (where `N`
     is the LLVM version number, e.g. `llvm-8-tools`). Alternately, you can specify
    @@ -58,8 +56,8 @@ or you can disable codegen test with the `codegen-tests` item in `bootstrap.toml
     
     ## Creating a target specification
     
    -You should start with a target JSON file. You can see the specification
    -for an existing target using `--print target-spec-json`:
    +You should start with a target JSON file.
    +You can see the specification for an existing target using `--print target-spec-json`:
     
     ```
     rustc -Z unstable-options --target=wasm32-unknown-unknown --print target-spec-json
    @@ -70,20 +68,20 @@ Save that JSON to a file and modify it as appropriate for your target.
     ### Adding a target specification
     
     Once you have filled out a JSON specification and been able to compile
    -somewhat successfully, you can copy the specification into the
    -compiler itself.
    +somewhat successfully, you can copy the specification into the compiler itself.
     
     You will need to add a line to the big table inside of the
    -`supported_targets` macro in the `rustc_target::spec` module. You
    -will then add a corresponding file for your new target containing a
    +`supported_targets` macro in the `rustc_target::spec` module.
    +You will then add a corresponding file for your new target containing a
     `target` function.
     
     Look for existing targets to use as examples.
     
     To use this target in bootstrap, we need to explicitly add the target triple to
    -the `STAGE0_MISSING_TARGETS` list in `src/bootstrap/src/core/sanity.rs`. This
    -is necessary because the default bootstrap compiler (typically a beta compiler)
    -does not recognize the new target we just added. Therefore, it should be added to 
    +the `STAGE0_MISSING_TARGETS` list in `src/bootstrap/src/core/sanity.rs`.
    +This is necessary because the default bootstrap compiler (typically a beta compiler)
    +does not recognize the new target we just added.
    +Therefore, it should be added to
     `STAGE0_MISSING_TARGETS` so that the bootstrap is aware that this target is not
     yet supported by the stage0 compiler.
     
    @@ -96,9 +94,9 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[
     ## Patching crates
     
     You may need to make changes to crates that the compiler depends on,
    -such as [`libc`][] or [`cc`][]. If so, you can use Cargo's
    -[`[patch]`][patch] ability. For example, if you want to use an
    -unreleased version of `libc`, you can add it to the top-level
    +such as [`libc`][] or [`cc`][].
    +If so, you can use Cargo's [`[patch]`][patch] ability.
    +For example, if you want to use an unreleased version of `libc`, you can add it to the top-level
     `Cargo.toml` file:
     
     ```diff
    @@ -118,9 +116,9 @@ index 1e83f05e0ca..4d0172071c1 100644
     After this, run `cargo update -p libc` to update the lockfiles.
     
     Beware that if you patch to a local `path` dependency, this will enable
    -warnings for that dependency. Some dependencies are not warning-free, and due
    -to the `deny-warnings` setting in `bootstrap.toml`, the build may suddenly start
    -to fail.
    +warnings for that dependency.
    +Some dependencies are not warning-free, and due
    +to the `deny-warnings` setting in `bootstrap.toml`, the build may suddenly start to fail.
     To work around warnings, you may want to:
     - Modify the dependency to remove the warnings
     - Or for local development purposes, suppress the warnings by setting deny-warnings = false in bootstrap.toml.
    @@ -137,8 +135,7 @@ deny-warnings = false
     
     ## Cross-compiling
     
    -Once you have a target specification in JSON and in the code, you can
    -cross-compile `rustc`:
    +Once you have a target specification in JSON and in the code, you can cross-compile `rustc`:
     
     ```
     DESTDIR=/path/to/install/in \
    
    From d442a793b23e2d55f6285abaf08ca2f93bd850df Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:13:40 +0200
    Subject: [PATCH 2030/3801] sembr
     src/rustdoc-internals/rustdoc-html-test-suite.md
    
    ---
     .../rustdoc-internals/rustdoc-html-test-suite.md   | 14 ++++++++------
     1 file changed, 8 insertions(+), 6 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-html-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-html-test-suite.md
    index b74405d310eb..a88e60c183b0 100644
    --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-html-test-suite.md
    +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-html-test-suite.md
    @@ -34,8 +34,8 @@ pub type Alias = Option;
     
     Here, we check that documentation generated for crate `file` contains a page for the
     public type alias `Alias` where the code block that is found at the top contains the
    -expected rendering of the item. The `//*[@class="rust item-decl"]//code` is an XPath
    -expression.
    +expected rendering of the item.
    +The `//*[@class="rust item-decl"]//code` is an XPath expression.
     
     Conventionally, you place these directives directly above the thing they are meant to test.
     Technically speaking however, they don't need to be as HtmlDocCk only looks for the directives.
    @@ -120,8 +120,8 @@ pre-recorded subtree or text (the "snapshot") in file `FILE_STEM.NAME.html` wher
     is the file stem of the test file.
     
     Pass the `--bless` option to `compiletest` to accept the current subtree/text as expected.
    -This will overwrite the aforementioned file (or create it if it doesn't exist). It will
    -automatically normalize the channel-dependent URL `https://doc.rust-lang.org/CHANNEL` to
    +This will overwrite the aforementioned file (or create it if it doesn't exist).
    +It will automatically normalize the channel-dependent URL `https://doc.rust-lang.org/CHANNEL` to
     the special string `{{channel}}`.
     
     ### `has-dir`
    @@ -152,7 +152,8 @@ It's *strongly recommended* to read that chapter if you don't know anything abou
     Here are some details that are relevant to this test suite specifically:
     
     * While you can use both `//@ compile-flags` and `//@ doc-flags` to pass flags to `rustdoc`,
    -  prefer to user the latter to show intent. The former is meant for `rustc`.
    +  prefer to user the latter to show intent.
    +  The former is meant for `rustc`.
     * Add `//@ build-aux-docs` to the test file that has auxiliary crates to not only compile the
       auxiliaries with `rustc` but to also document them with `rustdoc`.
     
    @@ -169,7 +170,8 @@ thus continue to test the correct thing or they won't in which case they would f
     forcing the author of the change to look at them.
     
     Compare that to *negative* checks (e.g., `//@ !has PATH XPATH PATTERN`) which won't fail if their
    -XPath expression "no longer" matches. The author who changed "the shape" thus won't get notified and
    +XPath expression "no longer" matches.
    +The author who changed "the shape" thus won't get notified and
     as a result someone else can unintentionally reintroduce `PATTERN` into the generated docs without
     the original negative check failing.
     
    
    From 328942672da88fecfdc04b488307d39ac2b5baf4 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:15:18 +0200
    Subject: [PATCH 2031/3801] sembr src/profiling/with_rustc_perf.md
    
    ---
     .../src/profiling/with_rustc_perf.md          | 22 ++++++++++++-------
     1 file changed, 14 insertions(+), 8 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
    index 7c7639a1ac3d..de4cb9eae930 100644
    --- a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
    +++ b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
    @@ -1,9 +1,11 @@
     # Profiling with rustc-perf
     
     The [Rust benchmark suite][rustc-perf] provides a comprehensive way of profiling and benchmarking
    -the Rust compiler. You can find instructions on how to use the suite in its [manual][rustc-perf-readme].
    +the Rust compiler.
    +You can find instructions on how to use the suite in its [manual][rustc-perf-readme].
     
    -However, using the suite manually can be a bit cumbersome. To make this easier for `rustc` contributors,
    +However, using the suite manually can be a bit cumbersome.
    +To make this easier for `rustc` contributors,
     the compiler build system (`bootstrap`) also provides built-in integration with the benchmarking suite,
     which will download and build the suite for you, build a local compiler toolchain and let you profile it using a simplified command-line interface.
     
    @@ -14,8 +16,9 @@ You can use normal bootstrap flags for this command, such as `--stage 1` or `--s
     `x perf` currently supports the following commands:
     - `benchmark `: Benchmark the compiler and store the results under the passed `id`.
     - `compare  `: Compare the benchmark results of two compilers with the two passed `id`s.
    -- `eprintln`: Just run the compiler and capture its `stderr` output. Note that the compiler normally does not print
    -  anything to `stderr`, you might want to add some `eprintln!` calls to get any output. 
    +- `eprintln`: Just run the compiler and capture its `stderr` output.
    +  Note that the compiler normally does not print
    +  anything to `stderr`, you might want to add some `eprintln!` calls to get any output.
     - `samply`: Profile the compiler using the [samply][samply] sampling profiler.
     - `cachegrind`: Use [Cachegrind][cachegrind] to generate a detailed simulated trace of the compiler's execution.
     
    @@ -29,15 +32,18 @@ You can use the following options for the `x perf` command, which mirror the cor
     - `--scenarios`: Select scenarios (`Full`, `IncrFull`, `IncrPatched`, `IncrUnchanged`) which should be profiled/benchmarked.
     
     ## Example profiling diff for external crates
    -It can be of interest to generate a local diff for two commits of the compiler for external crates. 
    +It can be of interest to generate a local diff for two commits of the compiler for external crates.
     To start, in the `rustc-perf` repo, build the collector, which runs the Rust compiler benchmarks as follows.
     ```
     cargo build --release -p collector
     ```
    -The collector can then be run using cargo, specifying the collector binary. It expects the following arguments:
    -- ``: Profiler selection for how performance should be measured. For this example we will use Cachegrind.
    +The collector can then be run using cargo, specifying the collector binary.
    +It expects the following arguments:
    +- ``: Profiler selection for how performance should be measured.
    +  For this example we will use Cachegrind.
     - ``: The Rust compiler revision to benchmark, specified as a commit SHA from `rust-lang/rust`.
    -Optional arguments allow running profiles and scenarios as described above. More information regarding the mandatory and 
    +Optional arguments allow running profiles and scenarios as described above.
    +More information regarding the mandatory and
     optional arguments can be found in the [rustc-perf-readme-profilers].
     
     Then, for the case of generating a profile diff for the crate `serve_derive-1.0.136`, for two commits `` and `` from the `rust-lang/rust` repository, 
    
    From c451d97ce1401384a7106892e8b4dfdd2768b82a Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:18:18 +0200
    Subject: [PATCH 2032/3801] a more natural continuation
    
    ---
     src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
    index de4cb9eae930..55fc0556463c 100644
    --- a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
    +++ b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
    @@ -18,7 +18,7 @@ You can use normal bootstrap flags for this command, such as `--stage 1` or `--s
     - `compare  `: Compare the benchmark results of two compilers with the two passed `id`s.
     - `eprintln`: Just run the compiler and capture its `stderr` output.
       Note that the compiler normally does not print
    -  anything to `stderr`, you might want to add some `eprintln!` calls to get any output.
    +  anything to `stderr`, so you might want to add some `eprintln!` calls to get any output.
     - `samply`: Profile the compiler using the [samply][samply] sampling profiler.
     - `cachegrind`: Use [Cachegrind][cachegrind] to generate a detailed simulated trace of the compiler's execution.
     
    
    From 2d9616a5d78bc26df42f29c74635edef57fdf743 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:18:33 +0200
    Subject: [PATCH 2033/3801] add missing pause
    
    ---
     src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
    index 55fc0556463c..2158b655b3e2 100644
    --- a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
    +++ b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md
    @@ -40,13 +40,13 @@ cargo build --release -p collector
     The collector can then be run using cargo, specifying the collector binary.
     It expects the following arguments:
     - ``: Profiler selection for how performance should be measured.
    -  For this example we will use Cachegrind.
    +  For this example, we will use Cachegrind.
     - ``: The Rust compiler revision to benchmark, specified as a commit SHA from `rust-lang/rust`.
     Optional arguments allow running profiles and scenarios as described above.
     More information regarding the mandatory and
     optional arguments can be found in the [rustc-perf-readme-profilers].
     
    -Then, for the case of generating a profile diff for the crate `serve_derive-1.0.136`, for two commits `` and `` from the `rust-lang/rust` repository, 
    +Then, for the case of generating a profile diff for the crate `serve_derive-1.0.136`, for two commits `` and `` from the `rust-lang/rust` repository,
     run the following in the `rustc-perf` repo:
     ```
     cargo run --release --bin collector profile_local cachegrind + --rustc2 + --exact-match serde_derive-1.0.136 --profiles Check --scenarios IncrUnchanged
    
    From d89da8044855c064be93f66293bbb97392b5ed65 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:19:30 +0200
    Subject: [PATCH 2034/3801] sembr src/tests/best-practices.md
    
    ---
     .../src/tests/best-practices.md               | 50 +++++++++----------
     1 file changed, 25 insertions(+), 25 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/tests/best-practices.md b/src/doc/rustc-dev-guide/src/tests/best-practices.md
    index ff4ea11bbc7a..3a029763db8c 100644
    --- a/src/doc/rustc-dev-guide/src/tests/best-practices.md
    +++ b/src/doc/rustc-dev-guide/src/tests/best-practices.md
    @@ -7,8 +7,8 @@ a bunch of git archeology.
     
     It's good practice to review the test that you authored by pretending that you
     are a different contributor who is looking at the test that failed several years
    -later without much context (this also helps yourself even a few days or months
    -later!). Then ask yourself: how can I make my life and their lives easier?
    +later without much context (this also helps yourself even a few days or months later!).
    +Then ask yourself: how can I make my life and their lives easier?
     
     To help put this into perspective, let's start with an aside on how to write a
     test that makes the life of another contributor as hard as possible.
    @@ -35,15 +35,14 @@ test that makes the life of another contributor as hard as possible.
     
     Make it easy for the reader to immediately understand what the test is
     exercising, instead of having to type in the issue number and dig through github
    -search for what the test is trying to exercise. This has an additional benefit
    -of making the test possible to be filtered via `--test-args` as a collection of
    -related tests.
    +search for what the test is trying to exercise.
    +This has an additional benefit
    +of making the test possible to be filtered via `--test-args` as a collection of related tests.
     
     - Name the test after what it's trying to exercise or prevent regressions of.
     - Keep it concise.
     - Avoid using issue numbers alone as test names.
    -- Avoid starting the test name with `issue-xxxxx` prefix as it degrades
    -  auto-completion.
    +- Avoid starting the test name with `issue-xxxxx` prefix as it degrades auto-completion.
     
     > **Avoid using only issue numbers as test names**
     >
    @@ -78,21 +77,22 @@ related tests.
     
     ## Test organization
     
    -- For most test suites, try to find a semantically meaningful subdirectory to
    -  home the test.
    +- For most test suites, try to find a semantically meaningful subdirectory to home the test.
         - E.g. for an implementation of RFC 2093 specifically, we can group a
    -      collection of tests under `tests/ui/rfc-2093-infer-outlives/`. For the
    -      directory name, include what the RFC is about.
    +      collection of tests under `tests/ui/rfc-2093-infer-outlives/`.
    +      For the directory name, include what the RFC is about.
     - For the [`run-make`]/`run-make-support` test suites, each `rmake.rs` must
       be contained within an immediate subdirectory under `tests/run-make/` or
    -  `tests/run-make-cargo/` respectively. Further nesting is not presently
    -  supported. Avoid using _only_ an issue number for the test name as well.
    +  `tests/run-make-cargo/` respectively.
    +  Further nesting is not presently supported.
    +  Avoid using _only_ an issue number for the test name as well.
     
     ## Test descriptions
     
     To help other contributors understand what the test is about if their changes
     lead to the test failing, we should make sure a test has sufficient docs about
    -its intent/purpose, links to relevant context (incl. issue numbers or other
    +its intent/purpose, links to relevant context (incl.
    +issue numbers or other
     discussions) and possibly relevant resources (e.g. can be helpful to link to
     Win32 APIs for specific behavior).
     
    @@ -136,8 +136,8 @@ fn main() {
     }
     ```
     
    -For how much context/explanation is needed, it is up to the author and
    -reviewer's discretion. A good rule of thumb is non-trivial things exercised in
    +For how much context/explanation is needed, it is up to the author and reviewer's discretion.
    +A good rule of thumb is non-trivial things exercised in
     the test deserves some explanation to help other contributors to understand.
     This may include remarks on:
     
    @@ -159,17 +159,17 @@ This may include remarks on:
     
     ## Flaky tests
     
    -All tests need to strive to be reproducible and reliable. Flaky tests are the
    -worst kind of tests, arguably even worse than not having the test in the first
    +All tests need to strive to be reproducible and reliable.
    +Flaky tests are the worst kind of tests, arguably even worse than not having the test in the first
     place.
     
     - Flaky tests can fail in completely unrelated PRs which can confuse other
    -  contributors and waste their time trying to figure out if test failure is
    -  related.
    +  contributors and waste their time trying to figure out if test failure is related.
     - Flaky tests provide no useful information from its test results other than
    -  it's flaky and not reliable: if a test passed but it's flakey, did I just get
    -  lucky? if a test is flakey but it failed, was it just spurious?
    -- Flaky tests degrade confidence in the whole test suite. If a test suite can
    +  it's flaky and not reliable: if a test passed but it's flakey, did I just get lucky?
    +  if a test is flakey but it failed, was it just spurious?
    +- Flaky tests degrade confidence in the whole test suite.
    +  If a test suite can
       randomly spuriously fail due to flaky tests, did the whole test suite pass or
       did I just get lucky/unlucky?
     - Flaky tests can randomly fail in full CI, wasting previous full CI resources.
    @@ -189,8 +189,8 @@ See [compiletest directives] for a listing of directives.
     See [LLVM FileCheck guide][FileCheck] for details.
     
     - Avoid matching on specific register numbers or basic block numbers unless
    -  they're special or critical for the test. Consider using patterns to match
    -  them where suitable.
    +  they're special or critical for the test.
    +  Consider using patterns to match them where suitable.
     
     > **TODO**
     >
    
    From 579e2b3009501d33a1636e84f2b8b48c68e9cdd0 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:26:30 +0200
    Subject: [PATCH 2035/3801] some improvements to tests/best-practices.md
    
    ---
     src/doc/rustc-dev-guide/src/tests/best-practices.md | 9 ++++-----
     1 file changed, 4 insertions(+), 5 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/tests/best-practices.md b/src/doc/rustc-dev-guide/src/tests/best-practices.md
    index 3a029763db8c..b6daffa6683c 100644
    --- a/src/doc/rustc-dev-guide/src/tests/best-practices.md
    +++ b/src/doc/rustc-dev-guide/src/tests/best-practices.md
    @@ -91,9 +91,8 @@ of making the test possible to be filtered via `--test-args` as a collection of
     
     To help other contributors understand what the test is about if their changes
     lead to the test failing, we should make sure a test has sufficient docs about
    -its intent/purpose, links to relevant context (incl.
    -issue numbers or other
    -discussions) and possibly relevant resources (e.g. can be helpful to link to
    +its intent/purpose, links to relevant context (including issue numbers or other discussions)
    +and possibly relevant resources (e.g. it can be helpful to link to
     Win32 APIs for specific behavior).
     
     **Synopsis of a test with good comments**
    @@ -146,7 +145,7 @@ This may include remarks on:
       separate because...).
     - Platform-specific behaviors.
     - Behavior of external dependencies and APIs: syscalls, linkers, tools,
    -  environments and the likes.
    +  environments and the like.
     
     ## Test content
     
    @@ -167,7 +166,7 @@ place.
       contributors and waste their time trying to figure out if test failure is related.
     - Flaky tests provide no useful information from its test results other than
       it's flaky and not reliable: if a test passed but it's flakey, did I just get lucky?
    -  if a test is flakey but it failed, was it just spurious?
    +  If a test is flakey but it failed, was it just spurious?
     - Flaky tests degrade confidence in the whole test suite.
       If a test suite can
       randomly spuriously fail due to flaky tests, did the whole test suite pass or
    
    From da5aa2825a5413d9120cef7b9d359bfa1110e2a0 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:26:55 +0200
    Subject: [PATCH 2036/3801] sembr src/tests/perf.md
    
    ---
     src/doc/rustc-dev-guide/src/tests/perf.md | 26 +++++++++++------------
     1 file changed, 13 insertions(+), 13 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/tests/perf.md b/src/doc/rustc-dev-guide/src/tests/perf.md
    index 18762556137e..a0aa3c033174 100644
    --- a/src/doc/rustc-dev-guide/src/tests/perf.md
    +++ b/src/doc/rustc-dev-guide/src/tests/perf.md
    @@ -6,12 +6,13 @@ A lot of work is put into improving the performance of the compiler and
     preventing performance regressions.
     
     The [rustc-perf](https://github.com/rust-lang/rustc-perf) project provides
    -several services for testing and tracking performance. It provides hosted
    -infrastructure for running benchmarks as a service. At this time, only
    -`x86_64-unknown-linux-gnu` builds are tracked.
    +several services for testing and tracking performance.
    +It provides hosted infrastructure for running benchmarks as a service.
    +At this time, only `x86_64-unknown-linux-gnu` builds are tracked.
     
     A "perf run" is used to compare the performance of the compiler in different
    -configurations for a large collection of popular crates. Different
    +configurations for a large collection of popular crates.
    +Different
     configurations include "fresh builds", builds with incremental compilation, etc.
     
     The result of a perf run is a comparison between two versions of the compiler
    @@ -28,8 +29,8 @@ Any changes are noted in a comment on the PR.
     
     ### Manual perf runs
     
    -Additionally, performance tests can be ran before a PR is merged on an as-needed
    -basis. You should request a perf run if your PR may affect performance,
    +Additionally, performance tests can be ran before a PR is merged on an as-needed basis.
    +You should request a perf run if your PR may affect performance,
     especially if it can affect performance adversely.
     
     To evaluate the performance impact of a PR, write this comment on the PR:
    @@ -46,10 +47,10 @@ To evaluate the performance impact of a PR, write this comment on the PR:
     [perf run]: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/perf.20run
     
     This will first tell bors to do a "try" build which do a full release build for
    -`x86_64-unknown-linux-gnu`. After the build finishes, it will place it in the
    -queue to run the performance suite against it. After the performance tests
    -finish, the bot will post a comment on the PR with a summary and a link to a
    -full report.
    +`x86_64-unknown-linux-gnu`.
    +After the build finishes, it will place it in the queue to run the performance suite against it.
    +After the performance tests
    +finish, the bot will post a comment on the PR with a summary and a link to a full report.
     
     If you want to do a perf run for an already built artifact (e.g. for a previous
     try build that wasn't benchmarked yet), you can run this instead:
    @@ -59,8 +60,7 @@ try build that wasn't benchmarked yet), you can run this instead:
     You cannot benchmark the same artifact twice though.
     
     More information about the available perf bot commands can be found
    -[here](https://perf.rust-lang.org/help.html). 
    +[here](https://perf.rust-lang.org/help.html).
     
    -More details about the benchmarking process itself are available in the [perf
    -collector
    +More details about the benchmarking process itself are available in the [perf collector
     documentation](https://github.com/rust-lang/rustc-perf/blob/master/collector/README.md).
    
    From 97a06feab0869c9a57a3a63c840d9e3e6664aea8 Mon Sep 17 00:00:00 2001
    From: Tshepang Mbambo 
    Date: Mon, 12 Jan 2026 22:33:08 +0200
    Subject: [PATCH 2037/3801] add range-diff triagebot option
    
    ---
     src/doc/rustc-dev-guide/triagebot.toml | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/src/doc/rustc-dev-guide/triagebot.toml b/src/doc/rustc-dev-guide/triagebot.toml
    index 974f4cd3dd96..f894456d0de3 100644
    --- a/src/doc/rustc-dev-guide/triagebot.toml
    +++ b/src/doc/rustc-dev-guide/triagebot.toml
    @@ -86,3 +86,6 @@ rustc-dev-guide = [
         "@jyn514",
         "@tshepang",
     ]
    +
    +# Make rebases more easy to read: https://forge.rust-lang.org/triagebot/range-diff.html
    +[range-diff]
    
    From 2d49cfe6aa0f613dbbd35ea3a0542bfe04957a50 Mon Sep 17 00:00:00 2001
    From: Jayan Sunil <73993003+JayanAXHF@users.noreply.github.com>
    Date: Tue, 13 Jan 2026 03:17:32 +0530
    Subject: [PATCH 2038/3801] fix: added missing type in triagebot.toml
    
    ---
     triagebot.toml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/triagebot.toml b/triagebot.toml
    index 89118fdb5948..f00b4b9daffc 100644
    --- a/triagebot.toml
    +++ b/triagebot.toml
    @@ -1006,7 +1006,7 @@ cc = ["@fmease"]
     [mentions."library/core/src/mem/type_info.rs"]
     message = """
     The reflection data structures are tied exactly to the implementation
    -in the compiler. Make sure to also adjust `rustc_const_eval/src/const_eval/type_info.rs
    +in the compiler. Make sure to also adjust `rustc_const_eval/src/const_eval/type_info.rs`
     """
     cc = ["@oli-obk"]
     
    
    From c98b90eaadc1a4ba4fca60572f3ce75f6f44b216 Mon Sep 17 00:00:00 2001
    From: Nicholas Bishop 
    Date: Mon, 12 Jan 2026 17:26:23 -0500
    Subject: [PATCH 2039/3801] std: Change UEFI env vars to volatile storage
    
    The UEFI variables set by the env vars should be volatile, otherwise
    they will persist after reboot and use up scarce non-volatile storage.
    ---
     library/std/src/sys/env/uefi.rs | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/library/std/src/sys/env/uefi.rs b/library/std/src/sys/env/uefi.rs
    index 5fe29a47a2ea..af16a02642a4 100644
    --- a/library/std/src/sys/env/uefi.rs
    +++ b/library/std/src/sys/env/uefi.rs
    @@ -95,8 +95,8 @@ mod uefi_env {
             val_ptr: *mut r_efi::efi::Char16,
         ) -> io::Result<()> {
             let shell = helpers::open_shell().ok_or(unsupported_err())?;
    -        let r =
    -            unsafe { ((*shell.as_ptr()).set_env)(key_ptr, val_ptr, r_efi::efi::Boolean::FALSE) };
    +        let volatile = r_efi::efi::Boolean::TRUE;
    +        let r = unsafe { ((*shell.as_ptr()).set_env)(key_ptr, val_ptr, volatile) };
             if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
         }
     }
    
    From feb44c3f4806069c76b8a06e4393ecb722dd17a1 Mon Sep 17 00:00:00 2001
    From: Urgau 
    Date: Thu, 8 Jan 2026 22:06:45 +0100
    Subject: [PATCH 2040/3801] Make `--print=check-cfg` output compatible
     `--check-cfg` arguments
    
    ---
     compiler/rustc_driver_impl/src/lib.rs         | 35 +++++-----
     .../src/compiler-flags/print-check-cfg.md     | 27 ++++----
     tests/run-make/print-check-cfg/rmake.rs       | 66 ++++++++++---------
     3 files changed, 72 insertions(+), 56 deletions(-)
    
    diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
    index 7820198f2dcf..a328298d3b15 100644
    --- a/compiler/rustc_driver_impl/src/lib.rs
    +++ b/compiler/rustc_driver_impl/src/lib.rs
    @@ -765,30 +765,35 @@ fn print_crate_info(
                     for (name, expected_values) in &sess.psess.check_config.expecteds {
                         use crate::config::ExpectedValues;
                         match expected_values {
    -                        ExpectedValues::Any => check_cfgs.push(format!("{name}=any()")),
    +                        ExpectedValues::Any => {
    +                            check_cfgs.push(format!("cfg({name}, values(any()))"))
    +                        }
                             ExpectedValues::Some(values) => {
    -                            if !values.is_empty() {
    -                                check_cfgs.extend(values.iter().map(|value| {
    +                            let mut values: Vec<_> = values
    +                                .iter()
    +                                .map(|value| {
                                         if let Some(value) = value {
    -                                        format!("{name}=\"{value}\"")
    +                                        format!("\"{value}\"")
                                         } else {
    -                                        name.to_string()
    +                                        "none()".to_string()
                                         }
    -                                }))
    -                            } else {
    -                                check_cfgs.push(format!("{name}="))
    -                            }
    +                                })
    +                                .collect();
    +
    +                            values.sort_unstable();
    +
    +                            let values = values.join(", ");
    +
    +                            check_cfgs.push(format!("cfg({name}, values({values}))"))
                             }
                         }
                     }
     
                     check_cfgs.sort_unstable();
    -                if !sess.psess.check_config.exhaustive_names {
    -                    if !sess.psess.check_config.exhaustive_values {
    -                        println_info!("any()=any()");
    -                    } else {
    -                        println_info!("any()");
    -                    }
    +                if !sess.psess.check_config.exhaustive_names
    +                    && sess.psess.check_config.exhaustive_values
    +                {
    +                    println_info!("cfg(any())");
                     }
                     for check_cfg in check_cfgs {
                         println_info!("{check_cfg}");
    diff --git a/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md b/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md
    index 8d314aa62d4c..1b41a0cd728f 100644
    --- a/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md
    +++ b/src/doc/unstable-book/src/compiler-flags/print-check-cfg.md
    @@ -9,18 +9,20 @@ This option of the `--print` flag print the list of all the expected cfgs.
     This is related to the [`--check-cfg` flag][check-cfg] which allows specifying arbitrary expected
     names and values.
     
    -This print option works similarly to `--print=cfg` (modulo check-cfg specifics).
    +This print option outputs compatible `--check-cfg` arguments with a reduced syntax where all the
    +expected values are on the same line and `values(...)` is always explicit.
     
    -| `--check-cfg`                     | `--print=check-cfg`         |
    -|-----------------------------------|-----------------------------|
    -| `cfg(foo)`                        | `foo`                       |
    -| `cfg(foo, values("bar"))`         | `foo="bar"`                 |
    -| `cfg(foo, values(none(), "bar"))` | `foo` & `foo="bar"`         |
    -|                                   | *check-cfg specific syntax* |
    -| `cfg(foo, values(any())`          | `foo=any()`                 |
    -| `cfg(foo, values())`              | `foo=`                      |
    -| `cfg(any())`                      | `any()`                     |
    -| *none*                            | `any()=any()`               |
    +| `--check-cfg`                     | `--print=check-cfg`               |
    +|-----------------------------------|-----------------------------------|
    +| `cfg(foo)`                        | `cfg(foo, values(none()))         |
    +| `cfg(foo, values("bar"))`         | `cfg(foo, values("bar"))`         |
    +| `cfg(foo, values(none(), "bar"))` | `cfg(foo, values(none(), "bar"))` |
    +| `cfg(foo, values(any())`          | `cfg(foo, values(any())`          |
    +| `cfg(foo, values())`              | `cfg(foo, values())`              |
    +| `cfg(any())`                      | `cfg(any())`                      |
    +| *nothing*                         | *nothing*                         |
    +
    +The print option includes well known cfgs.
     
     To be used like this:
     
    @@ -28,4 +30,7 @@ To be used like this:
     rustc --print=check-cfg -Zunstable-options lib.rs
     ```
     
    +> **Note:** Users should be resilient when parsing, in particular against new predicates that
    +may be added in the future.
    +
     [check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html
    diff --git a/tests/run-make/print-check-cfg/rmake.rs b/tests/run-make/print-check-cfg/rmake.rs
    index f6f7f7cece6e..e102d2904a80 100644
    --- a/tests/run-make/print-check-cfg/rmake.rs
    +++ b/tests/run-make/print-check-cfg/rmake.rs
    @@ -14,51 +14,55 @@ struct CheckCfg {
     
     enum Contains {
         Some { contains: &'static [&'static str], doesnt_contain: &'static [&'static str] },
    -    Only(&'static str),
    +    Nothing,
     }
     
     fn main() {
    -    check(CheckCfg { args: &[], contains: Contains::Only("any()=any()") });
    +    check(CheckCfg { args: &[], contains: Contains::Nothing });
         check(CheckCfg {
             args: &["--check-cfg=cfg()"],
             contains: Contains::Some {
    -            contains: &["unix", "miri"],
    -            doesnt_contain: &["any()", "any()=any()"],
    +            contains: &["cfg(unix, values(none()))", "cfg(miri, values(none()))"],
    +            doesnt_contain: &["cfg(any())"],
             },
         });
         check(CheckCfg {
             args: &["--check-cfg=cfg(any())"],
             contains: Contains::Some {
    -            contains: &["any()", "unix", r#"target_feature="crt-static""#],
    +            contains: &["cfg(any())", "cfg(unix, values(none()))"],
                 doesnt_contain: &["any()=any()"],
             },
         });
         check(CheckCfg {
             args: &["--check-cfg=cfg(feature)"],
             contains: Contains::Some {
    -            contains: &["unix", "miri", "feature"],
    -            doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="],
    +            contains: &[
    +                "cfg(unix, values(none()))",
    +                "cfg(miri, values(none()))",
    +                "cfg(feature, values(none()))",
    +            ],
    +            doesnt_contain: &["cfg(any())", "cfg(feature)"],
             },
         });
         check(CheckCfg {
             args: &[r#"--check-cfg=cfg(feature, values(none(), "", "test", "lol"))"#],
             contains: Contains::Some {
    -            contains: &["feature", "feature=\"\"", "feature=\"test\"", "feature=\"lol\""],
    -            doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="],
    +            contains: &[r#"cfg(feature, values("", "lol", "test", none()))"#],
    +            doesnt_contain: &["cfg(any())", "cfg(feature, values(none()))", "cfg(feature)"],
             },
         });
         check(CheckCfg {
             args: &["--check-cfg=cfg(feature, values())"],
             contains: Contains::Some {
    -            contains: &["feature="],
    -            doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature"],
    +            contains: &["cfg(feature, values())"],
    +            doesnt_contain: &["cfg(any())", "cfg(feature, values(none()))", "cfg(feature)"],
             },
         });
         check(CheckCfg {
             args: &["--check-cfg=cfg(feature, values())", "--check-cfg=cfg(feature, values(none()))"],
             contains: Contains::Some {
    -            contains: &["feature"],
    -            doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="],
    +            contains: &["cfg(feature, values(none()))"],
    +            doesnt_contain: &["cfg(any())", "cfg(feature, values())"],
             },
         });
         check(CheckCfg {
    @@ -67,8 +71,8 @@ fn main() {
                 r#"--check-cfg=cfg(feature, values("tmp"))"#,
             ],
             contains: Contains::Some {
    -            contains: &["unix", "miri", "feature=any()"],
    -            doesnt_contain: &["any()", "any()=any()", "feature", "feature=", "feature=\"tmp\""],
    +            contains: &["cfg(feature, values(any()))"],
    +            doesnt_contain: &["cfg(any())", r#"cfg(feature, values("tmp"))"#],
             },
         });
         check(CheckCfg {
    @@ -78,8 +82,12 @@ fn main() {
                 r#"--check-cfg=cfg(feature, values("tmp"))"#,
             ],
             contains: Contains::Some {
    -            contains: &["has_foo", "has_bar", "feature=\"tmp\""],
    -            doesnt_contain: &["any()", "any()=any()", "feature"],
    +            contains: &[
    +                "cfg(has_foo, values(none()))",
    +                "cfg(has_bar, values(none()))",
    +                r#"cfg(feature, values("tmp"))"#,
    +            ],
    +            doesnt_contain: &["cfg(any())", "cfg(feature)"],
             },
         });
     }
    @@ -94,16 +102,15 @@ fn check(CheckCfg { args, contains }: CheckCfg) {
     
         for l in stdout.lines() {
             assert!(l == l.trim());
    -        if let Some((left, right)) = l.split_once('=') {
    -            if right != "any()" && right != "" {
    -                assert!(right.starts_with("\""));
    -                assert!(right.ends_with("\""));
    -            }
    -            assert!(!left.contains("\""));
    -        } else {
    -            assert!(!l.contains("\""));
    -        }
    -        assert!(found.insert(l.to_string()), "{}", &l);
    +        assert!(l.starts_with("cfg("), "{l}");
    +        assert!(l.ends_with(")"), "{l}");
    +        assert_eq!(
    +            l.chars().filter(|c| *c == '(').count(),
    +            l.chars().filter(|c| *c == ')').count(),
    +            "{l}"
    +        );
    +        assert!(l.chars().filter(|c| *c == '"').count() % 2 == 0, "{l}");
    +        assert!(found.insert(l.to_string()), "{l}");
         }
     
         match contains {
    @@ -131,9 +138,8 @@ fn check(CheckCfg { args, contains }: CheckCfg) {
                     );
                 }
             }
    -        Contains::Only(only) => {
    -            assert!(found.contains(&only.to_string()), "{:?} != {:?}", &only, &found);
    -            assert!(found.len() == 1, "len: {}, instead of 1", found.len());
    +        Contains::Nothing => {
    +            assert!(found.len() == 0, "len: {}, instead of 0", found.len());
             }
         }
     }
    
    From dd2b0a8e9299512a2c8866edf8f67e301aa6d988 Mon Sep 17 00:00:00 2001
    From: Urgau 
    Date: Thu, 8 Jan 2026 22:07:24 +0100
    Subject: [PATCH 2041/3801] Update compiletest for new `--print=check-cfg`
     output
    
    ---
     src/tools/compiletest/src/common.rs | 18 +++++++++++++++++-
     1 file changed, 17 insertions(+), 1 deletion(-)
    
    diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
    index 450fde3bbc38..d2abc9dab148 100644
    --- a/src/tools/compiletest/src/common.rs
    +++ b/src/tools/compiletest/src/common.rs
    @@ -1065,11 +1065,27 @@ fn builtin_cfg_names(config: &Config) -> HashSet {
             Default::default(),
         )
         .lines()
    -    .map(|l| if let Some((name, _)) = l.split_once('=') { name.to_string() } else { l.to_string() })
    +    .map(|l| extract_cfg_name(&l).unwrap().to_string())
         .chain(std::iter::once(String::from("test")))
         .collect()
     }
     
    +/// Extract the cfg name from `cfg(name, values(...))` lines
    +fn extract_cfg_name(check_cfg_line: &str) -> Result<&str, &'static str> {
    +    let trimmed = check_cfg_line.trim();
    +
    +    #[rustfmt::skip]
    +    let inner = trimmed
    +        .strip_prefix("cfg(")
    +        .ok_or("missing cfg(")?
    +        .strip_suffix(")")
    +        .ok_or("missing )")?;
    +
    +    let first_comma = inner.find(',').ok_or("no comma found")?;
    +
    +    Ok(inner[..first_comma].trim())
    +}
    +
     pub const KNOWN_CRATE_TYPES: &[&str] =
         &["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
     
    
    From d697b4d7abf5573d63a9e3e5d7f84479eb554e67 Mon Sep 17 00:00:00 2001
    From: KaiTomotake 
    Date: Mon, 5 Jan 2026 01:32:34 +0900
    Subject: [PATCH 2042/3801] Improve std::path::Path::join documentation
    
    Adapt `PathBuf::push` documentation for `Path::join` and add it to `join`'s docs
    
    Fix to comply with tidy
    
    Remove unnecessary whitespace
    ---
     library/std/src/path.rs | 9 +++++++++
     1 file changed, 9 insertions(+)
    
    diff --git a/library/std/src/path.rs b/library/std/src/path.rs
    index e8eda3c5f76b..25bd7005b994 100644
    --- a/library/std/src/path.rs
    +++ b/library/std/src/path.rs
    @@ -2972,6 +2972,15 @@ impl Path {
         ///
         /// If `path` is absolute, it replaces the current path.
         ///
    +    /// On Windows:
    +    ///
    +    /// * if `path` has a root but no prefix (e.g., `\windows`), it
    +    ///   replaces and returns everything except for the prefix (if any) of `self`.
    +    /// * if `path` has a prefix but no root, `self` is ignored and `path` is returned.
    +    /// * if `self` has a verbatim prefix (e.g. `\\?\C:\windows`)
    +    ///   and `path` is not empty, the new path is normalized: all references
    +    ///   to `.` and `..` are removed.
    +    ///
         /// See [`PathBuf::push`] for more details on what it means to adjoin a path.
         ///
         /// # Examples
    
    From afe76df79cd43d510cc7e746e7402edf8f8eed58 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Heath=20Dutton=F0=9F=95=B4=EF=B8=8F?=
     
    Date: Mon, 12 Jan 2026 18:04:32 -0500
    Subject: [PATCH 2043/3801] Don't suggest replacing closure parameter with type
     name
    
    When a closure has an inferred parameter type like `|ch|` and the
    expected type differs in borrowing (e.g., `char` vs `&char`), the
    suggestion code would incorrectly suggest `|char|` instead of the
    valid `|ch: char|`.
    
    This happened because the code couldn't walk explicit `&` references
    in the HIR when the type is inferred, and fell back to replacing the
    entire parameter span with the expected type name.
    
    Fix by only emitting the suggestion when we can properly identify the
    `&` syntax to remove.
    ---
     .../src/error_reporting/traits/suggestions.rs            | 9 +++------
     tests/ui/closures/multiple-fn-bounds.stderr              | 5 -----
     2 files changed, 3 insertions(+), 11 deletions(-)
    
    diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
    index 511e9e85b5f6..81b921b3744f 100644
    --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
    +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
    @@ -5323,12 +5323,9 @@ fn hint_missing_borrow<'tcx>(
                         ty = mut_ty.ty;
                         left -= 1;
                     }
    -                let sugg = if left == 0 {
    -                    (span, String::new())
    -                } else {
    -                    (arg.span, expected_arg.to_string())
    -                };
    -                remove_borrow.push(sugg);
    +                if left == 0 {
    +                    remove_borrow.push((span, String::new()));
    +                }
                 }
             }
         }
    diff --git a/tests/ui/closures/multiple-fn-bounds.stderr b/tests/ui/closures/multiple-fn-bounds.stderr
    index 9b824fa0eefb..c99cbac01faf 100644
    --- a/tests/ui/closures/multiple-fn-bounds.stderr
    +++ b/tests/ui/closures/multiple-fn-bounds.stderr
    @@ -19,11 +19,6 @@ note: required by a bound in `foo`
        |
     LL | fn foo bool + Fn(char) -> bool>(f: F) {
        |                               ^^^^^^^^^^^^^^^^ required by this bound in `foo`
    -help: consider adjusting the signature so it does not borrow its argument
    -   |
    -LL -     foo(move |x| v);
    -LL +     foo(move |char| v);
    -   |
     
     error: aborting due to 1 previous error
     
    
    From 3777ebc6ca156092e47318a20c9c2ae40d9813e2 Mon Sep 17 00:00:00 2001
    From: Moulins 
    Date: Thu, 18 Dec 2025 19:23:37 +0100
    Subject: [PATCH 2044/3801] Don't expose redundant information in
     `rustc_public`'s `LayoutShape`
    
    Enum variant layouts don't need to store a full `LayoutShape`; just storing
    the fields offsets is enough and all other information can be inferred from
    the parent layout:
    - size, align and ABI don't make much sense for individual variants and
      should generally be taken from the parent layout instead;
    - variants always have `fields: FieldsShape::Arbitrary { .. }` and
      `variant: VariantShape::Single { .. }`.
    ---
     compiler/rustc_public/src/abi.rs              | 19 ++++++++++++++++++-
     .../src/unstable/convert/stable/abi.rs        | 12 ++++++++++--
     2 files changed, 28 insertions(+), 3 deletions(-)
    
    diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs
    index aced39059f6b..413bc835e50a 100644
    --- a/compiler/rustc_public/src/abi.rs
    +++ b/compiler/rustc_public/src/abi.rs
    @@ -188,10 +188,27 @@ pub enum VariantsShape {
             tag: Scalar,
             tag_encoding: TagEncoding,
             tag_field: usize,
    -        variants: Vec,
    +        variants: Vec,
         },
     }
     
    +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
    +pub struct VariantFields {
    +    /// Offsets for the first byte of each field,
    +    /// ordered to match the source definition order.
    +    /// I.e.: It follows the same order as [super::ty::VariantDef::fields()].
    +    /// This vector does not go in increasing order.
    +    pub offsets: Vec,
    +}
    +
    +impl VariantFields {
    +    pub fn fields_by_offset_order(&self) -> Vec {
    +        let mut indices = (0..self.offsets.len()).collect::>();
    +        indices.sort_by_key(|idx| self.offsets[*idx]);
    +        indices
    +    }
    +}
    +
     #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
     pub enum TagEncoding {
         /// The tag directly stores the discriminant, but possibly with a smaller layout
    diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs
    index 03328d084ee9..f6b750f75aea 100644
    --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs
    +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs
    @@ -11,7 +11,7 @@ use rustc_target::callconv;
     use crate::abi::{
         AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength,
         IntegerType, Layout, LayoutShape, PassMode, Primitive, ReprFlags, ReprOptions, Scalar,
    -    TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange,
    +    TagEncoding, TyAndLayout, ValueAbi, VariantFields, VariantsShape, WrappingRange,
     };
     use crate::compiler_interface::BridgeTys;
     use crate::target::MachineSize as Size;
    @@ -212,7 +212,15 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants VariantFields {
    +                                offsets: offsets.iter().as_slice().stable(tables, cx),
    +                            },
    +                            _ => panic!("variant layout should be Arbitrary"),
    +                        })
    +                        .collect(),
                     }
                 }
             }
    
    From cafe91749f491d8d4c10893f1dfa6298951dc9e8 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
    Date: Mon, 12 Jan 2026 22:38:32 +0000
    Subject: [PATCH 2045/3801] On unmet trait bound, mention if trait is unstable
    
    ---
     .../error_reporting/traits/fulfillment_errors.rs |  2 +-
     .../src/error_reporting/traits/suggestions.rs    |  9 ++++++++-
     tests/ui/abi/issues/issue-22565-rust-call.stderr |  4 ++--
     tests/ui/async-await/coroutine-not-future.stderr |  6 +++---
     tests/ui/async-await/issue-61076.rs              |  4 ++--
     tests/ui/async-await/issue-61076.stderr          |  4 ++--
     tests/ui/async-await/issue-84841.stderr          |  2 +-
     tests/ui/async-await/try-in-sync.stderr          |  2 +-
     .../adt_const_params/const_param_ty_bad.stderr   | 12 ++++++------
     .../const_param_ty_bad_empty_array.stderr        |  2 +-
     ...st_param_ty_generic_bounds_do_not_hold.stderr |  6 +++---
     .../const_param_ty_impl_no_structural_eq.stderr  |  4 ++--
     tests/ui/coroutine/gen_block_is_coro.stderr      |  6 +++---
     tests/ui/error-codes/E0059.stderr                |  4 ++--
     tests/ui/extern/extern-types-unsized.stderr      |  4 ++--
     tests/ui/extern/unsized-extern-derefmove.stderr  |  6 +++---
     .../feature-gate-sized-hierarchy.stderr          |  2 +-
     .../rust-call-abi-not-a-tuple-ice-81974.stderr   | 16 ++++++++--------
     .../ui/mir/validate/validate-unsize-cast.stderr  |  2 +-
     .../overloaded/overloaded-calls-nontuple.stderr  | 12 ++++++------
     .../deref-patterns/recursion-limit.stderr        |  2 +-
     .../deref-patterns/unsatisfied-bounds.stderr     |  2 +-
     tests/ui/proc-macro/quote/not-quotable.stderr    |  2 +-
     tests/ui/range/range-1.stderr                    |  2 +-
     .../disallowed-positions.e2021.stderr            |  6 +++---
     .../disallowed-positions.e2024.stderr            |  6 +++---
     tests/ui/sized-hierarchy/default-bound.stderr    |  2 +-
     tests/ui/sized-hierarchy/impls.stderr            | 10 +++++-----
     .../sized-hierarchy/pretty-print-opaque.stderr   |  6 +++---
     tests/ui/specialization/issue-44861.stderr       |  2 +-
     tests/ui/suggestions/fn-trait-notation.stderr    |  4 ++--
     tests/ui/suggestions/issue-72766.stderr          |  2 +-
     tests/ui/suggestions/issue-97704.stderr          |  2 +-
     .../unstable-trait-suggestion.stderr             |  4 ++--
     tests/ui/traits/issue-71036.rs                   |  2 +-
     tests/ui/traits/issue-71036.stderr               |  2 +-
     .../ui/traits/next-solver/coroutine.fail.stderr  |  2 +-
     .../higher-ranked-upcasting-ub.next.stderr       |  2 +-
     .../unsize-goal-escaping-bounds.current.stderr   |  2 +-
     tests/ui/transmutability/assoc-bound.stderr      |  2 +-
     .../dont-assume-err-is-yes-issue-126377.stderr   |  2 +-
     .../transmutability/references/unsafecell.stderr |  8 ++++----
     .../try-block-bad-type-heterogeneous.stderr      |  4 ++--
     tests/ui/try-block/try-block-bad-type.stderr     |  4 ++--
     tests/ui/try-block/try-block-in-while.stderr     |  2 +-
     tests/ui/try-trait/try-operator-on-main.stderr   |  6 +++---
     tests/ui/tuple/builtin-fail.stderr               |  8 ++++----
     tests/ui/type/pattern_types/nested.stderr        | 14 +++++++-------
     tests/ui/typeck/issue-57404.stderr               |  2 +-
     .../non-tupled-arg-mismatch.stderr               |  2 +-
     50 files changed, 116 insertions(+), 109 deletions(-)
    
    diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
    index 8762607edf5d..00d06779e652 100644
    --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
    +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
    @@ -681,7 +681,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         // Ambiguous predicates should never error
                         | ty::PredicateKind::Ambiguous
                         // We never return Err when proving UnstableFeature goal.
    -                    | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature{ .. })
    +                    | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature { .. })
                         | ty::PredicateKind::NormalizesTo { .. }
                         | ty::PredicateKind::AliasRelate { .. }
                         | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => {
    diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
    index 511e9e85b5f6..c9e07175773b 100644
    --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
    +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
    @@ -5515,7 +5515,14 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>(
             };
             if let ty::PredicatePolarity::Positive = trait_predicate.polarity() {
                 format!(
    -                "{pre_message}the trait `{}` is not implemented for{desc} `{}`",
    +                "{pre_message}the {}trait `{}` is not implemented for{desc} `{}`",
    +                if tcx.lookup_stability(trait_predicate.def_id()).map(|s| s.level.is_stable())
    +                    == Some(false)
    +                {
    +                    "nightly-only, unstable "
    +                } else {
    +                    ""
    +                },
                     trait_predicate.print_modifiers_and_trait_path(),
                     tcx.short_string(trait_predicate.self_ty().skip_binder(), long_ty_path),
                 )
    diff --git a/tests/ui/abi/issues/issue-22565-rust-call.stderr b/tests/ui/abi/issues/issue-22565-rust-call.stderr
    index 3e296bdaea41..90fa210fa2fa 100644
    --- a/tests/ui/abi/issues/issue-22565-rust-call.stderr
    +++ b/tests/ui/abi/issues/issue-22565-rust-call.stderr
    @@ -2,7 +2,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
       --> $DIR/issue-22565-rust-call.rs:3:1
        |
     LL | extern "rust-call" fn b(_i: i32) {}
    -   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `i32`
    +   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
     
     error: functions with the "rust-call" ABI must take a single non-self tuple argument
       --> $DIR/issue-22565-rust-call.rs:17:5
    @@ -32,7 +32,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
       --> $DIR/issue-22565-rust-call.rs:27:7
        |
     LL |     b(10);
    -   |       ^^ the trait `std::marker::Tuple` is not implemented for `i32`
    +   |       ^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
     
     error: functions with the "rust-call" ABI must take a single non-self tuple argument
       --> $DIR/issue-22565-rust-call.rs:29:5
    diff --git a/tests/ui/async-await/coroutine-not-future.stderr b/tests/ui/async-await/coroutine-not-future.stderr
    index b0f371f6706d..b55faf39ce69 100644
    --- a/tests/ui/async-await/coroutine-not-future.stderr
    +++ b/tests/ui/async-await/coroutine-not-future.stderr
    @@ -2,7 +2,7 @@ error[E0277]: the trait bound `impl Future: Coroutine<_>` is not sa
       --> $DIR/coroutine-not-future.rs:36:21
        |
     LL |     takes_coroutine(async_fn());
    -   |     --------------- ^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future`
    +   |     --------------- ^^^^^^^^^^ the nightly-only, unstable trait `Coroutine<_>` is not implemented for `impl Future`
        |     |
        |     required by a bound introduced by this call
        |
    @@ -16,7 +16,7 @@ error[E0277]: the trait bound `impl Future: Coroutine<_>` is not sa
       --> $DIR/coroutine-not-future.rs:38:21
        |
     LL |     takes_coroutine(returns_async_block());
    -   |     --------------- ^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future`
    +   |     --------------- ^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Coroutine<_>` is not implemented for `impl Future`
        |     |
        |     required by a bound introduced by this call
        |
    @@ -30,7 +30,7 @@ error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:40:21:
       --> $DIR/coroutine-not-future.rs:40:21
        |
     LL |     takes_coroutine(async {});
    -   |     --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:40:21: 40:26}`
    +   |     --------------- ^^^^^^^^ the nightly-only, unstable trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:40:21: 40:26}`
        |     |
        |     required by a bound introduced by this call
        |
    diff --git a/tests/ui/async-await/issue-61076.rs b/tests/ui/async-await/issue-61076.rs
    index 0a679a95970a..6fe7846ea8d9 100644
    --- a/tests/ui/async-await/issue-61076.rs
    +++ b/tests/ui/async-await/issue-61076.rs
    @@ -4,7 +4,7 @@ use core::future::Future;
     use core::pin::Pin;
     use core::task::{Context, Poll};
     
    -struct T; //~ HELP the trait `Try` is not implemented for `T`
    +struct T; //~ HELP the nightly-only, unstable trait `Try` is not implemented for `T`
     
     struct Tuple(i32);
     
    @@ -41,7 +41,7 @@ async fn foo() -> Result<(), ()> {
     async fn bar() -> Result<(), ()> {
         foo()?; //~ ERROR the `?` operator can only be applied to values that implement `Try`
         //~^ NOTE the `?` operator cannot be applied to type `impl Future>`
    -    //~| HELP the trait `Try` is not implemented for `impl Future>`
    +    //~| HELP the nightly-only, unstable trait `Try` is not implemented for `impl Future>`
         //~| HELP consider `await`ing on the `Future`
         //~| NOTE in this expansion of desugaring of operator `?`
         //~| NOTE in this expansion of desugaring of operator `?`
    diff --git a/tests/ui/async-await/issue-61076.stderr b/tests/ui/async-await/issue-61076.stderr
    index 7d46abe4a66b..dd49d00246cd 100644
    --- a/tests/ui/async-await/issue-61076.stderr
    +++ b/tests/ui/async-await/issue-61076.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |     foo()?;
        |     ^^^^^^ the `?` operator cannot be applied to type `impl Future>`
        |
    -   = help: the trait `Try` is not implemented for `impl Future>`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future>`
     help: consider `await`ing on the `Future`
        |
     LL |     foo().await?;
    @@ -16,7 +16,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |     t?;
        |     ^^ the `?` operator cannot be applied to type `T`
        |
    -help: the trait `Try` is not implemented for `T`
    +help: the nightly-only, unstable trait `Try` is not implemented for `T`
       --> $DIR/issue-61076.rs:7:1
        |
     LL | struct T;
    diff --git a/tests/ui/async-await/issue-84841.stderr b/tests/ui/async-await/issue-84841.stderr
    index 0d008477310a..6c714ce7828c 100644
    --- a/tests/ui/async-await/issue-84841.stderr
    +++ b/tests/ui/async-await/issue-84841.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |     test()?;
        |     ^^^^^^^ the `?` operator cannot be applied to type `impl Future`
        |
    -   = help: the trait `Try` is not implemented for `impl Future`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future`
     
     error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
       --> $DIR/issue-84841.rs:9:11
    diff --git a/tests/ui/async-await/try-in-sync.stderr b/tests/ui/async-await/try-in-sync.stderr
    index bc7a6bd01512..0957339a4dc5 100644
    --- a/tests/ui/async-await/try-in-sync.stderr
    +++ b/tests/ui/async-await/try-in-sync.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |     foo()?;
        |     ^^^^^^ the `?` operator cannot be applied to type `impl Future>`
        |
    -   = help: the trait `Try` is not implemented for `impl Future>`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future>`
     note: this implements `Future` and its output type supports `?`, but the future cannot be awaited in a synchronous function
       --> $DIR/try-in-sync.rs:6:10
        |
    diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr
    index 5109dccd96a1..be63c9e5c046 100644
    --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr
    +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr
    @@ -2,7 +2,7 @@ error[E0277]: `fn() {main}` can't be used as a const parameter type
       --> $DIR/const_param_ty_bad.rs:7:11
        |
     LL |     check(main);
    -   |     ----- ^^^^ the trait `ConstParamTy_` is not implemented for fn item `fn() {main}`
    +   |     ----- ^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for fn item `fn() {main}`
        |     |
        |     required by a bound introduced by this call
        |
    @@ -24,7 +24,7 @@ LL |     check(|| {});
        |     |
        |     required by a bound introduced by this call
        |
    -   = help: the trait `ConstParamTy_` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}`
    +   = help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}`
     note: required by a bound in `check`
       --> $DIR/const_param_ty_bad.rs:4:18
        |
    @@ -40,7 +40,7 @@ error[E0277]: `fn()` can't be used as a const parameter type
       --> $DIR/const_param_ty_bad.rs:9:11
        |
     LL |     check(main as fn());
    -   |     ----- ^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `fn()`
    +   |     ----- ^^^^^^^^^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for `fn()`
        |     |
        |     required by a bound introduced by this call
        |
    @@ -58,7 +58,7 @@ error[E0277]: `&mut ()` can't be used as a const parameter type
       --> $DIR/const_param_ty_bad.rs:10:11
        |
     LL |     check(&mut ());
    -   |     ----- ^^^^^^^ the trait `ConstParamTy_` is not implemented for `&mut ()`
    +   |     ----- ^^^^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for `&mut ()`
        |     |
        |     required by a bound introduced by this call
        |
    @@ -78,7 +78,7 @@ error[E0277]: `*mut ()` can't be used as a const parameter type
       --> $DIR/const_param_ty_bad.rs:11:11
        |
     LL |     check(&mut () as *mut ());
    -   |     ----- ^^^^^^^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `*mut ()`
    +   |     ----- ^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for `*mut ()`
        |     |
        |     required by a bound introduced by this call
        |
    @@ -98,7 +98,7 @@ error[E0277]: `*const ()` can't be used as a const parameter type
       --> $DIR/const_param_ty_bad.rs:12:11
        |
     LL |     check(&() as *const ());
    -   |     ----- ^^^^^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `*const ()`
    +   |     ----- ^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for `*const ()`
        |     |
        |     required by a bound introduced by this call
        |
    diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr
    index 373ac9435daf..460b7420e8c0 100644
    --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr
    +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr
    @@ -4,7 +4,7 @@ error[E0277]: `NotParam` can't be used as a const parameter type
     LL |     check::<[NotParam; 0]>();
        |             ^^^^^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `ConstParamTy_` is not implemented for `NotParam`
    +help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for `NotParam`
       --> $DIR/const_param_ty_bad_empty_array.rs:5:1
        |
     LL | struct NotParam;
    diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr
    index ca2aa3adcb7a..fd1162fe08e3 100644
    --- a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr
    +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr
    @@ -4,7 +4,7 @@ error[E0277]: `NotParam` can't be used as a const parameter type
     LL |     check::<&NotParam>();
        |             ^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `ConstParamTy_` is not implemented for `NotParam`
    +help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for `NotParam`
       --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1
        |
     LL | struct NotParam;
    @@ -22,7 +22,7 @@ error[E0277]: `NotParam` can't be used as a const parameter type
     LL |     check::<[NotParam]>();
        |             ^^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `ConstParamTy_` is not implemented for `NotParam`
    +help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for `NotParam`
       --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1
        |
     LL | struct NotParam;
    @@ -40,7 +40,7 @@ error[E0277]: `NotParam` can't be used as a const parameter type
     LL |     check::<[NotParam; 17]>();
        |             ^^^^^^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `ConstParamTy_` is not implemented for `NotParam`
    +help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for `NotParam`
       --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1
        |
     LL | struct NotParam;
    diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
    index c6b791ed9674..ca2a693d48ce 100644
    --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
    +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
    @@ -18,7 +18,7 @@ error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]`
     LL | impl std::marker::ConstParamTy_ for CantParam {}
        |                                     ^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `StructuralPartialEq` is not implemented for `CantParam`
    +help: the nightly-only, unstable trait `StructuralPartialEq` is not implemented for `CantParam`
       --> $DIR/const_param_ty_impl_no_structural_eq.rs:8:1
        |
     LL | struct CantParam(ImplementsConstParamTy);
    @@ -46,7 +46,7 @@ error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]`
     LL | #[derive(std::marker::ConstParamTy)]
        |          ^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `StructuralPartialEq` is not implemented for `CantParamDerive`
    +help: the nightly-only, unstable trait `StructuralPartialEq` is not implemented for `CantParamDerive`
       --> $DIR/const_param_ty_impl_no_structural_eq.rs:17:1
        |
     LL | struct CantParamDerive(ImplementsConstParamTy);
    diff --git a/tests/ui/coroutine/gen_block_is_coro.stderr b/tests/ui/coroutine/gen_block_is_coro.stderr
    index 444f0eca1d54..fac09f600059 100644
    --- a/tests/ui/coroutine/gen_block_is_coro.stderr
    +++ b/tests/ui/coroutine/gen_block_is_coro.stderr
    @@ -2,7 +2,7 @@ error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}: C
       --> $DIR/gen_block_is_coro.rs:7:13
        |
     LL | fn foo() -> impl Coroutine {
    -   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}`
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}`
     LL |     gen { yield 42 }
        |     ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}` here
     
    @@ -10,7 +10,7 @@ error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}:
       --> $DIR/gen_block_is_coro.rs:11:13
        |
     LL | fn bar() -> impl Coroutine {
    -   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}`
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}`
     LL |     gen { yield 42 }
        |     ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}` here
     
    @@ -18,7 +18,7 @@ error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}:
       --> $DIR/gen_block_is_coro.rs:15:13
        |
     LL | fn baz() -> impl Coroutine {
    -   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}`
    +   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}`
     LL |     gen { yield 42 }
        |     ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}` here
     
    diff --git a/tests/ui/error-codes/E0059.stderr b/tests/ui/error-codes/E0059.stderr
    index 698ee0a2a902..43191db8be10 100644
    --- a/tests/ui/error-codes/E0059.stderr
    +++ b/tests/ui/error-codes/E0059.stderr
    @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `Fn` trait must be a tuple
       --> $DIR/E0059.rs:3:11
        |
     LL | fn foo>(f: F) -> F::Output { f(3) }
    -   |           ^^^^^^^ the trait `std::marker::Tuple` is not implemented for `i32`
    +   |           ^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
        |
     note: required by a bound in `Fn`
       --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    @@ -11,7 +11,7 @@ error[E0277]: `i32` is not a tuple
       --> $DIR/E0059.rs:3:41
        |
     LL | fn foo>(f: F) -> F::Output { f(3) }
    -   |                                         ^^^^ the trait `std::marker::Tuple` is not implemented for `i32`
    +   |                                         ^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
     
     error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit
       --> $DIR/E0059.rs:3:41
    diff --git a/tests/ui/extern/extern-types-unsized.stderr b/tests/ui/extern/extern-types-unsized.stderr
    index 43dd9800d6d3..9953e5686632 100644
    --- a/tests/ui/extern/extern-types-unsized.stderr
    +++ b/tests/ui/extern/extern-types-unsized.stderr
    @@ -65,7 +65,7 @@ error[E0277]: the size for values of type `A` cannot be known
     LL |     assert_sized::>();
        |                    ^^^^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `A`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `A`
     note: required by a bound in `Bar`
       --> $DIR/extern-types-unsized.rs:14:12
        |
    @@ -100,7 +100,7 @@ error[E0277]: the size for values of type `A` cannot be known
     LL |     assert_sized::>>();
        |                    ^^^^^^^^^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `A`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `A`
     note: required by a bound in `Bar`
       --> $DIR/extern-types-unsized.rs:14:12
        |
    diff --git a/tests/ui/extern/unsized-extern-derefmove.stderr b/tests/ui/extern/unsized-extern-derefmove.stderr
    index a9efc2e66e3b..7eb9c6800dc6 100644
    --- a/tests/ui/extern/unsized-extern-derefmove.stderr
    +++ b/tests/ui/extern/unsized-extern-derefmove.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the size for values of type `Device` cannot be known
     LL | unsafe fn make_device() -> Box {
        |                            ^^^^^^^^^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `Device`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `Device`
     note: required by a bound in `Box`
       --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
     
    @@ -32,7 +32,7 @@ error[E0277]: the size for values of type `Device` cannot be known
     LL |     Box::from_raw(0 as *mut _)
        |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `Device`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `Device`
     note: required by a bound in `Box`
       --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
     
    @@ -55,7 +55,7 @@ error[E0277]: the size for values of type `Device` cannot be known
     LL |     let d: Device = unsafe { *make_device() };
        |                               ^^^^^^^^^^^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `Device`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `Device`
     note: required by a bound in `Box`
       --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
     
    diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr
    index 6a35fcfb0e8e..8e97c73c7d21 100644
    --- a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr
    +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr
    @@ -17,7 +17,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known
     LL |     needs_metasized::();
        |                       ^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `main::Foo`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo`
     note: required by a bound in `needs_metasized`
       --> $DIR/feature-gate-sized-hierarchy.rs:7:23
        |
    diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr
    index e7cb82687fa7..6d7f46fae805 100644
    --- a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr
    +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr
    @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
       --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5
        |
     LL |     extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
    -   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A`
    +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A`
        |
     note: required by a bound in `FnOnce`
       --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    @@ -15,7 +15,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
       --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:24:12
        |
     LL | impl FnOnce for CachedFun
    -   |            ^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A`
    +   |            ^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A`
        |
     note: required by a bound in `FnOnce`
       --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    @@ -28,7 +28,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
       --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5
        |
     LL |     extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
    -   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A`
    +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A`
        |
     note: required by a bound in `FnOnce`
       --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    @@ -41,7 +41,7 @@ error[E0059]: type parameter to bare `FnMut` trait must be a tuple
       --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:39:12
        |
     LL | impl FnMut for CachedFun
    -   |            ^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A`
    +   |            ^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A`
        |
     note: required by a bound in `FnMut`
       --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    @@ -54,7 +54,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
       --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5
        |
     LL |     extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
    -   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A`
    +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A`
        |
     help: consider further restricting type parameter `A` with unstable trait `Tuple`
        |
    @@ -65,7 +65,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
       --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5
        |
     LL |     extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
    -   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `A`
    +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A`
        |
     help: consider further restricting type parameter `A` with unstable trait `Tuple`
        |
    @@ -76,7 +76,7 @@ error[E0277]: `A` is not a tuple
       --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:34:19
        |
     LL |     self.call_mut(a)
    -   |          -------- ^ the trait `std::marker::Tuple` is not implemented for `A`
    +   |          -------- ^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A`
        |          |
        |          required by a bound introduced by this call
        |
    @@ -91,7 +91,7 @@ error[E0277]: `i32` is not a tuple
       --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:59:26
        |
     LL |     cachedcoso.call_once(1);
    -   |                --------- ^ the trait `std::marker::Tuple` is not implemented for `i32`
    +   |                --------- ^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
        |                |
        |                required by a bound introduced by this call
        |
    diff --git a/tests/ui/mir/validate/validate-unsize-cast.stderr b/tests/ui/mir/validate/validate-unsize-cast.stderr
    index 8449c6a24bd3..66dd5716826f 100644
    --- a/tests/ui/mir/validate/validate-unsize-cast.stderr
    +++ b/tests/ui/mir/validate/validate-unsize-cast.stderr
    @@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: Unsize` is not satisfied
       --> $DIR/validate-unsize-cast.rs:10:42
        |
     LL | impl CastTo for T {}
    -   |                                          ^ the trait `Unsize` is not implemented for `T`
    +   |                                          ^ the nightly-only, unstable trait `Unsize` is not implemented for `T`
        |
        = note: all implementations of `Unsize` are provided automatically by the compiler, see  for more information
     note: required by a bound in `CastTo`
    diff --git a/tests/ui/overloaded/overloaded-calls-nontuple.stderr b/tests/ui/overloaded/overloaded-calls-nontuple.stderr
    index 54a9d1f09b52..b898288c3e4b 100644
    --- a/tests/ui/overloaded/overloaded-calls-nontuple.stderr
    +++ b/tests/ui/overloaded/overloaded-calls-nontuple.stderr
    @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `FnMut` trait must be a tuple
       --> $DIR/overloaded-calls-nontuple.rs:10:6
        |
     LL | impl FnMut for S {
    -   |      ^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `isize`
    +   |      ^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize`
        |
     note: required by a bound in `FnMut`
       --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    @@ -11,7 +11,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
       --> $DIR/overloaded-calls-nontuple.rs:18:6
        |
     LL | impl FnOnce for S {
    -   |      ^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `isize`
    +   |      ^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize`
        |
     note: required by a bound in `FnOnce`
       --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    @@ -20,19 +20,19 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
       --> $DIR/overloaded-calls-nontuple.rs:12:5
        |
     LL |     extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
    -   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `isize`
    +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize`
     
     error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
       --> $DIR/overloaded-calls-nontuple.rs:21:5
        |
     LL |     extern "rust-call" fn call_once(mut self, z: isize) -> isize {
    -   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `isize`
    +   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize`
     
     error[E0277]: `isize` is not a tuple
       --> $DIR/overloaded-calls-nontuple.rs:23:23
        |
     LL |         self.call_mut(z)
    -   |              -------- ^ the trait `std::marker::Tuple` is not implemented for `isize`
    +   |              -------- ^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize`
        |              |
        |              required by a bound introduced by this call
        |
    @@ -53,7 +53,7 @@ error[E0277]: `isize` is not a tuple
       --> $DIR/overloaded-calls-nontuple.rs:29:10
        |
     LL |     drop(s(3))
    -   |          ^^^^ the trait `std::marker::Tuple` is not implemented for `isize`
    +   |          ^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize`
     
     error: aborting due to 7 previous errors
     
    diff --git a/tests/ui/pattern/deref-patterns/recursion-limit.stderr b/tests/ui/pattern/deref-patterns/recursion-limit.stderr
    index f6aa92b23adb..7c140e4493e7 100644
    --- a/tests/ui/pattern/deref-patterns/recursion-limit.stderr
    +++ b/tests/ui/pattern/deref-patterns/recursion-limit.stderr
    @@ -12,7 +12,7 @@ error[E0277]: the trait bound `Cyclic: DerefPure` is not satisfied
     LL |         () => {}
        |         ^^ unsatisfied trait bound
        |
    -help: the trait `DerefPure` is not implemented for `Cyclic`
    +help: the nightly-only, unstable trait `DerefPure` is not implemented for `Cyclic`
       --> $DIR/recursion-limit.rs:8:1
        |
     LL | struct Cyclic;
    diff --git a/tests/ui/pattern/deref-patterns/unsatisfied-bounds.stderr b/tests/ui/pattern/deref-patterns/unsatisfied-bounds.stderr
    index 0b1e8ef49780..3ee6efefe697 100644
    --- a/tests/ui/pattern/deref-patterns/unsatisfied-bounds.stderr
    +++ b/tests/ui/pattern/deref-patterns/unsatisfied-bounds.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the trait bound `MyPointer: DerefPure` is not satisfied
     LL |         () => {}
        |         ^^ unsatisfied trait bound
        |
    -help: the trait `DerefPure` is not implemented for `MyPointer`
    +help: the nightly-only, unstable trait `DerefPure` is not implemented for `MyPointer`
       --> $DIR/unsatisfied-bounds.rs:4:1
        |
     LL | struct MyPointer;
    diff --git a/tests/ui/proc-macro/quote/not-quotable.stderr b/tests/ui/proc-macro/quote/not-quotable.stderr
    index 62a02638e548..b00d029946d6 100644
    --- a/tests/ui/proc-macro/quote/not-quotable.stderr
    +++ b/tests/ui/proc-macro/quote/not-quotable.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied
     LL |     let _ = quote! { $ip };
        |             ^^^^^^^^^^^^^^
        |             |
    -   |             the trait `ToTokens` is not implemented for `Ipv4Addr`
    +   |             the nightly-only, unstable trait `ToTokens` is not implemented for `Ipv4Addr`
        |             required by a bound introduced by this call
        |
        = help: the following other types implement trait `ToTokens`:
    diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr
    index 8878ba143097..f2d603b32af0 100644
    --- a/tests/ui/range/range-1.stderr
    +++ b/tests/ui/range/range-1.stderr
    @@ -8,7 +8,7 @@ error[E0277]: the trait bound `bool: Step` is not satisfied
       --> $DIR/range-1.rs:9:14
        |
     LL |     for i in false..true {}
    -   |              ^^^^^^^^^^^ the trait `Step` is not implemented for `bool`
    +   |              ^^^^^^^^^^^ the nightly-only, unstable trait `Step` is not implemented for `bool`
        |
        = note: required for `std::ops::Range` to implement `Iterator`
        = note: required for `std::ops::Range` to implement `IntoIterator`
    diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2021.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2021.stderr
    index 15e7be8c65f2..40a32880f407 100644
    --- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2021.stderr
    +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2021.stderr
    @@ -1137,7 +1137,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |         if let 0 = 0? {}
        |                    ^^ the `?` operator cannot be applied to type `{integer}`
        |
    -   = help: the trait `Try` is not implemented for `{integer}`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}`
     
     error[E0308]: mismatched types
       --> $DIR/disallowed-positions.rs:224:11
    @@ -1198,7 +1198,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |         while let 0 = 0? {}
        |                       ^^ the `?` operator cannot be applied to type `{integer}`
        |
    -   = help: the trait `Try` is not implemented for `{integer}`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}`
     
     error[E0308]: mismatched types
       --> $DIR/disallowed-positions.rs:333:10
    @@ -1217,7 +1217,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |         let 0 = 0?;
        |                 ^^ the `?` operator cannot be applied to type `{integer}`
        |
    -   = help: the trait `Try` is not implemented for `{integer}`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}`
     
     error: aborting due to 134 previous errors
     
    diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2024.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2024.stderr
    index 20af65cf89a2..21167cf63d17 100644
    --- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2024.stderr
    +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2024.stderr
    @@ -1083,7 +1083,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |         if let 0 = 0? {}
        |                    ^^ the `?` operator cannot be applied to type `{integer}`
        |
    -   = help: the trait `Try` is not implemented for `{integer}`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}`
     
     error[E0308]: mismatched types
       --> $DIR/disallowed-positions.rs:224:11
    @@ -1144,7 +1144,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |         while let 0 = 0? {}
        |                       ^^ the `?` operator cannot be applied to type `{integer}`
        |
    -   = help: the trait `Try` is not implemented for `{integer}`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}`
     
     error[E0308]: mismatched types
       --> $DIR/disallowed-positions.rs:333:10
    @@ -1163,7 +1163,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |         let 0 = 0?;
        |                 ^^ the `?` operator cannot be applied to type `{integer}`
        |
    -   = help: the trait `Try` is not implemented for `{integer}`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}`
     
     error: aborting due to 125 previous errors
     
    diff --git a/tests/ui/sized-hierarchy/default-bound.stderr b/tests/ui/sized-hierarchy/default-bound.stderr
    index 0a4ea6f44d8e..9929e2dba524 100644
    --- a/tests/ui/sized-hierarchy/default-bound.stderr
    +++ b/tests/ui/sized-hierarchy/default-bound.stderr
    @@ -76,7 +76,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known
     LL |     metasized::();
        |                 ^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `main::Foo`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo`
     note: required by a bound in `metasized`
       --> $DIR/default-bound.rs:14:17
        |
    diff --git a/tests/ui/sized-hierarchy/impls.stderr b/tests/ui/sized-hierarchy/impls.stderr
    index ca70822aad28..25c6c933149f 100644
    --- a/tests/ui/sized-hierarchy/impls.stderr
    +++ b/tests/ui/sized-hierarchy/impls.stderr
    @@ -164,7 +164,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known
     LL |     needs_metasized::();
        |                       ^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `main::Foo`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo`
     note: required by a bound in `needs_metasized`
       --> $DIR/impls.rs:16:23
        |
    @@ -222,7 +222,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known
     LL |     needs_metasized::<(Foo, Foo)>();
        |                       ^^^^^^^^^^ doesn't have a known size
        |
    -   = help: within `(main::Foo, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo`
    +   = help: within `(main::Foo, main::Foo)`, the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo`
        = note: required because it appears within the type `(main::Foo, main::Foo)`
     note: required by a bound in `needs_metasized`
       --> $DIR/impls.rs:16:23
    @@ -273,7 +273,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known
     LL |     needs_metasized::<(u32, Foo)>();
        |                       ^^^^^^^^^^ doesn't have a known size
        |
    -   = help: within `(u32, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo`
    +   = help: within `(u32, main::Foo)`, the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo`
        = note: required because it appears within the type `(u32, main::Foo)`
     note: required by a bound in `needs_metasized`
       --> $DIR/impls.rs:16:23
    @@ -323,7 +323,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known
     LL |     needs_metasized::();
        |                       ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
        |
    -   = help: within `StructAllFieldsUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
    +   = help: within `StructAllFieldsUnsized`, the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo`
     note: required because it appears within the type `StructAllFieldsUnsized`
       --> $DIR/impls.rs:243:12
        |
    @@ -377,7 +377,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known
     LL |     needs_metasized::();
        |                       ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
        |
    -   = help: within `StructLastFieldUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
    +   = help: within `StructLastFieldUnsized`, the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo`
     note: required because it appears within the type `StructLastFieldUnsized`
       --> $DIR/impls.rs:259:12
        |
    diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr
    index ecf4d912be8f..9f9289d0f391 100644
    --- a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr
    +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be kno
     LL | pub fn pointeesized() -> Box {
        |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
     note: required by a bound in `Box`
       --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
     
    @@ -32,7 +32,7 @@ error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be kno
     LL |         let x = pointeesized();
        |                 ^^^^^^^^^^^^^^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
     note: required by a bound in `Box`
       --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
     
    @@ -51,7 +51,7 @@ error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be kno
     LL |         let y: Box = x;
        |                              ^ doesn't have a known size
        |
    -   = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
    +   = help: the nightly-only, unstable trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
        = note: required for the cast from `Box` to `Box`
     
     error: aborting due to 6 previous errors
    diff --git a/tests/ui/specialization/issue-44861.stderr b/tests/ui/specialization/issue-44861.stderr
    index d184c4468b68..e480f65333fd 100644
    --- a/tests/ui/specialization/issue-44861.stderr
    +++ b/tests/ui/specialization/issue-44861.stderr
    @@ -2,7 +2,7 @@ error[E0277]: the trait bound `(): CoerceUnsized<*const [u8]>` is not satisfied
       --> $DIR/issue-44861.rs:21:26
        |
     LL |     default type Data2 = ();
    -   |                          ^^ the trait `CoerceUnsized<*const [u8]>` is not implemented for `()`
    +   |                          ^^ the nightly-only, unstable trait `CoerceUnsized<*const [u8]>` is not implemented for `()`
        |
     note: required by a bound in `Smartass::Data2`
       --> $DIR/issue-44861.rs:12:17
    diff --git a/tests/ui/suggestions/fn-trait-notation.stderr b/tests/ui/suggestions/fn-trait-notation.stderr
    index 9d0845478527..ef7d5fe36282 100644
    --- a/tests/ui/suggestions/fn-trait-notation.stderr
    +++ b/tests/ui/suggestions/fn-trait-notation.stderr
    @@ -32,7 +32,7 @@ error[E0059]: type parameter to bare `Fn` trait must be a tuple
       --> $DIR/fn-trait-notation.rs:4:8
        |
     LL |     F: Fn,
    -   |        ^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `i32`
    +   |        ^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
        |
     note: required by a bound in `Fn`
       --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    @@ -47,7 +47,7 @@ error[E0277]: `i32` is not a tuple
       --> $DIR/fn-trait-notation.rs:9:5
        |
     LL |     f(3);
    -   |     ^^^^ the trait `std::marker::Tuple` is not implemented for `i32`
    +   |     ^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
     
     error[E0308]: mismatched types
       --> $DIR/fn-trait-notation.rs:17:5
    diff --git a/tests/ui/suggestions/issue-72766.stderr b/tests/ui/suggestions/issue-72766.stderr
    index f0680dfe19f7..03aad995b966 100644
    --- a/tests/ui/suggestions/issue-72766.stderr
    +++ b/tests/ui/suggestions/issue-72766.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |     SadGirl {}.call()?;
        |     ^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `impl Future>`
        |
    -   = help: the trait `Try` is not implemented for `impl Future>`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future>`
     help: consider `await`ing on the `Future`
        |
     LL |     SadGirl {}.call().await?;
    diff --git a/tests/ui/suggestions/issue-97704.stderr b/tests/ui/suggestions/issue-97704.stderr
    index a7284db1d956..e20c68057eb7 100644
    --- a/tests/ui/suggestions/issue-97704.stderr
    +++ b/tests/ui/suggestions/issue-97704.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |     func(async { Ok::<_, i32>(()) })?;
        |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `impl Future>`
        |
    -   = help: the trait `Try` is not implemented for `impl Future>`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future>`
     help: consider `await`ing on the `Future`
        |
     LL |     func(async { Ok::<_, i32>(()) }).await?;
    diff --git a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    index dfa47f2ab468..6df61e7bd1de 100644
    --- a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    +++ b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    @@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: Unstable` is not satisfied
       --> $DIR/unstable-trait-suggestion.rs:13:9
        |
     LL |     foo(t)
    -   |     --- ^ the trait `Unstable` is not implemented for `T`
    +   |     --- ^ the nightly-only, unstable trait `Unstable` is not implemented for `T`
        |     |
        |     required by a bound introduced by this call
        |
    @@ -20,7 +20,7 @@ error[E0277]: the trait bound `T: Step` is not satisfied
       --> $DIR/unstable-trait-suggestion.rs:17:14
        |
     LL |     for _ in t {}
    -   |              ^ the trait `Step` is not implemented for `T`
    +   |              ^ the nightly-only, unstable trait `Step` is not implemented for `T`
        |
        = note: required for `std::ops::Range` to implement `Iterator`
        = note: required for `std::ops::Range` to implement `IntoIterator`
    diff --git a/tests/ui/traits/issue-71036.rs b/tests/ui/traits/issue-71036.rs
    index 69eed0c0462f..9593503240b2 100644
    --- a/tests/ui/traits/issue-71036.rs
    +++ b/tests/ui/traits/issue-71036.rs
    @@ -10,7 +10,7 @@ struct Foo<'a, T: ?Sized> {
     
     impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn> for Foo<'a, T> {}
     //~^ ERROR the trait bound `&'a T: Unsize<&'a U>` is not satisfied
    -//~| NOTE the trait `Unsize<&'a U>` is not implemented for `&'a T`
    +//~| NOTE the nightly-only, unstable trait `Unsize<&'a U>` is not implemented for `&'a T`
     //~| NOTE all implementations of `Unsize` are provided automatically by the compiler
     //~| NOTE required for
     
    diff --git a/tests/ui/traits/issue-71036.stderr b/tests/ui/traits/issue-71036.stderr
    index 2452731f19f1..d2d88584f104 100644
    --- a/tests/ui/traits/issue-71036.stderr
    +++ b/tests/ui/traits/issue-71036.stderr
    @@ -2,7 +2,7 @@ error[E0277]: the trait bound `&'a T: Unsize<&'a U>` is not satisfied
       --> $DIR/issue-71036.rs:11:1
        |
     LL | impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn> for Foo<'a, T> {}
    -   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unsize<&'a U>` is not implemented for `&'a T`
    +   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Unsize<&'a U>` is not implemented for `&'a T`
        |
        = note: all implementations of `Unsize` are provided automatically by the compiler, see  for more information
        = note: required for `&'a &'a T` to implement `DispatchFromDyn<&'a &'a U>`
    diff --git a/tests/ui/traits/next-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr
    index 8c263e8644bd..a289e9839b23 100644
    --- a/tests/ui/traits/next-solver/coroutine.fail.stderr
    +++ b/tests/ui/traits/next-solver/coroutine.fail.stderr
    @@ -8,7 +8,7 @@ LL | /         || {
     LL | |
     LL | |             yield ();
     LL | |         },
    -   | |_________^ the trait `Coroutine` is not implemented for `{coroutine@$DIR/coroutine.rs:20:9: 20:11}`
    +   | |_________^ the nightly-only, unstable trait `Coroutine` is not implemented for `{coroutine@$DIR/coroutine.rs:20:9: 20:11}`
        |
     note: required by a bound in `needs_coroutine`
       --> $DIR/coroutine.rs:14:28
    diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr
    index 392680aa5064..1087fac50fd0 100644
    --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr
    +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr
    @@ -2,7 +2,7 @@ error[E0277]: the trait bound `&dyn for<'a> Subtrait<'a, 'a>: CoerceUnsized<&dyn
       --> $DIR/higher-ranked-upcasting-ub.rs:22:5
        |
     LL |     x
    -   |     ^ the trait `Unsize Supertrait<'a, 'b>>` is not implemented for `dyn for<'a> Subtrait<'a, 'a>`
    +   |     ^ the nightly-only, unstable trait `Unsize Supertrait<'a, 'b>>` is not implemented for `dyn for<'a> Subtrait<'a, 'a>`
        |
        = note: all implementations of `Unsize` are provided automatically by the compiler, see  for more information
        = note: required for `&dyn for<'a> Subtrait<'a, 'a>` to implement `CoerceUnsized<&dyn for<'a, 'b> Supertrait<'a, 'b>>`
    diff --git a/tests/ui/traits/unsize-goal-escaping-bounds.current.stderr b/tests/ui/traits/unsize-goal-escaping-bounds.current.stderr
    index e63a0bf50b7a..d2d679243ee7 100644
    --- a/tests/ui/traits/unsize-goal-escaping-bounds.current.stderr
    +++ b/tests/ui/traits/unsize-goal-escaping-bounds.current.stderr
    @@ -2,7 +2,7 @@ error[E0277]: the trait bound `for<'a> (): Unsize<(dyn Trait + 'a)>` is not sati
       --> $DIR/unsize-goal-escaping-bounds.rs:20:5
        |
     LL |     foo();
    -   |     ^^^^^ the trait `for<'a> Unsize<(dyn Trait + 'a)>` is not implemented for `()`
    +   |     ^^^^^ the nightly-only, unstable trait `for<'a> Unsize<(dyn Trait + 'a)>` is not implemented for `()`
        |
        = note: all implementations of `Unsize` are provided automatically by the compiler, see  for more information
     note: required by a bound in `foo`
    diff --git a/tests/ui/transmutability/assoc-bound.stderr b/tests/ui/transmutability/assoc-bound.stderr
    index 4dff24e2002a..66a81f353815 100644
    --- a/tests/ui/transmutability/assoc-bound.stderr
    +++ b/tests/ui/transmutability/assoc-bound.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the trait bound `::AssocA: TransmuteFrom<(), Assume { alig
     LL |     type AssocB = T::AssocA;
        |                   ^^^^^^^^^ unsatisfied trait bound
        |
    -   = help: the trait `TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `::AssocA`
    +   = help: the nightly-only, unstable trait `TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `::AssocA`
     note: required by a bound in `B::AssocB`
       --> $DIR/assoc-bound.rs:9:18
        |
    diff --git a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr
    index 6cb6a85c78a6..6f7e9e1bfa33 100644
    --- a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr
    +++ b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr
    @@ -17,7 +17,7 @@ error[E0277]: the trait bound `(): TransmuteFrom<(), { Assume::SAFETY }>` is not
       --> $DIR/dont-assume-err-is-yes-issue-126377.rs:14:23
        |
     LL |     is_transmutable::<{}>();
    -   |                       ^^ the trait `TransmuteFrom<(), { Assume::SAFETY }>` is not implemented for `()`
    +   |                       ^^ the nightly-only, unstable trait `TransmuteFrom<(), { Assume::SAFETY }>` is not implemented for `()`
        |
     note: required by a bound in `is_transmutable`
       --> $DIR/dont-assume-err-is-yes-issue-126377.rs:9:9
    diff --git a/tests/ui/transmutability/references/unsafecell.stderr b/tests/ui/transmutability/references/unsafecell.stderr
    index 02a0935e84ea..85d6724b03fa 100644
    --- a/tests/ui/transmutability/references/unsafecell.stderr
    +++ b/tests/ui/transmutability/references/unsafecell.stderr
    @@ -2,7 +2,7 @@ error[E0277]: `&u8` cannot be safely transmuted into `&UnsafeCell`
       --> $DIR/unsafecell.rs:27:50
        |
     LL |     assert::is_maybe_transmutable::<&'static u8, &'static UnsafeCell>();
    -   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell`
    +   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Freeze` is not implemented for `UnsafeCell`
        |
     note: required by a bound in `is_maybe_transmutable`
       --> $DIR/unsafecell.rs:12:14
    @@ -17,7 +17,7 @@ error[E0277]: `&UnsafeCell` cannot be safely transmuted into `&UnsafeCell $DIR/unsafecell.rs:29:62
        |
     LL |     assert::is_maybe_transmutable::<&'static UnsafeCell, &'static UnsafeCell>();
    -   |                                                              ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell`
    +   |                                                              ^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Freeze` is not implemented for `UnsafeCell`
        |
     note: required by a bound in `is_maybe_transmutable`
       --> $DIR/unsafecell.rs:12:14
    @@ -32,7 +32,7 @@ error[E0277]: `&mut bool` cannot be safely transmuted into `&UnsafeCell`
       --> $DIR/unsafecell.rs:45:56
        |
     LL |     assert::is_maybe_transmutable::<&'static mut bool, &'static UnsafeCell>();
    -   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell`
    +   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Freeze` is not implemented for `UnsafeCell`
        |
     note: required by a bound in `is_maybe_transmutable`
       --> $DIR/unsafecell.rs:12:14
    @@ -47,7 +47,7 @@ error[E0277]: `&mut UnsafeCell` cannot be safely transmuted into `&UnsafeC
       --> $DIR/unsafecell.rs:46:68
        |
     LL |     assert::is_maybe_transmutable::<&'static mut UnsafeCell, &'static UnsafeCell>();
    -   |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell`
    +   |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Freeze` is not implemented for `UnsafeCell`
        |
     note: required by a bound in `is_maybe_transmutable`
       --> $DIR/unsafecell.rs:12:14
    diff --git a/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr b/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr
    index 7c7cedd392e6..4962534cf294 100644
    --- a/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr
    +++ b/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr
    @@ -30,7 +30,7 @@ error[E0277]: a `try` block must return `Result` or `Option` (or another type th
     LL |     let res = try bikeshed () { };
        |                                 ^ could not wrap the final value of the block as `()` doesn't implement `Try`
        |
    -   = help: the trait `Try` is not implemented for `()`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `()`
     
     error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`)
       --> $DIR/try-block-bad-type-heterogeneous.rs:20:34
    @@ -38,7 +38,7 @@ error[E0277]: a `try` block must return `Result` or `Option` (or another type th
     LL |     let res = try bikeshed i32 { 5 };
        |                                  ^ could not wrap the final value of the block as `i32` doesn't implement `Try`
        |
    -   = help: the trait `Try` is not implemented for `i32`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `i32`
     
     error: aborting due to 5 previous errors
     
    diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr
    index 9df01a4cf5b1..6f806da088b6 100644
    --- a/tests/ui/try-block/try-block-bad-type.stderr
    +++ b/tests/ui/try-block/try-block-bad-type.stderr
    @@ -29,7 +29,7 @@ error[E0277]: a `try` block must return `Result` or `Option` (or another type th
     LL |     let res: () = try { };
        |                         ^ could not wrap the final value of the block as `()` doesn't implement `Try`
        |
    -   = help: the trait `Try` is not implemented for `()`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `()`
     
     error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`)
       --> $DIR/try-block-bad-type.rs:20:26
    @@ -37,7 +37,7 @@ error[E0277]: a `try` block must return `Result` or `Option` (or another type th
     LL |     let res: i32 = try { 5 };
        |                          ^ could not wrap the final value of the block as `i32` doesn't implement `Try`
        |
    -   = help: the trait `Try` is not implemented for `i32`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `i32`
     
     error: aborting due to 5 previous errors
     
    diff --git a/tests/ui/try-block/try-block-in-while.stderr b/tests/ui/try-block/try-block-in-while.stderr
    index 2760e930102b..6d6917362bc7 100644
    --- a/tests/ui/try-block/try-block-in-while.stderr
    +++ b/tests/ui/try-block/try-block-in-while.stderr
    @@ -4,7 +4,7 @@ error[E0277]: a `try` block must return `Result` or `Option` (or another type th
     LL |     while try { false } {}
        |                 ^^^^^ could not wrap the final value of the block as `bool` doesn't implement `Try`
        |
    -   = help: the trait `Try` is not implemented for `bool`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `bool`
     
     error: aborting due to 1 previous error
     
    diff --git a/tests/ui/try-trait/try-operator-on-main.stderr b/tests/ui/try-trait/try-operator-on-main.stderr
    index 9c2526442ab5..d58720638aec 100644
    --- a/tests/ui/try-trait/try-operator-on-main.stderr
    +++ b/tests/ui/try-trait/try-operator-on-main.stderr
    @@ -22,7 +22,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |     ()?;
        |     ^^^ the `?` operator cannot be applied to type `()`
        |
    -   = help: the trait `Try` is not implemented for `()`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `()`
     
     error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
       --> $DIR/try-operator-on-main.rs:10:7
    @@ -37,7 +37,7 @@ error[E0277]: the trait bound `(): Try` is not satisfied
       --> $DIR/try-operator-on-main.rs:14:25
        |
     LL |     try_trait_generic::<()>();
    -   |                         ^^ the trait `Try` is not implemented for `()`
    +   |                         ^^ the nightly-only, unstable trait `Try` is not implemented for `()`
        |
     note: required by a bound in `try_trait_generic`
       --> $DIR/try-operator-on-main.rs:17:25
    @@ -51,7 +51,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
     LL |     ()?;
        |     ^^^ the `?` operator cannot be applied to type `()`
        |
    -   = help: the trait `Try` is not implemented for `()`
    +   = help: the nightly-only, unstable trait `Try` is not implemented for `()`
     
     error: aborting due to 5 previous errors
     
    diff --git a/tests/ui/tuple/builtin-fail.stderr b/tests/ui/tuple/builtin-fail.stderr
    index 0dec88ded7ce..5e84dbff454d 100644
    --- a/tests/ui/tuple/builtin-fail.stderr
    +++ b/tests/ui/tuple/builtin-fail.stderr
    @@ -2,7 +2,7 @@ error[E0277]: `T` is not a tuple
       --> $DIR/builtin-fail.rs:8:23
        |
     LL |     assert_is_tuple::();
    -   |                       ^ the trait `std::marker::Tuple` is not implemented for `T`
    +   |                       ^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `T`
        |
     note: required by a bound in `assert_is_tuple`
       --> $DIR/builtin-fail.rs:3:23
    @@ -18,7 +18,7 @@ error[E0277]: `i32` is not a tuple
       --> $DIR/builtin-fail.rs:13:23
        |
     LL |     assert_is_tuple::();
    -   |                       ^^^ the trait `std::marker::Tuple` is not implemented for `i32`
    +   |                       ^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
        |
     note: required by a bound in `assert_is_tuple`
       --> $DIR/builtin-fail.rs:3:23
    @@ -30,7 +30,7 @@ error[E0277]: `i32` is not a tuple
       --> $DIR/builtin-fail.rs:15:24
        |
     LL |     assert_is_tuple::<(i32)>();
    -   |                        ^^^ the trait `std::marker::Tuple` is not implemented for `i32`
    +   |                        ^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
        |
     note: required by a bound in `assert_is_tuple`
       --> $DIR/builtin-fail.rs:3:23
    @@ -44,7 +44,7 @@ error[E0277]: `TupleStruct` is not a tuple
     LL |     assert_is_tuple::();
        |                       ^^^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `std::marker::Tuple` is not implemented for `TupleStruct`
    +help: the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `TupleStruct`
       --> $DIR/builtin-fail.rs:5:1
        |
     LL | struct TupleStruct(i32, i32);
    diff --git a/tests/ui/type/pattern_types/nested.stderr b/tests/ui/type/pattern_types/nested.stderr
    index bb206d9db3db..7893cc849248 100644
    --- a/tests/ui/type/pattern_types/nested.stderr
    +++ b/tests/ui/type/pattern_types/nested.stderr
    @@ -13,7 +13,7 @@ error[E0277]: `(u32) is 1..` is not a valid base type for range patterns
     LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
        |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported
        |
    -   = help: the trait `core::pat::RangePattern` is not implemented for `(u32) is 1..`
    +   = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `(u32) is 1..`
        = help: the following other types implement trait `core::pat::RangePattern`:
                  char
                  i128
    @@ -31,7 +31,7 @@ error[E0277]: `(i32) is 1..` is not a valid base type for range patterns
     LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
        |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported
        |
    -   = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..`
    +   = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `(i32) is 1..`
        = help: the following other types implement trait `core::pat::RangePattern`:
                  char
                  i128
    @@ -55,7 +55,7 @@ error[E0277]: `(i32) is 1..` is not a valid base type for range patterns
     LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
        |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported
        |
    -   = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..`
    +   = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `(i32) is 1..`
        = help: the following other types implement trait `core::pat::RangePattern`:
                  char
                  i128
    @@ -92,7 +92,7 @@ error[E0277]: `(i32) is 1..` is not a valid base type for range patterns
     LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
        |                                                                  ^ only integer types and `char` are supported
        |
    -   = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..`
    +   = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `(i32) is 1..`
        = help: the following other types implement trait `core::pat::RangePattern`:
                  char
                  i128
    @@ -110,7 +110,7 @@ error[E0277]: `()` is not a valid base type for range patterns
     LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
        |                                   ^^ only integer types and `char` are supported
        |
    -   = help: the trait `core::pat::RangePattern` is not implemented for `()`
    +   = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `()`
        = help: the following other types implement trait `core::pat::RangePattern`:
                  char
                  i128
    @@ -145,7 +145,7 @@ error[E0277]: `()` is not a valid base type for range patterns
     LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
        |                                           ^ only integer types and `char` are supported
        |
    -   = help: the trait `core::pat::RangePattern` is not implemented for `()`
    +   = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `()`
        = help: the following other types implement trait `core::pat::RangePattern`:
                  char
                  i128
    @@ -163,7 +163,7 @@ error[E0277]: `f32` is not a valid base type for range patterns
     LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
        |                                                 ^^^ only integer types and `char` are supported
        |
    -   = help: the trait `core::pat::RangePattern` is not implemented for `f32`
    +   = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `f32`
        = help: the following other types implement trait `core::pat::RangePattern`:
                  i128
                  i16
    diff --git a/tests/ui/typeck/issue-57404.stderr b/tests/ui/typeck/issue-57404.stderr
    index f1d28e475a07..7f8a99ebb917 100644
    --- a/tests/ui/typeck/issue-57404.stderr
    +++ b/tests/ui/typeck/issue-57404.stderr
    @@ -2,7 +2,7 @@ error[E0277]: `&mut ()` is not a tuple
       --> $DIR/issue-57404.rs:6:41
        |
     LL |     handlers.unwrap().as_mut().call_mut(&mut ());
    -   |                                -------- ^^^^^^^ the trait `std::marker::Tuple` is not implemented for `&mut ()`
    +   |                                -------- ^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `&mut ()`
        |                                |
        |                                required by a bound introduced by this call
        |
    diff --git a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
    index 621a533dd1c5..488dff646793 100644
    --- a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
    +++ b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
    @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `Fn` trait must be a tuple
       --> $DIR/non-tupled-arg-mismatch.rs:3:9
        |
     LL | fn a>(f: F) {}
    -   |         ^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `usize`
    +   |         ^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `usize`
        |
     note: required by a bound in `Fn`
       --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    
    From 89713fcef5b36e92db77bfea40378252607edf67 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
    Date: Mon, 12 Jan 2026 23:05:08 +0000
    Subject: [PATCH 2046/3801] Mention `Range` when `Step` trait bound is unmet
    
    ---
     library/core/src/iter/range.rs                         | 5 +++++
     tests/ui/range/range-1.stderr                          | 1 +
     tests/ui/trait-bounds/unstable-trait-suggestion.stderr | 1 +
     3 files changed, 7 insertions(+)
    
    diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
    index 9e43d5688cec..39e218a5f4b3 100644
    --- a/library/core/src/iter/range.rs
    +++ b/library/core/src/iter/range.rs
    @@ -21,6 +21,11 @@ unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u6
     /// The *successor* operation moves towards values that compare greater.
     /// The *predecessor* operation moves towards values that compare lesser.
     #[rustc_diagnostic_item = "range_step"]
    +#[rustc_on_unimplemented(
    +    note = "`Range` only implements `Iterator` for select types in the standard library, \
    +            particularly integers; to see the full list of types, see the documentation for the \
    +            unstable `Step` trait"
    +)]
     #[unstable(feature = "step_trait", issue = "42168")]
     pub trait Step: Clone + PartialOrd + Sized {
         /// Returns the bounds on the number of *successor* steps required to get from `start` to `end`
    diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr
    index f2d603b32af0..a5001a70eae6 100644
    --- a/tests/ui/range/range-1.stderr
    +++ b/tests/ui/range/range-1.stderr
    @@ -10,6 +10,7 @@ error[E0277]: the trait bound `bool: Step` is not satisfied
     LL |     for i in false..true {}
        |              ^^^^^^^^^^^ the nightly-only, unstable trait `Step` is not implemented for `bool`
        |
    +   = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait
        = note: required for `std::ops::Range` to implement `Iterator`
        = note: required for `std::ops::Range` to implement `IntoIterator`
     
    diff --git a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    index 6df61e7bd1de..5820074b41cc 100644
    --- a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    +++ b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    @@ -22,6 +22,7 @@ error[E0277]: the trait bound `T: Step` is not satisfied
     LL |     for _ in t {}
        |              ^ the nightly-only, unstable trait `Step` is not implemented for `T`
        |
    +   = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait
        = note: required for `std::ops::Range` to implement `Iterator`
        = note: required for `std::ops::Range` to implement `IntoIterator`
     help: consider restricting type parameter `T` with unstable trait `Step`
    
    From 45edce26d36b4d05e350c7b75419159e7f750e5e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
    Date: Tue, 13 Jan 2026 01:28:28 +0000
    Subject: [PATCH 2047/3801] Update rustc_on_unimplemented message for `Step`
    
    ---
     library/core/src/iter/range.rs                         | 1 +
     tests/ui/range/range-1.rs                              | 2 +-
     tests/ui/range/range-1.stderr                          | 2 +-
     tests/ui/trait-bounds/unstable-trait-suggestion.stderr | 2 +-
     4 files changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
    index 39e218a5f4b3..0be1e8699bf5 100644
    --- a/library/core/src/iter/range.rs
    +++ b/library/core/src/iter/range.rs
    @@ -22,6 +22,7 @@ unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u6
     /// The *predecessor* operation moves towards values that compare lesser.
     #[rustc_diagnostic_item = "range_step"]
     #[rustc_on_unimplemented(
    +    message = "`std::ops::Range<{Self}>` is not an iterator",
         note = "`Range` only implements `Iterator` for select types in the standard library, \
                 particularly integers; to see the full list of types, see the documentation for the \
                 unstable `Step` trait"
    diff --git a/tests/ui/range/range-1.rs b/tests/ui/range/range-1.rs
    index 192426fe228f..8fbfae55b8a6 100644
    --- a/tests/ui/range/range-1.rs
    +++ b/tests/ui/range/range-1.rs
    @@ -7,7 +7,7 @@ pub fn main() {
     
         // Bool => does not implement iterator.
         for i in false..true {}
    -    //~^ ERROR `bool: Step` is not satisfied
    +    //~^ ERROR `std::ops::Range` is not an iterator
     
         // Unsized type.
         let arr: &[_] = &[1, 2, 3];
    diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr
    index a5001a70eae6..5491d06aee09 100644
    --- a/tests/ui/range/range-1.stderr
    +++ b/tests/ui/range/range-1.stderr
    @@ -4,7 +4,7 @@ error[E0308]: mismatched types
     LL |     let _ = 0u32..10i32;
        |                   ^^^^^ expected `u32`, found `i32`
     
    -error[E0277]: the trait bound `bool: Step` is not satisfied
    +error[E0277]: `std::ops::Range` is not an iterator
       --> $DIR/range-1.rs:9:14
        |
     LL |     for i in false..true {}
    diff --git a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    index 5820074b41cc..011e56044bfe 100644
    --- a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    +++ b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    @@ -16,7 +16,7 @@ help: consider restricting type parameter `T` with unstable trait `Unstable`
     LL | pub fn bar(t: T) {
        |             ++++++++++
     
    -error[E0277]: the trait bound `T: Step` is not satisfied
    +error[E0277]: `std::ops::Range` is not an iterator
       --> $DIR/unstable-trait-suggestion.rs:17:14
        |
     LL |     for _ in t {}
    
    From 47089856ab3200d08f561714d87159660be8a2dc Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
    Date: Tue, 13 Jan 2026 02:14:31 +0000
    Subject: [PATCH 2048/3801] Update run-make test output
    
    ---
     .../missing-unstable-trait-bound/missing-bound.stderr        | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr b/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr
    index 7196a1a6fed7..e8a7d808bbee 100644
    --- a/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr
    +++ b/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr
    @@ -1,9 +1,10 @@
    -error[E0277]: the trait bound `T: Step` is not satisfied
    +error[E0277]: `std::ops::Range` is not an iterator
      --> missing-bound.rs:2:14
       |
     2 |     for _ in t {}
    -  |              ^ the trait `Step` is not implemented for `T`
    +  |              ^ the nightly-only, unstable trait `Step` is not implemented for `T`
       |
    +  = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait
       = note: required for `std::ops::Range` to implement `Iterator`
       = note: required for `std::ops::Range` to implement `IntoIterator`
     
    
    From 112317749850f1c3f09f9ee9b0a7d872c7324d5f Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Augusto=20C=C3=A9sar=20Perin?= 
    Date: Mon, 12 Jan 2026 23:49:20 -0300
    Subject: [PATCH 2049/3801] Unify and deduplicate From float tests
    
    Co-authored-by: ericinB 
    ---
     library/coretests/tests/floats/f128.rs | 50 -----------------
     library/coretests/tests/floats/f16.rs  | 35 ------------
     library/coretests/tests/floats/mod.rs  | 78 +++++++++++++++++++++++++-
     3 files changed, 75 insertions(+), 88 deletions(-)
     delete mode 100644 library/coretests/tests/floats/f128.rs
     delete mode 100644 library/coretests/tests/floats/f16.rs
    
    diff --git a/library/coretests/tests/floats/f128.rs b/library/coretests/tests/floats/f128.rs
    deleted file mode 100644
    index 8e4f0c9899e1..000000000000
    --- a/library/coretests/tests/floats/f128.rs
    +++ /dev/null
    @@ -1,50 +0,0 @@
    -// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
    -#![cfg(target_has_reliable_f128)]
    -
    -use super::assert_biteq;
    -
    -// Note these tolerances make sense around zero, but not for more extreme exponents.
    -
    -/// Default tolerances. Works for values that should be near precise but not exact. Roughly
    -/// the precision carried by `100 * 100`.
    -#[allow(unused)]
    -const TOL: f128 = 1e-12;
    -
    -/// For operations that are near exact, usually not involving math of different
    -/// signs.
    -#[allow(unused)]
    -const TOL_PRECISE: f128 = 1e-28;
    -
    -// FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support
    -// the intrinsics.
    -
    -#[test]
    -fn test_from() {
    -    assert_biteq!(f128::from(false), 0.0);
    -    assert_biteq!(f128::from(true), 1.0);
    -    assert_biteq!(f128::from(u8::MIN), 0.0);
    -    assert_biteq!(f128::from(42_u8), 42.0);
    -    assert_biteq!(f128::from(u8::MAX), 255.0);
    -    assert_biteq!(f128::from(i8::MIN), -128.0);
    -    assert_biteq!(f128::from(42_i8), 42.0);
    -    assert_biteq!(f128::from(i8::MAX), 127.0);
    -    assert_biteq!(f128::from(u16::MIN), 0.0);
    -    assert_biteq!(f128::from(42_u16), 42.0);
    -    assert_biteq!(f128::from(u16::MAX), 65535.0);
    -    assert_biteq!(f128::from(i16::MIN), -32768.0);
    -    assert_biteq!(f128::from(42_i16), 42.0);
    -    assert_biteq!(f128::from(i16::MAX), 32767.0);
    -    assert_biteq!(f128::from(u32::MIN), 0.0);
    -    assert_biteq!(f128::from(42_u32), 42.0);
    -    assert_biteq!(f128::from(u32::MAX), 4294967295.0);
    -    assert_biteq!(f128::from(i32::MIN), -2147483648.0);
    -    assert_biteq!(f128::from(42_i32), 42.0);
    -    assert_biteq!(f128::from(i32::MAX), 2147483647.0);
    -    // FIXME(f16_f128): Uncomment these tests once the From<{u64,i64}> impls are added.
    -    // assert_eq!(f128::from(u64::MIN), 0.0);
    -    // assert_eq!(f128::from(42_u64), 42.0);
    -    // assert_eq!(f128::from(u64::MAX), 18446744073709551615.0);
    -    // assert_eq!(f128::from(i64::MIN), -9223372036854775808.0);
    -    // assert_eq!(f128::from(42_i64), 42.0);
    -    // assert_eq!(f128::from(i64::MAX), 9223372036854775807.0);
    -}
    diff --git a/library/coretests/tests/floats/f16.rs b/library/coretests/tests/floats/f16.rs
    deleted file mode 100644
    index 3cff4259de54..000000000000
    --- a/library/coretests/tests/floats/f16.rs
    +++ /dev/null
    @@ -1,35 +0,0 @@
    -// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
    -#![cfg(target_has_reliable_f16)]
    -
    -use super::assert_biteq;
    -
    -/// Tolerance for results on the order of 10.0e-2
    -#[allow(unused)]
    -const TOL_N2: f16 = 0.0001;
    -
    -/// Tolerance for results on the order of 10.0e+0
    -#[allow(unused)]
    -const TOL_0: f16 = 0.01;
    -
    -/// Tolerance for results on the order of 10.0e+2
    -#[allow(unused)]
    -const TOL_P2: f16 = 0.5;
    -
    -/// Tolerance for results on the order of 10.0e+4
    -#[allow(unused)]
    -const TOL_P4: f16 = 10.0;
    -
    -// FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support
    -// the intrinsics.
    -
    -#[test]
    -fn test_from() {
    -    assert_biteq!(f16::from(false), 0.0);
    -    assert_biteq!(f16::from(true), 1.0);
    -    assert_biteq!(f16::from(u8::MIN), 0.0);
    -    assert_biteq!(f16::from(42_u8), 42.0);
    -    assert_biteq!(f16::from(u8::MAX), 255.0);
    -    assert_biteq!(f16::from(i8::MIN), -128.0);
    -    assert_biteq!(f16::from(42_i8), 42.0);
    -    assert_biteq!(f16::from(i8::MAX), 127.0);
    -}
    diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs
    index 63d5b8fb2c6e..87e21b21f310 100644
    --- a/library/coretests/tests/floats/mod.rs
    +++ b/library/coretests/tests/floats/mod.rs
    @@ -375,9 +375,6 @@ macro_rules! float_test {
         };
     }
     
    -mod f128;
    -mod f16;
    -
     float_test! {
         name: num,
         attrs: {
    @@ -1582,3 +1579,78 @@ float_test! {
             assert_biteq!((flt(-3.2)).mul_add(2.4, neg_inf), neg_inf);
         }
     }
    +
    +float_test! {
    +    name: from,
    +    attrs: {
    +        f16: #[cfg(any(miri, target_has_reliable_f16))],
    +        f128: #[cfg(any(miri, target_has_reliable_f128))],
    +    },
    +    test {
    +        assert_biteq!(Float::from(false), Float::ZERO);
    +        assert_biteq!(Float::from(true), Float::ONE);
    +
    +        assert_biteq!(Float::from(u8::MIN), Float::ZERO);
    +        assert_biteq!(Float::from(42_u8), 42.0);
    +        assert_biteq!(Float::from(u8::MAX), 255.0);
    +
    +        assert_biteq!(Float::from(i8::MIN), -128.0);
    +        assert_biteq!(Float::from(42_i8), 42.0);
    +        assert_biteq!(Float::from(i8::MAX), 127.0);
    +    }
    +}
    +
    +float_test! {
    +    name: from_u16_i16,
    +    attrs: {
    +        f16: #[cfg(false)],
    +        const f16: #[cfg(false)],
    +        f128: #[cfg(any(miri, target_has_reliable_f128))],
    +    },
    +    test {
    +        assert_biteq!(Float::from(u16::MIN), Float::ZERO);
    +        assert_biteq!(Float::from(42_u16), 42.0);
    +        assert_biteq!(Float::from(u16::MAX), 65535.0);
    +        assert_biteq!(Float::from(i16::MIN), -32768.0);
    +        assert_biteq!(Float::from(42_i16), 42.0);
    +        assert_biteq!(Float::from(i16::MAX), 32767.0);
    +    }
    +}
    +
    +float_test! {
    +    name: from_u32_i32,
    +    attrs: {
    +        f16: #[cfg(false)],
    +        const f16: #[cfg(false)],
    +        f32: #[cfg(false)],
    +        const f32: #[cfg(false)],
    +        f128: #[cfg(any(miri, target_has_reliable_f128))],
    +    },
    +    test {
    +        assert_biteq!(Float::from(u32::MIN), Float::ZERO);
    +        assert_biteq!(Float::from(42_u32), 42.0);
    +        assert_biteq!(Float::from(u32::MAX), 4294967295.0);
    +        assert_biteq!(Float::from(i32::MIN), -2147483648.0);
    +        assert_biteq!(Float::from(42_i32), 42.0);
    +        assert_biteq!(Float::from(i32::MAX), 2147483647.0);
    +    }
    +}
    +
    +// FIXME(f16_f128): Uncomment and adapt these tests once the From<{u64,i64}> impls are added.
    +// float_test! {
    +//     name: from_u64_i64,
    +//     attrs: {
    +//         f16: #[cfg(false)],
    +//         f32: #[cfg(false)],
    +//         f64: #[cfg(false)],
    +//         f128: #[cfg(any(miri, target_has_reliable_f128))],
    +//     },
    +//     test {
    +//         assert_biteq!(Float::from(u64::MIN), Float::ZERO);
    +//         assert_biteq!(Float::from(42_u64), 42.0);
    +//         assert_biteq!(Float::from(u64::MAX), 18446744073709551615.0);
    +//         assert_biteq!(Float::from(i64::MIN), -9223372036854775808.0);
    +//         assert_biteq!(Float::from(42_i64), 42.0);
    +//         assert_biteq!(Float::from(i64::MAX), 9223372036854775807.0);
    +//     }
    +// }
    
    From 9b7f612d44057840d41bdae399d0b491820647a5 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
    Date: Tue, 13 Jan 2026 02:57:40 +0000
    Subject: [PATCH 2050/3801] Update main label
    
    ---
     library/core/src/iter/range.rs                                 | 1 +
     .../run-make/missing-unstable-trait-bound/missing-bound.stderr | 2 +-
     tests/ui/range/range-1.stderr                                  | 3 ++-
     tests/ui/trait-bounds/unstable-trait-suggestion.stderr         | 2 +-
     4 files changed, 5 insertions(+), 3 deletions(-)
    
    diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
    index 0be1e8699bf5..7880e18d7d31 100644
    --- a/library/core/src/iter/range.rs
    +++ b/library/core/src/iter/range.rs
    @@ -23,6 +23,7 @@ unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u6
     #[rustc_diagnostic_item = "range_step"]
     #[rustc_on_unimplemented(
         message = "`std::ops::Range<{Self}>` is not an iterator",
    +    label = "not an iterator",
         note = "`Range` only implements `Iterator` for select types in the standard library, \
                 particularly integers; to see the full list of types, see the documentation for the \
                 unstable `Step` trait"
    diff --git a/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr b/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr
    index e8a7d808bbee..d503751a2e93 100644
    --- a/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr
    +++ b/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr
    @@ -2,7 +2,7 @@ error[E0277]: `std::ops::Range` is not an iterator
      --> missing-bound.rs:2:14
       |
     2 |     for _ in t {}
    -  |              ^ the nightly-only, unstable trait `Step` is not implemented for `T`
    +  |              ^ not an iterator
       |
       = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait
       = note: required for `std::ops::Range` to implement `Iterator`
    diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr
    index 5491d06aee09..9682122539c5 100644
    --- a/tests/ui/range/range-1.stderr
    +++ b/tests/ui/range/range-1.stderr
    @@ -8,8 +8,9 @@ error[E0277]: `std::ops::Range` is not an iterator
       --> $DIR/range-1.rs:9:14
        |
     LL |     for i in false..true {}
    -   |              ^^^^^^^^^^^ the nightly-only, unstable trait `Step` is not implemented for `bool`
    +   |              ^^^^^^^^^^^ not an iterator
        |
    +   = help: the nightly-only, unstable trait `Step` is not implemented for `bool`
        = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait
        = note: required for `std::ops::Range` to implement `Iterator`
        = note: required for `std::ops::Range` to implement `IntoIterator`
    diff --git a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    index 011e56044bfe..5edaed0f4dfe 100644
    --- a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    +++ b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr
    @@ -20,7 +20,7 @@ error[E0277]: `std::ops::Range` is not an iterator
       --> $DIR/unstable-trait-suggestion.rs:17:14
        |
     LL |     for _ in t {}
    -   |              ^ the nightly-only, unstable trait `Step` is not implemented for `T`
    +   |              ^ not an iterator
        |
        = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait
        = note: required for `std::ops::Range` to implement `Iterator`
    
    From e5dbb3b1a2234c49f7134b3a305ca004b993536b Mon Sep 17 00:00:00 2001
    From: Marco Trevisan 
    Date: Tue, 13 Jan 2026 04:01:45 +0100
    Subject: [PATCH 2051/3801] armv7-unknown-linux-uclibceabihf.md: Fix build-toml
     syntax
    
    With the suggested value we were getting instead:
    
    ```
    ERROR: Failed to parse '/tmp/rust/bootstrap.toml': unknown field `stage`, expected one of `build`, `description`, `host`, `target`, `build-dir`, `cargo`, `rustc`, `rustfmt`, `cargo-clippy`, `docs`, `compiler-docs`, `library-docs-private-items`, `docs-minification`, `submodules`, `gdb`, `lldb`, `nodejs`, `npm`, `yarn`, `python`, `windows-rc`, `reuse`, `locked-deps`, `vendor`, `full-bootstrap`, `bootstrap-cache-path`, `extended`, `tools`, `tool`, `verbose`, `sanitizers`, `profiler`, `cargo-native-static`, `low-priority`, `configure-args`, `local-rebuild`, `print-step-timings`, `print-step-rusage`, `check-stage`, `doc-stage`, `build-stage`, `test-stage`, `install-stage`, `dist-stage`, `bench-stage`, `patch-binaries-for-nix`, `metrics`, `android-ndk`, `optimized-compiler-builtins`, `jobs`, `compiletest-diff-tool`, `compiletest-allow-stage0`, `compiletest-use-stage0-libtest`, `tidy-extra-checks`, `ccache`, `exclude` for key `build`
    ```
    ---
     .../src/platform-support/armv7-unknown-linux-uclibceabihf.md    | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
    index 9fb24906b4fc..249c8fc23a0c 100644
    --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
    +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
    @@ -30,7 +30,7 @@ The target can be built by enabling it for a `rustc` build, by placing the follo
     ```toml
     [build]
     target = ["armv7-unknown-linux-uclibceabihf"]
    -stage = 2
    +build-stage = 2
     
     [target.armv7-unknown-linux-uclibceabihf]
     # ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN
    
    From 02333ad8a2805b333d2d0a944fc04a2ff3b37b90 Mon Sep 17 00:00:00 2001
    From: Zalathar 
    Date: Tue, 13 Jan 2026 14:10:53 +1100
    Subject: [PATCH 2052/3801] Simplify some literal-value negations with
     `u128::wrapping_neg`
    
    ---
     compiler/rustc_mir_build/src/builder/expr/as_constant.rs | 4 +++-
     compiler/rustc_mir_build/src/thir/constant.rs            | 8 ++++----
     2 files changed, 7 insertions(+), 5 deletions(-)
    
    diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs
    index 1772d66f5285..8a242445f175 100644
    --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs
    +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs
    @@ -157,7 +157,9 @@ fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>
             }
             (ast::LitKind::Int(n, _), ty::Uint(_)) if !neg => trunc(n.get()),
             (ast::LitKind::Int(n, _), ty::Int(_)) => {
    -            trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() })
    +            // Unsigned "negation" has the same bitwise effect as signed negation,
    +            // which gets the result we want without additional casts.
    +            trunc(if neg { u128::wrapping_neg(n.get()) } else { n.get() })
             }
             (ast::LitKind::Float(n, _), ty::Float(fty)) => {
                 parse_float_into_constval(n, *fty, neg).unwrap()
    diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
    index 7964a58a7ab0..96248499044a 100644
    --- a/compiler/rustc_mir_build/src/thir/constant.rs
    +++ b/compiler/rustc_mir_build/src/thir/constant.rs
    @@ -72,10 +72,10 @@ pub(crate) fn lit_to_const<'tcx>(
                 ty::ValTree::from_scalar_int(tcx, scalar_int)
             }
             (ast::LitKind::Int(n, _), ty::Int(i)) => {
    -            let scalar_int = trunc(
    -                if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() },
    -                i.to_unsigned(),
    -            );
    +            // Unsigned "negation" has the same bitwise effect as signed negation,
    +            // which gets the result we want without additional casts.
    +            let scalar_int =
    +                trunc(if neg { u128::wrapping_neg(n.get()) } else { n.get() }, i.to_unsigned());
                 ty::ValTree::from_scalar_int(tcx, scalar_int)
             }
             (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int(tcx, b.into()),
    
    From 1e6909140356a20c9301523a03176b38325cd7eb Mon Sep 17 00:00:00 2001
    From: Marco Trevisan 
    Date: Tue, 13 Jan 2026 04:17:51 +0100
    Subject: [PATCH 2053/3801] armv7-unknown-linux-uclibceabihf.md: Update
     toolchain download link
    
    The old toolchain is not working with recent rustc, as it does not
    defining `getauxval`
    ---
     .../src/platform-support/armv7-unknown-linux-uclibceabihf.md    | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
    index 249c8fc23a0c..d2635f12db21 100644
    --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
    +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
    @@ -21,7 +21,7 @@ This target is cross compiled, and requires a cross toolchain.  You can find sui
     
     Compiling rust for this target has been tested on `x86_64` linux hosts.  Other host types have not been tested, but may work, if you can find a suitable cross compilation toolchain for them.
     
    -If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2021.11-1.tar.bz2), and unpack it into a directory.
    +If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2025.08-1.tar.xz), and unpack it into a directory.
     
     ### Configure rust
     
    
    From 8a8b31a4d1e971044b7904acd711191d7f6b200c Mon Sep 17 00:00:00 2001
    From: Martin Nordholts 
    Date: Mon, 12 Jan 2026 06:53:19 +0100
    Subject: [PATCH 2054/3801] compiler: Make Externally Implementable Item (eii)
     macros "semiopaque"
    
    Otherwise eiis defined by std will produce large amounts of `missing
    stability attribute` errors.
    ---
     compiler/rustc_builtin_macros/src/eii.rs | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs
    index 0ebd3dc826d4..b1cd35c0433d 100644
    --- a/compiler/rustc_builtin_macros/src/eii.rs
    +++ b/compiler/rustc_builtin_macros/src/eii.rs
    @@ -425,6 +425,9 @@ fn generate_attribute_macro_to_implement(
         // errors for eii's in std.
         macro_attrs.extend_from_slice(attrs_from_decl);
     
    +    // Avoid "missing stability attribute" errors for eiis in std. See #146993.
    +    macro_attrs.push(ecx.attr_name_value_str(sym::rustc_macro_transparency, sym::semiopaque, span));
    +
         // #[builtin_macro(eii_shared_macro)]
         macro_attrs.push(ecx.attr_nested_word(sym::rustc_builtin_macro, sym::eii_shared_macro, span));
     
    
    From c263d36539d2859b9fd6f433e6a23a99a3d09d16 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= 
    Date: Tue, 13 Jan 2026 07:35:24 +0100
    Subject: [PATCH 2055/3801] Fix citool tests
    
    ---
     src/ci/citool/tests/jobs.rs | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs
    index 5231d4616e04..6787f00d9af8 100644
    --- a/src/ci/citool/tests/jobs.rs
    +++ b/src/ci/citool/tests/jobs.rs
    @@ -4,7 +4,7 @@ const TEST_JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/tes
     
     #[test]
     fn auto_jobs() {
    -    let stdout = get_matrix("push", "commit", "refs/heads/auto");
    +    let stdout = get_matrix("push", "commit", "refs/heads/automation/bors/auto");
         insta::assert_snapshot!(stdout, @r#"
         jobs=[{"name":"aarch64-gnu","full_name":"auto - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"x86_64-gnu-llvm-18-1","full_name":"auto - x86_64-gnu-llvm-18-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DOCKER_SCRIPT":"stage_2_test_set1.sh","IMAGE":"x86_64-gnu-llvm-18","READ_ONLY_SRC":"0","RUST_BACKTRACE":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"aarch64-apple","full_name":"auto - aarch64-apple","os":"macos-14","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set rust.jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","SELECT_XCODE":"/Applications/Xcode_15.4.app","TOOLSTATE_PUBLISH":1,"USE_XCODE_CLANG":1}},{"name":"dist-i686-msvc","full_name":"auto - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}},{"name":"pr-check-1","full_name":"auto - pr-check-1","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"pr-check-2","full_name":"auto - pr-check-2","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true},{"name":"tidy","full_name":"auto - tidy","os":"ubuntu-24.04","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"continue_on_error":false,"free_disk":true,"doc_url":"https://foo.bar"}]
         run_type=auto
    @@ -13,7 +13,7 @@ fn auto_jobs() {
     
     #[test]
     fn try_jobs() {
    -    let stdout = get_matrix("push", "commit", "refs/heads/try");
    +    let stdout = get_matrix("push", "commit", "refs/heads/automation/bors/try");
         insta::assert_snapshot!(stdout, @r###"
         jobs=[{"name":"dist-x86_64-linux","full_name":"try - dist-x86_64-linux","os":"ubuntu-22.04-16core-64gb","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_TRY_BUILD":1,"TOOLSTATE_PUBLISH":1}}]
         run_type=try
    @@ -28,7 +28,7 @@ fn try_custom_jobs() {
     
     try-job: aarch64-gnu
     try-job: dist-i686-msvc"#,
    -        "refs/heads/try",
    +        "refs/heads/automation/bors/try",
         );
         insta::assert_snapshot!(stdout, @r###"
         jobs=[{"name":"aarch64-gnu","full_name":"try - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"dist-i686-msvc","full_name":"try - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}}]
    
    From 506762f3ff5ecdc25725e68b9669dff2e452582b Mon Sep 17 00:00:00 2001
    From: Lukas Bergdoll 
    Date: Sun, 28 Dec 2025 11:22:41 +0100
    Subject: [PATCH 2056/3801] Explicitly export core and std macros
    
    Currently all core and std macros are automatically added to the prelude
    via #[macro_use]. However a situation arose where we want to add a new macro
    `assert_matches` but don't want to pull it into the standard prelude for
    compatibility reasons. By explicitly exporting the macros found in the core and
    std crates we get to decide on a per macro basis and can later add them via
    the rust_20xx preludes.
    ---
     .../src/standard_library_imports.rs           |  2 +-
     compiler/rustc_lint_defs/src/builtin.rs       | 37 ++++++++++
     compiler/rustc_resolve/src/diagnostics.rs     | 26 +++----
     compiler/rustc_resolve/src/ident.rs           | 23 +++++--
     compiler/rustc_resolve/src/imports.rs         |  7 +-
     compiler/rustc_resolve/src/lib.rs             | 14 +++-
     compiler/rustc_resolve/src/macros.rs          | 10 +--
     library/alloctests/lib.rs                     | 12 +++-
     library/core/src/prelude/v1.rs                | 49 ++++++++++++-
     library/std/src/prelude/mod.rs                | 21 +++++-
     library/std/src/prelude/v1.rs                 | 59 ++++++++++++++--
     library/std/src/process.rs                    |  2 +-
     tests/pretty/asm.pp                           |  1 -
     tests/pretty/autodiff/autodiff_forward.pp     |  1 -
     tests/pretty/autodiff/autodiff_reverse.pp     |  1 -
     tests/pretty/autodiff/inherent_impl.pp        |  1 -
     tests/pretty/cast-lt.pp                       |  1 -
     tests/pretty/delegation-impl-reuse.pp         |  1 -
     tests/pretty/delegation-inherit-attributes.pp |  1 -
     tests/pretty/delegation-inline-attribute.pp   |  1 -
     tests/pretty/dollar-crate.pp                  |  1 -
     tests/pretty/expanded-and-path-remap-80832.pp |  1 -
     tests/pretty/format-args-str-escape.pp        |  1 -
     tests/pretty/hir-delegation.pp                |  1 -
     tests/pretty/hir-fn-params.pp                 |  1 -
     tests/pretty/hir-fn-variadic.pp               |  1 -
     tests/pretty/hir-if-else.pp                   |  1 -
     tests/pretty/hir-lifetimes.pp                 |  1 -
     tests/pretty/hir-pretty-attr.pp               |  1 -
     tests/pretty/hir-pretty-loop.pp               |  1 -
     tests/pretty/hir-struct-expr.pp               |  1 -
     tests/pretty/if-else.pp                       |  1 -
     tests/pretty/issue-12590-c.pp                 |  1 -
     tests/pretty/issue-4264.pp                    |  1 -
     tests/pretty/issue-85089.pp                   |  1 -
     tests/pretty/never-pattern.pp                 |  1 -
     tests/pretty/pin-ergonomics-hir.pp            |  1 -
     tests/pretty/postfix-match/precedence.pp      |  1 -
     tests/pretty/shebang-at-top.pp                |  1 -
     tests/pretty/tests-are-sorted.pp              |  1 -
     tests/rustdoc-js-std/println-typo.js          |  3 +
     tests/ui/asm/unpretty-expanded.stdout         |  1 -
     .../unpretty-parenthesized.stdout             |  1 -
     .../ui/codemap_tests/unicode.expanded.stdout  |  1 -
     .../defaults/pretty-printing-ast.stdout       |  1 -
     .../deriving/built-in-proc-macro-scope.stdout |  1 -
     tests/ui/deriving/deriving-all-codegen.stdout |  1 -
     .../deriving-coerce-pointee-expanded.stdout   |  1 -
     .../proc-macro-attribute-mixing.stdout        |  1 -
     .../feature-gate-format_args_nl.rs            |  2 +
     .../feature-gate-format_args_nl.stderr        | 13 +++-
     tests/ui/hygiene/format-args.rs               |  2 +
     .../ambiguous-panic-glob-vs-multiouter.rs     | 16 +++++
     .../ambiguous-panic-glob-vs-multiouter.stderr | 23 +++++++
     .../ui/imports/ambiguous-panic-globvsglob.rs  | 23 +++++++
     .../imports/ambiguous-panic-globvsglob.stderr | 68 +++++++++++++++++++
     .../ambiguous-panic-no-implicit-prelude.rs    | 16 +++++
     ...ambiguous-panic-no-implicit-prelude.stderr | 19 ++++++
     .../ambiguous-panic-non-prelude-core-glob.rs  | 11 +++
     ...biguous-panic-non-prelude-core-glob.stderr | 22 ++++++
     .../ambiguous-panic-non-prelude-std-glob.rs   | 12 ++++
     ...mbiguous-panic-non-prelude-std-glob.stderr | 22 ++++++
     tests/ui/imports/ambiguous-panic-pick-core.rs | 11 +++
     .../imports/ambiguous-panic-pick-core.stderr  | 37 ++++++++++
     tests/ui/imports/ambiguous-panic-pick-std.rs  | 14 ++++
     .../imports/ambiguous-panic-pick-std.stderr   | 37 ++++++++++
     tests/ui/imports/ambiguous-panic-re-emit.rs   | 23 +++++++
     .../ui/imports/ambiguous-panic-re-emit.stderr | 29 ++++++++
     .../imports/ambiguous-panic-rename-builtin.rs | 15 ++++
     .../ambiguous-panic-rename-builtin.stderr     | 26 +++++++
     .../imports/ambiguous-panic-rename-panics.rs  | 17 +++++
     .../ambiguous-panic-rename-panics.stderr      | 23 +++++++
     tests/ui/imports/ambiguous-panic.rs           | 12 ++++
     tests/ui/imports/ambiguous-panic.stderr       | 26 +++++++
     tests/ui/imports/glob-shadowing.stderr        | 10 +--
     .../local-modularized-tricky-fail-1.stderr    | 10 +--
     tests/ui/imports/shadow_builtin_macros.stderr | 15 ++--
     tests/ui/lint/dead-code/with-core-crate.rs    |  1 -
     .../ui/lint/dead-code/with-core-crate.stderr  |  2 +-
     .../no_ice_for_partial_compiler_runs.stdout   |  1 -
     .../genercs-in-path-with-prettry-hir.stdout   |  1 -
     ...ming-methods-have-optimized-codegen.stdout |  1 -
     tests/ui/match/issue-82392.stdout             |  1 -
     tests/ui/proc-macro/meta-macro-hygiene.stdout |  1 -
     .../nonterminal-token-hygiene.stdout          |  1 -
     tests/ui/proc-macro/quote/debug.stdout        |  1 -
     .../ast-pretty-check.stdout                   |  1 -
     tests/ui/stats/input-stats.stderr             | 12 ++--
     .../type-alias-impl-trait/issue-60662.stdout  |  1 -
     tests/ui/unpretty/bad-literal.stdout          |  1 -
     tests/ui/unpretty/debug-fmt-hir.stdout        |  1 -
     tests/ui/unpretty/deprecated-attr.stdout      |  1 -
     tests/ui/unpretty/diagnostic-attr.stdout      |  1 -
     .../unpretty/exhaustive-asm.expanded.stdout   |  1 -
     tests/ui/unpretty/exhaustive-asm.hir.stdout   |  1 -
     tests/ui/unpretty/exhaustive.expanded.stdout  |  1 -
     tests/ui/unpretty/exhaustive.hir.stdout       |  1 -
     .../ui/unpretty/flattened-format-args.stdout  |  1 -
     .../ui/unpretty/interpolation-expanded.stdout |  1 -
     tests/ui/unpretty/let-else-hir.stdout         |  1 -
     tests/ui/unpretty/self-hir.stdout             |  1 -
     ...ct-exprs-tuple-call-pretty-printing.stdout |  1 -
     tests/ui/unpretty/unpretty-expr-fn-arg.stdout |  1 -
     103 files changed, 770 insertions(+), 123 deletions(-)
     create mode 100644 tests/ui/imports/ambiguous-panic-glob-vs-multiouter.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-glob-vs-multiouter.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic-globvsglob.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-globvsglob.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic-no-implicit-prelude.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-no-implicit-prelude.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic-non-prelude-core-glob.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-non-prelude-core-glob.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic-non-prelude-std-glob.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-non-prelude-std-glob.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic-pick-core.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-pick-core.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic-pick-std.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-pick-std.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic-re-emit.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-re-emit.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic-rename-builtin.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-rename-builtin.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic-rename-panics.rs
     create mode 100644 tests/ui/imports/ambiguous-panic-rename-panics.stderr
     create mode 100644 tests/ui/imports/ambiguous-panic.rs
     create mode 100644 tests/ui/imports/ambiguous-panic.stderr
    
    diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
    index 2068b5ca54dd..9f22d9eacb33 100644
    --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs
    +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
    @@ -43,7 +43,7 @@ pub fn inject(
     
         let item = cx.item(
             span,
    -        thin_vec![cx.attr_word(sym::macro_use, span)],
    +        ast::AttrVec::new(),
             ast::ItemKind::ExternCrate(None, Ident::new(name, ident_span)),
         );
     
    diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
    index 8c69cc089caf..4230aa7568e2 100644
    --- a/compiler/rustc_lint_defs/src/builtin.rs
    +++ b/compiler/rustc_lint_defs/src/builtin.rs
    @@ -19,6 +19,7 @@ declare_lint_pass! {
             AMBIGUOUS_ASSOCIATED_ITEMS,
             AMBIGUOUS_GLOB_IMPORTS,
             AMBIGUOUS_GLOB_REEXPORTS,
    +        AMBIGUOUS_PANIC_IMPORTS,
             ARITHMETIC_OVERFLOW,
             ASM_SUB_REGISTER,
             BAD_ASM_STYLE,
    @@ -4472,6 +4473,42 @@ declare_lint! {
         };
     }
     
    +declare_lint! {
    +    /// The `ambiguous_panic_imports` lint detects ambiguous core and std panic imports, but
    +    /// previously didn't do that due to `#[macro_use]` prelude macro import.
    +    ///
    +    /// ### Example
    +    ///
    +    /// ```rust,compile_fail
    +    /// #![deny(ambiguous_panic_imports)]
    +    /// #![no_std]
    +    ///
    +    /// extern crate std;
    +    /// use std::prelude::v1::*;
    +    ///
    +    /// fn xx() {
    +    ///     panic!(); // resolves to core::panic
    +    /// }
    +    /// ```
    +    ///
    +    /// {{produces}}
    +    ///
    +    /// ### Explanation
    +    ///
    +    /// Future versions of Rust will no longer accept the ambiguous resolution.
    +    ///
    +    /// This is a [future-incompatible] lint to transition this to a hard error in the future.
    +    ///
    +    /// [future-incompatible]: ../index.md#future-incompatible-lints
    +    pub AMBIGUOUS_PANIC_IMPORTS,
    +    Warn,
    +    "detects ambiguous core and std panic imports",
    +    @future_incompatible = FutureIncompatibleInfo {
    +        reason: fcw!(FutureReleaseError #147319),
    +        report_in_deps: false,
    +    };
    +}
    +
     declare_lint! {
         /// The `refining_impl_trait_reachable` lint detects `impl Trait` return
         /// types in method signatures that are refined by a publically reachable
    diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
    index 9781a77871f6..7bc08f1de546 100644
    --- a/compiler/rustc_resolve/src/diagnostics.rs
    +++ b/compiler/rustc_resolve/src/diagnostics.rs
    @@ -24,7 +24,7 @@ use rustc_middle::ty::TyCtxt;
     use rustc_session::Session;
     use rustc_session::lint::BuiltinLintDiag;
     use rustc_session::lint::builtin::{
    -    ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS,
    +    ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS, AMBIGUOUS_PANIC_IMPORTS,
         MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
     };
     use rustc_session::utils::was_invoked_from_cargo;
    @@ -44,10 +44,11 @@ use crate::errors::{
     use crate::imports::{Import, ImportKind};
     use crate::late::{DiagMetadata, PatternSource, Rib};
     use crate::{
    -    AmbiguityError, AmbiguityKind, BindingError, BindingKey, Decl, DeclKind, Finalize,
    -    ForwardGenericParamBanReason, HasGenericParams, LateDecl, MacroRulesScope, Module, ModuleKind,
    -    ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError, Resolver, Scope,
    -    ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs, path_names_to_string,
    +    AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingError, BindingKey, Decl, DeclKind,
    +    Finalize, ForwardGenericParamBanReason, HasGenericParams, LateDecl, MacroRulesScope, Module,
    +    ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError,
    +    Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs,
    +    path_names_to_string,
     };
     
     type Res = def::Res;
    @@ -146,17 +147,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             for ambiguity_error in &self.ambiguity_errors {
                 let diag = self.ambiguity_diagnostic(ambiguity_error);
     
    -            if ambiguity_error.warning {
    +            if let Some(ambiguity_warning) = ambiguity_error.warning {
                     let node_id = match ambiguity_error.b1.0.kind {
                         DeclKind::Import { import, .. } => import.root_id,
                         DeclKind::Def(_) => CRATE_NODE_ID,
                     };
    -                self.lint_buffer.buffer_lint(
    -                    AMBIGUOUS_GLOB_IMPORTS,
    -                    node_id,
    -                    diag.ident.span,
    -                    diag,
    -                );
    +
    +                let lint = match ambiguity_warning {
    +                    AmbiguityWarning::GlobImport => AMBIGUOUS_GLOB_IMPORTS,
    +                    AmbiguityWarning::PanicImport => AMBIGUOUS_PANIC_IMPORTS,
    +                };
    +
    +                self.lint_buffer.buffer_lint(lint, node_id, diag.ident.span, diag);
                 } else {
                     self.dcx().emit_err(diag);
                 }
    diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
    index 91fe6741950b..7f04216c5553 100644
    --- a/compiler/rustc_resolve/src/ident.rs
    +++ b/compiler/rustc_resolve/src/ident.rs
    @@ -8,6 +8,7 @@ use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRe
     use rustc_middle::{bug, span_bug};
     use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
     use rustc_session::parse::feature_err;
    +use rustc_span::edition::Edition;
     use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
     use rustc_span::{Ident, Macros20NormalizedIdent, Span, kw, sym};
     use smallvec::SmallVec;
    @@ -20,9 +21,10 @@ use crate::late::{
     };
     use crate::macros::{MacroRulesScope, sub_namespace_match};
     use crate::{
    -    AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Decl, DeclKind, Determinacy, Finalize,
    -    ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult,
    -    PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Used, errors,
    +    AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind,
    +    Determinacy, Finalize, ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot,
    +    ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet,
    +    Segment, Stage, Used, errors,
     };
     
     #[derive(Copy, Clone)]
    @@ -841,6 +843,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 if issue_145575_hack || issue_149681_hack {
                     self.issue_145575_hack_applied = true;
                 } else {
    +                // Turn ambiguity errors for core vs std panic into warnings.
    +                // FIXME: Remove with lang team approval.
    +                let is_issue_147319_hack = orig_ident.span.edition() <= Edition::Edition2024
    +                    && matches!(orig_ident.name, sym::panic)
    +                    && matches!(scope, Scope::StdLibPrelude)
    +                    && matches!(innermost_scope, Scope::ModuleGlobs(_, _))
    +                    && ((self.is_specific_builtin_macro(res, sym::std_panic)
    +                        && self.is_specific_builtin_macro(innermost_res, sym::core_panic))
    +                        || (self.is_specific_builtin_macro(res, sym::core_panic)
    +                            && self.is_specific_builtin_macro(innermost_res, sym::std_panic)));
    +
    +                let warning = is_issue_147319_hack.then_some(AmbiguityWarning::PanicImport);
    +
                     self.ambiguity_errors.push(AmbiguityError {
                         kind,
                         ident: orig_ident,
    @@ -848,7 +863,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         b2: decl,
                         scope1: innermost_scope,
                         scope2: scope,
    -                    warning: false,
    +                    warning,
                     });
                     return true;
                 }
    diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
    index b98061ea8130..4447374b8b06 100644
    --- a/compiler/rustc_resolve/src/imports.rs
    +++ b/compiler/rustc_resolve/src/imports.rs
    @@ -959,8 +959,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 ImportKind::Single { decls, .. } => decls[TypeNS].get().decl(),
                 _ => None,
             };
    -        let ambiguity_errors_len =
    -            |errors: &Vec>| errors.iter().filter(|error| !error.warning).count();
    +        let ambiguity_errors_len = |errors: &Vec>| {
    +            errors.iter().filter(|error| error.warning.is_none()).count()
    +        };
             let prev_ambiguity_errors_len = ambiguity_errors_len(&self.ambiguity_errors);
             let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
     
    @@ -1176,7 +1177,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                             });
                             let res = binding.res();
                             let has_ambiguity_error =
    -                            this.ambiguity_errors.iter().any(|error| !error.warning);
    +                            this.ambiguity_errors.iter().any(|error| error.warning.is_none());
                             if res == Res::Err || has_ambiguity_error {
                                 this.dcx()
                                     .span_delayed_bug(import.span, "some error happened for an import");
    diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
    index d82fad3861d5..c4c1e06f94ae 100644
    --- a/compiler/rustc_resolve/src/lib.rs
    +++ b/compiler/rustc_resolve/src/lib.rs
    @@ -911,6 +911,12 @@ impl AmbiguityKind {
         }
     }
     
    +#[derive(Clone, Copy, PartialEq)]
    +enum AmbiguityWarning {
    +    GlobImport,
    +    PanicImport,
    +}
    +
     struct AmbiguityError<'ra> {
         kind: AmbiguityKind,
         ident: Ident,
    @@ -919,7 +925,7 @@ struct AmbiguityError<'ra> {
         // `empty_module` in module scope serves as an unknown module here.
         scope1: Scope<'ra>,
         scope2: Scope<'ra>,
    -    warning: bool,
    +    warning: Option,
     }
     
     impl<'ra> DeclData<'ra> {
    @@ -1871,6 +1877,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
         }
     
    +    fn is_specific_builtin_macro(&self, res: Res, symbol: Symbol) -> bool {
    +        self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name == Some(symbol))
    +    }
    +
         fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
             loop {
                 match ctxt.outer_expn_data().macro_def_id {
    @@ -2063,7 +2073,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                     b2,
                     scope1: Scope::ModuleGlobs(self.empty_module, None),
                     scope2: Scope::ModuleGlobs(self.empty_module, None),
    -                warning: warn_ambiguity,
    +                warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None },
                 };
                 if !self.matches_previous_ambiguity_error(&ambiguity_error) {
                     // avoid duplicated span information to be emit out
    diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
    index 32d686d4f702..38628332f43e 100644
    --- a/compiler/rustc_resolve/src/macros.rs
    +++ b/compiler/rustc_resolve/src/macros.rs
    @@ -835,10 +835,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                                      res: Res| {
                 if let Some(initial_res) = initial_res {
                     if res != initial_res {
    -                    // Make sure compilation does not succeed if preferred macro resolution
    -                    // has changed after the macro had been expanded. In theory all such
    -                    // situations should be reported as errors, so this is a bug.
    -                    this.dcx().span_delayed_bug(span, "inconsistent resolution for a macro");
    +                    if this.ambiguity_errors.is_empty() {
    +                        // Make sure compilation does not succeed if preferred macro resolution
    +                        // has changed after the macro had been expanded. In theory all such
    +                        // situations should be reported as errors, so this is a bug.
    +                        this.dcx().span_delayed_bug(span, "inconsistent resolution for a macro");
    +                    }
                     }
                 } else if this.tcx.dcx().has_errors().is_none() && this.privacy_errors.is_empty() {
                     // It's possible that the macro was unresolved (indeterminate) and silently
    diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs
    index b85fc8eb9970..02364c01d4d6 100644
    --- a/library/alloctests/lib.rs
    +++ b/library/alloctests/lib.rs
    @@ -65,6 +65,7 @@
     #![feature(negative_impls)]
     #![feature(never_type)]
     #![feature(optimize_attribute)]
    +#![feature(prelude_import)]
     #![feature(rustc_allow_const_fn_unstable)]
     #![feature(rustc_attrs)]
     #![feature(staged_api)]
    @@ -74,11 +75,17 @@
     
     // Allow testing this library
     extern crate alloc as realalloc;
    -#[macro_use]
    +
    +// This is needed to provide macros to the directly imported alloc modules below.
     extern crate std;
    +#[prelude_import]
    +#[allow(unused_imports)]
    +use std::prelude::rust_2024::*;
    +
     #[cfg(test)]
     extern crate test;
     mod testing;
    +
     use realalloc::*;
     
     // We are directly including collections, raw_vec, and wtf8 here as they use non-public
    @@ -102,8 +109,7 @@ pub(crate) mod test_helpers {
             let mut hasher = std::hash::RandomState::new().build_hasher();
             std::panic::Location::caller().hash(&mut hasher);
             let hc64 = hasher.finish();
    -        let seed_vec =
    -            hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>();
    +        let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>();
             let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
             rand::SeedableRng::from_seed(seed)
         }
    diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs
    index 7e0a84df5118..354be271ff13 100644
    --- a/library/core/src/prelude/v1.rs
    +++ b/library/core/src/prelude/v1.rs
    @@ -59,12 +59,31 @@ pub use crate::hash::macros::Hash;
     
     #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
     #[doc(no_inline)]
    +#[expect(deprecated)]
     pub use crate::{
    -    assert, cfg, column, compile_error, concat, env, file, format_args,
    -    format_args_nl, include, include_bytes, include_str, line, log_syntax, module_path, option_env,
    -    stringify, trace_macros,
    +    assert, assert_eq, assert_ne, cfg, column, compile_error, concat, debug_assert, debug_assert_eq,
    +    debug_assert_ne, file, format_args, include, include_bytes, include_str, line, matches,
    +    module_path, option_env, stringify, todo, r#try, unimplemented, unreachable, write, writeln,
     };
     
    +// These macros need special handling, so that we don't export them *and* the modules of the same
    +// name. We only want the macros in the prelude so we shadow the original modules with private
    +// modules with the same names.
    +mod ambiguous_macros_only {
    +    mod env {}
    +    #[expect(hidden_glob_reexports)]
    +    mod panic {}
    +    #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
    +    pub use crate::*;
    +}
    +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
    +#[doc(no_inline)]
    +pub use self::ambiguous_macros_only::{env, panic};
    +
    +#[unstable(feature = "cfg_select", issue = "115585")]
    +#[doc(no_inline)]
    +pub use crate::cfg_select;
    +
     #[unstable(
         feature = "concat_bytes",
         issue = "87555",
    @@ -73,6 +92,30 @@ pub use crate::{
     #[doc(no_inline)]
     pub use crate::concat_bytes;
     
    +#[unstable(feature = "const_format_args", issue = "none")]
    +#[doc(no_inline)]
    +pub use crate::const_format_args;
    +
    +#[unstable(
    +    feature = "log_syntax",
    +    issue = "29598",
    +    reason = "`log_syntax!` is not stable enough for use and is subject to change"
    +)]
    +#[doc(no_inline)]
    +pub use crate::log_syntax;
    +
    +#[unstable(feature = "pattern_type_macro", issue = "123646")]
    +#[doc(no_inline)]
    +pub use crate::pattern_type;
    +
    +#[unstable(
    +    feature = "trace_macros",
    +    issue = "29598",
    +    reason = "`trace_macros` is not stable enough for use and is subject to change"
    +)]
    +#[doc(no_inline)]
    +pub use crate::trace_macros;
    +
     // Do not `doc(no_inline)` so that they become doc items on their own
     // (no public module for them to be re-exported from).
     #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
    diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
    index 5f7097c26e22..78eb79ac666a 100644
    --- a/library/std/src/prelude/mod.rs
    +++ b/library/std/src/prelude/mod.rs
    @@ -54,9 +54,9 @@
     //! * [std::convert]::{[AsRef], [AsMut], [Into], [From]}, generic
     //!   conversions, used by savvy API authors to create overloaded methods.
     //! * [std::default]::[Default], types that have default values.
    -//! * [std::iter]::{[Iterator], [Extend], [IntoIterator], [DoubleEndedIterator], [ExactSizeIterator]},
    -//!   iterators of various
    -//!   kinds.
    +//! * [std::iter]::{[Iterator], [Extend], [IntoIterator], [DoubleEndedIterator],
    +//!   [ExactSizeIterator]}, iterators of various kinds.
    +//! * Most of the standard macros.
     //! * [std::option]::[Option]::{[self][Option], [Some], [None]}, a
     //!   type which expresses the presence or absence of a value. This type is so
     //!   commonly used, its variants are also exported.
    @@ -145,6 +145,11 @@ pub mod rust_2021 {
         #[stable(feature = "prelude_2021", since = "1.55.0")]
         #[doc(no_inline)]
         pub use core::prelude::rust_2021::*;
    +
    +    // There are two different panic macros, one in `core` and one in `std`. They are slightly
    +    // different. For `std` we explicitly want the one defined in `std`.
    +    #[stable(feature = "prelude_2021", since = "1.55.0")]
    +    pub use super::v1::panic;
     }
     
     /// The 2024 version of the prelude of The Rust Standard Library.
    @@ -159,6 +164,11 @@ pub mod rust_2024 {
         #[stable(feature = "prelude_2024", since = "1.85.0")]
         #[doc(no_inline)]
         pub use core::prelude::rust_2024::*;
    +
    +    // There are two different panic macros, one in `core` and one in `std`. They are slightly
    +    // different. For `std` we explicitly want the one defined in `std`.
    +    #[stable(feature = "prelude_2024", since = "1.85.0")]
    +    pub use super::v1::panic;
     }
     
     /// The Future version of the prelude of The Rust Standard Library.
    @@ -174,4 +184,9 @@ pub mod rust_future {
         #[unstable(feature = "prelude_next", issue = "none")]
         #[doc(no_inline)]
         pub use core::prelude::rust_future::*;
    +
    +    // There are two different panic macros, one in `core` and one in `std`. They are slightly
    +    // different. For `std` we explicitly want the one defined in `std`.
    +    #[unstable(feature = "prelude_next", issue = "none")]
    +    pub use super::v1::panic;
     }
    diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs
    index 0f0841379b29..af9d28ebad35 100644
    --- a/library/std/src/prelude/v1.rs
    +++ b/library/std/src/prelude/v1.rs
    @@ -43,15 +43,46 @@ pub use crate::option::Option::{self, None, Some};
     #[doc(no_inline)]
     pub use crate::result::Result::{self, Err, Ok};
     
    -// Re-exported built-in macros
    +// Re-exported built-in macros and traits
     #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
     #[doc(no_inline)]
    +#[expect(deprecated)]
     pub use core::prelude::v1::{
    -    assert, cfg, column, compile_error, concat, env, file, format_args,
    -    format_args_nl, include, include_bytes, include_str, line, log_syntax, module_path, option_env,
    -    stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd,
    +    assert, assert_eq, assert_ne, cfg, column, compile_error, concat, debug_assert, debug_assert_eq,
    +    debug_assert_ne, env, file, format_args, include, include_bytes, include_str, line, matches,
    +    module_path, option_env, stringify, todo, r#try, unimplemented, unreachable, write,
    +    writeln, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd,
     };
     
    +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
    +#[doc(no_inline)]
    +pub use crate::{
    +    dbg, eprint, eprintln, format, is_x86_feature_detected, print, println, thread_local
    +};
    +
    +// These macros need special handling, so that we don't export them *and* the modules of the same
    +// name. We only want the macros in the prelude so we shadow the original modules with private
    +// modules with the same names.
    +mod ambiguous_macros_only {
    +    #[expect(hidden_glob_reexports)]
    +    mod vec {}
    +    #[expect(hidden_glob_reexports)]
    +    mod panic {}
    +    // Building std without the expect exported_private_dependencies will create warnings, but then
    +    // clippy claims its a useless_attribute. So silence both.
    +    #[expect(clippy::useless_attribute)]
    +    #[expect(exported_private_dependencies)]
    +    #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
    +    pub use crate::*;
    +}
    +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
    +#[doc(no_inline)]
    +pub use self::ambiguous_macros_only::{vec, panic};
    +
    +#[unstable(feature = "cfg_select", issue = "115585")]
    +#[doc(no_inline)]
    +pub use core::prelude::v1::cfg_select;
    +
     #[unstable(
         feature = "concat_bytes",
         issue = "87555",
    @@ -60,6 +91,26 @@ pub use core::prelude::v1::{
     #[doc(no_inline)]
     pub use core::prelude::v1::concat_bytes;
     
    +#[unstable(feature = "const_format_args", issue = "none")]
    +#[doc(no_inline)]
    +pub use core::prelude::v1::const_format_args;
    +
    +#[unstable(
    +    feature = "log_syntax",
    +    issue = "29598",
    +    reason = "`log_syntax!` is not stable enough for use and is subject to change"
    +)]
    +#[doc(no_inline)]
    +pub use core::prelude::v1::log_syntax;
    +
    +#[unstable(
    +    feature = "trace_macros",
    +    issue = "29598",
    +    reason = "`trace_macros` is not stable enough for use and is subject to change"
    +)]
    +#[doc(no_inline)]
    +pub use core::prelude::v1::trace_macros;
    +
     // Do not `doc(no_inline)` so that they become doc items on their own
     // (no public module for them to be re-exported from).
     #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
    diff --git a/library/std/src/process.rs b/library/std/src/process.rs
    index 720ba0ad73e2..6838bb422b0e 100644
    --- a/library/std/src/process.rs
    +++ b/library/std/src/process.rs
    @@ -167,7 +167,7 @@ use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
     use crate::num::NonZero;
     use crate::path::Path;
     use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, process as imp};
    -use crate::{fmt, fs, str};
    +use crate::{fmt, format_args_nl, fs, str};
     
     /// Representation of a running or exited child process.
     ///
    diff --git a/tests/pretty/asm.pp b/tests/pretty/asm.pp
    index dca28f99a37d..f1f020a68fb6 100644
    --- a/tests/pretty/asm.pp
    +++ b/tests/pretty/asm.pp
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/autodiff/autodiff_forward.pp b/tests/pretty/autodiff/autodiff_forward.pp
    index ea4e294f1ac3..c64da3f60884 100644
    --- a/tests/pretty/autodiff/autodiff_forward.pp
    +++ b/tests/pretty/autodiff/autodiff_forward.pp
    @@ -3,7 +3,6 @@
     //@ only-nightly
     
     #![feature(autodiff)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/autodiff/autodiff_reverse.pp b/tests/pretty/autodiff/autodiff_reverse.pp
    index 9202e0a76635..61ab121b31bc 100644
    --- a/tests/pretty/autodiff/autodiff_reverse.pp
    +++ b/tests/pretty/autodiff/autodiff_reverse.pp
    @@ -3,7 +3,6 @@
     //@ only-nightly
     
     #![feature(autodiff)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/autodiff/inherent_impl.pp b/tests/pretty/autodiff/inherent_impl.pp
    index bc70c4076121..1c83c66c8edf 100644
    --- a/tests/pretty/autodiff/inherent_impl.pp
    +++ b/tests/pretty/autodiff/inherent_impl.pp
    @@ -3,7 +3,6 @@
     //@ only-nightly
     
     #![feature(autodiff)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/cast-lt.pp b/tests/pretty/cast-lt.pp
    index e82636edca7e..deca38fc0962 100644
    --- a/tests/pretty/cast-lt.pp
    +++ b/tests/pretty/cast-lt.pp
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/delegation-impl-reuse.pp b/tests/pretty/delegation-impl-reuse.pp
    index 72f62de0eacb..6c6c8a594fc8 100644
    --- a/tests/pretty/delegation-impl-reuse.pp
    +++ b/tests/pretty/delegation-impl-reuse.pp
    @@ -6,7 +6,6 @@
     
     #![allow(incomplete_features)]
     #![feature(fn_delegation)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/delegation-inherit-attributes.pp b/tests/pretty/delegation-inherit-attributes.pp
    index 8e30da1ad589..2398cae90fdb 100644
    --- a/tests/pretty/delegation-inherit-attributes.pp
    +++ b/tests/pretty/delegation-inherit-attributes.pp
    @@ -6,7 +6,6 @@
     
     #![allow(incomplete_features)]
     #![feature(fn_delegation)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use std::prelude::rust_2021::*;
    diff --git a/tests/pretty/delegation-inline-attribute.pp b/tests/pretty/delegation-inline-attribute.pp
    index 826d099e8155..5235fd8d0ef2 100644
    --- a/tests/pretty/delegation-inline-attribute.pp
    +++ b/tests/pretty/delegation-inline-attribute.pp
    @@ -4,7 +4,6 @@
     
     #![allow(incomplete_features)]
     #![feature(fn_delegation)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/dollar-crate.pp b/tests/pretty/dollar-crate.pp
    index 31a55ec2bdaa..f7f6e5c3d493 100644
    --- a/tests/pretty/dollar-crate.pp
    +++ b/tests/pretty/dollar-crate.pp
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/expanded-and-path-remap-80832.pp b/tests/pretty/expanded-and-path-remap-80832.pp
    index 6206498e4a2b..d434633b7c4b 100644
    --- a/tests/pretty/expanded-and-path-remap-80832.pp
    +++ b/tests/pretty/expanded-and-path-remap-80832.pp
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/format-args-str-escape.pp b/tests/pretty/format-args-str-escape.pp
    index d0bd7cf0c72a..bf944f445e1c 100644
    --- a/tests/pretty/format-args-str-escape.pp
    +++ b/tests/pretty/format-args-str-escape.pp
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/hir-delegation.pp b/tests/pretty/hir-delegation.pp
    index b5f7a14eb2fc..44a1deb750dc 100644
    --- a/tests/pretty/hir-delegation.pp
    +++ b/tests/pretty/hir-delegation.pp
    @@ -4,7 +4,6 @@
     
     #![allow(incomplete_features)]
     #![feature(fn_delegation)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/hir-fn-params.pp b/tests/pretty/hir-fn-params.pp
    index fb4ea0304e5a..52310d5024cd 100644
    --- a/tests/pretty/hir-fn-params.pp
    +++ b/tests/pretty/hir-fn-params.pp
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/hir-fn-variadic.pp b/tests/pretty/hir-fn-variadic.pp
    index 8cbd8f41b646..6356eec80e0e 100644
    --- a/tests/pretty/hir-fn-variadic.pp
    +++ b/tests/pretty/hir-fn-variadic.pp
    @@ -3,7 +3,6 @@
     //@ pp-exact:hir-fn-variadic.pp
     
     #![feature(c_variadic)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/hir-if-else.pp b/tests/pretty/hir-if-else.pp
    index af5d31b07cb1..d3721e175815 100644
    --- a/tests/pretty/hir-if-else.pp
    +++ b/tests/pretty/hir-if-else.pp
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/hir-lifetimes.pp b/tests/pretty/hir-lifetimes.pp
    index e8b174189130..ceb0f6e3b7c2 100644
    --- a/tests/pretty/hir-lifetimes.pp
    +++ b/tests/pretty/hir-lifetimes.pp
    @@ -5,7 +5,6 @@
     // This tests the pretty-printing of lifetimes in lots of ways.
     
     #![allow(unused)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/hir-pretty-attr.pp b/tests/pretty/hir-pretty-attr.pp
    index 01bfe2c09547..a9d8b5e7e577 100644
    --- a/tests/pretty/hir-pretty-attr.pp
    +++ b/tests/pretty/hir-pretty-attr.pp
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/hir-pretty-loop.pp b/tests/pretty/hir-pretty-loop.pp
    index a0830c5188ad..e6614ce318cc 100644
    --- a/tests/pretty/hir-pretty-loop.pp
    +++ b/tests/pretty/hir-pretty-loop.pp
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/hir-struct-expr.pp b/tests/pretty/hir-struct-expr.pp
    index bb222dc2e5f1..198d7ad6a9b6 100644
    --- a/tests/pretty/hir-struct-expr.pp
    +++ b/tests/pretty/hir-struct-expr.pp
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/if-else.pp b/tests/pretty/if-else.pp
    index f29b693e571e..6ca71a3a3d34 100644
    --- a/tests/pretty/if-else.pp
    +++ b/tests/pretty/if-else.pp
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/issue-12590-c.pp b/tests/pretty/issue-12590-c.pp
    index 0df095b0ee55..b79b73337adb 100644
    --- a/tests/pretty/issue-12590-c.pp
    +++ b/tests/pretty/issue-12590-c.pp
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/issue-4264.pp b/tests/pretty/issue-4264.pp
    index 4eee6655cf6f..568269644bb8 100644
    --- a/tests/pretty/issue-4264.pp
    +++ b/tests/pretty/issue-4264.pp
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/issue-85089.pp b/tests/pretty/issue-85089.pp
    index 28a85bdf4ad8..919573220fdd 100644
    --- a/tests/pretty/issue-85089.pp
    +++ b/tests/pretty/issue-85089.pp
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/never-pattern.pp b/tests/pretty/never-pattern.pp
    index 1ce332ea5064..bb95a1ed442a 100644
    --- a/tests/pretty/never-pattern.pp
    +++ b/tests/pretty/never-pattern.pp
    @@ -7,7 +7,6 @@
     #![allow(incomplete_features)]
     #![feature(never_patterns)]
     #![feature(never_type)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/pin-ergonomics-hir.pp b/tests/pretty/pin-ergonomics-hir.pp
    index 127cb531cece..cf9b6707ed2f 100644
    --- a/tests/pretty/pin-ergonomics-hir.pp
    +++ b/tests/pretty/pin-ergonomics-hir.pp
    @@ -4,7 +4,6 @@
     
     #![feature(pin_ergonomics)]
     #![allow(dead_code, incomplete_features)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/postfix-match/precedence.pp b/tests/pretty/postfix-match/precedence.pp
    index b6ff45daea12..56ee1f1061af 100644
    --- a/tests/pretty/postfix-match/precedence.pp
    +++ b/tests/pretty/postfix-match/precedence.pp
    @@ -1,7 +1,6 @@
     #![feature(prelude_import)]
     #![no_std]
     #![feature(postfix_match)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/shebang-at-top.pp b/tests/pretty/shebang-at-top.pp
    index 197def4a154b..0c19c0c44e45 100644
    --- a/tests/pretty/shebang-at-top.pp
    +++ b/tests/pretty/shebang-at-top.pp
    @@ -1,7 +1,6 @@
     #!/usr/bin/env rust
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/pretty/tests-are-sorted.pp b/tests/pretty/tests-are-sorted.pp
    index 9e1566b2eff3..43f9838e68ce 100644
    --- a/tests/pretty/tests-are-sorted.pp
    +++ b/tests/pretty/tests-are-sorted.pp
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/rustdoc-js-std/println-typo.js b/tests/rustdoc-js-std/println-typo.js
    index a4dd90a44d5b..b91e7883b995 100644
    --- a/tests/rustdoc-js-std/println-typo.js
    +++ b/tests/rustdoc-js-std/println-typo.js
    @@ -6,7 +6,10 @@ const EXPECTED = {
         'query': 'prinltn',
         'others': [
             { 'path': 'std', 'name': 'println' },
    +        { 'path': 'std::prelude::v1', 'name': 'println' },
             { 'path': 'std', 'name': 'print' },
    +        { 'path': 'std::prelude::v1', 'name': 'print' },
             { 'path': 'std', 'name': 'eprintln' },
    +        { 'path': 'std::prelude::v1', 'name': 'eprintln' },
         ],
     };
    diff --git a/tests/ui/asm/unpretty-expanded.stdout b/tests/ui/asm/unpretty-expanded.stdout
    index 7678f6bc3450..ce636c150c1c 100644
    --- a/tests/ui/asm/unpretty-expanded.stdout
    +++ b/tests/ui/asm/unpretty-expanded.stdout
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout
    index 7499df5be5da..c53491a6747c 100644
    --- a/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout
    +++ b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout
    @@ -1,5 +1,4 @@
     #![feature(prelude_import)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use std::prelude::rust_2021::*;
    diff --git a/tests/ui/codemap_tests/unicode.expanded.stdout b/tests/ui/codemap_tests/unicode.expanded.stdout
    index af375108b478..4a29277fe3bf 100644
    --- a/tests/ui/codemap_tests/unicode.expanded.stdout
    +++ b/tests/ui/codemap_tests/unicode.expanded.stdout
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/const-generics/defaults/pretty-printing-ast.stdout b/tests/ui/const-generics/defaults/pretty-printing-ast.stdout
    index 030fcec9cf2a..efd703b24b43 100644
    --- a/tests/ui/const-generics/defaults/pretty-printing-ast.stdout
    +++ b/tests/ui/const-generics/defaults/pretty-printing-ast.stdout
    @@ -6,7 +6,6 @@
     //@ edition: 2015
     
     #![crate_type = "lib"]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/deriving/built-in-proc-macro-scope.stdout b/tests/ui/deriving/built-in-proc-macro-scope.stdout
    index 4fbce5edb819..e2a9119af3d6 100644
    --- a/tests/ui/deriving/built-in-proc-macro-scope.stdout
    +++ b/tests/ui/deriving/built-in-proc-macro-scope.stdout
    @@ -6,7 +6,6 @@
     //@ edition:2015
     
     #![feature(derive_coerce_pointee)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout
    index a40dece22a26..b778eab60596 100644
    --- a/tests/ui/deriving/deriving-all-codegen.stdout
    +++ b/tests/ui/deriving/deriving-all-codegen.stdout
    @@ -18,7 +18,6 @@
     #![allow(dead_code)]
     #![allow(deprecated)]
     #![feature(derive_from)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use std::prelude::rust_2021::*;
    diff --git a/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout b/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout
    index 89300a5c6d0c..ace45c4d760f 100644
    --- a/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout
    +++ b/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout
    @@ -4,7 +4,6 @@
     //@ compile-flags: -Zunpretty=expanded
     //@ edition: 2015
     #![feature(derive_coerce_pointee)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/deriving/proc-macro-attribute-mixing.stdout b/tests/ui/deriving/proc-macro-attribute-mixing.stdout
    index b81110682d68..e82f1780d095 100644
    --- a/tests/ui/deriving/proc-macro-attribute-mixing.stdout
    +++ b/tests/ui/deriving/proc-macro-attribute-mixing.stdout
    @@ -12,7 +12,6 @@
     //@ edition: 2015
     
     #![feature(derive_coerce_pointee)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/feature-gates/feature-gate-format_args_nl.rs b/tests/ui/feature-gates/feature-gate-format_args_nl.rs
    index aeee2fbad907..4749eea13a6d 100644
    --- a/tests/ui/feature-gates/feature-gate-format_args_nl.rs
    +++ b/tests/ui/feature-gates/feature-gate-format_args_nl.rs
    @@ -1,3 +1,5 @@
    +use std::format_args_nl; //~ ERROR `format_args_nl` is only for internal language use
    +
     fn main() {
         format_args_nl!(""); //~ ERROR `format_args_nl` is only for internal language use
     }
    diff --git a/tests/ui/feature-gates/feature-gate-format_args_nl.stderr b/tests/ui/feature-gates/feature-gate-format_args_nl.stderr
    index c7e8f8c686f9..1265bd447f40 100644
    --- a/tests/ui/feature-gates/feature-gate-format_args_nl.stderr
    +++ b/tests/ui/feature-gates/feature-gate-format_args_nl.stderr
    @@ -1,5 +1,5 @@
     error[E0658]: use of unstable library feature `format_args_nl`: `format_args_nl` is only for internal language use and is subject to change
    -  --> $DIR/feature-gate-format_args_nl.rs:2:5
    +  --> $DIR/feature-gate-format_args_nl.rs:4:5
        |
     LL |     format_args_nl!("");
        |     ^^^^^^^^^^^^^^
    @@ -7,6 +7,15 @@ LL |     format_args_nl!("");
        = help: add `#![feature(format_args_nl)]` 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
    +error[E0658]: use of unstable library feature `format_args_nl`: `format_args_nl` is only for internal language use and is subject to change
    +  --> $DIR/feature-gate-format_args_nl.rs:1:5
    +   |
    +LL | use std::format_args_nl;
    +   |     ^^^^^^^^^^^^^^^^^^^
    +   |
    +   = help: add `#![feature(format_args_nl)]` 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 2 previous errors
     
     For more information about this error, try `rustc --explain E0658`.
    diff --git a/tests/ui/hygiene/format-args.rs b/tests/ui/hygiene/format-args.rs
    index ff08aecfd9eb..f845f5d8a4c8 100644
    --- a/tests/ui/hygiene/format-args.rs
    +++ b/tests/ui/hygiene/format-args.rs
    @@ -3,6 +3,8 @@
     #![allow(non_upper_case_globals)]
     #![feature(format_args_nl)]
     
    +use std::format_args_nl;
    +
     static arg0: () = ();
     
     fn main() {
    diff --git a/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.rs b/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.rs
    new file mode 100644
    index 000000000000..6d37fbb7fdea
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.rs
    @@ -0,0 +1,16 @@
    +//@ edition: 2024
    +#![crate_type = "lib"]
    +mod m1 {
    +    pub use core::prelude::v1::*;
    +}
    +
    +mod m2 {
    +    pub use std::prelude::v1::*;
    +}
    +
    +use m2::*;
    +fn foo() {
    +    use m1::*;
    +
    +    panic!(); //~ ERROR: `panic` is ambiguous [E0659]
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.stderr b/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.stderr
    new file mode 100644
    index 000000000000..450a18478092
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.stderr
    @@ -0,0 +1,23 @@
    +error[E0659]: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-glob-vs-multiouter.rs:15:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-glob-vs-multiouter.rs:13:9
    +   |
    +LL |     use m1::*;
    +   |         ^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +note: `panic` could also refer to the macro imported here
    +  --> $DIR/ambiguous-panic-glob-vs-multiouter.rs:11:5
    +   |
    +LL | use m2::*;
    +   |     ^^^^^
    +   = help: use `crate::panic` to refer to this macro unambiguously
    +
    +error: aborting due to 1 previous error
    +
    +For more information about this error, try `rustc --explain E0659`.
    diff --git a/tests/ui/imports/ambiguous-panic-globvsglob.rs b/tests/ui/imports/ambiguous-panic-globvsglob.rs
    new file mode 100644
    index 000000000000..4ff3cc822535
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-globvsglob.rs
    @@ -0,0 +1,23 @@
    +//@ edition: 2024
    +#![crate_type = "lib"]
    +mod m1 {
    +    pub use core::prelude::v1::*;
    +}
    +
    +mod m2 {
    +    pub use std::prelude::v1::*;
    +}
    +
    +fn foo() {
    +    use m1::*;
    +    use m2::*;
    +
    +    // I had hoped that this would not produce the globvsglob error because it would never be
    +    // resolving `panic` via one of the ambiguous glob imports above but it appears to do so, not
    +    // sure why
    +    panic!();
    +    //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports]
    +    //~| WARN: this was previously accepted by the compiler
    +    //~| ERROR: `panic` is ambiguous [ambiguous_glob_imports]
    +    //~| WARN: this was previously accepted by the compiler
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-globvsglob.stderr b/tests/ui/imports/ambiguous-panic-globvsglob.stderr
    new file mode 100644
    index 000000000000..455c58bb6c02
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-globvsglob.stderr
    @@ -0,0 +1,68 @@
    +error: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-globvsglob.rs:18:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +   = note: for more information, see issue #114095 
    +   = note: ambiguous because of multiple glob imports of a name in the same module
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-globvsglob.rs:12:9
    +   |
    +LL |     use m1::*;
    +   |         ^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +note: `panic` could also refer to the macro imported here
    +  --> $DIR/ambiguous-panic-globvsglob.rs:13:9
    +   |
    +LL |     use m2::*;
    +   |         ^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +   = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default
    +
    +warning: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-globvsglob.rs:18:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +   = note: for more information, see issue #147319 
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-globvsglob.rs:12:9
    +   |
    +LL |     use m1::*;
    +   |         ^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    +   = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default
    +
    +error: aborting due to 1 previous error; 1 warning emitted
    +
    +Future incompatibility report: Future breakage diagnostic:
    +error: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-globvsglob.rs:18:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +   = note: for more information, see issue #114095 
    +   = note: ambiguous because of multiple glob imports of a name in the same module
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-globvsglob.rs:12:9
    +   |
    +LL |     use m1::*;
    +   |         ^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +note: `panic` could also refer to the macro imported here
    +  --> $DIR/ambiguous-panic-globvsglob.rs:13:9
    +   |
    +LL |     use m2::*;
    +   |         ^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +   = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default
    +
    diff --git a/tests/ui/imports/ambiguous-panic-no-implicit-prelude.rs b/tests/ui/imports/ambiguous-panic-no-implicit-prelude.rs
    new file mode 100644
    index 000000000000..1239cc67cd39
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-no-implicit-prelude.rs
    @@ -0,0 +1,16 @@
    +//@ edition: 2024
    +#![crate_type = "lib"]
    +#![no_implicit_prelude]
    +
    +mod m1 {
    +    macro_rules! panic {
    +        () => {};
    +    }
    +
    +    pub(crate) use panic;
    +}
    +
    +fn foo() {
    +    use m1::*;
    +    panic!(); //~ERROR: `panic` is ambiguous [E0659]
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-no-implicit-prelude.stderr b/tests/ui/imports/ambiguous-panic-no-implicit-prelude.stderr
    new file mode 100644
    index 000000000000..fa41409acb2c
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-no-implicit-prelude.stderr
    @@ -0,0 +1,19 @@
    +error[E0659]: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-no-implicit-prelude.rs:15:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-no-implicit-prelude.rs:14:9
    +   |
    +LL |     use m1::*;
    +   |         ^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    +
    +error: aborting due to 1 previous error
    +
    +For more information about this error, try `rustc --explain E0659`.
    diff --git a/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.rs b/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.rs
    new file mode 100644
    index 000000000000..e8b6e208c08b
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.rs
    @@ -0,0 +1,11 @@
    +//@ edition: 2024
    +//@ check-pass
    +#![crate_type = "lib"]
    +
    +use ::core::*;
    +
    +fn f() {
    +    panic!();
    +    //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports]
    +    //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.stderr b/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.stderr
    new file mode 100644
    index 000000000000..5317d8d6d312
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.stderr
    @@ -0,0 +1,22 @@
    +warning: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-non-prelude-core-glob.rs:8:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +   = note: for more information, see issue #147319 
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-non-prelude-core-glob.rs:5:5
    +   |
    +LL | use ::core::*;
    +   |     ^^^^^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +   = help: or use `crate::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    +   = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default
    +
    +warning: 1 warning emitted
    +
    diff --git a/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.rs b/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.rs
    new file mode 100644
    index 000000000000..0e63f97ec98a
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.rs
    @@ -0,0 +1,12 @@
    +//@ check-pass
    +#![crate_type = "lib"]
    +#![no_std]
    +
    +extern crate std;
    +use ::std::*;
    +
    +fn f() {
    +    panic!();
    +    //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports]
    +    //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.stderr b/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.stderr
    new file mode 100644
    index 000000000000..b7434e3737b8
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.stderr
    @@ -0,0 +1,22 @@
    +warning: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-non-prelude-std-glob.rs:9:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +   = note: for more information, see issue #147319 
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-non-prelude-std-glob.rs:6:5
    +   |
    +LL | use ::std::*;
    +   |     ^^^^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +   = help: or use `crate::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL
    +   = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default
    +
    +warning: 1 warning emitted
    +
    diff --git a/tests/ui/imports/ambiguous-panic-pick-core.rs b/tests/ui/imports/ambiguous-panic-pick-core.rs
    new file mode 100644
    index 000000000000..bcb8494b10d7
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-pick-core.rs
    @@ -0,0 +1,11 @@
    +//@ edition: 2018
    +//@ check-pass
    +#![crate_type = "lib"]
    +use ::core::prelude::v1::*;
    +
    +fn f() {
    +    panic!(&std::string::String::new());
    +    //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports]
    +    //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +    //~| WARN: panic message is not a string literal [non_fmt_panics]
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-pick-core.stderr b/tests/ui/imports/ambiguous-panic-pick-core.stderr
    new file mode 100644
    index 000000000000..5729311fabd0
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-pick-core.stderr
    @@ -0,0 +1,37 @@
    +warning: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-pick-core.rs:7:5
    +   |
    +LL |     panic!(&std::string::String::new());
    +   |     ^^^^^ ambiguous name
    +   |
    +   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +   = note: for more information, see issue #147319 
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-pick-core.rs:4:5
    +   |
    +LL | use ::core::prelude::v1::*;
    +   |     ^^^^^^^^^^^^^^^^^^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +   = help: or use `crate::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    +   = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default
    +
    +warning: panic message is not a string literal
    +  --> $DIR/ambiguous-panic-pick-core.rs:7:12
    +   |
    +LL |     panic!(&std::string::String::new());
    +   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +   |
    +   = note: for more information, see 
    +   = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
    +   = note: for more information, see 
    +   = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default
    +help: add a "{}" format string to `Display` the message
    +   |
    +LL |     panic!("{}", &std::string::String::new());
    +   |            +++++
    +
    +warning: 2 warnings emitted
    +
    diff --git a/tests/ui/imports/ambiguous-panic-pick-std.rs b/tests/ui/imports/ambiguous-panic-pick-std.rs
    new file mode 100644
    index 000000000000..67b285ee430a
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-pick-std.rs
    @@ -0,0 +1,14 @@
    +//@ edition: 2018
    +//@ check-pass
    +#![crate_type = "lib"]
    +#![no_std]
    +
    +extern crate std;
    +use ::std::prelude::v1::*;
    +
    +fn f() {
    +    panic!(std::string::String::new());
    +    //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports]
    +    //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +    //~| WARN: panic message is not a string literal [non_fmt_panics]
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-pick-std.stderr b/tests/ui/imports/ambiguous-panic-pick-std.stderr
    new file mode 100644
    index 000000000000..1b5b508a7965
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-pick-std.stderr
    @@ -0,0 +1,37 @@
    +warning: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-pick-std.rs:10:5
    +   |
    +LL |     panic!(std::string::String::new());
    +   |     ^^^^^ ambiguous name
    +   |
    +   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +   = note: for more information, see issue #147319 
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-pick-std.rs:7:5
    +   |
    +LL | use ::std::prelude::v1::*;
    +   |     ^^^^^^^^^^^^^^^^^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +   = help: or use `crate::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL
    +   = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default
    +
    +warning: panic message is not a string literal
    +  --> $DIR/ambiguous-panic-pick-std.rs:10:12
    +   |
    +LL |     panic!(std::string::String::new());
    +   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
    +   |
    +   = note: for more information, see 
    +   = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
    +   = note: for more information, see 
    +   = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default
    +help: add a "{}" format string to `Display` the message
    +   |
    +LL |     panic!("{}", std::string::String::new());
    +   |            +++++
    +
    +warning: 2 warnings emitted
    +
    diff --git a/tests/ui/imports/ambiguous-panic-re-emit.rs b/tests/ui/imports/ambiguous-panic-re-emit.rs
    new file mode 100644
    index 000000000000..dd3c0211b3a7
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-re-emit.rs
    @@ -0,0 +1,23 @@
    +#![crate_type = "lib"]
    +#![no_std]
    +
    +macro_rules! re_emit {
    +    ($($i:item)*) => ($($i)*)
    +}
    +
    +// By re-emitting the prelude import via a macro, we run into the delayed bugs code path.
    +re_emit! {
    +    extern crate std;
    +    use std::prelude::v1::*;
    +}
    +
    +fn xx() {
    +    panic!();
    +    //~^ WARNING `panic` is ambiguous
    +    //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +
    +    // We can't deny the above lint, or else it *won't* run into the problematic issue of *not*
    +    // having reported an error. So we crate a dummy error.
    +    let _ = unknown_item;
    +    //~^ ERROR: cannot find value `unknown_item`
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-re-emit.stderr b/tests/ui/imports/ambiguous-panic-re-emit.stderr
    new file mode 100644
    index 000000000000..ca30c54b84fe
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-re-emit.stderr
    @@ -0,0 +1,29 @@
    +error[E0425]: cannot find value `unknown_item` in this scope
    +  --> $DIR/ambiguous-panic-re-emit.rs:21:13
    +   |
    +LL |     let _ = unknown_item;
    +   |             ^^^^^^^^^^^^ not found in this scope
    +
    +warning: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-re-emit.rs:15:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +   = note: for more information, see issue #147319 
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-re-emit.rs:11:9
    +   |
    +LL |     use std::prelude::v1::*;
    +   |         ^^^^^^^^^^^^^^^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +   = help: or use `crate::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL
    +   = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default
    +
    +error: aborting due to 1 previous error; 1 warning emitted
    +
    +For more information about this error, try `rustc --explain E0425`.
    diff --git a/tests/ui/imports/ambiguous-panic-rename-builtin.rs b/tests/ui/imports/ambiguous-panic-rename-builtin.rs
    new file mode 100644
    index 000000000000..63dfa540c2a2
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-rename-builtin.rs
    @@ -0,0 +1,15 @@
    +//@ edition: 2024
    +#![crate_type = "lib"]
    +#![no_std]
    +
    +extern crate std;
    +mod m1 {
    +    pub use std::prelude::v1::env as panic;
    +}
    +use m1::*;
    +
    +fn xx() {
    +    panic!();
    +    //~^ ERROR: `env!()` takes 1 or 2 arguments
    +    //~| ERROR: `panic` is ambiguous [E0659]
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-rename-builtin.stderr b/tests/ui/imports/ambiguous-panic-rename-builtin.stderr
    new file mode 100644
    index 000000000000..146863762eaf
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-rename-builtin.stderr
    @@ -0,0 +1,26 @@
    +error: `env!()` takes 1 or 2 arguments
    +  --> $DIR/ambiguous-panic-rename-builtin.rs:12:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^^^^
    +
    +error[E0659]: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic-rename-builtin.rs:12:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-rename-builtin.rs:9:5
    +   |
    +LL | use m1::*;
    +   |     ^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +   = help: or use `crate::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL
    +
    +error: aborting due to 2 previous errors
    +
    +For more information about this error, try `rustc --explain E0659`.
    diff --git a/tests/ui/imports/ambiguous-panic-rename-panics.rs b/tests/ui/imports/ambiguous-panic-rename-panics.rs
    new file mode 100644
    index 000000000000..fbe23a223c93
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-rename-panics.rs
    @@ -0,0 +1,17 @@
    +//@ edition: 2024
    +#![crate_type = "lib"]
    +
    +mod m1 {
    +    pub use core::prelude::v1::panic as p;
    +}
    +
    +mod m2 {
    +    pub use std::prelude::v1::panic as p;
    +}
    +
    +use m2::*;
    +fn xx() {
    +    use m1::*;
    +
    +    p!(); //~ ERROR: `p` is ambiguous [E0659]
    +}
    diff --git a/tests/ui/imports/ambiguous-panic-rename-panics.stderr b/tests/ui/imports/ambiguous-panic-rename-panics.stderr
    new file mode 100644
    index 000000000000..0838b6bdf2c0
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic-rename-panics.stderr
    @@ -0,0 +1,23 @@
    +error[E0659]: `p` is ambiguous
    +  --> $DIR/ambiguous-panic-rename-panics.rs:16:5
    +   |
    +LL |     p!();
    +   |     ^ ambiguous name
    +   |
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `p` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic-rename-panics.rs:14:9
    +   |
    +LL |     use m1::*;
    +   |         ^^^^^
    +   = help: consider adding an explicit import of `p` to disambiguate
    +note: `p` could also refer to the macro imported here
    +  --> $DIR/ambiguous-panic-rename-panics.rs:12:5
    +   |
    +LL | use m2::*;
    +   |     ^^^^^
    +   = help: use `crate::p` to refer to this macro unambiguously
    +
    +error: aborting due to 1 previous error
    +
    +For more information about this error, try `rustc --explain E0659`.
    diff --git a/tests/ui/imports/ambiguous-panic.rs b/tests/ui/imports/ambiguous-panic.rs
    new file mode 100644
    index 000000000000..5a32fe22f31b
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic.rs
    @@ -0,0 +1,12 @@
    +#![deny(ambiguous_panic_imports)]
    +#![crate_type = "lib"]
    +#![no_std]
    +
    +extern crate std;
    +use std::prelude::v1::*;
    +
    +fn xx() {
    +    panic!();
    +    //~^ ERROR `panic` is ambiguous
    +    //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +}
    diff --git a/tests/ui/imports/ambiguous-panic.stderr b/tests/ui/imports/ambiguous-panic.stderr
    new file mode 100644
    index 000000000000..781424eede48
    --- /dev/null
    +++ b/tests/ui/imports/ambiguous-panic.stderr
    @@ -0,0 +1,26 @@
    +error: `panic` is ambiguous
    +  --> $DIR/ambiguous-panic.rs:9:5
    +   |
    +LL |     panic!();
    +   |     ^^^^^ ambiguous name
    +   |
    +   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    +   = note: for more information, see issue #147319 
    +   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    +note: `panic` could refer to the macro imported here
    +  --> $DIR/ambiguous-panic.rs:6:5
    +   |
    +LL | use std::prelude::v1::*;
    +   |     ^^^^^^^^^^^^^^^^^^^
    +   = help: consider adding an explicit import of `panic` to disambiguate
    +   = help: or use `crate::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL
    +note: the lint level is defined here
    +  --> $DIR/ambiguous-panic.rs:1:9
    +   |
    +LL | #![deny(ambiguous_panic_imports)]
    +   |         ^^^^^^^^^^^^^^^^^^^^^^^
    +
    +error: aborting due to 1 previous error
    +
    diff --git a/tests/ui/imports/glob-shadowing.stderr b/tests/ui/imports/glob-shadowing.stderr
    index 0ce8d4f54f8d..025147d08f01 100644
    --- a/tests/ui/imports/glob-shadowing.stderr
    +++ b/tests/ui/imports/glob-shadowing.stderr
    @@ -5,14 +5,15 @@ LL |         let x = env!("PATH");
        |                 ^^^ ambiguous name
        |
        = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    -   = note: `env` could refer to a macro from prelude
    -note: `env` could also refer to the macro imported here
    +note: `env` could refer to the macro imported here
       --> $DIR/glob-shadowing.rs:9:9
        |
     LL |     use crate::m::*;
        |         ^^^^^^^^^^^
        = help: consider adding an explicit import of `env` to disambiguate
        = help: or use `self::env` to refer to this macro unambiguously
    +note: `env` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
     
     error[E0659]: `env` is ambiguous
       --> $DIR/glob-shadowing.rs:19:21
    @@ -21,13 +22,14 @@ LL |             let x = env!("PATH");
        |                     ^^^ ambiguous name
        |
        = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    -   = note: `env` could refer to a macro from prelude
    -note: `env` could also refer to the macro imported here
    +note: `env` could refer to the macro imported here
       --> $DIR/glob-shadowing.rs:17:13
        |
     LL |         use crate::m::*;
        |             ^^^^^^^^^^^
        = help: consider adding an explicit import of `env` to disambiguate
    +note: `env` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
     
     error[E0659]: `fenv` is ambiguous
       --> $DIR/glob-shadowing.rs:29:21
    diff --git a/tests/ui/imports/local-modularized-tricky-fail-1.stderr b/tests/ui/imports/local-modularized-tricky-fail-1.stderr
    index b5b3be5953f9..0d1a29027845 100644
    --- a/tests/ui/imports/local-modularized-tricky-fail-1.stderr
    +++ b/tests/ui/imports/local-modularized-tricky-fail-1.stderr
    @@ -31,8 +31,7 @@ LL |     panic!();
        |     ^^^^^ ambiguous name
        |
        = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
    -   = note: `panic` could refer to a macro from prelude
    -note: `panic` could also refer to the macro defined here
    +note: `panic` could refer to the macro defined here
       --> $DIR/local-modularized-tricky-fail-1.rs:12:5
        |
     LL | /     macro_rules! panic {
    @@ -43,6 +42,8 @@ LL | |     }
     LL |       define_panic!();
        |       --------------- in this macro invocation
        = help: use `crate::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
        = note: this error originates in the macro `define_panic` (in Nightly builds, run with -Z macro-backtrace for more info)
     
     error[E0659]: `include` is ambiguous
    @@ -52,8 +53,7 @@ LL | include!();
        | ^^^^^^^ ambiguous name
        |
        = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
    -   = note: `include` could refer to a macro from prelude
    -note: `include` could also refer to the macro defined here
    +note: `include` could refer to the macro defined here
       --> $DIR/local-modularized-tricky-fail-1.rs:18:5
        |
     LL | /     macro_rules! include {
    @@ -64,6 +64,8 @@ LL | |     }
     LL |       define_include!();
        |       ----------------- in this macro invocation
        = help: use `crate::include` to refer to this macro unambiguously
    +note: `include` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
        = note: this error originates in the macro `define_include` (in Nightly builds, run with -Z macro-backtrace for more info)
     
     error: aborting due to 3 previous errors
    diff --git a/tests/ui/imports/shadow_builtin_macros.stderr b/tests/ui/imports/shadow_builtin_macros.stderr
    index c828b1193d81..7799fb230d43 100644
    --- a/tests/ui/imports/shadow_builtin_macros.stderr
    +++ b/tests/ui/imports/shadow_builtin_macros.stderr
    @@ -5,14 +5,15 @@ LL |     fn f() { panic!(); }
        |              ^^^^^ ambiguous name
        |
        = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    -   = note: `panic` could refer to a macro from prelude
    -note: `panic` could also refer to the macro imported here
    +note: `panic` could refer to the macro imported here
       --> $DIR/shadow_builtin_macros.rs:14:9
        |
     LL |     use crate::foo::*;
        |         ^^^^^^^^^^^^^
        = help: consider adding an explicit import of `panic` to disambiguate
        = help: or use `self::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
     
     error[E0659]: `panic` is ambiguous
       --> $DIR/shadow_builtin_macros.rs:33:5
    @@ -21,8 +22,7 @@ LL |     panic!();
        |     ^^^^^ ambiguous name
        |
        = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
    -   = note: `panic` could refer to a macro from prelude
    -note: `panic` could also refer to the macro defined here
    +note: `panic` could refer to the macro defined here
       --> $DIR/shadow_builtin_macros.rs:30:9
        |
     LL |         macro_rules! panic { () => {} }
    @@ -30,6 +30,8 @@ LL |         macro_rules! panic { () => {} }
     LL |     } }
     LL |     m!();
        |     ---- in this macro invocation
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
        = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
     
     error[E0659]: `n` is ambiguous
    @@ -59,13 +61,14 @@ LL |     fn f() { panic!(); }
        |              ^^^^^ ambiguous name
        |
        = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
    -   = note: `panic` could refer to a macro from prelude
    -note: `panic` could also refer to the macro imported here
    +note: `panic` could refer to the macro imported here
       --> $DIR/shadow_builtin_macros.rs:19:26
        |
     LL |     ::two_macros::m!(use crate::foo::panic;);
        |                          ^^^^^^^^^^^^^^^^^
        = help: use `self::panic` to refer to this macro unambiguously
    +note: `panic` could also refer to a macro from prelude
    +  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
     
     error: aborting due to 4 previous errors
     
    diff --git a/tests/ui/lint/dead-code/with-core-crate.rs b/tests/ui/lint/dead-code/with-core-crate.rs
    index 0a94b528f333..9ccb6aecb75f 100644
    --- a/tests/ui/lint/dead-code/with-core-crate.rs
    +++ b/tests/ui/lint/dead-code/with-core-crate.rs
    @@ -1,7 +1,6 @@
     #![deny(dead_code)]
     #![allow(unreachable_code)]
     
    -#[macro_use]
     extern crate core;
     
     fn foo() { //~ ERROR function `foo` is never used
    diff --git a/tests/ui/lint/dead-code/with-core-crate.stderr b/tests/ui/lint/dead-code/with-core-crate.stderr
    index f466a616580c..9db26c956298 100644
    --- a/tests/ui/lint/dead-code/with-core-crate.stderr
    +++ b/tests/ui/lint/dead-code/with-core-crate.stderr
    @@ -1,5 +1,5 @@
     error: function `foo` is never used
    -  --> $DIR/with-core-crate.rs:7:4
    +  --> $DIR/with-core-crate.rs:6:4
        |
     LL | fn foo() {
        |    ^^^
    diff --git a/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout b/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout
    index 80abac44ca84..0fcfc936a59b 100644
    --- a/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout
    +++ b/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout
    index ba93384644d5..6e41432ad7df 100644
    --- a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout
    +++ b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout
    index e29655faabe5..d47f733d40ed 100644
    --- a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout
    +++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout
    @@ -5,7 +5,6 @@
     //@ edition: 2015
     
     #![feature(core_intrinsics, generic_assert)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/match/issue-82392.stdout b/tests/ui/match/issue-82392.stdout
    index d7eef0497392..d44ffbe21671 100644
    --- a/tests/ui/match/issue-82392.stdout
    +++ b/tests/ui/match/issue-82392.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout
    index 452598c372c1..b5db9922b31a 100644
    --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout
    +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout
    @@ -16,7 +16,6 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro
     // in the stdout
     
     #![no_std /* 0#0 */]
    -#[macro_use /* 0#1 */]
     extern crate core /* 0#1 */;
     #[prelude_import /* 0#1 */]
     use core /* 0#1 */::prelude /* 0#1 */::rust_2018 /* 0#1 */::*;
    diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
    index e10a5199f179..e45abab03b4c 100644
    --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
    +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
    @@ -36,7 +36,6 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
     
     #![feature /* 0#0 */(decl_macro)]
     #![no_std /* 0#0 */]
    -#[macro_use /* 0#1 */]
     extern crate core /* 0#2 */;
     #[prelude_import /* 0#1 */]
     use ::core /* 0#1 */::prelude /* 0#1 */::rust_2015 /* 0#1 */::*;
    diff --git a/tests/ui/proc-macro/quote/debug.stdout b/tests/ui/proc-macro/quote/debug.stdout
    index 77c52f02a33c..896c809fedab 100644
    --- a/tests/ui/proc-macro/quote/debug.stdout
    +++ b/tests/ui/proc-macro/quote/debug.stdout
    @@ -12,7 +12,6 @@
     
     #![feature(proc_macro_quote)]
     #![crate_type = "proc-macro"]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-pretty-check.stdout b/tests/ui/rfcs/rfc-2497-if-let-chains/ast-pretty-check.stdout
    index 66ba726fb9a4..9a34d6c1af7a 100644
    --- a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-pretty-check.stdout
    +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/ast-pretty-check.stdout
    @@ -1,6 +1,5 @@
     #![feature(prelude_import)]
     #![no_std]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr
    index f2fcb98cb6a9..a91a15bc63df 100644
    --- a/tests/ui/stats/input-stats.stderr
    +++ b/tests/ui/stats/input-stats.stderr
    @@ -15,7 +15,7 @@ ast-stats - Ptr                       64 (NN.N%)             1
     ast-stats - Ref                       64 (NN.N%)             1
     ast-stats - ImplicitSelf             128 (NN.N%)             2
     ast-stats - Path                     640 (NN.N%)            10
    -ast-stats PathSegment              888 (NN.N%)            37            24
    +ast-stats PathSegment              864 (NN.N%)            36            24
     ast-stats Expr                     648 (NN.N%)             9            72
     ast-stats - InlineAsm                 72 (NN.N%)             1
     ast-stats - Match                     72 (NN.N%)             1
    @@ -41,9 +41,9 @@ ast-stats - Let                       32 (NN.N%)             1
     ast-stats - Semi                      32 (NN.N%)             1
     ast-stats - Expr                      96 (NN.N%)             3
     ast-stats Param                    160 (NN.N%)             4            40
    -ast-stats Attribute                160 (NN.N%)             5            32
    +ast-stats Attribute                128 (NN.N%)             4            32
     ast-stats - DocComment                32 (NN.N%)             1
    -ast-stats - Normal                   128 (NN.N%)             4
    +ast-stats - Normal                    96 (NN.N%)             3
     ast-stats InlineAsm                120 (NN.N%)             1           120
     ast-stats FnDecl                   120 (NN.N%)             5            24
     ast-stats Local                     96 (NN.N%)             1            96
    @@ -57,7 +57,7 @@ ast-stats GenericArgs               40 (NN.N%)             1            40
     ast-stats - AngleBracketed            40 (NN.N%)             1
     ast-stats Crate                     40 (NN.N%)             1            40
     ast-stats ----------------------------------------------------------------
    -ast-stats Total                  7_616                   129
    +ast-stats Total                  7_560                   127
     ast-stats ================================================================
     hir-stats ================================================================
     hir-stats HIR STATS: input_stats
    @@ -93,7 +93,7 @@ hir-stats GenericParam             400 (NN.N%)             5            80
     hir-stats Block                    288 (NN.N%)             6            48
     hir-stats GenericBound             256 (NN.N%)             4            64
     hir-stats - Trait                    256 (NN.N%)             4
    -hir-stats Attribute                200 (NN.N%)             5            40
    +hir-stats Attribute                160 (NN.N%)             4            40
     hir-stats Variant                  144 (NN.N%)             2            72
     hir-stats GenericArgs              144 (NN.N%)             3            48
     hir-stats FieldDef                 128 (NN.N%)             2            64
    @@ -119,5 +119,5 @@ hir-stats TraitItemId                8 (NN.N%)             2             4
     hir-stats ImplItemId                 8 (NN.N%)             2             4
     hir-stats ForeignItemId              4 (NN.N%)             1             4
     hir-stats ----------------------------------------------------------------
    -hir-stats Total                  8_616                   173
    +hir-stats Total                  8_576                   172
     hir-stats ================================================================
    diff --git a/tests/ui/type-alias-impl-trait/issue-60662.stdout b/tests/ui/type-alias-impl-trait/issue-60662.stdout
    index 7ad29c88bcfe..d1f337819f8b 100644
    --- a/tests/ui/type-alias-impl-trait/issue-60662.stdout
    +++ b/tests/ui/type-alias-impl-trait/issue-60662.stdout
    @@ -3,7 +3,6 @@
     //@ edition: 2015
     
     #![feature(type_alias_impl_trait)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/unpretty/bad-literal.stdout b/tests/ui/unpretty/bad-literal.stdout
    index 1f697aff27c9..267d59a868e4 100644
    --- a/tests/ui/unpretty/bad-literal.stdout
    +++ b/tests/ui/unpretty/bad-literal.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/unpretty/debug-fmt-hir.stdout b/tests/ui/unpretty/debug-fmt-hir.stdout
    index 9c79421e32ab..342dc144909c 100644
    --- a/tests/ui/unpretty/debug-fmt-hir.stdout
    +++ b/tests/ui/unpretty/debug-fmt-hir.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout
    index 26cc74c11604..0b0f17d55666 100644
    --- a/tests/ui/unpretty/deprecated-attr.stdout
    +++ b/tests/ui/unpretty/deprecated-attr.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/unpretty/diagnostic-attr.stdout b/tests/ui/unpretty/diagnostic-attr.stdout
    index 4822cf4700b9..80cd11753493 100644
    --- a/tests/ui/unpretty/diagnostic-attr.stdout
    +++ b/tests/ui/unpretty/diagnostic-attr.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/unpretty/exhaustive-asm.expanded.stdout b/tests/ui/unpretty/exhaustive-asm.expanded.stdout
    index 9a58e4c2877b..9b3c60b03ba7 100644
    --- a/tests/ui/unpretty/exhaustive-asm.expanded.stdout
    +++ b/tests/ui/unpretty/exhaustive-asm.expanded.stdout
    @@ -1,5 +1,4 @@
     #![feature(prelude_import)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use std::prelude::rust_2024::*;
    diff --git a/tests/ui/unpretty/exhaustive-asm.hir.stdout b/tests/ui/unpretty/exhaustive-asm.hir.stdout
    index b33b38c2caba..ed98191e1dd5 100644
    --- a/tests/ui/unpretty/exhaustive-asm.hir.stdout
    +++ b/tests/ui/unpretty/exhaustive-asm.hir.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use std::prelude::rust_2024::*;
    diff --git a/tests/ui/unpretty/exhaustive.expanded.stdout b/tests/ui/unpretty/exhaustive.expanded.stdout
    index 1fc9e6a72693..f555904e5dd7 100644
    --- a/tests/ui/unpretty/exhaustive.expanded.stdout
    +++ b/tests/ui/unpretty/exhaustive.expanded.stdout
    @@ -31,7 +31,6 @@
     #![feature(try_blocks_heterogeneous)]
     #![feature(yeet_expr)]
     #![allow(incomplete_features)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use std::prelude::rust_2024::*;
    diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout
    index 9396e937d843..f309aa0b5fb6 100644
    --- a/tests/ui/unpretty/exhaustive.hir.stdout
    +++ b/tests/ui/unpretty/exhaustive.hir.stdout
    @@ -30,7 +30,6 @@
     #![feature(try_blocks_heterogeneous)]
     #![feature(yeet_expr)]
     #![allow(incomplete_features)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use std::prelude::rust_2024::*;
    diff --git a/tests/ui/unpretty/flattened-format-args.stdout b/tests/ui/unpretty/flattened-format-args.stdout
    index 5c7866dcf39f..156dcd68a674 100644
    --- a/tests/ui/unpretty/flattened-format-args.stdout
    +++ b/tests/ui/unpretty/flattened-format-args.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/unpretty/interpolation-expanded.stdout b/tests/ui/unpretty/interpolation-expanded.stdout
    index 7284a89e7a9b..d385a021ed57 100644
    --- a/tests/ui/unpretty/interpolation-expanded.stdout
    +++ b/tests/ui/unpretty/interpolation-expanded.stdout
    @@ -10,7 +10,6 @@
     // synthesizing parentheses indiscriminately; only where necessary.
     
     #![feature(if_let_guard)]
    -#[macro_use]
     extern crate std;
     #[prelude_import]
     use std::prelude::rust_2024::*;
    diff --git a/tests/ui/unpretty/let-else-hir.stdout b/tests/ui/unpretty/let-else-hir.stdout
    index 14270a572027..cc19f392c3a4 100644
    --- a/tests/ui/unpretty/let-else-hir.stdout
    +++ b/tests/ui/unpretty/let-else-hir.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/unpretty/self-hir.stdout b/tests/ui/unpretty/self-hir.stdout
    index b190565dcc47..c973e143275c 100644
    --- a/tests/ui/unpretty/self-hir.stdout
    +++ b/tests/ui/unpretty/self-hir.stdout
    @@ -1,4 +1,3 @@
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout
    index fc0fbe8ef237..8b6ca4f672dc 100644
    --- a/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout
    +++ b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout
    @@ -4,7 +4,6 @@
     #![feature(min_generic_const_args, adt_const_params)]
     #![expect(incomplete_features)]
     #![allow(dead_code)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    diff --git a/tests/ui/unpretty/unpretty-expr-fn-arg.stdout b/tests/ui/unpretty/unpretty-expr-fn-arg.stdout
    index c04909a73613..41d62d11aaa6 100644
    --- a/tests/ui/unpretty/unpretty-expr-fn-arg.stdout
    +++ b/tests/ui/unpretty/unpretty-expr-fn-arg.stdout
    @@ -8,7 +8,6 @@
     //@ compile-flags: -Zunpretty=hir,typed
     //@ edition: 2015
     #![allow(dead_code)]
    -#[attr = MacroUse {arguments: UseAll}]
     extern crate std;
     #[prelude_import]
     use ::std::prelude::rust_2015::*;
    
    From ef9cbadc433ede9334ae9a9461e65fed4e90f9c2 Mon Sep 17 00:00:00 2001
    From: vsriram 
    Date: Tue, 13 Jan 2026 13:31:54 +0530
    Subject: [PATCH 2057/3801] ui: add regression test for macro resolution ICE
    
    ---
     tests/ui/resolve/decl-macro-use-no-ice.rs     | 20 ++++++++
     tests/ui/resolve/decl-macro-use-no-ice.stderr | 47 +++++++++++++++++++
     2 files changed, 67 insertions(+)
     create mode 100644 tests/ui/resolve/decl-macro-use-no-ice.rs
     create mode 100644 tests/ui/resolve/decl-macro-use-no-ice.stderr
    
    diff --git a/tests/ui/resolve/decl-macro-use-no-ice.rs b/tests/ui/resolve/decl-macro-use-no-ice.rs
    new file mode 100644
    index 000000000000..39b9cb03fea0
    --- /dev/null
    +++ b/tests/ui/resolve/decl-macro-use-no-ice.rs
    @@ -0,0 +1,20 @@
    +//@ edition: 2024
    +#![feature(decl_macro)]
    +
    +// Regression test for issue 
    +// The compiler previously ICE'd during identifier resolution
    +// involving `macro` items and `use` inside a public macro.
    +
    +
    +mod foo {
    +    macro f() {}
    +
    +    pub macro m() {
    +        use f;  //~ ERROR `f` is private, and cannot be re-exported
    +        f!();   //~ ERROR macro import `f` is private
    +    }
    +}
    +
    +fn main() {
    +    foo::m!();
    +}
    diff --git a/tests/ui/resolve/decl-macro-use-no-ice.stderr b/tests/ui/resolve/decl-macro-use-no-ice.stderr
    new file mode 100644
    index 000000000000..9fb75b48b428
    --- /dev/null
    +++ b/tests/ui/resolve/decl-macro-use-no-ice.stderr
    @@ -0,0 +1,47 @@
    +error[E0364]: `f` is private, and cannot be re-exported
    +  --> $DIR/decl-macro-use-no-ice.rs:13:13
    +   |
    +LL |         use f;
    +   |             ^
    +...
    +LL |     foo::m!();
    +   |     --------- in this macro invocation
    +   |
    +note: consider marking `f` as `pub` in the imported module
    +  --> $DIR/decl-macro-use-no-ice.rs:13:13
    +   |
    +LL |         use f;
    +   |             ^
    +...
    +LL |     foo::m!();
    +   |     --------- in this macro invocation
    +   = note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info)
    +
    +error[E0603]: macro import `f` is private
    +  --> $DIR/decl-macro-use-no-ice.rs:14:9
    +   |
    +LL |         f!();
    +   |         ^ private macro import
    +...
    +LL |     foo::m!();
    +   |     --------- in this macro invocation
    +   |
    +note: the macro import `f` is defined here...
    +  --> $DIR/decl-macro-use-no-ice.rs:13:13
    +   |
    +LL |         use f;
    +   |             ^
    +...
    +LL |     foo::m!();
    +   |     --------- in this macro invocation
    +note: ...and refers to the macro `f` which is defined here
    +  --> $DIR/decl-macro-use-no-ice.rs:10:5
    +   |
    +LL |     macro f() {}
    +   |     ^^^^^^^^^
    +   = note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info)
    +
    +error: aborting due to 2 previous errors
    +
    +Some errors have detailed explanations: E0364, E0603.
    +For more information about an error, try `rustc --explain E0364`.
    
    From 62849e64412e3dd9f7fba08881a6fab92aadadc3 Mon Sep 17 00:00:00 2001
    From: Guillaume Gomez 
    Date: Tue, 13 Jan 2026 10:22:34 +0100
    Subject: [PATCH 2058/3801] Reduce flakyness for
     `tests/rustdoc-gui/notable-trait.goml`
    
    ---
     tests/rustdoc-gui/notable-trait.goml | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml
    index 839988021fce..8e4c180e0ef1 100644
    --- a/tests/rustdoc-gui/notable-trait.goml
    +++ b/tests/rustdoc-gui/notable-trait.goml
    @@ -250,7 +250,7 @@ set-window-size: (1100, 600)
     reload:
     assert-count: ("//*[@class='tooltip popover']", 0)
     click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']"
    -assert-count: ("//*[@class='tooltip popover']", 1)
    +wait-for-count: ("//*[@class='tooltip popover']", 1)
     call-function: ("open-settings-menu", {})
    -assert-count: ("//*[@class='tooltip popover']", 0)
    +wait-for-count: ("//*[@class='tooltip popover']", 0)
     assert-false: "#method\.create_an_iterator_from_read .tooltip:focus"
    
    From e259373ce9eca5a10201d74a016a4a2e7ab42ed7 Mon Sep 17 00:00:00 2001
    From: joboet 
    Date: Tue, 6 Jan 2026 13:38:27 +0100
    Subject: [PATCH 2059/3801] std: move `errno` and related functions into
     `sys::io`
    
    ---
     library/std/src/io/error.rs                   |  12 +-
     library/std/src/io/error/tests.rs             |   3 +-
     library/std/src/sys/exit_guard.rs             |   2 +-
     library/std/src/sys/fs/unix.rs                |   4 +-
     library/std/src/sys/io/error/generic.rs       |  15 ++
     library/std/src/sys/io/error/hermit.rs        |  35 ++++
     library/std/src/sys/io/error/mod.rs           |  55 ++++++
     library/std/src/sys/io/error/motor.rs         |  67 +++++++
     library/std/src/sys/io/error/sgx.rs           |  65 ++++++
     library/std/src/sys/io/error/solid.rs         |  19 ++
     library/std/src/sys/io/error/teeos.rs         |  64 ++++++
     library/std/src/sys/io/error/uefi.rs          | 104 ++++++++++
     library/std/src/sys/io/error/unix.rs          | 186 ++++++++++++++++++
     library/std/src/sys/io/error/wasi.rs          |  80 ++++++++
     library/std/src/sys/io/error/windows.rs       | 140 +++++++++++++
     library/std/src/sys/io/error/xous.rs          |  17 ++
     library/std/src/sys/io/mod.rs                 |  20 +-
     .../std/src/sys/net/connection/socket/unix.rs |   2 +-
     library/std/src/sys/net/hostname/unix.rs      |   2 +-
     library/std/src/sys/pal/hermit/mod.rs         |  33 +---
     library/std/src/sys/pal/hermit/os.rs          |   8 -
     library/std/src/sys/pal/motor/mod.rs          |  39 ----
     library/std/src/sys/pal/motor/os.rs           |  29 ---
     library/std/src/sys/pal/sgx/mod.rs            |  50 -----
     library/std/src/sys/pal/sgx/os.rs             |  18 +-
     library/std/src/sys/pal/solid/mod.rs          |   9 -
     library/std/src/sys/pal/solid/os.rs           |  10 +-
     library/std/src/sys/pal/teeos/mod.rs          |  55 ------
     library/std/src/sys/pal/teeos/os.rs           |   8 -
     library/std/src/sys/pal/uefi/mod.rs           |  50 -----
     library/std/src/sys/pal/uefi/os.rs            |  53 -----
     library/std/src/sys/pal/unix/futex.rs         |   6 +-
     library/std/src/sys/pal/unix/mod.rs           |  61 +-----
     library/std/src/sys/pal/unix/os.rs            | 127 ------------
     .../pal/unix/stack_overflow/thread_info.rs    |   2 +-
     library/std/src/sys/pal/unsupported/common.rs |   8 -
     library/std/src/sys/pal/unsupported/os.rs     |   8 -
     library/std/src/sys/pal/vexos/mod.rs          |   4 +-
     library/std/src/sys/pal/vexos/os.rs           |   4 +-
     library/std/src/sys/pal/wasi/helpers.rs       |  56 +-----
     library/std/src/sys/pal/wasi/mod.rs           |   2 +-
     library/std/src/sys/pal/wasi/os.rs            |  30 +--
     library/std/src/sys/pal/windows/mod.rs        |  78 --------
     library/std/src/sys/pal/windows/os.rs         |  60 ------
     library/std/src/sys/pal/xous/os.rs            |   9 -
     library/std/src/sys/pal/zkvm/mod.rs           |   8 -
     library/std/src/sys/pal/zkvm/os.rs            |   8 -
     library/std/src/sys/process/uefi.rs           |   2 +-
     library/std/src/sys/process/unix/common.rs    |   2 +-
     library/std/src/sys/process/unix/unix.rs      |   2 +-
     library/std/src/sys/random/linux.rs           |   2 +-
     library/std/src/sys/sync/condvar/windows7.rs  |   4 +-
     library/std/src/sys/thread/unix.rs            |   9 +-
     53 files changed, 900 insertions(+), 846 deletions(-)
     create mode 100644 library/std/src/sys/io/error/generic.rs
     create mode 100644 library/std/src/sys/io/error/hermit.rs
     create mode 100644 library/std/src/sys/io/error/mod.rs
     create mode 100644 library/std/src/sys/io/error/motor.rs
     create mode 100644 library/std/src/sys/io/error/sgx.rs
     create mode 100644 library/std/src/sys/io/error/solid.rs
     create mode 100644 library/std/src/sys/io/error/teeos.rs
     create mode 100644 library/std/src/sys/io/error/uefi.rs
     create mode 100644 library/std/src/sys/io/error/unix.rs
     create mode 100644 library/std/src/sys/io/error/wasi.rs
     create mode 100644 library/std/src/sys/io/error/windows.rs
     create mode 100644 library/std/src/sys/io/error/xous.rs
    
    diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
    index 528eb185df08..b19087e7424a 100644
    --- a/library/std/src/io/error.rs
    +++ b/library/std/src/io/error.rs
    @@ -653,7 +653,7 @@ impl Error {
         #[must_use]
         #[inline]
         pub fn last_os_error() -> Error {
    -        Error::from_raw_os_error(sys::os::errno())
    +        Error::from_raw_os_error(sys::io::errno())
         }
     
         /// Creates a new instance of an [`Error`] from a particular OS error code.
    @@ -1004,7 +1004,7 @@ impl Error {
         #[inline]
         pub fn kind(&self) -> ErrorKind {
             match self.repr.data() {
    -            ErrorData::Os(code) => sys::decode_error_kind(code),
    +            ErrorData::Os(code) => sys::io::decode_error_kind(code),
                 ErrorData::Custom(c) => c.kind,
                 ErrorData::Simple(kind) => kind,
                 ErrorData::SimpleMessage(m) => m.kind,
    @@ -1014,7 +1014,7 @@ impl Error {
         #[inline]
         pub(crate) fn is_interrupted(&self) -> bool {
             match self.repr.data() {
    -            ErrorData::Os(code) => sys::is_interrupted(code),
    +            ErrorData::Os(code) => sys::io::is_interrupted(code),
                 ErrorData::Custom(c) => c.kind == ErrorKind::Interrupted,
                 ErrorData::Simple(kind) => kind == ErrorKind::Interrupted,
                 ErrorData::SimpleMessage(m) => m.kind == ErrorKind::Interrupted,
    @@ -1028,8 +1028,8 @@ impl fmt::Debug for Repr {
                 ErrorData::Os(code) => fmt
                     .debug_struct("Os")
                     .field("code", &code)
    -                .field("kind", &sys::decode_error_kind(code))
    -                .field("message", &sys::os::error_string(code))
    +                .field("kind", &sys::io::decode_error_kind(code))
    +                .field("message", &sys::io::error_string(code))
                     .finish(),
                 ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
                 ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
    @@ -1047,7 +1047,7 @@ impl fmt::Display for Error {
         fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
             match self.repr.data() {
                 ErrorData::Os(code) => {
    -                let detail = sys::os::error_string(code);
    +                let detail = sys::io::error_string(code);
                     write!(fmt, "{detail} (os error {code})")
                 }
                 ErrorData::Custom(ref c) => c.error.fmt(fmt),
    diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs
    index 3e4029768eb8..eef44c6ac3b6 100644
    --- a/library/std/src/io/error/tests.rs
    +++ b/library/std/src/io/error/tests.rs
    @@ -1,7 +1,6 @@
     use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error};
     use crate::assert_matches::assert_matches;
    -use crate::sys::decode_error_kind;
    -use crate::sys::os::error_string;
    +use crate::sys::io::{decode_error_kind, error_string};
     use crate::{error, fmt};
     
     #[test]
    diff --git a/library/std/src/sys/exit_guard.rs b/library/std/src/sys/exit_guard.rs
    index 00b91842e9db..e7d7a478a5ba 100644
    --- a/library/std/src/sys/exit_guard.rs
    +++ b/library/std/src/sys/exit_guard.rs
    @@ -34,7 +34,7 @@ cfg_select! {
                 // lifetime of the thread. Additionally, accesses to `errno` are
                 // async-signal-safe, so this function is available in all imaginable
                 // circumstances.
    -            let this_thread_id = crate::sys::os::errno_location();
    +            let this_thread_id = crate::sys::io::errno_location();
                 match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
                     Ok(_) => {
                         // This is the first thread to call `unique_thread_exit`,
    diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
    index 1cc2edd0cf47..716ca9783d1f 100644
    --- a/library/std/src/sys/fs/unix.rs
    +++ b/library/std/src/sys/fs/unix.rs
    @@ -726,7 +726,7 @@ impl Iterator for ReadDir {
             target_os = "wasi",
         ))]
         fn next(&mut self) -> Option> {
    -        use crate::sys::os::{errno, set_errno};
    +        use crate::sys::io::{errno, set_errno};
     
             if self.end_of_stream {
                 return None;
    @@ -864,7 +864,7 @@ impl Iterator for ReadDir {
     /// The downside is that it costs an extra syscall, so we only do it for debug.
     #[inline]
     pub(crate) fn debug_assert_fd_is_open(fd: RawFd) {
    -    use crate::sys::os::errno;
    +    use crate::sys::io::errno;
     
         // this is similar to assert_unsafe_precondition!() but it doesn't require const
         if core::ub_checks::check_library_ub() {
    diff --git a/library/std/src/sys/io/error/generic.rs b/library/std/src/sys/io/error/generic.rs
    new file mode 100644
    index 000000000000..fc70fbaba7e8
    --- /dev/null
    +++ b/library/std/src/sys/io/error/generic.rs
    @@ -0,0 +1,15 @@
    +pub fn errno() -> i32 {
    +    0
    +}
    +
    +pub fn is_interrupted(_code: i32) -> bool {
    +    false
    +}
    +
    +pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
    +    crate::io::ErrorKind::Uncategorized
    +}
    +
    +pub fn error_string(_errno: i32) -> String {
    +    "operation successful".to_string()
    +}
    diff --git a/library/std/src/sys/io/error/hermit.rs b/library/std/src/sys/io/error/hermit.rs
    new file mode 100644
    index 000000000000..5f42144bb7cf
    --- /dev/null
    +++ b/library/std/src/sys/io/error/hermit.rs
    @@ -0,0 +1,35 @@
    +use crate::io;
    +
    +pub fn errno() -> i32 {
    +    unsafe { hermit_abi::get_errno() }
    +}
    +
    +#[inline]
    +pub fn is_interrupted(errno: i32) -> bool {
    +    errno == hermit_abi::errno::EINTR
    +}
    +
    +pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
    +    match errno {
    +        hermit_abi::errno::EACCES => io::ErrorKind::PermissionDenied,
    +        hermit_abi::errno::EADDRINUSE => io::ErrorKind::AddrInUse,
    +        hermit_abi::errno::EADDRNOTAVAIL => io::ErrorKind::AddrNotAvailable,
    +        hermit_abi::errno::EAGAIN => io::ErrorKind::WouldBlock,
    +        hermit_abi::errno::ECONNABORTED => io::ErrorKind::ConnectionAborted,
    +        hermit_abi::errno::ECONNREFUSED => io::ErrorKind::ConnectionRefused,
    +        hermit_abi::errno::ECONNRESET => io::ErrorKind::ConnectionReset,
    +        hermit_abi::errno::EEXIST => io::ErrorKind::AlreadyExists,
    +        hermit_abi::errno::EINTR => io::ErrorKind::Interrupted,
    +        hermit_abi::errno::EINVAL => io::ErrorKind::InvalidInput,
    +        hermit_abi::errno::ENOENT => io::ErrorKind::NotFound,
    +        hermit_abi::errno::ENOTCONN => io::ErrorKind::NotConnected,
    +        hermit_abi::errno::EPERM => io::ErrorKind::PermissionDenied,
    +        hermit_abi::errno::EPIPE => io::ErrorKind::BrokenPipe,
    +        hermit_abi::errno::ETIMEDOUT => io::ErrorKind::TimedOut,
    +        _ => io::ErrorKind::Uncategorized,
    +    }
    +}
    +
    +pub fn error_string(errno: i32) -> String {
    +    hermit_abi::error_string(errno).to_string()
    +}
    diff --git a/library/std/src/sys/io/error/mod.rs b/library/std/src/sys/io/error/mod.rs
    new file mode 100644
    index 000000000000..d7a0b9b4b301
    --- /dev/null
    +++ b/library/std/src/sys/io/error/mod.rs
    @@ -0,0 +1,55 @@
    +cfg_select! {
    +    target_os = "hermit" => {
    +        mod hermit;
    +        pub use hermit::*;
    +    }
    +    target_os = "motor" => {
    +        mod motor;
    +        pub use motor::*;
    +    }
    +    all(target_vendor = "fortanix", target_env = "sgx") => {
    +        mod sgx;
    +        pub use sgx::*;
    +    }
    +    target_os = "solid_asp3" => {
    +        mod solid;
    +        pub use solid::*;
    +    }
    +    target_os = "teeos" => {
    +        mod teeos;
    +        pub use teeos::*;
    +    }
    +    target_os = "uefi" => {
    +        mod uefi;
    +        pub use uefi::*;
    +    }
    +    target_family = "unix" => {
    +        mod unix;
    +        pub use unix::*;
    +    }
    +    target_os = "wasi" => {
    +        mod wasi;
    +        pub use wasi::*;
    +    }
    +    target_os = "windows" => {
    +        mod windows;
    +        pub use windows::*;
    +    }
    +    target_os = "xous" => {
    +        mod xous;
    +        pub use xous::*;
    +    }
    +    any(
    +        target_os = "vexos",
    +        target_family = "wasm",
    +        target_os = "zkvm",
    +    ) => {
    +        mod generic;
    +        pub use generic::*;
    +    }
    +}
    +
    +pub type RawOsError = cfg_select! {
    +    target_os = "uefi" => usize,
    +    _ => i32,
    +};
    diff --git a/library/std/src/sys/io/error/motor.rs b/library/std/src/sys/io/error/motor.rs
    new file mode 100644
    index 000000000000..7d612d817cdd
    --- /dev/null
    +++ b/library/std/src/sys/io/error/motor.rs
    @@ -0,0 +1,67 @@
    +use crate::io;
    +use crate::sys::io::RawOsError;
    +
    +pub fn errno() -> RawOsError {
    +    // Not used in Motor OS because it is ambiguous: Motor OS
    +    // is micro-kernel-based, and I/O happens via a shared-memory
    +    // ring buffer, so an I/O operation that on a unix is a syscall
    +    // may involve no sycalls on Motor OS at all, or a syscall
    +    // that e.g. waits for a notification from the I/O driver
    +    // (sys-io); and the wait syscall may succeed, but the
    +    // driver may report an I/O error; or a bunch of results
    +    // for several I/O operations, some successful and some
    +    // not.
    +    //
    +    // Also I/O operations in a Motor OS process are handled by a
    +    // separate runtime background/I/O thread, so it is really hard
    +    // to define what "last system error in the current thread"
    +    // actually means.
    +    let error_code: moto_rt::ErrorCode = moto_rt::Error::Unknown.into();
    +    error_code.into()
    +}
    +
    +pub fn is_interrupted(_code: io::RawOsError) -> bool {
    +    false // Motor OS doesn't have signals.
    +}
    +
    +pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
    +    if code < 0 || code > u16::MAX.into() {
    +        return io::ErrorKind::Uncategorized;
    +    }
    +
    +    let error = moto_rt::Error::from(code as moto_rt::ErrorCode);
    +
    +    match error {
    +        moto_rt::Error::Unspecified => io::ErrorKind::Uncategorized,
    +        moto_rt::Error::Unknown => io::ErrorKind::Uncategorized,
    +        moto_rt::Error::NotReady => io::ErrorKind::WouldBlock,
    +        moto_rt::Error::NotImplemented => io::ErrorKind::Unsupported,
    +        moto_rt::Error::VersionTooHigh => io::ErrorKind::Unsupported,
    +        moto_rt::Error::VersionTooLow => io::ErrorKind::Unsupported,
    +        moto_rt::Error::InvalidArgument => io::ErrorKind::InvalidInput,
    +        moto_rt::Error::OutOfMemory => io::ErrorKind::OutOfMemory,
    +        moto_rt::Error::NotAllowed => io::ErrorKind::PermissionDenied,
    +        moto_rt::Error::NotFound => io::ErrorKind::NotFound,
    +        moto_rt::Error::InternalError => io::ErrorKind::Other,
    +        moto_rt::Error::TimedOut => io::ErrorKind::TimedOut,
    +        moto_rt::Error::AlreadyInUse => io::ErrorKind::AlreadyExists,
    +        moto_rt::Error::UnexpectedEof => io::ErrorKind::UnexpectedEof,
    +        moto_rt::Error::InvalidFilename => io::ErrorKind::InvalidFilename,
    +        moto_rt::Error::NotADirectory => io::ErrorKind::NotADirectory,
    +        moto_rt::Error::BadHandle => io::ErrorKind::InvalidInput,
    +        moto_rt::Error::FileTooLarge => io::ErrorKind::FileTooLarge,
    +        moto_rt::Error::NotConnected => io::ErrorKind::NotConnected,
    +        moto_rt::Error::StorageFull => io::ErrorKind::StorageFull,
    +        moto_rt::Error::InvalidData => io::ErrorKind::InvalidData,
    +        _ => io::ErrorKind::Uncategorized,
    +    }
    +}
    +
    +pub fn error_string(errno: RawOsError) -> String {
    +    let error: moto_rt::Error = match errno {
    +        x if x < 0 => moto_rt::Error::Unknown,
    +        x if x > u16::MAX.into() => moto_rt::Error::Unknown,
    +        x => (x as moto_rt::ErrorCode).into(), /* u16 */
    +    };
    +    format!("{}", error)
    +}
    diff --git a/library/std/src/sys/io/error/sgx.rs b/library/std/src/sys/io/error/sgx.rs
    new file mode 100644
    index 000000000000..8b3e08b0b661
    --- /dev/null
    +++ b/library/std/src/sys/io/error/sgx.rs
    @@ -0,0 +1,65 @@
    +use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
    +
    +use crate::io;
    +
    +pub fn errno() -> i32 {
    +    RESULT_SUCCESS
    +}
    +
    +#[inline]
    +pub fn is_interrupted(code: i32) -> bool {
    +    code == fortanix_sgx_abi::Error::Interrupted as _
    +}
    +
    +pub fn decode_error_kind(code: i32) -> io::ErrorKind {
    +    // FIXME: not sure how to make sure all variants of Error are covered
    +    if code == Error::NotFound as _ {
    +        io::ErrorKind::NotFound
    +    } else if code == Error::PermissionDenied as _ {
    +        io::ErrorKind::PermissionDenied
    +    } else if code == Error::ConnectionRefused as _ {
    +        io::ErrorKind::ConnectionRefused
    +    } else if code == Error::ConnectionReset as _ {
    +        io::ErrorKind::ConnectionReset
    +    } else if code == Error::ConnectionAborted as _ {
    +        io::ErrorKind::ConnectionAborted
    +    } else if code == Error::NotConnected as _ {
    +        io::ErrorKind::NotConnected
    +    } else if code == Error::AddrInUse as _ {
    +        io::ErrorKind::AddrInUse
    +    } else if code == Error::AddrNotAvailable as _ {
    +        io::ErrorKind::AddrNotAvailable
    +    } else if code == Error::BrokenPipe as _ {
    +        io::ErrorKind::BrokenPipe
    +    } else if code == Error::AlreadyExists as _ {
    +        io::ErrorKind::AlreadyExists
    +    } else if code == Error::WouldBlock as _ {
    +        io::ErrorKind::WouldBlock
    +    } else if code == Error::InvalidInput as _ {
    +        io::ErrorKind::InvalidInput
    +    } else if code == Error::InvalidData as _ {
    +        io::ErrorKind::InvalidData
    +    } else if code == Error::TimedOut as _ {
    +        io::ErrorKind::TimedOut
    +    } else if code == Error::WriteZero as _ {
    +        io::ErrorKind::WriteZero
    +    } else if code == Error::Interrupted as _ {
    +        io::ErrorKind::Interrupted
    +    } else if code == Error::Other as _ {
    +        io::ErrorKind::Uncategorized
    +    } else if code == Error::UnexpectedEof as _ {
    +        io::ErrorKind::UnexpectedEof
    +    } else {
    +        io::ErrorKind::Uncategorized
    +    }
    +}
    +
    +pub fn error_string(errno: i32) -> String {
    +    if errno == RESULT_SUCCESS {
    +        "operation successful".into()
    +    } else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) {
    +        format!("user-specified error {errno:08x}")
    +    } else {
    +        decode_error_kind(errno).as_str().into()
    +    }
    +}
    diff --git a/library/std/src/sys/io/error/solid.rs b/library/std/src/sys/io/error/solid.rs
    new file mode 100644
    index 000000000000..8e9503272abb
    --- /dev/null
    +++ b/library/std/src/sys/io/error/solid.rs
    @@ -0,0 +1,19 @@
    +use crate::io;
    +use crate::sys::pal::error;
    +
    +pub fn errno() -> i32 {
    +    0
    +}
    +
    +#[inline]
    +pub fn is_interrupted(code: i32) -> bool {
    +    crate::sys::net::is_interrupted(code)
    +}
    +
    +pub fn decode_error_kind(code: i32) -> io::ErrorKind {
    +    error::decode_error_kind(code)
    +}
    +
    +pub fn error_string(errno: i32) -> String {
    +    if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") }
    +}
    diff --git a/library/std/src/sys/io/error/teeos.rs b/library/std/src/sys/io/error/teeos.rs
    new file mode 100644
    index 000000000000..18826ffc3894
    --- /dev/null
    +++ b/library/std/src/sys/io/error/teeos.rs
    @@ -0,0 +1,64 @@
    +use crate::io;
    +
    +pub fn errno() -> i32 {
    +    unsafe { (*libc::__errno_location()) as i32 }
    +}
    +
    +#[inline]
    +pub fn is_interrupted(errno: i32) -> bool {
    +    errno == libc::EINTR
    +}
    +
    +// Note: code below is 1:1 copied from unix/mod.rs
    +pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
    +    use io::ErrorKind::*;
    +    match errno as libc::c_int {
    +        libc::E2BIG => ArgumentListTooLong,
    +        libc::EADDRINUSE => AddrInUse,
    +        libc::EADDRNOTAVAIL => AddrNotAvailable,
    +        libc::EBUSY => ResourceBusy,
    +        libc::ECONNABORTED => ConnectionAborted,
    +        libc::ECONNREFUSED => ConnectionRefused,
    +        libc::ECONNRESET => ConnectionReset,
    +        libc::EDEADLK => Deadlock,
    +        libc::EDQUOT => QuotaExceeded,
    +        libc::EEXIST => AlreadyExists,
    +        libc::EFBIG => FileTooLarge,
    +        libc::EHOSTUNREACH => HostUnreachable,
    +        libc::EINTR => Interrupted,
    +        libc::EINVAL => InvalidInput,
    +        libc::EISDIR => IsADirectory,
    +        libc::ELOOP => FilesystemLoop,
    +        libc::ENOENT => NotFound,
    +        libc::ENOMEM => OutOfMemory,
    +        libc::ENOSPC => StorageFull,
    +        libc::ENOSYS => Unsupported,
    +        libc::EMLINK => TooManyLinks,
    +        libc::ENAMETOOLONG => InvalidFilename,
    +        libc::ENETDOWN => NetworkDown,
    +        libc::ENETUNREACH => NetworkUnreachable,
    +        libc::ENOTCONN => NotConnected,
    +        libc::ENOTDIR => NotADirectory,
    +        libc::ENOTEMPTY => DirectoryNotEmpty,
    +        libc::EPIPE => BrokenPipe,
    +        libc::EROFS => ReadOnlyFilesystem,
    +        libc::ESPIPE => NotSeekable,
    +        libc::ESTALE => StaleNetworkFileHandle,
    +        libc::ETIMEDOUT => TimedOut,
    +        libc::ETXTBSY => ExecutableFileBusy,
    +        libc::EXDEV => CrossesDevices,
    +
    +        libc::EACCES | libc::EPERM => PermissionDenied,
    +
    +        // These two constants can have the same value on some systems,
    +        // but different values on others, so we can't use a match
    +        // clause
    +        x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
    +
    +        _ => Uncategorized,
    +    }
    +}
    +
    +pub fn error_string(_errno: i32) -> String {
    +    "error string unimplemented".to_string()
    +}
    diff --git a/library/std/src/sys/io/error/uefi.rs b/library/std/src/sys/io/error/uefi.rs
    new file mode 100644
    index 000000000000..bedea240d523
    --- /dev/null
    +++ b/library/std/src/sys/io/error/uefi.rs
    @@ -0,0 +1,104 @@
    +use r_efi::efi::Status;
    +
    +use crate::io;
    +
    +pub fn errno() -> io::RawOsError {
    +    0
    +}
    +
    +pub fn is_interrupted(_code: io::RawOsError) -> bool {
    +    false
    +}
    +
    +pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
    +    match Status::from_usize(code) {
    +        Status::ALREADY_STARTED
    +        | Status::COMPROMISED_DATA
    +        | Status::CONNECTION_FIN
    +        | Status::CRC_ERROR
    +        | Status::DEVICE_ERROR
    +        | Status::END_OF_MEDIA
    +        | Status::HTTP_ERROR
    +        | Status::ICMP_ERROR
    +        | Status::INCOMPATIBLE_VERSION
    +        | Status::LOAD_ERROR
    +        | Status::MEDIA_CHANGED
    +        | Status::NO_MAPPING
    +        | Status::NO_MEDIA
    +        | Status::NOT_STARTED
    +        | Status::PROTOCOL_ERROR
    +        | Status::PROTOCOL_UNREACHABLE
    +        | Status::TFTP_ERROR
    +        | Status::VOLUME_CORRUPTED => io::ErrorKind::Other,
    +        Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => io::ErrorKind::InvalidData,
    +        Status::ABORTED => io::ErrorKind::ConnectionAborted,
    +        Status::ACCESS_DENIED => io::ErrorKind::PermissionDenied,
    +        Status::BUFFER_TOO_SMALL => io::ErrorKind::FileTooLarge,
    +        Status::CONNECTION_REFUSED => io::ErrorKind::ConnectionRefused,
    +        Status::CONNECTION_RESET => io::ErrorKind::ConnectionReset,
    +        Status::END_OF_FILE => io::ErrorKind::UnexpectedEof,
    +        Status::HOST_UNREACHABLE => io::ErrorKind::HostUnreachable,
    +        Status::INVALID_PARAMETER => io::ErrorKind::InvalidInput,
    +        Status::IP_ADDRESS_CONFLICT => io::ErrorKind::AddrInUse,
    +        Status::NETWORK_UNREACHABLE => io::ErrorKind::NetworkUnreachable,
    +        Status::NO_RESPONSE => io::ErrorKind::HostUnreachable,
    +        Status::NOT_FOUND => io::ErrorKind::NotFound,
    +        Status::NOT_READY => io::ErrorKind::ResourceBusy,
    +        Status::OUT_OF_RESOURCES => io::ErrorKind::OutOfMemory,
    +        Status::SECURITY_VIOLATION => io::ErrorKind::PermissionDenied,
    +        Status::TIMEOUT => io::ErrorKind::TimedOut,
    +        Status::UNSUPPORTED => io::ErrorKind::Unsupported,
    +        Status::VOLUME_FULL => io::ErrorKind::StorageFull,
    +        Status::WRITE_PROTECTED => io::ErrorKind::ReadOnlyFilesystem,
    +        _ => io::ErrorKind::Uncategorized,
    +    }
    +}
    +
    +pub fn error_string(errno: io::RawOsError) -> String {
    +    // Keep the List in Alphabetical Order
    +    // The Messages are taken from UEFI Specification Appendix D - Status Codes
    +    #[rustfmt::skip]
    +    let msg = match Status::from_usize(errno) {
    +        Status::ABORTED => "The operation was aborted.",
    +        Status::ACCESS_DENIED => "Access was denied.",
    +        Status::ALREADY_STARTED => "The protocol has already been started.",
    +        Status::BAD_BUFFER_SIZE => "The buffer was not the proper size for the request.",
    +        Status::BUFFER_TOO_SMALL => "The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs.",
    +        Status::COMPROMISED_DATA => "The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status.",
    +        Status::CONNECTION_FIN => "The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance.",
    +        Status::CONNECTION_REFUSED => "The receiving or transmission operation fails because this connection is refused.",
    +        Status::CONNECTION_RESET => "The connect fails because the connection is reset either by instance itself or the communication peer.",
    +        Status::CRC_ERROR => "A CRC error was detected.",
    +        Status::DEVICE_ERROR => "The physical device reported an error while attempting the operation.",
    +        Status::END_OF_FILE => "The end of the file was reached.",
    +        Status::END_OF_MEDIA => "Beginning or end of media was reached",
    +        Status::HOST_UNREACHABLE => "The remote host is not reachable.",
    +        Status::HTTP_ERROR => "A HTTP error occurred during the network operation.",
    +        Status::ICMP_ERROR => "An ICMP error occurred during the network operation.",
    +        Status::INCOMPATIBLE_VERSION => "The function encountered an internal version that was incompatible with a version requested by the caller.",
    +        Status::INVALID_LANGUAGE => "The language specified was invalid.",
    +        Status::INVALID_PARAMETER => "A parameter was incorrect.",
    +        Status::IP_ADDRESS_CONFLICT => "There is an address conflict address allocation",
    +        Status::LOAD_ERROR => "The image failed to load.",
    +        Status::MEDIA_CHANGED => "The medium in the device has changed since the last access.",
    +        Status::NETWORK_UNREACHABLE => "The network containing the remote host is not reachable.",
    +        Status::NO_MAPPING => "A mapping to a device does not exist.",
    +        Status::NO_MEDIA => "The device does not contain any medium to perform the operation.",
    +        Status::NO_RESPONSE => "The server was not found or did not respond to the request.",
    +        Status::NOT_FOUND => "The item was not found.",
    +        Status::NOT_READY => "There is no data pending upon return.",
    +        Status::NOT_STARTED => "The protocol has not been started.",
    +        Status::OUT_OF_RESOURCES => "A resource has run out.",
    +        Status::PROTOCOL_ERROR => "A protocol error occurred during the network operation.",
    +        Status::PROTOCOL_UNREACHABLE => "An ICMP protocol unreachable error is received.",
    +        Status::SECURITY_VIOLATION => "The function was not performed due to a security violation.",
    +        Status::TFTP_ERROR => "A TFTP error occurred during the network operation.",
    +        Status::TIMEOUT => "The timeout time expired.",
    +        Status::UNSUPPORTED => "The operation is not supported.",
    +        Status::VOLUME_FULL => "There is no more space on the file system.",
    +        Status::VOLUME_CORRUPTED => "An inconstancy was detected on the file system causing the operating to fail.",
    +        Status::WRITE_PROTECTED => "The device cannot be written to.",
    +        _ => return format!("Status: {errno}"),
    +    };
    +    msg.to_owned()
    +}
    diff --git a/library/std/src/sys/io/error/unix.rs b/library/std/src/sys/io/error/unix.rs
    new file mode 100644
    index 000000000000..b10343b2752c
    --- /dev/null
    +++ b/library/std/src/sys/io/error/unix.rs
    @@ -0,0 +1,186 @@
    +use crate::ffi::{CStr, c_char, c_int};
    +use crate::io;
    +
    +unsafe extern "C" {
    +    #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
    +    #[cfg_attr(
    +        any(
    +            target_os = "linux",
    +            target_os = "emscripten",
    +            target_os = "fuchsia",
    +            target_os = "l4re",
    +            target_os = "hurd",
    +        ),
    +        link_name = "__errno_location"
    +    )]
    +    #[cfg_attr(
    +        any(
    +            target_os = "netbsd",
    +            target_os = "openbsd",
    +            target_os = "cygwin",
    +            target_os = "android",
    +            target_os = "redox",
    +            target_os = "nuttx",
    +            target_env = "newlib"
    +        ),
    +        link_name = "__errno"
    +    )]
    +    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")]
    +    #[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")]
    +    #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")]
    +    #[cfg_attr(target_os = "haiku", link_name = "_errnop")]
    +    #[cfg_attr(target_os = "aix", link_name = "_Errno")]
    +    // SAFETY: this will always return the same pointer on a given thread.
    +    #[unsafe(ffi_const)]
    +    pub safe fn errno_location() -> *mut c_int;
    +}
    +
    +/// Returns the platform-specific value of errno
    +#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
    +#[inline]
    +pub fn errno() -> i32 {
    +    unsafe { (*errno_location()) as i32 }
    +}
    +
    +/// Sets the platform-specific value of errno
    +// needed for readdir and syscall!
    +#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
    +#[allow(dead_code)] // but not all target cfgs actually end up using it
    +#[inline]
    +pub fn set_errno(e: i32) {
    +    unsafe { *errno_location() = e as c_int }
    +}
    +
    +#[cfg(target_os = "vxworks")]
    +#[inline]
    +pub fn errno() -> i32 {
    +    unsafe { libc::errnoGet() }
    +}
    +
    +#[cfg(target_os = "rtems")]
    +#[inline]
    +pub fn errno() -> i32 {
    +    unsafe extern "C" {
    +        #[thread_local]
    +        static _tls_errno: c_int;
    +    }
    +
    +    unsafe { _tls_errno as i32 }
    +}
    +
    +#[cfg(target_os = "dragonfly")]
    +#[inline]
    +pub fn errno() -> i32 {
    +    unsafe extern "C" {
    +        #[thread_local]
    +        static errno: c_int;
    +    }
    +
    +    unsafe { errno as i32 }
    +}
    +
    +#[cfg(target_os = "dragonfly")]
    +#[allow(dead_code)]
    +#[inline]
    +pub fn set_errno(e: i32) {
    +    unsafe extern "C" {
    +        #[thread_local]
    +        static mut errno: c_int;
    +    }
    +
    +    unsafe {
    +        errno = e;
    +    }
    +}
    +
    +#[inline]
    +pub fn is_interrupted(errno: i32) -> bool {
    +    errno == libc::EINTR
    +}
    +
    +pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
    +    use io::ErrorKind::*;
    +    match errno as libc::c_int {
    +        libc::E2BIG => ArgumentListTooLong,
    +        libc::EADDRINUSE => AddrInUse,
    +        libc::EADDRNOTAVAIL => AddrNotAvailable,
    +        libc::EBUSY => ResourceBusy,
    +        libc::ECONNABORTED => ConnectionAborted,
    +        libc::ECONNREFUSED => ConnectionRefused,
    +        libc::ECONNRESET => ConnectionReset,
    +        libc::EDEADLK => Deadlock,
    +        libc::EDQUOT => QuotaExceeded,
    +        libc::EEXIST => AlreadyExists,
    +        libc::EFBIG => FileTooLarge,
    +        libc::EHOSTUNREACH => HostUnreachable,
    +        libc::EINTR => Interrupted,
    +        libc::EINVAL => InvalidInput,
    +        libc::EISDIR => IsADirectory,
    +        libc::ELOOP => FilesystemLoop,
    +        libc::ENOENT => NotFound,
    +        libc::ENOMEM => OutOfMemory,
    +        libc::ENOSPC => StorageFull,
    +        libc::ENOSYS => Unsupported,
    +        libc::EMLINK => TooManyLinks,
    +        libc::ENAMETOOLONG => InvalidFilename,
    +        libc::ENETDOWN => NetworkDown,
    +        libc::ENETUNREACH => NetworkUnreachable,
    +        libc::ENOTCONN => NotConnected,
    +        libc::ENOTDIR => NotADirectory,
    +        #[cfg(not(target_os = "aix"))]
    +        libc::ENOTEMPTY => DirectoryNotEmpty,
    +        libc::EPIPE => BrokenPipe,
    +        libc::EROFS => ReadOnlyFilesystem,
    +        libc::ESPIPE => NotSeekable,
    +        libc::ESTALE => StaleNetworkFileHandle,
    +        libc::ETIMEDOUT => TimedOut,
    +        libc::ETXTBSY => ExecutableFileBusy,
    +        libc::EXDEV => CrossesDevices,
    +        libc::EINPROGRESS => InProgress,
    +        libc::EOPNOTSUPP => Unsupported,
    +
    +        libc::EACCES | libc::EPERM => PermissionDenied,
    +
    +        // These two constants can have the same value on some systems,
    +        // but different values on others, so we can't use a match
    +        // clause
    +        x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
    +
    +        _ => Uncategorized,
    +    }
    +}
    +
    +/// Gets a detailed string description for the given error number.
    +pub fn error_string(errno: i32) -> String {
    +    const TMPBUF_SZ: usize = 128;
    +
    +    unsafe extern "C" {
    +        #[cfg_attr(
    +            all(
    +                any(
    +                    target_os = "linux",
    +                    target_os = "hurd",
    +                    target_env = "newlib",
    +                    target_os = "cygwin"
    +                ),
    +                not(target_env = "ohos")
    +            ),
    +            link_name = "__xpg_strerror_r"
    +        )]
    +        fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int;
    +    }
    +
    +    let mut buf = [0 as c_char; TMPBUF_SZ];
    +
    +    let p = buf.as_mut_ptr();
    +    unsafe {
    +        if strerror_r(errno as c_int, p, buf.len()) < 0 {
    +            panic!("strerror_r failure");
    +        }
    +
    +        let p = p as *const _;
    +        // We can't always expect a UTF-8 environment. When we don't get that luxury,
    +        // it's better to give a low-quality error message than none at all.
    +        String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into()
    +    }
    +}
    diff --git a/library/std/src/sys/io/error/wasi.rs b/library/std/src/sys/io/error/wasi.rs
    new file mode 100644
    index 000000000000..719fc0c900ad
    --- /dev/null
    +++ b/library/std/src/sys/io/error/wasi.rs
    @@ -0,0 +1,80 @@
    +use crate::ffi::CStr;
    +use crate::io as std_io;
    +
    +unsafe extern "C" {
    +    #[thread_local]
    +    #[link_name = "errno"]
    +    static mut libc_errno: libc::c_int;
    +}
    +
    +pub fn errno() -> i32 {
    +    unsafe { libc_errno as i32 }
    +}
    +
    +pub fn set_errno(val: i32) {
    +    unsafe {
    +        libc_errno = val;
    +    }
    +}
    +
    +#[inline]
    +pub fn is_interrupted(errno: i32) -> bool {
    +    errno == libc::EINTR
    +}
    +
    +pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
    +    use std_io::ErrorKind::*;
    +    match errno as libc::c_int {
    +        libc::E2BIG => ArgumentListTooLong,
    +        libc::EADDRINUSE => AddrInUse,
    +        libc::EADDRNOTAVAIL => AddrNotAvailable,
    +        libc::EBUSY => ResourceBusy,
    +        libc::ECONNABORTED => ConnectionAborted,
    +        libc::ECONNREFUSED => ConnectionRefused,
    +        libc::ECONNRESET => ConnectionReset,
    +        libc::EDEADLK => Deadlock,
    +        libc::EDQUOT => QuotaExceeded,
    +        libc::EEXIST => AlreadyExists,
    +        libc::EFBIG => FileTooLarge,
    +        libc::EHOSTUNREACH => HostUnreachable,
    +        libc::EINTR => Interrupted,
    +        libc::EINVAL => InvalidInput,
    +        libc::EISDIR => IsADirectory,
    +        libc::ELOOP => FilesystemLoop,
    +        libc::ENOENT => NotFound,
    +        libc::ENOMEM => OutOfMemory,
    +        libc::ENOSPC => StorageFull,
    +        libc::ENOSYS => Unsupported,
    +        libc::EMLINK => TooManyLinks,
    +        libc::ENAMETOOLONG => InvalidFilename,
    +        libc::ENETDOWN => NetworkDown,
    +        libc::ENETUNREACH => NetworkUnreachable,
    +        libc::ENOTCONN => NotConnected,
    +        libc::ENOTDIR => NotADirectory,
    +        libc::EPIPE => BrokenPipe,
    +        libc::EROFS => ReadOnlyFilesystem,
    +        libc::ESPIPE => NotSeekable,
    +        libc::ESTALE => StaleNetworkFileHandle,
    +        libc::ETIMEDOUT => TimedOut,
    +        libc::ETXTBSY => ExecutableFileBusy,
    +        libc::EXDEV => CrossesDevices,
    +        libc::EINPROGRESS => InProgress,
    +        libc::EOPNOTSUPP => Unsupported,
    +        libc::EACCES | libc::EPERM => PermissionDenied,
    +        libc::EWOULDBLOCK => WouldBlock,
    +
    +        _ => Uncategorized,
    +    }
    +}
    +
    +pub fn error_string(errno: i32) -> String {
    +    let mut buf = [0 as libc::c_char; 1024];
    +
    +    let p = buf.as_mut_ptr();
    +    unsafe {
    +        if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 {
    +            panic!("strerror_r failure");
    +        }
    +        str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
    +    }
    +}
    diff --git a/library/std/src/sys/io/error/windows.rs b/library/std/src/sys/io/error/windows.rs
    new file mode 100644
    index 000000000000..e02197ac6775
    --- /dev/null
    +++ b/library/std/src/sys/io/error/windows.rs
    @@ -0,0 +1,140 @@
    +use crate::sys::pal::{api, c};
    +use crate::{io, ptr};
    +
    +pub fn errno() -> i32 {
    +    api::get_last_error().code as i32
    +}
    +
    +#[inline]
    +pub fn is_interrupted(_errno: i32) -> bool {
    +    false
    +}
    +
    +pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
    +    use io::ErrorKind::*;
    +
    +    match errno as u32 {
    +        c::ERROR_ACCESS_DENIED => return PermissionDenied,
    +        c::ERROR_ALREADY_EXISTS => return AlreadyExists,
    +        c::ERROR_FILE_EXISTS => return AlreadyExists,
    +        c::ERROR_BROKEN_PIPE => return BrokenPipe,
    +        c::ERROR_FILE_NOT_FOUND
    +        | c::ERROR_PATH_NOT_FOUND
    +        | c::ERROR_INVALID_DRIVE
    +        | c::ERROR_BAD_NETPATH
    +        | c::ERROR_BAD_NET_NAME => return NotFound,
    +        c::ERROR_NO_DATA => return BrokenPipe,
    +        c::ERROR_INVALID_NAME | c::ERROR_BAD_PATHNAME => return InvalidFilename,
    +        c::ERROR_INVALID_PARAMETER => return InvalidInput,
    +        c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory,
    +        c::ERROR_SEM_TIMEOUT
    +        | c::WAIT_TIMEOUT
    +        | c::ERROR_DRIVER_CANCEL_TIMEOUT
    +        | c::ERROR_OPERATION_ABORTED
    +        | c::ERROR_SERVICE_REQUEST_TIMEOUT
    +        | c::ERROR_COUNTER_TIMEOUT
    +        | c::ERROR_TIMEOUT
    +        | c::ERROR_RESOURCE_CALL_TIMED_OUT
    +        | c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT
    +        | c::ERROR_CTX_CLIENT_QUERY_TIMEOUT
    +        | c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT
    +        | c::ERROR_DS_TIMELIMIT_EXCEEDED
    +        | c::DNS_ERROR_RECORD_TIMED_OUT
    +        | c::ERROR_IPSEC_IKE_TIMED_OUT
    +        | c::ERROR_RUNLEVEL_SWITCH_TIMEOUT
    +        | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return TimedOut,
    +        c::ERROR_CALL_NOT_IMPLEMENTED => return Unsupported,
    +        c::ERROR_HOST_UNREACHABLE => return HostUnreachable,
    +        c::ERROR_NETWORK_UNREACHABLE => return NetworkUnreachable,
    +        c::ERROR_DIRECTORY => return NotADirectory,
    +        c::ERROR_DIRECTORY_NOT_SUPPORTED => return IsADirectory,
    +        c::ERROR_DIR_NOT_EMPTY => return DirectoryNotEmpty,
    +        c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem,
    +        c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull,
    +        c::ERROR_SEEK_ON_DEVICE => return NotSeekable,
    +        c::ERROR_DISK_QUOTA_EXCEEDED => return QuotaExceeded,
    +        c::ERROR_FILE_TOO_LARGE => return FileTooLarge,
    +        c::ERROR_BUSY => return ResourceBusy,
    +        c::ERROR_POSSIBLE_DEADLOCK => return Deadlock,
    +        c::ERROR_NOT_SAME_DEVICE => return CrossesDevices,
    +        c::ERROR_TOO_MANY_LINKS => return TooManyLinks,
    +        c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename,
    +        c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop,
    +        _ => {}
    +    }
    +
    +    match errno {
    +        c::WSAEACCES => PermissionDenied,
    +        c::WSAEADDRINUSE => AddrInUse,
    +        c::WSAEADDRNOTAVAIL => AddrNotAvailable,
    +        c::WSAECONNABORTED => ConnectionAborted,
    +        c::WSAECONNREFUSED => ConnectionRefused,
    +        c::WSAECONNRESET => ConnectionReset,
    +        c::WSAEINVAL => InvalidInput,
    +        c::WSAENOTCONN => NotConnected,
    +        c::WSAEWOULDBLOCK => WouldBlock,
    +        c::WSAETIMEDOUT => TimedOut,
    +        c::WSAEHOSTUNREACH => HostUnreachable,
    +        c::WSAENETDOWN => NetworkDown,
    +        c::WSAENETUNREACH => NetworkUnreachable,
    +        c::WSAEDQUOT => QuotaExceeded,
    +
    +        _ => Uncategorized,
    +    }
    +}
    +
    +/// Gets a detailed string description for the given error number.
    +pub fn error_string(mut errnum: i32) -> String {
    +    let mut buf = [0 as c::WCHAR; 2048];
    +
    +    unsafe {
    +        let mut module = ptr::null_mut();
    +        let mut flags = 0;
    +
    +        // NTSTATUS errors may be encoded as HRESULT, which may returned from
    +        // GetLastError. For more information about Windows error codes, see
    +        // `[MS-ERREF]`: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548a
    +        if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
    +            // format according to https://support.microsoft.com/en-us/help/259693
    +            const NTDLL_DLL: &[u16] = &[
    +                'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _,
    +                'L' as _, 0,
    +            ];
    +            module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
    +
    +            if !module.is_null() {
    +                errnum ^= c::FACILITY_NT_BIT as i32;
    +                flags = c::FORMAT_MESSAGE_FROM_HMODULE;
    +            }
    +        }
    +
    +        let res = c::FormatMessageW(
    +            flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS,
    +            module,
    +            errnum as u32,
    +            0,
    +            buf.as_mut_ptr(),
    +            buf.len() as u32,
    +            ptr::null(),
    +        ) as usize;
    +        if res == 0 {
    +            // Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId,
    +            let fm_err = errno();
    +            return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})");
    +        }
    +
    +        match String::from_utf16(&buf[..res]) {
    +            Ok(mut msg) => {
    +                // Trim trailing CRLF inserted by FormatMessageW
    +                let len = msg.trim_end().len();
    +                msg.truncate(len);
    +                msg
    +            }
    +            Err(..) => format!(
    +                "OS Error {} (FormatMessageW() returned \
    +                 invalid UTF-16)",
    +                errnum
    +            ),
    +        }
    +    }
    +}
    diff --git a/library/std/src/sys/io/error/xous.rs b/library/std/src/sys/io/error/xous.rs
    new file mode 100644
    index 000000000000..2e9ea8e4f092
    --- /dev/null
    +++ b/library/std/src/sys/io/error/xous.rs
    @@ -0,0 +1,17 @@
    +use crate::os::xous::ffi::Error as XousError;
    +
    +pub fn errno() -> i32 {
    +    0
    +}
    +
    +pub fn is_interrupted(_code: i32) -> bool {
    +    false
    +}
    +
    +pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
    +    crate::io::ErrorKind::Uncategorized
    +}
    +
    +pub fn error_string(errno: i32) -> String {
    +    Into::::into(errno).to_string()
    +}
    diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs
    index 4a5d6f8e27f2..b3587ab63696 100644
    --- a/library/std/src/sys/io/mod.rs
    +++ b/library/std/src/sys/io/mod.rs
    @@ -1,5 +1,7 @@
     #![forbid(unsafe_op_in_unsafe_fn)]
     
    +mod error;
    +
     mod io_slice {
         cfg_select! {
             any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty", target_os = "wasi") => {
    @@ -48,6 +50,19 @@ mod is_terminal {
     
     mod kernel_copy;
     
    +#[cfg_attr(not(target_os = "linux"), allow(unused_imports))]
    +#[cfg(all(
    +    target_family = "unix",
    +    not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems"))
    +))]
    +pub use error::errno_location;
    +#[cfg_attr(not(target_os = "linux"), allow(unused_imports))]
    +#[cfg(any(
    +    all(target_family = "unix", not(any(target_os = "vxworks", target_os = "rtems"))),
    +    target_os = "wasi",
    +))]
    +pub use error::set_errno;
    +pub use error::{RawOsError, decode_error_kind, errno, error_string, is_interrupted};
     pub use io_slice::{IoSlice, IoSliceMut};
     pub use is_terminal::is_terminal;
     pub use kernel_copy::{CopyState, kernel_copy};
    @@ -55,8 +70,3 @@ pub use kernel_copy::{CopyState, kernel_copy};
     // Bare metal platforms usually have very small amounts of RAM
     // (in the order of hundreds of KB)
     pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 };
    -
    -pub type RawOsError = cfg_select! {
    -    target_os = "uefi" => usize,
    -    _ => i32,
    -};
    diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs
    index d09ba97cfe01..5e20c0ffdfa6 100644
    --- a/library/std/src/sys/net/connection/socket/unix.rs
    +++ b/library/std/src/sys/net/connection/socket/unix.rs
    @@ -151,7 +151,7 @@ impl Socket {
             loop {
                 let result = unsafe { libc::connect(self.as_raw_fd(), addr.as_ptr(), len) };
                 if result.is_minus_one() {
    -                let err = crate::sys::os::errno();
    +                let err = crate::sys::io::errno();
                     match err {
                         libc::EINTR => continue,
                         libc::EISCONN => return Ok(()),
    diff --git a/library/std/src/sys/net/hostname/unix.rs b/library/std/src/sys/net/hostname/unix.rs
    index bc6fa82a38f0..d444182f3fde 100644
    --- a/library/std/src/sys/net/hostname/unix.rs
    +++ b/library/std/src/sys/net/hostname/unix.rs
    @@ -1,7 +1,7 @@
     use crate::ffi::OsString;
     use crate::io;
     use crate::os::unix::ffi::OsStringExt;
    -use crate::sys::pal::os::errno;
    +use crate::sys::io::errno;
     
     pub fn hostname() -> io::Result {
         // Query the system for the maximum host name length.
    diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
    index 0e1328a7972f..db64f8d882e2 100644
    --- a/library/std/src/sys/pal/hermit/mod.rs
    +++ b/library/std/src/sys/pal/hermit/mod.rs
    @@ -75,32 +75,6 @@ pub unsafe extern "C" fn runtime_entry(
         }
     }
     
    -#[inline]
    -pub(crate) fn is_interrupted(errno: i32) -> bool {
    -    errno == hermit_abi::errno::EINTR
    -}
    -
    -pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
    -    match errno {
    -        hermit_abi::errno::EACCES => io::ErrorKind::PermissionDenied,
    -        hermit_abi::errno::EADDRINUSE => io::ErrorKind::AddrInUse,
    -        hermit_abi::errno::EADDRNOTAVAIL => io::ErrorKind::AddrNotAvailable,
    -        hermit_abi::errno::EAGAIN => io::ErrorKind::WouldBlock,
    -        hermit_abi::errno::ECONNABORTED => io::ErrorKind::ConnectionAborted,
    -        hermit_abi::errno::ECONNREFUSED => io::ErrorKind::ConnectionRefused,
    -        hermit_abi::errno::ECONNRESET => io::ErrorKind::ConnectionReset,
    -        hermit_abi::errno::EEXIST => io::ErrorKind::AlreadyExists,
    -        hermit_abi::errno::EINTR => io::ErrorKind::Interrupted,
    -        hermit_abi::errno::EINVAL => io::ErrorKind::InvalidInput,
    -        hermit_abi::errno::ENOENT => io::ErrorKind::NotFound,
    -        hermit_abi::errno::ENOTCONN => io::ErrorKind::NotConnected,
    -        hermit_abi::errno::EPERM => io::ErrorKind::PermissionDenied,
    -        hermit_abi::errno::EPIPE => io::ErrorKind::BrokenPipe,
    -        hermit_abi::errno::ETIMEDOUT => io::ErrorKind::TimedOut,
    -        _ => io::ErrorKind::Uncategorized,
    -    }
    -}
    -
     #[doc(hidden)]
     pub trait IsNegative {
         fn is_negative(&self) -> bool;
    @@ -131,12 +105,7 @@ impl IsNegative for i32 {
     impl_is_negative! { i8 i16 i64 isize }
     
     pub fn cvt(t: T) -> io::Result {
    -    if t.is_negative() {
    -        let e = decode_error_kind(t.negate());
    -        Err(io::Error::from(e))
    -    } else {
    -        Ok(t)
    -    }
    +    if t.is_negative() { Err(io::Error::from_raw_os_error(t.negate())) } else { Ok(t) }
     }
     
     pub fn cvt_r(mut f: F) -> io::Result
    diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs
    index 9681964ed9b2..48a7cdcd2f76 100644
    --- a/library/std/src/sys/pal/hermit/os.rs
    +++ b/library/std/src/sys/pal/hermit/os.rs
    @@ -5,14 +5,6 @@ use crate::path::{self, PathBuf};
     use crate::sys::unsupported;
     use crate::{fmt, io};
     
    -pub fn errno() -> i32 {
    -    unsafe { hermit_abi::get_errno() }
    -}
    -
    -pub fn error_string(errno: i32) -> String {
    -    hermit_abi::error_string(errno).to_string()
    -}
    -
     pub fn getcwd() -> io::Result {
         Ok(PathBuf::from("/"))
     }
    diff --git a/library/std/src/sys/pal/motor/mod.rs b/library/std/src/sys/pal/motor/mod.rs
    index 016fbe5c154c..e5b99cea01d5 100644
    --- a/library/std/src/sys/pal/motor/mod.rs
    +++ b/library/std/src/sys/pal/motor/mod.rs
    @@ -44,45 +44,6 @@ pub fn unsupported_err() -> io::Error {
         io::Error::UNSUPPORTED_PLATFORM
     }
     
    -pub fn is_interrupted(_code: io::RawOsError) -> bool {
    -    false // Motor OS doesn't have signals.
    -}
    -
    -pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
    -    use moto_rt::error::*;
    -
    -    if code < 0 || code > u16::MAX.into() {
    -        return io::ErrorKind::Uncategorized;
    -    }
    -
    -    let error = moto_rt::Error::from(code as moto_rt::ErrorCode);
    -
    -    match error {
    -        moto_rt::Error::Unspecified => io::ErrorKind::Uncategorized,
    -        moto_rt::Error::Unknown => io::ErrorKind::Uncategorized,
    -        moto_rt::Error::NotReady => io::ErrorKind::WouldBlock,
    -        moto_rt::Error::NotImplemented => io::ErrorKind::Unsupported,
    -        moto_rt::Error::VersionTooHigh => io::ErrorKind::Unsupported,
    -        moto_rt::Error::VersionTooLow => io::ErrorKind::Unsupported,
    -        moto_rt::Error::InvalidArgument => io::ErrorKind::InvalidInput,
    -        moto_rt::Error::OutOfMemory => io::ErrorKind::OutOfMemory,
    -        moto_rt::Error::NotAllowed => io::ErrorKind::PermissionDenied,
    -        moto_rt::Error::NotFound => io::ErrorKind::NotFound,
    -        moto_rt::Error::InternalError => io::ErrorKind::Other,
    -        moto_rt::Error::TimedOut => io::ErrorKind::TimedOut,
    -        moto_rt::Error::AlreadyInUse => io::ErrorKind::AlreadyExists,
    -        moto_rt::Error::UnexpectedEof => io::ErrorKind::UnexpectedEof,
    -        moto_rt::Error::InvalidFilename => io::ErrorKind::InvalidFilename,
    -        moto_rt::Error::NotADirectory => io::ErrorKind::NotADirectory,
    -        moto_rt::Error::BadHandle => io::ErrorKind::InvalidInput,
    -        moto_rt::Error::FileTooLarge => io::ErrorKind::FileTooLarge,
    -        moto_rt::Error::NotConnected => io::ErrorKind::NotConnected,
    -        moto_rt::Error::StorageFull => io::ErrorKind::StorageFull,
    -        moto_rt::Error::InvalidData => io::ErrorKind::InvalidData,
    -        _ => io::ErrorKind::Uncategorized,
    -    }
    -}
    -
     pub fn abort_internal() -> ! {
         core::intrinsics::abort();
     }
    diff --git a/library/std/src/sys/pal/motor/os.rs b/library/std/src/sys/pal/motor/os.rs
    index 0367c905b453..cdf66e3958db 100644
    --- a/library/std/src/sys/pal/motor/os.rs
    +++ b/library/std/src/sys/pal/motor/os.rs
    @@ -4,37 +4,8 @@ use crate::ffi::{OsStr, OsString};
     use crate::marker::PhantomData;
     use crate::os::motor::ffi::OsStrExt;
     use crate::path::{self, PathBuf};
    -use crate::sys::io::RawOsError;
     use crate::{fmt, io};
     
    -pub fn errno() -> RawOsError {
    -    // Not used in Motor OS because it is ambiguous: Motor OS
    -    // is micro-kernel-based, and I/O happens via a shared-memory
    -    // ring buffer, so an I/O operation that on a unix is a syscall
    -    // may involve no sycalls on Motor OS at all, or a syscall
    -    // that e.g. waits for a notification from the I/O driver
    -    // (sys-io); and the wait syscall may succeed, but the
    -    // driver may report an I/O error; or a bunch of results
    -    // for several I/O operations, some successful and some
    -    // not.
    -    //
    -    // Also I/O operations in a Motor OS process are handled by a
    -    // separate runtime background/I/O thread, so it is really hard
    -    // to define what "last system error in the current thread"
    -    // actually means.
    -    let error_code: moto_rt::ErrorCode = moto_rt::Error::Unknown.into();
    -    error_code.into()
    -}
    -
    -pub fn error_string(errno: RawOsError) -> String {
    -    let error: moto_rt::Error = match errno {
    -        x if x < 0 => moto_rt::Error::Unknown,
    -        x if x > u16::MAX.into() => moto_rt::Error::Unknown,
    -        x => (x as moto_rt::ErrorCode).into(), /* u16 */
    -    };
    -    format!("{}", error)
    -}
    -
     pub fn getcwd() -> io::Result {
         moto_rt::fs::getcwd().map(PathBuf::from).map_err(map_motor_error)
     }
    diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
    index a067480508c7..7f1c81a0ff7b 100644
    --- a/library/std/src/sys/pal/sgx/mod.rs
    +++ b/library/std/src/sys/pal/sgx/mod.rs
    @@ -54,56 +54,6 @@ pub fn sgx_ineffective(v: T) -> io::Result {
         }
     }
     
    -#[inline]
    -pub fn is_interrupted(code: i32) -> bool {
    -    code == fortanix_sgx_abi::Error::Interrupted as _
    -}
    -
    -pub fn decode_error_kind(code: i32) -> io::ErrorKind {
    -    use fortanix_sgx_abi::Error;
    -
    -    // FIXME: not sure how to make sure all variants of Error are covered
    -    if code == Error::NotFound as _ {
    -        io::ErrorKind::NotFound
    -    } else if code == Error::PermissionDenied as _ {
    -        io::ErrorKind::PermissionDenied
    -    } else if code == Error::ConnectionRefused as _ {
    -        io::ErrorKind::ConnectionRefused
    -    } else if code == Error::ConnectionReset as _ {
    -        io::ErrorKind::ConnectionReset
    -    } else if code == Error::ConnectionAborted as _ {
    -        io::ErrorKind::ConnectionAborted
    -    } else if code == Error::NotConnected as _ {
    -        io::ErrorKind::NotConnected
    -    } else if code == Error::AddrInUse as _ {
    -        io::ErrorKind::AddrInUse
    -    } else if code == Error::AddrNotAvailable as _ {
    -        io::ErrorKind::AddrNotAvailable
    -    } else if code == Error::BrokenPipe as _ {
    -        io::ErrorKind::BrokenPipe
    -    } else if code == Error::AlreadyExists as _ {
    -        io::ErrorKind::AlreadyExists
    -    } else if code == Error::WouldBlock as _ {
    -        io::ErrorKind::WouldBlock
    -    } else if code == Error::InvalidInput as _ {
    -        io::ErrorKind::InvalidInput
    -    } else if code == Error::InvalidData as _ {
    -        io::ErrorKind::InvalidData
    -    } else if code == Error::TimedOut as _ {
    -        io::ErrorKind::TimedOut
    -    } else if code == Error::WriteZero as _ {
    -        io::ErrorKind::WriteZero
    -    } else if code == Error::Interrupted as _ {
    -        io::ErrorKind::Interrupted
    -    } else if code == Error::Other as _ {
    -        io::ErrorKind::Uncategorized
    -    } else if code == Error::UnexpectedEof as _ {
    -        io::ErrorKind::UnexpectedEof
    -    } else {
    -        io::ErrorKind::Uncategorized
    -    }
    -}
    -
     pub fn abort_internal() -> ! {
         abi::usercalls::exit(true)
     }
    diff --git a/library/std/src/sys/pal/sgx/os.rs b/library/std/src/sys/pal/sgx/os.rs
    index 28d79963ac87..ba47af7ff88d 100644
    --- a/library/std/src/sys/pal/sgx/os.rs
    +++ b/library/std/src/sys/pal/sgx/os.rs
    @@ -1,25 +1,9 @@
    -use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
    -
     use crate::ffi::{OsStr, OsString};
     use crate::marker::PhantomData;
     use crate::path::{self, PathBuf};
    -use crate::sys::{decode_error_kind, sgx_ineffective, unsupported};
    +use crate::sys::{sgx_ineffective, unsupported};
     use crate::{fmt, io};
     
    -pub fn errno() -> i32 {
    -    RESULT_SUCCESS
    -}
    -
    -pub fn error_string(errno: i32) -> String {
    -    if errno == RESULT_SUCCESS {
    -        "operation successful".into()
    -    } else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) {
    -        format!("user-specified error {errno:08x}")
    -    } else {
    -        decode_error_kind(errno).as_str().into()
    -    }
    -}
    -
     pub fn getcwd() -> io::Result {
         unsupported()
     }
    diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs
    index 01477c7dc5e9..4eec12dacd7c 100644
    --- a/library/std/src/sys/pal/solid/mod.rs
    +++ b/library/std/src/sys/pal/solid/mod.rs
    @@ -38,15 +38,6 @@ pub fn unsupported_err() -> io::Error {
         io::Error::UNSUPPORTED_PLATFORM
     }
     
    -#[inline]
    -pub fn is_interrupted(code: i32) -> bool {
    -    crate::sys::net::is_interrupted(code)
    -}
    -
    -pub fn decode_error_kind(code: i32) -> io::ErrorKind {
    -    error::decode_error_kind(code)
    -}
    -
     #[inline]
     pub fn abort_internal() -> ! {
         unsafe { libc::abort() }
    diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs
    index cb6e2cbceae6..c336a1042da4 100644
    --- a/library/std/src/sys/pal/solid/os.rs
    +++ b/library/std/src/sys/pal/solid/os.rs
    @@ -1,4 +1,4 @@
    -use super::{error, itron, unsupported};
    +use super::{itron, unsupported};
     use crate::ffi::{OsStr, OsString};
     use crate::path::{self, PathBuf};
     use crate::{fmt, io};
    @@ -11,14 +11,6 @@ impl itron::error::ItronError {
         }
     }
     
    -pub fn errno() -> i32 {
    -    0
    -}
    -
    -pub fn error_string(errno: i32) -> String {
    -    if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") }
    -}
    -
     pub fn getcwd() -> io::Result {
         unsupported()
     }
    diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs
    index 627096b11c38..d40c10663fd1 100644
    --- a/library/std/src/sys/pal/teeos/mod.rs
    +++ b/library/std/src/sys/pal/teeos/mod.rs
    @@ -38,61 +38,6 @@ pub unsafe fn cleanup() {
         // stack_overflow::cleanup();
     }
     
    -#[inline]
    -pub(crate) fn is_interrupted(errno: i32) -> bool {
    -    errno == libc::EINTR
    -}
    -
    -// Note: code below is 1:1 copied from unix/mod.rs
    -pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
    -    use io::ErrorKind::*;
    -    match errno as libc::c_int {
    -        libc::E2BIG => ArgumentListTooLong,
    -        libc::EADDRINUSE => AddrInUse,
    -        libc::EADDRNOTAVAIL => AddrNotAvailable,
    -        libc::EBUSY => ResourceBusy,
    -        libc::ECONNABORTED => ConnectionAborted,
    -        libc::ECONNREFUSED => ConnectionRefused,
    -        libc::ECONNRESET => ConnectionReset,
    -        libc::EDEADLK => Deadlock,
    -        libc::EDQUOT => QuotaExceeded,
    -        libc::EEXIST => AlreadyExists,
    -        libc::EFBIG => FileTooLarge,
    -        libc::EHOSTUNREACH => HostUnreachable,
    -        libc::EINTR => Interrupted,
    -        libc::EINVAL => InvalidInput,
    -        libc::EISDIR => IsADirectory,
    -        libc::ELOOP => FilesystemLoop,
    -        libc::ENOENT => NotFound,
    -        libc::ENOMEM => OutOfMemory,
    -        libc::ENOSPC => StorageFull,
    -        libc::ENOSYS => Unsupported,
    -        libc::EMLINK => TooManyLinks,
    -        libc::ENAMETOOLONG => InvalidFilename,
    -        libc::ENETDOWN => NetworkDown,
    -        libc::ENETUNREACH => NetworkUnreachable,
    -        libc::ENOTCONN => NotConnected,
    -        libc::ENOTDIR => NotADirectory,
    -        libc::ENOTEMPTY => DirectoryNotEmpty,
    -        libc::EPIPE => BrokenPipe,
    -        libc::EROFS => ReadOnlyFilesystem,
    -        libc::ESPIPE => NotSeekable,
    -        libc::ESTALE => StaleNetworkFileHandle,
    -        libc::ETIMEDOUT => TimedOut,
    -        libc::ETXTBSY => ExecutableFileBusy,
    -        libc::EXDEV => CrossesDevices,
    -
    -        libc::EACCES | libc::EPERM => PermissionDenied,
    -
    -        // These two constants can have the same value on some systems,
    -        // but different values on others, so we can't use a match
    -        // clause
    -        x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
    -
    -        _ => Uncategorized,
    -    }
    -}
    -
     #[doc(hidden)]
     pub trait IsMinusOne {
         fn is_minus_one(&self) -> bool;
    diff --git a/library/std/src/sys/pal/teeos/os.rs b/library/std/src/sys/pal/teeos/os.rs
    index 512b3e2885bf..a4b1d3c6ae67 100644
    --- a/library/std/src/sys/pal/teeos/os.rs
    +++ b/library/std/src/sys/pal/teeos/os.rs
    @@ -7,10 +7,6 @@ use crate::ffi::{OsStr, OsString};
     use crate::path::PathBuf;
     use crate::{fmt, io, path};
     
    -pub fn errno() -> i32 {
    -    unsafe { (*libc::__errno_location()) as i32 }
    -}
    -
     // Hardcoded to return 4096, since `sysconf` is only implemented as a stub.
     pub fn page_size() -> usize {
         // unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize };
    @@ -19,10 +15,6 @@ pub fn page_size() -> usize {
     
     // Everything below are stubs and copied from unsupported.rs
     
    -pub fn error_string(_errno: i32) -> String {
    -    "error string unimplemented".to_string()
    -}
    -
     pub fn getcwd() -> io::Result {
         unsupported()
     }
    diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
    index e2f99d6751f5..b181d78c2345 100644
    --- a/library/std/src/sys/pal/uefi/mod.rs
    +++ b/library/std/src/sys/pal/uefi/mod.rs
    @@ -83,52 +83,6 @@ pub const fn unsupported_err() -> io::Error {
         io::const_error!(io::ErrorKind::Unsupported, "operation not supported on UEFI")
     }
     
    -pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
    -    use r_efi::efi::Status;
    -
    -    match r_efi::efi::Status::from_usize(code) {
    -        Status::ALREADY_STARTED
    -        | Status::COMPROMISED_DATA
    -        | Status::CONNECTION_FIN
    -        | Status::CRC_ERROR
    -        | Status::DEVICE_ERROR
    -        | Status::END_OF_MEDIA
    -        | Status::HTTP_ERROR
    -        | Status::ICMP_ERROR
    -        | Status::INCOMPATIBLE_VERSION
    -        | Status::LOAD_ERROR
    -        | Status::MEDIA_CHANGED
    -        | Status::NO_MAPPING
    -        | Status::NO_MEDIA
    -        | Status::NOT_STARTED
    -        | Status::PROTOCOL_ERROR
    -        | Status::PROTOCOL_UNREACHABLE
    -        | Status::TFTP_ERROR
    -        | Status::VOLUME_CORRUPTED => io::ErrorKind::Other,
    -        Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => io::ErrorKind::InvalidData,
    -        Status::ABORTED => io::ErrorKind::ConnectionAborted,
    -        Status::ACCESS_DENIED => io::ErrorKind::PermissionDenied,
    -        Status::BUFFER_TOO_SMALL => io::ErrorKind::FileTooLarge,
    -        Status::CONNECTION_REFUSED => io::ErrorKind::ConnectionRefused,
    -        Status::CONNECTION_RESET => io::ErrorKind::ConnectionReset,
    -        Status::END_OF_FILE => io::ErrorKind::UnexpectedEof,
    -        Status::HOST_UNREACHABLE => io::ErrorKind::HostUnreachable,
    -        Status::INVALID_PARAMETER => io::ErrorKind::InvalidInput,
    -        Status::IP_ADDRESS_CONFLICT => io::ErrorKind::AddrInUse,
    -        Status::NETWORK_UNREACHABLE => io::ErrorKind::NetworkUnreachable,
    -        Status::NO_RESPONSE => io::ErrorKind::HostUnreachable,
    -        Status::NOT_FOUND => io::ErrorKind::NotFound,
    -        Status::NOT_READY => io::ErrorKind::ResourceBusy,
    -        Status::OUT_OF_RESOURCES => io::ErrorKind::OutOfMemory,
    -        Status::SECURITY_VIOLATION => io::ErrorKind::PermissionDenied,
    -        Status::TIMEOUT => io::ErrorKind::TimedOut,
    -        Status::UNSUPPORTED => io::ErrorKind::Unsupported,
    -        Status::VOLUME_FULL => io::ErrorKind::StorageFull,
    -        Status::WRITE_PROTECTED => io::ErrorKind::ReadOnlyFilesystem,
    -        _ => io::ErrorKind::Uncategorized,
    -    }
    -}
    -
     pub fn abort_internal() -> ! {
         if let Some(exit_boot_service_event) =
             NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire))
    @@ -158,7 +112,3 @@ pub fn abort_internal() -> ! {
     extern "efiapi" fn exit_boot_service_handler(_e: r_efi::efi::Event, _ctx: *mut crate::ffi::c_void) {
         uefi::env::disable_boot_services();
     }
    -
    -pub fn is_interrupted(_code: io::RawOsError) -> bool {
    -    false
    -}
    diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs
    index 5593e195178d..178f7f506341 100644
    --- a/library/std/src/sys/pal/uefi/os.rs
    +++ b/library/std/src/sys/pal/uefi/os.rs
    @@ -9,59 +9,6 @@ use crate::path::{self, PathBuf};
     use crate::ptr::NonNull;
     use crate::{fmt, io};
     
    -pub fn errno() -> io::RawOsError {
    -    0
    -}
    -
    -pub fn error_string(errno: io::RawOsError) -> String {
    -    // Keep the List in Alphabetical Order
    -    // The Messages are taken from UEFI Specification Appendix D - Status Codes
    -    #[rustfmt::skip]
    -    let msg = match r_efi::efi::Status::from_usize(errno) {
    -        Status::ABORTED => "The operation was aborted.",
    -        Status::ACCESS_DENIED => "Access was denied.",
    -        Status::ALREADY_STARTED => "The protocol has already been started.",
    -        Status::BAD_BUFFER_SIZE => "The buffer was not the proper size for the request.",
    -        Status::BUFFER_TOO_SMALL => "The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs.",
    -        Status::COMPROMISED_DATA => "The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status.",
    -        Status::CONNECTION_FIN => "The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance.",
    -        Status::CONNECTION_REFUSED => "The receiving or transmission operation fails because this connection is refused.",
    -        Status::CONNECTION_RESET => "The connect fails because the connection is reset either by instance itself or the communication peer.",
    -        Status::CRC_ERROR => "A CRC error was detected.",
    -        Status::DEVICE_ERROR => "The physical device reported an error while attempting the operation.",
    -        Status::END_OF_FILE => "The end of the file was reached.",
    -        Status::END_OF_MEDIA => "Beginning or end of media was reached",
    -        Status::HOST_UNREACHABLE => "The remote host is not reachable.",
    -        Status::HTTP_ERROR => "A HTTP error occurred during the network operation.",
    -        Status::ICMP_ERROR => "An ICMP error occurred during the network operation.",
    -        Status::INCOMPATIBLE_VERSION => "The function encountered an internal version that was incompatible with a version requested by the caller.",
    -        Status::INVALID_LANGUAGE => "The language specified was invalid.",
    -        Status::INVALID_PARAMETER => "A parameter was incorrect.",
    -        Status::IP_ADDRESS_CONFLICT => "There is an address conflict address allocation",
    -        Status::LOAD_ERROR => "The image failed to load.",
    -        Status::MEDIA_CHANGED => "The medium in the device has changed since the last access.",
    -        Status::NETWORK_UNREACHABLE => "The network containing the remote host is not reachable.",
    -        Status::NO_MAPPING => "A mapping to a device does not exist.",
    -        Status::NO_MEDIA => "The device does not contain any medium to perform the operation.",
    -        Status::NO_RESPONSE => "The server was not found or did not respond to the request.",
    -        Status::NOT_FOUND => "The item was not found.",
    -        Status::NOT_READY => "There is no data pending upon return.",
    -        Status::NOT_STARTED => "The protocol has not been started.",
    -        Status::OUT_OF_RESOURCES => "A resource has run out.",
    -        Status::PROTOCOL_ERROR => "A protocol error occurred during the network operation.",
    -        Status::PROTOCOL_UNREACHABLE => "An ICMP protocol unreachable error is received.",
    -        Status::SECURITY_VIOLATION => "The function was not performed due to a security violation.",
    -        Status::TFTP_ERROR => "A TFTP error occurred during the network operation.",
    -        Status::TIMEOUT => "The timeout time expired.",
    -        Status::UNSUPPORTED => "The operation is not supported.",
    -        Status::VOLUME_FULL => "There is no more space on the file system.",
    -        Status::VOLUME_CORRUPTED => "An inconstancy was detected on the file system causing the operating to fail.",
    -        Status::WRITE_PROTECTED => "The device cannot be written to.",
    -        _ => return format!("Status: {errno}"),
    -    };
    -    msg.to_owned()
    -}
    -
     pub fn getcwd() -> io::Result {
         match helpers::open_shell() {
             Some(shell) => {
    diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs
    index 265067d84d50..2948d3d594ea 100644
    --- a/library/std/src/sys/pal/unix/futex.rs
    +++ b/library/std/src/sys/pal/unix/futex.rs
    @@ -86,7 +86,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option)
                 }
             };
     
    -        match (r < 0).then(super::os::errno) {
    +        match (r < 0).then(crate::sys::io::errno) {
                 Some(libc::ETIMEDOUT) => return false,
                 Some(libc::EINTR) => continue,
                 _ => return true,
    @@ -167,7 +167,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option)
             )
         };
     
    -    r == 0 || super::os::errno() != libc::ETIMEDOUT
    +    r == 0 || crate::sys::io::errno() != libc::ETIMEDOUT
     }
     
     #[cfg(target_os = "openbsd")]
    @@ -210,7 +210,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option)
             libc::umtx_sleep(futex as *const Atomic as *const i32, expected as i32, timeout_ms)
         };
     
    -    r == 0 || super::os::errno() != libc::ETIMEDOUT
    +    r == 0 || crate::sys::io::errno() != libc::ETIMEDOUT
     }
     
     // DragonflyBSD doesn't tell us how many threads are woken up, so this always returns false.
    diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
    index f24898671af8..6127bb98f80e 100644
    --- a/library/std/src/sys/pal/unix/mod.rs
    +++ b/library/std/src/sys/pal/unix/mod.rs
    @@ -91,7 +91,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
                 target_vendor = "apple",
             )))]
             'poll: {
    -            use crate::sys::os::errno;
    +            use crate::sys::io::errno;
                 let pfds: &mut [_] = &mut [
                     libc::pollfd { fd: 0, events: 0, revents: 0 },
                     libc::pollfd { fd: 1, events: 0, revents: 0 },
    @@ -135,7 +135,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
                 target_os = "vita",
             )))]
             {
    -            use crate::sys::os::errno;
    +            use crate::sys::io::errno;
                 for fd in 0..3 {
                     if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
                         open_devnull();
    @@ -224,63 +224,6 @@ pub unsafe fn cleanup() {
     #[allow(unused_imports)]
     pub use libc::signal;
     
    -#[inline]
    -pub(crate) fn is_interrupted(errno: i32) -> bool {
    -    errno == libc::EINTR
    -}
    -
    -pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
    -    use io::ErrorKind::*;
    -    match errno as libc::c_int {
    -        libc::E2BIG => ArgumentListTooLong,
    -        libc::EADDRINUSE => AddrInUse,
    -        libc::EADDRNOTAVAIL => AddrNotAvailable,
    -        libc::EBUSY => ResourceBusy,
    -        libc::ECONNABORTED => ConnectionAborted,
    -        libc::ECONNREFUSED => ConnectionRefused,
    -        libc::ECONNRESET => ConnectionReset,
    -        libc::EDEADLK => Deadlock,
    -        libc::EDQUOT => QuotaExceeded,
    -        libc::EEXIST => AlreadyExists,
    -        libc::EFBIG => FileTooLarge,
    -        libc::EHOSTUNREACH => HostUnreachable,
    -        libc::EINTR => Interrupted,
    -        libc::EINVAL => InvalidInput,
    -        libc::EISDIR => IsADirectory,
    -        libc::ELOOP => FilesystemLoop,
    -        libc::ENOENT => NotFound,
    -        libc::ENOMEM => OutOfMemory,
    -        libc::ENOSPC => StorageFull,
    -        libc::ENOSYS => Unsupported,
    -        libc::EMLINK => TooManyLinks,
    -        libc::ENAMETOOLONG => InvalidFilename,
    -        libc::ENETDOWN => NetworkDown,
    -        libc::ENETUNREACH => NetworkUnreachable,
    -        libc::ENOTCONN => NotConnected,
    -        libc::ENOTDIR => NotADirectory,
    -        #[cfg(not(target_os = "aix"))]
    -        libc::ENOTEMPTY => DirectoryNotEmpty,
    -        libc::EPIPE => BrokenPipe,
    -        libc::EROFS => ReadOnlyFilesystem,
    -        libc::ESPIPE => NotSeekable,
    -        libc::ESTALE => StaleNetworkFileHandle,
    -        libc::ETIMEDOUT => TimedOut,
    -        libc::ETXTBSY => ExecutableFileBusy,
    -        libc::EXDEV => CrossesDevices,
    -        libc::EINPROGRESS => InProgress,
    -        libc::EOPNOTSUPP => Unsupported,
    -
    -        libc::EACCES | libc::EPERM => PermissionDenied,
    -
    -        // These two constants can have the same value on some systems,
    -        // but different values on others, so we can't use a match
    -        // clause
    -        x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
    -
    -        _ => Uncategorized,
    -    }
    -}
    -
     #[doc(hidden)]
     pub trait IsMinusOne {
         fn is_minus_one(&self) -> bool;
    diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
    index ef3b4a02f8ae..b8280a8f29a0 100644
    --- a/library/std/src/sys/pal/unix/os.rs
    +++ b/library/std/src/sys/pal/unix/os.rs
    @@ -14,135 +14,8 @@ use crate::sys::cvt;
     use crate::sys::helpers::run_path_with_cstr;
     use crate::{fmt, io, iter, mem, ptr, slice, str};
     
    -const TMPBUF_SZ: usize = 128;
    -
     const PATH_SEPARATOR: u8 = b':';
     
    -unsafe extern "C" {
    -    #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
    -    #[cfg_attr(
    -        any(
    -            target_os = "linux",
    -            target_os = "emscripten",
    -            target_os = "fuchsia",
    -            target_os = "l4re",
    -            target_os = "hurd",
    -        ),
    -        link_name = "__errno_location"
    -    )]
    -    #[cfg_attr(
    -        any(
    -            target_os = "netbsd",
    -            target_os = "openbsd",
    -            target_os = "cygwin",
    -            target_os = "android",
    -            target_os = "redox",
    -            target_os = "nuttx",
    -            target_env = "newlib"
    -        ),
    -        link_name = "__errno"
    -    )]
    -    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")]
    -    #[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")]
    -    #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")]
    -    #[cfg_attr(target_os = "haiku", link_name = "_errnop")]
    -    #[cfg_attr(target_os = "aix", link_name = "_Errno")]
    -    // SAFETY: this will always return the same pointer on a given thread.
    -    #[unsafe(ffi_const)]
    -    pub safe fn errno_location() -> *mut c_int;
    -}
    -
    -/// Returns the platform-specific value of errno
    -#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
    -#[inline]
    -pub fn errno() -> i32 {
    -    unsafe { (*errno_location()) as i32 }
    -}
    -
    -/// Sets the platform-specific value of errno
    -// needed for readdir and syscall!
    -#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
    -#[allow(dead_code)] // but not all target cfgs actually end up using it
    -#[inline]
    -pub fn set_errno(e: i32) {
    -    unsafe { *errno_location() = e as c_int }
    -}
    -
    -#[cfg(target_os = "vxworks")]
    -#[inline]
    -pub fn errno() -> i32 {
    -    unsafe { libc::errnoGet() }
    -}
    -
    -#[cfg(target_os = "rtems")]
    -#[inline]
    -pub fn errno() -> i32 {
    -    unsafe extern "C" {
    -        #[thread_local]
    -        static _tls_errno: c_int;
    -    }
    -
    -    unsafe { _tls_errno as i32 }
    -}
    -
    -#[cfg(target_os = "dragonfly")]
    -#[inline]
    -pub fn errno() -> i32 {
    -    unsafe extern "C" {
    -        #[thread_local]
    -        static errno: c_int;
    -    }
    -
    -    unsafe { errno as i32 }
    -}
    -
    -#[cfg(target_os = "dragonfly")]
    -#[allow(dead_code)]
    -#[inline]
    -pub fn set_errno(e: i32) {
    -    unsafe extern "C" {
    -        #[thread_local]
    -        static mut errno: c_int;
    -    }
    -
    -    unsafe {
    -        errno = e;
    -    }
    -}
    -
    -/// Gets a detailed string description for the given error number.
    -pub fn error_string(errno: i32) -> String {
    -    unsafe extern "C" {
    -        #[cfg_attr(
    -            all(
    -                any(
    -                    target_os = "linux",
    -                    target_os = "hurd",
    -                    target_env = "newlib",
    -                    target_os = "cygwin"
    -                ),
    -                not(target_env = "ohos")
    -            ),
    -            link_name = "__xpg_strerror_r"
    -        )]
    -        fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int;
    -    }
    -
    -    let mut buf = [0 as c_char; TMPBUF_SZ];
    -
    -    let p = buf.as_mut_ptr();
    -    unsafe {
    -        if strerror_r(errno as c_int, p, buf.len()) < 0 {
    -            panic!("strerror_r failure");
    -        }
    -
    -        let p = p as *const _;
    -        // We can't always expect a UTF-8 environment. When we don't get that luxury,
    -        // it's better to give a low-quality error message than none at all.
    -        String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into()
    -    }
    -}
    -
     #[cfg(target_os = "espidf")]
     pub fn getcwd() -> io::Result {
         Ok(PathBuf::from("/"))
    diff --git a/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs b/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs
    index 42eb0cd9a61a..45e2f09f303c 100644
    --- a/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs
    +++ b/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs
    @@ -29,7 +29,7 @@ use crate::hint::spin_loop;
     use crate::ops::Range;
     use crate::sync::Mutex;
     use crate::sync::atomic::{AtomicUsize, Ordering};
    -use crate::sys::os::errno_location;
    +use crate::sys::io::errno_location;
     
     pub struct ThreadInfo {
         pub tid: u64,
    diff --git a/library/std/src/sys/pal/unsupported/common.rs b/library/std/src/sys/pal/unsupported/common.rs
    index 34a766683830..d94b9015d0f5 100644
    --- a/library/std/src/sys/pal/unsupported/common.rs
    +++ b/library/std/src/sys/pal/unsupported/common.rs
    @@ -16,14 +16,6 @@ pub fn unsupported_err() -> std_io::Error {
         std_io::Error::UNSUPPORTED_PLATFORM
     }
     
    -pub fn is_interrupted(_code: i32) -> bool {
    -    false
    -}
    -
    -pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
    -    crate::io::ErrorKind::Uncategorized
    -}
    -
     pub fn abort_internal() -> ! {
         core::intrinsics::abort();
     }
    diff --git a/library/std/src/sys/pal/unsupported/os.rs b/library/std/src/sys/pal/unsupported/os.rs
    index 13d2a2044f48..cb925ef4348d 100644
    --- a/library/std/src/sys/pal/unsupported/os.rs
    +++ b/library/std/src/sys/pal/unsupported/os.rs
    @@ -4,14 +4,6 @@ use crate::marker::PhantomData;
     use crate::path::{self, PathBuf};
     use crate::{fmt, io};
     
    -pub fn errno() -> i32 {
    -    0
    -}
    -
    -pub fn error_string(_errno: i32) -> String {
    -    "operation successful".to_string()
    -}
    -
     pub fn getcwd() -> io::Result {
         unsupported()
     }
    diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs
    index 049b435905d4..0abfc2fd7986 100644
    --- a/library/std/src/sys/pal/vexos/mod.rs
    +++ b/library/std/src/sys/pal/vexos/mod.rs
    @@ -5,9 +5,7 @@ pub mod time;
     #[path = "../unsupported/common.rs"]
     mod unsupported_common;
     
    -pub use unsupported_common::{
    -    decode_error_kind, init, is_interrupted, unsupported, unsupported_err,
    -};
    +pub use unsupported_common::{init, unsupported, unsupported_err};
     
     use crate::arch::global_asm;
     use crate::ptr;
    diff --git a/library/std/src/sys/pal/vexos/os.rs b/library/std/src/sys/pal/vexos/os.rs
    index 405f7c918f4a..303b452a078f 100644
    --- a/library/std/src/sys/pal/vexos/os.rs
    +++ b/library/std/src/sys/pal/vexos/os.rs
    @@ -2,8 +2,8 @@
     #[path = "../unsupported/os.rs"]
     mod unsupported_os;
     pub use unsupported_os::{
    -    JoinPathsError, SplitPaths, chdir, current_exe, errno, error_string, getcwd, getpid, home_dir,
    -    join_paths, split_paths, temp_dir,
    +    JoinPathsError, SplitPaths, chdir, current_exe, getcwd, getpid, home_dir, join_paths,
    +    split_paths, temp_dir,
     };
     
     pub use super::unsupported;
    diff --git a/library/std/src/sys/pal/wasi/helpers.rs b/library/std/src/sys/pal/wasi/helpers.rs
    index 6bc41d469584..4f2eb1148f0b 100644
    --- a/library/std/src/sys/pal/wasi/helpers.rs
    +++ b/library/std/src/sys/pal/wasi/helpers.rs
    @@ -1,63 +1,11 @@
     #![forbid(unsafe_op_in_unsafe_fn)]
     
    -use crate::io as std_io;
    -
    -#[inline]
    -pub fn is_interrupted(errno: i32) -> bool {
    -    errno == libc::EINTR
    -}
    -
    -pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
    -    use std_io::ErrorKind::*;
    -    match errno as libc::c_int {
    -        libc::E2BIG => ArgumentListTooLong,
    -        libc::EADDRINUSE => AddrInUse,
    -        libc::EADDRNOTAVAIL => AddrNotAvailable,
    -        libc::EBUSY => ResourceBusy,
    -        libc::ECONNABORTED => ConnectionAborted,
    -        libc::ECONNREFUSED => ConnectionRefused,
    -        libc::ECONNRESET => ConnectionReset,
    -        libc::EDEADLK => Deadlock,
    -        libc::EDQUOT => QuotaExceeded,
    -        libc::EEXIST => AlreadyExists,
    -        libc::EFBIG => FileTooLarge,
    -        libc::EHOSTUNREACH => HostUnreachable,
    -        libc::EINTR => Interrupted,
    -        libc::EINVAL => InvalidInput,
    -        libc::EISDIR => IsADirectory,
    -        libc::ELOOP => FilesystemLoop,
    -        libc::ENOENT => NotFound,
    -        libc::ENOMEM => OutOfMemory,
    -        libc::ENOSPC => StorageFull,
    -        libc::ENOSYS => Unsupported,
    -        libc::EMLINK => TooManyLinks,
    -        libc::ENAMETOOLONG => InvalidFilename,
    -        libc::ENETDOWN => NetworkDown,
    -        libc::ENETUNREACH => NetworkUnreachable,
    -        libc::ENOTCONN => NotConnected,
    -        libc::ENOTDIR => NotADirectory,
    -        libc::EPIPE => BrokenPipe,
    -        libc::EROFS => ReadOnlyFilesystem,
    -        libc::ESPIPE => NotSeekable,
    -        libc::ESTALE => StaleNetworkFileHandle,
    -        libc::ETIMEDOUT => TimedOut,
    -        libc::ETXTBSY => ExecutableFileBusy,
    -        libc::EXDEV => CrossesDevices,
    -        libc::EINPROGRESS => InProgress,
    -        libc::EOPNOTSUPP => Unsupported,
    -        libc::EACCES | libc::EPERM => PermissionDenied,
    -        libc::EWOULDBLOCK => WouldBlock,
    -
    -        _ => Uncategorized,
    -    }
    -}
    -
     pub fn abort_internal() -> ! {
         unsafe { libc::abort() }
     }
     
     #[inline]
     #[cfg(target_env = "p1")]
    -pub(crate) fn err2io(err: wasi::Errno) -> std_io::Error {
    -    std_io::Error::from_raw_os_error(err.raw().into())
    +pub(crate) fn err2io(err: wasi::Errno) -> crate::io::Error {
    +    crate::io::Error::from_raw_os_error(err.raw().into())
     }
    diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
    index 5d36687df097..9b49db9af6b0 100644
    --- a/library/std/src/sys/pal/wasi/mod.rs
    +++ b/library/std/src/sys/pal/wasi/mod.rs
    @@ -26,9 +26,9 @@ mod helpers;
     // import conflict rules. If we glob export `helpers` and `common` together,
     // then the compiler complains about conflicts.
     
    +pub(crate) use helpers::abort_internal;
     #[cfg(target_env = "p1")]
     pub(crate) use helpers::err2io;
    -pub(crate) use helpers::{abort_internal, decode_error_kind, is_interrupted};
     #[cfg(not(target_env = "p1"))]
     pub use os::IsMinusOne;
     pub use os::{cvt, cvt_r};
    diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs
    index fee187a8adf3..285be3ca9fda 100644
    --- a/library/std/src/sys/pal/wasi/os.rs
    +++ b/library/std/src/sys/pal/wasi/os.rs
    @@ -6,7 +6,7 @@ use crate::os::wasi::prelude::*;
     use crate::path::{self, PathBuf};
     use crate::sys::helpers::run_path_with_cstr;
     use crate::sys::unsupported;
    -use crate::{fmt, io, str};
    +use crate::{fmt, io};
     
     // Add a few symbols not in upstream `libc` just yet.
     pub mod libc {
    @@ -19,34 +19,6 @@ pub mod libc {
         }
     }
     
    -unsafe extern "C" {
    -    #[thread_local]
    -    #[link_name = "errno"]
    -    static mut libc_errno: libc::c_int;
    -}
    -
    -pub fn errno() -> i32 {
    -    unsafe { libc_errno as i32 }
    -}
    -
    -pub fn set_errno(val: i32) {
    -    unsafe {
    -        libc_errno = val;
    -    }
    -}
    -
    -pub fn error_string(errno: i32) -> String {
    -    let mut buf = [0 as libc::c_char; 1024];
    -
    -    let p = buf.as_mut_ptr();
    -    unsafe {
    -        if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 {
    -            panic!("strerror_r failure");
    -        }
    -        str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
    -    }
    -}
    -
     pub fn getcwd() -> io::Result {
         let mut buf = Vec::with_capacity(512);
         loop {
    diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
    index 19f0259b1bf0..17e3cdbecd5c 100644
    --- a/library/std/src/sys/pal/windows/mod.rs
    +++ b/library/std/src/sys/pal/windows/mod.rs
    @@ -60,84 +60,6 @@ pub unsafe fn cleanup() {
         winsock::cleanup();
     }
     
    -#[inline]
    -pub fn is_interrupted(_errno: i32) -> bool {
    -    false
    -}
    -
    -pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
    -    use io::ErrorKind::*;
    -
    -    match errno as u32 {
    -        c::ERROR_ACCESS_DENIED => return PermissionDenied,
    -        c::ERROR_ALREADY_EXISTS => return AlreadyExists,
    -        c::ERROR_FILE_EXISTS => return AlreadyExists,
    -        c::ERROR_BROKEN_PIPE => return BrokenPipe,
    -        c::ERROR_FILE_NOT_FOUND
    -        | c::ERROR_PATH_NOT_FOUND
    -        | c::ERROR_INVALID_DRIVE
    -        | c::ERROR_BAD_NETPATH
    -        | c::ERROR_BAD_NET_NAME => return NotFound,
    -        c::ERROR_NO_DATA => return BrokenPipe,
    -        c::ERROR_INVALID_NAME | c::ERROR_BAD_PATHNAME => return InvalidFilename,
    -        c::ERROR_INVALID_PARAMETER => return InvalidInput,
    -        c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory,
    -        c::ERROR_SEM_TIMEOUT
    -        | c::WAIT_TIMEOUT
    -        | c::ERROR_DRIVER_CANCEL_TIMEOUT
    -        | c::ERROR_OPERATION_ABORTED
    -        | c::ERROR_SERVICE_REQUEST_TIMEOUT
    -        | c::ERROR_COUNTER_TIMEOUT
    -        | c::ERROR_TIMEOUT
    -        | c::ERROR_RESOURCE_CALL_TIMED_OUT
    -        | c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT
    -        | c::ERROR_CTX_CLIENT_QUERY_TIMEOUT
    -        | c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT
    -        | c::ERROR_DS_TIMELIMIT_EXCEEDED
    -        | c::DNS_ERROR_RECORD_TIMED_OUT
    -        | c::ERROR_IPSEC_IKE_TIMED_OUT
    -        | c::ERROR_RUNLEVEL_SWITCH_TIMEOUT
    -        | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return TimedOut,
    -        c::ERROR_CALL_NOT_IMPLEMENTED => return Unsupported,
    -        c::ERROR_HOST_UNREACHABLE => return HostUnreachable,
    -        c::ERROR_NETWORK_UNREACHABLE => return NetworkUnreachable,
    -        c::ERROR_DIRECTORY => return NotADirectory,
    -        c::ERROR_DIRECTORY_NOT_SUPPORTED => return IsADirectory,
    -        c::ERROR_DIR_NOT_EMPTY => return DirectoryNotEmpty,
    -        c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem,
    -        c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull,
    -        c::ERROR_SEEK_ON_DEVICE => return NotSeekable,
    -        c::ERROR_DISK_QUOTA_EXCEEDED => return QuotaExceeded,
    -        c::ERROR_FILE_TOO_LARGE => return FileTooLarge,
    -        c::ERROR_BUSY => return ResourceBusy,
    -        c::ERROR_POSSIBLE_DEADLOCK => return Deadlock,
    -        c::ERROR_NOT_SAME_DEVICE => return CrossesDevices,
    -        c::ERROR_TOO_MANY_LINKS => return TooManyLinks,
    -        c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename,
    -        c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop,
    -        _ => {}
    -    }
    -
    -    match errno {
    -        c::WSAEACCES => PermissionDenied,
    -        c::WSAEADDRINUSE => AddrInUse,
    -        c::WSAEADDRNOTAVAIL => AddrNotAvailable,
    -        c::WSAECONNABORTED => ConnectionAborted,
    -        c::WSAECONNREFUSED => ConnectionRefused,
    -        c::WSAECONNRESET => ConnectionReset,
    -        c::WSAEINVAL => InvalidInput,
    -        c::WSAENOTCONN => NotConnected,
    -        c::WSAEWOULDBLOCK => WouldBlock,
    -        c::WSAETIMEDOUT => TimedOut,
    -        c::WSAEHOSTUNREACH => HostUnreachable,
    -        c::WSAENETDOWN => NetworkDown,
    -        c::WSAENETUNREACH => NetworkUnreachable,
    -        c::WSAEDQUOT => QuotaExceeded,
    -
    -        _ => Uncategorized,
    -    }
    -}
    -
     pub fn unrolled_find_u16s(needle: u16, haystack: &[u16]) -> Option {
         let ptr = haystack.as_ptr();
         let mut start = haystack;
    diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs
    index 1b3c80c079be..3eb6ec827840 100644
    --- a/library/std/src/sys/pal/windows/os.rs
    +++ b/library/std/src/sys/pal/windows/os.rs
    @@ -15,66 +15,6 @@ use crate::path::{self, PathBuf};
     use crate::sys::pal::{c, cvt};
     use crate::{fmt, io, ptr};
     
    -pub fn errno() -> i32 {
    -    api::get_last_error().code as i32
    -}
    -
    -/// Gets a detailed string description for the given error number.
    -pub fn error_string(mut errnum: i32) -> String {
    -    let mut buf = [0 as c::WCHAR; 2048];
    -
    -    unsafe {
    -        let mut module = ptr::null_mut();
    -        let mut flags = 0;
    -
    -        // NTSTATUS errors may be encoded as HRESULT, which may returned from
    -        // GetLastError. For more information about Windows error codes, see
    -        // `[MS-ERREF]`: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548a
    -        if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
    -            // format according to https://support.microsoft.com/en-us/help/259693
    -            const NTDLL_DLL: &[u16] = &[
    -                'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _,
    -                'L' as _, 0,
    -            ];
    -            module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
    -
    -            if !module.is_null() {
    -                errnum ^= c::FACILITY_NT_BIT as i32;
    -                flags = c::FORMAT_MESSAGE_FROM_HMODULE;
    -            }
    -        }
    -
    -        let res = c::FormatMessageW(
    -            flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS,
    -            module,
    -            errnum as u32,
    -            0,
    -            buf.as_mut_ptr(),
    -            buf.len() as u32,
    -            ptr::null(),
    -        ) as usize;
    -        if res == 0 {
    -            // Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId,
    -            let fm_err = errno();
    -            return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})");
    -        }
    -
    -        match String::from_utf16(&buf[..res]) {
    -            Ok(mut msg) => {
    -                // Trim trailing CRLF inserted by FormatMessageW
    -                let len = msg.trim_end().len();
    -                msg.truncate(len);
    -                msg
    -            }
    -            Err(..) => format!(
    -                "OS Error {} (FormatMessageW() returned \
    -                 invalid UTF-16)",
    -                errnum
    -            ),
    -        }
    -    }
    -}
    -
     pub struct SplitPaths<'a> {
         data: EncodeWide<'a>,
         must_yield: bool,
    diff --git a/library/std/src/sys/pal/xous/os.rs b/library/std/src/sys/pal/xous/os.rs
    index 2da711f89dfa..cd7b7b59d112 100644
    --- a/library/std/src/sys/pal/xous/os.rs
    +++ b/library/std/src/sys/pal/xous/os.rs
    @@ -1,7 +1,6 @@
     use super::unsupported;
     use crate::ffi::{OsStr, OsString};
     use crate::marker::PhantomData;
    -use crate::os::xous::ffi::Error as XousError;
     use crate::path::{self, PathBuf};
     use crate::sync::atomic::{Atomic, AtomicPtr, Ordering};
     use crate::{fmt, io};
    @@ -63,14 +62,6 @@ mod c_compat {
         }
     }
     
    -pub fn errno() -> i32 {
    -    0
    -}
    -
    -pub fn error_string(errno: i32) -> String {
    -    Into::::into(errno).to_string()
    -}
    -
     pub fn getcwd() -> io::Result {
         unsupported()
     }
    diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs
    index 6dece1055a08..f09020820a03 100644
    --- a/library/std/src/sys/pal/zkvm/mod.rs
    +++ b/library/std/src/sys/pal/zkvm/mod.rs
    @@ -33,14 +33,6 @@ pub fn unsupported_err() -> std_io::Error {
         std_io::Error::UNSUPPORTED_PLATFORM
     }
     
    -pub fn is_interrupted(_code: i32) -> bool {
    -    false
    -}
    -
    -pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
    -    crate::io::ErrorKind::Uncategorized
    -}
    -
     pub fn abort_internal() -> ! {
         core::intrinsics::abort();
     }
    diff --git a/library/std/src/sys/pal/zkvm/os.rs b/library/std/src/sys/pal/zkvm/os.rs
    index 13d2a2044f48..cb925ef4348d 100644
    --- a/library/std/src/sys/pal/zkvm/os.rs
    +++ b/library/std/src/sys/pal/zkvm/os.rs
    @@ -4,14 +4,6 @@ use crate::marker::PhantomData;
     use crate::path::{self, PathBuf};
     use crate::{fmt, io};
     
    -pub fn errno() -> i32 {
    -    0
    -}
    -
    -pub fn error_string(_errno: i32) -> String {
    -    "operation successful".to_string()
    -}
    -
     pub fn getcwd() -> io::Result {
         unsupported()
     }
    diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs
    index d627a477dc1a..31914aeb67c5 100644
    --- a/library/std/src/sys/process/uefi.rs
    +++ b/library/std/src/sys/process/uefi.rs
    @@ -8,8 +8,8 @@ use crate::num::{NonZero, NonZeroI32};
     use crate::path::Path;
     use crate::process::StdioPipes;
     use crate::sys::fs::File;
    +use crate::sys::io::error_string;
     use crate::sys::pal::helpers;
    -use crate::sys::pal::os::error_string;
     use crate::sys::unsupported;
     use crate::{fmt, io};
     
    diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs
    index 2e1cd7068d7f..f6bbfed61ef3 100644
    --- a/library/std/src/sys/process/unix/common.rs
    +++ b/library/std/src/sys/process/unix/common.rs
    @@ -61,7 +61,7 @@ cfg_select! {
     
                 let bit = (signum - 1) as usize;
                 if set.is_null() || bit >= (8 * size_of::()) {
    -                crate::sys::pal::os::set_errno(libc::EINVAL);
    +                crate::sys::io::set_errno(libc::EINVAL);
                     return -1;
                 }
                 let raw = slice::from_raw_parts_mut(
    diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs
    index 5ba57e11679c..53fe69805de3 100644
    --- a/library/std/src/sys/process/unix/unix.rs
    +++ b/library/std/src/sys/process/unix/unix.rs
    @@ -194,7 +194,7 @@ impl Command {
         // See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html
         #[cfg(target_os = "nto")]
         unsafe fn do_fork(&mut self) -> Result {
    -        use crate::sys::os::errno;
    +        use crate::sys::io::errno;
     
             let mut delay = MIN_FORKSPAWN_SLEEP;
     
    diff --git a/library/std/src/sys/random/linux.rs b/library/std/src/sys/random/linux.rs
    index 53e2f1da6753..a5b790a1db42 100644
    --- a/library/std/src/sys/random/linux.rs
    +++ b/library/std/src/sys/random/linux.rs
    @@ -66,7 +66,7 @@ use crate::os::fd::AsRawFd;
     use crate::sync::OnceLock;
     use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
     use crate::sync::atomic::{Atomic, AtomicBool};
    -use crate::sys::pal::os::errno;
    +use crate::sys::io::errno;
     use crate::sys::pal::weak::syscall;
     
     fn getrandom(mut bytes: &mut [u8], insecure: bool) {
    diff --git a/library/std/src/sys/sync/condvar/windows7.rs b/library/std/src/sys/sync/condvar/windows7.rs
    index f03feef22212..c3f680be4bb5 100644
    --- a/library/std/src/sys/sync/condvar/windows7.rs
    +++ b/library/std/src/sys/sync/condvar/windows7.rs
    @@ -1,6 +1,6 @@
     use crate::cell::UnsafeCell;
    +use crate::sys::c;
     use crate::sys::sync::{Mutex, mutex};
    -use crate::sys::{c, os};
     use crate::time::Duration;
     
     pub struct Condvar {
    @@ -30,7 +30,7 @@ impl Condvar {
                 0,
             );
             if r == 0 {
    -            debug_assert_eq!(os::errno() as usize, c::ERROR_TIMEOUT as usize);
    +            debug_assert_eq!(crate::sys::io::errno() as usize, c::ERROR_TIMEOUT as usize);
                 false
             } else {
                 true
    diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs
    index d0396ed71300..82e2e0456e64 100644
    --- a/library/std/src/sys/thread/unix.rs
    +++ b/library/std/src/sys/thread/unix.rs
    @@ -14,10 +14,9 @@ use crate::num::NonZero;
     use crate::sys::weak::dlsym;
     #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))]
     use crate::sys::weak::weak;
    -use crate::sys::{os, stack_overflow};
     use crate::thread::ThreadInit;
     use crate::time::Duration;
    -use crate::{cmp, io, ptr};
    +use crate::{cmp, io, ptr, sys};
     #[cfg(not(any(
         target_os = "l4re",
         target_os = "vxworks",
    @@ -77,7 +76,7 @@ impl Thread {
                         // multiple of the system page size. Because it's definitely
                         // >= PTHREAD_STACK_MIN, it must be an alignment issue.
                         // Round up to the nearest page and try again.
    -                    let page_size = os::page_size();
    +                    let page_size = sys::os::page_size();
                         let stack_size =
                             (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
     
    @@ -114,7 +113,7 @@ impl Thread {
     
                     // Now that the thread information is set, set up our stack
                     // overflow handler.
    -                let _handler = stack_overflow::Handler::new();
    +                let _handler = sys::stack_overflow::Handler::new();
     
                     rust_start();
                 }
    @@ -536,7 +535,7 @@ pub fn sleep(dur: Duration) {
                 secs -= ts.tv_sec as u64;
                 let ts_ptr = &raw mut ts;
                 if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
    -                assert_eq!(os::errno(), libc::EINTR);
    +                assert_eq!(sys::io::errno(), libc::EINTR);
                     secs += ts.tv_sec as u64;
                     nsecs = ts.tv_nsec;
                 } else {
    
    From 0f25fca1a1f36ae93c76333a11132d8f54350b7c Mon Sep 17 00:00:00 2001
    From: joboet 
    Date: Tue, 6 Jan 2026 13:38:57 +0100
    Subject: [PATCH 2060/3801] update import in UI test
    
    ---
     tests/ui/stability-attribute/stability-in-private-module.rs     | 2 +-
     tests/ui/stability-attribute/stability-in-private-module.stderr | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/tests/ui/stability-attribute/stability-in-private-module.rs b/tests/ui/stability-attribute/stability-in-private-module.rs
    index df94931690b7..000de46ab45e 100644
    --- a/tests/ui/stability-attribute/stability-in-private-module.rs
    +++ b/tests/ui/stability-attribute/stability-in-private-module.rs
    @@ -1,4 +1,4 @@
     fn main() {
    -    let _ = std::sys::os::errno();
    +    let _ = std::sys::io::errno();
         //~^ERROR module `sys` is private
     }
    diff --git a/tests/ui/stability-attribute/stability-in-private-module.stderr b/tests/ui/stability-attribute/stability-in-private-module.stderr
    index e65f8aa9b1fc..ab27f703ab6b 100644
    --- a/tests/ui/stability-attribute/stability-in-private-module.stderr
    +++ b/tests/ui/stability-attribute/stability-in-private-module.stderr
    @@ -1,7 +1,7 @@
     error[E0603]: module `sys` is private
       --> $DIR/stability-in-private-module.rs:2:18
        |
    -LL |     let _ = std::sys::os::errno();
    +LL |     let _ = std::sys::io::errno();
        |                  ^^^      ----- function `errno` is not publicly re-exported
        |                  |
        |                  private module
    
    From 959be82effe087543befbd1aeb0920171ae2fc3f Mon Sep 17 00:00:00 2001
    From: joboet 
    Date: Mon, 12 Jan 2026 13:58:29 +0100
    Subject: [PATCH 2061/3801] std: implement `sleep_until` on Apple platforms
    
    ---
     library/std/src/lib.rs               |  1 +
     library/std/src/sys/pal/unix/time.rs | 52 ++++++++++++++++++++++------
     library/std/src/sys/thread/mod.rs    |  2 ++
     library/std/src/sys/thread/unix.rs   | 41 ++++++++++++++++++++++
     library/std/src/thread/functions.rs  |  1 +
     5 files changed, 87 insertions(+), 10 deletions(-)
    
    diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
    index f5b9f69a5f9f..93f2c519dd1b 100644
    --- a/library/std/src/lib.rs
    +++ b/library/std/src/lib.rs
    @@ -326,6 +326,7 @@
     #![feature(const_convert)]
     #![feature(core_intrinsics)]
     #![feature(core_io_borrowed_buf)]
    +#![feature(cstr_display)]
     #![feature(drop_guard)]
     #![feature(duration_constants)]
     #![feature(error_generic_member_access)]
    diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
    index 50b690256a20..a56034f3778c 100644
    --- a/library/std/src/sys/pal/unix/time.rs
    +++ b/library/std/src/sys/pal/unix/time.rs
    @@ -270,22 +270,25 @@ pub struct Instant {
     }
     
     impl Instant {
    +    // CLOCK_UPTIME_RAW   clock that increments monotonically, in the same man-
    +    //                    ner as CLOCK_MONOTONIC_RAW, but that does not incre-
    +    //                    ment while the system is asleep.  The returned value
    +    //                    is identical to the result of mach_absolute_time()
    +    //                    after the appropriate mach_timebase conversion is
    +    //                    applied.
    +    //
    +    // We use `CLOCK_UPTIME_RAW` instead of `CLOCK_MONOTONIC` since
    +    // `CLOCK_UPTIME_RAW` is based on `mach_absolute_time`, which is the
    +    // clock that all timeouts and deadlines are measured against inside
    +    // the kernel.
         #[cfg(target_vendor = "apple")]
         pub(crate) const CLOCK_ID: libc::clockid_t = libc::CLOCK_UPTIME_RAW;
    +
         #[cfg(not(target_vendor = "apple"))]
         pub(crate) const CLOCK_ID: libc::clockid_t = libc::CLOCK_MONOTONIC;
    +
         pub fn now() -> Instant {
             // https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_getres.html
    -        //
    -        // CLOCK_UPTIME_RAW   clock that increments monotonically, in the same man-
    -        //                    ner as CLOCK_MONOTONIC_RAW, but that does not incre-
    -        //                    ment while the system is asleep.  The returned value
    -        //                    is identical to the result of mach_absolute_time()
    -        //                    after the appropriate mach_timebase conversion is
    -        //                    applied.
    -        //
    -        // Instant on macos was historically implemented using mach_absolute_time;
    -        // we preserve this value domain out of an abundance of caution.
             Instant { t: Timespec::now(Self::CLOCK_ID) }
         }
     
    @@ -308,6 +311,35 @@ impl Instant {
         pub(crate) fn into_timespec(self) -> Timespec {
             self.t
         }
    +
    +    /// Returns `self` converted into units of `mach_absolute_time`, or `None`
    +    /// if `self` is before the system boot time.
    +    #[cfg(target_vendor = "apple")]
    +    pub fn into_mach_absolute_time(self) -> Option {
    +        #[repr(C)]
    +        struct mach_timebase_info {
    +            numer: u32,
    +            denom: u32,
    +        }
    +
    +        unsafe extern "C" {
    +            unsafe fn mach_timebase_info(info: *mut mach_timebase_info) -> libc::kern_return_t;
    +        }
    +
    +        let secs = u64::try_from(self.t.tv_sec).ok()?;
    +
    +        let mut timebase = mach_timebase_info { numer: 0, denom: 0 };
    +        assert_eq!(unsafe { mach_timebase_info(&mut timebase) }, libc::KERN_SUCCESS);
    +
    +        // Since `tv_sec` is 64-bit and `tv_nsec` is smaller than 1 billion,
    +        // this cannot overflow. The resulting number needs at most 94 bits.
    +        let nanos =
    +            u128::from(secs) * u128::from(NSEC_PER_SEC) + u128::from(self.t.tv_nsec.as_inner());
    +        // This multiplication cannot overflow since multiplying a 94-bit
    +        // number by a 32-bit number yields a number that needs at most
    +        // 126 bits.
    +        Some(nanos * u128::from(timebase.denom) / u128::from(timebase.numer))
    +    }
     }
     
     impl AsInner for Instant {
    diff --git a/library/std/src/sys/thread/mod.rs b/library/std/src/sys/thread/mod.rs
    index cb6bf6518f81..3460270b15fc 100644
    --- a/library/std/src/sys/thread/mod.rs
    +++ b/library/std/src/sys/thread/mod.rs
    @@ -73,6 +73,7 @@ cfg_select! {
                 target_os = "fuchsia",
                 target_os = "vxworks",
                 target_os = "wasi",
    +            target_vendor = "apple",
             ))]
             pub use unix::sleep_until;
             #[expect(dead_code)]
    @@ -133,6 +134,7 @@ cfg_select! {
         target_os = "fuchsia",
         target_os = "vxworks",
         target_os = "wasi",
    +    target_vendor = "apple",
     )))]
     pub fn sleep_until(deadline: crate::time::Instant) {
         use crate::time::Instant;
    diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs
    index d0396ed71300..e52bc63ea5b1 100644
    --- a/library/std/src/sys/thread/unix.rs
    +++ b/library/std/src/sys/thread/unix.rs
    @@ -636,6 +636,47 @@ pub fn sleep_until(deadline: crate::time::Instant) {
         }
     }
     
    +#[cfg(target_vendor = "apple")]
    +pub fn sleep_until(deadline: crate::time::Instant) {
    +    unsafe extern "C" {
    +        // This is defined in the public header mach/mach_time.h alongside
    +        // `mach_absolute_time`, and like it has been available since the very
    +        // beginning.
    +        //
    +        // There isn't really any documentation on this function, except for a
    +        // short reference in technical note 2169:
    +        // https://developer.apple.com/library/archive/technotes/tn2169/_index.html
    +        safe fn mach_wait_until(deadline: u64) -> libc::kern_return_t;
    +    }
    +
    +    let Some(deadline) = deadline.into_inner().into_mach_absolute_time() else {
    +        // Since the deadline is before the system boot time, it has already
    +        // passed, so we can return immediately.
    +        return;
    +    };
    +
    +    // If the deadline is not representable, then sleep for the maximum duration
    +    // possible and worry about the potential clock issues later (in ca. 600 years).
    +    let deadline = deadline.try_into().unwrap_or(u64::MAX);
    +    loop {
    +        match mach_wait_until(deadline) {
    +            // Success! The deadline has passed.
    +            libc::KERN_SUCCESS => break,
    +            // If the sleep gets interrupted by a signal, `mach_wait_until`
    +            // returns KERN_ABORTED, so we need to restart the syscall.
    +            // Also see Apple's implementation of the POSIX `nanosleep`, which
    +            // converts this error to the POSIX equivalent EINTR:
    +            // https://github.com/apple-oss-distributions/Libc/blob/55b54c0a0c37b3b24393b42b90a4c561d6c606b1/gen/nanosleep.c#L281-L306
    +            libc::KERN_ABORTED => continue,
    +            // All other errors indicate that something has gone wrong...
    +            error => {
    +                let description = unsafe { CStr::from_ptr(libc::mach_error_string(error)) };
    +                panic!("mach_wait_until failed: {} (code {error})", description.display())
    +            }
    +        }
    +    }
    +}
    +
     pub fn yield_now() {
         let ret = unsafe { libc::sched_yield() };
         debug_assert_eq!(ret, 0);
    diff --git a/library/std/src/thread/functions.rs b/library/std/src/thread/functions.rs
    index a25bae1aae31..73d727878570 100644
    --- a/library/std/src/thread/functions.rs
    +++ b/library/std/src/thread/functions.rs
    @@ -318,6 +318,7 @@ pub fn sleep(dur: Duration) {
     /// | Hurd      | [clock_nanosleep] (Monotonic Clock)]                                 |
     /// | Fuchsia   | [clock_nanosleep] (Monotonic Clock)]                                 |
     /// | Vxworks   | [clock_nanosleep] (Monotonic Clock)]                                 |
    +/// | Apple     | `mach_wait_until`                                                    |
     /// | Other     | `sleep_until` uses [`sleep`] and does not issue a syscall itself     |
     ///
     /// [currently]: crate::io#platform-specific-behavior
    
    From f09b0bc2cb7b7f43ecd6e0adee5e7b3dbc2c1290 Mon Sep 17 00:00:00 2001
    From: reucru01 
    Date: Mon, 22 Dec 2025 10:31:05 +0000
    Subject: [PATCH 2062/3801] Creates README for stdarch-gen-arm
    
    ---
     .../stdarch/crates/stdarch-gen-arm/README.md  | 300 ++++++++++++++++++
     1 file changed, 300 insertions(+)
     create mode 100644 library/stdarch/crates/stdarch-gen-arm/README.md
    
    diff --git a/library/stdarch/crates/stdarch-gen-arm/README.md b/library/stdarch/crates/stdarch-gen-arm/README.md
    new file mode 100644
    index 000000000000..4da14bcbb6c9
    --- /dev/null
    +++ b/library/stdarch/crates/stdarch-gen-arm/README.md
    @@ -0,0 +1,300 @@
    +# stdarch-gen-arm generator guide
    +## Running the generator
    +- Run: `cargo run --bin=stdarch-gen-arm -- crates/stdarch-gen-arm/spec`
    +```
    +$ cargo run --bin=stdarch-gen-arm -- crates/stdarch-gen-arm/spec
    +    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.18s
    +     Running `target/debug/stdarch-gen-arm crates/stdarch-gen-arm/spec`
    +```
    +## Input/Output
    +### Input files (intrinsic YAML definitions)
    + - `crates/stdarch-gen-arm/spec//*.spec.yml`
    +### Output files
    + - Generated intrinsics:
    +	 - `crates/core_arch/src///generated.rs`
    + - Generated load/store tests:
    +	 - `crates/core_arch/src///ld_st_tests_.rs`
    +	 - Only generated when `test: { load:  }` or `test: { store:  }` is set for SVE/SVE2 intrinsics.
    +## `.spec.yml` file anatomy
    +```
    +---
    +Configs
    +---
    +Variable definitions
    +---
    +
    +Intrinsic definitions
    +
    +---
    +```
    +- If you're new to YAML syntax, consider [reviewing](https://quickref.me/yaml.html) some of the less obvious syntax and features.
    +- For example, mapping an attribute to a sequence can be done in two different ways:
    +```yaml
    +attribute: [item_a, item_b, item_c]
    +```
    +or
    +```yaml
    +attribute:
    +    - item_a
    +    - item_b
    +    - item_c
    +``` 
    +## Configs
    +- Mappings defining top-level settings applied to all intrinsics:
    +- `arch_cfgs`
    +    - Sequence of mappings specifying `arch_name`, `target_feature` (sequence), and `llvm_prefix`.
    +- `uses_neon_types`(_Optional_)
    +    - A boolean specifying whether to emit NEON type imports in generated code.
    +- `auto_big_endian`(_Optional_)
    +    - A boolean specifying whether to auto-generate big-endian shuffles when possible.
    +- `auto_llvm_sign_conversion`(_Optional_)
    +    - A boolean specifying whether to auto-convert LLVM wrapper args to signed types.
    +## Variable definitions
    +- Defines YAML anchors/variables to avoid repetition.
    +- Commonly used for stability attributes, cfgs and target features.
    +## Intrinsic definitions
    +### Example
    +```yaml
    +    - name: "vtst{neon_type[0].no}"
    +      doc: "Signed compare bitwise Test bits nonzero"
    +      arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    +      return_type: "{neon_type[1]}"
    +      attr:
    +        - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [cmtst]]}]]
    +        - FnCall: [stable, ['feature = "neon_intrinsics"', 'since = "1.59.0"']]
    +      safety: safe
    +      types:
    +        - [int64x1_t, uint64x1_t, 'i64x1', 'i64x1::new(0)']
    +        - [int64x2_t, uint64x2_t, 'i64x2', 'i64x2::new(0, 0)']
    +        - [poly64x1_t, uint64x1_t, 'i64x1', 'i64x1::new(0)']
    +        - [poly64x2_t, uint64x2_t, 'i64x2', 'i64x2::new(0, 0)']
    +      compose:
    +        - Let: [c, "{neon_type[0]}", {FnCall: [simd_and, [a, b]]}]
    +        - Let: [d, "{type[2]}", "{type[3]}"]
    +        - FnCall: [simd_ne, [c, {FnCall: [transmute, [d]]}]]
    +```
    +
    +### Explanation of fields
    +- `name`
    +    - The name of the intrinsic
    +    - Often built from a base name followed by a type suffix
    +- `doc` (_Optional_)
    +    - A string explaining the purpose of the intrinsic
    +- `static_defs` (_Optional_)
    +    - A sequence of const generics of the format `"const : "`
    +- `arguments`
    +    - A sequence of strings in the format `": "`
    +- `return_type` (_Optional_)
    +    - A string specifying the return type. If omitted, the intrinsic returns `()`.
    +- `attr` (_Optional_)
    +    - A sequence of items defining the attributes to be applied to the intrinsic. Often stability attributes, target features, or `assert_instr` tests. At least one of `attr` or `assert_instr` must be set.
    +- `target_features` (_Optional_)
    +    - A sequence of target features to enable for this intrinsic (merged with any global `arch_cfgs` settings).
    +- `assert_instr` (_Optional_)
    +    - A sequence of strings expected to be found in the assembly. Required if `attr` is not set.
    +- `safety` (_Optional_)
    +    - Use `safe`, or map `unsafe:` to a sequence of unsafety comments:
    +        - `custom: ""`
    +        - `uninitialized`
    +        - `pointer_offset`, `pointer_offset_vnum`, or `dereference` (optionally qualified with `predicated`, `predicated_non_faulting`, or `predicated_first_faulting`)
    +        - `unpredictable_on_fault`
    +        - `non_temporal`
    +        - `neon`
    +        - `no_provenance: ""`
    +- `substitutions` (_Optional_)
    +    - Mappings of custom wildcard names to either `MatchSize` or `MatchKind` expressions
    +- `types`
    +    - A sequence or sequence of sequences specifying the types to use when producing each intrinsic variant. These sequences can then be indexed by wildcards.
    +- `constraints` (_Optional_)
    +    - A sequence of mappings. Each specifies a variable and a constraint. The available mappings are:
    +    - Assert a variable's value exists in a sequence of i32's
    +        - Usage: `{ variable: , any_values: [,...] }`
    +    - Assert a variable's value exists in a range (inclusive)
    +        - Usage: `{ variable: , range: [, ] }`
    +    - Assert a variable's value exists in a range via a match (inclusive)
    +        - Usage: `{ variable: , range:  }`
    +    - Assert a variable's value does not exceed the number of elements in a SVE type ``.
    +        - Usage: `{ variable: , sve_max_elems_type:  }`
    +    - Assert a variable's value does not exceed the number of elements in a vector type ``.
    +        - Usage: `{ variable: , vec_max_elems_type:  }`
    +- `predication_methods` (_Optional_)
    +    - Configuration for predicate-form variants. Only used when the intrinsic name includes an `_m*_` wildcard (e.g., `{_mx}`, `{_mxz}`).
    +    - `zeroing_method`: Required when requesting `_z`; either `{ drop:  }` to remove an argument and replace it with a zero initialiser, or `{ select:  }` to select zeros into a predicate.
    +    - `dont_care_method`: How `_x` should be implemented (`inferred`, `as_zeroing`, or `as_merging`).
    +- `compose`
    +    - A sequence of expressions that make up the body of the intrinsic
    +- `big_endian_inverse` (_Optional_)
    +    - A boolean, default false. If true, generates two implementations of each intrinsic variant, one for each endianness, and attempts to automatically generate the required bit swizzles
    +- `visibility` (_Optional_)
    +    - Function visibility. One of `public` (default) or `private`.
    +- `n_variant_op` (_Optional_)
    +    - Enables generation of an `_n` variant when the intrinsic name includes the `{_n}` wildcard. Set to the operand name that should be splattered for the `_n` form.
    +- `test` (_Optional_)
    +	- When set, load/store tests are automatically generated.
    +    - A mapping of either `load` or `store` to a number that indexes `types` to specify the type that the test should be addressing in memory. 
    +### Expressions
    +#### Common
    +- `Let`
    +    - Defines a variable
    +    - Usage: `Let: [, , ]`
    +- `Const`
    +    - Defines a const
    +    - Usage: `Const: [, , ]`
    +- `Assign`
    +    - Performs variable assignment
    +    - Usage: `Assign: [, ]`
    +- `FnCall`
    +    - Performs a function call
    +    - Usage: `FnCall: [, [, ... ], [, ...](optional), ]`
    +- `MacroCall`
    +    - Performs a macro call
    +    - Usage: `MacroCall: [, ]`
    +- `MethodCall`
    +    - Performs a method call
    +    - Usage: `MethodCall: [, , [, ... ]]`
    +- `LLVMLink`
    +    - Creates an LLVM link and stores the function's name in the wildcard `{llvm_link}` for later use in subsequent expressions.
    +    - If left unset, the arguments and return type inherit from the intrinsic's signature by default. The links will also be set automatically if unset.
    +    - Usage:
    +```yaml
    +LLVMLink:
    +    name: 
    +    arguments: [, ... ](optional)
    +    return_type: (optional)
    +    links: (optional)
    +        - link: 
    +          arch: 
    +        - ...
    +```
    +- `Identifier`
    +    - Emits a symbol. Prepend with a `$` to treat it as a scope variable, which engages variable tracking and enables inference. For example, `my_function_name` for a generic symbol or `$my_variable` for a variable.
    +    - Usage `Identifier: [, ]`
    +- `CastAs`
    +    - Casts an expression to an unchecked type
    +    - Usage: `CastAs: [, ]`
    +- `MatchSize`
    +    - Allows for conditional generation depending on the size of a specified type
    +    - Usage:
    +```yaml
    +MatchSize:
    +    - 
    +    - default: 
    +      byte(optional): 
    +      halfword(optional): 
    +      doubleword(optional): 
    +```
    +- `MatchKind`
    +    - Allows for conditional generation depending on the kind of a specified type
    +```yaml
    +MatchKind:
    +    - 
    +    - default: 
    +      float(optional): 
    +      unsigned(optional): 
    +```
    +#### Rarely Used
    +- `IntConstant`
    +    - Constant signed integer expression
    +    - Usage: `IntConstant: `
    +- `FloatConstant`
    +    - Constant floating-point expression
    +    - Usage: `FloatConstant: `
    +- `BoolConstant`
    +    - Constant boolean expression
    +    - Usage: `BoolConstant: `
    +- `Array`
    +    - An array of expressions
    +    - Usage: `Array: [, ...]`
    +- `SvUndef`
    +    - Returns the LLVM `undef` symbol
    +    - Usage: `SvUndef`
    +- `Multiply`
    +    - Simply `*`
    +    - Usage: `Multiply: [, ]`
    +- `Xor`
    +    - Simply `^`
    +    - Usage: `Xor: [, ]`
    +- `ConvertConst`
    +    - Converts the specified constant to the specified type's kind
    +    - Usage: `ConvertConst: [, ]`
    +- `Type`
    +    - Yields the given type in the Rust representation
    +    - Usage: `Type: []`
    +
    +### Wildstrings
    +- Wildstrings let you take advantage of wildcards.
    +- For example, they are often used in intrinsic names `name: "vtst{neon_type[0].no}"`
    +- As shown above, wildcards are identified by the surrounding curly brackets.
    +- Double curly brackets can be used to escape wildcard functionality if you need literal curly brackets in the generated intrinsic.
    +### Wildcards
    +Wildcards are heavily used in the spec. They let you write generalised definitions for a group of intrinsics that generate multiple variants. The wildcard itself is replaced with the relevant string in each variant.
    +Ignoring endianness, for each row in the `types` field of an intrinsic in the spec, a variant of the intrinsic will be generated. That row's contents can be indexed by the wildcards. Below is the behaviour of each wildcard.
    +- `type[]`
    +    - Replaced in each variant with the value in the indexed position in the relevant row of the `types` field.
    +    - For unnested sequences of `types` (i.e., `types` is a sequence where each element is a single item, not another sequence), the square brackets can be omitted. Simply: `type`
    +- `neon_type[]`
    +    - Extends the behaviour of `type` with some NEON-specific features and inference.
    +    - Tuples: This wildcard can also be written as `neon_type_x` where `n` is in the set `{2,3,4}`. This generates the `n`-tuple variant of the (inferred) NEON type.
    +    - Suffixes: These modify the behaviour of the wildcard from simple substitution.
    +	    - `no` -  normal behaviour. Tries to do as much work as it can for you, inferring when to emit:
    +            - Regular type-size suffixes: `_s8`, `_u16`, `_f32`, ...
    +            - `q` variants for double-width (128b) vector types: `q_s8`, `q_u16`, `q_f32`, ...
    +            - `_x` variants for tuple vector types: `_s8_x2`, `_u32_x3`, `_f64_x4`, ...
    +            - As well as any combination of the above: `q_s16_x16` ...
    +    - Most of the other suffixes modify the normal behaviour by disabling features or adding new ones. (See table below)
    +- `sve_type[]`
    +    - Similar to `neon_type`, but without the suffixes.
    +- `size[]`
    +    - The size (in bits) of the indexed type.
    +- `size_minus_one[]`
    +    - Emits the size (in bits) of the indexed type minus one.
    +- `size_literal[]`
    +    - The literal representation of the indexed type.
    +    - `b`: byte, `h`: halfword, `w`: word, or `d`: double.
    +- `type_kind[]`
    +    - The literal representation of the indexed type's kind.
    +    - `f`: float, `s`: signed, `u`: unsigned, `p`: polynomial, `b`: boolean.
    +- `size_in_bytes_log2[]`
    +    - Log2 of the size of the indexed type in *bytes*.
    +- `predicate[]`
    +    - SVE predicate vector type inferred from the indexed type.
    +- `max_predicate`
    +    - The same as predicate, but uses the largest type in the relevant `types` sequence/row.
    +- `_n`
    +    - Emits the current N-variant suffix when `n_variant_op` is configured.
    +- ` as `
    +    - If `` evaluates to a vector, it produces a vector of the same shape, but with `` as the base type.
    +- `llvm_link`
    +    - If the `LLVMLink` mapping has been set for an intrinsic, this will give the name of the link.
    +- `_m*`
    +    - Predicate form masks. Use wildcards such as `{_mx}` or `{_mxz}` to expand merging/don't-care/zeroing variants according to the mask.
    +- ``
    +    - You may simply call upon wildcards defined under `substitutions`.
    +### neon_type suffixes
    +
    +| suffix            | implication                                   |
    +| ----------------- | --------------------------------------------- |
    +| `.no`             | Normal                                        |
    +| `.noq`            | Never include `q`s                            |
    +| `.nox`            | Never include `_x`s                        |
    +| `.N`              | Include `_n_`, e.g., `_n_s8`                  |
    +| `.noq_N`          | Include `_n_`, but never `q`s                 |
    +| `.dup`            | Include `_dup_`, e.g., `_dup_s8`              |
    +| `.dup_nox`        | Include `_dup_` but never `_x`s            |
    +| `.lane`           | Include `_lane_`, e.g., `_lane_s8`            |
    +| `.lane_nox`       | Include `_lane_`, but never `_x`s          |
    +| `.rot90`          | Include `_rot90_`, e.g., `_rot90_s8`          |
    +| `.rot180`         | Include `_rot180_`, e.g., `_rot180_s8`        |
    +| `.rot270`         | Include `_rot270_`, e.g., `_rot270_s8`        |
    +| `.rot90_lane`     | Include `_rot90_lane_`                        |
    +| `.rot180_lane`    | Include `_rot180_lane_`                       |
    +| `.rot270_lane`    | Include `_rot270_lane_`                       |
    +| `.rot90_laneq`    | Include `_rot90_laneq_`                       |
    +| `.rot180_laneq`   | Include `_rot180_laneq_`                      |
    +| `.rot270_laneq`   | Include `_rot270_laneq_`                      |
    +| `.base`           | Produce only the size, e.g., `8`, `16`        |
    +| `.u`              | Produce the type's unsigned equivalent        |
    +| `.laneq_nox`      | Include `_laneq_`, but never `_x`s         |
    +| `.tuple`          | Produce only the size of the tuple, e.g., `3` |
    +| `.base_byte_size` | Produce only the size in bytes.               |
    + 
    
    From 1d968067881c968c3e79558472988ab117eaf8b2 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= 
    Date: Sat, 10 Jan 2026 10:54:31 +0100
    Subject: [PATCH 2063/3801] type params on eii
    
    ---
     tests/ui/eii/type_checking/type_params_149983.rs | 7 +++++++
     1 file changed, 7 insertions(+)
     create mode 100644 tests/ui/eii/type_checking/type_params_149983.rs
    
    diff --git a/tests/ui/eii/type_checking/type_params_149983.rs b/tests/ui/eii/type_checking/type_params_149983.rs
    new file mode 100644
    index 000000000000..a0314657bb1d
    --- /dev/null
    +++ b/tests/ui/eii/type_checking/type_params_149983.rs
    @@ -0,0 +1,7 @@
    +//@ check-fail
    +// Check that type parameters on EIIs are properly rejected.
    +// Specifically a regression test for https://github.com/rust-lang/rust/issues/149983.
    +#![feature(extern_item_impls)]
    +
    +#[eii]
    +fn foo() {}
    
    From d25f4718adf1f2358c63299af16c1c4c0519bb03 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= 
    Date: Sat, 10 Jan 2026 16:00:46 +0100
    Subject: [PATCH 2064/3801] deduplicate error message when EII has generics
    
    ---
     compiler/rustc_hir_analysis/messages.ftl      |  4 ----
     .../rustc_hir_analysis/src/check/check.rs     |  9 +++++++-
     .../src/check/compare_eii.rs                  | 23 +------------------
     compiler/rustc_hir_analysis/src/errors.rs     | 10 --------
     4 files changed, 9 insertions(+), 37 deletions(-)
    
    diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
    index 416a6b19edfc..9ead1225d5f5 100644
    --- a/compiler/rustc_hir_analysis/messages.ftl
    +++ b/compiler/rustc_hir_analysis/messages.ftl
    @@ -165,10 +165,6 @@ hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported
     hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice
         .label = parameter captured again here
     
    -hir_analysis_eii_with_generics =
    -    #[{$eii_name}] cannot have generic parameters other than lifetimes
    -    .label = required by this attribute
    -
     hir_analysis_empty_specialization = specialization impl does not specialize any associated items
         .note = impl is a specialization of this impl
     
    diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
    index 4664bfcce853..c37611ab2ee7 100644
    --- a/compiler/rustc_hir_analysis/src/check/check.rs
    +++ b/compiler/rustc_hir_analysis/src/check/check.rs
    @@ -974,12 +974,19 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
                             (0, _) => ("const", "consts", None),
                             _ => ("type or const", "types or consts", None),
                         };
    +                    let name =
    +                        if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::EiiForeignItem) {
    +                            "externally implementable items"
    +                        } else {
    +                            "foreign items"
    +                        };
    +
                         let span = tcx.def_span(def_id);
                         struct_span_code_err!(
                             tcx.dcx(),
                             span,
                             E0044,
    -                        "foreign items may not have {kinds} parameters",
    +                        "{name} may not have {kinds} parameters",
                         )
                         .with_span_label(span, format!("can't have {kinds} parameters"))
                         .with_help(
    diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs
    index d8afee9aafc9..c2a9b1fbdee0 100644
    --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs
    +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs
    @@ -24,7 +24,7 @@ use super::potentially_plural_count;
     use crate::check::compare_impl_item::{
         CheckNumberOfEarlyBoundRegionsError, check_number_of_early_bound_regions,
     };
    -use crate::errors::{EiiWithGenerics, LifetimesOrBoundsMismatchOnEii};
    +use crate::errors::LifetimesOrBoundsMismatchOnEii;
     
     /// Checks whether the signature of some `external_impl`, matches
     /// the signature of `declaration`, which it is supposed to be compatible
    @@ -154,32 +154,11 @@ fn check_is_structurally_compatible<'tcx>(
         eii_name: Symbol,
         eii_attr_span: Span,
     ) -> Result<(), ErrorGuaranteed> {
    -    check_no_generics(tcx, external_impl, declaration, eii_name, eii_attr_span)?;
         check_number_of_arguments(tcx, external_impl, declaration, eii_name, eii_attr_span)?;
         check_early_region_bounds(tcx, external_impl, declaration, eii_attr_span)?;
         Ok(())
     }
     
    -/// externally implementable items can't have generics
    -fn check_no_generics<'tcx>(
    -    tcx: TyCtxt<'tcx>,
    -    external_impl: LocalDefId,
    -    _declaration: DefId,
    -    eii_name: Symbol,
    -    eii_attr_span: Span,
    -) -> Result<(), ErrorGuaranteed> {
    -    let generics = tcx.generics_of(external_impl);
    -    if generics.own_requires_monomorphization() {
    -        tcx.dcx().emit_err(EiiWithGenerics {
    -            span: tcx.def_span(external_impl),
    -            attr: eii_attr_span,
    -            eii_name,
    -        });
    -    }
    -
    -    Ok(())
    -}
    -
     fn check_early_region_bounds<'tcx>(
         tcx: TyCtxt<'tcx>,
         external_impl: LocalDefId,
    diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
    index b388396ac4fc..7d4f65434dc4 100644
    --- a/compiler/rustc_hir_analysis/src/errors.rs
    +++ b/compiler/rustc_hir_analysis/src/errors.rs
    @@ -1652,13 +1652,3 @@ pub(crate) struct LifetimesOrBoundsMismatchOnEii {
         pub bounds_span: Vec,
         pub ident: Symbol,
     }
    -
    -#[derive(Diagnostic)]
    -#[diag(hir_analysis_eii_with_generics)]
    -pub(crate) struct EiiWithGenerics {
    -    #[primary_span]
    -    pub span: Span,
    -    #[label]
    -    pub attr: Span,
    -    pub eii_name: Symbol,
    -}
    
    From b64a9be97ebe4195e55768e98f6eb4dcdd9220a3 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= 
    Date: Sun, 11 Jan 2026 16:52:46 +0100
    Subject: [PATCH 2065/3801] bless the tests
    
    ---
     tests/ui/eii/type_checking/type_params_149983.rs     |  3 +++
     tests/ui/eii/type_checking/type_params_149983.stderr | 11 +++++++++++
     2 files changed, 14 insertions(+)
     create mode 100644 tests/ui/eii/type_checking/type_params_149983.stderr
    
    diff --git a/tests/ui/eii/type_checking/type_params_149983.rs b/tests/ui/eii/type_checking/type_params_149983.rs
    index a0314657bb1d..6dc9b309712e 100644
    --- a/tests/ui/eii/type_checking/type_params_149983.rs
    +++ b/tests/ui/eii/type_checking/type_params_149983.rs
    @@ -5,3 +5,6 @@
     
     #[eii]
     fn foo() {}
    +//~^ ERROR externally implementable items may not have type parameters
    +
    +fn main() {}
    diff --git a/tests/ui/eii/type_checking/type_params_149983.stderr b/tests/ui/eii/type_checking/type_params_149983.stderr
    new file mode 100644
    index 000000000000..11f06e6c88e2
    --- /dev/null
    +++ b/tests/ui/eii/type_checking/type_params_149983.stderr
    @@ -0,0 +1,11 @@
    +error[E0044]: externally implementable items may not have type parameters
    +  --> $DIR/type_params_149983.rs:7:1
    +   |
    +LL | fn foo() {}
    +   | ^^^^^^^^^^^ can't have type parameters
    +   |
    +   = help: replace the type parameters with concrete types like `u32`
    +
    +error: aborting due to 1 previous error
    +
    +For more information about this error, try `rustc --explain E0044`.
    
    From 467a2d2a1a8654524be29dbadd34c89d9616d8dd Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= 
    Date: Sun, 11 Jan 2026 16:09:18 +0100
    Subject: [PATCH 2066/3801] use self instead of super
    
    ---
     compiler/rustc_builtin_macros/src/eii.rs | 54 ++++--------------------
     1 file changed, 9 insertions(+), 45 deletions(-)
    
    diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs
    index cec7599d68e9..f72b78fe7f99 100644
    --- a/compiler/rustc_builtin_macros/src/eii.rs
    +++ b/compiler/rustc_builtin_macros/src/eii.rs
    @@ -105,10 +105,10 @@ fn eii_(
         let item_span = func.sig.span;
         let foreign_item_name = func.ident;
     
    -    let mut return_items = Vec::new();
    +    let mut module_items = Vec::new();
     
         if func.body.is_some() {
    -        return_items.push(generate_default_impl(
    +        module_items.push(generate_default_impl(
                 ecx,
                 &func,
                 impl_unsafe,
    @@ -119,7 +119,7 @@ fn eii_(
             ))
         }
     
    -    return_items.push(generate_foreign_item(
    +    module_items.push(generate_foreign_item(
             ecx,
             eii_attr_span,
             item_span,
    @@ -127,7 +127,7 @@ fn eii_(
             vis,
             &attrs_from_decl,
         ));
    -    return_items.push(generate_attribute_macro_to_implement(
    +    module_items.push(generate_attribute_macro_to_implement(
             ecx,
             eii_attr_span,
             macro_name,
    @@ -136,7 +136,7 @@ fn eii_(
             &attrs_from_decl,
         ));
     
    -    return_items.into_iter().map(wrap_item).collect()
    +    module_items.into_iter().map(wrap_item).collect()
     }
     
     /// Decide on the name of the macro that can be used to implement the EII.
    @@ -213,29 +213,13 @@ fn generate_default_impl(
             known_eii_macro_resolution: Some(ast::EiiDecl {
                 foreign_item: ecx.path(
                     foreign_item_name.span,
    -                // prefix super to escape the `dflt` module generated below
    -                vec![Ident::from_str_and_span("super", foreign_item_name.span), foreign_item_name],
    +                // prefix super to explicitly escape the const block generated below
    +                vec![Ident::from_str_and_span("self", foreign_item_name.span), foreign_item_name],
                 ),
                 impl_unsafe,
             }),
         });
     
    -    let item_mod = |span: Span, name: Ident, items: ThinVec>| {
    -        ecx.item(
    -            item_span,
    -            ThinVec::new(),
    -            ItemKind::Mod(
    -                ast::Safety::Default,
    -                name,
    -                ast::ModKind::Loaded(
    -                    items,
    -                    ast::Inline::Yes,
    -                    ast::ModSpans { inner_span: span, inject_use_span: span },
    -                ),
    -            ),
    -        )
    -    };
    -
         let anon_mod = |span: Span, stmts: ThinVec| {
             let unit = ecx.ty(item_span, ast::TyKind::Tup(ThinVec::new()));
             let underscore = Ident::new(kw::Underscore, item_span);
    @@ -248,33 +232,13 @@ fn generate_default_impl(
         };
     
         // const _: () = {
    -    //     mod dflt {
    -    //         use super::*;
    -    //         
    -    //     }
    +    //     
         // }
         anon_mod(
             item_span,
             thin_vec![ecx.stmt_item(
                 item_span,
    -            item_mod(
    -                item_span,
    -                Ident::from_str_and_span("dflt", item_span),
    -                thin_vec![
    -                    ecx.item(
    -                        item_span,
    -                        thin_vec![ecx.attr_nested_word(sym::allow, sym::unused_imports, item_span)],
    -                        ItemKind::Use(ast::UseTree {
    -                            prefix: ast::Path::from_ident(Ident::from_str_and_span(
    -                                "super", item_span,
    -                            )),
    -                            kind: ast::UseTreeKind::Glob,
    -                            span: item_span,
    -                        })
    -                    ),
    -                    ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func)))
    -                ]
    -            )
    +            ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func)))
             ),],
         )
     }
    
    From b454f76bd1ddf5c7459238f295647561a7895cbc Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= 
    Date: Sun, 11 Jan 2026 17:45:50 +0100
    Subject: [PATCH 2067/3801] ensure generics are still properly reported on EII
     *implementations*, and test this
    
    ---
     compiler/rustc_hir_analysis/messages.ftl      |  5 +++
     .../src/check/compare_eii.rs                  | 38 ++++++++++++++++++-
     compiler/rustc_hir_analysis/src/errors.rs     | 12 ++++++
     .../type_checking/generic_implementation.rs   | 13 +++++++
     .../generic_implementation.stderr             | 12 ++++++
     5 files changed, 78 insertions(+), 2 deletions(-)
     create mode 100644 tests/ui/eii/type_checking/generic_implementation.rs
     create mode 100644 tests/ui/eii/type_checking/generic_implementation.stderr
    
    diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
    index 9ead1225d5f5..fa3c4cb05f96 100644
    --- a/compiler/rustc_hir_analysis/messages.ftl
    +++ b/compiler/rustc_hir_analysis/messages.ftl
    @@ -165,6 +165,11 @@ hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported
     hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice
         .label = parameter captured again here
     
    +hir_analysis_eii_with_generics =
    +    `{$impl_name}` cannot have generic parameters other than lifetimes
    +    .label = required by this attribute
    +    .help = `#[{$eii_name}]` marks the implementation of an "externally implementable item"
    +
     hir_analysis_empty_specialization = specialization impl does not specialize any associated items
         .note = impl is a specialization of this impl
     
    diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs
    index c2a9b1fbdee0..2beb7eb09c11 100644
    --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs
    +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs
    @@ -8,8 +8,9 @@ use std::iter;
     
     use rustc_data_structures::fx::FxIndexSet;
     use rustc_errors::{Applicability, E0806, struct_span_code_err};
    +use rustc_hir::attrs::{AttributeKind, EiiImplResolution};
     use rustc_hir::def_id::{DefId, LocalDefId};
    -use rustc_hir::{self as hir, FnSig, HirId, ItemKind};
    +use rustc_hir::{self as hir, FnSig, HirId, ItemKind, find_attr};
     use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
     use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
     use rustc_middle::ty::error::{ExpectedFound, TypeError};
    @@ -24,7 +25,7 @@ use super::potentially_plural_count;
     use crate::check::compare_impl_item::{
         CheckNumberOfEarlyBoundRegionsError, check_number_of_early_bound_regions,
     };
    -use crate::errors::LifetimesOrBoundsMismatchOnEii;
    +use crate::errors::{EiiWithGenerics, LifetimesOrBoundsMismatchOnEii};
     
     /// Checks whether the signature of some `external_impl`, matches
     /// the signature of `declaration`, which it is supposed to be compatible
    @@ -154,11 +155,44 @@ fn check_is_structurally_compatible<'tcx>(
         eii_name: Symbol,
         eii_attr_span: Span,
     ) -> Result<(), ErrorGuaranteed> {
    +    check_no_generics(tcx, external_impl, declaration, eii_name, eii_attr_span)?;
         check_number_of_arguments(tcx, external_impl, declaration, eii_name, eii_attr_span)?;
         check_early_region_bounds(tcx, external_impl, declaration, eii_attr_span)?;
         Ok(())
     }
     
    +/// externally implementable items can't have generics
    +fn check_no_generics<'tcx>(
    +    tcx: TyCtxt<'tcx>,
    +    external_impl: LocalDefId,
    +    _declaration: DefId,
    +    eii_name: Symbol,
    +    eii_attr_span: Span,
    +) -> Result<(), ErrorGuaranteed> {
    +    let generics = tcx.generics_of(external_impl);
    +    if generics.own_requires_monomorphization()
    +        // When an EII implementation is automatically generated by the `#[eii]` macro,
    +        // it will directly refer to the foreign item, not through a macro.
    +        // We don't want to emit this error if it's an implementation that's generated by the `#[eii]` macro,
    +        // since in that case it looks like a duplicate error: the declaration of the EII already can't contain generics.
    +        // So, we check here if at least one of the eii impls has ImplResolution::Macro, which indicates it's
    +        // not generated as part of the declaration.
    +        && find_attr!(
    +            tcx.get_all_attrs(external_impl),
    +            AttributeKind::EiiImpls(impls) if impls.iter().any(|i| matches!(i.resolution, EiiImplResolution::Macro(_)))
    +        )
    +    {
    +        tcx.dcx().emit_err(EiiWithGenerics {
    +            span: tcx.def_span(external_impl),
    +            attr: eii_attr_span,
    +            eii_name,
    +            impl_name: tcx.item_name(external_impl),
    +        });
    +    }
    +
    +    Ok(())
    +}
    +
     fn check_early_region_bounds<'tcx>(
         tcx: TyCtxt<'tcx>,
         external_impl: LocalDefId,
    diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
    index 7d4f65434dc4..185a822bdfa6 100644
    --- a/compiler/rustc_hir_analysis/src/errors.rs
    +++ b/compiler/rustc_hir_analysis/src/errors.rs
    @@ -1652,3 +1652,15 @@ pub(crate) struct LifetimesOrBoundsMismatchOnEii {
         pub bounds_span: Vec,
         pub ident: Symbol,
     }
    +
    +#[derive(Diagnostic)]
    +#[diag(hir_analysis_eii_with_generics)]
    +#[help]
    +pub(crate) struct EiiWithGenerics {
    +    #[primary_span]
    +    pub span: Span,
    +    #[label]
    +    pub attr: Span,
    +    pub eii_name: Symbol,
    +    pub impl_name: Symbol,
    +}
    diff --git a/tests/ui/eii/type_checking/generic_implementation.rs b/tests/ui/eii/type_checking/generic_implementation.rs
    new file mode 100644
    index 000000000000..489fd2e645d8
    --- /dev/null
    +++ b/tests/ui/eii/type_checking/generic_implementation.rs
    @@ -0,0 +1,13 @@
    +//@ check-fail
    +// Check that type parameters on EIIs are properly rejected.
    +// Specifically a regression test for https://github.com/rust-lang/rust/issues/149983.
    +#![feature(extern_item_impls)]
    +
    +#[eii]
    +fn foo();
    +
    +#[foo]
    +fn foo_impl() {}
    +//~^ ERROR `foo_impl` cannot have generic parameters other than lifetimes
    +
    +fn main() {}
    diff --git a/tests/ui/eii/type_checking/generic_implementation.stderr b/tests/ui/eii/type_checking/generic_implementation.stderr
    new file mode 100644
    index 000000000000..17a71998423d
    --- /dev/null
    +++ b/tests/ui/eii/type_checking/generic_implementation.stderr
    @@ -0,0 +1,12 @@
    +error: `foo_impl` cannot have generic parameters other than lifetimes
    +  --> $DIR/generic_implementation.rs:10:1
    +   |
    +LL | #[foo]
    +   | ------ required by this attribute
    +LL | fn foo_impl() {}
    +   | ^^^^^^^^^^^^^^^^
    +   |
    +   = help: `#[foo]` marks the implementation of an "externally implementable item"
    +
    +error: aborting due to 1 previous error
    +
    
    From df55233c6d290bf23f499d846a51897982b7bee9 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= 
    Date: Sun, 11 Jan 2026 16:18:49 +0100
    Subject: [PATCH 2068/3801] disallow in statement position
    
    ---
     compiler/rustc_builtin_macros/messages.ftl  |  2 +
     compiler/rustc_builtin_macros/src/eii.rs    | 41 ++++++++++++---------
     compiler/rustc_builtin_macros/src/errors.rs | 10 +++++
     3 files changed, 35 insertions(+), 18 deletions(-)
    
    diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
    index 1501bd6c73e2..f9ffddf79084 100644
    --- a/compiler/rustc_builtin_macros/messages.ftl
    +++ b/compiler/rustc_builtin_macros/messages.ftl
    @@ -161,6 +161,8 @@ builtin_macros_eii_only_once = `#[{$name}]` can only be specified once
     
     builtin_macros_eii_shared_macro_expected_function = `#[{$name}]` is only valid on functions
     builtin_macros_eii_shared_macro_expected_max_one_argument = `#[{$name}]` expected no arguments or a single argument: `#[{$name}(default)]`
    +builtin_macros_eii_shared_macro_in_statement_position = `#[{$name}]` can only be used on functions inside a module
    +    .label = `#[{$name}]` is used on this item, which is part of another item's local scope
     
     builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time
         .cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead
    diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs
    index f72b78fe7f99..43e9dfe0092e 100644
    --- a/compiler/rustc_builtin_macros/src/eii.rs
    +++ b/compiler/rustc_builtin_macros/src/eii.rs
    @@ -1,8 +1,7 @@
     use rustc_ast::token::{Delimiter, TokenKind};
     use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
     use rustc_ast::{
    -    Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Path, Stmt, StmtKind,
    -    Visibility, ast,
    +    Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Path, StmtKind, Visibility, ast,
     };
     use rustc_ast_pretty::pprust::path_to_string;
     use rustc_expand::base::{Annotatable, ExtCtxt};
    @@ -12,6 +11,7 @@ use thin_vec::{ThinVec, thin_vec};
     use crate::errors::{
         EiiExternTargetExpectedList, EiiExternTargetExpectedMacro, EiiExternTargetExpectedUnsafe,
         EiiMacroExpectedMaxOneArgument, EiiOnlyOnce, EiiSharedMacroExpectedFunction,
    +    EiiSharedMacroInStatementPosition,
     };
     
     /// ```rust
    @@ -55,29 +55,29 @@ fn eii_(
         ecx: &mut ExtCtxt<'_>,
         eii_attr_span: Span,
         meta_item: &ast::MetaItem,
    -    item: Annotatable,
    +    orig_item: Annotatable,
         impl_unsafe: bool,
     ) -> Vec {
         let eii_attr_span = ecx.with_def_site_ctxt(eii_attr_span);
     
    -    let (item, wrap_item): (_, &dyn Fn(_) -> _) = if let Annotatable::Item(item) = item {
    -        (item, &Annotatable::Item)
    -    } else if let Annotatable::Stmt(ref stmt) = item
    +    let item = if let Annotatable::Item(item) = orig_item {
    +        item
    +    } else if let Annotatable::Stmt(ref stmt) = orig_item
             && let StmtKind::Item(ref item) = stmt.kind
    +        && let ItemKind::Fn(ref f) = item.kind
         {
    -        (item.clone(), &|item| {
    -            Annotatable::Stmt(Box::new(Stmt {
    -                id: DUMMY_NODE_ID,
    -                kind: StmtKind::Item(item),
    -                span: eii_attr_span,
    -            }))
    -        })
    +        ecx.dcx().emit_err(EiiSharedMacroInStatementPosition {
    +            span: eii_attr_span.to(item.span),
    +            name: path_to_string(&meta_item.path),
    +            item_span: f.ident.span,
    +        });
    +        return vec![orig_item];
         } else {
             ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
                 span: eii_attr_span,
                 name: path_to_string(&meta_item.path),
             });
    -        return vec![item];
    +        return vec![orig_item];
         };
     
         let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } =
    @@ -87,7 +87,7 @@ fn eii_(
                 span: eii_attr_span,
                 name: path_to_string(&meta_item.path),
             });
    -        return vec![wrap_item(item)];
    +        return vec![Annotatable::Item(item)];
         };
         // only clone what we need
         let attrs = attrs.clone();
    @@ -98,7 +98,9 @@ fn eii_(
             filter_attrs_for_multiple_eii_attr(ecx, attrs, eii_attr_span, &meta_item.path);
     
         let Ok(macro_name) = name_for_impl_macro(ecx, &func, &meta_item) else {
    -        return vec![wrap_item(item)];
    +        // we don't need to wrap in Annotatable::Stmt conditionally since
    +        // EII can't be used on items in statement position
    +        return vec![Annotatable::Item(item)];
         };
     
         // span of the declaring item without attributes
    @@ -136,7 +138,9 @@ fn eii_(
             &attrs_from_decl,
         ));
     
    -    module_items.into_iter().map(wrap_item).collect()
    +    // we don't need to wrap in Annotatable::Stmt conditionally since
    +    // EII can't be used on items in statement position
    +    module_items.into_iter().map(Annotatable::Item).collect()
     }
     
     /// Decide on the name of the macro that can be used to implement the EII.
    @@ -213,7 +217,8 @@ fn generate_default_impl(
             known_eii_macro_resolution: Some(ast::EiiDecl {
                 foreign_item: ecx.path(
                     foreign_item_name.span,
    -                // prefix super to explicitly escape the const block generated below
    +                // prefix self to explicitly escape the const block generated below
    +                // NOTE: this is why EIIs can't be used on statements
                     vec![Ident::from_str_and_span("self", foreign_item_name.span), foreign_item_name],
                 ),
                 impl_unsafe,
    diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
    index 5d4c4e340fa1..a9ce41c9be76 100644
    --- a/compiler/rustc_builtin_macros/src/errors.rs
    +++ b/compiler/rustc_builtin_macros/src/errors.rs
    @@ -1039,6 +1039,16 @@ pub(crate) struct EiiSharedMacroExpectedFunction {
         pub name: String,
     }
     
    +#[derive(Diagnostic)]
    +#[diag(builtin_macros_eii_shared_macro_in_statement_position)]
    +pub(crate) struct EiiSharedMacroInStatementPosition {
    +    #[primary_span]
    +    pub span: Span,
    +    pub name: String,
    +    #[label]
    +    pub item_span: Span,
    +}
    +
     #[derive(Diagnostic)]
     #[diag(builtin_macros_eii_only_once)]
     pub(crate) struct EiiOnlyOnce {
    
    From 8dd701cec77fec63902e78c575dd34e2f715dfa3 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= 
    Date: Sun, 11 Jan 2026 16:25:10 +0100
    Subject: [PATCH 2069/3801] add test for rejecting EIIs in statement position
    
    ---
     tests/ui/eii/error_statement_position.rs     | 15 ++++++++-------
     tests/ui/eii/error_statement_position.stderr | 13 +++++++++++--
     2 files changed, 19 insertions(+), 9 deletions(-)
    
    diff --git a/tests/ui/eii/error_statement_position.rs b/tests/ui/eii/error_statement_position.rs
    index cf81e7e6a8b2..75d87595b9e3 100644
    --- a/tests/ui/eii/error_statement_position.rs
    +++ b/tests/ui/eii/error_statement_position.rs
    @@ -1,11 +1,6 @@
     #![feature(extern_item_impls)]
    -// EIIs can, despite not being super useful, be declared in statement position
    -// nested inside items. Items in statement position, when expanded as part of a macro,
    -// need to be wrapped slightly differently (in an `ast::Statement`).
    -// We did this on the happy path (no errors), but when there was an error, we'd
    -// replace it with *just* an `ast::Item` not wrapped in an `ast::Statement`.
    -// This caused an ICE (https://github.com/rust-lang/rust/issues/149980).
    -// this test fails to build, but demonstrates that no ICE is produced.
    +// EIIs cannot be used in statement position.
    +// This is also a regression test for an ICE (https://github.com/rust-lang/rust/issues/149980).
     
     fn main() {
         struct Bar;
    @@ -13,4 +8,10 @@ fn main() {
         #[eii]
         //~^ ERROR `#[eii]` is only valid on functions
         impl Bar {}
    +
    +
    +    // Even on functions, eiis in statement position are rejected
    +    #[eii]
    +    //~^ ERROR `#[eii]` can only be used on functions inside a module
    +    fn foo() {}
     }
    diff --git a/tests/ui/eii/error_statement_position.stderr b/tests/ui/eii/error_statement_position.stderr
    index 01b7394ef00f..f14e6c33e64f 100644
    --- a/tests/ui/eii/error_statement_position.stderr
    +++ b/tests/ui/eii/error_statement_position.stderr
    @@ -1,8 +1,17 @@
     error: `#[eii]` is only valid on functions
    -  --> $DIR/error_statement_position.rs:13:5
    +  --> $DIR/error_statement_position.rs:8:5
        |
     LL |     #[eii]
        |     ^^^^^^
     
    -error: aborting due to 1 previous error
    +error: `#[eii]` can only be used on functions inside a module
    +  --> $DIR/error_statement_position.rs:14:5
    +   |
    +LL |     #[eii]
    +   |     ^^^^^^
    +LL |
    +LL |     fn foo() {}
    +   |        --- `#[eii]` is used on this item, which is part of another item's local scope
    +
    +error: aborting due to 2 previous errors
     
    
    From 5bf9ca7b00c5074d984e836dcd9bef68fc9284cb Mon Sep 17 00:00:00 2001
    From: Folkert de Vries 
    Date: Tue, 13 Jan 2026 12:11:18 +0100
    Subject: [PATCH 2070/3801] stabilize `__jscvt`
    
    ---
     .../stdarch/crates/core_arch/src/aarch64/neon/generated.rs  | 2 +-
     .../crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml       | 6 +++---
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
    index 7743e52f4fe1..90dba4409ed4 100644
    --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
    +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
    @@ -49,7 +49,7 @@ pub fn __crc32d(crc: u32, data: u64) -> u32 {
     #[inline]
     #[target_feature(enable = "jsconv")]
     #[cfg_attr(test, assert_instr(fjcvtzs))]
    -#[unstable(feature = "stdarch_aarch64_jscvt", issue = "147555")]
    +#[stable(feature = "stdarch_aarch64_jscvt", since = "CURRENT_RUSTC_VERSION")]
     pub fn __jcvt(a: f64) -> i32 {
         unsafe extern "unadjusted" {
             #[cfg_attr(
    diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml
    index 8f36c525fae9..a951343e0183 100644
    --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml
    +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml
    @@ -63,8 +63,8 @@ neon-unstable-f16: &neon-unstable-f16
     neon-unstable-feat-lut: &neon-unstable-feat-lut
       FnCall: [unstable, ['feature = "stdarch_neon_feat_lut"', 'issue = "138050"']]
     
    -aarch64-unstable-jscvt: &aarch64-unstable-jscvt
    -  FnCall: [unstable, ['feature = "stdarch_aarch64_jscvt"', 'issue = "147555"']]
    +aarch64-stable-jscvt: &aarch64-stable-jscvt
    +  FnCall: [stable, ['feature = "stdarch_aarch64_jscvt"', 'since = "CURRENT_RUSTC_VERSION"']]
     
     # #[cfg(target_endian = "little")]
     little-endian: &little-endian
    @@ -14275,7 +14275,7 @@ intrinsics:
         attr:
           - FnCall: [target_feature, ['enable = "jsconv"']]
           - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["fjcvtzs"]] }]]
    -      - *aarch64-unstable-jscvt
    +      - *aarch64-stable-jscvt
         safety: safe
         types:
           - f64
    
    From d616e6cb189c762789a8179cb00e065fcc7f9992 Mon Sep 17 00:00:00 2001
    From: reddevilmidzy 
    Date: Tue, 13 Jan 2026 21:36:53 +0900
    Subject: [PATCH 2071/3801] Emit error instead of delayed bug when meeting
     mismatch type for const array
    
    ---
     .../src/hir_ty_lowering/mod.rs                |  9 ++++----
     ...array-expr-type-mismatch-in-where-bound.rs | 21 +++++++++++++++++++
     ...y-expr-type-mismatch-in-where-bound.stderr | 15 +++++++++++++
     3 files changed, 40 insertions(+), 5 deletions(-)
     create mode 100644 tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs
     create mode 100644 tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr
    
    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 d2cbf89336d8..a66a521975c5 100644
    --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
    +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
    @@ -2415,11 +2415,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             };
     
             let ty::Array(elem_ty, _) = ty.kind() else {
    -            return Const::new_error_with_message(
    -                tcx,
    -                array_expr.span,
    -                "const array must have an array type",
    -            );
    +            let e = tcx
    +                .dcx()
    +                .span_err(array_expr.span, format!("expected `{}`, found const array", ty));
    +            return Const::new_error(tcx, e);
             };
     
             let elems = array_expr
    diff --git a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs
    new file mode 100644
    index 000000000000..cda519b96d4d
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs
    @@ -0,0 +1,21 @@
    +//! regression test for 
    +#![feature(min_generic_const_args)]
    +#![feature(adt_const_params)]
    +#![expect(incomplete_features)]
    +
    +trait Trait1 {}
    +trait Trait2 {}
    +
    +fn foo()
    +where
    +    T: Trait1<{ [] }>, //~ ERROR: expected `usize`, found const array
    +{
    +}
    +
    +fn bar()
    +where
    +    T: Trait2<3>, //~ ERROR: mismatched types
    +{
    +}
    +
    +fn main() {}
    diff --git a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr
    new file mode 100644
    index 000000000000..be40e4474226
    --- /dev/null
    +++ b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr
    @@ -0,0 +1,15 @@
    +error: expected `usize`, found const array
    +  --> $DIR/array-expr-type-mismatch-in-where-bound.rs:11:17
    +   |
    +LL |     T: Trait1<{ [] }>,
    +   |                 ^^
    +
    +error[E0308]: mismatched types
    +  --> $DIR/array-expr-type-mismatch-in-where-bound.rs:17:15
    +   |
    +LL |     T: Trait2<3>,
    +   |               ^ expected `[u8; 3]`, found integer
    +
    +error: aborting due to 2 previous errors
    +
    +For more information about this error, try `rustc --explain E0308`.
    
    From 2c32c0e8047eb5535f96c3b7e468cfe023568b31 Mon Sep 17 00:00:00 2001
    From: Chayim Refael Friedman 
    Date: Tue, 13 Jan 2026 14:56:51 +0200
    Subject: [PATCH 2072/3801] Make `naked_asm!()` always return `!`
    
    As it should.
    ---
     .../rust-analyzer/crates/hir-ty/src/infer/expr.rs  |  8 ++++++--
     .../crates/hir-ty/src/tests/simple.rs              | 14 ++++++++++++++
     .../crates/test-utils/src/minicore.rs              |  4 ++++
     3 files changed, 24 insertions(+), 2 deletions(-)
    
    diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
    index 62339779a562..c57d41cc5f73 100644
    --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
    +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
    @@ -8,7 +8,7 @@ use hir_def::{
         expr_store::path::{GenericArgs as HirGenericArgs, Path},
         hir::{
             Array, AsmOperand, AsmOptions, BinaryOp, BindingAnnotation, Expr, ExprId, ExprOrPatId,
    -        LabelId, Literal, Pat, PatId, Statement, UnaryOp,
    +        InlineAsmKind, LabelId, Literal, Pat, PatId, Statement, UnaryOp,
         },
         resolver::ValueNs,
     };
    @@ -1037,7 +1037,11 @@ impl<'db> InferenceContext<'_, 'db> {
                         // FIXME: `sym` should report for things that are not functions or statics.
                         AsmOperand::Sym(_) => (),
                     });
    -                if diverge { self.types.types.never } else { self.types.types.unit }
    +                if diverge || asm.kind == InlineAsmKind::NakedAsm {
    +                    self.types.types.never
    +                } else {
    +                    self.types.types.unit
    +                }
                 }
             };
             // use a new type variable if we got unknown here
    diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
    index 6367521841ab..d02e455fc3dc 100644
    --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
    +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
    @@ -3983,3 +3983,17 @@ fn foo() {
             "#]],
         );
     }
    +
    +#[test]
    +fn naked_asm_returns_never() {
    +    check_no_mismatches(
    +        r#"
    +//- minicore: asm
    +
    +#[unsafe(naked)]
    +extern "C" fn foo() -> ! {
    +    core::arch::naked_asm!("");
    +}
    +    "#,
    +    );
    +}
    diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
    index 01274a9835f4..580a619cf108 100644
    --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
    +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
    @@ -1880,6 +1880,10 @@ mod arch {
         pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
             /* compiler built-in */
         }
    +    #[rustc_builtin_macro]
    +    pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) {
    +        /* compiler built-in */
    +    }
     }
     // endregion:asm
     
    
    From a2154802699c6de58702bcf4e3211ccb977cd3be Mon Sep 17 00:00:00 2001
    From: A4-Tacks 
    Date: Tue, 13 Jan 2026 19:00:03 +0800
    Subject: [PATCH 2073/3801] Migrate `unwrap_block` assist to use SyntaxEditor
    
    - Fix invalid match in let-stmt
    - Fix multiple statements loses indent
    
    Example
    ---
    ```rust
    fn main() {
        let value = match rel_path {
            Ok(rel_path) => {$0
                let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
                Some((*id, rel_path))
            }
            Err(_) => None,
        };
    }
    ```
    
    **Before this PR**
    
    ```rust
    fn main() {
        let value = let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
        let value = Some((*id, rel_path));
    }
    ```
    
    **After this PR**
    
    ```rust
    fn main() {
        let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
        let value = Some((*id, rel_path));
    }
    ```
    
    ---
    
    ```rust
    fn main() {
        let mut a = {$0
            1;
            2;
            3
        };
    }
    ```
    
    **Before this PR**
    
    ```rust
    fn main() {
        1;
    2;
        let mut a = 3;
    }
    ```
    
    **After this PR**
    
    ```rust
    fn main() -> i32 {
        1;
        2;
        let mut a = 3;
    }
    ```
    ---
     .../ide-assists/src/handlers/unwrap_block.rs  | 257 +++++++++---------
     1 file changed, 136 insertions(+), 121 deletions(-)
    
    diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs
    index a83f6835ca61..e4f5e3523bd2 100644
    --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs
    +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_block.rs
    @@ -1,10 +1,12 @@
     use syntax::{
    -    AstNode, SyntaxKind, T, TextRange,
    +    AstNode, SyntaxElement, SyntaxKind, SyntaxNode, T,
         ast::{
             self,
             edit::{AstNodeEdit, IndentLevel},
             make,
         },
    +    match_ast,
    +    syntax_editor::{Element, Position, SyntaxEditor},
     };
     
     use crate::{AssistContext, AssistId, Assists};
    @@ -27,123 +29,108 @@ use crate::{AssistContext, AssistId, Assists};
     // }
     // ```
     pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
    -    let assist_id = AssistId::refactor_rewrite("unwrap_block");
    -    let assist_label = "Unwrap block";
         let l_curly_token = ctx.find_token_syntax_at_offset(T!['{'])?;
    -    let mut block = ast::BlockExpr::cast(l_curly_token.parent_ancestors().nth(1)?)?;
    +    let block = l_curly_token.parent_ancestors().nth(1).and_then(ast::BlockExpr::cast)?;
         let target = block.syntax().text_range();
    -    let mut parent = block.syntax().parent()?;
    -    if ast::MatchArm::can_cast(parent.kind()) {
    -        parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))?
    -    }
    +    let mut container = block.syntax().clone();
    +    let mut replacement = block.clone();
    +    let mut prefer_container = None;
     
    -    let kind = parent.kind();
    -    if matches!(kind, SyntaxKind::STMT_LIST | SyntaxKind::EXPR_STMT) {
    -        acc.add(assist_id, assist_label, target, |builder| {
    -            builder.replace(block.syntax().text_range(), update_expr_string(block.to_string()));
    -        })
    -    } else if matches!(kind, SyntaxKind::LET_STMT) {
    -        let parent = ast::LetStmt::cast(parent)?;
    -        let pattern = ast::Pat::cast(parent.syntax().first_child()?)?;
    -        let ty = parent.ty();
    -        let list = block.stmt_list()?;
    -        let replaced = match list.syntax().last_child() {
    -            Some(last) => {
    -                let stmts: Vec = list.statements().collect();
    -                let initializer = ast::Expr::cast(last)?;
    -                let let_stmt = make::let_stmt(pattern, ty, Some(initializer));
    -                if !stmts.is_empty() {
    -                    let block = make::block_expr(stmts, None);
    -                    format!("{}\n    {}", update_expr_string(block.to_string()), let_stmt)
    -                } else {
    -                    let_stmt.to_string()
    -                }
    -            }
    -            None => {
    -                let empty_tuple = make::ext::expr_unit();
    -                make::let_stmt(pattern, ty, Some(empty_tuple)).to_string()
    -            }
    -        };
    -        acc.add(assist_id, assist_label, target, |builder| {
    -            builder.replace(parent.syntax().text_range(), replaced);
    -        })
    -    } else {
    -        let parent = ast::Expr::cast(parent)?;
    -        match parent.clone() {
    -            ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
    -            ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
    -            ast::Expr::IfExpr(if_expr) => {
    -                let then_branch = if_expr.then_branch()?;
    -                if then_branch == block {
    -                    if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
    -                        // For `else if` blocks
    -                        let ancestor_then_branch = ancestor.then_branch()?;
    -
    -                        return acc.add(assist_id, assist_label, target, |edit| {
    -                            let range_to_del_else_if = TextRange::new(
    -                                ancestor_then_branch.syntax().text_range().end(),
    -                                l_curly_token.text_range().start(),
    -                            );
    -                            let range_to_del_rest = TextRange::new(
    -                                then_branch.syntax().text_range().end(),
    -                                if_expr.syntax().text_range().end(),
    -                            );
    -
    -                            edit.delete(range_to_del_rest);
    -                            edit.delete(range_to_del_else_if);
    -                            edit.replace(
    -                                target,
    -                                update_expr_string_without_newline(then_branch.to_string()),
    -                            );
    -                        });
    -                    }
    -                } else {
    -                    return acc.add(assist_id, assist_label, target, |edit| {
    -                        let range_to_del = TextRange::new(
    -                            then_branch.syntax().text_range().end(),
    -                            l_curly_token.text_range().start(),
    -                        );
    -
    -                        edit.delete(range_to_del);
    -                        edit.replace(target, update_expr_string_without_newline(block.to_string()));
    +    let from_indent = block.indent_level();
    +    let into_indent = loop {
    +        let parent = container.parent()?;
    +        container = match_ast! {
    +            match parent {
    +                ast::ForExpr(it) => it.syntax().clone(),
    +                ast::LoopExpr(it) => it.syntax().clone(),
    +                ast::WhileExpr(it) => it.syntax().clone(),
    +                ast::MatchArm(it) => it.parent_match().syntax().clone(),
    +                ast::LetStmt(it) => {
    +                    replacement = wrap_let(&it, replacement);
    +                    prefer_container = Some(it.syntax().clone());
    +                    it.syntax().clone()
    +                },
    +                ast::IfExpr(it) => {
    +                    prefer_container.get_or_insert_with(|| {
    +                        if let Some(else_branch) = it.else_branch()
    +                            && *else_branch.syntax() == container
    +                        {
    +                            else_branch.syntax().clone()
    +                        } else {
    +                            it.syntax().clone()
    +                        }
                         });
    -                }
    +                    it.syntax().clone()
    +                },
    +                ast::ExprStmt(it) => it.syntax().clone(),
    +                ast::StmtList(it) => break it.indent_level(),
    +                _ => return None,
                 }
    -            _ => return None,
             };
    +    };
    +    let replacement = replacement.stmt_list()?;
     
    -        acc.add(assist_id, assist_label, target, |builder| {
    -            builder.replace(parent.syntax().text_range(), update_expr_string(block.to_string()));
    -        })
    -    }
    +    acc.add(AssistId::refactor_rewrite("unwrap_block"), "Unwrap block", target, |builder| {
    +        let mut edit = builder.make_editor(block.syntax());
    +        let replacement = replacement.dedent(from_indent).indent(into_indent);
    +        let container = prefer_container.unwrap_or(container);
    +
    +        edit.replace_with_many(&container, extract_statements(replacement));
    +        delete_else_before(container, &mut edit);
    +
    +        builder.add_file_edits(ctx.vfs_file_id(), edit);
    +    })
     }
     
    -fn update_expr_string(expr_string: String) -> String {
    -    update_expr_string_with_pat(expr_string, &[' ', '\n'])
    +fn delete_else_before(container: SyntaxNode, edit: &mut SyntaxEditor) {
    +    let Some(else_token) = container
    +        .siblings_with_tokens(syntax::Direction::Prev)
    +        .skip(1)
    +        .map_while(|it| it.into_token())
    +        .find(|it| it.kind() == T![else])
    +    else {
    +        return;
    +    };
    +    itertools::chain(else_token.prev_token(), else_token.next_token())
    +        .filter(|it| it.kind() == SyntaxKind::WHITESPACE)
    +        .for_each(|it| edit.delete(it));
    +    let indent = IndentLevel::from_node(&container);
    +    let newline = make::tokens::whitespace(&format!("\n{indent}"));
    +    edit.replace(else_token, newline);
     }
     
    -fn update_expr_string_without_newline(expr_string: String) -> String {
    -    update_expr_string_with_pat(expr_string, &[' '])
    +fn wrap_let(assign: &ast::LetStmt, replacement: ast::BlockExpr) -> ast::BlockExpr {
    +    let try_wrap_assign = || {
    +        let initializer = assign.initializer()?.syntax().syntax_element();
    +        let replacement = replacement.clone_subtree();
    +        let assign = assign.clone_for_update();
    +        let tail_expr = replacement.tail_expr()?;
    +        let before =
    +            assign.syntax().children_with_tokens().take_while(|it| *it != initializer).collect();
    +        let after = assign
    +            .syntax()
    +            .children_with_tokens()
    +            .skip_while(|it| *it != initializer)
    +            .skip(1)
    +            .collect();
    +
    +        let mut edit = SyntaxEditor::new(replacement.syntax().clone());
    +        edit.insert_all(Position::before(tail_expr.syntax()), before);
    +        edit.insert_all(Position::after(tail_expr.syntax()), after);
    +        ast::BlockExpr::cast(edit.finish().new_root().clone())
    +    };
    +    try_wrap_assign().unwrap_or(replacement)
     }
     
    -fn update_expr_string_with_pat(expr_str: String, whitespace_pat: &[char]) -> String {
    -    // Remove leading whitespace, index to remove the leading '{',
    -    // then continue to remove leading whitespace.
    -    // We cannot assume the `{` is the first character because there are block modifiers
    -    // (`unsafe`, `async` etc.).
    -    let after_open_brace_index = expr_str.find('{').map_or(0, |it| it + 1);
    -    let expr_str = expr_str[after_open_brace_index..].trim_start_matches(whitespace_pat);
    -
    -    // Remove trailing whitespace, index [..expr_str.len() - 1] to remove the trailing '}',
    -    // then continue to remove trailing whitespace.
    -    let expr_str = expr_str.trim_end_matches(whitespace_pat);
    -    let expr_str = expr_str[..expr_str.len() - 1].trim_end_matches(whitespace_pat);
    -
    -    expr_str
    -        .lines()
    -        .map(|line| line.replacen("    ", "", 1)) // Delete indentation
    -        .collect::>()
    -        .join("\n")
    +fn extract_statements(stmt_list: ast::StmtList) -> Vec {
    +    let mut elements = stmt_list
    +        .syntax()
    +        .children_with_tokens()
    +        .filter(|it| !matches!(it.kind(), T!['{'] | T!['}']))
    +        .skip_while(|it| it.kind() == SyntaxKind::WHITESPACE)
    +        .collect::>();
    +    while elements.pop_if(|it| it.kind() == SyntaxKind::WHITESPACE).is_some() {}
    +    elements
     }
     
     #[cfg(test)]
    @@ -593,6 +580,30 @@ fn main() {
             );
         }
     
    +    #[test]
    +    fn unwrap_match_arm_in_let() {
    +        check_assist(
    +            unwrap_block,
    +            r#"
    +fn main() {
    +    let value = match rel_path {
    +        Ok(rel_path) => {$0
    +            let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
    +            Some((*id, rel_path))
    +        }
    +        Err(_) => None,
    +    };
    +}
    +"#,
    +            r#"
    +fn main() {
    +    let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
    +    let value = Some((*id, rel_path));
    +}
    +"#,
    +        );
    +    }
    +
         #[test]
         fn simple_if_in_while_bad_cursor_position() {
             check_assist_not_applicable(
    @@ -750,19 +761,6 @@ fn main() -> i32 {
             check_assist(
                 unwrap_block,
                 r#"
    -fn main() {
    -    let x = {$0};
    -}
    -"#,
    -            r#"
    -fn main() {
    -    let x = ();
    -}
    -"#,
    -        );
    -        check_assist(
    -            unwrap_block,
    -            r#"
     fn main() {
         let x = {$0
             bar
    @@ -784,8 +782,7 @@ fn main() -> i32 {
     "#,
                 r#"
     fn main() -> i32 {
    -    1;
    -    let _ = 2;
    +    1; let _ = 2;
     }
     "#,
             );
    @@ -795,11 +792,29 @@ fn main() -> i32 {
     fn main() -> i32 {
         let mut a = {$01; 2};
     }
    +"#,
    +            r#"
    +fn main() -> i32 {
    +    1; let mut a = 2;
    +}
    +"#,
    +        );
    +        check_assist(
    +            unwrap_block,
    +            r#"
    +fn main() -> i32 {
    +    let mut a = {$0
    +        1;
    +        2;
    +        3
    +    };
    +}
     "#,
                 r#"
     fn main() -> i32 {
         1;
    -    let mut a = 2;
    +    2;
    +    let mut a = 3;
     }
     "#,
             );
    
    From 84d59d073170aecbb15de9c1cdcf542bf7443673 Mon Sep 17 00:00:00 2001
    From: Jonathan Brouwer 
    Date: Mon, 12 Jan 2026 19:39:34 +0100
    Subject: [PATCH 2074/3801] Port `#[rustc_dump_user_args]`
    
    ---
     .../rustc_attr_parsing/src/attributes/mod.rs    |  1 +
     .../src/attributes/rustc_dump.rs                | 17 +++++++++++++++++
     compiler/rustc_attr_parsing/src/context.rs      |  2 ++
     compiler/rustc_hir/src/attrs/data_structures.rs |  3 +++
     .../rustc_hir/src/attrs/encode_cross_crate.rs   |  1 +
     compiler/rustc_hir_typeck/src/writeback.rs      |  9 +++++----
     compiler/rustc_passes/src/check_attr.rs         |  2 +-
     7 files changed, 30 insertions(+), 5 deletions(-)
     create mode 100644 compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    
    diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
    index e02d71a26158..26db2992d8af 100644
    --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
    +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
    @@ -57,6 +57,7 @@ pub(crate) mod pin_v2;
     pub(crate) mod proc_macro_attrs;
     pub(crate) mod prototype;
     pub(crate) mod repr;
    +pub(crate) mod rustc_dump;
     pub(crate) mod rustc_internal;
     pub(crate) mod semantics;
     pub(crate) mod stability;
    diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    new file mode 100644
    index 000000000000..d5593a7e02f3
    --- /dev/null
    +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    @@ -0,0 +1,17 @@
    +use rustc_hir::Target;
    +use rustc_hir::attrs::AttributeKind;
    +use rustc_span::{Span, Symbol, sym};
    +
    +use crate::attributes::prelude::Allow;
    +use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
    +use crate::context::Stage;
    +use crate::target_checking::AllowedTargets;
    +
    +pub(crate) struct RustcDumpUserArgs;
    +
    +impl NoArgsAttributeParser for RustcDumpUserArgs {
    +    const PATH: &[Symbol] = &[sym::rustc_dump_user_args];
    +    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
    +    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
    +    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs;
    +}
    diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
    index 6b1b1d484283..4ba1936086a2 100644
    --- a/compiler/rustc_attr_parsing/src/context.rs
    +++ b/compiler/rustc_attr_parsing/src/context.rs
    @@ -63,6 +63,7 @@ use crate::attributes::proc_macro_attrs::{
     };
     use crate::attributes::prototype::CustomMirParser;
     use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
    +use crate::attributes::rustc_dump::RustcDumpUserArgs;
     use crate::attributes::rustc_internal::{
         RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser,
         RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser,
    @@ -267,6 +268,7 @@ attribute_parsers!(
             Single>,
             Single>,
             Single>,
    +        Single>,
             Single>,
             Single>,
             Single>,
    diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
    index 8d18d335b355..42575f712d4a 100644
    --- a/compiler/rustc_hir/src/attrs/data_structures.rs
    +++ b/compiler/rustc_hir/src/attrs/data_structures.rs
    @@ -906,6 +906,9 @@ pub enum AttributeKind {
         /// Represents `#[rustc_coherence_is_core]`
         RustcCoherenceIsCore(Span),
     
    +    /// Represents `#[rustc_dump_user_args]`
    +    RustcDumpUserArgs,
    +
         /// Represents `#[rustc_has_incoherent_inherent_impls]`
         RustcHasIncoherentInherentImpls,
     
    diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    index 33655f4f0063..07dd9f8e3e06 100644
    --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    @@ -97,6 +97,7 @@ impl AttributeKind {
                 Repr { .. } => No,
                 RustcBuiltinMacro { .. } => Yes,
                 RustcCoherenceIsCore(..) => No,
    +            RustcDumpUserArgs => No,
                 RustcHasIncoherentInherentImpls => Yes,
                 RustcLayoutScalarValidRangeEnd(..) => Yes,
                 RustcLayoutScalarValidRangeStart(..) => Yes,
    diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
    index 960a8497a266..0078cd9d0683 100644
    --- a/compiler/rustc_hir_typeck/src/writeback.rs
    +++ b/compiler/rustc_hir_typeck/src/writeback.rs
    @@ -14,9 +14,10 @@ use std::ops::ControlFlow;
     use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
     use rustc_data_structures::unord::ExtendUnord;
     use rustc_errors::{E0720, ErrorGuaranteed};
    +use rustc_hir::attrs::AttributeKind;
     use rustc_hir::def_id::LocalDefId;
     use rustc_hir::intravisit::{self, InferKind, Visitor};
    -use rustc_hir::{self as hir, AmbigArg, HirId};
    +use rustc_hir::{self as hir, AmbigArg, HirId, find_attr};
     use rustc_infer::traits::solve::Goal;
     use rustc_middle::traits::ObligationCause;
     use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
    @@ -25,7 +26,7 @@ use rustc_middle::ty::{
         TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
         fold_regions,
     };
    -use rustc_span::{Span, sym};
    +use rustc_span::Span;
     use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
     use rustc_trait_selection::opaque_types::opaque_type_has_defining_use_args;
     use rustc_trait_selection::solve;
    @@ -45,8 +46,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     
             // This attribute causes us to dump some writeback information
             // in the form of errors, which is used for unit tests.
    -        let rustc_dump_user_args =
    -            self.has_rustc_attrs && self.tcx.has_attr(item_def_id, sym::rustc_dump_user_args);
    +        let rustc_dump_user_args = self.has_rustc_attrs
    +            && find_attr!(self.tcx.get_all_attrs(item_def_id), AttributeKind::RustcDumpUserArgs);
     
             let mut wbcx = WritebackCx::new(self, body, rustc_dump_user_args);
             for param in body.params {
    diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
    index 8f80822a81ab..f088bd5b5119 100644
    --- a/compiler/rustc_passes/src/check_attr.rs
    +++ b/compiler/rustc_passes/src/check_attr.rs
    @@ -309,6 +309,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         | AttributeKind::CfiEncoding { .. }
                         | AttributeKind::RustcHasIncoherentInherentImpls
                         | AttributeKind::MustNotSupend { .. }
    +                    | AttributeKind::RustcDumpUserArgs
                     ) => { /* do nothing  */ }
                     Attribute::Unparsed(attr_item) => {
                         style = Some(attr_item.style);
    @@ -379,7 +380,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                 | sym::rustc_variance_of_opaques
                                 | sym::rustc_hidden_type_of_opaques
                                 | sym::rustc_mir
    -                            | sym::rustc_dump_user_args
                                 | sym::rustc_effective_visibility
                                 | sym::rustc_outlives
                                 | sym::rustc_symbol_name
    
    From cf4d480eff238667a779c56938ebc51956f586d4 Mon Sep 17 00:00:00 2001
    From: Jonathan Brouwer 
    Date: Mon, 12 Jan 2026 19:43:31 +0100
    Subject: [PATCH 2075/3801] Port `#[rustc_dump_def_parents]`
    
    ---
     compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs | 9 +++++++++
     compiler/rustc_attr_parsing/src/context.rs               | 3 ++-
     compiler/rustc_hir/src/attrs/data_structures.rs          | 3 +++
     compiler/rustc_hir/src/attrs/encode_cross_crate.rs       | 1 +
     compiler/rustc_hir_analysis/src/collect/dump.rs          | 5 +++--
     compiler/rustc_passes/src/check_attr.rs                  | 2 +-
     6 files changed, 19 insertions(+), 4 deletions(-)
    
    diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    index d5593a7e02f3..86cc88fe26e6 100644
    --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    @@ -15,3 +15,12 @@ impl NoArgsAttributeParser for RustcDumpUserArgs {
         const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
         const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs;
     }
    +
    +pub(crate) struct RustcDumpDefParents;
    +
    +impl NoArgsAttributeParser for RustcDumpDefParents {
    +    const PATH: &[Symbol] = &[sym::rustc_dump_def_parents];
    +    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
    +    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
    +    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents;
    +}
    diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
    index 4ba1936086a2..adcdbf7752a3 100644
    --- a/compiler/rustc_attr_parsing/src/context.rs
    +++ b/compiler/rustc_attr_parsing/src/context.rs
    @@ -63,7 +63,7 @@ use crate::attributes::proc_macro_attrs::{
     };
     use crate::attributes::prototype::CustomMirParser;
     use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
    -use crate::attributes::rustc_dump::RustcDumpUserArgs;
    +use crate::attributes::rustc_dump::{RustcDumpUserArgs, RustcDumpDefParents};
     use crate::attributes::rustc_internal::{
         RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser,
         RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser,
    @@ -268,6 +268,7 @@ attribute_parsers!(
             Single>,
             Single>,
             Single>,
    +        Single>,
             Single>,
             Single>,
             Single>,
    diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
    index 42575f712d4a..63a89c84ed4a 100644
    --- a/compiler/rustc_hir/src/attrs/data_structures.rs
    +++ b/compiler/rustc_hir/src/attrs/data_structures.rs
    @@ -906,6 +906,9 @@ pub enum AttributeKind {
         /// Represents `#[rustc_coherence_is_core]`
         RustcCoherenceIsCore(Span),
     
    +    /// Represents `#[rustc_dump_def_parents]`
    +    RustcDumpDefParents,
    +    
         /// Represents `#[rustc_dump_user_args]`
         RustcDumpUserArgs,
     
    diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    index 07dd9f8e3e06..aa2a7cb6d4b4 100644
    --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    @@ -97,6 +97,7 @@ impl AttributeKind {
                 Repr { .. } => No,
                 RustcBuiltinMacro { .. } => Yes,
                 RustcCoherenceIsCore(..) => No,
    +            RustcDumpDefParents => No,
                 RustcDumpUserArgs => No,
                 RustcHasIncoherentInherentImpls => Yes,
                 RustcLayoutScalarValidRangeEnd(..) => Yes,
    diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
    index b167f31a246c..1ace60721eae 100644
    --- a/compiler/rustc_hir_analysis/src/collect/dump.rs
    +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
    @@ -1,6 +1,7 @@
     use rustc_hir as hir;
     use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
    -use rustc_hir::intravisit;
    +use rustc_hir::{find_attr, intravisit};
    +use rustc_hir::attrs::AttributeKind;
     use rustc_middle::hir::nested_filter;
     use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
     use rustc_span::sym;
    @@ -54,7 +55,7 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) {
     pub(crate) fn def_parents(tcx: TyCtxt<'_>) {
         for iid in tcx.hir_free_items() {
             let did = iid.owner_id.def_id;
    -        if tcx.has_attr(did, sym::rustc_dump_def_parents) {
    +        if find_attr!(tcx.get_all_attrs(did), AttributeKind::RustcDumpDefParents) {
                 struct AnonConstFinder<'tcx> {
                     tcx: TyCtxt<'tcx>,
                     anon_consts: Vec,
    diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
    index f088bd5b5119..dfa407964fc4 100644
    --- a/compiler/rustc_passes/src/check_attr.rs
    +++ b/compiler/rustc_passes/src/check_attr.rs
    @@ -310,6 +310,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         | AttributeKind::RustcHasIncoherentInherentImpls
                         | AttributeKind::MustNotSupend { .. }
                         | AttributeKind::RustcDumpUserArgs
    +                    | AttributeKind::RustcDumpDefParents
                     ) => { /* do nothing  */ }
                     Attribute::Unparsed(attr_item) => {
                         style = Some(attr_item.style);
    @@ -369,7 +370,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                 | sym::rustc_abi
                                 | sym::rustc_layout
                                 | sym::rustc_proc_macro_decls
    -                            | sym::rustc_dump_def_parents
                                 | sym::rustc_never_type_options
                                 | sym::rustc_autodiff
                                 | sym::rustc_capture_analysis
    
    From 2a455409e302df2d1db755edec775f5100641365 Mon Sep 17 00:00:00 2001
    From: Jonathan Brouwer 
    Date: Mon, 12 Jan 2026 19:47:18 +0100
    Subject: [PATCH 2076/3801] Port `#[rustc_dump_item_bounds]`
    
    ---
     compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs | 9 +++++++++
     compiler/rustc_attr_parsing/src/context.rs               | 5 +++--
     compiler/rustc_hir/src/attrs/data_structures.rs          | 5 ++++-
     compiler/rustc_hir/src/attrs/encode_cross_crate.rs       | 1 +
     compiler/rustc_hir_analysis/src/collect/dump.rs          | 4 ++--
     compiler/rustc_passes/src/check_attr.rs                  | 2 +-
     6 files changed, 20 insertions(+), 6 deletions(-)
    
    diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    index 86cc88fe26e6..cc866f9297d2 100644
    --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    @@ -24,3 +24,12 @@ impl NoArgsAttributeParser for RustcDumpDefParents {
         const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
         const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents;
     }
    +
    +pub(crate) struct RustcDumpItemBounds;
    +
    +impl NoArgsAttributeParser for RustcDumpItemBounds {
    +    const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds];
    +    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
    +    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]);
    +    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds;
    +}
    diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
    index adcdbf7752a3..5b959e553482 100644
    --- a/compiler/rustc_attr_parsing/src/context.rs
    +++ b/compiler/rustc_attr_parsing/src/context.rs
    @@ -63,7 +63,7 @@ use crate::attributes::proc_macro_attrs::{
     };
     use crate::attributes::prototype::CustomMirParser;
     use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
    -use crate::attributes::rustc_dump::{RustcDumpUserArgs, RustcDumpDefParents};
    +use crate::attributes::rustc_dump::{RustcDumpDefParents, RustcDumpItemBounds, RustcDumpUserArgs};
     use crate::attributes::rustc_internal::{
         RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser,
         RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser,
    @@ -268,7 +268,8 @@ attribute_parsers!(
             Single>,
             Single>,
             Single>,
    -        Single>,
    +        Single>,
    +        Single>,
             Single>,
             Single>,
             Single>,
    diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
    index 63a89c84ed4a..051bd76e6eb7 100644
    --- a/compiler/rustc_hir/src/attrs/data_structures.rs
    +++ b/compiler/rustc_hir/src/attrs/data_structures.rs
    @@ -908,7 +908,10 @@ pub enum AttributeKind {
     
         /// Represents `#[rustc_dump_def_parents]`
         RustcDumpDefParents,
    -    
    +
    +    /// Represents `#[rustc_dump_item_bounds]`
    +    RustcDumpItemBounds,
    +
         /// Represents `#[rustc_dump_user_args]`
         RustcDumpUserArgs,
     
    diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    index aa2a7cb6d4b4..f3da08bae5db 100644
    --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    @@ -98,6 +98,7 @@ impl AttributeKind {
                 RustcBuiltinMacro { .. } => Yes,
                 RustcCoherenceIsCore(..) => No,
                 RustcDumpDefParents => No,
    +            RustcDumpItemBounds => No,
                 RustcDumpUserArgs => No,
                 RustcHasIncoherentInherentImpls => Yes,
                 RustcLayoutScalarValidRangeEnd(..) => Yes,
    diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
    index 1ace60721eae..f87fb3a66095 100644
    --- a/compiler/rustc_hir_analysis/src/collect/dump.rs
    +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
    @@ -1,7 +1,7 @@
     use rustc_hir as hir;
    +use rustc_hir::attrs::AttributeKind;
     use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
     use rustc_hir::{find_attr, intravisit};
    -use rustc_hir::attrs::AttributeKind;
     use rustc_middle::hir::nested_filter;
     use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
     use rustc_span::sym;
    @@ -39,7 +39,7 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) {
                 }
                 diag.emit();
             }
    -        if tcx.has_attr(id, sym::rustc_dump_item_bounds) {
    +        if find_attr!(tcx.get_all_attrs(id), AttributeKind::RustcDumpItemBounds) {
                 let bounds = tcx.item_bounds(id).instantiate_identity();
                 let span = tcx.def_span(id);
     
    diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
    index dfa407964fc4..4f9f584a3a61 100644
    --- a/compiler/rustc_passes/src/check_attr.rs
    +++ b/compiler/rustc_passes/src/check_attr.rs
    @@ -310,6 +310,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         | AttributeKind::RustcHasIncoherentInherentImpls
                         | AttributeKind::MustNotSupend { .. }
                         | AttributeKind::RustcDumpUserArgs
    +                    | AttributeKind::RustcDumpItemBounds
                         | AttributeKind::RustcDumpDefParents
                     ) => { /* do nothing  */ }
                     Attribute::Unparsed(attr_item) => {
    @@ -386,7 +387,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                 | sym::rustc_evaluate_where_clauses
                                 | sym::rustc_dump_vtable
                                 | sym::rustc_delayed_bug_from_inside_query
    -                            | sym::rustc_dump_item_bounds
                                 | sym::rustc_def_path
                                 | sym::rustc_partition_reused
                                 | sym::rustc_partition_codegened
    
    From a4c34b421cf20e187f07c5254adedcee612aaad4 Mon Sep 17 00:00:00 2001
    From: Jonathan Brouwer 
    Date: Mon, 12 Jan 2026 19:51:50 +0100
    Subject: [PATCH 2077/3801] Port `#[rustc_dump_vtable]`
    
    ---
     .../src/attributes/rustc_dump.rs              | 12 ++++++++++++
     compiler/rustc_attr_parsing/src/context.rs    |  5 ++++-
     .../rustc_hir/src/attrs/data_structures.rs    |  3 +++
     .../rustc_hir/src/attrs/encode_cross_crate.rs |  1 +
     .../rustc_hir_analysis/src/collect/dump.rs    | 19 ++++++++++---------
     compiler/rustc_passes/src/check_attr.rs       |  2 +-
     6 files changed, 31 insertions(+), 11 deletions(-)
    
    diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    index cc866f9297d2..25e60d899422 100644
    --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    @@ -33,3 +33,15 @@ impl NoArgsAttributeParser for RustcDumpItemBounds {
         const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]);
         const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds;
     }
    +
    +pub(crate) struct RustcDumpVtable;
    +
    +impl NoArgsAttributeParser for RustcDumpVtable {
    +    const PATH: &[Symbol] = &[sym::rustc_dump_vtable];
    +    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
    +    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
    +        Allow(Target::Impl { of_trait: true }),
    +        Allow(Target::TyAlias),
    +    ]);
    +    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDumpVtable;
    +}
    diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
    index 5b959e553482..8cc09117e710 100644
    --- a/compiler/rustc_attr_parsing/src/context.rs
    +++ b/compiler/rustc_attr_parsing/src/context.rs
    @@ -63,7 +63,9 @@ use crate::attributes::proc_macro_attrs::{
     };
     use crate::attributes::prototype::CustomMirParser;
     use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
    -use crate::attributes::rustc_dump::{RustcDumpDefParents, RustcDumpItemBounds, RustcDumpUserArgs};
    +use crate::attributes::rustc_dump::{
    +    RustcDumpDefParents, RustcDumpItemBounds, RustcDumpUserArgs, RustcDumpVtable,
    +};
     use crate::attributes::rustc_internal::{
         RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser,
         RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser,
    @@ -271,6 +273,7 @@ attribute_parsers!(
             Single>,
             Single>,
             Single>,
    +        Single>,
             Single>,
             Single>,
             Single>,
    diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
    index 051bd76e6eb7..941c12c7d6fa 100644
    --- a/compiler/rustc_hir/src/attrs/data_structures.rs
    +++ b/compiler/rustc_hir/src/attrs/data_structures.rs
    @@ -915,6 +915,9 @@ pub enum AttributeKind {
         /// Represents `#[rustc_dump_user_args]`
         RustcDumpUserArgs,
     
    +    /// Represents `#[rustc_dump_vtable]`
    +    RustcDumpVtable(Span),
    +
         /// Represents `#[rustc_has_incoherent_inherent_impls]`
         RustcHasIncoherentInherentImpls,
     
    diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    index f3da08bae5db..df386a00dd11 100644
    --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    @@ -100,6 +100,7 @@ impl AttributeKind {
                 RustcDumpDefParents => No,
                 RustcDumpItemBounds => No,
                 RustcDumpUserArgs => No,
    +            RustcDumpVtable(..) => No,
                 RustcHasIncoherentInherentImpls => Yes,
                 RustcLayoutScalarValidRangeEnd(..) => Yes,
                 RustcLayoutScalarValidRangeStart(..) => Yes,
    diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
    index f87fb3a66095..a61ea29a1a71 100644
    --- a/compiler/rustc_hir_analysis/src/collect/dump.rs
    +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
    @@ -103,7 +103,9 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
         for id in tcx.hir_free_items() {
             let def_id = id.owner_id.def_id;
     
    -        let Some(attr) = tcx.get_attr(def_id, sym::rustc_dump_vtable) else {
    +        let Some(&attr_span) =
    +            find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcDumpVtable(span) => span)
    +        else {
                 continue;
             };
     
    @@ -112,14 +114,14 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
                     let trait_ref = tcx.impl_trait_ref(def_id).instantiate_identity();
                     if trait_ref.has_non_region_param() {
                         tcx.dcx().span_err(
    -                        attr.span(),
    +                        attr_span,
                             "`rustc_dump_vtable` must be applied to non-generic impl",
                         );
                         continue;
                     }
                     if !tcx.is_dyn_compatible(trait_ref.def_id) {
                         tcx.dcx().span_err(
    -                        attr.span(),
    +                        attr_span,
                             "`rustc_dump_vtable` must be applied to dyn-compatible trait",
                         );
                         continue;
    @@ -128,7 +130,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
                         .try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref)
                     else {
                         tcx.dcx().span_err(
    -                        attr.span(),
    +                        attr_span,
                             "`rustc_dump_vtable` applied to impl header that cannot be normalized",
                         );
                         continue;
    @@ -139,7 +141,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
                     let ty = tcx.type_of(def_id).instantiate_identity();
                     if ty.has_non_region_param() {
                         tcx.dcx().span_err(
    -                        attr.span(),
    +                        attr_span,
                             "`rustc_dump_vtable` must be applied to non-generic type",
                         );
                         continue;
    @@ -148,14 +150,13 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
                         tcx.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
                     else {
                         tcx.dcx().span_err(
    -                        attr.span(),
    +                        attr_span,
                             "`rustc_dump_vtable` applied to type alias that cannot be normalized",
                         );
                         continue;
                     };
                     let ty::Dynamic(data, _) = *ty.kind() else {
    -                    tcx.dcx()
    -                        .span_err(attr.span(), "`rustc_dump_vtable` to type alias of dyn type");
    +                    tcx.dcx().span_err(attr_span, "`rustc_dump_vtable` to type alias of dyn type");
                         continue;
                     };
                     if let Some(principal) = data.principal() {
    @@ -168,7 +169,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
                 }
                 _ => {
                     tcx.dcx().span_err(
    -                    attr.span(),
    +                    attr_span,
                         "`rustc_dump_vtable` only applies to impl, or type alias of dyn type",
                     );
                     continue;
    diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
    index 4f9f584a3a61..3d51429f20d7 100644
    --- a/compiler/rustc_passes/src/check_attr.rs
    +++ b/compiler/rustc_passes/src/check_attr.rs
    @@ -312,6 +312,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         | AttributeKind::RustcDumpUserArgs
                         | AttributeKind::RustcDumpItemBounds
                         | AttributeKind::RustcDumpDefParents
    +                    | AttributeKind::RustcDumpVtable(..)
                     ) => { /* do nothing  */ }
                     Attribute::Unparsed(attr_item) => {
                         style = Some(attr_item.style);
    @@ -385,7 +386,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                 | sym::rustc_outlives
                                 | sym::rustc_symbol_name
                                 | sym::rustc_evaluate_where_clauses
    -                            | sym::rustc_dump_vtable
                                 | sym::rustc_delayed_bug_from_inside_query
                                 | sym::rustc_def_path
                                 | sym::rustc_partition_reused
    
    From abcbf72bab56c56ab395b8c7cd44a87364ac43df Mon Sep 17 00:00:00 2001
    From: Jonathan Brouwer 
    Date: Mon, 12 Jan 2026 19:54:54 +0100
    Subject: [PATCH 2078/3801] Port `#[rustc_dump_predicates]`
    
    ---
     .../src/attributes/rustc_dump.rs                  | 15 +++++++++++++++
     compiler/rustc_attr_parsing/src/context.rs        |  4 +++-
     compiler/rustc_hir/src/attrs/data_structures.rs   |  3 +++
     .../rustc_hir/src/attrs/encode_cross_crate.rs     |  1 +
     compiler/rustc_hir_analysis/src/collect/dump.rs   |  2 +-
     compiler/rustc_passes/src/check_attr.rs           |  2 +-
     6 files changed, 24 insertions(+), 3 deletions(-)
    
    diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    index 25e60d899422..53120dece916 100644
    --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
    @@ -34,6 +34,21 @@ impl NoArgsAttributeParser for RustcDumpItemBounds {
         const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds;
     }
     
    +pub(crate) struct RustcDumpPredicates;
    +
    +impl NoArgsAttributeParser for RustcDumpPredicates {
    +    const PATH: &[Symbol] = &[sym::rustc_dump_predicates];
    +    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
    +    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
    +        Allow(Target::Struct),
    +        Allow(Target::Enum),
    +        Allow(Target::Union),
    +        Allow(Target::Trait),
    +        Allow(Target::AssocTy),
    +    ]);
    +    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpPredicates;
    +}
    +
     pub(crate) struct RustcDumpVtable;
     
     impl NoArgsAttributeParser for RustcDumpVtable {
    diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
    index 8cc09117e710..8305d027d13c 100644
    --- a/compiler/rustc_attr_parsing/src/context.rs
    +++ b/compiler/rustc_attr_parsing/src/context.rs
    @@ -64,7 +64,8 @@ use crate::attributes::proc_macro_attrs::{
     use crate::attributes::prototype::CustomMirParser;
     use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
     use crate::attributes::rustc_dump::{
    -    RustcDumpDefParents, RustcDumpItemBounds, RustcDumpUserArgs, RustcDumpVtable,
    +    RustcDumpDefParents, RustcDumpItemBounds, RustcDumpPredicates, RustcDumpUserArgs,
    +    RustcDumpVtable,
     };
     use crate::attributes::rustc_internal::{
         RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser,
    @@ -272,6 +273,7 @@ attribute_parsers!(
             Single>,
             Single>,
             Single>,
    +        Single>,
             Single>,
             Single>,
             Single>,
    diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
    index 941c12c7d6fa..3d9362d2d923 100644
    --- a/compiler/rustc_hir/src/attrs/data_structures.rs
    +++ b/compiler/rustc_hir/src/attrs/data_structures.rs
    @@ -912,6 +912,9 @@ pub enum AttributeKind {
         /// Represents `#[rustc_dump_item_bounds]`
         RustcDumpItemBounds,
     
    +    /// Represents `#[rustc_dump_predicates]`
    +    RustcDumpPredicates,
    +
         /// Represents `#[rustc_dump_user_args]`
         RustcDumpUserArgs,
     
    diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    index df386a00dd11..48f3ceba9c39 100644
    --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    @@ -99,6 +99,7 @@ impl AttributeKind {
                 RustcCoherenceIsCore(..) => No,
                 RustcDumpDefParents => No,
                 RustcDumpItemBounds => No,
    +            RustcDumpPredicates => No,
                 RustcDumpUserArgs => No,
                 RustcDumpVtable(..) => No,
                 RustcHasIncoherentInherentImpls => Yes,
    diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
    index a61ea29a1a71..2dfd4ab6111f 100644
    --- a/compiler/rustc_hir_analysis/src/collect/dump.rs
    +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
    @@ -29,7 +29,7 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
     
     pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) {
         for id in tcx.hir_crate_items(()).owners() {
    -        if tcx.has_attr(id, sym::rustc_dump_predicates) {
    +        if find_attr!(tcx.get_all_attrs(id), AttributeKind::RustcDumpPredicates) {
                 let preds = tcx.predicates_of(id).instantiate_identity(tcx).predicates;
                 let span = tcx.def_span(id);
     
    diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
    index 3d51429f20d7..f047d66a8254 100644
    --- a/compiler/rustc_passes/src/check_attr.rs
    +++ b/compiler/rustc_passes/src/check_attr.rs
    @@ -311,6 +311,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         | AttributeKind::MustNotSupend { .. }
                         | AttributeKind::RustcDumpUserArgs
                         | AttributeKind::RustcDumpItemBounds
    +                    | AttributeKind::RustcDumpPredicates
                         | AttributeKind::RustcDumpDefParents
                         | AttributeKind::RustcDumpVtable(..)
                     ) => { /* do nothing  */ }
    @@ -377,7 +378,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                 | sym::rustc_capture_analysis
                                 | sym::rustc_regions
                                 | sym::rustc_strict_coherence
    -                            | sym::rustc_dump_predicates
                                 | sym::rustc_variance
                                 | sym::rustc_variance_of_opaques
                                 | sym::rustc_hidden_type_of_opaques
    
    From 8afa95d28f70a98d5b32b78f03a918ff5578e263 Mon Sep 17 00:00:00 2001
    From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
    Date: Tue, 13 Jan 2026 15:16:06 +0000
    Subject: [PATCH 2079/3801] Avoid should-fail in two ui tests
    
    should-fail is only meant for testing the compiletest framework itself.
    It checks that the test runner itself panicked.
    ---
     tests/ui/borrowck/two-phase-reservation-sharing-interference.rs | 2 +-
     tests/ui/type-inference/box_has_sigdrop.rs                      | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/tests/ui/borrowck/two-phase-reservation-sharing-interference.rs b/tests/ui/borrowck/two-phase-reservation-sharing-interference.rs
    index 61446577db29..342b8cce7b01 100644
    --- a/tests/ui/borrowck/two-phase-reservation-sharing-interference.rs
    +++ b/tests/ui/borrowck/two-phase-reservation-sharing-interference.rs
    @@ -3,7 +3,7 @@
     // The nll_beyond revision is disabled due to missing support from two-phase beyond autorefs
     //@ unused-revision-names: nll_beyond
     //@[nll_beyond]compile-flags: -Z two-phase-beyond-autoref
    -//@[nll_beyond]should-fail
    +//@[nll_beyond]check-fail
     
     // This is a corner case that the current implementation is (probably)
     // treating more conservatively than is necessary. But it also does
    diff --git a/tests/ui/type-inference/box_has_sigdrop.rs b/tests/ui/type-inference/box_has_sigdrop.rs
    index 3e801197a78e..2d1b1cd0249e 100644
    --- a/tests/ui/type-inference/box_has_sigdrop.rs
    +++ b/tests/ui/type-inference/box_has_sigdrop.rs
    @@ -1,4 +1,4 @@
    -//@ should-fail
    +//@ known-bug: unknown
     //@ compile-flags: -Wrust-2021-incompatible-closure-captures
     // Inference, canonicalization, and significant drops should work nicely together.
     // Related issue: #86868
    
    From 15112eee6764c08f83d8c444dce7440d68adf9da Mon Sep 17 00:00:00 2001
    From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
    Date: Tue, 13 Jan 2026 15:21:20 +0000
    Subject: [PATCH 2080/3801] Avoid should-fail in a codegen-llvm test
    
    ---
     .../codegen-llvm/option-niche-unfixed/option-nonzero-eq.rs | 7 +++----
     1 file changed, 3 insertions(+), 4 deletions(-)
    
    diff --git a/tests/codegen-llvm/option-niche-unfixed/option-nonzero-eq.rs b/tests/codegen-llvm/option-niche-unfixed/option-nonzero-eq.rs
    index 308856cfb7e9..1eb4542323c1 100644
    --- a/tests/codegen-llvm/option-niche-unfixed/option-nonzero-eq.rs
    +++ b/tests/codegen-llvm/option-niche-unfixed/option-nonzero-eq.rs
    @@ -1,6 +1,5 @@
    -//@ should-fail
    +//@ known-bug: #49892
     //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
    -//! FIXME(#49892)
     //! Test that the derived implementation of `PartialEq` for `Option` is not fully
     //! optimized by LLVM. If this starts passing, the test and manual impl should
     //! be removed.
    @@ -18,7 +17,7 @@ pub enum Option {
     #[no_mangle]
     pub fn non_zero_eq(l: Option>, r: Option>) -> bool {
         // CHECK: start:
    -    // CHECK-NEXT: icmp eq i32
    -    // CHECK-NEXT: ret i1
    +    // COMMENTEDCHECK-NEXT: icmp eq i32
    +    // COMMENTEDCHECK-NEXT: ret i1
         l == r
     }
    
    From 513b6ad231859f0b3c7953c454f9b209d58c25a9 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= 
    Date: Tue, 13 Jan 2026 17:41:55 +0100
    Subject: [PATCH 2081/3801] Remove references to homu and fix bors delegation
     command
    
    ---
     src/doc/rustc-dev-guide/src/about-this-guide.md |  4 ++--
     src/doc/rustc-dev-guide/src/compiler-team.md    |  4 ++--
     src/doc/rustc-dev-guide/src/contributing.md     |  2 +-
     src/doc/rustc-dev-guide/src/tests/ci.md         | 11 +++--------
     4 files changed, 8 insertions(+), 13 deletions(-)
    
    diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md
    index 2082481a200e..9d493e0cb065 100644
    --- a/src/doc/rustc-dev-guide/src/about-this-guide.md
    +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md
    @@ -103,9 +103,9 @@ You might also find the following sites useful:
     [tlgba]: https://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/
     [ro]: https://www.rustaceans.org/
     [rctd]: tests/intro.md
    -[cheatsheet]: https://bors.rust-lang.org/
    +[cheatsheet]: https://bors.rust-lang.org/help
     [Miri]: https://github.com/rust-lang/miri
    -[@bors]: https://github.com/bors
    +[@bors]: https://github.com/rust-lang/bors
     [a GitHub repository]: https://github.com/rust-lang/rustc-dev-guide/
     [rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle
     [Forge]: https://forge.rust-lang.org/
    diff --git a/src/doc/rustc-dev-guide/src/compiler-team.md b/src/doc/rustc-dev-guide/src/compiler-team.md
    index dfc1e7eedf62..495bd22da4d8 100644
    --- a/src/doc/rustc-dev-guide/src/compiler-team.md
    +++ b/src/doc/rustc-dev-guide/src/compiler-team.md
    @@ -96,9 +96,9 @@ Once you have made a number of individual PRs to rustc, we will often
     offer r+ privileges. This means that you have the right to instruct
     "bors" (the robot that manages which PRs get landed into rustc) to
     merge a PR
    -([here are some instructions for how to talk to bors][homu-guide]).
    +([here are some instructions for how to talk to bors][bors-guide]).
     
    -[homu-guide]: https://bors.rust-lang.org/
    +[bors-guide]: https://bors.rust-lang.org/
     
     The guidelines for reviewers are as follows:
     
    diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md
    index 40ad58e025c1..46d0dc23394a 100644
    --- a/src/doc/rustc-dev-guide/src/contributing.md
    +++ b/src/doc/rustc-dev-guide/src/contributing.md
    @@ -283,7 +283,7 @@ this can take a while and the queue can sometimes be long.
     Also, note that PRs are never merged by hand.
     
     [@rustbot]: https://github.com/rustbot
    -[@bors]: https://github.com/bors
    +[@bors]: https://github.com/rust-lang/bors
     
     ### Opening a PR
     
    diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md
    index e132946ae83e..ce80b07fe08d 100644
    --- a/src/doc/rustc-dev-guide/src/tests/ci.md
    +++ b/src/doc/rustc-dev-guide/src/tests/ci.md
    @@ -198,7 +198,7 @@ to help make the perf comparison as fair as possible.
     >
     > 3. Run the prescribed try jobs with `@bors try`. As aforementioned, this
     >    requires the user to either (1) have `try` permissions or (2) be delegated
    ->    with `try` permissions by `@bors delegate` by someone who has `try`
    +>    with `try` permissions by `@bors delegate=try` by someone who has `try`
     >    permissions.
     >
     > Note that this is usually easier to do than manually edit [`jobs.yml`].
    @@ -213,10 +213,7 @@ the corresponding PR.
     Multiple try builds can execute concurrently across different PRs, but there can be at most
     a single try build running on a single PR at any given time.
     
    -Note that try builds are handled using the [new bors] implementation.
    -
     [rustc-perf]: https://github.com/rust-lang/rustc-perf
    -[new bors]: https://github.com/rust-lang/bors
     
     ### Modifying CI jobs
     
    @@ -281,8 +278,7 @@ Breakages like these usually happen when another, incompatible PR is merged
     after the build happened.
     
     To ensure a `main` branch that works all the time, we forbid manual merges.
    -Instead, all PRs have to be approved through our bot, [bors] (the software
    -behind it is called [homu]).
    +Instead, all PRs have to be approved through our bot, [bors].
     All the approved PRs are put in a [merge queue]
     (sorted by priority and creation date) and are automatically tested one at the time.
     If all the builders are green, the PR is merged, otherwise the failure is
    @@ -465,8 +461,7 @@ To do this:
     [`jobs.yml`]: https://github.com/rust-lang/rust/blob/HEAD/src/ci/github-actions/jobs.yml
     [`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/HEAD/.github/workflows/ci.yml
     [`src/ci/citool`]: https://github.com/rust-lang/rust/blob/HEAD/src/ci/citool
    -[bors]: https://github.com/bors
    -[homu]: https://github.com/rust-lang/homu
    +[bors]: https://github.com/rust-lang/bors
     [merge queue]: https://bors.rust-lang.org/queue/rust
     [dist-x86_64-linux]: https://github.com/rust-lang/rust/blob/HEAD/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
     [the GitHub Actions workflows page]: https://github.com/rust-lang/rust/actions
    
    From 27e09ce0be5693cd4767576bf97098ddb994d59e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
    Date: Tue, 13 Jan 2026 16:53:21 +0000
    Subject: [PATCH 2082/3801] Update ui-fulldeps --stage 2 tests
    
    ---
     tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr           | 2 +-
     tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr        | 2 +-
     .../diagnostic-derive-doc-comment-field.stderr                | 4 ++--
     tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr | 2 +-
     4 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr b/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr
    index d2303ef4bbb5..4a6ca56bf329 100644
    --- a/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr
    +++ b/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisf
     LL |     type Result = NotAValidResultType;
        |                   ^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `VisitorResult` is not implemented for `NotAValidResultType`
    +help: the nightly-only, unstable trait `VisitorResult` is not implemented for `NotAValidResultType`
       --> $DIR/rustc-dev-remap.rs:LL:COL
        |
     LL | struct NotAValidResultType;
    diff --git a/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr b/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr
    index 50bb60e78d68..18dffdb2cf79 100644
    --- a/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr
    +++ b/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr
    @@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisf
     LL |     type Result = NotAValidResultType;
        |                   ^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `VisitorResult` is not implemented for `NotAValidResultType`
    +help: the nightly-only, unstable trait `VisitorResult` is not implemented for `NotAValidResultType`
       --> $DIR/rustc-dev-remap.rs:LL:COL
        |
     LL | struct NotAValidResultType;
    diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr
    index 72e150dd5178..316f23888bc1 100644
    --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr
    +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr
    @@ -7,7 +7,7 @@ LL | #[derive(Diagnostic)]
     LL |     arg: NotIntoDiagArg,
        |          ^^^^^^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `IntoDiagArg` is not implemented for `NotIntoDiagArg`
    +help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg`
       --> $DIR/diagnostic-derive-doc-comment-field.rs:28:1
        |
     LL | struct NotIntoDiagArg;
    @@ -29,7 +29,7 @@ LL | #[derive(Subdiagnostic)]
     LL |     arg: NotIntoDiagArg,
        |          ^^^^^^^^^^^^^^ unsatisfied trait bound
        |
    -help: the trait `IntoDiagArg` is not implemented for `NotIntoDiagArg`
    +help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg`
       --> $DIR/diagnostic-derive-doc-comment-field.rs:28:1
        |
     LL | struct NotIntoDiagArg;
    diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
    index f2244a968769..90ad21ef08f9 100644
    --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
    +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
    @@ -657,7 +657,7 @@ LL | #[derive(Diagnostic)]
     LL |     other: Hello,
        |            ^^^^^ unsatisfied trait bound
        |
    -help: the trait `IntoDiagArg` is not implemented for `Hello`
    +help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `Hello`
       --> $DIR/diagnostic-derive.rs:40:1
        |
     LL | struct Hello {}
    
    From 814647f047e277399b6185b9e94f6096edb16a07 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Esteban=20K=C3=BCber?= 
    Date: Fri, 26 Dec 2025 20:23:50 +0000
    Subject: [PATCH 2083/3801] Change some `matches!(.., .. if ..)` with
     let-chains
    
    ---
     compiler/rustc_const_eval/src/check_consts/check.rs | 13 +++++++------
     .../rustc_lint/src/early/diagnostics/check_cfg.rs   |  2 +-
     compiler/rustc_lint/src/transmute.rs                |  4 +++-
     compiler/rustc_middle/src/mir/pretty.rs             |  7 +++++--
     compiler/rustc_parse/src/parser/diagnostics.rs      |  4 +++-
     compiler/rustc_parse/src/parser/mod.rs              |  7 +++----
     .../src/error_reporting/traits/suggestions.rs       |  3 ++-
     7 files changed, 24 insertions(+), 16 deletions(-)
    
    diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
    index b06b407a6085..3a85ca3760d2 100644
    --- a/compiler/rustc_const_eval/src/check_consts/check.rs
    +++ b/compiler/rustc_const_eval/src/check_consts/check.rs
    @@ -833,12 +833,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
     
                     // const-eval of `panic_display` assumes the argument is `&&str`
                     if tcx.is_lang_item(callee, LangItem::PanicDisplay) {
    -                    match args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() {
    -                        ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) =>
    -                            {}
    -                        _ => {
    -                            self.check_op(ops::PanicNonStr);
    -                        }
    +                    if let ty::Ref(_, ty, _) =
    +                        args[0].node.ty(&self.ccx.body.local_decls, tcx).kind()
    +                        && let ty::Ref(_, ty, _) = ty.kind()
    +                        && ty.is_str()
    +                    {
    +                    } else {
    +                        self.check_op(ops::PanicNonStr);
                         }
                         // Allow this call, skip all the checks below.
                         return;
    diff --git a/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs
    index 0c8d7523a9dc..fab0e9e863dc 100644
    --- a/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs
    +++ b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs
    @@ -70,7 +70,7 @@ fn cargo_help_sub(
         // `build_script_build`) to try to figure out if we are building a Cargo build script
     
         let unescaped = &inst(EscapeQuotes::No);
    -    if matches!(&sess.opts.crate_name, Some(crate_name) if crate_name == "build_script_build") {
    +    if let Some("build_script_build") = sess.opts.crate_name.as_deref() {
             lints::UnexpectedCfgCargoHelp::lint_cfg(unescaped)
         } else {
             lints::UnexpectedCfgCargoHelp::lint_cfg_and_build_rs(unescaped, &inst(EscapeQuotes::Yes))
    diff --git a/compiler/rustc_lint/src/transmute.rs b/compiler/rustc_lint/src/transmute.rs
    index 98510eea73b8..6bc4617eb2dc 100644
    --- a/compiler/rustc_lint/src/transmute.rs
    +++ b/compiler/rustc_lint/src/transmute.rs
    @@ -152,7 +152,9 @@ fn check_int_to_ptr_transmute<'tcx>(
             return;
         };
         // bail-out if the argument is literal 0 as we have other lints for those cases
    -    if matches!(arg.kind, hir::ExprKind::Lit(hir::Lit { node: LitKind::Int(v, _), .. }) if v == 0) {
    +    if let hir::ExprKind::Lit(hir::Lit { node: LitKind::Int(v, _), .. }) = arg.kind
    +        && v == 0
    +    {
             return;
         }
         // bail-out if the inner type is a ZST
    diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
    index a31f03362a3d..ded02595563c 100644
    --- a/compiler/rustc_middle/src/mir/pretty.rs
    +++ b/compiler/rustc_middle/src/mir/pretty.rs
    @@ -1871,13 +1871,16 @@ fn pretty_print_const_value_tcx<'tcx>(
         let u8_type = tcx.types.u8;
         match (ct, ty.kind()) {
             // Byte/string slices, printed as (byte) string literals.
    -        (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => {
    +        (_, ty::Ref(_, inner_ty, _)) if let ty::Str = inner_ty.kind() => {
                 if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
                     fmt.write_str(&format!("{:?}", String::from_utf8_lossy(data)))?;
                     return Ok(());
                 }
             }
    -        (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(t) if *t == u8_type) => {
    +        (_, ty::Ref(_, inner_ty, _))
    +            if let ty::Slice(t) = inner_ty.kind()
    +                && *t == u8_type =>
    +        {
                 if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
                     pretty_print_byte_str(fmt, data)?;
                     return Ok(());
    diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
    index 70ec80a50812..2fd1d146b1f6 100644
    --- a/compiler/rustc_parse/src/parser/diagnostics.rs
    +++ b/compiler/rustc_parse/src/parser/diagnostics.rs
    @@ -761,7 +761,9 @@ impl<'a> Parser<'a> {
             }
     
             // Check for misspelled keywords if there are no suggestions added to the diagnostic.
    -        if matches!(&err.suggestions, Suggestions::Enabled(list) if list.is_empty()) {
    +        if let Suggestions::Enabled(list) = &err.suggestions
    +            && list.is_empty()
    +        {
                 self.check_for_misspelled_kw(&mut err, &expected);
             }
             Err(err)
    diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
    index 4dade1d01282..d6e99bc540f7 100644
    --- a/compiler/rustc_parse/src/parser/mod.rs
    +++ b/compiler/rustc_parse/src/parser/mod.rs
    @@ -1203,10 +1203,9 @@ impl<'a> Parser<'a> {
             let mut token = Token::dummy();
             while i < dist {
                 token = cursor.next().0;
    -            if matches!(
    -                token.kind,
    -                token::OpenInvisible(origin) | token::CloseInvisible(origin) if origin.skip()
    -            ) {
    +            if let token::OpenInvisible(origin) | token::CloseInvisible(origin) = token.kind
    +                && origin.skip()
    +            {
                     continue;
                 }
                 i += 1;
    diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
    index 511e9e85b5f6..507371425e4f 100644
    --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
    +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
    @@ -4722,7 +4722,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             // slices of `element_ty` with `mutability`.
             let mut is_slice = |candidate: Ty<'tcx>| match *candidate.kind() {
                 ty::RawPtr(t, m) | ty::Ref(_, t, m) => {
    -                if matches!(*t.kind(), ty::Slice(e) if e == element_ty)
    +                if let ty::Slice(e) = *t.kind()
    +                    && e == element_ty
                         && m == mutability.unwrap_or(m)
                     {
                         // Use the candidate's mutability going forward.
    
    From e027ecdbb57822527ed69e3cc81ca9ce36735678 Mon Sep 17 00:00:00 2001
    From: BD103 <59022059+BD103@users.noreply.github.com>
    Date: Mon, 12 Jan 2026 16:24:49 -0500
    Subject: [PATCH 2084/3801] feat: support arrays in type reflection
    
    ---
     .../src/const_eval/type_info.rs               | 35 +++++++++++++++++--
     compiler/rustc_span/src/symbol.rs             |  2 ++
     library/core/src/mem/type_info.rs             | 13 +++++++
     library/coretests/tests/lib.rs                |  1 +
     library/coretests/tests/mem.rs                |  2 ++
     library/coretests/tests/mem/type_info.rs      | 23 ++++++++++++
     tests/ui/reflection/dump.rs                   |  1 +
     tests/ui/reflection/dump.run.stdout           |  6 ++++
     8 files changed, 81 insertions(+), 2 deletions(-)
     create mode 100644 library/coretests/tests/mem/type_info.rs
    
    diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs
    index f932b198b426..814c81278a10 100644
    --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs
    +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs
    @@ -3,7 +3,7 @@ use rustc_hir::LangItem;
     use rustc_middle::mir::interpret::CtfeProvenance;
     use rustc_middle::span_bug;
     use rustc_middle::ty::layout::TyAndLayout;
    -use rustc_middle::ty::{self, ScalarInt, Ty};
    +use rustc_middle::ty::{self, Const, ScalarInt, Ty};
     use rustc_span::{Symbol, sym};
     
     use crate::const_eval::CompileTimeMachine;
    @@ -56,6 +56,14 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
                                 self.write_tuple_fields(tuple_place, fields, ty)?;
                                 variant
                             }
    +                        ty::Array(ty, len) => {
    +                            let (variant, variant_place) = downcast(sym::Array)?;
    +                            let array_place = self.project_field(&variant_place, FieldIdx::ZERO)?;
    +
    +                            self.write_array_type_info(array_place, *ty, *len)?;
    +
    +                            variant
    +                        }
                             // For now just merge all primitives into one `Leaf` variant with no data
                             ty::Uint(_) | ty::Int(_) | ty::Float(_) | ty::Char | ty::Bool => {
                                 downcast(sym::Leaf)?.0
    @@ -63,7 +71,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
                             ty::Adt(_, _)
                             | ty::Foreign(_)
                             | ty::Str
    -                        | ty::Array(_, _)
                             | ty::Pat(_, _)
                             | ty::Slice(_)
                             | ty::RawPtr(..)
    @@ -172,4 +179,28 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
             }
             interp_ok(())
         }
    +
    +    pub(crate) fn write_array_type_info(
    +        &mut self,
    +        place: impl Writeable<'tcx, CtfeProvenance>,
    +        ty: Ty<'tcx>,
    +        len: Const<'tcx>,
    +    ) -> InterpResult<'tcx> {
    +        // Iterate over all fields of `type_info::Array`.
    +        for (field_idx, field) in
    +            place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated()
    +        {
    +            let field_place = self.project_field(&place, field_idx)?;
    +
    +            match field.name {
    +                // Write the `TypeId` of the array's elements to the `element_ty` field.
    +                sym::element_ty => self.write_type_id(ty, &field_place)?,
    +                // Write the length of the array to the `len` field.
    +                sym::len => self.write_scalar(len.to_leaf(), &field_place)?,
    +                other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"),
    +            }
    +        }
    +
    +        interp_ok(())
    +    }
     }
    diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
    index f56c3421ce0f..34804160ed39 100644
    --- a/compiler/rustc_span/src/symbol.rs
    +++ b/compiler/rustc_span/src/symbol.rs
    @@ -162,6 +162,7 @@ symbols! {
             Arc,
             ArcWeak,
             Argument,
    +        Array,
             ArrayIntoIter,
             AsMut,
             AsRef,
    @@ -939,6 +940,7 @@ symbols! {
             eii_impl,
             eii_internals,
             eii_shared_macro,
    +        element_ty,
             emit,
             emit_enum,
             emit_enum_variant,
    diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs
    index 7938e2b52ed0..208cbc299aae 100644
    --- a/library/core/src/mem/type_info.rs
    +++ b/library/core/src/mem/type_info.rs
    @@ -43,6 +43,8 @@ impl Type {
     pub enum TypeKind {
         /// Tuples.
         Tuple(Tuple),
    +    /// Arrays.
    +    Array(Array),
         /// Primitives
         /// FIXME(#146922): disambiguate further
         Leaf,
    @@ -69,3 +71,14 @@ pub struct Field {
         /// Offset in bytes from the parent type
         pub offset: usize,
     }
    +
    +/// Compile-time type information about arrays.
    +#[derive(Debug)]
    +#[non_exhaustive]
    +#[unstable(feature = "type_info", issue = "146922")]
    +pub struct Array {
    +    /// The type of each element in the array.
    +    pub element_ty: TypeId,
    +    /// The length of the array.
    +    pub len: usize,
    +}
    diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
    index ff4fc4c892af..caa130be1483 100644
    --- a/library/coretests/tests/lib.rs
    +++ b/library/coretests/tests/lib.rs
    @@ -115,6 +115,7 @@
     #![feature(try_blocks)]
     #![feature(try_find)]
     #![feature(try_trait_v2)]
    +#![feature(type_info)]
     #![feature(uint_bit_width)]
     #![feature(uint_gather_scatter_bits)]
     #![feature(unsize)]
    diff --git a/library/coretests/tests/mem.rs b/library/coretests/tests/mem.rs
    index 5247e01fba01..193d5416b06a 100644
    --- a/library/coretests/tests/mem.rs
    +++ b/library/coretests/tests/mem.rs
    @@ -1,3 +1,5 @@
    +mod type_info;
    +
     use core::mem::*;
     use core::{array, ptr};
     use std::cell::Cell;
    diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs
    new file mode 100644
    index 000000000000..5cd690363a01
    --- /dev/null
    +++ b/library/coretests/tests/mem/type_info.rs
    @@ -0,0 +1,23 @@
    +use std::any::TypeId;
    +use std::mem::type_info::{Type, TypeKind};
    +
    +#[test]
    +fn test_arrays() {
    +    // Normal array.
    +    match const { Type::of::<[u16; 4]>() }.kind {
    +        TypeKind::Array(array) => {
    +            assert_eq!(array.element_ty, TypeId::of::());
    +            assert_eq!(array.len, 4);
    +        }
    +        _ => unreachable!(),
    +    }
    +
    +    // Zero-length array.
    +    match const { Type::of::<[bool; 0]>() }.kind {
    +        TypeKind::Array(array) => {
    +            assert_eq!(array.element_ty, TypeId::of::());
    +            assert_eq!(array.len, 0);
    +        }
    +        _ => unreachable!(),
    +    }
    +}
    diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs
    index 3bf4f32b6641..cc3bcb8b9faf 100644
    --- a/tests/ui/reflection/dump.rs
    +++ b/tests/ui/reflection/dump.rs
    @@ -22,6 +22,7 @@ struct Unsized {
     
     fn main() {
         println!("{:#?}", const { Type::of::<(u8, u8, ())>() }.kind);
    +    println!("{:#?}", const { Type::of::<[u8; 2]>() }.kind);
         println!("{:#?}", const { Type::of::() }.kind);
         println!("{:#?}", const { Type::of::() }.kind);
         println!("{:#?}", const { Type::of::<&Unsized>() }.kind);
    diff --git a/tests/ui/reflection/dump.run.stdout b/tests/ui/reflection/dump.run.stdout
    index 71fd80b46658..7a0bb9592a3c 100644
    --- a/tests/ui/reflection/dump.run.stdout
    +++ b/tests/ui/reflection/dump.run.stdout
    @@ -16,6 +16,12 @@ Tuple(
             ],
         },
     )
    +Array(
    +    Array {
    +        element_ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb),
    +        len: 2,
    +    },
    +)
     Other
     Other
     Other
    
    From 71f8ea99fe5cfbca752ddcfb1c0b13453941a9e6 Mon Sep 17 00:00:00 2001
    From: BD103 <59022059+BD103@users.noreply.github.com>
    Date: Tue, 13 Jan 2026 12:19:37 -0500
    Subject: [PATCH 2085/3801] refactor: move tuples type info ui test to coretest
    
    ---
     library/coretests/tests/mem/type_info.rs | 33 ++++++++++++++++++++++
     tests/ui/reflection/tuples.rs            | 36 ------------------------
     2 files changed, 33 insertions(+), 36 deletions(-)
     delete mode 100644 tests/ui/reflection/tuples.rs
    
    diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs
    index 5cd690363a01..b3b8d96d49b0 100644
    --- a/library/coretests/tests/mem/type_info.rs
    +++ b/library/coretests/tests/mem/type_info.rs
    @@ -21,3 +21,36 @@ fn test_arrays() {
             _ => unreachable!(),
         }
     }
    +
    +#[test]
    +fn test_tuples() {
    +    fn assert_tuple_arity() {
    +        match const { Type::of::() }.kind {
    +            TypeKind::Tuple(tup) => {
    +                assert_eq!(tup.fields.len(), N);
    +            }
    +            _ => unreachable!(),
    +        }
    +    }
    +
    +    assert_tuple_arity::<(), 0>();
    +    assert_tuple_arity::<(u8,), 1>();
    +    assert_tuple_arity::<(u8, u8), 2>();
    +
    +    const {
    +        match Type::of::<(u8, u8)>().kind {
    +            TypeKind::Tuple(tup) => {
    +                let [a, b] = tup.fields else { unreachable!() };
    +
    +                assert!(a.offset == 0);
    +                assert!(b.offset == 1);
    +
    +                match (a.ty.info().kind, b.ty.info().kind) {
    +                    (TypeKind::Leaf, TypeKind::Leaf) => {}
    +                    _ => unreachable!(),
    +                }
    +            }
    +            _ => unreachable!(),
    +        }
    +    }
    +}
    diff --git a/tests/ui/reflection/tuples.rs b/tests/ui/reflection/tuples.rs
    deleted file mode 100644
    index eab25a691efe..000000000000
    --- a/tests/ui/reflection/tuples.rs
    +++ /dev/null
    @@ -1,36 +0,0 @@
    -#![feature(type_info)]
    -
    -//@ run-pass
    -
    -use std::mem::type_info::{Type, TypeKind};
    -
    -fn assert_tuple_arity() {
    -    const {
    -        match &Type::of::().kind {
    -            TypeKind::Tuple(tup) => {
    -                assert!(tup.fields.len() == N);
    -            }
    -            _ => unreachable!(),
    -        }
    -    }
    -}
    -
    -fn main() {
    -    assert_tuple_arity::<(), 0>();
    -    assert_tuple_arity::<(u8,), 1>();
    -    assert_tuple_arity::<(u8, u8), 2>();
    -    const {
    -        match &Type::of::<(u8, u8)>().kind {
    -            TypeKind::Tuple(tup) => {
    -                let [a, b] = tup.fields else { unreachable!() };
    -                assert!(a.offset == 0);
    -                assert!(b.offset == 1);
    -                match (&a.ty.info().kind, &b.ty.info().kind) {
    -                    (TypeKind::Leaf, TypeKind::Leaf) => {}
    -                    _ => unreachable!(),
    -                }
    -            }
    -            _ => unreachable!(),
    -        }
    -    }
    -}
    
    From c4820e6cb45407c8d34ebf7fe7a8bdd683f2003f Mon Sep 17 00:00:00 2001
    From: Vadim Petrochenkov 
    Date: Fri, 9 Jan 2026 14:40:20 +0300
    Subject: [PATCH 2086/3801] resolve: Refactor away the side table
     `decl_parent_modules`
    
    Instead keep parent modules in `DeclData` itself
    ---
     .../rustc_resolve/src/build_reduced_graph.rs  | 33 ++++++++++---------
     compiler/rustc_resolve/src/diagnostics.rs     | 27 +++++++--------
     compiler/rustc_resolve/src/imports.rs         |  9 ++---
     compiler/rustc_resolve/src/lib.rs             | 31 +++++++----------
     4 files changed, 46 insertions(+), 54 deletions(-)
    
    diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
    index 752d8c46beb4..736648c125b6 100644
    --- a/compiler/rustc_resolve/src/build_reduced_graph.rs
    +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
    @@ -48,14 +48,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         /// and report an error in case of a collision.
         pub(crate) fn plant_decl_into_local_module(
             &mut self,
    -        parent: Module<'ra>,
             ident: Macros20NormalizedIdent,
             ns: Namespace,
             decl: Decl<'ra>,
         ) {
    -        if let Err(old_decl) = self.try_plant_decl_into_local_module(parent, ident, ns, decl, false)
    -        {
    -            self.report_conflict(parent, ident.0, ns, old_decl, decl);
    +        if let Err(old_decl) = self.try_plant_decl_into_local_module(ident, ns, decl, false) {
    +            self.report_conflict(ident.0, ns, old_decl, decl);
             }
         }
     
    @@ -70,9 +68,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             span: Span,
             expn_id: LocalExpnId,
         ) {
    -        let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id);
    +        let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id, Some(parent));
             let ident = Macros20NormalizedIdent::new(ident);
    -        self.plant_decl_into_local_module(parent, ident, ns, decl);
    +        self.plant_decl_into_local_module(ident, ns, decl);
         }
     
         /// Create a name definitinon from the given components, and put it into the extern module.
    @@ -96,6 +94,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 vis: CmCell::new(vis),
                 span,
                 expansion,
    +            parent_module: Some(parent),
             });
             // Even if underscore names cannot be looked up, we still need to add them to modules,
             // because they can be fetched by glob imports from those modules, and bring traits
    @@ -289,7 +288,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child;
                 let span = child_span(self, reexport_chain, res);
                 let res = res.expect_non_local();
    -            self.arenas.new_def_decl(res, vis, span, expansion)
    +            self.arenas.new_def_decl(res, vis, span, expansion, Some(parent))
             });
     
             // Record primary definitions.
    @@ -844,7 +843,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                         ident,
                         local_def_id,
                         vis,
    -                    parent,
                     );
                 }
     
    @@ -976,10 +974,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
             ident: Ident,
             local_def_id: LocalDefId,
             vis: Visibility,
    -        parent: Module<'ra>,
         ) {
             let sp = item.span;
             let parent_scope = self.parent_scope;
    +        let parent = parent_scope.module;
             let expansion = parent_scope.expansion;
     
             let (used, module, decl) = if orig_name.is_none() && ident.name == kw::SelfLower {
    @@ -1009,7 +1007,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
             let import = self.r.arenas.alloc_import(ImportData {
                 kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
                 root_id: item.id,
    -            parent_scope: self.parent_scope,
    +            parent_scope,
                 imported_module: CmCell::new(module),
                 has_attributes: !item.attrs.is_empty(),
                 use_span_with_attributes: item.span_with_attributes(),
    @@ -1057,7 +1055,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                     }),
                 };
             }
    -        self.r.plant_decl_into_local_module(parent, ident, TypeNS, import_decl);
    +        self.r.plant_decl_into_local_module(ident, TypeNS, import_decl);
         }
     
         /// Constructs the reduced graph for one foreign item.
    @@ -1300,14 +1298,19 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                 } else {
                     Visibility::Restricted(CRATE_DEF_ID)
                 };
    -            let decl = self.r.arenas.new_def_decl(res, vis.to_def_id(), span, expansion);
    -            self.r.set_decl_parent_module(decl, parent_scope.module);
    +            let decl = self.r.arenas.new_def_decl(
    +                res,
    +                vis.to_def_id(),
    +                span,
    +                expansion,
    +                Some(parent_scope.module),
    +            );
                 self.r.all_macro_rules.insert(ident.name);
                 if is_macro_export {
                     let import = self.r.arenas.alloc_import(ImportData {
                         kind: ImportKind::MacroExport,
                         root_id: item.id,
    -                    parent_scope: self.parent_scope,
    +                    parent_scope: ParentScope { module: self.r.graph_root, ..parent_scope },
                         imported_module: CmCell::new(None),
                         has_attributes: false,
                         use_span_with_attributes: span,
    @@ -1320,7 +1323,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                     });
                     self.r.import_use_map.insert(import, Used::Other);
                     let import_decl = self.r.new_import_decl(decl, import);
    -                self.r.plant_decl_into_local_module(self.r.graph_root, ident, MacroNS, import_decl);
    +                self.r.plant_decl_into_local_module(ident, MacroNS, import_decl);
                 } else {
                     self.r.check_reserved_macro_name(ident.0, res);
                     self.insert_unused_macro(ident.0, def_id, item.id);
    diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
    index 7bc08f1de546..b80011e8c0cb 100644
    --- a/compiler/rustc_resolve/src/diagnostics.rs
    +++ b/compiler/rustc_resolve/src/diagnostics.rs
    @@ -210,7 +210,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     
         pub(crate) fn report_conflict(
             &mut self,
    -        parent: Module<'_>,
             ident: Ident,
             ns: Namespace,
             new_binding: Decl<'ra>,
    @@ -218,13 +217,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         ) {
             // Error on the second of two conflicting names
             if old_binding.span.lo() > new_binding.span.lo() {
    -            return self.report_conflict(parent, ident, ns, old_binding, new_binding);
    +            return self.report_conflict(ident, ns, old_binding, new_binding);
             }
     
    -        let container = match parent.kind {
    +        let container = match old_binding.parent_module.unwrap().kind {
                 // Avoid using TyCtxt::def_kind_descr in the resolver, because it
                 // indirectly *calls* the resolver, and would cause a query cycle.
    -            ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()),
    +            ModuleKind::Def(kind, def_id, _) => kind.descr(def_id),
                 ModuleKind::Block => "block",
             };
     
    @@ -2034,15 +2033,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                     help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously"))
                 }
     
    -            if let Scope::ModuleNonGlobs(module, _) | Scope::ModuleGlobs(module, _) = scope {
    -                if module == self.graph_root {
    -                    help_msgs.push(format!(
    -                        "use `crate::{ident}` to refer to this {thing} unambiguously"
    -                    ));
    -                } else if module != self.empty_module && module.is_normal() {
    -                    help_msgs.push(format!(
    -                        "use `self::{ident}` to refer to this {thing} unambiguously"
    -                    ));
    +            if kind != AmbiguityKind::GlobVsGlob {
    +                if let Scope::ModuleNonGlobs(module, _) | Scope::ModuleGlobs(module, _) = scope {
    +                    if module == self.graph_root {
    +                        help_msgs.push(format!(
    +                            "use `crate::{ident}` to refer to this {thing} unambiguously"
    +                        ));
    +                    } else if module.is_normal() {
    +                        help_msgs.push(format!(
    +                            "use `self::{ident}` to refer to this {thing} unambiguously"
    +                        ));
    +                    }
                     }
                 }
     
    diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
    index 4447374b8b06..e525abd00f99 100644
    --- a/compiler/rustc_resolve/src/imports.rs
    +++ b/compiler/rustc_resolve/src/imports.rs
    @@ -340,6 +340,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 span: import.span,
                 vis: CmCell::new(vis),
                 expansion: import.parent_scope.expansion,
    +            parent_module: Some(import.parent_scope.module),
             })
         }
     
    @@ -409,15 +410,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         /// and return existing declaration if there is a collision.
         pub(crate) fn try_plant_decl_into_local_module(
             &mut self,
    -        module: Module<'ra>,
             ident: Macros20NormalizedIdent,
             ns: Namespace,
             decl: Decl<'ra>,
             warn_ambiguity: bool,
         ) -> Result<(), Decl<'ra>> {
    +        let module = decl.parent_module.unwrap();
             let res = decl.res();
             self.check_reserved_macro_name(ident.0, res);
    -        self.set_decl_parent_module(decl, module);
             // Even if underscore names cannot be looked up, we still need to add them to modules,
             // because they can be fetched by glob imports from those modules, and bring traits
             // into scope both directly and through glob imports.
    @@ -511,7 +511,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 if self.is_accessible_from(binding.vis(), scope) {
                     let import_decl = self.new_import_decl(binding, *import);
                     let _ = self.try_plant_decl_into_local_module(
    -                    import.parent_scope.module,
                         ident,
                         key.ns,
                         import_decl,
    @@ -535,7 +534,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 self.per_ns(|this, ns| {
                     let module = import.parent_scope.module;
                     let ident = Macros20NormalizedIdent::new(target);
    -                let _ = this.try_plant_decl_into_local_module(module, ident, ns, dummy_decl, false);
    +                let _ = this.try_plant_decl_into_local_module(ident, ns, dummy_decl, false);
                     // Don't remove underscores from `single_imports`, they were never added.
                     if target.name != kw::Underscore {
                         let key = BindingKey::new(ident, ns);
    @@ -916,7 +915,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                             // We need the `target`, `source` can be extracted.
                             let import_decl = this.new_import_decl(binding, import);
                             this.get_mut_unchecked().plant_decl_into_local_module(
    -                            parent,
                                 Macros20NormalizedIdent::new(target),
                                 ns,
                                 import_decl,
    @@ -1542,7 +1540,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         .and_then(|r| r.binding())
                         .is_some_and(|binding| binding.warn_ambiguity_recursive());
                     let _ = self.try_plant_decl_into_local_module(
    -                    import.parent_scope.module,
                         key.ident,
                         key.ns,
                         import_decl,
    diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
    index c4c1e06f94ae..2c22aacb3241 100644
    --- a/compiler/rustc_resolve/src/lib.rs
    +++ b/compiler/rustc_resolve/src/lib.rs
    @@ -67,7 +67,6 @@ use rustc_metadata::creader::CStore;
     use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport};
     use rustc_middle::middle::privacy::EffectiveVisibilities;
     use rustc_middle::query::Providers;
    -use rustc_middle::span_bug;
     use rustc_middle::ty::{
         self, DelegationFnSig, DelegationInfo, Feed, MainDefinition, RegisteredTools,
         ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility,
    @@ -812,6 +811,7 @@ struct DeclData<'ra> {
         expansion: LocalExpnId,
         span: Span,
         vis: CmCell>,
    +    parent_module: Option>,
     }
     
     /// All name declarations are unique and allocated on a same arena,
    @@ -922,7 +922,6 @@ struct AmbiguityError<'ra> {
         ident: Ident,
         b1: Decl<'ra>,
         b2: Decl<'ra>,
    -    // `empty_module` in module scope serves as an unknown module here.
         scope1: Scope<'ra>,
         scope2: Scope<'ra>,
         warning: Option,
    @@ -1186,7 +1185,6 @@ pub struct Resolver<'ra, 'tcx> {
         local_module_map: FxIndexMap>,
         /// Lazily populated cache of modules loaded from external crates.
         extern_module_map: CacheRefCell>>,
    -    decl_parent_modules: FxHashMap, Module<'ra>>,
     
         /// Maps glob imports to the names of items actually imported.
         glob_map: FxIndexMap>,
    @@ -1349,6 +1347,7 @@ impl<'ra> ResolverArenas<'ra> {
             vis: Visibility,
             span: Span,
             expansion: LocalExpnId,
    +        parent_module: Option>,
         ) -> Decl<'ra> {
             self.alloc_decl(DeclData {
                 kind: DeclKind::Def(res),
    @@ -1357,11 +1356,12 @@ impl<'ra> ResolverArenas<'ra> {
                 vis: CmCell::new(vis),
                 span,
                 expansion,
    +            parent_module,
             })
         }
     
         fn new_pub_def_decl(&'ra self, res: Res, span: Span, expn_id: LocalExpnId) -> Decl<'ra> {
    -        self.new_def_decl(res, Visibility::Public, span, expn_id)
    +        self.new_def_decl(res, Visibility::Public, span, expn_id, None)
         }
     
         fn new_module(
    @@ -1616,7 +1616,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 local_module_map,
                 extern_module_map: Default::default(),
                 block_map: Default::default(),
    -            decl_parent_modules: FxHashMap::default(),
                 ast_transform_scopes: FxHashMap::default(),
     
                 glob_map: Default::default(),
    @@ -2071,8 +2070,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                     ident,
                     b1: used_decl,
                     b2,
    -                scope1: Scope::ModuleGlobs(self.empty_module, None),
    -                scope2: Scope::ModuleGlobs(self.empty_module, None),
    +                scope1: Scope::ModuleGlobs(used_decl.parent_module.unwrap(), None),
    +                scope2: Scope::ModuleGlobs(b2.parent_module.unwrap(), None),
                     warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None },
                 };
                 if !self.matches_previous_ambiguity_error(&ambiguity_error) {
    @@ -2237,14 +2236,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             vis.is_accessible_from(module.nearest_parent_mod(), self.tcx)
         }
     
    -    fn set_decl_parent_module(&mut self, decl: Decl<'ra>, module: Module<'ra>) {
    -        if let Some(old_module) = self.decl_parent_modules.insert(decl, module) {
    -            if module != old_module {
    -                span_bug!(decl.span, "parent module is reset for a name declaration");
    -            }
    -        }
    -    }
    -
         fn disambiguate_macro_rules_vs_modularized(
             &self,
             macro_rules: Decl<'ra>,
    @@ -2254,13 +2245,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             // is disambiguated to mitigate regressions from macro modularization.
             // Scoping for `macro_rules` behaves like scoping for `let` at module level, in general.
             //
    -        // panic on index should be impossible, the only name_bindings passed in should be from
    +        // Panic on unwrap should be impossible, the only name_bindings passed in should be from
             // `resolve_ident_in_scope_set` which will always refer to a local binding from an
    -        // import or macro definition
    -        let macro_rules = &self.decl_parent_modules[¯o_rules];
    -        let modularized = &self.decl_parent_modules[&modularized];
    +        // import or macro definition.
    +        let macro_rules = macro_rules.parent_module.unwrap();
    +        let modularized = modularized.parent_module.unwrap();
             macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod()
    -            && modularized.is_ancestor_of(*macro_rules)
    +            && modularized.is_ancestor_of(macro_rules)
         }
     
         fn extern_prelude_get_item<'r>(
    
    From 5435e8188ce1bf0912b3a98a54e316e391d3ca27 Mon Sep 17 00:00:00 2001
    From: The 8472 
    Date: Tue, 13 Jan 2026 18:52:04 +0100
    Subject: [PATCH 2087/3801] also handle ENOTTY ioctl errors when checking pidfd
     -> pid support
    
    Otherwise the std testsuite fails on older kernels.
    ---
     library/std/src/sys/pal/unix/linux/pidfd.rs       | 2 +-
     library/std/src/sys/pal/unix/linux/pidfd/tests.rs | 5 +++--
     2 files changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/library/std/src/sys/pal/unix/linux/pidfd.rs b/library/std/src/sys/pal/unix/linux/pidfd.rs
    index e9e4831fcc02..671046949aa1 100644
    --- a/library/std/src/sys/pal/unix/linux/pidfd.rs
    +++ b/library/std/src/sys/pal/unix/linux/pidfd.rs
    @@ -33,7 +33,7 @@ impl PidFd {
             match cvt(unsafe { libc::ioctl(self.0.as_raw_fd(), libc::PIDFD_GET_INFO, &mut pidfd_info) })
             {
                 Ok(_) => {}
    -            Err(e) if e.raw_os_error() == Some(libc::EINVAL) => {
    +            Err(e) if matches!(e.raw_os_error(), Some(libc::EINVAL | libc::ENOTTY)) => {
                     // kernel doesn't support that ioctl, try the glibc helper that looks at procfs
                     weak!(
                         fn pidfd_getpid(pidfd: RawFd) -> libc::pid_t;
    diff --git a/library/std/src/sys/pal/unix/linux/pidfd/tests.rs b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs
    index a3bb5d5d64ba..0330f28e647d 100644
    --- a/library/std/src/sys/pal/unix/linux/pidfd/tests.rs
    +++ b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs
    @@ -1,6 +1,5 @@
     use super::PidFd as InternalPidFd;
     use crate::assert_matches::assert_matches;
    -use crate::io::ErrorKind;
     use crate::os::fd::AsRawFd;
     use crate::os::linux::process::{ChildExt, CommandExt as _};
     use crate::os::unix::process::{CommandExt as _, ExitStatusExt};
    @@ -62,7 +61,9 @@ fn test_command_pidfd() {
         if let Ok(pidfd) = child.pidfd() {
             match pidfd.as_inner().pid() {
                 Ok(pid) => assert_eq!(pid, id),
    -            Err(e) if e.kind() == ErrorKind::InvalidInput => { /* older kernel */ }
    +            Err(e) if matches!(e.raw_os_error(), Some(libc::EINVAL | libc::ENOTTY)) => {
    +                /* older kernel */
    +            }
                 Err(e) => panic!("unexpected error getting pid from pidfd: {}", e),
             }
         }
    
    From 8fb704c17510f22700d4a84fc7151f67d9d20a27 Mon Sep 17 00:00:00 2001
    From: Lukas Wirth 
    Date: Tue, 13 Jan 2026 19:57:37 +0100
    Subject: [PATCH 2088/3801] fix: Hide renamed imports from macros in symbol
     index
    
    ---
     src/tools/rust-analyzer/crates/hir/src/symbols.rs | 15 +++++++++++++--
     1 file changed, 13 insertions(+), 2 deletions(-)
    
    diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
    index 4461659f5c4e..c088f3aa0cc0 100644
    --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs
    +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
    @@ -5,8 +5,8 @@ use std::marker::PhantomData;
     use base_db::FxIndexSet;
     use either::Either;
     use hir_def::{
    -    AdtId, AssocItemId, Complete, DefWithBodyId, ExternCrateId, HasModule, ImplId, Lookup, MacroId,
    -    ModuleDefId, ModuleId, TraitId,
    +    AdtId, AssocItemId, AstIdLoc, Complete, DefWithBodyId, ExternCrateId, HasModule, ImplId,
    +    Lookup, MacroId, ModuleDefId, ModuleId, TraitId,
         db::DefDatabase,
         item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob},
         nameres::crate_def_map,
    @@ -169,6 +169,7 @@ impl<'a> SymbolCollector<'a> {
     
         fn collect_from_module(&mut self, module_id: ModuleId) {
             let collect_pub_only = self.collect_pub_only;
    +        let is_block_module = module_id.is_block_module(self.db);
             let push_decl = |this: &mut Self, def: ModuleDefId, name, vis| {
                 if collect_pub_only && vis != Visibility::Public {
                     return;
    @@ -240,6 +241,10 @@ impl<'a> SymbolCollector<'a> {
                 let source = import_child_source_cache
                     .entry(i.use_)
                     .or_insert_with(|| i.use_.child_source(this.db));
    +            if is_block_module && source.file_id.is_macro() {
    +                // Macros tend to generate a lot of imports, the user really won't care about them
    +                return;
    +            }
                 let Some(use_tree_src) = source.value.get(i.idx) else { return };
                 let rename = use_tree_src.rename().and_then(|rename| rename.name());
                 let name_syntax = match rename {
    @@ -276,6 +281,12 @@ impl<'a> SymbolCollector<'a> {
                         return;
                     }
                     let loc = i.lookup(this.db);
    +                if is_block_module && loc.ast_id().file_id.is_macro() {
    +                    // Macros (especially derivves) tend to generate renamed extern crate items,
    +                    // the user really won't care about them
    +                    return;
    +                }
    +
                     let source = loc.source(this.db);
                     let rename = source.value.rename().and_then(|rename| rename.name());
     
    
    From 348bfe3e355a4479287d3940ca6b87f9be967040 Mon Sep 17 00:00:00 2001
    From: Josh Stone 
    Date: Tue, 13 Jan 2026 10:54:33 -0800
    Subject: [PATCH 2089/3801] compiler: upgrade to hashbrown 0.16.1
    
    See also #135634, #149159, and rust-lang/hashbrown#662.
    
    This includes an in-tree upgrade of `indexmap` as well, which uses the
    new `HashTable` buckets API internally, hopefully impacting performance
    for the better!
    ---
     Cargo.lock                                 | 19 +++++++++++--------
     compiler/rustc_data_structures/Cargo.toml  |  4 ++--
     compiler/rustc_mir_transform/Cargo.toml    |  2 +-
     compiler/rustc_query_system/Cargo.toml     |  2 +-
     src/bootstrap/src/utils/proc_macro_deps.rs |  1 +
     5 files changed, 16 insertions(+), 12 deletions(-)
    
    diff --git a/Cargo.lock b/Cargo.lock
    index bf28939ac87b..45d01c486faf 100644
    --- a/Cargo.lock
    +++ b/Cargo.lock
    @@ -1670,9 +1670,12 @@ dependencies = [
     
     [[package]]
     name = "hashbrown"
    -version = "0.16.0"
    +version = "0.16.1"
     source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
    +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
    +dependencies = [
    + "foldhash 0.2.0",
    +]
     
     [[package]]
     name = "heck"
    @@ -1950,12 +1953,12 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5"
     
     [[package]]
     name = "indexmap"
    -version = "2.12.0"
    +version = "2.12.1"
     source = "registry+https://github.com/rust-lang/crates.io-index"
    -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
    +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
     dependencies = [
      "equivalent",
    - "hashbrown 0.16.0",
    + "hashbrown 0.16.1",
      "serde",
      "serde_core",
     ]
    @@ -3730,7 +3733,7 @@ dependencies = [
      "either",
      "elsa",
      "ena",
    - "hashbrown 0.15.5",
    + "hashbrown 0.16.1",
      "indexmap",
      "jobserver",
      "libc",
    @@ -4346,7 +4349,7 @@ name = "rustc_mir_transform"
     version = "0.0.0"
     dependencies = [
      "either",
    - "hashbrown 0.15.5",
    + "hashbrown 0.16.1",
      "itertools",
      "rustc_abi",
      "rustc_arena",
    @@ -4557,7 +4560,7 @@ dependencies = [
     name = "rustc_query_system"
     version = "0.0.0"
     dependencies = [
    - "hashbrown 0.15.5",
    + "hashbrown 0.16.1",
      "parking_lot",
      "rustc_abi",
      "rustc_ast",
    diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
    index c8296e05f6bd..f358ffffb47d 100644
    --- a/compiler/rustc_data_structures/Cargo.toml
    +++ b/compiler/rustc_data_structures/Cargo.toml
    @@ -10,7 +10,7 @@ bitflags = "2.4.1"
     either = "1.0"
     elsa = "1.11.0"
     ena = "0.14.3"
    -indexmap = "2.4.0"
    +indexmap = "2.12.1"
     jobserver_crate = { version = "0.1.28", package = "jobserver" }
     measureme = "12.0.1"
     parking_lot = "0.12"
    @@ -31,7 +31,7 @@ tracing = "0.1"
     # tidy-alphabetical-end
     
     [dependencies.hashbrown]
    -version = "0.15.2"
    +version = "0.16.1"
     default-features = false
     features = ["nightly"] # for may_dangle
     
    diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml
    index 6df7a869ca28..22de197d374a 100644
    --- a/compiler/rustc_mir_transform/Cargo.toml
    +++ b/compiler/rustc_mir_transform/Cargo.toml
    @@ -6,7 +6,7 @@ edition = "2024"
     [dependencies]
     # tidy-alphabetical-start
     either = "1"
    -hashbrown = "0.15"
    +hashbrown = { version = "0.16.1", default-features = false }
     itertools = "0.12"
     rustc_abi = { path = "../rustc_abi" }
     rustc_arena = { path = "../rustc_arena" }
    diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
    index 7480ba03474f..73ab03576dec 100644
    --- a/compiler/rustc_query_system/Cargo.toml
    +++ b/compiler/rustc_query_system/Cargo.toml
    @@ -25,6 +25,6 @@ tracing = "0.1"
     # tidy-alphabetical-end
     
     [dependencies.hashbrown]
    -version = "0.15.2"
    +version = "0.16.1"
     default-features = false
     features = ["nightly"] # for may_dangle
    diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs
    index 71b6aacdebed..f1bf6e399fb1 100644
    --- a/src/bootstrap/src/utils/proc_macro_deps.rs
    +++ b/src/bootstrap/src/utils/proc_macro_deps.rs
    @@ -22,6 +22,7 @@ pub static CRATES: &[&str] = &[
         "fluent-langneg",
         "fluent-syntax",
         "fnv",
    +    "foldhash",
         "generic-array",
         "hashbrown",
         "heck",
    
    From afa2260a9cea4592606353895e0f8eee88356198 Mon Sep 17 00:00:00 2001
    From: Josh Stone 
    Date: Tue, 13 Jan 2026 10:54:39 -0800
    Subject: [PATCH 2090/3801] library: finish unspecializing `Copy`
    
    ---
     library/core/src/marker.rs | 3 ---
     1 file changed, 3 deletions(-)
    
    diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
    index 68f5649210de..da7ba167ef74 100644
    --- a/library/core/src/marker.rs
    +++ b/library/core/src/marker.rs
    @@ -455,9 +455,6 @@ marker_impls! {
     /// [impls]: #implementors
     #[stable(feature = "rust1", since = "1.0.0")]
     #[lang = "copy"]
    -// This is unsound, but required by `hashbrown`
    -// FIXME(joboet): change `hashbrown` to use `TrivialClone`
    -#[rustc_unsafe_specialization_marker]
     #[rustc_diagnostic_item = "Copy"]
     pub trait Copy: Clone {
         // Empty.
    
    From 8f953dea3aad273bc5e1450be7a15449ad07d7bb Mon Sep 17 00:00:00 2001
    From: Lukas Wirth 
    Date: Tue, 13 Jan 2026 20:30:38 +0100
    Subject: [PATCH 2091/3801] feat: Implement support for `feature(new_range)`
    
    ---
     .../crates/hir-def/src/lang_item.rs           |   5 +
     .../crates/hir-expand/src/mod_path.rs         |   4 +
     .../rust-analyzer/crates/hir-ty/src/infer.rs  |  28 ++++-
     .../crates/hir-ty/src/tests/patterns.rs       | 118 +++++++++---------
     .../crates/hir-ty/src/tests/simple.rs         |  41 ++++--
     .../crates/hir/src/source_analyzer.rs         |  80 ++++++++----
     .../crates/intern/src/symbol/symbols.rs       |   6 +
     .../crates/test-utils/src/minicore.rs         |  92 +++++++++-----
     8 files changed, 246 insertions(+), 128 deletions(-)
    
    diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
    index 092ff6e48671..51dd55301f44 100644
    --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
    +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
    @@ -499,6 +499,11 @@ language_item_table! { LangItems =>
         RangeToInclusive,        sym::RangeToInclusive,    StructId;
         RangeTo,                 sym::RangeTo,             StructId;
     
    +    RangeFromCopy,           sym::RangeFromCopy,           StructId;
    +    RangeInclusiveCopy,      sym::RangeInclusiveCopy,      StructId;
    +    RangeCopy,               sym::RangeCopy,               StructId;
    +    RangeToInclusiveCopy,    sym::RangeToInclusiveCopy,    StructId;
    +
         String,                  sym::String,              StructId;
         CStr,                    sym::CStr,                StructId;
         Ordering,                sym::Ordering,            EnumId;
    diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
    index 1712c28aa8ab..78228cf82e67 100644
    --- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
    +++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
    @@ -423,6 +423,10 @@ macro_rules! __known_path {
         (core::ops::RangeTo) => {};
         (core::ops::RangeToInclusive) => {};
         (core::ops::RangeInclusive) => {};
    +    (core::range::Range) => {};
    +    (core::range::RangeFrom) => {};
    +    (core::range::RangeInclusive) => {};
    +    (core::range::RangeToInclusive) => {};
         (core::future::Future) => {};
         (core::future::IntoFuture) => {};
         (core::fmt::Debug) => {};
    diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
    index d527a4ae29c2..35d744e7d16b 100644
    --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
    +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
    @@ -1815,18 +1815,34 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
             Some(struct_.into())
         }
     
    +    fn has_new_range_feature(&self) -> bool {
    +        self.resolver.top_level_def_map().is_unstable_feature_enabled(&sym::new_range)
    +    }
    +
         fn resolve_range(&self) -> Option {
    -        let struct_ = self.lang_items.Range?;
    +        let struct_ = if self.has_new_range_feature() {
    +            self.lang_items.RangeCopy?
    +        } else {
    +            self.lang_items.Range?
    +        };
             Some(struct_.into())
         }
     
         fn resolve_range_inclusive(&self) -> Option {
    -        let struct_ = self.lang_items.RangeInclusiveStruct?;
    +        let struct_ = if self.has_new_range_feature() {
    +            self.lang_items.RangeInclusiveCopy?
    +        } else {
    +            self.lang_items.RangeInclusiveStruct?
    +        };
             Some(struct_.into())
         }
     
         fn resolve_range_from(&self) -> Option {
    -        let struct_ = self.lang_items.RangeFrom?;
    +        let struct_ = if self.has_new_range_feature() {
    +            self.lang_items.RangeFromCopy?
    +        } else {
    +            self.lang_items.RangeFrom?
    +        };
             Some(struct_.into())
         }
     
    @@ -1836,7 +1852,11 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
         }
     
         fn resolve_range_to_inclusive(&self) -> Option {
    -        let struct_ = self.lang_items.RangeToInclusive?;
    +        let struct_ = if self.has_new_range_feature() {
    +            self.lang_items.RangeToInclusiveCopy?
    +        } else {
    +            self.lang_items.RangeToInclusive?
    +        };
             Some(struct_.into())
         }
     
    diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
    index 0b776938c5b3..8c7d29f99371 100644
    --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
    +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
    @@ -13,11 +13,11 @@ fn infer_pattern() {
                 let a = z;
                 let (c, d) = (1, "hello");
     
    -            for (e, f) in some_iter {
    +            for (e, f) in [(0, 1)] {
                     let g = e;
                 }
     
    -            if let [val] = opt {
    +            if let [val] = [y] {
                     let h = val;
                 }
     
    @@ -33,7 +33,7 @@ fn infer_pattern() {
             "#,
             expect![[r#"
                 8..9 'x': &'? i32
    -            17..400 '{     ...o_x; }': ()
    +            17..399 '{     ...o_x; }': ()
                 27..28 'y': &'? i32
                 31..32 'x': &'? i32
                 42..44 '&z': &'? i32
    @@ -47,58 +47,62 @@ fn infer_pattern() {
                 82..94 '(1, "hello")': (i32, &'? str)
                 83..84 '1': i32
                 86..93 '"hello"': &'static str
    -            101..151 'for (e...     }': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter
    -            101..151 'for (e...     }': <{unknown} as IntoIterator>::IntoIter
    -            101..151 'for (e...     }': !
    -            101..151 'for (e...     }': {unknown}
    -            101..151 'for (e...     }': &'? mut {unknown}
    -            101..151 'for (e...     }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
    -            101..151 'for (e...     }': Option<<{unknown} as Iterator>::Item>
    -            101..151 'for (e...     }': ()
    -            101..151 'for (e...     }': ()
    -            101..151 'for (e...     }': ()
    -            101..151 'for (e...     }': ()
    -            105..111 '(e, f)': ({unknown}, {unknown})
    -            106..107 'e': {unknown}
    -            109..110 'f': {unknown}
    -            115..124 'some_iter': {unknown}
    -            125..151 '{     ...     }': ()
    -            139..140 'g': {unknown}
    -            143..144 'e': {unknown}
    -            157..204 'if let...     }': ()
    -            160..175 'let [val] = opt': bool
    -            164..169 '[val]': [{unknown}]
    -            165..168 'val': {unknown}
    -            172..175 'opt': [{unknown}]
    -            176..204 '{     ...     }': ()
    -            190..191 'h': {unknown}
    -            194..197 'val': {unknown}
    -            210..236 'if let...rue {}': ()
    -            213..233 'let x ... &true': bool
    -            217..225 'x @ true': &'? bool
    -            221..225 'true': bool
    -            221..225 'true': bool
    -            228..233 '&true': &'? bool
    -            229..233 'true': bool
    -            234..236 '{}': ()
    -            246..252 'lambda': impl Fn(u64, u64, i32) -> i32
    -            255..287 '|a: u6...b; c }': impl Fn(u64, u64, i32) -> i32
    -            256..257 'a': u64
    -            264..265 'b': u64
    -            267..268 'c': i32
    -            275..287 '{ a + b; c }': i32
    -            277..278 'a': u64
    -            277..282 'a + b': u64
    -            281..282 'b': u64
    -            284..285 'c': i32
    -            298..310 'ref ref_to_x': &'? &'? i32
    -            313..314 'x': &'? i32
    -            324..333 'mut mut_x': &'? i32
    -            336..337 'x': &'? i32
    -            347..367 'ref mu...f_to_x': &'? mut &'? i32
    -            370..371 'x': &'? i32
    -            381..382 'k': &'? mut &'? i32
    -            385..397 'mut_ref_to_x': &'? mut &'? i32
    +            101..150 'for (e...     }': fn into_iter<[(i32, i32); 1]>([(i32, i32); 1]) -> <[(i32, i32); 1] as IntoIterator>::IntoIter
    +            101..150 'for (e...     }': IntoIter<(i32, i32), 1>
    +            101..150 'for (e...     }': !
    +            101..150 'for (e...     }': IntoIter<(i32, i32), 1>
    +            101..150 'for (e...     }': &'? mut IntoIter<(i32, i32), 1>
    +            101..150 'for (e...     }': fn next>(&'? mut IntoIter<(i32, i32), 1>) -> Option< as Iterator>::Item>
    +            101..150 'for (e...     }': Option<(i32, i32)>
    +            101..150 'for (e...     }': ()
    +            101..150 'for (e...     }': ()
    +            101..150 'for (e...     }': ()
    +            101..150 'for (e...     }': ()
    +            105..111 '(e, f)': (i32, i32)
    +            106..107 'e': i32
    +            109..110 'f': i32
    +            115..123 '[(0, 1)]': [(i32, i32); 1]
    +            116..122 '(0, 1)': (i32, i32)
    +            117..118 '0': i32
    +            120..121 '1': i32
    +            124..150 '{     ...     }': ()
    +            138..139 'g': i32
    +            142..143 'e': i32
    +            156..203 'if let...     }': ()
    +            159..174 'let [val] = [y]': bool
    +            163..168 '[val]': [&'? i32; 1]
    +            164..167 'val': &'? i32
    +            171..174 '[y]': [&'? i32; 1]
    +            172..173 'y': &'? i32
    +            175..203 '{     ...     }': ()
    +            189..190 'h': &'? i32
    +            193..196 'val': &'? i32
    +            209..235 'if let...rue {}': ()
    +            212..232 'let x ... &true': bool
    +            216..224 'x @ true': &'? bool
    +            220..224 'true': bool
    +            220..224 'true': bool
    +            227..232 '&true': &'? bool
    +            228..232 'true': bool
    +            233..235 '{}': ()
    +            245..251 'lambda': impl Fn(u64, u64, i32) -> i32
    +            254..286 '|a: u6...b; c }': impl Fn(u64, u64, i32) -> i32
    +            255..256 'a': u64
    +            263..264 'b': u64
    +            266..267 'c': i32
    +            274..286 '{ a + b; c }': i32
    +            276..277 'a': u64
    +            276..281 'a + b': u64
    +            280..281 'b': u64
    +            283..284 'c': i32
    +            297..309 'ref ref_to_x': &'? &'? i32
    +            312..313 'x': &'? i32
    +            323..332 'mut mut_x': &'? i32
    +            335..336 'x': &'? i32
    +            346..366 'ref mu...f_to_x': &'? mut &'? i32
    +            369..370 'x': &'? i32
    +            380..381 'k': &'? mut &'? i32
    +            384..396 'mut_ref_to_x': &'? mut &'? i32
             "#]],
         );
     }
    @@ -380,7 +384,7 @@ fn infer_pattern_match_string_literal() {
     fn infer_pattern_match_byte_string_literal() {
         check_infer_with_mismatches(
             r#"
    -        //- minicore: index
    +        //- minicore: index, range
             struct S;
             impl core::ops::Index for [T; N] {
                 type Output = [u8];
    @@ -395,7 +399,7 @@ fn infer_pattern_match_byte_string_literal() {
             "#,
             expect![[r#"
                 105..109 'self': &'? [T; N]
    -            111..116 'index': {unknown}
    +            111..116 'index': RangeFull
                 157..180 '{     ...     }': &'? [u8]
                 167..174 'loop {}': !
                 172..174 '{}': ()
    diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
    index a9a5e96f75cc..988d1dc7f242 100644
    --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
    +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
    @@ -64,20 +64,37 @@ fn type_alias_in_struct_lit() {
     
     #[test]
     fn infer_ranges() {
    -    check_types(
    +    check_no_mismatches(
             r#"
    -//- minicore: range
    -fn test() {
    -    let a = ..;
    -    let b = 1..;
    -    let c = ..2u32;
    -    let d = 1..2usize;
    -    let e = ..=10;
    -    let f = 'a'..='z';
    +//- minicore: range, new_range
     
    -    let t = (a, b, c, d, e, f);
    -    t;
    -} //^ (RangeFull, RangeFrom, RangeTo, Range, RangeToInclusive, RangeInclusive)
    +fn test() {
    +    let _: core::ops::RangeFull = ..;
    +    let _: core::ops::RangeFrom = 1..;
    +    let _: core::ops::RangeTo = ..2u32;
    +    let _: core::ops::Range = 1..2usize;
    +    let _: core::ops::RangeToInclusive = ..=10;
    +    let _: core::ops::RangeInclusive = 'a'..='z';
    +}
    +"#,
    +    );
    +}
    +
    +#[test]
    +fn infer_ranges_new_range() {
    +    check_no_mismatches(
    +        r#"
    +//- minicore: range, new_range
    +#![feature(new_range)]
    +
    +fn test() {
    +    let _: core::ops::RangeFull = ..;
    +    let _: core::range::RangeFrom = 1..;
    +    let _: core::ops::RangeTo = ..2u32;
    +    let _: core::range::Range = 1..2usize;
    +    let _: core::range::RangeToInclusive = ..=10;
    +    let _: core::range::RangeInclusive = 'a'..='z';
    +}
     "#,
         );
     }
    diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
    index 6ba7a42c1946..38e9c5b3f714 100644
    --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
    +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
    @@ -531,18 +531,12 @@ impl<'db> SourceAnalyzer<'db> {
             db: &'db dyn HirDatabase,
             range_pat: &ast::RangePat,
         ) -> Option {
    -        let path: ModPath = match (range_pat.op_kind()?, range_pat.start(), range_pat.end()) {
    -            (RangeOp::Exclusive, None, Some(_)) => path![core::ops::RangeTo],
    -            (RangeOp::Exclusive, Some(_), None) => path![core::ops::RangeFrom],
    -            (RangeOp::Exclusive, Some(_), Some(_)) => path![core::ops::Range],
    -            (RangeOp::Inclusive, None, Some(_)) => path![core::ops::RangeToInclusive],
    -            (RangeOp::Inclusive, Some(_), Some(_)) => path![core::ops::RangeInclusive],
    -
    -            (RangeOp::Exclusive, None, None) => return None,
    -            (RangeOp::Inclusive, None, None) => return None,
    -            (RangeOp::Inclusive, Some(_), None) => return None,
    -        };
    -        self.resolver.resolve_known_struct(db, &path)
    +        self.resolve_range_struct(
    +            db,
    +            range_pat.op_kind()?,
    +            range_pat.start().is_some(),
    +            range_pat.end().is_some(),
    +        )
         }
     
         pub(crate) fn resolve_range_expr(
    @@ -550,19 +544,59 @@ impl<'db> SourceAnalyzer<'db> {
             db: &'db dyn HirDatabase,
             range_expr: &ast::RangeExpr,
         ) -> Option {
    -        let path: ModPath = match (range_expr.op_kind()?, range_expr.start(), range_expr.end()) {
    -            (RangeOp::Exclusive, None, None) => path![core::ops::RangeFull],
    -            (RangeOp::Exclusive, None, Some(_)) => path![core::ops::RangeTo],
    -            (RangeOp::Exclusive, Some(_), None) => path![core::ops::RangeFrom],
    -            (RangeOp::Exclusive, Some(_), Some(_)) => path![core::ops::Range],
    -            (RangeOp::Inclusive, None, Some(_)) => path![core::ops::RangeToInclusive],
    -            (RangeOp::Inclusive, Some(_), Some(_)) => path![core::ops::RangeInclusive],
    +        self.resolve_range_struct(
    +            db,
    +            range_expr.op_kind()?,
    +            range_expr.start().is_some(),
    +            range_expr.end().is_some(),
    +        )
    +    }
     
    +    fn resolve_range_struct(
    +        &self,
    +        db: &'db dyn HirDatabase,
    +        op_kind: RangeOp,
    +        has_start: bool,
    +        has_end: bool,
    +    ) -> Option {
    +        let has_new_range =
    +            self.resolver.top_level_def_map().is_unstable_feature_enabled(&sym::new_range);
    +        let lang_items = self.lang_items(db);
    +        match (op_kind, has_start, has_end) {
    +            (RangeOp::Exclusive, false, false) => lang_items.RangeFull,
    +            (RangeOp::Exclusive, false, true) => lang_items.RangeTo,
    +            (RangeOp::Exclusive, true, false) => {
    +                if has_new_range {
    +                    lang_items.RangeFromCopy
    +                } else {
    +                    lang_items.RangeFrom
    +                }
    +            }
    +            (RangeOp::Exclusive, true, true) => {
    +                if has_new_range {
    +                    lang_items.RangeCopy
    +                } else {
    +                    lang_items.Range
    +                }
    +            }
    +            (RangeOp::Inclusive, false, true) => {
    +                if has_new_range {
    +                    lang_items.RangeToInclusiveCopy
    +                } else {
    +                    lang_items.RangeToInclusive
    +                }
    +            }
    +            (RangeOp::Inclusive, true, true) => {
    +                if has_new_range {
    +                    lang_items.RangeInclusiveCopy
    +                } else {
    +                    lang_items.RangeInclusiveStruct
    +                }
    +            }
                 // [E0586] inclusive ranges must be bounded at the end
    -            (RangeOp::Inclusive, None, None) => return None,
    -            (RangeOp::Inclusive, Some(_), None) => return None,
    -        };
    -        self.resolver.resolve_known_struct(db, &path)
    +            (RangeOp::Inclusive, false, false) => None,
    +            (RangeOp::Inclusive, true, false) => None,
    +        }
         }
     
         pub(crate) fn resolve_await_to_poll(
    diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
    index 781e58a1204e..513f51faba7f 100644
    --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
    +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
    @@ -525,6 +525,12 @@ define_symbols! {
         arbitrary_self_types,
         arbitrary_self_types_pointers,
         supertrait_item_shadowing,
    +    new_range,
    +    range,
    +    RangeCopy,
    +    RangeFromCopy,
    +    RangeInclusiveCopy,
    +    RangeToInclusiveCopy,
         hash,
         partial_cmp,
         cmp,
    diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
    index c3429356d9e5..26e125f8f2d6 100644
    --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
    +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
    @@ -58,6 +58,7 @@
     //!     pin:
     //!     pointee: copy, send, sync, ord, hash, unpin, phantom_data
     //!     range:
    +//!     new_range:
     //!     receiver: deref
     //!     result:
     //!     send: sized
    @@ -175,7 +176,9 @@ pub mod marker {
     
         // region:clone
         impl Clone for PhantomData {
    -        fn clone(&self) -> Self { Self }
    +        fn clone(&self) -> Self {
    +            Self
    +        }
         }
         // endregion:clone
     
    @@ -1128,6 +1131,32 @@ pub mod ops {
         // endregion:dispatch_from_dyn
     }
     
    +// region:new_range
    +pub mod range {
    +    #[lang = "RangeCopy"]
    +    pub struct Range {
    +        pub start: Idx,
    +        pub end: Idx,
    +    }
    +
    +    #[lang = "RangeFromCopy"]
    +    pub struct RangeFrom {
    +        pub start: Idx,
    +    }
    +
    +    #[lang = "RangeInclusiveCopy"]
    +    pub struct RangeInclusive {
    +        pub start: Idx,
    +        pub end: Idx,
    +    }
    +
    +    #[lang = "RangeToInclusiveCopy"]
    +    pub struct RangeToInclusive {
    +        pub end: Idx,
    +    }
    +}
    +// endregion:new_range
    +
     // region:eq
     pub mod cmp {
         use crate::marker::PointeeSized;
    @@ -1144,7 +1173,9 @@ pub mod cmp {
     
         // region:builtin_impls
         impl PartialEq for () {
    -        fn eq(&self, other: &()) -> bool { true }
    +        fn eq(&self, other: &()) -> bool {
    +            true
    +        }
         }
         // endregion:builtin_impls
     
    @@ -1567,10 +1598,7 @@ pub mod pin {
         }
         // endregion:dispatch_from_dyn
         // region:coerce_unsized
    -    impl crate::ops::CoerceUnsized> for Pin where
    -        Ptr: crate::ops::CoerceUnsized
    -    {
    -    }
    +    impl crate::ops::CoerceUnsized> for Pin where Ptr: crate::ops::CoerceUnsized {}
         // endregion:coerce_unsized
     }
     // endregion:pin
    @@ -1792,9 +1820,9 @@ pub mod iter {
                     fn from_iter>(iter: T) -> Self;
                 }
             }
    -        pub use self::collect::{IntoIterator, FromIterator};
    +        pub use self::collect::{FromIterator, IntoIterator};
         }
    -    pub use self::traits::{IntoIterator, FromIterator, Iterator};
    +    pub use self::traits::{FromIterator, IntoIterator, Iterator};
     }
     // endregion:iterator
     
    @@ -2087,30 +2115,30 @@ macro_rules! column {
     pub mod prelude {
         pub mod v1 {
             pub use crate::{
    -            clone::Clone,                            // :clone
    -            cmp::{Eq, PartialEq},                    // :eq
    -            cmp::{Ord, PartialOrd},                  // :ord
    -            convert::AsMut,                          // :as_mut
    -            convert::AsRef,                          // :as_ref
    -            convert::{From, Into, TryFrom, TryInto}, // :from
    -            default::Default,                        // :default
    -            iter::{IntoIterator, Iterator, FromIterator}, // :iterator
    -            macros::builtin::{derive, derive_const}, // :derive
    -            marker::Copy,                            // :copy
    -            marker::Send,                            // :send
    -            marker::Sized,                           // :sized
    -            marker::Sync,                            // :sync
    -            mem::drop,                               // :drop
    -            mem::size_of,                            // :size_of
    -            ops::Drop,                               // :drop
    -            ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}, // :async_fn
    -            ops::{Fn, FnMut, FnOnce},                // :fn
    -            option::Option::{self, None, Some},      // :option
    -            panic,                                   // :panic
    -            result::Result::{self, Err, Ok},         // :result
    -            str::FromStr,                            // :str
    -            fmt::derive::Debug,                      // :fmt, derive
    -            hash::derive::Hash,                      // :hash, derive
    +            clone::Clone,                                 // :clone
    +            cmp::{Eq, PartialEq},                         // :eq
    +            cmp::{Ord, PartialOrd},                       // :ord
    +            convert::AsMut,                               // :as_mut
    +            convert::AsRef,                               // :as_ref
    +            convert::{From, Into, TryFrom, TryInto},      // :from
    +            default::Default,                             // :default
    +            fmt::derive::Debug,                           // :fmt, derive
    +            hash::derive::Hash,                           // :hash, derive
    +            iter::{FromIterator, IntoIterator, Iterator}, // :iterator
    +            macros::builtin::{derive, derive_const},      // :derive
    +            marker::Copy,                                 // :copy
    +            marker::Send,                                 // :send
    +            marker::Sized,                                // :sized
    +            marker::Sync,                                 // :sync
    +            mem::drop,                                    // :drop
    +            mem::size_of,                                 // :size_of
    +            ops::Drop,                                    // :drop
    +            ops::{AsyncFn, AsyncFnMut, AsyncFnOnce},      // :async_fn
    +            ops::{Fn, FnMut, FnOnce},                     // :fn
    +            option::Option::{self, None, Some},           // :option
    +            panic,                                        // :panic
    +            result::Result::{self, Err, Ok},              // :result
    +            str::FromStr,                                 // :str
             };
         }
     
    
    From a1e2cea685fca526ad36667cb9f188127c6438eb Mon Sep 17 00:00:00 2001
    From: mejrs <59372212+mejrs@users.noreply.github.com>
    Date: Tue, 13 Jan 2026 16:29:02 +0100
    Subject: [PATCH 2092/3801] Port `do_not_recommend` to new attr parsing
    
    ---
     .../src/attributes/do_not_recommend.rs        | 31 +++++++++++++++++
     .../rustc_attr_parsing/src/attributes/mod.rs  |  1 +
     compiler/rustc_attr_parsing/src/context.rs    |  2 ++
     .../rustc_hir/src/attrs/data_structures.rs    |  3 ++
     .../rustc_hir/src/attrs/encode_cross_crate.rs |  1 +
     compiler/rustc_lint/messages.ftl              |  3 ++
     compiler/rustc_lint/src/early/diagnostics.rs  |  4 +++
     compiler/rustc_lint/src/lints.rs              |  4 +++
     compiler/rustc_lint_defs/src/lib.rs           |  1 +
     compiler/rustc_middle/src/ty/context.rs       |  2 +-
     compiler/rustc_middle/src/ty/mod.rs           | 33 +------------------
     compiler/rustc_passes/messages.ftl            |  3 --
     compiler/rustc_passes/src/check_attr.rs       | 20 +++--------
     compiler/rustc_passes/src/errors.rs           |  4 ---
     .../src/solve/fulfill/derive_errors.rs        |  2 +-
     tests/ui/attributes/malformed-attrs.stderr    | 15 ++++-----
     tests/ui/unpretty/diagnostic-attr.stdout      |  2 +-
     17 files changed, 65 insertions(+), 66 deletions(-)
     create mode 100644 compiler/rustc_attr_parsing/src/attributes/do_not_recommend.rs
    
    diff --git a/compiler/rustc_attr_parsing/src/attributes/do_not_recommend.rs b/compiler/rustc_attr_parsing/src/attributes/do_not_recommend.rs
    new file mode 100644
    index 000000000000..4a89cf6515ce
    --- /dev/null
    +++ b/compiler/rustc_attr_parsing/src/attributes/do_not_recommend.rs
    @@ -0,0 +1,31 @@
    +use rustc_feature::{AttributeTemplate, template};
    +use rustc_hir::attrs::AttributeKind;
    +use rustc_hir::lints::AttributeLintKind;
    +use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
    +use rustc_span::{Symbol, sym};
    +
    +use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
    +use crate::context::{AcceptContext, Stage};
    +use crate::parser::ArgParser;
    +use crate::target_checking::{ALL_TARGETS, AllowedTargets};
    +
    +pub(crate) struct DoNotRecommendParser;
    +impl SingleAttributeParser for DoNotRecommendParser {
    +    const PATH: &[Symbol] = &[sym::diagnostic, sym::do_not_recommend];
    +    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
    +    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
    +    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Checked in check_attr.
    +    const TEMPLATE: AttributeTemplate = template!(Word /*doesn't matter */);
    +
    +    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option {
    +        let attr_span = cx.attr_span;
    +        if !matches!(args, ArgParser::NoArgs) {
    +            cx.emit_lint(
    +                MALFORMED_DIAGNOSTIC_ATTRIBUTES,
    +                AttributeLintKind::DoNotRecommendDoesNotExpectArgs,
    +                attr_span,
    +            );
    +        }
    +        Some(AttributeKind::DoNotRecommend { attr_span })
    +    }
    +}
    diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
    index e02d71a26158..3da27f077a61 100644
    --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
    +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
    @@ -39,6 +39,7 @@ pub(crate) mod confusables;
     pub(crate) mod crate_level;
     pub(crate) mod debugger;
     pub(crate) mod deprecation;
    +pub(crate) mod do_not_recommend;
     pub(crate) mod doc;
     pub(crate) mod dummy;
     pub(crate) mod inline;
    diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
    index 6b1b1d484283..a207af57ccca 100644
    --- a/compiler/rustc_attr_parsing/src/context.rs
    +++ b/compiler/rustc_attr_parsing/src/context.rs
    @@ -34,6 +34,7 @@ use crate::attributes::crate_level::{
     };
     use crate::attributes::debugger::DebuggerViualizerParser;
     use crate::attributes::deprecation::DeprecationParser;
    +use crate::attributes::do_not_recommend::DoNotRecommendParser;
     use crate::attributes::doc::DocParser;
     use crate::attributes::dummy::DummyParser;
     use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
    @@ -197,6 +198,7 @@ attribute_parsers!(
             Single,
             Single,
             Single,
    +        Single,
             Single,
             Single,
             Single,
    diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
    index 8d18d335b355..16bee3d53297 100644
    --- a/compiler/rustc_hir/src/attrs/data_structures.rs
    +++ b/compiler/rustc_hir/src/attrs/data_structures.rs
    @@ -731,6 +731,9 @@ pub enum AttributeKind {
         /// Represents `#[rustc_do_not_implement_via_object]`.
         DoNotImplementViaObject(Span),
     
    +    /// Represents `#[diagnostic::do_not_recommend]`.
    +    DoNotRecommend { attr_span: Span },
    +
         /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html).
         /// Represents all other uses of the [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html)
         /// attribute.
    diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    index 33655f4f0063..7cdcdc3a5e94 100644
    --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
    @@ -44,6 +44,7 @@ impl AttributeKind {
                 DenyExplicitImpl(..) => No,
                 Deprecation { .. } => Yes,
                 DoNotImplementViaObject(..) => No,
    +            DoNotRecommend { .. } => Yes,
                 Doc(_) => Yes,
                 DocComment { .. } => Yes,
                 Dummy => No,
    diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
    index 9b0b1abc91df..f5b882494863 100644
    --- a/compiler/rustc_lint/messages.ftl
    +++ b/compiler/rustc_lint/messages.ftl
    @@ -480,6 +480,9 @@ lint_improper_ctypes_unsafe_binder = unsafe binders are incompatible with foreig
     lint_improper_gpu_kernel_arg = passing type `{$ty}` to a function with "gpu-kernel" ABI may have unexpected behavior
         .help = use primitive types and raw pointers to get reliable behavior
     
    +lint_incorrect_do_not_recommend_args =
    +    `#[diagnostic::do_not_recommend]` does not expect any arguments
    +
     lint_int_to_ptr_transmutes = transmuting an integer to a pointer creates a pointer without provenance
         .note = this is dangerous because dereferencing the resulting pointer is undefined behavior
         .note_exposed_provenance = exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
    diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs
    index 5745f0d4edde..037a31c162d2 100644
    --- a/compiler/rustc_lint/src/early/diagnostics.rs
    +++ b/compiler/rustc_lint/src/early/diagnostics.rs
    @@ -419,5 +419,9 @@ pub fn decorate_attribute_lint(
             &AttributeLintKind::DocTestLiteral => lints::DocTestLiteral.decorate_lint(diag),
     
             &AttributeLintKind::AttrCrateLevelOnly => lints::AttrCrateLevelOnly.decorate_lint(diag),
    +
    +        &AttributeLintKind::DoNotRecommendDoesNotExpectArgs => {
    +            lints::DoNotRecommendDoesNotExpectArgs.decorate_lint(diag)
    +        }
         }
     }
    diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
    index 33e9375ec71b..c85e4ffe91fc 100644
    --- a/compiler/rustc_lint/src/lints.rs
    +++ b/compiler/rustc_lint/src/lints.rs
    @@ -3317,3 +3317,7 @@ pub(crate) struct DocTestLiteral;
     #[diag(lint_attr_crate_level)]
     #[note]
     pub(crate) struct AttrCrateLevelOnly;
    +
    +#[derive(LintDiagnostic)]
    +#[diag(lint_incorrect_do_not_recommend_args)]
    +pub(crate) struct DoNotRecommendDoesNotExpectArgs;
    diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
    index c8713b23633f..4d0c44f16760 100644
    --- a/compiler/rustc_lint_defs/src/lib.rs
    +++ b/compiler/rustc_lint_defs/src/lib.rs
    @@ -821,6 +821,7 @@ pub enum AttributeLintKind {
         },
         DocTestLiteral,
         AttrCrateLevelOnly,
    +    DoNotRecommendDoesNotExpectArgs,
     }
     
     pub type RegisteredTools = FxIndexSet;
    diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
    index a3eec72214c0..e9fa3f14358e 100644
    --- a/compiler/rustc_middle/src/ty/context.rs
    +++ b/compiler/rustc_middle/src/ty/context.rs
    @@ -3540,7 +3540,7 @@ impl<'tcx> TyCtxt<'tcx> {
     
         /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
         pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
    -        self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
    +        find_attr!(self.get_all_attrs(def_id), AttributeKind::DoNotRecommend { .. })
         }
     
         pub fn is_trivial_const

    (self, def_id: P) -> bool diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e2a94b607de1..8eee114ead02 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -51,7 +51,7 @@ use rustc_query_system::ich::StableHashingContext; use rustc_serialize::{Decodable, Encodable}; pub use rustc_session::lint::RegisteredTools; use rustc_span::hygiene::MacroKind; -use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol}; pub use rustc_type_ir::data_structures::{DelayedMap, DelayedSet}; pub use rustc_type_ir::fast_reject::DeepRejectCtxt; #[allow( @@ -1819,37 +1819,6 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// Get an attribute from the diagnostic attribute namespace - /// - /// This function requests an attribute with the following structure: - /// - /// `#[diagnostic::$attr]` - /// - /// This function performs feature checking, so if an attribute is returned - /// it can be used by the consumer - pub fn get_diagnostic_attr( - self, - did: impl Into, - attr: Symbol, - ) -> Option<&'tcx hir::Attribute> { - let did: DefId = did.into(); - if did.as_local().is_some() { - // it's a crate local item, we need to check feature flags - if rustc_feature::is_stable_diagnostic_attribute(attr, self.features()) { - self.get_attrs_by_path(did, &[sym::diagnostic, sym::do_not_recommend]).next() - } else { - None - } - } else { - // we filter out unstable diagnostic attributes before - // encoding attributes - debug_assert!(rustc_feature::encode_cross_crate(attr)); - self.attrs_for_def(did) - .iter() - .find(|a| matches!(a.path().as_ref(), [sym::diagnostic, a] if *a == attr)) - } - } - pub fn get_attrs_by_path( self, did: DefId, diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 11e4b8b20222..51c439b4243c 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -246,9 +246,6 @@ passes_implied_feature_not_exist = passes_incorrect_crate_type = lang items are not allowed in stable dylibs -passes_incorrect_do_not_recommend_args = - `#[diagnostic::do_not_recommend]` does not expect any arguments - passes_incorrect_do_not_recommend_location = `#[diagnostic::do_not_recommend]` can only be placed on trait implementations diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8f80822a81ab..3402b9744b3c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -43,8 +43,8 @@ use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; use rustc_session::lint; use rustc_session::lint::builtin::{ - CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_ATTRIBUTES, - MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES, + CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES, + UNUSED_ATTRIBUTES, }; use rustc_session::parse::feature_err; use rustc_span::edition::Edition; @@ -223,6 +223,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::RustcMustImplementOneOf { attr_span, fn_names }) => { self.check_rustc_must_implement_one_of(*attr_span, fn_names, hir_id,target) }, + Attribute::Parsed(AttributeKind::DoNotRecommend{attr_span}) => {self.check_do_not_recommend(*attr_span, hir_id, target, item)}, Attribute::Parsed( AttributeKind::EiiDeclaration { .. } | AttributeKind::EiiForeignItem @@ -313,9 +314,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); match attr.path().as_slice() { - [sym::diagnostic, sym::do_not_recommend, ..] => { - self.check_do_not_recommend(attr.span(), hir_id, target, attr, item) - } [sym::diagnostic, sym::on_unimplemented, ..] => { self.check_diagnostic_on_unimplemented(attr.span(), hir_id, target) } @@ -568,14 +566,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl and that it has no - /// arguments. + /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl fn check_do_not_recommend( &self, attr_span: Span, hir_id: HirId, target: Target, - attr: &Attribute, item: Option>, ) { if !matches!(target, Target::Impl { .. }) @@ -592,14 +588,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { errors::IncorrectDoNotRecommendLocation, ); } - if !attr.is_word() { - self.tcx.emit_node_span_lint( - MALFORMED_DIAGNOSTIC_ATTRIBUTES, - hir_id, - attr_span, - errors::DoNotRecommendDoesNotExpectArgs, - ); - } } /// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 1f3f0d7f8884..bf9b615546d8 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -20,10 +20,6 @@ use crate::lang_items::Duplicate; #[diag(passes_incorrect_do_not_recommend_location)] pub(crate) struct IncorrectDoNotRecommendLocation; -#[derive(LintDiagnostic)] -#[diag(passes_incorrect_do_not_recommend_args)] -pub(crate) struct DoNotRecommendDoesNotExpectArgs; - #[derive(Diagnostic)] #[diag(passes_autodiff_attr)] pub(crate) struct AutoDiffAttr { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index eef8b870a5b8..77834320dbc6 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -434,7 +434,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { } = candidate.kind() && tcx.do_not_recommend_impl(impl_def_id) { - trace!("#[do_not_recommend] -> exit"); + trace!("#[diagnostic::do_not_recommend] -> exit"); return ControlFlow::Break(self.obligation.clone()); } diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index fc644668735e..04f51f54b2cd 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -729,14 +729,6 @@ help: use `#[rustc_align(...)]` instead LL | #[repr] | ^^^^^^^ -warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:155:1 - | -LL | #[diagnostic::do_not_recommend()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default - warning: missing options for `on_unimplemented` attribute --> $DIR/malformed-attrs.rs:144:1 | @@ -744,6 +736,7 @@ LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: at least one of the `message`, `note` and `label` options are expected + = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: malformed `on_unimplemented` attribute --> $DIR/malformed-attrs.rs:146:1 @@ -823,6 +816,12 @@ LL | #[no_implicit_prelude = 23] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[no_implicit_prelude]` can be applied to crates and modules +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/malformed-attrs.rs:155:1 + | +LL | #[diagnostic::do_not_recommend()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + warning: `#[automatically_derived]` attribute cannot be used on modules --> $DIR/malformed-attrs.rs:196:1 | diff --git a/tests/ui/unpretty/diagnostic-attr.stdout b/tests/ui/unpretty/diagnostic-attr.stdout index 4822cf4700b9..f74637fa7efe 100644 --- a/tests/ui/unpretty/diagnostic-attr.stdout +++ b/tests/ui/unpretty/diagnostic-attr.stdout @@ -11,5 +11,5 @@ use ::std::prelude::rust_2015::*; "My Label", note = "Note 1", note = "Note 2")] trait ImportantTrait { } -#[diagnostic::do_not_recommend] +#[attr = DoNotRecommend] impl ImportantTrait for T where T: Clone { } From ed6e63092c4f1303b127e10f5d5e300e59e9dbfa Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Tue, 13 Jan 2026 16:29:12 +0100 Subject: [PATCH 2093/3801] Keep allowing invalid metaitem syntax in diagnostic attributes --- compiler/rustc_attr_parsing/src/parser.rs | 5 +++-- .../does_not_acccept_args.current.stderr | 14 ++++++++++---- .../does_not_acccept_args.next.stderr | 14 ++++++++++---- .../do_not_recommend/does_not_acccept_args.rs | 5 +++++ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 68265649d182..72b0fc63cc15 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -113,8 +113,9 @@ impl ArgParser { Some(match value { AttrArgs::Empty => Self::NoArgs, AttrArgs::Delimited(args) => { - // The arguments of rustc_dummy are not validated if the arguments are delimited - if parts == &[sym::rustc_dummy] { + // The arguments of rustc_dummy and diagnostic attributes are not validated + // if the arguments are delimited + if parts == &[sym::rustc_dummy] || parts[0] == sym::diagnostic { return Some(ArgParser::List(MetaItemListParser { sub_parsers: ThinVec::new(), span: args.dspan.entire(), diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr index 2af24130a1e5..43205bd395fc 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:11:1 + --> $DIR/does_not_acccept_args.rs:12:1 | LL | #[diagnostic::do_not_recommend(not_accepted)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,16 +7,22 @@ LL | #[diagnostic::do_not_recommend(not_accepted)] = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:15:1 + --> $DIR/does_not_acccept_args.rs:16:1 | LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:19:1 + --> $DIR/does_not_acccept_args.rs:20:1 | LL | #[diagnostic::do_not_recommend(not_accepted(42))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 3 warnings emitted +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:24:1 + | +LL | #[diagnostic::do_not_recommend(x = y + z)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr index 2af24130a1e5..43205bd395fc 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:11:1 + --> $DIR/does_not_acccept_args.rs:12:1 | LL | #[diagnostic::do_not_recommend(not_accepted)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,16 +7,22 @@ LL | #[diagnostic::do_not_recommend(not_accepted)] = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:15:1 + --> $DIR/does_not_acccept_args.rs:16:1 | LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:19:1 + --> $DIR/does_not_acccept_args.rs:20:1 | LL | #[diagnostic::do_not_recommend(not_accepted(42))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 3 warnings emitted +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:24:1 + | +LL | #[diagnostic::do_not_recommend(x = y + z)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs index 5c21c045e10a..918bf5a0113e 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs @@ -7,6 +7,7 @@ trait Foo {} trait Bar {} trait Baz {} +trait Boo {} #[diagnostic::do_not_recommend(not_accepted)] //~^ WARNING `#[diagnostic::do_not_recommend]` does not expect any arguments @@ -20,4 +21,8 @@ impl Bar for T where T: Send {} //~^ WARNING `#[diagnostic::do_not_recommend]` does not expect any arguments impl Baz for T where T: Send {} +#[diagnostic::do_not_recommend(x = y + z)] +//~^ WARNING `#[diagnostic::do_not_recommend]` does not expect any arguments +impl Boo for T where T: Send {} + fn main() {} From 1fe705ca709cd81d3ce8735e992cd4333c1404fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Jan 2026 16:59:03 +0000 Subject: [PATCH 2094/3801] Mention the type in the label, to avoid confusion at the cost of redundancy --- library/core/src/iter/range.rs | 2 +- .../run-make/missing-unstable-trait-bound/missing-bound.stderr | 2 +- tests/ui/range/range-1.stderr | 2 +- tests/ui/trait-bounds/unstable-trait-suggestion.stderr | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 7880e18d7d31..a6ab2e4d8b7d 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -23,7 +23,7 @@ unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u6 #[rustc_diagnostic_item = "range_step"] #[rustc_on_unimplemented( message = "`std::ops::Range<{Self}>` is not an iterator", - label = "not an iterator", + label = "`Range<{Self}>` is not an iterator", note = "`Range` only implements `Iterator` for select types in the standard library, \ particularly integers; to see the full list of types, see the documentation for the \ unstable `Step` trait" diff --git a/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr b/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr index d503751a2e93..d680ae1aca1d 100644 --- a/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr +++ b/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr @@ -2,7 +2,7 @@ error[E0277]: `std::ops::Range` is not an iterator --> missing-bound.rs:2:14 | 2 | for _ in t {} - | ^ not an iterator + | ^ `Range` is not an iterator | = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait = note: required for `std::ops::Range` to implement `Iterator` diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr index 9682122539c5..d7d0f87ac991 100644 --- a/tests/ui/range/range-1.stderr +++ b/tests/ui/range/range-1.stderr @@ -8,7 +8,7 @@ error[E0277]: `std::ops::Range` is not an iterator --> $DIR/range-1.rs:9:14 | LL | for i in false..true {} - | ^^^^^^^^^^^ not an iterator + | ^^^^^^^^^^^ `Range` is not an iterator | = help: the nightly-only, unstable trait `Step` is not implemented for `bool` = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait diff --git a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr index 5edaed0f4dfe..9ae209d5aa96 100644 --- a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr +++ b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr @@ -20,7 +20,7 @@ error[E0277]: `std::ops::Range` is not an iterator --> $DIR/unstable-trait-suggestion.rs:17:14 | LL | for _ in t {} - | ^ not an iterator + | ^ `Range` is not an iterator | = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait = note: required for `std::ops::Range` to implement `Iterator` From 596ea17eae592b68a16a7661bf26c10a5155da89 Mon Sep 17 00:00:00 2001 From: rami3l Date: Tue, 13 Jan 2026 21:05:44 +0100 Subject: [PATCH 2095/3801] fix(build-manifest): enable docs target fallback for `rustc-docs` --- src/tools/build-manifest/src/main.rs | 12 ++++++------ src/tools/build-manifest/src/versions.rs | 5 +---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 4cec1b1f164b..58f7487a0fda 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -14,11 +14,11 @@ use crate::versions::{PkgType, Versions}; include!(concat!(env!("OUT_DIR"), "/targets.rs")); -/// This allows the manifest to contain rust-docs for hosts that don't build -/// docs. +/// This allows the manifest to contain rust-docs and rustc-docs for hosts +/// that don't build certain docs. /// /// Tuples of `(host_partial, host_instead)`. If the host does not have the -/// rust-docs component available, then if the host name contains +/// corresponding docs component available, then if the host name contains /// `host_partial`, it will use the docs from `host_instead` instead. /// /// The order here matters, more specific entries should be first. @@ -392,9 +392,9 @@ impl Builder { let t = Target::from_compressed_tar(self, &tarball_name!(fallback_target)); // Fallbacks should typically be available on 'production' builds // but may not be available for try builds, which only build one target by - // default. Ideally we'd gate this being a hard error on whether we're in a - // production build or not, but it's not information that's readily available - // here. + // default. It is also possible that `rust-docs` and `rustc-docs` differ in + // availability per target. Thus, we take the first available fallback we can + // find. if !t.available { eprintln!( "{:?} not available for fallback", diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 6ef8a0e83de3..da887a66d98e 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -133,10 +133,7 @@ impl PkgType { /// Whether to package these target-specific docs for another similar target. pub(crate) fn use_docs_fallback(&self) -> bool { - match self { - PkgType::JsonDocs | PkgType::HtmlDocs => true, - _ => false, - } + matches!(self, PkgType::JsonDocs | PkgType::HtmlDocs | PkgType::RustcDocs) } } From 6948a66ad81e149d8a0af5dcc0888b9a44f3d2b4 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Wed, 14 Jan 2026 05:40:27 +0900 Subject: [PATCH 2096/3801] fix: Sync cast checks to rustc again --- .../crates/hir-ty/src/infer/cast.rs | 270 +++++++++++++----- .../crates/hir-ty/src/infer/unify.rs | 10 - .../src/handlers/invalid_cast.rs | 10 +- 3 files changed, 201 insertions(+), 89 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs index d073b06ccc8a..d69b00adb7f7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs @@ -2,8 +2,10 @@ use hir_def::{AdtId, hir::ExprId, signatures::TraitFlags}; use rustc_ast_ir::Mutability; +use rustc_hash::FxHashSet; use rustc_type_ir::{ - Flags, InferTy, TypeFlags, UintTy, + InferTy, TypeVisitableExt, UintTy, elaborate, + error::TypeError, inherent::{AdtDef, BoundExistentialPredicates as _, IntoKind, Ty as _}, }; use stdx::never; @@ -12,7 +14,10 @@ use crate::{ InferenceDiagnostic, db::HirDatabase, infer::{AllowTwoPhase, InferenceContext, expr::ExprIsRead}, - next_solver::{BoundExistentialPredicates, DbInterner, ParamTy, Ty, TyKind}, + next_solver::{ + BoundExistentialPredicates, ExistentialPredicate, ParamTy, Region, Ty, TyKind, + infer::traits::ObligationCause, + }, }; #[derive(Debug)] @@ -66,12 +71,13 @@ pub enum CastError { DifferingKinds, SizedUnsizedCast, IllegalCast, - IntToFatCast, + IntToWideCast, NeedDeref, NeedViaPtr, NeedViaThinPtr, NeedViaInt, NonScalar, + PtrPtrAddingAutoTraits, // We don't want to report errors with unknown types currently. // UnknownCastPtrKind, // UnknownExprPtrKind, @@ -137,22 +143,13 @@ impl<'db> CastCheck<'db> { return Ok(()); } - if !self.cast_ty.flags().contains(TypeFlags::HAS_TY_INFER) - && !ctx.table.is_sized(self.cast_ty) - { + if !self.cast_ty.has_infer_types() && !ctx.table.is_sized(self.cast_ty) { return Err(InferenceDiagnostic::CastToUnsized { expr: self.expr, cast_ty: self.cast_ty.store(), }); } - // Chalk doesn't support trait upcasting and fails to solve some obvious goals - // when the trait environment contains some recursive traits (See issue #18047) - // We skip cast checks for such cases for now, until the next-gen solver. - if contains_dyn_trait(self.cast_ty) { - return Ok(()); - } - self.do_check(ctx).map_err(|e| e.into_diagnostic(self.expr, self.expr_ty, self.cast_ty)) } @@ -162,22 +159,23 @@ impl<'db> CastCheck<'db> { (Some(t_from), Some(t_cast)) => (t_from, t_cast), (None, Some(t_cast)) => match self.expr_ty.kind() { TyKind::FnDef(..) => { - let sig = - self.expr_ty.callable_sig(ctx.interner()).expect("FnDef had no sig"); - let sig = ctx.table.normalize_associated_types_in(sig); + // rustc calls `FnCtxt::normalize` on this but it's a no-op in next-solver + let sig = self.expr_ty.fn_sig(ctx.interner()); let fn_ptr = Ty::new_fn_ptr(ctx.interner(), sig); - if ctx - .coerce( - self.source_expr.into(), - self.expr_ty, - fn_ptr, - AllowTwoPhase::No, - ExprIsRead::Yes, - ) - .is_ok() - { - } else { - return Err(CastError::IllegalCast); + match ctx.coerce( + self.source_expr.into(), + self.expr_ty, + fn_ptr, + AllowTwoPhase::No, + ExprIsRead::Yes, + ) { + Ok(_) => {} + Err(TypeError::IntrinsicCast) => { + return Err(CastError::IllegalCast); + } + Err(_) => { + return Err(CastError::NonScalar); + } } (CastTy::FnPtr, t_cast) @@ -213,23 +211,41 @@ impl<'db> CastCheck<'db> { // rustc checks whether the `expr_ty` is foreign adt with `non_exhaustive` sym match (t_from, t_cast) { + // These types have invariants! can't cast into them. (_, CastTy::Int(Int::CEnum) | CastTy::FnPtr) => Err(CastError::NonScalar), + + // * -> Bool (_, CastTy::Int(Int::Bool)) => Err(CastError::CastToBool), - (CastTy::Int(Int::U(UintTy::U8)), CastTy::Int(Int::Char)) => Ok(()), + + // * -> Char + (CastTy::Int(Int::U(UintTy::U8)), CastTy::Int(Int::Char)) => Ok(()), // u8-char-cast (_, CastTy::Int(Int::Char)) => Err(CastError::CastToChar), + + // prim -> float,ptr (CastTy::Int(Int::Bool | Int::CEnum | Int::Char), CastTy::Float) => { Err(CastError::NeedViaInt) } + (CastTy::Int(Int::Bool | Int::CEnum | Int::Char) | CastTy::Float, CastTy::Ptr(..)) | (CastTy::Ptr(..) | CastTy::FnPtr, CastTy::Float) => Err(CastError::IllegalCast), - (CastTy::Ptr(src, _), CastTy::Ptr(dst, _)) => self.check_ptr_ptr_cast(ctx, src, dst), + + // ptr -> ptr + (CastTy::Ptr(src, _), CastTy::Ptr(dst, _)) => self.check_ptr_ptr_cast(ctx, src, dst), // ptr-ptr-cast + + // // ptr-addr-cast (CastTy::Ptr(src, _), CastTy::Int(_)) => self.check_ptr_addr_cast(ctx, src), + (CastTy::FnPtr, CastTy::Int(_)) => Ok(()), + + // addr-ptr-cast (CastTy::Int(_), CastTy::Ptr(dst, _)) => self.check_addr_ptr_cast(ctx, dst), + + // fn-ptr-cast (CastTy::FnPtr, CastTy::Ptr(dst, _)) => self.check_fptr_ptr_cast(ctx, dst), + + // prim -> prim (CastTy::Int(Int::CEnum), CastTy::Int(_)) => Ok(()), (CastTy::Int(Int::Char | Int::Bool), CastTy::Int(_)) => Ok(()), (CastTy::Int(_) | CastTy::Float, CastTy::Int(_) | CastTy::Float) => Ok(()), - (CastTy::FnPtr, CastTy::Int(_)) => Ok(()), } } @@ -241,10 +257,16 @@ impl<'db> CastCheck<'db> { t_cast: Ty<'db>, m_cast: Mutability, ) -> Result<(), CastError> { - // Mutability order is opposite to rustc. `Mut < Not` - if m_expr <= m_cast + let t_expr = ctx.table.try_structurally_resolve_type(t_expr); + let t_cast = ctx.table.try_structurally_resolve_type(t_cast); + + if m_expr >= m_cast && let TyKind::Array(ety, _) = t_expr.kind() + && ctx.infcx().can_eq(ctx.table.param_env, ety, t_cast) { + // Due to historical reasons we allow directly casting references of + // arrays into raw pointers of their element type. + // Coerce to a raw pointer so that we generate RawPtr in MIR. let array_ptr_type = Ty::new_ptr(ctx.interner(), t_expr, m_expr); if ctx @@ -265,14 +287,9 @@ impl<'db> CastCheck<'db> { ); } - // This is a less strict condition than rustc's `demand_eqtype`, - // but false negative is better than false positive - if ctx - .coerce(self.source_expr.into(), ety, t_cast, AllowTwoPhase::No, ExprIsRead::Yes) - .is_ok() - { - return Ok(()); - } + // this will report a type mismatch if needed + let _ = ctx.demand_eqtype(self.expr.into(), ety, t_cast); + return Ok(()); } Err(CastError::IllegalCast) @@ -289,30 +306,147 @@ impl<'db> CastCheck<'db> { match (src_kind, dst_kind) { (Some(PointerKind::Error), _) | (_, Some(PointerKind::Error)) => Ok(()), + // (_, None) => Err(CastError::UnknownCastPtrKind), // (None, _) => Err(CastError::UnknownExprPtrKind), (_, None) | (None, _) => Ok(()), + + // Cast to thin pointer is OK (_, Some(PointerKind::Thin)) => Ok(()), + + // thin -> fat? report invalid cast (don't complain about vtable kinds) (Some(PointerKind::Thin), _) => Err(CastError::SizedUnsizedCast), + + // trait object -> trait object? need to do additional checks (Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => { match (src_tty.principal_def_id(), dst_tty.principal_def_id()) { + // A + SrcAuto> -> B + DstAuto>. need to make sure + // - `Src` and `Dst` traits are the same + // - traits have the same generic arguments + // - projections are the same + // - `SrcAuto` (+auto traits implied by `Src`) is a superset of `DstAuto` + // + // Note that trait upcasting goes through a different mechanism (`coerce_unsized`) + // and is unaffected by this check. (Some(src_principal), Some(dst_principal)) => { if src_principal == dst_principal { return Ok(()); } - let src_principal = ctx.db.trait_signature(src_principal.0); - let dst_principal = ctx.db.trait_signature(dst_principal.0); - if src_principal.flags.contains(TraitFlags::AUTO) - && dst_principal.flags.contains(TraitFlags::AUTO) + + // We need to reconstruct trait object types. + // `m_src` and `m_dst` won't work for us here because they will potentially + // contain wrappers, which we do not care about. + // + // e.g. we want to allow `dyn T -> (dyn T,)`, etc. + // + // We also need to skip auto traits to emit an FCW and not an error. + let src_obj = Ty::new_dynamic( + ctx.interner(), + BoundExistentialPredicates::new_from_iter( + ctx.interner(), + src_tty.iter().filter(|pred| { + !matches!( + pred.skip_binder(), + ExistentialPredicate::AutoTrait(_) + ) + }), + ), + Region::new_erased(ctx.interner()), + ); + let dst_obj = Ty::new_dynamic( + ctx.interner(), + BoundExistentialPredicates::new_from_iter( + ctx.interner(), + dst_tty.iter().filter(|pred| { + !matches!( + pred.skip_binder(), + ExistentialPredicate::AutoTrait(_) + ) + }), + ), + Region::new_erased(ctx.interner()), + ); + + // `dyn Src = dyn Dst`, this checks for matching traits/generics/projections + // This is `fcx.demand_eqtype`, but inlined to give a better error. + if ctx + .table + .at(&ObligationCause::dummy()) + .eq(src_obj, dst_obj) + .map(|infer_ok| ctx.table.register_infer_ok(infer_ok)) + .is_err() { - Ok(()) - } else { - Err(CastError::DifferingKinds) + return Err(CastError::DifferingKinds); } + + // Check that `SrcAuto` (+auto traits implied by `Src`) is a superset of `DstAuto`. + // Emit an FCW otherwise. + let src_auto: FxHashSet<_> = src_tty + .auto_traits() + .into_iter() + .chain( + elaborate::supertrait_def_ids(ctx.interner(), src_principal) + .filter(|trait_| { + ctx.db + .trait_signature(trait_.0) + .flags + .contains(TraitFlags::AUTO) + }), + ) + .collect(); + + let added = dst_tty + .auto_traits() + .into_iter() + .any(|trait_| !src_auto.contains(&trait_)); + + if added { + return Err(CastError::PtrPtrAddingAutoTraits); + } + + Ok(()) } - _ => Err(CastError::Unknown), + + // dyn Auto -> dyn Auto'? ok. + (None, None) => Ok(()), + + // dyn Trait -> dyn Auto? not ok (for now). + // + // Although dropping the principal is already allowed for unsizing coercions + // (e.g. `*const (dyn Trait + Auto)` to `*const dyn Auto`), dropping it is + // currently **NOT** allowed for (non-coercion) ptr-to-ptr casts (e.g + // `*const Foo` to `*const Bar` where `Foo` has a `dyn Trait + Auto` tail + // and `Bar` has a `dyn Auto` tail), because the underlying MIR operations + // currently work very differently: + // + // * A MIR unsizing coercion on raw pointers to trait objects (`*const dyn Src` + // to `*const dyn Dst`) is currently equivalent to downcasting the source to + // the concrete sized type that it was originally unsized from first (via a + // ptr-to-ptr cast from `*const Src` to `*const T` with `T: Sized`) and then + // unsizing this thin pointer to the target type (unsizing `*const T` to + // `*const Dst`). In particular, this means that the pointer's metadata + // (vtable) will semantically change, e.g. for const eval and miri, even + // though the vtables will always be merged for codegen. + // + // * A MIR ptr-to-ptr cast is currently equivalent to a transmute and does not + // change the pointer metadata (vtable) at all. + // + // In addition to this potentially surprising difference between coercion and + // non-coercion casts, casting away the principal with a MIR ptr-to-ptr cast + // is currently considered undefined behavior: + // + // As a validity invariant of pointers to trait objects, we currently require + // that the principal of the vtable in the pointer metadata exactly matches + // the principal of the pointee type, where "no principal" is also considered + // a kind of principal. + (Some(_), None) => Err(CastError::DifferingKinds), + + // dyn Auto -> dyn Trait? not ok. + (None, Some(_)) => Err(CastError::DifferingKinds), } } + + // fat -> fat? metadata kinds must match (Some(src_kind), Some(dst_kind)) if src_kind == dst_kind => Ok(()), (_, _) => Err(CastError::DifferingKinds), } @@ -342,9 +476,9 @@ impl<'db> CastCheck<'db> { None => Ok(()), Some(PointerKind::Error) => Ok(()), Some(PointerKind::Thin) => Ok(()), - Some(PointerKind::VTable(_)) => Err(CastError::IntToFatCast), - Some(PointerKind::Length) => Err(CastError::IntToFatCast), - Some(PointerKind::OfAlias | PointerKind::OfParam(_)) => Err(CastError::IntToFatCast), + Some(PointerKind::VTable(_)) => Err(CastError::IntToWideCast), + Some(PointerKind::Length) => Err(CastError::IntToWideCast), + Some(PointerKind::OfAlias | PointerKind::OfParam(_)) => Err(CastError::IntToWideCast), } } @@ -363,15 +497,20 @@ impl<'db> CastCheck<'db> { } } +/// The kind of pointer and associated metadata (thin, length or vtable) - we +/// only allow casts between wide pointers if their metadata have the same +/// kind. #[derive(Debug, PartialEq, Eq)] enum PointerKind<'db> { - // thin pointer + /// No metadata attached, ie pointer to sized type or foreign type Thin, - // trait object + /// A trait object VTable(BoundExistentialPredicates<'db>), - // slice + /// Slice Length, + /// The unsize info of this projection or opaque type OfAlias, + /// The unsize info of this parameter OfParam(ParamTy), Error, } @@ -439,24 +578,3 @@ fn pointer_kind<'db>( } } } - -fn contains_dyn_trait<'db>(ty: Ty<'db>) -> bool { - use std::ops::ControlFlow; - - use rustc_type_ir::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; - - struct DynTraitVisitor; - - impl<'db> TypeVisitor> for DynTraitVisitor { - type Result = ControlFlow<()>; - - fn visit_ty(&mut self, ty: Ty<'db>) -> ControlFlow<()> { - match ty.kind() { - TyKind::Dynamic(..) => ControlFlow::Break(()), - _ => ty.super_visit_with(self), - } - } - } - - ty.visit_with(&mut DynTraitVisitor).is_break() -} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index d55fc0ab0da6..2057159c46d2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -261,16 +261,6 @@ impl<'db> InferenceTable<'db> { self.infer_ctxt.canonicalize_response(t) } - // FIXME: We should get rid of this method. We cannot deeply normalize during inference, only when finishing. - // Inference should use shallow normalization (`try_structurally_resolve_type()`) only, when needed. - pub(crate) fn normalize_associated_types_in(&mut self, ty: T) -> T - where - T: TypeFoldable> + Clone, - { - let ty = self.resolve_vars_with_obligations(ty); - self.at(&ObligationCause::new()).deeply_normalize(ty.clone()).unwrap_or(ty) - } - pub(crate) fn normalize_alias_ty(&mut self, alias: Ty<'db>) -> Ty<'db> { self.infer_ctxt .at(&ObligationCause::new(), self.param_env) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs index a59077b757b1..7479f8147d2e 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/invalid_cast.rs @@ -51,7 +51,7 @@ pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast<'_ DiagnosticCode::RustcHardError("E0606"), format_ty!(ctx, "casting `{}` as `{}` is invalid", d.expr_ty, d.cast_ty), ), - CastError::IntToFatCast => ( + CastError::IntToWideCast => ( DiagnosticCode::RustcHardError("E0606"), format_ty!(ctx, "cannot cast `{}` to a fat pointer `{}`", d.expr_ty, d.cast_ty), ), @@ -95,6 +95,10 @@ pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast<'_ DiagnosticCode::RustcHardError("E0605"), format_ty!(ctx, "non-primitive cast: `{}` as `{}`", d.expr_ty, d.cast_ty), ), + CastError::PtrPtrAddingAutoTraits => ( + DiagnosticCode::RustcHardError("E0804"), + "cannot add auto trait to dyn bound via pointer cast".to_owned(), + ), // CastError::UnknownCastPtrKind | CastError::UnknownExprPtrKind => ( // DiagnosticCode::RustcHardError("E0641"), // "cannot cast to a pointer of an unknown kind".to_owned(), @@ -444,8 +448,8 @@ fn main() { q as *const [i32]; //^^^^^^^^^^^^^^^^^ error: cannot cast thin pointer `*const i32` to fat pointer `*const [i32]` - // FIXME: This should emit diagnostics but disabled to prevent many false positives let t: *mut (dyn Trait + 'static) = 0 as *mut _; + //^^^^^^^^^^^ error: cannot cast `usize` to a fat pointer `*mut (dyn Trait + 'static)` let mut fail: *const str = 0 as *const str; //^^^^^^^^^^^^^^^ error: cannot cast `usize` to a fat pointer `*const str` @@ -543,7 +547,7 @@ fn main() { fn ptr_to_trait_obj_ok() { check_diagnostics( r#" -//- minicore: pointee +//- minicore: pointee, send, sync trait Trait<'a> {} fn remove_auto<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut dyn Trait<'a> { From 6166b619794ba095919deaad239628ad2ddce3b3 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Mon, 12 Jan 2026 00:45:50 +0900 Subject: [PATCH 2097/3801] Add crashes mGCA tests --- tests/crashes/138226-2.rs | 13 ++++++++ tests/crashes/138226.rs | 13 ++++++++ tests/crashes/149809.rs | 13 ++++++++ tests/crashes/150960.rs | 11 +++++++ .../mgca/cast-with-type-mismatched.rs | 14 -------- .../mgca/cast-with-type-mismatched.stderr | 20 ------------ .../mgca/const-eval-with-invalid-args.rs | 26 --------------- .../mgca/const-eval-with-invalid-args.stderr | 32 ------------------- .../recursive-self-referencing-const-param.rs | 11 ------- ...ursive-self-referencing-const-param.stderr | 23 ------------- .../mgca/size-of-generic-ptr-in-array-len.rs | 2 ++ .../size-of-generic-ptr-in-array-len.stderr | 8 ++++- 12 files changed, 59 insertions(+), 127 deletions(-) create mode 100644 tests/crashes/138226-2.rs create mode 100644 tests/crashes/138226.rs create mode 100644 tests/crashes/149809.rs create mode 100644 tests/crashes/150960.rs delete mode 100644 tests/ui/const-generics/mgca/cast-with-type-mismatched.rs delete mode 100644 tests/ui/const-generics/mgca/cast-with-type-mismatched.stderr delete mode 100644 tests/ui/const-generics/mgca/const-eval-with-invalid-args.rs delete mode 100644 tests/ui/const-generics/mgca/const-eval-with-invalid-args.stderr delete mode 100644 tests/ui/const-generics/mgca/recursive-self-referencing-const-param.rs delete mode 100644 tests/ui/const-generics/mgca/recursive-self-referencing-const-param.stderr diff --git a/tests/crashes/138226-2.rs b/tests/crashes/138226-2.rs new file mode 100644 index 000000000000..a2ebbdefdf3f --- /dev/null +++ b/tests/crashes/138226-2.rs @@ -0,0 +1,13 @@ +//@ known-bug: #138226 +//@ needs-rustc-debug-assertions +#![feature(min_generic_const_args)] +#![feature(inherent_associated_types)] +struct Bar; +impl Bar { + #[type_const] + const LEN: usize = 4; + + fn bar() { + let _ = [0; Self::LEN]; + } +} diff --git a/tests/crashes/138226.rs b/tests/crashes/138226.rs new file mode 100644 index 000000000000..7d13461a56b3 --- /dev/null +++ b/tests/crashes/138226.rs @@ -0,0 +1,13 @@ +//@ known-bug: #138226 +//@ needs-rustc-debug-assertions +#![feature(min_generic_const_args)] +#![feature(inherent_associated_types)] +struct Foo(A, B); +impl Foo { + #[type_const] + const LEN: usize = 4; + + fn foo() { + let _ = [5; Self::LEN]; + } +} diff --git a/tests/crashes/149809.rs b/tests/crashes/149809.rs new file mode 100644 index 000000000000..2b948e9079c3 --- /dev/null +++ b/tests/crashes/149809.rs @@ -0,0 +1,13 @@ +//@ known-bug: #149809 +#![feature(min_generic_const_args)] +#![feature(inherent_associated_types)] +struct Qux<'a> { + x: &'a (), +} +impl<'a> Qux<'a> { + #[type_const] + const LEN: usize = 4; + fn foo(_: [u8; Qux::LEN]) {} +} + +fn main() {} diff --git a/tests/crashes/150960.rs b/tests/crashes/150960.rs new file mode 100644 index 000000000000..2d46eea67989 --- /dev/null +++ b/tests/crashes/150960.rs @@ -0,0 +1,11 @@ +//@ known-bug: #150960 +#![feature(min_generic_const_args)] +struct Baz; +impl Baz { + #[type_const] + const LEN: usize = 4; + + fn baz() { + let _ = [0; const { Self::LEN }]; + } +} diff --git a/tests/ui/const-generics/mgca/cast-with-type-mismatched.rs b/tests/ui/const-generics/mgca/cast-with-type-mismatched.rs deleted file mode 100644 index 1f499c222e7f..000000000000 --- a/tests/ui/const-generics/mgca/cast-with-type-mismatched.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! regression test for -#![expect(incomplete_features)] -#![feature(generic_const_exprs)] -#![feature(min_generic_const_args)] - -fn foo(a: [(); N as usize]) {} -//~^ ERROR: complex const arguments must be placed inside of a `const` block - -const C: f32 = 1.0; - -fn main() { - foo::([]); - //~^ ERROR: the constant `C` is not of type `u32` -} diff --git a/tests/ui/const-generics/mgca/cast-with-type-mismatched.stderr b/tests/ui/const-generics/mgca/cast-with-type-mismatched.stderr deleted file mode 100644 index 7e1b21138ec8..000000000000 --- a/tests/ui/const-generics/mgca/cast-with-type-mismatched.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: complex const arguments must be placed inside of a `const` block - --> $DIR/cast-with-type-mismatched.rs:6:30 - | -LL | fn foo(a: [(); N as usize]) {} - | ^^^^^^^^^^ - -error: the constant `C` is not of type `u32` - --> $DIR/cast-with-type-mismatched.rs:12:11 - | -LL | foo::([]); - | ^ expected `u32`, found `f32` - | -note: required by a const generic parameter in `foo` - --> $DIR/cast-with-type-mismatched.rs:6:8 - | -LL | fn foo(a: [(); N as usize]) {} - | ^^^^^^^^^^^^ required by this const generic parameter in `foo` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/const-generics/mgca/const-eval-with-invalid-args.rs b/tests/ui/const-generics/mgca/const-eval-with-invalid-args.rs deleted file mode 100644 index 3bf951e0c212..000000000000 --- a/tests/ui/const-generics/mgca/const-eval-with-invalid-args.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! regression test for -#![expect(incomplete_features)] -#![feature(generic_const_exprs)] -#![feature(min_generic_const_args)] - -// The previous ICE was an "invalid field access on immediate". -// If we remove `val: i32` from the field, another ICE occurs. -// "assertion `left == right` failed: invalid field type in -// Immediate::offset: scalar value has wrong size" -struct A { - arr: usize, - val: i32, -} - -struct B { - //~^ ERROR: `A` is forbidden as the type of a const generic parameter - arr: [u8; N.arr], - //~^ ERROR: complex const arguments must be placed inside of a `const` block -} - -const C: u32 = 1; -fn main() { - let b = B:: {arr: [1]}; - //~^ ERROR: the constant `C` is not of type `A` - let _ = b.arr.len(); -} diff --git a/tests/ui/const-generics/mgca/const-eval-with-invalid-args.stderr b/tests/ui/const-generics/mgca/const-eval-with-invalid-args.stderr deleted file mode 100644 index a226718ccf1b..000000000000 --- a/tests/ui/const-generics/mgca/const-eval-with-invalid-args.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error: complex const arguments must be placed inside of a `const` block - --> $DIR/const-eval-with-invalid-args.rs:17:15 - | -LL | arr: [u8; N.arr], - | ^^^^^ - -error: `A` is forbidden as the type of a const generic parameter - --> $DIR/const-eval-with-invalid-args.rs:15:19 - | -LL | struct B { - | ^ - | - = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types - | -LL + #![feature(adt_const_params)] - | - -error: the constant `C` is not of type `A` - --> $DIR/const-eval-with-invalid-args.rs:23:17 - | -LL | let b = B:: {arr: [1]}; - | ^ expected `A`, found `u32` - | -note: required by a const generic parameter in `B` - --> $DIR/const-eval-with-invalid-args.rs:15:10 - | -LL | struct B { - | ^^^^^^^^^^ required by this const generic parameter in `B` - -error: aborting due to 3 previous errors - diff --git a/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.rs b/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.rs deleted file mode 100644 index 37dcc58ff468..000000000000 --- a/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! regression test for -#![expect(incomplete_features)] -#![feature(generic_const_exprs)] -#![feature(min_generic_const_args)] - -fn identity }>() }>>(); -//~^ ERROR: free function without a body -//~| ERROR: expected type, found function `identity` -//~| ERROR: complex const arguments must be placed inside of a `const` block - -fn main() {} diff --git a/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.stderr b/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.stderr deleted file mode 100644 index d1899c476ec6..000000000000 --- a/tests/ui/const-generics/mgca/recursive-self-referencing-const-param.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error: free function without a body - --> $DIR/recursive-self-referencing-const-param.rs:6:1 - | -LL | fn identity }>() }>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | - | help: provide a definition for the function: `{ }` - -error[E0573]: expected type, found function `identity` - --> $DIR/recursive-self-referencing-const-param.rs:6:22 - | -LL | fn identity }>() }>>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type - -error: complex const arguments must be placed inside of a `const` block - --> $DIR/recursive-self-referencing-const-param.rs:6:57 - | -LL | fn identity }>() }>>(); - | ^^ - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs index 2a7c23929845..22963b6438c0 100644 --- a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs @@ -5,6 +5,8 @@ fn foo() { [0; size_of::<*mut T>()]; //~^ ERROR: tuple constructor with invalid base path + [0; const { size_of::<*mut T>() }]; + //~^ ERROR: generic parameters may not be used in const operations } fn main() {} diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr index dcdc56a1cf47..913d8195fe21 100644 --- a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr @@ -4,5 +4,11 @@ error: tuple constructor with invalid base path LL | [0; size_of::<*mut T>()]; | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: generic parameters may not be used in const operations + --> $DIR/size-of-generic-ptr-in-array-len.rs:8:32 + | +LL | [0; const { size_of::<*mut T>() }]; + | ^ + +error: aborting due to 2 previous errors From 6c4cdfaf42bef13a33935835e09bedd353791af6 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Tue, 13 Jan 2026 23:11:42 +0100 Subject: [PATCH 2098/3801] =?UTF-8?q?Replace=20complex=20`matches!(?= =?UTF-8?q?=E2=80=A6,=20=E2=80=A6=20if=20=E2=80=A6)`=20by=20`if=20let`=20c?= =?UTF-8?q?hain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clippy_lints/src/slow_vector_initialization.rs | 4 +++- clippy_lints/src/unnested_or_patterns.rs | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index b25fa0905feb..8524497c387c 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -150,7 +150,9 @@ impl SlowVectorInit { && func.ty_rel_def(cx).is_diag_item(cx, sym::vec_with_capacity) { Some(InitializedSize::Initialized(len_expr)) - } else if matches!(expr.kind, ExprKind::Call(func, []) if func.ty_rel_def(cx).is_diag_item(cx, sym::vec_new)) { + } else if let ExprKind::Call(func, []) = expr.kind + && func.ty_rel_def(cx).is_diag_item(cx, sym::vec_new) + { Some(InitializedSize::Uninitialized) } else { None diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 975dd332ad06..12f8bd50e144 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -152,7 +152,12 @@ fn insert_necessary_parens(pat: &mut Pat) { walk_pat(self, pat); let target = match &mut pat.kind { // `i @ a | b`, `box a | b`, and `& mut? a | b`. - Ident(.., Some(p)) | Box(p) | Ref(p, _, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p, + Ident(.., Some(p)) | Box(p) | Ref(p, _, _) + if let Or(ps) = &p.kind + && ps.len() > 1 => + { + p + }, // `&(mut x)` Ref(p, Pinnedness::Not, Mutability::Not) if matches!(p.kind, Ident(BindingMode::MUT, ..)) => p, _ => return, From 0ee43b16b6aa77096246e42c294de72affa60f40 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:57:34 +0100 Subject: [PATCH 2099/3801] Do not validate `diagnostic::do_not_recommend` args --- compiler/rustc_attr_parsing/src/parser.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 72b0fc63cc15..63c82ccbc7df 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -113,9 +113,12 @@ impl ArgParser { Some(match value { AttrArgs::Empty => Self::NoArgs, AttrArgs::Delimited(args) => { - // The arguments of rustc_dummy and diagnostic attributes are not validated - // if the arguments are delimited - if parts == &[sym::rustc_dummy] || parts[0] == sym::diagnostic { + // The arguments of rustc_dummy and diagnostic::do_not_recommend are not validated + // if the arguments are delimited. + // See https://doc.rust-lang.org/reference/attributes/diagnostics.html#r-attributes.diagnostic.namespace.unknown-invalid-syntax + if parts == &[sym::rustc_dummy] + || parts == &[sym::diagnostic, sym::do_not_recommend] + { return Some(ArgParser::List(MetaItemListParser { sub_parsers: ThinVec::new(), span: args.dspan.entire(), From 03cc50fc57424001285b72c02af2e19f36aabfd5 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 13 Jan 2026 15:23:59 -0800 Subject: [PATCH 2100/3801] update to indexmap v2.13.0 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45d01c486faf..4297c1b32e35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1953,9 +1953,9 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", From 15d8e9ea66442a7ee8c642245aaa77f6a78f2cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Jan 2026 19:33:40 +0000 Subject: [PATCH 2101/3801] Recognize potential `impl` to `impl` mistake When encountering code like `impl Bar for [u8; N]`, suggest `impl Bar for [u8; N]` as a possibility. ``` error[E0423]: expected value, found type parameter `T` --> $DIR/issue-69654.rs:5:25 | LL | impl Bar for [u8; T] {} | - ^ not a value | | | found this type parameter | help: you might have meant to write a const parameter here | LL | impl Bar for [u8; T] {} | +++++ ++++++++++++ ``` --- compiler/rustc_resolve/src/errors.rs | 13 +++++++ .../rustc_resolve/src/late/diagnostics.rs | 35 ++++++++++++++++++- .../generic_const_exprs/issue-69654.stderr | 5 +++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index af58d88ec35f..8880c2ba2666 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -867,6 +867,19 @@ pub(crate) struct UnexpectedResChangeTyToConstParamSugg { pub applicability: Applicability, } +#[derive(Subdiagnostic)] +#[multipart_suggestion( + resolve_unexpected_res_change_ty_to_const_param_sugg, + applicability = "has-placeholders", + style = "verbose" +)] +pub(crate) struct UnexpectedResChangeTyParamToConstParamSugg { + #[suggestion_part(code = "const ")] + pub before: Span, + #[suggestion_part(code = ": /* Type */")] + pub after: Span, +} + #[derive(Subdiagnostic)] #[suggestion( resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a2805497e796..c5d15dcc91af 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -414,6 +414,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { /// Handles error reporting for `smart_resolve_path_fragment` function. /// Creates base error and amends it with one short label and possibly some longer helps/notes. + #[tracing::instrument(skip(self), level = "debug")] pub(crate) fn smart_resolve_report_errors( &mut self, path: &[Segment], @@ -451,7 +452,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.span_suggestion_verbose(sugg.0, sugg.1, &sugg.2, Applicability::MaybeIncorrect); } - self.suggest_changing_type_to_const_param(&mut err, res, source, span); + self.suggest_changing_type_to_const_param(&mut err, res, source, path, following_seg, span); self.explain_functions_in_pattern(&mut err, res, source); if self.suggest_pattern_match_with_let(&mut err, source, span) { @@ -1505,8 +1506,40 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err: &mut Diag<'_>, res: Option, source: PathSource<'_, '_, '_>, + path: &[Segment], + following_seg: Option<&Segment>, span: Span, ) { + if let PathSource::Expr(None) = source + && let Some(Res::Def(DefKind::TyParam, _)) = res + && following_seg.is_none() + && let [segment] = path + { + // We have something like + // impl From<[T; N]> for VecWrapper { + // fn from(slice: [T; N]) -> Self { + // VecWrapper(slice.to_vec()) + // } + // } + // where `N` is a type param but should likely have been a const param. + let Some(item) = self.diag_metadata.current_item else { return }; + let Some(generics) = item.kind.generics() else { return }; + let Some(span) = generics.params.iter().find_map(|param| { + // Only consider type params with no bounds. + if param.bounds.is_empty() && param.ident.name == segment.ident.name { + Some(param.ident.span) + } else { + None + } + }) else { + return; + }; + err.subdiagnostic(errors::UnexpectedResChangeTyParamToConstParamSugg { + before: span.shrink_to_lo(), + after: span.shrink_to_hi(), + }); + return; + } let PathSource::Trait(_) = source else { return }; // We don't include `DefKind::Str` and `DefKind::AssocTy` as they can't be reached here anyway. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr index eb4ff8305dac..7fa0d8c7dbaa 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr @@ -5,6 +5,11 @@ LL | impl Bar for [u8; T] {} | - ^ not a value | | | found this type parameter + | +help: you might have meant to write a const parameter here + | +LL | impl Bar for [u8; T] {} + | +++++ ++++++++++++ error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied --> $DIR/issue-69654.rs:17:10 From c8c7b5b449d243a4ee5474e49e9bb112d56264aa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 14 Jan 2026 00:58:35 +0100 Subject: [PATCH 2102/3801] Generate macro expansion for rust compiler crates docs --- src/bootstrap/src/core/build_steps/doc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index b86582807f72..fa36a6471cae 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -932,6 +932,7 @@ impl Step for Rustc { // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222 // If there is any bug, please comment out the next line. cargo.rustdocflag("--generate-link-to-definition"); + cargo.rustdocflag("--generate-macro-expansion"); compile::rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates); cargo.arg("-Zskip-rustdoc-fingerprint"); From b202eee0816938126195e95488ce6df8e9602214 Mon Sep 17 00:00:00 2001 From: Taeyoon Kim Date: Wed, 14 Jan 2026 10:06:39 +0900 Subject: [PATCH 2103/3801] Add Korean translation to Rust By Example Add korean translation. Thanks in advanced --- src/bootstrap/src/core/build_steps/doc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index b86582807f72..9bb16fe33fd5 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -75,7 +75,7 @@ book!( EditionGuide, "src/doc/edition-guide", "edition-guide", &[]; EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[]; Nomicon, "src/doc/nomicon", "nomicon", &[]; - RustByExample, "src/doc/rust-by-example", "rust-by-example", &["es", "ja", "zh"]; + RustByExample, "src/doc/rust-by-example", "rust-by-example", &["es", "ja", "zh", "ko"]; RustdocBook, "src/doc/rustdoc", "rustdoc", &[]; StyleGuide, "src/doc/style-guide", "style-guide", &[]; ); From 795745ccf1f7af296334204931ae1d0e467d62c2 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Tue, 13 Jan 2026 19:48:38 -0500 Subject: [PATCH 2104/3801] remote-test-server: Fix compilation on UEFI targets Tested with: ./x build src/tools/remote-test-server --target x86_64-unknown-uefi --- src/tools/remote-test-server/src/main.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index bfe8f54937f6..a15f30d4659e 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -10,13 +10,13 @@ //! themselves having support libraries. All data over the TCP sockets is in a //! basically custom format suiting our needs. -#[cfg(all(not(windows), not(target_os = "motor")))] +#[cfg(not(any(windows, target_os = "motor", target_os = "uefi")))] use std::fs::Permissions; use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufReader}; use std::net::{SocketAddr, TcpListener, TcpStream}; -#[cfg(all(not(windows), not(target_os = "motor")))] +#[cfg(not(any(windows, target_os = "motor", target_os = "uefi")))] use std::os::unix::prelude::*; use std::path::{Path, PathBuf}; use std::process::{Command, ExitStatus, Stdio}; @@ -325,7 +325,7 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf ])); } -#[cfg(all(not(windows), not(target_os = "motor")))] +#[cfg(not(any(windows, target_os = "motor", target_os = "uefi")))] fn get_status_code(status: &ExitStatus) -> (u8, i32) { match status.code() { Some(n) => (0, n), @@ -333,7 +333,7 @@ fn get_status_code(status: &ExitStatus) -> (u8, i32) { } } -#[cfg(any(windows, target_os = "motor"))] +#[cfg(any(windows, target_os = "motor", target_os = "uefi"))] fn get_status_code(status: &ExitStatus) -> (u8, i32) { (0, status.code().unwrap()) } @@ -359,11 +359,11 @@ fn recv(dir: &Path, io: &mut B) -> PathBuf { dst } -#[cfg(all(not(windows), not(target_os = "motor")))] +#[cfg(not(any(windows, target_os = "motor", target_os = "uefi")))] fn set_permissions(path: &Path) { t!(fs::set_permissions(&path, Permissions::from_mode(0o755))); } -#[cfg(any(windows, target_os = "motor"))] +#[cfg(any(windows, target_os = "motor", target_os = "uefi"))] fn set_permissions(_path: &Path) {} fn my_copy(src: &mut dyn Read, which: u8, dst: &Mutex) { From cd6c41283838023ee3b22709106d666869ec9a6f Mon Sep 17 00:00:00 2001 From: Zachary S Date: Tue, 13 Jan 2026 22:40:12 -0600 Subject: [PATCH 2105/3801] Add test for feature-gating `mut ref` patterns in struct field shorthand. --- tests/ui/feature-gates/feature-gate-mut-ref.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/ui/feature-gates/feature-gate-mut-ref.rs b/tests/ui/feature-gates/feature-gate-mut-ref.rs index 752ae35d8a9a..eac2a59002e2 100644 --- a/tests/ui/feature-gates/feature-gate-mut-ref.rs +++ b/tests/ui/feature-gates/feature-gate-mut-ref.rs @@ -10,4 +10,7 @@ fn main() { let mut ref x = 10; //~ ERROR [E0658] #[cfg(false)] let mut ref mut y = 10; //~ ERROR [E0658] + + struct Foo { x: i32 } + let Foo { mut ref x } = Foo { x: 10 }; } From f809e332d895bc80d28d8d2cb10297a3fe9ca4f2 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Tue, 13 Jan 2026 12:57:04 -0600 Subject: [PATCH 2106/3801] Feature-gate `mut ref` patterns in struct field shorthand. --- compiler/rustc_parse/src/parser/pat.rs | 6 ++++++ tests/ui/feature-gates/feature-gate-mut-ref.rs | 2 +- tests/ui/feature-gates/feature-gate-mut-ref.stderr | 12 +++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index d7f3a36122e5..f3e12d48a6a5 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -1750,6 +1750,12 @@ impl<'a> Parser<'a> { hi = self.prev_token.span; let ann = BindingMode(by_ref, mutability); let fieldpat = self.mk_pat_ident(boxed_span.to(hi), ann, fieldname); + if matches!( + fieldpat.kind, + PatKind::Ident(BindingMode(ByRef::Yes(..), Mutability::Mut), ..) + ) { + self.psess.gated_spans.gate(sym::mut_ref, fieldpat.span); + } let subpat = if is_box { self.mk_pat(lo.to(hi), PatKind::Box(Box::new(fieldpat))) } else { diff --git a/tests/ui/feature-gates/feature-gate-mut-ref.rs b/tests/ui/feature-gates/feature-gate-mut-ref.rs index eac2a59002e2..74b1fba5dfea 100644 --- a/tests/ui/feature-gates/feature-gate-mut-ref.rs +++ b/tests/ui/feature-gates/feature-gate-mut-ref.rs @@ -12,5 +12,5 @@ fn main() { let mut ref mut y = 10; //~ ERROR [E0658] struct Foo { x: i32 } - let Foo { mut ref x } = Foo { x: 10 }; + let Foo { mut ref x } = Foo { x: 10 }; //~ ERROR [E0658] } diff --git a/tests/ui/feature-gates/feature-gate-mut-ref.stderr b/tests/ui/feature-gates/feature-gate-mut-ref.stderr index d3eb674e92de..921ff878bf4d 100644 --- a/tests/ui/feature-gates/feature-gate-mut-ref.stderr +++ b/tests/ui/feature-gates/feature-gate-mut-ref.stderr @@ -38,6 +38,16 @@ LL | let mut ref mut y = 10; = help: add `#![feature(mut_ref)]` 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 4 previous errors +error[E0658]: mutable by-reference bindings are experimental + --> $DIR/feature-gate-mut-ref.rs:15:15 + | +LL | let Foo { mut ref x } = Foo { x: 10 }; + | ^^^^^^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` 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 5 previous errors For more information about this error, try `rustc --explain E0658`. From 3aa31788b57da7a5eeee8184dccb00178b40121b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 14 Jan 2026 10:30:08 +1100 Subject: [PATCH 2107/3801] Remove `Deref`/`DerefMut` impl for `Providers`. It's described as a "backwards compatibility hack to keep the diff small". Removing it requires only a modest amount of churn, and the resulting code is clearer without the invisible derefs. --- compiler/rustc_codegen_gcc/src/lib.rs | 3 +- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- .../src/back/symbol_export.rs | 18 ++++---- compiler/rustc_codegen_ssa/src/lib.rs | 6 +-- compiler/rustc_const_eval/src/lib.rs | 16 +++---- compiler/rustc_interface/src/passes.rs | 46 +++++++++---------- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_middle/src/util/mod.rs | 17 ------- compiler/rustc_mir_build/src/lib.rs | 12 ++--- compiler/rustc_mir_transform/src/lib.rs | 6 +-- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_monomorphize/src/lib.rs | 2 +- .../rustc_monomorphize/src/partitioning.rs | 8 ++-- compiler/rustc_passes/src/lib.rs | 2 +- src/librustdoc/core.rs | 9 ++-- src/tools/miri/src/bin/miri.rs | 2 +- tests/ui-fulldeps/obtain-borrowck.rs | 6 +-- 17 files changed, 72 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 96d3a0024f41..cf1be1806235 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -286,7 +286,8 @@ impl CodegenBackend for GccCodegenBackend { } fn provide(&self, providers: &mut Providers) { - providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess) + providers.queries.global_backend_features = + |tcx, ()| gcc_util::global_gcc_features(tcx.sess) } fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 438a74e0a091..e0007f69828d 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -264,7 +264,7 @@ impl CodegenBackend for LlvmCodegenBackend { } fn provide(&self, providers: &mut Providers) { - providers.global_backend_features = + providers.queries.global_backend_features = |tcx, ()| llvm_util::global_llvm_features(tcx.sess, false) } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 27989f6f5ea2..59d0f5ee9d54 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -474,15 +474,15 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId) } pub(crate) fn provide(providers: &mut Providers) { - providers.reachable_non_generics = reachable_non_generics_provider; - providers.is_reachable_non_generic = is_reachable_non_generic_provider_local; - providers.exported_non_generic_symbols = exported_non_generic_symbols_provider_local; - providers.exported_generic_symbols = exported_generic_symbols_provider_local; - providers.upstream_monomorphizations = upstream_monomorphizations_provider; - providers.is_unreachable_local_definition = is_unreachable_local_definition_provider; - providers.upstream_drop_glue_for = upstream_drop_glue_for_provider; - providers.upstream_async_drop_glue_for = upstream_async_drop_glue_for_provider; - providers.wasm_import_module_map = wasm_import_module_map; + providers.queries.reachable_non_generics = reachable_non_generics_provider; + providers.queries.is_reachable_non_generic = is_reachable_non_generic_provider_local; + providers.queries.exported_non_generic_symbols = exported_non_generic_symbols_provider_local; + providers.queries.exported_generic_symbols = exported_generic_symbols_provider_local; + providers.queries.upstream_monomorphizations = upstream_monomorphizations_provider; + providers.queries.is_unreachable_local_definition = is_unreachable_local_definition_provider; + providers.queries.upstream_drop_glue_for = upstream_drop_glue_for_provider; + providers.queries.upstream_async_drop_glue_for = upstream_async_drop_glue_for_provider; + providers.queries.wasm_import_module_map = wasm_import_module_map; providers.extern_queries.is_reachable_non_generic = is_reachable_non_generic_provider_extern; providers.extern_queries.upstream_monomorphizations_for = upstream_monomorphizations_for_provider; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index d7461c76ff03..8c39d04ef21d 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -266,9 +266,9 @@ pub enum CodegenErrors { pub fn provide(providers: &mut Providers) { crate::back::symbol_export::provide(providers); - crate::base::provide(providers); - crate::target_features::provide(providers); - crate::codegen_attrs::provide(providers); + crate::base::provide(&mut providers.queries); + crate::target_features::provide(&mut providers.queries); + crate::codegen_attrs::provide(&mut providers.queries); providers.queries.global_backend_features = |_tcx: TyCtxt<'_>, ()| vec![]; } diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 2fce4b8c0566..9b1d4652212b 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -30,20 +30,20 @@ pub use self::errors::ReportErrorExt; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } pub fn provide(providers: &mut Providers) { - const_eval::provide(providers); - providers.tag_for_variant = const_eval::tag_for_variant_provider; - providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider; - providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; - providers.eval_static_initializer = const_eval::eval_static_initializer_provider; + const_eval::provide(&mut providers.queries); + providers.queries.tag_for_variant = const_eval::tag_for_variant_provider; + providers.queries.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider; + providers.queries.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; + providers.queries.eval_static_initializer = const_eval::eval_static_initializer_provider; providers.hooks.const_caller_location = util::caller_location::const_caller_location_provider; - providers.eval_to_valtree = |tcx, ty::PseudoCanonicalInput { typing_env, value }| { + providers.queries.eval_to_valtree = |tcx, ty::PseudoCanonicalInput { typing_env, value }| { const_eval::eval_to_valtree(tcx, typing_env, value) }; providers.hooks.try_destructure_mir_constant_for_user_output = const_eval::try_destructure_mir_constant_for_user_output; - providers.valtree_to_const_val = + providers.queries.valtree_to_const_val = |tcx, cv| const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(), cv); - providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| { + providers.queries.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| { util::check_validity_requirement(tcx, init_kind, param_env_and_ty) }; providers.hooks.validate_scalar_in_layout = diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index a0383b187de5..35ab202d4c27 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -880,36 +880,36 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { let providers = &mut Providers::default(); - providers.analysis = analysis; - providers.hir_crate = rustc_ast_lowering::lower_to_hir; - providers.resolver_for_lowering_raw = resolver_for_lowering_raw; - providers.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..]; - providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1; - providers.early_lint_checks = early_lint_checks; - providers.env_var_os = env_var_os; - limits::provide(providers); - proc_macro_decls::provide(providers); + providers.queries.analysis = analysis; + providers.queries.hir_crate = rustc_ast_lowering::lower_to_hir; + providers.queries.resolver_for_lowering_raw = resolver_for_lowering_raw; + providers.queries.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..]; + providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1; + providers.queries.early_lint_checks = early_lint_checks; + providers.queries.env_var_os = env_var_os; + limits::provide(&mut providers.queries); + proc_macro_decls::provide(&mut providers.queries); rustc_const_eval::provide(providers); - rustc_middle::hir::provide(providers); - rustc_borrowck::provide(providers); + rustc_middle::hir::provide(&mut providers.queries); + rustc_borrowck::provide(&mut providers.queries); rustc_incremental::provide(providers); rustc_mir_build::provide(providers); rustc_mir_transform::provide(providers); rustc_monomorphize::provide(providers); - rustc_privacy::provide(providers); + rustc_privacy::provide(&mut providers.queries); rustc_query_impl::provide(providers); - rustc_resolve::provide(providers); - rustc_hir_analysis::provide(providers); - rustc_hir_typeck::provide(providers); - ty::provide(providers); - traits::provide(providers); - solve::provide(providers); - rustc_passes::provide(providers); - rustc_traits::provide(providers); - rustc_ty_utils::provide(providers); + rustc_resolve::provide(&mut providers.queries); + rustc_hir_analysis::provide(&mut providers.queries); + rustc_hir_typeck::provide(&mut providers.queries); + ty::provide(&mut providers.queries); + traits::provide(&mut providers.queries); + solve::provide(&mut providers.queries); + rustc_passes::provide(&mut providers.queries); + rustc_traits::provide(&mut providers.queries); + rustc_ty_utils::provide(&mut providers.queries); rustc_metadata::provide(providers); - rustc_lint::provide(providers); - rustc_symbol_mangling::provide(providers); + rustc_lint::provide(&mut providers.queries); + rustc_symbol_mangling::provide(&mut providers.queries); rustc_codegen_ssa::provide(providers); *providers }); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 0de54cf87433..af6df0cd6eb6 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -585,6 +585,6 @@ const SYMBOL_OFFSET: u8 = 1; const SYMBOL_PREDEFINED: u8 = 2; pub fn provide(providers: &mut Providers) { - encoder::provide(providers); + encoder::provide(&mut providers.queries); decoder::provide(providers); } diff --git a/compiler/rustc_middle/src/util/mod.rs b/compiler/rustc_middle/src/util/mod.rs index 85519fb0a7d2..d5076a278eab 100644 --- a/compiler/rustc_middle/src/util/mod.rs +++ b/compiler/rustc_middle/src/util/mod.rs @@ -6,20 +6,3 @@ pub struct Providers { pub extern_queries: crate::query::ExternProviders, pub hooks: crate::hooks::Providers, } - -/// Backwards compatibility hack to keep the diff small. This -/// gives direct access to the `queries` field's fields, which -/// are what almost everything wants access to. -impl std::ops::DerefMut for Providers { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.queries - } -} - -impl std::ops::Deref for Providers { - type Target = crate::query::Providers; - - fn deref(&self) -> &Self::Target { - &self.queries - } -} diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 410ea791ac5c..91cc4dfa665f 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -23,12 +23,12 @@ use rustc_middle::util::Providers; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } pub fn provide(providers: &mut Providers) { - providers.check_match = thir::pattern::check_match; - providers.lit_to_const = thir::constant::lit_to_const; - providers.closure_saved_names_of_captured_variables = + providers.queries.check_match = thir::pattern::check_match; + providers.queries.lit_to_const = thir::constant::lit_to_const; + providers.queries.closure_saved_names_of_captured_variables = builder::closure_saved_names_of_captured_variables; - providers.check_unsafety = check_unsafety::check_unsafety; - providers.check_tail_calls = check_tail_calls::check_tail_calls; - providers.thir_body = thir::cx::thir_body; + providers.queries.check_unsafety = check_unsafety::check_unsafety; + providers.queries.check_tail_calls = check_tail_calls::check_tail_calls; + providers.queries.thir_body = thir::cx::thir_body; providers.hooks.build_mir_inner_impl = builder::build_mir_inner_impl; } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index c78b0adaf6f1..328a4b23c175 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -206,9 +206,9 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" } pub fn provide(providers: &mut Providers) { coverage::query::provide(providers); - ffi_unwind_calls::provide(providers); - shim::provide(providers); - cross_crate_inline::provide(providers); + ffi_unwind_calls::provide(&mut providers.queries); + shim::provide(&mut providers.queries); + cross_crate_inline::provide(&mut providers.queries); providers.queries = query::Providers { mir_keys, mir_built, diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 070db1ae6b5e..ce1704696918 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1825,5 +1825,5 @@ pub(crate) fn collect_crate_mono_items<'tcx>( pub(crate) fn provide(providers: &mut Providers) { providers.hooks.should_codegen_locally = should_codegen_locally; - providers.items_of_instance = items_of_instance; + providers.queries.items_of_instance = items_of_instance; } diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 5b4f74ca6a70..56c74b693fb7 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -52,5 +52,5 @@ fn custom_coerce_unsize_info<'tcx>( pub fn provide(providers: &mut Providers) { partitioning::provide(providers); - mono_checks::provide(providers); + mono_checks::provide(&mut providers.queries); } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 13d7f6a25f76..a86230e9ab22 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -1313,12 +1313,12 @@ fn dump_mono_items_stats<'tcx>( } pub(crate) fn provide(providers: &mut Providers) { - providers.collect_and_partition_mono_items = collect_and_partition_mono_items; + providers.queries.collect_and_partition_mono_items = collect_and_partition_mono_items; - providers.is_codegened_item = + providers.queries.is_codegened_item = |tcx, def_id| tcx.collect_and_partition_mono_items(()).all_mono_items.contains(&def_id); - providers.codegen_unit = |tcx, name| { + providers.queries.codegen_unit = |tcx, name| { tcx.collect_and_partition_mono_items(()) .codegen_units .iter() @@ -1326,7 +1326,7 @@ pub(crate) fn provide(providers: &mut Providers) { .unwrap_or_else(|| panic!("failed to find cgu with name {name:?}")) }; - providers.size_estimate = |tcx, instance| { + providers.queries.size_estimate = |tcx, instance| { match instance.def { // "Normal" functions size estimate: the number of // statements, plus one for the terminator. diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 865f2a9c3b8b..d371589cba6c 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -9,7 +9,7 @@ #![feature(map_try_insert)] // tidy-alphabetical-end -use rustc_middle::util::Providers; +use rustc_middle::query::Providers; pub mod abi_test; mod check_attr; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index fb2088963284..413163290ee3 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -297,14 +297,15 @@ pub(crate) fn create_config( override_queries: Some(|_sess, providers| { // We do not register late module lints, so this only runs `MissingDoc`. // Most lints will require typechecking, so just don't run them. - providers.lint_mod = |tcx, module_def_id| late_lint_mod(tcx, module_def_id, MissingDoc); + providers.queries.lint_mod = + |tcx, module_def_id| late_lint_mod(tcx, module_def_id, MissingDoc); // hack so that `used_trait_imports` won't try to call typeck - providers.used_trait_imports = |_, _| { + providers.queries.used_trait_imports = |_, _| { static EMPTY_SET: LazyLock> = LazyLock::new(UnordSet::default); &EMPTY_SET }; // In case typeck does end up being called, don't ICE in case there were name resolution errors - providers.typeck = move |tcx, def_id| { + providers.queries.typeck = move |tcx, def_id| { // Closures' tables come from their outermost function, // as they are part of the same "inference environment". // This avoids emitting errors for the parent twice (see similar code in `typeck_with_fallback`) @@ -316,7 +317,7 @@ pub(crate) fn create_config( let body = tcx.hir_body_owned_by(def_id); debug!("visiting body for {def_id:?}"); EmitIgnoredResolutionErrors::new(tcx).visit_body(body); - (rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id) + (rustc_interface::DEFAULT_QUERY_PROVIDERS.queries.typeck)(tcx, def_id) }; }), extra_symbols: Vec::new(), diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 19fbf90246c9..9816061a8eca 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -305,7 +305,7 @@ impl rustc_driver::Callbacks for MiriDepCompilerCalls { config.override_queries = Some(|_, local_providers| { // We need to add #[used] symbols to exported_symbols for `lookup_link_section`. // FIXME handle this somehow in rustc itself to avoid this hack. - local_providers.exported_non_generic_symbols = |tcx, LocalCrate| { + local_providers.queries.exported_non_generic_symbols = |tcx, LocalCrate| { let reachable_set = tcx .with_stable_hashing_context(|hcx| tcx.reachable_set(()).to_sorted(&hcx, true)); tcx.arena.alloc_from_iter( diff --git a/tests/ui-fulldeps/obtain-borrowck.rs b/tests/ui-fulldeps/obtain-borrowck.rs index 08213fd75880..a562d0ccd3df 100644 --- a/tests/ui-fulldeps/obtain-borrowck.rs +++ b/tests/ui-fulldeps/obtain-borrowck.rs @@ -114,7 +114,7 @@ impl rustc_driver::Callbacks for CompilerCalls { } fn override_queries(_session: &Session, local: &mut Providers) { - local.mir_borrowck = mir_borrowck; + local.queries.mir_borrowck = mir_borrowck; } // Since mir_borrowck does not have access to any other state, we need to use a @@ -142,8 +142,8 @@ fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ProvidedValue<'t } }); let mut providers = Providers::default(); - rustc_borrowck::provide(&mut providers); - let original_mir_borrowck = providers.mir_borrowck; + rustc_borrowck::provide(&mut providers.queries); + let original_mir_borrowck = providers.queries.mir_borrowck; original_mir_borrowck(tcx, def_id) } From c9a063ced93ec7dce1dfaca57f818dba5334cfca Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 14 Jan 2026 10:30:08 +1100 Subject: [PATCH 2108/3801] Remove `Deref`/`DerefMut` impl for `Providers`. It's described as a "backwards compatibility hack to keep the diff small". Removing it requires only a modest amount of churn, and the resulting code is clearer without the invisible derefs. --- src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 96d3a0024f41..cf1be1806235 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -286,7 +286,8 @@ impl CodegenBackend for GccCodegenBackend { } fn provide(&self, providers: &mut Providers) { - providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess) + providers.queries.global_backend_features = + |tcx, ()| gcc_util::global_gcc_features(tcx.sess) } fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { From 0c57e8c83266603eb2ef4e899fe76c783073ce7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 7 Jan 2026 16:57:33 +0100 Subject: [PATCH 2109/3801] Change `bors build finished` job to `publish toolstate` --- .github/workflows/ci.yml | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fe906cb8622..e6a00bb42785 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -305,30 +305,22 @@ jobs: DD_GITHUB_JOB_NAME: ${{ matrix.full_name }} run: ./build/citool/debug/citool upload-build-metrics build/cpu-usage.csv - # This job isused to tell bors the final status of the build, as there is no practical way to detect - # when a workflow is successful listening to webhooks only in our current bors implementation (homu). + # This job is used to publish toolstate for successful auto builds. outcome: - name: bors build finished + name: publish toolstate runs-on: ubuntu-24.04 needs: [ calculate_matrix, job ] - # !cancelled() executes the job regardless of whether the previous jobs passed or failed - if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }} - environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} + if: ${{ needs.calculate_matrix.outputs.run_type == 'auto' }} + environment: ${{ (github.repository == 'rust-lang/rust' && 'bors') || '' }} steps: - name: checkout the source code uses: actions/checkout@v5 with: fetch-depth: 2 - # Calculate the exit status of the whole CI workflow. - # If all dependent jobs were successful, this exits with 0 (and the outcome job continues successfully). - # If a some dependent job has failed, this exits with 1. - - name: calculate the correct exit status - run: jq --exit-status 'all(.result == "success" or .result == "skipped")' <<< '${{ toJson(needs) }}' # Publish the toolstate if an auto build succeeds (just before push to the default branch) - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash - if: needs.calculate_matrix.outputs.run_type == 'auto' env: TOOLSTATE_ISSUES_API_URL: https://api.github.com/repos/rust-lang/rust/issues TOOLSTATE_PUBLISH: 1 From 414e00d3509a4cfedaab0d9c712a5f41861ea0c6 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 14 Jan 2026 15:55:49 +1100 Subject: [PATCH 2110/3801] Clarify the docs/examples for `ProjectionElem::ConstantIndex` --- compiler/rustc_middle/src/mir/syntax.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 83e9a1f1784b..6ec874fb15f7 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1221,25 +1221,32 @@ pub enum ProjectionElem { /// thing is true of the `ConstantIndex` and `Subslice` projections below. Index(V), - /// These indices are generated by slice patterns. Easiest to explain - /// by example: + /// These endpoint-relative indices are generated by slice/array patterns. + /// + /// For array types, `offset` is always relative to the start of the array. + /// For slice types, `from_end` determines whether `offset` is relative to + /// the start or the end of the slice being inspected. + /// + /// Slice-pattern indices are easiest to explain by the position of `X` in + /// these examples: /// /// ```ignore (illustrative) - /// [X, _, .._, _, _] => { offset: 0, min_length: 4, from_end: false }, - /// [_, X, .._, _, _] => { offset: 1, min_length: 4, from_end: false }, - /// [_, _, .._, X, _] => { offset: 2, min_length: 4, from_end: true }, - /// [_, _, .._, _, X] => { offset: 1, min_length: 4, from_end: true }, + /// [X, _, .., _, _] => { offset: 0, min_length: 4, from_end: false }, + /// [_, X, .., _, _] => { offset: 1, min_length: 4, from_end: false }, + /// [_, _, .., X, _] => { offset: 2, min_length: 4, from_end: true }, + /// [_, _, .., _, X] => { offset: 1, min_length: 4, from_end: true }, /// ``` ConstantIndex { - /// index or -index (in Python terms), depending on from_end + /// - If `from_end == false`, this is a 0-based offset from the start of the array/slice. + /// - If `from_end == true`, this is a 1-based offset from the end of the slice. offset: u64, /// The thing being indexed must be at least this long -- otherwise, the /// projection is UB. /// /// For arrays this is always the exact length. min_length: u64, - /// Counting backwards from end? This is always false when indexing an - /// array. + /// If `true`, `offset` is a 1-based offset from the end of the slice. + /// Always false when indexing an array. from_end: bool, }, From a9ce7503d51b2be5a71a25315b4b4cb63eebf8b6 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 14 Jan 2026 14:53:57 +1100 Subject: [PATCH 2111/3801] Pull array length determination out of `prefix_slice_suffix` --- .../src/builder/matches/match_pair.rs | 85 +++++++++++-------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 8cee3ff27e8f..19b4cd70c0b9 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -40,33 +40,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match_pairs: &mut Vec>, extra_data: &mut PatternExtraData<'tcx>, place: &PlaceBuilder<'tcx>, + array_len: Option, prefix: &[Pat<'tcx>], opt_slice: &Option>>, suffix: &[Pat<'tcx>], ) { - let tcx = self.tcx; - let (min_length, exact_size) = if let Some(place_resolved) = place.try_to_place(self) { - let place_ty = place_resolved.ty(&self.local_decls, tcx).ty; - match place_ty.kind() { - ty::Array(_, length) => { - if let Some(length) = length.try_to_target_usize(tcx) { - (length, true) - } else { - // This can happen when the array length is a generic const - // expression that couldn't be evaluated (e.g., due to an error). - // Since there's already a compilation error, we use a fallback - // to avoid an ICE. - tcx.dcx().span_delayed_bug( - tcx.def_span(self.def_id), - "array length in pattern couldn't be evaluated", - ); - ((prefix.len() + suffix.len()).try_into().unwrap(), false) - } - } - _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false), - } - } else { - ((prefix.len() + suffix.len()).try_into().unwrap(), false) + let prefix_len = u64::try_from(prefix.len()).unwrap(); + let suffix_len = u64::try_from(suffix.len()).unwrap(); + + // For slice patterns with a `..` followed by 0 or more suffix subpatterns, + // the actual slice index of those subpatterns isn't statically known, so + // we have to index them relative to the end of the slice. + // + // For array patterns, all subpatterns are indexed relative to the start. + let (min_length, is_array) = match array_len { + Some(len) => (len, true), + None => (prefix_len + suffix_len, false), }; for (idx, subpattern) in prefix.iter().enumerate() { @@ -77,11 +66,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } if let Some(subslice_pat) = opt_slice { - let suffix_len = suffix.len() as u64; let subslice = place.clone_project(PlaceElem::Subslice { - from: prefix.len() as u64, - to: if exact_size { min_length - suffix_len } else { suffix_len }, - from_end: !exact_size, + from: prefix_len, + to: if is_array { min_length - suffix_len } else { suffix_len }, + from_end: !is_array, }); MatchPairTree::for_pattern(subslice, subslice_pat, self, match_pairs, extra_data); } @@ -89,9 +77,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { for (idx, subpattern) in suffix.iter().rev().enumerate() { let end_offset = (idx + 1) as u64; let elem = ProjectionElem::ConstantIndex { - offset: if exact_size { min_length - end_offset } else { end_offset }, + offset: if is_array { min_length - end_offset } else { end_offset }, min_length, - from_end: !exact_size, + from_end: !is_array, }; let place = place.clone_project(elem); MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data) @@ -256,14 +244,36 @@ impl<'tcx> MatchPairTree<'tcx> { } PatKind::Array { ref prefix, ref slice, ref suffix } => { - cx.prefix_slice_suffix( - &mut subpairs, - extra_data, - &place_builder, - prefix, - slice, - suffix, - ); + // Determine the statically-known length of the array type being matched. + // This should always succeed for legal programs, but could fail for + // erroneous programs (e.g. the type is `[u8; const { panic!() }]`), + // so take care not to ICE if this fails. + let array_len = match pattern.ty.kind() { + ty::Array(_, len) => len.try_to_target_usize(cx.tcx), + _ => None, + }; + if let Some(array_len) = array_len { + cx.prefix_slice_suffix( + &mut subpairs, + extra_data, + &place_builder, + Some(array_len), + prefix, + slice, + suffix, + ); + } else { + // If the array length couldn't be determined, ignore the + // subpatterns and delayed-assert that compilation will fail. + cx.tcx.dcx().span_delayed_bug( + pattern.span, + format!( + "array length in pattern couldn't be determined for ty={:?}", + pattern.ty + ), + ); + } + None } PatKind::Slice { ref prefix, ref slice, ref suffix } => { @@ -271,6 +281,7 @@ impl<'tcx> MatchPairTree<'tcx> { &mut subpairs, extra_data, &place_builder, + None, prefix, slice, suffix, From a72083f739c369cd1ce675a1d278505656674af6 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 14 Jan 2026 16:13:49 +1100 Subject: [PATCH 2112/3801] Avoid some more usize-to-u64 casts in `prefix_slice_suffix` --- .../rustc_mir_build/src/builder/matches/match_pair.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 19b4cd70c0b9..3edd0234b0ad 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -58,9 +58,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None => (prefix_len + suffix_len, false), }; - for (idx, subpattern) in prefix.iter().enumerate() { - let elem = - ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false }; + for (offset, subpattern) in (0u64..).zip(prefix) { + let elem = ProjectionElem::ConstantIndex { offset, min_length, from_end: false }; let place = place.clone_project(elem); MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data) } @@ -74,8 +73,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { MatchPairTree::for_pattern(subslice, subslice_pat, self, match_pairs, extra_data); } - for (idx, subpattern) in suffix.iter().rev().enumerate() { - let end_offset = (idx + 1) as u64; + for (end_offset, subpattern) in (1u64..).zip(suffix.iter().rev()) { let elem = ProjectionElem::ConstantIndex { offset: if is_array { min_length - end_offset } else { end_offset }, min_length, From 05939a8d38959b1ff418a0f54663eaba0f5e3108 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 14 Jan 2026 17:54:23 +0800 Subject: [PATCH 2113/3801] Fix false positive precedence in `(2 as i32) < 3` Example --- ```rust fn f() { _ = $0(1 as u32) << 10; } ``` **Before this PR** This is syntax error ```rust fn f() { _ = 1 as u32 << 10; } ``` **After this PR** Assist not applicable --- .../src/handlers/remove_parentheses.rs | 6 +++++ .../crates/syntax/src/ast/prec.rs | 24 +++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs index aa4d2bcadb01..f07da489e23a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs @@ -321,6 +321,12 @@ mod tests { ); } + #[test] + fn remove_parens_conflict_cast_before_l_angle() { + check_assist_not_applicable(remove_parentheses, r#"fn f() { _ = $0(1 as u32) << 10; }"#); + check_assist_not_applicable(remove_parentheses, r#"fn f() { _ = $0(1 as u32) < 10; }"#); + } + #[test] fn remove_parens_double_paren_stmt() { check_assist( diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs index 8c88224a761a..d99cf492616e 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs @@ -154,6 +154,11 @@ fn check_ancestry(ancestor: &SyntaxNode, descendent: &SyntaxNode) -> bool { bail() } +fn next_token_of(node: &SyntaxNode) -> Option { + let last = node.last_token()?; + skip_trivia_token(last.next_token()?, Direction::Next) +} + impl Expr { pub fn precedence(&self) -> ExprPrecedence { precedence(self) @@ -197,6 +202,8 @@ impl Expr { if is_parent_call_expr && is_field_expr { return true; } + let place_of_parent = + || place_of.ancestors().find(|it| it.parent().is_none_or(|p| &p == parent.syntax())); // Special-case block weirdness if parent.child_is_followed_by_a_block() { @@ -226,15 +233,24 @@ impl Expr { // For `&&`, we avoid introducing ` && ` into a binary chain. if self.precedence() == ExprPrecedence::Jump - && let Some(node) = - place_of.ancestors().find(|it| it.parent().is_none_or(|p| &p == parent.syntax())) - && let Some(next) = - node.last_token().and_then(|t| skip_trivia_token(t.next_token()?, Direction::Next)) + && let Some(node) = place_of_parent() + && let Some(next) = next_token_of(&node) && matches!(next.kind(), T![||] | T![&&]) { return true; } + // Special-case `2 as x < 3` + if let ast::Expr::CastExpr(it) = self + && let Some(ty) = it.ty() + && ty.syntax().last_token().and_then(|it| ast::NameLike::cast(it.parent()?)).is_some() + && let Some(node) = place_of_parent() + && let Some(next) = next_token_of(&node) + && matches!(next.kind(), T![<] | T![<<]) + { + return true; + } + if self.is_paren_like() || parent.is_paren_like() || self.is_prefix() From bc751adcdb7cd5cce59a6aec36e74b959132e0af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= Date: Sun, 4 Jan 2026 17:26:21 +0100 Subject: [PATCH 2114/3801] Minor doc and ty fixes --- compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index b8eb4f038216..7817755dafe4 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -445,9 +445,8 @@ fn declare_offload_fn<'ll>( // the gpu. For now, we only handle the data transfer part of it. // If two consecutive kernels use the same memory, we still move it to the host and back to the gpu. // Since in our frontend users (by default) don't have to specify data transfer, this is something -// we should optimize in the future! We also assume that everything should be copied back and forth, -// but sometimes we can directly zero-allocate on the device and only move back, or if something is -// immutable, we might only copy it to the device, but not back. +// we should optimize in the future! In some cases we can directly zero-allocate ont he device and +// only move data back, or if something is immutable, we might only copy it to the device. // // Current steps: // 0. Alloca some variables for the following steps From 2c9c5d14a210767f83358c6cb17c7a81ec7ae41c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelo=20Dom=C3=ADnguez?= Date: Tue, 6 Jan 2026 19:14:14 +0100 Subject: [PATCH 2115/3801] Allow bounded types --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 481f75f337d6..59cbcd78dd0f 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1388,7 +1388,8 @@ fn codegen_offload<'ll, 'tcx>( let args = get_args_from_tuple(bx, args[3], fn_target); let target_symbol = symbol_name_for_instance_in_crate(tcx, fn_target, LOCAL_CRATE); - let sig = tcx.fn_sig(fn_target.def_id()).skip_binder().skip_binder(); + let sig = tcx.fn_sig(fn_target.def_id()).instantiate_identity(); + let sig = tcx.instantiate_bound_regions_with_erased(sig); let inputs = sig.inputs(); let metadata = inputs.iter().map(|ty| OffloadMetadata::from_ty(tcx, *ty)).collect::>(); From 5769006794df86e3a27fedbc5317f695c0f153e6 Mon Sep 17 00:00:00 2001 From: dianqk Date: Wed, 14 Jan 2026 18:57:17 +0800 Subject: [PATCH 2116/3801] Run dummy_span.rs test with SimplifyComparisonIntegral --- tests/debuginfo/dummy_span.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/debuginfo/dummy_span.rs b/tests/debuginfo/dummy_span.rs index fec4f33e3d56..6cf79c46d9a9 100644 --- a/tests/debuginfo/dummy_span.rs +++ b/tests/debuginfo/dummy_span.rs @@ -1,6 +1,8 @@ //@ min-lldb-version: 310 //@ compile-flags:-g +// FIXME: Investigate why test fails without SimplifyComparisonIntegral pass. +//@ compile-flags: -Zmir-enable-passes=+SimplifyComparisonIntegral //@ ignore-backends: gcc // === GDB TESTS =================================================================================== From 4b5b42c82c1cf2095fcb183c72406eb82c908b21 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 14 Jan 2026 16:34:31 +0530 Subject: [PATCH 2117/3801] remove postcard from legacy --- .../src/bidirectional_protocol.rs | 9 +--- .../proc-macro-api/src/legacy_protocol.rs | 8 +--- .../crates/proc-macro-api/src/lib.rs | 3 -- .../crates/proc-macro-api/src/process.rs | 45 ++++++------------- .../crates/proc-macro-srv-cli/src/main.rs | 5 --- .../proc-macro-srv-cli/src/main_loop.rs | 1 - 6 files changed, 16 insertions(+), 55 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index e44723a6a389..5996f882981c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -212,14 +212,7 @@ fn run_request( if let Some(err) = srv.exited() { return Err(err.clone()); } - - match srv.use_postcard() { - true => srv.run_bidirectional::(msg, callback), - false => Err(ServerError { - message: "bidirectional messaging does not support JSON".to_owned(), - io: None, - }), - } + srv.run_bidirectional::(msg, callback) } pub fn reject_subrequests(req: SubRequest) -> Result { diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs index 4524d1b66bfe..aabe5a011851 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs @@ -19,7 +19,7 @@ use crate::{ }, process::ProcMacroServerProcess, transport::codec::Codec, - transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, + transport::codec::json::JsonProtocol, version, }; @@ -148,11 +148,7 @@ fn send_task(srv: &ProcMacroServerProcess, req: Request) -> Result(send_request::, req) - } else { - srv.send_task::<_, _, JsonProtocol>(send_request::, req) - } + srv.send_task::<_, _, JsonProtocol>(send_request::, req) } /// Sends a request to the server and reads the response. diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 822809943a36..01195c10feef 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -49,8 +49,6 @@ pub mod version { pub enum ProtocolFormat { /// JSON-based legacy protocol (newline-delimited JSON). JsonLegacy, - /// Postcard-based legacy protocol (COBS-encoded postcard). - PostcardLegacy, /// Bidirectional postcard protocol with sub-request support. BidirectionalPostcardPrototype, } @@ -59,7 +57,6 @@ impl fmt::Display for ProtocolFormat { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ProtocolFormat::JsonLegacy => write!(f, "json-legacy"), - ProtocolFormat::PostcardLegacy => write!(f, "postcard-legacy"), ProtocolFormat::BidirectionalPostcardPrototype => { write!(f, "bidirectional-postcard-prototype") } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index 4f8762158790..cd387dad0d0b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -43,7 +43,6 @@ impl std::fmt::Debug for ProcMacroServerProcess { #[derive(Debug, Clone)] pub(crate) enum Protocol { LegacyJson { mode: SpanMode }, - LegacyPostcard { mode: SpanMode }, BidirectionalPostcardPrototype { mode: SpanMode }, } @@ -136,7 +135,6 @@ impl ProcMacroServerProcess { { &[ Some(ProtocolFormat::BidirectionalPostcardPrototype), - Some(ProtocolFormat::PostcardLegacy), Some(ProtocolFormat::JsonLegacy), ] } else { @@ -155,9 +153,6 @@ impl ProcMacroServerProcess { Some(ProtocolFormat::BidirectionalPostcardPrototype) => { Protocol::BidirectionalPostcardPrototype { mode: SpanMode::Id } } - Some(ProtocolFormat::PostcardLegacy) => { - Protocol::LegacyPostcard { mode: SpanMode::Id } - } Some(ProtocolFormat::JsonLegacy) | None => { Protocol::LegacyJson { mode: SpanMode::Id } } @@ -185,7 +180,6 @@ impl ProcMacroServerProcess { { match &mut srv.protocol { Protocol::LegacyJson { mode } - | Protocol::LegacyPostcard { mode } | Protocol::BidirectionalPostcardPrototype { mode } => *mode = new_mode, } } @@ -208,10 +202,6 @@ impl ProcMacroServerProcess { self.exited.get().map(|it| &it.0) } - pub(crate) fn use_postcard(&self) -> bool { - matches!(self.protocol, Protocol::LegacyPostcard { .. }) - } - /// Retrieves the API version of the proc-macro server. pub(crate) fn version(&self) -> u32 { self.version @@ -221,7 +211,6 @@ impl ProcMacroServerProcess { pub(crate) fn rust_analyzer_spans(&self) -> bool { match self.protocol { Protocol::LegacyJson { mode } => mode == SpanMode::RustAnalyzer, - Protocol::LegacyPostcard { mode } => mode == SpanMode::RustAnalyzer, Protocol::BidirectionalPostcardPrototype { mode } => mode == SpanMode::RustAnalyzer, } } @@ -229,9 +218,7 @@ impl ProcMacroServerProcess { /// Checks the API version of the running proc-macro server. fn version_check(&self, callback: Option>) -> Result { match self.protocol { - Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { - legacy_protocol::version_check(self) - } + Protocol::LegacyJson { .. } => legacy_protocol::version_check(self), Protocol::BidirectionalPostcardPrototype { .. } => { let cb = callback.expect("callback required for bidirectional protocol"); bidirectional_protocol::version_check(self, cb) @@ -245,9 +232,7 @@ impl ProcMacroServerProcess { callback: Option>, ) -> Result { match self.protocol { - Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { - legacy_protocol::enable_rust_analyzer_spans(self) - } + Protocol::LegacyJson { .. } => legacy_protocol::enable_rust_analyzer_spans(self), Protocol::BidirectionalPostcardPrototype { .. } => { let cb = callback.expect("callback required for bidirectional protocol"); bidirectional_protocol::enable_rust_analyzer_spans(self, cb) @@ -262,9 +247,7 @@ impl ProcMacroServerProcess { callback: Option>, ) -> Result, String>, ServerError> { match self.protocol { - Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { - legacy_protocol::find_proc_macros(self, dylib_path) - } + Protocol::LegacyJson { .. } => legacy_protocol::find_proc_macros(self, dylib_path), Protocol::BidirectionalPostcardPrototype { .. } => { let cb = callback.expect("callback required for bidirectional protocol"); bidirectional_protocol::find_proc_macros(self, dylib_path, cb) @@ -285,18 +268,16 @@ impl ProcMacroServerProcess { callback: Option>, ) -> Result, ServerError> { match self.protocol { - Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { - legacy_protocol::expand( - proc_macro, - subtree, - attr, - env, - def_site, - call_site, - mixed_site, - current_dir, - ) - } + Protocol::LegacyJson { .. } => legacy_protocol::expand( + proc_macro, + subtree, + attr, + env, + def_site, + call_site, + mixed_site, + current_dir, + ), Protocol::BidirectionalPostcardPrototype { .. } => bidirectional_protocol::expand( proc_macro, subtree, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index a246d4d3f28f..928753659f1c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -67,7 +67,6 @@ impl ValueEnum for ProtocolFormatArg { fn value_variants<'a>() -> &'a [Self] { &[ ProtocolFormatArg(ProtocolFormat::JsonLegacy), - ProtocolFormatArg(ProtocolFormat::PostcardLegacy), ProtocolFormatArg(ProtocolFormat::BidirectionalPostcardPrototype), ] } @@ -75,9 +74,6 @@ impl ValueEnum for ProtocolFormatArg { fn to_possible_value(&self) -> Option { match self.0 { ProtocolFormat::JsonLegacy => Some(clap::builder::PossibleValue::new("json-legacy")), - ProtocolFormat::PostcardLegacy => { - Some(clap::builder::PossibleValue::new("postcard-legacy")) - } ProtocolFormat::BidirectionalPostcardPrototype => { Some(clap::builder::PossibleValue::new("bidirectional-postcard-prototype")) } @@ -87,7 +83,6 @@ impl ValueEnum for ProtocolFormatArg { fn from_str(input: &str, _ignore_case: bool) -> Result { match input { "json-legacy" => Ok(ProtocolFormatArg(ProtocolFormat::JsonLegacy)), - "postcard-legacy" => Ok(ProtocolFormatArg(ProtocolFormat::PostcardLegacy)), "bidirectional-postcard-prototype" => { Ok(ProtocolFormatArg(ProtocolFormat::BidirectionalPostcardPrototype)) } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 5180ede9fb90..70e1e091c197 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -41,7 +41,6 @@ pub fn run( ) -> io::Result<()> { match format { ProtocolFormat::JsonLegacy => run_old::(stdin, stdout), - ProtocolFormat::PostcardLegacy => run_old::(stdin, stdout), ProtocolFormat::BidirectionalPostcardPrototype => { run_new::(stdin, stdout) } From 31817f6deaf57c58f713bb61666d32bbd8306a3b Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 14 Jan 2026 16:34:57 +0530 Subject: [PATCH 2118/3801] remove flatten from ExpandMacro message in bidirectional messages --- .../crates/proc-macro-api/src/bidirectional_protocol/msg.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 57e7b1ee8f68..c56ed5191694 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -70,7 +70,6 @@ pub struct ExpandMacro { pub lib: Utf8PathBuf, pub env: Vec<(String, String)>, pub current_dir: Option, - #[serde(flatten)] pub data: ExpandMacroData, } From 98e1f7103b5d6bfcfcad849fa30a19614303160d Mon Sep 17 00:00:00 2001 From: Roberto Aloi Date: Wed, 14 Jan 2026 13:15:09 +0100 Subject: [PATCH 2119/3801] Bump camino to 1.2.2 --- src/tools/rust-analyzer/Cargo.lock | 4 ++-- src/tools/rust-analyzer/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index d6c6250e13dc..a2a18cf8eeea 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -178,9 +178,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "camino" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1de8bc0aa9e9385ceb3bf0c152e3a9b9544f6c4a912c8ae504e80c1f0368603" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" dependencies = [ "serde_core", ] diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 8003cb2fba8e..04b513b38b58 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -107,7 +107,7 @@ anyhow = "1.0.98" arrayvec = "0.7.6" bitflags = "2.9.1" cargo_metadata = "0.23.0" -camino = "1.1.10" +camino = "1.2.2" crossbeam-channel = "0.5.15" dissimilar = "1.0.10" dot = "0.1.4" From d0b760369f46eeb8ded4d7420d67d7bdc9f02dd1 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sat, 10 Jan 2026 17:06:21 +0800 Subject: [PATCH 2120/3801] Remove all usage of FeedConstTy::No --- .../src/hir_ty_lowering/bounds.rs | 34 ++++----- .../src/hir_ty_lowering/mod.rs | 53 +++++++++++--- compiler/rustc_hir_typeck/src/expr.rs | 5 +- src/librustdoc/clean/mod.rs | 70 ++++++++++++++++--- 4 files changed, 126 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 72d21371f66c..0a874b881801 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -510,7 +510,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Create the generic arguments for the associated type or constant by joining the // parent arguments (the arguments of the trait) and the own arguments (the ones of // the associated item itself) and construct an alias type using them. - let alias_term = candidate.map_bound(|trait_ref| { + candidate.map_bound(|trait_ref| { let item_segment = hir::PathSegment { ident: constraint.ident, hir_id: constraint.hir_id, @@ -528,20 +528,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(?alias_args); ty::AliasTerm::new_from_args(tcx, assoc_item.def_id, alias_args) - }); - - // Provide the resolved type of the associated constant to `type_of(AnonConst)`. - if let Some(const_arg) = constraint.ct() - && let hir::ConstArgKind::Anon(anon_const) = const_arg.kind - { - let ty = alias_term - .map_bound(|alias| tcx.type_of(alias.def_id).instantiate(tcx, alias.args)); - let ty = - check_assoc_const_binding_type(self, constraint.ident, ty, constraint.hir_id); - tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty)); - } - - alias_term + }) }; match constraint.kind { @@ -555,7 +542,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::AssocItemConstraintKind::Equality { term } => { let term = match term { hir::Term::Ty(ty) => self.lower_ty(ty).into(), - hir::Term::Const(ct) => self.lower_const_arg(ct, FeedConstTy::No).into(), + hir::Term::Const(ct) => { + // Provide the resolved type of the associated constant + let ty = projection_term.map_bound(|alias| { + tcx.type_of(alias.def_id).instantiate(tcx, alias.args) + }); + let ty = check_assoc_const_binding_type( + self, + constraint.ident, + ty, + constraint.hir_id, + ); + + self.lower_const_arg(ct, FeedConstTy::WithTy(ty)).into() + } }; // Find any late-bound regions declared in `ty` that are not @@ -871,7 +871,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// probably gate this behind another feature flag. /// /// [^1]: . -fn check_assoc_const_binding_type<'tcx>( +pub(crate) fn check_assoc_const_binding_type<'tcx>( cx: &dyn HirTyLowerer<'tcx>, assoc_const: Ident, ty: ty::Binder<'tcx, Ty<'tcx>>, 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 d2cbf89336d8..be5ac21e2ca8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1269,10 +1269,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut where_bounds = vec![]; for bound in [bound, bound2].into_iter().chain(matching_candidates) { let bound_id = bound.def_id(); - let bound_span = tcx - .associated_items(bound_id) - .find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id) - .and_then(|item| tcx.hir_span_if_local(item.def_id)); + let assoc_item = tcx.associated_items(bound_id).find_by_ident_and_kind( + tcx, + assoc_ident, + assoc_tag, + bound_id, + ); + let bound_span = assoc_item.and_then(|item| tcx.hir_span_if_local(item.def_id)); if let Some(bound_span) = bound_span { err.span_label( @@ -1285,7 +1288,41 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let term: ty::Term<'_> = match term { hir::Term::Ty(ty) => self.lower_ty(ty).into(), hir::Term::Const(ct) => { - self.lower_const_arg(ct, FeedConstTy::No).into() + let assoc_item = + assoc_item.expect("assoc_item should be present"); + let projection_term = bound.map_bound(|trait_ref| { + let item_segment = hir::PathSegment { + ident: constraint.ident, + hir_id: constraint.hir_id, + res: Res::Err, + args: Some(constraint.gen_args), + infer_args: false, + }; + + let alias_args = self.lower_generic_args_of_assoc_item( + constraint.ident.span, + assoc_item.def_id, + &item_segment, + trait_ref.args, + ); + ty::AliasTerm::new_from_args( + tcx, + assoc_item.def_id, + alias_args, + ) + }); + + let ty = projection_term.map_bound(|alias| { + tcx.type_of(alias.def_id).instantiate(tcx, alias.args) + }); + let ty = bounds::check_assoc_const_binding_type( + self, + constraint.ident, + ty, + constraint.hir_id, + ); + + self.lower_const_arg(ct, FeedConstTy::WithTy(ty)).into() } }; if term.references_error() { @@ -2993,7 +3030,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .unwrap_or_else(|guar| Ty::new_error(tcx, guar)) } hir::TyKind::Array(ty, length) => { - let length = self.lower_const_arg(length, FeedConstTy::No); + let length = self.lower_const_arg(length, FeedConstTy::WithTy(tcx.types.usize)); Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length) } hir::TyKind::Infer(()) => { @@ -3033,8 +3070,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Keep this list of types in sync with the list of types that // the `RangePattern` trait is implemented for. ty::Int(_) | ty::Uint(_) | ty::Char => { - let start = self.lower_const_arg(start, FeedConstTy::No); - let end = self.lower_const_arg(end, FeedConstTy::No); + let start = self.lower_const_arg(start, FeedConstTy::WithTy(ty)); + let end = self.lower_const_arg(end, FeedConstTy::WithTy(ty)); Ok(ty::PatternKind::Range { start, end }) } _ => Err(self diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9d7e09b020a7..d7366887d85c 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1749,7 +1749,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let count_span = count.span; let count = self.try_structurally_resolve_const( count_span, - self.normalize(count_span, self.lower_const_arg(count, FeedConstTy::No)), + self.normalize( + count_span, + self.lower_const_arg(count, FeedConstTy::WithTy(tcx.types.usize)), + ), ); if let Some(count) = count.try_to_target_usize(tcx) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 597a85f39769..ac17014ebfde 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -469,11 +469,23 @@ fn clean_middle_term<'tcx>( } } -fn clean_hir_term<'tcx>(term: &hir::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term { +fn clean_hir_term<'tcx>( + assoc_item: Option, + term: &hir::Term<'tcx>, + span: rustc_span::Span, + cx: &mut DocContext<'tcx>, +) -> Term { match term { hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)), hir::Term::Const(c) => { - let ct = lower_const_arg_for_rustdoc(cx.tcx, c, FeedConstTy::No); + let ty = if let Some(assoc_item) = assoc_item { + // FIXME(generic_const_items): this should instantiate with the alias item's args + cx.tcx.type_of(assoc_item).instantiate_identity() + } else { + Ty::new_error_with_message(cx.tcx, span, "cannot find the associated constant") + }; + + let ct = lower_const_arg_for_rustdoc(cx.tcx, c, FeedConstTy::WithTy(ty)); Term::Constant(clean_middle_const(ty::Binder::dummy(ct), cx)) } } @@ -650,7 +662,14 @@ fn clean_generic_param<'tcx>( GenericParamDefKind::Const { ty: Box::new(clean_ty(ty, cx)), default: default.map(|ct| { - Box::new(lower_const_arg_for_rustdoc(cx.tcx, ct, FeedConstTy::No).to_string()) + Box::new( + lower_const_arg_for_rustdoc( + cx.tcx, + ct, + FeedConstTy::WithTy(lower_ty(cx.tcx, ty)), + ) + .to_string(), + ) }), }, ), @@ -1531,7 +1550,7 @@ fn first_non_private_clean_path<'tcx>( && path_last.args.is_some() { assert!(new_path_last.args.is_empty()); - new_path_last.args = clean_generic_args(path_last_args, cx); + new_path_last.args = clean_generic_args(None, path_last_args, cx); } new_clean_path } @@ -1812,7 +1831,11 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T let length = match const_arg.kind { hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => "_".to_string(), hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) => { - let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); + let ct = lower_const_arg_for_rustdoc( + cx.tcx, + const_arg, + FeedConstTy::WithTy(cx.tcx.types.usize), + ); let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id); let ct = cx.tcx.normalize_erasing_regions(typing_env, ct); print_const(cx, ct) @@ -1823,7 +1846,11 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T | hir::ConstArgKind::Tup(..) | hir::ConstArgKind::Array(..) | hir::ConstArgKind::Literal(..) => { - let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); + let ct = lower_const_arg_for_rustdoc( + cx.tcx, + const_arg, + FeedConstTy::WithTy(cx.tcx.types.usize), + ); print_const(cx, ct) } }; @@ -2516,6 +2543,7 @@ fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path { } fn clean_generic_args<'tcx>( + trait_did: Option, generic_args: &hir::GenericArgs<'tcx>, cx: &mut DocContext<'tcx>, ) -> GenericArgs { @@ -2539,7 +2567,13 @@ fn clean_generic_args<'tcx>( let constraints = generic_args .constraints .iter() - .map(|c| clean_assoc_item_constraint(c, cx)) + .map(|c| { + clean_assoc_item_constraint( + trait_did.expect("only trait ref has constraints"), + c, + cx, + ) + }) .collect::>(); GenericArgs::AngleBracketed { args, constraints } } @@ -2562,7 +2596,11 @@ fn clean_path_segment<'tcx>( path: &hir::PathSegment<'tcx>, cx: &mut DocContext<'tcx>, ) -> PathSegment { - PathSegment { name: path.ident.name, args: clean_generic_args(path.args(), cx) } + let trait_did = match path.res { + hir::def::Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did), + _ => None, + }; + PathSegment { name: path.ident.name, args: clean_generic_args(trait_did, path.args(), cx) } } fn clean_bare_fn_ty<'tcx>( @@ -3126,17 +3164,29 @@ fn clean_maybe_renamed_foreign_item<'tcx>( } fn clean_assoc_item_constraint<'tcx>( + trait_did: DefId, constraint: &hir::AssocItemConstraint<'tcx>, cx: &mut DocContext<'tcx>, ) -> AssocItemConstraint { AssocItemConstraint { assoc: PathSegment { name: constraint.ident.name, - args: clean_generic_args(constraint.gen_args, cx), + args: clean_generic_args(None, constraint.gen_args, cx), }, kind: match constraint.kind { hir::AssocItemConstraintKind::Equality { ref term } => { - AssocItemConstraintKind::Equality { term: clean_hir_term(term, cx) } + let assoc_tag = match term { + hir::Term::Ty(_) => ty::AssocTag::Type, + hir::Term::Const(_) => ty::AssocTag::Const, + }; + let assoc_item = cx + .tcx + .associated_items(trait_did) + .find_by_ident_and_kind(cx.tcx, constraint.ident, assoc_tag, trait_did) + .map(|item| item.def_id); + AssocItemConstraintKind::Equality { + term: clean_hir_term(assoc_item, term, constraint.span, cx), + } } hir::AssocItemConstraintKind::Bound { bounds } => AssocItemConstraintKind::Bound { bounds: bounds.iter().filter_map(|b| clean_generic_bound(b, cx)).collect(), From e27fcfd28eb6b185894e38d1f9fbde216f026f3e Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sun, 11 Jan 2026 18:43:25 +0800 Subject: [PATCH 2121/3801] Remove FeedConstTy --- compiler/rustc_hir_analysis/src/collect.rs | 8 +- .../src/hir_ty_lowering/bounds.rs | 5 +- .../src/hir_ty_lowering/mod.rs | 89 +++++-------------- compiler/rustc_hir_analysis/src/lib.rs | 6 +- compiler/rustc_hir_typeck/src/expr.rs | 7 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 13 +-- .../rustc_hir_typeck/src/method/confirm.rs | 7 +- src/librustdoc/clean/mod.rs | 22 +---- 8 files changed, 48 insertions(+), 109 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index bacdf0049806..2c0253409387 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -47,9 +47,7 @@ use rustc_trait_selection::traits::{ use tracing::{debug, instrument}; use crate::errors; -use crate::hir_ty_lowering::{ - FeedConstTy, HirTyLowerer, InherentAssocCandidate, RegionInferReason, -}; +use crate::hir_ty_lowering::{HirTyLowerer, InherentAssocCandidate, RegionInferReason}; pub(crate) mod dump; mod generics_of; @@ -1499,7 +1497,7 @@ fn const_param_default<'tcx>( let ct = icx .lowerer() - .lower_const_arg(default_ct, FeedConstTy::with_type_of(tcx, def_id, identity_args)); + .lower_const_arg(default_ct, tcx.type_of(def_id).instantiate(tcx, identity_args)); ty::EarlyBinder::bind(ct) } @@ -1557,7 +1555,7 @@ fn const_of_item<'tcx>( let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let ct = icx .lowerer() - .lower_const_arg(ct_arg, FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args)); + .lower_const_arg(ct_arg, tcx.type_of(def_id.to_def_id()).instantiate(tcx, identity_args)); if let Err(e) = icx.check_tainted_by_errors() && !ct.references_error() { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 0a874b881801..d6441702b268 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -20,7 +20,7 @@ use tracing::{debug, instrument}; use crate::errors; use crate::hir_ty_lowering::{ - AssocItemQSelf, FeedConstTy, GenericsArgsErrExtend, HirTyLowerer, ImpliedBoundsContext, + AssocItemQSelf, GenericsArgsErrExtend, HirTyLowerer, ImpliedBoundsContext, OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason, }; @@ -543,7 +543,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let term = match term { hir::Term::Ty(ty) => self.lower_ty(ty).into(), hir::Term::Const(ct) => { - // Provide the resolved type of the associated constant let ty = projection_term.map_bound(|alias| { tcx.type_of(alias.def_id).instantiate(tcx, alias.args) }); @@ -554,7 +553,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { constraint.hir_id, ); - self.lower_const_arg(ct, FeedConstTy::WithTy(ty)).into() + self.lower_const_arg(ct, ty).into() } }; 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 be5ac21e2ca8..3dcc0232b301 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -253,35 +253,6 @@ impl AssocItemQSelf { } } -/// In some cases, [`hir::ConstArg`]s that are being used in the type system -/// through const generics need to have their type "fed" to them -/// using the query system. -/// -/// Use this enum with `::lower_const_arg` to instruct it with the -/// desired behavior. -#[derive(Debug, Clone, Copy)] -pub enum FeedConstTy<'tcx> { - /// Feed the type to the (anno) const arg. - WithTy(Ty<'tcx>), - /// Don't feed the type. - No, -} - -impl<'tcx> FeedConstTy<'tcx> { - /// The `DefId` belongs to the const param that we are supplying - /// this (anon) const arg to. - /// - /// The list of generic args is used to instantiate the parameters - /// used by the type of the const param specified by `DefId`. - pub fn with_type_of( - tcx: TyCtxt<'tcx>, - def_id: DefId, - generic_args: &[ty::GenericArg<'tcx>], - ) -> Self { - Self::WithTy(tcx.type_of(def_id).instantiate(tcx, generic_args)) - } -} - #[derive(Debug, Clone, Copy)] enum LowerTypeRelativePathMode { Type(PermitVariants), @@ -733,7 +704,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Ambig portions of `ConstArg` are handled in the match arm below .lower_const_arg( ct.as_unambig_ct(), - FeedConstTy::with_type_of(tcx, param.def_id, preceding_args), + tcx.type_of(param.def_id).instantiate(tcx, preceding_args), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { @@ -1322,7 +1293,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { constraint.hir_id, ); - self.lower_const_arg(ct, FeedConstTy::WithTy(ty)).into() + self.lower_const_arg(ct, ty).into() } }; if term.references_error() { @@ -2347,16 +2318,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Lower a [`hir::ConstArg`] to a (type-level) [`ty::Const`](Const). #[instrument(skip(self), level = "debug")] - pub fn lower_const_arg( - &self, - const_arg: &hir::ConstArg<'tcx>, - feed: FeedConstTy<'tcx>, - ) -> Const<'tcx> { + pub fn lower_const_arg(&self, const_arg: &hir::ConstArg<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { let tcx = self.tcx(); - if let FeedConstTy::WithTy(anon_const_type) = feed - && let hir::ConstArgKind::Anon(anon) = &const_arg.kind - { + if let hir::ConstArgKind::Anon(anon) = &const_arg.kind { // FIXME(generic_const_parameter_types): Ideally we remove these errors below when // we have the ability to intermix typeck of anon const const args with the parent // bodies typeck. @@ -2366,7 +2331,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // hir typeck was using equality but mir borrowck wound up using subtyping as that could // result in a non-infer in hir typeck but a region variable in borrowck. if tcx.features().generic_const_parameter_types() - && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions()) + && (ty.has_free_regions() || ty.has_erased_regions()) { let e = self.dcx().span_err( const_arg.span, @@ -2378,7 +2343,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // We must error if the instantiated type has any inference variables as we will // use this type to feed the `type_of` and query results must not contain inference // variables otherwise we will ICE. - if anon_const_type.has_non_region_infer() { + if ty.has_non_region_infer() { let e = self.dcx().span_err( const_arg.span, "anonymous constants with inferred types are not yet supported", @@ -2388,7 +2353,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } // We error when the type contains unsubstituted generics since we do not currently // give the anon const any of the generics from the parent. - if anon_const_type.has_non_region_param() { + if ty.has_non_region_param() { let e = self.dcx().span_err( const_arg.span, "anonymous constants referencing generics are not yet supported", @@ -2397,12 +2362,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return ty::Const::new_error(tcx, e); } - tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(anon_const_type)); + tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(ty)); } let hir_id = const_arg.hir_id; match const_arg.kind { - hir::ConstArgKind::Tup(exprs) => self.lower_const_arg_tup(exprs, feed, const_arg.span), + hir::ConstArgKind::Tup(exprs) => self.lower_const_arg_tup(exprs, ty, const_arg.span), hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => { debug!(?maybe_qself, ?path); let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself)); @@ -2426,16 +2391,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::ConstArgKind::TupleCall(qpath, args) => { self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span) } - hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, feed), + hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, ty), hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span), hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e), - hir::ConstArgKind::Literal(kind) if let FeedConstTy::WithTy(anon_const_type) = feed => { - self.lower_const_arg_literal(&kind, anon_const_type, const_arg.span) - } - hir::ConstArgKind::Literal(..) => { - let e = self.dcx().span_err(const_arg.span, "literal of unknown type"); - ty::Const::new_error(tcx, e) + hir::ConstArgKind::Literal(kind) => { + self.lower_const_arg_literal(&kind, ty, const_arg.span) } } } @@ -2443,14 +2404,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn lower_const_arg_array( &self, array_expr: &'tcx hir::ConstArgArrayExpr<'tcx>, - feed: FeedConstTy<'tcx>, + ty: Ty<'tcx>, ) -> Const<'tcx> { let tcx = self.tcx(); - let FeedConstTy::WithTy(ty) = feed else { - return Const::new_error_with_message(tcx, array_expr.span, "unsupported const array"); - }; - let ty::Array(elem_ty, _) = ty.kind() else { return Const::new_error_with_message( tcx, @@ -2462,7 +2419,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let elems = array_expr .elems .iter() - .map(|elem| self.lower_const_arg(elem, FeedConstTy::WithTy(*elem_ty))) + .map(|elem| self.lower_const_arg(elem, *elem_ty)) .collect::>(); let valtree = ty::ValTree::from_branches(tcx, elems); @@ -2545,7 +2502,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .zip(args) .map(|(field_def, arg)| { - self.lower_const_arg(arg, FeedConstTy::with_type_of(tcx, field_def.did, adt_args)) + self.lower_const_arg(arg, tcx.type_of(field_def.did).instantiate(tcx, adt_args)) }) .collect::>(); @@ -2564,15 +2521,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn lower_const_arg_tup( &self, exprs: &'tcx [&'tcx hir::ConstArg<'tcx>], - feed: FeedConstTy<'tcx>, + ty: Ty<'tcx>, span: Span, ) -> Const<'tcx> { let tcx = self.tcx(); - let FeedConstTy::WithTy(ty) = feed else { - return Const::new_error_with_message(tcx, span, "const tuple lack type information"); - }; - let ty::Tuple(tys) = ty.kind() else { let e = tcx.dcx().span_err(span, format!("expected `{}`, found const tuple", ty)); return Const::new_error(tcx, e); @@ -2581,7 +2534,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let exprs = exprs .iter() .zip(tys.iter()) - .map(|(expr, ty)| self.lower_const_arg(expr, FeedConstTy::WithTy(ty))) + .map(|(expr, ty)| self.lower_const_arg(expr, ty)) .collect::>(); let valtree = ty::ValTree::from_branches(tcx, exprs); @@ -2668,7 +2621,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.lower_const_arg( expr.expr, - FeedConstTy::with_type_of(tcx, field_def.did, adt_args), + tcx.type_of(field_def.did).instantiate(tcx, adt_args), ) } None => { @@ -3030,7 +2983,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .unwrap_or_else(|guar| Ty::new_error(tcx, guar)) } hir::TyKind::Array(ty, length) => { - let length = self.lower_const_arg(length, FeedConstTy::WithTy(tcx.types.usize)); + let length = self.lower_const_arg(length, tcx.types.usize); Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length) } hir::TyKind::Infer(()) => { @@ -3070,8 +3023,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Keep this list of types in sync with the list of types that // the `RangePattern` trait is implemented for. ty::Int(_) | ty::Uint(_) | ty::Char => { - let start = self.lower_const_arg(start, FeedConstTy::WithTy(ty)); - let end = self.lower_const_arg(end, FeedConstTy::WithTy(ty)); + let start = self.lower_const_arg(start, ty); + let end = self.lower_const_arg(end, ty); Ok(ty::PatternKind::Range { start, end }) } _ => Err(self diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 7296ba6f964a..a51355adf72f 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -101,7 +101,7 @@ use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits; pub use crate::collect::suggest_impl_trait; -use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer}; +use crate::hir_ty_lowering::HirTyLowerer; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } @@ -301,8 +301,8 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { pub fn lower_const_arg_for_rustdoc<'tcx>( tcx: TyCtxt<'tcx>, hir_ct: &hir::ConstArg<'tcx>, - feed: FeedConstTy<'tcx>, + ty: Ty<'tcx>, ) -> Const<'tcx> { let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id); - collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed) + collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, ty) } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index d7366887d85c..9f3ff0b2d03c 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -21,7 +21,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, HirId, QPath, find_attr, is_range_literal}; use rustc_hir_analysis::NoVariantNamed; -use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _}; +use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _; use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk, RegionVariableOrigin}; use rustc_infer::traits::query::NoSolution; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; @@ -1749,10 +1749,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let count_span = count.span; let count = self.try_structurally_resolve_const( count_span, - self.normalize( - count_span, - self.lower_const_arg(count, FeedConstTy::WithTy(tcx.types.usize)), - ), + self.normalize(count_span, self.lower_const_arg(count, tcx.types.usize)), ); if let Some(count) = count.try_to_target_usize(tcx) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index a66ff2a23c25..91f91d911444 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -14,8 +14,8 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{ check_generic_arg_count_for_call, lower_generic_args, }; use rustc_hir_analysis::hir_ty_lowering::{ - ExplicitLateBound, FeedConstTy, GenericArgCountMismatch, GenericArgCountResult, - GenericArgsLowerer, GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason, + ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer, + GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason, }; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::{DefineOpaqueTypes, InferResult}; @@ -525,9 +525,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn lower_const_arg( &self, const_arg: &'tcx hir::ConstArg<'tcx>, - feed: FeedConstTy<'tcx>, + ty: Ty<'tcx>, ) -> ty::Const<'tcx> { - let ct = self.lowerer().lower_const_arg(const_arg, feed); + let ct = self.lowerer().lower_const_arg(const_arg, ty); self.register_wf_obligation( ct.into(), self.tcx.hir_span(const_arg.hir_id), @@ -1228,7 +1228,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Ambiguous parts of `ConstArg` are handled in the match arms below .lower_const_arg( ct.as_unambig_ct(), - FeedConstTy::with_type_of(self.fcx.tcx, param.def_id, preceding_args), + self.fcx + .tcx + .type_of(param.def_id) + .instantiate(self.fcx.tcx, preceding_args), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index aab4e3985555..270f011b2b15 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -7,7 +7,7 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{ check_generic_arg_count_for_call, lower_generic_args, }; use rustc_hir_analysis::hir_ty_lowering::{ - FeedConstTy, GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason, + GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason, }; use rustc_infer::infer::{ BoundRegionConversionTime, DefineOpaqueTypes, InferOk, RegionVariableOrigin, @@ -447,7 +447,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // We handle the ambig portions of `ConstArg` in the match arms below .lower_const_arg( ct.as_unambig_ct(), - FeedConstTy::with_type_of(self.cfcx.tcx, param.def_id, preceding_args), + self.cfcx + .tcx + .type_of(param.def_id) + .instantiate(self.cfcx.tcx, preceding_args), ) .into(), (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ac17014ebfde..c7c23f75d694 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -43,7 +43,6 @@ use rustc_hir::attrs::{AttributeKind, DocAttribute, DocInline}; use rustc_hir::def::{CtorKind, DefKind, MacroKinds, Res}; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId}; use rustc_hir::{LangItem, PredicateOrigin, find_attr}; -use rustc_hir_analysis::hir_ty_lowering::FeedConstTy; use rustc_hir_analysis::{lower_const_arg_for_rustdoc, lower_ty}; use rustc_middle::metadata::Reexport; use rustc_middle::middle::resolve_bound_vars as rbv; @@ -485,7 +484,7 @@ fn clean_hir_term<'tcx>( Ty::new_error_with_message(cx.tcx, span, "cannot find the associated constant") }; - let ct = lower_const_arg_for_rustdoc(cx.tcx, c, FeedConstTy::WithTy(ty)); + let ct = lower_const_arg_for_rustdoc(cx.tcx, c, ty); Term::Constant(clean_middle_const(ty::Binder::dummy(ct), cx)) } } @@ -663,12 +662,7 @@ fn clean_generic_param<'tcx>( ty: Box::new(clean_ty(ty, cx)), default: default.map(|ct| { Box::new( - lower_const_arg_for_rustdoc( - cx.tcx, - ct, - FeedConstTy::WithTy(lower_ty(cx.tcx, ty)), - ) - .to_string(), + lower_const_arg_for_rustdoc(cx.tcx, ct, lower_ty(cx.tcx, ty)).to_string(), ) }), }, @@ -1831,11 +1825,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T let length = match const_arg.kind { hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => "_".to_string(), hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) => { - let ct = lower_const_arg_for_rustdoc( - cx.tcx, - const_arg, - FeedConstTy::WithTy(cx.tcx.types.usize), - ); + let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, cx.tcx.types.usize); let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id); let ct = cx.tcx.normalize_erasing_regions(typing_env, ct); print_const(cx, ct) @@ -1846,11 +1836,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T | hir::ConstArgKind::Tup(..) | hir::ConstArgKind::Array(..) | hir::ConstArgKind::Literal(..) => { - let ct = lower_const_arg_for_rustdoc( - cx.tcx, - const_arg, - FeedConstTy::WithTy(cx.tcx.types.usize), - ); + let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, cx.tcx.types.usize); print_const(cx, ct) } }; From 37f20b7631c6a6c712f0c19a91531623282d6507 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sun, 11 Jan 2026 21:02:00 +0800 Subject: [PATCH 2122/3801] Bless tests --- .../associated-const-bindings/ambiguity.stderr | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr b/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr index a14afe9d6923..806708f18d65 100644 --- a/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr +++ b/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr @@ -27,6 +27,12 @@ LL | const C: &'static str; ... LL | fn take1(_: impl Trait1) {} | ^^^^^^^ ambiguous associated constant `C` + | + = help: consider introducing a new type parameter `T` and adding `where` constraints: + where + T: Trait1, + T: Parent2::C = "?", + T: Parent1::C = "?" error: aborting due to 2 previous errors From 80bd069138feba6452059852785bb913a7dba66c Mon Sep 17 00:00:00 2001 From: mu001999 Date: Mon, 12 Jan 2026 23:50:32 +0800 Subject: [PATCH 2123/3801] Fix review comments --- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 ++ src/librustdoc/clean/mod.rs | 14 +++----------- 2 files changed, 5 insertions(+), 11 deletions(-) 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 3dcc0232b301..65d2d61e6fc4 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1283,6 +1283,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) }); + // FIXME(mgca): code duplication with other places we lower + // the rhs' of associated const bindings let ty = projection_term.map_bound(|alias| { tcx.type_of(alias.def_id).instantiate(tcx, alias.args) }); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c7c23f75d694..0ad9d2fdbe80 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -471,19 +471,13 @@ fn clean_middle_term<'tcx>( fn clean_hir_term<'tcx>( assoc_item: Option, term: &hir::Term<'tcx>, - span: rustc_span::Span, cx: &mut DocContext<'tcx>, ) -> Term { match term { hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)), hir::Term::Const(c) => { - let ty = if let Some(assoc_item) = assoc_item { - // FIXME(generic_const_items): this should instantiate with the alias item's args - cx.tcx.type_of(assoc_item).instantiate_identity() - } else { - Ty::new_error_with_message(cx.tcx, span, "cannot find the associated constant") - }; - + // FIXME(generic_const_items): this should instantiate with the alias item's args + let ty = cx.tcx.type_of(assoc_item.unwrap()).instantiate_identity(); let ct = lower_const_arg_for_rustdoc(cx.tcx, c, ty); Term::Constant(clean_middle_const(ty::Binder::dummy(ct), cx)) } @@ -3170,9 +3164,7 @@ fn clean_assoc_item_constraint<'tcx>( .associated_items(trait_did) .find_by_ident_and_kind(cx.tcx, constraint.ident, assoc_tag, trait_did) .map(|item| item.def_id); - AssocItemConstraintKind::Equality { - term: clean_hir_term(assoc_item, term, constraint.span, cx), - } + AssocItemConstraintKind::Equality { term: clean_hir_term(assoc_item, term, cx) } } hir::AssocItemConstraintKind::Bound { bounds } => AssocItemConstraintKind::Bound { bounds: bounds.iter().filter_map(|b| clean_generic_bound(b, cx)).collect(), From 12b4b72715b5814ab48fc4c78169fd6cef0ccc25 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Tue, 13 Jan 2026 20:53:48 +0800 Subject: [PATCH 2124/3801] Add test for issue 151048 --- .../mgca/tuple_expr_arg_bad-issue-151048.rs | 8 ++++++++ .../mgca/tuple_expr_arg_bad-issue-151048.stderr | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs create mode 100644 tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs new file mode 100644 index 000000000000..4aecd30e86bb --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs @@ -0,0 +1,8 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +struct Y { + stuff: [u8; { ([1, 2], 3, [4, 5]) }], //~ ERROR expected `usize`, found const tuple +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr new file mode 100644 index 000000000000..468bf703d90d --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr @@ -0,0 +1,8 @@ +error: expected `usize`, found const tuple + --> $DIR/tuple_expr_arg_bad-issue-151048.rs:5:19 + | +LL | stuff: [u8; { ([1, 2], 3, [4, 5]) }], + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From 2b209a69cf97c18ecef9043abf3ec8b6fe9867b9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 14 Jan 2026 13:21:16 +0000 Subject: [PATCH 2125/3801] Avoid serde dependency in build_helper when not necessary --- src/bootstrap/Cargo.toml | 2 +- src/build_helper/Cargo.toml | 7 +++++-- src/build_helper/src/lib.rs | 1 + src/ci/citool/Cargo.toml | 2 +- src/tools/opt-dist/Cargo.toml | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index e1725db60cfc..e66c0576e9ee 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -6,7 +6,7 @@ build = "build.rs" default-run = "bootstrap" [features] -build-metrics = ["sysinfo"] +build-metrics = ["dep:sysinfo", "build_helper/metrics"] tracing = ["dep:tracing", "dep:tracing-chrome", "dep:tracing-subscriber", "dep:chrono", "dep:tempfile"] [lib] diff --git a/src/build_helper/Cargo.toml b/src/build_helper/Cargo.toml index 66894e1abc40..2ec44fe2730b 100644 --- a/src/build_helper/Cargo.toml +++ b/src/build_helper/Cargo.toml @@ -6,5 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde = "1" -serde_derive = "1" +serde = { version = "1", optional = true } +serde_derive = { version = "1", optional = true } + +[features] +metrics = ["dep:serde", "dep:serde_derive"] diff --git a/src/build_helper/src/lib.rs b/src/build_helper/src/lib.rs index 266eedc62458..e23a158ac059 100644 --- a/src/build_helper/src/lib.rs +++ b/src/build_helper/src/lib.rs @@ -4,6 +4,7 @@ pub mod ci; pub mod drop_bomb; pub mod fs; pub mod git; +#[cfg(feature = "metrics")] pub mod metrics; pub mod npm; pub mod stage0_parser; diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index 468d8c8a02aa..539edf60033a 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -15,7 +15,7 @@ serde_yaml = "0.9" serde_json = "1" ureq = { version = "3", features = ["json"] } -build_helper = { path = "../../build_helper" } +build_helper = { path = "../../build_helper", features = ["metrics"] } [dev-dependencies] insta = "1" diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml index f4051ae67d7c..66c19183f343 100644 --- a/src/tools/opt-dist/Cargo.toml +++ b/src/tools/opt-dist/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2024" [dependencies] -build_helper = { path = "../../build_helper" } +build_helper = { path = "../../build_helper", features = ["metrics"] } env_logger = "0.11" log = "0.4" anyhow = "1" From 7d80e7d720162fed8223407e91912683631c93f2 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 14 Jan 2026 23:12:57 +0900 Subject: [PATCH 2126/3801] rustc_target: Remove unused Arch::PowerPC64LE target_arch for powerpc64le- targets is "powerpc64". --- compiler/rustc_codegen_llvm/src/mono_item.rs | 2 +- compiler/rustc_codegen_llvm/src/va_arg.rs | 9 --------- compiler/rustc_span/src/symbol.rs | 1 - compiler/rustc_target/src/asm/mod.rs | 2 +- compiler/rustc_target/src/callconv/mod.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 7 ++----- compiler/rustc_target/src/target_features.rs | 8 +------- src/tools/miri/src/shims/alloc.rs | 1 - 8 files changed, 6 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 1878f4043ee8..838db689e729 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -144,7 +144,7 @@ impl CodegenCx<'_, '_> { } // PowerPC64 prefers TOC indirection to avoid copy relocations. - if matches!(self.tcx.sess.target.arch, Arch::PowerPC64 | Arch::PowerPC64LE) { + if self.tcx.sess.target.arch == Arch::PowerPC64 { return false; } diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 688f461e7478..c7da2457ada5 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -1064,15 +1064,6 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( AllowHigherAlign::Yes, ForceRightAdjust::Yes, ), - Arch::PowerPC64LE => emit_ptr_va_arg( - bx, - addr, - target_ty, - PassMode::Direct, - SlotSize::Bytes8, - AllowHigherAlign::Yes, - ForceRightAdjust::No, - ), Arch::LoongArch32 => emit_ptr_va_arg( bx, addr, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b473d36a45fc..c4f77cedbe09 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1723,7 +1723,6 @@ symbols! { postfix_match, powerpc, powerpc64, - powerpc64le, powerpc_target_feature, powf16, powf32, diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 0078866ab950..a10699bbce88 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -261,7 +261,7 @@ impl InlineAsmArch { Arch::Mips | Arch::Mips32r6 => Some(Self::Mips), Arch::Mips64 | Arch::Mips64r6 => Some(Self::Mips64), Arch::PowerPC => Some(Self::PowerPC), - Arch::PowerPC64 | Arch::PowerPC64LE => Some(Self::PowerPC64), + Arch::PowerPC64 => Some(Self::PowerPC64), Arch::S390x => Some(Self::S390x), Arch::Sparc => Some(Self::Sparc), Arch::Sparc64 => Some(Self::Sparc64), diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 6faa57252ca2..6c8e0e181c4a 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -702,7 +702,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { Arch::RiscV32 | Arch::RiscV64 => riscv::compute_abi_info(cx, self), Arch::Wasm32 | Arch::Wasm64 => wasm::compute_abi_info(cx, self), Arch::Bpf => bpf::compute_abi_info(cx, self), - arch @ (Arch::PowerPC64LE | Arch::SpirV | Arch::Other(_)) => { + arch @ (Arch::SpirV | Arch::Other(_)) => { panic!("no lowering implemented for {arch}") } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 89c9fdc935cc..57effe3a8668 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1873,7 +1873,6 @@ crate::target_spec_enum! { Nvptx64 = "nvptx64", PowerPC = "powerpc", PowerPC64 = "powerpc64", - PowerPC64LE = "powerpc64le", RiscV32 = "riscv32", RiscV64 = "riscv64", S390x = "s390x", @@ -1911,7 +1910,6 @@ impl Arch { Self::Nvptx64 => sym::nvptx64, Self::PowerPC => sym::powerpc, Self::PowerPC64 => sym::powerpc64, - Self::PowerPC64LE => sym::powerpc64le, Self::RiscV32 => sym::riscv32, Self::RiscV64 => sym::riscv64, Self::S390x => sym::s390x, @@ -1940,8 +1938,8 @@ impl Arch { AArch64 | AmdGpu | Arm | Arm64EC | Avr | CSky | Hexagon | LoongArch32 | LoongArch64 | M68k | Mips | Mips32r6 | Mips64 | Mips64r6 | Msp430 | Nvptx64 | PowerPC - | PowerPC64 | PowerPC64LE | RiscV32 | RiscV64 | S390x | Sparc | Sparc64 | Wasm32 - | Wasm64 | X86 | X86_64 | Xtensa => true, + | PowerPC64 | RiscV32 | RiscV64 | S390x | Sparc | Sparc64 | Wasm32 | Wasm64 | X86 + | X86_64 | Xtensa => true, } } } @@ -3436,7 +3434,6 @@ impl Target { Arch::Arm64EC => (Architecture::Aarch64, Some(object::SubArchitecture::Arm64EC)), Arch::AmdGpu | Arch::Nvptx64 - | Arch::PowerPC64LE | Arch::SpirV | Arch::Wasm32 | Arch::Wasm64 diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 40cc4f40a333..4eba426dda59 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -986,7 +986,6 @@ impl Target { Arch::AmdGpu | Arch::Avr | Arch::Msp430 - | Arch::PowerPC64LE | Arch::SpirV | Arch::Xtensa | Arch::Other(_) => &[], @@ -1015,12 +1014,7 @@ impl Target { Arch::CSky => CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, // FIXME: for some tier3 targets, we are overly cautious and always give warnings // when passing args in vector registers. - Arch::Avr - | Arch::Msp430 - | Arch::PowerPC64LE - | Arch::SpirV - | Arch::Xtensa - | Arch::Other(_) => &[], + Arch::Avr | Arch::Msp430 | Arch::SpirV | Arch::Xtensa | Arch::Other(_) => &[], } } diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 94649dde4736..b4d53c36d19b 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -52,7 +52,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | Arch::Bpf | Arch::Msp430 | Arch::Nvptx64 - | Arch::PowerPC64LE | Arch::SpirV | Arch::Other(_)) => bug!("unsupported target architecture for malloc: `{arch}`"), }; From c1bcae06384b1e6e0c1ddb25970df5eb77024084 Mon Sep 17 00:00:00 2001 From: Colin Murphy Date: Mon, 12 Jan 2026 10:45:24 -0500 Subject: [PATCH 2127/3801] Fix WASI threading regression with minimal invasive change Recent changes made WASI targets use the Unix threading implementation, but WASI does not support threading. When the Unix code tries to call pthread_create, it fails with EAGAIN, causing libraries like rayon to panic when trying to initialize their global thread pool. This fix adds an early return in Thread::new() that checks for WASI and returns UNSUPPORTED_PLATFORM. This approach: - Continues using most of the unix.rs code path (less invasive) - Only requires a small cfg check at the start of Thread::new() - Can be easily removed once wasi-sdk is updated with the proper fix The real fix is being tracked in `WebAssembly/wasi-libc#716` which will change the error code returned by pthread_create to properly indicate unsupported operations. Once that propagates to wasi-sdk, this workaround can be removed. Fixes the regression where rayon-based code (e.g., lopdf in PDF handling) panicked on WASI after nightly-2025-12-10. Before fix: pthread_create returns EAGAIN (error code 6) ThreadPoolBuildError { kind: IOError(Os { code: 6, kind: WouldBlock, message: "Resource temporarily unavailable" }) } After fix: Thread::new returns Err(io::Error::UNSUPPORTED_PLATFORM) Libraries can gracefully handle the lack of threading support --- library/std/src/sys/thread/unix.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index d0396ed71300..f0cfdb956392 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -45,6 +45,15 @@ impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn new(stack: usize, init: Box) -> io::Result { + // FIXME: remove this block once wasi-sdk is updated with the fix from + // https://github.com/WebAssembly/wasi-libc/pull/716 + // WASI does not support threading via pthreads. While wasi-libc provides + // pthread stubs, pthread_create returns EAGAIN, which causes confusing + // errors. We return UNSUPPORTED_PLATFORM directly instead. + if cfg!(target_os = "wasi") { + return Err(io::Error::UNSUPPORTED_PLATFORM); + } + let data = init; let mut attr: mem::MaybeUninit = mem::MaybeUninit::uninit(); assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0); From 0d8aa8991c33f7dec592856760b3a1c32251bfba Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 14 Jan 2026 09:16:17 +0100 Subject: [PATCH 2128/3801] fix: Fix path symbol search not respecting re-exports --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 17 ++++ .../crates/ide-db/src/symbol_index.rs | 97 ++++++++++++++----- 2 files changed, 91 insertions(+), 23 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 78be5a7e8fa9..252d71fb80a4 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -610,6 +610,23 @@ impl Module { res } + pub fn modules_in_scope(&self, db: &dyn HirDatabase, pub_only: bool) -> Vec<(Name, Module)> { + let def_map = self.id.def_map(db); + let scope = &def_map[self.id].scope; + + let mut res = Vec::new(); + + for (name, item) in scope.types() { + if let ModuleDefId::ModuleId(m) = item.def + && (!pub_only || item.vis == Visibility::Public) + { + res.push((name.clone(), Module { id: m })); + } + } + + res + } + /// Returns a `ModuleScope`: a set of items, visible in this module. pub fn scope( self, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index c95b541748ec..d7f4c66f465b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -35,6 +35,7 @@ use hir::{ import_map::{AssocSearchMode, SearchMode}, symbols::{FileSymbol, SymbolCollector}, }; +use itertools::Itertools; use rayon::prelude::*; use salsa::Update; @@ -224,12 +225,10 @@ pub fn world_symbols(db: &RootDatabase, mut query: Query) -> Vec> // Search for crates by name (handles "::" and "::foo" queries) let indices: Vec<_> = if query.is_crate_search() { query.only_types = false; - query.libs = true; vec![SymbolIndex::extern_prelude_symbols(db)] // If we have a path filter, resolve it to target modules } else if !query.path_filter.is_empty() { query.only_types = false; - query.libs = true; let target_modules = resolve_path_to_modules( db, &query.path_filter, @@ -313,11 +312,11 @@ fn resolve_path_to_modules( // If anchor_to_crate is true, first segment MUST be a crate name // If anchor_to_crate is false, first segment could be a crate OR a module in local crates - let mut candidate_modules: Vec = vec![]; + let mut candidate_modules: Vec<(Module, bool)> = vec![]; // Add crate root modules for matching crates for krate in matching_crates { - candidate_modules.push(krate.root_module(db)); + candidate_modules.push((krate.root_module(db), krate.origin(db).is_local())); } // If not anchored to crate, also search for modules matching first segment in local crates @@ -329,7 +328,7 @@ fn resolve_path_to_modules( if let Some(name) = child.name(db) && names_match(name.as_str(), first_segment) { - candidate_modules.push(child); + candidate_modules.push((child, true)); } } } @@ -340,11 +339,14 @@ fn resolve_path_to_modules( for segment in rest_segments { candidate_modules = candidate_modules .into_iter() - .flat_map(|module| { - module.children(db).filter(|child| { - child.name(db).is_some_and(|name| names_match(name.as_str(), segment)) - }) + .flat_map(|(module, local)| { + module + .modules_in_scope(db, !local) + .into_iter() + .filter(|(name, _)| names_match(name.as_str(), segment)) + .map(move |(_, module)| (module, local)) }) + .unique() .collect(); if candidate_modules.is_empty() { @@ -352,7 +354,7 @@ fn resolve_path_to_modules( } } - candidate_modules + candidate_modules.into_iter().map(|(module, _)| module).collect() } #[derive(Default)] @@ -839,7 +841,7 @@ pub struct Foo; assert_eq!(item, "foo"); assert!(anchor); - // Trailing :: (module browsing) + // Trailing :: let (path, item, anchor) = Query::parse_path_query("foo::"); assert_eq!(path, vec!["foo"]); assert_eq!(item, ""); @@ -909,7 +911,7 @@ pub mod nested { } #[test] - fn test_module_browsing() { + fn test_path_search_module() { let (mut db, _) = RootDatabase::with_many_files( r#" //- /lib.rs crate:main @@ -1066,20 +1068,11 @@ pub fn root_fn() {} let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); assert!(names.contains(&"RootItem"), "Expected RootItem at crate root in {:?}", names); - // Browse crate root let query = Query::new("mylib::".to_owned()); let symbols = world_symbols(&db, query); let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); - assert!( - names.contains(&"RootItem"), - "Expected RootItem when browsing crate root in {:?}", - names - ); - assert!( - names.contains(&"root_fn"), - "Expected root_fn when browsing crate root in {:?}", - names - ); + assert!(names.contains(&"RootItem"), "Expected RootItem {:?}", names); + assert!(names.contains(&"root_fn"), "Expected root_fn {:?}", names); } #[test] @@ -1163,4 +1156,62 @@ pub struct FooStruct; let symbols = world_symbols(&db, query); assert!(symbols.is_empty(), "Expected empty results for non-matching crate pattern"); } + + #[test] + fn test_path_search_with_use_reexport() { + // Test that module resolution works for `use` items (re-exports), not just `mod` items + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs crate:main +mod inner; +pub use inner::nested; + +//- /inner.rs +pub mod nested { + pub struct NestedStruct; + pub fn nested_fn() {} +} +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + LocalRoots::get(&db).set_roots(&mut db).to(local_roots); + + // Search via the re-exported path (main::nested::NestedStruct) + // This should work because `nested` is in scope via `pub use inner::nested` + let query = Query::new("main::nested::NestedStruct".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!( + names.contains(&"NestedStruct"), + "Expected NestedStruct via re-exported path in {:?}", + names + ); + + // Also verify the original path still works + let query = Query::new("main::inner::nested::NestedStruct".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!( + names.contains(&"NestedStruct"), + "Expected NestedStruct via original path in {:?}", + names + ); + + // Browse the re-exported module + let query = Query::new("main::nested::".to_owned()); + let symbols = world_symbols(&db, query); + let names: Vec<_> = symbols.iter().map(|s| s.name.as_str()).collect(); + assert!( + names.contains(&"NestedStruct"), + "Expected NestedStruct when browsing re-exported module in {:?}", + names + ); + assert!( + names.contains(&"nested_fn"), + "Expected nested_fn when browsing re-exported module in {:?}", + names + ); + } } From 0361bd004a5074e7fddc8479bca9414e03178e04 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 12 Jan 2026 02:10:41 +0300 Subject: [PATCH 2129/3801] resolve: In `visit_scopes` do not extract ctxt out of span unless necessary --- compiler/rustc_resolve/src/diagnostics.rs | 5 ++++- compiler/rustc_resolve/src/ident.rs | 19 +++++++++++-------- compiler/rustc_resolve/src/late.rs | 8 +++----- compiler/rustc_resolve/src/lib.rs | 2 +- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7bc08f1de546..899f81525529 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -32,7 +32,9 @@ use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{SourceMap, Spanned}; -use rustc_span::{BytePos, Ident, Macros20NormalizedIdent, Span, Symbol, SyntaxContext, kw, sym}; +use rustc_span::{ + BytePos, DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, SyntaxContext, kw, sym, +}; use thin_vec::{ThinVec, thin_vec}; use tracing::{debug, instrument}; @@ -1179,6 +1181,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ctxt: SyntaxContext, filter_fn: &impl Fn(Res) -> bool, ) { + let ctxt = DUMMY_SP.with_ctxt(ctxt); self.cm().visit_scopes(scope_set, ps, ctxt, None, |this, scope, use_prelude, _| { match scope { Scope::DeriveHelpers(expn_id) => { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 7f04216c5553..f7e628048ccd 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -53,13 +53,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { mut self: CmResolver<'r, 'ra, 'tcx>, scope_set: ScopeSet<'ra>, parent_scope: &ParentScope<'ra>, - orig_ctxt: SyntaxContext, + // Location of the span is not significant, but pass a `Span` instead of `SyntaxContext` + // to avoid extracting and re-packaging the syntax context unnecessarily. + orig_ctxt: Span, derive_fallback_lint_id: Option, mut visitor: impl FnMut( &mut CmResolver<'r, 'ra, 'tcx>, Scope<'ra>, UsePrelude, - SyntaxContext, + Span, ) -> ControlFlow, ) -> Option { // General principles: @@ -238,11 +240,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn hygienic_lexical_parent( &self, module: Module<'ra>, - ctxt: &mut SyntaxContext, + span: &mut Span, derive_fallback_lint_id: Option, ) -> Option<(Module<'ra>, Option)> { - if !module.expansion.outer_expn_is_descendant_of(*ctxt) { - return Some((self.expn_def_scope(ctxt.remove_mark()), None)); + let ctxt = span.ctxt(); + if !module.expansion.outer_expn_is_descendant_of(ctxt) { + return Some((self.expn_def_scope(span.remove_mark()), None)); } if let ModuleKind::Block = module.kind { @@ -272,7 +275,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let ext = &self.get_macro_by_def_id(def_id).ext; if ext.builtin_name.is_none() && ext.macro_kinds() == MacroKinds::DERIVE - && parent.expansion.outer_expn_is_descendant_of(*ctxt) + && parent.expansion.outer_expn_is_descendant_of(ctxt) { return Some((parent, derive_fallback_lint_id)); } @@ -433,10 +436,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let break_result = self.visit_scopes( scope_set, parent_scope, - orig_ident.span.ctxt(), + orig_ident.span, derive_fallback_lint_id, |this, scope, use_prelude, ctxt| { - let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt)); + let ident = Ident::new(orig_ident.name, ctxt); // The passed `ctxt` is already normalized, so avoid expensive double normalization. let ident = Macros20NormalizedIdent(ident); let res = match this.reborrow().resolve_ident_in_scope( diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6d0097631772..6557e1dea1a1 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -37,9 +37,7 @@ use rustc_session::config::{CrateType, ResolveDocLinks}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::source_map::{Spanned, respan}; -use rustc_span::{ - BytePos, DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, SyntaxContext, kw, sym, -}; +use rustc_span::{BytePos, DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; @@ -5224,7 +5222,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.r.traits_in_scope( self.current_trait_ref.as_ref().map(|(module, _)| *module), &self.parent_scope, - ident.span.ctxt(), + ident.span, Some((ident.name, ns)), ) } @@ -5323,7 +5321,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .entry(self.parent_scope.module.nearest_parent_mod().expect_local()) .or_insert_with(|| { self.r - .traits_in_scope(None, &self.parent_scope, SyntaxContext::root(), None) + .traits_in_scope(None, &self.parent_scope, DUMMY_SP, None) .into_iter() .filter_map(|tr| { if self.is_invalid_proc_macro_item_for_doc(tr.def_id) { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index c4c1e06f94ae..0939f8cddbe5 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1918,7 +1918,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &mut self, current_trait: Option>, parent_scope: &ParentScope<'ra>, - ctxt: SyntaxContext, + ctxt: Span, assoc_item: Option<(Symbol, Namespace)>, ) -> Vec { let mut found_traits = Vec::new(); From 00384df08069939166b91813bca8b3c67d47d850 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Wed, 14 Jan 2026 17:47:11 +0100 Subject: [PATCH 2130/3801] Delete `MetaItemOrLitParser::Err` --- compiler/rustc_attr_parsing/src/attributes/cfg.rs | 1 - compiler/rustc_attr_parsing/src/attributes/doc.rs | 6 ------ compiler/rustc_attr_parsing/src/parser.rs | 8 +++----- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index ccf0a394afd0..dcb74dda81af 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -94,7 +94,6 @@ pub fn parse_cfg_entry( LitKind::Bool(b) => CfgEntry::Bool(b, lit.span), _ => return Err(cx.expected_identifier(lit.span)), }, - MetaItemOrLitParser::Err(_, err) => return Err(*err), }) } diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 6cc4ac35eadb..409102a79c06 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -514,9 +514,6 @@ impl DocParser { MetaItemOrLitParser::Lit(lit) => { cx.unexpected_literal(lit.span); } - MetaItemOrLitParser::Err(..) => { - // already had an error here, move on. - } } } } @@ -600,9 +597,6 @@ impl DocParser { MetaItemOrLitParser::Lit(lit) => { cx.expected_name_value(lit.span, None); } - MetaItemOrLitParser::Err(..) => { - // already had an error here, move on. - } } } } diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 68265649d182..ebf12dd1dfde 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -18,7 +18,7 @@ use rustc_parse::exp; use rustc_parse::parser::{ForceCollect, Parser, PathStyle, token_descr}; use rustc_session::errors::{create_lit_error, report_lit_error}; use rustc_session::parse::ParseSess; -use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, sym}; +use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::ThinVec; use crate::ShouldEmit; @@ -192,7 +192,6 @@ impl ArgParser { pub enum MetaItemOrLitParser { MetaItemParser(MetaItemParser), Lit(MetaItemLit), - Err(Span, ErrorGuaranteed), } impl MetaItemOrLitParser { @@ -210,21 +209,20 @@ impl MetaItemOrLitParser { generic_meta_item_parser.span() } MetaItemOrLitParser::Lit(meta_item_lit) => meta_item_lit.span, - MetaItemOrLitParser::Err(span, _) => *span, } } pub fn lit(&self) -> Option<&MetaItemLit> { match self { MetaItemOrLitParser::Lit(meta_item_lit) => Some(meta_item_lit), - _ => None, + MetaItemOrLitParser::MetaItemParser(_) => None, } } pub fn meta_item(&self) -> Option<&MetaItemParser> { match self { MetaItemOrLitParser::MetaItemParser(parser) => Some(parser), - _ => None, + MetaItemOrLitParser::Lit(_) => None, } } } From 8b52c73b3ec29dadf5df8dc02aeea5aeea778fd7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 10 Jan 2026 19:21:38 +0300 Subject: [PATCH 2131/3801] resolve: Relax some asserts in glob overwriting and add tests --- compiler/rustc_resolve/src/imports.rs | 6 ++--- tests/ui/imports/overwrite-deep-glob.rs | 22 ++++++++++++++++ tests/ui/imports/overwrite-deep-glob.stderr | 12 +++++++++ tests/ui/imports/overwrite-different-ambig.rs | 25 +++++++++++++++++++ tests/ui/imports/overwrite-different-vis.rs | 21 ++++++++++++++++ 5 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 tests/ui/imports/overwrite-deep-glob.rs create mode 100644 tests/ui/imports/overwrite-deep-glob.stderr create mode 100644 tests/ui/imports/overwrite-different-ambig.rs create mode 100644 tests/ui/imports/overwrite-different-vis.rs diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index e525abd00f99..7c0cbcf1d522 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -300,13 +300,13 @@ fn remove_same_import<'ra>(d1: Decl<'ra>, d2: Decl<'ra>) -> (Decl<'ra>, Decl<'ra if let DeclKind::Import { import: import1, source_decl: d1_next } = d1.kind && let DeclKind::Import { import: import2, source_decl: d2_next } = d2.kind && import1 == import2 - && d1.warn_ambiguity.get() == d2.warn_ambiguity.get() { assert_eq!(d1.ambiguity.get(), d2.ambiguity.get()); - assert!(!d1.warn_ambiguity.get()); assert_eq!(d1.expansion, d2.expansion); assert_eq!(d1.span, d2.span); - assert_eq!(d1.vis(), d2.vis()); + // Visibility of the new import declaration may be different, + // because it already incorporates the visibility of the source binding. + // `warn_ambiguity` of a re-fetched glob can also change in both directions. remove_same_import(d1_next, d2_next) } else { (d1, d2) diff --git a/tests/ui/imports/overwrite-deep-glob.rs b/tests/ui/imports/overwrite-deep-glob.rs new file mode 100644 index 000000000000..261b22f6e0a0 --- /dev/null +++ b/tests/ui/imports/overwrite-deep-glob.rs @@ -0,0 +1,22 @@ +//@ check-pass + +mod openssl { + pub use self::handwritten::*; + + mod handwritten { + mod m1 { + pub struct S {} + } + mod m2 { + #[derive(Default)] + pub struct S {} + } + + pub use self::m1::*; //~ WARN ambiguous glob re-exports + pub use self::m2::*; + } +} + +pub use openssl::*; + +fn main() {} diff --git a/tests/ui/imports/overwrite-deep-glob.stderr b/tests/ui/imports/overwrite-deep-glob.stderr new file mode 100644 index 000000000000..093478c57c93 --- /dev/null +++ b/tests/ui/imports/overwrite-deep-glob.stderr @@ -0,0 +1,12 @@ +warning: ambiguous glob re-exports + --> $DIR/overwrite-deep-glob.rs:15:17 + | +LL | pub use self::m1::*; + | ^^^^^^^^^^^ the name `S` in the type namespace is first re-exported here +LL | pub use self::m2::*; + | ----------- but the name `S` in the type namespace is also re-exported here + | + = note: `#[warn(ambiguous_glob_reexports)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/overwrite-different-ambig.rs b/tests/ui/imports/overwrite-different-ambig.rs new file mode 100644 index 000000000000..9aee63e18973 --- /dev/null +++ b/tests/ui/imports/overwrite-different-ambig.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ edition:2024 + +mod a { + mod b { + mod c { + pub struct E; + } + mod d { + mod c { + pub struct E; + } + mod d { + #[derive(Debug)] + pub struct E; + } + pub use c::*; + use d::*; + } + use c::*; + use d::*; + } +} + +fn main() {} diff --git a/tests/ui/imports/overwrite-different-vis.rs b/tests/ui/imports/overwrite-different-vis.rs new file mode 100644 index 000000000000..edcc441bcb77 --- /dev/null +++ b/tests/ui/imports/overwrite-different-vis.rs @@ -0,0 +1,21 @@ +//@ check-pass + +mod b { + pub mod http { + pub struct HeaderMap; + } + + pub(crate) use self::http::*; + #[derive(Debug)] + pub struct HeaderMap; +} + +mod a { + pub use crate::b::*; + + fn check_type() { + let _: HeaderMap = crate::b::HeaderMap; + } +} + +fn main() {} From 81ef42d5b7c4de7e8fa621fff4dc8f4627a581dc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Jan 2026 01:31:10 +0300 Subject: [PATCH 2132/3801] resolve: Consistently use old decls before new decls in interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The opposite ordering was a consistent source of confusion during debuggingю `report_conflict` actually used an incorrect order due to similar confusion. --- compiler/rustc_resolve/src/diagnostics.rs | 4 ++-- compiler/rustc_resolve/src/imports.rs | 8 ++++---- tests/ui/hygiene/cross-crate-redefine.rs | 2 +- tests/ui/hygiene/cross-crate-redefine.stderr | 7 +++---- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index b80011e8c0cb..9f13ba1201f7 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -212,12 +212,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &mut self, ident: Ident, ns: Namespace, - new_binding: Decl<'ra>, old_binding: Decl<'ra>, + new_binding: Decl<'ra>, ) { // Error on the second of two conflicting names if old_binding.span.lo() > new_binding.span.lo() { - return self.report_conflict(ident, ns, old_binding, new_binding); + return self.report_conflict(ident, ns, new_binding, old_binding); } let container = match old_binding.parent_module.unwrap().kind { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 7c0cbcf1d522..c3ea408deb89 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -348,8 +348,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// decide which one to keep. fn select_glob_decl( &self, - glob_decl: Decl<'ra>, old_glob_decl: Decl<'ra>, + glob_decl: Decl<'ra>, warn_ambiguity: bool, ) -> Decl<'ra> { assert!(glob_decl.is_glob_import()); @@ -369,7 +369,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // with the re-fetched decls. // This is probably incorrect in corner cases, and the outdated decls still get // propagated to other places and get stuck there, but that's what we have at the moment. - let (deep_decl, old_deep_decl) = remove_same_import(glob_decl, old_glob_decl); + let (old_deep_decl, deep_decl) = remove_same_import(old_glob_decl, glob_decl); if deep_decl != glob_decl { // Some import layers have been removed, need to overwrite. assert_ne!(old_deep_decl, old_glob_decl); @@ -436,7 +436,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match (old_decl.is_glob_import(), decl.is_glob_import()) { (true, true) => { resolution.glob_decl = - Some(this.select_glob_decl(decl, old_decl, warn_ambiguity)); + Some(this.select_glob_decl(old_decl, decl, warn_ambiguity)); } (old_glob @ true, false) | (old_glob @ false, true) => { let (glob_decl, non_glob_decl) = @@ -446,7 +446,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && old_glob_decl != glob_decl { resolution.glob_decl = - Some(this.select_glob_decl(glob_decl, old_glob_decl, false)); + Some(this.select_glob_decl(old_glob_decl, glob_decl, false)); } else { resolution.glob_decl = Some(glob_decl); } diff --git a/tests/ui/hygiene/cross-crate-redefine.rs b/tests/ui/hygiene/cross-crate-redefine.rs index e42c5e3de064..a87c933391d4 100644 --- a/tests/ui/hygiene/cross-crate-redefine.rs +++ b/tests/ui/hygiene/cross-crate-redefine.rs @@ -8,7 +8,7 @@ extern crate use_by_macro; use use_by_macro::*; my_struct!(define); -//~^ ERROR the name `MyStruct` is defined multiple times my_struct!(define); +//~^ ERROR the name `MyStruct` is defined multiple times fn main() {} diff --git a/tests/ui/hygiene/cross-crate-redefine.stderr b/tests/ui/hygiene/cross-crate-redefine.stderr index c0fd3f4b7ebf..8ad7d6d7b089 100644 --- a/tests/ui/hygiene/cross-crate-redefine.stderr +++ b/tests/ui/hygiene/cross-crate-redefine.stderr @@ -1,11 +1,10 @@ error[E0428]: the name `MyStruct` is defined multiple times - --> $DIR/cross-crate-redefine.rs:10:1 + --> $DIR/cross-crate-redefine.rs:11:1 | -LL | my_struct!(define); - | ^^^^^^^^^^^^^^^^^^ `MyStruct` redefined here -LL | LL | my_struct!(define); | ------------------ previous definition of the type `MyStruct` here +LL | my_struct!(define); + | ^^^^^^^^^^^^^^^^^^ `MyStruct` redefined here | = note: `MyStruct` must be defined only once in the type namespace of this module = note: this error originates in the macro `my_struct` (in Nightly builds, run with -Z macro-backtrace for more info) From 1c3841b372a248c0e8c405b051050dbef68f1527 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Jan 2026 22:44:37 +0300 Subject: [PATCH 2133/3801] Add a test for issue 150977 --- .../overwrite-different-warn-ambiguity.rs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/ui/imports/overwrite-different-warn-ambiguity.rs diff --git a/tests/ui/imports/overwrite-different-warn-ambiguity.rs b/tests/ui/imports/overwrite-different-warn-ambiguity.rs new file mode 100644 index 000000000000..f843208b37d6 --- /dev/null +++ b/tests/ui/imports/overwrite-different-warn-ambiguity.rs @@ -0,0 +1,28 @@ +//@ check-pass +//@ edition:2024 + +mod framing { + mod public_message_in { + mod public_message { + mod public_message { + pub struct ConfirmedTranscriptHashInput; + } + mod public_message_in { + use super::*; + #[derive(Debug)] + pub struct ConfirmedTranscriptHashInput; + } + pub use public_message::*; + use public_message_in::*; + } + mod public_message_in { + #[derive(Debug)] + pub struct ConfirmedTranscriptHashInput; + } + pub use public_message::*; + use public_message_in::*; + } + use public_message_in::*; +} + +fn main() {} From 83c5f2c19409deb44778bc6ad36a33f3b9ce0f57 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Jan 2026 23:16:42 +0300 Subject: [PATCH 2134/3801] resolve: Relax one more assert in glob overwriting and add a test Also avoid losing some glob ambiguities when re-fetching globs --- compiler/rustc_resolve/src/imports.rs | 9 +++- .../ui/imports/overwrite-different-ambig-2.rs | 24 +++++++++ .../overwrite-different-ambig-2.stderr | 49 +++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/ui/imports/overwrite-different-ambig-2.rs create mode 100644 tests/ui/imports/overwrite-different-ambig-2.stderr diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index c3ea408deb89..451779ae32c6 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -301,9 +301,12 @@ fn remove_same_import<'ra>(d1: Decl<'ra>, d2: Decl<'ra>) -> (Decl<'ra>, Decl<'ra && let DeclKind::Import { import: import2, source_decl: d2_next } = d2.kind && import1 == import2 { - assert_eq!(d1.ambiguity.get(), d2.ambiguity.get()); assert_eq!(d1.expansion, d2.expansion); assert_eq!(d1.span, d2.span); + if d1.ambiguity.get() != d2.ambiguity.get() { + assert!(d1.ambiguity.get().is_some()); + assert!(d2.ambiguity.get().is_none()); + } // Visibility of the new import declaration may be different, // because it already incorporates the visibility of the source binding. // `warn_ambiguity` of a re-fetched glob can also change in both directions. @@ -377,6 +380,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // assert_ne!(old_deep_decl, deep_decl); // assert!(old_deep_decl.is_glob_import()); assert!(!deep_decl.is_glob_import()); + if old_glob_decl.ambiguity.get().is_some() && glob_decl.ambiguity.get().is_none() { + // Do not lose glob ambiguities when re-fetching the glob. + glob_decl.ambiguity.set_unchecked(old_glob_decl.ambiguity.get()); + } if glob_decl.is_ambiguity_recursive() { glob_decl.warn_ambiguity.set_unchecked(true); } diff --git a/tests/ui/imports/overwrite-different-ambig-2.rs b/tests/ui/imports/overwrite-different-ambig-2.rs new file mode 100644 index 000000000000..1b6d20e24d30 --- /dev/null +++ b/tests/ui/imports/overwrite-different-ambig-2.rs @@ -0,0 +1,24 @@ +mod m1 { + mod inner { + pub struct S {} + } + pub use self::inner::*; + + #[derive(Debug)] + pub struct S {} +} + +mod m2 { + pub struct S {} +} + +// First we have a glob ambiguity in this glob (with `m2::*`). +// Then we re-fetch `m1::*` because non-glob `m1::S` materializes from derive, +// and we need to make sure that the glob ambiguity is not lost during re-fetching. +use m1::*; +use m2::*; + +fn main() { + let _: m1::S = S {}; //~ ERROR `S` is ambiguous + //~| WARN this was previously accepted +} diff --git a/tests/ui/imports/overwrite-different-ambig-2.stderr b/tests/ui/imports/overwrite-different-ambig-2.stderr new file mode 100644 index 000000000000..e75f552d119c --- /dev/null +++ b/tests/ui/imports/overwrite-different-ambig-2.stderr @@ -0,0 +1,49 @@ +error: `S` is ambiguous + --> $DIR/overwrite-different-ambig-2.rs:22:20 + | +LL | let _: m1::S = S {}; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `S` could refer to the struct imported here + --> $DIR/overwrite-different-ambig-2.rs:18:5 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `S` to disambiguate +note: `S` could also refer to the struct imported here + --> $DIR/overwrite-different-ambig-2.rs:19:5 + | +LL | use m2::*; + | ^^^^^ + = help: consider adding an explicit import of `S` to disambiguate + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + +error: aborting due to 1 previous error + +Future incompatibility report: Future breakage diagnostic: +error: `S` is ambiguous + --> $DIR/overwrite-different-ambig-2.rs:22:20 + | +LL | let _: m1::S = S {}; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `S` could refer to the struct imported here + --> $DIR/overwrite-different-ambig-2.rs:18:5 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `S` to disambiguate +note: `S` could also refer to the struct imported here + --> $DIR/overwrite-different-ambig-2.rs:19:5 + | +LL | use m2::*; + | ^^^^^ + = help: consider adding an explicit import of `S` to disambiguate + = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + From 9f1cf9efe0eaa25e76243e23a695b9a042c16c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 14 Jan 2026 18:01:50 +0100 Subject: [PATCH 2135/3801] Add temporary new bors e-mail address to the mailmap To match it to bors in thanks. --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 4c254b396b53..948f1ab14fde 100644 --- a/.mailmap +++ b/.mailmap @@ -96,6 +96,7 @@ boolean_coercion Boris Egorov bors bors[bot] <26634292+bors[bot]@users.noreply.github.com> bors bors[bot] +bors <122020455+rust-bors[bot]@users.noreply.github.com> BoxyUwU BoxyUwU Braden Nelson From 92db7b2b5ab89a37a2d7bdd9c8a25fd8be31e303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 14 Jan 2026 02:22:54 +0000 Subject: [PATCH 2136/3801] Recover parse gracefully from `` When a const param doesn't have a `: Type`, recover the parser state and provide a structured suggestion. This not only provides guidance on what was missing, but it also makes subsuequent errors to be emitted that would otherwise be silenced. ``` error: expected `:`, found `>` --> $DIR/incorrect-const-param.rs:26:16 | LL | impl From<[T; N]> for VecWrapper | ^ expected `:` | help: you might have meant to write the type of the const parameter here | LL | impl From<[T; N]> for VecWrapper | ++++++++++++ ``` --- compiler/rustc_parse/src/parser/generics.rs | 26 ++++++- .../const-generics/incorrect-const-param.rs | 45 ++++++++++++ .../incorrect-const-param.stderr | 70 +++++++++++++++++++ 3 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 tests/ui/const-generics/incorrect-const-param.rs create mode 100644 tests/ui/const-generics/incorrect-const-param.stderr diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 2c76c0fe3583..ef6c9cc344ce 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -109,7 +109,31 @@ impl<'a> Parser<'a> { self.expect_keyword(exp!(Const))?; let ident = self.parse_ident()?; - self.expect(exp!(Colon))?; + if let Err(mut err) = self.expect(exp!(Colon)) { + return if self.token.kind == token::Comma || self.token.kind == token::Gt { + // Recover parse from `` where the type is missing. + let span = const_span.to(ident.span); + err.span_suggestion_verbose( + ident.span.shrink_to_hi(), + "you likely meant to write the type of the const parameter here", + ": /* Type */".to_string(), + Applicability::HasPlaceholders, + ); + let kind = TyKind::Err(err.emit()); + let ty = self.mk_ty(span, kind); + Ok(GenericParam { + ident, + id: ast::DUMMY_NODE_ID, + attrs: preceding_attrs, + bounds: Vec::new(), + kind: GenericParamKind::Const { ty, span, default: None }, + is_placeholder: false, + colon_span: None, + }) + } else { + Err(err) + }; + } let ty = self.parse_ty()?; // Parse optional const generics default value. diff --git a/tests/ui/const-generics/incorrect-const-param.rs b/tests/ui/const-generics/incorrect-const-param.rs new file mode 100644 index 000000000000..5f1d8ca2ae99 --- /dev/null +++ b/tests/ui/const-generics/incorrect-const-param.rs @@ -0,0 +1,45 @@ +// #84327 + +struct VecWrapper(Vec); + +// Correct +impl From<[T; N]> for VecWrapper +where + T: Clone, +{ + fn from(slice: [T; N]) -> Self { + VecWrapper(slice.to_vec()) + } +} + +// Forgot const +impl From<[T; N]> for VecWrapper //~ ERROR expected value, found type parameter `N` +where //~^ ERROR expected trait, found builtin type `usize` + T: Clone, +{ + fn from(slice: [T; N]) -> Self { //~ ERROR expected value, found type parameter `N` + VecWrapper(slice.to_vec()) + } +} + +// Forgot type +impl From<[T; N]> for VecWrapper //~ ERROR expected `:`, found `>` +where + T: Clone, +{ + fn from(slice: [T; N]) -> Self { + VecWrapper(slice.to_vec()) + } +} + +// Forgot const and type +impl From<[T; N]> for VecWrapper //~ ERROR expected value, found type parameter `N` +where + T: Clone, +{ + fn from(slice: [T; N]) -> Self { //~ ERROR expected value, found type parameter `N` + VecWrapper(slice.to_vec()) + } +} + +fn main() {} diff --git a/tests/ui/const-generics/incorrect-const-param.stderr b/tests/ui/const-generics/incorrect-const-param.stderr new file mode 100644 index 000000000000..c5cf54500ee0 --- /dev/null +++ b/tests/ui/const-generics/incorrect-const-param.stderr @@ -0,0 +1,70 @@ +error: expected `:`, found `>` + --> $DIR/incorrect-const-param.rs:26:16 + | +LL | impl From<[T; N]> for VecWrapper + | ^ expected `:` + | +help: you likely meant to write the type of the const parameter here + | +LL | impl From<[T; N]> for VecWrapper + | ++++++++++++ + +error[E0423]: expected value, found type parameter `N` + --> $DIR/incorrect-const-param.rs:16:28 + | +LL | impl From<[T; N]> for VecWrapper + | - ^ not a value + | | + | found this type parameter + +error[E0404]: expected trait, found builtin type `usize` + --> $DIR/incorrect-const-param.rs:16:12 + | +LL | impl From<[T; N]> for VecWrapper + | ^^^^^ not a trait + | +help: you might have meant to write a const parameter here + | +LL | impl From<[T; N]> for VecWrapper + | +++++ + +error[E0423]: expected value, found type parameter `N` + --> $DIR/incorrect-const-param.rs:20:24 + | +LL | impl From<[T; N]> for VecWrapper + | - found this type parameter +... +LL | fn from(slice: [T; N]) -> Self { + | ^ not a value + +error[E0423]: expected value, found type parameter `N` + --> $DIR/incorrect-const-param.rs:36:21 + | +LL | impl From<[T; N]> for VecWrapper + | - ^ not a value + | | + | found this type parameter + | +help: you might have meant to write a const parameter here + | +LL | impl From<[T; N]> for VecWrapper + | +++++ ++++++++++++ + +error[E0423]: expected value, found type parameter `N` + --> $DIR/incorrect-const-param.rs:40:24 + | +LL | impl From<[T; N]> for VecWrapper + | - found this type parameter +... +LL | fn from(slice: [T; N]) -> Self { + | ^ not a value + | +help: you might have meant to write a const parameter here + | +LL | impl From<[T; N]> for VecWrapper + | +++++ ++++++++++++ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0404, E0423. +For more information about an error, try `rustc --explain E0404`. From 79ec275e2d513d5f1b8a685a20476b9b700674fe Mon Sep 17 00:00:00 2001 From: Asuna Date: Wed, 14 Jan 2026 17:00:22 +0100 Subject: [PATCH 2137/3801] Support primitives in type info reflection Support {bool,char,int,uint,float,str} primitive types for feature `type_info` reflection. --- .../src/const_eval/type_info.rs | 84 +++++++- compiler/rustc_span/src/symbol.rs | 8 +- library/core/src/mem/type_info.rs | 75 ++++++- library/coretests/tests/mem/type_info.rs | 39 +++- .../const_prop/invalid_constant.main.GVN.diff | 2 +- .../invalid_constant.main.RemoveZsts.diff | 2 +- tests/ui/lint/recommend-literal.rs | 2 + tests/ui/lint/recommend-literal.stderr | 22 ++- tests/ui/reflection/dump.bit32.run.stdout | 186 ++++++++++++++++++ tests/ui/reflection/dump.bit64.run.stdout | 186 ++++++++++++++++++ tests/ui/reflection/dump.rs | 33 ++-- tests/ui/reflection/dump.run.stdout | 31 --- ...stion-when-stmt-and-expr-span-equal.stderr | 4 +- tests/ui/traits/issue-77982.stderr | 2 +- tests/ui/try-trait/bad-interconversion.stderr | 2 +- 15 files changed, 612 insertions(+), 66 deletions(-) create mode 100644 tests/ui/reflection/dump.bit32.run.stdout create mode 100644 tests/ui/reflection/dump.bit64.run.stdout delete mode 100644 tests/ui/reflection/dump.run.stdout diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 814c81278a10..fc3378275be2 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -35,6 +35,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok((variant_id, self.project_downcast(&field_dest, variant_id)?)) }; + let ptr_bit_width = || self.tcx.data_layout.pointer_size().bits(); match field.name { sym::kind => { let variant_index = match ty.kind() { @@ -64,13 +65,60 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } - // For now just merge all primitives into one `Leaf` variant with no data - ty::Uint(_) | ty::Int(_) | ty::Float(_) | ty::Char | ty::Bool => { - downcast(sym::Leaf)?.0 + ty::Bool => { + let (variant, variant_place) = downcast(sym::Bool)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_primitive_type_info(place, ty, None)?; + variant + } + ty::Char => { + let (variant, variant_place) = downcast(sym::Char)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_primitive_type_info(place, ty, None)?; + variant + } + ty::Int(int_ty) => { + let (variant, variant_place) = downcast(sym::Int)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_primitive_type_info( + place, + ty, + Some( + int_ty + .bit_width() + .unwrap_or_else(/* isize */ ptr_bit_width), + ), + )?; + variant + } + ty::Uint(uint_ty) => { + let (variant, variant_place) = downcast(sym::Uint)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_primitive_type_info( + place, + ty, + Some( + uint_ty + .bit_width() + .unwrap_or_else(/* usize */ ptr_bit_width), + ), + )?; + variant + } + ty::Float(float_ty) => { + let (variant, variant_place) = downcast(sym::Float)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_primitive_type_info(place, ty, Some(float_ty.bit_width()))?; + variant + } + ty::Str => { + let (variant, variant_place) = downcast(sym::Str)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_primitive_type_info(place, ty, None)?; + variant } ty::Adt(_, _) | ty::Foreign(_) - | ty::Str | ty::Pat(_, _) | ty::Slice(_) | ty::RawPtr(..) @@ -203,4 +251,32 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } + + // This method always writes to field `ty`. + // If field `bit_width` is present, it also writes to it (in which case parameter `write_bit_width` must be `Some`). + fn write_primitive_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + ty: Ty<'tcx>, + write_bit_width: Option, + ) -> InterpResult<'tcx> { + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + match field.name { + sym::ty => self.write_type_id(ty, &field_place)?, + sym::bit_width => { + let bit_width = write_bit_width + .expect("type info struct needs a `bit_width` but none was provided"); + self.write_scalar( + ScalarInt::try_from_target_usize(bit_width, self.tcx.tcx).unwrap(), + &field_place, + )? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + interp_ok(()) + } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 34804160ed39..4c19fa83fd3a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -190,6 +190,7 @@ symbols! { BTreeMap, BTreeSet, BinaryHeap, + Bool, Borrow, BorrowMut, Break, @@ -202,6 +203,7 @@ symbols! { Capture, Cell, Center, + Char, Child, Cleanup, Clone, @@ -238,6 +240,7 @@ symbols! { Error, File, FileType, + Float, FmtArgumentsNew, FmtWrite, Fn, @@ -263,6 +266,7 @@ symbols! { IndexOutput, Input, Instant, + Int, Into, IntoFuture, IntoIterator, @@ -285,7 +289,6 @@ symbols! { IteratorItem, IteratorMap, Layout, - Leaf, Left, LinkedList, LintDiagnostic, @@ -363,6 +366,7 @@ symbols! { Some, SpanCtxt, Stdin, + Str, String, StructuralPartialEq, SubdiagMessage, @@ -387,6 +391,7 @@ symbols! { Ty, TyCtxt, TyKind, + Uint, Unknown, Unsize, UnsizedConstParamTy, @@ -584,6 +589,7 @@ symbols! { binaryheap_iter, bind_by_move_pattern_guards, bindings_after_at, + bit_width, bitand, bitand_assign, bitor, diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index e4ccc408f1c6..7db4f3b00123 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -45,9 +45,18 @@ pub enum TypeKind { Tuple(Tuple), /// Arrays. Array(Array), - /// Primitives - /// FIXME(#146922): disambiguate further - Leaf, + /// Primitive boolean type. + Bool(Bool), + /// Primitive character type. + Char(Char), + /// Primitive signed integer type. + Int(Int), + /// Primitive unsigned integer type. + Uint(Uint), + /// Primitive floating-point type. + Float(Float), + /// String slice type. + Str(Str), /// FIXME(#146922): add all the common types Other, } @@ -82,3 +91,63 @@ pub struct Array { /// The length of the array. pub len: usize, } + +/// Compile-time type information about `bool`. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Bool { + /// The type id of `bool`. + pub ty: TypeId, +} + +/// Compile-time type information about `char`. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Char { + /// The type id of `char`. + pub ty: TypeId, +} + +/// Compile-time type information about signed integer types. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Int { + /// The type id of signed integer type. + pub ty: TypeId, + /// The bit width of the signed integer type. + pub bit_width: usize, +} + +/// Compile-time type information about unsigned integer types. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Uint { + /// The type id of unsigned integer type. + pub ty: TypeId, + /// The bit width of the unsigned integer type. + pub bit_width: usize, +} + +/// Compile-time type information about floating-point types. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Float { + /// The type id of floating-point type. + pub ty: TypeId, + /// The bit width of the floating-point type. + pub bit_width: usize, +} + +/// Compile-time type information about string slice types. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Str { + /// The type id of `str`. + pub ty: TypeId, +} diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index b3b8d96d49b0..5dd8f4034d11 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -46,7 +46,10 @@ fn test_tuples() { assert!(b.offset == 1); match (a.ty.info().kind, b.ty.info().kind) { - (TypeKind::Leaf, TypeKind::Leaf) => {} + (TypeKind::Uint(a), TypeKind::Uint(b)) => { + assert!(a.bit_width == 8); + assert!(b.bit_width == 8); + } _ => unreachable!(), } } @@ -54,3 +57,37 @@ fn test_tuples() { } } } + +#[test] +fn test_primitives() { + use TypeKind::*; + + let Type { kind: Bool(_ty), size, .. } = (const { Type::of::() }) else { panic!() }; + assert_eq!(size, Some(1)); + + let Type { kind: Char(_ty), size, .. } = (const { Type::of::() }) else { panic!() }; + assert_eq!(size, Some(4)); + + let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; + assert_eq!(size, Some(4)); + assert_eq!(ty.bit_width, 32); + + let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; + assert_eq!(size, Some(size_of::())); + assert_eq!(ty.bit_width, size_of::() * 8); + + let Type { kind: Uint(ty), size, .. } = (const { Type::of::() }) else { panic!() }; + assert_eq!(size, Some(4)); + assert_eq!(ty.bit_width, 32); + + let Type { kind: Uint(ty), size, .. } = (const { Type::of::() }) else { panic!() }; + assert_eq!(size, Some(size_of::())); + assert_eq!(ty.bit_width, size_of::() * 8); + + let Type { kind: Float(ty), size, .. } = (const { Type::of::() }) else { panic!() }; + assert_eq!(size, Some(4)); + assert_eq!(ty.bit_width, 32); + + let Type { kind: Str(_ty), size, .. } = (const { Type::of::() }) else { panic!() }; + assert_eq!(size, None); +} diff --git a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff index 20923d0352cd..3dc6fc9e3f65 100644 --- a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff +++ b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff @@ -19,7 +19,7 @@ debug _enum_without_variants => const [ZeroSized: Empty]; let _9: main::Str<"���">; scope 4 { - debug _non_utf8_str => const Str::<"���">; + debug _non_utf8_str => const main::Str::<"���">; } } } diff --git a/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff b/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff index 6593b329756c..c16cbaf4c0f2 100644 --- a/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff +++ b/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff @@ -21,7 +21,7 @@ let _9: main::Str<"���">; scope 4 { - debug _non_utf8_str => _9; -+ debug _non_utf8_str => const Str::<"���">; ++ debug _non_utf8_str => const main::Str::<"���">; } } } diff --git a/tests/ui/lint/recommend-literal.rs b/tests/ui/lint/recommend-literal.rs index 45f9ae0a7bdf..be074c111453 100644 --- a/tests/ui/lint/recommend-literal.rs +++ b/tests/ui/lint/recommend-literal.rs @@ -1,3 +1,5 @@ +//~vv HELP consider importing this struct + type Real = double; //~^ ERROR cannot find type `double` in this scope //~| HELP perhaps you intended to use this type diff --git a/tests/ui/lint/recommend-literal.stderr b/tests/ui/lint/recommend-literal.stderr index 6b6dd134e1d2..01e993df17a9 100644 --- a/tests/ui/lint/recommend-literal.stderr +++ b/tests/ui/lint/recommend-literal.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find type `double` in this scope - --> $DIR/recommend-literal.rs:1:13 + --> $DIR/recommend-literal.rs:3:13 | LL | type Real = double; | ^^^^^^ @@ -8,7 +8,7 @@ LL | type Real = double; | help: perhaps you intended to use this type: `f64` error[E0425]: cannot find type `long` in this scope - --> $DIR/recommend-literal.rs:7:12 + --> $DIR/recommend-literal.rs:9:12 | LL | let y: long = 74802374902374923; | ^^^^ @@ -17,7 +17,7 @@ LL | let y: long = 74802374902374923; | help: perhaps you intended to use this type: `i64` error[E0425]: cannot find type `Boolean` in this scope - --> $DIR/recommend-literal.rs:10:13 + --> $DIR/recommend-literal.rs:12:13 | LL | let v1: Boolean = true; | ^^^^^^^ @@ -26,7 +26,7 @@ LL | let v1: Boolean = true; | help: perhaps you intended to use this type: `bool` error[E0425]: cannot find type `Bool` in this scope - --> $DIR/recommend-literal.rs:13:13 + --> $DIR/recommend-literal.rs:15:13 | LL | let v2: Bool = true; | ^^^^ @@ -41,9 +41,13 @@ help: perhaps you intended to use this type LL - let v2: Bool = true; LL + let v2: bool = true; | +help: consider importing this struct + | +LL + use std::mem::type_info::Bool; + | error[E0425]: cannot find type `boolean` in this scope - --> $DIR/recommend-literal.rs:19:9 + --> $DIR/recommend-literal.rs:21:9 | LL | fn z(a: boolean) { | ^^^^^^^ @@ -52,7 +56,7 @@ LL | fn z(a: boolean) { | help: perhaps you intended to use this type: `bool` error[E0425]: cannot find type `byte` in this scope - --> $DIR/recommend-literal.rs:24:11 + --> $DIR/recommend-literal.rs:26:11 | LL | fn a() -> byte { | ^^^^ @@ -61,7 +65,7 @@ LL | fn a() -> byte { | help: perhaps you intended to use this type: `u8` error[E0425]: cannot find type `float` in this scope - --> $DIR/recommend-literal.rs:31:12 + --> $DIR/recommend-literal.rs:33:12 | LL | width: float, | ^^^^^ @@ -70,7 +74,7 @@ LL | width: float, | help: perhaps you intended to use this type: `f32` error[E0425]: cannot find type `int` in this scope - --> $DIR/recommend-literal.rs:34:19 + --> $DIR/recommend-literal.rs:36:19 | LL | depth: Option, | ^^^ not found in this scope @@ -86,7 +90,7 @@ LL | struct Data { | +++++ error[E0425]: cannot find type `short` in this scope - --> $DIR/recommend-literal.rs:40:16 + --> $DIR/recommend-literal.rs:42:16 | LL | impl Stuff for short {} | ^^^^^ diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout new file mode 100644 index 000000000000..d747ee210204 --- /dev/null +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -0,0 +1,186 @@ +Type { + kind: Tuple( + Tuple { + fields: [ + Field { + ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + offset: 0, + }, + Field { + ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + offset: 1, + }, + Field { + ty: TypeId(0x41223169ff28813ba79b7268a2a968d9), + offset: 2, + }, + ], + }, + ), + size: Some( + 2, + ), +} +Type { + kind: Array( + Array { + element_ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + len: 2, + }, + ), + size: Some( + 2, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0x12427c993eca190c841e0d92c5b7a45d), + bit_width: 8, + }, + ), + size: Some( + 1, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013), + bit_width: 32, + }, + ), + size: Some( + 4, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0xae6c4318bb07632e00428affbea41961), + bit_width: 64, + }, + ), + size: Some( + 8, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0xc7164498f3902dde0d8194a7b9733e79), + bit_width: 128, + }, + ), + size: Some( + 16, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0x1e5f92831c560aac8658b980a22e60b0), + bit_width: 32, + }, + ), + size: Some( + 4, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + bit_width: 8, + }, + ), + size: Some( + 1, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + bit_width: 32, + }, + ), + size: Some( + 4, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x9ed91be891e304132cb86891e578f4a5), + bit_width: 64, + }, + ), + size: Some( + 8, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x7bf7411d57d603e9fb393892a9c3f362), + bit_width: 128, + }, + ), + size: Some( + 16, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x763d199bccd319899208909ed1a860c6), + bit_width: 32, + }, + ), + size: Some( + 4, + ), +} +Type { + kind: Other, + size: Some( + 4, + ), +} +Type { + kind: Other, + size: Some( + 12, + ), +} +Type { + kind: Other, + size: Some( + 8, + ), +} +Type { + kind: Other, + size: Some( + 8, + ), +} +Type { + kind: Other, + size: Some( + 8, + ), +} +Type { + kind: Str( + Str { + ty: TypeId(0x474ccf3b5db264ef53916706f7d7bb2c), + }, + ), + size: None, +} +Type { + kind: Other, + size: None, +} diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout new file mode 100644 index 000000000000..180a6e2882d7 --- /dev/null +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -0,0 +1,186 @@ +Type { + kind: Tuple( + Tuple { + fields: [ + Field { + ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + offset: 0, + }, + Field { + ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + offset: 1, + }, + Field { + ty: TypeId(0x41223169ff28813ba79b7268a2a968d9), + offset: 2, + }, + ], + }, + ), + size: Some( + 2, + ), +} +Type { + kind: Array( + Array { + element_ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + len: 2, + }, + ), + size: Some( + 2, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0x12427c993eca190c841e0d92c5b7a45d), + bit_width: 8, + }, + ), + size: Some( + 1, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013), + bit_width: 32, + }, + ), + size: Some( + 4, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0xae6c4318bb07632e00428affbea41961), + bit_width: 64, + }, + ), + size: Some( + 8, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0xc7164498f3902dde0d8194a7b9733e79), + bit_width: 128, + }, + ), + size: Some( + 16, + ), +} +Type { + kind: Int( + Int { + ty: TypeId(0x1e5f92831c560aac8658b980a22e60b0), + bit_width: 64, + }, + ), + size: Some( + 8, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + bit_width: 8, + }, + ), + size: Some( + 1, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + bit_width: 32, + }, + ), + size: Some( + 4, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x9ed91be891e304132cb86891e578f4a5), + bit_width: 64, + }, + ), + size: Some( + 8, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x7bf7411d57d603e9fb393892a9c3f362), + bit_width: 128, + }, + ), + size: Some( + 16, + ), +} +Type { + kind: Uint( + Uint { + ty: TypeId(0x763d199bccd319899208909ed1a860c6), + bit_width: 64, + }, + ), + size: Some( + 8, + ), +} +Type { + kind: Other, + size: Some( + 4, + ), +} +Type { + kind: Other, + size: Some( + 24, + ), +} +Type { + kind: Other, + size: Some( + 16, + ), +} +Type { + kind: Other, + size: Some( + 16, + ), +} +Type { + kind: Other, + size: Some( + 16, + ), +} +Type { + kind: Str( + Str { + ty: TypeId(0x474ccf3b5db264ef53916706f7d7bb2c), + }, + ), + size: None, +} +Type { + kind: Other, + size: None, +} diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs index 0adcda481b5a..584b7c8ed4ae 100644 --- a/tests/ui/reflection/dump.rs +++ b/tests/ui/reflection/dump.rs @@ -1,6 +1,11 @@ -#![feature(type_info)] +// Some types whose length depends on the target pointer length will be dumped. +//@ revisions: bit32 bit64 +//@[bit32] only-32bit +//@[bit64] only-64bit //@ run-pass //@ check-run-results + +#![feature(type_info)] #![allow(dead_code)] use std::mem::type_info::Type; @@ -20,14 +25,20 @@ struct Unsized { s: str, } -fn main() { - println!("{:#?}", const { Type::of::<(u8, u8, ())>() }.kind); - println!("{:#?}", const { Type::of::<[u8; 2]>() }.kind); - println!("{:#?}", const { Type::of::() }.kind); - println!("{:#?}", const { Type::of::() }.kind); - println!("{:#?}", const { Type::of::<&Unsized>() }.kind); - println!("{:#?}", const { Type::of::<&str>() }.kind); - println!("{:#?}", const { Type::of::<&[u8]>() }.kind); - println!("{:#?}", const { Type::of::() }.kind); - println!("{:#?}", const { Type::of::<[u8]>() }.kind); +macro_rules! dump_types { + ($($ty:ty),+ $(,)?) => { + $(println!("{:#?}", const { Type::of::<$ty>() });)+ + }; +} + +fn main() { + dump_types! { + (u8, u8, ()), + [u8; 2], + i8, i32, i64, i128, isize, + u8, u32, u64, u128, usize, + Foo, Bar, + &Unsized, &str, &[u8], + str, [u8], + } } diff --git a/tests/ui/reflection/dump.run.stdout b/tests/ui/reflection/dump.run.stdout deleted file mode 100644 index dfd128664e2d..000000000000 --- a/tests/ui/reflection/dump.run.stdout +++ /dev/null @@ -1,31 +0,0 @@ -Tuple( - Tuple { - fields: [ - Field { - ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), - offset: 0, - }, - Field { - ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), - offset: 1, - }, - Field { - ty: TypeId(0x41223169ff28813ba79b7268a2a968d9), - offset: 2, - }, - ], - }, -) -Array( - Array { - element_ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), - len: 2, - }, -) -Other -Other -Other -Other -Other -Other -Other diff --git a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr index aa96159aacf5..9f34d2747881 100644 --- a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr +++ b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr @@ -21,14 +21,14 @@ LL | .collect::(); | = help: the trait `FromIterator<()>` is not implemented for `String` = help: the following other types implement trait `FromIterator`: - `String` implements `FromIterator<&Char>` `String` implements `FromIterator<&char>` + `String` implements `FromIterator<&std::ascii::Char>` `String` implements `FromIterator<&str>` `String` implements `FromIterator>` - `String` implements `FromIterator` `String` implements `FromIterator>` `String` implements `FromIterator` `String` implements `FromIterator` + `String` implements `FromIterator` note: the method call chain might not have had the expected associated types --> $DIR/semi-suggestion-when-stmt-and-expr-span-equal.rs:20:10 | diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index 4bc24e81215a..b1baabc4394b 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -44,10 +44,10 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect( | type must be known at this point | = note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate: - - impl From for u32; - impl From for u32; - impl From for u32; - impl From for u32; + - impl From for u32; - impl From for u32; - impl From for u32; help: try using a fully qualified path to specify the expected types diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index 61fecaf89917..f8c0deba99ba 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -18,7 +18,7 @@ help: the following other types implement trait `From` = note: in this macro invocation --> $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL | - = note: `u8` implements `From` + = note: `u8` implements `From` ::: $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL | = note: in this macro invocation From 6ecee2a415db5f3abf32414372e8325d3ff47f7b Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Wed, 14 Jan 2026 18:26:02 +0000 Subject: [PATCH 2138/3801] internal: Improve docs for discoverConfig Add concrete examples of CLI invocations and JSONL outputs, use BUCK for consistency with the first example, and polish the wording. --- .../crates/rust-analyzer/src/config.rs | 116 +++++++++++------- .../docs/book/src/configuration_generated.md | 116 +++++++++++------- .../docs/book/src/non_cargo_based_projects.md | 2 +- .../rust-analyzer/editors/code/package.json | 2 +- 4 files changed, 142 insertions(+), 94 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 28ac94e4deb6..8d6b19a84caa 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -478,14 +478,26 @@ config_data! { typing_triggerChars: Option = Some("=.".to_owned()), - /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. + /// Configure a command that rust-analyzer can invoke to + /// obtain configuration. /// - /// [`DiscoverWorkspaceConfig`] also requires setting `progressLabel` and `filesToWatch`. - /// `progressLabel` is used for the title in progress indicators, whereas `filesToWatch` - /// is used to determine which build system-specific files should be watched in order to - /// reload rust-analyzer. + /// This is an alternative to manually generating + /// `rust-project.json`: it enables rust-analyzer to generate + /// rust-project.json on the fly, and regenerate it when + /// switching or modifying projects. + /// + /// This is an object with three fields: + /// + /// * `command`: the shell command to invoke + /// + /// * `filesToWatch`: which build system-specific files should + /// be watched to trigger regenerating the configuration + /// + /// * `progressLabel`: the name of the command, used in + /// progress indicators in the IDE + /// + /// Here's an example of a valid configuration: /// - /// Below is an example of a valid configuration: /// ```json /// "rust-analyzer.workspace.discoverConfig": { /// "command": [ @@ -500,12 +512,49 @@ config_data! { /// } /// ``` /// - /// ## Workspace Discovery Protocol + /// ## Argument Substitutions + /// + /// If `command` includes the argument `{arg}`, that argument will be substituted + /// with the JSON-serialized form of the following enum: + /// + /// ```norun + /// #[derive(PartialEq, Clone, Debug, Serialize)] + /// #[serde(rename_all = "camelCase")] + /// pub enum DiscoverArgument { + /// Path(AbsPathBuf), + /// Buildfile(AbsPathBuf), + /// } + /// ``` + /// + /// rust-analyzer will use the path invocation to find and + /// generate a `rust-project.json` and therefore a + /// workspace. Example: + /// + /// + /// ```norun + /// rust-project develop-json '{ "path": "myproject/src/main.rs" }' + /// ``` + /// + /// rust-analyzer will use build file invocations to update an + /// existing workspace. Example: + /// + /// Or with a build file and the configuration above: + /// + /// ```norun + /// rust-project develop-json '{ "buildfile": "myproject/BUCK" }' + /// ``` + /// + /// As a reference for implementors, buck2's `rust-project` + /// will likely be useful: + /// . + /// + /// ## Discover Command Output /// /// **Warning**: This format is provisional and subject to change. /// - /// [`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to - /// `DiscoverProjectData::Finished`: + /// The discover command should output JSON objects, one per + /// line (JSONL format). These objects should correspond to + /// this Rust data type: /// /// ```norun /// #[derive(Debug, Clone, Deserialize, Serialize)] @@ -518,7 +567,14 @@ config_data! { /// } /// ``` /// - /// As JSON, `DiscoverProjectData::Finished` is: + /// For example, a progress event: + /// + /// ```json + /// {"kind":"progress","message":"generating rust-project.json"} + /// ``` + /// + /// A finished event can look like this (expanded and + /// commented for readability): /// /// ```json /// { @@ -526,7 +582,7 @@ config_data! { /// "kind": "finished", /// // the file used by a non-Cargo build system to define /// // a package or target. - /// "buildfile": "rust-analyzer/BUILD", + /// "buildfile": "rust-analyzer/BUCK", /// // the contents of a rust-project.json, elided for brevity /// "project": { /// "sysroot": "foo", @@ -535,41 +591,9 @@ config_data! { /// } /// ``` /// - /// It is encouraged, but not required, to use the other variants on `DiscoverProjectData` - /// to provide a more polished end-user experience. - /// - /// `DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`, which will be - /// substituted with the JSON-serialized form of the following enum: - /// - /// ```norun - /// #[derive(PartialEq, Clone, Debug, Serialize)] - /// #[serde(rename_all = "camelCase")] - /// pub enum DiscoverArgument { - /// Path(AbsPathBuf), - /// Buildfile(AbsPathBuf), - /// } - /// ``` - /// - /// The JSON representation of `DiscoverArgument::Path` is: - /// - /// ```json - /// { - /// "path": "src/main.rs" - /// } - /// ``` - /// - /// Similarly, the JSON representation of `DiscoverArgument::Buildfile` is: - /// - /// ```json - /// { - /// "buildfile": "BUILD" - /// } - /// ``` - /// - /// `DiscoverArgument::Path` is used to find and generate a `rust-project.json`, and - /// therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to to update an - /// existing workspace. As a reference for implementors, buck2's `rust-project` will likely - /// be useful: . + /// Only the finished event is required, but the other + /// variants are encouraged to give users more feedback about + /// progress or errors. workspace_discoverConfig: Option = None, } } diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index c4124aaae075..9bc412631039 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1619,14 +1619,26 @@ though Cargo might be the eventual consumer. Default: `null` -Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. +Configure a command that rust-analyzer can invoke to +obtain configuration. -[`DiscoverWorkspaceConfig`] also requires setting `progressLabel` and `filesToWatch`. -`progressLabel` is used for the title in progress indicators, whereas `filesToWatch` -is used to determine which build system-specific files should be watched in order to -reload rust-analyzer. +This is an alternative to manually generating +`rust-project.json`: it enables rust-analyzer to generate +rust-project.json on the fly, and regenerate it when +switching or modifying projects. + +This is an object with three fields: + +* `command`: the shell command to invoke + +* `filesToWatch`: which build system-specific files should +be watched to trigger regenerating the configuration + +* `progressLabel`: the name of the command, used in +progress indicators in the IDE + +Here's an example of a valid configuration: -Below is an example of a valid configuration: ```json "rust-analyzer.workspace.discoverConfig": { "command": [ @@ -1641,12 +1653,49 @@ Below is an example of a valid configuration: } ``` -## Workspace Discovery Protocol +## Argument Substitutions + +If `command` includes the argument `{arg}`, that argument will be substituted +with the JSON-serialized form of the following enum: + +```norun +#[derive(PartialEq, Clone, Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub enum DiscoverArgument { + Path(AbsPathBuf), + Buildfile(AbsPathBuf), +} +``` + +rust-analyzer will use the path invocation to find and +generate a `rust-project.json` and therefore a +workspace. Example: + + +```norun +rust-project develop-json '{ "path": "myproject/src/main.rs" }' +``` + +rust-analyzer will use build file invocations to update an +existing workspace. Example: + +Or with a build file and the configuration above: + +```norun +rust-project develop-json '{ "buildfile": "myproject/BUCK" }' +``` + +As a reference for implementors, buck2's `rust-project` +will likely be useful: +. + +## Discover Command Output **Warning**: This format is provisional and subject to change. -[`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to -`DiscoverProjectData::Finished`: +The discover command should output JSON objects, one per +line (JSONL format). These objects should correspond to +this Rust data type: ```norun #[derive(Debug, Clone, Deserialize, Serialize)] @@ -1659,7 +1708,14 @@ enum DiscoverProjectData { } ``` -As JSON, `DiscoverProjectData::Finished` is: +For example, a progress event: + +```json +{"kind":"progress","message":"generating rust-project.json"} +``` + +A finished event can look like this (expanded and +commented for readability): ```json { @@ -1667,7 +1723,7 @@ As JSON, `DiscoverProjectData::Finished` is: "kind": "finished", // the file used by a non-Cargo build system to define // a package or target. - "buildfile": "rust-analyzer/BUILD", + "buildfile": "rust-analyzer/BUCK", // the contents of a rust-project.json, elided for brevity "project": { "sysroot": "foo", @@ -1676,41 +1732,9 @@ As JSON, `DiscoverProjectData::Finished` is: } ``` -It is encouraged, but not required, to use the other variants on `DiscoverProjectData` -to provide a more polished end-user experience. - -`DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`, which will be -substituted with the JSON-serialized form of the following enum: - -```norun -#[derive(PartialEq, Clone, Debug, Serialize)] -#[serde(rename_all = "camelCase")] -pub enum DiscoverArgument { - Path(AbsPathBuf), - Buildfile(AbsPathBuf), -} -``` - -The JSON representation of `DiscoverArgument::Path` is: - -```json -{ - "path": "src/main.rs" -} -``` - -Similarly, the JSON representation of `DiscoverArgument::Buildfile` is: - -```json -{ - "buildfile": "BUILD" -} -``` - -`DiscoverArgument::Path` is used to find and generate a `rust-project.json`, and -therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to to update an -existing workspace. As a reference for implementors, buck2's `rust-project` will likely -be useful: . +Only the finished event is required, but the other +variants are encouraged to give users more feedback about +progress or errors. ## rust-analyzer.workspace.symbol.search.excludeImports {#workspace.symbol.search.excludeImports} diff --git a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md index a48b025c7b3a..f1f10ae33653 100644 --- a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md +++ b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md @@ -237,7 +237,7 @@ There are four ways to feed `rust-project.json` to rust-analyzer: [`"rust-analyzer.workspace.discoverConfig": … }`](./configuration.md#workspace.discoverConfig) to specify a workspace discovery command to generate project descriptions on-the-fly. Please note that the command output is message-oriented and must - follow [the discovery protocol](./configuration.md#workspace-discovery-protocol). + output JSONL [as described in the configuration docs](./configuration.md#workspace.discoverConfig). - Place `rust-project.json` file at the root of the project, and rust-analyzer will discover it. diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 0d91378706a4..a197b7abd84c 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -3135,7 +3135,7 @@ "title": "Workspace", "properties": { "rust-analyzer.workspace.discoverConfig": { - "markdownDescription": "Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].\n\n[`DiscoverWorkspaceConfig`] also requires setting `progressLabel` and `filesToWatch`.\n`progressLabel` is used for the title in progress indicators, whereas `filesToWatch`\nis used to determine which build system-specific files should be watched in order to\nreload rust-analyzer.\n\nBelow is an example of a valid configuration:\n```json\n\"rust-analyzer.workspace.discoverConfig\": {\n \"command\": [\n \"rust-project\",\n \"develop-json\",\n \"{arg}\"\n ],\n \"progressLabel\": \"buck2/rust-project\",\n \"filesToWatch\": [\n \"BUCK\"\n ]\n}\n```\n\n## Workspace Discovery Protocol\n\n**Warning**: This format is provisional and subject to change.\n\n[`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to\n`DiscoverProjectData::Finished`:\n\n```norun\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(tag = \"kind\")]\n#[serde(rename_all = \"snake_case\")]\nenum DiscoverProjectData {\n Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },\n Error { error: String, source: Option },\n Progress { message: String },\n}\n```\n\nAs JSON, `DiscoverProjectData::Finished` is:\n\n```json\n{\n // the internally-tagged representation of the enum.\n \"kind\": \"finished\",\n // the file used by a non-Cargo build system to define\n // a package or target.\n \"buildfile\": \"rust-analyzer/BUILD\",\n // the contents of a rust-project.json, elided for brevity\n \"project\": {\n \"sysroot\": \"foo\",\n \"crates\": []\n }\n}\n```\n\nIt is encouraged, but not required, to use the other variants on `DiscoverProjectData`\nto provide a more polished end-user experience.\n\n`DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`, which will be\nsubstituted with the JSON-serialized form of the following enum:\n\n```norun\n#[derive(PartialEq, Clone, Debug, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub enum DiscoverArgument {\n Path(AbsPathBuf),\n Buildfile(AbsPathBuf),\n}\n```\n\nThe JSON representation of `DiscoverArgument::Path` is:\n\n```json\n{\n \"path\": \"src/main.rs\"\n}\n```\n\nSimilarly, the JSON representation of `DiscoverArgument::Buildfile` is:\n\n```json\n{\n \"buildfile\": \"BUILD\"\n}\n```\n\n`DiscoverArgument::Path` is used to find and generate a `rust-project.json`, and\ntherefore, a workspace, whereas `DiscoverArgument::buildfile` is used to to update an\nexisting workspace. As a reference for implementors, buck2's `rust-project` will likely\nbe useful: .", + "markdownDescription": "Configure a command that rust-analyzer can invoke to\nobtain configuration.\n\nThis is an alternative to manually generating\n`rust-project.json`: it enables rust-analyzer to generate\nrust-project.json on the fly, and regenerate it when\nswitching or modifying projects.\n\nThis is an object with three fields:\n\n* `command`: the shell command to invoke\n\n* `filesToWatch`: which build system-specific files should\nbe watched to trigger regenerating the configuration\n\n* `progressLabel`: the name of the command, used in\nprogress indicators in the IDE\n\nHere's an example of a valid configuration:\n\n```json\n\"rust-analyzer.workspace.discoverConfig\": {\n \"command\": [\n \"rust-project\",\n \"develop-json\",\n \"{arg}\"\n ],\n \"progressLabel\": \"buck2/rust-project\",\n \"filesToWatch\": [\n \"BUCK\"\n ]\n}\n```\n\n## Argument Substitutions\n\nIf `command` includes the argument `{arg}`, that argument will be substituted\nwith the JSON-serialized form of the following enum:\n\n```norun\n#[derive(PartialEq, Clone, Debug, Serialize)]\n#[serde(rename_all = \"camelCase\")]\npub enum DiscoverArgument {\n Path(AbsPathBuf),\n Buildfile(AbsPathBuf),\n}\n```\n\nrust-analyzer will use the path invocation to find and\ngenerate a `rust-project.json` and therefore a\nworkspace. Example:\n\n\n```norun\nrust-project develop-json '{ \"path\": \"myproject/src/main.rs\" }'\n```\n\nrust-analyzer will use build file invocations to update an\nexisting workspace. Example:\n\nOr with a build file and the configuration above:\n\n```norun\nrust-project develop-json '{ \"buildfile\": \"myproject/BUCK\" }'\n```\n\nAs a reference for implementors, buck2's `rust-project`\nwill likely be useful:\n.\n\n## Discover Command Output\n\n**Warning**: This format is provisional and subject to change.\n\nThe discover command should output JSON objects, one per\nline (JSONL format). These objects should correspond to\nthis Rust data type:\n\n```norun\n#[derive(Debug, Clone, Deserialize, Serialize)]\n#[serde(tag = \"kind\")]\n#[serde(rename_all = \"snake_case\")]\nenum DiscoverProjectData {\n Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },\n Error { error: String, source: Option },\n Progress { message: String },\n}\n```\n\nFor example, a progress event:\n\n```json\n{\"kind\":\"progress\",\"message\":\"generating rust-project.json\"}\n```\n\nA finished event can look like this (expanded and\ncommented for readability):\n\n```json\n{\n // the internally-tagged representation of the enum.\n \"kind\": \"finished\",\n // the file used by a non-Cargo build system to define\n // a package or target.\n \"buildfile\": \"rust-analyzer/BUCK\",\n // the contents of a rust-project.json, elided for brevity\n \"project\": {\n \"sysroot\": \"foo\",\n \"crates\": []\n }\n}\n```\n\nOnly the finished event is required, but the other\nvariants are encouraged to give users more feedback about\nprogress or errors.", "default": null, "anyOf": [ { From 1028c7a66a718a6421241b3a46268681f79fd597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sun, 11 Jan 2026 20:10:22 +0100 Subject: [PATCH 2139/3801] Avoid ICEs after bad patterns, for the other syntactic variants --- compiler/rustc_hir_typeck/src/pat.rs | 13 +++--- tests/ui/pattern/type_mismatch.rs | 63 ++++++++++++++++++++++++++- tests/ui/pattern/type_mismatch.stderr | 61 +++++++++++++++++++++++++- 3 files changed, 128 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 90e22b2cd381..b56ab6dcb4ab 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1512,11 +1512,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { // Type-check the path. - let _ = self.demand_eqtype_pat(pat.span, expected, pat_ty, &pat_info.top_info); + let had_err = self.demand_eqtype_pat(pat.span, expected, pat_ty, &pat_info.top_info); // Type-check subpatterns. match self.check_struct_pat_fields(pat_ty, pat, variant, fields, has_rest_pat, pat_info) { - Ok(()) => pat_ty, + Ok(()) => match had_err { + Ok(()) => pat_ty, + Err(guar) => Ty::new_error(self.tcx, guar), + }, Err(guar) => Ty::new_error(self.tcx, guar), } } @@ -1764,8 +1767,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Type-check the tuple struct pattern against the expected type. - let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, &pat_info.top_info); - let had_err = diag.map_err(|diag| diag.emit()); + let had_err = self.demand_eqtype_pat(pat.span, expected, pat_ty, &pat_info.top_info); // Type-check subpatterns. if subpats.len() == variant.fields.len() @@ -1989,11 +1991,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Err(reported) = self.demand_eqtype_pat(span, expected, pat_ty, &pat_info.top_info) { // Walk subpatterns with an expected type of `err` in this case to silence // further errors being emitted when using the bindings. #50333 - let element_tys_iter = (0..max_len).map(|_| Ty::new_error(tcx, reported)); for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { self.check_pat(elem, Ty::new_error(tcx, reported), pat_info); } - Ty::new_tup_from_iter(tcx, element_tys_iter) + Ty::new_error(tcx, reported) } else { for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { self.check_pat(elem, element_tys[i], pat_info); diff --git a/tests/ui/pattern/type_mismatch.rs b/tests/ui/pattern/type_mismatch.rs index 408ff7588471..39d57301e98f 100644 --- a/tests/ui/pattern/type_mismatch.rs +++ b/tests/ui/pattern/type_mismatch.rs @@ -1,4 +1,4 @@ -//! This test used to ICE: rust-lang/rust#109812 +//! These tests used to ICE: rust-lang/rust#109812, rust-lang/rust#150507 //! Instead of actually analyzing the erroneous patterns, //! we instead stop after typeck where errors are already //! reported. @@ -8,12 +8,21 @@ enum Either { One(X), Two(X), + Three { a: X }, } struct X(Y); struct Y; +struct Z(*const i32); +unsafe impl Send for Z {} + +enum Meow { + A { a: Z }, + B(Z), +} + fn consume_fnmut(_: impl FnMut()) {} fn move_into_fnmut() { @@ -25,6 +34,58 @@ fn move_into_fnmut() { let X(mut _t) = x; }); + + consume_fnmut(|| { + let Either::Three { a: ref mut _t } = x; + //~^ ERROR: mismatched types + + let X(mut _t) = x; + }); +} + +fn tuple_against_array() { + let variant: [();1] = [()]; + + || match variant { + (2,) => (), + //~^ ERROR: mismatched types + _ => {} + }; + + || { + let ((2,) | _) = variant; + //~^ ERROR: mismatched types + }; +} + +// Reproducer that triggers the compatibility lint more reliably, instead of relying on the fact +// that at the time of writing, an unresolved integer type variable does not implement any +// auto-traits. +// +// The @_ makes this example also reproduce ICE #150507 before PR #138961 +fn arcane() { + let variant: [();1] = [()]; + + || { + match variant { + (Z(y@_),) => {} + //~^ ERROR: mismatched types + } + }; + + || { + match variant { + Meow::A { a: Z(y@_) } => {} + //~^ ERROR: mismatched types + } + }; + + || { + match variant { + Meow::B(Z(y@_)) => {} + //~^ ERROR: mismatched types + } + }; } fn main() {} diff --git a/tests/ui/pattern/type_mismatch.stderr b/tests/ui/pattern/type_mismatch.stderr index b0441b1fadcf..3f24b2e70694 100644 --- a/tests/ui/pattern/type_mismatch.stderr +++ b/tests/ui/pattern/type_mismatch.stderr @@ -1,11 +1,68 @@ error[E0308]: mismatched types - --> $DIR/type_mismatch.rs:23:13 + --> $DIR/type_mismatch.rs:32:13 | LL | let Either::Two(ref mut _t) = x; | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `X` | | | expected `X`, found `Either` -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:39:13 + | +LL | let Either::Three { a: ref mut _t } = x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `X` + | | + | expected `X`, found `Either` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:50:9 + | +LL | || match variant { + | ------- this expression has type `[(); 1]` +LL | (2,) => (), + | ^^^^ expected `[(); 1]`, found `(_,)` + | + = note: expected array `[(); 1]` + found tuple `(_,)` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:56:14 + | +LL | let ((2,) | _) = variant; + | ^^^^ ------- this expression has type `[(); 1]` + | | + | expected `[(); 1]`, found `(_,)` + | + = note: expected array `[(); 1]` + found tuple `(_,)` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:71:13 + | +LL | match variant { + | ------- this expression has type `[(); 1]` +LL | (Z(y@_),) => {} + | ^^^^^^^^^ expected `[(); 1]`, found `(_,)` + | + = note: expected array `[(); 1]` + found tuple `(_,)` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:78:13 + | +LL | match variant { + | ------- this expression has type `[(); 1]` +LL | Meow::A { a: Z(y@_) } => {} + | ^^^^^^^^^^^^^^^^^^^^^ expected `[(); 1]`, found `Meow` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:85:13 + | +LL | match variant { + | ------- this expression has type `[(); 1]` +LL | Meow::B(Z(y@_)) => {} + | ^^^^^^^^^^^^^^^ expected `[(); 1]`, found `Meow` + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0308`. From a1a944880f89b275745d1c5838463433980b3f72 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Wed, 14 Jan 2026 21:16:54 +0100 Subject: [PATCH 2140/3801] checksum-freshness: Add binary file inclusion to integration test --- tests/run-make/checksum-freshness/binary_file | 1 + tests/run-make/checksum-freshness/expected.d | 6 ++++-- tests/run-make/checksum-freshness/lib.rs | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 tests/run-make/checksum-freshness/binary_file diff --git a/tests/run-make/checksum-freshness/binary_file b/tests/run-make/checksum-freshness/binary_file new file mode 100644 index 000000000000..45f1873fb781 --- /dev/null +++ b/tests/run-make/checksum-freshness/binary_file @@ -0,0 +1 @@ +binary \ No newline at end of file diff --git a/tests/run-make/checksum-freshness/expected.d b/tests/run-make/checksum-freshness/expected.d index 51467af53a20..4554c509e36e 100644 --- a/tests/run-make/checksum-freshness/expected.d +++ b/tests/run-make/checksum-freshness/expected.d @@ -1,6 +1,8 @@ -lib.d: lib.rs foo.rs +lib.d: lib.rs foo.rs binary_file lib.rs: foo.rs: -# checksum:blake3=94af75ee4ed805434484c3de51c9025278e5c3ada2315e2592052e102168a503 file_len:120 lib.rs +binary_file: +# checksum:blake3=4ac56f3f877798fb762d714c7bcb72e70133f4cc585f80dbd99c07755ae2c7f6 file_len:222 lib.rs # checksum:blake3=2720e17bfda4f3b2a5c96bb61b7e76ed8ebe3359b34128c0e5d8032c090a4f1a file_len:119 foo.rs +# checksum:blake3=119a5db8711914922c5b1c1908be4958175c5afa95c08888de594725329b5439 file_len:7 binary_file diff --git a/tests/run-make/checksum-freshness/lib.rs b/tests/run-make/checksum-freshness/lib.rs index 7bc6757959b1..0cd4243423de 100644 --- a/tests/run-make/checksum-freshness/lib.rs +++ b/tests/run-make/checksum-freshness/lib.rs @@ -1,7 +1,8 @@ // A basic library to be used in tests with no real purpose. mod foo; - +// Binary file with invalid UTF-8 sequence. +static BINARY_FILE: &[u8] = include_bytes!("binary_file"); pub fn sum(a: i32, b: i32) -> i32 { a + b } From 436fb87eeb833f8986ca520311e91f32ed0c32e2 Mon Sep 17 00:00:00 2001 From: Zijie Zhao Date: Wed, 14 Jan 2026 14:20:45 -0600 Subject: [PATCH 2141/3801] Rename `rust.use-lld` to `rust.bootstrap-override-lld` in INSTALL.md --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 98eb825cd10f..dd6c64b3df5f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -97,7 +97,7 @@ See [the rustc-dev-guide for more info][sysllvm]. --set llvm.ninja=false \ --set rust.debug-assertions=false \ --set rust.jemalloc \ - --set rust.use-lld=true \ + --set rust.bootstrap-override-lld=true \ --set rust.lto=thin \ --set rust.codegen-units=1 ``` From ed7479c658484647858e08342a9aa00aa0fb5b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 14 Jan 2026 21:47:24 +0100 Subject: [PATCH 2142/3801] Add the GCC codegen backend to build-manifest --- src/tools/build-manifest/src/main.rs | 3 ++- src/tools/build-manifest/src/versions.rs | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 4cec1b1f164b..7c0c528bcc04 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -32,7 +32,7 @@ static DOCS_FALLBACK: &[(&str, &str)] = &[ static PKG_INSTALLERS: &[&str] = &["x86_64-apple-darwin", "aarch64-apple-darwin"]; static NIGHTLY_ONLY_COMPONENTS: &[PkgType] = - &[PkgType::Miri, PkgType::JsonDocs, PkgType::RustcCodegenCranelift]; + &[PkgType::Miri, PkgType::JsonDocs, PkgType::RustcCodegenCranelift, PkgType::RustcCodegenGcc]; macro_rules! t { ($e:expr) => { @@ -302,6 +302,7 @@ impl Builder { | PkgType::RustAnalysis | PkgType::JsonDocs | PkgType::RustcCodegenCranelift + | PkgType::RustcCodegenGcc | PkgType::LlvmBitcodeLinker => { extensions.push(host_component(pkg)); } diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 6ef8a0e83de3..1e55d1d467e6 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -59,6 +59,7 @@ pkg_type! { JsonDocs = "rust-docs-json"; preview = true, RustcCodegenCranelift = "rustc-codegen-cranelift"; preview = true, LlvmBitcodeLinker = "llvm-bitcode-linker"; preview = true, + RustcCodegenGcc = "rustc-codegen-gcc"; preview = true, } impl PkgType { @@ -82,6 +83,7 @@ impl PkgType { PkgType::LlvmTools => false, PkgType::Miri => false, PkgType::RustcCodegenCranelift => false, + PkgType::RustcCodegenGcc => false, PkgType::Rust => true, PkgType::RustStd => true, @@ -111,6 +113,7 @@ impl PkgType { RustcDocs => HOSTS, Cargo => HOSTS, RustcCodegenCranelift => HOSTS, + RustcCodegenGcc => HOSTS, RustMingw => MINGW, RustStd => TARGETS, HtmlDocs => HOSTS, From 4ceb13807e8062d5a4a3e9adecbd1d42a61eecf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 14 Jan 2026 21:49:44 +0100 Subject: [PATCH 2143/3801] Forbid distributing GCC on CI if `gcc.download-ci-gcc` is enabled --- src/bootstrap/src/core/build_steps/dist.rs | 10 +++++++++- src/bootstrap/src/core/config/mod.rs | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index cfcb144e0993..bfffc958f858 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -30,7 +30,7 @@ use crate::core::build_steps::tool::{ use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor}; use crate::core::build_steps::{compile, llvm}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata}; -use crate::core::config::TargetSelection; +use crate::core::config::{GccCiMode, TargetSelection}; use crate::utils::build_stamp::{self, BuildStamp}; use crate::utils::channel::{self, Info}; use crate::utils::exec::{BootstrapCommand, command}; @@ -3035,6 +3035,14 @@ impl Step for Gcc { return None; } + if builder.config.is_running_on_ci { + assert_eq!( + builder.config.gcc_ci_mode, + GccCiMode::BuildLocally, + "Cannot use gcc.download-ci-gcc when distributing GCC on CI" + ); + } + // We need the GCC sources to build GCC and also to add its license and README // files to the tarball builder.require_submodule( diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs index 007ed4aaba13..7651def62672 100644 --- a/src/bootstrap/src/core/config/mod.rs +++ b/src/bootstrap/src/core/config/mod.rs @@ -425,7 +425,7 @@ impl std::str::FromStr for RustcLto { } /// Determines how will GCC be provided. -#[derive(Default, Clone)] +#[derive(Default, Debug, Clone, PartialEq)] pub enum GccCiMode { /// Build GCC from the local `src/gcc` submodule. BuildLocally, From e4e2e8bd6f607e16c35c966f16a616daced632e7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 14 Jan 2026 16:37:01 +0100 Subject: [PATCH 2144/3801] Fix `deprecated` attribute intra-doc link not resolved in the right location on reexported item --- .../passes/collect_intra_doc_links.rs | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 07d6efaa97e1..8a37f46b9a96 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -7,7 +7,6 @@ use std::fmt::Display; use std::mem; use std::ops::Range; -use rustc_ast::attr::AttributeExt; use rustc_ast::util::comments::may_have_doc_links; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; @@ -1038,10 +1037,11 @@ fn preprocessed_markdown_links(s: &str) -> Vec { impl LinkCollector<'_, '_> { #[instrument(level = "debug", skip_all)] fn resolve_links(&mut self, item: &Item) { + let tcx = self.cx.tcx; if !self.cx.document_private() && let Some(def_id) = item.item_id.as_def_id() && let Some(def_id) = def_id.as_local() - && !self.cx.tcx.effective_visibilities(()).is_exported(def_id) + && !tcx.effective_visibilities(()).is_exported(def_id) && !has_primitive_or_keyword_or_attribute_docs(&item.attrs.other_attrs) { // Skip link resolution for non-exported items. @@ -1049,9 +1049,9 @@ impl LinkCollector<'_, '_> { } let mut insert_links = |item_id, doc: &str| { - let module_id = match self.cx.tcx.def_kind(item_id) { - DefKind::Mod if item.inner_docs(self.cx.tcx) => item_id, - _ => find_nearest_parent_module(self.cx.tcx, item_id).unwrap(), + let module_id = match tcx.def_kind(item_id) { + DefKind::Mod if item.inner_docs(tcx) => item_id, + _ => find_nearest_parent_module(tcx, item_id).unwrap(), }; for md_link in preprocessed_markdown_links(&doc) { let link = self.resolve_link(&doc, item, item_id, module_id, &md_link); @@ -1084,7 +1084,14 @@ impl LinkCollector<'_, '_> { // Also resolve links in the note text of `#[deprecated]`. for attr in &item.attrs.other_attrs { - let Some(note_sym) = attr.deprecation_note() else { continue }; + let rustc_hir::Attribute::Parsed(rustc_hir::attrs::AttributeKind::Deprecation { + span, + deprecation, + }) = attr + else { + continue; + }; + let Some(note_sym) = deprecation.note else { continue }; let note = note_sym.as_str(); if !may_have_doc_links(note) { @@ -1092,7 +1099,18 @@ impl LinkCollector<'_, '_> { } debug!("deprecated_note={note}"); - insert_links(item.item_id.expect_def_id(), note) + // When resolving an intra-doc link inside a deprecation note that is on an inlined + // `use` statement, we need to use the `def_id` of the `use` statement, not the + // inlined item. + // + let item_id = if let Some(inline_stmt_id) = item.inline_stmt_id + && item.span(tcx).is_none_or(|item_span| !item_span.inner().contains(*span)) + { + inline_stmt_id.to_def_id() + } else { + item.item_id.expect_def_id() + }; + insert_links(item_id, note) } } From c341745970fa9f18e5f87166bba95574231edebf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 14 Jan 2026 16:37:24 +0100 Subject: [PATCH 2145/3801] Add regression test for #151028 --- .../intra-doc/ice-deprecated-note-on-reexport.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/rustdoc-html/intra-doc/ice-deprecated-note-on-reexport.rs diff --git a/tests/rustdoc-html/intra-doc/ice-deprecated-note-on-reexport.rs b/tests/rustdoc-html/intra-doc/ice-deprecated-note-on-reexport.rs new file mode 100644 index 000000000000..99415a9a2fd4 --- /dev/null +++ b/tests/rustdoc-html/intra-doc/ice-deprecated-note-on-reexport.rs @@ -0,0 +1,11 @@ +// This test ensures that the intra-doc link in `deprecated` note is resolved at the correct +// location (ie in the current crate and not in the reexported item's location/crate) and +// therefore doesn't crash. +// +// This is a regression test for . + +#![crate_name = "foo"] + +#[deprecated(note = "use [`std::mem::forget`]")] +#[doc(inline)] +pub use std::mem::drop; From 4ded6397b376b0a005c26381ed92c944e3702019 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 14 Jan 2026 00:45:16 +0100 Subject: [PATCH 2146/3801] Add new "hide deprecated items" setting in rustdoc --- src/librustdoc/clean/auto_trait.rs | 1 + src/librustdoc/clean/blanket_impl.rs | 3 ++ src/librustdoc/clean/inline.rs | 3 ++ src/librustdoc/clean/mod.rs | 4 ++ src/librustdoc/clean/types.rs | 8 ++++ src/librustdoc/html/render/mod.rs | 33 +++++++++++---- src/librustdoc/html/render/print_item.rs | 49 +++++++++++++++------- src/librustdoc/html/static/css/rustdoc.css | 9 ++++ src/librustdoc/html/static/js/search.js | 3 ++ src/librustdoc/html/static/js/settings.js | 11 +++++ src/librustdoc/html/static/js/storage.js | 3 ++ src/librustdoc/json/conversions.rs | 3 +- 12 files changed, 107 insertions(+), 23 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 6c67916571a4..847e688d03d0 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -126,6 +126,7 @@ fn synthesize_auto_trait_impl<'tcx>( items: Vec::new(), polarity, kind: clean::ImplKind::Auto, + is_deprecated: false, })), item_id: clean::ItemId::Auto { trait_: trait_def_id, for_: item_def_id }, cfg: None, diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index ddfce7aeb92d..de45922e856f 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -117,6 +117,9 @@ pub(crate) fn synthesize_blanket_impls( None, None, ))), + is_deprecated: tcx + .lookup_deprecation(impl_def_id) + .is_some_and(|deprecation| deprecation.is_in_effect()), })), cfg: None, inline_stmt_id: None, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c86a655c083a..19974f4847d4 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -645,6 +645,9 @@ pub(crate) fn build_impl( } else { ImplKind::Normal }, + is_deprecated: tcx + .lookup_deprecation(did) + .is_some_and(|deprecation| deprecation.is_in_effect()), })), merged_attrs, cfg, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 817eda4c52ec..0e970a042ff0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2882,6 +2882,9 @@ fn clean_impl<'tcx>( )), _ => None, }); + let is_deprecated = tcx + .lookup_deprecation(def_id.to_def_id()) + .is_some_and(|deprecation| deprecation.is_in_effect()); let mut make_item = |trait_: Option, for_: Type, items: Vec| { let kind = ImplItem(Box::new(Impl { safety: match impl_.of_trait { @@ -2902,6 +2905,7 @@ fn clean_impl<'tcx>( } else { ImplKind::Normal }, + is_deprecated, })); Item::from_def_id_and_parts(def_id.to_def_id(), None, kind, cx) }; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c3bafd3db13a..93863ea41396 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -427,6 +427,10 @@ impl Item { }) } + pub(crate) fn is_deprecated(&self, tcx: TyCtxt<'_>) -> bool { + self.deprecation(tcx).is_some_and(|deprecation| deprecation.is_in_effect()) + } + pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool { self.item_id.as_def_id().map(|did| inner_docs(tcx.get_all_attrs(did))).unwrap_or(false) } @@ -1270,6 +1274,9 @@ impl Trait { pub(crate) fn is_dyn_compatible(&self, tcx: TyCtxt<'_>) -> bool { tcx.is_dyn_compatible(self.def_id) } + pub(crate) fn is_deprecated(&self, tcx: TyCtxt<'_>) -> bool { + tcx.lookup_deprecation(self.def_id).is_some_and(|deprecation| deprecation.is_in_effect()) + } } #[derive(Clone, Debug)] @@ -2254,6 +2261,7 @@ pub(crate) struct Impl { pub(crate) items: Vec, pub(crate) polarity: ty::ImplPolarity, pub(crate) kind: ImplKind, + pub(crate) is_deprecated: bool, } impl Impl { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 63de870f07f4..106aefa4626b 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1794,12 +1794,14 @@ fn render_impl( let mut info_buffer = String::new(); let mut short_documented = true; + let mut trait_item_deprecated = false; if render_method_item { if !is_default_item { if let Some(t) = trait_ { // The trait item may have been stripped so we might not // find any documentation or stability for it. if let Some(it) = t.items.iter().find(|i| i.name == item.name) { + trait_item_deprecated = it.is_deprecated(cx.tcx()); // We need the stability of the item from the trait // because impls can't have a stability. if !item.doc_value().is_empty() { @@ -1839,10 +1841,20 @@ fn render_impl( Either::Right(boring) }; + let mut deprecation_class = if trait_item_deprecated || item.is_deprecated(cx.tcx()) { + " deprecated" + } else { + "" + }; + let toggled = !doc_buffer.is_empty(); if toggled { let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" }; - write!(w, "

    ")?; + write!( + w, + "
    " + )?; + deprecation_class = ""; } match &item.kind { clean::MethodItem(..) | clean::RequiredMethodItem(_) => { @@ -1859,7 +1871,7 @@ fn render_impl( .map(|item| format!("{}.{name}", item.type_())); write!( w, - "
    \ + "
    \ {}", render_rightside(cx, item, render_mode) )?; @@ -1885,7 +1897,7 @@ fn render_impl( let id = cx.derive_id(&source_id); write!( w, - "
    \ + "
    \ {}", render_rightside(cx, item, render_mode) )?; @@ -1912,7 +1924,7 @@ fn render_impl( let id = cx.derive_id(&source_id); write!( w, - "
    \ + "
    \ {}", render_rightside(cx, item, render_mode), )?; @@ -1944,7 +1956,7 @@ fn render_impl( let id = cx.derive_id(&source_id); write!( w, - "
    \ + "
    \ {}", render_rightside(cx, item, render_mode), )?; @@ -1971,7 +1983,7 @@ fn render_impl( let id = cx.derive_id(&source_id); write!( w, - "
    \ + "
    \ {}", render_rightside(cx, item, render_mode), )?; @@ -2143,11 +2155,18 @@ fn render_impl( } if render_mode == RenderMode::Normal { let toggled = !(impl_items.is_empty() && default_impl_items.is_empty()); + let deprecation_attr = if impl_.is_deprecated + || trait_.is_some_and(|trait_| trait_.is_deprecated(cx.tcx())) + { + " deprecated" + } else { + "" + }; if toggled { close_tags.push("
    "); write!( w, - "
    \ + "
    \ ", if rendering_params.toggle_open_by_default { " open" } else { "" } )?; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 84e93a479b5b..55e36c462f96 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -217,6 +217,10 @@ fn toggle_close(mut w: impl fmt::Write) { } fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> impl fmt::Display { + fn deprecation_class_attr(is_deprecated: bool) -> &'static str { + if is_deprecated { " class=\"deprecated\"" } else { "" } + } + fmt::from_fn(|w| { write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?; @@ -370,11 +374,18 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i write!(w, "")? } clean::ImportItem(ref import) => { - let stab_tags = - import.source.did.map_or_else(String::new, |import_def_id| { - print_extra_info_tags(tcx, myitem, item, Some(import_def_id)) - .to_string() - }); + let (stab_tags, deprecation) = match import.source.did { + Some(import_def_id) => { + let stab_tags = + print_extra_info_tags(tcx, myitem, item, Some(import_def_id)) + .to_string(); + let deprecation = tcx + .lookup_deprecation(import_def_id) + .is_some_and(|deprecation| deprecation.is_in_effect()); + (stab_tags, deprecation) + } + None => (String::new(), item.is_deprecated(tcx)), + }; let id = match import.kind { clean::ImportKind::Simple(s) => { format!(" id=\"{}\"", cx.derive_id(format!("reexport.{s}"))) @@ -383,8 +394,8 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i }; write!( w, - "\ - " + "", + deprecation_attr = deprecation_class_attr(deprecation) )?; render_attributes_in_code(w, myitem, "", cx)?; write!( @@ -396,9 +407,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i )?; } _ => { - if myitem.name.is_none() { - continue; - } + let Some(item_name) = myitem.name else { continue }; let unsafety_flag = match myitem.kind { clean::FunctionItem(_) | clean::ForeignFunctionItem(..) @@ -431,9 +440,10 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i .into_string(); let (docs_before, docs_after) = if docs.is_empty() { ("", "") } else { ("
    ", "
    ") }; + let deprecation_attr = deprecation_class_attr(myitem.is_deprecated(tcx)); write!( w, - "
    \ + "\ \ {name}\ \ @@ -442,12 +452,12 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i {stab_tags}\
    \ {docs_before}{docs}{docs_after}", - name = EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()), + name = EscapeBodyTextWithWbr(item_name.as_str()), visibility_and_hidden = visibility_and_hidden, stab_tags = print_extra_info_tags(tcx, myitem, item, None), class = type_, unsafety_flag = unsafety_flag, - href = print_item_path(type_, myitem.name.unwrap().as_str()), + href = print_item_path(type_, item_name.as_str()), title1 = myitem.type_(), title2 = full_path(cx, myitem), )?; @@ -778,15 +788,24 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: let content = document_full(m, cx, HeadingOffset::H5).to_string(); + let mut deprecation_class = + if m.is_deprecated(cx.tcx()) { " deprecated" } else { "" }; + let toggled = !content.is_empty(); if toggled { let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" }; - write!(w, "
    ")?; + write!( + w, + "
    " + )?; + deprecation_class = ""; } write!( w, - "
    \ + "
    \ {}\

    {}

    ", render_rightside(cx, m, RenderMode::Normal), diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index b770a0e2a0e4..73eb260a2b8e 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -2642,6 +2642,15 @@ However, it's not needed with smaller screen width because the doc/code block is } } +/* Items on module pages */ +.hide-deprecated-items dt.deprecated, +.hide-deprecated-items dt.deprecated + dd, +/* Items on item pages */ +.hide-deprecated-items .deprecated, +.hide-deprecated-items .deprecated + .item-info { + display: none; +} + /* WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY If you update this line, then you also need to update the line with the same warning diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index b2880a2f4c2b..9961c1447ec2 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -4920,6 +4920,9 @@ async function addTab(results, query, display, finishedCallback, isTypeSearch) { const link = document.createElement("a"); link.className = "result-" + type; + if (obj.item.deprecated) { + link.className += " deprecated"; + } link.href = obj.href; const resultName = document.createElement("span"); diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 347d3d0750ec..b28b76b0d2e7 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -78,6 +78,12 @@ removeClass(document.documentElement, "word-wrap-source-code"); } break; + case "hide-deprecated-items": + if (value === true) { + addClass(document.documentElement, "hide-deprecated-items"); + } else { + removeClass(document.documentElement, "hide-deprecated-items"); + } } } @@ -274,6 +280,11 @@ "js_name": "word-wrap-source-code", "default": false, }, + { + "name": "Hide deprecated items", + "js_name": "hide-deprecated-items", + "default": false, + }, ]; // Then we build the DOM. diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 40ab8be03c93..7cc70374378b 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -334,6 +334,9 @@ if (getSettingValue("sans-serif-fonts") === "true") { if (getSettingValue("word-wrap-source-code") === "true") { addClass(document.documentElement, "word-wrap-source-code"); } +if (getSettingValue("hide-deprecated-items") === "true") { + addClass(document.documentElement, "hide-deprecated-items"); +} function updateSidebarWidth() { const desktopSidebarWidth = getSettingValue("desktop-sidebar-width"); if (desktopSidebarWidth && desktopSidebarWidth !== "null") { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 892cc483dbd6..2edf7891be40 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -711,7 +711,8 @@ impl FromClean for PolyTrait { impl FromClean for Impl { fn from_clean(impl_: &clean::Impl, renderer: &JsonRenderer<'_>) -> Self { let provided_trait_methods = impl_.provided_trait_methods(renderer.tcx); - let clean::Impl { safety, generics, trait_, for_, items, polarity, kind } = impl_; + let clean::Impl { safety, generics, trait_, for_, items, polarity, kind, is_deprecated: _ } = + impl_; // FIXME: use something like ImplKind in JSON? let (is_synthetic, blanket_impl) = match kind { clean::ImplKind::Normal | clean::ImplKind::FakeVariadic => (false, None), From 4bacdf7b8b9046507ef5ae3bcb349d54fb827b0d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 14 Jan 2026 22:47:53 +0100 Subject: [PATCH 2147/3801] Reduce rustdoc GUI flakyness, take 2 --- tests/rustdoc-gui/utils.goml | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/tests/rustdoc-gui/utils.goml b/tests/rustdoc-gui/utils.goml index c0625ead2f1a..c5c8ab3b1af8 100644 --- a/tests/rustdoc-gui/utils.goml +++ b/tests/rustdoc-gui/utils.goml @@ -29,9 +29,18 @@ define-function: ( "open-settings-menu", [], block { - call-function: ("click-settings-button", {}) - // Wait for the popover to appear... - wait-for-css: ("#settings", {"display": "block"}) + store-count: ("#settings", nb_settings_menu) + if: (|nb_settings_menu| != 0, block { + store-css: ("#settings", {"display": settings_display}) + }) + else: block { + store-value: (settings_display, "none") + } + if: (|settings_display| != "block", block { + call-function: ("click-settings-button", {}) + // Wait for the popover to appear... + wait-for-css: ("#settings", {"display": "block"}) + }) } ) @@ -39,9 +48,18 @@ define-function: ( "close-settings-menu", [], block { - call-function: ("click-settings-button", {}) - // Wait for the popover to disappear... - wait-for-css-false: ("#settings", {"display": "block"}) + store-count: ("#settings", nb_settings_menu) + if: (|nb_settings_menu| != 0, block { + store-css: ("#settings", {"display": settings_display}) + }) + else: block { + store-value: (settings_display, "block") + } + if: (|settings_display| == "block", block { + call-function: ("click-settings-button", {}) + // Wait for the popover to disappear... + wait-for-css-false: ("#settings", {"display": "block"}) + }) } ) From 36d37fd11b43e4cce1a2d993497937c40db9a7a2 Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 8 Jan 2026 15:44:41 -0800 Subject: [PATCH 2148/3801] THIR: directly contain `HirId`s, not `LintLevel`s --- compiler/rustc_middle/src/thir.rs | 8 +- compiler/rustc_middle/src/thir/visit.rs | 8 +- compiler/rustc_mir_build/src/builder/block.rs | 12 +-- .../src/builder/expr/as_constant.rs | 2 +- .../src/builder/expr/as_operand.rs | 8 +- .../src/builder/expr/as_place.rs | 4 +- .../src/builder/expr/as_rvalue.rs | 8 +- .../src/builder/expr/as_temp.rs | 10 ++- .../rustc_mir_build/src/builder/expr/into.rs | 4 +- .../rustc_mir_build/src/builder/expr/stmt.rs | 8 +- .../src/builder/matches/mod.rs | 6 +- .../rustc_mir_build/src/check_unsafety.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/block.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 4 +- .../src/thir/pattern/check_match.rs | 66 +++++++--------- compiler/rustc_mir_build/src/thir/print.rs | 12 +-- tests/ui/thir-print/c-variadic.stdout | 2 +- tests/ui/thir-print/offset_of.stdout | 76 +++++++++---------- .../thir-print/thir-flat-const-variant.stdout | 36 +++------ tests/ui/thir-print/thir-flat.stdout | 4 +- .../ui/thir-print/thir-tree-loop-match.stdout | 24 +++--- tests/ui/thir-print/thir-tree-match.stdout | 20 ++--- tests/ui/thir-print/thir-tree.stdout | 2 +- tests/ui/unpretty/box.stdout | 8 +- 24 files changed, 155 insertions(+), 181 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 3683c1cfb7dd..86bd6fb803b7 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -236,8 +236,8 @@ pub enum StmtKind<'tcx> { /// `let pat: ty = else { }` else_block: Option, - /// The lint level for this `let` statement. - lint_level: LintLevel, + /// The [`HirId`] for this `let` statement. + hir_id: HirId, /// Span of the `let = ` part. span: Span, @@ -271,7 +271,7 @@ pub enum ExprKind<'tcx> { /// and to track the `HirId` of the expressions within the scope. Scope { region_scope: region::Scope, - lint_level: LintLevel, + hir_id: HirId, value: ExprId, }, /// A `box ` expression. @@ -579,7 +579,7 @@ pub struct Arm<'tcx> { pub pattern: Box>, pub guard: Option, pub body: ExprId, - pub lint_level: LintLevel, + pub hir_id: HirId, pub scope: region::Scope, pub span: Span, } diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index d792bbe60c88..4e30c450c89b 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -47,9 +47,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( use ExprKind::*; let Expr { kind, ty: _, temp_scope_id: _, span: _ } = expr; match *kind { - Scope { value, region_scope: _, lint_level: _ } => { - visitor.visit_expr(&visitor.thir()[value]) - } + Scope { value, region_scope: _, hir_id: _ } => visitor.visit_expr(&visitor.thir()[value]), Box { value } => visitor.visit_expr(&visitor.thir()[value]), If { cond, then, else_opt, if_then_scope: _ } => { visitor.visit_expr(&visitor.thir()[cond]); @@ -205,7 +203,7 @@ pub fn walk_stmt<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( remainder_scope: _, init_scope: _, pattern, - lint_level: _, + hir_id: _, else_block, span: _, } => { @@ -238,7 +236,7 @@ pub fn walk_arm<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( visitor: &mut V, arm: &'thir Arm<'tcx>, ) { - let Arm { guard, pattern, body, lint_level: _, span: _, scope: _ } = arm; + let Arm { guard, pattern, body, hir_id: _, span: _, scope: _ } = arm; if let Some(expr) = guard { visitor.visit_expr(&visitor.thir()[*expr]) } diff --git a/compiler/rustc_mir_build/src/builder/block.rs b/compiler/rustc_mir_build/src/builder/block.rs index 88533ad22648..d8837d2b195a 100644 --- a/compiler/rustc_mir_build/src/builder/block.rs +++ b/compiler/rustc_mir_build/src/builder/block.rs @@ -83,7 +83,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { init_scope, pattern, initializer: Some(initializer), - lint_level, + hir_id, else_block: Some(else_block), span: _, } => { @@ -191,7 +191,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let initializer_span = this.thir[*initializer].span; let scope = (*init_scope, source_info); - let failure_and_block = this.in_scope(scope, *lint_level, |this| { + let lint_level = LintLevel::Explicit(*hir_id); + let failure_and_block = this.in_scope(scope, lint_level, |this| { this.declare_bindings( visibility_scope, remainder_span, @@ -232,7 +233,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { init_scope, pattern, initializer, - lint_level, + hir_id, else_block: None, span: _, } => { @@ -250,12 +251,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some(this.new_source_scope(remainder_span, LintLevel::Inherited)); // Evaluate the initializer, if present. + let lint_level = LintLevel::Explicit(*hir_id); if let Some(init) = *initializer { let initializer_span = this.thir[init].span; let scope = (*init_scope, source_info); block = this - .in_scope(scope, *lint_level, |this| { + .in_scope(scope, lint_level, |this| { this.declare_bindings( visibility_scope, remainder_span, @@ -269,7 +271,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .into_block(); } else { let scope = (*init_scope, source_info); - let _: BlockAnd<()> = this.in_scope(scope, *lint_level, |this| { + let _: BlockAnd<()> = this.in_scope(scope, lint_level, |this| { this.declare_bindings( visibility_scope, remainder_span, diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 186fde4883df..39b4390f7749 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -23,7 +23,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let tcx = this.tcx; let Expr { ty, temp_scope_id: _, span, ref kind } = *expr; match kind { - ExprKind::Scope { region_scope: _, lint_level: _, value } => { + ExprKind::Scope { region_scope: _, hir_id: _, value } => { this.as_constant(&this.thir[*value]) } _ => as_constant_inner( diff --git a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs index 5989a15b9346..c9c166b7f018 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs @@ -122,10 +122,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let this = self; // See "LET_THIS_SELF". let expr = &this.thir[expr_id]; - if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind { + if let ExprKind::Scope { region_scope, hir_id, value } = expr.kind { let source_info = this.source_info(expr.span); let region_scope = (region_scope, source_info); - return this.in_scope(region_scope, lint_level, |this| { + return this.in_scope(region_scope, LintLevel::Explicit(hir_id), |this| { this.as_operand(block, scope, value, local_info, needs_temporary) }); } @@ -165,10 +165,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let expr = &this.thir[expr_id]; debug!("as_call_operand(block={:?}, expr={:?})", block, expr); - if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind { + if let ExprKind::Scope { region_scope, hir_id, value } = expr.kind { let source_info = this.source_info(expr.span); let region_scope = (region_scope, source_info); - return this.in_scope(region_scope, lint_level, |this| { + return this.in_scope(region_scope, LintLevel::Explicit(hir_id), |this| { this.as_call_operand(block, scope, value) }); } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs index cb81b42128a8..db9aa3cd8704 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs @@ -427,8 +427,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let expr_span = expr.span; let source_info = this.source_info(expr_span); match expr.kind { - ExprKind::Scope { region_scope, lint_level, value } => { - this.in_scope((region_scope, source_info), lint_level, |this| { + ExprKind::Scope { region_scope, hir_id, value } => { + this.in_scope((region_scope, source_info), LintLevel::Explicit(hir_id), |this| { this.expr_as_place(block, value, mutability, fake_borrow_temps) }) } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index bb1095ced47a..3d1774bd1d68 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -56,9 +56,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match expr.kind { ExprKind::ThreadLocalRef(did) => block.and(Rvalue::ThreadLocalRef(did)), - ExprKind::Scope { region_scope, lint_level, value } => { + ExprKind::Scope { region_scope, hir_id, value } => { let region_scope = (region_scope, source_info); - this.in_scope(region_scope, lint_level, |this| this.as_rvalue(block, scope, value)) + this.in_scope(region_scope, LintLevel::Explicit(hir_id), |this| { + this.as_rvalue(block, scope, value) + }) } ExprKind::Repeat { value, count } => { if Some(0) == count.try_to_target_usize(this.tcx) { @@ -657,7 +659,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source: eid, is_from_as_cast: _, } - | &ExprKind::Scope { region_scope: _, lint_level: _, value: eid } => { + | &ExprKind::Scope { region_scope: _, hir_id: _, value: eid } => { kind = &self.thir[eid].kind } _ => return matches!(Category::of(&kind), Some(Category::Constant)), diff --git a/compiler/rustc_mir_build/src/builder/expr/as_temp.rs b/compiler/rustc_mir_build/src/builder/expr/as_temp.rs index d8ac19e34aae..2aace64062cd 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_temp.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_temp.rs @@ -39,10 +39,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let expr = &this.thir[expr_id]; let expr_span = expr.span; let source_info = this.source_info(expr_span); - if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind { - return this.in_scope((region_scope, source_info), lint_level, |this| { - this.as_temp(block, temp_lifetime, value, mutability) - }); + if let ExprKind::Scope { region_scope, hir_id, value } = expr.kind { + return this.in_scope( + (region_scope, source_info), + LintLevel::Explicit(hir_id), + |this| this.as_temp(block, temp_lifetime, value, mutability), + ); } let expr_ty = expr.ty; diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index f595cfc77e9d..9731f0de135f 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -45,10 +45,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let block_and = match expr.kind { - ExprKind::Scope { region_scope, lint_level, value } => { + ExprKind::Scope { region_scope, hir_id, value } => { let region_scope = (region_scope, source_info); ensure_sufficient_stack(|| { - this.in_scope(region_scope, lint_level, |this| { + this.in_scope(region_scope, LintLevel::Explicit(hir_id), |this| { this.expr_into_dest(destination, block, value) }) }) diff --git a/compiler/rustc_mir_build/src/builder/expr/stmt.rs b/compiler/rustc_mir_build/src/builder/expr/stmt.rs index 66ee13939849..f28e483b6a5d 100644 --- a/compiler/rustc_mir_build/src/builder/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/builder/expr/stmt.rs @@ -25,8 +25,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Handle a number of expressions that don't need a destination at all. This // avoids needing a mountain of temporary `()` variables. match expr.kind { - ExprKind::Scope { region_scope, lint_level, value } => { - this.in_scope((region_scope, source_info), lint_level, |this| { + ExprKind::Scope { region_scope, hir_id, value } => { + this.in_scope((region_scope, source_info), LintLevel::Explicit(hir_id), |this| { this.stmt_expr(block, value, statement_scope) }) } @@ -106,7 +106,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Become { value } => { let v = &this.thir[value]; - let ExprKind::Scope { value, lint_level, region_scope } = v.kind else { + let ExprKind::Scope { value, hir_id, region_scope } = v.kind else { span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}") }; @@ -115,7 +115,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}") }; - this.in_scope((region_scope, source_info), lint_level, |this| { + this.in_scope((region_scope, source_info), LintLevel::Explicit(hir_id), |this| { let fun = unpack!(block = this.as_local_operand(block, fun)); let args: Box<[_]> = args .into_iter() diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 9080e2ba801b..49caee4a1896 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -182,9 +182,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.break_for_else(success_block, args.variable_source_info); failure_block.unit() } - ExprKind::Scope { region_scope, lint_level, value } => { + ExprKind::Scope { region_scope, hir_id, value } => { let region_scope = (region_scope, this.source_info(expr_span)); - this.in_scope(region_scope, lint_level, |this| { + this.in_scope(region_scope, LintLevel::Explicit(hir_id), |this| { this.then_else_break_inner(block, value, args) }) } @@ -434,7 +434,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let guard_scope = arm .guard .map(|_| region::Scope { data: region::ScopeData::MatchGuard, ..arm.scope }); - self.in_scope(arm_scope, arm.lint_level, |this| { + self.in_scope(arm_scope, LintLevel::Explicit(arm.hir_id), |this| { this.opt_in_scope(guard_scope.map(|scope| (scope, arm_source_info)), |this| { // `if let` guard temps needing deduplicating will be in the guard scope. let old_dedup_scope = diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 4f03e3d965c6..e330242c8a1f 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -478,7 +478,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } }; match expr.kind { - ExprKind::Scope { value, lint_level: LintLevel::Explicit(hir_id), region_scope: _ } => { + ExprKind::Scope { value, hir_id, region_scope: _ } => { let prev_id = self.hir_context; self.hir_context = hir_id; ensure_sufficient_stack(|| { diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 7cdd70a7fc27..fad73a7115b0 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -88,7 +88,7 @@ impl<'tcx> ThirBuildCx<'tcx> { pattern, initializer: local.init.map(|init| self.mirror_expr(init)), else_block, - lint_level: LintLevel::Explicit(local.hir_id), + hir_id: local.hir_id, span, }, }; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 50ccbd50d971..8e02424706ee 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -77,7 +77,7 @@ impl<'tcx> ThirBuildCx<'tcx> { kind: ExprKind::Scope { region_scope: expr_scope, value: self.thir.exprs.push(expr), - lint_level: LintLevel::Explicit(hir_expr.hir_id), + hir_id: hir_expr.hir_id, }, }; @@ -1192,7 +1192,7 @@ impl<'tcx> ThirBuildCx<'tcx> { pattern: self.pattern_from_hir(&arm.pat), guard: arm.guard.as_ref().map(|g| self.mirror_expr(g)), body: self.mirror_expr(arm.body), - lint_level: LintLevel::Explicit(arm.hir_id), + hir_id: arm.hir_id, scope: region::Scope { local_id: arm.hir_id.local_id, data: region::ScopeData::Node }, span: arm.span, }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index bf480cf601ee..b8c64d98881b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -43,7 +43,7 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err typeck_results, // FIXME(#132279): We're in a body, should handle opaques. typing_env: ty::TypingEnv::non_body_analysis(tcx, def_id), - lint_level: tcx.local_def_id_to_hir_id(def_id), + hir_source: tcx.local_def_id_to_hir_id(def_id), let_source: LetSource::None, pattern_arena: &pattern_arena, dropless_arena: &dropless_arena, @@ -92,7 +92,7 @@ struct MatchVisitor<'p, 'tcx> { typing_env: ty::TypingEnv<'tcx>, typeck_results: &'tcx ty::TypeckResults<'tcx>, thir: &'p Thir<'tcx>, - lint_level: HirId, + hir_source: HirId, let_source: LetSource, pattern_arena: &'p TypedArena>, dropless_arena: &'p DroplessArena, @@ -111,7 +111,7 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> { #[instrument(level = "trace", skip(self))] fn visit_arm(&mut self, arm: &'p Arm<'tcx>) { - self.with_lint_level(arm.lint_level, |this| { + self.with_hir_source(arm.hir_id, |this| { if let Some(expr) = arm.guard { this.with_let_source(LetSource::IfLetGuard, |this| { this.visit_expr(&this.thir[expr]) @@ -125,8 +125,8 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> { #[instrument(level = "trace", skip(self))] fn visit_expr(&mut self, ex: &'p Expr<'tcx>) { match ex.kind { - ExprKind::Scope { value, lint_level, .. } => { - self.with_lint_level(lint_level, |this| { + ExprKind::Scope { value, hir_id, .. } => { + self.with_hir_source(hir_id, |this| { this.visit_expr(&this.thir[value]); }); return; @@ -181,10 +181,8 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> { fn visit_stmt(&mut self, stmt: &'p Stmt<'tcx>) { match stmt.kind { - StmtKind::Let { - box ref pattern, initializer, else_block, lint_level, span, .. - } => { - self.with_lint_level(lint_level, |this| { + StmtKind::Let { box ref pattern, initializer, else_block, hir_id, span, .. } => { + self.with_hir_source(hir_id, |this| { let let_source = if else_block.is_some() { LetSource::LetElse } else { LetSource::PlainLet }; this.with_let_source(let_source, |this| { @@ -209,20 +207,12 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { self.let_source = old_let_source; } - fn with_lint_level( - &mut self, - new_lint_level: LintLevel, - f: impl FnOnce(&mut Self) -> T, - ) -> T { - if let LintLevel::Explicit(hir_id) = new_lint_level { - let old_lint_level = self.lint_level; - self.lint_level = hir_id; - let ret = f(self); - self.lint_level = old_lint_level; - ret - } else { - f(self) - } + fn with_hir_source(&mut self, new_hir_source: HirId, f: impl FnOnce(&mut Self) -> T) -> T { + let old_hir_source = self.hir_source; + self.hir_source = new_hir_source; + let ret = f(self); + self.hir_source = old_hir_source; + ret } /// Visit a nested chain of `&&`. Used for if-let chains. This must call `visit_expr` on the @@ -233,9 +223,9 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { accumulator: &mut Vec>, ) -> Result<(), ErrorGuaranteed> { match ex.kind { - ExprKind::Scope { value, lint_level, .. } => self.with_lint_level(lint_level, |this| { - this.visit_land(&this.thir[value], accumulator) - }), + ExprKind::Scope { value, hir_id, .. } => { + self.with_hir_source(hir_id, |this| this.visit_land(&this.thir[value], accumulator)) + } ExprKind::LogicalOp { op: LogicalOp::And, lhs, rhs } => { // We recurse into the lhs only, because `&&` chains associate to the left. let res_lhs = self.visit_land(&self.thir[lhs], accumulator); @@ -259,8 +249,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { ex: &'p Expr<'tcx>, ) -> Result, ErrorGuaranteed> { match ex.kind { - ExprKind::Scope { value, lint_level, .. } => { - self.with_lint_level(lint_level, |this| this.visit_land_rhs(&this.thir[value])) + ExprKind::Scope { value, hir_id, .. } => { + self.with_hir_source(hir_id, |this| this.visit_land_rhs(&this.thir[value])) } ExprKind::Let { box ref pat, expr } => { let expr = &self.thir()[expr]; @@ -398,9 +388,9 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { tcx: self.tcx, typeck_results: self.typeck_results, typing_env: self.typing_env, - module: self.tcx.parent_module(self.lint_level).to_def_id(), + module: self.tcx.parent_module(self.hir_source).to_def_id(), dropless_arena: self.dropless_arena, - match_lint_level: self.lint_level, + match_lint_level: self.hir_source, whole_match_span, scrut_span, refutable, @@ -448,7 +438,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { if matches!(refutability, Irrefutable) { report_irrefutable_let_patterns( self.tcx, - self.lint_level, + self.hir_source, self.let_source, 1, span, @@ -470,10 +460,10 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let mut tarms = Vec::with_capacity(arms.len()); for &arm in arms { let arm = &self.thir.arms[arm]; - let got_error = self.with_lint_level(arm.lint_level, |this| { + let got_error = self.with_hir_source(arm.hir_id, |this| { let Ok(pat) = this.lower_pattern(&cx, &arm.pattern) else { return true }; let arm = - MatchArm { pat, arm_data: this.lint_level, has_guard: arm.guard.is_some() }; + MatchArm { pat, arm_data: this.hir_source, has_guard: arm.guard.is_some() }; tarms.push(arm); false }); @@ -572,7 +562,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { // The entire chain is made up of irrefutable `let` statements report_irrefutable_let_patterns( self.tcx, - self.lint_level, + self.hir_source, self.let_source, chain_refutabilities.len(), whole_chain_span, @@ -605,7 +595,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let count = prefix.len(); self.tcx.emit_node_span_lint( IRREFUTABLE_LET_PATTERNS, - self.lint_level, + self.hir_source, span, LeadingIrrefutableLetPatterns { count }, ); @@ -624,7 +614,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let count = suffix.len(); self.tcx.emit_node_span_lint( IRREFUTABLE_LET_PATTERNS, - self.lint_level, + self.hir_source, span, TrailingIrrefutableLetPatterns { count }, ); @@ -639,7 +629,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { ) -> Result<(PatCtxt<'p, 'tcx>, UsefulnessReport<'p, 'tcx>), ErrorGuaranteed> { let cx = self.new_cx(refutability, None, scrut, pat.span); let pat = self.lower_pattern(&cx, pat)?; - let arms = [MatchArm { pat, arm_data: self.lint_level, has_guard: false }]; + let arms = [MatchArm { pat, arm_data: self.hir_source, has_guard: false }]; let report = self.analyze_patterns(&cx, &arms, pat.ty().inner())?; Ok((cx, report)) } @@ -893,7 +883,7 @@ fn check_for_bindings_named_same_as_variants( let ty_path = with_no_trimmed_paths!(cx.tcx.def_path_str(edef.did())); cx.tcx.emit_node_span_lint( BINDINGS_WITH_VARIANT_NAME, - cx.lint_level, + cx.hir_source, pat.span, BindingsWithVariantName { // If this is an irrefutable pattern, and there's > 1 variant, diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 5a2d6cfef1cc..d837aa3d70ca 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -142,7 +142,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { pattern, initializer, else_block, - lint_level, + hir_id, span, } => { print_indented!(self, "kind: Let {", depth_lvl + 1); @@ -173,7 +173,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, "else_block: None", depth_lvl + 2); } - print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2); + print_indented!(self, format!("hir_id: {:?}", hir_id), depth_lvl + 2); print_indented!(self, format!("span: {:?}", span), depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); } @@ -197,10 +197,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { use rustc_middle::thir::ExprKind::*; match expr_kind { - Scope { region_scope, value, lint_level } => { + Scope { region_scope, value, hir_id } => { print_indented!(self, "Scope {", depth_lvl); print_indented!(self, format!("region_scope: {:?}", region_scope), depth_lvl + 1); - print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 1); + print_indented!(self, format!("hir_id: {:?}", hir_id), depth_lvl + 1); print_indented!(self, "value:", depth_lvl + 1); self.print_expr(*value, depth_lvl + 2); print_indented!(self, "}", depth_lvl); @@ -642,7 +642,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, "Arm {", depth_lvl); let arm = &self.thir.arms[arm_id]; - let Arm { pattern, guard, body, lint_level, scope, span } = arm; + let Arm { pattern, guard, body, hir_id, scope, span } = arm; print_indented!(self, "pattern: ", depth_lvl + 1); self.print_pat(pattern, depth_lvl + 2); @@ -656,7 +656,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, "body: ", depth_lvl + 1); self.print_expr(*body, depth_lvl + 2); - print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 1); + print_indented!(self, format!("hir_id: {:?}", hir_id), depth_lvl + 1); print_indented!(self, format!("scope: {:?}", scope), depth_lvl + 1); print_indented!(self, format!("span: {:?}", span), depth_lvl + 1); print_indented!(self, "}", depth_lvl); diff --git a/tests/ui/thir-print/c-variadic.stdout b/tests/ui/thir-print/c-variadic.stdout index f1905e04f72b..a3e3fa5e0008 100644 --- a/tests/ui/thir-print/c-variadic.stdout +++ b/tests/ui/thir-print/c-variadic.stdout @@ -39,7 +39,7 @@ body: kind: Scope { region_scope: Node(6) - lint_level: Explicit(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).6)) + hir_id: HirId(DefId(0:3 ~ c_variadic[a5de]::foo).6) value: Expr { ty: () diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index dcf60a86af9b..29399bb98e32 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -9,7 +9,7 @@ body: kind: Scope { region_scope: Node(52) - lint_level: Explicit(HirId(DefId(offset_of::concrete).52)) + hir_id: HirId(DefId(offset_of::concrete).52) value: Expr { ty: () @@ -51,7 +51,7 @@ body: kind: Scope { region_scope: Node(3) - lint_level: Explicit(HirId(DefId(offset_of::concrete).3)) + hir_id: HirId(DefId(offset_of::concrete).3) value: Expr { ty: usize @@ -67,7 +67,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).10)) + hir_id: HirId(DefId(offset_of::concrete).10) span: $DIR/offset_of.rs:37:5: 1440:57 (#0) } } @@ -100,7 +100,7 @@ body: kind: Scope { region_scope: Node(13) - lint_level: Explicit(HirId(DefId(offset_of::concrete).13)) + hir_id: HirId(DefId(offset_of::concrete).13) value: Expr { ty: usize @@ -116,7 +116,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).20)) + hir_id: HirId(DefId(offset_of::concrete).20) span: $DIR/offset_of.rs:38:5: 1440:57 (#0) } } @@ -149,7 +149,7 @@ body: kind: Scope { region_scope: Node(23) - lint_level: Explicit(HirId(DefId(offset_of::concrete).23)) + hir_id: HirId(DefId(offset_of::concrete).23) value: Expr { ty: usize @@ -165,7 +165,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).30)) + hir_id: HirId(DefId(offset_of::concrete).30) span: $DIR/offset_of.rs:39:5: 1440:57 (#0) } } @@ -198,7 +198,7 @@ body: kind: Scope { region_scope: Node(33) - lint_level: Explicit(HirId(DefId(offset_of::concrete).33)) + hir_id: HirId(DefId(offset_of::concrete).33) value: Expr { ty: usize @@ -214,7 +214,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).40)) + hir_id: HirId(DefId(offset_of::concrete).40) span: $DIR/offset_of.rs:40:5: 1440:57 (#0) } } @@ -247,7 +247,7 @@ body: kind: Scope { region_scope: Node(43) - lint_level: Explicit(HirId(DefId(offset_of::concrete).43)) + hir_id: HirId(DefId(offset_of::concrete).43) value: Expr { ty: usize @@ -263,7 +263,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).50)) + hir_id: HirId(DefId(offset_of::concrete).50) span: $DIR/offset_of.rs:41:5: 1440:57 (#0) } } @@ -286,7 +286,7 @@ body: kind: Scope { region_scope: Node(5) - lint_level: Explicit(HirId(DefId(offset_of::concrete).5)) + hir_id: HirId(DefId(offset_of::concrete).5) value: Expr { ty: usize @@ -307,7 +307,7 @@ body: kind: Scope { region_scope: Node(7) - lint_level: Explicit(HirId(DefId(offset_of::concrete).7)) + hir_id: HirId(DefId(offset_of::concrete).7) value: Expr { ty: usize @@ -369,7 +369,7 @@ body: kind: Scope { region_scope: Node(15) - lint_level: Explicit(HirId(DefId(offset_of::concrete).15)) + hir_id: HirId(DefId(offset_of::concrete).15) value: Expr { ty: usize @@ -390,7 +390,7 @@ body: kind: Scope { region_scope: Node(17) - lint_level: Explicit(HirId(DefId(offset_of::concrete).17)) + hir_id: HirId(DefId(offset_of::concrete).17) value: Expr { ty: usize @@ -452,7 +452,7 @@ body: kind: Scope { region_scope: Node(25) - lint_level: Explicit(HirId(DefId(offset_of::concrete).25)) + hir_id: HirId(DefId(offset_of::concrete).25) value: Expr { ty: usize @@ -473,7 +473,7 @@ body: kind: Scope { region_scope: Node(27) - lint_level: Explicit(HirId(DefId(offset_of::concrete).27)) + hir_id: HirId(DefId(offset_of::concrete).27) value: Expr { ty: usize @@ -535,7 +535,7 @@ body: kind: Scope { region_scope: Node(35) - lint_level: Explicit(HirId(DefId(offset_of::concrete).35)) + hir_id: HirId(DefId(offset_of::concrete).35) value: Expr { ty: usize @@ -556,7 +556,7 @@ body: kind: Scope { region_scope: Node(37) - lint_level: Explicit(HirId(DefId(offset_of::concrete).37)) + hir_id: HirId(DefId(offset_of::concrete).37) value: Expr { ty: usize @@ -670,7 +670,7 @@ body: kind: Scope { region_scope: Node(45) - lint_level: Explicit(HirId(DefId(offset_of::concrete).45)) + hir_id: HirId(DefId(offset_of::concrete).45) value: Expr { ty: usize @@ -691,7 +691,7 @@ body: kind: Scope { region_scope: Node(47) - lint_level: Explicit(HirId(DefId(offset_of::concrete).47)) + hir_id: HirId(DefId(offset_of::concrete).47) value: Expr { ty: usize @@ -805,7 +805,7 @@ body: kind: Scope { region_scope: Node(50) - lint_level: Explicit(HirId(DefId(offset_of::generic).50)) + hir_id: HirId(DefId(offset_of::generic).50) value: Expr { ty: () @@ -847,7 +847,7 @@ body: kind: Scope { region_scope: Node(3) - lint_level: Explicit(HirId(DefId(offset_of::generic).3)) + hir_id: HirId(DefId(offset_of::generic).3) value: Expr { ty: usize @@ -863,7 +863,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::generic).12)) + hir_id: HirId(DefId(offset_of::generic).12) span: $DIR/offset_of.rs:45:5: 1440:57 (#0) } } @@ -896,7 +896,7 @@ body: kind: Scope { region_scope: Node(15) - lint_level: Explicit(HirId(DefId(offset_of::generic).15)) + hir_id: HirId(DefId(offset_of::generic).15) value: Expr { ty: usize @@ -912,7 +912,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::generic).24)) + hir_id: HirId(DefId(offset_of::generic).24) span: $DIR/offset_of.rs:46:5: 1440:57 (#0) } } @@ -945,7 +945,7 @@ body: kind: Scope { region_scope: Node(27) - lint_level: Explicit(HirId(DefId(offset_of::generic).27)) + hir_id: HirId(DefId(offset_of::generic).27) value: Expr { ty: usize @@ -961,7 +961,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::generic).36)) + hir_id: HirId(DefId(offset_of::generic).36) span: $DIR/offset_of.rs:47:5: 1440:57 (#0) } } @@ -994,7 +994,7 @@ body: kind: Scope { region_scope: Node(39) - lint_level: Explicit(HirId(DefId(offset_of::generic).39)) + hir_id: HirId(DefId(offset_of::generic).39) value: Expr { ty: usize @@ -1010,7 +1010,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::generic).48)) + hir_id: HirId(DefId(offset_of::generic).48) span: $DIR/offset_of.rs:48:5: 1440:57 (#0) } } @@ -1033,7 +1033,7 @@ body: kind: Scope { region_scope: Node(5) - lint_level: Explicit(HirId(DefId(offset_of::generic).5)) + hir_id: HirId(DefId(offset_of::generic).5) value: Expr { ty: usize @@ -1054,7 +1054,7 @@ body: kind: Scope { region_scope: Node(7) - lint_level: Explicit(HirId(DefId(offset_of::generic).7)) + hir_id: HirId(DefId(offset_of::generic).7) value: Expr { ty: usize @@ -1116,7 +1116,7 @@ body: kind: Scope { region_scope: Node(17) - lint_level: Explicit(HirId(DefId(offset_of::generic).17)) + hir_id: HirId(DefId(offset_of::generic).17) value: Expr { ty: usize @@ -1137,7 +1137,7 @@ body: kind: Scope { region_scope: Node(19) - lint_level: Explicit(HirId(DefId(offset_of::generic).19)) + hir_id: HirId(DefId(offset_of::generic).19) value: Expr { ty: usize @@ -1199,7 +1199,7 @@ body: kind: Scope { region_scope: Node(29) - lint_level: Explicit(HirId(DefId(offset_of::generic).29)) + hir_id: HirId(DefId(offset_of::generic).29) value: Expr { ty: usize @@ -1220,7 +1220,7 @@ body: kind: Scope { region_scope: Node(31) - lint_level: Explicit(HirId(DefId(offset_of::generic).31)) + hir_id: HirId(DefId(offset_of::generic).31) value: Expr { ty: usize @@ -1282,7 +1282,7 @@ body: kind: Scope { region_scope: Node(41) - lint_level: Explicit(HirId(DefId(offset_of::generic).41)) + hir_id: HirId(DefId(offset_of::generic).41) value: Expr { ty: usize @@ -1303,7 +1303,7 @@ body: kind: Scope { region_scope: Node(43) - lint_level: Explicit(HirId(DefId(offset_of::generic).43)) + hir_id: HirId(DefId(offset_of::generic).43) value: Expr { ty: usize diff --git a/tests/ui/thir-print/thir-flat-const-variant.stdout b/tests/ui/thir-print/thir-flat-const-variant.stdout index 750a47a7141c..908684094ec3 100644 --- a/tests/ui/thir-print/thir-flat-const-variant.stdout +++ b/tests/ui/thir-print/thir-flat-const-variant.stdout @@ -17,9 +17,7 @@ Thir { Expr { kind: Scope { region_scope: Node(7), - lint_level: Explicit( - HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).7), - ), + hir_id: HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).7), value: e0, }, ty: (), @@ -49,9 +47,7 @@ Thir { Expr { kind: Scope { region_scope: Node(3), - lint_level: Explicit( - HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).3), - ), + hir_id: HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).3), value: e2, }, ty: Foo, @@ -82,9 +78,7 @@ Thir { Expr { kind: Scope { region_scope: Node(8), - lint_level: Explicit( - HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).8), - ), + hir_id: HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).8), value: e0, }, ty: (), @@ -114,9 +108,7 @@ Thir { Expr { kind: Scope { region_scope: Node(3), - lint_level: Explicit( - HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).3), - ), + hir_id: HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).3), value: e2, }, ty: Foo, @@ -147,9 +139,7 @@ Thir { Expr { kind: Scope { region_scope: Node(7), - lint_level: Explicit( - HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).7), - ), + hir_id: HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).7), value: e0, }, ty: (), @@ -179,9 +169,7 @@ Thir { Expr { kind: Scope { region_scope: Node(3), - lint_level: Explicit( - HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).3), - ), + hir_id: HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).3), value: e2, }, ty: Foo, @@ -212,9 +200,7 @@ Thir { Expr { kind: Scope { region_scope: Node(8), - lint_level: Explicit( - HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).8), - ), + hir_id: HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).8), value: e0, }, ty: (), @@ -244,9 +230,7 @@ Thir { Expr { kind: Scope { region_scope: Node(3), - lint_level: Explicit( - HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).3), - ), + hir_id: HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).3), value: e2, }, ty: Foo, @@ -286,9 +270,7 @@ Thir { Expr { kind: Scope { region_scope: Node(2), - lint_level: Explicit( - HirId(DefId(0:12 ~ thir_flat_const_variant[1f54]::main).2), - ), + hir_id: HirId(DefId(0:12 ~ thir_flat_const_variant[1f54]::main).2), value: e0, }, ty: (), diff --git a/tests/ui/thir-print/thir-flat.stdout b/tests/ui/thir-print/thir-flat.stdout index f01d64e60b3d..37106427745e 100644 --- a/tests/ui/thir-print/thir-flat.stdout +++ b/tests/ui/thir-print/thir-flat.stdout @@ -26,9 +26,7 @@ Thir { Expr { kind: Scope { region_scope: Node(2), - lint_level: Explicit( - HirId(DefId(0:3 ~ thir_flat[7b97]::main).2), - ), + hir_id: HirId(DefId(0:3 ~ thir_flat[7b97]::main).2), value: e0, }, ty: (), diff --git a/tests/ui/thir-print/thir-tree-loop-match.stdout b/tests/ui/thir-print/thir-tree-loop-match.stdout index 5f6b130c3905..4a1b2aaf67f5 100644 --- a/tests/ui/thir-print/thir-tree-loop-match.stdout +++ b/tests/ui/thir-print/thir-tree-loop-match.stdout @@ -32,7 +32,7 @@ body: kind: Scope { region_scope: Node(28) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).28)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).28) value: Expr { ty: bool @@ -53,7 +53,7 @@ body: kind: Scope { region_scope: Node(4) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).4)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).4) value: Expr { ty: bool @@ -76,7 +76,7 @@ body: kind: Scope { region_scope: Node(7) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).7)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).7) value: Expr { ty: bool @@ -101,7 +101,7 @@ body: kind: Scope { region_scope: Node(12) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).12)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).12) value: Expr { ty: bool @@ -135,7 +135,7 @@ body: kind: Scope { region_scope: Node(17) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).17)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).17) value: Expr { ty: bool @@ -166,7 +166,7 @@ body: kind: Scope { region_scope: Node(19) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).19)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).19) value: Expr { ty: ! @@ -183,7 +183,7 @@ body: kind: Scope { region_scope: Node(20) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).20)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).20) value: Expr { ty: bool @@ -209,7 +209,7 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).16)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).16) scope: Node(16) span: $DIR/thir-tree-loop-match.rs:12:17: 15:18 (#0) } @@ -233,7 +233,7 @@ body: kind: Scope { region_scope: Node(25) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).25)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).25) value: Expr { ty: bool @@ -256,7 +256,7 @@ body: kind: Scope { region_scope: Node(26) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).26)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).26) value: Expr { ty: bool @@ -275,7 +275,7 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).24)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).24) scope: Node(24) span: $DIR/thir-tree-loop-match.rs:16:17: 16:38 (#0) } @@ -304,7 +304,7 @@ body: kind: Scope { region_scope: Node(2) - lint_level: Explicit(HirId(DefId(0:4 ~ thir_tree_loop_match[3c53]::main).2)) + hir_id: HirId(DefId(0:4 ~ thir_tree_loop_match[3c53]::main).2) value: Expr { ty: () diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index ecc5fb21435f..a6d23ee204cb 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -32,7 +32,7 @@ body: kind: Scope { region_scope: Node(28) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).28)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).28) value: Expr { ty: bool @@ -53,7 +53,7 @@ body: kind: Scope { region_scope: Node(4) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).4)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).4) value: Expr { ty: bool @@ -69,7 +69,7 @@ body: kind: Scope { region_scope: Node(5) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).5)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).5) value: Expr { ty: Foo @@ -129,7 +129,7 @@ body: kind: Scope { region_scope: Node(15) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).15)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).15) value: Expr { ty: bool @@ -141,7 +141,7 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).14)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).14) scope: Node(14) span: $DIR/thir-tree-match.rs:17:9: 17:40 (#0) } @@ -181,7 +181,7 @@ body: kind: Scope { region_scope: Node(21) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).21)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).21) value: Expr { ty: bool @@ -193,7 +193,7 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).20)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).20) scope: Node(20) span: $DIR/thir-tree-match.rs:18:9: 18:32 (#0) } @@ -225,7 +225,7 @@ body: kind: Scope { region_scope: Node(27) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).27)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).27) value: Expr { ty: bool @@ -237,7 +237,7 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).26)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).26) scope: Node(26) span: $DIR/thir-tree-match.rs:19:9: 19:28 (#0) } @@ -263,7 +263,7 @@ body: kind: Scope { region_scope: Node(2) - lint_level: Explicit(HirId(DefId(0:17 ~ thir_tree_match[fcf8]::main).2)) + hir_id: HirId(DefId(0:17 ~ thir_tree_match[fcf8]::main).2) value: Expr { ty: () diff --git a/tests/ui/thir-print/thir-tree.stdout b/tests/ui/thir-print/thir-tree.stdout index d61176d6480f..25d0ccfa7a05 100644 --- a/tests/ui/thir-print/thir-tree.stdout +++ b/tests/ui/thir-print/thir-tree.stdout @@ -9,7 +9,7 @@ body: kind: Scope { region_scope: Node(2) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree[7aaa]::main).2)) + hir_id: HirId(DefId(0:3 ~ thir_tree[7aaa]::main).2) value: Expr { ty: () diff --git a/tests/ui/unpretty/box.stdout b/tests/ui/unpretty/box.stdout index 54bd98c7a683..123273be4efe 100644 --- a/tests/ui/unpretty/box.stdout +++ b/tests/ui/unpretty/box.stdout @@ -9,7 +9,7 @@ body: kind: Scope { region_scope: Node(11) - lint_level: Explicit(HirId(DefId(0:3 ~ box[efb9]::main).11)) + hir_id: HirId(DefId(0:3 ~ box[efb9]::main).11) value: Expr { ty: () @@ -43,7 +43,7 @@ body: kind: Scope { region_scope: Node(3) - lint_level: Explicit(HirId(DefId(0:3 ~ box[efb9]::main).3)) + hir_id: HirId(DefId(0:3 ~ box[efb9]::main).3) value: Expr { ty: std::boxed::Box @@ -58,7 +58,7 @@ body: kind: Scope { region_scope: Node(8) - lint_level: Explicit(HirId(DefId(0:3 ~ box[efb9]::main).8)) + hir_id: HirId(DefId(0:3 ~ box[efb9]::main).8) value: Expr { ty: i32 @@ -76,7 +76,7 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(0:3 ~ box[efb9]::main).9)) + hir_id: HirId(DefId(0:3 ~ box[efb9]::main).9) span: $DIR/box.rs:7:5: 7:35 (#0) } } From 8868b479a81cdf27e7493c2ac41d2b7efa2dbe89 Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 8 Jan 2026 16:04:02 -0800 Subject: [PATCH 2149/3801] move `LintLevel` to `rustc_mir_build` --- compiler/rustc_middle/src/thir.rs | 6 ------ compiler/rustc_mir_build/src/builder/block.rs | 1 + .../rustc_mir_build/src/builder/expr/as_operand.rs | 1 + compiler/rustc_mir_build/src/builder/expr/as_place.rs | 1 + compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs | 1 + compiler/rustc_mir_build/src/builder/expr/as_temp.rs | 2 +- compiler/rustc_mir_build/src/builder/expr/into.rs | 1 + compiler/rustc_mir_build/src/builder/expr/stmt.rs | 2 +- compiler/rustc_mir_build/src/builder/matches/mod.rs | 2 +- compiler/rustc_mir_build/src/builder/mod.rs | 4 ++-- compiler/rustc_mir_build/src/builder/scope.rs | 10 +++++++++- 11 files changed, 19 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 86bd6fb803b7..86c19520e072 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -116,12 +116,6 @@ pub struct Param<'tcx> { pub hir_id: Option, } -#[derive(Copy, Clone, Debug, HashStable)] -pub enum LintLevel { - Inherited, - Explicit(HirId), -} - #[derive(Clone, Debug, HashStable)] pub struct Block { /// Whether the block itself has a label. Used by `label: {}` diff --git a/compiler/rustc_mir_build/src/builder/block.rs b/compiler/rustc_mir_build/src/builder/block.rs index d8837d2b195a..bfbb6fa7d169 100644 --- a/compiler/rustc_mir_build/src/builder/block.rs +++ b/compiler/rustc_mir_build/src/builder/block.rs @@ -7,6 +7,7 @@ use tracing::debug; use crate::builder::ForGuard::OutsideGuard; use crate::builder::matches::{DeclareLetBindings, ScheduleDrops}; +use crate::builder::scope::LintLevel; use crate::builder::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; impl<'a, 'tcx> Builder<'a, 'tcx> { diff --git a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs index c9c166b7f018..d2f06cc9d57b 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs @@ -6,6 +6,7 @@ use rustc_middle::thir::*; use tracing::{debug, instrument}; use crate::builder::expr::category::Category; +use crate::builder::scope::LintLevel; use crate::builder::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary}; impl<'a, 'tcx> Builder<'a, 'tcx> { diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs index db9aa3cd8704..139c6da29d44 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs @@ -16,6 +16,7 @@ use tracing::{debug, instrument, trace}; use crate::builder::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::builder::expr::category::Category; +use crate::builder::scope::LintLevel; use crate::builder::{BlockAnd, BlockAndExtension, Builder, Capture, CaptureMap}; /// The "outermost" place that holds this value. diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs index 3d1774bd1d68..8de79ab2531f 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs @@ -18,6 +18,7 @@ use tracing::debug; use crate::builder::expr::as_place::PlaceBase; use crate::builder::expr::category::{Category, RvalueFunc}; +use crate::builder::scope::LintLevel; use crate::builder::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary}; impl<'a, 'tcx> Builder<'a, 'tcx> { diff --git a/compiler/rustc_mir_build/src/builder/expr/as_temp.rs b/compiler/rustc_mir_build/src/builder/expr/as_temp.rs index 2aace64062cd..55296c647c81 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_temp.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_temp.rs @@ -7,7 +7,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use tracing::{debug, instrument}; -use crate::builder::scope::DropKind; +use crate::builder::scope::{DropKind, LintLevel}; use crate::builder::{BlockAnd, BlockAndExtension, Builder}; impl<'a, 'tcx> Builder<'a, 'tcx> { diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index 9731f0de135f..60e05b691a83 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -16,6 +16,7 @@ use tracing::{debug, instrument}; use crate::builder::expr::category::{Category, RvalueFunc}; use crate::builder::matches::{DeclareLetBindings, HasMatchGuard}; +use crate::builder::scope::LintLevel; use crate::builder::{BlockAnd, BlockAndExtension, BlockFrame, Builder, NeedsTemporary}; use crate::errors::{LoopMatchArmWithGuard, LoopMatchUnsupportedType}; diff --git a/compiler/rustc_mir_build/src/builder/expr/stmt.rs b/compiler/rustc_mir_build/src/builder/expr/stmt.rs index f28e483b6a5d..3d603afbaa4a 100644 --- a/compiler/rustc_mir_build/src/builder/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/builder/expr/stmt.rs @@ -5,7 +5,7 @@ use rustc_middle::thir::*; use rustc_span::source_map::Spanned; use tracing::debug; -use crate::builder::scope::BreakableTarget; +use crate::builder::scope::{BreakableTarget, LintLevel}; use crate::builder::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; impl<'a, 'tcx> Builder<'a, 'tcx> { diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 49caee4a1896..565d97fa68b8 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -29,7 +29,7 @@ use crate::builder::ForGuard::{self, OutsideGuard, RefWithinGuard}; use crate::builder::expr::as_place::PlaceBuilder; use crate::builder::matches::buckets::PartitionedCandidates; use crate::builder::matches::user_ty::ProjectedUserTypesNode; -use crate::builder::scope::DropKind; +use crate::builder::scope::{DropKind, LintLevel}; use crate::builder::{ BlockAnd, BlockAndExtension, Builder, GuardFrame, GuardFrameLocal, LocalsForNode, }; diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 40f1fe0d5d11..132062961da6 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -38,14 +38,14 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::middle::region; use rustc_middle::mir::*; -use rustc_middle::thir::{self, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir}; +use rustc_middle::thir::{self, ExprId, LocalVarId, Param, ParamId, PatKind, Thir}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt, TypeVisitableExt, TypingMode}; use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::{Span, Symbol, sym}; use crate::builder::expr::as_place::PlaceBuilder; -use crate::builder::scope::DropKind; +use crate::builder::scope::{DropKind, LintLevel}; use crate::errors; pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 981704052536..b10df60e0f75 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -89,7 +89,7 @@ use rustc_hir::HirId; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::middle::region; use rustc_middle::mir::{self, *}; -use rustc_middle::thir::{AdtExpr, AdtExprBase, ArmId, ExprId, ExprKind, LintLevel}; +use rustc_middle::thir::{AdtExpr, AdtExprBase, ArmId, ExprId, ExprKind}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, ValTree}; use rustc_middle::{bug, span_bug}; use rustc_pattern_analysis::rustc::RustcPatCtxt; @@ -522,6 +522,14 @@ impl<'tcx> Scopes<'tcx> { } } +/// Used by [`Builder::in_scope`] to create source scopes mapping from MIR back to HIR at points +/// where lint levels change. +#[derive(Copy, Clone, Debug)] +pub(crate) enum LintLevel { + Inherited, + Explicit(HirId), +} + impl<'a, 'tcx> Builder<'a, 'tcx> { // Adding and removing scopes // ========================== From cd79ff2e2c804c626c5ab0dce701077afc35db83 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Thu, 15 Jan 2026 09:37:16 +0800 Subject: [PATCH 2150/3801] Revert "avoid phi node for pointers flowing into Vec appends #130998" This reverts PR because the added test seems to be flaky / non-deterministic, and has been failing in unrelated PRs during merge CI. --- compiler/rustc_codegen_llvm/src/attributes.rs | 11 +------ library/alloc/src/slice.rs | 8 ++--- library/alloc/src/vec/mod.rs | 6 +--- .../lib-optimizations/append-elements.rs | 30 ------------------- 4 files changed, 5 insertions(+), 50 deletions(-) delete mode 100644 tests/codegen-llvm/lib-optimizations/append-elements.rs diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index bf6bb81b53b0..a25ce9e5a90a 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -517,16 +517,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( to_add.push(llvm::CreateAllocKindAttr(cx.llcx, AllocKindFlags::Free)); // applies to argument place instead of function place let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx); - let attrs: &[_] = if llvm_util::get_version() >= (21, 0, 0) { - // "Does not capture provenance" means "if the function call stashes the pointer somewhere, - // accessing that pointer after the function returns is UB". That is definitely the case here since - // freeing will destroy the provenance. - let captures_addr = AttributeKind::CapturesAddress.create_attr(cx.llcx); - &[allocated_pointer, captures_addr] - } else { - &[allocated_pointer] - }; - attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), attrs); + attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]); } if let Some(align) = codegen_fn_attrs.alignment { llvm::set_alignment(llfn, align); diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 58abf4bd6571..e7d0fc3454ee 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -448,11 +448,9 @@ impl [T] { // SAFETY: // allocated above with the capacity of `s`, and initialize to `s.len()` in // ptr::copy_to_non_overlapping below. - if s.len() > 0 { - unsafe { - s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len()); - v.set_len(s.len()); - } + unsafe { + s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len()); + v.set_len(s.len()); } v } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index ac86399df7ab..379e964f0a0c 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2818,11 +2818,7 @@ impl Vec { let count = other.len(); self.reserve(count); let len = self.len(); - if count > 0 { - unsafe { - ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) - }; - } + unsafe { ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) }; self.len += count; } diff --git a/tests/codegen-llvm/lib-optimizations/append-elements.rs b/tests/codegen-llvm/lib-optimizations/append-elements.rs deleted file mode 100644 index 8ee520a131f0..000000000000 --- a/tests/codegen-llvm/lib-optimizations/append-elements.rs +++ /dev/null @@ -1,30 +0,0 @@ -//@ compile-flags: -O -Zmerge-functions=disabled -//@ min-llvm-version: 21 -#![crate_type = "lib"] - -//! Check that a temporary intermediate allocations can eliminated and replaced -//! with memcpy forwarding. -//! This requires Vec code to be structured in a way that avoids phi nodes from the -//! zero-capacity length flowing into the memcpy arguments. - -// CHECK-LABEL: @vec_append_with_temp_alloc -#[no_mangle] -pub fn vec_append_with_temp_alloc(dst: &mut Vec, src: &[u8]) { - // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.*}}%dst.i{{.*}}%src.0 - // CHECK-NOT: call void @llvm.memcpy - let temp = src.to_vec(); - dst.extend(&temp); - // CHECK: ret -} - -// CHECK-LABEL: @string_append_with_temp_alloc -#[no_mangle] -pub fn string_append_with_temp_alloc(dst: &mut String, src: &str) { - // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.*}}%dst.i{{.*}}%src.0 - // CHECK-NOT: call void @llvm.memcpy - let temp = src.to_string(); - dst.push_str(&temp); - // CHECK: ret -} From df386c5b48e2b3a3dabae22f2b018501f5abcbe8 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 30 Dec 2025 16:57:56 -0500 Subject: [PATCH 2151/3801] Test that -Zbuild-std=core works on a variety of profiles --- Cargo.lock | 1 + .../src/spec/targets/i586_unknown_redox.rs | 2 +- .../spec/targets/x86_64_unknown_linux_none.rs | 2 +- .../src/spec/targets/xtensa_esp32_espidf.rs | 2 +- .../src/spec/targets/xtensa_esp32s2_espidf.rs | 2 +- .../src/spec/targets/xtensa_esp32s3_espidf.rs | 2 +- src/bootstrap/mk/Makefile.in | 5 + src/bootstrap/src/core/build_steps/test.rs | 8 +- src/bootstrap/src/core/builder/cli_paths.rs | 1 + .../cli_paths/snapshots/x_test_tests.snap | 3 + .../snapshots/x_test_tests_skip_coverage.snap | 3 + src/bootstrap/src/core/builder/mod.rs | 1 + src/bootstrap/src/core/builder/tests.rs | 4 +- .../rustc-dev-guide/src/tests/compiletest.md | 10 ++ src/tools/compiletest/src/common.rs | 1 + src/tools/compiletest/src/runtest/run_make.rs | 4 +- src/tools/run-make-support/Cargo.toml | 1 + src/tools/run-make-support/src/command.rs | 13 ++ src/tools/run-make-support/src/lib.rs | 4 +- src/tools/run-make-support/src/util.rs | 3 + tests/build-std/configurations/rmake.rs | 131 ++++++++++++++++++ 21 files changed, 192 insertions(+), 11 deletions(-) create mode 100644 tests/build-std/configurations/rmake.rs diff --git a/Cargo.lock b/Cargo.lock index bf28939ac87b..bf0bc9234d39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3334,6 +3334,7 @@ dependencies = [ "rustdoc-json-types", "serde_json", "similar", + "tempfile", "wasmparser 0.236.1", ] diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs index 935666630dae..56e1c8a9705d 100644 --- a/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/i586_unknown_redox.rs @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "i586-unknown-redox".into(), - metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None }, + metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None }, pointer_width: 32, data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128" diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs index ecf232f1ab2f..768b1a1ba112 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { llvm_target: "x86_64-unknown-linux-none".into(), metadata: TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, std: Some(false), }, diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs index 83835705f3da..0fb4d186087b 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs @@ -9,7 +9,7 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), arch: Arch::Xtensa, - metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None }, + metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None }, options: TargetOptions { endian: Endian::Little, diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs index 42e4c7bf8bec..81eab657db71 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs @@ -9,7 +9,7 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), arch: Arch::Xtensa, - metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None }, + metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None }, options: TargetOptions { endian: Endian::Little, diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs index 498daf4e6063..fb1f4f471979 100644 --- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs @@ -9,7 +9,7 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), arch: Arch::Xtensa, - metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None }, + metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None }, options: TargetOptions { endian: Endian::Little, diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 6bef58a0ac20..5f956f03ecb1 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -53,6 +53,11 @@ check-aux: src/tools/cargotest \ src/tools/test-float-parse \ $(BOOTSTRAP_ARGS) + # The build-std suite is off by default because it is uncommonly slow + # and memory-hungry. + $(Q)$(BOOTSTRAP) test --stage 2 \ + build-std \ + $(BOOTSTRAP_ARGS) # Run standard library tests in Miri. $(Q)MIRIFLAGS="-Zmiri-strict-provenance" \ $(BOOTSTRAP) miri --stage 2 \ diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index f3a1c6b0e3dd..080931fc0a93 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1625,6 +1625,12 @@ test!(RunMakeCargo { suite: "run-make-cargo", default: true }); +test!(BuildStd { + path: "tests/build-std", + mode: CompiletestMode::RunMake, + suite: "build-std", + default: false +}); test!(AssemblyLlvm { path: "tests/assembly-llvm", @@ -1948,7 +1954,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let stage0_rustc_path = builder.compiler(0, test_compiler.host); cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path)); - if suite == "run-make-cargo" { + if matches!(suite, "run-make-cargo" | "build-std") { let cargo_path = if test_compiler.stage == 0 { // If we're using `--stage 0`, we should provide the bootstrap cargo. builder.initial_cargo.clone() diff --git a/src/bootstrap/src/core/builder/cli_paths.rs b/src/bootstrap/src/core/builder/cli_paths.rs index 5ff2b380e4b9..1b0caa980e1d 100644 --- a/src/bootstrap/src/core/builder/cli_paths.rs +++ b/src/bootstrap/src/core/builder/cli_paths.rs @@ -20,6 +20,7 @@ pub(crate) const PATH_REMAP: &[(&str, &[&str])] = &[ &[ // tidy-alphabetical-start "tests/assembly-llvm", + "tests/build-std", "tests/codegen-llvm", "tests/codegen-units", "tests/coverage", diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap index ad9660ef5c91..65349a59a1e8 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests.snap @@ -5,6 +5,9 @@ expression: test tests [Test] test::AssemblyLlvm targets: [aarch64-unknown-linux-gnu] - Suite(test::tests/assembly-llvm) +[Test] test::BuildStd + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/build-std) [Test] test::CodegenLlvm targets: [aarch64-unknown-linux-gnu] - Suite(test::tests/codegen-llvm) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap index 4572f089b0ae..694bb0672ee4 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_skip_coverage.snap @@ -5,6 +5,9 @@ expression: test tests --skip=coverage [Test] test::AssemblyLlvm targets: [aarch64-unknown-linux-gnu] - Suite(test::tests/assembly-llvm) +[Test] test::BuildStd + targets: [aarch64-unknown-linux-gnu] + - Suite(test::tests/build-std) [Test] test::CodegenLlvm targets: [aarch64-unknown-linux-gnu] - Suite(test::tests/codegen-llvm) diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 4a04b97c549a..7f98e42227af 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -927,6 +927,7 @@ impl<'a> Builder<'a> { test::CollectLicenseMetadata, test::RunMake, test::RunMakeCargo, + test::BuildStd, ), Kind::Miri => describe!(test::Crate), Kind::Bench => describe!(test::Crate, test::CrateLibrustc, test::CrateRustdoc), diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 66614cc6cced..af26c2f87d02 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2077,7 +2077,7 @@ mod snapshot { let ctx = TestCtx::new(); insta::assert_snapshot!( prepare_test_config(&ctx) - .render_steps(), @r" + .render_steps(), @" [build] rustc 0 -> Tidy 1 [test] tidy <> [build] rustdoc 0 @@ -2255,7 +2255,7 @@ mod snapshot { insta::assert_snapshot!( prepare_test_config(&ctx) .stage(2) - .render_steps(), @r" + .render_steps(), @" [build] rustc 0 -> Tidy 1 [test] tidy <> [build] rustdoc 0 diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index d69e0a5ce988..7f22bc27600c 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -78,6 +78,10 @@ The following test suites are available, with links for more information: [`run-make`](#run-make-tests) are general purpose tests using Rust programs. +### The build-std test suite + +[`build-std`](#build-std-tests) test that -Zbuild-std works. + ### Rustdoc test suites | Test suite | Purpose | @@ -429,6 +433,12 @@ use cases that require testing in-tree `cargo` in conjunction with in-tree `rust The `run-make` test suite does not have access to in-tree `cargo` (so it can be the faster-to-iterate test suite). +### `build-std` tests + +The tests in [`tests/build-std`] check that `-Zbuild-std` works. This is currently +just a run-make test suite with a single recipe. The recipe generates test cases +and runs them in parallel. + #### Using Rust recipes Each test should be in a separate directory with a `rmake.rs` Rust program, diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index a2f3a8f00dac..843b4ad2975d 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -77,6 +77,7 @@ string_enum! { RustdocUi => "rustdoc-ui", Ui => "ui", UiFullDeps => "ui-fulldeps", + BuildStd => "build-std", } } diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 4eb8f91fe894..ac8846a263c0 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -190,8 +190,8 @@ impl TestCx<'_> { // through a specific CI runner). .env("LLVM_COMPONENTS", &self.config.llvm_components); - // Only `run-make-cargo` test suite gets an in-tree `cargo`, not `run-make`. - if self.config.suite == TestSuite::RunMakeCargo { + // The `run-make-cargo` and `build-std` suites need an in-tree `cargo`, `run-make` does not. + if matches!(self.config.suite, TestSuite::RunMakeCargo | TestSuite::BuildStd) { cmd.env( "CARGO", self.config.cargo_path.as_ref().expect("cargo must be built and made available"), diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index 9d9cd656f570..918f5ef0d506 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -17,6 +17,7 @@ object = "0.37" regex = "1.11" serde_json = "1.0" similar = "2.7" +tempfile = "3" wasmparser = { version = "0.236", default-features = false, features = ["std", "features", "validate"] } # tidy-alphabetical-end diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index 0aeb189bb6a5..f4a09f9faae8 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -46,6 +46,8 @@ pub struct Command { // Emulate linear type semantics. drop_bomb: DropBomb, already_executed: bool, + + context: String, } impl Command { @@ -60,6 +62,7 @@ impl Command { stdout: None, stderr: None, already_executed: false, + context: String::new(), } } @@ -69,6 +72,16 @@ impl Command { self.cmd } + pub(crate) fn get_context(&self) -> &str { + &self.context + } + + /// Appends context to the command, to provide a better error message if the command fails. + pub fn context(&mut self, ctx: &str) -> &mut Self { + self.context.push_str(&format!("{ctx}\n")); + self + } + /// Specify a stdin input buffer. This is a convenience helper, pub fn stdin_buf>(&mut self, input: I) -> &mut Self { self.stdin_buf = Some(input.as_ref().to_vec().into_boxed_slice()); diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 5253dc04a93e..b19d73b78a94 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -34,7 +34,9 @@ pub mod rfs { } // Re-exports of third-party library crates. -pub use {bstr, gimli, libc, object, regex, rustdoc_json_types, serde_json, similar, wasmparser}; +pub use { + bstr, gimli, libc, object, regex, rustdoc_json_types, serde_json, similar, tempfile, wasmparser, +}; // Helpers for building names of output artifacts that are potentially target-specific. pub use crate::artifact_names::{ diff --git a/src/tools/run-make-support/src/util.rs b/src/tools/run-make-support/src/util.rs index af01758447b9..7908dc1f7b3d 100644 --- a/src/tools/run-make-support/src/util.rs +++ b/src/tools/run-make-support/src/util.rs @@ -21,6 +21,9 @@ pub(crate) fn handle_failed_output( eprintln!("output status: `{}`", output.status()); eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8()); eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8()); + if !cmd.get_context().is_empty() { + eprintln!("Context:\n{}", cmd.get_context()); + } std::process::exit(1) } diff --git a/tests/build-std/configurations/rmake.rs b/tests/build-std/configurations/rmake.rs new file mode 100644 index 000000000000..99cb9f9b0f4d --- /dev/null +++ b/tests/build-std/configurations/rmake.rs @@ -0,0 +1,131 @@ +// This test ensures we are able to compile -Zbuild-std=core under a variety of profiles. +// Currently, it tests that we can compile to all Tier 1 targets, and it does this by checking what +// the tier metadata in target-spec JSON. This means that all in-tree targets must have a tier set. + +#![deny(warnings)] + +use std::collections::HashMap; +use std::sync::{Arc, Mutex}; +use std::thread; + +use run_make_support::serde_json::{self, Value}; +use run_make_support::tempfile::TempDir; +use run_make_support::{cargo, rfs, rustc}; + +#[derive(Clone)] +struct Task { + target: String, + opt_level: u8, + debug: u8, + panic: &'static str, +} + +fn manifest(task: &Task) -> String { + let Task { opt_level, debug, panic, target: _ } = task; + format!( + r#"[package] +name = "scratch" +version = "0.1.0" +edition = "2024" + +[lib] +path = "lib.rs" + +[profile.release] +opt-level = {opt_level} +debug = {debug} +panic = "{panic}" +"# + ) +} + +fn main() { + let mut targets = Vec::new(); + let all_targets = + rustc().args(&["--print=all-target-specs-json", "-Zunstable-options"]).run().stdout_utf8(); + let all_targets: HashMap = serde_json::from_str(&all_targets).unwrap(); + for (target, spec) in all_targets { + let metadata = spec.as_object().unwrap()["metadata"].as_object().unwrap(); + let tier = metadata["tier"] + .as_u64() + .expect(&format!("Target {} is missing tier metadata", target)); + if tier == 1 { + targets.push(target); + } + } + + let mut tasks = Vec::new(); + + // Testing every combination of compiler flags is infeasible. So we are making some attempt to + // choose combinations that will tend to run into problems. + // + // The particular combination of settings below is tuned to look for problems generating the + // code for compiler-builtins. + // We only exercise opt-level 0 and 3 to exercise mir-opt-level 1 and 2. + // We only exercise debug 0 and 2 because level 2 turns off some MIR optimizations. + // We only test abort and immediate-abort because abort vs unwind doesn't change MIR much at + // all. but immediate-abort does. + // + // Currently this only tests that we can compile the tier 1 targets. But since we are using + // -Zbuild-std=core, we could have any list of targets. + + for opt_level in [0, 3] { + for debug in [0, 2] { + for panic in ["abort", "immediate-abort"] { + for target in &targets { + tasks.push(Task { target: target.clone(), opt_level, debug, panic }); + } + } + } + } + + let tasks = Arc::new(Mutex::new(tasks)); + let mut threads = Vec::new(); + + // Try to obey the -j argument passed to bootstrap, otherwise fall back to using all the system + // resouces. This test can be rather memory-hungry (~1 GB/thread); if it causes trouble in + // practice do not hesitate to limit its parallelism. + for _ in 0..run_make_support::env::jobs() { + let tasks = Arc::clone(&tasks); + let handle = thread::spawn(move || { + loop { + let maybe_task = tasks.lock().unwrap().pop(); + if let Some(task) = maybe_task { + test(task); + } else { + break; + } + } + }); + threads.push(handle); + } + + for t in threads { + t.join().unwrap(); + } +} + +fn test(task: Task) { + let dir = TempDir::new().unwrap(); + + let manifest = manifest(&task); + rfs::write(dir.path().join("Cargo.toml"), &manifest); + rfs::write(dir.path().join("lib.rs"), "#![no_std]"); + + let mut args = vec!["build", "--release", "-Zbuild-std=core", "--target", &task.target, "-j1"]; + if task.panic == "immediate-abort" { + args.push("-Zpanic-immediate-abort"); + } + cargo() + .current_dir(dir.path()) + .args(&args) + .env("RUSTC_BOOTSTRAP", "1") + // Visual Studio 2022 requires that the LIB env var be set so it can + // find the Windows SDK. + .env("LIB", std::env::var("LIB").unwrap_or_default()) + .context(&format!( + "build-std for target `{}` failed with the following Cargo.toml:\n\n{manifest}", + task.target + )) + .run(); +} From c31add03870e80556703be3c9544109328559379 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 15 Jan 2026 04:21:53 +0000 Subject: [PATCH 2152/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to b6fdaf2a15736cbccf248b532f48e33179614d40. --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index b53a66c66751..a6ccd9bab393 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -44a5b55557c26353f388400d7da95527256fe260 +b6fdaf2a15736cbccf248b532f48e33179614d40 From d59c47c2bc933f46e63ea5f23618f9618c0b9f51 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 15 Jan 2026 05:01:05 +0000 Subject: [PATCH 2153/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to b6fdaf2a15736cbccf248b532f48e33179614d40. --- 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 b53a66c66751..a6ccd9bab393 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -44a5b55557c26353f388400d7da95527256fe260 +b6fdaf2a15736cbccf248b532f48e33179614d40 From d7e5996e4f55158af402fc77322812bea46eb8c2 Mon Sep 17 00:00:00 2001 From: Hugh Date: Wed, 14 Jan 2026 23:12:46 -0800 Subject: [PATCH 2154/3801] Skip elidable_lifetime_names lint for proc-macro generated code When linting code generated by proc macros (like `derivative`), the `elidable_lifetime_names` lint can produce fix suggestions with overlapping spans. This causes `cargo clippy --fix` to fail with "cannot replace slice of data that was already replaced". This change adds `is_from_proc_macro` checks to the three lint entry points (`check_item`, `check_impl_item`, `check_trait_item`) to skip linting proc-macro generated code entirely. Fixes #16316 --- clippy_lints/src/lifetimes.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 727e9b172a87..8917c90262a4 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::trait_ref_of_method; +use clippy_utils::{is_from_proc_macro, trait_ref_of_method}; use itertools::Itertools; use rustc_ast::visit::{try_visit, walk_list}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; @@ -149,16 +149,22 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes { .. } = item.kind { + if is_from_proc_macro(cx, item) { + return; + } check_fn_inner(cx, sig, Some(id), None, generics, item.span, true, self.msrv); } else if let ItemKind::Impl(impl_) = &item.kind && !item.span.from_expansion() + && !is_from_proc_macro(cx, item) { report_extra_impl_lifetimes(cx, impl_); } } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { - if let ImplItemKind::Fn(ref sig, id) = item.kind { + if let ImplItemKind::Fn(ref sig, id) = item.kind + && !is_from_proc_macro(cx, item) + { let report_extra_lifetimes = trait_ref_of_method(cx, item.owner_id).is_none(); check_fn_inner( cx, @@ -174,7 +180,9 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes { } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { - if let TraitItemKind::Fn(ref sig, ref body) = item.kind { + if let TraitItemKind::Fn(ref sig, ref body) = item.kind + && !is_from_proc_macro(cx, item) + { let (body, trait_sig) = match *body { TraitFn::Required(sig) => (None, Some(sig)), TraitFn::Provided(id) => (Some(id), None), From cd05071ec4a4b62d469603fb7b89d0a35857cbe1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 14 Jan 2026 20:18:09 +0300 Subject: [PATCH 2155/3801] resolve: Downgrade `ambiguous_glob_imports` to warn-by-default But still keep it report-in-deps. To revert after ~February 27 2026, when Rust 1.95 branches out from the main branch. --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- tests/ui/imports/ambiguous-10.rs | 4 ++-- tests/ui/imports/ambiguous-10.stderr | 10 ++++----- tests/ui/imports/ambiguous-12.rs | 4 ++-- tests/ui/imports/ambiguous-12.stderr | 10 ++++----- tests/ui/imports/ambiguous-13.rs | 4 ++-- tests/ui/imports/ambiguous-13.stderr | 10 ++++----- tests/ui/imports/ambiguous-14.rs | 4 ++-- tests/ui/imports/ambiguous-14.stderr | 10 ++++----- tests/ui/imports/ambiguous-15.rs | 4 ++-- tests/ui/imports/ambiguous-15.stderr | 10 ++++----- tests/ui/imports/ambiguous-16.rs | 4 ++-- tests/ui/imports/ambiguous-16.stderr | 10 ++++----- tests/ui/imports/ambiguous-17.rs | 4 ++-- tests/ui/imports/ambiguous-17.stderr | 10 ++++----- tests/ui/imports/ambiguous-2.rs | 4 ++-- tests/ui/imports/ambiguous-2.stderr | 10 ++++----- tests/ui/imports/ambiguous-3.rs | 4 ++-- tests/ui/imports/ambiguous-3.stderr | 10 ++++----- tests/ui/imports/ambiguous-4.rs | 4 ++-- tests/ui/imports/ambiguous-4.stderr | 10 ++++----- tests/ui/imports/ambiguous-5.rs | 4 ++-- tests/ui/imports/ambiguous-5.stderr | 10 ++++----- tests/ui/imports/ambiguous-6.rs | 4 ++-- tests/ui/imports/ambiguous-6.stderr | 10 ++++----- tests/ui/imports/ambiguous-9.rs | 6 ++--- tests/ui/imports/ambiguous-9.stderr | 16 +++++++------- .../ui/imports/ambiguous-panic-globvsglob.rs | 4 ++-- .../imports/ambiguous-panic-globvsglob.stderr | 10 ++++----- tests/ui/imports/duplicate.rs | 2 +- tests/ui/imports/duplicate.stderr | 10 ++++----- .../ui/imports/glob-conflict-cross-crate-1.rs | 6 ++--- .../glob-conflict-cross-crate-1.stderr | 16 +++++++------- .../ui/imports/glob-conflict-cross-crate-2.rs | 4 ++-- .../glob-conflict-cross-crate-2.stderr | 10 ++++----- .../ui/imports/glob-conflict-cross-crate-3.rs | 6 ++--- .../glob-conflict-cross-crate-3.stderr | 16 +++++++------- tests/ui/imports/issue-114682-2.rs | 6 ++--- tests/ui/imports/issue-114682-2.stderr | 16 +++++++------- tests/ui/imports/issue-114682-4.rs | 2 +- tests/ui/imports/issue-114682-4.stderr | 10 ++++----- tests/ui/imports/issue-114682-5.rs | 2 +- tests/ui/imports/issue-114682-5.stderr | 10 ++++----- tests/ui/imports/issue-114682-6.rs | 4 ++-- tests/ui/imports/issue-114682-6.stderr | 10 ++++----- .../ui/imports/overwrite-different-ambig-2.rs | 4 +++- .../overwrite-different-ambig-2.stderr | 22 +++++++++---------- .../imports/unresolved-seg-after-ambiguous.rs | 2 +- .../unresolved-seg-after-ambiguous.stderr | 10 ++++----- 49 files changed, 188 insertions(+), 186 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 4230aa7568e2..c165b91cc916 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4465,7 +4465,7 @@ declare_lint! { /// /// [future-incompatible]: ../index.md#future-incompatible-lints pub AMBIGUOUS_GLOB_IMPORTS, - Deny, + Warn, "detects certain glob imports that require reporting an ambiguity error", @future_incompatible = FutureIncompatibleInfo { reason: fcw!(FutureReleaseError #114095), diff --git a/tests/ui/imports/ambiguous-10.rs b/tests/ui/imports/ambiguous-10.rs index 166b01ede12d..61069cb75124 100644 --- a/tests/ui/imports/ambiguous-10.rs +++ b/tests/ui/imports/ambiguous-10.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296 - +//@ check-pass mod a { pub enum Token {} } @@ -13,6 +13,6 @@ mod b { use crate::a::*; use crate::b::*; fn c(_: Token) {} -//~^ ERROR `Token` is ambiguous +//~^ WARN `Token` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() { } diff --git a/tests/ui/imports/ambiguous-10.stderr b/tests/ui/imports/ambiguous-10.stderr index f175d27c99e9..4ae3e4203fab 100644 --- a/tests/ui/imports/ambiguous-10.stderr +++ b/tests/ui/imports/ambiguous-10.stderr @@ -1,4 +1,4 @@ -error: `Token` is ambiguous +warning: `Token` is ambiguous --> $DIR/ambiguous-10.rs:15:9 | LL | fn c(_: Token) {} @@ -19,12 +19,12 @@ note: `Token` could also refer to the enum imported here LL | use crate::b::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `Token` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `Token` is ambiguous +warning: `Token` is ambiguous --> $DIR/ambiguous-10.rs:15:9 | LL | fn c(_: Token) {} @@ -45,5 +45,5 @@ note: `Token` could also refer to the enum imported here LL | use crate::b::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `Token` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-12.rs b/tests/ui/imports/ambiguous-12.rs index 543396b8dfe5..93cd3ca6f347 100644 --- a/tests/ui/imports/ambiguous-12.rs +++ b/tests/ui/imports/ambiguous-12.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296 - +//@ check-pass macro_rules! m { () => { pub fn b() {} @@ -19,6 +19,6 @@ use crate::public::*; fn main() { b(); - //~^ ERROR `b` is ambiguous + //~^ WARN `b` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-12.stderr b/tests/ui/imports/ambiguous-12.stderr index 5f92eae0dbcb..1a1777dedac4 100644 --- a/tests/ui/imports/ambiguous-12.stderr +++ b/tests/ui/imports/ambiguous-12.stderr @@ -1,4 +1,4 @@ -error: `b` is ambiguous +warning: `b` is ambiguous --> $DIR/ambiguous-12.rs:21:5 | LL | b(); @@ -19,12 +19,12 @@ note: `b` could also refer to the function imported here LL | use crate::public::*; | ^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `b` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `b` is ambiguous +warning: `b` is ambiguous --> $DIR/ambiguous-12.rs:21:5 | LL | b(); @@ -45,5 +45,5 @@ note: `b` could also refer to the function imported here LL | use crate::public::*; | ^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `b` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-13.rs b/tests/ui/imports/ambiguous-13.rs index 3569dd5d9adc..5fbb71d8545a 100644 --- a/tests/ui/imports/ambiguous-13.rs +++ b/tests/ui/imports/ambiguous-13.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296 - +//@ check-pass pub mod object { #[derive(Debug)] pub struct Rect; @@ -16,6 +16,6 @@ use crate::object::*; use crate::content::*; fn a(_: Rect) {} -//~^ ERROR `Rect` is ambiguous +//~^ WARN `Rect` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() { } diff --git a/tests/ui/imports/ambiguous-13.stderr b/tests/ui/imports/ambiguous-13.stderr index 279b4e8f1420..ca83cf63c12c 100644 --- a/tests/ui/imports/ambiguous-13.stderr +++ b/tests/ui/imports/ambiguous-13.stderr @@ -1,4 +1,4 @@ -error: `Rect` is ambiguous +warning: `Rect` is ambiguous --> $DIR/ambiguous-13.rs:18:9 | LL | fn a(_: Rect) {} @@ -19,12 +19,12 @@ note: `Rect` could also refer to the struct imported here LL | use crate::content::*; | ^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `Rect` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `Rect` is ambiguous +warning: `Rect` is ambiguous --> $DIR/ambiguous-13.rs:18:9 | LL | fn a(_: Rect) {} @@ -45,5 +45,5 @@ note: `Rect` could also refer to the struct imported here LL | use crate::content::*; | ^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `Rect` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-14.rs b/tests/ui/imports/ambiguous-14.rs index ba2d7dc4e016..325b29f3b481 100644 --- a/tests/ui/imports/ambiguous-14.rs +++ b/tests/ui/imports/ambiguous-14.rs @@ -1,6 +1,6 @@ //@ edition:2015 // https://github.com/rust-lang/rust/issues/98467 - +//@ check-pass mod a { pub fn foo() {} } @@ -21,6 +21,6 @@ mod g { fn main() { g::foo(); - //~^ ERROR `foo` is ambiguous + //~^ WARN `foo` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-14.stderr b/tests/ui/imports/ambiguous-14.stderr index 2a3557c31f12..6823d728c368 100644 --- a/tests/ui/imports/ambiguous-14.stderr +++ b/tests/ui/imports/ambiguous-14.stderr @@ -1,4 +1,4 @@ -error: `foo` is ambiguous +warning: `foo` is ambiguous --> $DIR/ambiguous-14.rs:23:8 | LL | g::foo(); @@ -19,12 +19,12 @@ note: `foo` could also refer to the function imported here LL | pub use f::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `foo` is ambiguous +warning: `foo` is ambiguous --> $DIR/ambiguous-14.rs:23:8 | LL | g::foo(); @@ -45,5 +45,5 @@ note: `foo` could also refer to the function imported here LL | pub use f::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-15.rs b/tests/ui/imports/ambiguous-15.rs index 07d8893b2dea..f90d9696e8ef 100644 --- a/tests/ui/imports/ambiguous-15.rs +++ b/tests/ui/imports/ambiguous-15.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1638206152 - +//@ check-pass mod t2 { #[derive(Debug)] pub enum Error {} @@ -20,7 +20,7 @@ mod t3 { use self::t3::*; fn a(_: E) {} -//~^ ERROR `Error` is ambiguous +//~^ WARN `Error` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() {} diff --git a/tests/ui/imports/ambiguous-15.stderr b/tests/ui/imports/ambiguous-15.stderr index 15f83546532e..59f9cb0526fc 100644 --- a/tests/ui/imports/ambiguous-15.stderr +++ b/tests/ui/imports/ambiguous-15.stderr @@ -1,4 +1,4 @@ -error: `Error` is ambiguous +warning: `Error` is ambiguous --> $DIR/ambiguous-15.rs:22:9 | LL | fn a(_: E) {} @@ -19,12 +19,12 @@ note: `Error` could also refer to the enum imported here LL | pub use t2::*; | ^^^^^ = help: consider adding an explicit import of `Error` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `Error` is ambiguous +warning: `Error` is ambiguous --> $DIR/ambiguous-15.rs:22:9 | LL | fn a(_: E) {} @@ -45,5 +45,5 @@ note: `Error` could also refer to the enum imported here LL | pub use t2::*; | ^^^^^ = help: consider adding an explicit import of `Error` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-16.rs b/tests/ui/imports/ambiguous-16.rs index f31c78d18a38..2cd1e2aca9d3 100644 --- a/tests/ui/imports/ambiguous-16.rs +++ b/tests/ui/imports/ambiguous-16.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099 - +//@ check-pass mod framing { mod public_message { use super::*; @@ -20,7 +20,7 @@ mod framing { } use crate::framing::ConfirmedTranscriptHashInput; -//~^ ERROR `ConfirmedTranscriptHashInput` is ambiguous +//~^ WARN `ConfirmedTranscriptHashInput` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() { } diff --git a/tests/ui/imports/ambiguous-16.stderr b/tests/ui/imports/ambiguous-16.stderr index 7c80dee17f04..bb76111ebe89 100644 --- a/tests/ui/imports/ambiguous-16.stderr +++ b/tests/ui/imports/ambiguous-16.stderr @@ -1,4 +1,4 @@ -error: `ConfirmedTranscriptHashInput` is ambiguous +warning: `ConfirmedTranscriptHashInput` is ambiguous --> $DIR/ambiguous-16.rs:22:21 | LL | use crate::framing::ConfirmedTranscriptHashInput; @@ -19,12 +19,12 @@ note: `ConfirmedTranscriptHashInput` could also refer to the struct imported her LL | pub use self::public_message_in::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `ConfirmedTranscriptHashInput` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `ConfirmedTranscriptHashInput` is ambiguous +warning: `ConfirmedTranscriptHashInput` is ambiguous --> $DIR/ambiguous-16.rs:22:21 | LL | use crate::framing::ConfirmedTranscriptHashInput; @@ -45,5 +45,5 @@ note: `ConfirmedTranscriptHashInput` could also refer to the struct imported her LL | pub use self::public_message_in::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `ConfirmedTranscriptHashInput` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-17.rs b/tests/ui/imports/ambiguous-17.rs index 3a51c156d34c..8ef0318fa046 100644 --- a/tests/ui/imports/ambiguous-17.rs +++ b/tests/ui/imports/ambiguous-17.rs @@ -1,6 +1,6 @@ //@ edition:2015 // https://github.com/rust-lang/rust/pull/113099#issuecomment-1638206152 - +//@ check-pass pub use evp::*; //~ WARNING ambiguous glob re-exports pub use handwritten::*; @@ -24,6 +24,6 @@ mod handwritten { fn main() { id(); - //~^ ERROR `id` is ambiguous + //~^ WARN `id` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-17.stderr b/tests/ui/imports/ambiguous-17.stderr index 1849b83d76a3..ef4a835a0b3c 100644 --- a/tests/ui/imports/ambiguous-17.stderr +++ b/tests/ui/imports/ambiguous-17.stderr @@ -8,7 +8,7 @@ LL | pub use handwritten::*; | = note: `#[warn(ambiguous_glob_reexports)]` on by default -error: `id` is ambiguous +warning: `id` is ambiguous --> $DIR/ambiguous-17.rs:26:5 | LL | id(); @@ -29,12 +29,12 @@ note: `id` could also refer to the function imported here LL | pub use handwritten::*; | ^^^^^^^^^^^^^^ = help: consider adding an explicit import of `id` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error; 1 warning emitted +warning: 2 warnings emitted Future incompatibility report: Future breakage diagnostic: -error: `id` is ambiguous +warning: `id` is ambiguous --> $DIR/ambiguous-17.rs:26:5 | LL | id(); @@ -55,5 +55,5 @@ note: `id` could also refer to the function imported here LL | pub use handwritten::*; | ^^^^^^^^^^^^^^ = help: consider adding an explicit import of `id` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-2.rs b/tests/ui/imports/ambiguous-2.rs index 65c971c00b9a..978655bc0177 100644 --- a/tests/ui/imports/ambiguous-2.rs +++ b/tests/ui/imports/ambiguous-2.rs @@ -1,9 +1,9 @@ //@ aux-build: ../ambiguous-1.rs // https://github.com/rust-lang/rust/pull/113099#issuecomment-1633574396 - +//@ check-pass extern crate ambiguous_1; fn main() { - ambiguous_1::id(); //~ ERROR `id` is ambiguous + ambiguous_1::id(); //~ WARN `id` is ambiguous //~| WARN this was previously accepted } diff --git a/tests/ui/imports/ambiguous-2.stderr b/tests/ui/imports/ambiguous-2.stderr index d428e58a78fd..a0222099239a 100644 --- a/tests/ui/imports/ambiguous-2.stderr +++ b/tests/ui/imports/ambiguous-2.stderr @@ -1,4 +1,4 @@ -error: `id` is ambiguous +warning: `id` is ambiguous --> $DIR/ambiguous-2.rs:7:18 | LL | ambiguous_1::id(); @@ -17,12 +17,12 @@ note: `id` could also refer to the function defined here | LL | pub use self::handwritten::*; | ^^^^^^^^^^^^^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `id` is ambiguous +warning: `id` is ambiguous --> $DIR/ambiguous-2.rs:7:18 | LL | ambiguous_1::id(); @@ -41,5 +41,5 @@ note: `id` could also refer to the function defined here | LL | pub use self::handwritten::*; | ^^^^^^^^^^^^^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-3.rs b/tests/ui/imports/ambiguous-3.rs index ff0dcc221ec0..717c1eb8597a 100644 --- a/tests/ui/imports/ambiguous-3.rs +++ b/tests/ui/imports/ambiguous-3.rs @@ -1,9 +1,9 @@ // https://github.com/rust-lang/rust/issues/47525 - +//@ check-pass fn main() { use a::*; x(); - //~^ ERROR `x` is ambiguous + //~^ WARN `x` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-3.stderr b/tests/ui/imports/ambiguous-3.stderr index 27fa05a195b9..7addf9bc797c 100644 --- a/tests/ui/imports/ambiguous-3.stderr +++ b/tests/ui/imports/ambiguous-3.stderr @@ -1,4 +1,4 @@ -error: `x` is ambiguous +warning: `x` is ambiguous --> $DIR/ambiguous-3.rs:5:5 | LL | x(); @@ -19,12 +19,12 @@ note: `x` could also refer to the function imported here LL | pub use self::c::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `x` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `x` is ambiguous +warning: `x` is ambiguous --> $DIR/ambiguous-3.rs:5:5 | LL | x(); @@ -45,5 +45,5 @@ note: `x` could also refer to the function imported here LL | pub use self::c::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `x` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-4.rs b/tests/ui/imports/ambiguous-4.rs index e66d231f93cc..1a2bfeaf53dc 100644 --- a/tests/ui/imports/ambiguous-4.rs +++ b/tests/ui/imports/ambiguous-4.rs @@ -1,9 +1,9 @@ //@ edition:2015 //@ aux-build: ../ambiguous-4-extern.rs - +//@ check-pass extern crate ambiguous_4_extern; fn main() { - ambiguous_4_extern::id(); //~ ERROR `id` is ambiguous + ambiguous_4_extern::id(); //~ WARN `id` is ambiguous //~| WARN this was previously accepted } diff --git a/tests/ui/imports/ambiguous-4.stderr b/tests/ui/imports/ambiguous-4.stderr index cf4127cbbb1c..6c1a2679fcae 100644 --- a/tests/ui/imports/ambiguous-4.stderr +++ b/tests/ui/imports/ambiguous-4.stderr @@ -1,4 +1,4 @@ -error: `id` is ambiguous +warning: `id` is ambiguous --> $DIR/ambiguous-4.rs:7:25 | LL | ambiguous_4_extern::id(); @@ -17,12 +17,12 @@ note: `id` could also refer to the function defined here | LL | pub use handwritten::*; | ^^^^^^^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `id` is ambiguous +warning: `id` is ambiguous --> $DIR/ambiguous-4.rs:7:25 | LL | ambiguous_4_extern::id(); @@ -41,5 +41,5 @@ note: `id` could also refer to the function defined here | LL | pub use handwritten::*; | ^^^^^^^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-5.rs b/tests/ui/imports/ambiguous-5.rs index 8f89c966d4a5..9879216280a2 100644 --- a/tests/ui/imports/ambiguous-5.rs +++ b/tests/ui/imports/ambiguous-5.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296 - +//@ check-pass mod a { pub struct Class(u16); } @@ -10,7 +10,7 @@ mod gpos { use super::gsubgpos::*; use super::*; struct MarkRecord(Class); - //~^ ERROR`Class` is ambiguous + //~^ WARN`Class` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-5.stderr b/tests/ui/imports/ambiguous-5.stderr index 1fc5f4543f35..a4f3151c9e85 100644 --- a/tests/ui/imports/ambiguous-5.stderr +++ b/tests/ui/imports/ambiguous-5.stderr @@ -1,4 +1,4 @@ -error: `Class` is ambiguous +warning: `Class` is ambiguous --> $DIR/ambiguous-5.rs:12:23 | LL | struct MarkRecord(Class); @@ -19,12 +19,12 @@ note: `Class` could also refer to the struct imported here LL | use super::gsubgpos::*; | ^^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `Class` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `Class` is ambiguous +warning: `Class` is ambiguous --> $DIR/ambiguous-5.rs:12:23 | LL | struct MarkRecord(Class); @@ -45,5 +45,5 @@ note: `Class` could also refer to the struct imported here LL | use super::gsubgpos::*; | ^^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `Class` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-6.rs b/tests/ui/imports/ambiguous-6.rs index 1c6e34377165..9a3a138bda4c 100644 --- a/tests/ui/imports/ambiguous-6.rs +++ b/tests/ui/imports/ambiguous-6.rs @@ -1,10 +1,10 @@ //@ edition: 2021 // https://github.com/rust-lang/rust/issues/112713 - +//@ check-pass pub fn foo() -> u32 { use sub::*; C - //~^ ERROR `C` is ambiguous + //~^ WARN `C` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-6.stderr b/tests/ui/imports/ambiguous-6.stderr index 681bc40931f5..d811cfa4236a 100644 --- a/tests/ui/imports/ambiguous-6.stderr +++ b/tests/ui/imports/ambiguous-6.stderr @@ -1,4 +1,4 @@ -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/ambiguous-6.rs:6:5 | LL | C @@ -19,12 +19,12 @@ note: `C` could also refer to the constant imported here LL | pub use mod2::*; | ^^^^^^^ = help: consider adding an explicit import of `C` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/ambiguous-6.rs:6:5 | LL | C @@ -45,5 +45,5 @@ note: `C` could also refer to the constant imported here LL | pub use mod2::*; | ^^^^^^^ = help: consider adding an explicit import of `C` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-9.rs b/tests/ui/imports/ambiguous-9.rs index c10b1268060c..e6329b8d46ac 100644 --- a/tests/ui/imports/ambiguous-9.rs +++ b/tests/ui/imports/ambiguous-9.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1638206152 - +//@ check-pass pub mod dsl { mod range { pub fn date_range() {} @@ -21,8 +21,8 @@ use prelude::*; fn main() { date_range(); - //~^ ERROR `date_range` is ambiguous + //~^ WARN `date_range` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //~| ERROR `date_range` is ambiguous + //~| WARN `date_range` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-9.stderr b/tests/ui/imports/ambiguous-9.stderr index 800a2e10c9d7..da7d2d970fdd 100644 --- a/tests/ui/imports/ambiguous-9.stderr +++ b/tests/ui/imports/ambiguous-9.stderr @@ -8,7 +8,7 @@ LL | use super::prelude::*; | = note: `#[warn(ambiguous_glob_reexports)]` on by default -error: `date_range` is ambiguous +warning: `date_range` is ambiguous --> $DIR/ambiguous-9.rs:23:5 | LL | date_range(); @@ -29,7 +29,7 @@ note: `date_range` could also refer to the function imported here LL | use super::prelude::*; | ^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default warning: ambiguous glob re-exports --> $DIR/ambiguous-9.rs:15:13 @@ -39,7 +39,7 @@ LL | pub use self::t::*; LL | pub use super::dsl::*; | ------------- but the name `date_range` in the value namespace is also re-exported here -error: `date_range` is ambiguous +warning: `date_range` is ambiguous --> $DIR/ambiguous-9.rs:23:5 | LL | date_range(); @@ -61,10 +61,10 @@ LL | use prelude::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate -error: aborting due to 2 previous errors; 2 warnings emitted +warning: 4 warnings emitted Future incompatibility report: Future breakage diagnostic: -error: `date_range` is ambiguous +warning: `date_range` is ambiguous --> $DIR/ambiguous-9.rs:23:5 | LL | date_range(); @@ -85,10 +85,10 @@ note: `date_range` could also refer to the function imported here LL | use super::prelude::*; | ^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default Future breakage diagnostic: -error: `date_range` is ambiguous +warning: `date_range` is ambiguous --> $DIR/ambiguous-9.rs:23:5 | LL | date_range(); @@ -109,5 +109,5 @@ note: `date_range` could also refer to the function imported here LL | use prelude::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-panic-globvsglob.rs b/tests/ui/imports/ambiguous-panic-globvsglob.rs index 4ff3cc822535..335fba74b208 100644 --- a/tests/ui/imports/ambiguous-panic-globvsglob.rs +++ b/tests/ui/imports/ambiguous-panic-globvsglob.rs @@ -3,7 +3,7 @@ mod m1 { pub use core::prelude::v1::*; } - +//@ check-pass mod m2 { pub use std::prelude::v1::*; } @@ -18,6 +18,6 @@ fn foo() { panic!(); //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports] //~| WARN: this was previously accepted by the compiler - //~| ERROR: `panic` is ambiguous [ambiguous_glob_imports] + //~| WARN: `panic` is ambiguous [ambiguous_glob_imports] //~| WARN: this was previously accepted by the compiler } diff --git a/tests/ui/imports/ambiguous-panic-globvsglob.stderr b/tests/ui/imports/ambiguous-panic-globvsglob.stderr index 455c58bb6c02..8e216b21734f 100644 --- a/tests/ui/imports/ambiguous-panic-globvsglob.stderr +++ b/tests/ui/imports/ambiguous-panic-globvsglob.stderr @@ -1,4 +1,4 @@ -error: `panic` is ambiguous +warning: `panic` is ambiguous --> $DIR/ambiguous-panic-globvsglob.rs:18:5 | LL | panic!(); @@ -19,7 +19,7 @@ note: `panic` could also refer to the macro imported here LL | use m2::*; | ^^^^^ = help: consider adding an explicit import of `panic` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default warning: `panic` is ambiguous --> $DIR/ambiguous-panic-globvsglob.rs:18:5 @@ -40,10 +40,10 @@ note: `panic` could also refer to a macro from prelude --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error; 1 warning emitted +warning: 2 warnings emitted Future incompatibility report: Future breakage diagnostic: -error: `panic` is ambiguous +warning: `panic` is ambiguous --> $DIR/ambiguous-panic-globvsglob.rs:18:5 | LL | panic!(); @@ -64,5 +64,5 @@ note: `panic` could also refer to the macro imported here LL | use m2::*; | ^^^^^ = help: consider adding an explicit import of `panic` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/duplicate.rs b/tests/ui/imports/duplicate.rs index 0a652889ca8a..ef54726c9a93 100644 --- a/tests/ui/imports/duplicate.rs +++ b/tests/ui/imports/duplicate.rs @@ -34,7 +34,7 @@ fn main() { e::foo(); f::foo(); //~ ERROR `foo` is ambiguous g::foo(); - //~^ ERROR `foo` is ambiguous + //~^ WARN `foo` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/duplicate.stderr b/tests/ui/imports/duplicate.stderr index 74829fc21e22..9252a041749d 100644 --- a/tests/ui/imports/duplicate.stderr +++ b/tests/ui/imports/duplicate.stderr @@ -68,7 +68,7 @@ LL | use self::m2::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate -error: `foo` is ambiguous +warning: `foo` is ambiguous --> $DIR/duplicate.rs:36:8 | LL | g::foo(); @@ -89,14 +89,14 @@ note: `foo` could also refer to the function imported here LL | pub use crate::f::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors; 1 warning emitted Some errors have detailed explanations: E0252, E0659. For more information about an error, try `rustc --explain E0252`. Future incompatibility report: Future breakage diagnostic: -error: `foo` is ambiguous +warning: `foo` is ambiguous --> $DIR/duplicate.rs:36:8 | LL | g::foo(); @@ -117,5 +117,5 @@ note: `foo` could also refer to the function imported here LL | pub use crate::f::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.rs b/tests/ui/imports/glob-conflict-cross-crate-1.rs index 08ce6166b5c1..787fa36db2d9 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-1.rs @@ -1,11 +1,11 @@ //@ edition:2015 //@ aux-build:glob-conflict.rs - +//@ check-pass extern crate glob_conflict; fn main() { - glob_conflict::f(); //~ ERROR `f` is ambiguous + glob_conflict::f(); //~ WARN `f` is ambiguous //~| WARN this was previously accepted - glob_conflict::glob::f(); //~ ERROR `f` is ambiguous + glob_conflict::glob::f(); //~ WARN `f` is ambiguous //~| WARN this was previously accepted } diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr index 54b7976b057e..440113653675 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -1,4 +1,4 @@ -error: `f` is ambiguous +warning: `f` is ambiguous --> $DIR/glob-conflict-cross-crate-1.rs:7:20 | LL | glob_conflict::f(); @@ -17,9 +17,9 @@ note: `f` could also refer to the function defined here | LL | pub use m2::*; | ^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: `f` is ambiguous +warning: `f` is ambiguous --> $DIR/glob-conflict-cross-crate-1.rs:9:26 | LL | glob_conflict::glob::f(); @@ -39,10 +39,10 @@ note: `f` could also refer to the function defined here LL | pub use m2::*; | ^^ -error: aborting due to 2 previous errors +warning: 2 warnings emitted Future incompatibility report: Future breakage diagnostic: -error: `f` is ambiguous +warning: `f` is ambiguous --> $DIR/glob-conflict-cross-crate-1.rs:7:20 | LL | glob_conflict::f(); @@ -61,10 +61,10 @@ note: `f` could also refer to the function defined here | LL | pub use m2::*; | ^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default Future breakage diagnostic: -error: `f` is ambiguous +warning: `f` is ambiguous --> $DIR/glob-conflict-cross-crate-1.rs:9:26 | LL | glob_conflict::glob::f(); @@ -83,5 +83,5 @@ note: `f` could also refer to the function defined here | LL | pub use m2::*; | ^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.rs b/tests/ui/imports/glob-conflict-cross-crate-2.rs index b4dd3d8eeb44..018a74d35d7f 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-2.rs @@ -1,10 +1,10 @@ //@ aux-build:glob-conflict-cross-crate-2-extern.rs - +//@ check-pass extern crate glob_conflict_cross_crate_2_extern; use glob_conflict_cross_crate_2_extern::*; fn main() { - let _a: C = 1; //~ ERROR `C` is ambiguous + let _a: C = 1; //~ WARN `C` is ambiguous //~| WARN this was previously accepted } diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.stderr b/tests/ui/imports/glob-conflict-cross-crate-2.stderr index cbc2180c14f4..2ee519a364b3 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-2.stderr @@ -1,4 +1,4 @@ -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/glob-conflict-cross-crate-2.rs:8:13 | LL | let _a: C = 1; @@ -17,12 +17,12 @@ note: `C` could also refer to the type alias defined here | LL | pub use b::*; | ^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/glob-conflict-cross-crate-2.rs:8:13 | LL | let _a: C = 1; @@ -41,5 +41,5 @@ note: `C` could also refer to the type alias defined here | LL | pub use b::*; | ^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/glob-conflict-cross-crate-3.rs b/tests/ui/imports/glob-conflict-cross-crate-3.rs index 31c234b9250f..a7b215359090 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-3.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-3.rs @@ -1,5 +1,5 @@ //@ aux-build:glob-conflict-cross-crate-2-extern.rs - +//@ check-pass extern crate glob_conflict_cross_crate_2_extern; mod a { @@ -11,8 +11,8 @@ use a::*; fn main() { let _a: C = 1; - //~^ ERROR `C` is ambiguous - //~| ERROR `C` is ambiguous + //~^ WARN `C` is ambiguous + //~| WARN `C` is ambiguous //~| WARN this was previously accepted //~| WARN this was previously accepted } diff --git a/tests/ui/imports/glob-conflict-cross-crate-3.stderr b/tests/ui/imports/glob-conflict-cross-crate-3.stderr index 213eafda20b7..c7457efe866e 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-3.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-3.stderr @@ -1,4 +1,4 @@ -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/glob-conflict-cross-crate-3.rs:13:13 | LL | let _a: C = 1; @@ -17,9 +17,9 @@ note: `C` could also refer to the type alias defined here | LL | pub use b::*; | ^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/glob-conflict-cross-crate-3.rs:13:13 | LL | let _a: C = 1; @@ -41,10 +41,10 @@ LL | use a::*; | ^^^^ = help: consider adding an explicit import of `C` to disambiguate -error: aborting due to 2 previous errors +warning: 2 warnings emitted Future incompatibility report: Future breakage diagnostic: -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/glob-conflict-cross-crate-3.rs:13:13 | LL | let _a: C = 1; @@ -63,10 +63,10 @@ note: `C` could also refer to the type alias defined here | LL | pub use b::*; | ^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default Future breakage diagnostic: -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/glob-conflict-cross-crate-3.rs:13:13 | LL | let _a: C = 1; @@ -87,5 +87,5 @@ note: `C` could also refer to the type alias imported here LL | use a::*; | ^^^^ = help: consider adding an explicit import of `C` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/issue-114682-2.rs b/tests/ui/imports/issue-114682-2.rs index a9459c5b02ef..da145f3addc0 100644 --- a/tests/ui/imports/issue-114682-2.rs +++ b/tests/ui/imports/issue-114682-2.rs @@ -1,12 +1,12 @@ //@ aux-build: issue-114682-2-extern.rs // https://github.com/rust-lang/rust/pull/114682#issuecomment-1879998900 - +//@ check-pass extern crate issue_114682_2_extern; -use issue_114682_2_extern::max; //~ ERROR `max` is ambiguous +use issue_114682_2_extern::max; //~ WARN `max` is ambiguous //~| WARN this was previously accepted -type A = issue_114682_2_extern::max; //~ ERROR `max` is ambiguous +type A = issue_114682_2_extern::max; //~ WARN `max` is ambiguous //~| WARN this was previously accepted fn main() {} diff --git a/tests/ui/imports/issue-114682-2.stderr b/tests/ui/imports/issue-114682-2.stderr index 07c696651c38..f93e4409f0c4 100644 --- a/tests/ui/imports/issue-114682-2.stderr +++ b/tests/ui/imports/issue-114682-2.stderr @@ -1,4 +1,4 @@ -error: `max` is ambiguous +warning: `max` is ambiguous --> $DIR/issue-114682-2.rs:6:28 | LL | use issue_114682_2_extern::max; @@ -17,9 +17,9 @@ note: `max` could also refer to the module defined here | LL | pub use self::d::*; | ^^^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: `max` is ambiguous +warning: `max` is ambiguous --> $DIR/issue-114682-2.rs:9:33 | LL | type A = issue_114682_2_extern::max; @@ -39,10 +39,10 @@ note: `max` could also refer to the module defined here LL | pub use self::d::*; | ^^^^^^^ -error: aborting due to 2 previous errors +warning: 2 warnings emitted Future incompatibility report: Future breakage diagnostic: -error: `max` is ambiguous +warning: `max` is ambiguous --> $DIR/issue-114682-2.rs:6:28 | LL | use issue_114682_2_extern::max; @@ -61,10 +61,10 @@ note: `max` could also refer to the module defined here | LL | pub use self::d::*; | ^^^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default Future breakage diagnostic: -error: `max` is ambiguous +warning: `max` is ambiguous --> $DIR/issue-114682-2.rs:9:33 | LL | type A = issue_114682_2_extern::max; @@ -83,5 +83,5 @@ note: `max` could also refer to the module defined here | LL | pub use self::d::*; | ^^^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/issue-114682-4.rs b/tests/ui/imports/issue-114682-4.rs index 01921928a007..29e175b5ed54 100644 --- a/tests/ui/imports/issue-114682-4.rs +++ b/tests/ui/imports/issue-114682-4.rs @@ -6,7 +6,7 @@ extern crate issue_114682_4_extern; use issue_114682_4_extern::*; //~v ERROR type alias takes 1 generic argument but 2 generic arguments were supplied -fn a() -> Result { //~ ERROR `Result` is ambiguous +fn a() -> Result { //~ WARN `Result` is ambiguous //~| WARN this was previously accepted Ok(1) } diff --git a/tests/ui/imports/issue-114682-4.stderr b/tests/ui/imports/issue-114682-4.stderr index 5e677cd7ae72..12cb9ae95a42 100644 --- a/tests/ui/imports/issue-114682-4.stderr +++ b/tests/ui/imports/issue-114682-4.stderr @@ -1,4 +1,4 @@ -error: `Result` is ambiguous +warning: `Result` is ambiguous --> $DIR/issue-114682-4.rs:9:11 | LL | fn a() -> Result { @@ -17,7 +17,7 @@ note: `Result` could also refer to the type alias defined here | LL | pub use b::*; | ^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default error[E0107]: type alias takes 1 generic argument but 2 generic arguments were supplied --> $DIR/issue-114682-4.rs:9:11 @@ -33,11 +33,11 @@ note: type alias defined here, with 1 generic parameter: `T` LL | pub type Result = std::result::Result; | ^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0107`. Future incompatibility report: Future breakage diagnostic: -error: `Result` is ambiguous +warning: `Result` is ambiguous --> $DIR/issue-114682-4.rs:9:11 | LL | fn a() -> Result { @@ -56,5 +56,5 @@ note: `Result` could also refer to the type alias defined here | LL | pub use b::*; | ^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/issue-114682-5.rs b/tests/ui/imports/issue-114682-5.rs index be33960e40b8..1408a8105d75 100644 --- a/tests/ui/imports/issue-114682-5.rs +++ b/tests/ui/imports/issue-114682-5.rs @@ -9,7 +9,7 @@ extern crate issue_114682_5_extern_2; use issue_114682_5_extern_2::p::*; use issue_114682_5_extern_1::Url; //~^ ERROR `issue_114682_5_extern_1` is ambiguous -//~| ERROR `issue_114682_5_extern_1` is ambiguous +//~| WARN `issue_114682_5_extern_1` is ambiguous //~| ERROR unresolved import `issue_114682_5_extern_1::Url` //~| WARN this was previously accepted diff --git a/tests/ui/imports/issue-114682-5.stderr b/tests/ui/imports/issue-114682-5.stderr index 427a5b16765b..74b42e0990b7 100644 --- a/tests/ui/imports/issue-114682-5.stderr +++ b/tests/ui/imports/issue-114682-5.stderr @@ -26,7 +26,7 @@ LL | use issue_114682_5_extern_2::p::*; = help: consider adding an explicit import of `issue_114682_5_extern_1` to disambiguate = help: or use `crate::issue_114682_5_extern_1` to refer to this module unambiguously -error: `issue_114682_5_extern_1` is ambiguous +warning: `issue_114682_5_extern_1` is ambiguous --> $DIR/issue-114682-5.rs:10:5 | LL | use issue_114682_5_extern_1::Url; @@ -46,14 +46,14 @@ note: `issue_114682_5_extern_1` could also refer to the crate defined here LL | pub use crate::*; | ^^^^^ = help: use `::issue_114682_5_extern_1` to refer to this crate unambiguously - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors; 1 warning emitted Some errors have detailed explanations: E0432, E0659. For more information about an error, try `rustc --explain E0432`. Future incompatibility report: Future breakage diagnostic: -error: `issue_114682_5_extern_1` is ambiguous +warning: `issue_114682_5_extern_1` is ambiguous --> $DIR/issue-114682-5.rs:10:5 | LL | use issue_114682_5_extern_1::Url; @@ -73,5 +73,5 @@ note: `issue_114682_5_extern_1` could also refer to the crate defined here LL | pub use crate::*; | ^^^^^ = help: use `::issue_114682_5_extern_1` to refer to this crate unambiguously - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/issue-114682-6.rs b/tests/ui/imports/issue-114682-6.rs index 92173f4b8464..480caedb70a1 100644 --- a/tests/ui/imports/issue-114682-6.rs +++ b/tests/ui/imports/issue-114682-6.rs @@ -1,12 +1,12 @@ //@ aux-build: issue-114682-6-extern.rs // https://github.com/rust-lang/rust/pull/114682#issuecomment-1880755441 - +//@ check-pass extern crate issue_114682_6_extern; use issue_114682_6_extern::*; fn main() { - let log = 2; //~ ERROR `log` is ambiguous + let log = 2; //~ WARN `log` is ambiguous //~| WARN this was previously accepted let _ = log; } diff --git a/tests/ui/imports/issue-114682-6.stderr b/tests/ui/imports/issue-114682-6.stderr index 67ad25798c19..37f8f6c16ff2 100644 --- a/tests/ui/imports/issue-114682-6.stderr +++ b/tests/ui/imports/issue-114682-6.stderr @@ -1,4 +1,4 @@ -error: `log` is ambiguous +warning: `log` is ambiguous --> $DIR/issue-114682-6.rs:9:9 | LL | let log = 2; @@ -17,12 +17,12 @@ note: `log` could also refer to the function defined here | LL | pub use self::b::*; | ^^^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `log` is ambiguous +warning: `log` is ambiguous --> $DIR/issue-114682-6.rs:9:9 | LL | let log = 2; @@ -41,5 +41,5 @@ note: `log` could also refer to the function defined here | LL | pub use self::b::*; | ^^^^^^^ - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/overwrite-different-ambig-2.rs b/tests/ui/imports/overwrite-different-ambig-2.rs index 1b6d20e24d30..1d6416c00fdc 100644 --- a/tests/ui/imports/overwrite-different-ambig-2.rs +++ b/tests/ui/imports/overwrite-different-ambig-2.rs @@ -1,3 +1,5 @@ +//@ check-pass + mod m1 { mod inner { pub struct S {} @@ -19,6 +21,6 @@ use m1::*; use m2::*; fn main() { - let _: m1::S = S {}; //~ ERROR `S` is ambiguous + let _: m1::S = S {}; //~ WARN `S` is ambiguous //~| WARN this was previously accepted } diff --git a/tests/ui/imports/overwrite-different-ambig-2.stderr b/tests/ui/imports/overwrite-different-ambig-2.stderr index e75f552d119c..2d8446585717 100644 --- a/tests/ui/imports/overwrite-different-ambig-2.stderr +++ b/tests/ui/imports/overwrite-different-ambig-2.stderr @@ -1,5 +1,5 @@ -error: `S` is ambiguous - --> $DIR/overwrite-different-ambig-2.rs:22:20 +warning: `S` is ambiguous + --> $DIR/overwrite-different-ambig-2.rs:24:20 | LL | let _: m1::S = S {}; | ^ ambiguous name @@ -8,24 +8,24 @@ LL | let _: m1::S = S {}; = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `S` could refer to the struct imported here - --> $DIR/overwrite-different-ambig-2.rs:18:5 + --> $DIR/overwrite-different-ambig-2.rs:20:5 | LL | use m1::*; | ^^^^^ = help: consider adding an explicit import of `S` to disambiguate note: `S` could also refer to the struct imported here - --> $DIR/overwrite-different-ambig-2.rs:19:5 + --> $DIR/overwrite-different-ambig-2.rs:21:5 | LL | use m2::*; | ^^^^^ = help: consider adding an explicit import of `S` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `S` is ambiguous - --> $DIR/overwrite-different-ambig-2.rs:22:20 +warning: `S` is ambiguous + --> $DIR/overwrite-different-ambig-2.rs:24:20 | LL | let _: m1::S = S {}; | ^ ambiguous name @@ -34,16 +34,16 @@ LL | let _: m1::S = S {}; = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `S` could refer to the struct imported here - --> $DIR/overwrite-different-ambig-2.rs:18:5 + --> $DIR/overwrite-different-ambig-2.rs:20:5 | LL | use m1::*; | ^^^^^ = help: consider adding an explicit import of `S` to disambiguate note: `S` could also refer to the struct imported here - --> $DIR/overwrite-different-ambig-2.rs:19:5 + --> $DIR/overwrite-different-ambig-2.rs:21:5 | LL | use m2::*; | ^^^^^ = help: consider adding an explicit import of `S` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/unresolved-seg-after-ambiguous.rs b/tests/ui/imports/unresolved-seg-after-ambiguous.rs index 67366deabaaf..820f579ae3bb 100644 --- a/tests/ui/imports/unresolved-seg-after-ambiguous.rs +++ b/tests/ui/imports/unresolved-seg-after-ambiguous.rs @@ -18,7 +18,7 @@ mod a { use self::a::E::in_exist; //~^ ERROR: unresolved import `self::a::E` -//~| ERROR: `E` is ambiguous +//~| WARN: `E` is ambiguous //~| WARNING: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() {} diff --git a/tests/ui/imports/unresolved-seg-after-ambiguous.stderr b/tests/ui/imports/unresolved-seg-after-ambiguous.stderr index 67316462a27e..411cd1dbe5ef 100644 --- a/tests/ui/imports/unresolved-seg-after-ambiguous.stderr +++ b/tests/ui/imports/unresolved-seg-after-ambiguous.stderr @@ -4,7 +4,7 @@ error[E0432]: unresolved import `self::a::E` LL | use self::a::E::in_exist; | ^ `E` is a struct, not a module -error: `E` is ambiguous +warning: `E` is ambiguous --> $DIR/unresolved-seg-after-ambiguous.rs:19:14 | LL | use self::a::E::in_exist; @@ -25,13 +25,13 @@ note: `E` could also refer to the struct imported here LL | pub use self::d::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `E` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 2 previous errors +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0432`. Future incompatibility report: Future breakage diagnostic: -error: `E` is ambiguous +warning: `E` is ambiguous --> $DIR/unresolved-seg-after-ambiguous.rs:19:14 | LL | use self::a::E::in_exist; @@ -52,5 +52,5 @@ note: `E` could also refer to the struct imported here LL | pub use self::d::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `E` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default From ea9b062a8a71d16f8327ddf7d9ceac405a9a3bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 15 Jan 2026 11:15:26 +0100 Subject: [PATCH 2156/3801] Add GCC to build-manifest --- src/tools/build-manifest/src/main.rs | 7 +-- src/tools/build-manifest/src/versions.rs | 56 +++++++++++++++++++----- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 7c0c528bcc04..cd6efad01141 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -158,7 +158,7 @@ impl Builder { } fn add_packages_to(&mut self, manifest: &mut Manifest) { - for pkg in PkgType::all() { + for pkg in &PkgType::all() { self.package(pkg, &mut manifest.pkg); } } @@ -227,7 +227,7 @@ impl Builder { }; for pkg in PkgType::all() { if pkg.is_preview() { - rename(pkg.tarball_component_name(), &pkg.manifest_component_name()); + rename(&pkg.tarball_component_name(), &pkg.manifest_component_name()); } } } @@ -263,7 +263,7 @@ impl Builder { let host_component = |pkg: &_| Component::from_pkg(pkg, host); - for pkg in PkgType::all() { + for pkg in &PkgType::all() { match pkg { // rustc/rust-std/cargo/docs are all required PkgType::Rustc | PkgType::Cargo | PkgType::HtmlDocs => { @@ -303,6 +303,7 @@ impl Builder { | PkgType::JsonDocs | PkgType::RustcCodegenCranelift | PkgType::RustcCodegenGcc + | PkgType::Gcc { .. } | PkgType::LlvmBitcodeLinker => { extensions.push(host_component(pkg)); } diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 1e55d1d467e6..b53f6c5edc5d 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -11,29 +11,54 @@ use xz2::read::XzDecoder; const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu"; macro_rules! pkg_type { - ( $($variant:ident = $component:literal $(; preview = true $(@$is_preview:tt)? )? ),+ $(,)? ) => { + ( $($variant:ident = $component:literal $(; preview = true $(@$is_preview:tt)? )? $(; suffixes = [$($suffixes:literal),+] $(@$is_suffixed:tt)? )? ),+ $(,)? ) => { #[derive(Debug, Hash, Eq, PartialEq, Clone)] pub(crate) enum PkgType { - $($variant,)+ + $($variant $( $($is_suffixed)? { suffix: &'static str })?,)+ } impl PkgType { pub(crate) fn is_preview(&self) -> bool { match self { - $( $( $($is_preview)? PkgType::$variant => true, )? )+ - _ => false, + $( PkgType::$variant $($($is_suffixed)? { .. })? => false $( $($is_preview)? || true)?, )+ } } - /// First part of the tarball name. - pub(crate) fn tarball_component_name(&self) -> &str { + /// First part of the tarball name. May include a suffix, if the package has one. + pub(crate) fn tarball_component_name(&self) -> String { match self { - $( PkgType::$variant => $component,)+ + $( PkgType::$variant $($($is_suffixed)? { suffix })? => { + #[allow(unused_mut)] + let mut name = $component.to_owned(); + $($($is_suffixed)? + name.push('-'); + name.push_str(suffix); + )? + name + },)+ } } - pub(crate) fn all() -> &'static [PkgType] { - &[ $(PkgType::$variant),+ ] + pub(crate) fn all() -> Vec { + let mut packages = vec![]; + $( + // Push the single variant + packages.push(PkgType::$variant $($($is_suffixed)? { suffix: "" })?); + // Macro hell, we have to remove the fake empty suffix if we actually have + // suffixes + $( + $($is_suffixed)? + packages.pop(); + )? + // And now add the suffixes, if any + $( + $($is_suffixed)? + $( + packages.push(PkgType::$variant { suffix: $suffixes }); + )+ + )? + )+ + packages } } } @@ -60,6 +85,9 @@ pkg_type! { RustcCodegenCranelift = "rustc-codegen-cranelift"; preview = true, LlvmBitcodeLinker = "llvm-bitcode-linker"; preview = true, RustcCodegenGcc = "rustc-codegen-gcc"; preview = true, + Gcc = "gcc"; preview = true; suffixes = [ + "x86_64-unknown-linux-gnu" + ], } impl PkgType { @@ -68,7 +96,7 @@ impl PkgType { if self.is_preview() { format!("{}-preview", self.tarball_component_name()) } else { - self.tarball_component_name().to_string() + self.tarball_component_name() } } @@ -84,6 +112,7 @@ impl PkgType { PkgType::Miri => false, PkgType::RustcCodegenCranelift => false, PkgType::RustcCodegenGcc => false, + PkgType::Gcc { suffix: _ } => false, PkgType::Rust => true, PkgType::RustStd => true, @@ -114,6 +143,13 @@ impl PkgType { Cargo => HOSTS, RustcCodegenCranelift => HOSTS, RustcCodegenGcc => HOSTS, + // Gcc is "special", because we need a separate libgccjit.so for each + // (host, target) compilation pair. So it's even more special than stdlib, which has a + // separate component per target. This component thus hardcodes its compilation + // target in its name, and we thus ship it for HOSTS only. So we essentially have + // gcc-T1, gcc-T2, a separate *component/package* per each compilation target. + // So on host T1, if you want to compile for T2, you would install gcc-T2. + Gcc { suffix: _ } => HOSTS, RustMingw => MINGW, RustStd => TARGETS, HtmlDocs => HOSTS, From 55abc484d7243eea77fd40247b531bcb0796e697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 15 Jan 2026 11:29:07 +0100 Subject: [PATCH 2157/3801] Extend build-manifest local test guide Fill in more blanks about how to test build-manifest changes with Rustup. --- src/tools/build-manifest/README.md | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md index bc1992ef80cc..f88949f48d8b 100644 --- a/src/tools/build-manifest/README.md +++ b/src/tools/build-manifest/README.md @@ -18,7 +18,7 @@ This gets called by `promote-release` build/dist/channel-rust-nightly.toml.sha256 +``` + +And start a HTTP server from the `build` directory: +```sh +cd build +python3 -m http.server 8000 +``` + +After you do all that, you can then install the locally generated components with rustup: +``` +rustup uninstall nightly +RUSTUP_DIST_SERVER=http://localhost:8000 rustup toolchain install nightly --profile minimal +RUSTUP_DIST_SERVER=http://localhost:8000 rustup +nightly component add +``` + +Note that generally it will not work to combine components built locally and those built from CI (nightly). Ideally, if you want to ship new rustup components, first dist them in nightly, and then test everything from nightly here after it's available on CI. From 316627ee24c2214037631c227dc073bde46001e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 16 Dec 2025 21:19:20 +0100 Subject: [PATCH 2158/3801] Refactor `Enzyme` step --- src/bootstrap/src/core/build_steps/compile.rs | 22 +++------ src/bootstrap/src/core/build_steps/llvm.rs | 49 +++++++++++++++---- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 11f2a28bb935..651ff03a8690 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2292,23 +2292,13 @@ impl Step for Assemble { builder.compiler(target_compiler.stage - 1, builder.config.host_target); // Build enzyme - if builder.config.llvm_enzyme && !builder.config.dry_run() { + if builder.config.llvm_enzyme { debug!("`llvm_enzyme` requested"); - let enzyme_install = builder.ensure(llvm::Enzyme { target: build_compiler.host }); - if let Some(llvm_config) = builder.llvm_config(builder.config.host_target) { - let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config); - let lib_ext = std::env::consts::DLL_EXTENSION; - let libenzyme = format!("libEnzyme-{llvm_version_major}"); - let src_lib = - enzyme_install.join("build/Enzyme").join(&libenzyme).with_extension(lib_ext); - let libdir = builder.sysroot_target_libdir(build_compiler, build_compiler.host); - let target_libdir = - builder.sysroot_target_libdir(target_compiler, target_compiler.host); - let dst_lib = libdir.join(&libenzyme).with_extension(lib_ext); - let target_dst_lib = target_libdir.join(&libenzyme).with_extension(lib_ext); - builder.copy_link(&src_lib, &dst_lib, FileType::NativeLibrary); - builder.copy_link(&src_lib, &target_dst_lib, FileType::NativeLibrary); - } + let enzyme = builder.ensure(llvm::Enzyme { target: build_compiler.host }); + let target_libdir = + builder.sysroot_target_libdir(target_compiler, target_compiler.host); + let target_dst_lib = target_libdir.join(enzyme.enzyme_filename()); + builder.copy_link(&enzyme.enzyme_path(), &target_dst_lib, FileType::NativeLibrary); } if builder.config.llvm_offload && !builder.config.dry_run() { diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index c3935d9810e9..f6a763b94075 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -17,6 +17,7 @@ use std::{env, fs}; use build_helper::exit; use build_helper::git::PathFreshness; +use crate::core::build_steps::llvm; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step, StepMetadata}; use crate::core::config::{Config, TargetSelection}; use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash}; @@ -1077,13 +1078,28 @@ impl Step for OmpOffload { } } +#[derive(Clone)] +pub struct BuiltEnzyme { + /// Path to the libEnzyme dylib. + enzyme: PathBuf, +} + +impl BuiltEnzyme { + pub fn enzyme_path(&self) -> PathBuf { + self.enzyme.clone() + } + pub fn enzyme_filename(&self) -> String { + self.enzyme.file_name().unwrap().to_str().unwrap().to_owned() + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Enzyme { pub target: TargetSelection, } impl Step for Enzyme { - type Output = PathBuf; + type Output = BuiltEnzyme; const IS_HOST: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -1095,17 +1111,17 @@ impl Step for Enzyme { } /// Compile Enzyme for `target`. - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> Self::Output { builder.require_submodule( "src/tools/enzyme", Some("The Enzyme sources are required for autodiff."), ); - if builder.config.dry_run() { - let out_dir = builder.enzyme_out(self.target); - return out_dir; - } let target = self.target; + if builder.config.dry_run() { + return BuiltEnzyme { enzyme: builder.config.tempdir().join("enzyme-dryrun") }; + } + let LlvmResult { host_llvm_config, llvm_cmake_dir } = builder.ensure(Llvm { target }); static STAMP_HASH_MEMO: OnceLock = OnceLock::new(); @@ -1120,6 +1136,12 @@ impl Step for Enzyme { let out_dir = builder.enzyme_out(target); let stamp = BuildStamp::new(&out_dir).with_prefix("enzyme").add_stamp(smart_stamp_hash); + let llvm_version_major = llvm::get_llvm_version_major(builder, &host_llvm_config); + let lib_ext = std::env::consts::DLL_EXTENSION; + let libenzyme = format!("libEnzyme-{llvm_version_major}"); + let build_dir = out_dir.join("lib"); + let dylib = build_dir.join(&libenzyme).with_extension(lib_ext); + trace!("checking build stamp to see if we need to rebuild enzyme artifacts"); if stamp.is_up_to_date() { trace!(?out_dir, "enzyme build artifacts are up to date"); @@ -1133,7 +1155,7 @@ impl Step for Enzyme { stamp.path().display() )); } - return out_dir; + return BuiltEnzyme { enzyme: dylib }; } if !builder.config.dry_run() && !llvm_cmake_dir.is_dir() { @@ -1149,7 +1171,6 @@ impl Step for Enzyme { let _time = helpers::timeit(builder); t!(fs::create_dir_all(&out_dir)); - builder.config.update_submodule("src/tools/enzyme"); let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/")); // Enzyme devs maintain upstream compatibility, but only fix deprecations when they are about // to turn into a hard error. As such, Enzyme generates various warnings which could make it @@ -1178,8 +1199,18 @@ impl Step for Enzyme { cfg.build(); + // At this point, `out_dir` should contain the built libEnzyme-. + // file. + if !dylib.exists() { + eprintln!( + "`{libenzyme}` not found in `{}`. Either the build has failed or Enzyme was built with a wrong version of LLVM", + build_dir.display() + ); + exit!(1); + } + t!(stamp.write()); - out_dir + BuiltEnzyme { enzyme: dylib } } } From 85e01e3c4e328a63b39ea1189de03b79cc02b0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 16 Dec 2025 21:55:56 +0100 Subject: [PATCH 2159/3801] Add dist step for `Enzyme` --- src/bootstrap/src/core/build_steps/dist.rs | 49 ++++++++++++++++++++++ src/bootstrap/src/core/builder/mod.rs | 1 + src/bootstrap/src/utils/tarball.rs | 3 ++ 3 files changed, 53 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index cfcb144e0993..8ba05a7fa3a7 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2717,6 +2717,55 @@ impl Step for LlvmBitcodeLinker { } } +/// Distributes the `enzyme` library so that it can be used by a compiler whose host +/// is `target`. +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct Enzyme { + /// Enzyme will by usable by rustc on this host. + pub target: TargetSelection, +} + +impl Step for Enzyme { + type Output = Option; + const IS_HOST: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("enzyme") + } + + fn is_default_step(builder: &Builder<'_>) -> bool { + builder.config.llvm_enzyme + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Enzyme { target: run.target }); + } + + fn run(self, builder: &Builder<'_>) -> Option { + // This prevents Enzyme from being built for "dist" + // or "install" on the stable/beta channels. It is not yet stable and + // should not be included. + if !builder.build.unstable_features() { + return None; + } + + let target = self.target; + + let enzyme = builder.ensure(llvm::Enzyme { target }); + + let target_libdir = format!("lib/rustlib/{}/lib", target.triple); + + // Prepare the image directory + let mut tarball = Tarball::new(builder, "enzyme", &target.triple); + tarball.set_overlay(OverlayKind::Enzyme); + tarball.is_preview(true); + + tarball.add_file(enzyme.enzyme_path(), target_libdir, FileType::NativeLibrary); + + Some(tarball.generate()) + } +} + /// Tarball intended for internal consumption to ease rustc/std development. /// /// Should not be considered stable by end users. diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index f63b8e044550..14cae2d0efc4 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -980,6 +980,7 @@ impl<'a> Builder<'a> { dist::LlvmTools, dist::LlvmBitcodeLinker, dist::RustDev, + dist::Enzyme, dist::Bootstrap, dist::Extended, // It seems that PlainSourceTarball somehow changes how some of the tools diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index cd6a03c84870..17d75e83daea 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -28,6 +28,7 @@ pub(crate) enum OverlayKind { RustcCodegenGcc, Gcc, LlvmBitcodeLinker, + Enzyme, } impl OverlayKind { @@ -37,6 +38,7 @@ impl OverlayKind { OverlayKind::Llvm => { &["src/llvm-project/llvm/LICENSE.TXT", "src/llvm-project/llvm/README.txt"] } + OverlayKind::Enzyme => &["src/tools/enzyme/LICENSE", "src/tools/enzyme/Readme.md"], OverlayKind::Cargo => &[ "src/tools/cargo/README.md", "src/tools/cargo/LICENSE-MIT", @@ -111,6 +113,7 @@ impl OverlayKind { OverlayKind::RustcCodegenGcc => builder.rust_version(), OverlayKind::LlvmBitcodeLinker => builder.rust_version(), OverlayKind::Gcc => builder.rust_version(), + OverlayKind::Enzyme => builder.rust_version(), } } } From d85965634996e60e80440b4fef7415b6379d2487 Mon Sep 17 00:00:00 2001 From: lummax Date: Thu, 15 Jan 2026 12:54:01 +0100 Subject: [PATCH 2160/3801] fix: lookup flycheck by ID instead of vector index After a recent introduction of per-package flycheck for JSON projects, the code assumed that `world.flycheck` indices matched `world.workspaces` indices. However, not all workspaces have flycheck enabled (e.g., JSON projects without a flycheck template configured), so the flycheck vector can be shorter than the workspaces vector. This caused an index-out-of-bounds panic when saving a file in a JSON project without flycheck configured: thread 'Worker' panicked at notification.rs: index out of bounds: the len is 0 but the index is 0 Fix by looking up the flycheck handle by its ID (which is the workspace index set during spawn) rather than using the workspace index directly as a vector index. --- .../src/handlers/notification.rs | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs index d95601043330..6cc40677fb51 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs @@ -387,14 +387,21 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { } => false, }); if let Some(idx) = package_workspace_idx { - let workspace_deps = - world.all_workspace_dependencies_for_package(&package); - world.flycheck[idx].restart_for_package( - package, - target, - workspace_deps, - saved_file.clone(), - ); + // flycheck handles are indexed by their ID (which is the workspace index), + // but not all workspaces have flycheck enabled (e.g., JSON projects without + // a flycheck template). Find the flycheck handle by its ID. + if let Some(flycheck) = + world.flycheck.iter().find(|fc| fc.id() == idx) + { + let workspace_deps = + world.all_workspace_dependencies_for_package(&package); + flycheck.restart_for_package( + package, + target, + workspace_deps, + saved_file.clone(), + ); + } } } } From cd7d40d97507d75b4d0341e19a24edfaf654c6c5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 15 Jan 2026 15:06:29 +0100 Subject: [PATCH 2161/3801] Update `rustc_attr_parsing::SharedContext::target` type from `Option` to `Target` --- compiler/rustc_attr_parsing/src/attributes/cfg.rs | 3 ++- compiler/rustc_attr_parsing/src/attributes/cfg_select.rs | 4 +++- compiler/rustc_attr_parsing/src/attributes/doc.rs | 4 ++-- compiler/rustc_attr_parsing/src/context.rs | 2 +- compiler/rustc_attr_parsing/src/interface.rs | 9 ++++++--- compiler/rustc_builtin_macros/src/cfg.rs | 4 +++- compiler/rustc_expand/src/config.rs | 3 +++ compiler/rustc_expand/src/expand.rs | 2 ++ 8 files changed, 22 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index ccf0a394afd0..3e430cf59485 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -9,7 +9,7 @@ use rustc_feature::{ }; use rustc_hir::attrs::CfgEntry; use rustc_hir::lints::AttributeLintKind; -use rustc_hir::{AttrPath, RustcVersion}; +use rustc_hir::{AttrPath, RustcVersion, Target}; use rustc_parse::parser::{ForceCollect, Parser}; use rustc_parse::{exp, parse_in}; use rustc_session::Session; @@ -374,6 +374,7 @@ fn parse_cfg_attr_internal<'a>( ParsedDescription::Attribute, pred_span, CRATE_NODE_ID, + Target::Crate, features, ShouldEmit::ErrorsAndLints, &meta, diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs index 24b989e22a2b..e80084021a84 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs @@ -2,8 +2,8 @@ use rustc_ast::token::Token; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{AttrStyle, NodeId, token}; use rustc_feature::{AttributeTemplate, Features}; -use rustc_hir::AttrPath; use rustc_hir::attrs::CfgEntry; +use rustc_hir::{AttrPath, Target}; use rustc_parse::exp; use rustc_parse::parser::Parser; use rustc_session::Session; @@ -91,6 +91,8 @@ pub fn parse_cfg_select( ParsedDescription::Macro, cfg_span, lint_node_id, + // Doesn't matter what the target actually is here. + Target::Crate, features, ShouldEmit::ErrorsAndLints, &meta, diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 6cc4ac35eadb..99825d93216f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -50,7 +50,7 @@ fn check_attr_not_crate_level( span: Span, attr_name: Symbol, ) -> bool { - if cx.shared.target.is_some_and(|target| target == Target::Crate) { + if cx.shared.target == Target::Crate { cx.emit_err(DocAttrNotCrateLevel { span, attr_name }); return false; } @@ -59,7 +59,7 @@ fn check_attr_not_crate_level( /// Checks that an attribute is used at the crate level. Returns `true` if valid. fn check_attr_crate_level(cx: &mut AcceptContext<'_, '_, S>, span: Span) -> bool { - if cx.shared.target.is_some_and(|target| target != Target::Crate) { + if cx.shared.target != Target::Crate { cx.emit_lint( rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, AttributeLintKind::AttrCrateLevelOnly, diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8305d027d13c..f885151330a3 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -665,7 +665,7 @@ pub struct SharedContext<'p, 'sess, S: Stage> { pub(crate) target_span: Span, /// The id ([`NodeId`] if `S` is `Early`, [`HirId`] if `S` is `Late`) of the syntactical component this attribute was applied to pub(crate) target_id: S::Id, - pub(crate) target: Option, + pub(crate) target: rustc_hir::Target, pub(crate) emit_lint: &'p mut dyn FnMut(AttributeLint), } diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index b7137c60e63a..8f2c36fa8c9e 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -135,6 +135,7 @@ impl<'sess> AttributeParser<'sess, Early> { attr: &ast::Attribute, target_span: Span, target_node_id: NodeId, + target: Target, features: Option<&'sess Features>, emit_errors: ShouldEmit, parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser) -> Option, @@ -163,6 +164,7 @@ impl<'sess> AttributeParser<'sess, Early> { ParsedDescription::Attribute, target_span, target_node_id, + target, features, emit_errors, &args, @@ -183,6 +185,7 @@ impl<'sess> AttributeParser<'sess, Early> { parsed_description: ParsedDescription, target_span: Span, target_node_id: NodeId, + target: Target, features: Option<&'sess Features>, emit_errors: ShouldEmit, args: &I, @@ -218,7 +221,7 @@ impl<'sess> AttributeParser<'sess, Early> { cx: &mut parser, target_span, target_id: target_node_id, - target: None, + target, emit_lint: &mut emit_lint, }, attr_span, @@ -379,7 +382,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { cx: self, target_span, target_id, - target: Some(target), + target, emit_lint: &mut emit_lint, }, attr_span, @@ -431,7 +434,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { cx: self, target_span, target_id, - target: Some(target), + target, emit_lint: &mut emit_lint, }, all_attrs: &attr_paths, diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 557daa94b98e..be1ce5a06d5e 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -10,8 +10,8 @@ use rustc_attr_parsing::{ AttributeParser, CFG_TEMPLATE, ParsedDescription, ShouldEmit, parse_cfg_entry, }; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; -use rustc_hir::AttrPath; use rustc_hir::attrs::CfgEntry; +use rustc_hir::{AttrPath, Target}; use rustc_parse::exp; use rustc_span::{ErrorGuaranteed, Span, sym}; @@ -52,6 +52,8 @@ fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result StripUnconfigured<'a> { attr, attr.span, self.lint_node_id, + // Doesn't matter what the target actually is here. + Target::Crate, self.features, emit_errors, parse_cfg, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index c130d9f59940..fabe1f5a8c5d 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2218,6 +2218,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { &attr, attr.span, self.cfg().lint_node_id, + // Target doesn't matter for `cfg` parsing. + Target::Crate, self.cfg().features, ShouldEmit::ErrorsAndLints, parse_cfg, From 820579243f5cd9a27c3831d6c335f138a4567c41 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 15 Jan 2026 15:39:00 +0100 Subject: [PATCH 2162/3801] Remove `rustc_attr_parsing::SharedContext::target_id` field --- compiler/rustc_ast_lowering/src/lib.rs | 12 +++-- compiler/rustc_attr_parsing/src/context.rs | 11 +++-- compiler/rustc_attr_parsing/src/interface.rs | 47 +++++++------------- compiler/rustc_attr_parsing/src/safety.rs | 16 +++---- compiler/rustc_resolve/src/def_collector.rs | 3 +- 5 files changed, 36 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 350fa04ab3bd..51d1fd20cec6 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -51,7 +51,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId}; use rustc_hir::definitions::{DefPathData, DisambiguatorState}; -use rustc_hir::lints::DelayedLint; +use rustc_hir::lints::{AttributeLint, DelayedLint}; use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr, @@ -1022,12 +1022,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.attribute_parser.parse_attribute_list( attrs, target_span, - target_hir_id, target, OmitDoc::Lower, |s| l.lower(s), - |l| { - self.delayed_lints.push(DelayedLint::AttributeParsing(l)); + |lint_id, span, kind| { + self.delayed_lints.push(DelayedLint::AttributeParsing(AttributeLint { + lint_id, + id: target_hir_id, + span, + kind, + })); }, ) } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index f885151330a3..d6a3ddf4d300 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -8,7 +8,7 @@ use rustc_ast::{AttrStyle, MetaItemLit, NodeId}; use rustc_errors::{Diag, Diagnostic, Level}; use rustc_feature::{AttrSuggestionStyle, AttributeTemplate}; use rustc_hir::attrs::AttributeKind; -use rustc_hir::lints::{AttributeLint, AttributeLintKind}; +use rustc_hir::lints::AttributeLintKind; use rustc_hir::{AttrPath, HirId}; use rustc_session::Session; use rustc_session::lint::{Lint, LintId}; @@ -417,8 +417,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { ) { return; } - let id = self.target_id; - (self.emit_lint)(AttributeLint { lint_id: LintId::of(lint), id, span, kind }); + (self.emit_lint)(LintId::of(lint), span, kind); } pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) { @@ -663,11 +662,11 @@ pub struct SharedContext<'p, 'sess, S: Stage> { pub(crate) cx: &'p mut AttributeParser<'sess, S>, /// The span of the syntactical component this attribute was applied to pub(crate) target_span: Span, - /// The id ([`NodeId`] if `S` is `Early`, [`HirId`] if `S` is `Late`) of the syntactical component this attribute was applied to - pub(crate) target_id: S::Id, pub(crate) target: rustc_hir::Target, - pub(crate) emit_lint: &'p mut dyn FnMut(AttributeLint), + /// The second argument of the closure is a [`NodeId`] if `S` is `Early` and a [`HirId`] if `S` + /// is `Late` and is the ID of the syntactical component this attribute was applied to. + pub(crate) emit_lint: &'p mut dyn FnMut(LintId, Span, AttributeLintKind), } /// Context given to every attribute parser during finalization. diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 8f2c36fa8c9e..c6be18321b5e 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -6,10 +6,10 @@ use rustc_ast::{AttrItemKind, AttrStyle, NodeId, Safety}; use rustc_errors::DiagCtxtHandle; use rustc_feature::{AttributeTemplate, Features}; use rustc_hir::attrs::AttributeKind; -use rustc_hir::lints::AttributeLint; +use rustc_hir::lints::AttributeLintKind; use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId, Target}; use rustc_session::Session; -use rustc_session::lint::BuiltinLintDiag; +use rustc_session::lint::{BuiltinLintDiag, LintId}; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage}; @@ -113,16 +113,15 @@ impl<'sess> AttributeParser<'sess, Early> { p.parse_attribute_list( attrs, target_span, - target_node_id, target, OmitDoc::Skip, std::convert::identity, - |lint| { + |lint_id, span, kind| { sess.psess.buffer_lint( - lint.lint_id.lint, - lint.span, - lint.id, - BuiltinLintDiag::AttributeLint(lint.kind), + lint_id.lint, + span, + target_node_id, + BuiltinLintDiag::AttributeLint(kind), ) }, ) @@ -199,28 +198,21 @@ impl<'sess> AttributeParser<'sess, Early> { sess, stage: Early { emit_errors }, }; - let mut emit_lint = |lint: AttributeLint| { + let mut emit_lint = |lint_id: LintId, span: Span, kind: AttributeLintKind| { sess.psess.buffer_lint( - lint.lint_id.lint, - lint.span, - lint.id, - BuiltinLintDiag::AttributeLint(lint.kind), + lint_id.lint, + span, + target_node_id, + BuiltinLintDiag::AttributeLint(kind), ) }; if let Some(safety) = attr_safety { - parser.check_attribute_safety( - &attr_path, - inner_span, - safety, - &mut emit_lint, - target_node_id, - ) + parser.check_attribute_safety(&attr_path, inner_span, safety, &mut emit_lint) } let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext { shared: SharedContext { cx: &mut parser, target_span, - target_id: target_node_id, target, emit_lint: &mut emit_lint, }, @@ -269,11 +261,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { &mut self, attrs: &[ast::Attribute], target_span: Span, - target_id: S::Id, target: Target, omit_doc: OmitDoc, lower_span: impl Copy + Fn(Span) -> Span, - mut emit_lint: impl FnMut(AttributeLint), + mut emit_lint: impl FnMut(LintId, Span, AttributeLintKind), ) -> Vec { let mut attributes = Vec::new(); let mut attr_paths: Vec> = Vec::new(); @@ -329,7 +320,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { lower_span(n.item.span()), n.item.unsafety, &mut emit_lint, - target_id, ); let parts = @@ -381,7 +371,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { shared: SharedContext { cx: self, target_span, - target_id, target, emit_lint: &mut emit_lint, }, @@ -430,13 +419,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { early_parsed_state.finalize_early_parsed_attributes(&mut attributes); for f in &S::parsers().finalizers { if let Some(attr) = f(&mut FinalizeContext { - shared: SharedContext { - cx: self, - target_span, - target_id, - target, - emit_lint: &mut emit_lint, - }, + shared: SharedContext { cx: self, target_span, target, emit_lint: &mut emit_lint }, all_attrs: &attr_paths, }) { attributes.push(Attribute::Parsed(attr)); diff --git a/compiler/rustc_attr_parsing/src/safety.rs b/compiler/rustc_attr_parsing/src/safety.rs index 9fca57f88025..4cc703c5d0cc 100644 --- a/compiler/rustc_attr_parsing/src/safety.rs +++ b/compiler/rustc_attr_parsing/src/safety.rs @@ -1,7 +1,7 @@ use rustc_ast::Safety; use rustc_feature::{AttributeSafety, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir::AttrPath; -use rustc_hir::lints::{AttributeLint, AttributeLintKind}; +use rustc_hir::lints::AttributeLintKind; use rustc_session::lint::LintId; use rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE; use rustc_span::Span; @@ -15,8 +15,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attr_path: &AttrPath, attr_span: Span, attr_safety: Safety, - emit_lint: &mut impl FnMut(AttributeLint), - target_id: S::Id, + emit_lint: &mut impl FnMut(LintId, Span, AttributeLintKind), ) { if matches!(self.stage.should_emit(), ShouldEmit::Nothing) { return; @@ -82,16 +81,15 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { }, ); } else { - emit_lint(AttributeLint { - lint_id: LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE), - id: target_id, - span: path_span, - kind: AttributeLintKind::UnsafeAttrOutsideUnsafe { + emit_lint( + LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE), + path_span, + AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span: path_span, sugg_spans: not_from_proc_macro .then(|| (diag_span.shrink_to_lo(), diag_span.shrink_to_hi())), }, - }) + ) } } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index ea5640ecc1fa..8f1a43c090b1 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -148,11 +148,10 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { let attrs = parser.parse_attribute_list( &i.attrs, i.span, - i.id, Target::MacroDef, OmitDoc::Skip, std::convert::identity, - |_l| { + |_lint_id, _span, _kind| { // FIXME(jdonszelmann): emit lints here properly // NOTE that before new attribute parsing, they didn't happen either // but it would be nice if we could change that. From 6cd43592a8dbbe8f4c888eca3a4994710b57d978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Thu, 15 Jan 2026 15:46:39 +0100 Subject: [PATCH 2163/3801] Stabilise 'EULER_GAMMA' and 'GOLDEN_RATIO' constants; --- library/core/src/num/f128.rs | 8 ++++---- library/core/src/num/f16.rs | 6 ++---- library/core/src/num/f32.rs | 8 ++++---- library/core/src/num/f64.rs | 8 ++++---- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index bf99fee4fc78..65afdd2969b8 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -34,13 +34,13 @@ pub mod consts { /// The golden ratio (φ) #[unstable(feature = "f128", issue = "116909")] - // Also, #[unstable(feature = "more_float_constants", issue = "146939")] - pub const PHI: f128 = 1.61803398874989484820458683436563811772030917980576286213545_f128; + pub const GOLDEN_RATIO: f128 = + 1.61803398874989484820458683436563811772030917980576286213545_f128; /// The Euler-Mascheroni constant (γ) #[unstable(feature = "f128", issue = "116909")] - // Also, #[unstable(feature = "more_float_constants", issue = "146939")] - pub const EGAMMA: f128 = 0.577215664901532860606512090082402431042159335939923598805767_f128; + pub const EULER_GAMMA: f128 = + 0.577215664901532860606512090082402431042159335939923598805767_f128; /// π/2 #[unstable(feature = "f128", issue = "116909")] diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index f39ee22871d5..bcf0f3fc45c2 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -36,13 +36,11 @@ pub mod consts { /// The golden ratio (φ) #[unstable(feature = "f16", issue = "116909")] - // Also, #[unstable(feature = "more_float_constants", issue = "146939")] - pub const PHI: f16 = 1.618033988749894848204586834365638118_f16; + pub const GOLDEN_RATIO: f16 = 1.618033988749894848204586834365638118_f16; /// The Euler-Mascheroni constant (γ) #[unstable(feature = "f16", issue = "116909")] - // Also, #[unstable(feature = "more_float_constants", issue = "146939")] - pub const EGAMMA: f16 = 0.577215664901532860606512090082402431_f16; + pub const EULER_GAMMA: f16 = 0.577215664901532860606512090082402431_f16; /// π/2 #[unstable(feature = "f16", issue = "116909")] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 6fe4285374b2..f7f16b57a526 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -292,12 +292,12 @@ pub mod consts { pub const TAU: f32 = 6.28318530717958647692528676655900577_f32; /// The golden ratio (φ) - #[unstable(feature = "more_float_constants", issue = "146939")] - pub const PHI: f32 = 1.618033988749894848204586834365638118_f32; + #[stable(feature = "euler_gamma_golden_ratio", since = "CURRENT_RUSTC_VERSION")] + pub const GOLDEN_RATIO: f32 = 1.618033988749894848204586834365638118_f32; /// The Euler-Mascheroni constant (γ) - #[unstable(feature = "more_float_constants", issue = "146939")] - pub const EGAMMA: f32 = 0.577215664901532860606512090082402431_f32; + #[stable(feature = "euler_gamma_golden_ratio", since = "CURRENT_RUSTC_VERSION")] + pub const EULER_GAMMA: f32 = 0.577215664901532860606512090082402431_f32; /// π/2 #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index d0aca152415e..f021c88f2235 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -292,12 +292,12 @@ pub mod consts { pub const TAU: f64 = 6.28318530717958647692528676655900577_f64; /// The golden ratio (φ) - #[unstable(feature = "more_float_constants", issue = "146939")] - pub const PHI: f64 = 1.618033988749894848204586834365638118_f64; + #[stable(feature = "euler_gamma_golden_ratio", since = "CURRENT_RUSTC_VERSION")] + pub const GOLDEN_RATIO: f64 = 1.618033988749894848204586834365638118_f64; /// The Euler-Mascheroni constant (γ) - #[unstable(feature = "more_float_constants", issue = "146939")] - pub const EGAMMA: f64 = 0.577215664901532860606512090082402431_f64; + #[stable(feature = "euler_gamma_golden_ratio", since = "CURRENT_RUSTC_VERSION")] + pub const EULER_GAMMA: f64 = 0.577215664901532860606512090082402431_f64; /// π/2 #[stable(feature = "rust1", since = "1.0.0")] From 08362d3e51a2da3eb10fa7a918c5739249873cd8 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Fri, 16 Jan 2026 00:35:10 +0900 Subject: [PATCH 2164/3801] fix: Do not delay E0107 when there exists an assoc ty with the same name --- .../src/hir_ty_lowering/generics.rs | 22 ++++++++++-- ...me-name-with-lacking-generic-arg-148121.rs | 17 +++++++++ ...ame-with-lacking-generic-arg-148121.stderr | 35 +++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs create mode 100644 tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index f5a64ede398e..0a2946323c7b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -9,6 +9,7 @@ use rustc_middle::ty::{ }; use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS; use rustc_span::kw; +use rustc_trait_selection::traits; use smallvec::SmallVec; use tracing::{debug, instrument}; @@ -535,9 +536,26 @@ pub(crate) fn check_generic_arg_count( .map(|param| param.name) .collect(); if constraint_names == param_names { + let has_assoc_ty_with_same_name = + if let DefKind::Trait = cx.tcx().def_kind(def_id) { + gen_args.constraints.iter().any(|constraint| { + traits::supertrait_def_ids(cx.tcx(), def_id).any(|trait_did| { + cx.probe_trait_that_defines_assoc_item( + trait_did, + ty::AssocTag::Type, + constraint.ident, + ) + }) + }) + } else { + false + }; // We set this to true and delay emitting `WrongNumberOfGenericArgs` - // to provide a succinct error for cases like issue #113073 - all_params_are_binded = true; + // to provide a succinct error for cases like issue #113073, + // but only if when we don't have any assoc type with the same name with a + // generic arg. Otherwise it will cause an ICE due to a delayed error because we + // don't have any error other than `WrongNumberOfGenericArgs`. + all_params_are_binded = !has_assoc_ty_with_same_name; }; } diff --git a/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs new file mode 100644 index 000000000000..f1dffc0ff6b4 --- /dev/null +++ b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs @@ -0,0 +1,17 @@ +// A regression test for https://github.com/rust-lang/rust/issues/148121 + +pub trait Super { + type X; +} + +pub trait Zelf: Super {} + +pub trait A {} + +impl A for dyn Super {} +//~^ ERROR: trait takes 1 generic argument but 0 generic arguments were supplied + +impl A for dyn Zelf {} +//~^ ERROR: trait takes 1 generic argument but 0 generic arguments were supplied + +fn main() {} diff --git a/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr new file mode 100644 index 000000000000..5a7969193b55 --- /dev/null +++ b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr @@ -0,0 +1,35 @@ +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied + --> $DIR/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs:11:16 + | +LL | impl A for dyn Super {} + | ^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `X` + --> $DIR/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs:3:11 + | +LL | pub trait Super { + | ^^^^^ - +help: add missing generic argument + | +LL | impl A for dyn Super {} + | ++ + +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied + --> $DIR/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs:14:16 + | +LL | impl A for dyn Zelf {} + | ^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `X` + --> $DIR/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs:7:11 + | +LL | pub trait Zelf: Super {} + | ^^^^ - +help: add missing generic argument + | +LL | impl A for dyn Zelf {} + | ++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. From 8536979cdb67143bc09398150cf7d2f023992488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Thu, 15 Jan 2026 16:50:20 +0100 Subject: [PATCH 2165/3801] Move some match edge case tests While these test cases were inspired by issue 137467, they aren't directly related, and better fit into match-edge-cases_2.rs --- .../match/match-edge-cases_2.rs | 78 +++++++++++++++++++ tests/ui/closures/or-patterns-issue-137467.rs | 64 --------------- 2 files changed, 78 insertions(+), 64 deletions(-) diff --git a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs index a3b19708899a..81013e5b2cd1 100644 --- a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs +++ b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs @@ -34,4 +34,82 @@ fn edge_case_if() { _b(); } +struct Unit; + +enum TSingle { + A(u32, u32), +} + +enum SSingle { + A { a: u32, b: u32 }, +} + +struct TStruct(u32, u32); +struct SStruct { a: u32, b: u32 } + + +// Destructuring a unit struct should not capture it +fn match_unit_struct(mut x: (Unit, u32)) { + let r = &mut x.0; + let _ = || { + let (Unit, a) = x; + a + }; + + let _ = *r; +} + +// The same is true for an equivalent enum +fn match_unit_enum(mut x: (SingleVariant, u32)) { + let r = &mut x.0; + let _ = || { + let (SingleVariant::A, a) = x; + a + }; + + let _ = *r; +} + +// More generally, destructuring a struct should only capture the fields being touched +fn match_struct(mut x: SStruct) { + let r = &mut x.a; + let _ = || { + let SStruct { b, .. } = x; + b + }; + + let _ = *r; +} + +fn match_tuple_struct(mut x: TStruct) { + let r = &mut x.0; + let _ = || { + let TStruct(_, a) = x; + a + }; + + let _ = *r; +} + +// The same is true for an equivalent enum as well +fn match_singleton(mut x: SSingle) { + let SSingle::A { a: ref mut r, .. } = x; + let _ = || { + let SSingle::A { b, .. } = x; + b + }; + + let _ = *r; +} + +fn match_tuple_singleton(mut x: TSingle) { + let TSingle::A(ref mut r, _) = x; + let _ = || { + let TSingle::A(_, a) = x; + a + }; + + let _ = *r; +} + fn main() {} diff --git a/tests/ui/closures/or-patterns-issue-137467.rs b/tests/ui/closures/or-patterns-issue-137467.rs index 5a1e84e1c9a0..de2a4beeaf9d 100644 --- a/tests/ui/closures/or-patterns-issue-137467.rs +++ b/tests/ui/closures/or-patterns-issue-137467.rs @@ -40,30 +40,6 @@ fn match_unit_variant(x: (Choice, u32, u32)) { }; } -struct Unit; - -fn match_unit_struct(mut x: (Unit, u32)) { - let r = &mut x.0; - let _ = || { - let (Unit, a) = x; - a - }; - - let _ = *r; -} - -enum Also { Unit } - -fn match_unit_enum(mut x: (Also, u32)) { - let r = &mut x.0; - let _ = || { - let (Also::Unit, a) = x; - a - }; - - let _ = *r; -} - enum TEnum { A(u32), B(u32), @@ -99,46 +75,6 @@ enum SSingle { struct TStruct(u32, u32); struct SStruct { a: u32, b: u32 } -fn match_struct(mut x: SStruct) { - let r = &mut x.a; - let _ = || { - let SStruct { b, .. } = x; - b - }; - - let _ = *r; -} - -fn match_tuple_struct(mut x: TStruct) { - let r = &mut x.0; - let _ = || { - let TStruct(_, a) = x; - a - }; - - let _ = *r; -} - -fn match_singleton(mut x: SSingle) { - let SSingle::A { a: ref mut r, .. } = x; - let _ = || { - let SSingle::A { b, .. } = x; - b - }; - - let _ = *r; -} - -fn match_tuple_singleton(mut x: TSingle) { - let TSingle::A(ref mut r, _) = x; - let _ = || { - let TSingle::A(_, a) = x; - a - }; - - let _ = *r; -} - fn match_slice(x: (&[u32], u32, u32)) { let _ = || { let (([], a, _) | ([_, ..], _, a)) = x; From 4e090078b46833b2b71179b7e4382ddbddafc4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Thu, 15 Jan 2026 17:24:27 +0100 Subject: [PATCH 2166/3801] capture-enums.rs: get rid of feature gate noise --- .../2229_closure_analysis/capture-enums.rs | 7 +-- .../capture-enums.stderr | 51 ++++++------------- 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/tests/ui/closures/2229_closure_analysis/capture-enums.rs b/tests/ui/closures/2229_closure_analysis/capture-enums.rs index 4c600ccdaa43..36b98351854b 100644 --- a/tests/ui/closures/2229_closure_analysis/capture-enums.rs +++ b/tests/ui/closures/2229_closure_analysis/capture-enums.rs @@ -1,6 +1,7 @@ //@ edition:2021 #![feature(rustc_attrs)] +#![feature(stmt_expr_attributes)] enum Info { Point(i32, i32, String), @@ -14,9 +15,6 @@ fn multi_variant_enum() { let meta = Info::Meta("meta".into(), vec); let c = #[rustc_capture_analysis] - //~^ ERROR: attributes on expressions are experimental - //~| NOTE: see issue #15701 - //~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date || { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: @@ -48,9 +46,6 @@ fn single_variant_enum() { let point = SingleVariant::Point(10, -10, "1".into()); let c = #[rustc_capture_analysis] - //~^ ERROR: attributes on expressions are experimental - //~| NOTE: see issue #15701 - //~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date || { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: diff --git a/tests/ui/closures/2229_closure_analysis/capture-enums.stderr b/tests/ui/closures/2229_closure_analysis/capture-enums.stderr index b62384ffe12e..2f49c8668f85 100644 --- a/tests/ui/closures/2229_closure_analysis/capture-enums.stderr +++ b/tests/ui/closures/2229_closure_analysis/capture-enums.stderr @@ -1,25 +1,5 @@ -error[E0658]: attributes on expressions are experimental - --> $DIR/capture-enums.rs:16:13 - | -LL | let c = #[rustc_capture_analysis] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #15701 for more information - = help: add `#![feature(stmt_expr_attributes)]` 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[E0658]: attributes on expressions are experimental - --> $DIR/capture-enums.rs:50:13 - | -LL | let c = #[rustc_capture_analysis] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #15701 for more information - = help: add `#![feature(stmt_expr_attributes)]` 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: First Pass analysis includes: - --> $DIR/capture-enums.rs:20:5 + --> $DIR/capture-enums.rs:18:5 | LL | / || { LL | | @@ -30,38 +10,38 @@ LL | | }; | |_____^ | note: Capturing point[] -> Immutable - --> $DIR/capture-enums.rs:23:41 + --> $DIR/capture-enums.rs:21:41 | LL | if let Info::Point(_, _, str) = point { | ^^^^^ note: Capturing point[] -> Immutable - --> $DIR/capture-enums.rs:23:41 + --> $DIR/capture-enums.rs:21:41 | LL | if let Info::Point(_, _, str) = point { | ^^^^^ note: Capturing point[(2, 0)] -> ByValue - --> $DIR/capture-enums.rs:23:41 + --> $DIR/capture-enums.rs:21:41 | LL | if let Info::Point(_, _, str) = point { | ^^^^^ note: Capturing meta[] -> Immutable - --> $DIR/capture-enums.rs:31:35 + --> $DIR/capture-enums.rs:29:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ note: Capturing meta[] -> Immutable - --> $DIR/capture-enums.rs:31:35 + --> $DIR/capture-enums.rs:29:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ note: Capturing meta[(1, 1)] -> ByValue - --> $DIR/capture-enums.rs:31:35 + --> $DIR/capture-enums.rs:29:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ error: Min Capture analysis includes: - --> $DIR/capture-enums.rs:20:5 + --> $DIR/capture-enums.rs:18:5 | LL | / || { LL | | @@ -72,18 +52,18 @@ LL | | }; | |_____^ | note: Min Capture point[] -> ByValue - --> $DIR/capture-enums.rs:23:41 + --> $DIR/capture-enums.rs:21:41 | LL | if let Info::Point(_, _, str) = point { | ^^^^^ note: Min Capture meta[] -> ByValue - --> $DIR/capture-enums.rs:31:35 + --> $DIR/capture-enums.rs:29:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ error: First Pass analysis includes: - --> $DIR/capture-enums.rs:54:5 + --> $DIR/capture-enums.rs:49:5 | LL | / || { LL | | @@ -95,13 +75,13 @@ LL | | }; | |_____^ | note: Capturing point[(2, 0)] -> ByValue - --> $DIR/capture-enums.rs:57:47 + --> $DIR/capture-enums.rs:52:47 | LL | let SingleVariant::Point(_, _, str) = point; | ^^^^^ error: Min Capture analysis includes: - --> $DIR/capture-enums.rs:54:5 + --> $DIR/capture-enums.rs:49:5 | LL | / || { LL | | @@ -113,11 +93,10 @@ LL | | }; | |_____^ | note: Min Capture point[(2, 0)] -> ByValue - --> $DIR/capture-enums.rs:57:47 + --> $DIR/capture-enums.rs:52:47 | LL | let SingleVariant::Point(_, _, str) = point; | ^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0658`. From 940a48966fd1c4cf8809abcac8d501cf47e4576c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Thu, 15 Jan 2026 17:30:51 +0100 Subject: [PATCH 2167/3801] non-exhaustive-match.rs: actually test what the comments say --- .../2229_closure_analysis/match/non-exhaustive-match.rs | 2 ++ .../match/non-exhaustive-match.stderr | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs index 322555827181..5b7259c6c2cc 100644 --- a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs +++ b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs @@ -10,6 +10,8 @@ // Ignore non_exhaustive in the same crate #[non_exhaustive] enum L1 { A, B } + +#[non_exhaustive] enum L2 { C } extern crate match_non_exhaustive_lib; diff --git a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr index 85426dd9a5ea..99d33b05429e 100644 --- a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `L1::B` not covered - --> $DIR/non-exhaustive-match.rs:26:25 + --> $DIR/non-exhaustive-match.rs:28:25 | LL | let _b = || { match l1 { L1::A => () } }; | ^^ pattern `L1::B` not covered @@ -16,7 +16,7 @@ LL | let _b = || { match l1 { L1::A => (), L1::B => todo!() } }; | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: type `E1` is non-empty - --> $DIR/non-exhaustive-match.rs:37:25 + --> $DIR/non-exhaustive-match.rs:39:25 | LL | let _d = || { match e1 {} }; | ^^ @@ -35,7 +35,7 @@ LL ~ } }; | error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/non-exhaustive-match.rs:39:25 + --> $DIR/non-exhaustive-match.rs:41:25 | LL | let _e = || { match e2 { E2::A => (), E2::B => () } }; | ^^ pattern `_` not covered @@ -53,7 +53,7 @@ LL | let _e = || { match e2 { E2::A => (), E2::B => (), _ => todo!() } }; | ++++++++++++++ error[E0505]: cannot move out of `e3` because it is borrowed - --> $DIR/non-exhaustive-match.rs:46:22 + --> $DIR/non-exhaustive-match.rs:48:22 | LL | let _g = || { match e3 { E3::C => (), _ => () } }; | -- -- borrow occurs due to use in closure From a28b279357283aacb9cfb0ecb8321a798738df46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Wed, 14 Jan 2026 23:47:33 +0100 Subject: [PATCH 2168/3801] Make some mir-opt tests more resilient --- tests/mir-opt/unreachable.rs | 7 ++++--- tests/mir-opt/unreachable_enum_branching.rs | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/mir-opt/unreachable.rs b/tests/mir-opt/unreachable.rs index f7f4815ae7ce..afab1291fc3d 100644 --- a/tests/mir-opt/unreachable.rs +++ b/tests/mir-opt/unreachable.rs @@ -47,10 +47,11 @@ fn as_match() { // CHECK: bb1: { // CHECK: [[eq:_.*]] = Ne({{.*}}, const 1_isize); // CHECK-NEXT: assume(move [[eq]]); - // CHECK-NEXT: goto -> bb2; - // CHECK: bb2: { + // CHECK-NEXT: goto -> [[return:bb.*]]; + // CHECK: [[return]]: { + // CHECK-NOT: {{bb.*}}: { // CHECK: return; - // CHECK: bb3: { + // CHECK: {{bb.*}}: { // CHECK-NEXT: unreachable; match empty() { Some(_x) => match _x {}, diff --git a/tests/mir-opt/unreachable_enum_branching.rs b/tests/mir-opt/unreachable_enum_branching.rs index 7647f9bf0779..0f6656f4168e 100644 --- a/tests/mir-opt/unreachable_enum_branching.rs +++ b/tests/mir-opt/unreachable_enum_branching.rs @@ -49,7 +49,7 @@ struct Plop { fn simple() { // CHECK-LABEL: fn simple( // CHECK: [[discr:_.*]] = discriminant( - // CHECK: switchInt(move [[discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: bb1, otherwise: [[unreachable]]]; + // CHECK: switchInt(move [[discr]]) -> [0: [[unreachable:bb.*]], 1: [[unreachable]], 2: {{bb.*}}, otherwise: [[unreachable]]]; // CHECK: [[unreachable]]: { // CHECK-NEXT: unreachable; match Test1::C { @@ -63,7 +63,7 @@ fn simple() { fn custom_discriminant() { // CHECK-LABEL: fn custom_discriminant( // CHECK: [[discr:_.*]] = discriminant( - // CHECK: switchInt(move [[discr]]) -> [4: bb3, 5: bb2, otherwise: [[unreachable:bb.*]]]; + // CHECK: switchInt(move [[discr]]) -> [4: {{bb.*}}, 5: {{bb.*}}, otherwise: [[unreachable:bb.*]]]; // CHECK: [[unreachable]]: { // CHECK-NEXT: unreachable; match Test2::D { @@ -76,7 +76,7 @@ fn custom_discriminant() { fn otherwise_t1() { // CHECK-LABEL: fn otherwise_t1( // CHECK: [[discr:_.*]] = discriminant( - // CHECK: switchInt(move [[discr]]) -> [0: bb5, 1: bb5, 2: bb1, otherwise: [[unreachable:bb.*]]]; + // CHECK: switchInt(move [[discr]]) -> [0: {{bb.*}}, 1: {{bb.*}}, 2: {{bb.*}}, otherwise: [[unreachable:bb.*]]]; // CHECK: [[unreachable]]: { // CHECK-NEXT: unreachable; match Test1::C { @@ -90,7 +90,7 @@ fn otherwise_t1() { fn otherwise_t2() { // CHECK-LABEL: fn otherwise_t2( // CHECK: [[discr:_.*]] = discriminant( - // CHECK: switchInt(move [[discr]]) -> [4: bb2, 5: bb1, otherwise: [[unreachable:bb.*]]]; + // CHECK: switchInt(move [[discr]]) -> [4: {{bb.*}}, 5: {{bb.*}}, otherwise: [[unreachable:bb.*]]]; // CHECK: [[unreachable]]: { // CHECK-NEXT: unreachable; match Test2::D { From 628bacac3312357af71816b0875174062b310a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sun, 4 Jan 2026 04:22:55 +0100 Subject: [PATCH 2169/3801] add tests for emergent behavior of partial captures --- .../auxiliary/partial_move_drop_order_lib.rs | 11 ++ .../match/auxiliary/partial_move_lib.rs | 4 + .../match/partial-move-drop-order.rs | 83 ++++++++++++ .../match/partial-move-drop-order.run.stdout | 23 ++++ .../match/partial-move.rs | 118 +++++++++++++++++ .../match/partial-move.stderr | 123 ++++++++++++++++++ 6 files changed, 362 insertions(+) create mode 100644 tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_drop_order_lib.rs create mode 100644 tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_lib.rs create mode 100644 tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs create mode 100644 tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout create mode 100644 tests/ui/closures/2229_closure_analysis/match/partial-move.rs create mode 100644 tests/ui/closures/2229_closure_analysis/match/partial-move.stderr diff --git a/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_drop_order_lib.rs b/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_drop_order_lib.rs new file mode 100644 index 000000000000..8cf25c6ba7b2 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_drop_order_lib.rs @@ -0,0 +1,11 @@ +pub struct LoudDrop(pub &'static str); +impl Drop for LoudDrop { + fn drop(&mut self) { + println!("dropping {}", self.0); + } +} + +#[non_exhaustive] +pub enum ExtNonExhaustive { + One(i32, LoudDrop), +} diff --git a/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_lib.rs b/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_lib.rs new file mode 100644 index 000000000000..b0646f1d0032 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_lib.rs @@ -0,0 +1,4 @@ +#[non_exhaustive] +pub enum ExtNonExhaustive { + A(u32, String), +} diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs new file mode 100644 index 000000000000..1c178bd3f684 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs @@ -0,0 +1,83 @@ +//@ edition:2021 +//@ run-pass +//@ check-run-results +//@ aux-build:partial_move_drop_order_lib.rs + +extern crate partial_move_drop_order_lib; +use partial_move_drop_order_lib::{LoudDrop, ExtNonExhaustive}; + +pub enum OneVariant { + One(i32, LoudDrop), +} + +pub enum TwoVariants { + One(i32, LoudDrop), + Two, +} + +#[non_exhaustive] +pub enum NonExhaustive { + One(i32, LoudDrop), +} + +#[allow(unused)] +fn one_variant() { + println!("one variant:"); + let mut thing = OneVariant::One(0, LoudDrop("a")); + let closure = move || match thing { + OneVariant::One(x, _) => {} + _ => unreachable!(), + }; + println!("before assign"); + thing = OneVariant::One(1, LoudDrop("b")); + println!("after assign"); +} + +#[allow(unused)] +fn two_variants() { + println!("two variants:"); + let mut thing = TwoVariants::One(0, LoudDrop("a")); + let closure = move || match thing { + TwoVariants::One(x, _) => {} + _ => unreachable!(), + }; + println!("before assign"); + thing = TwoVariants::One(1, LoudDrop("b")); + println!("after assign"); +} + +#[allow(unused)] +fn non_exhaustive() { + println!("non exhaustive:"); + let mut thing = NonExhaustive::One(0, LoudDrop("a")); + let closure = move || match thing { + NonExhaustive::One(x, _) => {} + _ => unreachable!(), + }; + println!("before assign"); + thing = NonExhaustive::One(1, LoudDrop("b")); + println!("after assign"); +} + +#[allow(unused)] +fn ext_non_exhaustive() { + println!("external non exhaustive:"); + let mut thing = ExtNonExhaustive::One(0, LoudDrop("a")); + let closure = move || match thing { + ExtNonExhaustive::One(x, _) => {} + _ => unreachable!(), + }; + println!("before assign"); + thing = ExtNonExhaustive::One(1, LoudDrop("b")); + println!("after assign"); +} + +fn main() { + one_variant(); + println!(); + two_variants(); + println!(); + non_exhaustive(); + println!(); + ext_non_exhaustive(); +} diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout new file mode 100644 index 000000000000..e0d83dd99549 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout @@ -0,0 +1,23 @@ +one variant: +before assign +dropping a +after assign +dropping b + +two variants: +before assign +after assign +dropping a +dropping b + +non exhaustive: +before assign +dropping a +after assign +dropping b + +external non exhaustive: +before assign +after assign +dropping a +dropping b diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move.rs b/tests/ui/closures/2229_closure_analysis/match/partial-move.rs new file mode 100644 index 000000000000..62d1b362cb83 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move.rs @@ -0,0 +1,118 @@ +// This test measures the effect of matching-induced partial captures on the borrow checker. +// In particular, in each of the cases below, the closure either captures the entire enum/struct, +// or each field separately. +// +// If the entire ADT gets captured, it'll happen by move, and the closure will live for 'static. +// On the other hand, if each field gets captured separately, the u32 field, being Copy, will only +// get captured by an immutable borrow, resulting in a borrow checker error. +// +// See rust-lang/rust#147722 +// +//@ edition:2021 +//@ aux-build:partial_move_lib.rs +pub struct Struct(u32, String); + +pub enum Enum { + A(u32, String), +} + +pub enum TwoVariants { + A(u32, String), + B, +} + +#[non_exhaustive] +pub enum NonExhaustive { + A(u32, String), +} + +extern crate partial_move_lib; +use partial_move_lib::ExtNonExhaustive; + +// First, let's assert that the additional wildcard arm is not a source of any behavior +// differences: +pub fn test_enum1(x: Enum) -> impl FnOnce() { + || { + //~^ ERROR: closure may outlive the current function, but it borrows `x.0` + match x { + Enum::A(a, b) => { + drop((a, b)); + } + _ => unreachable!(), + } + } +} + +pub fn test_enum2(x: Enum) -> impl FnOnce() { + || { + //~^ ERROR: closure may outlive the current function, but it borrows `x.0` + match x { + Enum::A(a, b) => { + drop((a, b)); + } + } + } +} + +// The behavior for single-variant enums matches what happens for a struct +pub fn test_struct(x: Struct) -> impl FnOnce() { + || { + //~^ ERROR: closure may outlive the current function, but it borrows `x.0` + match x { + Struct(a, b) => { + drop((a, b)); + } + } + } +} + +// If we have two variants, the entire enum gets moved into the closure +pub fn test_two_variants(x: TwoVariants) -> impl FnOnce() { + || { + match x { + TwoVariants::A(a, b) => { + drop((a, b)); + } + _ => unreachable!(), + } + } +} + +// ...and single-variant, non-exhaustive enums *should* behave as if they had multiple variants +pub fn test_non_exhaustive1(x: NonExhaustive) -> impl FnOnce() { + || { + //~^ ERROR: closure may outlive the current function, but it borrows `x.0` + match x { + NonExhaustive::A(a, b) => { + drop((a, b)); + } + _ => unreachable!(), + } + } +} + +// (again, wildcard branch or not) +pub fn test_non_exhaustive2(x: NonExhaustive) -> impl FnOnce() { + || { + //~^ ERROR: closure may outlive the current function, but it borrows `x.0` + match x { + NonExhaustive::A(a, b) => { + drop((a, b)); + } + } + } +} + +// ...regardless of whether the enum is defined in the current, or in another crate +pub fn test_ext(x: ExtNonExhaustive) -> impl FnOnce() { + || { + match x { + ExtNonExhaustive::A(a, b) => { + drop((a, b)); + } + _ => unreachable!(), + } + } +} + +fn main() {} diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr b/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr new file mode 100644 index 000000000000..36adcc6717ed --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr @@ -0,0 +1,123 @@ +error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function + --> $DIR/partial-move.rs:35:5 + | +LL | || { + | ^^ may outlive borrowed value `x.0` +LL | +LL | match x { + | - `x.0` is borrowed here + | +note: closure is returned here + --> $DIR/partial-move.rs:35:5 + | +LL | / || { +LL | | +LL | | match x { +LL | | Enum::A(a, b) => { +... | +LL | | } + | |_____^ +help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword + | +LL | move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function + --> $DIR/partial-move.rs:47:5 + | +LL | || { + | ^^ may outlive borrowed value `x.0` +LL | +LL | match x { + | - `x.0` is borrowed here + | +note: closure is returned here + --> $DIR/partial-move.rs:47:5 + | +LL | / || { +LL | | +LL | | match x { +LL | | Enum::A(a, b) => { +... | +LL | | } + | |_____^ +help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword + | +LL | move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function + --> $DIR/partial-move.rs:59:5 + | +LL | || { + | ^^ may outlive borrowed value `x.0` +LL | +LL | match x { + | - `x.0` is borrowed here + | +note: closure is returned here + --> $DIR/partial-move.rs:59:5 + | +LL | / || { +LL | | +LL | | match x { +LL | | Struct(a, b) => { +... | +LL | | } + | |_____^ +help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword + | +LL | move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function + --> $DIR/partial-move.rs:83:5 + | +LL | || { + | ^^ may outlive borrowed value `x.0` +LL | +LL | match x { + | - `x.0` is borrowed here + | +note: closure is returned here + --> $DIR/partial-move.rs:83:5 + | +LL | / || { +LL | | +LL | | match x { +LL | | NonExhaustive::A(a, b) => { +... | +LL | | } + | |_____^ +help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword + | +LL | move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function + --> $DIR/partial-move.rs:96:5 + | +LL | || { + | ^^ may outlive borrowed value `x.0` +LL | +LL | match x { + | - `x.0` is borrowed here + | +note: closure is returned here + --> $DIR/partial-move.rs:96:5 + | +LL | / || { +LL | | +LL | | match x { +LL | | NonExhaustive::A(a, b) => { +... | +LL | | } + | |_____^ +help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword + | +LL | move || { + | ++++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0373`. From 3c175080dca2a60eb42a28d46ecc416d3a6f8879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sun, 4 Jan 2026 19:34:37 +0100 Subject: [PATCH 2170/3801] add tests for discriminant read borrowck --- tests/ui/match/borrowck-uninhabited.rs | 53 +++++++++++++++++++ tests/ui/match/borrowck-uninhabited.stderr | 14 +++++ tests/ui/match/uninhabited-granular-moves.rs | 46 ++++++++++++++++ .../match/uninhabited-granular-moves.stderr | 18 +++++++ 4 files changed, 131 insertions(+) create mode 100644 tests/ui/match/borrowck-uninhabited.rs create mode 100644 tests/ui/match/borrowck-uninhabited.stderr create mode 100644 tests/ui/match/uninhabited-granular-moves.rs create mode 100644 tests/ui/match/uninhabited-granular-moves.stderr diff --git a/tests/ui/match/borrowck-uninhabited.rs b/tests/ui/match/borrowck-uninhabited.rs new file mode 100644 index 000000000000..93838ede2793 --- /dev/null +++ b/tests/ui/match/borrowck-uninhabited.rs @@ -0,0 +1,53 @@ +// See: rust-lang/rust#146590 + +enum Never {} + +// baseline +fn both_inhabited(x: &mut Result) { + match x { + &mut Ok(ref mut y) => match x { + //~^ ERROR: cannot use `*x` because it was mutably borrowed + &mut Err(ref mut z) => { + let _y = y; + let _z = z; + } + _ => {} + }, + _ => {} + }; +} + +fn ref_uninhabited(x: &mut Result) { + match x { + &mut Ok(ref mut y) => match x { + &mut Err(ref mut z) => { + let _y = y; + let _z = z; + } + _ => {} + }, + _ => {} + }; +} + +enum Single { + V(String, String), +} + +// arguably this should be rejected as well, but currently it is still accepted +fn single_variant(x: &mut Single) { + match x { + &mut Single::V(ref mut y, _) => { + match x { + &mut Single::V(_, ref mut z) => { + let _y = y; + let _z = z; + } + _ => {} + } + }, + _ => {} + }; +} + +fn main() {} diff --git a/tests/ui/match/borrowck-uninhabited.stderr b/tests/ui/match/borrowck-uninhabited.stderr new file mode 100644 index 000000000000..ee3b814da9f4 --- /dev/null +++ b/tests/ui/match/borrowck-uninhabited.stderr @@ -0,0 +1,14 @@ +error[E0503]: cannot use `*x` because it was mutably borrowed + --> $DIR/borrowck-uninhabited.rs:8:37 + | +LL | &mut Ok(ref mut y) => match x { + | --------- ^ use of borrowed `x.0` + | | + | `x.0` is borrowed here +... +LL | let _y = y; + | - borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0503`. diff --git a/tests/ui/match/uninhabited-granular-moves.rs b/tests/ui/match/uninhabited-granular-moves.rs new file mode 100644 index 000000000000..9d04fcb3259e --- /dev/null +++ b/tests/ui/match/uninhabited-granular-moves.rs @@ -0,0 +1,46 @@ +// See rust-lang/rust#146590, as well as Zulip discussion: +// +// https://rust-lang.zulipchat.com/#narrow/channel/513289-t-patterns/topic/Question.20about.20patterns.20and.20moves/with/558638455 +// +// Whether pattern matching performs a discriminant read shouldn't depend on whether +// you explicitly write down an uninhabited branch, or leave it implicit. + +enum Emp { } + +enum Foo { + Bar(A), + Qux(Emp), +} + +fn test1(thefoo: Foo<(Box, Box)>) { + match thefoo { + Foo::Bar((a, _)) => { } + } + + match thefoo { + Foo::Bar((_, a)) => { } + } +} + +fn test2(thefoo: Foo<(Box, Box)>) { + match thefoo { + Foo::Bar((a, _)) => { } + Foo::Qux(_) => { } + } + match thefoo { //~ ERROR: use of partially moved value: `thefoo` + Foo::Bar((_, a)) => { } + Foo::Qux(_) => { } + } +} + +fn test3(thefoo: Foo<(Box, Box)>) { + match thefoo { + Foo::Bar((a, _)) => { } + Foo::Qux(_) => { } + } + match thefoo { + Foo::Bar((_, a)) => { } + } +} + +fn main() {} diff --git a/tests/ui/match/uninhabited-granular-moves.stderr b/tests/ui/match/uninhabited-granular-moves.stderr new file mode 100644 index 000000000000..d32f935d3d55 --- /dev/null +++ b/tests/ui/match/uninhabited-granular-moves.stderr @@ -0,0 +1,18 @@ +error[E0382]: use of partially moved value: `thefoo` + --> $DIR/uninhabited-granular-moves.rs:30:11 + | +LL | Foo::Bar((a, _)) => { } + | - value partially moved here +... +LL | match thefoo { + | ^^^^^^ value used here after partial move + | + = note: partial move occurs because value has type `Box`, which does not implement the `Copy` trait +help: borrow this binding in the pattern to avoid moving the value + | +LL | Foo::Bar((ref a, _)) => { } + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. From ee1a6f4e88bb71d964864de1d7c935d53a3d0cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sun, 4 Jan 2026 04:22:55 +0100 Subject: [PATCH 2171/3801] match in closure: capture non_exhaustive even if defined in current crate --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 29 +++-------- .../match/non-exhaustive-match.rs | 16 +++--- .../match/non-exhaustive-match.stderr | 19 +++++-- .../match/partial-move-drop-order.rs | 5 ++ .../match/partial-move-drop-order.run.stdout | 2 +- .../match/partial-move.rs | 4 +- .../match/partial-move.stderr | 50 +------------------ 7 files changed, 39 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index ad34994526ed..9e9b511b9b23 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -818,14 +818,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// The core driver for walking a pattern /// /// This should mirror how pattern-matching gets lowered to MIR, as - /// otherwise lowering will ICE when trying to resolve the upvars. + /// otherwise said lowering will ICE when trying to resolve the upvars. /// /// However, it is okay to approximate it here by doing *more* accesses than /// the actual MIR builder will, which is useful when some checks are too - /// cumbersome to perform here. For example, if after typeck it becomes - /// clear that only one variant of an enum is inhabited, and therefore a - /// read of the discriminant is not necessary, `walk_pat` will have - /// over-approximated the necessary upvar capture granularity. + /// cumbersome to perform here, because e.g. they require more typeck results + /// than available. /// /// Do note that discrepancies like these do still create obscure corners /// in the semantics of the language, and should be avoided if possible. @@ -1852,26 +1850,13 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } /// Checks whether a type has multiple variants, and therefore, whether a - /// read of the discriminant might be necessary. Note that the actual MIR - /// builder code does a more specific check, filtering out variants that - /// happen to be uninhabited. - /// - /// Here, it is not practical to perform such a check, because inhabitedness - /// queries require typeck results, and typeck requires closure capture analysis. - /// - /// Moreover, the language is moving towards uninhabited variants still semantically - /// causing a discriminant read, so we *shouldn't* perform any such check. - /// - /// FIXME(never_patterns): update this comment once the aforementioned MIR builder - /// code is changed to be insensitive to inhhabitedness. + /// read of the discriminant might be necessary. #[instrument(skip(self, span), level = "debug")] fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool { if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() { - // Note that if a non-exhaustive SingleVariant is defined in another crate, we need - // to assume that more cases will be added to the variant in the future. This mean - // that we should handle non-exhaustive SingleVariant the same way we would handle - // a MultiVariant. - def.variants().len() > 1 || def.variant_list_has_applicable_non_exhaustive() + // We treat non-exhaustive enums the same independent of the crate they are + // defined in, to avoid differences in the operational semantics between crates. + def.variants().len() > 1 || def.is_variant_list_non_exhaustive() } else { false } diff --git a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs index 5b7259c6c2cc..f47d70b52f20 100644 --- a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs +++ b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs @@ -28,12 +28,6 @@ fn main() { let _b = || { match l1 { L1::A => () } }; //~^ ERROR: non-exhaustive patterns: `L1::B` not covered [E0004] - // l2 should not be captured as it is a non-exhaustive SingleVariant - // defined in this crate - let _c = || { match l2 { L2::C => (), _ => () } }; - let mut mut_l2 = l2; - _c(); - // E1 is not visibly uninhabited from here let (e1, e2, e3, e4) = bar(); let _d = || { match e1 {} }; @@ -42,8 +36,14 @@ fn main() { //~^ ERROR: non-exhaustive patterns: `_` not covered [E0004] let _f = || { match e2 { E2::A => (), E2::B => (), _ => () } }; - // e3 should be captured as it is a non-exhaustive SingleVariant - // defined in another crate + // non-exhaustive enums should always be captured, regardless if they + // are defined in the current crate: + let _c = || { match l2 { L2::C => (), _ => () } }; + let mut mut_l2 = l2; + //~^ ERROR: cannot move out of `l2` because it is borrowed + _c(); + + // ...or in another crate: let _g = || { match e3 { E3::C => (), _ => () } }; let mut mut_e3 = e3; //~^ ERROR: cannot move out of `e3` because it is borrowed diff --git a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr index 99d33b05429e..e34d1889803a 100644 --- a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr @@ -16,7 +16,7 @@ LL | let _b = || { match l1 { L1::A => (), L1::B => todo!() } }; | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: type `E1` is non-empty - --> $DIR/non-exhaustive-match.rs:39:25 + --> $DIR/non-exhaustive-match.rs:33:25 | LL | let _d = || { match e1 {} }; | ^^ @@ -35,7 +35,7 @@ LL ~ } }; | error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/non-exhaustive-match.rs:41:25 + --> $DIR/non-exhaustive-match.rs:35:25 | LL | let _e = || { match e2 { E2::A => (), E2::B => () } }; | ^^ pattern `_` not covered @@ -52,6 +52,19 @@ help: ensure that all possible cases are being handled by adding a match arm wit LL | let _e = || { match e2 { E2::A => (), E2::B => (), _ => todo!() } }; | ++++++++++++++ +error[E0505]: cannot move out of `l2` because it is borrowed + --> $DIR/non-exhaustive-match.rs:42:22 + | +LL | let _c = || { match l2 { L2::C => (), _ => () } }; + | -- -- borrow occurs due to use in closure + | | + | borrow of `l2` occurs here +LL | let mut mut_l2 = l2; + | ^^ move out of `l2` occurs here +LL | +LL | _c(); + | -- borrow later used here + error[E0505]: cannot move out of `e3` because it is borrowed --> $DIR/non-exhaustive-match.rs:48:22 | @@ -65,7 +78,7 @@ LL | LL | _g(); | -- borrow later used here -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0004, E0505. For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs index 1c178bd3f684..348d558dd980 100644 --- a/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs @@ -1,3 +1,8 @@ +// Make sure that #[non_exhaustive] cannot cause drop order to depend on which +// crate the code is in. +// +// See rust-lang/rust#147722 +// //@ edition:2021 //@ run-pass //@ check-run-results diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout index e0d83dd99549..3fa346d87b07 100644 --- a/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout @@ -12,8 +12,8 @@ dropping b non exhaustive: before assign -dropping a after assign +dropping a dropping b external non exhaustive: diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move.rs b/tests/ui/closures/2229_closure_analysis/match/partial-move.rs index 62d1b362cb83..7bd435bd1856 100644 --- a/tests/ui/closures/2229_closure_analysis/match/partial-move.rs +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move.rs @@ -78,10 +78,9 @@ pub fn test_two_variants(x: TwoVariants) -> impl FnOnce() { } } -// ...and single-variant, non-exhaustive enums *should* behave as if they had multiple variants +// ...and single-variant, non-exhaustive enums behave as if they had multiple variants pub fn test_non_exhaustive1(x: NonExhaustive) -> impl FnOnce() { || { - //~^ ERROR: closure may outlive the current function, but it borrows `x.0` match x { NonExhaustive::A(a, b) => { drop((a, b)); @@ -94,7 +93,6 @@ pub fn test_non_exhaustive1(x: NonExhaustive) -> impl FnOnce() { // (again, wildcard branch or not) pub fn test_non_exhaustive2(x: NonExhaustive) -> impl FnOnce() { || { - //~^ ERROR: closure may outlive the current function, but it borrows `x.0` match x { NonExhaustive::A(a, b) => { drop((a, b)); diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr b/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr index 36adcc6717ed..09f9adf95d5b 100644 --- a/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr @@ -70,54 +70,6 @@ help: to force the closure to take ownership of `x.0` (and any other referenced LL | move || { | ++++ -error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function - --> $DIR/partial-move.rs:83:5 - | -LL | || { - | ^^ may outlive borrowed value `x.0` -LL | -LL | match x { - | - `x.0` is borrowed here - | -note: closure is returned here - --> $DIR/partial-move.rs:83:5 - | -LL | / || { -LL | | -LL | | match x { -LL | | NonExhaustive::A(a, b) => { -... | -LL | | } - | |_____^ -help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword - | -LL | move || { - | ++++ - -error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function - --> $DIR/partial-move.rs:96:5 - | -LL | || { - | ^^ may outlive borrowed value `x.0` -LL | -LL | match x { - | - `x.0` is borrowed here - | -note: closure is returned here - --> $DIR/partial-move.rs:96:5 - | -LL | / || { -LL | | -LL | | match x { -LL | | NonExhaustive::A(a, b) => { -... | -LL | | } - | |_____^ -help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword - | -LL | move || { - | ++++ - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0373`. From 3387a58bc777d31493f37160cdd1f57223f0bc0c Mon Sep 17 00:00:00 2001 From: James Hendry Date: Wed, 14 Jan 2026 10:48:24 +0000 Subject: [PATCH 2172/3801] fN::BITS constants for feature float_bits_const Also enables the feature for compiler_builtins as otherwise this causes a warning and conflicts with the Float extension trait Explicitly use Float trait BITS in miri tests to prevent warnings against upcoming BITS field for floats --- library/compiler-builtins/compiler-builtins/src/lib.rs | 1 + library/core/src/num/f128.rs | 5 +++++ library/core/src/num/f16.rs | 5 +++++ library/core/src/num/f32.rs | 4 ++++ library/core/src/num/f64.rs | 4 ++++ src/tools/miri/tests/pass/float.rs | 6 +++--- src/tools/test-float-parse/src/traits.rs | 2 +- 7 files changed, 23 insertions(+), 4 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/src/lib.rs b/library/compiler-builtins/compiler-builtins/src/lib.rs index c993209699be..342427aca9c7 100644 --- a/library/compiler-builtins/compiler-builtins/src/lib.rs +++ b/library/compiler-builtins/compiler-builtins/src/lib.rs @@ -11,6 +11,7 @@ #![feature(repr_simd)] #![feature(macro_metavar_expr_concat)] #![feature(rustc_attrs)] +#![feature(float_bits_const)] #![cfg_attr(f16_enabled, feature(f16))] #![cfg_attr(f128_enabled, feature(f128))] #![no_builtins] diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index bf99fee4fc78..8bb919de729e 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -145,6 +145,11 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] pub const RADIX: u32 = 2; + /// The size of this float type in bits. + // #[unstable(feature = "f128", issue = "116909")] + #[unstable(feature = "float_bits_const", issue = "151073")] + pub const BITS: u32 = 128; + /// Number of significant digits in base 2. /// /// Note that the size of the mantissa in the bitwise representation is one diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index f39ee22871d5..699b2e3c25c4 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -142,6 +142,11 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] pub const RADIX: u32 = 2; + /// The size of this float type in bits. + // #[unstable(feature = "f16", issue = "116909")] + #[unstable(feature = "float_bits_const", issue = "151073")] + pub const BITS: u32 = 16; + /// Number of significant digits in base 2. /// /// Note that the size of the mantissa in the bitwise representation is one diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 6fe4285374b2..118ef4ff3d43 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -390,6 +390,10 @@ impl f32 { #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const RADIX: u32 = 2; + /// The size of this float type in bits. + #[unstable(feature = "float_bits_const", issue = "151073")] + pub const BITS: u32 = 32; + /// Number of significant digits in base 2. /// /// Note that the size of the mantissa in the bitwise representation is one diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index d0aca152415e..eacbd3ff20bf 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -390,6 +390,10 @@ impl f64 { #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const RADIX: u32 = 2; + /// The size of this float type in bits. + #[unstable(feature = "float_bits_const", issue = "151073")] + pub const BITS: u32 = 64; + /// Number of significant digits in base 2. /// /// Note that the size of the mantissa in the bitwise representation is one diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index a74a66d5455a..052c83d1aa31 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -353,7 +353,7 @@ macro_rules! test_ftoi_itof { assert_itof(i, f, msg); } - let fbits = <$fty>::BITS; + let fbits = <$fty as Float>::BITS; let fsig_bits = <$fty>::SIGNIFICAND_BITS; let ibits = <$ity>::BITS; let imax: $ity = <$ity>::MAX; @@ -528,9 +528,9 @@ macro_rules! test_ftof { assert!((<$f1>::NAN as $f2).is_nan(), "{} -> {} nan", stringify!($f1), stringify!($f2)); let min_sub_casted = <$f1>::from_bits(0x1) as $f2; - let min_neg_sub_casted = <$f1>::from_bits(0x1 | 1 << (<$f1>::BITS - 1)) as $f2; + let min_neg_sub_casted = <$f1>::from_bits(0x1 | 1 << (<$f1 as Float>::BITS - 1)) as $f2; - if <$f1>::BITS > <$f2>::BITS { + if <$f1 as Float>::BITS > <$f2 as Float>::BITS { assert_feq(<$f1>::MAX as $f2, <$f2>::INFINITY, "max -> inf"); assert_feq(<$f1>::MIN as $f2, <$f2>::NEG_INFINITY, "max -> inf"); assert_biteq(min_sub_casted, f2zero, "min subnormal -> 0.0"); diff --git a/src/tools/test-float-parse/src/traits.rs b/src/tools/test-float-parse/src/traits.rs index 65a8721bfa5c..0cb44d297bfb 100644 --- a/src/tools/test-float-parse/src/traits.rs +++ b/src/tools/test-float-parse/src/traits.rs @@ -155,7 +155,7 @@ macro_rules! impl_float { const BITS: u32 = <$ity>::BITS; const MAN_BITS: u32 = Self::MANTISSA_DIGITS - 1; const MAN_MASK: Self::Int = (Self::Int::ONE << Self::MAN_BITS) - Self::Int::ONE; - const SIGN_MASK: Self::Int = Self::Int::ONE << (Self::BITS-1); + const SIGN_MASK: Self::Int = Self::Int::ONE << (::BITS-1); fn from_bits(i: Self::Int) -> Self { Self::from_bits(i) } fn to_bits(self) -> Self::Int { self.to_bits() } fn constants() -> &'static Constants { From af302a67fdc508cfd08ee22facb96bcf0e5bf831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sun, 4 Jan 2026 19:34:37 +0100 Subject: [PATCH 2173/3801] discriminant reads: make semantics independent of module/crate --- .../src/builder/matches/match_pair.rs | 20 +++----- .../fail/match/all_variants_uninhabited.rs | 25 ++++++++++ .../match/all_variants_uninhabited.stderr | 13 +++++ .../{ => match}/closures/deref-in-pattern.rs | 0 .../closures/deref-in-pattern.stderr | 2 +- .../{ => match}/closures/partial-pattern.rs | 0 .../closures/partial-pattern.stderr | 2 +- .../closures/uninhabited-variant1.rs} | 0 .../closures/uninhabited-variant1.stderr} | 6 +-- .../match/closures/uninhabited-variant2.rs | 32 ++++++++++++ .../closures/uninhabited-variant2.stderr | 18 +++++++ .../fail/match/only_inhabited_variant.rs | 21 ++++++++ .../fail/match/only_inhabited_variant.stderr | 13 +++++ .../miri/tests/fail/match/single_variant.rs | 31 ++++++++++++ .../tests/fail/match/single_variant.stderr | 13 +++++ .../tests/fail/match/single_variant_uninit.rs | 36 +++++++++++++ .../fail/match/single_variant_uninit.stderr | 18 +++++++ .../enum/enum-transparent-extract.rs | 4 ++ ...atterns.opt1.SimplifyCfg-initial.after.mir | 10 ++-- ...atterns.opt2.SimplifyCfg-initial.after.mir | 15 ++++++ ...atterns.opt3.SimplifyCfg-initial.after.mir | 17 ++++--- ...ng.identity.JumpThreading.panic-abort.diff | 19 +++++-- ...g.identity.JumpThreading.panic-unwind.diff | 19 +++++-- ...map_via_question_mark.PreCodegen.after.mir | 50 +++++++++++-------- ...e_const_switch.identity.JumpThreading.diff | 15 ++++-- ...ch.UnreachablePropagation.panic-abort.diff | 12 +++-- ...h.UnreachablePropagation.panic-unwind.diff | 12 +++-- tests/mir-opt/unreachable.rs | 2 +- ....UnreachableEnumBranching.panic-abort.diff | 28 +++++------ ...UnreachableEnumBranching.panic-unwind.diff | 28 +++++------ tests/ui/match/borrowck-uninhabited.rs | 2 + tests/ui/match/borrowck-uninhabited.stderr | 13 ++++- tests/ui/match/uninhabited-granular-moves.rs | 4 +- .../match/uninhabited-granular-moves.stderr | 32 +++++++++++- .../borrowck-exhaustive.rs | 12 ----- .../borrowck-non-exhaustive.rs | 12 +++++ .../borrowck-non-exhaustive.stderr | 15 +++++- 37 files changed, 455 insertions(+), 116 deletions(-) create mode 100644 src/tools/miri/tests/fail/match/all_variants_uninhabited.rs create mode 100644 src/tools/miri/tests/fail/match/all_variants_uninhabited.stderr rename src/tools/miri/tests/fail/{ => match}/closures/deref-in-pattern.rs (100%) rename src/tools/miri/tests/fail/{ => match}/closures/deref-in-pattern.stderr (91%) rename src/tools/miri/tests/fail/{ => match}/closures/partial-pattern.rs (100%) rename src/tools/miri/tests/fail/{ => match}/closures/partial-pattern.stderr (92%) rename src/tools/miri/tests/fail/{closures/uninhabited-variant.rs => match/closures/uninhabited-variant1.rs} (100%) rename src/tools/miri/tests/fail/{closures/uninhabited-variant.stderr => match/closures/uninhabited-variant1.stderr} (74%) create mode 100644 src/tools/miri/tests/fail/match/closures/uninhabited-variant2.rs create mode 100644 src/tools/miri/tests/fail/match/closures/uninhabited-variant2.stderr create mode 100644 src/tools/miri/tests/fail/match/only_inhabited_variant.rs create mode 100644 src/tools/miri/tests/fail/match/only_inhabited_variant.stderr create mode 100644 src/tools/miri/tests/fail/match/single_variant.rs create mode 100644 src/tools/miri/tests/fail/match/single_variant.stderr create mode 100644 src/tools/miri/tests/fail/match/single_variant_uninit.rs create mode 100644 src/tools/miri/tests/fail/match/single_variant_uninit.stderr diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 8cee3ff27e8f..07af66127ef9 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -295,22 +295,18 @@ impl<'tcx> MatchPairTree<'tcx> { } } - PatKind::Variant { adt_def, variant_index, args, ref subpatterns } => { + PatKind::Variant { adt_def, variant_index, args: _, ref subpatterns } => { let downcast_place = place_builder.downcast(adt_def, variant_index); // `(x as Variant)` cx.field_match_pairs(&mut subpairs, extra_data, downcast_place, subpatterns); - let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { - i == variant_index - || !v.inhabited_predicate(cx.tcx, adt_def).instantiate(cx.tcx, args).apply( - cx.tcx, - cx.infcx.typing_env(cx.param_env), - cx.def_id.into(), - ) - }) && !adt_def.variant_list_has_applicable_non_exhaustive(); - if irrefutable { - None - } else { + // We treat non-exhaustive enums the same independent of the crate they are + // defined in, to avoid differences in the operational semantics between crates. + let refutable = + adt_def.variants().len() > 1 || adt_def.is_variant_list_non_exhaustive(); + if refutable { Some(TestableCase::Variant { adt_def, variant_index }) + } else { + None } } diff --git a/src/tools/miri/tests/fail/match/all_variants_uninhabited.rs b/src/tools/miri/tests/fail/match/all_variants_uninhabited.rs new file mode 100644 index 000000000000..e7ca45579d84 --- /dev/null +++ b/src/tools/miri/tests/fail/match/all_variants_uninhabited.rs @@ -0,0 +1,25 @@ +#![allow(deref_nullptr)] + +enum Never {} + +fn main() { + unsafe { + match *std::ptr::null::>() { + //~^ ERROR: read discriminant of an uninhabited enum variant + Ok(_) => { + lol(); + } + Err(_) => { + wut(); + } + } + } +} + +fn lol() { + println!("lol"); +} + +fn wut() { + println!("wut"); +} diff --git a/src/tools/miri/tests/fail/match/all_variants_uninhabited.stderr b/src/tools/miri/tests/fail/match/all_variants_uninhabited.stderr new file mode 100644 index 000000000000..90809219340b --- /dev/null +++ b/src/tools/miri/tests/fail/match/all_variants_uninhabited.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: read discriminant of an uninhabited enum variant + --> tests/fail/match/all_variants_uninhabited.rs:LL:CC + | +LL | match *std::ptr::null::>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 + +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/closures/deref-in-pattern.rs b/src/tools/miri/tests/fail/match/closures/deref-in-pattern.rs similarity index 100% rename from src/tools/miri/tests/fail/closures/deref-in-pattern.rs rename to src/tools/miri/tests/fail/match/closures/deref-in-pattern.rs diff --git a/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr b/src/tools/miri/tests/fail/match/closures/deref-in-pattern.stderr similarity index 91% rename from src/tools/miri/tests/fail/closures/deref-in-pattern.stderr rename to src/tools/miri/tests/fail/match/closures/deref-in-pattern.stderr index fae2d286c487..cbb74df5de77 100644 --- a/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr +++ b/src/tools/miri/tests/fail/match/closures/deref-in-pattern.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: constructing invalid value: encountered a dangling reference (use-after-free) - --> tests/fail/closures/deref-in-pattern.rs:LL:CC + --> tests/fail/match/closures/deref-in-pattern.rs:LL:CC | LL | let _ = || { | _____________^ diff --git a/src/tools/miri/tests/fail/closures/partial-pattern.rs b/src/tools/miri/tests/fail/match/closures/partial-pattern.rs similarity index 100% rename from src/tools/miri/tests/fail/closures/partial-pattern.rs rename to src/tools/miri/tests/fail/match/closures/partial-pattern.rs diff --git a/src/tools/miri/tests/fail/closures/partial-pattern.stderr b/src/tools/miri/tests/fail/match/closures/partial-pattern.stderr similarity index 92% rename from src/tools/miri/tests/fail/closures/partial-pattern.stderr rename to src/tools/miri/tests/fail/match/closures/partial-pattern.stderr index 8dea4d4d8c64..b8ca04559e23 100644 --- a/src/tools/miri/tests/fail/closures/partial-pattern.stderr +++ b/src/tools/miri/tests/fail/match/closures/partial-pattern.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: constructing invalid value: encountered a dangling reference (use-after-free) - --> tests/fail/closures/partial-pattern.rs:LL:CC + --> tests/fail/match/closures/partial-pattern.rs:LL:CC | LL | let _ = || { | _____________^ diff --git a/src/tools/miri/tests/fail/closures/uninhabited-variant.rs b/src/tools/miri/tests/fail/match/closures/uninhabited-variant1.rs similarity index 100% rename from src/tools/miri/tests/fail/closures/uninhabited-variant.rs rename to src/tools/miri/tests/fail/match/closures/uninhabited-variant1.rs diff --git a/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr b/src/tools/miri/tests/fail/match/closures/uninhabited-variant1.stderr similarity index 74% rename from src/tools/miri/tests/fail/closures/uninhabited-variant.stderr rename to src/tools/miri/tests/fail/match/closures/uninhabited-variant1.stderr index aea878660115..1a10a5b24d25 100644 --- a/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr +++ b/src/tools/miri/tests/fail/match/closures/uninhabited-variant1.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: read discriminant of an uninhabited enum variant - --> tests/fail/closures/uninhabited-variant.rs:LL:CC + --> tests/fail/match/closures/uninhabited-variant1.rs:LL:CC | LL | match r { | ^ Undefined Behavior occurred here @@ -8,9 +8,9 @@ LL | match r { = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: stack backtrace: 0: main::{closure#0} - at tests/fail/closures/uninhabited-variant.rs:LL:CC + at tests/fail/match/closures/uninhabited-variant1.rs:LL:CC 1: main - at tests/fail/closures/uninhabited-variant.rs:LL:CC + at tests/fail/match/closures/uninhabited-variant1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/match/closures/uninhabited-variant2.rs b/src/tools/miri/tests/fail/match/closures/uninhabited-variant2.rs new file mode 100644 index 000000000000..ed68e357fbd5 --- /dev/null +++ b/src/tools/miri/tests/fail/match/closures/uninhabited-variant2.rs @@ -0,0 +1,32 @@ +// Motivated by rust-lang/rust#138961, this shows how invalid discriminants interact with +// closure captures. +// +// Test case with only one inhabited variant, for which rustc used to not emit +// a discriminant read in the first place. See: rust-lang/miri#4778 +#![feature(never_type)] + +#[repr(C)] +#[allow(dead_code)] +enum E { + V0, // discriminant: 0 + V1(!), // 1 +} + +fn main() { + assert_eq!(std::mem::size_of::(), 4); + + let val = 1u32; + let ptr = (&raw const val).cast::(); + let r = unsafe { &*ptr }; + let f = || { + // After rust-lang/rust#138961, constructing the closure performs a reborrow of r. + // Nevertheless, the discriminant is only actually inspected when the closure + // is called. + match r { //~ ERROR: read discriminant of an uninhabited enum variant + E::V0 => {} + E::V1(_) => {} + } + }; + + f(); +} diff --git a/src/tools/miri/tests/fail/match/closures/uninhabited-variant2.stderr b/src/tools/miri/tests/fail/match/closures/uninhabited-variant2.stderr new file mode 100644 index 000000000000..611e0435ef0e --- /dev/null +++ b/src/tools/miri/tests/fail/match/closures/uninhabited-variant2.stderr @@ -0,0 +1,18 @@ +error: Undefined Behavior: read discriminant of an uninhabited enum variant + --> tests/fail/match/closures/uninhabited-variant2.rs:LL:CC + | +LL | match r { + | ^ 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 + = note: stack backtrace: + 0: main::{closure#0} + at tests/fail/match/closures/uninhabited-variant2.rs:LL:CC + 1: main + at tests/fail/match/closures/uninhabited-variant2.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/match/only_inhabited_variant.rs b/src/tools/miri/tests/fail/match/only_inhabited_variant.rs new file mode 100644 index 000000000000..30a7350d2b66 --- /dev/null +++ b/src/tools/miri/tests/fail/match/only_inhabited_variant.rs @@ -0,0 +1,21 @@ +// rust-lang/miri#4778 +#![feature(never_type)] + +#[repr(C)] +#[allow(dead_code)] +enum E { + V0, // discriminant: 0 + V1(!), // 1 +} + +fn main() { + assert_eq!(std::mem::size_of::(), 4); + + let val = 1u32; + let ptr = (&raw const val).cast::(); + let r = unsafe { &*ptr }; + match r { //~ ERROR: read discriminant of an uninhabited enum variant + E::V0 => {} + E::V1(_) => {} + } +} diff --git a/src/tools/miri/tests/fail/match/only_inhabited_variant.stderr b/src/tools/miri/tests/fail/match/only_inhabited_variant.stderr new file mode 100644 index 000000000000..8ca362f902d3 --- /dev/null +++ b/src/tools/miri/tests/fail/match/only_inhabited_variant.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: read discriminant of an uninhabited enum variant + --> tests/fail/match/only_inhabited_variant.rs:LL:CC + | +LL | match r { + | ^ 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 + +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/match/single_variant.rs b/src/tools/miri/tests/fail/match/single_variant.rs new file mode 100644 index 000000000000..dcef6d461a2c --- /dev/null +++ b/src/tools/miri/tests/fail/match/single_variant.rs @@ -0,0 +1,31 @@ +// Ideally, this would be UB regardless of #[non_exhaustive]. For now, +// at least the semantics don't depend on the crate you're in. +// +// See: rust-lang/rust#147722 +#![allow(dead_code)] + +#[repr(u8)] +enum Exhaustive { + A(u8) = 42, +} + +#[repr(u8)] +#[non_exhaustive] +enum NonExhaustive { + A(u8) = 42, +} + +fn main() { + unsafe { + let x: &[u8; 2] = &[21, 37]; + let y: &Exhaustive = std::mem::transmute(x); + match y { + Exhaustive::A(_) => {}, + } + + let y: &NonExhaustive = std::mem::transmute(x); + match y { //~ ERROR: enum value has invalid tag + NonExhaustive::A(_) => {}, + } + } +} diff --git a/src/tools/miri/tests/fail/match/single_variant.stderr b/src/tools/miri/tests/fail/match/single_variant.stderr new file mode 100644 index 000000000000..7467e27ff791 --- /dev/null +++ b/src/tools/miri/tests/fail/match/single_variant.stderr @@ -0,0 +1,13 @@ +error: Undefined Behavior: enum value has invalid tag: 0x15 + --> tests/fail/match/single_variant.rs:LL:CC + | +LL | match y { + | ^ 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 + +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/match/single_variant_uninit.rs b/src/tools/miri/tests/fail/match/single_variant_uninit.rs new file mode 100644 index 000000000000..51e8bc57c837 --- /dev/null +++ b/src/tools/miri/tests/fail/match/single_variant_uninit.rs @@ -0,0 +1,36 @@ +// Ideally, this would be UB regardless of #[non_exhaustive]. For now, +// at least the semantics don't depend on the crate you're in. +// +// See: rust-lang/rust#147722 +#![allow(dead_code)] +#![allow(unreachable_patterns)] + +#[repr(u8)] +enum Exhaustive { + A(u8) = 0, +} + +#[repr(u8)] +#[non_exhaustive] +enum NonExhaustive { + A(u8) = 0, +} + +use std::mem::MaybeUninit; + +fn main() { + let buffer: [MaybeUninit; 2] = [MaybeUninit::uninit(), MaybeUninit::new(0u8)]; + let exh: *const Exhaustive = (&raw const buffer).cast(); + let nexh: *const NonExhaustive = (&raw const buffer).cast(); + unsafe { + match *exh { + Exhaustive::A(ref _val) => {} + _ => {} + } + + match *nexh { //~ ERROR: memory is uninitialized + NonExhaustive::A(ref _val) => {} + _ => {} + } + } +} diff --git a/src/tools/miri/tests/fail/match/single_variant_uninit.stderr b/src/tools/miri/tests/fail/match/single_variant_uninit.stderr new file mode 100644 index 000000000000..fa8e9babae60 --- /dev/null +++ b/src/tools/miri/tests/fail/match/single_variant_uninit.stderr @@ -0,0 +1,18 @@ +error: Undefined Behavior: reading memory at ALLOC[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory + --> tests/fail/match/single_variant_uninit.rs:LL:CC + | +LL | match *nexh { + | ^^^^^ 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 + +Uninitialized memory occurred at ALLOC[0x0..0x1], in this allocation: +ALLOC (stack variable, size: 2, align: 1) { + __ 00 │ ░. +} + +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/tests/codegen-llvm/enum/enum-transparent-extract.rs b/tests/codegen-llvm/enum/enum-transparent-extract.rs index 1435e6ec8022..1a05b236abfb 100644 --- a/tests/codegen-llvm/enum/enum-transparent-extract.rs +++ b/tests/codegen-llvm/enum/enum-transparent-extract.rs @@ -11,6 +11,8 @@ pub enum Never {} pub fn make_unmake_result_never(x: i32) -> i32 { // CHECK-LABEL: define i32 @make_unmake_result_never(i32{{( signext)?}} %x) // CHECK: start: + // CHECK-NEXT: br label %[[next:bb.*]] + // CHECK: [[next]]: // CHECK-NEXT: ret i32 %x let y: Result = Ok(x); @@ -22,6 +24,8 @@ pub fn make_unmake_result_never(x: i32) -> i32 { pub fn extract_control_flow_never(x: ControlFlow<&str, Never>) -> &str { // CHECK-LABEL: define { ptr, i64 } @extract_control_flow_never(ptr align 1 %x.0, i64 %x.1) // CHECK: start: + // CHECK-NEXT: br label %[[next:bb.*]] + // CHECK: [[next]]: // CHECK-NEXT: %[[P0:.+]] = insertvalue { ptr, i64 } poison, ptr %x.0, 0 // CHECK-NEXT: %[[P1:.+]] = insertvalue { ptr, i64 } %[[P0]], i64 %x.1, 1 // CHECK-NEXT: ret { ptr, i64 } %[[P1]] diff --git a/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir index bba4d9c0149a..78356a90743a 100644 --- a/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/never_patterns.opt1.SimplifyCfg-initial.after.mir @@ -13,17 +13,17 @@ fn opt1(_1: &Result) -> &u32 { bb0: { PlaceMention(_1); - falseEdge -> [real: bb4, imaginary: bb1]; + _2 = discriminant((*_1)); + switchInt(move _2) -> [0: bb2, 1: bb3, otherwise: bb1]; } bb1: { - _2 = discriminant((*_1)); - switchInt(move _2) -> [1: bb3, otherwise: bb2]; + FakeRead(ForMatchedPlace(None), _1); + unreachable; } bb2: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; + falseEdge -> [real: bb4, imaginary: bb3]; } bb3: { diff --git a/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir index fc0769d6f7dc..979fbb2860dc 100644 --- a/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/never_patterns.opt2.SimplifyCfg-initial.after.mir @@ -11,10 +11,25 @@ fn opt2(_1: &Result) -> &u32 { bb0: { PlaceMention(_1); + _2 = discriminant((*_1)); + switchInt(move _2) -> [0: bb2, 1: bb3, otherwise: bb1]; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb2: { StorageLive(_3); _3 = &(((*_1) as Ok).0: u32); _0 = &(*_3); StorageDead(_3); return; } + + bb3: { + FakeRead(ForMatchedPlace(None), (((*_1) as Err).0: Void)); + unreachable; + } } diff --git a/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir index 86347db4d92e..93ebe600b3ff 100644 --- a/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/never_patterns.opt3.SimplifyCfg-initial.after.mir @@ -12,19 +12,24 @@ fn opt3(_1: &Result) -> &u32 { bb0: { PlaceMention(_1); _2 = discriminant((*_1)); - switchInt(move _2) -> [1: bb2, otherwise: bb1]; + switchInt(move _2) -> [0: bb3, 1: bb2, otherwise: bb1]; } bb1: { - StorageLive(_3); - _3 = &(((*_1) as Ok).0: u32); - _0 = &(*_3); - StorageDead(_3); - return; + FakeRead(ForMatchedPlace(None), _1); + unreachable; } bb2: { FakeRead(ForMatchedPlace(None), (((*_1) as Err).0: Void)); unreachable; } + + bb3: { + StorageLive(_3); + _3 = &(((*_1) as Ok).0: u32); + _0 = &(*_3); + StorageDead(_3); + return; + } } diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff index 97b8d484194f..9630f4001494 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff @@ -16,8 +16,10 @@ debug residual => _6; scope 2 { scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { - let _14: i32; - let mut _15: i32; + let mut _14: isize; + let _15: i32; + let mut _16: i32; + let mut _17: bool; scope 9 { scope 10 (inlined >::from) { } @@ -74,10 +76,17 @@ StorageLive(_8); _8 = copy _6; StorageLive(_14); - _14 = move ((_8 as Err).0: i32); StorageLive(_15); - _15 = move _14; - _0 = Result::::Err(move _15); + StorageLive(_17); + _14 = discriminant(_8); + _17 = Eq(copy _14, const 1_isize); + assume(move _17); + _15 = move ((_8 as Err).0: i32); + StorageLive(_16); + _16 = move _15; + _0 = Result::::Err(move _16); + StorageDead(_16); + StorageDead(_17); StorageDead(_15); StorageDead(_14); StorageDead(_8); diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff index 97b8d484194f..9630f4001494 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff @@ -16,8 +16,10 @@ debug residual => _6; scope 2 { scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { - let _14: i32; - let mut _15: i32; + let mut _14: isize; + let _15: i32; + let mut _16: i32; + let mut _17: bool; scope 9 { scope 10 (inlined >::from) { } @@ -74,10 +76,17 @@ StorageLive(_8); _8 = copy _6; StorageLive(_14); - _14 = move ((_8 as Err).0: i32); StorageLive(_15); - _15 = move _14; - _0 = Result::::Err(move _15); + StorageLive(_17); + _14 = discriminant(_8); + _17 = Eq(copy _14, const 1_isize); + assume(move _17); + _15 = move ((_8 as Err).0: i32); + StorageLive(_16); + _16 = move _15; + _0 = Result::::Err(move _16); + StorageDead(_16); + StorageDead(_17); StorageDead(_15); StorageDead(_14); StorageDead(_8); diff --git a/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.PreCodegen.after.mir index b921b96966b2..ef7ccfa5bddf 100644 --- a/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.PreCodegen.after.mir @@ -3,56 +3,66 @@ fn map_via_question_mark(_1: Option) -> Option { debug x => _1; let mut _0: std::option::Option; - let mut _4: std::ops::ControlFlow, i32>; - let _5: i32; - let mut _6: i32; + let mut _4: std::option::Option; + let mut _7: std::ops::ControlFlow, i32>; + let _8: i32; + let mut _9: i32; scope 1 { debug residual => const Option::::None; scope 2 { scope 7 (inlined as FromResidual>>::from_residual) { + let mut _3: isize; + let mut _5: bool; } } } scope 3 { - debug val => _5; + debug val => _8; scope 4 { } } scope 5 (inlined as Try>::branch) { let mut _2: isize; - let _3: i32; + let _6: i32; scope 6 { } } bb0: { - StorageLive(_6); - StorageLive(_4); + StorageLive(_9); + StorageLive(_7); StorageLive(_2); - StorageLive(_3); + StorageLive(_6); _2 = discriminant(_1); switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; } bb1: { - StorageDead(_3); - StorageDead(_2); - _0 = const Option::::None; StorageDead(_6); - StorageDead(_4); + StorageDead(_2); + StorageLive(_3); + StorageLive(_5); + _3 = discriminant(_4); + _5 = Eq(copy _3, const 0_isize); + assume(move _5); + _0 = const Option::::None; + StorageDead(_5); + StorageDead(_3); + StorageDead(_9); + StorageDead(_7); goto -> bb3; } bb2: { - _3 = copy ((_1 as Some).0: i32); - _4 = ControlFlow::, i32>::Continue(copy _3); - StorageDead(_3); - StorageDead(_2); - _5 = copy ((_4 as Continue).0: i32); - _6 = Add(copy _5, const 1_i32); - _0 = Option::::Some(move _6); + _6 = copy ((_1 as Some).0: i32); + _7 = ControlFlow::, i32>::Continue(copy _6); StorageDead(_6); - StorageDead(_4); + StorageDead(_2); + _8 = copy ((_7 as Continue).0: i32); + _9 = Add(copy _8, const 1_i32); + _0 = Option::::Some(move _9); + StorageDead(_9); + StorageDead(_7); goto -> bb3; } diff --git a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff index 34f451fc698c..10ad4ec75414 100644 --- a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff +++ b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff @@ -12,7 +12,9 @@ debug residual => _4; scope 2 { scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { - let _10: i32; + let mut _10: isize; + let _11: i32; + let mut _12: bool; scope 9 { scope 10 (inlined >::from) { } @@ -58,8 +60,15 @@ bb3: { _4 = copy ((_2 as Break).0: std::result::Result); - _10 = copy ((_4 as Err).0: i32); - _0 = Result::::Err(copy _10); + StorageLive(_10); + StorageLive(_12); + _10 = discriminant(_4); + _12 = Eq(copy _10, const 1_isize); + assume(move _12); + _11 = copy ((_4 as Err).0: i32); + _0 = Result::::Err(copy _11); + StorageDead(_12); + StorageDead(_10); StorageDead(_2); return; } diff --git a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff index 17ddce0cdf8d..8c3b8ad9b66a 100644 --- a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff +++ b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-abort.diff @@ -19,19 +19,23 @@ bb1: { _2 = discriminant(_1); -- switchInt(move _2) -> [1: bb3, otherwise: bb2]; -+ _5 = Ne(copy _2, const 1_isize); +- switchInt(move _2) -> [0: bb3, 1: bb4, otherwise: bb2]; ++ _5 = Eq(copy _2, const 0_isize); + assume(move _5); -+ goto -> bb2; ++ goto -> bb3; } bb2: { + unreachable; + } + + bb3: { _0 = const (); StorageDead(_1); return; } - bb3: { + bb4: { - StorageLive(_3); - _3 = move ((_1 as Some).0: Empty); - StorageLive(_4); diff --git a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff index 2f78092f5bd2..98f2a0a692ff 100644 --- a/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff +++ b/tests/mir-opt/unreachable.as_match.UnreachablePropagation.panic-unwind.diff @@ -19,19 +19,23 @@ bb1: { _2 = discriminant(_1); -- switchInt(move _2) -> [1: bb3, otherwise: bb2]; -+ _5 = Ne(copy _2, const 1_isize); +- switchInt(move _2) -> [0: bb3, 1: bb4, otherwise: bb2]; ++ _5 = Eq(copy _2, const 0_isize); + assume(move _5); -+ goto -> bb2; ++ goto -> bb3; } bb2: { + unreachable; + } + + bb3: { _0 = const (); StorageDead(_1); return; } - bb3: { + bb4: { - StorageLive(_3); - _3 = move ((_1 as Some).0: Empty); - StorageLive(_4); diff --git a/tests/mir-opt/unreachable.rs b/tests/mir-opt/unreachable.rs index afab1291fc3d..97cd15b107c1 100644 --- a/tests/mir-opt/unreachable.rs +++ b/tests/mir-opt/unreachable.rs @@ -45,7 +45,7 @@ fn as_match() { // CHECK: bb0: { // CHECK: {{_.*}} = empty() // CHECK: bb1: { - // CHECK: [[eq:_.*]] = Ne({{.*}}, const 1_isize); + // CHECK: [[eq:_.*]] = Eq({{.*}}, const 0_isize); // CHECK-NEXT: assume(move [[eq]]); // CHECK-NEXT: goto -> [[return:bb.*]]; // CHECK: [[return]]: { diff --git a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff index c24bd7e7446d..befee026d6cb 100644 --- a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff +++ b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff @@ -14,40 +14,40 @@ StorageLive(_2); _2 = Test1::C; _3 = discriminant(_2); -- switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; -+ switchInt(move _3) -> [0: bb5, 1: bb5, 2: bb1, otherwise: bb5]; +- switchInt(move _3) -> [0: bb4, 1: bb3, 2: bb2, otherwise: bb1]; ++ switchInt(move _3) -> [0: bb1, 1: bb1, 2: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_5); _5 = const "C"; _1 = &(*_5); StorageDead(_5); - goto -> bb4; + goto -> bb5; } - bb2: { + bb3: { StorageLive(_4); _4 = const "B(Empty)"; _1 = &(*_4); StorageDead(_4); - goto -> bb4; - } - - bb3: { - _1 = const "A(Empty)"; - goto -> bb4; + goto -> bb5; } bb4: { + _1 = const "A(Empty)"; + goto -> bb5; + } + + bb5: { StorageDead(_2); StorageDead(_1); _0 = const (); return; -+ } -+ -+ bb5: { -+ unreachable; } } diff --git a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff index c24bd7e7446d..befee026d6cb 100644 --- a/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff +++ b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff @@ -14,40 +14,40 @@ StorageLive(_2); _2 = Test1::C; _3 = discriminant(_2); -- switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1]; -+ switchInt(move _3) -> [0: bb5, 1: bb5, 2: bb1, otherwise: bb5]; +- switchInt(move _3) -> [0: bb4, 1: bb3, 2: bb2, otherwise: bb1]; ++ switchInt(move _3) -> [0: bb1, 1: bb1, 2: bb2, otherwise: bb1]; } bb1: { + unreachable; + } + + bb2: { StorageLive(_5); _5 = const "C"; _1 = &(*_5); StorageDead(_5); - goto -> bb4; + goto -> bb5; } - bb2: { + bb3: { StorageLive(_4); _4 = const "B(Empty)"; _1 = &(*_4); StorageDead(_4); - goto -> bb4; - } - - bb3: { - _1 = const "A(Empty)"; - goto -> bb4; + goto -> bb5; } bb4: { + _1 = const "A(Empty)"; + goto -> bb5; + } + + bb5: { StorageDead(_2); StorageDead(_1); _0 = const (); return; -+ } -+ -+ bb5: { -+ unreachable; } } diff --git a/tests/ui/match/borrowck-uninhabited.rs b/tests/ui/match/borrowck-uninhabited.rs index 93838ede2793..34f5e323a91e 100644 --- a/tests/ui/match/borrowck-uninhabited.rs +++ b/tests/ui/match/borrowck-uninhabited.rs @@ -17,9 +17,11 @@ fn both_inhabited(x: &mut Result) { }; } +// this used to be accepted, even though it shouldn't fn ref_uninhabited(x: &mut Result) { match x { &mut Ok(ref mut y) => match x { + //~^ ERROR: cannot use `*x` because it was mutably borrowed &mut Err(ref mut z) => { let _y = y; let _z = z; diff --git a/tests/ui/match/borrowck-uninhabited.stderr b/tests/ui/match/borrowck-uninhabited.stderr index ee3b814da9f4..4bbe6ecea16b 100644 --- a/tests/ui/match/borrowck-uninhabited.stderr +++ b/tests/ui/match/borrowck-uninhabited.stderr @@ -9,6 +9,17 @@ LL | &mut Ok(ref mut y) => match x { LL | let _y = y; | - borrow later used here -error: aborting due to 1 previous error +error[E0503]: cannot use `*x` because it was mutably borrowed + --> $DIR/borrowck-uninhabited.rs:23:37 + | +LL | &mut Ok(ref mut y) => match x { + | --------- ^ use of borrowed `x.0` + | | + | `x.0` is borrowed here +... +LL | let _y = y; + | - borrow later used here + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0503`. diff --git a/tests/ui/match/uninhabited-granular-moves.rs b/tests/ui/match/uninhabited-granular-moves.rs index 9d04fcb3259e..f836aedbebc7 100644 --- a/tests/ui/match/uninhabited-granular-moves.rs +++ b/tests/ui/match/uninhabited-granular-moves.rs @@ -17,7 +17,7 @@ fn test1(thefoo: Foo<(Box, Box)>) { Foo::Bar((a, _)) => { } } - match thefoo { + match thefoo { //~ ERROR: use of partially moved value: `thefoo` Foo::Bar((_, a)) => { } } } @@ -38,7 +38,7 @@ fn test3(thefoo: Foo<(Box, Box)>) { Foo::Bar((a, _)) => { } Foo::Qux(_) => { } } - match thefoo { + match thefoo { //~ ERROR: use of partially moved value: `thefoo` Foo::Bar((_, a)) => { } } } diff --git a/tests/ui/match/uninhabited-granular-moves.stderr b/tests/ui/match/uninhabited-granular-moves.stderr index d32f935d3d55..e3a66db526d4 100644 --- a/tests/ui/match/uninhabited-granular-moves.stderr +++ b/tests/ui/match/uninhabited-granular-moves.stderr @@ -1,3 +1,18 @@ +error[E0382]: use of partially moved value: `thefoo` + --> $DIR/uninhabited-granular-moves.rs:20:11 + | +LL | Foo::Bar((a, _)) => { } + | - value partially moved here +... +LL | match thefoo { + | ^^^^^^ value used here after partial move + | + = note: partial move occurs because value has type `Box`, which does not implement the `Copy` trait +help: borrow this binding in the pattern to avoid moving the value + | +LL | Foo::Bar((ref a, _)) => { } + | +++ + error[E0382]: use of partially moved value: `thefoo` --> $DIR/uninhabited-granular-moves.rs:30:11 | @@ -13,6 +28,21 @@ help: borrow this binding in the pattern to avoid moving the value LL | Foo::Bar((ref a, _)) => { } | +++ -error: aborting due to 1 previous error +error[E0382]: use of partially moved value: `thefoo` + --> $DIR/uninhabited-granular-moves.rs:41:11 + | +LL | Foo::Bar((a, _)) => { } + | - value partially moved here +... +LL | match thefoo { + | ^^^^^^ value used here after partial move + | + = note: partial move occurs because value has type `Box`, which does not implement the `Copy` trait +help: borrow this binding in the pattern to avoid moving the value + | +LL | Foo::Bar((ref a, _)) => { } + | +++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-exhaustive.rs index b2ebab382bd9..2e40819d69ad 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-exhaustive.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-exhaustive.rs @@ -14,11 +14,6 @@ enum Local { Variant(u32), } -#[non_exhaustive] -enum LocalNonExhaustive { - Variant(u32), -} - fn main() { let mut x = ExhaustiveMonovariant::Variant(1); let y = &mut x; @@ -34,11 +29,4 @@ fn main() { _ => {}, } drop(y); - let mut x = LocalNonExhaustive::Variant(1); - let y = &mut x; - match x { - LocalNonExhaustive::Variant(_) => {}, - _ => {}, - } - drop(y); } diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs index d616f5e5e89a..a6a369e92a6c 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs @@ -6,6 +6,11 @@ extern crate monovariants; use monovariants::NonExhaustiveMonovariant; +#[non_exhaustive] +enum LocalNonExhaustive { + Variant(u32), +} + fn main() { let mut x = NonExhaustiveMonovariant::Variant(1); let y = &mut x; @@ -15,4 +20,11 @@ fn main() { _ => {}, } drop(y); + let mut x = LocalNonExhaustive::Variant(1); + let y = &mut x; + match x { //~ ERROR cannot use `x` because it was mutably borrowed + LocalNonExhaustive::Variant(_) => {}, + _ => {}, + } + drop(y); } diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr index 70f5b2b84d86..d6225adc95cb 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr @@ -1,5 +1,5 @@ error[E0503]: cannot use `x` because it was mutably borrowed - --> $DIR/borrowck-non-exhaustive.rs:12:11 + --> $DIR/borrowck-non-exhaustive.rs:17:11 | LL | let y = &mut x; | ------ `x` is borrowed here @@ -9,6 +9,17 @@ LL | match x { LL | drop(y); | - borrow later used here -error: aborting due to 1 previous error +error[E0503]: cannot use `x` because it was mutably borrowed + --> $DIR/borrowck-non-exhaustive.rs:25:11 + | +LL | let y = &mut x; + | ------ `x` is borrowed here +LL | match x { + | ^ use of borrowed `x` +... +LL | drop(y); + | - borrow later used here + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0503`. From d194795f142639a7155ce82422f47fc56c53ed4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 15 Jan 2026 19:32:39 +0000 Subject: [PATCH 2174/3801] Do not recover from `Trait()` if generic list is unterminated If we encounter `fn foo`), we bail from the recovery as more likely there could have been a missing closing `>` and the `(` corresponds to the start of the fn parameter list. --- compiler/rustc_parse/src/parser/generics.rs | 13 ++++- compiler/rustc_parse/src/parser/mod.rs | 3 ++ compiler/rustc_parse/src/parser/ty.rs | 47 +++++++++++++++++-- .../missing-closing-generics-bracket.fixed | 10 ++++ .../missing-closing-generics-bracket.rs | 10 ++++ .../missing-closing-generics-bracket.stderr | 13 +++++ 6 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 tests/ui/parser/missing-closing-generics-bracket.fixed create mode 100644 tests/ui/parser/missing-closing-generics-bracket.rs create mode 100644 tests/ui/parser/missing-closing-generics-bracket.stderr diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index ef6c9cc344ce..8c02092fd678 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -204,9 +204,11 @@ impl<'a> Parser<'a> { pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec> { let mut params = ThinVec::new(); let mut done = false; + let prev = self.parsing_generics; + self.parsing_generics = true; while !done { let attrs = self.parse_outer_attributes()?; - let param = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { + let param = match self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { if this.eat_keyword_noexpect(kw::SelfUpper) { // `Self` as a generic param is invalid. Here we emit the diagnostic and continue parsing // as if `Self` never existed. @@ -288,7 +290,13 @@ impl<'a> Parser<'a> { } // We just ate the comma, so no need to capture the trailing token. Ok((param, Trailing::No, UsePreAttrPos::No)) - })?; + }) { + Ok(param) => param, + Err(err) => { + self.parsing_generics = prev; + return Err(err); + } + }; if let Some(param) = param { params.push(param); @@ -296,6 +304,7 @@ impl<'a> Parser<'a> { break; } } + self.parsing_generics = prev; Ok(params) } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index d6e99bc540f7..ca2048d07147 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -212,6 +212,8 @@ pub struct Parser<'a> { /// See the comments in the `parse_path_segment` function for more details. unmatched_angle_bracket_count: u16, angle_bracket_nesting: u16, + /// Keep track of when we're within `<...>` for proper error recovery. + parsing_generics: bool = false, last_unexpected_token_span: Option, /// If present, this `Parser` is not parsing Rust code but rather a macro call. @@ -372,6 +374,7 @@ impl<'a> Parser<'a> { }, current_closure: None, recovery: Recovery::Allowed, + .. }; // Make parser point to the first token. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 0185c51c5c56..380b6a214846 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -1488,14 +1488,44 @@ impl<'a> Parser<'a> { return Ok(()); } + let snapshot = if self.parsing_generics { + // The snapshot is only relevant if we're parsing the generics of an `fn` to avoid + // incorrect recovery. + Some(self.create_snapshot_for_diagnostic()) + } else { + None + }; // Parse `(T, U) -> R`. let inputs_lo = self.token.span; let mode = FnParseMode { req_name: |_, _| false, context: FnContext::Free, req_body: false }; - let inputs: ThinVec<_> = - self.parse_fn_params(&mode)?.into_iter().map(|input| input.ty).collect(); + let params = match self.parse_fn_params(&mode) { + Ok(params) => params, + Err(err) => { + if let Some(snapshot) = snapshot { + self.restore_snapshot(snapshot); + err.cancel(); + return Ok(()); + } else { + return Err(err); + } + } + }; + let inputs: ThinVec<_> = params.into_iter().map(|input| input.ty).collect(); let inputs_span = inputs_lo.to(self.prev_token.span); - let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?; + let output = match self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No) + { + Ok(output) => output, + Err(err) => { + if let Some(snapshot) = snapshot { + self.restore_snapshot(snapshot); + err.cancel(); + return Ok(()); + } else { + return Err(err); + } + } + }; let args = ast::ParenthesizedArgs { span: fn_path_segment.span().to(self.prev_token.span), inputs, @@ -1503,6 +1533,17 @@ impl<'a> Parser<'a> { output, } .into(); + + if let Some(snapshot) = snapshot + && ![token::Comma, token::Gt, token::Plus].contains(&self.token.kind) + { + // We would expect another bound or the end of type params by now. Most likely we've + // encountered a `(` *not* representing `Trait()`, but rather the start of the `fn`'s + // argument list where the generic param list wasn't properly closed. + self.restore_snapshot(snapshot); + return Ok(()); + } + *fn_path_segment = ast::PathSegment { ident: fn_path_segment.ident, args: Some(args), diff --git a/tests/ui/parser/missing-closing-generics-bracket.fixed b/tests/ui/parser/missing-closing-generics-bracket.fixed new file mode 100644 index 000000000000..3166887fa8c3 --- /dev/null +++ b/tests/ui/parser/missing-closing-generics-bracket.fixed @@ -0,0 +1,10 @@ +// Issue #141436 +//@ run-rustfix +#![allow(dead_code)] + +trait Trait<'a> {} + +fn foo>() {} +//~^ ERROR expected one of + +fn main() {} diff --git a/tests/ui/parser/missing-closing-generics-bracket.rs b/tests/ui/parser/missing-closing-generics-bracket.rs new file mode 100644 index 000000000000..9424e3467246 --- /dev/null +++ b/tests/ui/parser/missing-closing-generics-bracket.rs @@ -0,0 +1,10 @@ +// Issue #141436 +//@ run-rustfix +#![allow(dead_code)] + +trait Trait<'a> {} + +fn foo() {} +//~^ ERROR expected one of + +fn main() {} diff --git a/tests/ui/parser/missing-closing-generics-bracket.stderr b/tests/ui/parser/missing-closing-generics-bracket.stderr new file mode 100644 index 000000000000..c4287301c595 --- /dev/null +++ b/tests/ui/parser/missing-closing-generics-bracket.stderr @@ -0,0 +1,13 @@ +error: expected one of `+`, `,`, `::`, `=`, or `>`, found `(` + --> $DIR/missing-closing-generics-bracket.rs:7:25 + | +LL | fn foo() {} + | ^ expected one of `+`, `,`, `::`, `=`, or `>` + | +help: you might have meant to end the type parameters here + | +LL | fn foo>() {} + | + + +error: aborting due to 1 previous error + From 3df0dc880376ef16076851046c40f2ad7374b63c Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 10 Jan 2026 14:21:33 +0100 Subject: [PATCH 2175/3801] mark rust_dealloc as captures(address) Co-authored-by: Ralf Jung --- compiler/rustc_codegen_llvm/src/attributes.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index a25ce9e5a90a..bf6bb81b53b0 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -517,7 +517,16 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( to_add.push(llvm::CreateAllocKindAttr(cx.llcx, AllocKindFlags::Free)); // applies to argument place instead of function place let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx); - attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]); + let attrs: &[_] = if llvm_util::get_version() >= (21, 0, 0) { + // "Does not capture provenance" means "if the function call stashes the pointer somewhere, + // accessing that pointer after the function returns is UB". That is definitely the case here since + // freeing will destroy the provenance. + let captures_addr = AttributeKind::CapturesAddress.create_attr(cx.llcx); + &[allocated_pointer, captures_addr] + } else { + &[allocated_pointer] + }; + attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), attrs); } if let Some(align) = codegen_fn_attrs.alignment { llvm::set_alignment(llfn, align); From c6c4372f8231bab89007267c23a42e35b177578b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 15 Jan 2026 19:46:54 +0000 Subject: [PATCH 2176/3801] Use default field values in `Parser` --- compiler/rustc_ast/src/token.rs | 4 +- compiler/rustc_parse/src/parser/mod.rs | 39 +++++++------------ compiler/rustc_parse/src/parser/token_type.rs | 2 +- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index accf4d181632..e0807dbceee4 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -625,12 +625,12 @@ impl TokenKind { } impl Token { - pub fn new(kind: TokenKind, span: Span) -> Self { + pub const fn new(kind: TokenKind, span: Span) -> Self { Token { kind, span } } /// Some token that will be thrown away later. - pub fn dummy() -> Self { + pub const fn dummy() -> Self { Token::new(TokenKind::Question, DUMMY_SP) } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index ca2048d07147..4145cd5727dc 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -175,17 +175,17 @@ pub enum Recovery { pub struct Parser<'a> { pub psess: &'a ParseSess, /// The current token. - pub token: Token, + pub token: Token = Token::dummy(), /// The spacing for the current token. - token_spacing: Spacing, + token_spacing: Spacing = Spacing::Alone, /// The previous token. - pub prev_token: Token, - pub capture_cfg: bool, - restrictions: Restrictions, - expected_token_types: TokenTypeSet, + pub prev_token: Token = Token::dummy(), + pub capture_cfg: bool = false, + restrictions: Restrictions = Restrictions::empty(), + expected_token_types: TokenTypeSet = TokenTypeSet::new(), token_cursor: TokenCursor, // The number of calls to `bump`, i.e. the position in the token stream. - num_bump_calls: u32, + num_bump_calls: u32 = 0, // During parsing we may sometimes need to "unglue" a glued token into two // or three component tokens (e.g. `>>` into `>` and `>`, or `>>=` into `>` // and `>` and `=`), so the parser can consume them one at a time. This @@ -204,27 +204,27 @@ pub struct Parser<'a> { // // This value is always 0, 1, or 2. It can only reach 2 when splitting // `>>=` or `<<=`. - break_last_token: u32, + break_last_token: u32 = 0, /// This field is used to keep track of how many left angle brackets we have seen. This is /// required in order to detect extra leading left angle brackets (`<` characters) and error /// appropriately. /// /// See the comments in the `parse_path_segment` function for more details. - unmatched_angle_bracket_count: u16, - angle_bracket_nesting: u16, + unmatched_angle_bracket_count: u16 = 0, + angle_bracket_nesting: u16 = 0, /// Keep track of when we're within `<...>` for proper error recovery. parsing_generics: bool = false, - last_unexpected_token_span: Option, + last_unexpected_token_span: Option = None, /// If present, this `Parser` is not parsing Rust code but rather a macro call. subparser_name: Option<&'static str>, capture_state: CaptureState, /// This allows us to recover when the user forget to add braces around /// multiple statements in the closure body. - current_closure: Option, + current_closure: Option = None, /// Whether the parser is allowed to do recovery. /// This is disabled when parsing macro arguments, see #103534 - recovery: Recovery, + recovery: Recovery = Recovery::Allowed, } // This type is used a lot, e.g. it's cloned when matching many declarative macro rules with @@ -353,18 +353,7 @@ impl<'a> Parser<'a> { ) -> Self { let mut parser = Parser { psess, - token: Token::dummy(), - token_spacing: Spacing::Alone, - prev_token: Token::dummy(), - capture_cfg: false, - restrictions: Restrictions::empty(), - expected_token_types: TokenTypeSet::new(), token_cursor: TokenCursor { curr: TokenTreeCursor::new(stream), stack: Vec::new() }, - num_bump_calls: 0, - break_last_token: 0, - unmatched_angle_bracket_count: 0, - angle_bracket_nesting: 0, - last_unexpected_token_span: None, subparser_name, capture_state: CaptureState { capturing: Capturing::No, @@ -372,8 +361,6 @@ impl<'a> Parser<'a> { inner_attr_parser_ranges: Default::default(), seen_attrs: IntervalSet::new(u32::MAX as usize), }, - current_closure: None, - recovery: Recovery::Allowed, .. }; diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs index e5dda7cf9104..567b1be5e5d9 100644 --- a/compiler/rustc_parse/src/parser/token_type.rs +++ b/compiler/rustc_parse/src/parser/token_type.rs @@ -585,7 +585,7 @@ macro_rules! exp { pub(super) struct TokenTypeSet(u128); impl TokenTypeSet { - pub(super) fn new() -> TokenTypeSet { + pub(super) const fn new() -> TokenTypeSet { TokenTypeSet(0) } From b4781c8fe9f97b582b44d615d2edf2bb114f1f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 15 Jan 2026 20:39:14 +0000 Subject: [PATCH 2177/3801] Use default field values in a few more cases Makes the use expressions significantly shorter. --- .../src/diagnostics/conflict_errors.rs | 48 ++++++------------- compiler/rustc_borrowck/src/lib.rs | 1 + .../rustc_hir_analysis/src/hir_wf_check.rs | 18 ++----- compiler/rustc_hir_analysis/src/lib.rs | 1 + 4 files changed, 22 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 5cfe9db009bf..1b1c72394e75 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2312,12 +2312,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { tcx: TyCtxt<'hir>, issue_span: Span, expr_span: Span, - body_expr: Option<&'hir hir::Expr<'hir>>, - loop_bind: Option<&'hir Ident>, - loop_span: Option, - head_span: Option, - pat_span: Option, - head: Option<&'hir hir::Expr<'hir>>, + body_expr: Option<&'hir hir::Expr<'hir>> = None, + loop_bind: Option<&'hir Ident> = None, + loop_span: Option = None, + head_span: Option = None, + pat_span: Option = None, + head: Option<&'hir hir::Expr<'hir>> = None, } impl<'hir> Visitor<'hir> for ExprFinder<'hir> { fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { @@ -2383,17 +2383,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { hir::intravisit::walk_expr(self, ex); } } - let mut finder = ExprFinder { - tcx, - expr_span: span, - issue_span, - loop_bind: None, - body_expr: None, - head_span: None, - loop_span: None, - pat_span: None, - head: None, - }; + let mut finder = ExprFinder { tcx, expr_span: span, issue_span, .. }; finder.visit_expr(tcx.hir_body(body_id).value); if let Some(body_expr) = finder.body_expr @@ -2628,13 +2618,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { struct ExpressionFinder<'tcx> { capture_span: Span, - closure_change_spans: Vec, - closure_arg_span: Option, - in_closure: bool, - suggest_arg: String, + closure_change_spans: Vec = vec![], + closure_arg_span: Option = None, + in_closure: bool = false, + suggest_arg: String = String::new(), tcx: TyCtxt<'tcx>, - closure_local_id: Option, - closure_call_changes: Vec<(Span, String)>, + closure_local_id: Option = None, + closure_call_changes: Vec<(Span, String)> = vec![], } impl<'hir> Visitor<'hir> for ExpressionFinder<'hir> { fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) { @@ -2715,16 +2705,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }) = self.infcx.tcx.hir_node(self.mir_hir_id()) && let hir::Node::Expr(expr) = self.infcx.tcx.hir_node(body_id.hir_id) { - let mut finder = ExpressionFinder { - capture_span: *capture_kind_span, - closure_change_spans: vec![], - closure_arg_span: None, - in_closure: false, - suggest_arg: String::new(), - closure_local_id: None, - closure_call_changes: vec![], - tcx: self.infcx.tcx, - }; + let mut finder = + ExpressionFinder { capture_span: *capture_kind_span, tcx: self.infcx.tcx, .. }; finder.visit_expr(expr); if finder.closure_change_spans.is_empty() || finder.closure_call_changes.is_empty() { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 91defbad0a0e..f2ea8cef192e 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -4,6 +4,7 @@ #![allow(internal_features)] #![feature(assert_matches)] #![feature(box_patterns)] +#![feature(default_field_values)] #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(negative_impls)] diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index f879153c5765..d414f4dbcc24 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -51,12 +51,12 @@ pub(super) fn diagnostic_hir_wf_check<'tcx>( struct HirWfCheck<'tcx> { tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>, - cause: Option>, - cause_depth: usize, + cause: Option> = None, + cause_depth: usize = 0, icx: ItemCtxt<'tcx>, def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, - depth: usize, + depth: usize = 0, } impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> { @@ -124,16 +124,8 @@ pub(super) fn diagnostic_hir_wf_check<'tcx>( } } - let mut visitor = HirWfCheck { - tcx, - predicate, - cause: None, - cause_depth: 0, - icx, - def_id, - param_env: tcx.param_env(def_id.to_def_id()), - depth: 0, - }; + let param_env = tcx.param_env(def_id.to_def_id()); + let mut visitor = HirWfCheck { tcx, predicate, icx, def_id, param_env, .. }; // Get the starting `hir::Ty` using our `WellFormedLoc`. // We will walk 'into' this type to try to find diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index a51355adf72f..95f0e641c611 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -59,6 +59,7 @@ This API is completely unstable and subject to change. #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![feature(assert_matches)] +#![feature(default_field_values)] #![feature(gen_blocks)] #![feature(if_let_guard)] #![feature(iter_intersperse)] From 9750d22c17092fa747e088ae24bb749077edefa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Jan 2026 21:13:48 +0000 Subject: [PATCH 2178/3801] Silence unused type param and inference errors on struct parse error --- compiler/rustc_hir/src/hir.rs | 20 +++++++++++++++ .../rustc_hir_analysis/src/check/wfcheck.rs | 7 +++++- .../error_reporting/infer/need_type_info.rs | 25 ++++++++++++++++++- .../structs/parse-error-with-type-param.fixed | 14 +++++++++++ .../ui/structs/parse-error-with-type-param.rs | 14 +++++++++++ .../parse-error-with-type-param.stderr | 18 +++++++++++++ 6 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 tests/ui/structs/parse-error-with-type-param.fixed create mode 100644 tests/ui/structs/parse-error-with-type-param.rs create mode 100644 tests/ui/structs/parse-error-with-type-param.stderr diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index dac4c7e3965a..b296522749f0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4525,6 +4525,26 @@ impl ItemKind<'_> { _ => return None, }) } + + pub fn recovered(&self) -> bool { + match self { + ItemKind::Struct( + _, + _, + VariantData::Struct { recovered: ast::Recovered::Yes(_), .. }, + ) => true, + ItemKind::Union( + _, + _, + VariantData::Struct { recovered: ast::Recovered::Yes(_), .. }, + ) => true, + ItemKind::Enum(_, _, def) => def.variants.iter().any(|v| match v.data { + VariantData::Struct { recovered: ast::Recovered::Yes(_), .. } => true, + _ => false, + }), + _ => false, + } + } } // The bodies for items are stored "out of line", in a separate diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index cfc7e57cc14e..8b50eceb26e4 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2160,7 +2160,12 @@ fn report_bivariance<'tcx>( const_param_help, }); diag.code(E0392); - diag.emit() + if item.kind.recovered() { + // Silence potentially redundant error, as the item had a parse error. + diag.delay_as_bug() + } else { + diag.emit() + } } /// Detects cases where an ADT/LTA is trivially cyclical -- we want to detect this so diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 0a2442b71e78..e3c8bfe4a452 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -488,7 +488,30 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } let Some(InferSource { span, kind }) = local_visitor.infer_source else { - return self.bad_inference_failure_err(failure_span, arg_data, error_code); + let silence = if let DefKind::AssocFn = self.tcx.def_kind(body_def_id) + && let parent = self.tcx.parent(body_def_id.into()) + && self.tcx.is_automatically_derived(parent) + && let Some(parent) = parent.as_local() + && let hir::Node::Item(item) = self.tcx.hir_node_by_def_id(parent) + && let hir::ItemKind::Impl(imp) = item.kind + && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = imp.self_ty.kind + && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, def_id) = path.res + && let Some(def_id) = def_id.as_local() + && let hir::Node::Item(item) = self.tcx.hir_node_by_def_id(def_id) + { + // We have encountered an inference error within an automatically derived `impl`, + // from a `#[derive(..)]` on an item that had a parse error. Because the parse + // error might have caused the expanded code to be malformed, we silence the + // inference error. + item.kind.recovered() + } else { + false + }; + let mut err = self.bad_inference_failure_err(failure_span, arg_data, error_code); + if silence { + err.downgrade_to_delayed_bug(); + } + return err; }; let (source_kind, name, long_ty_path) = kind.ty_localized_msg(self); diff --git a/tests/ui/structs/parse-error-with-type-param.fixed b/tests/ui/structs/parse-error-with-type-param.fixed new file mode 100644 index 000000000000..46d1c2722843 --- /dev/null +++ b/tests/ui/structs/parse-error-with-type-param.fixed @@ -0,0 +1,14 @@ +//@ run-rustfix +// #141403 +#![allow(dead_code)] + +#[derive(Clone)] +struct B { + a: A<(T, u32)>, // <- note, comma is missing here + /// asdf + //~^ ERROR found a documentation comment that doesn't document anything + b: u32, +} +#[derive(Clone)] +struct A(T); +fn main() {} diff --git a/tests/ui/structs/parse-error-with-type-param.rs b/tests/ui/structs/parse-error-with-type-param.rs new file mode 100644 index 000000000000..27a9fc854f57 --- /dev/null +++ b/tests/ui/structs/parse-error-with-type-param.rs @@ -0,0 +1,14 @@ +//@ run-rustfix +// #141403 +#![allow(dead_code)] + +#[derive(Clone)] +struct B { + a: A<(T, u32)> // <- note, comma is missing here + /// asdf + //~^ ERROR found a documentation comment that doesn't document anything + b: u32, +} +#[derive(Clone)] +struct A(T); +fn main() {} diff --git a/tests/ui/structs/parse-error-with-type-param.stderr b/tests/ui/structs/parse-error-with-type-param.stderr new file mode 100644 index 000000000000..d01eae193b14 --- /dev/null +++ b/tests/ui/structs/parse-error-with-type-param.stderr @@ -0,0 +1,18 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/parse-error-with-type-param.rs:8:5 + | +LL | struct B { + | - while parsing this struct +LL | a: A<(T, u32)> // <- note, comma is missing here +LL | /// asdf + | ^^^^^^^^ + | + = help: doc comments must come before what they document, if a comment was intended use `//` +help: missing comma here + | +LL | a: A<(T, u32)>, // <- note, comma is missing here + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0585`. From 559e67248921197206f009792560fa2861dd1750 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Thu, 15 Jan 2026 15:41:27 +0900 Subject: [PATCH 2179/3801] move some tests --- .../issue-50600.rs => array-slice-vec/closure-in-array-len.rs} | 0 .../closure-in-array-len.stderr} | 0 .../issue-51714.rs => array-slice-vec/return-in-array-len.rs} | 0 .../return-in-array-len.stderr} | 0 .../issue-17503.rs => array-slice-vec/slice-of-multi-ref.rs} | 0 .../issue-42453.rs => derives/derive-hygiene-struct-builder.rs} | 0 tests/ui/{issues/issue-17361.rs => dst/unsized-str-mutability.rs} | 0 .../issue-28105.rs => for-loop-while/break-outside-loop-2.rs} | 0 .../break-outside-loop-2.stderr} | 0 .../issue-22706.rs => generics/type-args-on-module-in-bound.rs} | 0 .../type-args-on-module-in-bound.stderr} | 0 .../ui/{issues/issue-28109.rs => label/undeclared-label-span.rs} | 0 .../issue-28109.stderr => label/undeclared-label-span.stderr} | 0 .../{issues/issue-43057.rs => macros/column-macro-collision.rs} | 0 .../array-repeat-unit-struct.rs} | 0 .../array-repeat-unit-struct.stderr} | 0 .../vec-hashset-type-mismatch.rs} | 0 .../vec-hashset-type-mismatch.stderr} | 0 .../issue-16725.rs => privacy/auxiliary/private-extern-fn.rs} | 0 tests/ui/{issues/issue-28433.rs => privacy/privacy-sanity-2.rs} | 0 .../issue-28433.stderr => privacy/privacy-sanity-2.stderr} | 0 .../issue-16725.rs => privacy/private-extern-fn-visibility.rs} | 0 .../private-extern-fn-visibility.stderr} | 0 .../ui/{issues/issue-22894.rs => static/static-str-deref-ref.rs} | 0 .../std-sync-right-kind-impls-2.rs} | 0 25 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-50600.rs => array-slice-vec/closure-in-array-len.rs} (100%) rename tests/ui/{issues/issue-50600.stderr => array-slice-vec/closure-in-array-len.stderr} (100%) rename tests/ui/{issues/issue-51714.rs => array-slice-vec/return-in-array-len.rs} (100%) rename tests/ui/{issues/issue-51714.stderr => array-slice-vec/return-in-array-len.stderr} (100%) rename tests/ui/{issues/issue-17503.rs => array-slice-vec/slice-of-multi-ref.rs} (100%) rename tests/ui/{issues/issue-42453.rs => derives/derive-hygiene-struct-builder.rs} (100%) rename tests/ui/{issues/issue-17361.rs => dst/unsized-str-mutability.rs} (100%) rename tests/ui/{issues/issue-28105.rs => for-loop-while/break-outside-loop-2.rs} (100%) rename tests/ui/{issues/issue-28105.stderr => for-loop-while/break-outside-loop-2.stderr} (100%) rename tests/ui/{issues/issue-22706.rs => generics/type-args-on-module-in-bound.rs} (100%) rename tests/ui/{issues/issue-22706.stderr => generics/type-args-on-module-in-bound.stderr} (100%) rename tests/ui/{issues/issue-28109.rs => label/undeclared-label-span.rs} (100%) rename tests/ui/{issues/issue-28109.stderr => label/undeclared-label-span.stderr} (100%) rename tests/ui/{issues/issue-43057.rs => macros/column-macro-collision.rs} (100%) rename tests/ui/{issues/issue-27008.rs => mismatched_types/array-repeat-unit-struct.rs} (100%) rename tests/ui/{issues/issue-27008.stderr => mismatched_types/array-repeat-unit-struct.stderr} (100%) rename tests/ui/{issues/issue-24819.rs => mismatched_types/vec-hashset-type-mismatch.rs} (100%) rename tests/ui/{issues/issue-24819.stderr => mismatched_types/vec-hashset-type-mismatch.stderr} (100%) rename tests/ui/{issues/auxiliary/issue-16725.rs => privacy/auxiliary/private-extern-fn.rs} (100%) rename tests/ui/{issues/issue-28433.rs => privacy/privacy-sanity-2.rs} (100%) rename tests/ui/{issues/issue-28433.stderr => privacy/privacy-sanity-2.stderr} (100%) rename tests/ui/{issues/issue-16725.rs => privacy/private-extern-fn-visibility.rs} (100%) rename tests/ui/{issues/issue-16725.stderr => privacy/private-extern-fn-visibility.stderr} (100%) rename tests/ui/{issues/issue-22894.rs => static/static-str-deref-ref.rs} (100%) rename tests/ui/{issues/issue-22577.rs => threads-sendsync/std-sync-right-kind-impls-2.rs} (100%) diff --git a/tests/ui/issues/issue-50600.rs b/tests/ui/array-slice-vec/closure-in-array-len.rs similarity index 100% rename from tests/ui/issues/issue-50600.rs rename to tests/ui/array-slice-vec/closure-in-array-len.rs diff --git a/tests/ui/issues/issue-50600.stderr b/tests/ui/array-slice-vec/closure-in-array-len.stderr similarity index 100% rename from tests/ui/issues/issue-50600.stderr rename to tests/ui/array-slice-vec/closure-in-array-len.stderr diff --git a/tests/ui/issues/issue-51714.rs b/tests/ui/array-slice-vec/return-in-array-len.rs similarity index 100% rename from tests/ui/issues/issue-51714.rs rename to tests/ui/array-slice-vec/return-in-array-len.rs diff --git a/tests/ui/issues/issue-51714.stderr b/tests/ui/array-slice-vec/return-in-array-len.stderr similarity index 100% rename from tests/ui/issues/issue-51714.stderr rename to tests/ui/array-slice-vec/return-in-array-len.stderr diff --git a/tests/ui/issues/issue-17503.rs b/tests/ui/array-slice-vec/slice-of-multi-ref.rs similarity index 100% rename from tests/ui/issues/issue-17503.rs rename to tests/ui/array-slice-vec/slice-of-multi-ref.rs diff --git a/tests/ui/issues/issue-42453.rs b/tests/ui/derives/derive-hygiene-struct-builder.rs similarity index 100% rename from tests/ui/issues/issue-42453.rs rename to tests/ui/derives/derive-hygiene-struct-builder.rs diff --git a/tests/ui/issues/issue-17361.rs b/tests/ui/dst/unsized-str-mutability.rs similarity index 100% rename from tests/ui/issues/issue-17361.rs rename to tests/ui/dst/unsized-str-mutability.rs diff --git a/tests/ui/issues/issue-28105.rs b/tests/ui/for-loop-while/break-outside-loop-2.rs similarity index 100% rename from tests/ui/issues/issue-28105.rs rename to tests/ui/for-loop-while/break-outside-loop-2.rs diff --git a/tests/ui/issues/issue-28105.stderr b/tests/ui/for-loop-while/break-outside-loop-2.stderr similarity index 100% rename from tests/ui/issues/issue-28105.stderr rename to tests/ui/for-loop-while/break-outside-loop-2.stderr diff --git a/tests/ui/issues/issue-22706.rs b/tests/ui/generics/type-args-on-module-in-bound.rs similarity index 100% rename from tests/ui/issues/issue-22706.rs rename to tests/ui/generics/type-args-on-module-in-bound.rs diff --git a/tests/ui/issues/issue-22706.stderr b/tests/ui/generics/type-args-on-module-in-bound.stderr similarity index 100% rename from tests/ui/issues/issue-22706.stderr rename to tests/ui/generics/type-args-on-module-in-bound.stderr diff --git a/tests/ui/issues/issue-28109.rs b/tests/ui/label/undeclared-label-span.rs similarity index 100% rename from tests/ui/issues/issue-28109.rs rename to tests/ui/label/undeclared-label-span.rs diff --git a/tests/ui/issues/issue-28109.stderr b/tests/ui/label/undeclared-label-span.stderr similarity index 100% rename from tests/ui/issues/issue-28109.stderr rename to tests/ui/label/undeclared-label-span.stderr diff --git a/tests/ui/issues/issue-43057.rs b/tests/ui/macros/column-macro-collision.rs similarity index 100% rename from tests/ui/issues/issue-43057.rs rename to tests/ui/macros/column-macro-collision.rs diff --git a/tests/ui/issues/issue-27008.rs b/tests/ui/mismatched_types/array-repeat-unit-struct.rs similarity index 100% rename from tests/ui/issues/issue-27008.rs rename to tests/ui/mismatched_types/array-repeat-unit-struct.rs diff --git a/tests/ui/issues/issue-27008.stderr b/tests/ui/mismatched_types/array-repeat-unit-struct.stderr similarity index 100% rename from tests/ui/issues/issue-27008.stderr rename to tests/ui/mismatched_types/array-repeat-unit-struct.stderr diff --git a/tests/ui/issues/issue-24819.rs b/tests/ui/mismatched_types/vec-hashset-type-mismatch.rs similarity index 100% rename from tests/ui/issues/issue-24819.rs rename to tests/ui/mismatched_types/vec-hashset-type-mismatch.rs diff --git a/tests/ui/issues/issue-24819.stderr b/tests/ui/mismatched_types/vec-hashset-type-mismatch.stderr similarity index 100% rename from tests/ui/issues/issue-24819.stderr rename to tests/ui/mismatched_types/vec-hashset-type-mismatch.stderr diff --git a/tests/ui/issues/auxiliary/issue-16725.rs b/tests/ui/privacy/auxiliary/private-extern-fn.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-16725.rs rename to tests/ui/privacy/auxiliary/private-extern-fn.rs diff --git a/tests/ui/issues/issue-28433.rs b/tests/ui/privacy/privacy-sanity-2.rs similarity index 100% rename from tests/ui/issues/issue-28433.rs rename to tests/ui/privacy/privacy-sanity-2.rs diff --git a/tests/ui/issues/issue-28433.stderr b/tests/ui/privacy/privacy-sanity-2.stderr similarity index 100% rename from tests/ui/issues/issue-28433.stderr rename to tests/ui/privacy/privacy-sanity-2.stderr diff --git a/tests/ui/issues/issue-16725.rs b/tests/ui/privacy/private-extern-fn-visibility.rs similarity index 100% rename from tests/ui/issues/issue-16725.rs rename to tests/ui/privacy/private-extern-fn-visibility.rs diff --git a/tests/ui/issues/issue-16725.stderr b/tests/ui/privacy/private-extern-fn-visibility.stderr similarity index 100% rename from tests/ui/issues/issue-16725.stderr rename to tests/ui/privacy/private-extern-fn-visibility.stderr diff --git a/tests/ui/issues/issue-22894.rs b/tests/ui/static/static-str-deref-ref.rs similarity index 100% rename from tests/ui/issues/issue-22894.rs rename to tests/ui/static/static-str-deref-ref.rs diff --git a/tests/ui/issues/issue-22577.rs b/tests/ui/threads-sendsync/std-sync-right-kind-impls-2.rs similarity index 100% rename from tests/ui/issues/issue-22577.rs rename to tests/ui/threads-sendsync/std-sync-right-kind-impls-2.rs From 77b2a196fb13a1b4c6751c9361dad7d55a0e7d9d Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Thu, 15 Jan 2026 18:34:54 +0900 Subject: [PATCH 2180/3801] cleaned up some tests merge privacy/privacy-sanity-2 with privacy/privacy-sanity.rs Add comment to generics/type-args-on-module-in-bound.rs Add comment to array-slice-vec/closure-in-array-eln.rs Add comment to array-slice-vec/return-in-array-len.rs Merge for-loop-while/break-outside-loop-2.rs with for-loop-while/break-outside-loop.rs Add comment to macros/column-macro-collision.rs Add comment to privacy/private-extern-fn-visibility.rs Add comment to mismatched_types/vec-hashset-type-mismatch.rs Merge std-sync-right-kind-impls-2.rs with std-sync-right-kind-impls.rs Add comment to array-slice-vec/slice-of-multi-ref.rs Add comment to mismatched_types\vec-hashset-type-mismatch.rs Add comment to derives/derive-hygiene-struct-builder.rs Add comment to label/undeclared-label-span.rs Add comment to label\undeclared-label-span.rs Add comment to mismatched_types/array-repeat-unit-struct.rs --- .../array-slice-vec/closure-in-array-len.rs | 3 +- .../closure-in-array-len.stderr | 4 +- .../ui/array-slice-vec/return-in-array-len.rs | 1 + .../return-in-array-len.stderr | 8 +-- .../ui/array-slice-vec/slice-of-multi-ref.rs | 1 + .../derives/derive-hygiene-struct-builder.rs | 6 +- tests/ui/dst/unsized-str-mutability.rs | 4 +- .../ui/for-loop-while/break-outside-loop-2.rs | 8 --- .../break-outside-loop-2.stderr | 15 ----- tests/ui/for-loop-while/break-outside-loop.rs | 40 ++++++++++--- .../for-loop-while/break-outside-loop.stderr | 43 +++++++++----- .../generics/type-args-on-module-in-bound.rs | 1 + .../type-args-on-module-in-bound.stderr | 2 +- tests/ui/label/undeclared-label-span.rs | 3 +- tests/ui/label/undeclared-label-span.stderr | 4 +- tests/ui/macros/column-macro-collision.rs | 3 + .../array-repeat-unit-struct.rs | 2 + .../array-repeat-unit-struct.stderr | 2 +- .../vec-hashset-type-mismatch.rs | 4 +- .../vec-hashset-type-mismatch.stderr | 6 +- tests/ui/privacy/privacy-sanity-2.rs | 12 ---- tests/ui/privacy/privacy-sanity-2.stderr | 19 ------ tests/ui/privacy/privacy-sanity.rs | 15 +++++ tests/ui/privacy/privacy-sanity.stderr | 58 ++++++++++++++----- .../privacy/private-extern-fn-visibility.rs | 11 ++-- .../private-extern-fn-visibility.stderr | 8 +-- tests/ui/static/static-str-deref-ref.rs | 1 + .../std-sync-right-kind-impls-2.rs | 25 -------- .../std-sync-right-kind-impls.rs | 18 +++++- 29 files changed, 180 insertions(+), 147 deletions(-) delete mode 100644 tests/ui/for-loop-while/break-outside-loop-2.rs delete mode 100644 tests/ui/for-loop-while/break-outside-loop-2.stderr delete mode 100644 tests/ui/privacy/privacy-sanity-2.rs delete mode 100644 tests/ui/privacy/privacy-sanity-2.stderr delete mode 100644 tests/ui/threads-sendsync/std-sync-right-kind-impls-2.rs diff --git a/tests/ui/array-slice-vec/closure-in-array-len.rs b/tests/ui/array-slice-vec/closure-in-array-len.rs index 963e607afcfd..ce13e0f16081 100644 --- a/tests/ui/array-slice-vec/closure-in-array-len.rs +++ b/tests/ui/array-slice-vec/closure-in-array-len.rs @@ -1,4 +1,5 @@ -struct Foo ( +//! regression test for +struct Foo( fn([u8; |x: u8| {}]), //~ ERROR mismatched types ); diff --git a/tests/ui/array-slice-vec/closure-in-array-len.stderr b/tests/ui/array-slice-vec/closure-in-array-len.stderr index e3ae7f144c35..decdde042c6f 100644 --- a/tests/ui/array-slice-vec/closure-in-array-len.stderr +++ b/tests/ui/array-slice-vec/closure-in-array-len.stderr @@ -1,11 +1,11 @@ error[E0308]: mismatched types - --> $DIR/issue-50600.rs:2:13 + --> $DIR/closure-in-array-len.rs:3:13 | LL | fn([u8; |x: u8| {}]), | ^^^^^^^^^^ expected `usize`, found closure | = note: expected type `usize` - found closure `{closure@$DIR/issue-50600.rs:2:13: 2:20}` + found closure `{closure@$DIR/closure-in-array-len.rs:3:13: 3:20}` error: aborting due to 1 previous error diff --git a/tests/ui/array-slice-vec/return-in-array-len.rs b/tests/ui/array-slice-vec/return-in-array-len.rs index 03b50b7963ea..dea1bb2818bb 100644 --- a/tests/ui/array-slice-vec/return-in-array-len.rs +++ b/tests/ui/array-slice-vec/return-in-array-len.rs @@ -1,3 +1,4 @@ +//! regression test for fn main() { //~^ NOTE: not the enclosing function body //~| NOTE: not the enclosing function body diff --git a/tests/ui/array-slice-vec/return-in-array-len.stderr b/tests/ui/array-slice-vec/return-in-array-len.stderr index da3e3caea29a..974a748edc93 100644 --- a/tests/ui/array-slice-vec/return-in-array-len.stderr +++ b/tests/ui/array-slice-vec/return-in-array-len.stderr @@ -1,5 +1,5 @@ error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:6:13 + --> $DIR/return-in-array-len.rs:7:13 | LL | / fn main() { ... | @@ -10,7 +10,7 @@ LL | | } | |_- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:10:10 + --> $DIR/return-in-array-len.rs:11:10 | LL | / fn main() { ... | @@ -21,7 +21,7 @@ LL | | } | |_- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:14:10 + --> $DIR/return-in-array-len.rs:15:10 | LL | / fn main() { ... | @@ -32,7 +32,7 @@ LL | | } | |_- ...not the enclosing function body error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:18:10 + --> $DIR/return-in-array-len.rs:19:10 | LL | / fn main() { ... | diff --git a/tests/ui/array-slice-vec/slice-of-multi-ref.rs b/tests/ui/array-slice-vec/slice-of-multi-ref.rs index 6c966b5319cd..b4917f594d83 100644 --- a/tests/ui/array-slice-vec/slice-of-multi-ref.rs +++ b/tests/ui/array-slice-vec/slice-of-multi-ref.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass fn main() { let s: &[isize] = &[0, 1, 2, 3, 4]; diff --git a/tests/ui/derives/derive-hygiene-struct-builder.rs b/tests/ui/derives/derive-hygiene-struct-builder.rs index 9ed9080e8a92..95245a3b3f5a 100644 --- a/tests/ui/derives/derive-hygiene-struct-builder.rs +++ b/tests/ui/derives/derive-hygiene-struct-builder.rs @@ -1,3 +1,5 @@ +//! regression test for +//! struct named "builder" conflicted with derive macro internals. //@ run-pass #![allow(dead_code)] #![allow(non_camel_case_types)] @@ -5,6 +7,4 @@ #[derive(Debug)] struct builder; -fn main() { - -} +fn main() {} diff --git a/tests/ui/dst/unsized-str-mutability.rs b/tests/ui/dst/unsized-str-mutability.rs index 6f6fc42db383..d84fa001fd67 100644 --- a/tests/ui/dst/unsized-str-mutability.rs +++ b/tests/ui/dst/unsized-str-mutability.rs @@ -1,6 +1,6 @@ +//! regression test for +//! Test that HIR ty lowering doesn't forget about mutability of `&mut str`. //@ run-pass -// Test that HIR ty lowering doesn't forget about mutability of `&mut str`. - fn main() { fn foo(_: &mut T) {} diff --git a/tests/ui/for-loop-while/break-outside-loop-2.rs b/tests/ui/for-loop-while/break-outside-loop-2.rs deleted file mode 100644 index 1e8d2d6ccf13..000000000000 --- a/tests/ui/for-loop-while/break-outside-loop-2.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Make sure that a continue span actually contains the keyword. - -fn main() { - continue //~ ERROR `continue` outside of a loop - ; - break //~ ERROR `break` outside of a loop - ; -} diff --git a/tests/ui/for-loop-while/break-outside-loop-2.stderr b/tests/ui/for-loop-while/break-outside-loop-2.stderr deleted file mode 100644 index f450256f3ecf..000000000000 --- a/tests/ui/for-loop-while/break-outside-loop-2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0268]: `continue` outside of a loop - --> $DIR/issue-28105.rs:4:5 - | -LL | continue - | ^^^^^^^^ cannot `continue` outside of a loop - -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/issue-28105.rs:6:5 - | -LL | break - | ^^^^^ cannot `break` outside of a loop or labeled block - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/for-loop-while/break-outside-loop.rs b/tests/ui/for-loop-while/break-outside-loop.rs index 26769b30dd5f..06c513aa8457 100644 --- a/tests/ui/for-loop-while/break-outside-loop.rs +++ b/tests/ui/for-loop-while/break-outside-loop.rs @@ -1,25 +1,41 @@ struct Foo { - t: String + t: String, } -fn cond() -> bool { true } +fn cond() -> bool { + true +} -fn foo(_: F) where F: FnOnce() {} +fn foo(_: F) +where + F: FnOnce(), +{ +} fn main() { let pth = break; //~ ERROR: `break` outside of a loop - if cond() { continue } //~ ERROR: `continue` outside of a loop + if cond() { + continue; //~ ERROR: `continue` outside of a loop + } while cond() { - if cond() { break } - if cond() { continue } + if cond() { + break; + } + if cond() { + continue; + } foo(|| { - if cond() { break } //~ ERROR: `break` inside of a closure - if cond() { continue } //~ ERROR: `continue` inside of a closure + if cond() { + break; //~ ERROR: `break` inside of a closure + } + if cond() { + continue; //~ ERROR: `continue` inside of a closure + } }) } - let rs: Foo = Foo{t: pth}; + let rs: Foo = Foo { t: pth }; let unconstrained = break; //~ ERROR: `break` outside of a loop @@ -32,4 +48,10 @@ fn main() { //~| ERROR `break` inside of a closure }; } + + // Make sure that a continue span actually contains the keyword. (#28105) + continue //~ ERROR `continue` outside of a loop + ; + break //~ ERROR `break` outside of a loop + ; } diff --git a/tests/ui/for-loop-while/break-outside-loop.stderr b/tests/ui/for-loop-while/break-outside-loop.stderr index 9092f34df354..7dbff2d41245 100644 --- a/tests/ui/for-loop-while/break-outside-loop.stderr +++ b/tests/ui/for-loop-while/break-outside-loop.stderr @@ -1,5 +1,5 @@ error[E0767]: use of unreachable label `'lab` - --> $DIR/break-outside-loop.rs:30:19 + --> $DIR/break-outside-loop.rs:46:19 | LL | 'lab: loop { | ---- unreachable label defined here @@ -10,49 +10,62 @@ LL | break 'lab; = note: labels are unreachable through functions, closures, async blocks and modules error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-outside-loop.rs:10:15 + --> $DIR/break-outside-loop.rs:16:15 | LL | let pth = break; | ^^^^^ cannot `break` outside of a loop or labeled block error[E0268]: `continue` outside of a loop - --> $DIR/break-outside-loop.rs:11:17 + --> $DIR/break-outside-loop.rs:18:9 | -LL | if cond() { continue } - | ^^^^^^^^ cannot `continue` outside of a loop +LL | continue; + | ^^^^^^^^ cannot `continue` outside of a loop error[E0267]: `break` inside of a closure - --> $DIR/break-outside-loop.rs:17:25 + --> $DIR/break-outside-loop.rs:30:17 | LL | foo(|| { | -- enclosing closure -LL | if cond() { break } - | ^^^^^ cannot `break` inside of a closure +LL | if cond() { +LL | break; + | ^^^^^ cannot `break` inside of a closure error[E0267]: `continue` inside of a closure - --> $DIR/break-outside-loop.rs:18:25 + --> $DIR/break-outside-loop.rs:33:17 | LL | foo(|| { | -- enclosing closure -LL | if cond() { break } -LL | if cond() { continue } - | ^^^^^^^^ cannot `continue` inside of a closure +... +LL | continue; + | ^^^^^^^^ cannot `continue` inside of a closure error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-outside-loop.rs:24:25 + --> $DIR/break-outside-loop.rs:40:25 | LL | let unconstrained = break; | ^^^^^ cannot `break` outside of a loop or labeled block error[E0267]: `break` inside of a closure - --> $DIR/break-outside-loop.rs:30:13 + --> $DIR/break-outside-loop.rs:46:13 | LL | || { | -- enclosing closure LL | break 'lab; | ^^^^^^^^^^ cannot `break` inside of a closure -error: aborting due to 7 previous errors +error[E0268]: `continue` outside of a loop + --> $DIR/break-outside-loop.rs:53:5 + | +LL | continue + | ^^^^^^^^ cannot `continue` outside of a loop + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-outside-loop.rs:55:5 + | +LL | break + | ^^^^^ cannot `break` outside of a loop or labeled block + +error: aborting due to 9 previous errors Some errors have detailed explanations: E0267, E0268, E0767. For more information about an error, try `rustc --explain E0267`. diff --git a/tests/ui/generics/type-args-on-module-in-bound.rs b/tests/ui/generics/type-args-on-module-in-bound.rs index bb8a58d3d2ec..96ca37407cfc 100644 --- a/tests/ui/generics/type-args-on-module-in-bound.rs +++ b/tests/ui/generics/type-args-on-module-in-bound.rs @@ -1,3 +1,4 @@ +//! regression test for fn is_copy::Copy>() {} //~^ ERROR type arguments are not allowed on module `marker` [E0109] fn main() {} diff --git a/tests/ui/generics/type-args-on-module-in-bound.stderr b/tests/ui/generics/type-args-on-module-in-bound.stderr index 309e11a25f1a..ac70ae63e90b 100644 --- a/tests/ui/generics/type-args-on-module-in-bound.stderr +++ b/tests/ui/generics/type-args-on-module-in-bound.stderr @@ -1,5 +1,5 @@ error[E0109]: type arguments are not allowed on module `marker` - --> $DIR/issue-22706.rs:1:29 + --> $DIR/type-args-on-module-in-bound.rs:2:29 | LL | fn is_copy::Copy>() {} | ------ ^^^ type argument not allowed diff --git a/tests/ui/label/undeclared-label-span.rs b/tests/ui/label/undeclared-label-span.rs index 755a539b5003..c6f38c067192 100644 --- a/tests/ui/label/undeclared-label-span.rs +++ b/tests/ui/label/undeclared-label-span.rs @@ -1,4 +1,5 @@ -// Make sure that label for continue and break is spanned correctly +//! regression test for +//! Make sure that label for continue and break is spanned correctly. fn main() { loop { diff --git a/tests/ui/label/undeclared-label-span.stderr b/tests/ui/label/undeclared-label-span.stderr index 0f918d3b6f70..e5451b4655d8 100644 --- a/tests/ui/label/undeclared-label-span.stderr +++ b/tests/ui/label/undeclared-label-span.stderr @@ -1,11 +1,11 @@ error[E0426]: use of undeclared label `'b` - --> $DIR/issue-28109.rs:6:9 + --> $DIR/undeclared-label-span.rs:7:9 | LL | 'b | ^^ undeclared label `'b` error[E0426]: use of undeclared label `'c` - --> $DIR/issue-28109.rs:9:9 + --> $DIR/undeclared-label-span.rs:10:9 | LL | 'c | ^^ undeclared label `'c` diff --git a/tests/ui/macros/column-macro-collision.rs b/tests/ui/macros/column-macro-collision.rs index 4dd1fe461f1b..7acf491888af 100644 --- a/tests/ui/macros/column-macro-collision.rs +++ b/tests/ui/macros/column-macro-collision.rs @@ -1,3 +1,6 @@ +//! regression test for +//! user-defined `column!` macro must not shadow +//! the built-in `column!()` used internally by `panic!()`. //@ check-pass #![allow(unused)] diff --git a/tests/ui/mismatched_types/array-repeat-unit-struct.rs b/tests/ui/mismatched_types/array-repeat-unit-struct.rs index 20aa4f282c7e..db05e1daedbd 100644 --- a/tests/ui/mismatched_types/array-repeat-unit-struct.rs +++ b/tests/ui/mismatched_types/array-repeat-unit-struct.rs @@ -1,3 +1,5 @@ +//! regression test for + struct S; fn main() { diff --git a/tests/ui/mismatched_types/array-repeat-unit-struct.stderr b/tests/ui/mismatched_types/array-repeat-unit-struct.stderr index b4bfaa278633..9a9cc946f82a 100644 --- a/tests/ui/mismatched_types/array-repeat-unit-struct.stderr +++ b/tests/ui/mismatched_types/array-repeat-unit-struct.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-27008.rs:4:17 + --> $DIR/array-repeat-unit-struct.rs:6:17 | LL | let b = [0; S]; | ^ expected `usize`, found `S` diff --git a/tests/ui/mismatched_types/vec-hashset-type-mismatch.rs b/tests/ui/mismatched_types/vec-hashset-type-mismatch.rs index 97d288e5cb14..3724a423d0dd 100644 --- a/tests/ui/mismatched_types/vec-hashset-type-mismatch.rs +++ b/tests/ui/mismatched_types/vec-hashset-type-mismatch.rs @@ -1,3 +1,4 @@ +//! regression test for //@ dont-require-annotations: NOTE use std::collections::HashSet; @@ -9,5 +10,4 @@ fn main() { //~| NOTE expected `&mut HashSet`, found `&mut Vec<_>` } -fn foo(h: &mut HashSet) { -} +fn foo(h: &mut HashSet) {} diff --git a/tests/ui/mismatched_types/vec-hashset-type-mismatch.stderr b/tests/ui/mismatched_types/vec-hashset-type-mismatch.stderr index e144f37d6e48..e778422d0064 100644 --- a/tests/ui/mismatched_types/vec-hashset-type-mismatch.stderr +++ b/tests/ui/mismatched_types/vec-hashset-type-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-24819.rs:7:9 + --> $DIR/vec-hashset-type-mismatch.rs:8:9 | LL | foo(&mut v); | --- ^^^^^^ expected `&mut HashSet`, found `&mut Vec<_>` @@ -9,9 +9,9 @@ LL | foo(&mut v); = note: expected mutable reference `&mut HashSet` found mutable reference `&mut Vec<_>` note: function defined here - --> $DIR/issue-24819.rs:12:4 + --> $DIR/vec-hashset-type-mismatch.rs:13:4 | -LL | fn foo(h: &mut HashSet) { +LL | fn foo(h: &mut HashSet) {} | ^^^ -------------------- error: aborting due to 1 previous error diff --git a/tests/ui/privacy/privacy-sanity-2.rs b/tests/ui/privacy/privacy-sanity-2.rs deleted file mode 100644 index 2298ad240d56..000000000000 --- a/tests/ui/privacy/privacy-sanity-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -enum Bird { - pub Duck, - //~^ ERROR visibility qualifiers are not permitted here - Goose, - pub(crate) Dove - //~^ ERROR visibility qualifiers are not permitted here -} - - -fn main() { - let y = Bird::Goose; -} diff --git a/tests/ui/privacy/privacy-sanity-2.stderr b/tests/ui/privacy/privacy-sanity-2.stderr deleted file mode 100644 index 0fa67e35f1d4..000000000000 --- a/tests/ui/privacy/privacy-sanity-2.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0449]: visibility qualifiers are not permitted here - --> $DIR/issue-28433.rs:2:5 - | -LL | pub Duck, - | ^^^ help: remove the qualifier - | - = note: enum variants and their fields always share the visibility of the enum they are in - -error[E0449]: visibility qualifiers are not permitted here - --> $DIR/issue-28433.rs:5:5 - | -LL | pub(crate) Dove - | ^^^^^^^^^^ help: remove the qualifier - | - = note: enum variants and their fields always share the visibility of the enum they are in - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0449`. diff --git a/tests/ui/privacy/privacy-sanity.rs b/tests/ui/privacy/privacy-sanity.rs index 6622089dda6d..fcd03394d631 100644 --- a/tests/ui/privacy/privacy-sanity.rs +++ b/tests/ui/privacy/privacy-sanity.rs @@ -25,6 +25,14 @@ pub extern "C" { //~ ERROR visibility qualifiers are not permitted here pub static St: u8; } +enum Bird { + pub Duck, + //~^ ERROR visibility qualifiers are not permitted here + pub(crate) Dove, + //~^ ERROR visibility qualifiers are not permitted here + Goose, +} + const MAIN: u8 = { pub trait Tr { fn f(); @@ -79,4 +87,11 @@ fn main() { pub fn f(); pub static St: u8; } + enum Bird { + pub Duck, + //~^ ERROR visibility qualifiers are not permitted here + pub(crate) Dove, + //~^ ERROR visibility qualifiers are not permitted here + Goose, + } } diff --git a/tests/ui/privacy/privacy-sanity.stderr b/tests/ui/privacy/privacy-sanity.stderr index 0acb05cbabaa..fd643357335a 100644 --- a/tests/ui/privacy/privacy-sanity.stderr +++ b/tests/ui/privacy/privacy-sanity.stderr @@ -47,7 +47,23 @@ LL | pub extern "C" { = note: place qualifiers on individual foreign items instead error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:39:5 + --> $DIR/privacy-sanity.rs:29:5 + | +LL | pub Duck, + | ^^^ help: remove the qualifier + | + = note: enum variants and their fields always share the visibility of the enum they are in + +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/privacy-sanity.rs:31:5 + | +LL | pub(crate) Dove, + | ^^^^^^^^^^ help: remove the qualifier + | + = note: enum variants and their fields always share the visibility of the enum they are in + +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/privacy-sanity.rs:47:5 | LL | pub impl Tr for S { | ^^^ help: remove the qualifier @@ -55,7 +71,7 @@ LL | pub impl Tr for S { = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:40:9 + --> $DIR/privacy-sanity.rs:48:9 | LL | pub fn f() {} | ^^^ help: remove the qualifier @@ -63,7 +79,7 @@ LL | pub fn f() {} = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:41:9 + --> $DIR/privacy-sanity.rs:49:9 | LL | pub const C: u8 = 0; | ^^^ help: remove the qualifier @@ -71,7 +87,7 @@ LL | pub const C: u8 = 0; = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:42:9 + --> $DIR/privacy-sanity.rs:50:9 | LL | pub type T = u8; | ^^^ help: remove the qualifier @@ -79,7 +95,7 @@ LL | pub type T = u8; = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:44:5 + --> $DIR/privacy-sanity.rs:52:5 | LL | pub impl S { | ^^^ help: remove the qualifier @@ -87,7 +103,7 @@ LL | pub impl S { = note: place qualifiers on individual impl items instead error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:49:5 + --> $DIR/privacy-sanity.rs:57:5 | LL | pub extern "C" { | ^^^ help: remove the qualifier @@ -95,7 +111,7 @@ LL | pub extern "C" { = note: place qualifiers on individual foreign items instead error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:68:5 + --> $DIR/privacy-sanity.rs:76:5 | LL | pub impl Tr for S { | ^^^ help: remove the qualifier @@ -103,7 +119,7 @@ LL | pub impl Tr for S { = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:69:9 + --> $DIR/privacy-sanity.rs:77:9 | LL | pub fn f() {} | ^^^ help: remove the qualifier @@ -111,7 +127,7 @@ LL | pub fn f() {} = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:70:9 + --> $DIR/privacy-sanity.rs:78:9 | LL | pub const C: u8 = 0; | ^^^ help: remove the qualifier @@ -119,7 +135,7 @@ LL | pub const C: u8 = 0; = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:71:9 + --> $DIR/privacy-sanity.rs:79:9 | LL | pub type T = u8; | ^^^ help: remove the qualifier @@ -127,7 +143,7 @@ LL | pub type T = u8; = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:73:5 + --> $DIR/privacy-sanity.rs:81:5 | LL | pub impl S { | ^^^ help: remove the qualifier @@ -135,13 +151,29 @@ LL | pub impl S { = note: place qualifiers on individual impl items instead error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:78:5 + --> $DIR/privacy-sanity.rs:86:5 | LL | pub extern "C" { | ^^^ help: remove the qualifier | = note: place qualifiers on individual foreign items instead -error: aborting due to 18 previous errors +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/privacy-sanity.rs:91:9 + | +LL | pub Duck, + | ^^^ help: remove the qualifier + | + = note: enum variants and their fields always share the visibility of the enum they are in + +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/privacy-sanity.rs:93:9 + | +LL | pub(crate) Dove, + | ^^^^^^^^^^ help: remove the qualifier + | + = note: enum variants and their fields always share the visibility of the enum they are in + +error: aborting due to 22 previous errors For more information about this error, try `rustc --explain E0449`. diff --git a/tests/ui/privacy/private-extern-fn-visibility.rs b/tests/ui/privacy/private-extern-fn-visibility.rs index 7741f828c474..39f2c3c003d5 100644 --- a/tests/ui/privacy/private-extern-fn-visibility.rs +++ b/tests/ui/privacy/private-extern-fn-visibility.rs @@ -1,8 +1,11 @@ -//@ aux-build:issue-16725.rs +//! regression test for +//@ aux-build:private-extern-fn.rs -extern crate issue_16725 as foo; +extern crate private_extern_fn as foo; fn main() { - unsafe { foo::bar(); } - //~^ ERROR: function `bar` is private + unsafe { + foo::bar(); + //~^ ERROR: function `bar` is private + } } diff --git a/tests/ui/privacy/private-extern-fn-visibility.stderr b/tests/ui/privacy/private-extern-fn-visibility.stderr index dcb7d58b0f96..8b1fa512b5de 100644 --- a/tests/ui/privacy/private-extern-fn-visibility.stderr +++ b/tests/ui/privacy/private-extern-fn-visibility.stderr @@ -1,11 +1,11 @@ error[E0603]: function `bar` is private - --> $DIR/issue-16725.rs:6:19 + --> $DIR/private-extern-fn-visibility.rs:8:14 | -LL | unsafe { foo::bar(); } - | ^^^ private function +LL | foo::bar(); + | ^^^ private function | note: the function `bar` is defined here - --> $DIR/auxiliary/issue-16725.rs:2:5 + --> $DIR/auxiliary/private-extern-fn.rs:2:5 | LL | fn bar(); | ^^^^^^^^^ diff --git a/tests/ui/static/static-str-deref-ref.rs b/tests/ui/static/static-str-deref-ref.rs index e8fc680f0422..86c37e527657 100644 --- a/tests/ui/static/static-str-deref-ref.rs +++ b/tests/ui/static/static-str-deref-ref.rs @@ -1,3 +1,4 @@ +//! regression test for //@ build-pass #[allow(dead_code)] static X: &'static str = &*""; diff --git a/tests/ui/threads-sendsync/std-sync-right-kind-impls-2.rs b/tests/ui/threads-sendsync/std-sync-right-kind-impls-2.rs deleted file mode 100644 index 0fa284cc7c0c..000000000000 --- a/tests/ui/threads-sendsync/std-sync-right-kind-impls-2.rs +++ /dev/null @@ -1,25 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -use std::{fs, net}; - -fn assert_both() {} -fn assert_send() {} - -fn main() { - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); -} diff --git a/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs b/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs index b2d22631c1a5..42135fe1c45b 100644 --- a/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs +++ b/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs @@ -1,6 +1,6 @@ //@ run-pass -use std::sync; +use std::{fs, net, sync}; fn assert_both() {} @@ -12,4 +12,20 @@ fn main() { assert_both::>(); assert_both::>(); assert_both::(); + + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); } From 5c057ad89617b3872de836f6658f53db2a6c6e3a Mon Sep 17 00:00:00 2001 From: Asuna Date: Thu, 15 Jan 2026 21:12:04 +0100 Subject: [PATCH 2181/3801] Remove their own `TypeId` from type info for primitives --- .../src/const_eval/type_info.rs | 52 +++++-------------- library/core/src/mem/type_info.rs | 15 ++---- tests/ui/reflection/dump.bit32.run.stdout | 14 +---- tests/ui/reflection/dump.bit64.run.stdout | 14 +---- 4 files changed, 19 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index fc3378275be2..1e4b72d0ddac 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -66,55 +66,39 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::Bool => { - let (variant, variant_place) = downcast(sym::Bool)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_primitive_type_info(place, ty, None)?; + let (variant, _variant_place) = downcast(sym::Bool)?; variant } ty::Char => { - let (variant, variant_place) = downcast(sym::Char)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_primitive_type_info(place, ty, None)?; + let (variant, _variant_place) = downcast(sym::Char)?; variant } ty::Int(int_ty) => { let (variant, variant_place) = downcast(sym::Int)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_primitive_type_info( + self.write_int_float_type_info( place, - ty, - Some( - int_ty - .bit_width() - .unwrap_or_else(/* isize */ ptr_bit_width), - ), + int_ty.bit_width().unwrap_or_else(/* isize */ ptr_bit_width), )?; variant } ty::Uint(uint_ty) => { let (variant, variant_place) = downcast(sym::Uint)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_primitive_type_info( + self.write_int_float_type_info( place, - ty, - Some( - uint_ty - .bit_width() - .unwrap_or_else(/* usize */ ptr_bit_width), - ), + uint_ty.bit_width().unwrap_or_else(/* usize */ ptr_bit_width), )?; variant } ty::Float(float_ty) => { let (variant, variant_place) = downcast(sym::Float)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_primitive_type_info(place, ty, Some(float_ty.bit_width()))?; + self.write_int_float_type_info(place, float_ty.bit_width())?; variant } ty::Str => { - let (variant, variant_place) = downcast(sym::Str)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_primitive_type_info(place, ty, None)?; + let (variant, _variant_place) = downcast(sym::Str)?; variant } ty::Adt(_, _) @@ -252,28 +236,20 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } - // This method always writes to field `ty`. - // If field `bit_width` is present, it also writes to it (in which case parameter `write_bit_width` must be `Some`). - fn write_primitive_type_info( + fn write_int_float_type_info( &mut self, place: impl Writeable<'tcx, CtfeProvenance>, - ty: Ty<'tcx>, - write_bit_width: Option, + bit_width: u64, ) -> InterpResult<'tcx> { for (field_idx, field) in place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() { let field_place = self.project_field(&place, field_idx)?; match field.name { - sym::ty => self.write_type_id(ty, &field_place)?, - sym::bit_width => { - let bit_width = write_bit_width - .expect("type info struct needs a `bit_width` but none was provided"); - self.write_scalar( - ScalarInt::try_from_target_usize(bit_width, self.tcx.tcx).unwrap(), - &field_place, - )? - } + sym::bit_width => self.write_scalar( + ScalarInt::try_from_target_usize(bit_width, self.tcx.tcx).unwrap(), + &field_place, + )?, other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), } } diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 7db4f3b00123..e02e07ae3b4a 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -97,8 +97,7 @@ pub struct Array { #[non_exhaustive] #[unstable(feature = "type_info", issue = "146922")] pub struct Bool { - /// The type id of `bool`. - pub ty: TypeId, + // No additional information to provide for now. } /// Compile-time type information about `char`. @@ -106,8 +105,7 @@ pub struct Bool { #[non_exhaustive] #[unstable(feature = "type_info", issue = "146922")] pub struct Char { - /// The type id of `char`. - pub ty: TypeId, + // No additional information to provide for now. } /// Compile-time type information about signed integer types. @@ -115,8 +113,6 @@ pub struct Char { #[non_exhaustive] #[unstable(feature = "type_info", issue = "146922")] pub struct Int { - /// The type id of signed integer type. - pub ty: TypeId, /// The bit width of the signed integer type. pub bit_width: usize, } @@ -126,8 +122,6 @@ pub struct Int { #[non_exhaustive] #[unstable(feature = "type_info", issue = "146922")] pub struct Uint { - /// The type id of unsigned integer type. - pub ty: TypeId, /// The bit width of the unsigned integer type. pub bit_width: usize, } @@ -137,8 +131,6 @@ pub struct Uint { #[non_exhaustive] #[unstable(feature = "type_info", issue = "146922")] pub struct Float { - /// The type id of floating-point type. - pub ty: TypeId, /// The bit width of the floating-point type. pub bit_width: usize, } @@ -148,6 +140,5 @@ pub struct Float { #[non_exhaustive] #[unstable(feature = "type_info", issue = "146922")] pub struct Str { - /// The type id of `str`. - pub ty: TypeId, + // No additional information to provide for now. } diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout index d747ee210204..c6df7b00bf4a 100644 --- a/tests/ui/reflection/dump.bit32.run.stdout +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -35,7 +35,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0x12427c993eca190c841e0d92c5b7a45d), bit_width: 8, }, ), @@ -46,7 +45,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013), bit_width: 32, }, ), @@ -57,7 +55,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0xae6c4318bb07632e00428affbea41961), bit_width: 64, }, ), @@ -68,7 +65,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0xc7164498f3902dde0d8194a7b9733e79), bit_width: 128, }, ), @@ -79,7 +75,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0x1e5f92831c560aac8658b980a22e60b0), bit_width: 32, }, ), @@ -90,7 +85,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), bit_width: 8, }, ), @@ -101,7 +95,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), bit_width: 32, }, ), @@ -112,7 +105,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x9ed91be891e304132cb86891e578f4a5), bit_width: 64, }, ), @@ -123,7 +115,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x7bf7411d57d603e9fb393892a9c3f362), bit_width: 128, }, ), @@ -134,7 +125,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x763d199bccd319899208909ed1a860c6), bit_width: 32, }, ), @@ -174,9 +164,7 @@ Type { } Type { kind: Str( - Str { - ty: TypeId(0x474ccf3b5db264ef53916706f7d7bb2c), - }, + Str, ), size: None, } diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout index 180a6e2882d7..0f39e3e4c6b0 100644 --- a/tests/ui/reflection/dump.bit64.run.stdout +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -35,7 +35,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0x12427c993eca190c841e0d92c5b7a45d), bit_width: 8, }, ), @@ -46,7 +45,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013), bit_width: 32, }, ), @@ -57,7 +55,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0xae6c4318bb07632e00428affbea41961), bit_width: 64, }, ), @@ -68,7 +65,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0xc7164498f3902dde0d8194a7b9733e79), bit_width: 128, }, ), @@ -79,7 +75,6 @@ Type { Type { kind: Int( Int { - ty: TypeId(0x1e5f92831c560aac8658b980a22e60b0), bit_width: 64, }, ), @@ -90,7 +85,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), bit_width: 8, }, ), @@ -101,7 +95,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), bit_width: 32, }, ), @@ -112,7 +105,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x9ed91be891e304132cb86891e578f4a5), bit_width: 64, }, ), @@ -123,7 +115,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x7bf7411d57d603e9fb393892a9c3f362), bit_width: 128, }, ), @@ -134,7 +125,6 @@ Type { Type { kind: Uint( Uint { - ty: TypeId(0x763d199bccd319899208909ed1a860c6), bit_width: 64, }, ), @@ -174,9 +164,7 @@ Type { } Type { kind: Str( - Str { - ty: TypeId(0x474ccf3b5db264ef53916706f7d7bb2c), - }, + Str, ), size: None, } From b2a7b18ec4c93ef11eb51cb2dccbe5f257993bd1 Mon Sep 17 00:00:00 2001 From: Asuna Date: Thu, 15 Jan 2026 22:17:43 +0100 Subject: [PATCH 2182/3801] Merge type info variant `Uint` into `Int` --- .../src/const_eval/type_info.rs | 36 +++++++++++++++---- compiler/rustc_span/src/symbol.rs | 2 +- library/core/src/mem/type_info.rs | 17 +++------ library/coretests/tests/mem/type_info.rs | 16 +++++---- tests/ui/reflection/dump.bit32.run.stdout | 30 ++++++++++------ tests/ui/reflection/dump.bit64.run.stdout | 30 ++++++++++------ 6 files changed, 85 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 1e4b72d0ddac..5d37db06d76a 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -1,6 +1,6 @@ use rustc_abi::FieldIdx; use rustc_hir::LangItem; -use rustc_middle::mir::interpret::CtfeProvenance; +use rustc_middle::mir::interpret::{CtfeProvenance, Scalar}; use rustc_middle::span_bug; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{self, Const, ScalarInt, Ty}; @@ -76,25 +76,27 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { ty::Int(int_ty) => { let (variant, variant_place) = downcast(sym::Int)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_int_float_type_info( + self.write_int_type_info( place, int_ty.bit_width().unwrap_or_else(/* isize */ ptr_bit_width), + true, )?; variant } ty::Uint(uint_ty) => { - let (variant, variant_place) = downcast(sym::Uint)?; + let (variant, variant_place) = downcast(sym::Int)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_int_float_type_info( + self.write_int_type_info( place, uint_ty.bit_width().unwrap_or_else(/* usize */ ptr_bit_width), + false, )?; variant } ty::Float(float_ty) => { let (variant, variant_place) = downcast(sym::Float)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_int_float_type_info(place, float_ty.bit_width())?; + self.write_float_type_info(place, float_ty.bit_width())?; variant } ty::Str => { @@ -236,7 +238,29 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } - fn write_int_float_type_info( + fn write_int_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + bit_width: u64, + signed: bool, + ) -> InterpResult<'tcx> { + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + match field.name { + sym::bit_width => self.write_scalar( + ScalarInt::try_from_target_usize(bit_width, self.tcx.tcx).unwrap(), + &field_place, + )?, + sym::signed => self.write_scalar(Scalar::from_bool(signed), &field_place)?, + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + interp_ok(()) + } + + fn write_float_type_info( &mut self, place: impl Writeable<'tcx, CtfeProvenance>, bit_width: u64, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4c19fa83fd3a..6aa6ce269517 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -391,7 +391,6 @@ symbols! { Ty, TyCtxt, TyKind, - Uint, Unknown, Unsize, UnsizedConstParamTy, @@ -2066,6 +2065,7 @@ symbols! { shr_assign, sig_dfl, sig_ign, + signed, simd, simd_add, simd_and, diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index e02e07ae3b4a..2e3bdb45ce05 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -49,10 +49,8 @@ pub enum TypeKind { Bool(Bool), /// Primitive character type. Char(Char), - /// Primitive signed integer type. + /// Primitive signed and unsigned integer type. Int(Int), - /// Primitive unsigned integer type. - Uint(Uint), /// Primitive floating-point type. Float(Float), /// String slice type. @@ -108,22 +106,15 @@ pub struct Char { // No additional information to provide for now. } -/// Compile-time type information about signed integer types. +/// Compile-time type information about signed and unsigned integer types. #[derive(Debug)] #[non_exhaustive] #[unstable(feature = "type_info", issue = "146922")] pub struct Int { /// The bit width of the signed integer type. pub bit_width: usize, -} - -/// Compile-time type information about unsigned integer types. -#[derive(Debug)] -#[non_exhaustive] -#[unstable(feature = "type_info", issue = "146922")] -pub struct Uint { - /// The bit width of the unsigned integer type. - pub bit_width: usize, + /// Whether the integer type is signed. + pub signed: bool, } /// Compile-time type information about floating-point types. diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 5dd8f4034d11..fc13637a5574 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -38,7 +38,7 @@ fn test_tuples() { assert_tuple_arity::<(u8, u8), 2>(); const { - match Type::of::<(u8, u8)>().kind { + match Type::of::<(i8, u8)>().kind { TypeKind::Tuple(tup) => { let [a, b] = tup.fields else { unreachable!() }; @@ -46,9 +46,9 @@ fn test_tuples() { assert!(b.offset == 1); match (a.ty.info().kind, b.ty.info().kind) { - (TypeKind::Uint(a), TypeKind::Uint(b)) => { - assert!(a.bit_width == 8); - assert!(b.bit_width == 8); + (TypeKind::Int(a), TypeKind::Int(b)) => { + assert!(a.bit_width == 8 && a.signed); + assert!(b.bit_width == 8 && !b.signed); } _ => unreachable!(), } @@ -71,18 +71,22 @@ fn test_primitives() { let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(4)); assert_eq!(ty.bit_width, 32); + assert!(ty.signed); let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(size_of::())); assert_eq!(ty.bit_width, size_of::() * 8); + assert!(ty.signed); - let Type { kind: Uint(ty), size, .. } = (const { Type::of::() }) else { panic!() }; + let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(4)); assert_eq!(ty.bit_width, 32); + assert!(!ty.signed); - let Type { kind: Uint(ty), size, .. } = (const { Type::of::() }) else { panic!() }; + let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(size_of::())); assert_eq!(ty.bit_width, size_of::() * 8); + assert!(!ty.signed); let Type { kind: Float(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(4)); diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout index c6df7b00bf4a..483efdbbd12a 100644 --- a/tests/ui/reflection/dump.bit32.run.stdout +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -36,6 +36,7 @@ Type { kind: Int( Int { bit_width: 8, + signed: true, }, ), size: Some( @@ -46,6 +47,7 @@ Type { kind: Int( Int { bit_width: 32, + signed: true, }, ), size: Some( @@ -56,6 +58,7 @@ Type { kind: Int( Int { bit_width: 64, + signed: true, }, ), size: Some( @@ -66,6 +69,7 @@ Type { kind: Int( Int { bit_width: 128, + signed: true, }, ), size: Some( @@ -76,6 +80,7 @@ Type { kind: Int( Int { bit_width: 32, + signed: true, }, ), size: Some( @@ -83,9 +88,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 8, + signed: false, }, ), size: Some( @@ -93,9 +99,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 32, + signed: false, }, ), size: Some( @@ -103,9 +110,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 64, + signed: false, }, ), size: Some( @@ -113,9 +121,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 128, + signed: false, }, ), size: Some( @@ -123,9 +132,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 32, + signed: false, }, ), size: Some( diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout index 0f39e3e4c6b0..681e81b71d56 100644 --- a/tests/ui/reflection/dump.bit64.run.stdout +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -36,6 +36,7 @@ Type { kind: Int( Int { bit_width: 8, + signed: true, }, ), size: Some( @@ -46,6 +47,7 @@ Type { kind: Int( Int { bit_width: 32, + signed: true, }, ), size: Some( @@ -56,6 +58,7 @@ Type { kind: Int( Int { bit_width: 64, + signed: true, }, ), size: Some( @@ -66,6 +69,7 @@ Type { kind: Int( Int { bit_width: 128, + signed: true, }, ), size: Some( @@ -76,6 +80,7 @@ Type { kind: Int( Int { bit_width: 64, + signed: true, }, ), size: Some( @@ -83,9 +88,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 8, + signed: false, }, ), size: Some( @@ -93,9 +99,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 32, + signed: false, }, ), size: Some( @@ -103,9 +110,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 64, + signed: false, }, ), size: Some( @@ -113,9 +121,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 128, + signed: false, }, ), size: Some( @@ -123,9 +132,10 @@ Type { ), } Type { - kind: Uint( - Uint { + kind: Int( + Int { bit_width: 64, + signed: false, }, ), size: Some( From 0dc5b52e8eef98e973d9935c45e8dc3d7fbd6a1d Mon Sep 17 00:00:00 2001 From: Usman Akinyemi Date: Fri, 16 Jan 2026 04:25:12 +0530 Subject: [PATCH 2183/3801] simplify words initialization using Rc::new_zeroed Now that Rc::new_zeroed is stable, remove the cfg(feature = "nightly") branch and the temporary zeroed array on stable. This avoids copying a potentially large [Word; CHUNK_WORDS] into the Rc. Signed-off-by: Usman Akinyemi --- compiler/rustc_index/src/bit_set.rs | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index a9bdf597e128..184fa409d960 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -634,22 +634,12 @@ impl ChunkedBitSet { match *chunk { Zeros => { if chunk_domain_size > 1 { - #[cfg(feature = "nightly")] let mut words = { // We take some effort to avoid copying the words. let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed(); // SAFETY: `words` can safely be all zeroes. unsafe { words.assume_init() } }; - #[cfg(not(feature = "nightly"))] - let mut words = { - // FIXME: unconditionally use `Rc::new_zeroed` once it is stable (#129396). - let words = mem::MaybeUninit::<[Word; CHUNK_WORDS]>::zeroed(); - // SAFETY: `words` can safely be all zeroes. - let words = unsafe { words.assume_init() }; - // Unfortunate possibly-large copy - Rc::new(words) - }; let words_ref = Rc::get_mut(&mut words).unwrap(); let (word_index, mask) = chunk_word_index_and_mask(elem); @@ -695,22 +685,12 @@ impl ChunkedBitSet { Zeros => false, Ones => { if chunk_domain_size > 1 { - #[cfg(feature = "nightly")] let mut words = { // We take some effort to avoid copying the words. let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed(); // SAFETY: `words` can safely be all zeroes. unsafe { words.assume_init() } }; - #[cfg(not(feature = "nightly"))] - let mut words = { - // FIXME: unconditionally use `Rc::new_zeroed` once it is stable (#129396). - let words = mem::MaybeUninit::<[Word; CHUNK_WORDS]>::zeroed(); - // SAFETY: `words` can safely be all zeroes. - let words = unsafe { words.assume_init() }; - // Unfortunate possibly-large copy - Rc::new(words) - }; let words_ref = Rc::get_mut(&mut words).unwrap(); // Set only the bits in use. From 676d71a45b4fa9966e77e9d4fe6508d8bbea7d29 Mon Sep 17 00:00:00 2001 From: Hugh Date: Thu, 15 Jan 2026 16:22:23 -0800 Subject: [PATCH 2184/3801] Defer is_from_proc_macro check and add tests Move the is_from_proc_macro check inside check_fn_inner to be called only right before emitting lints, rather than at the entry points. This avoids the expensive check when early returns would prevent any lint emission anyway. Add tests for proc-macro generated code covering all check locations: - Standalone functions - Methods in impl blocks - Trait methods - Impl blocks with extra lifetimes --- clippy_lints/src/lifetimes.rs | 46 +++++++++++++++++--------- tests/ui/extra_unused_lifetimes.rs | 32 ++++++++++++++++++ tests/ui/extra_unused_lifetimes.stderr | 14 ++++---- tests/ui/needless_lifetimes.fixed | 25 +++++++++++++- tests/ui/needless_lifetimes.rs | 25 +++++++++++++- 5 files changed, 118 insertions(+), 24 deletions(-) diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 8917c90262a4..679fb983d532 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -149,10 +149,9 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes { .. } = item.kind { - if is_from_proc_macro(cx, item) { - return; - } - check_fn_inner(cx, sig, Some(id), None, generics, item.span, true, self.msrv); + check_fn_inner(cx, sig, Some(id), None, generics, item.span, true, self.msrv, || { + is_from_proc_macro(cx, item) + }); } else if let ItemKind::Impl(impl_) = &item.kind && !item.span.from_expansion() && !is_from_proc_macro(cx, item) @@ -162,9 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes { } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { - if let ImplItemKind::Fn(ref sig, id) = item.kind - && !is_from_proc_macro(cx, item) - { + if let ImplItemKind::Fn(ref sig, id) = item.kind { let report_extra_lifetimes = trait_ref_of_method(cx, item.owner_id).is_none(); check_fn_inner( cx, @@ -175,19 +172,28 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes { item.span, report_extra_lifetimes, self.msrv, + || is_from_proc_macro(cx, item), ); } } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { - if let TraitItemKind::Fn(ref sig, ref body) = item.kind - && !is_from_proc_macro(cx, item) - { + if let TraitItemKind::Fn(ref sig, ref body) = item.kind { let (body, trait_sig) = match *body { TraitFn::Required(sig) => (None, Some(sig)), TraitFn::Provided(id) => (Some(id), None), }; - check_fn_inner(cx, sig, body, trait_sig, item.generics, item.span, true, self.msrv); + check_fn_inner( + cx, + sig, + body, + trait_sig, + item.generics, + item.span, + true, + self.msrv, + || is_from_proc_macro(cx, item), + ); } } } @@ -202,6 +208,7 @@ fn check_fn_inner<'tcx>( span: Span, report_extra_lifetimes: bool, msrv: Msrv, + is_from_proc_macro: impl FnOnce() -> bool, ) { if span.in_external_macro(cx.sess().source_map()) || has_where_lifetimes(cx, generics) { return; @@ -253,10 +260,19 @@ fn check_fn_inner<'tcx>( } } - if let Some((elidable_lts, usages)) = could_use_elision(cx, sig.decl, body, trait_sig, generics.params, msrv) { - if usages.iter().any(|usage| !usage.ident.span.eq_ctxt(span)) { - return; - } + let elidable = could_use_elision(cx, sig.decl, body, trait_sig, generics.params, msrv); + let has_elidable_lts = elidable + .as_ref() + .is_some_and(|(_, usages)| !usages.iter().any(|usage| !usage.ident.span.eq_ctxt(span))); + + // Only check is_from_proc_macro if we're about to emit a lint (it's an expensive check) + if (has_elidable_lts || report_extra_lifetimes) && is_from_proc_macro() { + return; + } + + if let Some((elidable_lts, usages)) = elidable + && has_elidable_lts + { // async functions have usages whose spans point at the lifetime declaration which messes up // suggestions let include_suggestions = !sig.header.is_async(); diff --git a/tests/ui/extra_unused_lifetimes.rs b/tests/ui/extra_unused_lifetimes.rs index 5fdcd5a7e078..677523489599 100644 --- a/tests/ui/extra_unused_lifetimes.rs +++ b/tests/ui/extra_unused_lifetimes.rs @@ -1,4 +1,5 @@ //@aux-build:proc_macro_derive.rs +//@aux-build:proc_macros.rs #![allow( unused, @@ -11,6 +12,7 @@ #[macro_use] extern crate proc_macro_derive; +extern crate proc_macros; fn empty() {} @@ -148,4 +150,34 @@ mod issue_13578 { impl<'a, T: 'a> Foo for Option where &'a T: Foo {} } +// no lint on proc macro generated code +mod proc_macro_generated { + use proc_macros::external; + + // no lint on external macro (extra unused lifetimes in impl block) + external! { + struct ExternalImplStruct; + + impl<'a> ExternalImplStruct { + fn foo() {} + } + } + + // no lint on external macro (extra unused lifetimes in method) + external! { + struct ExternalMethodStruct; + + impl ExternalMethodStruct { + fn bar<'a>(&self) {} + } + } + + // no lint on external macro (extra unused lifetimes in trait method) + external! { + trait ExternalUnusedLifetimeTrait { + fn unused_lt<'a>(x: u8) {} + } + } +} + fn main() {} diff --git a/tests/ui/extra_unused_lifetimes.stderr b/tests/ui/extra_unused_lifetimes.stderr index 0cecbbe80f76..d748376d476c 100644 --- a/tests/ui/extra_unused_lifetimes.stderr +++ b/tests/ui/extra_unused_lifetimes.stderr @@ -1,5 +1,5 @@ error: this lifetime isn't used in the function definition - --> tests/ui/extra_unused_lifetimes.rs:19:14 + --> tests/ui/extra_unused_lifetimes.rs:21:14 | LL | fn unused_lt<'a>(x: u8) {} | ^^ @@ -8,37 +8,37 @@ LL | fn unused_lt<'a>(x: u8) {} = help: to override `-D warnings` add `#[allow(clippy::extra_unused_lifetimes)]` error: this lifetime isn't used in the function definition - --> tests/ui/extra_unused_lifetimes.rs:47:10 + --> tests/ui/extra_unused_lifetimes.rs:49:10 | LL | fn x<'a>(&self) {} | ^^ error: this lifetime isn't used in the function definition - --> tests/ui/extra_unused_lifetimes.rs:74:22 + --> tests/ui/extra_unused_lifetimes.rs:76:22 | LL | fn unused_lt<'a>(x: u8) {} | ^^ error: this lifetime isn't used in the impl - --> tests/ui/extra_unused_lifetimes.rs:86:10 + --> tests/ui/extra_unused_lifetimes.rs:88:10 | LL | impl<'a> std::ops::AddAssign<&Scalar> for &mut Scalar { | ^^ error: this lifetime isn't used in the impl - --> tests/ui/extra_unused_lifetimes.rs:93:10 + --> tests/ui/extra_unused_lifetimes.rs:95:10 | LL | impl<'b> Scalar { | ^^ error: this lifetime isn't used in the function definition - --> tests/ui/extra_unused_lifetimes.rs:95:26 + --> tests/ui/extra_unused_lifetimes.rs:97:26 | LL | pub fn something<'c>() -> Self { | ^^ error: this lifetime isn't used in the impl - --> tests/ui/extra_unused_lifetimes.rs:125:10 + --> tests/ui/extra_unused_lifetimes.rs:127:10 | LL | impl<'a, T: Source + ?Sized + 'a> Source for Box { | ^^ diff --git a/tests/ui/needless_lifetimes.fixed b/tests/ui/needless_lifetimes.fixed index 15ca409c95bd..90a07454b4d7 100644 --- a/tests/ui/needless_lifetimes.fixed +++ b/tests/ui/needless_lifetimes.fixed @@ -470,13 +470,36 @@ mod in_macro { } } - // no lint on external macro + // no lint on external macro (standalone function) external! { fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 { unimplemented!() } } + // no lint on external macro (method in impl block) + external! { + struct ExternalStruct; + + impl ExternalStruct { + fn needless_lifetime_method<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() + } + } + } + + // no lint on external macro (trait method) + external! { + trait ExternalTrait { + fn needless_lifetime_trait_method<'a>(x: &'a u8) -> &'a u8; + } + } + + // no lint on external macro (extra unused lifetimes in function) + external! { + fn extra_unused_lifetime<'a>(x: u8) {} + } + inline! { fn f<$'a>(arg: &$'a str) -> &$'a str { arg diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs index af9649d72987..6df38897f42d 100644 --- a/tests/ui/needless_lifetimes.rs +++ b/tests/ui/needless_lifetimes.rs @@ -470,13 +470,36 @@ mod in_macro { } } - // no lint on external macro + // no lint on external macro (standalone function) external! { fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 { unimplemented!() } } + // no lint on external macro (method in impl block) + external! { + struct ExternalStruct; + + impl ExternalStruct { + fn needless_lifetime_method<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() + } + } + } + + // no lint on external macro (trait method) + external! { + trait ExternalTrait { + fn needless_lifetime_trait_method<'a>(x: &'a u8) -> &'a u8; + } + } + + // no lint on external macro (extra unused lifetimes in function) + external! { + fn extra_unused_lifetime<'a>(x: u8) {} + } + inline! { fn f<$'a>(arg: &$'a str) -> &$'a str { arg From 02c5f9a5b455ecf4e9eeeb0510c8ba65ff39ce28 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 15 Jan 2026 16:22:18 +1100 Subject: [PATCH 2185/3801] Add a snapshot test for string patterns in THIR --- tests/ui/thir-print/str-patterns.rs | 17 ++ tests/ui/thir-print/str-patterns.stdout | 310 ++++++++++++++++++++++++ 2 files changed, 327 insertions(+) create mode 100644 tests/ui/thir-print/str-patterns.rs create mode 100644 tests/ui/thir-print/str-patterns.stdout diff --git a/tests/ui/thir-print/str-patterns.rs b/tests/ui/thir-print/str-patterns.rs new file mode 100644 index 000000000000..4ad782f63a50 --- /dev/null +++ b/tests/ui/thir-print/str-patterns.rs @@ -0,0 +1,17 @@ +#![crate_type = "rlib"] +//@ edition: 2024 +//@ compile-flags: -Zunpretty=thir-flat +//@ check-pass + +// Snapshot test capturing the THIR pattern structure produced by +// string-literal and string-constant patterns. + +pub fn hello_world(x: &str) { + match x { + "hello" => {} + CONSTANT => {} + _ => {} + } +} + +const CONSTANT: &str = "constant"; diff --git a/tests/ui/thir-print/str-patterns.stdout b/tests/ui/thir-print/str-patterns.stdout new file mode 100644 index 000000000000..8f8944ad4e09 --- /dev/null +++ b/tests/ui/thir-print/str-patterns.stdout @@ -0,0 +1,310 @@ +DefId(0:3 ~ str_patterns[fc71]::hello_world): +Thir { + body_type: Fn( + fn(&'{erased} str), + ), + arms: [ + Arm { + pattern: Pat { + ty: &'{erased} str, + span: $DIR/str-patterns.rs:11:9: 11:16 (#0), + extra: None, + kind: Constant { + value: Value { + ty: &'{erased} str, + valtree: Branch( + [ + 104_u8, + 101_u8, + 108_u8, + 108_u8, + 111_u8, + ], + ), + }, + }, + }, + guard: None, + body: e3, + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).9), + scope: Node(9), + span: $DIR/str-patterns.rs:11:9: 11:22 (#0), + }, + Arm { + pattern: Pat { + ty: &'{erased} str, + span: $DIR/str-patterns.rs:12:9: 12:17 (#0), + extra: Some( + PatExtra { + expanded_const: Some( + DefId(0:4 ~ str_patterns[fc71]::CONSTANT), + ), + ascriptions: [], + }, + ), + kind: Constant { + value: Value { + ty: &'{erased} str, + valtree: Branch( + [ + 99_u8, + 111_u8, + 110_u8, + 115_u8, + 116_u8, + 97_u8, + 110_u8, + 116_u8, + ], + ), + }, + }, + }, + guard: None, + body: e5, + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).15), + scope: Node(15), + span: $DIR/str-patterns.rs:12:9: 12:23 (#0), + }, + Arm { + pattern: Pat { + ty: &'{erased} str, + span: $DIR/str-patterns.rs:13:9: 13:10 (#0), + extra: None, + kind: Wild, + }, + guard: None, + body: e7, + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).19), + scope: Node(19), + span: $DIR/str-patterns.rs:13:9: 13:16 (#0), + }, + ], + blocks: [ + Block { + targeted_by_break: false, + region_scope: Node(11), + span: $DIR/str-patterns.rs:11:20: 11:22 (#0), + stmts: [], + expr: None, + safety_mode: Safe, + }, + Block { + targeted_by_break: false, + region_scope: Node(17), + span: $DIR/str-patterns.rs:12:21: 12:23 (#0), + stmts: [], + expr: None, + safety_mode: Safe, + }, + Block { + targeted_by_break: false, + region_scope: Node(21), + span: $DIR/str-patterns.rs:13:14: 13:16 (#0), + stmts: [], + expr: None, + safety_mode: Safe, + }, + Block { + targeted_by_break: false, + region_scope: Node(3), + span: $DIR/str-patterns.rs:9:29: 15:2 (#0), + stmts: [], + expr: Some( + e9, + ), + safety_mode: Safe, + }, + ], + exprs: [ + Expr { + kind: VarRef { + id: LocalVarId( + HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).2), + ), + }, + ty: &'{erased} str, + temp_scope_id: 5, + span: $DIR/str-patterns.rs:10:11: 10:12 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(5), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).5), + value: e0, + }, + ty: &'{erased} str, + temp_scope_id: 5, + span: $DIR/str-patterns.rs:10:11: 10:12 (#0), + }, + Expr { + kind: Block { + block: b0, + }, + ty: (), + temp_scope_id: 10, + span: $DIR/str-patterns.rs:11:20: 11:22 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(10), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).10), + value: e2, + }, + ty: (), + temp_scope_id: 10, + span: $DIR/str-patterns.rs:11:20: 11:22 (#0), + }, + Expr { + kind: Block { + block: b1, + }, + ty: (), + temp_scope_id: 16, + span: $DIR/str-patterns.rs:12:21: 12:23 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(16), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).16), + value: e4, + }, + ty: (), + temp_scope_id: 16, + span: $DIR/str-patterns.rs:12:21: 12:23 (#0), + }, + Expr { + kind: Block { + block: b2, + }, + ty: (), + temp_scope_id: 20, + span: $DIR/str-patterns.rs:13:14: 13:16 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(20), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).20), + value: e6, + }, + ty: (), + temp_scope_id: 20, + span: $DIR/str-patterns.rs:13:14: 13:16 (#0), + }, + Expr { + kind: Match { + scrutinee: e1, + arms: [ + a0, + a1, + a2, + ], + match_source: Normal, + }, + ty: (), + temp_scope_id: 4, + span: $DIR/str-patterns.rs:10:5: 14:6 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(4), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).4), + value: e8, + }, + ty: (), + temp_scope_id: 4, + span: $DIR/str-patterns.rs:10:5: 14:6 (#0), + }, + Expr { + kind: Block { + block: b3, + }, + ty: (), + temp_scope_id: 22, + span: $DIR/str-patterns.rs:9:29: 15:2 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(22), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).22), + value: e10, + }, + ty: (), + temp_scope_id: 22, + span: $DIR/str-patterns.rs:9:29: 15:2 (#0), + }, + ], + stmts: [], + params: [ + Param { + pat: Some( + Pat { + ty: &'{erased} str, + span: $DIR/str-patterns.rs:9:20: 9:21 (#0), + extra: None, + kind: Binding { + name: "x", + mode: BindingMode( + No, + Not, + ), + var: LocalVarId( + HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).2), + ), + ty: &'{erased} str, + subpattern: None, + is_primary: true, + is_shorthand: false, + }, + }, + ), + ty: &'{erased} str, + ty_span: Some( + $DIR/str-patterns.rs:9:23: 9:27 (#0), + ), + self_kind: None, + hir_id: Some( + HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).1), + ), + }, + ], +} + +DefId(0:4 ~ str_patterns[fc71]::CONSTANT): +Thir { + body_type: Const( + &'{erased} str, + ), + arms: [], + blocks: [], + exprs: [ + Expr { + kind: Literal { + lit: Spanned { + node: Str( + "constant", + Cooked, + ), + span: $DIR/str-patterns.rs:17:24: 17:34 (#0), + }, + neg: false, + }, + ty: &'{erased} str, + temp_scope_id: 5, + span: $DIR/str-patterns.rs:17:24: 17:34 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(5), + hir_id: HirId(DefId(0:4 ~ str_patterns[fc71]::CONSTANT).5), + value: e0, + }, + ty: &'{erased} str, + temp_scope_id: 5, + span: $DIR/str-patterns.rs:17:24: 17:34 (#0), + }, + ], + stmts: [], + params: [], +} + From 066eb6d2eaea164d3623df9b2bde383e9c8917f3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 15 Jan 2026 00:17:06 +1100 Subject: [PATCH 2186/3801] THIR patterns: Always use type `str` for string-constant-value nodes --- .../src/builder/matches/match_pair.rs | 16 +---- .../src/builder/matches/mod.rs | 6 +- .../src/builder/matches/test.rs | 62 +++++++---------- .../src/thir/pattern/const_to_pat.rs | 45 ++++++------ compiler/rustc_pattern_analysis/src/rustc.rs | 20 ++---- ....constant_eq.SimplifyCfg-initial.after.mir | 37 ++++++---- tests/ui/thir-print/str-patterns.stdout | 68 +++++++++++-------- 7 files changed, 118 insertions(+), 136 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 3edd0234b0ad..e80e29415e6f 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -2,7 +2,6 @@ use std::sync::Arc; use rustc_abi::FieldIdx; use rustc_middle::mir::*; -use rustc_middle::span_bug; use rustc_middle::thir::*; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; @@ -160,10 +159,7 @@ impl<'tcx> MatchPairTree<'tcx> { } PatKind::Constant { value } => { - // CAUTION: The type of the pattern node (`pattern.ty`) is - // _often_ the same as the type of the const value (`value.ty`), - // but there are some cases where those types differ - // (e.g. when `deref!(..)` patterns interact with `String`). + assert_eq!(pattern.ty, value.ty); // Classify the constant-pattern into further kinds, to // reduce the number of ad-hoc type tests needed later on. @@ -175,16 +171,6 @@ impl<'tcx> MatchPairTree<'tcx> { } else if pat_ty.is_floating_point() { PatConstKind::Float } else if pat_ty.is_str() { - // Deref-patterns can cause string-literal patterns to have - // type `str` instead of the usual `&str`. - if !cx.tcx.features().deref_patterns() { - span_bug!( - pattern.span, - "const pattern has type `str` but deref_patterns is not enabled" - ); - } - PatConstKind::String - } else if pat_ty.is_imm_ref_str() { PatConstKind::String } else { // FIXME(Zalathar): This still covers several different diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 0463f7c914a4..ddd70a3b597c 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1339,11 +1339,9 @@ enum TestKind<'tcx> { /// Tests the place against a string constant using string equality. StringEq { - /// Constant `&str` value to test against. + /// Constant string value to test against. + /// Note that this value has type `str` (not `&str`). value: ty::Value<'tcx>, - /// Type of the corresponding pattern node. Usually `&str`, but could - /// be `str` for patterns like `deref!("..."): String`. - pat_ty: Ty<'tcx>, }, /// Tests the place against a constant using scalar equality. diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index c2e39d47a92c..bab9f38f084d 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -9,10 +9,10 @@ use std::sync::Arc; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::{LangItem, RangeEnd}; +use rustc_middle::bug; use rustc_middle::mir::*; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt}; -use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; @@ -39,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TestKind::SwitchInt } TestableCase::Constant { value, kind: PatConstKind::String } => { - TestKind::StringEq { value, pat_ty: match_pair.pattern_ty } + TestKind::StringEq { value } } TestableCase::Constant { value, kind: PatConstKind::Float | PatConstKind::Other } => { TestKind::ScalarEq { value, pat_ty: match_pair.pattern_ty } @@ -141,47 +141,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate(block, self.source_info(match_start_span), terminator); } - TestKind::StringEq { value, pat_ty } => { + TestKind::StringEq { value } => { let tcx = self.tcx; let success_block = target_block(TestBranch::Success); let fail_block = target_block(TestBranch::Failure); - let expected_value_ty = value.ty; + let ref_str_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, tcx.types.str_); + assert!(ref_str_ty.is_imm_ref_str(), "{ref_str_ty:?}"); + + // The string constant we're testing against has type `str`, but + // calling `::eq` requires `&str` operands. + // + // Because `str` and `&str` have the same valtree representation, + // we can "cast" to the desired type by just replacing the type. + assert!(value.ty.is_str(), "unexpected value type for StringEq test: {value:?}"); + let expected_value = ty::Value { ty: ref_str_ty, valtree: value.valtree }; let expected_value_operand = - self.literal_operand(test.span, Const::from_ty_value(tcx, value)); + self.literal_operand(test.span, Const::from_ty_value(tcx, expected_value)); - let mut actual_value_ty = pat_ty; - let mut actual_value_place = place; - - match pat_ty.kind() { - ty::Str => { - // String literal patterns may have type `str` if `deref_patterns` is - // enabled, in order to allow `deref!("..."): String`. In this case, `value` - // is of type `&str`, so we compare it to `&place`. - if !tcx.features().deref_patterns() { - span_bug!( - test.span, - "matching on `str` went through without enabling deref_patterns" - ); - } - let re_erased = tcx.lifetimes.re_erased; - let ref_str_ty = Ty::new_imm_ref(tcx, re_erased, tcx.types.str_); - let ref_place = self.temp(ref_str_ty, test.span); - // `let ref_place: &str = &place;` - self.cfg.push_assign( - block, - self.source_info(test.span), - ref_place, - Rvalue::Ref(re_erased, BorrowKind::Shared, place), - ); - actual_value_place = ref_place; - actual_value_ty = ref_str_ty; - } - _ => {} - } - - assert_eq!(expected_value_ty, actual_value_ty); - assert!(actual_value_ty.is_imm_ref_str()); + // Similarly, the scrutinized place has type `str`, but we need `&str`. + // Get a reference by doing `let actual_value_ref_place: &str = &place`. + let actual_value_ref_place = self.temp(ref_str_ty, test.span); + self.cfg.push_assign( + block, + self.source_info(test.span), + actual_value_ref_place, + Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, place), + ); // Compare two strings using `::eq`. // (Interestingly this means that exhaustiveness analysis relies, for soundness, @@ -192,7 +178,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fail_block, source_info, expected_value_operand, - Operand::Copy(actual_value_place), + Operand::Copy(actual_value_ref_place), ); } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 02409d2bae9f..70bc142131e4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -289,32 +289,29 @@ impl<'tcx> ConstToPat<'tcx> { suffix: Box::new([]), }, ty::Str => { - // String literal patterns may have type `str` if `deref_patterns` is enabled, in - // order to allow `deref!("..."): String`. Since we need a `&str` for the comparison - // when lowering to MIR in `Builder::perform_test`, treat the constant as a `&str`. - // This works because `str` and `&str` have the same valtree representation. - let ref_str_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, ty); - PatKind::Constant { value: ty::Value { ty: ref_str_ty, valtree: cv } } + // Constant/literal patterns of type `&str` are lowered to a + // `PatKind::Deref` wrapping a `PatKind::Constant` of type `str`. + // This pattern node is the `str` constant part. + // + // Under `feature(deref_patterns)`, string literal patterns can also + // have type `str` directly, without the `&`, in order to allow things + // like `deref!("...")` to work when the scrutinee is `String`. + PatKind::Constant { value: ty::Value { ty, valtree: cv } } } - ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() { - // `&str` is represented as a valtree, let's keep using this - // optimization for now. - ty::Str => PatKind::Constant { value: ty::Value { ty, valtree: cv } }, - // All other references are converted into deref patterns and then recursively - // convert the dereferenced constant to a pattern that is the sub-pattern of the - // deref pattern. - _ => { - if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() { - return self.mk_err( - tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }), - ty, - ); - } else { - // References have the same valtree representation as their pointee. - PatKind::Deref { subpattern: self.valtree_to_pat(cv, *pointee_ty) } - } + ty::Ref(_, pointee_ty, ..) => { + if pointee_ty.is_str() + || pointee_ty.is_slice() + || pointee_ty.is_sized(tcx, self.typing_env) + { + // References have the same valtree representation as their pointee. + PatKind::Deref { subpattern: self.valtree_to_pat(cv, *pointee_ty) } + } else { + return self.mk_err( + tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }), + ty, + ); } - }, + } ty::Float(flt) => { let v = cv.to_leaf(); let is_nan = match flt { diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 721635ed48ff..5e75192ff309 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -583,19 +583,13 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { fields = vec![]; arity = 0; } - ty::Ref(_, t, _) if t.is_str() => { - // We want a `&str` constant to behave like a `Deref` pattern, to be compatible - // with other `Deref` patterns. This could have been done in `const_to_pat`, - // but that causes issues with the rest of the matching code. - // So here, the constructor for a `"foo"` pattern is `&` (represented by - // `Ref`), and has one field. That field has constructor `Str(value)` and no - // subfields. - // Note: `t` is `str`, not `&str`. - let ty = self.reveal_opaque_ty(*t); - let subpattern = DeconstructedPat::new(Str(*value), Vec::new(), 0, ty, pat); - ctor = Ref; - fields = vec![subpattern.at_index(0)]; - arity = 1; + ty::Str => { + // For constant/literal patterns of type `&str`, the THIR + // pattern is a `PatKind::Deref` of type `&str` wrapping a + // `PatKind::Const` of type `str`. + ctor = Str(*value); + fields = vec![]; + arity = 0; } // All constants that can be structurally matched have already been expanded // into the corresponding `Pat`s by `const_to_pat`. Constants that remain are diff --git a/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir index b8f54fef0faf..4d13d087586e 100644 --- a/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir @@ -7,11 +7,14 @@ fn constant_eq(_1: &str, _2: bool) -> u32 { let mut _3: (&str, bool); let mut _4: &str; let mut _5: bool; - let mut _6: &&str; - let mut _7: &bool; - let mut _8: bool; - let mut _9: bool; + let mut _6: &str; + let mut _7: &&str; + let mut _8: &bool; + let mut _9: &str; let mut _10: bool; + let mut _11: &str; + let mut _12: bool; + let mut _13: bool; bb0: { StorageLive(_3); @@ -23,7 +26,8 @@ fn constant_eq(_1: &str, _2: bool) -> u32 { StorageDead(_5); StorageDead(_4); PlaceMention(_3); - _9 = ::eq(copy (_3.0: &str), const "a") -> [return: bb9, unwind: bb19]; + _11 = &(*(_3.0: &str)); + _12 = ::eq(copy _11, const "a") -> [return: bb9, unwind: bb19]; } bb1: { @@ -43,7 +47,8 @@ fn constant_eq(_1: &str, _2: bool) -> u32 { } bb5: { - _8 = ::eq(copy (_3.0: &str), const "b") -> [return: bb8, unwind: bb19]; + _9 = &(*(_3.0: &str)); + _10 = ::eq(copy _9, const "b") -> [return: bb8, unwind: bb19]; } bb6: { @@ -55,11 +60,11 @@ fn constant_eq(_1: &str, _2: bool) -> u32 { } bb8: { - switchInt(move _8) -> [0: bb1, otherwise: bb6]; + switchInt(move _10) -> [0: bb1, otherwise: bb6]; } bb9: { - switchInt(move _9) -> [0: bb5, otherwise: bb2]; + switchInt(move _12) -> [0: bb5, otherwise: bb2]; } bb10: { @@ -87,23 +92,25 @@ fn constant_eq(_1: &str, _2: bool) -> u32 { } bb15: { - _6 = &fake shallow (_3.0: &str); - _7 = &fake shallow (_3.1: bool); - StorageLive(_10); - _10 = const true; - switchInt(move _10) -> [0: bb17, otherwise: bb16]; + _6 = &fake shallow (*(_3.0: &str)); + _7 = &fake shallow (_3.0: &str); + _8 = &fake shallow (_3.1: bool); + StorageLive(_13); + _13 = const true; + switchInt(move _13) -> [0: bb17, otherwise: bb16]; } bb16: { - StorageDead(_10); + StorageDead(_13); FakeRead(ForMatchGuard, _6); FakeRead(ForMatchGuard, _7); + FakeRead(ForMatchGuard, _8); _0 = const 1_u32; goto -> bb18; } bb17: { - StorageDead(_10); + StorageDead(_13); falseEdge -> [real: bb3, imaginary: bb5]; } diff --git a/tests/ui/thir-print/str-patterns.stdout b/tests/ui/thir-print/str-patterns.stdout index 8f8944ad4e09..6941ab15130f 100644 --- a/tests/ui/thir-print/str-patterns.stdout +++ b/tests/ui/thir-print/str-patterns.stdout @@ -9,18 +9,25 @@ Thir { ty: &'{erased} str, span: $DIR/str-patterns.rs:11:9: 11:16 (#0), extra: None, - kind: Constant { - value: Value { - ty: &'{erased} str, - valtree: Branch( - [ - 104_u8, - 101_u8, - 108_u8, - 108_u8, - 111_u8, - ], - ), + kind: Deref { + subpattern: Pat { + ty: str, + span: $DIR/str-patterns.rs:11:9: 11:16 (#0), + extra: None, + kind: Constant { + value: Value { + ty: str, + valtree: Branch( + [ + 104_u8, + 101_u8, + 108_u8, + 108_u8, + 111_u8, + ], + ), + }, + }, }, }, }, @@ -42,21 +49,28 @@ Thir { ascriptions: [], }, ), - kind: Constant { - value: Value { - ty: &'{erased} str, - valtree: Branch( - [ - 99_u8, - 111_u8, - 110_u8, - 115_u8, - 116_u8, - 97_u8, - 110_u8, - 116_u8, - ], - ), + kind: Deref { + subpattern: Pat { + ty: str, + span: $DIR/str-patterns.rs:12:9: 12:17 (#0), + extra: None, + kind: Constant { + value: Value { + ty: str, + valtree: Branch( + [ + 99_u8, + 111_u8, + 110_u8, + 115_u8, + 116_u8, + 97_u8, + 110_u8, + 116_u8, + ], + ), + }, + }, }, }, }, From e673bf57c224f2449f810911f94c909a7ffd5f8c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 15 Jan 2026 16:44:14 +1100 Subject: [PATCH 2187/3801] Also remove `pat_ty` from `TestKind::ScalarEq` --- compiler/rustc_mir_build/src/builder/matches/mod.rs | 6 +----- compiler/rustc_mir_build/src/builder/matches/test.rs | 12 ++++-------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index ddd70a3b597c..11a181cfa8ce 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1345,11 +1345,7 @@ enum TestKind<'tcx> { }, /// Tests the place against a constant using scalar equality. - ScalarEq { - value: ty::Value<'tcx>, - /// Type of the corresponding pattern node. - pat_ty: Ty<'tcx>, - }, + ScalarEq { value: ty::Value<'tcx> }, /// Test whether the value falls within an inclusive or exclusive range. Range(Arc>), diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index bab9f38f084d..5c3173a7b148 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TestKind::StringEq { value } } TestableCase::Constant { value, kind: PatConstKind::Float | PatConstKind::Other } => { - TestKind::ScalarEq { value, pat_ty: match_pair.pattern_ty } + TestKind::ScalarEq { value } } TestableCase::Range(ref range) => { @@ -182,7 +182,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); } - TestKind::ScalarEq { value, pat_ty } => { + TestKind::ScalarEq { value } => { let tcx = self.tcx; let success_block = target_block(TestBranch::Success); let fail_block = target_block(TestBranch::Failure); @@ -191,12 +191,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut expected_value_operand = self.literal_operand(test.span, Const::from_ty_value(tcx, value)); - let mut actual_value_ty = pat_ty; let mut actual_value_place = place; - match pat_ty.kind() { + match value.ty.kind() { &ty::Pat(base, _) => { - assert_eq!(pat_ty, value.ty); assert!(base.is_trivially_pure_clone_copy()); let transmuted_place = self.temp(base, test.span); @@ -220,15 +218,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); actual_value_place = transmuted_place; - actual_value_ty = base; expected_value_operand = Operand::Copy(transmuted_expect); expected_value_ty = base; } _ => {} } - assert_eq!(expected_value_ty, actual_value_ty); - assert!(actual_value_ty.is_scalar()); + assert!(expected_value_ty.is_scalar()); self.compare( block, From 8dfb888812dd3727cb2edca012cfac220db1d061 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 16 Jan 2026 09:27:45 +0800 Subject: [PATCH 2188/3801] Disable `dump-ice-to-disk` on `i686-pc-windows-msvc` Sometimes the middle frames of the ICE backtrace becomes `` on `i686-pc-windows-msvc` which then makes this test flaky. --- tests/run-make/dump-ice-to-disk/rmake.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/run-make/dump-ice-to-disk/rmake.rs b/tests/run-make/dump-ice-to-disk/rmake.rs index 09a34cdeb5e7..319cbc6e0ca8 100644 --- a/tests/run-make/dump-ice-to-disk/rmake.rs +++ b/tests/run-make/dump-ice-to-disk/rmake.rs @@ -18,13 +18,16 @@ //! # Test history //! //! The previous rmake.rs iteration of this test was flaky for unknown reason on -//! `i686-pc-windows-gnu` *specifically*, so assertion failures in this test was made extremely -//! verbose to help diagnose why the ICE messages was different. It appears that backtraces on -//! `i686-pc-windows-gnu` specifically are quite unpredictable in how many backtrace frames are -//! involved. +//! `i686-pc-windows-gnu`, so assertion failures in this test was made extremely verbose to help +//! diagnose why the ICE messages was different. It appears that backtraces on `i686-pc-windows-gnu` +//! specifically are quite unpredictable in how many backtrace frames are involved. +//! +//! Disabled on `i686-pc-windows-msvc` as well, because sometimes the middle portion of the ICE +//! backtrace becomes ``. //@ ignore-cross-compile (exercising ICE dump on host) //@ ignore-i686-pc-windows-gnu (unwind mechanism produces unpredictable backtraces) +//@ ignore-i686-pc-windows-msvc (sometimes partial backtrace becomes ``) use std::cell::OnceCell; use std::path::{Path, PathBuf}; From bfd1a9a86f5f344f09a550338eeb08c29458015c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 16 Jan 2026 02:14:01 +0000 Subject: [PATCH 2189/3801] Use default_field_values more in `Resolver` Provide `const` functions to get around lack of `const Default` for `FxHash*` types. Use default field values in `Resolver` more. --- compiler/rustc_data_structures/src/fx.rs | 15 +++++ compiler/rustc_resolve/src/lib.rs | 77 ++++++++---------------- 2 files changed, 41 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_data_structures/src/fx.rs b/compiler/rustc_data_structures/src/fx.rs index c1a5c8ebc764..026ec5c230ec 100644 --- a/compiler/rustc_data_structures/src/fx.rs +++ b/compiler/rustc_data_structures/src/fx.rs @@ -28,3 +28,18 @@ macro_rules! define_stable_id_collections { pub type $entry_name<'a, T> = $crate::fx::IndexEntry<'a, $key, T>; }; } + +pub mod default { + use super::{FxBuildHasher, FxHashMap, FxHashSet}; + + // FIXME: These two functions will become unnecessary after + // lands and we start using the corresponding + // `rustc-hash` version. After that we can use `Default::default()` instead. + pub const fn fx_hash_map() -> FxHashMap { + FxHashMap::with_hasher(FxBuildHasher) + } + + pub const fn fx_hash_set() -> FxHashSet { + FxHashSet::with_hasher(FxBuildHasher) + } +} diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 2c22aacb3241..b7efff929f70 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -45,7 +45,7 @@ use rustc_ast::{ self as ast, AngleBracketedArg, CRATE_NODE_ID, Crate, Expr, ExprKind, GenericArg, GenericArgs, NodeId, Path, attr, }; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, default}; use rustc_data_structures::intern::Interned; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{FreezeReadGuard, FreezeWriteGuard}; @@ -1129,7 +1129,7 @@ pub struct Resolver<'ra, 'tcx> { /// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax. /// Used for hints during error reporting. - field_visibility_spans: FxHashMap>, + field_visibility_spans: FxHashMap> = default::fx_hash_map(), /// All imports known to succeed or fail. determined_imports: Vec> = Vec::new(), @@ -1146,7 +1146,7 @@ pub struct Resolver<'ra, 'tcx> { /// Resolutions for import nodes, which have multiple resolutions in different namespaces. import_res_map: NodeMap>>, /// An import will be inserted into this map if it has been used. - import_use_map: FxHashMap, Used>, + import_use_map: FxHashMap, Used> = default::fx_hash_map(), /// Resolutions for labels (node IDs of their corresponding blocks or loops). label_res_map: NodeMap, /// Resolutions for lifetimes. @@ -1190,7 +1190,7 @@ pub struct Resolver<'ra, 'tcx> { glob_map: FxIndexMap>, glob_error: Option = None, visibilities_for_hashing: Vec<(LocalDefId, Visibility)> = Vec::new(), - used_imports: FxHashSet, + used_imports: FxHashSet = default::fx_hash_set(), maybe_unused_trait_imports: FxIndexSet, /// Privacy errors are delayed until the end in order to deduplicate them. @@ -1206,30 +1206,30 @@ pub struct Resolver<'ra, 'tcx> { /// When a type is re-exported that has an inaccessible constructor because it has fields that /// are inaccessible from the import's scope, we mark that as the type won't be able to be built /// through the re-export. We use this information to extend the existing diagnostic. - inaccessible_ctor_reexport: FxHashMap, + inaccessible_ctor_reexport: FxHashMap = default::fx_hash_map(), arenas: &'ra ResolverArenas<'ra>, dummy_decl: Decl<'ra>, builtin_type_decls: FxHashMap>, builtin_attr_decls: FxHashMap>, registered_tool_decls: FxHashMap>, - macro_names: FxHashSet, - builtin_macros: FxHashMap, + macro_names: FxHashSet = default::fx_hash_set(), + builtin_macros: FxHashMap = default::fx_hash_map(), registered_tools: &'tcx RegisteredTools, macro_use_prelude: FxIndexMap>, /// Eagerly populated map of all local macro definitions. - local_macro_map: FxHashMap, + local_macro_map: FxHashMap = default::fx_hash_map(), /// Lazily populated cache of macro definitions loaded from external crates. extern_macro_map: CacheRefCell>, dummy_ext_bang: Arc, dummy_ext_derive: Arc, non_macro_attr: &'ra MacroData, - local_macro_def_scopes: FxHashMap>, - ast_transform_scopes: FxHashMap>, + local_macro_def_scopes: FxHashMap> = default::fx_hash_map(), + ast_transform_scopes: FxHashMap> = default::fx_hash_map(), unused_macros: FxIndexMap, /// A map from the macro to all its potentially unused arms. unused_macro_rules: FxIndexMap>, - proc_macro_stubs: FxHashSet, + proc_macro_stubs: FxHashSet = default::fx_hash_set(), /// Traces collected during macro resolution and validated when it's complete. single_segment_macro_resolutions: CmRefCell, Option>, Option)>>, @@ -1239,23 +1239,23 @@ pub struct Resolver<'ra, 'tcx> { /// `derive(Copy)` marks items they are applied to so they are treated specially later. /// Derive macros cannot modify the item themselves and have to store the markers in the global /// context, so they attach the markers to derive container IDs using this resolver table. - containers_deriving_copy: FxHashSet, + containers_deriving_copy: FxHashSet = default::fx_hash_set(), /// Parent scopes in which the macros were invoked. /// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere. - invocation_parent_scopes: FxHashMap>, + invocation_parent_scopes: FxHashMap> = default::fx_hash_map(), /// `macro_rules` scopes *produced* by expanding the macro invocations, /// include all the `macro_rules` items and other invocations generated by them. - output_macro_rules_scopes: FxHashMap>, + output_macro_rules_scopes: FxHashMap> = default::fx_hash_map(), /// `macro_rules` scopes produced by `macro_rules` item definitions. - macro_rules_scopes: FxHashMap>, + macro_rules_scopes: FxHashMap> = default::fx_hash_map(), /// Helper attributes that are in scope for the given expansion. - helper_attrs: FxHashMap)>>, + helper_attrs: FxHashMap)>> = default::fx_hash_map(), /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute /// with the given `ExpnId`. - derive_data: FxHashMap, + derive_data: FxHashMap = default::fx_hash_map(), /// Avoid duplicated errors for "name already defined". - name_already_seen: FxHashMap, + name_already_seen: FxHashMap = default::fx_hash_map(), potentially_unused_imports: Vec> = Vec::new(), @@ -1275,14 +1275,14 @@ pub struct Resolver<'ra, 'tcx> { disambiguator: DisambiguatorState, /// Indices of unnamed struct or variant fields with unresolved attributes. - placeholder_field_indices: FxHashMap, + placeholder_field_indices: FxHashMap = default::fx_hash_map(), /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId` /// we know what parent node that fragment should be attached to thanks to this table, /// and how the `impl Trait` fragments were introduced. invocation_parents: FxHashMap, /// Amount of lifetime parameters for each item in the crate. - item_generics_num_lifetimes: FxHashMap, + item_generics_num_lifetimes: FxHashMap = default::fx_hash_map(), delegation_fn_sigs: LocalDefIdMap, delegation_infos: LocalDefIdMap, @@ -1293,7 +1293,7 @@ pub struct Resolver<'ra, 'tcx> { proc_macros: Vec = Vec::new(), confused_type_with_std_module: FxIndexMap, /// Whether lifetime elision was successful. - lifetime_elision_allowed: FxHashSet, + lifetime_elision_allowed: FxHashSet = default::fx_hash_set(), /// Names of items that were stripped out via cfg with their corresponding cfg meta item. stripped_cfg_items: Vec> = Vec::new(), @@ -1304,19 +1304,19 @@ pub struct Resolver<'ra, 'tcx> { all_macro_rules: UnordSet, /// Invocation ids of all glob delegations. - glob_delegation_invoc_ids: FxHashSet, + glob_delegation_invoc_ids: FxHashSet = default::fx_hash_set(), /// Analogue of module `unexpanded_invocations` but in trait impls, excluding glob delegations. /// Needed because glob delegations wait for all other neighboring macros to expand. - impl_unexpanded_invocations: FxHashMap>, + impl_unexpanded_invocations: FxHashMap> = default::fx_hash_map(), /// Simplified analogue of module `resolutions` but in trait impls, excluding glob delegations. /// Needed because glob delegations exclude explicitly defined names. - impl_binding_keys: FxHashMap>, + impl_binding_keys: FxHashMap> = default::fx_hash_map(), /// This is the `Span` where an `extern crate foo;` suggestion would be inserted, if `foo` /// could be a crate that wasn't imported. For diagnostics use only. current_crate_outer_attr_insert_span: Span, - mods_with_parse_errors: FxHashSet, + mods_with_parse_errors: FxHashSet = default::fx_hash_set(), /// Whether `Resolver::register_macros_for_all_crates` has been called once already, as we /// don't need to run it more than once. @@ -1325,7 +1325,7 @@ pub struct Resolver<'ra, 'tcx> { // Stores pre-expansion and pre-placeholder-fragment-insertion names for `impl Trait` types // that were encountered during resolution. These names are used to generate item names // for APITs, so we don't want to leak details of resolution into these names. - impl_trait_names: FxHashMap, + impl_trait_names: FxHashMap = default::fx_hash_map(), } /// This provides memory for the rest of the crate. The `'ra` lifetime that is @@ -1598,12 +1598,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { field_names: Default::default(), field_defaults: Default::default(), - field_visibility_spans: FxHashMap::default(), pat_span_map: Default::default(), partial_res_map: Default::default(), import_res_map: Default::default(), - import_use_map: Default::default(), label_res_map: Default::default(), lifetimes_res_map: Default::default(), extra_lifetime_params_map: Default::default(), @@ -1616,12 +1614,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { local_module_map, extern_module_map: Default::default(), block_map: Default::default(), - ast_transform_scopes: FxHashMap::default(), glob_map: Default::default(), - used_imports: FxHashSet::default(), maybe_unused_trait_imports: Default::default(), - inaccessible_ctor_reexport: Default::default(), arenas, dummy_decl: arenas.new_pub_def_decl(Res::Err, DUMMY_SP, LocalExpnId::ROOT), @@ -1649,52 +1644,32 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { (*ident, decl) }) .collect(), - macro_names: FxHashSet::default(), - builtin_macros: Default::default(), registered_tools, macro_use_prelude: Default::default(), - local_macro_map: Default::default(), extern_macro_map: Default::default(), dummy_ext_bang: Arc::new(SyntaxExtension::dummy_bang(edition)), dummy_ext_derive: Arc::new(SyntaxExtension::dummy_derive(edition)), non_macro_attr: arenas .alloc_macro(MacroData::new(Arc::new(SyntaxExtension::non_macro_attr(edition)))), - invocation_parent_scopes: Default::default(), - output_macro_rules_scopes: Default::default(), - macro_rules_scopes: Default::default(), - helper_attrs: Default::default(), - derive_data: Default::default(), - local_macro_def_scopes: FxHashMap::default(), - name_already_seen: FxHashMap::default(), struct_constructors: Default::default(), unused_macros: Default::default(), unused_macro_rules: Default::default(), - proc_macro_stubs: Default::default(), single_segment_macro_resolutions: Default::default(), multi_segment_macro_resolutions: Default::default(), builtin_attrs: Default::default(), - containers_deriving_copy: Default::default(), lint_buffer: LintBuffer::default(), node_id_to_def_id, disambiguator: DisambiguatorState::new(), - placeholder_field_indices: Default::default(), invocation_parents, - item_generics_num_lifetimes: Default::default(), trait_impls: Default::default(), confused_type_with_std_module: Default::default(), - lifetime_elision_allowed: Default::default(), stripped_cfg_items: Default::default(), effective_visibilities: Default::default(), doc_link_resolutions: Default::default(), doc_link_traits_in_scope: Default::default(), all_macro_rules: Default::default(), delegation_fn_sigs: Default::default(), - glob_delegation_invoc_ids: Default::default(), - impl_unexpanded_invocations: Default::default(), - impl_binding_keys: Default::default(), current_crate_outer_attr_insert_span, - mods_with_parse_errors: Default::default(), - impl_trait_names: Default::default(), delegation_infos: Default::default(), .. }; From 2766ccfd4e419bae7d1b30d0f1e80d423bffee83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 16 Jan 2026 02:23:44 +0000 Subject: [PATCH 2190/3801] Make `UnordSet` and `UnordMap` `const Default` and use it in `Resolver` --- compiler/rustc_data_structures/src/lib.rs | 2 ++ compiler/rustc_data_structures/src/unord.rs | 10 +++--- compiler/rustc_resolve/src/lib.rs | 34 ++++++++------------- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 41f6292e740b..ff1dd41c82cc 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -18,6 +18,8 @@ #![feature(assert_matches)] #![feature(auto_traits)] #![feature(cfg_select)] +#![feature(const_default)] +#![feature(const_trait_impl)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(extend_one)] diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index 3d44fb1fd48d..0a9a86d7a43b 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs @@ -8,7 +8,7 @@ use std::hash::Hash; use std::iter::{Product, Sum}; use std::ops::Index; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet}; use rustc_macros::{Decodable_NoContext, Encodable_NoContext}; use crate::fingerprint::Fingerprint; @@ -241,10 +241,10 @@ pub struct UnordSet { impl UnordCollection for UnordSet {} -impl Default for UnordSet { +impl const Default for UnordSet { #[inline] fn default() -> Self { - Self { inner: FxHashSet::default() } + Self { inner: FxHashSet::with_hasher(FxBuildHasher) } } } @@ -438,10 +438,10 @@ pub struct UnordMap { impl UnordCollection for UnordMap {} -impl Default for UnordMap { +impl const Default for UnordMap { #[inline] fn default() -> Self { - Self { inner: FxHashMap::default() } + Self { inner: FxHashMap::with_hasher(FxBuildHasher) } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b7efff929f70..c31cec482351 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -13,6 +13,8 @@ #![feature(arbitrary_self_types)] #![feature(assert_matches)] #![feature(box_patterns)] +#![feature(const_default)] +#![feature(const_trait_impl)] #![feature(control_flow_into_value)] #![feature(decl_macro)] #![feature(default_field_values)] @@ -1113,7 +1115,7 @@ pub struct Resolver<'ra, 'tcx> { tcx: TyCtxt<'tcx>, /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. - expn_that_defined: UnordMap, + expn_that_defined: UnordMap = Default::default(), graph_root: Module<'ra>, @@ -1124,8 +1126,8 @@ pub struct Resolver<'ra, 'tcx> { extern_prelude: FxIndexMap>, /// N.B., this is used only for better diagnostics, not name resolution itself. - field_names: LocalDefIdMap>, - field_defaults: LocalDefIdMap>, + field_names: LocalDefIdMap> = Default::default(), + field_defaults: LocalDefIdMap> = Default::default(), /// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax. /// Used for hints during error reporting. @@ -1155,9 +1157,9 @@ pub struct Resolver<'ra, 'tcx> { extra_lifetime_params_map: NodeMap>, /// `CrateNum` resolutions of `extern crate` items. - extern_crate_map: UnordMap, - module_children: LocalDefIdMap>, - ambig_module_children: LocalDefIdMap>, + extern_crate_map: UnordMap = Default::default(), + module_children: LocalDefIdMap> = Default::default(), + ambig_module_children: LocalDefIdMap> = Default::default(), trait_map: NodeMap>, /// A map from nodes to anonymous modules. @@ -1264,7 +1266,7 @@ pub struct Resolver<'ra, 'tcx> { /// Table for mapping struct IDs into struct constructor IDs, /// it's not used during normal resolution, only for better error reporting. /// Also includes of list of each fields visibility - struct_constructors: LocalDefIdMap<(Res, Visibility, Vec>)>, + struct_constructors: LocalDefIdMap<(Res, Visibility, Vec>)> = Default::default(), lint_buffer: LintBuffer, @@ -1283,8 +1285,8 @@ pub struct Resolver<'ra, 'tcx> { /// Amount of lifetime parameters for each item in the crate. item_generics_num_lifetimes: FxHashMap = default::fx_hash_map(), - delegation_fn_sigs: LocalDefIdMap, - delegation_infos: LocalDefIdMap, + delegation_fn_sigs: LocalDefIdMap = Default::default(), + delegation_infos: LocalDefIdMap = Default::default(), main_def: Option = None, trait_impls: FxIndexMap>, @@ -1301,7 +1303,7 @@ pub struct Resolver<'ra, 'tcx> { effective_visibilities: EffectiveVisibilities, doc_link_resolutions: FxIndexMap, doc_link_traits_in_scope: FxIndexMap>, - all_macro_rules: UnordSet, + all_macro_rules: UnordSet = Default::default(), /// Invocation ids of all glob delegations. glob_delegation_invoc_ids: FxHashSet = default::fx_hash_set(), @@ -1587,8 +1589,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut resolver = Resolver { tcx, - expn_that_defined: Default::default(), - // The outermost module has def ID 0; this is not reflected in the // AST. graph_root, @@ -1596,18 +1596,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { prelude: None, extern_prelude, - field_names: Default::default(), - field_defaults: Default::default(), - pat_span_map: Default::default(), partial_res_map: Default::default(), import_res_map: Default::default(), label_res_map: Default::default(), lifetimes_res_map: Default::default(), extra_lifetime_params_map: Default::default(), - extern_crate_map: Default::default(), - module_children: Default::default(), - ambig_module_children: Default::default(), trait_map: NodeMap::default(), empty_module, local_modules, @@ -1651,7 +1645,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { dummy_ext_derive: Arc::new(SyntaxExtension::dummy_derive(edition)), non_macro_attr: arenas .alloc_macro(MacroData::new(Arc::new(SyntaxExtension::non_macro_attr(edition)))), - struct_constructors: Default::default(), unused_macros: Default::default(), unused_macro_rules: Default::default(), single_segment_macro_resolutions: Default::default(), @@ -1667,10 +1660,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { effective_visibilities: Default::default(), doc_link_resolutions: Default::default(), doc_link_traits_in_scope: Default::default(), - all_macro_rules: Default::default(), - delegation_fn_sigs: Default::default(), current_crate_outer_attr_insert_span, - delegation_infos: Default::default(), .. }; From dd4d60f701ae8bf43fb10f69260b8ffb07faa6be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 16 Jan 2026 02:28:49 +0000 Subject: [PATCH 2191/3801] Provide default field in `Resolver` for `NodeMap` fields --- compiler/rustc_resolve/src/lib.rs | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index c31cec482351..cd4d738663d4 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1141,26 +1141,26 @@ pub struct Resolver<'ra, 'tcx> { // Spans for local variables found during pattern resolution. // Used for suggestions during error reporting. - pat_span_map: NodeMap, + pat_span_map: NodeMap = Default::default(), /// Resolutions for nodes that have a single resolution. - partial_res_map: NodeMap, + partial_res_map: NodeMap = Default::default(), /// Resolutions for import nodes, which have multiple resolutions in different namespaces. - import_res_map: NodeMap>>, + import_res_map: NodeMap>> = Default::default(), /// An import will be inserted into this map if it has been used. import_use_map: FxHashMap, Used> = default::fx_hash_map(), /// Resolutions for labels (node IDs of their corresponding blocks or loops). - label_res_map: NodeMap, + label_res_map: NodeMap = Default::default(), /// Resolutions for lifetimes. - lifetimes_res_map: NodeMap, + lifetimes_res_map: NodeMap = Default::default(), /// Lifetime parameters that lowering will have to introduce. - extra_lifetime_params_map: NodeMap>, + extra_lifetime_params_map: NodeMap> = Default::default(), /// `CrateNum` resolutions of `extern crate` items. extern_crate_map: UnordMap = Default::default(), module_children: LocalDefIdMap> = Default::default(), ambig_module_children: LocalDefIdMap> = Default::default(), - trait_map: NodeMap>, + trait_map: NodeMap> = Default::default(), /// A map from nodes to anonymous modules. /// Anonymous modules are pseudo-modules that are implicitly created around items @@ -1176,7 +1176,7 @@ pub struct Resolver<'ra, 'tcx> { /// /// There will be an anonymous module created around `g` with the ID of the /// entry block for `f`. - block_map: NodeMap>, + block_map: NodeMap> = Default::default(), /// A fake module that contains no definition and no prelude. Used so that /// some AST passes can generate identifiers that only resolve to local or /// lang items. @@ -1596,18 +1596,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { prelude: None, extern_prelude, - pat_span_map: Default::default(), - partial_res_map: Default::default(), - import_res_map: Default::default(), - label_res_map: Default::default(), - lifetimes_res_map: Default::default(), - extra_lifetime_params_map: Default::default(), - trait_map: NodeMap::default(), empty_module, local_modules, local_module_map, extern_module_map: Default::default(), - block_map: Default::default(), glob_map: Default::default(), maybe_unused_trait_imports: Default::default(), From 664e19bc3a68c88dfa433fefe39a8e0338315eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 16 Jan 2026 02:34:19 +0000 Subject: [PATCH 2192/3801] Make `DisambiguatorState` `const`-buildable --- compiler/rustc_hir/src/definitions.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 01f84c90ec7a..5e361891f6d0 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -103,7 +103,7 @@ pub struct DisambiguatorState { } impl DisambiguatorState { - pub fn new() -> Self { + pub const fn new() -> Self { Self { next: Default::default() } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index cd4d738663d4..3bee1efba886 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1237,7 +1237,7 @@ pub struct Resolver<'ra, 'tcx> { CmRefCell, Option>, Option)>>, multi_segment_macro_resolutions: CmRefCell, Span, MacroKind, ParentScope<'ra>, Option, Namespace)>>, - builtin_attrs: Vec<(Ident, ParentScope<'ra>)>, + builtin_attrs: Vec<(Ident, ParentScope<'ra>)> = Vec::new(), /// `derive(Copy)` marks items they are applied to so they are treated specially later. /// Derive macros cannot modify the item themselves and have to store the markers in the global /// context, so they attach the markers to derive container IDs using this resolver table. @@ -1274,7 +1274,7 @@ pub struct Resolver<'ra, 'tcx> { node_id_to_def_id: NodeMap>, - disambiguator: DisambiguatorState, + disambiguator: DisambiguatorState = DisambiguatorState::new(), /// Indices of unnamed struct or variant fields with unresolved attributes. placeholder_field_indices: FxHashMap = default::fx_hash_map(), @@ -1641,10 +1641,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { unused_macro_rules: Default::default(), single_segment_macro_resolutions: Default::default(), multi_segment_macro_resolutions: Default::default(), - builtin_attrs: Default::default(), lint_buffer: LintBuffer::default(), node_id_to_def_id, - disambiguator: DisambiguatorState::new(), invocation_parents, trait_impls: Default::default(), confused_type_with_std_module: Default::default(), From 2b139b786ee2bf21b8250f6dfb800a85ad2f8db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 16 Jan 2026 02:36:07 +0000 Subject: [PATCH 2193/3801] `prelude` is already defaulted --- compiler/rustc_resolve/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 3bee1efba886..d62635759981 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1593,7 +1593,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // AST. graph_root, assert_speculative: false, // Only set/cleared in Resolver::resolve_imports for now - prelude: None, extern_prelude, empty_module, From 9f6e7473d6ac3e7e1596bef17cfbfda4e563ffc7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 16 Jan 2026 14:54:14 +1100 Subject: [PATCH 2194/3801] Fix a typo. --- compiler/rustc_middle/src/query/plumbing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 8d01d9482ed4..9300c942a525 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -278,7 +278,7 @@ macro_rules! define_callbacks { ($V) ); - /// This function takes `ProvidedValue` and coverts it to an erased `Value` by + /// This function takes `ProvidedValue` and converts it to an erased `Value` by /// allocating it on an arena if the query has the `arena_cache` modifier. The /// value is then erased and returned. This will happen when computing the query /// using a provider or decoding a stored result. From 4c2e447027399f4ebe98563177c68831898c16e6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 16 Jan 2026 14:54:48 +1100 Subject: [PATCH 2195/3801] Rename `fatal_cycle` as `cycle_fatal`. To be consistent with the closely related `cycle_stash` and `cycle_delay_bug`. --- compiler/rustc_macros/src/query.rs | 12 ++++----- compiler/rustc_middle/src/query/mod.rs | 28 ++++++++++----------- compiler/rustc_middle/src/query/plumbing.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 5d32950875ad..104e95277a1a 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -93,7 +93,7 @@ struct QueryModifiers { cache: Option<(Option, Block)>, /// A cycle error for this query aborting the compilation with a fatal error. - fatal_cycle: Option, + cycle_fatal: Option, /// A cycle error results in a delay_bug call cycle_delay_bug: Option, @@ -136,7 +136,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { let mut arena_cache = None; let mut cache = None; let mut desc = None; - let mut fatal_cycle = None; + let mut cycle_fatal = None; let mut cycle_delay_bug = None; let mut cycle_stash = None; let mut no_hash = None; @@ -189,8 +189,8 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { try_insert!(cache = (args, block)); } else if modifier == "arena_cache" { try_insert!(arena_cache = modifier); - } else if modifier == "fatal_cycle" { - try_insert!(fatal_cycle = modifier); + } else if modifier == "cycle_fatal" { + try_insert!(cycle_fatal = modifier); } else if modifier == "cycle_delay_bug" { try_insert!(cycle_delay_bug = modifier); } else if modifier == "cycle_stash" { @@ -220,7 +220,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { arena_cache, cache, desc, - fatal_cycle, + cycle_fatal, cycle_delay_bug, cycle_stash, no_hash, @@ -366,8 +366,8 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { } passthrough!( - fatal_cycle, arena_cache, + cycle_fatal, cycle_delay_bug, cycle_stash, no_hash, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 5f40c36423b3..fc1bf78c82f3 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -28,7 +28,7 @@ //! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required for every query. //! - `arena_cache`: Use an arena for in-memory caching of the query result. //! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to true. -//! - `fatal_cycle`: If a dependency cycle is detected, abort compilation with a fatal error. +//! - `cycle_fatal`: If a dependency cycle is detected, abort compilation with a fatal error. //! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately. //! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling. //! - `no_hash`: Do not hash the query result for incremental compilation; just mark as dirty if recomputed. @@ -160,7 +160,7 @@ pub mod plumbing; // The result type of each query must implement `Clone`, and additionally // `ty::query::values::Value`, which produces an appropriate placeholder // (error) value if the query resulted in a query cycle. -// Queries marked with `fatal_cycle` do not need the latter implementation, +// Queries marked with `cycle_fatal` do not need the latter implementation, // as they will raise an fatal error on query cycles instead. rustc_queries! { /// This exists purely for testing the interactions between delayed bugs and incremental. @@ -584,7 +584,7 @@ rustc_queries! { } query is_panic_runtime(_: CrateNum) -> bool { - fatal_cycle + cycle_fatal desc { "checking if the crate is_panic_runtime" } separate_provide_extern } @@ -1315,7 +1315,7 @@ rustc_queries! { /// Return the set of (transitive) callees that may result in a recursive call to `key`, /// if we were able to walk all callees. query mir_callgraph_cyclic(key: LocalDefId) -> &'tcx Option> { - fatal_cycle + cycle_fatal arena_cache desc { |tcx| "computing (transitive) callees of `{}` that may recurse", @@ -1326,7 +1326,7 @@ rustc_queries! { /// Obtain all the calls into other local functions query mir_inliner_callees(key: ty::InstanceKind<'tcx>) -> &'tcx [(DefId, GenericArgsRef<'tcx>)] { - fatal_cycle + cycle_fatal desc { |tcx| "computing all local function calls in `{}`", tcx.def_path_str(key.def_id()), @@ -1822,31 +1822,31 @@ rustc_queries! { } query is_compiler_builtins(_: CrateNum) -> bool { - fatal_cycle + cycle_fatal desc { "checking if the crate is_compiler_builtins" } separate_provide_extern } query has_global_allocator(_: CrateNum) -> bool { // This query depends on untracked global state in CStore eval_always - fatal_cycle + cycle_fatal desc { "checking if the crate has_global_allocator" } separate_provide_extern } query has_alloc_error_handler(_: CrateNum) -> bool { // This query depends on untracked global state in CStore eval_always - fatal_cycle + cycle_fatal desc { "checking if the crate has_alloc_error_handler" } separate_provide_extern } query has_panic_handler(_: CrateNum) -> bool { - fatal_cycle + cycle_fatal desc { "checking if the crate has_panic_handler" } separate_provide_extern } query is_profiler_runtime(_: CrateNum) -> bool { - fatal_cycle + cycle_fatal desc { "checking if a crate is `#![profiler_runtime]`" } separate_provide_extern } @@ -1855,22 +1855,22 @@ rustc_queries! { cache_on_disk_if { true } } query required_panic_strategy(_: CrateNum) -> Option { - fatal_cycle + cycle_fatal desc { "getting a crate's required panic strategy" } separate_provide_extern } query panic_in_drop_strategy(_: CrateNum) -> PanicStrategy { - fatal_cycle + cycle_fatal desc { "getting a crate's configured panic-in-drop strategy" } separate_provide_extern } query is_no_builtins(_: CrateNum) -> bool { - fatal_cycle + cycle_fatal desc { "getting whether a crate has `#![no_builtins]`" } separate_provide_extern } query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion { - fatal_cycle + cycle_fatal desc { "getting a crate's symbol mangling version" } separate_provide_extern } diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 9300c942a525..25c9a0a81ab4 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -532,7 +532,7 @@ macro_rules! define_feedable { // The result type of each query must implement `Clone`, and additionally // `ty::query::values::Value`, which produces an appropriate placeholder // (error) value if the query resulted in a query cycle. -// Queries marked with `fatal_cycle` do not need the latter implementation, +// Queries marked with `cycle_fatal` do not need the latter implementation, // as they will raise an fatal error on query cycles instead. mod sealed { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 39b6fac4ebc0..c98affe0cb19 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -219,7 +219,7 @@ macro_rules! handle_cycle_error { ([]) => {{ rustc_query_system::HandleCycleError::Error }}; - ([(fatal_cycle) $($rest:tt)*]) => {{ + ([(cycle_fatal) $($rest:tt)*]) => {{ rustc_query_system::HandleCycleError::Fatal }}; ([(cycle_stash) $($rest:tt)*]) => {{ From 2e58d05a0a40533914aeaf11cf664ba41d070955 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 16 Jan 2026 15:51:13 +1100 Subject: [PATCH 2196/3801] Add test from #124901. Issue #124901 was an OOM caused by a query cycle. It was fixed by a complex change in PR #138672, but that PR did not add the test case. Let's add it now, because it's the only known reproducer of the OOM. --- tests/ui/resolve/query-cycle-issue-124901.rs | 24 +++++++++++++++++++ .../resolve/query-cycle-issue-124901.stderr | 9 +++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/ui/resolve/query-cycle-issue-124901.rs create mode 100644 tests/ui/resolve/query-cycle-issue-124901.stderr diff --git a/tests/ui/resolve/query-cycle-issue-124901.rs b/tests/ui/resolve/query-cycle-issue-124901.rs new file mode 100644 index 000000000000..6cb1e58b6258 --- /dev/null +++ b/tests/ui/resolve/query-cycle-issue-124901.rs @@ -0,0 +1,24 @@ +//~ ERROR: cycle detected when looking up span for `Default` +trait Default { + type Id; + + fn intu(&self) -> &Self::Id; +} + +impl, U: Copy> Default for U { + default type Id = T; + fn intu(&self) -> &Self::Id { + self + } +} + +fn specialization(t: T) -> U { + *t.intu() +} + +use std::num::NonZero; + +fn main() { + let assert_eq = NonZero::>>(0); + assert_eq!(specialization, None); +} diff --git a/tests/ui/resolve/query-cycle-issue-124901.stderr b/tests/ui/resolve/query-cycle-issue-124901.stderr new file mode 100644 index 000000000000..9c1d7b1de33a --- /dev/null +++ b/tests/ui/resolve/query-cycle-issue-124901.stderr @@ -0,0 +1,9 @@ +error[E0391]: cycle detected when looking up span for `Default` + | + = note: ...which immediately requires looking up span for `Default` again + = note: cycle used when perform lints prior to AST lowering + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. From 8fa2f693bb566cd99aae6c057c890b1f2e42c773 Mon Sep 17 00:00:00 2001 From: Felix Rath Date: Wed, 13 Aug 2025 13:05:07 +0200 Subject: [PATCH 2197/3801] Implement incremental caching for derive macro expansions --- Cargo.lock | 2 + compiler/rustc_ast/src/ast.rs | 3 +- compiler/rustc_ast/src/token.rs | 16 +- compiler/rustc_ast/src/tokenstream.rs | 20 +-- compiler/rustc_expand/Cargo.toml | 2 + compiler/rustc_expand/src/lib.rs | 4 + compiler/rustc_expand/src/proc_macro.rs | 168 ++++++++++++++---- .../src/persist/dirty_clean.rs | 36 ++-- compiler/rustc_interface/src/passes.rs | 1 + compiler/rustc_middle/src/arena.rs | 1 + .../rustc_middle/src/dep_graph/dep_node.rs | 6 + compiler/rustc_middle/src/dep_graph/mod.rs | 2 +- compiler/rustc_middle/src/query/erase.rs | 5 + compiler/rustc_middle/src/query/keys.rs | 16 +- compiler/rustc_middle/src/query/mod.rs | 14 +- .../rustc_middle/src/query/on_disk_cache.rs | 7 + .../rustc_query_system/src/dep_graph/graph.rs | 12 ++ compiler/rustc_session/src/options.rs | 2 + compiler/rustc_span/src/hygiene.rs | 6 + .../auxiliary/derive_nothing.rs | 15 ++ .../proc_macro_unchanged.rs | 18 ++ 21 files changed, 284 insertions(+), 72 deletions(-) create mode 100644 tests/incremental/derive_macro_expansion/auxiliary/derive_nothing.rs create mode 100644 tests/incremental/derive_macro_expansion/proc_macro_unchanged.rs diff --git a/Cargo.lock b/Cargo.lock index bf28939ac87b..d83bdf767e5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3887,11 +3887,13 @@ dependencies = [ "rustc_lexer", "rustc_lint_defs", "rustc_macros", + "rustc_middle", "rustc_parse", "rustc_proc_macro", "rustc_serialize", "rustc_session", "rustc_span", + "scoped-tls", "smallvec", "thin-vec", "tracing", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 079238b12bfd..b2b1f997ac54 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3348,7 +3348,8 @@ impl UseTree { /// Distinguishes between `Attribute`s that decorate items and Attributes that /// are contained as statements within items. These two cases need to be /// distinguished for pretty-printing. -#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy)] +#[derive(Encodable, Decodable, HashStable_Generic, Walkable)] pub enum AttrStyle { Outer, Inner, diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index accf4d181632..453e7443d324 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -40,13 +40,13 @@ impl DocFragmentKind { } } -#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)] pub enum CommentKind { Line, Block, } -#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable, HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)] pub enum InvisibleOrigin { // From the expansion of a metavariable in a declarative macro. MetaVar(MetaVarKind), @@ -123,7 +123,7 @@ impl fmt::Display for MetaVarKind { /// Describes how a sequence of token trees is delimited. /// Cannot use `proc_macro::Delimiter` directly because this /// structure should implement some additional traits. -#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)] pub enum Delimiter { /// `( ... )` Parenthesis, @@ -186,7 +186,7 @@ impl Delimiter { // type. This means that float literals like `1f32` are classified by this type // as `Int`. Only upon conversion to `ast::LitKind` will such a literal be // given the `Float` kind. -#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)] pub enum LitKind { Bool, // AST only, must never appear in a `Token` Byte, @@ -203,7 +203,7 @@ pub enum LitKind { } /// A literal token. -#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)] pub struct Lit { pub kind: LitKind, pub symbol: Symbol, @@ -349,7 +349,7 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: IdentIsRaw) -> bool { .contains(&name) } -#[derive(PartialEq, Encodable, Decodable, Debug, Copy, Clone, HashStable_Generic)] +#[derive(PartialEq, Eq, Encodable, Decodable, Hash, Debug, Copy, Clone, HashStable_Generic)] pub enum IdentIsRaw { No, Yes, @@ -376,7 +376,7 @@ impl From for IdentIsRaw { } } -#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)] pub enum TokenKind { /* Expression-operator symbols. */ /// `=` @@ -526,7 +526,7 @@ pub enum TokenKind { Eof, } -#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, Debug, HashStable_Generic)] pub struct Token { pub kind: TokenKind, pub span: Span, diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 4111182c3b7d..e346a56bcf40 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -5,6 +5,7 @@ //! which are themselves a single [`Token`] or a `Delimited` subsequence of tokens. use std::borrow::Cow; +use std::hash::Hash; use std::ops::Range; use std::sync::Arc; use std::{cmp, fmt, iter, mem}; @@ -22,7 +23,7 @@ use crate::token::{self, Delimiter, Token, TokenKind}; use crate::{AttrVec, Attribute}; /// Part of a `TokenStream`. -#[derive(Debug, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)] pub enum TokenTree { /// A single token. Should never be `OpenDelim` or `CloseDelim`, because /// delimiters are implicitly represented by `Delimited`. @@ -538,7 +539,7 @@ pub struct AttrsTarget { /// compound token. Used for conversions to `proc_macro::Spacing`. Also used to /// guide pretty-printing, which is where the `JointHidden` value (which isn't /// part of `proc_macro::Spacing`) comes in useful. -#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)] pub enum Spacing { /// The token cannot join with the following token to form a compound /// token. @@ -595,7 +596,7 @@ pub enum Spacing { } /// A `TokenStream` is an abstract sequence of tokens, organized into [`TokenTree`]s. -#[derive(Clone, Debug, Default, Encodable, Decodable)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Encodable, Decodable)] pub struct TokenStream(pub(crate) Arc>); impl TokenStream { @@ -811,14 +812,6 @@ impl TokenStream { } } -impl PartialEq for TokenStream { - fn eq(&self, other: &TokenStream) -> bool { - self.iter().eq(other.iter()) - } -} - -impl Eq for TokenStream {} - impl FromIterator for TokenStream { fn from_iter>(iter: I) -> Self { TokenStream::new(iter.into_iter().collect::>()) @@ -970,7 +963,8 @@ impl TokenCursor { } } -#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Encodable, Decodable, HashStable_Generic, Walkable)] pub struct DelimSpan { pub open: Span, pub close: Span, @@ -994,7 +988,7 @@ impl DelimSpan { } } -#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)] pub struct DelimSpacing { pub open: Spacing, pub close: Spacing, diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index f897833d85c0..a18506c42afc 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -21,6 +21,7 @@ rustc_hir = { path = "../rustc_hir" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } +rustc_middle = { path = "../rustc_middle" } rustc_parse = { path = "../rustc_parse" } # We must use the proc_macro version that we will compile proc-macros against, # not the one from our own sysroot. @@ -28,6 +29,7 @@ rustc_proc_macro = { path = "../rustc_proc_macro" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } +scoped-tls = "1.0" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 5eefa4bcdf6b..5ac7ec0cd035 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -29,4 +29,8 @@ pub mod module; #[allow(rustc::untranslatable_diagnostic)] pub mod proc_macro; +pub fn provide(providers: &mut rustc_middle::query::Providers) { + providers.derive_macro_expansion = proc_macro::provide_derive_macro_expansion; +} + rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 9bfda8764f55..5e7a272bcba4 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -1,9 +1,11 @@ use rustc_ast::tokenstream::TokenStream; use rustc_errors::ErrorGuaranteed; +use rustc_middle::ty::{self, TyCtxt}; use rustc_parse::parser::{ForceCollect, Parser}; +use rustc_session::Session; use rustc_session::config::ProcMacroExecutionStrategy; -use rustc_span::Span; use rustc_span::profiling::SpannedEventArgRecorder; +use rustc_span::{LocalExpnId, Span}; use {rustc_ast as ast, rustc_proc_macro as pm}; use crate::base::{self, *}; @@ -30,9 +32,9 @@ impl pm::bridge::server::MessagePipe for MessagePipe { } } -fn exec_strategy(ecx: &ExtCtxt<'_>) -> impl pm::bridge::server::ExecutionStrategy + 'static { +fn exec_strategy(sess: &Session) -> impl pm::bridge::server::ExecutionStrategy + 'static { pm::bridge::server::MaybeCrossThread::>::new( - ecx.sess.opts.unstable_opts.proc_macro_execution_strategy + sess.opts.unstable_opts.proc_macro_execution_strategy == ProcMacroExecutionStrategy::CrossThread, ) } @@ -54,7 +56,7 @@ impl base::BangProcMacro for BangProcMacro { }); let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; - let strategy = exec_strategy(ecx); + let strategy = exec_strategy(ecx.sess); let server = proc_macro_server::Rustc::new(ecx); self.client.run(&strategy, server, input, proc_macro_backtrace).map_err(|e| { ecx.dcx().emit_err(errors::ProcMacroPanicked { @@ -85,7 +87,7 @@ impl base::AttrProcMacro for AttrProcMacro { }); let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; - let strategy = exec_strategy(ecx); + let strategy = exec_strategy(ecx.sess); let server = proc_macro_server::Rustc::new(ecx); self.client.run(&strategy, server, annotation, annotated, proc_macro_backtrace).map_err( |e| { @@ -101,7 +103,7 @@ impl base::AttrProcMacro for AttrProcMacro { } pub struct DeriveProcMacro { - pub client: pm::bridge::client::Client, + pub client: DeriveClient, } impl MultiItemModifier for DeriveProcMacro { @@ -113,6 +115,13 @@ impl MultiItemModifier for DeriveProcMacro { item: Annotatable, _is_derive_const: bool, ) -> ExpandResult, Annotatable> { + let _timer = ecx.sess.prof.generic_activity_with_arg_recorder( + "expand_derive_proc_macro_outer", + |recorder| { + recorder.record_arg_with_span(ecx.sess.source_map(), ecx.expansion_descr(), span); + }, + ); + // We need special handling for statement items // (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`) let is_stmt = matches!(item, Annotatable::Stmt(..)); @@ -123,36 +132,31 @@ impl MultiItemModifier for DeriveProcMacro { // altogether. See #73345. crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess.psess); let input = item.to_tokens(); - let stream = { - let _timer = - ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| { - recorder.record_arg_with_span( - ecx.sess.source_map(), - ecx.expansion_descr(), - span, - ); - }); - let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; - let strategy = exec_strategy(ecx); - let server = proc_macro_server::Rustc::new(ecx); - match self.client.run(&strategy, server, input, proc_macro_backtrace) { - Ok(stream) => stream, - Err(e) => { - ecx.dcx().emit_err({ - errors::ProcMacroDerivePanicked { - span, - message: e.as_str().map(|message| { - errors::ProcMacroDerivePanickedHelp { message: message.into() } - }), - } - }); - return ExpandResult::Ready(vec![]); - } - } + + let invoc_id = ecx.current_expansion.id; + + let res = if ecx.sess.opts.incremental.is_some() + && ecx.sess.opts.unstable_opts.cache_proc_macros + { + ty::tls::with(|tcx| { + let input = &*tcx.arena.alloc(input); + let key: (LocalExpnId, &TokenStream) = (invoc_id, input); + + QueryDeriveExpandCtx::enter(ecx, self.client, move || { + tcx.derive_macro_expansion(key).cloned() + }) + }) + } else { + expand_derive_macro(invoc_id, input, ecx, self.client) + }; + + let Ok(output) = res else { + // error will already have been emitted + return ExpandResult::Ready(vec![]); }; let error_count_before = ecx.dcx().err_count(); - let mut parser = Parser::new(&ecx.sess.psess, stream, Some("proc-macro derive")); + let mut parser = Parser::new(&ecx.sess.psess, output, Some("proc-macro derive")); let mut items = vec![]; loop { @@ -180,3 +184,101 @@ impl MultiItemModifier for DeriveProcMacro { ExpandResult::Ready(items) } } + +/// Provide a query for computing the output of a derive macro. +pub(super) fn provide_derive_macro_expansion<'tcx>( + tcx: TyCtxt<'tcx>, + key: (LocalExpnId, &'tcx TokenStream), +) -> Result<&'tcx TokenStream, ()> { + let (invoc_id, input) = key; + + // Make sure that we invalidate the query when the crate defining the proc macro changes + let _ = tcx.crate_hash(invoc_id.expn_data().macro_def_id.unwrap().krate); + + QueryDeriveExpandCtx::with(|ecx, client| { + expand_derive_macro(invoc_id, input.clone(), ecx, client).map(|ts| &*tcx.arena.alloc(ts)) + }) +} + +type DeriveClient = pm::bridge::client::Client; + +fn expand_derive_macro( + invoc_id: LocalExpnId, + input: TokenStream, + ecx: &mut ExtCtxt<'_>, + client: DeriveClient, +) -> Result { + let _timer = + ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| { + let invoc_expn_data = invoc_id.expn_data(); + let span = invoc_expn_data.call_site; + let event_arg = invoc_expn_data.kind.descr(); + recorder.record_arg_with_span(ecx.sess.source_map(), event_arg.clone(), span); + }); + + let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; + let strategy = exec_strategy(ecx.sess); + let server = proc_macro_server::Rustc::new(ecx); + + match client.run(&strategy, server, input, proc_macro_backtrace) { + Ok(stream) => Ok(stream), + Err(e) => { + let invoc_expn_data = invoc_id.expn_data(); + let span = invoc_expn_data.call_site; + ecx.dcx().emit_err({ + errors::ProcMacroDerivePanicked { + span, + message: e.as_str().map(|message| errors::ProcMacroDerivePanickedHelp { + message: message.into(), + }), + } + }); + Err(()) + } + } +} + +/// Stores the context necessary to expand a derive proc macro via a query. +struct QueryDeriveExpandCtx { + /// Type-erased version of `&mut ExtCtxt` + expansion_ctx: *mut (), + client: DeriveClient, +} + +impl QueryDeriveExpandCtx { + /// Store the extension context and the client into the thread local value. + /// It will be accessible via the `with` method while `f` is active. + fn enter(ecx: &mut ExtCtxt<'_>, client: DeriveClient, f: F) -> R + where + F: FnOnce() -> R, + { + // We need erasure to get rid of the lifetime + let ctx = Self { expansion_ctx: ecx as *mut _ as *mut (), client }; + DERIVE_EXPAND_CTX.set(&ctx, || f()) + } + + /// Accesses the thread local value of the derive expansion context. + /// Must be called while the `enter` function is active. + fn with(f: F) -> R + where + F: for<'a, 'b> FnOnce(&'b mut ExtCtxt<'a>, DeriveClient) -> R, + { + DERIVE_EXPAND_CTX.with(|ctx| { + let ectx = { + let casted = ctx.expansion_ctx.cast::>(); + // SAFETY: We can only get the value from `with` while the `enter` function + // is active (on the callstack), and that function's signature ensures that the + // lifetime is valid. + // If `with` is called at some other time, it will panic due to usage of + // `scoped_tls::with`. + unsafe { casted.as_mut().unwrap() } + }; + + f(ectx, ctx.client) + }) + } +} + +// When we invoke a query to expand a derive proc macro, we need to provide it with the expansion +// context and derive Client. We do that using a thread-local. +scoped_tls::scoped_thread_local!(static DERIVE_EXPAND_CTX: QueryDeriveExpandCtx); diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 64166255fa48..71fb18895246 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -26,7 +26,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::{ Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, intravisit, }; -use rustc_middle::dep_graph::{DepNode, DepNodeExt, label_strs}; +use rustc_middle::dep_graph::{DepNode, DepNodeExt, dep_kind_from_label, label_strs}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::{Span, Symbol, sym}; @@ -357,17 +357,6 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { } } - fn assert_loaded_from_disk(&self, item_span: Span, dep_node: DepNode) { - debug!("assert_loaded_from_disk({:?})", dep_node); - - if !self.tcx.dep_graph.debug_was_loaded_from_disk(dep_node) { - let dep_node_str = self.dep_node_str(&dep_node); - self.tcx - .dcx() - .emit_err(errors::NotLoaded { span: item_span, dep_node_str: &dep_node_str }); - } - } - fn check_item(&mut self, item_id: LocalDefId) { let item_span = self.tcx.def_span(item_id.to_def_id()); let def_path_hash = self.tcx.def_path_hash(item_id.to_def_id()); @@ -385,8 +374,27 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { self.assert_dirty(item_span, dep_node); } for label in assertion.loaded_from_disk.items().into_sorted_stable_ord() { - let dep_node = DepNode::from_label_string(self.tcx, label, def_path_hash).unwrap(); - self.assert_loaded_from_disk(item_span, dep_node); + match DepNode::from_label_string(self.tcx, label, def_path_hash) { + Ok(dep_node) => { + if !self.tcx.dep_graph.debug_was_loaded_from_disk(dep_node) { + let dep_node_str = self.dep_node_str(&dep_node); + self.tcx.dcx().emit_err(errors::NotLoaded { + span: item_span, + dep_node_str: &dep_node_str, + }); + } + } + // Opaque/unit hash, we only know the dep kind + Err(()) => { + let dep_kind = dep_kind_from_label(label); + if !self.tcx.dep_graph.debug_dep_kind_was_loaded_from_disk(dep_kind) { + self.tcx.dcx().emit_err(errors::NotLoaded { + span: item_span, + dep_node_str: &label, + }); + } + } + } } } } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 35ab202d4c27..12a6a616d64f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -889,6 +889,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { providers.queries.env_var_os = env_var_os; limits::provide(&mut providers.queries); proc_macro_decls::provide(&mut providers.queries); + rustc_expand::provide(&mut providers.queries); rustc_const_eval::provide(providers); rustc_middle::hir::provide(&mut providers.queries); rustc_borrowck::provide(&mut providers.queries); diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 4fa39eb83e9e..0bdc1bfd45ee 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -119,6 +119,7 @@ macro_rules! arena_types { [decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph, [] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls, [] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>, + [decode] token_stream: rustc_ast::tokenstream::TokenStream, ]); ) } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 0c757a390ca0..3ee1db67911f 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -176,6 +176,12 @@ impl DepNodeExt for DepNode { } } +/// Maps a query label to its DepKind. Panics if a query with the given label does not exist. +pub fn dep_kind_from_label(label: &str) -> DepKind { + dep_kind_from_label_string(label) + .unwrap_or_else(|_| panic!("Query label {label} does not exist")) +} + impl<'tcx> DepNodeParams> for () { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 781e3e442e64..b24ea4acc6b7 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -8,7 +8,7 @@ use crate::ty::{self, TyCtxt}; #[macro_use] mod dep_node; -pub use dep_node::{DepKind, DepNode, DepNodeExt, dep_kinds, label_strs}; +pub use dep_node::{DepKind, DepNode, DepNodeExt, dep_kind_from_label, dep_kinds, label_strs}; pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item, make_metadata}; pub use rustc_query_system::dep_graph::debug::{DepNodeFilter, EdgeFilter}; pub use rustc_query_system::dep_graph::{ diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 711a597d4603..940cc30c17e6 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -2,6 +2,7 @@ use std::ffi::OsStr; use std::intrinsics::transmute_unchecked; use std::mem::MaybeUninit; +use rustc_ast::tokenstream::TokenStream; use rustc_span::ErrorGuaranteed; use rustc_span::source_map::Spanned; @@ -188,6 +189,10 @@ impl EraseType >()]; } +impl EraseType for Result<&'_ TokenStream, ()> { + type Result = [u8; size_of::>()]; +} + impl EraseType for Option<&'_ T> { type Result = [u8; size_of::>()]; } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 4d914c42cfc6..dd9ba4325545 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -2,11 +2,12 @@ use std::ffi::OsStr; +use rustc_ast::tokenstream::TokenStream; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId}; use rustc_hir::hir_id::{HirId, OwnerId}; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::query::{DefIdCache, DefaultCache, SingleCache, VecCache}; -use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; +use rustc_span::{DUMMY_SP, Ident, LocalExpnId, Span, Symbol}; use crate::infer::canonical::CanonicalQueryInput; use crate::mir::mono::CollectionMode; @@ -616,6 +617,19 @@ impl Key for (LocalDefId, HirId) { } } +impl<'tcx> Key for (LocalExpnId, &'tcx TokenStream) { + type Cache = DefaultCache; + + fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { + self.0.expn_data().call_site + } + + #[inline(always)] + fn key_as_def_id(&self) -> Option { + None + } +} + impl<'tcx> Key for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) { type Cache = DefaultCache; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 5f40c36423b3..9335afe760ae 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -70,6 +70,7 @@ use std::sync::Arc; use rustc_abi::Align; use rustc_arena::TypedArena; use rustc_ast::expand::allocator::AllocatorKind; +use rustc_ast::tokenstream::TokenStream; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::steal::Steal; @@ -96,7 +97,7 @@ use rustc_session::cstore::{ use rustc_session::lint::LintExpectationId; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::source_map::Spanned; -use rustc_span::{DUMMY_SP, Span, Symbol}; +use rustc_span::{DUMMY_SP, LocalExpnId, Span, Symbol}; use rustc_target::spec::PanicStrategy; use {rustc_abi as abi, rustc_ast as ast, rustc_hir as hir}; @@ -163,6 +164,17 @@ pub mod plumbing; // Queries marked with `fatal_cycle` do not need the latter implementation, // as they will raise an fatal error on query cycles instead. rustc_queries! { + /// Caches the expansion of a derive proc macro, e.g. `#[derive(Serialize)]`. + /// The key is: + /// - A unique key corresponding to the invocation of a macro. + /// - Token stream which serves as an input to the macro. + /// + /// The output is the token stream generated by the proc macro. + query derive_macro_expansion(key: (LocalExpnId, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> { + desc { "expanding a derive (proc) macro" } + cache_on_disk_if { true } + } + /// This exists purely for testing the interactions between delayed bugs and incremental. query trigger_delayed_bug(key: DefId) { desc { "triggering a delayed bug for testing incremental" } diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index 29cceb708850..5ef0c2500e7a 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -785,6 +785,13 @@ impl<'a, 'tcx> Decodable> } } +impl<'a, 'tcx> Decodable> for &'tcx rustc_ast::tokenstream::TokenStream { + #[inline] + fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { + RefDecodable::decode(d) + } +} + macro_rules! impl_ref_decoder { (<$tcx:tt> $($ty:ty,)*) => { $(impl<'a, $tcx> Decodable> for &$tcx [$ty] { diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 8634274c3a75..0b50d376b552 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -795,6 +795,18 @@ impl DepGraph { self.data.as_ref().unwrap().debug_loaded_from_disk.lock().contains(&dep_node) } + pub fn debug_dep_kind_was_loaded_from_disk(&self, dep_kind: DepKind) -> bool { + // We only check if we have a dep node corresponding to the given dep kind. + #[allow(rustc::potential_query_instability)] + self.data + .as_ref() + .unwrap() + .debug_loaded_from_disk + .lock() + .iter() + .any(|node| node.kind == dep_kind) + } + #[cfg(debug_assertions)] #[inline(always)] pub(crate) fn register_dep_node_debug_str(&self, dep_node: DepNode, debug_str_gen: F) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 99ab13403812..96bdcf8beffb 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2278,6 +2278,8 @@ options! { "set options for branch target identification and pointer authentication on AArch64"), build_sdylib_interface: bool = (false, parse_bool, [UNTRACKED], "whether the stable interface is being built"), + cache_proc_macros: bool = (false, parse_bool, [TRACKED], + "cache the results of derive proc macro invocations (potentially unsound!) (default: no"), cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED], "instrument control-flow architecture protection"), check_cfg_all_expected: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 51da538de94d..d94d82835d65 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1571,3 +1571,9 @@ impl HashStable for ExpnId { hash.hash_stable(ctx, hasher); } } + +impl HashStable for LocalExpnId { + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + self.to_expn_id().hash_stable(hcx, hasher); + } +} diff --git a/tests/incremental/derive_macro_expansion/auxiliary/derive_nothing.rs b/tests/incremental/derive_macro_expansion/auxiliary/derive_nothing.rs new file mode 100644 index 000000000000..24957b052856 --- /dev/null +++ b/tests/incremental/derive_macro_expansion/auxiliary/derive_nothing.rs @@ -0,0 +1,15 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(Nothing)] +pub fn derive(_input: TokenStream) -> TokenStream { + return r#" + pub mod nothing_mod { + pub fn nothing() { + eprintln!("nothing"); + } + } + "# + .parse() + .unwrap(); +} diff --git a/tests/incremental/derive_macro_expansion/proc_macro_unchanged.rs b/tests/incremental/derive_macro_expansion/proc_macro_unchanged.rs new file mode 100644 index 000000000000..64364e31bc45 --- /dev/null +++ b/tests/incremental/derive_macro_expansion/proc_macro_unchanged.rs @@ -0,0 +1,18 @@ +// This test tests that derive proc macro execution is cached. + +//@ proc-macro:derive_nothing.rs +//@ revisions:rpass1 rpass2 +//@ compile-flags: -Zquery-dep-graph -Zcache-proc-macros +//@ ignore-backends: gcc + +#![feature(rustc_attrs)] + +#[macro_use] +extern crate derive_nothing; + +#[cfg(any(rpass1, rpass2))] +#[rustc_clean(cfg = "rpass2", loaded_from_disk = "derive_macro_expansion")] +#[derive(Nothing)] +pub struct Foo; + +fn main() {} From 48bcaf7ed1795ceb8b1e4ad4822e7e85e2cb5de5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 16 Jan 2026 18:34:46 +1100 Subject: [PATCH 2198/3801] Revert the `QueryStackFrameExtra`/`QueryStackDeferred` split. PR #138672 introduced a complex and invasive split of `QueryStackFrame` to avoid a query cycle. This commit reverts that change because there is a much simpler change that fixes the problem, which will be in the next commit. --- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/query/plumbing.rs | 2 +- compiler/rustc_middle/src/values.rs | 4 +- compiler/rustc_query_impl/src/lib.rs | 11 +- compiler/rustc_query_impl/src/plumbing.rs | 86 ++++-------- .../rustc_query_system/src/query/config.rs | 5 +- compiler/rustc_query_system/src/query/job.rs | 131 ++++++++---------- compiler/rustc_query_system/src/query/mod.rs | 129 ++++------------- .../rustc_query_system/src/query/plumbing.rs | 61 ++++---- 9 files changed, 145 insertions(+), 286 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index fc1bf78c82f3..285097832ba9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -87,7 +87,7 @@ use rustc_index::IndexVec; use rustc_lint_defs::LintId; use rustc_macros::rustc_queries; use rustc_query_system::ich::StableHashingContext; -use rustc_query_system::query::{QueryMode, QueryStackDeferred, QueryState}; +use rustc_query_system::query::{QueryMode, QueryState}; use rustc_session::Limits; use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; use rustc_session::cstore::{ diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 25c9a0a81ab4..df333e68add1 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -431,7 +431,7 @@ macro_rules! define_callbacks { #[derive(Default)] pub struct QueryStates<'tcx> { $( - pub $name: QueryState<$($K)*, QueryStackDeferred<'tcx>>, + pub $name: QueryState<$($K)*>, )* } diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index bc73d36216ef..8d614a535498 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -88,7 +88,7 @@ impl<'tcx> Value> for Representability { if info.query.dep_kind == dep_kinds::representability && let Some(field_id) = info.query.def_id && let Some(field_id) = field_id.as_local() - && let Some(DefKind::Field) = info.query.info.def_kind + && let Some(DefKind::Field) = info.query.def_kind { let parent_id = tcx.parent(field_id.to_def_id()); let item_id = match tcx.def_kind(parent_id) { @@ -224,7 +224,7 @@ impl<'tcx, T> Value> for Result> continue; }; let frame_span = - frame.query.info.default_span(cycle[(i + 1) % cycle.len()].span); + frame.query.default_span(cycle[(i + 1) % cycle.len()].span); if frame_span.is_dummy() { continue; } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 6904af771f0c..f763b707aa23 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -21,8 +21,8 @@ use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - CycleError, HashResult, QueryCache, QueryConfig, QueryMap, QueryMode, QueryStackDeferred, - QueryState, get_query_incr, get_query_non_incr, + CycleError, HashResult, QueryCache, QueryConfig, QueryMap, QueryMode, QueryState, + get_query_incr, get_query_non_incr, }; use rustc_query_system::{HandleCycleError, Value}; use rustc_span::{ErrorGuaranteed, Span}; @@ -79,10 +79,7 @@ where } #[inline(always)] - fn query_state<'a>( - self, - qcx: QueryCtxt<'tcx>, - ) -> &'a QueryState> + fn query_state<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a QueryState where QueryCtxt<'tcx>: 'a, { @@ -91,7 +88,7 @@ where unsafe { &*(&qcx.tcx.query_system.states as *const QueryStates<'tcx>) .byte_add(self.dynamic.query_state) - .cast::>>() + .cast::>() } } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index c98affe0cb19..ba1a358d2415 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -6,7 +6,6 @@ use std::num::NonZero; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::unord::UnordMap; use rustc_hashes::Hash64; use rustc_hir::limit::Limit; @@ -27,8 +26,8 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffect, - QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, force_query, + QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffect, QueryStackFrame, + force_query, }; use rustc_query_system::{QueryOverflow, QueryOverflowNote}; use rustc_serialize::{Decodable, Encodable}; @@ -67,9 +66,7 @@ impl<'tcx> HasDepContext for QueryCtxt<'tcx> { } } -impl<'tcx> QueryContext for QueryCtxt<'tcx> { - type QueryInfo = QueryStackDeferred<'tcx>; - +impl QueryContext for QueryCtxt<'_> { #[inline] fn jobserver_proxy(&self) -> &Proxy { &*self.jobserver_proxy @@ -98,10 +95,7 @@ impl<'tcx> QueryContext for QueryCtxt<'tcx> { /// Prefer passing `false` to `require_complete` to avoid potential deadlocks, /// especially when called from within a deadlock handler, unless a /// complete map is needed and no deadlock is possible at this call site. - fn collect_active_jobs( - self, - require_complete: bool, - ) -> Result>, QueryMap>> { + fn collect_active_jobs(self, require_complete: bool) -> Result { let mut jobs = QueryMap::default(); let mut complete = true; @@ -114,13 +108,6 @@ impl<'tcx> QueryContext for QueryCtxt<'tcx> { if complete { Ok(jobs) } else { Err(jobs) } } - fn lift_query_info( - self, - info: &QueryStackDeferred<'tcx>, - ) -> rustc_query_system::query::QueryStackFrameExtra { - info.extract() - } - // Interactions with on_disk_cache fn load_side_effect( self, @@ -181,10 +168,7 @@ impl<'tcx> QueryContext for QueryCtxt<'tcx> { self.sess.dcx().emit_fatal(QueryOverflow { span: info.job.span, - note: QueryOverflowNote { - desc: self.lift_query_info(&info.query.info).description, - depth, - }, + note: QueryOverflowNote { desc: info.query.description, depth }, suggested_limit, crate_name: self.crate_name(LOCAL_CRATE), }); @@ -321,17 +305,16 @@ macro_rules! should_ever_cache_on_disk { }; } -fn create_query_frame_extra<'tcx, K: Key + Copy + 'tcx>( - (tcx, key, kind, name, do_describe): ( - TyCtxt<'tcx>, - K, - DepKind, - &'static str, - fn(TyCtxt<'tcx>, K) -> String, - ), -) -> QueryStackFrameExtra { - let def_id = key.key_as_def_id(); - +pub(crate) fn create_query_frame< + 'tcx, + K: Copy + Key + for<'a> HashStable>, +>( + tcx: TyCtxt<'tcx>, + do_describe: fn(TyCtxt<'tcx>, K) -> String, + key: K, + kind: DepKind, + name: &'static str, +) -> QueryStackFrame { // If reduced queries are requested, we may be printing a query stack due // to a panic. Avoid using `default_span` and `def_kind` in that case. let reduce_queries = with_reduced_queries(); @@ -343,6 +326,7 @@ fn create_query_frame_extra<'tcx, K: Key + Copy + 'tcx>( } else { description }; + let span = if kind == dep_graph::dep_kinds::def_span || reduce_queries { // The `def_span` query is used to calculate `default_span`, // so exit to avoid infinite recursion. @@ -351,41 +335,25 @@ fn create_query_frame_extra<'tcx, K: Key + Copy + 'tcx>( Some(key.default_span(tcx)) }; + let def_id = key.key_as_def_id(); + let def_kind = if kind == dep_graph::dep_kinds::def_kind || reduce_queries { // Try to avoid infinite recursion. None } else { def_id.and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id)) }; - QueryStackFrameExtra::new(description, span, def_kind) -} -pub(crate) fn create_query_frame< - 'tcx, - K: Copy + DynSend + DynSync + Key + for<'a> HashStable> + 'tcx, ->( - tcx: TyCtxt<'tcx>, - do_describe: fn(TyCtxt<'tcx>, K) -> String, - key: K, - kind: DepKind, - name: &'static str, -) -> QueryStackFrame> { - let def_id = key.key_as_def_id(); - - let hash = || { - tcx.with_stable_hashing_context(|mut hcx| { - let mut hasher = StableHasher::new(); - kind.as_usize().hash_stable(&mut hcx, &mut hasher); - key.hash_stable(&mut hcx, &mut hasher); - hasher.finish::() - }) - }; let def_id_for_ty_in_cycle = key.def_id_for_ty_in_cycle(); - let info = - QueryStackDeferred::new((tcx, key, kind, name, do_describe), create_query_frame_extra); + let hash = tcx.with_stable_hashing_context(|mut hcx| { + let mut hasher = StableHasher::new(); + kind.as_usize().hash_stable(&mut hcx, &mut hasher); + key.hash_stable(&mut hcx, &mut hasher); + hasher.finish::() + }); - QueryStackFrame::new(info, kind, hash, def_id, def_id_for_ty_in_cycle) + QueryStackFrame::new(description, span, def_id, def_kind, kind, def_id_for_ty_in_cycle, hash) } pub(crate) fn encode_query_results<'a, 'tcx, Q>( @@ -737,7 +705,7 @@ macro_rules! define_queries { pub(crate) fn collect_active_jobs<'tcx>( tcx: TyCtxt<'tcx>, - qmap: &mut QueryMap>, + qmap: &mut QueryMap, require_complete: bool, ) -> Option<()> { let make_query = |tcx, key| { @@ -821,7 +789,7 @@ macro_rules! define_queries { // These arrays are used for iteration and can't be indexed by `DepKind`. const COLLECT_ACTIVE_JOBS: &[ - for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap>, bool) -> Option<()> + for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap, bool) -> Option<()> ] = &[$(query_impl::$name::collect_active_jobs),*]; diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index e508eadb73b0..371b896400a5 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -6,7 +6,6 @@ use std::hash::Hash; use rustc_data_structures::fingerprint::Fingerprint; use rustc_span::ErrorGuaranteed; -use super::QueryStackFrameExtra; use crate::dep_graph::{DepKind, DepNode, DepNodeParams, SerializedDepNodeIndex}; use crate::error::HandleCycleError; use crate::ich::StableHashingContext; @@ -28,7 +27,7 @@ pub trait QueryConfig: Copy { fn format_value(self) -> fn(&Self::Value) -> String; // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_state<'a>(self, tcx: Qcx) -> &'a QueryState + fn query_state<'a>(self, tcx: Qcx) -> &'a QueryState where Qcx: 'a; @@ -58,7 +57,7 @@ pub trait QueryConfig: Copy { fn value_from_cycle_error( self, tcx: Qcx::DepContext, - cycle_error: &CycleError, + cycle_error: &CycleError, guar: ErrorGuaranteed, ) -> Self::Value; diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 7d9b594d501f..4a9b6a0d557c 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -1,4 +1,3 @@ -use std::fmt::Debug; use std::hash::Hash; use std::io::Write; use std::iter; @@ -12,7 +11,6 @@ use rustc_hir::def::DefKind; use rustc_session::Session; use rustc_span::{DUMMY_SP, Span}; -use super::QueryStackFrameExtra; use crate::dep_graph::DepContext; use crate::error::CycleStack; use crate::query::plumbing::CycleError; @@ -20,54 +18,45 @@ use crate::query::{QueryContext, QueryStackFrame}; /// Represents a span and a query key. #[derive(Clone, Debug)] -pub struct QueryInfo { +pub struct QueryInfo { /// The span corresponding to the reason for which this query was required. pub span: Span, - pub query: QueryStackFrame, + pub query: QueryStackFrame, } -impl QueryInfo { - pub(crate) fn lift>( - &self, - qcx: Qcx, - ) -> QueryInfo { - QueryInfo { span: self.span, query: self.query.lift(qcx) } - } -} - -pub type QueryMap = FxHashMap>; +pub type QueryMap = FxHashMap; /// A value uniquely identifying an active query job. #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct QueryJobId(pub NonZero); impl QueryJobId { - fn query(self, map: &QueryMap) -> QueryStackFrame { + fn query(self, map: &QueryMap) -> QueryStackFrame { map.get(&self).unwrap().query.clone() } - fn span(self, map: &QueryMap) -> Span { + fn span(self, map: &QueryMap) -> Span { map.get(&self).unwrap().job.span } - fn parent(self, map: &QueryMap) -> Option { + fn parent(self, map: &QueryMap) -> Option { map.get(&self).unwrap().job.parent } - fn latch(self, map: &QueryMap) -> Option<&QueryLatch> { + fn latch(self, map: &QueryMap) -> Option<&QueryLatch> { map.get(&self).unwrap().job.latch.as_ref() } } #[derive(Clone, Debug)] -pub struct QueryJobInfo { - pub query: QueryStackFrame, - pub job: QueryJob, +pub struct QueryJobInfo { + pub query: QueryStackFrame, + pub job: QueryJob, } /// Represents an active query job. #[derive(Debug)] -pub struct QueryJob { +pub struct QueryJob { pub id: QueryJobId, /// The span corresponding to the reason for which this query was required. @@ -77,23 +66,23 @@ pub struct QueryJob { pub parent: Option, /// The latch that is used to wait on this job. - latch: Option>, + latch: Option, } -impl Clone for QueryJob { +impl Clone for QueryJob { fn clone(&self) -> Self { Self { id: self.id, span: self.span, parent: self.parent, latch: self.latch.clone() } } } -impl QueryJob { +impl QueryJob { /// Creates a new query job. #[inline] pub fn new(id: QueryJobId, span: Span, parent: Option) -> Self { QueryJob { id, span, parent, latch: None } } - pub(super) fn latch(&mut self) -> QueryLatch { + pub(super) fn latch(&mut self) -> QueryLatch { if self.latch.is_none() { self.latch = Some(QueryLatch::new()); } @@ -113,12 +102,12 @@ impl QueryJob { } impl QueryJobId { - pub(super) fn find_cycle_in_stack( + pub(super) fn find_cycle_in_stack( &self, - query_map: QueryMap, + query_map: QueryMap, current_job: &Option, span: Span, - ) -> CycleError { + ) -> CycleError { // Find the waitee amongst `current_job` parents let mut cycle = Vec::new(); let mut current_job = Option::clone(current_job); @@ -152,7 +141,7 @@ impl QueryJobId { #[cold] #[inline(never)] - pub fn find_dep_kind_root(&self, query_map: QueryMap) -> (QueryJobInfo, usize) { + pub fn find_dep_kind_root(&self, query_map: QueryMap) -> (QueryJobInfo, usize) { let mut depth = 1; let info = query_map.get(&self).unwrap(); let dep_kind = info.query.dep_kind; @@ -172,31 +161,31 @@ impl QueryJobId { } #[derive(Debug)] -struct QueryWaiter { +struct QueryWaiter { query: Option, condvar: Condvar, span: Span, - cycle: Mutex>>, + cycle: Mutex>, } #[derive(Debug)] -struct QueryLatchInfo { +struct QueryLatchInfo { complete: bool, - waiters: Vec>>, + waiters: Vec>, } #[derive(Debug)] -pub(super) struct QueryLatch { - info: Arc>>, +pub(super) struct QueryLatch { + info: Arc>, } -impl Clone for QueryLatch { +impl Clone for QueryLatch { fn clone(&self) -> Self { Self { info: Arc::clone(&self.info) } } } -impl QueryLatch { +impl QueryLatch { fn new() -> Self { QueryLatch { info: Arc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })), @@ -209,7 +198,7 @@ impl QueryLatch { qcx: impl QueryContext, query: Option, span: Span, - ) -> Result<(), CycleError> { + ) -> Result<(), CycleError> { let waiter = Arc::new(QueryWaiter { query, span, cycle: Mutex::new(None), condvar: Condvar::new() }); self.wait_on_inner(qcx, &waiter); @@ -224,7 +213,7 @@ impl QueryLatch { } /// Awaits the caller on this latch by blocking the current thread. - fn wait_on_inner(&self, qcx: impl QueryContext, waiter: &Arc>) { + fn wait_on_inner(&self, qcx: impl QueryContext, waiter: &Arc) { let mut info = self.info.lock(); if !info.complete { // We push the waiter on to the `waiters` list. It can be accessed inside @@ -260,7 +249,7 @@ impl QueryLatch { /// Removes a single waiter from the list of waiters. /// This is used to break query cycles. - fn extract_waiter(&self, waiter: usize) -> Arc> { + fn extract_waiter(&self, waiter: usize) -> Arc { let mut info = self.info.lock(); debug_assert!(!info.complete); // Remove the waiter from the list of waiters @@ -280,11 +269,7 @@ type Waiter = (QueryJobId, usize); /// For visits of resumable waiters it returns Some(Some(Waiter)) which has the /// required information to resume the waiter. /// If all `visit` calls returns None, this function also returns None. -fn visit_waiters( - query_map: &QueryMap, - query: QueryJobId, - mut visit: F, -) -> Option> +fn visit_waiters(query_map: &QueryMap, query: QueryJobId, mut visit: F) -> Option> where F: FnMut(Span, QueryJobId) -> Option>, { @@ -314,8 +299,8 @@ where /// `span` is the reason for the `query` to execute. This is initially DUMMY_SP. /// If a cycle is detected, this initial value is replaced with the span causing /// the cycle. -fn cycle_check( - query_map: &QueryMap, +fn cycle_check( + query_map: &QueryMap, query: QueryJobId, span: Span, stack: &mut Vec<(Span, QueryJobId)>, @@ -354,8 +339,8 @@ fn cycle_check( /// Finds out if there's a path to the compiler root (aka. code which isn't in a query) /// from `query` without going through any of the queries in `visited`. /// This is achieved with a depth first search. -fn connected_to_root( - query_map: &QueryMap, +fn connected_to_root( + query_map: &QueryMap, query: QueryJobId, visited: &mut FxHashSet, ) -> bool { @@ -376,7 +361,7 @@ fn connected_to_root( } // Deterministically pick an query from a list -fn pick_query<'a, I: Clone, T, F>(query_map: &QueryMap, queries: &'a [T], f: F) -> &'a T +fn pick_query<'a, T, F>(query_map: &QueryMap, queries: &'a [T], f: F) -> &'a T where F: Fn(&T) -> (Span, QueryJobId), { @@ -401,10 +386,10 @@ where /// the function return true. /// If a cycle was not found, the starting query is removed from `jobs` and /// the function returns false. -fn remove_cycle( - query_map: &QueryMap, +fn remove_cycle( + query_map: &QueryMap, jobs: &mut Vec, - wakelist: &mut Vec>>, + wakelist: &mut Vec>, ) -> bool { let mut visited = FxHashSet::default(); let mut stack = Vec::new(); @@ -505,10 +490,7 @@ fn remove_cycle( /// uses a query latch and then resuming that waiter. /// There may be multiple cycles involved in a deadlock, so this searches /// all active queries for cycles before finally resuming all the waiters at once. -pub fn break_query_cycles( - query_map: QueryMap, - registry: &rustc_thread_pool::Registry, -) { +pub fn break_query_cycles(query_map: QueryMap, registry: &rustc_thread_pool::Registry) { let mut wakelist = Vec::new(); // It is OK per the comments: // - https://github.com/rust-lang/rust/pull/131200#issuecomment-2798854932 @@ -559,7 +541,7 @@ pub fn report_cycle<'a>( ) -> Diag<'a> { assert!(!stack.is_empty()); - let span = stack[0].query.info.default_span(stack[1 % stack.len()].span); + let span = stack[0].query.default_span(stack[1 % stack.len()].span); let mut cycle_stack = Vec::new(); @@ -568,31 +550,31 @@ pub fn report_cycle<'a>( for i in 1..stack.len() { let query = &stack[i].query; - let span = query.info.default_span(stack[(i + 1) % stack.len()].span); - cycle_stack.push(CycleStack { span, desc: query.info.description.to_owned() }); + let span = query.default_span(stack[(i + 1) % stack.len()].span); + cycle_stack.push(CycleStack { span, desc: query.description.to_owned() }); } let mut cycle_usage = None; if let Some((span, ref query)) = *usage { cycle_usage = Some(crate::error::CycleUsage { - span: query.info.default_span(span), - usage: query.info.description.to_string(), + span: query.default_span(span), + usage: query.description.to_string(), }); } - let alias = - if stack.iter().all(|entry| matches!(entry.query.info.def_kind, Some(DefKind::TyAlias))) { - Some(crate::error::Alias::Ty) - } else if stack.iter().all(|entry| entry.query.info.def_kind == Some(DefKind::TraitAlias)) { - Some(crate::error::Alias::Trait) - } else { - None - }; + let alias = if stack.iter().all(|entry| matches!(entry.query.def_kind, Some(DefKind::TyAlias))) + { + Some(crate::error::Alias::Ty) + } else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) { + Some(crate::error::Alias::Trait) + } else { + None + }; let cycle_diag = crate::error::Cycle { span, cycle_stack, - stack_bottom: stack[0].query.info.description.to_owned(), + stack_bottom: stack[0].query.description.to_owned(), alias, cycle_usage, stack_count, @@ -628,7 +610,6 @@ pub fn print_query_stack( let Some(query_info) = query_map.get(&query) else { break; }; - let query_extra = qcx.lift_query_info(&query_info.query.info); if Some(count_printed) < limit_frames || limit_frames.is_none() { // Only print to stderr as many stack frames as `num_frames` when present. // FIXME: needs translation @@ -636,7 +617,7 @@ pub fn print_query_stack( #[allow(rustc::untranslatable_diagnostic)] dcx.struct_failure_note(format!( "#{} [{:?}] {}", - count_printed, query_info.query.dep_kind, query_extra.description + count_printed, query_info.query.dep_kind, query_info.query.description )) .with_span(query_info.job.span) .emit(); @@ -649,7 +630,7 @@ pub fn print_query_stack( "#{} [{}] {}", count_total, qcx.dep_context().dep_kind_info(query_info.query.dep_kind).name, - query_extra.description + query_info.query.description ); } diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index ce3456d532e6..b524756d81b6 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -1,23 +1,4 @@ -mod plumbing; -use std::fmt::Debug; -use std::marker::PhantomData; -use std::mem::transmute; -use std::sync::Arc; - -pub use self::plumbing::*; - -mod job; -pub use self::job::{ - QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap, break_query_cycles, print_query_stack, - report_cycle, -}; - -mod caches; -pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; - -mod config; use rustc_data_structures::jobserver::Proxy; -use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_errors::DiagInner; use rustc_hashes::Hash64; use rustc_hir::def::DefKind; @@ -25,66 +6,49 @@ use rustc_macros::{Decodable, Encodable}; use rustc_span::Span; use rustc_span::def_id::DefId; +pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; pub use self::config::{HashResult, QueryConfig}; +pub use self::job::{ + QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap, break_query_cycles, print_query_stack, + report_cycle, +}; +pub use self::plumbing::*; use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; +mod caches; +mod config; +mod job; +mod plumbing; + /// Description of a frame in the query stack. /// /// This is mostly used in case of cycles for error reporting. #[derive(Clone, Debug)] -pub struct QueryStackFrame { - /// This field initially stores a `QueryStackDeferred` during collection, - /// but can later be changed to `QueryStackFrameExtra` containing concrete information - /// by calling `lift`. This is done so that collecting query does not need to invoke - /// queries, instead `lift` will call queries in a more appropriate location. - pub info: I, - +pub struct QueryStackFrame { + pub description: String, + span: Option, + pub def_id: Option, + pub def_kind: Option, + /// A def-id that is extracted from a `Ty` in a query key + pub def_id_for_ty_in_cycle: Option, pub dep_kind: DepKind, /// This hash is used to deterministically pick /// a query to remove cycles in the parallel compiler. hash: Hash64, - pub def_id: Option, - /// A def-id that is extracted from a `Ty` in a query key - pub def_id_for_ty_in_cycle: Option, } -impl QueryStackFrame { +impl QueryStackFrame { #[inline] pub fn new( - info: I, - dep_kind: DepKind, - hash: impl FnOnce() -> Hash64, + description: String, + span: Option, def_id: Option, + def_kind: Option, + dep_kind: DepKind, def_id_for_ty_in_cycle: Option, + hash: Hash64, ) -> Self { - Self { info, def_id, dep_kind, hash: hash(), def_id_for_ty_in_cycle } - } - - fn lift>( - &self, - qcx: Qcx, - ) -> QueryStackFrame { - QueryStackFrame { - info: qcx.lift_query_info(&self.info), - dep_kind: self.dep_kind, - hash: self.hash, - def_id: self.def_id, - def_id_for_ty_in_cycle: self.def_id_for_ty_in_cycle, - } - } -} - -#[derive(Clone, Debug)] -pub struct QueryStackFrameExtra { - pub description: String, - span: Option, - pub def_kind: Option, -} - -impl QueryStackFrameExtra { - #[inline] - pub fn new(description: String, span: Option, def_kind: Option) -> Self { - Self { description, span, def_kind } + Self { description, span, def_id, def_kind, def_id_for_ty_in_cycle, dep_kind, hash } } // FIXME(eddyb) Get more valid `Span`s on queries. @@ -97,40 +61,6 @@ impl QueryStackFrameExtra { } } -/// Track a 'side effect' for a particular query. -/// This is used to hold a closure which can create `QueryStackFrameExtra`. -#[derive(Clone)] -pub struct QueryStackDeferred<'tcx> { - _dummy: PhantomData<&'tcx ()>, - - // `extract` may contain references to 'tcx, but we can't tell drop checking that it won't - // access it in the destructor. - extract: Arc QueryStackFrameExtra + DynSync + DynSend>, -} - -impl<'tcx> QueryStackDeferred<'tcx> { - pub fn new( - context: C, - extract: fn(C) -> QueryStackFrameExtra, - ) -> Self { - let extract: Arc QueryStackFrameExtra + DynSync + DynSend + 'tcx> = - Arc::new(move || extract(context)); - // SAFETY: The `extract` closure does not access 'tcx in its destructor as the only - // captured variable is `context` which is Copy and cannot have a destructor. - Self { _dummy: PhantomData, extract: unsafe { transmute(extract) } } - } - - pub fn extract(&self) -> QueryStackFrameExtra { - (self.extract)() - } -} - -impl<'tcx> Debug for QueryStackDeferred<'tcx> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("QueryStackDeferred") - } -} - /// Tracks 'side effects' for a particular query. /// This struct is saved to disk along with the query result, /// and loaded from disk if we mark the query as green. @@ -150,8 +80,6 @@ pub enum QuerySideEffect { } pub trait QueryContext: HasDepContext { - type QueryInfo: Clone; - /// Gets a jobserver reference which is used to release then acquire /// a token while waiting on a query. fn jobserver_proxy(&self) -> &Proxy; @@ -161,12 +89,7 @@ pub trait QueryContext: HasDepContext { /// Get the query information from the TLS context. fn current_query_job(self) -> Option; - fn collect_active_jobs( - self, - require_complete: bool, - ) -> Result, QueryMap>; - - fn lift_query_info(self, info: &Self::QueryInfo) -> QueryStackFrameExtra; + fn collect_active_jobs(self, require_complete: bool) -> Result; /// Load a side effect associated to the node in the previous session. fn load_side_effect( diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index dea47c8fa787..fa5a94d65188 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -18,7 +18,7 @@ use rustc_errors::{Diag, FatalError, StashKey}; use rustc_span::{DUMMY_SP, Span}; use tracing::instrument; -use super::{QueryConfig, QueryStackFrameExtra}; +use super::QueryConfig; use crate::HandleCycleError; use crate::dep_graph::{DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeParams}; use crate::ich::StableHashingContext; @@ -31,23 +31,23 @@ fn equivalent_key(k: &K) -> impl Fn(&(K, V)) -> bool + '_ { move |x| x.0 == *k } -pub struct QueryState { - active: Sharded)>>, +pub struct QueryState { + active: Sharded>, } /// Indicates the state of a query for a given key in a query map. -enum QueryResult { +enum QueryResult { /// An already executing query. The query job can be used to await for its completion. - Started(QueryJob), + Started(QueryJob), /// The query panicked. Queries trying to wait on this will raise a fatal error which will /// silently panic. Poisoned, } -impl QueryResult { +impl QueryResult { /// Unwraps the query job expecting that it has started. - fn expect_job(self) -> QueryJob { + fn expect_job(self) -> QueryJob { match self { Self::Started(job) => job, Self::Poisoned => { @@ -57,7 +57,7 @@ impl QueryResult { } } -impl QueryState +impl QueryState where K: Eq + Hash + Copy + Debug, { @@ -68,13 +68,13 @@ where pub fn collect_active_jobs( &self, qcx: Qcx, - make_query: fn(Qcx, K) -> QueryStackFrame, - jobs: &mut QueryMap, + make_query: fn(Qcx, K) -> QueryStackFrame, + jobs: &mut QueryMap, require_complete: bool, ) -> Option<()> { let mut active = Vec::new(); - let mut collect = |iter: LockGuard<'_, HashTable<(K, QueryResult)>>| { + let mut collect = |iter: LockGuard<'_, HashTable<(K, QueryResult)>>| { for (k, v) in iter.iter() { if let QueryResult::Started(ref job) = *v { active.push((*k, job.clone())); @@ -105,19 +105,19 @@ where } } -impl Default for QueryState { - fn default() -> QueryState { +impl Default for QueryState { + fn default() -> QueryState { QueryState { active: Default::default() } } } /// A type representing the responsibility to execute the job in the `job` field. /// This will poison the relevant query if dropped. -struct JobOwner<'tcx, K, I> +struct JobOwner<'tcx, K> where K: Eq + Hash + Copy, { - state: &'tcx QueryState, + state: &'tcx QueryState, key: K, } @@ -159,7 +159,7 @@ where } Stash => { let guar = if let Some(root) = cycle_error.cycle.first() - && let Some(span) = root.query.info.span + && let Some(span) = root.query.span { error.stash(span, StashKey::Cycle).unwrap() } else { @@ -170,7 +170,7 @@ where } } -impl<'tcx, K, I> JobOwner<'tcx, K, I> +impl<'tcx, K> JobOwner<'tcx, K> where K: Eq + Hash + Copy, { @@ -207,7 +207,7 @@ where } } -impl<'tcx, K, I> Drop for JobOwner<'tcx, K, I> +impl<'tcx, K> Drop for JobOwner<'tcx, K> where K: Eq + Hash + Copy, { @@ -235,19 +235,10 @@ where } #[derive(Clone, Debug)] -pub struct CycleError { +pub struct CycleError { /// The query and related span that uses the cycle. - pub usage: Option<(Span, QueryStackFrame)>, - pub cycle: Vec>, -} - -impl CycleError { - fn lift>(&self, qcx: Qcx) -> CycleError { - CycleError { - usage: self.usage.as_ref().map(|(span, frame)| (*span, frame.lift(qcx))), - cycle: self.cycle.iter().map(|info| info.lift(qcx)).collect(), - } - } + pub usage: Option<(Span, QueryStackFrame)>, + pub cycle: Vec, } /// Checks whether there is already a value for this key in the in-memory @@ -284,10 +275,10 @@ where { // Ensure there was no errors collecting all active jobs. // We need the complete map to ensure we find a cycle to break. - let query_map = qcx.collect_active_jobs(false).ok().expect("failed to collect active queries"); + let query_map = qcx.collect_active_jobs(false).expect("failed to collect active queries"); let error = try_execute.find_cycle_in_stack(query_map, &qcx.current_query_job(), span); - (mk_cycle(query, qcx, error.lift(qcx)), None) + (mk_cycle(query, qcx, error), None) } #[inline(always)] @@ -296,7 +287,7 @@ fn wait_for_query( qcx: Qcx, span: Span, key: Q::Key, - latch: QueryLatch, + latch: QueryLatch, current: Option, ) -> (Q::Value, Option) where @@ -336,7 +327,7 @@ where (v, Some(index)) } - Err(cycle) => (mk_cycle(query, qcx, cycle.lift(qcx)), None), + Err(cycle) => (mk_cycle(query, qcx, cycle), None), } } @@ -414,7 +405,7 @@ where fn execute_job( query: Q, qcx: Qcx, - state: &QueryState, + state: &QueryState, key: Q::Key, key_hash: u64, id: QueryJobId, From 90e4a421623ed4e9f8e1985795456f734ec822a1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 16 Jan 2026 19:18:16 +1100 Subject: [PATCH 2199/3801] Use `with_reduced_queries` to avoid query cycles. This changes the error message of `query-cycle-issue-124901.rs`, which doesn't matter much. --- compiler/rustc_query_impl/src/plumbing.rs | 10 ++++++---- tests/ui/resolve/query-cycle-issue-124901.rs | 2 +- tests/ui/resolve/query-cycle-issue-124901.stderr | 9 ++++++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index ba1a358d2415..67ab1114af62 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -327,21 +327,23 @@ pub(crate) fn create_query_frame< description }; - let span = if kind == dep_graph::dep_kinds::def_span || reduce_queries { + let span = if reduce_queries { // The `def_span` query is used to calculate `default_span`, // so exit to avoid infinite recursion. None } else { - Some(key.default_span(tcx)) + Some(tcx.with_reduced_queries(|| key.default_span(tcx))) }; let def_id = key.key_as_def_id(); - let def_kind = if kind == dep_graph::dep_kinds::def_kind || reduce_queries { + let def_kind = if reduce_queries { // Try to avoid infinite recursion. None } else { - def_id.and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id)) + def_id + .and_then(|def_id| def_id.as_local()) + .map(|def_id| tcx.with_reduced_queries(|| tcx.def_kind(def_id))) }; let def_id_for_ty_in_cycle = key.def_id_for_ty_in_cycle(); diff --git a/tests/ui/resolve/query-cycle-issue-124901.rs b/tests/ui/resolve/query-cycle-issue-124901.rs index 6cb1e58b6258..ccaee0e6bc6f 100644 --- a/tests/ui/resolve/query-cycle-issue-124901.rs +++ b/tests/ui/resolve/query-cycle-issue-124901.rs @@ -1,4 +1,4 @@ -//~ ERROR: cycle detected when looking up span for `Default` +//~ ERROR: cycle detected when getting HIR ID of `Default` trait Default { type Id; diff --git a/tests/ui/resolve/query-cycle-issue-124901.stderr b/tests/ui/resolve/query-cycle-issue-124901.stderr index 9c1d7b1de33a..3679925c6db4 100644 --- a/tests/ui/resolve/query-cycle-issue-124901.stderr +++ b/tests/ui/resolve/query-cycle-issue-124901.stderr @@ -1,7 +1,10 @@ -error[E0391]: cycle detected when looking up span for `Default` +error[E0391]: cycle detected when getting HIR ID of `Default` | - = note: ...which immediately requires looking up span for `Default` again - = note: cycle used when perform lints prior to AST lowering + = note: ...which requires getting the crate HIR... + = note: ...which requires perform lints prior to AST lowering... + = note: ...which requires looking up span for `Default`... + = note: ...which again requires getting HIR ID of `Default`, completing the cycle + = note: cycle used when getting the resolver for lowering = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 1 previous error From db36c093ca556bc711c167f508c54bda6d3ba5af Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 16 Jan 2026 10:21:06 +0100 Subject: [PATCH 2200/3801] remove lcnr from compiler review rotation --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 456fd696af43..e51622f1e5a9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1458,7 +1458,6 @@ compiler = [ "@jieyouxu", "@jdonszelmann", "@JonathanBrouwer", - "@lcnr", "@madsmtm", "@mati865", "@Nadrieril", From f19591ad27ba306ffe0d2665790894420e0f96bc Mon Sep 17 00:00:00 2001 From: Redddy Date: Fri, 16 Jan 2026 18:39:38 +0900 Subject: [PATCH 2201/3801] Add rust-analyzer setup for out-of-tree rustc_private crates --- .../remarks-on-perma-unstable-features.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md b/src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md index b434cfc9cf14..3c2fe133be84 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md @@ -49,6 +49,29 @@ For custom-built toolchains or environments not using rustup, additional configu ``` 3. **Check version compatibility**: Ensure your LLVM version is compatible with your Rust toolchain +### Configuring `rust-analyzer` for Out-of-Tree Projects + +When developing out-of-tree projects that use `rustc_private` crates, you can configure `rust-analyzer` to recognize these crates. + +#### Configuration Steps + +1. **Set rust-analyzer configuration** + Configure `rust-analyzer.rustc.source` to `"discover"` in your editor settings. + For VS Code, add to `rust_analyzer_settings.json`: + ```json + { + "rust-analyzer.rustc.source": "discover" + } + ``` +2. **Add metadata to Cargo.toml** + Add the following to the `Cargo.toml` of every crate that uses `rustc_private`: + ```toml + [package.metadata.rust-analyzer] + rustc_private = true + ``` + +This configuration allows `rust-analyzer` to properly recognize and provide IDE support for `rustc_private` crates in out-of-tree projects. + ### Additional Resources - [GitHub Issue #137421](https://github.com/rust-lang/rust/issues/137421): Explains that `rustc_private` linker failures often occur because `llvm-tools` is not installed From 21f269e72ed90f73abbd531243d6f563d2689650 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 16 Jan 2026 10:47:01 +0100 Subject: [PATCH 2202/3801] add RPITIT cycle issue --- .../src/solve/candidate-preference.md | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/solve/candidate-preference.md b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md index 8b28f56760a7..d5a75b41ff1f 100644 --- a/src/doc/rustc-dev-guide/src/solve/candidate-preference.md +++ b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md @@ -260,11 +260,13 @@ We prefer builtin trait object impls over user-written impls. This is **unsound* The candidate preference behavior during normalization is implemented in [`fn assemble_and_merge_candidates`]. -### Where-bounds shadow impls +### Trait where-bounds shadow impls Normalization of associated items does not consider impls if the corresponding trait goal has been proven via a `ParamEnv` or `AliasBound` candidate. This means that for where-bounds which do not constrain associated types, the associated types remain *rigid*. +#### Using impls results in different region constraints + This is necessary to avoid unnecessary region constraints from applying impls. ```rust trait Trait<'a> { @@ -286,6 +288,39 @@ where } ``` +#### RPITIT `type_of` cycles + +We currently have to avoid impl candidates if there are where-bounds to avoid query cycles for RPITIT, see [#139762]. It feels desirable to me to stop relying on auto-trait leakage of during RPITIT computation to remove this issue, see [#139788]. + +```rust +use std::future::Future; +pub trait ReactiveFunction: Send { + type Output; + + fn invoke(self) -> Self::Output; +} + +trait AttributeValue { + fn resolve(self) -> impl Future + Send; +} + +impl AttributeValue for F +where + F: ReactiveFunction, + V: AttributeValue, +{ + async fn resolve(self) { + // We're awaiting `::{synthetic#0}` here. + // Normalizing that one via the the impl we're currently in + // relies on `collect_return_position_impl_trait_in_trait_tys` which + // ends up relying on auto-trait leakage when checking that the + // opaque return type of this function implements the `Send` item + // bound of the trait definition. + self.invoke().resolve().await + } +} +``` + ### We always consider `AliasBound` candidates In case the where-bound does not specify the associated item, we consider `AliasBound` candidates instead of treating the alias as rigid, even though the trait goal was proven via a `ParamEnv` candidate. @@ -424,4 +459,6 @@ where [`fn assemble_and_merge_candidates`]: https://github.com/rust-lang/rust/blob/e3ee7f7aea5b45af3b42b5e4713da43876a65ac9/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs#L920-L1003 [trait-system-refactor-initiative#76]: https://github.com/rust-lang/trait-system-refactor-initiative/issues/76 [#24066]: https://github.com/rust-lang/rust/issues/24066 -[#133044]: https://github.com/rust-lang/rust/issues/133044 \ No newline at end of file +[#133044]: https://github.com/rust-lang/rust/issues/133044 +[#139762]: https://github.com/rust-lang/rust/pull/139762 +[#139788]: https://github.com/rust-lang/rust/issues/139788 \ No newline at end of file From 908ae5a86f5191bf316456dcc9257a942d8bce7f Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 16 Jan 2026 10:48:01 +0100 Subject: [PATCH 2203/3801] move section --- .../src/solve/candidate-preference.md | 121 +++++++++--------- 1 file changed, 61 insertions(+), 60 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/solve/candidate-preference.md b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md index d5a75b41ff1f..461523424b3c 100644 --- a/src/doc/rustc-dev-guide/src/solve/candidate-preference.md +++ b/src/doc/rustc-dev-guide/src/solve/candidate-preference.md @@ -260,66 +260,6 @@ We prefer builtin trait object impls over user-written impls. This is **unsound* The candidate preference behavior during normalization is implemented in [`fn assemble_and_merge_candidates`]. -### Trait where-bounds shadow impls - -Normalization of associated items does not consider impls if the corresponding trait goal has been proven via a `ParamEnv` or `AliasBound` candidate. -This means that for where-bounds which do not constrain associated types, the associated types remain *rigid*. - -#### Using impls results in different region constraints - -This is necessary to avoid unnecessary region constraints from applying impls. -```rust -trait Trait<'a> { - type Assoc; -} -impl Trait<'static> for u32 { - type Assoc = u32; -} - -fn bar<'b, T: Trait<'b>>() -> T::Assoc { todo!() } -fn foo<'a>() -where - u32: Trait<'a>, -{ - // Normalizing the return type would use the impl, proving - // the `T: Trait` where-bound would use the where-bound, resulting - // in different region constraints. - bar::<'_, u32>(); -} -``` - -#### RPITIT `type_of` cycles - -We currently have to avoid impl candidates if there are where-bounds to avoid query cycles for RPITIT, see [#139762]. It feels desirable to me to stop relying on auto-trait leakage of during RPITIT computation to remove this issue, see [#139788]. - -```rust -use std::future::Future; -pub trait ReactiveFunction: Send { - type Output; - - fn invoke(self) -> Self::Output; -} - -trait AttributeValue { - fn resolve(self) -> impl Future + Send; -} - -impl AttributeValue for F -where - F: ReactiveFunction, - V: AttributeValue, -{ - async fn resolve(self) { - // We're awaiting `::{synthetic#0}` here. - // Normalizing that one via the the impl we're currently in - // relies on `collect_return_position_impl_trait_in_trait_tys` which - // ends up relying on auto-trait leakage when checking that the - // opaque return type of this function implements the `Send` item - // bound of the trait definition. - self.invoke().resolve().await - } -} -``` ### We always consider `AliasBound` candidates @@ -453,6 +393,67 @@ where } ``` +### Trait where-bounds shadow impls + +Normalization of associated items does not consider impls if the corresponding trait goal has been proven via a `ParamEnv` or `AliasBound` candidate. +This means that for where-bounds which do not constrain associated types, the associated types remain *rigid*. + +#### Using impls results in different region constraints + +This is necessary to avoid unnecessary region constraints from applying impls. +```rust +trait Trait<'a> { + type Assoc; +} +impl Trait<'static> for u32 { + type Assoc = u32; +} + +fn bar<'b, T: Trait<'b>>() -> T::Assoc { todo!() } +fn foo<'a>() +where + u32: Trait<'a>, +{ + // Normalizing the return type would use the impl, proving + // the `T: Trait` where-bound would use the where-bound, resulting + // in different region constraints. + bar::<'_, u32>(); +} +``` + +#### RPITIT `type_of` cycles + +We currently have to avoid impl candidates if there are where-bounds to avoid query cycles for RPITIT, see [#139762]. It feels desirable to me to stop relying on auto-trait leakage of during RPITIT computation to remove this issue, see [#139788]. + +```rust +use std::future::Future; +pub trait ReactiveFunction: Send { + type Output; + + fn invoke(self) -> Self::Output; +} + +trait AttributeValue { + fn resolve(self) -> impl Future + Send; +} + +impl AttributeValue for F +where + F: ReactiveFunction, + V: AttributeValue, +{ + async fn resolve(self) { + // We're awaiting `::{synthetic#0}` here. + // Normalizing that one via the the impl we're currently in + // relies on `collect_return_position_impl_trait_in_trait_tys` which + // ends up relying on auto-trait leakage when checking that the + // opaque return type of this function implements the `Send` item + // bound of the trait definition. + self.invoke().resolve().await + } +} +``` + [`Candidate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/assembly/struct.Candidate.html [`CandidateSource`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/enum.CandidateSource.html [`fn merge_trait_candidates`]: https://github.com/rust-lang/rust/blob/e3ee7f7aea5b45af3b42b5e4713da43876a65ac9/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs#L1342-L1424 From 9e4c55ac8d9d1083983bdc2c35a3513cddb3fc69 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Fri, 16 Jan 2026 19:26:34 +0900 Subject: [PATCH 2204/3801] Rename "remarks on perma unstable features" to "external rustc_drivers" --- src/doc/rustc-dev-guide/src/SUMMARY.md | 2 +- ...-on-perma-unstable-features.md => external-rustc-drivers.md} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/doc/rustc-dev-guide/src/rustc-driver/{remarks-on-perma-unstable-features.md => external-rustc-drivers.md} (98%) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 2dd07144a78c..daaaef42d909 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -140,7 +140,7 @@ - [Command-line arguments](./cli.md) - [rustc_driver and rustc_interface](./rustc-driver/intro.md) - - [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md) + - [External rustc_drivers](./rustc-driver/external-rustc-drivers.md) - [Example: Type checking](./rustc-driver/interacting-with-the-ast.md) - [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md) - [Errors and lints](diagnostics.md) diff --git a/src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md b/src/doc/rustc-dev-guide/src/rustc-driver/external-rustc-drivers.md similarity index 98% rename from src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md rename to src/doc/rustc-dev-guide/src/rustc-driver/external-rustc-drivers.md index 3c2fe133be84..1049d7a82ddd 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver/remarks-on-perma-unstable-features.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver/external-rustc-drivers.md @@ -1,4 +1,4 @@ -# Remarks on perma unstable features +# External `rustc_driver`s ## `rustc_private` From 75445635784ebf4683a6d22aa8b9563469bd0e0c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 15 Jan 2026 16:48:30 +0100 Subject: [PATCH 2205/3801] Only enable rustdoc `--generate-macro-expansion` option for stage builds higher than 1 --- src/bootstrap/src/core/build_steps/doc.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index fa36a6471cae..d8e8f65caa98 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -932,7 +932,13 @@ impl Step for Rustc { // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222 // If there is any bug, please comment out the next line. cargo.rustdocflag("--generate-link-to-definition"); - cargo.rustdocflag("--generate-macro-expansion"); + // FIXME: Currently, `--generate-macro-expansion` option is buggy in `beta` rustdoc. To + // allow CI to pass, we only enable the option in stage 2 and higher. + // cfg(bootstrap) + // ^ Adding this so it's not forgotten when the new release is done. + if builder.top_stage > 1 { + cargo.rustdocflag("--generate-macro-expansion"); + } compile::rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates); cargo.arg("-Zskip-rustdoc-fingerprint"); From 567b569e2bb131abcbf77eef7d98b7f50d47465a Mon Sep 17 00:00:00 2001 From: Clara Engler Date: Fri, 16 Jan 2026 10:39:35 +0100 Subject: [PATCH 2206/3801] time: Add saturating arithmetic for `SystemTime` This commit implements the following methods: * `SystemTime::saturating_add` * `SystemTime::saturating_sub` * `SystemTime::saturating_duration_since` The implementation of these methods is rather trivial, as the main logic lies behind the constants `SystemTime::MIN` and `SystemTime::MAX`. --- library/std/src/time.rs | 50 +++++++++++++++++++++++++++++++++++++++ library/std/tests/time.rs | 39 ++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 3d09824019e3..1805d8926098 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -682,6 +682,56 @@ impl SystemTime { pub fn checked_sub(&self, duration: Duration) -> Option { self.0.checked_sub_duration(&duration).map(SystemTime) } + + /// Saturating [`SystemTime`] addition, computing `self + duration`, + /// returning [`SystemTime::MAX`] if overflow occurred. + /// + /// In the case that the `duration` is smaller than the time precision of + /// the operating system, `self` will be returned. + #[unstable(feature = "time_saturating_systemtime", issue = "151199")] + pub fn saturating_add(&self, duration: Duration) -> SystemTime { + self.checked_add(duration).unwrap_or(SystemTime::MAX) + } + + /// Saturating [`SystemTime`] subtraction, computing `self - duration`, + /// returning [`SystemTime::MIN`] if overflow occurred. + /// + /// In the case that the `duration` is smaller than the time precision of + /// the operating system, `self` will be returned. + #[unstable(feature = "time_saturating_systemtime", issue = "151199")] + pub fn saturating_sub(&self, duration: Duration) -> SystemTime { + self.checked_sub(duration).unwrap_or(SystemTime::MIN) + } + + /// Saturating computation of time elapsed from an earlier point in time, + /// returning [`Duration::ZERO`] in the case that `earlier` is later or + /// equal to `self`. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(time_saturating_systemtime)] + /// use std::time::{Duration, SystemTime}; + /// + /// let now = SystemTime::now(); + /// let prev = now.saturating_sub(Duration::new(1, 0)); + /// + /// // now - prev should return non-zero. + /// assert_eq!(now.saturating_duration_since(prev), Duration::new(1, 0)); + /// assert!(now.duration_since(prev).is_ok()); + /// + /// // prev - now should return zero (and fail with the non-saturating). + /// assert_eq!(prev.saturating_duration_since(now), Duration::ZERO); + /// assert!(prev.duration_since(now).is_err()); + /// + /// // now - now should return zero (and work with the non-saturating). + /// assert_eq!(now.saturating_duration_since(now), Duration::ZERO); + /// assert!(now.duration_since(now).is_ok()); + /// ``` + #[unstable(feature = "time_saturating_systemtime", issue = "151199")] + pub fn saturating_duration_since(&self, earlier: SystemTime) -> Duration { + self.duration_since(earlier).unwrap_or(Duration::ZERO) + } } #[stable(feature = "time2", since = "1.8.0")] diff --git a/library/std/tests/time.rs b/library/std/tests/time.rs index 0ef89bb09c63..b73e7bc3962e 100644 --- a/library/std/tests/time.rs +++ b/library/std/tests/time.rs @@ -1,5 +1,6 @@ #![feature(duration_constants)] #![feature(time_systemtime_limits)] +#![feature(time_saturating_systemtime)] use std::fmt::Debug; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; @@ -269,3 +270,41 @@ fn system_time_max_min() { assert!(SystemTime::MIN.checked_add(MIN_INTERVAL).is_some()); assert!(SystemTime::MIN.checked_sub(MIN_INTERVAL).is_none()); } + +#[test] +fn system_time_saturating() { + // Perform saturating addition on SystemTime::MAX to see how it behaves. + assert_eq!(SystemTime::MAX.saturating_add(Duration::ZERO), SystemTime::MAX); + assert_eq!(SystemTime::MAX.saturating_add(Duration::new(1, 0)), SystemTime::MAX); + assert!(SystemTime::MAX.checked_add(Duration::new(1, 0)).is_none()); + assert_eq!( + SystemTime::MAX.saturating_sub(Duration::new(1, 0)), + SystemTime::MAX.checked_sub(Duration::new(1, 0)).unwrap() + ); + + // Perform saturating subtraction on SystemTime::MIn to see how it behaves. + assert_eq!(SystemTime::MIN.saturating_sub(Duration::ZERO), SystemTime::MIN); + assert_eq!(SystemTime::MIN.saturating_sub(Duration::new(1, 0)), SystemTime::MIN); + assert!(SystemTime::MIN.checked_sub(Duration::new(1, 0)).is_none()); + assert_eq!( + SystemTime::MIN.saturating_add(Duration::new(1, 0)), + SystemTime::MIN.checked_add(Duration::new(1, 0)).unwrap() + ); + + // Check saturating_duration_since with various constant values. + assert!(SystemTime::MAX.saturating_duration_since(SystemTime::MIN) >= Duration::ZERO); + assert_eq!(SystemTime::MAX.saturating_duration_since(SystemTime::MAX), Duration::ZERO); + assert!(SystemTime::MAX.duration_since(SystemTime::MAX).is_ok()); + assert_eq!(SystemTime::MIN.saturating_duration_since(SystemTime::MAX), Duration::ZERO); + assert!(SystemTime::MIN.duration_since(SystemTime::MAX).is_err()); + assert_eq!( + (SystemTime::UNIX_EPOCH + Duration::new(1, 0)) + .saturating_duration_since(SystemTime::UNIX_EPOCH), + Duration::new(1, 0) + ); + assert_eq!( + SystemTime::UNIX_EPOCH + .saturating_duration_since(SystemTime::UNIX_EPOCH + Duration::new(1, 0)), + Duration::ZERO + ); +} From d028956f11c85206f6d02c5dd38ccf5f4ce24b91 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Fri, 16 Jan 2026 10:22:43 +0100 Subject: [PATCH 2207/3801] Add an additional help note to the ambiguity lint error This PR adds an additional help note to the ambiguity lint error output to ask users updating their dependencies. This hopefully helps with cases like https://github.com/rust-lang/rust/issues/149845 where newer crate versions are fixed. --- compiler/rustc_resolve/src/diagnostics.rs | 15 +++++++++++++++ compiler/rustc_resolve/src/errors.rs | 6 ++++++ tests/ui/imports/ambiguous-2.stderr | 4 ++++ tests/ui/imports/ambiguous-4.stderr | 4 ++++ .../ui/imports/glob-conflict-cross-crate-1.stderr | 8 ++++++++ .../ui/imports/glob-conflict-cross-crate-2.stderr | 4 ++++ .../ui/imports/glob-conflict-cross-crate-3.stderr | 4 ++++ tests/ui/imports/issue-114682-2.stderr | 8 ++++++++ tests/ui/imports/issue-114682-4.stderr | 4 ++++ tests/ui/imports/issue-114682-5.stderr | 4 ++++ tests/ui/imports/issue-114682-6.stderr | 4 ++++ 11 files changed, 65 insertions(+) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index e9f94dedf522..4f371643ed24 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2064,9 +2064,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; let (b1_note, b1_help_msgs) = could_refer_to(b1, scope1, ""); let (b2_note, b2_help_msgs) = could_refer_to(b2, scope2, " also"); + let help = if kind == AmbiguityKind::GlobVsGlob + && b1 + .parent_module + .and_then(|m| m.opt_def_id()) + .map(|d| !d.is_local()) + .unwrap_or_default() + { + Some(&[ + "consider updating this dependency to resolve this error", + "if updating the dependency does not resolve the problem report the problem to the author of the relevant crate", + ] as &[_]) + } else { + None + }; errors::Ambiguity { ident, + help, kind: kind.descr(), b1_note, b1_help_msgs, diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 8880c2ba2666..d614219e8eab 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1464,6 +1464,7 @@ pub(crate) struct UnknownDiagnosticAttributeTypoSugg { pub(crate) struct Ambiguity { pub ident: Ident, pub kind: &'static str, + pub help: Option<&'static [&'static str]>, pub b1_note: Spanned, pub b1_help_msgs: Vec, pub b2_note: Spanned, @@ -1476,6 +1477,11 @@ impl Ambiguity { diag.span_label(self.ident.span, "ambiguous name"); diag.note(format!("ambiguous because of {}", self.kind)); diag.span_note(self.b1_note.span, self.b1_note.node); + if let Some(help) = self.help { + for help in help { + diag.help(*help); + } + } for help_msg in self.b1_help_msgs { diag.help(help_msg); } diff --git a/tests/ui/imports/ambiguous-2.stderr b/tests/ui/imports/ambiguous-2.stderr index a0222099239a..5b12491af19d 100644 --- a/tests/ui/imports/ambiguous-2.stderr +++ b/tests/ui/imports/ambiguous-2.stderr @@ -12,6 +12,8 @@ note: `id` could refer to the function defined here | LL | pub use self::evp::*; | ^^^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `id` could also refer to the function defined here --> $DIR/auxiliary/../ambiguous-1.rs:15:13 | @@ -36,6 +38,8 @@ note: `id` could refer to the function defined here | LL | pub use self::evp::*; | ^^^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `id` could also refer to the function defined here --> $DIR/auxiliary/../ambiguous-1.rs:15:13 | diff --git a/tests/ui/imports/ambiguous-4.stderr b/tests/ui/imports/ambiguous-4.stderr index 6c1a2679fcae..691dd33a398a 100644 --- a/tests/ui/imports/ambiguous-4.stderr +++ b/tests/ui/imports/ambiguous-4.stderr @@ -12,6 +12,8 @@ note: `id` could refer to the function defined here | LL | pub use evp::*; | ^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `id` could also refer to the function defined here --> $DIR/auxiliary/../ambiguous-4-extern.rs:14:9 | @@ -36,6 +38,8 @@ note: `id` could refer to the function defined here | LL | pub use evp::*; | ^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `id` could also refer to the function defined here --> $DIR/auxiliary/../ambiguous-4-extern.rs:14:9 | diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr index 440113653675..4eb27729b41a 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -12,6 +12,8 @@ note: `f` could refer to the function defined here | LL | pub use m1::*; | ^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `f` could also refer to the function defined here --> $DIR/auxiliary/glob-conflict.rs:13:9 | @@ -33,6 +35,8 @@ note: `f` could refer to the function defined here | LL | pub use m1::*; | ^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `f` could also refer to the function defined here --> $DIR/auxiliary/glob-conflict.rs:13:9 | @@ -56,6 +60,8 @@ note: `f` could refer to the function defined here | LL | pub use m1::*; | ^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `f` could also refer to the function defined here --> $DIR/auxiliary/glob-conflict.rs:13:9 | @@ -78,6 +84,8 @@ note: `f` could refer to the function defined here | LL | pub use m1::*; | ^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `f` could also refer to the function defined here --> $DIR/auxiliary/glob-conflict.rs:13:9 | diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.stderr b/tests/ui/imports/glob-conflict-cross-crate-2.stderr index 2ee519a364b3..6ff36477e45f 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-2.stderr @@ -12,6 +12,8 @@ note: `C` could refer to the type alias defined here | LL | pub use a::*; | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `C` could also refer to the type alias defined here --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 | @@ -36,6 +38,8 @@ note: `C` could refer to the type alias defined here | LL | pub use a::*; | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `C` could also refer to the type alias defined here --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 | diff --git a/tests/ui/imports/glob-conflict-cross-crate-3.stderr b/tests/ui/imports/glob-conflict-cross-crate-3.stderr index c7457efe866e..9b6867774ebe 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-3.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-3.stderr @@ -12,6 +12,8 @@ note: `C` could refer to the type alias defined here | LL | pub use a::*; | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `C` could also refer to the type alias defined here --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 | @@ -58,6 +60,8 @@ note: `C` could refer to the type alias defined here | LL | pub use a::*; | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `C` could also refer to the type alias defined here --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 | diff --git a/tests/ui/imports/issue-114682-2.stderr b/tests/ui/imports/issue-114682-2.stderr index f93e4409f0c4..92fac9f0a424 100644 --- a/tests/ui/imports/issue-114682-2.stderr +++ b/tests/ui/imports/issue-114682-2.stderr @@ -12,6 +12,8 @@ note: `max` could refer to the type alias defined here | LL | pub use self::e::*; | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `max` could also refer to the module defined here --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 | @@ -33,6 +35,8 @@ note: `max` could refer to the type alias defined here | LL | pub use self::e::*; | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `max` could also refer to the module defined here --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 | @@ -56,6 +60,8 @@ note: `max` could refer to the type alias defined here | LL | pub use self::e::*; | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `max` could also refer to the module defined here --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 | @@ -78,6 +84,8 @@ note: `max` could refer to the type alias defined here | LL | pub use self::e::*; | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `max` could also refer to the module defined here --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 | diff --git a/tests/ui/imports/issue-114682-4.stderr b/tests/ui/imports/issue-114682-4.stderr index 12cb9ae95a42..5b012e21ea81 100644 --- a/tests/ui/imports/issue-114682-4.stderr +++ b/tests/ui/imports/issue-114682-4.stderr @@ -12,6 +12,8 @@ note: `Result` could refer to the type alias defined here | LL | pub use a::*; | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `Result` could also refer to the type alias defined here --> $DIR/auxiliary/issue-114682-4-extern.rs:10:9 | @@ -51,6 +53,8 @@ note: `Result` could refer to the type alias defined here | LL | pub use a::*; | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `Result` could also refer to the type alias defined here --> $DIR/auxiliary/issue-114682-4-extern.rs:10:9 | diff --git a/tests/ui/imports/issue-114682-5.stderr b/tests/ui/imports/issue-114682-5.stderr index 74b42e0990b7..5937f6f33117 100644 --- a/tests/ui/imports/issue-114682-5.stderr +++ b/tests/ui/imports/issue-114682-5.stderr @@ -40,6 +40,8 @@ note: `issue_114682_5_extern_1` could refer to the module defined here | LL | pub use crate::types::*; | ^^^^^^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `issue_114682_5_extern_1` could also refer to the crate defined here --> $DIR/auxiliary/issue-114682-5-extern-2.rs:7:13 | @@ -67,6 +69,8 @@ note: `issue_114682_5_extern_1` could refer to the module defined here | LL | pub use crate::types::*; | ^^^^^^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `issue_114682_5_extern_1` could also refer to the crate defined here --> $DIR/auxiliary/issue-114682-5-extern-2.rs:7:13 | diff --git a/tests/ui/imports/issue-114682-6.stderr b/tests/ui/imports/issue-114682-6.stderr index 37f8f6c16ff2..a2e9afb6eedb 100644 --- a/tests/ui/imports/issue-114682-6.stderr +++ b/tests/ui/imports/issue-114682-6.stderr @@ -12,6 +12,8 @@ note: `log` could refer to the function defined here | LL | pub use self::a::*; | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `log` could also refer to the function defined here --> $DIR/auxiliary/issue-114682-6-extern.rs:9:9 | @@ -36,6 +38,8 @@ note: `log` could refer to the function defined here | LL | pub use self::a::*; | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate note: `log` could also refer to the function defined here --> $DIR/auxiliary/issue-114682-6-extern.rs:9:9 | From 19e0d7914f2865c707ace136fd33ab6f8c2931fb Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 16 Jan 2026 13:08:09 +0000 Subject: [PATCH 2208/3801] Mention `cast_signed` in docs of `cast_possible_wrap` changelog: [`cast_possible_wrap`]: mention `cast_{un,}signed()` methods in doc I was evaluating this lint recently, and accepted using it because these methods exist. But the docs on the lint don't mention it, so I thought it would be prudent to include it in the docs. See also https://github.com/rust-lang/rust-clippy/pull/15384 Co-authored-by: Kaur Kuut Co-authored-by: Samuel Tardieu --- clippy_lints/src/casts/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 7220a8a80066..3c9ebef73f0d 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -145,6 +145,12 @@ declare_clippy_lint! { /// let _ = i32::try_from(u32::MAX).ok(); /// ``` /// + /// If the wrapping is intended, you can use: + /// ```no_run + /// let _ = u32::MAX.cast_signed(); + /// let _ = (-1i32).cast_unsigned(); + /// ``` + /// #[clippy::version = "pre 1.29.0"] pub CAST_POSSIBLE_WRAP, pedantic, From e45e4a7cc65242f5dd2a750ec8860952b0f69949 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 16 Jan 2026 13:31:38 +0000 Subject: [PATCH 2209/3801] delete weird `fd_read` feature --- library/std/src/sys/net/connection/socket/windows.rs | 1 - src/doc/unstable-book/src/library-features/fd-read.md | 5 ----- 2 files changed, 6 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/fd-read.md diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index 3f99249efc47..b23fb9c09f87 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs @@ -451,7 +451,6 @@ impl Socket { } } -#[unstable(reason = "not public", issue = "none", feature = "fd_read")] impl<'a> Read for &'a Socket { fn read(&mut self, buf: &mut [u8]) -> io::Result { (**self).read(buf) diff --git a/src/doc/unstable-book/src/library-features/fd-read.md b/src/doc/unstable-book/src/library-features/fd-read.md deleted file mode 100644 index e78d4330abfc..000000000000 --- a/src/doc/unstable-book/src/library-features/fd-read.md +++ /dev/null @@ -1,5 +0,0 @@ -# `fd_read` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- From f13b1549cee9d2c7e47084f9e8d57f8fbec45382 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 16 Jan 2026 13:32:24 +0000 Subject: [PATCH 2210/3801] remove `reason = "recently added"` from `#[unstable(...)]` --- library/core/src/iter/adapters/array_chunks.rs | 12 ++++++------ library/core/src/iter/adapters/intersperse.rs | 16 ++++++++-------- library/core/src/iter/adapters/map_windows.rs | 12 ++++++------ library/core/src/iter/adapters/mod.rs | 6 +++--- library/core/src/iter/mod.rs | 6 +++--- library/core/src/iter/traits/double_ended.rs | 2 +- library/core/src/iter/traits/iterator.rs | 12 ++++++------ library/std/src/io/mod.rs | 2 +- library/std/src/os/unix/io/mod.rs | 6 +++--- 9 files changed, 37 insertions(+), 37 deletions(-) diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs index 21f46ab8b6a4..7c003cff10c7 100644 --- a/library/core/src/iter/adapters/array_chunks.rs +++ b/library/core/src/iter/adapters/array_chunks.rs @@ -15,7 +15,7 @@ use crate::ops::{ControlFlow, NeverShortCircuit, Try}; /// method on [`Iterator`]. See its documentation for more. #[derive(Debug, Clone)] #[must_use = "iterators are lazy and do nothing unless consumed"] -#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] +#[unstable(feature = "iter_array_chunks", issue = "100450")] pub struct ArrayChunks { iter: I, remainder: Option>, @@ -44,7 +44,7 @@ where /// assert_eq!(rem.next(), Some(5)); /// assert_eq!(rem.next(), None); /// ``` - #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] + #[unstable(feature = "iter_array_chunks", issue = "100450")] #[inline] pub fn into_remainder(mut self) -> array::IntoIter { if self.remainder.is_none() { @@ -54,7 +54,7 @@ where } } -#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] +#[unstable(feature = "iter_array_chunks", issue = "100450")] impl Iterator for ArrayChunks where I: Iterator, @@ -108,7 +108,7 @@ where } } -#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] +#[unstable(feature = "iter_array_chunks", issue = "100450")] impl DoubleEndedIterator for ArrayChunks where I: DoubleEndedIterator + ExactSizeIterator, @@ -173,13 +173,13 @@ where } } -#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] +#[unstable(feature = "iter_array_chunks", issue = "100450")] impl FusedIterator for ArrayChunks where I: FusedIterator {} #[unstable(issue = "none", feature = "trusted_fused")] unsafe impl TrustedFused for ArrayChunks where I: TrustedFused + Iterator {} -#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] +#[unstable(feature = "iter_array_chunks", issue = "100450")] impl ExactSizeIterator for ArrayChunks where I: ExactSizeIterator, diff --git a/library/core/src/iter/adapters/intersperse.rs b/library/core/src/iter/adapters/intersperse.rs index 843479e2a27a..bb94ed0a0a17 100644 --- a/library/core/src/iter/adapters/intersperse.rs +++ b/library/core/src/iter/adapters/intersperse.rs @@ -5,7 +5,7 @@ use crate::iter::{Fuse, FusedIterator}; /// /// This `struct` is created by [`Iterator::intersperse`]. See its documentation /// for more information. -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] #[derive(Debug, Clone)] pub struct Intersperse where @@ -17,7 +17,7 @@ where iter: Fuse, } -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] impl FusedIterator for Intersperse where I: FusedIterator, @@ -34,7 +34,7 @@ where } } -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] impl Iterator for Intersperse where I: Iterator, @@ -87,7 +87,7 @@ where /// /// This `struct` is created by [`Iterator::intersperse_with`]. See its /// documentation for more information. -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] pub struct IntersperseWith where I: Iterator, @@ -98,7 +98,7 @@ where iter: Fuse, } -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] impl FusedIterator for IntersperseWith where I: FusedIterator, @@ -106,7 +106,7 @@ where { } -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] impl fmt::Debug for IntersperseWith where I: Iterator + fmt::Debug, @@ -123,7 +123,7 @@ where } } -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] impl Clone for IntersperseWith where I: Iterator + Clone, @@ -150,7 +150,7 @@ where } } -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] impl Iterator for IntersperseWith where I: Iterator, diff --git a/library/core/src/iter/adapters/map_windows.rs b/library/core/src/iter/adapters/map_windows.rs index 0dada9eb6aac..cef556319143 100644 --- a/library/core/src/iter/adapters/map_windows.rs +++ b/library/core/src/iter/adapters/map_windows.rs @@ -7,7 +7,7 @@ use crate::{fmt, ptr}; /// This `struct` is created by the [`Iterator::map_windows`]. See its /// documentation for more information. #[must_use = "iterators are lazy and do nothing unless consumed"] -#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")] +#[unstable(feature = "iter_map_windows", issue = "87155")] pub struct MapWindows { f: F, inner: MapWindowsInner, @@ -234,7 +234,7 @@ impl Drop for Buffer { } } -#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")] +#[unstable(feature = "iter_map_windows", issue = "87155")] impl Iterator for MapWindows where I: Iterator, @@ -255,7 +255,7 @@ where // Note that even if the inner iterator not fused, the `MapWindows` is still fused, // because we don't allow "holes" in the mapping window. -#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")] +#[unstable(feature = "iter_map_windows", issue = "87155")] impl FusedIterator for MapWindows where I: Iterator, @@ -263,7 +263,7 @@ where { } -#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")] +#[unstable(feature = "iter_map_windows", issue = "87155")] impl ExactSizeIterator for MapWindows where I: ExactSizeIterator, @@ -271,14 +271,14 @@ where { } -#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")] +#[unstable(feature = "iter_map_windows", issue = "87155")] impl fmt::Debug for MapWindows { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MapWindows").field("iter", &self.inner.iter).finish() } } -#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")] +#[unstable(feature = "iter_map_windows", issue = "87155")] impl Clone for MapWindows where I: Iterator + Clone, diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 1ff5093922b6..d0b89fdbb584 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -28,7 +28,7 @@ mod take; mod take_while; mod zip; -#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] +#[unstable(feature = "iter_array_chunks", issue = "100450")] pub use self::array_chunks::ArrayChunks; #[unstable(feature = "std_internals", issue = "none")] pub use self::by_ref_sized::ByRefSized; @@ -40,11 +40,11 @@ pub use self::cloned::Cloned; pub use self::copied::Copied; #[stable(feature = "iterator_flatten", since = "1.29.0")] pub use self::flatten::Flatten; -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] pub use self::intersperse::{Intersperse, IntersperseWith}; #[stable(feature = "iter_map_while", since = "1.57.0")] pub use self::map_while::MapWhile; -#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")] +#[unstable(feature = "iter_map_windows", issue = "87155")] pub use self::map_windows::MapWindows; #[stable(feature = "iterator_step_by", since = "1.28.0")] pub use self::step_by::StepBy; diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs index c7e1c4ef767b..d532f1e56807 100644 --- a/library/core/src/iter/mod.rs +++ b/library/core/src/iter/mod.rs @@ -382,7 +382,7 @@ macro_rules! impl_fold_via_try_fold { }; } -#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] +#[unstable(feature = "iter_array_chunks", issue = "100450")] pub use self::adapters::ArrayChunks; #[unstable(feature = "std_internals", issue = "none")] pub use self::adapters::ByRefSized; @@ -394,7 +394,7 @@ pub use self::adapters::Copied; pub use self::adapters::Flatten; #[stable(feature = "iter_map_while", since = "1.57.0")] pub use self::adapters::MapWhile; -#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")] +#[unstable(feature = "iter_map_windows", issue = "87155")] pub use self::adapters::MapWindows; #[unstable(feature = "inplace_iteration", issue = "none")] pub use self::adapters::SourceIter; @@ -414,7 +414,7 @@ pub use self::adapters::{ Chain, Cycle, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Scan, Skip, SkipWhile, Take, TakeWhile, Zip, }; -#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] +#[unstable(feature = "iter_intersperse", issue = "79524")] pub use self::adapters::{Intersperse, IntersperseWith}; #[unstable( feature = "step_trait", diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index da0b05063657..9f7ac7da2dbd 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -134,7 +134,7 @@ pub trait DoubleEndedIterator: Iterator { /// [`Ok(())`]: Ok /// [`Err(k)`]: Err #[inline] - #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] + #[unstable(feature = "iter_advance_by", issue = "77404")] fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { for i in 0..n { if self.next_back().is_none() { diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 419f66089b10..81901fc011be 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -106,7 +106,7 @@ pub trait Iterator { /// assert_eq!(third, "those"); /// ``` #[inline] - #[unstable(feature = "iter_next_chunk", reason = "recently added", issue = "98326")] + #[unstable(feature = "iter_next_chunk", issue = "98326")] fn next_chunk( &mut self, ) -> Result<[Self::Item; N], array::IntoIter> @@ -297,7 +297,7 @@ pub trait Iterator { /// assert_eq!(iter.advance_by(100), Err(NonZero::new(99).unwrap())); // only `4` was skipped /// ``` #[inline] - #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] + #[unstable(feature = "iter_advance_by", issue = "77404")] fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { /// Helper trait to specialize `advance_by` via `try_fold` for `Sized` iterators. trait SpecAdvanceBy { @@ -656,7 +656,7 @@ pub trait Iterator { /// [`Clone`]: crate::clone::Clone /// [`intersperse_with`]: Iterator::intersperse_with #[inline] - #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] + #[unstable(feature = "iter_intersperse", issue = "79524")] fn intersperse(self, separator: Self::Item) -> Intersperse where Self: Sized, @@ -714,7 +714,7 @@ pub trait Iterator { /// [`Clone`]: crate::clone::Clone /// [`intersperse`]: Iterator::intersperse #[inline] - #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] + #[unstable(feature = "iter_intersperse", issue = "79524")] fn intersperse_with(self, separator: G) -> IntersperseWith where Self: Sized, @@ -1713,7 +1713,7 @@ pub trait Iterator { /// assert_eq!(iter.next(), None); /// ``` #[inline] - #[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")] + #[unstable(feature = "iter_map_windows", issue = "87155")] fn map_windows(self, f: F) -> MapWindows where Self: Sized, @@ -3554,7 +3554,7 @@ pub trait Iterator { /// } /// ``` #[track_caller] - #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] + #[unstable(feature = "iter_array_chunks", issue = "100450")] fn array_chunks(self) -> ArrayChunks where Self: Sized, diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index b7756befa11e..623c34c6d291 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2431,7 +2431,7 @@ pub trait BufRead: Read { /// } /// # std::io::Result::Ok(()) /// ``` - #[unstable(feature = "buf_read_has_data_left", reason = "recently added", issue = "86423")] + #[unstable(feature = "buf_read_has_data_left", issue = "86423")] fn has_data_left(&mut self) -> Result { self.fill_buf().map(|b| !b.is_empty()) } diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs index 708ebaec362e..18b0f70c0687 100644 --- a/library/std/src/os/unix/io/mod.rs +++ b/library/std/src/os/unix/io/mod.rs @@ -102,7 +102,7 @@ use crate::sys::cvt; #[cfg(test)] mod tests; -#[unstable(feature = "stdio_swap", issue = "150667", reason = "recently added")] +#[unstable(feature = "stdio_swap", issue = "150667")] pub trait StdioExt: crate::sealed::Sealed { /// Redirects the stdio file descriptor to point to the file description underpinning `fd`. /// @@ -159,7 +159,7 @@ pub trait StdioExt: crate::sealed::Sealed { } macro io_ext_impl($stdio_ty:ty, $stdio_lock_ty:ty, $writer:literal) { - #[unstable(feature = "stdio_swap", issue = "150667", reason = "recently added")] + #[unstable(feature = "stdio_swap", issue = "150667")] impl StdioExt for $stdio_ty { fn set_fd>(&mut self, fd: T) -> io::Result<()> { self.lock().set_fd(fd) @@ -174,7 +174,7 @@ macro io_ext_impl($stdio_ty:ty, $stdio_lock_ty:ty, $writer:literal) { } } - #[unstable(feature = "stdio_swap", issue = "150667", reason = "recently added")] + #[unstable(feature = "stdio_swap", issue = "150667")] impl StdioExt for $stdio_lock_ty { fn set_fd>(&mut self, fd: T) -> io::Result<()> { #[cfg($writer)] From 69da4016aaa085c185aa7f6251555ac226d35f51 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 16 Jan 2026 13:34:34 +0000 Subject: [PATCH 2211/3801] remove `reason = "new API"` from `#[unstable(...)]` --- library/alloc/src/boxed.rs | 8 ++++---- library/alloc/src/collections/mod.rs | 2 +- library/alloc/src/string.rs | 2 +- library/alloc/src/vec/mod.rs | 14 +++++++------- library/core/src/iter/traits/iterator.rs | 10 +++++----- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 60758551cc04..de9c92db11d3 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1313,7 +1313,7 @@ impl Box { /// ``` /// /// [memory layout]: self#memory-layout - #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] + #[unstable(feature = "box_vec_non_null", issue = "130364")] #[inline] #[must_use = "call `drop(Box::from_non_null(ptr))` if you intend to drop the `Box`"] pub unsafe fn from_non_null(ptr: NonNull) -> Self { @@ -1431,7 +1431,7 @@ impl Box { /// /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] - #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] + #[unstable(feature = "box_vec_non_null", issue = "130364")] #[inline] pub fn into_non_null(b: Self) -> NonNull { // SAFETY: `Box` is guaranteed to be non-null. @@ -1540,7 +1540,7 @@ impl Box { /// /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] + // #[unstable(feature = "box_vec_non_null", issue = "130364")] #[inline] pub unsafe fn from_non_null_in(raw: NonNull, alloc: A) -> Self { // SAFETY: guaranteed by the caller. @@ -1655,7 +1655,7 @@ impl Box { /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] + // #[unstable(feature = "box_vec_non_null", issue = "130364")] #[inline] pub fn into_non_null_with_allocator(b: Self) -> (NonNull, A) { let (ptr, alloc) = Box::into_raw_with_allocator(b); diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs index e09326759fd1..d306d2016ea2 100644 --- a/library/alloc/src/collections/mod.rs +++ b/library/alloc/src/collections/mod.rs @@ -156,7 +156,7 @@ impl const From for TryReserveError { } } -#[unstable(feature = "try_reserve_kind", reason = "new API", issue = "48043")] +#[unstable(feature = "try_reserve_kind", issue = "48043")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] #[cfg(not(test))] impl const From for TryReserveErrorKind { diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 1e7f4f208a7f..4100ee55a4c7 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1563,7 +1563,7 @@ impl String { /// assert_eq!("bna", s); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "string_remove_matches", reason = "new API", issue = "72826")] + #[unstable(feature = "string_remove_matches", issue = "72826")] pub fn remove_matches(&mut self, pat: P) { use core::str::pattern::Searcher; diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 379e964f0a0c..93432f3e049e 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -743,7 +743,7 @@ impl Vec { /// } /// ``` #[inline] - #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] + #[unstable(feature = "box_vec_non_null", issue = "130364")] pub unsafe fn from_parts(ptr: NonNull, length: usize, capacity: usize) -> Self { unsafe { Self::from_parts_in(ptr, length, capacity, Global) } } @@ -793,7 +793,7 @@ impl Vec { /// ``` #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "vec_from_fn", reason = "new API", issue = "149698")] + #[unstable(feature = "vec_from_fn", issue = "149698")] pub fn from_fn(length: usize, f: F) -> Self where F: FnMut(usize) -> T, @@ -878,7 +878,7 @@ impl Vec { /// assert_eq!(rebuilt, [4294967295, 0, 1]); /// ``` #[must_use = "losing the pointer will leak memory"] - #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] + #[unstable(feature = "box_vec_non_null", issue = "130364")] pub fn into_parts(self) -> (NonNull, usize, usize) { let (ptr, len, capacity) = self.into_raw_parts(); // SAFETY: A `Vec` always has a non-null pointer. @@ -1291,7 +1291,7 @@ impl Vec { /// } /// ``` #[inline] - #[unstable(feature = "allocator_api", reason = "new API", issue = "32838")] + #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "box_vec_non_null", issue = "130364")] pub unsafe fn from_parts_in(ptr: NonNull, length: usize, capacity: usize, alloc: A) -> Self { ub_checks::assert_unsafe_precondition!( @@ -1390,7 +1390,7 @@ impl Vec { /// ``` #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] + // #[unstable(feature = "box_vec_non_null", issue = "130364")] pub fn into_parts_with_alloc(self) -> (NonNull, usize, usize, A) { let (ptr, len, capacity, alloc) = self.into_raw_parts_with_alloc(); // SAFETY: A `Vec` always has a non-null pointer. @@ -1994,8 +1994,8 @@ impl Vec { /// [`as_mut_ptr`]: Vec::as_mut_ptr /// [`as_ptr`]: Vec::as_ptr /// [`as_non_null`]: Vec::as_non_null - #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] - #[rustc_const_unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] + #[unstable(feature = "box_vec_non_null", issue = "130364")] + #[rustc_const_unstable(feature = "box_vec_non_null", issue = "130364")] #[inline] pub const fn as_non_null(&mut self) -> NonNull { self.buf.non_null() diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 81901fc011be..dc484e2a27f6 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2177,7 +2177,7 @@ pub trait Iterator { /// assert_eq!(vec, vec![1, 2, 3, 1, 2, 3]); /// ``` #[inline] - #[unstable(feature = "iter_collect_into", reason = "new API", issue = "94780")] + #[unstable(feature = "iter_collect_into", issue = "94780")] fn collect_into>(self, collection: &mut E) -> &mut E where Self: Sized, @@ -2271,7 +2271,7 @@ pub trait Iterator { /// assert!(a[..i].iter().all(|n| n % 2 == 0)); // evens /// assert!(a[i..].iter().all(|n| n % 2 == 1)); // odds /// ``` - #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")] + #[unstable(feature = "iter_partition_in_place", issue = "62543")] fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize where Self: Sized + DoubleEndedIterator, @@ -2328,7 +2328,7 @@ pub trait Iterator { /// assert!("Iterator".chars().is_partitioned(char::is_uppercase)); /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase)); /// ``` - #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "62544")] + #[unstable(feature = "iter_is_partitioned", issue = "62544")] fn is_partitioned

    (mut self, mut predicate: P) -> bool where Self: Sized, @@ -2707,7 +2707,7 @@ pub trait Iterator { /// assert_eq!(max, Ok(Some("5"))); /// ``` #[inline] - #[unstable(feature = "iterator_try_reduce", reason = "new API", issue = "87053")] + #[unstable(feature = "iterator_try_reduce", issue = "87053")] fn try_reduce( &mut self, f: impl FnMut(Self::Item, Self::Item) -> R, @@ -2980,7 +2980,7 @@ pub trait Iterator { /// assert_eq!(result, None); /// ``` #[inline] - #[unstable(feature = "try_find", reason = "new API", issue = "63178")] + #[unstable(feature = "try_find", issue = "63178")] fn try_find( &mut self, f: impl FnMut(&Self::Item) -> R, From 8cb5da3aadbc086fc464d06dc5bd0b5db80d8eb6 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 16 Jan 2026 13:35:40 +0000 Subject: [PATCH 2212/3801] remove `reason = "recently redesigned"` from `#[unstable(...)]` --- library/core/src/iter/range.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 9e43d5688cec..9d4015ac8c37 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -254,7 +254,7 @@ macro_rules! step_integer_impls { } => { $( #[allow(unreachable_patterns)] - #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] + #[unstable(feature = "step_trait", issue = "42168")] impl Step for $u_narrower { step_identical_methods!(); step_unsigned_methods!(); @@ -288,7 +288,7 @@ macro_rules! step_integer_impls { } #[allow(unreachable_patterns)] - #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] + #[unstable(feature = "step_trait", issue = "42168")] impl Step for $i_narrower { step_identical_methods!(); step_signed_methods!($u_narrower); @@ -354,7 +354,7 @@ macro_rules! step_integer_impls { $( #[allow(unreachable_patterns)] - #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] + #[unstable(feature = "step_trait", issue = "42168")] impl Step for $u_wider { step_identical_methods!(); step_unsigned_methods!(); @@ -384,7 +384,7 @@ macro_rules! step_integer_impls { } #[allow(unreachable_patterns)] - #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] + #[unstable(feature = "step_trait", issue = "42168")] impl Step for $i_wider { step_identical_methods!(); step_signed_methods!($u_wider); @@ -441,7 +441,7 @@ step_integer_impls! { wider than usize: [u32 i32], [u64 i64], [u128 i128]; } -#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] +#[unstable(feature = "step_trait", issue = "42168")] impl Step for char { #[inline] fn steps_between(&start: &char, &end: &char) -> (usize, Option) { @@ -528,7 +528,7 @@ impl Step for char { } } -#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] +#[unstable(feature = "step_trait", issue = "42168")] impl Step for AsciiChar { #[inline] fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option) { @@ -570,7 +570,7 @@ impl Step for AsciiChar { } } -#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] +#[unstable(feature = "step_trait", issue = "42168")] impl Step for Ipv4Addr { #[inline] fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> (usize, Option) { @@ -602,7 +602,7 @@ impl Step for Ipv4Addr { } } -#[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] +#[unstable(feature = "step_trait", issue = "42168")] impl Step for Ipv6Addr { #[inline] fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option) { From 2f3b9ce72c700766ad7e331b698afb38fd04f9b6 Mon Sep 17 00:00:00 2001 From: Dima Khort Date: Wed, 14 Jan 2026 00:31:54 +0100 Subject: [PATCH 2213/3801] feat(strlen_on_c_strings): suggest .count_bytes() --- clippy_lints/src/lib.rs | 2 +- clippy_lints/src/strlen_on_c_strings.rs | 31 +++++++++++++---- clippy_utils/src/msrvs.rs | 2 +- tests/ui/strlen_on_c_strings.fixed | 42 ++++++++++++++++------ tests/ui/strlen_on_c_strings.rs | 22 ++++++++++++ tests/ui/strlen_on_c_strings.stderr | 46 +++++++++++++++++++------ 6 files changed, 116 insertions(+), 29 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index ef2461f8b097..bd9db80d98ad 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -718,7 +718,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(|_| Box::::default()), Box::new(move |tcx| Box::new(disallowed_types::DisallowedTypes::new(tcx, conf))), Box::new(move |tcx| Box::new(missing_enforced_import_rename::ImportRename::new(tcx, conf))), - Box::new(|_| Box::new(strlen_on_c_strings::StrlenOnCStrings)), + Box::new(move |_| Box::new(strlen_on_c_strings::StrlenOnCStrings::new(conf))), Box::new(move |_| Box::new(self_named_constructors::SelfNamedConstructors)), Box::new(move |_| Box::new(iter_not_returning_iterator::IterNotReturningIterator)), Box::new(move |_| Box::new(manual_assert::ManualAssert)), diff --git a/clippy_lints/src/strlen_on_c_strings.rs b/clippy_lints/src/strlen_on_c_strings.rs index 5eb160720c52..962ab9cce14c 100644 --- a/clippy_lints/src/strlen_on_c_strings.rs +++ b/clippy_lints/src/strlen_on_c_strings.rs @@ -1,4 +1,6 @@ +use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeDef; use clippy_utils::source::snippet_with_context; use clippy_utils::visitors::is_expr_unsafe; @@ -6,12 +8,12 @@ use clippy_utils::{match_libc_symbol, sym}; use rustc_errors::Applicability; use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, LangItem, Node, UnsafeSource}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::declare_lint_pass; +use rustc_session::impl_lint_pass; declare_clippy_lint! { /// ### What it does /// Checks for usage of `libc::strlen` on a `CString` or `CStr` value, - /// and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead. + /// and suggest calling `count_bytes()` instead. /// /// ### Why is this bad? /// libc::strlen is an unsafe function, which we don't need to call @@ -27,15 +29,25 @@ declare_clippy_lint! { /// ```rust, no_run /// use std::ffi::CString; /// let cstring = CString::new("foo").expect("CString::new failed"); - /// let len = cstring.as_bytes().len(); + /// let len = cstring.count_bytes(); /// ``` #[clippy::version = "1.55.0"] pub STRLEN_ON_C_STRINGS, complexity, - "using `libc::strlen` on a `CString` or `CStr` value, while `as_bytes().len()` or `to_bytes().len()` respectively can be used instead" + "using `libc::strlen` on a `CString` or `CStr` value, while `count_bytes()` can be used instead" } -declare_lint_pass!(StrlenOnCStrings => [STRLEN_ON_C_STRINGS]); +pub struct StrlenOnCStrings { + msrv: Msrv, +} + +impl StrlenOnCStrings { + pub fn new(conf: &Conf) -> Self { + Self { msrv: conf.msrv } + } +} + +impl_lint_pass!(StrlenOnCStrings => [STRLEN_ON_C_STRINGS]); impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { @@ -80,7 +92,14 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings { |diag| { let mut app = Applicability::MachineApplicable; let val_name = snippet_with_context(cx, self_arg.span, ctxt, "_", &mut app).0; - diag.span_suggestion(span, "use", format!("{val_name}.to_bytes().len()"), app); + + let suggestion = if self.msrv.meets(cx, msrvs::CSTR_COUNT_BYTES) { + format!("{val_name}.count_bytes()") + } else { + format!("{val_name}.to_bytes().len()") + }; + + diag.span_suggestion(span, "use", suggestion, app); }, ); } diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 39a2c2df1f81..18fab6035f28 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -32,7 +32,7 @@ msrv_aliases! { 1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP, SPECIALIZED_TO_STRING_FOR_REFS } 1,81,0 { LINT_REASONS_STABILIZATION, ERROR_IN_CORE, EXPLICIT_SELF_TYPE_ELISION, DURATION_ABS_DIFF } 1,80,0 { BOX_INTO_ITER, LAZY_CELL } - 1,79,0 { CONST_BLOCKS } + 1,79,0 { CONST_BLOCKS, CSTR_COUNT_BYTES } 1,77,0 { C_STR_LITERALS } 1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT } 1,75,0 { OPTION_AS_SLICE } diff --git a/tests/ui/strlen_on_c_strings.fixed b/tests/ui/strlen_on_c_strings.fixed index 33a328af6df4..6604da70874d 100644 --- a/tests/ui/strlen_on_c_strings.fixed +++ b/tests/ui/strlen_on_c_strings.fixed @@ -7,40 +7,62 @@ use std::ffi::{CStr, CString}; fn main() { // CString let cstring = CString::new("foo").expect("CString::new failed"); - let _ = cstring.to_bytes().len(); + let _ = cstring.count_bytes(); //~^ ERROR: using `libc::strlen` on a `CString` value // CStr let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); - let _ = cstr.to_bytes().len(); + let _ = cstr.count_bytes(); //~^ ERROR: using `libc::strlen` on a `CStr` value - let _ = cstr.to_bytes().len(); + let _ = cstr.count_bytes(); //~^ ERROR: using `libc::strlen` on a `CStr` value let pcstr: *const &CStr = &cstr; - let _ = unsafe { (*pcstr).to_bytes().len() }; + let _ = unsafe { (*pcstr).count_bytes() }; //~^ ERROR: using `libc::strlen` on a `CStr` value unsafe fn unsafe_identity(x: T) -> T { x } - let _ = unsafe { unsafe_identity(cstr).to_bytes().len() }; + let _ = unsafe { unsafe_identity(cstr).count_bytes() }; //~^ ERROR: using `libc::strlen` on a `CStr` value - let _ = unsafe { unsafe_identity(cstr) }.to_bytes().len(); + let _ = unsafe { unsafe_identity(cstr) }.count_bytes(); //~^ ERROR: using `libc::strlen` on a `CStr` value let f: unsafe fn(_) -> _ = unsafe_identity; - let _ = unsafe { f(cstr).to_bytes().len() }; + let _ = unsafe { f(cstr).count_bytes() }; //~^ ERROR: using `libc::strlen` on a `CStr` value } // make sure we lint types that _adjust_ to `CStr` fn adjusted(box_cstring: Box, box_cstr: Box, arc_cstring: std::sync::Arc) { - let _ = box_cstring.to_bytes().len(); + let _ = box_cstring.count_bytes(); //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr` - let _ = box_cstr.to_bytes().len(); + let _ = box_cstr.count_bytes(); //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr` - let _ = arc_cstring.to_bytes().len(); + let _ = arc_cstring.count_bytes(); //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr` } + +#[clippy::msrv = "1.78"] +fn msrv_1_78() { + let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + let _ = cstr.to_bytes().len(); + //~^ strlen_on_c_strings + + let cstring = CString::new("foo").expect("CString::new failed"); + let _ = cstring.to_bytes().len(); + //~^ strlen_on_c_strings +} + +#[clippy::msrv = "1.79"] +fn msrv_1_79() { + let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + let _ = cstr.count_bytes(); + //~^ strlen_on_c_strings + + let cstring = CString::new("foo").expect("CString::new failed"); + let _ = cstring.count_bytes(); + //~^ strlen_on_c_strings +} diff --git a/tests/ui/strlen_on_c_strings.rs b/tests/ui/strlen_on_c_strings.rs index 3c11c3a05269..11fbdf585064 100644 --- a/tests/ui/strlen_on_c_strings.rs +++ b/tests/ui/strlen_on_c_strings.rs @@ -44,3 +44,25 @@ fn adjusted(box_cstring: Box, box_cstr: Box, arc_cstring: std::sy let _ = unsafe { libc::strlen(arc_cstring.as_ptr()) }; //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr` } + +#[clippy::msrv = "1.78"] +fn msrv_1_78() { + let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + let _ = unsafe { libc::strlen(cstr.as_ptr()) }; + //~^ strlen_on_c_strings + + let cstring = CString::new("foo").expect("CString::new failed"); + let _ = unsafe { libc::strlen(cstring.as_ptr()) }; + //~^ strlen_on_c_strings +} + +#[clippy::msrv = "1.79"] +fn msrv_1_79() { + let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + let _ = unsafe { libc::strlen(cstr.as_ptr()) }; + //~^ strlen_on_c_strings + + let cstring = CString::new("foo").expect("CString::new failed"); + let _ = unsafe { libc::strlen(cstring.as_ptr()) }; + //~^ strlen_on_c_strings +} diff --git a/tests/ui/strlen_on_c_strings.stderr b/tests/ui/strlen_on_c_strings.stderr index 2b059872a2da..1f1b5ccdb0ef 100644 --- a/tests/ui/strlen_on_c_strings.stderr +++ b/tests/ui/strlen_on_c_strings.stderr @@ -2,7 +2,7 @@ error: using `libc::strlen` on a `CString` value --> tests/ui/strlen_on_c_strings.rs:10:13 | LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.count_bytes()` | = note: `-D clippy::strlen-on-c-strings` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]` @@ -11,55 +11,79 @@ error: using `libc::strlen` on a `CStr` value --> tests/ui/strlen_on_c_strings.rs:15:13 | LL | let _ = unsafe { libc::strlen(cstr.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.count_bytes()` error: using `libc::strlen` on a `CStr` value --> tests/ui/strlen_on_c_strings.rs:18:13 | LL | let _ = unsafe { strlen(cstr.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.count_bytes()` error: using `libc::strlen` on a `CStr` value --> tests/ui/strlen_on_c_strings.rs:22:22 | LL | let _ = unsafe { strlen((*pcstr).as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `(*pcstr).to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `(*pcstr).count_bytes()` error: using `libc::strlen` on a `CStr` value --> tests/ui/strlen_on_c_strings.rs:28:22 | LL | let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe_identity(cstr).to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe_identity(cstr).count_bytes()` error: using `libc::strlen` on a `CStr` value --> tests/ui/strlen_on_c_strings.rs:30:13 | LL | let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe { unsafe_identity(cstr) }.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe { unsafe_identity(cstr) }.count_bytes()` error: using `libc::strlen` on a `CStr` value --> tests/ui/strlen_on_c_strings.rs:34:22 | LL | let _ = unsafe { strlen(f(cstr).as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `f(cstr).to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `f(cstr).count_bytes()` error: using `libc::strlen` on a type that dereferences to `CStr` --> tests/ui/strlen_on_c_strings.rs:40:13 | LL | let _ = unsafe { libc::strlen(box_cstring.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `box_cstring.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `box_cstring.count_bytes()` error: using `libc::strlen` on a type that dereferences to `CStr` --> tests/ui/strlen_on_c_strings.rs:42:13 | LL | let _ = unsafe { libc::strlen(box_cstr.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `box_cstr.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `box_cstr.count_bytes()` error: using `libc::strlen` on a type that dereferences to `CStr` --> tests/ui/strlen_on_c_strings.rs:44:13 | LL | let _ = unsafe { libc::strlen(arc_cstring.as_ptr()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `arc_cstring.to_bytes().len()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `arc_cstring.count_bytes()` -error: aborting due to 10 previous errors +error: using `libc::strlen` on a `CStr` value + --> tests/ui/strlen_on_c_strings.rs:51:13 + | +LL | let _ = unsafe { libc::strlen(cstr.as_ptr()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()` + +error: using `libc::strlen` on a `CString` value + --> tests/ui/strlen_on_c_strings.rs:55:13 + | +LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.to_bytes().len()` + +error: using `libc::strlen` on a `CStr` value + --> tests/ui/strlen_on_c_strings.rs:62:13 + | +LL | let _ = unsafe { libc::strlen(cstr.as_ptr()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.count_bytes()` + +error: using `libc::strlen` on a `CString` value + --> tests/ui/strlen_on_c_strings.rs:66:13 + | +LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.count_bytes()` + +error: aborting due to 14 previous errors From 7d3bf37c4ddacf866129c90b58e0a4e7728368f2 Mon Sep 17 00:00:00 2001 From: Daedalus <16168171+RedDaedalus@users.noreply.github.com> Date: Mon, 12 Jan 2026 19:02:03 -0700 Subject: [PATCH 2214/3801] fix fallback impl for select_unpredictable intrinsic --- library/core/src/intrinsics/mod.rs | 15 +++++++++------ .../intrinsics/select-unpredictable-drop.rs | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 20f34036b25c..ac3456eb904e 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -55,7 +55,7 @@ #![allow(missing_docs)] use crate::ffi::va_list::{VaArgSafe, VaList}; -use crate::marker::{ConstParamTy, Destruct, DiscriminantKind, PointeeSized, Tuple}; +use crate::marker::{ConstParamTy, DiscriminantKind, PointeeSized, Tuple}; use crate::{mem, ptr}; mod bounds; @@ -482,11 +482,14 @@ pub const fn unlikely(b: bool) -> bool { #[rustc_nounwind] #[miri::intrinsic_fallback_is_spec] #[inline] -pub const fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T -where - T: [const] Destruct, -{ - if b { true_val } else { false_val } +pub const fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T { + if b { + forget(false_val); + true_val + } else { + forget(true_val); + false_val + } } /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited: diff --git a/src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs b/src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs new file mode 100644 index 000000000000..ecf9f4b92058 --- /dev/null +++ b/src/tools/miri/tests/pass/intrinsics/select-unpredictable-drop.rs @@ -0,0 +1,19 @@ +//! Check that `select_unpredictable` properly forgets the value it does not select. +#![feature(core_intrinsics)] +use std::cell::Cell; +use std::intrinsics::select_unpredictable; + +fn main() { + let (true_val, false_val) = (Cell::new(false), Cell::new(false)); + _ = select_unpredictable(true, TraceDrop(&true_val), TraceDrop(&false_val)); + assert!(true_val.get()); + assert!(!false_val.get()); +} + +struct TraceDrop<'a>(&'a Cell); + +impl<'a> Drop for TraceDrop<'a> { + fn drop(&mut self) { + self.0.set(true); + } +} From 41daada3bbc5d5fb10119218c3b737854a27ce61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 16 Jan 2026 09:23:00 +0100 Subject: [PATCH 2215/3801] Ship LLVM (`rust-dev`) in fast try builds again --- src/tools/opt-dist/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index b52dab001ef5..cdbeee63d6c2 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -442,11 +442,12 @@ fn main() -> anyhow::Result<()> { // Skip components that are not needed for fast try builds to speed them up if is_fast_try_build() { log::info!("Skipping building of unimportant components for a fast try build"); + // Note for future onlookers: do not ignore rust-dev here. We need it for try builds when + // a PR makes a change to how LLVM is built. for target in [ "rust-docs", "rustc-docs", "rustc-dev", - "rust-dev", "rust-docs-json", "rust-analyzer", "rustc-src", From 035bcfa46d2892f873b59f9981999bb17f2df4a7 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 16 Jan 2026 13:54:40 +0000 Subject: [PATCH 2216/3801] remove `reason = "unstable"` from `#[unstable(...)]` --- library/std/src/os/unix/net/mod.rs | 2 +- library/std/src/os/unix/net/stream.rs | 2 +- library/std/src/os/unix/net/ucred.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs index 94523d7d1e45..a44b23a77d2d 100644 --- a/library/std/src/os/unix/net/mod.rs +++ b/library/std/src/os/unix/net/mod.rs @@ -47,5 +47,5 @@ pub use self::stream::*; target_vendor = "apple", target_os = "cygwin", ))] -#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] +#[unstable(feature = "peer_credentials_unix_socket", issue = "42839")] pub use self::ucred::*; diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index c0a8045884a5..30124d96951e 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -251,7 +251,7 @@ impl UnixStream { /// Ok(()) /// } /// ``` - #[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] + #[unstable(feature = "peer_credentials_unix_socket", issue = "42839")] #[cfg(any( target_os = "android", target_os = "linux", diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs index 36fb9c46b4ab..1395d2ef4be3 100644 --- a/library/std/src/os/unix/net/ucred.rs +++ b/library/std/src/os/unix/net/ucred.rs @@ -7,7 +7,7 @@ use libc::{gid_t, pid_t, uid_t}; /// Credentials for a UNIX process for credentials passing. -#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] +#[unstable(feature = "peer_credentials_unix_socket", issue = "42839")] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct UCred { /// The UID part of the peer credential. This is the effective UID of the process at the domain From 1f691f7dbd8fce50a265d43baf004d7bf2247828 Mon Sep 17 00:00:00 2001 From: Alex Celeste Date: Fri, 16 Jan 2026 12:34:51 +0000 Subject: [PATCH 2217/3801] Add missing closing brackets to THIR output. Closing brackets were missing on AdtDef, the field_types list in FruInfo, and InlineAsmExpr, breaking folding in some editors; Fields were incorrectly (?) indexed in the list for functional update syntax, showing the (implicit, irrelevant) iteration index instead of the field index; also spurious colon after Pat. --- compiler/rustc_mir_build/src/thir/print.rs | 10 +- tests/ui/thir-print/c-variadic.stdout | 4 +- tests/ui/thir-print/offset_of.stdout | 18 +- .../thir-print/thir-tree-field-expr-index.rs | 25 + .../thir-tree-field-expr-index.stdout | 921 ++++++++++++++++++ .../ui/thir-print/thir-tree-loop-match.stdout | 6 +- tests/ui/thir-print/thir-tree-match.stdout | 16 +- tests/ui/unpretty/box.stdout | 2 +- 8 files changed, 978 insertions(+), 24 deletions(-) create mode 100644 tests/ui/thir-print/thir-tree-field-expr-index.rs create mode 100644 tests/ui/thir-print/thir-tree-field-expr-index.stdout diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 2cafb73a74a4..a87257fa79bf 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -618,8 +618,8 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, format!("args: {:?}", adt_expr.args), depth_lvl + 1); print_indented!(self, format!("user_ty: {:?}", adt_expr.user_ty), depth_lvl + 1); - for (i, field_expr) in adt_expr.fields.iter().enumerate() { - print_indented!(self, format!("field {}:", i), depth_lvl + 1); + for field_expr in adt_expr.fields.iter() { + print_indented!(self, format!("field {}:", field_expr.name.as_u32()), depth_lvl + 1); self.print_expr(field_expr.expr, depth_lvl + 2); } @@ -643,6 +643,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, format!("variants: {:?}", adt_def.variants()), depth_lvl + 1); print_indented!(self, format!("flags: {:?}", adt_def.flags()), depth_lvl + 1); print_indented!(self, format!("repr: {:?}", adt_def.repr()), depth_lvl + 1); + print_indented!(self, "}", depth_lvl); } fn print_fru_info(&mut self, fru_info: &FruInfo<'tcx>, depth_lvl: usize) { @@ -653,6 +654,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { for ty in fru_info.field_types.iter() { print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 2); } + print_indented!(self, "]", depth_lvl + 1); print_indented!(self, "}", depth_lvl); } @@ -683,7 +685,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { fn print_pat(&mut self, pat: &Pat<'tcx>, depth_lvl: usize) { let &Pat { ty, span, ref kind, ref extra } = pat; - print_indented!(self, "Pat: {", depth_lvl); + print_indented!(self, "Pat {", depth_lvl); print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1); print_indented!(self, format!("span: {:?}", span), depth_lvl + 1); self.print_pat_extra(extra.as_deref(), depth_lvl + 1); @@ -913,6 +915,8 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, format!("options: {:?}", options), depth_lvl + 1); print_indented!(self, format!("line_spans: {:?}", line_spans), depth_lvl + 1); + + print_indented!(self, "}", depth_lvl); } fn print_inline_operand(&mut self, operand: &InlineAsmOperand<'tcx>, depth_lvl: usize) { diff --git a/tests/ui/thir-print/c-variadic.stdout b/tests/ui/thir-print/c-variadic.stdout index a3e3fa5e0008..a426902b2deb 100644 --- a/tests/ui/thir-print/c-variadic.stdout +++ b/tests/ui/thir-print/c-variadic.stdout @@ -6,7 +6,7 @@ params: [ self_kind: None hir_id: Some(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).1)) param: Some( - Pat: { + Pat { ty: i32 span: $DIR/c-variadic.rs:7:26: 7:27 (#0) kind: PatKind { @@ -21,7 +21,7 @@ params: [ self_kind: None hir_id: Some(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).3)) param: Some( - Pat: { + Pat { ty: std::ffi::VaList<'{erased}> span: $DIR/c-variadic.rs:7:34: 7:37 (#0) kind: PatKind { diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index 29399bb98e32..b3791a2446cb 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -27,7 +27,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 0} init_scope: Node(2) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:37:9: 37:10 (#0) kind: PatKind { @@ -76,7 +76,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 1} init_scope: Node(12) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:38:9: 38:10 (#0) kind: PatKind { @@ -125,7 +125,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 2} init_scope: Node(22) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:39:9: 39:10 (#0) kind: PatKind { @@ -174,7 +174,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 3} init_scope: Node(32) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:40:9: 40:11 (#0) kind: PatKind { @@ -223,7 +223,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 4} init_scope: Node(42) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:41:9: 41:11 (#0) kind: PatKind { @@ -823,7 +823,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 0} init_scope: Node(2) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:45:9: 45:11 (#0) kind: PatKind { @@ -872,7 +872,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 1} init_scope: Node(14) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:46:9: 46:11 (#0) kind: PatKind { @@ -921,7 +921,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 2} init_scope: Node(26) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:47:9: 47:11 (#0) kind: PatKind { @@ -970,7 +970,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 3} init_scope: Node(38) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:48:9: 48:11 (#0) kind: PatKind { diff --git a/tests/ui/thir-print/thir-tree-field-expr-index.rs b/tests/ui/thir-print/thir-tree-field-expr-index.rs new file mode 100644 index 000000000000..399b78528289 --- /dev/null +++ b/tests/ui/thir-print/thir-tree-field-expr-index.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ compile-flags: -Zunpretty=thir-tree + +struct S { + a: u32, + b: u32, + c: u32, + d: u32, + e: u32, +} + +fn update(x: u32) { + let s = S { a: x, b: x, c: x, d: x, e: x }; + + S { a: x , ..s }; + S { b: x , ..s }; + S { c: x , ..s }; + S { d: x , ..s }; + S { e: x , ..s }; + + S { b: x, d: x, ..s }; + S { a: x, c: x, e: x, ..s }; +} + +fn main() {} diff --git a/tests/ui/thir-print/thir-tree-field-expr-index.stdout b/tests/ui/thir-print/thir-tree-field-expr-index.stdout new file mode 100644 index 000000000000..5bf97a185290 --- /dev/null +++ b/tests/ui/thir-print/thir-tree-field-expr-index.stdout @@ -0,0 +1,921 @@ +DefId(0:9 ~ thir_tree_field_expr_index[5059]::update): +params: [ + Param { + ty: u32 + ty_span: Some($DIR/thir-tree-field-expr-index.rs:12:14: 12:17 (#0)) + self_kind: None + hir_id: Some(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).1)) + param: Some( + Pat { + ty: u32 + span: $DIR/thir-tree-field-expr-index.rs:12:11: 12:12 (#0) + kind: PatKind { + Binding { + name: "x" + mode: BindingMode(No, Not) + var: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + ty: u32 + is_primary: true + is_shorthand: false + subpattern: None + } + } + } + ) + } +] +body: + Expr { + ty: () + temp_scope_id: 89 + span: $DIR/thir-tree-field-expr-index.rs:12:19: 23:2 (#0) + kind: + Scope { + region_scope: Node(89) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).89) + value: + Expr { + ty: () + temp_scope_id: 89 + span: $DIR/thir-tree-field-expr-index.rs:12:19: 23:2 (#0) + kind: + Block { + targeted_by_break: false + span: $DIR/thir-tree-field-expr-index.rs:12:19: 23:2 (#0) + region_scope: Node(3) + safety_mode: Safe + stmts: [ + Stmt { + kind: Let { + remainder_scope: Remainder { block: 3, first_statement_index: 0} + init_scope: Node(4) + pattern: + Pat { + ty: S + span: $DIR/thir-tree-field-expr-index.rs:13:7: 13:8 (#0) + kind: PatKind { + Binding { + name: "s" + mode: BindingMode(No, Not) + var: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + ty: S + is_primary: true + is_shorthand: false + subpattern: None + } + } + } + , + initializer: Some( + Expr { + ty: S + temp_scope_id: 5 + span: $DIR/thir-tree-field-expr-index.rs:13:11: 13:45 (#0) + kind: + Scope { + region_scope: Node(5) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).5) + value: + Expr { + ty: S + temp_scope_id: 5 + span: $DIR/thir-tree-field-expr-index.rs:13:11: 13:45 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 0: + Expr { + ty: u32 + temp_scope_id: 8 + span: $DIR/thir-tree-field-expr-index.rs:13:18: 13:19 (#0) + kind: + Scope { + region_scope: Node(8) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).8) + value: + Expr { + ty: u32 + temp_scope_id: 8 + span: $DIR/thir-tree-field-expr-index.rs:13:18: 13:19 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 1: + Expr { + ty: u32 + temp_scope_id: 11 + span: $DIR/thir-tree-field-expr-index.rs:13:24: 13:25 (#0) + kind: + Scope { + region_scope: Node(11) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).11) + value: + Expr { + ty: u32 + temp_scope_id: 11 + span: $DIR/thir-tree-field-expr-index.rs:13:24: 13:25 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 2: + Expr { + ty: u32 + temp_scope_id: 14 + span: $DIR/thir-tree-field-expr-index.rs:13:30: 13:31 (#0) + kind: + Scope { + region_scope: Node(14) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).14) + value: + Expr { + ty: u32 + temp_scope_id: 14 + span: $DIR/thir-tree-field-expr-index.rs:13:30: 13:31 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 3: + Expr { + ty: u32 + temp_scope_id: 17 + span: $DIR/thir-tree-field-expr-index.rs:13:36: 13:37 (#0) + kind: + Scope { + region_scope: Node(17) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).17) + value: + Expr { + ty: u32 + temp_scope_id: 17 + span: $DIR/thir-tree-field-expr-index.rs:13:36: 13:37 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 4: + Expr { + ty: u32 + temp_scope_id: 20 + span: $DIR/thir-tree-field-expr-index.rs:13:42: 13:43 (#0) + kind: + Scope { + region_scope: Node(20) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).20) + value: + Expr { + ty: u32 + temp_scope_id: 20 + span: $DIR/thir-tree-field-expr-index.rs:13:42: 13:43 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: None + } + } + } + } + ) + else_block: None + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).22) + span: $DIR/thir-tree-field-expr-index.rs:13:3: 13:45 (#0) + } + } + Stmt { + kind: Expr { + scope: Node(31) + expr: + Expr { + ty: S + temp_scope_id: 24 + span: $DIR/thir-tree-field-expr-index.rs:15:3: 15:19 (#0) + kind: + Scope { + region_scope: Node(24) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).24) + value: + Expr { + ty: S + temp_scope_id: 24 + span: $DIR/thir-tree-field-expr-index.rs:15:3: 15:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 0: + Expr { + ty: u32 + temp_scope_id: 29 + span: $DIR/thir-tree-field-expr-index.rs:15:10: 15:11 (#0) + kind: + Scope { + region_scope: Node(29) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).29) + value: + Expr { + ty: u32 + temp_scope_id: 29 + span: $DIR/thir-tree-field-expr-index.rs:15:10: 15:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 25 + span: $DIR/thir-tree-field-expr-index.rs:15:16: 15:17 (#0) + kind: + Scope { + region_scope: Node(25) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).25) + value: + Expr { + ty: S + temp_scope_id: 25 + span: $DIR/thir-tree-field-expr-index.rs:15:16: 15:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(39) + expr: + Expr { + ty: S + temp_scope_id: 32 + span: $DIR/thir-tree-field-expr-index.rs:16:3: 16:19 (#0) + kind: + Scope { + region_scope: Node(32) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).32) + value: + Expr { + ty: S + temp_scope_id: 32 + span: $DIR/thir-tree-field-expr-index.rs:16:3: 16:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 1: + Expr { + ty: u32 + temp_scope_id: 37 + span: $DIR/thir-tree-field-expr-index.rs:16:10: 16:11 (#0) + kind: + Scope { + region_scope: Node(37) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).37) + value: + Expr { + ty: u32 + temp_scope_id: 37 + span: $DIR/thir-tree-field-expr-index.rs:16:10: 16:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 33 + span: $DIR/thir-tree-field-expr-index.rs:16:16: 16:17 (#0) + kind: + Scope { + region_scope: Node(33) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).33) + value: + Expr { + ty: S + temp_scope_id: 33 + span: $DIR/thir-tree-field-expr-index.rs:16:16: 16:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(47) + expr: + Expr { + ty: S + temp_scope_id: 40 + span: $DIR/thir-tree-field-expr-index.rs:17:3: 17:19 (#0) + kind: + Scope { + region_scope: Node(40) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).40) + value: + Expr { + ty: S + temp_scope_id: 40 + span: $DIR/thir-tree-field-expr-index.rs:17:3: 17:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 2: + Expr { + ty: u32 + temp_scope_id: 45 + span: $DIR/thir-tree-field-expr-index.rs:17:10: 17:11 (#0) + kind: + Scope { + region_scope: Node(45) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).45) + value: + Expr { + ty: u32 + temp_scope_id: 45 + span: $DIR/thir-tree-field-expr-index.rs:17:10: 17:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 41 + span: $DIR/thir-tree-field-expr-index.rs:17:16: 17:17 (#0) + kind: + Scope { + region_scope: Node(41) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).41) + value: + Expr { + ty: S + temp_scope_id: 41 + span: $DIR/thir-tree-field-expr-index.rs:17:16: 17:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(55) + expr: + Expr { + ty: S + temp_scope_id: 48 + span: $DIR/thir-tree-field-expr-index.rs:18:3: 18:19 (#0) + kind: + Scope { + region_scope: Node(48) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).48) + value: + Expr { + ty: S + temp_scope_id: 48 + span: $DIR/thir-tree-field-expr-index.rs:18:3: 18:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 3: + Expr { + ty: u32 + temp_scope_id: 53 + span: $DIR/thir-tree-field-expr-index.rs:18:10: 18:11 (#0) + kind: + Scope { + region_scope: Node(53) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).53) + value: + Expr { + ty: u32 + temp_scope_id: 53 + span: $DIR/thir-tree-field-expr-index.rs:18:10: 18:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 49 + span: $DIR/thir-tree-field-expr-index.rs:18:16: 18:17 (#0) + kind: + Scope { + region_scope: Node(49) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).49) + value: + Expr { + ty: S + temp_scope_id: 49 + span: $DIR/thir-tree-field-expr-index.rs:18:16: 18:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(63) + expr: + Expr { + ty: S + temp_scope_id: 56 + span: $DIR/thir-tree-field-expr-index.rs:19:3: 19:19 (#0) + kind: + Scope { + region_scope: Node(56) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).56) + value: + Expr { + ty: S + temp_scope_id: 56 + span: $DIR/thir-tree-field-expr-index.rs:19:3: 19:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 4: + Expr { + ty: u32 + temp_scope_id: 61 + span: $DIR/thir-tree-field-expr-index.rs:19:10: 19:11 (#0) + kind: + Scope { + region_scope: Node(61) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).61) + value: + Expr { + ty: u32 + temp_scope_id: 61 + span: $DIR/thir-tree-field-expr-index.rs:19:10: 19:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 57 + span: $DIR/thir-tree-field-expr-index.rs:19:16: 19:17 (#0) + kind: + Scope { + region_scope: Node(57) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).57) + value: + Expr { + ty: S + temp_scope_id: 57 + span: $DIR/thir-tree-field-expr-index.rs:19:16: 19:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(74) + expr: + Expr { + ty: S + temp_scope_id: 64 + span: $DIR/thir-tree-field-expr-index.rs:21:3: 21:24 (#0) + kind: + Scope { + region_scope: Node(64) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).64) + value: + Expr { + ty: S + temp_scope_id: 64 + span: $DIR/thir-tree-field-expr-index.rs:21:3: 21:24 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 1: + Expr { + ty: u32 + temp_scope_id: 69 + span: $DIR/thir-tree-field-expr-index.rs:21:10: 21:11 (#0) + kind: + Scope { + region_scope: Node(69) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).69) + value: + Expr { + ty: u32 + temp_scope_id: 69 + span: $DIR/thir-tree-field-expr-index.rs:21:10: 21:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 3: + Expr { + ty: u32 + temp_scope_id: 72 + span: $DIR/thir-tree-field-expr-index.rs:21:16: 21:17 (#0) + kind: + Scope { + region_scope: Node(72) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).72) + value: + Expr { + ty: u32 + temp_scope_id: 72 + span: $DIR/thir-tree-field-expr-index.rs:21:16: 21:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 65 + span: $DIR/thir-tree-field-expr-index.rs:21:21: 21:22 (#0) + kind: + Scope { + region_scope: Node(65) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).65) + value: + Expr { + ty: S + temp_scope_id: 65 + span: $DIR/thir-tree-field-expr-index.rs:21:21: 21:22 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(88) + expr: + Expr { + ty: S + temp_scope_id: 75 + span: $DIR/thir-tree-field-expr-index.rs:22:3: 22:30 (#0) + kind: + Scope { + region_scope: Node(75) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).75) + value: + Expr { + ty: S + temp_scope_id: 75 + span: $DIR/thir-tree-field-expr-index.rs:22:3: 22:30 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 0: + Expr { + ty: u32 + temp_scope_id: 80 + span: $DIR/thir-tree-field-expr-index.rs:22:10: 22:11 (#0) + kind: + Scope { + region_scope: Node(80) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).80) + value: + Expr { + ty: u32 + temp_scope_id: 80 + span: $DIR/thir-tree-field-expr-index.rs:22:10: 22:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 2: + Expr { + ty: u32 + temp_scope_id: 83 + span: $DIR/thir-tree-field-expr-index.rs:22:16: 22:17 (#0) + kind: + Scope { + region_scope: Node(83) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).83) + value: + Expr { + ty: u32 + temp_scope_id: 83 + span: $DIR/thir-tree-field-expr-index.rs:22:16: 22:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 4: + Expr { + ty: u32 + temp_scope_id: 86 + span: $DIR/thir-tree-field-expr-index.rs:22:22: 22:23 (#0) + kind: + Scope { + region_scope: Node(86) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).86) + value: + Expr { + ty: u32 + temp_scope_id: 86 + span: $DIR/thir-tree-field-expr-index.rs:22:22: 22:23 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 76 + span: $DIR/thir-tree-field-expr-index.rs:22:27: 22:28 (#0) + kind: + Scope { + region_scope: Node(76) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).76) + value: + Expr { + ty: S + temp_scope_id: 76 + span: $DIR/thir-tree-field-expr-index.rs:22:27: 22:28 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + ] + expr: [] + } + } + } + } + + +DefId(0:10 ~ thir_tree_field_expr_index[5059]::main): +params: [ +] +body: + Expr { + ty: () + temp_scope_id: 2 + span: $DIR/thir-tree-field-expr-index.rs:25:11: 25:13 (#0) + kind: + Scope { + region_scope: Node(2) + hir_id: HirId(DefId(0:10 ~ thir_tree_field_expr_index[5059]::main).2) + value: + Expr { + ty: () + temp_scope_id: 2 + span: $DIR/thir-tree-field-expr-index.rs:25:11: 25:13 (#0) + kind: + Block { + targeted_by_break: false + span: $DIR/thir-tree-field-expr-index.rs:25:11: 25:13 (#0) + region_scope: Node(1) + safety_mode: Safe + stmts: [] + expr: [] + } + } + } + } + + diff --git a/tests/ui/thir-print/thir-tree-loop-match.stdout b/tests/ui/thir-print/thir-tree-loop-match.stdout index 4a1b2aaf67f5..1bfd3f0952a3 100644 --- a/tests/ui/thir-print/thir-tree-loop-match.stdout +++ b/tests/ui/thir-print/thir-tree-loop-match.stdout @@ -6,7 +6,7 @@ params: [ self_kind: None hir_id: Some(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).1)) param: Some( - Pat: { + Pat { ty: bool span: $DIR/thir-tree-loop-match.rs:7:12: 7:21 (#0) kind: PatKind { @@ -117,7 +117,7 @@ body: arms: [ Arm { pattern: - Pat: { + Pat { ty: bool span: $DIR/thir-tree-loop-match.rs:12:17: 12:21 (#0) kind: PatKind { @@ -215,7 +215,7 @@ body: } Arm { pattern: - Pat: { + Pat { ty: bool span: $DIR/thir-tree-loop-match.rs:16:17: 16:22 (#0) kind: PatKind { diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index a6d23ee204cb..31f8d368736c 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -6,7 +6,7 @@ params: [ self_kind: None hir_id: Some(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).1)) param: Some( - Pat: { + Pat { ty: Foo span: $DIR/thir-tree-match.rs:15:14: 15:17 (#0) kind: PatKind { @@ -85,7 +85,7 @@ body: arms: [ Arm { pattern: - Pat: { + Pat { ty: Foo span: $DIR/thir-tree-match.rs:17:9: 17:32 (#0) kind: PatKind { @@ -96,10 +96,11 @@ body: variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 13397682652773712997 } + } args: [] variant_index: 0 subpatterns: [ - Pat: { + Pat { ty: Bar span: $DIR/thir-tree-match.rs:17:21: 17:31 (#0) kind: PatKind { @@ -110,6 +111,7 @@ body: variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7908585036048874241 } + } args: [] variant_index: 0 subpatterns: [] @@ -147,7 +149,7 @@ body: } Arm { pattern: - Pat: { + Pat { ty: Foo span: $DIR/thir-tree-match.rs:18:9: 18:23 (#0) kind: PatKind { @@ -158,10 +160,11 @@ body: variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 13397682652773712997 } + } args: [] variant_index: 0 subpatterns: [ - Pat: { + Pat { ty: Bar span: $DIR/thir-tree-match.rs:18:21: 18:22 (#0) kind: PatKind { @@ -199,7 +202,7 @@ body: } Arm { pattern: - Pat: { + Pat { ty: Foo span: $DIR/thir-tree-match.rs:19:9: 19:20 (#0) kind: PatKind { @@ -210,6 +213,7 @@ body: variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 13397682652773712997 } + } args: [] variant_index: 1 subpatterns: [] diff --git a/tests/ui/unpretty/box.stdout b/tests/ui/unpretty/box.stdout index 123273be4efe..2576a2aa125d 100644 --- a/tests/ui/unpretty/box.stdout +++ b/tests/ui/unpretty/box.stdout @@ -27,7 +27,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 0} init_scope: Node(2) pattern: - Pat: { + Pat { ty: std::boxed::Box span: $DIR/box.rs:7:9: 7:10 (#0) kind: PatKind { From 3e789ed57663cac867309eb4d9e1f14094b02900 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Jan 2026 16:38:10 +0100 Subject: [PATCH 2218/3801] Stop cloning old `llvmint` repositories to generate intrinsics --- src/intrinsic/archs.rs | 1424 +--------------------------------- src/intrinsic/llvm.rs | 2 + src/intrinsic/old_archs.rs | 1384 +++++++++++++++++++++++++++++++++ tools/generate_intrinsics.py | 50 +- 4 files changed, 1420 insertions(+), 1440 deletions(-) create mode 100644 src/intrinsic/old_archs.rs diff --git a/src/intrinsic/archs.rs b/src/intrinsic/archs.rs index 43e7c352c34a..89a6cf7f3d6e 100644 --- a/src/intrinsic/archs.rs +++ b/src/intrinsic/archs.rs @@ -6,47 +6,13 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { unimplemented!("***** unsupported LLVM intrinsic {}", full_name) }; let Some((arch, name)) = name.split_once('.') else { - unimplemented!("***** unsupported LLVM intrinsic {}", name) + unimplemented!("***** unsupported LLVM intrinsic llvm.{}", name) }; + let old_arch_res = old_archs(arch, name); + if let ArchCheckResult::Ok(res) = old_arch_res { + return res; + } match arch { - "AMDGPU" => { - #[expect(non_snake_case)] - fn AMDGPU(name: &str, full_name: &str) -> &'static str { - match name { - // AMDGPU - "div.fixup.f32" => "__builtin_amdgpu_div_fixup", - "div.fixup.f64" => "__builtin_amdgpu_div_fixup", - "div.fixup.v2f64" => "__builtin_amdgpu_div_fixup", - "div.fixup.v4f32" => "__builtin_amdgpu_div_fixup", - "div.fmas.f32" => "__builtin_amdgpu_div_fmas", - "div.fmas.f64" => "__builtin_amdgpu_div_fmas", - "div.fmas.v2f64" => "__builtin_amdgpu_div_fmas", - "div.fmas.v4f32" => "__builtin_amdgpu_div_fmas", - "ldexp.f32" => "__builtin_amdgpu_ldexp", - "ldexp.f64" => "__builtin_amdgpu_ldexp", - "ldexp.v2f64" => "__builtin_amdgpu_ldexp", - "ldexp.v4f32" => "__builtin_amdgpu_ldexp", - "rcp.f32" => "__builtin_amdgpu_rcp", - "rcp.f64" => "__builtin_amdgpu_rcp", - "rcp.v2f64" => "__builtin_amdgpu_rcp", - "rcp.v4f32" => "__builtin_amdgpu_rcp", - "rsq.clamped.f32" => "__builtin_amdgpu_rsq_clamped", - "rsq.clamped.f64" => "__builtin_amdgpu_rsq_clamped", - "rsq.clamped.v2f64" => "__builtin_amdgpu_rsq_clamped", - "rsq.clamped.v4f32" => "__builtin_amdgpu_rsq_clamped", - "rsq.f32" => "__builtin_amdgpu_rsq", - "rsq.f64" => "__builtin_amdgpu_rsq", - "rsq.v2f64" => "__builtin_amdgpu_rsq", - "rsq.v4f32" => "__builtin_amdgpu_rsq", - "trig.preop.f32" => "__builtin_amdgpu_trig_preop", - "trig.preop.f64" => "__builtin_amdgpu_trig_preop", - "trig.preop.v2f64" => "__builtin_amdgpu_trig_preop", - "trig.preop.v4f32" => "__builtin_amdgpu_trig_preop", - _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), - } - } - AMDGPU(name, full_name) - } "aarch64" => { fn aarch64(name: &str, full_name: &str) -> &'static str { match name { @@ -537,8 +503,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "ldcl" => "__builtin_arm_ldcl", "mcr" => "__builtin_arm_mcr", "mcr2" => "__builtin_arm_mcr2", - "mcrr" => "__builtin_arm_mcrr", - "mcrr2" => "__builtin_arm_mcrr2", "mrc" => "__builtin_arm_mrc", "mrc2" => "__builtin_arm_mrc2", "qadd" => "__builtin_arm_qadd", @@ -595,7 +559,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "stcl" => "__builtin_arm_stcl", "sxtab16" => "__builtin_arm_sxtab16", "sxtb16" => "__builtin_arm_sxtb16", - "thread.pointer" => "__builtin_thread_pointer", "uadd16" => "__builtin_arm_uadd16", "uadd8" => "__builtin_arm_uadd8", "uasx" => "__builtin_arm_uasx", @@ -646,16 +609,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { } bpf(name, full_name) } - "cuda" => { - fn cuda(name: &str, full_name: &str) -> &'static str { - match name { - // cuda - "syncthreads" => "__syncthreads", - _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), - } - } - cuda(name, full_name) - } "hexagon" => { fn hexagon(name: &str, full_name: &str) -> &'static str { match name { @@ -959,19 +912,10 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "F2.dfcmpge" => "__builtin_HEXAGON_F2_dfcmpge", "F2.dfcmpgt" => "__builtin_HEXAGON_F2_dfcmpgt", "F2.dfcmpuo" => "__builtin_HEXAGON_F2_dfcmpuo", - "F2.dffixupd" => "__builtin_HEXAGON_F2_dffixupd", - "F2.dffixupn" => "__builtin_HEXAGON_F2_dffixupn", - "F2.dffixupr" => "__builtin_HEXAGON_F2_dffixupr", - "F2.dffma" => "__builtin_HEXAGON_F2_dffma", - "F2.dffma.lib" => "__builtin_HEXAGON_F2_dffma_lib", - "F2.dffma.sc" => "__builtin_HEXAGON_F2_dffma_sc", - "F2.dffms" => "__builtin_HEXAGON_F2_dffms", - "F2.dffms.lib" => "__builtin_HEXAGON_F2_dffms_lib", "F2.dfimm.n" => "__builtin_HEXAGON_F2_dfimm_n", "F2.dfimm.p" => "__builtin_HEXAGON_F2_dfimm_p", "F2.dfmax" => "__builtin_HEXAGON_F2_dfmax", "F2.dfmin" => "__builtin_HEXAGON_F2_dfmin", - "F2.dfmpy" => "__builtin_HEXAGON_F2_dfmpy", "F2.dfmpyfix" => "__builtin_HEXAGON_F2_dfmpyfix", "F2.dfmpyhh" => "__builtin_HEXAGON_F2_dfmpyhh", "F2.dfmpylh" => "__builtin_HEXAGON_F2_dfmpylh", @@ -1398,7 +1342,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "S2.asr.r.vw" => "__builtin_HEXAGON_S2_asr_r_vw", "S2.brev" => "__builtin_HEXAGON_S2_brev", "S2.brevp" => "__builtin_HEXAGON_S2_brevp", - "S2.cabacencbin" => "__builtin_HEXAGON_S2_cabacencbin", "S2.cl0" => "__builtin_HEXAGON_S2_cl0", "S2.cl0p" => "__builtin_HEXAGON_S2_cl0p", "S2.cl1" => "__builtin_HEXAGON_S2_cl1", @@ -1569,7 +1512,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "S6.vsplatrbp" => "__builtin_HEXAGON_S6_vsplatrbp", "S6.vtrunehb.ppp" => "__builtin_HEXAGON_S6_vtrunehb_ppp", "S6.vtrunohb.ppp" => "__builtin_HEXAGON_S6_vtrunohb_ppp", - "SI.to.SXTHI.asrh" => "__builtin_SI_to_SXTHI_asrh", "V6.extractw" => "__builtin_HEXAGON_V6_extractw", "V6.extractw.128B" => "__builtin_HEXAGON_V6_extractw_128B", "V6.get.qfext" => "__builtin_HEXAGON_V6_get_qfext", @@ -2160,14 +2102,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vlsrwv.128B" => "__builtin_HEXAGON_V6_vlsrwv_128B", "V6.vlut4" => "__builtin_HEXAGON_V6_vlut4", "V6.vlut4.128B" => "__builtin_HEXAGON_V6_vlut4_128B", - "V6.vlutb" => "__builtin_HEXAGON_V6_vlutb", - "V6.vlutb.128B" => "__builtin_HEXAGON_V6_vlutb_128B", - "V6.vlutb.acc" => "__builtin_HEXAGON_V6_vlutb_acc", - "V6.vlutb.acc.128B" => "__builtin_HEXAGON_V6_vlutb_acc_128B", - "V6.vlutb.dv" => "__builtin_HEXAGON_V6_vlutb_dv", - "V6.vlutb.dv.128B" => "__builtin_HEXAGON_V6_vlutb_dv_128B", - "V6.vlutb.dv.acc" => "__builtin_HEXAGON_V6_vlutb_dv_acc", - "V6.vlutb.dv.acc.128B" => "__builtin_HEXAGON_V6_vlutb_dv_acc_128B", "V6.vlutvvb" => "__builtin_HEXAGON_V6_vlutvvb", "V6.vlutvvb.128B" => "__builtin_HEXAGON_V6_vlutvvb_128B", "V6.vlutvvb.nm" => "__builtin_HEXAGON_V6_vlutvvb_nm", @@ -2669,17 +2603,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "Y6.dmresume" => "__builtin_HEXAGON_Y6_dmresume", "Y6.dmstart" => "__builtin_HEXAGON_Y6_dmstart", "Y6.dmwait" => "__builtin_HEXAGON_Y6_dmwait", - "brev.ldb" => "__builtin_brev_ldb", - "brev.ldd" => "__builtin_brev_ldd", - "brev.ldh" => "__builtin_brev_ldh", - "brev.ldub" => "__builtin_brev_ldub", - "brev.lduh" => "__builtin_brev_lduh", - "brev.ldw" => "__builtin_brev_ldw", - "brev.stb" => "__builtin_brev_stb", - "brev.std" => "__builtin_brev_std", - "brev.sth" => "__builtin_brev_sth", - "brev.sthhi" => "__builtin_brev_sthhi", - "brev.stw" => "__builtin_brev_stw", "circ.ldb" => "__builtin_circ_ldb", "circ.ldd" => "__builtin_circ_ldd", "circ.ldh" => "__builtin_circ_ldh", @@ -2691,7 +2614,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "circ.sth" => "__builtin_circ_sth", "circ.sthhi" => "__builtin_circ_sthhi", "circ.stw" => "__builtin_circ_stw", - "mm256i.vaddw" => "__builtin__mm256i_vaddw", "prefetch" => "__builtin_HEXAGON_prefetch", "vmemcpy" => "__builtin_hexagon_vmemcpy", "vmemset" => "__builtin_hexagon_vmemset", @@ -4910,8 +4832,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { fn nvvm(name: &str, full_name: &str) -> &'static str { match name { // nvvm - "abs.i" => "__nvvm_abs_i", - "abs.ll" => "__nvvm_abs_ll", "activemask" => "__nvvm_activemask", "add.rm.d" => "__nvvm_add_rm_d", "add.rm.f" => "__nvvm_add_rm_f", @@ -4925,10 +4845,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "add.rz.d" => "__nvvm_add_rz_d", "add.rz.f" => "__nvvm_add_rz_f", "add.rz.ftz.f" => "__nvvm_add_rz_ftz_f", - "bar.sync" => "__nvvm_bar_sync", "bar.warp.sync" => "__nvvm_bar_warp_sync", - "barrier0" => "__nvvm_bar0", - // [DUPLICATE]: "barrier0" => "__syncthreads", "barrier0.and" => "__nvvm_bar0_and", "barrier0.or" => "__nvvm_bar0_or", "barrier0.popc" => "__nvvm_bar0_popc", @@ -4938,17 +4855,9 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "bf16x2.to.ue8m0x2.rz.satfinite" => "__nvvm_bf16x2_to_ue8m0x2_rz_satfinite", "bf2h.rn" => "__nvvm_bf2h_rn", "bf2h.rn.ftz" => "__nvvm_bf2h_rn_ftz", - "bitcast.d2ll" => "__nvvm_bitcast_d2ll", - "bitcast.f2i" => "__nvvm_bitcast_f2i", - "bitcast.i2f" => "__nvvm_bitcast_i2f", - "bitcast.ll2d" => "__nvvm_bitcast_ll2d", - "brev32" => "__nvvm_brev32", - "brev64" => "__nvvm_brev64", "ceil.d" => "__nvvm_ceil_d", "ceil.f" => "__nvvm_ceil_f", "ceil.ftz.f" => "__nvvm_ceil_ftz_f", - "clz.i" => "__nvvm_clz_i", - "clz.ll" => "__nvvm_clz_ll", "cos.approx.f" => "__nvvm_cos_approx_f", "cos.approx.ftz.f" => "__nvvm_cos_approx_ftz_f", "cp.async.commit.group" => "__nvvm_cp_async_commit_group", @@ -5012,9 +4921,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "e4m3x2.to.f16x2.rn.relu" => "__nvvm_e4m3x2_to_f16x2_rn_relu", "e5m2x2.to.f16x2.rn" => "__nvvm_e5m2x2_to_f16x2_rn", "e5m2x2.to.f16x2.rn.relu" => "__nvvm_e5m2x2_to_f16x2_rn_relu", - "ex2.approx.d" => "__nvvm_ex2_approx_d", - "ex2.approx.f" => "__nvvm_ex2_approx_f", - "ex2.approx.ftz.f" => "__nvvm_ex2_approx_ftz_f", "exit" => "__nvvm_exit", "f16x2.to.e4m3x2.rn" => "__nvvm_f16x2_to_e4m3x2_rn", "f16x2.to.e4m3x2.rn.relu" => "__nvvm_f16x2_to_e4m3x2_rn_relu", @@ -5100,9 +5006,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "__nvvm_f32x4_to_e5m2x4_rs_relu_satfinite" } "f32x4.to.e5m2x4.rs.satfinite" => "__nvvm_f32x4_to_e5m2x4_rs_satfinite", - "fabs.d" => "__nvvm_fabs_d", - "fabs.f" => "__nvvm_fabs_f", - "fabs.ftz.f" => "__nvvm_fabs_ftz_f", "ff.to.e2m1x2.rn.relu.satfinite" => "__nvvm_ff_to_e2m1x2_rn_relu_satfinite", "ff.to.e2m1x2.rn.satfinite" => "__nvvm_ff_to_e2m1x2_rn_satfinite", "ff.to.e2m3x2.rn.relu.satfinite" => "__nvvm_ff_to_e2m3x2_rn_relu_satfinite", @@ -5219,7 +5122,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "fmin.xorsign.abs.bf16x2" => "__nvvm_fmin_xorsign_abs_bf16x2", "fmin.xorsign.abs.f" => "__nvvm_fmin_xorsign_abs_f", "fns" => "__nvvm_fns", - "h2f" => "__nvvm_h2f", "i2d.rm" => "__nvvm_i2d_rm", "i2d.rn" => "__nvvm_i2d_rn", "i2d.rp" => "__nvvm_i2d_rp", @@ -5250,10 +5152,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "lohi.i2d" => "__nvvm_lohi_i2d", "match.any.sync.i32" => "__nvvm_match_any_sync_i32", "match.any.sync.i64" => "__nvvm_match_any_sync_i64", - "max.i" => "__nvvm_max_i", - "max.ll" => "__nvvm_max_ll", - "max.ui" => "__nvvm_max_ui", - "max.ull" => "__nvvm_max_ull", "mbarrier.arrive" => "__nvvm_mbarrier_arrive", "mbarrier.arrive.drop" => "__nvvm_mbarrier_arrive_drop", "mbarrier.arrive.drop.noComplete" => "__nvvm_mbarrier_arrive_drop_noComplete", @@ -5276,10 +5174,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "membar.cta" => "__nvvm_membar_cta", "membar.gl" => "__nvvm_membar_gl", "membar.sys" => "__nvvm_membar_sys", - "min.i" => "__nvvm_min_i", - "min.ll" => "__nvvm_min_ll", - "min.ui" => "__nvvm_min_ui", - "min.ull" => "__nvvm_min_ull", "mul.rm.d" => "__nvvm_mul_rm_d", "mul.rm.f" => "__nvvm_mul_rm_f", "mul.rm.ftz.f" => "__nvvm_mul_rm_ftz_f", @@ -5304,8 +5198,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "neg.bf16" => "__nvvm_neg_bf16", "neg.bf16x2" => "__nvvm_neg_bf16x2", "pm.event.mask" => "__nvvm_pm_event_mask", - "popc.i" => "__nvvm_popc_i", - "popc.ll" => "__nvvm_popc_ll", "prmt" => "__nvvm_prmt", "rcp.approx.ftz.d" => "__nvvm_rcp_approx_ftz_d", "rcp.approx.ftz.f" => "__nvvm_rcp_approx_ftz_f", @@ -5322,9 +5214,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "rcp.rz.f" => "__nvvm_rcp_rz_f", "rcp.rz.ftz.f" => "__nvvm_rcp_rz_ftz_f", "read.ptx.sreg.clock" => "__nvvm_read_ptx_sreg_clock", - // [DUPLICATE]: "read.ptx.sreg.clock" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.clock64" => "__nvvm_read_ptx_sreg_clock64", - // [DUPLICATE]: "read.ptx.sreg.clock64" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.ctaid.w" => "__nvvm_read_ptx_sreg_ctaid_w", "read.ptx.sreg.ctaid.x" => "__nvvm_read_ptx_sreg_ctaid_x", "read.ptx.sreg.ctaid.y" => "__nvvm_read_ptx_sreg_ctaid_y", @@ -5364,49 +5254,33 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "read.ptx.sreg.globaltimer" => "__nvvm_read_ptx_sreg_globaltimer", "read.ptx.sreg.globaltimer.lo" => "__nvvm_read_ptx_sreg_globaltimer_lo", "read.ptx.sreg.gridid" => "__nvvm_read_ptx_sreg_gridid", - // [DUPLICATE]: "read.ptx.sreg.gridid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.laneid" => "__nvvm_read_ptx_sreg_laneid", - // [DUPLICATE]: "read.ptx.sreg.laneid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.eq" => "__nvvm_read_ptx_sreg_lanemask_eq", - // [DUPLICATE]: "read.ptx.sreg.lanemask.eq" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.ge" => "__nvvm_read_ptx_sreg_lanemask_ge", - // [DUPLICATE]: "read.ptx.sreg.lanemask.ge" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.gt" => "__nvvm_read_ptx_sreg_lanemask_gt", - // [DUPLICATE]: "read.ptx.sreg.lanemask.gt" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.le" => "__nvvm_read_ptx_sreg_lanemask_le", - // [DUPLICATE]: "read.ptx.sreg.lanemask.le" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.lt" => "__nvvm_read_ptx_sreg_lanemask_lt", - // [DUPLICATE]: "read.ptx.sreg.lanemask.lt" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.nctaid.w" => "__nvvm_read_ptx_sreg_nctaid_w", "read.ptx.sreg.nctaid.x" => "__nvvm_read_ptx_sreg_nctaid_x", "read.ptx.sreg.nctaid.y" => "__nvvm_read_ptx_sreg_nctaid_y", "read.ptx.sreg.nctaid.z" => "__nvvm_read_ptx_sreg_nctaid_z", "read.ptx.sreg.nsmid" => "__nvvm_read_ptx_sreg_nsmid", - // [DUPLICATE]: "read.ptx.sreg.nsmid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.ntid.w" => "__nvvm_read_ptx_sreg_ntid_w", "read.ptx.sreg.ntid.x" => "__nvvm_read_ptx_sreg_ntid_x", "read.ptx.sreg.ntid.y" => "__nvvm_read_ptx_sreg_ntid_y", "read.ptx.sreg.ntid.z" => "__nvvm_read_ptx_sreg_ntid_z", "read.ptx.sreg.nwarpid" => "__nvvm_read_ptx_sreg_nwarpid", - // [DUPLICATE]: "read.ptx.sreg.nwarpid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.pm0" => "__nvvm_read_ptx_sreg_pm0", - // [DUPLICATE]: "read.ptx.sreg.pm0" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.pm1" => "__nvvm_read_ptx_sreg_pm1", - // [DUPLICATE]: "read.ptx.sreg.pm1" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.pm2" => "__nvvm_read_ptx_sreg_pm2", - // [DUPLICATE]: "read.ptx.sreg.pm2" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.pm3" => "__nvvm_read_ptx_sreg_pm3", - // [DUPLICATE]: "read.ptx.sreg.pm3" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.smid" => "__nvvm_read_ptx_sreg_smid", - // [DUPLICATE]: "read.ptx.sreg.smid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.tid.w" => "__nvvm_read_ptx_sreg_tid_w", "read.ptx.sreg.tid.x" => "__nvvm_read_ptx_sreg_tid_x", "read.ptx.sreg.tid.y" => "__nvvm_read_ptx_sreg_tid_y", "read.ptx.sreg.tid.z" => "__nvvm_read_ptx_sreg_tid_z", "read.ptx.sreg.warpid" => "__nvvm_read_ptx_sreg_warpid", - // [DUPLICATE]: "read.ptx.sreg.warpid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.warpsize" => "__nvvm_read_ptx_sreg_warpsize", - // [DUPLICATE]: "read.ptx.sreg.warpsize" => "__nvvm_read_ptx_sreg_", "redux.sync.add" => "__nvvm_redux_sync_add", "redux.sync.and" => "__nvvm_redux_sync_and", "redux.sync.fmax" => "__nvvm_redux_sync_fmax", @@ -5424,9 +5298,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "redux.sync.umin" => "__nvvm_redux_sync_umin", "redux.sync.xor" => "__nvvm_redux_sync_xor", "reflect" => "__nvvm_reflect", - "rotate.b32" => "__nvvm_rotate_b32", - "rotate.b64" => "__nvvm_rotate_b64", - "rotate.right.b64" => "__nvvm_rotate_right_b64", "round.d" => "__nvvm_round_d", "round.f" => "__nvvm_round_f", "round.ftz.f" => "__nvvm_round_ftz_f", @@ -5692,7 +5563,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sust.p.3d.v4i16.trap" => "__nvvm_sust_p_3d_v4i16_trap", "sust.p.3d.v4i32.trap" => "__nvvm_sust_p_3d_v4i32_trap", "sust.p.3d.v4i8.trap" => "__nvvm_sust_p_3d_v4i8_trap", - "swap.lo.hi.b64" => "__nvvm_swap_lo_hi_b64", "trunc.d" => "__nvvm_trunc_d", "trunc.f" => "__nvvm_trunc_f", "trunc.ftz.f" => "__nvvm_trunc_ftz_f", @@ -6132,89 +6002,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "packed2zoned" => "__builtin_ppc_packed2zoned", "pdepd" => "__builtin_pdepd", "pextd" => "__builtin_pextd", - "qpx.qvfabs" => "__builtin_qpx_qvfabs", - "qpx.qvfadd" => "__builtin_qpx_qvfadd", - "qpx.qvfadds" => "__builtin_qpx_qvfadds", - "qpx.qvfcfid" => "__builtin_qpx_qvfcfid", - "qpx.qvfcfids" => "__builtin_qpx_qvfcfids", - "qpx.qvfcfidu" => "__builtin_qpx_qvfcfidu", - "qpx.qvfcfidus" => "__builtin_qpx_qvfcfidus", - "qpx.qvfcmpeq" => "__builtin_qpx_qvfcmpeq", - "qpx.qvfcmpgt" => "__builtin_qpx_qvfcmpgt", - "qpx.qvfcmplt" => "__builtin_qpx_qvfcmplt", - "qpx.qvfcpsgn" => "__builtin_qpx_qvfcpsgn", - "qpx.qvfctid" => "__builtin_qpx_qvfctid", - "qpx.qvfctidu" => "__builtin_qpx_qvfctidu", - "qpx.qvfctiduz" => "__builtin_qpx_qvfctiduz", - "qpx.qvfctidz" => "__builtin_qpx_qvfctidz", - "qpx.qvfctiw" => "__builtin_qpx_qvfctiw", - "qpx.qvfctiwu" => "__builtin_qpx_qvfctiwu", - "qpx.qvfctiwuz" => "__builtin_qpx_qvfctiwuz", - "qpx.qvfctiwz" => "__builtin_qpx_qvfctiwz", - "qpx.qvflogical" => "__builtin_qpx_qvflogical", - "qpx.qvfmadd" => "__builtin_qpx_qvfmadd", - "qpx.qvfmadds" => "__builtin_qpx_qvfmadds", - "qpx.qvfmsub" => "__builtin_qpx_qvfmsub", - "qpx.qvfmsubs" => "__builtin_qpx_qvfmsubs", - "qpx.qvfmul" => "__builtin_qpx_qvfmul", - "qpx.qvfmuls" => "__builtin_qpx_qvfmuls", - "qpx.qvfnabs" => "__builtin_qpx_qvfnabs", - "qpx.qvfneg" => "__builtin_qpx_qvfneg", - "qpx.qvfnmadd" => "__builtin_qpx_qvfnmadd", - "qpx.qvfnmadds" => "__builtin_qpx_qvfnmadds", - "qpx.qvfnmsub" => "__builtin_qpx_qvfnmsub", - "qpx.qvfnmsubs" => "__builtin_qpx_qvfnmsubs", - "qpx.qvfperm" => "__builtin_qpx_qvfperm", - "qpx.qvfre" => "__builtin_qpx_qvfre", - "qpx.qvfres" => "__builtin_qpx_qvfres", - "qpx.qvfrim" => "__builtin_qpx_qvfrim", - "qpx.qvfrin" => "__builtin_qpx_qvfrin", - "qpx.qvfrip" => "__builtin_qpx_qvfrip", - "qpx.qvfriz" => "__builtin_qpx_qvfriz", - "qpx.qvfrsp" => "__builtin_qpx_qvfrsp", - "qpx.qvfrsqrte" => "__builtin_qpx_qvfrsqrte", - "qpx.qvfrsqrtes" => "__builtin_qpx_qvfrsqrtes", - "qpx.qvfsel" => "__builtin_qpx_qvfsel", - "qpx.qvfsub" => "__builtin_qpx_qvfsub", - "qpx.qvfsubs" => "__builtin_qpx_qvfsubs", - "qpx.qvftstnan" => "__builtin_qpx_qvftstnan", - "qpx.qvfxmadd" => "__builtin_qpx_qvfxmadd", - "qpx.qvfxmadds" => "__builtin_qpx_qvfxmadds", - "qpx.qvfxmul" => "__builtin_qpx_qvfxmul", - "qpx.qvfxmuls" => "__builtin_qpx_qvfxmuls", - "qpx.qvfxxcpnmadd" => "__builtin_qpx_qvfxxcpnmadd", - "qpx.qvfxxcpnmadds" => "__builtin_qpx_qvfxxcpnmadds", - "qpx.qvfxxmadd" => "__builtin_qpx_qvfxxmadd", - "qpx.qvfxxmadds" => "__builtin_qpx_qvfxxmadds", - "qpx.qvfxxnpmadd" => "__builtin_qpx_qvfxxnpmadd", - "qpx.qvfxxnpmadds" => "__builtin_qpx_qvfxxnpmadds", - "qpx.qvgpci" => "__builtin_qpx_qvgpci", - "qpx.qvlfcd" => "__builtin_qpx_qvlfcd", - "qpx.qvlfcda" => "__builtin_qpx_qvlfcda", - "qpx.qvlfcs" => "__builtin_qpx_qvlfcs", - "qpx.qvlfcsa" => "__builtin_qpx_qvlfcsa", - "qpx.qvlfd" => "__builtin_qpx_qvlfd", - "qpx.qvlfda" => "__builtin_qpx_qvlfda", - "qpx.qvlfiwa" => "__builtin_qpx_qvlfiwa", - "qpx.qvlfiwaa" => "__builtin_qpx_qvlfiwaa", - "qpx.qvlfiwz" => "__builtin_qpx_qvlfiwz", - "qpx.qvlfiwza" => "__builtin_qpx_qvlfiwza", - "qpx.qvlfs" => "__builtin_qpx_qvlfs", - "qpx.qvlfsa" => "__builtin_qpx_qvlfsa", - "qpx.qvlpcld" => "__builtin_qpx_qvlpcld", - "qpx.qvlpcls" => "__builtin_qpx_qvlpcls", - "qpx.qvlpcrd" => "__builtin_qpx_qvlpcrd", - "qpx.qvlpcrs" => "__builtin_qpx_qvlpcrs", - "qpx.qvstfcd" => "__builtin_qpx_qvstfcd", - "qpx.qvstfcda" => "__builtin_qpx_qvstfcda", - "qpx.qvstfcs" => "__builtin_qpx_qvstfcs", - "qpx.qvstfcsa" => "__builtin_qpx_qvstfcsa", - "qpx.qvstfd" => "__builtin_qpx_qvstfd", - "qpx.qvstfda" => "__builtin_qpx_qvstfda", - "qpx.qvstfiw" => "__builtin_qpx_qvstfiw", - "qpx.qvstfiwa" => "__builtin_qpx_qvstfiwa", - "qpx.qvstfs" => "__builtin_qpx_qvstfs", - "qpx.qvstfsa" => "__builtin_qpx_qvstfsa", "readflm" => "__builtin_readflm", "rlwimi" => "__builtin_ppc_rlwimi", "rlwnm" => "__builtin_ppc_rlwnm", @@ -6329,33 +6116,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { } ppc(name, full_name) } - "ptx" => { - fn ptx(name: &str, full_name: &str) -> &'static str { - match name { - // ptx - "bar.sync" => "__builtin_ptx_bar_sync", - "read.clock" => "__builtin_ptx_read_clock", - "read.clock64" => "__builtin_ptx_read_clock64", - "read.gridid" => "__builtin_ptx_read_gridid", - "read.laneid" => "__builtin_ptx_read_laneid", - "read.lanemask.eq" => "__builtin_ptx_read_lanemask_eq", - "read.lanemask.ge" => "__builtin_ptx_read_lanemask_ge", - "read.lanemask.gt" => "__builtin_ptx_read_lanemask_gt", - "read.lanemask.le" => "__builtin_ptx_read_lanemask_le", - "read.lanemask.lt" => "__builtin_ptx_read_lanemask_lt", - "read.nsmid" => "__builtin_ptx_read_nsmid", - "read.nwarpid" => "__builtin_ptx_read_nwarpid", - "read.pm0" => "__builtin_ptx_read_pm0", - "read.pm1" => "__builtin_ptx_read_pm1", - "read.pm2" => "__builtin_ptx_read_pm2", - "read.pm3" => "__builtin_ptx_read_pm3", - "read.smid" => "__builtin_ptx_read_smid", - "read.warpid" => "__builtin_ptx_read_warpid", - _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), - } - } - ptx(name, full_name) - } "r600" => { fn r600(name: &str, full_name: &str) -> &'static str { match name { @@ -7902,10 +7662,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "aadd64" => "__builtin_ia32_aadd64", "aand32" => "__builtin_ia32_aand32", "aand64" => "__builtin_ia32_aand64", - "addcarry.u32" => "__builtin_ia32_addcarry_u32", - "addcarry.u64" => "__builtin_ia32_addcarry_u64", - "addcarryx.u32" => "__builtin_ia32_addcarryx_u32", - "addcarryx.u64" => "__builtin_ia32_addcarryx_u64", "aesni.aesdec" => "__builtin_ia32_aesdec128", "aesni.aesdec.256" => "__builtin_ia32_aesdec256", "aesni.aesdec.512" => "__builtin_ia32_aesdec512", @@ -7924,18 +7680,11 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "aor64" => "__builtin_ia32_aor64", "avx.addsub.pd.256" => "__builtin_ia32_addsubpd256", "avx.addsub.ps.256" => "__builtin_ia32_addsubps256", - "avx.blend.pd.256" => "__builtin_ia32_blendpd256", - "avx.blend.ps.256" => "__builtin_ia32_blendps256", "avx.blendv.pd.256" => "__builtin_ia32_blendvpd256", "avx.blendv.ps.256" => "__builtin_ia32_blendvps256", - "avx.cmp.pd.256" => "__builtin_ia32_cmppd256", - "avx.cmp.ps.256" => "__builtin_ia32_cmpps256", "avx.cvt.pd2.ps.256" => "__builtin_ia32_cvtpd2ps256", "avx.cvt.pd2dq.256" => "__builtin_ia32_cvtpd2dq256", - "avx.cvt.ps2.pd.256" => "__builtin_ia32_cvtps2pd256", "avx.cvt.ps2dq.256" => "__builtin_ia32_cvtps2dq256", - "avx.cvtdq2.pd.256" => "__builtin_ia32_cvtdq2pd256", - "avx.cvtdq2.ps.256" => "__builtin_ia32_cvtdq2ps256", "avx.cvtt.pd2dq.256" => "__builtin_ia32_cvttpd2dq256", "avx.cvtt.ps2dq.256" => "__builtin_ia32_cvttps2dq256", "avx.dp.ps.256" => "__builtin_ia32_dpps256", @@ -7965,22 +7714,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx.round.pd.256" => "__builtin_ia32_roundpd256", "avx.round.ps.256" => "__builtin_ia32_roundps256", "avx.rsqrt.ps.256" => "__builtin_ia32_rsqrtps256", - "avx.sqrt.pd.256" => "__builtin_ia32_sqrtpd256", - "avx.sqrt.ps.256" => "__builtin_ia32_sqrtps256", - "avx.storeu.dq.256" => "__builtin_ia32_storedqu256", - "avx.storeu.pd.256" => "__builtin_ia32_storeupd256", - "avx.storeu.ps.256" => "__builtin_ia32_storeups256", - "avx.vbroadcastf128.pd.256" => "__builtin_ia32_vbroadcastf128_pd256", - "avx.vbroadcastf128.ps.256" => "__builtin_ia32_vbroadcastf128_ps256", - "avx.vextractf128.pd.256" => "__builtin_ia32_vextractf128_pd256", - "avx.vextractf128.ps.256" => "__builtin_ia32_vextractf128_ps256", - "avx.vextractf128.si.256" => "__builtin_ia32_vextractf128_si256", - "avx.vinsertf128.pd.256" => "__builtin_ia32_vinsertf128_pd256", - "avx.vinsertf128.ps.256" => "__builtin_ia32_vinsertf128_ps256", - "avx.vinsertf128.si.256" => "__builtin_ia32_vinsertf128_si256", - "avx.vperm2f128.pd.256" => "__builtin_ia32_vperm2f128_pd256", - "avx.vperm2f128.ps.256" => "__builtin_ia32_vperm2f128_ps256", - "avx.vperm2f128.si.256" => "__builtin_ia32_vperm2f128_si256", "avx.vpermilvar.pd" => "__builtin_ia32_vpermilvarpd", "avx.vpermilvar.pd.256" => "__builtin_ia32_vpermilvarpd256", "avx.vpermilvar.ps" => "__builtin_ia32_vpermilvarps", @@ -8265,33 +7998,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.maskstore.d.256" => "__builtin_ia32_maskstored256", "avx2.maskstore.q" => "__builtin_ia32_maskstoreq", "avx2.maskstore.q.256" => "__builtin_ia32_maskstoreq256", - "avx2.movntdqa" => "__builtin_ia32_movntdqa256", "avx2.mpsadbw" => "__builtin_ia32_mpsadbw256", - "avx2.pabs.b" => "__builtin_ia32_pabsb256", - "avx2.pabs.d" => "__builtin_ia32_pabsd256", - "avx2.pabs.w" => "__builtin_ia32_pabsw256", "avx2.packssdw" => "__builtin_ia32_packssdw256", "avx2.packsswb" => "__builtin_ia32_packsswb256", "avx2.packusdw" => "__builtin_ia32_packusdw256", "avx2.packuswb" => "__builtin_ia32_packuswb256", - "avx2.padds.b" => "__builtin_ia32_paddsb256", - "avx2.padds.w" => "__builtin_ia32_paddsw256", - "avx2.paddus.b" => "__builtin_ia32_paddusb256", - "avx2.paddus.w" => "__builtin_ia32_paddusw256", "avx2.pavg.b" => "__builtin_ia32_pavgb256", "avx2.pavg.w" => "__builtin_ia32_pavgw256", - "avx2.pblendd.128" => "__builtin_ia32_pblendd128", - "avx2.pblendd.256" => "__builtin_ia32_pblendd256", "avx2.pblendvb" => "__builtin_ia32_pblendvb256", - "avx2.pblendw" => "__builtin_ia32_pblendw256", - "avx2.pbroadcastb.128" => "__builtin_ia32_pbroadcastb128", - "avx2.pbroadcastb.256" => "__builtin_ia32_pbroadcastb256", - "avx2.pbroadcastd.128" => "__builtin_ia32_pbroadcastd128", - "avx2.pbroadcastd.256" => "__builtin_ia32_pbroadcastd256", - "avx2.pbroadcastq.128" => "__builtin_ia32_pbroadcastq128", - "avx2.pbroadcastq.256" => "__builtin_ia32_pbroadcastq256", - "avx2.pbroadcastw.128" => "__builtin_ia32_pbroadcastw128", - "avx2.pbroadcastw.256" => "__builtin_ia32_pbroadcastw256", "avx2.permd" => "__builtin_ia32_permvarsi256", "avx2.permps" => "__builtin_ia32_permvarsf256", "avx2.phadd.d" => "__builtin_ia32_phaddd256", @@ -8302,44 +8016,16 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.phsub.w" => "__builtin_ia32_phsubw256", "avx2.pmadd.ub.sw" => "__builtin_ia32_pmaddubsw256", "avx2.pmadd.wd" => "__builtin_ia32_pmaddwd256", - "avx2.pmaxs.b" => "__builtin_ia32_pmaxsb256", - "avx2.pmaxs.d" => "__builtin_ia32_pmaxsd256", - "avx2.pmaxs.w" => "__builtin_ia32_pmaxsw256", - "avx2.pmaxu.b" => "__builtin_ia32_pmaxub256", - "avx2.pmaxu.d" => "__builtin_ia32_pmaxud256", - "avx2.pmaxu.w" => "__builtin_ia32_pmaxuw256", - "avx2.pmins.b" => "__builtin_ia32_pminsb256", - "avx2.pmins.d" => "__builtin_ia32_pminsd256", - "avx2.pmins.w" => "__builtin_ia32_pminsw256", - "avx2.pminu.b" => "__builtin_ia32_pminub256", - "avx2.pminu.d" => "__builtin_ia32_pminud256", - "avx2.pminu.w" => "__builtin_ia32_pminuw256", "avx2.pmovmskb" => "__builtin_ia32_pmovmskb256", - "avx2.pmovsxbd" => "__builtin_ia32_pmovsxbd256", - "avx2.pmovsxbq" => "__builtin_ia32_pmovsxbq256", - "avx2.pmovsxbw" => "__builtin_ia32_pmovsxbw256", - "avx2.pmovsxdq" => "__builtin_ia32_pmovsxdq256", - "avx2.pmovsxwd" => "__builtin_ia32_pmovsxwd256", - "avx2.pmovsxwq" => "__builtin_ia32_pmovsxwq256", - "avx2.pmovzxbd" => "__builtin_ia32_pmovzxbd256", - "avx2.pmovzxbq" => "__builtin_ia32_pmovzxbq256", - "avx2.pmovzxbw" => "__builtin_ia32_pmovzxbw256", - "avx2.pmovzxdq" => "__builtin_ia32_pmovzxdq256", - "avx2.pmovzxwd" => "__builtin_ia32_pmovzxwd256", - "avx2.pmovzxwq" => "__builtin_ia32_pmovzxwq256", - "avx2.pmul.dq" => "__builtin_ia32_pmuldq256", "avx2.pmul.hr.sw" => "__builtin_ia32_pmulhrsw256", "avx2.pmulh.w" => "__builtin_ia32_pmulhw256", "avx2.pmulhu.w" => "__builtin_ia32_pmulhuw256", - "avx2.pmulu.dq" => "__builtin_ia32_pmuludq256", "avx2.psad.bw" => "__builtin_ia32_psadbw256", "avx2.pshuf.b" => "__builtin_ia32_pshufb256", "avx2.psign.b" => "__builtin_ia32_psignb256", "avx2.psign.d" => "__builtin_ia32_psignd256", "avx2.psign.w" => "__builtin_ia32_psignw256", "avx2.psll.d" => "__builtin_ia32_pslld256", - "avx2.psll.dq" => "__builtin_ia32_pslldqi256", - "avx2.psll.dq.bs" => "__builtin_ia32_pslldqi256_byteshift", "avx2.psll.q" => "__builtin_ia32_psllq256", "avx2.psll.w" => "__builtin_ia32_psllw256", "avx2.pslli.d" => "__builtin_ia32_pslldi256", @@ -8356,8 +8042,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.psrav.d" => "__builtin_ia32_psrav4si", "avx2.psrav.d.256" => "__builtin_ia32_psrav8si", "avx2.psrl.d" => "__builtin_ia32_psrld256", - "avx2.psrl.dq" => "__builtin_ia32_psrldqi256", - "avx2.psrl.dq.bs" => "__builtin_ia32_psrldqi256_byteshift", "avx2.psrl.q" => "__builtin_ia32_psrlq256", "avx2.psrl.w" => "__builtin_ia32_psrlw256", "avx2.psrli.d" => "__builtin_ia32_psrldi256", @@ -8367,15 +8051,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.psrlv.d.256" => "__builtin_ia32_psrlv8si", "avx2.psrlv.q" => "__builtin_ia32_psrlv2di", "avx2.psrlv.q.256" => "__builtin_ia32_psrlv4di", - "avx2.psubs.b" => "__builtin_ia32_psubsb256", - "avx2.psubs.w" => "__builtin_ia32_psubsw256", - "avx2.psubus.b" => "__builtin_ia32_psubusb256", - "avx2.psubus.w" => "__builtin_ia32_psubusw256", - "avx2.vbroadcast.sd.pd.256" => "__builtin_ia32_vbroadcastsd_pd256", - "avx2.vbroadcast.ss.ps" => "__builtin_ia32_vbroadcastss_ps", - "avx2.vbroadcast.ss.ps.256" => "__builtin_ia32_vbroadcastss_ps256", - "avx2.vextracti128" => "__builtin_ia32_extract128i256", - "avx2.vinserti128" => "__builtin_ia32_insert128i256", "avx2.vpdpbssd.128" => "__builtin_ia32_vpdpbssd128", "avx2.vpdpbssd.256" => "__builtin_ia32_vpdpbssd256", "avx2.vpdpbssds.128" => "__builtin_ia32_vpdpbssds128", @@ -8400,7 +8075,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.vpdpwuud.256" => "__builtin_ia32_vpdpwuud256", "avx2.vpdpwuuds.128" => "__builtin_ia32_vpdpwuuds128", "avx2.vpdpwuuds.256" => "__builtin_ia32_vpdpwuuds256", - "avx2.vperm2i128" => "__builtin_ia32_permti256", "avx512.add.pd.512" => "__builtin_ia32_addpd512", "avx512.add.ps.512" => "__builtin_ia32_addps512", "avx512.broadcastmb.128" => "__builtin_ia32_broadcastmb128", @@ -8415,194 +8089,32 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.conflict.q.128" => "__builtin_ia32_vpconflictdi_128", "avx512.conflict.q.256" => "__builtin_ia32_vpconflictdi_256", "avx512.conflict.q.512" => "__builtin_ia32_vpconflictdi_512", - "avx512.cvtb2mask.128" => "__builtin_ia32_cvtb2mask128", - "avx512.cvtb2mask.256" => "__builtin_ia32_cvtb2mask256", - "avx512.cvtb2mask.512" => "__builtin_ia32_cvtb2mask512", - "avx512.cvtd2mask.128" => "__builtin_ia32_cvtd2mask128", - "avx512.cvtd2mask.256" => "__builtin_ia32_cvtd2mask256", - "avx512.cvtd2mask.512" => "__builtin_ia32_cvtd2mask512", - "avx512.cvtmask2b.128" => "__builtin_ia32_cvtmask2b128", - "avx512.cvtmask2b.256" => "__builtin_ia32_cvtmask2b256", - "avx512.cvtmask2b.512" => "__builtin_ia32_cvtmask2b512", - "avx512.cvtmask2d.128" => "__builtin_ia32_cvtmask2d128", - "avx512.cvtmask2d.256" => "__builtin_ia32_cvtmask2d256", - "avx512.cvtmask2d.512" => "__builtin_ia32_cvtmask2d512", - "avx512.cvtmask2q.128" => "__builtin_ia32_cvtmask2q128", - "avx512.cvtmask2q.256" => "__builtin_ia32_cvtmask2q256", - "avx512.cvtmask2q.512" => "__builtin_ia32_cvtmask2q512", - "avx512.cvtmask2w.128" => "__builtin_ia32_cvtmask2w128", - "avx512.cvtmask2w.256" => "__builtin_ia32_cvtmask2w256", - "avx512.cvtmask2w.512" => "__builtin_ia32_cvtmask2w512", - "avx512.cvtq2mask.128" => "__builtin_ia32_cvtq2mask128", - "avx512.cvtq2mask.256" => "__builtin_ia32_cvtq2mask256", - "avx512.cvtq2mask.512" => "__builtin_ia32_cvtq2mask512", - "avx512.cvtsd2usi" => "__builtin_ia32_cvtsd2usi", - "avx512.cvtsd2usi64" => "__builtin_ia32_cvtsd2usi64", - "avx512.cvtsi2sd32" => "__builtin_ia32_cvtsi2sd32", "avx512.cvtsi2sd64" => "__builtin_ia32_cvtsi2sd64", "avx512.cvtsi2ss32" => "__builtin_ia32_cvtsi2ss32", "avx512.cvtsi2ss64" => "__builtin_ia32_cvtsi2ss64", - "avx512.cvtss2usi" => "__builtin_ia32_cvtss2usi", - "avx512.cvtss2usi64" => "__builtin_ia32_cvtss2usi64", "avx512.cvttsd2si" => "__builtin_ia32_vcvttsd2si32", "avx512.cvttsd2si64" => "__builtin_ia32_vcvttsd2si64", "avx512.cvttsd2usi" => "__builtin_ia32_vcvttsd2usi32", - // [DUPLICATE]: "avx512.cvttsd2usi" => "__builtin_ia32_cvttsd2usi", "avx512.cvttsd2usi64" => "__builtin_ia32_vcvttsd2usi64", - // [DUPLICATE]: "avx512.cvttsd2usi64" => "__builtin_ia32_cvttsd2usi64", "avx512.cvttss2si" => "__builtin_ia32_vcvttss2si32", "avx512.cvttss2si64" => "__builtin_ia32_vcvttss2si64", "avx512.cvttss2usi" => "__builtin_ia32_vcvttss2usi32", - // [DUPLICATE]: "avx512.cvttss2usi" => "__builtin_ia32_cvttss2usi", "avx512.cvttss2usi64" => "__builtin_ia32_vcvttss2usi64", - // [DUPLICATE]: "avx512.cvttss2usi64" => "__builtin_ia32_cvttss2usi64", - "avx512.cvtusi2sd" => "__builtin_ia32_cvtusi2sd", - // [DUPLICATE]: "avx512.cvtusi2sd" => "__builtin_ia32_cvtusi2sd32", "avx512.cvtusi2ss" => "__builtin_ia32_cvtusi2ss32", - // [DUPLICATE]: "avx512.cvtusi2ss" => "__builtin_ia32_cvtusi2ss", "avx512.cvtusi642sd" => "__builtin_ia32_cvtusi2sd64", - // [DUPLICATE]: "avx512.cvtusi642sd" => "__builtin_ia32_cvtusi642sd", "avx512.cvtusi642ss" => "__builtin_ia32_cvtusi2ss64", - // [DUPLICATE]: "avx512.cvtusi642ss" => "__builtin_ia32_cvtusi642ss", - "avx512.cvtw2mask.128" => "__builtin_ia32_cvtw2mask128", - "avx512.cvtw2mask.256" => "__builtin_ia32_cvtw2mask256", - "avx512.cvtw2mask.512" => "__builtin_ia32_cvtw2mask512", "avx512.dbpsadbw.128" => "__builtin_ia32_dbpsadbw128", "avx512.dbpsadbw.256" => "__builtin_ia32_dbpsadbw256", "avx512.dbpsadbw.512" => "__builtin_ia32_dbpsadbw512", "avx512.div.pd.512" => "__builtin_ia32_divpd512", "avx512.div.ps.512" => "__builtin_ia32_divps512", - "avx512.exp2.pd" => "__builtin_ia32_exp2pd_mask", - "avx512.exp2.ps" => "__builtin_ia32_exp2ps_mask", - "avx512.gather.dpd.512" => "__builtin_ia32_gathersiv8df", - "avx512.gather.dpi.512" => "__builtin_ia32_gathersiv16si", - "avx512.gather.dpq.512" => "__builtin_ia32_gathersiv8di", - "avx512.gather.dps.512" => "__builtin_ia32_gathersiv16sf", - "avx512.gather.qpd.512" => "__builtin_ia32_gatherdiv8df", - "avx512.gather.qpi.512" => "__builtin_ia32_gatherdiv16si", - "avx512.gather.qpq.512" => "__builtin_ia32_gatherdiv8di", - "avx512.gather.qps.512" => "__builtin_ia32_gatherdiv16sf", - "avx512.gather3div2.df" => "__builtin_ia32_gather3div2df", - "avx512.gather3div2.di" => "__builtin_ia32_gather3div2di", - "avx512.gather3div4.df" => "__builtin_ia32_gather3div4df", - "avx512.gather3div4.di" => "__builtin_ia32_gather3div4di", - "avx512.gather3div4.sf" => "__builtin_ia32_gather3div4sf", - "avx512.gather3div4.si" => "__builtin_ia32_gather3div4si", - "avx512.gather3div8.sf" => "__builtin_ia32_gather3div8sf", - "avx512.gather3div8.si" => "__builtin_ia32_gather3div8si", - "avx512.gather3siv2.df" => "__builtin_ia32_gather3siv2df", - "avx512.gather3siv2.di" => "__builtin_ia32_gather3siv2di", - "avx512.gather3siv4.df" => "__builtin_ia32_gather3siv4df", - "avx512.gather3siv4.di" => "__builtin_ia32_gather3siv4di", - "avx512.gather3siv4.sf" => "__builtin_ia32_gather3siv4sf", - "avx512.gather3siv4.si" => "__builtin_ia32_gather3siv4si", - "avx512.gather3siv8.sf" => "__builtin_ia32_gather3siv8sf", - "avx512.gather3siv8.si" => "__builtin_ia32_gather3siv8si", - "avx512.gatherpf.dpd.512" => "__builtin_ia32_gatherpfdpd", - "avx512.gatherpf.dps.512" => "__builtin_ia32_gatherpfdps", - "avx512.gatherpf.qpd.512" => "__builtin_ia32_gatherpfqpd", - "avx512.gatherpf.qps.512" => "__builtin_ia32_gatherpfqps", - "avx512.kand.w" => "__builtin_ia32_kandhi", - "avx512.kandn.w" => "__builtin_ia32_kandnhi", - "avx512.knot.w" => "__builtin_ia32_knothi", - "avx512.kor.w" => "__builtin_ia32_korhi", - "avx512.kortestc.w" => "__builtin_ia32_kortestchi", - "avx512.kortestz.w" => "__builtin_ia32_kortestzhi", - "avx512.kunpck.bw" => "__builtin_ia32_kunpckhi", - "avx512.kunpck.dq" => "__builtin_ia32_kunpckdi", - "avx512.kunpck.wd" => "__builtin_ia32_kunpcksi", - "avx512.kxnor.w" => "__builtin_ia32_kxnorhi", - "avx512.kxor.w" => "__builtin_ia32_kxorhi", - "avx512.mask.add.pd.128" => "__builtin_ia32_addpd128_mask", - "avx512.mask.add.pd.256" => "__builtin_ia32_addpd256_mask", - "avx512.mask.add.pd.512" => "__builtin_ia32_addpd512_mask", - "avx512.mask.add.ps.128" => "__builtin_ia32_addps128_mask", - "avx512.mask.add.ps.256" => "__builtin_ia32_addps256_mask", - "avx512.mask.add.ps.512" => "__builtin_ia32_addps512_mask", // [INVALID CONVERSION]: "avx512.mask.add.sd.round" => "__builtin_ia32_addsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.add.ss.round" => "__builtin_ia32_addss_round_mask", - "avx512.mask.and.pd.128" => "__builtin_ia32_andpd128_mask", - "avx512.mask.and.pd.256" => "__builtin_ia32_andpd256_mask", - "avx512.mask.and.pd.512" => "__builtin_ia32_andpd512_mask", - "avx512.mask.and.ps.128" => "__builtin_ia32_andps128_mask", - "avx512.mask.and.ps.256" => "__builtin_ia32_andps256_mask", - "avx512.mask.and.ps.512" => "__builtin_ia32_andps512_mask", - "avx512.mask.andn.pd.128" => "__builtin_ia32_andnpd128_mask", - "avx512.mask.andn.pd.256" => "__builtin_ia32_andnpd256_mask", - "avx512.mask.andn.pd.512" => "__builtin_ia32_andnpd512_mask", - "avx512.mask.andn.ps.128" => "__builtin_ia32_andnps128_mask", - "avx512.mask.andn.ps.256" => "__builtin_ia32_andnps256_mask", - "avx512.mask.andn.ps.512" => "__builtin_ia32_andnps512_mask", - "avx512.mask.blend.d.512" => "__builtin_ia32_blendmd_512_mask", - "avx512.mask.blend.pd.512" => "__builtin_ia32_blendmpd_512_mask", - "avx512.mask.blend.ps.512" => "__builtin_ia32_blendmps_512_mask", - "avx512.mask.blend.q.512" => "__builtin_ia32_blendmq_512_mask", - "avx512.mask.broadcastf32x2.256" => "__builtin_ia32_broadcastf32x2_256_mask", - "avx512.mask.broadcastf32x2.512" => "__builtin_ia32_broadcastf32x2_512_mask", - "avx512.mask.broadcastf32x4.256" => "__builtin_ia32_broadcastf32x4_256_mask", - "avx512.mask.broadcastf32x4.512" => "__builtin_ia32_broadcastf32x4_512", - "avx512.mask.broadcastf32x8.512" => "__builtin_ia32_broadcastf32x8_512_mask", - "avx512.mask.broadcastf64x2.256" => "__builtin_ia32_broadcastf64x2_256_mask", - "avx512.mask.broadcastf64x2.512" => "__builtin_ia32_broadcastf64x2_512_mask", - "avx512.mask.broadcastf64x4.512" => "__builtin_ia32_broadcastf64x4_512", - "avx512.mask.broadcasti32x2.128" => "__builtin_ia32_broadcasti32x2_128_mask", - "avx512.mask.broadcasti32x2.256" => "__builtin_ia32_broadcasti32x2_256_mask", - "avx512.mask.broadcasti32x2.512" => "__builtin_ia32_broadcasti32x2_512_mask", - "avx512.mask.broadcasti32x4.256" => "__builtin_ia32_broadcasti32x4_256_mask", - "avx512.mask.broadcasti32x4.512" => "__builtin_ia32_broadcasti32x4_512", - "avx512.mask.broadcasti32x8.512" => "__builtin_ia32_broadcasti32x8_512_mask", - "avx512.mask.broadcasti64x2.256" => "__builtin_ia32_broadcasti64x2_256_mask", - "avx512.mask.broadcasti64x2.512" => "__builtin_ia32_broadcasti64x2_512_mask", - "avx512.mask.broadcasti64x4.512" => "__builtin_ia32_broadcasti64x4_512", - "avx512.mask.cmp.pd.128" => "__builtin_ia32_cmppd128_mask", - "avx512.mask.cmp.pd.256" => "__builtin_ia32_cmppd256_mask", - "avx512.mask.cmp.pd.512" => "__builtin_ia32_cmppd512_mask", - "avx512.mask.cmp.ps.128" => "__builtin_ia32_cmpps128_mask", - "avx512.mask.cmp.ps.256" => "__builtin_ia32_cmpps256_mask", - "avx512.mask.cmp.ps.512" => "__builtin_ia32_cmpps512_mask", "avx512.mask.cmp.sd" => "__builtin_ia32_cmpsd_mask", "avx512.mask.cmp.ss" => "__builtin_ia32_cmpss_mask", - "avx512.mask.compress.d.128" => "__builtin_ia32_compresssi128_mask", - "avx512.mask.compress.d.256" => "__builtin_ia32_compresssi256_mask", - "avx512.mask.compress.d.512" => "__builtin_ia32_compresssi512_mask", - "avx512.mask.compress.pd.128" => "__builtin_ia32_compressdf128_mask", - "avx512.mask.compress.pd.256" => "__builtin_ia32_compressdf256_mask", - "avx512.mask.compress.pd.512" => "__builtin_ia32_compressdf512_mask", - "avx512.mask.compress.ps.128" => "__builtin_ia32_compresssf128_mask", - "avx512.mask.compress.ps.256" => "__builtin_ia32_compresssf256_mask", - "avx512.mask.compress.ps.512" => "__builtin_ia32_compresssf512_mask", - "avx512.mask.compress.q.128" => "__builtin_ia32_compressdi128_mask", - "avx512.mask.compress.q.256" => "__builtin_ia32_compressdi256_mask", - "avx512.mask.compress.q.512" => "__builtin_ia32_compressdi512_mask", - "avx512.mask.compress.store.d.128" => "__builtin_ia32_compressstoresi128_mask", - "avx512.mask.compress.store.d.256" => "__builtin_ia32_compressstoresi256_mask", - "avx512.mask.compress.store.d.512" => "__builtin_ia32_compressstoresi512_mask", - "avx512.mask.compress.store.pd.128" => "__builtin_ia32_compressstoredf128_mask", - "avx512.mask.compress.store.pd.256" => "__builtin_ia32_compressstoredf256_mask", - "avx512.mask.compress.store.pd.512" => "__builtin_ia32_compressstoredf512_mask", - "avx512.mask.compress.store.ps.128" => "__builtin_ia32_compressstoresf128_mask", - "avx512.mask.compress.store.ps.256" => "__builtin_ia32_compressstoresf256_mask", - "avx512.mask.compress.store.ps.512" => "__builtin_ia32_compressstoresf512_mask", - "avx512.mask.compress.store.q.128" => "__builtin_ia32_compressstoredi128_mask", - "avx512.mask.compress.store.q.256" => "__builtin_ia32_compressstoredi256_mask", - "avx512.mask.compress.store.q.512" => "__builtin_ia32_compressstoredi512_mask", - "avx512.mask.conflict.d.128" => "__builtin_ia32_vpconflictsi_128_mask", - "avx512.mask.conflict.d.256" => "__builtin_ia32_vpconflictsi_256_mask", - "avx512.mask.conflict.d.512" => "__builtin_ia32_vpconflictsi_512_mask", - "avx512.mask.conflict.q.128" => "__builtin_ia32_vpconflictdi_128_mask", - "avx512.mask.conflict.q.256" => "__builtin_ia32_vpconflictdi_256_mask", - "avx512.mask.conflict.q.512" => "__builtin_ia32_vpconflictdi_512_mask", - "avx512.mask.cvtdq2pd.128" => "__builtin_ia32_cvtdq2pd128_mask", - "avx512.mask.cvtdq2pd.256" => "__builtin_ia32_cvtdq2pd256_mask", - "avx512.mask.cvtdq2pd.512" => "__builtin_ia32_cvtdq2pd512_mask", - "avx512.mask.cvtdq2ps.128" => "__builtin_ia32_cvtdq2ps128_mask", - "avx512.mask.cvtdq2ps.256" => "__builtin_ia32_cvtdq2ps256_mask", - "avx512.mask.cvtdq2ps.512" => "__builtin_ia32_cvtdq2ps512_mask", "avx512.mask.cvtpd2dq.128" => "__builtin_ia32_cvtpd2dq128_mask", - "avx512.mask.cvtpd2dq.256" => "__builtin_ia32_cvtpd2dq256_mask", "avx512.mask.cvtpd2dq.512" => "__builtin_ia32_cvtpd2dq512_mask", "avx512.mask.cvtpd2ps" => "__builtin_ia32_cvtpd2ps_mask", - "avx512.mask.cvtpd2ps.256" => "__builtin_ia32_cvtpd2ps256_mask", "avx512.mask.cvtpd2ps.512" => "__builtin_ia32_cvtpd2ps512_mask", "avx512.mask.cvtpd2qq.128" => "__builtin_ia32_cvtpd2qq128_mask", "avx512.mask.cvtpd2qq.256" => "__builtin_ia32_cvtpd2qq256_mask", @@ -8616,8 +8128,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.cvtps2dq.128" => "__builtin_ia32_cvtps2dq128_mask", "avx512.mask.cvtps2dq.256" => "__builtin_ia32_cvtps2dq256_mask", "avx512.mask.cvtps2dq.512" => "__builtin_ia32_cvtps2dq512_mask", - "avx512.mask.cvtps2pd.128" => "__builtin_ia32_cvtps2pd128_mask", - "avx512.mask.cvtps2pd.256" => "__builtin_ia32_cvtps2pd256_mask", "avx512.mask.cvtps2pd.512" => "__builtin_ia32_cvtps2pd512_mask", "avx512.mask.cvtps2qq.128" => "__builtin_ia32_cvtps2qq128_mask", "avx512.mask.cvtps2qq.256" => "__builtin_ia32_cvtps2qq256_mask", @@ -8628,16 +8138,10 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.cvtps2uqq.128" => "__builtin_ia32_cvtps2uqq128_mask", "avx512.mask.cvtps2uqq.256" => "__builtin_ia32_cvtps2uqq256_mask", "avx512.mask.cvtps2uqq.512" => "__builtin_ia32_cvtps2uqq512_mask", - "avx512.mask.cvtqq2pd.128" => "__builtin_ia32_cvtqq2pd128_mask", - "avx512.mask.cvtqq2pd.256" => "__builtin_ia32_cvtqq2pd256_mask", - "avx512.mask.cvtqq2pd.512" => "__builtin_ia32_cvtqq2pd512_mask", "avx512.mask.cvtqq2ps.128" => "__builtin_ia32_cvtqq2ps128_mask", - "avx512.mask.cvtqq2ps.256" => "__builtin_ia32_cvtqq2ps256_mask", - "avx512.mask.cvtqq2ps.512" => "__builtin_ia32_cvtqq2ps512_mask", // [INVALID CONVERSION]: "avx512.mask.cvtsd2ss.round" => "__builtin_ia32_cvtsd2ss_round_mask", // [INVALID CONVERSION]: "avx512.mask.cvtss2sd.round" => "__builtin_ia32_cvtss2sd_round_mask", "avx512.mask.cvttpd2dq.128" => "__builtin_ia32_cvttpd2dq128_mask", - "avx512.mask.cvttpd2dq.256" => "__builtin_ia32_cvttpd2dq256_mask", "avx512.mask.cvttpd2dq.512" => "__builtin_ia32_cvttpd2dq512_mask", "avx512.mask.cvttpd2qq.128" => "__builtin_ia32_cvttpd2qq128_mask", "avx512.mask.cvttpd2qq.256" => "__builtin_ia32_cvttpd2qq256_mask", @@ -8648,8 +8152,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.cvttpd2uqq.128" => "__builtin_ia32_cvttpd2uqq128_mask", "avx512.mask.cvttpd2uqq.256" => "__builtin_ia32_cvttpd2uqq256_mask", "avx512.mask.cvttpd2uqq.512" => "__builtin_ia32_cvttpd2uqq512_mask", - "avx512.mask.cvttps2dq.128" => "__builtin_ia32_cvttps2dq128_mask", - "avx512.mask.cvttps2dq.256" => "__builtin_ia32_cvttps2dq256_mask", "avx512.mask.cvttps2dq.512" => "__builtin_ia32_cvttps2dq512_mask", "avx512.mask.cvttps2qq.128" => "__builtin_ia32_cvttps2qq128_mask", "avx512.mask.cvttps2qq.256" => "__builtin_ia32_cvttps2qq256_mask", @@ -8660,53 +8162,9 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.cvttps2uqq.128" => "__builtin_ia32_cvttps2uqq128_mask", "avx512.mask.cvttps2uqq.256" => "__builtin_ia32_cvttps2uqq256_mask", "avx512.mask.cvttps2uqq.512" => "__builtin_ia32_cvttps2uqq512_mask", - "avx512.mask.cvtudq2pd.128" => "__builtin_ia32_cvtudq2pd128_mask", - "avx512.mask.cvtudq2pd.256" => "__builtin_ia32_cvtudq2pd256_mask", - "avx512.mask.cvtudq2pd.512" => "__builtin_ia32_cvtudq2pd512_mask", - "avx512.mask.cvtudq2ps.128" => "__builtin_ia32_cvtudq2ps128_mask", - "avx512.mask.cvtudq2ps.256" => "__builtin_ia32_cvtudq2ps256_mask", - "avx512.mask.cvtudq2ps.512" => "__builtin_ia32_cvtudq2ps512_mask", - "avx512.mask.cvtuqq2pd.128" => "__builtin_ia32_cvtuqq2pd128_mask", - "avx512.mask.cvtuqq2pd.256" => "__builtin_ia32_cvtuqq2pd256_mask", - "avx512.mask.cvtuqq2pd.512" => "__builtin_ia32_cvtuqq2pd512_mask", "avx512.mask.cvtuqq2ps.128" => "__builtin_ia32_cvtuqq2ps128_mask", - "avx512.mask.cvtuqq2ps.256" => "__builtin_ia32_cvtuqq2ps256_mask", - "avx512.mask.cvtuqq2ps.512" => "__builtin_ia32_cvtuqq2ps512_mask", - "avx512.mask.dbpsadbw.128" => "__builtin_ia32_dbpsadbw128_mask", - "avx512.mask.dbpsadbw.256" => "__builtin_ia32_dbpsadbw256_mask", - "avx512.mask.dbpsadbw.512" => "__builtin_ia32_dbpsadbw512_mask", - "avx512.mask.div.pd.128" => "__builtin_ia32_divpd_mask", - "avx512.mask.div.pd.256" => "__builtin_ia32_divpd256_mask", - "avx512.mask.div.pd.512" => "__builtin_ia32_divpd512_mask", - "avx512.mask.div.ps.128" => "__builtin_ia32_divps_mask", - "avx512.mask.div.ps.256" => "__builtin_ia32_divps256_mask", - "avx512.mask.div.ps.512" => "__builtin_ia32_divps512_mask", // [INVALID CONVERSION]: "avx512.mask.div.sd.round" => "__builtin_ia32_divsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.div.ss.round" => "__builtin_ia32_divss_round_mask", - "avx512.mask.expand.d.128" => "__builtin_ia32_expandsi128_mask", - "avx512.mask.expand.d.256" => "__builtin_ia32_expandsi256_mask", - "avx512.mask.expand.d.512" => "__builtin_ia32_expandsi512_mask", - "avx512.mask.expand.load.d.128" => "__builtin_ia32_expandloadsi128_mask", - "avx512.mask.expand.load.d.256" => "__builtin_ia32_expandloadsi256_mask", - "avx512.mask.expand.load.d.512" => "__builtin_ia32_expandloadsi512_mask", - "avx512.mask.expand.load.pd.128" => "__builtin_ia32_expandloaddf128_mask", - "avx512.mask.expand.load.pd.256" => "__builtin_ia32_expandloaddf256_mask", - "avx512.mask.expand.load.pd.512" => "__builtin_ia32_expandloaddf512_mask", - "avx512.mask.expand.load.ps.128" => "__builtin_ia32_expandloadsf128_mask", - "avx512.mask.expand.load.ps.256" => "__builtin_ia32_expandloadsf256_mask", - "avx512.mask.expand.load.ps.512" => "__builtin_ia32_expandloadsf512_mask", - "avx512.mask.expand.load.q.128" => "__builtin_ia32_expandloaddi128_mask", - "avx512.mask.expand.load.q.256" => "__builtin_ia32_expandloaddi256_mask", - "avx512.mask.expand.load.q.512" => "__builtin_ia32_expandloaddi512_mask", - "avx512.mask.expand.pd.128" => "__builtin_ia32_expanddf128_mask", - "avx512.mask.expand.pd.256" => "__builtin_ia32_expanddf256_mask", - "avx512.mask.expand.pd.512" => "__builtin_ia32_expanddf512_mask", - "avx512.mask.expand.ps.128" => "__builtin_ia32_expandsf128_mask", - "avx512.mask.expand.ps.256" => "__builtin_ia32_expandsf256_mask", - "avx512.mask.expand.ps.512" => "__builtin_ia32_expandsf512_mask", - "avx512.mask.expand.q.128" => "__builtin_ia32_expanddi128_mask", - "avx512.mask.expand.q.256" => "__builtin_ia32_expanddi256_mask", - "avx512.mask.expand.q.512" => "__builtin_ia32_expanddi512_mask", "avx512.mask.fixupimm.pd.128" => "__builtin_ia32_fixupimmpd128_mask", "avx512.mask.fixupimm.pd.256" => "__builtin_ia32_fixupimmpd256_mask", "avx512.mask.fixupimm.pd.512" => "__builtin_ia32_fixupimmpd512_mask", @@ -8715,12 +8173,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.fixupimm.ps.512" => "__builtin_ia32_fixupimmps512_mask", "avx512.mask.fixupimm.sd" => "__builtin_ia32_fixupimmsd_mask", "avx512.mask.fixupimm.ss" => "__builtin_ia32_fixupimmss_mask", - "avx512.mask.fpclass.pd.128" => "__builtin_ia32_fpclasspd128_mask", - "avx512.mask.fpclass.pd.256" => "__builtin_ia32_fpclasspd256_mask", - "avx512.mask.fpclass.pd.512" => "__builtin_ia32_fpclasspd512_mask", - "avx512.mask.fpclass.ps.128" => "__builtin_ia32_fpclassps128_mask", - "avx512.mask.fpclass.ps.256" => "__builtin_ia32_fpclassps256_mask", - "avx512.mask.fpclass.ps.512" => "__builtin_ia32_fpclassps512_mask", "avx512.mask.fpclass.sd" => "__builtin_ia32_fpclasssd_mask", "avx512.mask.fpclass.ss" => "__builtin_ia32_fpclassss_mask", "avx512.mask.getexp.pd.128" => "__builtin_ia32_getexppd128_mask", @@ -8739,226 +8191,19 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.getmant.ps.512" => "__builtin_ia32_getmantps512_mask", // [INVALID CONVERSION]: "avx512.mask.getmant.sd" => "__builtin_ia32_getmantsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.getmant.ss" => "__builtin_ia32_getmantss_round_mask", - "avx512.mask.insertf32x4.256" => "__builtin_ia32_insertf32x4_256_mask", - "avx512.mask.insertf32x4.512" => "__builtin_ia32_insertf32x4_mask", - "avx512.mask.insertf32x8.512" => "__builtin_ia32_insertf32x8_mask", - "avx512.mask.insertf64x2.256" => "__builtin_ia32_insertf64x2_256_mask", - "avx512.mask.insertf64x2.512" => "__builtin_ia32_insertf64x2_512_mask", - "avx512.mask.insertf64x4.512" => "__builtin_ia32_insertf64x4_mask", - "avx512.mask.inserti32x4.256" => "__builtin_ia32_inserti32x4_256_mask", - "avx512.mask.inserti32x4.512" => "__builtin_ia32_inserti32x4_mask", - "avx512.mask.inserti32x8.512" => "__builtin_ia32_inserti32x8_mask", - "avx512.mask.inserti64x2.256" => "__builtin_ia32_inserti64x2_256_mask", - "avx512.mask.inserti64x2.512" => "__builtin_ia32_inserti64x2_512_mask", - "avx512.mask.inserti64x4.512" => "__builtin_ia32_inserti64x4_mask", - "avx512.mask.loadu.d.512" => "__builtin_ia32_loaddqusi512_mask", - "avx512.mask.loadu.pd.512" => "__builtin_ia32_loadupd512_mask", - "avx512.mask.loadu.ps.512" => "__builtin_ia32_loadups512_mask", - "avx512.mask.loadu.q.512" => "__builtin_ia32_loaddqudi512_mask", - "avx512.mask.lzcnt.d.512" => "__builtin_ia32_vplzcntd_512_mask", - "avx512.mask.lzcnt.q.512" => "__builtin_ia32_vplzcntq_512_mask", - "avx512.mask.max.pd.128" => "__builtin_ia32_maxpd_mask", - "avx512.mask.max.pd.256" => "__builtin_ia32_maxpd256_mask", - "avx512.mask.max.pd.512" => "__builtin_ia32_maxpd512_mask", - "avx512.mask.max.ps.128" => "__builtin_ia32_maxps_mask", - "avx512.mask.max.ps.256" => "__builtin_ia32_maxps256_mask", - "avx512.mask.max.ps.512" => "__builtin_ia32_maxps512_mask", // [INVALID CONVERSION]: "avx512.mask.max.sd.round" => "__builtin_ia32_maxsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.max.ss.round" => "__builtin_ia32_maxss_round_mask", - "avx512.mask.min.pd.128" => "__builtin_ia32_minpd_mask", - "avx512.mask.min.pd.256" => "__builtin_ia32_minpd256_mask", - "avx512.mask.min.pd.512" => "__builtin_ia32_minpd512_mask", - "avx512.mask.min.ps.128" => "__builtin_ia32_minps_mask", - "avx512.mask.min.ps.256" => "__builtin_ia32_minps256_mask", - "avx512.mask.min.ps.512" => "__builtin_ia32_minps512_mask", // [INVALID CONVERSION]: "avx512.mask.min.sd.round" => "__builtin_ia32_minsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.min.ss.round" => "__builtin_ia32_minss_round_mask", - "avx512.mask.move.sd" => "__builtin_ia32_movsd_mask", - "avx512.mask.move.ss" => "__builtin_ia32_movss_mask", - "avx512.mask.mul.pd.128" => "__builtin_ia32_mulpd_mask", - "avx512.mask.mul.pd.256" => "__builtin_ia32_mulpd256_mask", - "avx512.mask.mul.pd.512" => "__builtin_ia32_mulpd512_mask", - "avx512.mask.mul.ps.128" => "__builtin_ia32_mulps_mask", - "avx512.mask.mul.ps.256" => "__builtin_ia32_mulps256_mask", - "avx512.mask.mul.ps.512" => "__builtin_ia32_mulps512_mask", // [INVALID CONVERSION]: "avx512.mask.mul.sd.round" => "__builtin_ia32_mulsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.mul.ss.round" => "__builtin_ia32_mulss_round_mask", - "avx512.mask.or.pd.128" => "__builtin_ia32_orpd128_mask", - "avx512.mask.or.pd.256" => "__builtin_ia32_orpd256_mask", - "avx512.mask.or.pd.512" => "__builtin_ia32_orpd512_mask", - "avx512.mask.or.ps.128" => "__builtin_ia32_orps128_mask", - "avx512.mask.or.ps.256" => "__builtin_ia32_orps256_mask", - "avx512.mask.or.ps.512" => "__builtin_ia32_orps512_mask", - "avx512.mask.pabs.b.128" => "__builtin_ia32_pabsb128_mask", - "avx512.mask.pabs.b.256" => "__builtin_ia32_pabsb256_mask", - "avx512.mask.pabs.b.512" => "__builtin_ia32_pabsb512_mask", - "avx512.mask.pabs.d.128" => "__builtin_ia32_pabsd128_mask", - "avx512.mask.pabs.d.256" => "__builtin_ia32_pabsd256_mask", - "avx512.mask.pabs.d.512" => "__builtin_ia32_pabsd512_mask", - "avx512.mask.pabs.q.128" => "__builtin_ia32_pabsq128_mask", - "avx512.mask.pabs.q.256" => "__builtin_ia32_pabsq256_mask", - "avx512.mask.pabs.q.512" => "__builtin_ia32_pabsq512_mask", - "avx512.mask.pabs.w.128" => "__builtin_ia32_pabsw128_mask", - "avx512.mask.pabs.w.256" => "__builtin_ia32_pabsw256_mask", - "avx512.mask.pabs.w.512" => "__builtin_ia32_pabsw512_mask", - "avx512.mask.packssdw.128" => "__builtin_ia32_packssdw128_mask", - "avx512.mask.packssdw.256" => "__builtin_ia32_packssdw256_mask", - "avx512.mask.packssdw.512" => "__builtin_ia32_packssdw512_mask", - "avx512.mask.packsswb.128" => "__builtin_ia32_packsswb128_mask", - "avx512.mask.packsswb.256" => "__builtin_ia32_packsswb256_mask", - "avx512.mask.packsswb.512" => "__builtin_ia32_packsswb512_mask", - "avx512.mask.packusdw.128" => "__builtin_ia32_packusdw128_mask", - "avx512.mask.packusdw.256" => "__builtin_ia32_packusdw256_mask", - "avx512.mask.packusdw.512" => "__builtin_ia32_packusdw512_mask", - "avx512.mask.packuswb.128" => "__builtin_ia32_packuswb128_mask", - "avx512.mask.packuswb.256" => "__builtin_ia32_packuswb256_mask", - "avx512.mask.packuswb.512" => "__builtin_ia32_packuswb512_mask", - "avx512.mask.padd.b.128" => "__builtin_ia32_paddb128_mask", - "avx512.mask.padd.b.256" => "__builtin_ia32_paddb256_mask", - "avx512.mask.padd.b.512" => "__builtin_ia32_paddb512_mask", - "avx512.mask.padd.d.128" => "__builtin_ia32_paddd128_mask", - "avx512.mask.padd.d.256" => "__builtin_ia32_paddd256_mask", - "avx512.mask.padd.d.512" => "__builtin_ia32_paddd512_mask", - "avx512.mask.padd.q.128" => "__builtin_ia32_paddq128_mask", - "avx512.mask.padd.q.256" => "__builtin_ia32_paddq256_mask", - "avx512.mask.padd.q.512" => "__builtin_ia32_paddq512_mask", - "avx512.mask.padd.w.128" => "__builtin_ia32_paddw128_mask", - "avx512.mask.padd.w.256" => "__builtin_ia32_paddw256_mask", - "avx512.mask.padd.w.512" => "__builtin_ia32_paddw512_mask", - "avx512.mask.padds.b.128" => "__builtin_ia32_paddsb128_mask", - "avx512.mask.padds.b.256" => "__builtin_ia32_paddsb256_mask", - "avx512.mask.padds.b.512" => "__builtin_ia32_paddsb512_mask", - "avx512.mask.padds.w.128" => "__builtin_ia32_paddsw128_mask", - "avx512.mask.padds.w.256" => "__builtin_ia32_paddsw256_mask", - "avx512.mask.padds.w.512" => "__builtin_ia32_paddsw512_mask", - "avx512.mask.paddus.b.128" => "__builtin_ia32_paddusb128_mask", - "avx512.mask.paddus.b.256" => "__builtin_ia32_paddusb256_mask", - "avx512.mask.paddus.b.512" => "__builtin_ia32_paddusb512_mask", - "avx512.mask.paddus.w.128" => "__builtin_ia32_paddusw128_mask", - "avx512.mask.paddus.w.256" => "__builtin_ia32_paddusw256_mask", - "avx512.mask.paddus.w.512" => "__builtin_ia32_paddusw512_mask", - "avx512.mask.pand.d.512" => "__builtin_ia32_pandd512_mask", - "avx512.mask.pand.q.512" => "__builtin_ia32_pandq512_mask", - "avx512.mask.pavg.b.128" => "__builtin_ia32_pavgb128_mask", - "avx512.mask.pavg.b.256" => "__builtin_ia32_pavgb256_mask", - "avx512.mask.pavg.b.512" => "__builtin_ia32_pavgb512_mask", - "avx512.mask.pavg.w.128" => "__builtin_ia32_pavgw128_mask", - "avx512.mask.pavg.w.256" => "__builtin_ia32_pavgw256_mask", - "avx512.mask.pavg.w.512" => "__builtin_ia32_pavgw512_mask", - "avx512.mask.pbroadcast.b.gpr.128" => "__builtin_ia32_pbroadcastb128_gpr_mask", - "avx512.mask.pbroadcast.b.gpr.256" => "__builtin_ia32_pbroadcastb256_gpr_mask", - "avx512.mask.pbroadcast.b.gpr.512" => "__builtin_ia32_pbroadcastb512_gpr_mask", - "avx512.mask.pbroadcast.d.gpr.128" => "__builtin_ia32_pbroadcastd128_gpr_mask", - "avx512.mask.pbroadcast.d.gpr.256" => "__builtin_ia32_pbroadcastd256_gpr_mask", - "avx512.mask.pbroadcast.d.gpr.512" => "__builtin_ia32_pbroadcastd512_gpr_mask", - "avx512.mask.pbroadcast.q.gpr.128" => "__builtin_ia32_pbroadcastq128_gpr_mask", - "avx512.mask.pbroadcast.q.gpr.256" => "__builtin_ia32_pbroadcastq256_gpr_mask", - "avx512.mask.pbroadcast.q.gpr.512" => "__builtin_ia32_pbroadcastq512_gpr_mask", - "avx512.mask.pbroadcast.q.mem.512" => "__builtin_ia32_pbroadcastq512_mem_mask", - "avx512.mask.pbroadcast.w.gpr.128" => "__builtin_ia32_pbroadcastw128_gpr_mask", - "avx512.mask.pbroadcast.w.gpr.256" => "__builtin_ia32_pbroadcastw256_gpr_mask", - "avx512.mask.pbroadcast.w.gpr.512" => "__builtin_ia32_pbroadcastw512_gpr_mask", - "avx512.mask.pcmpeq.b.128" => "__builtin_ia32_pcmpeqb128_mask", - "avx512.mask.pcmpeq.b.256" => "__builtin_ia32_pcmpeqb256_mask", - "avx512.mask.pcmpeq.b.512" => "__builtin_ia32_pcmpeqb512_mask", - "avx512.mask.pcmpeq.d.128" => "__builtin_ia32_pcmpeqd128_mask", - "avx512.mask.pcmpeq.d.256" => "__builtin_ia32_pcmpeqd256_mask", - "avx512.mask.pcmpeq.d.512" => "__builtin_ia32_pcmpeqd512_mask", - "avx512.mask.pcmpeq.q.128" => "__builtin_ia32_pcmpeqq128_mask", - "avx512.mask.pcmpeq.q.256" => "__builtin_ia32_pcmpeqq256_mask", - "avx512.mask.pcmpeq.q.512" => "__builtin_ia32_pcmpeqq512_mask", - "avx512.mask.pcmpeq.w.128" => "__builtin_ia32_pcmpeqw128_mask", - "avx512.mask.pcmpeq.w.256" => "__builtin_ia32_pcmpeqw256_mask", - "avx512.mask.pcmpeq.w.512" => "__builtin_ia32_pcmpeqw512_mask", - "avx512.mask.pcmpgt.b.128" => "__builtin_ia32_pcmpgtb128_mask", - "avx512.mask.pcmpgt.b.256" => "__builtin_ia32_pcmpgtb256_mask", - "avx512.mask.pcmpgt.b.512" => "__builtin_ia32_pcmpgtb512_mask", - "avx512.mask.pcmpgt.d.128" => "__builtin_ia32_pcmpgtd128_mask", - "avx512.mask.pcmpgt.d.256" => "__builtin_ia32_pcmpgtd256_mask", - "avx512.mask.pcmpgt.d.512" => "__builtin_ia32_pcmpgtd512_mask", - "avx512.mask.pcmpgt.q.128" => "__builtin_ia32_pcmpgtq128_mask", - "avx512.mask.pcmpgt.q.256" => "__builtin_ia32_pcmpgtq256_mask", - "avx512.mask.pcmpgt.q.512" => "__builtin_ia32_pcmpgtq512_mask", - "avx512.mask.pcmpgt.w.128" => "__builtin_ia32_pcmpgtw128_mask", - "avx512.mask.pcmpgt.w.256" => "__builtin_ia32_pcmpgtw256_mask", - "avx512.mask.pcmpgt.w.512" => "__builtin_ia32_pcmpgtw512_mask", - "avx512.mask.permvar.df.256" => "__builtin_ia32_permvardf256_mask", - "avx512.mask.permvar.df.512" => "__builtin_ia32_permvardf512_mask", - "avx512.mask.permvar.di.256" => "__builtin_ia32_permvardi256_mask", - "avx512.mask.permvar.di.512" => "__builtin_ia32_permvardi512_mask", - "avx512.mask.permvar.hi.128" => "__builtin_ia32_permvarhi128_mask", - "avx512.mask.permvar.hi.256" => "__builtin_ia32_permvarhi256_mask", - "avx512.mask.permvar.hi.512" => "__builtin_ia32_permvarhi512_mask", - "avx512.mask.permvar.qi.128" => "__builtin_ia32_permvarqi128_mask", - "avx512.mask.permvar.qi.256" => "__builtin_ia32_permvarqi256_mask", - "avx512.mask.permvar.qi.512" => "__builtin_ia32_permvarqi512_mask", - "avx512.mask.permvar.sf.256" => "__builtin_ia32_permvarsf256_mask", - "avx512.mask.permvar.sf.512" => "__builtin_ia32_permvarsf512_mask", - "avx512.mask.permvar.si.256" => "__builtin_ia32_permvarsi256_mask", - "avx512.mask.permvar.si.512" => "__builtin_ia32_permvarsi512_mask", - "avx512.mask.pmaddubs.w.128" => "__builtin_ia32_pmaddubsw128_mask", - "avx512.mask.pmaddubs.w.256" => "__builtin_ia32_pmaddubsw256_mask", - "avx512.mask.pmaddubs.w.512" => "__builtin_ia32_pmaddubsw512_mask", - "avx512.mask.pmaddw.d.128" => "__builtin_ia32_pmaddwd128_mask", - "avx512.mask.pmaddw.d.256" => "__builtin_ia32_pmaddwd256_mask", - "avx512.mask.pmaddw.d.512" => "__builtin_ia32_pmaddwd512_mask", - "avx512.mask.pmaxs.b.128" => "__builtin_ia32_pmaxsb128_mask", - "avx512.mask.pmaxs.b.256" => "__builtin_ia32_pmaxsb256_mask", - "avx512.mask.pmaxs.b.512" => "__builtin_ia32_pmaxsb512_mask", - "avx512.mask.pmaxs.d.128" => "__builtin_ia32_pmaxsd128_mask", - "avx512.mask.pmaxs.d.256" => "__builtin_ia32_pmaxsd256_mask", - "avx512.mask.pmaxs.d.512" => "__builtin_ia32_pmaxsd512_mask", - "avx512.mask.pmaxs.q.128" => "__builtin_ia32_pmaxsq128_mask", - "avx512.mask.pmaxs.q.256" => "__builtin_ia32_pmaxsq256_mask", - "avx512.mask.pmaxs.q.512" => "__builtin_ia32_pmaxsq512_mask", - "avx512.mask.pmaxs.w.128" => "__builtin_ia32_pmaxsw128_mask", - "avx512.mask.pmaxs.w.256" => "__builtin_ia32_pmaxsw256_mask", - "avx512.mask.pmaxs.w.512" => "__builtin_ia32_pmaxsw512_mask", - "avx512.mask.pmaxu.b.128" => "__builtin_ia32_pmaxub128_mask", - "avx512.mask.pmaxu.b.256" => "__builtin_ia32_pmaxub256_mask", - "avx512.mask.pmaxu.b.512" => "__builtin_ia32_pmaxub512_mask", - "avx512.mask.pmaxu.d.128" => "__builtin_ia32_pmaxud128_mask", - "avx512.mask.pmaxu.d.256" => "__builtin_ia32_pmaxud256_mask", - "avx512.mask.pmaxu.d.512" => "__builtin_ia32_pmaxud512_mask", - "avx512.mask.pmaxu.q.128" => "__builtin_ia32_pmaxuq128_mask", - "avx512.mask.pmaxu.q.256" => "__builtin_ia32_pmaxuq256_mask", - "avx512.mask.pmaxu.q.512" => "__builtin_ia32_pmaxuq512_mask", - "avx512.mask.pmaxu.w.128" => "__builtin_ia32_pmaxuw128_mask", - "avx512.mask.pmaxu.w.256" => "__builtin_ia32_pmaxuw256_mask", - "avx512.mask.pmaxu.w.512" => "__builtin_ia32_pmaxuw512_mask", - "avx512.mask.pmins.b.128" => "__builtin_ia32_pminsb128_mask", - "avx512.mask.pmins.b.256" => "__builtin_ia32_pminsb256_mask", - "avx512.mask.pmins.b.512" => "__builtin_ia32_pminsb512_mask", - "avx512.mask.pmins.d.128" => "__builtin_ia32_pminsd128_mask", - "avx512.mask.pmins.d.256" => "__builtin_ia32_pminsd256_mask", - "avx512.mask.pmins.d.512" => "__builtin_ia32_pminsd512_mask", - "avx512.mask.pmins.q.128" => "__builtin_ia32_pminsq128_mask", - "avx512.mask.pmins.q.256" => "__builtin_ia32_pminsq256_mask", - "avx512.mask.pmins.q.512" => "__builtin_ia32_pminsq512_mask", - "avx512.mask.pmins.w.128" => "__builtin_ia32_pminsw128_mask", - "avx512.mask.pmins.w.256" => "__builtin_ia32_pminsw256_mask", - "avx512.mask.pmins.w.512" => "__builtin_ia32_pminsw512_mask", - "avx512.mask.pminu.b.128" => "__builtin_ia32_pminub128_mask", - "avx512.mask.pminu.b.256" => "__builtin_ia32_pminub256_mask", - "avx512.mask.pminu.b.512" => "__builtin_ia32_pminub512_mask", - "avx512.mask.pminu.d.128" => "__builtin_ia32_pminud128_mask", - "avx512.mask.pminu.d.256" => "__builtin_ia32_pminud256_mask", - "avx512.mask.pminu.d.512" => "__builtin_ia32_pminud512_mask", - "avx512.mask.pminu.q.128" => "__builtin_ia32_pminuq128_mask", - "avx512.mask.pminu.q.256" => "__builtin_ia32_pminuq256_mask", - "avx512.mask.pminu.q.512" => "__builtin_ia32_pminuq512_mask", - "avx512.mask.pminu.w.128" => "__builtin_ia32_pminuw128_mask", - "avx512.mask.pminu.w.256" => "__builtin_ia32_pminuw256_mask", - "avx512.mask.pminu.w.512" => "__builtin_ia32_pminuw512_mask", "avx512.mask.pmov.db.128" => "__builtin_ia32_pmovdb128_mask", "avx512.mask.pmov.db.256" => "__builtin_ia32_pmovdb256_mask", - "avx512.mask.pmov.db.512" => "__builtin_ia32_pmovdb512_mask", "avx512.mask.pmov.db.mem.128" => "__builtin_ia32_pmovdb128mem_mask", "avx512.mask.pmov.db.mem.256" => "__builtin_ia32_pmovdb256mem_mask", "avx512.mask.pmov.db.mem.512" => "__builtin_ia32_pmovdb512mem_mask", "avx512.mask.pmov.dw.128" => "__builtin_ia32_pmovdw128_mask", "avx512.mask.pmov.dw.256" => "__builtin_ia32_pmovdw256_mask", - "avx512.mask.pmov.dw.512" => "__builtin_ia32_pmovdw512_mask", "avx512.mask.pmov.dw.mem.128" => "__builtin_ia32_pmovdw128mem_mask", "avx512.mask.pmov.dw.mem.256" => "__builtin_ia32_pmovdw256mem_mask", "avx512.mask.pmov.dw.mem.512" => "__builtin_ia32_pmovdw512mem_mask", @@ -8969,20 +8214,15 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.pmov.qb.mem.256" => "__builtin_ia32_pmovqb256mem_mask", "avx512.mask.pmov.qb.mem.512" => "__builtin_ia32_pmovqb512mem_mask", "avx512.mask.pmov.qd.128" => "__builtin_ia32_pmovqd128_mask", - "avx512.mask.pmov.qd.256" => "__builtin_ia32_pmovqd256_mask", - "avx512.mask.pmov.qd.512" => "__builtin_ia32_pmovqd512_mask", "avx512.mask.pmov.qd.mem.128" => "__builtin_ia32_pmovqd128mem_mask", "avx512.mask.pmov.qd.mem.256" => "__builtin_ia32_pmovqd256mem_mask", "avx512.mask.pmov.qd.mem.512" => "__builtin_ia32_pmovqd512mem_mask", "avx512.mask.pmov.qw.128" => "__builtin_ia32_pmovqw128_mask", "avx512.mask.pmov.qw.256" => "__builtin_ia32_pmovqw256_mask", - "avx512.mask.pmov.qw.512" => "__builtin_ia32_pmovqw512_mask", "avx512.mask.pmov.qw.mem.128" => "__builtin_ia32_pmovqw128mem_mask", "avx512.mask.pmov.qw.mem.256" => "__builtin_ia32_pmovqw256mem_mask", "avx512.mask.pmov.qw.mem.512" => "__builtin_ia32_pmovqw512mem_mask", "avx512.mask.pmov.wb.128" => "__builtin_ia32_pmovwb128_mask", - "avx512.mask.pmov.wb.256" => "__builtin_ia32_pmovwb256_mask", - "avx512.mask.pmov.wb.512" => "__builtin_ia32_pmovwb512_mask", "avx512.mask.pmov.wb.mem.128" => "__builtin_ia32_pmovwb128mem_mask", "avx512.mask.pmov.wb.mem.256" => "__builtin_ia32_pmovwb256mem_mask", "avx512.mask.pmov.wb.mem.512" => "__builtin_ia32_pmovwb512mem_mask", @@ -9022,24 +8262,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.pmovs.wb.mem.128" => "__builtin_ia32_pmovswb128mem_mask", "avx512.mask.pmovs.wb.mem.256" => "__builtin_ia32_pmovswb256mem_mask", "avx512.mask.pmovs.wb.mem.512" => "__builtin_ia32_pmovswb512mem_mask", - "avx512.mask.pmovsxb.d.128" => "__builtin_ia32_pmovsxbd128_mask", - "avx512.mask.pmovsxb.d.256" => "__builtin_ia32_pmovsxbd256_mask", - "avx512.mask.pmovsxb.d.512" => "__builtin_ia32_pmovsxbd512_mask", - "avx512.mask.pmovsxb.q.128" => "__builtin_ia32_pmovsxbq128_mask", - "avx512.mask.pmovsxb.q.256" => "__builtin_ia32_pmovsxbq256_mask", - "avx512.mask.pmovsxb.q.512" => "__builtin_ia32_pmovsxbq512_mask", - "avx512.mask.pmovsxb.w.128" => "__builtin_ia32_pmovsxbw128_mask", - "avx512.mask.pmovsxb.w.256" => "__builtin_ia32_pmovsxbw256_mask", - "avx512.mask.pmovsxb.w.512" => "__builtin_ia32_pmovsxbw512_mask", - "avx512.mask.pmovsxd.q.128" => "__builtin_ia32_pmovsxdq128_mask", - "avx512.mask.pmovsxd.q.256" => "__builtin_ia32_pmovsxdq256_mask", - "avx512.mask.pmovsxd.q.512" => "__builtin_ia32_pmovsxdq512_mask", - "avx512.mask.pmovsxw.d.128" => "__builtin_ia32_pmovsxwd128_mask", - "avx512.mask.pmovsxw.d.256" => "__builtin_ia32_pmovsxwd256_mask", - "avx512.mask.pmovsxw.d.512" => "__builtin_ia32_pmovsxwd512_mask", - "avx512.mask.pmovsxw.q.128" => "__builtin_ia32_pmovsxwq128_mask", - "avx512.mask.pmovsxw.q.256" => "__builtin_ia32_pmovsxwq256_mask", - "avx512.mask.pmovsxw.q.512" => "__builtin_ia32_pmovsxwq512_mask", "avx512.mask.pmovus.db.128" => "__builtin_ia32_pmovusdb128_mask", "avx512.mask.pmovus.db.256" => "__builtin_ia32_pmovusdb256_mask", "avx512.mask.pmovus.db.512" => "__builtin_ia32_pmovusdb512_mask", @@ -9076,191 +8298,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.pmovus.wb.mem.128" => "__builtin_ia32_pmovuswb128mem_mask", "avx512.mask.pmovus.wb.mem.256" => "__builtin_ia32_pmovuswb256mem_mask", "avx512.mask.pmovus.wb.mem.512" => "__builtin_ia32_pmovuswb512mem_mask", - "avx512.mask.pmovzxb.d.128" => "__builtin_ia32_pmovzxbd128_mask", - "avx512.mask.pmovzxb.d.256" => "__builtin_ia32_pmovzxbd256_mask", - "avx512.mask.pmovzxb.d.512" => "__builtin_ia32_pmovzxbd512_mask", - "avx512.mask.pmovzxb.q.128" => "__builtin_ia32_pmovzxbq128_mask", - "avx512.mask.pmovzxb.q.256" => "__builtin_ia32_pmovzxbq256_mask", - "avx512.mask.pmovzxb.q.512" => "__builtin_ia32_pmovzxbq512_mask", - "avx512.mask.pmovzxb.w.128" => "__builtin_ia32_pmovzxbw128_mask", - "avx512.mask.pmovzxb.w.256" => "__builtin_ia32_pmovzxbw256_mask", - "avx512.mask.pmovzxb.w.512" => "__builtin_ia32_pmovzxbw512_mask", - "avx512.mask.pmovzxd.q.128" => "__builtin_ia32_pmovzxdq128_mask", - "avx512.mask.pmovzxd.q.256" => "__builtin_ia32_pmovzxdq256_mask", - "avx512.mask.pmovzxd.q.512" => "__builtin_ia32_pmovzxdq512_mask", - "avx512.mask.pmovzxw.d.128" => "__builtin_ia32_pmovzxwd128_mask", - "avx512.mask.pmovzxw.d.256" => "__builtin_ia32_pmovzxwd256_mask", - "avx512.mask.pmovzxw.d.512" => "__builtin_ia32_pmovzxwd512_mask", - "avx512.mask.pmovzxw.q.128" => "__builtin_ia32_pmovzxwq128_mask", - "avx512.mask.pmovzxw.q.256" => "__builtin_ia32_pmovzxwq256_mask", - "avx512.mask.pmovzxw.q.512" => "__builtin_ia32_pmovzxwq512_mask", - "avx512.mask.pmul.dq.128" => "__builtin_ia32_pmuldq128_mask", - "avx512.mask.pmul.dq.256" => "__builtin_ia32_pmuldq256_mask", - "avx512.mask.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask", - "avx512.mask.pmul.hr.sw.128" => "__builtin_ia32_pmulhrsw128_mask", - "avx512.mask.pmul.hr.sw.256" => "__builtin_ia32_pmulhrsw256_mask", - "avx512.mask.pmul.hr.sw.512" => "__builtin_ia32_pmulhrsw512_mask", - "avx512.mask.pmulh.w.128" => "__builtin_ia32_pmulhw128_mask", - "avx512.mask.pmulh.w.256" => "__builtin_ia32_pmulhw256_mask", - "avx512.mask.pmulh.w.512" => "__builtin_ia32_pmulhw512_mask", - "avx512.mask.pmulhu.w.128" => "__builtin_ia32_pmulhuw128_mask", - "avx512.mask.pmulhu.w.256" => "__builtin_ia32_pmulhuw256_mask", - "avx512.mask.pmulhu.w.512" => "__builtin_ia32_pmulhuw512_mask", - "avx512.mask.pmull.d.128" => "__builtin_ia32_pmulld128_mask", - "avx512.mask.pmull.d.256" => "__builtin_ia32_pmulld256_mask", - "avx512.mask.pmull.d.512" => "__builtin_ia32_pmulld512_mask", - "avx512.mask.pmull.q.128" => "__builtin_ia32_pmullq128_mask", - "avx512.mask.pmull.q.256" => "__builtin_ia32_pmullq256_mask", - "avx512.mask.pmull.q.512" => "__builtin_ia32_pmullq512_mask", - "avx512.mask.pmull.w.128" => "__builtin_ia32_pmullw128_mask", - "avx512.mask.pmull.w.256" => "__builtin_ia32_pmullw256_mask", - "avx512.mask.pmull.w.512" => "__builtin_ia32_pmullw512_mask", - "avx512.mask.pmultishift.qb.128" => "__builtin_ia32_vpmultishiftqb128_mask", - "avx512.mask.pmultishift.qb.256" => "__builtin_ia32_vpmultishiftqb256_mask", - "avx512.mask.pmultishift.qb.512" => "__builtin_ia32_vpmultishiftqb512_mask", - "avx512.mask.pmulu.dq.128" => "__builtin_ia32_pmuludq128_mask", - "avx512.mask.pmulu.dq.256" => "__builtin_ia32_pmuludq256_mask", - "avx512.mask.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask", - "avx512.mask.prol.d.128" => "__builtin_ia32_prold128_mask", - "avx512.mask.prol.d.256" => "__builtin_ia32_prold256_mask", - "avx512.mask.prol.d.512" => "__builtin_ia32_prold512_mask", - "avx512.mask.prol.q.128" => "__builtin_ia32_prolq128_mask", - "avx512.mask.prol.q.256" => "__builtin_ia32_prolq256_mask", - "avx512.mask.prol.q.512" => "__builtin_ia32_prolq512_mask", - "avx512.mask.prolv.d.128" => "__builtin_ia32_prolvd128_mask", - "avx512.mask.prolv.d.256" => "__builtin_ia32_prolvd256_mask", - "avx512.mask.prolv.d.512" => "__builtin_ia32_prolvd512_mask", - "avx512.mask.prolv.q.128" => "__builtin_ia32_prolvq128_mask", - "avx512.mask.prolv.q.256" => "__builtin_ia32_prolvq256_mask", - "avx512.mask.prolv.q.512" => "__builtin_ia32_prolvq512_mask", - "avx512.mask.pror.d.128" => "__builtin_ia32_prord128_mask", - "avx512.mask.pror.d.256" => "__builtin_ia32_prord256_mask", - "avx512.mask.pror.d.512" => "__builtin_ia32_prord512_mask", - "avx512.mask.pror.q.128" => "__builtin_ia32_prorq128_mask", - "avx512.mask.pror.q.256" => "__builtin_ia32_prorq256_mask", - "avx512.mask.pror.q.512" => "__builtin_ia32_prorq512_mask", - "avx512.mask.prorv.d.128" => "__builtin_ia32_prorvd128_mask", - "avx512.mask.prorv.d.256" => "__builtin_ia32_prorvd256_mask", - "avx512.mask.prorv.d.512" => "__builtin_ia32_prorvd512_mask", - "avx512.mask.prorv.q.128" => "__builtin_ia32_prorvq128_mask", - "avx512.mask.prorv.q.256" => "__builtin_ia32_prorvq256_mask", - "avx512.mask.prorv.q.512" => "__builtin_ia32_prorvq512_mask", - "avx512.mask.pshuf.b.128" => "__builtin_ia32_pshufb128_mask", - "avx512.mask.pshuf.b.256" => "__builtin_ia32_pshufb256_mask", - "avx512.mask.pshuf.b.512" => "__builtin_ia32_pshufb512_mask", - "avx512.mask.psll.d" => "__builtin_ia32_pslld512_mask", - "avx512.mask.psll.d.128" => "__builtin_ia32_pslld128_mask", - "avx512.mask.psll.d.256" => "__builtin_ia32_pslld256_mask", - "avx512.mask.psll.di.128" => "__builtin_ia32_pslldi128_mask", - "avx512.mask.psll.di.256" => "__builtin_ia32_pslldi256_mask", - "avx512.mask.psll.di.512" => "__builtin_ia32_pslldi512_mask", - "avx512.mask.psll.q" => "__builtin_ia32_psllq512_mask", - "avx512.mask.psll.q.128" => "__builtin_ia32_psllq128_mask", - "avx512.mask.psll.q.256" => "__builtin_ia32_psllq256_mask", - "avx512.mask.psll.qi.128" => "__builtin_ia32_psllqi128_mask", - "avx512.mask.psll.qi.256" => "__builtin_ia32_psllqi256_mask", - "avx512.mask.psll.qi.512" => "__builtin_ia32_psllqi512_mask", - "avx512.mask.psll.w.128" => "__builtin_ia32_psllw128_mask", - "avx512.mask.psll.w.256" => "__builtin_ia32_psllw256_mask", - "avx512.mask.psll.w.512" => "__builtin_ia32_psllw512_mask", - "avx512.mask.psll.wi.128" => "__builtin_ia32_psllwi128_mask", - "avx512.mask.psll.wi.256" => "__builtin_ia32_psllwi256_mask", - "avx512.mask.psll.wi.512" => "__builtin_ia32_psllwi512_mask", - "avx512.mask.psllv.d" => "__builtin_ia32_psllv16si_mask", - "avx512.mask.psllv.q" => "__builtin_ia32_psllv8di_mask", - "avx512.mask.psllv16.hi" => "__builtin_ia32_psllv16hi_mask", - "avx512.mask.psllv2.di" => "__builtin_ia32_psllv2di_mask", - "avx512.mask.psllv32hi" => "__builtin_ia32_psllv32hi_mask", - "avx512.mask.psllv4.di" => "__builtin_ia32_psllv4di_mask", - "avx512.mask.psllv4.si" => "__builtin_ia32_psllv4si_mask", - "avx512.mask.psllv8.hi" => "__builtin_ia32_psllv8hi_mask", - "avx512.mask.psllv8.si" => "__builtin_ia32_psllv8si_mask", - "avx512.mask.psra.d" => "__builtin_ia32_psrad512_mask", - "avx512.mask.psra.d.128" => "__builtin_ia32_psrad128_mask", - "avx512.mask.psra.d.256" => "__builtin_ia32_psrad256_mask", - "avx512.mask.psra.di.128" => "__builtin_ia32_psradi128_mask", - "avx512.mask.psra.di.256" => "__builtin_ia32_psradi256_mask", - "avx512.mask.psra.di.512" => "__builtin_ia32_psradi512_mask", - "avx512.mask.psra.q" => "__builtin_ia32_psraq512_mask", - "avx512.mask.psra.q.128" => "__builtin_ia32_psraq128_mask", - "avx512.mask.psra.q.256" => "__builtin_ia32_psraq256_mask", - "avx512.mask.psra.qi.128" => "__builtin_ia32_psraqi128_mask", - "avx512.mask.psra.qi.256" => "__builtin_ia32_psraqi256_mask", - "avx512.mask.psra.qi.512" => "__builtin_ia32_psraqi512_mask", - "avx512.mask.psra.w.128" => "__builtin_ia32_psraw128_mask", - "avx512.mask.psra.w.256" => "__builtin_ia32_psraw256_mask", - "avx512.mask.psra.w.512" => "__builtin_ia32_psraw512_mask", - "avx512.mask.psra.wi.128" => "__builtin_ia32_psrawi128_mask", - "avx512.mask.psra.wi.256" => "__builtin_ia32_psrawi256_mask", - "avx512.mask.psra.wi.512" => "__builtin_ia32_psrawi512_mask", - "avx512.mask.psrav.d" => "__builtin_ia32_psrav16si_mask", - "avx512.mask.psrav.q" => "__builtin_ia32_psrav8di_mask", - "avx512.mask.psrav.q.128" => "__builtin_ia32_psravq128_mask", - "avx512.mask.psrav.q.256" => "__builtin_ia32_psravq256_mask", - "avx512.mask.psrav16.hi" => "__builtin_ia32_psrav16hi_mask", - "avx512.mask.psrav32.hi" => "__builtin_ia32_psrav32hi_mask", - "avx512.mask.psrav4.si" => "__builtin_ia32_psrav4si_mask", - "avx512.mask.psrav8.hi" => "__builtin_ia32_psrav8hi_mask", - "avx512.mask.psrav8.si" => "__builtin_ia32_psrav8si_mask", - "avx512.mask.psrl.d" => "__builtin_ia32_psrld512_mask", - "avx512.mask.psrl.d.128" => "__builtin_ia32_psrld128_mask", - "avx512.mask.psrl.d.256" => "__builtin_ia32_psrld256_mask", - "avx512.mask.psrl.di.128" => "__builtin_ia32_psrldi128_mask", - "avx512.mask.psrl.di.256" => "__builtin_ia32_psrldi256_mask", - "avx512.mask.psrl.di.512" => "__builtin_ia32_psrldi512_mask", - "avx512.mask.psrl.q" => "__builtin_ia32_psrlq512_mask", - "avx512.mask.psrl.q.128" => "__builtin_ia32_psrlq128_mask", - "avx512.mask.psrl.q.256" => "__builtin_ia32_psrlq256_mask", - "avx512.mask.psrl.qi.128" => "__builtin_ia32_psrlqi128_mask", - "avx512.mask.psrl.qi.256" => "__builtin_ia32_psrlqi256_mask", - "avx512.mask.psrl.qi.512" => "__builtin_ia32_psrlqi512_mask", - "avx512.mask.psrl.w.128" => "__builtin_ia32_psrlw128_mask", - "avx512.mask.psrl.w.256" => "__builtin_ia32_psrlw256_mask", - "avx512.mask.psrl.w.512" => "__builtin_ia32_psrlw512_mask", - "avx512.mask.psrl.wi.128" => "__builtin_ia32_psrlwi128_mask", - "avx512.mask.psrl.wi.256" => "__builtin_ia32_psrlwi256_mask", - "avx512.mask.psrl.wi.512" => "__builtin_ia32_psrlwi512_mask", - "avx512.mask.psrlv.d" => "__builtin_ia32_psrlv16si_mask", - "avx512.mask.psrlv.q" => "__builtin_ia32_psrlv8di_mask", - "avx512.mask.psrlv16.hi" => "__builtin_ia32_psrlv16hi_mask", - "avx512.mask.psrlv2.di" => "__builtin_ia32_psrlv2di_mask", - "avx512.mask.psrlv32hi" => "__builtin_ia32_psrlv32hi_mask", - "avx512.mask.psrlv4.di" => "__builtin_ia32_psrlv4di_mask", - "avx512.mask.psrlv4.si" => "__builtin_ia32_psrlv4si_mask", - "avx512.mask.psrlv8.hi" => "__builtin_ia32_psrlv8hi_mask", - "avx512.mask.psrlv8.si" => "__builtin_ia32_psrlv8si_mask", - "avx512.mask.psub.b.128" => "__builtin_ia32_psubb128_mask", - "avx512.mask.psub.b.256" => "__builtin_ia32_psubb256_mask", - "avx512.mask.psub.b.512" => "__builtin_ia32_psubb512_mask", - "avx512.mask.psub.d.128" => "__builtin_ia32_psubd128_mask", - "avx512.mask.psub.d.256" => "__builtin_ia32_psubd256_mask", - "avx512.mask.psub.d.512" => "__builtin_ia32_psubd512_mask", - "avx512.mask.psub.q.128" => "__builtin_ia32_psubq128_mask", - "avx512.mask.psub.q.256" => "__builtin_ia32_psubq256_mask", - "avx512.mask.psub.q.512" => "__builtin_ia32_psubq512_mask", - "avx512.mask.psub.w.128" => "__builtin_ia32_psubw128_mask", - "avx512.mask.psub.w.256" => "__builtin_ia32_psubw256_mask", - "avx512.mask.psub.w.512" => "__builtin_ia32_psubw512_mask", - "avx512.mask.psubs.b.128" => "__builtin_ia32_psubsb128_mask", - "avx512.mask.psubs.b.256" => "__builtin_ia32_psubsb256_mask", - "avx512.mask.psubs.b.512" => "__builtin_ia32_psubsb512_mask", - "avx512.mask.psubs.w.128" => "__builtin_ia32_psubsw128_mask", - "avx512.mask.psubs.w.256" => "__builtin_ia32_psubsw256_mask", - "avx512.mask.psubs.w.512" => "__builtin_ia32_psubsw512_mask", - "avx512.mask.psubus.b.128" => "__builtin_ia32_psubusb128_mask", - "avx512.mask.psubus.b.256" => "__builtin_ia32_psubusb256_mask", - "avx512.mask.psubus.b.512" => "__builtin_ia32_psubusb512_mask", - "avx512.mask.psubus.w.128" => "__builtin_ia32_psubusw128_mask", - "avx512.mask.psubus.w.256" => "__builtin_ia32_psubusw256_mask", - "avx512.mask.psubus.w.512" => "__builtin_ia32_psubusw512_mask", - "avx512.mask.pternlog.d.128" => "__builtin_ia32_pternlogd128_mask", - "avx512.mask.pternlog.d.256" => "__builtin_ia32_pternlogd256_mask", - "avx512.mask.pternlog.d.512" => "__builtin_ia32_pternlogd512_mask", - "avx512.mask.pternlog.q.128" => "__builtin_ia32_pternlogq128_mask", - "avx512.mask.pternlog.q.256" => "__builtin_ia32_pternlogq256_mask", - "avx512.mask.pternlog.q.512" => "__builtin_ia32_pternlogq512_mask", - "avx512.mask.ptestm.d.512" => "__builtin_ia32_ptestmd512", - "avx512.mask.ptestm.q.512" => "__builtin_ia32_ptestmq512", "avx512.mask.range.pd.128" => "__builtin_ia32_rangepd128_mask", "avx512.mask.range.pd.256" => "__builtin_ia32_rangepd256_mask", "avx512.mask.range.pd.512" => "__builtin_ia32_rangepd512_mask", @@ -9293,181 +8330,11 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.scalef.ps.512" => "__builtin_ia32_scalefps512_mask", // [INVALID CONVERSION]: "avx512.mask.scalef.sd" => "__builtin_ia32_scalefsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.scalef.ss" => "__builtin_ia32_scalefss_round_mask", - "avx512.mask.shuf.f32x4" => "__builtin_ia32_shuf_f32x4_mask", - "avx512.mask.shuf.f32x4.256" => "__builtin_ia32_shuf_f32x4_256_mask", - "avx512.mask.shuf.f64x2" => "__builtin_ia32_shuf_f64x2_mask", - "avx512.mask.shuf.f64x2.256" => "__builtin_ia32_shuf_f64x2_256_mask", - "avx512.mask.shuf.i32x4" => "__builtin_ia32_shuf_i32x4_mask", - "avx512.mask.shuf.i32x4.256" => "__builtin_ia32_shuf_i32x4_256_mask", - "avx512.mask.shuf.i64x2" => "__builtin_ia32_shuf_i64x2_mask", - "avx512.mask.shuf.i64x2.256" => "__builtin_ia32_shuf_i64x2_256_mask", - "avx512.mask.shuf.pd.128" => "__builtin_ia32_shufpd128_mask", - "avx512.mask.shuf.pd.256" => "__builtin_ia32_shufpd256_mask", - "avx512.mask.shuf.pd.512" => "__builtin_ia32_shufpd512_mask", - "avx512.mask.shuf.ps.128" => "__builtin_ia32_shufps128_mask", - "avx512.mask.shuf.ps.256" => "__builtin_ia32_shufps256_mask", - "avx512.mask.shuf.ps.512" => "__builtin_ia32_shufps512_mask", - "avx512.mask.sqrt.pd.128" => "__builtin_ia32_sqrtpd128_mask", - "avx512.mask.sqrt.pd.256" => "__builtin_ia32_sqrtpd256_mask", - "avx512.mask.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", - "avx512.mask.sqrt.ps.128" => "__builtin_ia32_sqrtps128_mask", - "avx512.mask.sqrt.ps.256" => "__builtin_ia32_sqrtps256_mask", - "avx512.mask.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", - // [INVALID CONVERSION]: "avx512.mask.sqrt.sd" => "__builtin_ia32_sqrtsd_round_mask", - // [INVALID CONVERSION]: "avx512.mask.sqrt.ss" => "__builtin_ia32_sqrtss_round_mask", - "avx512.mask.store.ss" => "__builtin_ia32_storess_mask", - "avx512.mask.storeu.d.512" => "__builtin_ia32_storedqusi512_mask", - "avx512.mask.storeu.pd.512" => "__builtin_ia32_storeupd512_mask", - "avx512.mask.storeu.ps.512" => "__builtin_ia32_storeups512_mask", - "avx512.mask.storeu.q.512" => "__builtin_ia32_storedqudi512_mask", - "avx512.mask.sub.pd.128" => "__builtin_ia32_subpd128_mask", - "avx512.mask.sub.pd.256" => "__builtin_ia32_subpd256_mask", - "avx512.mask.sub.pd.512" => "__builtin_ia32_subpd512_mask", - "avx512.mask.sub.ps.128" => "__builtin_ia32_subps128_mask", - "avx512.mask.sub.ps.256" => "__builtin_ia32_subps256_mask", - "avx512.mask.sub.ps.512" => "__builtin_ia32_subps512_mask", // [INVALID CONVERSION]: "avx512.mask.sub.sd.round" => "__builtin_ia32_subsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.sub.ss.round" => "__builtin_ia32_subss_round_mask", - "avx512.mask.valign.d.128" => "__builtin_ia32_alignd128_mask", - "avx512.mask.valign.d.256" => "__builtin_ia32_alignd256_mask", - "avx512.mask.valign.d.512" => "__builtin_ia32_alignd512_mask", - "avx512.mask.valign.q.128" => "__builtin_ia32_alignq128_mask", - "avx512.mask.valign.q.256" => "__builtin_ia32_alignq256_mask", - "avx512.mask.valign.q.512" => "__builtin_ia32_alignq512_mask", - "avx512.mask.vcvtph2ps.128" => "__builtin_ia32_vcvtph2ps_mask", - "avx512.mask.vcvtph2ps.256" => "__builtin_ia32_vcvtph2ps256_mask", - "avx512.mask.vcvtph2ps.512" => "__builtin_ia32_vcvtph2ps512_mask", "avx512.mask.vcvtps2ph.128" => "__builtin_ia32_vcvtps2ph_mask", "avx512.mask.vcvtps2ph.256" => "__builtin_ia32_vcvtps2ph256_mask", "avx512.mask.vcvtps2ph.512" => "__builtin_ia32_vcvtps2ph512_mask", - "avx512.mask.vextractf32x4.256" => "__builtin_ia32_extractf32x4_256_mask", - "avx512.mask.vextractf32x4.512" => "__builtin_ia32_extractf32x4_mask", - "avx512.mask.vextractf32x8.512" => "__builtin_ia32_extractf32x8_mask", - "avx512.mask.vextractf64x2.256" => "__builtin_ia32_extractf64x2_256_mask", - "avx512.mask.vextractf64x2.512" => "__builtin_ia32_extractf64x2_512_mask", - "avx512.mask.vextractf64x4.512" => "__builtin_ia32_extractf64x4_mask", - "avx512.mask.vextracti32x4.256" => "__builtin_ia32_extracti32x4_256_mask", - "avx512.mask.vextracti32x4.512" => "__builtin_ia32_extracti32x4_mask", - "avx512.mask.vextracti32x8.512" => "__builtin_ia32_extracti32x8_mask", - "avx512.mask.vextracti64x2.256" => "__builtin_ia32_extracti64x2_256_mask", - "avx512.mask.vextracti64x2.512" => "__builtin_ia32_extracti64x2_512_mask", - "avx512.mask.vextracti64x4.512" => "__builtin_ia32_extracti64x4_mask", - "avx512.mask.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask", - "avx512.mask.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask", - "avx512.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", - "avx512.mask.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask", - "avx512.mask.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask", - "avx512.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", - "avx512.mask.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask", - "avx512.mask.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask", - "avx512.mask.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask", - "avx512.mask.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask", - "avx512.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", - "avx512.mask.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask", - "avx512.mask.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask", - "avx512.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", - "avx512.mask.vfnmadd.pd.128" => "__builtin_ia32_vfnmaddpd128_mask", - "avx512.mask.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256_mask", - "avx512.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", - "avx512.mask.vfnmadd.ps.128" => "__builtin_ia32_vfnmaddps128_mask", - "avx512.mask.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256_mask", - "avx512.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", - "avx512.mask.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask", - "avx512.mask.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask", - "avx512.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", - "avx512.mask.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask", - "avx512.mask.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask", - "avx512.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", - "avx512.mask.vpermi2var.d.128" => "__builtin_ia32_vpermi2vard128_mask", - "avx512.mask.vpermi2var.d.256" => "__builtin_ia32_vpermi2vard256_mask", - "avx512.mask.vpermi2var.d.512" => "__builtin_ia32_vpermi2vard512_mask", - "avx512.mask.vpermi2var.hi.128" => "__builtin_ia32_vpermi2varhi128_mask", - "avx512.mask.vpermi2var.hi.256" => "__builtin_ia32_vpermi2varhi256_mask", - "avx512.mask.vpermi2var.hi.512" => "__builtin_ia32_vpermi2varhi512_mask", - "avx512.mask.vpermi2var.pd.128" => "__builtin_ia32_vpermi2varpd128_mask", - "avx512.mask.vpermi2var.pd.256" => "__builtin_ia32_vpermi2varpd256_mask", - "avx512.mask.vpermi2var.pd.512" => "__builtin_ia32_vpermi2varpd512_mask", - "avx512.mask.vpermi2var.ps.128" => "__builtin_ia32_vpermi2varps128_mask", - "avx512.mask.vpermi2var.ps.256" => "__builtin_ia32_vpermi2varps256_mask", - "avx512.mask.vpermi2var.ps.512" => "__builtin_ia32_vpermi2varps512_mask", - "avx512.mask.vpermi2var.q.128" => "__builtin_ia32_vpermi2varq128_mask", - "avx512.mask.vpermi2var.q.256" => "__builtin_ia32_vpermi2varq256_mask", - "avx512.mask.vpermi2var.q.512" => "__builtin_ia32_vpermi2varq512_mask", - "avx512.mask.vpermi2var.qi.128" => "__builtin_ia32_vpermi2varqi128_mask", - "avx512.mask.vpermi2var.qi.256" => "__builtin_ia32_vpermi2varqi256_mask", - "avx512.mask.vpermi2var.qi.512" => "__builtin_ia32_vpermi2varqi512_mask", - "avx512.mask.vpermilvar.pd.128" => "__builtin_ia32_vpermilvarpd_mask", - "avx512.mask.vpermilvar.pd.256" => "__builtin_ia32_vpermilvarpd256_mask", - "avx512.mask.vpermilvar.pd.512" => "__builtin_ia32_vpermilvarpd512_mask", - "avx512.mask.vpermilvar.ps.128" => "__builtin_ia32_vpermilvarps_mask", - "avx512.mask.vpermilvar.ps.256" => "__builtin_ia32_vpermilvarps256_mask", - "avx512.mask.vpermilvar.ps.512" => "__builtin_ia32_vpermilvarps512_mask", - "avx512.mask.vpermt.d.512" => "__builtin_ia32_vpermt2vard512_mask", - "avx512.mask.vpermt.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", - "avx512.mask.vpermt.ps.512" => "__builtin_ia32_vpermt2varps512_mask", - "avx512.mask.vpermt.q.512" => "__builtin_ia32_vpermt2varq512_mask", - "avx512.mask.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_mask", - "avx512.mask.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_mask", - "avx512.mask.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_mask", - "avx512.mask.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_mask", - "avx512.mask.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_mask", - "avx512.mask.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_mask", - "avx512.mask.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_mask", - "avx512.mask.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_mask", - "avx512.mask.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", - "avx512.mask.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_mask", - "avx512.mask.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_mask", - "avx512.mask.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_mask", - "avx512.mask.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_mask", - "avx512.mask.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_mask", - "avx512.mask.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_mask", - "avx512.mask.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_mask", - "avx512.mask.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_mask", - "avx512.mask.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_mask", - "avx512.mask.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_mask", - "avx512.mask.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_mask", - "avx512.mask.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_mask", - "avx512.mask.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_mask", - "avx512.mask.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_mask", - "avx512.mask.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_mask", - "avx512.mask.xor.pd.128" => "__builtin_ia32_xorpd128_mask", - "avx512.mask.xor.pd.256" => "__builtin_ia32_xorpd256_mask", - "avx512.mask.xor.pd.512" => "__builtin_ia32_xorpd512_mask", - "avx512.mask.xor.ps.128" => "__builtin_ia32_xorps128_mask", - "avx512.mask.xor.ps.256" => "__builtin_ia32_xorps256_mask", - "avx512.mask.xor.ps.512" => "__builtin_ia32_xorps512_mask", - "avx512.mask3.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask3", - "avx512.mask3.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask3", - "avx512.mask3.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask3", - "avx512.mask3.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask3", - "avx512.mask3.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask3", - "avx512.mask3.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask3", - "avx512.mask3.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask3", - "avx512.mask3.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask3", - "avx512.mask3.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask3", - "avx512.mask3.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask3", - "avx512.mask3.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask3", - "avx512.mask3.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask3", - "avx512.mask3.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask3", - "avx512.mask3.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask3", - "avx512.mask3.vfmsub.pd.128" => "__builtin_ia32_vfmsubpd128_mask3", - "avx512.mask3.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256_mask3", - "avx512.mask3.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask3", - "avx512.mask3.vfmsub.ps.128" => "__builtin_ia32_vfmsubps128_mask3", - "avx512.mask3.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256_mask3", - "avx512.mask3.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask3", - "avx512.mask3.vfmsubadd.pd.128" => "__builtin_ia32_vfmsubaddpd128_mask3", - "avx512.mask3.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256_mask3", - "avx512.mask3.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask3", - "avx512.mask3.vfmsubadd.ps.128" => "__builtin_ia32_vfmsubaddps128_mask3", - "avx512.mask3.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256_mask3", - "avx512.mask3.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask3", - "avx512.mask3.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask3", - "avx512.mask3.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask3", - "avx512.mask3.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask3", - "avx512.mask3.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask3", - "avx512.mask3.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask3", - "avx512.mask3.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask3", "avx512.maskz.fixupimm.pd.128" => "__builtin_ia32_fixupimmpd128_maskz", "avx512.maskz.fixupimm.pd.256" => "__builtin_ia32_fixupimmpd256_maskz", "avx512.maskz.fixupimm.pd.512" => "__builtin_ia32_fixupimmpd512_maskz", @@ -9476,55 +8343,10 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.maskz.fixupimm.ps.512" => "__builtin_ia32_fixupimmps512_maskz", "avx512.maskz.fixupimm.sd" => "__builtin_ia32_fixupimmsd_maskz", "avx512.maskz.fixupimm.ss" => "__builtin_ia32_fixupimmss_maskz", - "avx512.maskz.pternlog.d.128" => "__builtin_ia32_pternlogd128_maskz", - "avx512.maskz.pternlog.d.256" => "__builtin_ia32_pternlogd256_maskz", - "avx512.maskz.pternlog.d.512" => "__builtin_ia32_pternlogd512_maskz", - "avx512.maskz.pternlog.q.128" => "__builtin_ia32_pternlogq128_maskz", - "avx512.maskz.pternlog.q.256" => "__builtin_ia32_pternlogq256_maskz", - "avx512.maskz.pternlog.q.512" => "__builtin_ia32_pternlogq512_maskz", - "avx512.maskz.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_maskz", - "avx512.maskz.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_maskz", - "avx512.maskz.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_maskz", - "avx512.maskz.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_maskz", - "avx512.maskz.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_maskz", - "avx512.maskz.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_maskz", - "avx512.maskz.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_maskz", - "avx512.maskz.vfmadd.ss" => "__builtin_ia32_vfmaddss3_maskz", - "avx512.maskz.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_maskz", - "avx512.maskz.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_maskz", - "avx512.maskz.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_maskz", - "avx512.maskz.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_maskz", - "avx512.maskz.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_maskz", - "avx512.maskz.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_maskz", - "avx512.maskz.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_maskz", - "avx512.maskz.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_maskz", - "avx512.maskz.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_maskz", - "avx512.maskz.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_maskz", - "avx512.maskz.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_maskz", - "avx512.maskz.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_maskz", - "avx512.maskz.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_maskz", - "avx512.maskz.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_maskz", - "avx512.maskz.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_maskz", - "avx512.maskz.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_maskz", - "avx512.maskz.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_maskz", - "avx512.maskz.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_maskz", - "avx512.maskz.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_maskz", - "avx512.maskz.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_maskz", - "avx512.maskz.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_maskz", - "avx512.maskz.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_maskz", - "avx512.maskz.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_maskz", - "avx512.maskz.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_maskz", - "avx512.maskz.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_maskz", - "avx512.maskz.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_maskz", - "avx512.maskz.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_maskz", - "avx512.maskz.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_maskz", - "avx512.maskz.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_maskz", - "avx512.maskz.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_maskz", "avx512.max.pd.512" => "__builtin_ia32_maxpd512", "avx512.max.ps.512" => "__builtin_ia32_maxps512", "avx512.min.pd.512" => "__builtin_ia32_minpd512", "avx512.min.ps.512" => "__builtin_ia32_minps512", - "avx512.movntdqa" => "__builtin_ia32_movntdqa512", "avx512.mul.pd.512" => "__builtin_ia32_mulpd512", "avx512.mul.ps.512" => "__builtin_ia32_mulps512", "avx512.packssdw.512" => "__builtin_ia32_packssdw512", @@ -9533,8 +8355,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.packuswb.512" => "__builtin_ia32_packuswb512", "avx512.pavg.b.512" => "__builtin_ia32_pavgb512", "avx512.pavg.w.512" => "__builtin_ia32_pavgw512", - "avx512.pbroadcastd.512" => "__builtin_ia32_pbroadcastd512", - "avx512.pbroadcastq.512" => "__builtin_ia32_pbroadcastq512", "avx512.permvar.df.256" => "__builtin_ia32_permvardf256", "avx512.permvar.df.512" => "__builtin_ia32_permvardf512", "avx512.permvar.di.256" => "__builtin_ia32_permvardi256", @@ -9549,11 +8369,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.permvar.si.512" => "__builtin_ia32_permvarsi512", "avx512.pmaddubs.w.512" => "__builtin_ia32_pmaddubsw512", "avx512.pmaddw.d.512" => "__builtin_ia32_pmaddwd512", - "avx512.pmovzxbd" => "__builtin_ia32_pmovzxbd512", - "avx512.pmovzxbq" => "__builtin_ia32_pmovzxbq512", - "avx512.pmovzxdq" => "__builtin_ia32_pmovzxdq512", - "avx512.pmovzxwd" => "__builtin_ia32_pmovzxwd512", - "avx512.pmovzxwq" => "__builtin_ia32_pmovzxwq512", "avx512.pmul.hr.sw.512" => "__builtin_ia32_pmulhrsw512", "avx512.pmulh.w.512" => "__builtin_ia32_pmulhw512", "avx512.pmulhu.w.512" => "__builtin_ia32_pmulhuw512", @@ -9563,8 +8378,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.psad.bw.512" => "__builtin_ia32_psadbw512", "avx512.pshuf.b.512" => "__builtin_ia32_pshufb512", "avx512.psll.d.512" => "__builtin_ia32_pslld512", - "avx512.psll.dq" => "__builtin_ia32_pslldqi512", - "avx512.psll.dq.bs" => "__builtin_ia32_pslldqi512_byteshift", "avx512.psll.q.512" => "__builtin_ia32_psllq512", "avx512.psll.w.512" => "__builtin_ia32_psllw512", "avx512.pslli.d.512" => "__builtin_ia32_pslldi512", @@ -9593,8 +8406,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.psrav.w.256" => "__builtin_ia32_psrav16hi", "avx512.psrav.w.512" => "__builtin_ia32_psrav32hi", "avx512.psrl.d.512" => "__builtin_ia32_psrld512", - "avx512.psrl.dq" => "__builtin_ia32_psrldqi512", - "avx512.psrl.dq.bs" => "__builtin_ia32_psrldqi512_byteshift", "avx512.psrl.q.512" => "__builtin_ia32_psrlq512", "avx512.psrl.w.512" => "__builtin_ia32_psrlw512", "avx512.psrli.d.512" => "__builtin_ia32_psrldi512", @@ -9611,30 +8422,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.pternlog.q.128" => "__builtin_ia32_pternlogq128", "avx512.pternlog.q.256" => "__builtin_ia32_pternlogq256", "avx512.pternlog.q.512" => "__builtin_ia32_pternlogq512", - "avx512.ptestm.b.128" => "__builtin_ia32_ptestmb128", - "avx512.ptestm.b.256" => "__builtin_ia32_ptestmb256", - "avx512.ptestm.b.512" => "__builtin_ia32_ptestmb512", - "avx512.ptestm.d.128" => "__builtin_ia32_ptestmd128", - "avx512.ptestm.d.256" => "__builtin_ia32_ptestmd256", - "avx512.ptestm.d.512" => "__builtin_ia32_ptestmd512", - "avx512.ptestm.q.128" => "__builtin_ia32_ptestmq128", - "avx512.ptestm.q.256" => "__builtin_ia32_ptestmq256", - "avx512.ptestm.q.512" => "__builtin_ia32_ptestmq512", - "avx512.ptestm.w.128" => "__builtin_ia32_ptestmw128", - "avx512.ptestm.w.256" => "__builtin_ia32_ptestmw256", - "avx512.ptestm.w.512" => "__builtin_ia32_ptestmw512", - "avx512.ptestnm.b.128" => "__builtin_ia32_ptestnmb128", - "avx512.ptestnm.b.256" => "__builtin_ia32_ptestnmb256", - "avx512.ptestnm.b.512" => "__builtin_ia32_ptestnmb512", - "avx512.ptestnm.d.128" => "__builtin_ia32_ptestnmd128", - "avx512.ptestnm.d.256" => "__builtin_ia32_ptestnmd256", - "avx512.ptestnm.d.512" => "__builtin_ia32_ptestnmd512", - "avx512.ptestnm.q.128" => "__builtin_ia32_ptestnmq128", - "avx512.ptestnm.q.256" => "__builtin_ia32_ptestnmq256", - "avx512.ptestnm.q.512" => "__builtin_ia32_ptestnmq512", - "avx512.ptestnm.w.128" => "__builtin_ia32_ptestnmw128", - "avx512.ptestnm.w.256" => "__builtin_ia32_ptestnmw256", - "avx512.ptestnm.w.512" => "__builtin_ia32_ptestnmw512", "avx512.rcp14.pd.128" => "__builtin_ia32_rcp14pd128_mask", "avx512.rcp14.pd.256" => "__builtin_ia32_rcp14pd256_mask", "avx512.rcp14.pd.512" => "__builtin_ia32_rcp14pd512_mask", @@ -9643,14 +8430,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.rcp14.ps.512" => "__builtin_ia32_rcp14ps512_mask", "avx512.rcp14.sd" => "__builtin_ia32_rcp14sd_mask", "avx512.rcp14.ss" => "__builtin_ia32_rcp14ss_mask", - "avx512.rcp28.pd" => "__builtin_ia32_rcp28pd_mask", - "avx512.rcp28.ps" => "__builtin_ia32_rcp28ps_mask", - "avx512.rcp28.sd" => "__builtin_ia32_rcp28sd_mask", - // [DUPLICATE]: "avx512.rcp28.sd" => "__builtin_ia32_rcp28sd_round_mask", - "avx512.rcp28.ss" => "__builtin_ia32_rcp28ss_mask", - // [DUPLICATE]: "avx512.rcp28.ss" => "__builtin_ia32_rcp28ss_round_mask", - "avx512.rndscale.sd" => "__builtin_ia32_rndscalesd", - "avx512.rndscale.ss" => "__builtin_ia32_rndscaless", "avx512.rsqrt14.pd.128" => "__builtin_ia32_rsqrt14pd128_mask", "avx512.rsqrt14.pd.256" => "__builtin_ia32_rsqrt14pd256_mask", "avx512.rsqrt14.pd.512" => "__builtin_ia32_rsqrt14pd512_mask", @@ -9659,50 +8438,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.rsqrt14.ps.512" => "__builtin_ia32_rsqrt14ps512_mask", "avx512.rsqrt14.sd" => "__builtin_ia32_rsqrt14sd_mask", "avx512.rsqrt14.ss" => "__builtin_ia32_rsqrt14ss_mask", - "avx512.rsqrt28.pd" => "__builtin_ia32_rsqrt28pd_mask", - "avx512.rsqrt28.ps" => "__builtin_ia32_rsqrt28ps_mask", - "avx512.rsqrt28.sd" => "__builtin_ia32_rsqrt28sd_mask", - // [DUPLICATE]: "avx512.rsqrt28.sd" => "__builtin_ia32_rsqrt28sd_round_mask", - "avx512.rsqrt28.ss" => "__builtin_ia32_rsqrt28ss_mask", - // [DUPLICATE]: "avx512.rsqrt28.ss" => "__builtin_ia32_rsqrt28ss_round_mask", - "avx512.scatter.dpd.512" => "__builtin_ia32_scattersiv8df", - "avx512.scatter.dpi.512" => "__builtin_ia32_scattersiv16si", - "avx512.scatter.dpq.512" => "__builtin_ia32_scattersiv8di", - "avx512.scatter.dps.512" => "__builtin_ia32_scattersiv16sf", - "avx512.scatter.qpd.512" => "__builtin_ia32_scatterdiv8df", - "avx512.scatter.qpi.512" => "__builtin_ia32_scatterdiv16si", - "avx512.scatter.qpq.512" => "__builtin_ia32_scatterdiv8di", - "avx512.scatter.qps.512" => "__builtin_ia32_scatterdiv16sf", - "avx512.scatterdiv2.df" => "__builtin_ia32_scatterdiv2df", - "avx512.scatterdiv2.di" => "__builtin_ia32_scatterdiv2di", - "avx512.scatterdiv4.df" => "__builtin_ia32_scatterdiv4df", - "avx512.scatterdiv4.di" => "__builtin_ia32_scatterdiv4di", - "avx512.scatterdiv4.sf" => "__builtin_ia32_scatterdiv4sf", - "avx512.scatterdiv4.si" => "__builtin_ia32_scatterdiv4si", - "avx512.scatterdiv8.sf" => "__builtin_ia32_scatterdiv8sf", - "avx512.scatterdiv8.si" => "__builtin_ia32_scatterdiv8si", - "avx512.scatterpf.dpd.512" => "__builtin_ia32_scatterpfdpd", - "avx512.scatterpf.dps.512" => "__builtin_ia32_scatterpfdps", - "avx512.scatterpf.qpd.512" => "__builtin_ia32_scatterpfqpd", - "avx512.scatterpf.qps.512" => "__builtin_ia32_scatterpfqps", - "avx512.scattersiv2.df" => "__builtin_ia32_scattersiv2df", - "avx512.scattersiv2.di" => "__builtin_ia32_scattersiv2di", - "avx512.scattersiv4.df" => "__builtin_ia32_scattersiv4df", - "avx512.scattersiv4.di" => "__builtin_ia32_scattersiv4di", - "avx512.scattersiv4.sf" => "__builtin_ia32_scattersiv4sf", - "avx512.scattersiv4.si" => "__builtin_ia32_scattersiv4si", - "avx512.scattersiv8.sf" => "__builtin_ia32_scattersiv8sf", - "avx512.scattersiv8.si" => "__builtin_ia32_scattersiv8si", - "avx512.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", - "avx512.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", - "avx512.sqrt.sd" => "__builtin_ia32_sqrtrndsd", - "avx512.sqrt.ss" => "__builtin_ia32_sqrtrndss", "avx512.sub.pd.512" => "__builtin_ia32_subpd512", "avx512.sub.ps.512" => "__builtin_ia32_subps512", - "avx512.vbroadcast.sd.512" => "__builtin_ia32_vbroadcastsd512", - "avx512.vbroadcast.sd.pd.512" => "__builtin_ia32_vbroadcastsd_pd512", - "avx512.vbroadcast.ss.512" => "__builtin_ia32_vbroadcastss512", - "avx512.vbroadcast.ss.ps.512" => "__builtin_ia32_vbroadcastss_ps512", "avx512.vcomi.sd" => "__builtin_ia32_vcomisd", "avx512.vcomi.ss" => "__builtin_ia32_vcomiss", "avx512.vcvtsd2si32" => "__builtin_ia32_vcvtsd2si32", @@ -9928,50 +8665,10 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "flags.read.u64" => "__builtin_ia32_readeflags_u64", "flags.write.u32" => "__builtin_ia32_writeeflags_u32", "flags.write.u64" => "__builtin_ia32_writeeflags_u64", - "fma.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", - "fma.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", - "fma.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", - "fma.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", - "fma.mask.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask", - "fma.mask.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask", - "fma.mask.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask", - "fma.mask.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask", - "fma.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", - "fma.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", - "fma.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", - "fma.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", - "fma.vfmadd.pd" => "__builtin_ia32_vfmaddpd", - "fma.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256", - "fma.vfmadd.ps" => "__builtin_ia32_vfmaddps", - "fma.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256", - "fma.vfmadd.sd" => "__builtin_ia32_vfmaddsd", - "fma.vfmadd.ss" => "__builtin_ia32_vfmaddss", "fma.vfmaddsub.pd" => "__builtin_ia32_vfmaddsubpd", "fma.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256", "fma.vfmaddsub.ps" => "__builtin_ia32_vfmaddsubps", "fma.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256", - "fma.vfmsub.pd" => "__builtin_ia32_vfmsubpd", - "fma.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256", - "fma.vfmsub.ps" => "__builtin_ia32_vfmsubps", - "fma.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256", - "fma.vfmsub.sd" => "__builtin_ia32_vfmsubsd", - "fma.vfmsub.ss" => "__builtin_ia32_vfmsubss", - "fma.vfmsubadd.pd" => "__builtin_ia32_vfmsubaddpd", - "fma.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256", - "fma.vfmsubadd.ps" => "__builtin_ia32_vfmsubaddps", - "fma.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256", - "fma.vfnmadd.pd" => "__builtin_ia32_vfnmaddpd", - "fma.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256", - "fma.vfnmadd.ps" => "__builtin_ia32_vfnmaddps", - "fma.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256", - "fma.vfnmadd.sd" => "__builtin_ia32_vfnmaddsd", - "fma.vfnmadd.ss" => "__builtin_ia32_vfnmaddss", - "fma.vfnmsub.pd" => "__builtin_ia32_vfnmsubpd", - "fma.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256", - "fma.vfnmsub.ps" => "__builtin_ia32_vfnmsubps", - "fma.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256", - "fma.vfnmsub.sd" => "__builtin_ia32_vfnmsubsd", - "fma.vfnmsub.ss" => "__builtin_ia32_vfnmsubss", "fxrstor" => "__builtin_ia32_fxrstor", "fxrstor64" => "__builtin_ia32_fxrstor64", "fxsave" => "__builtin_ia32_fxsave", @@ -9988,7 +8685,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "lwpval32" => "__builtin_ia32_lwpval32", "lwpval64" => "__builtin_ia32_lwpval64", "mmx.emms" => "__builtin_ia32_emms", - "mmx.femms" => "__builtin_ia32_femms", "monitorx" => "__builtin_ia32_monitorx", "movdir64b" => "__builtin_ia32_movdir64b", "movrsdi" => "__builtin_ia32_movrsdi", @@ -10013,7 +8709,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "rdsspd" => "__builtin_ia32_rdsspd", "rdsspq" => "__builtin_ia32_rdsspq", "rdtsc" => "__builtin_ia32_rdtsc", - "rdtscp" => "__builtin_ia32_rdtscp", "rstorssp" => "__builtin_ia32_rstorssp", "saveprevssp" => "__builtin_ia32_saveprevssp", "senduipi" => "__builtin_ia32_senduipi", @@ -10027,8 +8722,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sha256msg2" => "__builtin_ia32_sha256msg2", "sha256rnds2" => "__builtin_ia32_sha256rnds2", "slwpcb" => "__builtin_ia32_slwpcb", - "sse.add.ss" => "__builtin_ia32_addss", - "sse.cmp.ps" => "__builtin_ia32_cmpps", "sse.cmp.ss" => "__builtin_ia32_cmpss", "sse.comieq.ss" => "__builtin_ia32_comieq", "sse.comige.ss" => "__builtin_ia32_comige", @@ -10036,37 +8729,27 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse.comile.ss" => "__builtin_ia32_comile", "sse.comilt.ss" => "__builtin_ia32_comilt", "sse.comineq.ss" => "__builtin_ia32_comineq", - "sse.cvtsi2ss" => "__builtin_ia32_cvtsi2ss", - "sse.cvtsi642ss" => "__builtin_ia32_cvtsi642ss", "sse.cvtss2si" => "__builtin_ia32_cvtss2si", "sse.cvtss2si64" => "__builtin_ia32_cvtss2si64", "sse.cvttss2si" => "__builtin_ia32_cvttss2si", "sse.cvttss2si64" => "__builtin_ia32_cvttss2si64", - "sse.div.ss" => "__builtin_ia32_divss", "sse.max.ps" => "__builtin_ia32_maxps", "sse.max.ss" => "__builtin_ia32_maxss", "sse.min.ps" => "__builtin_ia32_minps", "sse.min.ss" => "__builtin_ia32_minss", "sse.movmsk.ps" => "__builtin_ia32_movmskps", - "sse.mul.ss" => "__builtin_ia32_mulss", "sse.rcp.ps" => "__builtin_ia32_rcpps", "sse.rcp.ss" => "__builtin_ia32_rcpss", "sse.rsqrt.ps" => "__builtin_ia32_rsqrtps", "sse.rsqrt.ss" => "__builtin_ia32_rsqrtss", "sse.sfence" => "__builtin_ia32_sfence", - "sse.sqrt.ps" => "__builtin_ia32_sqrtps", - "sse.sqrt.ss" => "__builtin_ia32_sqrtss", - "sse.storeu.ps" => "__builtin_ia32_storeups", - "sse.sub.ss" => "__builtin_ia32_subss", "sse.ucomieq.ss" => "__builtin_ia32_ucomieq", "sse.ucomige.ss" => "__builtin_ia32_ucomige", "sse.ucomigt.ss" => "__builtin_ia32_ucomigt", "sse.ucomile.ss" => "__builtin_ia32_ucomile", "sse.ucomilt.ss" => "__builtin_ia32_ucomilt", "sse.ucomineq.ss" => "__builtin_ia32_ucomineq", - "sse2.add.sd" => "__builtin_ia32_addsd", "sse2.clflush" => "__builtin_ia32_clflush", - "sse2.cmp.pd" => "__builtin_ia32_cmppd", "sse2.cmp.sd" => "__builtin_ia32_cmpsd", "sse2.comieq.sd" => "__builtin_ia32_comisdeq", "sse2.comige.sd" => "__builtin_ia32_comisdge", @@ -10074,23 +8757,16 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse2.comile.sd" => "__builtin_ia32_comisdle", "sse2.comilt.sd" => "__builtin_ia32_comisdlt", "sse2.comineq.sd" => "__builtin_ia32_comisdneq", - "sse2.cvtdq2pd" => "__builtin_ia32_cvtdq2pd", - "sse2.cvtdq2ps" => "__builtin_ia32_cvtdq2ps", "sse2.cvtpd2dq" => "__builtin_ia32_cvtpd2dq", "sse2.cvtpd2ps" => "__builtin_ia32_cvtpd2ps", "sse2.cvtps2dq" => "__builtin_ia32_cvtps2dq", - "sse2.cvtps2pd" => "__builtin_ia32_cvtps2pd", "sse2.cvtsd2si" => "__builtin_ia32_cvtsd2si", "sse2.cvtsd2si64" => "__builtin_ia32_cvtsd2si64", "sse2.cvtsd2ss" => "__builtin_ia32_cvtsd2ss", - "sse2.cvtsi2sd" => "__builtin_ia32_cvtsi2sd", - "sse2.cvtsi642sd" => "__builtin_ia32_cvtsi642sd", - "sse2.cvtss2sd" => "__builtin_ia32_cvtss2sd", "sse2.cvttpd2dq" => "__builtin_ia32_cvttpd2dq", "sse2.cvttps2dq" => "__builtin_ia32_cvttps2dq", "sse2.cvttsd2si" => "__builtin_ia32_cvttsd2si", "sse2.cvttsd2si64" => "__builtin_ia32_cvttsd2si64", - "sse2.div.sd" => "__builtin_ia32_divsd", "sse2.lfence" => "__builtin_ia32_lfence", "sse2.maskmov.dqu" => "__builtin_ia32_maskmovdqu", "sse2.max.pd" => "__builtin_ia32_maxpd", @@ -10099,33 +8775,18 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse2.min.pd" => "__builtin_ia32_minpd", "sse2.min.sd" => "__builtin_ia32_minsd", "sse2.movmsk.pd" => "__builtin_ia32_movmskpd", - "sse2.mul.sd" => "__builtin_ia32_mulsd", "sse2.packssdw.128" => "__builtin_ia32_packssdw128", "sse2.packsswb.128" => "__builtin_ia32_packsswb128", "sse2.packuswb.128" => "__builtin_ia32_packuswb128", - "sse2.padds.b" => "__builtin_ia32_paddsb128", - "sse2.padds.w" => "__builtin_ia32_paddsw128", - "sse2.paddus.b" => "__builtin_ia32_paddusb128", - "sse2.paddus.w" => "__builtin_ia32_paddusw128", "sse2.pause" => "__builtin_ia32_pause", "sse2.pavg.b" => "__builtin_ia32_pavgb128", "sse2.pavg.w" => "__builtin_ia32_pavgw128", "sse2.pmadd.wd" => "__builtin_ia32_pmaddwd128", - "sse2.pmaxs.w" => "__builtin_ia32_pmaxsw128", - "sse2.pmaxu.b" => "__builtin_ia32_pmaxub128", - "sse2.pmins.w" => "__builtin_ia32_pminsw128", - "sse2.pminu.b" => "__builtin_ia32_pminub128", "sse2.pmovmskb.128" => "__builtin_ia32_pmovmskb128", "sse2.pmulh.w" => "__builtin_ia32_pmulhw128", "sse2.pmulhu.w" => "__builtin_ia32_pmulhuw128", - "sse2.pmulu.dq" => "__builtin_ia32_pmuludq128", "sse2.psad.bw" => "__builtin_ia32_psadbw128", - "sse2.pshuf.d" => "__builtin_ia32_pshufd", - "sse2.pshufh.w" => "__builtin_ia32_pshufhw", - "sse2.pshufl.w" => "__builtin_ia32_pshuflw", "sse2.psll.d" => "__builtin_ia32_pslld128", - "sse2.psll.dq" => "__builtin_ia32_pslldqi128", - "sse2.psll.dq.bs" => "__builtin_ia32_pslldqi128_byteshift", "sse2.psll.q" => "__builtin_ia32_psllq128", "sse2.psll.w" => "__builtin_ia32_psllw128", "sse2.pslli.d" => "__builtin_ia32_pslldi128", @@ -10136,23 +8797,11 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse2.psrai.d" => "__builtin_ia32_psradi128", "sse2.psrai.w" => "__builtin_ia32_psrawi128", "sse2.psrl.d" => "__builtin_ia32_psrld128", - "sse2.psrl.dq" => "__builtin_ia32_psrldqi128", - "sse2.psrl.dq.bs" => "__builtin_ia32_psrldqi128_byteshift", "sse2.psrl.q" => "__builtin_ia32_psrlq128", "sse2.psrl.w" => "__builtin_ia32_psrlw128", "sse2.psrli.d" => "__builtin_ia32_psrldi128", "sse2.psrli.q" => "__builtin_ia32_psrlqi128", "sse2.psrli.w" => "__builtin_ia32_psrlwi128", - "sse2.psubs.b" => "__builtin_ia32_psubsb128", - "sse2.psubs.w" => "__builtin_ia32_psubsw128", - "sse2.psubus.b" => "__builtin_ia32_psubusb128", - "sse2.psubus.w" => "__builtin_ia32_psubusw128", - "sse2.sqrt.pd" => "__builtin_ia32_sqrtpd", - "sse2.sqrt.sd" => "__builtin_ia32_sqrtsd", - "sse2.storel.dq" => "__builtin_ia32_storelv4si", - "sse2.storeu.dq" => "__builtin_ia32_storedqu", - "sse2.storeu.pd" => "__builtin_ia32_storeupd", - "sse2.sub.sd" => "__builtin_ia32_subsd", "sse2.ucomieq.sd" => "__builtin_ia32_ucomisdeq", "sse2.ucomige.sd" => "__builtin_ia32_ucomisdge", "sse2.ucomigt.sd" => "__builtin_ia32_ucomisdgt", @@ -10168,41 +8817,15 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse3.ldu.dq" => "__builtin_ia32_lddqu", "sse3.monitor" => "__builtin_ia32_monitor", "sse3.mwait" => "__builtin_ia32_mwait", - "sse41.blendpd" => "__builtin_ia32_blendpd", - "sse41.blendps" => "__builtin_ia32_blendps", "sse41.blendvpd" => "__builtin_ia32_blendvpd", "sse41.blendvps" => "__builtin_ia32_blendvps", "sse41.dppd" => "__builtin_ia32_dppd", "sse41.dpps" => "__builtin_ia32_dpps", - "sse41.extractps" => "__builtin_ia32_extractps128", "sse41.insertps" => "__builtin_ia32_insertps128", - "sse41.movntdqa" => "__builtin_ia32_movntdqa", "sse41.mpsadbw" => "__builtin_ia32_mpsadbw128", "sse41.packusdw" => "__builtin_ia32_packusdw128", "sse41.pblendvb" => "__builtin_ia32_pblendvb128", - "sse41.pblendw" => "__builtin_ia32_pblendw128", "sse41.phminposuw" => "__builtin_ia32_phminposuw128", - "sse41.pmaxsb" => "__builtin_ia32_pmaxsb128", - "sse41.pmaxsd" => "__builtin_ia32_pmaxsd128", - "sse41.pmaxud" => "__builtin_ia32_pmaxud128", - "sse41.pmaxuw" => "__builtin_ia32_pmaxuw128", - "sse41.pminsb" => "__builtin_ia32_pminsb128", - "sse41.pminsd" => "__builtin_ia32_pminsd128", - "sse41.pminud" => "__builtin_ia32_pminud128", - "sse41.pminuw" => "__builtin_ia32_pminuw128", - "sse41.pmovsxbd" => "__builtin_ia32_pmovsxbd128", - "sse41.pmovsxbq" => "__builtin_ia32_pmovsxbq128", - "sse41.pmovsxbw" => "__builtin_ia32_pmovsxbw128", - "sse41.pmovsxdq" => "__builtin_ia32_pmovsxdq128", - "sse41.pmovsxwd" => "__builtin_ia32_pmovsxwd128", - "sse41.pmovsxwq" => "__builtin_ia32_pmovsxwq128", - "sse41.pmovzxbd" => "__builtin_ia32_pmovzxbd128", - "sse41.pmovzxbq" => "__builtin_ia32_pmovzxbq128", - "sse41.pmovzxbw" => "__builtin_ia32_pmovzxbw128", - "sse41.pmovzxdq" => "__builtin_ia32_pmovzxdq128", - "sse41.pmovzxwd" => "__builtin_ia32_pmovzxwd128", - "sse41.pmovzxwq" => "__builtin_ia32_pmovzxwq128", - "sse41.pmuldq" => "__builtin_ia32_pmuldq128", "sse41.ptestc" => "__builtin_ia32_ptestc128", "sse41.ptestnzc" => "__builtin_ia32_ptestnzc128", "sse41.ptestz" => "__builtin_ia32_ptestz128", @@ -10232,11 +8855,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse4a.extrqi" => "__builtin_ia32_extrqi", "sse4a.insertq" => "__builtin_ia32_insertq", "sse4a.insertqi" => "__builtin_ia32_insertqi", - "sse4a.movnt.sd" => "__builtin_ia32_movntsd", - "sse4a.movnt.ss" => "__builtin_ia32_movntss", - "ssse3.pabs.b.128" => "__builtin_ia32_pabsb128", - "ssse3.pabs.d.128" => "__builtin_ia32_pabsd128", - "ssse3.pabs.w.128" => "__builtin_ia32_pabsw128", "ssse3.phadd.d.128" => "__builtin_ia32_phaddd128", "ssse3.phadd.sw.128" => "__builtin_ia32_phaddsw128", "ssse3.phadd.w.128" => "__builtin_ia32_phaddw128", @@ -10251,8 +8869,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "ssse3.psign.w.128" => "__builtin_ia32_psignw128", "sttilecfg" => "__builtin_ia32_tile_storeconfig", "stui" => "__builtin_ia32_stui", - "subborrow.u32" => "__builtin_ia32_subborrow_u32", - "subborrow.u64" => "__builtin_ia32_subborrow_u64", "t2rpntlvwz0rs" => "__builtin_ia32_t2rpntlvwz0rs", "t2rpntlvwz0rst1" => "__builtin_ia32_t2rpntlvwz0rst1", "t2rpntlvwz1rs" => "__builtin_ia32_t2rpntlvwz1rs", @@ -10330,8 +8946,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "vcvtneoph2ps256" => "__builtin_ia32_vcvtneoph2ps256", "vcvtneps2bf16128" => "__builtin_ia32_vcvtneps2bf16128", "vcvtneps2bf16256" => "__builtin_ia32_vcvtneps2bf16256", - "vcvtph2ps.128" => "__builtin_ia32_vcvtph2ps", - "vcvtph2ps.256" => "__builtin_ia32_vcvtph2ps256", "vcvtps2ph.128" => "__builtin_ia32_vcvtps2ph", "vcvtps2ph.256" => "__builtin_ia32_vcvtps2ph256", "vgf2p8affineinvqb.128" => "__builtin_ia32_vgf2p8affineinvqb_v16qi", @@ -10375,16 +8989,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "xop.vfrcz.ps.256" => "__builtin_ia32_vfrczps256", "xop.vfrcz.sd" => "__builtin_ia32_vfrczsd", "xop.vfrcz.ss" => "__builtin_ia32_vfrczss", - "xop.vpcmov" => "__builtin_ia32_vpcmov", - "xop.vpcmov.256" => "__builtin_ia32_vpcmov_256", - "xop.vpcomb" => "__builtin_ia32_vpcomb", - "xop.vpcomd" => "__builtin_ia32_vpcomd", - "xop.vpcomq" => "__builtin_ia32_vpcomq", - "xop.vpcomub" => "__builtin_ia32_vpcomub", - "xop.vpcomud" => "__builtin_ia32_vpcomud", - "xop.vpcomuq" => "__builtin_ia32_vpcomuq", - "xop.vpcomuw" => "__builtin_ia32_vpcomuw", - "xop.vpcomw" => "__builtin_ia32_vpcomw", "xop.vpermil2pd" => "__builtin_ia32_vpermil2pd", "xop.vpermil2pd.256" => "__builtin_ia32_vpermil2pd256", "xop.vpermil2ps" => "__builtin_ia32_vpermil2ps", @@ -10417,14 +9021,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "xop.vpmadcsswd" => "__builtin_ia32_vpmadcsswd", "xop.vpmadcswd" => "__builtin_ia32_vpmadcswd", "xop.vpperm" => "__builtin_ia32_vpperm", - "xop.vprotb" => "__builtin_ia32_vprotb", - "xop.vprotbi" => "__builtin_ia32_vprotbi", - "xop.vprotd" => "__builtin_ia32_vprotd", - "xop.vprotdi" => "__builtin_ia32_vprotdi", - "xop.vprotq" => "__builtin_ia32_vprotq", - "xop.vprotqi" => "__builtin_ia32_vprotqi", - "xop.vprotw" => "__builtin_ia32_vprotw", - "xop.vprotwi" => "__builtin_ia32_vprotwi", "xop.vpshab" => "__builtin_ia32_vpshab", "xop.vpshad" => "__builtin_ia32_vpshad", "xop.vpshaq" => "__builtin_ia32_vpshaq", @@ -10454,6 +9050,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { } xcore(name, full_name) } - _ => unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic:{full_name}"), + _ => match old_arch_res { + ArchCheckResult::UnknownIntrinsic => { + unimplemented!("***** unsupported LLVM intrinsic {full_name}") + } + ArchCheckResult::UnknownArch => { + unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic: {full_name}") + } + ArchCheckResult::Ok(_) => unreachable!(), + }, } } diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index e3d189c95ced..72fc72d118b7 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -1604,5 +1604,7 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function func } +#[cfg(feature = "master")] +include!("old_archs.rs"); #[cfg(feature = "master")] include!("archs.rs"); diff --git a/src/intrinsic/old_archs.rs b/src/intrinsic/old_archs.rs new file mode 100644 index 000000000000..3a59707b2ebe --- /dev/null +++ b/src/intrinsic/old_archs.rs @@ -0,0 +1,1384 @@ +// All these translations used to be automatically generated in the past. However, since they never +// changed, we decided to simplify the translation generation script to move them directly into this +// file. +// +// So in short: avoid editing this file. + +pub(crate) enum ArchCheckResult { + Ok(&'static str), + UnknownIntrinsic, + UnknownArch, +} + +pub(crate) fn old_archs(arch: &str, name: &str) -> ArchCheckResult { + ArchCheckResult::Ok(match arch { + "AMDGPU" => match name { + "div.fixup.f32" => "__builtin_amdgpu_div_fixup", + "div.fixup.f64" => "__builtin_amdgpu_div_fixup", + "div.fixup.v2f64" => "__builtin_amdgpu_div_fixup", + "div.fixup.v4f32" => "__builtin_amdgpu_div_fixup", + "div.fmas.f32" => "__builtin_amdgpu_div_fmas", + "div.fmas.f64" => "__builtin_amdgpu_div_fmas", + "div.fmas.v2f64" => "__builtin_amdgpu_div_fmas", + "div.fmas.v4f32" => "__builtin_amdgpu_div_fmas", + "ldexp.f32" => "__builtin_amdgpu_ldexp", + "ldexp.f64" => "__builtin_amdgpu_ldexp", + "ldexp.v2f64" => "__builtin_amdgpu_ldexp", + "ldexp.v4f32" => "__builtin_amdgpu_ldexp", + "rcp.f32" => "__builtin_amdgpu_rcp", + "rcp.f64" => "__builtin_amdgpu_rcp", + "rcp.v2f64" => "__builtin_amdgpu_rcp", + "rcp.v4f32" => "__builtin_amdgpu_rcp", + "rsq.clamped.f32" => "__builtin_amdgpu_rsq_clamped", + "rsq.clamped.f64" => "__builtin_amdgpu_rsq_clamped", + "rsq.clamped.v2f64" => "__builtin_amdgpu_rsq_clamped", + "rsq.clamped.v4f32" => "__builtin_amdgpu_rsq_clamped", + "rsq.f32" => "__builtin_amdgpu_rsq", + "rsq.f64" => "__builtin_amdgpu_rsq", + "rsq.v2f64" => "__builtin_amdgpu_rsq", + "rsq.v4f32" => "__builtin_amdgpu_rsq", + "trig.preop.f32" => "__builtin_amdgpu_trig_preop", + "trig.preop.f64" => "__builtin_amdgpu_trig_preop", + "trig.preop.v2f64" => "__builtin_amdgpu_trig_preop", + "trig.preop.v4f32" => "__builtin_amdgpu_trig_preop", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "arm" => match name { + "mcrr" => "__builtin_arm_mcrr", + "mcrr2" => "__builtin_arm_mcrr2", + "thread.pointer" => "__builtin_thread_pointer", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "cuda" => match name { + "syncthreads" => "__syncthreads", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "hexagon" => match name { + "F2.dffixupd" => "__builtin_HEXAGON_F2_dffixupd", + "F2.dffixupn" => "__builtin_HEXAGON_F2_dffixupn", + "F2.dffixupr" => "__builtin_HEXAGON_F2_dffixupr", + "F2.dffma" => "__builtin_HEXAGON_F2_dffma", + "F2.dffma.lib" => "__builtin_HEXAGON_F2_dffma_lib", + "F2.dffma.sc" => "__builtin_HEXAGON_F2_dffma_sc", + "F2.dffms" => "__builtin_HEXAGON_F2_dffms", + "F2.dffms.lib" => "__builtin_HEXAGON_F2_dffms_lib", + "F2.dfmpy" => "__builtin_HEXAGON_F2_dfmpy", + "S2.cabacencbin" => "__builtin_HEXAGON_S2_cabacencbin", + "SI.to.SXTHI.asrh" => "__builtin_SI_to_SXTHI_asrh", + "V6.vlutb" => "__builtin_HEXAGON_V6_vlutb", + "V6.vlutb.128B" => "__builtin_HEXAGON_V6_vlutb_128B", + "V6.vlutb.acc" => "__builtin_HEXAGON_V6_vlutb_acc", + "V6.vlutb.acc.128B" => "__builtin_HEXAGON_V6_vlutb_acc_128B", + "V6.vlutb.dv" => "__builtin_HEXAGON_V6_vlutb_dv", + "V6.vlutb.dv.128B" => "__builtin_HEXAGON_V6_vlutb_dv_128B", + "V6.vlutb.dv.acc" => "__builtin_HEXAGON_V6_vlutb_dv_acc", + "V6.vlutb.dv.acc.128B" => "__builtin_HEXAGON_V6_vlutb_dv_acc_128B", + "brev.ldb" => "__builtin_brev_ldb", + "brev.ldd" => "__builtin_brev_ldd", + "brev.ldh" => "__builtin_brev_ldh", + "brev.ldub" => "__builtin_brev_ldub", + "brev.lduh" => "__builtin_brev_lduh", + "brev.ldw" => "__builtin_brev_ldw", + "brev.stb" => "__builtin_brev_stb", + "brev.std" => "__builtin_brev_std", + "brev.sth" => "__builtin_brev_sth", + "brev.sthhi" => "__builtin_brev_sthhi", + "brev.stw" => "__builtin_brev_stw", + "mm256i.vaddw" => "__builtin__mm256i_vaddw", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "nvvm" => match name { + "abs.i" => "__nvvm_abs_i", + "abs.ll" => "__nvvm_abs_ll", + "bar.sync" => "__nvvm_bar_sync", + "barrier0" => "__nvvm_bar0", + "bitcast.d2ll" => "__nvvm_bitcast_d2ll", + "bitcast.f2i" => "__nvvm_bitcast_f2i", + "bitcast.i2f" => "__nvvm_bitcast_i2f", + "bitcast.ll2d" => "__nvvm_bitcast_ll2d", + "brev32" => "__nvvm_brev32", + "brev64" => "__nvvm_brev64", + "clz.i" => "__nvvm_clz_i", + "clz.ll" => "__nvvm_clz_ll", + "ex2.approx.d" => "__nvvm_ex2_approx_d", + "ex2.approx.f" => "__nvvm_ex2_approx_f", + "ex2.approx.ftz.f" => "__nvvm_ex2_approx_ftz_f", + "fabs.d" => "__nvvm_fabs_d", + "fabs.f" => "__nvvm_fabs_f", + "fabs.ftz.f" => "__nvvm_fabs_ftz_f", + "h2f" => "__nvvm_h2f", + "max.i" => "__nvvm_max_i", + "max.ll" => "__nvvm_max_ll", + "max.ui" => "__nvvm_max_ui", + "max.ull" => "__nvvm_max_ull", + "min.i" => "__nvvm_min_i", + "min.ll" => "__nvvm_min_ll", + "min.ui" => "__nvvm_min_ui", + "min.ull" => "__nvvm_min_ull", + "popc.i" => "__nvvm_popc_i", + "popc.ll" => "__nvvm_popc_ll", + "rotate.b32" => "__nvvm_rotate_b32", + "rotate.b64" => "__nvvm_rotate_b64", + "rotate.right.b64" => "__nvvm_rotate_right_b64", + "swap.lo.hi.b64" => "__nvvm_swap_lo_hi_b64", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "ppc" => match name { + "qpx.qvfabs" => "__builtin_qpx_qvfabs", + "qpx.qvfadd" => "__builtin_qpx_qvfadd", + "qpx.qvfadds" => "__builtin_qpx_qvfadds", + "qpx.qvfcfid" => "__builtin_qpx_qvfcfid", + "qpx.qvfcfids" => "__builtin_qpx_qvfcfids", + "qpx.qvfcfidu" => "__builtin_qpx_qvfcfidu", + "qpx.qvfcfidus" => "__builtin_qpx_qvfcfidus", + "qpx.qvfcmpeq" => "__builtin_qpx_qvfcmpeq", + "qpx.qvfcmpgt" => "__builtin_qpx_qvfcmpgt", + "qpx.qvfcmplt" => "__builtin_qpx_qvfcmplt", + "qpx.qvfcpsgn" => "__builtin_qpx_qvfcpsgn", + "qpx.qvfctid" => "__builtin_qpx_qvfctid", + "qpx.qvfctidu" => "__builtin_qpx_qvfctidu", + "qpx.qvfctiduz" => "__builtin_qpx_qvfctiduz", + "qpx.qvfctidz" => "__builtin_qpx_qvfctidz", + "qpx.qvfctiw" => "__builtin_qpx_qvfctiw", + "qpx.qvfctiwu" => "__builtin_qpx_qvfctiwu", + "qpx.qvfctiwuz" => "__builtin_qpx_qvfctiwuz", + "qpx.qvfctiwz" => "__builtin_qpx_qvfctiwz", + "qpx.qvflogical" => "__builtin_qpx_qvflogical", + "qpx.qvfmadd" => "__builtin_qpx_qvfmadd", + "qpx.qvfmadds" => "__builtin_qpx_qvfmadds", + "qpx.qvfmsub" => "__builtin_qpx_qvfmsub", + "qpx.qvfmsubs" => "__builtin_qpx_qvfmsubs", + "qpx.qvfmul" => "__builtin_qpx_qvfmul", + "qpx.qvfmuls" => "__builtin_qpx_qvfmuls", + "qpx.qvfnabs" => "__builtin_qpx_qvfnabs", + "qpx.qvfneg" => "__builtin_qpx_qvfneg", + "qpx.qvfnmadd" => "__builtin_qpx_qvfnmadd", + "qpx.qvfnmadds" => "__builtin_qpx_qvfnmadds", + "qpx.qvfnmsub" => "__builtin_qpx_qvfnmsub", + "qpx.qvfnmsubs" => "__builtin_qpx_qvfnmsubs", + "qpx.qvfperm" => "__builtin_qpx_qvfperm", + "qpx.qvfre" => "__builtin_qpx_qvfre", + "qpx.qvfres" => "__builtin_qpx_qvfres", + "qpx.qvfrim" => "__builtin_qpx_qvfrim", + "qpx.qvfrin" => "__builtin_qpx_qvfrin", + "qpx.qvfrip" => "__builtin_qpx_qvfrip", + "qpx.qvfriz" => "__builtin_qpx_qvfriz", + "qpx.qvfrsp" => "__builtin_qpx_qvfrsp", + "qpx.qvfrsqrte" => "__builtin_qpx_qvfrsqrte", + "qpx.qvfrsqrtes" => "__builtin_qpx_qvfrsqrtes", + "qpx.qvfsel" => "__builtin_qpx_qvfsel", + "qpx.qvfsub" => "__builtin_qpx_qvfsub", + "qpx.qvfsubs" => "__builtin_qpx_qvfsubs", + "qpx.qvftstnan" => "__builtin_qpx_qvftstnan", + "qpx.qvfxmadd" => "__builtin_qpx_qvfxmadd", + "qpx.qvfxmadds" => "__builtin_qpx_qvfxmadds", + "qpx.qvfxmul" => "__builtin_qpx_qvfxmul", + "qpx.qvfxmuls" => "__builtin_qpx_qvfxmuls", + "qpx.qvfxxcpnmadd" => "__builtin_qpx_qvfxxcpnmadd", + "qpx.qvfxxcpnmadds" => "__builtin_qpx_qvfxxcpnmadds", + "qpx.qvfxxmadd" => "__builtin_qpx_qvfxxmadd", + "qpx.qvfxxmadds" => "__builtin_qpx_qvfxxmadds", + "qpx.qvfxxnpmadd" => "__builtin_qpx_qvfxxnpmadd", + "qpx.qvfxxnpmadds" => "__builtin_qpx_qvfxxnpmadds", + "qpx.qvgpci" => "__builtin_qpx_qvgpci", + "qpx.qvlfcd" => "__builtin_qpx_qvlfcd", + "qpx.qvlfcda" => "__builtin_qpx_qvlfcda", + "qpx.qvlfcs" => "__builtin_qpx_qvlfcs", + "qpx.qvlfcsa" => "__builtin_qpx_qvlfcsa", + "qpx.qvlfd" => "__builtin_qpx_qvlfd", + "qpx.qvlfda" => "__builtin_qpx_qvlfda", + "qpx.qvlfiwa" => "__builtin_qpx_qvlfiwa", + "qpx.qvlfiwaa" => "__builtin_qpx_qvlfiwaa", + "qpx.qvlfiwz" => "__builtin_qpx_qvlfiwz", + "qpx.qvlfiwza" => "__builtin_qpx_qvlfiwza", + "qpx.qvlfs" => "__builtin_qpx_qvlfs", + "qpx.qvlfsa" => "__builtin_qpx_qvlfsa", + "qpx.qvlpcld" => "__builtin_qpx_qvlpcld", + "qpx.qvlpcls" => "__builtin_qpx_qvlpcls", + "qpx.qvlpcrd" => "__builtin_qpx_qvlpcrd", + "qpx.qvlpcrs" => "__builtin_qpx_qvlpcrs", + "qpx.qvstfcd" => "__builtin_qpx_qvstfcd", + "qpx.qvstfcda" => "__builtin_qpx_qvstfcda", + "qpx.qvstfcs" => "__builtin_qpx_qvstfcs", + "qpx.qvstfcsa" => "__builtin_qpx_qvstfcsa", + "qpx.qvstfd" => "__builtin_qpx_qvstfd", + "qpx.qvstfda" => "__builtin_qpx_qvstfda", + "qpx.qvstfiw" => "__builtin_qpx_qvstfiw", + "qpx.qvstfiwa" => "__builtin_qpx_qvstfiwa", + "qpx.qvstfs" => "__builtin_qpx_qvstfs", + "qpx.qvstfsa" => "__builtin_qpx_qvstfsa", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "ptx" => match name { + "bar.sync" => "__builtin_ptx_bar_sync", + "read.clock" => "__builtin_ptx_read_clock", + "read.clock64" => "__builtin_ptx_read_clock64", + "read.gridid" => "__builtin_ptx_read_gridid", + "read.laneid" => "__builtin_ptx_read_laneid", + "read.lanemask.eq" => "__builtin_ptx_read_lanemask_eq", + "read.lanemask.ge" => "__builtin_ptx_read_lanemask_ge", + "read.lanemask.gt" => "__builtin_ptx_read_lanemask_gt", + "read.lanemask.le" => "__builtin_ptx_read_lanemask_le", + "read.lanemask.lt" => "__builtin_ptx_read_lanemask_lt", + "read.nsmid" => "__builtin_ptx_read_nsmid", + "read.nwarpid" => "__builtin_ptx_read_nwarpid", + "read.pm0" => "__builtin_ptx_read_pm0", + "read.pm1" => "__builtin_ptx_read_pm1", + "read.pm2" => "__builtin_ptx_read_pm2", + "read.pm3" => "__builtin_ptx_read_pm3", + "read.smid" => "__builtin_ptx_read_smid", + "read.warpid" => "__builtin_ptx_read_warpid", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "x86" => match name { + "addcarry.u32" => "__builtin_ia32_addcarry_u32", + "addcarry.u64" => "__builtin_ia32_addcarry_u64", + "addcarryx.u32" => "__builtin_ia32_addcarryx_u32", + "addcarryx.u64" => "__builtin_ia32_addcarryx_u64", + "avx.blend.pd.256" => "__builtin_ia32_blendpd256", + "avx.blend.ps.256" => "__builtin_ia32_blendps256", + "avx.cmp.pd.256" => "__builtin_ia32_cmppd256", + "avx.cmp.ps.256" => "__builtin_ia32_cmpps256", + "avx.cvt.ps2.pd.256" => "__builtin_ia32_cvtps2pd256", + "avx.cvtdq2.pd.256" => "__builtin_ia32_cvtdq2pd256", + "avx.cvtdq2.ps.256" => "__builtin_ia32_cvtdq2ps256", + "avx.sqrt.pd.256" => "__builtin_ia32_sqrtpd256", + "avx.sqrt.ps.256" => "__builtin_ia32_sqrtps256", + "avx.storeu.dq.256" => "__builtin_ia32_storedqu256", + "avx.storeu.pd.256" => "__builtin_ia32_storeupd256", + "avx.storeu.ps.256" => "__builtin_ia32_storeups256", + "avx.vbroadcastf128.pd.256" => "__builtin_ia32_vbroadcastf128_pd256", + "avx.vbroadcastf128.ps.256" => "__builtin_ia32_vbroadcastf128_ps256", + "avx.vextractf128.pd.256" => "__builtin_ia32_vextractf128_pd256", + "avx.vextractf128.ps.256" => "__builtin_ia32_vextractf128_ps256", + "avx.vextractf128.si.256" => "__builtin_ia32_vextractf128_si256", + "avx.vinsertf128.pd.256" => "__builtin_ia32_vinsertf128_pd256", + "avx.vinsertf128.ps.256" => "__builtin_ia32_vinsertf128_ps256", + "avx.vinsertf128.si.256" => "__builtin_ia32_vinsertf128_si256", + "avx.vperm2f128.pd.256" => "__builtin_ia32_vperm2f128_pd256", + "avx.vperm2f128.ps.256" => "__builtin_ia32_vperm2f128_ps256", + "avx.vperm2f128.si.256" => "__builtin_ia32_vperm2f128_si256", + "avx2.movntdqa" => "__builtin_ia32_movntdqa256", + "avx2.pabs.b" => "__builtin_ia32_pabsb256", + "avx2.pabs.d" => "__builtin_ia32_pabsd256", + "avx2.pabs.w" => "__builtin_ia32_pabsw256", + "avx2.padds.b" => "__builtin_ia32_paddsb256", + "avx2.padds.w" => "__builtin_ia32_paddsw256", + "avx2.paddus.b" => "__builtin_ia32_paddusb256", + "avx2.paddus.w" => "__builtin_ia32_paddusw256", + "avx2.pblendd.128" => "__builtin_ia32_pblendd128", + "avx2.pblendd.256" => "__builtin_ia32_pblendd256", + "avx2.pblendw" => "__builtin_ia32_pblendw256", + "avx2.pbroadcastb.128" => "__builtin_ia32_pbroadcastb128", + "avx2.pbroadcastb.256" => "__builtin_ia32_pbroadcastb256", + "avx2.pbroadcastd.128" => "__builtin_ia32_pbroadcastd128", + "avx2.pbroadcastd.256" => "__builtin_ia32_pbroadcastd256", + "avx2.pbroadcastq.128" => "__builtin_ia32_pbroadcastq128", + "avx2.pbroadcastq.256" => "__builtin_ia32_pbroadcastq256", + "avx2.pbroadcastw.128" => "__builtin_ia32_pbroadcastw128", + "avx2.pbroadcastw.256" => "__builtin_ia32_pbroadcastw256", + "avx2.pmaxs.b" => "__builtin_ia32_pmaxsb256", + "avx2.pmaxs.d" => "__builtin_ia32_pmaxsd256", + "avx2.pmaxs.w" => "__builtin_ia32_pmaxsw256", + "avx2.pmaxu.b" => "__builtin_ia32_pmaxub256", + "avx2.pmaxu.d" => "__builtin_ia32_pmaxud256", + "avx2.pmaxu.w" => "__builtin_ia32_pmaxuw256", + "avx2.pmins.b" => "__builtin_ia32_pminsb256", + "avx2.pmins.d" => "__builtin_ia32_pminsd256", + "avx2.pmins.w" => "__builtin_ia32_pminsw256", + "avx2.pminu.b" => "__builtin_ia32_pminub256", + "avx2.pminu.d" => "__builtin_ia32_pminud256", + "avx2.pminu.w" => "__builtin_ia32_pminuw256", + "avx2.pmovsxbd" => "__builtin_ia32_pmovsxbd256", + "avx2.pmovsxbq" => "__builtin_ia32_pmovsxbq256", + "avx2.pmovsxbw" => "__builtin_ia32_pmovsxbw256", + "avx2.pmovsxdq" => "__builtin_ia32_pmovsxdq256", + "avx2.pmovsxwd" => "__builtin_ia32_pmovsxwd256", + "avx2.pmovsxwq" => "__builtin_ia32_pmovsxwq256", + "avx2.pmovzxbd" => "__builtin_ia32_pmovzxbd256", + "avx2.pmovzxbq" => "__builtin_ia32_pmovzxbq256", + "avx2.pmovzxbw" => "__builtin_ia32_pmovzxbw256", + "avx2.pmovzxdq" => "__builtin_ia32_pmovzxdq256", + "avx2.pmovzxwd" => "__builtin_ia32_pmovzxwd256", + "avx2.pmovzxwq" => "__builtin_ia32_pmovzxwq256", + "avx2.pmul.dq" => "__builtin_ia32_pmuldq256", + "avx2.pmulu.dq" => "__builtin_ia32_pmuludq256", + "avx2.psll.dq" => "__builtin_ia32_pslldqi256", + "avx2.psll.dq.bs" => "__builtin_ia32_pslldqi256_byteshift", + "avx2.psrl.dq" => "__builtin_ia32_psrldqi256", + "avx2.psrl.dq.bs" => "__builtin_ia32_psrldqi256_byteshift", + "avx2.psubs.b" => "__builtin_ia32_psubsb256", + "avx2.psubs.w" => "__builtin_ia32_psubsw256", + "avx2.psubus.b" => "__builtin_ia32_psubusb256", + "avx2.psubus.w" => "__builtin_ia32_psubusw256", + "avx2.vbroadcast.sd.pd.256" => "__builtin_ia32_vbroadcastsd_pd256", + "avx2.vbroadcast.ss.ps" => "__builtin_ia32_vbroadcastss_ps", + "avx2.vbroadcast.ss.ps.256" => "__builtin_ia32_vbroadcastss_ps256", + "avx2.vextracti128" => "__builtin_ia32_extract128i256", + "avx2.vinserti128" => "__builtin_ia32_insert128i256", + "avx2.vperm2i128" => "__builtin_ia32_permti256", + "avx512.cvtb2mask.128" => "__builtin_ia32_cvtb2mask128", + "avx512.cvtb2mask.256" => "__builtin_ia32_cvtb2mask256", + "avx512.cvtb2mask.512" => "__builtin_ia32_cvtb2mask512", + "avx512.cvtd2mask.128" => "__builtin_ia32_cvtd2mask128", + "avx512.cvtd2mask.256" => "__builtin_ia32_cvtd2mask256", + "avx512.cvtd2mask.512" => "__builtin_ia32_cvtd2mask512", + "avx512.cvtmask2b.128" => "__builtin_ia32_cvtmask2b128", + "avx512.cvtmask2b.256" => "__builtin_ia32_cvtmask2b256", + "avx512.cvtmask2b.512" => "__builtin_ia32_cvtmask2b512", + "avx512.cvtmask2d.128" => "__builtin_ia32_cvtmask2d128", + "avx512.cvtmask2d.256" => "__builtin_ia32_cvtmask2d256", + "avx512.cvtmask2d.512" => "__builtin_ia32_cvtmask2d512", + "avx512.cvtmask2q.128" => "__builtin_ia32_cvtmask2q128", + "avx512.cvtmask2q.256" => "__builtin_ia32_cvtmask2q256", + "avx512.cvtmask2q.512" => "__builtin_ia32_cvtmask2q512", + "avx512.cvtmask2w.128" => "__builtin_ia32_cvtmask2w128", + "avx512.cvtmask2w.256" => "__builtin_ia32_cvtmask2w256", + "avx512.cvtmask2w.512" => "__builtin_ia32_cvtmask2w512", + "avx512.cvtq2mask.128" => "__builtin_ia32_cvtq2mask128", + "avx512.cvtq2mask.256" => "__builtin_ia32_cvtq2mask256", + "avx512.cvtq2mask.512" => "__builtin_ia32_cvtq2mask512", + "avx512.cvtsd2usi" => "__builtin_ia32_cvtsd2usi", + "avx512.cvtsd2usi64" => "__builtin_ia32_cvtsd2usi64", + "avx512.cvtsi2sd32" => "__builtin_ia32_cvtsi2sd32", + "avx512.cvtss2usi" => "__builtin_ia32_cvtss2usi", + "avx512.cvtss2usi64" => "__builtin_ia32_cvtss2usi64", + "avx512.cvtw2mask.128" => "__builtin_ia32_cvtw2mask128", + "avx512.cvtw2mask.256" => "__builtin_ia32_cvtw2mask256", + "avx512.cvtw2mask.512" => "__builtin_ia32_cvtw2mask512", + "avx512.exp2.pd" => "__builtin_ia32_exp2pd_mask", + "avx512.exp2.ps" => "__builtin_ia32_exp2ps_mask", + "avx512.gather.dpd.512" => "__builtin_ia32_gathersiv8df", + "avx512.gather.dpi.512" => "__builtin_ia32_gathersiv16si", + "avx512.gather.dpq.512" => "__builtin_ia32_gathersiv8di", + "avx512.gather.dps.512" => "__builtin_ia32_gathersiv16sf", + "avx512.gather.qpd.512" => "__builtin_ia32_gatherdiv8df", + "avx512.gather.qpi.512" => "__builtin_ia32_gatherdiv16si", + "avx512.gather.qpq.512" => "__builtin_ia32_gatherdiv8di", + "avx512.gather.qps.512" => "__builtin_ia32_gatherdiv16sf", + "avx512.gather3div2.df" => "__builtin_ia32_gather3div2df", + "avx512.gather3div2.di" => "__builtin_ia32_gather3div2di", + "avx512.gather3div4.df" => "__builtin_ia32_gather3div4df", + "avx512.gather3div4.di" => "__builtin_ia32_gather3div4di", + "avx512.gather3div4.sf" => "__builtin_ia32_gather3div4sf", + "avx512.gather3div4.si" => "__builtin_ia32_gather3div4si", + "avx512.gather3div8.sf" => "__builtin_ia32_gather3div8sf", + "avx512.gather3div8.si" => "__builtin_ia32_gather3div8si", + "avx512.gather3siv2.df" => "__builtin_ia32_gather3siv2df", + "avx512.gather3siv2.di" => "__builtin_ia32_gather3siv2di", + "avx512.gather3siv4.df" => "__builtin_ia32_gather3siv4df", + "avx512.gather3siv4.di" => "__builtin_ia32_gather3siv4di", + "avx512.gather3siv4.sf" => "__builtin_ia32_gather3siv4sf", + "avx512.gather3siv4.si" => "__builtin_ia32_gather3siv4si", + "avx512.gather3siv8.sf" => "__builtin_ia32_gather3siv8sf", + "avx512.gather3siv8.si" => "__builtin_ia32_gather3siv8si", + "avx512.gatherpf.dpd.512" => "__builtin_ia32_gatherpfdpd", + "avx512.gatherpf.dps.512" => "__builtin_ia32_gatherpfdps", + "avx512.gatherpf.qpd.512" => "__builtin_ia32_gatherpfqpd", + "avx512.gatherpf.qps.512" => "__builtin_ia32_gatherpfqps", + "avx512.kand.w" => "__builtin_ia32_kandhi", + "avx512.kandn.w" => "__builtin_ia32_kandnhi", + "avx512.knot.w" => "__builtin_ia32_knothi", + "avx512.kor.w" => "__builtin_ia32_korhi", + "avx512.kortestc.w" => "__builtin_ia32_kortestchi", + "avx512.kortestz.w" => "__builtin_ia32_kortestzhi", + "avx512.kunpck.bw" => "__builtin_ia32_kunpckhi", + "avx512.kunpck.dq" => "__builtin_ia32_kunpckdi", + "avx512.kunpck.wd" => "__builtin_ia32_kunpcksi", + "avx512.kxnor.w" => "__builtin_ia32_kxnorhi", + "avx512.kxor.w" => "__builtin_ia32_kxorhi", + "avx512.mask.add.pd.128" => "__builtin_ia32_addpd128_mask", + "avx512.mask.add.pd.256" => "__builtin_ia32_addpd256_mask", + "avx512.mask.add.pd.512" => "__builtin_ia32_addpd512_mask", + "avx512.mask.add.ps.128" => "__builtin_ia32_addps128_mask", + "avx512.mask.add.ps.256" => "__builtin_ia32_addps256_mask", + "avx512.mask.add.ps.512" => "__builtin_ia32_addps512_mask", + "avx512.mask.and.pd.128" => "__builtin_ia32_andpd128_mask", + "avx512.mask.and.pd.256" => "__builtin_ia32_andpd256_mask", + "avx512.mask.and.pd.512" => "__builtin_ia32_andpd512_mask", + "avx512.mask.and.ps.128" => "__builtin_ia32_andps128_mask", + "avx512.mask.and.ps.256" => "__builtin_ia32_andps256_mask", + "avx512.mask.and.ps.512" => "__builtin_ia32_andps512_mask", + "avx512.mask.andn.pd.128" => "__builtin_ia32_andnpd128_mask", + "avx512.mask.andn.pd.256" => "__builtin_ia32_andnpd256_mask", + "avx512.mask.andn.pd.512" => "__builtin_ia32_andnpd512_mask", + "avx512.mask.andn.ps.128" => "__builtin_ia32_andnps128_mask", + "avx512.mask.andn.ps.256" => "__builtin_ia32_andnps256_mask", + "avx512.mask.andn.ps.512" => "__builtin_ia32_andnps512_mask", + "avx512.mask.blend.d.512" => "__builtin_ia32_blendmd_512_mask", + "avx512.mask.blend.pd.512" => "__builtin_ia32_blendmpd_512_mask", + "avx512.mask.blend.ps.512" => "__builtin_ia32_blendmps_512_mask", + "avx512.mask.blend.q.512" => "__builtin_ia32_blendmq_512_mask", + "avx512.mask.broadcastf32x2.256" => "__builtin_ia32_broadcastf32x2_256_mask", + "avx512.mask.broadcastf32x2.512" => "__builtin_ia32_broadcastf32x2_512_mask", + "avx512.mask.broadcastf32x4.256" => "__builtin_ia32_broadcastf32x4_256_mask", + "avx512.mask.broadcastf32x4.512" => "__builtin_ia32_broadcastf32x4_512", + "avx512.mask.broadcastf32x8.512" => "__builtin_ia32_broadcastf32x8_512_mask", + "avx512.mask.broadcastf64x2.256" => "__builtin_ia32_broadcastf64x2_256_mask", + "avx512.mask.broadcastf64x2.512" => "__builtin_ia32_broadcastf64x2_512_mask", + "avx512.mask.broadcastf64x4.512" => "__builtin_ia32_broadcastf64x4_512", + "avx512.mask.broadcasti32x2.128" => "__builtin_ia32_broadcasti32x2_128_mask", + "avx512.mask.broadcasti32x2.256" => "__builtin_ia32_broadcasti32x2_256_mask", + "avx512.mask.broadcasti32x2.512" => "__builtin_ia32_broadcasti32x2_512_mask", + "avx512.mask.broadcasti32x4.256" => "__builtin_ia32_broadcasti32x4_256_mask", + "avx512.mask.broadcasti32x4.512" => "__builtin_ia32_broadcasti32x4_512", + "avx512.mask.broadcasti32x8.512" => "__builtin_ia32_broadcasti32x8_512_mask", + "avx512.mask.broadcasti64x2.256" => "__builtin_ia32_broadcasti64x2_256_mask", + "avx512.mask.broadcasti64x2.512" => "__builtin_ia32_broadcasti64x2_512_mask", + "avx512.mask.broadcasti64x4.512" => "__builtin_ia32_broadcasti64x4_512", + "avx512.mask.cmp.pd.128" => "__builtin_ia32_cmppd128_mask", + "avx512.mask.cmp.pd.256" => "__builtin_ia32_cmppd256_mask", + "avx512.mask.cmp.pd.512" => "__builtin_ia32_cmppd512_mask", + "avx512.mask.cmp.ps.128" => "__builtin_ia32_cmpps128_mask", + "avx512.mask.cmp.ps.256" => "__builtin_ia32_cmpps256_mask", + "avx512.mask.cmp.ps.512" => "__builtin_ia32_cmpps512_mask", + "avx512.mask.compress.d.128" => "__builtin_ia32_compresssi128_mask", + "avx512.mask.compress.d.256" => "__builtin_ia32_compresssi256_mask", + "avx512.mask.compress.d.512" => "__builtin_ia32_compresssi512_mask", + "avx512.mask.compress.pd.128" => "__builtin_ia32_compressdf128_mask", + "avx512.mask.compress.pd.256" => "__builtin_ia32_compressdf256_mask", + "avx512.mask.compress.pd.512" => "__builtin_ia32_compressdf512_mask", + "avx512.mask.compress.ps.128" => "__builtin_ia32_compresssf128_mask", + "avx512.mask.compress.ps.256" => "__builtin_ia32_compresssf256_mask", + "avx512.mask.compress.ps.512" => "__builtin_ia32_compresssf512_mask", + "avx512.mask.compress.q.128" => "__builtin_ia32_compressdi128_mask", + "avx512.mask.compress.q.256" => "__builtin_ia32_compressdi256_mask", + "avx512.mask.compress.q.512" => "__builtin_ia32_compressdi512_mask", + "avx512.mask.compress.store.d.128" => "__builtin_ia32_compressstoresi128_mask", + "avx512.mask.compress.store.d.256" => "__builtin_ia32_compressstoresi256_mask", + "avx512.mask.compress.store.d.512" => "__builtin_ia32_compressstoresi512_mask", + "avx512.mask.compress.store.pd.128" => "__builtin_ia32_compressstoredf128_mask", + "avx512.mask.compress.store.pd.256" => "__builtin_ia32_compressstoredf256_mask", + "avx512.mask.compress.store.pd.512" => "__builtin_ia32_compressstoredf512_mask", + "avx512.mask.compress.store.ps.128" => "__builtin_ia32_compressstoresf128_mask", + "avx512.mask.compress.store.ps.256" => "__builtin_ia32_compressstoresf256_mask", + "avx512.mask.compress.store.ps.512" => "__builtin_ia32_compressstoresf512_mask", + "avx512.mask.compress.store.q.128" => "__builtin_ia32_compressstoredi128_mask", + "avx512.mask.compress.store.q.256" => "__builtin_ia32_compressstoredi256_mask", + "avx512.mask.compress.store.q.512" => "__builtin_ia32_compressstoredi512_mask", + "avx512.mask.conflict.d.128" => "__builtin_ia32_vpconflictsi_128_mask", + "avx512.mask.conflict.d.256" => "__builtin_ia32_vpconflictsi_256_mask", + "avx512.mask.conflict.d.512" => "__builtin_ia32_vpconflictsi_512_mask", + "avx512.mask.conflict.q.128" => "__builtin_ia32_vpconflictdi_128_mask", + "avx512.mask.conflict.q.256" => "__builtin_ia32_vpconflictdi_256_mask", + "avx512.mask.conflict.q.512" => "__builtin_ia32_vpconflictdi_512_mask", + "avx512.mask.cvtdq2pd.128" => "__builtin_ia32_cvtdq2pd128_mask", + "avx512.mask.cvtdq2pd.256" => "__builtin_ia32_cvtdq2pd256_mask", + "avx512.mask.cvtdq2pd.512" => "__builtin_ia32_cvtdq2pd512_mask", + "avx512.mask.cvtdq2ps.128" => "__builtin_ia32_cvtdq2ps128_mask", + "avx512.mask.cvtdq2ps.256" => "__builtin_ia32_cvtdq2ps256_mask", + "avx512.mask.cvtdq2ps.512" => "__builtin_ia32_cvtdq2ps512_mask", + "avx512.mask.cvtpd2dq.256" => "__builtin_ia32_cvtpd2dq256_mask", + "avx512.mask.cvtps2pd.128" => "__builtin_ia32_cvtps2pd128_mask", + "avx512.mask.cvtps2pd.256" => "__builtin_ia32_cvtps2pd256_mask", + "avx512.mask.cvtqq2pd.128" => "__builtin_ia32_cvtqq2pd128_mask", + "avx512.mask.cvtqq2pd.256" => "__builtin_ia32_cvtqq2pd256_mask", + "avx512.mask.cvtqq2pd.512" => "__builtin_ia32_cvtqq2pd512_mask", + "avx512.mask.cvtqq2ps.256" => "__builtin_ia32_cvtqq2ps256_mask", + "avx512.mask.cvtqq2ps.512" => "__builtin_ia32_cvtqq2ps512_mask", + "avx512.mask.cvttpd2dq.256" => "__builtin_ia32_cvttpd2dq256_mask", + "avx512.mask.cvttps2dq.128" => "__builtin_ia32_cvttps2dq128_mask", + "avx512.mask.cvttps2dq.256" => "__builtin_ia32_cvttps2dq256_mask", + "avx512.mask.cvtudq2pd.128" => "__builtin_ia32_cvtudq2pd128_mask", + "avx512.mask.cvtudq2pd.256" => "__builtin_ia32_cvtudq2pd256_mask", + "avx512.mask.cvtudq2pd.512" => "__builtin_ia32_cvtudq2pd512_mask", + "avx512.mask.cvtudq2ps.128" => "__builtin_ia32_cvtudq2ps128_mask", + "avx512.mask.cvtudq2ps.256" => "__builtin_ia32_cvtudq2ps256_mask", + "avx512.mask.cvtudq2ps.512" => "__builtin_ia32_cvtudq2ps512_mask", + "avx512.mask.cvtuqq2pd.128" => "__builtin_ia32_cvtuqq2pd128_mask", + "avx512.mask.cvtuqq2pd.256" => "__builtin_ia32_cvtuqq2pd256_mask", + "avx512.mask.cvtuqq2pd.512" => "__builtin_ia32_cvtuqq2pd512_mask", + "avx512.mask.cvtuqq2ps.256" => "__builtin_ia32_cvtuqq2ps256_mask", + "avx512.mask.cvtuqq2ps.512" => "__builtin_ia32_cvtuqq2ps512_mask", + "avx512.mask.dbpsadbw.128" => "__builtin_ia32_dbpsadbw128_mask", + "avx512.mask.dbpsadbw.256" => "__builtin_ia32_dbpsadbw256_mask", + "avx512.mask.dbpsadbw.512" => "__builtin_ia32_dbpsadbw512_mask", + "avx512.mask.div.pd.128" => "__builtin_ia32_divpd_mask", + "avx512.mask.div.pd.256" => "__builtin_ia32_divpd256_mask", + "avx512.mask.div.pd.512" => "__builtin_ia32_divpd512_mask", + "avx512.mask.div.ps.128" => "__builtin_ia32_divps_mask", + "avx512.mask.div.ps.256" => "__builtin_ia32_divps256_mask", + "avx512.mask.div.ps.512" => "__builtin_ia32_divps512_mask", + "avx512.mask.expand.d.128" => "__builtin_ia32_expandsi128_mask", + "avx512.mask.expand.d.256" => "__builtin_ia32_expandsi256_mask", + "avx512.mask.expand.d.512" => "__builtin_ia32_expandsi512_mask", + "avx512.mask.expand.load.d.128" => "__builtin_ia32_expandloadsi128_mask", + "avx512.mask.expand.load.d.256" => "__builtin_ia32_expandloadsi256_mask", + "avx512.mask.expand.load.d.512" => "__builtin_ia32_expandloadsi512_mask", + "avx512.mask.expand.load.pd.128" => "__builtin_ia32_expandloaddf128_mask", + "avx512.mask.expand.load.pd.256" => "__builtin_ia32_expandloaddf256_mask", + "avx512.mask.expand.load.pd.512" => "__builtin_ia32_expandloaddf512_mask", + "avx512.mask.expand.load.ps.128" => "__builtin_ia32_expandloadsf128_mask", + "avx512.mask.expand.load.ps.256" => "__builtin_ia32_expandloadsf256_mask", + "avx512.mask.expand.load.ps.512" => "__builtin_ia32_expandloadsf512_mask", + "avx512.mask.expand.load.q.128" => "__builtin_ia32_expandloaddi128_mask", + "avx512.mask.expand.load.q.256" => "__builtin_ia32_expandloaddi256_mask", + "avx512.mask.expand.load.q.512" => "__builtin_ia32_expandloaddi512_mask", + "avx512.mask.expand.pd.128" => "__builtin_ia32_expanddf128_mask", + "avx512.mask.expand.pd.256" => "__builtin_ia32_expanddf256_mask", + "avx512.mask.expand.pd.512" => "__builtin_ia32_expanddf512_mask", + "avx512.mask.expand.ps.128" => "__builtin_ia32_expandsf128_mask", + "avx512.mask.expand.ps.256" => "__builtin_ia32_expandsf256_mask", + "avx512.mask.expand.ps.512" => "__builtin_ia32_expandsf512_mask", + "avx512.mask.expand.q.128" => "__builtin_ia32_expanddi128_mask", + "avx512.mask.expand.q.256" => "__builtin_ia32_expanddi256_mask", + "avx512.mask.expand.q.512" => "__builtin_ia32_expanddi512_mask", + "avx512.mask.fpclass.pd.128" => "__builtin_ia32_fpclasspd128_mask", + "avx512.mask.fpclass.pd.256" => "__builtin_ia32_fpclasspd256_mask", + "avx512.mask.fpclass.pd.512" => "__builtin_ia32_fpclasspd512_mask", + "avx512.mask.fpclass.ps.128" => "__builtin_ia32_fpclassps128_mask", + "avx512.mask.fpclass.ps.256" => "__builtin_ia32_fpclassps256_mask", + "avx512.mask.fpclass.ps.512" => "__builtin_ia32_fpclassps512_mask", + "avx512.mask.insertf32x4.256" => "__builtin_ia32_insertf32x4_256_mask", + "avx512.mask.insertf32x4.512" => "__builtin_ia32_insertf32x4_mask", + "avx512.mask.insertf32x8.512" => "__builtin_ia32_insertf32x8_mask", + "avx512.mask.insertf64x2.256" => "__builtin_ia32_insertf64x2_256_mask", + "avx512.mask.insertf64x2.512" => "__builtin_ia32_insertf64x2_512_mask", + "avx512.mask.insertf64x4.512" => "__builtin_ia32_insertf64x4_mask", + "avx512.mask.inserti32x4.256" => "__builtin_ia32_inserti32x4_256_mask", + "avx512.mask.inserti32x4.512" => "__builtin_ia32_inserti32x4_mask", + "avx512.mask.inserti32x8.512" => "__builtin_ia32_inserti32x8_mask", + "avx512.mask.inserti64x2.256" => "__builtin_ia32_inserti64x2_256_mask", + "avx512.mask.inserti64x2.512" => "__builtin_ia32_inserti64x2_512_mask", + "avx512.mask.inserti64x4.512" => "__builtin_ia32_inserti64x4_mask", + "avx512.mask.loadu.d.512" => "__builtin_ia32_loaddqusi512_mask", + "avx512.mask.loadu.pd.512" => "__builtin_ia32_loadupd512_mask", + "avx512.mask.loadu.ps.512" => "__builtin_ia32_loadups512_mask", + "avx512.mask.loadu.q.512" => "__builtin_ia32_loaddqudi512_mask", + "avx512.mask.lzcnt.d.512" => "__builtin_ia32_vplzcntd_512_mask", + "avx512.mask.lzcnt.q.512" => "__builtin_ia32_vplzcntq_512_mask", + "avx512.mask.max.pd.128" => "__builtin_ia32_maxpd_mask", + "avx512.mask.max.pd.256" => "__builtin_ia32_maxpd256_mask", + "avx512.mask.max.pd.512" => "__builtin_ia32_maxpd512_mask", + "avx512.mask.max.ps.128" => "__builtin_ia32_maxps_mask", + "avx512.mask.max.ps.256" => "__builtin_ia32_maxps256_mask", + "avx512.mask.max.ps.512" => "__builtin_ia32_maxps512_mask", + "avx512.mask.min.pd.128" => "__builtin_ia32_minpd_mask", + "avx512.mask.min.pd.256" => "__builtin_ia32_minpd256_mask", + "avx512.mask.min.pd.512" => "__builtin_ia32_minpd512_mask", + "avx512.mask.min.ps.128" => "__builtin_ia32_minps_mask", + "avx512.mask.min.ps.256" => "__builtin_ia32_minps256_mask", + "avx512.mask.min.ps.512" => "__builtin_ia32_minps512_mask", + "avx512.mask.move.sd" => "__builtin_ia32_movsd_mask", + "avx512.mask.move.ss" => "__builtin_ia32_movss_mask", + "avx512.mask.mul.pd.128" => "__builtin_ia32_mulpd_mask", + "avx512.mask.mul.pd.256" => "__builtin_ia32_mulpd256_mask", + "avx512.mask.mul.pd.512" => "__builtin_ia32_mulpd512_mask", + "avx512.mask.mul.ps.128" => "__builtin_ia32_mulps_mask", + "avx512.mask.mul.ps.256" => "__builtin_ia32_mulps256_mask", + "avx512.mask.mul.ps.512" => "__builtin_ia32_mulps512_mask", + "avx512.mask.or.pd.128" => "__builtin_ia32_orpd128_mask", + "avx512.mask.or.pd.256" => "__builtin_ia32_orpd256_mask", + "avx512.mask.or.pd.512" => "__builtin_ia32_orpd512_mask", + "avx512.mask.or.ps.128" => "__builtin_ia32_orps128_mask", + "avx512.mask.or.ps.256" => "__builtin_ia32_orps256_mask", + "avx512.mask.or.ps.512" => "__builtin_ia32_orps512_mask", + "avx512.mask.pabs.b.128" => "__builtin_ia32_pabsb128_mask", + "avx512.mask.pabs.b.256" => "__builtin_ia32_pabsb256_mask", + "avx512.mask.pabs.b.512" => "__builtin_ia32_pabsb512_mask", + "avx512.mask.pabs.d.128" => "__builtin_ia32_pabsd128_mask", + "avx512.mask.pabs.d.256" => "__builtin_ia32_pabsd256_mask", + "avx512.mask.pabs.d.512" => "__builtin_ia32_pabsd512_mask", + "avx512.mask.pabs.q.128" => "__builtin_ia32_pabsq128_mask", + "avx512.mask.pabs.q.256" => "__builtin_ia32_pabsq256_mask", + "avx512.mask.pabs.q.512" => "__builtin_ia32_pabsq512_mask", + "avx512.mask.pabs.w.128" => "__builtin_ia32_pabsw128_mask", + "avx512.mask.pabs.w.256" => "__builtin_ia32_pabsw256_mask", + "avx512.mask.pabs.w.512" => "__builtin_ia32_pabsw512_mask", + "avx512.mask.packssdw.128" => "__builtin_ia32_packssdw128_mask", + "avx512.mask.packssdw.256" => "__builtin_ia32_packssdw256_mask", + "avx512.mask.packssdw.512" => "__builtin_ia32_packssdw512_mask", + "avx512.mask.packsswb.128" => "__builtin_ia32_packsswb128_mask", + "avx512.mask.packsswb.256" => "__builtin_ia32_packsswb256_mask", + "avx512.mask.packsswb.512" => "__builtin_ia32_packsswb512_mask", + "avx512.mask.packusdw.128" => "__builtin_ia32_packusdw128_mask", + "avx512.mask.packusdw.256" => "__builtin_ia32_packusdw256_mask", + "avx512.mask.packusdw.512" => "__builtin_ia32_packusdw512_mask", + "avx512.mask.packuswb.128" => "__builtin_ia32_packuswb128_mask", + "avx512.mask.packuswb.256" => "__builtin_ia32_packuswb256_mask", + "avx512.mask.packuswb.512" => "__builtin_ia32_packuswb512_mask", + "avx512.mask.padd.b.128" => "__builtin_ia32_paddb128_mask", + "avx512.mask.padd.b.256" => "__builtin_ia32_paddb256_mask", + "avx512.mask.padd.b.512" => "__builtin_ia32_paddb512_mask", + "avx512.mask.padd.d.128" => "__builtin_ia32_paddd128_mask", + "avx512.mask.padd.d.256" => "__builtin_ia32_paddd256_mask", + "avx512.mask.padd.d.512" => "__builtin_ia32_paddd512_mask", + "avx512.mask.padd.q.128" => "__builtin_ia32_paddq128_mask", + "avx512.mask.padd.q.256" => "__builtin_ia32_paddq256_mask", + "avx512.mask.padd.q.512" => "__builtin_ia32_paddq512_mask", + "avx512.mask.padd.w.128" => "__builtin_ia32_paddw128_mask", + "avx512.mask.padd.w.256" => "__builtin_ia32_paddw256_mask", + "avx512.mask.padd.w.512" => "__builtin_ia32_paddw512_mask", + "avx512.mask.padds.b.128" => "__builtin_ia32_paddsb128_mask", + "avx512.mask.padds.b.256" => "__builtin_ia32_paddsb256_mask", + "avx512.mask.padds.b.512" => "__builtin_ia32_paddsb512_mask", + "avx512.mask.padds.w.128" => "__builtin_ia32_paddsw128_mask", + "avx512.mask.padds.w.256" => "__builtin_ia32_paddsw256_mask", + "avx512.mask.padds.w.512" => "__builtin_ia32_paddsw512_mask", + "avx512.mask.paddus.b.128" => "__builtin_ia32_paddusb128_mask", + "avx512.mask.paddus.b.256" => "__builtin_ia32_paddusb256_mask", + "avx512.mask.paddus.b.512" => "__builtin_ia32_paddusb512_mask", + "avx512.mask.paddus.w.128" => "__builtin_ia32_paddusw128_mask", + "avx512.mask.paddus.w.256" => "__builtin_ia32_paddusw256_mask", + "avx512.mask.paddus.w.512" => "__builtin_ia32_paddusw512_mask", + "avx512.mask.pand.d.512" => "__builtin_ia32_pandd512_mask", + "avx512.mask.pand.q.512" => "__builtin_ia32_pandq512_mask", + "avx512.mask.pavg.b.128" => "__builtin_ia32_pavgb128_mask", + "avx512.mask.pavg.b.256" => "__builtin_ia32_pavgb256_mask", + "avx512.mask.pavg.b.512" => "__builtin_ia32_pavgb512_mask", + "avx512.mask.pavg.w.128" => "__builtin_ia32_pavgw128_mask", + "avx512.mask.pavg.w.256" => "__builtin_ia32_pavgw256_mask", + "avx512.mask.pavg.w.512" => "__builtin_ia32_pavgw512_mask", + "avx512.mask.pbroadcast.b.gpr.128" => "__builtin_ia32_pbroadcastb128_gpr_mask", + "avx512.mask.pbroadcast.b.gpr.256" => "__builtin_ia32_pbroadcastb256_gpr_mask", + "avx512.mask.pbroadcast.b.gpr.512" => "__builtin_ia32_pbroadcastb512_gpr_mask", + "avx512.mask.pbroadcast.d.gpr.128" => "__builtin_ia32_pbroadcastd128_gpr_mask", + "avx512.mask.pbroadcast.d.gpr.256" => "__builtin_ia32_pbroadcastd256_gpr_mask", + "avx512.mask.pbroadcast.d.gpr.512" => "__builtin_ia32_pbroadcastd512_gpr_mask", + "avx512.mask.pbroadcast.q.gpr.128" => "__builtin_ia32_pbroadcastq128_gpr_mask", + "avx512.mask.pbroadcast.q.gpr.256" => "__builtin_ia32_pbroadcastq256_gpr_mask", + "avx512.mask.pbroadcast.q.gpr.512" => "__builtin_ia32_pbroadcastq512_gpr_mask", + "avx512.mask.pbroadcast.q.mem.512" => "__builtin_ia32_pbroadcastq512_mem_mask", + "avx512.mask.pbroadcast.w.gpr.128" => "__builtin_ia32_pbroadcastw128_gpr_mask", + "avx512.mask.pbroadcast.w.gpr.256" => "__builtin_ia32_pbroadcastw256_gpr_mask", + "avx512.mask.pbroadcast.w.gpr.512" => "__builtin_ia32_pbroadcastw512_gpr_mask", + "avx512.mask.pcmpeq.b.128" => "__builtin_ia32_pcmpeqb128_mask", + "avx512.mask.pcmpeq.b.256" => "__builtin_ia32_pcmpeqb256_mask", + "avx512.mask.pcmpeq.b.512" => "__builtin_ia32_pcmpeqb512_mask", + "avx512.mask.pcmpeq.d.128" => "__builtin_ia32_pcmpeqd128_mask", + "avx512.mask.pcmpeq.d.256" => "__builtin_ia32_pcmpeqd256_mask", + "avx512.mask.pcmpeq.d.512" => "__builtin_ia32_pcmpeqd512_mask", + "avx512.mask.pcmpeq.q.128" => "__builtin_ia32_pcmpeqq128_mask", + "avx512.mask.pcmpeq.q.256" => "__builtin_ia32_pcmpeqq256_mask", + "avx512.mask.pcmpeq.q.512" => "__builtin_ia32_pcmpeqq512_mask", + "avx512.mask.pcmpeq.w.128" => "__builtin_ia32_pcmpeqw128_mask", + "avx512.mask.pcmpeq.w.256" => "__builtin_ia32_pcmpeqw256_mask", + "avx512.mask.pcmpeq.w.512" => "__builtin_ia32_pcmpeqw512_mask", + "avx512.mask.pcmpgt.b.128" => "__builtin_ia32_pcmpgtb128_mask", + "avx512.mask.pcmpgt.b.256" => "__builtin_ia32_pcmpgtb256_mask", + "avx512.mask.pcmpgt.b.512" => "__builtin_ia32_pcmpgtb512_mask", + "avx512.mask.pcmpgt.d.128" => "__builtin_ia32_pcmpgtd128_mask", + "avx512.mask.pcmpgt.d.256" => "__builtin_ia32_pcmpgtd256_mask", + "avx512.mask.pcmpgt.d.512" => "__builtin_ia32_pcmpgtd512_mask", + "avx512.mask.pcmpgt.q.128" => "__builtin_ia32_pcmpgtq128_mask", + "avx512.mask.pcmpgt.q.256" => "__builtin_ia32_pcmpgtq256_mask", + "avx512.mask.pcmpgt.q.512" => "__builtin_ia32_pcmpgtq512_mask", + "avx512.mask.pcmpgt.w.128" => "__builtin_ia32_pcmpgtw128_mask", + "avx512.mask.pcmpgt.w.256" => "__builtin_ia32_pcmpgtw256_mask", + "avx512.mask.pcmpgt.w.512" => "__builtin_ia32_pcmpgtw512_mask", + "avx512.mask.permvar.df.256" => "__builtin_ia32_permvardf256_mask", + "avx512.mask.permvar.df.512" => "__builtin_ia32_permvardf512_mask", + "avx512.mask.permvar.di.256" => "__builtin_ia32_permvardi256_mask", + "avx512.mask.permvar.di.512" => "__builtin_ia32_permvardi512_mask", + "avx512.mask.permvar.hi.128" => "__builtin_ia32_permvarhi128_mask", + "avx512.mask.permvar.hi.256" => "__builtin_ia32_permvarhi256_mask", + "avx512.mask.permvar.hi.512" => "__builtin_ia32_permvarhi512_mask", + "avx512.mask.permvar.qi.128" => "__builtin_ia32_permvarqi128_mask", + "avx512.mask.permvar.qi.256" => "__builtin_ia32_permvarqi256_mask", + "avx512.mask.permvar.qi.512" => "__builtin_ia32_permvarqi512_mask", + "avx512.mask.permvar.sf.256" => "__builtin_ia32_permvarsf256_mask", + "avx512.mask.permvar.sf.512" => "__builtin_ia32_permvarsf512_mask", + "avx512.mask.permvar.si.256" => "__builtin_ia32_permvarsi256_mask", + "avx512.mask.permvar.si.512" => "__builtin_ia32_permvarsi512_mask", + "avx512.mask.pmaddubs.w.128" => "__builtin_ia32_pmaddubsw128_mask", + "avx512.mask.pmaddubs.w.256" => "__builtin_ia32_pmaddubsw256_mask", + "avx512.mask.pmaddubs.w.512" => "__builtin_ia32_pmaddubsw512_mask", + "avx512.mask.pmaddw.d.128" => "__builtin_ia32_pmaddwd128_mask", + "avx512.mask.pmaddw.d.256" => "__builtin_ia32_pmaddwd256_mask", + "avx512.mask.pmaddw.d.512" => "__builtin_ia32_pmaddwd512_mask", + "avx512.mask.pmaxs.b.128" => "__builtin_ia32_pmaxsb128_mask", + "avx512.mask.pmaxs.b.256" => "__builtin_ia32_pmaxsb256_mask", + "avx512.mask.pmaxs.b.512" => "__builtin_ia32_pmaxsb512_mask", + "avx512.mask.pmaxs.d.128" => "__builtin_ia32_pmaxsd128_mask", + "avx512.mask.pmaxs.d.256" => "__builtin_ia32_pmaxsd256_mask", + "avx512.mask.pmaxs.d.512" => "__builtin_ia32_pmaxsd512_mask", + "avx512.mask.pmaxs.q.128" => "__builtin_ia32_pmaxsq128_mask", + "avx512.mask.pmaxs.q.256" => "__builtin_ia32_pmaxsq256_mask", + "avx512.mask.pmaxs.q.512" => "__builtin_ia32_pmaxsq512_mask", + "avx512.mask.pmaxs.w.128" => "__builtin_ia32_pmaxsw128_mask", + "avx512.mask.pmaxs.w.256" => "__builtin_ia32_pmaxsw256_mask", + "avx512.mask.pmaxs.w.512" => "__builtin_ia32_pmaxsw512_mask", + "avx512.mask.pmaxu.b.128" => "__builtin_ia32_pmaxub128_mask", + "avx512.mask.pmaxu.b.256" => "__builtin_ia32_pmaxub256_mask", + "avx512.mask.pmaxu.b.512" => "__builtin_ia32_pmaxub512_mask", + "avx512.mask.pmaxu.d.128" => "__builtin_ia32_pmaxud128_mask", + "avx512.mask.pmaxu.d.256" => "__builtin_ia32_pmaxud256_mask", + "avx512.mask.pmaxu.d.512" => "__builtin_ia32_pmaxud512_mask", + "avx512.mask.pmaxu.q.128" => "__builtin_ia32_pmaxuq128_mask", + "avx512.mask.pmaxu.q.256" => "__builtin_ia32_pmaxuq256_mask", + "avx512.mask.pmaxu.q.512" => "__builtin_ia32_pmaxuq512_mask", + "avx512.mask.pmaxu.w.128" => "__builtin_ia32_pmaxuw128_mask", + "avx512.mask.pmaxu.w.256" => "__builtin_ia32_pmaxuw256_mask", + "avx512.mask.pmaxu.w.512" => "__builtin_ia32_pmaxuw512_mask", + "avx512.mask.pmins.b.128" => "__builtin_ia32_pminsb128_mask", + "avx512.mask.pmins.b.256" => "__builtin_ia32_pminsb256_mask", + "avx512.mask.pmins.b.512" => "__builtin_ia32_pminsb512_mask", + "avx512.mask.pmins.d.128" => "__builtin_ia32_pminsd128_mask", + "avx512.mask.pmins.d.256" => "__builtin_ia32_pminsd256_mask", + "avx512.mask.pmins.d.512" => "__builtin_ia32_pminsd512_mask", + "avx512.mask.pmins.q.128" => "__builtin_ia32_pminsq128_mask", + "avx512.mask.pmins.q.256" => "__builtin_ia32_pminsq256_mask", + "avx512.mask.pmins.q.512" => "__builtin_ia32_pminsq512_mask", + "avx512.mask.pmins.w.128" => "__builtin_ia32_pminsw128_mask", + "avx512.mask.pmins.w.256" => "__builtin_ia32_pminsw256_mask", + "avx512.mask.pmins.w.512" => "__builtin_ia32_pminsw512_mask", + "avx512.mask.pminu.b.128" => "__builtin_ia32_pminub128_mask", + "avx512.mask.pminu.b.256" => "__builtin_ia32_pminub256_mask", + "avx512.mask.pminu.b.512" => "__builtin_ia32_pminub512_mask", + "avx512.mask.pminu.d.128" => "__builtin_ia32_pminud128_mask", + "avx512.mask.pminu.d.256" => "__builtin_ia32_pminud256_mask", + "avx512.mask.pminu.d.512" => "__builtin_ia32_pminud512_mask", + "avx512.mask.pminu.q.128" => "__builtin_ia32_pminuq128_mask", + "avx512.mask.pminu.q.256" => "__builtin_ia32_pminuq256_mask", + "avx512.mask.pminu.q.512" => "__builtin_ia32_pminuq512_mask", + "avx512.mask.pminu.w.128" => "__builtin_ia32_pminuw128_mask", + "avx512.mask.pminu.w.256" => "__builtin_ia32_pminuw256_mask", + "avx512.mask.pminu.w.512" => "__builtin_ia32_pminuw512_mask", + "avx512.mask.pmov.db.512" => "__builtin_ia32_pmovdb512_mask", + "avx512.mask.pmov.dw.512" => "__builtin_ia32_pmovdw512_mask", + "avx512.mask.pmov.qd.256" => "__builtin_ia32_pmovqd256_mask", + "avx512.mask.pmov.qd.512" => "__builtin_ia32_pmovqd512_mask", + "avx512.mask.pmov.qw.512" => "__builtin_ia32_pmovqw512_mask", + "avx512.mask.pmov.wb.256" => "__builtin_ia32_pmovwb256_mask", + "avx512.mask.pmov.wb.512" => "__builtin_ia32_pmovwb512_mask", + "avx512.mask.pmovsxb.d.128" => "__builtin_ia32_pmovsxbd128_mask", + "avx512.mask.pmovsxb.d.256" => "__builtin_ia32_pmovsxbd256_mask", + "avx512.mask.pmovsxb.d.512" => "__builtin_ia32_pmovsxbd512_mask", + "avx512.mask.pmovsxb.q.128" => "__builtin_ia32_pmovsxbq128_mask", + "avx512.mask.pmovsxb.q.256" => "__builtin_ia32_pmovsxbq256_mask", + "avx512.mask.pmovsxb.q.512" => "__builtin_ia32_pmovsxbq512_mask", + "avx512.mask.pmovsxb.w.128" => "__builtin_ia32_pmovsxbw128_mask", + "avx512.mask.pmovsxb.w.256" => "__builtin_ia32_pmovsxbw256_mask", + "avx512.mask.pmovsxb.w.512" => "__builtin_ia32_pmovsxbw512_mask", + "avx512.mask.pmovsxd.q.128" => "__builtin_ia32_pmovsxdq128_mask", + "avx512.mask.pmovsxd.q.256" => "__builtin_ia32_pmovsxdq256_mask", + "avx512.mask.pmovsxd.q.512" => "__builtin_ia32_pmovsxdq512_mask", + "avx512.mask.pmovsxw.d.128" => "__builtin_ia32_pmovsxwd128_mask", + "avx512.mask.pmovsxw.d.256" => "__builtin_ia32_pmovsxwd256_mask", + "avx512.mask.pmovsxw.d.512" => "__builtin_ia32_pmovsxwd512_mask", + "avx512.mask.pmovsxw.q.128" => "__builtin_ia32_pmovsxwq128_mask", + "avx512.mask.pmovsxw.q.256" => "__builtin_ia32_pmovsxwq256_mask", + "avx512.mask.pmovsxw.q.512" => "__builtin_ia32_pmovsxwq512_mask", + "avx512.mask.pmovzxb.d.128" => "__builtin_ia32_pmovzxbd128_mask", + "avx512.mask.pmovzxb.d.256" => "__builtin_ia32_pmovzxbd256_mask", + "avx512.mask.pmovzxb.d.512" => "__builtin_ia32_pmovzxbd512_mask", + "avx512.mask.pmovzxb.q.128" => "__builtin_ia32_pmovzxbq128_mask", + "avx512.mask.pmovzxb.q.256" => "__builtin_ia32_pmovzxbq256_mask", + "avx512.mask.pmovzxb.q.512" => "__builtin_ia32_pmovzxbq512_mask", + "avx512.mask.pmovzxb.w.128" => "__builtin_ia32_pmovzxbw128_mask", + "avx512.mask.pmovzxb.w.256" => "__builtin_ia32_pmovzxbw256_mask", + "avx512.mask.pmovzxb.w.512" => "__builtin_ia32_pmovzxbw512_mask", + "avx512.mask.pmovzxd.q.128" => "__builtin_ia32_pmovzxdq128_mask", + "avx512.mask.pmovzxd.q.256" => "__builtin_ia32_pmovzxdq256_mask", + "avx512.mask.pmovzxd.q.512" => "__builtin_ia32_pmovzxdq512_mask", + "avx512.mask.pmovzxw.d.128" => "__builtin_ia32_pmovzxwd128_mask", + "avx512.mask.pmovzxw.d.256" => "__builtin_ia32_pmovzxwd256_mask", + "avx512.mask.pmovzxw.d.512" => "__builtin_ia32_pmovzxwd512_mask", + "avx512.mask.pmovzxw.q.128" => "__builtin_ia32_pmovzxwq128_mask", + "avx512.mask.pmovzxw.q.256" => "__builtin_ia32_pmovzxwq256_mask", + "avx512.mask.pmovzxw.q.512" => "__builtin_ia32_pmovzxwq512_mask", + "avx512.mask.pmul.dq.128" => "__builtin_ia32_pmuldq128_mask", + "avx512.mask.pmul.dq.256" => "__builtin_ia32_pmuldq256_mask", + "avx512.mask.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask", + "avx512.mask.pmul.hr.sw.128" => "__builtin_ia32_pmulhrsw128_mask", + "avx512.mask.pmul.hr.sw.256" => "__builtin_ia32_pmulhrsw256_mask", + "avx512.mask.pmul.hr.sw.512" => "__builtin_ia32_pmulhrsw512_mask", + "avx512.mask.pmulh.w.128" => "__builtin_ia32_pmulhw128_mask", + "avx512.mask.pmulh.w.256" => "__builtin_ia32_pmulhw256_mask", + "avx512.mask.pmulh.w.512" => "__builtin_ia32_pmulhw512_mask", + "avx512.mask.pmulhu.w.128" => "__builtin_ia32_pmulhuw128_mask", + "avx512.mask.pmulhu.w.256" => "__builtin_ia32_pmulhuw256_mask", + "avx512.mask.pmulhu.w.512" => "__builtin_ia32_pmulhuw512_mask", + "avx512.mask.pmull.d.128" => "__builtin_ia32_pmulld128_mask", + "avx512.mask.pmull.d.256" => "__builtin_ia32_pmulld256_mask", + "avx512.mask.pmull.d.512" => "__builtin_ia32_pmulld512_mask", + "avx512.mask.pmull.q.128" => "__builtin_ia32_pmullq128_mask", + "avx512.mask.pmull.q.256" => "__builtin_ia32_pmullq256_mask", + "avx512.mask.pmull.q.512" => "__builtin_ia32_pmullq512_mask", + "avx512.mask.pmull.w.128" => "__builtin_ia32_pmullw128_mask", + "avx512.mask.pmull.w.256" => "__builtin_ia32_pmullw256_mask", + "avx512.mask.pmull.w.512" => "__builtin_ia32_pmullw512_mask", + "avx512.mask.pmultishift.qb.128" => "__builtin_ia32_vpmultishiftqb128_mask", + "avx512.mask.pmultishift.qb.256" => "__builtin_ia32_vpmultishiftqb256_mask", + "avx512.mask.pmultishift.qb.512" => "__builtin_ia32_vpmultishiftqb512_mask", + "avx512.mask.pmulu.dq.128" => "__builtin_ia32_pmuludq128_mask", + "avx512.mask.pmulu.dq.256" => "__builtin_ia32_pmuludq256_mask", + "avx512.mask.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask", + "avx512.mask.prol.d.128" => "__builtin_ia32_prold128_mask", + "avx512.mask.prol.d.256" => "__builtin_ia32_prold256_mask", + "avx512.mask.prol.d.512" => "__builtin_ia32_prold512_mask", + "avx512.mask.prol.q.128" => "__builtin_ia32_prolq128_mask", + "avx512.mask.prol.q.256" => "__builtin_ia32_prolq256_mask", + "avx512.mask.prol.q.512" => "__builtin_ia32_prolq512_mask", + "avx512.mask.prolv.d.128" => "__builtin_ia32_prolvd128_mask", + "avx512.mask.prolv.d.256" => "__builtin_ia32_prolvd256_mask", + "avx512.mask.prolv.d.512" => "__builtin_ia32_prolvd512_mask", + "avx512.mask.prolv.q.128" => "__builtin_ia32_prolvq128_mask", + "avx512.mask.prolv.q.256" => "__builtin_ia32_prolvq256_mask", + "avx512.mask.prolv.q.512" => "__builtin_ia32_prolvq512_mask", + "avx512.mask.pror.d.128" => "__builtin_ia32_prord128_mask", + "avx512.mask.pror.d.256" => "__builtin_ia32_prord256_mask", + "avx512.mask.pror.d.512" => "__builtin_ia32_prord512_mask", + "avx512.mask.pror.q.128" => "__builtin_ia32_prorq128_mask", + "avx512.mask.pror.q.256" => "__builtin_ia32_prorq256_mask", + "avx512.mask.pror.q.512" => "__builtin_ia32_prorq512_mask", + "avx512.mask.prorv.d.128" => "__builtin_ia32_prorvd128_mask", + "avx512.mask.prorv.d.256" => "__builtin_ia32_prorvd256_mask", + "avx512.mask.prorv.d.512" => "__builtin_ia32_prorvd512_mask", + "avx512.mask.prorv.q.128" => "__builtin_ia32_prorvq128_mask", + "avx512.mask.prorv.q.256" => "__builtin_ia32_prorvq256_mask", + "avx512.mask.prorv.q.512" => "__builtin_ia32_prorvq512_mask", + "avx512.mask.pshuf.b.128" => "__builtin_ia32_pshufb128_mask", + "avx512.mask.pshuf.b.256" => "__builtin_ia32_pshufb256_mask", + "avx512.mask.pshuf.b.512" => "__builtin_ia32_pshufb512_mask", + "avx512.mask.psll.d" => "__builtin_ia32_pslld512_mask", + "avx512.mask.psll.d.128" => "__builtin_ia32_pslld128_mask", + "avx512.mask.psll.d.256" => "__builtin_ia32_pslld256_mask", + "avx512.mask.psll.di.128" => "__builtin_ia32_pslldi128_mask", + "avx512.mask.psll.di.256" => "__builtin_ia32_pslldi256_mask", + "avx512.mask.psll.di.512" => "__builtin_ia32_pslldi512_mask", + "avx512.mask.psll.q" => "__builtin_ia32_psllq512_mask", + "avx512.mask.psll.q.128" => "__builtin_ia32_psllq128_mask", + "avx512.mask.psll.q.256" => "__builtin_ia32_psllq256_mask", + "avx512.mask.psll.qi.128" => "__builtin_ia32_psllqi128_mask", + "avx512.mask.psll.qi.256" => "__builtin_ia32_psllqi256_mask", + "avx512.mask.psll.qi.512" => "__builtin_ia32_psllqi512_mask", + "avx512.mask.psll.w.128" => "__builtin_ia32_psllw128_mask", + "avx512.mask.psll.w.256" => "__builtin_ia32_psllw256_mask", + "avx512.mask.psll.w.512" => "__builtin_ia32_psllw512_mask", + "avx512.mask.psll.wi.128" => "__builtin_ia32_psllwi128_mask", + "avx512.mask.psll.wi.256" => "__builtin_ia32_psllwi256_mask", + "avx512.mask.psll.wi.512" => "__builtin_ia32_psllwi512_mask", + "avx512.mask.psllv.d" => "__builtin_ia32_psllv16si_mask", + "avx512.mask.psllv.q" => "__builtin_ia32_psllv8di_mask", + "avx512.mask.psllv16.hi" => "__builtin_ia32_psllv16hi_mask", + "avx512.mask.psllv2.di" => "__builtin_ia32_psllv2di_mask", + "avx512.mask.psllv32hi" => "__builtin_ia32_psllv32hi_mask", + "avx512.mask.psllv4.di" => "__builtin_ia32_psllv4di_mask", + "avx512.mask.psllv4.si" => "__builtin_ia32_psllv4si_mask", + "avx512.mask.psllv8.hi" => "__builtin_ia32_psllv8hi_mask", + "avx512.mask.psllv8.si" => "__builtin_ia32_psllv8si_mask", + "avx512.mask.psra.d" => "__builtin_ia32_psrad512_mask", + "avx512.mask.psra.d.128" => "__builtin_ia32_psrad128_mask", + "avx512.mask.psra.d.256" => "__builtin_ia32_psrad256_mask", + "avx512.mask.psra.di.128" => "__builtin_ia32_psradi128_mask", + "avx512.mask.psra.di.256" => "__builtin_ia32_psradi256_mask", + "avx512.mask.psra.di.512" => "__builtin_ia32_psradi512_mask", + "avx512.mask.psra.q" => "__builtin_ia32_psraq512_mask", + "avx512.mask.psra.q.128" => "__builtin_ia32_psraq128_mask", + "avx512.mask.psra.q.256" => "__builtin_ia32_psraq256_mask", + "avx512.mask.psra.qi.128" => "__builtin_ia32_psraqi128_mask", + "avx512.mask.psra.qi.256" => "__builtin_ia32_psraqi256_mask", + "avx512.mask.psra.qi.512" => "__builtin_ia32_psraqi512_mask", + "avx512.mask.psra.w.128" => "__builtin_ia32_psraw128_mask", + "avx512.mask.psra.w.256" => "__builtin_ia32_psraw256_mask", + "avx512.mask.psra.w.512" => "__builtin_ia32_psraw512_mask", + "avx512.mask.psra.wi.128" => "__builtin_ia32_psrawi128_mask", + "avx512.mask.psra.wi.256" => "__builtin_ia32_psrawi256_mask", + "avx512.mask.psra.wi.512" => "__builtin_ia32_psrawi512_mask", + "avx512.mask.psrav.d" => "__builtin_ia32_psrav16si_mask", + "avx512.mask.psrav.q" => "__builtin_ia32_psrav8di_mask", + "avx512.mask.psrav.q.128" => "__builtin_ia32_psravq128_mask", + "avx512.mask.psrav.q.256" => "__builtin_ia32_psravq256_mask", + "avx512.mask.psrav16.hi" => "__builtin_ia32_psrav16hi_mask", + "avx512.mask.psrav32.hi" => "__builtin_ia32_psrav32hi_mask", + "avx512.mask.psrav4.si" => "__builtin_ia32_psrav4si_mask", + "avx512.mask.psrav8.hi" => "__builtin_ia32_psrav8hi_mask", + "avx512.mask.psrav8.si" => "__builtin_ia32_psrav8si_mask", + "avx512.mask.psrl.d" => "__builtin_ia32_psrld512_mask", + "avx512.mask.psrl.d.128" => "__builtin_ia32_psrld128_mask", + "avx512.mask.psrl.d.256" => "__builtin_ia32_psrld256_mask", + "avx512.mask.psrl.di.128" => "__builtin_ia32_psrldi128_mask", + "avx512.mask.psrl.di.256" => "__builtin_ia32_psrldi256_mask", + "avx512.mask.psrl.di.512" => "__builtin_ia32_psrldi512_mask", + "avx512.mask.psrl.q" => "__builtin_ia32_psrlq512_mask", + "avx512.mask.psrl.q.128" => "__builtin_ia32_psrlq128_mask", + "avx512.mask.psrl.q.256" => "__builtin_ia32_psrlq256_mask", + "avx512.mask.psrl.qi.128" => "__builtin_ia32_psrlqi128_mask", + "avx512.mask.psrl.qi.256" => "__builtin_ia32_psrlqi256_mask", + "avx512.mask.psrl.qi.512" => "__builtin_ia32_psrlqi512_mask", + "avx512.mask.psrl.w.128" => "__builtin_ia32_psrlw128_mask", + "avx512.mask.psrl.w.256" => "__builtin_ia32_psrlw256_mask", + "avx512.mask.psrl.w.512" => "__builtin_ia32_psrlw512_mask", + "avx512.mask.psrl.wi.128" => "__builtin_ia32_psrlwi128_mask", + "avx512.mask.psrl.wi.256" => "__builtin_ia32_psrlwi256_mask", + "avx512.mask.psrl.wi.512" => "__builtin_ia32_psrlwi512_mask", + "avx512.mask.psrlv.d" => "__builtin_ia32_psrlv16si_mask", + "avx512.mask.psrlv.q" => "__builtin_ia32_psrlv8di_mask", + "avx512.mask.psrlv16.hi" => "__builtin_ia32_psrlv16hi_mask", + "avx512.mask.psrlv2.di" => "__builtin_ia32_psrlv2di_mask", + "avx512.mask.psrlv32hi" => "__builtin_ia32_psrlv32hi_mask", + "avx512.mask.psrlv4.di" => "__builtin_ia32_psrlv4di_mask", + "avx512.mask.psrlv4.si" => "__builtin_ia32_psrlv4si_mask", + "avx512.mask.psrlv8.hi" => "__builtin_ia32_psrlv8hi_mask", + "avx512.mask.psrlv8.si" => "__builtin_ia32_psrlv8si_mask", + "avx512.mask.psub.b.128" => "__builtin_ia32_psubb128_mask", + "avx512.mask.psub.b.256" => "__builtin_ia32_psubb256_mask", + "avx512.mask.psub.b.512" => "__builtin_ia32_psubb512_mask", + "avx512.mask.psub.d.128" => "__builtin_ia32_psubd128_mask", + "avx512.mask.psub.d.256" => "__builtin_ia32_psubd256_mask", + "avx512.mask.psub.d.512" => "__builtin_ia32_psubd512_mask", + "avx512.mask.psub.q.128" => "__builtin_ia32_psubq128_mask", + "avx512.mask.psub.q.256" => "__builtin_ia32_psubq256_mask", + "avx512.mask.psub.q.512" => "__builtin_ia32_psubq512_mask", + "avx512.mask.psub.w.128" => "__builtin_ia32_psubw128_mask", + "avx512.mask.psub.w.256" => "__builtin_ia32_psubw256_mask", + "avx512.mask.psub.w.512" => "__builtin_ia32_psubw512_mask", + "avx512.mask.psubs.b.128" => "__builtin_ia32_psubsb128_mask", + "avx512.mask.psubs.b.256" => "__builtin_ia32_psubsb256_mask", + "avx512.mask.psubs.b.512" => "__builtin_ia32_psubsb512_mask", + "avx512.mask.psubs.w.128" => "__builtin_ia32_psubsw128_mask", + "avx512.mask.psubs.w.256" => "__builtin_ia32_psubsw256_mask", + "avx512.mask.psubs.w.512" => "__builtin_ia32_psubsw512_mask", + "avx512.mask.psubus.b.128" => "__builtin_ia32_psubusb128_mask", + "avx512.mask.psubus.b.256" => "__builtin_ia32_psubusb256_mask", + "avx512.mask.psubus.b.512" => "__builtin_ia32_psubusb512_mask", + "avx512.mask.psubus.w.128" => "__builtin_ia32_psubusw128_mask", + "avx512.mask.psubus.w.256" => "__builtin_ia32_psubusw256_mask", + "avx512.mask.psubus.w.512" => "__builtin_ia32_psubusw512_mask", + "avx512.mask.pternlog.d.128" => "__builtin_ia32_pternlogd128_mask", + "avx512.mask.pternlog.d.256" => "__builtin_ia32_pternlogd256_mask", + "avx512.mask.pternlog.d.512" => "__builtin_ia32_pternlogd512_mask", + "avx512.mask.pternlog.q.128" => "__builtin_ia32_pternlogq128_mask", + "avx512.mask.pternlog.q.256" => "__builtin_ia32_pternlogq256_mask", + "avx512.mask.pternlog.q.512" => "__builtin_ia32_pternlogq512_mask", + "avx512.mask.ptestm.d.512" => "__builtin_ia32_ptestmd512", + "avx512.mask.ptestm.q.512" => "__builtin_ia32_ptestmq512", + "avx512.mask.shuf.f32x4" => "__builtin_ia32_shuf_f32x4_mask", + "avx512.mask.shuf.f32x4.256" => "__builtin_ia32_shuf_f32x4_256_mask", + "avx512.mask.shuf.f64x2" => "__builtin_ia32_shuf_f64x2_mask", + "avx512.mask.shuf.f64x2.256" => "__builtin_ia32_shuf_f64x2_256_mask", + "avx512.mask.shuf.i32x4" => "__builtin_ia32_shuf_i32x4_mask", + "avx512.mask.shuf.i32x4.256" => "__builtin_ia32_shuf_i32x4_256_mask", + "avx512.mask.shuf.i64x2" => "__builtin_ia32_shuf_i64x2_mask", + "avx512.mask.shuf.i64x2.256" => "__builtin_ia32_shuf_i64x2_256_mask", + "avx512.mask.shuf.pd.128" => "__builtin_ia32_shufpd128_mask", + "avx512.mask.shuf.pd.256" => "__builtin_ia32_shufpd256_mask", + "avx512.mask.shuf.pd.512" => "__builtin_ia32_shufpd512_mask", + "avx512.mask.shuf.ps.128" => "__builtin_ia32_shufps128_mask", + "avx512.mask.shuf.ps.256" => "__builtin_ia32_shufps256_mask", + "avx512.mask.shuf.ps.512" => "__builtin_ia32_shufps512_mask", + "avx512.mask.sqrt.pd.128" => "__builtin_ia32_sqrtpd128_mask", + "avx512.mask.sqrt.pd.256" => "__builtin_ia32_sqrtpd256_mask", + "avx512.mask.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", + "avx512.mask.sqrt.ps.128" => "__builtin_ia32_sqrtps128_mask", + "avx512.mask.sqrt.ps.256" => "__builtin_ia32_sqrtps256_mask", + "avx512.mask.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", + "avx512.mask.store.ss" => "__builtin_ia32_storess_mask", + "avx512.mask.storeu.d.512" => "__builtin_ia32_storedqusi512_mask", + "avx512.mask.storeu.pd.512" => "__builtin_ia32_storeupd512_mask", + "avx512.mask.storeu.ps.512" => "__builtin_ia32_storeups512_mask", + "avx512.mask.storeu.q.512" => "__builtin_ia32_storedqudi512_mask", + "avx512.mask.sub.pd.128" => "__builtin_ia32_subpd128_mask", + "avx512.mask.sub.pd.256" => "__builtin_ia32_subpd256_mask", + "avx512.mask.sub.pd.512" => "__builtin_ia32_subpd512_mask", + "avx512.mask.sub.ps.128" => "__builtin_ia32_subps128_mask", + "avx512.mask.sub.ps.256" => "__builtin_ia32_subps256_mask", + "avx512.mask.sub.ps.512" => "__builtin_ia32_subps512_mask", + "avx512.mask.valign.d.128" => "__builtin_ia32_alignd128_mask", + "avx512.mask.valign.d.256" => "__builtin_ia32_alignd256_mask", + "avx512.mask.valign.d.512" => "__builtin_ia32_alignd512_mask", + "avx512.mask.valign.q.128" => "__builtin_ia32_alignq128_mask", + "avx512.mask.valign.q.256" => "__builtin_ia32_alignq256_mask", + "avx512.mask.valign.q.512" => "__builtin_ia32_alignq512_mask", + "avx512.mask.vcvtph2ps.128" => "__builtin_ia32_vcvtph2ps_mask", + "avx512.mask.vcvtph2ps.256" => "__builtin_ia32_vcvtph2ps256_mask", + "avx512.mask.vcvtph2ps.512" => "__builtin_ia32_vcvtph2ps512_mask", + "avx512.mask.vextractf32x4.256" => "__builtin_ia32_extractf32x4_256_mask", + "avx512.mask.vextractf32x4.512" => "__builtin_ia32_extractf32x4_mask", + "avx512.mask.vextractf32x8.512" => "__builtin_ia32_extractf32x8_mask", + "avx512.mask.vextractf64x2.256" => "__builtin_ia32_extractf64x2_256_mask", + "avx512.mask.vextractf64x2.512" => "__builtin_ia32_extractf64x2_512_mask", + "avx512.mask.vextractf64x4.512" => "__builtin_ia32_extractf64x4_mask", + "avx512.mask.vextracti32x4.256" => "__builtin_ia32_extracti32x4_256_mask", + "avx512.mask.vextracti32x4.512" => "__builtin_ia32_extracti32x4_mask", + "avx512.mask.vextracti32x8.512" => "__builtin_ia32_extracti32x8_mask", + "avx512.mask.vextracti64x2.256" => "__builtin_ia32_extracti64x2_256_mask", + "avx512.mask.vextracti64x2.512" => "__builtin_ia32_extracti64x2_512_mask", + "avx512.mask.vextracti64x4.512" => "__builtin_ia32_extracti64x4_mask", + "avx512.mask.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask", + "avx512.mask.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask", + "avx512.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", + "avx512.mask.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask", + "avx512.mask.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask", + "avx512.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", + "avx512.mask.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask", + "avx512.mask.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask", + "avx512.mask.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask", + "avx512.mask.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask", + "avx512.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", + "avx512.mask.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask", + "avx512.mask.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask", + "avx512.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", + "avx512.mask.vfnmadd.pd.128" => "__builtin_ia32_vfnmaddpd128_mask", + "avx512.mask.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256_mask", + "avx512.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", + "avx512.mask.vfnmadd.ps.128" => "__builtin_ia32_vfnmaddps128_mask", + "avx512.mask.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256_mask", + "avx512.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", + "avx512.mask.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask", + "avx512.mask.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask", + "avx512.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", + "avx512.mask.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask", + "avx512.mask.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask", + "avx512.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", + "avx512.mask.vpermi2var.d.128" => "__builtin_ia32_vpermi2vard128_mask", + "avx512.mask.vpermi2var.d.256" => "__builtin_ia32_vpermi2vard256_mask", + "avx512.mask.vpermi2var.d.512" => "__builtin_ia32_vpermi2vard512_mask", + "avx512.mask.vpermi2var.hi.128" => "__builtin_ia32_vpermi2varhi128_mask", + "avx512.mask.vpermi2var.hi.256" => "__builtin_ia32_vpermi2varhi256_mask", + "avx512.mask.vpermi2var.hi.512" => "__builtin_ia32_vpermi2varhi512_mask", + "avx512.mask.vpermi2var.pd.128" => "__builtin_ia32_vpermi2varpd128_mask", + "avx512.mask.vpermi2var.pd.256" => "__builtin_ia32_vpermi2varpd256_mask", + "avx512.mask.vpermi2var.pd.512" => "__builtin_ia32_vpermi2varpd512_mask", + "avx512.mask.vpermi2var.ps.128" => "__builtin_ia32_vpermi2varps128_mask", + "avx512.mask.vpermi2var.ps.256" => "__builtin_ia32_vpermi2varps256_mask", + "avx512.mask.vpermi2var.ps.512" => "__builtin_ia32_vpermi2varps512_mask", + "avx512.mask.vpermi2var.q.128" => "__builtin_ia32_vpermi2varq128_mask", + "avx512.mask.vpermi2var.q.256" => "__builtin_ia32_vpermi2varq256_mask", + "avx512.mask.vpermi2var.q.512" => "__builtin_ia32_vpermi2varq512_mask", + "avx512.mask.vpermi2var.qi.128" => "__builtin_ia32_vpermi2varqi128_mask", + "avx512.mask.vpermi2var.qi.256" => "__builtin_ia32_vpermi2varqi256_mask", + "avx512.mask.vpermi2var.qi.512" => "__builtin_ia32_vpermi2varqi512_mask", + "avx512.mask.vpermilvar.pd.128" => "__builtin_ia32_vpermilvarpd_mask", + "avx512.mask.vpermilvar.pd.256" => "__builtin_ia32_vpermilvarpd256_mask", + "avx512.mask.vpermilvar.pd.512" => "__builtin_ia32_vpermilvarpd512_mask", + "avx512.mask.vpermilvar.ps.128" => "__builtin_ia32_vpermilvarps_mask", + "avx512.mask.vpermilvar.ps.256" => "__builtin_ia32_vpermilvarps256_mask", + "avx512.mask.vpermilvar.ps.512" => "__builtin_ia32_vpermilvarps512_mask", + "avx512.mask.vpermt.d.512" => "__builtin_ia32_vpermt2vard512_mask", + "avx512.mask.vpermt.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", + "avx512.mask.vpermt.ps.512" => "__builtin_ia32_vpermt2varps512_mask", + "avx512.mask.vpermt.q.512" => "__builtin_ia32_vpermt2varq512_mask", + "avx512.mask.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_mask", + "avx512.mask.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_mask", + "avx512.mask.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_mask", + "avx512.mask.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_mask", + "avx512.mask.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_mask", + "avx512.mask.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_mask", + "avx512.mask.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_mask", + "avx512.mask.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_mask", + "avx512.mask.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", + "avx512.mask.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_mask", + "avx512.mask.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_mask", + "avx512.mask.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_mask", + "avx512.mask.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_mask", + "avx512.mask.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_mask", + "avx512.mask.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_mask", + "avx512.mask.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_mask", + "avx512.mask.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_mask", + "avx512.mask.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_mask", + "avx512.mask.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_mask", + "avx512.mask.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_mask", + "avx512.mask.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_mask", + "avx512.mask.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_mask", + "avx512.mask.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_mask", + "avx512.mask.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_mask", + "avx512.mask.xor.pd.128" => "__builtin_ia32_xorpd128_mask", + "avx512.mask.xor.pd.256" => "__builtin_ia32_xorpd256_mask", + "avx512.mask.xor.pd.512" => "__builtin_ia32_xorpd512_mask", + "avx512.mask.xor.ps.128" => "__builtin_ia32_xorps128_mask", + "avx512.mask.xor.ps.256" => "__builtin_ia32_xorps256_mask", + "avx512.mask.xor.ps.512" => "__builtin_ia32_xorps512_mask", + "avx512.mask3.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask3", + "avx512.mask3.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask3", + "avx512.mask3.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask3", + "avx512.mask3.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask3", + "avx512.mask3.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask3", + "avx512.mask3.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask3", + "avx512.mask3.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask3", + "avx512.mask3.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask3", + "avx512.mask3.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask3", + "avx512.mask3.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask3", + "avx512.mask3.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask3", + "avx512.mask3.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask3", + "avx512.mask3.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask3", + "avx512.mask3.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask3", + "avx512.mask3.vfmsub.pd.128" => "__builtin_ia32_vfmsubpd128_mask3", + "avx512.mask3.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256_mask3", + "avx512.mask3.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask3", + "avx512.mask3.vfmsub.ps.128" => "__builtin_ia32_vfmsubps128_mask3", + "avx512.mask3.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256_mask3", + "avx512.mask3.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask3", + "avx512.mask3.vfmsubadd.pd.128" => "__builtin_ia32_vfmsubaddpd128_mask3", + "avx512.mask3.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256_mask3", + "avx512.mask3.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask3", + "avx512.mask3.vfmsubadd.ps.128" => "__builtin_ia32_vfmsubaddps128_mask3", + "avx512.mask3.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256_mask3", + "avx512.mask3.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask3", + "avx512.mask3.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask3", + "avx512.mask3.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask3", + "avx512.mask3.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask3", + "avx512.mask3.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask3", + "avx512.mask3.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask3", + "avx512.mask3.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask3", + "avx512.maskz.pternlog.d.128" => "__builtin_ia32_pternlogd128_maskz", + "avx512.maskz.pternlog.d.256" => "__builtin_ia32_pternlogd256_maskz", + "avx512.maskz.pternlog.d.512" => "__builtin_ia32_pternlogd512_maskz", + "avx512.maskz.pternlog.q.128" => "__builtin_ia32_pternlogq128_maskz", + "avx512.maskz.pternlog.q.256" => "__builtin_ia32_pternlogq256_maskz", + "avx512.maskz.pternlog.q.512" => "__builtin_ia32_pternlogq512_maskz", + "avx512.maskz.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_maskz", + "avx512.maskz.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_maskz", + "avx512.maskz.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_maskz", + "avx512.maskz.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_maskz", + "avx512.maskz.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_maskz", + "avx512.maskz.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_maskz", + "avx512.maskz.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_maskz", + "avx512.maskz.vfmadd.ss" => "__builtin_ia32_vfmaddss3_maskz", + "avx512.maskz.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_maskz", + "avx512.maskz.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_maskz", + "avx512.maskz.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_maskz", + "avx512.maskz.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_maskz", + "avx512.maskz.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_maskz", + "avx512.maskz.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_maskz", + "avx512.maskz.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_maskz", + "avx512.maskz.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_maskz", + "avx512.maskz.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_maskz", + "avx512.maskz.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_maskz", + "avx512.maskz.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_maskz", + "avx512.maskz.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_maskz", + "avx512.maskz.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_maskz", + "avx512.maskz.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_maskz", + "avx512.maskz.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_maskz", + "avx512.maskz.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_maskz", + "avx512.maskz.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_maskz", + "avx512.maskz.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_maskz", + "avx512.maskz.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_maskz", + "avx512.maskz.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_maskz", + "avx512.maskz.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_maskz", + "avx512.maskz.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_maskz", + "avx512.maskz.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_maskz", + "avx512.maskz.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_maskz", + "avx512.maskz.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_maskz", + "avx512.maskz.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_maskz", + "avx512.maskz.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_maskz", + "avx512.maskz.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_maskz", + "avx512.maskz.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_maskz", + "avx512.maskz.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_maskz", + "avx512.movntdqa" => "__builtin_ia32_movntdqa512", + "avx512.pbroadcastd.512" => "__builtin_ia32_pbroadcastd512", + "avx512.pbroadcastq.512" => "__builtin_ia32_pbroadcastq512", + "avx512.pmovzxbd" => "__builtin_ia32_pmovzxbd512", + "avx512.pmovzxbq" => "__builtin_ia32_pmovzxbq512", + "avx512.pmovzxdq" => "__builtin_ia32_pmovzxdq512", + "avx512.pmovzxwd" => "__builtin_ia32_pmovzxwd512", + "avx512.pmovzxwq" => "__builtin_ia32_pmovzxwq512", + "avx512.psll.dq" => "__builtin_ia32_pslldqi512", + "avx512.psll.dq.bs" => "__builtin_ia32_pslldqi512_byteshift", + "avx512.psrl.dq" => "__builtin_ia32_psrldqi512", + "avx512.psrl.dq.bs" => "__builtin_ia32_psrldqi512_byteshift", + "avx512.ptestm.b.128" => "__builtin_ia32_ptestmb128", + "avx512.ptestm.b.256" => "__builtin_ia32_ptestmb256", + "avx512.ptestm.b.512" => "__builtin_ia32_ptestmb512", + "avx512.ptestm.d.128" => "__builtin_ia32_ptestmd128", + "avx512.ptestm.d.256" => "__builtin_ia32_ptestmd256", + "avx512.ptestm.d.512" => "__builtin_ia32_ptestmd512", + "avx512.ptestm.q.128" => "__builtin_ia32_ptestmq128", + "avx512.ptestm.q.256" => "__builtin_ia32_ptestmq256", + "avx512.ptestm.q.512" => "__builtin_ia32_ptestmq512", + "avx512.ptestm.w.128" => "__builtin_ia32_ptestmw128", + "avx512.ptestm.w.256" => "__builtin_ia32_ptestmw256", + "avx512.ptestm.w.512" => "__builtin_ia32_ptestmw512", + "avx512.ptestnm.b.128" => "__builtin_ia32_ptestnmb128", + "avx512.ptestnm.b.256" => "__builtin_ia32_ptestnmb256", + "avx512.ptestnm.b.512" => "__builtin_ia32_ptestnmb512", + "avx512.ptestnm.d.128" => "__builtin_ia32_ptestnmd128", + "avx512.ptestnm.d.256" => "__builtin_ia32_ptestnmd256", + "avx512.ptestnm.d.512" => "__builtin_ia32_ptestnmd512", + "avx512.ptestnm.q.128" => "__builtin_ia32_ptestnmq128", + "avx512.ptestnm.q.256" => "__builtin_ia32_ptestnmq256", + "avx512.ptestnm.q.512" => "__builtin_ia32_ptestnmq512", + "avx512.ptestnm.w.128" => "__builtin_ia32_ptestnmw128", + "avx512.ptestnm.w.256" => "__builtin_ia32_ptestnmw256", + "avx512.ptestnm.w.512" => "__builtin_ia32_ptestnmw512", + "avx512.rcp28.pd" => "__builtin_ia32_rcp28pd_mask", + "avx512.rcp28.ps" => "__builtin_ia32_rcp28ps_mask", + "avx512.rcp28.sd" => "__builtin_ia32_rcp28sd_mask", + "avx512.rcp28.ss" => "__builtin_ia32_rcp28ss_mask", + "avx512.rndscale.sd" => "__builtin_ia32_rndscalesd", + "avx512.rndscale.ss" => "__builtin_ia32_rndscaless", + "avx512.rsqrt28.pd" => "__builtin_ia32_rsqrt28pd_mask", + "avx512.rsqrt28.ps" => "__builtin_ia32_rsqrt28ps_mask", + "avx512.rsqrt28.sd" => "__builtin_ia32_rsqrt28sd_mask", + "avx512.rsqrt28.ss" => "__builtin_ia32_rsqrt28ss_mask", + "avx512.scatter.dpd.512" => "__builtin_ia32_scattersiv8df", + "avx512.scatter.dpi.512" => "__builtin_ia32_scattersiv16si", + "avx512.scatter.dpq.512" => "__builtin_ia32_scattersiv8di", + "avx512.scatter.dps.512" => "__builtin_ia32_scattersiv16sf", + "avx512.scatter.qpd.512" => "__builtin_ia32_scatterdiv8df", + "avx512.scatter.qpi.512" => "__builtin_ia32_scatterdiv16si", + "avx512.scatter.qpq.512" => "__builtin_ia32_scatterdiv8di", + "avx512.scatter.qps.512" => "__builtin_ia32_scatterdiv16sf", + "avx512.scatterdiv2.df" => "__builtin_ia32_scatterdiv2df", + "avx512.scatterdiv2.di" => "__builtin_ia32_scatterdiv2di", + "avx512.scatterdiv4.df" => "__builtin_ia32_scatterdiv4df", + "avx512.scatterdiv4.di" => "__builtin_ia32_scatterdiv4di", + "avx512.scatterdiv4.sf" => "__builtin_ia32_scatterdiv4sf", + "avx512.scatterdiv4.si" => "__builtin_ia32_scatterdiv4si", + "avx512.scatterdiv8.sf" => "__builtin_ia32_scatterdiv8sf", + "avx512.scatterdiv8.si" => "__builtin_ia32_scatterdiv8si", + "avx512.scatterpf.dpd.512" => "__builtin_ia32_scatterpfdpd", + "avx512.scatterpf.dps.512" => "__builtin_ia32_scatterpfdps", + "avx512.scatterpf.qpd.512" => "__builtin_ia32_scatterpfqpd", + "avx512.scatterpf.qps.512" => "__builtin_ia32_scatterpfqps", + "avx512.scattersiv2.df" => "__builtin_ia32_scattersiv2df", + "avx512.scattersiv2.di" => "__builtin_ia32_scattersiv2di", + "avx512.scattersiv4.df" => "__builtin_ia32_scattersiv4df", + "avx512.scattersiv4.di" => "__builtin_ia32_scattersiv4di", + "avx512.scattersiv4.sf" => "__builtin_ia32_scattersiv4sf", + "avx512.scattersiv4.si" => "__builtin_ia32_scattersiv4si", + "avx512.scattersiv8.sf" => "__builtin_ia32_scattersiv8sf", + "avx512.scattersiv8.si" => "__builtin_ia32_scattersiv8si", + "avx512.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", + "avx512.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", + "avx512.sqrt.sd" => "__builtin_ia32_sqrtrndsd", + "avx512.sqrt.ss" => "__builtin_ia32_sqrtrndss", + "avx512.vbroadcast.sd.512" => "__builtin_ia32_vbroadcastsd512", + "avx512.vbroadcast.sd.pd.512" => "__builtin_ia32_vbroadcastsd_pd512", + "avx512.vbroadcast.ss.512" => "__builtin_ia32_vbroadcastss512", + "avx512.vbroadcast.ss.ps.512" => "__builtin_ia32_vbroadcastss_ps512", + "fma.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", + "fma.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", + "fma.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", + "fma.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", + "fma.mask.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask", + "fma.mask.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask", + "fma.mask.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask", + "fma.mask.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask", + "fma.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", + "fma.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", + "fma.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", + "fma.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", + "fma.vfmadd.pd" => "__builtin_ia32_vfmaddpd", + "fma.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256", + "fma.vfmadd.ps" => "__builtin_ia32_vfmaddps", + "fma.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256", + "fma.vfmadd.sd" => "__builtin_ia32_vfmaddsd", + "fma.vfmadd.ss" => "__builtin_ia32_vfmaddss", + "fma.vfmsub.pd" => "__builtin_ia32_vfmsubpd", + "fma.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256", + "fma.vfmsub.ps" => "__builtin_ia32_vfmsubps", + "fma.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256", + "fma.vfmsub.sd" => "__builtin_ia32_vfmsubsd", + "fma.vfmsub.ss" => "__builtin_ia32_vfmsubss", + "fma.vfmsubadd.pd" => "__builtin_ia32_vfmsubaddpd", + "fma.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256", + "fma.vfmsubadd.ps" => "__builtin_ia32_vfmsubaddps", + "fma.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256", + "fma.vfnmadd.pd" => "__builtin_ia32_vfnmaddpd", + "fma.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256", + "fma.vfnmadd.ps" => "__builtin_ia32_vfnmaddps", + "fma.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256", + "fma.vfnmadd.sd" => "__builtin_ia32_vfnmaddsd", + "fma.vfnmadd.ss" => "__builtin_ia32_vfnmaddss", + "fma.vfnmsub.pd" => "__builtin_ia32_vfnmsubpd", + "fma.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256", + "fma.vfnmsub.ps" => "__builtin_ia32_vfnmsubps", + "fma.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256", + "fma.vfnmsub.sd" => "__builtin_ia32_vfnmsubsd", + "fma.vfnmsub.ss" => "__builtin_ia32_vfnmsubss", + "mmx.femms" => "__builtin_ia32_femms", + "rdtscp" => "__builtin_ia32_rdtscp", + "sse.add.ss" => "__builtin_ia32_addss", + "sse.cmp.ps" => "__builtin_ia32_cmpps", + "sse.cvtsi2ss" => "__builtin_ia32_cvtsi2ss", + "sse.cvtsi642ss" => "__builtin_ia32_cvtsi642ss", + "sse.div.ss" => "__builtin_ia32_divss", + "sse.mul.ss" => "__builtin_ia32_mulss", + "sse.sqrt.ps" => "__builtin_ia32_sqrtps", + "sse.sqrt.ss" => "__builtin_ia32_sqrtss", + "sse.storeu.ps" => "__builtin_ia32_storeups", + "sse.sub.ss" => "__builtin_ia32_subss", + "sse2.add.sd" => "__builtin_ia32_addsd", + "sse2.cmp.pd" => "__builtin_ia32_cmppd", + "sse2.cvtdq2pd" => "__builtin_ia32_cvtdq2pd", + "sse2.cvtdq2ps" => "__builtin_ia32_cvtdq2ps", + "sse2.cvtps2pd" => "__builtin_ia32_cvtps2pd", + "sse2.cvtsi2sd" => "__builtin_ia32_cvtsi2sd", + "sse2.cvtsi642sd" => "__builtin_ia32_cvtsi642sd", + "sse2.cvtss2sd" => "__builtin_ia32_cvtss2sd", + "sse2.div.sd" => "__builtin_ia32_divsd", + "sse2.mul.sd" => "__builtin_ia32_mulsd", + "sse2.padds.b" => "__builtin_ia32_paddsb128", + "sse2.padds.w" => "__builtin_ia32_paddsw128", + "sse2.paddus.b" => "__builtin_ia32_paddusb128", + "sse2.paddus.w" => "__builtin_ia32_paddusw128", + "sse2.pmaxs.w" => "__builtin_ia32_pmaxsw128", + "sse2.pmaxu.b" => "__builtin_ia32_pmaxub128", + "sse2.pmins.w" => "__builtin_ia32_pminsw128", + "sse2.pminu.b" => "__builtin_ia32_pminub128", + "sse2.pmulu.dq" => "__builtin_ia32_pmuludq128", + "sse2.pshuf.d" => "__builtin_ia32_pshufd", + "sse2.pshufh.w" => "__builtin_ia32_pshufhw", + "sse2.pshufl.w" => "__builtin_ia32_pshuflw", + "sse2.psll.dq" => "__builtin_ia32_pslldqi128", + "sse2.psll.dq.bs" => "__builtin_ia32_pslldqi128_byteshift", + "sse2.psrl.dq" => "__builtin_ia32_psrldqi128", + "sse2.psrl.dq.bs" => "__builtin_ia32_psrldqi128_byteshift", + "sse2.psubs.b" => "__builtin_ia32_psubsb128", + "sse2.psubs.w" => "__builtin_ia32_psubsw128", + "sse2.psubus.b" => "__builtin_ia32_psubusb128", + "sse2.psubus.w" => "__builtin_ia32_psubusw128", + "sse2.sqrt.pd" => "__builtin_ia32_sqrtpd", + "sse2.sqrt.sd" => "__builtin_ia32_sqrtsd", + "sse2.storel.dq" => "__builtin_ia32_storelv4si", + "sse2.storeu.dq" => "__builtin_ia32_storedqu", + "sse2.storeu.pd" => "__builtin_ia32_storeupd", + "sse2.sub.sd" => "__builtin_ia32_subsd", + "sse41.blendpd" => "__builtin_ia32_blendpd", + "sse41.blendps" => "__builtin_ia32_blendps", + "sse41.extractps" => "__builtin_ia32_extractps128", + "sse41.movntdqa" => "__builtin_ia32_movntdqa", + "sse41.pblendw" => "__builtin_ia32_pblendw128", + "sse41.pmaxsb" => "__builtin_ia32_pmaxsb128", + "sse41.pmaxsd" => "__builtin_ia32_pmaxsd128", + "sse41.pmaxud" => "__builtin_ia32_pmaxud128", + "sse41.pmaxuw" => "__builtin_ia32_pmaxuw128", + "sse41.pminsb" => "__builtin_ia32_pminsb128", + "sse41.pminsd" => "__builtin_ia32_pminsd128", + "sse41.pminud" => "__builtin_ia32_pminud128", + "sse41.pminuw" => "__builtin_ia32_pminuw128", + "sse41.pmovsxbd" => "__builtin_ia32_pmovsxbd128", + "sse41.pmovsxbq" => "__builtin_ia32_pmovsxbq128", + "sse41.pmovsxbw" => "__builtin_ia32_pmovsxbw128", + "sse41.pmovsxdq" => "__builtin_ia32_pmovsxdq128", + "sse41.pmovsxwd" => "__builtin_ia32_pmovsxwd128", + "sse41.pmovsxwq" => "__builtin_ia32_pmovsxwq128", + "sse41.pmovzxbd" => "__builtin_ia32_pmovzxbd128", + "sse41.pmovzxbq" => "__builtin_ia32_pmovzxbq128", + "sse41.pmovzxbw" => "__builtin_ia32_pmovzxbw128", + "sse41.pmovzxdq" => "__builtin_ia32_pmovzxdq128", + "sse41.pmovzxwd" => "__builtin_ia32_pmovzxwd128", + "sse41.pmovzxwq" => "__builtin_ia32_pmovzxwq128", + "sse41.pmuldq" => "__builtin_ia32_pmuldq128", + "sse4a.movnt.sd" => "__builtin_ia32_movntsd", + "sse4a.movnt.ss" => "__builtin_ia32_movntss", + "ssse3.pabs.b.128" => "__builtin_ia32_pabsb128", + "ssse3.pabs.d.128" => "__builtin_ia32_pabsd128", + "ssse3.pabs.w.128" => "__builtin_ia32_pabsw128", + "subborrow.u32" => "__builtin_ia32_subborrow_u32", + "subborrow.u64" => "__builtin_ia32_subborrow_u64", + "xop.vpcmov" => "__builtin_ia32_vpcmov", + "xop.vpcmov.256" => "__builtin_ia32_vpcmov_256", + "xop.vpcomb" => "__builtin_ia32_vpcomb", + "xop.vpcomd" => "__builtin_ia32_vpcomd", + "xop.vpcomq" => "__builtin_ia32_vpcomq", + "xop.vpcomub" => "__builtin_ia32_vpcomub", + "xop.vpcomud" => "__builtin_ia32_vpcomud", + "xop.vpcomuq" => "__builtin_ia32_vpcomuq", + "xop.vpcomuw" => "__builtin_ia32_vpcomuw", + "xop.vpcomw" => "__builtin_ia32_vpcomw", + "xop.vprotb" => "__builtin_ia32_vprotb", + "xop.vprotbi" => "__builtin_ia32_vprotbi", + "xop.vprotd" => "__builtin_ia32_vprotd", + "xop.vprotdi" => "__builtin_ia32_vprotdi", + "xop.vprotq" => "__builtin_ia32_vprotq", + "xop.vprotqi" => "__builtin_ia32_vprotqi", + "xop.vprotw" => "__builtin_ia32_vprotw", + "xop.vprotwi" => "__builtin_ia32_vprotwi", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + _ => return ArchCheckResult::UnknownArch, + }) +} diff --git a/tools/generate_intrinsics.py b/tools/generate_intrinsics.py index 767082c23cce..56b425cdb0cd 100644 --- a/tools/generate_intrinsics.py +++ b/tools/generate_intrinsics.py @@ -147,14 +147,12 @@ def fill_intrinsics(intrinsics, from_intrinsics, all_intrinsics): all_intrinsics[entry[0]] = entry[1] -def update_intrinsics(llvm_path, llvmint, llvmint2): +def update_intrinsics(llvm_path): intrinsics_llvm = {} intrinsics_llvmint = {} all_intrinsics = {} extract_intrinsics_from_llvm(llvm_path, intrinsics_llvm) - extract_intrinsics_from_llvmint(llvmint, intrinsics_llvmint) - extract_intrinsics_from_llvmint(llvmint2, intrinsics_llvmint) intrinsics = {} # We give priority to translations from LLVM over the ones from llvmint. @@ -173,13 +171,17 @@ def update_intrinsics(llvm_path, llvmint, llvmint2): # Since all intrinsic names start with "llvm.", we skip that prefix. print("Updating content of `{}`...".format(output_file)) with open(output_file, "w", encoding="utf8") as out: - out.write("// File generated by `rustc_codegen_gcc/tools/generate_intrinsics.py`\n") - out.write("// DO NOT EDIT IT!\n") - out.write("/// Translate a given LLVM intrinsic name to an equivalent GCC one.\n") - out.write("fn map_arch_intrinsic(full_name:&str)->&'static str{\n") - out.write('let Some(name) = full_name.strip_prefix("llvm.") else { unimplemented!("***** unsupported LLVM intrinsic {}", full_name) };\n') - out.write('let Some((arch, name)) = name.split_once(\'.\') else { unimplemented!("***** unsupported LLVM intrinsic {}", name) };\n') - out.write("match arch {\n") + out.write("""// File generated by `rustc_codegen_gcc/tools/generate_intrinsics.py` +// DO NOT EDIT IT! +/// Translate a given LLVM intrinsic name to an equivalent GCC one. +fn map_arch_intrinsic(full_name:&str)-> &'static str { + let Some(name) = full_name.strip_prefix("llvm.") else { unimplemented!("***** unsupported LLVM intrinsic {}", full_name) }; + let Some((arch, name)) = name.split_once('.') else { unimplemented!("***** unsupported LLVM intrinsic llvm.{}", name) }; + let old_arch_res = old_archs(arch, name); + if let ArchCheckResult::Ok(res) = old_arch_res { + return res; + } +match arch {""") for arch in archs: if len(intrinsics[arch]) == 0: continue @@ -199,7 +201,13 @@ def update_intrinsics(llvm_path, llvmint, llvmint2): out.write(' "{}" => "{}",\n'.format(llvm_name, entry[1])) out.write(' _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"),\n') out.write("}} }} {}(name,full_name) }}\n,".format(arch)) - out.write(' _ => unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic:{full_name}"),\n') + out.write(""" _ => { + match old_arch_res { + ArchCheckResult::UnknownIntrinsic => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), + ArchCheckResult::UnknownArch => unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic: {full_name}"), + ArchCheckResult::Ok(_) => unreachable!(), + } + }""") out.write("}\n}") subprocess.call(["rustfmt", output_file]) print("Done!") @@ -210,14 +218,6 @@ def main(): os.path.dirname(os.path.abspath(__file__)), "llvm-project", ) - llvmint_path = os.path.join( - os.path.dirname(os.path.abspath(__file__)), - "llvmint", - ) - llvmint2_path = os.path.join( - os.path.dirname(os.path.abspath(__file__)), - "llvmint-2", - ) # First, we clone the LLVM repository if it's not already here. clone_repository( @@ -227,17 +227,7 @@ def main(): branch="main", sub_paths=["llvm/include/llvm/IR", "llvm/include/llvm/CodeGen/"], ) - clone_repository( - "llvmint", - llvmint_path, - "https://github.com/GuillaumeGomez/llvmint", - ) - clone_repository( - "llvmint2", - llvmint2_path, - "https://github.com/antoyo/llvmint", - ) - update_intrinsics(llvm_path, llvmint_path, llvmint2_path) + update_intrinsics(llvm_path) if __name__ == "__main__": From 3dc60d0bf14638cbc2dcaf70e720c6f417608365 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Jan 2026 16:48:14 +0100 Subject: [PATCH 2219/3801] Simplify intrinsics translation generation script --- tools/generate_intrinsics.py | 150 ++++++++--------------------------- 1 file changed, 33 insertions(+), 117 deletions(-) diff --git a/tools/generate_intrinsics.py b/tools/generate_intrinsics.py index 56b425cdb0cd..539032340777 100644 --- a/tools/generate_intrinsics.py +++ b/tools/generate_intrinsics.py @@ -12,7 +12,7 @@ def run_command(command, cwd=None): sys.exit(1) -def clone_repository(repo_name, path, repo_url, branch="master", sub_paths=None): +def clone_repository(repo_name, path, repo_url, sub_paths): if os.path.exists(path): while True: choice = input("There is already a `{}` folder, do you want to update it? [y/N]".format(path)) @@ -21,18 +21,15 @@ def clone_repository(repo_name, path, repo_url, branch="master", sub_paths=None) return elif choice.lower() == "y": print("Updating repository...") - run_command(["git", "pull", "origin", branch], cwd=path) + run_command(["git", "pull", "origin", "main"], cwd=path) return else: print("Didn't understand answer...") print("Cloning {} repository...".format(repo_name)) - if sub_paths is None: - run_command(["git", "clone", repo_url, "--depth", "1", path]) - else: - run_command(["git", "clone", repo_url, "--filter=tree:0", "--no-checkout", path]) - run_command(["git", "sparse-checkout", "init"], cwd=path) - run_command(["git", "sparse-checkout", "set", *sub_paths], cwd=path) - run_command(["git", "checkout"], cwd=path) + run_command(["git", "clone", repo_url, "--filter=tree:0", "--no-checkout", path]) + run_command(["git", "sparse-checkout", "init"], cwd=path) + run_command(["git", "sparse-checkout", "set", *sub_paths], cwd=path) + run_command(["git", "checkout"], cwd=path) def append_intrinsic(array, intrinsic_name, translation): @@ -45,119 +42,36 @@ def convert_to_string(content): return content -def extract_intrinsics_from_llvm(llvm_path, intrinsics): - command = ["llvm-tblgen", "llvm/IR/Intrinsics.td"] +def extract_intrinsics_from_llvm(llvm_path): + intrinsics = {} + command = ["llvm-tblgen", "llvm/IR/Intrinsics.td", "--dump-json"] cwd = os.path.join(llvm_path, "llvm/include") print("=> Running command `{}` from `{}`".format(command, cwd)) p = subprocess.Popen(command, cwd=cwd, stdout=subprocess.PIPE) output, err = p.communicate() - lines = convert_to_string(output).splitlines() - pos = 0 - while pos < len(lines): - line = lines[pos] - if not line.startswith("def "): - pos += 1 + content = json.loads(convert_to_string(output)) + for intrinsic in content: + data = content[intrinsic] + if not isinstance(data, dict): continue - intrinsic = line.split(" ")[1].strip() - content = line - while pos < len(lines): - line = lines[pos].split(" // ")[0].strip() - content += line - pos += 1 - if line == "}": - break - entries = re.findall('string ClangBuiltinName = "(\\w+)";', content) - current_arch = re.findall('string TargetPrefix = "(\\w+)";', content) - if len(entries) == 1 and len(current_arch) == 1: - current_arch = current_arch[0] - intrinsic = intrinsic.split("_") - if len(intrinsic) < 2 or intrinsic[0] != "int": - continue - intrinsic[0] = "llvm" - intrinsic = ".".join(intrinsic) - if current_arch not in intrinsics: - intrinsics[current_arch] = [] - append_intrinsic(intrinsics[current_arch], intrinsic, entries[0]) - - -def append_translation(json_data, p, array): - it = json_data["index"][p] - content = it["docs"].split('`') - if len(content) != 5: - return - append_intrinsic(array, content[1], content[3]) - - -def extract_intrinsics_from_llvmint(llvmint, intrinsics): - archs = [ - "AMDGPU", - "aarch64", - "arm", - "cuda", - "hexagon", - "mips", - "nvvm", - "ppc", - "ptx", - "x86", - "xcore", - ] - - json_file = os.path.join(llvmint, "target/doc/llvmint.json") - # We need to regenerate the documentation! - run_command( - ["cargo", "rustdoc", "--", "-Zunstable-options", "--output-format", "json"], - cwd=llvmint, - ) - with open(json_file, "r", encoding="utf8") as f: - json_data = json.loads(f.read()) - for p in json_data["paths"]: - it = json_data["paths"][p] - if it["crate_id"] != 0: - # This is from an external crate. + current_arch = data.get("TargetPrefix") + builtin_name = data.get("ClangBuiltinName") + if current_arch is None or current_arch == "" or builtin_name is None: continue - if it["kind"] != "function": - # We're only looking for functions. + intrinsic = intrinsic.split("_") + if len(intrinsic) < 2 or intrinsic[0] != "int": continue - # if len(it["path"]) == 2: - # # This is a "general" intrinsic, not bound to a specific arch. - # append_translation(json_data, p, general) - # continue - if len(it["path"]) != 3 or it["path"][1] not in archs: - continue - arch = it["path"][1] - if arch not in intrinsics: - intrinsics[arch] = [] - append_translation(json_data, p, intrinsics[arch]) + intrinsic[0] = "llvm" + intrinsic = ".".join(intrinsic) + if current_arch not in intrinsics: + intrinsics[current_arch] = [] + append_intrinsic(intrinsics[current_arch], intrinsic, builtin_name) - -def fill_intrinsics(intrinsics, from_intrinsics, all_intrinsics): - for arch in from_intrinsics: - if arch not in intrinsics: - intrinsics[arch] = [] - for entry in from_intrinsics[arch]: - if entry[0] in all_intrinsics: - if all_intrinsics[entry[0]] == entry[1]: - # This is a "full" duplicate, both the LLVM instruction and the GCC - # translation are the same. - continue - intrinsics[arch].append((entry[0], entry[1], True)) - else: - intrinsics[arch].append((entry[0], entry[1], False)) - all_intrinsics[entry[0]] = entry[1] + return intrinsics def update_intrinsics(llvm_path): - intrinsics_llvm = {} - intrinsics_llvmint = {} - all_intrinsics = {} - - extract_intrinsics_from_llvm(llvm_path, intrinsics_llvm) - - intrinsics = {} - # We give priority to translations from LLVM over the ones from llvmint. - fill_intrinsics(intrinsics, intrinsics_llvm, all_intrinsics) - fill_intrinsics(intrinsics, intrinsics_llvmint, all_intrinsics) + intrinsics = extract_intrinsics_from_llvm(llvm_path) archs = [arch for arch in intrinsics] archs.sort() @@ -187,15 +101,13 @@ match arch {""") continue attribute = "#[expect(non_snake_case)]" if arch[0].isupper() else "" out.write("\"{}\" => {{ {} fn {}(name: &str,full_name:&str) -> &'static str {{ match name {{".format(arch, attribute, arch)) - intrinsics[arch].sort(key=lambda x: (x[0], x[2])) + intrinsics[arch].sort(key=lambda x: (x[0], x[1])) out.write(' // {}\n'.format(arch)) for entry in intrinsics[arch]: llvm_name = entry[0].removeprefix("llvm."); llvm_name = llvm_name.removeprefix(arch); llvm_name = llvm_name.removeprefix("."); - if entry[2] is True: # if it is a duplicate - out.write(' // [DUPLICATE]: "{}" => "{}",\n'.format(llvm_name, entry[1])) - elif "_round_mask" in entry[1]: + if "_round_mask" in entry[1]: out.write(' // [INVALID CONVERSION]: "{}" => "{}",\n'.format(llvm_name, entry[1])) else: out.write(' "{}" => "{}",\n'.format(llvm_name, entry[1])) @@ -224,11 +136,15 @@ def main(): "llvm-project", llvm_path, "https://github.com/llvm/llvm-project", - branch="main", - sub_paths=["llvm/include/llvm/IR", "llvm/include/llvm/CodeGen/"], + ["llvm/include/llvm/IR", "llvm/include/llvm/CodeGen/"], ) update_intrinsics(llvm_path) +# llvm-tblgen can be built with: +# +# mkdir llvm-tblgen-build && cd llvm-tblgen-build +# cmake -G Ninja -DLLVM_ENABLE_PROJECTS="llvm" -DCMAKE_BUILD_TYPE=Release ../llvm +# ninja llvm-tblgen if __name__ == "__main__": sys.exit(main()) From c848b28a5d20b512e7edcd03da5ba616fabf0a8d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Jan 2026 17:05:01 +0100 Subject: [PATCH 2220/3801] Ignore `src/intrinsic/old_archs.rs` for typo checks --- .cspell.json | 1 + _typos.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.cspell.json b/.cspell.json index 388ccce2b091..556432d69a41 100644 --- a/.cspell.json +++ b/.cspell.json @@ -18,6 +18,7 @@ ], "ignorePaths": [ "src/intrinsic/archs.rs", + "src/intrinsic/old_archs.rs", "src/intrinsic/llvm.rs" ], "ignoreRegExpList": [ diff --git a/_typos.toml b/_typos.toml index 4a6a506a981a..c4918b114621 100644 --- a/_typos.toml +++ b/_typos.toml @@ -6,4 +6,4 @@ seh = "seh" typ = "typ" [files] -extend-exclude = ["src/intrinsic/archs.rs"] +extend-exclude = ["src/intrinsic/archs.rs", "src/intrinsic/old_archs.rs"] From 5f58acba529112e75692833212ea25ad337828ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 16 Jan 2026 04:17:24 +0000 Subject: [PATCH 2221/3801] Add `const Default` impls for `HashSet` and `HashMap` with custom `Hasher` --- library/core/src/hash/mod.rs | 3 ++- library/core/src/hash/sip.rs | 9 ++++++--- library/std/src/collections/hash/map.rs | 5 +++-- library/std/src/collections/hash/map/tests.rs | 3 +++ library/std/src/collections/hash/set.rs | 7 ++++--- library/std/src/collections/hash/set/tests.rs | 2 ++ library/std/src/hash/random.rs | 6 ++++-- 7 files changed, 24 insertions(+), 11 deletions(-) diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index c3f3cd729425..a800e1b41fbe 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -784,7 +784,8 @@ impl Clone for BuildHasherDefault { } #[stable(since = "1.7.0", feature = "build_hasher")] -impl Default for BuildHasherDefault { +#[rustc_const_unstable(feature = "const_default", issue = "143894")] +impl const Default for BuildHasherDefault { fn default() -> BuildHasherDefault { Self::new() } diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs index 4f2e8a22d180..4569c7da035d 100644 --- a/library/core/src/hash/sip.rs +++ b/library/core/src/hash/sip.rs @@ -166,16 +166,18 @@ impl SipHasher13 { /// Creates a new `SipHasher13` with the two initial keys set to 0. #[inline] #[unstable(feature = "hashmap_internals", issue = "none")] + #[rustc_const_unstable(feature = "const_default", issue = "143894")] #[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")] - pub fn new() -> SipHasher13 { + pub const fn new() -> SipHasher13 { SipHasher13::new_with_keys(0, 0) } /// Creates a `SipHasher13` that is keyed off the provided keys. #[inline] #[unstable(feature = "hashmap_internals", issue = "none")] + #[rustc_const_unstable(feature = "const_default", issue = "143894")] #[deprecated(since = "1.13.0", note = "use `std::hash::DefaultHasher` instead")] - pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 { + pub const fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 { SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) } } } @@ -338,7 +340,8 @@ impl Clone for Hasher { } } -impl Default for Hasher { +#[rustc_const_unstable(feature = "const_default", issue = "143894")] +impl const Default for Hasher { /// Creates a `Hasher` with the two initial keys set to 0. #[inline] fn default() -> Hasher { diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index ad6328f76ed6..b82beb3b8b2e 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1444,9 +1444,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for HashMap +#[rustc_const_unstable(feature = "const_default", issue = "143894")] +impl const Default for HashMap where - S: Default, + S: [const] Default, { /// Creates an empty `HashMap`, with the `Default` value for the hasher. #[inline] diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs index 9f7df20a1d7e..cc1a9900bec9 100644 --- a/library/std/src/collections/hash/map/tests.rs +++ b/library/std/src/collections/hash/map/tests.rs @@ -1053,4 +1053,7 @@ fn const_with_hasher() { assert_eq!(y.len(), 0); y.insert((), ()); assert_eq!(y.len(), 1); + + const Z: HashMap<(), (), BuildHasherDefault> = Default::default(); + assert_eq!(X, Z); } diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 02a4a0d9c815..3f3d601e4d30 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -1236,14 +1236,15 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for HashSet +#[rustc_const_unstable(feature = "const_default", issue = "143894")] +impl const Default for HashSet where - S: Default, + S: [const] Default, { /// Creates an empty `HashSet` with the `Default` value for the hasher. #[inline] fn default() -> HashSet { - HashSet { base: Default::default() } + HashSet { base: base::HashSet::with_hasher(Default::default()) } } } diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs index 8ee8a3e8bf6a..d7bbc7bdc6a5 100644 --- a/library/std/src/collections/hash/set/tests.rs +++ b/library/std/src/collections/hash/set/tests.rs @@ -504,7 +504,9 @@ fn from_array() { #[test] fn const_with_hasher() { const X: HashSet<(), ()> = HashSet::with_hasher(()); + const Y: HashSet<(), ()> = Default::default(); assert_eq!(X.len(), 0); + assert_eq!(Y.len(), 0); } #[test] diff --git a/library/std/src/hash/random.rs b/library/std/src/hash/random.rs index 236803b24a2e..fab090e31f03 100644 --- a/library/std/src/hash/random.rs +++ b/library/std/src/hash/random.rs @@ -105,14 +105,16 @@ impl DefaultHasher { #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] #[inline] #[allow(deprecated)] + #[rustc_const_unstable(feature = "const_default", issue = "143894")] #[must_use] - pub fn new() -> DefaultHasher { + pub const fn new() -> DefaultHasher { DefaultHasher(SipHasher13::new_with_keys(0, 0)) } } #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] -impl Default for DefaultHasher { +#[rustc_const_unstable(feature = "const_default", issue = "143894")] +impl const Default for DefaultHasher { /// Creates a new `DefaultHasher` using [`new`]. /// See its documentation for more. /// From 4f59819c26c72f86baa98a2805d411cd5b665759 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 16 Jan 2026 17:46:34 +0100 Subject: [PATCH 2222/3801] Regenerate intrinsics --- src/intrinsic/archs.rs | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/intrinsic/archs.rs b/src/intrinsic/archs.rs index 89a6cf7f3d6e..3c1698df6dec 100644 --- a/src/intrinsic/archs.rs +++ b/src/intrinsic/archs.rs @@ -24,6 +24,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "gcsss" => "__builtin_arm_gcsss", "isb" => "__builtin_arm_isb", "prefetch" => "__builtin_arm_prefetch", + "range.prefetch" => "__builtin_arm_range_prefetch", "sme.in.streaming.mode" => "__builtin_arm_in_streaming_mode", "sve.aesd" => "__builtin_sve_svaesd_u8", "sve.aese" => "__builtin_sve_svaese_u8", @@ -414,6 +415,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "s.wait.event.export.ready" => "__builtin_amdgcn_s_wait_event_export_ready", "s.wait.tensorcnt" => "__builtin_amdgcn_s_wait_tensorcnt", "s.waitcnt" => "__builtin_amdgcn_s_waitcnt", + "s.wakeup.barrier" => "__builtin_amdgcn_s_wakeup_barrier", "sad.hi.u8" => "__builtin_amdgcn_sad_hi_u8", "sad.u16" => "__builtin_amdgcn_sad_u16", "sad.u8" => "__builtin_amdgcn_sad_u8", @@ -4836,19 +4838,24 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "add.rm.d" => "__nvvm_add_rm_d", "add.rm.f" => "__nvvm_add_rm_f", "add.rm.ftz.f" => "__nvvm_add_rm_ftz_f", + "add.rm.ftz.sat.f" => "__nvvm_add_rm_ftz_sat_f", + "add.rm.sat.f" => "__nvvm_add_rm_sat_f", "add.rn.d" => "__nvvm_add_rn_d", "add.rn.f" => "__nvvm_add_rn_f", "add.rn.ftz.f" => "__nvvm_add_rn_ftz_f", + "add.rn.ftz.sat.f" => "__nvvm_add_rn_ftz_sat_f", + "add.rn.sat.f" => "__nvvm_add_rn_sat_f", "add.rp.d" => "__nvvm_add_rp_d", "add.rp.f" => "__nvvm_add_rp_f", "add.rp.ftz.f" => "__nvvm_add_rp_ftz_f", + "add.rp.ftz.sat.f" => "__nvvm_add_rp_ftz_sat_f", + "add.rp.sat.f" => "__nvvm_add_rp_sat_f", "add.rz.d" => "__nvvm_add_rz_d", "add.rz.f" => "__nvvm_add_rz_f", "add.rz.ftz.f" => "__nvvm_add_rz_ftz_f", + "add.rz.ftz.sat.f" => "__nvvm_add_rz_ftz_sat_f", + "add.rz.sat.f" => "__nvvm_add_rz_sat_f", "bar.warp.sync" => "__nvvm_bar_warp_sync", - "barrier0.and" => "__nvvm_bar0_and", - "barrier0.or" => "__nvvm_bar0_or", - "barrier0.popc" => "__nvvm_bar0_popc", "bf16x2.to.ue8m0x2.rp" => "__nvvm_bf16x2_to_ue8m0x2_rp", "bf16x2.to.ue8m0x2.rp.satfinite" => "__nvvm_bf16x2_to_ue8m0x2_rp_satfinite", "bf16x2.to.ue8m0x2.rz" => "__nvvm_bf16x2_to_ue8m0x2_rz", @@ -5050,6 +5057,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "fma.rm.d" => "__nvvm_fma_rm_d", "fma.rm.f" => "__nvvm_fma_rm_f", "fma.rm.ftz.f" => "__nvvm_fma_rm_ftz_f", + "fma.rm.ftz.sat.f" => "__nvvm_fma_rm_ftz_sat_f", + "fma.rm.sat.f" => "__nvvm_fma_rm_sat_f", "fma.rn.bf16" => "__nvvm_fma_rn_bf16", "fma.rn.bf16x2" => "__nvvm_fma_rn_bf16x2", "fma.rn.d" => "__nvvm_fma_rn_d", @@ -5061,16 +5070,22 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "fma.rn.ftz.relu.bf16x2" => "__nvvm_fma_rn_ftz_relu_bf16x2", "fma.rn.ftz.sat.bf16" => "__nvvm_fma_rn_ftz_sat_bf16", "fma.rn.ftz.sat.bf16x2" => "__nvvm_fma_rn_ftz_sat_bf16x2", + "fma.rn.ftz.sat.f" => "__nvvm_fma_rn_ftz_sat_f", "fma.rn.relu.bf16" => "__nvvm_fma_rn_relu_bf16", "fma.rn.relu.bf16x2" => "__nvvm_fma_rn_relu_bf16x2", "fma.rn.sat.bf16" => "__nvvm_fma_rn_sat_bf16", "fma.rn.sat.bf16x2" => "__nvvm_fma_rn_sat_bf16x2", + "fma.rn.sat.f" => "__nvvm_fma_rn_sat_f", "fma.rp.d" => "__nvvm_fma_rp_d", "fma.rp.f" => "__nvvm_fma_rp_f", "fma.rp.ftz.f" => "__nvvm_fma_rp_ftz_f", + "fma.rp.ftz.sat.f" => "__nvvm_fma_rp_ftz_sat_f", + "fma.rp.sat.f" => "__nvvm_fma_rp_sat_f", "fma.rz.d" => "__nvvm_fma_rz_d", "fma.rz.f" => "__nvvm_fma_rz_f", "fma.rz.ftz.f" => "__nvvm_fma_rz_ftz_f", + "fma.rz.ftz.sat.f" => "__nvvm_fma_rz_ftz_sat_f", + "fma.rz.sat.f" => "__nvvm_fma_rz_sat_f", "fmax.bf16" => "__nvvm_fmax_bf16", "fmax.bf16x2" => "__nvvm_fmax_bf16x2", "fmax.d" => "__nvvm_fmax_d", @@ -5274,6 +5289,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "read.ptx.sreg.pm1" => "__nvvm_read_ptx_sreg_pm1", "read.ptx.sreg.pm2" => "__nvvm_read_ptx_sreg_pm2", "read.ptx.sreg.pm3" => "__nvvm_read_ptx_sreg_pm3", + "read.ptx.sreg.pm4" => "__nvvm_read_ptx_sreg_pm4", "read.ptx.sreg.smid" => "__nvvm_read_ptx_sreg_smid", "read.ptx.sreg.tid.w" => "__nvvm_read_ptx_sreg_tid_w", "read.ptx.sreg.tid.x" => "__nvvm_read_ptx_sreg_tid_x", @@ -6370,6 +6386,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { fn spv(name: &str, full_name: &str) -> &'static str { match name { // spv + "group.memory.barrier.with.group.sync" => "__builtin_spirv_group_barrier", "num.subgroups" => "__builtin_spirv_num_subgroups", "subgroup.id" => "__builtin_spirv_subgroup_id", "subgroup.local.invocation.id" => { @@ -6377,6 +6394,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { } "subgroup.max.size" => "__builtin_spirv_subgroup_max_size", "subgroup.size" => "__builtin_spirv_subgroup_size", + "wave.ballot" => "__builtin_spirv_subgroup_ballot", _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), } } @@ -7711,8 +7729,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx.ptestnzc.256" => "__builtin_ia32_ptestnzc256", "avx.ptestz.256" => "__builtin_ia32_ptestz256", "avx.rcp.ps.256" => "__builtin_ia32_rcpps256", - "avx.round.pd.256" => "__builtin_ia32_roundpd256", - "avx.round.ps.256" => "__builtin_ia32_roundps256", "avx.rsqrt.ps.256" => "__builtin_ia32_rsqrtps256", "avx.vpermilvar.pd" => "__builtin_ia32_vpermilvarpd", "avx.vpermilvar.pd.256" => "__builtin_ia32_vpermilvarpd256", @@ -8829,10 +8845,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse41.ptestc" => "__builtin_ia32_ptestc128", "sse41.ptestnzc" => "__builtin_ia32_ptestnzc128", "sse41.ptestz" => "__builtin_ia32_ptestz128", - "sse41.round.pd" => "__builtin_ia32_roundpd", - "sse41.round.ps" => "__builtin_ia32_roundps", - "sse41.round.sd" => "__builtin_ia32_roundsd", - "sse41.round.ss" => "__builtin_ia32_roundss", "sse42.crc32.32.16" => "__builtin_ia32_crc32hi", "sse42.crc32.32.32" => "__builtin_ia32_crc32si", "sse42.crc32.32.8" => "__builtin_ia32_crc32qi", @@ -8869,10 +8881,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "ssse3.psign.w.128" => "__builtin_ia32_psignw128", "sttilecfg" => "__builtin_ia32_tile_storeconfig", "stui" => "__builtin_ia32_stui", - "t2rpntlvwz0rs" => "__builtin_ia32_t2rpntlvwz0rs", - "t2rpntlvwz0rst1" => "__builtin_ia32_t2rpntlvwz0rst1", - "t2rpntlvwz1rs" => "__builtin_ia32_t2rpntlvwz1rs", - "t2rpntlvwz1rst1" => "__builtin_ia32_t2rpntlvwz1rst1", "tbm.bextri.u32" => "__builtin_ia32_bextri_u32", "tbm.bextri.u64" => "__builtin_ia32_bextri_u64", "tcmmimfp16ps" => "__builtin_ia32_tcmmimfp16ps", @@ -8881,14 +8889,19 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "tcmmrlfp16ps.internal" => "__builtin_ia32_tcmmrlfp16ps_internal", "tcvtrowd2ps" => "__builtin_ia32_tcvtrowd2ps", "tcvtrowd2ps.internal" => "__builtin_ia32_tcvtrowd2ps_internal", + "tcvtrowd2psi" => "__builtin_ia32_tcvtrowd2psi", "tcvtrowps2bf16h" => "__builtin_ia32_tcvtrowps2bf16h", "tcvtrowps2bf16h.internal" => "__builtin_ia32_tcvtrowps2bf16h_internal", + "tcvtrowps2bf16hi" => "__builtin_ia32_tcvtrowps2bf16hi", "tcvtrowps2bf16l" => "__builtin_ia32_tcvtrowps2bf16l", "tcvtrowps2bf16l.internal" => "__builtin_ia32_tcvtrowps2bf16l_internal", + "tcvtrowps2bf16li" => "__builtin_ia32_tcvtrowps2bf16li", "tcvtrowps2phh" => "__builtin_ia32_tcvtrowps2phh", "tcvtrowps2phh.internal" => "__builtin_ia32_tcvtrowps2phh_internal", + "tcvtrowps2phhi" => "__builtin_ia32_tcvtrowps2phhi", "tcvtrowps2phl" => "__builtin_ia32_tcvtrowps2phl", "tcvtrowps2phl.internal" => "__builtin_ia32_tcvtrowps2phl_internal", + "tcvtrowps2phli" => "__builtin_ia32_tcvtrowps2phli", "tdpbf16ps" => "__builtin_ia32_tdpbf16ps", "tdpbf16ps.internal" => "__builtin_ia32_tdpbf16ps_internal", "tdpbf8ps" => "__builtin_ia32_tdpbf8ps", @@ -8920,6 +8933,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "tileloaddt164.internal" => "__builtin_ia32_tileloaddt164_internal", "tilemovrow" => "__builtin_ia32_tilemovrow", "tilemovrow.internal" => "__builtin_ia32_tilemovrow_internal", + "tilemovrowi" => "__builtin_ia32_tilemovrowi", "tilerelease" => "__builtin_ia32_tilerelease", "tilestored64" => "__builtin_ia32_tilestored64", "tilestored64.internal" => "__builtin_ia32_tilestored64_internal", From 4cb70c8e4a18c073703d3ccda8adeb2931fe4fc6 Mon Sep 17 00:00:00 2001 From: linshuy2 Date: Fri, 16 Jan 2026 03:46:38 +0000 Subject: [PATCH 2223/3801] fix: `unnecessary_sort_by` FN on field access --- .../src/methods/unnecessary_sort_by.rs | 24 ++++++++++----- tests/ui/unnecessary_sort_by.fixed | 30 +++++++++++++++++++ tests/ui/unnecessary_sort_by.rs | 30 +++++++++++++++++++ tests/ui/unnecessary_sort_by.stderr | 20 ++++++++++++- 4 files changed, 96 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs index 9dddbe814317..c7339a3bdd05 100644 --- a/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -2,12 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; use clippy_utils::std_or_core; use clippy_utils::sugg::Sugg; -use clippy_utils::ty::implements_trait; +use clippy_utils::ty::{implements_trait, is_copy}; use rustc_errors::Applicability; use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath}; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_middle::ty::GenericArgKind; +use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_span::sym; use rustc_span::symbol::{Ident, Symbol}; use std::iter; @@ -70,7 +69,7 @@ fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: Ident, b_expr: &Expr<'_>, b_ident: mirrored_exprs(left_block, a_ident, right_block, b_ident) }, (ExprKind::Field(left_expr, left_ident), ExprKind::Field(right_expr, right_ident)) => { - left_ident.name == right_ident.name && mirrored_exprs(left_expr, a_ident, right_expr, right_ident) + left_ident.name == right_ident.name && mirrored_exprs(left_expr, a_ident, right_expr, b_ident) }, // Two paths: either one is a and the other is b, or they're identical to each other ( @@ -159,7 +158,11 @@ fn detect_lint<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, arg: &Expr<'_>) -> return Some(LintTrigger::Sort); } - if !expr_borrows(cx, left_expr) { + let left_expr_ty = cx.typeck_results().expr_ty(left_expr); + if !expr_borrows(left_expr_ty) + // Don't lint if the closure is accessing non-Copy fields + && (!expr_is_field_access(left_expr) || is_copy(cx, left_expr_ty)) + { return Some(LintTrigger::SortByKey(SortByKeyDetection { closure_arg, closure_body, @@ -171,11 +174,18 @@ fn detect_lint<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, arg: &Expr<'_>) -> None } -fn expr_borrows(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - let ty = cx.typeck_results().expr_ty(expr); +fn expr_borrows(ty: Ty<'_>) -> bool { matches!(ty.kind(), ty::Ref(..)) || ty.walk().any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(_))) } +fn expr_is_field_access(expr: &Expr<'_>) -> bool { + match expr.kind { + ExprKind::Field(_, _) => true, + ExprKind::AddrOf(_, Mutability::Not, inner) => expr_is_field_access(inner), + _ => false, + } +} + pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, diff --git a/tests/ui/unnecessary_sort_by.fixed b/tests/ui/unnecessary_sort_by.fixed index 5255ab173efb..372cf683f223 100644 --- a/tests/ui/unnecessary_sort_by.fixed +++ b/tests/ui/unnecessary_sort_by.fixed @@ -111,3 +111,33 @@ fn main() { issue_5754::test(); issue_6001::test(); } + +fn issue16405() { + let mut v: Vec<(i32, &str)> = vec![(1, "foo"), (2, "bar")]; + + v.sort_by_key(|a| a.0); + //~^ unnecessary_sort_by + + struct Item { + key: i32, + value: String, + } + + let mut items = vec![ + Item { + key: 2, + value: "b".to_string(), + }, + Item { + key: 1, + value: "a".to_string(), + }, + ]; + items.sort_by_key(|item1| item1.key); + //~^ unnecessary_sort_by + + items.sort_by(|item1, item2| item1.value.cmp(&item2.value)); + + items.sort_by_key(|item1| item1.value.clone()); + //~^ unnecessary_sort_by +} diff --git a/tests/ui/unnecessary_sort_by.rs b/tests/ui/unnecessary_sort_by.rs index 65db7ca3f137..7dd274623b35 100644 --- a/tests/ui/unnecessary_sort_by.rs +++ b/tests/ui/unnecessary_sort_by.rs @@ -111,3 +111,33 @@ fn main() { issue_5754::test(); issue_6001::test(); } + +fn issue16405() { + let mut v: Vec<(i32, &str)> = vec![(1, "foo"), (2, "bar")]; + + v.sort_by(|a, b| a.0.cmp(&b.0)); + //~^ unnecessary_sort_by + + struct Item { + key: i32, + value: String, + } + + let mut items = vec![ + Item { + key: 2, + value: "b".to_string(), + }, + Item { + key: 1, + value: "a".to_string(), + }, + ]; + items.sort_by(|item1, item2| item1.key.cmp(&item2.key)); + //~^ unnecessary_sort_by + + items.sort_by(|item1, item2| item1.value.cmp(&item2.value)); + + items.sort_by(|item1, item2| item1.value.clone().cmp(&item2.value.clone())); + //~^ unnecessary_sort_by +} diff --git a/tests/ui/unnecessary_sort_by.stderr b/tests/ui/unnecessary_sort_by.stderr index a066554037fe..b555245b0d01 100644 --- a/tests/ui/unnecessary_sort_by.stderr +++ b/tests/ui/unnecessary_sort_by.stderr @@ -73,5 +73,23 @@ error: consider using `sort_unstable_by_key` LL | args.sort_unstable_by(|a, b| b.name().cmp(&a.name())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_unstable_by_key(|b| std::cmp::Reverse(b.name()))` -error: aborting due to 12 previous errors +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:118:5 + | +LL | v.sort_by(|a, b| a.0.cmp(&b.0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|a| a.0)` + +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:136:5 + | +LL | items.sort_by(|item1, item2| item1.key.cmp(&item2.key)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `items.sort_by_key(|item1| item1.key)` + +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:141:5 + | +LL | items.sort_by(|item1, item2| item1.value.clone().cmp(&item2.value.clone())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `items.sort_by_key(|item1| item1.value.clone())` + +error: aborting due to 15 previous errors From 03fd408af5657404b1d165f7c7679918ed0f536a Mon Sep 17 00:00:00 2001 From: linshuy2 Date: Fri, 16 Jan 2026 05:08:40 +0000 Subject: [PATCH 2224/3801] Apply `unnecessary_sort_by` to Clippy itself --- clippy_utils/src/ty/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index a90d64e972c1..979170d72006 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -824,7 +824,7 @@ impl AdtVariantInfo { } }) .collect::>(); - variants_size.sort_by(|a, b| b.size.cmp(&a.size)); + variants_size.sort_by_key(|b| std::cmp::Reverse(b.size)); variants_size } } From 4870a5fb692e0fb796a4db6a8259a22b047e14e9 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 1 Jan 2026 09:41:09 +0530 Subject: [PATCH 2225/3801] add worker abstraction --- .../src/bidirectional_protocol.rs | 12 +-- .../proc-macro-api/src/legacy_protocol.rs | 4 +- .../crates/proc-macro-api/src/lib.rs | 17 ++-- .../crates/proc-macro-api/src/process.rs | 94 +++++++++++++++++-- 4 files changed, 103 insertions(+), 24 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index 5996f882981c..643ba98f5176 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -21,7 +21,7 @@ use crate::{ serialize_span_data_index_map, }, }, - process::ProcMacroServerProcess, + process::{ProcMacroWorker, SynIO}, transport::codec::postcard::PostcardProtocol, version, }; @@ -84,7 +84,7 @@ fn wrap_decode(err: io::Error) -> ServerError { } pub(crate) fn version_check( - srv: &ProcMacroServerProcess, + srv: &dyn ProcMacroWorker, callback: SubCallback<'_>, ) -> Result { let request = BidirectionalMessage::Request(Request::ApiVersionCheck {}); @@ -101,7 +101,7 @@ pub(crate) fn version_check( /// Enable support for rust-analyzer span mode if the server supports it. pub(crate) fn enable_rust_analyzer_spans( - srv: &ProcMacroServerProcess, + srv: &dyn ProcMacroWorker, callback: SubCallback<'_>, ) -> Result { let request = BidirectionalMessage::Request(Request::SetConfig(ServerConfig { @@ -120,7 +120,7 @@ pub(crate) fn enable_rust_analyzer_spans( /// Finds proc-macros in a given dynamic library. pub(crate) fn find_proc_macros( - srv: &ProcMacroServerProcess, + srv: &dyn ProcMacroWorker, dylib_path: &AbsPath, callback: SubCallback<'_>, ) -> Result, String>, ServerError> { @@ -175,7 +175,7 @@ pub(crate) fn expand( current_dir: Some(current_dir), }))); - let response_payload = run_request(&proc_macro.process, task, callback)?; + let response_payload = run_request(proc_macro.process.as_ref(), task, callback)?; match response_payload { BidirectionalMessage::Response(Response::ExpandMacro(it)) => Ok(it @@ -205,7 +205,7 @@ pub(crate) fn expand( } fn run_request( - srv: &ProcMacroServerProcess, + srv: &dyn ProcMacroWorker, msg: BidirectionalMessage, callback: SubCallback<'_>, ) -> Result { diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs index aabe5a011851..56bf863a88e9 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs @@ -113,7 +113,7 @@ pub(crate) fn expand( current_dir: Some(current_dir), }; - let response = send_task(&proc_macro.process, Request::ExpandMacro(Box::new(task)))?; + let response = send_task(proc_macro.process.as_ref(), Request::ExpandMacro(Box::new(task)))?; match response { Response::ExpandMacro(it) => Ok(it @@ -143,7 +143,7 @@ pub(crate) fn expand( } /// Sends a request to the proc-macro server and waits for a response. -fn send_task(srv: &ProcMacroServerProcess, req: Request) -> Result { +fn send_task(srv: &dyn ProcMacroWorker, req: Request) -> Result { if let Some(server_error) = srv.exited() { return Err(server_error.clone()); } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 01195c10feef..dd0c89103a2b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -27,7 +27,10 @@ use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span}; use std::{fmt, io, sync::Arc, time::SystemTime}; pub use crate::transport::codec::Codec; -use crate::{bidirectional_protocol::SubCallback, process::ProcMacroServerProcess}; +use crate::{ + bidirectional_protocol::SubCallback, + process::{ProcMacroServerProcess, ProcMacroWorker}, +}; /// The versions of the server protocol pub mod version { @@ -85,7 +88,7 @@ pub struct ProcMacroClient { /// /// That means that concurrent salsa requests may block each other when expanding proc macros, /// which is unfortunate, but simple and good enough for the time being. - process: Arc, + worker: Arc, path: AbsPathBuf, } @@ -107,7 +110,7 @@ impl MacroDylib { /// we share a single expander process for all macros within a workspace. #[derive(Debug, Clone)] pub struct ProcMacro { - process: Arc, + process: Arc, dylib_path: Arc, name: Box, kind: ProcMacroKind, @@ -171,7 +174,7 @@ impl ProcMacroClient { version: Option<&Version>, ) -> io::Result { let process = ProcMacroServerProcess::run(spawn, version, || "".to_owned())?; - Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() }) + Ok(ProcMacroClient { worker: Arc::new(process), path: process_path.to_owned() }) } /// Returns the absolute path to the proc-macro server. @@ -186,7 +189,7 @@ impl ProcMacroClient { callback: Option>, ) -> Result, ServerError> { let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); - let macros = self.process.find_proc_macros(&dylib.path, callback)?; + let macros = self.worker.find_proc_macros(&dylib.path, callback)?; let dylib_path = Arc::new(dylib.path); let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) @@ -196,7 +199,7 @@ impl ProcMacroClient { Ok(macros) => Ok(macros .into_iter() .map(|(name, kind)| ProcMacro { - process: self.process.clone(), + process: self.worker.clone(), name: name.into(), kind, dylib_path: dylib_path.clone(), @@ -209,7 +212,7 @@ impl ProcMacroClient { /// Checks if the proc-macro server has exited. pub fn exited(&self) -> Option<&ServerError> { - self.process.exited() + self.worker.exited() } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index cd387dad0d0b..a206e9fc5d90 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -1,8 +1,9 @@ //! Handle process life-time and message passing for proc-macro client use std::{ + fmt::Debug, io::{self, BufRead, BufReader, Read, Write}, - panic::AssertUnwindSafe, + panic::{AssertUnwindSafe, RefUnwindSafe}, process::{Child, ChildStdin, ChildStdout, Command, Stdio}, sync::{Arc, Mutex, OnceLock}, }; @@ -74,12 +75,79 @@ impl ProcessExit for Process { } /// Maintains the state of the proc-macro server process. -struct ProcessSrvState { +pub(crate) struct ProcessSrvState { process: Box, stdin: Box, stdout: Box, } +impl ProcMacroWorker for ProcMacroServerProcess { + fn find_proc_macros( + &self, + dylib_path: &AbsPath, + callback: Option>, + ) -> Result, String>, ServerError> { + ProcMacroServerProcess::find_proc_macros(self, dylib_path, callback) + } + + fn expand( + &self, + proc_macro: &ProcMacro, + subtree: tt::SubtreeView<'_>, + attr: Option>, + env: Vec<(String, String)>, + def_site: Span, + call_site: Span, + mixed_site: Span, + current_dir: String, + callback: Option>, + ) -> Result, ServerError> { + ProcMacroServerProcess::expand( + self, + proc_macro, + subtree, + attr, + env, + def_site, + call_site, + mixed_site, + current_dir, + callback, + ) + } + + fn exited(&self) -> Option<&ServerError> { + ProcMacroServerProcess::exited(self) + } + + fn version(&self) -> u32 { + ProcMacroServerProcess::version(self) + } + + fn rust_analyzer_spans(&self) -> bool { + ProcMacroServerProcess::rust_analyzer_spans(self) + } + + fn enable_rust_analyzer_spans( + &self, + callback: Option>, + ) -> Result { + ProcMacroServerProcess::enable_rust_analyzer_spans(self, callback) + } + + fn use_postcard(&self) -> bool { + ProcMacroServerProcess::use_postcard(self) + } + + fn state(&self) -> &Mutex { + &self.state + } + + fn get_exited(&self) -> &OnceLock> { + &self.exited + } +} + impl ProcMacroServerProcess { /// Starts the proc-macro server and performs a version check pub(crate) fn spawn<'a>( @@ -291,9 +359,13 @@ impl ProcMacroServerProcess { ), } } +} +pub(crate) struct SynIO; + +impl SynIO { pub(crate) fn send_task( - &self, + proc_macro_worker: &dyn ProcMacroWorker, send: impl FnOnce( &mut dyn Write, &mut dyn BufRead, @@ -302,7 +374,7 @@ impl ProcMacroServerProcess { ) -> Result, ServerError>, req: Request, ) -> Result { - self.with_locked_io::(|writer, reader, buf| { + SynIO::with_locked_io::(proc_macro_worker, |writer, reader, buf| { send(writer, reader, req, buf).and_then(|res| { res.ok_or_else(|| { let message = "proc-macro server did not respond with data".to_owned(); @@ -319,10 +391,10 @@ impl ProcMacroServerProcess { } pub(crate) fn with_locked_io( - &self, + proc_macro_worker: &dyn ProcMacroWorker, f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut C::Buf) -> Result, ) -> Result { - let state = &mut *self.state.lock().unwrap(); + let state = &mut *proc_macro_worker.state().lock().unwrap(); let mut buf = C::Buf::default(); f(&mut state.stdin, &mut state.stdout, &mut buf).map_err(|e| { @@ -330,7 +402,11 @@ impl ProcMacroServerProcess { match state.process.exit_err() { None => e, Some(server_error) => { - self.exited.get_or_init(|| AssertUnwindSafe(server_error)).0.clone() + proc_macro_worker + .get_exited() + .get_or_init(|| AssertUnwindSafe(server_error)) + .0 + .clone() } } } else { @@ -340,11 +416,11 @@ impl ProcMacroServerProcess { } pub(crate) fn run_bidirectional( - &self, + proc_macro_worker: &dyn ProcMacroWorker, initial: BidirectionalMessage, callback: SubCallback<'_>, ) -> Result { - self.with_locked_io::(|writer, reader, buf| { + SynIO::with_locked_io::(proc_macro_worker, |writer, reader, buf| { bidirectional_protocol::run_conversation::(writer, reader, buf, initial, callback) }) } From 98d4496a1e9f03a5193e85304f069757d8032768 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 1 Jan 2026 13:39:04 +0530 Subject: [PATCH 2226/3801] add termination flag to procmacroserverprocess --- .../crates/proc-macro-api/src/process.rs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index a206e9fc5d90..efb8e0e84a1f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -29,6 +29,7 @@ pub(crate) struct ProcMacroServerProcess { protocol: Protocol, /// Populated when the server exits. exited: OnceLock>, + single_use: bool, } impl std::fmt::Debug for ProcMacroServerProcess { @@ -146,6 +147,10 @@ impl ProcMacroWorker for ProcMacroServerProcess { fn get_exited(&self) -> &OnceLock> { &self.exited } + + fn is_reusable(&self) -> bool { + !self.single_use + } } impl ProcMacroServerProcess { @@ -226,6 +231,7 @@ impl ProcMacroServerProcess { } }, exited: OnceLock::new(), + single_use, }) }; let mut srv = create_srv()?; @@ -335,7 +341,7 @@ impl ProcMacroServerProcess { current_dir: String, callback: Option>, ) -> Result, ServerError> { - match self.protocol { + let result = match self.protocol { Protocol::LegacyJson { .. } => legacy_protocol::expand( proc_macro, subtree, @@ -357,6 +363,18 @@ impl ProcMacroServerProcess { current_dir, callback.expect("callback required for bidirectional protocol"), ), + }; + + if self.is_reusable() { + self.terminate(); + } + + result + } + + fn terminate(&self) { + if let Ok(mut state) = self.state.lock() { + let _ = state.process.child.kill(); } } } From 9fb5d34626d2ce137167e556d53c01f04e410329 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 1 Jan 2026 16:05:33 +0530 Subject: [PATCH 2227/3801] add pool of processes --- .../src/bidirectional_protocol.rs | 10 +- .../proc-macro-api/src/legacy_protocol.rs | 2 +- .../crates/proc-macro-api/src/lib.rs | 31 +--- .../crates/proc-macro-api/src/pool.rs | 61 ++++++++ .../crates/proc-macro-api/src/process.rs | 147 ++++++------------ 5 files changed, 122 insertions(+), 129 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index 643ba98f5176..137f2dafc0de 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -21,7 +21,7 @@ use crate::{ serialize_span_data_index_map, }, }, - process::{ProcMacroWorker, SynIO}, + process::ProcMacroServerProcess, transport::codec::postcard::PostcardProtocol, version, }; @@ -84,7 +84,7 @@ fn wrap_decode(err: io::Error) -> ServerError { } pub(crate) fn version_check( - srv: &dyn ProcMacroWorker, + srv: &ProcMacroServerProcess, callback: SubCallback<'_>, ) -> Result { let request = BidirectionalMessage::Request(Request::ApiVersionCheck {}); @@ -101,7 +101,7 @@ pub(crate) fn version_check( /// Enable support for rust-analyzer span mode if the server supports it. pub(crate) fn enable_rust_analyzer_spans( - srv: &dyn ProcMacroWorker, + srv: &ProcMacroServerProcess, callback: SubCallback<'_>, ) -> Result { let request = BidirectionalMessage::Request(Request::SetConfig(ServerConfig { @@ -120,7 +120,7 @@ pub(crate) fn enable_rust_analyzer_spans( /// Finds proc-macros in a given dynamic library. pub(crate) fn find_proc_macros( - srv: &dyn ProcMacroWorker, + srv: &ProcMacroServerProcess, dylib_path: &AbsPath, callback: SubCallback<'_>, ) -> Result, String>, ServerError> { @@ -205,7 +205,7 @@ pub(crate) fn expand( } fn run_request( - srv: &dyn ProcMacroWorker, + srv: &ProcMacroServerProcess, msg: BidirectionalMessage, callback: SubCallback<'_>, ) -> Result { diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs index 56bf863a88e9..7b546cf7aef6 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs @@ -143,7 +143,7 @@ pub(crate) fn expand( } /// Sends a request to the proc-macro server and waits for a response. -fn send_task(srv: &dyn ProcMacroWorker, req: Request) -> Result { +fn send_task(srv: &ProcMacroServerProcess, req: Request) -> Result { if let Some(server_error) = srv.exited() { return Err(server_error.clone()); } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index dd0c89103a2b..ffae28f92c05 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -18,6 +18,7 @@ extern crate rustc_driver as _; pub mod bidirectional_protocol; pub mod legacy_protocol; +pub mod pool; pub mod process; pub mod transport; @@ -29,7 +30,8 @@ use std::{fmt, io, sync::Arc, time::SystemTime}; pub use crate::transport::codec::Codec; use crate::{ bidirectional_protocol::SubCallback, - process::{ProcMacroServerProcess, ProcMacroWorker}, + pool::{ProcMacroServerPool, default_pool_size}, + process::ProcMacroServerProcess, }; /// The versions of the server protocol @@ -88,7 +90,7 @@ pub struct ProcMacroClient { /// /// That means that concurrent salsa requests may block each other when expanding proc macros, /// which is unfortunate, but simple and good enough for the time being. - worker: Arc, + pool: Arc, path: AbsPathBuf, } @@ -110,7 +112,7 @@ impl MacroDylib { /// we share a single expander process for all macros within a workspace. #[derive(Debug, Clone)] pub struct ProcMacro { - process: Arc, + process: Arc, dylib_path: Arc, name: Box, kind: ProcMacroKind, @@ -188,31 +190,12 @@ impl ProcMacroClient { dylib: MacroDylib, callback: Option>, ) -> Result, ServerError> { - let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); - let macros = self.worker.find_proc_macros(&dylib.path, callback)?; - - let dylib_path = Arc::new(dylib.path); - let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) - .ok() - .and_then(|metadata| metadata.modified().ok()); - match macros { - Ok(macros) => Ok(macros - .into_iter() - .map(|(name, kind)| ProcMacro { - process: self.worker.clone(), - name: name.into(), - kind, - dylib_path: dylib_path.clone(), - dylib_last_modified, - }) - .collect()), - Err(message) => Err(ServerError { message, io: None }), - } + self.pool.load_dylib(&dylib, callback) } /// Checks if the proc-macro server has exited. pub fn exited(&self) -> Option<&ServerError> { - self.worker.exited() + self.pool.exited() } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs new file mode 100644 index 000000000000..685bc05be62a --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -0,0 +1,61 @@ +use std::sync::Arc; + +use crate::{ + MacroDylib, ProcMacro, ServerError, bidirectional_protocol::SubCallback, + process::ProcMacroServerProcess, +}; + +#[derive(Debug)] +pub(crate) struct ProcMacroServerPool { + workers: Vec>, +} + +impl ProcMacroServerPool { + pub(crate) fn new(workers: Vec>) -> Self { + Self { workers } + } +} + +impl ProcMacroServerPool { + pub(crate) fn exited(&self) -> Option<&ServerError> { + for worker in &self.workers { + if let Some(e) = worker.exited() { + return Some(e); + } + } + None + } + + pub(crate) fn load_dylib( + &self, + dylib: &MacroDylib, + _callback: Option>, + ) -> Result, ServerError> { + let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); + let mut all_macros = Vec::new(); + + for worker in &self.workers { + let dylib_path = Arc::new(dylib.path.clone()); + let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) + .ok() + .and_then(|metadata| metadata.modified().ok()); + let macros = worker.load_dylib(&dylib.path, None)?; + + for (name, kind) in macros { + all_macros.push(ProcMacro { + process: worker.clone(), + name: name.into(), + kind, + dylib_path: Arc::new(dylib.path.clone()), + dylib_last_modified, + }); + } + } + + Ok(all_macros) + } +} + +pub(crate) fn default_pool_size() -> usize { + std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1).min(4) +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index efb8e0e84a1f..30877c5cf491 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -3,7 +3,7 @@ use std::{ fmt::Debug, io::{self, BufRead, BufReader, Read, Write}, - panic::{AssertUnwindSafe, RefUnwindSafe}, + panic::AssertUnwindSafe, process::{Child, ChildStdin, ChildStdout, Command, Stdio}, sync::{Arc, Mutex, OnceLock}, }; @@ -82,77 +82,6 @@ pub(crate) struct ProcessSrvState { stdout: Box, } -impl ProcMacroWorker for ProcMacroServerProcess { - fn find_proc_macros( - &self, - dylib_path: &AbsPath, - callback: Option>, - ) -> Result, String>, ServerError> { - ProcMacroServerProcess::find_proc_macros(self, dylib_path, callback) - } - - fn expand( - &self, - proc_macro: &ProcMacro, - subtree: tt::SubtreeView<'_>, - attr: Option>, - env: Vec<(String, String)>, - def_site: Span, - call_site: Span, - mixed_site: Span, - current_dir: String, - callback: Option>, - ) -> Result, ServerError> { - ProcMacroServerProcess::expand( - self, - proc_macro, - subtree, - attr, - env, - def_site, - call_site, - mixed_site, - current_dir, - callback, - ) - } - - fn exited(&self) -> Option<&ServerError> { - ProcMacroServerProcess::exited(self) - } - - fn version(&self) -> u32 { - ProcMacroServerProcess::version(self) - } - - fn rust_analyzer_spans(&self) -> bool { - ProcMacroServerProcess::rust_analyzer_spans(self) - } - - fn enable_rust_analyzer_spans( - &self, - callback: Option>, - ) -> Result { - ProcMacroServerProcess::enable_rust_analyzer_spans(self, callback) - } - - fn use_postcard(&self) -> bool { - ProcMacroServerProcess::use_postcard(self) - } - - fn state(&self) -> &Mutex { - &self.state - } - - fn get_exited(&self) -> &OnceLock> { - &self.exited - } - - fn is_reusable(&self) -> bool { - !self.single_use - } -} - impl ProcMacroServerProcess { /// Starts the proc-macro server and performs a version check pub(crate) fn spawn<'a>( @@ -220,7 +149,11 @@ impl ProcMacroServerProcess { let (process, stdin, stdout) = spawn(format)?; io::Result::Ok(ProcMacroServerProcess { - state: Mutex::new(ProcessSrvState { process, stdin, stdout }), + state: Mutex::new(ProcessSrvState { + process, + stdin, + stdout, + }), version: 0, protocol: match format { Some(ProtocolFormat::BidirectionalPostcardPrototype) => { @@ -271,6 +204,37 @@ impl ProcMacroServerProcess { Err(err.unwrap()) } + pub(crate) fn load_dylib( + &self, + dylib_path: &AbsPath, + callback: Option>, + ) -> Result, ServerError> { + let _state = self.state.lock().unwrap(); + + // if state.loaded_dylibs.contains(dylib_path) { + // // Already loaded in this worker + // return Ok(Vec::new()); + // } + + let result = match self.protocol { + Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { + legacy_protocol::find_proc_macros(self, dylib_path)? + } + Protocol::BidirectionalPostcardPrototype { .. } => { + let cb = callback.expect("callback required"); + bidirectional_protocol::find_proc_macros(self, dylib_path, cb)? + } + }; + + match result { + Ok(macros) => { + // state.loaded_dylibs.insert(dylib_path.to_owned()); + Ok(macros) + } + Err(message) => Err(ServerError { message, io: None }), + } + } + /// Returns the server error if the process has exited. pub(crate) fn exited(&self) -> Option<&ServerError> { self.exited.get().map(|it| &it.0) @@ -314,21 +278,6 @@ impl ProcMacroServerProcess { } } - /// Finds proc-macros in a given dynamic library. - pub(crate) fn find_proc_macros( - &self, - dylib_path: &AbsPath, - callback: Option>, - ) -> Result, String>, ServerError> { - match self.protocol { - Protocol::LegacyJson { .. } => legacy_protocol::find_proc_macros(self, dylib_path), - Protocol::BidirectionalPostcardPrototype { .. } => { - let cb = callback.expect("callback required for bidirectional protocol"); - bidirectional_protocol::find_proc_macros(self, dylib_path, cb) - } - } - } - pub(crate) fn expand( &self, proc_macro: &ProcMacro, @@ -365,25 +314,25 @@ impl ProcMacroServerProcess { ), }; - if self.is_reusable() { + if !self.is_reusable() { self.terminate(); } result } + fn is_reusable(&self) -> bool { + self.single_use + } + fn terminate(&self) { if let Ok(mut state) = self.state.lock() { let _ = state.process.child.kill(); } } -} -pub(crate) struct SynIO; - -impl SynIO { pub(crate) fn send_task( - proc_macro_worker: &dyn ProcMacroWorker, + &self, send: impl FnOnce( &mut dyn Write, &mut dyn BufRead, @@ -392,7 +341,7 @@ impl SynIO { ) -> Result, ServerError>, req: Request, ) -> Result { - SynIO::with_locked_io::(proc_macro_worker, |writer, reader, buf| { + self.with_locked_io::(|writer, reader, buf| { send(writer, reader, req, buf).and_then(|res| { res.ok_or_else(|| { let message = "proc-macro server did not respond with data".to_owned(); @@ -409,10 +358,10 @@ impl SynIO { } pub(crate) fn with_locked_io( - proc_macro_worker: &dyn ProcMacroWorker, + &self, f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut C::Buf) -> Result, ) -> Result { - let state = &mut *proc_macro_worker.state().lock().unwrap(); + let state = &mut *self.state.lock().unwrap(); let mut buf = C::Buf::default(); f(&mut state.stdin, &mut state.stdout, &mut buf).map_err(|e| { @@ -434,11 +383,11 @@ impl SynIO { } pub(crate) fn run_bidirectional( - proc_macro_worker: &dyn ProcMacroWorker, + &self, initial: BidirectionalMessage, callback: SubCallback<'_>, ) -> Result { - SynIO::with_locked_io::(proc_macro_worker, |writer, reader, buf| { + self.with_locked_io::(|writer, reader, buf| { bidirectional_protocol::run_conversation::(writer, reader, buf, initial, callback) }) } From c685aa912349b96f21485c434d03ee288cfceb9e Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 2 Jan 2026 11:03:20 +0530 Subject: [PATCH 2228/3801] direct client calls via pool --- .../src/bidirectional_protocol.rs | 11 +-- .../proc-macro-api/src/legacy_protocol.rs | 11 +-- .../crates/proc-macro-api/src/lib.rs | 21 +----- .../crates/proc-macro-api/src/pool.rs | 72 ++++++++++++++++--- .../crates/proc-macro-api/src/process.rs | 65 ++++++----------- 5 files changed, 98 insertions(+), 82 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index 137f2dafc0de..cd1f6f6f1f33 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -138,6 +138,7 @@ pub(crate) fn find_proc_macros( pub(crate) fn expand( proc_macro: &ProcMacro, + process: &ProcMacroServerProcess, subtree: tt::SubtreeView<'_>, attr: Option>, env: Vec<(String, String)>, @@ -147,7 +148,7 @@ pub(crate) fn expand( current_dir: String, callback: SubCallback<'_>, ) -> Result, crate::ServerError> { - let version = proc_macro.process.version(); + let version = process.version(); let mut span_data_table = SpanDataIndexMap::default(); let def_site = span_data_table.insert_full(def_site).0; let call_site = span_data_table.insert_full(call_site).0; @@ -164,7 +165,7 @@ pub(crate) fn expand( call_site, mixed_site, }, - span_data_table: if proc_macro.process.rust_analyzer_spans() { + span_data_table: if process.rust_analyzer_spans() { serialize_span_data_index_map(&span_data_table) } else { Vec::new() @@ -175,13 +176,13 @@ pub(crate) fn expand( current_dir: Some(current_dir), }))); - let response_payload = run_request(proc_macro.process.as_ref(), task, callback)?; + let response_payload = run_request(process, task, callback)?; match response_payload { BidirectionalMessage::Response(Response::ExpandMacro(it)) => Ok(it .map(|tree| { let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table); - if proc_macro.needs_fixup_change() { + if proc_macro.needs_fixup_change(process) { proc_macro.change_fixup_to_match_old_server(&mut expanded); } expanded @@ -194,7 +195,7 @@ pub(crate) fn expand( version, &deserialize_span_data_index_map(&resp.span_data_table), ); - if proc_macro.needs_fixup_change() { + if proc_macro.needs_fixup_change(process) { proc_macro.change_fixup_to_match_old_server(&mut expanded); } expanded diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs index 7b546cf7aef6..412d20730324 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs @@ -77,6 +77,7 @@ pub(crate) fn find_proc_macros( pub(crate) fn expand( proc_macro: &ProcMacro, + process: &ProcMacroServerProcess, subtree: tt::SubtreeView<'_>, attr: Option>, env: Vec<(String, String)>, @@ -85,7 +86,7 @@ pub(crate) fn expand( mixed_site: Span, current_dir: String, ) -> Result, crate::ServerError> { - let version = proc_macro.process.version(); + let version = process.version(); let mut span_data_table = SpanDataIndexMap::default(); let def_site = span_data_table.insert_full(def_site).0; let call_site = span_data_table.insert_full(call_site).0; @@ -102,7 +103,7 @@ pub(crate) fn expand( call_site, mixed_site, }, - span_data_table: if proc_macro.process.rust_analyzer_spans() { + span_data_table: if process.rust_analyzer_spans() { serialize_span_data_index_map(&span_data_table) } else { Vec::new() @@ -113,13 +114,13 @@ pub(crate) fn expand( current_dir: Some(current_dir), }; - let response = send_task(proc_macro.process.as_ref(), Request::ExpandMacro(Box::new(task)))?; + let response = send_task(process, Request::ExpandMacro(Box::new(task)))?; match response { Response::ExpandMacro(it) => Ok(it .map(|tree| { let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table); - if proc_macro.needs_fixup_change() { + if proc_macro.needs_fixup_change(process) { proc_macro.change_fixup_to_match_old_server(&mut expanded); } expanded @@ -132,7 +133,7 @@ pub(crate) fn expand( version, &deserialize_span_data_index_map(&resp.span_data_table), ); - if proc_macro.needs_fixup_change() { + if proc_macro.needs_fixup_change(process) { proc_macro.change_fixup_to_match_old_server(&mut expanded); } expanded diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index ffae28f92c05..fe17e14024cc 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -112,7 +112,7 @@ impl MacroDylib { /// we share a single expander process for all macros within a workspace. #[derive(Debug, Clone)] pub struct ProcMacro { - process: Arc, + process: ProcMacroServerPool, dylib_path: Arc, name: Box, kind: ProcMacroKind, @@ -126,7 +126,6 @@ impl PartialEq for ProcMacro { && self.kind == other.kind && self.dylib_path == other.dylib_path && self.dylib_last_modified == other.dylib_last_modified - && Arc::ptr_eq(&self.process, &other.process) } } @@ -210,8 +209,8 @@ impl ProcMacro { self.kind } - fn needs_fixup_change(&self) -> bool { - let version = self.process.version(); + fn needs_fixup_change(&self, process: &ProcMacroServerProcess) -> bool { + let version = process.version(); (version::RUST_ANALYZER_SPAN_SUPPORT..version::HASHED_AST_ID).contains(&version) } @@ -241,20 +240,6 @@ impl ProcMacro { current_dir: String, callback: Option>, ) -> Result, ServerError> { - let (mut subtree, mut attr) = (subtree, attr); - let (mut subtree_changed, mut attr_changed); - if self.needs_fixup_change() { - subtree_changed = tt::TopSubtree::from_subtree(subtree); - self.change_fixup_to_match_old_server(&mut subtree_changed); - subtree = subtree_changed.view(); - - if let Some(attr) = &mut attr { - attr_changed = tt::TopSubtree::from_subtree(*attr); - self.change_fixup_to_match_old_server(&mut attr_changed); - *attr = attr_changed.view(); - } - } - self.process.expand( self, subtree, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index 685bc05be62a..4639374f3e24 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -1,29 +1,38 @@ use std::sync::Arc; +use tt::Span; + use crate::{ MacroDylib, ProcMacro, ServerError, bidirectional_protocol::SubCallback, process::ProcMacroServerProcess, }; -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct ProcMacroServerPool { - workers: Vec>, + workers: Arc<[ProcMacroServerProcess]>, } impl ProcMacroServerPool { - pub(crate) fn new(workers: Vec>) -> Self { - Self { workers } + pub(crate) fn new(workers: Vec) -> Self { + Self { workers: workers.into() } } } impl ProcMacroServerPool { pub(crate) fn exited(&self) -> Option<&ServerError> { - for worker in &self.workers { - if let Some(e) = worker.exited() { - return Some(e); + for worker in &*self.workers { + worker.exited()?; + } + self.workers[0].exited() + } + + fn pick_process(&self) -> &ProcMacroServerProcess { + for workers in &*self.workers { + if workers.can_use() { + return workers; } } - None + &self.workers[0] } pub(crate) fn load_dylib( @@ -34,16 +43,16 @@ impl ProcMacroServerPool { let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); let mut all_macros = Vec::new(); - for worker in &self.workers { + for worker in &*self.workers { let dylib_path = Arc::new(dylib.path.clone()); let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) .ok() .and_then(|metadata| metadata.modified().ok()); - let macros = worker.load_dylib(&dylib.path, None)?; + let macros = worker.find_proc_macros(&dylib.path, None)?.unwrap(); for (name, kind) in macros { all_macros.push(ProcMacro { - process: worker.clone(), + process: self.clone(), name: name.into(), kind, dylib_path: Arc::new(dylib.path.clone()), @@ -54,6 +63,47 @@ impl ProcMacroServerPool { Ok(all_macros) } + + pub(crate) fn expand( + &self, + proc_macro: &ProcMacro, + subtree: tt::SubtreeView<'_>, + attr: Option>, + env: Vec<(String, String)>, + def_site: Span, + call_site: Span, + mixed_site: Span, + current_dir: String, + callback: Option>, + ) -> Result, ServerError> { + let process = self.pick_process(); + + let (mut subtree, mut attr) = (subtree, attr); + let (mut subtree_changed, mut attr_changed); + if proc_macro.needs_fixup_change(process) { + subtree_changed = tt::TopSubtree::from_subtree(subtree); + proc_macro.change_fixup_to_match_old_server(&mut subtree_changed); + subtree = subtree_changed.view(); + + if let Some(attr) = &mut attr { + attr_changed = tt::TopSubtree::from_subtree(*attr); + proc_macro.change_fixup_to_match_old_server(&mut attr_changed); + *attr = attr_changed.view(); + } + } + + process.expand( + proc_macro, + subtree, + attr, + env, + def_site, + call_site, + mixed_site, + current_dir, + callback, + ) + } } pub(crate) fn default_pool_size() -> usize { diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index 30877c5cf491..a41bb58e74be 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -5,7 +5,10 @@ use std::{ io::{self, BufRead, BufReader, Read, Write}, panic::AssertUnwindSafe, process::{Child, ChildStdin, ChildStdout, Command, Stdio}, - sync::{Arc, Mutex, OnceLock}, + sync::{ + Arc, Mutex, OnceLock, + atomic::{AtomicBool, Ordering}, + }, }; use paths::AbsPath; @@ -29,7 +32,7 @@ pub(crate) struct ProcMacroServerProcess { protocol: Protocol, /// Populated when the server exits. exited: OnceLock>, - single_use: bool, + can_use: AtomicBool, } impl std::fmt::Debug for ProcMacroServerProcess { @@ -149,11 +152,7 @@ impl ProcMacroServerProcess { let (process, stdin, stdout) = spawn(format)?; io::Result::Ok(ProcMacroServerProcess { - state: Mutex::new(ProcessSrvState { - process, - stdin, - stdout, - }), + state: Mutex::new(ProcessSrvState { process, stdin, stdout }), version: 0, protocol: match format { Some(ProtocolFormat::BidirectionalPostcardPrototype) => { @@ -164,7 +163,7 @@ impl ProcMacroServerProcess { } }, exited: OnceLock::new(), - single_use, + can_use: AtomicBool::new(true), }) }; let mut srv = create_srv()?; @@ -204,34 +203,20 @@ impl ProcMacroServerProcess { Err(err.unwrap()) } - pub(crate) fn load_dylib( + /// Finds proc-macros in a given dynamic library. + pub(crate) fn find_proc_macros( &self, dylib_path: &AbsPath, callback: Option>, - ) -> Result, ServerError> { - let _state = self.state.lock().unwrap(); - - // if state.loaded_dylibs.contains(dylib_path) { - // // Already loaded in this worker - // return Ok(Vec::new()); - // } - - let result = match self.protocol { + ) -> Result, String>, ServerError> { + match self.protocol { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { - legacy_protocol::find_proc_macros(self, dylib_path)? + legacy_protocol::find_proc_macros(self, dylib_path) } Protocol::BidirectionalPostcardPrototype { .. } => { - let cb = callback.expect("callback required"); - bidirectional_protocol::find_proc_macros(self, dylib_path, cb)? + let cb = callback.expect("callback required for bidirectional protocol"); + bidirectional_protocol::find_proc_macros(self, dylib_path, cb) } - }; - - match result { - Ok(macros) => { - // state.loaded_dylibs.insert(dylib_path.to_owned()); - Ok(macros) - } - Err(message) => Err(ServerError { message, io: None }), } } @@ -290,9 +275,11 @@ impl ProcMacroServerProcess { current_dir: String, callback: Option>, ) -> Result, ServerError> { + self.can_use.store(false, Ordering::Release); let result = match self.protocol { Protocol::LegacyJson { .. } => legacy_protocol::expand( proc_macro, + self, subtree, attr, env, @@ -303,6 +290,7 @@ impl ProcMacroServerProcess { ), Protocol::BidirectionalPostcardPrototype { .. } => bidirectional_protocol::expand( proc_macro, + self, subtree, attr, env, @@ -314,23 +302,10 @@ impl ProcMacroServerProcess { ), }; - if !self.is_reusable() { - self.terminate(); - } - + self.can_use.store(true, Ordering::Release); result } - fn is_reusable(&self) -> bool { - self.single_use - } - - fn terminate(&self) { - if let Ok(mut state) = self.state.lock() { - let _ = state.process.child.kill(); - } - } - pub(crate) fn send_task( &self, send: impl FnOnce( @@ -391,6 +366,10 @@ impl ProcMacroServerProcess { bidirectional_protocol::run_conversation::(writer, reader, buf, initial, callback) }) } + + pub(crate) fn can_use(&self) -> bool { + self.can_use.load(Ordering::Acquire) + } } /// Manages the execution of the proc-macro server process. From 82e758acc1a76b2a8d8083121b031fc2b3e3a653 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 2 Jan 2026 11:46:00 +0530 Subject: [PATCH 2229/3801] add better process picker and improve loading dylib --- .../crates/proc-macro-api/src/pool.rs | 48 ++++++++++--------- .../crates/proc-macro-api/src/process.rs | 14 +++--- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index 4639374f3e24..4215b0f2c04f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -27,12 +27,10 @@ impl ProcMacroServerPool { } fn pick_process(&self) -> &ProcMacroServerProcess { - for workers in &*self.workers { - if workers.can_use() { - return workers; - } - } - &self.workers[0] + self.workers + .iter() + .min_by_key(|w| w.number_of_active_req()) + .expect("worker pool must not be empty") } pub(crate) fn load_dylib( @@ -41,27 +39,31 @@ impl ProcMacroServerPool { _callback: Option>, ) -> Result, ServerError> { let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); - let mut all_macros = Vec::new(); - for worker in &*self.workers { - let dylib_path = Arc::new(dylib.path.clone()); - let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) - .ok() - .and_then(|metadata| metadata.modified().ok()); - let macros = worker.find_proc_macros(&dylib.path, None)?.unwrap(); + let dylib_path = Arc::new(dylib.path.clone()); + let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) + .ok() + .and_then(|metadata| metadata.modified().ok()); - for (name, kind) in macros { - all_macros.push(ProcMacro { - process: self.clone(), - name: name.into(), - kind, - dylib_path: Arc::new(dylib.path.clone()), - dylib_last_modified, - }); - } + let first = &self.workers[0]; + let macros = first.find_proc_macros(&dylib.path, None)?.unwrap(); + + for worker in &self.workers[1..] { + let _ = worker.find_proc_macros(&dylib.path, None)?; } - Ok(all_macros) + let result = macros + .into_iter() + .map(|(name, kind)| ProcMacro { + process: self.clone(), + name: name.into(), + kind, + dylib_path: dylib_path.clone(), + dylib_last_modified, + }) + .collect(); + + Ok(result) } pub(crate) fn expand( diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index a41bb58e74be..775d59174f1c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -7,7 +7,7 @@ use std::{ process::{Child, ChildStdin, ChildStdout, Command, Stdio}, sync::{ Arc, Mutex, OnceLock, - atomic::{AtomicBool, Ordering}, + atomic::{AtomicU32, Ordering}, }, }; @@ -32,7 +32,7 @@ pub(crate) struct ProcMacroServerProcess { protocol: Protocol, /// Populated when the server exits. exited: OnceLock>, - can_use: AtomicBool, + active: AtomicU32, } impl std::fmt::Debug for ProcMacroServerProcess { @@ -163,7 +163,7 @@ impl ProcMacroServerProcess { } }, exited: OnceLock::new(), - can_use: AtomicBool::new(true), + active: AtomicU32::new(0), }) }; let mut srv = create_srv()?; @@ -275,7 +275,7 @@ impl ProcMacroServerProcess { current_dir: String, callback: Option>, ) -> Result, ServerError> { - self.can_use.store(false, Ordering::Release); + self.active.fetch_add(1, Ordering::AcqRel); let result = match self.protocol { Protocol::LegacyJson { .. } => legacy_protocol::expand( proc_macro, @@ -302,7 +302,7 @@ impl ProcMacroServerProcess { ), }; - self.can_use.store(true, Ordering::Release); + self.active.fetch_sub(1, Ordering::AcqRel); result } @@ -367,8 +367,8 @@ impl ProcMacroServerProcess { }) } - pub(crate) fn can_use(&self) -> bool { - self.can_use.load(Ordering::Acquire) + pub(crate) fn number_of_active_req(&self) -> u32 { + self.active.load(Ordering::Acquire) } } From 922bc7e4d49da5656c901e0a2d4a9805f413dcf8 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 2 Jan 2026 11:56:19 +0530 Subject: [PATCH 2230/3801] rename process to pool in ProcMacro struct --- src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs | 4 ++-- src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index fe17e14024cc..09999ea5081a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -112,7 +112,7 @@ impl MacroDylib { /// we share a single expander process for all macros within a workspace. #[derive(Debug, Clone)] pub struct ProcMacro { - process: ProcMacroServerPool, + pool: ProcMacroServerPool, dylib_path: Arc, name: Box, kind: ProcMacroKind, @@ -240,7 +240,7 @@ impl ProcMacro { current_dir: String, callback: Option>, ) -> Result, ServerError> { - self.process.expand( + self.pool.expand( self, subtree, attr, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index 4215b0f2c04f..eef8d0194dc5 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -55,7 +55,7 @@ impl ProcMacroServerPool { let result = macros .into_iter() .map(|(name, kind)| ProcMacro { - process: self.clone(), + pool: self.clone(), name: name.into(), kind, dylib_path: dylib_path.clone(), From c4c336ad7c291686542826bfd5b0bc8f2e298777 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 2 Jan 2026 12:11:11 +0530 Subject: [PATCH 2231/3801] keep it clean and tidy --- src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index eef8d0194dc5..fe4649441b89 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -1,3 +1,4 @@ +//! This module represents Process Pool use std::sync::Arc; use tt::Span; From c8a3551bd162c6374d4c49bfc06070488edb44ed Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 11:32:08 +0530 Subject: [PATCH 2232/3801] change callback from FnMut to Fn as we only transform messages and not really change change state --- src/tools/rust-analyzer/crates/load-cargo/src/lib.rs | 6 +++--- .../crates/proc-macro-api/src/bidirectional_protocol.rs | 2 +- .../rust-analyzer/crates/proc-macro-api/src/process.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 8342492a33a4..ccc9aa4291ec 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -435,7 +435,7 @@ pub fn load_proc_macro( ) -> ProcMacroLoadResult { let res: Result, _> = (|| { let dylib = MacroDylib::new(path.to_path_buf()); - let vec = server.load_dylib(dylib, Some(&mut reject_subrequests)).map_err(|e| { + let vec = server.load_dylib(dylib, Some(&reject_subrequests)).map_err(|e| { ProcMacroLoadingError::ProcMacroSrvError(format!("{e}").into_boxed_str()) })?; if vec.is_empty() { @@ -541,7 +541,7 @@ impl ProcMacroExpander for Expander { mixed_site: Span, current_dir: String, ) -> Result { - let mut cb = |req| match req { + let cb = |req| match req { SubRequest::LocalFilePath { file_id } => { let file_id = FileId::from_raw(file_id); let source_root_id = db.file_source_root(file_id).source_root_id(db); @@ -613,7 +613,7 @@ impl ProcMacroExpander for Expander { call_site, mixed_site, current_dir, - Some(&mut cb), + Some(&cb), ) { Ok(Ok(subtree)) => Ok(subtree), Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err)), diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index cd1f6f6f1f33..25266c46fe89 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -28,7 +28,7 @@ use crate::{ pub mod msg; -pub type SubCallback<'a> = &'a mut dyn FnMut(SubRequest) -> Result; +pub type SubCallback<'a> = &'a dyn Fn(SubRequest) -> Result; pub fn run_conversation( writer: &mut dyn Write, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index 775d59174f1c..c1b95fa7f10e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -168,7 +168,7 @@ impl ProcMacroServerProcess { }; let mut srv = create_srv()?; tracing::info!("sending proc-macro server version check"); - match srv.version_check(Some(&mut reject_subrequests)) { + match srv.version_check(Some(&reject_subrequests)) { Ok(v) if v > version::CURRENT_API_VERSION => { let process_version = binary_server_version(); err = Some(io::Error::other(format!( @@ -182,7 +182,7 @@ impl ProcMacroServerProcess { srv.version = v; if srv.version >= version::RUST_ANALYZER_SPAN_SUPPORT && let Ok(new_mode) = - srv.enable_rust_analyzer_spans(Some(&mut reject_subrequests)) + srv.enable_rust_analyzer_spans(Some(&reject_subrequests)) { match &mut srv.protocol { Protocol::LegacyJson { mode } From 66bca6a25214332ff559acb7678d3ce423279e77 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 11:36:09 +0530 Subject: [PATCH 2233/3801] propagate error from load dylibs --- .../crates/proc-macro-api/src/pool.rs | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index fe4649441b89..20389f666883 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -37,23 +37,27 @@ impl ProcMacroServerPool { pub(crate) fn load_dylib( &self, dylib: &MacroDylib, - _callback: Option>, + callback: Option>, ) -> Result, ServerError> { - let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); + let _span = tracing::info_span!("ProcMacroServer::load_dylib").entered(); let dylib_path = Arc::new(dylib.path.clone()); - let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) - .ok() - .and_then(|metadata| metadata.modified().ok()); + let dylib_last_modified = + std::fs::metadata(dylib_path.as_path()).ok().and_then(|m| m.modified().ok()); - let first = &self.workers[0]; - let macros = first.find_proc_macros(&dylib.path, None)?.unwrap(); + let (first, rest) = self.workers.split_first().expect("worker pool must not be empty"); - for worker in &self.workers[1..] { - let _ = worker.find_proc_macros(&dylib.path, None)?; + let macros = first + .find_proc_macros(&dylib.path, callback)? + .map_err(|e| ServerError { message: e, io: None })?; + + for worker in rest { + worker + .find_proc_macros(&dylib.path, callback)? + .map_err(|e| ServerError { message: e, io: None })?; } - let result = macros + Ok(macros .into_iter() .map(|(name, kind)| ProcMacro { pool: self.clone(), @@ -62,9 +66,7 @@ impl ProcMacroServerPool { dylib_path: dylib_path.clone(), dylib_last_modified, }) - .collect(); - - Ok(result) + .collect()) } pub(crate) fn expand( From 09c91b79a84faebb2e06094f8c8d1592a371a3e4 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 3 Jan 2026 13:43:23 +0530 Subject: [PATCH 2234/3801] pick workers which have not exited --- .../rust-analyzer/crates/proc-macro-api/src/pool.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index 20389f666883..c75e9742a5d1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -27,11 +27,15 @@ impl ProcMacroServerPool { self.workers[0].exited() } - fn pick_process(&self) -> &ProcMacroServerProcess { + fn pick_process(&self) -> Result<&ProcMacroServerProcess, ServerError> { self.workers .iter() + .filter(|w| w.exited().is_none()) .min_by_key(|w| w.number_of_active_req()) - .expect("worker pool must not be empty") + .ok_or_else(|| ServerError { + message: "all proc-macro server workers have exited".into(), + io: None, + }) } pub(crate) fn load_dylib( @@ -81,7 +85,7 @@ impl ProcMacroServerPool { current_dir: String, callback: Option>, ) -> Result, ServerError> { - let process = self.pick_process(); + let process = self.pick_process()?; let (mut subtree, mut attr) = (subtree, attr); let (mut subtree_changed, mut attr_changed); From 0936597b3ea2944869d1a0b2058746e295eeb16d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 4 Jan 2026 05:02:15 +0530 Subject: [PATCH 2235/3801] add version to pool --- .../src/bidirectional_protocol.rs | 4 ++-- .../proc-macro-api/src/legacy_protocol.rs | 4 ++-- .../crates/proc-macro-api/src/lib.rs | 18 ++++++++++++-- .../crates/proc-macro-api/src/pool.rs | 24 +++++++------------ 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index 25266c46fe89..b5f43e1d3726 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -182,7 +182,7 @@ pub(crate) fn expand( BidirectionalMessage::Response(Response::ExpandMacro(it)) => Ok(it .map(|tree| { let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table); - if proc_macro.needs_fixup_change(process) { + if proc_macro.needs_fixup_change() { proc_macro.change_fixup_to_match_old_server(&mut expanded); } expanded @@ -195,7 +195,7 @@ pub(crate) fn expand( version, &deserialize_span_data_index_map(&resp.span_data_table), ); - if proc_macro.needs_fixup_change(process) { + if proc_macro.needs_fixup_change() { proc_macro.change_fixup_to_match_old_server(&mut expanded); } expanded diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs index 412d20730324..eedf66d46086 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs @@ -120,7 +120,7 @@ pub(crate) fn expand( Response::ExpandMacro(it) => Ok(it .map(|tree| { let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table); - if proc_macro.needs_fixup_change(process) { + if proc_macro.needs_fixup_change() { proc_macro.change_fixup_to_match_old_server(&mut expanded); } expanded @@ -133,7 +133,7 @@ pub(crate) fn expand( version, &deserialize_span_data_index_map(&resp.span_data_table), ); - if proc_macro.needs_fixup_change(process) { + if proc_macro.needs_fixup_change() { proc_macro.change_fixup_to_match_old_server(&mut expanded); } expanded diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 09999ea5081a..4874e63244c4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -209,8 +209,8 @@ impl ProcMacro { self.kind } - fn needs_fixup_change(&self, process: &ProcMacroServerProcess) -> bool { - let version = process.version(); + fn needs_fixup_change(&self) -> bool { + let version = self.pool.version(); (version::RUST_ANALYZER_SPAN_SUPPORT..version::HASHED_AST_ID).contains(&version) } @@ -240,6 +240,20 @@ impl ProcMacro { current_dir: String, callback: Option>, ) -> Result, ServerError> { + let (mut subtree, mut attr) = (subtree, attr); + let (mut subtree_changed, mut attr_changed); + if self.needs_fixup_change() { + subtree_changed = tt::TopSubtree::from_subtree(subtree); + self.change_fixup_to_match_old_server(&mut subtree_changed); + subtree = subtree_changed.view(); + + if let Some(attr) = &mut attr { + attr_changed = tt::TopSubtree::from_subtree(*attr); + self.change_fixup_to_match_old_server(&mut attr_changed); + *attr = attr_changed.view(); + } + } + self.pool.expand( self, subtree, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index c75e9742a5d1..fd8b726f820e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -1,4 +1,4 @@ -//! This module represents Process Pool +//! A pool of proc-macro server processes use std::sync::Arc; use tt::Span; @@ -11,11 +11,13 @@ use crate::{ #[derive(Debug, Clone)] pub(crate) struct ProcMacroServerPool { workers: Arc<[ProcMacroServerProcess]>, + version: u32, } impl ProcMacroServerPool { pub(crate) fn new(workers: Vec) -> Self { - Self { workers: workers.into() } + let version = workers[0].version(); + Self { workers: workers.into(), version } } } @@ -87,20 +89,6 @@ impl ProcMacroServerPool { ) -> Result, ServerError> { let process = self.pick_process()?; - let (mut subtree, mut attr) = (subtree, attr); - let (mut subtree_changed, mut attr_changed); - if proc_macro.needs_fixup_change(process) { - subtree_changed = tt::TopSubtree::from_subtree(subtree); - proc_macro.change_fixup_to_match_old_server(&mut subtree_changed); - subtree = subtree_changed.view(); - - if let Some(attr) = &mut attr { - attr_changed = tt::TopSubtree::from_subtree(*attr); - proc_macro.change_fixup_to_match_old_server(&mut attr_changed); - *attr = attr_changed.view(); - } - } - process.expand( proc_macro, subtree, @@ -113,6 +101,10 @@ impl ProcMacroServerPool { callback, ) } + + pub(crate) fn version(&self) -> u32 { + self.version + } } pub(crate) fn default_pool_size() -> usize { From 263015a4a4d4cbbbc1e7cd0e118c10e0a8e740df Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 4 Jan 2026 05:50:16 +0530 Subject: [PATCH 2236/3801] remove expand from pool --- .../crates/proc-macro-api/src/lib.rs | 2 +- .../crates/proc-macro-api/src/pool.rs | 31 +------------------ 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 4874e63244c4..ad462ff31a1b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -254,7 +254,7 @@ impl ProcMacro { } } - self.pool.expand( + self.pool.pick_process()?.expand( self, subtree, attr, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index fd8b726f820e..13a4b5ee8f9e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -1,8 +1,6 @@ //! A pool of proc-macro server processes use std::sync::Arc; -use tt::Span; - use crate::{ MacroDylib, ProcMacro, ServerError, bidirectional_protocol::SubCallback, process::ProcMacroServerProcess, @@ -29,7 +27,7 @@ impl ProcMacroServerPool { self.workers[0].exited() } - fn pick_process(&self) -> Result<&ProcMacroServerProcess, ServerError> { + pub(crate) fn pick_process(&self) -> Result<&ProcMacroServerProcess, ServerError> { self.workers .iter() .filter(|w| w.exited().is_none()) @@ -75,33 +73,6 @@ impl ProcMacroServerPool { .collect()) } - pub(crate) fn expand( - &self, - proc_macro: &ProcMacro, - subtree: tt::SubtreeView<'_>, - attr: Option>, - env: Vec<(String, String)>, - def_site: Span, - call_site: Span, - mixed_site: Span, - current_dir: String, - callback: Option>, - ) -> Result, ServerError> { - let process = self.pick_process()?; - - process.expand( - proc_macro, - subtree, - attr, - env, - def_site, - call_site, - mixed_site, - current_dir, - callback, - ) - } - pub(crate) fn version(&self) -> u32 { self.version } From e3e7c2905442499a6c3eb778be14730dc16d82af Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 5 Jan 2026 09:41:39 +0530 Subject: [PATCH 2237/3801] remove default pool size from pool --- src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index 13a4b5ee8f9e..0cb505aa40a9 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -77,7 +77,3 @@ impl ProcMacroServerPool { self.version } } - -pub(crate) fn default_pool_size() -> usize { - std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1).min(4) -} From 96ecd1773c56e11def32667a3d70f4b29563f137 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 5 Jan 2026 09:44:15 +0530 Subject: [PATCH 2238/3801] add num process in config --- .../crates/rust-analyzer/src/config.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 28ac94e4deb6..cb6552c32ffb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -380,6 +380,8 @@ config_data! { /// The number of worker threads in the main loop. The default `null` means to pick /// automatically. numThreads: Option = None, + /// The number of proc-macro-srv processes + proc_macro_processes: NumProcesses = NumProcesses::Concrete(1), /// Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set. procMacro_attributes_enable: bool = true, @@ -2641,6 +2643,13 @@ impl Config { } } + pub fn proc_macro_num_processes(&self) -> usize { + match self.proc_macro_processes() { + NumProcesses::Concrete(0) | NumProcesses::Physical => num_cpus::get_physical(), + &NumProcesses::Concrete(n) => n, + } + } + pub fn main_loop_num_threads(&self) -> usize { match self.numThreads() { Some(NumThreads::Concrete(0)) | None | Some(NumThreads::Physical) => { @@ -3077,6 +3086,14 @@ pub enum NumThreads { Concrete(usize), } +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum NumProcesses { + Physical, + #[serde(untagged)] + Concrete(usize), +} + macro_rules! _default_val { ($default:expr, $ty:ty) => {{ let default_: $ty = $default; From 9d5e60005addf5eb8635884f051771a8119f0bb2 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 5 Jan 2026 09:44:44 +0530 Subject: [PATCH 2239/3801] add proc_macro_processes in load config --- .../crates/load-cargo/src/lib.rs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index ccc9aa4291ec..c2935d94a8a7 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -45,6 +45,7 @@ pub struct LoadCargoConfig { pub load_out_dirs_from_check: bool, pub with_proc_macro_server: ProcMacroServerChoice, pub prefill_caches: bool, + pub proc_macro_processes: usize, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -113,15 +114,25 @@ pub fn load_workspace_into_db( let proc_macro_server = match &load_config.with_proc_macro_server { ProcMacroServerChoice::Sysroot => ws.find_sysroot_proc_macro_srv().map(|it| { it.and_then(|it| { - ProcMacroClient::spawn(&it, extra_env, ws.toolchain.as_ref()).map_err(Into::into) + ProcMacroClient::spawn( + &it, + extra_env, + ws.toolchain.as_ref(), + load_config.proc_macro_processes, + ) + .map_err(Into::into) }) .map_err(|e| ProcMacroLoadingError::ProcMacroSrvError(e.to_string().into_boxed_str())) }), - ProcMacroServerChoice::Explicit(path) => { - Some(ProcMacroClient::spawn(path, extra_env, ws.toolchain.as_ref()).map_err(|e| { - ProcMacroLoadingError::ProcMacroSrvError(e.to_string().into_boxed_str()) - })) - } + ProcMacroServerChoice::Explicit(path) => Some( + ProcMacroClient::spawn( + path, + extra_env, + ws.toolchain.as_ref(), + load_config.proc_macro_processes, + ) + .map_err(|e| ProcMacroLoadingError::ProcMacroSrvError(e.to_string().into_boxed_str())), + ), ProcMacroServerChoice::None => Some(Err(ProcMacroLoadingError::Disabled)), }; match &proc_macro_server { @@ -657,6 +668,7 @@ mod tests { load_out_dirs_from_check: false, with_proc_macro_server: ProcMacroServerChoice::None, prefill_caches: false, + proc_macro_processes: 1, }; let (db, _vfs, _proc_macro) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {}).unwrap(); From 721361f2898b4e3c299e3687b8b4581b2e6c2b48 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 5 Jan 2026 09:45:06 +0530 Subject: [PATCH 2240/3801] update all cli workflows --- .../crates/proc-macro-api/src/lib.rs | 5 ++--- .../rust-analyzer/src/cli/analysis_stats.rs | 1 + .../rust-analyzer/src/cli/diagnostics.rs | 1 + .../crates/rust-analyzer/src/cli/lsif.rs | 1 + .../rust-analyzer/src/cli/prime_caches.rs | 1 + .../crates/rust-analyzer/src/cli/run_tests.rs | 1 + .../rust-analyzer/src/cli/rustc_tests.rs | 1 + .../crates/rust-analyzer/src/cli/scip.rs | 1 + .../crates/rust-analyzer/src/cli/ssr.rs | 2 ++ .../src/cli/unresolved_references.rs | 1 + .../src/integrated_benchmarks.rs | 3 +++ .../crates/rust-analyzer/src/reload.rs | 20 +++++++++++-------- 12 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index ad462ff31a1b..2c0008ae1d82 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -29,9 +29,7 @@ use std::{fmt, io, sync::Arc, time::SystemTime}; pub use crate::transport::codec::Codec; use crate::{ - bidirectional_protocol::SubCallback, - pool::{ProcMacroServerPool, default_pool_size}, - process::ProcMacroServerProcess, + bidirectional_protocol::SubCallback, pool::ProcMacroServerPool, process::ProcMacroServerProcess, }; /// The versions of the server protocol @@ -155,6 +153,7 @@ impl ProcMacroClient { Item = (impl AsRef, &'a Option>), > + Clone, version: Option<&Version>, + num_process: usize, ) -> io::Result { let process = ProcMacroServerProcess::spawn(process_path, env, version)?; Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() }) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index a02d1a78564f..1995d3889891 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -91,6 +91,7 @@ impl flags::AnalysisStats { } }, prefill_caches: false, + proc_macro_processes: 1, }; let build_scripts_time = if self.disable_build_scripts { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs index 776069f155f0..575c77f8428c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs @@ -41,6 +41,7 @@ impl flags::Diagnostics { load_out_dirs_from_check: !self.disable_build_scripts, with_proc_macro_server, prefill_caches: false, + proc_macro_processes: 1, }; let (db, _vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs index f3b0699d5515..e5e238db6361 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs @@ -293,6 +293,7 @@ impl flags::Lsif { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let path = AbsPathBuf::assert_utf8(env::current_dir()?.join(self.path)); let root = ProjectManifest::discover_single(&path)?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs index 467d8a53884a..d5da6791797b 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs @@ -38,6 +38,7 @@ impl flags::PrimeCaches { // we want to ensure that this command, not `load_workspace_at`, // is responsible for that work. prefill_caches: false, + proc_macro_processes: config.proc_macro_num_processes(), }; let root = AbsPathBuf::assert_utf8(std::env::current_dir()?.join(root)); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs index 82ace8c8b315..d4a56d773e7d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs @@ -23,6 +23,7 @@ impl flags::RunTests { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (ref db, _vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index 249566d2ac16..e8c6c5f4d4f7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -103,6 +103,7 @@ impl Tester { load_out_dirs_from_check: false, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (db, _vfs, _proc_macro) = load_workspace(workspace, &cargo_config.extra_env, &load_cargo_config)?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs index 271d2507bcfe..ed0476697c9c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs @@ -52,6 +52,7 @@ impl flags::Scip { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, + proc_macro_processes: config.proc_macro_num_processes(), }; let cargo_config = config.cargo(None); let (db, vfs, _) = load_workspace_at( diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs index 39186831459c..5c69bda723fb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs @@ -20,6 +20,7 @@ impl flags::Ssr { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (ref db, vfs, _proc_macro) = load_workspace_at( &std::env::current_dir()?, @@ -56,6 +57,7 @@ impl flags::Search { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (ref db, _vfs, _proc_macro) = load_workspace_at( &std::env::current_dir()?, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs index 294add682d01..49c6fcb91ebf 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs @@ -44,6 +44,7 @@ impl flags::UnresolvedReferences { load_out_dirs_from_check: !self.disable_build_scripts, with_proc_macro_server, prefill_caches: false, + proc_macro_processes: config.proc_macro_num_processes(), }; let (db, vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs index c61825b99fec..d16ca2fb48ac 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs @@ -53,6 +53,7 @@ fn integrated_highlighting_benchmark() { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (db, vfs, _proc_macro) = { @@ -121,6 +122,7 @@ fn integrated_completion_benchmark() { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, + proc_macro_processes: 1, }; let (db, vfs, _proc_macro) = { @@ -322,6 +324,7 @@ fn integrated_diagnostics_benchmark() { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, + proc_macro_processes: 1, }; let (db, vfs, _proc_macro) = { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index ccafbd7b30b9..83f4a19b39fa 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -701,15 +701,19 @@ impl GlobalState { _ => Default::default(), }; info!("Using proc-macro server at {path}"); + let num_process = self.config.proc_macro_num_processes(); - Some(ProcMacroClient::spawn(&path, &env, ws.toolchain.as_ref()).map_err(|err| { - tracing::error!( - "Failed to run proc-macro server from path {path}, error: {err:?}", - ); - anyhow::format_err!( - "Failed to run proc-macro server from path {path}, error: {err:?}", - ) - })) + Some( + ProcMacroClient::spawn(&path, &env, ws.toolchain.as_ref(), num_process) + .map_err(|err| { + tracing::error!( + "Failed to run proc-macro server from path {path}, error: {err:?}", + ); + anyhow::format_err!( + "Failed to run proc-macro server from path {path}, error: {err:?}", + ) + }), + ) })) } From 0587cbdd6fc2321564394828d6172fd268fc6617 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 5 Jan 2026 09:56:02 +0530 Subject: [PATCH 2241/3801] optimize pick_process to short circuit and return as early as possible if a valid process is found --- .../crates/proc-macro-api/src/pool.rs | 28 +++++++++++++------ .../crates/rust-analyzer/src/config.rs | 2 +- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs index 0cb505aa40a9..a637bc0e480a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -28,14 +28,26 @@ impl ProcMacroServerPool { } pub(crate) fn pick_process(&self) -> Result<&ProcMacroServerProcess, ServerError> { - self.workers - .iter() - .filter(|w| w.exited().is_none()) - .min_by_key(|w| w.number_of_active_req()) - .ok_or_else(|| ServerError { - message: "all proc-macro server workers have exited".into(), - io: None, - }) + let mut best: Option<&ProcMacroServerProcess> = None; + let mut best_load = u32::MAX; + + for w in self.workers.iter().filter(|w| w.exited().is_none()) { + let load = w.number_of_active_req(); + + if load == 0 { + return Ok(w); + } + + if load < best_load { + best = Some(w); + best_load = load; + } + } + + best.ok_or_else(|| ServerError { + message: "all proc-macro server workers have exited".into(), + io: None, + }) } pub(crate) fn load_dylib( diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index cb6552c32ffb..409f2468a7b1 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -380,7 +380,7 @@ config_data! { /// The number of worker threads in the main loop. The default `null` means to pick /// automatically. numThreads: Option = None, - /// The number of proc-macro-srv processes + /// The number of proc-macro-srv processes proc_macro_processes: NumProcesses = NumProcesses::Concrete(1), /// Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set. From b49417eea9fcb252ffe62d35068375534d553af0 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 5 Jan 2026 10:22:49 +0530 Subject: [PATCH 2242/3801] fix test and update some autogen files --- .../crates/rust-analyzer/src/config.rs | 24 ++++++++++++++++-- .../docs/book/src/configuration_generated.md | 10 ++++++++ .../rust-analyzer/editors/code/package.json | 25 +++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 409f2468a7b1..015e6df96f2f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -380,8 +380,6 @@ config_data! { /// The number of worker threads in the main loop. The default `null` means to pick /// automatically. numThreads: Option = None, - /// The number of proc-macro-srv processes - proc_macro_processes: NumProcesses = NumProcesses::Concrete(1), /// Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set. procMacro_attributes_enable: bool = true, @@ -392,6 +390,12 @@ config_data! { /// Internal config, path to proc-macro server executable. procMacro_server: Option = None, + /// Number of proc-macro server processes to spawn. + /// + /// Controls how many independent `proc-macro-srv` processes rust-analyzer + /// runs in parallel to handle macro expansion. + proc_macro_processes: NumProcesses = NumProcesses::Concrete(1), + /// The path where to save memory profiling output. /// /// **Note:** Memory profiling is not enabled by default in rust-analyzer builds, you need to build @@ -3920,6 +3924,22 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json }, ], }, + "NumProcesses" => set! { + "anyOf": [ + { + "type": "number", + "minimum": 0, + "maximum": 255 + }, + { + "type": "string", + "enum": ["physical"], + "enumDescriptions": [ + "Use the number of physical cores", + ], + }, + ], + }, "Option" => set! { "anyOf": [ { diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index c4124aaae075..d3f41fb152e1 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1325,6 +1325,16 @@ Default: `null` Internal config, path to proc-macro server executable. +## rust-analyzer.proc.macro.processes {#proc.macro.processes} + +Default: `1` + +Number of proc-macro server processes to spawn. + +Controls how many independent `proc-macro-srv` processes rust-analyzer +runs in parallel to handle macro expansion. + + ## rust-analyzer.profiling.memoryProfile {#profiling.memoryProfile} Default: `null` diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 0d91378706a4..a1266c4a67ed 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -2783,6 +2783,31 @@ } } }, + { + "title": "Proc", + "properties": { + "rust-analyzer.proc.macro.processes": { + "markdownDescription": "Number of proc-macro server processes to spawn.\n\nControls how many independent `proc-macro-srv` processes rust-analyzer\nruns in parallel to handle macro expansion.", + "default": 1, + "anyOf": [ + { + "type": "number", + "minimum": 0, + "maximum": 255 + }, + { + "type": "string", + "enum": [ + "physical" + ], + "enumDescriptions": [ + "Use the number of physical cores" + ] + } + ] + } + } + }, { "title": "Profiling", "properties": { From a81da31f4096bf754eed0c40b384ef2f5b4d854c Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 5 Jan 2026 10:32:00 +0530 Subject: [PATCH 2243/3801] rename from proc_macro_processes to procMacro_processes --- .../crates/rust-analyzer/src/config.rs | 10 +++---- .../docs/book/src/configuration_generated.md | 16 +++++------ .../rust-analyzer/editors/code/package.json | 28 +++++++++---------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 015e6df96f2f..98495f6150da 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -387,14 +387,14 @@ config_data! { /// Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`. procMacro_enable: bool = true, - /// Internal config, path to proc-macro server executable. - procMacro_server: Option = None, - /// Number of proc-macro server processes to spawn. /// /// Controls how many independent `proc-macro-srv` processes rust-analyzer /// runs in parallel to handle macro expansion. - proc_macro_processes: NumProcesses = NumProcesses::Concrete(1), + procMacro_processes: NumProcesses = NumProcesses::Concrete(1), + + /// Internal config, path to proc-macro server executable. + procMacro_server: Option = None, /// The path where to save memory profiling output. /// @@ -2648,7 +2648,7 @@ impl Config { } pub fn proc_macro_num_processes(&self) -> usize { - match self.proc_macro_processes() { + match self.procMacro_processes() { NumProcesses::Concrete(0) | NumProcesses::Physical => num_cpus::get_physical(), &NumProcesses::Concrete(n) => n, } diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index d3f41fb152e1..5b1a2e111196 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -1318,14 +1318,7 @@ These proc-macros will be ignored when trying to expand them. This config takes a map of crate names with the exported proc-macro names to ignore as values. -## rust-analyzer.procMacro.server {#procMacro.server} - -Default: `null` - -Internal config, path to proc-macro server executable. - - -## rust-analyzer.proc.macro.processes {#proc.macro.processes} +## rust-analyzer.procMacro.processes {#procMacro.processes} Default: `1` @@ -1335,6 +1328,13 @@ Controls how many independent `proc-macro-srv` processes rust-analyzer runs in parallel to handle macro expansion. +## rust-analyzer.procMacro.server {#procMacro.server} + +Default: `null` + +Internal config, path to proc-macro server executable. + + ## rust-analyzer.profiling.memoryProfile {#profiling.memoryProfile} Default: `null` diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index a1266c4a67ed..406e41767f6d 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -2773,20 +2773,7 @@ { "title": "Proc Macro", "properties": { - "rust-analyzer.procMacro.server": { - "markdownDescription": "Internal config, path to proc-macro server executable.", - "default": null, - "type": [ - "null", - "string" - ] - } - } - }, - { - "title": "Proc", - "properties": { - "rust-analyzer.proc.macro.processes": { + "rust-analyzer.procMacro.processes": { "markdownDescription": "Number of proc-macro server processes to spawn.\n\nControls how many independent `proc-macro-srv` processes rust-analyzer\nruns in parallel to handle macro expansion.", "default": 1, "anyOf": [ @@ -2808,6 +2795,19 @@ } } }, + { + "title": "Proc Macro", + "properties": { + "rust-analyzer.procMacro.server": { + "markdownDescription": "Internal config, path to proc-macro server executable.", + "default": null, + "type": [ + "null", + "string" + ] + } + } + }, { "title": "Profiling", "properties": { From 8da5de0ca02c316fee3fb97c11052e3d70a32bef Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 11 Jan 2026 15:46:03 +0530 Subject: [PATCH 2244/3801] rebased changes --- .../crates/proc-macro-api/src/lib.rs | 26 +++++++++++++++---- .../crates/proc-macro-api/src/process.rs | 13 +++------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 2c0008ae1d82..3acd0b292a31 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -155,8 +155,15 @@ impl ProcMacroClient { version: Option<&Version>, num_process: usize, ) -> io::Result { - let process = ProcMacroServerProcess::spawn(process_path, env, version)?; - Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() }) + let pool_size = num_process; + let mut workers = Vec::with_capacity(pool_size); + for _ in 0..pool_size { + let worker = ProcMacroServerProcess::spawn(process_path, env.clone(), version)?; + workers.push(worker); + } + + let pool = ProcMacroServerPool::new(workers); + Ok(ProcMacroClient { pool: Arc::new(pool), path: process_path.to_owned() }) } /// Invokes `spawn` and returns a client connected to the resulting read and write handles. @@ -170,11 +177,20 @@ impl ProcMacroClient { Box, Box, Box, - )>, + )> + Clone, version: Option<&Version>, + num_process: usize, ) -> io::Result { - let process = ProcMacroServerProcess::run(spawn, version, || "".to_owned())?; - Ok(ProcMacroClient { worker: Arc::new(process), path: process_path.to_owned() }) + let pool_size = num_process; + let mut workers = Vec::with_capacity(pool_size); + for _ in 0..pool_size { + let worker = + ProcMacroServerProcess::run(spawn.clone(), version, || "".to_owned())?; + workers.push(worker); + } + + let pool = ProcMacroServerPool::new(workers); + Ok(ProcMacroClient { pool: Arc::new(pool), path: process_path.to_owned() }) } /// Returns the absolute path to the proc-macro server. diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index c1b95fa7f10e..2f5bef69abd5 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -210,9 +210,8 @@ impl ProcMacroServerProcess { callback: Option>, ) -> Result, String>, ServerError> { match self.protocol { - Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { - legacy_protocol::find_proc_macros(self, dylib_path) - } + Protocol::LegacyJson { .. } => legacy_protocol::find_proc_macros(self, dylib_path), + Protocol::BidirectionalPostcardPrototype { .. } => { let cb = callback.expect("callback required for bidirectional protocol"); bidirectional_protocol::find_proc_macros(self, dylib_path, cb) @@ -279,7 +278,7 @@ impl ProcMacroServerProcess { let result = match self.protocol { Protocol::LegacyJson { .. } => legacy_protocol::expand( proc_macro, - self, + self, subtree, attr, env, @@ -344,11 +343,7 @@ impl ProcMacroServerProcess { match state.process.exit_err() { None => e, Some(server_error) => { - proc_macro_worker - .get_exited() - .get_or_init(|| AssertUnwindSafe(server_error)) - .0 - .clone() + self.exited.get_or_init(|| AssertUnwindSafe(server_error)).0.clone() } } } else { From b7e4315b3287ba27cbaf396a0f3d7baf7c237ecd Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 15 Jan 2026 20:35:35 +0100 Subject: [PATCH 2245/3801] Do not output an error if standard output is full on --help/--version This matches rustc's behavior. --- src/driver.rs | 13 ++++++++----- src/main.rs | 17 +++++++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/driver.rs b/src/driver.rs index 8693973ef78c..6094c8445398 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -32,11 +32,10 @@ use rustc_span::symbol::Symbol; use std::env; use std::fs::read_to_string; +use std::io::Write as _; use std::path::Path; use std::process::exit; -use anstream::println; - /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If /// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`. fn arg_value<'a>(args: &'a [String], find_arg: &str, pred: impl Fn(&str) -> bool) -> Option<&'a str> { @@ -186,7 +185,9 @@ impl rustc_driver::Callbacks for ClippyCallbacks { } fn display_help() { - println!("{}", help_message()); + if writeln!(&mut anstream::stdout().lock(), "{}", help_message()).is_err() { + exit(rustc_driver::EXIT_FAILURE); + } } const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml"; @@ -253,8 +254,10 @@ pub fn main() { if orig_args.iter().any(|a| a == "--version" || a == "-V") { let version_info = rustc_tools_util::get_version_info!(); - println!("{version_info}"); - exit(0); + match writeln!(&mut anstream::stdout().lock(), "{version_info}") { + Ok(()) => exit(rustc_driver::EXIT_SUCCESS), + Err(_) => exit(rustc_driver::EXIT_FAILURE), + } } // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument. diff --git a/src/main.rs b/src/main.rs index 688161c7bfcb..98b888444831 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,19 +4,24 @@ // warn on lints, that are included in `rust-lang/rust`s bootstrap #![warn(rust_2018_idioms, unused_lifetimes)] -use std::env; -use std::path::PathBuf; -use std::process::{self, Command}; +extern crate rustc_driver; -use anstream::println; +use std::env; +use std::io::Write as _; +use std::path::PathBuf; +use std::process::{self, Command, exit}; fn show_help() { - println!("{}", help_message()); + if writeln!(&mut anstream::stdout().lock(), "{}", help_message()).is_err() { + exit(rustc_driver::EXIT_FAILURE); + } } fn show_version() { let version_info = rustc_tools_util::get_version_info!(); - println!("{version_info}"); + if writeln!(&mut anstream::stdout().lock(), "{version_info}").is_err() { + exit(rustc_driver::EXIT_FAILURE); + } } pub fn main() { From bad82f22a9f1e1972fb5000e5e1c03fc3281aa7a Mon Sep 17 00:00:00 2001 From: tuturuu Date: Fri, 16 Jan 2026 17:51:43 +0100 Subject: [PATCH 2246/3801] move tests --- .../elided-self-lifetime-in-trait-fn.rs} | 0 .../elided-self-lifetime-in-trait-fn.stderr} | 2 +- .../struct_pattern_on_tuple_enum_in_match.rs} | 0 .../struct_pattern_on_tuple_enum_in_match.stderr} | 2 +- .../trait_more_private_than_item.rs} | 0 .../trait_more_private_than_item.stderr} | 4 ++-- .../{issues/issue-18119.rs => resolve/impl-on-non-type.rs} | 0 .../issue-18119.stderr => resolve/impl-on-non-type.stderr} | 6 +++--- .../issue-17994.rs => type-alias/unused_type_parameter.rs} | 0 .../unused_type_parameter.stderr} | 2 +- 10 files changed, 8 insertions(+), 8 deletions(-) rename tests/ui/{issues/issue-16683.rs => lifetimes/elided-self-lifetime-in-trait-fn.rs} (100%) rename tests/ui/{issues/issue-16683.stderr => lifetimes/elided-self-lifetime-in-trait-fn.stderr} (87%) rename tests/ui/{issues/issue-17405.rs => mismatched_types/struct_pattern_on_tuple_enum_in_match.rs} (100%) rename tests/ui/{issues/issue-17405.stderr => mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr} (82%) rename tests/ui/{issues/issue-18389.rs => privacy/trait_more_private_than_item.rs} (100%) rename tests/ui/{issues/issue-18389.stderr => privacy/trait_more_private_than_item.stderr} (85%) rename tests/ui/{issues/issue-18119.rs => resolve/impl-on-non-type.rs} (100%) rename tests/ui/{issues/issue-18119.stderr => resolve/impl-on-non-type.stderr} (78%) rename tests/ui/{issues/issue-17994.rs => type-alias/unused_type_parameter.rs} (100%) rename tests/ui/{issues/issue-17994.stderr => type-alias/unused_type_parameter.stderr} (88%) diff --git a/tests/ui/issues/issue-16683.rs b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs similarity index 100% rename from tests/ui/issues/issue-16683.rs rename to tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs diff --git a/tests/ui/issues/issue-16683.stderr b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr similarity index 87% rename from tests/ui/issues/issue-16683.stderr rename to tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr index 39b22ed1f156..127f1ab99457 100644 --- a/tests/ui/issues/issue-16683.stderr +++ b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-16683.rs:4:9 + --> $DIR/elided-self-lifetime-in-trait-fn.rs:4:9 | LL | trait T<'a> { | -- lifetime `'a` defined here diff --git a/tests/ui/issues/issue-17405.rs b/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.rs similarity index 100% rename from tests/ui/issues/issue-17405.rs rename to tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.rs diff --git a/tests/ui/issues/issue-17405.stderr b/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr similarity index 82% rename from tests/ui/issues/issue-17405.stderr rename to tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr index 47f5bf4dc330..52da5c9b9cb3 100644 --- a/tests/ui/issues/issue-17405.stderr +++ b/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr @@ -1,5 +1,5 @@ error[E0574]: expected struct, variant or union type, found enum `Foo` - --> $DIR/issue-17405.rs:7:9 + --> $DIR/struct_pattern_on_tuple_enum_in_match.rs:7:9 | LL | Foo { i } => () | ^^^ not a struct, variant or union type diff --git a/tests/ui/issues/issue-18389.rs b/tests/ui/privacy/trait_more_private_than_item.rs similarity index 100% rename from tests/ui/issues/issue-18389.rs rename to tests/ui/privacy/trait_more_private_than_item.rs diff --git a/tests/ui/issues/issue-18389.stderr b/tests/ui/privacy/trait_more_private_than_item.stderr similarity index 85% rename from tests/ui/issues/issue-18389.stderr rename to tests/ui/privacy/trait_more_private_than_item.stderr index 4706d1ba1779..7ec3a1030599 100644 --- a/tests/ui/issues/issue-18389.stderr +++ b/tests/ui/privacy/trait_more_private_than_item.stderr @@ -1,5 +1,5 @@ warning: trait `Private<::P, ::R>` is more private than the item `Public` - --> $DIR/issue-18389.rs:9:1 + --> $DIR/trait_more_private_than_item.rs:9:1 | LL | / pub trait Public: Private< LL | | @@ -9,7 +9,7 @@ LL | | > { | |_^ trait `Public` is reachable at visibility `pub` | note: but trait `Private<::P, ::R>` is only usable at visibility `pub(crate)` - --> $DIR/issue-18389.rs:6:1 + --> $DIR/trait_more_private_than_item.rs:6:1 | LL | trait Private { | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-18119.rs b/tests/ui/resolve/impl-on-non-type.rs similarity index 100% rename from tests/ui/issues/issue-18119.rs rename to tests/ui/resolve/impl-on-non-type.rs diff --git a/tests/ui/issues/issue-18119.stderr b/tests/ui/resolve/impl-on-non-type.stderr similarity index 78% rename from tests/ui/issues/issue-18119.stderr rename to tests/ui/resolve/impl-on-non-type.stderr index ddee5a9da7a4..e29ac90b297c 100644 --- a/tests/ui/issues/issue-18119.stderr +++ b/tests/ui/resolve/impl-on-non-type.stderr @@ -1,17 +1,17 @@ error[E0573]: expected type, found constant `X` - --> $DIR/issue-18119.rs:5:6 + --> $DIR/impl-on-non-type.rs:5:6 | LL | impl X {} | ^ not a type error[E0573]: expected type, found static `Y` - --> $DIR/issue-18119.rs:7:6 + --> $DIR/impl-on-non-type.rs:7:6 | LL | impl Y {} | ^ not a type error[E0573]: expected type, found function `foo` - --> $DIR/issue-18119.rs:9:6 + --> $DIR/impl-on-non-type.rs:9:6 | LL | impl foo {} | ^^^ not a type diff --git a/tests/ui/issues/issue-17994.rs b/tests/ui/type-alias/unused_type_parameter.rs similarity index 100% rename from tests/ui/issues/issue-17994.rs rename to tests/ui/type-alias/unused_type_parameter.rs diff --git a/tests/ui/issues/issue-17994.stderr b/tests/ui/type-alias/unused_type_parameter.stderr similarity index 88% rename from tests/ui/issues/issue-17994.stderr rename to tests/ui/type-alias/unused_type_parameter.stderr index f149e5d08faa..4c9f356ebbee 100644 --- a/tests/ui/issues/issue-17994.stderr +++ b/tests/ui/type-alias/unused_type_parameter.stderr @@ -1,5 +1,5 @@ error[E0091]: type parameter `T` is never used - --> $DIR/issue-17994.rs:2:10 + --> $DIR/unused_type_parameter.rs:2:10 | LL | type Huh where T: Tr = isize; | ^ unused type parameter From 9d1a1ae298f47bbc319ae5ea8c5e6164e9ad8a46 Mon Sep 17 00:00:00 2001 From: tuturuu Date: Fri, 16 Jan 2026 18:15:09 +0100 Subject: [PATCH 2247/3801] add tests metadata, regenerate stderr --- tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs | 1 + tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr | 2 +- .../struct_pattern_on_tuple_enum_in_match.rs | 1 + .../struct_pattern_on_tuple_enum_in_match.stderr | 2 +- tests/ui/privacy/trait_more_private_than_item.rs | 1 + tests/ui/privacy/trait_more_private_than_item.stderr | 4 ++-- tests/ui/resolve/impl-on-non-type.rs | 1 + tests/ui/resolve/impl-on-non-type.stderr | 6 +++--- tests/ui/type-alias/unused_type_parameter.rs | 1 + tests/ui/type-alias/unused_type_parameter.stderr | 2 +- 10 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs index 72fa21bddd18..5ac39c6f5d9b 100644 --- a/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs +++ b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs @@ -1,3 +1,4 @@ +//! regression test for trait T<'a> { fn a(&'a self) -> &'a bool; fn b(&self) { diff --git a/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr index 127f1ab99457..383afaf782f9 100644 --- a/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr +++ b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/elided-self-lifetime-in-trait-fn.rs:4:9 + --> $DIR/elided-self-lifetime-in-trait-fn.rs:5:9 | LL | trait T<'a> { | -- lifetime `'a` defined here diff --git a/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.rs b/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.rs index 14781a7d3f7e..a82778841939 100644 --- a/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.rs +++ b/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.rs @@ -1,3 +1,4 @@ +//! regression test for enum Foo { Bar(isize) } diff --git a/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr b/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr index 52da5c9b9cb3..c9cc1580b480 100644 --- a/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr +++ b/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr @@ -1,5 +1,5 @@ error[E0574]: expected struct, variant or union type, found enum `Foo` - --> $DIR/struct_pattern_on_tuple_enum_in_match.rs:7:9 + --> $DIR/struct_pattern_on_tuple_enum_in_match.rs:8:9 | LL | Foo { i } => () | ^^^ not a struct, variant or union type diff --git a/tests/ui/privacy/trait_more_private_than_item.rs b/tests/ui/privacy/trait_more_private_than_item.rs index 0ab3f1454572..f55a494abd21 100644 --- a/tests/ui/privacy/trait_more_private_than_item.rs +++ b/tests/ui/privacy/trait_more_private_than_item.rs @@ -1,3 +1,4 @@ +//! regression test for //@ check-pass use std::any::Any; diff --git a/tests/ui/privacy/trait_more_private_than_item.stderr b/tests/ui/privacy/trait_more_private_than_item.stderr index 7ec3a1030599..03bffcd390c5 100644 --- a/tests/ui/privacy/trait_more_private_than_item.stderr +++ b/tests/ui/privacy/trait_more_private_than_item.stderr @@ -1,5 +1,5 @@ warning: trait `Private<::P, ::R>` is more private than the item `Public` - --> $DIR/trait_more_private_than_item.rs:9:1 + --> $DIR/trait_more_private_than_item.rs:10:1 | LL | / pub trait Public: Private< LL | | @@ -9,7 +9,7 @@ LL | | > { | |_^ trait `Public` is reachable at visibility `pub` | note: but trait `Private<::P, ::R>` is only usable at visibility `pub(crate)` - --> $DIR/trait_more_private_than_item.rs:6:1 + --> $DIR/trait_more_private_than_item.rs:7:1 | LL | trait Private { | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/resolve/impl-on-non-type.rs b/tests/ui/resolve/impl-on-non-type.rs index e48dc51a2c64..3db13d520f9f 100644 --- a/tests/ui/resolve/impl-on-non-type.rs +++ b/tests/ui/resolve/impl-on-non-type.rs @@ -1,3 +1,4 @@ +//! regression test for const X: u8 = 1; static Y: u8 = 1; fn foo() {} diff --git a/tests/ui/resolve/impl-on-non-type.stderr b/tests/ui/resolve/impl-on-non-type.stderr index e29ac90b297c..99cc405015b5 100644 --- a/tests/ui/resolve/impl-on-non-type.stderr +++ b/tests/ui/resolve/impl-on-non-type.stderr @@ -1,17 +1,17 @@ error[E0573]: expected type, found constant `X` - --> $DIR/impl-on-non-type.rs:5:6 + --> $DIR/impl-on-non-type.rs:6:6 | LL | impl X {} | ^ not a type error[E0573]: expected type, found static `Y` - --> $DIR/impl-on-non-type.rs:7:6 + --> $DIR/impl-on-non-type.rs:8:6 | LL | impl Y {} | ^ not a type error[E0573]: expected type, found function `foo` - --> $DIR/impl-on-non-type.rs:9:6 + --> $DIR/impl-on-non-type.rs:10:6 | LL | impl foo {} | ^^^ not a type diff --git a/tests/ui/type-alias/unused_type_parameter.rs b/tests/ui/type-alias/unused_type_parameter.rs index ab37a172eaa7..64fb98be1bf7 100644 --- a/tests/ui/type-alias/unused_type_parameter.rs +++ b/tests/ui/type-alias/unused_type_parameter.rs @@ -1,3 +1,4 @@ +//! regression test for trait Tr {} type Huh where T: Tr = isize; //~ ERROR type parameter `T` is never used fn main() {} diff --git a/tests/ui/type-alias/unused_type_parameter.stderr b/tests/ui/type-alias/unused_type_parameter.stderr index 4c9f356ebbee..a9ddbc8c5001 100644 --- a/tests/ui/type-alias/unused_type_parameter.stderr +++ b/tests/ui/type-alias/unused_type_parameter.stderr @@ -1,5 +1,5 @@ error[E0091]: type parameter `T` is never used - --> $DIR/unused_type_parameter.rs:2:10 + --> $DIR/unused_type_parameter.rs:3:10 | LL | type Huh where T: Tr = isize; | ^ unused type parameter From 4530e26f4eec47b92061d9ab3fca18ed8db97e63 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Fri, 16 Jan 2026 17:47:42 +0100 Subject: [PATCH 2248/3801] compiletest: Add `AuxCrate` struct with docs. To make the code clearer. --- src/tools/compiletest/src/directives.rs | 2 +- .../compiletest/src/directives/auxiliary.rs | 24 +++++++++++++------ src/tools/compiletest/src/runtest.rs | 8 +++---- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 624f4dd7c2b1..0263b91f50b8 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -8,8 +8,8 @@ use tracing::*; use crate::common::{CodegenBackend, Config, Debugger, FailMode, PassMode, RunFailMode, TestMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; -pub(crate) use crate::directives::auxiliary::AuxProps; use crate::directives::auxiliary::parse_and_update_aux; +pub(crate) use crate::directives::auxiliary::{AuxCrate, AuxProps}; use crate::directives::directive_names::{ KNOWN_DIRECTIVE_NAMES_SET, KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, KNOWN_JSONDOCCK_DIRECTIVE_NAMES, }; diff --git a/src/tools/compiletest/src/directives/auxiliary.rs b/src/tools/compiletest/src/directives/auxiliary.rs index 40e2e7049c8f..1b72931949c5 100644 --- a/src/tools/compiletest/src/directives/auxiliary.rs +++ b/src/tools/compiletest/src/directives/auxiliary.rs @@ -7,6 +7,16 @@ use super::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC use crate::common::Config; use crate::directives::DirectiveLine; +/// The value of an `aux-crate` directive. +#[derive(Clone, Debug, Default)] +pub struct AuxCrate { + /// With `aux-crate: foo=bar.rs` this will be `foo`. + /// With `aux-crate: noprelude:foo=bar.rs` this will be `noprelude:foo`. + pub name: String, + /// With `aux-crate: foo=bar.rs` this will be `bar.rs`. + pub path: String, +} + /// Properties parsed from `aux-*` test directives. #[derive(Clone, Debug, Default)] pub(crate) struct AuxProps { @@ -17,7 +27,7 @@ pub(crate) struct AuxProps { pub(crate) bins: Vec, /// Similar to `builds`, but a list of NAME=somelib.rs of dependencies /// to build and pass with the `--extern` flag. - pub(crate) crates: Vec<(String, String)>, + pub(crate) crates: Vec, /// Same as `builds`, but for proc-macros. pub(crate) proc_macros: Vec, /// Similar to `builds`, but also uses the resulting dylib as a @@ -34,7 +44,7 @@ impl AuxProps { iter::empty() .chain(builds.iter().map(String::as_str)) .chain(bins.iter().map(String::as_str)) - .chain(crates.iter().map(|(_, path)| path.as_str())) + .chain(crates.iter().map(|c| c.path.as_str())) .chain(proc_macros.iter().map(String::as_str)) .chain(codegen_backend.iter().map(String::as_str)) } @@ -63,10 +73,10 @@ pub(super) fn parse_and_update_aux( } } -fn parse_aux_crate(r: String) -> (String, String) { +fn parse_aux_crate(r: String) -> AuxCrate { let mut parts = r.trim().splitn(2, '='); - ( - parts.next().expect("missing aux-crate name (e.g. log=log.rs)").to_string(), - parts.next().expect("missing aux-crate value (e.g. log=log.rs)").to_string(), - ) + AuxCrate { + name: parts.next().expect("missing aux-crate name (e.g. log=log.rs)").to_string(), + path: parts.next().expect("missing aux-crate value (e.g. log=log.rs)").to_string(), + } } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 6efdb5a99ee2..901ce8421ebf 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -18,7 +18,7 @@ use crate::common::{ TestSuite, UI_EXTENSIONS, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT, UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, expected_output_path, incremental_dir, output_base_dir, output_base_name, }; -use crate::directives::TestProps; +use crate::directives::{AuxCrate, TestProps}; use crate::errors::{Error, ErrorKind, load_errors}; use crate::output_capture::ConsoleOut; use crate::read2::{Truncated, read2_abbreviated}; @@ -1285,9 +1285,9 @@ impl<'test> TestCx<'test> { } }; - for (aux_name, aux_path) in &self.props.aux.crates { - let aux_type = self.build_auxiliary(&aux_path, &aux_dir, None); - add_extern(rustc, aux_name, aux_path, aux_type); + for AuxCrate { name, path } in &self.props.aux.crates { + let aux_type = self.build_auxiliary(&path, &aux_dir, None); + add_extern(rustc, name, path, aux_type); } for proc_macro in &self.props.aux.proc_macros { From 2177aa9ac736b0c16c8ad73230508fcb273b980e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 16 Jan 2026 18:09:37 +0100 Subject: [PATCH 2249/3801] Manually include intrinsic conversion that is not present in LLVM files --- src/intrinsic/old_archs.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/intrinsic/old_archs.rs b/src/intrinsic/old_archs.rs index 3a59707b2ebe..8d3e3487b5cb 100644 --- a/src/intrinsic/old_archs.rs +++ b/src/intrinsic/old_archs.rs @@ -242,6 +242,8 @@ pub(crate) fn old_archs(arch: &str, name: &str) -> ArchCheckResult { "avx.cvt.ps2.pd.256" => "__builtin_ia32_cvtps2pd256", "avx.cvtdq2.pd.256" => "__builtin_ia32_cvtdq2pd256", "avx.cvtdq2.ps.256" => "__builtin_ia32_cvtdq2ps256", + "avx.round.pd.256" => "__builtin_ia32_roundpd256", + "avx.round.ps.256" => "__builtin_ia32_roundps256", "avx.sqrt.pd.256" => "__builtin_ia32_sqrtpd256", "avx.sqrt.ps.256" => "__builtin_ia32_sqrtps256", "avx.storeu.dq.256" => "__builtin_ia32_storedqu256", @@ -1352,6 +1354,10 @@ pub(crate) fn old_archs(arch: &str, name: &str) -> ArchCheckResult { "sse41.pmovzxwd" => "__builtin_ia32_pmovzxwd128", "sse41.pmovzxwq" => "__builtin_ia32_pmovzxwq128", "sse41.pmuldq" => "__builtin_ia32_pmuldq128", + "sse41.round.pd" => "__builtin_ia32_roundpd", + "sse41.round.ps" => "__builtin_ia32_roundps", + "sse41.round.sd" => "__builtin_ia32_roundsd", + "sse41.round.ss" => "__builtin_ia32_roundss", "sse4a.movnt.sd" => "__builtin_ia32_movntsd", "sse4a.movnt.ss" => "__builtin_ia32_movntss", "ssse3.pabs.b.128" => "__builtin_ia32_pabsb128", From b323651ded6429a4205af1de65af01503dfe59eb Mon Sep 17 00:00:00 2001 From: tuturuu Date: Fri, 16 Jan 2026 20:55:37 +0100 Subject: [PATCH 2250/3801] move struct_pattern_on_tuple_enum to ui/pattern --- .../struct_pattern_on_tuple_enum.rs} | 0 .../struct_pattern_on_tuple_enum.stderr} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/ui/{mismatched_types/struct_pattern_on_tuple_enum_in_match.rs => pattern/struct_pattern_on_tuple_enum.rs} (100%) rename tests/ui/{mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr => pattern/struct_pattern_on_tuple_enum.stderr} (82%) diff --git a/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.rs b/tests/ui/pattern/struct_pattern_on_tuple_enum.rs similarity index 100% rename from tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.rs rename to tests/ui/pattern/struct_pattern_on_tuple_enum.rs diff --git a/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr b/tests/ui/pattern/struct_pattern_on_tuple_enum.stderr similarity index 82% rename from tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr rename to tests/ui/pattern/struct_pattern_on_tuple_enum.stderr index c9cc1580b480..a322b363aa9c 100644 --- a/tests/ui/mismatched_types/struct_pattern_on_tuple_enum_in_match.stderr +++ b/tests/ui/pattern/struct_pattern_on_tuple_enum.stderr @@ -1,5 +1,5 @@ error[E0574]: expected struct, variant or union type, found enum `Foo` - --> $DIR/struct_pattern_on_tuple_enum_in_match.rs:8:9 + --> $DIR/struct_pattern_on_tuple_enum.rs:8:9 | LL | Foo { i } => () | ^^^ not a struct, variant or union type From 5c85d522d0083bee0d5fd7f26868fa0e62372485 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 13 Jan 2026 09:52:36 -0800 Subject: [PATCH 2251/3801] Generate global openmp metadata to trigger llvm openmp-opt pass --- compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs | 4 ++++ tests/codegen-llvm/gpu_offload/gpu_host.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index b8eb4f038216..084d40317ba8 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -55,6 +55,10 @@ impl<'ll> OffloadGlobals<'ll> { let init_ty = cx.type_func(&[], cx.type_void()); let init_rtls = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); + // We want LLVM's openmp-opt pass to pick up and optimize this module, since it covers both + // openmp and offload optimizations. + llvm::add_module_flag_u32(cx.llmod(), llvm::ModuleFlagMergeBehavior::Max, "openmp", 51); + OffloadGlobals { launcher_fn, launcher_ty, diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index dcbd65b14427..27ff6f325aa0 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -104,3 +104,5 @@ pub fn _kernel_1(x: &mut [f32; 256]) { // CHECK-NEXT: call void @__tgt_unregister_lib(ptr nonnull %EmptyDesc) // CHECK-NEXT: ret void // CHECK-NEXT: } + +// CHECK: !{i32 7, !"openmp", i32 51} From c9bbf951c22fff8a9c1bc4cfc4c04b43bd0fe431 Mon Sep 17 00:00:00 2001 From: linshuy2 Date: Fri, 16 Jan 2026 20:22:33 +0000 Subject: [PATCH 2252/3801] Allow `unnecessary_sort_by` to lint closures with input patterns --- .../src/methods/unnecessary_sort_by.rs | 288 +++++++++++++----- clippy_utils/src/ty/mod.rs | 15 + tests/ui/unnecessary_sort_by.fixed | 32 ++ tests/ui/unnecessary_sort_by.rs | 32 ++ tests/ui/unnecessary_sort_by.stderr | 44 ++- 5 files changed, 341 insertions(+), 70 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs index c7339a3bdd05..ac13fc0b6850 100644 --- a/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -1,42 +1,51 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; +use clippy_utils::source::snippet_with_applicability; use clippy_utils::std_or_core; use clippy_utils::sugg::Sugg; -use clippy_utils::ty::{implements_trait, is_copy}; +use clippy_utils::ty::{implements_trait, is_copy, peel_n_ty_refs}; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath}; use rustc_lint::LateContext; use rustc_middle::ty::{self, GenericArgKind, Ty}; -use rustc_span::sym; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::Ident; +use rustc_span::{Span, sym}; use std::iter; +use std::ops::Not; use super::UNNECESSARY_SORT_BY; -enum LintTrigger<'tcx> { +enum LintTrigger { Sort, - SortByKey(SortByKeyDetection<'tcx>), + SortByKey(SortByKeyDetection), } -struct SortByKeyDetection<'tcx> { - closure_arg: Symbol, - closure_body: &'tcx Expr<'tcx>, +struct SortByKeyDetection { + closure_arg: Span, + closure_body: String, reverse: bool, + applicability: Applicability, } /// Detect if the two expressions are mirrored (identical, except one /// contains a and the other replaces it with b) -fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: Ident, b_expr: &Expr<'_>, b_ident: Ident) -> bool { +fn mirrored_exprs( + a_expr: &Expr<'_>, + b_expr: &Expr<'_>, + binding_map: &BindingMap, + binding_source: BindingSource, +) -> bool { match (a_expr.kind, b_expr.kind) { // Two arrays with mirrored contents - (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => { - iter::zip(left_exprs, right_exprs).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) - }, + (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => iter::zip(left_exprs, right_exprs) + .all(|(left, right)| mirrored_exprs(left, right, binding_map, binding_source)), // The two exprs are function calls. // Check to see that the function itself and its arguments are mirrored (ExprKind::Call(left_expr, left_args), ExprKind::Call(right_expr, right_args)) => { - mirrored_exprs(left_expr, a_ident, right_expr, b_ident) - && iter::zip(left_args, right_args).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) + mirrored_exprs(left_expr, right_expr, binding_map, binding_source) + && iter::zip(left_args, right_args) + .all(|(left, right)| mirrored_exprs(left, right, binding_map, binding_source)) }, // The two exprs are method calls. // Check to see that the function is the same and the arguments and receivers are mirrored @@ -45,31 +54,31 @@ fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: Ident, b_expr: &Expr<'_>, b_ident: ExprKind::MethodCall(right_segment, right_receiver, right_args, _), ) => { left_segment.ident == right_segment.ident - && iter::zip(left_args, right_args).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) - && mirrored_exprs(left_receiver, a_ident, right_receiver, b_ident) + && iter::zip(left_args, right_args) + .all(|(left, right)| mirrored_exprs(left, right, binding_map, binding_source)) + && mirrored_exprs(left_receiver, right_receiver, binding_map, binding_source) }, // Two tuples with mirrored contents - (ExprKind::Tup(left_exprs), ExprKind::Tup(right_exprs)) => { - iter::zip(left_exprs, right_exprs).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) - }, + (ExprKind::Tup(left_exprs), ExprKind::Tup(right_exprs)) => iter::zip(left_exprs, right_exprs) + .all(|(left, right)| mirrored_exprs(left, right, binding_map, binding_source)), // Two binary ops, which are the same operation and which have mirrored arguments (ExprKind::Binary(left_op, left_left, left_right), ExprKind::Binary(right_op, right_left, right_right)) => { left_op.node == right_op.node - && mirrored_exprs(left_left, a_ident, right_left, b_ident) - && mirrored_exprs(left_right, a_ident, right_right, b_ident) + && mirrored_exprs(left_left, right_left, binding_map, binding_source) + && mirrored_exprs(left_right, right_right, binding_map, binding_source) }, // Two unary ops, which are the same operation and which have the same argument (ExprKind::Unary(left_op, left_expr), ExprKind::Unary(right_op, right_expr)) => { - left_op == right_op && mirrored_exprs(left_expr, a_ident, right_expr, b_ident) + left_op == right_op && mirrored_exprs(left_expr, right_expr, binding_map, binding_source) }, // The two exprs are literals of some kind (ExprKind::Lit(left_lit), ExprKind::Lit(right_lit)) => left_lit.node == right_lit.node, - (ExprKind::Cast(left, _), ExprKind::Cast(right, _)) => mirrored_exprs(left, a_ident, right, b_ident), + (ExprKind::Cast(left, _), ExprKind::Cast(right, _)) => mirrored_exprs(left, right, binding_map, binding_source), (ExprKind::DropTemps(left_block), ExprKind::DropTemps(right_block)) => { - mirrored_exprs(left_block, a_ident, right_block, b_ident) + mirrored_exprs(left_block, right_block, binding_map, binding_source) }, (ExprKind::Field(left_expr, left_ident), ExprKind::Field(right_expr, right_ident)) => { - left_ident.name == right_ident.name && mirrored_exprs(left_expr, a_ident, right_expr, b_ident) + left_ident.name == right_ident.name && mirrored_exprs(left_expr, right_expr, binding_map, binding_source) }, // Two paths: either one is a and the other is b, or they're identical to each other ( @@ -89,60 +98,174 @@ fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: Ident, b_expr: &Expr<'_>, b_ident: )), ) => { (iter::zip(left_segments, right_segments).all(|(left, right)| left.ident == right.ident) - && left_segments - .iter() - .all(|seg| seg.ident != a_ident && seg.ident != b_ident)) + && left_segments.iter().all(|seg| { + !binding_map.contains_key(&BindingKey { + ident: seg.ident, + source: BindingSource::Left, + }) && !binding_map.contains_key(&BindingKey { + ident: seg.ident, + source: BindingSource::Right, + }) + })) || (left_segments.len() == 1 - && left_segments[0].ident == a_ident && right_segments.len() == 1 - && right_segments[0].ident == b_ident) + && binding_map + .get(&BindingKey { + ident: left_segments[0].ident, + source: binding_source, + }) + .is_some_and(|value| value.mirrored.ident == right_segments[0].ident)) }, // Matching expressions, but one or both is borrowed ( ExprKind::AddrOf(left_kind, Mutability::Not, left_expr), ExprKind::AddrOf(right_kind, Mutability::Not, right_expr), - ) => left_kind == right_kind && mirrored_exprs(left_expr, a_ident, right_expr, b_ident), - (_, ExprKind::AddrOf(_, Mutability::Not, right_expr)) => mirrored_exprs(a_expr, a_ident, right_expr, b_ident), - (ExprKind::AddrOf(_, Mutability::Not, left_expr), _) => mirrored_exprs(left_expr, a_ident, b_expr, b_ident), + ) => left_kind == right_kind && mirrored_exprs(left_expr, right_expr, binding_map, binding_source), + (_, ExprKind::AddrOf(_, Mutability::Not, right_expr)) => { + mirrored_exprs(a_expr, right_expr, binding_map, binding_source) + }, + (ExprKind::AddrOf(_, Mutability::Not, left_expr), _) => { + mirrored_exprs(left_expr, b_expr, binding_map, binding_source) + }, _ => false, } } -fn detect_lint<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, arg: &Expr<'_>) -> Option> { +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +enum BindingSource { + Left, + Right, +} + +impl Not for BindingSource { + type Output = BindingSource; + + fn not(self) -> Self::Output { + match self { + BindingSource::Left => BindingSource::Right, + BindingSource::Right => BindingSource::Left, + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +struct BindingKey { + /// The identifier of the binding. + ident: Ident, + /// The source of the binding. + source: BindingSource, +} + +struct BindingValue { + /// The mirrored binding. + mirrored: BindingKey, + /// The number of refs the binding is wrapped in. + n_refs: usize, +} + +/// A map from binding info to the number of refs the binding is wrapped in. +type BindingMap = FxHashMap; +/// Extract the binding pairs, if the two patterns are mirrored. The pats are assumed to be used in +/// closure inputs and thus irrefutable. +fn mapping_of_mirrored_pats(a_pat: &Pat<'_>, b_pat: &Pat<'_>) -> Option { + fn mapping_of_mirrored_pats_inner( + a_pat: &Pat<'_>, + b_pat: &Pat<'_>, + mapping: &mut BindingMap, + n_refs: usize, + ) -> bool { + match (&a_pat.kind, &b_pat.kind) { + (PatKind::Tuple(a_pats, a_dots), PatKind::Tuple(b_pats, b_dots)) => { + a_dots == b_dots + && a_pats.len() == b_pats.len() + && iter::zip(a_pats.iter(), b_pats.iter()) + .all(|(a, b)| mapping_of_mirrored_pats_inner(a, b, mapping, n_refs)) + }, + (PatKind::Binding(_, _, a_ident, _), PatKind::Binding(_, _, b_ident, _)) => { + let a_key = BindingKey { + ident: *a_ident, + source: BindingSource::Left, + }; + let b_key = BindingKey { + ident: *b_ident, + source: BindingSource::Right, + }; + let a_value = BindingValue { + mirrored: b_key, + n_refs, + }; + let b_value = BindingValue { + mirrored: a_key, + n_refs, + }; + mapping.insert(a_key, a_value); + mapping.insert(b_key, b_value); + true + }, + (PatKind::Wild, PatKind::Wild) => true, + (PatKind::TupleStruct(_, a_pats, a_dots), PatKind::TupleStruct(_, b_pats, b_dots)) => { + a_dots == b_dots + && a_pats.len() == b_pats.len() + && iter::zip(a_pats.iter(), b_pats.iter()) + .all(|(a, b)| mapping_of_mirrored_pats_inner(a, b, mapping, n_refs)) + }, + (PatKind::Struct(_, a_fields, a_rest), PatKind::Struct(_, b_fields, b_rest)) => { + a_rest == b_rest + && a_fields.len() == b_fields.len() + && iter::zip(a_fields.iter(), b_fields.iter()).all(|(a_field, b_field)| { + a_field.ident == b_field.ident + && mapping_of_mirrored_pats_inner(a_field.pat, b_field.pat, mapping, n_refs) + }) + }, + (PatKind::Ref(a_inner, _, _), PatKind::Ref(b_inner, _, _)) => { + mapping_of_mirrored_pats_inner(a_inner, b_inner, mapping, n_refs + 1) + }, + (PatKind::Slice(a_elems, None, a_rest), PatKind::Slice(b_elems, None, b_rest)) => { + a_elems.len() == b_elems.len() + && iter::zip(a_elems.iter(), b_elems.iter()) + .all(|(a, b)| mapping_of_mirrored_pats_inner(a, b, mapping, n_refs)) + && a_rest.len() == b_rest.len() + && iter::zip(a_rest.iter(), b_rest.iter()) + .all(|(a, b)| mapping_of_mirrored_pats_inner(a, b, mapping, n_refs)) + }, + _ => false, + } + } + + let mut mapping = FxHashMap::default(); + if mapping_of_mirrored_pats_inner(a_pat, b_pat, &mut mapping, 0) { + return Some(mapping); + } + + None +} + +fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>) -> Option { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) && cx.tcx.type_of(impl_id).instantiate_identity().is_slice() && let ExprKind::Closure(&Closure { body, .. }) = arg.kind && let closure_body = cx.tcx.hir_body(body) - && let &[ - Param { - pat: - &Pat { - kind: PatKind::Binding(_, _, left_ident, _), - .. - }, - .. - }, - Param { - pat: - &Pat { - kind: PatKind::Binding(_, _, right_ident, _), - .. - }, - .. - }, - ] = closure_body.params + && let &[Param { pat: l_pat, .. }, Param { pat: r_pat, .. }] = closure_body.params + && let Some(binding_map) = mapping_of_mirrored_pats(l_pat, r_pat) && let ExprKind::MethodCall(method_path, left_expr, [right_expr], _) = closure_body.value.kind && method_path.ident.name == sym::cmp && let Some(ord_trait) = cx.tcx.get_diagnostic_item(sym::Ord) && cx.ty_based_def(closure_body.value).opt_parent(cx).opt_def_id() == Some(ord_trait) { - let (closure_body, closure_arg, reverse) = if mirrored_exprs(left_expr, left_ident, right_expr, right_ident) { - (left_expr, left_ident.name, false) - } else if mirrored_exprs(left_expr, right_ident, right_expr, left_ident) { - (left_expr, right_ident.name, true) + let (closure_body, closure_arg, reverse) = + if mirrored_exprs(left_expr, right_expr, &binding_map, BindingSource::Left) { + (left_expr, l_pat.span, false) + } else if mirrored_exprs(left_expr, right_expr, &binding_map, BindingSource::Right) { + (left_expr, r_pat.span, true) + } else { + return None; + }; + + let mut applicability = if reverse { + Applicability::MaybeIncorrect } else { - return None; + Applicability::MachineApplicable }; if let ExprKind::Path(QPath::Resolved( @@ -152,10 +275,39 @@ fn detect_lint<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, arg: &Expr<'_>) -> .. }, )) = left_expr.kind - && *left_name == left_ident - && implements_trait(cx, cx.typeck_results().expr_ty(left_expr), ord_trait, &[]) { - return Some(LintTrigger::Sort); + if let PatKind::Binding(_, _, left_ident, _) = l_pat.kind + && *left_name == left_ident + && implements_trait(cx, cx.typeck_results().expr_ty(left_expr), ord_trait, &[]) + { + return Some(LintTrigger::Sort); + } + + let mut left_expr_ty = cx.typeck_results().expr_ty(left_expr); + let left_ident_n_refs = binding_map + .get(&BindingKey { + ident: *left_name, + source: BindingSource::Left, + }) + .map_or(0, |value| value.n_refs); + // Peel off the outer-most ref which is introduced by the closure, if it is not already peeled + // by the pattern + if left_ident_n_refs == 0 { + (left_expr_ty, _) = peel_n_ty_refs(left_expr_ty, 1); + } + if !reverse && is_copy(cx, left_expr_ty) { + let mut closure_body = + snippet_with_applicability(cx, closure_body.span, "_", &mut applicability).to_string(); + if left_ident_n_refs == 0 { + closure_body = format!("*{closure_body}"); + } + return Some(LintTrigger::SortByKey(SortByKeyDetection { + closure_arg, + closure_body, + reverse, + applicability, + })); + } } let left_expr_ty = cx.typeck_results().expr_ty(left_expr); @@ -163,10 +315,12 @@ fn detect_lint<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, arg: &Expr<'_>) -> // Don't lint if the closure is accessing non-Copy fields && (!expr_is_field_access(left_expr) || is_copy(cx, left_expr_ty)) { + let closure_body = Sugg::hir_with_applicability(cx, closure_body, "_", &mut applicability).to_string(); return Some(LintTrigger::SortByKey(SortByKeyDetection { closure_arg, closure_body, reverse, + applicability, })); } } @@ -212,22 +366,18 @@ pub(super) fn check<'tcx>( expr.span, format!("consider using `{method}`"), |diag| { - let mut app = if trigger.reverse { - Applicability::MaybeIncorrect - } else { - Applicability::MachineApplicable - }; + let mut app = trigger.applicability; let recv = Sugg::hir_with_applicability(cx, recv, "(_)", &mut app); - let closure_body = Sugg::hir_with_applicability(cx, trigger.closure_body, "_", &mut app); let closure_body = if trigger.reverse { - format!("{std_or_core}::cmp::Reverse({closure_body})") + format!("{std_or_core}::cmp::Reverse({})", trigger.closure_body) } else { - closure_body.to_string() + trigger.closure_body }; + let closure_arg = snippet_with_applicability(cx, trigger.closure_arg, "_", &mut app); diag.span_suggestion( expr.span, "try", - format!("{recv}.{method}(|{}| {})", trigger.closure_arg, closure_body), + format!("{recv}.{method}(|{closure_arg}| {closure_body})"), app, ); }, diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index 979170d72006..a0fa5e714289 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -438,6 +438,21 @@ pub fn peel_and_count_ty_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize, Option, n: usize) -> (Ty<'_>, Option) { + let mut mutbl = None; + for _ in 0..n { + if let ty::Ref(_, dest_ty, m) = ty.kind() { + ty = *dest_ty; + mutbl.replace(mutbl.map_or(*m, |mutbl: Mutability| mutbl.min(*m))); + } else { + break; + } + } + (ty, mutbl) +} + /// Checks whether `a` and `b` are same types having same `Const` generic args, but ignores /// lifetimes. /// diff --git a/tests/ui/unnecessary_sort_by.fixed b/tests/ui/unnecessary_sort_by.fixed index 372cf683f223..6870470e74c5 100644 --- a/tests/ui/unnecessary_sort_by.fixed +++ b/tests/ui/unnecessary_sort_by.fixed @@ -141,3 +141,35 @@ fn issue16405() { items.sort_by_key(|item1| item1.value.clone()); //~^ unnecessary_sort_by } + +fn issue16348() { + let mut v: Vec<(i32, &str)> = vec![(1, "foo"), (2, "bar")]; + v.sort_by_key(|(_, s1)| *s1); + //~^ unnecessary_sort_by + + struct Foo { + bar: i32, + } + let mut v: Vec = vec![Foo { bar: 1 }, Foo { bar: 2 }]; + v.sort_by_key(|Foo { bar: b1 }| *b1); + //~^ unnecessary_sort_by + + struct Baz(i32); + let mut v: Vec = vec![Baz(1), Baz(2)]; + v.sort_by_key(|Baz(b1)| *b1); + //~^ unnecessary_sort_by + + v.sort_by_key(|&Baz(b1)| b1); + //~^ unnecessary_sort_by + + let mut v: Vec<&i32> = vec![&1, &2]; + v.sort_by_key(|&&b1| b1); + //~^ unnecessary_sort_by + + let mut v: Vec<[i32; 2]> = vec![[1, 2], [3, 4]]; + v.sort_by_key(|[a1, b1]| *a1); + //~^ unnecessary_sort_by + + v.sort_by_key(|[a1, b1]| a1 - b1); + //~^ unnecessary_sort_by +} diff --git a/tests/ui/unnecessary_sort_by.rs b/tests/ui/unnecessary_sort_by.rs index 7dd274623b35..d95306176817 100644 --- a/tests/ui/unnecessary_sort_by.rs +++ b/tests/ui/unnecessary_sort_by.rs @@ -141,3 +141,35 @@ fn issue16405() { items.sort_by(|item1, item2| item1.value.clone().cmp(&item2.value.clone())); //~^ unnecessary_sort_by } + +fn issue16348() { + let mut v: Vec<(i32, &str)> = vec![(1, "foo"), (2, "bar")]; + v.sort_by(|(_, s1), (_, s2)| s1.cmp(s2)); + //~^ unnecessary_sort_by + + struct Foo { + bar: i32, + } + let mut v: Vec = vec![Foo { bar: 1 }, Foo { bar: 2 }]; + v.sort_by(|Foo { bar: b1 }, Foo { bar: b2 }| b1.cmp(b2)); + //~^ unnecessary_sort_by + + struct Baz(i32); + let mut v: Vec = vec![Baz(1), Baz(2)]; + v.sort_by(|Baz(b1), Baz(b2)| b1.cmp(b2)); + //~^ unnecessary_sort_by + + v.sort_by(|&Baz(b1), &Baz(b2)| b1.cmp(&b2)); + //~^ unnecessary_sort_by + + let mut v: Vec<&i32> = vec![&1, &2]; + v.sort_by(|&&b1, &&b2| b1.cmp(&b2)); + //~^ unnecessary_sort_by + + let mut v: Vec<[i32; 2]> = vec![[1, 2], [3, 4]]; + v.sort_by(|[a1, b1], [a2, b2]| a1.cmp(a2)); + //~^ unnecessary_sort_by + + v.sort_by(|[a1, b1], [a2, b2]| (a1 - b1).cmp(&(a2 - b2))); + //~^ unnecessary_sort_by +} diff --git a/tests/ui/unnecessary_sort_by.stderr b/tests/ui/unnecessary_sort_by.stderr index b555245b0d01..b23d27c3729f 100644 --- a/tests/ui/unnecessary_sort_by.stderr +++ b/tests/ui/unnecessary_sort_by.stderr @@ -91,5 +91,47 @@ error: consider using `sort_by_key` LL | items.sort_by(|item1, item2| item1.value.clone().cmp(&item2.value.clone())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `items.sort_by_key(|item1| item1.value.clone())` -error: aborting due to 15 previous errors +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:147:5 + | +LL | v.sort_by(|(_, s1), (_, s2)| s1.cmp(s2)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|(_, s1)| *s1)` + +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:154:5 + | +LL | v.sort_by(|Foo { bar: b1 }, Foo { bar: b2 }| b1.cmp(b2)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|Foo { bar: b1 }| *b1)` + +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:159:5 + | +LL | v.sort_by(|Baz(b1), Baz(b2)| b1.cmp(b2)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|Baz(b1)| *b1)` + +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:162:5 + | +LL | v.sort_by(|&Baz(b1), &Baz(b2)| b1.cmp(&b2)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|&Baz(b1)| b1)` + +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:166:5 + | +LL | v.sort_by(|&&b1, &&b2| b1.cmp(&b2)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|&&b1| b1)` + +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:170:5 + | +LL | v.sort_by(|[a1, b1], [a2, b2]| a1.cmp(a2)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|[a1, b1]| *a1)` + +error: consider using `sort_by_key` + --> tests/ui/unnecessary_sort_by.rs:173:5 + | +LL | v.sort_by(|[a1, b1], [a2, b2]| (a1 - b1).cmp(&(a2 - b2))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|[a1, b1]| a1 - b1)` + +error: aborting due to 22 previous errors From 5937b8ba10651eef9e328c6d6f054ba09726ead2 Mon Sep 17 00:00:00 2001 From: linshuy2 Date: Fri, 16 Jan 2026 20:33:32 +0000 Subject: [PATCH 2253/3801] Apply `unnecessary_sort_by` to Clippy itself --- clippy_utils/src/ty/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs index a0fa5e714289..747dc1f13ab5 100644 --- a/clippy_utils/src/ty/mod.rs +++ b/clippy_utils/src/ty/mod.rs @@ -830,7 +830,7 @@ impl AdtVariantInfo { .enumerate() .map(|(i, f)| (i, approx_ty_size(cx, f.ty(cx.tcx, subst)))) .collect::>(); - fields_size.sort_by(|(_, a_size), (_, b_size)| a_size.cmp(b_size)); + fields_size.sort_by_key(|(_, a_size)| *a_size); Self { ind: i, From 500c94f94517a7bf2df86e04bb900ab35aca1678 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 16 Jan 2026 15:45:53 -0500 Subject: [PATCH 2254/3801] Update cargo submodule --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 6d1bd93c47f0..85eff7c80277 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 6d1bd93c47f059ec1344cb31e68a2fb284cbc6b1 +Subproject commit 85eff7c80277b57f78b11e28d14154ab12fcf643 From 196c098d24f54b661f76c2f9a3e1d74b8a5ce9b7 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 16 Jan 2026 22:42:53 +0100 Subject: [PATCH 2255/3801] `unnecessary_sort_by`: reduce suggestion diffs Now, only `call_span` is replaced, so the receiver is not a part of the diff. This also removes the need to create a snippet for the receiver. --- clippy_lints/src/methods/mod.rs | 4 +- .../src/methods/unnecessary_sort_by.rs | 18 +- tests/ui/unnecessary_sort_by.stderr | 175 +++++++++++++++--- tests/ui/unnecessary_sort_by_no_std.stderr | 15 +- 4 files changed, 178 insertions(+), 34 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 659a704a1ecb..376e93aa7e7d 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -5532,10 +5532,10 @@ impl Methods { stable_sort_primitive::check(cx, expr, recv); }, (sym::sort_by, [arg]) => { - unnecessary_sort_by::check(cx, expr, recv, arg, false); + unnecessary_sort_by::check(cx, expr, call_span, arg, false); }, (sym::sort_unstable_by, [arg]) => { - unnecessary_sort_by::check(cx, expr, recv, arg, true); + unnecessary_sort_by::check(cx, expr, call_span, arg, true); }, (sym::split, [arg]) => { str_split::check(cx, expr, recv, arg); diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs index ac13fc0b6850..3f81a6ecd2f8 100644 --- a/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -343,7 +343,7 @@ fn expr_is_field_access(expr: &Expr<'_>) -> bool { pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, - recv: &'tcx Expr<'_>, + call_span: Span, arg: &'tcx Expr<'_>, is_unstable: bool, ) { @@ -367,17 +367,16 @@ pub(super) fn check<'tcx>( format!("consider using `{method}`"), |diag| { let mut app = trigger.applicability; - let recv = Sugg::hir_with_applicability(cx, recv, "(_)", &mut app); let closure_body = if trigger.reverse { format!("{std_or_core}::cmp::Reverse({})", trigger.closure_body) } else { trigger.closure_body }; let closure_arg = snippet_with_applicability(cx, trigger.closure_arg, "_", &mut app); - diag.span_suggestion( - expr.span, + diag.span_suggestion_verbose( + call_span, "try", - format!("{recv}.{method}(|{closure_arg}| {closure_body})"), + format!("{method}(|{closure_arg}| {closure_body})"), app, ); }, @@ -391,9 +390,12 @@ pub(super) fn check<'tcx>( expr.span, format!("consider using `{method}`"), |diag| { - let mut app = Applicability::MachineApplicable; - let recv = Sugg::hir_with_applicability(cx, recv, "(_)", &mut app); - diag.span_suggestion(expr.span, "try", format!("{recv}.{method}()"), app); + diag.span_suggestion_verbose( + call_span, + "try", + format!("{method}()"), + Applicability::MachineApplicable, + ); }, ); }, diff --git a/tests/ui/unnecessary_sort_by.stderr b/tests/ui/unnecessary_sort_by.stderr index b23d27c3729f..cc545d604ff3 100644 --- a/tests/ui/unnecessary_sort_by.stderr +++ b/tests/ui/unnecessary_sort_by.stderr @@ -2,136 +2,267 @@ error: consider using `sort` --> tests/ui/unnecessary_sort_by.rs:12:5 | LL | vec.sort_by(|a, b| a.cmp(b)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::unnecessary-sort-by` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]` +help: try + | +LL - vec.sort_by(|a, b| a.cmp(b)); +LL + vec.sort(); + | error: consider using `sort_unstable` --> tests/ui/unnecessary_sort_by.rs:14:5 | LL | vec.sort_unstable_by(|a, b| a.cmp(b)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - vec.sort_unstable_by(|a, b| a.cmp(b)); +LL + vec.sort_unstable(); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:16:5 | LL | vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (a + 5).abs())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs())); +LL + vec.sort_by_key(|a| (a + 5).abs()); + | error: consider using `sort_unstable_by_key` --> tests/ui/unnecessary_sort_by.rs:18:5 | LL | vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| id(-a))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b))); +LL + vec.sort_unstable_by_key(|a| id(-a)); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:22:5 | LL | vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs()))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs())); +LL + vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs())); + | error: consider using `sort_unstable_by_key` --> tests/ui/unnecessary_sort_by.rs:24:5 | LL | vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|b| std::cmp::Reverse(id(-b)))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a))); +LL + vec.sort_unstable_by_key(|b| std::cmp::Reverse(id(-b))); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:35:5 | LL | vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (***a).abs())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs())); +LL + vec.sort_by_key(|a| (***a).abs()); + | error: consider using `sort_unstable_by_key` --> tests/ui/unnecessary_sort_by.rs:37:5 | LL | vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| (***a).abs())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs())); +LL + vec.sort_unstable_by_key(|a| (***a).abs()); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:97:9 | LL | args.sort_by(|a, b| a.name().cmp(&b.name())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|a| a.name())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - args.sort_by(|a, b| a.name().cmp(&b.name())); +LL + args.sort_by_key(|a| a.name()); + | error: consider using `sort_unstable_by_key` --> tests/ui/unnecessary_sort_by.rs:99:9 | LL | args.sort_unstable_by(|a, b| a.name().cmp(&b.name())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_unstable_by_key(|a| a.name())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - args.sort_unstable_by(|a, b| a.name().cmp(&b.name())); +LL + args.sort_unstable_by_key(|a| a.name()); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:102:9 | LL | args.sort_by(|a, b| b.name().cmp(&a.name())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|b| std::cmp::Reverse(b.name()))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - args.sort_by(|a, b| b.name().cmp(&a.name())); +LL + args.sort_by_key(|b| std::cmp::Reverse(b.name())); + | error: consider using `sort_unstable_by_key` --> tests/ui/unnecessary_sort_by.rs:104:9 | LL | args.sort_unstable_by(|a, b| b.name().cmp(&a.name())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_unstable_by_key(|b| std::cmp::Reverse(b.name()))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - args.sort_unstable_by(|a, b| b.name().cmp(&a.name())); +LL + args.sort_unstable_by_key(|b| std::cmp::Reverse(b.name())); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:118:5 | LL | v.sort_by(|a, b| a.0.cmp(&b.0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|a| a.0)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - v.sort_by(|a, b| a.0.cmp(&b.0)); +LL + v.sort_by_key(|a| a.0); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:136:5 | LL | items.sort_by(|item1, item2| item1.key.cmp(&item2.key)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `items.sort_by_key(|item1| item1.key)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - items.sort_by(|item1, item2| item1.key.cmp(&item2.key)); +LL + items.sort_by_key(|item1| item1.key); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:141:5 | LL | items.sort_by(|item1, item2| item1.value.clone().cmp(&item2.value.clone())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `items.sort_by_key(|item1| item1.value.clone())` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - items.sort_by(|item1, item2| item1.value.clone().cmp(&item2.value.clone())); +LL + items.sort_by_key(|item1| item1.value.clone()); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:147:5 | LL | v.sort_by(|(_, s1), (_, s2)| s1.cmp(s2)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|(_, s1)| *s1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - v.sort_by(|(_, s1), (_, s2)| s1.cmp(s2)); +LL + v.sort_by_key(|(_, s1)| *s1); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:154:5 | LL | v.sort_by(|Foo { bar: b1 }, Foo { bar: b2 }| b1.cmp(b2)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|Foo { bar: b1 }| *b1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - v.sort_by(|Foo { bar: b1 }, Foo { bar: b2 }| b1.cmp(b2)); +LL + v.sort_by_key(|Foo { bar: b1 }| *b1); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:159:5 | LL | v.sort_by(|Baz(b1), Baz(b2)| b1.cmp(b2)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|Baz(b1)| *b1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - v.sort_by(|Baz(b1), Baz(b2)| b1.cmp(b2)); +LL + v.sort_by_key(|Baz(b1)| *b1); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:162:5 | LL | v.sort_by(|&Baz(b1), &Baz(b2)| b1.cmp(&b2)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|&Baz(b1)| b1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - v.sort_by(|&Baz(b1), &Baz(b2)| b1.cmp(&b2)); +LL + v.sort_by_key(|&Baz(b1)| b1); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:166:5 | LL | v.sort_by(|&&b1, &&b2| b1.cmp(&b2)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|&&b1| b1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - v.sort_by(|&&b1, &&b2| b1.cmp(&b2)); +LL + v.sort_by_key(|&&b1| b1); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:170:5 | LL | v.sort_by(|[a1, b1], [a2, b2]| a1.cmp(a2)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|[a1, b1]| *a1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - v.sort_by(|[a1, b1], [a2, b2]| a1.cmp(a2)); +LL + v.sort_by_key(|[a1, b1]| *a1); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by.rs:173:5 | LL | v.sort_by(|[a1, b1], [a2, b2]| (a1 - b1).cmp(&(a2 - b2))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.sort_by_key(|[a1, b1]| a1 - b1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - v.sort_by(|[a1, b1], [a2, b2]| (a1 - b1).cmp(&(a2 - b2))); +LL + v.sort_by_key(|[a1, b1]| a1 - b1); + | error: aborting due to 22 previous errors diff --git a/tests/ui/unnecessary_sort_by_no_std.stderr b/tests/ui/unnecessary_sort_by_no_std.stderr index de3ef4123514..b4dd6a6dbdc5 100644 --- a/tests/ui/unnecessary_sort_by_no_std.stderr +++ b/tests/ui/unnecessary_sort_by_no_std.stderr @@ -2,16 +2,27 @@ error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by_no_std.rs:10:5 | LL | vec.sort_by(|a, b| (a + 1).cmp(&(b + 1))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| a + 1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::unnecessary-sort-by` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]` +help: try + | +LL - vec.sort_by(|a, b| (a + 1).cmp(&(b + 1))); +LL + vec.sort_by_key(|a| a + 1); + | error: consider using `sort_by_key` --> tests/ui/unnecessary_sort_by_no_std.rs:19:5 | LL | vec.sort_by(|a, b| (b + 1).cmp(&(a + 1))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|b| core::cmp::Reverse(b + 1))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - vec.sort_by(|a, b| (b + 1).cmp(&(a + 1))); +LL + vec.sort_by_key(|b| core::cmp::Reverse(b + 1)); + | error: aborting due to 2 previous errors From ccdda582a84a2985a90374cb8720b0084b4c9408 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Fri, 16 Jan 2026 22:53:37 +0100 Subject: [PATCH 2256/3801] clean-up --- clippy_lints/src/methods/str_split.rs | 6 ++++-- tests/ui/str_split.fixed | 2 -- tests/ui/str_split.rs | 2 -- tests/ui/str_split.stderr | 20 ++++++++++---------- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/methods/str_split.rs b/clippy_lints/src/methods/str_split.rs index 479064a0671e..9644b2c774b5 100644 --- a/clippy_lints/src/methods/str_split.rs +++ b/clippy_lints/src/methods/str_split.rs @@ -19,8 +19,10 @@ pub(super) fn check<'a>(cx: &LateContext<'a>, expr: &'_ Expr<'_>, split_recv: &' && cx.typeck_results().expr_ty_adjusted(trim_recv).peel_refs().is_str() && !is_const_evaluatable(cx, trim_recv) && let ExprKind::Lit(split_lit) = split_arg.kind - && (matches!(split_lit.node, LitKind::Char('\n')) - || matches!(split_lit.node, LitKind::Str(sym::LF | sym::CRLF, _))) + && matches!( + split_lit.node, + LitKind::Char('\n') | LitKind::Str(sym::LF | sym::CRLF, _) + ) { let mut app = Applicability::MaybeIncorrect; span_lint_and_sugg( diff --git a/tests/ui/str_split.fixed b/tests/ui/str_split.fixed index 6aca5051c570..c93d4d4f818d 100644 --- a/tests/ui/str_split.fixed +++ b/tests/ui/str_split.fixed @@ -1,7 +1,5 @@ #![warn(clippy::str_split_at_newline)] -#![allow(clippy::needless_lifetimes)] -use core::str::Split; use std::ops::Deref; struct NotStr<'a> { diff --git a/tests/ui/str_split.rs b/tests/ui/str_split.rs index 11e9862da14b..5792ce04ec33 100644 --- a/tests/ui/str_split.rs +++ b/tests/ui/str_split.rs @@ -1,7 +1,5 @@ #![warn(clippy::str_split_at_newline)] -#![allow(clippy::needless_lifetimes)] -use core::str::Split; use std::ops::Deref; struct NotStr<'a> { diff --git a/tests/ui/str_split.stderr b/tests/ui/str_split.stderr index c4eca81004c5..40202c8ac47a 100644 --- a/tests/ui/str_split.stderr +++ b/tests/ui/str_split.stderr @@ -1,5 +1,5 @@ error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:60:13 + --> tests/ui/str_split.rs:58:13 | LL | let _ = s1.trim().split('\n'); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()` @@ -8,55 +8,55 @@ LL | let _ = s1.trim().split('\n'); = help: to override `-D warnings` add `#[allow(clippy::str_split_at_newline)]` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:63:13 + --> tests/ui/str_split.rs:61:13 | LL | let _ = s1.trim().split("\n"); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:65:13 + --> tests/ui/str_split.rs:63:13 | LL | let _ = s1.trim().split("\r\n"); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:69:13 + --> tests/ui/str_split.rs:67:13 | LL | let _ = s2.trim().split('\n'); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:72:13 + --> tests/ui/str_split.rs:70:13 | LL | let _ = s2.trim().split("\n"); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:74:13 + --> tests/ui/str_split.rs:72:13 | LL | let _ = s2.trim().split("\r\n"); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:79:13 + --> tests/ui/str_split.rs:77:13 | LL | let _ = s3.trim().split('\n'); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:82:13 + --> tests/ui/str_split.rs:80:13 | LL | let _ = s3.trim().split("\n"); | ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:84:13 + --> tests/ui/str_split.rs:82:13 | LL | let _ = s3.trim().split("\r\n"); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()` error: using `str.trim().split()` with hard-coded newlines - --> tests/ui/str_split.rs:88:13 + --> tests/ui/str_split.rs:86:13 | LL | let _ = make_str!(s1).trim().split('\n'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `make_str!(s1).lines()` From bcde8c10707c521480d1beb1bf4dd0fc72cc3902 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sat, 17 Jan 2026 00:00:06 +0100 Subject: [PATCH 2257/3801] Do not consider binary operators as commutative by default Only `==` (and thus `!=`) are supposed to be commutative according to Rust's documentation. Do not make assumptions about other operators whose meaning may depend on the types on which they apply. However, special-case operators known to be commutative for primitive types such as addition or multiplication. --- clippy_utils/src/hir_utils.rs | 31 ++-- tests/ui/if_same_then_else.rs | 84 +++++++++-- tests/ui/if_same_then_else.stderr | 230 ++++++++++++++++++++++++++++-- 3 files changed, 309 insertions(+), 36 deletions(-) diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index bdc1550d69b7..79994d8a3c23 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -505,7 +505,7 @@ impl HirEqInterExpr<'_, '_, '_> { (ExprKind::Block(l, _), ExprKind::Block(r, _)) => self.eq_block(l, r), (ExprKind::Binary(l_op, ll, lr), ExprKind::Binary(r_op, rl, rr)) => { l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) - || swap_binop(l_op.node, ll, lr).is_some_and(|(l_op, ll, lr)| { + || swap_binop(self.inner.cx, l_op.node, ll, lr).is_some_and(|(l_op, ll, lr)| { l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr) }) }, @@ -939,26 +939,35 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &' } fn swap_binop<'a>( + cx: &LateContext<'_>, binop: BinOpKind, lhs: &'a Expr<'a>, rhs: &'a Expr<'a>, ) -> Option<(BinOpKind, &'a Expr<'a>, &'a Expr<'a>)> { match binop { - BinOpKind::Add | BinOpKind::Eq | BinOpKind::Ne | BinOpKind::BitAnd | BinOpKind::BitXor | BinOpKind::BitOr => { - Some((binop, rhs, lhs)) - }, + // `==` and `!=`, are commutative + BinOpKind::Eq | BinOpKind::Ne => Some((binop, rhs, lhs)), + // Comparisons can be reversed BinOpKind::Lt => Some((BinOpKind::Gt, rhs, lhs)), BinOpKind::Le => Some((BinOpKind::Ge, rhs, lhs)), BinOpKind::Ge => Some((BinOpKind::Le, rhs, lhs)), BinOpKind::Gt => Some((BinOpKind::Lt, rhs, lhs)), - BinOpKind::Mul // Not always commutative, e.g. with matrices. See issue #5698 - | BinOpKind::Shl - | BinOpKind::Shr - | BinOpKind::Rem - | BinOpKind::Sub - | BinOpKind::Div + // Non-commutative operators + BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Rem | BinOpKind::Sub | BinOpKind::Div => None, + // We know that those operators are commutative for primitive types, + // and we don't assume anything for other types + BinOpKind::Mul + | BinOpKind::Add | BinOpKind::And - | BinOpKind::Or => None, + | BinOpKind::Or + | BinOpKind::BitAnd + | BinOpKind::BitXor + | BinOpKind::BitOr => cx + .typeck_results() + .expr_ty_adjusted(lhs) + .peel_refs() + .is_primitive() + .then_some((binop, rhs, lhs)), } } diff --git a/tests/ui/if_same_then_else.rs b/tests/ui/if_same_then_else.rs index 6d2e63e7299a..6e0e2c5ea720 100644 --- a/tests/ui/if_same_then_else.rs +++ b/tests/ui/if_same_then_else.rs @@ -11,6 +11,8 @@ unreachable_code )] +use std::ops::*; + struct Foo { bar: u8, } @@ -133,18 +135,6 @@ fn func() { fn f(val: &[u8]) {} -mod issue_5698 { - fn mul_not_always_commutative(x: i32, y: i32) -> i32 { - if x == 42 { - x * y - } else if x == 21 { - y * x - } else { - 0 - } - } -} - mod issue_8836 { fn do_not_lint() { if true { @@ -245,3 +235,73 @@ mod issue_11213 { } fn main() {} + +fn issue16416(x: bool, a: T, b: T) +where + T: Add + Sub + Mul + Div + Rem + BitAnd + BitOr + BitXor + PartialEq + Eq + PartialOrd + Ord + Shr + Shl + Copy, +{ + // Non-guaranteed-commutative operators + _ = if x { a * b } else { b * a }; + _ = if x { a + b } else { b + a }; + _ = if x { a - b } else { b - a }; + _ = if x { a / b } else { b / a }; + _ = if x { a % b } else { b % a }; + _ = if x { a << b } else { b << a }; + _ = if x { a >> b } else { b >> a }; + _ = if x { a & b } else { b & a }; + _ = if x { a ^ b } else { b ^ a }; + _ = if x { a | b } else { b | a }; + + // Guaranteed commutative operators + //~v if_same_then_else + _ = if x { a == b } else { b == a }; + //~v if_same_then_else + _ = if x { a != b } else { b != a }; + + // Symetric operators + //~v if_same_then_else + _ = if x { a < b } else { b > a }; + //~v if_same_then_else + _ = if x { a <= b } else { b >= a }; + //~v if_same_then_else + _ = if x { a > b } else { b < a }; + //~v if_same_then_else + _ = if x { a >= b } else { b <= a }; +} + +fn issue16416_prim(x: bool, a: u32, b: u32) { + // Non-commutative operators + _ = if x { a - b } else { b - a }; + _ = if x { a / b } else { b / a }; + _ = if x { a % b } else { b % a }; + _ = if x { a << b } else { b << a }; + _ = if x { a >> b } else { b >> a }; + + // Commutative operators on primitive types + //~v if_same_then_else + _ = if x { a * b } else { b * a }; + //~v if_same_then_else + _ = if x { a + b } else { b + a }; + //~v if_same_then_else + _ = if x { a & b } else { b & a }; + //~v if_same_then_else + _ = if x { a ^ b } else { b ^ a }; + //~v if_same_then_else + _ = if x { a | b } else { b | a }; + + // Always commutative operators + //~v if_same_then_else + _ = if x { a == b } else { b == a }; + //~v if_same_then_else + _ = if x { a != b } else { b != a }; + + // Symetric operators + //~v if_same_then_else + _ = if x { a < b } else { b > a }; + //~v if_same_then_else + _ = if x { a <= b } else { b >= a }; + //~v if_same_then_else + _ = if x { a > b } else { b < a }; + //~v if_same_then_else + _ = if x { a >= b } else { b <= a }; +} diff --git a/tests/ui/if_same_then_else.stderr b/tests/ui/if_same_then_else.stderr index b76da3fb1cb5..57396a566941 100644 --- a/tests/ui/if_same_then_else.stderr +++ b/tests/ui/if_same_then_else.stderr @@ -1,5 +1,5 @@ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:23:13 + --> tests/ui/if_same_then_else.rs:25:13 | LL | if true { | _____________^ @@ -12,7 +12,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else.rs:31:12 + --> tests/ui/if_same_then_else.rs:33:12 | LL | } else { | ____________^ @@ -27,43 +27,43 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]` error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:67:21 + --> tests/ui/if_same_then_else.rs:69:21 | LL | let _ = if true { 0.0 } else { 0.0 }; | ^^^^^^^ | note: same as this - --> tests/ui/if_same_then_else.rs:67:34 + --> tests/ui/if_same_then_else.rs:69:34 | LL | let _ = if true { 0.0 } else { 0.0 }; | ^^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:70:21 + --> tests/ui/if_same_then_else.rs:72:21 | LL | let _ = if true { -0.0 } else { -0.0 }; | ^^^^^^^^ | note: same as this - --> tests/ui/if_same_then_else.rs:70:35 + --> tests/ui/if_same_then_else.rs:72:35 | LL | let _ = if true { -0.0 } else { -0.0 }; | ^^^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:82:21 + --> tests/ui/if_same_then_else.rs:84:21 | LL | let _ = if true { 42 } else { 42 }; | ^^^^^^ | note: same as this - --> tests/ui/if_same_then_else.rs:82:33 + --> tests/ui/if_same_then_else.rs:84:33 | LL | let _ = if true { 42 } else { 42 }; | ^^^^^^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:85:13 + --> tests/ui/if_same_then_else.rs:87:13 | LL | if true { | _____________^ @@ -76,7 +76,7 @@ LL | | } else { | |_____^ | note: same as this - --> tests/ui/if_same_then_else.rs:92:12 + --> tests/ui/if_same_then_else.rs:94:12 | LL | } else { | ____________^ @@ -89,7 +89,7 @@ LL | | } | |_____^ error: this `if` has identical blocks - --> tests/ui/if_same_then_else.rs:238:14 + --> tests/ui/if_same_then_else.rs:228:14 | LL | if x { | ______________^ @@ -98,7 +98,7 @@ LL | | } else { | |_________^ | note: same as this - --> tests/ui/if_same_then_else.rs:240:16 + --> tests/ui/if_same_then_else.rs:230:16 | LL | } else { | ________________^ @@ -106,5 +106,209 @@ LL | | 0_u8.is_power_of_two() LL | | } | |_________^ -error: aborting due to 6 previous errors +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:257:14 + | +LL | _ = if x { a == b } else { b == a }; + | ^^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:257:30 + | +LL | _ = if x { a == b } else { b == a }; + | ^^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:259:14 + | +LL | _ = if x { a != b } else { b != a }; + | ^^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:259:30 + | +LL | _ = if x { a != b } else { b != a }; + | ^^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:263:14 + | +LL | _ = if x { a < b } else { b > a }; + | ^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:263:29 + | +LL | _ = if x { a < b } else { b > a }; + | ^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:265:14 + | +LL | _ = if x { a <= b } else { b >= a }; + | ^^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:265:30 + | +LL | _ = if x { a <= b } else { b >= a }; + | ^^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:267:14 + | +LL | _ = if x { a > b } else { b < a }; + | ^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:267:29 + | +LL | _ = if x { a > b } else { b < a }; + | ^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:269:14 + | +LL | _ = if x { a >= b } else { b <= a }; + | ^^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:269:30 + | +LL | _ = if x { a >= b } else { b <= a }; + | ^^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:282:14 + | +LL | _ = if x { a * b } else { b * a }; + | ^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:282:29 + | +LL | _ = if x { a * b } else { b * a }; + | ^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:284:14 + | +LL | _ = if x { a + b } else { b + a }; + | ^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:284:29 + | +LL | _ = if x { a + b } else { b + a }; + | ^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:286:14 + | +LL | _ = if x { a & b } else { b & a }; + | ^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:286:29 + | +LL | _ = if x { a & b } else { b & a }; + | ^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:288:14 + | +LL | _ = if x { a ^ b } else { b ^ a }; + | ^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:288:29 + | +LL | _ = if x { a ^ b } else { b ^ a }; + | ^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:290:14 + | +LL | _ = if x { a | b } else { b | a }; + | ^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:290:29 + | +LL | _ = if x { a | b } else { b | a }; + | ^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:294:14 + | +LL | _ = if x { a == b } else { b == a }; + | ^^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:294:30 + | +LL | _ = if x { a == b } else { b == a }; + | ^^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:296:14 + | +LL | _ = if x { a != b } else { b != a }; + | ^^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:296:30 + | +LL | _ = if x { a != b } else { b != a }; + | ^^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:300:14 + | +LL | _ = if x { a < b } else { b > a }; + | ^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:300:29 + | +LL | _ = if x { a < b } else { b > a }; + | ^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:302:14 + | +LL | _ = if x { a <= b } else { b >= a }; + | ^^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:302:30 + | +LL | _ = if x { a <= b } else { b >= a }; + | ^^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:304:14 + | +LL | _ = if x { a > b } else { b < a }; + | ^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:304:29 + | +LL | _ = if x { a > b } else { b < a }; + | ^^^^^^^^^ + +error: this `if` has identical blocks + --> tests/ui/if_same_then_else.rs:306:14 + | +LL | _ = if x { a >= b } else { b <= a }; + | ^^^^^^^^^^ + | +note: same as this + --> tests/ui/if_same_then_else.rs:306:30 + | +LL | _ = if x { a >= b } else { b <= a }; + | ^^^^^^^^^^ + +error: aborting due to 23 previous errors From dd61de95e47de79c4676c528f275cd07654fe377 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sat, 17 Jan 2026 00:41:20 +0100 Subject: [PATCH 2258/3801] Remove empty stderr file from tests --- tests/ui/manual_take_nocore.stderr | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/ui/manual_take_nocore.stderr diff --git a/tests/ui/manual_take_nocore.stderr b/tests/ui/manual_take_nocore.stderr deleted file mode 100644 index e69de29bb2d1..000000000000 From 79f12eb1ed02e763dafe13938996f69e6b0b5f7a Mon Sep 17 00:00:00 2001 From: dianne Date: Fri, 16 Jan 2026 15:42:25 -0800 Subject: [PATCH 2259/3801] remove some confusing mutation `oprnd_t` was used both for the type of the operand of a unary operator and for the type of the operator expression as a whole. Now it's only used for the operand's type. --- compiler/rustc_hir_typeck/src/expr.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9f3ff0b2d03c..1d7faf1345cf 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -434,14 +434,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::UnOp::Not | hir::UnOp::Neg => expected, hir::UnOp::Deref => NoExpectation, }; - let mut oprnd_t = self.check_expr_with_expectation(oprnd, expected_inner); + let oprnd_t = self.check_expr_with_expectation(oprnd, expected_inner); - if !oprnd_t.references_error() { - oprnd_t = self.structurally_resolve_type(expr.span, oprnd_t); + if let Err(guar) = oprnd_t.error_reported() { + Ty::new_error(tcx, guar) + } else { + let oprnd_t = self.structurally_resolve_type(expr.span, oprnd_t); match unop { hir::UnOp::Deref => { if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) { - oprnd_t = ty; + ty } else { let mut err = self.dcx().create_err(CantDereference { span: expr.span, ty: oprnd_t }); @@ -451,26 +453,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } - oprnd_t = Ty::new_error(tcx, err.emit()); + Ty::new_error(tcx, err.emit()) } } hir::UnOp::Not => { let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); // If it's builtin, we can reuse the type, this helps inference. - if !(oprnd_t.is_integral() || *oprnd_t.kind() == ty::Bool) { - oprnd_t = result; + if oprnd_t.is_integral() || *oprnd_t.kind() == ty::Bool { + oprnd_t + } else { + result } } hir::UnOp::Neg => { let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); // If it's builtin, we can reuse the type, this helps inference. - if !oprnd_t.is_numeric() { - oprnd_t = result; - } + if oprnd_t.is_numeric() { oprnd_t } else { result } } } } - oprnd_t } fn check_expr_addr_of( From 91bbb692d5a32faae9a8fb3f212f518bd98ff3cd Mon Sep 17 00:00:00 2001 From: dianne Date: Fri, 16 Jan 2026 15:51:29 -0800 Subject: [PATCH 2260/3801] re-style `check_expr_unop` --- compiler/rustc_hir_typeck/src/expr.rs | 54 +++++++++++---------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 1d7faf1345cf..885af3b909b8 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -437,39 +437,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let oprnd_t = self.check_expr_with_expectation(oprnd, expected_inner); if let Err(guar) = oprnd_t.error_reported() { - Ty::new_error(tcx, guar) - } else { - let oprnd_t = self.structurally_resolve_type(expr.span, oprnd_t); - match unop { - hir::UnOp::Deref => { - if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) { - ty - } else { - let mut err = - self.dcx().create_err(CantDereference { span: expr.span, ty: oprnd_t }); - let sp = tcx.sess.source_map().start_point(expr.span).with_parent(None); - if let Some(sp) = - tcx.sess.psess.ambiguous_block_expr_parse.borrow().get(&sp) - { - err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); - } - Ty::new_error(tcx, err.emit()) - } - } - hir::UnOp::Not => { - let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); - // If it's builtin, we can reuse the type, this helps inference. - if oprnd_t.is_integral() || *oprnd_t.kind() == ty::Bool { - oprnd_t - } else { - result - } - } - hir::UnOp::Neg => { - let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); - // If it's builtin, we can reuse the type, this helps inference. - if oprnd_t.is_numeric() { oprnd_t } else { result } + return Ty::new_error(tcx, guar); + } + + let oprnd_t = self.structurally_resolve_type(expr.span, oprnd_t); + match unop { + hir::UnOp::Deref => self.lookup_derefing(expr, oprnd, oprnd_t).unwrap_or_else(|| { + let mut err = + self.dcx().create_err(CantDereference { span: expr.span, ty: oprnd_t }); + let sp = tcx.sess.source_map().start_point(expr.span).with_parent(None); + if let Some(sp) = tcx.sess.psess.ambiguous_block_expr_parse.borrow().get(&sp) { + err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } + Ty::new_error(tcx, err.emit()) + }), + hir::UnOp::Not => { + let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); + // If it's builtin, we can reuse the type, this helps inference. + if oprnd_t.is_integral() || *oprnd_t.kind() == ty::Bool { oprnd_t } else { result } + } + hir::UnOp::Neg => { + let result = self.check_user_unop(expr, oprnd_t, unop, expected_inner); + // If it's builtin, we can reuse the type, this helps inference. + if oprnd_t.is_numeric() { oprnd_t } else { result } } } } From 696f616b78940380e34f06f6d094c17ab7c647a4 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Fri, 16 Jan 2026 23:59:16 +0000 Subject: [PATCH 2261/3801] Remove known problems from `comparison_chain` This reverts commit e42ba4829c02e8308ae142b5a2fd5efb6ccf0a7b, reversing changes made to d75bc868caee77f1b29763f8ba5a00494ed52f6b. --- clippy_lints/src/comparison_chain.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/clippy_lints/src/comparison_chain.rs b/clippy_lints/src/comparison_chain.rs index 238ebd4a444c..a2ddf3dad7a2 100644 --- a/clippy_lints/src/comparison_chain.rs +++ b/clippy_lints/src/comparison_chain.rs @@ -17,10 +17,6 @@ declare_clippy_lint! { /// `if` is not guaranteed to be exhaustive and conditionals can get /// repetitive /// - /// ### Known problems - /// The match statement may be slower due to the compiler - /// not inlining the call to cmp. See issue [#5354](https://github.com/rust-lang/rust-clippy/issues/5354) - /// /// ### Example /// ```rust,ignore /// # fn a() {} From c7031e93c50ad46601993efe6d7e6139977bd1a2 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Fri, 16 Jan 2026 18:31:11 +0000 Subject: [PATCH 2262/3801] feat: Support references in reflection type info --- .../src/const_eval/type_info.rs | 35 ++++++++++++++- compiler/rustc_span/src/symbol.rs | 2 + library/core/src/mem/type_info.rs | 13 ++++++ library/coretests/tests/mem/type_info.rs | 32 +++++++++++++- tests/ui/reflection/dump.bit32.run.stdout | 43 +++++++++++++++++-- tests/ui/reflection/dump.bit64.run.stdout | 43 +++++++++++++++++-- tests/ui/reflection/dump.rs | 1 + 7 files changed, 161 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 5d37db06d76a..3c6064d3f87d 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -1,4 +1,5 @@ use rustc_abi::FieldIdx; +use rustc_ast::Mutability; use rustc_hir::LangItem; use rustc_middle::mir::interpret::{CtfeProvenance, Scalar}; use rustc_middle::span_bug; @@ -103,12 +104,19 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { let (variant, _variant_place) = downcast(sym::Str)?; variant } + ty::Ref(_, ty, mutability) => { + let (variant, variant_place) = downcast(sym::Reference)?; + let reference_place = + self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_reference_type_info(reference_place, *ty, *mutability)?; + + variant + } ty::Adt(_, _) | ty::Foreign(_) | ty::Pat(_, _) | ty::Slice(_) | ty::RawPtr(..) - | ty::Ref(..) | ty::FnDef(..) | ty::FnPtr(..) | ty::UnsafeBinder(..) @@ -279,4 +287,29 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { } interp_ok(()) } + + pub(crate) fn write_reference_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + ty: Ty<'tcx>, + mutability: Mutability, + ) -> InterpResult<'tcx> { + // Iterate over all fields of `type_info::Reference`. + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + // Write the `TypeId` of the reference's inner type to the `ty` field. + sym::pointee => self.write_type_id(ty, &field_place)?, + // Write the boolean representing the reference's mutability to the `mutable` field. + sym::mutable => { + self.write_scalar(Scalar::from_bool(mutability.is_mut()), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + interp_ok(()) + } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 51920db8cd79..f0576002354d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -343,6 +343,7 @@ symbols! { RefCell, RefCellRef, RefCellRefMut, + Reference, Relaxed, Release, Result, @@ -1521,6 +1522,7 @@ symbols! { must_use, mut_preserve_binding_mode_2024, mut_ref, + mutable, naked, naked_asm, naked_functions, diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 2e3bdb45ce05..ee647ef55840 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -55,6 +55,8 @@ pub enum TypeKind { Float(Float), /// String slice type. Str(Str), + /// References. + Reference(Reference), /// FIXME(#146922): add all the common types Other, } @@ -133,3 +135,14 @@ pub struct Float { pub struct Str { // No additional information to provide for now. } + +/// Compile-time type information about references. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Reference { + /// The type of the value being referred to. + pub pointee: TypeId, + /// Whether this reference is mutable or not. + pub mutable: bool, +} diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index fc13637a5574..7df632981ce1 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -1,4 +1,4 @@ -use std::any::TypeId; +use std::any::{Any, TypeId}; use std::mem::type_info::{Type, TypeKind}; #[test] @@ -95,3 +95,33 @@ fn test_primitives() { let Type { kind: Str(_ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, None); } + +#[test] +fn test_references() { + // Immutable reference. + match const { Type::of::<&u8>() }.kind { + TypeKind::Reference(reference) => { + assert_eq!(reference.pointee, TypeId::of::()); + assert!(!reference.mutable); + } + _ => unreachable!(), + } + + // Mutable pointer. + match const { Type::of::<&mut u64>() }.kind { + TypeKind::Reference(reference) => { + assert_eq!(reference.pointee, TypeId::of::()); + assert!(reference.mutable); + } + _ => unreachable!(), + } + + // Wide pointer. + match const { Type::of::<&dyn Any>() }.kind { + TypeKind::Reference(reference) => { + assert_eq!(reference.pointee, TypeId::of::()); + assert!(!reference.mutable); + } + _ => unreachable!(), + } +} diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout index 483efdbbd12a..8d0398bdd53a 100644 --- a/tests/ui/reflection/dump.bit32.run.stdout +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -155,19 +155,34 @@ Type { ), } Type { - kind: Other, + kind: Reference( + Reference { + pointee: TypeId(0xda1b6da9bd297bb2900de9303aadea79), + mutable: false, + }, + ), size: Some( 8, ), } Type { - kind: Other, + kind: Reference( + Reference { + pointee: TypeId(0x474ccf3b5db264ef53916706f7d7bb2c), + mutable: false, + }, + ), size: Some( 8, ), } Type { - kind: Other, + kind: Reference( + Reference { + pointee: TypeId(0x641e3def269c37acc6dcb92bf8c5f196), + mutable: false, + }, + ), size: Some( 8, ), @@ -182,3 +197,25 @@ Type { kind: Other, size: None, } +Type { + kind: Reference( + Reference { + pointee: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + mutable: false, + }, + ), + size: Some( + 4, + ), +} +Type { + kind: Reference( + Reference { + pointee: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + mutable: true, + }, + ), + size: Some( + 4, + ), +} diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout index 681e81b71d56..3564922fc171 100644 --- a/tests/ui/reflection/dump.bit64.run.stdout +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -155,19 +155,34 @@ Type { ), } Type { - kind: Other, + kind: Reference( + Reference { + pointee: TypeId(0xda1b6da9bd297bb2900de9303aadea79), + mutable: false, + }, + ), size: Some( 16, ), } Type { - kind: Other, + kind: Reference( + Reference { + pointee: TypeId(0x474ccf3b5db264ef53916706f7d7bb2c), + mutable: false, + }, + ), size: Some( 16, ), } Type { - kind: Other, + kind: Reference( + Reference { + pointee: TypeId(0x641e3def269c37acc6dcb92bf8c5f196), + mutable: false, + }, + ), size: Some( 16, ), @@ -182,3 +197,25 @@ Type { kind: Other, size: None, } +Type { + kind: Reference( + Reference { + pointee: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + mutable: false, + }, + ), + size: Some( + 8, + ), +} +Type { + kind: Reference( + Reference { + pointee: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), + mutable: true, + }, + ), + size: Some( + 8, + ), +} diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs index 584b7c8ed4ae..d42216a62fdc 100644 --- a/tests/ui/reflection/dump.rs +++ b/tests/ui/reflection/dump.rs @@ -40,5 +40,6 @@ fn main() { Foo, Bar, &Unsized, &str, &[u8], str, [u8], + &u8, &mut u8, } } From 27b02796609e43103ce06a5c38cfc82e029c53c7 Mon Sep 17 00:00:00 2001 From: Asuna Date: Sat, 17 Jan 2026 01:53:08 +0100 Subject: [PATCH 2263/3801] Change field `bit_width: usize` to `bits: u32` in type info --- .../src/const_eval/type_info.rs | 8 ++++---- compiler/rustc_span/src/symbol.rs | 2 +- library/core/src/mem/type_info.rs | 4 ++-- library/coretests/tests/mem/type_info.rs | 14 ++++++------- tests/ui/reflection/dump.bit32.run.stdout | 20 +++++++++---------- tests/ui/reflection/dump.bit64.run.stdout | 20 +++++++++---------- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 5d37db06d76a..195714b1c0e6 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -249,8 +249,8 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { { let field_place = self.project_field(&place, field_idx)?; match field.name { - sym::bit_width => self.write_scalar( - ScalarInt::try_from_target_usize(bit_width, self.tcx.tcx).unwrap(), + sym::bits => self.write_scalar( + Scalar::from_u32(bit_width.try_into().expect("bit_width overflowed")), &field_place, )?, sym::signed => self.write_scalar(Scalar::from_bool(signed), &field_place)?, @@ -270,8 +270,8 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { { let field_place = self.project_field(&place, field_idx)?; match field.name { - sym::bit_width => self.write_scalar( - ScalarInt::try_from_target_usize(bit_width, self.tcx.tcx).unwrap(), + sym::bits => self.write_scalar( + Scalar::from_u32(bit_width.try_into().expect("bit_width overflowed")), &field_place, )?, other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 51920db8cd79..2bd9ee6a6123 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -589,12 +589,12 @@ symbols! { binaryheap_iter, bind_by_move_pattern_guards, bindings_after_at, - bit_width, bitand, bitand_assign, bitor, bitor_assign, bitreverse, + bits, bitxor, bitxor_assign, black_box, diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 2e3bdb45ce05..5a105573db77 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -112,7 +112,7 @@ pub struct Char { #[unstable(feature = "type_info", issue = "146922")] pub struct Int { /// The bit width of the signed integer type. - pub bit_width: usize, + pub bits: u32, /// Whether the integer type is signed. pub signed: bool, } @@ -123,7 +123,7 @@ pub struct Int { #[unstable(feature = "type_info", issue = "146922")] pub struct Float { /// The bit width of the floating-point type. - pub bit_width: usize, + pub bits: u32, } /// Compile-time type information about string slice types. diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index fc13637a5574..53195fc5be0e 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -47,8 +47,8 @@ fn test_tuples() { match (a.ty.info().kind, b.ty.info().kind) { (TypeKind::Int(a), TypeKind::Int(b)) => { - assert!(a.bit_width == 8 && a.signed); - assert!(b.bit_width == 8 && !b.signed); + assert!(a.bits == 8 && a.signed); + assert!(b.bits == 8 && !b.signed); } _ => unreachable!(), } @@ -70,27 +70,27 @@ fn test_primitives() { let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(4)); - assert_eq!(ty.bit_width, 32); + assert_eq!(ty.bits, 32); assert!(ty.signed); let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(size_of::())); - assert_eq!(ty.bit_width, size_of::() * 8); + assert_eq!(ty.bits as usize, size_of::() * 8); assert!(ty.signed); let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(4)); - assert_eq!(ty.bit_width, 32); + assert_eq!(ty.bits, 32); assert!(!ty.signed); let Type { kind: Int(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(size_of::())); - assert_eq!(ty.bit_width, size_of::() * 8); + assert_eq!(ty.bits as usize, size_of::() * 8); assert!(!ty.signed); let Type { kind: Float(ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, Some(4)); - assert_eq!(ty.bit_width, 32); + assert_eq!(ty.bits, 32); let Type { kind: Str(_ty), size, .. } = (const { Type::of::() }) else { panic!() }; assert_eq!(size, None); diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout index 483efdbbd12a..c086cdd11aff 100644 --- a/tests/ui/reflection/dump.bit32.run.stdout +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -35,7 +35,7 @@ Type { Type { kind: Int( Int { - bit_width: 8, + bits: 8, signed: true, }, ), @@ -46,7 +46,7 @@ Type { Type { kind: Int( Int { - bit_width: 32, + bits: 32, signed: true, }, ), @@ -57,7 +57,7 @@ Type { Type { kind: Int( Int { - bit_width: 64, + bits: 64, signed: true, }, ), @@ -68,7 +68,7 @@ Type { Type { kind: Int( Int { - bit_width: 128, + bits: 128, signed: true, }, ), @@ -79,7 +79,7 @@ Type { Type { kind: Int( Int { - bit_width: 32, + bits: 32, signed: true, }, ), @@ -90,7 +90,7 @@ Type { Type { kind: Int( Int { - bit_width: 8, + bits: 8, signed: false, }, ), @@ -101,7 +101,7 @@ Type { Type { kind: Int( Int { - bit_width: 32, + bits: 32, signed: false, }, ), @@ -112,7 +112,7 @@ Type { Type { kind: Int( Int { - bit_width: 64, + bits: 64, signed: false, }, ), @@ -123,7 +123,7 @@ Type { Type { kind: Int( Int { - bit_width: 128, + bits: 128, signed: false, }, ), @@ -134,7 +134,7 @@ Type { Type { kind: Int( Int { - bit_width: 32, + bits: 32, signed: false, }, ), diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout index 681e81b71d56..5f82ab44a91d 100644 --- a/tests/ui/reflection/dump.bit64.run.stdout +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -35,7 +35,7 @@ Type { Type { kind: Int( Int { - bit_width: 8, + bits: 8, signed: true, }, ), @@ -46,7 +46,7 @@ Type { Type { kind: Int( Int { - bit_width: 32, + bits: 32, signed: true, }, ), @@ -57,7 +57,7 @@ Type { Type { kind: Int( Int { - bit_width: 64, + bits: 64, signed: true, }, ), @@ -68,7 +68,7 @@ Type { Type { kind: Int( Int { - bit_width: 128, + bits: 128, signed: true, }, ), @@ -79,7 +79,7 @@ Type { Type { kind: Int( Int { - bit_width: 64, + bits: 64, signed: true, }, ), @@ -90,7 +90,7 @@ Type { Type { kind: Int( Int { - bit_width: 8, + bits: 8, signed: false, }, ), @@ -101,7 +101,7 @@ Type { Type { kind: Int( Int { - bit_width: 32, + bits: 32, signed: false, }, ), @@ -112,7 +112,7 @@ Type { Type { kind: Int( Int { - bit_width: 64, + bits: 64, signed: false, }, ), @@ -123,7 +123,7 @@ Type { Type { kind: Int( Int { - bit_width: 128, + bits: 128, signed: false, }, ), @@ -134,7 +134,7 @@ Type { Type { kind: Int( Int { - bit_width: 64, + bits: 64, signed: false, }, ), From 4c93efae2b741b9df51fd55364ad08d57c2f196d Mon Sep 17 00:00:00 2001 From: Keith-Cancel Date: Tue, 13 Jan 2026 13:02:33 -0800 Subject: [PATCH 2264/3801] Fix ICE: When Trying to check visibility of a #[type_const], check RHS instead. We want to evaluate the rhs of a type_const. Also added an early return/guard in eval_in_interpreter which is used in functions like `eval_to_allocation_raw_provider` Lastly add a debug assert to `thir_body()` if we have gotten there with a type_const something as gone wrong. Get rid of a call to is_type_const() and instead use a match arm. Change this is_type_const() check to a debug_assert!() Change to use an if else statment instead. Update type_const-pub.rs Fix formatting. Noticed that this is the same check as is_type_const() centralize it. Add test case for pub type_const. --- .../rustc_const_eval/src/const_eval/eval_queries.rs | 4 +++- compiler/rustc_metadata/src/rmeta/encoder.rs | 5 ++--- compiler/rustc_mir_build/src/thir/cx/mod.rs | 2 ++ compiler/rustc_passes/src/reachable.rs | 5 ++++- tests/ui/const-generics/mgca/type_const-pub.rs | 10 ++++++++++ 5 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 tests/ui/const-generics/mgca/type_const-pub.rs diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index beea1b4a28c9..5383ab3547af 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -394,8 +394,10 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>( typing_env: ty::TypingEnv<'tcx>, ) -> Result { let def = cid.instance.def.def_id(); - let is_static = tcx.is_static(def); + // #[type_const] don't have bodys + debug_assert!(!tcx.is_type_const(def), "CTFE tried to evaluate type-const: {:?}", def); + let is_static = tcx.is_static(def); let mut ecx = InterpCx::new( tcx, tcx.def_span(def), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a62826cd7cec..4fcc7f064f3f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1379,9 +1379,8 @@ fn should_encode_const(def_kind: DefKind) -> bool { } fn should_encode_const_of_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: DefKind) -> bool { - matches!(def_kind, DefKind::Const | DefKind::AssocConst) - && find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) - // AssocConst ==> assoc item has value + // AssocConst ==> assoc item has value + tcx.is_type_const(def_id) && (!matches!(def_kind, DefKind::AssocConst) || assoc_item_has_value(tcx, def_id)) } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 79e85a243f40..b08d1d4bcf27 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -18,6 +18,8 @@ pub(crate) fn thir_body( tcx: TyCtxt<'_>, owner_def: LocalDefId, ) -> Result<(&Steal>, ExprId), ErrorGuaranteed> { + debug_assert!(!tcx.is_type_const(owner_def.to_def_id()), "thir_body queried for type_const"); + let body = tcx.hir_body_owned_by(owner_def); let mut cx = ThirBuildCx::new(tcx, owner_def); if let Some(reported) = cx.typeck_results.tainted_by_errors { diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index b9323e91ca83..d9565e2dae0e 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -209,7 +209,10 @@ impl<'tcx> ReachableContext<'tcx> { self.visit_nested_body(body); } } - + // For #[type_const] we want to evaluate the RHS. + hir::ItemKind::Const(_, _, _, init @ hir::ConstItemRhs::TypeConst(_)) => { + self.visit_const_item_rhs(init); + } hir::ItemKind::Const(_, _, _, init) => { // Only things actually ending up in the final constant value are reachable // for codegen. Everything else is only needed during const-eval, so even if diff --git a/tests/ui/const-generics/mgca/type_const-pub.rs b/tests/ui/const-generics/mgca/type_const-pub.rs new file mode 100644 index 000000000000..fc5b1ce36a14 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-pub.rs @@ -0,0 +1,10 @@ +//@ check-pass +// This previously caused an ICE when checking reachability of a pub const item +// This is because reachability also tried to evaluate the #[type_const] which +// requires the item have a body. #[type_const] do not have bodies. +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +#[type_const] +pub const TYPE_CONST : usize = 1; +fn main() {} From ac8e8505b7c12d826f970e8e8ec8c18b067c6dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 16 Jan 2026 21:08:01 +0100 Subject: [PATCH 2265/3801] rustdoc: Stop unconditionally evaluating the initializer of associated consts --- src/librustdoc/html/render/mod.rs | 9 ++--- .../anchors/anchors.no_const_anchor2.html | 2 +- tests/rustdoc-html/attributes.rs | 2 +- .../constant/assoc-const-has-projection-ty.rs | 31 +++++++++++++++++ tests/rustdoc-html/constant/assoc-consts.rs | 2 +- .../rustdoc-html/deref/deref-to-primitive.rs | 2 +- tests/rustdoc-html/display-hidden-items.rs | 4 +-- .../impl/impl-associated-items-order.rs | 4 +-- tests/rustdoc-ui/diverging-assoc-consts.rs | 33 +++++++++++++++++++ 9 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 tests/rustdoc-html/constant/assoc-const-has-projection-ty.rs create mode 100644 tests/rustdoc-ui/diverging-assoc-consts.rs diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 63de870f07f4..e6fca29e23e5 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1050,14 +1050,11 @@ fn assoc_const( ty = print_type(ty, cx), )?; if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value { - // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the - // hood which adds noisy underscores and a type suffix to number literals. - // This hurts readability in this context especially when more complex expressions - // are involved and it doesn't add much of value. - // Find a way to print constants here without all that jazz. - let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx)); + let repr = konst.expr(tcx); if match value { AssocConstValue::TraitDefault(_) => true, // always show + // FIXME: Comparing against the special string "_" denoting overly complex const exprs + // is rather hacky; `ConstKind::expr` should have a richer return type. AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show AssocConstValue::None => unreachable!(), } { diff --git a/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html b/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html index 091dac3e4b26..310957ac1ae0 100644 --- a/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html +++ b/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html @@ -1 +1 @@ -

    Source

    pub const X: i32 = 0i32

    \ No newline at end of file +
    Source

    pub const X: i32 = 0

    \ No newline at end of file diff --git a/tests/rustdoc-html/attributes.rs b/tests/rustdoc-html/attributes.rs index 429a42a7252c..6032c3d38801 100644 --- a/tests/rustdoc-html/attributes.rs +++ b/tests/rustdoc-html/attributes.rs @@ -59,7 +59,7 @@ pub enum Enum { pub trait Trait { //@ has 'foo/trait.Trait.html' //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[unsafe(link_section = "bar")]' - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0' #[unsafe(link_section = "bar")] const BAR: u32 = 0; diff --git a/tests/rustdoc-html/constant/assoc-const-has-projection-ty.rs b/tests/rustdoc-html/constant/assoc-const-has-projection-ty.rs new file mode 100644 index 000000000000..ed0789dade57 --- /dev/null +++ b/tests/rustdoc-html/constant/assoc-const-has-projection-ty.rs @@ -0,0 +1,31 @@ +// Ensure that we properly print the value `1` as `1` in the initializer of associated constants +// that have user type "projection". +// +// We once used to evaluate the initializer in rustdoc and use rustc's MIR pretty-printer to +// render the resulting MIR const value. This pretty printer matches on the type to interpret +// the data and falls back to a cryptic `"{transmute(0x$data): $ty}"` for types it can't handle. +// Crucially, when constructing the MIR const we passed the unnormalized type of the initializer, +// i.e., the projection `::Ty` instead of the normalized `u32` which the +// pretty printer obviously can't handle. +// +// Now we no longer evaluate it and use a custom printer for the const expr. +// +// issue: + +#![crate_name = "it"] + +pub trait Trait { + type Ty; + + const CT: Self::Ty; +} + +pub struct Struct; + +impl Trait for Struct { + type Ty = u32; + + //@ has it/struct.Struct.html + //@ has - '//*[@id="associatedconstant.CT"]' 'const CT: Self::Ty = 1' + const CT: Self::Ty = 1; +} diff --git a/tests/rustdoc-html/constant/assoc-consts.rs b/tests/rustdoc-html/constant/assoc-consts.rs index 247b5b180a86..0994ec7517e3 100644 --- a/tests/rustdoc-html/constant/assoc-consts.rs +++ b/tests/rustdoc-html/constant/assoc-consts.rs @@ -1,6 +1,6 @@ pub trait Foo { //@ has assoc_consts/trait.Foo.html '//pre[@class="rust item-decl"]' \ - // 'const FOO: usize = 13usize;' + // 'const FOO: usize = _;' //@ has - '//*[@id="associatedconstant.FOO"]' 'const FOO: usize' const FOO: usize = 12 + 1; //@ has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool' diff --git a/tests/rustdoc-html/deref/deref-to-primitive.rs b/tests/rustdoc-html/deref/deref-to-primitive.rs index 7a5a3cd8fd65..6fdc382b2213 100644 --- a/tests/rustdoc-html/deref/deref-to-primitive.rs +++ b/tests/rustdoc-html/deref/deref-to-primitive.rs @@ -3,7 +3,7 @@ //@ has 'foo/struct.Foo.html' //@ has - '//*[@id="deref-methods-i32"]' 'Methods from Deref' //@ has - '//*[@id="deref-methods-i32-1"]//*[@id="associatedconstant.BITS"]/h4' \ -// 'pub const BITS: u32 = 32u32' +// 'pub const BITS: u32 = u32::BITS' pub struct Foo(i32); impl std::ops::Deref for Foo { diff --git a/tests/rustdoc-html/display-hidden-items.rs b/tests/rustdoc-html/display-hidden-items.rs index 40cd636e2fe2..8b0854d1ade8 100644 --- a/tests/rustdoc-html/display-hidden-items.rs +++ b/tests/rustdoc-html/display-hidden-items.rs @@ -20,7 +20,7 @@ pub trait TraitHidden {} //@ has 'foo/index.html' '//dt/a[@class="trait"]' 'Trait' pub trait Trait { //@ has 'foo/trait.Trait.html' - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0' #[doc(hidden)] const BAR: u32 = 0; @@ -44,7 +44,7 @@ impl Struct { } impl Trait for Struct { - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0' //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' '#[doc(hidden)] fn foo()' } //@ has - '//*[@id="impl-TraitHidden-for-Struct"]/*[@class="code-header"]' 'impl TraitHidden for Struct' diff --git a/tests/rustdoc-html/impl/impl-associated-items-order.rs b/tests/rustdoc-html/impl/impl-associated-items-order.rs index 759e0f0b4009..3f1d04720163 100644 --- a/tests/rustdoc-html/impl/impl-associated-items-order.rs +++ b/tests/rustdoc-html/impl/impl-associated-items-order.rs @@ -16,7 +16,7 @@ impl Bar { // 'pub fn foo()' pub fn foo() {} //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[1]/h4' \ - // 'pub const X: u8 = 12u8' + // 'pub const X: u8 = 12' pub const X: u8 = 12; //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[2]/h4' \ // 'pub type Y = u8' @@ -34,7 +34,7 @@ impl Foo for Bar { // 'type Z = u8' type Z = u8; //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[1]/h4' \ - // 'const W: u32 = 12u32' + // 'const W: u32 = 12' const W: u32 = 12; //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[3]/h4' \ // 'fn yeay()' diff --git a/tests/rustdoc-ui/diverging-assoc-consts.rs b/tests/rustdoc-ui/diverging-assoc-consts.rs new file mode 100644 index 000000000000..fd0a177e7c4b --- /dev/null +++ b/tests/rustdoc-ui/diverging-assoc-consts.rs @@ -0,0 +1,33 @@ +// Ensure that we don't unconditionally evaluate the initializer of associated constants. +// +// We once used to evaluate them so we could display more kinds of expressions +// (like `1 + 1` as `2`) given the fact that we generally only want to render +// literals (otherwise we would risk dumping extremely large exprs or leaking +// private struct fields). +// +// However, that deviated from rustc's behavior, made rustdoc accept less code +// and was understandably surprising to users. So let's not. +// +// In the future we *might* provide users a mechanism to control this behavior. +// E.g., via a new `#[doc(...)]` attribute. +// +// See also: +// issue: +// issue: + +//@ check-pass + +pub struct Type; + +impl Type { + pub const K0: () = panic!(); + pub const K1: std::convert::Infallible = loop {}; +} + +pub trait Trait { + const K2: i32 = panic!(); +} + +impl Trait for Type { + const K2: i32 = loop {}; +} From 36e6625457599bccf2a5067110b47de82802a9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 16 Jan 2026 21:08:01 +0100 Subject: [PATCH 2266/3801] [beta] rustdoc: Stop unconditionally evaluating the initializer of associated consts --- src/librustdoc/html/render/mod.rs | 9 ++--- tests/rustdoc-ui/diverging-assoc-consts.rs | 33 +++++++++++++++++++ .../anchors/anchors.no_const_anchor2.html | 2 +- tests/rustdoc/attributes.rs | 2 +- .../constant/assoc-const-has-projection-ty.rs | 31 +++++++++++++++++ tests/rustdoc/constant/assoc-consts.rs | 2 +- tests/rustdoc/deref/deref-to-primitive.rs | 2 +- tests/rustdoc/display-hidden-items.rs | 4 +-- .../impl/impl-associated-items-order.rs | 4 +-- 9 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 tests/rustdoc-ui/diverging-assoc-consts.rs create mode 100644 tests/rustdoc/constant/assoc-const-has-projection-ty.rs diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 8740b5935973..2e7a0f46d8cc 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1049,14 +1049,11 @@ fn assoc_const( ty = print_type(ty, cx), )?; if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value { - // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the - // hood which adds noisy underscores and a type suffix to number literals. - // This hurts readability in this context especially when more complex expressions - // are involved and it doesn't add much of value. - // Find a way to print constants here without all that jazz. - let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx)); + let repr = konst.expr(tcx); if match value { AssocConstValue::TraitDefault(_) => true, // always show + // FIXME: Comparing against the special string "_" denoting overly complex const exprs + // is rather hacky; `ConstKind::expr` should have a richer return type. AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show AssocConstValue::None => unreachable!(), } { diff --git a/tests/rustdoc-ui/diverging-assoc-consts.rs b/tests/rustdoc-ui/diverging-assoc-consts.rs new file mode 100644 index 000000000000..fd0a177e7c4b --- /dev/null +++ b/tests/rustdoc-ui/diverging-assoc-consts.rs @@ -0,0 +1,33 @@ +// Ensure that we don't unconditionally evaluate the initializer of associated constants. +// +// We once used to evaluate them so we could display more kinds of expressions +// (like `1 + 1` as `2`) given the fact that we generally only want to render +// literals (otherwise we would risk dumping extremely large exprs or leaking +// private struct fields). +// +// However, that deviated from rustc's behavior, made rustdoc accept less code +// and was understandably surprising to users. So let's not. +// +// In the future we *might* provide users a mechanism to control this behavior. +// E.g., via a new `#[doc(...)]` attribute. +// +// See also: +// issue: +// issue: + +//@ check-pass + +pub struct Type; + +impl Type { + pub const K0: () = panic!(); + pub const K1: std::convert::Infallible = loop {}; +} + +pub trait Trait { + const K2: i32 = panic!(); +} + +impl Trait for Type { + const K2: i32 = loop {}; +} diff --git a/tests/rustdoc/anchors/anchors.no_const_anchor2.html b/tests/rustdoc/anchors/anchors.no_const_anchor2.html index 091dac3e4b26..310957ac1ae0 100644 --- a/tests/rustdoc/anchors/anchors.no_const_anchor2.html +++ b/tests/rustdoc/anchors/anchors.no_const_anchor2.html @@ -1 +1 @@ -
    Source

    pub const X: i32 = 0i32

    \ No newline at end of file +
    Source

    pub const X: i32 = 0

    \ No newline at end of file diff --git a/tests/rustdoc/attributes.rs b/tests/rustdoc/attributes.rs index 429a42a7252c..6032c3d38801 100644 --- a/tests/rustdoc/attributes.rs +++ b/tests/rustdoc/attributes.rs @@ -59,7 +59,7 @@ pub enum Enum { pub trait Trait { //@ has 'foo/trait.Trait.html' //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[unsafe(link_section = "bar")]' - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0' #[unsafe(link_section = "bar")] const BAR: u32 = 0; diff --git a/tests/rustdoc/constant/assoc-const-has-projection-ty.rs b/tests/rustdoc/constant/assoc-const-has-projection-ty.rs new file mode 100644 index 000000000000..ed0789dade57 --- /dev/null +++ b/tests/rustdoc/constant/assoc-const-has-projection-ty.rs @@ -0,0 +1,31 @@ +// Ensure that we properly print the value `1` as `1` in the initializer of associated constants +// that have user type "projection". +// +// We once used to evaluate the initializer in rustdoc and use rustc's MIR pretty-printer to +// render the resulting MIR const value. This pretty printer matches on the type to interpret +// the data and falls back to a cryptic `"{transmute(0x$data): $ty}"` for types it can't handle. +// Crucially, when constructing the MIR const we passed the unnormalized type of the initializer, +// i.e., the projection `::Ty` instead of the normalized `u32` which the +// pretty printer obviously can't handle. +// +// Now we no longer evaluate it and use a custom printer for the const expr. +// +// issue: + +#![crate_name = "it"] + +pub trait Trait { + type Ty; + + const CT: Self::Ty; +} + +pub struct Struct; + +impl Trait for Struct { + type Ty = u32; + + //@ has it/struct.Struct.html + //@ has - '//*[@id="associatedconstant.CT"]' 'const CT: Self::Ty = 1' + const CT: Self::Ty = 1; +} diff --git a/tests/rustdoc/constant/assoc-consts.rs b/tests/rustdoc/constant/assoc-consts.rs index 247b5b180a86..0994ec7517e3 100644 --- a/tests/rustdoc/constant/assoc-consts.rs +++ b/tests/rustdoc/constant/assoc-consts.rs @@ -1,6 +1,6 @@ pub trait Foo { //@ has assoc_consts/trait.Foo.html '//pre[@class="rust item-decl"]' \ - // 'const FOO: usize = 13usize;' + // 'const FOO: usize = _;' //@ has - '//*[@id="associatedconstant.FOO"]' 'const FOO: usize' const FOO: usize = 12 + 1; //@ has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool' diff --git a/tests/rustdoc/deref/deref-to-primitive.rs b/tests/rustdoc/deref/deref-to-primitive.rs index 7a5a3cd8fd65..6fdc382b2213 100644 --- a/tests/rustdoc/deref/deref-to-primitive.rs +++ b/tests/rustdoc/deref/deref-to-primitive.rs @@ -3,7 +3,7 @@ //@ has 'foo/struct.Foo.html' //@ has - '//*[@id="deref-methods-i32"]' 'Methods from Deref' //@ has - '//*[@id="deref-methods-i32-1"]//*[@id="associatedconstant.BITS"]/h4' \ -// 'pub const BITS: u32 = 32u32' +// 'pub const BITS: u32 = u32::BITS' pub struct Foo(i32); impl std::ops::Deref for Foo { diff --git a/tests/rustdoc/display-hidden-items.rs b/tests/rustdoc/display-hidden-items.rs index 40cd636e2fe2..8b0854d1ade8 100644 --- a/tests/rustdoc/display-hidden-items.rs +++ b/tests/rustdoc/display-hidden-items.rs @@ -20,7 +20,7 @@ pub trait TraitHidden {} //@ has 'foo/index.html' '//dt/a[@class="trait"]' 'Trait' pub trait Trait { //@ has 'foo/trait.Trait.html' - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0' #[doc(hidden)] const BAR: u32 = 0; @@ -44,7 +44,7 @@ impl Struct { } impl Trait for Struct { - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0' //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' '#[doc(hidden)] fn foo()' } //@ has - '//*[@id="impl-TraitHidden-for-Struct"]/*[@class="code-header"]' 'impl TraitHidden for Struct' diff --git a/tests/rustdoc/impl/impl-associated-items-order.rs b/tests/rustdoc/impl/impl-associated-items-order.rs index 759e0f0b4009..3f1d04720163 100644 --- a/tests/rustdoc/impl/impl-associated-items-order.rs +++ b/tests/rustdoc/impl/impl-associated-items-order.rs @@ -16,7 +16,7 @@ impl Bar { // 'pub fn foo()' pub fn foo() {} //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[1]/h4' \ - // 'pub const X: u8 = 12u8' + // 'pub const X: u8 = 12' pub const X: u8 = 12; //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[2]/h4' \ // 'pub type Y = u8' @@ -34,7 +34,7 @@ impl Foo for Bar { // 'type Z = u8' type Z = u8; //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[1]/h4' \ - // 'const W: u32 = 12u32' + // 'const W: u32 = 12' const W: u32 = 12; //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[3]/h4' \ // 'fn yeay()' From ebfd22796fa3eb0bc52612ce7b45cd789f8cb089 Mon Sep 17 00:00:00 2001 From: Oscar Bray Date: Sat, 17 Jan 2026 12:02:37 +0000 Subject: [PATCH 2267/3801] Port #[needs_allocator] to attribute parser --- compiler/rustc_attr_parsing/src/attributes/link_attrs.rs | 9 +++++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 61f975555884..2a04b55f469e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -658,3 +658,12 @@ impl SingleAttributeParser for LinkageParser { Some(AttributeKind::Linkage(linkage, cx.attr_span)) } } + +pub(crate) struct NeedsAllocatorParser; + +impl NoArgsAttributeParser for NeedsAllocatorParser { + const PATH: &[Symbol] = &[sym::needs_allocator]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsAllocator; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 2a2fccd32202..449894f7834b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -41,7 +41,7 @@ use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; use crate::attributes::instruction_set::InstructionSetParser; use crate::attributes::link_attrs::{ ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser, - LinkParser, LinkSectionParser, LinkageParser, StdInternalSymbolParser, + LinkParser, LinkSectionParser, LinkageParser, NeedsAllocatorParser, StdInternalSymbolParser, }; use crate::attributes::lint_helpers::{ AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser, @@ -259,6 +259,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 126fb8eac11b..7b7fae9fdcca 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -840,6 +840,9 @@ pub enum AttributeKind { /// Represents `#[naked]` Naked(Span), + /// Represents `#[needs_allocator]` + NeedsAllocator, + /// Represents `#[no_core]` NoCore(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 760e7c76df35..dff8a5727771 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -75,6 +75,7 @@ impl AttributeKind { MustNotSupend { .. } => Yes, MustUse { .. } => Yes, Naked(..) => No, + NeedsAllocator => No, NoCore(..) => No, NoImplicitPrelude(..) => No, NoLink => No, diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a62826cd7cec..dbcb44e3220e 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -742,7 +742,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { proc_macro_data, debugger_visualizers, compiler_builtins: ast::attr::contains_name(attrs, sym::compiler_builtins), - needs_allocator: ast::attr::contains_name(attrs, sym::needs_allocator), + needs_allocator: find_attr!(attrs, AttributeKind::NeedsAllocator), needs_panic_runtime: ast::attr::contains_name(attrs, sym::needs_panic_runtime), no_builtins: ast::attr::contains_name(attrs, sym::no_builtins), panic_runtime: ast::attr::contains_name(attrs, sym::panic_runtime), diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index f57bd62d3e99..4b71d4755cb6 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -315,6 +315,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDumpPredicates | AttributeKind::RustcDumpDefParents | AttributeKind::RustcDumpVtable(..) + | AttributeKind::NeedsAllocator ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -346,7 +347,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::prelude_import | sym::panic_handler | sym::lang - | sym::needs_allocator | sym::default_lib_allocator | sym::rustc_diagnostic_item | sym::rustc_no_mir_inline From c31698b6958b5c818e4f4c86d3e4d12e128152f9 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 17 Jan 2026 19:24:19 +0800 Subject: [PATCH 2268/3801] Improve move_guard redundanted block Example --- ```rust fn main() { match 92 { x $0if x > 10 => { let _ = true; false }, _ => true } } ``` **Before this PR** ```rust fn main() { match 92 { x => if x > 10 { { let _ = true; false } }, _ => true } } ``` **After this PR** ```rust fn main() { match 92 { x => if x > 10 { let _ = true; false }, _ => true } } ``` --- .../ide-assists/src/handlers/move_guard.rs | 35 ++++++++++++++++--- .../crates/ide-assists/src/utils.rs | 11 ++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs index 31baa63372ff..84f02bdfdba6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs @@ -49,7 +49,7 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext<'_>) let guard_condition = guard.condition()?.reset_indent(); let arm_expr = match_arm.expr()?; - let then_branch = make::block_expr(None, Some(arm_expr.reset_indent().indent(1.into()))); + let then_branch = crate::utils::wrap_block(&arm_expr); let if_expr = make::expr_if(guard_condition, then_branch, None).indent(arm_expr.indent_level()); let target = guard.syntax().text_range(); @@ -344,6 +344,35 @@ fn main() { ); } + #[test] + fn move_guard_to_block_arm_body_works() { + check_assist( + move_guard_to_arm_body, + r#" +fn main() { + match 92 { + x $0if x > 10 => { + let _ = true; + false + }, + _ => true + } +} +"#, + r#" +fn main() { + match 92 { + x => if x > 10 { + let _ = true; + false + }, + _ => true + } +} +"#, + ); + } + #[test] fn move_let_guard_to_arm_body_works() { check_assist( @@ -395,9 +424,7 @@ fn main() { && true && true { { - { - false - } + false } }, _ => true diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 9a96374c00af..4b8c19305793 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -86,6 +86,17 @@ pub fn extract_trivial_expression(block_expr: &ast::BlockExpr) -> Option ast::BlockExpr { + if let ast::Expr::BlockExpr(block) = expr + && let Some(first) = block.syntax().first_token() + && first.kind() == T!['{'] + { + block.reset_indent() + } else { + make::block_expr(None, Some(expr.reset_indent().indent(1.into()))) + } +} + /// This is a method with a heuristics to support test methods annotated with custom test annotations, such as /// `#[test_case(...)]`, `#[tokio::test]` and similar. /// Also a regular `#[test]` annotation is supported. From fe63539778fd3ae3b7aae1e03b96f10991f41d16 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 17 Jan 2026 14:18:11 +0100 Subject: [PATCH 2269/3801] Explicitly list crate level attrs --- compiler/rustc_passes/src/check_attr.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index f57bd62d3e99..a4aed2b92804 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -389,13 +389,25 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_partition_reused | sym::rustc_partition_codegened | sym::rustc_expected_cgu_reuse - | sym::rustc_nounwind, + | sym::rustc_nounwind + // crate-level attrs, are checked below + | sym::feature + | sym::register_tool + | sym::rustc_no_implicit_bounds + | sym::test_runner + | sym::reexport_test_harness_main + | sym::no_main + | sym::no_builtins + | sym::crate_type + | sym::compiler_builtins + | sym::profiler_runtime + | sym::needs_panic_runtime + | sym::panic_runtime + | sym::rustc_preserve_ub_checks, .. ] => {} [name, rest@..] => { match BUILTIN_ATTRIBUTE_MAP.get(name) { - // checked below - Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {} Some(_) => { if rest.len() > 0 && AttributeParser::::is_parsed_attribute(slice::from_ref(name)) { // Check if we tried to use a builtin attribute as an attribute namespace, like `#[must_use::skip]`. From ad3e082afe997060dc1be247dc227db3e8d250d6 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 17 Jan 2026 10:19:26 -0500 Subject: [PATCH 2270/3801] Bump version to 1.95.0 --- src/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version b/src/version index 8db4a57b3d02..55f6ae93382d 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.94.0 +1.95.0 From 308b736541d4fdc000cf8abb1577f0d55e05c77c Mon Sep 17 00:00:00 2001 From: Redddy Date: Thu, 15 Jan 2026 23:56:14 +0900 Subject: [PATCH 2271/3801] Added section on using GitHub Dev for PR inspection --- src/doc/rustc-dev-guide/src/git.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md index e7e84e2ea7f5..abe72b29cb1e 100644 --- a/src/doc/rustc-dev-guide/src/git.md +++ b/src/doc/rustc-dev-guide/src/git.md @@ -495,6 +495,14 @@ command to check it out locally. See for more info. ![`gh` suggestion](./img/github-cli.png) +### Using GitHub dev + +As an alternative to the GitHub web UI, GitHub Dev provides a web-based editor for browsing +repository and PRs. It can be opened by replacing `github.com` with `github.dev` in the URL +or by pressing `.` on a GitHub page. +See [the docs for github.dev editor](https://docs.github.com/en/codespaces/the-githubdev-web-based-editor) +for more details. + ### Moving large sections of code Git and Github's default diff view for large moves *within* a file is quite poor; it will show each From b3a5f53e8f50e5c2532b52cb7dc9222692e739f4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 17 Jan 2026 17:02:46 +0100 Subject: [PATCH 2272/3801] rustdoc: Fix ICE when deprecated note is not resolved on the correct `DefId` --- .../passes/collect_intra_doc_links.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 018e20b76dc8..a68e9dc87ae5 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -11,10 +11,11 @@ use rustc_ast::util::comments::may_have_doc_links; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_errors::{Applicability, Diag, DiagMessage}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::Namespace::*; use rustc_hir::def::{DefKind, MacroKinds, Namespace, PerNS}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE}; -use rustc_hir::{Mutability, Safety}; +use rustc_hir::{Attribute, Mutability, Safety}; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::{bug, span_bug, ty}; use rustc_resolve::rustdoc::pulldown_cmark::LinkType; @@ -1108,10 +1109,8 @@ impl LinkCollector<'_, '_> { // Also resolve links in the note text of `#[deprecated]`. for attr in &item.attrs.other_attrs { - let rustc_hir::Attribute::Parsed(rustc_hir::attrs::AttributeKind::Deprecation { - span, - deprecation, - }) = attr + let Attribute::Parsed(AttributeKind::Deprecation { span: depr_span, deprecation }) = + attr else { continue; }; @@ -1128,8 +1127,14 @@ impl LinkCollector<'_, '_> { // inlined item. // let item_id = if let Some(inline_stmt_id) = item.inline_stmt_id - && item.span(tcx).is_none_or(|item_span| !item_span.inner().contains(*span)) - { + && tcx.get_all_attrs(inline_stmt_id).iter().any(|attr| { + matches!( + attr, + Attribute::Parsed(AttributeKind::Deprecation { + span: attr_span, .. + }) if attr_span == depr_span, + ) + }) { inline_stmt_id.to_def_id() } else { item.item_id.expect_def_id() From 1faaa769615cda3c662f96b5f48678e6f97ee245 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 17 Jan 2026 17:03:04 +0100 Subject: [PATCH 2273/3801] Add regression test for ICE when deprecated note is not resolved on the correct `DefId` --- .../deprecated-note-from-reexported.rs | 16 +++++++++ .../deprecated-note-from-reexported.stderr | 34 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs create mode 100644 tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr diff --git a/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs new file mode 100644 index 000000000000..3d1e48a4c638 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs @@ -0,0 +1,16 @@ +// This test ensures that the intra-doc link from reexported deprecated attribute note +// are resolved where they are declared. + +#![deny(rustdoc::broken_intra_doc_links)] + +#[doc(inline)] +pub use bar::sql_function_proc as sql_function; + +pub fn define_sql_function() {} + +pub mod bar { + #[deprecated(note = "Use [`define_sql_function`] instead")] + //~^ ERROR: unresolved link + //~| ERROR: unresolved link + pub fn sql_function_proc() {} +} diff --git a/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr new file mode 100644 index 000000000000..25f10b24d9fb --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr @@ -0,0 +1,34 @@ +error: unresolved link to `define_sql_function` + --> $DIR/deprecated-note-from-reexported.rs:12:25 + | +LL | #[deprecated(note = "Use [`define_sql_function`] instead")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + Use [`define_sql_function`] instead + ^^^^^^^^^^^^^^^^^^^^^ + = note: no item named `define_sql_function` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/deprecated-note-from-reexported.rs:4:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `define_sql_function` + --> $DIR/deprecated-note-from-reexported.rs:12:25 + | +LL | #[deprecated(note = "Use [`define_sql_function`] instead")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + Use [`define_sql_function`] instead + ^^^^^^^^^^^^^^^^^^^^^ + = note: no item named `define_sql_function` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + From a0f9a15b4a916c92d51131418e9fe080c83f9d3c Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Sat, 17 Jan 2026 11:36:25 +0100 Subject: [PATCH 2274/3801] Fix is_ascii performance regression on AVX-512 CPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `[u8]::is_ascii()` is compiled with `-C target-cpu=native` on AVX-512 CPUs, LLVM generates inefficient code. Because `is_ascii` is marked `#[inline]`, it gets inlined and recompiled with the user's target settings. The previous implementation used a counting loop that LLVM auto-vectorizes to `pmovmskb` on SSE2, but with AVX-512 enabled, LLVM uses k-registers and extracts bits individually with ~31 `kshiftrd` instructions. This fix replaces the counting loop with explicit SSE2 intrinsics (`_mm_loadu_si128`, `_mm_or_si128`, `_mm_movemask_epi8`) for x86_64. `_mm_movemask_epi8` compiles to `pmovmskb`, forcing efficient codegen regardless of CPU features. Benchmark results on AMD Ryzen 5 7500F (Zen 4 with AVX-512): - Default build: ~73 GB/s → ~74 GB/s (no regression) - With -C target-cpu=native: ~3 GB/s → ~67 GB/s (22x improvement) The loongarch64 implementation retains the original counting loop since it doesn't have this issue. Regression from: https://github.com/rust-lang/rust/pull/130733 --- library/core/src/slice/ascii.rs | 86 +++++++++++++++++--- tests/assembly-llvm/slice-is-ascii-avx512.rs | 18 ++++ tests/codegen-llvm/slice-is-ascii.rs | 9 +- 3 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 tests/assembly-llvm/slice-is-ascii-avx512.rs diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 3e8c553f9f15..c9e168d6cbf8 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -3,10 +3,7 @@ use core::ascii::EscapeDefault; use crate::fmt::{self, Write}; -#[cfg(not(any( - all(target_arch = "x86_64", target_feature = "sse2"), - all(target_arch = "loongarch64", target_feature = "lsx") -)))] +#[cfg(not(all(target_arch = "loongarch64", target_feature = "lsx")))] use crate::intrinsics::const_eval_select; use crate::{ascii, iter, ops}; @@ -463,19 +460,84 @@ const fn is_ascii(s: &[u8]) -> bool { ) } -/// ASCII test optimized to use the `pmovmskb` instruction on `x86-64` and the -/// `vmskltz.b` instruction on `loongarch64`. +/// SSE2 implementation using `_mm_movemask_epi8` (compiles to `pmovmskb`) to +/// avoid LLVM's broken AVX-512 auto-vectorization of counting loops. +/// +/// # Safety +/// Requires SSE2 support (guaranteed on x86_64). +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +#[target_feature(enable = "sse2")] +unsafe fn is_ascii_sse2(bytes: &[u8]) -> bool { + use crate::arch::x86_64::{__m128i, _mm_loadu_si128, _mm_movemask_epi8, _mm_or_si128}; + + const CHUNK_SIZE: usize = 32; + + let mut i = 0; + + while i + CHUNK_SIZE <= bytes.len() { + // SAFETY: We have verified that `i + CHUNK_SIZE <= bytes.len()`. + let ptr = unsafe { bytes.as_ptr().add(i) }; + + // Load two 16-byte chunks and combine them. + // SAFETY: We verified `i + 32 <= len`, so ptr is valid for 32 bytes. + // `_mm_loadu_si128` allows unaligned loads. + let chunk1 = unsafe { _mm_loadu_si128(ptr as *const __m128i) }; + // SAFETY: Same as above - ptr.add(16) is within the valid 32-byte range. + let chunk2 = unsafe { _mm_loadu_si128(ptr.add(16) as *const __m128i) }; + + // OR them together - if any byte has the high bit set, the result will too + let combined = _mm_or_si128(chunk1, chunk2); + + // Create a mask from the MSBs of each byte. + // If any byte is >= 128, its MSB is 1, so the mask will be non-zero. + let mask = _mm_movemask_epi8(combined); + + if mask != 0 { + return false; + } + + i += CHUNK_SIZE; + } + + // Handle remaining bytes with simple loop + while i < bytes.len() { + if !bytes[i].is_ascii() { + return false; + } + i += 1; + } + + true +} + +/// ASCII test optimized to use the `pmovmskb` instruction on `x86-64`. +/// +/// Uses explicit SSE2 intrinsics to prevent LLVM from auto-vectorizing with +/// broken AVX-512 code that extracts mask bits one-by-one. +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +#[inline] +#[rustc_allow_const_fn_unstable(const_eval_select)] +const fn is_ascii(bytes: &[u8]) -> bool { + const_eval_select!( + @capture { bytes: &[u8] } -> bool: + if const { + is_ascii_simple(bytes) + } else { + // SAFETY: SSE2 is guaranteed available on x86_64 + unsafe { is_ascii_sse2(bytes) } + } + ) +} + +/// ASCII test optimized to use the `vmskltz.b` instruction on `loongarch64`. /// /// Other platforms are not likely to benefit from this code structure, so they /// use SWAR techniques to test for ASCII in `usize`-sized chunks. -#[cfg(any( - all(target_arch = "x86_64", target_feature = "sse2"), - all(target_arch = "loongarch64", target_feature = "lsx") -))] +#[cfg(all(target_arch = "loongarch64", target_feature = "lsx"))] #[inline] const fn is_ascii(bytes: &[u8]) -> bool { // Process chunks of 32 bytes at a time in the fast path to enable - // auto-vectorization and use of `pmovmskb`. Two 128-bit vector registers + // auto-vectorization and use of `vmskltz.b`. Two 128-bit vector registers // can be OR'd together and then the resulting vector can be tested for // non-ASCII bytes. const CHUNK_SIZE: usize = 32; @@ -485,7 +547,7 @@ const fn is_ascii(bytes: &[u8]) -> bool { while i + CHUNK_SIZE <= bytes.len() { let chunk_end = i + CHUNK_SIZE; - // Get LLVM to produce a `pmovmskb` instruction on x86-64 which + // Get LLVM to produce a `vmskltz.b` instruction on loongarch64 which // creates a mask from the most significant bit of each byte. // ASCII bytes are less than 128 (0x80), so their most significant // bit is unset. diff --git a/tests/assembly-llvm/slice-is-ascii-avx512.rs b/tests/assembly-llvm/slice-is-ascii-avx512.rs new file mode 100644 index 000000000000..d3a441fec96c --- /dev/null +++ b/tests/assembly-llvm/slice-is-ascii-avx512.rs @@ -0,0 +1,18 @@ +//@ only-x86_64 +//@ compile-flags: -C opt-level=3 -C target-cpu=znver4 +//@ compile-flags: -C llvm-args=-x86-asm-syntax=intel +//@ assembly-output: emit-asm +#![crate_type = "lib"] + +// Verify is_ascii uses pmovmskb/vpmovmskb instead of kshiftrd with AVX-512. +// The fix uses explicit SSE2 intrinsics to avoid LLVM's broken auto-vectorization. +// +// See: https://github.com/rust-lang/rust/issues/129293 + +// CHECK-LABEL: test_is_ascii +#[no_mangle] +pub fn test_is_ascii(s: &[u8]) -> bool { + // CHECK-NOT: kshiftrd + // CHECK-NOT: kshiftrq + s.is_ascii() +} diff --git a/tests/codegen-llvm/slice-is-ascii.rs b/tests/codegen-llvm/slice-is-ascii.rs index 67537c871a0a..1f41b69e4396 100644 --- a/tests/codegen-llvm/slice-is-ascii.rs +++ b/tests/codegen-llvm/slice-is-ascii.rs @@ -1,10 +1,13 @@ -//@ only-x86_64 -//@ compile-flags: -C opt-level=3 -C target-cpu=x86-64 +//@ only-loongarch64 +//@ compile-flags: -C opt-level=3 #![crate_type = "lib"] -/// Check that the fast-path of `is_ascii` uses a `pmovmskb` instruction. +/// Check that the fast-path of `is_ascii` uses a `vmskltz.b` instruction. /// Platforms lacking an equivalent instruction use other techniques for /// optimizing `is_ascii`. +/// +/// Note: x86_64 uses explicit SSE2 intrinsics instead of relying on +/// auto-vectorization. See `slice-is-ascii-avx512.rs`. // CHECK-LABEL: @is_ascii_autovectorized #[no_mangle] pub fn is_ascii_autovectorized(s: &[u8]) -> bool { From 4d2f6a0843b161df938c341ecf142e636cd54b5b Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sun, 18 Jan 2026 04:34:46 +0900 Subject: [PATCH 2275/3801] fix ICE on inconsistent import resolution with macro-attributed extern crate --- compiler/rustc_resolve/src/imports.rs | 2 +- .../resolve/ice-inconsistent-resolution-151213.rs | 14 ++++++++++++++ .../ice-inconsistent-resolution-151213.stderr | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/ui/resolve/ice-inconsistent-resolution-151213.rs create mode 100644 tests/ui/resolve/ice-inconsistent-resolution-151213.stderr diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 451779ae32c6..016fc407daab 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -989,7 +989,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { PathResult::Module(module) => { // Consistency checks, analogous to `finalize_macro_resolutions`. if let Some(initial_module) = import.imported_module.get() { - if module != initial_module && no_ambiguity { + if module != initial_module && no_ambiguity && !self.issue_145575_hack_applied { span_bug!(import.span, "inconsistent resolution for an import"); } } else if self.privacy_errors.is_empty() { diff --git a/tests/ui/resolve/ice-inconsistent-resolution-151213.rs b/tests/ui/resolve/ice-inconsistent-resolution-151213.rs new file mode 100644 index 000000000000..ea0f1c2858ef --- /dev/null +++ b/tests/ui/resolve/ice-inconsistent-resolution-151213.rs @@ -0,0 +1,14 @@ +//@ edition: 2024 + +#[attr] +//~^ ERROR cannot find attribute `attr` in this scope +extern crate core as std; +//~^ ERROR macro-expanded `extern crate` items cannot shadow names passed with `--extern` + +mod inner { + use std::str; + + use crate::*; +} + +fn main() {} diff --git a/tests/ui/resolve/ice-inconsistent-resolution-151213.stderr b/tests/ui/resolve/ice-inconsistent-resolution-151213.stderr new file mode 100644 index 000000000000..deb1e6c3e1cf --- /dev/null +++ b/tests/ui/resolve/ice-inconsistent-resolution-151213.stderr @@ -0,0 +1,14 @@ +error: macro-expanded `extern crate` items cannot shadow names passed with `--extern` + --> $DIR/ice-inconsistent-resolution-151213.rs:5:1 + | +LL | extern crate core as std; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot find attribute `attr` in this scope + --> $DIR/ice-inconsistent-resolution-151213.rs:3:3 + | +LL | #[attr] + | ^^^^ + +error: aborting due to 2 previous errors + From a8201d341a8b5b456eff782f32197af6b6533038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 11 Jan 2026 10:35:13 +0100 Subject: [PATCH 2276/3801] Remove references to bors2 --- src/ci/github-actions/jobs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 9acad5c06b21..7411b394b94a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -152,8 +152,8 @@ try: - <<: *job-dist-x86_64-linux # Jobs that only run when explicitly invoked in one of the following ways: -# - comment `@bors2 try jobs=` -# - `try-job: ` in the PR description and comment `@bors try` or `@bors2 try`. +# - comment `@bors try jobs=` +# - `try-job: ` in the PR description and comment `@bors try`. optional: # This job is used just to test optional jobs. # It will be replaced by tier 2 and tier 3 jobs in the future. From 4c28b43a948cdcd98f21283fe49d8c30883cd1bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 11 Jan 2026 10:38:58 +0100 Subject: [PATCH 2277/3801] Revert bors email to the original homu one --- src/build_helper/src/git.rs | 19 ++++++++++--------- src/stage0 | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 1fdc2ddb4cfc..330fb465de42 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -152,7 +152,10 @@ pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool { }) } -const LEGACY_BORS_EMAIL: &str = "bors@rust-lang.org"; +// Temporary e-mail used by new bors for merge commits for a few days, until it learned how to reuse +// the original homu e-mail +// FIXME: remove in Q2 2026 +const TEMPORARY_BORS_EMAIL: &str = "122020455+rust-bors[bot]@users.noreply.github.com"; /// Escape characters from the git user e-mail, so that git commands do not interpret it as regex /// special characters. @@ -193,10 +196,9 @@ fn get_latest_upstream_commit_that_modified_files( &escape_email_git_regex(git_config.git_merge_commit_email), ]); - // Also search for legacy bors account, before we accrue enough commits to - // have changes to all relevant file paths done by new bors. - if git_config.git_merge_commit_email != LEGACY_BORS_EMAIL { - git.args(["--author", LEGACY_BORS_EMAIL]); + // Also search for temporary bors account + if git_config.git_merge_commit_email != TEMPORARY_BORS_EMAIL { + git.args(["--author", &escape_email_git_regex(TEMPORARY_BORS_EMAIL)]); } if !target_paths.is_empty() { @@ -248,10 +250,9 @@ pub fn get_closest_upstream_commit( base, ]); - // Also search for legacy bors account, before we accrue enough commits to - // have changes to all relevant file paths done by new bors. - if config.git_merge_commit_email != LEGACY_BORS_EMAIL { - git.args(["--author", LEGACY_BORS_EMAIL]); + // Also search for temporary bors account + if config.git_merge_commit_email != TEMPORARY_BORS_EMAIL { + git.args(["--author", &escape_email_git_regex(TEMPORARY_BORS_EMAIL)]); } let output = output_result(&mut git)?.trim().to_owned(); diff --git a/src/stage0 b/src/stage0 index 0686ddef7d95..ea0fe3bf84c4 100644 --- a/src/stage0 +++ b/src/stage0 @@ -1,7 +1,7 @@ dist_server=https://static.rust-lang.org artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt -git_merge_commit_email=122020455+rust-bors[bot]@users.noreply.github.com +git_merge_commit_email=bors@rust-lang.org nightly_branch=main # The configuration above this comment is editable, and can be changed From 2b8a999ac43b386edc6472d6e34a1f50683c18f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 11 Jan 2026 10:40:40 +0100 Subject: [PATCH 2278/3801] Use both bors e-mails for CI postprocessing git lookup --- .github/workflows/ci.yml | 2 +- .github/workflows/post-merge.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb6bc325a3bb..2458eb5fafb1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -289,7 +289,7 @@ jobs: fi # Get closest bors merge commit - PARENT_COMMIT=`git rev-list --author='bors ' -n1 --first-parent HEAD^1` + PARENT_COMMIT=`git rev-list --author='bors@rust-lang.org' --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` ./build/citool/debug/citool postprocess-metrics \ --job-name ${CI_JOB_NAME} \ diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 51e0a40d46f2..c3d9217a645b 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -29,7 +29,7 @@ jobs: sleep 60 # Get closest bors merge commit - PARENT_COMMIT=`git rev-list --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` + PARENT_COMMIT=`git rev-list --author='bors@rust-lang.org' --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1` echo "Parent: ${PARENT_COMMIT}" # Find PR for the current commit From 6feceec6b3e782aab1ca914b800bf6cccdc560cb Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 17 Jan 2026 13:49:43 -0500 Subject: [PATCH 2279/3801] Disable SimplifyComparisonIntegral --- .../src/simplify_comparison_integral.rs | 2 +- tests/codegen-llvm/hint/likely.rs | 2 +- tests/codegen-llvm/hint/unlikely.rs | 2 +- tests/debuginfo/dummy_span.rs | 2 +- ...onential_common.GVN.32bit.panic-abort.diff | 44 +-- ...nential_common.GVN.32bit.panic-unwind.diff | 44 +-- ...onential_common.GVN.64bit.panic-abort.diff | 44 +-- ...nential_common.GVN.64bit.panic-unwind.diff | 44 +-- tests/mir-opt/issue_76432.rs | 1 + ...git.PreCodegen.after.32bit.panic-abort.mir | 41 +-- ...it.PreCodegen.after.32bit.panic-unwind.mir | 41 +-- ...git.PreCodegen.after.64bit.panic-abort.mir | 41 +-- ...it.PreCodegen.after.64bit.panic-unwind.mir | 41 +-- ...ace.PreCodegen.after.32bit.panic-abort.mir | 20 +- ...ce.PreCodegen.after.32bit.panic-unwind.mir | 20 +- ...ace.PreCodegen.after.64bit.panic-abort.mir | 20 +- ...ce.PreCodegen.after.64bit.panic-unwind.mir | 20 +- .../loops.vec_move.PreCodegen.after.mir | 306 ++---------------- ...ated_loop.PreCodegen.after.panic-abort.mir | 137 ++++---- ...ward_loop.PreCodegen.after.panic-abort.mir | 81 ++--- ...ard_loop.PreCodegen.after.panic-unwind.mir | 111 ++++--- ...iter_next.PreCodegen.after.panic-abort.mir | 43 +-- ...ter_next.PreCodegen.after.panic-unwind.mir | 43 +-- 23 files changed, 484 insertions(+), 666 deletions(-) diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 2643d78990e5..54f9f8809a75 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -27,7 +27,7 @@ pub(super) struct SimplifyComparisonIntegral; impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() > 0 + sess.mir_opt_level() > 0 && sess.opts.unstable_opts.unsound_mir_opts } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/tests/codegen-llvm/hint/likely.rs b/tests/codegen-llvm/hint/likely.rs index 75f9e7aae367..c588b6b8a8e8 100644 --- a/tests/codegen-llvm/hint/likely.rs +++ b/tests/codegen-llvm/hint/likely.rs @@ -70,7 +70,7 @@ pub fn test4(x: u64) { } // CHECK-LABEL: @test4( - // CHECK: br i1 %0, label %bb3, label %bb2, !prof ![[NUM2:[0-9]+]] + // CHECK: br i1 %_2.not, label %bb3, label %bb2, !prof ![[NUM2:[0-9]+]] // CHECK: bb3: // CHECK: path_a // CHECK: bb2: diff --git a/tests/codegen-llvm/hint/unlikely.rs b/tests/codegen-llvm/hint/unlikely.rs index 248b1e2537e9..8a75be50cfc9 100644 --- a/tests/codegen-llvm/hint/unlikely.rs +++ b/tests/codegen-llvm/hint/unlikely.rs @@ -70,7 +70,7 @@ pub fn test4(x: u64) { } // CHECK-LABEL: @test4( - // CHECK: br i1 %0, label %bb4, label %bb2, !prof ![[NUM2:[0-9]+]] + // CHECK: br i1 %_2.not, label %bb4, label %bb2, !prof ![[NUM2:[0-9]+]] // CHECK: bb4: // CHECK: path_a // CHECK: bb2: diff --git a/tests/debuginfo/dummy_span.rs b/tests/debuginfo/dummy_span.rs index fec4f33e3d56..cbdd7c109f36 100644 --- a/tests/debuginfo/dummy_span.rs +++ b/tests/debuginfo/dummy_span.rs @@ -1,6 +1,6 @@ //@ min-lldb-version: 310 -//@ compile-flags:-g +//@ compile-flags:-g -Zunsound-mir-opts //@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff index 6baa902b6f4b..519be6e1e93e 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff @@ -29,10 +29,11 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { - let mut _22: u32; + let mut _22: bool; let mut _23: u32; - let mut _24: usize; - let mut _25: u16; + let mut _24: u32; + let mut _25: usize; + let mut _26: u16; } } } @@ -71,10 +72,12 @@ StorageLive(_6); StorageLive(_22); StorageLive(_23); - _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); - _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); - StorageDead(_23); - switchInt(move _22) -> [0: bb10, otherwise: bb11]; + StorageLive(_24); + _24 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _23 = BitAnd(move _24, const core::fmt::flags::PRECISION_FLAG); + StorageDead(_24); + _22 = Eq(move _23, const 0_u32); + switchInt(move _22) -> [0: bb10, otherwise: bb9]; } bb4: { @@ -142,26 +145,27 @@ } bb9: { - _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; + StorageDead(_23); + _6 = const Option::::None; + goto -> bb11; } bb10: { - StorageDead(_22); - _6 = const Option::::None; - goto -> bb9; + StorageDead(_23); + StorageLive(_25); + StorageLive(_26); + _26 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); + _25 = move _26 as usize (IntToInt); + StorageDead(_26); + _6 = Option::::Some(move _25); + StorageDead(_25); + goto -> bb11; } bb11: { StorageDead(_22); - StorageLive(_24); - StorageLive(_25); - _25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); - _24 = move _25 as usize (IntToInt); - StorageDead(_25); - _6 = Option::::Some(move _24); - StorageDead(_24); - goto -> bb9; + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; } bb12: { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff index 36540e038654..3d97e19218dd 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff @@ -29,10 +29,11 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { - let mut _22: u32; + let mut _22: bool; let mut _23: u32; - let mut _24: usize; - let mut _25: u16; + let mut _24: u32; + let mut _25: usize; + let mut _26: u16; } } } @@ -71,10 +72,12 @@ StorageLive(_6); StorageLive(_22); StorageLive(_23); - _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); - _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); - StorageDead(_23); - switchInt(move _22) -> [0: bb10, otherwise: bb11]; + StorageLive(_24); + _24 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _23 = BitAnd(move _24, const core::fmt::flags::PRECISION_FLAG); + StorageDead(_24); + _22 = Eq(move _23, const 0_u32); + switchInt(move _22) -> [0: bb10, otherwise: bb9]; } bb4: { @@ -142,26 +145,27 @@ } bb9: { - _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; + StorageDead(_23); + _6 = const Option::::None; + goto -> bb11; } bb10: { - StorageDead(_22); - _6 = const Option::::None; - goto -> bb9; + StorageDead(_23); + StorageLive(_25); + StorageLive(_26); + _26 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); + _25 = move _26 as usize (IntToInt); + StorageDead(_26); + _6 = Option::::Some(move _25); + StorageDead(_25); + goto -> bb11; } bb11: { StorageDead(_22); - StorageLive(_24); - StorageLive(_25); - _25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); - _24 = move _25 as usize (IntToInt); - StorageDead(_25); - _6 = Option::::Some(move _24); - StorageDead(_24); - goto -> bb9; + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; } bb12: { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff index 41c350f3eaeb..c6477f0e055c 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff @@ -29,10 +29,11 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { - let mut _22: u32; + let mut _22: bool; let mut _23: u32; - let mut _24: usize; - let mut _25: u16; + let mut _24: u32; + let mut _25: usize; + let mut _26: u16; } } } @@ -71,10 +72,12 @@ StorageLive(_6); StorageLive(_22); StorageLive(_23); - _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); - _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); - StorageDead(_23); - switchInt(move _22) -> [0: bb10, otherwise: bb11]; + StorageLive(_24); + _24 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _23 = BitAnd(move _24, const core::fmt::flags::PRECISION_FLAG); + StorageDead(_24); + _22 = Eq(move _23, const 0_u32); + switchInt(move _22) -> [0: bb10, otherwise: bb9]; } bb4: { @@ -142,26 +145,27 @@ } bb9: { - _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; + StorageDead(_23); + _6 = const Option::::None; + goto -> bb11; } bb10: { - StorageDead(_22); - _6 = const Option::::None; - goto -> bb9; + StorageDead(_23); + StorageLive(_25); + StorageLive(_26); + _26 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); + _25 = move _26 as usize (IntToInt); + StorageDead(_26); + _6 = Option::::Some(move _25); + StorageDead(_25); + goto -> bb11; } bb11: { StorageDead(_22); - StorageLive(_24); - StorageLive(_25); - _25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); - _24 = move _25 as usize (IntToInt); - StorageDead(_25); - _6 = Option::::Some(move _24); - StorageDead(_24); - goto -> bb9; + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; } bb12: { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff index b839bf81eaf4..d491e2a5e4c7 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff @@ -29,10 +29,11 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { - let mut _22: u32; + let mut _22: bool; let mut _23: u32; - let mut _24: usize; - let mut _25: u16; + let mut _24: u32; + let mut _25: usize; + let mut _26: u16; } } } @@ -71,10 +72,12 @@ StorageLive(_6); StorageLive(_22); StorageLive(_23); - _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); - _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); - StorageDead(_23); - switchInt(move _22) -> [0: bb10, otherwise: bb11]; + StorageLive(_24); + _24 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _23 = BitAnd(move _24, const core::fmt::flags::PRECISION_FLAG); + StorageDead(_24); + _22 = Eq(move _23, const 0_u32); + switchInt(move _22) -> [0: bb10, otherwise: bb9]; } bb4: { @@ -142,26 +145,27 @@ } bb9: { - _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; + StorageDead(_23); + _6 = const Option::::None; + goto -> bb11; } bb10: { - StorageDead(_22); - _6 = const Option::::None; - goto -> bb9; + StorageDead(_23); + StorageLive(_25); + StorageLive(_26); + _26 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); + _25 = move _26 as usize (IntToInt); + StorageDead(_26); + _6 = Option::::Some(move _25); + StorageDead(_25); + goto -> bb11; } bb11: { StorageDead(_22); - StorageLive(_24); - StorageLive(_25); - _25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); - _24 = move _25 as usize (IntToInt); - StorageDead(_25); - _6 = Option::::Some(move _24); - StorageDead(_24); - goto -> bb9; + _7 = discriminant(_6); + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; } bb12: { diff --git a/tests/mir-opt/issue_76432.rs b/tests/mir-opt/issue_76432.rs index 6d884063caaf..bc2552d82c2e 100644 --- a/tests/mir-opt/issue_76432.rs +++ b/tests/mir-opt/issue_76432.rs @@ -1,6 +1,7 @@ // skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // Check that we do not insert StorageDead at each target if StorageDead was never seen +//@ compile-flags: -Zunsound-mir-opts use std::fmt::Debug; diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir index b5c23822162c..cdb8ce66a77a 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir @@ -3,7 +3,8 @@ fn num_to_digit(_1: char) -> u32 { debug num => _1; let mut _0: u32; - let mut _4: std::option::Option; + let mut _4: bool; + let mut _5: std::option::Option; scope 1 (inlined char::methods::::is_digit) { let _2: std::option::Option; scope 2 (inlined Option::::is_some) { @@ -13,13 +14,14 @@ fn num_to_digit(_1: char) -> u32 { } } scope 4 (inlined #[track_caller] Option::::unwrap) { - let mut _5: isize; - let mut _6: !; + let mut _6: isize; + let mut _7: !; scope 5 { } } bb0: { + StorageLive(_4); StorageLive(_2); _2 = char::methods::::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind unreachable]; } @@ -27,44 +29,45 @@ fn num_to_digit(_1: char) -> u32 { bb1: { StorageLive(_3); _3 = discriminant(_2); + _4 = Eq(copy _3, const 1_isize); + StorageDead(_3); StorageDead(_2); - switchInt(move _3) -> [1: bb2, otherwise: bb7]; + switchInt(move _4) -> [0: bb2, otherwise: bb3]; } bb2: { - StorageDead(_3); - StorageLive(_4); - _4 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable]; + _0 = const 0_u32; + goto -> bb7; } bb3: { StorageLive(_5); - _5 = discriminant(_4); - switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6]; + _5 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb4, unwind unreachable]; } bb4: { - _6 = option::unwrap_failed() -> unwind unreachable; + StorageLive(_6); + _6 = discriminant(_5); + switchInt(move _6) -> [0: bb5, 1: bb6, otherwise: bb8]; } bb5: { - _0 = move ((_4 as Some).0: u32); - StorageDead(_5); - StorageDead(_4); - goto -> bb8; + _7 = option::unwrap_failed() -> unwind unreachable; } bb6: { - unreachable; + _0 = move ((_5 as Some).0: u32); + StorageDead(_6); + StorageDead(_5); + goto -> bb7; } bb7: { - StorageDead(_3); - _0 = const 0_u32; - goto -> bb8; + StorageDead(_4); + return; } bb8: { - return; + unreachable; } } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir index f22b8835735d..ad0e4dfa0f33 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir @@ -3,7 +3,8 @@ fn num_to_digit(_1: char) -> u32 { debug num => _1; let mut _0: u32; - let mut _4: std::option::Option; + let mut _4: bool; + let mut _5: std::option::Option; scope 1 (inlined char::methods::::is_digit) { let _2: std::option::Option; scope 2 (inlined Option::::is_some) { @@ -13,13 +14,14 @@ fn num_to_digit(_1: char) -> u32 { } } scope 4 (inlined #[track_caller] Option::::unwrap) { - let mut _5: isize; - let mut _6: !; + let mut _6: isize; + let mut _7: !; scope 5 { } } bb0: { + StorageLive(_4); StorageLive(_2); _2 = char::methods::::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind continue]; } @@ -27,44 +29,45 @@ fn num_to_digit(_1: char) -> u32 { bb1: { StorageLive(_3); _3 = discriminant(_2); + _4 = Eq(copy _3, const 1_isize); + StorageDead(_3); StorageDead(_2); - switchInt(move _3) -> [1: bb2, otherwise: bb7]; + switchInt(move _4) -> [0: bb2, otherwise: bb3]; } bb2: { - StorageDead(_3); - StorageLive(_4); - _4 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue]; + _0 = const 0_u32; + goto -> bb7; } bb3: { StorageLive(_5); - _5 = discriminant(_4); - switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6]; + _5 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb4, unwind continue]; } bb4: { - _6 = option::unwrap_failed() -> unwind continue; + StorageLive(_6); + _6 = discriminant(_5); + switchInt(move _6) -> [0: bb5, 1: bb6, otherwise: bb8]; } bb5: { - _0 = move ((_4 as Some).0: u32); - StorageDead(_5); - StorageDead(_4); - goto -> bb8; + _7 = option::unwrap_failed() -> unwind continue; } bb6: { - unreachable; + _0 = move ((_5 as Some).0: u32); + StorageDead(_6); + StorageDead(_5); + goto -> bb7; } bb7: { - StorageDead(_3); - _0 = const 0_u32; - goto -> bb8; + StorageDead(_4); + return; } bb8: { - return; + unreachable; } } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir index b5c23822162c..cdb8ce66a77a 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir @@ -3,7 +3,8 @@ fn num_to_digit(_1: char) -> u32 { debug num => _1; let mut _0: u32; - let mut _4: std::option::Option; + let mut _4: bool; + let mut _5: std::option::Option; scope 1 (inlined char::methods::::is_digit) { let _2: std::option::Option; scope 2 (inlined Option::::is_some) { @@ -13,13 +14,14 @@ fn num_to_digit(_1: char) -> u32 { } } scope 4 (inlined #[track_caller] Option::::unwrap) { - let mut _5: isize; - let mut _6: !; + let mut _6: isize; + let mut _7: !; scope 5 { } } bb0: { + StorageLive(_4); StorageLive(_2); _2 = char::methods::::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind unreachable]; } @@ -27,44 +29,45 @@ fn num_to_digit(_1: char) -> u32 { bb1: { StorageLive(_3); _3 = discriminant(_2); + _4 = Eq(copy _3, const 1_isize); + StorageDead(_3); StorageDead(_2); - switchInt(move _3) -> [1: bb2, otherwise: bb7]; + switchInt(move _4) -> [0: bb2, otherwise: bb3]; } bb2: { - StorageDead(_3); - StorageLive(_4); - _4 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable]; + _0 = const 0_u32; + goto -> bb7; } bb3: { StorageLive(_5); - _5 = discriminant(_4); - switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6]; + _5 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb4, unwind unreachable]; } bb4: { - _6 = option::unwrap_failed() -> unwind unreachable; + StorageLive(_6); + _6 = discriminant(_5); + switchInt(move _6) -> [0: bb5, 1: bb6, otherwise: bb8]; } bb5: { - _0 = move ((_4 as Some).0: u32); - StorageDead(_5); - StorageDead(_4); - goto -> bb8; + _7 = option::unwrap_failed() -> unwind unreachable; } bb6: { - unreachable; + _0 = move ((_5 as Some).0: u32); + StorageDead(_6); + StorageDead(_5); + goto -> bb7; } bb7: { - StorageDead(_3); - _0 = const 0_u32; - goto -> bb8; + StorageDead(_4); + return; } bb8: { - return; + unreachable; } } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir index f22b8835735d..ad0e4dfa0f33 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir @@ -3,7 +3,8 @@ fn num_to_digit(_1: char) -> u32 { debug num => _1; let mut _0: u32; - let mut _4: std::option::Option; + let mut _4: bool; + let mut _5: std::option::Option; scope 1 (inlined char::methods::::is_digit) { let _2: std::option::Option; scope 2 (inlined Option::::is_some) { @@ -13,13 +14,14 @@ fn num_to_digit(_1: char) -> u32 { } } scope 4 (inlined #[track_caller] Option::::unwrap) { - let mut _5: isize; - let mut _6: !; + let mut _6: isize; + let mut _7: !; scope 5 { } } bb0: { + StorageLive(_4); StorageLive(_2); _2 = char::methods::::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind continue]; } @@ -27,44 +29,45 @@ fn num_to_digit(_1: char) -> u32 { bb1: { StorageLive(_3); _3 = discriminant(_2); + _4 = Eq(copy _3, const 1_isize); + StorageDead(_3); StorageDead(_2); - switchInt(move _3) -> [1: bb2, otherwise: bb7]; + switchInt(move _4) -> [0: bb2, otherwise: bb3]; } bb2: { - StorageDead(_3); - StorageLive(_4); - _4 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue]; + _0 = const 0_u32; + goto -> bb7; } bb3: { StorageLive(_5); - _5 = discriminant(_4); - switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6]; + _5 = char::methods::::to_digit(move _1, const 8_u32) -> [return: bb4, unwind continue]; } bb4: { - _6 = option::unwrap_failed() -> unwind continue; + StorageLive(_6); + _6 = discriminant(_5); + switchInt(move _6) -> [0: bb5, 1: bb6, otherwise: bb8]; } bb5: { - _0 = move ((_4 as Some).0: u32); - StorageDead(_5); - StorageDead(_4); - goto -> bb8; + _7 = option::unwrap_failed() -> unwind continue; } bb6: { - unreachable; + _0 = move ((_5 as Some).0: u32); + StorageDead(_6); + StorageDead(_5); + goto -> bb7; } bb7: { - StorageDead(_3); - _0 = const 0_u32; - goto -> bb8; + StorageDead(_4); + return; } bb8: { - return; + unreachable; } } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir index 791d6b71a6f7..49f8465326b0 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir @@ -8,7 +8,8 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { let _2: std::ptr::NonNull<[T]>; let mut _3: *mut [T]; let mut _4: *const [T]; - let _11: (); + let mut _9: bool; + let _12: (); scope 3 { let _8: std::ptr::alignment::AlignmentEnum; scope 4 { @@ -25,13 +26,13 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } scope 18 (inlined ::deallocate) { - let mut _9: *mut u8; + let mut _10: *mut u8; scope 19 (inlined Layout::size) { } scope 20 (inlined NonNull::::as_ptr) { } scope 21 (inlined std::alloc::dealloc) { - let mut _10: usize; + let mut _11: usize; scope 22 (inlined Layout::size) { } scope 23 (inlined Layout::align) { @@ -80,20 +81,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { StorageDead(_7); StorageDead(_6); StorageDead(_4); - switchInt(copy _5) -> [0: bb4, otherwise: bb2]; + _9 = Ne(copy _5, const 0_usize); + switchInt(copy _9) -> [0: bb4, otherwise: bb2]; } bb2: { - StorageLive(_9); - _9 = copy _3 as *mut u8 (PtrToPtr); StorageLive(_10); - _10 = discriminant(_8); - _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable]; + _10 = copy _3 as *mut u8 (PtrToPtr); + StorageLive(_11); + _11 = discriminant(_8); + _12 = alloc::alloc::__rust_dealloc(move _10, move _5, move _11) -> [return: bb3, unwind unreachable]; } bb3: { + StorageDead(_11); StorageDead(_10); - StorageDead(_9); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir index 791d6b71a6f7..49f8465326b0 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir @@ -8,7 +8,8 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { let _2: std::ptr::NonNull<[T]>; let mut _3: *mut [T]; let mut _4: *const [T]; - let _11: (); + let mut _9: bool; + let _12: (); scope 3 { let _8: std::ptr::alignment::AlignmentEnum; scope 4 { @@ -25,13 +26,13 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } scope 18 (inlined ::deallocate) { - let mut _9: *mut u8; + let mut _10: *mut u8; scope 19 (inlined Layout::size) { } scope 20 (inlined NonNull::::as_ptr) { } scope 21 (inlined std::alloc::dealloc) { - let mut _10: usize; + let mut _11: usize; scope 22 (inlined Layout::size) { } scope 23 (inlined Layout::align) { @@ -80,20 +81,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { StorageDead(_7); StorageDead(_6); StorageDead(_4); - switchInt(copy _5) -> [0: bb4, otherwise: bb2]; + _9 = Ne(copy _5, const 0_usize); + switchInt(copy _9) -> [0: bb4, otherwise: bb2]; } bb2: { - StorageLive(_9); - _9 = copy _3 as *mut u8 (PtrToPtr); StorageLive(_10); - _10 = discriminant(_8); - _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable]; + _10 = copy _3 as *mut u8 (PtrToPtr); + StorageLive(_11); + _11 = discriminant(_8); + _12 = alloc::alloc::__rust_dealloc(move _10, move _5, move _11) -> [return: bb3, unwind unreachable]; } bb3: { + StorageDead(_11); StorageDead(_10); - StorageDead(_9); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir index 791d6b71a6f7..49f8465326b0 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir @@ -8,7 +8,8 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { let _2: std::ptr::NonNull<[T]>; let mut _3: *mut [T]; let mut _4: *const [T]; - let _11: (); + let mut _9: bool; + let _12: (); scope 3 { let _8: std::ptr::alignment::AlignmentEnum; scope 4 { @@ -25,13 +26,13 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } scope 18 (inlined ::deallocate) { - let mut _9: *mut u8; + let mut _10: *mut u8; scope 19 (inlined Layout::size) { } scope 20 (inlined NonNull::::as_ptr) { } scope 21 (inlined std::alloc::dealloc) { - let mut _10: usize; + let mut _11: usize; scope 22 (inlined Layout::size) { } scope 23 (inlined Layout::align) { @@ -80,20 +81,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { StorageDead(_7); StorageDead(_6); StorageDead(_4); - switchInt(copy _5) -> [0: bb4, otherwise: bb2]; + _9 = Ne(copy _5, const 0_usize); + switchInt(copy _9) -> [0: bb4, otherwise: bb2]; } bb2: { - StorageLive(_9); - _9 = copy _3 as *mut u8 (PtrToPtr); StorageLive(_10); - _10 = discriminant(_8); - _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable]; + _10 = copy _3 as *mut u8 (PtrToPtr); + StorageLive(_11); + _11 = discriminant(_8); + _12 = alloc::alloc::__rust_dealloc(move _10, move _5, move _11) -> [return: bb3, unwind unreachable]; } bb3: { + StorageDead(_11); StorageDead(_10); - StorageDead(_9); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir index 791d6b71a6f7..49f8465326b0 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir @@ -8,7 +8,8 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { let _2: std::ptr::NonNull<[T]>; let mut _3: *mut [T]; let mut _4: *const [T]; - let _11: (); + let mut _9: bool; + let _12: (); scope 3 { let _8: std::ptr::alignment::AlignmentEnum; scope 4 { @@ -25,13 +26,13 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } scope 18 (inlined ::deallocate) { - let mut _9: *mut u8; + let mut _10: *mut u8; scope 19 (inlined Layout::size) { } scope 20 (inlined NonNull::::as_ptr) { } scope 21 (inlined std::alloc::dealloc) { - let mut _10: usize; + let mut _11: usize; scope 22 (inlined Layout::size) { } scope 23 (inlined Layout::align) { @@ -80,20 +81,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { StorageDead(_7); StorageDead(_6); StorageDead(_4); - switchInt(copy _5) -> [0: bb4, otherwise: bb2]; + _9 = Ne(copy _5, const 0_usize); + switchInt(copy _9) -> [0: bb4, otherwise: bb2]; } bb2: { - StorageLive(_9); - _9 = copy _3 as *mut u8 (PtrToPtr); StorageLive(_10); - _10 = discriminant(_8); - _11 = alloc::alloc::__rust_dealloc(move _9, move _5, move _10) -> [return: bb3, unwind unreachable]; + _10 = copy _3 as *mut u8 (PtrToPtr); + StorageLive(_11); + _11 = discriminant(_8); + _12 = alloc::alloc::__rust_dealloc(move _10, move _5, move _11) -> [return: bb3, unwind unreachable]; } bb3: { + StorageDead(_11); StorageDead(_10); - StorageDead(_9); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir index 4260ec3eaedf..e537dd6a28ef 100644 --- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir @@ -3,316 +3,72 @@ fn vec_move(_1: Vec) -> () { debug v => _1; let mut _0: (); - let mut _21: std::vec::IntoIter; - let mut _22: std::vec::IntoIter; - let mut _23: &mut std::vec::IntoIter; - let mut _24: std::option::Option; - let mut _25: isize; - let _27: (); + let mut _2: std::vec::IntoIter; + let mut _3: std::vec::IntoIter; + let mut _4: &mut std::vec::IntoIter; + let mut _5: std::option::Option; + let mut _6: isize; + let _8: (); scope 1 { - debug iter => _22; - let _26: impl Sized; + debug iter => _3; + let _7: impl Sized; scope 2 { - debug x => _26; - } - } - scope 3 (inlined as IntoIterator>::into_iter) { - debug self => _1; - let _2: std::mem::ManuallyDrop>; - let mut _3: *const std::alloc::Global; - let mut _8: usize; - let mut _10: *mut impl Sized; - let mut _11: *const impl Sized; - let mut _12: usize; - let _28: &std::vec::Vec; - let mut _29: &std::mem::ManuallyDrop>; - let mut _30: &alloc::raw_vec::RawVec; - let mut _31: &std::mem::ManuallyDrop>; - let _32: &std::vec::Vec; - let mut _33: &std::mem::ManuallyDrop>; - let _34: &std::vec::Vec; - let mut _35: &std::mem::ManuallyDrop>; - let mut _36: &alloc::raw_vec::RawVec; - let mut _37: &std::mem::ManuallyDrop>; - scope 4 { - debug me => _2; - scope 5 { - debug alloc => const ManuallyDrop:: {{ value: std::alloc::Global }}; - let _6: std::ptr::NonNull; - scope 6 { - debug buf => _6; - let _7: *mut impl Sized; - scope 7 { - debug begin => _7; - scope 8 { - debug end => _11; - let _19: usize; - scope 9 { - debug cap => _19; - } - scope 39 (inlined > as Deref>::deref) { - debug self => _37; - } - scope 40 (inlined alloc::raw_vec::RawVec::::capacity) { - debug self => _36; - let mut _38: &alloc::raw_vec::RawVecInner; - scope 41 (inlined std::mem::size_of::) { - } - scope 42 (inlined alloc::raw_vec::RawVecInner::capacity) { - debug self => _38; - debug elem_size => const ::SIZE; - let mut _20: core::num::niche_types::UsizeNoHighBit; - scope 43 (inlined core::num::niche_types::UsizeNoHighBit::as_inner) { - debug self => _20; - } - } - } - } - scope 25 (inlined > as Deref>::deref) { - debug self => _33; - } - scope 26 (inlined Vec::::len) { - debug self => _32; - let mut _13: bool; - scope 27 { - } - } - scope 28 (inlined std::ptr::mut_ptr::::wrapping_byte_add) { - debug self => _7; - debug count => _12; - let mut _14: *mut u8; - let mut _18: *mut u8; - scope 29 (inlined std::ptr::mut_ptr::::cast::) { - debug self => _7; - } - scope 30 (inlined std::ptr::mut_ptr::::wrapping_add) { - debug self => _14; - debug count => _12; - let mut _15: isize; - scope 31 (inlined std::ptr::mut_ptr::::wrapping_offset) { - debug self => _14; - debug count => _15; - let mut _16: *const u8; - let mut _17: *const u8; - } - } - scope 32 (inlined std::ptr::mut_ptr::::with_metadata_of::) { - debug self => _18; - debug meta => _5; - scope 33 (inlined std::ptr::metadata::) { - debug ptr => _5; - } - scope 34 (inlined std::ptr::from_raw_parts_mut::) { - } - } - } - scope 35 (inlined > as Deref>::deref) { - debug self => _35; - } - scope 36 (inlined Vec::::len) { - debug self => _34; - let mut _9: bool; - scope 37 { - } - } - scope 38 (inlined #[track_caller] std::ptr::mut_ptr::::add) { - debug self => _7; - debug count => _8; - } - } - scope 24 (inlined NonNull::::as_ptr) { - debug self => _6; - } - } - scope 17 (inlined > as Deref>::deref) { - debug self => _31; - } - scope 18 (inlined alloc::raw_vec::RawVec::::non_null) { - debug self => _30; - scope 19 (inlined alloc::raw_vec::RawVecInner::non_null::) { - let mut _4: std::ptr::NonNull; - scope 20 (inlined Unique::::cast::) { - scope 21 (inlined NonNull::::cast::) { - let mut _5: *const impl Sized; - scope 22 (inlined NonNull::::as_ptr) { - } - } - } - scope 23 (inlined Unique::::as_non_null_ptr) { - } - } - } - } - scope 11 (inlined > as Deref>::deref) { - debug self => _29; - } - scope 12 (inlined Vec::::allocator) { - debug self => _28; - scope 13 (inlined alloc::raw_vec::RawVec::::allocator) { - scope 14 (inlined alloc::raw_vec::RawVecInner::allocator) { - } - } - } - scope 15 (inlined #[track_caller] std::ptr::read::) { - debug src => _3; - } - scope 16 (inlined ManuallyDrop::::new) { - debug value => const std::alloc::Global; - } - } - scope 10 (inlined ManuallyDrop::>::new) { - debug value => _1; + debug x => _7; } } bb0: { - StorageLive(_21); - StorageLive(_6); - StorageLive(_7); - StorageLive(_11); - StorageLive(_19); - StorageLive(_5); - StorageLive(_4); - StorageLive(_17); StorageLive(_2); - _2 = ManuallyDrop::> { value: copy _1 }; - StorageLive(_3); - // DBG: _29 = &_2; - // DBG: _28 = &(_2.0: std::vec::Vec); - _3 = &raw const ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).2: std::alloc::Global); - StorageDead(_3); - // DBG: _31 = &_2; - // DBG: _30 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); - _4 = copy (((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); - _5 = copy _4 as *const impl Sized (Transmute); - _6 = NonNull:: { pointer: copy _5 }; - _7 = copy _4 as *mut impl Sized (Transmute); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; + _2 = as IntoIterator>::into_iter(move _1) -> [return: bb1, unwind continue]; } bb1: { - StorageLive(_10); - StorageLive(_8); - // DBG: _35 = &_2; - // DBG: _34 = &(_2.0: std::vec::Vec); - _8 = copy ((_2.0: std::vec::Vec).1: usize); - StorageLive(_9); - _9 = Le(copy _8, const ::MAX_SLICE_LEN); - assume(move _9); - StorageDead(_9); - _10 = Offset(copy _7, copy _8); - _11 = copy _10 as *const impl Sized (PtrToPtr); - StorageDead(_8); - StorageDead(_10); - goto -> bb4; + StorageLive(_3); + _3 = move _2; + goto -> bb2; } bb2: { - StorageLive(_12); - // DBG: _33 = &_2; - // DBG: _32 = &(_2.0: std::vec::Vec); - _12 = copy ((_2.0: std::vec::Vec).1: usize); - StorageLive(_13); - _13 = Le(copy _12, const ::MAX_SLICE_LEN); - assume(move _13); - StorageDead(_13); - StorageLive(_18); - StorageLive(_14); - _14 = copy _4 as *mut u8 (Transmute); - StorageLive(_15); - _15 = copy _12 as isize (IntToInt); - StorageLive(_16); - _16 = copy _4 as *const u8 (Transmute); - _17 = arith_offset::(move _16, move _15) -> [return: bb3, unwind unreachable]; + StorageLive(_5); + _4 = &mut _3; + _5 = as Iterator>::next(move _4) -> [return: bb3, unwind: bb9]; } bb3: { - StorageDead(_16); - _18 = copy _17 as *mut u8 (PtrToPtr); - StorageDead(_15); - StorageDead(_14); - StorageDead(_18); - StorageDead(_12); - _11 = copy _17 as *const impl Sized (PtrToPtr); - goto -> bb4; + _6 = discriminant(_5); + switchInt(move _6) -> [0: bb4, 1: bb6, otherwise: bb8]; } bb4: { - // DBG: _37 = &_2; - // DBG: _36 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); - // DBG: _38 = &(((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner); - switchInt(const ::SIZE) -> [0: bb5, otherwise: bb6]; + StorageDead(_5); + drop(_3) -> [return: bb5, unwind continue]; } bb5: { - _19 = const usize::MAX; - goto -> bb7; - } - - bb6: { - StorageLive(_20); - _20 = copy ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).1: core::num::niche_types::UsizeNoHighBit); - _19 = copy _20 as usize (Transmute); - StorageDead(_20); - goto -> bb7; - } - - bb7: { - _21 = std::vec::IntoIter:: { buf: copy _6, phantom: const ZeroSized: PhantomData, cap: move _19, alloc: const ManuallyDrop:: {{ value: std::alloc::Global }}, ptr: copy _6, end: copy _11 }; + StorageDead(_3); StorageDead(_2); - StorageDead(_17); - StorageDead(_4); - StorageDead(_5); - StorageDead(_19); - StorageDead(_11); - StorageDead(_7); - StorageDead(_6); - StorageLive(_22); - _22 = move _21; - goto -> bb8; - } - - bb8: { - StorageLive(_24); - _23 = &mut _22; - _24 = as Iterator>::next(move _23) -> [return: bb9, unwind: bb15]; - } - - bb9: { - _25 = discriminant(_24); - switchInt(move _25) -> [0: bb10, 1: bb12, otherwise: bb14]; - } - - bb10: { - StorageDead(_24); - drop(_22) -> [return: bb11, unwind continue]; - } - - bb11: { - StorageDead(_22); - StorageDead(_21); return; } - bb12: { - _26 = move ((_24 as Some).0: impl Sized); - _27 = opaque::(move _26) -> [return: bb13, unwind: bb15]; + bb6: { + _7 = move ((_5 as Some).0: impl Sized); + _8 = opaque::(move _7) -> [return: bb7, unwind: bb9]; } - bb13: { - StorageDead(_24); - goto -> bb8; + bb7: { + StorageDead(_5); + goto -> bb2; } - bb14: { + bb8: { unreachable; } - bb15 (cleanup): { - drop(_22) -> [return: bb16, unwind terminate(cleanup)]; + bb9 (cleanup): { + drop(_3) -> [return: bb10, unwind terminate(cleanup)]; } - bb16 (cleanup): { + bb10 (cleanup): { resume; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index f72611b7cb8e..fffd39c0c4ab 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -5,27 +5,27 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug f => _2; let mut _0: (); let mut _10: usize; - let mut _28: std::option::Option<(usize, &T)>; - let mut _31: &impl Fn(usize, &T); - let mut _32: (usize, &T); - let _33: (); + let mut _29: std::option::Option<(usize, &T)>; + let mut _32: &impl Fn(usize, &T); + let mut _33: (usize, &T); + let _34: (); scope 1 { debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _6; debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).1: *const T) => _9; debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; debug ((iter: Enumerate>).1: usize) => _10; - let _29: usize; - let _30: &T; + let _30: usize; + let _31: &T; scope 2 { - debug i => _29; - debug x => _30; + debug i => _30; + debug x => _31; } scope 18 (inlined > as Iterator>::next) { - let mut _23: std::option::Option<&T>; - let mut _26: (usize, bool); - let mut _27: (usize, &T); + let mut _24: std::option::Option<&T>; + let mut _27: (usize, bool); + let mut _28: (usize, &T); scope 19 { - let _25: usize; + let _26: usize; scope 24 { } } @@ -40,7 +40,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 25 (inlined as Try>::branch) { - let _24: &T; + let _25: &T; scope 26 { } } @@ -49,8 +49,9 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _11: std::ptr::NonNull; let _13: std::ptr::NonNull; let mut _16: bool; - let mut _20: usize; - let _22: &T; + let mut _20: bool; + let mut _21: usize; + let _23: &T; scope 29 { let _12: *const T; scope 30 { @@ -84,7 +85,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 43 (inlined NonNull::::as_ref::<'_>) { - let _21: *const T; + let _22: *const T; scope 44 (inlined NonNull::::as_ptr) { } scope 45 (inlined std::ptr::mut_ptr::::cast_const) { @@ -169,16 +170,16 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb4: { - StorageLive(_28); - StorageLive(_25); + StorageLive(_29); StorageLive(_26); - StorageLive(_23); + StorageLive(_27); + StorageLive(_24); StorageLive(_11); StorageLive(_12); StorageLive(_19); - StorageLive(_20); + StorageLive(_21); StorageLive(_13); - StorageLive(_22); + StorageLive(_23); _11 = copy _6; _12 = copy _9; switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; @@ -206,88 +207,92 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { StorageDead(_17); _6 = NonNull:: { pointer: copy _18 }; StorageDead(_18); - goto -> bb13; + goto -> bb10; } bb7: { StorageDead(_16); - goto -> bb10; + goto -> bb14; } bb8: { _19 = copy _12 as usize (Transmute); - switchInt(copy _19) -> [0: bb9, otherwise: bb12]; + StorageLive(_20); + _20 = Eq(copy _19, const 0_usize); + switchInt(move _20) -> [0: bb9, otherwise: bb13]; } bb9: { + StorageDead(_20); + _21 = SubUnchecked(copy _19, const 1_usize); + _9 = copy _21 as *const T (Transmute); goto -> bb10; } bb10: { + StorageLive(_22); + _22 = copy _11 as *const T (Transmute); + _23 = &(*_22); StorageDead(_22); + _24 = Option::<&T>::Some(copy _23); + StorageDead(_23); StorageDead(_13); - StorageDead(_20); + StorageDead(_21); StorageDead(_19); StorageDead(_12); StorageDead(_11); - StorageDead(_23); - StorageDead(_26); - StorageDead(_25); - StorageDead(_28); - StorageDead(_10); - drop(_2) -> [return: bb11, unwind unreachable]; + _25 = copy ((_24 as Some).0: &T); + StorageDead(_24); + _26 = copy _10; + _27 = AddWithOverflow(copy _10, const 1_usize); + assert(!move (_27.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _10, const 1_usize) -> [success: bb11, unwind unreachable]; } bb11: { - return; + _10 = move (_27.0: usize); + StorageLive(_28); + _28 = (copy _26, copy _25); + _29 = Option::<(usize, &T)>::Some(move _28); + StorageDead(_28); + StorageDead(_27); + StorageDead(_26); + _30 = copy (((_29 as Some).0: (usize, &T)).0: usize); + _31 = copy (((_29 as Some).0: (usize, &T)).1: &T); + StorageLive(_32); + _32 = &_2; + StorageLive(_33); + _33 = (copy _30, copy _31); + _34 = >::call(move _32, move _33) -> [return: bb12, unwind unreachable]; } bb12: { - _20 = SubUnchecked(copy _19, const 1_usize); - _9 = copy _20 as *const T (Transmute); - goto -> bb13; + StorageDead(_33); + StorageDead(_32); + StorageDead(_29); + goto -> bb4; } bb13: { - StorageLive(_21); - _21 = copy _11 as *const T (Transmute); - _22 = &(*_21); - StorageDead(_21); - _23 = Option::<&T>::Some(copy _22); - StorageDead(_22); - StorageDead(_13); StorageDead(_20); - StorageDead(_19); - StorageDead(_12); - StorageDead(_11); - _24 = copy ((_23 as Some).0: &T); - StorageDead(_23); - _25 = copy _10; - _26 = AddWithOverflow(copy _10, const 1_usize); - assert(!move (_26.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _10, const 1_usize) -> [success: bb14, unwind unreachable]; + goto -> bb14; } bb14: { - _10 = move (_26.0: usize); - StorageLive(_27); - _27 = (copy _25, copy _24); - _28 = Option::<(usize, &T)>::Some(move _27); + StorageDead(_23); + StorageDead(_13); + StorageDead(_21); + StorageDead(_19); + StorageDead(_12); + StorageDead(_11); + StorageDead(_24); StorageDead(_27); StorageDead(_26); - StorageDead(_25); - _29 = copy (((_28 as Some).0: (usize, &T)).0: usize); - _30 = copy (((_28 as Some).0: (usize, &T)).1: &T); - StorageLive(_31); - _31 = &_2; - StorageLive(_32); - _32 = (copy _29, copy _30); - _33 = >::call(move _31, move _32) -> [return: bb15, unwind unreachable]; + StorageDead(_29); + StorageDead(_10); + drop(_2) -> [return: bb15, unwind unreachable]; } bb15: { - StorageDead(_32); - StorageDead(_31); - StorageDead(_28); - goto -> bb4; + return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index b210efb1f46c..208739042172 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,25 +4,26 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _22: std::option::Option<&T>; - let mut _24: &impl Fn(&T); - let mut _25: (&T,); - let _26: (); + let mut _23: std::option::Option<&T>; + let mut _25: &impl Fn(&T); + let mut _26: (&T,); + let _27: (); scope 1 { debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _6; debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _9; debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - let _23: &T; + let _24: &T; scope 2 { - debug x => _23; + debug x => _24; } scope 16 (inlined as Iterator>::next) { let mut _6: std::ptr::NonNull; let _10: std::ptr::NonNull; let _12: std::ptr::NonNull; let mut _15: bool; - let mut _19: usize; - let _21: &T; + let mut _19: bool; + let mut _20: usize; + let _22: &T; scope 17 { let _11: *const T; scope 18 { @@ -56,7 +57,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 31 (inlined NonNull::::as_ref::<'_>) { - let _20: *const T; + let _21: *const T; scope 32 (inlined NonNull::::as_ptr) { } scope 33 (inlined std::ptr::mut_ptr::::cast_const) { @@ -134,13 +135,13 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { - StorageLive(_22); + StorageLive(_23); StorageLive(_10); StorageLive(_11); StorageLive(_18); - StorageLive(_19); + StorageLive(_20); StorageLive(_12); - StorageLive(_21); + StorageLive(_22); _10 = copy _6; _11 = copy _9; switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; @@ -168,68 +169,72 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageDead(_16); _6 = NonNull:: { pointer: copy _17 }; StorageDead(_17); - goto -> bb13; + goto -> bb10; } bb7: { StorageDead(_15); - goto -> bb10; + goto -> bb13; } bb8: { _18 = copy _11 as usize (Transmute); - switchInt(copy _18) -> [0: bb9, otherwise: bb12]; + StorageLive(_19); + _19 = Eq(copy _18, const 0_usize); + switchInt(move _19) -> [0: bb9, otherwise: bb12]; } bb9: { + StorageDead(_19); + _20 = SubUnchecked(copy _18, const 1_usize); + _9 = copy _20 as *const T (Transmute); goto -> bb10; } bb10: { + StorageLive(_21); + _21 = copy _10 as *const T (Transmute); + _22 = &(*_21); StorageDead(_21); + _23 = Option::<&T>::Some(copy _22); + StorageDead(_22); StorageDead(_12); - StorageDead(_19); + StorageDead(_20); StorageDead(_18); StorageDead(_11); StorageDead(_10); - StorageDead(_22); - drop(_2) -> [return: bb11, unwind unreachable]; + _24 = copy ((_23 as Some).0: &T); + StorageLive(_25); + _25 = &_2; + StorageLive(_26); + _26 = (copy _24,); + _27 = >::call(move _25, move _26) -> [return: bb11, unwind unreachable]; } bb11: { - return; + StorageDead(_26); + StorageDead(_25); + StorageDead(_23); + goto -> bb4; } bb12: { - _19 = SubUnchecked(copy _18, const 1_usize); - _9 = copy _19 as *const T (Transmute); + StorageDead(_19); goto -> bb13; } bb13: { - StorageLive(_20); - _20 = copy _10 as *const T (Transmute); - _21 = &(*_20); - StorageDead(_20); - _22 = Option::<&T>::Some(copy _21); - StorageDead(_21); + StorageDead(_22); StorageDead(_12); - StorageDead(_19); + StorageDead(_20); StorageDead(_18); StorageDead(_11); StorageDead(_10); - _23 = copy ((_22 as Some).0: &T); - StorageLive(_24); - _24 = &_2; - StorageLive(_25); - _25 = (copy _23,); - _26 = >::call(move _24, move _25) -> [return: bb14, unwind unreachable]; + StorageDead(_23); + drop(_2) -> [return: bb14, unwind unreachable]; } bb14: { - StorageDead(_25); - StorageDead(_24); - StorageDead(_22); - goto -> bb4; + return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index ab6e2bf0b36b..3f8ed2c47c0e 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,25 +4,26 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _22: std::option::Option<&T>; - let mut _24: &impl Fn(&T); - let mut _25: (&T,); - let _26: (); + let mut _23: std::option::Option<&T>; + let mut _25: &impl Fn(&T); + let mut _26: (&T,); + let _27: (); scope 1 { debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _6; debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _9; debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - let _23: &T; + let _24: &T; scope 2 { - debug x => _23; + debug x => _24; } scope 16 (inlined as Iterator>::next) { let mut _6: std::ptr::NonNull; let _10: std::ptr::NonNull; let _12: std::ptr::NonNull; let mut _15: bool; - let mut _19: usize; - let _21: &T; + let mut _19: bool; + let mut _20: usize; + let _22: &T; scope 17 { let _11: *const T; scope 18 { @@ -56,7 +57,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 31 (inlined NonNull::::as_ref::<'_>) { - let _20: *const T; + let _21: *const T; scope 32 (inlined NonNull::::as_ptr) { } scope 33 (inlined std::ptr::mut_ptr::::cast_const) { @@ -134,13 +135,13 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { - StorageLive(_22); + StorageLive(_23); StorageLive(_10); StorageLive(_11); StorageLive(_18); - StorageLive(_19); + StorageLive(_20); StorageLive(_12); - StorageLive(_21); + StorageLive(_22); _10 = copy _6; _11 = copy _9; switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; @@ -168,76 +169,80 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageDead(_16); _6 = NonNull:: { pointer: copy _17 }; StorageDead(_17); - goto -> bb13; + goto -> bb10; } bb7: { StorageDead(_15); - goto -> bb10; + goto -> bb15; } bb8: { _18 = copy _11 as usize (Transmute); - switchInt(copy _18) -> [0: bb9, otherwise: bb12]; + StorageLive(_19); + _19 = Eq(copy _18, const 0_usize); + switchInt(move _19) -> [0: bb9, otherwise: bb14]; } bb9: { + StorageDead(_19); + _20 = SubUnchecked(copy _18, const 1_usize); + _9 = copy _20 as *const T (Transmute); goto -> bb10; } bb10: { + StorageLive(_21); + _21 = copy _10 as *const T (Transmute); + _22 = &(*_21); StorageDead(_21); + _23 = Option::<&T>::Some(copy _22); + StorageDead(_22); StorageDead(_12); - StorageDead(_19); + StorageDead(_20); StorageDead(_18); StorageDead(_11); StorageDead(_10); - StorageDead(_22); - drop(_2) -> [return: bb11, unwind continue]; + _24 = copy ((_23 as Some).0: &T); + StorageLive(_25); + _25 = &_2; + StorageLive(_26); + _26 = (copy _24,); + _27 = >::call(move _25, move _26) -> [return: bb11, unwind: bb12]; } bb11: { - return; - } - - bb12: { - _19 = SubUnchecked(copy _18, const 1_usize); - _9 = copy _19 as *const T (Transmute); - goto -> bb13; - } - - bb13: { - StorageLive(_20); - _20 = copy _10 as *const T (Transmute); - _21 = &(*_20); - StorageDead(_20); - _22 = Option::<&T>::Some(copy _21); - StorageDead(_21); - StorageDead(_12); - StorageDead(_19); - StorageDead(_18); - StorageDead(_11); - StorageDead(_10); - _23 = copy ((_22 as Some).0: &T); - StorageLive(_24); - _24 = &_2; - StorageLive(_25); - _25 = (copy _23,); - _26 = >::call(move _24, move _25) -> [return: bb14, unwind: bb15]; - } - - bb14: { + StorageDead(_26); StorageDead(_25); - StorageDead(_24); - StorageDead(_22); + StorageDead(_23); goto -> bb4; } - bb15 (cleanup): { - drop(_2) -> [return: bb16, unwind terminate(cleanup)]; + bb12 (cleanup): { + drop(_2) -> [return: bb13, unwind terminate(cleanup)]; } - bb16 (cleanup): { + bb13 (cleanup): { resume; } + + bb14: { + StorageDead(_19); + goto -> bb15; + } + + bb15: { + StorageDead(_22); + StorageDead(_12); + StorageDead(_20); + StorageDead(_18); + StorageDead(_11); + StorageDead(_10); + StorageDead(_23); + drop(_2) -> [return: bb16, unwind continue]; + } + + bb16: { + return; + } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir index cc0fce26149e..b14022b283dc 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir @@ -8,8 +8,9 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { let _4: std::ptr::NonNull; let mut _7: bool; let mut _10: std::ptr::NonNull; - let mut _12: usize; - let _14: &T; + let mut _12: bool; + let mut _13: usize; + let _15: &T; scope 2 { let _3: *const T; scope 3 { @@ -43,7 +44,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { } } scope 16 (inlined NonNull::::as_ref::<'_>) { - let _13: *const T; + let _14: *const T; scope 17 (inlined NonNull::::as_ptr) { } scope 18 (inlined std::ptr::mut_ptr::::cast_const) { @@ -57,9 +58,9 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { StorageLive(_2); StorageLive(_3); StorageLive(_11); - StorageLive(_12); + StorageLive(_13); StorageLive(_4); - StorageLive(_14); + StorageLive(_15); _2 = copy ((*_1).0: std::ptr::NonNull); _3 = copy ((*_1).1: *const T); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb4]; @@ -90,7 +91,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { StorageDead(_9); ((*_1).0: std::ptr::NonNull) = move _10; StorageDead(_10); - goto -> bb7; + goto -> bb6; } bb3: { @@ -101,33 +102,37 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { bb4: { _11 = copy _3 as usize (Transmute); - switchInt(copy _11) -> [0: bb5, otherwise: bb6]; + StorageLive(_12); + _12 = Eq(copy _11, const 0_usize); + switchInt(move _12) -> [0: bb5, otherwise: bb7]; } bb5: { - _0 = const {transmute(0x0000000000000000): Option<&T>}; - goto -> bb8; + StorageDead(_12); + _13 = SubUnchecked(copy _11, const 1_usize); + ((*_1).1: *const T) = copy _13 as *const T (Transmute); + goto -> bb6; } bb6: { - _12 = SubUnchecked(copy _11, const 1_usize); - ((*_1).1: *const T) = copy _12 as *const T (Transmute); - goto -> bb7; + StorageLive(_14); + _14 = copy _2 as *const T (Transmute); + _15 = &(*_14); + StorageDead(_14); + _0 = Option::<&T>::Some(copy _15); + goto -> bb8; } bb7: { - StorageLive(_13); - _13 = copy _2 as *const T (Transmute); - _14 = &(*_13); - StorageDead(_13); - _0 = Option::<&T>::Some(copy _14); + _0 = const {transmute(0x0000000000000000): Option<&T>}; + StorageDead(_12); goto -> bb8; } bb8: { - StorageDead(_14); + StorageDead(_15); StorageDead(_4); - StorageDead(_12); + StorageDead(_13); StorageDead(_11); StorageDead(_3); StorageDead(_2); diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir index cc0fce26149e..b14022b283dc 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir @@ -8,8 +8,9 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { let _4: std::ptr::NonNull; let mut _7: bool; let mut _10: std::ptr::NonNull; - let mut _12: usize; - let _14: &T; + let mut _12: bool; + let mut _13: usize; + let _15: &T; scope 2 { let _3: *const T; scope 3 { @@ -43,7 +44,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { } } scope 16 (inlined NonNull::::as_ref::<'_>) { - let _13: *const T; + let _14: *const T; scope 17 (inlined NonNull::::as_ptr) { } scope 18 (inlined std::ptr::mut_ptr::::cast_const) { @@ -57,9 +58,9 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { StorageLive(_2); StorageLive(_3); StorageLive(_11); - StorageLive(_12); + StorageLive(_13); StorageLive(_4); - StorageLive(_14); + StorageLive(_15); _2 = copy ((*_1).0: std::ptr::NonNull); _3 = copy ((*_1).1: *const T); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb4]; @@ -90,7 +91,7 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { StorageDead(_9); ((*_1).0: std::ptr::NonNull) = move _10; StorageDead(_10); - goto -> bb7; + goto -> bb6; } bb3: { @@ -101,33 +102,37 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { bb4: { _11 = copy _3 as usize (Transmute); - switchInt(copy _11) -> [0: bb5, otherwise: bb6]; + StorageLive(_12); + _12 = Eq(copy _11, const 0_usize); + switchInt(move _12) -> [0: bb5, otherwise: bb7]; } bb5: { - _0 = const {transmute(0x0000000000000000): Option<&T>}; - goto -> bb8; + StorageDead(_12); + _13 = SubUnchecked(copy _11, const 1_usize); + ((*_1).1: *const T) = copy _13 as *const T (Transmute); + goto -> bb6; } bb6: { - _12 = SubUnchecked(copy _11, const 1_usize); - ((*_1).1: *const T) = copy _12 as *const T (Transmute); - goto -> bb7; + StorageLive(_14); + _14 = copy _2 as *const T (Transmute); + _15 = &(*_14); + StorageDead(_14); + _0 = Option::<&T>::Some(copy _15); + goto -> bb8; } bb7: { - StorageLive(_13); - _13 = copy _2 as *const T (Transmute); - _14 = &(*_13); - StorageDead(_13); - _0 = Option::<&T>::Some(copy _14); + _0 = const {transmute(0x0000000000000000): Option<&T>}; + StorageDead(_12); goto -> bb8; } bb8: { - StorageDead(_14); + StorageDead(_15); StorageDead(_4); - StorageDead(_12); + StorageDead(_13); StorageDead(_11); StorageDead(_3); StorageDead(_2); From b49539e0490188136ae5805e144967ad6d510a2b Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 17 Jan 2026 15:08:53 -0800 Subject: [PATCH 2280/3801] Include a link to `count_ones` in the docs for `uN::count_zeros` --- library/core/src/num/uint_macros.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index eea5ce348355..57f0cd48fbe8 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -93,6 +93,28 @@ macro_rules! uint_impl { #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")] /// assert_eq!(max.count_zeros(), 0); /// ``` + /// + /// This is heavily dependent on the width of the type, and thus + /// might give surprising results depending on type inference: + /// ``` + /// # fn foo(_: u8) {} + /// # fn bar(_: u16) {} + /// let lucky = 7; + /// foo(lucky); + /// assert_eq!(lucky.count_zeros(), 5); + /// assert_eq!(lucky.count_ones(), 3); + /// + /// let lucky = 7; + /// bar(lucky); + /// assert_eq!(lucky.count_zeros(), 13); + /// assert_eq!(lucky.count_ones(), 3); + /// ``` + /// You might want to use [`Self::count_ones`] instead, or emphasize + /// the type you're using in the call rather than method syntax: + /// ``` + /// let small = 1; + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::count_zeros(small), ", stringify!($BITS_MINUS_ONE) ,");")] + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_math", since = "1.32.0")] #[must_use = "this returns the result of the operation, \ From bdc08aeb91626171a7dc5bfbc1e0d109770ee457 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 6 Jun 2024 12:49:31 -0700 Subject: [PATCH 2281/3801] Reword the caveats on `array::map` Thanks to 107634 and some improvements in LLVM (particularly `dead_on_unwind`), the method actually optimizes reasonably well now. So focus the discussion on the fundamental ordering differences where the optimizer might never be able to fix it because of the different behaviour, and encouraging `Iterator::map` where an array wasn't actually ever needed. --- library/core/src/array/mod.rs | 51 ++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 6cca2e6358b6..4a2cf1527744 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -516,20 +516,47 @@ impl [T; N] { /// /// # Note on performance and stack usage /// - /// Unfortunately, usages of this method are currently not always optimized - /// as well as they could be. This mainly concerns large arrays, as mapping - /// over small arrays seem to be optimized just fine. Also note that in - /// debug mode (i.e. without any optimizations), this method can use a lot - /// of stack space (a few times the size of the array or more). + /// Note that this method is *eager*. It evaluates `f` all `N` times before + /// returning the new array. /// - /// Therefore, in performance-critical code, try to avoid using this method - /// on large arrays or check the emitted code. Also try to avoid chained - /// maps (e.g. `arr.map(...).map(...)`). + /// That means that `arr.map(f).map(g)` is, in general, *not* equivalent to + /// `array.map(|x| g(f(x)))`, as the former calls `f` 4 times then `g` 4 times, + /// whereas the latter interleaves the calls (`fgfgfgfg`). /// - /// In many cases, you can instead use [`Iterator::map`] by calling `.iter()` - /// or `.into_iter()` on your array. `[T; N]::map` is only necessary if you - /// really need a new array of the same size as the result. Rust's lazy - /// iterators tend to get optimized very well. + /// A consequence of this is that it can have fairly-high stack usage, especially + /// in debug mode or for long arrays. The backend may be able to optimize it + /// away, but especially for complicated mappings it might not be able to. + /// + /// If you're doing a one-step `map` and really want an array as the result, + /// then absolutely use this method. Its implementation uses a bunch of tricks + /// to help the optimizer handle it well. Particularly for simple arrays, + /// like `[u8; 3]` or `[f32; 4]`, there's nothing to be concerned about. + /// + /// However, if you don't actually need an *array* of the results specifically, + /// just to process them, then you likely want [`Iterator::map`] instead. + /// + /// For example, rather than doing an array-to-array map of all the elements + /// in the array up-front and only iterating after that completes, + /// + /// ``` + /// # let my_array = [1, 2, 3]; + /// # let f = |x: i32| x + 1; + /// for x in my_array.map(f) { + /// // ... + /// } + /// ``` + /// + /// It's often better to use an iterator along the lines of + /// + /// ``` + /// # let my_array = [1, 2, 3]; + /// # let f = |x: i32| x + 1; + /// for x in my_array.into_iter().map(f) { + /// // ... + /// } + /// ``` + /// + /// as that's more likely to avoid large temporaries. /// /// /// # Examples From 216ca145fd5967d1ff8731b8cc76eca7b53cff03 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 17 Jan 2026 21:43:50 -0500 Subject: [PATCH 2282/3801] remove trailing periods in built-in attribute gate messages --- compiler/rustc_feature/src/builtin_attrs.rs | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 22753adb4c99..1fd6c3c10fab 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -678,7 +678,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_pass_indirectly_in_non_rustic_abis, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No, - "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic abis." + "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs" ), // Limits: @@ -1275,38 +1275,38 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_as_ptr, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, - "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations." + "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations" ), rustc_attr!( rustc_should_not_be_called_on_const_items, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, - "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts." + "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts" ), rustc_attr!( rustc_pass_by_value, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, - "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference." + "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference" ), rustc_attr!( rustc_never_returns_null_ptr, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, - "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers." + "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers" ), rustc_attr!( rustc_no_implicit_autorefs, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, - "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument." + "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument" ), rustc_attr!( rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No, - "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`." + "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`" ), rustc_attr!( rustc_coinductive, AttributeType::Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, - "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver." + "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver" ), rustc_attr!( rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No, - "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl." + "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl" ), rustc_attr!( rustc_preserve_ub_checks, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No, @@ -1333,7 +1333,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, "`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \ - the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`." + the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`" ), BuiltinAttribute { @@ -1396,7 +1396,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ from method dispatch when the receiver is of the following type, for compatibility in \ - editions < 2021 (array) or editions < 2024 (boxed_slice)." + editions < 2021 (array) or editions < 2024 (boxed_slice)" ), rustc_attr!( rustc_must_implement_one_of, Normal, template!(List: &["function1, function2, ..."]), From 7510f747a8599c430a054ba58d53dc8dae1465ee Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sun, 18 Jan 2026 11:40:42 +0800 Subject: [PATCH 2283/3801] Normalize type_const items even with feature `generic_const_exprs` --- .../rustc_trait_selection/src/traits/normalize.rs | 7 ++++++- tests/crashes/138089.rs | 2 ++ .../const-generics/mgca/cyclic-type-const-151251.rs | 11 +++++++++++ .../mgca/cyclic-type-const-151251.stderr | 11 +++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/ui/const-generics/mgca/cyclic-type-const-151251.rs create mode 100644 tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 71e9914f93fa..24854990fe71 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -433,7 +433,12 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx #[instrument(skip(self), level = "debug")] fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { let tcx = self.selcx.tcx(); - if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &ct) { + + if tcx.features().generic_const_exprs() + // Normalize type_const items even with feature `generic_const_exprs`. + && !matches!(ct.kind(), ty::ConstKind::Unevaluated(uv) if tcx.is_type_const(uv.def)) + || !needs_normalization(self.selcx.infcx, &ct) + { return ct; } diff --git a/tests/crashes/138089.rs b/tests/crashes/138089.rs index 054d1b216959..f4864971ae5d 100644 --- a/tests/crashes/138089.rs +++ b/tests/crashes/138089.rs @@ -1,4 +1,6 @@ //@ known-bug: #138089 +//@ needs-rustc-debug-assertions + #![feature(generic_const_exprs)] #![feature(min_generic_const_args)] #![feature(inherent_associated_types)] diff --git a/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs b/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs new file mode 100644 index 000000000000..823a6d58bf47 --- /dev/null +++ b/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs @@ -0,0 +1,11 @@ +//@ needs-rustc-debug-assertions + +#![feature(min_generic_const_args)] +#![feature(generic_const_exprs)] +#![expect(incomplete_features)] + +#[type_const] +const A: u8 = A; +//~^ ERROR overflow normalizing the unevaluated constant `A` + +fn main() {} diff --git a/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr b/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr new file mode 100644 index 000000000000..1ce2af817277 --- /dev/null +++ b/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow normalizing the unevaluated constant `A` + --> $DIR/cyclic-type-const-151251.rs:8:1 + | +LL | const A: u8 = A; + | ^^^^^^^^^^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. From cf5a7da23f59af669aab128d919d04b96d9ec08b Mon Sep 17 00:00:00 2001 From: tuturuu Date: Sun, 18 Jan 2026 05:16:29 +0100 Subject: [PATCH 2284/3801] move some tests --- .../associated-type-as-value.rs} | 0 .../associated-type-as-value.stderr} | 0 tests/ui/{issues/issue-17441.rs => cast/cast-to-unsized-type.rs} | 0 .../issue-17441.stderr => cast/cast-to-unsized-type.stderr} | 0 .../issue-2995.rs => cast/non-primitive-isize-ref-cast.rs} | 0 .../non-primitive-isize-ref-cast.stderr} | 0 .../ui/{issues/issue-19922.rs => enum/enum-nonexisting-field.rs} | 0 .../issue-19922.stderr => enum/enum-nonexisting-field.stderr} | 0 .../ui/{issues/issue-17351.rs => lint/unused/unused-trait-fn.rs} | 0 .../issue-17351.stderr => lint/unused/unused-trait-fn.stderr} | 0 .../issue-22599.rs => lint/unused/unused-var-in-match-arm.rs} | 0 .../unused/unused-var-in-match-arm.stderr} | 0 .../issue-19692.rs => methods/method-not-found-on-struct.rs} | 0 .../method-not-found-on-struct.stderr} | 0 .../{issues/issue-34209.rs => pattern/enum-variant-not-found.rs} | 0 .../issue-34209.stderr => pattern/enum-variant-not-found.stderr} | 0 .../issue-16745.rs => pattern/match-constant-and-byte-literal.rs} | 0 .../auxiliary/imported-enum-is-private.rs} | 0 .../issue-11680.rs => privacy/imported-enum-is-private.rs} | 0 .../imported-enum-is-private.stderr} | 0 .../issue-26472.rs => privacy/private-struct-field-in-module.rs} | 0 .../private-struct-field-in-module.stderr} | 0 .../panic-with-unspecified-type.rs} | 0 .../panic-with-unspecified-type.stderr} | 0 .../send-with-unspecified-type.rs} | 0 .../send-with-unspecified-type.stderr} | 0 .../swap-with-unspecified-type.rs} | 0 .../swap-with-unspecified-type.stderr} | 0 .../issue-35241.rs => type/struct-constructor-as-value.rs} | 0 .../struct-constructor-as-value.stderr} | 0 30 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-38919.rs => associated-types/associated-type-as-value.rs} (100%) rename tests/ui/{issues/issue-38919.stderr => associated-types/associated-type-as-value.stderr} (100%) rename tests/ui/{issues/issue-17441.rs => cast/cast-to-unsized-type.rs} (100%) rename tests/ui/{issues/issue-17441.stderr => cast/cast-to-unsized-type.stderr} (100%) rename tests/ui/{issues/issue-2995.rs => cast/non-primitive-isize-ref-cast.rs} (100%) rename tests/ui/{issues/issue-2995.stderr => cast/non-primitive-isize-ref-cast.stderr} (100%) rename tests/ui/{issues/issue-19922.rs => enum/enum-nonexisting-field.rs} (100%) rename tests/ui/{issues/issue-19922.stderr => enum/enum-nonexisting-field.stderr} (100%) rename tests/ui/{issues/issue-17351.rs => lint/unused/unused-trait-fn.rs} (100%) rename tests/ui/{issues/issue-17351.stderr => lint/unused/unused-trait-fn.stderr} (100%) rename tests/ui/{issues/issue-22599.rs => lint/unused/unused-var-in-match-arm.rs} (100%) rename tests/ui/{issues/issue-22599.stderr => lint/unused/unused-var-in-match-arm.stderr} (100%) rename tests/ui/{issues/issue-19692.rs => methods/method-not-found-on-struct.rs} (100%) rename tests/ui/{issues/issue-19692.stderr => methods/method-not-found-on-struct.stderr} (100%) rename tests/ui/{issues/issue-34209.rs => pattern/enum-variant-not-found.rs} (100%) rename tests/ui/{issues/issue-34209.stderr => pattern/enum-variant-not-found.stderr} (100%) rename tests/ui/{issues/issue-16745.rs => pattern/match-constant-and-byte-literal.rs} (100%) rename tests/ui/{issues/auxiliary/issue-11680.rs => privacy/auxiliary/imported-enum-is-private.rs} (100%) rename tests/ui/{issues/issue-11680.rs => privacy/imported-enum-is-private.rs} (100%) rename tests/ui/{issues/issue-11680.stderr => privacy/imported-enum-is-private.stderr} (100%) rename tests/ui/{issues/issue-26472.rs => privacy/private-struct-field-in-module.rs} (100%) rename tests/ui/{issues/issue-26472.stderr => privacy/private-struct-field-in-module.stderr} (100%) rename tests/ui/{issues/issue-16966.rs => type-inference/panic-with-unspecified-type.rs} (100%) rename tests/ui/{issues/issue-16966.stderr => type-inference/panic-with-unspecified-type.stderr} (100%) rename tests/ui/{issues/issue-25368.rs => type-inference/send-with-unspecified-type.rs} (100%) rename tests/ui/{issues/issue-25368.stderr => type-inference/send-with-unspecified-type.stderr} (100%) rename tests/ui/{issues/issue-24013.rs => type-inference/swap-with-unspecified-type.rs} (100%) rename tests/ui/{issues/issue-24013.stderr => type-inference/swap-with-unspecified-type.stderr} (100%) rename tests/ui/{issues/issue-35241.rs => type/struct-constructor-as-value.rs} (100%) rename tests/ui/{issues/issue-35241.stderr => type/struct-constructor-as-value.stderr} (100%) diff --git a/tests/ui/issues/issue-38919.rs b/tests/ui/associated-types/associated-type-as-value.rs similarity index 100% rename from tests/ui/issues/issue-38919.rs rename to tests/ui/associated-types/associated-type-as-value.rs diff --git a/tests/ui/issues/issue-38919.stderr b/tests/ui/associated-types/associated-type-as-value.stderr similarity index 100% rename from tests/ui/issues/issue-38919.stderr rename to tests/ui/associated-types/associated-type-as-value.stderr diff --git a/tests/ui/issues/issue-17441.rs b/tests/ui/cast/cast-to-unsized-type.rs similarity index 100% rename from tests/ui/issues/issue-17441.rs rename to tests/ui/cast/cast-to-unsized-type.rs diff --git a/tests/ui/issues/issue-17441.stderr b/tests/ui/cast/cast-to-unsized-type.stderr similarity index 100% rename from tests/ui/issues/issue-17441.stderr rename to tests/ui/cast/cast-to-unsized-type.stderr diff --git a/tests/ui/issues/issue-2995.rs b/tests/ui/cast/non-primitive-isize-ref-cast.rs similarity index 100% rename from tests/ui/issues/issue-2995.rs rename to tests/ui/cast/non-primitive-isize-ref-cast.rs diff --git a/tests/ui/issues/issue-2995.stderr b/tests/ui/cast/non-primitive-isize-ref-cast.stderr similarity index 100% rename from tests/ui/issues/issue-2995.stderr rename to tests/ui/cast/non-primitive-isize-ref-cast.stderr diff --git a/tests/ui/issues/issue-19922.rs b/tests/ui/enum/enum-nonexisting-field.rs similarity index 100% rename from tests/ui/issues/issue-19922.rs rename to tests/ui/enum/enum-nonexisting-field.rs diff --git a/tests/ui/issues/issue-19922.stderr b/tests/ui/enum/enum-nonexisting-field.stderr similarity index 100% rename from tests/ui/issues/issue-19922.stderr rename to tests/ui/enum/enum-nonexisting-field.stderr diff --git a/tests/ui/issues/issue-17351.rs b/tests/ui/lint/unused/unused-trait-fn.rs similarity index 100% rename from tests/ui/issues/issue-17351.rs rename to tests/ui/lint/unused/unused-trait-fn.rs diff --git a/tests/ui/issues/issue-17351.stderr b/tests/ui/lint/unused/unused-trait-fn.stderr similarity index 100% rename from tests/ui/issues/issue-17351.stderr rename to tests/ui/lint/unused/unused-trait-fn.stderr diff --git a/tests/ui/issues/issue-22599.rs b/tests/ui/lint/unused/unused-var-in-match-arm.rs similarity index 100% rename from tests/ui/issues/issue-22599.rs rename to tests/ui/lint/unused/unused-var-in-match-arm.rs diff --git a/tests/ui/issues/issue-22599.stderr b/tests/ui/lint/unused/unused-var-in-match-arm.stderr similarity index 100% rename from tests/ui/issues/issue-22599.stderr rename to tests/ui/lint/unused/unused-var-in-match-arm.stderr diff --git a/tests/ui/issues/issue-19692.rs b/tests/ui/methods/method-not-found-on-struct.rs similarity index 100% rename from tests/ui/issues/issue-19692.rs rename to tests/ui/methods/method-not-found-on-struct.rs diff --git a/tests/ui/issues/issue-19692.stderr b/tests/ui/methods/method-not-found-on-struct.stderr similarity index 100% rename from tests/ui/issues/issue-19692.stderr rename to tests/ui/methods/method-not-found-on-struct.stderr diff --git a/tests/ui/issues/issue-34209.rs b/tests/ui/pattern/enum-variant-not-found.rs similarity index 100% rename from tests/ui/issues/issue-34209.rs rename to tests/ui/pattern/enum-variant-not-found.rs diff --git a/tests/ui/issues/issue-34209.stderr b/tests/ui/pattern/enum-variant-not-found.stderr similarity index 100% rename from tests/ui/issues/issue-34209.stderr rename to tests/ui/pattern/enum-variant-not-found.stderr diff --git a/tests/ui/issues/issue-16745.rs b/tests/ui/pattern/match-constant-and-byte-literal.rs similarity index 100% rename from tests/ui/issues/issue-16745.rs rename to tests/ui/pattern/match-constant-and-byte-literal.rs diff --git a/tests/ui/issues/auxiliary/issue-11680.rs b/tests/ui/privacy/auxiliary/imported-enum-is-private.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-11680.rs rename to tests/ui/privacy/auxiliary/imported-enum-is-private.rs diff --git a/tests/ui/issues/issue-11680.rs b/tests/ui/privacy/imported-enum-is-private.rs similarity index 100% rename from tests/ui/issues/issue-11680.rs rename to tests/ui/privacy/imported-enum-is-private.rs diff --git a/tests/ui/issues/issue-11680.stderr b/tests/ui/privacy/imported-enum-is-private.stderr similarity index 100% rename from tests/ui/issues/issue-11680.stderr rename to tests/ui/privacy/imported-enum-is-private.stderr diff --git a/tests/ui/issues/issue-26472.rs b/tests/ui/privacy/private-struct-field-in-module.rs similarity index 100% rename from tests/ui/issues/issue-26472.rs rename to tests/ui/privacy/private-struct-field-in-module.rs diff --git a/tests/ui/issues/issue-26472.stderr b/tests/ui/privacy/private-struct-field-in-module.stderr similarity index 100% rename from tests/ui/issues/issue-26472.stderr rename to tests/ui/privacy/private-struct-field-in-module.stderr diff --git a/tests/ui/issues/issue-16966.rs b/tests/ui/type-inference/panic-with-unspecified-type.rs similarity index 100% rename from tests/ui/issues/issue-16966.rs rename to tests/ui/type-inference/panic-with-unspecified-type.rs diff --git a/tests/ui/issues/issue-16966.stderr b/tests/ui/type-inference/panic-with-unspecified-type.stderr similarity index 100% rename from tests/ui/issues/issue-16966.stderr rename to tests/ui/type-inference/panic-with-unspecified-type.stderr diff --git a/tests/ui/issues/issue-25368.rs b/tests/ui/type-inference/send-with-unspecified-type.rs similarity index 100% rename from tests/ui/issues/issue-25368.rs rename to tests/ui/type-inference/send-with-unspecified-type.rs diff --git a/tests/ui/issues/issue-25368.stderr b/tests/ui/type-inference/send-with-unspecified-type.stderr similarity index 100% rename from tests/ui/issues/issue-25368.stderr rename to tests/ui/type-inference/send-with-unspecified-type.stderr diff --git a/tests/ui/issues/issue-24013.rs b/tests/ui/type-inference/swap-with-unspecified-type.rs similarity index 100% rename from tests/ui/issues/issue-24013.rs rename to tests/ui/type-inference/swap-with-unspecified-type.rs diff --git a/tests/ui/issues/issue-24013.stderr b/tests/ui/type-inference/swap-with-unspecified-type.stderr similarity index 100% rename from tests/ui/issues/issue-24013.stderr rename to tests/ui/type-inference/swap-with-unspecified-type.stderr diff --git a/tests/ui/issues/issue-35241.rs b/tests/ui/type/struct-constructor-as-value.rs similarity index 100% rename from tests/ui/issues/issue-35241.rs rename to tests/ui/type/struct-constructor-as-value.rs diff --git a/tests/ui/issues/issue-35241.stderr b/tests/ui/type/struct-constructor-as-value.stderr similarity index 100% rename from tests/ui/issues/issue-35241.stderr rename to tests/ui/type/struct-constructor-as-value.stderr From 2c7969a0cd4217900f96511b16117a0ef31836c4 Mon Sep 17 00:00:00 2001 From: tuturuu Date: Sun, 18 Jan 2026 06:10:16 +0100 Subject: [PATCH 2285/3801] add metadata and bless moved tests --- .../ui/associated-types/associated-type-as-value.rs | 2 ++ .../associated-types/associated-type-as-value.stderr | 2 +- tests/ui/cast/cast-to-unsized-type.rs | 2 ++ tests/ui/cast/cast-to-unsized-type.stderr | 12 ++++++------ tests/ui/cast/non-primitive-isize-ref-cast.rs | 2 ++ tests/ui/cast/non-primitive-isize-ref-cast.stderr | 2 +- tests/ui/enum/enum-nonexisting-field.rs | 2 ++ tests/ui/enum/enum-nonexisting-field.stderr | 2 +- tests/ui/lint/unused/unused-trait-fn.rs | 1 + tests/ui/lint/unused/unused-trait-fn.stderr | 2 +- tests/ui/lint/unused/unused-var-in-match-arm.rs | 1 + tests/ui/lint/unused/unused-var-in-match-arm.stderr | 4 ++-- tests/ui/methods/method-not-found-on-struct.rs | 2 ++ tests/ui/methods/method-not-found-on-struct.stderr | 2 +- tests/ui/pattern/enum-variant-not-found.rs | 2 ++ tests/ui/pattern/enum-variant-not-found.stderr | 2 +- tests/ui/pattern/match-constant-and-byte-literal.rs | 1 + .../ui/privacy/auxiliary/imported-enum-is-private.rs | 2 ++ tests/ui/privacy/imported-enum-is-private.rs | 5 +++-- tests/ui/privacy/imported-enum-is-private.stderr | 8 ++++---- tests/ui/privacy/private-struct-field-in-module.rs | 2 ++ .../ui/privacy/private-struct-field-in-module.stderr | 4 ++-- .../ui/type-inference/panic-with-unspecified-type.rs | 1 + .../panic-with-unspecified-type.stderr | 2 +- .../ui/type-inference/send-with-unspecified-type.rs | 2 ++ .../type-inference/send-with-unspecified-type.stderr | 2 +- .../ui/type-inference/swap-with-unspecified-type.rs | 2 ++ .../type-inference/swap-with-unspecified-type.stderr | 2 +- tests/ui/type/struct-constructor-as-value.rs | 2 ++ tests/ui/type/struct-constructor-as-value.stderr | 2 +- 30 files changed, 53 insertions(+), 26 deletions(-) diff --git a/tests/ui/associated-types/associated-type-as-value.rs b/tests/ui/associated-types/associated-type-as-value.rs index 3d28f1936b47..ddc808236658 100644 --- a/tests/ui/associated-types/associated-type-as-value.rs +++ b/tests/ui/associated-types/associated-type-as-value.rs @@ -1,3 +1,5 @@ +//! regression test for + fn foo() { T::Item; //~ ERROR no associated item named `Item` found } diff --git a/tests/ui/associated-types/associated-type-as-value.stderr b/tests/ui/associated-types/associated-type-as-value.stderr index 4a4bd2ee43d8..c553582b3907 100644 --- a/tests/ui/associated-types/associated-type-as-value.stderr +++ b/tests/ui/associated-types/associated-type-as-value.stderr @@ -1,5 +1,5 @@ error[E0599]: no associated item named `Item` found for type parameter `T` in the current scope - --> $DIR/issue-38919.rs:2:8 + --> $DIR/associated-type-as-value.rs:4:8 | LL | fn foo() { | - associated item `Item` not found for this type parameter diff --git a/tests/ui/cast/cast-to-unsized-type.rs b/tests/ui/cast/cast-to-unsized-type.rs index e5f83c4ebadd..4c7ca49fd98d 100644 --- a/tests/ui/cast/cast-to-unsized-type.rs +++ b/tests/ui/cast/cast-to-unsized-type.rs @@ -1,3 +1,5 @@ +//! regression test for + fn main() { let _foo = &[1_usize, 2] as [usize]; //~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]` diff --git a/tests/ui/cast/cast-to-unsized-type.stderr b/tests/ui/cast/cast-to-unsized-type.stderr index 96aad879e24d..087cfac77484 100644 --- a/tests/ui/cast/cast-to-unsized-type.stderr +++ b/tests/ui/cast/cast-to-unsized-type.stderr @@ -1,5 +1,5 @@ error[E0620]: cast to unsized type: `&[usize; 2]` as `[usize]` - --> $DIR/issue-17441.rs:2:16 + --> $DIR/cast-to-unsized-type.rs:4:16 | LL | let _foo = &[1_usize, 2] as [usize]; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | let _foo = &[1_usize, 2] as &[usize]; | + error[E0620]: cast to unsized type: `Box` as `dyn Debug` - --> $DIR/issue-17441.rs:5:16 + --> $DIR/cast-to-unsized-type.rs:7:16 | LL | let _bar = Box::new(1_usize) as dyn std::fmt::Debug; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -21,25 +21,25 @@ LL | let _bar = Box::new(1_usize) as Box; | ++++ + error[E0620]: cast to unsized type: `usize` as `dyn Debug` - --> $DIR/issue-17441.rs:8:16 + --> $DIR/cast-to-unsized-type.rs:10:16 | LL | let _baz = 1_usize as dyn std::fmt::Debug; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider using a box or reference as appropriate - --> $DIR/issue-17441.rs:8:16 + --> $DIR/cast-to-unsized-type.rs:10:16 | LL | let _baz = 1_usize as dyn std::fmt::Debug; | ^^^^^^^ error[E0620]: cast to unsized type: `[usize; 2]` as `[usize]` - --> $DIR/issue-17441.rs:11:17 + --> $DIR/cast-to-unsized-type.rs:13:17 | LL | let _quux = [1_usize, 2] as [usize]; | ^^^^^^^^^^^^^^^^^^^^^^^ | help: consider using a box or reference as appropriate - --> $DIR/issue-17441.rs:11:17 + --> $DIR/cast-to-unsized-type.rs:13:17 | LL | let _quux = [1_usize, 2] as [usize]; | ^^^^^^^^^^^^ diff --git a/tests/ui/cast/non-primitive-isize-ref-cast.rs b/tests/ui/cast/non-primitive-isize-ref-cast.rs index 0da7909480d2..95259456eede 100644 --- a/tests/ui/cast/non-primitive-isize-ref-cast.rs +++ b/tests/ui/cast/non-primitive-isize-ref-cast.rs @@ -1,3 +1,5 @@ +//! regression test for + fn bad (p: *const isize) { let _q: &isize = p as &isize; //~ ERROR non-primitive cast } diff --git a/tests/ui/cast/non-primitive-isize-ref-cast.stderr b/tests/ui/cast/non-primitive-isize-ref-cast.stderr index f4a08e1751fc..3f4c171d3dc7 100644 --- a/tests/ui/cast/non-primitive-isize-ref-cast.stderr +++ b/tests/ui/cast/non-primitive-isize-ref-cast.stderr @@ -1,5 +1,5 @@ error[E0605]: non-primitive cast: `*const isize` as `&isize` - --> $DIR/issue-2995.rs:2:22 + --> $DIR/non-primitive-isize-ref-cast.rs:4:22 | LL | let _q: &isize = p as &isize; | ^^^^^^^^^^^ invalid cast diff --git a/tests/ui/enum/enum-nonexisting-field.rs b/tests/ui/enum/enum-nonexisting-field.rs index fede86f22afd..837430340f33 100644 --- a/tests/ui/enum/enum-nonexisting-field.rs +++ b/tests/ui/enum/enum-nonexisting-field.rs @@ -1,3 +1,5 @@ +//! regression test for + enum Homura { Akemi { madoka: () } } diff --git a/tests/ui/enum/enum-nonexisting-field.stderr b/tests/ui/enum/enum-nonexisting-field.stderr index 0355d3a89710..22bfa08dadb3 100644 --- a/tests/ui/enum/enum-nonexisting-field.stderr +++ b/tests/ui/enum/enum-nonexisting-field.stderr @@ -1,5 +1,5 @@ error[E0559]: variant `Homura::Akemi` has no field named `kaname` - --> $DIR/issue-19922.rs:6:34 + --> $DIR/enum-nonexisting-field.rs:8:34 | LL | let homura = Homura::Akemi { kaname: () }; | ^^^^^^ `Homura::Akemi` does not have this field diff --git a/tests/ui/lint/unused/unused-trait-fn.rs b/tests/ui/lint/unused/unused-trait-fn.rs index 86049377198c..57b39c0de17e 100644 --- a/tests/ui/lint/unused/unused-trait-fn.rs +++ b/tests/ui/lint/unused/unused-trait-fn.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass trait Str { fn foo(&self) {} } //~ WARN method `foo` is never used diff --git a/tests/ui/lint/unused/unused-trait-fn.stderr b/tests/ui/lint/unused/unused-trait-fn.stderr index 043d4ffc7808..f33fed29c94c 100644 --- a/tests/ui/lint/unused/unused-trait-fn.stderr +++ b/tests/ui/lint/unused/unused-trait-fn.stderr @@ -1,5 +1,5 @@ warning: method `foo` is never used - --> $DIR/issue-17351.rs:3:16 + --> $DIR/unused-trait-fn.rs:4:16 | LL | trait Str { fn foo(&self) {} } | --- ^^^ diff --git a/tests/ui/lint/unused/unused-var-in-match-arm.rs b/tests/ui/lint/unused/unused-var-in-match-arm.rs index 05096e5c1853..780225f98dbb 100644 --- a/tests/ui/lint/unused/unused-var-in-match-arm.rs +++ b/tests/ui/lint/unused/unused-var-in-match-arm.rs @@ -1,3 +1,4 @@ +//! regression test for #![deny(unused_variables)] fn f(_: i32) {} diff --git a/tests/ui/lint/unused/unused-var-in-match-arm.stderr b/tests/ui/lint/unused/unused-var-in-match-arm.stderr index b599f6febe31..a1b9849293ef 100644 --- a/tests/ui/lint/unused/unused-var-in-match-arm.stderr +++ b/tests/ui/lint/unused/unused-var-in-match-arm.stderr @@ -1,11 +1,11 @@ error: unused variable: `a` - --> $DIR/issue-22599.rs:8:19 + --> $DIR/unused-var-in-match-arm.rs:9:19 | LL | v = match 0 { a => 0 }; | ^ help: if this is intentional, prefix it with an underscore: `_a` | note: the lint level is defined here - --> $DIR/issue-22599.rs:1:9 + --> $DIR/unused-var-in-match-arm.rs:2:9 | LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/methods/method-not-found-on-struct.rs b/tests/ui/methods/method-not-found-on-struct.rs index 99eccc8a8175..b2a457ed19e5 100644 --- a/tests/ui/methods/method-not-found-on-struct.rs +++ b/tests/ui/methods/method-not-found-on-struct.rs @@ -1,3 +1,5 @@ +//! regression test for + struct Homura; fn akemi(homura: Homura) { diff --git a/tests/ui/methods/method-not-found-on-struct.stderr b/tests/ui/methods/method-not-found-on-struct.stderr index 1e3d7a2e2f51..3bf775f30a7a 100644 --- a/tests/ui/methods/method-not-found-on-struct.stderr +++ b/tests/ui/methods/method-not-found-on-struct.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `kaname` found for struct `Homura` in the current scope - --> $DIR/issue-19692.rs:4:40 + --> $DIR/method-not-found-on-struct.rs:6:40 | LL | struct Homura; | ------------- method `kaname` not found for this struct diff --git a/tests/ui/pattern/enum-variant-not-found.rs b/tests/ui/pattern/enum-variant-not-found.rs index 632ddb91b36f..e78e28abeb6e 100644 --- a/tests/ui/pattern/enum-variant-not-found.rs +++ b/tests/ui/pattern/enum-variant-not-found.rs @@ -1,3 +1,5 @@ +//! regression test for + enum S { A, } diff --git a/tests/ui/pattern/enum-variant-not-found.stderr b/tests/ui/pattern/enum-variant-not-found.stderr index 83b40d0c0816..6db4cf79d6b3 100644 --- a/tests/ui/pattern/enum-variant-not-found.stderr +++ b/tests/ui/pattern/enum-variant-not-found.stderr @@ -1,5 +1,5 @@ error[E0599]: no variant named `B` found for enum `S` - --> $DIR/issue-34209.rs:7:12 + --> $DIR/enum-variant-not-found.rs:9:12 | LL | enum S { | ------ variant `B` not found here diff --git a/tests/ui/pattern/match-constant-and-byte-literal.rs b/tests/ui/pattern/match-constant-and-byte-literal.rs index 99c85bcffcf8..7a793478016d 100644 --- a/tests/ui/pattern/match-constant-and-byte-literal.rs +++ b/tests/ui/pattern/match-constant-and-byte-literal.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass fn main() { const X: u8 = 0; diff --git a/tests/ui/privacy/auxiliary/imported-enum-is-private.rs b/tests/ui/privacy/auxiliary/imported-enum-is-private.rs index 74abbf0bf8cd..ea847d9aff13 100644 --- a/tests/ui/privacy/auxiliary/imported-enum-is-private.rs +++ b/tests/ui/privacy/auxiliary/imported-enum-is-private.rs @@ -1,3 +1,5 @@ +//! auxiliary crate for + enum Foo { Bar(isize) } diff --git a/tests/ui/privacy/imported-enum-is-private.rs b/tests/ui/privacy/imported-enum-is-private.rs index 9f3dfebcc812..b628676a25c6 100644 --- a/tests/ui/privacy/imported-enum-is-private.rs +++ b/tests/ui/privacy/imported-enum-is-private.rs @@ -1,6 +1,7 @@ -//@ aux-build:issue-11680.rs +//! regression test for +//@ aux-build:imported-enum-is-private.rs -extern crate issue_11680 as other; +extern crate imported_enum_is_private as other; fn main() { let _b = other::Foo::Bar(1); diff --git a/tests/ui/privacy/imported-enum-is-private.stderr b/tests/ui/privacy/imported-enum-is-private.stderr index 5bcf93de811f..cae1ebb0e29e 100644 --- a/tests/ui/privacy/imported-enum-is-private.stderr +++ b/tests/ui/privacy/imported-enum-is-private.stderr @@ -1,5 +1,5 @@ error[E0603]: enum `Foo` is private - --> $DIR/issue-11680.rs:6:21 + --> $DIR/imported-enum-is-private.rs:7:21 | LL | let _b = other::Foo::Bar(1); | ^^^ --- tuple variant `Bar` is not publicly re-exported @@ -7,13 +7,13 @@ LL | let _b = other::Foo::Bar(1); | private enum | note: the enum `Foo` is defined here - --> $DIR/auxiliary/issue-11680.rs:1:1 + --> $DIR/auxiliary/imported-enum-is-private.rs:3:1 | LL | enum Foo { | ^^^^^^^^ error[E0603]: enum `Foo` is private - --> $DIR/issue-11680.rs:9:27 + --> $DIR/imported-enum-is-private.rs:10:27 | LL | let _b = other::test::Foo::Bar(1); | ^^^ --- tuple variant `Bar` is not publicly re-exported @@ -21,7 +21,7 @@ LL | let _b = other::test::Foo::Bar(1); | private enum | note: the enum `Foo` is defined here - --> $DIR/auxiliary/issue-11680.rs:6:5 + --> $DIR/auxiliary/imported-enum-is-private.rs:8:5 | LL | enum Foo { | ^^^^^^^^ diff --git a/tests/ui/privacy/private-struct-field-in-module.rs b/tests/ui/privacy/private-struct-field-in-module.rs index b100c59ad0bd..7ed8def1c691 100644 --- a/tests/ui/privacy/private-struct-field-in-module.rs +++ b/tests/ui/privacy/private-struct-field-in-module.rs @@ -1,3 +1,5 @@ +//! regression test for + mod sub { pub struct S { len: usize } impl S { diff --git a/tests/ui/privacy/private-struct-field-in-module.stderr b/tests/ui/privacy/private-struct-field-in-module.stderr index d7134bff1761..2394686f69ca 100644 --- a/tests/ui/privacy/private-struct-field-in-module.stderr +++ b/tests/ui/privacy/private-struct-field-in-module.stderr @@ -1,5 +1,5 @@ error[E0616]: field `len` of struct `S` is private - --> $DIR/issue-26472.rs:11:15 + --> $DIR/private-struct-field-in-module.rs:13:15 | LL | let v = s.len; | ^^^ private field @@ -10,7 +10,7 @@ LL | let v = s.len(); | ++ error[E0616]: field `len` of struct `S` is private - --> $DIR/issue-26472.rs:12:7 + --> $DIR/private-struct-field-in-module.rs:14:7 | LL | s.len = v; | ^^^ private field diff --git a/tests/ui/type-inference/panic-with-unspecified-type.rs b/tests/ui/type-inference/panic-with-unspecified-type.rs index 66a3fadac8d9..0f96759e8144 100644 --- a/tests/ui/type-inference/panic-with-unspecified-type.rs +++ b/tests/ui/type-inference/panic-with-unspecified-type.rs @@ -1,3 +1,4 @@ +//! regression test for //@ edition:2015..2021 fn main() { panic!(std::default::Default::default()); diff --git a/tests/ui/type-inference/panic-with-unspecified-type.stderr b/tests/ui/type-inference/panic-with-unspecified-type.stderr index e294d8830de0..5f08a7552632 100644 --- a/tests/ui/type-inference/panic-with-unspecified-type.stderr +++ b/tests/ui/type-inference/panic-with-unspecified-type.stderr @@ -1,5 +1,5 @@ error[E0283]: type annotations needed - --> $DIR/issue-16966.rs:3:12 + --> $DIR/panic-with-unspecified-type.rs:4:12 | LL | panic!(std::default::Default::default()); | -------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- diff --git a/tests/ui/type-inference/send-with-unspecified-type.rs b/tests/ui/type-inference/send-with-unspecified-type.rs index 4be83457f7a8..4c2de025d69c 100644 --- a/tests/ui/type-inference/send-with-unspecified-type.rs +++ b/tests/ui/type-inference/send-with-unspecified-type.rs @@ -1,3 +1,5 @@ +//! regression test for + use std::sync::mpsc::channel; use std::thread::spawn; use std::marker::PhantomData; diff --git a/tests/ui/type-inference/send-with-unspecified-type.stderr b/tests/ui/type-inference/send-with-unspecified-type.stderr index 23f1441e69dc..85692e8ad0cd 100644 --- a/tests/ui/type-inference/send-with-unspecified-type.stderr +++ b/tests/ui/type-inference/send-with-unspecified-type.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/issue-25368.rs:11:27 + --> $DIR/send-with-unspecified-type.rs:13:27 | LL | tx.send(Foo{ foo: PhantomData }); | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData` diff --git a/tests/ui/type-inference/swap-with-unspecified-type.rs b/tests/ui/type-inference/swap-with-unspecified-type.rs index c6d301671272..db415df19e99 100644 --- a/tests/ui/type-inference/swap-with-unspecified-type.rs +++ b/tests/ui/type-inference/swap-with-unspecified-type.rs @@ -1,3 +1,5 @@ +//! regression test for + fn main() { use std::mem::{transmute, swap}; let a = 1; diff --git a/tests/ui/type-inference/swap-with-unspecified-type.stderr b/tests/ui/type-inference/swap-with-unspecified-type.stderr index 37a86ecc5437..eaaed559ebf1 100644 --- a/tests/ui/type-inference/swap-with-unspecified-type.stderr +++ b/tests/ui/type-inference/swap-with-unspecified-type.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/issue-24013.rs:5:13 + --> $DIR/swap-with-unspecified-type.rs:7:13 | LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `swap` diff --git a/tests/ui/type/struct-constructor-as-value.rs b/tests/ui/type/struct-constructor-as-value.rs index 2fa762475da9..9cac1caf86ec 100644 --- a/tests/ui/type/struct-constructor-as-value.rs +++ b/tests/ui/type/struct-constructor-as-value.rs @@ -1,3 +1,5 @@ +//! regression test for + struct Foo(u32); fn test() -> Foo { Foo } //~ ERROR mismatched types diff --git a/tests/ui/type/struct-constructor-as-value.stderr b/tests/ui/type/struct-constructor-as-value.stderr index 6f6602793fdb..5915f971b324 100644 --- a/tests/ui/type/struct-constructor-as-value.stderr +++ b/tests/ui/type/struct-constructor-as-value.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-35241.rs:3:20 + --> $DIR/struct-constructor-as-value.rs:5:20 | LL | struct Foo(u32); | ---------- `Foo` defines a struct constructor here, which should be called From db9f9e65013419e87af78c54727f1b4f44bf75b2 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sun, 18 Jan 2026 13:38:19 +0800 Subject: [PATCH 2286/3801] Use find_attr instead of attr::contains_name in lower_const_item_rhs --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- .../type-const-assoc-const-without-body.rs | 19 +++++++++++++++++++ ...type-const-assoc-const-without-body.stderr | 10 ++++++++++ ...const-inherent-assoc-const-without-body.rs | 12 ++++++++++++ ...t-inherent-assoc-const-without-body.stderr | 17 +++++++++++++++++ 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs create mode 100644 tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr create mode 100644 tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs create mode 100644 tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 51d1fd20cec6..8c6ee9d6bc63 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2384,7 +2384,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Some(ConstItemRhs::TypeConst(anon)) => { hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg_and_alloc(anon)) } - None if attr::contains_name(attrs, sym::type_const) => { + None if find_attr!(attrs, AttributeKind::TypeConst(_)) => { let const_arg = ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Error( diff --git a/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs new file mode 100644 index 000000000000..158a7addd10d --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs @@ -0,0 +1,19 @@ +//@ needs-rustc-debug-assertions + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Tr { + #[type_const] + const SIZE: usize; +} + +struct T; + +impl Tr for T { + #[type_const] + const SIZE: usize; + //~^ ERROR associated constant in `impl` without body +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr new file mode 100644 index 000000000000..2db677aa0ca6 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr @@ -0,0 +1,10 @@ +error: associated constant in `impl` without body + --> $DIR/type-const-assoc-const-without-body.rs:15:5 + | +LL | const SIZE: usize; + | ^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs new file mode 100644 index 000000000000..85b2327d3351 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs @@ -0,0 +1,12 @@ +//@ needs-rustc-debug-assertions + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +impl S { //~ ERROR cannot find type `S` in this scope + #[type_const] + const SIZE: usize; + //~^ ERROR associated constant in `impl` without body +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr new file mode 100644 index 000000000000..ac520a4e6946 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr @@ -0,0 +1,17 @@ +error: associated constant in `impl` without body + --> $DIR/type-const-inherent-assoc-const-without-body.rs:8:5 + | +LL | const SIZE: usize; + | ^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` + +error[E0425]: cannot find type `S` in this scope + --> $DIR/type-const-inherent-assoc-const-without-body.rs:6:6 + | +LL | impl S { + | ^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. From eed703ccc0d534f38e5d7eca30c6675364566b69 Mon Sep 17 00:00:00 2001 From: Oscar Bray Date: Sun, 18 Jan 2026 08:22:33 +0000 Subject: [PATCH 2287/3801] Fix typo. Match "build-rust-analyzer" in src/building/how-to-build-and-run.md and in the default editor settings from the rustc repo. --- src/doc/rustc-dev-guide/src/building/suggested.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 1c75de3e9042..c87dc6b28d87 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -97,7 +97,7 @@ for two reasons: additional rebuilds in some cases. To avoid these problems: -- Add `--build-dir=build/rust-analyzer` to all of the custom `x` commands in +- Add `--build-dir=build-rust-analyzer` to all of the custom `x` commands in your editor's rust-analyzer configuration. (Feel free to choose a different directory name if desired.) - Modify the `rust-analyzer.rustfmt.overrideCommand` setting so that it points From cbad6dd11772b3d02a4eaca4e049f66907bb72a1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 16 Jan 2026 16:23:56 +0100 Subject: [PATCH 2288/3801] fix: Do not show sysroot dependencies in symbol search --- src/tools/rust-analyzer/crates/base-db/src/input.rs | 3 ++- src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs | 8 +++++++- .../rust-analyzer/crates/project-model/src/workspace.rs | 6 +++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index 240f1264917a..94793a3618e1 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -221,6 +221,7 @@ pub enum LangCrateOrigin { ProcMacro, Std, Test, + Dependency, Other, } @@ -245,7 +246,7 @@ impl fmt::Display for LangCrateOrigin { LangCrateOrigin::ProcMacro => "proc_macro", LangCrateOrigin::Std => "std", LangCrateOrigin::Test => "test", - LangCrateOrigin::Other => "other", + LangCrateOrigin::Other | LangCrateOrigin::Dependency => "other", }; f.write_str(text) } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index d7f4c66f465b..183f6b649537 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -27,7 +27,7 @@ use std::{ ops::ControlFlow, }; -use base_db::{LibraryRoots, LocalRoots, RootQueryDb, SourceRootId}; +use base_db::{CrateOrigin, LangCrateOrigin, LibraryRoots, LocalRoots, RootQueryDb, SourceRootId}; use fst::{Automaton, Streamer, raw::IndexedValue}; use hir::{ Crate, Module, @@ -446,6 +446,12 @@ impl<'db> SymbolIndex<'db> { { continue; } + if let CrateOrigin::Lang(LangCrateOrigin::Dependency | LangCrateOrigin::Other) = + krate.origin(db) + { + // don't show dependencies of the sysroot + continue; + } collector.push_crate_root(krate); } diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index fa3a79e041e0..8f15f7e1507c 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -1161,6 +1161,8 @@ fn project_json_to_crate_graph( name: Some(name.canonical_name().to_owned()), } } + } else if is_sysroot { + CrateOrigin::Lang(LangCrateOrigin::Dependency) } else { CrateOrigin::Local { repo: None, name: None } }, @@ -1294,6 +1296,8 @@ fn cargo_to_crate_graph( name: Some(Symbol::intern(&pkg_data.name)), } } + } else if cargo.is_sysroot() { + CrateOrigin::Lang(LangCrateOrigin::Dependency) } else { CrateOrigin::Library { repo: pkg_data.repository.clone(), @@ -1717,7 +1721,7 @@ fn extend_crate_graph_with_sysroot( !matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc), )), LangCrateOrigin::ProcMacro => libproc_macro = Some(cid), - LangCrateOrigin::Other => (), + LangCrateOrigin::Other | LangCrateOrigin::Dependency => (), } } } From bfbee86a2de8e281db70b08367ce8245082431a2 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 16 Jan 2026 13:35:31 +0100 Subject: [PATCH 2289/3801] feat: Trigger flycheck if non-workspace files get modified Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Co-authored-by: dino --- .../crates/rust-analyzer/src/config.rs | 6 ++++++ .../rust-analyzer/src/handlers/notification.rs | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 28ac94e4deb6..7382edfa96f7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -1043,6 +1043,7 @@ pub struct Config { /// The workspace roots as registered by the LSP client workspace_roots: Vec, caps: ClientCapabilities, + /// The LSP root path, deprecated in favor of `workspace_roots` root_path: AbsPathBuf, snippets: Vec, client_info: Option, @@ -1366,6 +1367,10 @@ impl Config { self.discovered_projects_from_command.push(ProjectJsonFromCommand { data, buildfile }); } + + pub fn workspace_roots(&self) -> &[AbsPathBuf] { + &self.workspace_roots + } } #[derive(Default, Debug)] @@ -1742,6 +1747,7 @@ impl Config { } pub fn root_path(&self) -> &AbsPathBuf { + // We should probably use `workspace_roots` here if set &self.root_path } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs index 6cc40677fb51..138310b78f62 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs @@ -289,11 +289,24 @@ pub(crate) fn handle_did_change_watched_files( state: &mut GlobalState, params: DidChangeWatchedFilesParams, ) -> anyhow::Result<()> { + // we want to trigger flycheck if a file outside of our workspaces has changed, + // as to reduce stale diagnostics when outside changes happen + let mut trigger_flycheck = false; for change in params.changes.iter().unique_by(|&it| &it.uri) { if let Ok(path) = from_proto::abs_path(&change.uri) { + if !trigger_flycheck { + trigger_flycheck = + state.config.workspace_roots().iter().any(|root| !path.starts_with(root)); + } state.loader.handle.invalidate(path); } } + + if trigger_flycheck && state.config.check_on_save(None) { + for flycheck in state.flycheck.iter() { + flycheck.restart_workspace(None); + } + } Ok(()) } From 97603c0df04af46512957dda2b5d9dbba73353e3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 18 Jan 2026 18:00:08 +1100 Subject: [PATCH 2290/3801] Use `ty::Value` in more places throughout `const_to_pat` --- .../src/thir/pattern/const_to_pat.rs | 85 +++++++++---------- 1 file changed, 39 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 70bc142131e4..7fbf8cd11466 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -13,9 +13,7 @@ use rustc_infer::traits::Obligation; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::span_bug; use rustc_middle::thir::{FieldPat, Pat, PatKind}; -use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitableExt, TypeVisitor, ValTree, -}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitableExt, TypeVisitor}; use rustc_span::def_id::DefId; use rustc_span::{DUMMY_SP, Span}; use rustc_trait_selection::traits::ObligationCause; @@ -48,7 +46,7 @@ impl<'tcx> PatCtxt<'tcx> { match c.kind() { ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty), - ty::ConstKind::Value(cv) => convert.valtree_to_pat(cv.valtree, cv.ty), + ty::ConstKind::Value(value) => convert.valtree_to_pat(value), _ => span_bug!(span, "Invalid `ConstKind` for `const_to_pat`: {:?}", c), } } @@ -175,7 +173,7 @@ impl<'tcx> ConstToPat<'tcx> { }; // Lower the valtree to a THIR pattern. - let mut thir_pat = self.valtree_to_pat(valtree, ty); + let mut thir_pat = self.valtree_to_pat(ty::Value { ty, valtree }); if !thir_pat.references_error() { // Always check for `PartialEq` if we had no other errors yet. @@ -192,31 +190,32 @@ impl<'tcx> ConstToPat<'tcx> { thir_pat } - fn field_pats( + fn lower_field_values_to_fieldpats( &self, - vals: impl Iterator, Ty<'tcx>)>, + values: impl Iterator>, ) -> Vec> { - vals.enumerate() - .map(|(idx, (val, ty))| { - let field = FieldIdx::new(idx); - // Patterns can only use monomorphic types. - let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty); - FieldPat { field, pattern: *self.valtree_to_pat(val, ty) } + values + .enumerate() + .map(|(index, value)| FieldPat { + field: FieldIdx::new(index), + pattern: *self.valtree_to_pat(value), }) .collect() } // Recursive helper for `to_pat`; invoke that (instead of calling this directly). - // FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately. #[instrument(skip(self), level = "debug")] - fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> Box> { + fn valtree_to_pat(&self, value: ty::Value<'tcx>) -> Box> { let span = self.span; let tcx = self.tcx; + let ty::Value { ty, valtree } = value; + let kind = match ty.kind() { + // Extremely important check for all ADTs! + // Make sure they are eligible to be used in patterns, and if not, emit an error. ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => { - // Extremely important check for all ADTs! Make sure they opted-in to be used in - // patterns. - debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty); + // This ADT cannot be used as a constant in patterns. + debug!(?adt_def, ?value.ty, "ADT type in pattern is not `type_marked_structural`"); let PartialEqImplStatus { is_derived, structural_partial_eq, non_blanket_impl, .. } = type_has_partial_eq_impl(self.tcx, self.typing_env, ty); @@ -239,51 +238,43 @@ impl<'tcx> ConstToPat<'tcx> { return self.mk_err(tcx.dcx().create_err(err), ty); } ty::Adt(adt_def, args) if adt_def.is_enum() => { - let (&variant_index, fields) = cv.to_branch().split_first().unwrap(); + let (&variant_index, fields) = valtree.to_branch().split_first().unwrap(); let variant_index = VariantIdx::from_u32(variant_index.to_leaf().to_u32()); PatKind::Variant { adt_def: *adt_def, args, variant_index, - subpatterns: self.field_pats( - fields.iter().map(|ct| ct.to_value().valtree).zip( - adt_def.variants()[variant_index] - .fields - .iter() - .map(|field| field.ty(tcx, args)), - ), - ), + subpatterns: self + .lower_field_values_to_fieldpats(fields.iter().map(|ct| ct.to_value())), } } - ty::Adt(def, args) => { + ty::Adt(def, _) => { assert!(!def.is_union()); // Valtree construction would never succeed for unions. PatKind::Leaf { - subpatterns: self.field_pats( - cv.to_branch().iter().map(|ct| ct.to_value().valtree).zip( - def.non_enum_variant().fields.iter().map(|field| field.ty(tcx, args)), - ), + subpatterns: self.lower_field_values_to_fieldpats( + valtree.to_branch().iter().map(|ct| ct.to_value()), ), } } - ty::Tuple(fields) => PatKind::Leaf { - subpatterns: self.field_pats( - cv.to_branch().iter().map(|ct| ct.to_value().valtree).zip(fields.iter()), + ty::Tuple(_) => PatKind::Leaf { + subpatterns: self.lower_field_values_to_fieldpats( + valtree.to_branch().iter().map(|ct| ct.to_value()), ), }, - ty::Slice(elem_ty) => PatKind::Slice { - prefix: cv + ty::Slice(_) => PatKind::Slice { + prefix: valtree .to_branch() .iter() - .map(|val| *self.valtree_to_pat(val.to_value().valtree, *elem_ty)) + .map(|val| *self.valtree_to_pat(val.to_value())) .collect(), slice: None, suffix: Box::new([]), }, - ty::Array(elem_ty, _) => PatKind::Array { - prefix: cv + ty::Array(_, _) => PatKind::Array { + prefix: valtree .to_branch() .iter() - .map(|val| *self.valtree_to_pat(val.to_value().valtree, *elem_ty)) + .map(|val| *self.valtree_to_pat(val.to_value())) .collect(), slice: None, suffix: Box::new([]), @@ -296,7 +287,7 @@ impl<'tcx> ConstToPat<'tcx> { // Under `feature(deref_patterns)`, string literal patterns can also // have type `str` directly, without the `&`, in order to allow things // like `deref!("...")` to work when the scrutinee is `String`. - PatKind::Constant { value: ty::Value { ty, valtree: cv } } + PatKind::Constant { value } } ty::Ref(_, pointee_ty, ..) => { if pointee_ty.is_str() @@ -304,7 +295,9 @@ impl<'tcx> ConstToPat<'tcx> { || pointee_ty.is_sized(tcx, self.typing_env) { // References have the same valtree representation as their pointee. - PatKind::Deref { subpattern: self.valtree_to_pat(cv, *pointee_ty) } + PatKind::Deref { + subpattern: self.valtree_to_pat(ty::Value { ty: *pointee_ty, valtree }), + } } else { return self.mk_err( tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }), @@ -313,7 +306,7 @@ impl<'tcx> ConstToPat<'tcx> { } } ty::Float(flt) => { - let v = cv.to_leaf(); + let v = valtree.to_leaf(); let is_nan = match flt { ty::FloatTy::F16 => v.to_f16().is_nan(), ty::FloatTy::F32 => v.to_f32().is_nan(), @@ -325,13 +318,13 @@ impl<'tcx> ConstToPat<'tcx> { // Also see . return self.mk_err(tcx.dcx().create_err(NaNPattern { span }), ty); } else { - PatKind::Constant { value: ty::Value { ty, valtree: cv } } + PatKind::Constant { value } } } ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => { // The raw pointers we see here have been "vetted" by valtree construction to be // just integers, so we simply allow them. - PatKind::Constant { value: ty::Value { ty, valtree: cv } } + PatKind::Constant { value } } ty::FnPtr(..) => { unreachable!( From c5785601773223450e8d1b8d553cac32de01840f Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 28 Nov 2025 14:07:18 +0800 Subject: [PATCH 2291/3801] Surpress suggestion from unstable items on stable channel --- compiler/rustc_resolve/src/diagnostics.rs | 1 + .../issue-149402-suggest-unresolve/foo.rs | 6 ++++ .../nightly.err | 18 ++++++++++++ .../output.diff | 16 ++++++++++ .../issue-149402-suggest-unresolve/rmake.rs | 29 +++++++++++++++++++ .../issue-149402-suggest-unresolve/stable.err | 9 ++++++ 6 files changed, 79 insertions(+) create mode 100644 tests/run-make/issue-149402-suggest-unresolve/foo.rs create mode 100644 tests/run-make/issue-149402-suggest-unresolve/nightly.err create mode 100644 tests/run-make/issue-149402-suggest-unresolve/output.diff create mode 100644 tests/run-make/issue-149402-suggest-unresolve/rmake.rs create mode 100644 tests/run-make/issue-149402-suggest-unresolve/stable.err diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index d704280f3fa2..9fc32b31b32a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1610,6 +1610,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } + suggestions.retain(|suggestion| suggestion.is_stable || self.tcx.sess.is_nightly_build()); suggestions } diff --git a/tests/run-make/issue-149402-suggest-unresolve/foo.rs b/tests/run-make/issue-149402-suggest-unresolve/foo.rs new file mode 100644 index 000000000000..8456990829b4 --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/foo.rs @@ -0,0 +1,6 @@ +fn foo() { + let x = Vec::new(); + x.push(Complete::Item { name: "hello" }); +} + +fn main() {} diff --git a/tests/run-make/issue-149402-suggest-unresolve/nightly.err b/tests/run-make/issue-149402-suggest-unresolve/nightly.err new file mode 100644 index 000000000000..8659f0170df3 --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/nightly.err @@ -0,0 +1,18 @@ +error[E0433]: failed to resolve: use of undeclared type `Complete` + --> foo.rs:3:12 + | +3 | x.push(Complete::Item { name: "hello" }); + | ^^^^^^^^ use of undeclared type `Complete` + | +help: there is an enum variant `core::ops::CoroutineState::Complete` and 1 other; try using the variant's enum + | +3 - x.push(Complete::Item { name: "hello" }); +3 + x.push(core::ops::CoroutineState::Item { name: "hello" }); + | +3 - x.push(Complete::Item { name: "hello" }); +3 + x.push(std::ops::CoroutineState::Item { name: "hello" }); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/run-make/issue-149402-suggest-unresolve/output.diff b/tests/run-make/issue-149402-suggest-unresolve/output.diff new file mode 100644 index 000000000000..196c0326a714 --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/output.diff @@ -0,0 +1,16 @@ +@@ -3,6 +3,15 @@ + | + 3 | x.push(Complete::Item { name: "hello" }); + | ^^^^^^^^ use of undeclared type `Complete` ++ | ++help: there is an enum variant `core::ops::CoroutineState::Complete` and 1 other; try using the variant's enum ++ | ++3 - x.push(Complete::Item { name: "hello" }); ++3 + x.push(core::ops::CoroutineState::Item { name: "hello" }); ++ | ++3 - x.push(Complete::Item { name: "hello" }); ++3 + x.push(std::ops::CoroutineState::Item { name: "hello" }); ++ | + + error: aborting due to 1 previous error + diff --git a/tests/run-make/issue-149402-suggest-unresolve/rmake.rs b/tests/run-make/issue-149402-suggest-unresolve/rmake.rs new file mode 100644 index 000000000000..5bca0c0206cb --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/rmake.rs @@ -0,0 +1,29 @@ +//! Check that unstable name-resolution suggestions are omitted on stable. +//! +//! Regression test for . +//! +//@ only-nightly +//@ needs-target-std + +use run_make_support::{diff, rustc, similar}; + +fn main() { + let stable_like = rustc() + .env("RUSTC_BOOTSTRAP", "-1") + .edition("2024") + .input("foo.rs") + .run_fail() + .stderr_utf8(); + + assert!(!stable_like.contains("CoroutineState::Complete")); + diff().expected_file("stable.err").actual_text("stable_like", &stable_like).run(); + + let nightly = rustc().edition("2024").input("foo.rs").run_fail().stderr_utf8(); + + assert!(nightly.contains("CoroutineState::Complete")); + diff().expected_file("nightly.err").actual_text("nightly", &nightly).run(); + + let stderr_diff = + similar::TextDiff::from_lines(&stable_like, &nightly).unified_diff().to_string(); + diff().expected_file("output.diff").actual_text("diff", stderr_diff).run(); +} diff --git a/tests/run-make/issue-149402-suggest-unresolve/stable.err b/tests/run-make/issue-149402-suggest-unresolve/stable.err new file mode 100644 index 000000000000..6e82fe1a67ea --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/stable.err @@ -0,0 +1,9 @@ +error[E0433]: failed to resolve: use of undeclared type `Complete` + --> foo.rs:3:12 + | +3 | x.push(Complete::Item { name: "hello" }); + | ^^^^^^^^ use of undeclared type `Complete` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`. From f3e73dced1144f3b7cc81b34c45fdafec66e29f2 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Sun, 30 Nov 2025 17:02:07 +0100 Subject: [PATCH 2292/3801] Supress some lookup errors if a module contains `compile_error!` The problem is that when a macro expand to `compile_error!` because its input is malformed, the actual error message from the `compile_error!` might be hidden in a long list of other messages about using items that should have otherwise been generated by the macro. So suppress error about missing items in that module. Fixes issue 68838 --- .../rustc_builtin_macros/src/compile_error.rs | 1 + compiler/rustc_expand/src/base.rs | 4 ++ compiler/rustc_resolve/src/ident.rs | 3 +- compiler/rustc_resolve/src/macros.rs | 8 ++++ .../compile_error_macro-suppress-errors.rs | 40 ++++++++++++++++ ...compile_error_macro-suppress-errors.stderr | 46 +++++++++++++++++++ 6 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 tests/ui/macros/compile_error_macro-suppress-errors.rs create mode 100644 tests/ui/macros/compile_error_macro-suppress-errors.stderr diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs index 7fc4b437c1d8..df64d8f314db 100644 --- a/compiler/rustc_builtin_macros/src/compile_error.rs +++ b/compiler/rustc_builtin_macros/src/compile_error.rs @@ -22,6 +22,7 @@ pub(crate) fn expand_compile_error<'cx>( #[expect(rustc::diagnostic_outside_of_impl, reason = "diagnostic message is specified by user")] #[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")] let guar = cx.dcx().span_err(sp, var.to_string()); + cx.resolver.mark_scope_with_compile_error(cx.current_expansion.lint_node_id); ExpandResult::Ready(DummyResult::any(sp, guar)) } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index bf653fac5253..a1fc9694d663 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1173,6 +1173,10 @@ pub trait ResolverExpand { /// Record the name of an opaque `Ty::ImplTrait` pre-expansion so that it can be used /// to generate an item name later that does not reference placeholder macros. fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol); + + /// Mark the scope as having a compile error so that error for lookup in this scope + /// should be suppressed + fn mark_scope_with_compile_error(&mut self, parent_node: NodeId); } pub trait LintStoreExpand { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index f7e628048ccd..79d08828ccc4 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1711,7 +1711,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { diag_metadata: Option<&DiagMetadata<'_>>, ) -> PathResult<'ra> { let mut module = None; - let mut module_had_parse_errors = false; + let mut module_had_parse_errors = !self.mods_with_parse_errors.is_empty() + && self.mods_with_parse_errors.contains(&parent_scope.module.nearest_parent_mod()); let mut allow_super = true; let mut second_binding = None; diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 38628332f43e..7246eded2e72 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -166,6 +166,14 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { self.invocation_parents[&id].parent_def } + fn mark_scope_with_compile_error(&mut self, id: NodeId) { + if let Some(id) = self.opt_local_def_id(id) + && self.tcx.def_kind(id).is_module_like() + { + self.mods_with_parse_errors.insert(id.to_def_id()); + } + } + fn resolve_dollar_crates(&self) { hygiene::update_dollar_crate_names(|ctxt| { let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt)); diff --git a/tests/ui/macros/compile_error_macro-suppress-errors.rs b/tests/ui/macros/compile_error_macro-suppress-errors.rs new file mode 100644 index 000000000000..b2b6a8ae0088 --- /dev/null +++ b/tests/ui/macros/compile_error_macro-suppress-errors.rs @@ -0,0 +1,40 @@ +pub mod some_module { + compile_error!("Error in a module"); //~ ERROR: Error in a module + + fn abc() -> Hello { + let _: self::SomeType = self::Hello::new(); + let _: SomeType = Hello::new(); + } + + mod inner_module { + use super::Hello; + use crate::another_module::NotExist; //~ ERROR: unresolved import `crate::another_module::NotExist` + use crate::some_module::World; + struct Foo { + bar: crate::some_module::Xyz, + error: self::MissingType, //~ ERROR: cannot find type `MissingType` in module `self` + } + } +} + +pub mod another_module { + use crate::some_module::NotExist; + fn error_in_this_function() { + compile_error!("Error in a function"); //~ ERROR: Error in a function + } +} + +fn main() { + // these errors are suppressed because of the compile_error! macro + + let _ = some_module::some_function(); + let _: some_module::SomeType = some_module::Hello::new(); + + // these errors are not suppressed + + let _ = another_module::some_function(); + //~^ ERROR: cannot find function `some_function` in module `another_module` + let _: another_module::SomeType = another_module::Hello::new(); + //~^ ERROR: cannot find type `SomeType` in module `another_module` + //~^^ ERROR: failed to resolve: could not find `Hello` in `another_module` +} diff --git a/tests/ui/macros/compile_error_macro-suppress-errors.stderr b/tests/ui/macros/compile_error_macro-suppress-errors.stderr new file mode 100644 index 000000000000..73b156359624 --- /dev/null +++ b/tests/ui/macros/compile_error_macro-suppress-errors.stderr @@ -0,0 +1,46 @@ +error: Error in a module + --> $DIR/compile_error_macro-suppress-errors.rs:2:5 + | +LL | compile_error!("Error in a module"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: Error in a function + --> $DIR/compile_error_macro-suppress-errors.rs:23:9 + | +LL | compile_error!("Error in a function"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0432]: unresolved import `crate::another_module::NotExist` + --> $DIR/compile_error_macro-suppress-errors.rs:11:13 + | +LL | use crate::another_module::NotExist; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `NotExist` in `another_module` + +error[E0433]: failed to resolve: could not find `Hello` in `another_module` + --> $DIR/compile_error_macro-suppress-errors.rs:37:55 + | +LL | let _: another_module::SomeType = another_module::Hello::new(); + | ^^^^^ could not find `Hello` in `another_module` + +error[E0425]: cannot find type `MissingType` in module `self` + --> $DIR/compile_error_macro-suppress-errors.rs:15:26 + | +LL | error: self::MissingType, + | ^^^^^^^^^^^ not found in `self` + +error[E0425]: cannot find function `some_function` in module `another_module` + --> $DIR/compile_error_macro-suppress-errors.rs:35:29 + | +LL | let _ = another_module::some_function(); + | ^^^^^^^^^^^^^ not found in `another_module` + +error[E0425]: cannot find type `SomeType` in module `another_module` + --> $DIR/compile_error_macro-suppress-errors.rs:37:28 + | +LL | let _: another_module::SomeType = another_module::Hello::new(); + | ^^^^^^^^ not found in `another_module` + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0425, E0432, E0433. +For more information about an error, try `rustc --explain E0425`. From 2ef85d7894ff46efdd6ab49393ecc88aaf60b0e5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 18 Jan 2026 15:30:05 +0100 Subject: [PATCH 2293/3801] use epoll_ctl_add more often --- .../pass-dep/libc/libc-epoll-blocking.rs | 50 ++++------ .../pass-dep/libc/libc-epoll-no-blocking.rs | 94 +++++++------------ 2 files changed, 49 insertions(+), 95 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs index d5a59796de02..f9615fc6e414 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs @@ -21,9 +21,6 @@ fn main() { multiple_events_wake_multiple_threads(); } -// Using `as` cast since `EPOLLET` wraps around -const EPOLL_IN_OUT_ET: i32 = (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _; - // This test allows epoll_wait to block, then unblock without notification. fn test_epoll_block_without_notification() { // Create an epoll instance. @@ -34,10 +31,10 @@ fn test_epoll_block_without_notification() { let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap(); // Register eventfd with epoll. - epoll_ctl_add(epfd, fd, EPOLL_IN_OUT_ET).unwrap(); + epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // epoll_wait to clear notification. - check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT as _, data: fd }], 0); + check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT, data: fd }], 0); // This epoll wait blocks, and timeout without notification. check_epoll_wait::<1>(epfd, &[], 5); @@ -53,21 +50,17 @@ fn test_epoll_block_then_unblock() { errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Register one side of the socketpair with epoll. - epoll_ctl_add(epfd, fds[0], EPOLL_IN_OUT_ET).unwrap(); + epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // epoll_wait to clear notification. - check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT as _, data: fds[0] }], 0); + check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT, data: fds[0] }], 0); // epoll_wait before triggering notification so it will block then get unblocked before timeout. let thread1 = thread::spawn(move || { thread::yield_now(); write_all_from_slice(fds[1], b"abcde").unwrap(); }); - check_epoll_wait::<1>( - epfd, - &[Ev { events: (libc::EPOLLIN | libc::EPOLLOUT) as _, data: fds[0] }], - 10, - ); + check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLIN | libc::EPOLLOUT, data: fds[0] }], 10); thread1.join().unwrap(); } @@ -81,10 +74,10 @@ fn test_notification_after_timeout() { errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Register one side of the socketpair with epoll. - epoll_ctl_add(epfd, fds[0], EPOLL_IN_OUT_ET).unwrap(); + epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // epoll_wait to clear notification. - check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT as _, data: fds[0] }], 0); + check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT, data: fds[0] }], 0); // epoll_wait timeouts without notification. check_epoll_wait::<1>(epfd, &[], 10); @@ -93,11 +86,7 @@ fn test_notification_after_timeout() { write_all_from_slice(fds[1], b"abcde").unwrap(); // Check the result of the notification. - check_epoll_wait::<1>( - epfd, - &[Ev { events: (libc::EPOLLIN | libc::EPOLLOUT) as _, data: fds[0] }], - 10, - ); + check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLIN | libc::EPOLLOUT, data: fds[0] }], 10); } // This test shows a data_race before epoll had vector clocks added. @@ -110,7 +99,7 @@ fn test_epoll_race() { let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap(); // Register eventfd with the epoll instance. - epoll_ctl_add(epfd, fd, EPOLL_IN_OUT_ET).unwrap(); + epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); static mut VAL: u8 = 0; let thread1 = thread::spawn(move || { @@ -121,11 +110,7 @@ fn test_epoll_race() { }); thread::yield_now(); // epoll_wait for the event to happen. - check_epoll_wait::<8>( - epfd, - &[Ev { events: (libc::EPOLLIN | libc::EPOLLOUT) as _, data: fd }], - -1, - ); + check_epoll_wait::<8>(epfd, &[Ev { events: (libc::EPOLLIN | libc::EPOLLOUT), data: fd }], -1); // Read from the static mut variable. #[allow(static_mut_refs)] unsafe { @@ -151,7 +136,7 @@ fn wakeup_on_new_interest() { let t = std::thread::spawn(move || { check_epoll_wait::<8>( epfd, - &[Ev { events: (libc::EPOLLIN | libc::EPOLLOUT) as _, data: fds[1] }], + &[Ev { events: libc::EPOLLIN | libc::EPOLLOUT, data: fds[1] }], -1, ); }); @@ -159,7 +144,8 @@ fn wakeup_on_new_interest() { std::thread::yield_now(); // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP - epoll_ctl_add(epfd, fds[1], EPOLL_IN_OUT_ET | libc::EPOLLRDHUP as i32).unwrap(); + epoll_ctl_add(epfd, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP) + .unwrap(); // This should wake up the thread. t.join().unwrap(); @@ -178,14 +164,12 @@ fn multiple_events_wake_multiple_threads() { let fd2 = errno_result(unsafe { libc::dup(fd1) }).unwrap(); // Register both with epoll. - epoll_ctl_add(epfd, fd1, EPOLL_IN_OUT_ET).unwrap(); - epoll_ctl_add(epfd, fd2, EPOLL_IN_OUT_ET).unwrap(); + epoll_ctl_add(epfd, fd1, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); + epoll_ctl_add(epfd, fd2, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Consume the initial events. - let expected = [ - Ev { events: libc::EPOLLOUT as _, data: fd1 }, - Ev { events: libc::EPOLLOUT as _, data: fd2 }, - ]; + let expected = + [Ev { events: libc::EPOLLOUT, data: fd1 }, Ev { events: libc::EPOLLOUT, data: fd2 }]; check_epoll_wait::<8>(epfd, &expected, -1); // Block two threads on the epoll, both wanting to get just one event. diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs index 490895c8541b..63300c9a433c 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs @@ -32,9 +32,6 @@ fn main() { test_issue_4374_reads(); } -// Using `as` cast since `EPOLLET` wraps around -const EPOLL_IN_OUT_ET: u32 = (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _; - #[track_caller] fn check_epoll_wait(epfd: i32, expected_notifications: &[(u32, u64)]) { let epoll_event = libc::epoll_event { events: 0, u64: 0 }; @@ -145,7 +142,10 @@ fn test_epoll_ctl_del() { assert_eq!(res, 5); // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fds[1]).unwrap() }; + let mut ev = libc::epoll_event { + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as u32, + u64: u64::try_from(fds[1]).unwrap(), + }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_eq!(res, 0); @@ -173,11 +173,8 @@ fn test_two_epoll_instance() { assert_eq!(res, 5); // Register one side of the socketpair with EPOLLIN | EPOLLOUT | EPOLLET. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fds[1]).unwrap() }; - let res = unsafe { libc::epoll_ctl(epfd1, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; - assert_eq!(res, 0); - let res = unsafe { libc::epoll_ctl(epfd2, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd1, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); + epoll_ctl_add(epfd2, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Notification should be received from both instance of epoll. let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); @@ -201,7 +198,10 @@ fn test_two_same_fd_in_same_epoll_instance() { assert_ne!(newfd, -1); // Register both fd to the same epoll instance. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: 5 as u64 }; + let mut ev = libc::epoll_event { + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(), + u64: 5u64, + }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; assert_eq!(res, 0); let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, newfd, &mut ev) }; @@ -214,7 +214,7 @@ fn test_two_same_fd_in_same_epoll_instance() { // Two notification should be received. let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); - let expected_value = 5 as u64; + let expected_value = 5u64; check_epoll_wait::<8>( epfd, &[(expected_event, expected_value), (expected_event, expected_value)], @@ -233,9 +233,7 @@ fn test_epoll_eventfd() { let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap(); // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Check result from epoll_wait. let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); @@ -278,12 +276,8 @@ fn test_epoll_socketpair_both_sides() { errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Register both fd to the same epoll instance. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; - assert_eq!(res, 0); - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[1] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); + epoll_ctl_add(epfd, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Write to fds[1]. // (We do the write after the register here, unlike in `test_epoll_socketpair`, to ensure @@ -326,9 +320,7 @@ fn test_closed_fd() { let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap(); // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Write to the eventfd instance. let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes(); @@ -360,9 +352,7 @@ fn test_not_fully_closed_fd() { let newfd = errno_result(unsafe { libc::dup(fd) }).unwrap(); // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Close the original fd that being used to register with epoll. errno_check(unsafe { libc::close(fd) }); @@ -402,7 +392,7 @@ fn test_event_overwrite() { // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET let mut ev = libc::epoll_event { - events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _, + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(), u64: u64::try_from(fd).unwrap(), }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; @@ -431,13 +421,13 @@ fn test_socketpair_read() { // Register both fd to the same epoll instance. let mut ev = libc::epoll_event { - events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _, + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(), u64: fds[0] as u64, }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; assert_eq!(res, 0); let mut ev = libc::epoll_event { - events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _, + events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(), u64: fds[1] as u64, }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; @@ -493,7 +483,7 @@ fn test_no_notification_for_unregister_flag() { // Register fd[0] with EPOLLOUT|EPOLLET. let mut ev = libc::epoll_event { - events: (libc::EPOLLOUT | libc::EPOLLET) as _, + events: (libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(), u64: u64::try_from(fds[0]).unwrap(), }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; @@ -543,19 +533,15 @@ fn test_socketpair_epollerr() { errno_check(unsafe { libc::close(fds[1]) }); // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP - let mut ev = libc::epoll_event { - events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP) as _, - u64: u64::try_from(fds[1]).unwrap(), - }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; - assert_ne!(res, -1); + epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP) + .unwrap(); // Check result from epoll_wait. let expected_event = u32::try_from( libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLHUP | libc::EPOLLRDHUP | libc::EPOLLERR, ) .unwrap(); - let expected_value = u64::try_from(fds[1]).unwrap(); + let expected_value = u64::try_from(fds[0]).unwrap(); check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]); } @@ -570,12 +556,8 @@ fn test_epoll_lost_events() { errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Register both fd to the same epoll instance. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; - assert_eq!(res, 0); - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[1] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); + epoll_ctl_add(epfd, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Two notification should be received. But we only provide buffer for one event. let expected_event0 = u32::try_from(libc::EPOLLOUT).unwrap(); @@ -601,12 +583,8 @@ fn test_ready_list_fetching_logic() { let fd1 = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap(); // Register both fd to the same epoll instance. At this point, both of them are on the ready list. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fd0 as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd0, &mut ev) }; - assert_eq!(res, 0); - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fd1 as u64 }; - let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd1, &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd, fd0, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); + epoll_ctl_add(epfd, fd1, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Close fd0 so the first entry in the ready list will be empty. errno_check(unsafe { libc::close(fd0) }); @@ -643,9 +621,7 @@ fn test_epoll_ctl_notification() { errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); // Register one side of the socketpair with epoll. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd0, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd0, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // epoll_wait to clear notification for epfd0. let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); @@ -657,9 +633,7 @@ fn test_epoll_ctl_notification() { assert_ne!(epfd1, -1); // Register the same file description for epfd1. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd1, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd1, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); check_epoll_wait::<1>(epfd1, &[(expected_event, expected_value)]); // Previously this epoll_wait will receive a notification, but we shouldn't return notification @@ -683,7 +657,7 @@ fn test_issue_3858() { // Register eventfd with EPOLLIN | EPOLLET. let mut ev = libc::epoll_event { - events: (libc::EPOLLIN | libc::EPOLLET) as _, + events: (libc::EPOLLIN | libc::EPOLLET).cast_unsigned(), u64: u64::try_from(fd).unwrap(), }; let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) }; @@ -715,9 +689,7 @@ fn test_issue_4374() { assert_eq!(unsafe { libc::fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK) }, 0); // Register fds[0] with epoll while it is writable (but not readable). - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd0, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd0, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Fill up fds[0] so that it is not writable any more. let zeros = [0u8; 512]; @@ -754,9 +726,7 @@ fn test_issue_4374_reads() { assert_eq!(res, 5); // Register fds[0] with epoll while it is readable. - let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; - let res = unsafe { libc::epoll_ctl(epfd0, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; - assert_eq!(res, 0); + epoll_ctl_add(epfd0, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap(); // Read fds[0] so it is no longer readable. let mut buf = [0u8; 512]; From b35f80f7f71336b1b22c5de4af9eb8e6b59cb8f5 Mon Sep 17 00:00:00 2001 From: oligamiq Date: Sun, 18 Jan 2026 23:37:51 +0900 Subject: [PATCH 2294/3801] fix: thread creation failed on the wasm32-wasip1-threads target. --- library/std/src/sys/thread/unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 6f23c28c04d6..5a210703ce9b 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -49,7 +49,7 @@ impl Thread { // WASI does not support threading via pthreads. While wasi-libc provides // pthread stubs, pthread_create returns EAGAIN, which causes confusing // errors. We return UNSUPPORTED_PLATFORM directly instead. - if cfg!(target_os = "wasi") { + if cfg!(all(target_os = "wasi", not(target_feature = "atomics"))) { return Err(io::Error::UNSUPPORTED_PLATFORM); } From d6362e6d0fa95ec0d6d5bdcd2b81516bf9e3a4b6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 17 Dec 2025 14:00:59 +0100 Subject: [PATCH 2295/3801] document guidelines for which shims have a place in Miri --- src/tools/miri/CONTRIBUTING.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md index 1995300c5bcb..f9cb60c66d91 100644 --- a/src/tools/miri/CONTRIBUTING.md +++ b/src/tools/miri/CONTRIBUTING.md @@ -66,6 +66,23 @@ process for such contributions: This process is largely informal, and its primary goal is to more clearly communicate expectations. Please get in touch with us if you have any questions! +## Scope of Miri shims + +Miri has "shims" to implement functionality that is usually implemented in C libraries which are +invoked from Rust code, such as opening files or spawning threads, as well as for +CPU-vendor-provided SIMD intrinsics. However, the set of C functions that Rust code invokes this way +is enormous, and for obvious reasons we have no intention of implementing every C API ever written +in Miri. + +At the moment, the general guideline for "could this function have a shim in Miri" is: we will +generally only add shims for functions that can be implemented in a portable way using just what is +provided by the Rust standard library. The function should also be reasonably widely-used in Rust +code to justify the review and maintenance effort (i.e. the easier the function is to implement, the +lower the barrier). Other than that, we might make exceptions for certain cases if (a) there is a +good case for why Miri should support those APIs, and (b) robust and widely-used portable libraries +exist in the Rust ecosystem. We will generally not add shims to Miri that would require Miri to +directly interact with platform-specific APIs (such as `libc` or `windows-sys`). + ## Preparing the build environment Miri heavily relies on internal and unstable rustc interfaces to execute MIR, From ea77786cdb7e94006f74399ee67ff57068773375 Mon Sep 17 00:00:00 2001 From: Oscar Bray Date: Sun, 18 Jan 2026 16:48:45 +0000 Subject: [PATCH 2296/3801] Port #![no_main] to the attribute parser. --- .../src/attributes/crate_level.rs | 9 ++ compiler/rustc_attr_parsing/src/context.rs | 7 +- .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 1 + compiler/rustc_passes/src/entry.rs | 5 +- .../issue-43106-gating-of-builtin-attrs.rs | 12 +- ...issue-43106-gating-of-builtin-attrs.stderr | 131 ++++++++++-------- 8 files changed, 96 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 5604fbd25edc..ab99186777f9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -136,6 +136,15 @@ impl NoArgsAttributeParser for NoStdParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd; } +pub(crate) struct NoMainParser; + +impl NoArgsAttributeParser for NoMainParser { + const PATH: &[Symbol] = &[sym::no_main]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoMain; +} + pub(crate) struct RustcCoherenceIsCoreParser; impl NoArgsAttributeParser for RustcCoherenceIsCoreParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 449894f7834b..c5b98139074e 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -28,9 +28,9 @@ use crate::attributes::codegen_attrs::{ }; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::crate_level::{ - CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser, - RecursionLimitParser, RustcCoherenceIsCoreParser, TypeLengthLimitParser, - WindowsSubsystemParser, + CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoMainParser, NoStdParser, + PatternComplexityLimitParser, RecursionLimitParser, RustcCoherenceIsCoreParser, + TypeLengthLimitParser, WindowsSubsystemParser, }; use crate::attributes::debugger::DebuggerViualizerParser; use crate::attributes::deprecation::DeprecationParser; @@ -263,6 +263,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 7b7fae9fdcca..119bf554b2ae 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -852,6 +852,9 @@ pub enum AttributeKind { /// Represents `#[no_link]` NoLink, + /// Represents `#[no_main]` + NoMain, + /// Represents `#[no_mangle]` NoMangle(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index dff8a5727771..7ba268c16271 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -79,6 +79,7 @@ impl AttributeKind { NoCore(..) => No, NoImplicitPrelude(..) => No, NoLink => No, + NoMain => No, NoMangle(..) => Yes, // Needed for rustdoc NoStd(..) => No, NonExhaustive(..) => Yes, // Needed for rustdoc diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4b71d4755cb6..50e80cabdb07 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -297,6 +297,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::PatternComplexityLimit { .. } | AttributeKind::NoCore { .. } | AttributeKind::NoStd { .. } + | AttributeKind::NoMain | AttributeKind::ObjcClass { .. } | AttributeKind::ObjcSelector { .. } | AttributeKind::RustcCoherenceIsCore(..) diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index c02a01c1b823..bd737518ed47 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -1,4 +1,3 @@ -use rustc_ast::attr; use rustc_ast::entry::EntryPointType; use rustc_errors::codes::*; use rustc_hir::attrs::AttributeKind; @@ -7,7 +6,7 @@ use rustc_hir::{CRATE_HIR_ID, ItemId, Node, find_attr}; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::config::{CrateType, EntryFnType, sigpipe}; -use rustc_span::{RemapPathScopeComponents, Span, sym}; +use rustc_span::{RemapPathScopeComponents, Span}; use crate::errors::{ExternMain, MultipleRustcMain, NoMainErr}; @@ -30,7 +29,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { } // If the user wants no main function at all, then stop here. - if attr::contains_name(tcx.hir_attrs(CRATE_HIR_ID), sym::no_main) { + if find_attr!(tcx.hir_attrs(CRATE_HIR_ID), AttributeKind::NoMain) { return None; } diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 6716e78a7197..3e3235e658f6 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -884,26 +884,26 @@ mod feature { #[no_main] //~^ WARN crate-level attribute should be an inner attribute -//~| HELP add a `!` mod no_main_1 { + //~^ NOTE: This attribute does not have an `!`, which means it is applied to this module mod inner { #![no_main] } -//~^ WARN crate-level attribute should be in the root module + //~^ WARN the `#![no_main]` attribute can only be used at the crate root #[no_main] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this function #[no_main] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this struct #[no_main] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias #[no_main] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation } #[no_builtins] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 8ed39a0079ba..d89aec222be8 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -240,17 +240,6 @@ help: add a `!` LL | #![feature(x0600)] | + -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:1 - | -LL | #[no_main] - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] - | + - warning: crate-level attribute should be an inner attribute --> $DIR/issue-43106-gating-of-builtin-attrs.rs:909:1 | @@ -476,56 +465,6 @@ help: add a `!` LL | #![feature(x0600)] impl S { } | + -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:889:17 - | -LL | mod inner { #![no_main] } - | ^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5 - | -LL | #[no_main] fn f() { } - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5 - | -LL | #[no_main] struct S; - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5 - | -LL | #[no_main] type T = S; - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:5 - | -LL | #[no_main] impl S { } - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] impl S { } - | + - warning: crate-level attribute should be in the root module --> $DIR/issue-43106-gating-of-builtin-attrs.rs:913:17 | @@ -1407,6 +1346,76 @@ note: This attribute does not have an `!`, which means it is applied to this imp LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^ +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:1 + | +LL | #[no_main] + | ^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:887:1 + | +LL | / mod no_main_1 { +LL | | +LL | | mod inner { #![no_main] } +... | +LL | | } + | |_^ + +warning: the `#![no_main]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:889:17 + | +LL | mod inner { #![no_main] } + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5 + | +LL | #[no_main] fn f() { } + | ^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:16 + | +LL | #[no_main] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5 + | +LL | #[no_main] struct S; + | ^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:16 + | +LL | #[no_main] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5 + | +LL | #[no_main] type T = S; + | ^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:16 + | +LL | #[no_main] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:5 + | +LL | #[no_main] impl S { } + | ^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:16 + | +LL | #[no_main] impl S { } + | ^^^^^^^^^^ + warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` --> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:1 | From c367dfde6972ba60eca9f295d68be2f80060742e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 18 Jan 2026 18:08:16 +0100 Subject: [PATCH 2297/3801] shims: add FIXME for missing direct tests --- .../src/shims/unix/android/foreign_items.rs | 6 ++++ .../miri/src/shims/unix/foreign_items.rs | 19 ++++++++++++ .../src/shims/unix/freebsd/foreign_items.rs | 3 ++ .../src/shims/unix/linux/foreign_items.rs | 5 +++ .../src/shims/unix/macos/foreign_items.rs | 11 +++++++ .../src/shims/unix/solarish/foreign_items.rs | 5 +++ .../miri/src/shims/windows/foreign_items.rs | 31 +++++++++++++++++++ .../fail-dep/concurrency/windows_join_main.rs | 2 +- 8 files changed, 81 insertions(+), 1 deletion(-) 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 2b290b68c78c..f00bfb0a2078 100644 --- a/src/tools/miri/src/shims/unix/android/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs @@ -28,21 +28,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // File related shims "stat" => { + // FIXME: This does not have a direct test (#3179). let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" => { + // FIXME: This does not have a direct test (#3179). let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.lstat(path, buf)?; this.write_scalar(result, dest)?; } "readdir" => { + // FIXME: This does not have a direct test (#3179). let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.readdir64("dirent", dirp)?; this.write_scalar(result, dest)?; } "pread64" => { + // FIXME: This does not have a direct test (#3179). let [fd, buf, count, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *mut _, usize, libc::off64_t) -> isize), link_name, @@ -56,6 +60,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read(fd, buf, count, Some(offset), dest)?; } "pwrite64" => { + // FIXME: This does not have a direct test (#3179). let [fd, buf, n, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *const _, usize, libc::off64_t) -> isize), link_name, @@ -70,6 +75,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, Some(offset), dest)?; } "lseek64" => { + // 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, diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 8eacdc3583d4..04ec260eccd0 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -143,6 +143,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "getcwd" => { + // FIXME: This does not have a direct test (#3179). let [buf, size] = this.check_shim_sig( shim_sig!(extern "C" fn(*mut _, usize) -> *mut _), link_name, @@ -153,6 +154,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(result, dest)?; } "chdir" => { + // FIXME: This does not have a direct test (#3179). let [path] = this.check_shim_sig( shim_sig!(extern "C" fn(*const _) -> i32), link_name, @@ -209,6 +211,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, None, dest)?; } "pread" => { + // FIXME: This does not have a direct test (#3179). let [fd, buf, count, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *mut _, usize, libc::off_t) -> isize), link_name, @@ -222,6 +225,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read(fd, buf, count, Some(offset), dest)?; } "pwrite" => { + // FIXME: This does not have a direct test (#3179). let [fd, buf, n, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *const _, usize, libc::off_t) -> isize), link_name, @@ -299,6 +303,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { 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(*const _) -> i32), link_name, @@ -309,6 +314,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "symlink" => { + // FIXME: This does not have a direct test (#3179). let [target, linkpath] = this.check_shim_sig( shim_sig!(extern "C" fn(*const _, *const _) -> i32), link_name, @@ -324,6 +330,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "rename" => { + // FIXME: This does not have a direct test (#3179). let [oldpath, newpath] = this.check_shim_sig( shim_sig!(extern "C" fn(*const _, *const _) -> i32), link_name, @@ -334,6 +341,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "mkdir" => { + // FIXME: This does not have a direct test (#3179). let [path, mode] = this.check_shim_sig( shim_sig!(extern "C" fn(*const _, libc::mode_t) -> i32), link_name, @@ -344,6 +352,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { 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(*const _) -> i32), link_name, @@ -354,6 +363,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "opendir" => { + // FIXME: This does not have a direct test (#3179). let [name] = this.check_shim_sig( shim_sig!(extern "C" fn(*const _) -> *mut _), link_name, @@ -364,6 +374,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "closedir" => { + // FIXME: This does not have a direct test (#3179). let [dirp] = this.check_shim_sig( shim_sig!(extern "C" fn(*mut _) -> i32), link_name, @@ -374,6 +385,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, 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, @@ -398,6 +410,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "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, @@ -408,6 +421,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { 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, @@ -659,6 +673,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "pthread_key_delete" => { + // FIXME: This does not have a direct test (#3179). let [key] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; this.machine.tls.delete_tls_key(key)?; @@ -666,6 +681,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "pthread_getspecific" => { + // FIXME: This does not have a direct test (#3179). let [key] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; let active_thread = this.active_thread(); @@ -673,6 +689,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(ptr, dest)?; } "pthread_setspecific" => { + // FIXME: This does not have a direct test (#3179). let [key, new_ptr] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; @@ -833,6 +850,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "sched_yield" => { + // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; this.sched_yield()?; this.write_null(dest)?; @@ -941,6 +959,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "pthread_atfork" => { + // FIXME: This does not have a direct test (#3179). let [prepare, parent, child] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; this.read_pointer(prepare)?; 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 fb2d3f758420..b94ee27c46a0 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -139,11 +139,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // For those, we both intercept `func` and `call@FBSD_1.0` symbols cases // since freebsd 12 the former form can be expected. "stat" | "stat@FBSD_1.0" => { + // FIXME: This does not have a direct test (#3179). let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat@FBSD_1.0" => { + // FIXME: This does not have a direct test (#3179). let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.lstat(path, buf)?; this.write_scalar(result, dest)?; @@ -154,6 +156,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "readdir" | "readdir@FBSD_1.0" => { + // FIXME: This does not have a direct test (#3179). let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.readdir64("dirent", dirp)?; 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 a7cb2ed11b2b..426bc28ce887 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -45,6 +45,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "pread64" => { + // FIXME: This does not have a direct test (#3179). let [fd, buf, count, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *mut _, usize, libc::off64_t) -> isize), link_name, @@ -58,6 +59,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read(fd, buf, count, Some(offset), dest)?; } "pwrite64" => { + // FIXME: This does not have a direct test (#3179). let [fd, buf, n, offset] = this.check_shim_sig( shim_sig!(extern "C" fn(i32, *const _, usize, libc::off64_t) -> isize), link_name, @@ -72,6 +74,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, Some(offset), dest)?; } "lseek64" => { + // 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, @@ -111,6 +114,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "readdir64" => { + // FIXME: This does not have a direct test (#3179). let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.readdir64("dirent64", dirp)?; this.write_scalar(result, dest)?; @@ -122,6 +126,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "statx" => { + // FIXME: This does not have a direct test (#3179). let [dirfd, pathname, flags, mask, statxbuf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?; diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index f798f64441b1..204934f4c41d 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -47,11 +47,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "stat" | "stat$INODE64" => { + // FIXME: This does not have a direct test (#3179). let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat$INODE64" => { + // FIXME: This does not have a direct test (#3179). let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.lstat(path, buf)?; this.write_scalar(result, dest)?; @@ -62,11 +64,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "opendir$INODE64" => { + // FIXME: This does not have a direct test (#3179). let [name] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r$INODE64" => { + // FIXME: This does not have a direct test (#3179). let [dirp, entry, result] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.macos_readdir_r(dirp, entry, result)?; @@ -87,6 +91,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Environment related shims "_NSGetEnviron" => { + // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let environ = this.machine.env_vars.unix().environ(); this.write_pointer(environ, dest)?; @@ -111,6 +116,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "mach_timebase_info" => { + // FIXME: This does not have a direct test (#3179). let [info] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.mach_timebase_info(info)?; this.write_scalar(result, dest)?; @@ -118,14 +124,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Access to command-line arguments "_NSGetArgc" => { + // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; this.write_pointer(this.machine.argc.expect("machine must be initialized"), dest)?; } "_NSGetArgv" => { + // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; this.write_pointer(this.machine.argv.expect("machine must be initialized"), dest)?; } "_NSGetExecutablePath" => { + // FIXME: This does not have a direct test (#3179). let [buf, bufsize] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; this.check_no_isolation("`_NSGetExecutablePath`")?; @@ -168,12 +177,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "pthread_get_stackaddr_np" => { + // FIXME: This does not have a direct test (#3179). let [thread] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; this.read_target_usize(thread)?; let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size()); this.write_scalar(stack_addr, dest)?; } "pthread_get_stacksize_np" => { + // FIXME: This does not have a direct test (#3179). let [thread] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; this.read_target_usize(thread)?; let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size()); 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 fa8c86b025a7..f3918fdccf12 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -91,16 +91,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File related shims "stat" => { + // FIXME: This does not have a direct test (#3179). let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" => { + // FIXME: This does not have a direct test (#3179). let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.lstat(path, buf)?; this.write_scalar(result, dest)?; } "readdir" => { + // FIXME: This does not have a direct test (#3179). let [dirp] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let result = this.readdir64("dirent", dirp)?; this.write_scalar(result, dest)?; @@ -122,6 +125,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "stack_getbounds" => { + // FIXME: This does not have a direct test (#3179). let [stack] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?; @@ -140,6 +144,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pset_info" => { + // FIXME: This does not have a direct test (#3179). let [pset, tpe, cpus, list] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; // We do not need to handle the current process cpu mask, available_parallelism diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 1905fb22e26a..0bdf6bb78505 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -148,6 +148,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Environment related shims "GetEnvironmentVariableW" => { + // FIXME: This does not have a direct test (#3179). let [name, buf, size] = this.check_shim_sig( shim_sig!(extern "system" fn(*const _, *mut _, u32) -> u32), link_name, @@ -158,6 +159,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "SetEnvironmentVariableW" => { + // FIXME: This does not have a direct test (#3179). let [name, value] = this.check_shim_sig( shim_sig!(extern "system" fn(*const _, *const _) -> winapi::BOOL), link_name, @@ -168,6 +170,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "GetEnvironmentStringsW" => { + // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> *mut _), link_name, @@ -178,6 +181,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(result, dest)?; } "FreeEnvironmentStringsW" => { + // FIXME: This does not have a direct test (#3179). let [env_block] = this.check_shim_sig( shim_sig!(extern "system" fn(*mut _) -> winapi::BOOL), link_name, @@ -188,6 +192,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "GetCurrentDirectoryW" => { + // FIXME: This does not have a direct test (#3179). let [size, buf] = this.check_shim_sig( shim_sig!(extern "system" fn(u32, *mut _) -> u32), link_name, @@ -198,6 +203,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "SetCurrentDirectoryW" => { + // FIXME: This does not have a direct test (#3179). let [path] = this.check_shim_sig( shim_sig!(extern "system" fn(*const _) -> winapi::BOOL), link_name, @@ -208,6 +214,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "GetUserProfileDirectoryW" => { + // FIXME: This does not have a direct test (#3179). let [token, buf, size] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, *mut _, *mut _) -> winapi::BOOL), link_name, @@ -218,6 +225,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "GetCurrentProcessId" => { + // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> u32), link_name, @@ -314,6 +322,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "GetFullPathNameW" => { + // FIXME: This does not have a direct test (#3179). let [filename, size, buffer, filepart] = this.check_shim_sig( shim_sig!(extern "system" fn(*const _, u32, *mut _, *mut _) -> u32), link_name, @@ -445,6 +454,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Allocation "HeapAlloc" => { + // 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) -> *mut _), link_name, @@ -472,6 +482,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr, dest)?; } "HeapFree" => { + // 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, *mut _) -> winapi::BOOL), link_name, @@ -489,6 +500,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_i32(1), dest)?; } "HeapReAlloc" => { + // 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, *mut _, usize) -> *mut _), link_name, @@ -514,6 +526,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(new_ptr, dest)?; } "LocalFree" => { + // 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, @@ -577,6 +590,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "GetSystemInfo" => { + // FIXME: This does not have a direct test (#3179). // Also called from `page_size` crate. let [system_info] = this.check_shim_sig( shim_sig!(extern "system" fn(*mut _) -> ()), @@ -658,6 +672,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Access to command-line arguments "GetCommandLineW" => { + // FIXME: This does not have a direct test (#3179). let [] = this.check_shim_sig( shim_sig!(extern "system" fn() -> *mut _), link_name, @@ -672,6 +687,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Time related shims "GetSystemTimeAsFileTime" | "GetSystemTimePreciseAsFileTime" => { + // FIXME: This does not have a direct test (#3179). let [filetime] = this.check_shim_sig( shim_sig!(extern "system" fn(*mut _) -> ()), link_name, @@ -681,6 +697,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.GetSystemTimeAsFileTime(link_name.as_str(), filetime)?; } "QueryPerformanceCounter" => { + // FIXME: This does not have a direct test (#3179). let [performance_count] = this.check_shim_sig( shim_sig!(extern "system" fn(*mut _) -> winapi::BOOL), link_name, @@ -691,6 +708,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "QueryPerformanceFrequency" => { + // FIXME: This does not have a direct test (#3179). let [frequency] = this.check_shim_sig( shim_sig!(extern "system" fn(*mut _) -> winapi::BOOL), link_name, @@ -701,6 +719,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "Sleep" => { + // FIXME: This does not have a direct test (#3179). let [timeout] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> ()), link_name, @@ -711,6 +730,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.Sleep(timeout)?; } "CreateWaitableTimerExW" => { + // FIXME: This does not have a direct test (#3179). let [attributes, name, flags, access] = this.check_shim_sig( shim_sig!(extern "system" fn(*mut _, *const _, u32, u32) -> winapi::HANDLE), link_name, @@ -748,6 +768,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "WaitOnAddress" => { + // FIXME: This does not have a direct test (#3179). let [ptr_op, compare_op, size_op, timeout_op] = this.check_shim_sig( // First pointer is volatile shim_sig!(extern "system" fn(*mut _, *mut _, usize, u32) -> winapi::BOOL), @@ -759,6 +780,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?; } "WakeByAddressSingle" => { + // FIXME: This does not have a direct test (#3179). let [ptr_op] = this.check_shim_sig( shim_sig!(extern "system" fn(*mut _) -> ()), link_name, @@ -769,6 +791,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.WakeByAddressSingle(ptr_op)?; } "WakeByAddressAll" => { + // FIXME: This does not have a direct test (#3179). let [ptr_op] = this.check_shim_sig( shim_sig!(extern "system" fn(*mut _) -> ()), link_name, @@ -781,6 +804,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Dynamic symbol loading "GetProcAddress" => { + // FIXME: This does not have a direct test (#3179). let [module, proc_name] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HMODULE, *const _) -> winapi::FARPROC), link_name, @@ -936,6 +960,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "ExitProcess" => { + // FIXME: This does not have a direct test (#3179). let [code] = this.check_shim_sig( shim_sig!(extern "system" fn(u32) -> ()), link_name, @@ -962,6 +987,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_bool(true), dest)?; } "ProcessPrng" => { + // FIXME: This does not have a direct test (#3179). // used by `std` let [ptr, len] = this.check_shim_sig( shim_sig!(extern "system" fn(*mut _, usize) -> winapi::BOOL), @@ -1014,6 +1040,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; // STATUS_SUCCESS } "GetConsoleScreenBufferInfo" => { + // FIXME: This does not have a direct test (#3179). // `term` needs this, so we fake it. let [console, buffer_info] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HANDLE, *mut _) -> winapi::BOOL), @@ -1029,6 +1056,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "GetStdHandle" => { + // 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, @@ -1080,6 +1108,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(ret, dest)?; } "GetModuleFileNameW" => { + // FIXME: This does not have a direct test (#3179). let [handle, filename, size] = this.check_shim_sig( shim_sig!(extern "system" fn(winapi::HMODULE, *mut _, u32) -> u32), link_name, @@ -1118,6 +1147,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "FormatMessageW" => { + // FIXME: This does not have a direct test (#3179). let [flags, module, message_id, language_id, buffer, size, arguments] = this .check_shim_sig( shim_sig!( @@ -1159,6 +1189,7 @@ 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/fail-dep/concurrency/windows_join_main.rs b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs index da549a8d117d..a71778b1d0d4 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs @@ -12,7 +12,7 @@ use windows_sys::Win32::System::Threading::{INFINITE, WaitForSingleObject}; // XXX HACK: This is how miri represents the handle for thread 0. // This value can be "legitimately" obtained by using `GetCurrentThread` with `DuplicateHandle` -// but miri does not implement `DuplicateHandle` yet. +// but miri does not implement `DuplicateHandle` yet. (FIXME: it does now.) const MAIN_THREAD: HANDLE = (2i32 << 29) as HANDLE; fn main() { From ec787b07fd34fd68a35a6d9b07927dd06dad6da4 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 18 Jan 2026 18:26:59 +0100 Subject: [PATCH 2298/3801] Remove `DiagMessage::Translated` in favour of `DiagMessage::Str` --- compiler/rustc_error_messages/src/lib.rs | 22 +++++----------------- compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_errors/src/translation.rs | 2 +- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 085403c8ef36..c0737edd7d65 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -244,13 +244,6 @@ type FluentId = Cow<'static, str>; pub enum SubdiagMessage { /// Non-translatable diagnostic message. Str(Cow<'static, str>), - /// Translatable message which has already been translated eagerly. - /// - /// Some diagnostics have repeated subdiagnostics where the same interpolated variables would - /// be instantiated multiple times with different values. These subdiagnostics' messages - /// are translated when they are added to the parent diagnostic, producing this variant of - /// `DiagMessage`. - Translated(Cow<'static, str>), /// Identifier of a Fluent message. Instances of this variant are generated by the /// `Subdiagnostic` derive. FluentIdentifier(FluentId), @@ -285,15 +278,13 @@ impl From> for SubdiagMessage { #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] #[rustc_diagnostic_item = "DiagMessage"] pub enum DiagMessage { - /// Non-translatable diagnostic message. - Str(Cow<'static, str>), - /// Translatable message which has been already translated. + /// Non-translatable diagnostic message or a message that has been translated eagerly. /// /// Some diagnostics have repeated subdiagnostics where the same interpolated variables would /// be instantiated multiple times with different values. These subdiagnostics' messages - /// are translated when they are added to the parent diagnostic, producing this variant of - /// `DiagMessage`. - Translated(Cow<'static, str>), + /// are translated when they are added to the parent diagnostic. This is one of the ways + /// this variant of `DiagMessage` is produced. + Str(Cow<'static, str>), /// Identifier for a Fluent message (with optional attribute) corresponding to the diagnostic /// message. Yet to be translated. /// @@ -311,7 +302,6 @@ impl DiagMessage { pub fn with_subdiagnostic_message(&self, sub: SubdiagMessage) -> Self { let attr = match sub { SubdiagMessage::Str(s) => return DiagMessage::Str(s), - SubdiagMessage::Translated(s) => return DiagMessage::Translated(s), SubdiagMessage::FluentIdentifier(id) => { return DiagMessage::FluentIdentifier(id, None); } @@ -320,7 +310,6 @@ impl DiagMessage { match self { DiagMessage::Str(s) => DiagMessage::Str(s.clone()), - DiagMessage::Translated(s) => DiagMessage::Translated(s.clone()), DiagMessage::FluentIdentifier(id, _) => { DiagMessage::FluentIdentifier(id.clone(), Some(attr)) } @@ -329,7 +318,7 @@ impl DiagMessage { pub fn as_str(&self) -> Option<&str> { match self { - DiagMessage::Translated(s) | DiagMessage::Str(s) => Some(s), + DiagMessage::Str(s) => Some(s), DiagMessage::FluentIdentifier(_, _) => None, } } @@ -360,7 +349,6 @@ impl From for SubdiagMessage { fn from(val: DiagMessage) -> Self { match val { DiagMessage::Str(s) => SubdiagMessage::Str(s), - DiagMessage::Translated(s) => SubdiagMessage::Translated(s), DiagMessage::FluentIdentifier(id, None) => SubdiagMessage::FluentIdentifier(id), // There isn't really a sensible behaviour for this because it loses information but // this is the most sensible of the behaviours. diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 148368045f4f..102dd840556b 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1745,7 +1745,7 @@ impl DiagCtxtInner { message: DiagMessage, args: impl Iterator>, ) -> SubdiagMessage { - SubdiagMessage::Translated(Cow::from(self.eagerly_translate_to_string(message, args))) + SubdiagMessage::Str(Cow::from(self.eagerly_translate_to_string(message, args))) } /// Translate `message` eagerly with `args` to `String`. diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index c0bcec093c7e..5bffd74740dc 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -76,7 +76,7 @@ impl Translator { ) -> Result, TranslateError<'a>> { trace!(?message, ?args); let (identifier, attr) = match message { - DiagMessage::Str(msg) | DiagMessage::Translated(msg) => { + DiagMessage::Str(msg) => { return Ok(Cow::Borrowed(msg)); } DiagMessage::FluentIdentifier(identifier, attr) => (identifier, attr), From 85200a4ef0e889c35473dad54a3b04ab8540fce6 Mon Sep 17 00:00:00 2001 From: Clara Engler Date: Fri, 16 Jan 2026 18:10:08 +0100 Subject: [PATCH 2299/3801] option: Use Option::map in Option::cloned This commit removes a repetitive match statement in favor of Option::map for Option::cloned. --- library/core/src/option.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index ed31d4efaa75..eb4f978b7c19 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2103,10 +2103,7 @@ impl Option<&T> { where T: Clone, { - match self { - Some(t) => Some(t.clone()), - None => None, - } + self.map(T::clone) } } @@ -2154,10 +2151,7 @@ impl Option<&mut T> { where T: Clone, { - match self { - Some(t) => Some(t.clone()), - None => None, - } + self.as_deref().map(T::clone) } } From 43fb39f3fed61e05520aebe23d3c5815fbc896f4 Mon Sep 17 00:00:00 2001 From: chillfish8 Date: Sun, 11 Jan 2026 21:56:30 +0000 Subject: [PATCH 2300/3801] Add avx512 `pack*` family of instructions --- src/tools/miri/src/shims/x86/avx512.rs | 34 ++++- .../pass/shims/x86/intrinsics-x86-avx512.rs | 130 +++++++++++++++++- 2 files changed, 161 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/src/shims/x86/avx512.rs b/src/tools/miri/src/shims/x86/avx512.rs index 9231fc446919..b057a78b6c8e 100644 --- a/src/tools/miri/src/shims/x86/avx512.rs +++ b/src/tools/miri/src/shims/x86/avx512.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use super::{permute, pmaddbw, pmaddwd, psadbw, pshufb}; +use super::{packssdw, packsswb, packusdw, packuswb, permute, pmaddbw, pmaddwd, psadbw, pshufb}; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -130,6 +130,38 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { vpdpbusd(this, src, a, b, dest)?; } + // Used to implement the _mm512_packs_epi16 function + "packsswb.512" => { + this.expect_target_feature_for_intrinsic(link_name, "avx512bw")?; + + let [a, b] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + packsswb(this, a, b, dest)?; + } + // Used to implement the _mm512_packus_epi16 function + "packuswb.512" => { + this.expect_target_feature_for_intrinsic(link_name, "avx512bw")?; + + let [a, b] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + packuswb(this, a, b, dest)?; + } + // Used to implement the _mm512_packs_epi32 function + "packssdw.512" => { + this.expect_target_feature_for_intrinsic(link_name, "avx512bw")?; + + let [a, b] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + packssdw(this, a, b, dest)?; + } + // Used to implement the _mm512_packus_epi32 function + "packusdw.512" => { + this.expect_target_feature_for_intrinsic(link_name, "avx512bw")?; + + let [a, b] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + packusdw(this, a, b, dest)?; + } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn) diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs index 7cc554ef5a3c..e1e23eda8428 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs @@ -1,6 +1,6 @@ // We're testing x86 target specific features //@only-target: x86_64 i686 -//@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bitalg,+avx512vpopcntdq,+avx512vnni +//@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512bitalg,+avx512vpopcntdq,+avx512vnni #[cfg(target_arch = "x86")] use std::arch::x86::*; @@ -11,12 +11,14 @@ use std::mem::transmute; fn main() { assert!(is_x86_feature_detected!("avx512f")); assert!(is_x86_feature_detected!("avx512vl")); + assert!(is_x86_feature_detected!("avx512bw")); assert!(is_x86_feature_detected!("avx512bitalg")); assert!(is_x86_feature_detected!("avx512vpopcntdq")); assert!(is_x86_feature_detected!("avx512vnni")); unsafe { test_avx512(); + test_avx512bw(); test_avx512bitalg(); test_avx512vpopcntdq(); test_avx512ternarylogic(); @@ -579,9 +581,133 @@ unsafe fn test_avx512vnni() { test_mm512_dpbusd_epi32(); } +#[target_feature(enable = "avx512bw")] +unsafe fn test_avx512bw() { + #[target_feature(enable = "avx512bw")] + unsafe fn test_mm512_packs_epi16() { + let a = _mm512_set1_epi16(120); + + // Because `packs` instructions do signed saturation, we expect + // that any value over `i8::MAX` will be saturated to `i8::MAX`, and any value + // less than `i8::MIN` will also be saturated to `i8::MIN`. + let b = _mm512_set_epi16( + 200, 200, 200, 200, 200, 200, 200, 200, -200, -200, -200, -200, -200, -200, -200, -200, + 200, 200, 200, 200, 200, 200, 200, 200, -200, -200, -200, -200, -200, -200, -200, -200, + ); + + // The pack* family of instructions in x86 operate in blocks + // of 128-bit lanes, meaning the first 128-bit lane in `a` is converted and written + // then the first 128-bit lane of `b`, followed by the second 128-bit lane in `a`, etc... + // Because we are going from 16-bits to 8-bits our 128-bit block becomes 64-bits in + // the output register. + // This leaves us with 8x 8-bit values interleaved in the final register. + #[rustfmt::skip] + const DST: [i8; 64] = [ + 120, 120, 120, 120, 120, 120, 120, 120, + i8::MIN, i8::MIN, i8::MIN, i8::MIN, i8::MIN, i8::MIN, i8::MIN, i8::MIN, + 120, 120, 120, 120, 120, 120, 120, 120, + i8::MAX, i8::MAX, i8::MAX, i8::MAX, i8::MAX, i8::MAX, i8::MAX, i8::MAX, + 120, 120, 120, 120, 120, 120, 120, 120, + i8::MIN, i8::MIN, i8::MIN, i8::MIN, i8::MIN, i8::MIN, i8::MIN, i8::MIN, + 120, 120, 120, 120, 120, 120, 120, 120, + i8::MAX, i8::MAX, i8::MAX, i8::MAX, i8::MAX, i8::MAX, i8::MAX, i8::MAX, + ]; + let dst = _mm512_loadu_si512(DST.as_ptr().cast::<__m512i>()); + assert_eq_m512i(_mm512_packs_epi16(a, b), dst); + } + test_mm512_packs_epi16(); + + #[target_feature(enable = "avx512bw")] + unsafe fn test_mm512_packus_epi16() { + let a = _mm512_set1_epi16(120); + + // Because `packus` instructions do unsigned saturation, we expect + // that any value over `u8::MAX` will be saturated to `u8::MAX`, and any value + // less than `u8::MIN` will also be saturated to `u8::MIN`. + let b = _mm512_set_epi16( + 300, 300, 300, 300, 300, 300, 300, 300, -200, -200, -200, -200, -200, -200, -200, -200, + 300, 300, 300, 300, 300, 300, 300, 300, -200, -200, -200, -200, -200, -200, -200, -200, + ); + + // See `test_mm512_packs_epi16` for an explanation of the output structure. + #[rustfmt::skip] + const DST: [u8; 64] = [ + 120, 120, 120, 120, 120, 120, 120, 120, + u8::MIN, u8::MIN, u8::MIN, u8::MIN, u8::MIN, u8::MIN, u8::MIN, u8::MIN, + 120, 120, 120, 120, 120, 120, 120, 120, + u8::MAX, u8::MAX, u8::MAX, u8::MAX, u8::MAX, u8::MAX, u8::MAX, u8::MAX, + 120, 120, 120, 120, 120, 120, 120, 120, + u8::MIN, u8::MIN, u8::MIN, u8::MIN, u8::MIN, u8::MIN, u8::MIN, u8::MIN, + 120, 120, 120, 120, 120, 120, 120, 120, + u8::MAX, u8::MAX, u8::MAX, u8::MAX, u8::MAX, u8::MAX, u8::MAX, u8::MAX, + ]; + let dst = _mm512_loadu_si512(DST.as_ptr().cast::<__m512i>()); + assert_eq_m512i(_mm512_packus_epi16(a, b), dst); + } + test_mm512_packus_epi16(); + + #[target_feature(enable = "avx512bw")] + unsafe fn test_mm512_packs_epi32() { + let a = _mm512_set1_epi32(8_000); + + // Because `packs` instructions do signed saturation, we expect + // that any value over `i16::MAX` will be saturated to `i16::MAX`, and any value + // less than `i16::MIN` will also be saturated to `i16::MIN`. + let b = _mm512_set_epi32( + 50_000, 50_000, 50_000, 50_000, -50_000, -50_000, -50_000, -50_000, 50_000, 50_000, + 50_000, 50_000, -50_000, -50_000, -50_000, -50_000, + ); + + // See `test_mm512_packs_epi16` for an explanation of the output structure. + #[rustfmt::skip] + const DST: [i16; 32] = [ + 8_000, 8_000, 8_000, 8_000, + i16::MIN, i16::MIN, i16::MIN, i16::MIN, + 8_000, 8_000, 8_000, 8_000, + i16::MAX, i16::MAX, i16::MAX, i16::MAX, + 8_000, 8_000, 8_000, 8_000, + i16::MIN, i16::MIN, i16::MIN, i16::MIN, + 8_000, 8_000, 8_000, 8_000, + i16::MAX, i16::MAX, i16::MAX, i16::MAX, + ]; + let dst = _mm512_loadu_si512(DST.as_ptr().cast::<__m512i>()); + assert_eq_m512i(_mm512_packs_epi32(a, b), dst); + } + test_mm512_packs_epi32(); + + #[target_feature(enable = "avx512bw")] + unsafe fn test_mm512_packus_epi32() { + let a = _mm512_set1_epi32(8_000); + + // Because `packus` instructions do unsigned saturation, we expect + // that any value over `u16::MAX` will be saturated to `u16::MAX`, and any value + // less than `u16::MIN` will also be saturated to `u16::MIN`. + let b = _mm512_set_epi32( + 80_000, 80_000, 80_000, 80_000, -50_000, -50_000, -50_000, -50_000, 80_000, 80_000, + 80_000, 80_000, -50_000, -50_000, -50_000, -50_000, + ); + + // See `test_mm512_packs_epi16` for an explanation of the output structure. + #[rustfmt::skip] + const DST: [u16; 32] = [ + 8_000, 8_000, 8_000, 8_000, + u16::MIN, u16::MIN, u16::MIN, u16::MIN, + 8_000, 8_000, 8_000, 8_000, + u16::MAX, u16::MAX, u16::MAX, u16::MAX, + 8_000, 8_000, 8_000, 8_000, + u16::MIN, u16::MIN, u16::MIN, u16::MIN, + 8_000, 8_000, 8_000, 8_000, + u16::MAX, u16::MAX, u16::MAX, u16::MAX, + ]; + let dst = _mm512_loadu_si512(DST.as_ptr().cast::<__m512i>()); + assert_eq_m512i(_mm512_packus_epi32(a, b), dst); + } + test_mm512_packus_epi32(); +} + #[track_caller] unsafe fn assert_eq_m512i(a: __m512i, b: __m512i) { - assert_eq!(transmute::<_, [i32; 16]>(a), transmute::<_, [i32; 16]>(b)) + assert_eq!(transmute::<_, [u16; 32]>(a), transmute::<_, [u16; 32]>(b)) } #[track_caller] From 858fb400225aca8bc3a666ba9e1a039b03cc3131 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sun, 18 Jan 2026 20:06:15 +0100 Subject: [PATCH 2301/3801] Port #[rustc_allocator] to attr parser --- compiler/rustc_attr_parsing/src/attributes/mod.rs | 1 + .../src/attributes/rustc_allocator.rs | 11 +++++++++++ compiler/rustc_attr_parsing/src/context.rs | 15 +++++++++------ compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 +++- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- 7 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 64aa7a66b019..0d328d5cc6a7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -58,6 +58,7 @@ pub(crate) mod pin_v2; pub(crate) mod proc_macro_attrs; pub(crate) mod prototype; pub(crate) mod repr; +pub(crate) mod rustc_allocator; pub(crate) mod rustc_dump; pub(crate) mod rustc_internal; pub(crate) mod semantics; diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs new file mode 100644 index 000000000000..d7925f6fc372 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs @@ -0,0 +1,11 @@ +use super::prelude::*; + +pub(crate) struct RustcAllocatorParser; + +impl NoArgsAttributeParser for RustcAllocatorParser { + const PATH: &[Symbol] = &[sym::rustc_allocator]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocator; +} \ No newline at end of file diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 449894f7834b..652a5e2cf1c6 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -64,17 +64,19 @@ use crate::attributes::proc_macro_attrs::{ }; use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; +use crate::attributes::rustc_allocator::RustcAllocatorParser; use crate::attributes::rustc_dump::{ RustcDumpDefParents, RustcDumpItemBounds, RustcDumpPredicates, RustcDumpUserArgs, RustcDumpVtable, }; use crate::attributes::rustc_internal::{ - RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser, - RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser, - RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, - RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, - RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser, - RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, + RustcHasIncoherentInherentImplsParser, + RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, + RustcLegacyConstGenericsParser, RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, + RustcLintOptTyParser, RustcLintQueryInstabilityParser, + RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser, + RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, + RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; @@ -273,6 +275,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index fa02c5c51f7c..c3bf92df34a0 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -335,6 +335,9 @@ fn process_builtin_attrs( AttributeKind::InstructionSet(instruction_set) => { codegen_fn_attrs.instruction_set = Some(*instruction_set) } + AttributeKind::RustcAllocator => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR + } _ => {} } } @@ -344,7 +347,6 @@ fn process_builtin_attrs( }; match name { - sym::rustc_allocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR, sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR, sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 7b7fae9fdcca..b884372c2a7c 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -906,6 +906,9 @@ pub enum AttributeKind { /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span }, + /// Represents `#[rustc_allocator]` + RustcAllocator, + /// Represents `#[rustc_builtin_macro]`. RustcBuiltinMacro { builtin_name: Option, helper_attrs: ThinVec, span: Span }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index dff8a5727771..e81e74435e51 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -97,6 +97,7 @@ impl AttributeKind { PubTransparent(..) => Yes, RecursionLimit { .. } => No, Repr { .. } => No, + RustcAllocator => No, RustcBuiltinMacro { .. } => Yes, RustcCoherenceIsCore(..) => No, RustcDumpDefParents => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4b71d4755cb6..c4de0f44a648 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -316,6 +316,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDumpDefParents | AttributeKind::RustcDumpVtable(..) | AttributeKind::NeedsAllocator + | AttributeKind::RustcAllocator ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -360,7 +361,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_do_not_const_check | sym::rustc_reservation_impl | sym::rustc_doc_primitive - | sym::rustc_allocator | sym::rustc_deallocator | sym::rustc_reallocator | sym::rustc_conversion_suggestion From 027a6f268f4989198db21aded966c22eb48311cf Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sun, 18 Jan 2026 19:35:33 +0100 Subject: [PATCH 2302/3801] Port `#[rustc_deallocator]` to attr parser --- .../src/attributes/rustc_allocator.rs | 12 +++++++++++- compiler/rustc_attr_parsing/src/context.rs | 16 ++++++++-------- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 +++- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs index d7925f6fc372..8eb252d3ff8d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs @@ -8,4 +8,14 @@ impl NoArgsAttributeParser for RustcAllocatorParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocator; -} \ No newline at end of file +} + +pub(crate) struct RustcDeallocatorParser; + +impl NoArgsAttributeParser for RustcDeallocatorParser { + const PATH: &[Symbol] = &[sym::rustc_deallocator]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDeallocator; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 652a5e2cf1c6..454a2b427313 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -64,19 +64,18 @@ use crate::attributes::proc_macro_attrs::{ }; use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; -use crate::attributes::rustc_allocator::RustcAllocatorParser; +use crate::attributes::rustc_allocator::{RustcAllocatorParser, RustcDeallocatorParser}; use crate::attributes::rustc_dump::{ RustcDumpDefParents, RustcDumpItemBounds, RustcDumpPredicates, RustcDumpUserArgs, RustcDumpVtable, }; use crate::attributes::rustc_internal::{ - RustcHasIncoherentInherentImplsParser, - RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, - RustcLintOptTyParser, RustcLintQueryInstabilityParser, - RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser, - RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, - RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, + RustcHasIncoherentInherentImplsParser, RustcLayoutScalarValidRangeEndParser, + RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser, + RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, + RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, + RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser, + RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; @@ -277,6 +276,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index c3bf92df34a0..70328c14b19c 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -338,6 +338,9 @@ fn process_builtin_attrs( AttributeKind::RustcAllocator => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR } + AttributeKind::RustcDeallocator => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR + } _ => {} } } @@ -349,7 +352,6 @@ fn process_builtin_attrs( match name { sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR, - sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR, sym::rustc_allocator_zeroed => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index b884372c2a7c..6f91dd48cb5a 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -915,6 +915,9 @@ pub enum AttributeKind { /// Represents `#[rustc_coherence_is_core]` RustcCoherenceIsCore(Span), + /// Represents `#[rustc_deallocator]` + RustcDeallocator, + /// Represents `#[rustc_dump_def_parents]` RustcDumpDefParents, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index e81e74435e51..9fcaf77f69a4 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -100,6 +100,7 @@ impl AttributeKind { RustcAllocator => No, RustcBuiltinMacro { .. } => Yes, RustcCoherenceIsCore(..) => No, + RustcDeallocator => No, RustcDumpDefParents => No, RustcDumpItemBounds => No, RustcDumpPredicates => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c4de0f44a648..83a4bd9f0cda 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -317,6 +317,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDumpVtable(..) | AttributeKind::NeedsAllocator | AttributeKind::RustcAllocator + | AttributeKind::RustcDeallocator ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -361,7 +362,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_do_not_const_check | sym::rustc_reservation_impl | sym::rustc_doc_primitive - | sym::rustc_deallocator | sym::rustc_reallocator | sym::rustc_conversion_suggestion | sym::rustc_allocator_zeroed From 9a7614da04b5b3258b24ce64e197dd2989cff1d9 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sun, 18 Jan 2026 19:40:19 +0100 Subject: [PATCH 2303/3801] Port `#[rustc_reallocator]` to attr parser --- .../src/attributes/rustc_allocator.rs | 10 ++++++++++ compiler/rustc_attr_parsing/src/context.rs | 5 ++++- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 +++- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs index 8eb252d3ff8d..9324f0c01156 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs @@ -19,3 +19,13 @@ impl NoArgsAttributeParser for RustcDeallocatorParser { AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDeallocator; } + +pub(crate) struct RustcReallocatorParser; + +impl NoArgsAttributeParser for RustcReallocatorParser { + const PATH: &[Symbol] = &[sym::rustc_reallocator]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcReallocator; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 454a2b427313..19e03f1ad3eb 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -64,7 +64,9 @@ use crate::attributes::proc_macro_attrs::{ }; use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; -use crate::attributes::rustc_allocator::{RustcAllocatorParser, RustcDeallocatorParser}; +use crate::attributes::rustc_allocator::{ + RustcAllocatorParser, RustcDeallocatorParser, RustcReallocatorParser, +}; use crate::attributes::rustc_dump::{ RustcDumpDefParents, RustcDumpItemBounds, RustcDumpPredicates, RustcDumpUserArgs, RustcDumpVtable, @@ -291,6 +293,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 70328c14b19c..86ea1ac94b4e 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -341,6 +341,9 @@ fn process_builtin_attrs( AttributeKind::RustcDeallocator => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR } + AttributeKind::RustcReallocator => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR + } _ => {} } } @@ -351,7 +354,6 @@ fn process_builtin_attrs( match name { sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, - sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR, sym::rustc_allocator_zeroed => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 6f91dd48cb5a..95c4b28f1421 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -978,6 +978,9 @@ pub enum AttributeKind { /// Represents `#[rustc_pass_indirectly_in_non_rustic_abis]` RustcPassIndirectlyInNonRusticAbis(Span), + /// Represents `#[rustc_reallocator]` + RustcReallocator, + /// Represents `#[rustc_scalable_vector(N)]` RustcScalableVector { /// The base multiple of lanes that are in a scalable vector, if provided. `element_count` diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 9fcaf77f69a4..0dd2cefc83cf 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -121,6 +121,7 @@ impl AttributeKind { RustcNoImplicitAutorefs => Yes, RustcObjectLifetimeDefault => No, RustcPassIndirectlyInNonRusticAbis(..) => No, + RustcReallocator => No, RustcScalableVector { .. } => Yes, RustcShouldNotBeCalledOnConstItems(..) => Yes, RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 83a4bd9f0cda..4e904b6f11ad 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -318,6 +318,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::NeedsAllocator | AttributeKind::RustcAllocator | AttributeKind::RustcDeallocator + | AttributeKind::RustcReallocator ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -362,7 +363,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_do_not_const_check | sym::rustc_reservation_impl | sym::rustc_doc_primitive - | sym::rustc_reallocator | sym::rustc_conversion_suggestion | sym::rustc_allocator_zeroed | sym::rustc_allocator_zeroed_variant From 21c9bd7692a9ed139e12c2bfc367b9c71160fcd5 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sun, 18 Jan 2026 19:47:09 +0100 Subject: [PATCH 2304/3801] Port `#[rustc_allocator_zeroed]` to attr parser --- .../src/attributes/rustc_allocator.rs | 10 ++++++++++ compiler/rustc_attr_parsing/src/context.rs | 4 +++- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 6 +++--- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs index 9324f0c01156..4622348ef1db 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs @@ -10,6 +10,16 @@ impl NoArgsAttributeParser for RustcAllocatorParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocator; } +pub(crate) struct RustcAllocatorZeroedParser; + +impl NoArgsAttributeParser for RustcAllocatorZeroedParser { + const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocatorZeroed; +} + pub(crate) struct RustcDeallocatorParser; impl NoArgsAttributeParser for RustcDeallocatorParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 19e03f1ad3eb..7e69cbf1ff6d 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -65,7 +65,8 @@ use crate::attributes::proc_macro_attrs::{ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_allocator::{ - RustcAllocatorParser, RustcDeallocatorParser, RustcReallocatorParser, + RustcAllocatorParser, RustcAllocatorZeroedParser, RustcDeallocatorParser, + RustcReallocatorParser, }; use crate::attributes::rustc_dump::{ RustcDumpDefParents, RustcDumpItemBounds, RustcDumpPredicates, RustcDumpUserArgs, @@ -277,6 +278,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 86ea1ac94b4e..1b0427e7e676 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -344,6 +344,9 @@ fn process_builtin_attrs( AttributeKind::RustcReallocator => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR } + AttributeKind::RustcAllocatorZeroed => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED + } _ => {} } } @@ -354,9 +357,6 @@ fn process_builtin_attrs( match name { sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, - sym::rustc_allocator_zeroed => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED - } sym::patchable_function_entry => { codegen_fn_attrs.patchable_function_entry = parse_patchable_function_entry(tcx, attr); diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 95c4b28f1421..1c0562d38d8a 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -909,6 +909,9 @@ pub enum AttributeKind { /// Represents `#[rustc_allocator]` RustcAllocator, + /// Represents `#[rustc_allocator_zeroed]` + RustcAllocatorZeroed, + /// Represents `#[rustc_builtin_macro]`. RustcBuiltinMacro { builtin_name: Option, helper_attrs: ThinVec, span: Span }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 0dd2cefc83cf..803aca49b406 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -98,6 +98,7 @@ impl AttributeKind { RecursionLimit { .. } => No, Repr { .. } => No, RustcAllocator => No, + RustcAllocatorZeroed => No, RustcBuiltinMacro { .. } => Yes, RustcCoherenceIsCore(..) => No, RustcDeallocator => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4e904b6f11ad..ca0d6b90a1c4 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -317,6 +317,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDumpVtable(..) | AttributeKind::NeedsAllocator | AttributeKind::RustcAllocator + | AttributeKind::RustcAllocatorZeroed | AttributeKind::RustcDeallocator | AttributeKind::RustcReallocator ) => { /* do nothing */ } @@ -364,7 +365,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_reservation_impl | sym::rustc_doc_primitive | sym::rustc_conversion_suggestion - | sym::rustc_allocator_zeroed | sym::rustc_allocator_zeroed_variant | sym::rustc_deprecated_safe_2024 | sym::rustc_test_marker From 9a931e8bf2c4a329df8f32d587e056d7b127ec5a Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sun, 18 Jan 2026 20:02:41 +0100 Subject: [PATCH 2305/3801] Port `#[rustc_allocator_zeroed_variant]` to attr parser --- .../src/attributes/rustc_allocator.rs | 19 +++++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 5 +++-- compiler/rustc_codegen_llvm/src/attributes.rs | 5 ++--- .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs index 4622348ef1db..5782f9473a99 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs @@ -20,6 +20,25 @@ impl NoArgsAttributeParser for RustcAllocatorZeroedParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocatorZeroed; } +pub(crate) struct RustcAllocatorZeroedVariantParser; + +impl SingleAttributeParser for RustcAllocatorZeroedVariantParser { + const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed_variant]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "function"); + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(name) = args.name_value().and_then(NameValueParser::value_as_str) else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + + Some(AttributeKind::RustcAllocatorZeroedVariant { name }) + } +} + pub(crate) struct RustcDeallocatorParser; impl NoArgsAttributeParser for RustcDeallocatorParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 7e69cbf1ff6d..7c0182c7e063 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -65,8 +65,8 @@ use crate::attributes::proc_macro_attrs::{ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_allocator::{ - RustcAllocatorParser, RustcAllocatorZeroedParser, RustcDeallocatorParser, - RustcReallocatorParser, + RustcAllocatorParser, RustcAllocatorZeroedParser, RustcAllocatorZeroedVariantParser, + RustcDeallocatorParser, RustcReallocatorParser, }; use crate::attributes::rustc_dump::{ RustcDumpDefParents, RustcDumpItemBounds, RustcDumpPredicates, RustcDumpUserArgs, @@ -227,6 +227,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index a25ce9e5a90a..28e91a25a21a 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -1,6 +1,7 @@ //! Set and unset common attributes on LLVM values. use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr, RtsanSetting}; use rustc_hir::def_id::DefId; +use rustc_hir::find_attr; use rustc_middle::middle::codegen_fn_attrs::{ CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, }; @@ -470,9 +471,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( { to_add.push(create_alloc_family_attr(cx.llcx)); if let Some(instance) = instance - && let Some(zv) = - tcx.get_attr(instance.def_id(), rustc_span::sym::rustc_allocator_zeroed_variant) - && let Some(name) = zv.value_str() + && let Some(name) = find_attr!(tcx.get_all_attrs(instance.def_id()), rustc_hir::attrs::AttributeKind::RustcAllocatorZeroedVariant {name} => name) { to_add.push(llvm::CreateAttrStringValue( cx.llcx, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 1c0562d38d8a..eff871cb8bb4 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -912,6 +912,9 @@ pub enum AttributeKind { /// Represents `#[rustc_allocator_zeroed]` RustcAllocatorZeroed, + /// Represents `#[rustc_allocator_zeroed_variant]` + RustcAllocatorZeroedVariant { name: Symbol }, + /// Represents `#[rustc_builtin_macro]`. RustcBuiltinMacro { builtin_name: Option, helper_attrs: ThinVec, span: Span }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 803aca49b406..28b41ac70925 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -99,6 +99,7 @@ impl AttributeKind { Repr { .. } => No, RustcAllocator => No, RustcAllocatorZeroed => No, + RustcAllocatorZeroedVariant { .. } => Yes, RustcBuiltinMacro { .. } => Yes, RustcCoherenceIsCore(..) => No, RustcDeallocator => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ca0d6b90a1c4..1e723dd6b464 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -318,6 +318,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::NeedsAllocator | AttributeKind::RustcAllocator | AttributeKind::RustcAllocatorZeroed + | AttributeKind::RustcAllocatorZeroedVariant { .. } | AttributeKind::RustcDeallocator | AttributeKind::RustcReallocator ) => { /* do nothing */ } @@ -365,7 +366,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_reservation_impl | sym::rustc_doc_primitive | sym::rustc_conversion_suggestion - | sym::rustc_allocator_zeroed_variant | sym::rustc_deprecated_safe_2024 | sym::rustc_test_marker | sym::rustc_abi From 2b8f4a562f24afcb45f4f12b109c13beb5b45f75 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 29 Sep 2024 00:27:50 +0200 Subject: [PATCH 2306/3801] avoid phi node for pointers flowing into Vec appends --- library/alloc/src/slice.rs | 11 ++++--- library/alloc/src/vec/mod.rs | 6 +++- .../lib-optimizations/append-elements.rs | 33 +++++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 tests/codegen-llvm/lib-optimizations/append-elements.rs diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index e7d0fc3454ee..634747ca3f84 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -444,13 +444,16 @@ impl [T] { impl ConvertVec for T { #[inline] fn to_vec(s: &[Self], alloc: A) -> Vec { - let mut v = Vec::with_capacity_in(s.len(), alloc); + let len = s.len(); + let mut v = Vec::with_capacity_in(len, alloc); // SAFETY: // allocated above with the capacity of `s`, and initialize to `s.len()` in // ptr::copy_to_non_overlapping below. - unsafe { - s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len()); - v.set_len(s.len()); + if len > 0 { + unsafe { + s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), len); + v.set_len(len); + } } v } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 379e964f0a0c..ac86399df7ab 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2818,7 +2818,11 @@ impl Vec { let count = other.len(); self.reserve(count); let len = self.len(); - unsafe { ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) }; + if count > 0 { + unsafe { + ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) + }; + } self.len += count; } diff --git a/tests/codegen-llvm/lib-optimizations/append-elements.rs b/tests/codegen-llvm/lib-optimizations/append-elements.rs new file mode 100644 index 000000000000..b8657104d665 --- /dev/null +++ b/tests/codegen-llvm/lib-optimizations/append-elements.rs @@ -0,0 +1,33 @@ +//@ compile-flags: -O -Zmerge-functions=disabled +//@ needs-deterministic-layouts +//@ min-llvm-version: 21 +#![crate_type = "lib"] + +//! Check that a temporary intermediate allocations can eliminated and replaced +//! with memcpy forwarding. +//! This requires Vec code to be structured in a way that avoids phi nodes from the +//! zero-capacity length flowing into the memcpy arguments. + +// CHECK-LABEL: @vec_append_with_temp_alloc +// CHECK-SAME: ptr{{.*}}[[DST:%[a-z]+]]{{.*}}ptr{{.*}}[[SRC:%[a-z]+]] +#[no_mangle] +pub fn vec_append_with_temp_alloc(dst: &mut Vec, src: &[u8]) { + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.*}}[[DST]].i{{.*}}[[SRC]] + // CHECK-NOT: call void @llvm.memcpy + let temp = src.to_vec(); + dst.extend(&temp); + // CHECK: ret +} + +// CHECK-LABEL: @string_append_with_temp_alloc +// CHECK-SAME: ptr{{.*}}[[DST:%[a-z]+]]{{.*}}ptr{{.*}}[[SRC:%[a-z]+]] +#[no_mangle] +pub fn string_append_with_temp_alloc(dst: &mut String, src: &str) { + // CHECK-NOT: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy.{{.*}}[[DST]].i{{.*}}[[SRC]] + // CHECK-NOT: call void @llvm.memcpy + let temp = src.to_string(); + dst.push_str(&temp); + // CHECK: ret +} From 7216b035fa406b924099d1b1e8c4f392e4e02597 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 18 Jan 2026 21:27:40 +0100 Subject: [PATCH 2307/3801] Factor out diagnostic slug checking from `DiagnosticDerive` and `LintDiagnosticDerive` --- .../src/diagnostics/diagnostic.rs | 100 +++--------------- .../src/diagnostics/diagnostic_builder.rs | 49 +++++++++ 2 files changed, 66 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 185d07049669..7e784e3464e9 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -4,12 +4,10 @@ use std::cell::RefCell; use proc_macro2::TokenStream; use quote::quote; -use syn::spanned::Spanned; use synstructure::Structure; use crate::diagnostics::diagnostic_builder::DiagnosticDeriveKind; -use crate::diagnostics::error::{DiagnosticDeriveError, span_err}; -use crate::diagnostics::utils::SetOnce; +use crate::diagnostics::error::DiagnosticDeriveError; /// The central struct for constructing the `into_diag` method from an annotated struct. pub(crate) struct DiagnosticDerive<'a> { @@ -29,36 +27,16 @@ impl<'a> DiagnosticDerive<'a> { let preamble = builder.preamble(variant); let body = builder.body(variant); - let init = match builder.slug.value_ref() { - None => { - span_err(builder.span, "diagnostic slug not specified") - .help( - "specify the slug as the first argument to the `#[diag(...)]` \ - attribute, such as `#[diag(hir_analysis_example_error)]`", - ) - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - Some(slug) - if let Some(Mismatch { slug_name, crate_name, slug_prefix }) = - Mismatch::check(slug) => - { - span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") - .note(format!("slug is `{slug_name}` but the crate name is `{crate_name}`")) - .help(format!("expected a slug starting with `{slug_prefix}_...`")) - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - Some(slug) => { - slugs.borrow_mut().push(slug.clone()); - quote! { - let mut diag = rustc_errors::Diag::new( - dcx, - level, - crate::fluent_generated::#slug - ); - } - } + let Some(slug) = builder.primary_message() else { + return DiagnosticDeriveError::ErrorHandled.to_compile_error(); + }; + slugs.borrow_mut().push(slug.clone()); + let init = quote! { + let mut diag = rustc_errors::Diag::new( + dcx, + level, + crate::fluent_generated::#slug + ); }; let formatting_init = &builder.formatting_init; @@ -113,32 +91,12 @@ impl<'a> LintDiagnosticDerive<'a> { let preamble = builder.preamble(variant); let body = builder.body(variant); - let primary_message = match builder.slug.value_ref() { - None => { - span_err(builder.span, "diagnostic slug not specified") - .help( - "specify the slug as the first argument to the attribute, such as \ - `#[diag(compiletest_example)]`", - ) - .emit(); - DiagnosticDeriveError::ErrorHandled.to_compile_error() - } - Some(slug) - if let Some(Mismatch { slug_name, crate_name, slug_prefix }) = - Mismatch::check(slug) => - { - span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") - .note(format!("slug is `{slug_name}` but the crate name is `{crate_name}`")) - .help(format!("expected a slug starting with `{slug_prefix}_...`")) - .emit(); - DiagnosticDeriveError::ErrorHandled.to_compile_error() - } - Some(slug) => { - slugs.borrow_mut().push(slug.clone()); - quote! { - diag.primary_message(crate::fluent_generated::#slug); - } - } + let Some(slug) = builder.primary_message() else { + return DiagnosticDeriveError::ErrorHandled.to_compile_error(); + }; + slugs.borrow_mut().push(slug.clone()); + let primary_message = quote! { + diag.primary_message(crate::fluent_generated::#slug); }; let formatting_init = &builder.formatting_init; @@ -172,30 +130,6 @@ impl<'a> LintDiagnosticDerive<'a> { } } -struct Mismatch { - slug_name: String, - crate_name: String, - slug_prefix: String, -} - -impl Mismatch { - /// Checks whether the slug starts with the crate name it's in. - fn check(slug: &syn::Path) -> Option { - // If this is missing we're probably in a test, so bail. - let crate_name = std::env::var("CARGO_CRATE_NAME").ok()?; - - // If we're not in a "rustc_" crate, bail. - let Some(("rustc", slug_prefix)) = crate_name.split_once('_') else { return None }; - - let slug_name = slug.segments.first()?.ident.to_string(); - if !slug_name.starts_with(slug_prefix) { - Some(Mismatch { slug_name, slug_prefix: slug_prefix.to_string(), crate_name }) - } else { - None - } - } -} - /// Generates a `#[test]` that verifies that all referenced variables /// exist on this structure. fn generate_test(slug: &syn::Path, structure: &Structure<'_>) -> TokenStream { diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 1055f27c1e48..cbc70b55d7ee 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -110,6 +110,31 @@ impl DiagnosticDeriveKind { } impl DiagnosticDeriveVariantBuilder { + pub(crate) fn primary_message(&self) -> Option<&Path> { + match self.slug.value_ref() { + None => { + span_err(self.span, "diagnostic slug not specified") + .help( + "specify the slug as the first argument to the `#[diag(...)]` \ + attribute, such as `#[diag(hir_analysis_example_error)]`", + ) + .emit(); + None + } + Some(slug) + if let Some(Mismatch { slug_name, crate_name, slug_prefix }) = + Mismatch::check(slug) => + { + span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") + .note(format!("slug is `{slug_name}` but the crate name is `{crate_name}`")) + .help(format!("expected a slug starting with `{slug_prefix}_...`")) + .emit(); + None + } + Some(slug) => Some(slug), + } + } + /// Generates calls to `code` and similar functions based on the attributes on the type or /// variant. pub(crate) fn preamble(&mut self, variant: &VariantInfo<'_>) -> TokenStream { @@ -504,3 +529,27 @@ impl DiagnosticDeriveVariantBuilder { } } } + +struct Mismatch { + slug_name: String, + crate_name: String, + slug_prefix: String, +} + +impl Mismatch { + /// Checks whether the slug starts with the crate name it's in. + fn check(slug: &syn::Path) -> Option { + // If this is missing we're probably in a test, so bail. + let crate_name = std::env::var("CARGO_CRATE_NAME").ok()?; + + // If we're not in a "rustc_" crate, bail. + let Some(("rustc", slug_prefix)) = crate_name.split_once('_') else { return None }; + + let slug_name = slug.segments.first()?.ident.to_string(); + if slug_name.starts_with(slug_prefix) { + return None; + } + + Some(Mismatch { slug_name, slug_prefix: slug_prefix.to_string(), crate_name }) + } +} From 7ec4a8e798cc37bdf4c9cac1c4a481f6c1d22a0d Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 18 Jan 2026 22:36:39 +0100 Subject: [PATCH 2308/3801] Update uitests --- tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 90ad21ef08f9..77c48aceca8e 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -384,7 +384,7 @@ error: derive(Diagnostic): diagnostic slug not specified LL | #[lint(no_crate_example, code = E0123)] | ^ | - = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): attribute specified multiple times --> $DIR/diagnostic-derive.rs:613:53 From e668836c929e1a30b0c53583567e7c6cf42fe4da Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 18 Jan 2026 22:40:55 +0100 Subject: [PATCH 2309/3801] Fix capitalization of error messages --- compiler/rustc_attr_parsing/messages.ftl | 2 +- compiler/rustc_const_eval/messages.ftl | 12 ++++++------ compiler/rustc_lint/messages.ftl | 2 +- compiler/rustc_monomorphize/messages.ftl | 2 +- compiler/rustc_passes/messages.ftl | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 4b4358ab0a9c..3e4c1a9dfad8 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -230,7 +230,7 @@ attr_parsing_unstable_cfg_target_compact = compact `cfg(target(..))` is experimental and subject to change attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable - .help = If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` + .help = if this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` attr_parsing_unsupported_instruction_set = target `{$current_target}` does not support `#[instruction_set({$instruction_set}::*)]` diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 38ab46a7bb5b..4aa0a0b2a96f 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -140,9 +140,9 @@ const_eval_incompatible_return_types = const_eval_interior_mutable_borrow_escaping = interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed .label = this borrow of an interior mutable value refers to such a temporary - .note = Temporaries in constants and statics can have their lifetime extended until the end of the program - .note2 = To avoid accidentally creating global mutable state, such temporaries must be immutable - .help = If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + .note = temporaries in constants and statics can have their lifetime extended until the end of the program + .note2 = to avoid accidentally creating global mutable state, such temporaries must be immutable + .help = if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` const_eval_intern_kind = {$kind -> [static] static @@ -225,9 +225,9 @@ const_eval_modified_global = const_eval_mutable_borrow_escaping = mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed .label = this mutable borrow refers to such a temporary - .note = Temporaries in constants and statics can have their lifetime extended until the end of the program - .note2 = To avoid accidentally creating global mutable state, such temporaries must be immutable - .help = If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + .note = temporaries in constants and statics can have their lifetime extended until the end of the program + .note2 = to avoid accidentally creating global mutable state, such temporaries must be immutable + .help = if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind} diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index f5b882494863..e38130aa9a29 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -542,7 +542,7 @@ lint_invalid_style = {$is_used_as_inner -> [false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]` *[other] the `#![{$name}]` attribute can only be used at the crate root } - .note = This attribute does not have an `!`, which means it is applied to this {$target} + .note = this attribute does not have an `!`, which means it is applied to this {$target} lint_invalid_target = `#[{$name}]` attribute cannot be used on {$target} .warn = {-lint_previously_accepted} diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index 09500ba73359..9c791208c093 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -62,7 +62,7 @@ monomorphize_encountered_error_while_instantiating_global_asm = monomorphize_large_assignments = moving {$size} bytes .label = value moved from here - .note = The current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + .note = the current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` monomorphize_no_optimized_mir = missing optimized MIR for `{$instance}` in the crate `{$crate_name}` diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 51c439b4243c..395d940ddae6 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -376,7 +376,7 @@ passes_no_main_function = } .consider_adding_main_to_file = consider adding a `main` function to `{$filename}` .consider_adding_main_at_crate = consider adding a `main` function at the crate level - .teach_note = If you don't know the basics of Rust, you can go look to the Rust Book to get started: https://doc.rust-lang.org/book/ + .teach_note = if you don't know the basics of Rust, you can go look to the Rust Book to get started: https://doc.rust-lang.org/book/ .non_function_main = non-function item at `crate::main` is found passes_non_exhaustive_with_default_field_values = From f5a1fc75ad10186b13ad34a65e176760b7306630 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 18 Jan 2026 22:41:00 +0100 Subject: [PATCH 2310/3801] Update uitests --- .../ui/attributes/crate-only-as-outer.stderr | 2 +- tests/ui/attributes/malformed-attrs.stderr | 2 +- tests/ui/attributes/malformed-no-std.stderr | 4 +- .../consts/const-mut-refs/issue-76510.stderr | 6 +- .../const-mut-refs/mut_ref_in_final.stderr | 36 +++++------ .../const-promoted-opaque.atomic.stderr | 6 +- .../issue-17718-const-bad-values.stderr | 6 +- .../ui/consts/issue-17718-const-borrow.stderr | 18 +++--- tests/ui/consts/partial_qualif.stderr | 6 +- tests/ui/consts/qualif_overwrite.stderr | 6 +- tests/ui/consts/qualif_overwrite_2.stderr | 6 +- tests/ui/consts/refs-to-cell-in-final.stderr | 18 +++--- .../consts/write_to_static_via_mut_ref.stderr | 6 +- tests/ui/error-codes/E0017.stderr | 12 ++-- tests/ui/error-codes/E0492.stderr | 12 ++-- .../issue-43106-gating-of-builtin-attrs.rs | 60 +++++++++---------- ...issue-43106-gating-of-builtin-attrs.stderr | 60 +++++++++---------- tests/ui/issues/issue-46604.stderr | 6 +- .../copy_into_box_rc_arc.stderr | 4 +- .../large_assignments/copy_into_fn.stderr | 6 +- .../lint/large_assignments/inline_mir.stderr | 4 +- .../large_future.attribute.stderr | 4 +- .../large_future.option.stderr | 4 +- .../move_into_box_rc_arc.stderr | 2 +- .../large_assignments/move_into_fn.stderr | 4 +- .../concat-in-crate-name-issue-137687.stderr | 2 +- .../unused/unused-attr-macro-rules.stderr | 2 +- .../statics/check-immutable-mut-slices.stderr | 6 +- ...eature_bound_incompatible_stability.stderr | 2 +- 29 files changed, 156 insertions(+), 156 deletions(-) diff --git a/tests/ui/attributes/crate-only-as-outer.stderr b/tests/ui/attributes/crate-only-as-outer.stderr index 270f02af9873..c1787a73d290 100644 --- a/tests/ui/attributes/crate-only-as-outer.stderr +++ b/tests/ui/attributes/crate-only-as-outer.stderr @@ -4,7 +4,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[crate_name = "owo"] | ^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/crate-only-as-outer.rs:5:1 | LL | fn main() {} diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 04f51f54b2cd..3d51731df792 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -771,7 +771,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[crate_name] | ^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/malformed-attrs.rs:116:1 | LL | / fn test() { diff --git a/tests/ui/attributes/malformed-no-std.stderr b/tests/ui/attributes/malformed-no-std.stderr index 89d7ee410d70..e994e28e030f 100644 --- a/tests/ui/attributes/malformed-no-std.stderr +++ b/tests/ui/attributes/malformed-no-std.stderr @@ -58,7 +58,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[no_std] | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this extern crate +note: this attribute does not have an `!`, which means it is applied to this extern crate --> $DIR/malformed-no-std.rs:26:1 | LL | extern crate core; @@ -75,7 +75,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[no_core] | ^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this extern crate +note: this attribute does not have an `!`, which means it is applied to this extern crate --> $DIR/malformed-no-std.rs:26:1 | LL | extern crate core; diff --git a/tests/ui/consts/const-mut-refs/issue-76510.stderr b/tests/ui/consts/const-mut-refs/issue-76510.stderr index 3a6c95141e52..82c9d523e738 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.stderr +++ b/tests/ui/consts/const-mut-refs/issue-76510.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr index da6f2a28d5a8..8f54b4eda227 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const B: *mut i32 = &mut 4; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:21:35 @@ -14,9 +14,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const B3: Option<&mut i32> = Some(&mut 42); | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0716]: temporary value dropped while borrowed --> $DIR/mut_ref_in_final.rs:24:42 @@ -86,9 +86,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static RAW_MUT_CAST_S: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:73:54 @@ -96,9 +96,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static RAW_MUT_COERCE_S: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:75:52 @@ -106,9 +106,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const RAW_MUT_CAST_C: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:77:53 @@ -116,9 +116,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const RAW_MUT_COERCE_C: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0080]: constructing invalid value at ..0: encountered a dangling reference (0x2a[noalloc] has no provenance) --> $DIR/mut_ref_in_final.rs:86:5 diff --git a/tests/ui/consts/const-promoted-opaque.atomic.stderr b/tests/ui/consts/const-promoted-opaque.atomic.stderr index 64cc7b3a3292..ac31992d0631 100644 --- a/tests/ui/consts/const-promoted-opaque.atomic.stderr +++ b/tests/ui/consts/const-promoted-opaque.atomic.stderr @@ -13,9 +13,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const BAZ: &Foo = &FOO; | ^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0716]: temporary value dropped while borrowed --> $DIR/const-promoted-opaque.rs:40:26 diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index 11e11adcb5ae..eebfa5d6ea40 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const C1: &'static mut [usize] = &mut []; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/issue-17718-const-borrow.stderr b/tests/ui/consts/issue-17718-const-borrow.stderr index 420a2c378a25..b801498c2028 100644 --- a/tests/ui/consts/issue-17718-const-borrow.stderr +++ b/tests/ui/consts/issue-17718-const-borrow.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const B: &'static UnsafeCell = &A; | ^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-17718-const-borrow.rs:9:39 @@ -14,9 +14,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const E: &'static UnsafeCell = &D.a; | ^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-17718-const-borrow.rs:11:23 @@ -24,9 +24,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const F: &'static C = &D; | ^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/partial_qualif.stderr b/tests/ui/consts/partial_qualif.stderr index b7632eb868ac..f69fa1c46c01 100644 --- a/tests/ui/consts/partial_qualif.stderr +++ b/tests/ui/consts/partial_qualif.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | &{a} | ^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/qualif_overwrite.stderr b/tests/ui/consts/qualif_overwrite.stderr index 4aaaa4b2ca90..1dc2bf7f1231 100644 --- a/tests/ui/consts/qualif_overwrite.stderr +++ b/tests/ui/consts/qualif_overwrite.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | &{a} | ^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/qualif_overwrite_2.stderr b/tests/ui/consts/qualif_overwrite_2.stderr index bc1681418765..fb8ac601c67a 100644 --- a/tests/ui/consts/qualif_overwrite_2.stderr +++ b/tests/ui/consts/qualif_overwrite_2.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | &{a.0} | ^^^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/refs-to-cell-in-final.stderr b/tests/ui/consts/refs-to-cell-in-final.stderr index ac866dbe7210..e30b5aa24e76 100644 --- a/tests/ui/consts/refs-to-cell-in-final.stderr +++ b/tests/ui/consts/refs-to-cell-in-final.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | static RAW_SYNC_S: SyncPtr> = SyncPtr { x: &Cell::new(42) }; | ^^^^^^^^^^^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/refs-to-cell-in-final.rs:15:53 @@ -14,9 +14,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const RAW_SYNC_C: SyncPtr> = SyncPtr { x: &Cell::new(42) }; | ^^^^^^^^^^^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/refs-to-cell-in-final.rs:41:57 @@ -31,9 +31,9 @@ LL | | x LL | | }; | |_^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/write_to_static_via_mut_ref.stderr b/tests/ui/consts/write_to_static_via_mut_ref.stderr index ce44047f1550..be1f7178998a 100644 --- a/tests/ui/consts/write_to_static_via_mut_ref.stderr +++ b/tests/ui/consts/write_to_static_via_mut_ref.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static OH_NO: &mut i32 = &mut 42; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0594]: cannot assign to `*OH_NO`, as `OH_NO` is an immutable static item --> $DIR/write_to_static_via_mut_ref.rs:4:5 diff --git a/tests/ui/error-codes/E0017.stderr b/tests/ui/error-codes/E0017.stderr index fcc57b9e5c3c..70186165d862 100644 --- a/tests/ui/error-codes/E0017.stderr +++ b/tests/ui/error-codes/E0017.stderr @@ -19,9 +19,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const CR: &'static mut i32 = &mut C; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0017.rs:11:39 @@ -52,9 +52,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 3 previous errors; 2 warnings emitted diff --git a/tests/ui/error-codes/E0492.stderr b/tests/ui/error-codes/E0492.stderr index 43a3a872e4e7..a5057e8baedb 100644 --- a/tests/ui/error-codes/E0492.stderr +++ b/tests/ui/error-codes/E0492.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const B: &'static AtomicUsize = &A; | ^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/E0492.rs:5:34 @@ -14,9 +14,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | static C: &'static AtomicUsize = &A; | ^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 3e3235e658f6..ce2f9a4e6eeb 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -525,25 +525,25 @@ mod macro_escape { #[no_std] //~^ WARN crate-level attribute should be an inner attribute mod no_std { - //~^ NOTE This attribute does not have an `!`, which means it is applied to this module + //~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![no_std] } //~^ WARN the `#![no_std]` attribute can only be used at the crate root #[no_std] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[no_std] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[no_std] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[no_std] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } // At time of authorship, #[proc_macro_derive = "2500"] signals error @@ -786,25 +786,25 @@ mod must_use { #[windows_subsystem = "windows"] //~^ WARN crate-level attribute should be an inner attribute mod windows_subsystem { - //~^ NOTE This attribute does not have an `!`, which means it is applied to this module + //~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![windows_subsystem="windows"] } //~^ WARN the `#![windows_subsystem]` attribute can only be used at the crate root #[windows_subsystem = "windows"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[windows_subsystem = "windows"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[windows_subsystem = "windows"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[windows_subsystem = "windows"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } // BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES @@ -812,25 +812,25 @@ mod windows_subsystem { #[crate_name = "0900"] //~^ WARN crate-level attribute should be an inner attribute mod crate_name { -//~^ NOTE This attribute does not have an `!`, which means it is applied to this module +//~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![crate_name="0900"] } //~^ WARN the `#![crate_name]` attribute can only be used at the crate root #[crate_name = "0900"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[crate_name = "0900"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[crate_name = "0900"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[crate_name = "0900"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } #[crate_type = "0800"] @@ -885,25 +885,25 @@ mod feature { #[no_main] //~^ WARN crate-level attribute should be an inner attribute mod no_main_1 { - //~^ NOTE: This attribute does not have an `!`, which means it is applied to this module + //~^ NOTE: this attribute does not have an `!`, which means it is applied to this module mod inner { #![no_main] } //~^ WARN the `#![no_main]` attribute can only be used at the crate root #[no_main] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[no_main] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[no_main] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[no_main] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation } #[no_builtins] @@ -933,49 +933,49 @@ mod no_builtins { #[recursion_limit="0200"] //~^ WARN crate-level attribute should be an inner attribute mod recursion_limit { - //~^ NOTE This attribute does not have an `!`, which means it is applied to this module + //~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![recursion_limit="0200"] } //~^ WARN the `#![recursion_limit]` attribute can only be used at the crate root #[recursion_limit="0200"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[recursion_limit="0200"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[recursion_limit="0200"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[recursion_limit="0200"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } #[type_length_limit="0100"] //~^ WARN crate-level attribute should be an inner attribute mod type_length_limit { - //~^ NOTE This attribute does not have an `!`, which means it is applied to this module + //~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![type_length_limit="0100"] } //~^ WARN the `#![type_length_limit]` attribute can only be used at the crate root #[type_length_limit="0100"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[type_length_limit="0100"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[type_length_limit="0100"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[type_length_limit="0100"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } fn main() {} diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index d89aec222be8..cbb80ccd753c 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -935,7 +935,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module +note: this attribute does not have an `!`, which means it is applied to this module --> $DIR/issue-43106-gating-of-builtin-attrs.rs:527:1 | LL | / mod no_std { @@ -957,7 +957,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] fn f() { } | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:15 | LL | #[no_std] fn f() { } @@ -969,7 +969,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] struct S; | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct +note: this attribute does not have an `!`, which means it is applied to this struct --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:15 | LL | #[no_std] struct S; @@ -981,7 +981,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] type T = S; | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias +note: this attribute does not have an `!`, which means it is applied to this type alias --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:15 | LL | #[no_std] type T = S; @@ -993,7 +993,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] impl S { } | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block +note: this attribute does not have an `!`, which means it is applied to this implementation block --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:15 | LL | #[no_std] impl S { } @@ -1212,7 +1212,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[windows_subsystem = "windows"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module +note: this attribute does not have an `!`, which means it is applied to this module --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:1 | LL | / mod windows_subsystem { @@ -1234,7 +1234,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[windows_subsystem = "windows"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:38 | LL | #[windows_subsystem = "windows"] fn f() { } @@ -1246,7 +1246,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[windows_subsystem = "windows"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct +note: this attribute does not have an `!`, which means it is applied to this struct --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:38 | LL | #[windows_subsystem = "windows"] struct S; @@ -1258,7 +1258,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[windows_subsystem = "windows"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias +note: this attribute does not have an `!`, which means it is applied to this type alias --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:38 | LL | #[windows_subsystem = "windows"] type T = S; @@ -1270,7 +1270,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[windows_subsystem = "windows"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block +note: this attribute does not have an `!`, which means it is applied to this implementation block --> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:38 | LL | #[windows_subsystem = "windows"] impl S { } @@ -1282,7 +1282,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module +note: this attribute does not have an `!`, which means it is applied to this module --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:1 | LL | / mod crate_name { @@ -1304,7 +1304,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:28 | LL | #[crate_name = "0900"] fn f() { } @@ -1316,7 +1316,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct +note: this attribute does not have an `!`, which means it is applied to this struct --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:28 | LL | #[crate_name = "0900"] struct S; @@ -1328,7 +1328,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias +note: this attribute does not have an `!`, which means it is applied to this type alias --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:28 | LL | #[crate_name = "0900"] type T = S; @@ -1340,7 +1340,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block +note: this attribute does not have an `!`, which means it is applied to this implementation block --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:28 | LL | #[crate_name = "0900"] impl S { } @@ -1352,7 +1352,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_main] | ^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module +note: this attribute does not have an `!`, which means it is applied to this module --> $DIR/issue-43106-gating-of-builtin-attrs.rs:887:1 | LL | / mod no_main_1 { @@ -1374,7 +1374,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_main] fn f() { } | ^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:16 | LL | #[no_main] fn f() { } @@ -1386,7 +1386,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_main] struct S; | ^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct +note: this attribute does not have an `!`, which means it is applied to this struct --> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:16 | LL | #[no_main] struct S; @@ -1398,7 +1398,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_main] type T = S; | ^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias +note: this attribute does not have an `!`, which means it is applied to this type alias --> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:16 | LL | #[no_main] type T = S; @@ -1410,7 +1410,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_main] impl S { } | ^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block +note: this attribute does not have an `!`, which means it is applied to this implementation block --> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:16 | LL | #[no_main] impl S { } @@ -1422,7 +1422,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module +note: this attribute does not have an `!`, which means it is applied to this module --> $DIR/issue-43106-gating-of-builtin-attrs.rs:935:1 | LL | / mod recursion_limit { @@ -1444,7 +1444,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:31 | LL | #[recursion_limit="0200"] fn f() { } @@ -1456,7 +1456,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct +note: this attribute does not have an `!`, which means it is applied to this struct --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:31 | LL | #[recursion_limit="0200"] struct S; @@ -1468,7 +1468,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias +note: this attribute does not have an `!`, which means it is applied to this type alias --> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:31 | LL | #[recursion_limit="0200"] type T = S; @@ -1480,7 +1480,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block +note: this attribute does not have an `!`, which means it is applied to this implementation block --> $DIR/issue-43106-gating-of-builtin-attrs.rs:952:31 | LL | #[recursion_limit="0200"] impl S { } @@ -1492,7 +1492,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module +note: this attribute does not have an `!`, which means it is applied to this module --> $DIR/issue-43106-gating-of-builtin-attrs.rs:959:1 | LL | / mod type_length_limit { @@ -1514,7 +1514,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:33 | LL | #[type_length_limit="0100"] fn f() { } @@ -1526,7 +1526,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct +note: this attribute does not have an `!`, which means it is applied to this struct --> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:33 | LL | #[type_length_limit="0100"] struct S; @@ -1538,7 +1538,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias +note: this attribute does not have an `!`, which means it is applied to this type alias --> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:33 | LL | #[type_length_limit="0100"] type T = S; @@ -1550,7 +1550,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block +note: this attribute does not have an `!`, which means it is applied to this implementation block --> $DIR/issue-43106-gating-of-builtin-attrs.rs:976:33 | LL | #[type_length_limit="0100"] impl S { } diff --git a/tests/ui/issues/issue-46604.stderr b/tests/ui/issues/issue-46604.stderr index abe3ad476c60..21abc498de12 100644 --- a/tests/ui/issues/issue-46604.stderr +++ b/tests/ui/issues/issue-46604.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; | ^^^^^^^^^^^^^^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0594]: cannot assign to `buf[_]`, as `buf` is an immutable static item --> $DIR/issue-46604.rs:6:5 diff --git a/tests/ui/lint/large_assignments/copy_into_box_rc_arc.stderr b/tests/ui/lint/large_assignments/copy_into_box_rc_arc.stderr index 6e42328a1113..b8e7abf4807c 100644 --- a/tests/ui/lint/large_assignments/copy_into_box_rc_arc.stderr +++ b/tests/ui/lint/large_assignments/copy_into_box_rc_arc.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | let _ = NotBox::new(data); | ^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/copy_into_box_rc_arc.rs:1:9 | @@ -19,7 +19,7 @@ LL | | data, LL | | } | |_________^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/large_assignments/copy_into_fn.stderr b/tests/ui/lint/large_assignments/copy_into_fn.stderr index f05fc33e17e1..a4c4800266af 100644 --- a/tests/ui/lint/large_assignments/copy_into_fn.stderr +++ b/tests/ui/lint/large_assignments/copy_into_fn.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | one_arg(Data([0; 9999])); | ^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/copy_into_fn.rs:5:9 | @@ -17,7 +17,7 @@ error: moving 9999 bytes LL | many_args(Data([0; 9999]), true, Data([0; 9999])); | ^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: moving 9999 bytes --> $DIR/copy_into_fn.rs:17:38 @@ -25,7 +25,7 @@ error: moving 9999 bytes LL | many_args(Data([0; 9999]), true, Data([0; 9999])); | ^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 3 previous errors diff --git a/tests/ui/lint/large_assignments/inline_mir.stderr b/tests/ui/lint/large_assignments/inline_mir.stderr index 1a5fcb6c8fc1..b8170d8977d2 100644 --- a/tests/ui/lint/large_assignments/inline_mir.stderr +++ b/tests/ui/lint/large_assignments/inline_mir.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | let cell = std::cell::UnsafeCell::new(data); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/inline_mir.rs:2:9 | @@ -17,7 +17,7 @@ error: moving 9999 bytes LL | std::hint::black_box(cell); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/large_assignments/large_future.attribute.stderr b/tests/ui/lint/large_assignments/large_future.attribute.stderr index 734b7ff7ba22..1580c31df3c2 100644 --- a/tests/ui/lint/large_assignments/large_future.attribute.stderr +++ b/tests/ui/lint/large_assignments/large_future.attribute.stderr @@ -4,7 +4,7 @@ error: moving 10024 bytes LL | let z = (x, 42); | ^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/large_future.rs:1:9 | @@ -17,7 +17,7 @@ error: moving 10024 bytes LL | let a = z.0; | ^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/large_assignments/large_future.option.stderr b/tests/ui/lint/large_assignments/large_future.option.stderr index 734b7ff7ba22..1580c31df3c2 100644 --- a/tests/ui/lint/large_assignments/large_future.option.stderr +++ b/tests/ui/lint/large_assignments/large_future.option.stderr @@ -4,7 +4,7 @@ error: moving 10024 bytes LL | let z = (x, 42); | ^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/large_future.rs:1:9 | @@ -17,7 +17,7 @@ error: moving 10024 bytes LL | let a = z.0; | ^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/large_assignments/move_into_box_rc_arc.stderr b/tests/ui/lint/large_assignments/move_into_box_rc_arc.stderr index a386de5e5e8e..35f30a79ad99 100644 --- a/tests/ui/lint/large_assignments/move_into_box_rc_arc.stderr +++ b/tests/ui/lint/large_assignments/move_into_box_rc_arc.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | data, | ^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/move_into_box_rc_arc.rs:1:9 | diff --git a/tests/ui/lint/large_assignments/move_into_fn.stderr b/tests/ui/lint/large_assignments/move_into_fn.stderr index 19ec6a51d2e7..4f4c710cacef 100644 --- a/tests/ui/lint/large_assignments/move_into_fn.stderr +++ b/tests/ui/lint/large_assignments/move_into_fn.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | let data = Data([100; 9999]); | ^^^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/move_into_fn.rs:5:9 | @@ -17,7 +17,7 @@ error: moving 9999 bytes LL | take_data(data); | ^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/unused/concat-in-crate-name-issue-137687.stderr b/tests/ui/lint/unused/concat-in-crate-name-issue-137687.stderr index b06e65af7bc7..5928eb6c58c4 100644 --- a/tests/ui/lint/unused/concat-in-crate-name-issue-137687.stderr +++ b/tests/ui/lint/unused/concat-in-crate-name-issue-137687.stderr @@ -17,7 +17,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[crate_name = concat !()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this macro def +note: this attribute does not have an `!`, which means it is applied to this macro def --> $DIR/concat-in-crate-name-issue-137687.rs:5:1 | LL | / macro_rules! a { diff --git a/tests/ui/lint/unused/unused-attr-macro-rules.stderr b/tests/ui/lint/unused/unused-attr-macro-rules.stderr index e251ec65622e..75e86d3c014f 100644 --- a/tests/ui/lint/unused/unused-attr-macro-rules.stderr +++ b/tests/ui/lint/unused/unused-attr-macro-rules.stderr @@ -27,7 +27,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[recursion_limit="1"] | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this macro def +note: this attribute does not have an `!`, which means it is applied to this macro def --> $DIR/unused-attr-macro-rules.rs:12:1 | LL | / macro_rules! foo { diff --git a/tests/ui/statics/check-immutable-mut-slices.stderr b/tests/ui/statics/check-immutable-mut-slices.stderr index a9486fc9d781..1e6dfb78c93d 100644 --- a/tests/ui/statics/check-immutable-mut-slices.stderr +++ b/tests/ui/statics/check-immutable-mut-slices.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static TEST: &'static mut [isize] = &mut []; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr index 9f07e63e4544..e144b981f3cd 100644 --- a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr @@ -4,7 +4,7 @@ error: item annotated with `#[unstable_feature_bound]` should not be stable LL | fn bar() {} | ^^^^^^^^^^^ | - = help: If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` + = help: if this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` error: aborting due to 1 previous error From 08432c892758a06a6bab9fa0584effb7e7881303 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Sun, 18 Jan 2026 22:49:37 +0100 Subject: [PATCH 2311/3801] Optimize small input path for is_ascii on x86_64 For inputs smaller than 32 bytes, use usize-at-a-time processing instead of calling the SSE2 function. This avoids function call overhead from #[target_feature(enable = "sse2")] which prevents inlining. Also moves CHUNK_SIZE to module level so it can be shared between is_ascii and is_ascii_sse2. --- library/core/src/slice/ascii.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index c9e168d6cbf8..25b8a10af355 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -460,6 +460,10 @@ const fn is_ascii(s: &[u8]) -> bool { ) } +/// Chunk size for vectorized ASCII checking (two 16-byte SSE registers). +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +const CHUNK_SIZE: usize = 32; + /// SSE2 implementation using `_mm_movemask_epi8` (compiles to `pmovmskb`) to /// avoid LLVM's broken AVX-512 auto-vectorization of counting loops. /// @@ -470,8 +474,6 @@ const fn is_ascii(s: &[u8]) -> bool { unsafe fn is_ascii_sse2(bytes: &[u8]) -> bool { use crate::arch::x86_64::{__m128i, _mm_loadu_si128, _mm_movemask_epi8, _mm_or_si128}; - const CHUNK_SIZE: usize = 32; - let mut i = 0; while i + CHUNK_SIZE <= bytes.len() { @@ -518,11 +520,27 @@ unsafe fn is_ascii_sse2(bytes: &[u8]) -> bool { #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] const fn is_ascii(bytes: &[u8]) -> bool { + const USIZE_SIZE: usize = size_of::(); + const NONASCII_MASK: usize = usize::MAX / 255 * 0x80; + const_eval_select!( @capture { bytes: &[u8] } -> bool: if const { is_ascii_simple(bytes) } else { + // For small inputs, use usize-at-a-time processing to avoid SSE2 call overhead. + if bytes.len() < CHUNK_SIZE { + let chunks = bytes.chunks_exact(USIZE_SIZE); + let remainder = chunks.remainder(); + for chunk in chunks { + let word = usize::from_ne_bytes(chunk.try_into().unwrap()); + if (word & NONASCII_MASK) != 0 { + return false; + } + } + return remainder.iter().all(|b| b.is_ascii()); + } + // SAFETY: SSE2 is guaranteed available on x86_64 unsafe { is_ascii_sse2(bytes) } } From 3a8b57715f1e762fbb78edc89c767446b7fdc0ea Mon Sep 17 00:00:00 2001 From: KaiTomotake Date: Sun, 18 Jan 2026 22:43:35 +0900 Subject: [PATCH 2312/3801] add lint test Co-authored-by: Redddy --- .../unused_assignments_across_match_guards.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/ui/lint/unused/unused_assignments_across_match_guards.rs diff --git a/tests/ui/lint/unused/unused_assignments_across_match_guards.rs b/tests/ui/lint/unused/unused_assignments_across_match_guards.rs new file mode 100644 index 000000000000..666a529b8f85 --- /dev/null +++ b/tests/ui/lint/unused/unused_assignments_across_match_guards.rs @@ -0,0 +1,19 @@ +// Regression test for +// This test ensures that unused_assignments does not report assignments used in a match. +//@ check-pass + +fn pnk(x: usize) -> &'static str { + let mut k1 = "k1"; + let mut h1 = "h1"; + match x & 3 { + 3 if { k1 = "unused?"; false } => (), + _ if { h1 = k1; true } => (), + _ => (), + } + h1 +} + +#[deny(unused_assignments)] +fn main() { + pnk(3); +} From 3327a92b4353a03c60dbb2c58564be754e93db22 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Nov 2025 20:40:15 +1100 Subject: [PATCH 2313/3801] Add some tests for trimmed paths in diagnostics --- .../auxiliary/doc_hidden_helper.rs | 18 +++++ tests/ui/trimmed-paths/core-unicode.rs | 19 ++++++ tests/ui/trimmed-paths/core-unicode.stderr | 14 ++++ tests/ui/trimmed-paths/doc-hidden.rs | 68 +++++++++++++++++++ tests/ui/trimmed-paths/doc-hidden.stderr | 39 +++++++++++ 5 files changed, 158 insertions(+) create mode 100644 tests/ui/trimmed-paths/auxiliary/doc_hidden_helper.rs create mode 100644 tests/ui/trimmed-paths/core-unicode.rs create mode 100644 tests/ui/trimmed-paths/core-unicode.stderr create mode 100644 tests/ui/trimmed-paths/doc-hidden.rs create mode 100644 tests/ui/trimmed-paths/doc-hidden.stderr diff --git a/tests/ui/trimmed-paths/auxiliary/doc_hidden_helper.rs b/tests/ui/trimmed-paths/auxiliary/doc_hidden_helper.rs new file mode 100644 index 000000000000..2e5e1591606e --- /dev/null +++ b/tests/ui/trimmed-paths/auxiliary/doc_hidden_helper.rs @@ -0,0 +1,18 @@ +//@ edition: 2024 + +pub struct ActuallyPub {} +#[doc(hidden)] +pub struct DocHidden {} + +pub mod pub_mod { + pub struct ActuallyPubInPubMod {} + #[doc(hidden)] + pub struct DocHiddenInPubMod {} +} + +#[doc(hidden)] +pub mod hidden_mod { + pub struct ActuallyPubInHiddenMod {} + #[doc(hidden)] + pub struct DocHiddenInHiddenMod {} +} diff --git a/tests/ui/trimmed-paths/core-unicode.rs b/tests/ui/trimmed-paths/core-unicode.rs new file mode 100644 index 000000000000..54bde92a5335 --- /dev/null +++ b/tests/ui/trimmed-paths/core-unicode.rs @@ -0,0 +1,19 @@ +//@ edition: 2024 + +// Test that the `#[doc(hidden)]` module `core::unicode` module does not +// disqualify another item named `unicode` from path trimming in diagnostics. + +use core::marker::PhantomData; + +mod inner { + #[expect(non_camel_case_types)] + pub(crate) enum unicode {} +} + +fn main() { + let PhantomData::<(inner::unicode, u32)> = PhantomData::<(u32, inner::unicode)>; + //~^ ERROR mismatched types [E0308] + //~| NOTE expected `PhantomData<(u32, unicode)>`, found `PhantomData<(unicode, u32)>` + //~| NOTE this expression has type `PhantomData<(u32, inner::unicode)>` + //~| NOTE expected struct `PhantomData<(u32, inner::unicode)>` +} diff --git a/tests/ui/trimmed-paths/core-unicode.stderr b/tests/ui/trimmed-paths/core-unicode.stderr new file mode 100644 index 000000000000..9023200d1c92 --- /dev/null +++ b/tests/ui/trimmed-paths/core-unicode.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/core-unicode.rs:14:9 + | +LL | let PhantomData::<(inner::unicode, u32)> = PhantomData::<(u32, inner::unicode)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------------------------ this expression has type `PhantomData<(u32, inner::unicode)>` + | | + | expected `PhantomData<(u32, unicode)>`, found `PhantomData<(unicode, u32)>` + | + = note: expected struct `PhantomData<(u32, inner::unicode)>` + found struct `PhantomData<(inner::unicode, u32)>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/trimmed-paths/doc-hidden.rs b/tests/ui/trimmed-paths/doc-hidden.rs new file mode 100644 index 000000000000..b73d04c3c6ae --- /dev/null +++ b/tests/ui/trimmed-paths/doc-hidden.rs @@ -0,0 +1,68 @@ +//@ edition: 2024 +//@ aux-crate: helper=doc_hidden_helper.rs + +// Test that `#[doc(hidden)]` items in other crates do not disqualify another +// item with the same name from path trimming in diagnostics. + +// Declare several modules and types whose short names match those in the aux crate. +// +// Of these, only `ActuallyPub` and `ActuallyPubInPubMod` should be disqualified +// from path trimming, because the other names only collide with `#[doc(hidden)]` +// names. +mod local { + pub(crate) struct ActuallyPub {} + pub(crate) struct DocHidden {} + + pub(crate) mod pub_mod { + pub(crate) struct ActuallyPubInPubMod {} + pub(crate) struct DocHiddenInPubMod {} + } + + pub(crate) mod hidden_mod { + pub(crate) struct ActuallyPubInHiddenMod {} + pub(crate) struct DocHiddenInHiddenMod {} + } +} + +fn main() { + uses_local(); + uses_helper(); +} + +fn uses_local() { + use local::{ActuallyPub, DocHidden}; + use local::pub_mod::{ActuallyPubInPubMod, DocHiddenInPubMod}; + use local::hidden_mod::{ActuallyPubInHiddenMod, DocHiddenInHiddenMod}; + + let _: ( + //~^ NOTE expected due to this + ActuallyPub, + DocHidden, + ActuallyPubInPubMod, + DocHiddenInPubMod, + ActuallyPubInHiddenMod, + DocHiddenInHiddenMod, + ) = 3u32; + //~^ ERROR mismatched types [E0308] + //~| NOTE expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + //~| NOTE expected tuple `(local::ActuallyPub, local::DocHidden, local::pub_mod::ActuallyPubInPubMod, local::pub_mod::DocHiddenInPubMod, local::hidden_mod::ActuallyPubInHiddenMod, local::hidden_mod::DocHiddenInHiddenMod)` +} + +fn uses_helper() { + use helper::{ActuallyPub, DocHidden}; + use helper::pub_mod::{ActuallyPubInPubMod, DocHiddenInPubMod}; + use helper::hidden_mod::{ActuallyPubInHiddenMod, DocHiddenInHiddenMod}; + + let _: ( + //~^ NOTE expected due to this + ActuallyPub, + DocHidden, + ActuallyPubInPubMod, + DocHiddenInPubMod, + ActuallyPubInHiddenMod, + DocHiddenInHiddenMod, + ) = 3u32; + //~^ ERROR mismatched types [E0308] + //~| NOTE expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + //~| NOTE expected tuple `(doc_hidden_helper::ActuallyPub, doc_hidden_helper::DocHidden, doc_hidden_helper::pub_mod::ActuallyPubInPubMod, doc_hidden_helper::pub_mod::DocHiddenInPubMod, doc_hidden_helper::hidden_mod::ActuallyPubInHiddenMod, doc_hidden_helper::hidden_mod::DocHiddenInHiddenMod)` +} diff --git a/tests/ui/trimmed-paths/doc-hidden.stderr b/tests/ui/trimmed-paths/doc-hidden.stderr new file mode 100644 index 000000000000..6f6f8f21fbe0 --- /dev/null +++ b/tests/ui/trimmed-paths/doc-hidden.stderr @@ -0,0 +1,39 @@ +error[E0308]: mismatched types + --> $DIR/doc-hidden.rs:45:9 + | +LL | let _: ( + | ____________- +LL | | +LL | | ActuallyPub, +LL | | DocHidden, +... | +LL | | DocHiddenInHiddenMod, +LL | | ) = 3u32; + | | - ^^^^ expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + | |_____| + | expected due to this + | + = note: expected tuple `(local::ActuallyPub, local::DocHidden, local::pub_mod::ActuallyPubInPubMod, local::pub_mod::DocHiddenInPubMod, local::hidden_mod::ActuallyPubInHiddenMod, local::hidden_mod::DocHiddenInHiddenMod)` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/doc-hidden.rs:64:9 + | +LL | let _: ( + | ____________- +LL | | +LL | | ActuallyPub, +LL | | DocHidden, +... | +LL | | DocHiddenInHiddenMod, +LL | | ) = 3u32; + | | - ^^^^ expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + | |_____| + | expected due to this + | + = note: expected tuple `(doc_hidden_helper::ActuallyPub, doc_hidden_helper::DocHidden, doc_hidden_helper::pub_mod::ActuallyPubInPubMod, doc_hidden_helper::pub_mod::DocHiddenInPubMod, doc_hidden_helper::hidden_mod::ActuallyPubInHiddenMod, doc_hidden_helper::hidden_mod::DocHiddenInHiddenMod)` + found type `u32` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 2df2c72d7ae36d11313ed730960030cc5af9fb21 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Nov 2025 18:56:10 +1100 Subject: [PATCH 2314/3801] Ignore `#[doc(hidden)]` items when computing trimmed paths --- compiler/rustc_middle/src/ty/print/pretty.rs | 7 ++++++ ...oo-{closure#0}-{closure#0}.built.after.mir | 2 +- ...-{closure#0}-{synthetic#0}.built.after.mir | 2 +- ...0}-{closure#0}-{closure#0}.built.after.mir | 2 +- ...-{closure#0}-{synthetic#0}.built.after.mir | 2 +- ...0}-{closure#1}-{closure#0}.built.after.mir | 2 +- ...-{closure#1}-{synthetic#0}.built.after.mir | 2 +- tests/mir-opt/box_expr.rs | 2 +- .../issue_101867.main.built.after.mir | 2 +- .../boxes.main.GVN.panic-abort.diff | 4 ++-- .../boxes.main.GVN.panic-unwind.diff | 4 ++-- ..._simplification.hello.GVN.panic-abort.diff | 2 +- ...simplification.hello.GVN.panic-unwind.diff | 2 +- .../transmute.unreachable_box.GVN.32bit.diff | 2 +- .../transmute.unreachable_box.GVN.64bit.diff | 2 +- ...n.DataflowConstProp.32bit.panic-abort.diff | 10 ++++----- ....DataflowConstProp.32bit.panic-unwind.diff | 10 ++++----- ...n.DataflowConstProp.64bit.panic-abort.diff | 10 ++++----- ....DataflowConstProp.64bit.panic-unwind.diff | 10 ++++----- ...oxed_slice.main.GVN.32bit.panic-abort.diff | 12 +++++----- ...xed_slice.main.GVN.32bit.panic-unwind.diff | 12 +++++----- ...oxed_slice.main.GVN.64bit.panic-abort.diff | 12 +++++----- ...xed_slice.main.GVN.64bit.panic-unwind.diff | 12 +++++----- ...reachable_box.DataflowConstProp.32bit.diff | 2 +- ...reachable_box.DataflowConstProp.64bit.diff | 2 +- ...ng_operand.test.GVN.32bit.panic-abort.diff | 2 +- ...ng_operand.test.GVN.64bit.panic-abort.diff | 2 +- ...onential_common.GVN.32bit.panic-abort.diff | 4 ++-- ...nential_common.GVN.32bit.panic-unwind.diff | 4 ++-- ...onential_common.GVN.64bit.panic-abort.diff | 4 ++-- ...nential_common.GVN.64bit.panic-unwind.diff | 4 ++-- tests/mir-opt/gvn.slices.GVN.panic-abort.diff | 8 +++---- .../mir-opt/gvn.slices.GVN.panic-unwind.diff | 8 +++---- .../gvn.wrap_unwrap.GVN.panic-abort.diff | 2 +- .../gvn.wrap_unwrap.GVN.panic-unwind.diff | 2 +- ...inline_diverging.g.Inline.panic-abort.diff | 2 +- ...nline_diverging.g.Inline.panic-unwind.diff | 2 +- .../inline_shims.drop.Inline.panic-abort.diff | 4 ++-- ..._conditions.JumpThreading.panic-abort.diff | 8 +++---- ...conditions.JumpThreading.panic-unwind.diff | 8 +++---- ...fg-pre-optimizations.after.panic-abort.mir | 2 +- ...g-pre-optimizations.after.panic-unwind.mir | 2 +- ...ace.PreCodegen.after.32bit.panic-abort.mir | 8 +++---- ...ce.PreCodegen.after.32bit.panic-unwind.mir | 8 +++---- ...ace.PreCodegen.after.64bit.panic-abort.mir | 8 +++---- ...ce.PreCodegen.after.64bit.panic-unwind.mir | 8 +++---- .../loops.vec_move.PreCodegen.after.mir | 4 ++-- ..._to_slice.PreCodegen.after.panic-abort.mir | 4 ++-- ...to_slice.PreCodegen.after.panic-unwind.mir | 4 ++-- ...mes.foo.ScalarReplacementOfAggregates.diff | 2 +- .../async-closures/def-path.stderr | 4 ++-- .../unsizing-wfcheck-issue-126272.stderr | 2 +- tests/ui/consts/const-eval/format.rs | 2 +- tests/ui/consts/const-eval/format.stderr | 2 +- .../contract-captures-via-closure-noncopy.rs | 2 +- ...ntract-captures-via-closure-noncopy.stderr | 4 ++-- ...derives-span-Eq-enum-struct-variant.stderr | 2 +- tests/ui/derives/derives-span-Eq-enum.stderr | 2 +- .../ui/derives/derives-span-Eq-struct.stderr | 2 +- .../derives-span-Eq-tuple-struct.stderr | 2 +- tests/ui/deriving/issue-103157.stderr | 2 +- tests/ui/issues/issue-27340.stderr | 2 +- tests/ui/kindck/kindck-send-object.stderr | 2 +- tests/ui/kindck/kindck-send-object1.stderr | 2 +- tests/ui/kindck/kindck-send-object2.stderr | 2 +- tests/ui/kindck/kindck-send-owned.stderr | 2 +- .../type-length-limit-enforcement.stderr | 4 +++- tests/ui/proc-macro/bad-projection.stderr | 2 +- tests/ui/proc-macro/proc-macro-abi.stderr | 12 +++++----- ...does-not-have-iter-interpolated-dup.stderr | 2 +- .../does-not-have-iter-interpolated.stderr | 2 +- tests/ui/proc-macro/quote/not-quotable.stderr | 2 +- .../signature-proc-macro-attribute.stderr | 16 +++++++------- .../signature-proc-macro-derive.stderr | 22 +++++++++---------- .../ui/proc-macro/signature-proc-macro.stderr | 22 +++++++++---------- tests/ui/proc-macro/signature.stderr | 2 +- ...lobal-variable-promotion-error-7364.stderr | 2 +- tests/ui/traits/const-traits/issue-79450.rs | 2 +- .../ui/traits/const-traits/issue-79450.stderr | 2 +- tests/ui/traits/cycle-cache-err-60010.stderr | 4 ++-- .../negated-auto-traits-error.stderr | 8 +++---- tests/ui/trimmed-paths/core-unicode.rs | 4 ++-- tests/ui/trimmed-paths/core-unicode.stderr | 6 ++--- tests/ui/trimmed-paths/doc-hidden.rs | 2 +- tests/ui/trimmed-paths/doc-hidden.stderr | 2 +- .../panic-with-unspecified-type.stderr | 2 +- .../ui/type/pattern_types/derives_fail.stderr | 2 +- tests/ui/union/union-derive-clone.stderr | 2 +- tests/ui/union/union-derive-eq.current.stderr | 2 +- tests/ui/union/union-derive-eq.next.stderr | 2 +- 90 files changed, 209 insertions(+), 200 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 2a65517de403..fd0a5ca309a4 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3421,6 +3421,13 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N def::Res::Def(DefKind::AssocTy, _) => {} def::Res::Def(DefKind::TyAlias, _) => {} def::Res::Def(defkind, def_id) => { + // Ignore external `#[doc(hidden)]` items and their descendants. + // They shouldn't prevent other items from being considered + // unique, and should be printed with a full path if necessary. + if tcx.is_doc_hidden(def_id) { + continue; + } + if let Some(ns) = defkind.ns() { collect_fn(&child.ident, ns, def_id); } diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir index 9ff1a90ab820..4c9ca11f8283 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `foo::{closure#0}::{closure#0}` after built -fn foo::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> () +fn foo::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: std::future::ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir index 4b745caf48c5..e80fdea7051d 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `foo::{closure#0}::{synthetic#0}` after built -fn foo::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> () +fn foo::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: std::future::ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir index 4d484b16b507..075065b4c090 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{closure#0}` after built -fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: std::future::ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir index ace780f773e8..0f4e5f3cb02f 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{synthetic#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{synthetic#0}` after built -fn main::{closure#0}::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: std::future::ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir index f50ad689f447..18f4e741384f 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#1}::{closure#0}` after built -fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: std::future::ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir index 62d8adeedcb6..257586c4a080 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{synthetic#0}.built.after.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#1}::{synthetic#0}` after built -fn main::{closure#0}::{closure#1}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#1}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: std::future::ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/box_expr.rs b/tests/mir-opt/box_expr.rs index 6299c9871809..dbb07a028a93 100644 --- a/tests/mir-opt/box_expr.rs +++ b/tests/mir-opt/box_expr.rs @@ -8,7 +8,7 @@ fn main() { // CHECK-LABEL: fn main( // CHECK: [[ptr:_.*]] = move {{_.*}} as *const S (Transmute); // CHECK: [[nonnull:_.*]] = NonNull:: { pointer: move [[ptr]] }; - // CHECK: [[unique:_.*]] = Unique:: { pointer: move [[nonnull]], _marker: const PhantomData:: }; + // CHECK: [[unique:_.*]] = std::ptr::Unique:: { pointer: move [[nonnull]], _marker: const PhantomData:: }; // CHECK: [[box:_.*]] = Box::(move [[unique]], const std::alloc::Global); // CHECK: [[ptr:_.*]] = copy (([[box]].0: std::ptr::Unique).0: std::ptr::NonNull) as *const S (Transmute); // CHECK: (*[[ptr]]) = S::new() -> [return: [[ret:bb.*]], unwind: [[unwind:bb.*]]]; diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir index 83281dea44db..cef4325b9a4d 100644 --- a/tests/mir-opt/building/issue_101867.main.built.after.mir +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -32,7 +32,7 @@ fn main() -> () { bb1: { StorageLive(_3); StorageLive(_4); - _4 = begin_panic::<&str>(const "explicit panic") -> bb8; + _4 = std::rt::begin_panic::<&str>(const "explicit panic") -> bb8; } bb2: { diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff index 95eaf18b4703..ecc4b35ebcb6 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff @@ -29,10 +29,10 @@ StorageLive(_5); - _6 = move _4 as *const i32 (Transmute); - _7 = NonNull:: { pointer: move _6 }; -- _8 = Unique:: { pointer: move _7, _marker: const PhantomData:: }; +- _8 = std::ptr::Unique:: { pointer: move _7, _marker: const PhantomData:: }; + _6 = copy _4 as *const i32 (PtrToPtr); + _7 = NonNull:: { pointer: copy _6 }; -+ _8 = Unique:: { pointer: copy _7, _marker: const PhantomData:: }; ++ _8 = std::ptr::Unique:: { pointer: copy _7, _marker: const PhantomData:: }; _5 = Box::(move _8, const std::alloc::Global); - _9 = copy ((_5.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - (*_9) = const 42_i32; diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff index 6d8d3a0dcfe2..aba1a4f1df47 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff @@ -29,10 +29,10 @@ StorageLive(_5); - _6 = move _4 as *const i32 (Transmute); - _7 = NonNull:: { pointer: move _6 }; -- _8 = Unique:: { pointer: move _7, _marker: const PhantomData:: }; +- _8 = std::ptr::Unique:: { pointer: move _7, _marker: const PhantomData:: }; + _6 = copy _4 as *const i32 (PtrToPtr); + _7 = NonNull:: { pointer: copy _6 }; -+ _8 = Unique:: { pointer: copy _7, _marker: const PhantomData:: }; ++ _8 = std::ptr::Unique:: { pointer: copy _7, _marker: const PhantomData:: }; _5 = Box::(move _8, const std::alloc::Global); - _9 = copy ((_5.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - (*_9) = const 42_i32; diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff index 5df2232053fe..2ecf41638125 100644 --- a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff +++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff @@ -10,7 +10,7 @@ } bb1: { - _1 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; + _1 = std::rt::begin_panic::<&str>(const "explicit panic") -> unwind unreachable; } bb2: { diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff index 788a4424943e..06287b670dd4 100644 --- a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff +++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff @@ -10,7 +10,7 @@ } bb1: { - _1 = begin_panic::<&str>(const "explicit panic") -> unwind continue; + _1 = std::rt::begin_panic::<&str>(const "explicit panic") -> unwind continue; } bb2: { diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff index b698d8f37357..bd24af602c88 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff @@ -13,7 +13,7 @@ StorageLive(_1); - _1 = const 1_usize as std::boxed::Box (Transmute); - _2 = copy ((_1.0: std::ptr::Unique).0: std::ptr::NonNull) as *const Never (Transmute); -+ _1 = const Box::(Unique:: {{ pointer: NonNull:: {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData:: }}, std::alloc::Global); ++ _1 = const Box::(std::ptr::Unique:: {{ pointer: NonNull:: {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData:: }}, std::alloc::Global); + _2 = const std::ptr::NonNull:: {{ pointer: {0x1 as *const Never} }} as *const Never (Transmute); unreachable; } diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff index b698d8f37357..bd24af602c88 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff @@ -13,7 +13,7 @@ StorageLive(_1); - _1 = const 1_usize as std::boxed::Box (Transmute); - _2 = copy ((_1.0: std::ptr::Unique).0: std::ptr::NonNull) as *const Never (Transmute); -+ _1 = const Box::(Unique:: {{ pointer: NonNull:: {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData:: }}, std::alloc::Global); ++ _1 = const Box::(std::ptr::Unique:: {{ pointer: NonNull:: {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData:: }}, std::alloc::Global); + _2 = const std::ptr::NonNull:: {{ pointer: {0x1 as *const Never} }} as *const Never (Transmute); unreachable; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff index 2c89670dcf7d..7a60070b7074 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff @@ -13,7 +13,7 @@ let mut _4: std::ptr::Unique<[bool; 0]>; scope 3 { } - scope 4 (inlined Unique::<[bool; 0]>::dangling) { + scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { let mut _6: std::num::NonZero; @@ -51,13 +51,13 @@ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_7); StorageDead(_6); - _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; + _4 = const std::ptr::Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); - _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; + _3 = const std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); + _2 = const Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); StorageDead(_3); - _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; + _1 = const A {{ foo: Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind unreachable]; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff index 8fecfe224cc6..d13d0d962a69 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff @@ -13,7 +13,7 @@ let mut _4: std::ptr::Unique<[bool; 0]>; scope 3 { } - scope 4 (inlined Unique::<[bool; 0]>::dangling) { + scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { let mut _6: std::num::NonZero; @@ -51,13 +51,13 @@ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_7); StorageDead(_6); - _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; + _4 = const std::ptr::Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); - _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; + _3 = const std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); + _2 = const Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); StorageDead(_3); - _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; + _1 = const A {{ foo: Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind: bb2]; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff index 976ea252c2f8..8701e879e959 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff @@ -13,7 +13,7 @@ let mut _4: std::ptr::Unique<[bool; 0]>; scope 3 { } - scope 4 (inlined Unique::<[bool; 0]>::dangling) { + scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { let mut _6: std::num::NonZero; @@ -51,13 +51,13 @@ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_7); StorageDead(_6); - _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; + _4 = const std::ptr::Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); - _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; + _3 = const std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); + _2 = const Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); StorageDead(_3); - _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; + _1 = const A {{ foo: Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind unreachable]; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff index 6c59f5e3e2e8..ac1c8d627baa 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff @@ -13,7 +13,7 @@ let mut _4: std::ptr::Unique<[bool; 0]>; scope 3 { } - scope 4 (inlined Unique::<[bool; 0]>::dangling) { + scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { let mut _6: std::num::NonZero; @@ -51,13 +51,13 @@ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_7); StorageDead(_6); - _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; + _4 = const std::ptr::Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); - _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; + _3 = const std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); + _2 = const Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); StorageDead(_3); - _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; + _1 = const A {{ foo: Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind: bb2]; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff index 1f9cf6d6aca8..0205d0cc3d16 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff @@ -13,7 +13,7 @@ let mut _4: std::ptr::Unique<[bool; 0]>; scope 3 { } - scope 4 (inlined Unique::<[bool; 0]>::dangling) { + scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { let mut _6: std::num::NonZero; @@ -54,17 +54,17 @@ + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_7); StorageDead(_6); -- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; -+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; +- _4 = std::ptr::Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; ++ _4 = const std::ptr::Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); - _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); -+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; ++ _3 = const std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = Box::<[bool]>(copy _3, const std::alloc::Global); -+ _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); ++ _2 = const Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); StorageDead(_3); - _1 = A { foo: move _2 }; -+ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; ++ _1 = const A {{ foo: Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind unreachable]; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff index a8760285fac1..f6babe35b5a0 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff @@ -13,7 +13,7 @@ let mut _4: std::ptr::Unique<[bool; 0]>; scope 3 { } - scope 4 (inlined Unique::<[bool; 0]>::dangling) { + scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { let mut _6: std::num::NonZero; @@ -54,17 +54,17 @@ + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_7); StorageDead(_6); -- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; -+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; +- _4 = std::ptr::Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; ++ _4 = const std::ptr::Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); - _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); -+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; ++ _3 = const std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = Box::<[bool]>(copy _3, const std::alloc::Global); -+ _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); ++ _2 = const Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); StorageDead(_3); - _1 = A { foo: move _2 }; -+ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; ++ _1 = const A {{ foo: Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind: bb2]; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff index c398ae70a1a3..204e59415c6b 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff @@ -13,7 +13,7 @@ let mut _4: std::ptr::Unique<[bool; 0]>; scope 3 { } - scope 4 (inlined Unique::<[bool; 0]>::dangling) { + scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { let mut _6: std::num::NonZero; @@ -54,17 +54,17 @@ + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_7); StorageDead(_6); -- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; -+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; +- _4 = std::ptr::Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; ++ _4 = const std::ptr::Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); - _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); -+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; ++ _3 = const std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = Box::<[bool]>(copy _3, const std::alloc::Global); -+ _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); ++ _2 = const Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); StorageDead(_3); - _1 = A { foo: move _2 }; -+ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; ++ _1 = const A {{ foo: Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind unreachable]; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff index 02934c02587d..0cf3f43c0464 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff @@ -13,7 +13,7 @@ let mut _4: std::ptr::Unique<[bool; 0]>; scope 3 { } - scope 4 (inlined Unique::<[bool; 0]>::dangling) { + scope 4 (inlined std::ptr::Unique::<[bool; 0]>::dangling) { let mut _5: std::ptr::NonNull<[bool; 0]>; scope 5 (inlined NonNull::<[bool; 0]>::dangling) { let mut _6: std::num::NonZero; @@ -54,17 +54,17 @@ + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; StorageDead(_7); StorageDead(_6); -- _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; -+ _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; +- _4 = std::ptr::Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; ++ _4 = const std::ptr::Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); - _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); -+ _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; ++ _3 = const std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = Box::<[bool]>(copy _3, const std::alloc::Global); -+ _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); ++ _2 = const Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global); StorageDead(_3); - _1 = A { foo: move _2 }; -+ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; ++ _1 = const A {{ foo: Box::<[bool]>(std::ptr::Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); drop(_1) -> [return: bb1, unwind: bb2]; diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff index fa6c2e29e072..3bc5f8507590 100644 --- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff @@ -12,7 +12,7 @@ bb0: { StorageLive(_1); - _1 = const 1_usize as std::boxed::Box (Transmute); -+ _1 = const Box::(Unique:: {{ pointer: NonNull:: {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData:: }}, std::alloc::Global); ++ _1 = const Box::(std::ptr::Unique:: {{ pointer: NonNull:: {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData:: }}, std::alloc::Global); _2 = copy ((_1.0: std::ptr::Unique).0: std::ptr::NonNull) as *const Never (Transmute); unreachable; } diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff index fa6c2e29e072..3bc5f8507590 100644 --- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff @@ -12,7 +12,7 @@ bb0: { StorageLive(_1); - _1 = const 1_usize as std::boxed::Box (Transmute); -+ _1 = const Box::(Unique:: {{ pointer: NonNull:: {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData:: }}, std::alloc::Global); ++ _1 = const Box::(std::ptr::Unique:: {{ pointer: NonNull:: {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData:: }}, std::alloc::Global); _2 = copy ((_1.0: std::ptr::Unique).0: std::ptr::NonNull) as *const Never (Transmute); unreachable; } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index bcf0ad7c165f..2e428b778504 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -133,7 +133,7 @@ - _13 = copy _12 as *const () (PtrToPtr); + _13 = copy _25 as *const () (PtrToPtr); _14 = NonNull::<()> { pointer: copy _13 }; - _15 = Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> }; + _15 = std::ptr::Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> }; _3 = Box::<()>(move _15, const std::alloc::Global); - (*_13) = move _4; + (*_13) = const (); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 1b75a2bcba8b..4531720ee501 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -133,7 +133,7 @@ - _13 = copy _12 as *const () (PtrToPtr); + _13 = copy _25 as *const () (PtrToPtr); _14 = NonNull::<()> { pointer: copy _13 }; - _15 = Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> }; + _15 = std::ptr::Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> }; _3 = Box::<()>(move _15, const std::alloc::Global); - (*_13) = move _4; + (*_13) = const (); diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff index 2b77aa380a0f..88c77832a4e1 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff @@ -56,8 +56,8 @@ } bb1: { -- _5 = MinusPlus; -+ _5 = const MinusPlus; +- _5 = core::num::flt2dec::Sign::MinusPlus; ++ _5 = const core::num::flt2dec::Sign::MinusPlus; goto -> bb3; } diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff index ba6d2f3e155c..8a6e7fd35ccd 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff @@ -56,8 +56,8 @@ } bb1: { -- _5 = MinusPlus; -+ _5 = const MinusPlus; +- _5 = core::num::flt2dec::Sign::MinusPlus; ++ _5 = const core::num::flt2dec::Sign::MinusPlus; goto -> bb3; } diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff index bf6d9d864d57..ce10f4bb247a 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff @@ -56,8 +56,8 @@ } bb1: { -- _5 = MinusPlus; -+ _5 = const MinusPlus; +- _5 = core::num::flt2dec::Sign::MinusPlus; ++ _5 = const core::num::flt2dec::Sign::MinusPlus; goto -> bb3; } diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff index 01c87fd5317a..b19f2438d022 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff @@ -56,8 +56,8 @@ } bb1: { -- _5 = MinusPlus; -+ _5 = const MinusPlus; +- _5 = core::num::flt2dec::Sign::MinusPlus; ++ _5 = const core::num::flt2dec::Sign::MinusPlus; goto -> bb3; } diff --git a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff index b7872fc9952b..247ddc73ec36 100644 --- a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff @@ -210,9 +210,9 @@ _26 = &(*_27); StorageLive(_28); - _28 = Option::>::None; -- _22 = assert_failed::<*const u8, *const u8>(move _23, move _24, move _26, move _28) -> unwind unreachable; +- _22 = core::panicking::assert_failed::<*const u8, *const u8>(move _23, move _24, move _26, move _28) -> unwind unreachable; + _28 = const Option::>::None; -+ _22 = assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _24, move _26, const Option::>::None) -> unwind unreachable; ++ _22 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _24, move _26, const Option::>::None) -> unwind unreachable; } bb7: { @@ -313,9 +313,9 @@ _52 = &(*_53); StorageLive(_54); - _54 = Option::>::None; -- _48 = assert_failed::<*const u8, *const u8>(move _49, move _50, move _52, move _54) -> unwind unreachable; +- _48 = core::panicking::assert_failed::<*const u8, *const u8>(move _49, move _50, move _52, move _54) -> unwind unreachable; + _54 = const Option::>::None; -+ _48 = assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _50, move _52, const Option::>::None) -> unwind unreachable; ++ _48 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _50, move _52, const Option::>::None) -> unwind unreachable; } } diff --git a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff index 37817b48c199..f15c16f1ce0f 100644 --- a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff @@ -210,9 +210,9 @@ _26 = &(*_27); StorageLive(_28); - _28 = Option::>::None; -- _22 = assert_failed::<*const u8, *const u8>(move _23, move _24, move _26, move _28) -> unwind continue; +- _22 = core::panicking::assert_failed::<*const u8, *const u8>(move _23, move _24, move _26, move _28) -> unwind continue; + _28 = const Option::>::None; -+ _22 = assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _24, move _26, const Option::>::None) -> unwind continue; ++ _22 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _24, move _26, const Option::>::None) -> unwind continue; } bb7: { @@ -313,9 +313,9 @@ _52 = &(*_53); StorageLive(_54); - _54 = Option::>::None; -- _48 = assert_failed::<*const u8, *const u8>(move _49, move _50, move _52, move _54) -> unwind continue; +- _48 = core::panicking::assert_failed::<*const u8, *const u8>(move _49, move _50, move _52, move _54) -> unwind continue; + _54 = const Option::>::None; -+ _48 = assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _50, move _52, const Option::>::None) -> unwind continue; ++ _48 = core::panicking::assert_failed::<*const u8, *const u8>(const core::panicking::AssertKind::Eq, move _50, move _52, const Option::>::None) -> unwind continue; } } diff --git a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff index 3bbfd3a891eb..c3eb5d9092be 100644 --- a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff @@ -32,7 +32,7 @@ bb2: { StorageLive(_6); - _6 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; + _6 = std::rt::begin_panic::<&str>(const "explicit panic") -> unwind unreachable; } bb3: { diff --git a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff index 03464f43f81e..ea1878be8cf6 100644 --- a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff @@ -32,7 +32,7 @@ bb2: { StorageLive(_6); - _6 = begin_panic::<&str>(const "explicit panic") -> unwind continue; + _6 = std::rt::begin_panic::<&str>(const "explicit panic") -> unwind continue; } bb3: { diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff index 423de59e5754..66b1bc29877a 100644 --- a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-abort.diff @@ -36,7 +36,7 @@ StorageLive(_6); - _6 = panic() -> unwind unreachable; + StorageLive(_7); -+ _7 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; ++ _7 = std::rt::begin_panic::<&str>(const "explicit panic") -> unwind unreachable; } + } + diff --git a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff index 3689744dcb04..68dd9530137d 100644 --- a/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_diverging.g.Inline.panic-unwind.diff @@ -36,7 +36,7 @@ StorageLive(_6); - _6 = panic() -> unwind continue; + StorageLive(_7); -+ _7 = begin_panic::<&str>(const "explicit panic") -> unwind continue; ++ _7 = std::rt::begin_panic::<&str>(const "explicit panic") -> unwind continue; } + } + diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff index 9509739413b7..a74309e16e88 100644 --- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff @@ -20,13 +20,13 @@ + scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { + scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { + let mut _11: std::ptr::NonNull; -+ scope 7 (inlined Unique::::cast::) { ++ scope 7 (inlined std::ptr::Unique::::cast::) { + scope 8 (inlined NonNull::::cast::) { + scope 9 (inlined NonNull::::as_ptr) { + } + } + } -+ scope 10 (inlined Unique::::as_non_null_ptr) { ++ scope 10 (inlined std::ptr::Unique::::as_non_null_ptr) { + } + } + scope 11 (inlined NonNull::::as_ptr) { diff --git a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff index 3cf28f4b60af..6c9cf0cf623b 100644 --- a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff @@ -57,13 +57,13 @@ scope 11 (inlined alloc::raw_vec::RawVecInner::ptr::) { scope 12 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _34: std::ptr::NonNull; - scope 13 (inlined Unique::::cast::) { + scope 13 (inlined std::ptr::Unique::::cast::) { scope 14 (inlined NonNull::::cast::) { scope 15 (inlined NonNull::::as_ptr) { } } } - scope 16 (inlined Unique::::as_non_null_ptr) { + scope 16 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 17 (inlined NonNull::::as_ptr) { @@ -115,13 +115,13 @@ scope 34 (inlined alloc::raw_vec::RawVecInner::ptr::) { scope 35 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _46: std::ptr::NonNull; - scope 36 (inlined Unique::::cast::) { + scope 36 (inlined std::ptr::Unique::::cast::) { scope 37 (inlined NonNull::::cast::) { scope 38 (inlined NonNull::::as_ptr) { } } } - scope 39 (inlined Unique::::as_non_null_ptr) { + scope 39 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 40 (inlined NonNull::::as_ptr) { diff --git a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff index 2f0d83f92792..49cd68577a12 100644 --- a/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-unwind.diff @@ -57,13 +57,13 @@ scope 11 (inlined alloc::raw_vec::RawVecInner::ptr::) { scope 12 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _34: std::ptr::NonNull; - scope 13 (inlined Unique::::cast::) { + scope 13 (inlined std::ptr::Unique::::cast::) { scope 14 (inlined NonNull::::cast::) { scope 15 (inlined NonNull::::as_ptr) { } } } - scope 16 (inlined Unique::::as_non_null_ptr) { + scope 16 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 17 (inlined NonNull::::as_ptr) { @@ -115,13 +115,13 @@ scope 34 (inlined alloc::raw_vec::RawVecInner::ptr::) { scope 35 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _46: std::ptr::NonNull; - scope 36 (inlined Unique::::cast::) { + scope 36 (inlined std::ptr::Unique::::cast::) { scope 37 (inlined NonNull::::cast::) { scope 38 (inlined NonNull::::as_ptr) { } } } - scope 39 (inlined Unique::::as_non_null_ptr) { + scope 39 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 40 (inlined NonNull::::as_ptr) { diff --git a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-pre-optimizations.after.panic-abort.mir index 6e5f6dc9ea89..7933a36c92c2 100644 --- a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-pre-optimizations.after.panic-abort.mir +++ b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-pre-optimizations.after.panic-abort.mir @@ -24,7 +24,7 @@ fn unwrap(_1: Option) -> T { bb2: { StorageLive(_4); - _4 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; + _4 = std::rt::begin_panic::<&str>(const "explicit panic") -> unwind unreachable; } bb3: { diff --git a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-pre-optimizations.after.panic-unwind.mir index 758aa45f2a2b..04176b82ccd5 100644 --- a/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-pre-optimizations.after.panic-unwind.mir +++ b/tests/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-pre-optimizations.after.panic-unwind.mir @@ -24,7 +24,7 @@ fn unwrap(_1: Option) -> T { bb2: { StorageLive(_4); - _4 = begin_panic::<&str>(const "explicit panic") -> bb4; + _4 = std::rt::begin_panic::<&str>(const "explicit panic") -> bb4; } bb3: { diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir index 013361d1d2fb..9202814adec7 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir @@ -14,14 +14,14 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { scope 4 { scope 12 (inlined Layout::size) { } - scope 13 (inlined Unique::<[T]>::cast::) { + scope 13 (inlined std::ptr::Unique::<[T]>::cast::) { scope 14 (inlined NonNull::<[T]>::cast::) { scope 15 (inlined NonNull::<[T]>::as_ptr) { } } } - scope 16 (inlined as From>>::from) { - scope 17 (inlined Unique::::as_non_null_ptr) { + scope 16 (inlined as From>>::from) { + scope 17 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 18 (inlined ::deallocate) { @@ -45,7 +45,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } } - scope 5 (inlined Unique::<[T]>::as_ptr) { + scope 5 (inlined std::ptr::Unique::<[T]>::as_ptr) { scope 6 (inlined NonNull::<[T]>::as_ptr) { } } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir index 013361d1d2fb..9202814adec7 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir @@ -14,14 +14,14 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { scope 4 { scope 12 (inlined Layout::size) { } - scope 13 (inlined Unique::<[T]>::cast::) { + scope 13 (inlined std::ptr::Unique::<[T]>::cast::) { scope 14 (inlined NonNull::<[T]>::cast::) { scope 15 (inlined NonNull::<[T]>::as_ptr) { } } } - scope 16 (inlined as From>>::from) { - scope 17 (inlined Unique::::as_non_null_ptr) { + scope 16 (inlined as From>>::from) { + scope 17 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 18 (inlined ::deallocate) { @@ -45,7 +45,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } } - scope 5 (inlined Unique::<[T]>::as_ptr) { + scope 5 (inlined std::ptr::Unique::<[T]>::as_ptr) { scope 6 (inlined NonNull::<[T]>::as_ptr) { } } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir index 013361d1d2fb..9202814adec7 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir @@ -14,14 +14,14 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { scope 4 { scope 12 (inlined Layout::size) { } - scope 13 (inlined Unique::<[T]>::cast::) { + scope 13 (inlined std::ptr::Unique::<[T]>::cast::) { scope 14 (inlined NonNull::<[T]>::cast::) { scope 15 (inlined NonNull::<[T]>::as_ptr) { } } } - scope 16 (inlined as From>>::from) { - scope 17 (inlined Unique::::as_non_null_ptr) { + scope 16 (inlined as From>>::from) { + scope 17 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 18 (inlined ::deallocate) { @@ -45,7 +45,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } } - scope 5 (inlined Unique::<[T]>::as_ptr) { + scope 5 (inlined std::ptr::Unique::<[T]>::as_ptr) { scope 6 (inlined NonNull::<[T]>::as_ptr) { } } diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir index 013361d1d2fb..9202814adec7 100644 --- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir @@ -14,14 +14,14 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { scope 4 { scope 12 (inlined Layout::size) { } - scope 13 (inlined Unique::<[T]>::cast::) { + scope 13 (inlined std::ptr::Unique::<[T]>::cast::) { scope 14 (inlined NonNull::<[T]>::cast::) { scope 15 (inlined NonNull::<[T]>::as_ptr) { } } } - scope 16 (inlined as From>>::from) { - scope 17 (inlined Unique::::as_non_null_ptr) { + scope 16 (inlined as From>>::from) { + scope 17 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 18 (inlined ::deallocate) { @@ -45,7 +45,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () { } } } - scope 5 (inlined Unique::<[T]>::as_ptr) { + scope 5 (inlined std::ptr::Unique::<[T]>::as_ptr) { scope 6 (inlined NonNull::<[T]>::as_ptr) { } } diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir index 6ab4b7712306..c8b9ff1dbed9 100644 --- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir @@ -139,14 +139,14 @@ fn vec_move(_1: Vec) -> () { debug self => _31; scope 23 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _5: std::ptr::NonNull; - scope 24 (inlined Unique::::cast::) { + scope 24 (inlined std::ptr::Unique::::cast::) { scope 25 (inlined NonNull::::cast::) { let mut _6: *const impl Sized; scope 26 (inlined NonNull::::as_ptr) { } } } - scope 27 (inlined Unique::::as_non_null_ptr) { + scope 27 (inlined std::ptr::Unique::::as_non_null_ptr) { } } } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir index 8308ecbad716..730aedf4f1a3 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir @@ -16,13 +16,13 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _2: std::ptr::NonNull; - scope 7 (inlined Unique::::cast::) { + scope 7 (inlined std::ptr::Unique::::cast::) { scope 8 (inlined NonNull::::cast::) { scope 9 (inlined NonNull::::as_ptr) { } } } - scope 10 (inlined Unique::::as_non_null_ptr) { + scope 10 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 11 (inlined NonNull::::as_ptr) { diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir index 8308ecbad716..730aedf4f1a3 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir @@ -16,13 +16,13 @@ fn vec_deref_to_slice(_1: &Vec) -> &[u8] { scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::) { scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::) { let mut _2: std::ptr::NonNull; - scope 7 (inlined Unique::::cast::) { + scope 7 (inlined std::ptr::Unique::::cast::) { scope 8 (inlined NonNull::::cast::) { scope 9 (inlined NonNull::::as_ptr) { } } } - scope 10 (inlined Unique::::as_non_null_ptr) { + scope 10 (inlined std::ptr::Unique::::as_non_null_ptr) { } } scope 11 (inlined NonNull::::as_ptr) { diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index 7012cc5aa7f6..f9965a529ebc 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -152,7 +152,7 @@ StorageDead(_22); StorageDead(_21); StorageDead(_20); - _10 = _eprint(move _11) -> [return: bb6, unwind unreachable]; + _10 = std::io::_eprint(move _11) -> [return: bb6, unwind unreachable]; } bb6: { diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr index a507fa697604..e140e9b94b30 100644 --- a/tests/ui/async-await/async-closures/def-path.stderr +++ b/tests/ui/async-await/async-closures/def-path.stderr @@ -5,11 +5,11 @@ LL | let x = async || {}; | -- the expected `async` closure body LL | LL | let () = x(); - | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}` + | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=std::future::ResumeTy yield_ty=() return_ty=()}` | | | expected `async` closure body, found `()` | - = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}` + = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=std::future::ResumeTy yield_ty=() return_ty=()}` found unit type `()` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index af29eaa35cb6..aecd97ef7763 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -99,7 +99,7 @@ LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ^^ unsatisfied trait bound introduced in this `derive` macro = note: 1 redundant requirement hidden = note: required for `&'static Bar` to implement `Eq` -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time diff --git a/tests/ui/consts/const-eval/format.rs b/tests/ui/consts/const-eval/format.rs index a8085a786e18..f25c7018f826 100644 --- a/tests/ui/consts/const-eval/format.rs +++ b/tests/ui/consts/const-eval/format.rs @@ -6,7 +6,7 @@ const fn failure() { const fn print() { println!("{:?}", 0); //~^ ERROR cannot call non-const formatting macro in constant functions - //~| ERROR cannot call non-const function `_print` in constant functions + //~| ERROR cannot call non-const function `std::io::_print` in constant functions } const fn format_args() { diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index ea191eb5c098..06bada8da011 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -15,7 +15,7 @@ LL | println!("{:?}", 0); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0015]: cannot call non-const function `_print` in constant functions +error[E0015]: cannot call non-const function `std::io::_print` in constant functions --> $DIR/format.rs:7:5 | LL | println!("{:?}", 0); diff --git a/tests/ui/contracts/contract-captures-via-closure-noncopy.rs b/tests/ui/contracts/contract-captures-via-closure-noncopy.rs index c7aa72d2b0f6..5153a7b48dcd 100644 --- a/tests/ui/contracts/contract-captures-via-closure-noncopy.rs +++ b/tests/ui/contracts/contract-captures-via-closure-noncopy.rs @@ -13,7 +13,7 @@ struct Baz { #[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz*2 })] // Relevant thing is this: ^^^^^^^^^^^ // because we are capturing state that is non-Copy. -//~^^^ ERROR trait bound `Baz: std::marker::Copy` is not satisfied +//~^^^ ERROR trait bound `Baz: Copy` is not satisfied fn doubler(x: Baz) -> Baz { Baz { baz: x.baz + 10 } } diff --git a/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr index 5f55faed80c8..20c220e98bcc 100644 --- a/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr +++ b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Baz: std::marker::Copy` is not satisfied in `{closure@$DIR/contract-captures-via-closure-noncopy.rs:13:42: 13:57}` +error[E0277]: the trait bound `Baz: Copy` is not satisfied in `{closure@$DIR/contract-captures-via-closure-noncopy.rs:13:42: 13:57}` --> $DIR/contract-captures-via-closure-noncopy.rs:13:1 | LL | #[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz*2 })] @@ -9,7 +9,7 @@ LL | #[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz | unsatisfied trait bound | required by a bound introduced by this call | - = help: within `{closure@$DIR/contract-captures-via-closure-noncopy.rs:13:42: 13:57}`, the trait `std::marker::Copy` is not implemented for `Baz` + = help: within `{closure@$DIR/contract-captures-via-closure-noncopy.rs:13:42: 13:57}`, the trait `Copy` is not implemented for `Baz` note: required because it's used within this closure --> $DIR/contract-captures-via-closure-noncopy.rs:13:42 | diff --git a/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr b/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr index e0cb3c1b43da..42dc8d46b575 100644 --- a/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr @@ -7,7 +7,7 @@ LL | #[derive(Eq,PartialEq)] LL | x: Error | ^^^^^^^^ the trait `Eq` is not implemented for `Error` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `Error` with `#[derive(Eq)]` | diff --git a/tests/ui/derives/derives-span-Eq-enum.stderr b/tests/ui/derives/derives-span-Eq-enum.stderr index 2f09b9ea385f..ef1d9e3242ad 100644 --- a/tests/ui/derives/derives-span-Eq-enum.stderr +++ b/tests/ui/derives/derives-span-Eq-enum.stderr @@ -7,7 +7,7 @@ LL | #[derive(Eq,PartialEq)] LL | Error | ^^^^^ the trait `Eq` is not implemented for `Error` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `Error` with `#[derive(Eq)]` | diff --git a/tests/ui/derives/derives-span-Eq-struct.stderr b/tests/ui/derives/derives-span-Eq-struct.stderr index c16d9118e10f..bae7bb0361df 100644 --- a/tests/ui/derives/derives-span-Eq-struct.stderr +++ b/tests/ui/derives/derives-span-Eq-struct.stderr @@ -7,7 +7,7 @@ LL | struct Struct { LL | x: Error | ^^^^^^^^ the trait `Eq` is not implemented for `Error` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `Error` with `#[derive(Eq)]` | diff --git a/tests/ui/derives/derives-span-Eq-tuple-struct.stderr b/tests/ui/derives/derives-span-Eq-tuple-struct.stderr index dac295eed919..13396cb27246 100644 --- a/tests/ui/derives/derives-span-Eq-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-Eq-tuple-struct.stderr @@ -7,7 +7,7 @@ LL | struct Struct( LL | Error | ^^^^^ the trait `Eq` is not implemented for `Error` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `Error` with `#[derive(Eq)]` | diff --git a/tests/ui/deriving/issue-103157.stderr b/tests/ui/deriving/issue-103157.stderr index 51d4d0a89745..0e4a3f75db3f 100644 --- a/tests/ui/deriving/issue-103157.stderr +++ b/tests/ui/deriving/issue-103157.stderr @@ -18,7 +18,7 @@ LL | Float(Option), u16 and 4 others = note: required for `Option` to implement `Eq` -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-27340.stderr b/tests/ui/issues/issue-27340.stderr index d5ff29a618b0..7cde901ffd95 100644 --- a/tests/ui/issues/issue-27340.stderr +++ b/tests/ui/issues/issue-27340.stderr @@ -16,7 +16,7 @@ LL | LL | struct Bar(Foo); | ^^^ the trait `Clone` is not implemented for `Foo` | -note: required by a bound in `AssertParamIsClone` +note: required by a bound in `std::clone::AssertParamIsClone` --> $SRC_DIR/core/src/clone.rs:LL:COL help: consider annotating `Foo` with `#[derive(Clone)]` | diff --git a/tests/ui/kindck/kindck-send-object.stderr b/tests/ui/kindck/kindck-send-object.stderr index 0e2ff1730c8d..b71d4029350e 100644 --- a/tests/ui/kindck/kindck-send-object.stderr +++ b/tests/ui/kindck/kindck-send-object.stderr @@ -19,7 +19,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` - = note: required for `Unique` to implement `Send` + = note: required for `std::ptr::Unique` to implement `Send` note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr index e3ff2eb9ff4c..2184ae704673 100644 --- a/tests/ui/kindck/kindck-send-object1.stderr +++ b/tests/ui/kindck/kindck-send-object1.stderr @@ -19,7 +19,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` - = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send` + = note: required for `std::ptr::Unique<(dyn Dummy + 'a)>` to implement `Send` note: required because it appears within the type `Box<(dyn Dummy + 'a)>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` diff --git a/tests/ui/kindck/kindck-send-object2.stderr b/tests/ui/kindck/kindck-send-object2.stderr index 8898bf5b3fab..52a7055b4229 100644 --- a/tests/ui/kindck/kindck-send-object2.stderr +++ b/tests/ui/kindck/kindck-send-object2.stderr @@ -19,7 +19,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` - = note: required for `Unique` to implement `Send` + = note: required for `std::ptr::Unique` to implement `Send` note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` diff --git a/tests/ui/kindck/kindck-send-owned.stderr b/tests/ui/kindck/kindck-send-owned.stderr index 860a9391bbb0..c433d80cf140 100644 --- a/tests/ui/kindck/kindck-send-owned.stderr +++ b/tests/ui/kindck/kindck-send-owned.stderr @@ -5,7 +5,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `*mut u8` - = note: required for `Unique<*mut u8>` to implement `Send` + = note: required for `std::ptr::Unique<*mut u8>` to implement `Send` note: required because it appears within the type `Box<*mut u8>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` diff --git a/tests/ui/limits/type-length-limit-enforcement.stderr b/tests/ui/limits/type-length-limit-enforcement.stderr index bfea0b5a4482..82855bd75528 100644 --- a/tests/ui/limits/type-length-limit-enforcement.stderr +++ b/tests/ui/limits/type-length-limit-enforcement.stderr @@ -8,9 +8,11 @@ LL | drop::>(None); = note: the full name for the type has been written to '$TEST_BUILD_DIR/type-length-limit-enforcement.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console -error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` +error: reached the type-length limit while instantiating `<{closure@...} as FnMut<()>>::call_mut` | = help: consider adding a `#![type_length_limit="10"]` attribute to your crate + = note: the full name for the type has been written to '$TEST_BUILD_DIR/type-length-limit-enforcement.long-type-$LONG_TYPE_HASH.txt' + = note: consider using `--verbose` to print the full type name to the console error: aborting due to 2 previous errors diff --git a/tests/ui/proc-macro/bad-projection.stderr b/tests/ui/proc-macro/bad-projection.stderr index f2981499367b..5b472d407044 100644 --- a/tests/ui/proc-macro/bad-projection.stderr +++ b/tests/ui/proc-macro/bad-projection.stderr @@ -33,7 +33,7 @@ LL | pub fn uwu() -> <() as Project>::Assoc {} | takes 0 arguments | required by a bound introduced by this call | -note: required by a bound in `ProcMacro::bang` +note: required by a bound in `proc_macro::bridge::client::ProcMacro::bang` --> $SRC_DIR/proc_macro/src/bridge/client.rs:LL:COL error[E0277]: the trait bound `(): Project` is not satisfied diff --git a/tests/ui/proc-macro/proc-macro-abi.stderr b/tests/ui/proc-macro/proc-macro-abi.stderr index ccc72e5187ed..ccefdbfa3a86 100644 --- a/tests/ui/proc-macro/proc-macro-abi.stderr +++ b/tests/ui/proc-macro/proc-macro-abi.stderr @@ -4,8 +4,8 @@ error: function-like proc macro has incorrect signature LL | pub extern "C" fn abi(a: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "C" fn | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `extern "C" fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `extern "C" fn(TokenStream) -> TokenStream` error: function-like proc macro has incorrect signature --> $DIR/proc-macro-abi.rs:17:1 @@ -13,8 +13,8 @@ error: function-like proc macro has incorrect signature LL | pub extern "system" fn abi2(a: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "system" fn | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `extern "system" fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `extern "system" fn(TokenStream) -> TokenStream` error: function-like proc macro has incorrect signature --> $DIR/proc-macro-abi.rs:23:1 @@ -22,8 +22,8 @@ error: function-like proc macro has incorrect signature LL | pub extern fn abi3(a: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "C" fn | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `extern "C" fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `extern "C" fn(TokenStream) -> TokenStream` error: aborting due to 3 previous errors diff --git a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr index 0bcea9b85f47..86a00713a456 100644 --- a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr +++ b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr @@ -5,7 +5,7 @@ LL | quote!($($nonrep $nonrep)*); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` + | here the type of `has_iter` is inferred to be `proc_macro::ThereIsNoIteratorInRepetition` error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr index d945ab41a12e..325e50f9796a 100644 --- a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr +++ b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr @@ -5,7 +5,7 @@ LL | quote!($($nonrep)*); | ^^^^^^^^^^^^^^^^^^^ | | | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` + | here the type of `has_iter` is inferred to be `proc_macro::ThereIsNoIteratorInRepetition` error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/quote/not-quotable.stderr b/tests/ui/proc-macro/quote/not-quotable.stderr index b00d029946d6..4177d9c672b5 100644 --- a/tests/ui/proc-macro/quote/not-quotable.stderr +++ b/tests/ui/proc-macro/quote/not-quotable.stderr @@ -11,11 +11,11 @@ LL | let _ = quote! { $ip }; &T &mut T Box + CStr CString Cow<'_, T> Option Rc - bool and 24 others error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr index ce832eaa5c7a..9dfb081a10e6 100644 --- a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr @@ -4,8 +4,8 @@ error: attribute proc macro has incorrect signature LL | pub fn bad_input(input: String) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream, TokenStream) -> TokenStream` + found signature `fn(String) -> TokenStream` error: attribute proc macro has incorrect signature --> $DIR/signature-proc-macro-attribute.rs:16:1 @@ -13,8 +13,8 @@ error: attribute proc macro has incorrect signature LL | pub fn bad_output(input: TokenStream) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream) -> std::string::String` + = note: expected signature `fn(TokenStream, TokenStream) -> TokenStream` + found signature `fn(TokenStream) -> String` error: attribute proc macro has incorrect signature --> $DIR/signature-proc-macro-attribute.rs:22:1 @@ -22,8 +22,8 @@ error: attribute proc macro has incorrect signature LL | pub fn bad_everything(input: String) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> std::string::String` + = note: expected signature `fn(TokenStream, TokenStream) -> TokenStream` + found signature `fn(String) -> String` error: attribute proc macro has incorrect signature --> $DIR/signature-proc-macro-attribute.rs:28:52 @@ -31,8 +31,8 @@ error: attribute proc macro has incorrect signature LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { | ^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream, TokenStream) -> TokenStream` + found signature `fn(TokenStream, TokenStream, String) -> TokenStream` error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/signature-proc-macro-derive.stderr b/tests/ui/proc-macro/signature-proc-macro-derive.stderr index 03c6abad17d9..3539ae7c2e17 100644 --- a/tests/ui/proc-macro/signature-proc-macro-derive.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-derive.stderr @@ -2,28 +2,28 @@ error: derive proc macro has incorrect signature --> $DIR/signature-proc-macro-derive.rs:10:25 | LL | pub fn bad_input(input: String) -> TokenStream { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(String) -> TokenStream` error: derive proc macro has incorrect signature --> $DIR/signature-proc-macro-derive.rs:16:42 | LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream) -> std::string::String` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(TokenStream) -> String` error: derive proc macro has incorrect signature --> $DIR/signature-proc-macro-derive.rs:22:30 | LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> std::string::String` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(String) -> String` error: derive proc macro has incorrect signature --> $DIR/signature-proc-macro-derive.rs:28:36 @@ -31,8 +31,8 @@ error: derive proc macro has incorrect signature LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { | ^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(TokenStream, TokenStream, String) -> TokenStream` error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/signature-proc-macro.stderr b/tests/ui/proc-macro/signature-proc-macro.stderr index dd2cb0570daa..1959d8c6d615 100644 --- a/tests/ui/proc-macro/signature-proc-macro.stderr +++ b/tests/ui/proc-macro/signature-proc-macro.stderr @@ -2,28 +2,28 @@ error: function-like proc macro has incorrect signature --> $DIR/signature-proc-macro.rs:10:25 | LL | pub fn bad_input(input: String) -> TokenStream { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(String) -> TokenStream` error: function-like proc macro has incorrect signature --> $DIR/signature-proc-macro.rs:16:42 | LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream) -> std::string::String` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(TokenStream) -> String` error: function-like proc macro has incorrect signature --> $DIR/signature-proc-macro.rs:22:30 | LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> std::string::String` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(String) -> String` error: function-like proc macro has incorrect signature --> $DIR/signature-proc-macro.rs:28:36 @@ -31,8 +31,8 @@ error: function-like proc macro has incorrect signature LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { | ^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(TokenStream, TokenStream, String) -> TokenStream` error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/signature.stderr b/tests/ui/proc-macro/signature.stderr index fd679442b6af..2c1973eb6e6d 100644 --- a/tests/ui/proc-macro/signature.stderr +++ b/tests/ui/proc-macro/signature.stderr @@ -4,7 +4,7 @@ error: derive proc macro has incorrect signature LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected safe fn, found unsafe fn | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` found signature `unsafe extern "C" fn(i32, u32) -> u32` error: aborting due to 1 previous error diff --git a/tests/ui/static/global-variable-promotion-error-7364.stderr b/tests/ui/static/global-variable-promotion-error-7364.stderr index b9d75676bef8..9f0026621c13 100644 --- a/tests/ui/static/global-variable-promotion-error-7364.stderr +++ b/tests/ui/static/global-variable-promotion-error-7364.stderr @@ -6,7 +6,7 @@ LL | static boxed: Box> = Box::new(RefCell::new(0)); | = help: the trait `Sync` is not implemented for `RefCell` = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead - = note: required for `Unique>` to implement `Sync` + = note: required for `std::ptr::Unique>` to implement `Sync` note: required because it appears within the type `Box>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL = note: shared static variables must have a type that implements `Sync` diff --git a/tests/ui/traits/const-traits/issue-79450.rs b/tests/ui/traits/const-traits/issue-79450.rs index e74da811fc80..c6234f8616d7 100644 --- a/tests/ui/traits/const-traits/issue-79450.rs +++ b/tests/ui/traits/const-traits/issue-79450.rs @@ -5,7 +5,7 @@ const trait Tr { fn req(&self); fn prov(&self) { - println!("lul"); //~ ERROR: cannot call non-const function `_print` in constant functions + println!("lul"); //~ ERROR: cannot call non-const function `std::io::_print` in constant functions self.req(); } } diff --git a/tests/ui/traits/const-traits/issue-79450.stderr b/tests/ui/traits/const-traits/issue-79450.stderr index c10023e9f0ef..702e93a76a8f 100644 --- a/tests/ui/traits/const-traits/issue-79450.stderr +++ b/tests/ui/traits/const-traits/issue-79450.stderr @@ -1,4 +1,4 @@ -error[E0015]: cannot call non-const function `_print` in constant functions +error[E0015]: cannot call non-const function `std::io::_print` in constant functions --> $DIR/issue-79450.rs:8:9 | LL | println!("lul"); diff --git a/tests/ui/traits/cycle-cache-err-60010.stderr b/tests/ui/traits/cycle-cache-err-60010.stderr index 4f5e31818321..9665d5badf59 100644 --- a/tests/ui/traits/cycle-cache-err-60010.stderr +++ b/tests/ui/traits/cycle-cache-err-60010.stderr @@ -6,7 +6,7 @@ LL | _parse: >::Data, | note: required because it appears within the type `PhantomData` --> $SRC_DIR/core/src/marker.rs:LL:COL -note: required because it appears within the type `Unique` +note: required because it appears within the type `std::ptr::Unique` --> $SRC_DIR/core/src/ptr/unique.rs:LL:COL note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL @@ -45,7 +45,7 @@ LL | type Storage = SalsaStorage; | note: required because it appears within the type `PhantomData` --> $SRC_DIR/core/src/marker.rs:LL:COL -note: required because it appears within the type `Unique` +note: required because it appears within the type `std::ptr::Unique` --> $SRC_DIR/core/src/ptr/unique.rs:LL:COL note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr index f450f786f608..b7d8484e1041 100644 --- a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -77,12 +77,12 @@ error[E0277]: `dummy2::TestType` cannot be sent between threads safely --> $DIR/negated-auto-traits-error.rs:48:13 | LL | is_send(Box::new(TestType)); - | ------- ^^^^^^^^^^^^^^^^^^ the trait `Send` is not implemented for `Unique` + | ------- ^^^^^^^^^^^^^^^^^^ the trait `Send` is not implemented for `std::ptr::Unique` | | | required by a bound introduced by this call | - = note: the trait bound `Unique: Send` is not satisfied - = note: required for `Unique` to implement `Send` + = note: the trait bound `std::ptr::Unique: Send` is not satisfied + = note: required for `std::ptr::Unique` to implement `Send` note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `is_send` @@ -113,7 +113,7 @@ note: required because it appears within the type `Outer2` | LL | struct Outer2(T); | ^^^^^^ - = note: required for `Unique>` to implement `Send` + = note: required for `std::ptr::Unique>` to implement `Send` note: required because it appears within the type `Box>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `is_send` diff --git a/tests/ui/trimmed-paths/core-unicode.rs b/tests/ui/trimmed-paths/core-unicode.rs index 54bde92a5335..4a3eeca62970 100644 --- a/tests/ui/trimmed-paths/core-unicode.rs +++ b/tests/ui/trimmed-paths/core-unicode.rs @@ -14,6 +14,6 @@ fn main() { let PhantomData::<(inner::unicode, u32)> = PhantomData::<(u32, inner::unicode)>; //~^ ERROR mismatched types [E0308] //~| NOTE expected `PhantomData<(u32, unicode)>`, found `PhantomData<(unicode, u32)>` - //~| NOTE this expression has type `PhantomData<(u32, inner::unicode)>` - //~| NOTE expected struct `PhantomData<(u32, inner::unicode)>` + //~| NOTE this expression has type `PhantomData<(u32, unicode)>` + //~| NOTE expected struct `PhantomData<(u32, unicode)>` } diff --git a/tests/ui/trimmed-paths/core-unicode.stderr b/tests/ui/trimmed-paths/core-unicode.stderr index 9023200d1c92..7351896b0b54 100644 --- a/tests/ui/trimmed-paths/core-unicode.stderr +++ b/tests/ui/trimmed-paths/core-unicode.stderr @@ -2,12 +2,12 @@ error[E0308]: mismatched types --> $DIR/core-unicode.rs:14:9 | LL | let PhantomData::<(inner::unicode, u32)> = PhantomData::<(u32, inner::unicode)>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------------------------ this expression has type `PhantomData<(u32, inner::unicode)>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------------------------ this expression has type `PhantomData<(u32, unicode)>` | | | expected `PhantomData<(u32, unicode)>`, found `PhantomData<(unicode, u32)>` | - = note: expected struct `PhantomData<(u32, inner::unicode)>` - found struct `PhantomData<(inner::unicode, u32)>` + = note: expected struct `PhantomData<(u32, unicode)>` + found struct `PhantomData<(unicode, u32)>` error: aborting due to 1 previous error diff --git a/tests/ui/trimmed-paths/doc-hidden.rs b/tests/ui/trimmed-paths/doc-hidden.rs index b73d04c3c6ae..c3125385c7e4 100644 --- a/tests/ui/trimmed-paths/doc-hidden.rs +++ b/tests/ui/trimmed-paths/doc-hidden.rs @@ -45,7 +45,7 @@ fn uses_local() { ) = 3u32; //~^ ERROR mismatched types [E0308] //~| NOTE expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` - //~| NOTE expected tuple `(local::ActuallyPub, local::DocHidden, local::pub_mod::ActuallyPubInPubMod, local::pub_mod::DocHiddenInPubMod, local::hidden_mod::ActuallyPubInHiddenMod, local::hidden_mod::DocHiddenInHiddenMod)` + //~| NOTE expected tuple `(local::ActuallyPub, DocHidden, local::pub_mod::ActuallyPubInPubMod, DocHiddenInPubMod, ActuallyPubInHiddenMod, DocHiddenInHiddenMod)` } fn uses_helper() { diff --git a/tests/ui/trimmed-paths/doc-hidden.stderr b/tests/ui/trimmed-paths/doc-hidden.stderr index 6f6f8f21fbe0..167c92c50a35 100644 --- a/tests/ui/trimmed-paths/doc-hidden.stderr +++ b/tests/ui/trimmed-paths/doc-hidden.stderr @@ -13,7 +13,7 @@ LL | | ) = 3u32; | |_____| | expected due to this | - = note: expected tuple `(local::ActuallyPub, local::DocHidden, local::pub_mod::ActuallyPubInPubMod, local::pub_mod::DocHiddenInPubMod, local::hidden_mod::ActuallyPubInHiddenMod, local::hidden_mod::DocHiddenInHiddenMod)` + = note: expected tuple `(local::ActuallyPub, DocHidden, local::pub_mod::ActuallyPubInPubMod, DocHiddenInPubMod, ActuallyPubInHiddenMod, DocHiddenInHiddenMod)` found type `u32` error[E0308]: mismatched types diff --git a/tests/ui/type-inference/panic-with-unspecified-type.stderr b/tests/ui/type-inference/panic-with-unspecified-type.stderr index 5f08a7552632..cd8485f392bc 100644 --- a/tests/ui/type-inference/panic-with-unspecified-type.stderr +++ b/tests/ui/type-inference/panic-with-unspecified-type.stderr @@ -8,7 +8,7 @@ LL | panic!(std::default::Default::default()); | required by a bound introduced by this call | = note: cannot satisfy `_: Any` -note: required by a bound in `begin_panic` +note: required by a bound in `std::rt::begin_panic` --> $SRC_DIR/std/src/panicking.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/type/pattern_types/derives_fail.stderr b/tests/ui/type/pattern_types/derives_fail.stderr index 6b2e27494f0e..45c9bae1f280 100644 --- a/tests/ui/type/pattern_types/derives_fail.stderr +++ b/tests/ui/type/pattern_types/derives_fail.stderr @@ -16,7 +16,7 @@ LL | #[repr(transparent)] LL | struct Nanoseconds(NanoI32); | ^^^^^^^ the trait `Eq` is not implemented for `(i32) is 0..=999999999` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL error[E0277]: `(i32) is 0..=999999999` doesn't implement `Debug` diff --git a/tests/ui/union/union-derive-clone.stderr b/tests/ui/union/union-derive-clone.stderr index 679ab6a38e49..18f862aaa7d6 100644 --- a/tests/ui/union/union-derive-clone.stderr +++ b/tests/ui/union/union-derive-clone.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `U1: Copy` is not satisfied LL | #[derive(Clone)] | ^^^^^ the trait `Copy` is not implemented for `U1` | -note: required by a bound in `AssertParamIsCopy` +note: required by a bound in `std::clone::AssertParamIsCopy` --> $SRC_DIR/core/src/clone.rs:LL:COL help: consider annotating `U1` with `#[derive(Copy)]` | diff --git a/tests/ui/union/union-derive-eq.current.stderr b/tests/ui/union/union-derive-eq.current.stderr index a0339687dad4..df8e6db887bc 100644 --- a/tests/ui/union/union-derive-eq.current.stderr +++ b/tests/ui/union/union-derive-eq.current.stderr @@ -7,7 +7,7 @@ LL | union U2 { LL | a: PartialEqNotEq, | ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `PartialEqNotEq` with `#[derive(Eq)]` | diff --git a/tests/ui/union/union-derive-eq.next.stderr b/tests/ui/union/union-derive-eq.next.stderr index a0339687dad4..df8e6db887bc 100644 --- a/tests/ui/union/union-derive-eq.next.stderr +++ b/tests/ui/union/union-derive-eq.next.stderr @@ -7,7 +7,7 @@ LL | union U2 { LL | a: PartialEqNotEq, | ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `PartialEqNotEq` with `#[derive(Eq)]` | From 40691d0ca6a20bae367533fb2b58320251b4ad17 Mon Sep 17 00:00:00 2001 From: tiif Date: Mon, 19 Jan 2026 01:46:08 +0000 Subject: [PATCH 2315/3801] Add myself to the review rotation --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index e51622f1e5a9..a25c2a0a388c 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1465,6 +1465,7 @@ compiler = [ "@oli-obk", "@petrochenkov", "@SparrowLii", + "@tiif", "@WaffleLapkin", "@wesleywiser", ] From 37135122179974e9073f4a885b70044cedfa3f80 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Sat, 17 Jan 2026 22:53:08 +0800 Subject: [PATCH 2316/3801] Parse ident with allowing recovery when trying to recover in diagnosing --- .../rustc_parse/src/parser/diagnostics.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 3 +- compiler/rustc_parse/src/parser/mod.rs | 2 +- .../kw-in-const-item-pos-recovery-149692.rs | 3 +- ...w-in-const-item-pos-recovery-149692.stderr | 19 ++++++-- .../macro/kw-in-item-pos-recovery-149692.rs | 9 ++-- .../kw-in-item-pos-recovery-149692.stderr | 48 +++++++++++++++---- .../macro/kw-in-item-pos-recovery-151238.rs | 13 +++++ .../kw-in-item-pos-recovery-151238.stderr | 25 ++++++++++ 9 files changed, 102 insertions(+), 22 deletions(-) create mode 100644 tests/ui/parser/macro/kw-in-item-pos-recovery-151238.rs create mode 100644 tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 2fd1d146b1f6..60e12fa05adf 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2264,7 +2264,7 @@ impl<'a> Parser<'a> { && self.look_ahead(1, |t| *t == token::Comma || *t == token::CloseParen) { // `fn foo(String s) {}` - let ident = self.parse_ident().unwrap(); + let ident = self.parse_ident_common(true).unwrap(); let span = pat.span.with_hi(ident.span.hi()); err.span_suggestion( diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index bc76418429aa..c7d09b834540 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -408,12 +408,11 @@ impl<'a> Parser<'a> { let insert_span = ident_span.shrink_to_lo(); let ident = if self.token.is_ident() - && self.token.is_non_reserved_ident() && (!is_const || self.look_ahead(1, |t| *t == token::OpenParen)) && self.look_ahead(1, |t| { matches!(t.kind, token::Lt | token::OpenBrace | token::OpenParen) }) { - self.parse_ident().unwrap() + self.parse_ident_common(true).unwrap() } else { return Ok(()); }; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index d6e99bc540f7..c39e8351f0bd 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -469,7 +469,7 @@ impl<'a> Parser<'a> { self.parse_ident_common(self.may_recover()) } - fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> { + pub(crate) fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> { let (ident, is_raw) = self.ident_or_err(recover)?; if is_raw == IdentIsRaw::No && ident.is_reserved() { diff --git a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs index 58bb62bc4bf8..8619856cad67 100644 --- a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs +++ b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs @@ -6,6 +6,7 @@ macro_rules! m { } m!(const Self()); -//~^ ERROR expected one of `!` or `::`, found `(` +//~^ ERROR expected identifier, found keyword `Self` +//~^^ ERROR missing `fn` or `struct` for function or struct definition fn main() {} diff --git a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr index f9b73109dbb4..d412c59c4372 100644 --- a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr +++ b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr @@ -1,11 +1,22 @@ -error: expected one of `!` or `::`, found `(` - --> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:14 +error: expected identifier, found keyword `Self` + --> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:10 + | +LL | m!(const Self()); + | ^^^^ expected identifier, found keyword + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:10 | LL | (const $id:item()) => {} | -------- while parsing argument for this `item` macro fragment ... LL | m!(const Self()); - | ^ expected one of `!` or `::` + | ^^^^ + | +help: if you meant to call a macro, try + | +LL | m!(const Self!()); + | + -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs index 223864e33296..77372ced09c4 100644 --- a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs @@ -8,12 +8,15 @@ macro_rules! m { } m!(Self()); -//~^ ERROR expected one of `!` or `::`, found `(` +//~^ ERROR expected identifier, found keyword `Self` +//~^^ ERROR missing `fn` or `struct` for function or struct definition m!(Self{}); -//~^ ERROR expected one of `!` or `::`, found `{` +//~^ ERROR expected identifier, found keyword `Self` +//~^^ ERROR missing `enum` or `struct` for enum or struct definition m!(crate()); -//~^ ERROR expected one of `!` or `::`, found `(` +//~^ ERROR expected identifier, found keyword `crate` +//~^^ ERROR missing `fn` or `struct` for function or struct definition fn main() {} diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr index a65214b0d1f9..39f3e2d3a9ea 100644 --- a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr @@ -1,29 +1,57 @@ -error: expected one of `!` or `::`, found `(` - --> $DIR/kw-in-item-pos-recovery-149692.rs:10:8 +error: expected identifier, found keyword `Self` + --> $DIR/kw-in-item-pos-recovery-149692.rs:10:4 + | +LL | m!(Self()); + | ^^^^ expected identifier, found keyword + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/kw-in-item-pos-recovery-149692.rs:10:4 | LL | ($id:item()) => {} | -------- while parsing argument for this `item` macro fragment ... LL | m!(Self()); - | ^ expected one of `!` or `::` + | ^^^^ + | +help: if you meant to call a macro, try + | +LL | m!(Self!()); + | + -error: expected one of `!` or `::`, found `{` - --> $DIR/kw-in-item-pos-recovery-149692.rs:13:8 +error: expected identifier, found keyword `Self` + --> $DIR/kw-in-item-pos-recovery-149692.rs:14:4 + | +LL | m!(Self{}); + | ^^^^ expected identifier, found keyword + +error: missing `enum` or `struct` for enum or struct definition + --> $DIR/kw-in-item-pos-recovery-149692.rs:14:4 | LL | ($id:item()) => {} | -------- while parsing argument for this `item` macro fragment ... LL | m!(Self{}); - | ^ expected one of `!` or `::` + | ^^^^ -error: expected one of `!` or `::`, found `(` - --> $DIR/kw-in-item-pos-recovery-149692.rs:16:9 +error: expected identifier, found keyword `crate` + --> $DIR/kw-in-item-pos-recovery-149692.rs:18:4 + | +LL | m!(crate()); + | ^^^^^ expected identifier, found keyword + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/kw-in-item-pos-recovery-149692.rs:18:4 | LL | ($id:item()) => {} | -------- while parsing argument for this `item` macro fragment ... LL | m!(crate()); - | ^ expected one of `!` or `::` + | ^^^^^ + | +help: if you meant to call a macro, try + | +LL | m!(crate!()); + | + -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.rs b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.rs new file mode 100644 index 000000000000..bd1785ba5b3c --- /dev/null +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.rs @@ -0,0 +1,13 @@ +//@ edition: 2021 + +macro_rules! x { + ($ty : item) => {}; +} +x! { + trait MyTrait { fn bar(c self) } + //~^ ERROR expected identifier, found keyword `self` + //~^^ ERROR expected one of `:`, `@`, or `|`, found keyword `self` + //~^^^ ERROR expected one of `->`, `;`, `where`, or `{`, found `}` +} + +fn main() {} diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr new file mode 100644 index 000000000000..81151edaf0c0 --- /dev/null +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr @@ -0,0 +1,25 @@ +error: expected identifier, found keyword `self` + --> $DIR/kw-in-item-pos-recovery-151238.rs:7:28 + | +LL | trait MyTrait { fn bar(c self) } + | ^^^^ expected identifier, found keyword + +error: expected one of `:`, `@`, or `|`, found keyword `self` + --> $DIR/kw-in-item-pos-recovery-151238.rs:7:28 + | +LL | trait MyTrait { fn bar(c self) } + | --^^^^ + | | | + | | expected one of `:`, `@`, or `|` + | help: declare the type after the parameter binding: `: ` + +error: expected one of `->`, `;`, `where`, or `{`, found `}` + --> $DIR/kw-in-item-pos-recovery-151238.rs:7:34 + | +LL | trait MyTrait { fn bar(c self) } + | --- ^ expected one of `->`, `;`, `where`, or `{` + | | + | while parsing this `fn` + +error: aborting due to 3 previous errors + From ebcbff2a2e79d0c36442bb19a9eb154dc202f2d5 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 19 Jan 2026 04:50:23 +0200 Subject: [PATCH 2317/3801] Do not mix the order of builtin/regular derives in "Expand macro recursively" --- .../rust-analyzer/crates/hir/src/semantics.rs | 7 +++++-- .../crates/ide/src/expand_macro.rs | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index e55b693ef018..98f5739600f3 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -641,11 +641,14 @@ impl<'db> SemanticsImpl<'db> { }) } - pub fn expand_derive_macro(&self, attr: &ast::Attr) -> Option>> { + pub fn expand_derive_macro( + &self, + attr: &ast::Attr, + ) -> Option>>> { let res: Vec<_> = self .derive_macro_calls(attr)? .into_iter() - .flat_map(|call| { + .map(|call| { let file_id = call?.left()?; let ExpandResult { value, err } = self.db.parse_macro_expansion(file_id); let root_node = value.0.syntax_node(); diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index ba8b3aa9cafe..44285d9315af 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -63,7 +63,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< .take_while(|it| it != &token) .filter(|it| it.kind() == T![,]) .count(); - let ExpandResult { err, value: expansion } = expansions.get(idx)?.clone(); + let ExpandResult { err, value: expansion } = expansions.get(idx)?.clone()?; let expansion_file_id = sema.hir_file_for(&expansion).macro_file()?; let expansion_span_map = db.expansion_span_map(expansion_file_id); let mut expansion = format( @@ -848,4 +848,19 @@ struct S { u32"#]], ); } + + #[test] + fn regression_21489() { + check( + r#" +//- proc_macros: derive_identity +//- minicore: derive, fmt +#[derive(Debug, proc_macros::DeriveIdentity$0)] +struct Foo; + "#, + expect![[r#" + proc_macros::DeriveIdentity + struct Foo;"#]], + ); + } } From e519c686cfe9220609929e014642bf99eebb48c4 Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 19 Jan 2026 11:15:20 +0800 Subject: [PATCH 2318/3801] Deduplicate diagnostics for const trait supertraits --- .../traits/fulfillment_errors.rs | 31 +++++++++++++++++++ tests/ui/consts/issue-94675.rs | 1 - tests/ui/consts/issue-94675.stderr | 13 +------- tests/ui/traits/const-traits/call.rs | 1 - tests/ui/traits/const-traits/call.stderr | 11 +------ ...closure-const_trait_impl-ice-113381.stderr | 11 +------ ...-const-op-const-closure-non-const-outer.rs | 3 +- ...st-op-const-closure-non-const-outer.stderr | 15 ++------- 8 files changed, 39 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 00d06779e652..6872d038fb7f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1442,6 +1442,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.can_eq(param_env, goal.trait_ref, trait_assumption.trait_ref) } + fn can_match_host_effect( + &self, + param_env: ty::ParamEnv<'tcx>, + goal: ty::HostEffectPredicate<'tcx>, + assumption: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>, + ) -> bool { + let assumption = self.instantiate_binder_with_fresh_vars( + DUMMY_SP, + infer::BoundRegionConversionTime::HigherRankedType, + assumption, + ); + + assumption.constness.satisfies(goal.constness) + && self.can_eq(param_env, goal.trait_ref, assumption.trait_ref) + } + + fn as_host_effect_clause( + predicate: ty::Predicate<'tcx>, + ) -> Option>> { + predicate.as_clause().and_then(|clause| match clause.kind().skip_binder() { + ty::ClauseKind::HostEffect(pred) => Some(clause.kind().rebind(pred)), + _ => None, + }) + } + fn can_match_projection( &self, param_env: ty::ParamEnv<'tcx>, @@ -1484,6 +1509,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .filter_map(|implied| implied.as_trait_clause()) .any(|implied| self.can_match_trait(param_env, error, implied)) }) + } else if let Some(error) = Self::as_host_effect_clause(error.predicate) { + self.enter_forall(error, |error| { + elaborate(self.tcx, std::iter::once(cond.predicate)) + .filter_map(Self::as_host_effect_clause) + .any(|implied| self.can_match_host_effect(param_env, error, implied)) + }) } else if let Some(error) = error.predicate.as_projection_clause() { self.enter_forall(error, |error| { elaborate(self.tcx, std::iter::once(cond.predicate)) diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs index f2ddc928d122..0553b676bc3e 100644 --- a/tests/ui/consts/issue-94675.rs +++ b/tests/ui/consts/issue-94675.rs @@ -10,7 +10,6 @@ impl<'a> Foo<'a> { const fn spam(&mut self, baz: &mut Vec) { self.bar[0] = baz.len(); //~^ ERROR: `Vec: [const] Index<_>` is not satisfied - //~| ERROR: `Vec: [const] Index` is not satisfied //~| ERROR: `Vec: [const] IndexMut` is not satisfied } } diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr index 771f2a14c305..ab7a76a90e02 100644 --- a/tests/ui/consts/issue-94675.stderr +++ b/tests/ui/consts/issue-94675.stderr @@ -16,17 +16,6 @@ LL | self.bar[0] = baz.len(); note: trait `IndexMut` is implemented but not `const` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -error[E0277]: the trait bound `Vec: [const] Index` is not satisfied - --> $DIR/issue-94675.rs:11:9 - | -LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ - | -note: trait `Index` is implemented but not `const` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -note: required by a bound in `std::ops::IndexMut::index_mut` - --> $SRC_DIR/core/src/ops/index.rs:LL:COL - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/call.rs b/tests/ui/traits/const-traits/call.rs index c36adc4248f0..360c08e1b7fe 100644 --- a/tests/ui/traits/const-traits/call.rs +++ b/tests/ui/traits/const-traits/call.rs @@ -6,7 +6,6 @@ const _: () = { assert!((const || true)()); //~^ ERROR }: [const] Fn()` is not satisfied - //~| ERROR }: [const] FnMut()` is not satisfied }; fn main() {} diff --git a/tests/ui/traits/const-traits/call.stderr b/tests/ui/traits/const-traits/call.stderr index b688746e2506..8e32cab6dfcf 100644 --- a/tests/ui/traits/const-traits/call.stderr +++ b/tests/ui/traits/const-traits/call.stderr @@ -4,15 +4,6 @@ error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] Fn()` LL | assert!((const || true)()); | ^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] FnMut()` is not satisfied - --> $DIR/call.rs:7:13 - | -LL | assert!((const || true)()); - | ^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `call` - --> $SRC_DIR/core/src/ops/function.rs:LL:COL - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr index 90e87c724f54..dab3f14161fa 100644 --- a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr +++ b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr @@ -4,15 +4,6 @@ error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice- LL | (const || (()).foo())(); | ^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice-113381.rs:15:6: 15:14}: [const] FnMut()` is not satisfied - --> $DIR/const_closure-const_trait_impl-ice-113381.rs:15:5 - | -LL | (const || (()).foo())(); - | ^^^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `call` - --> $SRC_DIR/core/src/ops/function.rs:LL:COL - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs index ee4ff02f4c7c..de5bedf0ace7 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs @@ -10,7 +10,8 @@ impl Foo for () { } fn main() { + // #150052 deduplicate diagnostics for const trait supertraits + // so we only get one error here (const || { (()).foo() })(); //~^ ERROR: }: [const] Fn()` is not satisfied - //~| ERROR: }: [const] FnMut()` is not satisfied } diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr index 69d289537da1..efbedca1c7e7 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr @@ -1,18 +1,9 @@ -error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:13:6: 13:14}: [const] Fn()` is not satisfied - --> $DIR/non-const-op-const-closure-non-const-outer.rs:13:5 +error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:15:6: 15:14}: [const] Fn()` is not satisfied + --> $DIR/non-const-op-const-closure-non-const-outer.rs:15:5 | LL | (const || { (()).foo() })(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:13:6: 13:14}: [const] FnMut()` is not satisfied - --> $DIR/non-const-op-const-closure-non-const-outer.rs:13:5 - | -LL | (const || { (()).foo() })(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `call` - --> $SRC_DIR/core/src/ops/function.rs:LL:COL - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. From 4dad9b90819bac5aeb50182d77ee0a90c5a196d5 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 19 Jan 2026 05:21:54 +0200 Subject: [PATCH 2319/3801] Insert type vars and normalize for the type of a used `static` They have their own special path, so they slipped through. --- .../crates/hir-ty/src/infer/path.rs | 1 + .../crates/hir-ty/src/tests/simple.rs | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index b11650bbcd9a..ef1a610a323d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -93,6 +93,7 @@ impl<'db> InferenceContext<'_, 'db> { if let GenericDefId::StaticId(_) = generic_def { // `Static` is the kind of item that can never be generic currently. We can just skip the binders to get its type. let ty = self.db.value_ty(value_def)?.skip_binder(); + let ty = self.process_remote_user_written_ty(ty); return Some(ValuePathResolution::NonGeneric(ty)); }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index 28759bcbae61..d2a4149bc630 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs @@ -3997,3 +3997,46 @@ extern "C" fn foo() -> ! { "#, ); } + +#[test] +fn regression_21478() { + check_infer( + r#" +//- minicore: unsize, coerce_unsized +struct LazyLock(T); + +impl LazyLock { + const fn new() -> Self { + loop {} + } + + fn force(this: &Self) -> &T { + loop {} + } +} + +static VALUES_LAZY_LOCK: LazyLock<[u32; { 0 }]> = LazyLock::new(); + +fn foo() { + let _ = LazyLock::force(&VALUES_LAZY_LOCK); +} + "#, + expect![[r#" + 73..96 '{ ... }': LazyLock + 83..90 'loop {}': ! + 88..90 '{}': () + 111..115 'this': &'? LazyLock + 130..153 '{ ... }': &'? T + 140..147 'loop {}': ! + 145..147 '{}': () + 207..220 'LazyLock::new': fn new<[u32; _]>() -> LazyLock<[u32; _]> + 207..222 'LazyLock::new()': LazyLock<[u32; _]> + 234..285 '{ ...CK); }': () + 244..245 '_': &'? [u32; _] + 248..263 'LazyLock::force': fn force<[u32; _]>(&'? LazyLock<[u32; _]>) -> &'? [u32; _] + 248..282 'LazyLo..._LOCK)': &'? [u32; _] + 264..281 '&VALUE...Y_LOCK': &'? LazyLock<[u32; _]> + 265..281 'VALUES...Y_LOCK': LazyLock<[u32; _]> + "#]], + ); +} From 1285b1b13c28e5e11637884e741b6b7e8f36efc8 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 19 Jan 2026 07:14:48 +0200 Subject: [PATCH 2320/3801] Ensure correct capturing of async fn params even when they use weird patterns rustc does the same. --- .../crates/hir-def/src/expr_store/lower.rs | 66 ++++++++++++++----- .../hir-def/src/expr_store/tests/body.rs | 18 +++++ .../crates/hir-ty/src/tests/regression.rs | 1 - .../crates/hir-ty/src/tests/simple.rs | 1 - .../crates/hir-ty/src/tests/traits.rs | 3 - 5 files changed, 68 insertions(+), 21 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index 4ae4271b92f5..79222615929f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -150,6 +150,7 @@ pub(super) fn lower_body( }; let body_expr = collector.collect( + &mut params, body, if is_async_fn { Awaitable::Yes @@ -903,24 +904,57 @@ impl<'db> ExprCollector<'db> { }) } - fn collect(&mut self, expr: Option, awaitable: Awaitable) -> ExprId { + /// An `async fn` needs to capture all parameters in the generated `async` block, even if they have + /// non-captured patterns such as wildcards (to ensure consistent drop order). + fn lower_async_fn(&mut self, params: &mut Vec, body: ExprId) -> ExprId { + let mut statements = Vec::new(); + for param in params { + let name = match self.store.pats[*param] { + Pat::Bind { id, .. } + if matches!( + self.store.bindings[id].mode, + BindingAnnotation::Unannotated | BindingAnnotation::Mutable + ) => + { + // If this is a direct binding, we can leave it as-is, as it'll always be captured anyway. + continue; + } + Pat::Bind { id, .. } => { + // If this is a `ref` binding, we can't leave it as is but we can at least reuse the name, for better display. + self.store.bindings[id].name.clone() + } + _ => self.generate_new_name(), + }; + let binding_id = + self.alloc_binding(name.clone(), BindingAnnotation::Mutable, HygieneId::ROOT); + let pat_id = self.alloc_pat_desugared(Pat::Bind { id: binding_id, subpat: None }); + let expr = self.alloc_expr_desugared(Expr::Path(name.into())); + statements.push(Statement::Let { + pat: *param, + type_ref: None, + initializer: Some(expr), + else_branch: None, + }); + *param = pat_id; + } + + self.alloc_expr_desugared(Expr::Async { + id: None, + statements: statements.into_boxed_slice(), + tail: Some(body), + }) + } + + fn collect( + &mut self, + params: &mut Vec, + expr: Option, + awaitable: Awaitable, + ) -> ExprId { self.awaitable_context.replace(awaitable); self.with_label_rib(RibKind::Closure, |this| { - if awaitable == Awaitable::Yes { - match expr { - Some(e) => { - let syntax_ptr = AstPtr::new(&e); - let expr = this.collect_expr(e); - this.alloc_expr_desugared_with_ptr( - Expr::Async { id: None, statements: Box::new([]), tail: Some(expr) }, - syntax_ptr, - ) - } - None => this.missing_expr(), - } - } else { - this.collect_expr_opt(expr) - } + let body = this.collect_expr_opt(expr); + if awaitable == Awaitable::Yes { this.lower_async_fn(params, body) } else { body } }) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs index 504c310684d6..8f857aeeff95 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs @@ -659,3 +659,21 @@ fn main() { }"#]] .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) } + +#[test] +fn async_fn_weird_param_patterns() { + let (db, body, def) = lower( + r#" +async fn main(&self, param1: i32, ref mut param2: i32, _: i32, param4 @ _: i32, 123: i32) {} +"#, + ); + + expect![[r#" + fn main(self, param1, mut param2, mut 0, param4 @ _, mut 1) async { + let ref mut param2 = param2; + let _ = 0; + let 123 = 1; + {} + }"#]] + .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT)) +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index a04c46f8eabd..4f1480c39366 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -2235,7 +2235,6 @@ async fn f() -> Bar {} "#, expect![[r#" 64..66 '{}': () - 64..66 '{}': impl Future "#]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index 28759bcbae61..80e21450c7a9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs @@ -2139,7 +2139,6 @@ async fn main() { "#, expect![[r#" 16..193 '{ ...2 }; }': () - 16..193 '{ ...2 }; }': impl Future 26..27 'x': i32 30..43 'unsafe { 92 }': i32 39..41 '92': i32 diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs index b825a0a8f0e5..390553c0d7a9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs @@ -4869,7 +4869,6 @@ async fn baz i32>(c: T) { expect![[r#" 37..38 'a': T 43..83 '{ ...ait; }': () - 43..83 '{ ...ait; }': impl Future 53..57 'fut1': >::CallRefFuture<'?> 60..61 'a': T 60..64 'a(0)': >::CallRefFuture<'?> @@ -4878,7 +4877,6 @@ async fn baz i32>(c: T) { 70..80 'fut1.await': i32 124..129 'mut b': T 134..174 '{ ...ait; }': () - 134..174 '{ ...ait; }': impl Future 144..148 'fut2': >::CallRefFuture<'?> 151..152 'b': T 151..155 'b(0)': >::CallRefFuture<'?> @@ -4887,7 +4885,6 @@ async fn baz i32>(c: T) { 161..171 'fut2.await': i32 216..217 'c': T 222..262 '{ ...ait; }': () - 222..262 '{ ...ait; }': impl Future 232..236 'fut3': >::CallOnceFuture 239..240 'c': T 239..243 'c(0)': >::CallOnceFuture From 0895c4cbe6ff960b23626a538d1691d2ebf51311 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Mon, 19 Jan 2026 04:48:23 +0000 Subject: [PATCH 2321/3801] ci: Move lockfile updates to a script --- .github/workflows/dependencies.yml | 16 +++------------- src/tools/update-lockfile.sh | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 13 deletions(-) create mode 100755 src/tools/update-lockfile.sh diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 80ffd67e04e1..7c721c7abeaa 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -62,19 +62,9 @@ jobs: rustup toolchain install --no-self-update --profile minimal $TOOLCHAIN rustup default $TOOLCHAIN - - name: cargo update compiler & tools - # Remove first line that always just says "Updating crates.io index" - run: | - echo -e "\ncompiler & tools dependencies:" >> cargo_update.log - cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log - - name: cargo update library - run: | - echo -e "\nlibrary dependencies:" >> cargo_update.log - cargo update --manifest-path library/Cargo.toml 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log - - name: cargo update rustbook - run: | - echo -e "\nrustbook dependencies:" >> cargo_update.log - cargo update --manifest-path src/tools/rustbook/Cargo.toml 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log + - name: cargo update + run: ./src/tools/update-lockfile.sh + - name: upload Cargo.lock artifact for use in PR uses: actions/upload-artifact@v4 with: diff --git a/src/tools/update-lockfile.sh b/src/tools/update-lockfile.sh new file mode 100755 index 000000000000..a968d83d8152 --- /dev/null +++ b/src/tools/update-lockfile.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# Updates the workspaces in `.`, `library` and `src/tools/rustbook` +# Logs are written to `cargo_update.log` +# Used as part of regular dependency bumps + +set -euo pipefail + +echo -e "\ncompiler & tools dependencies:" > cargo_update.log +# Remove first line that always just says "Updating crates.io index" +cargo update 2>&1 | sed '/crates.io index/d' | \ + tee -a cargo_update.log +echo -e "\nlibrary dependencies:" >> cargo_update.log +cargo update --manifest-path library/Cargo.toml 2>&1 | sed '/crates.io index/d' | \ + tee -a cargo_update.log +echo -e "\nrustbook dependencies:" >> cargo_update.log +cargo update --manifest-path src/tools/rustbook/Cargo.toml 2>&1 | sed '/crates.io index/d' | \ + tee -a cargo_update.log From 740eb6b59fa663e9f1b721d7f6995dcec4af4bc9 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 16 Jan 2026 01:16:57 +0530 Subject: [PATCH 2322/3801] remove non-describing field annotation from bidirectional message definition --- .../proc-macro-api/src/bidirectional_protocol/msg.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index c56ed5191694..2644cd406b63 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -84,18 +84,14 @@ pub struct ExpandMacroData { pub macro_body: FlatTree, pub macro_name: String, pub attributes: Option, - #[serde(skip_serializing_if = "ExpnGlobals::skip_serializing_if")] #[serde(default)] pub has_global_spans: ExpnGlobals, - - #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] pub span_data_table: Vec, } #[derive(Clone, Copy, Default, Debug, Serialize, Deserialize)] pub struct ExpnGlobals { - #[serde(skip_serializing)] #[serde(default)] pub serialize: bool, pub def_site: usize, @@ -103,10 +99,4 @@ pub struct ExpnGlobals { pub mixed_site: usize, } -impl ExpnGlobals { - fn skip_serializing_if(&self) -> bool { - !self.serialize - } -} - impl Message for BidirectionalMessage {} From ffa2dadf0eeab0a484688373cffe9f1939173084 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 18 Jan 2026 19:34:03 +0530 Subject: [PATCH 2323/3801] remove serialize from Expn Globals --- .../crates/proc-macro-api/src/bidirectional_protocol.rs | 8 +------- .../proc-macro-api/src/bidirectional_protocol/msg.rs | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index b5f43e1d3726..a13bff7d7d02 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -23,7 +23,6 @@ use crate::{ }, process::ProcMacroServerProcess, transport::codec::postcard::PostcardProtocol, - version, }; pub mod msg; @@ -159,12 +158,7 @@ pub(crate) fn expand( macro_name: proc_macro.name.to_string(), attributes: attr .map(|subtree| FlatTree::from_subtree(subtree, version, &mut span_data_table)), - has_global_spans: ExpnGlobals { - serialize: version >= version::HAS_GLOBAL_SPANS, - def_site, - call_site, - mixed_site, - }, + has_global_spans: ExpnGlobals { def_site, call_site, mixed_site }, span_data_table: if process.rust_analyzer_spans() { serialize_span_data_index_map(&span_data_table) } else { diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 2644cd406b63..d030498e59c4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -92,8 +92,6 @@ pub struct ExpandMacroData { #[derive(Clone, Copy, Default, Debug, Serialize, Deserialize)] pub struct ExpnGlobals { - #[serde(default)] - pub serialize: bool, pub def_site: usize, pub call_site: usize, pub mixed_site: usize, From 8fd55694389332c648a76c0ad533ba9e01ecc1fe Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 18 Jan 2026 20:23:30 +0530 Subject: [PATCH 2324/3801] add bidirectional flow --- .../proc-macro-srv-cli/tests/common/utils.rs | 570 +++++++++++------- 1 file changed, 357 insertions(+), 213 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs index 722e92eec7e5..63b3a74aa4e8 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs @@ -1,213 +1,357 @@ -use std::{ - collections::VecDeque, - io::{self, BufRead, Read, Write}, - sync::{Arc, Condvar, Mutex}, - thread, -}; - -use paths::Utf8PathBuf; -use proc_macro_api::{ - legacy_protocol::msg::{FlatTree, Message, Request, Response, SpanDataIndexMap}, - transport::codec::json::JsonProtocol, -}; -use span::{Edition, EditionedFileId, FileId, Span, SpanAnchor, SyntaxContext, TextRange}; -use tt::{Delimiter, DelimiterKind, TopSubtreeBuilder}; - -/// Shared state for an in-memory byte channel. -#[derive(Default)] -struct ChannelState { - buffer: VecDeque, - closed: bool, -} - -type InMemoryChannel = Arc<(Mutex, Condvar)>; - -/// Writer end of an in-memory channel. -pub(crate) struct ChannelWriter { - state: InMemoryChannel, -} - -impl Write for ChannelWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - let (lock, cvar) = &*self.state; - let mut state = lock.lock().unwrap(); - if state.closed { - return Err(io::Error::new(io::ErrorKind::BrokenPipe, "channel closed")); - } - state.buffer.extend(buf); - cvar.notify_all(); - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl Drop for ChannelWriter { - fn drop(&mut self) { - let (lock, cvar) = &*self.state; - let mut state = lock.lock().unwrap(); - state.closed = true; - cvar.notify_all(); - } -} - -/// Reader end of an in-memory channel. -pub(crate) struct ChannelReader { - state: InMemoryChannel, - internal_buf: Vec, -} - -impl Read for ChannelReader { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - let (lock, cvar) = &*self.state; - let mut state = lock.lock().unwrap(); - - while state.buffer.is_empty() && !state.closed { - state = cvar.wait(state).unwrap(); - } - - if state.buffer.is_empty() && state.closed { - return Ok(0); - } - - let to_read = buf.len().min(state.buffer.len()); - for (dst, src) in buf.iter_mut().zip(state.buffer.drain(..to_read)) { - *dst = src; - } - Ok(to_read) - } -} - -impl BufRead for ChannelReader { - fn fill_buf(&mut self) -> io::Result<&[u8]> { - let (lock, cvar) = &*self.state; - let mut state = lock.lock().unwrap(); - - while state.buffer.is_empty() && !state.closed { - state = cvar.wait(state).unwrap(); - } - - self.internal_buf.clear(); - self.internal_buf.extend(&state.buffer); - Ok(&self.internal_buf) - } - - fn consume(&mut self, amt: usize) { - let (lock, _) = &*self.state; - let mut state = lock.lock().unwrap(); - let to_drain = amt.min(state.buffer.len()); - drop(state.buffer.drain(..to_drain)); - } -} - -/// Creates a connected pair of channels for bidirectional communication. -fn create_channel_pair() -> (ChannelWriter, ChannelReader, ChannelWriter, ChannelReader) { - // Channel for client -> server communication - let client_to_server = Arc::new(( - Mutex::new(ChannelState { buffer: VecDeque::new(), closed: false }), - Condvar::new(), - )); - let client_writer = ChannelWriter { state: client_to_server.clone() }; - let server_reader = ChannelReader { state: client_to_server, internal_buf: Vec::new() }; - - // Channel for server -> client communication - let server_to_client = Arc::new(( - Mutex::new(ChannelState { buffer: VecDeque::new(), closed: false }), - Condvar::new(), - )); - - let server_writer = ChannelWriter { state: server_to_client.clone() }; - let client_reader = ChannelReader { state: server_to_client, internal_buf: Vec::new() }; - - (client_writer, client_reader, server_writer, server_reader) -} - -pub(crate) fn proc_macro_test_dylib_path() -> Utf8PathBuf { - let path = proc_macro_test::PROC_MACRO_TEST_LOCATION; - if path.is_empty() { - panic!("proc-macro-test dylib not available (requires nightly toolchain)"); - } - path.into() -} - -/// Runs a test with the server in a background thread. -pub(crate) fn with_server(test_fn: F) -> R -where - F: FnOnce(&mut dyn Write, &mut dyn BufRead) -> R, -{ - let (mut client_writer, mut client_reader, mut server_writer, mut server_reader) = - create_channel_pair(); - - let server_handle = thread::spawn(move || { - proc_macro_srv_cli::main_loop::run( - &mut server_reader, - &mut server_writer, - proc_macro_api::ProtocolFormat::JsonLegacy, - ) - }); - - let result = test_fn(&mut client_writer, &mut client_reader); - - // Close the client writer to signal the server to stop - drop(client_writer); - - // Wait for server to finish - match server_handle.join() { - Ok(Ok(())) => {} - Ok(Err(e)) => { - // IO error from server is expected when client disconnects - if matches!( - e.kind(), - io::ErrorKind::BrokenPipe - | io::ErrorKind::UnexpectedEof - | io::ErrorKind::InvalidData - ) { - panic!("Server error: {e}"); - } - } - Err(e) => std::panic::resume_unwind(e), - } - - result -} - -/// Sends a request and reads the response using JSON protocol. -pub(crate) fn request( - writer: &mut dyn Write, - reader: &mut dyn BufRead, - request: Request, -) -> Response { - request.write::(writer).expect("failed to write request"); - - let mut buf = String::new(); - Response::read::(reader, &mut buf) - .expect("failed to read response") - .expect("no response received") -} - -/// Creates a simple empty token tree suitable for testing. -pub(crate) fn create_empty_token_tree( - version: u32, - span_data_table: &mut SpanDataIndexMap, -) -> FlatTree { - let anchor = SpanAnchor { - file_id: EditionedFileId::new(FileId::from_raw(0), Edition::CURRENT), - ast_id: span::ROOT_ERASED_FILE_AST_ID, - }; - let span = Span { - range: TextRange::empty(0.into()), - anchor, - ctx: SyntaxContext::root(Edition::CURRENT), - }; - - let builder = TopSubtreeBuilder::new(Delimiter { - open: span, - close: span, - kind: DelimiterKind::Invisible, - }); - let tt = builder.build(); - - FlatTree::from_subtree(tt.view(), version, span_data_table) -} +use std::{ + collections::VecDeque, + io::{self, BufRead, Read, Write}, + sync::{Arc, Condvar, Mutex}, + thread, +}; + +use paths::Utf8PathBuf; +use proc_macro_api::{ + ServerError, + bidirectional_protocol::msg::{ + BidirectionalMessage, Request as BiRequest, Response as BiResponse, SubRequest, SubResponse, + }, + legacy_protocol::msg::{FlatTree, Message, Request, Response, SpanDataIndexMap}, + transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, +}; +use span::{Edition, EditionedFileId, FileId, Span, SpanAnchor, SyntaxContext, TextRange}; +use tt::{Delimiter, DelimiterKind, TopSubtreeBuilder}; + +/// Shared state for an in-memory byte channel. +#[derive(Default)] +struct ChannelState { + buffer: VecDeque, + closed: bool, +} + +type InMemoryChannel = Arc<(Mutex, Condvar)>; + +/// Writer end of an in-memory channel. +pub(crate) struct ChannelWriter { + state: InMemoryChannel, +} + +impl Write for ChannelWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + if state.closed { + return Err(io::Error::new(io::ErrorKind::BrokenPipe, "channel closed")); + } + state.buffer.extend(buf); + cvar.notify_all(); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Drop for ChannelWriter { + fn drop(&mut self) { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + state.closed = true; + cvar.notify_all(); + } +} + +/// Reader end of an in-memory channel. +pub(crate) struct ChannelReader { + state: InMemoryChannel, + internal_buf: Vec, +} + +impl Read for ChannelReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + + while state.buffer.is_empty() && !state.closed { + state = cvar.wait(state).unwrap(); + } + + if state.buffer.is_empty() && state.closed { + return Ok(0); + } + + let to_read = buf.len().min(state.buffer.len()); + for (dst, src) in buf.iter_mut().zip(state.buffer.drain(..to_read)) { + *dst = src; + } + Ok(to_read) + } +} + +impl BufRead for ChannelReader { + fn fill_buf(&mut self) -> io::Result<&[u8]> { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + + while state.buffer.is_empty() && !state.closed { + state = cvar.wait(state).unwrap(); + } + + self.internal_buf.clear(); + self.internal_buf.extend(&state.buffer); + Ok(&self.internal_buf) + } + + fn consume(&mut self, amt: usize) { + let (lock, _) = &*self.state; + let mut state = lock.lock().unwrap(); + let to_drain = amt.min(state.buffer.len()); + drop(state.buffer.drain(..to_drain)); + } +} + +/// Creates a connected pair of channels for bidirectional communication. +fn create_channel_pair() -> (ChannelWriter, ChannelReader, ChannelWriter, ChannelReader) { + // Channel for client -> server communication + let client_to_server = Arc::new(( + Mutex::new(ChannelState { buffer: VecDeque::new(), closed: false }), + Condvar::new(), + )); + let client_writer = ChannelWriter { state: client_to_server.clone() }; + let server_reader = ChannelReader { state: client_to_server, internal_buf: Vec::new() }; + + // Channel for server -> client communication + let server_to_client = Arc::new(( + Mutex::new(ChannelState { buffer: VecDeque::new(), closed: false }), + Condvar::new(), + )); + + let server_writer = ChannelWriter { state: server_to_client.clone() }; + let client_reader = ChannelReader { state: server_to_client, internal_buf: Vec::new() }; + + (client_writer, client_reader, server_writer, server_reader) +} + +pub(crate) fn proc_macro_test_dylib_path() -> Utf8PathBuf { + let path = proc_macro_test::PROC_MACRO_TEST_LOCATION; + if path.is_empty() { + panic!("proc-macro-test dylib not available (requires nightly toolchain)"); + } + path.into() +} + +/// Creates a simple empty token tree suitable for testing. +pub(crate) fn create_empty_token_tree( + version: u32, + span_data_table: &mut SpanDataIndexMap, +) -> FlatTree { + let anchor = SpanAnchor { + file_id: EditionedFileId::new(FileId::from_raw(0), Edition::CURRENT), + ast_id: span::ROOT_ERASED_FILE_AST_ID, + }; + let span = Span { + range: TextRange::empty(0.into()), + anchor, + ctx: SyntaxContext::root(Edition::CURRENT), + }; + + let builder = TopSubtreeBuilder::new(Delimiter { + open: span, + close: span, + kind: DelimiterKind::Invisible, + }); + let tt = builder.build(); + + FlatTree::from_subtree(tt.view(), version, span_data_table) +} + +pub(crate) fn with_server(format: proc_macro_api::ProtocolFormat, test_fn: F) -> R +where + F: FnOnce(&mut dyn Write, &mut dyn BufRead) -> R, +{ + let (mut client_writer, mut client_reader, mut server_writer, mut server_reader) = + create_channel_pair(); + + let server_handle = thread::spawn(move || { + proc_macro_srv_cli::main_loop::run(&mut server_reader, &mut server_writer, format) + }); + + let result = test_fn(&mut client_writer, &mut client_reader); + + drop(client_writer); + + match server_handle.join() { + Ok(Ok(())) => {} + Ok(Err(e)) => { + if !matches!( + e.kind(), + io::ErrorKind::BrokenPipe + | io::ErrorKind::UnexpectedEof + | io::ErrorKind::InvalidData + ) { + panic!("Server error: {e}"); + } + } + Err(e) => std::panic::resume_unwind(e), + } + + result +} + +trait TestProtocol { + type Request; + type Response; + + fn send(&self, writer: &mut dyn Write, req: Self::Request); + fn drive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> Self::Response; +} + +struct JsonLegacy; + +impl TestProtocol for JsonLegacy { + type Request = Request; + type Response = Response; + + fn send(&self, writer: &mut dyn Write, req: Request) { + req.write::(writer).expect("failed to write request"); + } + + fn drive(&self, reader: &mut dyn BufRead, _writer: &mut dyn Write) -> Response { + let mut buf = String::new(); + Response::read::(reader, &mut buf) + .expect("failed to read response") + .expect("no response received") + } +} + +struct PostcardBidirectional +where + F: Fn(SubRequest) -> Result, +{ + callback: F, +} + +impl TestProtocol for PostcardBidirectional +where + F: Fn(SubRequest) -> Result, +{ + type Request = BiRequest; + type Response = BiResponse; + + fn send(&self, writer: &mut dyn Write, req: BiRequest) { + let msg = BidirectionalMessage::Request(req); + msg.write::(writer).expect("failed to write request"); + } + + fn drive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> BiResponse { + let mut buf = Vec::new(); + + loop { + let msg = BidirectionalMessage::read::(reader, &mut buf) + .expect("failed to read message") + .expect("no message received"); + + match msg { + BidirectionalMessage::Response(resp) => return resp, + BidirectionalMessage::SubRequest(sr) => { + let reply = (self.callback)(sr).expect("subrequest callback failed"); + let msg = BidirectionalMessage::SubResponse(reply); + msg.write::(writer).expect("failed to write subresponse"); + } + other => panic!("unexpected message: {other:?}"), + } + } + } +} + +pub(crate) fn request( + writer: &mut dyn Write, + reader: &mut dyn BufRead, + request: impl Into, + callback: Option<&dyn Fn(SubRequest) -> Result>, +) -> AutoResponse { + let protocol = match callback { + None => AutoProtocol::Legacy(JsonLegacy), + Some(cb) => AutoProtocol::Bidirectional(PostcardBidirectional { callback: cb }), + }; + + protocol.send(writer, request.into()); + protocol.drive(reader, writer) +} + +enum AutoProtocol +where + F: Fn(SubRequest) -> Result, +{ + Legacy(JsonLegacy), + Bidirectional(PostcardBidirectional), +} + +impl TestProtocol for AutoProtocol +where + F: Fn(SubRequest) -> Result, +{ + type Request = AutoRequest; + type Response = AutoResponse; + + fn send(&self, writer: &mut dyn Write, req: AutoRequest) { + match (self, req) { + (AutoProtocol::Legacy(p), AutoRequest::Legacy(r)) => { + p.send(writer, r); + } + (AutoProtocol::Bidirectional(p), AutoRequest::Bidirectional(r)) => { + p.send(writer, r); + } + (AutoProtocol::Legacy(_), AutoRequest::Bidirectional(_)) => { + panic!("bidirectional request used with legacy protocol"); + } + (AutoProtocol::Bidirectional(_), AutoRequest::Legacy(_)) => { + panic!("legacy request used with bidirectional protocol"); + } + } + } + + fn drive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> AutoResponse { + match self { + AutoProtocol::Legacy(p) => AutoResponse::Legacy(p.drive(reader, writer)), + AutoProtocol::Bidirectional(p) => AutoResponse::Bidirectional(p.drive(reader, writer)), + } + } +} + +pub(crate) enum AutoRequest { + Legacy(Request), + Bidirectional(BiRequest), +} + +#[derive(Debug)] +pub(crate) enum AutoResponse { + Legacy(Response), + Bidirectional(BiResponse), +} + +impl From for AutoRequest { + fn from(req: Request) -> AutoRequest { + AutoRequest::Legacy(req) + } +} + +impl From for AutoRequest { + fn from(req: BiRequest) -> AutoRequest { + AutoRequest::Bidirectional(req) + } +} + +impl From for Response { + fn from(res: AutoResponse) -> Response { + match res { + AutoResponse::Legacy(res) => res, + _ => panic!("Should be legacy response"), + } + } +} + +impl From for BiResponse { + fn from(res: AutoResponse) -> BiResponse { + match res { + AutoResponse::Bidirectional(res) => res, + _ => panic!("Should be bidirectional response"), + } + } +} From ee35fd6cb206e00b0e43b7e676a1aed8eb013684 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 18 Jan 2026 20:23:40 +0530 Subject: [PATCH 2325/3801] add bidirectional test --- .../tests/bidirectional_postcard.rs | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs new file mode 100644 index 000000000000..08e44bad3723 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs @@ -0,0 +1,223 @@ +#![cfg(feature = "sysroot-abi")] + +mod common { + pub(crate) mod utils; +} + +use common::utils::{create_empty_token_tree, proc_macro_test_dylib_path, request, with_server}; +use expect_test::expect; +use proc_macro_api::{ + ProtocolFormat::BidirectionalPostcardPrototype, + bidirectional_protocol::{ + msg::{ExpandMacro, ExpandMacroData, ExpnGlobals, Request, Response}, + reject_subrequests, + }, + legacy_protocol::msg::{PanicMessage, ServerConfig, SpanDataIndexMap, SpanMode}, + version::CURRENT_API_VERSION, +}; + +#[test] +fn test_bidi_version_check_bidirectional() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let response = + request(writer, reader, Request::ApiVersionCheck {}, Some(&reject_subrequests)).into(); + + match response { + Response::ApiVersionCheck(version) => { + assert_eq!(version, CURRENT_API_VERSION); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_list_macros() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + let response = + request(writer, reader, Request::ListMacros { dylib_path }, Some(&reject_subrequests)) + .into(); + + let Response::ListMacros(Ok(macros)) = response else { + panic!("expected successful ListMacros response"); + }; + + let mut macro_list: Vec<_> = + macros.iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect(); + macro_list.sort(); + let macro_list_str = macro_list.join("\n"); + + expect![[r#" + DeriveEmpty [CustomDerive] + DeriveError [CustomDerive] + DerivePanic [CustomDerive] + DeriveReemit [CustomDerive] + attr_error [Attr] + attr_noop [Attr] + attr_panic [Attr] + fn_like_clone_tokens [Bang] + fn_like_error [Bang] + fn_like_mk_idents [Bang] + fn_like_mk_literals [Bang] + fn_like_noop [Bang] + fn_like_panic [Bang] + fn_like_span_join [Bang] + fn_like_span_line_column [Bang] + fn_like_span_ops [Bang]"#]] + .assert_eq(¯o_list_str); + }); +} + +#[test] +fn test_bidi_list_macros_invalid_path() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let response = request( + writer, + reader, + Request::ListMacros { dylib_path: "/nonexistent/path/to/dylib.so".into() }, + Some(&reject_subrequests), + ) + .into(); + + match response { + Response::ListMacros(Err(e)) => assert!( + e.starts_with("Cannot create expander for /nonexistent/path/to/dylib.so"), + "{e}" + ), + other => panic!("expected error response, got: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_set_config() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let config = ServerConfig { span_mode: SpanMode::Id }; + let response = + request(writer, reader, Request::SetConfig(config), Some(&reject_subrequests)).into(); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::Id); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_set_config_rust_analyzer_mode() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let config = ServerConfig { span_mode: SpanMode::RustAnalyzer }; + let response = + request(writer, reader, Request::SetConfig(config), Some(&reject_subrequests)).into(); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::RustAnalyzer); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_expand_macro_panic() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = + common::utils::create_empty_token_tree(CURRENT_API_VERSION, &mut span_data_table); + + let request1 = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "fn_like_panic".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { def_site: 0, call_site: 0, mixed_site: 0 }, + span_data_table: vec![], + }, + })); + + let response = request(writer, reader, request1, Some(&reject_subrequests)).into(); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + assert!(msg.contains("fn_like_panic"), "panic message should mention macro name"); + } + other => panic!("expected panic response, got: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_basic_call_flow() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let response1 = + request(writer, reader, Request::ApiVersionCheck {}, Some(&reject_subrequests)).into(); + assert!(matches!(response1, Response::ApiVersionCheck(_))); + + let response2 = request( + writer, + reader, + Request::SetConfig(ServerConfig { span_mode: SpanMode::Id }), + Some(&reject_subrequests), + ) + .into(); + assert!(matches!(response2, Response::SetConfig(_))); + + let response3 = request( + writer, + reader, + Request::ListMacros { dylib_path: dylib_path.clone() }, + Some(&reject_subrequests), + ) + .into(); + assert!(matches!(response3, Response::ListMacros(Ok(_)))); + }); +} + +#[test] +fn test_bidi_expand_nonexistent_macro() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let version_response = + request(writer, reader, Request::ApiVersionCheck {}, Some(&reject_subrequests)).into(); + let Response::ApiVersionCheck(version) = version_response else { + panic!("expected version check response"); + }; + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = create_empty_token_tree(version, &mut span_data_table); + + let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "NonexistentMacro".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { def_site: 0, call_site: 0, mixed_site: 0 }, + span_data_table: vec![], + }, + })); + + let response = request(writer, reader, expand_request, Some(&reject_subrequests)).into(); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + expect!["proc-macro `NonexistentMacro` is missing"].assert_eq(&msg) + } + other => panic!("expected error for nonexistent macro, got: {other:?}"), + } + }); +} From a151d7dc5617ecd8c0cf8fbb688654c66e9776b6 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 18 Jan 2026 20:23:49 +0530 Subject: [PATCH 2326/3801] adapt json test --- .../proc-macro-srv-cli/tests/legacy_json.rs | 457 +++++++++--------- 1 file changed, 233 insertions(+), 224 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs index 1fa886219a8a..8daee7b2bceb 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs @@ -1,224 +1,233 @@ -//! Integration tests for the proc-macro-srv-cli main loop. -//! -//! These tests exercise the full client-server RPC procedure using in-memory -//! channels without needing to spawn the actual server and client processes. - -#![cfg(feature = "sysroot-abi")] - -mod common { - pub(crate) mod utils; -} - -use common::utils::{create_empty_token_tree, proc_macro_test_dylib_path, request, with_server}; -use expect_test::expect; -use proc_macro_api::{ - legacy_protocol::msg::{ - ExpandMacro, ExpandMacroData, ExpnGlobals, PanicMessage, Request, Response, ServerConfig, - SpanDataIndexMap, SpanMode, - }, - version::CURRENT_API_VERSION, -}; - -#[test] -fn test_version_check() { - with_server(|writer, reader| { - let response = request(writer, reader, Request::ApiVersionCheck {}); - - match response { - Response::ApiVersionCheck(version) => { - assert_eq!(version, CURRENT_API_VERSION); - } - other => panic!("unexpected response: {other:?}"), - } - }); -} - -#[test] -fn test_list_macros() { - with_server(|writer, reader| { - let dylib_path = proc_macro_test_dylib_path(); - let response = request(writer, reader, Request::ListMacros { dylib_path }); - - let Response::ListMacros(Ok(macros)) = response else { - panic!("expected successful ListMacros response"); - }; - - let mut macro_list: Vec<_> = - macros.iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect(); - macro_list.sort(); - let macro_list_str = macro_list.join("\n"); - - expect![[r#" - DeriveEmpty [CustomDerive] - DeriveError [CustomDerive] - DerivePanic [CustomDerive] - DeriveReemit [CustomDerive] - attr_error [Attr] - attr_noop [Attr] - attr_panic [Attr] - fn_like_clone_tokens [Bang] - fn_like_error [Bang] - fn_like_mk_idents [Bang] - fn_like_mk_literals [Bang] - fn_like_noop [Bang] - fn_like_panic [Bang] - fn_like_span_join [Bang] - fn_like_span_line_column [Bang] - fn_like_span_ops [Bang]"#]] - .assert_eq(¯o_list_str); - }); -} - -#[test] -fn test_list_macros_invalid_path() { - with_server(|writer, reader| { - let response = request( - writer, - reader, - Request::ListMacros { dylib_path: "/nonexistent/path/to/dylib.so".into() }, - ); - - match response { - Response::ListMacros(Err(e)) => assert!( - e.starts_with("Cannot create expander for /nonexistent/path/to/dylib.so"), - "{e}" - ), - other => panic!("expected error response, got: {other:?}"), - } - }); -} - -#[test] -fn test_set_config() { - with_server(|writer, reader| { - let config = ServerConfig { span_mode: SpanMode::Id }; - let response = request(writer, reader, Request::SetConfig(config)); - - match response { - Response::SetConfig(returned_config) => { - assert_eq!(returned_config.span_mode, SpanMode::Id); - } - other => panic!("unexpected response: {other:?}"), - } - }); -} - -#[test] -fn test_set_config_rust_analyzer_mode() { - with_server(|writer, reader| { - let config = ServerConfig { span_mode: SpanMode::RustAnalyzer }; - let response = request(writer, reader, Request::SetConfig(config)); - - match response { - Response::SetConfig(returned_config) => { - assert_eq!(returned_config.span_mode, SpanMode::RustAnalyzer); - } - other => panic!("unexpected response: {other:?}"), - } - }); -} - -#[test] -fn test_expand_macro_panic() { - with_server(|writer, reader| { - let dylib_path = proc_macro_test_dylib_path(); - - let version_response = request(writer, reader, Request::ApiVersionCheck {}); - let Response::ApiVersionCheck(version) = version_response else { - panic!("expected version check response"); - }; - - let mut span_data_table = SpanDataIndexMap::default(); - let macro_body = create_empty_token_tree(version, &mut span_data_table); - - let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { - lib: dylib_path, - env: vec![], - current_dir: None, - data: ExpandMacroData { - macro_body, - macro_name: "fn_like_panic".to_owned(), - attributes: None, - has_global_spans: ExpnGlobals { - serialize: version >= 3, - def_site: 0, - call_site: 0, - mixed_site: 0, - }, - span_data_table: vec![], - }, - })); - - let response = request(writer, reader, expand_request); - - match response { - Response::ExpandMacro(Err(PanicMessage(msg))) => { - assert!(msg.contains("fn_like_panic"), "panic message should mention the macro"); - } - Response::ExpandMacro(Ok(_)) => { - panic!("expected panic, but macro succeeded"); - } - other => panic!("unexpected response: {other:?}"), - } - }); -} - -#[test] -fn test_basic_call_flow() { - with_server(|writer, reader| { - let dylib_path = proc_macro_test_dylib_path(); - - let response1 = request(writer, reader, Request::ApiVersionCheck {}); - assert!(matches!(response1, Response::ApiVersionCheck(_))); - - let response2 = - request(writer, reader, Request::SetConfig(ServerConfig { span_mode: SpanMode::Id })); - assert!(matches!(response2, Response::SetConfig(_))); - - let response3 = - request(writer, reader, Request::ListMacros { dylib_path: dylib_path.clone() }); - assert!(matches!(response3, Response::ListMacros(Ok(_)))); - }); -} - -#[test] -fn test_expand_nonexistent_macro() { - with_server(|writer, reader| { - let dylib_path = proc_macro_test_dylib_path(); - - let version_response = request(writer, reader, Request::ApiVersionCheck {}); - let Response::ApiVersionCheck(version) = version_response else { - panic!("expected version check response"); - }; - - let mut span_data_table = SpanDataIndexMap::default(); - let macro_body = create_empty_token_tree(version, &mut span_data_table); - - let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { - lib: dylib_path, - env: vec![], - current_dir: None, - data: ExpandMacroData { - macro_body, - macro_name: "NonexistentMacro".to_owned(), - attributes: None, - has_global_spans: ExpnGlobals { - serialize: version >= 3, - def_site: 0, - call_site: 0, - mixed_site: 0, - }, - span_data_table: vec![], - }, - })); - - let response = request(writer, reader, expand_request); - - match response { - Response::ExpandMacro(Err(PanicMessage(msg))) => { - expect!["proc-macro `NonexistentMacro` is missing"].assert_eq(&msg) - } - other => panic!("expected error for nonexistent macro, got: {other:?}"), - } - }); -} +//! Integration tests for the proc-macro-srv-cli main loop. +//! +//! These tests exercise the full client-server RPC procedure using in-memory +//! channels without needing to spawn the actual server and client processes. + +#![cfg(feature = "sysroot-abi")] + +mod common { + pub(crate) mod utils; +} + +use common::utils::{create_empty_token_tree, proc_macro_test_dylib_path, request, with_server}; +use expect_test::expect; +use proc_macro_api::{ + ProtocolFormat::JsonLegacy, + legacy_protocol::msg::{ + ExpandMacro, ExpandMacroData, ExpnGlobals, PanicMessage, Request, Response, ServerConfig, + SpanDataIndexMap, SpanMode, + }, + version::CURRENT_API_VERSION, +}; + +#[test] +fn test_version_check() { + with_server(JsonLegacy, |writer, reader| { + let response = request(writer, reader, Request::ApiVersionCheck {}, None).into(); + + match response { + Response::ApiVersionCheck(version) => { + assert_eq!(version, CURRENT_API_VERSION); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_list_macros() { + with_server(JsonLegacy, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + let response = request(writer, reader, Request::ListMacros { dylib_path }, None).into(); + + let Response::ListMacros(Ok(macros)) = response else { + panic!("expected successful ListMacros response"); + }; + + let mut macro_list: Vec<_> = + macros.iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect(); + macro_list.sort(); + let macro_list_str = macro_list.join("\n"); + + expect![[r#" + DeriveEmpty [CustomDerive] + DeriveError [CustomDerive] + DerivePanic [CustomDerive] + DeriveReemit [CustomDerive] + attr_error [Attr] + attr_noop [Attr] + attr_panic [Attr] + fn_like_clone_tokens [Bang] + fn_like_error [Bang] + fn_like_mk_idents [Bang] + fn_like_mk_literals [Bang] + fn_like_noop [Bang] + fn_like_panic [Bang] + fn_like_span_join [Bang] + fn_like_span_line_column [Bang] + fn_like_span_ops [Bang]"#]] + .assert_eq(¯o_list_str); + }); +} + +#[test] +fn test_list_macros_invalid_path() { + with_server(JsonLegacy, |writer, reader| { + let response = request( + writer, + reader, + Request::ListMacros { dylib_path: "/nonexistent/path/to/dylib.so".into() }, + None, + ) + .into(); + + match response { + Response::ListMacros(Err(e)) => assert!( + e.starts_with("Cannot create expander for /nonexistent/path/to/dylib.so"), + "{e}" + ), + other => panic!("expected error response, got: {other:?}"), + } + }); +} + +#[test] +fn test_set_config() { + with_server(JsonLegacy, |writer, reader| { + let config = ServerConfig { span_mode: SpanMode::Id }; + let response = request(writer, reader, Request::SetConfig(config), None).into(); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::Id); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_set_config_rust_analyzer_mode() { + with_server(JsonLegacy, |writer, reader| { + let config = ServerConfig { span_mode: SpanMode::RustAnalyzer }; + let response = request(writer, reader, Request::SetConfig(config), None).into(); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::RustAnalyzer); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_expand_macro_panic() { + with_server(JsonLegacy, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let version_response = request(writer, reader, Request::ApiVersionCheck {}, None).into(); + let Response::ApiVersionCheck(version) = version_response else { + panic!("expected version check response"); + }; + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = create_empty_token_tree(version, &mut span_data_table); + + let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "fn_like_panic".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { + serialize: version >= 3, + def_site: 0, + call_site: 0, + mixed_site: 0, + }, + span_data_table: vec![], + }, + })); + + let response = request(writer, reader, expand_request, None).into(); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + assert!(msg.contains("fn_like_panic"), "panic message should mention the macro"); + } + Response::ExpandMacro(Ok(_)) => { + panic!("expected panic, but macro succeeded"); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_basic_call_flow() { + with_server(JsonLegacy, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let response1 = request(writer, reader, Request::ApiVersionCheck {}, None).into(); + assert!(matches!(response1, Response::ApiVersionCheck(_))); + + let response2 = request( + writer, + reader, + Request::SetConfig(ServerConfig { span_mode: SpanMode::Id }), + None, + ) + .into(); + assert!(matches!(response2, Response::SetConfig(_))); + + let response3 = + request(writer, reader, Request::ListMacros { dylib_path: dylib_path.clone() }, None) + .into(); + assert!(matches!(response3, Response::ListMacros(Ok(_)))); + }); +} + +#[test] +fn test_expand_nonexistent_macro() { + with_server(JsonLegacy, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let version_response = request(writer, reader, Request::ApiVersionCheck {}, None).into(); + let Response::ApiVersionCheck(version) = version_response else { + panic!("expected version check response"); + }; + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = create_empty_token_tree(version, &mut span_data_table); + + let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "NonexistentMacro".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { + serialize: version >= 3, + def_site: 0, + call_site: 0, + mixed_site: 0, + }, + span_data_table: vec![], + }, + })); + + let response = request(writer, reader, expand_request, None).into(); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + expect!["proc-macro `NonexistentMacro` is missing"].assert_eq(&msg) + } + other => panic!("expected error for nonexistent macro, got: {other:?}"), + } + }); +} From 095b0138028d51e45ca987e0b0b1dcf4e16a876d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 18 Jan 2026 20:38:58 +0530 Subject: [PATCH 2327/3801] rename send and drive to request and receive and remove auto* --- .../tests/bidirectional_postcard.rs | 48 +++---- .../proc-macro-srv-cli/tests/common/utils.rs | 118 ++++-------------- .../proc-macro-srv-cli/tests/legacy_json.rs | 37 +++--- 3 files changed, 67 insertions(+), 136 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs index 08e44bad3723..33ca1d791de7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs @@ -4,7 +4,9 @@ mod common { pub(crate) mod utils; } -use common::utils::{create_empty_token_tree, proc_macro_test_dylib_path, request, with_server}; +use common::utils::{ + create_empty_token_tree, proc_macro_test_dylib_path, request_bidirectional, with_server, +}; use expect_test::expect; use proc_macro_api::{ ProtocolFormat::BidirectionalPostcardPrototype, @@ -20,7 +22,7 @@ use proc_macro_api::{ fn test_bidi_version_check_bidirectional() { with_server(BidirectionalPostcardPrototype, |writer, reader| { let response = - request(writer, reader, Request::ApiVersionCheck {}, Some(&reject_subrequests)).into(); + request_bidirectional(writer, reader, Request::ApiVersionCheck {}, reject_subrequests); match response { Response::ApiVersionCheck(version) => { @@ -35,9 +37,12 @@ fn test_bidi_version_check_bidirectional() { fn test_bidi_list_macros() { with_server(BidirectionalPostcardPrototype, |writer, reader| { let dylib_path = proc_macro_test_dylib_path(); - let response = - request(writer, reader, Request::ListMacros { dylib_path }, Some(&reject_subrequests)) - .into(); + let response = request_bidirectional( + writer, + reader, + Request::ListMacros { dylib_path }, + &reject_subrequests, + ); let Response::ListMacros(Ok(macros)) = response else { panic!("expected successful ListMacros response"); @@ -72,13 +77,12 @@ fn test_bidi_list_macros() { #[test] fn test_bidi_list_macros_invalid_path() { with_server(BidirectionalPostcardPrototype, |writer, reader| { - let response = request( + let response = request_bidirectional( writer, reader, Request::ListMacros { dylib_path: "/nonexistent/path/to/dylib.so".into() }, - Some(&reject_subrequests), - ) - .into(); + reject_subrequests, + ); match response { Response::ListMacros(Err(e)) => assert!( @@ -95,7 +99,7 @@ fn test_bidi_set_config() { with_server(BidirectionalPostcardPrototype, |writer, reader| { let config = ServerConfig { span_mode: SpanMode::Id }; let response = - request(writer, reader, Request::SetConfig(config), Some(&reject_subrequests)).into(); + request_bidirectional(writer, reader, Request::SetConfig(config), reject_subrequests); match response { Response::SetConfig(returned_config) => { @@ -111,7 +115,7 @@ fn test_bidi_set_config_rust_analyzer_mode() { with_server(BidirectionalPostcardPrototype, |writer, reader| { let config = ServerConfig { span_mode: SpanMode::RustAnalyzer }; let response = - request(writer, reader, Request::SetConfig(config), Some(&reject_subrequests)).into(); + request_bidirectional(writer, reader, Request::SetConfig(config), reject_subrequests); match response { Response::SetConfig(returned_config) => { @@ -144,7 +148,7 @@ fn test_bidi_expand_macro_panic() { }, })); - let response = request(writer, reader, request1, Some(&reject_subrequests)).into(); + let response = request_bidirectional(writer, reader, request1, reject_subrequests); match response { Response::ExpandMacro(Err(PanicMessage(msg))) => { @@ -161,25 +165,23 @@ fn test_bidi_basic_call_flow() { let dylib_path = proc_macro_test_dylib_path(); let response1 = - request(writer, reader, Request::ApiVersionCheck {}, Some(&reject_subrequests)).into(); + request_bidirectional(writer, reader, Request::ApiVersionCheck {}, reject_subrequests); assert!(matches!(response1, Response::ApiVersionCheck(_))); - let response2 = request( + let response2 = request_bidirectional( writer, reader, Request::SetConfig(ServerConfig { span_mode: SpanMode::Id }), - Some(&reject_subrequests), - ) - .into(); + reject_subrequests, + ); assert!(matches!(response2, Response::SetConfig(_))); - let response3 = request( + let response3 = request_bidirectional( writer, reader, Request::ListMacros { dylib_path: dylib_path.clone() }, - Some(&reject_subrequests), - ) - .into(); + reject_subrequests, + ); assert!(matches!(response3, Response::ListMacros(Ok(_)))); }); } @@ -190,7 +192,7 @@ fn test_bidi_expand_nonexistent_macro() { let dylib_path = proc_macro_test_dylib_path(); let version_response = - request(writer, reader, Request::ApiVersionCheck {}, Some(&reject_subrequests)).into(); + request_bidirectional(writer, reader, Request::ApiVersionCheck {}, reject_subrequests); let Response::ApiVersionCheck(version) = version_response else { panic!("expected version check response"); }; @@ -211,7 +213,7 @@ fn test_bidi_expand_nonexistent_macro() { }, })); - let response = request(writer, reader, expand_request, Some(&reject_subrequests)).into(); + let response = request_bidirectional(writer, reader, expand_request, reject_subrequests); match response { Response::ExpandMacro(Err(PanicMessage(msg))) => { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs index 63b3a74aa4e8..85c394734b33 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs @@ -198,21 +198,22 @@ trait TestProtocol { type Request; type Response; - fn send(&self, writer: &mut dyn Write, req: Self::Request); - fn drive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> Self::Response; + fn request(&self, writer: &mut dyn Write, req: Self::Request); + fn receive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> Self::Response; } +#[allow(dead_code)] struct JsonLegacy; impl TestProtocol for JsonLegacy { type Request = Request; type Response = Response; - fn send(&self, writer: &mut dyn Write, req: Request) { + fn request(&self, writer: &mut dyn Write, req: Request) { req.write::(writer).expect("failed to write request"); } - fn drive(&self, reader: &mut dyn BufRead, _writer: &mut dyn Write) -> Response { + fn receive(&self, reader: &mut dyn BufRead, _writer: &mut dyn Write) -> Response { let mut buf = String::new(); Response::read::(reader, &mut buf) .expect("failed to read response") @@ -220,6 +221,7 @@ impl TestProtocol for JsonLegacy { } } +#[allow(dead_code)] struct PostcardBidirectional where F: Fn(SubRequest) -> Result, @@ -234,12 +236,12 @@ where type Request = BiRequest; type Response = BiResponse; - fn send(&self, writer: &mut dyn Write, req: BiRequest) { + fn request(&self, writer: &mut dyn Write, req: BiRequest) { let msg = BidirectionalMessage::Request(req); msg.write::(writer).expect("failed to write request"); } - fn drive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> BiResponse { + fn receive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> BiResponse { let mut buf = Vec::new(); loop { @@ -260,98 +262,28 @@ where } } -pub(crate) fn request( +#[allow(dead_code)] +pub(crate) fn request_legacy( writer: &mut dyn Write, reader: &mut dyn BufRead, - request: impl Into, - callback: Option<&dyn Fn(SubRequest) -> Result>, -) -> AutoResponse { - let protocol = match callback { - None => AutoProtocol::Legacy(JsonLegacy), - Some(cb) => AutoProtocol::Bidirectional(PostcardBidirectional { callback: cb }), - }; - - protocol.send(writer, request.into()); - protocol.drive(reader, writer) + request: Request, +) -> Response { + let protocol = JsonLegacy; + protocol.request(writer, request); + protocol.receive(reader, writer) } -enum AutoProtocol +#[allow(dead_code)] +pub(crate) fn request_bidirectional( + writer: &mut dyn Write, + reader: &mut dyn BufRead, + request: BiRequest, + callback: F, +) -> BiResponse where F: Fn(SubRequest) -> Result, { - Legacy(JsonLegacy), - Bidirectional(PostcardBidirectional), -} - -impl TestProtocol for AutoProtocol -where - F: Fn(SubRequest) -> Result, -{ - type Request = AutoRequest; - type Response = AutoResponse; - - fn send(&self, writer: &mut dyn Write, req: AutoRequest) { - match (self, req) { - (AutoProtocol::Legacy(p), AutoRequest::Legacy(r)) => { - p.send(writer, r); - } - (AutoProtocol::Bidirectional(p), AutoRequest::Bidirectional(r)) => { - p.send(writer, r); - } - (AutoProtocol::Legacy(_), AutoRequest::Bidirectional(_)) => { - panic!("bidirectional request used with legacy protocol"); - } - (AutoProtocol::Bidirectional(_), AutoRequest::Legacy(_)) => { - panic!("legacy request used with bidirectional protocol"); - } - } - } - - fn drive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> AutoResponse { - match self { - AutoProtocol::Legacy(p) => AutoResponse::Legacy(p.drive(reader, writer)), - AutoProtocol::Bidirectional(p) => AutoResponse::Bidirectional(p.drive(reader, writer)), - } - } -} - -pub(crate) enum AutoRequest { - Legacy(Request), - Bidirectional(BiRequest), -} - -#[derive(Debug)] -pub(crate) enum AutoResponse { - Legacy(Response), - Bidirectional(BiResponse), -} - -impl From for AutoRequest { - fn from(req: Request) -> AutoRequest { - AutoRequest::Legacy(req) - } -} - -impl From for AutoRequest { - fn from(req: BiRequest) -> AutoRequest { - AutoRequest::Bidirectional(req) - } -} - -impl From for Response { - fn from(res: AutoResponse) -> Response { - match res { - AutoResponse::Legacy(res) => res, - _ => panic!("Should be legacy response"), - } - } -} - -impl From for BiResponse { - fn from(res: AutoResponse) -> BiResponse { - match res { - AutoResponse::Bidirectional(res) => res, - _ => panic!("Should be bidirectional response"), - } - } + let protocol = PostcardBidirectional { callback }; + protocol.request(writer, request); + protocol.receive(reader, writer) } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs index 8daee7b2bceb..c0dbfd1679f7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs @@ -9,7 +9,9 @@ mod common { pub(crate) mod utils; } -use common::utils::{create_empty_token_tree, proc_macro_test_dylib_path, request, with_server}; +use common::utils::{ + create_empty_token_tree, proc_macro_test_dylib_path, request_legacy, with_server, +}; use expect_test::expect; use proc_macro_api::{ ProtocolFormat::JsonLegacy, @@ -23,7 +25,7 @@ use proc_macro_api::{ #[test] fn test_version_check() { with_server(JsonLegacy, |writer, reader| { - let response = request(writer, reader, Request::ApiVersionCheck {}, None).into(); + let response = request_legacy(writer, reader, Request::ApiVersionCheck {}); match response { Response::ApiVersionCheck(version) => { @@ -38,7 +40,7 @@ fn test_version_check() { fn test_list_macros() { with_server(JsonLegacy, |writer, reader| { let dylib_path = proc_macro_test_dylib_path(); - let response = request(writer, reader, Request::ListMacros { dylib_path }, None).into(); + let response = request_legacy(writer, reader, Request::ListMacros { dylib_path }); let Response::ListMacros(Ok(macros)) = response else { panic!("expected successful ListMacros response"); @@ -73,13 +75,11 @@ fn test_list_macros() { #[test] fn test_list_macros_invalid_path() { with_server(JsonLegacy, |writer, reader| { - let response = request( + let response = request_legacy( writer, reader, Request::ListMacros { dylib_path: "/nonexistent/path/to/dylib.so".into() }, - None, - ) - .into(); + ); match response { Response::ListMacros(Err(e)) => assert!( @@ -95,7 +95,7 @@ fn test_list_macros_invalid_path() { fn test_set_config() { with_server(JsonLegacy, |writer, reader| { let config = ServerConfig { span_mode: SpanMode::Id }; - let response = request(writer, reader, Request::SetConfig(config), None).into(); + let response = request_legacy(writer, reader, Request::SetConfig(config)); match response { Response::SetConfig(returned_config) => { @@ -110,7 +110,7 @@ fn test_set_config() { fn test_set_config_rust_analyzer_mode() { with_server(JsonLegacy, |writer, reader| { let config = ServerConfig { span_mode: SpanMode::RustAnalyzer }; - let response = request(writer, reader, Request::SetConfig(config), None).into(); + let response = request_legacy(writer, reader, Request::SetConfig(config)); match response { Response::SetConfig(returned_config) => { @@ -126,7 +126,7 @@ fn test_expand_macro_panic() { with_server(JsonLegacy, |writer, reader| { let dylib_path = proc_macro_test_dylib_path(); - let version_response = request(writer, reader, Request::ApiVersionCheck {}, None).into(); + let version_response = request_legacy(writer, reader, Request::ApiVersionCheck {}); let Response::ApiVersionCheck(version) = version_response else { panic!("expected version check response"); }; @@ -152,7 +152,7 @@ fn test_expand_macro_panic() { }, })); - let response = request(writer, reader, expand_request, None).into(); + let response = request_legacy(writer, reader, expand_request); match response { Response::ExpandMacro(Err(PanicMessage(msg))) => { @@ -171,21 +171,18 @@ fn test_basic_call_flow() { with_server(JsonLegacy, |writer, reader| { let dylib_path = proc_macro_test_dylib_path(); - let response1 = request(writer, reader, Request::ApiVersionCheck {}, None).into(); + let response1 = request_legacy(writer, reader, Request::ApiVersionCheck {}); assert!(matches!(response1, Response::ApiVersionCheck(_))); - let response2 = request( + let response2 = request_legacy( writer, reader, Request::SetConfig(ServerConfig { span_mode: SpanMode::Id }), - None, - ) - .into(); + ); assert!(matches!(response2, Response::SetConfig(_))); let response3 = - request(writer, reader, Request::ListMacros { dylib_path: dylib_path.clone() }, None) - .into(); + request_legacy(writer, reader, Request::ListMacros { dylib_path: dylib_path.clone() }); assert!(matches!(response3, Response::ListMacros(Ok(_)))); }); } @@ -195,7 +192,7 @@ fn test_expand_nonexistent_macro() { with_server(JsonLegacy, |writer, reader| { let dylib_path = proc_macro_test_dylib_path(); - let version_response = request(writer, reader, Request::ApiVersionCheck {}, None).into(); + let version_response = request_legacy(writer, reader, Request::ApiVersionCheck {}); let Response::ApiVersionCheck(version) = version_response else { panic!("expected version check response"); }; @@ -221,7 +218,7 @@ fn test_expand_nonexistent_macro() { }, })); - let response = request(writer, reader, expand_request, None).into(); + let response = request_legacy(writer, reader, expand_request); match response { Response::ExpandMacro(Err(PanicMessage(msg))) => { From 7ec34defe9e62a1a6946d3e700b5903d8dc89ece Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 19 Jan 2026 14:46:38 +1100 Subject: [PATCH 2328/3801] Temporarily re-export `assert_matches!` to reduce stabilization churn --- compiler/rustc_abi/src/extern_abi/tests.rs | 3 ++- compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs | 3 +-- compiler/rustc_borrowck/src/type_check/input_output.rs | 3 +-- compiler/rustc_builtin_macros/src/test.rs | 2 +- compiler/rustc_codegen_llvm/src/asm.rs | 3 +-- compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs | 2 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/builder.rs | 2 +- compiler/rustc_const_eval/src/check_consts/check.rs | 2 +- compiler/rustc_const_eval/src/interpret/call.rs | 2 +- compiler/rustc_const_eval/src/interpret/cast.rs | 3 +-- compiler/rustc_const_eval/src/interpret/eval_context.rs | 3 +-- compiler/rustc_const_eval/src/interpret/intrinsics.rs | 3 +-- compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs | 3 ++- compiler/rustc_const_eval/src/interpret/memory.rs | 2 +- compiler/rustc_const_eval/src/interpret/operand.rs | 3 +-- compiler/rustc_const_eval/src/interpret/place.rs | 3 +-- compiler/rustc_data_structures/src/graph/scc/mod.rs | 2 +- compiler/rustc_data_structures/src/lib.rs | 5 +++++ compiler/rustc_errors/src/lib.rs | 3 +-- compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/rustc_hir_analysis/src/collect/generics_of.rs | 2 +- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 3 +-- compiler/rustc_hir_analysis/src/delegation.rs | 3 +-- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 3 +-- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- compiler/rustc_infer/src/infer/outlives/verify.rs | 3 +-- compiler/rustc_infer/src/infer/snapshot/undo_log.rs | 3 +-- compiler/rustc_lint/src/impl_trait_overcaptures.rs | 2 +- compiler/rustc_middle/src/ty/consts/kind.rs | 3 +-- compiler/rustc_middle/src/ty/context.rs | 3 +-- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_mir_build/src/builder/coverageinfo.rs | 2 +- compiler/rustc_mir_build/src/builder/expr/as_place.rs | 2 +- compiler/rustc_mir_build/src/builder/matches/mod.rs | 2 +- compiler/rustc_mir_build/src/builder/matches/user_ty.rs | 2 +- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 2 +- compiler/rustc_mir_build/src/thir/util.rs | 3 +-- compiler/rustc_mir_dataflow/src/impls/initialized.rs | 3 +-- compiler/rustc_mir_dataflow/src/value_analysis.rs | 2 +- compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 2 +- compiler/rustc_mir_transform/src/inline.rs | 2 +- compiler/rustc_mir_transform/src/promote_consts.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 2 +- compiler/rustc_parse/src/parser/mod.rs | 2 +- compiler/rustc_parse/src/parser/tests.rs | 2 +- compiler/rustc_query_system/src/dep_graph/graph.rs | 3 +-- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_symbol_mangling/src/export.rs | 3 +-- .../src/error_reporting/traits/suggestions.rs | 2 +- compiler/rustc_trait_selection/src/solve/inspect/analyse.rs | 3 +-- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- compiler/rustc_ty_utils/src/abi.rs | 2 +- compiler/rustc_ty_utils/src/layout/invariant.rs | 3 +-- 58 files changed, 64 insertions(+), 79 deletions(-) diff --git a/compiler/rustc_abi/src/extern_abi/tests.rs b/compiler/rustc_abi/src/extern_abi/tests.rs index fc546a6570f0..8b9353ccae97 100644 --- a/compiler/rustc_abi/src/extern_abi/tests.rs +++ b/compiler/rustc_abi/src/extern_abi/tests.rs @@ -1,6 +1,7 @@ -use std::assert_matches::assert_matches; use std::str::FromStr; +use rustc_data_structures::assert_matches; + use super::*; #[allow(non_snake_case)] diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 743a28822eb9..8f643d8f460f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -3,8 +3,7 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -use std::assert_matches::assert_matches; - +use rustc_data_structures::assert_matches; use rustc_errors::{Applicability, Diag, EmissionGuarantee}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index eb31b5de05d2..f3b9dcc90a84 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -7,9 +7,8 @@ //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! contain revealed `impl Trait` values). -use std::assert_matches::assert_matches; - use itertools::Itertools; +use rustc_data_structures::assert_matches; use rustc_hir as hir; use rustc_infer::infer::{BoundRegionConversionTime, RegionVariableOrigin}; use rustc_middle::mir::*; diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 6f14385d5d30..d5f774865a9e 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -1,12 +1,12 @@ //! The expansion from a test function to the appropriate test struct for libtest //! Ideally, this code would be in libtest but for efficiency and error messages it lives here. -use std::assert_matches::assert_matches; use std::iter; use rustc_ast::{self as ast, GenericParamKind, HasNodeId, attr, join_path_idents}; use rustc_ast_pretty::pprust; use rustc_attr_parsing::AttributeParser; +use rustc_data_structures::assert_matches; use rustc_errors::{Applicability, Diag, Level}; use rustc_expand::base::*; use rustc_hir::Attribute; diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index ee1b6d45e149..7f02518d6c0d 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -1,9 +1,8 @@ -use std::assert_matches::assert_matches; - use rustc_abi::{BackendRepr, Float, Integer, Primitive, Scalar}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_codegen_ssa::mir::operand::OperandValue; use rustc_codegen_ssa::traits::*; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::Instance; use rustc_middle::ty::layout::TyAndLayout; diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index a728f3ea1e66..b27b1a88f133 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -1,9 +1,9 @@ -use std::assert_matches::assert_matches; use std::sync::Arc; use itertools::Itertools; use rustc_abi::Align; use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods}; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxIndexMap; use rustc_index::IndexVec; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index c6aae89f1e51..565db7d298bc 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1,4 +1,3 @@ -use std::assert_matches::assert_matches; use std::cmp::Ordering; use std::ffi::c_uint; use std::ptr; @@ -13,6 +12,7 @@ use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphizati use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; use rustc_codegen_ssa::traits::*; +use rustc_data_structures::assert_matches; use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::{self as hir}; use rustc_middle::mir::BinOp; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 3e36bd8552b1..53121fc6275b 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1,4 +1,3 @@ -use std::assert_matches::assert_matches; use std::marker::PhantomData; use std::panic::AssertUnwindSafe; use std::path::{Path, PathBuf}; @@ -8,6 +7,7 @@ use std::{fs, io, mem, str, thread}; use rustc_abi::Size; use rustc_ast::attr; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::{self, Acquired}; use rustc_data_structures::memmap::Mmap; diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 4f45c614e003..ba36188f05d1 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -1,7 +1,7 @@ -use std::assert_matches::assert_matches; use std::ops::Deref; use rustc_abi::{Align, Scalar, Size, WrappingRange}; +use rustc_data_structures::assert_matches; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 3a85ca3760d2..95dbf42d4d44 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -1,11 +1,11 @@ //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. -use std::assert_matches::assert_matches; use std::borrow::Cow; use std::mem; use std::num::NonZero; use std::ops::Deref; +use rustc_data_structures::assert_matches; use rustc_errors::{Diag, ErrorGuaranteed}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 94c6fd1b3238..9c8ca44c5e8f 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -1,10 +1,10 @@ //! Manages calling a concrete function (with known MIR body) with argument passing, //! and returning the return value to the caller. -use std::assert_matches::assert_matches; use std::borrow::Cow; use either::{Left, Right}; use rustc_abi::{self as abi, ExternAbi, FieldIdx, Integer, VariantIdx}; +use rustc_data_structures::assert_matches; use rustc_hir::def_id::DefId; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef}; diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 3485a5c625ba..43de2e7f078a 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -1,8 +1,7 @@ -use std::assert_matches::assert_matches; - use rustc_abi::{FieldIdx, Integer}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, FloatConvert}; +use rustc_data_structures::assert_matches; use rustc_middle::mir::CastKind; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::ty::adjustment::PointerCoercion; diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d23369caffa4..aeadf0257ea8 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -1,7 +1,6 @@ -use std::assert_matches::debug_assert_matches; - use either::{Left, Right}; use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout}; +use rustc_data_structures::debug_assert_matches; use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::DefId; use rustc_hir::limit::Limit; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index fe1dd1b6eb35..e526f6120689 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -4,10 +4,9 @@ mod simd; -use std::assert_matches::assert_matches; - use rustc_abi::{FIRST_VARIANT, FieldIdx, HasDataLayout, Size, VariantIdx}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; +use rustc_data_structures::assert_matches; use rustc_hir::def_id::CRATE_DEF_ID; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint}; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index 33a115384a88..d7fe7801fb08 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -2,6 +2,7 @@ use either::Either; use rustc_abi::{BackendRepr, Endian}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, Round}; +use rustc_data_structures::assert_matches; use rustc_middle::mir::interpret::{InterpErrorKind, Pointer, UndefinedBehaviorInfo}; use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign}; use rustc_middle::{bug, err_ub_format, mir, span_bug, throw_unsup_format, ty}; @@ -10,7 +11,7 @@ use tracing::trace; use super::{ ImmTy, InterpCx, InterpResult, Machine, MinMax, MulAddType, OpTy, PlaceTy, Provenance, Scalar, - Size, TyAndLayout, assert_matches, interp_ok, throw_ub_format, + Size, TyAndLayout, interp_ok, throw_ub_format, }; use crate::interpret::Writeable; diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 862fe4779080..a6c8b28cce9f 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -6,7 +6,6 @@ //! integer. It is crucial that these operations call `check_align` *before* //! short-circuiting the empty case! -use std::assert_matches::assert_matches; use std::borrow::{Borrow, Cow}; use std::cell::Cell; use std::collections::VecDeque; @@ -14,6 +13,7 @@ use std::{fmt, ptr}; use rustc_abi::{Align, HasDataLayout, Size}; use rustc_ast::Mutability; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_middle::mir::display_allocation; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 9a956259ba57..e8e77de8eb3e 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -1,11 +1,10 @@ //! Functions concerning immediate values and operands, and reading from operands. //! All high-level functions to read from memory work on operands as sources. -use std::assert_matches::assert_matches; - use either::{Either, Left, Right}; use rustc_abi as abi; use rustc_abi::{BackendRepr, HasDataLayout, Size}; +use rustc_data_structures::assert_matches; use rustc_hir::def::Namespace; use rustc_middle::mir::interpret::ScalarSizeMismatch; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout}; diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index a409c7fad417..d472c14253b5 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -2,10 +2,9 @@ //! into a place. //! All high-level functions to write to memory work on places as destinations. -use std::assert_matches::assert_matches; - use either::{Either, Left, Right}; use rustc_abi::{BackendRepr, HasDataLayout, Size}; +use rustc_data_structures::assert_matches; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, mir, span_bug}; diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 1882e6e835a4..91cbe3c533bb 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -8,7 +8,6 @@ //! Typical examples would include: minimum element in SCC, maximum element //! reachable from it, etc. -use std::assert_matches::debug_assert_matches; use std::fmt::Debug; use std::marker::PhantomData; use std::ops::Range; @@ -16,6 +15,7 @@ use std::ops::Range; use rustc_index::{Idx, IndexSlice, IndexVec}; use tracing::{debug, instrument, trace}; +use crate::debug_assert_matches; use crate::fx::FxHashSet; use crate::graph::vec_graph::VecGraph; use crate::graph::{DirectedGraph, NumEdges, Successors}; diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index ff1dd41c82cc..8377213850b8 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -38,6 +38,11 @@ #![feature(unwrap_infallible)] // tidy-alphabetical-end +// Temporarily re-export `assert_matches!`, so that the rest of the compiler doesn't +// have to worry about it being moved to a different module in std during stabilization. +// FIXME(#151359): Remove this when `feature(assert_matches)` is stable in stage0. +// (This doesn't necessarily need to be fixed during the beta bump itself.) +pub use std::assert_matches::{assert_matches, debug_assert_matches}; use std::fmt; pub use atomic_ref::AtomicRef; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 148368045f4f..ce40f3ae8bf8 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -23,7 +23,6 @@ extern crate self as rustc_errors; -use std::assert_matches::assert_matches; use std::backtrace::{Backtrace, BacktraceStatus}; use std::borrow::Cow; use std::cell::Cell; @@ -55,10 +54,10 @@ pub use diagnostic_impls::{ }; pub use emitter::ColorConfig; use emitter::{ConfusionType, DynEmitter, Emitter, detect_confusion_type, is_different}; -use rustc_data_structures::AtomicRef; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{DynSend, Lock}; +use rustc_data_structures::{AtomicRef, assert_matches}; pub use rustc_error_messages::{ DiagArg, DiagArgFromDisplay, DiagArgName, DiagArgValue, DiagMessage, FluentBundle, IntoDiagArg, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 2c0253409387..9c0b638c1482 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -14,13 +14,13 @@ //! At present, however, we do run collection across all items in the //! crate as a kind of pass. This should eventually be factored away. -use std::assert_matches::assert_matches; use std::cell::Cell; use std::iter; use std::ops::Bound; use rustc_abi::{ExternAbi, Size}; use rustc_ast::Recovered; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey, struct_span_code_err, diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 3d2f0466cad0..511d513216eb 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -1,6 +1,6 @@ -use std::assert_matches::assert_matches; use std::ops::ControlFlow; +use rustc_data_structures::assert_matches; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor, VisitorExt}; diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 178c47b09c84..a2236b426305 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -1,6 +1,5 @@ -use std::assert_matches::assert_matches; - use hir::Node; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::attrs::AttributeKind; diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index cf0533c39e73..f64341d755f8 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -2,8 +2,7 @@ //! //! For more information about delegation design, see the tracking issue #118212. -use std::assert_matches::debug_assert_matches; - +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; 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 6e1e6c157a91..924967b65c19 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -19,10 +19,10 @@ mod dyn_trait; pub mod errors; pub mod generics; -use std::assert_matches::assert_matches; use std::slice; use rustc_ast::LitKind; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{ diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index cadbc54c3410..f5c77c680000 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -8,9 +8,8 @@ //! specialization errors. These things can (and probably should) be //! fixed, but for the moment it's easier to do these checks early. -use std::assert_matches::debug_assert_matches; - use min_specialization::check_min_specialization; +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_errors::codes::*; diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index beb0337d8c59..ed71ad2119c9 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1,8 +1,8 @@ -use std::assert_matches::debug_assert_matches; use std::cell::{Cell, RefCell}; use std::cmp::max; use std::ops::Deref; +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; use rustc_errors::Applicability; diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index f67b99cb3f84..affeb01e6d05 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -1,5 +1,4 @@ -use std::assert_matches::assert_matches; - +use rustc_data_structures::assert_matches; use rustc_middle::ty::outlives::{Component, compute_alias_components_recursive}; use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt}; use smallvec::smallvec; diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index c859d64133c4..a6f324b70471 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -1,8 +1,7 @@ -use std::assert_matches::assert_matches; use std::marker::PhantomData; use rustc_data_structures::undo_log::{Rollback, UndoLogs}; -use rustc_data_structures::{snapshot_vec as sv, unify as ut}; +use rustc_data_structures::{assert_matches, snapshot_vec as sv, unify as ut}; use rustc_middle::ty::{self, OpaqueTypeKey, ProvisionalHiddenType}; use tracing::debug; diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 2fc9d562dc56..f6c2e5946079 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -1,6 +1,6 @@ -use std::assert_matches::debug_assert_matches; use std::cell::LazyCell; +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordSet; use rustc_errors::{LintDiagnostic, Subdiagnostic}; diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index b3436550e8e0..c9ccb9bd0b3e 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -1,5 +1,4 @@ -use std::assert_matches::assert_matches; - +use rustc_data_structures::assert_matches; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use super::Const; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e9fa3f14358e..a5aead9829f1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -4,7 +4,6 @@ pub mod tls; -use std::assert_matches::debug_assert_matches; use std::borrow::{Borrow, Cow}; use std::cmp::Ordering; use std::env::VarError; @@ -17,7 +16,6 @@ use std::{fmt, iter, mem}; use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx}; use rustc_ast as ast; -use rustc_data_structures::defer; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; @@ -29,6 +27,7 @@ use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{ self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal, }; +use rustc_data_structures::{debug_assert_matches, defer}; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan, }; diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index c27d47fcc0d8..0e9dd7dd169c 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -1,6 +1,6 @@ -use std::assert_matches::assert_matches; use std::fmt; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8eee114ead02..ce713dcf42f5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -11,7 +11,6 @@ #![allow(rustc::usage_of_ty_tykind)] -use std::assert_matches::assert_matches; use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::marker::PhantomData; @@ -31,6 +30,7 @@ use rustc_ast::AttrVec; use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree}; use rustc_ast::node_id::NodeMap; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c282f2211f65..34aca8adb4a0 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2,12 +2,12 @@ #![allow(rustc::usage_of_ty_tykind)] -use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::ops::{ControlFlow, Range}; use hir::def::{CtorKind, DefKind}; use rustc_abi::{FIRST_VARIANT, FieldIdx, ScalableElt, VariantIdx}; +use rustc_data_structures::debug_assert_matches; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::LangItem; diff --git a/compiler/rustc_mir_build/src/builder/coverageinfo.rs b/compiler/rustc_mir_build/src/builder/coverageinfo.rs index 091b9dad5bc1..ae36b2fb7f38 100644 --- a/compiler/rustc_mir_build/src/builder/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/builder/coverageinfo.rs @@ -1,6 +1,6 @@ -use std::assert_matches::assert_matches; use std::collections::hash_map::Entry; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxHashMap; use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageInfoHi, CoverageKind}; use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp}; diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs index 139c6da29d44..172dbf7c31b5 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs @@ -1,9 +1,9 @@ //! See docs in build/expr/mod.rs -use std::assert_matches::assert_matches; use std::iter; use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; +use rustc_data_structures::assert_matches; use rustc_hir::def_id::LocalDefId; use rustc_middle::hir::place::{Projection as HirProjection, ProjectionKind as HirProjectionKind}; use rustc_middle::mir::AssertKind::BoundsCheck; diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 11a181cfa8ce..2f9486c2d552 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -5,13 +5,13 @@ //! This also includes code for pattern bindings in `let` statements and //! function parameters. -use std::assert_matches::debug_assert_matches; use std::borrow::Borrow; use std::mem; use std::sync::Arc; use itertools::{Itertools, Position}; use rustc_abi::{FIRST_VARIANT, VariantIdx}; +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::{BindingMode, ByRef, LangItem, LetStmt, LocalSource, Node}; diff --git a/compiler/rustc_mir_build/src/builder/matches/user_ty.rs b/compiler/rustc_mir_build/src/builder/matches/user_ty.rs index 2dcfd3772902..6ba5e360ef82 100644 --- a/compiler/rustc_mir_build/src/builder/matches/user_ty.rs +++ b/compiler/rustc_mir_build/src/builder/matches/user_ty.rs @@ -4,10 +4,10 @@ //! This avoids having to repeatedly clone a partly-built [`UserTypeProjections`] //! at every step of the traversal, which is what the previous code was doing. -use std::assert_matches::assert_matches; use std::iter; use rustc_abi::{FieldIdx, VariantIdx}; +use rustc_data_structures::assert_matches; use rustc_data_structures::smallvec::SmallVec; use rustc_middle::mir::{ProjectionElem, UserTypeProjection, UserTypeProjections}; use rustc_middle::ty::{AdtDef, UserTypeAnnotationIndex}; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 650650cbaac9..d0abb6396145 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -4,11 +4,11 @@ mod check_match; mod const_to_pat; mod migration; -use std::assert_matches::assert_matches; use std::cmp::Ordering; use std::sync::Arc; use rustc_abi::{FieldIdx, Integer}; +use rustc_data_structures::assert_matches; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs index 457957f5fce9..0093bb762110 100644 --- a/compiler/rustc_mir_build/src/thir/util.rs +++ b/compiler/rustc_mir_build/src/thir/util.rs @@ -1,5 +1,4 @@ -use std::assert_matches::assert_matches; - +use rustc_data_structures::assert_matches; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_middle::bug; diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index 9216106b6edd..6a0881ec2bcb 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -1,6 +1,5 @@ -use std::assert_matches::assert_matches; - use rustc_abi::VariantIdx; +use rustc_data_structures::assert_matches; use rustc_index::Idx; use rustc_index::bit_set::{DenseBitSet, MixedBitSet}; use rustc_middle::bug; diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index ac94ee5c8104..f102b7bb50f5 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -1,8 +1,8 @@ -use std::assert_matches::debug_assert_matches; use std::fmt::{Debug, Formatter}; use std::ops::Range; use rustc_abi::{FieldIdx, VariantIdx}; +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::{FxHashMap, FxIndexSet, StdEntry}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_index::IndexVec; diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 5254f60a1503..604f1da1a3ab 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -2,7 +2,6 @@ //! //! Currently, this pass only propagates scalar values. -use std::assert_matches::assert_matches; use std::cell::RefCell; use std::fmt::Formatter; @@ -11,6 +10,7 @@ use rustc_const_eval::const_eval::{DummyMachine, throw_machine_stop_str}; use rustc_const_eval::interpret::{ ImmTy, Immediate, InterpCx, OpTy, PlaceTy, Projectable, interp_ok, }; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; use rustc_middle::bug; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 1e9665f4337d..179ada36be75 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -1,10 +1,10 @@ //! Inlining pass for MIR functions. -use std::assert_matches::debug_assert_matches; use std::iter; use std::ops::{Range, RangeFrom}; use rustc_abi::{ExternAbi, FieldIdx}; +use rustc_data_structures::debug_assert_matches; use rustc_hir::attrs::{InlineAttr, OptimizeAttr}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 11266ccc2832..2cc8e9d6739c 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -10,12 +10,12 @@ //! otherwise silence errors, if move analysis runs after promotion on broken //! MIR. -use std::assert_matches::assert_matches; use std::cell::Cell; use std::{cmp, iter, mem}; use either::{Left, Right}; use rustc_const_eval::check_consts::{ConstCx, qualifs}; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_index::{IndexSlice, IndexVec}; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 85e340c0a02a..cc1cb3d4f3ff 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -1,7 +1,7 @@ -use std::assert_matches::assert_matches; use std::{fmt, iter}; use rustc_abi::{ExternAbi, FIRST_VARIANT, FieldIdx, VariantIdx}; +use rustc_data_structures::assert_matches; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index d6e99bc540f7..c1ab8d76380a 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -16,7 +16,6 @@ mod ty; pub mod asm; pub mod cfg_select; -use std::assert_matches::debug_assert_matches; use std::{fmt, mem, slice}; use attr_wrapper::{AttrWrapper, UsePreAttrPos}; @@ -40,6 +39,7 @@ use rustc_ast::{ Mutability, Recovered, Safety, StrLit, Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, Diag, FatalError, MultiSpan, PResult}; use rustc_index::interval::IntervalSet; diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 62e97c0c308c..2e1acca9e9af 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -1,5 +1,4 @@ #![allow(rustc::symbol_intern_string_literal)] -use std::assert_matches::assert_matches; use std::io::prelude::*; use std::iter::Peekable; use std::path::PathBuf; @@ -11,6 +10,7 @@ use rustc_ast::token::{self, Delimiter, Token}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::{self as ast, PatKind, visit}; use rustc_ast_pretty::pprust::item_to_string; +use rustc_data_structures::assert_matches; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::emitter::{HumanEmitter, OutputTheme}; use rustc_errors::translation::Translator; diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 0b50d376b552..f32f3f78c04b 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1,4 +1,3 @@ -use std::assert_matches::assert_matches; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; @@ -7,12 +6,12 @@ use std::sync::atomic::{AtomicU32, Ordering}; use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::outline; use rustc_data_structures::profiling::QueryInvocationId; use rustc_data_structures::sharded::{self, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU64, Lock}; use rustc_data_structures::unord::UnordMap; +use rustc_data_structures::{assert_matches, outline}; use rustc_errors::DiagInner; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable}; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6557e1dea1a1..963bee369f6b 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -6,7 +6,6 @@ //! If you wonder why there's no `early.rs`, that's because it's split into three files - //! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`. -use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::collections::hash_map::Entry; use std::mem::{replace, swap, take}; @@ -16,6 +15,7 @@ use rustc_ast::visit::{ AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, try_visit, visit_opt, walk_list, }; use rustc_ast::*; +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::codes::*; diff --git a/compiler/rustc_symbol_mangling/src/export.rs b/compiler/rustc_symbol_mangling/src/export.rs index 3896e06a627b..c99ba1d58f31 100644 --- a/compiler/rustc_symbol_mangling/src/export.rs +++ b/compiler/rustc_symbol_mangling/src/export.rs @@ -1,6 +1,5 @@ -use std::assert_matches::debug_assert_matches; - use rustc_abi::IntegerType; +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::stable_hasher::StableHasher; use rustc_hashes::Hash128; use rustc_hir::def::DefKind; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ef50dafec950..1c08b5e33142 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1,12 +1,12 @@ // ignore-tidy-filelength -use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::iter; use std::path::PathBuf; use itertools::{EitherOrBoth, Itertools}; use rustc_abi::ExternAbi; +use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::codes::*; diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 944d57bf95d1..ea8360c10b6f 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -9,8 +9,7 @@ //! coherence right now and was annoying to implement, so I am leaving it //! as is until we start using it for something else. -use std::assert_matches::assert_matches; - +use rustc_data_structures::assert_matches; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::Obligation; use rustc_macros::extension; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index d6c9adfb2817..787dd4ea6254 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2,13 +2,13 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html#selection -use std::assert_matches::assert_matches; use std::cell::{Cell, RefCell}; use std::cmp; use std::fmt::{self, Display}; use std::ops::ControlFlow; use hir::def::DefKind; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Diag, EmissionGuarantee}; diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index ad621c67772c..34c080c4938f 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -1,8 +1,8 @@ -use std::assert_matches::assert_matches; use std::iter; use rustc_abi::Primitive::Pointer; use rustc_abi::{BackendRepr, ExternAbi, PointerKind, Scalar, Size}; +use rustc_data_structures::assert_matches; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_middle::bug; diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index b013902f3fe3..97c98d0c2403 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -1,6 +1,5 @@ -use std::assert_matches::assert_matches; - use rustc_abi::{BackendRepr, FieldsShape, Scalar, Size, TagEncoding, Variants}; +use rustc_data_structures::assert_matches; use rustc_middle::bug; use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, TyAndLayout}; From 29aad0493b082c5d36a006fa39656d61b2c3ddc3 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 19 Jan 2026 09:58:15 +0200 Subject: [PATCH 2329/3801] Cache `Clauses::empty()` --- .../rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs index 5758e2dc7e93..6f4fae707317 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs @@ -273,9 +273,8 @@ impl<'db> std::fmt::Debug for Clauses<'db> { impl<'db> Clauses<'db> { #[inline] - pub fn empty(_interner: DbInterner<'db>) -> Self { - // FIXME: Get from a static. - Self::new_from_slice(&[]) + pub fn empty(interner: DbInterner<'db>) -> Self { + interner.default_types().empty.clauses } #[inline] From 03b8b68073bd9273b9614830aaefe5b7f5d603c3 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sun, 18 Jan 2026 20:30:48 +0100 Subject: [PATCH 2330/3801] Port `#[rustc_nounwind]` to attr parser --- .../src/attributes/rustc_internal.rs | 15 +++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 5 +++-- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 +++- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 834b1d988cb4..f8ee011f559b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -320,3 +320,18 @@ impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParse ]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHasIncoherentInherentImpls; } + +pub(crate) struct RustcNounwindParser; + +impl NoArgsAttributeParser for RustcNounwindParser { + const PATH: &[Symbol] = &[sym::rustc_nounwind]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::ForeignFn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Method(MethodKind::Trait { body: true })), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNounwind; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 1a06f4edeaa6..e62dbc124eab 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -78,8 +78,8 @@ use crate::attributes::rustc_internal::{ RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser, - RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, - RustcSimdMonomorphizeLaneLimitParser, + RustcNoImplicitAutorefsParser, RustcNounwindParser, RustcObjectLifetimeDefaultParser, + RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -296,6 +296,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 1b0427e7e676..e29ba9c8725f 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -347,6 +347,9 @@ fn process_builtin_attrs( AttributeKind::RustcAllocatorZeroed => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } + AttributeKind::RustcNounwind => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND + } _ => {} } } @@ -356,7 +359,6 @@ fn process_builtin_attrs( }; match name { - sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, sym::patchable_function_entry => { codegen_fn_attrs.patchable_function_entry = parse_patchable_function_entry(tcx, attr); diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 5cd508acc567..379ebf648f47 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -981,6 +981,9 @@ pub enum AttributeKind { /// Represents `#[rustc_no_implicit_autorefs]` RustcNoImplicitAutorefs, + /// Represents `#[rustc_nounwind]` + RustcNounwind, + /// Represents `#[rustc_object_lifetime_default]`. RustcObjectLifetimeDefault, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 19243c7d8468..44f040e5fdc8 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -122,6 +122,7 @@ impl AttributeKind { RustcMustImplementOneOf { .. } => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes, + RustcNounwind => No, RustcObjectLifetimeDefault => No, RustcPassIndirectlyInNonRusticAbis(..) => No, RustcReallocator => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3a086ba5ff78..74edff7badba 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -322,6 +322,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcAllocatorZeroedVariant { .. } | AttributeKind::RustcDeallocator | AttributeKind::RustcReallocator + | AttributeKind::RustcNounwind ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -390,7 +391,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_partition_reused | sym::rustc_partition_codegened | sym::rustc_expected_cgu_reuse - | sym::rustc_nounwind // crate-level attrs, are checked below | sym::feature | sym::register_tool From 3e731f7e84301a898a36e46ee5e4845ff9bda98a Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sun, 18 Jan 2026 20:41:29 +0100 Subject: [PATCH 2331/3801] Port `#[rustc_offload_kernel]` to attr parser --- .../rustc_attr_parsing/src/attributes/rustc_internal.rs | 9 +++++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 6 +++--- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 1 + 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index f8ee011f559b..51792b7aff72 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -335,3 +335,12 @@ impl NoArgsAttributeParser for RustcNounwindParser { ]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNounwind; } + +pub(crate) struct RustcOffloadKernelParser; + +impl NoArgsAttributeParser for RustcOffloadKernelParser { + const PATH: &[Symbol] = &[sym::rustc_offload_kernel]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOffloadKernel; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index e62dbc124eab..0c882fee01c8 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -79,7 +79,7 @@ use crate::attributes::rustc_internal::{ RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, RustcNounwindParser, RustcObjectLifetimeDefaultParser, - RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, + RustcOffloadKernelParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -297,6 +297,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index e29ba9c8725f..e35d884b6711 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -350,6 +350,9 @@ fn process_builtin_attrs( AttributeKind::RustcNounwind => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND } + AttributeKind::RustcOffloadKernel => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::OFFLOAD_KERNEL + } _ => {} } } @@ -363,9 +366,6 @@ fn process_builtin_attrs( codegen_fn_attrs.patchable_function_entry = parse_patchable_function_entry(tcx, attr); } - sym::rustc_offload_kernel => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::OFFLOAD_KERNEL - } _ => {} } } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 379ebf648f47..314f36d6132d 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -987,6 +987,9 @@ pub enum AttributeKind { /// Represents `#[rustc_object_lifetime_default]`. RustcObjectLifetimeDefault, + /// Represents `#[rustc_offload_kernel]` + RustcOffloadKernel, + /// Represents `#[rustc_pass_indirectly_in_non_rustic_abis]` RustcPassIndirectlyInNonRusticAbis(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 44f040e5fdc8..b55a5d0e29e1 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -124,6 +124,7 @@ impl AttributeKind { RustcNoImplicitAutorefs => Yes, RustcNounwind => No, RustcObjectLifetimeDefault => No, + RustcOffloadKernel => Yes, RustcPassIndirectlyInNonRusticAbis(..) => No, RustcReallocator => No, RustcScalableVector { .. } => Yes, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 74edff7badba..8074ae429892 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -323,6 +323,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDeallocator | AttributeKind::RustcReallocator | AttributeKind::RustcNounwind + | AttributeKind::RustcOffloadKernel ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); From eeed3376e25905b6b1b42ee1fa1af2e75f4482f0 Mon Sep 17 00:00:00 2001 From: KaiTomotake Date: Mon, 19 Jan 2026 17:06:07 +0900 Subject: [PATCH 2332/3801] add test program A test for the issue where the variable meta is mistakenly treated as a reserved keyword. --- tests/ui/reserved/meta-is-not-reserved.rs | 7 +++++++ tests/ui/reserved/meta-is-not-reserved.stderr | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/ui/reserved/meta-is-not-reserved.rs create mode 100644 tests/ui/reserved/meta-is-not-reserved.stderr diff --git a/tests/ui/reserved/meta-is-not-reserved.rs b/tests/ui/reserved/meta-is-not-reserved.rs new file mode 100644 index 000000000000..ceefe345ff0c --- /dev/null +++ b/tests/ui/reserved/meta-is-not-reserved.rs @@ -0,0 +1,7 @@ +// Regression test for +// A test for the issue where the variable meta is mistakenly treated as a reserved keyword. + +fn main() { + let xyz = meta; + //~^ ERROR cannot find value `meta` in this scope [E0425] +} diff --git a/tests/ui/reserved/meta-is-not-reserved.stderr b/tests/ui/reserved/meta-is-not-reserved.stderr new file mode 100644 index 000000000000..33f8fd82df85 --- /dev/null +++ b/tests/ui/reserved/meta-is-not-reserved.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `meta` in this scope + --> $DIR/meta-is-not-reserved.rs:5:15 + | +LL | let xyz = meta; + | ^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. From 345e9a089bde20917fb7cf1f9db5092d69d70b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 16 Jan 2026 22:04:53 +0100 Subject: [PATCH 2333/3801] Document `-Zcache-proc-macros` --- .../src/compiler-flags/cache-proc-macros.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/doc/unstable-book/src/compiler-flags/cache-proc-macros.md diff --git a/src/doc/unstable-book/src/compiler-flags/cache-proc-macros.md b/src/doc/unstable-book/src/compiler-flags/cache-proc-macros.md new file mode 100644 index 000000000000..eefaf9ca2f1b --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/cache-proc-macros.md @@ -0,0 +1,9 @@ +## `cache-proc-macros` + +The tracking issue for this feature is: [#151364] + +[#151364]: https://github.com/rust-lang/rust/issues/151364 + +------------------------ + +This option instructs `rustc` to cache (derive) proc-macro invocations using the incremental system. Note that the compiler does not currently check whether the proc-macro is actually "cacheable" or not. If you use this flag when compiling a crate that uses non-pure proc-macros, it can result in stale expansions being compiled. From 67c45b739af089b9c8d96f0706c22b899a2ac324 Mon Sep 17 00:00:00 2001 From: JayanAXHF Date: Sat, 10 Jan 2026 01:37:51 +0530 Subject: [PATCH 2334/3801] feat: added syntax highlighting for code blocks in `rustc --explain` This commit adds a heuristics-based syntax highlighter for the `rustc --explain` command. It uses `rsutc_lexer`'s lexer to parse input in tokens, and matches on them to determine their color. --- Cargo.lock | 2 + compiler/rustc_driver_impl/Cargo.toml | 2 + compiler/rustc_driver_impl/src/highlighter.rs | 159 ++++++++++++++++++ compiler/rustc_driver_impl/src/lib.rs | 7 +- compiler/rustc_errors/src/markdown/mod.rs | 11 +- compiler/rustc_errors/src/markdown/term.rs | 41 +++-- .../src/markdown/tests/output.stdout | 10 +- .../rustc_errors/src/markdown/tests/term.rs | 2 +- tests/ui-fulldeps/explain_highlighter.rs | 29 ++++ .../explain_highlighter.run.stdout | 12 ++ 10 files changed, 249 insertions(+), 26 deletions(-) create mode 100644 compiler/rustc_driver_impl/src/highlighter.rs create mode 100644 tests/ui-fulldeps/explain_highlighter.rs create mode 100644 tests/ui-fulldeps/explain_highlighter.run.stdout diff --git a/Cargo.lock b/Cargo.lock index 470b38d5a91c..2d23541b4314 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3809,6 +3809,7 @@ dependencies = [ name = "rustc_driver_impl" version = "0.0.0" dependencies = [ + "anstyle", "ctrlc", "jiff", "libc", @@ -3834,6 +3835,7 @@ dependencies = [ "rustc_index", "rustc_infer", "rustc_interface", + "rustc_lexer", "rustc_lint", "rustc_log", "rustc_macros", diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 531b9e0c8ff7..c160240a18a7 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start +anstyle = "1.0.13" jiff = { version = "0.2.5", default-features = false, features = ["std"] } rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } @@ -28,6 +29,7 @@ rustc_incremental = { path = "../rustc_incremental" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_interface = { path = "../rustc_interface" } +rustc_lexer = { path = "../rustc_lexer" } rustc_lint = { path = "../rustc_lint" } rustc_log = { path = "../rustc_log" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_driver_impl/src/highlighter.rs b/compiler/rustc_driver_impl/src/highlighter.rs new file mode 100644 index 000000000000..70b73cc29b72 --- /dev/null +++ b/compiler/rustc_driver_impl/src/highlighter.rs @@ -0,0 +1,159 @@ +//! This module provides a syntax highlighter for Rust code. +//! It is used by the `rustc --explain` command. +//! +//! The syntax highlighter uses `rustc_lexer`'s `tokenize` +//! function to parse the Rust code into a `Vec` of tokens. +//! The highlighter then highlights the tokens in the `Vec`, +//! and writes the highlighted output to the buffer. +use std::io::{self, Write}; + +use anstyle::{AnsiColor, Color, Effects, Style}; +use rustc_lexer::{LiteralKind, strip_shebang, tokenize}; + +const PRIMITIVE_TYPES: &'static [&str] = &[ + "i8", "i16", "i32", "i64", "i128", "isize", // signed integers + "u8", "u16", "u32", "u64", "u128", "usize", // unsigned integers + "f32", "f64", // floating point + "char", "bool", // others +]; + +const KEYWORDS: &'static [&str] = &[ + "static", "struct", "super", "trait", "true", "type", "unsafe", "use", "where", "while", "as", + "async", "await", "break", "const", "continue", "crate", "dyn", "else", "enum", "extern", + "false", "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", + "ref", +]; + +const STR_LITERAL_COLOR: AnsiColor = AnsiColor::Green; +const OTHER_LITERAL_COLOR: AnsiColor = AnsiColor::BrightRed; +const DERIVE_COLOR: AnsiColor = AnsiColor::BrightRed; +const KEYWORD_COLOR: AnsiColor = AnsiColor::BrightMagenta; +const TYPE_COLOR: AnsiColor = AnsiColor::Yellow; +const FUNCTION_COLOR: AnsiColor = AnsiColor::Blue; +const USE_COLOR: AnsiColor = AnsiColor::BrightMagenta; +const PRIMITIVE_TYPE_COLOR: AnsiColor = AnsiColor::Cyan; + +/// Highlight a Rust code string and write the highlighted +/// output to the buffer. It serves as a wrapper around +/// `Highlighter::highlight_rustc_lexer`. It is passed to +/// `write_anstream_buf` in the `lib.rs` file. +pub fn highlight(code: &str, buf: &mut Vec) -> io::Result<()> { + let mut highlighter = Highlighter::default(); + highlighter.highlight_rustc_lexer(code, buf) +} + +/// A syntax highlighter for Rust code +/// It is used by the `rustc --explain` command. +#[derive(Default)] +pub struct Highlighter { + /// Used to track if the previous token was a token + /// that warrants the next token to be colored differently + /// + /// For example, the keyword `fn` requires the next token + /// (the function name) to be colored differently. + prev_was_special: bool, + /// Used to track the length of tokens that have been + /// written so far. This is used to find the original + /// lexeme for a token from the code string. + len_accum: usize, +} + +impl Highlighter { + /// Create a new highlighter + pub fn new() -> Self { + Self::default() + } + + /// Highlight a Rust code string and write the highlighted + /// output to the buffer. + pub fn highlight_rustc_lexer(&mut self, code: &str, buf: &mut Vec) -> io::Result<()> { + use rustc_lexer::TokenKind; + + // Remove shebang from code string + let stripped_idx = strip_shebang(code).unwrap_or(0); + let stripped_code = &code[stripped_idx..]; + self.len_accum = stripped_idx; + let len_accum = &mut self.len_accum; + let tokens = tokenize(stripped_code, rustc_lexer::FrontmatterAllowed::No); + for token in tokens { + let len = token.len as usize; + // If the previous token was a special token, and this token is + // not a whitespace token, then it should be colored differently + let token_str = &code[*len_accum..*len_accum + len]; + if self.prev_was_special { + if token_str != " " { + self.prev_was_special = false; + } + let style = Style::new().fg_color(Some(Color::Ansi(AnsiColor::Blue))); + write!(buf, "{style}{token_str}{style:#}")?; + *len_accum += len; + continue; + } + match token.kind { + TokenKind::Ident => { + let mut style = Style::new(); + // Match if an identifier is a (well-known) keyword + if KEYWORDS.contains(&token_str) { + if token_str == "fn" { + self.prev_was_special = true; + } + style = style.fg_color(Some(Color::Ansi(KEYWORD_COLOR))); + } + // The `use` keyword is colored differently + if matches!(token_str, "use") { + style = style.fg_color(Some(Color::Ansi(USE_COLOR))); + } + // This heuristic test is to detect if the identifier is + // a function call. If it is, then the function identifier is + // colored differently. + if code[*len_accum..*len_accum + len + 1].ends_with('(') { + style = style.fg_color(Some(Color::Ansi(FUNCTION_COLOR))); + } + // The `derive` keyword is colored differently. + if token_str == "derive" { + style = style.fg_color(Some(Color::Ansi(DERIVE_COLOR))); + } + // This heuristic test is to detect if the identifier is + // a type. If it is, then the identifier is colored differently. + if matches!(token_str.chars().next().map(|c| c.is_uppercase()), Some(true)) { + style = style.fg_color(Some(Color::Ansi(TYPE_COLOR))); + } + // This if statement is to detect if the identifier is a primitive type. + if PRIMITIVE_TYPES.contains(&token_str) { + style = style.fg_color(Some(Color::Ansi(PRIMITIVE_TYPE_COLOR))); + } + write!(buf, "{style}{token_str}{style:#}")?; + } + + // Color literals + TokenKind::Literal { kind, suffix_start: _ } => { + // Strings -> Green + // Chars -> Green + // Raw strings -> Green + // C strings -> Green + // Byte Strings -> Green + // Other literals -> Bright Red (Orage-esque) + let style = match kind { + LiteralKind::Str { terminated: _ } + | LiteralKind::Char { terminated: _ } + | LiteralKind::RawStr { n_hashes: _ } + | LiteralKind::CStr { terminated: _ } => { + Style::new().fg_color(Some(Color::Ansi(STR_LITERAL_COLOR))) + } + _ => Style::new().fg_color(Some(Color::Ansi(OTHER_LITERAL_COLOR))), + }; + write!(buf, "{style}{token_str}{style:#}")?; + } + _ => { + // All other tokens are dimmed + let style = Style::new() + .fg_color(Some(Color::Ansi(AnsiColor::BrightWhite))) + .effects(Effects::DIMMED); + write!(buf, "{style}{token_str}{style:#}")?; + } + } + *len_accum += len; + } + Ok(()) + } +} diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 7820198f2dcf..045292338e58 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -86,6 +86,7 @@ pub mod args; pub mod pretty; #[macro_use] mod print; +pub mod highlighter; mod session_diagnostics; // Keep the OS parts of this `cfg` in sync with the `cfg` on the `libc` @@ -521,7 +522,11 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { let mdstream = markdown::MdStream::parse_str(content); let bufwtr = markdown::create_stdout_bufwtr(); let mut mdbuf = Vec::new(); - if mdstream.write_anstream_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None } + if mdstream.write_anstream_buf(&mut mdbuf, Some(&highlighter::highlight)).is_ok() { + Some((bufwtr, mdbuf)) + } else { + None + } }; // Try to print via the pager, pretty output if possible. diff --git a/compiler/rustc_errors/src/markdown/mod.rs b/compiler/rustc_errors/src/markdown/mod.rs index 4f5e2328234d..9993407b05c0 100644 --- a/compiler/rustc_errors/src/markdown/mod.rs +++ b/compiler/rustc_errors/src/markdown/mod.rs @@ -18,9 +18,14 @@ impl<'a> MdStream<'a> { parse::entrypoint(s) } - /// Write formatted output to an anstream buffer - pub fn write_anstream_buf(&self, buf: &mut Vec) -> io::Result<()> { - term::entrypoint(self, buf) + /// Write formatted output to a stdout buffer, optionally with + /// a formatter for code blocks + pub fn write_anstream_buf( + &self, + buf: &mut Vec, + formatter: Option<&(dyn Fn(&str, &mut Vec) -> io::Result<()> + 'static)>, + ) -> io::Result<()> { + term::entrypoint(self, buf, formatter) } } diff --git a/compiler/rustc_errors/src/markdown/term.rs b/compiler/rustc_errors/src/markdown/term.rs index b0ce01548f00..b94cd06b30ef 100644 --- a/compiler/rustc_errors/src/markdown/term.rs +++ b/compiler/rustc_errors/src/markdown/term.rs @@ -12,29 +12,33 @@ thread_local! { static CURSOR: Cell = const { Cell::new(0) }; /// Width of the terminal static WIDTH: Cell = const { Cell::new(DEFAULT_COLUMN_WIDTH) }; + } -/// Print to terminal output to a buffer -pub(crate) fn entrypoint(stream: &MdStream<'_>, buf: &mut Vec) -> io::Result<()> { - #[cfg(not(test))] - if let Some((w, _)) = termize::dimensions() { - WIDTH.set(std::cmp::min(w, DEFAULT_COLUMN_WIDTH)); - } - write_stream(stream, buf, None, 0)?; +/// Print to the terminal output to a buffer +/// optionally with a formatter for code blocks +pub(crate) fn entrypoint( + stream: &MdStream<'_>, + buf: &mut Vec, + formatter: Option<&(dyn Fn(&str, &mut Vec) -> io::Result<()> + 'static)>, +) -> io::Result<()> { + write_stream(stream, buf, None, 0, formatter)?; buf.write_all(b"\n") } -/// Write the buffer, reset to the default style after each + +/// Write the buffer, reset to the default style after each, +/// optionally with a formatter for code blocks fn write_stream( MdStream(stream): &MdStream<'_>, buf: &mut Vec, + default: Option
    fn main() {
    -    let hello = "hello";
    -    let x = hello.to_string();
    -    let y = hello.to_string();
    +    let hello = "hello";
    +    let x = hello.to_string();
    +    let y = hello.to_string();
     
    -    let x = "other color please!";
    -    let y = x.to_string();
    +    let x = "other color please!";
    +    let y = x.to_string();
     }
     
     fn bar() {
    -    let mut hello = "hello";
    +    let mut hello = "hello";
     }
    \ No newline at end of file From 9a114c686f9e618a217f54920530bcbe66cb8a04 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 17:13:30 +0100 Subject: [PATCH 3339/3801] Convert to inline diagnostics in `rustc_parse` --- Cargo.lock | 1 - compiler/rustc_driver_impl/src/lib.rs | 1 - compiler/rustc_interface/src/interface.rs | 14 +- .../rustc_macros/src/diagnostics/message.rs | 3 +- compiler/rustc_parse/Cargo.toml | 1 - compiler/rustc_parse/messages.ftl | 1043 --------- compiler/rustc_parse/src/errors.rs | 2012 +++++++++++------ compiler/rustc_parse/src/lib.rs | 2 - compiler/rustc_parse/src/parser/attr.rs | 54 +- .../rustc_parse/src/parser/diagnostics.rs | 6 +- compiler/rustc_parse/src/parser/item.rs | 6 +- compiler/rustc_parse/src/parser/tests.rs | 24 +- compiler/rustc_session/src/parse.rs | 4 +- .../ui-fulldeps/mod_dir_path_canonicalized.rs | 2 +- tests/ui-fulldeps/pprust-expr-roundtrip.rs | 2 +- .../pprust-parenthesis-insertion.rs | 2 +- 16 files changed, 1401 insertions(+), 1776 deletions(-) delete mode 100644 compiler/rustc_parse/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 1d2289357300..54822628ca45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4381,7 +4381,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_index", "rustc_lexer", "rustc_macros", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3685d4ee7ebb..315b11056085 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -114,7 +114,6 @@ pub fn default_translator() -> Translator { pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ // tidy-alphabetical-start rustc_lint::DEFAULT_LOCALE_RESOURCE, - rustc_parse::DEFAULT_LOCALE_RESOURCE, // tidy-alphabetical-end ]; diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 3dbe1057c19d..722e9a420540 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -53,10 +53,9 @@ pub struct Compiler { pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec) -> Cfg { cfgs.into_iter() .map(|s| { - let psess = ParseSess::emitter_with_note( - vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], - format!("this occurred on the command line: `--cfg={s}`"), - ); + let psess = ParseSess::emitter_with_note(format!( + "this occurred on the command line: `--cfg={s}`" + )); let filename = FileName::cfg_spec_source_code(&s); macro_rules! error { @@ -125,10 +124,9 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec) -> Ch let mut check_cfg = CheckCfg { exhaustive_names, exhaustive_values, ..CheckCfg::default() }; for s in specs { - let psess = ParseSess::emitter_with_note( - vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], - format!("this occurred on the command line: `--check-cfg={s}`"), - ); + let psess = ParseSess::emitter_with_note(format!( + "this occurred on the command line: `--check-cfg={s}`" + )); let filename = FileName::cfg_spec_source_code(&s); const VISIT: &str = diff --git a/compiler/rustc_macros/src/diagnostics/message.rs b/compiler/rustc_macros/src/diagnostics/message.rs index 948cc9e93064..ad3ca4d1f8ea 100644 --- a/compiler/rustc_macros/src/diagnostics/message.rs +++ b/compiler/rustc_macros/src/diagnostics/message.rs @@ -3,6 +3,7 @@ use fluent_syntax::ast::{Expression, InlineExpression, Pattern, PatternElement}; use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::Path; +use syn::ext::IdentExt; use synstructure::{Structure, VariantInfo}; use crate::diagnostics::error::span_err; @@ -100,7 +101,7 @@ fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&Var .bindings() .iter() .flat_map(|b| b.ast().ident.as_ref()) - .map(|id| id.to_string()) + .map(|id| id.unraw().to_string()) .collect(); for variable in variable_references(&message) { if !fields.iter().any(|f| f == variable) { diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index f0c84e07a56f..28a67ae12126 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -12,7 +12,6 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl deleted file mode 100644 index 3f3300117460..000000000000 --- a/compiler/rustc_parse/messages.ftl +++ /dev/null @@ -1,1043 +0,0 @@ -parse_add_paren = try adding parentheses - -parse_ambiguous_range_pattern = the range pattern here has ambiguous interpretation -parse_ambiguous_range_pattern_suggestion = add parentheses to clarify the precedence - -parse_array_brackets_instead_of_braces = this is a block expression, not an array - .suggestion = to make an array, use square brackets instead of curly braces - -parse_array_index_offset_of = array indexing not supported in offset_of - -parse_asm_expected_comma = expected token: `,` - .label = expected `,` - -parse_asm_expected_other = expected operand, {$is_inline_asm -> - [false] options - *[true] clobber_abi, options - }, or additional template string - -parse_asm_expected_register_class_or_explicit_register = expected register class or explicit register - -parse_asm_expected_string_literal = expected string literal - .label = not a string literal - -parse_asm_non_abi = at least one abi must be provided as an argument to `clobber_abi` - -parse_asm_requires_template = requires at least a template string argument - -parse_asm_sym_no_path = expected a path for argument to `sym` - -parse_asm_underscore_input = _ cannot be used for input operands - -parse_asm_unsupported_operand = the `{$symbol}` operand cannot be used with `{$macro_name}!` - .label = the `{$symbol}` operand is not meaningful for global-scoped inline assembly, remove it - -parse_assignment_else_not_allowed = ... else {"{"} ... {"}"} is not allowed - -parse_associated_static_item_not_allowed = associated `static` items are not allowed - -parse_async_block_in_2015 = `async` blocks are only allowed in Rust 2018 or later - -parse_async_bound_modifier_in_2015 = `async` trait bounds are only allowed in Rust 2018 or later - -parse_async_fn_in_2015 = `async fn` is not permitted in Rust 2015 - .label = to use `async fn`, switch to Rust 2018 or later - -parse_async_impl = `async` trait implementations are unsupported - -parse_async_move_block_in_2015 = `async move` blocks are only allowed in Rust 2018 or later - -parse_async_move_order_incorrect = the order of `move` and `async` is incorrect - .suggestion = try switching the order - -parse_async_use_block_in_2015 = `async use` blocks are only allowed in Rust 2018 or later - -parse_async_use_order_incorrect = the order of `use` and `async` is incorrect - .suggestion = try switching the order - -parse_at_dot_dot_in_struct_pattern = `@ ..` is not supported in struct patterns - .suggestion = bind to each field separately or, if you don't need them, just remove `{$ident} @` - -parse_at_in_struct_pattern = unexpected `@` in struct pattern - .note = struct patterns use `field: pattern` syntax to bind to fields - .help = consider replacing `new_name @ field_name` with `field_name: new_name` if that is what you intended - -parse_attr_after_generic = trailing attribute after generic parameter - .label = attributes must go before parameters - -parse_attr_without_generics = attribute without generic parameters - .label = attributes are only permitted when preceding parameters - -parse_attribute_on_empty_type = attributes cannot be applied here - .label = attributes are not allowed here - -parse_attribute_on_generic_arg = attributes cannot be applied to generic arguments - .label = attributes are not allowed here - .suggestion = remove attribute from here - -parse_attribute_on_param_type = attributes cannot be applied to a function parameter's type - .label = attributes are not allowed here - -parse_attribute_on_type = attributes cannot be applied to types - .label = attributes are not allowed here - .suggestion = remove attribute from here - -parse_bad_assoc_type_bounds = bounds on associated types do not belong here - .label = belongs in `where` clause - -parse_bad_item_kind = {$descr} is not supported in {$ctx} - .help = consider moving the {$descr} out to a nearby module scope - -parse_bad_return_type_notation_output = - return type not allowed with return type notation - .suggestion = remove the return type - -parse_bare_cr = {$double_quotes -> - [true] bare CR not allowed in string, use `\r` instead - *[false] character constant must be escaped: `\r` - } - .escape = escape the character - -parse_bare_cr_in_frontmatter = bare CR not allowed in frontmatter - -parse_bare_cr_in_raw_string = bare CR not allowed in raw string - -parse_binder_and_polarity = `for<...>` binder not allowed with `{$polarity}` trait polarity modifier - .label = there is not a well-defined meaning for a higher-ranked `{$polarity}` trait - -parse_binder_before_modifiers = `for<...>` binder should be placed before trait bound modifiers - .label = place the `for<...>` binder before any modifiers - -parse_bounds_not_allowed_on_trait_aliases = bounds are not allowed on trait aliases - -parse_box_not_pat = expected pattern, found {$descr} - .note = `box` is a reserved keyword - .suggestion = escape `box` to use it as an identifier - -parse_box_syntax_removed = `box_syntax` has been removed -parse_box_syntax_removed_suggestion = use `Box::new()` instead - -parse_cannot_be_raw_ident = `{$ident}` cannot be a raw identifier - -parse_cannot_be_raw_lifetime = `{$ident}` cannot be a raw lifetime - -parse_catch_after_try = keyword `catch` cannot follow a `try` block - .help = try using `match` on the result of the `try` block instead - -parse_colon_as_semi = statements are terminated with a semicolon - .suggestion = use a semicolon instead - -parse_comma_after_base_struct = cannot use a comma after the base struct - .note = the base struct must always be the last field - .suggestion = remove this comma - -parse_comparison_interpreted_as_generic = - `<` is interpreted as a start of generic arguments for `{$type}`, not a comparison - .label_args = interpreted as generic arguments - .label_comparison = not interpreted as comparison - .suggestion = try comparing the cast value - -parse_comparison_operators_cannot_be_chained = comparison operators cannot be chained - .sugg_parentheses_for_function_args = or use `(...)` if you meant to specify fn arguments - .sugg_split_comparison = split the comparison into two - .sugg_parenthesize = parenthesize the comparison -parse_compound_assignment_expression_in_let = can't reassign to an uninitialized variable - .suggestion = initialize the variable - .help = if you meant to overwrite, remove the `let` binding - -parse_const_generic_without_braces = expressions must be enclosed in braces to be used as const generic arguments - .suggestion = enclose the `const` expression in braces - -parse_const_global_cannot_be_mutable = const globals cannot be mutable - .label = cannot be mutable - .suggestion = you might want to declare a static instead - -parse_const_let_mutually_exclusive = `const` and `let` are mutually exclusive - .suggestion = remove `let` - -parse_cr_doc_comment = bare CR not allowed in {$block -> - [true] block doc-comment - *[false] doc-comment -} - -parse_default_not_followed_by_item = `default` is not followed by an item - .label = the `default` qualifier - .note = only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` - -parse_delegation_non_trait_impl_reuse = only trait impls can be reused - -parse_do_catch_syntax_removed = found removed `do catch` syntax - .note = following RFC #2388, the new non-placeholder syntax is `try` - .suggestion = replace with the new syntax - -parse_doc_comment_does_not_document_anything = found a documentation comment that doesn't document anything - .help = doc comments must come before what they document, if a comment was intended use `//` - .suggestion = missing comma here - -parse_doc_comment_on_param_type = documentation comments cannot be applied to a function parameter's type - .label = doc comments are not allowed here - -parse_dot_dot_dot_for_remaining_fields = expected field pattern, found `{$token_str}` - .suggestion = to omit remaining fields, use `..` - -parse_dot_dot_dot_range_to_pattern_not_allowed = range-to patterns with `...` are not allowed - .suggestion = use `..=` instead - -parse_dot_dot_range_attribute = attributes are not allowed on range expressions starting with `..` - -parse_dotdotdot = unexpected token: `...` - .suggest_exclusive_range = use `..` for an exclusive range - .suggest_inclusive_range = or `..=` for an inclusive range - -parse_dotdotdot_rest_pattern = unexpected `...` - .label = not a valid pattern - .suggestion = for a rest pattern, use `..` instead of `...` - .note = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list - -parse_dotdotdot_rest_type = unexpected `...` - .note = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list - -parse_double_colon_in_bound = expected `:` followed by trait or lifetime - .suggestion = use single colon - -parse_dyn_after_mut = `mut` must precede `dyn` - .suggestion = place `mut` before `dyn` - -parse_empty_exponent_float = expected at least one digit in exponent - -parse_empty_unicode_escape = empty unicode escape - .label = this escape must have at least 1 hex digit - -parse_enum_pattern_instead_of_identifier = expected identifier, found enum pattern - -parse_enum_struct_mutually_exclusive = `enum` and `struct` are mutually exclusive - .suggestion = replace `enum struct` with - -parse_eq_field_init = expected `:`, found `=` - .suggestion = replace equals symbol with a colon - -parse_escape_only_char = {$byte -> - [true] byte - *[false] character - } constant must be escaped: `{$escaped_msg}` - .escape = escape the character - -parse_expect_dotdot_not_dotdotdot = expected `..`, found `...` - .suggestion = use `..` to fill in the rest of the fields - -parse_expect_eq_instead_of_eqeq = expected `=`, found `==` - .suggestion = consider using `=` here - -parse_expect_label_found_ident = expected a label, found an identifier - .suggestion = labels start with a tick - -parse_expect_path = expected a path - -parse_expected_binding_left_of_at = left-hand side of `@` must be a binding - .label_lhs = interpreted as a pattern, not a binding - .label_rhs = also a pattern - .note = bindings are `x`, `mut x`, `ref x`, and `ref mut x` - -parse_expected_builtin_ident = expected identifier after `builtin #` - -parse_expected_comma_after_pattern_field = expected `,` - -parse_expected_else_block = expected `{"{"}`, found {$first_tok} - .label = expected an `if` or a block after this `else` - .suggestion = add an `if` if this is the condition of a chained `else if` statement - -parse_expected_expression_found_let = expected expression, found `let` statement - .note = only supported directly in conditions of `if` and `while` expressions - .not_supported_or = `||` operators are not supported in let chain expressions - .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains - -parse_expected_fn_path_found_fn_keyword = expected identifier, found keyword `fn` - .suggestion = use `Fn` to refer to the trait - -parse_expected_identifier = expected identifier - -parse_expected_identifier_found_doc_comment = expected identifier, found doc comment -parse_expected_identifier_found_doc_comment_str = expected identifier, found doc comment `{$token}` -parse_expected_identifier_found_keyword = expected identifier, found keyword -parse_expected_identifier_found_keyword_str = expected identifier, found keyword `{$token}` -parse_expected_identifier_found_metavar = expected identifier, found metavariable -# This one deliberately doesn't print a token. -parse_expected_identifier_found_metavar_str = expected identifier, found metavariable -parse_expected_identifier_found_reserved_identifier = expected identifier, found reserved identifier -parse_expected_identifier_found_reserved_identifier_str = expected identifier, found reserved identifier `{$token}` -parse_expected_identifier_found_reserved_keyword = expected identifier, found reserved keyword -parse_expected_identifier_found_reserved_keyword_str = expected identifier, found reserved keyword `{$token}` -parse_expected_identifier_found_str = expected identifier, found `{$token}` - -parse_expected_mut_or_const_in_raw_pointer_type = expected `mut` or `const` keyword in raw pointer type - .suggestion = add `mut` or `const` here - -parse_expected_semi_found_doc_comment_str = expected `;`, found doc comment `{$token}` -parse_expected_semi_found_keyword_str = expected `;`, found keyword `{$token}` -# This one deliberately doesn't print a token. -parse_expected_semi_found_metavar_str = expected `;`, found metavariable -parse_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token}` -parse_expected_semi_found_reserved_keyword_str = expected `;`, found reserved keyword `{$token}` -parse_expected_semi_found_str = expected `;`, found `{$token}` - -parse_expected_statement_after_outer_attr = expected statement after outer attribute - -parse_expected_struct_field = expected one of `,`, `:`, or `{"}"}`, found `{$token}` - .label = expected one of `,`, `:`, or `{"}"}` - .ident_label = while parsing this struct field - -parse_expected_trait_in_trait_impl_found_type = expected a trait, found type - -parse_expr_rarrow_call = `->` is not valid syntax for field accesses and method calls - .suggestion = try using `.` instead - .help = the `.` operator will automatically dereference the value, except if the value is a raw pointer - -parse_extern_crate_name_with_dashes = crate name using dashes are not valid in `extern crate` statements - .label = dash-separated idents are not valid - .suggestion = if the original crate name uses dashes you need to use underscores in the code - -parse_extern_item_cannot_be_const = extern items cannot be `const` - .suggestion = try using a static value - .note = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html - -parse_extra_if_in_let_else = remove the `if` if you meant to write a `let...else` statement - -parse_extra_impl_keyword_in_trait_impl = unexpected `impl` keyword - .suggestion = remove the extra `impl` - .note = this is parsed as an `impl Trait` type, but a trait is expected at this position - - -parse_field_expression_with_generic = field expressions cannot have generic arguments - -parse_float_literal_requires_integer_part = float literals must have an integer part - .suggestion = must have an integer part - -parse_float_literal_unsupported_base = {$base} float literal is not supported - -parse_fn_pointer_cannot_be_async = an `fn` pointer type cannot be `async` - .label = `async` because of this - .suggestion = remove the `async` qualifier - .note = allowed qualifiers are: `unsafe` and `extern` - -parse_fn_pointer_cannot_be_const = an `fn` pointer type cannot be `const` - .label = `const` because of this - .suggestion = remove the `const` qualifier - .note = allowed qualifiers are: `unsafe` and `extern` - -parse_fn_ptr_with_generics = function pointer types may not have generic parameters - .suggestion = consider moving the lifetime {$arity -> - [one] parameter - *[other] parameters - } to {$for_param_list_exists -> - [true] the - *[false] a - } `for` parameter list - -parse_fn_trait_missing_paren = `Fn` bounds require arguments in parentheses - .add_paren = add the missing parentheses - -parse_forgot_paren = perhaps you forgot parentheses? - -parse_found_expr_would_be_stmt = expected expression, found `{$token}` - .label = expected expression - -parse_frontmatter_extra_characters_after_close = extra characters after frontmatter close are not allowed -parse_frontmatter_invalid_close_preceding_whitespace = invalid preceding whitespace for frontmatter close - .note = frontmatter close should not be preceded by whitespace -parse_frontmatter_invalid_infostring = invalid infostring for frontmatter - .note = frontmatter infostrings must be a single identifier immediately following the opening -parse_frontmatter_invalid_opening_preceding_whitespace = invalid preceding whitespace for frontmatter opening - .note = frontmatter opening should not be preceded by whitespace -parse_frontmatter_length_mismatch = frontmatter close does not match the opening - .label_opening = the opening here has {$len_opening} dashes... - .label_close = ...while the close has {$len_close} dashes -parse_frontmatter_too_many_dashes = too many `-` symbols: frontmatter openings may be delimited by up to 255 `-` symbols, but found {$len_opening} -parse_frontmatter_unclosed = unclosed frontmatter - .note = frontmatter opening here was not closed -parse_function_body_equals_expr = function body cannot be `= expression;` - .suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;` - -parse_generic_args_in_pat_require_turbofish_syntax = generic args in patterns require the turbofish syntax - -parse_generic_parameters_without_angle_brackets = generic parameters without surrounding angle brackets - .suggestion = surround the type parameters with angle brackets - -parse_generics_in_path = unexpected generic arguments in path - -parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` -parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` - -parse_hidden_unicode_codepoints = unicode codepoint changing visible direction of text present in {$label} - .label = this {$label} contains {$count -> - [one] an invisible - *[other] invisible - } unicode text flow control {$count -> - [one] codepoint - *[other] codepoints - } - .note = these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen - .suggestion_remove = if their presence wasn't intentional, you can remove them - .suggestion_escape = if you want to keep them but make them visible in your source code, you can escape them - .no_suggestion_note_escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped} - -parse_if_expression_missing_condition = missing condition for `if` expression - .condition_label = expected condition here - .block_label = if this block is the condition of the `if` expression, then it must be followed by another block - -parse_if_expression_missing_then_block = this `if` expression is missing a block after the condition - .add_then_block = add a block here - .condition_possibly_unfinished = this binary operation is possibly unfinished - -parse_in_in_typo = - expected iterable, found keyword `in` - .suggestion = remove the duplicated `in` - -parse_inappropriate_default = {$article} {$descr} cannot be `default` - .label = `default` because of this - .note = only associated `fn`, `const`, and `type` items can be `default` - -parse_inclusive_range_extra_equals = unexpected `=` after inclusive range - .suggestion_remove_eq = use `..=` instead - .note = inclusive ranges end with a single equals sign (`..=`) - -parse_inclusive_range_match_arrow = unexpected `>` after inclusive range - .label = this is parsed as an inclusive range `..=` - .suggestion = add a space between the pattern and `=>` - -parse_inclusive_range_no_end = inclusive range with no end - .suggestion_open_range = use `..` instead - .note = inclusive ranges must be bounded at the end (`..=b` or `a..=b`) - -parse_incorrect_parens_trait_bounds = incorrect parentheses around trait bounds -parse_incorrect_parens_trait_bounds_sugg = fix the parentheses - -parse_incorrect_semicolon = - expected item, found `;` - .suggestion = remove this semicolon - .help = {$name} declarations are not followed by a semicolon - -parse_incorrect_type_on_self = type not allowed for shorthand `self` parameter - .suggestion = move the modifiers on `self` to the type - -parse_incorrect_use_of_await = incorrect use of `await` - .parentheses_suggestion = `await` is not a method call, remove the parentheses - -parse_incorrect_use_of_await_postfix_suggestion = `await` is a postfix operation - -parse_incorrect_use_of_use = incorrect use of `use` - .parentheses_suggestion = `use` is not a method call, try removing the parentheses - -parse_incorrect_visibility_restriction = incorrect visibility restriction - .help = some possible visibility restrictions are: - `pub(crate)`: visible only on the current crate - `pub(super)`: visible only in the current module's parent - `pub(in path::to::module)`: visible only on the specified path - .suggestion = make this visible only to module `{$inner_str}` with `in` - -parse_inner_attr_explanation = inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -parse_inner_attr_not_permitted = an inner attribute is not permitted in this context - .label_does_not_annotate_this = {parse_label_inner_attr_does_not_annotate_this} - .sugg_change_inner_to_outer = {parse_sugg_change_inner_attr_to_outer} - -parse_inner_attr_not_permitted_after_outer_attr = an inner attribute is not permitted following an outer attribute - .label_attr = not permitted following an outer attribute - .label_prev_attr = previous outer attribute - .label_does_not_annotate_this = {parse_label_inner_attr_does_not_annotate_this} - .sugg_change_inner_to_outer = {parse_sugg_change_inner_attr_to_outer} - -parse_inner_attr_not_permitted_after_outer_doc_comment = an inner attribute is not permitted following an outer doc comment - .label_attr = not permitted following an outer doc comment - .label_prev_doc_comment = previous doc comment - .label_does_not_annotate_this = {parse_label_inner_attr_does_not_annotate_this} - .sugg_change_inner_to_outer = {parse_sugg_change_inner_attr_to_outer} - -parse_inner_doc_comment_not_permitted = expected outer doc comment - .note = inner doc comments like this (starting with `//!` or `/*!`) can only appear before items - .suggestion = you might have meant to write a regular comment - .label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item} - .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style - -parse_invalid_block_macro_segment = cannot use a `block` macro fragment here - .label = the `block` fragment is within this context - .suggestion = wrap this in another block - -parse_invalid_char_in_escape = {parse_invalid_char_in_escape_msg}: `{$ch}` - .label = {parse_invalid_char_in_escape_msg} - -parse_invalid_char_in_escape_msg = invalid character in {$is_hex -> - [true] numeric character - *[false] unicode - } escape - - -parse_invalid_comparison_operator = invalid comparison operator `{$invalid}` - .use_instead = `{$invalid}` is not a valid comparison operator, use `{$correct}` - .spaceship_operator_invalid = `<=>` is not a valid comparison operator, use `std::cmp::Ordering` - -parse_invalid_curly_in_let_else = right curly brace `{"}"}` before `else` in a `let...else` statement not allowed -parse_invalid_digit_literal = invalid digit for a base {$base} literal - -parse_invalid_dyn_keyword = invalid `dyn` keyword - .help = `dyn` is only needed at the start of a trait `+`-separated list - .suggestion = remove this keyword - -parse_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else` -parse_invalid_identifier_with_leading_number = identifiers cannot start with a number - -parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid - .label = invalid suffix `{$suffix}` - -parse_invalid_logical_operator = `{$incorrect}` is not a logical operator - .note = unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators - .use_amp_amp_for_conjunction = use `&&` to perform logical conjunction - .use_pipe_pipe_for_disjunction = use `||` to perform logical disjunction - -parse_invalid_meta_item = expected unsuffixed literal, found {$descr} - .quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal - -parse_invalid_offset_of = offset_of expects dot-separated field and variant names - -parse_invalid_path_sep_in_fn_definition = invalid path separator in function definition - .suggestion = remove invalid path separator - -parse_invalid_unicode_escape = invalid unicode character escape - .label = invalid escape - .help = unicode escape must {$surrogate -> - [true] not be a surrogate - *[false] be at most 10FFFF - } - -parse_invalid_variable_declaration = - invalid variable declaration - -parse_keyword_label = labels cannot use keyword names - -parse_keyword_lifetime = - lifetimes cannot use keyword names - -parse_kw_bad_case = keyword `{$kw}` is written in the wrong case - .suggestion = write it in {$case} - -parse_label_inner_attr_does_not_annotate_this = the inner attribute doesn't annotate this {$item} -parse_label_unexpected_token = unexpected token - -parse_label_while_parsing_or_pattern_here = while parsing this or-pattern starting here - -parse_labeled_loop_in_break = parentheses are required around this expression to avoid confusion with a labeled break expression - -parse_leading_plus_not_supported = leading `+` is not supported - .label = unexpected `+` - .suggestion_remove_plus = try removing the `+` - -parse_leading_underscore_unicode_escape = {parse_leading_underscore_unicode_escape_label}: `_` -parse_leading_underscore_unicode_escape_label = invalid start of unicode escape - -parse_left_arrow_operator = unexpected token: `<-` - .suggestion = if you meant to write a comparison against a negative value, add a space in between `<` and `-` - -parse_let_chain_pre_2024 = let chains are only allowed in Rust 2024 or later - -parse_lifetime_after_mut = lifetime must precede `mut` - .suggestion = place the lifetime before `mut` - -parse_lifetime_in_borrow_expression = borrow expressions cannot be annotated with lifetimes - .suggestion = remove the lifetime annotation - .label = annotated with lifetime here - -parse_lifetime_in_eq_constraint = lifetimes are not permitted in this context - .label = lifetime is not allowed here - .context_label = this introduces an associated item binding - .help = if you meant to specify a trait object, write `dyn /* Trait */ + {$lifetime}` - .colon_sugg = you might have meant to write a bound here - -parse_lone_slash = invalid trailing slash in literal - .label = {parse_lone_slash} - -parse_loop_else = `{$loop_kind}...else` loops are not supported - .note = consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run - .loop_keyword = `else` is attached to this loop - -parse_macro_expands_to_adt_field = macros cannot expand to {$adt_ty} fields - -parse_macro_expands_to_enum_variant = macros cannot expand to enum variants - -parse_macro_invocation_visibility = can't qualify macro invocation with `pub` - .suggestion = remove the visibility - .help = try adjusting the macro to put `{$vis}` inside the invocation - -parse_macro_invocation_with_qualified_path = macros cannot use qualified paths - -parse_macro_name_remove_bang = macro names aren't followed by a `!` - .suggestion = remove the `!` - -parse_macro_rules_missing_bang = expected `!` after `macro_rules` - .suggestion = add a `!` - -parse_macro_rules_visibility = can't qualify macro_rules invocation with `{$vis}` - .suggestion = try exporting the macro - -parse_malformed_loop_label = malformed loop label - .suggestion = use the correct loop label format - -parse_match_arm_body_without_braces = `match` arm body without braces - .label_statements = {$num_statements -> - [one] this statement is not surrounded by a body - *[other] these statements are not surrounded by a body - } - .label_arrow = while parsing the `match` arm starting here - .suggestion_add_braces = surround the {$num_statements -> - [one] statement - *[other] statements - } with a body - .suggestion_use_comma_not_semicolon = replace `;` with `,` to end a `match` arm expression - -parse_maybe_comparison = you might have meant to compare for equality - -parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of `fn` - .suggestion = replace `fn` with `impl` here - -parse_maybe_missing_let = you might have meant to continue the let-chain - -parse_maybe_recover_from_bad_qpath_stage_2 = - missing angle brackets in associated item path - .suggestion = types that don't start with an identifier need to be surrounded with angle brackets in qualified paths - -parse_maybe_recover_from_bad_type_plus = - expected a path on the left-hand side of `+` - -parse_maybe_report_ambiguous_plus = - ambiguous `+` in a type - .suggestion = use parentheses to disambiguate - -parse_mismatched_closing_delimiter = mismatched closing delimiter: `{$delimiter}` - .label_unmatched = mismatched closing delimiter - .label_opening_candidate = closing delimiter possibly meant for this - .label_unclosed = unclosed delimiter - -parse_misplaced_return_type = place the return type after the function parameters - -parse_missing_comma_after_match_arm = expected `,` following `match` arm - .suggestion = missing a comma here to end this `match` arm - -parse_missing_const_type = missing type for `{$kind}` item - .suggestion = provide a type for the item - -parse_missing_enum_for_enum_definition = missing `enum` for enum definition - .suggestion = add `enum` here to parse `{$ident}` as an enum - -parse_missing_enum_or_struct_for_item_definition = missing `enum` or `struct` for enum or struct definition - -parse_missing_expression_in_for_loop = missing expression to iterate on in `for` loop - .suggestion = try adding an expression to the `for` loop - -parse_missing_fn_for_function_definition = missing `fn` for function definition - .suggestion = add `fn` here to parse `{$ident}` as a function - -parse_missing_fn_for_method_definition = missing `fn` for method definition - .suggestion = add `fn` here to parse `{$ident}` as a method - -parse_missing_fn_or_struct_for_item_definition = missing `fn` or `struct` for function or struct definition - .suggestion = if you meant to call a macro, try - .help = if you meant to call a macro, remove the `pub` and add a trailing `!` after the identifier - -parse_missing_fn_params = missing parameters for function definition - .suggestion = add a parameter list - -parse_missing_for_in_trait_impl = missing `for` in a trait impl - .suggestion = add `for` here - -parse_missing_in_in_for_loop = missing `in` in `for` loop - .use_in = try using `in` here instead - .add_in = try adding `in` here - -parse_missing_let_before_mut = missing keyword -parse_missing_plus_in_bounds = expected `+` between lifetime and {$sym} - .suggestion = add `+` - -parse_missing_semicolon_before_array = expected `;`, found `[` - .suggestion = consider adding `;` here - -parse_missing_struct_for_struct_definition = missing `struct` for struct definition - .suggestion = add `struct` here to parse `{$ident}` as a struct - -parse_missing_trait_in_trait_impl = missing trait in a trait impl - .suggestion_add_trait = add a trait here - .suggestion_remove_for = for an inherent impl, drop this `for` - -parse_misspelled_kw = {$is_incorrect_case -> - [true] write keyword `{$similar_kw}` in lowercase - *[false] there is a keyword `{$similar_kw}` with a similar name -} - -parse_modifier_lifetime = `{$modifier}` may only modify trait bounds, not lifetime bounds - .suggestion = remove the `{$modifier}` - -parse_modifiers_and_polarity = `{$modifiers_concatenated}` trait not allowed with `{$polarity}` trait polarity modifier - .label = there is not a well-defined meaning for a `{$modifiers_concatenated} {$polarity}` trait - -parse_more_than_one_char = character literal may only contain one codepoint - .followed_by = this `{$chr}` is followed by the combining {$len -> - [one] mark - *[other] marks - } `{$escaped_marks}` - .non_printing = there are non-printing characters, the full sequence is `{$escaped}` - .consider_normalized = consider using the normalized form `{$ch}` of this character - .remove_non = consider removing the non-printing characters - .use_double_quotes = if you meant to write a {$is_byte -> - [true] byte string - *[false] string - } literal, use double quotes - -parse_multiple_skipped_lines = multiple lines skipped by escaped newline - .label = skipping everything up to and including this point - -parse_multiple_where_clauses = cannot define duplicate `where` clauses on an item - .label = previous `where` clause starts here - .suggestion = consider joining the two `where` clauses into one - -parse_mut_on_nested_ident_pattern = `mut` must be attached to each individual binding - .suggestion = add `mut` to each binding -parse_mut_on_non_ident_pattern = `mut` must be followed by a named binding - .suggestion = remove the `mut` prefix - -parse_need_plus_after_trait_object_lifetime = lifetimes must be followed by `+` to form a trait object type - .suggestion = consider adding a trait bound after the potential lifetime bound - -parse_nested_adt = `{$kw_str}` definition cannot be nested inside `{$keyword}` - .suggestion = consider creating a new `{$kw_str}` definition instead of nesting - -parse_nested_c_variadic_type = C-variadic type `...` may not be nested inside another type - -parse_no_brace_unicode_escape = incorrect unicode escape sequence - .label = {parse_no_brace_unicode_escape} - .use_braces = format of unicode escape sequences uses braces - .format_of_unicode = format of unicode escape sequences is `\u{"{...}"}` - -parse_no_digits_literal = no valid digits found for number - -parse_non_string_abi_literal = non-string ABI literal - .suggestion = specify the ABI with a string literal - -parse_nonterminal_expected_ident = expected ident, found `{$token}` -parse_nonterminal_expected_item_keyword = expected an item keyword -parse_nonterminal_expected_lifetime = expected a lifetime, found `{$token}` - -parse_nonterminal_expected_statement = expected a statement - -parse_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide - -parse_note_mut_pattern_usage = `mut` may be followed by `variable` and `variable @ pattern` - -parse_note_pattern_alternatives_use_single_vert = alternatives in or-patterns are separated with `|`, not `||` - -parse_nul_in_c_str = null characters in C string literals are not supported - -parse_or_in_let_chain = `||` operators are not supported in let chain conditions - -parse_or_pattern_not_allowed_in_fn_parameters = function parameters require top-level or-patterns in parentheses -parse_or_pattern_not_allowed_in_let_binding = `let` bindings require top-level or-patterns in parentheses - -parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them - -parse_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches - .branch_label = the attributes are attached to this branch - .ctx_label = the branch belongs to this `{$ctx}` - .suggestion = remove the attributes - -parse_overlong_unicode_escape = overlong unicode escape - .label = must have at most 6 hex digits - -parse_parentheses_with_struct_fields = invalid `struct` delimiters or `fn` call arguments - .suggestion_braces_for_struct = if `{$type}` is a struct, use braces as delimiters - .suggestion_no_fields_for_fn = if `{$type}` is a function, use the arguments directly - -parse_path_double_colon = path separator must be a double colon - .suggestion = use a double colon instead - - -parse_path_found_attribute_in_params = `Trait(...)` syntax does not support attributes in parameters - .suggestion = remove the attributes - -parse_path_found_c_variadic_params = `Trait(...)` syntax does not support c_variadic parameters - .suggestion = remove the `...` - -parse_path_found_named_params = `Trait(...)` syntax does not support named parameters - .suggestion = remove the parameter name - -parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies - .suggestion = give this argument a name or use an underscore to ignore it - -parse_pattern_on_wrong_side_of_at = pattern on wrong side of `@` - .label_pattern = pattern on the left, should be on the right - .label_binding = binding on the right, should be on the left - .suggestion = switch the order - -parse_question_mark_in_type = invalid `?` in type - .label = `?` is only allowed on expressions, not types - .suggestion = if you meant to express that the type might not contain a value, use the `Option` wrapper type - -parse_recover_import_as_use = expected item, found {$token_name} - .suggestion = items are imported using the `use` keyword - -parse_remove_let = expected pattern, found `let` - .suggestion = remove the unnecessary `let` keyword - -parse_repeated_mut_in_pattern = `mut` on a binding may not be repeated - .suggestion = remove the additional `mut`s - -parse_require_colon_after_labeled_expression = labeled expression must be followed by `:` - .note = labels are used before loops and blocks, allowing e.g., `break 'label` to them - .label = the label - .suggestion = add `:` after the label - -parse_reserved_multihash = reserved multi-hash token is forbidden - .note = sequences of two or more # are reserved for future use since Rust 2024 - .suggestion_whitespace = consider inserting whitespace here - -parse_reserved_string = invalid string literal - .note = unprefixed guarded string literals are reserved for future use since Rust 2024 - .suggestion_whitespace = consider inserting whitespace here - -parse_return_types_use_thin_arrow = return types are denoted using `->` - .suggestion = use `->` instead - -parse_self_argument_pointer = cannot pass `self` by raw pointer - .label = cannot pass `self` by raw pointer - -parse_self_param_not_first = unexpected `self` parameter in function - .label = must be the first parameter of an associated function - -parse_shift_interpreted_as_generic = - `<<` is interpreted as a start of generic arguments for `{$type}`, not a shift - .label_args = interpreted as generic arguments - .label_comparison = not interpreted as shift - .suggestion = try shifting the cast value - -parse_single_colon_import_path = expected `::`, found `:` - .suggestion = use double colon - .note = import paths are delimited using `::` - -parse_static_with_generics = static items may not have generic parameters - -parse_struct_literal_body_without_path = - struct literal body without path - .suggestion = you might have forgotten to add the struct literal inside the block - -parse_struct_literal_body_without_path_late = - struct literal body without path - .label = struct name missing for struct literal - .suggestion = add the correct type - -parse_struct_literal_not_allowed_here = struct literals are not allowed here - .suggestion = surround the struct literal with parentheses - -parse_struct_literal_placeholder_path = - placeholder `_` is not allowed for the path in struct literals - .label = not allowed in struct literals - .suggestion = replace it with the correct type - -parse_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes - .help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) - -parse_sugg_add_let_for_stmt = you might have meant to introduce a new binding - -parse_sugg_add_semi = add `;` here -parse_sugg_change_inner_attr_to_outer = to annotate the {$item}, change the attribute from inner to outer style - -parse_sugg_change_this_to_semi = change this to `;` -parse_sugg_escape_identifier = escape `{$ident_name}` to use it as an identifier - -parse_sugg_remove_comma = remove this comma -parse_sugg_remove_leading_vert_in_pattern = remove the `|` -parse_sugg_turbofish_syntax = use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments - -parse_sugg_wrap_expression_in_parentheses = wrap the expression in parentheses - -parse_sugg_wrap_macro_in_parentheses = use parentheses instead of braces for this macro - -parse_sugg_wrap_pattern_in_parens = wrap the pattern in parentheses - -parse_switch_mut_let_order = - switch the order of `mut` and `let` - -parse_switch_ref_box_order = switch the order of `ref` and `box` - .suggestion = swap them - -parse_ternary_operator = Rust has no ternary operator - -parse_tilde_is_not_unary_operator = `~` cannot be used as a unary operator - .suggestion = use `!` to perform bitwise not - -parse_too_many_hashes = too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found {$num} - -parse_too_short_hex_escape = numeric character escape is too short - -parse_trailing_vert_not_allowed = a trailing `{$token}` is not allowed in an or-pattern - -parse_trait_alias_cannot_be_auto = trait aliases cannot be `auto` -parse_trait_alias_cannot_be_unsafe = trait aliases cannot be `unsafe` - -parse_trait_impl_modifier_in_inherent_impl = inherent impls cannot be {$modifier_name} - .because = {$modifier_name} because of this - .type = inherent impl for this type - .note = only trait implementations may be annotated with `{$modifier}` - -parse_transpose_dyn_or_impl = `for<...>` expected after `{$kw}`, not before - .suggestion = move `{$kw}` before the `for<...>` - -parse_unclosed_unicode_escape = unterminated unicode escape - .label = missing a closing `{"}"}` - .terminate = terminate the unicode escape - -parse_underscore_literal_suffix = underscore literal suffix is not allowed - -parse_unexpected_const_in_generic_param = expected lifetime, type, or constant, found keyword `const` - .suggestion = the `const` keyword is only needed in the definition of the type - -parse_unexpected_const_param_declaration = unexpected `const` parameter declaration - .label = expected a `const` expression, not a parameter declaration - .suggestion = `const` parameters must be declared for the `impl` - -parse_unexpected_default_value_for_lifetime_in_generic_parameters = unexpected default lifetime parameter - .label = lifetime parameters cannot have default values - -parse_unexpected_expr_in_pat = - expected {$is_bound -> - [true] a pattern range bound - *[false] a pattern - }, found an expression - - .label = not a pattern - .note = arbitrary expressions are not allowed in patterns: - -parse_unexpected_expr_in_pat_const_sugg = consider extracting the expression into a `const` - -parse_unexpected_expr_in_pat_create_guard_sugg = consider moving the expression to a match arm guard - -parse_unexpected_expr_in_pat_update_guard_sugg = consider moving the expression to the match arm guard - -parse_unexpected_if_with_if = unexpected `if` in the condition expression - .suggestion = remove the `if` - -parse_unexpected_lifetime_in_pattern = unexpected lifetime `{$symbol}` in pattern - .suggestion = remove the lifetime - -parse_unexpected_paren_in_range_pat = range pattern bounds cannot have parentheses -parse_unexpected_paren_in_range_pat_sugg = remove these parentheses - -parse_unexpected_parentheses_in_for_head = unexpected parentheses surrounding `for` loop head - .suggestion = remove parentheses in `for` loop - -parse_unexpected_parentheses_in_match_arm_pattern = unexpected parentheses surrounding `match` arm pattern - .suggestion = remove parentheses surrounding the pattern - -parse_unexpected_self_in_generic_parameters = unexpected keyword `Self` in generic parameters - .note = you cannot use `Self` as a generic parameter because it is reserved for associated items - -parse_unexpected_token_after_dot = unexpected token: {$actual} - -parse_unexpected_token_after_label = expected `while`, `for`, `loop` or `{"{"}` after a label - .suggestion_remove_label = consider removing the label - .suggestion_enclose_in_block = consider enclosing expression in a block - -parse_unexpected_token_after_not = unexpected {$negated_desc} after identifier -parse_unexpected_token_after_not_bitwise = use `!` to perform bitwise not -parse_unexpected_token_after_not_default = use `!` to perform logical negation or bitwise not - -parse_unexpected_token_after_not_logical = use `!` to perform logical negation -parse_unexpected_token_after_struct_name = expected `where`, `{"{"}`, `(`, or `;` after struct name -parse_unexpected_token_after_struct_name_found_doc_comment = expected `where`, `{"{"}`, `(`, or `;` after struct name, found doc comment `{$token}` -parse_unexpected_token_after_struct_name_found_keyword = expected `where`, `{"{"}`, `(`, or `;` after struct name, found keyword `{$token}` -# This one deliberately doesn't print a token. -parse_unexpected_token_after_struct_name_found_metavar = expected `where`, `{"{"}`, `(`, or `;` after struct name, found metavar -parse_unexpected_token_after_struct_name_found_other = expected `where`, `{"{"}`, `(`, or `;` after struct name, found `{$token}` - -parse_unexpected_token_after_struct_name_found_reserved_identifier = expected `where`, `{"{"}`, `(`, or `;` after struct name, found reserved identifier `{$token}` -parse_unexpected_token_after_struct_name_found_reserved_keyword = expected `where`, `{"{"}`, `(`, or `;` after struct name, found reserved keyword `{$token}` -parse_unexpected_vert_vert_before_function_parameter = unexpected `||` before function parameter - .suggestion = remove the `||` - -parse_unexpected_vert_vert_in_pattern = unexpected token `||` in pattern - .suggestion = use a single `|` to separate multiple alternative patterns - -parse_unicode_escape_in_byte = unicode escape in byte string - .label = {parse_unicode_escape_in_byte} - .help = unicode escape sequences cannot be used as a byte or in a byte string - -parse_unknown_builtin_construct = unknown `builtin #` construct `{$name}` - -parse_unknown_prefix = prefix `{$prefix}` is unknown - .label = unknown prefix - .note = prefixed identifiers and literals are reserved since Rust 2021 - .suggestion_br = use `br` for a raw byte string - .suggestion_cr = use `cr` for a raw C-string - .suggestion_str = if you meant to write a string literal, use double quotes - .suggestion_whitespace = consider inserting whitespace here - -parse_unknown_start_of_token = unknown start of token: {$escaped} - .sugg_quotes = Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '{$ascii_str}' ({$ascii_name}), but are not - .sugg_other = Unicode character '{$ch}' ({$u_name}) looks like '{$ascii_str}' ({$ascii_name}), but it is not - .help_null = source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used - .help_invisible_char = invisible characters like '{$escaped}' are not usually visible in text editors - .note_repeats = character appears {$repeats -> - [one] once more - *[other] {$repeats} more times - } - -parse_unmatched_angle = unmatched angle {$plural -> - [true] brackets - *[false] bracket - } - .suggestion = remove extra angle {$plural -> - [true] brackets - *[false] bracket - } - -parse_unmatched_angle_brackets = {$num_extra_brackets -> - [one] unmatched angle bracket - *[other] unmatched angle brackets - } - .suggestion = {$num_extra_brackets -> - [one] remove extra angle bracket - *[other] remove extra angle brackets - } - - -parse_unskipped_whitespace = whitespace symbol '{$ch}' is not skipped - .label = {parse_unskipped_whitespace} - -parse_use_empty_block_not_semi = expected { "`{}`" }, found `;` - .suggestion = try using { "`{}`" } instead - -parse_use_eq_instead = unexpected `==` - .suggestion = try using `=` instead - -parse_use_if_else = use an `if-else` expression instead - -parse_use_let_not_auto = write `let` instead of `auto` to introduce a new variable -parse_use_let_not_var = write `let` instead of `var` to introduce a new variable - -parse_varargs_without_pattern = missing pattern for `...` argument - .suggestion = name the argument, or use `_` to continue ignoring it - -parse_visibility_not_followed_by_item = visibility `{$vis}` is not followed by an item - .label = the visibility - .help = you likely meant to define an item, e.g., `{$vis} fn foo() {"{}"}` - -parse_where_clause_before_const_body = where clauses are not allowed before const item bodies - .label = unexpected where clause - .name_label = while parsing this const item - .body_label = the item body - .suggestion = move the body before the where clause - -parse_where_clause_before_tuple_struct_body = where clauses are not allowed before tuple struct bodies - .label = unexpected where clause - .name_label = while parsing this tuple struct - .body_label = the struct body - .suggestion = move the body before the where clause - -parse_where_generics = generic parameters on `where` clauses are reserved for future use - .label = currently unsupported - -parse_zero_chars = empty character literal - .label = {parse_zero_chars} diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 8991e3b9d502..4a7031257700 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -9,17 +9,15 @@ use rustc_ast::{Path, Visibility}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, - Level, Subdiagnostic, SuggestionStyle, + Level, Subdiagnostic, SuggestionStyle, inline_fluent, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; use rustc_span::{Ident, Span, Symbol}; -use crate::fluent_generated as fluent; - #[derive(Diagnostic)] -#[diag(parse_maybe_report_ambiguous_plus)] +#[diag("ambiguous `+` in a type")] pub(crate) struct AmbiguousPlus { #[primary_span] pub span: Span, @@ -28,7 +26,7 @@ pub(crate) struct AmbiguousPlus { } #[derive(Diagnostic)] -#[diag(parse_maybe_recover_from_bad_type_plus, code = E0178)] +#[diag("expected a path on the left-hand side of `+`", code = E0178)] pub(crate) struct BadTypePlus { #[primary_span] pub span: Span, @@ -37,7 +35,7 @@ pub(crate) struct BadTypePlus { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")] +#[multipart_suggestion("try adding parentheses", applicability = "machine-applicable")] pub(crate) struct AddParen { #[suggestion_part(code = "(")] pub lo: Span, @@ -51,12 +49,12 @@ pub(crate) enum BadTypePlusSub { #[subdiagnostic] suggestion: AddParen, }, - #[label(parse_forgot_paren)] + #[label("perhaps you forgot parentheses?")] ForgotParen { #[primary_span] span: Span, }, - #[label(parse_expect_path)] + #[label("expected a path")] ExpectPath { #[primary_span] span: Span, @@ -64,7 +62,7 @@ pub(crate) enum BadTypePlusSub { } #[derive(Diagnostic)] -#[diag(parse_maybe_recover_from_bad_qpath_stage_2)] +#[diag("missing angle brackets in associated item path")] pub(crate) struct BadQPathStage2 { #[primary_span] pub span: Span, @@ -73,21 +71,24 @@ pub(crate) struct BadQPathStage2 { } #[derive(Diagnostic)] -#[diag(parse_trait_impl_modifier_in_inherent_impl)] -#[note] +#[diag("inherent impls cannot be {$modifier_name}")] +#[note("only trait implementations may be annotated with `{$modifier}`")] pub(crate) struct TraitImplModifierInInherentImpl { #[primary_span] pub span: Span, pub modifier: &'static str, pub modifier_name: &'static str, - #[label(parse_because)] + #[label("{$modifier_name} because of this")] pub modifier_span: Span, - #[label(parse_type)] + #[label("inherent impl for this type")] pub self_ty: Span, } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "types that don't start with an identifier need to be surrounded with angle brackets in qualified paths", + applicability = "machine-applicable" +)] pub(crate) struct WrapType { #[suggestion_part(code = "<")] pub lo: Span, @@ -96,22 +97,27 @@ pub(crate) struct WrapType { } #[derive(Diagnostic)] -#[diag(parse_incorrect_semicolon)] +#[diag("expected item, found `;`")] pub(crate) struct IncorrectSemicolon<'a> { #[primary_span] - #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")] + #[suggestion( + "remove this semicolon", + style = "verbose", + code = "", + applicability = "machine-applicable" + )] pub span: Span, - #[help] + #[help("{$name} declarations are not followed by a semicolon")] pub show_help: bool, pub name: &'a str, } #[derive(Diagnostic)] -#[diag(parse_incorrect_use_of_await)] +#[diag("incorrect use of `await`")] pub(crate) struct IncorrectUseOfAwait { #[primary_span] #[suggestion( - parse_parentheses_suggestion, + "`await` is not a method call, remove the parentheses", style = "verbose", code = "", applicability = "machine-applicable" @@ -120,11 +126,11 @@ pub(crate) struct IncorrectUseOfAwait { } #[derive(Diagnostic)] -#[diag(parse_incorrect_use_of_use)] +#[diag("incorrect use of `use`")] pub(crate) struct IncorrectUseOfUse { #[primary_span] #[suggestion( - parse_parentheses_suggestion, + "`use` is not a method call, try removing the parentheses", style = "verbose", code = "", applicability = "machine-applicable" @@ -133,10 +139,7 @@ pub(crate) struct IncorrectUseOfUse { } #[derive(Subdiagnostic)] -#[multipart_suggestion( - parse_incorrect_use_of_await_postfix_suggestion, - applicability = "machine-applicable" -)] +#[multipart_suggestion("`await` is a postfix operation", applicability = "machine-applicable")] pub(crate) struct AwaitSuggestion { #[suggestion_part(code = "")] pub removal: Span, @@ -146,7 +149,7 @@ pub(crate) struct AwaitSuggestion { } #[derive(Diagnostic)] -#[diag(parse_incorrect_use_of_await)] +#[diag("incorrect use of `await`")] pub(crate) struct IncorrectAwait { #[primary_span] pub span: Span, @@ -155,16 +158,21 @@ pub(crate) struct IncorrectAwait { } #[derive(Diagnostic)] -#[diag(parse_in_in_typo)] +#[diag("expected iterable, found keyword `in`")] pub(crate) struct InInTypo { #[primary_span] pub span: Span, - #[suggestion(code = "", style = "verbose", applicability = "machine-applicable")] + #[suggestion( + "remove the duplicated `in`", + code = "", + style = "verbose", + applicability = "machine-applicable" + )] pub sugg_span: Span, } #[derive(Diagnostic)] -#[diag(parse_invalid_variable_declaration)] +#[diag("invalid variable declaration")] pub(crate) struct InvalidVariableDeclaration { #[primary_span] pub span: Span, @@ -175,28 +183,28 @@ pub(crate) struct InvalidVariableDeclaration { #[derive(Subdiagnostic)] pub(crate) enum InvalidVariableDeclarationSub { #[suggestion( - parse_switch_mut_let_order, + "switch the order of `mut` and `let`", style = "verbose", applicability = "maybe-incorrect", code = "let mut" )] SwitchMutLetOrder(#[primary_span] Span), #[suggestion( - parse_missing_let_before_mut, + "missing keyword", applicability = "machine-applicable", style = "verbose", code = "let mut" )] MissingLet(#[primary_span] Span), #[suggestion( - parse_use_let_not_auto, + "write `let` instead of `auto` to introduce a new variable", style = "verbose", applicability = "machine-applicable", code = "let" )] UseLetNotAuto(#[primary_span] Span), #[suggestion( - parse_use_let_not_var, + "write `let` instead of `var` to introduce a new variable", style = "verbose", applicability = "machine-applicable", code = "let" @@ -205,15 +213,20 @@ pub(crate) enum InvalidVariableDeclarationSub { } #[derive(Diagnostic)] -#[diag(parse_switch_ref_box_order)] +#[diag("switch the order of `ref` and `box`")] pub(crate) struct SwitchRefBoxOrder { #[primary_span] - #[suggestion(applicability = "machine-applicable", style = "verbose", code = "box ref")] + #[suggestion( + "swap them", + applicability = "machine-applicable", + style = "verbose", + code = "box ref" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_invalid_comparison_operator)] +#[diag("invalid comparison operator `{$invalid}`")] pub(crate) struct InvalidComparisonOperator { #[primary_span] pub span: Span, @@ -225,7 +238,7 @@ pub(crate) struct InvalidComparisonOperator { #[derive(Subdiagnostic)] pub(crate) enum InvalidComparisonOperatorSub { #[suggestion( - parse_use_instead, + "`{$invalid}` is not a valid comparison operator, use `{$correct}`", style = "verbose", applicability = "machine-applicable", code = "{correct}" @@ -236,13 +249,13 @@ pub(crate) enum InvalidComparisonOperatorSub { invalid: String, correct: String, }, - #[label(parse_spaceship_operator_invalid)] + #[label("`<=>` is not a valid comparison operator, use `std::cmp::Ordering`")] Spaceship(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(parse_invalid_logical_operator)] -#[note] +#[diag("`{$incorrect}` is not a logical operator")] +#[note("unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators")] pub(crate) struct InvalidLogicalOperator { #[primary_span] pub span: Span, @@ -254,14 +267,14 @@ pub(crate) struct InvalidLogicalOperator { #[derive(Subdiagnostic)] pub(crate) enum InvalidLogicalOperatorSub { #[suggestion( - parse_use_amp_amp_for_conjunction, + "use `&&` to perform logical conjunction", style = "verbose", applicability = "machine-applicable", code = "&&" )] Conjunction(#[primary_span] Span), #[suggestion( - parse_use_pipe_pipe_for_disjunction, + "use `||` to perform logical disjunction", style = "verbose", applicability = "machine-applicable", code = "||" @@ -270,15 +283,20 @@ pub(crate) enum InvalidLogicalOperatorSub { } #[derive(Diagnostic)] -#[diag(parse_tilde_is_not_unary_operator)] +#[diag("`~` cannot be used as a unary operator")] pub(crate) struct TildeAsUnaryOperator( #[primary_span] - #[suggestion(style = "verbose", applicability = "machine-applicable", code = "!")] + #[suggestion( + "use `!` to perform bitwise not", + style = "verbose", + applicability = "machine-applicable", + code = "!" + )] pub Span, ); #[derive(Diagnostic)] -#[diag(parse_unexpected_token_after_not)] +#[diag("unexpected {$negated_desc} after identifier")] pub(crate) struct NotAsNegationOperator { #[primary_span] pub negated: Span, @@ -290,7 +308,7 @@ pub(crate) struct NotAsNegationOperator { #[derive(Subdiagnostic)] pub(crate) enum NotAsNegationOperatorSub { #[suggestion( - parse_unexpected_token_after_not_default, + "use `!` to perform logical negation or bitwise not", style = "verbose", applicability = "machine-applicable", code = "!" @@ -298,7 +316,7 @@ pub(crate) enum NotAsNegationOperatorSub { SuggestNotDefault(#[primary_span] Span), #[suggestion( - parse_unexpected_token_after_not_bitwise, + "use `!` to perform bitwise not", style = "verbose", applicability = "machine-applicable", code = "!" @@ -306,7 +324,7 @@ pub(crate) enum NotAsNegationOperatorSub { SuggestNotBitwise(#[primary_span] Span), #[suggestion( - parse_unexpected_token_after_not_logical, + "use `!` to perform logical negation", style = "verbose", applicability = "machine-applicable", code = "!" @@ -315,46 +333,59 @@ pub(crate) enum NotAsNegationOperatorSub { } #[derive(Diagnostic)] -#[diag(parse_malformed_loop_label)] +#[diag("malformed loop label")] pub(crate) struct MalformedLoopLabel { #[primary_span] pub span: Span, - #[suggestion(applicability = "machine-applicable", code = "'", style = "verbose")] + #[suggestion( + "use the correct loop label format", + applicability = "machine-applicable", + code = "'", + style = "verbose" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_lifetime_in_borrow_expression)] +#[diag("borrow expressions cannot be annotated with lifetimes")] pub(crate) struct LifetimeInBorrowExpression { #[primary_span] pub span: Span, - #[suggestion(applicability = "machine-applicable", code = "", style = "verbose")] - #[label] + #[suggestion( + "remove the lifetime annotation", + applicability = "machine-applicable", + code = "", + style = "verbose" + )] + #[label("annotated with lifetime here")] pub lifetime_span: Span, } #[derive(Diagnostic)] -#[diag(parse_field_expression_with_generic)] +#[diag("field expressions cannot have generic arguments")] pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span); #[derive(Diagnostic)] -#[diag(parse_macro_invocation_with_qualified_path)] +#[diag("macros cannot use qualified paths")] pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span); #[derive(Diagnostic)] -#[diag(parse_unexpected_token_after_label)] +#[diag("expected `while`, `for`, `loop` or `{\"{\"}` after a label")] pub(crate) struct UnexpectedTokenAfterLabel { #[primary_span] - #[label(parse_unexpected_token_after_label)] + #[label("expected `while`, `for`, `loop` or `{\"{\"}` after a label")] pub span: Span, - #[suggestion(parse_suggestion_remove_label, style = "verbose", code = "")] + #[suggestion("consider removing the label", style = "verbose", code = "")] pub remove_label: Option, #[subdiagnostic] pub enclose_in_block: Option, } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion_enclose_in_block, applicability = "machine-applicable")] +#[multipart_suggestion( + "consider enclosing expression in a block", + applicability = "machine-applicable" +)] pub(crate) struct UnexpectedTokenAfterLabelSugg { #[suggestion_part(code = "{{ ")] pub left: Span, @@ -363,66 +394,91 @@ pub(crate) struct UnexpectedTokenAfterLabelSugg { } #[derive(Diagnostic)] -#[diag(parse_require_colon_after_labeled_expression)] -#[note] +#[diag("labeled expression must be followed by `:`")] +#[note("labels are used before loops and blocks, allowing e.g., `break 'label` to them")] pub(crate) struct RequireColonAfterLabeledExpression { #[primary_span] pub span: Span, - #[label] + #[label("the label")] pub label: Span, - #[suggestion(style = "verbose", applicability = "machine-applicable", code = ": ")] + #[suggestion( + "add `:` after the label", + style = "verbose", + applicability = "machine-applicable", + code = ": " + )] pub label_end: Span, } #[derive(Diagnostic)] -#[diag(parse_do_catch_syntax_removed)] -#[note] +#[diag("found removed `do catch` syntax")] +#[note("following RFC #2388, the new non-placeholder syntax is `try`")] pub(crate) struct DoCatchSyntaxRemoved { #[primary_span] - #[suggestion(applicability = "machine-applicable", code = "try", style = "verbose")] + #[suggestion( + "replace with the new syntax", + applicability = "machine-applicable", + code = "try", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_float_literal_requires_integer_part)] +#[diag("float literals must have an integer part")] pub(crate) struct FloatLiteralRequiresIntegerPart { #[primary_span] pub span: Span, - #[suggestion(applicability = "machine-applicable", code = "0", style = "verbose")] + #[suggestion( + "must have an integer part", + applicability = "machine-applicable", + code = "0", + style = "verbose" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_missing_semicolon_before_array)] +#[diag("expected `;`, found `[`")] pub(crate) struct MissingSemicolonBeforeArray { #[primary_span] pub open_delim: Span, - #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = ";")] + #[suggestion( + "consider adding `;` here", + style = "verbose", + applicability = "maybe-incorrect", + code = ";" + )] pub semicolon: Span, } #[derive(Diagnostic)] -#[diag(parse_expect_dotdot_not_dotdotdot)] +#[diag("expected `..`, found `...`")] pub(crate) struct MissingDotDot { #[primary_span] pub token_span: Span, - #[suggestion(applicability = "maybe-incorrect", code = "..", style = "verbose")] + #[suggestion( + "use `..` to fill in the rest of the fields", + applicability = "maybe-incorrect", + code = "..", + style = "verbose" + )] pub sugg_span: Span, } #[derive(Diagnostic)] -#[diag(parse_invalid_block_macro_segment)] +#[diag("cannot use a `block` macro fragment here")] pub(crate) struct InvalidBlockMacroSegment { #[primary_span] pub span: Span, - #[label] + #[label("the `block` fragment is within this context")] pub context: Span, #[subdiagnostic] pub wrap: WrapInExplicitBlock, } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion("wrap this in another block", applicability = "machine-applicable")] pub(crate) struct WrapInExplicitBlock { #[suggestion_part(code = "{{ ")] pub lo: Span, @@ -431,7 +487,7 @@ pub(crate) struct WrapInExplicitBlock { } #[derive(Diagnostic)] -#[diag(parse_if_expression_missing_then_block)] +#[diag("this `if` expression is missing a block after the condition")] pub(crate) struct IfExpressionMissingThenBlock { #[primary_span] pub if_span: Span, @@ -443,14 +499,14 @@ pub(crate) struct IfExpressionMissingThenBlock { #[derive(Subdiagnostic)] pub(crate) enum IfExpressionMissingThenBlockSub { - #[help(parse_condition_possibly_unfinished)] + #[help("this binary operation is possibly unfinished")] UnfinishedCondition(#[primary_span] Span), - #[help(parse_add_then_block)] + #[help("add a block here")] AddThenBlock(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(parse_ternary_operator)] +#[diag("Rust has no ternary operator")] pub(crate) struct TernaryOperator { #[primary_span] pub span: Span, @@ -458,12 +514,16 @@ pub(crate) struct TernaryOperator { #[subdiagnostic] pub sugg: Option, /// Otherwise, just print the suggestion message - #[help(parse_use_if_else)] + #[help("use an `if-else` expression instead")] pub no_sugg: bool, } #[derive(Subdiagnostic, Copy, Clone)] -#[multipart_suggestion(parse_use_if_else, applicability = "maybe-incorrect", style = "verbose")] +#[multipart_suggestion( + "use an `if-else` expression instead", + applicability = "maybe-incorrect", + style = "verbose" +)] pub(crate) struct TernaryOperatorSuggestion { #[suggestion_part(code = "if ")] pub before_cond: Span, @@ -477,7 +537,7 @@ pub(crate) struct TernaryOperatorSuggestion { #[derive(Subdiagnostic)] #[suggestion( - parse_extra_if_in_let_else, + "remove the `if` if you meant to write a `let...else` statement", applicability = "maybe-incorrect", code = "", style = "verbose" @@ -488,18 +548,20 @@ pub(crate) struct IfExpressionLetSomeSub { } #[derive(Diagnostic)] -#[diag(parse_if_expression_missing_condition)] +#[diag("missing condition for `if` expression")] pub(crate) struct IfExpressionMissingCondition { #[primary_span] - #[label(parse_condition_label)] + #[label("expected condition here")] pub if_span: Span, - #[label(parse_block_label)] + #[label( + "if this block is the condition of the `if` expression, then it must be followed by another block" + )] pub block_span: Span, } #[derive(Diagnostic)] -#[diag(parse_expected_expression_found_let)] -#[note] +#[diag("expected expression, found `let` statement")] +#[note("only supported directly in conditions of `if` and `while` expressions")] pub(crate) struct ExpectedExpressionFoundLet { #[primary_span] pub span: Span, @@ -512,7 +574,7 @@ pub(crate) struct ExpectedExpressionFoundLet { } #[derive(Diagnostic)] -#[diag(parse_or_in_let_chain)] +#[diag("`||` operators are not supported in let chain conditions")] pub(crate) struct OrInLetChain { #[primary_span] pub span: Span, @@ -520,7 +582,7 @@ pub(crate) struct OrInLetChain { #[derive(Subdiagnostic, Clone, Copy)] #[multipart_suggestion( - parse_maybe_missing_let, + "you might have meant to continue the let-chain", applicability = "maybe-incorrect", style = "verbose" )] @@ -531,7 +593,7 @@ pub(crate) struct MaybeMissingLet { #[derive(Subdiagnostic, Clone, Copy)] #[multipart_suggestion( - parse_maybe_comparison, + "you might have meant to compare for equality", applicability = "maybe-incorrect", style = "verbose" )] @@ -541,56 +603,71 @@ pub(crate) struct MaybeComparison { } #[derive(Diagnostic)] -#[diag(parse_expect_eq_instead_of_eqeq)] +#[diag("expected `=`, found `==`")] pub(crate) struct ExpectedEqForLetExpr { #[primary_span] pub span: Span, - #[suggestion(applicability = "maybe-incorrect", code = "=", style = "verbose")] + #[suggestion( + "consider using `=` here", + applicability = "maybe-incorrect", + code = "=", + style = "verbose" + )] pub sugg_span: Span, } #[derive(Diagnostic)] -#[diag(parse_expected_else_block)] +#[diag("expected `{\"{\"}`, found {$first_tok}")] pub(crate) struct ExpectedElseBlock { #[primary_span] pub first_tok_span: Span, pub first_tok: String, - #[label] + #[label("expected an `if` or a block after this `else`")] pub else_span: Span, - #[suggestion(applicability = "maybe-incorrect", code = "if ", style = "verbose")] + #[suggestion( + "add an `if` if this is the condition of a chained `else if` statement", + applicability = "maybe-incorrect", + code = "if ", + style = "verbose" + )] pub condition_start: Span, } #[derive(Diagnostic)] -#[diag(parse_expected_struct_field)] +#[diag("expected one of `,`, `:`, or `{\"}\"}`, found `{$token}`")] pub(crate) struct ExpectedStructField { #[primary_span] - #[label] + #[label("expected one of `,`, `:`, or `{\"}\"}`")] pub span: Span, pub token: Token, - #[label(parse_ident_label)] + #[label("while parsing this struct field")] pub ident_span: Span, } #[derive(Diagnostic)] -#[diag(parse_outer_attribute_not_allowed_on_if_else)] +#[diag("outer attributes are not allowed on `if` and `else` branches")] pub(crate) struct OuterAttributeNotAllowedOnIfElse { #[primary_span] pub last: Span, - #[label(parse_branch_label)] + #[label("the attributes are attached to this branch")] pub branch_span: Span, - #[label(parse_ctx_label)] + #[label("the branch belongs to this `{$ctx}`")] pub ctx_span: Span, pub ctx: String, - #[suggestion(applicability = "machine-applicable", code = "", style = "verbose")] + #[suggestion( + "remove the attributes", + applicability = "machine-applicable", + code = "", + style = "verbose" + )] pub attributes: Span, } #[derive(Diagnostic)] -#[diag(parse_missing_in_in_for_loop)] +#[diag("missing `in` in `for` loop")] pub(crate) struct MissingInInForLoop { #[primary_span] pub span: Span, @@ -602,20 +679,36 @@ pub(crate) struct MissingInInForLoop { pub(crate) enum MissingInInForLoopSub { // User wrote `for pat of expr {}` // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect - #[suggestion(parse_use_in, style = "verbose", applicability = "maybe-incorrect", code = "in")] + #[suggestion( + "try using `in` here instead", + style = "verbose", + applicability = "maybe-incorrect", + code = "in" + )] InNotOf(#[primary_span] Span), // User wrote `for pat = expr {}` - #[suggestion(parse_use_in, style = "verbose", applicability = "maybe-incorrect", code = "in")] + #[suggestion( + "try using `in` here instead", + style = "verbose", + applicability = "maybe-incorrect", + code = "in" + )] InNotEq(#[primary_span] Span), - #[suggestion(parse_add_in, style = "verbose", applicability = "maybe-incorrect", code = " in ")] + #[suggestion( + "try adding `in` here", + style = "verbose", + applicability = "maybe-incorrect", + code = " in " + )] AddIn(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(parse_missing_expression_in_for_loop)] +#[diag("missing expression to iterate on in `for` loop")] pub(crate) struct MissingExpressionInForLoop { #[primary_span] #[suggestion( + "try adding an expression to the `for` loop", code = "/* expression */ ", applicability = "has-placeholders", style = "verbose" @@ -624,63 +717,80 @@ pub(crate) struct MissingExpressionInForLoop { } #[derive(Diagnostic)] -#[diag(parse_loop_else)] -#[note] +#[diag("`{$loop_kind}...else` loops are not supported")] +#[note( + "consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run" +)] pub(crate) struct LoopElseNotSupported { #[primary_span] pub span: Span, pub loop_kind: &'static str, - #[label(parse_loop_keyword)] + #[label("`else` is attached to this loop")] pub loop_kw: Span, } #[derive(Diagnostic)] -#[diag(parse_missing_comma_after_match_arm)] +#[diag("expected `,` following `match` arm")] pub(crate) struct MissingCommaAfterMatchArm { #[primary_span] - #[suggestion(applicability = "machine-applicable", code = ",", style = "verbose")] + #[suggestion( + "missing a comma here to end this `match` arm", + applicability = "machine-applicable", + code = ",", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_catch_after_try)] -#[help] +#[diag("keyword `catch` cannot follow a `try` block")] +#[help("try using `match` on the result of the `try` block instead")] pub(crate) struct CatchAfterTry { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_comma_after_base_struct)] -#[note] +#[diag("cannot use a comma after the base struct")] +#[note("the base struct must always be the last field")] pub(crate) struct CommaAfterBaseStruct { #[primary_span] pub span: Span, - #[suggestion(style = "verbose", applicability = "machine-applicable", code = "")] + #[suggestion( + "remove this comma", + style = "verbose", + applicability = "machine-applicable", + code = "" + )] pub comma: Span, } #[derive(Diagnostic)] -#[diag(parse_eq_field_init)] +#[diag("expected `:`, found `=`")] pub(crate) struct EqFieldInit { #[primary_span] pub span: Span, - #[suggestion(applicability = "machine-applicable", code = ":", style = "verbose")] + #[suggestion( + "replace equals symbol with a colon", + applicability = "machine-applicable", + code = ":", + style = "verbose" + )] pub eq: Span, } #[derive(Diagnostic)] -#[diag(parse_dotdotdot)] +#[diag("unexpected token: `...`")] pub(crate) struct DotDotDot { #[primary_span] #[suggestion( - parse_suggest_exclusive_range, + "use `..` for an exclusive range", applicability = "maybe-incorrect", code = "..", style = "verbose" )] #[suggestion( - parse_suggest_inclusive_range, + "or `..=` for an inclusive range", applicability = "maybe-incorrect", code = "..=", style = "verbose" @@ -689,66 +799,86 @@ pub(crate) struct DotDotDot { } #[derive(Diagnostic)] -#[diag(parse_left_arrow_operator)] +#[diag("unexpected token: `<-`")] pub(crate) struct LeftArrowOperator { #[primary_span] - #[suggestion(applicability = "maybe-incorrect", code = "< -", style = "verbose")] + #[suggestion( + "if you meant to write a comparison against a negative value, add a space in between `<` and `-`", + applicability = "maybe-incorrect", + code = "< -", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_remove_let)] +#[diag("expected pattern, found `let`")] pub(crate) struct RemoveLet { #[primary_span] pub span: Span, - #[suggestion(applicability = "machine-applicable", code = "", style = "verbose")] + #[suggestion( + "remove the unnecessary `let` keyword", + applicability = "machine-applicable", + code = "", + style = "verbose" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_use_eq_instead)] +#[diag("unexpected `==`")] pub(crate) struct UseEqInstead { #[primary_span] - #[suggestion(style = "verbose", applicability = "machine-applicable", code = "=")] + #[suggestion( + "try using `=` instead", + style = "verbose", + applicability = "machine-applicable", + code = "=" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_use_empty_block_not_semi)] +#[diag("expected { \"`{}`\" }, found `;`")] pub(crate) struct UseEmptyBlockNotSemi { #[primary_span] - #[suggestion(style = "hidden", applicability = "machine-applicable", code = "{{}}")] + #[suggestion( + r#"try using { "`{}`" } instead"#, + style = "hidden", + applicability = "machine-applicable", + code = "{{}}" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_comparison_interpreted_as_generic)] +#[diag("`<` is interpreted as a start of generic arguments for `{$type}`, not a comparison")] pub(crate) struct ComparisonInterpretedAsGeneric { #[primary_span] - #[label(parse_label_comparison)] + #[label("not interpreted as comparison")] pub comparison: Span, pub r#type: Path, - #[label(parse_label_args)] + #[label("interpreted as generic arguments")] pub args: Span, #[subdiagnostic] pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg, } #[derive(Diagnostic)] -#[diag(parse_shift_interpreted_as_generic)] +#[diag("`<<` is interpreted as a start of generic arguments for `{$type}`, not a shift")] pub(crate) struct ShiftInterpretedAsGeneric { #[primary_span] - #[label(parse_label_comparison)] + #[label("not interpreted as shift")] pub shift: Span, pub r#type: Path, - #[label(parse_label_args)] + #[label("interpreted as generic arguments")] pub args: Span, #[subdiagnostic] pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg, } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion("BROKEN", applicability = "machine-applicable")] pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg { #[suggestion_part(code = "(")] pub left: Span, @@ -757,10 +887,10 @@ pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg { } #[derive(Diagnostic)] -#[diag(parse_found_expr_would_be_stmt)] +#[diag("expected expression, found `{$token}`")] pub(crate) struct FoundExprWouldBeStmt { #[primary_span] - #[label] + #[label("expected expression")] pub span: Span, pub token: Token, #[subdiagnostic] @@ -768,81 +898,83 @@ pub(crate) struct FoundExprWouldBeStmt { } #[derive(Diagnostic)] -#[diag(parse_frontmatter_extra_characters_after_close)] +#[diag("extra characters after frontmatter close are not allowed")] pub(crate) struct FrontmatterExtraCharactersAfterClose { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_frontmatter_invalid_infostring)] -#[note] +#[diag("invalid infostring for frontmatter")] +#[note("frontmatter infostrings must be a single identifier immediately following the opening")] pub(crate) struct FrontmatterInvalidInfostring { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_frontmatter_invalid_opening_preceding_whitespace)] +#[diag("invalid preceding whitespace for frontmatter opening")] pub(crate) struct FrontmatterInvalidOpeningPrecedingWhitespace { #[primary_span] pub span: Span, - #[note] + #[note("frontmatter opening should not be preceded by whitespace")] pub note_span: Span, } #[derive(Diagnostic)] -#[diag(parse_frontmatter_unclosed)] +#[diag("unclosed frontmatter")] pub(crate) struct FrontmatterUnclosed { #[primary_span] pub span: Span, - #[note] + #[note("frontmatter opening here was not closed")] pub note_span: Span, } #[derive(Diagnostic)] -#[diag(parse_frontmatter_invalid_close_preceding_whitespace)] +#[diag("invalid preceding whitespace for frontmatter close")] pub(crate) struct FrontmatterInvalidClosingPrecedingWhitespace { #[primary_span] pub span: Span, - #[note] + #[note("frontmatter close should not be preceded by whitespace")] pub note_span: Span, } #[derive(Diagnostic)] -#[diag(parse_frontmatter_length_mismatch)] +#[diag("frontmatter close does not match the opening")] pub(crate) struct FrontmatterLengthMismatch { #[primary_span] pub span: Span, - #[label(parse_label_opening)] + #[label("the opening here has {$len_opening} dashes...")] pub opening: Span, - #[label(parse_label_close)] + #[label("...while the close has {$len_close} dashes")] pub close: Span, pub len_opening: usize, pub len_close: usize, } #[derive(Diagnostic)] -#[diag(parse_frontmatter_too_many_dashes)] +#[diag( + "too many `-` symbols: frontmatter openings may be delimited by up to 255 `-` symbols, but found {$len_opening}" +)] pub(crate) struct FrontmatterTooManyDashes { pub len_opening: usize, } #[derive(Diagnostic)] -#[diag(parse_bare_cr_in_frontmatter)] +#[diag("bare CR not allowed in frontmatter")] pub(crate) struct BareCrFrontmatter { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_leading_plus_not_supported)] +#[diag("leading `+` is not supported")] pub(crate) struct LeadingPlusNotSupported { #[primary_span] - #[label] + #[label("unexpected `+`")] pub span: Span, #[suggestion( - parse_suggestion_remove_plus, + "try removing the `+`", style = "verbose", code = "", applicability = "machine-applicable" @@ -853,7 +985,7 @@ pub(crate) struct LeadingPlusNotSupported { } #[derive(Diagnostic)] -#[diag(parse_parentheses_with_struct_fields)] +#[diag("invalid `struct` delimiters or `fn` call arguments")] pub(crate) struct ParenthesesWithStructFields { #[primary_span] pub span: Span, @@ -865,7 +997,10 @@ pub(crate) struct ParenthesesWithStructFields { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion_braces_for_struct, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "if `{$type}` is a struct, use braces as delimiters", + applicability = "maybe-incorrect" +)] pub(crate) struct BracesForStructLiteral { #[suggestion_part(code = " {{ ")] pub first: Span, @@ -874,14 +1009,19 @@ pub(crate) struct BracesForStructLiteral { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion_no_fields_for_fn, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "if `{$type}` is a function, use the arguments directly", + applicability = "maybe-incorrect" +)] pub(crate) struct NoFieldsForFnCall { #[suggestion_part(code = "")] pub fields: Vec, } #[derive(Diagnostic)] -#[diag(parse_labeled_loop_in_break)] +#[diag( + "parentheses are required around this expression to avoid confusion with a labeled break expression" +)] pub(crate) struct LabeledLoopInBreak { #[primary_span] pub span: Span, @@ -892,7 +1032,7 @@ pub(crate) struct LabeledLoopInBreak { #[derive(Subdiagnostic)] pub(crate) enum WrapInParentheses { #[multipart_suggestion( - parse_sugg_wrap_expression_in_parentheses, + "wrap the expression in parentheses", applicability = "machine-applicable" )] Expression { @@ -902,7 +1042,7 @@ pub(crate) enum WrapInParentheses { right: Span, }, #[multipart_suggestion( - parse_sugg_wrap_macro_in_parentheses, + "use parentheses instead of braces for this macro", applicability = "machine-applicable" )] MacroArgs { @@ -914,7 +1054,7 @@ pub(crate) enum WrapInParentheses { } #[derive(Diagnostic)] -#[diag(parse_array_brackets_instead_of_braces)] +#[diag("this is a block expression, not an array")] pub(crate) struct ArrayBracketsInsteadOfBraces { #[primary_span] pub span: Span, @@ -923,7 +1063,10 @@ pub(crate) struct ArrayBracketsInsteadOfBraces { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "to make an array, use square brackets instead of curly braces", + applicability = "maybe-incorrect" +)] pub(crate) struct ArrayBracketsInsteadOfBracesSugg { #[suggestion_part(code = "[")] pub left: Span, @@ -932,12 +1075,17 @@ pub(crate) struct ArrayBracketsInsteadOfBracesSugg { } #[derive(Diagnostic)] -#[diag(parse_match_arm_body_without_braces)] +#[diag("`match` arm body without braces")] pub(crate) struct MatchArmBodyWithoutBraces { #[primary_span] - #[label(parse_label_statements)] + #[label( + "{$num_statements -> + [one] this statement is not surrounded by a body + *[other] these statements are not surrounded by a body + }" + )] pub statements: Span, - #[label(parse_label_arrow)] + #[label("while parsing the `match` arm starting here")] pub arrow: Span, pub num_statements: usize, #[subdiagnostic] @@ -945,12 +1093,12 @@ pub(crate) struct MatchArmBodyWithoutBraces { } #[derive(Diagnostic)] -#[diag(parse_inclusive_range_extra_equals)] -#[note] +#[diag("unexpected `=` after inclusive range")] +#[note("inclusive ranges end with a single equals sign (`..=`)")] pub(crate) struct InclusiveRangeExtraEquals { #[primary_span] #[suggestion( - parse_suggestion_remove_eq, + "use `..=` instead", style = "verbose", code = "..=", applicability = "maybe-incorrect" @@ -959,24 +1107,29 @@ pub(crate) struct InclusiveRangeExtraEquals { } #[derive(Diagnostic)] -#[diag(parse_inclusive_range_match_arrow)] +#[diag("unexpected `>` after inclusive range")] pub(crate) struct InclusiveRangeMatchArrow { #[primary_span] pub arrow: Span, - #[label] + #[label("this is parsed as an inclusive range `..=`")] pub span: Span, - #[suggestion(style = "verbose", code = " ", applicability = "machine-applicable")] + #[suggestion( + "add a space between the pattern and `=>`", + style = "verbose", + code = " ", + applicability = "machine-applicable" + )] pub after_pat: Span, } #[derive(Diagnostic)] -#[diag(parse_inclusive_range_no_end, code = E0586)] -#[note] +#[diag("inclusive range with no end", code = E0586)] +#[note("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)")] pub(crate) struct InclusiveRangeNoEnd { #[primary_span] pub span: Span, #[suggestion( - parse_suggestion_open_range, + "use `..` instead", code = "", applicability = "machine-applicable", style = "verbose" @@ -986,7 +1139,13 @@ pub(crate) struct InclusiveRangeNoEnd { #[derive(Subdiagnostic)] pub(crate) enum MatchArmBodyWithoutBracesSugg { - #[multipart_suggestion(parse_suggestion_add_braces, applicability = "machine-applicable")] + #[multipart_suggestion( + "surround the {$num_statements -> + [one] statement + *[other] statements + } with a body", + applicability = "machine-applicable" + )] AddBraces { #[suggestion_part(code = "{{ ")] left: Span, @@ -994,7 +1153,7 @@ pub(crate) enum MatchArmBodyWithoutBracesSugg { right: Span, }, #[suggestion( - parse_suggestion_use_comma_not_semicolon, + "replace `;` with `,` to end a `match` arm expression", code = ",", applicability = "machine-applicable", style = "verbose" @@ -1006,7 +1165,7 @@ pub(crate) enum MatchArmBodyWithoutBracesSugg { } #[derive(Diagnostic)] -#[diag(parse_struct_literal_not_allowed_here)] +#[diag("struct literals are not allowed here")] pub(crate) struct StructLiteralNotAllowedHere { #[primary_span] pub span: Span, @@ -1015,7 +1174,10 @@ pub(crate) struct StructLiteralNotAllowedHere { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "surround the struct literal with parentheses", + applicability = "machine-applicable" +)] pub(crate) struct StructLiteralNotAllowedHereSugg { #[suggestion_part(code = "(")] pub left: Span, @@ -1024,80 +1186,105 @@ pub(crate) struct StructLiteralNotAllowedHereSugg { } #[derive(Diagnostic)] -#[diag(parse_invalid_literal_suffix_on_tuple_index)] +#[diag("suffixes on a tuple index are invalid")] pub(crate) struct InvalidLiteralSuffixOnTupleIndex { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] pub span: Span, pub suffix: Symbol, } #[derive(Diagnostic)] -#[diag(parse_non_string_abi_literal)] +#[diag("non-string ABI literal")] pub(crate) struct NonStringAbiLiteral { #[primary_span] - #[suggestion(code = "\"C\"", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "specify the ABI with a string literal", + code = "\"C\"", + applicability = "maybe-incorrect", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_mismatched_closing_delimiter)] +#[diag("mismatched closing delimiter: `{$delimiter}`")] pub(crate) struct MismatchedClosingDelimiter { #[primary_span] pub spans: Vec, pub delimiter: String, - #[label(parse_label_unmatched)] + #[label("mismatched closing delimiter")] pub unmatched: Span, - #[label(parse_label_opening_candidate)] + #[label("closing delimiter possibly meant for this")] pub opening_candidate: Option, - #[label(parse_label_unclosed)] + #[label("unclosed delimiter")] pub unclosed: Option, } #[derive(Diagnostic)] -#[diag(parse_incorrect_visibility_restriction, code = E0704)] -#[help] +#[diag("incorrect visibility restriction", code = E0704)] +#[help( + "some possible visibility restrictions are: + `pub(crate)`: visible only on the current crate + `pub(super)`: visible only in the current module's parent + `pub(in path::to::module)`: visible only on the specified path" +)] pub(crate) struct IncorrectVisibilityRestriction { #[primary_span] - #[suggestion(code = "in {inner_str}", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "make this visible only to module `{$inner_str}` with `in`", + code = "in {inner_str}", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, pub inner_str: String, } #[derive(Diagnostic)] -#[diag(parse_assignment_else_not_allowed)] +#[diag(" ... else {\"{\"} ... {\"}\"} is not allowed")] pub(crate) struct AssignmentElseNotAllowed { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_expected_statement_after_outer_attr)] +#[diag("expected statement after outer attribute")] pub(crate) struct ExpectedStatementAfterOuterAttr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_doc_comment_does_not_document_anything, code = E0585)] -#[help] +#[diag("found a documentation comment that doesn't document anything", code = E0585)] +#[help("doc comments must come before what they document, if a comment was intended use `//`")] pub(crate) struct DocCommentDoesNotDocumentAnything { #[primary_span] pub span: Span, - #[suggestion(code = ",", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "missing comma here", + code = ",", + applicability = "machine-applicable", + style = "verbose" + )] pub missing_comma: Option, } #[derive(Diagnostic)] -#[diag(parse_const_let_mutually_exclusive)] +#[diag("`const` and `let` are mutually exclusive")] pub(crate) struct ConstLetMutuallyExclusive { #[primary_span] - #[suggestion(code = "const", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "remove `let`", + code = "const", + applicability = "maybe-incorrect", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_invalid_expression_in_let_else)] +#[diag("a `{$operator}` expression cannot be directly assigned in `let...else`")] pub(crate) struct InvalidExpressionInLetElse { #[primary_span] pub span: Span, @@ -1107,7 +1294,7 @@ pub(crate) struct InvalidExpressionInLetElse { } #[derive(Diagnostic)] -#[diag(parse_invalid_curly_in_let_else)] +#[diag("right curly brace `{\"}\"}` before `else` in a `let...else` statement not allowed")] pub(crate) struct InvalidCurlyInLetElse { #[primary_span] pub span: Span, @@ -1116,25 +1303,32 @@ pub(crate) struct InvalidCurlyInLetElse { } #[derive(Diagnostic)] -#[diag(parse_compound_assignment_expression_in_let)] -#[help] +#[diag("can't reassign to an uninitialized variable")] +#[help("if you meant to overwrite, remove the `let` binding")] pub(crate) struct CompoundAssignmentExpressionInLet { #[primary_span] pub span: Span, - #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")] + #[suggestion( + "initialize the variable", + style = "verbose", + code = "", + applicability = "maybe-incorrect" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_suffixed_literal_in_attribute)] -#[help] +#[diag("suffixed literals are not allowed in attributes")] +#[help( + "instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)" +)] pub(crate) struct SuffixedLiteralInAttribute { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_invalid_meta_item)] +#[diag("expected unsuffixed literal, found {$descr}")] pub(crate) struct InvalidMetaItem { #[primary_span] pub span: Span, @@ -1144,7 +1338,10 @@ pub(crate) struct InvalidMetaItem { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_quote_ident_sugg, applicability = "machine-applicable")] +#[multipart_suggestion( + "surround the identifier with quotation marks to make it into a string literal", + applicability = "machine-applicable" +)] pub(crate) struct InvalidMetaItemQuoteIdentSugg { #[suggestion_part(code = "\"")] pub before: Span, @@ -1154,7 +1351,7 @@ pub(crate) struct InvalidMetaItemQuoteIdentSugg { #[derive(Subdiagnostic)] #[suggestion( - parse_sugg_escape_identifier, + "escape `{$ident_name}` to use it as an identifier", style = "verbose", applicability = "maybe-incorrect", code = "r#" @@ -1167,7 +1364,7 @@ pub(crate) struct SuggEscapeIdentifier { #[derive(Subdiagnostic)] #[suggestion( - parse_sugg_remove_comma, + "remove this comma", applicability = "machine-applicable", code = "", style = "verbose" @@ -1179,7 +1376,7 @@ pub(crate) struct SuggRemoveComma { #[derive(Subdiagnostic)] #[suggestion( - parse_sugg_add_let_for_stmt, + "you might have meant to introduce a new binding", style = "verbose", applicability = "maybe-incorrect", code = "let " @@ -1191,17 +1388,17 @@ pub(crate) struct SuggAddMissingLetStmt { #[derive(Subdiagnostic)] pub(crate) enum ExpectedIdentifierFound { - #[label(parse_expected_identifier_found_reserved_identifier)] + #[label("expected identifier, found reserved identifier")] ReservedIdentifier(#[primary_span] Span), - #[label(parse_expected_identifier_found_keyword)] + #[label("expected identifier, found keyword")] Keyword(#[primary_span] Span), - #[label(parse_expected_identifier_found_reserved_keyword)] + #[label("expected identifier, found reserved keyword")] ReservedKeyword(#[primary_span] Span), - #[label(parse_expected_identifier_found_doc_comment)] + #[label("expected identifier, found doc comment")] DocComment(#[primary_span] Span), - #[label(parse_expected_identifier_found_metavar)] + #[label("expected identifier, found metavariable")] MetaVar(#[primary_span] Span), - #[label(parse_expected_identifier)] + #[label("expected identifier")] Other(#[primary_span] Span), } @@ -1239,22 +1436,22 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedIdentifier { level, match token_descr { Some(TokenDescription::ReservedIdentifier) => { - fluent::parse_expected_identifier_found_reserved_identifier_str + inline_fluent!("expected identifier, found reserved identifier `{$token}`") } Some(TokenDescription::Keyword) => { - fluent::parse_expected_identifier_found_keyword_str + inline_fluent!("expected identifier, found keyword `{$token}`") } Some(TokenDescription::ReservedKeyword) => { - fluent::parse_expected_identifier_found_reserved_keyword_str + inline_fluent!("expected identifier, found reserved keyword `{$token}`") } Some(TokenDescription::DocComment) => { - fluent::parse_expected_identifier_found_doc_comment_str + inline_fluent!("expected identifier, found doc comment `{$token}`") } Some(TokenDescription::MetaVar(_)) => { add_token = false; - fluent::parse_expected_identifier_found_metavar_str + inline_fluent!("expected identifier, found metavariable") } - None => fluent::parse_expected_identifier_found_str, + None => inline_fluent!("expected identifier, found `{$token}`"), }, ); diag.span(self.span); @@ -1281,7 +1478,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedIdentifier { } #[derive(Subdiagnostic)] -#[help(parse_invalid_identifier_with_leading_number)] +#[help("identifiers cannot start with a number")] pub(crate) struct HelpIdentifierStartsWithNumber { #[primary_span] pub num_span: Span, @@ -1306,20 +1503,22 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi { level, match token_descr { Some(TokenDescription::ReservedIdentifier) => { - fluent::parse_expected_semi_found_reserved_identifier_str + inline_fluent!("expected `;`, found reserved identifier `{$token}`") + } + Some(TokenDescription::Keyword) => { + inline_fluent!("expected `;`, found keyword `{$token}`") } - Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str, Some(TokenDescription::ReservedKeyword) => { - fluent::parse_expected_semi_found_reserved_keyword_str + inline_fluent!("expected `;`, found reserved keyword `{$token}`") } Some(TokenDescription::DocComment) => { - fluent::parse_expected_semi_found_doc_comment_str + inline_fluent!("expected `;`, found doc comment `{$token}`") } Some(TokenDescription::MetaVar(_)) => { add_token = false; - fluent::parse_expected_semi_found_metavar_str + inline_fluent!("expected `;`, found metavariable") } - None => fluent::parse_expected_semi_found_str, + None => inline_fluent!("expected `;`, found `{$token}`"), }, ); diag.span(self.span); @@ -1328,7 +1527,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi { } if let Some(unexpected_token_label) = self.unexpected_token_label { - diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token); + diag.span_label(unexpected_token_label, inline_fluent!("unexpected token")); } self.sugg.add_to_diag(&mut diag); @@ -1340,23 +1539,18 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi { #[derive(Subdiagnostic)] pub(crate) enum ExpectedSemiSugg { #[suggestion( - parse_sugg_change_this_to_semi, + "change this to `;`", code = ";", applicability = "machine-applicable", style = "short" )] ChangeToSemi(#[primary_span] Span), - #[suggestion( - parse_sugg_add_semi, - code = ";", - applicability = "machine-applicable", - style = "short" - )] + #[suggestion("add `;` here", code = ";", applicability = "machine-applicable", style = "short")] AddSemi(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(parse_struct_literal_body_without_path)] +#[diag("struct literal body without path")] pub(crate) struct StructLiteralBodyWithoutPath { #[primary_span] pub span: Span, @@ -1365,7 +1559,10 @@ pub(crate) struct StructLiteralBodyWithoutPath { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "has-placeholders")] +#[multipart_suggestion( + "you might have forgotten to add the struct literal inside the block", + applicability = "has-placeholders" +)] pub(crate) struct StructLiteralBodyWithoutPathSugg { #[suggestion_part(code = "{{ SomeStruct ")] pub before: Span, @@ -1374,16 +1571,29 @@ pub(crate) struct StructLiteralBodyWithoutPathSugg { } #[derive(Diagnostic)] -#[diag(parse_unmatched_angle_brackets)] +#[diag( + "{$num_extra_brackets -> + [one] unmatched angle bracket + *[other] unmatched angle brackets + }" +)] pub(crate) struct UnmatchedAngleBrackets { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "{$num_extra_brackets -> + [one] remove extra angle bracket + *[other] remove extra angle brackets + }", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, pub num_extra_brackets: usize, } #[derive(Diagnostic)] -#[diag(parse_generic_parameters_without_angle_brackets)] +#[diag("generic parameters without surrounding angle brackets")] pub(crate) struct GenericParamsWithoutAngleBrackets { #[primary_span] pub span: Span, @@ -1392,7 +1602,10 @@ pub(crate) struct GenericParamsWithoutAngleBrackets { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "surround the type parameters with angle brackets", + applicability = "machine-applicable" +)] pub(crate) struct GenericParamsWithoutAngleBracketsSugg { #[suggestion_part(code = "<")] pub left: Span, @@ -1401,19 +1614,19 @@ pub(crate) struct GenericParamsWithoutAngleBracketsSugg { } #[derive(Diagnostic)] -#[diag(parse_comparison_operators_cannot_be_chained)] +#[diag("comparison operators cannot be chained")] pub(crate) struct ComparisonOperatorsCannotBeChained { #[primary_span] pub span: Vec, #[suggestion( - parse_sugg_turbofish_syntax, + "use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments", style = "verbose", code = "::", applicability = "maybe-incorrect" )] pub suggest_turbofish: Option, - #[help(parse_sugg_turbofish_syntax)] - #[help(parse_sugg_parentheses_for_function_args)] + #[help("use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments")] + #[help("or use `(...)` if you meant to specify fn arguments")] pub help_turbofish: bool, #[subdiagnostic] pub chaining_sugg: Option, @@ -1422,7 +1635,7 @@ pub(crate) struct ComparisonOperatorsCannotBeChained { #[derive(Subdiagnostic)] pub(crate) enum ComparisonOperatorsCannotBeChainedSugg { #[suggestion( - parse_sugg_split_comparison, + "split the comparison into two", style = "verbose", code = " && {middle_term}", applicability = "maybe-incorrect" @@ -1432,7 +1645,7 @@ pub(crate) enum ComparisonOperatorsCannotBeChainedSugg { span: Span, middle_term: String, }, - #[multipart_suggestion(parse_sugg_parenthesize, applicability = "maybe-incorrect")] + #[multipart_suggestion("parenthesize the comparison", applicability = "maybe-incorrect")] Parenthesize { #[suggestion_part(code = "(")] left: Span, @@ -1442,17 +1655,20 @@ pub(crate) enum ComparisonOperatorsCannotBeChainedSugg { } #[derive(Diagnostic)] -#[diag(parse_question_mark_in_type)] +#[diag("invalid `?` in type")] pub(crate) struct QuestionMarkInType { #[primary_span] - #[label] + #[label("`?` is only allowed on expressions, not types")] pub span: Span, #[subdiagnostic] pub sugg: QuestionMarkInTypeSugg, } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "if you meant to express that the type might not contain a value, use the `Option` wrapper type", + applicability = "machine-applicable" +)] pub(crate) struct QuestionMarkInTypeSugg { #[suggestion_part(code = "Option<")] pub left: Span, @@ -1461,7 +1677,7 @@ pub(crate) struct QuestionMarkInTypeSugg { } #[derive(Diagnostic)] -#[diag(parse_unexpected_parentheses_in_for_head)] +#[diag("unexpected parentheses surrounding `for` loop head")] pub(crate) struct ParenthesesInForHead { #[primary_span] pub span: Vec, @@ -1470,7 +1686,7 @@ pub(crate) struct ParenthesesInForHead { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion("remove parentheses in `for` loop", applicability = "machine-applicable")] pub(crate) struct ParenthesesInForHeadSugg { #[suggestion_part(code = " ")] pub left: Span, @@ -1479,7 +1695,7 @@ pub(crate) struct ParenthesesInForHeadSugg { } #[derive(Diagnostic)] -#[diag(parse_unexpected_parentheses_in_match_arm_pattern)] +#[diag("unexpected parentheses surrounding `match` arm pattern")] pub(crate) struct ParenthesesInMatchPat { #[primary_span] pub span: Vec, @@ -1488,7 +1704,10 @@ pub(crate) struct ParenthesesInMatchPat { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "remove parentheses surrounding the pattern", + applicability = "machine-applicable" +)] pub(crate) struct ParenthesesInMatchPatSugg { #[suggestion_part(code = "")] pub left: Span, @@ -1497,67 +1716,82 @@ pub(crate) struct ParenthesesInMatchPatSugg { } #[derive(Diagnostic)] -#[diag(parse_doc_comment_on_param_type)] +#[diag("documentation comments cannot be applied to a function parameter's type")] pub(crate) struct DocCommentOnParamType { #[primary_span] - #[label] + #[label("doc comments are not allowed here")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_attribute_on_param_type)] +#[diag("attributes cannot be applied to a function parameter's type")] pub(crate) struct AttributeOnParamType { #[primary_span] - #[label] + #[label("attributes are not allowed here")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_attribute_on_type)] +#[diag("attributes cannot be applied to types")] pub(crate) struct AttributeOnType { #[primary_span] - #[label] + #[label("attributes are not allowed here")] pub span: Span, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove attribute from here", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub fix_span: Span, } #[derive(Diagnostic)] -#[diag(parse_attribute_on_generic_arg)] +#[diag("attributes cannot be applied to generic arguments")] pub(crate) struct AttributeOnGenericArg { #[primary_span] - #[label] + #[label("attributes are not allowed here")] pub span: Span, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove attribute from here", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub fix_span: Span, } #[derive(Diagnostic)] -#[diag(parse_attribute_on_empty_type)] +#[diag("attributes cannot be applied here")] pub(crate) struct AttributeOnEmptyType { #[primary_span] - #[label] + #[label("attributes are not allowed here")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_pattern_method_param_without_body, code = E0642)] +#[diag("patterns aren't allowed in methods without bodies", code = E0642)] pub(crate) struct PatternMethodParamWithoutBody { #[primary_span] - #[suggestion(code = "_", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "give this argument a name or use an underscore to ignore it", + code = "_", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_self_param_not_first)] +#[diag("unexpected `self` parameter in function")] pub(crate) struct SelfParamNotFirst { #[primary_span] - #[label] + #[label("must be the first parameter of an associated function")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_const_generic_without_braces)] +#[diag("expressions must be enclosed in braces to be used as const generic arguments")] pub(crate) struct ConstGenericWithoutBraces { #[primary_span] pub span: Span, @@ -1566,7 +1800,10 @@ pub(crate) struct ConstGenericWithoutBraces { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "enclose the `const` expression in braces", + applicability = "machine-applicable" +)] pub(crate) struct ConstGenericWithoutBracesSugg { #[suggestion_part(code = "{{ ")] pub left: Span, @@ -1575,10 +1812,10 @@ pub(crate) struct ConstGenericWithoutBracesSugg { } #[derive(Diagnostic)] -#[diag(parse_unexpected_const_param_declaration)] +#[diag("unexpected `const` parameter declaration")] pub(crate) struct UnexpectedConstParamDeclaration { #[primary_span] - #[label] + #[label("expected a `const` expression, not a parameter declaration")] pub span: Span, #[subdiagnostic] pub sugg: Option, @@ -1586,7 +1823,10 @@ pub(crate) struct UnexpectedConstParamDeclaration { #[derive(Subdiagnostic)] pub(crate) enum UnexpectedConstParamDeclarationSugg { - #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] + #[multipart_suggestion( + "`const` parameters must be declared for the `impl`", + applicability = "machine-applicable" + )] AddParam { #[suggestion_part(code = "<{snippet}>")] impl_generics: Span, @@ -1595,7 +1835,10 @@ pub(crate) enum UnexpectedConstParamDeclarationSugg { snippet: String, ident: String, }, - #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] + #[multipart_suggestion( + "`const` parameters must be declared for the `impl`", + applicability = "machine-applicable" + )] AppendParam { #[suggestion_part(code = ", {snippet}")] impl_generics_end: Span, @@ -1607,41 +1850,61 @@ pub(crate) enum UnexpectedConstParamDeclarationSugg { } #[derive(Diagnostic)] -#[diag(parse_unexpected_const_in_generic_param)] +#[diag("expected lifetime, type, or constant, found keyword `const`")] pub(crate) struct UnexpectedConstInGenericParam { #[primary_span] pub span: Span, - #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")] + #[suggestion( + "the `const` keyword is only needed in the definition of the type", + style = "verbose", + code = "", + applicability = "maybe-incorrect" + )] pub to_remove: Option, } #[derive(Diagnostic)] -#[diag(parse_async_move_order_incorrect)] +#[diag("the order of `move` and `async` is incorrect")] pub(crate) struct AsyncMoveOrderIncorrect { #[primary_span] - #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")] + #[suggestion( + "try switching the order", + style = "verbose", + code = "async move", + applicability = "maybe-incorrect" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_async_use_order_incorrect)] +#[diag("the order of `use` and `async` is incorrect")] pub(crate) struct AsyncUseOrderIncorrect { #[primary_span] - #[suggestion(style = "verbose", code = "async use", applicability = "maybe-incorrect")] + #[suggestion( + "try switching the order", + style = "verbose", + code = "async use", + applicability = "maybe-incorrect" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_double_colon_in_bound)] +#[diag("expected `:` followed by trait or lifetime")] pub(crate) struct DoubleColonInBound { #[primary_span] pub span: Span, - #[suggestion(code = ": ", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "use single colon", + code = ": ", + applicability = "machine-applicable", + style = "verbose" + )] pub between: Span, } #[derive(Diagnostic)] -#[diag(parse_fn_ptr_with_generics)] +#[diag("function pointer types may not have generic parameters")] pub(crate) struct FnPtrWithGenerics { #[primary_span] pub span: Span, @@ -1651,7 +1914,7 @@ pub(crate) struct FnPtrWithGenerics { #[derive(Subdiagnostic)] #[multipart_suggestion( - parse_misplaced_return_type, + "place the return type after the function parameters", style = "verbose", applicability = "maybe-incorrect" )] @@ -1664,7 +1927,16 @@ pub(crate) struct MisplacedReturnType { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "consider moving the lifetime {$arity -> + [one] parameter + *[other] parameters + } to {$for_param_list_exists -> + [true] the + *[false] a + } `for` parameter list", + applicability = "maybe-incorrect" +)] pub(crate) struct FnPtrWithGenericsSugg { #[suggestion_part(code = "{snippet}")] pub left: Span, @@ -1681,10 +1953,10 @@ pub(crate) struct FnTraitMissingParen { impl Subdiagnostic for FnTraitMissingParen { fn add_to_diag(self, diag: &mut Diag<'_, G>) { - diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren); + diag.span_label(self.span, inline_fluent!("`Fn` bounds require arguments in parentheses")); diag.span_suggestion_short( self.span.shrink_to_hi(), - crate::fluent_generated::parse_add_paren, + inline_fluent!("try adding parentheses"), "()", Applicability::MachineApplicable, ); @@ -1692,95 +1964,128 @@ impl Subdiagnostic for FnTraitMissingParen { } #[derive(Diagnostic)] -#[diag(parse_unexpected_if_with_if)] +#[diag("unexpected `if` in the condition expression")] pub(crate) struct UnexpectedIfWithIf( #[primary_span] - #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")] + #[suggestion( + "remove the `if`", + applicability = "machine-applicable", + code = " ", + style = "verbose" + )] pub Span, ); #[derive(Diagnostic)] -#[diag(parse_maybe_fn_typo_with_impl)] +#[diag("you might have meant to write `impl` instead of `fn`")] pub(crate) struct FnTypoWithImpl { #[primary_span] - #[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")] + #[suggestion( + "replace `fn` with `impl` here", + applicability = "maybe-incorrect", + code = "impl", + style = "verbose" + )] pub fn_span: Span, } #[derive(Diagnostic)] -#[diag(parse_expected_fn_path_found_fn_keyword)] +#[diag("expected identifier, found keyword `fn`")] pub(crate) struct ExpectedFnPathFoundFnKeyword { #[primary_span] - #[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")] + #[suggestion( + "use `Fn` to refer to the trait", + applicability = "machine-applicable", + code = "Fn", + style = "verbose" + )] pub fn_token_span: Span, } #[derive(Diagnostic)] -#[diag(parse_path_found_named_params)] +#[diag("`Trait(...)` syntax does not support named parameters")] pub(crate) struct FnPathFoundNamedParams { #[primary_span] - #[suggestion(applicability = "machine-applicable", code = "")] + #[suggestion("remove the parameter name", applicability = "machine-applicable", code = "")] pub named_param_span: Span, } #[derive(Diagnostic)] -#[diag(parse_path_found_c_variadic_params)] +#[diag("`Trait(...)` syntax does not support c_variadic parameters")] pub(crate) struct PathFoundCVariadicParams { #[primary_span] - #[suggestion(applicability = "machine-applicable", code = "")] + #[suggestion("remove the `...`", applicability = "machine-applicable", code = "")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_path_found_attribute_in_params)] +#[diag("`Trait(...)` syntax does not support attributes in parameters")] pub(crate) struct PathFoundAttributeInParams { #[primary_span] - #[suggestion(applicability = "machine-applicable", code = "")] + #[suggestion("remove the attributes", applicability = "machine-applicable", code = "")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_path_double_colon)] +#[diag("path separator must be a double colon")] pub(crate) struct PathSingleColon { #[primary_span] pub span: Span, - #[suggestion(applicability = "machine-applicable", code = ":", style = "verbose")] + #[suggestion( + "use a double colon instead", + applicability = "machine-applicable", + code = ":", + style = "verbose" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_path_double_colon)] +#[diag("path separator must be a double colon")] pub(crate) struct PathTripleColon { #[primary_span] - #[suggestion(applicability = "maybe-incorrect", code = "", style = "verbose")] + #[suggestion( + "use a double colon instead", + applicability = "maybe-incorrect", + code = "", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_colon_as_semi)] +#[diag("statements are terminated with a semicolon")] pub(crate) struct ColonAsSemi { #[primary_span] - #[suggestion(applicability = "machine-applicable", code = ";", style = "verbose")] + #[suggestion( + "use a semicolon instead", + applicability = "machine-applicable", + code = ";", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_where_clause_before_tuple_struct_body)] +#[diag("where clauses are not allowed before tuple struct bodies")] pub(crate) struct WhereClauseBeforeTupleStructBody { #[primary_span] - #[label] + #[label("unexpected where clause")] pub span: Span, - #[label(parse_name_label)] + #[label("while parsing this tuple struct")] pub name: Span, - #[label(parse_body_label)] + #[label("the struct body")] pub body: Span, #[subdiagnostic] pub sugg: Option, } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "move the body before the where clause", + applicability = "machine-applicable" +)] pub(crate) struct WhereClauseBeforeTupleStructBodySugg { #[suggestion_part(code = "{snippet}")] pub left: Span, @@ -1790,38 +2095,38 @@ pub(crate) struct WhereClauseBeforeTupleStructBodySugg { } #[derive(Diagnostic)] -#[diag(parse_async_fn_in_2015, code = E0670)] +#[diag("`async fn` is not permitted in Rust 2015", code = E0670)] pub(crate) struct AsyncFnIn2015 { #[primary_span] - #[label] + #[label("to use `async fn`, switch to Rust 2018 or later")] pub span: Span, #[subdiagnostic] pub help: HelpUseLatestEdition, } #[derive(Subdiagnostic)] -#[label(parse_async_block_in_2015)] +#[label("`async` blocks are only allowed in Rust 2018 or later")] pub(crate) struct AsyncBlockIn2015 { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_async_move_block_in_2015)] +#[diag("`async move` blocks are only allowed in Rust 2018 or later")] pub(crate) struct AsyncMoveBlockIn2015 { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_async_use_block_in_2015)] +#[diag("`async use` blocks are only allowed in Rust 2018 or later")] pub(crate) struct AsyncUseBlockIn2015 { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_async_bound_modifier_in_2015)] +#[diag("`async` trait bounds are only allowed in Rust 2018 or later")] pub(crate) struct AsyncBoundModifierIn2015 { #[primary_span] pub span: Span, @@ -1830,22 +2135,22 @@ pub(crate) struct AsyncBoundModifierIn2015 { } #[derive(Diagnostic)] -#[diag(parse_let_chain_pre_2024)] +#[diag("let chains are only allowed in Rust 2024 or later")] pub(crate) struct LetChainPre2024 { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_self_argument_pointer)] +#[diag("cannot pass `self` by raw pointer")] pub(crate) struct SelfArgumentPointer { #[primary_span] - #[label] + #[label("cannot pass `self` by raw pointer")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_unexpected_token_after_dot)] +#[diag("unexpected token: {$actual}")] pub(crate) struct UnexpectedTokenAfterDot { #[primary_span] pub span: Span, @@ -1853,64 +2158,84 @@ pub(crate) struct UnexpectedTokenAfterDot { } #[derive(Diagnostic)] -#[diag(parse_visibility_not_followed_by_item)] -#[help] +#[diag("visibility `{$vis}` is not followed by an item")] +#[help("you likely meant to define an item, e.g., `{$vis} fn foo() {\"{}\"}`")] pub(crate) struct VisibilityNotFollowedByItem { #[primary_span] - #[label] + #[label("the visibility")] pub span: Span, pub vis: Visibility, } #[derive(Diagnostic)] -#[diag(parse_default_not_followed_by_item)] -#[note] +#[diag("`default` is not followed by an item")] +#[note("only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`")] pub(crate) struct DefaultNotFollowedByItem { #[primary_span] - #[label] + #[label("the `default` qualifier")] pub span: Span, } #[derive(Diagnostic)] pub(crate) enum MissingKeywordForItemDefinition { - #[diag(parse_missing_enum_for_enum_definition)] + #[diag("missing `enum` for enum definition")] Enum { #[primary_span] span: Span, - #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "enum ")] + #[suggestion( + "add `enum` here to parse `{$ident}` as an enum", + style = "verbose", + applicability = "maybe-incorrect", + code = "enum " + )] insert_span: Span, ident: Ident, }, - #[diag(parse_missing_enum_or_struct_for_item_definition)] + #[diag("missing `enum` or `struct` for enum or struct definition")] EnumOrStruct { #[primary_span] span: Span, }, - #[diag(parse_missing_struct_for_struct_definition)] + #[diag("missing `struct` for struct definition")] Struct { #[primary_span] span: Span, - #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "struct ")] + #[suggestion( + "add `struct` here to parse `{$ident}` as a struct", + style = "verbose", + applicability = "maybe-incorrect", + code = "struct " + )] insert_span: Span, ident: Ident, }, - #[diag(parse_missing_fn_for_function_definition)] + #[diag("missing `fn` for function definition")] Function { #[primary_span] span: Span, - #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "fn ")] + #[suggestion( + "add `fn` here to parse `{$ident}` as a function", + style = "verbose", + applicability = "maybe-incorrect", + code = "fn " + )] insert_span: Span, ident: Ident, }, - #[diag(parse_missing_fn_for_method_definition)] + #[diag("missing `fn` for method definition")] Method { #[primary_span] span: Span, - #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "fn ")] + #[suggestion( + "add `fn` here to parse `{$ident}` as a method", + style = "verbose", + applicability = "maybe-incorrect", + code = "fn " + )] insert_span: Span, ident: Ident, }, - #[diag(parse_missing_fn_or_struct_for_item_definition)] + #[diag("missing `fn` or `struct` for function or struct definition")] Ambiguous { #[primary_span] span: Span, @@ -1922,7 +2247,7 @@ pub(crate) enum MissingKeywordForItemDefinition { #[derive(Subdiagnostic)] pub(crate) enum AmbiguousMissingKwForItemSub { #[suggestion( - parse_suggestion, + "if you meant to call a macro, try", applicability = "maybe-incorrect", code = "{snippet}!", style = "verbose" @@ -1932,39 +2257,49 @@ pub(crate) enum AmbiguousMissingKwForItemSub { span: Span, snippet: String, }, - #[help(parse_help)] + #[help("you likely meant to define an item, e.g., `{$vis} fn foo() {\"{}\"}`")] HelpMacro, } #[derive(Diagnostic)] -#[diag(parse_missing_fn_params)] +#[diag("missing parameters for function definition")] pub(crate) struct MissingFnParams { #[primary_span] - #[suggestion(code = "()", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "add a parameter list", + code = "()", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_invalid_path_sep_in_fn_definition)] +#[diag("invalid path separator in function definition")] pub(crate) struct InvalidPathSepInFnDefinition { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove invalid path separator", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_missing_trait_in_trait_impl)] +#[diag("missing trait in a trait impl")] pub(crate) struct MissingTraitInTraitImpl { #[primary_span] #[suggestion( - parse_suggestion_add_trait, + "add a trait here", code = " Trait ", applicability = "has-placeholders", style = "verbose" )] pub span: Span, #[suggestion( - parse_suggestion_remove_for, + "for an inherent impl, drop this `for`", code = "", applicability = "maybe-incorrect", style = "verbose" @@ -1973,102 +2308,130 @@ pub(crate) struct MissingTraitInTraitImpl { } #[derive(Diagnostic)] -#[diag(parse_missing_for_in_trait_impl)] +#[diag("missing `for` in a trait impl")] pub(crate) struct MissingForInTraitImpl { #[primary_span] - #[suggestion(style = "verbose", code = " for ", applicability = "machine-applicable")] + #[suggestion( + "add `for` here", + style = "verbose", + code = " for ", + applicability = "machine-applicable" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_expected_trait_in_trait_impl_found_type)] +#[diag("expected a trait, found type")] pub(crate) struct ExpectedTraitInTraitImplFoundType { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_extra_impl_keyword_in_trait_impl)] +#[diag("unexpected `impl` keyword")] pub(crate) struct ExtraImplKeywordInTraitImpl { #[primary_span] - #[suggestion(code = "", applicability = "maybe-incorrect", style = "short")] + #[suggestion( + "remove the extra `impl`", + code = "", + applicability = "maybe-incorrect", + style = "short" + )] pub extra_impl_kw: Span, - #[note] + #[note("this is parsed as an `impl Trait` type, but a trait is expected at this position")] pub impl_trait_span: Span, } #[derive(Diagnostic)] -#[diag(parse_bounds_not_allowed_on_trait_aliases)] +#[diag("bounds are not allowed on trait aliases")] pub(crate) struct BoundsNotAllowedOnTraitAliases { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_trait_alias_cannot_be_auto)] +#[diag("trait aliases cannot be `auto`")] pub(crate) struct TraitAliasCannotBeAuto { #[primary_span] - #[label(parse_trait_alias_cannot_be_auto)] + #[label("trait aliases cannot be `auto`")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_trait_alias_cannot_be_unsafe)] +#[diag("trait aliases cannot be `unsafe`")] pub(crate) struct TraitAliasCannotBeUnsafe { #[primary_span] - #[label(parse_trait_alias_cannot_be_unsafe)] + #[label("trait aliases cannot be `unsafe`")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_associated_static_item_not_allowed)] +#[diag("associated `static` items are not allowed")] pub(crate) struct AssociatedStaticItemNotAllowed { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_extern_crate_name_with_dashes)] +#[diag("crate name using dashes are not valid in `extern crate` statements")] pub(crate) struct ExternCrateNameWithDashes { #[primary_span] - #[label] + #[label("dash-separated idents are not valid")] pub span: Span, #[subdiagnostic] pub sugg: ExternCrateNameWithDashesSugg, } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "if the original crate name uses dashes you need to use underscores in the code", + applicability = "machine-applicable" +)] pub(crate) struct ExternCrateNameWithDashesSugg { #[suggestion_part(code = "_")] pub dashes: Vec, } #[derive(Diagnostic)] -#[diag(parse_extern_item_cannot_be_const)] -#[note] +#[diag("extern items cannot be `const`")] +#[note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")] pub(crate) struct ExternItemCannotBeConst { #[primary_span] pub ident_span: Span, - #[suggestion(code = "static ", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "try using a static value", + code = "static ", + applicability = "machine-applicable", + style = "verbose" + )] pub const_span: Option, } #[derive(Diagnostic)] -#[diag(parse_const_global_cannot_be_mutable)] +#[diag("const globals cannot be mutable")] pub(crate) struct ConstGlobalCannotBeMutable { #[primary_span] - #[label] + #[label("cannot be mutable")] pub ident_span: Span, - #[suggestion(code = "static", style = "verbose", applicability = "maybe-incorrect")] + #[suggestion( + "you might want to declare a static instead", + code = "static", + style = "verbose", + applicability = "maybe-incorrect" + )] pub const_span: Span, } #[derive(Diagnostic)] -#[diag(parse_missing_const_type)] +#[diag("missing type for `{$kind}` item")] pub(crate) struct MissingConstType { #[primary_span] - #[suggestion(code = "{colon} ", style = "verbose", applicability = "has-placeholders")] + #[suggestion( + "provide a type for the item", + code = "{colon} ", + style = "verbose", + applicability = "has-placeholders" + )] pub span: Span, pub kind: &'static str, @@ -2076,53 +2439,64 @@ pub(crate) struct MissingConstType { } #[derive(Diagnostic)] -#[diag(parse_enum_struct_mutually_exclusive)] +#[diag("`enum` and `struct` are mutually exclusive")] pub(crate) struct EnumStructMutuallyExclusive { #[primary_span] - #[suggestion(code = "enum", style = "verbose", applicability = "machine-applicable")] + #[suggestion( + "replace `enum struct` with", + code = "enum", + style = "verbose", + applicability = "machine-applicable" + )] pub span: Span, } #[derive(Diagnostic)] pub(crate) enum UnexpectedTokenAfterStructName { - #[diag(parse_unexpected_token_after_struct_name_found_reserved_identifier)] + #[diag( + "expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found reserved identifier `{$token}`" + )] ReservedIdentifier { #[primary_span] - #[label(parse_unexpected_token_after_struct_name)] + #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] span: Span, token: Token, }, - #[diag(parse_unexpected_token_after_struct_name_found_keyword)] + #[diag("expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found keyword `{$token}`")] Keyword { #[primary_span] - #[label(parse_unexpected_token_after_struct_name)] + #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] span: Span, token: Token, }, - #[diag(parse_unexpected_token_after_struct_name_found_reserved_keyword)] + #[diag( + "expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found reserved keyword `{$token}`" + )] ReservedKeyword { #[primary_span] - #[label(parse_unexpected_token_after_struct_name)] + #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] span: Span, token: Token, }, - #[diag(parse_unexpected_token_after_struct_name_found_doc_comment)] + #[diag( + "expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found doc comment `{$token}`" + )] DocComment { #[primary_span] - #[label(parse_unexpected_token_after_struct_name)] + #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] span: Span, token: Token, }, - #[diag(parse_unexpected_token_after_struct_name_found_metavar)] + #[diag("expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found metavar")] MetaVar { #[primary_span] - #[label(parse_unexpected_token_after_struct_name)] + #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] span: Span, }, - #[diag(parse_unexpected_token_after_struct_name_found_other)] + #[diag("expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found `{$token}`")] Other { #[primary_span] - #[label(parse_unexpected_token_after_struct_name)] + #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] span: Span, token: Token, }, @@ -2142,45 +2516,50 @@ impl UnexpectedTokenAfterStructName { } #[derive(Diagnostic)] -#[diag(parse_unexpected_self_in_generic_parameters)] -#[note] +#[diag("unexpected keyword `Self` in generic parameters")] +#[note("you cannot use `Self` as a generic parameter because it is reserved for associated items")] pub(crate) struct UnexpectedSelfInGenericParameters { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_unexpected_default_value_for_lifetime_in_generic_parameters)] +#[diag("unexpected default lifetime parameter")] pub(crate) struct UnexpectedDefaultValueForLifetimeInGenericParameters { #[primary_span] - #[label] + #[label("lifetime parameters cannot have default values")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_multiple_where_clauses)] +#[diag("cannot define duplicate `where` clauses on an item")] pub(crate) struct MultipleWhereClauses { #[primary_span] pub span: Span, - #[label] + #[label("previous `where` clause starts here")] pub previous: Span, - #[suggestion(style = "verbose", code = ",", applicability = "maybe-incorrect")] + #[suggestion( + "consider joining the two `where` clauses into one", + style = "verbose", + code = ",", + applicability = "maybe-incorrect" + )] pub between: Span, } #[derive(Diagnostic)] pub(crate) enum UnexpectedNonterminal { - #[diag(parse_nonterminal_expected_item_keyword)] + #[diag("expected an item keyword")] Item(#[primary_span] Span), - #[diag(parse_nonterminal_expected_statement)] + #[diag("expected a statement")] Statement(#[primary_span] Span), - #[diag(parse_nonterminal_expected_ident)] + #[diag("expected ident, found `{$token}`")] Ident { #[primary_span] span: Span, token: Token, }, - #[diag(parse_nonterminal_expected_lifetime)] + #[diag("expected a lifetime, found `{$token}`")] Lifetime { #[primary_span] span: Span, @@ -2190,14 +2569,14 @@ pub(crate) enum UnexpectedNonterminal { #[derive(Diagnostic)] pub(crate) enum TopLevelOrPatternNotAllowed { - #[diag(parse_or_pattern_not_allowed_in_let_binding)] + #[diag("`let` bindings require top-level or-patterns in parentheses")] LetBinding { #[primary_span] span: Span, #[subdiagnostic] sub: Option, }, - #[diag(parse_or_pattern_not_allowed_in_fn_parameters)] + #[diag("function parameters require top-level or-patterns in parentheses")] FunctionParameter { #[primary_span] span: Span, @@ -2207,7 +2586,7 @@ pub(crate) enum TopLevelOrPatternNotAllowed { } #[derive(Diagnostic)] -#[diag(parse_cannot_be_raw_ident)] +#[diag("`{$ident}` cannot be a raw identifier")] pub(crate) struct CannotBeRawIdent { #[primary_span] pub span: Span, @@ -2215,7 +2594,7 @@ pub(crate) struct CannotBeRawIdent { } #[derive(Diagnostic)] -#[diag(parse_cannot_be_raw_lifetime)] +#[diag("`{$ident}` cannot be a raw lifetime")] pub(crate) struct CannotBeRawLifetime { #[primary_span] pub span: Span, @@ -2223,21 +2602,26 @@ pub(crate) struct CannotBeRawLifetime { } #[derive(Diagnostic)] -#[diag(parse_keyword_lifetime)] +#[diag("lifetimes cannot use keyword names")] pub(crate) struct KeywordLifetime { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_keyword_label)] +#[diag("labels cannot use keyword names")] pub(crate) struct KeywordLabel { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_cr_doc_comment)] +#[diag( + "bare CR not allowed in {$block -> + [true] block doc-comment + *[false] doc-comment + }" +)] pub(crate) struct CrDocComment { #[primary_span] pub span: Span, @@ -2245,14 +2629,14 @@ pub(crate) struct CrDocComment { } #[derive(Diagnostic)] -#[diag(parse_no_digits_literal, code = E0768)] +#[diag("no valid digits found for number", code = E0768)] pub(crate) struct NoDigitsLiteral { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_invalid_digit_literal)] +#[diag("invalid digit for a base {$base} literal")] pub(crate) struct InvalidDigitLiteral { #[primary_span] pub span: Span, @@ -2260,14 +2644,14 @@ pub(crate) struct InvalidDigitLiteral { } #[derive(Diagnostic)] -#[diag(parse_empty_exponent_float)] +#[diag("expected at least one digit in exponent")] pub(crate) struct EmptyExponentFloat { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_float_literal_unsupported_base)] +#[diag("{$base} float literal is not supported")] pub(crate) struct FloatLiteralUnsupportedBase { #[primary_span] pub span: Span, @@ -2275,11 +2659,11 @@ pub(crate) struct FloatLiteralUnsupportedBase { } #[derive(Diagnostic)] -#[diag(parse_unknown_prefix)] -#[note] +#[diag("prefix `{$prefix}` is unknown")] +#[note("prefixed identifiers and literals are reserved since Rust 2021")] pub(crate) struct UnknownPrefix<'a> { #[primary_span] - #[label] + #[label("unknown prefix")] pub span: Span, pub prefix: &'a str, #[subdiagnostic] @@ -2287,7 +2671,7 @@ pub(crate) struct UnknownPrefix<'a> { } #[derive(Subdiagnostic)] -#[note(parse_macro_expands_to_adt_field)] +#[note("macros cannot expand to {$adt_ty} fields")] pub(crate) struct MacroExpandsToAdtField<'a> { pub adt_ty: &'a str, } @@ -2295,28 +2679,28 @@ pub(crate) struct MacroExpandsToAdtField<'a> { #[derive(Subdiagnostic)] pub(crate) enum UnknownPrefixSugg { #[suggestion( - parse_suggestion_br, + "use `br` for a raw byte string", code = "br", applicability = "maybe-incorrect", style = "verbose" )] UseBr(#[primary_span] Span), #[suggestion( - parse_suggestion_cr, + "use `cr` for a raw C-string", code = "cr", applicability = "maybe-incorrect", style = "verbose" )] UseCr(#[primary_span] Span), #[suggestion( - parse_suggestion_whitespace, + "consider inserting whitespace here", code = " ", applicability = "maybe-incorrect", style = "verbose" )] Whitespace(#[primary_span] Span), #[multipart_suggestion( - parse_suggestion_str, + "if you meant to write a string literal, use double quotes", applicability = "maybe-incorrect", style = "verbose" )] @@ -2329,8 +2713,8 @@ pub(crate) enum UnknownPrefixSugg { } #[derive(Diagnostic)] -#[diag(parse_reserved_multihash)] -#[note] +#[diag("reserved multi-hash token is forbidden")] +#[note("sequences of two or more # are reserved for future use since Rust 2024")] pub(crate) struct ReservedMultihash { #[primary_span] pub span: Span, @@ -2338,8 +2722,8 @@ pub(crate) struct ReservedMultihash { pub sugg: Option, } #[derive(Diagnostic)] -#[diag(parse_reserved_string)] -#[note] +#[diag("invalid string literal")] +#[note("unprefixed guarded string literals are reserved for future use since Rust 2024")] pub(crate) struct ReservedString { #[primary_span] pub span: Span, @@ -2348,7 +2732,7 @@ pub(crate) struct ReservedString { } #[derive(Subdiagnostic)] #[suggestion( - parse_suggestion_whitespace, + "consider inserting whitespace here", code = " ", applicability = "maybe-incorrect", style = "verbose" @@ -2356,7 +2740,9 @@ pub(crate) struct ReservedString { pub(crate) struct GuardedStringSugg(#[primary_span] pub Span); #[derive(Diagnostic)] -#[diag(parse_too_many_hashes)] +#[diag( + "too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found {$num}" +)] pub(crate) struct TooManyHashes { #[primary_span] pub span: Span, @@ -2364,7 +2750,7 @@ pub(crate) struct TooManyHashes { } #[derive(Diagnostic)] -#[diag(parse_unknown_start_of_token)] +#[diag("unknown start of token: {$escaped}")] pub(crate) struct UnknownTokenStart { #[primary_span] pub span: Span, @@ -2382,7 +2768,7 @@ pub(crate) struct UnknownTokenStart { #[derive(Subdiagnostic)] pub(crate) enum TokenSubstitution { #[suggestion( - parse_sugg_quotes, + "Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '{$ascii_str}' ({$ascii_name}), but are not", code = "{suggestion}", applicability = "maybe-incorrect", style = "verbose" @@ -2395,7 +2781,7 @@ pub(crate) enum TokenSubstitution { ascii_name: &'static str, }, #[suggestion( - parse_sugg_other, + "Unicode character '{$ch}' ({$u_name}) looks like '{$ascii_str}' ({$ascii_name}), but it is not", code = "{suggestion}", applicability = "maybe-incorrect", style = "verbose" @@ -2412,35 +2798,52 @@ pub(crate) enum TokenSubstitution { } #[derive(Subdiagnostic)] -#[note(parse_note_repeats)] +#[note( + "character appears {$repeats -> + [one] once more + *[other] {$repeats} more times + }" +)] pub(crate) struct UnknownTokenRepeat { pub repeats: usize, } #[derive(Subdiagnostic)] -#[help(parse_help_invisible_char)] +#[help("invisible characters like '{$escaped}' are not usually visible in text editors")] pub(crate) struct InvisibleCharacter; #[derive(Subdiagnostic)] -#[help(parse_help_null)] +#[help( + "source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used" +)] pub(crate) struct UnknownTokenNull; #[derive(Diagnostic)] pub(crate) enum UnescapeError { - #[diag(parse_invalid_unicode_escape)] - #[help] + #[diag("invalid unicode character escape")] + #[help( + "unicode escape must {$surrogate -> + [true] not be a surrogate + *[false] be at most 10FFFF + }" + )] InvalidUnicodeEscape { #[primary_span] - #[label] + #[label("invalid escape")] span: Span, surrogate: bool, }, - #[diag(parse_escape_only_char)] + #[diag( + "{$byte -> + [true] byte + *[false] character + } constant must be escaped: `{$escaped_msg}`" + )] EscapeOnlyChar { #[primary_span] span: Span, #[suggestion( - parse_escape, + "escape the character", applicability = "machine-applicable", code = "{escaped_sugg}", style = "verbose" @@ -2450,11 +2853,16 @@ pub(crate) enum UnescapeError { escaped_msg: String, byte: bool, }, - #[diag(parse_bare_cr)] + #[diag( + r#"{$double_quotes -> + [true] bare CR not allowed in string, use `\r` instead + *[false] character constant must be escaped: `\r` + }"# + )] BareCr { #[primary_span] #[suggestion( - parse_escape, + "escape the character", applicability = "machine-applicable", code = "\\r", style = "verbose" @@ -2462,93 +2870,103 @@ pub(crate) enum UnescapeError { span: Span, double_quotes: bool, }, - #[diag(parse_bare_cr_in_raw_string)] + #[diag("bare CR not allowed in raw string")] BareCrRawString(#[primary_span] Span), - #[diag(parse_too_short_hex_escape)] + #[diag("numeric character escape is too short")] TooShortHexEscape(#[primary_span] Span), - #[diag(parse_invalid_char_in_escape)] + #[diag( + "invalid character in {$is_hex -> + [true] numeric character + *[false] unicode + } escape: `{$ch}`" + )] InvalidCharInEscape { #[primary_span] - #[label] + #[label( + "invalid character in {$is_hex -> + [true] numeric character + *[false] unicode + } escape" + )] span: Span, is_hex: bool, ch: String, }, - #[diag(parse_leading_underscore_unicode_escape)] + #[diag("invalid start of unicode escape: `_`")] LeadingUnderscoreUnicodeEscape { #[primary_span] - #[label(parse_leading_underscore_unicode_escape_label)] + #[label("invalid start of unicode escape")] span: Span, ch: String, }, - #[diag(parse_overlong_unicode_escape)] + #[diag("overlong unicode escape")] OverlongUnicodeEscape( #[primary_span] - #[label] + #[label("must have at most 6 hex digits")] Span, ), - #[diag(parse_unclosed_unicode_escape)] + #[diag("unterminated unicode escape")] UnclosedUnicodeEscape( #[primary_span] - #[label] + #[label(r#"missing a closing `{"}"}`"#)] Span, #[suggestion( - parse_terminate, + "terminate the unicode escape", code = "}}", applicability = "maybe-incorrect", style = "verbose" )] Span, ), - #[diag(parse_no_brace_unicode_escape)] + #[diag("incorrect unicode escape sequence")] NoBraceInUnicodeEscape { #[primary_span] span: Span, - #[label] + #[label("incorrect unicode escape sequence")] label: Option, #[subdiagnostic] sub: NoBraceUnicodeSub, }, - #[diag(parse_unicode_escape_in_byte)] - #[help] + #[diag("unicode escape in byte string")] + #[help("unicode escape sequences cannot be used as a byte or in a byte string")] UnicodeEscapeInByte( #[primary_span] - #[label] + #[label("unicode escape in byte string")] Span, ), - #[diag(parse_empty_unicode_escape)] + #[diag("empty unicode escape")] EmptyUnicodeEscape( #[primary_span] - #[label] + #[label("this escape must have at least 1 hex digit")] Span, ), - #[diag(parse_zero_chars)] + #[diag("empty character literal")] ZeroChars( #[primary_span] - #[label] + #[label("empty character literal")] Span, ), - #[diag(parse_lone_slash)] + #[diag("invalid trailing slash in literal")] LoneSlash( #[primary_span] - #[label] + #[label("invalid trailing slash in literal")] Span, ), - #[diag(parse_unskipped_whitespace)] + #[diag("whitespace symbol '{$ch}' is not skipped")] UnskippedWhitespace { #[primary_span] span: Span, - #[label] + #[label("whitespace symbol '{$ch}' is not skipped")] char_span: Span, ch: String, }, - #[diag(parse_multiple_skipped_lines)] + #[diag("multiple lines skipped by escaped newline")] MultipleSkippedLinesWarning( #[primary_span] - #[label] + #[label("skipping everything up to and including this point")] Span, ), - #[diag(parse_more_than_one_char)] + #[diag("character literal may only contain one codepoint")] MoreThanOneChar { #[primary_span] span: Span, @@ -2557,7 +2975,7 @@ pub(crate) enum UnescapeError { #[subdiagnostic] suggestion: MoreThanOneCharSugg, }, - #[diag(parse_nul_in_c_str)] + #[diag("null characters in C string literals are not supported")] NulInCStr { #[primary_span] span: Span, @@ -2567,7 +2985,7 @@ pub(crate) enum UnescapeError { #[derive(Subdiagnostic)] pub(crate) enum MoreThanOneCharSugg { #[suggestion( - parse_consider_normalized, + "consider using the normalized form `{$ch}` of this character", code = "{normalized}", applicability = "machine-applicable", style = "verbose" @@ -2579,7 +2997,7 @@ pub(crate) enum MoreThanOneCharSugg { normalized: String, }, #[suggestion( - parse_remove_non, + "consider removing the non-printing characters", code = "{ch}", applicability = "maybe-incorrect", style = "verbose" @@ -2590,7 +3008,10 @@ pub(crate) enum MoreThanOneCharSugg { ch: String, }, #[suggestion( - parse_use_double_quotes, + "if you meant to write a {$is_byte -> + [true] byte string + *[false] string + } literal, use double quotes", code = "{sugg}", applicability = "machine-applicable", style = "verbose" @@ -2601,7 +3022,13 @@ pub(crate) enum MoreThanOneCharSugg { is_byte: bool, sugg: String, }, - #[multipart_suggestion(parse_use_double_quotes, applicability = "machine-applicable")] + #[multipart_suggestion( + "if you meant to write a {$is_byte -> + [true] byte string + *[false] string + } literal, use double quotes", + applicability = "machine-applicable" + )] Quotes { #[suggestion_part(code = "{prefix}\"")] start: Span, @@ -2614,7 +3041,12 @@ pub(crate) enum MoreThanOneCharSugg { #[derive(Subdiagnostic)] pub(crate) enum MoreThanOneCharNote { - #[note(parse_followed_by)] + #[note( + "this `{$chr}` is followed by the combining {$len -> + [one] mark + *[other] marks + } `{$escaped_marks}`" + )] AllCombining { #[primary_span] span: Span, @@ -2622,7 +3054,7 @@ pub(crate) enum MoreThanOneCharNote { len: usize, escaped_marks: String, }, - #[note(parse_non_printing)] + #[note("there are non-printing characters, the full sequence is `{$escaped}`")] NonPrinting { #[primary_span] span: Span, @@ -2633,7 +3065,7 @@ pub(crate) enum MoreThanOneCharNote { #[derive(Subdiagnostic)] pub(crate) enum NoBraceUnicodeSub { #[suggestion( - parse_use_braces, + "format of unicode escape sequences uses braces", code = "{suggestion}", applicability = "maybe-incorrect", style = "verbose" @@ -2643,12 +3075,12 @@ pub(crate) enum NoBraceUnicodeSub { span: Span, suggestion: String, }, - #[help(parse_format_of_unicode)] + #[help(r#"format of unicode escape sequences is `\u{"{...}"}`"#)] Help, } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_sugg_wrap_pattern_in_parens, applicability = "machine-applicable")] +#[multipart_suggestion("wrap the pattern in parentheses", applicability = "machine-applicable")] pub(crate) struct WrapInParens { #[suggestion_part(code = "(")] pub(crate) lo: Span, @@ -2659,7 +3091,7 @@ pub(crate) struct WrapInParens { #[derive(Subdiagnostic)] pub(crate) enum TopLevelOrPatternNotAllowedSugg { #[suggestion( - parse_sugg_remove_leading_vert_in_pattern, + "remove the `|`", code = "", applicability = "machine-applicable", style = "tool-only" @@ -2677,27 +3109,37 @@ pub(crate) enum TopLevelOrPatternNotAllowedSugg { } #[derive(Diagnostic)] -#[diag(parse_unexpected_vert_vert_before_function_parameter)] -#[note(parse_note_pattern_alternatives_use_single_vert)] +#[diag("unexpected `||` before function parameter")] +#[note("alternatives in or-patterns are separated with `|`, not `||`")] pub(crate) struct UnexpectedVertVertBeforeFunctionParam { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove the `||`", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_unexpected_vert_vert_in_pattern)] +#[diag("unexpected token `||` in pattern")] pub(crate) struct UnexpectedVertVertInPattern { #[primary_span] - #[suggestion(code = "|", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "use a single `|` to separate multiple alternative patterns", + code = "|", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, - #[label(parse_label_while_parsing_or_pattern_here)] + #[label("while parsing this or-pattern starting here")] pub start: Option, } #[derive(Subdiagnostic)] #[suggestion( - parse_trailing_vert_not_allowed, + "a trailing `{$token}` is not allowed in an or-pattern", code = "", applicability = "machine-applicable", style = "tool-only" @@ -2708,59 +3150,71 @@ pub(crate) struct TrailingVertSuggestion { } #[derive(Diagnostic)] -#[diag(parse_trailing_vert_not_allowed)] +#[diag("a trailing `{$token}` is not allowed in an or-pattern")] pub(crate) struct TrailingVertNotAllowed { #[primary_span] pub span: Span, #[subdiagnostic] pub suggestion: TrailingVertSuggestion, - #[label(parse_label_while_parsing_or_pattern_here)] + #[label("while parsing this or-pattern starting here")] pub start: Option, pub token: Token, - #[note(parse_note_pattern_alternatives_use_single_vert)] + #[note("alternatives in or-patterns are separated with `|`, not `||`")] pub note_double_vert: bool, } #[derive(Diagnostic)] -#[diag(parse_dotdotdot_rest_pattern)] +#[diag("unexpected `...`")] pub(crate) struct DotDotDotRestPattern { #[primary_span] - #[label] + #[label("not a valid pattern")] pub span: Span, - #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")] + #[suggestion( + "for a rest pattern, use `..` instead of `...`", + style = "verbose", + code = "", + applicability = "machine-applicable" + )] pub suggestion: Option, - #[note] + #[note( + "only `extern \"C\"` and `extern \"C-unwind\"` functions may have a C variable argument list" + )] pub var_args: Option<()>, } #[derive(Diagnostic)] -#[diag(parse_pattern_on_wrong_side_of_at)] +#[diag("pattern on wrong side of `@`")] pub(crate) struct PatternOnWrongSideOfAt { #[primary_span] - #[suggestion(code = "{whole_pat}", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "switch the order", + code = "{whole_pat}", + applicability = "machine-applicable", + style = "verbose" + )] pub whole_span: Span, pub whole_pat: String, - #[label(parse_label_pattern)] + #[label("pattern on the left, should be on the right")] pub pattern: Span, - #[label(parse_label_binding)] + #[label("binding on the right, should be on the left")] pub binding: Span, } #[derive(Diagnostic)] -#[diag(parse_expected_binding_left_of_at)] -#[note] +#[diag("left-hand side of `@` must be a binding")] +#[note("bindings are `x`, `mut x`, `ref x`, and `ref mut x`")] pub(crate) struct ExpectedBindingLeftOfAt { #[primary_span] pub whole_span: Span, - #[label(parse_label_lhs)] + #[label("interpreted as a pattern, not a binding")] pub lhs: Span, - #[label(parse_label_rhs)] + #[label("also a pattern")] pub rhs: Span, } #[derive(Subdiagnostic)] #[multipart_suggestion( - parse_ambiguous_range_pattern_suggestion, + "add parentheses to clarify the precedence", applicability = "machine-applicable" )] pub(crate) struct ParenRangeSuggestion { @@ -2771,7 +3225,7 @@ pub(crate) struct ParenRangeSuggestion { } #[derive(Diagnostic)] -#[diag(parse_ambiguous_range_pattern)] +#[diag("the range pattern here has ambiguous interpretation")] pub(crate) struct AmbiguousRangePattern { #[primary_span] pub span: Span, @@ -2780,100 +3234,144 @@ pub(crate) struct AmbiguousRangePattern { } #[derive(Diagnostic)] -#[diag(parse_unexpected_lifetime_in_pattern)] +#[diag("unexpected lifetime `{$symbol}` in pattern")] pub(crate) struct UnexpectedLifetimeInPattern { #[primary_span] pub span: Span, pub symbol: Symbol, - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove the lifetime", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] pub suggestion: Span, } #[derive(Diagnostic)] pub(crate) enum InvalidMutInPattern { - #[diag(parse_mut_on_nested_ident_pattern)] - #[note(parse_note_mut_pattern_usage)] + #[diag("`mut` must be attached to each individual binding")] + #[note("`mut` may be followed by `variable` and `variable @ pattern`")] NestedIdent { #[primary_span] - #[suggestion(code = "{pat}", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "add `mut` to each binding", + code = "{pat}", + applicability = "machine-applicable", + style = "verbose" + )] span: Span, pat: String, }, - #[diag(parse_mut_on_non_ident_pattern)] - #[note(parse_note_mut_pattern_usage)] + #[diag("`mut` must be followed by a named binding")] + #[note("`mut` may be followed by `variable` and `variable @ pattern`")] NonIdent { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove the `mut` prefix", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] span: Span, }, } #[derive(Diagnostic)] -#[diag(parse_repeated_mut_in_pattern)] +#[diag("`mut` on a binding may not be repeated")] pub(crate) struct RepeatedMutInPattern { #[primary_span] pub span: Span, - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove the additional `mut`s", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_dot_dot_dot_range_to_pattern_not_allowed)] +#[diag("range-to patterns with `...` are not allowed")] pub(crate) struct DotDotDotRangeToPatternNotAllowed { #[primary_span] - #[suggestion(style = "verbose", code = "..=", applicability = "machine-applicable")] + #[suggestion( + "use `..=` instead", + style = "verbose", + code = "..=", + applicability = "machine-applicable" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_enum_pattern_instead_of_identifier)] +#[diag("expected identifier, found enum pattern")] pub(crate) struct EnumPatternInsteadOfIdentifier { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_at_dot_dot_in_struct_pattern)] +#[diag("`@ ..` is not supported in struct patterns")] pub(crate) struct AtDotDotInStructPattern { #[primary_span] pub span: Span, - #[suggestion(code = "", style = "verbose", applicability = "machine-applicable")] + #[suggestion( + "bind to each field separately or, if you don't need them, just remove `{$ident} @`", + code = "", + style = "verbose", + applicability = "machine-applicable" + )] pub remove: Span, pub ident: Ident, } #[derive(Diagnostic)] -#[diag(parse_at_in_struct_pattern)] -#[note] -#[help] +#[diag("unexpected `@` in struct pattern")] +#[note("struct patterns use `field: pattern` syntax to bind to fields")] +#[help( + "consider replacing `new_name @ field_name` with `field_name: new_name` if that is what you intended" +)] pub(crate) struct AtInStructPattern { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_dot_dot_dot_for_remaining_fields)] +#[diag("expected field pattern, found `{$token_str}`")] pub(crate) struct DotDotDotForRemainingFields { #[primary_span] - #[suggestion(code = "..", style = "verbose", applicability = "machine-applicable")] + #[suggestion( + "to omit remaining fields, use `..`", + code = "..", + style = "verbose", + applicability = "machine-applicable" + )] pub span: Span, pub token_str: Cow<'static, str>, } #[derive(Diagnostic)] -#[diag(parse_expected_comma_after_pattern_field)] +#[diag("expected `,`")] pub(crate) struct ExpectedCommaAfterPatternField { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_unexpected_expr_in_pat)] -#[note] +#[diag( + "expected {$is_bound -> + [true] a pattern range bound + *[false] a pattern + }, found an expression" +)] +#[note( + "arbitrary expressions are not allowed in patterns: " +)] pub(crate) struct UnexpectedExpressionInPattern { /// The unexpected expr's span. #[primary_span] - #[label] + #[label("not a pattern")] pub span: Span, /// Was a `RangePatternBound` expected? pub is_bound: bool, @@ -2884,7 +3382,7 @@ pub(crate) struct UnexpectedExpressionInPattern { #[derive(Subdiagnostic)] pub(crate) enum UnexpectedExpressionInPatternSugg { #[multipart_suggestion( - parse_unexpected_expr_in_pat_create_guard_sugg, + "consider moving the expression to a match arm guard", applicability = "maybe-incorrect" )] CreateGuard { @@ -2901,7 +3399,7 @@ pub(crate) enum UnexpectedExpressionInPatternSugg { }, #[multipart_suggestion( - parse_unexpected_expr_in_pat_update_guard_sugg, + "consider moving the expression to the match arm guard", applicability = "maybe-incorrect" )] UpdateGuard { @@ -2923,7 +3421,7 @@ pub(crate) enum UnexpectedExpressionInPatternSugg { }, #[multipart_suggestion( - parse_unexpected_expr_in_pat_const_sugg, + "consider extracting the expression into a `const`", applicability = "has-placeholders" )] Const { @@ -2943,7 +3441,7 @@ pub(crate) enum UnexpectedExpressionInPatternSugg { } #[derive(Diagnostic)] -#[diag(parse_unexpected_paren_in_range_pat)] +#[diag("range pattern bounds cannot have parentheses")] pub(crate) struct UnexpectedParenInRangePat { #[primary_span] pub span: Vec, @@ -2952,10 +3450,7 @@ pub(crate) struct UnexpectedParenInRangePat { } #[derive(Subdiagnostic)] -#[multipart_suggestion( - parse_unexpected_paren_in_range_pat_sugg, - applicability = "machine-applicable" -)] +#[multipart_suggestion("remove these parentheses", applicability = "machine-applicable")] pub(crate) struct UnexpectedParenInRangePatSugg { #[suggestion_part(code = "")] pub start_span: Span, @@ -2964,104 +3459,145 @@ pub(crate) struct UnexpectedParenInRangePatSugg { } #[derive(Diagnostic)] -#[diag(parse_return_types_use_thin_arrow)] +#[diag("return types are denoted using `->`")] pub(crate) struct ReturnTypesUseThinArrow { #[primary_span] pub span: Span, - #[suggestion(style = "verbose", code = " -> ", applicability = "machine-applicable")] + #[suggestion( + "use `->` instead", + style = "verbose", + code = " -> ", + applicability = "machine-applicable" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_need_plus_after_trait_object_lifetime)] +#[diag("lifetimes must be followed by `+` to form a trait object type")] pub(crate) struct NeedPlusAfterTraitObjectLifetime { #[primary_span] pub span: Span, - #[suggestion(code = " + /* Trait */", applicability = "has-placeholders")] + #[suggestion( + "consider adding a trait bound after the potential lifetime bound", + code = " + /* Trait */", + applicability = "has-placeholders" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_expected_mut_or_const_in_raw_pointer_type)] +#[diag("expected `mut` or `const` keyword in raw pointer type")] pub(crate) struct ExpectedMutOrConstInRawPointerType { #[primary_span] pub span: Span, - #[suggestion(code("mut ", "const "), applicability = "has-placeholders", style = "verbose")] + #[suggestion( + "add `mut` or `const` here", + code("mut ", "const "), + applicability = "has-placeholders", + style = "verbose" + )] pub after_asterisk: Span, } #[derive(Diagnostic)] -#[diag(parse_lifetime_after_mut)] +#[diag("lifetime must precede `mut`")] pub(crate) struct LifetimeAfterMut { #[primary_span] pub span: Span, - #[suggestion(code = "&{snippet} mut", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "place the lifetime before `mut`", + code = "&{snippet} mut", + applicability = "maybe-incorrect", + style = "verbose" + )] pub suggest_lifetime: Option, pub snippet: String, } #[derive(Diagnostic)] -#[diag(parse_dyn_after_mut)] +#[diag("`mut` must precede `dyn`")] pub(crate) struct DynAfterMut { #[primary_span] - #[suggestion(code = "&mut dyn", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "place `mut` before `dyn`", + code = "&mut dyn", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_fn_pointer_cannot_be_const)] -#[note] +#[diag("an `fn` pointer type cannot be `const`")] +#[note("allowed qualifiers are: `unsafe` and `extern`")] pub(crate) struct FnPointerCannotBeConst { #[primary_span] - #[label] + #[label("`const` because of this")] pub span: Span, - #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "remove the `const` qualifier", + code = "", + applicability = "maybe-incorrect", + style = "verbose" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_fn_pointer_cannot_be_async)] -#[note] +#[diag("an `fn` pointer type cannot be `async`")] +#[note("allowed qualifiers are: `unsafe` and `extern`")] pub(crate) struct FnPointerCannotBeAsync { #[primary_span] - #[label] + #[label("`async` because of this")] pub span: Span, - #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "remove the `async` qualifier", + code = "", + applicability = "maybe-incorrect", + style = "verbose" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_nested_c_variadic_type, code = E0743)] +#[diag("C-variadic type `...` may not be nested inside another type", code = E0743)] pub(crate) struct NestedCVariadicType { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_dotdotdot_rest_type)] -#[note] +#[diag("unexpected `...`")] +#[note( + "only `extern \"C\"` and `extern \"C-unwind\"` functions may have a C variable argument list" +)] pub(crate) struct InvalidCVariadicType { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_invalid_dyn_keyword)] -#[help] +#[diag("invalid `dyn` keyword")] +#[help("`dyn` is only needed at the start of a trait `+`-separated list")] pub(crate) struct InvalidDynKeyword { #[primary_span] pub span: Span, - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove this keyword", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] pub suggestion: Span, } #[derive(Subdiagnostic)] pub(crate) enum HelpUseLatestEdition { - #[help(parse_help_set_edition_cargo)] - #[note(parse_note_edition_guide)] + #[help("set `edition = \"{$edition}\"` in `Cargo.toml`")] + #[note("for more on editions, read https://doc.rust-lang.org/edition-guide")] Cargo { edition: Edition }, - #[help(parse_help_set_edition_standalone)] - #[note(parse_note_edition_guide)] + #[help("pass `--edition {$edition}` to `rustc`")] + #[note("for more on editions, read https://doc.rust-lang.org/edition-guide")] Standalone { edition: Edition }, } @@ -3077,7 +3613,7 @@ impl HelpUseLatestEdition { } #[derive(Diagnostic)] -#[diag(parse_box_syntax_removed)] +#[diag("`box_syntax` has been removed")] pub(crate) struct BoxSyntaxRemoved { #[primary_span] pub span: Span, @@ -3087,7 +3623,7 @@ pub(crate) struct BoxSyntaxRemoved { #[derive(Subdiagnostic)] #[multipart_suggestion( - parse_box_syntax_removed_suggestion, + "use `Box::new()` instead", applicability = "machine-applicable", style = "verbose" )] @@ -3099,65 +3635,70 @@ pub(crate) struct AddBoxNew { } #[derive(Diagnostic)] -#[diag(parse_bad_return_type_notation_output)] +#[diag("return type not allowed with return type notation")] pub(crate) struct BadReturnTypeNotationOutput { #[primary_span] pub span: Span, - #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "remove the return type", + code = "", + applicability = "maybe-incorrect", + style = "verbose" + )] pub suggestion: Span, } #[derive(Diagnostic)] -#[diag(parse_bad_assoc_type_bounds)] +#[diag("bounds on associated types do not belong here")] pub(crate) struct BadAssocTypeBounds { #[primary_span] - #[label] + #[label("belongs in `where` clause")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_attr_after_generic)] +#[diag("trailing attribute after generic parameter")] pub(crate) struct AttrAfterGeneric { #[primary_span] - #[label] + #[label("attributes must go before parameters")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_attr_without_generics)] +#[diag("attribute without generic parameters")] pub(crate) struct AttrWithoutGenerics { #[primary_span] - #[label] + #[label("attributes are only permitted when preceding parameters")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_where_generics)] +#[diag("generic parameters on `where` clauses are reserved for future use")] pub(crate) struct WhereOnGenerics { #[primary_span] - #[label] + #[label("currently unsupported")] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_generics_in_path)] +#[diag("unexpected generic arguments in path")] pub(crate) struct GenericsInPath { #[primary_span] pub span: Vec, } #[derive(Diagnostic)] -#[diag(parse_lifetime_in_eq_constraint)] -#[help] +#[diag("lifetimes are not permitted in this context")] +#[help("if you meant to specify a trait object, write `dyn /* Trait */ + {$lifetime}`")] pub(crate) struct LifetimeInEqConstraint { #[primary_span] - #[label] + #[label("lifetime is not allowed here")] pub span: Span, pub lifetime: Ident, - #[label(parse_context_label)] + #[label("this introduces an associated item binding")] pub binding_label: Span, #[suggestion( - parse_colon_sugg, + "you might have meant to write a bound here", style = "verbose", applicability = "maybe-incorrect", code = ": " @@ -3166,119 +3707,159 @@ pub(crate) struct LifetimeInEqConstraint { } #[derive(Diagnostic)] -#[diag(parse_modifier_lifetime)] +#[diag("`{$modifier}` may only modify trait bounds, not lifetime bounds")] pub(crate) struct ModifierLifetime { #[primary_span] - #[suggestion(style = "tool-only", applicability = "maybe-incorrect", code = "")] + #[suggestion( + "remove the `{$modifier}`", + style = "tool-only", + applicability = "maybe-incorrect", + code = "" + )] pub span: Span, pub modifier: &'static str, } #[derive(Diagnostic)] -#[diag(parse_underscore_literal_suffix)] +#[diag("underscore literal suffix is not allowed")] pub(crate) struct UnderscoreLiteralSuffix { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_expect_label_found_ident)] +#[diag("expected a label, found an identifier")] pub(crate) struct ExpectedLabelFoundIdent { #[primary_span] pub span: Span, - #[suggestion(code = "'", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "labels start with a tick", + code = "'", + applicability = "machine-applicable", + style = "verbose" + )] pub start: Span, } #[derive(Diagnostic)] -#[diag(parse_inappropriate_default)] -#[note] +#[diag("{$article} {$descr} cannot be `default`")] +#[note("only associated `fn`, `const`, and `type` items can be `default`")] pub(crate) struct InappropriateDefault { #[primary_span] - #[label] + #[label("`default` because of this")] pub span: Span, pub article: &'static str, pub descr: &'static str, } #[derive(Diagnostic)] -#[diag(parse_recover_import_as_use)] +#[diag("expected item, found {$token_name}")] pub(crate) struct RecoverImportAsUse { #[primary_span] - #[suggestion(code = "use", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "items are imported using the `use` keyword", + code = "use", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, pub token_name: String, } #[derive(Diagnostic)] -#[diag(parse_single_colon_import_path)] -#[note] +#[diag("expected `::`, found `:`")] +#[note("import paths are delimited using `::`")] pub(crate) struct SingleColonImportPath { #[primary_span] - #[suggestion(code = "::", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "use double colon", + code = "::", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_bad_item_kind)] +#[diag("{$descr} is not supported in {$ctx}")] pub(crate) struct BadItemKind { #[primary_span] pub span: Span, pub descr: &'static str, pub ctx: &'static str, - #[help] + #[help("consider moving the {$descr} out to a nearby module scope")] pub help: bool, } #[derive(Diagnostic)] -#[diag(parse_macro_rules_missing_bang)] +#[diag("expected `!` after `macro_rules`")] pub(crate) struct MacroRulesMissingBang { #[primary_span] pub span: Span, - #[suggestion(code = "!", applicability = "machine-applicable", style = "verbose")] + #[suggestion("add a `!`", code = "!", applicability = "machine-applicable", style = "verbose")] pub hi: Span, } #[derive(Diagnostic)] -#[diag(parse_macro_name_remove_bang)] +#[diag("macro names aren't followed by a `!`")] pub(crate) struct MacroNameRemoveBang { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "short")] + #[suggestion( + "remove the `!`", + code = "", + applicability = "machine-applicable", + style = "short" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_macro_rules_visibility)] +#[diag("can't qualify macro_rules invocation with `{$vis}`")] pub(crate) struct MacroRulesVisibility<'a> { #[primary_span] - #[suggestion(code = "#[macro_export]", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "try exporting the macro", + code = "#[macro_export]", + applicability = "maybe-incorrect", + style = "verbose" + )] pub span: Span, pub vis: &'a str, } #[derive(Diagnostic)] -#[diag(parse_macro_invocation_visibility)] -#[help] +#[diag("can't qualify macro invocation with `pub`")] +#[help("try adjusting the macro to put `{$vis}` inside the invocation")] pub(crate) struct MacroInvocationVisibility<'a> { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove the visibility", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, pub vis: &'a str, } #[derive(Diagnostic)] -#[diag(parse_nested_adt)] +#[diag("`{$kw_str}` definition cannot be nested inside `{$keyword}`")] pub(crate) struct NestedAdt<'a> { #[primary_span] pub span: Span, - #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "consider creating a new `{$kw_str}` definition instead of nesting", + code = "", + applicability = "maybe-incorrect", + style = "verbose" + )] pub item: Span, pub keyword: &'a str, pub kw_str: Cow<'a, str>, } #[derive(Diagnostic)] -#[diag(parse_function_body_equals_expr)] +#[diag("function body cannot be `= expression;`")] pub(crate) struct FunctionBodyEqualsExpr { #[primary_span] pub span: Span, @@ -3287,7 +3868,10 @@ pub(crate) struct FunctionBodyEqualsExpr { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + r#"surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;`"#, + applicability = "machine-applicable" +)] pub(crate) struct FunctionBodyEqualsExprSugg { #[suggestion_part(code = "{{")] pub eq: Span, @@ -3296,38 +3880,56 @@ pub(crate) struct FunctionBodyEqualsExprSugg { } #[derive(Diagnostic)] -#[diag(parse_box_not_pat)] +#[diag("expected pattern, found {$descr}")] pub(crate) struct BoxNotPat { #[primary_span] pub span: Span, - #[note] + #[note("`box` is a reserved keyword")] pub kw: Span, - #[suggestion(code = "r#", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + "escape `box` to use it as an identifier", + code = "r#", + applicability = "maybe-incorrect", + style = "verbose" + )] pub lo: Span, pub descr: String, } #[derive(Diagnostic)] -#[diag(parse_unmatched_angle)] +#[diag( + "unmatched angle {$plural -> + [true] brackets + *[false] bracket + }" +)] pub(crate) struct UnmatchedAngle { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] + #[suggestion( + "remove extra angle {$plural -> + [true] brackets + *[false] bracket + }", + code = "", + applicability = "machine-applicable", + style = "verbose" + )] pub span: Span, pub plural: bool, } #[derive(Diagnostic)] -#[diag(parse_missing_plus_in_bounds)] +#[diag("expected `+` between lifetime and {$sym}")] pub(crate) struct MissingPlusBounds { #[primary_span] pub span: Span, - #[suggestion(code = " +", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion("add `+`", code = " +", applicability = "maybe-incorrect", style = "verbose")] pub hi: Span, pub sym: Symbol, } #[derive(Diagnostic)] -#[diag(parse_incorrect_parens_trait_bounds)] +#[diag("incorrect parentheses around trait bounds")] pub(crate) struct IncorrectParensTraitBounds { #[primary_span] pub span: Vec, @@ -3336,10 +3938,7 @@ pub(crate) struct IncorrectParensTraitBounds { } #[derive(Subdiagnostic)] -#[multipart_suggestion( - parse_incorrect_parens_trait_bounds_sugg, - applicability = "machine-applicable" -)] +#[multipart_suggestion("fix the parentheses", applicability = "machine-applicable")] pub(crate) struct IncorrectParensTraitBoundsSugg { #[suggestion_part(code = " ")] pub wrong_span: Span, @@ -3348,10 +3947,15 @@ pub(crate) struct IncorrectParensTraitBoundsSugg { } #[derive(Diagnostic)] -#[diag(parse_kw_bad_case)] +#[diag("keyword `{$kw}` is written in the wrong case")] pub(crate) struct KwBadCase<'a> { #[primary_span] - #[suggestion(code = "{kw}", style = "verbose", applicability = "machine-applicable")] + #[suggestion( + "write it in {$case}", + code = "{kw}", + style = "verbose", + applicability = "machine-applicable" + )] pub span: Span, pub kw: &'a str, pub case: Case, @@ -3375,7 +3979,7 @@ impl IntoDiagArg for Case { } #[derive(Diagnostic)] -#[diag(parse_unknown_builtin_construct)] +#[diag("unknown `builtin #` construct `{$name}`")] pub(crate) struct UnknownBuiltinConstruct { #[primary_span] pub span: Span, @@ -3383,35 +3987,38 @@ pub(crate) struct UnknownBuiltinConstruct { } #[derive(Diagnostic)] -#[diag(parse_expected_builtin_ident)] +#[diag("expected identifier after `builtin #`")] pub(crate) struct ExpectedBuiltinIdent { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_static_with_generics)] +#[diag("static items may not have generic parameters")] pub(crate) struct StaticWithGenerics { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_where_clause_before_const_body)] +#[diag("where clauses are not allowed before const item bodies")] pub(crate) struct WhereClauseBeforeConstBody { #[primary_span] - #[label] + #[label("unexpected where clause")] pub span: Span, - #[label(parse_name_label)] + #[label("while parsing this const item")] pub name: Span, - #[label(parse_body_label)] + #[label("the item body")] pub body: Span, #[subdiagnostic] pub sugg: Option, } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "move the body before the where clause", + applicability = "machine-applicable" +)] pub(crate) struct WhereClauseBeforeConstBodySugg { #[suggestion_part(code = "= {snippet} ")] pub left: Span, @@ -3421,12 +4028,12 @@ pub(crate) struct WhereClauseBeforeConstBodySugg { } #[derive(Diagnostic)] -#[diag(parse_generic_args_in_pat_require_turbofish_syntax)] +#[diag("generic args in patterns require the turbofish syntax")] pub(crate) struct GenericArgsInPatRequireTurbofishSyntax { #[primary_span] pub span: Span, #[suggestion( - parse_sugg_turbofish_syntax, + "use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments", style = "verbose", code = "::", applicability = "maybe-incorrect" @@ -3435,7 +4042,7 @@ pub(crate) struct GenericArgsInPatRequireTurbofishSyntax { } #[derive(Diagnostic)] -#[diag(parse_transpose_dyn_or_impl)] +#[diag("`for<...>` expected after `{$kw}`, not before")] pub(crate) struct TransposeDynOrImpl<'a> { #[primary_span] pub span: Span, @@ -3445,7 +4052,7 @@ pub(crate) struct TransposeDynOrImpl<'a> { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion("move `{$kw}` before the `for<...>`", applicability = "machine-applicable")] pub(crate) struct TransposeDynOrImplSugg<'a> { #[suggestion_part(code = "")] pub removal_span: Span, @@ -3455,68 +4062,77 @@ pub(crate) struct TransposeDynOrImplSugg<'a> { } #[derive(Diagnostic)] -#[diag(parse_array_index_offset_of)] +#[diag("array indexing not supported in offset_of")] pub(crate) struct ArrayIndexInOffsetOf(#[primary_span] pub Span); #[derive(Diagnostic)] -#[diag(parse_invalid_offset_of)] +#[diag("offset_of expects dot-separated field and variant names")] pub(crate) struct InvalidOffsetOf(#[primary_span] pub Span); #[derive(Diagnostic)] -#[diag(parse_async_impl)] +#[diag("`async` trait implementations are unsupported")] pub(crate) struct AsyncImpl { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_expr_rarrow_call)] -#[help] +#[diag("`->` is not valid syntax for field accesses and method calls")] +#[help( + "the `.` operator will automatically dereference the value, except if the value is a raw pointer" +)] pub(crate) struct ExprRArrowCall { #[primary_span] - #[suggestion(style = "verbose", applicability = "machine-applicable", code = ".")] + #[suggestion( + "try using `.` instead", + style = "verbose", + applicability = "machine-applicable", + code = "." + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_dot_dot_range_attribute)] +#[diag("attributes are not allowed on range expressions starting with `..`")] pub(crate) struct DotDotRangeAttribute { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_binder_before_modifiers)] +#[diag("`for<...>` binder should be placed before trait bound modifiers")] pub(crate) struct BinderBeforeModifiers { #[primary_span] pub binder_span: Span, - #[label] + #[label("place the `for<...>` binder before any modifiers")] pub modifiers_span: Span, } #[derive(Diagnostic)] -#[diag(parse_binder_and_polarity)] +#[diag("`for<...>` binder not allowed with `{$polarity}` trait polarity modifier")] pub(crate) struct BinderAndPolarity { #[primary_span] pub polarity_span: Span, - #[label] + #[label("there is not a well-defined meaning for a higher-ranked `{$polarity}` trait")] pub binder_span: Span, pub polarity: &'static str, } #[derive(Diagnostic)] -#[diag(parse_modifiers_and_polarity)] +#[diag("`{$modifiers_concatenated}` trait not allowed with `{$polarity}` trait polarity modifier")] pub(crate) struct PolarityAndModifiers { #[primary_span] pub polarity_span: Span, - #[label] + #[label( + "there is not a well-defined meaning for a `{$modifiers_concatenated} {$polarity}` trait" + )] pub modifiers_span: Span, pub polarity: &'static str, pub modifiers_concatenated: String, } #[derive(Diagnostic)] -#[diag(parse_incorrect_type_on_self)] +#[diag("type not allowed for shorthand `self` parameter")] pub(crate) struct IncorrectTypeOnSelf { #[primary_span] pub span: Span, @@ -3525,7 +4141,10 @@ pub(crate) struct IncorrectTypeOnSelf { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "move the modifiers on `self` to the type", + applicability = "machine-applicable" +)] pub(crate) struct MoveSelfModifier { #[suggestion_part(code = "")] pub removal_span: Span, @@ -3535,82 +4154,104 @@ pub(crate) struct MoveSelfModifier { } #[derive(Diagnostic)] -#[diag(parse_asm_unsupported_operand)] +#[diag("the `{$symbol}` operand cannot be used with `{$macro_name}!`")] pub(crate) struct AsmUnsupportedOperand<'a> { #[primary_span] - #[label] + #[label( + "the `{$symbol}` operand is not meaningful for global-scoped inline assembly, remove it" + )] pub(crate) span: Span, pub(crate) symbol: &'a str, pub(crate) macro_name: &'static str, } #[derive(Diagnostic)] -#[diag(parse_asm_underscore_input)] +#[diag("_ cannot be used for input operands")] pub(crate) struct AsmUnderscoreInput { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(parse_asm_sym_no_path)] +#[diag("expected a path for argument to `sym`")] pub(crate) struct AsmSymNoPath { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(parse_asm_requires_template)] +#[diag("requires at least a template string argument")] pub(crate) struct AsmRequiresTemplate { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(parse_asm_expected_comma)] +#[diag("expected token: `,`")] pub(crate) struct AsmExpectedComma { #[primary_span] - #[label] + #[label("expected `,`")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(parse_asm_expected_other)] +#[diag( + "expected operand, {$is_inline_asm -> + [false] options + *[true] clobber_abi, options + }, or additional template string" +)] pub(crate) struct AsmExpectedOther { #[primary_span] - #[label(parse_asm_expected_other)] + #[label( + "expected operand, {$is_inline_asm -> + [false] options + *[true] clobber_abi, options + }, or additional template string" + )] pub(crate) span: Span, pub(crate) is_inline_asm: bool, } #[derive(Diagnostic)] -#[diag(parse_asm_non_abi)] +#[diag("at least one abi must be provided as an argument to `clobber_abi`")] pub(crate) struct NonABI { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(parse_asm_expected_string_literal)] +#[diag("expected string literal")] pub(crate) struct AsmExpectedStringLiteral { #[primary_span] - #[label] + #[label("not a string literal")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(parse_asm_expected_register_class_or_explicit_register)] +#[diag("expected register class or explicit register")] pub(crate) struct ExpectedRegisterClassOrExplicitRegister { #[primary_span] pub(crate) span: Span, } #[derive(LintDiagnostic)] -#[diag(parse_hidden_unicode_codepoints)] -#[note] +#[diag("unicode codepoint changing visible direction of text present in {$label}")] +#[note( + "these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen" +)] pub(crate) struct HiddenUnicodeCodepointsDiag { pub label: String, pub count: usize, - #[label] + #[label( + "this {$label} contains {$count -> + [one] an invisible + *[other] invisible + } unicode text flow control {$count -> + [one] codepoint + *[other] codepoints + }" + )] pub span_label: Span, #[subdiagnostic] pub labels: Option, @@ -3641,13 +4282,13 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub { match self { HiddenUnicodeCodepointsDiagSub::Escape { spans } => { diag.multipart_suggestion_with_style( - fluent::parse_suggestion_remove, + inline_fluent!("if their presence wasn't intentional, you can remove them"), spans.iter().map(|(_, span)| (*span, "".to_string())).collect(), Applicability::MachineApplicable, SuggestionStyle::HideCodeAlways, ); diag.multipart_suggestion( - fluent::parse_suggestion_escape, + inline_fluent!("if you want to keep them but make them visible in your source code, you can escape them"), spans .into_iter() .map(|(c, span)| { @@ -3670,43 +4311,59 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub { .collect::>() .join(", "), ); - diag.note(fluent::parse_suggestion_remove); - diag.note(fluent::parse_no_suggestion_note_escape); + diag.note(inline_fluent!( + "if their presence wasn't intentional, you can remove them" + )); + diag.note(inline_fluent!("if you want to keep them but make them visible in your source code, you can escape them: {$escaped}")); } } } } #[derive(LintDiagnostic)] -#[diag(parse_varargs_without_pattern)] +#[diag("missing pattern for `...` argument")] pub(crate) struct VarargsWithoutPattern { - #[suggestion(code = "_: ...", applicability = "machine-applicable")] + #[suggestion( + "name the argument, or use `_` to continue ignoring it", + code = "_: ...", + applicability = "machine-applicable" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_delegation_non_trait_impl_reuse)] +#[diag("only trait impls can be reused")] pub(crate) struct ImplReuseInherentImpl { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_struct_literal_placeholder_path)] +#[diag("placeholder `_` is not allowed for the path in struct literals")] pub(crate) struct StructLiteralPlaceholderPath { #[primary_span] - #[label] - #[suggestion(applicability = "has-placeholders", code = "/* Type */", style = "verbose")] + #[label("not allowed in struct literals")] + #[suggestion( + "replace it with the correct type", + applicability = "has-placeholders", + code = "/* Type */", + style = "verbose" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(parse_struct_literal_body_without_path_late)] +#[diag("struct literal body without path")] pub(crate) struct StructLiteralWithoutPathLate { #[primary_span] - #[label] + #[label("struct name missing for struct literal")] pub span: Span, - #[suggestion(applicability = "has-placeholders", code = "/* Type */ ", style = "verbose")] + #[suggestion( + "add the correct type", + applicability = "has-placeholders", + code = "/* Type */ ", + style = "verbose" + )] pub suggestion_span: Span, } @@ -3716,19 +4373,22 @@ pub(crate) enum ForbiddenLetReason { /// `let` is not valid and the source environment is not important OtherForbidden, /// A let chain with the `||` operator - #[note(parse_not_supported_or)] + #[note("`||` operators are not supported in let chain expressions")] NotSupportedOr(#[primary_span] Span), /// A let chain with invalid parentheses /// /// For example, `let 1 = 1 && (expr && expr)` is allowed /// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not - #[note(parse_not_supported_parentheses)] + #[note("`let`s wrapped in parentheses are not supported in a context with let chains")] NotSupportedParentheses(#[primary_span] Span), } #[derive(Debug, rustc_macros::Subdiagnostic)] #[suggestion( - parse_misspelled_kw, + "{$is_incorrect_case -> + [true] write keyword `{$similar_kw}` in lowercase + *[false] there is a keyword `{$similar_kw}` with a similar name + }", applicability = "machine-applicable", code = "{similar_kw}", style = "verbose" diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index c836d52a71e4..40cdcfc35c2f 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -75,8 +75,6 @@ const _: () = { } }; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - // Unwrap the result if `Ok`, otherwise emit the diagnostics and abort. pub fn unwrap_or_emit_fatal(expr: Result>>) -> T { match expr { diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index fe8c1deedff7..3830d4b4cd41 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -3,7 +3,7 @@ use rustc_ast::token::{self, MetaVarKind}; use rustc_ast::tokenstream::ParserRange; use rustc_ast::{AttrItemKind, Attribute, attr}; use rustc_errors::codes::*; -use rustc_errors::{Diag, PResult}; +use rustc_errors::{Diag, PResult, inline_fluent}; use rustc_span::{BytePos, Span}; use thin_vec::ThinVec; use tracing::debug; @@ -13,7 +13,7 @@ use super::{ Trailing, UsePreAttrPos, }; use crate::parser::FnContext; -use crate::{errors, exp, fluent_generated as fluent}; +use crate::{errors, exp}; // Public for rustfmt usage #[derive(Debug)] @@ -68,7 +68,7 @@ impl<'a> Parser<'a> { let span = self.token.span; let mut err = self .dcx() - .struct_span_err(span, fluent::parse_inner_doc_comment_not_permitted); + .struct_span_err(span, inline_fluent!("expected outer doc comment")); err.code(E0753); if let Some(replacement_span) = self.annotate_following_item_if_applicable( &mut err, @@ -79,10 +79,12 @@ impl<'a> Parser<'a> { }, true, ) { - err.note(fluent::parse_note); + err.note(inline_fluent!( + "inner doc comments like this (starting with `//!` or `/*!`) can only appear before items" + )); err.span_suggestion_verbose( replacement_span, - fluent::parse_suggestion, + inline_fluent!("you might have meant to write a regular comment"), "", rustc_errors::Applicability::MachineApplicable, ); @@ -209,11 +211,11 @@ impl<'a> Parser<'a> { Ok(Some(item)) => { // FIXME(#100717) err.arg("item", item.kind.descr()); - err.span_label(item.span, fluent::parse_label_does_not_annotate_this); + err.span_label(item.span, inline_fluent!("BROKEN")); if suggest_to_outer { err.span_suggestion_verbose( replacement_span, - fluent::parse_sugg_change_inner_to_outer, + inline_fluent!("BROKEN"), match attr_type { OuterAttributeType::Attribute => "", OuterAttributeType::DocBlockComment => "*", @@ -244,28 +246,42 @@ impl<'a> Parser<'a> { self.dcx() .struct_span_err( attr_sp, - fluent::parse_inner_attr_not_permitted_after_outer_doc_comment, + inline_fluent!( + "an inner attribute is not permitted following an outer doc comment" + ), + ) + .with_span_label( + attr_sp, + inline_fluent!("not permitted following an outer doc comment"), ) - .with_span_label(attr_sp, fluent::parse_label_attr) .with_span_label( prev_doc_comment_span, - fluent::parse_label_prev_doc_comment, + inline_fluent!("previous doc comment"), ) } Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => self .dcx() .struct_span_err( attr_sp, - fluent::parse_inner_attr_not_permitted_after_outer_attr, + inline_fluent!( + "an inner attribute is not permitted following an outer attribute" + ), ) - .with_span_label(attr_sp, fluent::parse_label_attr) - .with_span_label(prev_outer_attr_sp, fluent::parse_label_prev_attr), - Some(InnerAttrForbiddenReason::InCodeBlock) | None => { - self.dcx().struct_span_err(attr_sp, fluent::parse_inner_attr_not_permitted) - } + .with_span_label( + attr_sp, + inline_fluent!("not permitted following an outer attribute"), + ) + .with_span_label( + prev_outer_attr_sp, + inline_fluent!("previous outer attribute"), + ), + Some(InnerAttrForbiddenReason::InCodeBlock) | None => self.dcx().struct_span_err( + attr_sp, + inline_fluent!("an inner attribute is not permitted in this context"), + ), }; - diag.note(fluent::parse_inner_attr_explanation); + diag.note(inline_fluent!("inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files")); if self .annotate_following_item_if_applicable( &mut diag, @@ -275,7 +291,9 @@ impl<'a> Parser<'a> { ) .is_some() { - diag.note(fluent::parse_outer_attr_explanation); + diag.note(inline_fluent!( + "outer attributes, like `#[test]`, annotate the item following them" + )); }; diag.emit(); } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index cb8a291c7fa0..adba2065c457 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -13,7 +13,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, PResult, Subdiagnostic, Suggestions, - pluralize, + inline_fluent, pluralize, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; @@ -41,10 +41,10 @@ use crate::errors::{ TernaryOperatorSuggestion, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType, }; +use crate::exp; use crate::parser::FnContext; use crate::parser::attr::InnerAttrPolicy; use crate::parser::item::IsDotDotDot; -use crate::{exp, fluent_generated as fluent}; /// Creates a placeholder argument. pub(super) fn dummy_arg(ident: Ident, guar: ErrorGuaranteed) -> Param { @@ -1272,7 +1272,7 @@ impl<'a> Parser<'a> { // We made sense of it. Improve the error message. e.span_suggestion_verbose( binop.span.shrink_to_lo(), - fluent::parse_sugg_turbofish_syntax, + inline_fluent!("use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments"), "::", Applicability::MaybeIncorrect, ); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 6b61504f2327..c35ddc4dc943 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -11,7 +11,7 @@ use rustc_ast::{ }; use rustc_ast_pretty::pprust; use rustc_errors::codes::*; -use rustc_errors::{Applicability, PResult, StashKey, struct_span_code_err}; +use rustc_errors::{Applicability, PResult, StashKey, inline_fluent, struct_span_code_err}; use rustc_session::lint::builtin::VARARGS_WITHOUT_PATTERN; use rustc_span::edit_distance::edit_distance; use rustc_span::edition::Edition; @@ -26,7 +26,7 @@ use super::{ Parser, PathStyle, Recovered, Trailing, UsePreAttrPos, }; use crate::errors::{self, FnPointerCannotBeAsync, FnPointerCannotBeConst, MacroExpandsToAdtField}; -use crate::{exp, fluent_generated as fluent}; +use crate::exp; impl<'a> Parser<'a> { /// Parses a source module as a crate. This is the main entry point for the parser. @@ -1721,7 +1721,7 @@ impl<'a> Parser<'a> { if this.token == token::Bang { if let Err(err) = this.unexpected() { - err.with_note(fluent::parse_macro_expands_to_enum_variant).emit(); + err.with_note(inline_fluent!("macros cannot expand to enum variants")).emit(); } this.bump(); diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 61b498431b04..1b17f422345f 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -25,10 +25,6 @@ use crate::lexer::StripTokens; use crate::parser::{AllowConstBlockItems, ForceCollect, Parser}; use crate::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal}; -fn psess() -> ParseSess { - ParseSess::new(vec![crate::DEFAULT_LOCALE_RESOURCE]) -} - fn filename(sm: &SourceMap, path: &str) -> FileName { FileName::Real(sm.path_mapping().to_real_filename(sm.working_dir(), PathBuf::from(path))) } @@ -46,7 +42,7 @@ fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> { fn create_test_handler(theme: OutputTheme) -> (DiagCtxt, Arc, Arc>>) { let output = Arc::new(Mutex::new(Vec::new())); let source_map = Arc::new(SourceMap::new(FilePathMapping::empty())); - let translator = Translator::with_fallback_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false); + let translator = Translator::with_fallback_bundle(vec![], false); let shared: Box = Box::new(Shared { data: output.clone() }); let auto_stream = AutoStream::never(shared); let dcx = DiagCtxt::new(Box::new( @@ -93,7 +89,7 @@ where /// Maps a string to tts, using a made-up filename. pub(crate) fn string_to_stream(source_str: String) -> TokenStream { - let psess = psess(); + let psess = ParseSess::new(vec![]); unwrap_or_emit_fatal(source_str_to_stream( &psess, filename(psess.source_map(), "bogofile"), @@ -2243,12 +2239,12 @@ fn sp(a: u32, b: u32) -> Span { /// Parses a string, return an expression. fn string_to_expr(source_str: String) -> Box { - with_error_checking_parse(source_str, &psess(), |p| p.parse_expr()) + with_error_checking_parse(source_str, &ParseSess::new(vec![]), |p| p.parse_expr()) } /// Parses a string, returns an item. fn string_to_item(source_str: String) -> Option> { - with_error_checking_parse(source_str, &psess(), |p| { + with_error_checking_parse(source_str, &ParseSess::new(vec![]), |p| { p.parse_item(ForceCollect::No, AllowConstBlockItems::Yes) }) } @@ -2484,7 +2480,7 @@ let mut fflags: c_int = wb(); #[test] fn crlf_doc_comments() { create_default_session_globals_then(|| { - let psess = psess(); + let psess = ParseSess::new(vec![]); let name_1 = FileName::Custom("crlf_source_1".to_string()); let source = "/// doc comment\r\nfn foo() {}".to_string(); @@ -2519,7 +2515,7 @@ fn ttdelim_span() { } create_default_session_globals_then(|| { - let psess = psess(); + let psess = ParseSess::new(vec![]); let expr = parse_expr_from_source_str( filename(psess.source_map(), "foo"), "foo!( fn main() { body } )".to_string(), @@ -2555,7 +2551,7 @@ fn look_ahead() { let sym_S = Symbol::intern("S"); let raw_no = IdentIsRaw::No; - let psess = psess(); + let psess = ParseSess::new(vec![]); let mut p = string_to_parser(&psess, "fn f(x: u32) { x } struct S;".to_string()); // Current position is the `fn`. @@ -2630,7 +2626,7 @@ fn look_ahead_non_outermost_stream() { let sym_S = Symbol::intern("S"); let raw_no = IdentIsRaw::No; - let psess = psess(); + let psess = ParseSess::new(vec![]); let mut p = string_to_parser(&psess, "mod m { fn f(x: u32) { x } struct S; }".to_string()); // Move forward to the `fn`, which is not within the outermost token @@ -2662,7 +2658,7 @@ fn look_ahead_non_outermost_stream() { #[test] fn debug_lookahead() { create_default_session_globals_then(|| { - let psess = psess(); + let psess = ParseSess::new(vec![]); let mut p = string_to_parser(&psess, "fn f(x: u32) { x } struct S;".to_string()); // Current position is the `fn`. @@ -2883,7 +2879,7 @@ fn debug_lookahead() { #[test] fn out_of_line_mod() { create_default_session_globals_then(|| { - let psess = psess(); + let psess = ParseSess::new(vec![]); let item = parse_item_from_source_str( filename(psess.source_map(), "foo"), "mod foo { struct S; mod this_does_not_exist; }".to_owned(), diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index d198675c0b22..7bebbc579c43 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -313,8 +313,8 @@ impl ParseSess { } } - pub fn emitter_with_note(locale_resources: Vec<&'static str>, note: String) -> Self { - let translator = Translator::with_fallback_bundle(locale_resources, false); + pub fn emitter_with_note(note: String) -> Self { + let translator = Translator::with_fallback_bundle(vec![], false); let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); let emitter = Box::new(AnnotateSnippetEmitter::new( stderr_destination(ColorConfig::Auto), diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs index 86f2d5f5954a..894fec248f1f 100644 --- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs +++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs @@ -29,7 +29,7 @@ pub fn main() { } fn parse() { - let psess = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]); + let psess = ParseSess::new(vec![]); let path = Path::new(file!()); let path = path.canonicalize().unwrap(); diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs index 08ded2aee53d..7fe71004522a 100644 --- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs @@ -219,7 +219,7 @@ fn main() { } fn run() { - let psess = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]); + let psess = ParseSess::new(vec![]); iter_exprs(2, &mut |mut e| { // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`, diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 72b5cfb90630..90cf9b89a293 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -196,7 +196,7 @@ fn main() -> ExitCode { }; rustc_span::create_default_session_globals_then(|| { - let psess = &ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]); + let psess = &ParseSess::new(vec![]); for &source_code in EXPRS { let Some(expr) = parse_expr(psess, source_code) else { From cda9b8c15752df635d693cfe73b147e6090faddc Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 16:44:53 +0100 Subject: [PATCH 3340/3801] Split `ComparisonOrShiftInterpretedAsGenericSugg` --- compiler/rustc_parse/src/errors.rs | 17 +++++++++++++---- compiler/rustc_parse/src/parser/expr.rs | 15 ++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 4a7031257700..418d56f632bd 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -861,7 +861,16 @@ pub(crate) struct ComparisonInterpretedAsGeneric { #[label("interpreted as generic arguments")] pub args: Span, #[subdiagnostic] - pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg, + pub suggestion: ComparisonInterpretedAsGenericSugg, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("try comparing the cast value", applicability = "machine-applicable")] +pub(crate) struct ComparisonInterpretedAsGenericSugg { + #[suggestion_part(code = "(")] + pub left: Span, + #[suggestion_part(code = ")")] + pub right: Span, } #[derive(Diagnostic)] @@ -874,12 +883,12 @@ pub(crate) struct ShiftInterpretedAsGeneric { #[label("interpreted as generic arguments")] pub args: Span, #[subdiagnostic] - pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg, + pub suggestion: ShiftInterpretedAsGenericSugg, } #[derive(Subdiagnostic)] -#[multipart_suggestion("BROKEN", applicability = "machine-applicable")] -pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg { +#[multipart_suggestion("try shifting the cast value", applicability = "machine-applicable")] +pub(crate) struct ShiftInterpretedAsGenericSugg { #[suggestion_part(code = "(")] pub left: Span, #[suggestion_part(code = ")")] diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 11cde35fab17..8bb22c2a831b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -727,25 +727,26 @@ impl<'a> Parser<'a> { ); let args_span = self.look_ahead(1, |t| t.span).to(span_after_type); - let suggestion = errors::ComparisonOrShiftInterpretedAsGenericSugg { - left: expr.span.shrink_to_lo(), - right: expr.span.shrink_to_hi(), - }; - match self.token.kind { token::Lt => { self.dcx().emit_err(errors::ComparisonInterpretedAsGeneric { comparison: self.token.span, r#type: path, args: args_span, - suggestion, + suggestion: errors::ComparisonInterpretedAsGenericSugg { + left: expr.span.shrink_to_lo(), + right: expr.span.shrink_to_hi(), + }, }) } token::Shl => self.dcx().emit_err(errors::ShiftInterpretedAsGeneric { shift: self.token.span, r#type: path, args: args_span, - suggestion, + suggestion: errors::ShiftInterpretedAsGenericSugg { + left: expr.span.shrink_to_lo(), + right: expr.span.shrink_to_hi(), + }, }), _ => { // We can end up here even without `<` being the next token, for From c5587ca91967f91bf2f1467fbfa68e5d5448bce3 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 16:59:55 +0100 Subject: [PATCH 3341/3801] Split `parse_inner_attr` errors by case --- compiler/rustc_parse/src/parser/attr.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 3830d4b4cd41..3d16f37c000e 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -209,13 +209,25 @@ impl<'a> Parser<'a> { AllowConstBlockItems::Yes, ) { Ok(Some(item)) => { - // FIXME(#100717) err.arg("item", item.kind.descr()); - err.span_label(item.span, inline_fluent!("BROKEN")); + err.span_label( + item.span, + match attr_type { + OuterAttributeType::Attribute => { + inline_fluent!("the inner attribute doesn't annotate this {$item}") + } + OuterAttributeType::DocComment | OuterAttributeType::DocBlockComment => { + inline_fluent!("the inner doc comment doesn't annotate this {$item}") + } + }, + ); if suggest_to_outer { err.span_suggestion_verbose( replacement_span, - inline_fluent!("BROKEN"), + match attr_type { + OuterAttributeType::Attribute => inline_fluent!("to annotate the {$item}, change the attribute from inner to outer style"), + OuterAttributeType::DocComment | OuterAttributeType::DocBlockComment => inline_fluent!("to annotate the {$item}, change the doc comment from inner to outer style"), + }, match attr_type { OuterAttributeType::Attribute => "", OuterAttributeType::DocBlockComment => "*", From 0ef518c94695c7d852ec49ec9903d338efec109d Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 18:00:22 +0100 Subject: [PATCH 3342/3801] Disable the `run-make/translation` test for now --- tests/run-make/translation/rmake.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/run-make/translation/rmake.rs b/tests/run-make/translation/rmake.rs index 86078888c2e1..4d7fd71a2f4a 100644 --- a/tests/run-make/translation/rmake.rs +++ b/tests/run-make/translation/rmake.rs @@ -10,6 +10,9 @@ //@ needs-symlink //@ needs-subprocess +// FIXME(151366) Currently `-Ztranslate-additional-ftl` is currently broken +//@ ignore-test + #![deny(warnings)] use std::path::{Path, PathBuf}; From 00dd7dbe57923937377ed81369ec3206bf61b161 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 7 Feb 2026 10:31:36 +0100 Subject: [PATCH 3343/3801] Allow more capitalized words --- compiler/rustc_macros/src/diagnostics/message.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_macros/src/diagnostics/message.rs b/compiler/rustc_macros/src/diagnostics/message.rs index ad3ca4d1f8ea..2db8df2f69ae 100644 --- a/compiler/rustc_macros/src/diagnostics/message.rs +++ b/compiler/rustc_macros/src/diagnostics/message.rs @@ -156,6 +156,8 @@ const ALLOWED_CAPITALIZED_WORDS: &[&str] = &[ "MIR", "NaNs", "OK", + "Rust", + "Unicode", "VS", // tidy-alphabetical-end ]; From c9d59bac1ec002137c1e53bc211f29996a849cea Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 7 Feb 2026 04:39:20 -0600 Subject: [PATCH 3344/3801] ci: Update all docker images to the latest version --- .../ci/docker/aarch64-unknown-linux-gnu/Dockerfile | 6 +++--- .../ci/docker/arm-unknown-linux-gnueabi/Dockerfile | 6 +++--- .../ci/docker/arm-unknown-linux-gnueabihf/Dockerfile | 6 +++--- .../ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile | 6 +++--- .../ci/docker/i586-unknown-linux-gnu/Dockerfile | 2 +- .../ci/docker/i686-unknown-linux-gnu/Dockerfile | 2 +- .../ci/docker/loongarch64-unknown-linux-gnu/Dockerfile | 6 +++--- .../ci/docker/mips-unknown-linux-gnu/Dockerfile | 6 +++--- .../ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile | 6 +++--- .../ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile | 6 +++--- .../ci/docker/mipsel-unknown-linux-gnu/Dockerfile | 6 +++--- .../ci/docker/powerpc-unknown-linux-gnu/Dockerfile | 6 +++--- .../ci/docker/powerpc64-unknown-linux-gnu/Dockerfile | 6 +++--- .../ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile | 6 +++--- .../ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile | 6 +++--- .../ci/docker/thumbv6m-none-eabi/Dockerfile | 2 +- .../ci/docker/thumbv7em-none-eabi/Dockerfile | 2 +- .../ci/docker/thumbv7em-none-eabihf/Dockerfile | 2 +- .../ci/docker/thumbv7m-none-eabi/Dockerfile | 2 +- .../ci/docker/wasm32-unknown-unknown/Dockerfile | 2 +- .../ci/docker/x86_64-unknown-linux-gnu/Dockerfile | 2 +- library/compiler-builtins/ci/run-docker.sh | 2 +- 22 files changed, 48 insertions(+), 48 deletions(-) diff --git a/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile index 69b99f5b6b32..683bd07fd47e 100644 --- a/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile @@ -1,15 +1,15 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc libc6-dev ca-certificates \ gcc-aarch64-linux-gnu m4 make libc6-dev-arm64-cross \ - qemu-user-static + qemu-user ENV TOOLCHAIN_PREFIX=aarch64-linux-gnu- ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-aarch64-static \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-aarch64 \ AR_aarch64_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_aarch64_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/aarch64-linux-gnu \ diff --git a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile index 2fa6f8520520..781abd1b6e88 100644 --- a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile +++ b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile @@ -1,14 +1,14 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc libc6-dev ca-certificates \ - gcc-arm-linux-gnueabi libc6-dev-armel-cross qemu-user-static + gcc-arm-linux-gnueabi libc6-dev-armel-cross qemu-user ENV TOOLCHAIN_PREFIX=arm-linux-gnueabi- ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_RUNNER=qemu-arm-static \ + CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_RUNNER=qemu-arm \ AR_arm_unknown_linux_gnueabi="$TOOLCHAIN_PREFIX"ar \ CC_arm_unknown_linux_gnueabi="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/arm-linux-gnueabi \ diff --git a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile index 85f7335f5a85..36ea4827dc52 100644 --- a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile +++ b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile @@ -1,14 +1,14 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc libc6-dev ca-certificates \ - gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user-static + gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user ENV TOOLCHAIN_PREFIX=arm-linux-gnueabihf- ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm-static \ + CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm \ AR_arm_unknown_linux_gnueabihf="$TOOLCHAIN_PREFIX"ar \ CC_arm_unknown_linux_gnueabihf="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf \ diff --git a/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile b/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile index 42511479f36f..8b76693b2799 100644 --- a/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile +++ b/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile @@ -1,14 +1,14 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc libc6-dev ca-certificates \ - gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user-static + gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user ENV TOOLCHAIN_PREFIX=arm-linux-gnueabihf- ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm-static \ + CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm \ AR_armv7_unknown_linux_gnueabihf="$TOOLCHAIN_PREFIX"ar \ CC_armv7_unknown_linux_gnueabihf="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf \ diff --git a/library/compiler-builtins/ci/docker/i586-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/i586-unknown-linux-gnu/Dockerfile index 35488c477493..9125038acbde 100644 --- a/library/compiler-builtins/ci/docker/i586-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/i586-unknown-linux-gnu/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ diff --git a/library/compiler-builtins/ci/docker/i686-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/i686-unknown-linux-gnu/Dockerfile index 35488c477493..9125038acbde 100644 --- a/library/compiler-builtins/ci/docker/i686-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/i686-unknown-linux-gnu/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ diff --git a/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile index e95a1b9163ff..a65223595877 100644 --- a/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile @@ -1,13 +1,13 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user-static ca-certificates \ + gcc libc6-dev qemu-user ca-certificates \ gcc-14-loongarch64-linux-gnu libc6-dev-loong64-cross ENV CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_LINKER=loongarch64-linux-gnu-gcc-14 \ - CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-loongarch64-static \ + CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-loongarch64 \ AR_loongarch64_unknown_linux_gnu=loongarch64-linux-gnu-ar \ CC_loongarch64_unknown_linux_gnu=loongarch64-linux-gnu-gcc-14 \ QEMU_LD_PREFIX=/usr/loongarch64-linux-gnu \ diff --git a/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile index fd1877603100..0913f33c05ce 100644 --- a/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile @@ -1,15 +1,15 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc libc6-dev ca-certificates \ gcc-mips-linux-gnu libc6-dev-mips-cross \ - binfmt-support qemu-user-static qemu-system-mips + binfmt-support qemu-user qemu-system-mips ENV TOOLCHAIN_PREFIX=mips-linux-gnu- ENV CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_RUNNER=qemu-mips-static \ + CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_RUNNER=qemu-mips \ AR_mips_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_mips_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/mips-linux-gnu \ diff --git a/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile b/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile index 4e542ce6858c..d2f4e484b1aa 100644 --- a/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile +++ b/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ @@ -8,12 +8,12 @@ RUN apt-get update && \ gcc-mips64-linux-gnuabi64 \ libc6-dev \ libc6-dev-mips64-cross \ - qemu-user-static \ + qemu-user \ qemu-system-mips ENV TOOLCHAIN_PREFIX=mips64-linux-gnuabi64- ENV CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_RUNNER=qemu-mips64-static \ + CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_RUNNER=qemu-mips64 \ AR_mips64_unknown_linux_gnuabi64="$TOOLCHAIN_PREFIX"ar \ CC_mips64_unknown_linux_gnuabi64="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/mips64-linux-gnuabi64 \ diff --git a/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile b/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile index 528dfd8940d5..873754b2793e 100644 --- a/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile +++ b/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ @@ -8,11 +8,11 @@ RUN apt-get update && \ gcc-mips64el-linux-gnuabi64 \ libc6-dev \ libc6-dev-mips64el-cross \ - qemu-user-static + qemu-user ENV TOOLCHAIN_PREFIX=mips64el-linux-gnuabi64- ENV CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_RUNNER=qemu-mips64el-static \ + CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_RUNNER=qemu-mips64el \ AR_mips64el_unknown_linux_gnuabi64="$TOOLCHAIN_PREFIX"ar \ CC_mips64el_unknown_linux_gnuabi64="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/mips64el-linux-gnuabi64 \ diff --git a/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile index 2572180238e2..5768b68d6c95 100644 --- a/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile @@ -1,15 +1,15 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc libc6-dev ca-certificates \ gcc-mipsel-linux-gnu libc6-dev-mipsel-cross \ - binfmt-support qemu-user-static + binfmt-support qemu-user ENV TOOLCHAIN_PREFIX=mipsel-linux-gnu- ENV CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_GNU_RUNNER=qemu-mipsel-static \ + CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_GNU_RUNNER=qemu-mipsel \ AR_mipsel_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_mipsel_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/mipsel-linux-gnu \ diff --git a/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile index cac1f23610aa..c625a4bcd5d7 100644 --- a/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile @@ -1,15 +1,15 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user-static ca-certificates \ + gcc libc6-dev qemu-user ca-certificates \ gcc-powerpc-linux-gnu libc6-dev-powerpc-cross \ qemu-system-ppc ENV TOOLCHAIN_PREFIX=powerpc-linux-gnu- ENV CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc-static \ + CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc \ AR_powerpc_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_powerpc_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/powerpc-linux-gnu \ diff --git a/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile index 76127b7dbb8c..86a7a8cd46e4 100644 --- a/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile @@ -1,15 +1,15 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc libc6-dev ca-certificates \ gcc-powerpc64-linux-gnu libc6-dev-ppc64-cross \ - binfmt-support qemu-user-static qemu-system-ppc + binfmt-support qemu-user qemu-system-ppc ENV TOOLCHAIN_PREFIX=powerpc64-linux-gnu- ENV CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64-static \ + CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64 \ AR_powerpc64_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_powerpc64_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/powerpc64-linux-gnu \ diff --git a/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile index da1d56ca66f2..722b10b0a734 100644 --- a/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile @@ -1,15 +1,15 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user-static ca-certificates \ + gcc libc6-dev qemu-user ca-certificates \ gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross \ qemu-system-ppc ENV TOOLCHAIN_PREFIX=powerpc64le-linux-gnu- ENV CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64le-static \ + CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64le \ AR_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu \ diff --git a/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile index 513efacd6d96..7a721ba05416 100644 --- a/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile @@ -1,15 +1,15 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user-static ca-certificates \ + gcc libc6-dev qemu-user ca-certificates \ gcc-riscv64-linux-gnu libc6-dev-riscv64-cross \ qemu-system-riscv64 ENV TOOLCHAIN_PREFIX=riscv64-linux-gnu- ENV CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ - CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_RUNNER=qemu-riscv64-static \ + CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_RUNNER=qemu-riscv64 \ AR_riscv64gc_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_riscv64gc_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ QEMU_LD_PREFIX=/usr/riscv64-linux-gnu \ diff --git a/library/compiler-builtins/ci/docker/thumbv6m-none-eabi/Dockerfile b/library/compiler-builtins/ci/docker/thumbv6m-none-eabi/Dockerfile index a9a172a21137..a1a6b3cf5cfd 100644 --- a/library/compiler-builtins/ci/docker/thumbv6m-none-eabi/Dockerfile +++ b/library/compiler-builtins/ci/docker/thumbv6m-none-eabi/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ diff --git a/library/compiler-builtins/ci/docker/thumbv7em-none-eabi/Dockerfile b/library/compiler-builtins/ci/docker/thumbv7em-none-eabi/Dockerfile index a9a172a21137..a1a6b3cf5cfd 100644 --- a/library/compiler-builtins/ci/docker/thumbv7em-none-eabi/Dockerfile +++ b/library/compiler-builtins/ci/docker/thumbv7em-none-eabi/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ diff --git a/library/compiler-builtins/ci/docker/thumbv7em-none-eabihf/Dockerfile b/library/compiler-builtins/ci/docker/thumbv7em-none-eabihf/Dockerfile index a9a172a21137..a1a6b3cf5cfd 100644 --- a/library/compiler-builtins/ci/docker/thumbv7em-none-eabihf/Dockerfile +++ b/library/compiler-builtins/ci/docker/thumbv7em-none-eabihf/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ diff --git a/library/compiler-builtins/ci/docker/thumbv7m-none-eabi/Dockerfile b/library/compiler-builtins/ci/docker/thumbv7m-none-eabi/Dockerfile index a9a172a21137..a1a6b3cf5cfd 100644 --- a/library/compiler-builtins/ci/docker/thumbv7m-none-eabi/Dockerfile +++ b/library/compiler-builtins/ci/docker/thumbv7m-none-eabi/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ diff --git a/library/compiler-builtins/ci/docker/wasm32-unknown-unknown/Dockerfile b/library/compiler-builtins/ci/docker/wasm32-unknown-unknown/Dockerfile index 2813d318670e..b646a72bb37c 100644 --- a/library/compiler-builtins/ci/docker/wasm32-unknown-unknown/Dockerfile +++ b/library/compiler-builtins/ci/docker/wasm32-unknown-unknown/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:20.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ diff --git a/library/compiler-builtins/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/x86_64-unknown-linux-gnu/Dockerfile index 2ef800129d67..927515f90f32 100644 --- a/library/compiler-builtins/ci/docker/x86_64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/x86_64-unknown-linux-gnu/Dockerfile @@ -1,4 +1,4 @@ -ARG IMAGE=ubuntu:25.04 +ARG IMAGE=ubuntu:25.10 FROM $IMAGE RUN apt-get update && \ diff --git a/library/compiler-builtins/ci/run-docker.sh b/library/compiler-builtins/ci/run-docker.sh index 4c1fe0fe2644..e65ada271904 100755 --- a/library/compiler-builtins/ci/run-docker.sh +++ b/library/compiler-builtins/ci/run-docker.sh @@ -97,7 +97,7 @@ if [ "${1:-}" = "--help" ] || [ "$#" -gt 1 ]; then usage: ./ci/run-docker.sh [target] you can also set DOCKER_BASE_IMAGE to use something other than the default - ubuntu:25.04 (or rustlang/rust:nightly). + ubuntu:25.10 (or rustlang/rust:nightly). " exit fi From 4d24b508bb1004116eb71b93afaabfd83a3aa9e3 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 7 Feb 2026 04:10:45 -0600 Subject: [PATCH 3345/3801] meta: Upgrade all dependencies to the latest compatible versions This allows us to drop wasm-specific configuration for `getrandom`. Link: https://github.com/rust-random/getrandom/blob/314fd5ab3e6d9ef2ec90243894731865a725417d/CHANGELOG.md#major-change-to-wasm_js-backend --- library/compiler-builtins/ci/run.sh | 5 ----- .../crates/libm-macros/Cargo.toml | 6 +++--- .../crates/musl-math-sys/Cargo.toml | 2 +- .../crates/symbol-check/Cargo.toml | 4 ++-- library/compiler-builtins/crates/util/Cargo.toml | 2 +- library/compiler-builtins/libm-test/Cargo.toml | 16 ++++++++-------- .../compiler-builtins/libm-test/src/precision.rs | 2 +- 7 files changed, 16 insertions(+), 21 deletions(-) diff --git a/library/compiler-builtins/ci/run.sh b/library/compiler-builtins/ci/run.sh index 0c07b32c74b9..52fb4b151ca5 100755 --- a/library/compiler-builtins/ci/run.sh +++ b/library/compiler-builtins/ci/run.sh @@ -13,11 +13,6 @@ if [ -z "$target" ]; then target="$host_target" fi -if [[ "$target" = *"wasm"* ]]; then - # Enable the random backend - export RUSTFLAGS="${RUSTFLAGS:-} --cfg getrandom_backend=\"wasm_js\"" -fi - if [ "${USING_CONTAINER_RUSTC:-}" = 1 ]; then # Install nonstandard components if we have control of the environment rustup target list --installed | diff --git a/library/compiler-builtins/crates/libm-macros/Cargo.toml b/library/compiler-builtins/crates/libm-macros/Cargo.toml index 100a8d0ec30e..f6697b783457 100644 --- a/library/compiler-builtins/crates/libm-macros/Cargo.toml +++ b/library/compiler-builtins/crates/libm-macros/Cargo.toml @@ -10,9 +10,9 @@ proc-macro = true [dependencies] heck = "0.5.0" -proc-macro2 = "1.0.95" -quote = "1.0.40" -syn = { version = "2.0.104", features = ["full", "extra-traits", "visit-mut"] } +proc-macro2 = "1.0.106" +quote = "1.0.44" +syn = { version = "2.0.114", features = ["full", "extra-traits", "visit-mut"] } [lints.rust] # Values used during testing diff --git a/library/compiler-builtins/crates/musl-math-sys/Cargo.toml b/library/compiler-builtins/crates/musl-math-sys/Cargo.toml index 39f6fa9065bd..60b0647b6dc6 100644 --- a/library/compiler-builtins/crates/musl-math-sys/Cargo.toml +++ b/library/compiler-builtins/crates/musl-math-sys/Cargo.toml @@ -11,4 +11,4 @@ license = "MIT OR Apache-2.0" libm = { path = "../../libm" } [build-dependencies] -cc = "1.2.29" +cc = "1.2.55" diff --git a/library/compiler-builtins/crates/symbol-check/Cargo.toml b/library/compiler-builtins/crates/symbol-check/Cargo.toml index e2218b491720..9f027df1e4f5 100644 --- a/library/compiler-builtins/crates/symbol-check/Cargo.toml +++ b/library/compiler-builtins/crates/symbol-check/Cargo.toml @@ -5,8 +5,8 @@ edition = "2024" publish = false [dependencies] -object = "0.37.1" -serde_json = "1.0.140" +object = "0.37.3" +serde_json = "1.0.149" [features] wasm = ["object/wasm"] diff --git a/library/compiler-builtins/crates/util/Cargo.toml b/library/compiler-builtins/crates/util/Cargo.toml index 614c54bd8355..b1ccd8a9e63c 100644 --- a/library/compiler-builtins/crates/util/Cargo.toml +++ b/library/compiler-builtins/crates/util/Cargo.toml @@ -16,4 +16,4 @@ libm = { path = "../../libm", default-features = false } libm-macros = { path = "../libm-macros" } libm-test = { path = "../../libm-test", default-features = false } musl-math-sys = { path = "../musl-math-sys", optional = true } -rug = { version = "1.27.0", optional = true, default-features = false, features = ["float", "std"] } +rug = { version = "1.28.1", optional = true, default-features = false, features = ["float", "std"] } diff --git a/library/compiler-builtins/libm-test/Cargo.toml b/library/compiler-builtins/libm-test/Cargo.toml index adecfc1af6b8..b813331a8552 100644 --- a/library/compiler-builtins/libm-test/Cargo.toml +++ b/library/compiler-builtins/libm-test/Cargo.toml @@ -28,25 +28,25 @@ icount = ["dep:gungraun"] short-benchmarks = [] [dependencies] -anyhow = "1.0.98" +anyhow = "1.0.101" # This is not directly used but is required so we can enable `gmp-mpfr-sys/force-cross`. -gmp-mpfr-sys = { version = "1.6.5", optional = true, default-features = false } +gmp-mpfr-sys = { version = "1.6.8", optional = true, default-features = false } gungraun = { version = "0.17.0", optional = true } -indicatif = { version = "0.18.0", default-features = false } +indicatif = { version = "0.18.3", default-features = false } libm = { path = "../libm", features = ["unstable-public-internals"] } libm-macros = { path = "../crates/libm-macros" } musl-math-sys = { path = "../crates/musl-math-sys", optional = true } paste = "1.0.15" -rand = "0.9.1" +rand = "0.9.2" rand_chacha = "0.9.0" -rayon = "1.10.0" -rug = { version = "1.27.0", optional = true, default-features = false, features = ["float", "integer", "std"] } +rayon = "1.11.0" +rug = { version = "1.28.1", optional = true, default-features = false, features = ["float", "integer", "std"] } [target.'cfg(target_family = "wasm")'.dependencies] -getrandom = { version = "0.3.3", features = ["wasm_js"] } +getrandom = { version = "0.3.4", features = ["wasm_js"] } [build-dependencies] -rand = { version = "0.9.1", optional = true } +rand = { version = "0.9.2", optional = true } [dev-dependencies] criterion = { version = "0.6.0", default-features = false, features = ["cargo_bench_support"] } diff --git a/library/compiler-builtins/libm-test/src/precision.rs b/library/compiler-builtins/libm-test/src/precision.rs index 897f21da78e7..a94fe429f5f3 100644 --- a/library/compiler-builtins/libm-test/src/precision.rs +++ b/library/compiler-builtins/libm-test/src/precision.rs @@ -498,7 +498,7 @@ fn int_float_common( if input.0 > 4000 { return XFAIL_NOCHECK; } else if input.0 > 100 { - return CheckAction::AssertWithUlp(1_000_000); + return CheckAction::AssertWithUlp(2_000_000); } } DEFAULT From 6733cf42a6f5e26cd98b2ae7ad87b4e3c57ffe9b Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 7 Feb 2026 05:04:20 -0600 Subject: [PATCH 3346/3801] symcheck: Enable wasm by default The build time isn't very different so we can keep things simpler. --- library/compiler-builtins/ci/run.sh | 1 - library/compiler-builtins/crates/symbol-check/Cargo.toml | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/library/compiler-builtins/ci/run.sh b/library/compiler-builtins/ci/run.sh index 52fb4b151ca5..ca1304f3dc87 100755 --- a/library/compiler-builtins/ci/run.sh +++ b/library/compiler-builtins/ci/run.sh @@ -47,7 +47,6 @@ fi # `compiler-builtins` is built with various features. Symcheck invokes Cargo to # build with the arguments we provide it, then validates the built artifacts. symcheck=(cargo run -p symbol-check --release) -[[ "$target" = "wasm"* ]] && symcheck+=(--features wasm) symcheck+=(-- build-and-check) "${symcheck[@]}" "$target" -- -p compiler_builtins diff --git a/library/compiler-builtins/crates/symbol-check/Cargo.toml b/library/compiler-builtins/crates/symbol-check/Cargo.toml index 9f027df1e4f5..9e4bc739da15 100644 --- a/library/compiler-builtins/crates/symbol-check/Cargo.toml +++ b/library/compiler-builtins/crates/symbol-check/Cargo.toml @@ -5,8 +5,5 @@ edition = "2024" publish = false [dependencies] -object = "0.37.3" +object = { version = "0.37.3", features = ["wasm"] } serde_json = "1.0.149" - -[features] -wasm = ["object/wasm"] From 9184a5f661e074690b59ab28d7ef16c1c6ae0d06 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 6 Feb 2026 17:54:06 -0600 Subject: [PATCH 3347/3801] symcheck: Add tests for the symbol checker Ensure that these are actually doing what is expected. --- library/compiler-builtins/ci/run.sh | 4 +- .../crates/symbol-check/Cargo.toml | 5 + .../crates/symbol-check/build.rs | 6 + .../crates/symbol-check/src/main.rs | 30 ++--- .../crates/symbol-check/tests/all.rs | 124 ++++++++++++++++++ .../symbol-check/tests/input/core_symbols.rs | 11 ++ .../symbol-check/tests/input/duplicates.rs | 12 ++ .../crates/symbol-check/tests/input/good.rs | 4 + 8 files changed, 176 insertions(+), 20 deletions(-) create mode 100644 library/compiler-builtins/crates/symbol-check/build.rs create mode 100644 library/compiler-builtins/crates/symbol-check/tests/all.rs create mode 100644 library/compiler-builtins/crates/symbol-check/tests/input/core_symbols.rs create mode 100644 library/compiler-builtins/crates/symbol-check/tests/input/duplicates.rs create mode 100644 library/compiler-builtins/crates/symbol-check/tests/input/good.rs diff --git a/library/compiler-builtins/ci/run.sh b/library/compiler-builtins/ci/run.sh index ca1304f3dc87..12b3f37889c9 100755 --- a/library/compiler-builtins/ci/run.sh +++ b/library/compiler-builtins/ci/run.sh @@ -46,6 +46,7 @@ fi # Ensure there are no duplicate symbols or references to `core` when # `compiler-builtins` is built with various features. Symcheck invokes Cargo to # build with the arguments we provide it, then validates the built artifacts. +SYMCHECK_TEST_TARGET="$target" cargo test -p symbol-check --release symcheck=(cargo run -p symbol-check --release) symcheck+=(-- build-and-check) @@ -151,7 +152,8 @@ if [ "${BUILD_ONLY:-}" = "1" ]; then echo "can't run tests on $target; skipping" else - mflags+=(--workspace --target "$target") + # symcheck tests need specific env setup, and is already tested above + mflags+=(--workspace --exclude symbol-check --target "$target") cmd=(cargo test "${mflags[@]}") profile_flag="--profile" diff --git a/library/compiler-builtins/crates/symbol-check/Cargo.toml b/library/compiler-builtins/crates/symbol-check/Cargo.toml index 9e4bc739da15..774d1c31a4b0 100644 --- a/library/compiler-builtins/crates/symbol-check/Cargo.toml +++ b/library/compiler-builtins/crates/symbol-check/Cargo.toml @@ -7,3 +7,8 @@ publish = false [dependencies] object = { version = "0.37.3", features = ["wasm"] } serde_json = "1.0.149" + +[dev-dependencies] +assert_cmd = "2.1.2" +cc = "1.2.55" +tempfile = "3.24.0" diff --git a/library/compiler-builtins/crates/symbol-check/build.rs b/library/compiler-builtins/crates/symbol-check/build.rs new file mode 100644 index 000000000000..b3e53c38b0bd --- /dev/null +++ b/library/compiler-builtins/crates/symbol-check/build.rs @@ -0,0 +1,6 @@ +use std::env; + +fn main() { + println!("cargo::rustc-env=HOST={}", env::var("HOST").unwrap()); + println!("cargo::rustc-env=TARGET={}", env::var("TARGET").unwrap()); +} diff --git a/library/compiler-builtins/crates/symbol-check/src/main.rs b/library/compiler-builtins/crates/symbol-check/src/main.rs index 7d0b7e90addb..1413042e6c70 100644 --- a/library/compiler-builtins/crates/symbol-check/src/main.rs +++ b/library/compiler-builtins/crates/symbol-check/src/main.rs @@ -1,7 +1,10 @@ //! Tool used by CI to inspect compiler-builtins archives and help ensure we won't run into any //! linking errors. +//! +//! Note that symcheck is a "hostprog", i.e. is built and run on the host target even when the +//! actual target is cross compiled. -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::fs; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; @@ -42,8 +45,7 @@ fn main() { run_build_and_check(target, args); } ["build-and-check", "--", args @ ..] if !args.is_empty() => { - let target = &host_target(); - run_build_and_check(target, args); + run_build_and_check(env!("HOST"), args); } ["check", paths @ ..] if !paths.is_empty() => { check_paths(paths); @@ -80,20 +82,6 @@ fn check_paths>(paths: &[P]) { } } -fn host_target() -> String { - let out = Command::new("rustc") - .arg("--version") - .arg("--verbose") - .output() - .unwrap(); - assert!(out.status.success()); - let out = String::from_utf8(out.stdout).unwrap(); - out.lines() - .find_map(|s| s.strip_prefix("host: ")) - .unwrap() - .to_owned() -} - /// Run `cargo build` with the provided additional arguments, collecting the list of created /// libraries. fn exec_cargo_with_args(target: &str, args: &[&str]) -> Vec { @@ -257,8 +245,9 @@ fn verify_no_duplicates(archive: &BinFile) { assert!(found_any, "no symbols found"); if !dups.is_empty() { + let count = dups.iter().map(|x| &x.name).collect::>().len(); dups.sort_unstable_by(|a, b| a.name.cmp(&b.name)); - panic!("found duplicate symbols: {dups:#?}"); + panic!("found {count} duplicate symbols: {dups:#?}"); } println!(" success: no duplicate symbols found"); @@ -293,7 +282,10 @@ fn verify_core_symbols(archive: &BinFile) { if !undefined.is_empty() { undefined.sort_unstable_by(|a, b| a.name.cmp(&b.name)); - panic!("found undefined symbols from core: {undefined:#?}"); + panic!( + "found {} undefined symbols from core: {undefined:#?}", + undefined.len() + ); } println!(" success: no undefined references to core found"); diff --git a/library/compiler-builtins/crates/symbol-check/tests/all.rs b/library/compiler-builtins/crates/symbol-check/tests/all.rs new file mode 100644 index 000000000000..4ad9509726fb --- /dev/null +++ b/library/compiler-builtins/crates/symbol-check/tests/all.rs @@ -0,0 +1,124 @@ +use std::env; +use std::ffi::OsString; +use std::path::{Path, PathBuf}; +use std::process::{Command, Stdio}; +use std::sync::LazyLock; + +use assert_cmd::assert::Assert; +use assert_cmd::cargo::cargo_bin_cmd; +use tempfile::tempdir; + +trait AssertExt { + fn stderr_contains(self, s: &str) -> Self; +} + +impl AssertExt for Assert { + fn stderr_contains(self, s: &str) -> Self { + let out = String::from_utf8_lossy(&self.get_output().stderr); + assert!(out.contains(s), "looking for: `{s}`\nout:\n```\n{out}\n```"); + self + } +} + +#[test] +fn test_duplicates() { + let dir = tempdir().unwrap(); + let dup_out = dir.path().join("dup.o"); + let lib_out = dir.path().join("libfoo.rlib"); + + // For the "bad" file, we need duplicate symbols from different object files in the archive. Do + // this reliably by building an archive and a separate object file then merging them. + rustc_build(&input_dir().join("duplicates.rs"), &lib_out, |cmd| cmd); + rustc_build(&input_dir().join("duplicates.rs"), &dup_out, |cmd| { + cmd.arg("--emit=obj") + }); + + let mut ar = cc_build().get_archiver(); + + if ar.get_program().to_string_lossy().contains("lib.exe") { + let mut out_arg = OsString::from("-out:"); + out_arg.push(&lib_out); + ar.arg(&out_arg); + // Repeating the same file as the first arg makes lib.exe append (taken from the + // `cc` implementation). + ar.arg(&lib_out); + } else { + ar.arg("rs") + // Eat an `libfoo.rlib(lib.rmeta) has no symbols` info message on MacOS + .stderr(Stdio::null()) + .arg(&lib_out); + } + let status = ar.arg(&dup_out).status().unwrap(); + assert!(status.success()); + + let assert = cargo_bin_cmd!().arg("check").arg(&lib_out).assert(); + assert + .failure() + .stderr_contains("duplicate symbols") + .stderr_contains("FDUP") + .stderr_contains("IDUP") + .stderr_contains("fndup"); +} + +#[test] +fn test_core_symbols() { + let dir = tempdir().unwrap(); + let lib_out = dir.path().join("libfoo.rlib"); + rustc_build(&input_dir().join("core_symbols.rs"), &lib_out, |cmd| cmd); + let assert = cargo_bin_cmd!().arg("check").arg(&lib_out).assert(); + // FIXME(symcheck): this should fail but we don't detect the new mangling. + assert.success(); +} + +#[test] +fn test_good() { + let dir = tempdir().unwrap(); + let lib_out = dir.path().join("libfoo.rlib"); + rustc_build(&input_dir().join("good.rs"), &lib_out, |cmd| cmd); + let assert = cargo_bin_cmd!().arg("check").arg(&lib_out).assert(); + assert.success(); +} + +/// Build i -> o with optional additional configuration. +fn rustc_build(i: &Path, o: &Path, mut f: impl FnMut(&mut Command) -> &mut Command) { + let mut cmd = Command::new("rustc"); + cmd.arg(i) + .arg("--target") + .arg(target()) + .arg("--crate-type=lib") + .arg("-o") + .arg(o); + f(&mut cmd); + let status = cmd.status().unwrap(); + assert!(status.success()); +} + +/// Configure `cc` with the host and target. +fn cc_build() -> cc::Build { + let mut b = cc::Build::new(); + b.host(env!("HOST")).target(&target()); + b +} + +/// Symcheck runs on the host but we want to verify that we find issues on all targets, so +/// the cross target may be specified. +fn target() -> String { + static TARGET: LazyLock = LazyLock::new(|| { + let target = match env::var("SYMCHECK_TEST_TARGET") { + Ok(t) => t, + // Require on CI so we don't accidentally always test the native target + _ if env::var("CI").is_ok() => panic!("SYMCHECK_TEST_TARGET must be set in CI"), + // Fall back to native for local convenience. + Err(_) => env!("HOST").to_string(), + }; + + println!("using target {target}"); + target + }); + + TARGET.clone() +} + +fn input_dir() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/input") +} diff --git a/library/compiler-builtins/crates/symbol-check/tests/input/core_symbols.rs b/library/compiler-builtins/crates/symbol-check/tests/input/core_symbols.rs new file mode 100644 index 000000000000..cf74f9779661 --- /dev/null +++ b/library/compiler-builtins/crates/symbol-check/tests/input/core_symbols.rs @@ -0,0 +1,11 @@ +//! Ensure we catch calls to `core`. + +#![no_std] + +#[unsafe(no_mangle)] +pub fn call_from_core(s: &[u8]) -> &str { + match core::str::from_utf8(&s) { + Ok(s) => s, + Err(_) => "", + } +} diff --git a/library/compiler-builtins/crates/symbol-check/tests/input/duplicates.rs b/library/compiler-builtins/crates/symbol-check/tests/input/duplicates.rs new file mode 100644 index 000000000000..92623a0b2e1a --- /dev/null +++ b/library/compiler-builtins/crates/symbol-check/tests/input/duplicates.rs @@ -0,0 +1,12 @@ +//! Ensure we catch duplicate symbols (the duplicates are in the aux file). Gets built twice +//! as separate object files. + +#![no_std] + +#[unsafe(no_mangle)] +static IDUP: i32 = 0; +#[unsafe(no_mangle)] +static FDUP: f32 = 0.0; + +#[unsafe(no_mangle)] +pub fn fndup() {} diff --git a/library/compiler-builtins/crates/symbol-check/tests/input/good.rs b/library/compiler-builtins/crates/symbol-check/tests/input/good.rs new file mode 100644 index 000000000000..6679ee1dd30c --- /dev/null +++ b/library/compiler-builtins/crates/symbol-check/tests/input/good.rs @@ -0,0 +1,4 @@ +#![no_std] + +#[unsafe(no_mangle)] +pub fn good() {} From 0de74158757dcb2db583c27b412f14391ae9ce0c Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 7 Feb 2026 19:44:34 +0900 Subject: [PATCH 3348/3801] borrowck: suggest `&mut *x` for pattern reborrows --- .../src/diagnostics/mutability_errors.rs | 73 +++++++++++++++++-- tests/ui/borrowck/mut-borrow-of-mut-ref.fixed | 37 ++++++++++ tests/ui/borrowck/mut-borrow-of-mut-ref.rs | 3 +- .../ui/borrowck/mut-borrow-of-mut-ref.stderr | 16 +--- .../reborrow-in-match-suggest-deref.fixed | 23 ++++++ .../reborrow-in-match-suggest-deref.rs | 23 ++++++ .../reborrow-in-match-suggest-deref.stderr | 23 ++++++ 7 files changed, 175 insertions(+), 23 deletions(-) create mode 100644 tests/ui/borrowck/mut-borrow-of-mut-ref.fixed create mode 100644 tests/ui/borrowck/reborrow-in-match-suggest-deref.fixed create mode 100644 tests/ui/borrowck/reborrow-in-match-suggest-deref.rs create mode 100644 tests/ui/borrowck/reborrow-in-match-suggest-deref.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 4fb739403ced..07d2313cc7fd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -354,14 +354,71 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.infcx.tcx.sess.source_map().span_to_snippet(source_info.span) { if snippet.starts_with("&mut ") { - // We don't have access to the HIR to get accurate spans, but we can - // give a best effort structured suggestion. - err.span_suggestion_verbose( - source_info.span.with_hi(source_info.span.lo() + BytePos(5)), - "if there is only one mutable reborrow, remove the `&mut`", - "", - Applicability::MaybeIncorrect, - ); + // In calls, `&mut &mut T` may be deref-coerced to `&mut T`, and + // removing the extra `&mut` is the most direct suggestion. But for + // pattern-matching expressions (`match`, `if let`, `while let`), that + // can easily turn into a move, so prefer suggesting an explicit + // reborrow via `&mut *x` instead. + let mut in_pat_scrutinee = false; + let mut is_deref_coerced = false; + if let Some(expr) = self.find_expr(source_info.span) { + let tcx = self.infcx.tcx; + let span = expr.span.source_callsite(); + for (_, node) in tcx.hir_parent_iter(expr.hir_id) { + if let Node::Expr(parent_expr) = node { + match parent_expr.kind { + ExprKind::Match(scrutinee, ..) + if scrutinee + .span + .source_callsite() + .contains(span) => + { + in_pat_scrutinee = true; + break; + } + ExprKind::Let(let_expr) + if let_expr + .init + .span + .source_callsite() + .contains(span) => + { + in_pat_scrutinee = true; + break; + } + _ => {} + } + } + } + + let typeck = tcx.typeck(expr.hir_id.owner.def_id); + is_deref_coerced = + typeck.expr_adjustments(expr).iter().any(|adj| { + matches!(adj.kind, ty::adjustment::Adjust::Deref(_)) + }); + } + + if in_pat_scrutinee { + // Best-effort structured suggestion: insert `*` after `&mut `. + err.span_suggestion_verbose( + source_info + .span + .with_lo(source_info.span.lo() + BytePos(5)) + .shrink_to_lo(), + "to reborrow the mutable reference, add `*`", + "*", + Applicability::MaybeIncorrect, + ); + } else if is_deref_coerced { + // We don't have access to the HIR to get accurate spans, but we + // can give a best effort structured suggestion. + err.span_suggestion_verbose( + source_info.span.with_hi(source_info.span.lo() + BytePos(5)), + "if there is only one mutable reborrow, remove the `&mut`", + "", + Applicability::MaybeIncorrect, + ); + } } else { // This can occur with things like `(&mut self).foo()`. err.span_help(source_info.span, "try removing `&mut` here"); diff --git a/tests/ui/borrowck/mut-borrow-of-mut-ref.fixed b/tests/ui/borrowck/mut-borrow-of-mut-ref.fixed new file mode 100644 index 000000000000..f70983c65223 --- /dev/null +++ b/tests/ui/borrowck/mut-borrow-of-mut-ref.fixed @@ -0,0 +1,37 @@ +// Suggest not mutably borrowing a mutable reference +//@ run-rustfix +#![crate_type = "rlib"] + +pub fn f(mut b: &mut i32) { + //~^ ERROR: cannot borrow + //~| NOTE: not mutable + //~| NOTE: the binding is already a mutable borrow + //~| HELP: consider making the binding mutable if you need to reborrow multiple times + h(b); + //~^ NOTE: cannot borrow as mutable + //~| HELP: if there is only one mutable reborrow, remove the `&mut` + g(&mut &mut b); + //~^ NOTE: cannot borrow as mutable +} + +pub fn g(mut b: &mut i32) { //~ NOTE: the binding is already a mutable borrow + //~^ HELP: consider making the binding mutable if you need to reborrow multiple times + h(&mut &mut b); + //~^ ERROR: cannot borrow + //~| NOTE: cannot borrow as mutable +} + +pub fn h(_: &mut i32) {} + +trait Foo { + fn bar(&mut self); +} + +impl Foo for &mut String { + fn bar(&mut self) {} +} + +pub fn baz(mut f: &mut String) { //~ HELP consider making the binding mutable + f.bar(); //~ ERROR cannot borrow `f` as mutable, as it is not declared as mutable + //~^ NOTE cannot borrow as mutable +} diff --git a/tests/ui/borrowck/mut-borrow-of-mut-ref.rs b/tests/ui/borrowck/mut-borrow-of-mut-ref.rs index 33954592bf65..d150b249bf2d 100644 --- a/tests/ui/borrowck/mut-borrow-of-mut-ref.rs +++ b/tests/ui/borrowck/mut-borrow-of-mut-ref.rs @@ -1,4 +1,5 @@ // Suggest not mutably borrowing a mutable reference +//@ run-rustfix #![crate_type = "rlib"] pub fn f(b: &mut i32) { @@ -11,7 +12,6 @@ pub fn f(b: &mut i32) { //~| HELP: if there is only one mutable reborrow, remove the `&mut` g(&mut &mut b); //~^ NOTE: cannot borrow as mutable - //~| HELP: if there is only one mutable reborrow, remove the `&mut` } pub fn g(b: &mut i32) { //~ NOTE: the binding is already a mutable borrow @@ -19,7 +19,6 @@ pub fn g(b: &mut i32) { //~ NOTE: the binding is already a mutable borrow h(&mut &mut b); //~^ ERROR: cannot borrow //~| NOTE: cannot borrow as mutable - //~| HELP: if there is only one mutable reborrow, remove the `&mut` } pub fn h(_: &mut i32) {} diff --git a/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr b/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr index 4c4a5e718393..01ceba90c943 100644 --- a/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr +++ b/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable - --> $DIR/mut-borrow-of-mut-ref.rs:4:10 + --> $DIR/mut-borrow-of-mut-ref.rs:5:10 | LL | pub fn f(b: &mut i32) { | ^ not mutable @@ -11,7 +11,7 @@ LL | g(&mut &mut b); | ------ cannot borrow as mutable | note: the binding is already a mutable borrow - --> $DIR/mut-borrow-of-mut-ref.rs:4:13 + --> $DIR/mut-borrow-of-mut-ref.rs:5:13 | LL | pub fn f(b: &mut i32) { | ^^^^^^^^ @@ -24,11 +24,6 @@ help: if there is only one mutable reborrow, remove the `&mut` LL - h(&mut b); LL + h(b); | -help: if there is only one mutable reborrow, remove the `&mut` - | -LL - g(&mut &mut b); -LL + g(&mut b); - | error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable --> $DIR/mut-borrow-of-mut-ref.rs:19:12 @@ -45,14 +40,9 @@ help: consider making the binding mutable if you need to reborrow multiple times | LL | pub fn g(mut b: &mut i32) { | +++ -help: if there is only one mutable reborrow, remove the `&mut` - | -LL - h(&mut &mut b); -LL + h(&mut b); - | error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable - --> $DIR/mut-borrow-of-mut-ref.rs:36:5 + --> $DIR/mut-borrow-of-mut-ref.rs:35:5 | LL | f.bar(); | ^ cannot borrow as mutable diff --git a/tests/ui/borrowck/reborrow-in-match-suggest-deref.fixed b/tests/ui/borrowck/reborrow-in-match-suggest-deref.fixed new file mode 100644 index 000000000000..3f52e57a804c --- /dev/null +++ b/tests/ui/borrowck/reborrow-in-match-suggest-deref.fixed @@ -0,0 +1,23 @@ +// Regression test for #81059. +// edition:2024 +//@ run-rustfix + +#![allow(unused)] + +fn test(mut outer: &mut Option) { + //~^ NOTE: the binding is already a mutable borrow + //~| HELP: consider making the binding mutable if you need to reborrow multiple times + match (&mut *outer, 23) { + //~^ ERROR: cannot borrow `outer` as mutable, as it is not declared as mutable + //~| NOTE: cannot borrow as mutable + //~| HELP: to reborrow the mutable reference, add `*` + (Some(inner), _) => { + *inner = 17; + } + _ => { + *outer = Some(2); + } + } +} + +fn main() {} diff --git a/tests/ui/borrowck/reborrow-in-match-suggest-deref.rs b/tests/ui/borrowck/reborrow-in-match-suggest-deref.rs new file mode 100644 index 000000000000..34c299f4f7b1 --- /dev/null +++ b/tests/ui/borrowck/reborrow-in-match-suggest-deref.rs @@ -0,0 +1,23 @@ +// Regression test for #81059. +// edition:2024 +//@ run-rustfix + +#![allow(unused)] + +fn test(outer: &mut Option) { + //~^ NOTE: the binding is already a mutable borrow + //~| HELP: consider making the binding mutable if you need to reborrow multiple times + match (&mut outer, 23) { + //~^ ERROR: cannot borrow `outer` as mutable, as it is not declared as mutable + //~| NOTE: cannot borrow as mutable + //~| HELP: to reborrow the mutable reference, add `*` + (Some(inner), _) => { + *inner = 17; + } + _ => { + *outer = Some(2); + } + } +} + +fn main() {} diff --git a/tests/ui/borrowck/reborrow-in-match-suggest-deref.stderr b/tests/ui/borrowck/reborrow-in-match-suggest-deref.stderr new file mode 100644 index 000000000000..db3129461518 --- /dev/null +++ b/tests/ui/borrowck/reborrow-in-match-suggest-deref.stderr @@ -0,0 +1,23 @@ +error[E0596]: cannot borrow `outer` as mutable, as it is not declared as mutable + --> $DIR/reborrow-in-match-suggest-deref.rs:10:12 + | +LL | match (&mut outer, 23) { + | ^^^^^^^^^^ cannot borrow as mutable + | +note: the binding is already a mutable borrow + --> $DIR/reborrow-in-match-suggest-deref.rs:7:16 + | +LL | fn test(outer: &mut Option) { + | ^^^^^^^^^^^^^^^^ +help: consider making the binding mutable if you need to reborrow multiple times + | +LL | fn test(mut outer: &mut Option) { + | +++ +help: to reborrow the mutable reference, add `*` + | +LL | match (&mut *outer, 23) { + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`. From 3ee0286396e9cfacd3c0cb1ce7417b6a7a8e6308 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 18 Jan 2026 13:35:42 +0100 Subject: [PATCH 3349/3801] internal: Remove `Edition::CURRENT_FIXME` --- src/tools/rust-analyzer/Cargo.toml | 2 - .../bench_data/glorious_old_parser | 18 +------ .../rust-analyzer/crates/edition/src/lib.rs | 2 - .../crates/hir/src/term_search/tactics.rs | 19 +++++-- .../ide-assists/src/handlers/auto_import.rs | 1 + .../crates/ide-db/src/imports/insert_use.rs | 9 +++- .../ide-db/src/syntax_helpers/suggest_name.rs | 50 +++++++++++-------- .../rust-analyzer/crates/ide/src/typing.rs | 18 ++++--- .../crates/project-model/src/sysroot.rs | 6 ++- .../crates/project-model/src/workspace.rs | 2 +- 10 files changed, 70 insertions(+), 57 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 2288933a96cc..9f31e1903af5 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -192,8 +192,6 @@ unused_lifetimes = "warn" unreachable_pub = "warn" [workspace.lints.clippy] -# FIXME Remove the tidy test once the lint table is stable - ## lint groups complexity = { level = "warn", priority = -1 } correctness = { level = "deny", priority = -1 } diff --git a/src/tools/rust-analyzer/bench_data/glorious_old_parser b/src/tools/rust-analyzer/bench_data/glorious_old_parser index f593f2b2955a..8136daa8329f 100644 --- a/src/tools/rust-analyzer/bench_data/glorious_old_parser +++ b/src/tools/rust-analyzer/bench_data/glorious_old_parser @@ -724,7 +724,7 @@ impl<'a> Parser<'a> { // {foo(bar {}} // - ^ // | | - // | help: `)` may belong here (FIXME: #58270) + // | help: `)` may belong here // | // unclosed delimiter if let Some(sp) = unmatched.unclosed_span { @@ -3217,7 +3217,6 @@ impl<'a> Parser<'a> { } _ => { - // FIXME Could factor this out into non_fatal_unexpected or something. let actual = self.this_token_to_string(); self.span_err(self.span, &format!("unexpected token: `{}`", actual)); } @@ -5250,7 +5249,6 @@ impl<'a> Parser<'a> { } } } else { - // FIXME: Bad copy of attrs let old_directory_ownership = mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock); let item = self.parse_item_(attrs.clone(), false, true)?; @@ -5953,23 +5951,14 @@ impl<'a> Parser<'a> { }); assoc_ty_bindings.push(span); } else if self.check_const_arg() { - // FIXME(const_generics): to distinguish between idents for types and consts, - // we should introduce a GenericArg::Ident in the AST and distinguish when - // lowering to the HIR. For now, idents for const args are not permitted. - // Parse const argument. let expr = if let token::OpenDelim(token::Brace) = self.token { self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())? } else if self.token.is_ident() { - // FIXME(const_generics): to distinguish between idents for types and consts, - // we should introduce a GenericArg::Ident in the AST and distinguish when - // lowering to the HIR. For now, idents for const args are not permitted. return Err( self.fatal("identifiers may currently not be used for const generics") ); } else { - // FIXME(const_generics): this currently conflicts with emplacement syntax - // with negative integer literals. self.parse_literal_maybe_minus()? }; let value = AnonConst { @@ -5991,9 +5980,6 @@ impl<'a> Parser<'a> { } } - // FIXME: we would like to report this in ast_validation instead, but we currently do not - // preserve ordering of generic parameters with respect to associated type binding, so we - // lose that information after parsing. if misplaced_assoc_ty_bindings.len() > 0 { let mut err = self.struct_span_err( args_lo.to(self.prev_span), @@ -6079,8 +6065,6 @@ impl<'a> Parser<'a> { bounds, } )); - // FIXME: Decide what should be used here, `=` or `==`. - // FIXME: We are just dropping the binders in lifetime_defs on the floor here. } else if self.eat(&token::Eq) || self.eat(&token::EqEq) { let rhs_ty = self.parse_ty()?; where_clause.predicates.push(ast::WherePredicate::EqPredicate( diff --git a/src/tools/rust-analyzer/crates/edition/src/lib.rs b/src/tools/rust-analyzer/crates/edition/src/lib.rs index f1a1fe596493..eb4cec39dce0 100644 --- a/src/tools/rust-analyzer/crates/edition/src/lib.rs +++ b/src/tools/rust-analyzer/crates/edition/src/lib.rs @@ -16,8 +16,6 @@ impl Edition { pub const DEFAULT: Edition = Edition::Edition2015; pub const LATEST: Edition = Edition::Edition2024; pub const CURRENT: Edition = Edition::Edition2024; - /// The current latest stable edition, note this is usually not the right choice in code. - pub const CURRENT_FIXME: Edition = Edition::Edition2024; pub fn from_u32(u32: u32) -> Edition { match u32 { diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs index 05a89e76529b..8622aa1378b3 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs @@ -18,7 +18,6 @@ use hir_ty::{ use itertools::Itertools; use rustc_hash::FxHashSet; use rustc_type_ir::inherent::Ty as _; -use span::Edition; use crate::{ Adt, AssocItem, GenericDef, GenericParam, HasAttrs, HasVisibility, Impl, ModuleDef, ScopeDef, @@ -367,7 +366,11 @@ pub(super) fn free_function<'a, 'lt, 'db, DB: HirDatabase>( let ret_ty = it.ret_type_with_args(db, generics.iter().cloned()); // Filter out private and unsafe functions if !it.is_visible_from(db, module) - || it.is_unsafe_to_call(db, None, Edition::CURRENT_FIXME) + || it.is_unsafe_to_call( + db, + None, + crate::Crate::from(ctx.scope.resolver().krate()).edition(db), + ) || it.is_unstable(db) || ctx.config.enable_borrowcheck && ret_ty.contains_reference(db) || ret_ty.is_raw_ptr() @@ -473,7 +476,11 @@ pub(super) fn impl_method<'a, 'lt, 'db, DB: HirDatabase>( // Filter out private and unsafe functions if !it.is_visible_from(db, module) - || it.is_unsafe_to_call(db, None, Edition::CURRENT_FIXME) + || it.is_unsafe_to_call( + db, + None, + crate::Crate::from(ctx.scope.resolver().krate()).edition(db), + ) || it.is_unstable(db) { return None; @@ -667,7 +674,11 @@ pub(super) fn impl_static_method<'a, 'lt, 'db, DB: HirDatabase>( // Filter out private and unsafe functions if !it.is_visible_from(db, module) - || it.is_unsafe_to_call(db, None, Edition::CURRENT_FIXME) + || it.is_unsafe_to_call( + db, + None, + crate::Crate::from(ctx.scope.resolver().krate()).edition(db), + ) || it.is_unstable(db) { return None; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs index cc2bf8174941..2694910aa609 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs @@ -155,6 +155,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< &scope, mod_path_to_ast(&import_path, edition), &ctx.config.insert_use, + edition, ); }, ); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs index 4444ef5d81d5..db1d599d550d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs @@ -146,9 +146,14 @@ pub fn insert_use(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) { insert_use_with_alias_option(scope, path, cfg, None); } -pub fn insert_use_as_alias(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) { +pub fn insert_use_as_alias( + scope: &ImportScope, + path: ast::Path, + cfg: &InsertUseConfig, + edition: span::Edition, +) { let text: &str = "use foo as _"; - let parse = syntax::SourceFile::parse(text, span::Edition::CURRENT_FIXME); + let parse = syntax::SourceFile::parse(text, edition); let node = parse .tree() .syntax() diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs index b8b9a7a76816..5d1e876ea298 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs @@ -206,17 +206,18 @@ impl NameGenerator { expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>, ) -> Option { + let edition = sema.scope(expr.syntax())?.krate().edition(sema.db); // `from_param` does not benefit from stripping it need the largest // context possible so we check firstmost - if let Some(name) = from_param(expr, sema) { + if let Some(name) = from_param(expr, sema, edition) { return Some(self.suggest_name(&name)); } let mut next_expr = Some(expr.clone()); while let Some(expr) = next_expr { - let name = from_call(&expr) - .or_else(|| from_type(&expr, sema)) - .or_else(|| from_field_name(&expr)); + let name = from_call(&expr, edition) + .or_else(|| from_type(&expr, sema, edition)) + .or_else(|| from_field_name(&expr, edition)); if let Some(name) = name { return Some(self.suggest_name(&name)); } @@ -270,7 +271,7 @@ impl NameGenerator { } } -fn normalize(name: &str) -> Option { +fn normalize(name: &str, edition: syntax::Edition) -> Option { let name = to_lower_snake_case(name).to_smolstr(); if USELESS_NAMES.contains(&name.as_str()) { @@ -281,16 +282,16 @@ fn normalize(name: &str) -> Option { return None; } - if !is_valid_name(&name) { + if !is_valid_name(&name, edition) { return None; } Some(name) } -fn is_valid_name(name: &str) -> bool { +fn is_valid_name(name: &str, edition: syntax::Edition) -> bool { matches!( - super::LexedStr::single_token(syntax::Edition::CURRENT_FIXME, name), + super::LexedStr::single_token(edition, name), Some((syntax::SyntaxKind::IDENT, _error)) ) } @@ -304,11 +305,11 @@ fn is_useless_method(method: &ast::MethodCallExpr) -> bool { } } -fn from_call(expr: &ast::Expr) -> Option { - from_func_call(expr).or_else(|| from_method_call(expr)) +fn from_call(expr: &ast::Expr, edition: syntax::Edition) -> Option { + from_func_call(expr, edition).or_else(|| from_method_call(expr, edition)) } -fn from_func_call(expr: &ast::Expr) -> Option { +fn from_func_call(expr: &ast::Expr, edition: syntax::Edition) -> Option { let call = match expr { ast::Expr::CallExpr(call) => call, _ => return None, @@ -318,10 +319,10 @@ fn from_func_call(expr: &ast::Expr) -> Option { _ => return None, }; let ident = func.path()?.segment()?.name_ref()?.ident_token()?; - normalize(ident.text()) + normalize(ident.text(), edition) } -fn from_method_call(expr: &ast::Expr) -> Option { +fn from_method_call(expr: &ast::Expr, edition: syntax::Edition) -> Option { let method = match expr { ast::Expr::MethodCallExpr(call) => call, _ => return None, @@ -340,10 +341,14 @@ fn from_method_call(expr: &ast::Expr) -> Option { } } - normalize(name) + normalize(name, edition) } -fn from_param(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option { +fn from_param( + expr: &ast::Expr, + sema: &Semantics<'_, RootDatabase>, + edition: Edition, +) -> Option { let arg_list = expr.syntax().parent().and_then(ast::ArgList::cast)?; let args_parent = arg_list.syntax().parent()?; let func = match_ast! { @@ -362,7 +367,7 @@ fn from_param(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option Option { @@ -374,10 +379,13 @@ fn var_name_from_pat(pat: &ast::Pat) -> Option { } } -fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option { +fn from_type( + expr: &ast::Expr, + sema: &Semantics<'_, RootDatabase>, + edition: Edition, +) -> Option { let ty = sema.type_of_expr(expr)?.adjusted(); let ty = ty.remove_ref().unwrap_or(ty); - let edition = sema.scope(expr.syntax())?.krate().edition(sema.db); name_of_type(&ty, sema.db, edition) } @@ -417,7 +425,7 @@ fn name_of_type<'db>( } else { return None; }; - normalize(&name) + normalize(&name, edition) } fn sequence_name<'db>( @@ -450,13 +458,13 @@ fn trait_name(trait_: &hir::Trait, db: &RootDatabase, edition: Edition) -> Optio Some(name) } -fn from_field_name(expr: &ast::Expr) -> Option { +fn from_field_name(expr: &ast::Expr, edition: syntax::Edition) -> Option { let field = match expr { ast::Expr::FieldExpr(field) => field, _ => return None, }; let ident = field.name_ref()?.ident_token()?; - normalize(ident.text()) + normalize(ident.text(), edition) } #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/ide/src/typing.rs b/src/tools/rust-analyzer/crates/ide/src/typing.rs index 0381865fed45..f8b0dbfe6282 100644 --- a/src/tools/rust-analyzer/crates/ide/src/typing.rs +++ b/src/tools/rust-analyzer/crates/ide/src/typing.rs @@ -17,7 +17,10 @@ mod on_enter; use either::Either; use hir::EditionedFileId; -use ide_db::{FilePosition, RootDatabase, base_db::RootQueryDb}; +use ide_db::{ + FilePosition, RootDatabase, + base_db::{RootQueryDb, SourceDatabase}, +}; use span::Edition; use std::iter; @@ -70,11 +73,12 @@ pub(crate) fn on_char_typed( if !TRIGGER_CHARS.contains(&char_typed) { return None; } - // FIXME: We need to figure out the edition of the file here, but that means hitting the - // database for more than just parsing the file which is bad. + let edition = db + .source_root_crates(db.file_source_root(position.file_id).source_root_id(db)) + .first() + .map_or(Edition::CURRENT, |crates| crates.data(db).edition); // FIXME: We are hitting the database here, if we are unlucky this call might block momentarily - // causing the editor to feel sluggish! - let edition = Edition::CURRENT_FIXME; + // causing the editor to feel sluggish! We need to make this bail if it would block too long? let editioned_file_id_wrapper = EditionedFileId::from_span_guess_origin( db, span::EditionedFileId::new(position.file_id, edition), @@ -457,8 +461,8 @@ mod tests { let (offset, mut before) = extract_offset(before); let edit = TextEdit::insert(offset, char_typed.to_string()); edit.apply(&mut before); - let parse = SourceFile::parse(&before, span::Edition::CURRENT_FIXME); - on_char_typed_(&parse, offset, char_typed, span::Edition::CURRENT_FIXME).map(|it| { + let parse = SourceFile::parse(&before, span::Edition::CURRENT); + on_char_typed_(&parse, offset, char_typed, span::Edition::CURRENT).map(|it| { it.apply(&mut before); before.to_string() }) diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs index f244c9736c7c..546a1e05a063 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs @@ -275,7 +275,10 @@ impl Sysroot { } tracing::debug!("Stitching sysroot library: {src_root}"); - let mut stitched = stitched::Stitched { crates: Default::default() }; + let mut stitched = stitched::Stitched { + crates: Default::default(), + edition: span::Edition::Edition2024, + }; for path in stitched::SYSROOT_CRATES.trim().lines() { let name = path.split('/').next_back().unwrap(); @@ -511,6 +514,7 @@ pub(crate) mod stitched { #[derive(Debug, Clone, Eq, PartialEq)] pub struct Stitched { pub(super) crates: Arena, + pub(crate) edition: span::Edition, } impl ops::Index for Stitched { diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 8f15f7e1507c..581b5fa51446 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -1831,7 +1831,7 @@ fn sysroot_to_crate_graph( let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name); let crate_id = crate_graph.add_crate_root( file_id, - Edition::CURRENT_FIXME, + stitched.edition, Some(display_name), None, cfg_options.clone(), From 5768fb7d93414e830c6ca0fbf0f4f8502d2de4f4 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 7 Feb 2026 05:49:02 -0600 Subject: [PATCH 3350/3801] symcheck: Check for core symbols with the new mangling The recent switch in default mangling meant that the check was no longer working correctly. Resolve this by checking for both legacy- and v0-mangled core symbols to the extent that this is possible. --- .../compiler-builtins/crates/symbol-check/Cargo.toml | 1 + .../crates/symbol-check/src/main.rs | 12 +++++++++++- .../crates/symbol-check/tests/all.rs | 6 ++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/library/compiler-builtins/crates/symbol-check/Cargo.toml b/library/compiler-builtins/crates/symbol-check/Cargo.toml index 774d1c31a4b0..6291a0ca7f45 100644 --- a/library/compiler-builtins/crates/symbol-check/Cargo.toml +++ b/library/compiler-builtins/crates/symbol-check/Cargo.toml @@ -6,6 +6,7 @@ publish = false [dependencies] object = { version = "0.37.3", features = ["wasm"] } +regex = "1.12.3" serde_json = "1.0.149" [dev-dependencies] diff --git a/library/compiler-builtins/crates/symbol-check/src/main.rs b/library/compiler-builtins/crates/symbol-check/src/main.rs index 1413042e6c70..733d9f4e8bef 100644 --- a/library/compiler-builtins/crates/symbol-check/src/main.rs +++ b/library/compiler-builtins/crates/symbol-check/src/main.rs @@ -9,12 +9,14 @@ use std::fs; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; +use std::sync::LazyLock; use object::read::archive::ArchiveFile; use object::{ File as ObjFile, Object, ObjectSection, ObjectSymbol, Result as ObjResult, Symbol, SymbolKind, SymbolScope, }; +use regex::Regex; use serde_json::Value; const CHECK_LIBRARIES: &[&str] = &["compiler_builtins", "builtins_test_intrinsics"]; @@ -255,6 +257,14 @@ fn verify_no_duplicates(archive: &BinFile) { /// Ensure that there are no references to symbols from `core` that aren't also (somehow) defined. fn verify_core_symbols(archive: &BinFile) { + // Match both mangling styles: + // + // * `_ZN4core3str8converts9from_utf817hd4454ac14cbbb790E` (old) + // * `_RNvNtNtCscK9O3IwVk7N_4core3str8converts9from_utf8` (v0) + // + // Also account for the Apple leading `_`. + static RE: LazyLock = LazyLock::new(|| Regex::new(r"^_?_[RZ].*4core").unwrap()); + let mut defined = BTreeSet::new(); let mut undefined = Vec::new(); let mut has_symbols = false; @@ -263,7 +273,7 @@ fn verify_core_symbols(archive: &BinFile) { has_symbols = true; // Find only symbols from `core` - if !symbol.name().unwrap().contains("_ZN4core") { + if !RE.is_match(symbol.name().unwrap()) { return; } diff --git a/library/compiler-builtins/crates/symbol-check/tests/all.rs b/library/compiler-builtins/crates/symbol-check/tests/all.rs index 4ad9509726fb..400469a49e2a 100644 --- a/library/compiler-builtins/crates/symbol-check/tests/all.rs +++ b/library/compiler-builtins/crates/symbol-check/tests/all.rs @@ -66,8 +66,10 @@ fn test_core_symbols() { let lib_out = dir.path().join("libfoo.rlib"); rustc_build(&input_dir().join("core_symbols.rs"), &lib_out, |cmd| cmd); let assert = cargo_bin_cmd!().arg("check").arg(&lib_out).assert(); - // FIXME(symcheck): this should fail but we don't detect the new mangling. - assert.success(); + assert + .failure() + .stderr_contains("found 1 undefined symbols from core") + .stderr_contains("from_utf8"); } #[test] From bad1a450c01c285b727e82b116c5baf226ed4f86 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 7 Feb 2026 13:33:25 +0100 Subject: [PATCH 3351/3801] use `test` instead of `unix` to be platform-independent --- tests/ui/macros/cfg_select.rs | 6 ++++-- tests/ui/macros/cfg_select.stderr | 32 ++++++++++++++++++------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index 09d2c116a86d..0f009756e211 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -151,8 +151,10 @@ cfg_select! { } cfg_select! { - unix => {} - unix => {} + test => {} + test => {} + //~^ WARN unreachable configuration predicate + _ => {} //~^ WARN unreachable configuration predicate } diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index be238e0a65e5..5878708668d3 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -1,5 +1,5 @@ error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:159:1 + --> $DIR/cfg_select.rs:161:1 | LL | / cfg_select! { LL | | @@ -8,49 +8,49 @@ LL | | } | |_^ error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:164:1 + --> $DIR/cfg_select.rs:166:1 | LL | cfg_select! {} | ^^^^^^^^^^^^^^ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `=>` - --> $DIR/cfg_select.rs:168:5 + --> $DIR/cfg_select.rs:170:5 | LL | => {} | ^^ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression - --> $DIR/cfg_select.rs:173:5 + --> $DIR/cfg_select.rs:175:5 | LL | () => {} | ^^ expressions are not allowed here error[E0539]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:178:5 + --> $DIR/cfg_select.rs:180:5 | LL | "str" => {} | ^^^^^ expected a valid identifier here error[E0539]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:183:5 + --> $DIR/cfg_select.rs:185:5 | LL | a::b => {} | ^^^^ expected a valid identifier here error[E0537]: invalid predicate `a` - --> $DIR/cfg_select.rs:188:5 + --> $DIR/cfg_select.rs:190:5 | LL | a() => {} | ^^^ error: expected one of `(`, `::`, `=>`, or `=`, found `+` - --> $DIR/cfg_select.rs:193:7 + --> $DIR/cfg_select.rs:195:7 | LL | a + 1 => {} | ^ expected one of `(`, `::`, `=>`, or `=` error: expected one of `(`, `::`, `=>`, or `=`, found `!` - --> $DIR/cfg_select.rs:199:8 + --> $DIR/cfg_select.rs:201:8 | LL | cfg!() => {} | ^ expected one of `(`, `::`, `=>`, or `=` @@ -86,11 +86,17 @@ LL | _ => {} warning: unreachable configuration predicate --> $DIR/cfg_select.rs:155:5 | -LL | unix => {} +LL | test => {} | ^^^^ this configuration predicate is never reached +warning: unreachable configuration predicate + --> $DIR/cfg_select.rs:157:5 + | +LL | _ => {} + | ^ this configuration predicate is never reached + warning: unexpected `cfg` condition name: `a` - --> $DIR/cfg_select.rs:193:5 + --> $DIR/cfg_select.rs:195:5 | LL | a + 1 => {} | ^ help: found config with similar value: `target_feature = "a"` @@ -101,7 +107,7 @@ LL | a + 1 => {} = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `cfg` - --> $DIR/cfg_select.rs:199:5 + --> $DIR/cfg_select.rs:201:5 | LL | cfg!() => {} | ^^^ @@ -109,7 +115,7 @@ LL | cfg!() => {} = help: to expect this configuration use `--check-cfg=cfg(cfg)` = note: see for more information about checking conditional configuration -error: aborting due to 9 previous errors; 6 warnings emitted +error: aborting due to 9 previous errors; 7 warnings emitted Some errors have detailed explanations: E0537, E0539. For more information about an error, try `rustc --explain E0537`. From 63eefa9ee992ea62c60d2bf5ba1bdb6fa6d086b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 12:33:55 +0000 Subject: [PATCH 3352/3801] Bump time from 0.3.44 to 0.3.47 Bumps [time](https://github.com/time-rs/time) from 0.3.44 to 0.3.47. - [Release notes](https://github.com/time-rs/time/releases) - [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md) - [Commits](https://github.com/time-rs/time/compare/v0.3.44...v0.3.47) --- updated-dependencies: - dependency-name: time dependency-version: 0.3.47 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- src/tools/rust-analyzer/Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 2cf3e37a43bc..11d41a17b165 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1614,9 +1614,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-traits" @@ -2914,9 +2914,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.44" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -2924,22 +2924,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", From fb5a4dca328798ec30fa001aed16f19ceb32e000 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 7 Feb 2026 23:16:12 +1100 Subject: [PATCH 3353/3801] Regression test for `let x = offset_of!(..) else { .. }` span --- tests/ui/span/let-offset-of.rs | 19 +++++++++++++++++++ tests/ui/span/let-offset-of.stderr | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/ui/span/let-offset-of.rs create mode 100644 tests/ui/span/let-offset-of.stderr diff --git a/tests/ui/span/let-offset-of.rs b/tests/ui/span/let-offset-of.rs new file mode 100644 index 000000000000..99b34a192847 --- /dev/null +++ b/tests/ui/span/let-offset-of.rs @@ -0,0 +1,19 @@ +#![crate_type = "rlib"] +//@ edition: 2024 +//@ check-pass + +// Using `offset_of` in the RHS of a let-else statement should not produce +// malformed spans or a blank diagnostic snippet. +// +// Regression test for . + +fn init_to_offset_of() { + use std::mem::offset_of; + struct Foo { field: u32 } + + if let x = offset_of!(Foo, field) {} + //~^ WARN irrefutable `if let` pattern + + let x = offset_of!(Foo, field) else { return; }; + //~^ WARN irrefutable `let...else` pattern +} diff --git a/tests/ui/span/let-offset-of.stderr b/tests/ui/span/let-offset-of.stderr new file mode 100644 index 000000000000..a0ef3fcc5ef5 --- /dev/null +++ b/tests/ui/span/let-offset-of.stderr @@ -0,0 +1,17 @@ +warning: irrefutable `if let` pattern + --> $DIR/let-offset-of.rs:14:8 + | +LL | if let x = offset_of!(Foo, field) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + = note: `#[warn(irrefutable_let_patterns)]` on by default + +warning: irrefutable `let...else` pattern + | + = note: this pattern will always match, so the `else` clause is useless + = help: consider removing the `else` clause + +warning: 2 warnings emitted + From cc3fdc637a6314f69bcc5be0a4c281f285a04bbc Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 7 Feb 2026 22:27:23 +1100 Subject: [PATCH 3354/3801] Avoid a bogus THIR span for `let x = offset_of!(..)` --- compiler/rustc_mir_build/src/thir/cx/block.rs | 9 +++++++-- tests/ui/span/let-offset-of.stderr | 4 ++++ tests/ui/thir-print/offset_of.stdout | 18 +++++++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index fad73a7115b0..b108dff5555f 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -75,8 +75,13 @@ impl<'tcx> ThirBuildCx<'tcx> { debug!(?pattern); let span = match local.init { - Some(init) => local.span.with_hi(init.span.hi()), - None => local.span, + Some(init) + if let Some(init_span) = + init.span.find_ancestor_inside_same_ctxt(local.span) => + { + local.span.with_hi(init_span.hi()) + } + Some(_) | None => local.span, }; let stmt = Stmt { kind: StmtKind::Let { diff --git a/tests/ui/span/let-offset-of.stderr b/tests/ui/span/let-offset-of.stderr index a0ef3fcc5ef5..6ea9b2194a36 100644 --- a/tests/ui/span/let-offset-of.stderr +++ b/tests/ui/span/let-offset-of.stderr @@ -9,6 +9,10 @@ LL | if let x = offset_of!(Foo, field) {} = note: `#[warn(irrefutable_let_patterns)]` on by default warning: irrefutable `let...else` pattern + --> $DIR/let-offset-of.rs:17:5 + | +LL | let x = offset_of!(Foo, field) else { return; }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this pattern will always match, so the `else` clause is useless = help: consider removing the `else` clause diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index 5666a5972f37..25c099438754 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -68,7 +68,7 @@ body: ) else_block: None hir_id: HirId(DefId(offset_of::concrete).10) - span: $DIR/offset_of.rs:37:5: 1445:57 (#0) + span: $DIR/offset_of.rs:37:5: 37:33 (#0) } } Stmt { @@ -117,7 +117,7 @@ body: ) else_block: None hir_id: HirId(DefId(offset_of::concrete).20) - span: $DIR/offset_of.rs:38:5: 1445:57 (#0) + span: $DIR/offset_of.rs:38:5: 38:33 (#0) } } Stmt { @@ -166,7 +166,7 @@ body: ) else_block: None hir_id: HirId(DefId(offset_of::concrete).30) - span: $DIR/offset_of.rs:39:5: 1445:57 (#0) + span: $DIR/offset_of.rs:39:5: 39:34 (#0) } } Stmt { @@ -215,7 +215,7 @@ body: ) else_block: None hir_id: HirId(DefId(offset_of::concrete).40) - span: $DIR/offset_of.rs:40:5: 1445:57 (#0) + span: $DIR/offset_of.rs:40:5: 40:36 (#0) } } Stmt { @@ -264,7 +264,7 @@ body: ) else_block: None hir_id: HirId(DefId(offset_of::concrete).50) - span: $DIR/offset_of.rs:41:5: 1445:57 (#0) + span: $DIR/offset_of.rs:41:5: 41:36 (#0) } } ] @@ -864,7 +864,7 @@ body: ) else_block: None hir_id: HirId(DefId(offset_of::generic).12) - span: $DIR/offset_of.rs:45:5: 1445:57 (#0) + span: $DIR/offset_of.rs:45:5: 45:37 (#0) } } Stmt { @@ -913,7 +913,7 @@ body: ) else_block: None hir_id: HirId(DefId(offset_of::generic).24) - span: $DIR/offset_of.rs:46:5: 1445:57 (#0) + span: $DIR/offset_of.rs:46:5: 46:37 (#0) } } Stmt { @@ -962,7 +962,7 @@ body: ) else_block: None hir_id: HirId(DefId(offset_of::generic).36) - span: $DIR/offset_of.rs:47:5: 1445:57 (#0) + span: $DIR/offset_of.rs:47:5: 47:37 (#0) } } Stmt { @@ -1011,7 +1011,7 @@ body: ) else_block: None hir_id: HirId(DefId(offset_of::generic).48) - span: $DIR/offset_of.rs:48:5: 1445:57 (#0) + span: $DIR/offset_of.rs:48:5: 48:37 (#0) } } ] From 729f384e486a424555c4ebc186b879146b074fcb Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 7 Feb 2026 13:55:11 +0100 Subject: [PATCH 3355/3801] Bump salsa --- src/tools/rust-analyzer/Cargo.lock | 12 ++--- src/tools/rust-analyzer/Cargo.toml | 4 +- .../crates/base-db/src/editioned_file_id.rs | 2 +- .../crates/hir-ty/src/tests/regression.rs | 1 + .../rust-analyzer/crates/span/src/hygiene.rs | 51 +++++++++---------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 2cf3e37a43bc..9c98e0502070 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2453,9 +2453,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa" -version = "0.25.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e2aa2fca57727371eeafc975acc8e6f4c52f8166a78035543f6ee1c74c2dcc" +checksum = "f77debccd43ba198e9cee23efd7f10330ff445e46a98a2b107fed9094a1ee676" dependencies = [ "boxcar", "crossbeam-queue", @@ -2478,15 +2478,15 @@ dependencies = [ [[package]] name = "salsa-macro-rules" -version = "0.25.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfc2a1e7bf06964105515451d728f2422dedc3a112383324a00b191a5c397a3" +checksum = "ea07adbf42d91cc076b7daf3b38bc8168c19eb362c665964118a89bc55ef19a5" [[package]] name = "salsa-macros" -version = "0.25.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d844c1aa34946da46af683b5c27ec1088a3d9d84a2b837a108223fd830220e1" +checksum = "d16d4d8b66451b9c75ddf740b7fc8399bc7b8ba33e854a5d7526d18708f67b05" dependencies = [ "proc-macro2", "quote", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 2288933a96cc..694f616d1b0b 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -135,13 +135,13 @@ rayon = "1.10.0" rowan = "=0.15.17" # Ideally we'd not enable the macros feature but unfortunately the `tracked` attribute does not work # on impls without it -salsa = { version = "0.25.2", default-features = false, features = [ +salsa = { version = "0.26", default-features = false, features = [ "rayon", "salsa_unstable", "macros", "inventory", ] } -salsa-macros = "0.25.2" +salsa-macros = "0.26" semver = "1.0.26" serde = { version = "1.0.219" } serde_derive = { version = "1.0.219" } diff --git a/src/tools/rust-analyzer/crates/base-db/src/editioned_file_id.rs b/src/tools/rust-analyzer/crates/base-db/src/editioned_file_id.rs index 13fb05d56547..dd419f48fc7e 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/editioned_file_id.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/editioned_file_id.rs @@ -60,7 +60,7 @@ const _: () = { } } - impl zalsa_struct_::HashEqLike for EditionedFileIdData { + impl zalsa_::HashEqLike for EditionedFileIdData { #[inline] fn hash(&self, state: &mut H) { Hash::hash(self, state); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 4f1480c39366..716409e16027 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -2363,6 +2363,7 @@ fn test() { } "#, expect![[r#" + 46..49 'Foo': Foo 93..97 'self': Foo 108..125 '{ ... }': usize 118..119 'N': usize diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index fe05ef946518..0a81cef52ec5 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -81,25 +81,24 @@ const _: () = { #[derive(Hash)] struct StructKey<'db, T0, T1, T2, T3>(T0, T1, T2, T3, std::marker::PhantomData<&'db ()>); - impl<'db, T0, T1, T2, T3> zalsa_::interned::HashEqLike> - for SyntaxContextData + impl<'db, T0, T1, T2, T3> zalsa_::HashEqLike> for SyntaxContextData where - Option: zalsa_::interned::HashEqLike, - Transparency: zalsa_::interned::HashEqLike, - Edition: zalsa_::interned::HashEqLike, - SyntaxContext: zalsa_::interned::HashEqLike, + Option: zalsa_::HashEqLike, + Transparency: zalsa_::HashEqLike, + Edition: zalsa_::HashEqLike, + SyntaxContext: zalsa_::HashEqLike, { fn hash(&self, h: &mut H) { - zalsa_::interned::HashEqLike::::hash(&self.outer_expn, &mut *h); - zalsa_::interned::HashEqLike::::hash(&self.outer_transparency, &mut *h); - zalsa_::interned::HashEqLike::::hash(&self.edition, &mut *h); - zalsa_::interned::HashEqLike::::hash(&self.parent, &mut *h); + zalsa_::HashEqLike::::hash(&self.outer_expn, &mut *h); + zalsa_::HashEqLike::::hash(&self.outer_transparency, &mut *h); + zalsa_::HashEqLike::::hash(&self.edition, &mut *h); + zalsa_::HashEqLike::::hash(&self.parent, &mut *h); } fn eq(&self, data: &StructKey<'db, T0, T1, T2, T3>) -> bool { - zalsa_::interned::HashEqLike::::eq(&self.outer_expn, &data.0) - && zalsa_::interned::HashEqLike::::eq(&self.outer_transparency, &data.1) - && zalsa_::interned::HashEqLike::::eq(&self.edition, &data.2) - && zalsa_::interned::HashEqLike::::eq(&self.parent, &data.3) + zalsa_::HashEqLike::::eq(&self.outer_expn, &data.0) + && zalsa_::HashEqLike::::eq(&self.outer_transparency, &data.1) + && zalsa_::HashEqLike::::eq(&self.edition, &data.2) + && zalsa_::HashEqLike::::eq(&self.parent, &data.3) } } impl zalsa_struct_::Configuration for SyntaxContext { @@ -203,10 +202,10 @@ const _: () = { impl<'db> SyntaxContext { pub fn new< Db, - T0: zalsa_::interned::Lookup> + std::hash::Hash, - T1: zalsa_::interned::Lookup + std::hash::Hash, - T2: zalsa_::interned::Lookup + std::hash::Hash, - T3: zalsa_::interned::Lookup + std::hash::Hash, + T0: zalsa_::Lookup> + std::hash::Hash, + T1: zalsa_::Lookup + std::hash::Hash, + T2: zalsa_::Lookup + std::hash::Hash, + T3: zalsa_::Lookup + std::hash::Hash, >( db: &'db Db, outer_expn: T0, @@ -218,10 +217,10 @@ const _: () = { ) -> Self where Db: ?Sized + salsa::Database, - Option: zalsa_::interned::HashEqLike, - Transparency: zalsa_::interned::HashEqLike, - Edition: zalsa_::interned::HashEqLike, - SyntaxContext: zalsa_::interned::HashEqLike, + Option: zalsa_::HashEqLike, + Transparency: zalsa_::HashEqLike, + Edition: zalsa_::HashEqLike, + SyntaxContext: zalsa_::HashEqLike, { let (zalsa, zalsa_local) = db.zalsas(); @@ -236,10 +235,10 @@ const _: () = { std::marker::PhantomData, ), |id, data| SyntaxContextData { - outer_expn: zalsa_::interned::Lookup::into_owned(data.0), - outer_transparency: zalsa_::interned::Lookup::into_owned(data.1), - edition: zalsa_::interned::Lookup::into_owned(data.2), - parent: zalsa_::interned::Lookup::into_owned(data.3), + outer_expn: zalsa_::Lookup::into_owned(data.0), + outer_transparency: zalsa_::Lookup::into_owned(data.1), + edition: zalsa_::Lookup::into_owned(data.2), + parent: zalsa_::Lookup::into_owned(data.3), opaque: opaque(zalsa_::FromId::from_id(id)), opaque_and_semiopaque: opaque_and_semiopaque(zalsa_::FromId::from_id(id)), }, From 84c2a531ac6db87db84e0f422a353a79af912694 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 1 Jan 2026 11:46:49 +0100 Subject: [PATCH 3356/3801] Correctly implement client side request cancellation support --- src/tools/rust-analyzer/Cargo.lock | 12 ++++++++++++ src/tools/rust-analyzer/crates/ide/src/lib.rs | 6 +++++- .../crates/rust-analyzer/src/global_state.rs | 8 +++++++- .../rust-analyzer/src/handlers/dispatch.rs | 17 ++++++++++++++++- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 9c98e0502070..12a6c09b8dfb 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -3754,3 +3754,15 @@ dependencies = [ "memchr", "time", ] + +[[patch.unused]] +name = "salsa" +version = "0.25.2" + +[[patch.unused]] +name = "salsa-macro-rules" +version = "0.25.2" + +[[patch.unused]] +name = "salsa-macros" +version = "0.25.2" diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index 930eaf2262d9..2e618550f92f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -67,7 +67,7 @@ use ide_db::{ FxHashMap, FxIndexSet, LineIndexDatabase, base_db::{ CrateOrigin, CrateWorkspaceData, Env, FileSet, RootQueryDb, SourceDatabase, VfsPath, - salsa::{Cancelled, Database}, + salsa::{CancellationToken, Cancelled, Database}, }, prime_caches, symbol_index, }; @@ -947,6 +947,10 @@ impl Analysis { // We use `attach_db_allow_change()` and not `attach_db()` because fixture injection can change the database. hir::attach_db_allow_change(&self.db, || Cancelled::catch(|| f(&self.db))) } + + pub fn cancellation_token(&self) -> CancellationToken { + self.db.cancellation_token() + } } #[test] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index afd4162de622..1462727df4e1 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -14,7 +14,7 @@ use hir::ChangeWithProcMacros; use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId}; use ide_db::{ MiniCore, - base_db::{Crate, ProcMacroPaths, SourceDatabase, salsa::Revision}, + base_db::{Crate, ProcMacroPaths, SourceDatabase, salsa::CancellationToken, salsa::Revision}, }; use itertools::Itertools; use load_cargo::SourceRootConfig; @@ -88,6 +88,7 @@ pub(crate) struct GlobalState { pub(crate) task_pool: Handle, Receiver>, pub(crate) fmt_pool: Handle, Receiver>, pub(crate) cancellation_pool: thread::Pool, + pub(crate) cancellation_tokens: FxHashMap, pub(crate) config: Arc, pub(crate) config_errors: Option, @@ -265,6 +266,7 @@ impl GlobalState { task_pool, fmt_pool, cancellation_pool, + cancellation_tokens: Default::default(), loader, config: Arc::new(config.clone()), analysis_host, @@ -617,6 +619,7 @@ impl GlobalState { } pub(crate) fn respond(&mut self, response: lsp_server::Response) { + self.cancellation_tokens.remove(&response.id); if let Some((method, start)) = self.req_queue.incoming.complete(&response.id) { if let Some(err) = &response.error && err.message.starts_with("server panicked") @@ -631,6 +634,9 @@ impl GlobalState { } pub(crate) fn cancel(&mut self, request_id: lsp_server::RequestId) { + if let Some(token) = self.cancellation_tokens.remove(&request_id) { + token.cancel(); + } if let Some(response) = self.req_queue.incoming.cancel(request_id) { self.send(response.into()); } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs index 90deae2d902e..63b4e6430c2d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs @@ -253,6 +253,9 @@ impl RequestDispatcher<'_> { tracing::debug!(?params); let world = self.global_state.snapshot(); + self.global_state + .cancellation_tokens + .insert(req.id.clone(), world.analysis.cancellation_token()); if RUSTFMT { &mut self.global_state.fmt_pool.handle } else { @@ -265,7 +268,19 @@ impl RequestDispatcher<'_> { }); match thread_result_to_response::(req.id.clone(), result) { Ok(response) => Task::Response(response), - Err(_cancelled) if ALLOW_RETRYING => Task::Retry(req), + Err(HandlerCancelledError::Inner( + Cancelled::PendingWrite | Cancelled::PropagatedPanic, + )) if ALLOW_RETRYING => Task::Retry(req), + // Note: Technically the return value here does not matter as we have already responded to the client with this error. + Err(HandlerCancelledError::Inner(Cancelled::Local)) => Task::Response(Response { + id: req.id, + result: None, + error: Some(ResponseError { + code: lsp_server::ErrorCode::RequestCanceled as i32, + message: "canceled by client".to_owned(), + data: None, + }), + }), Err(_cancelled) => { let error = on_cancelled(); Task::Response(Response { id: req.id, result: None, error: Some(error) }) From cee9cc6113b1c5ae3f47a87b73f546099d4b4296 Mon Sep 17 00:00:00 2001 From: Jacob Adam Date: Sat, 7 Feb 2026 12:37:00 +0100 Subject: [PATCH 3357/3801] Fix an ICE in the vtable iteration for a trait reference in const eval when a supertrait not implemented compiler/rustc_trait_selection/src/traits/vtable.rs@`vtable_entries`: The impossible predicates check in `vtable_entries` used `instantiate_own` which only includes the method's own where-clauses, not the parent trait's bounds. Replace it with `instantiate_and_check_impossible_predicates` which also checks the trait ref itself, so unsatisfied supertrait bounds are caught and the method is marked `Vacant` instead of ICEing. --- compiler/rustc_trait_selection/src/traits/vtable.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 584c8e2a27c8..bd48068eb579 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -12,7 +12,7 @@ use rustc_span::DUMMY_SP; use smallvec::{SmallVec, smallvec}; use tracing::debug; -use crate::traits::{impossible_predicates, is_vtable_safe_method}; +use crate::traits::is_vtable_safe_method; #[derive(Clone, Debug)] pub enum VtblSegment<'tcx> { @@ -271,11 +271,7 @@ fn vtable_entries<'tcx>( // do not hold for this particular set of type parameters. // Note that this method could then never be called, so we // do not want to try and codegen it, in that case (see #23435). - let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args); - if impossible_predicates( - tcx, - predicates.map(|(predicate, _)| predicate).collect(), - ) { + if tcx.instantiate_and_check_impossible_predicates((def_id, args)) { debug!("vtable_entries: predicates do not hold"); return VtblEntry::Vacant; } From 6af91c56d199851abfebbbab4745f34f229649f1 Mon Sep 17 00:00:00 2001 From: Jacob Adam Date: Sat, 7 Feb 2026 12:42:59 +0100 Subject: [PATCH 3358/3801] Move tests from tests/crashes to tests/ui now that they don't ICE --- tests/crashes/137190-2.rs | 18 ------------- tests/crashes/137190-3.rs | 10 -------- .../vtable-impossible-predicates-async.rs} | 6 ++++- .../vtable-unsatisfied-supertrait-generics.rs | 25 +++++++++++++++++++ ...ble-unsatisfied-supertrait-generics.stderr | 20 +++++++++++++++ .../coercion/vtable-unsatisfied-supertrait.rs | 16 ++++++++++++ .../vtable-unsatisfied-supertrait.stderr | 20 +++++++++++++++ 7 files changed, 86 insertions(+), 29 deletions(-) delete mode 100644 tests/crashes/137190-2.rs delete mode 100644 tests/crashes/137190-3.rs rename tests/{crashes/135470.rs => ui/coercion/vtable-impossible-predicates-async.rs} (79%) create mode 100644 tests/ui/coercion/vtable-unsatisfied-supertrait-generics.rs create mode 100644 tests/ui/coercion/vtable-unsatisfied-supertrait-generics.stderr create mode 100644 tests/ui/coercion/vtable-unsatisfied-supertrait.rs create mode 100644 tests/ui/coercion/vtable-unsatisfied-supertrait.stderr diff --git a/tests/crashes/137190-2.rs b/tests/crashes/137190-2.rs deleted file mode 100644 index 0c68b5aa4a51..000000000000 --- a/tests/crashes/137190-2.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ known-bug: #137190 -trait Supertrait { - fn method(&self) {} -} - -trait Trait

    : Supertrait<()> {} - -impl

    Trait

    for () {} - -const fn upcast

    (x: &dyn Trait

    ) -> &dyn Supertrait<()> { - x -} - -const fn foo() -> &'static dyn Supertrait<()> { - upcast::<()>(&()) -} - -const _: &'static dyn Supertrait<()> = foo(); diff --git a/tests/crashes/137190-3.rs b/tests/crashes/137190-3.rs deleted file mode 100644 index 88ae88e11bcd..000000000000 --- a/tests/crashes/137190-3.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #137190 -trait Supertrait { - fn method(&self) {} -} - -trait Trait: Supertrait {} - -impl Trait for () {} - -const _: &dyn Supertrait = &() as &dyn Trait as &dyn Supertrait; diff --git a/tests/crashes/135470.rs b/tests/ui/coercion/vtable-impossible-predicates-async.rs similarity index 79% rename from tests/crashes/135470.rs rename to tests/ui/coercion/vtable-impossible-predicates-async.rs index efa017b5457c..fe6aa9843fc6 100644 --- a/tests/crashes/135470.rs +++ b/tests/ui/coercion/vtable-impossible-predicates-async.rs @@ -1,4 +1,8 @@ -//@ known-bug: #135470 +// Regression test for #135470. +// Verify that we don't ICE when building vtable entries +// for a blanket impl involving async and impossible predicates. + +//@ check-pass //@ compile-flags: -Copt-level=0 //@ edition: 2021 diff --git a/tests/ui/coercion/vtable-unsatisfied-supertrait-generics.rs b/tests/ui/coercion/vtable-unsatisfied-supertrait-generics.rs new file mode 100644 index 000000000000..41e603fc0a0a --- /dev/null +++ b/tests/ui/coercion/vtable-unsatisfied-supertrait-generics.rs @@ -0,0 +1,25 @@ +// Regression test for #137190. +// Variant of vtable-unsatisfied-supertrait.rs with generic traits. +// Verify that we don't ICE when building vtable entries +// for a generic trait whose supertrait is not implemented. + +//@ compile-flags: --crate-type lib + +trait Supertrait { + fn method(&self) {} +} + +trait Trait

    : Supertrait<()> {} + +impl

    Trait

    for () {} +//~^ ERROR the trait bound `(): Supertrait<()>` is not satisfied + +const fn upcast

    (x: &dyn Trait

    ) -> &dyn Supertrait<()> { + x +} + +const fn foo() -> &'static dyn Supertrait<()> { + upcast::<()>(&()) +} + +const _: &'static dyn Supertrait<()> = foo(); diff --git a/tests/ui/coercion/vtable-unsatisfied-supertrait-generics.stderr b/tests/ui/coercion/vtable-unsatisfied-supertrait-generics.stderr new file mode 100644 index 000000000000..a485d2d53953 --- /dev/null +++ b/tests/ui/coercion/vtable-unsatisfied-supertrait-generics.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `(): Supertrait<()>` is not satisfied + --> $DIR/vtable-unsatisfied-supertrait-generics.rs:14:22 + | +LL | impl

    Trait

    for () {} + | ^^ the trait `Supertrait<()>` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/vtable-unsatisfied-supertrait-generics.rs:8:1 + | +LL | trait Supertrait { + | ^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `Trait` + --> $DIR/vtable-unsatisfied-supertrait-generics.rs:12:17 + | +LL | trait Trait

    : Supertrait<()> {} + | ^^^^^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coercion/vtable-unsatisfied-supertrait.rs b/tests/ui/coercion/vtable-unsatisfied-supertrait.rs new file mode 100644 index 000000000000..26a83d2fb066 --- /dev/null +++ b/tests/ui/coercion/vtable-unsatisfied-supertrait.rs @@ -0,0 +1,16 @@ +// Regression test for #137190. +// Verify that we don't ICE when building vtable entries +// for a trait whose supertrait is not implemented. + +//@ compile-flags: --crate-type lib + +trait Supertrait { + fn method(&self) {} +} + +trait Trait: Supertrait {} + +impl Trait for () {} +//~^ ERROR the trait bound `(): Supertrait` is not satisfied + +const _: &dyn Supertrait = &() as &dyn Trait as &dyn Supertrait; diff --git a/tests/ui/coercion/vtable-unsatisfied-supertrait.stderr b/tests/ui/coercion/vtable-unsatisfied-supertrait.stderr new file mode 100644 index 000000000000..7df2c95c7fac --- /dev/null +++ b/tests/ui/coercion/vtable-unsatisfied-supertrait.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `(): Supertrait` is not satisfied + --> $DIR/vtable-unsatisfied-supertrait.rs:13:16 + | +LL | impl Trait for () {} + | ^^ the trait `Supertrait` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/vtable-unsatisfied-supertrait.rs:7:1 + | +LL | trait Supertrait { + | ^^^^^^^^^^^^^^^^ +note: required by a bound in `Trait` + --> $DIR/vtable-unsatisfied-supertrait.rs:11:14 + | +LL | trait Trait: Supertrait {} + | ^^^^^^^^^^ required by this bound in `Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 9249e9f78a7c12f1e797e6519375df698fd96970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 5 Feb 2026 14:02:06 +0100 Subject: [PATCH 3359/3801] Port rustc_intrinsic to the new attribute parser --- compiler/rustc_ast_lowering/src/item.rs | 2 +- .../rustc_attr_parsing/src/attributes/rustc_internal.rs | 9 +++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_middle/src/ty/util.rs | 6 ++++-- compiler/rustc_mir_transform/src/check_inline.rs | 5 +++-- compiler/rustc_mir_transform/src/cross_crate_inline.rs | 7 ++++--- compiler/rustc_passes/src/check_attr.rs | 2 +- src/tools/clippy/clippy_lints/src/loops/empty_loop.rs | 7 ++++--- 10 files changed, 31 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index cde8b8f9fe2e..12eaa99143e9 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1397,7 +1397,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // create a fake body so that the entire rest of the compiler doesn't have to deal with // this as a special case. return self.lower_fn_body(decl, contract, |this| { - if attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic)) + if find_attr!(attrs, AttributeKind::RustcIntrinsic) || this.tcx.is_sdylib_interface_build() { let span = this.lower_span(span); diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 3b7d25b43ba2..637912210638 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -810,3 +810,12 @@ impl SingleAttributeParser for RustcDefPath { Some(AttributeKind::RustcDefPath(cx.attr_span)) } } + +pub(crate) struct RustcIntrinsicParser; + +impl NoArgsAttributeParser for RustcIntrinsicParser { + const PATH: &[Symbol] = &[sym::rustc_intrinsic]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsic; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 5b489d306499..68c9f232e1b1 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -264,6 +264,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index fa781a74c9e2..1bcf0bf1541e 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1120,6 +1120,9 @@ pub enum AttributeKind { /// Represents `#[rustc_if_this_changed]` RustcIfThisChanged(Span, Option), + /// Represents `#[rustc_intrinsic]` + RustcIntrinsic, + /// Represents `#[rustc_layout]` RustcLayout(ThinVec), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 14b54c129d3e..92066c9cfad4 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -118,6 +118,7 @@ impl AttributeKind { RustcHasIncoherentInherentImpls => Yes, RustcHiddenTypeOfOpaques => No, RustcIfThisChanged(..) => No, + RustcIntrinsic => Yes, RustcLayout(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index d6e6ffae7300..47b9bb95f830 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -10,11 +10,11 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorGuaranteed; use rustc_hashes::Hash128; -use rustc_hir as hir; use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_hir::limit::Limit; +use rustc_hir::{self as hir, find_attr}; use rustc_index::bit_set::GrowableBitSet; use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension}; use rustc_span::sym; @@ -1679,7 +1679,9 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { /// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may /// cause an ICE that we otherwise may want to prevent. pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - if tcx.features().intrinsics() && tcx.has_attr(def_id, sym::rustc_intrinsic) { + if tcx.features().intrinsics() + && find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcIntrinsic) + { let must_be_overridden = match tcx.hir_node_by_def_id(def_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { has_body, .. }, .. }) => { !has_body diff --git a/compiler/rustc_mir_transform/src/check_inline.rs b/compiler/rustc_mir_transform/src/check_inline.rs index 8d28cb3ca003..2d1876426727 100644 --- a/compiler/rustc_mir_transform/src/check_inline.rs +++ b/compiler/rustc_mir_transform/src/check_inline.rs @@ -1,8 +1,9 @@ //! Check that a body annotated with `#[rustc_force_inline]` will not fail to inline based on its //! definition alone (irrespective of any specific caller). -use rustc_hir::attrs::InlineAttr; +use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def_id::DefId; +use rustc_hir::find_attr; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::{Body, TerminatorKind}; use rustc_middle::ty; @@ -62,7 +63,7 @@ pub(super) fn is_inline_valid_on_fn<'tcx>( // but at this stage we don't know whether codegen knows the intrinsic, // so just conservatively don't inline it. This also ensures that we do not // accidentally inline the body of an intrinsic that *must* be overridden. - if tcx.has_attr(def_id, sym::rustc_intrinsic) { + if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcIntrinsic) { return Err("callee is an intrinsic"); } diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 71bdafa958ca..da133861617f 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -1,6 +1,7 @@ -use rustc_hir::attrs::InlineAttr; +use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_hir::find_attr; use rustc_middle::bug; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; @@ -43,7 +44,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return true; } - if tcx.has_attr(def_id, sym::rustc_intrinsic) { + if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcIntrinsic) { // Intrinsic fallback bodies are always cross-crate inlineable. // To ensure that the MIR inliner doesn't cluelessly try to inline fallback // bodies even when the backend would implement something better, we stop @@ -157,7 +158,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { // But intrinsics don't have a body that gets assigned to a CGU, so they are // ignored. if let Some((fn_def_id, _)) = func.const_fn_def() - && self.tcx.has_attr(fn_def_id, sym::rustc_intrinsic) + && find_attr!(tcx.get_all_attrs(fn_def_id), AttributeKind::RustcIntrinsic) { return; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 680a93908354..8dcc0eb63c2f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -313,6 +313,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcHasIncoherentInherentImpls | AttributeKind::RustcHiddenTypeOfOpaques | AttributeKind::RustcIfThisChanged(..) + | AttributeKind::RustcIntrinsic | AttributeKind::RustcLayout(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcLayoutScalarValidRangeStart(..) @@ -385,7 +386,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_no_mir_inline | sym::rustc_insignificant_dtor | sym::rustc_nonnull_optimization_guaranteed - | sym::rustc_intrinsic | sym::rustc_inherit_overflow_checks | sym::rustc_intrinsic_const_stable_indirect | sym::rustc_trivial_field_reads diff --git a/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs b/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs index e809987d75a0..0a5b26bfa689 100644 --- a/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs @@ -1,8 +1,9 @@ use super::EMPTY_LOOP; use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::{is_in_panic_handler, is_no_std_crate, sym}; +use clippy_utils::{is_in_panic_handler, is_no_std_crate}; -use rustc_hir::{Block, Expr, ItemKind, Node}; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{Block, Expr, ItemKind, Node, find_attr}; use rustc_lint::LateContext; pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, loop_block: &Block<'_>) { @@ -10,7 +11,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, loop_block: &Block<'_ if let Node::Item(parent_node) = cx.tcx.hir_node(parent_hir_id) && matches!(parent_node.kind, ItemKind::Fn { .. }) && let attrs = cx.tcx.hir_attrs(parent_hir_id) - && attrs.iter().any(|attr| attr.has_name(sym::rustc_intrinsic)) + && find_attr!(attrs, AttributeKind::RustcIntrinsic) { // Intrinsic functions are expanded into an empty loop when lowering the AST // to simplify the job of later passes which might expect any function to have a body. From c42a581d2f02da46b77f0c2ff00f6a7e6ff4b524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 5 Feb 2026 14:09:40 +0100 Subject: [PATCH 3360/3801] Port rustc_intrinsic_const_stable_indirect to the new attribute parser --- .../src/attributes/rustc_internal.rs | 10 ++++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_middle/src/ty/util.rs | 5 ++++- compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 20 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 637912210638..7e4feedd2548 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -490,6 +490,7 @@ impl CombineAttributeParser for RustcMirParser { .collect() } } + pub(crate) struct RustcNonConstTraitMethodParser; impl NoArgsAttributeParser for RustcNonConstTraitMethodParser { @@ -819,3 +820,12 @@ impl NoArgsAttributeParser for RustcIntrinsicParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsic; } + +pub(crate) struct RustcIntrinsicConstStableIndirectParser; + +impl NoArgsAttributeParser for RustcIntrinsicConstStableIndirectParser { + const PATH: &'static [Symbol] = &[sym::rustc_intrinsic_const_stable_indirect]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsicConstStableIndirect; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 68c9f232e1b1..0d594270ba68 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -264,6 +264,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 1bcf0bf1541e..0e6208831190 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1123,6 +1123,9 @@ pub enum AttributeKind { /// Represents `#[rustc_intrinsic]` RustcIntrinsic, + /// Represents `#[rustc_intrinsic_const_stable_indirect]` + RustcIntrinsicConstStableIndirect, + /// Represents `#[rustc_layout]` RustcLayout(ThinVec), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 92066c9cfad4..1f322d84fad4 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -119,6 +119,7 @@ impl AttributeKind { RustcHiddenTypeOfOpaques => No, RustcIfThisChanged(..) => No, RustcIntrinsic => Yes, + RustcIntrinsicConstStableIndirect => No, RustcLayout(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 47b9bb95f830..e01a5721a5e0 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1691,7 +1691,10 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option CheckAttrVisitor<'tcx> { | AttributeKind::RustcHiddenTypeOfOpaques | AttributeKind::RustcIfThisChanged(..) | AttributeKind::RustcIntrinsic + | AttributeKind::RustcIntrinsicConstStableIndirect | AttributeKind::RustcLayout(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcLayoutScalarValidRangeStart(..) @@ -387,7 +388,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_insignificant_dtor | sym::rustc_nonnull_optimization_guaranteed | sym::rustc_inherit_overflow_checks - | sym::rustc_intrinsic_const_stable_indirect | sym::rustc_trivial_field_reads | sym::rustc_on_unimplemented | sym::rustc_do_not_const_check From f090e9ce83e0873591e5faca204cfb68da93ff67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 5 Feb 2026 14:02:06 +0100 Subject: [PATCH 3361/3801] Port rustc_intrinsic to the new attribute parser --- clippy_lints/src/loops/empty_loop.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/loops/empty_loop.rs b/clippy_lints/src/loops/empty_loop.rs index e809987d75a0..0a5b26bfa689 100644 --- a/clippy_lints/src/loops/empty_loop.rs +++ b/clippy_lints/src/loops/empty_loop.rs @@ -1,8 +1,9 @@ use super::EMPTY_LOOP; use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::{is_in_panic_handler, is_no_std_crate, sym}; +use clippy_utils::{is_in_panic_handler, is_no_std_crate}; -use rustc_hir::{Block, Expr, ItemKind, Node}; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{Block, Expr, ItemKind, Node, find_attr}; use rustc_lint::LateContext; pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, loop_block: &Block<'_>) { @@ -10,7 +11,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, loop_block: &Block<'_ if let Node::Item(parent_node) = cx.tcx.hir_node(parent_hir_id) && matches!(parent_node.kind, ItemKind::Fn { .. }) && let attrs = cx.tcx.hir_attrs(parent_hir_id) - && attrs.iter().any(|attr| attr.has_name(sym::rustc_intrinsic)) + && find_attr!(attrs, AttributeKind::RustcIntrinsic) { // Intrinsic functions are expanded into an empty loop when lowering the AST // to simplify the job of later passes which might expect any function to have a body. From fd7ff90f7029a79f2b19f696471c0e675932c283 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 7 Feb 2026 14:28:12 +0100 Subject: [PATCH 3362/3801] Allow only a single accepter per attribute --- compiler/rustc_attr_parsing/src/context.rs | 36 ++++++++++-------- compiler/rustc_attr_parsing/src/interface.rs | 40 ++++++++++---------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 5b489d306499..8db561575562 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -1,5 +1,6 @@ use std::cell::RefCell; use std::collections::BTreeMap; +use std::collections::btree_map::Entry; use std::ops::{Deref, DerefMut}; use std::sync::LazyLock; @@ -61,7 +62,7 @@ use crate::target_checking::AllowedTargets; type GroupType = LazyLock>; pub(super) struct GroupTypeInner { - pub(super) accepters: BTreeMap<&'static [Symbol], Vec>>, + pub(super) accepters: BTreeMap<&'static [Symbol], GroupTypeInnerAccept>, } pub(super) struct GroupTypeInnerAccept { @@ -101,7 +102,7 @@ macro_rules! attribute_parsers { @[$stage: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?]; ) => { pub(crate) static $name: GroupType<$stage> = LazyLock::new(|| { - let mut accepters = BTreeMap::<_, Vec>>::new(); + let mut accepters = BTreeMap::<_, GroupTypeInnerAccept<$stage>>::new(); $( { thread_local! { @@ -109,19 +110,24 @@ macro_rules! attribute_parsers { }; for (path, template, accept_fn) in <$names>::ATTRIBUTES { - accepters.entry(*path).or_default().push(GroupTypeInnerAccept { - template: *template, - accept_fn: Box::new(|cx, args| { - STATE_OBJECT.with_borrow_mut(|s| { - accept_fn(s, cx, args) - }) - }), - allowed_targets: <$names as crate::attributes::AttributeParser<$stage>>::ALLOWED_TARGETS, - finalizer: Box::new(|cx| { - let state = STATE_OBJECT.take(); - state.finalize(cx) - }), - }); + match accepters.entry(*path) { + Entry::Vacant(e) => { + e.insert(GroupTypeInnerAccept { + template: *template, + accept_fn: Box::new(|cx, args| { + STATE_OBJECT.with_borrow_mut(|s| { + accept_fn(s, cx, args) + }) + }), + allowed_targets: <$names as crate::attributes::AttributeParser<$stage>>::ALLOWED_TARGETS, + finalizer: Box::new(|cx| { + let state = STATE_OBJECT.take(); + state.finalize(cx) + }) + }); + } + Entry::Occupied(_) => panic!("Attribute {path:?} has multiple accepters"), + } } } )* diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index bac4936c20d2..f75f63a0e811 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -327,7 +327,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { let parts = n.item.path.segments.iter().map(|seg| seg.ident.name).collect::>(); - if let Some(accepts) = S::parsers().accepters.get(parts.as_slice()) { + if let Some(accept) = S::parsers().accepters.get(parts.as_slice()) { let Some(args) = ArgParser::from_attr_args( args, &parts, @@ -368,28 +368,26 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { continue; } - for accept in accepts { - let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext { - shared: SharedContext { - cx: self, - target_span, - target, - emit_lint: &mut emit_lint, - }, - attr_span, - inner_span: lower_span(n.item.span()), - attr_style: attr.style, - parsed_description: ParsedDescription::Attribute, - template: &accept.template, - attr_path: attr_path.clone(), - }; + let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext { + shared: SharedContext { + cx: self, + target_span, + target, + emit_lint: &mut emit_lint, + }, + attr_span, + inner_span: lower_span(n.item.span()), + attr_style: attr.style, + parsed_description: ParsedDescription::Attribute, + template: &accept.template, + attr_path: attr_path.clone(), + }; - (accept.accept_fn)(&mut cx, &args); - finalizers.push(&accept.finalizer); + (accept.accept_fn)(&mut cx, &args); + finalizers.push(&accept.finalizer); - if !matches!(cx.stage.should_emit(), ShouldEmit::Nothing) { - Self::check_target(&accept.allowed_targets, target, &mut cx); - } + if !matches!(cx.stage.should_emit(), ShouldEmit::Nothing) { + Self::check_target(&accept.allowed_targets, target, &mut cx); } } else { // If we're here, we must be compiling a tool attribute... Or someone From 2407f47903869fab5ff713126037c932caf77e3a Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 7 Feb 2026 14:29:40 +0100 Subject: [PATCH 3363/3801] Also duplicate `#[expect]` attribute in `#[derive]`-ed code --- .../src/deriving/generic/mod.rs | 1 + .../derive-expect-issue-150553-2.rs | 14 ++++++++++++ .../derive-expect-issue-150553-3.rs | 14 ++++++++++++ .../derive-expect-issue-150553-3.stderr | 18 +++++++++++++++ .../derive-expect-issue-150553.rs | 22 +++++++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-2.rs create mode 100644 tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.rs create mode 100644 tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.stderr create mode 100644 tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553.rs diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index bc86cdbc9f7e..3fe5e89ef06d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -540,6 +540,7 @@ impl<'a> TraitDef<'a> { .filter(|a| { a.has_any_name(&[ sym::allow, + sym::expect, sym::warn, sym::deny, sym::forbid, diff --git a/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-2.rs b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-2.rs new file mode 100644 index 000000000000..43ee6bf26a69 --- /dev/null +++ b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-2.rs @@ -0,0 +1,14 @@ +// Make sure that the copied `#[expect]` attr in the derived code does not trigger an unfulfilled +// expectation as it's linked to the original one which is fulfilled. +// +// See for rational. + +//@ check-pass + +#[expect(non_camel_case_types)] +#[derive(Debug)] +pub struct SCREAMING_CASE { + pub t_ref: i64, +} + +fn main() {} diff --git a/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.rs b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.rs new file mode 100644 index 000000000000..904366e6532e --- /dev/null +++ b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.rs @@ -0,0 +1,14 @@ +// Make sure we produce the unfulfilled expectation lint if neither the struct or the +// derived code fulfilled it. + +//@ check-pass + +#[expect(unexpected_cfgs)] +//~^ WARN this lint expectation is unfulfilled +//~^^ WARN this lint expectation is unfulfilled +#[derive(Debug)] +pub struct MyStruct { + pub t_ref: i64, +} + +fn main() {} diff --git a/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.stderr b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.stderr new file mode 100644 index 000000000000..6478ec435db0 --- /dev/null +++ b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.stderr @@ -0,0 +1,18 @@ +warning: this lint expectation is unfulfilled + --> $DIR/derive-expect-issue-150553-3.rs:6:10 + | +LL | #[expect(unexpected_cfgs)] + | ^^^^^^^^^^^^^^^ + | + = note: `#[warn(unfulfilled_lint_expectations)]` on by default + +warning: this lint expectation is unfulfilled + --> $DIR/derive-expect-issue-150553-3.rs:6:10 + | +LL | #[expect(unexpected_cfgs)] + | ^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +warning: 2 warnings emitted + diff --git a/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553.rs b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553.rs new file mode 100644 index 000000000000..1752835c8bb8 --- /dev/null +++ b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553.rs @@ -0,0 +1,22 @@ +// Make sure we properly copy the `#[expect]` attr to the derived code and that no +// unfulfilled expectations are trigerred. +// +// See for rational. + +//@ check-pass + +#![deny(redundant_lifetimes)] + +use std::fmt::Debug; + +#[derive(Debug)] +#[expect(redundant_lifetimes)] +pub struct RefWrapper<'a, T> +where + 'a: 'static, + T: Debug, +{ + pub t_ref: &'a T, +} + +fn main() {} From 0538f7b2ab82f5ea828dec77eeded64f0df24c8f Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 7 Feb 2026 06:33:33 -0600 Subject: [PATCH 3364/3801] meta: Switch to workspace dependencies We have a handful of repeated dependencies that can be cleaned up, so change here. --- library/compiler-builtins/Cargo.toml | 33 +++++++++++++++++++ .../builtins-shim/Cargo.toml | 5 ++- .../builtins-test/Cargo.toml | 21 ++++++------ .../compiler-builtins/Cargo.toml | 2 +- .../crates/libm-macros/Cargo.toml | 8 ++--- .../crates/musl-math-sys/Cargo.toml | 6 ++-- .../crates/symbol-check/Cargo.toml | 12 +++---- .../compiler-builtins/crates/util/Cargo.toml | 10 +++--- .../compiler-builtins/libm-test/Cargo.toml | 32 +++++++++--------- library/compiler-builtins/libm/Cargo.toml | 1 + 10 files changed, 82 insertions(+), 48 deletions(-) diff --git a/library/compiler-builtins/Cargo.toml b/library/compiler-builtins/Cargo.toml index d0eaa16393cd..26f67e02fc52 100644 --- a/library/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/Cargo.toml @@ -31,6 +31,39 @@ exclude = [ "compiler-builtins", ] +[workspace.dependencies] +anyhow = "1.0.101" +assert_cmd = "2.1.2" +cc = "1.2.55" +compiler_builtins = { path = "builtins-shim", default-features = false } +criterion = { version = "0.6.0", default-features = false, features = ["cargo_bench_support"] } +getrandom = "0.3.4" +gmp-mpfr-sys = { version = "1.6.8", default-features = false } +gungraun = "0.17.0" +heck = "0.5.0" +indicatif = { version = "0.18.3", default-features = false } +libm = { path = "libm", default-features = false } +libm-macros = { path = "crates/libm-macros" } +libm-test = { path = "libm-test", default-features = false } +libtest-mimic = "0.8.1" +musl-math-sys = { path = "crates/musl-math-sys" } +no-panic = "0.1.35" +object = { version = "0.37.3", features = ["wasm"] } +panic-handler = { path = "crates/panic-handler" } +paste = "1.0.15" +proc-macro2 = "1.0.106" +quote = "1.0.44" +rand = "0.9.2" +rand_chacha = "0.9.0" +rand_xoshiro = "0.7" +rayon = "1.11.0" +regex = "1.12.3" +rug = { version = "1.28.1", default-features = false, features = ["float", "integer", "std"] } +rustc_apfloat = "0.2.3" +serde_json = "1.0.149" +syn = "2.0.114" +tempfile = "3.24.0" + [profile.release] panic = "abort" diff --git a/library/compiler-builtins/builtins-shim/Cargo.toml b/library/compiler-builtins/builtins-shim/Cargo.toml index 746d5b21dc3f..37d3407e9f66 100644 --- a/library/compiler-builtins/builtins-shim/Cargo.toml +++ b/library/compiler-builtins/builtins-shim/Cargo.toml @@ -7,6 +7,9 @@ # manifest that is identical except for the `core` dependency and forwards # to the same sources, which acts as the `compiler-builtins` Cargo entrypoint # for out of tree testing +# +# Ideally we can eventually replace this with a patch in the workspace +# manifest . [package] name = "compiler_builtins" @@ -33,7 +36,7 @@ doctest = false test = false [build-dependencies] -cc = { optional = true, version = "1.2" } +cc = { version = "1.2", optional = true } [features] default = ["compiler-builtins"] diff --git a/library/compiler-builtins/builtins-test/Cargo.toml b/library/compiler-builtins/builtins-test/Cargo.toml index 550f736a76db..9395ab1a985e 100644 --- a/library/compiler-builtins/builtins-test/Cargo.toml +++ b/library/compiler-builtins/builtins-test/Cargo.toml @@ -6,23 +6,22 @@ publish = false license = "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)" [dependencies] +compiler_builtins = { workspace = true, features = ["unstable-public-internals"] } + # For fuzzing tests we want a deterministic seedable RNG. We also eliminate potential # problems with system RNGs on the variety of platforms this crate is tested on. # `xoshiro128**` is used for its quality, size, and speed at generating `u32` shift amounts. -rand_xoshiro = "0.7" -# To compare float builtins against -rustc_apfloat = "0.2.3" -# Really a dev dependency, but dev dependencies can't be optional -gungraun = { version = "0.17.0", optional = true } +rand_xoshiro.workspace = true -[dependencies.compiler_builtins] -path = "../builtins-shim" -default-features = false -features = ["unstable-public-internals"] +# To compare float builtins against +rustc_apfloat.workspace = true + +# Really a dev dependency, but dev dependencies can't be optional +gungraun = { workspace = true, optional = true } [dev-dependencies] -criterion = { version = "0.6.0", default-features = false, features = ["cargo_bench_support"] } -paste = "1.0.15" +criterion.workspace = true +paste.workspace = true [target.'cfg(all(target_arch = "arm", not(any(target_env = "gnu", target_env = "musl")), target_os = "linux"))'.dev-dependencies] test = { git = "https://github.com/japaric/utest" } diff --git a/library/compiler-builtins/compiler-builtins/Cargo.toml b/library/compiler-builtins/compiler-builtins/Cargo.toml index 496dde2d4cf2..a8b8920421b3 100644 --- a/library/compiler-builtins/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/compiler-builtins/Cargo.toml @@ -31,7 +31,7 @@ doc = false core = { path = "../../core", optional = true } [build-dependencies] -cc = { optional = true, version = "1.2" } +cc = { version = "1.2", optional = true } [features] default = ["compiler-builtins"] diff --git a/library/compiler-builtins/crates/libm-macros/Cargo.toml b/library/compiler-builtins/crates/libm-macros/Cargo.toml index f6697b783457..f99a92e21c70 100644 --- a/library/compiler-builtins/crates/libm-macros/Cargo.toml +++ b/library/compiler-builtins/crates/libm-macros/Cargo.toml @@ -9,10 +9,10 @@ license = "MIT OR Apache-2.0" proc-macro = true [dependencies] -heck = "0.5.0" -proc-macro2 = "1.0.106" -quote = "1.0.44" -syn = { version = "2.0.114", features = ["full", "extra-traits", "visit-mut"] } +heck.workspace = true +proc-macro2.workspace = true +quote.workspace = true +syn = { workspace = true, features = ["full", "extra-traits", "visit-mut"] } [lints.rust] # Values used during testing diff --git a/library/compiler-builtins/crates/musl-math-sys/Cargo.toml b/library/compiler-builtins/crates/musl-math-sys/Cargo.toml index 60b0647b6dc6..eb97ffbc8669 100644 --- a/library/compiler-builtins/crates/musl-math-sys/Cargo.toml +++ b/library/compiler-builtins/crates/musl-math-sys/Cargo.toml @@ -5,10 +5,8 @@ edition = "2024" publish = false license = "MIT OR Apache-2.0" -[dependencies] - [dev-dependencies] -libm = { path = "../../libm" } +libm.workspace = true [build-dependencies] -cc = "1.2.55" +cc.workspace = true diff --git a/library/compiler-builtins/crates/symbol-check/Cargo.toml b/library/compiler-builtins/crates/symbol-check/Cargo.toml index 6291a0ca7f45..5bc13d337c27 100644 --- a/library/compiler-builtins/crates/symbol-check/Cargo.toml +++ b/library/compiler-builtins/crates/symbol-check/Cargo.toml @@ -5,11 +5,11 @@ edition = "2024" publish = false [dependencies] -object = { version = "0.37.3", features = ["wasm"] } -regex = "1.12.3" -serde_json = "1.0.149" +object.workspace = true +regex.workspace = true +serde_json.workspace = true [dev-dependencies] -assert_cmd = "2.1.2" -cc = "1.2.55" -tempfile = "3.24.0" +assert_cmd.workspace = true +cc.workspace = true +tempfile.workspace = true diff --git a/library/compiler-builtins/crates/util/Cargo.toml b/library/compiler-builtins/crates/util/Cargo.toml index b1ccd8a9e63c..88e0b332065d 100644 --- a/library/compiler-builtins/crates/util/Cargo.toml +++ b/library/compiler-builtins/crates/util/Cargo.toml @@ -12,8 +12,8 @@ build-mpfr = ["libm-test/build-mpfr", "dep:rug"] unstable-float = ["libm/unstable-float", "libm-test/unstable-float", "rug?/nightly-float"] [dependencies] -libm = { path = "../../libm", default-features = false } -libm-macros = { path = "../libm-macros" } -libm-test = { path = "../../libm-test", default-features = false } -musl-math-sys = { path = "../musl-math-sys", optional = true } -rug = { version = "1.28.1", optional = true, default-features = false, features = ["float", "std"] } +libm.workspace = true +libm-macros.workspace = true +libm-test.workspace = true +musl-math-sys = { workspace = true, optional = true } +rug = { workspace = true, optional = true } diff --git a/library/compiler-builtins/libm-test/Cargo.toml b/library/compiler-builtins/libm-test/Cargo.toml index b813331a8552..c395d6a21bd5 100644 --- a/library/compiler-builtins/libm-test/Cargo.toml +++ b/library/compiler-builtins/libm-test/Cargo.toml @@ -28,29 +28,29 @@ icount = ["dep:gungraun"] short-benchmarks = [] [dependencies] -anyhow = "1.0.101" +anyhow.workspace = true # This is not directly used but is required so we can enable `gmp-mpfr-sys/force-cross`. -gmp-mpfr-sys = { version = "1.6.8", optional = true, default-features = false } -gungraun = { version = "0.17.0", optional = true } -indicatif = { version = "0.18.3", default-features = false } -libm = { path = "../libm", features = ["unstable-public-internals"] } -libm-macros = { path = "../crates/libm-macros" } -musl-math-sys = { path = "../crates/musl-math-sys", optional = true } -paste = "1.0.15" -rand = "0.9.2" -rand_chacha = "0.9.0" -rayon = "1.11.0" -rug = { version = "1.28.1", optional = true, default-features = false, features = ["float", "integer", "std"] } +gmp-mpfr-sys = { workspace = true, optional = true } +gungraun = { workspace = true, optional = true } +indicatif.workspace = true +libm = { workspace = true, default-features = true, features = ["unstable-public-internals"] } +libm-macros.workspace = true +musl-math-sys = { workspace = true, optional = true } +paste.workspace = true +rand.workspace = true +rand_chacha.workspace = true +rayon.workspace = true +rug = { workspace = true, optional = true } [target.'cfg(target_family = "wasm")'.dependencies] -getrandom = { version = "0.3.4", features = ["wasm_js"] } +getrandom = { workspace = true, features = ["wasm_js"] } [build-dependencies] -rand = { version = "0.9.2", optional = true } +rand = { workspace = true, optional = true } [dev-dependencies] -criterion = { version = "0.6.0", default-features = false, features = ["cargo_bench_support"] } -libtest-mimic = "0.8.1" +criterion.workspace = true +libtest-mimic.workspace = true [[bench]] name = "icount" diff --git a/library/compiler-builtins/libm/Cargo.toml b/library/compiler-builtins/libm/Cargo.toml index 4d8b9bf827ad..617914a4dfae 100644 --- a/library/compiler-builtins/libm/Cargo.toml +++ b/library/compiler-builtins/libm/Cargo.toml @@ -43,6 +43,7 @@ unstable-float = [] force-soft-floats = [] [dev-dependencies] +# FIXME(msrv): switch to `no-panic.workspace` when possible no-panic = "0.1.35" [lints.rust] From 7c9ae5b0213393660abe57add8d4b34c90c3430f Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 7 Feb 2026 06:48:37 -0600 Subject: [PATCH 3365/3801] meta: Sort Cargo.toml `[features]` table after `[dependencies]` --- .../compiler-builtins/crates/util/Cargo.toml | 12 ++--- .../compiler-builtins/libm-test/Cargo.toml | 44 +++++++++---------- library/compiler-builtins/libm/Cargo.toml | 8 ++-- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/library/compiler-builtins/crates/util/Cargo.toml b/library/compiler-builtins/crates/util/Cargo.toml index 88e0b332065d..c56e2cc12ea5 100644 --- a/library/compiler-builtins/crates/util/Cargo.toml +++ b/library/compiler-builtins/crates/util/Cargo.toml @@ -5,15 +5,15 @@ edition = "2024" publish = false license = "MIT OR Apache-2.0" -[features] -default = ["build-musl", "build-mpfr", "unstable-float"] -build-musl = ["libm-test/build-musl", "dep:musl-math-sys"] -build-mpfr = ["libm-test/build-mpfr", "dep:rug"] -unstable-float = ["libm/unstable-float", "libm-test/unstable-float", "rug?/nightly-float"] - [dependencies] libm.workspace = true libm-macros.workspace = true libm-test.workspace = true musl-math-sys = { workspace = true, optional = true } rug = { workspace = true, optional = true } + +[features] +default = ["build-musl", "build-mpfr", "unstable-float"] +build-musl = ["libm-test/build-musl", "dep:musl-math-sys"] +build-mpfr = ["libm-test/build-mpfr", "dep:rug"] +unstable-float = ["libm/unstable-float", "libm-test/unstable-float", "rug?/nightly-float"] diff --git a/library/compiler-builtins/libm-test/Cargo.toml b/library/compiler-builtins/libm-test/Cargo.toml index c395d6a21bd5..4f65504bd584 100644 --- a/library/compiler-builtins/libm-test/Cargo.toml +++ b/library/compiler-builtins/libm-test/Cargo.toml @@ -5,28 +5,6 @@ edition = "2024" publish = false license = "MIT OR Apache-2.0" -[features] -default = ["build-mpfr", "unstable-float"] - -# Propagated from libm because this affects which functions we test. -unstable-float = ["libm/unstable-float", "rug?/nightly-float"] - -# Generate tests which are random inputs and the outputs are calculated with -# musl libc. -build-mpfr = ["dep:rug", "dep:gmp-mpfr-sys"] - -# Build our own musl for testing and benchmarks -build-musl = ["dep:musl-math-sys"] - -# Enable report generation without bringing in more dependencies by default -benchmarking-reports = ["criterion/plotters", "criterion/html_reports"] - -# Enable icount benchmarks (requires gungraun-runner and valgrind locally) -icount = ["dep:gungraun"] - -# Run with a reduced set of benchmarks, such as for CI -short-benchmarks = [] - [dependencies] anyhow.workspace = true # This is not directly used but is required so we can enable `gmp-mpfr-sys/force-cross`. @@ -52,6 +30,28 @@ rand = { workspace = true, optional = true } criterion.workspace = true libtest-mimic.workspace = true +[features] +default = ["build-mpfr", "unstable-float"] + +# Propagated from libm because this affects which functions we test. +unstable-float = ["libm/unstable-float", "rug?/nightly-float"] + +# Generate tests which are random inputs and the outputs are calculated with +# musl libc. +build-mpfr = ["dep:rug", "dep:gmp-mpfr-sys"] + +# Build our own musl for testing and benchmarks +build-musl = ["dep:musl-math-sys"] + +# Enable report generation without bringing in more dependencies by default +benchmarking-reports = ["criterion/plotters", "criterion/html_reports"] + +# Enable icount benchmarks (requires gungraun-runner and valgrind locally) +icount = ["dep:gungraun"] + +# Run with a reduced set of benchmarks, such as for CI +short-benchmarks = [] + [[bench]] name = "icount" harness = false diff --git a/library/compiler-builtins/libm/Cargo.toml b/library/compiler-builtins/libm/Cargo.toml index 617914a4dfae..d80ddab0ab7a 100644 --- a/library/compiler-builtins/libm/Cargo.toml +++ b/library/compiler-builtins/libm/Cargo.toml @@ -15,6 +15,10 @@ license = "MIT" edition = "2021" rust-version = "1.63" +[dev-dependencies] +# FIXME(msrv): switch to `no-panic.workspace` when possible +no-panic = "0.1.35" + [features] default = ["arch"] @@ -42,10 +46,6 @@ unstable-float = [] # hard float operations. force-soft-floats = [] -[dev-dependencies] -# FIXME(msrv): switch to `no-panic.workspace` when possible -no-panic = "0.1.35" - [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = [ # compiler-builtins sets this feature, but we use it in `libm` From da421f55850b5f7ef7e560ec8e52b41c39ff03be Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 27 Jan 2026 23:54:24 +0300 Subject: [PATCH 3366/3801] =?UTF-8?q?`const=20{=20'=CE=A3'.len=5Futf8()=20?= =?UTF-8?q?}`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/alloc/src/str.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index e772ac25a95c..8a3326c7d76a 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -411,9 +411,8 @@ impl str { fn map_uppercase_sigma(from: &str, i: usize) -> char { // See https://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 // for the definition of `Final_Sigma`. - debug_assert!('Σ'.len_utf8() == 2); let is_word_final = case_ignorable_then_cased(from[..i].chars().rev()) - && !case_ignorable_then_cased(from[i + 2..].chars()); + && !case_ignorable_then_cased(from[i + const { 'Σ'.len_utf8() }..].chars()); if is_word_final { 'ς' } else { 'σ' } } From 03dcd99aa322a0d5c9b5f203b1222798bbabf941 Mon Sep 17 00:00:00 2001 From: ia0 Date: Sat, 7 Feb 2026 15:39:42 +0100 Subject: [PATCH 3367/3801] Format heterogeneous try blocks --- src/tools/rustfmt/src/expr.rs | 29 +++++++++++++-- .../tests/source/try_blocks_heterogeneous.rs | 34 ++++++++++++++++++ .../tests/target/try_blocks_heterogeneous.rs | 36 +++++++++++++++++++ 3 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs create mode 100644 src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index de96f004dc87..70bce1920047 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -385,8 +385,33 @@ pub(crate) fn format_expr( )) } } - // FIXME: heterogeneous try blocks, which include a type so are harder to format - ast::ExprKind::TryBlock(_, Some(_)) => Err(RewriteError::Unknown), + ast::ExprKind::TryBlock(ref block, Some(ref ty)) => { + let keyword = "try bikeshed "; + // 2 = " {".len() + let ty_shape = shape + .shrink_left(keyword.len()) + .and_then(|shape| shape.sub_width(2)) + .max_width_error(shape.width, expr.span)?; + let ty_str = ty.rewrite_result(context, ty_shape)?; + let prefix = format!("{keyword}{ty_str} "); + if let rw @ Ok(_) = + rewrite_single_line_block(context, &prefix, block, Some(&expr.attrs), None, shape) + { + rw + } else { + let budget = shape.width.saturating_sub(prefix.len()); + Ok(format!( + "{prefix}{}", + rewrite_block( + block, + Some(&expr.attrs), + None, + context, + Shape::legacy(budget, shape.indent) + )? + )) + } + } ast::ExprKind::Gen(capture_by, ref block, ref kind, _) => { let mover = if matches!(capture_by, ast::CaptureBy::Value { .. }) { "move " diff --git a/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs b/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs new file mode 100644 index 000000000000..bae0060374d8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs @@ -0,0 +1,34 @@ +// rustfmt-edition: 2018 + +fn main() -> Result<(), !> { + let _x = try bikeshed Option<_> { + 4 + }; + + try bikeshed Result<_, _> {} +} + +fn baz() -> Option { + if (1 == 1) { + return try bikeshed Option { + 5 + }; + } + + // test + let x = try bikeshed Option<()> { + // try blocks are great + }; + + let y = try bikeshed Option { + 6 + }; // comment + + let x = try bikeshed Option { baz()?; baz()?; baz()?; 7 }; + + let x = try bikeshed Foo { 1 + 1 + 1 }; + + let x = try bikeshed Foo {}; + + return None; +} diff --git a/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs b/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs new file mode 100644 index 000000000000..6f910ed5d051 --- /dev/null +++ b/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs @@ -0,0 +1,36 @@ +// rustfmt-edition: 2018 + +fn main() -> Result<(), !> { + let _x = try bikeshed Option<_> { 4 }; + + try bikeshed Result<_, _> {} +} + +fn baz() -> Option { + if (1 == 1) { + return try bikeshed Option { 5 }; + } + + // test + let x = try bikeshed Option<()> { + // try blocks are great + }; + + let y = try bikeshed Option { 6 }; // comment + + let x = try bikeshed Option { + baz()?; + baz()?; + baz()?; + 7 + }; + + let x = try bikeshed Foo { + 1 + 1 + 1 + }; + + let x = + try bikeshed Foo {}; + + return None; +} From 1ec5101f20cfffb67557692a5ec647133e2bcd19 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 7 Feb 2026 07:06:05 -0600 Subject: [PATCH 3368/3801] Bump the libm MSRV to 1.67 This gets us: * `saturating_sub_unsigned` * `::ilog2` * Correct lexing of float literals with the `f16` or `f128` suffix Link: https://github.com/rust-lang/compiler-builtins/issues/1017 --- library/compiler-builtins/libm/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/libm/Cargo.toml b/library/compiler-builtins/libm/Cargo.toml index d80ddab0ab7a..98202d1977dc 100644 --- a/library/compiler-builtins/libm/Cargo.toml +++ b/library/compiler-builtins/libm/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["libm", "math"] repository = "https://github.com/rust-lang/compiler-builtins" license = "MIT" edition = "2021" -rust-version = "1.63" +rust-version = "1.67" [dev-dependencies] # FIXME(msrv): switch to `no-panic.workspace` when possible From 3d0989266de7d312a17ffac4e8251eb7a710358f Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 7 Feb 2026 07:06:05 -0600 Subject: [PATCH 3369/3801] cleanup: Perform some simplifications possible with the MSRV bump --- .../libm/src/math/generic/sqrt.rs | 4 +-- .../libm/src/math/support/float_traits.rs | 7 +---- .../libm/src/math/support/hex_float.rs | 28 +------------------ 3 files changed, 3 insertions(+), 36 deletions(-) diff --git a/library/compiler-builtins/libm/src/math/generic/sqrt.rs b/library/compiler-builtins/libm/src/math/generic/sqrt.rs index 9481c4cdb7bb..e97a43d34956 100644 --- a/library/compiler-builtins/libm/src/math/generic/sqrt.rs +++ b/library/compiler-builtins/libm/src/math/generic/sqrt.rs @@ -419,9 +419,7 @@ mod tests { fn conformance_tests_f16() { let cases = [ (f16::PI, 0x3f17_u16), - // 10_000.0, using a hex literal for MSRV hack (Rust < 1.67 checks literal widths as - // part of the AST, so the `cfg` is irrelevant here). - (f16::from_bits(0x70e2), 0x5640_u16), + (10000.0_f16, 0x5640_u16), (f16::from_bits(0x0000000f), 0x13bf_u16), (f16::INFINITY, f16::INFINITY.to_bits()), ]; diff --git a/library/compiler-builtins/libm/src/math/support/float_traits.rs b/library/compiler-builtins/libm/src/math/support/float_traits.rs index 4e5011f62e0f..60c8bfca5165 100644 --- a/library/compiler-builtins/libm/src/math/support/float_traits.rs +++ b/library/compiler-builtins/libm/src/math/support/float_traits.rs @@ -1,5 +1,3 @@ -#![allow(unknown_lints)] // FIXME(msrv) we shouldn't need this - use core::{fmt, mem, ops}; use super::int_traits::{CastFrom, Int, MinInt}; @@ -289,10 +287,7 @@ macro_rules! float_impl { cfg_if! { // fma is not yet available in `core` if #[cfg(intrinsics_enabled)] { - // FIXME(msrv,bench): once our benchmark rustc version is above the - // 2022-09-23 nightly, this can be removed. - #[allow(unused_unsafe)] - unsafe { core::intrinsics::$fma_intrinsic(self, y, z) } + core::intrinsics::$fma_intrinsic(self, y, z) } else { super::super::$fma_fn(self, y, z) } diff --git a/library/compiler-builtins/libm/src/math/support/hex_float.rs b/library/compiler-builtins/libm/src/math/support/hex_float.rs index c8558b90053d..2f9369e50441 100644 --- a/library/compiler-builtins/libm/src/math/support/hex_float.rs +++ b/library/compiler-builtins/libm/src/math/support/hex_float.rs @@ -121,7 +121,7 @@ const fn parse_finite( Ok(Parsed { sig, exp }) => (sig, exp), }; - let mut round_bits = u128_ilog2(sig) as i32 - sig_bits as i32; + let mut round_bits = sig.ilog2() as i32 - sig_bits as i32; // Round at least up to min_lsb if exp < min_lsb - round_bits { @@ -299,29 +299,11 @@ const fn parse_hex(mut b: &[u8]) -> Result { )); }; - { - let e; - if negate_exp { - e = (exp as i64) - (pexp as i64); - } else { - e = (exp as i64) + (pexp as i64); - }; - - exp = if e < i32::MIN as i64 { - i32::MIN - } else if e > i32::MAX as i64 { - i32::MAX - } else { - e as i32 - }; - } - /* FIXME(msrv): once MSRV >= 1.66, replace the above workaround block with: if negate_exp { exp = exp.saturating_sub_unsigned(pexp); } else { exp = exp.saturating_add_unsigned(pexp); }; - */ Ok(Parsed { sig, exp }) } @@ -342,14 +324,6 @@ const fn hex_digit(c: u8) -> Option { } } -/* FIXME(msrv): vendor some things that are not const stable at our MSRV */ - -/// `u128::ilog2` -const fn u128_ilog2(v: u128) -> u32 { - assert!(v != 0); - u128::BITS - 1 - v.leading_zeros() -} - #[cfg(any(test, feature = "unstable-public-internals"))] mod hex_fmt { use core::fmt; From cf1a784f3f2643bb5afb0fa7e1944c8748a0fefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 17:21:25 +0100 Subject: [PATCH 3370/3801] Port rustc_regions to the new attribute parser --- .../src/attributes/rustc_internal.rs | 16 ++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_borrowck/src/nll.rs | 5 +++-- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 3b7d25b43ba2..526d5ec1e1dc 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -219,6 +219,22 @@ impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintQueryInstability; } +pub(crate) struct RustcRegionsParser; + +impl NoArgsAttributeParser for RustcRegionsParser { + const PATH: &[Symbol] = &[sym::rustc_regions]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcRegions; +} + pub(crate) struct RustcLintUntrackedQueryInformationParser; impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 5b489d306499..3c49c272c121 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -276,6 +276,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 64e3b59acfff..ee32d64e9958 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -7,6 +7,8 @@ use std::str::FromStr; use polonius_engine::{Algorithm, AllFacts, Output}; use rustc_data_structures::frozen::Frozen; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; use rustc_index::IndexSlice; use rustc_middle::mir::pretty::PrettyPrintMirOptions; use rustc_middle::mir::{Body, MirDumper, PassWhere, Promoted}; @@ -15,7 +17,6 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_session::config::MirIncludeSpans; -use rustc_span::sym; use tracing::{debug, instrument}; use crate::borrow_set::BorrowSet; @@ -295,7 +296,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( ) { let tcx = infcx.tcx; let base_def_id = tcx.typeck_root_def_id(body.source.def_id()); - if !tcx.has_attr(base_def_id, sym::rustc_regions) { + if !find_attr!(tcx.get_all_attrs(base_def_id), AttributeKind::RustcRegions) { return; } diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index fa781a74c9e2..2bbb19e0d10f 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1198,6 +1198,9 @@ pub enum AttributeKind { /// Represents `#[rustc_reallocator]` RustcReallocator, + /// Represents `#[rustc_regions]` + RustcRegions, + /// Represents `#[rustc_scalable_vector(N)]` RustcScalableVector { /// The base multiple of lanes that are in a scalable vector, if provided. `element_count` diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 14b54c129d3e..ee4915eec649 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -144,6 +144,7 @@ impl AttributeKind { RustcPreserveUbChecks => No, RustcPubTransparent(..) => Yes, RustcReallocator => No, + RustcRegions => No, RustcScalableVector { .. } => Yes, RustcShouldNotBeCalledOnConstItems(..) => Yes, RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 680a93908354..292db8e1b684 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -335,6 +335,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) | AttributeKind::RustcPreserveUbChecks | AttributeKind::RustcReallocator + | AttributeKind::RustcRegions | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcShouldNotBeCalledOnConstItems(..) | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) @@ -401,7 +402,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_never_type_options | sym::rustc_autodiff | sym::rustc_capture_analysis - | sym::rustc_regions | sym::rustc_strict_coherence | sym::rustc_mir | sym::rustc_outlives From 85ca098f55cade17d59dd625d2e9af724a73a33b Mon Sep 17 00:00:00 2001 From: Usman Akinyemi Date: Sun, 1 Feb 2026 22:34:22 +0530 Subject: [PATCH 3371/3801] rustc_parse: improve the error diagnostic for "missing let" Signed-off-by: Usman Akinyemi --- compiler/rustc_parse/src/errors.rs | 18 ++++++++++ compiler/rustc_parse/src/parser/expr.rs | 47 ++++++++++++++++++++++++- tests/ui/missing/missing-let.rs | 12 +++++++ tests/ui/missing/missing-let.stderr | 28 +++++++++++++-- 4 files changed, 102 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 418d56f632bd..aafe585a4649 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -573,6 +573,24 @@ pub(crate) struct ExpectedExpressionFoundLet { pub comparison: Option, } +#[derive(Diagnostic)] +#[diag("let-chain with missing `let`")] +pub(crate) struct LetChainMissingLet { + #[primary_span] + pub span: Span, + #[label("expected `let` expression, found assignment")] + pub label_span: Span, + #[label("let expression later in the condition")] + pub rhs_span: Span, + #[suggestion( + "add `let` before the expression", + applicability = "maybe-incorrect", + code = "let ", + style = "verbose" + )] + pub sug_span: Span, +} + #[derive(Diagnostic)] #[diag("`||` operators are not supported in let chain conditions")] pub(crate) struct OrInLetChain { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 8bb22c2a831b..05216be06ff5 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -4282,7 +4282,52 @@ impl MutVisitor for CondChecker<'_> { mut_visit::walk_expr(self, e); self.forbid_let_reason = forbid_let_reason; } - ExprKind::Assign(ref lhs, _, span) => { + ExprKind::Assign(ref lhs, ref rhs, span) => { + if let ExprKind::Call(_, _) = &lhs.kind { + fn get_path_from_rhs(e: &Expr) -> Option<(u32, &Path)> { + fn inner(e: &Expr, depth: u32) -> Option<(u32, &Path)> { + match &e.kind { + ExprKind::Binary(_, lhs, _) => inner(lhs, depth + 1), + ExprKind::Path(_, path) => Some((depth, path)), + _ => None, + } + } + + inner(e, 0) + } + + if let Some((depth, path)) = get_path_from_rhs(rhs) { + // For cases like if Some(_) = x && let Some(_) = y && let Some(_) = z + // This return let Some(_) = y expression + fn find_let_some(expr: &Expr) -> Option<&Expr> { + match &expr.kind { + ExprKind::Let(..) => Some(expr), + + ExprKind::Binary(op, lhs, rhs) if op.node == BinOpKind::And => { + find_let_some(lhs).or_else(|| find_let_some(rhs)) + } + + _ => None, + } + } + + let expr_span = lhs.span.to(path.span); + + if let Some(later_rhs) = find_let_some(rhs) + && depth > 0 + { + let guar = self.parser.dcx().emit_err(errors::LetChainMissingLet { + span: lhs.span, + label_span: expr_span, + rhs_span: later_rhs.span, + sug_span: lhs.span.shrink_to_lo(), + }); + + self.found_incorrect_let_chain = Some(guar); + } + } + } + let forbid_let_reason = self.forbid_let_reason; self.forbid_let_reason = Some(errors::ForbiddenLetReason::OtherForbidden); let missing_let = self.missing_let; diff --git a/tests/ui/missing/missing-let.rs b/tests/ui/missing/missing-let.rs index 36db7bc95826..595de640470b 100644 --- a/tests/ui/missing/missing-let.rs +++ b/tests/ui/missing/missing-let.rs @@ -1,6 +1,18 @@ fn main() { let x = Some(42); + let y = Some(42); + let z = Some(42); if let Some(_) = x && Some(x) = x //~^ ERROR expected expression, found `let` statement + //~| NOTE: only supported directly in conditions of `if` and `while` expressions + {} + + if Some(_) = y && + //~^ NOTE expected `let` expression, found assignment + //~| ERROR let-chain with missing `let` + let Some(_) = z + //~^ ERROR: expected expression, found `let` statement + //~| NOTE: let expression later in the condition + //~| NOTE: only supported directly in conditions of `if` and `while` expressions {} } diff --git a/tests/ui/missing/missing-let.stderr b/tests/ui/missing/missing-let.stderr index 897ff6329d59..0a6e76b154f7 100644 --- a/tests/ui/missing/missing-let.stderr +++ b/tests/ui/missing/missing-let.stderr @@ -1,5 +1,5 @@ error: expected expression, found `let` statement - --> $DIR/missing-let.rs:3:8 + --> $DIR/missing-let.rs:5:8 | LL | if let Some(_) = x | ^^^^^^^^^^^^^^^ @@ -14,5 +14,29 @@ help: you might have meant to compare for equality LL | && Some(x) == x | + -error: aborting due to 1 previous error +error: expected expression, found `let` statement + --> $DIR/missing-let.rs:13:9 + | +LL | let Some(_) = z + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: let-chain with missing `let` + --> $DIR/missing-let.rs:10:8 + | +LL | if Some(_) = y && + | ^^^^^^^---- + | | + | expected `let` expression, found assignment +... +LL | let Some(_) = z + | --------------- let expression later in the condition + | +help: add `let` before the expression + | +LL | if let Some(_) = y && + | +++ + +error: aborting due to 3 previous errors From c814f76c0680cb073941c19e8750d859be7e6393 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 14:58:56 +0100 Subject: [PATCH 3372/3801] Convert to inline diagnostics in `rustc_lint` --- Cargo.lock | 1 - compiler/rustc_driver_impl/src/lib.rs | 6 +- compiler/rustc_lint/Cargo.toml | 1 - compiler/rustc_lint/messages.ftl | 1088 ----------- compiler/rustc_lint/src/async_closures.rs | 8 +- compiler/rustc_lint/src/builtin.rs | 15 +- compiler/rustc_lint/src/errors.rs | 41 +- compiler/rustc_lint/src/if_let_rescope.rs | 23 +- .../rustc_lint/src/impl_trait_overcaptures.rs | 26 +- compiler/rustc_lint/src/levels.rs | 7 +- compiler/rustc_lint/src/lib.rs | 2 - compiler/rustc_lint/src/lints.rs | 1740 +++++++++++------ compiler/rustc_lint/src/non_fmt_panic.rs | 23 +- compiler/rustc_lint/src/non_local_def.rs | 11 +- .../src/opaque_hidden_inferred_bound.rs | 6 +- compiler/rustc_lint/src/transmute.rs | 10 +- .../rustc_lint/src/types/improper_ctypes.rs | 112 +- 17 files changed, 1307 insertions(+), 1813 deletions(-) delete mode 100644 compiler/rustc_lint/messages.ftl diff --git a/Cargo.lock b/Cargo.lock index 7a8e06e5ba93..03cf3bcba894 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4143,7 +4143,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 315b11056085..d72913764e9d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -111,11 +111,7 @@ pub fn default_translator() -> Translator { Translator::with_fallback_bundle(DEFAULT_LOCALE_RESOURCES.to_vec(), false) } -pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ - // tidy-alphabetical-start - rustc_lint::DEFAULT_LOCALE_RESOURCE, - // tidy-alphabetical-end -]; +pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[]; /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index 035d8b4903fa..758d2762a6af 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -14,7 +14,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl deleted file mode 100644 index ff771532ae49..000000000000 --- a/compiler/rustc_lint/messages.ftl +++ /dev/null @@ -1,1088 +0,0 @@ -lint_abs_path_with_module = absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition - .suggestion = use `crate` - -lint_ambiguous_glob_reexport = ambiguous glob re-exports - .label_first_reexport = the name `{$name}` in the {$namespace} namespace is first re-exported here - .label_duplicate_reexport = but the name `{$name}` in the {$namespace} namespace is also re-exported here - -lint_ambiguous_negative_literals = `-` has lower precedence than method calls, which might be unexpected - .example = e.g. `-4.abs()` equals `-4`; while `(-4).abs()` equals `4` - .negative_literal = add parentheses around the `-` and the literal to call the method on a negative literal - .current_behavior = add parentheses around the literal and the method call to keep the current behavior - -lint_ambiguous_wide_pointer_comparisons = ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - .addr_metadata_suggestion = use explicit `std::ptr::eq` method to compare metadata and addresses - .addr_suggestion = use `std::ptr::addr_eq` or untyped pointers to only compare their addresses - .cast_suggestion = use untyped pointers to only compare their addresses - .expect_suggestion = or expect the lint to compare the pointers metadata and addresses - -lint_associated_const_elided_lifetime = {$elided -> - [true] `&` without an explicit lifetime name cannot be used here - *[false] `'_` cannot be used here - } - .suggestion = use the `'static` lifetime - .note = cannot automatically infer `'static` because of other lifetimes in scope - -lint_async_fn_in_trait = use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified - .note = you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future` - .suggestion = you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change - -lint_atomic_ordering_fence = memory fences cannot have `Relaxed` ordering - .help = consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst` - -lint_atomic_ordering_invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write - .label = invalid failure ordering - .help = consider using `Acquire` or `Relaxed` failure ordering instead - -lint_atomic_ordering_load = atomic loads cannot have `Release` or `AcqRel` ordering - .help = consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` - -lint_atomic_ordering_store = atomic stores cannot have `Acquire` or `AcqRel` ordering - .help = consider using ordering modes `Release`, `SeqCst` or `Relaxed` - -lint_attr_crate_level = - this attribute can only be applied at the crate level - .suggestion = to apply to the crate, use an inner attribute - .note = read for more information - -lint_bad_attribute_argument = bad attribute argument - -lint_bad_opt_access = {$msg} - -lint_break_with_label_and_loop = this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression - .suggestion = wrap this expression in parentheses - -lint_builtin_allow_internal_unsafe = - `allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site - -lint_builtin_anonymous_params = anonymous parameters are deprecated and will be removed in the next edition - .suggestion = try naming the parameter or explicitly ignoring it - -lint_builtin_clashing_extern_diff_name = `{$this}` redeclares `{$orig}` with a different signature - .previous_decl_label = `{$orig}` previously declared here - .mismatch_label = this signature doesn't match the previous declaration - -lint_builtin_clashing_extern_same_name = `{$this}` redeclared with a different signature - .previous_decl_label = `{$orig}` previously declared here - .mismatch_label = this signature doesn't match the previous declaration -lint_builtin_const_no_mangle = const items should never be `#[no_mangle]` - .suggestion = try a static value - -lint_builtin_decl_unsafe_fn = declaration of an `unsafe` function -lint_builtin_decl_unsafe_method = declaration of an `unsafe` method - -lint_builtin_deref_nullptr = dereferencing a null pointer - .label = this code causes undefined behavior when executed - -lint_builtin_double_negations = use of a double negation - .note = the prefix `--` could be misinterpreted as a decrement operator which exists in other languages - .note_decrement = use `-= 1` if you meant to decrement the value - .add_parens_suggestion = add parentheses for clarity - -lint_builtin_ellipsis_inclusive_range_patterns = `...` range patterns are deprecated - .suggestion = use `..=` for an inclusive range - -lint_builtin_explicit_outlives = outlives requirements can be inferred - .suggestion = remove {$count -> - [one] this bound - *[other] these bounds - } - -lint_builtin_export_name_fn = declaration of a function with `export_name` -lint_builtin_export_name_method = declaration of a method with `export_name` -lint_builtin_export_name_static = declaration of a static with `export_name` - -lint_builtin_global_asm = usage of `core::arch::global_asm` -lint_builtin_global_macro_unsafety = using this macro is unsafe even though it does not need an `unsafe` block - -lint_builtin_impl_unsafe_method = implementation of an `unsafe` method - -lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes - .note = see issue #{$n} for more information - .help = consider using `min_{$name}` instead, which is more stable and complete - -lint_builtin_internal_features = the feature `{$name}` is internal to the compiler or standard library - .note = using it is strongly discouraged - -lint_builtin_keyword_idents = `{$kw}` is a keyword in the {$next} edition - .suggestion = you can use a raw identifier to stay compatible - -lint_builtin_link_section_fn = declaration of a function with `link_section` - -lint_builtin_link_section_static = declaration of a static with `link_section` - -lint_builtin_missing_copy_impl = type could implement `Copy`; consider adding `impl Copy` - -lint_builtin_missing_debug_impl = - type does not implement `{$debug}`; consider adding `#[derive(Debug)]` or a manual implementation - -lint_builtin_missing_doc = missing documentation for {$article} {$desc} - -lint_builtin_mutable_transmutes = - transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell - -lint_builtin_no_mangle_fn = declaration of a `no_mangle` function -lint_builtin_no_mangle_generic = functions generic over types or consts must be mangled - .suggestion = remove this attribute - -lint_builtin_no_mangle_method = declaration of a `no_mangle` method -lint_builtin_no_mangle_static = declaration of a `no_mangle` static -lint_builtin_non_shorthand_field_patterns = the `{$ident}:` in this pattern is redundant - .suggestion = use shorthand field pattern - -lint_builtin_overridden_symbol_name = - the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them - -lint_builtin_overridden_symbol_section = - the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them - -lint_builtin_special_module_name_used_lib = found module declaration for lib.rs - .note = lib.rs is the root of this crate's library target - .help = to refer to it from other targets, use the library's name as the path - -lint_builtin_special_module_name_used_main = found module declaration for main.rs - .note = a binary crate cannot be used as library - -lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters - -lint_builtin_type_alias_bounds_enable_feat_help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -lint_builtin_type_alias_bounds_label = will not be checked at usage sites of the type alias -lint_builtin_type_alias_bounds_limitation_note = this is a known limitation of the type checker that may be lifted in a future edition. - see issue #112792 for more information -lint_builtin_type_alias_bounds_param_bounds = bounds on generic parameters in type aliases are not enforced - .suggestion = remove {$count -> - [one] this bound - *[other] these bounds - } -lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg = fully qualify this associated type -lint_builtin_type_alias_bounds_where_clause = where clauses on type aliases are not enforced - .suggestion = remove this where clause - -lint_builtin_unpermitted_type_init_label = this code causes undefined behavior when executed -lint_builtin_unpermitted_type_init_label_suggestion = help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - -lint_builtin_unpermitted_type_init_uninit = the type `{$ty}` does not permit being left uninitialized - -lint_builtin_unpermitted_type_init_zeroed = the type `{$ty}` does not permit zero-initialization -lint_builtin_unreachable_pub = unreachable `pub` {$what} - .suggestion = consider restricting its visibility - .help = or consider exporting it for use by other crates - -lint_builtin_unsafe_block = usage of an `unsafe` block - -lint_builtin_unsafe_extern_block = usage of an `unsafe extern` block - -lint_builtin_unsafe_impl = implementation of an `unsafe` trait - -lint_builtin_unsafe_trait = declaration of an `unsafe` trait - -lint_builtin_unstable_features = use of an unstable feature - -lint_builtin_unused_doc_comment = unused doc comment - .label = rustdoc does not generate documentation for {$kind} - .plain_help = use `//` for a plain comment - .block_help = use `/* */` for a plain comment - -lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}` - .suggestion = use `loop` - -lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}` - -lint_closure_returning_async_block = closure returning async block can be made into an async closure - .label = this async block can be removed, and the closure can be turned into an async closure - .suggestion = turn this into an async closure - -lint_command_line_source = `forbid` lint level was set on command line - -lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike - .current_use = this identifier can be confused with `{$existing_sym}` - .other_use = other identifier used here - -lint_const_item_interior_mutations = - mutation of an interior mutable `const` item with call to `{$method_name}` - .label = `{$const_name}` is a interior mutable `const` item of type `{$const_ty}` - .temporary = each usage of a `const` item creates a new temporary - .never_original = only the temporaries and never the original `const {$const_name}` will be modified - .suggestion_static = for a shared instance of `{$const_name}`, consider making it a `static` item instead - .help = for more details on interior mutability see - -lint_dangling_pointers_from_locals = {$fn_kind} returns a dangling pointer to dropped local variable `{$local_var_name}` - .ret_ty = return type is `{$ret_ty}` - .local_var = local variable `{$local_var_name}` is dropped at the end of the {$fn_kind} - .created_at = dangling pointer created here - .note_safe = a dangling pointer is safe, but dereferencing one is undefined behavior - .note_more_info = for more information, see - -lint_dangling_pointers_from_temporaries = this creates a dangling pointer because temporary `{$ty}` is dropped at end of statement - .label_ptr = pointer created here - .label_temporary = this `{$ty}` is dropped at end of statement - .help_bind = bind the `{$ty}` to a variable such that it outlives the pointer returned by `{$callee}` - .note_safe = a dangling pointer is safe, but dereferencing one is undefined behavior - .note_return = returning a pointer to a local variable will always result in a dangling pointer - .note_more_info = for more information, see - - -lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance - .note = a `use rustc_data_structures::fx::{$preferred}` may be necessary - -lint_default_source = `forbid` lint level is the default for {$id} - -lint_deprecated_lint_name = - lint name `{$name}` is deprecated and may not have an effect in the future - .suggestion = change it to - .help = change it to {$replace} - -lint_deprecated_where_clause_location = where clause not allowed here - .note = see issue #89122 for more information - .suggestion_move_to_end = move it to the end of the type declaration - .suggestion_remove_where = remove this `where` - -lint_doc_alias_duplicated = doc alias is duplicated - .label = first defined here - -lint_doc_auto_cfg_expects_hide_or_show = - only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` - -lint_doc_auto_cfg_hide_show_expects_list = - `#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items - -lint_doc_auto_cfg_hide_show_unexpected_item = - `#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items - -lint_doc_auto_cfg_wrong_literal = - expected boolean for `#[doc(auto_cfg = ...)]` - -lint_doc_invalid = - invalid `doc` attribute - -lint_doc_test_literal = `#![doc(test(...)]` does not take a literal - -lint_doc_test_takes_list = - `#[doc(test(...)]` takes a list of attributes - -lint_doc_test_unknown = - unknown `doc(test)` attribute `{$name}` - -lint_doc_unknown_any = - unknown `doc` attribute `{$name}` - -lint_doc_unknown_include = - unknown `doc` attribute `include` - .suggestion = use `doc = include_str!` instead - -lint_doc_unknown_passes = - unknown `doc` attribute `{$name}` - .note = `doc` attribute `{$name}` no longer functions; see issue #44136 - .label = no longer functions - .no_op_note = `doc({$name})` is now a no-op - -lint_doc_unknown_plugins = - unknown `doc` attribute `plugins` - .note = `doc` attribute `plugins` no longer functions; see issue #44136 and CVE-2018-1000622 - .label = no longer functions - .no_op_note = `doc(plugins)` is now a no-op - -lint_doc_unknown_spotlight = - unknown `doc` attribute `spotlight` - .note = `doc(spotlight)` was renamed to `doc(notable_trait)` - .suggestion = use `notable_trait` instead - .no_op_note = `doc(spotlight)` is now a no-op - - -lint_drop_glue = - types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped - -lint_drop_trait_constraints = - bounds on `{$predicate}` are most likely incorrect, consider instead using `{$needs_drop}` to detect whether a type can be trivially dropped - -lint_dropping_copy_types = calls to `std::mem::drop` with a value that implements `Copy` does nothing - .label = argument has type `{$arg_ty}` - -lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing - .label = argument has type `{$arg_ty}` - -lint_empty_attribute = - unused attribute - .suggestion = {$valid_without_list -> - [true] remove these parentheses - *[other] remove this attribute - } - .note = {$valid_without_list -> - [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all - *[other] using `{$attr_path}` with an empty list has no effect - } - --lint_previously_accepted = - this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -lint_enum_intrinsics_mem_discriminant = - the return value of `mem::discriminant` is unspecified when called with a non-enum type - .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum - -lint_enum_intrinsics_mem_variant = - the return value of `mem::variant_count` is unspecified when called with a non-enum type - .note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum - -lint_expectation = this lint expectation is unfulfilled - .note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message - .rationale = {$rationale} - -lint_expected_name_value = - expected this to be of the form `... = "..."` - .warn = {-lint_previously_accepted} - -lint_expected_no_args = - didn't expect any arguments here - .warn = {-lint_previously_accepted} - -lint_for_loops_over_fallibles = - for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement - .suggestion = consider using `if let` to clear intent - .remove_next = to iterate over `{$recv_snip}` remove the call to `next` - .use_while_let = to check pattern in a loop use `while let` - .use_question_mark = consider unwrapping the `Result` with `?` to iterate over its contents - -lint_forgetting_copy_types = calls to `std::mem::forget` with a value that implements `Copy` does nothing - .label = argument has type `{$arg_ty}` - -lint_forgetting_references = calls to `std::mem::forget` with a reference instead of an owned value does nothing - .label = argument has type `{$arg_ty}` - -lint_function_casts_as_integer = direct cast of function item into an integer - .cast_as_fn = first cast to a pointer `as *const ()` - -lint_hidden_glob_reexport = private item shadows public glob re-export - .note_glob_reexport = the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here - .note_private_item = but the private item here shadows it - -lint_hidden_lifetime_parameters = hidden lifetime parameters in types are deprecated - -lint_identifier_non_ascii_char = identifier contains non-ASCII characters - -lint_identifier_uncommon_codepoints = identifier contains {$codepoints_len -> - [one] { $identifier_type -> - [Exclusion] a character from an archaic script - [Technical] a character that is for non-linguistic, specialized usage - [Limited_Use] a character from a script in limited use - [Not_NFKC] a non normalized (NFKC) character - *[other] an uncommon character - } - *[other] { $identifier_type -> - [Exclusion] {$codepoints_len} characters from archaic scripts - [Technical] {$codepoints_len} characters that are for non-linguistic, specialized usage - [Limited_Use] {$codepoints_len} characters from scripts in limited use - [Not_NFKC] {$codepoints_len} non normalized (NFKC) characters - *[other] uncommon characters - } -}: {$codepoints} - .note = {$codepoints_len -> - [one] this character is - *[other] these characters are - } included in the{$identifier_type -> - [Restricted] {""} - *[other] {" "}{$identifier_type} - } Unicode general security profile - -lint_if_let_dtor = {$dtor_kind -> - [dyn] value may invoke a custom destructor because it contains a trait object - *[concrete] value invokes this custom destructor - } - -lint_if_let_rescope = `if let` assigns a shorter lifetime since Edition 2024 - .label = this value has a significant drop implementation which may observe a major change in drop order and requires your discretion - .help = the value is now dropped here in Edition 2024 - .suggestion = a `match` with a single arm can preserve the drop order up to Edition 2021 - -lint_ignored_unless_crate_specified = {$level}({$name}) is ignored unless specified at crate level - -lint_ill_formed_attribute_input = {$num_suggestions -> - [1] attribute must be of the form {$suggestions} - *[other] valid forms for the attribute are {$suggestions} - } - .note = for more information, visit <{$docs}> - -lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than possibly intended in edition 2024 - .note = specifically, {$num_captured -> - [one] this lifetime is - *[other] these lifetimes are - } in scope but not mentioned in the type's bounds - .note2 = all lifetimes in scope will be captured by `impl Trait`s in edition 2024 - -lint_impl_trait_redundant_captures = all possible in-scope parameters are already captured, so `use<...>` syntax is redundant - .suggestion = remove the `use<...>` syntax - -lint_implicit_sysroot_crate_import = dangerous use of `extern crate {$name}` which is not guaranteed to exist exactly once in the sysroot - .help = try using a cargo dependency or using a re-export of the dependency provided by a rustc_* crate - -lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dereference of a raw pointer - .note = creating a reference requires the pointer target to be valid and imposes aliasing requirements - .raw_ptr = this raw pointer has type `{$raw_ptr_ty}` - .autoref = autoref is being applied to this expression, resulting in: `{$autoref_ty}` - .overloaded_deref = references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations - .method_def = method calls to `{$method_name}` require a reference - .suggestion = try using a raw pointer method instead; or if this reference is intentional, make it explicit - -lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe - .label = not FFI-safe - .note = the type is defined here - -lint_improper_ctypes_array_help = consider passing a pointer to the array - -lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe -lint_improper_ctypes_box = box cannot be represented as a single pointer - -lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead - -lint_improper_ctypes_char_reason = the `char` type has no C equivalent - -lint_improper_ctypes_cstr_help = - consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()` -lint_improper_ctypes_cstr_reason = `CStr`/`CString` do not have a guaranteed layout - -lint_improper_ctypes_dyn = trait objects have no C equivalent - -lint_improper_ctypes_enum_repr_help = - consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum - -lint_improper_ctypes_enum_repr_reason = enum has no representation hint -lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead - -lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention -lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive -lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants - -lint_improper_ctypes_only_phantomdata = composed only of `PhantomData` - -lint_improper_ctypes_opaque = opaque types have no C equivalent - -lint_improper_ctypes_slice_help = consider using a raw pointer instead - -lint_improper_ctypes_slice_reason = slices have no C equivalent -lint_improper_ctypes_str_help = consider using `*const u8` and a length instead - -lint_improper_ctypes_str_reason = string slices have no C equivalent -lint_improper_ctypes_struct_fieldless_help = consider adding a member to this struct - -lint_improper_ctypes_struct_fieldless_reason = this struct has no fields -lint_improper_ctypes_struct_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct - -lint_improper_ctypes_struct_layout_reason = this struct has unspecified layout -lint_improper_ctypes_struct_non_exhaustive = this struct is non-exhaustive -lint_improper_ctypes_struct_zst = this struct contains only zero-sized fields - -lint_improper_ctypes_tuple_help = consider using a struct instead - -lint_improper_ctypes_tuple_reason = tuples have unspecified layout -lint_improper_ctypes_union_fieldless_help = consider adding a member to this union - -lint_improper_ctypes_union_fieldless_reason = this union has no fields -lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union - -lint_improper_ctypes_union_layout_reason = this union has unspecified layout -lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive - -lint_improper_ctypes_unsafe_binder = unsafe binders are incompatible with foreign function interfaces - -lint_improper_gpu_kernel_arg = passing type `{$ty}` to a function with "gpu-kernel" ABI may have unexpected behavior - .help = use primitive types and raw pointers to get reliable behavior - -lint_incorrect_do_not_recommend_args = - `#[diagnostic::do_not_recommend]` does not expect any arguments - -lint_int_to_ptr_transmutes = transmuting an integer to a pointer creates a pointer without provenance - .note = this is dangerous because dereferencing the resulting pointer is undefined behavior - .note_exposed_provenance = exposed provenance semantics can be used to create a pointer based on some previously exposed provenance - .help_transmute = for more information about transmute, see - .help_exposed_provenance = for more information about exposed provenance, see - .suggestion_with_exposed_provenance = use `std::ptr::with_exposed_provenance{$suffix}` instead to use a previously exposed provenance - .suggestion_without_provenance_mut = if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut` - -lint_invalid_asm_label_binary = avoid using labels containing only the digits `0` and `1` in inline assembly - .label = use a different label that doesn't start with `0` or `1` - .help = start numbering with `2` instead - .note1 = an LLVM bug makes these labels ambiguous with a binary literal number on x86 - .note2 = see for more information - -lint_invalid_asm_label_format_arg = avoid using named labels in inline assembly - .help = only local labels of the form `:` should be used in inline asm - .note1 = format arguments may expand to a non-numeric value - .note2 = see the asm section of Rust By Example for more information -lint_invalid_asm_label_named = avoid using named labels in inline assembly - .help = only local labels of the form `:` should be used in inline asm - .note = see the asm section of Rust By Example for more information -lint_invalid_asm_label_no_span = the label may be declared in the expansion of a macro - -lint_invalid_crate_type_value = invalid `crate_type` value - .suggestion = did you mean - -# FIXME: we should ordinalize $valid_up_to when we add support for doing so -lint_invalid_from_utf8_checked = calls to `{$method}` with an invalid literal always return an error - .label = the literal was valid UTF-8 up to the {$valid_up_to} bytes - -# FIXME: we should ordinalize $valid_up_to when we add support for doing so -lint_invalid_from_utf8_unchecked = calls to `{$method}` with an invalid literal are undefined behavior - .label = the literal was valid UTF-8 up to the {$valid_up_to} bytes - -lint_invalid_nan_comparisons_eq_ne = incorrect NaN comparison, NaN cannot be directly compared to itself - .suggestion = use `f32::is_nan()` or `f64::is_nan()` instead - -lint_invalid_nan_comparisons_lt_le_gt_ge = incorrect NaN comparison, NaN is not orderable - -lint_invalid_null_arguments = calling this function with a null pointer is undefined behavior, even if the result of the function is unused - .origin = null pointer originates from here - .doc = for more information, visit and - -lint_invalid_reference_casting_assign_to_ref = assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - .label = casting happened here - -lint_invalid_reference_casting_bigger_layout = casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused - .label = casting happened here - .alloc = backing allocation comes from here - .layout = casting from `{$from_ty}` ({$from_size} bytes) to `{$to_ty}` ({$to_size} bytes) - -lint_invalid_reference_casting_borrow_as_mut = casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - .label = casting happened here - -lint_invalid_reference_casting_note_book = for more information, visit - -lint_invalid_reference_casting_note_ty_has_interior_mutability = even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` - -lint_invalid_style = {$is_used_as_inner -> - [false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]` - *[other] the `#![{$name}]` attribute can only be used at the crate root - } - .note = this attribute does not have an `!`, which means it is applied to this {$target} - -lint_invalid_target = `#[{$name}]` attribute cannot be used on {$target} - .warn = {-lint_previously_accepted} - .help = `#[{$name}]` can {$only}be applied to {$applied} - .suggestion = remove the attribute - -lint_lintpass_by_hand = implementing `LintPass` by hand - .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead - -lint_macro_expr_fragment_specifier_2024_migration = - the `expr` fragment specifier will accept more expressions in the 2024 edition - .suggestion = to keep the existing behavior, use the `expr_2021` fragment specifier - -lint_malformed_attribute = malformed lint attribute input - -lint_malformed_doc = - malformed `doc` attribute input - .warn = {-lint_previously_accepted} - -lint_map_unit_fn = `Iterator::map` call that discard the iterator's values - .note = `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated - .function_label = this function returns `()`, which is likely not what you wanted - .argument_label = called `Iterator::map` with callable that returns `()` - .map_label = after this call to map, the resulting iterator is `impl Iterator`, which means the only information carried by the iterator is the number of items - .suggestion = you might have meant to use `Iterator::for_each` - -lint_mismatched_lifetime_syntaxes_eliding_while_named = - eliding a lifetime that's named elsewhere is confusing - -lint_mismatched_lifetime_syntaxes_help = - the same lifetime is referred to in inconsistent ways, making the signature confusing - -lint_mismatched_lifetime_syntaxes_hiding_and_eliding_while_named = - hiding or eliding a lifetime that's named elsewhere is confusing - -lint_mismatched_lifetime_syntaxes_hiding_while_elided = - hiding a lifetime that's elided elsewhere is confusing - -lint_mismatched_lifetime_syntaxes_hiding_while_named = - hiding a lifetime that's named elsewhere is confusing - -lint_mismatched_lifetime_syntaxes_input_elided = - the lifetime is elided here - -lint_mismatched_lifetime_syntaxes_input_hidden = - the lifetime is hidden here - -lint_mismatched_lifetime_syntaxes_input_named = - the lifetime is named here - -lint_mismatched_lifetime_syntaxes_output_elided = - the same lifetime is elided here - -lint_mismatched_lifetime_syntaxes_output_hidden = - the same lifetime is hidden here - -lint_mismatched_lifetime_syntaxes_output_named = - the same lifetime is named here - -lint_mismatched_lifetime_syntaxes_suggestion_explicit = - consistently use `{$lifetime_name}` - -lint_mismatched_lifetime_syntaxes_suggestion_implicit = - remove the lifetime name from references - -lint_mismatched_lifetime_syntaxes_suggestion_mixed = - remove the lifetime name from references and use `'_` for type paths - -lint_mismatched_lifetime_syntaxes_suggestion_mixed_only_paths = - use `'_` for type paths - -lint_missing_gpu_kernel_export_name = function with the "gpu-kernel" ABI has a mangled name - .note = mangled names make it hard to find the kernel, this is usually not intended - .help = use `unsafe(no_mangle)` or `unsafe(export_name = "")` - -lint_mixed_script_confusables = - the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables - .includes_note = the usage includes {$includes} - .note = please recheck to make sure their usages are indeed what you want - -lint_multiple_supertrait_upcastable = `{$ident}` is dyn-compatible and has multiple supertraits - -lint_named_argument_used_positionally = named argument `{$named_arg_name}` is not used by name - .label_named_arg = this named argument is referred to by position in formatting string - .label_position_arg = this formatting argument uses named argument `{$named_arg_name}` by position - .suggestion = use the named argument by name to avoid ambiguity - -lint_node_source = `forbid` level set here - .note = {$reason} - -lint_non_binding_let_multi_drop_fn = - consider immediately dropping the value using `drop(..)` after the `let` statement - -lint_non_binding_let_multi_suggestion = - consider immediately dropping the value - -lint_non_binding_let_on_drop_type = - non-binding let on a type that has a destructor - -lint_non_binding_let_on_sync_lock = non-binding let on a synchronization lock - .label = this lock is not assigned to a binding and is immediately dropped - -lint_non_binding_let_suggestion = - consider binding to an unused variable to avoid immediately dropping the value - -lint_non_camel_case_type = {$sort} `{$name}` should have an upper camel case name - .suggestion = convert the identifier to upper camel case - .label = should have an UpperCamelCase name - -lint_non_fmt_panic = panic message is not a string literal - .note = this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021 - .more_info_note = for more information, see - .supports_fmt_note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here - .supports_fmt_suggestion = remove the `format!(..)` macro call - .display_suggestion = add a "{"{"}{"}"}" format string to `Display` the message - .debug_suggestion = - add a "{"{"}:?{"}"}" format string to use the `Debug` implementation of `{$ty}` - .panic_suggestion = {$already_suggested -> - [true] or use - *[false] use - } std::panic::panic_any instead - -lint_non_fmt_panic_braces = - panic message contains {$count -> - [one] a brace - *[other] braces - } - .note = this message is not used as a format string, but will be in Rust 2021 - .suggestion = add a "{"{"}{"}"}" format string to use the message literally - -lint_non_fmt_panic_unused = - panic message contains {$count -> - [one] an unused - *[other] unused - } formatting {$count -> - [one] placeholder - *[other] placeholders - } - .note = this message is not used as a format string when given without arguments, but will be in Rust 2021 - .add_args_suggestion = add the missing {$count -> - [one] argument - *[other] arguments - } - .add_fmt_suggestion = or add a "{"{"}{"}"}" format string to use the message literally - -lint_non_glob_import_type_ir_inherent = non-glob import of `rustc_type_ir::inherent` - .suggestion = try using a glob import instead - -lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}` - -lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks should be written at the same level as their item - .non_local = an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - .doctest = make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}` - .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint - .const_anon = use a const-anon item to suppress this lint - .macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed - -lint_non_local_definitions_impl_move_help = - move the `impl` block outside of this {$body_kind_descr} {$depth -> - [one] `{$body_name}` - *[other] `{$body_name}` and up {$depth} bodies - } - -lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - .help = - remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth -> - [one] `{$body_name}` - *[other] `{$body_name}` and up {$depth} bodies - } - .help_doctest = - remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}` - .non_local = a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute - -lint_non_snake_case = {$sort} `{$name}` should have a snake case name - .rename_or_convert_suggestion = rename the identifier or convert it to a snake case raw identifier - .cannot_convert_note = `{$sc}` cannot be used as a raw identifier - .rename_suggestion = rename the identifier - .convert_suggestion = convert the identifier to snake case - .help = convert the identifier to snake case: `{$sc}` - .label = should have a snake_case name - -lint_non_upper_case_global = {$sort} `{$name}` should have an upper case name - .suggestion = convert the identifier to upper case - .label = should have an UPPER_CASE name - -lint_noop_method_call = call to `.{$method}()` on a reference in this situation does nothing - .suggestion = remove this redundant call - .note = the type `{$orig_ty}` does not implement `{$trait_}`, so calling `{$method}` on `&{$orig_ty}` copies the reference, which does not do anything and can be removed - .derive_suggestion = if you meant to clone `{$orig_ty}`, implement `Clone` for it - -lint_only_cast_u8_to_char = only `u8` can be cast into `char` - .suggestion = use a `char` literal instead - -lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its associated type bounds - .specifically = this associated type bound is unsatisfied for `{$proj_ty}` - -lint_opaque_hidden_inferred_bound_sugg = add this bound - -lint_overflowing_bin_hex = literal out of range for `{$ty}` - .negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` - .negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}` - .positive_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}` - .suggestion = consider using the type `{$suggestion_ty}` instead - .sign_bit_suggestion = to use as a negative number (decimal `{$negative_val}`), consider using the type `{$uint_ty}` for the literal and cast it to `{$int_ty}` - .help = consider using the type `{$suggestion_ty}` instead - -lint_overflowing_int = literal out of range for `{$ty}` - .note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}` - .help = consider using the type `{$suggestion_ty}` instead - -lint_overflowing_literal = literal out of range for `{$ty}` - .note = the literal `{$lit}` does not fit into the type `{$ty}` and will be converted to `{$ty}::INFINITY` - -lint_overflowing_uint = literal out of range for `{$ty}` - .note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}` - -lint_overruled_attribute = {$lint_level}({$lint_source}) incompatible with previous forbid - .label = overruled by previous forbid - -lint_pass_by_value = passing `{$ty}` by reference - .suggestion = try passing by value - -lint_path_statement_drop = path statement drops value - .suggestion = use `drop` to clarify the intent - -lint_path_statement_no_effect = path statement with no effect - -lint_pattern_in_bodiless = patterns aren't allowed in functions without bodies - .label = pattern not allowed in function without body - -lint_pattern_in_foreign = patterns aren't allowed in foreign function declarations - .label = pattern not allowed in foreign function - -lint_query_instability = using `{$query}` can result in unstable query results - .note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale - -lint_query_untracked = `{$method}` accesses information that is not tracked by the query system - .note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale - -lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}` - -lint_range_use_inclusive_range = use an inclusive range instead - - -lint_raw_prefix = prefix `'r` is reserved - .label = reserved prefix - .suggestion = insert whitespace here to avoid this being parsed as a prefix in Rust 2021 - -lint_reason_must_be_string_literal = reason must be a string literal - -lint_reason_must_come_last = reason in lint attribute must come last - -lint_redundant_import = the item `{$ident}` is imported redundantly - .label_imported_here = the item `{$ident}` is already imported here - .label_defined_here = the item `{$ident}` is already defined here - .label_imported_prelude = the item `{$ident}` is already imported by the extern prelude - .label_defined_prelude = the item `{$ident}` is already defined by the extern prelude - -lint_redundant_semicolons = - unnecessary trailing {$multiple -> - [true] semicolons - *[false] semicolon - } - -lint_redundant_semicolons_suggestion = remove {$multiple_semicolons -> - [true] these semicolons - *[false] this semicolon - } - -lint_remove_mut_from_pattern = remove `mut` from the parameter - -lint_removed_lint = lint `{$name}` has been removed: {$reason} - -lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}` - .suggestion = use the new name - .help = use the new name `{$replace}` - -lint_requested_level = requested on the command line with `{$level} {$lint_name}` - -lint_reserved_multihash = reserved token in Rust 2024 - .suggestion = insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024 - -lint_reserved_prefix = prefix `{$prefix}` is unknown - .label = unknown prefix - .suggestion = insert whitespace here to avoid this being parsed as a prefix in Rust 2021 - -lint_reserved_string = will be parsed as a guarded string in Rust 2024 - .suggestion = insert whitespace here to avoid this being parsed as a guarded string in Rust 2024 - -lint_shadowed_into_iter = - this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<{$target} as IntoIterator>::into_iter` in Rust {$edition} - .use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity - .remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value - .use_explicit_into_iter_suggestion = - or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value - -lint_single_use_lifetime = lifetime parameter `{$ident}` only used once - .label_param = this lifetime... - .label_use = ...is used only here - .suggestion = elide the single-use lifetime - -lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()` - -lint_static_mut_refs_lint = creating a {$shared_label}reference to mutable static - .label = {$shared_label}reference to mutable static - .suggestion = use `&raw const` instead to create a raw pointer - .suggestion_mut = use `&raw mut` instead to create a raw pointer - .shared_note = shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives - .mut_note = mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives - -lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion - .label = `{$self_ty}` implements `Deref` which conflicts with supertrait `{$supertrait_principal}` - .label2 = target type is a supertrait of `{$self_ty}` - .help = consider removing this implementation or replacing it with a method instead - -lint_surrogate_char_cast = surrogate values are not valid for `char` - .note = `0xD800..=0xDFFF` are reserved for Unicode surrogates and are not valid `char` values - -lint_suspicious_double_ref_clone = - using `.clone()` on a double reference, which returns `{$ty}` instead of cloning the inner type - -lint_suspicious_double_ref_deref = - using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type - -lint_symbol_intern_string_literal = using `Symbol::intern` on a string literal - .help = consider adding the symbol to `compiler/rustc_span/src/symbol.rs` - -lint_too_large_char_cast = value exceeds maximum `char` value - .note = maximum valid `char` value is `0x10FFFF` - -lint_ty_qualified = usage of qualified `ty::{$ty}` - .suggestion = try importing it and using it unqualified - -lint_tykind = usage of `ty::TyKind` - .help = try using `Ty` instead - -lint_tykind_kind = usage of `ty::TyKind::` - .suggestion = try using `ty::` directly - -lint_type_ir_direct_use = do not use `rustc_type_ir` unless you are implementing type system internals - .note = use `rustc_middle::ty` instead - -lint_type_ir_inherent_usage = do not use `rustc_type_ir::inherent` unless you're inside of the trait solver - .note = the method or struct you're looking for is likely defined somewhere else downstream in the compiler - -lint_type_ir_trait_usage = do not use `rustc_type_ir::Interner` or `rustc_type_ir::InferCtxtLike` unless you're inside of the trait solver - .note = the method or struct you're looking for is likely defined somewhere else downstream in the compiler - -lint_undefined_transmute = pointers cannot be transmuted to integers during const eval - .note = at compile-time, pointers do not have an integer value - .note2 = avoiding this restriction via `union` or raw pointers leads to compile-time undefined behavior - .help = for more information, see https://doc.rust-lang.org/std/mem/fn.transmute.html - -lint_undropped_manually_drops = calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing - .label = argument has type `{$arg_ty}` - .suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value - -lint_unexpected_cfg_add_build_rs_println = or consider adding `{$build_rs_println}` to the top of the `build.rs` -lint_unexpected_cfg_add_cargo_feature = consider using a Cargo feature instead -lint_unexpected_cfg_add_cargo_toml_lint_cfg = or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:{$cargo_toml_lint_cfg} -lint_unexpected_cfg_add_cmdline_arg = to expect this configuration use `{$cmdline_arg}` -lint_unexpected_cfg_boolean = you may have meant to use `{$literal}` (notice the capitalization). Doing so makes this predicate evaluate to `{$literal}` unconditionally -lint_unexpected_cfg_cargo_update = the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}` - -lint_unexpected_cfg_define_features = consider defining some features in `Cargo.toml` -lint_unexpected_cfg_doc_cargo = see for more information about checking conditional configuration -lint_unexpected_cfg_doc_rustc = see for more information about checking conditional configuration - -lint_unexpected_cfg_from_external_macro_origin = using a cfg inside a {$macro_kind} will use the cfgs from the destination crate and not the ones from the defining crate -lint_unexpected_cfg_from_external_macro_refer = try referring to `{$macro_name}` crate for guidance on how handle this unexpected cfg -lint_unexpected_cfg_name = unexpected `cfg` condition name: `{$name}` -lint_unexpected_cfg_name_expected_names = expected names are: {$possibilities}{$and_more -> - [0] {""} - *[other] {" "}and {$and_more} more - } -lint_unexpected_cfg_name_expected_values = expected values for `{$best_match}` are: {$possibilities} -lint_unexpected_cfg_name_similar_name = there is a config with a similar name -lint_unexpected_cfg_name_similar_name_different_values = there is a config with a similar name and different values -lint_unexpected_cfg_name_similar_name_no_value = there is a config with a similar name and no value -lint_unexpected_cfg_name_similar_name_value = there is a config with a similar name and value -lint_unexpected_cfg_name_version_syntax = there is a similar config predicate: `version("..")` -lint_unexpected_cfg_name_with_similar_value = found config with similar value - -lint_unexpected_cfg_value = unexpected `cfg` condition value: {$has_value -> - [true] `{$value}` - *[false] (none) - } -lint_unexpected_cfg_value_add_feature = consider adding `{$value}` as a feature in `Cargo.toml` -lint_unexpected_cfg_value_expected_values = expected values for `{$name}` are: {$have_none_possibility -> - [true] {"(none), "} - *[false] {""} - }{$possibilities}{$and_more -> - [0] {""} - *[other] {" "}and {$and_more} more - } -lint_unexpected_cfg_value_no_expected_value = no expected value for `{$name}` -lint_unexpected_cfg_value_no_expected_values = no expected values for `{$name}` -lint_unexpected_cfg_value_remove_condition = remove the condition -lint_unexpected_cfg_value_remove_value = remove the value -lint_unexpected_cfg_value_similar_name = there is a expected value with a similar name -lint_unexpected_cfg_value_specify_value = specify a config value - -lint_ungated_async_fn_track_caller = `#[track_caller]` on async functions is a no-op - .label = this function will not propagate the caller location - -lint_unicode_text_flow = unicode codepoint changing visible direction of text present in comment - .label = {$num_codepoints -> - [1] this comment contains an invisible unicode text flow control codepoint - *[other] this comment contains invisible unicode text flow control codepoints - } - .note = these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen - .suggestion = if their presence wasn't intentional, you can remove them - .label_comment_char = {$c_debug} - - -lint_unit_bindings = binding has unit type `()` - .label = this pattern is inferred to be the unit type `()` - -lint_unknown_gated_lint = - unknown lint: `{$name}` - .note = the `{$name}` lint is unstable - -lint_unknown_lint = - unknown lint: `{$name}` - .suggestion = {$from_rustc -> - [true] a lint with a similar name exists in `rustc` lints - *[false] did you mean - } - .help = {$from_rustc -> - [true] a lint with a similar name exists in `rustc` lints: `{$replace}` - *[false] did you mean: `{$replace}` - } - -lint_unknown_tool_in_scoped_lint = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}` - .help = add `#![register_tool({$tool_name})]` to the crate root - -lint_unnecessary_qualification = unnecessary qualification - .suggestion = remove the unnecessary path segments - -lint_unpredictable_fn_pointer_comparisons = function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique - .note_duplicated_fn = the address of the same function can vary between different codegen units - .note_deduplicated_fn = furthermore, different functions could have the same address after being merged together - .note_visit_fn_addr_eq = for more information visit - .fn_addr_eq_suggestion = refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint - -lint_unqualified_local_imports = `use` of a local item without leading `self::`, `super::`, or `crate::` - -lint_unreachable_cfg_select_predicate = unreachable configuration predicate - .label = this configuration predicate is never reached - -lint_unreachable_cfg_select_predicate_wildcard = unreachable configuration predicate - .label = always matches - .label2 = this configuration predicate is never reached - -lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe - .label = usage of unsafe attribute -lint_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)` - -lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´ - -lint_unused_allocation = unnecessary allocation, use `&` instead -lint_unused_allocation_mut = unnecessary allocation, use `&mut` instead - -lint_unused_closure = - unused {$pre}{$count -> - [one] closure - *[other] closures - }{$post} that must be used - .note = closures are lazy and do nothing unless called - -lint_unused_comparisons = comparison is useless due to type limits - -lint_unused_coroutine = - unused {$pre}{$count -> - [one] coroutine - *[other] coroutine - }{$post} that must be used - .note = coroutines are lazy and do nothing unless resumed - -lint_unused_crate_dependency = extern crate `{$extern_crate}` is unused in crate `{$local_crate}` - .help = remove the dependency or add `use {$extern_crate} as _;` to the crate root - -lint_unused_def = unused {$pre}`{$def}`{$post} that must be used - .suggestion = use `let _ = ...` to ignore the resulting value - -lint_unused_delim = unnecessary {$delim} around {$item} - .suggestion = remove these {$delim} - -lint_unused_duplicate = - unused attribute - .suggestion = remove this attribute - .note = attribute also specified here - .warn = {-lint_previously_accepted} - -lint_unused_import_braces = braces around {$node} is unnecessary - -lint_unused_imports = {$num_snippets -> - [one] unused import: {$span_snippets} - *[other] unused imports: {$span_snippets} - } - .suggestion_remove_whole_use = remove the whole `use` item - .suggestion_remove_imports = {$num_to_remove -> - [one] remove the unused import - *[other] remove the unused imports - } - .help = if this is a test module, consider adding a `#[cfg(test)]` to the containing module - -lint_unused_lifetime = lifetime parameter `{$ident}` never used - .suggestion = elide the unused lifetime - -lint_unused_op = unused {$op} that must be used - .label = the {$op} produces a value - .suggestion = use `let _ = ...` to ignore the resulting value - -lint_unused_result = unused result of type `{$ty}` - -lint_unused_visibilities = visibility qualifiers have no effect on `const _` declarations - .note = `const _` does not declare a name, so there is nothing for the qualifier to apply to - .suggestion = remove the qualifier - -lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result - -lint_useless_ptr_null_checks_fn_ptr = function pointers are not nullable, so checking them for null will always return false - .help = wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value - .label = expression has type `{$orig_ty}` - -lint_useless_ptr_null_checks_fn_ret = returned pointer of `{$fn_name}` call is never null, so checking it for null will always return false - -lint_useless_ptr_null_checks_ref = references are not nullable, so checking them for null will always return false - .label = expression has type `{$orig_ty}` - -lint_uses_power_alignment = repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - -lint_variant_size_differences = - enum variant is more than three times larger ({$largest} bytes) than the next largest diff --git a/compiler/rustc_lint/src/async_closures.rs b/compiler/rustc_lint/src/async_closures.rs index 02fb22bf782e..0d3a954667f7 100644 --- a/compiler/rustc_lint/src/async_closures.rs +++ b/compiler/rustc_lint/src/async_closures.rs @@ -108,16 +108,18 @@ impl<'tcx> LateLintPass<'tcx> for AsyncClosureUsage { } #[derive(LintDiagnostic)] -#[diag(lint_closure_returning_async_block)] +#[diag("closure returning async block can be made into an async closure")] struct ClosureReturningAsyncBlock { - #[label] + #[label( + "this async block can be removed, and the closure can be turned into an async closure" + )] async_decl_span: Span, #[subdiagnostic] sugg: AsyncClosureSugg, } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion("turn this into an async closure", applicability = "maybe-incorrect")] struct AsyncClosureSugg { #[suggestion_part(code = "")] deletion_span: Span, diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index e2a061cab680..ef21b3f573be 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -22,7 +22,7 @@ use rustc_ast::visit::{FnCtxt, FnKind}; use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust::expr_to_string; use rustc_attr_parsing::AttributeParser; -use rustc_errors::{Applicability, LintDiagnostic}; +use rustc_errors::{Applicability, LintDiagnostic, inline_fluent}; use rustc_feature::GateIssue; use rustc_hir as hir; use rustc_hir::attrs::{AttributeKind, DocAttribute}; @@ -61,10 +61,7 @@ use crate::lints::{ BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, BuiltinWhileTrue, InvalidAsmLabel, }; -use crate::{ - EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext, - fluent_generated as fluent, -}; +use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext}; declare_lint! { /// The `while_true` lint detects `while true { }`. /// @@ -2655,8 +2652,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { let conjured_ty = cx.typeck_results().expr_ty(expr); if let Some(err) = with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init)) { let msg = match init { - InitKind::Zeroed => fluent::lint_builtin_unpermitted_type_init_zeroed, - InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_uninit, + InitKind::Zeroed => { + inline_fluent!("the type `{$ty}` does not permit zero-initialization") + } + InitKind::Uninit => { + inline_fluent!("the type `{$ty}` does not permit being left uninitialized") + } }; let sub = BuiltinUnpermittedTypeInitSub { err }; cx.emit_span_lint( diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 8f2f3594161a..b0154bed1a51 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -1,17 +1,15 @@ use rustc_errors::codes::*; -use rustc_errors::{Diag, EmissionGuarantee, Subdiagnostic}; +use rustc_errors::{Diag, EmissionGuarantee, Subdiagnostic, inline_fluent}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_session::lint::Level; use rustc_span::{Span, Symbol}; -use crate::fluent_generated as fluent; - #[derive(Diagnostic)] -#[diag(lint_overruled_attribute, code = E0453)] +#[diag("{$lint_level}({$lint_source}) incompatible with previous forbid", code = E0453)] pub(crate) struct OverruledAttribute<'a> { #[primary_span] pub span: Span, - #[label] + #[label("overruled by previous forbid")] pub overruled: Span, pub lint_level: &'a str, pub lint_source: Symbol, @@ -29,24 +27,24 @@ impl Subdiagnostic for OverruledAttributeSub { fn add_to_diag(self, diag: &mut Diag<'_, G>) { match self { OverruledAttributeSub::DefaultSource { id } => { - diag.note(fluent::lint_default_source); + diag.note(inline_fluent!("`forbid` lint level is the default for {$id}")); diag.arg("id", id); } OverruledAttributeSub::NodeSource { span, reason } => { - diag.span_label(span, fluent::lint_node_source); + diag.span_label(span, inline_fluent!("`forbid` level set here")); if let Some(rationale) = reason { diag.note(rationale.to_string()); } } OverruledAttributeSub::CommandLineSource => { - diag.note(fluent::lint_command_line_source); + diag.note(inline_fluent!("`forbid` lint level was set on command line")); } } } } #[derive(Diagnostic)] -#[diag(lint_malformed_attribute, code = E0452)] +#[diag("malformed lint attribute input", code = E0452)] pub(crate) struct MalformedAttribute { #[primary_span] pub span: Span, @@ -56,50 +54,55 @@ pub(crate) struct MalformedAttribute { #[derive(Subdiagnostic)] pub(crate) enum MalformedAttributeSub { - #[label(lint_bad_attribute_argument)] + #[label("bad attribute argument")] BadAttributeArgument(#[primary_span] Span), - #[label(lint_reason_must_be_string_literal)] + #[label("reason must be a string literal")] ReasonMustBeStringLiteral(#[primary_span] Span), - #[label(lint_reason_must_come_last)] + #[label("reason in lint attribute must come last")] ReasonMustComeLast(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(lint_unknown_tool_in_scoped_lint, code = E0710)] +#[diag("unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}`", code = E0710)] pub(crate) struct UnknownToolInScopedLint { #[primary_span] pub span: Option, pub tool_name: Symbol, pub lint_name: String, - #[help] + #[help("add `#![register_tool({$tool_name})]` to the crate root")] pub is_nightly_build: bool, } #[derive(Diagnostic)] -#[diag(lint_builtin_ellipsis_inclusive_range_patterns, code = E0783)] +#[diag("`...` range patterns are deprecated", code = E0783)] pub(crate) struct BuiltinEllipsisInclusiveRangePatterns { #[primary_span] pub span: Span, - #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")] + #[suggestion( + "use `..=` for an inclusive range", + style = "short", + code = "{replace}", + applicability = "machine-applicable" + )] pub suggestion: Span, pub replace: String, } #[derive(Subdiagnostic)] -#[note(lint_requested_level)] +#[note("requested on the command line with `{$level} {$lint_name}`")] pub(crate) struct RequestedLevel<'a> { pub level: Level, pub lint_name: &'a str, } #[derive(Diagnostic)] -#[diag(lint_unsupported_group, code = E0602)] +#[diag("`{$lint_group}` lint group is not supported with ´--force-warn´", code = E0602)] pub(crate) struct UnsupportedGroup { pub lint_group: String, } #[derive(Diagnostic)] -#[diag(lint_check_name_unknown_tool, code = E0602)] +#[diag("unknown lint tool: `{$tool_name}`", code = E0602)] pub(crate) struct CheckNameUnknownTool<'a> { pub tool_name: Symbol, #[subdiagnostic] diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 612d542a27de..8569070a43ca 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -3,7 +3,9 @@ use std::ops::ControlFlow; use hir::intravisit::{self, Visitor}; use rustc_ast::Recovered; -use rustc_errors::{Applicability, Diag, EmissionGuarantee, Subdiagnostic, SuggestionStyle}; +use rustc_errors::{ + Applicability, Diag, EmissionGuarantee, Subdiagnostic, SuggestionStyle, inline_fluent, +}; use rustc_hir::{self as hir, HirIdSet}; use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::adjustment::Adjust; @@ -303,13 +305,15 @@ impl<'tcx> LateLintPass<'tcx> for IfLetRescope { } #[derive(LintDiagnostic)] -#[diag(lint_if_let_rescope)] +#[diag("`if let` assigns a shorter lifetime since Edition 2024")] struct IfLetRescopeLint { #[subdiagnostic] destructors: Vec, - #[label] + #[label( + "this value has a significant drop implementation which may observe a major change in drop order and requires your discretion" + )] significant_droppers: Vec, - #[help] + #[help("the value is now dropped here in Edition 2024")] lifetime_ends: Vec, #[subdiagnostic] rewrite: Option, @@ -352,7 +356,9 @@ impl Subdiagnostic for IfLetRescopeRewrite { .chain(repeat_n('}', closing_brackets.count)) .collect(), )); - let msg = diag.eagerly_translate(crate::fluent_generated::lint_suggestion); + let msg = diag.eagerly_translate(inline_fluent!( + "a `match` with a single arm can preserve the drop order up to Edition 2021" + )); diag.multipart_suggestion_with_style( msg, suggestions, @@ -363,7 +369,12 @@ impl Subdiagnostic for IfLetRescopeRewrite { } #[derive(Subdiagnostic)] -#[note(lint_if_let_dtor)] +#[note( + "{$dtor_kind -> + [dyn] value may invoke a custom destructor because it contains a trait object + *[concrete] value invokes this custom destructor + }" +)] struct DestructorLabel { #[primary_span] span: Span, diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 1cdc5e4a1b36..087403719968 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -3,7 +3,7 @@ use std::cell::LazyCell; use rustc_data_structures::debug_assert_matches; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{LintDiagnostic, Subdiagnostic}; +use rustc_errors::{LintDiagnostic, Subdiagnostic, inline_fluent}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -28,7 +28,7 @@ use rustc_trait_selection::errors::{ use rustc_trait_selection::regions::OutlivesEnvironmentBuildExt; use rustc_trait_selection::traits::ObligationCtxt; -use crate::{LateContext, LateLintPass, fluent_generated as fluent}; +use crate::{LateContext, LateLintPass}; declare_lint! { /// The `impl_trait_overcaptures` lint warns against cases where lifetime @@ -435,11 +435,23 @@ struct ImplTraitOvercapturesLint<'tcx> { impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { - diag.primary_message(fluent::lint_impl_trait_overcaptures); + diag.primary_message(inline_fluent!( + "`{$self_ty}` will capture more lifetimes than possibly intended in edition 2024" + )); diag.arg("self_ty", self.self_ty.to_string()) .arg("num_captured", self.num_captured) - .span_note(self.uncaptured_spans, fluent::lint_note) - .note(fluent::lint_note2); + .span_note( + self.uncaptured_spans, + inline_fluent!( + "specifically, {$num_captured -> + [one] this lifetime is + *[other] these lifetimes are + } in scope but not mentioned in the type's bounds" + ), + ) + .note(inline_fluent!( + "all lifetimes in scope will be captured by `impl Trait`s in edition 2024" + )); if let Some(suggestion) = self.suggestion { suggestion.add_to_diag(diag); } @@ -447,9 +459,9 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { } #[derive(LintDiagnostic)] -#[diag(lint_impl_trait_redundant_captures)] +#[diag("all possible in-scope parameters are already captured, so `use<...>` syntax is redundant")] struct ImplTraitRedundantCapturesLint { - #[suggestion(lint_suggestion, code = "", applicability = "machine-applicable")] + #[suggestion("remove the `use<...>` syntax", code = "", applicability = "machine-applicable")] capturing_span: Span, } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 57dacbc11e05..cebe1a5dc373 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -2,7 +2,7 @@ use rustc_ast::attr::AttributeExt; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{Diag, LintDiagnostic, MultiSpan}; +use rustc_errors::{Diag, LintDiagnostic, MultiSpan, inline_fluent}; use rustc_feature::{Features, GateIssue}; use rustc_hir::HirId; use rustc_hir::intravisit::{self, Visitor}; @@ -31,7 +31,6 @@ use crate::errors::{ CheckNameUnknownTool, MalformedAttribute, MalformedAttributeSub, OverruledAttribute, OverruledAttributeSub, RequestedLevel, UnknownToolInScopedLint, UnsupportedGroup, }; -use crate::fluent_generated as fluent; use crate::late::unerased_lint_store; use crate::lints::{ DeprecatedLintName, DeprecatedLintNameFromCommandLine, IgnoredUnlessCrateSpecified, @@ -942,9 +941,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { let lint = builtin::UNKNOWN_LINTS; let level = self.lint_level(builtin::UNKNOWN_LINTS); lint_level(self.sess, lint, level, Some(span.into()), |lint| { - lint.primary_message(fluent::lint_unknown_gated_lint); + lint.primary_message(inline_fluent!("unknown lint: `{$name}`")); lint.arg("name", lint_id.lint.name_lower()); - lint.note(fluent::lint_note); + lint.note(inline_fluent!("the `{$name}` lint is unstable")); rustc_session::parse::add_feature_diagnostics_for_issue( lint, &self.sess, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index ea31a6373cbc..93b6f1491041 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -139,8 +139,6 @@ pub use rustc_errors::BufferedEarlyLint; pub use rustc_session::lint::Level::{self, *}; pub use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintId, LintPass, LintVec}; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn provide(providers: &mut Providers) { levels::provide(providers); expect::provide(providers); diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index bdc171f11e3b..0aa5199cffc6 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -5,7 +5,7 @@ use std::num::NonZero; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString, ElidedLifetimeInPathSubdiag, - EmissionGuarantee, LintDiagnostic, MultiSpan, Subdiagnostic, SuggestionStyle, + EmissionGuarantee, LintDiagnostic, MultiSpan, Subdiagnostic, SuggestionStyle, inline_fluent, }; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -17,18 +17,24 @@ use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::{Ident, Span, Symbol, sym}; +use crate::LateContext; use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds}; use crate::errors::{OverruledAttributeSub, RequestedLevel}; use crate::lifetime_syntax::LifetimeSyntaxCategories; -use crate::{LateContext, fluent_generated as fluent}; // array_into_iter.rs #[derive(LintDiagnostic)] -#[diag(lint_shadowed_into_iter)] +#[diag( + "this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<{$target} as IntoIterator>::into_iter` in Rust {$edition}" +)] pub(crate) struct ShadowedIntoIterDiag { pub target: &'static str, pub edition: &'static str, - #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")] + #[suggestion( + "use `.iter()` instead of `.into_iter()` to avoid ambiguity", + code = "iter", + applicability = "machine-applicable" + )] pub suggestion: Span, #[subdiagnostic] pub sub: Option, @@ -36,13 +42,17 @@ pub(crate) struct ShadowedIntoIterDiag { #[derive(Subdiagnostic)] pub(crate) enum ShadowedIntoIterDiagSub { - #[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")] + #[suggestion( + "or remove `.into_iter()` to iterate by value", + code = "", + applicability = "maybe-incorrect" + )] RemoveIntoIter { #[primary_span] span: Span, }, #[multipart_suggestion( - lint_use_explicit_into_iter_suggestion, + "or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value", applicability = "maybe-incorrect" )] UseExplicitIntoIter { @@ -55,10 +65,12 @@ pub(crate) enum ShadowedIntoIterDiagSub { // autorefs.rs #[derive(LintDiagnostic)] -#[diag(lint_implicit_unsafe_autorefs)] -#[note] +#[diag("implicit autoref creates a reference to the dereference of a raw pointer")] +#[note( + "creating a reference requires the pointer target to be valid and imposes aliasing requirements" +)] pub(crate) struct ImplicitUnsafeAutorefsDiag<'a> { - #[label(lint_raw_ptr)] + #[label("this raw pointer has type `{$raw_ptr_ty}`")] pub raw_ptr_span: Span, pub raw_ptr_ty: Ty<'a>, #[subdiagnostic] @@ -71,18 +83,20 @@ pub(crate) struct ImplicitUnsafeAutorefsDiag<'a> { #[derive(Subdiagnostic)] pub(crate) enum ImplicitUnsafeAutorefsOrigin<'a> { - #[note(lint_autoref)] + #[note("autoref is being applied to this expression, resulting in: `{$autoref_ty}`")] Autoref { #[primary_span] autoref_span: Span, autoref_ty: Ty<'a>, }, - #[note(lint_overloaded_deref)] + #[note( + "references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations" + )] OverloadedDeref, } #[derive(Subdiagnostic)] -#[note(lint_method_def)] +#[note("method calls to `{$method_name}` require a reference")] pub(crate) struct ImplicitUnsafeAutorefsMethodNote { #[primary_span] pub def_span: Span, @@ -90,7 +104,10 @@ pub(crate) struct ImplicitUnsafeAutorefsMethodNote { } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "try using a raw pointer method instead; or if this reference is intentional, make it explicit", + applicability = "maybe-incorrect" +)] pub(crate) struct ImplicitUnsafeAutorefsSuggestion { pub mutbl: &'static str, pub deref: &'static str, @@ -102,78 +119,105 @@ pub(crate) struct ImplicitUnsafeAutorefsSuggestion { // builtin.rs #[derive(LintDiagnostic)] -#[diag(lint_builtin_while_true)] +#[diag("denote infinite loops with `loop {\"{\"} ... {\"}\"}`")] pub(crate) struct BuiltinWhileTrue { - #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")] + #[suggestion( + "use `loop`", + style = "short", + code = "{replace}", + applicability = "machine-applicable" + )] pub suggestion: Span, pub replace: String, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_non_shorthand_field_patterns)] +#[diag("the `{$ident}:` in this pattern is redundant")] pub(crate) struct BuiltinNonShorthandFieldPatterns { pub ident: Ident, - #[suggestion(code = "{prefix}{ident}", applicability = "machine-applicable")] + #[suggestion( + "use shorthand field pattern", + code = "{prefix}{ident}", + applicability = "machine-applicable" + )] pub suggestion: Span, pub prefix: &'static str, } #[derive(LintDiagnostic)] pub(crate) enum BuiltinUnsafe { - #[diag(lint_builtin_allow_internal_unsafe)] + #[diag( + "`allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site" + )] AllowInternalUnsafe, - #[diag(lint_builtin_unsafe_block)] + #[diag("usage of an `unsafe` block")] UnsafeBlock, - #[diag(lint_builtin_unsafe_extern_block)] + #[diag("usage of an `unsafe extern` block")] UnsafeExternBlock, - #[diag(lint_builtin_unsafe_trait)] + #[diag("declaration of an `unsafe` trait")] UnsafeTrait, - #[diag(lint_builtin_unsafe_impl)] + #[diag("implementation of an `unsafe` trait")] UnsafeImpl, - #[diag(lint_builtin_no_mangle_fn)] - #[note(lint_builtin_overridden_symbol_name)] + #[diag("declaration of a `no_mangle` function")] + #[note( + "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them" + )] NoMangleFn, - #[diag(lint_builtin_export_name_fn)] - #[note(lint_builtin_overridden_symbol_name)] + #[diag("declaration of a function with `export_name`")] + #[note( + "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them" + )] ExportNameFn, - #[diag(lint_builtin_link_section_fn)] - #[note(lint_builtin_overridden_symbol_section)] + #[diag("declaration of a function with `link_section`")] + #[note( + "the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them" + )] LinkSectionFn, - #[diag(lint_builtin_no_mangle_static)] - #[note(lint_builtin_overridden_symbol_name)] + #[diag("declaration of a `no_mangle` static")] + #[note( + "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them" + )] NoMangleStatic, - #[diag(lint_builtin_export_name_static)] - #[note(lint_builtin_overridden_symbol_name)] + #[diag("declaration of a static with `export_name`")] + #[note( + "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them" + )] ExportNameStatic, - #[diag(lint_builtin_link_section_static)] - #[note(lint_builtin_overridden_symbol_section)] + #[diag("declaration of a static with `link_section`")] + #[note( + "the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them" + )] LinkSectionStatic, - #[diag(lint_builtin_no_mangle_method)] - #[note(lint_builtin_overridden_symbol_name)] + #[diag("declaration of a `no_mangle` method")] + #[note( + "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them" + )] NoMangleMethod, - #[diag(lint_builtin_export_name_method)] - #[note(lint_builtin_overridden_symbol_name)] + #[diag("declaration of a method with `export_name`")] + #[note( + "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them" + )] ExportNameMethod, - #[diag(lint_builtin_decl_unsafe_fn)] + #[diag("declaration of an `unsafe` function")] DeclUnsafeFn, - #[diag(lint_builtin_decl_unsafe_method)] + #[diag("declaration of an `unsafe` method")] DeclUnsafeMethod, - #[diag(lint_builtin_impl_unsafe_method)] + #[diag("implementation of an `unsafe` method")] ImplUnsafeMethod, - #[diag(lint_builtin_global_asm)] - #[note(lint_builtin_global_macro_unsafety)] + #[diag("usage of `core::arch::global_asm`")] + #[note("using this macro is unsafe even though it does not need an `unsafe` block")] GlobalAsm, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_missing_doc)] +#[diag("missing documentation for {$article} {$desc}")] pub(crate) struct BuiltinMissingDoc<'a> { pub article: &'a str, pub desc: &'a str, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_missing_copy_impl)] +#[diag("type could implement `Copy`; consider adding `impl Copy`")] pub(crate) struct BuiltinMissingCopyImpl; pub(crate) struct BuiltinMissingDebugImpl<'a> { @@ -184,24 +228,24 @@ pub(crate) struct BuiltinMissingDebugImpl<'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { - diag.primary_message(fluent::lint_builtin_missing_debug_impl); + diag.primary_message(inline_fluent!("type does not implement `{$debug}`; consider adding `#[derive(Debug)]` or a manual implementation")); diag.arg("debug", self.tcx.def_path_str(self.def_id)); } } #[derive(LintDiagnostic)] -#[diag(lint_builtin_anonymous_params)] +#[diag("anonymous parameters are deprecated and will be removed in the next edition")] pub(crate) struct BuiltinAnonymousParams<'a> { - #[suggestion(code = "_: {ty_snip}")] + #[suggestion("try naming the parameter or explicitly ignoring it", code = "_: {ty_snip}")] pub suggestion: (Span, Applicability), pub ty_snip: &'a str, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_unused_doc_comment)] +#[diag("unused doc comment")] pub(crate) struct BuiltinUnusedDocComment<'a> { pub kind: &'a str, - #[label] + #[label("rustdoc does not generate documentation for {$kind}")] pub label: Span, #[subdiagnostic] pub sub: BuiltinUnusedDocCommentSub, @@ -209,34 +253,41 @@ pub(crate) struct BuiltinUnusedDocComment<'a> { #[derive(Subdiagnostic)] pub(crate) enum BuiltinUnusedDocCommentSub { - #[help(lint_plain_help)] + #[help("use `//` for a plain comment")] PlainHelp, - #[help(lint_block_help)] + #[help("use `/* */` for a plain comment")] BlockHelp, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_no_mangle_generic)] +#[diag("functions generic over types or consts must be mangled")] pub(crate) struct BuiltinNoMangleGeneric { // Use of `#[no_mangle]` suggests FFI intent; correct // fix may be to monomorphize source by hand - #[suggestion(style = "short", code = "", applicability = "maybe-incorrect")] + #[suggestion( + "remove this attribute", + style = "short", + code = "", + applicability = "maybe-incorrect" + )] pub suggestion: Span, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_const_no_mangle)] +#[diag("const items should never be `#[no_mangle]`")] pub(crate) struct BuiltinConstNoMangle { - #[suggestion(code = "pub static ", applicability = "machine-applicable")] + #[suggestion("try a static value", code = "pub static ", applicability = "machine-applicable")] pub suggestion: Option, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_mutable_transmutes)] +#[diag( + "transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell" +)] pub(crate) struct BuiltinMutablesTransmutes; #[derive(LintDiagnostic)] -#[diag(lint_builtin_unstable_features)] +#[diag("use of an unstable feature")] pub(crate) struct BuiltinUnstableFeatures; // lint_ungated_async_fn_track_caller @@ -247,8 +298,11 @@ pub(crate) struct BuiltinUngatedAsyncFnTrackCaller<'a> { impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - diag.primary_message(fluent::lint_ungated_async_fn_track_caller); - diag.span_label(self.label, fluent::lint_label); + diag.primary_message(inline_fluent!("`#[track_caller]` on async functions is a no-op")); + diag.span_label( + self.label, + inline_fluent!("this function will not propagate the caller location"), + ); rustc_session::parse::add_feature_diagnostics( diag, self.session, @@ -258,20 +312,24 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { } #[derive(LintDiagnostic)] -#[diag(lint_builtin_unreachable_pub)] +#[diag("unreachable `pub` {$what}")] pub(crate) struct BuiltinUnreachablePub<'a> { pub what: &'a str, pub new_vis: &'a str, - #[suggestion(code = "{new_vis}")] + #[suggestion("consider restricting its visibility", code = "{new_vis}")] pub suggestion: (Span, Applicability), - #[help] + #[help("or consider exporting it for use by other crates")] pub help: bool, } #[derive(LintDiagnostic)] -#[diag(lint_macro_expr_fragment_specifier_2024_migration)] +#[diag("the `expr` fragment specifier will accept more expressions in the 2024 edition")] pub(crate) struct MacroExprFragment2024 { - #[suggestion(code = "expr_2021", applicability = "machine-applicable")] + #[suggestion( + "to keep the existing behavior, use the `expr_2021` fragment specifier", + code = "expr_2021", + applicability = "machine-applicable" + )] pub suggestion: Span, } @@ -287,14 +345,18 @@ pub(crate) struct BuiltinTypeAliasBounds<'hir> { impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { diag.primary_message(if self.in_where_clause { - fluent::lint_builtin_type_alias_bounds_where_clause + inline_fluent!("where clauses on type aliases are not enforced") } else { - fluent::lint_builtin_type_alias_bounds_param_bounds + inline_fluent!("bounds on generic parameters in type aliases are not enforced") }); - diag.span_label(self.label, fluent::lint_builtin_type_alias_bounds_label); - diag.note(fluent::lint_builtin_type_alias_bounds_limitation_note); + diag.span_label( + self.label, + inline_fluent!("will not be checked at usage sites of the type alias"), + ); + diag.note(inline_fluent!("this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information")); if self.enable_feat_help { - diag.help(fluent::lint_builtin_type_alias_bounds_enable_feat_help); + diag.help(inline_fluent!("add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics")); } // We perform the walk in here instead of in `` to @@ -319,7 +381,20 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> { }; diag.arg("count", self.suggestions.len()); - diag.multipart_suggestion(fluent::lint_suggestion, self.suggestions, applicability); + diag.multipart_suggestion( + if self.in_where_clause { + inline_fluent!("remove this where clause") + } else { + inline_fluent!( + "remove {$count -> + [one] this bound + *[other] these bounds + }" + ) + }, + self.suggestions, + applicability, + ); // Suggest fully qualifying paths of the form `T::Assoc` with `T` type param via // `::Assoc` to remove their reliance on any type param bounds. @@ -333,7 +408,7 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> { // (We could employ some simple heuristics but that's likely not worth it). for qself in collector.qselves { diag.multipart_suggestion( - fluent::lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg, + inline_fluent!("fully qualify this associated type"), vec![ (qself.shrink_to_lo(), "<".into()), (qself.shrink_to_hi(), " as /* Trait */>".into()), @@ -345,23 +420,27 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> { } #[derive(LintDiagnostic)] -#[diag(lint_builtin_trivial_bounds)] +#[diag( + "{$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters" +)] pub(crate) struct BuiltinTrivialBounds<'a> { pub predicate_kind_name: &'a str, pub predicate: Clause<'a>, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_double_negations)] -#[note(lint_note)] -#[note(lint_note_decrement)] +#[diag("use of a double negation")] +#[note( + "the prefix `--` could be misinterpreted as a decrement operator which exists in other languages" +)] +#[note("use `-= 1` if you meant to decrement the value")] pub(crate) struct BuiltinDoubleNegations { #[subdiagnostic] pub add_parens: BuiltinDoubleNegationsAddParens, } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_add_parens_suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion("add parentheses for clarity", applicability = "maybe-incorrect")] pub(crate) struct BuiltinDoubleNegationsAddParens { #[suggestion_part(code = "(")] pub start_span: Span, @@ -371,31 +450,44 @@ pub(crate) struct BuiltinDoubleNegationsAddParens { #[derive(LintDiagnostic)] pub(crate) enum BuiltinEllipsisInclusiveRangePatternsLint { - #[diag(lint_builtin_ellipsis_inclusive_range_patterns)] + #[diag("`...` range patterns are deprecated")] Parenthesise { - #[suggestion(code = "{replace}", applicability = "machine-applicable")] + #[suggestion( + "use `..=` for an inclusive range", + code = "{replace}", + applicability = "machine-applicable" + )] suggestion: Span, replace: String, }, - #[diag(lint_builtin_ellipsis_inclusive_range_patterns)] + #[diag("`...` range patterns are deprecated")] NonParenthesise { - #[suggestion(style = "short", code = "..=", applicability = "machine-applicable")] + #[suggestion( + "use `..=` for an inclusive range", + style = "short", + code = "..=", + applicability = "machine-applicable" + )] suggestion: Span, }, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_keyword_idents)] +#[diag("`{$kw}` is a keyword in the {$next} edition")] pub(crate) struct BuiltinKeywordIdents { pub kw: Ident, pub next: Edition, - #[suggestion(code = "{prefix}r#{kw}", applicability = "machine-applicable")] + #[suggestion( + "you can use a raw identifier to stay compatible", + code = "{prefix}r#{kw}", + applicability = "machine-applicable" + )] pub suggestion: Span, pub prefix: &'static str, } #[derive(LintDiagnostic)] -#[diag(lint_builtin_explicit_outlives)] +#[diag("outlives requirements can be inferred")] pub(crate) struct BuiltinExplicitOutlives { pub count: usize, #[subdiagnostic] @@ -403,7 +495,12 @@ pub(crate) struct BuiltinExplicitOutlives { } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_suggestion)] +#[multipart_suggestion( + "remove {$count -> + [one] this bound + *[other] these bounds + }" +)] pub(crate) struct BuiltinExplicitOutlivesSuggestion { #[suggestion_part(code = "")] pub spans: Vec, @@ -412,7 +509,9 @@ pub(crate) struct BuiltinExplicitOutlivesSuggestion { } #[derive(LintDiagnostic)] -#[diag(lint_builtin_incomplete_features)] +#[diag( + "the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes" +)] pub(crate) struct BuiltinIncompleteFeatures { pub name: Symbol, #[subdiagnostic] @@ -422,18 +521,18 @@ pub(crate) struct BuiltinIncompleteFeatures { } #[derive(LintDiagnostic)] -#[diag(lint_builtin_internal_features)] -#[note] +#[diag("the feature `{$name}` is internal to the compiler or standard library")] +#[note("using it is strongly discouraged")] pub(crate) struct BuiltinInternalFeatures { pub name: Symbol, } #[derive(Subdiagnostic)] -#[help(lint_help)] +#[help("consider using `min_{$name}` instead, which is more stable and complete")] pub(crate) struct BuiltinIncompleteFeaturesHelp; #[derive(Subdiagnostic)] -#[note(lint_note)] +#[note("see issue #{$n} for more information")] pub(crate) struct BuiltinFeatureIssueNote { pub n: NonZero, } @@ -450,12 +549,15 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { diag.primary_message(self.msg); diag.arg("ty", self.ty); - diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label); + diag.span_label( + self.label, + inline_fluent!("this code causes undefined behavior when executed"), + ); if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) { // Only suggest late `MaybeUninit::assume_init` initialization if the type is inhabited. diag.span_label( self.label, - fluent::lint_builtin_unpermitted_type_init_label_suggestion, + inline_fluent!("help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done"), ); } self.sub.add_to_diag(diag); @@ -487,24 +589,24 @@ impl Subdiagnostic for BuiltinUnpermittedTypeInitSub { #[derive(LintDiagnostic)] pub(crate) enum BuiltinClashingExtern<'a> { - #[diag(lint_builtin_clashing_extern_same_name)] + #[diag("`{$this}` redeclared with a different signature")] SameName { this: Symbol, orig: Symbol, - #[label(lint_previous_decl_label)] + #[label("`{$orig}` previously declared here")] previous_decl_label: Span, - #[label(lint_mismatch_label)] + #[label("this signature doesn't match the previous declaration")] mismatch_label: Span, #[subdiagnostic] sub: BuiltinClashingExternSub<'a>, }, - #[diag(lint_builtin_clashing_extern_diff_name)] + #[diag("`{$this}` redeclares `{$orig}` with a different signature")] DiffName { this: Symbol, orig: Symbol, - #[label(lint_previous_decl_label)] + #[label("`{$orig}` previously declared here")] previous_decl_label: Span, - #[label(lint_mismatch_label)] + #[label("this signature doesn't match the previous declaration")] mismatch_label: Span, #[subdiagnostic] sub: BuiltinClashingExternSub<'a>, @@ -529,9 +631,9 @@ impl Subdiagnostic for BuiltinClashingExternSub<'_> { } #[derive(LintDiagnostic)] -#[diag(lint_builtin_deref_nullptr)] +#[diag("dereferencing a null pointer")] pub(crate) struct BuiltinDerefNullptr { - #[label] + #[label("this code causes undefined behavior when executed")] pub label: Span, } @@ -539,30 +641,32 @@ pub(crate) struct BuiltinDerefNullptr { #[derive(LintDiagnostic)] pub(crate) enum BuiltinSpecialModuleNameUsed { - #[diag(lint_builtin_special_module_name_used_lib)] - #[note] - #[help] + #[diag("found module declaration for lib.rs")] + #[note("lib.rs is the root of this crate's library target")] + #[help("to refer to it from other targets, use the library's name as the path")] Lib, - #[diag(lint_builtin_special_module_name_used_main)] - #[note] + #[diag("found module declaration for main.rs")] + #[note("a binary crate cannot be used as library")] Main, } // deref_into_dyn_supertrait.rs #[derive(LintDiagnostic)] -#[diag(lint_supertrait_as_deref_target)] +#[diag("this `Deref` implementation is covered by an implicit supertrait coercion")] pub(crate) struct SupertraitAsDerefTarget<'a> { pub self_ty: Ty<'a>, pub supertrait_principal: PolyExistentialTraitRef<'a>, pub target_principal: PolyExistentialTraitRef<'a>, - #[label] + #[label( + "`{$self_ty}` implements `Deref` which conflicts with supertrait `{$supertrait_principal}`" + )] pub label: Span, #[subdiagnostic] pub label2: Option, } #[derive(Subdiagnostic)] -#[label(lint_label2)] +#[label("target type is a supertrait of `{$self_ty}`")] pub(crate) struct SupertraitAsDerefTargetLabel { #[primary_span] pub label: Span, @@ -570,32 +674,38 @@ pub(crate) struct SupertraitAsDerefTargetLabel { // enum_intrinsics_non_enums.rs #[derive(LintDiagnostic)] -#[diag(lint_enum_intrinsics_mem_discriminant)] +#[diag("the return value of `mem::discriminant` is unspecified when called with a non-enum type")] pub(crate) struct EnumIntrinsicsMemDiscriminate<'a> { pub ty_param: Ty<'a>, - #[note] + #[note( + "the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum" + )] pub note: Span, } #[derive(LintDiagnostic)] -#[diag(lint_enum_intrinsics_mem_variant)] -#[note] +#[diag("the return value of `mem::variant_count` is unspecified when called with a non-enum type")] +#[note( + "the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum" +)] pub(crate) struct EnumIntrinsicsMemVariant<'a> { pub ty_param: Ty<'a>, } // expect.rs #[derive(LintDiagnostic)] -#[diag(lint_expectation)] +#[diag("this lint expectation is unfulfilled")] pub(crate) struct Expectation { #[subdiagnostic] pub rationale: Option, - #[note] + #[note( + "the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message" + )] pub note: bool, } #[derive(Subdiagnostic)] -#[note(lint_rationale)] +#[note("{$rationale}")] pub(crate) struct ExpectationNote { pub rationale: Symbol, } @@ -603,42 +713,58 @@ pub(crate) struct ExpectationNote { // ptr_nulls.rs #[derive(LintDiagnostic)] pub(crate) enum UselessPtrNullChecksDiag<'a> { - #[diag(lint_useless_ptr_null_checks_fn_ptr)] - #[help] + #[diag( + "function pointers are not nullable, so checking them for null will always return false" + )] + #[help( + "wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value" + )] FnPtr { orig_ty: Ty<'a>, - #[label] + #[label("expression has type `{$orig_ty}`")] label: Span, }, - #[diag(lint_useless_ptr_null_checks_ref)] + #[diag("references are not nullable, so checking them for null will always return false")] Ref { orig_ty: Ty<'a>, - #[label] + #[label("expression has type `{$orig_ty}`")] label: Span, }, - #[diag(lint_useless_ptr_null_checks_fn_ret)] + #[diag( + "returned pointer of `{$fn_name}` call is never null, so checking it for null will always return false" + )] FnRet { fn_name: Ident }, } #[derive(LintDiagnostic)] pub(crate) enum InvalidNullArgumentsDiag { - #[diag(lint_invalid_null_arguments)] - #[help(lint_doc)] + #[diag( + "calling this function with a null pointer is undefined behavior, even if the result of the function is unused" + )] + #[help( + "for more information, visit and " + )] NullPtrInline { - #[label(lint_origin)] + #[label("null pointer originates from here")] null_span: Span, }, - #[diag(lint_invalid_null_arguments)] - #[help(lint_doc)] + #[diag( + "calling this function with a null pointer is undefined behavior, even if the result of the function is unused" + )] + #[help( + "for more information, visit and " + )] NullPtrThroughBinding { - #[note(lint_origin)] + #[note("null pointer originates from here")] null_span: Span, }, } // for_loops_over_fallibles.rs #[derive(LintDiagnostic)] -#[diag(lint_for_loops_over_fallibles)] +#[diag( + "for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement" +)] pub(crate) struct ForLoopsOverFalliblesDiag<'a> { pub article: &'static str, pub ref_prefix: &'static str, @@ -653,13 +779,20 @@ pub(crate) struct ForLoopsOverFalliblesDiag<'a> { #[derive(Subdiagnostic)] pub(crate) enum ForLoopsOverFalliblesLoopSub<'a> { - #[suggestion(lint_remove_next, code = ".by_ref()", applicability = "maybe-incorrect")] + #[suggestion( + "to iterate over `{$recv_snip}` remove the call to `next`", + code = ".by_ref()", + applicability = "maybe-incorrect" + )] RemoveNext { #[primary_span] suggestion: Span, recv_snip: String, }, - #[multipart_suggestion(lint_use_while_let, applicability = "maybe-incorrect")] + #[multipart_suggestion( + "to check pattern in a loop use `while let`", + applicability = "maybe-incorrect" + )] UseWhileLet { #[suggestion_part(code = "while let {var}(")] start_span: Span, @@ -670,14 +803,21 @@ pub(crate) enum ForLoopsOverFalliblesLoopSub<'a> { } #[derive(Subdiagnostic)] -#[suggestion(lint_use_question_mark, code = "?", applicability = "maybe-incorrect")] +#[suggestion( + "consider unwrapping the `Result` with `?` to iterate over its contents", + code = "?", + applicability = "maybe-incorrect" +)] pub(crate) struct ForLoopsOverFalliblesQuestionMark { #[primary_span] pub suggestion: Span, } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "consider using `if let` to clear intent", + applicability = "maybe-incorrect" +)] pub(crate) struct ForLoopsOverFalliblesSuggestion<'a> { pub var: &'a str, #[suggestion_part(code = "if let {var}(")] @@ -688,10 +828,10 @@ pub(crate) struct ForLoopsOverFalliblesSuggestion<'a> { #[derive(Subdiagnostic)] pub(crate) enum UseLetUnderscoreIgnoreSuggestion { - #[note(lint_use_let_underscore_ignore_suggestion)] + #[note("use `let _ = ...` to ignore the expression or result")] Note, #[multipart_suggestion( - lint_use_let_underscore_ignore_suggestion, + "use `let _ = ...` to ignore the expression or result", style = "verbose", applicability = "maybe-incorrect" )] @@ -705,57 +845,62 @@ pub(crate) enum UseLetUnderscoreIgnoreSuggestion { // drop_forget_useless.rs #[derive(LintDiagnostic)] -#[diag(lint_dropping_references)] +#[diag("calls to `std::mem::drop` with a reference instead of an owned value does nothing")] pub(crate) struct DropRefDiag<'a> { pub arg_ty: Ty<'a>, - #[label] + #[label("argument has type `{$arg_ty}`")] pub label: Span, #[subdiagnostic] pub sugg: UseLetUnderscoreIgnoreSuggestion, } #[derive(LintDiagnostic)] -#[diag(lint_dropping_copy_types)] +#[diag("calls to `std::mem::drop` with a value that implements `Copy` does nothing")] pub(crate) struct DropCopyDiag<'a> { pub arg_ty: Ty<'a>, - #[label] + #[label("argument has type `{$arg_ty}`")] pub label: Span, #[subdiagnostic] pub sugg: UseLetUnderscoreIgnoreSuggestion, } #[derive(LintDiagnostic)] -#[diag(lint_forgetting_references)] +#[diag("calls to `std::mem::forget` with a reference instead of an owned value does nothing")] pub(crate) struct ForgetRefDiag<'a> { pub arg_ty: Ty<'a>, - #[label] + #[label("argument has type `{$arg_ty}`")] pub label: Span, #[subdiagnostic] pub sugg: UseLetUnderscoreIgnoreSuggestion, } #[derive(LintDiagnostic)] -#[diag(lint_forgetting_copy_types)] +#[diag("calls to `std::mem::forget` with a value that implements `Copy` does nothing")] pub(crate) struct ForgetCopyDiag<'a> { pub arg_ty: Ty<'a>, - #[label] + #[label("argument has type `{$arg_ty}`")] pub label: Span, #[subdiagnostic] pub sugg: UseLetUnderscoreIgnoreSuggestion, } #[derive(LintDiagnostic)] -#[diag(lint_undropped_manually_drops)] +#[diag( + "calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing" +)] pub(crate) struct UndroppedManuallyDropsDiag<'a> { pub arg_ty: Ty<'a>, - #[label] + #[label("argument has type `{$arg_ty}`")] pub label: Span, #[subdiagnostic] pub suggestion: UndroppedManuallyDropsSuggestion, } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion( + "use `std::mem::ManuallyDrop::into_inner` to get the inner value", + applicability = "machine-applicable" +)] pub(crate) struct UndroppedManuallyDropsSuggestion { #[suggestion_part(code = "std::mem::ManuallyDrop::into_inner(")] pub start_span: Span, @@ -766,33 +911,35 @@ pub(crate) struct UndroppedManuallyDropsSuggestion { // invalid_from_utf8.rs #[derive(LintDiagnostic)] pub(crate) enum InvalidFromUtf8Diag { - #[diag(lint_invalid_from_utf8_unchecked)] + #[diag("calls to `{$method}` with an invalid literal are undefined behavior")] Unchecked { method: String, valid_up_to: usize, - #[label] + #[label("the literal was valid UTF-8 up to the {$valid_up_to} bytes")] label: Span, }, - #[diag(lint_invalid_from_utf8_checked)] + #[diag("calls to `{$method}` with an invalid literal always return an error")] Checked { method: String, valid_up_to: usize, - #[label] + #[label("the literal was valid UTF-8 up to the {$valid_up_to} bytes")] label: Span, }, } // interior_mutable_consts.rs #[derive(LintDiagnostic)] -#[diag(lint_const_item_interior_mutations)] -#[note(lint_temporary)] -#[note(lint_never_original)] -#[help] +#[diag("mutation of an interior mutable `const` item with call to `{$method_name}`")] +#[note("each usage of a `const` item creates a new temporary")] +#[note("only the temporaries and never the original `const {$const_name}` will be modified")] +#[help( + "for more details on interior mutability see " +)] pub(crate) struct ConstItemInteriorMutationsDiag<'tcx> { pub method_name: Ident, pub const_name: Ident, pub const_ty: Ty<'tcx>, - #[label] + #[label("`{$const_name}` is a interior mutable `const` item of type `{$const_ty}`")] pub receiver_span: Span, #[subdiagnostic] pub sugg_static: Option, @@ -801,7 +948,7 @@ pub(crate) struct ConstItemInteriorMutationsDiag<'tcx> { #[derive(Subdiagnostic)] pub(crate) enum ConstItemInteriorMutationsSuggestionStatic { #[suggestion( - lint_suggestion_static, + "for a shared instance of `{$const_name}`, consider making it a `static` item instead", code = "{before}static ", style = "verbose", applicability = "maybe-incorrect" @@ -811,35 +958,47 @@ pub(crate) enum ConstItemInteriorMutationsSuggestionStatic { const_: Span, before: &'static str, }, - #[help(lint_suggestion_static)] + #[help("for a shared instance of `{$const_name}`, consider making it a `static` item instead")] Spanless, } // reference_casting.rs #[derive(LintDiagnostic)] pub(crate) enum InvalidReferenceCastingDiag<'tcx> { - #[diag(lint_invalid_reference_casting_borrow_as_mut)] - #[note(lint_invalid_reference_casting_note_book)] + #[diag( + "casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`" + )] + #[note( + "for more information, visit " + )] BorrowAsMut { - #[label] + #[label("casting happened here")] orig_cast: Option, - #[note(lint_invalid_reference_casting_note_ty_has_interior_mutability)] + #[note( + "even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`" + )] ty_has_interior_mutability: bool, }, - #[diag(lint_invalid_reference_casting_assign_to_ref)] - #[note(lint_invalid_reference_casting_note_book)] + #[diag("assigning to `&T` is undefined behavior, consider using an `UnsafeCell`")] + #[note( + "for more information, visit " + )] AssignToRef { - #[label] + #[label("casting happened here")] orig_cast: Option, - #[note(lint_invalid_reference_casting_note_ty_has_interior_mutability)] + #[note( + "even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`" + )] ty_has_interior_mutability: bool, }, - #[diag(lint_invalid_reference_casting_bigger_layout)] - #[note(lint_layout)] + #[diag( + "casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused" + )] + #[note("casting from `{$from_ty}` ({$from_size} bytes) to `{$to_ty}` ({$to_size} bytes)")] BiggerLayout { - #[label] + #[label("casting happened here")] orig_cast: Option, - #[label(lint_alloc)] + #[label("backing allocation comes from here")] alloc: Span, from_ty: Ty<'tcx>, from_size: u64, @@ -850,108 +1009,143 @@ pub(crate) enum InvalidReferenceCastingDiag<'tcx> { // map_unit_fn.rs #[derive(LintDiagnostic)] -#[diag(lint_map_unit_fn)] -#[note] +#[diag("`Iterator::map` call that discard the iterator's values")] +#[note( + "`Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated" +)] pub(crate) struct MappingToUnit { - #[label(lint_function_label)] + #[label("this function returns `()`, which is likely not what you wanted")] pub function_label: Span, - #[label(lint_argument_label)] + #[label("called `Iterator::map` with callable that returns `()`")] pub argument_label: Span, - #[label(lint_map_label)] + #[label( + "after this call to map, the resulting iterator is `impl Iterator`, which means the only information carried by the iterator is the number of items" + )] pub map_label: Span, - #[suggestion(style = "verbose", code = "for_each", applicability = "maybe-incorrect")] + #[suggestion( + "you might have meant to use `Iterator::for_each`", + style = "verbose", + code = "for_each", + applicability = "maybe-incorrect" + )] pub suggestion: Span, } // internal.rs #[derive(LintDiagnostic)] -#[diag(lint_default_hash_types)] -#[note] +#[diag("prefer `{$preferred}` over `{$used}`, it has better performance")] +#[note("a `use rustc_data_structures::fx::{$preferred}` may be necessary")] pub(crate) struct DefaultHashTypesDiag<'a> { pub preferred: &'a str, pub used: Symbol, } #[derive(LintDiagnostic)] -#[diag(lint_query_instability)] -#[note] +#[diag("using `{$query}` can result in unstable query results")] +#[note( + "if you believe this case to be fine, allow this lint and add a comment explaining your rationale" +)] pub(crate) struct QueryInstability { pub query: Symbol, } #[derive(LintDiagnostic)] -#[diag(lint_query_untracked)] -#[note] +#[diag("`{$method}` accesses information that is not tracked by the query system")] +#[note( + "if you believe this case to be fine, allow this lint and add a comment explaining your rationale" +)] pub(crate) struct QueryUntracked { pub method: Symbol, } #[derive(LintDiagnostic)] -#[diag(lint_span_use_eq_ctxt)] +#[diag("use `.eq_ctxt()` instead of `.ctxt() == .ctxt()`")] pub(crate) struct SpanUseEqCtxtDiag; #[derive(LintDiagnostic)] -#[diag(lint_symbol_intern_string_literal)] -#[help] +#[diag("using `Symbol::intern` on a string literal")] +#[help("consider adding the symbol to `compiler/rustc_span/src/symbol.rs`")] pub(crate) struct SymbolInternStringLiteralDiag; #[derive(LintDiagnostic)] -#[diag(lint_tykind_kind)] +#[diag("usage of `ty::TyKind::`")] pub(crate) struct TykindKind { - #[suggestion(code = "ty", applicability = "maybe-incorrect")] + #[suggestion( + "try using `ty::` directly", + code = "ty", + applicability = "maybe-incorrect" + )] pub suggestion: Span, } #[derive(LintDiagnostic)] -#[diag(lint_tykind)] -#[help] +#[diag("usage of `ty::TyKind`")] +#[help("try using `Ty` instead")] pub(crate) struct TykindDiag; #[derive(LintDiagnostic)] -#[diag(lint_ty_qualified)] +#[diag("usage of qualified `ty::{$ty}`")] pub(crate) struct TyQualified { pub ty: String, - #[suggestion(code = "{ty}", applicability = "maybe-incorrect")] + #[suggestion( + "try importing it and using it unqualified", + code = "{ty}", + applicability = "maybe-incorrect" + )] pub suggestion: Span, } #[derive(LintDiagnostic)] -#[diag(lint_type_ir_inherent_usage)] -#[note] +#[diag("do not use `rustc_type_ir::inherent` unless you're inside of the trait solver")] +#[note( + "the method or struct you're looking for is likely defined somewhere else downstream in the compiler" +)] pub(crate) struct TypeIrInherentUsage; #[derive(LintDiagnostic)] -#[diag(lint_type_ir_trait_usage)] -#[note] +#[diag( + "do not use `rustc_type_ir::Interner` or `rustc_type_ir::InferCtxtLike` unless you're inside of the trait solver" +)] +#[note( + "the method or struct you're looking for is likely defined somewhere else downstream in the compiler" +)] pub(crate) struct TypeIrTraitUsage; #[derive(LintDiagnostic)] -#[diag(lint_type_ir_direct_use)] -#[note] +#[diag("do not use `rustc_type_ir` unless you are implementing type system internals")] +#[note("use `rustc_middle::ty` instead")] pub(crate) struct TypeIrDirectUse; #[derive(LintDiagnostic)] -#[diag(lint_non_glob_import_type_ir_inherent)] +#[diag("non-glob import of `rustc_type_ir::inherent`")] pub(crate) struct NonGlobImportTypeIrInherent { - #[suggestion(code = "{snippet}", applicability = "maybe-incorrect")] + #[suggestion( + "try using a glob import instead", + code = "{snippet}", + applicability = "maybe-incorrect" + )] pub suggestion: Option, pub snippet: &'static str, } #[derive(LintDiagnostic)] -#[diag(lint_lintpass_by_hand)] -#[help] +#[diag("implementing `LintPass` by hand")] +#[help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")] pub(crate) struct LintPassByHand; #[derive(LintDiagnostic)] -#[diag(lint_bad_opt_access)] +#[diag("{$msg}")] pub(crate) struct BadOptAccessDiag<'a> { pub msg: &'a str, } #[derive(LintDiagnostic)] -#[diag(lint_implicit_sysroot_crate_import)] -#[help] +#[diag( + "dangerous use of `extern crate {$name}` which is not guaranteed to exist exactly once in the sysroot" +)] +#[help( + "try using a cargo dependency or using a re-export of the dependency provided by a rustc_* crate" +)] pub(crate) struct ImplicitSysrootCrateImportDiag<'a> { pub name: &'a str, } @@ -959,14 +1153,14 @@ pub(crate) struct ImplicitSysrootCrateImportDiag<'a> { // let_underscore.rs #[derive(LintDiagnostic)] pub(crate) enum NonBindingLet { - #[diag(lint_non_binding_let_on_sync_lock)] + #[diag("non-binding let on a synchronization lock")] SyncLock { - #[label] + #[label("this lock is not assigned to a binding and is immediately dropped")] pat: Span, #[subdiagnostic] sub: NonBindingLetSub, }, - #[diag(lint_non_binding_let_on_drop_type)] + #[diag("non-binding let on a type that has a destructor")] DropType { #[subdiagnostic] sub: NonBindingLetSub, @@ -987,16 +1181,23 @@ impl Subdiagnostic for NonBindingLetSub { let prefix = if self.is_assign_desugar { "let " } else { "" }; diag.span_suggestion_verbose( self.suggestion, - fluent::lint_non_binding_let_suggestion, + inline_fluent!( + "consider binding to an unused variable to avoid immediately dropping the value" + ), format!("{prefix}_unused"), Applicability::MachineApplicable, ); } else { - diag.span_help(self.suggestion, fluent::lint_non_binding_let_suggestion); + diag.span_help( + self.suggestion, + inline_fluent!( + "consider binding to an unused variable to avoid immediately dropping the value" + ), + ); } if let Some(drop_fn_start_end) = self.drop_fn_start_end { diag.multipart_suggestion( - fluent::lint_non_binding_let_multi_suggestion, + inline_fluent!("consider immediately dropping the value"), vec![ (drop_fn_start_end.0, "drop(".to_string()), (drop_fn_start_end.1, ")".to_string()), @@ -1004,16 +1205,18 @@ impl Subdiagnostic for NonBindingLetSub { Applicability::MachineApplicable, ); } else { - diag.help(fluent::lint_non_binding_let_multi_drop_fn); + diag.help(inline_fluent!( + "consider immediately dropping the value using `drop(..)` after the `let` statement" + )); } } } // levels.rs #[derive(LintDiagnostic)] -#[diag(lint_overruled_attribute)] +#[diag("{$lint_level}({$lint_source}) incompatible with previous forbid")] pub(crate) struct OverruledAttributeLint<'a> { - #[label] + #[label("overruled by previous forbid")] pub overruled: Span, pub lint_level: &'a str, pub lint_source: Symbol, @@ -1022,17 +1225,17 @@ pub(crate) struct OverruledAttributeLint<'a> { } #[derive(LintDiagnostic)] -#[diag(lint_deprecated_lint_name)] +#[diag("lint name `{$name}` is deprecated and may not have an effect in the future")] pub(crate) struct DeprecatedLintName<'a> { pub name: String, - #[suggestion(code = "{replace}", applicability = "machine-applicable")] + #[suggestion("change it to", code = "{replace}", applicability = "machine-applicable")] pub suggestion: Span, pub replace: &'a str, } #[derive(LintDiagnostic)] -#[diag(lint_deprecated_lint_name)] -#[help] +#[diag("lint name `{$name}` is deprecated and may not have an effect in the future")] +#[help("change it to {$replace}")] pub(crate) struct DeprecatedLintNameFromCommandLine<'a> { pub name: String, pub replace: &'a str, @@ -1041,7 +1244,7 @@ pub(crate) struct DeprecatedLintNameFromCommandLine<'a> { } #[derive(LintDiagnostic)] -#[diag(lint_renamed_lint)] +#[diag("lint `{$name}` has been renamed to `{$replace}`")] pub(crate) struct RenamedLint<'a> { pub name: &'a str, pub replace: &'a str, @@ -1051,18 +1254,18 @@ pub(crate) struct RenamedLint<'a> { #[derive(Subdiagnostic)] pub(crate) enum RenamedLintSuggestion<'a> { - #[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")] + #[suggestion("use the new name", code = "{replace}", applicability = "machine-applicable")] WithSpan { #[primary_span] suggestion: Span, replace: &'a str, }, - #[help(lint_help)] + #[help("use the new name `{$replace}`")] WithoutSpan { replace: &'a str }, } #[derive(LintDiagnostic)] -#[diag(lint_renamed_lint)] +#[diag("lint `{$name}` has been renamed to `{$replace}`")] pub(crate) struct RenamedLintFromCommandLine<'a> { pub name: &'a str, pub replace: &'a str, @@ -1073,14 +1276,14 @@ pub(crate) struct RenamedLintFromCommandLine<'a> { } #[derive(LintDiagnostic)] -#[diag(lint_removed_lint)] +#[diag("lint `{$name}` has been removed: {$reason}")] pub(crate) struct RemovedLint<'a> { pub name: &'a str, pub reason: &'a str, } #[derive(LintDiagnostic)] -#[diag(lint_removed_lint)] +#[diag("lint `{$name}` has been removed: {$reason}")] pub(crate) struct RemovedLintFromCommandLine<'a> { pub name: &'a str, pub reason: &'a str, @@ -1089,7 +1292,7 @@ pub(crate) struct RemovedLintFromCommandLine<'a> { } #[derive(LintDiagnostic)] -#[diag(lint_unknown_lint)] +#[diag("unknown lint: `{$name}`")] pub(crate) struct UnknownLint { pub name: String, #[subdiagnostic] @@ -1098,19 +1301,31 @@ pub(crate) struct UnknownLint { #[derive(Subdiagnostic)] pub(crate) enum UnknownLintSuggestion { - #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")] + #[suggestion( + "{$from_rustc -> + [true] a lint with a similar name exists in `rustc` lints + *[false] did you mean + }", + code = "{replace}", + applicability = "maybe-incorrect" + )] WithSpan { #[primary_span] suggestion: Span, replace: Symbol, from_rustc: bool, }, - #[help(lint_help)] + #[help( + "{$from_rustc -> + [true] a lint with a similar name exists in `rustc` lints: `{$replace}` + *[false] did you mean: `{$replace}` + }" + )] WithoutSpan { replace: Symbol, from_rustc: bool }, } #[derive(LintDiagnostic)] -#[diag(lint_unknown_lint, code = E0602)] +#[diag("unknown lint: `{$name}`", code = E0602)] pub(crate) struct UnknownLintFromCommandLine<'a> { pub name: String, #[subdiagnostic] @@ -1120,7 +1335,7 @@ pub(crate) struct UnknownLintFromCommandLine<'a> { } #[derive(LintDiagnostic)] -#[diag(lint_ignored_unless_crate_specified)] +#[diag("{$level}({$name}) is ignored unless specified at crate level")] pub(crate) struct IgnoredUnlessCrateSpecified<'a> { pub level: &'a str, pub name: Symbol, @@ -1128,53 +1343,78 @@ pub(crate) struct IgnoredUnlessCrateSpecified<'a> { // dangling.rs #[derive(LintDiagnostic)] -#[diag(lint_dangling_pointers_from_temporaries)] -#[help(lint_help_bind)] -#[note(lint_note_safe)] -#[note(lint_note_return)] -#[note(lint_note_more_info)] +#[diag("this creates a dangling pointer because temporary `{$ty}` is dropped at end of statement")] +#[help("bind the `{$ty}` to a variable such that it outlives the pointer returned by `{$callee}`")] +#[note("a dangling pointer is safe, but dereferencing one is undefined behavior")] +#[note("returning a pointer to a local variable will always result in a dangling pointer")] +#[note("for more information, see ")] // FIXME: put #[primary_span] on `ptr_span` once it does not cause conflicts pub(crate) struct DanglingPointersFromTemporaries<'tcx> { pub callee: Ident, pub ty: Ty<'tcx>, - #[label(lint_label_ptr)] + #[label("pointer created here")] pub ptr_span: Span, - #[label(lint_label_temporary)] + #[label("this `{$ty}` is dropped at end of statement")] pub temporary_span: Span, } #[derive(LintDiagnostic)] -#[diag(lint_dangling_pointers_from_locals)] -#[note(lint_note_safe)] -#[note(lint_note_more_info)] +#[diag("{$fn_kind} returns a dangling pointer to dropped local variable `{$local_var_name}`")] +#[note("a dangling pointer is safe, but dereferencing one is undefined behavior")] +#[note("for more information, see ")] pub(crate) struct DanglingPointersFromLocals<'tcx> { pub ret_ty: Ty<'tcx>, - #[label(lint_ret_ty)] + #[label("return type is `{$ret_ty}`")] pub ret_ty_span: Span, pub fn_kind: &'static str, - #[label(lint_local_var)] + #[label("local variable `{$local_var_name}` is dropped at the end of the {$fn_kind}")] pub local_var: Span, pub local_var_name: Ident, pub local_var_ty: Ty<'tcx>, - #[label(lint_created_at)] + #[label("dangling pointer created here")] pub created_at: Option, } // multiple_supertrait_upcastable.rs #[derive(LintDiagnostic)] -#[diag(lint_multiple_supertrait_upcastable)] +#[diag("`{$ident}` is dyn-compatible and has multiple supertraits")] pub(crate) struct MultipleSupertraitUpcastable { pub ident: Ident, } // non_ascii_idents.rs #[derive(LintDiagnostic)] -#[diag(lint_identifier_non_ascii_char)] +#[diag("identifier contains non-ASCII characters")] pub(crate) struct IdentifierNonAsciiChar; #[derive(LintDiagnostic)] -#[diag(lint_identifier_uncommon_codepoints)] -#[note] +#[diag( + "identifier contains {$codepoints_len -> + [one] { $identifier_type -> + [Exclusion] a character from an archaic script + [Technical] a character that is for non-linguistic, specialized usage + [Limited_Use] a character from a script in limited use + [Not_NFKC] a non normalized (NFKC) character + *[other] an uncommon character + } + *[other] { $identifier_type -> + [Exclusion] {$codepoints_len} characters from archaic scripts + [Technical] {$codepoints_len} characters that are for non-linguistic, specialized usage + [Limited_Use] {$codepoints_len} characters from scripts in limited use + [Not_NFKC] {$codepoints_len} non normalized (NFKC) characters + *[other] uncommon characters + } + }: {$codepoints}" +)] +#[note( + r#"{$codepoints_len -> + [one] this character is + *[other] these characters are + } included in the{$identifier_type -> + [Restricted] {""} + *[other] {" "}{$identifier_type} + } Unicode general security profile"# +)] pub(crate) struct IdentifierUncommonCodepoints { pub codepoints: Vec, pub codepoints_len: usize, @@ -1182,20 +1422,22 @@ pub(crate) struct IdentifierUncommonCodepoints { } #[derive(LintDiagnostic)] -#[diag(lint_confusable_identifier_pair)] +#[diag("found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike")] pub(crate) struct ConfusableIdentifierPair { pub existing_sym: Symbol, pub sym: Symbol, - #[label(lint_other_use)] + #[label("other identifier used here")] pub label: Span, - #[label(lint_current_use)] + #[label("this identifier can be confused with `{$existing_sym}`")] pub main_label: Span, } #[derive(LintDiagnostic)] -#[diag(lint_mixed_script_confusables)] -#[note(lint_includes_note)] -#[note] +#[diag( + "the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables" +)] +#[note("the usage includes {$includes}")] +#[note("please recheck to make sure their usages are indeed what you want")] pub(crate) struct MixedScriptConfusables { pub set: String, pub includes: String, @@ -1210,19 +1452,34 @@ pub(crate) struct NonFmtPanicUnused { // Used because of two suggestions based on one Option impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - diag.primary_message(fluent::lint_non_fmt_panic_unused); + diag.primary_message(inline_fluent!( + "panic message contains {$count -> + [one] an unused + *[other] unused + } formatting {$count -> + [one] placeholder + *[other] placeholders + }" + )); diag.arg("count", self.count); - diag.note(fluent::lint_note); + diag.note(inline_fluent!("this message is not used as a format string when given without arguments, but will be in Rust 2021")); if let Some(span) = self.suggestion { diag.span_suggestion( span.shrink_to_hi(), - fluent::lint_add_args_suggestion, + inline_fluent!( + "add the missing {$count -> + [one] argument + *[other] arguments + }" + ), ", ...", Applicability::HasPlaceholders, ); diag.span_suggestion( span.shrink_to_lo(), - fluent::lint_add_fmt_suggestion, + inline_fluent!( + r#"or add a "{"{"}{"}"}" format string to use the message literally"# + ), "\"{}\", ", Applicability::MachineApplicable, ); @@ -1231,17 +1488,26 @@ impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { } #[derive(LintDiagnostic)] -#[diag(lint_non_fmt_panic_braces)] -#[note] +#[diag( + "panic message contains {$count -> + [one] a brace + *[other] braces + }" +)] +#[note("this message is not used as a format string, but will be in Rust 2021")] pub(crate) struct NonFmtPanicBraces { pub count: usize, - #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")] + #[suggestion( + "add a \"{\"{\"}{\"}\"}\" format string to use the message literally", + code = "\"{{}}\", ", + applicability = "machine-applicable" + )] pub suggestion: Option, } // nonstandard_style.rs #[derive(LintDiagnostic)] -#[diag(lint_non_camel_case_type)] +#[diag("{$sort} `{$name}` should have an upper camel case name")] pub(crate) struct NonCamelCaseType<'a> { pub sort: &'a str, pub name: &'a str, @@ -1251,12 +1517,16 @@ pub(crate) struct NonCamelCaseType<'a> { #[derive(Subdiagnostic)] pub(crate) enum NonCamelCaseTypeSub { - #[label(lint_label)] + #[label("should have an UpperCamelCase name")] Label { #[primary_span] span: Span, }, - #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")] + #[suggestion( + "convert the identifier to upper camel case", + code = "{replace}", + applicability = "maybe-incorrect" + )] Suggestion { #[primary_span] span: Span, @@ -1265,7 +1535,7 @@ pub(crate) enum NonCamelCaseTypeSub { } #[derive(LintDiagnostic)] -#[diag(lint_non_snake_case)] +#[diag("{$sort} `{$name}` should have a snake case name")] pub(crate) struct NonSnakeCaseDiag<'a> { pub sort: &'a str, pub name: &'a str, @@ -1286,15 +1556,15 @@ impl Subdiagnostic for NonSnakeCaseDiagSub { fn add_to_diag(self, diag: &mut Diag<'_, G>) { match self { NonSnakeCaseDiagSub::Label { span } => { - diag.span_label(span, fluent::lint_label); + diag.span_label(span, inline_fluent!("should have a snake_case name")); } NonSnakeCaseDiagSub::Help => { - diag.help(fluent::lint_help); + diag.help(inline_fluent!("convert the identifier to snake case: `{$sc}`")); } NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => { diag.span_suggestion( span, - fluent::lint_convert_suggestion, + inline_fluent!("convert the identifier to snake case"), suggestion, Applicability::MaybeIncorrect, ); @@ -1302,16 +1572,18 @@ impl Subdiagnostic for NonSnakeCaseDiagSub { NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => { diag.span_suggestion( span, - fluent::lint_rename_or_convert_suggestion, + inline_fluent!( + "rename the identifier or convert it to a snake case raw identifier" + ), suggestion, Applicability::MaybeIncorrect, ); } NonSnakeCaseDiagSub::SuggestionAndNote { span } => { - diag.note(fluent::lint_cannot_convert_note); + diag.note(inline_fluent!("`{$sc}` cannot be used as a raw identifier")); diag.span_suggestion( span, - fluent::lint_rename_suggestion, + inline_fluent!("rename the identifier"), "", Applicability::MaybeIncorrect, ); @@ -1321,7 +1593,7 @@ impl Subdiagnostic for NonSnakeCaseDiagSub { } #[derive(LintDiagnostic)] -#[diag(lint_non_upper_case_global)] +#[diag("{$sort} `{$name}` should have an upper case name")] pub(crate) struct NonUpperCaseGlobal<'a> { pub sort: &'a str, pub name: &'a str, @@ -1333,12 +1605,12 @@ pub(crate) struct NonUpperCaseGlobal<'a> { #[derive(Subdiagnostic)] pub(crate) enum NonUpperCaseGlobalSub { - #[label(lint_label)] + #[label("should have an UPPER_CASE name")] Label { #[primary_span] span: Span, }, - #[suggestion(lint_suggestion, code = "{replace}")] + #[suggestion("convert the identifier to upper case", code = "{replace}")] Suggestion { #[primary_span] span: Span, @@ -1350,7 +1622,7 @@ pub(crate) enum NonUpperCaseGlobalSub { #[derive(Subdiagnostic)] #[suggestion( - lint_suggestion, + "convert the identifier to upper case", code = "{replace}", applicability = "machine-applicable", style = "tool-only" @@ -1363,16 +1635,18 @@ pub(crate) struct NonUpperCaseGlobalSubTool { // noop_method_call.rs #[derive(LintDiagnostic)] -#[diag(lint_noop_method_call)] -#[note] +#[diag("call to `.{$method}()` on a reference in this situation does nothing")] +#[note( + "the type `{$orig_ty}` does not implement `{$trait_}`, so calling `{$method}` on `&{$orig_ty}` copies the reference, which does not do anything and can be removed" +)] pub(crate) struct NoopMethodCallDiag<'a> { pub method: Ident, pub orig_ty: Ty<'a>, pub trait_: Symbol, - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove this redundant call", code = "", applicability = "machine-applicable")] pub label: Span, #[suggestion( - lint_derive_suggestion, + "if you meant to clone `{$orig_ty}`, implement `Clone` for it", code = "#[derive(Clone)]\n", applicability = "maybe-incorrect" )] @@ -1380,13 +1654,17 @@ pub(crate) struct NoopMethodCallDiag<'a> { } #[derive(LintDiagnostic)] -#[diag(lint_suspicious_double_ref_deref)] +#[diag( + "using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type" +)] pub(crate) struct SuspiciousDoubleRefDerefDiag<'a> { pub ty: Ty<'a>, } #[derive(LintDiagnostic)] -#[diag(lint_suspicious_double_ref_clone)] +#[diag( + "using `.clone()` on a double reference, which returns `{$ty}` instead of cloning the inner type" +)] pub(crate) struct SuspiciousDoubleRefCloneDiag<'a> { pub ty: Ty<'a>, } @@ -1423,7 +1701,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { doctest, macro_to_change, } => { - diag.primary_message(fluent::lint_non_local_definitions_impl); + diag.primary_message(inline_fluent!("non-local `impl` definition, `impl` blocks should be written at the same level as their item")); diag.arg("depth", depth); diag.arg("body_kind_descr", body_kind_descr); diag.arg("body_name", body_name); @@ -1431,24 +1709,24 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { if let Some((macro_to_change, macro_kind)) = macro_to_change { diag.arg("macro_to_change", macro_to_change); diag.arg("macro_kind", macro_kind); - diag.note(fluent::lint_macro_to_change); + diag.note(inline_fluent!("the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed")); } if let Some(cargo_update) = cargo_update { diag.subdiagnostic(cargo_update); } - diag.note(fluent::lint_non_local); + diag.note(inline_fluent!("an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`")); if doctest { - diag.help(fluent::lint_doctest); + diag.help(inline_fluent!("make this doc-test a standalone test with its own `fn main() {\"{\"} ... {\"}\"}`")); } if let Some(const_anon) = const_anon { - diag.note(fluent::lint_exception); + diag.note(inline_fluent!("items in an anonymous const item (`const _: () = {\"{\"} ... {\"}\"}`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint")); if let Some(const_anon) = const_anon { diag.span_suggestion( const_anon, - fluent::lint_const_anon, + inline_fluent!("use a const-anon item to suppress this lint"), "_", Applicability::MachineApplicable, ); @@ -1462,18 +1740,21 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { doctest, cargo_update, } => { - diag.primary_message(fluent::lint_non_local_definitions_macro_rules); + diag.primary_message(inline_fluent!("non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module")); diag.arg("depth", depth); diag.arg("body_kind_descr", body_kind_descr); diag.arg("body_name", body_name); if doctest { - diag.help(fluent::lint_help_doctest); + diag.help(inline_fluent!(r#"remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`"#)); } else { - diag.help(fluent::lint_help); + diag.help(inline_fluent!("remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth -> + [one] `{$body_name}` + *[other] `{$body_name}` and up {$depth} bodies + }")); } - diag.note(fluent::lint_non_local); + diag.note(inline_fluent!("a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute")); if let Some(cargo_update) = cargo_update { diag.subdiagnostic(cargo_update); @@ -1484,7 +1765,9 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { } #[derive(Subdiagnostic)] -#[note(lint_non_local_definitions_cargo_update)] +#[note( + "the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}`" +)] pub(crate) struct NonLocalDefinitionsCargoUpdateNote { pub macro_kind: &'static str, pub macro_name: Symbol, @@ -1493,8 +1776,8 @@ pub(crate) struct NonLocalDefinitionsCargoUpdateNote { // precedence.rs #[derive(LintDiagnostic)] -#[diag(lint_ambiguous_negative_literals)] -#[note(lint_example)] +#[diag("`-` has lower precedence than method calls, which might be unexpected")] +#[note("e.g. `-4.abs()` equals `-4`; while `(-4).abs()` equals `4`")] pub(crate) struct AmbiguousNegativeLiteralsDiag { #[subdiagnostic] pub negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion, @@ -1503,7 +1786,10 @@ pub(crate) struct AmbiguousNegativeLiteralsDiag { } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_negative_literal, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "add parentheses around the `-` and the literal to call the method on a negative literal", + applicability = "maybe-incorrect" +)] pub(crate) struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion { #[suggestion_part(code = "(")] pub start_span: Span, @@ -1512,7 +1798,10 @@ pub(crate) struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion { } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_current_behavior, applicability = "maybe-incorrect")] +#[multipart_suggestion( + "add parentheses around the literal and the method call to keep the current behavior", + applicability = "maybe-incorrect" +)] pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion { #[suggestion_part(code = "(")] pub start_span: Span, @@ -1522,16 +1811,21 @@ pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion { // pass_by_value.rs #[derive(LintDiagnostic)] -#[diag(lint_pass_by_value)] +#[diag("passing `{$ty}` by reference")] pub(crate) struct PassByValueDiag { pub ty: String, - #[suggestion(code = "{ty}", applicability = "maybe-incorrect")] + #[suggestion("try passing by value", code = "{ty}", applicability = "maybe-incorrect")] pub suggestion: Span, } // redundant_semicolon.rs #[derive(LintDiagnostic)] -#[diag(lint_redundant_semicolons)] +#[diag( + "unnecessary trailing {$multiple -> + [true] semicolons + *[false] semicolon + }" +)] pub(crate) struct RedundantSemicolonsDiag { pub multiple: bool, #[subdiagnostic] @@ -1539,7 +1833,14 @@ pub(crate) struct RedundantSemicolonsDiag { } #[derive(Subdiagnostic)] -#[suggestion(lint_redundant_semicolons_suggestion, code = "", applicability = "maybe-incorrect")] +#[suggestion( + "remove {$multiple_semicolons -> + [true] these semicolons + *[false] this semicolon + }", + code = "", + applicability = "maybe-incorrect" +)] pub(crate) struct RedundantSemicolonsSuggestion { pub multiple_semicolons: bool, #[primary_span] @@ -1556,7 +1857,7 @@ pub(crate) struct DropTraitConstraintsDiag<'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - diag.primary_message(fluent::lint_drop_trait_constraints); + diag.primary_message(inline_fluent!("bounds on `{$predicate}` are most likely incorrect, consider instead using `{$needs_drop}` to detect whether a type can be trivially dropped")); diag.arg("predicate", self.predicate); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); } @@ -1570,19 +1871,27 @@ pub(crate) struct DropGlue<'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - diag.primary_message(fluent::lint_drop_glue); + diag.primary_message(inline_fluent!("types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped")); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); } } // transmute.rs #[derive(LintDiagnostic)] -#[diag(lint_int_to_ptr_transmutes)] -#[note] -#[note(lint_note_exposed_provenance)] -#[help(lint_suggestion_without_provenance_mut)] -#[help(lint_help_transmute)] -#[help(lint_help_exposed_provenance)] +#[diag("transmuting an integer to a pointer creates a pointer without provenance")] +#[note("this is dangerous because dereferencing the resulting pointer is undefined behavior")] +#[note( + "exposed provenance semantics can be used to create a pointer based on some previously exposed provenance" +)] +#[help( + "if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`" +)] +#[help( + "for more information about transmute, see " +)] +#[help( + "for more information about exposed provenance, see " +)] pub(crate) struct IntegerToPtrTransmutes<'tcx> { #[subdiagnostic] pub suggestion: Option>, @@ -1591,7 +1900,7 @@ pub(crate) struct IntegerToPtrTransmutes<'tcx> { #[derive(Subdiagnostic)] pub(crate) enum IntegerToPtrTransmutesSuggestion<'tcx> { #[multipart_suggestion( - lint_suggestion_with_exposed_provenance, + "use `std::ptr::with_exposed_provenance{$suffix}` instead to use a previously exposed provenance", applicability = "machine-applicable", style = "verbose" )] @@ -1602,7 +1911,7 @@ pub(crate) enum IntegerToPtrTransmutesSuggestion<'tcx> { start_call: Span, }, #[multipart_suggestion( - lint_suggestion_with_exposed_provenance, + "use `std::ptr::with_exposed_provenance{$suffix}` instead to use a previously exposed provenance", applicability = "machine-applicable", style = "verbose" )] @@ -1619,7 +1928,7 @@ pub(crate) enum IntegerToPtrTransmutesSuggestion<'tcx> { // types.rs #[derive(LintDiagnostic)] -#[diag(lint_range_endpoint_out_of_range)] +#[diag("range endpoint is out of range for `{$ty}`")] pub(crate) struct RangeEndpointOutOfRange<'a> { pub ty: &'a str, #[subdiagnostic] @@ -1629,7 +1938,7 @@ pub(crate) struct RangeEndpointOutOfRange<'a> { #[derive(Subdiagnostic)] pub(crate) enum UseInclusiveRange<'a> { #[suggestion( - lint_range_use_inclusive_range, + "use an inclusive range instead", code = "{start}..={literal}{suffix}", applicability = "machine-applicable" )] @@ -1640,7 +1949,7 @@ pub(crate) enum UseInclusiveRange<'a> { literal: u128, suffix: &'a str, }, - #[multipart_suggestion(lint_range_use_inclusive_range, applicability = "machine-applicable")] + #[multipart_suggestion("use an inclusive range instead", applicability = "machine-applicable")] WithParen { #[suggestion_part(code = "=")] eq_sugg: Span, @@ -1652,7 +1961,7 @@ pub(crate) enum UseInclusiveRange<'a> { } #[derive(LintDiagnostic)] -#[diag(lint_overflowing_bin_hex)] +#[diag("literal out of range for `{$ty}`")] pub(crate) struct OverflowingBinHex<'a> { pub ty: &'a str, pub lit: String, @@ -1675,11 +1984,13 @@ impl Subdiagnostic for OverflowingBinHexSign { fn add_to_diag(self, diag: &mut Diag<'_, G>) { match self { OverflowingBinHexSign::Positive => { - diag.note(fluent::lint_positive_note); + diag.note(inline_fluent!("the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`")); } OverflowingBinHexSign::Negative => { - diag.note(fluent::lint_negative_note); - diag.note(fluent::lint_negative_becomes_note); + diag.note(inline_fluent!( + "the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`" + )); + diag.note(inline_fluent!("and the value `-{$lit}` will become `{$actually}{$ty}`")); } } } @@ -1688,7 +1999,7 @@ impl Subdiagnostic for OverflowingBinHexSign { #[derive(Subdiagnostic)] pub(crate) enum OverflowingBinHexSub<'a> { #[suggestion( - lint_suggestion, + "consider using the type `{$suggestion_ty}` instead", code = "{sans_suffix}{suggestion_ty}", applicability = "machine-applicable" )] @@ -1698,13 +2009,13 @@ pub(crate) enum OverflowingBinHexSub<'a> { suggestion_ty: &'a str, sans_suffix: &'a str, }, - #[help(lint_help)] + #[help("consider using the type `{$suggestion_ty}` instead")] Help { suggestion_ty: &'a str }, } #[derive(Subdiagnostic)] #[suggestion( - lint_sign_bit_suggestion, + "to use as a negative number (decimal `{$negative_val}`), consider using the type `{$uint_ty}` for the literal and cast it to `{$int_ty}`", code = "{lit_no_suffix}{uint_ty} as {int_ty}", applicability = "maybe-incorrect" )] @@ -1718,8 +2029,8 @@ pub(crate) struct OverflowingBinHexSignBitSub<'a> { } #[derive(LintDiagnostic)] -#[diag(lint_overflowing_int)] -#[note] +#[diag("literal out of range for `{$ty}`")] +#[note("the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`")] pub(crate) struct OverflowingInt<'a> { pub ty: &'a str, pub lit: String, @@ -1730,22 +2041,26 @@ pub(crate) struct OverflowingInt<'a> { } #[derive(Subdiagnostic)] -#[help(lint_help)] +#[help("consider using the type `{$suggestion_ty}` instead")] pub(crate) struct OverflowingIntHelp<'a> { pub suggestion_ty: &'a str, } #[derive(LintDiagnostic)] -#[diag(lint_only_cast_u8_to_char)] +#[diag("only `u8` can be cast into `char`")] pub(crate) struct OnlyCastu8ToChar { - #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")] + #[suggestion( + "use a `char` literal instead", + code = "'\\u{{{literal:X}}}'", + applicability = "machine-applicable" + )] pub span: Span, pub literal: u128, } #[derive(LintDiagnostic)] -#[diag(lint_overflowing_uint)] -#[note] +#[diag("literal out of range for `{$ty}`")] +#[note("the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`")] pub(crate) struct OverflowingUInt<'a> { pub ty: &'a str, pub lit: String, @@ -1754,50 +2069,54 @@ pub(crate) struct OverflowingUInt<'a> { } #[derive(LintDiagnostic)] -#[diag(lint_overflowing_literal)] -#[note] +#[diag("literal out of range for `{$ty}`")] +#[note( + "the literal `{$lit}` does not fit into the type `{$ty}` and will be converted to `{$ty}::INFINITY`" +)] pub(crate) struct OverflowingLiteral<'a> { pub ty: &'a str, pub lit: String, } #[derive(LintDiagnostic)] -#[diag(lint_surrogate_char_cast)] -#[note] +#[diag("surrogate values are not valid for `char`")] +#[note("`0xD800..=0xDFFF` are reserved for Unicode surrogates and are not valid `char` values")] pub(crate) struct SurrogateCharCast { pub literal: u128, } #[derive(LintDiagnostic)] -#[diag(lint_too_large_char_cast)] -#[note] +#[diag("value exceeds maximum `char` value")] +#[note("maximum valid `char` value is `0x10FFFF`")] pub(crate) struct TooLargeCharCast { pub literal: u128, } #[derive(LintDiagnostic)] -#[diag(lint_uses_power_alignment)] +#[diag( + "repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type" +)] pub(crate) struct UsesPowerAlignment; #[derive(LintDiagnostic)] -#[diag(lint_unused_comparisons)] +#[diag("comparison is useless due to type limits")] pub(crate) struct UnusedComparisons; #[derive(LintDiagnostic)] pub(crate) enum InvalidNanComparisons { - #[diag(lint_invalid_nan_comparisons_eq_ne)] + #[diag("incorrect NaN comparison, NaN cannot be directly compared to itself")] EqNe { #[subdiagnostic] suggestion: InvalidNanComparisonsSuggestion, }, - #[diag(lint_invalid_nan_comparisons_lt_le_gt_ge)] + #[diag("incorrect NaN comparison, NaN is not orderable")] LtLeGtGe, } #[derive(Subdiagnostic)] pub(crate) enum InvalidNanComparisonsSuggestion { #[multipart_suggestion( - lint_suggestion, + "use `f32::is_nan()` or `f64::is_nan()` instead", style = "verbose", applicability = "machine-applicable" )] @@ -1809,35 +2128,41 @@ pub(crate) enum InvalidNanComparisonsSuggestion { #[suggestion_part(code = "")] nan_plus_binop: Span, }, - #[help(lint_suggestion)] + #[help("use `f32::is_nan()` or `f64::is_nan()` instead")] Spanless, } #[derive(LintDiagnostic)] pub(crate) enum AmbiguousWidePointerComparisons<'a> { - #[diag(lint_ambiguous_wide_pointer_comparisons)] + #[diag( + "ambiguous wide pointer comparison, the comparison includes metadata which may not be expected" + )] SpanfulEq { #[subdiagnostic] addr_suggestion: AmbiguousWidePointerComparisonsAddrSuggestion<'a>, #[subdiagnostic] addr_metadata_suggestion: Option>, }, - #[diag(lint_ambiguous_wide_pointer_comparisons)] + #[diag( + "ambiguous wide pointer comparison, the comparison includes metadata which may not be expected" + )] SpanfulCmp { #[subdiagnostic] cast_suggestion: AmbiguousWidePointerComparisonsCastSuggestion<'a>, #[subdiagnostic] expect_suggestion: AmbiguousWidePointerComparisonsExpectSuggestion<'a>, }, - #[diag(lint_ambiguous_wide_pointer_comparisons)] - #[help(lint_addr_metadata_suggestion)] - #[help(lint_addr_suggestion)] + #[diag( + "ambiguous wide pointer comparison, the comparison includes metadata which may not be expected" + )] + #[help("use explicit `std::ptr::eq` method to compare metadata and addresses")] + #[help("use `std::ptr::addr_eq` or untyped pointers to only compare their addresses")] Spanless, } #[derive(Subdiagnostic)] #[multipart_suggestion( - lint_addr_metadata_suggestion, + "use explicit `std::ptr::eq` method to compare metadata and addresses", style = "verbose", // FIXME(#53934): make machine-applicable again applicability = "maybe-incorrect" @@ -1858,7 +2183,7 @@ pub(crate) struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> { #[derive(Subdiagnostic)] #[multipart_suggestion( - lint_addr_suggestion, + "use `std::ptr::addr_eq` or untyped pointers to only compare their addresses", style = "verbose", // FIXME(#53934): make machine-applicable again applicability = "maybe-incorrect" @@ -1879,7 +2204,7 @@ pub(crate) struct AmbiguousWidePointerComparisonsAddrSuggestion<'a> { #[derive(Subdiagnostic)] #[multipart_suggestion( - lint_cast_suggestion, + "use untyped pointers to only compare their addresses", style = "verbose", // FIXME(#53934): make machine-applicable again applicability = "maybe-incorrect" @@ -1903,7 +2228,7 @@ pub(crate) struct AmbiguousWidePointerComparisonsCastSuggestion<'a> { #[derive(Subdiagnostic)] #[multipart_suggestion( - lint_expect_suggestion, + "or expect the lint to compare the pointers metadata and addresses", style = "verbose", // FIXME(#53934): make machine-applicable again applicability = "maybe-incorrect" @@ -1922,25 +2247,37 @@ pub(crate) struct AmbiguousWidePointerComparisonsExpectSuggestion<'a> { #[derive(LintDiagnostic)] pub(crate) enum UnpredictableFunctionPointerComparisons<'a, 'tcx> { - #[diag(lint_unpredictable_fn_pointer_comparisons)] - #[note(lint_note_duplicated_fn)] - #[note(lint_note_deduplicated_fn)] - #[note(lint_note_visit_fn_addr_eq)] + #[diag( + "function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique" + )] + #[note("the address of the same function can vary between different codegen units")] + #[note( + "furthermore, different functions could have the same address after being merged together" + )] + #[note( + "for more information visit " + )] Suggestion { #[subdiagnostic] sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx>, }, - #[diag(lint_unpredictable_fn_pointer_comparisons)] - #[note(lint_note_duplicated_fn)] - #[note(lint_note_deduplicated_fn)] - #[note(lint_note_visit_fn_addr_eq)] + #[diag( + "function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique" + )] + #[note("the address of the same function can vary between different codegen units")] + #[note( + "furthermore, different functions could have the same address after being merged together" + )] + #[note( + "for more information visit " + )] Warn, } #[derive(Subdiagnostic)] pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> { #[multipart_suggestion( - lint_fn_addr_eq_suggestion, + "refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint", style = "verbose", applicability = "maybe-incorrect" )] @@ -1956,7 +2293,7 @@ pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> { right: Span, }, #[multipart_suggestion( - lint_fn_addr_eq_suggestion, + "refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint", style = "verbose", applicability = "maybe-incorrect" )] @@ -1986,69 +2323,73 @@ pub(crate) struct ImproperCTypes<'a> { // Used because of the complexity of Option, DiagMessage, and Option impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - diag.primary_message(fluent::lint_improper_ctypes); + diag.primary_message(inline_fluent!( + "`extern` {$desc} uses type `{$ty}`, which is not FFI-safe" + )); diag.arg("ty", self.ty); diag.arg("desc", self.desc); - diag.span_label(self.label, fluent::lint_label); + diag.span_label(self.label, inline_fluent!("not FFI-safe")); if let Some(help) = self.help { diag.help(help); } diag.note(self.note); if let Some(note) = self.span_note { - diag.span_note(note, fluent::lint_note); + diag.span_note(note, inline_fluent!("the type is defined here")); } } } #[derive(LintDiagnostic)] -#[diag(lint_improper_gpu_kernel_arg)] -#[help] +#[diag("passing type `{$ty}` to a function with \"gpu-kernel\" ABI may have unexpected behavior")] +#[help("use primitive types and raw pointers to get reliable behavior")] pub(crate) struct ImproperGpuKernelArg<'a> { pub ty: Ty<'a>, } #[derive(LintDiagnostic)] -#[diag(lint_missing_gpu_kernel_export_name)] -#[help] -#[note] +#[diag("function with the \"gpu-kernel\" ABI has a mangled name")] +#[help("use `unsafe(no_mangle)` or `unsafe(export_name = \"\")`")] +#[note("mangled names make it hard to find the kernel, this is usually not intended")] pub(crate) struct MissingGpuKernelExportName; #[derive(LintDiagnostic)] -#[diag(lint_variant_size_differences)] +#[diag("enum variant is more than three times larger ({$largest} bytes) than the next largest")] pub(crate) struct VariantSizeDifferencesDiag { pub largest: u64, } #[derive(LintDiagnostic)] -#[diag(lint_atomic_ordering_load)] -#[help] +#[diag("atomic loads cannot have `Release` or `AcqRel` ordering")] +#[help("consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`")] pub(crate) struct AtomicOrderingLoad; #[derive(LintDiagnostic)] -#[diag(lint_atomic_ordering_store)] -#[help] +#[diag("atomic stores cannot have `Acquire` or `AcqRel` ordering")] +#[help("consider using ordering modes `Release`, `SeqCst` or `Relaxed`")] pub(crate) struct AtomicOrderingStore; #[derive(LintDiagnostic)] -#[diag(lint_atomic_ordering_fence)] -#[help] +#[diag("memory fences cannot have `Relaxed` ordering")] +#[help("consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`")] pub(crate) struct AtomicOrderingFence; #[derive(LintDiagnostic)] -#[diag(lint_atomic_ordering_invalid)] -#[help] +#[diag( + "`{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write" +)] +#[help("consider using `Acquire` or `Relaxed` failure ordering instead")] pub(crate) struct InvalidAtomicOrderingDiag { pub method: Symbol, - #[label] + #[label("invalid failure ordering")] pub fail_order_arg_span: Span, } // unused.rs #[derive(LintDiagnostic)] -#[diag(lint_unused_op)] +#[diag("unused {$op} that must be used")] pub(crate) struct UnusedOp<'a> { pub op: &'a str, - #[label] + #[label("the {$op} produces a value")] pub label: Span, #[subdiagnostic] pub suggestion: UnusedOpSuggestion, @@ -2057,7 +2398,7 @@ pub(crate) struct UnusedOp<'a> { #[derive(Subdiagnostic)] pub(crate) enum UnusedOpSuggestion { #[suggestion( - lint_suggestion, + "use `let _ = ...` to ignore the resulting value", style = "verbose", code = "let _ = ", applicability = "maybe-incorrect" @@ -2066,7 +2407,11 @@ pub(crate) enum UnusedOpSuggestion { #[primary_span] span: Span, }, - #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")] + #[multipart_suggestion( + "use `let _ = ...` to ignore the resulting value", + style = "verbose", + applicability = "maybe-incorrect" + )] BlockTailExpr { #[suggestion_part(code = "let _ = ")] before_span: Span, @@ -2076,7 +2421,7 @@ pub(crate) enum UnusedOpSuggestion { } #[derive(LintDiagnostic)] -#[diag(lint_unused_result)] +#[diag("unused result of type `{$ty}`")] pub(crate) struct UnusedResult<'a> { pub ty: Ty<'a>, } @@ -2084,8 +2429,13 @@ pub(crate) struct UnusedResult<'a> { // FIXME(davidtwco): this isn't properly translatable because of the // pre/post strings #[derive(LintDiagnostic)] -#[diag(lint_unused_closure)] -#[note] +#[diag( + "unused {$pre}{$count -> + [one] closure + *[other] closures + }{$post} that must be used" +)] +#[note("closures are lazy and do nothing unless called")] pub(crate) struct UnusedClosure<'a> { pub count: usize, pub pre: &'a str, @@ -2095,8 +2445,13 @@ pub(crate) struct UnusedClosure<'a> { // FIXME(davidtwco): this isn't properly translatable because of the // pre/post strings #[derive(LintDiagnostic)] -#[diag(lint_unused_coroutine)] -#[note] +#[diag( + "unused {$pre}{$count -> + [one] coroutine + *[other] coroutine + }{$post} that must be used" +)] +#[note("coroutines are lazy and do nothing unless resumed")] pub(crate) struct UnusedCoroutine<'a> { pub count: usize, pub pre: &'a str, @@ -2115,10 +2470,9 @@ pub(crate) struct UnusedDef<'a, 'b> { } #[derive(Subdiagnostic)] - pub(crate) enum UnusedDefSuggestion { #[suggestion( - lint_suggestion, + "use `let _ = ...` to ignore the resulting value", style = "verbose", code = "let _ = ", applicability = "maybe-incorrect" @@ -2127,7 +2481,11 @@ pub(crate) enum UnusedDefSuggestion { #[primary_span] span: Span, }, - #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")] + #[multipart_suggestion( + "use `let _ = ...` to ignore the resulting value", + style = "verbose", + applicability = "maybe-incorrect" + )] BlockTailExpr { #[suggestion_part(code = "let _ = ")] before_span: Span, @@ -2139,7 +2497,7 @@ pub(crate) enum UnusedDefSuggestion { // Needed because of def_path_str impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - diag.primary_message(fluent::lint_unused_def); + diag.primary_message(inline_fluent!("unused {$pre}`{$def}`{$post} that must be used")); diag.arg("pre", self.pre); diag.arg("post", self.post); diag.arg("def", self.cx.tcx.def_path_str(self.def_id)); @@ -2154,7 +2512,7 @@ impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { } #[derive(LintDiagnostic)] -#[diag(lint_path_statement_drop)] +#[diag("path statement drops value")] pub(crate) struct PathStatementDrop { #[subdiagnostic] pub sub: PathStatementDropSub, @@ -2162,13 +2520,17 @@ pub(crate) struct PathStatementDrop { #[derive(Subdiagnostic)] pub(crate) enum PathStatementDropSub { - #[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")] + #[suggestion( + "use `drop` to clarify the intent", + code = "drop({snippet});", + applicability = "machine-applicable" + )] Suggestion { #[primary_span] span: Span, snippet: String, }, - #[help(lint_help)] + #[help("use `drop` to clarify the intent")] Help { #[primary_span] span: Span, @@ -2176,11 +2538,11 @@ pub(crate) enum PathStatementDropSub { } #[derive(LintDiagnostic)] -#[diag(lint_path_statement_no_effect)] +#[diag("path statement with no effect")] pub(crate) struct PathStatementNoEffect; #[derive(LintDiagnostic)] -#[diag(lint_unused_delim)] +#[diag("unnecessary {$delim} around {$item}")] pub(crate) struct UnusedDelim<'a> { pub delim: &'static str, pub item: &'a str, @@ -2189,7 +2551,7 @@ pub(crate) struct UnusedDelim<'a> { } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion("remove these {$delim}", applicability = "machine-applicable")] pub(crate) struct UnusedDelimSuggestion { #[suggestion_part(code = "{start_replace}")] pub start_span: Span, @@ -2200,17 +2562,17 @@ pub(crate) struct UnusedDelimSuggestion { } #[derive(LintDiagnostic)] -#[diag(lint_unused_import_braces)] +#[diag("braces around {$node} is unnecessary")] pub(crate) struct UnusedImportBracesDiag { pub node: Symbol, } #[derive(LintDiagnostic)] -#[diag(lint_unused_allocation)] +#[diag("unnecessary allocation, use `&` instead")] pub(crate) struct UnusedAllocationDiag; #[derive(LintDiagnostic)] -#[diag(lint_unused_allocation_mut)] +#[diag("unnecessary allocation, use `&mut` instead")] pub(crate) struct UnusedAllocationMutDiag; pub(crate) struct AsyncFnInTraitDiag { @@ -2219,59 +2581,67 @@ pub(crate) struct AsyncFnInTraitDiag { impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - diag.primary_message(fluent::lint_async_fn_in_trait); - diag.note(fluent::lint_note); + diag.primary_message(inline_fluent!("use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified")); + diag.note(inline_fluent!("you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future`")); if let Some(sugg) = self.sugg { - diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect); + diag.multipart_suggestion(inline_fluent!("you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change"), sugg, Applicability::MaybeIncorrect); } } } #[derive(LintDiagnostic)] -#[diag(lint_unit_bindings)] +#[diag("binding has unit type `()`")] pub(crate) struct UnitBindingsDiag { - #[label] + #[label("this pattern is inferred to be the unit type `()`")] pub label: Span, } #[derive(LintDiagnostic)] pub(crate) enum InvalidAsmLabel { - #[diag(lint_invalid_asm_label_named)] - #[help] - #[note] + #[diag("avoid using named labels in inline assembly")] + #[help("only local labels of the form `:` should be used in inline asm")] + #[note( + "see the asm section of Rust By Example for more information" + )] Named { - #[note(lint_invalid_asm_label_no_span)] + #[note("the label may be declared in the expansion of a macro")] missing_precise_span: bool, }, - #[diag(lint_invalid_asm_label_format_arg)] - #[help] - #[note(lint_note1)] - #[note(lint_note2)] + #[diag("avoid using named labels in inline assembly")] + #[help("only local labels of the form `:` should be used in inline asm")] + #[note("format arguments may expand to a non-numeric value")] + #[note( + "see the asm section of Rust By Example for more information" + )] FormatArg { - #[note(lint_invalid_asm_label_no_span)] + #[note("the label may be declared in the expansion of a macro")] missing_precise_span: bool, }, - #[diag(lint_invalid_asm_label_binary)] - #[help] - #[note(lint_note1)] - #[note(lint_note2)] + #[diag("avoid using labels containing only the digits `0` and `1` in inline assembly")] + #[help("start numbering with `2` instead")] + #[note("an LLVM bug makes these labels ambiguous with a binary literal number on x86")] + #[note("see for more information")] Binary { - #[note(lint_invalid_asm_label_no_span)] + #[note("the label may be declared in the expansion of a macro")] missing_precise_span: bool, // hack to get a label on the whole span, must match the emitted span - #[label] + #[label("use a different label that doesn't start with `0` or `1`")] span: Span, }, } #[derive(Subdiagnostic)] pub(crate) enum UnexpectedCfgCargoHelp { - #[help(lint_unexpected_cfg_add_cargo_feature)] - #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)] + #[help("consider using a Cargo feature instead")] + #[help( + "or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:{$cargo_toml_lint_cfg}" + )] LintCfg { cargo_toml_lint_cfg: String }, - #[help(lint_unexpected_cfg_add_cargo_feature)] - #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)] - #[help(lint_unexpected_cfg_add_build_rs_println)] + #[help("consider using a Cargo feature instead")] + #[help( + "or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:{$cargo_toml_lint_cfg}" + )] + #[help("or consider adding `{$build_rs_println}` to the top of the `build.rs`")] LintCfgAndBuildRs { cargo_toml_lint_cfg: String, build_rs_println: String }, } @@ -2297,7 +2667,7 @@ impl UnexpectedCfgCargoHelp { } #[derive(Subdiagnostic)] -#[help(lint_unexpected_cfg_add_cmdline_arg)] +#[help("to expect this configuration use `{$cmdline_arg}`")] pub(crate) struct UnexpectedCfgRustcHelp { pub cmdline_arg: String, } @@ -2309,17 +2679,23 @@ impl UnexpectedCfgRustcHelp { } #[derive(Subdiagnostic)] -#[note(lint_unexpected_cfg_from_external_macro_origin)] -#[help(lint_unexpected_cfg_from_external_macro_refer)] +#[note( + "using a cfg inside a {$macro_kind} will use the cfgs from the destination crate and not the ones from the defining crate" +)] +#[help("try referring to `{$macro_name}` crate for guidance on how handle this unexpected cfg")] pub(crate) struct UnexpectedCfgRustcMacroHelp { pub macro_kind: &'static str, pub macro_name: Symbol, } #[derive(Subdiagnostic)] -#[note(lint_unexpected_cfg_from_external_macro_origin)] -#[help(lint_unexpected_cfg_from_external_macro_refer)] -#[help(lint_unexpected_cfg_cargo_update)] +#[note( + "using a cfg inside a {$macro_kind} will use the cfgs from the destination crate and not the ones from the defining crate" +)] +#[help("try referring to `{$macro_name}` crate for guidance on how handle this unexpected cfg")] +#[help( + "the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}`" +)] pub(crate) struct UnexpectedCfgCargoMacroHelp { pub macro_kind: &'static str, pub macro_name: Symbol, @@ -2327,7 +2703,7 @@ pub(crate) struct UnexpectedCfgCargoMacroHelp { } #[derive(LintDiagnostic)] -#[diag(lint_unexpected_cfg_name)] +#[diag("unexpected `cfg` condition name: `{$name}`")] pub(crate) struct UnexpectedCfgName { #[subdiagnostic] pub code_sugg: unexpected_cfg_name::CodeSuggestion, @@ -2344,10 +2720,10 @@ pub(crate) mod unexpected_cfg_name { #[derive(Subdiagnostic)] pub(crate) enum CodeSuggestion { - #[help(lint_unexpected_cfg_define_features)] + #[help("consider defining some features in `Cargo.toml`")] DefineFeatures, #[multipart_suggestion( - lint_unexpected_cfg_name_version_syntax, + "there is a similar config predicate: `version(\"..\")`", applicability = "machine-applicable" )] VersionSyntax { @@ -2357,7 +2733,7 @@ pub(crate) mod unexpected_cfg_name { after_value: Span, }, #[suggestion( - lint_unexpected_cfg_name_similar_name_value, + "there is a config with a similar name and value", applicability = "maybe-incorrect", code = "{code}" )] @@ -2367,7 +2743,7 @@ pub(crate) mod unexpected_cfg_name { code: String, }, #[suggestion( - lint_unexpected_cfg_name_similar_name_no_value, + "there is a config with a similar name and no value", applicability = "maybe-incorrect", code = "{code}" )] @@ -2377,7 +2753,7 @@ pub(crate) mod unexpected_cfg_name { code: String, }, #[suggestion( - lint_unexpected_cfg_name_similar_name_different_values, + "there is a config with a similar name and different values", applicability = "maybe-incorrect", code = "{code}" )] @@ -2389,7 +2765,7 @@ pub(crate) mod unexpected_cfg_name { expected: Option, }, #[suggestion( - lint_unexpected_cfg_name_similar_name, + "there is a config with a similar name", applicability = "maybe-incorrect", code = "{code}" )] @@ -2407,7 +2783,7 @@ pub(crate) mod unexpected_cfg_name { expected_names: Option, }, #[suggestion( - lint_unexpected_cfg_boolean, + "you may have meant to use `{$literal}` (notice the capitalization). Doing so makes this predicate evaluate to `{$literal}` unconditionally", applicability = "machine-applicable", style = "verbose", code = "{literal}" @@ -2420,7 +2796,7 @@ pub(crate) mod unexpected_cfg_name { } #[derive(Subdiagnostic)] - #[help(lint_unexpected_cfg_name_expected_values)] + #[help("expected values for `{$best_match}` are: {$possibilities}")] pub(crate) struct ExpectedValues { pub best_match: Symbol, pub possibilities: DiagSymbolList, @@ -2428,7 +2804,7 @@ pub(crate) mod unexpected_cfg_name { #[derive(Subdiagnostic)] #[suggestion( - lint_unexpected_cfg_name_with_similar_value, + "found config with similar value", applicability = "maybe-incorrect", code = "{code}" )] @@ -2439,7 +2815,12 @@ pub(crate) mod unexpected_cfg_name { } #[derive(Subdiagnostic)] - #[help_once(lint_unexpected_cfg_name_expected_names)] + #[help_once( + "expected names are: {$possibilities}{$and_more -> + [0] {\"\"} + *[other] {\" \"}and {$and_more} more + }" + )] pub(crate) struct ExpectedNames { pub possibilities: DiagSymbolList, pub and_more: usize, @@ -2447,14 +2828,18 @@ pub(crate) mod unexpected_cfg_name { #[derive(Subdiagnostic)] pub(crate) enum InvocationHelp { - #[note(lint_unexpected_cfg_doc_cargo)] + #[note( + "see for more information about checking conditional configuration" + )] Cargo { #[subdiagnostic] macro_help: Option, #[subdiagnostic] help: Option, }, - #[note(lint_unexpected_cfg_doc_rustc)] + #[note( + "see for more information about checking conditional configuration" + )] Rustc { #[subdiagnostic] macro_help: Option, @@ -2465,7 +2850,12 @@ pub(crate) mod unexpected_cfg_name { } #[derive(LintDiagnostic)] -#[diag(lint_unexpected_cfg_value)] +#[diag( + "unexpected `cfg` condition value: {$has_value -> + [true] `{$value}` + *[false] (none) + }" +)] pub(crate) struct UnexpectedCfgValue { #[subdiagnostic] pub code_sugg: unexpected_cfg_value::CodeSuggestion, @@ -2489,14 +2879,14 @@ pub(crate) mod unexpected_cfg_value { #[subdiagnostic] suggestion: Option, }, - #[note(lint_unexpected_cfg_value_no_expected_value)] + #[note("no expected value for `{$name}`")] RemoveValue { #[subdiagnostic] suggestion: Option, name: Symbol, }, - #[note(lint_unexpected_cfg_value_no_expected_values)] + #[note("no expected values for `{$name}`")] RemoveCondition { #[subdiagnostic] suggestion: RemoveConditionSuggestion, @@ -2508,7 +2898,7 @@ pub(crate) mod unexpected_cfg_value { #[derive(Subdiagnostic)] pub(crate) enum ChangeValueSuggestion { #[suggestion( - lint_unexpected_cfg_value_similar_name, + "there is a expected value with a similar name", code = r#""{best_match}""#, applicability = "maybe-incorrect" )] @@ -2518,7 +2908,7 @@ pub(crate) mod unexpected_cfg_value { best_match: Symbol, }, #[suggestion( - lint_unexpected_cfg_value_specify_value, + "specify a config value", code = r#" = "{first_possibility}""#, applicability = "maybe-incorrect" )] @@ -2530,29 +2920,29 @@ pub(crate) mod unexpected_cfg_value { } #[derive(Subdiagnostic)] - #[suggestion( - lint_unexpected_cfg_value_remove_value, - code = "", - applicability = "maybe-incorrect" - )] + #[suggestion("remove the value", code = "", applicability = "maybe-incorrect")] pub(crate) struct RemoveValueSuggestion { #[primary_span] pub span: Span, } #[derive(Subdiagnostic)] - #[suggestion( - lint_unexpected_cfg_value_remove_condition, - code = "", - applicability = "maybe-incorrect" - )] + #[suggestion("remove the condition", code = "", applicability = "maybe-incorrect")] pub(crate) struct RemoveConditionSuggestion { #[primary_span] pub span: Span, } #[derive(Subdiagnostic)] - #[note(lint_unexpected_cfg_value_expected_values)] + #[note( + "expected values for `{$name}` are: {$have_none_possibility -> + [true] {\"(none), \"} + *[false] {\"\"} + }{$possibilities}{$and_more -> + [0] {\"\"} + *[other] {\" \"}and {$and_more} more + }" + )] pub(crate) struct ExpectedValues { pub name: Symbol, pub have_none_possibility: bool, @@ -2562,14 +2952,18 @@ pub(crate) mod unexpected_cfg_value { #[derive(Subdiagnostic)] pub(crate) enum InvocationHelp { - #[note(lint_unexpected_cfg_doc_cargo)] + #[note( + "see for more information about checking conditional configuration" + )] Cargo { #[subdiagnostic] help: Option, #[subdiagnostic] macro_help: Option, }, - #[note(lint_unexpected_cfg_doc_rustc)] + #[note( + "see for more information about checking conditional configuration" + )] Rustc { #[subdiagnostic] help: Option, @@ -2580,19 +2974,19 @@ pub(crate) mod unexpected_cfg_value { #[derive(Subdiagnostic)] pub(crate) enum CargoHelp { - #[help(lint_unexpected_cfg_value_add_feature)] + #[help("consider adding `{$value}` as a feature in `Cargo.toml`")] AddFeature { value: Symbol, }, - #[help(lint_unexpected_cfg_define_features)] + #[help("consider defining some features in `Cargo.toml`")] DefineFeatures, Other(#[subdiagnostic] super::UnexpectedCfgCargoHelp), } } #[derive(LintDiagnostic)] -#[diag(lint_unused_crate_dependency)] -#[help] +#[diag("extern crate `{$extern_crate}` is unused in crate `{$local_crate}`")] +#[help("remove the dependency or add `use {$extern_crate} as _;` to the crate root")] pub(crate) struct UnusedCrateDependency { pub extern_crate: Symbol, pub local_crate: Symbol, @@ -2600,20 +2994,32 @@ pub(crate) struct UnusedCrateDependency { // FIXME(jdonszelmann): duplicated in rustc_attr_parsing, should be moved there completely. #[derive(LintDiagnostic)] -#[diag(lint_ill_formed_attribute_input)] +#[diag( + "{$num_suggestions -> + [1] attribute must be of the form {$suggestions} + *[other] valid forms for the attribute are {$suggestions} + }" +)] pub(crate) struct IllFormedAttributeInput { pub num_suggestions: usize, pub suggestions: DiagArgValue, - #[note] + #[note("for more information, visit <{$docs}>")] pub has_docs: bool, pub docs: &'static str, } #[derive(LintDiagnostic)] -#[diag(lint_unicode_text_flow)] -#[note] +#[diag("unicode codepoint changing visible direction of text present in comment")] +#[note( + "these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen" +)] pub(crate) struct UnicodeTextFlow { - #[label] + #[label( + "{$num_codepoints -> + [1] this comment contains an invisible unicode text flow control codepoint + *[other] this comment contains invisible unicode text flow control codepoints + }" + )] pub comment_span: Span, #[subdiagnostic] pub characters: Vec, @@ -2624,7 +3030,7 @@ pub(crate) struct UnicodeTextFlow { } #[derive(Subdiagnostic)] -#[label(lint_label_comment_char)] +#[label("{$c_debug}")] pub(crate) struct UnicodeCharNoteSub { #[primary_span] pub span: Span, @@ -2632,21 +3038,27 @@ pub(crate) struct UnicodeCharNoteSub { } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable", style = "hidden")] +#[multipart_suggestion( + "if their presence wasn't intentional, you can remove them", + applicability = "machine-applicable", + style = "hidden" +)] pub(crate) struct UnicodeTextFlowSuggestion { #[suggestion_part(code = "")] pub spans: Vec, } #[derive(LintDiagnostic)] -#[diag(lint_abs_path_with_module)] +#[diag( + "absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition" +)] pub(crate) struct AbsPathWithModule { #[subdiagnostic] pub sugg: AbsPathWithModuleSugg, } #[derive(Subdiagnostic)] -#[suggestion(lint_suggestion, code = "{replacement}")] +#[suggestion("use `crate`", code = "{replacement}")] pub(crate) struct AbsPathWithModuleSugg { #[primary_span] pub span: Span, @@ -2656,18 +3068,23 @@ pub(crate) struct AbsPathWithModuleSugg { } #[derive(LintDiagnostic)] -#[diag(lint_hidden_lifetime_parameters)] +#[diag("hidden lifetime parameters in types are deprecated")] pub(crate) struct ElidedLifetimesInPaths { #[subdiagnostic] pub subdiag: ElidedLifetimeInPathSubdiag, } #[derive(LintDiagnostic)] -#[diag(lint_unused_imports)] +#[diag( + "{$num_snippets -> + [one] unused import: {$span_snippets} + *[other] unused imports: {$span_snippets} + }" +)] pub(crate) struct UnusedImports { #[subdiagnostic] pub sugg: UnusedImportsSugg, - #[help] + #[help("if this is a test module, consider adding a `#[cfg(test)]` to the containing module")] pub test_module_span: Option, pub span_snippets: DiagArgValue, @@ -2677,7 +3094,7 @@ pub(crate) struct UnusedImports { #[derive(Subdiagnostic)] pub(crate) enum UnusedImportsSugg { #[suggestion( - lint_suggestion_remove_whole_use, + "remove the whole `use` item", applicability = "machine-applicable", code = "", style = "tool-only" @@ -2687,7 +3104,10 @@ pub(crate) enum UnusedImportsSugg { span: Span, }, #[multipart_suggestion( - lint_suggestion_remove_imports, + "{$num_to_remove -> + [one] remove the unused import + *[other] remove the unused imports + }", applicability = "machine-applicable", style = "tool-only" )] @@ -2699,7 +3119,7 @@ pub(crate) enum UnusedImportsSugg { } #[derive(LintDiagnostic)] -#[diag(lint_redundant_import)] +#[diag("the item `{$ident}` is imported redundantly")] pub(crate) struct RedundantImport { #[subdiagnostic] pub subs: Vec, @@ -2709,24 +3129,24 @@ pub(crate) struct RedundantImport { #[derive(Subdiagnostic)] pub(crate) enum RedundantImportSub { - #[label(lint_label_imported_here)] + #[label("the item `{$ident}` is already imported here")] ImportedHere(#[primary_span] Span), - #[label(lint_label_defined_here)] + #[label("the item `{$ident}` is already defined here")] DefinedHere(#[primary_span] Span), - #[label(lint_label_imported_prelude)] + #[label("the item `{$ident}` is already imported by the extern prelude")] ImportedPrelude(#[primary_span] Span), - #[label(lint_label_defined_prelude)] + #[label("the item `{$ident}` is already defined by the extern prelude")] DefinedPrelude(#[primary_span] Span), } #[derive(LintDiagnostic)] pub(crate) enum PatternsInFnsWithoutBody { - #[diag(lint_pattern_in_foreign)] + #[diag("patterns aren't allowed in foreign function declarations")] Foreign { #[subdiagnostic] sub: PatternsInFnsWithoutBodySub, }, - #[diag(lint_pattern_in_bodiless)] + #[diag("patterns aren't allowed in functions without bodies")] Bodiless { #[subdiagnostic] sub: PatternsInFnsWithoutBodySub, @@ -2734,7 +3154,11 @@ pub(crate) enum PatternsInFnsWithoutBody { } #[derive(Subdiagnostic)] -#[suggestion(lint_remove_mut_from_pattern, code = "{ident}", applicability = "machine-applicable")] +#[suggestion( + "remove `mut` from the parameter", + code = "{ident}", + applicability = "machine-applicable" +)] pub(crate) struct PatternsInFnsWithoutBodySub { #[primary_span] pub span: Span, @@ -2743,34 +3167,44 @@ pub(crate) struct PatternsInFnsWithoutBodySub { } #[derive(LintDiagnostic)] -#[diag(lint_reserved_prefix)] +#[diag("prefix `{$prefix}` is unknown")] pub(crate) struct ReservedPrefix { - #[label] + #[label("unknown prefix")] pub label: Span, - #[suggestion(code = " ", applicability = "machine-applicable")] + #[suggestion( + "insert whitespace here to avoid this being parsed as a prefix in Rust 2021", + code = " ", + applicability = "machine-applicable" + )] pub suggestion: Span, pub prefix: String, } #[derive(LintDiagnostic)] -#[diag(lint_raw_prefix)] +#[diag("prefix `'r` is reserved")] pub(crate) struct RawPrefix { - #[label] + #[label("reserved prefix")] pub label: Span, - #[suggestion(code = " ", applicability = "machine-applicable")] + #[suggestion( + "insert whitespace here to avoid this being parsed as a prefix in Rust 2021", + code = " ", + applicability = "machine-applicable" + )] pub suggestion: Span, } #[derive(LintDiagnostic)] -#[diag(lint_break_with_label_and_loop)] +#[diag( + "this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression" +)] pub(crate) struct BreakWithLabelAndLoop { #[subdiagnostic] pub sub: BreakWithLabelAndLoopSub, } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion("wrap this expression in parentheses", applicability = "machine-applicable")] pub(crate) struct BreakWithLabelAndLoopSub { #[suggestion_part(code = "(")] pub left: Span, @@ -2779,8 +3213,8 @@ pub(crate) struct BreakWithLabelAndLoopSub { } #[derive(LintDiagnostic)] -#[diag(lint_deprecated_where_clause_location)] -#[note] +#[diag("where clause not allowed here")] +#[note("see issue #89122 for more information")] pub(crate) struct DeprecatedWhereClauseLocation { #[subdiagnostic] pub suggestion: DeprecatedWhereClauseLocationSugg, @@ -2788,7 +3222,10 @@ pub(crate) struct DeprecatedWhereClauseLocation { #[derive(Subdiagnostic)] pub(crate) enum DeprecatedWhereClauseLocationSugg { - #[multipart_suggestion(lint_suggestion_move_to_end, applicability = "machine-applicable")] + #[multipart_suggestion( + "move it to the end of the type declaration", + applicability = "machine-applicable" + )] MoveToEnd { #[suggestion_part(code = "")] left: Span, @@ -2797,7 +3234,7 @@ pub(crate) enum DeprecatedWhereClauseLocationSugg { sugg: String, }, - #[suggestion(lint_suggestion_remove_where, code = "", applicability = "machine-applicable")] + #[suggestion("remove this `where`", code = "", applicability = "machine-applicable")] RemoveWhere { #[primary_span] span: Span, @@ -2805,11 +3242,11 @@ pub(crate) enum DeprecatedWhereClauseLocationSugg { } #[derive(LintDiagnostic)] -#[diag(lint_single_use_lifetime)] +#[diag("lifetime parameter `{$ident}` only used once")] pub(crate) struct SingleUseLifetime { - #[label(lint_label_param)] + #[label("this lifetime...")] pub param_span: Span, - #[label(lint_label_use)] + #[label("...is used only here")] pub use_span: Span, #[subdiagnostic] pub suggestion: Option, @@ -2818,7 +3255,7 @@ pub(crate) struct SingleUseLifetime { } #[derive(Subdiagnostic)] -#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion("elide the single-use lifetime", applicability = "machine-applicable")] pub(crate) struct SingleUseLifetimeSugg { #[suggestion_part(code = "")] pub deletion_span: Option, @@ -2829,22 +3266,27 @@ pub(crate) struct SingleUseLifetimeSugg { } #[derive(LintDiagnostic)] -#[diag(lint_unused_lifetime)] +#[diag("lifetime parameter `{$ident}` never used")] pub(crate) struct UnusedLifetime { - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("elide the unused lifetime", code = "", applicability = "machine-applicable")] pub deletion_span: Option, pub ident: Ident, } #[derive(LintDiagnostic)] -#[diag(lint_named_argument_used_positionally)] +#[diag("named argument `{$named_arg_name}` is not used by name")] pub(crate) struct NamedArgumentUsedPositionally { - #[label(lint_label_named_arg)] + #[label("this named argument is referred to by position in formatting string")] pub named_arg_sp: Span, - #[label(lint_label_position_arg)] + #[label("this formatting argument uses named argument `{$named_arg_name}` by position")] pub position_label_sp: Option, - #[suggestion(style = "verbose", code = "{name}", applicability = "maybe-incorrect")] + #[suggestion( + "use the named argument by name to avoid ambiguity", + style = "verbose", + code = "{name}", + applicability = "maybe-incorrect" + )] pub suggestion: Option, pub name: String, @@ -2852,11 +3294,11 @@ pub(crate) struct NamedArgumentUsedPositionally { } #[derive(LintDiagnostic)] -#[diag(lint_ambiguous_glob_reexport)] +#[diag("ambiguous glob re-exports")] pub(crate) struct AmbiguousGlobReexports { - #[label(lint_label_first_reexport)] + #[label("the name `{$name}` in the {$namespace} namespace is first re-exported here")] pub first_reexport: Span, - #[label(lint_label_duplicate_reexport)] + #[label("but the name `{$name}` in the {$namespace} namespace is also re-exported here")] pub duplicate_reexport: Span, pub name: String, @@ -2864,11 +3306,13 @@ pub(crate) struct AmbiguousGlobReexports { } #[derive(LintDiagnostic)] -#[diag(lint_hidden_glob_reexport)] +#[diag("private item shadows public glob re-export")] pub(crate) struct HiddenGlobReexports { - #[note(lint_note_glob_reexport)] + #[note( + "the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here" + )] pub glob_reexport: Span, - #[note(lint_note_private_item)] + #[note("but the private item here shadows it")] pub private_item: Span, pub name: String, @@ -2876,47 +3320,70 @@ pub(crate) struct HiddenGlobReexports { } #[derive(LintDiagnostic)] -#[diag(lint_unnecessary_qualification)] +#[diag("unnecessary qualification")] pub(crate) struct UnusedQualifications { - #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")] + #[suggestion( + "remove the unnecessary path segments", + style = "verbose", + code = "", + applicability = "machine-applicable" + )] pub removal_span: Span, } #[derive(LintDiagnostic)] -#[diag(lint_associated_const_elided_lifetime)] +#[diag( + "{$elided -> + [true] `&` without an explicit lifetime name cannot be used here + *[false] `'_` cannot be used here + }" +)] pub(crate) struct AssociatedConstElidedLifetime { - #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")] + #[suggestion( + "use the `'static` lifetime", + style = "verbose", + code = "{code}", + applicability = "machine-applicable" + )] pub span: Span, pub code: &'static str, pub elided: bool, - #[note] + #[note("cannot automatically infer `'static` because of other lifetimes in scope")] pub lifetimes_in_scope: MultiSpan, } #[derive(LintDiagnostic)] -#[diag(lint_static_mut_refs_lint)] +#[diag("creating a {$shared_label}reference to mutable static")] pub(crate) struct RefOfMutStatic<'a> { - #[label] + #[label("{$shared_label}reference to mutable static")] pub span: Span, #[subdiagnostic] pub sugg: Option, pub shared_label: &'a str, - #[note(lint_shared_note)] + #[note( + "shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives" + )] pub shared_note: bool, - #[note(lint_mut_note)] + #[note( + "mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives" + )] pub mut_note: bool, } #[derive(Subdiagnostic)] pub(crate) enum MutRefSugg { - #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")] + #[multipart_suggestion( + "use `&raw const` instead to create a raw pointer", + style = "verbose", + applicability = "maybe-incorrect" + )] Shared { #[suggestion_part(code = "&raw const ")] span: Span, }, #[multipart_suggestion( - lint_suggestion_mut, + "use `&raw mut` instead to create a raw pointer", style = "verbose", applicability = "maybe-incorrect" )] @@ -2927,25 +3394,33 @@ pub(crate) enum MutRefSugg { } #[derive(LintDiagnostic)] -#[diag(lint_unqualified_local_imports)] +#[diag("`use` of a local item without leading `self::`, `super::`, or `crate::`")] pub(crate) struct UnqualifiedLocalImportsDiag {} #[derive(LintDiagnostic)] -#[diag(lint_reserved_string)] +#[diag("will be parsed as a guarded string in Rust 2024")] pub(crate) struct ReservedString { - #[suggestion(code = " ", applicability = "machine-applicable")] + #[suggestion( + "insert whitespace here to avoid this being parsed as a guarded string in Rust 2024", + code = " ", + applicability = "machine-applicable" + )] pub suggestion: Span, } #[derive(LintDiagnostic)] -#[diag(lint_reserved_multihash)] +#[diag("reserved token in Rust 2024")] pub(crate) struct ReservedMultihash { - #[suggestion(code = " ", applicability = "machine-applicable")] + #[suggestion( + "insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024", + code = " ", + applicability = "machine-applicable" + )] pub suggestion: Span, } #[derive(LintDiagnostic)] -#[diag(lint_function_casts_as_integer)] +#[diag("direct cast of function item into an integer")] pub(crate) struct FunctionCastsAsIntegerDiag<'tcx> { #[subdiagnostic] pub(crate) sugg: FunctionCastsAsIntegerSugg<'tcx>, @@ -2953,7 +3428,7 @@ pub(crate) struct FunctionCastsAsIntegerDiag<'tcx> { #[derive(Subdiagnostic)] #[suggestion( - lint_cast_as_fn, + "first cast to a pointer `as *const ()`", code = " as *const ()", applicability = "machine-applicable", style = "verbose" @@ -2981,44 +3456,46 @@ impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for MismatchedLifetimeSynta } LifetimeSyntaxCategories { hidden: _, elided: _, named: 0 } => { - fluent::lint_mismatched_lifetime_syntaxes_hiding_while_elided + inline_fluent!("hiding a lifetime that's elided elsewhere is confusing") } LifetimeSyntaxCategories { hidden: _, elided: 0, named: _ } => { - fluent::lint_mismatched_lifetime_syntaxes_hiding_while_named + inline_fluent!("hiding a lifetime that's named elsewhere is confusing") } LifetimeSyntaxCategories { hidden: 0, elided: _, named: _ } => { - fluent::lint_mismatched_lifetime_syntaxes_eliding_while_named + inline_fluent!("eliding a lifetime that's named elsewhere is confusing") } LifetimeSyntaxCategories { hidden: _, elided: _, named: _ } => { - fluent::lint_mismatched_lifetime_syntaxes_hiding_and_eliding_while_named + inline_fluent!("hiding or eliding a lifetime that's named elsewhere is confusing") } }; diag.primary_message(message); for s in self.inputs.hidden { - diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_input_hidden); + diag.span_label(s, inline_fluent!("the lifetime is hidden here")); } for s in self.inputs.elided { - diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_input_elided); + diag.span_label(s, inline_fluent!("the lifetime is elided here")); } for s in self.inputs.named { - diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_input_named); + diag.span_label(s, inline_fluent!("the lifetime is named here")); } for s in self.outputs.hidden { - diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_output_hidden); + diag.span_label(s, inline_fluent!("the same lifetime is hidden here")); } for s in self.outputs.elided { - diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_output_elided); + diag.span_label(s, inline_fluent!("the same lifetime is elided here")); } for s in self.outputs.named { - diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_output_named); + diag.span_label(s, inline_fluent!("the same lifetime is named here")); } - diag.help(fluent::lint_mismatched_lifetime_syntaxes_help); + diag.help(inline_fluent!( + "the same lifetime is referred to in inconsistent ways, making the signature confusing" + )); let mut suggestions = self.suggestions.into_iter(); if let Some(s) = suggestions.next() { @@ -3092,7 +3569,7 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { Implicit { suggestions, optional_alternative } => { let suggestions = suggestions.into_iter().map(|s| (s, String::new())).collect(); diag.multipart_suggestion_with_style( - fluent::lint_mismatched_lifetime_syntaxes_suggestion_implicit, + inline_fluent!("remove the lifetime name from references"), suggestions, applicability(optional_alternative), style(optional_alternative), @@ -3105,9 +3582,11 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { optional_alternative, } => { let message = if implicit_suggestions.is_empty() { - fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed_only_paths + inline_fluent!("use `'_` for type paths") } else { - fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed + inline_fluent!( + "remove the lifetime name from references and use `'_` for type paths" + ) }; let implicit_suggestions = @@ -3126,9 +3605,8 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { Explicit { lifetime_name, suggestions, optional_alternative } => { diag.arg("lifetime_name", lifetime_name); - let msg = diag.eagerly_translate( - fluent::lint_mismatched_lifetime_syntaxes_suggestion_explicit, - ); + let msg = + diag.eagerly_translate(inline_fluent!("consistently use `{$lifetime_name}`")); diag.remove_arg("lifetime_name"); diag.multipart_suggestion_with_style( msg, @@ -3142,78 +3620,107 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { } #[derive(LintDiagnostic)] -#[diag(lint_empty_attribute)] -#[note] +#[diag("unused attribute")] +#[note( + "{$valid_without_list -> + [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all + *[other] using `{$attr_path}` with an empty list has no effect + }" +)] pub(crate) struct EmptyAttributeList { - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion( + "{$valid_without_list -> + [true] remove these parentheses + *[other] remove this attribute + }", + code = "", + applicability = "machine-applicable" + )] pub attr_span: Span, pub attr_path: String, pub valid_without_list: bool, } #[derive(LintDiagnostic)] -#[diag(lint_invalid_target)] -#[warning] -#[help] +#[diag("`#[{$name}]` attribute cannot be used on {$target}")] +#[warning( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" +)] +#[help("`#[{$name}]` can {$only}be applied to {$applied}")] pub(crate) struct InvalidTargetLint { pub name: String, pub target: &'static str, pub applied: DiagArgValue, pub only: &'static str, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove the attribute", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub attr_span: Span, } #[derive(LintDiagnostic)] -#[diag(lint_invalid_style)] +#[diag( + "{$is_used_as_inner -> + [false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]` + *[other] the `#![{$name}]` attribute can only be used at the crate root + }" +)] pub(crate) struct InvalidAttrStyle { pub name: String, pub is_used_as_inner: bool, - #[note] + #[note("this attribute does not have an `!`, which means it is applied to this {$target}")] pub target_span: Option, pub target: &'static str, } #[derive(LintDiagnostic)] -#[diag(lint_unused_duplicate)] +#[diag("unused attribute")] pub(crate) struct UnusedDuplicate { - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] pub this: Span, - #[note] + #[note("attribute also specified here")] pub other: Span, - #[warning] + #[warning( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" + )] pub warning: bool, } #[derive(LintDiagnostic)] -#[diag(lint_malformed_doc)] -#[warning] +#[diag("malformed `doc` attribute input")] +#[warning( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" +)] pub(crate) struct MalformedDoc; #[derive(LintDiagnostic)] -#[diag(lint_expected_no_args)] -#[warning] +#[diag("didn't expect any arguments here")] +#[warning( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" +)] pub(crate) struct ExpectedNoArgs; #[derive(LintDiagnostic)] -#[diag(lint_expected_name_value)] -#[warning] +#[diag("expected this to be of the form `... = \"...\"`")] +#[warning( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" +)] pub(crate) struct ExpectedNameValue; #[derive(LintDiagnostic)] -#[diag(lint_unsafe_attr_outside_unsafe)] +#[diag("unsafe attribute used without unsafe")] pub(crate) struct UnsafeAttrOutsideUnsafeLint { - #[label] + #[label("usage of unsafe attribute")] pub span: Span, #[subdiagnostic] pub suggestion: Option, } #[derive(Subdiagnostic)] -#[multipart_suggestion( - lint_unsafe_attr_outside_unsafe_suggestion, - applicability = "machine-applicable" -)] +#[multipart_suggestion("wrap the attribute in `unsafe(...)`", applicability = "machine-applicable")] pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { #[suggestion_part(code = "unsafe(")] pub left: Span, @@ -3222,119 +3729,138 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { } #[derive(LintDiagnostic)] -#[diag(lint_unused_visibilities)] -#[note] +#[diag("visibility qualifiers have no effect on `const _` declarations")] +#[note("`const _` does not declare a name, so there is nothing for the qualifier to apply to")] pub(crate) struct UnusedVisibility { - #[suggestion(style = "short", code = "", applicability = "machine-applicable")] + #[suggestion( + "remove the qualifier", + style = "short", + code = "", + applicability = "machine-applicable" + )] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(lint_doc_alias_duplicated)] +#[diag("doc alias is duplicated")] pub(crate) struct DocAliasDuplicated { - #[label] + #[label("first defined here")] pub first_defn: Span, } #[derive(LintDiagnostic)] -#[diag(lint_doc_auto_cfg_expects_hide_or_show)] +#[diag("only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]`")] pub(crate) struct DocAutoCfgExpectsHideOrShow; #[derive(LintDiagnostic)] -#[diag(lint_doc_auto_cfg_hide_show_unexpected_item)] +#[diag("`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items")] pub(crate) struct DocAutoCfgHideShowUnexpectedItem { pub attr_name: Symbol, } #[derive(LintDiagnostic)] -#[diag(lint_doc_auto_cfg_hide_show_expects_list)] +#[diag("`#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items")] pub(crate) struct DocAutoCfgHideShowExpectsList { pub attr_name: Symbol, } #[derive(LintDiagnostic)] -#[diag(lint_doc_invalid)] +#[diag("invalid `doc` attribute")] pub(crate) struct DocInvalid; #[derive(LintDiagnostic)] -#[diag(lint_doc_unknown_include)] +#[diag("unknown `doc` attribute `include`")] pub(crate) struct DocUnknownInclude { pub inner: &'static str, pub value: Symbol, - #[suggestion(code = "#{inner}[doc = include_str!(\"{value}\")]")] + #[suggestion( + "use `doc = include_str!` instead", + code = "#{inner}[doc = include_str!(\"{value}\")]" + )] pub sugg: (Span, Applicability), } #[derive(LintDiagnostic)] -#[diag(lint_doc_unknown_spotlight)] -#[note] -#[note(lint_no_op_note)] +#[diag("unknown `doc` attribute `spotlight`")] +#[note("`doc(spotlight)` was renamed to `doc(notable_trait)`")] +#[note("`doc(spotlight)` is now a no-op")] pub(crate) struct DocUnknownSpotlight { - #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")] + #[suggestion( + "use `notable_trait` instead", + style = "short", + applicability = "machine-applicable", + code = "notable_trait" + )] pub sugg_span: Span, } #[derive(LintDiagnostic)] -#[diag(lint_doc_unknown_passes)] -#[note] -#[note(lint_no_op_note)] +#[diag("unknown `doc` attribute `{$name}`")] +#[note( + "`doc` attribute `{$name}` no longer functions; see issue #44136 " +)] +#[note("`doc({$name})` is now a no-op")] pub(crate) struct DocUnknownPasses { pub name: Symbol, - #[label] + #[label("no longer functions")] pub note_span: Span, } #[derive(LintDiagnostic)] -#[diag(lint_doc_unknown_plugins)] -#[note] -#[note(lint_no_op_note)] +#[diag("unknown `doc` attribute `plugins`")] +#[note( + "`doc` attribute `plugins` no longer functions; see issue #44136 and CVE-2018-1000622 " +)] +#[note("`doc(plugins)` is now a no-op")] pub(crate) struct DocUnknownPlugins { - #[label] + #[label("no longer functions")] pub label_span: Span, } #[derive(LintDiagnostic)] -#[diag(lint_doc_unknown_any)] +#[diag("unknown `doc` attribute `{$name}`")] pub(crate) struct DocUnknownAny { pub name: Symbol, } #[derive(LintDiagnostic)] -#[diag(lint_doc_auto_cfg_wrong_literal)] +#[diag("expected boolean for `#[doc(auto_cfg = ...)]`")] pub(crate) struct DocAutoCfgWrongLiteral; #[derive(LintDiagnostic)] -#[diag(lint_doc_test_takes_list)] +#[diag("`#[doc(test(...)]` takes a list of attributes")] pub(crate) struct DocTestTakesList; #[derive(LintDiagnostic)] -#[diag(lint_doc_test_unknown)] +#[diag("unknown `doc(test)` attribute `{$name}`")] pub(crate) struct DocTestUnknown { pub name: Symbol, } #[derive(LintDiagnostic)] -#[diag(lint_doc_test_literal)] +#[diag("`#![doc(test(...)]` does not take a literal")] pub(crate) struct DocTestLiteral; #[derive(LintDiagnostic)] -#[diag(lint_attr_crate_level)] -#[note] +#[diag("this attribute can only be applied at the crate level")] +#[note( + "read for more information" +)] pub(crate) struct AttrCrateLevelOnly; #[derive(LintDiagnostic)] -#[diag(lint_incorrect_do_not_recommend_args)] +#[diag("`#[diagnostic::do_not_recommend]` does not expect any arguments")] pub(crate) struct DoNotRecommendDoesNotExpectArgs; #[derive(LintDiagnostic)] -#[diag(lint_invalid_crate_type_value)] +#[diag("invalid `crate_type` value")] pub(crate) struct UnknownCrateTypes { #[subdiagnostic] pub sugg: Option, } #[derive(Subdiagnostic)] -#[suggestion(lint_suggestion, code = r#""{snippet}""#, applicability = "maybe-incorrect")] +#[suggestion("did you mean", code = r#""{snippet}""#, applicability = "maybe-incorrect")] pub(crate) struct UnknownCrateTypesSuggestion { #[primary_span] pub span: Span, @@ -3342,18 +3868,18 @@ pub(crate) struct UnknownCrateTypesSuggestion { } #[derive(LintDiagnostic)] -#[diag(lint_unreachable_cfg_select_predicate)] +#[diag("unreachable configuration predicate")] pub(crate) struct UnreachableCfgSelectPredicate { - #[label] + #[label("this configuration predicate is never reached")] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(lint_unreachable_cfg_select_predicate_wildcard)] +#[diag("unreachable configuration predicate")] pub(crate) struct UnreachableCfgSelectPredicateWildcard { - #[label(lint_label2)] + #[label("this configuration predicate is never reached")] pub span: Span, - #[label] + #[label("always matches")] pub wildcard_span: Span, } diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index a07c3b372d34..daf62277693a 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -1,5 +1,5 @@ use rustc_ast as ast; -use rustc_errors::Applicability; +use rustc_errors::{Applicability, inline_fluent}; use rustc_hir::{self as hir, LangItem}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::{bug, ty}; @@ -10,7 +10,7 @@ use rustc_span::{InnerSpan, Span, Symbol, hygiene, sym}; use rustc_trait_selection::infer::InferCtxtExt; use crate::lints::{NonFmtPanicBraces, NonFmtPanicUnused}; -use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent}; +use crate::{LateContext, LateLintPass, LintContext}; declare_lint! { /// The `non_fmt_panics` lint detects `panic!(..)` invocations where the first @@ -121,20 +121,20 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc } cx.span_lint(NON_FMT_PANICS, arg_span, |lint| { - lint.primary_message(fluent::lint_non_fmt_panic); + lint.primary_message(inline_fluent!("panic message is not a string literal")); lint.arg("name", symbol); - lint.note(fluent::lint_note); - lint.note(fluent::lint_more_info_note); + lint.note(inline_fluent!("this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021")); + lint.note(inline_fluent!("for more information, see ")); if !is_arg_inside_call(arg_span, span) { // No clue where this argument is coming from. return; } if arg_macro.is_some_and(|id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) { // A case of `panic!(format!(..))`. - lint.note(fluent::lint_supports_fmt_note); + lint.note(inline_fluent!("the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here")); if let Some((open, close, _)) = find_delimiters(cx, arg_span) { lint.multipart_suggestion( - fluent::lint_supports_fmt_suggestion, + inline_fluent!("remove the `format!(..)` macro call"), vec![ (arg_span.until(open.shrink_to_hi()), "".into()), (close.until(arg_span.shrink_to_hi()), "".into()), @@ -178,7 +178,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc if suggest_display { lint.span_suggestion_verbose( arg_span.shrink_to_lo(), - fluent::lint_display_suggestion, + inline_fluent!(r#"add a "{"{"}{"}"}" format string to `Display` the message"#), "\"{}\", ", fmt_applicability, ); @@ -186,7 +186,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc lint.arg("ty", ty); lint.span_suggestion_verbose( arg_span.shrink_to_lo(), - fluent::lint_debug_suggestion, + inline_fluent!(r#"add a "{"{"}:?{"}"}" format string to use the `Debug` implementation of `{$ty}`"#), "\"{:?}\", ", fmt_applicability, ); @@ -196,7 +196,10 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc if let Some((open, close, del)) = find_delimiters(cx, span) { lint.arg("already_suggested", suggest_display || suggest_debug); lint.multipart_suggestion( - fluent::lint_panic_suggestion, + inline_fluent!("{$already_suggested -> + [true] or use + *[false] use + } std::panic::panic_any instead"), if del == '(' { vec![(span.until(open), "std::panic::panic_any".into())] } else { diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index bcf4d9ec3b29..fc7e5a821b02 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -1,4 +1,4 @@ -use rustc_errors::MultiSpan; +use rustc_errors::{MultiSpan, inline_fluent}; use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{self, Visitor, VisitorExt}; @@ -9,7 +9,7 @@ use rustc_span::def_id::{DefId, LOCAL_CRATE}; use rustc_span::{ExpnKind, Span, kw}; use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag}; -use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent}; +use crate::{LateContext, LateLintPass, LintContext}; declare_lint! { /// The `non_local_definitions` lint checks for `impl` blocks and `#[macro_export]` @@ -210,7 +210,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { if !doctest { ms.push_span_label( cx.tcx.def_span(parent), - fluent::lint_non_local_definitions_impl_move_help, + inline_fluent!( + "move the `impl` block outside of this {$body_kind_descr} {$depth -> + [one] `{$body_name}` + *[other] `{$body_name}` and up {$depth} bodies + }" + ), ); } diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 3f2ca92a021a..b5b57eaa3389 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -202,11 +202,11 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { } #[derive(LintDiagnostic)] -#[diag(lint_opaque_hidden_inferred_bound)] +#[diag("opaque type `{$ty}` does not satisfy its associated type bounds")] struct OpaqueHiddenInferredBoundLint<'tcx> { ty: Ty<'tcx>, proj_ty: Ty<'tcx>, - #[label(lint_specifically)] + #[label("this associated type bound is unsatisfied for `{$proj_ty}`")] assoc_pred_span: Span, #[subdiagnostic] add_bound: Option>, @@ -214,7 +214,7 @@ struct OpaqueHiddenInferredBoundLint<'tcx> { #[derive(Subdiagnostic)] #[suggestion( - lint_opaque_hidden_inferred_bound_sugg, + "add this bound", style = "verbose", applicability = "machine-applicable", code = " + {trait_ref}" diff --git a/compiler/rustc_lint/src/transmute.rs b/compiler/rustc_lint/src/transmute.rs index 6bc4617eb2dc..e4716c869c5f 100644 --- a/compiler/rustc_lint/src/transmute.rs +++ b/compiler/rustc_lint/src/transmute.rs @@ -369,8 +369,10 @@ fn check_unnecessary_transmute<'tcx>( } #[derive(LintDiagnostic)] -#[diag(lint_undefined_transmute)] -#[note] -#[note(lint_note2)] -#[help] +#[diag("pointers cannot be transmuted to integers during const eval")] +#[note("at compile-time, pointers do not have an integer value")] +#[note( + "avoiding this restriction via `union` or raw pointers leads to compile-time undefined behavior" +)] +#[help("for more information, see https://doc.rust-lang.org/std/mem/fn.transmute.html")] pub(crate) struct UndefinedTransmuteLint; diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 38094c67c34a..fb9b55efa220 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -4,7 +4,7 @@ use std::ops::ControlFlow; use bitflags::bitflags; use rustc_abi::VariantIdx; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::DiagMessage; +use rustc_errors::{DiagMessage, inline_fluent}; use rustc_hir::def::CtorKind; use rustc_hir::intravisit::VisitorExt; use rustc_hir::{self as hir, AmbigArg}; @@ -21,7 +21,7 @@ use tracing::debug; use super::repr_nullable_ptr; use crate::lints::{ImproperCTypes, UsesPowerAlignment}; -use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent}; +use crate::{LateContext, LateLintPass, LintContext}; declare_lint! { /// The `improper_ctypes` lint detects incorrect use of types in foreign @@ -158,12 +158,12 @@ pub(crate) fn check_non_exhaustive_variant( // with an enum like `#[repr(u8)] enum Enum { A(DataA), B(DataB), }` // but exempt enums with unit ctors like C's (e.g. from rust-bindgen) if variant_has_complex_ctor(variant) { - return ControlFlow::Break(fluent::lint_improper_ctypes_non_exhaustive); + return ControlFlow::Break(inline_fluent!("this enum is non-exhaustive")); } } if variant.field_list_has_applicable_non_exhaustive() { - return ControlFlow::Break(fluent::lint_improper_ctypes_non_exhaustive_variant); + return ControlFlow::Break(inline_fluent!("this enum has non-exhaustive variants")); } ControlFlow::Continue(()) @@ -424,7 +424,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { if all_phantom { FfiPhantom(ty) } else if transparent_with_all_zst_fields { - FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_struct_zst, help: None } + FfiUnsafe { + ty, + reason: inline_fluent!("this struct contains only zero-sized fields"), + help: None, + } } else { FfiSafe } @@ -460,7 +464,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } else { return FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_box, + reason: inline_fluent!("box cannot be represented as a single pointer"), help: None, }; } @@ -476,8 +480,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { { return FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_cstr_reason, - help: Some(fluent::lint_improper_ctypes_cstr_help), + reason: inline_fluent!( + "`CStr`/`CString` do not have a guaranteed layout" + ), + help: Some(inline_fluent!( + "consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`" + )), }; } @@ -485,14 +493,18 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return FfiUnsafe { ty, reason: if def.is_struct() { - fluent::lint_improper_ctypes_struct_layout_reason + inline_fluent!("this struct has unspecified layout") } else { - fluent::lint_improper_ctypes_union_layout_reason + inline_fluent!("this union has unspecified layout") }, help: if def.is_struct() { - Some(fluent::lint_improper_ctypes_struct_layout_help) + Some(inline_fluent!( + "consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct" + )) } else { - Some(fluent::lint_improper_ctypes_union_layout_help) + Some(inline_fluent!( + "consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union" + )) }, }; } @@ -501,9 +513,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return FfiUnsafe { ty, reason: if def.is_struct() { - fluent::lint_improper_ctypes_struct_non_exhaustive + inline_fluent!("this struct is non-exhaustive") } else { - fluent::lint_improper_ctypes_union_non_exhaustive + inline_fluent!("this union is non-exhaustive") }, help: None, }; @@ -513,14 +525,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return FfiUnsafe { ty, reason: if def.is_struct() { - fluent::lint_improper_ctypes_struct_fieldless_reason + inline_fluent!("this struct has no fields") } else { - fluent::lint_improper_ctypes_union_fieldless_reason + inline_fluent!("this union has no fields") }, help: if def.is_struct() { - Some(fluent::lint_improper_ctypes_struct_fieldless_help) + Some(inline_fluent!("consider adding a member to this struct")) } else { - Some(fluent::lint_improper_ctypes_union_fieldless_help) + Some(inline_fluent!("consider adding a member to this union")) }, }; } @@ -545,8 +557,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_enum_repr_reason, - help: Some(fluent::lint_improper_ctypes_enum_repr_help), + reason: inline_fluent!("enum has no representation hint"), + help: Some(inline_fluent!( + "consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum" + )), }; } @@ -572,8 +586,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::Char => FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_char_reason, - help: Some(fluent::lint_improper_ctypes_char_help), + reason: inline_fluent!("the `char` type has no C equivalent"), + help: Some(inline_fluent!("consider using `u32` or `libc::wchar_t` instead")), }, // It's just extra invariants on the type that you need to uphold, @@ -585,24 +599,26 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::Slice(_) => FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_slice_reason, - help: Some(fluent::lint_improper_ctypes_slice_help), + reason: inline_fluent!("slices have no C equivalent"), + help: Some(inline_fluent!("consider using a raw pointer instead")), }, - ty::Dynamic(..) => { - FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_dyn, help: None } - } + ty::Dynamic(..) => FfiUnsafe { + ty, + reason: inline_fluent!("trait objects have no C equivalent"), + help: None, + }, ty::Str => FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_str_reason, - help: Some(fluent::lint_improper_ctypes_str_help), + reason: inline_fluent!("string slices have no C equivalent"), + help: Some(inline_fluent!("consider using `*const u8` and a length instead")), }, ty::Tuple(..) => FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_tuple_reason, - help: Some(fluent::lint_improper_ctypes_tuple_help), + reason: inline_fluent!("tuples have unspecified layout"), + help: Some(inline_fluent!("consider using a struct instead")), }, ty::RawPtr(ty, _) | ty::Ref(_, ty, _) @@ -632,8 +648,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { if sig.abi().is_rustic_abi() { return FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_fnptr_reason, - help: Some(fluent::lint_improper_ctypes_fnptr_help), + reason: inline_fluent!( + "this function pointer has Rust-specific calling convention" + ), + help: Some(inline_fluent!( + "consider using an `extern fn(...) -> ...` function pointer instead" + )), }; } @@ -657,9 +677,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // While opaque types are checked for earlier, if a projection in a struct field // normalizes to an opaque type, then it will reach this branch. - ty::Alias(ty::Opaque, ..) => { - FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_opaque, help: None } - } + ty::Alias(ty::Opaque, ..) => FfiUnsafe { + ty, + reason: inline_fluent!("opaque types have no C equivalent"), + help: None, + }, // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe, // so they are currently ignored for the purposes of this lint. @@ -669,9 +691,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { FfiSafe } - ty::UnsafeBinder(_) => { - FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_unsafe_binder, help: None } - } + ty::UnsafeBinder(_) => FfiUnsafe { + ty, + reason: inline_fluent!( + "unsafe binders are incompatible with foreign function interfaces" + ), + help: None, + }, ty::Param(..) | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..) @@ -715,7 +741,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { { Some(FfiResult::FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_opaque, + reason: inline_fluent!("opaque types have no C equivalent"), help: None, }) } else { @@ -728,8 +754,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { if let ty::Array(..) = ty.kind() { Some(FfiResult::FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_array_reason, - help: Some(fluent::lint_improper_ctypes_array_help), + reason: inline_fluent!("passing raw arrays by value is not FFI-safe"), + help: Some(inline_fluent!("consider passing a pointer to the array")), }) } else { None @@ -908,7 +934,7 @@ impl<'tcx> ImproperCTypesLint { cx, ty, sp, - fluent::lint_improper_ctypes_only_phantomdata, + inline_fluent!("composed only of `PhantomData`"), None, fn_mode, ); From f35d734d3fc0105c4f130be961c86deac299dd6c Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 19:32:52 +0100 Subject: [PATCH 3373/3801] Remove `rustc_fluent_macro` --- Cargo.lock | 13 - compiler/rustc_fluent_macro/Cargo.toml | 18 - compiler/rustc_fluent_macro/src/fluent.rs | 315 ------------------ compiler/rustc_fluent_macro/src/lib.rs | 67 ---- .../builder/cli_paths/snapshots/x_bench.snap | 1 - .../cli_paths/snapshots/x_build_compiler.snap | 1 - .../builder/cli_paths/snapshots/x_check.snap | 1 - .../cli_paths/snapshots/x_check_compiler.snap | 1 - ...eck_compiletest_include_default_paths.snap | 1 - .../builder/cli_paths/snapshots/x_clippy.snap | 1 - .../builder/cli_paths/snapshots/x_fix.snap | 1 - .../builder/cli_paths/snapshots/x_test.snap | 1 - .../snapshots/x_test_skip_coverage.snap | 1 - .../snapshots/x_test_skip_tests.snap | 2 - .../snapshots/x_test_skip_tests_etc.snap | 2 - src/bootstrap/src/core/builder/tests.rs | 10 +- src/bootstrap/src/utils/proc_macro_deps.rs | 3 - 17 files changed, 5 insertions(+), 434 deletions(-) delete mode 100644 compiler/rustc_fluent_macro/Cargo.toml delete mode 100644 compiler/rustc_fluent_macro/src/fluent.rs delete mode 100644 compiler/rustc_fluent_macro/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 03cf3bcba894..545c776b4805 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3888,19 +3888,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "rustc_fluent_macro" -version = "0.0.0" -dependencies = [ - "annotate-snippets 0.11.5", - "fluent-bundle", - "fluent-syntax", - "proc-macro2", - "quote", - "syn 2.0.110", - "unic-langid", -] - [[package]] name = "rustc_fs_util" version = "0.0.0" diff --git a/compiler/rustc_fluent_macro/Cargo.toml b/compiler/rustc_fluent_macro/Cargo.toml deleted file mode 100644 index d7ef4280aef0..000000000000 --- a/compiler/rustc_fluent_macro/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "rustc_fluent_macro" -version = "0.0.0" -edition = "2024" - -[lib] -proc-macro = true - -[dependencies] -# tidy-alphabetical-start -annotate-snippets = "0.11" -fluent-bundle = "0.16" -fluent-syntax = "0.12" -proc-macro2 = "1" -quote = "1" -syn = { version = "2", features = ["full"] } -unic-langid = { version = "0.9.0", features = ["macros"] } -# tidy-alphabetical-end diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs deleted file mode 100644 index 41357bb1ac76..000000000000 --- a/compiler/rustc_fluent_macro/src/fluent.rs +++ /dev/null @@ -1,315 +0,0 @@ -use std::collections::{HashMap, HashSet}; -use std::fs::read_to_string; -use std::path::{Path, PathBuf}; - -use annotate_snippets::{Renderer, Snippet}; -use fluent_bundle::{FluentBundle, FluentError, FluentResource}; -use fluent_syntax::ast::{ - Attribute, Entry, Expression, Identifier, InlineExpression, Message, Pattern, PatternElement, -}; -use fluent_syntax::parser::ParserError; -use proc_macro::tracked::path; -use proc_macro::{Diagnostic, Level, Span}; -use proc_macro2::TokenStream; -use quote::quote; -use syn::{Ident, LitStr, parse_macro_input}; -use unic_langid::langid; - -/// Helper function for returning an absolute path for macro-invocation relative file paths. -/// -/// If the input is already absolute, then the input is returned. If the input is not absolute, -/// then it is appended to the directory containing the source file with this macro invocation. -fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf { - let path = Path::new(path); - if path.is_absolute() { - path.to_path_buf() - } else { - // `/a/b/c/foo/bar.rs` contains the current macro invocation - let mut source_file_path = span.local_file().unwrap(); - // `/a/b/c/foo/` - source_file_path.pop(); - // `/a/b/c/foo/../locales/en-US/example.ftl` - source_file_path.push(path); - source_file_path - } -} - -/// Final tokens. -fn finish(body: TokenStream, resource: TokenStream) -> proc_macro::TokenStream { - quote! { - /// Raw content of Fluent resource for this crate, generated by `fluent_messages` macro, - /// imported by `rustc_driver` to include all crates' resources in one bundle. - pub static DEFAULT_LOCALE_RESOURCE: &'static str = #resource; - - #[allow(non_upper_case_globals)] - #[doc(hidden)] - /// Auto-generated constants for type-checked references to Fluent messages. - pub(crate) mod fluent_generated { - #body - - /// Constants expected to exist by the diagnostic derive macros to use as default Fluent - /// identifiers for different subdiagnostic kinds. - pub mod _subdiag { - /// Default for `#[help]` - pub const help: rustc_errors::SubdiagMessage = - rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("help")); - /// Default for `#[note]` - pub const note: rustc_errors::SubdiagMessage = - rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("note")); - /// Default for `#[warn]` - pub const warn: rustc_errors::SubdiagMessage = - rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("warn")); - /// Default for `#[label]` - pub const label: rustc_errors::SubdiagMessage = - rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("label")); - /// Default for `#[suggestion]` - pub const suggestion: rustc_errors::SubdiagMessage = - rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion")); - } - } - } - .into() -} - -/// Tokens to be returned when the macro cannot proceed. -fn failed(crate_name: &Ident) -> proc_macro::TokenStream { - finish(quote! { pub mod #crate_name {} }, quote! { "" }) -} - -/// See [rustc_fluent_macro::fluent_messages]. -pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let crate_name = std::env::var("CARGO_CRATE_NAME") - // If `CARGO_CRATE_NAME` is missing, then we're probably running in a test, so use - // `no_crate`. - .unwrap_or_else(|_| "no_crate".to_string()) - .replace("rustc_", ""); - - // Cannot iterate over individual messages in a bundle, so do that using the - // `FluentResource` instead. Construct a bundle anyway to find out if there are conflicting - // messages in the resources. - let mut bundle = FluentBundle::new(vec![langid!("en-US")]); - - // Set of Fluent attribute names already output, to avoid duplicate type errors - any given - // constant created for a given attribute is the same. - let mut previous_attrs = HashSet::new(); - - let resource_str = parse_macro_input!(input as LitStr); - let resource_span = resource_str.span().unwrap(); - let relative_ftl_path = resource_str.value(); - let absolute_ftl_path = invocation_relative_path_to_absolute(resource_span, &relative_ftl_path); - - let crate_name = Ident::new(&crate_name, resource_str.span()); - - path(absolute_ftl_path.to_str().unwrap()); - let resource_contents = match read_to_string(absolute_ftl_path) { - Ok(resource_contents) => resource_contents, - Err(e) => { - Diagnostic::spanned( - resource_span, - Level::Error, - format!("could not open Fluent resource: {e}"), - ) - .emit(); - return failed(&crate_name); - } - }; - let mut bad = false; - for esc in ["\\n", "\\\"", "\\'"] { - for _ in resource_contents.matches(esc) { - bad = true; - Diagnostic::spanned(resource_span, Level::Error, format!("invalid escape `{esc}` in Fluent resource")) - .note("Fluent does not interpret these escape sequences ()") - .emit(); - } - } - if bad { - return failed(&crate_name); - } - - let resource = match FluentResource::try_new(resource_contents) { - Ok(resource) => resource, - Err((this, errs)) => { - Diagnostic::spanned(resource_span, Level::Error, "could not parse Fluent resource") - .help("see additional errors emitted") - .emit(); - for ParserError { pos, slice: _, kind } in errs { - let mut err = kind.to_string(); - // Entirely unnecessary string modification so that the error message starts - // with a lowercase as rustc errors do. - err.replace_range(0..1, &err.chars().next().unwrap().to_lowercase().to_string()); - - let message = annotate_snippets::Level::Error.title(&err).snippet( - Snippet::source(this.source()) - .origin(&relative_ftl_path) - .fold(true) - .annotation(annotate_snippets::Level::Error.span(pos.start..pos.end - 1)), - ); - let renderer = Renderer::plain(); - eprintln!("{}\n", renderer.render(message)); - } - - return failed(&crate_name); - } - }; - - let mut constants = TokenStream::new(); - let mut previous_defns = HashMap::new(); - let mut message_refs = Vec::new(); - for entry in resource.entries() { - if let Entry::Message(msg) = entry { - let Message { id: Identifier { name }, attributes, value, .. } = msg; - let _ = previous_defns.entry(name.to_string()).or_insert(resource_span); - if name.contains('-') { - Diagnostic::spanned( - resource_span, - Level::Error, - format!("name `{name}` contains a '-' character"), - ) - .help("replace any '-'s with '_'s") - .emit(); - } - - if let Some(Pattern { elements }) = value { - for elt in elements { - if let PatternElement::Placeable { - expression: - Expression::Inline(InlineExpression::MessageReference { id, .. }), - } = elt - { - message_refs.push((id.name, *name)); - } - } - } - - // `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`) - // `const_eval_baz` => `baz` (in `const_eval.ftl`) - // `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`) - // The last case we error about above, but we want to fall back gracefully - // so that only the error is being emitted and not also one about the macro - // failing. - let crate_prefix = format!("{crate_name}_"); - - let snake_name = name.replace('-', "_"); - if !snake_name.starts_with(&crate_prefix) { - Diagnostic::spanned( - resource_span, - Level::Error, - format!("name `{name}` does not start with the crate name"), - ) - .help(format!( - "prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`" - )) - .emit(); - }; - let snake_name = Ident::new(&snake_name, resource_str.span()); - - if !previous_attrs.insert(snake_name.clone()) { - continue; - } - - let docstr = - format!("Constant referring to Fluent message `{name}` from `{crate_name}`"); - constants.extend(quote! { - #[doc = #docstr] - pub const #snake_name: rustc_errors::DiagMessage = - rustc_errors::DiagMessage::FluentIdentifier( - std::borrow::Cow::Borrowed(#name), - None - ); - }); - - for Attribute { id: Identifier { name: attr_name }, .. } in attributes { - let snake_name = Ident::new( - &format!("{crate_prefix}{}", attr_name.replace('-', "_")), - resource_str.span(), - ); - if !previous_attrs.insert(snake_name.clone()) { - continue; - } - - if attr_name.contains('-') { - Diagnostic::spanned( - resource_span, - Level::Error, - format!("attribute `{attr_name}` contains a '-' character"), - ) - .help("replace any '-'s with '_'s") - .emit(); - } - - let msg = format!( - "Constant referring to Fluent message `{name}.{attr_name}` from `{crate_name}`" - ); - constants.extend(quote! { - #[doc = #msg] - pub const #snake_name: rustc_errors::SubdiagMessage = - rustc_errors::SubdiagMessage::FluentAttr(std::borrow::Cow::Borrowed(#attr_name)); - }); - } - - // Record variables referenced by these messages so we can produce - // tests in the derive diagnostics to validate them. - let ident = quote::format_ident!("{snake_name}_refs"); - let vrefs = variable_references(msg); - constants.extend(quote! { - #[cfg(test)] - pub const #ident: &[&str] = &[#(#vrefs),*]; - }) - } - } - - for (mref, name) in message_refs.into_iter() { - if !previous_defns.contains_key(mref) { - Diagnostic::spanned( - resource_span, - Level::Error, - format!("referenced message `{mref}` does not exist (in message `{name}`)"), - ) - .help(format!("you may have meant to use a variable reference (`{{${mref}}}`)")) - .emit(); - } - } - - if let Err(errs) = bundle.add_resource(resource) { - for e in errs { - match e { - FluentError::Overriding { kind, id } => { - Diagnostic::spanned( - resource_span, - Level::Error, - format!("overrides existing {kind}: `{id}`"), - ) - .emit(); - } - FluentError::ResolverError(_) | FluentError::ParserError(_) => unreachable!(), - } - } - } - - finish(constants, quote! { include_str!(#relative_ftl_path) }) -} - -fn variable_references<'a>(msg: &Message<&'a str>) -> Vec<&'a str> { - let mut refs = vec![]; - if let Some(Pattern { elements }) = &msg.value { - for elt in elements { - if let PatternElement::Placeable { - expression: Expression::Inline(InlineExpression::VariableReference { id }), - } = elt - { - refs.push(id.name); - } - } - } - for attr in &msg.attributes { - for elt in &attr.value.elements { - if let PatternElement::Placeable { - expression: Expression::Inline(InlineExpression::VariableReference { id }), - } = elt - { - refs.push(id.name); - } - } - } - refs -} diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs deleted file mode 100644 index 9cd947c4c672..000000000000 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ /dev/null @@ -1,67 +0,0 @@ -// tidy-alphabetical-start -#![allow(rustc::default_hash_types)] -#![feature(proc_macro_diagnostic)] -#![feature(proc_macro_tracked_path)] -// tidy-alphabetical-end - -use proc_macro::TokenStream; - -mod fluent; - -/// Implements the `fluent_messages` macro, which performs compile-time validation of the -/// compiler's Fluent resources (i.e. that the resources parse and don't multiply define the same -/// messages) and generates constants that make using those messages in diagnostics more ergonomic. -/// -/// For example, given the following invocation of the macro.. -/// -/// ```ignore (rust) -/// fluent_messages! { "./typeck.ftl" } -/// ``` -/// ..where `typeck.ftl` has the following contents.. -/// -/// ```fluent -/// typeck_field_multiply_specified_in_initializer = -/// field `{$ident}` specified more than once -/// .label = used more than once -/// .label_previous_use = first use of `{$ident}` -/// ``` -/// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and -/// will generate the following code: -/// -/// ```ignore (rust) -/// pub static DEFAULT_LOCALE_RESOURCE: &'static [&'static str] = include_str!("./typeck.ftl"); -/// -/// mod fluent_generated { -/// mod typeck { -/// pub const field_multiply_specified_in_initializer: DiagMessage = -/// DiagMessage::fluent("typeck_field_multiply_specified_in_initializer"); -/// pub const field_multiply_specified_in_initializer_label_previous_use: DiagMessage = -/// DiagMessage::fluent_attr( -/// "typeck_field_multiply_specified_in_initializer", -/// "previous_use_label" -/// ); -/// } -/// } -/// ``` -/// When emitting a diagnostic, the generated constants can be used as follows: -/// -/// ```ignore (rust) -/// let mut err = sess.struct_span_err( -/// span, -/// fluent::typeck::field_multiply_specified_in_initializer -/// ); -/// err.span_default_label(span); -/// err.span_label( -/// previous_use_span, -/// fluent::typeck::field_multiply_specified_in_initializer_label_previous_use -/// ); -/// err.emit(); -/// ``` -/// -/// Note: any crate using this macro must also have a dependency on -/// `rustc_errors`, because the generated code refers to things from that -/// crate. -#[proc_macro] -pub fn fluent_messages(input: TokenStream) -> TokenStream { - fluent::fluent_messages(input) -} diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_bench.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_bench.snap index 13a06e353d89..3adf952d66e0 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_bench.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_bench.snap @@ -44,7 +44,6 @@ expression: bench - Set({bench::compiler/rustc_errors}) - Set({bench::compiler/rustc_expand}) - Set({bench::compiler/rustc_feature}) - - Set({bench::compiler/rustc_fluent_macro}) - Set({bench::compiler/rustc_fs_util}) - Set({bench::compiler/rustc_graphviz}) - Set({bench::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap index 721ecaf4c487..1d6e63696b06 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_build_compiler.snap @@ -26,7 +26,6 @@ expression: build compiler - Set({build::compiler/rustc_errors}) - Set({build::compiler/rustc_expand}) - Set({build::compiler/rustc_feature}) - - Set({build::compiler/rustc_fluent_macro}) - Set({build::compiler/rustc_fs_util}) - Set({build::compiler/rustc_graphviz}) - Set({build::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap index 4c3b6e11b0e4..6fc2e190290e 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check.snap @@ -28,7 +28,6 @@ expression: check - Set({check::compiler/rustc_errors}) - Set({check::compiler/rustc_expand}) - Set({check::compiler/rustc_feature}) - - Set({check::compiler/rustc_fluent_macro}) - Set({check::compiler/rustc_fs_util}) - Set({check::compiler/rustc_graphviz}) - Set({check::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap index 71d9c0fafb80..c0456f7f84d3 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiler.snap @@ -28,7 +28,6 @@ expression: check compiler - Set({check::compiler/rustc_errors}) - Set({check::compiler/rustc_expand}) - Set({check::compiler/rustc_feature}) - - Set({check::compiler/rustc_fluent_macro}) - Set({check::compiler/rustc_fs_util}) - Set({check::compiler/rustc_graphviz}) - Set({check::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap index 16348adc79df..10f36ffa6748 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_check_compiletest_include_default_paths.snap @@ -28,7 +28,6 @@ expression: check compiletest --include-default-paths - Set({check::compiler/rustc_errors}) - Set({check::compiler/rustc_expand}) - Set({check::compiler/rustc_feature}) - - Set({check::compiler/rustc_fluent_macro}) - Set({check::compiler/rustc_fs_util}) - Set({check::compiler/rustc_graphviz}) - Set({check::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_clippy.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_clippy.snap index fe8334641285..492a10d3862a 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_clippy.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_clippy.snap @@ -43,7 +43,6 @@ expression: clippy - Set({clippy::compiler/rustc_errors}) - Set({clippy::compiler/rustc_expand}) - Set({clippy::compiler/rustc_feature}) - - Set({clippy::compiler/rustc_fluent_macro}) - Set({clippy::compiler/rustc_fs_util}) - Set({clippy::compiler/rustc_graphviz}) - Set({clippy::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_fix.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_fix.snap index 8a11b4d89dde..41889cd12480 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_fix.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_fix.snap @@ -28,7 +28,6 @@ expression: fix - Set({fix::compiler/rustc_errors}) - Set({fix::compiler/rustc_expand}) - Set({fix::compiler/rustc_feature}) - - Set({fix::compiler/rustc_fluent_macro}) - Set({fix::compiler/rustc_fs_util}) - Set({fix::compiler/rustc_graphviz}) - Set({fix::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap index 46e93aa667cc..51e2c270e3ba 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test.snap @@ -94,7 +94,6 @@ expression: test - Set({test::compiler/rustc_errors}) - Set({test::compiler/rustc_expand}) - Set({test::compiler/rustc_feature}) - - Set({test::compiler/rustc_fluent_macro}) - Set({test::compiler/rustc_fs_util}) - Set({test::compiler/rustc_graphviz}) - Set({test::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap index c27da5a2a9e2..bc828c162bb0 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_coverage.snap @@ -93,7 +93,6 @@ expression: test --skip=coverage - Set({test::compiler/rustc_errors}) - Set({test::compiler/rustc_expand}) - Set({test::compiler/rustc_feature}) - - Set({test::compiler/rustc_fluent_macro}) - Set({test::compiler/rustc_fs_util}) - Set({test::compiler/rustc_graphviz}) - Set({test::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap index d5d709a60b49..ceb910e4cb36 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests.snap @@ -1,6 +1,5 @@ --- source: src/bootstrap/src/core/builder/cli_paths/tests.rs -assertion_line: 68 expression: test --skip=tests --- [Test] test::Tidy @@ -58,7 +57,6 @@ expression: test --skip=tests - Set({test::compiler/rustc_errors}) - Set({test::compiler/rustc_expand}) - Set({test::compiler/rustc_feature}) - - Set({test::compiler/rustc_fluent_macro}) - Set({test::compiler/rustc_fs_util}) - Set({test::compiler/rustc_graphviz}) - Set({test::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap index 85ca8f6ef7a0..f0e8f1aee2c7 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_skip_tests_etc.snap @@ -1,6 +1,5 @@ --- source: src/bootstrap/src/core/builder/cli_paths/tests.rs -assertion_line: 68 expression: test --skip=tests --skip=coverage-map --skip=coverage-run --skip=library --skip=tidyselftest --- [Test] test::Tidy @@ -38,7 +37,6 @@ expression: test --skip=tests --skip=coverage-map --skip=coverage-run --skip=lib - Set({test::compiler/rustc_errors}) - Set({test::compiler/rustc_expand}) - Set({test::compiler/rustc_feature}) - - Set({test::compiler/rustc_fluent_macro}) - Set({test::compiler/rustc_fs_util}) - Set({test::compiler/rustc_graphviz}) - Set({test::compiler/rustc_hashes}) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index af26c2f87d02..61db494c8c18 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1815,7 +1815,7 @@ mod snapshot { insta::assert_snapshot!( ctx.config("check") .path("compiler") - .render_steps(), @"[check] rustc 0 -> rustc 1 (75 crates)"); + .render_steps(), @"[check] rustc 0 -> rustc 1 (74 crates)"); } #[test] @@ -1841,7 +1841,7 @@ mod snapshot { ctx.config("check") .path("compiler") .stage(1) - .render_steps(), @"[check] rustc 0 -> rustc 1 (75 crates)"); + .render_steps(), @"[check] rustc 0 -> rustc 1 (74 crates)"); } #[test] @@ -1855,7 +1855,7 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 - [check] rustc 1 -> rustc 2 (75 crates) + [check] rustc 1 -> rustc 2 (74 crates) "); } @@ -1871,7 +1871,7 @@ mod snapshot { [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 [check] rustc 1 -> std 1 - [check] rustc 1 -> rustc 2 (75 crates) + [check] rustc 1 -> rustc 2 (74 crates) [check] rustc 1 -> rustc 2 [check] rustc 1 -> Rustdoc 2 [check] rustc 1 -> rustc_codegen_cranelift 2 @@ -1967,7 +1967,7 @@ mod snapshot { ctx.config("check") .paths(&["library", "compiler"]) .args(&args) - .render_steps(), @"[check] rustc 0 -> rustc 1 (75 crates)"); + .render_steps(), @"[check] rustc 0 -> rustc 1 (74 crates)"); } #[test] diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs index f1bf6e399fb1..fee9b12aca06 100644 --- a/src/bootstrap/src/utils/proc_macro_deps.rs +++ b/src/bootstrap/src/utils/proc_macro_deps.rs @@ -3,8 +3,6 @@ /// See pub static CRATES: &[&str] = &[ // tidy-alphabetical-start - "annotate-snippets", - "anstyle", "askama_derive", "askama_parser", "basic-toml", @@ -59,7 +57,6 @@ pub static CRATES: &[&str] = &[ "unic-langid-impl", "unic-langid-macros", "unicode-ident", - "unicode-width", "version_check", "wasm-bindgen-macro-support", "wasm-bindgen-shared", From 38374315165c83e77008f4457b862fd7aeee7d6d Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 19:04:39 +0100 Subject: [PATCH 3374/3801] Remove `ui-fulldeps` tests for slugs --- .../fluent-messages/duplicate-a-b.ftl | 1 - .../fluent-messages/duplicate-a.ftl | 1 - .../ui-fulldeps/fluent-messages/duplicate.ftl | 3 - .../fluent-messages/invalid-escape.ftl | 1 - .../fluent-messages/label-with-hyphens.ftl | 2 - .../fluent-messages/many-lines.ftl | 11 - .../fluent-messages/missing-crate-name.ftl | 2 - .../fluent-messages/missing-message-ref.ftl | 1 - .../fluent-messages/missing-message.ftl | 1 - .../fluent-messages/slug-with-hyphens.ftl | 1 - tests/ui-fulldeps/fluent-messages/test.rs | 87 -- tests/ui-fulldeps/fluent-messages/test.stderr | 122 --- tests/ui-fulldeps/fluent-messages/valid.ftl | 1 - .../session-diagnostic/diagnostic-derive.rs | 827 ------------------ .../diagnostic-derive.stderr | 634 -------------- .../session-diagnostic/enforce_slug_naming.rs | 24 - .../enforce_slug_naming.stderr | 11 - .../session-diagnostic/example.ftl | 7 - .../session-diagnostic/invalid-variable.rs | 20 - .../subdiagnostic-derive-2.rs | 37 - .../subdiagnostic-derive-2.stderr | 9 - .../subdiagnostic-derive.rs | 809 ----------------- .../subdiagnostic-derive.stderr | 549 ------------ 23 files changed, 3161 deletions(-) delete mode 100644 tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/duplicate-a.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/duplicate.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/invalid-escape.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/many-lines.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/missing-message.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl delete mode 100644 tests/ui-fulldeps/fluent-messages/test.rs delete mode 100644 tests/ui-fulldeps/fluent-messages/test.stderr delete mode 100644 tests/ui-fulldeps/fluent-messages/valid.ftl delete mode 100644 tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs delete mode 100644 tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr delete mode 100644 tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs delete mode 100644 tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr delete mode 100644 tests/ui-fulldeps/session-diagnostic/example.ftl delete mode 100644 tests/ui-fulldeps/session-diagnostic/invalid-variable.rs delete mode 100644 tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.rs delete mode 100644 tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.stderr delete mode 100644 tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs delete mode 100644 tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr diff --git a/tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl b/tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl deleted file mode 100644 index 9407c5170450..000000000000 --- a/tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl +++ /dev/null @@ -1 +0,0 @@ -a_b_key = Value diff --git a/tests/ui-fulldeps/fluent-messages/duplicate-a.ftl b/tests/ui-fulldeps/fluent-messages/duplicate-a.ftl deleted file mode 100644 index 9407c5170450..000000000000 --- a/tests/ui-fulldeps/fluent-messages/duplicate-a.ftl +++ /dev/null @@ -1 +0,0 @@ -a_b_key = Value diff --git a/tests/ui-fulldeps/fluent-messages/duplicate.ftl b/tests/ui-fulldeps/fluent-messages/duplicate.ftl deleted file mode 100644 index 871550b231a3..000000000000 --- a/tests/ui-fulldeps/fluent-messages/duplicate.ftl +++ /dev/null @@ -1,3 +0,0 @@ -no_crate_a_b_key = Value - -no_crate_a_b_key = Another Value diff --git a/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl b/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl deleted file mode 100644 index e28852ea0050..000000000000 --- a/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_bad_escape = don't use \n, \', or \" diff --git a/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl deleted file mode 100644 index 3088b1f8dc83..000000000000 --- a/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl +++ /dev/null @@ -1,2 +0,0 @@ -no_crate_some_slug = hi - .label-has-hyphens = test diff --git a/tests/ui-fulldeps/fluent-messages/many-lines.ftl b/tests/ui-fulldeps/fluent-messages/many-lines.ftl deleted file mode 100644 index 43660ebeacdc..000000000000 --- a/tests/ui-fulldeps/fluent-messages/many-lines.ftl +++ /dev/null @@ -1,11 +0,0 @@ -no_crate_foo = foo - -# This file tests error reporting for -# fluent files with many lines. -# The error message should point to the correct line number -# and include no more context than necessary. - -no_crate_bar = - -no_crate_baz = - baz diff --git a/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl b/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl deleted file mode 100644 index 0a64e3894bd5..000000000000 --- a/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl +++ /dev/null @@ -1,2 +0,0 @@ -with-hyphens = 1234 -no-crate_foo = abcd diff --git a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl deleted file mode 100644 index 4c6514a97700..000000000000 --- a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_missing_message_ref = {message} diff --git a/tests/ui-fulldeps/fluent-messages/missing-message.ftl b/tests/ui-fulldeps/fluent-messages/missing-message.ftl deleted file mode 100644 index 61f56fd4d57b..000000000000 --- a/tests/ui-fulldeps/fluent-messages/missing-message.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_missing_message = diff --git a/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl deleted file mode 100644 index a64c85094f1d..000000000000 --- a/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_this-slug-has-hyphens = hi diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs deleted file mode 100644 index c1f5fe730c76..000000000000 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ /dev/null @@ -1,87 +0,0 @@ -//@ normalize-stderr: "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" - -#![feature(rustc_private)] -#![crate_type = "lib"] -extern crate rustc_errors; -extern crate rustc_fluent_macro; - -/// Copy of the relevant `DiagMessage` variant constructed by `fluent_messages` as it -/// expects `crate::DiagMessage` to exist. -pub enum DiagMessage { - FluentIdentifier(std::borrow::Cow<'static, str>, Option>), -} - -/// Copy of the relevant `SubdiagMessage` variant constructed by `fluent_messages` as it -/// expects `crate::SubdiagMessage` to exist. -pub enum SubdiagMessage { - FluentAttr(std::borrow::Cow<'static, str>), -} - -mod missing_absolute { - rustc_fluent_macro::fluent_messages! { "/definitely_does_not_exist.ftl" } - //~^ ERROR could not open Fluent resource -} - -mod missing_relative { - rustc_fluent_macro::fluent_messages! { "../definitely_does_not_exist.ftl" } - //~^ ERROR could not open Fluent resource -} - -mod missing_message { - rustc_fluent_macro::fluent_messages! { "./missing-message.ftl" } - //~^ ERROR could not parse Fluent resource -} - -mod duplicate { - rustc_fluent_macro::fluent_messages! { "./duplicate.ftl" } - //~^ ERROR overrides existing message: `no_crate_a_b_key` -} - -mod slug_with_hyphens { - rustc_fluent_macro::fluent_messages! { "./slug-with-hyphens.ftl" } - //~^ ERROR name `no_crate_this-slug-has-hyphens` contains a '-' character -} - -mod label_with_hyphens { - rustc_fluent_macro::fluent_messages! { "./label-with-hyphens.ftl" } - //~^ ERROR attribute `label-has-hyphens` contains a '-' character -} - -mod valid { - rustc_fluent_macro::fluent_messages! { "./valid.ftl" } - - mod test_generated { - use super::{fluent_generated::no_crate_key, DEFAULT_LOCALE_RESOURCE}; - } -} - -mod missing_crate_name { - rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } - //~^ ERROR name `no-crate_foo` contains a '-' character - //~| ERROR name `with-hyphens` contains a '-' character - //~| ERROR name `with-hyphens` does not start with the crate name - - mod test_generated { - use super::{ - fluent_generated::{no_crate_foo, with_hyphens}, - DEFAULT_LOCALE_RESOURCE, - }; - } -} - -mod missing_message_ref { - rustc_fluent_macro::fluent_messages! { "./missing-message-ref.ftl" } - //~^ ERROR referenced message `message` does not exist -} - -mod bad_escape { - rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } - //~^ ERROR invalid escape `\n` - //~| ERROR invalid escape `\"` - //~| ERROR invalid escape `\'` -} - -mod many_lines { - rustc_fluent_macro::fluent_messages! { "./many-lines.ftl" } - //~^ ERROR could not parse Fluent resource -} diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr deleted file mode 100644 index 0b3bb14ce513..000000000000 --- a/tests/ui-fulldeps/fluent-messages/test.stderr +++ /dev/null @@ -1,122 +0,0 @@ -error: could not open Fluent resource: os-specific message - --> $DIR/test.rs:21:44 - | -LL | rustc_fluent_macro::fluent_messages! { "/definitely_does_not_exist.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: could not open Fluent resource: os-specific message - --> $DIR/test.rs:26:44 - | -LL | rustc_fluent_macro::fluent_messages! { "../definitely_does_not_exist.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: could not parse Fluent resource - --> $DIR/test.rs:31:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-message.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: see additional errors emitted - -error: expected a message field for "no_crate_missing_message" - --> ./missing-message.ftl:1:1 - | -1 | no_crate_missing_message = - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -error: overrides existing message: `no_crate_a_b_key` - --> $DIR/test.rs:36:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./duplicate.ftl" } - | ^^^^^^^^^^^^^^^^^ - -error: name `no_crate_this-slug-has-hyphens` contains a '-' character - --> $DIR/test.rs:41:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./slug-with-hyphens.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: replace any '-'s with '_'s - -error: attribute `label-has-hyphens` contains a '-' character - --> $DIR/test.rs:46:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./label-with-hyphens.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: replace any '-'s with '_'s - -error: name `with-hyphens` contains a '-' character - --> $DIR/test.rs:59:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: replace any '-'s with '_'s - -error: name `with-hyphens` does not start with the crate name - --> $DIR/test.rs:59:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: prepend `no_crate_` to the slug name: `no_crate_with_hyphens` - -error: name `no-crate_foo` contains a '-' character - --> $DIR/test.rs:59:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: replace any '-'s with '_'s - -error: referenced message `message` does not exist (in message `no_crate_missing_message_ref`) - --> $DIR/test.rs:73:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-message-ref.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: you may have meant to use a variable reference (`{$message}`) - -error: invalid escape `\n` in Fluent resource - --> $DIR/test.rs:78:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: Fluent does not interpret these escape sequences () - -error: invalid escape `\"` in Fluent resource - --> $DIR/test.rs:78:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: Fluent does not interpret these escape sequences () - -error: invalid escape `\'` in Fluent resource - --> $DIR/test.rs:78:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: Fluent does not interpret these escape sequences () - -error: could not parse Fluent resource - --> $DIR/test.rs:85:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./many-lines.ftl" } - | ^^^^^^^^^^^^^^^^^^ - | - = help: see additional errors emitted - -error: expected a message field for "no_crate_bar" - --> ./many-lines.ftl:8:1 - | -8 | no_crate_bar = - | ^^^^^^^^^^^^^^ - | - -error: aborting due to 14 previous errors - diff --git a/tests/ui-fulldeps/fluent-messages/valid.ftl b/tests/ui-fulldeps/fluent-messages/valid.ftl deleted file mode 100644 index 598473adb680..000000000000 --- a/tests/ui-fulldeps/fluent-messages/valid.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_key = Valid! diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs deleted file mode 100644 index 798eca68b1c9..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ /dev/null @@ -1,827 +0,0 @@ -//@ check-fail -// Tests error conditions for specifying diagnostics using #[derive(Diagnostic)] -//@ normalize-stderr: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" -//@ normalize-stderr: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" - -// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, -// changing the output of this test. Since Diagnostic is strictly internal to the compiler -// the test is just ignored on stable and beta: -//@ ignore-stage1 -//@ ignore-beta -//@ ignore-stable - -#![feature(rustc_private)] -#![crate_type = "lib"] - -extern crate rustc_span; -use rustc_span::symbol::Ident; -use rustc_span::Span; - -extern crate rustc_fluent_macro; -extern crate rustc_macros; -use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; - -extern crate rustc_middle; -use rustc_middle::ty::Ty; - -extern crate rustc_errors; -use rustc_errors::{Applicability, DiagMessage, ErrCode, MultiSpan, SubdiagMessage}; - -extern crate rustc_session; - -extern crate core; - -rustc_fluent_macro::fluent_messages! { "./example.ftl" } - -// E0123 and E0456 are no longer used, so we define our own constants here just for this test. -const E0123: ErrCode = ErrCode::from_u32(0123); -const E0456: ErrCode = ErrCode::from_u32(0456); - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct Hello {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct HelloWarn {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -//~^ ERROR unsupported type attribute for diagnostic derive enum -enum DiagnosticOnEnum { - Foo, - //~^ ERROR diagnostic slug not specified - Bar, - //~^ ERROR diagnostic slug not specified -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[diag = "E0123"] -//~^ ERROR expected parentheses: #[diag(...)] -struct WrongStructAttrStyle {} - -#[derive(Diagnostic)] -#[nonsense(no_crate_example, code = E0123)] -//~^ ERROR `#[nonsense(...)]` is not a valid attribute -//~^^ ERROR diagnostic slug not specified -//~^^^ ERROR cannot find attribute `nonsense` in this scope -struct InvalidStructAttr {} - -#[derive(Diagnostic)] -#[diag(code = E0123)] -//~^ ERROR diagnostic slug not specified -struct InvalidLitNestedAttr {} - -#[derive(Diagnostic)] -#[diag(nonsense, code = E0123)] -//~^ ERROR cannot find value `nonsense` in module `crate::fluent_generated` -struct InvalidNestedStructAttr {} - -#[derive(Diagnostic)] -#[diag(nonsense("foo"), code = E0123, slug = "foo")] -//~^ ERROR derive(Diagnostic): diagnostic slug not specified -struct InvalidNestedStructAttr1 {} - -#[derive(Diagnostic)] -#[diag(nonsense = "...", code = E0123, slug = "foo")] -//~^ ERROR diagnostic slug not specified -struct InvalidNestedStructAttr2 {} - -#[derive(Diagnostic)] -#[diag(nonsense = 4, code = E0123, slug = "foo")] -//~^ ERROR diagnostic slug not specified -struct InvalidNestedStructAttr3 {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123, slug = "foo")] -//~^ ERROR unknown argument -struct InvalidNestedStructAttr4 {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct WrongPlaceField { - #[suggestion = "bar"] - //~^ ERROR `#[suggestion = ...]` is not a valid attribute - sp: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[diag(no_crate_example, code = E0456)] -//~^ ERROR specified multiple times -struct DiagSpecifiedTwice {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123, code = E0456)] -//~^ ERROR specified multiple times -struct CodeSpecifiedTwice {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, no_crate::example, code = E0123)] -//~^ ERROR diagnostic slug must be the first argument -struct SlugSpecifiedTwice {} - -#[derive(Diagnostic)] -struct KindNotProvided {} //~ ERROR diagnostic slug not specified - -#[derive(Diagnostic)] -#[diag(code = E0123)] -//~^ ERROR diagnostic slug not specified -struct SlugNotProvided {} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct CodeNotProvided {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct MessageWrongType { - #[primary_span] - //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - foo: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct InvalidPathFieldAttr { - #[nonsense] - //~^ ERROR `#[nonsense]` is not a valid attribute - //~^^ ERROR cannot find attribute `nonsense` in this scope - foo: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithField { - name: String, - #[label(no_crate_label)] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithMessageAppliedToField { - #[label(no_crate_label)] - //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - name: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithNonexistentField { - #[suggestion(no_crate_suggestion, code = "{name}")] - //~^ ERROR `name` doesn't refer to a field on this type - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -//~^ ERROR invalid format string: expected `}` -#[diag(no_crate_example, code = E0123)] -struct ErrorMissingClosingBrace { - #[suggestion(no_crate_suggestion, code = "{name")] - suggestion: (Span, Applicability), - name: String, - val: usize, -} - -#[derive(Diagnostic)] -//~^ ERROR invalid format string: unmatched `}` -#[diag(no_crate_example, code = E0123)] -struct ErrorMissingOpeningBrace { - #[suggestion(no_crate_suggestion, code = "name}")] - suggestion: (Span, Applicability), - name: String, - val: usize, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelOnSpan { - #[label(no_crate_label)] - sp: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelOnNonSpan { - #[label(no_crate_label)] - //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - id: u32, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct Suggest { - #[suggestion(no_crate_suggestion, code = "This is the suggested code")] - #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "normal")] - #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "short")] - #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "hidden")] - #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "verbose")] - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithoutCode { - #[suggestion(no_crate_suggestion)] - //~^ ERROR suggestion without `code = "..."` - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithBadKey { - #[suggestion(nonsense = "bar")] - //~^ ERROR invalid nested attribute - //~| ERROR suggestion without `code = "..."` - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithShorthandMsg { - #[suggestion(msg = "bar")] - //~^ ERROR invalid nested attribute - //~| ERROR suggestion without `code = "..."` - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithoutMsg { - #[suggestion(code = "bar")] - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithTypesSwapped { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - suggestion: (Applicability, Span), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithWrongTypeApplicabilityOnly { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - //~^ ERROR wrong field type for suggestion - suggestion: Applicability, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithSpanOnly { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithDuplicateSpanAndApplicability { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - suggestion: (Span, Span, Applicability), - //~^ ERROR specified multiple times -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithDuplicateApplicabilityAndSpan { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - suggestion: (Applicability, Applicability, Span), - //~^ ERROR specified multiple times -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct WrongKindOfAnnotation { - #[label = "bar"] - //~^ ERROR `#[label = ...]` is not a valid attribute - z: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct OptionsInErrors { - #[label(no_crate_label)] - label: Option, - #[suggestion(no_crate_suggestion, code = "...")] - opt_sugg: Option<(Span, Applicability)>, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct MoveOutOfBorrowError<'tcx> { - name: Ident, - ty: Ty<'tcx>, - #[primary_span] - #[label(no_crate_label)] - span: Span, - #[label(no_crate_label)] - other_span: Span, - #[suggestion(no_crate_suggestion, code = "{name}.clone()")] - opt_sugg: Option<(Span, Applicability)>, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithLifetime<'a> { - #[label(no_crate_label)] - span: Span, - name: &'a str, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithDefaultLabelAttr<'a> { - #[label] - span: Span, - name: &'a str, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ArgFieldWithoutSkip { - #[primary_span] - span: Span, - other: Hello, - //~^ ERROR the trait bound `Hello: IntoDiagArg` is not satisfied -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ArgFieldWithSkip { - #[primary_span] - span: Span, - // `Hello` does not implement `IntoDiagArg` so this would result in an error if - // not for `#[skip_arg]`. - #[skip_arg] - other: Hello, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithSpannedNote { - #[note] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithSpannedNoteCustom { - #[note(no_crate_note)] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[note] -struct ErrorWithNote { - val: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[note(no_crate_note)] -struct ErrorWithNoteCustom { - val: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithSpannedHelp { - #[help] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithSpannedHelpCustom { - #[help(no_crate_help)] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[help] -struct ErrorWithHelp { - val: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[help(no_crate_help)] -struct ErrorWithHelpCustom { - val: String, -} - -#[derive(Diagnostic)] -#[help] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithHelpWrongOrder { - val: String, -} - -#[derive(Diagnostic)] -#[help(no_crate_help)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithHelpCustomWrongOrder { - val: String, -} - -#[derive(Diagnostic)] -#[note] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithNoteWrongOrder { - val: String, -} - -#[derive(Diagnostic)] -#[note(no_crate_note)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithNoteCustomWrongOrder { - val: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ApplicabilityInBoth { - #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] - //~^ ERROR specified multiple times - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct InvalidApplicability { - #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")] - //~^ ERROR invalid applicability - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ValidApplicability { - #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct NoApplicability { - #[suggestion(no_crate_suggestion, code = "...")] - suggestion: Span, -} - -#[derive(Subdiagnostic)] -#[note(no_crate_example)] -struct Note; - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct Subdiagnostic { - #[subdiagnostic] - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct VecField { - #[primary_span] - #[label] - spans: Vec, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct UnitField { - #[primary_span] - spans: Span, - #[help] - foo: (), - #[help(no_crate_help)] - bar: (), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct OptUnitField { - #[primary_span] - spans: Span, - #[help] - foo: Option<()>, - #[help(no_crate_help)] - bar: Option<()>, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct BoolField { - #[primary_span] - spans: Span, - #[help] - foo: bool, - #[help(no_crate_help)] - //~^ ERROR the `#[help(...)]` attribute can only be applied to fields of type - // only allow plain 'bool' fields - bar: Option, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelWithTrailingPath { - #[label(no_crate_label, foo)] - //~^ ERROR a diagnostic slug must be the first argument to the attribute - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelWithTrailingNameValue { - #[label(no_crate_label, foo = "...")] - //~^ ERROR no nested attribute expected here - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelWithTrailingList { - #[label(no_crate_label, foo("..."))] - //~^ ERROR no nested attribute expected here - span: Span, -} - -#[derive(LintDiagnostic)] -#[diag(no_crate_example)] -struct LintsGood {} - -#[derive(LintDiagnostic)] -#[diag(no_crate_example)] -struct PrimarySpanOnLint { - #[primary_span] - //~^ ERROR `#[primary_span]` is not a valid attribute - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithMultiSpan { - #[primary_span] - span: MultiSpan, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[warning] -struct ErrorWithWarn { - val: String, -} - -#[derive(Diagnostic)] -#[error(no_crate_example, code = E0123)] -//~^ ERROR `#[error(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `error` in this scope -struct ErrorAttribute {} - -#[derive(Diagnostic)] -#[warn_(no_crate_example, code = E0123)] -//~^ ERROR `#[warn_(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `warn_` in this scope -struct WarnAttribute {} - -#[derive(Diagnostic)] -#[lint(no_crate_example, code = E0123)] -//~^ ERROR `#[lint(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `lint` in this scope -struct LintAttributeOnSessionDiag {} - -#[derive(LintDiagnostic)] -#[lint(no_crate_example, code = E0123)] -//~^ ERROR `#[lint(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `lint` in this scope -struct LintAttributeOnLintDiag {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct DuplicatedSuggestionCode { - #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] - //~^ ERROR specified multiple times - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct InvalidTypeInSuggestionTuple { - #[suggestion(no_crate_suggestion, code = "...")] - suggestion: (Span, usize), - //~^ ERROR wrong types for suggestion -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct MissingApplicabilityInSuggestionTuple { - #[suggestion(no_crate_suggestion, code = "...")] - suggestion: (Span,), - //~^ ERROR wrong types for suggestion -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct MissingCodeInSuggestion { - #[suggestion(no_crate_suggestion)] - //~^ ERROR suggestion without `code = "..."` - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[multipart_suggestion(no_crate_suggestion)] -//~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute -//~| ERROR cannot find attribute `multipart_suggestion` in this scope -#[multipart_suggestion()] -//~^ ERROR cannot find attribute `multipart_suggestion` in this scope -//~| ERROR `#[multipart_suggestion(...)]` is not a valid attribute -struct MultipartSuggestion { - #[multipart_suggestion(no_crate_suggestion)] - //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute - //~| ERROR cannot find attribute `multipart_suggestion` in this scope - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[suggestion(no_crate_suggestion, code = "...")] -//~^ ERROR `#[suggestion(...)]` is not a valid attribute -struct SuggestionOnStruct { - #[primary_span] - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[label] -//~^ ERROR `#[label]` is not a valid attribute -struct LabelOnStruct { - #[primary_span] - suggestion: Span, -} - -#[derive(Diagnostic)] -enum ExampleEnum { - #[diag(no_crate_example)] - Foo { - #[primary_span] - sp: Span, - #[note] - note_sp: Span, - }, - #[diag(no_crate_example)] - Bar { - #[primary_span] - sp: Span, - }, - #[diag(no_crate_example)] - Baz, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct RawIdentDiagnosticArg { - pub r#type: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticBad { - #[subdiagnostic(bad)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticBadStr { - #[subdiagnostic = "bad"] - //~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticBadTwice { - #[subdiagnostic(bad, bad)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticBadLitStr { - #[subdiagnostic("bad")] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -#[derive(LintDiagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticEagerLint { - #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticEagerFormerlyCorrect { - #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -// Check that formatting of `correct` in suggestion doesn't move the binding for that field, making -// the `arg` call a compile error; and that isn't worked around by moving the `arg` call -// after the `span_suggestion` call - which breaks eager translation. - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, applicability = "machine-applicable", code = "{correct}")] -pub(crate) struct SubdiagnosticWithSuggestion { - #[primary_span] - span: Span, - invalid: String, - correct: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticEagerSuggestion { - #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - sub: SubdiagnosticWithSuggestion, -} - -/// with a doc comment on the type.. -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct WithDocComment { - /// ..and the field - #[primary_span] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionsGood { - #[suggestion(code("foo", "bar"))] - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionsSingleItem { - #[suggestion(code("foo"))] - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionsNoItem { - #[suggestion(code())] - //~^ ERROR expected at least one string literal for `code(...)` - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionsInvalidItem { - #[suggestion(code(foo))] - //~^ ERROR `code(...)` must contain only string literals - //~| ERROR unexpected token, expected `)` - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionsInvalidLiteral { - #[suggestion(code = 3)] - //~^ ERROR expected string literal - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionStyleGood { - #[suggestion(code = "", style = "hidden")] - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionOnVec { - #[suggestion(no_crate_suggestion, code = "")] - //~^ ERROR `#[suggestion(...)]` is not a valid attribute - sub: Vec, -} diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr deleted file mode 100644 index 9ecb6c15767e..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ /dev/null @@ -1,634 +0,0 @@ -error: derive(Diagnostic): unsupported type attribute for diagnostic derive enum - --> $DIR/diagnostic-derive.rs:49:1 - | -LL | #[diag(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:52:5 - | -LL | Foo, - | ^^^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:54:5 - | -LL | Bar, - | ^^^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: expected parentheses: #[diag(...)] - --> $DIR/diagnostic-derive.rs:60:8 - | -LL | #[diag = "E0123"] - | ^ - -error: derive(Diagnostic): `#[nonsense(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:65:1 - | -LL | #[nonsense(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:65:1 - | -LL | #[nonsense(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:72:1 - | -LL | #[diag(code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:82:1 - | -LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:87:1 - | -LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:92:1 - | -LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): unknown argument - --> $DIR/diagnostic-derive.rs:97:40 - | -LL | #[diag(no_crate_example, code = E0123, slug = "foo")] - | ^^^^ - | - = note: only the `code` parameter is valid after the slug - -error: derive(Diagnostic): `#[suggestion = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:104:5 - | -LL | #[suggestion = "bar"] - | ^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:111:26 - | -LL | #[diag(no_crate_example, code = E0456)] - | ^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:110:26 - | -LL | #[diag(no_crate_example, code = E0123)] - | ^^^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:116:40 - | -LL | #[diag(no_crate_example, code = E0123, code = E0456)] - | ^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:116:26 - | -LL | #[diag(no_crate_example, code = E0123, code = E0456)] - | ^^^^ - -error: derive(Diagnostic): diagnostic slug must be the first argument - --> $DIR/diagnostic-derive.rs:121:26 - | -LL | #[diag(no_crate_example, no_crate::example, code = E0123)] - | ^^^^^^^^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:126:1 - | -LL | struct KindNotProvided {} - | ^^^^^^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:129:1 - | -LL | #[diag(code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:140:5 - | -LL | #[primary_span] - | ^ - -error: derive(Diagnostic): `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:148:5 - | -LL | #[nonsense] - | ^ - -error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:165:5 - | -LL | #[label(no_crate_label)] - | ^ - -error: derive(Diagnostic): `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:173:46 - | -LL | #[suggestion(no_crate_suggestion, code = "{name}")] - | ^^^^^^^^ - -error: invalid format string: expected `}` but string was terminated - --> $DIR/diagnostic-derive.rs:178:10 - | -LL | #[derive(Diagnostic)] - | ^^^^^^^^^^ expected `}` in format string - | - = note: if you intended to print `{`, you can escape it using `{{` - = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive.rs:188:10 - | -LL | #[derive(Diagnostic)] - | ^^^^^^^^^^ unmatched `}` in format string - | - = note: if you intended to print `}`, you can escape it using `}}` - = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:208:5 - | -LL | #[label(no_crate_label)] - | ^ - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:227:5 - | -LL | #[suggestion(no_crate_suggestion)] - | ^ - -error: derive(Diagnostic): invalid nested attribute - --> $DIR/diagnostic-derive.rs:235:18 - | -LL | #[suggestion(nonsense = "bar")] - | ^^^^^^^^ - | - = help: only `style`, `code` and `applicability` are valid nested attributes - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:235:5 - | -LL | #[suggestion(nonsense = "bar")] - | ^ - -error: derive(Diagnostic): invalid nested attribute - --> $DIR/diagnostic-derive.rs:244:18 - | -LL | #[suggestion(msg = "bar")] - | ^^^ - | - = help: only `style`, `code` and `applicability` are valid nested attributes - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:244:5 - | -LL | #[suggestion(msg = "bar")] - | ^ - -error: derive(Diagnostic): wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:267:5 - | -LL | #[suggestion(no_crate_suggestion, code = "This is suggested code")] - | ^ - | - = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:283:24 - | -LL | suggestion: (Span, Span, Applicability), - | ^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:283:18 - | -LL | suggestion: (Span, Span, Applicability), - | ^^^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:291:33 - | -LL | suggestion: (Applicability, Applicability, Span), - | ^^^^^^^^^^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:291:18 - | -LL | suggestion: (Applicability, Applicability, Span), - | ^^^^^^^^^^^^^ - -error: derive(Diagnostic): `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:298:5 - | -LL | #[label = "bar"] - | ^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:449:5 - | -LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] - | ^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:451:24 - | -LL | suggestion: (Span, Applicability), - | ^^^^^^^^^^^^^ - -error: derive(Diagnostic): invalid applicability - --> $DIR/diagnostic-derive.rs:457:69 - | -LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")] - | ^^^^^^^^ - -error: derive(Diagnostic): the `#[help(...)]` attribute can only be applied to fields of type `Span`, `MultiSpan`, `bool` or `()` - --> $DIR/diagnostic-derive.rs:524:5 - | -LL | #[help(no_crate_help)] - | ^ - -error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/diagnostic-derive.rs:533:29 - | -LL | #[label(no_crate_label, foo)] - | ^^^ - -error: derive(Diagnostic): no nested attribute expected here - --> $DIR/diagnostic-derive.rs:541:29 - | -LL | #[label(no_crate_label, foo = "...")] - | ^^^ - -error: derive(Diagnostic): no nested attribute expected here - --> $DIR/diagnostic-derive.rs:549:29 - | -LL | #[label(no_crate_label, foo("..."))] - | ^^^ - -error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:561:5 - | -LL | #[primary_span] - | ^ - | - = help: the `primary_span` field attribute is not valid for lint diagnostics - -error: derive(Diagnostic): `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:581:1 - | -LL | #[error(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:581:1 - | -LL | #[error(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:588:1 - | -LL | #[warn_(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:588:1 - | -LL | #[warn_(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:595:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:595:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:602:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:602:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:611:53 - | -LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] - | ^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:611:39 - | -LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] - | ^^^^ - -error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive.rs:620:24 - | -LL | suggestion: (Span, usize), - | ^^^^^ - | - = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` - -error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive.rs:628:17 - | -LL | suggestion: (Span,), - | ^^^^^^^ - | - = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:635:5 - | -LL | #[suggestion(no_crate_suggestion)] - | ^ - -error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:642:1 - | -LL | #[multipart_suggestion(no_crate_suggestion)] - | ^ - | - = help: consider creating a `Subdiagnostic` instead - -error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:645:1 - | -LL | #[multipart_suggestion()] - | ^ - | - = help: consider creating a `Subdiagnostic` instead - -error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:649:5 - | -LL | #[multipart_suggestion(no_crate_suggestion)] - | ^ - | - = help: consider creating a `Subdiagnostic` instead - -error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:657:1 - | -LL | #[suggestion(no_crate_suggestion, code = "...")] - | ^ - | - = help: `#[label]` and `#[suggestion]` can only be applied to fields - -error: derive(Diagnostic): `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:666:1 - | -LL | #[label] - | ^ - | - = help: `#[label]` and `#[suggestion]` can only be applied to fields - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:700:5 - | -LL | #[subdiagnostic(bad)] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:708:5 - | -LL | #[subdiagnostic = "bad"] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:716:5 - | -LL | #[subdiagnostic(bad, bad)] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:724:5 - | -LL | #[subdiagnostic("bad")] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:732:5 - | -LL | #[subdiagnostic(eager)] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:740:5 - | -LL | #[subdiagnostic(eager)] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:761:5 - | -LL | #[subdiagnostic(eager)] - | ^ - -error: derive(Diagnostic): expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:792:23 - | -LL | #[suggestion(code())] - | ^ - -error: derive(Diagnostic): `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:800:23 - | -LL | #[suggestion(code(foo))] - | ^^^ - -error: unexpected token, expected `)` - --> $DIR/diagnostic-derive.rs:800:23 - | -LL | #[suggestion(code(foo))] - | ^^^ - -error: expected string literal - --> $DIR/diagnostic-derive.rs:809:25 - | -LL | #[suggestion(code = 3)] - | ^ - -error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:824:5 - | -LL | #[suggestion(no_crate_suggestion, code = "")] - | ^ - | - = note: `#[suggestion(...)]` applied to `Vec` field is ambiguous - = help: to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]` - = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` - -error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:65:3 - | -LL | #[nonsense(no_crate_example, code = E0123)] - | ^^^^^^^^ - -error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:148:7 - | -LL | #[nonsense] - | ^^^^^^^^ - -error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive.rs:581:3 - | -LL | #[error(no_crate_example, code = E0123)] - | ^^^^^ - | -help: `error` is an attribute that can be used by the derive macro `Error`, you might be missing a `derive` attribute - | -LL + #[derive(Error)] -LL | struct ErrorAttribute {} - | - -error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive.rs:588:3 - | -LL | #[warn_(no_crate_example, code = E0123)] - | ^^^^^ - | -help: a built-in attribute with a similar name exists - | -LL - #[warn_(no_crate_example, code = E0123)] -LL + #[warn(no_crate_example, code = E0123)] - | - -error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:595:3 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^^^^ - | -help: a built-in attribute with a similar name exists - | -LL - #[lint(no_crate_example, code = E0123)] -LL + #[link(no_crate_example, code = E0123)] - | - -error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:602:3 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^^^^ - | -help: a built-in attribute with a similar name exists - | -LL - #[lint(no_crate_example, code = E0123)] -LL + #[link(no_crate_example, code = E0123)] - | - -error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:642:3 - | -LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^ - | -help: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute - | -LL + #[derive(Subdiagnostic)] -LL | struct MultipartSuggestion { - | - -error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:645:3 - | -LL | #[multipart_suggestion()] - | ^^^^^^^^^^^^^^^^^^^^ - | -help: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute - | -LL + #[derive(Subdiagnostic)] -LL | struct MultipartSuggestion { - | - -error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:649:7 - | -LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute - -error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated` - --> $DIR/diagnostic-derive.rs:77:8 - | -LL | #[diag(nonsense, code = E0123)] - | ^^^^^^^^ not found in `crate::fluent_generated` - -error[E0277]: the trait bound `Hello: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive.rs:347:12 - | -LL | #[derive(Diagnostic)] - | ---------- required by a bound introduced by this call -... -LL | other: Hello, - | ^^^^^ unsatisfied trait bound - | -help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `Hello` - --> $DIR/diagnostic-derive.rs:42:1 - | -LL | struct Hello {} - | ^^^^^^^^^^^^ - = help: normalized in stderr -note: required by a bound in `Diag::<'a, G>::arg` - --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC - ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC - | - = note: in this macro invocation - = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 80 previous errors - -Some errors have detailed explanations: E0277, E0425. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs deleted file mode 100644 index 6402b00ef0a9..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ rustc-env:CARGO_CRATE_NAME=rustc_dummy - -#![feature(rustc_private)] -#![crate_type = "lib"] - -extern crate rustc_span; -use rustc_span::symbol::Ident; -use rustc_span::Span; - -extern crate rustc_macros; -use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; - -extern crate rustc_middle; -use rustc_middle::ty::Ty; - -extern crate rustc_errors; -use rustc_errors::{Applicability, MultiSpan}; - -extern crate rustc_session; - -#[derive(Diagnostic)] -#[diag(compiletest_example, code = E0123)] -//~^ ERROR diagnostic slug and crate name do not match -struct Hello {} diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr deleted file mode 100644 index 4f54239f0fa3..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: derive(Diagnostic): diagnostic slug and crate name do not match - --> $DIR/enforce_slug_naming.rs:22:8 - | -LL | #[diag(compiletest_example, code = E0123)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: slug is `compiletest_example` but the crate name is `rustc_dummy` - = help: expected a slug starting with `dummy_...` - -error: aborting due to 1 previous error - diff --git a/tests/ui-fulldeps/session-diagnostic/example.ftl b/tests/ui-fulldeps/session-diagnostic/example.ftl deleted file mode 100644 index 1d1ba8e1bd5c..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/example.ftl +++ /dev/null @@ -1,7 +0,0 @@ -no_crate_example = this is an example message used in testing - .note = with a note - .help = with a help - .suggestion = with a suggestion - .label = with a label - -no_crate_bad_reference = {$r} does not exist diff --git a/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs b/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs deleted file mode 100644 index cbe9e3f4ef4c..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ run-fail -//@ compile-flags: --test -// test that messages referencing non-existent fields cause test failures - -#![feature(rustc_private)] -#![crate_type = "lib"] - -extern crate rustc_driver; -extern crate rustc_fluent_macro; -extern crate rustc_macros; -extern crate rustc_errors; -use rustc_macros::Diagnostic; -use rustc_errors::{DiagMessage, SubdiagMessage}; -extern crate rustc_session; - -rustc_fluent_macro::fluent_messages! { "./example.ftl" } - -#[derive(Diagnostic)] -#[diag(no_crate_bad_reference)] -struct BadRef; diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.rs deleted file mode 100644 index f42fe1689842..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.rs +++ /dev/null @@ -1,37 +0,0 @@ -//@ check-fail -// Tests error conditions for specifying subdiagnostics using #[derive(Subdiagnostic)]. -// This test is split off from the main `subdiagnostic-derive`, -// because this error is generated post-expansion. - -// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, -// changing the output of this test. Since Subdiagnostic is strictly internal to the compiler -// the test is just ignored on stable and beta: -//@ ignore-stage1 -//@ ignore-beta -//@ ignore-stable - -#![feature(rustc_private)] -#![crate_type = "lib"] - -extern crate rustc_errors; -extern crate rustc_fluent_macro; -extern crate rustc_macros; -extern crate rustc_session; -extern crate rustc_span; -extern crate core; - -use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; -use rustc_macros::Subdiagnostic; -use rustc_span::Span; - -rustc_fluent_macro::fluent_messages! { "./example.ftl" } - -#[derive(Subdiagnostic)] -#[label(slug)] -//~^ ERROR cannot find value `slug` in module `crate::fluent_generated` -//~^^ NOTE not found in `crate::fluent_generated` -struct L { - #[primary_span] - span: Span, - var: String, -} diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.stderr deleted file mode 100644 index 37566e39fcd6..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0425]: cannot find value `slug` in module `crate::fluent_generated` - --> $DIR/subdiagnostic-derive-2.rs:30:9 - | -LL | #[label(slug)] - | ^^^^ not found in `crate::fluent_generated` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs deleted file mode 100644 index c06ea451b9bf..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ /dev/null @@ -1,809 +0,0 @@ -//@ check-fail -// Tests error conditions for specifying subdiagnostics using #[derive(Subdiagnostic)] - -// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, -// changing the output of this test. Since Subdiagnostic is strictly internal to the compiler -// the test is just ignored on stable and beta: -//@ ignore-stage1 -//@ ignore-beta -//@ ignore-stable - -#![feature(rustc_private)] -#![crate_type = "lib"] - -extern crate rustc_errors; -extern crate rustc_fluent_macro; -extern crate rustc_macros; -extern crate rustc_session; -extern crate rustc_span; -extern crate core; - -use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; -use rustc_macros::Subdiagnostic; -use rustc_span::Span; - -rustc_fluent_macro::fluent_messages! { "./example.ftl" } - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct A { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -enum B { - #[label(no_crate_example)] - A { - #[primary_span] - span: Span, - var: String, - }, - #[label(no_crate_example)] - B { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -//~^ ERROR label without `#[primary_span]` field -struct C { - var: String, -} - -#[derive(Subdiagnostic)] -#[label] -//~^ ERROR diagnostic slug must be first argument -struct D { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[foo] -//~^ ERROR `#[foo]` is not a valid attribute -//~^^ ERROR cannot find attribute `foo` in this scope -struct E { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label = "..."] -//~^ ERROR `#[label = ...]` is not a valid attribute -struct F { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(bug = "...")] -//~^ ERROR no nested attribute expected here -//~| ERROR diagnostic slug must be first argument -struct G { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(slug = 4)] -//~^ ERROR no nested attribute expected here -//~| ERROR diagnostic slug must be first argument -struct J { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(slug("..."))] -//~^ ERROR no nested attribute expected here -//~| ERROR diagnostic slug must be first argument -struct K { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label()] -//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute -struct M { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example, code = "...")] -//~^ ERROR no nested attribute expected here -struct N { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example, applicability = "machine-applicable")] -//~^ ERROR no nested attribute expected here -struct O { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[foo] -//~^ ERROR cannot find attribute `foo` in this scope -//~^^ ERROR unsupported type attribute for subdiagnostic enum -enum P { - #[label(no_crate_example)] - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum Q { - #[bar] - //~^ ERROR `#[bar]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum R { - #[bar = "..."] - //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum S { - #[bar = 4] - //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum T { - #[bar("...")] - //~^ ERROR `#[bar(...)]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum U { - #[label(code = "...")] - //~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute - //~| ERROR no nested attribute expected here - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum V { - #[label(no_crate_example)] - A { - #[primary_span] - span: Span, - var: String, - }, - B { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -//~^ ERROR label without `#[primary_span]` field -struct W { - #[primary_span] - //~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - span: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct X { - #[primary_span] - span: Span, - #[applicability] - //~^ ERROR `#[applicability]` is only valid on suggestions - applicability: Applicability, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct Y { - #[primary_span] - span: Span, - #[bar] - //~^ ERROR `#[bar]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - bar: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct Z { - #[primary_span] - span: Span, - #[bar = "..."] - //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - bar: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct AA { - #[primary_span] - span: Span, - #[bar("...")] - //~^ ERROR `#[bar(...)]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - bar: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct AB { - #[primary_span] - span: Span, - #[skip_arg] - z: Z, -} - -#[derive(Subdiagnostic)] -union AC { - //~^ ERROR unexpected unsupported untagged union - span: u32, - b: u64, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -#[label(no_crate_example)] -struct AD { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example, no_crate::example)] -//~^ ERROR a diagnostic slug must be the first argument to the attribute -struct AE { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct AF { - #[primary_span] - //~^ NOTE previously specified here - span_a: Span, - #[primary_span] - //~^ ERROR specified multiple times - span_b: Span, -} - -#[derive(Subdiagnostic)] -struct AG { - //~^ ERROR subdiagnostic kind not specified - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -struct AH { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, - var: String, -} - -#[derive(Subdiagnostic)] -enum AI { - #[suggestion(no_crate_example, code = "...")] - A { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, - var: String, - }, - #[suggestion(no_crate_example, code = "...")] - B { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, - var: String, - }, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...", code = "...")] -//~^ ERROR specified multiple times -//~^^ NOTE previously specified here -struct AJ { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -struct AK { - #[primary_span] - span: Span, - #[applicability] - //~^ NOTE previously specified here - applicability_a: Applicability, - #[applicability] - //~^ ERROR specified multiple times - applicability_b: Applicability, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -struct AL { - #[primary_span] - span: Span, - #[applicability] - //~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability` - applicability: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -struct AM { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example)] -//~^ ERROR suggestion without `code = "..."` -struct AN { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...", applicability = "foo")] -//~^ ERROR invalid applicability -struct AO { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[help(no_crate_example)] -struct AP { - var: String, -} - -#[derive(Subdiagnostic)] -#[note(no_crate_example)] -struct AQ; - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -//~^ ERROR suggestion without `#[primary_span]` field -struct AR { - var: String, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] -struct AS { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[label] -//~^ ERROR unsupported type attribute for subdiagnostic enum -enum AT { - #[label(no_crate_example)] - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] -struct AU { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] -//~^ ERROR `var` doesn't refer to a field on this type -struct AV { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -enum AW { - #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum AX { - #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] - //~^ ERROR `var` doesn't refer to a field on this type - A { - #[primary_span] - span: Span, - }, -} - -#[derive(Subdiagnostic)] -#[warning(no_crate_example)] -struct AY {} - -#[derive(Subdiagnostic)] -#[warning(no_crate_example)] -struct AZ { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -//~^ ERROR suggestion without `#[primary_span]` field -struct BA { - #[suggestion_part] - //~^ ERROR `#[suggestion_part]` is not a valid attribute - span: Span, - #[suggestion_part(code = "...")] - //~^ ERROR `#[suggestion_part(...)]` is not a valid attribute - span2: Span, - #[applicability] - applicability: Applicability, - var: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] -//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields -//~| ERROR invalid nested attribute -struct BBa { - var: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BBb { - #[suggestion_part] - //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` - span1: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BBc { - #[suggestion_part()] - //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` - span1: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields -struct BC { - #[primary_span] - //~^ ERROR `#[primary_span]` is not a valid attribute - span: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BD { - #[suggestion_part] - //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` - span1: Span, - #[suggestion_part()] - //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` - span2: Span, - #[suggestion_part(foo = "bar")] - //~^ ERROR `code` is the only valid nested attribute - //~| ERROR expected `,` - span4: Span, - #[suggestion_part(code = "...")] - //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - s1: String, - #[suggestion_part()] - //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - s2: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BE { - #[suggestion_part(code = "...", code = ",,,")] - //~^ ERROR specified multiple times - //~| NOTE previously specified here - span: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BF { - #[suggestion_part(code = "(")] - first: Span, - #[suggestion_part(code = ")")] - second: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BG { - #[applicability] - appl: Applicability, - #[suggestion_part(code = "(")] - first: Span, - #[suggestion_part(code = ")")] - second: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BH { - #[applicability] - //~^ ERROR `#[applicability]` has no effect - appl: Applicability, - #[suggestion_part(code = "(")] - first: Span, - #[suggestion_part(code = ")")] - second: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BI { - #[suggestion_part(code = "")] - spans: Vec, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct BJ { - #[primary_span] - span: Span, - r#type: String, -} - -/// with a doc comment on the type.. -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct BK { - /// ..and the field - #[primary_span] - span: Span, -} - -/// with a doc comment on the type.. -#[derive(Subdiagnostic)] -enum BL { - /// ..and the variant.. - #[label(no_crate_example)] - Foo { - /// ..and the field - #[primary_span] - span: Span, - }, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BM { - #[suggestion_part(code("foo"))] - //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR unexpected token, expected `)` - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BN { - #[suggestion_part(code("foo", "bar"))] - //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR unexpected token, expected `)` - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BO { - #[suggestion_part(code(3))] - //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR unexpected token, expected `)` - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BP { - #[suggestion_part(code())] - //~^ ERROR expected exactly one string literal for `code = ...` - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BQ { - #[suggestion_part(code = 3)] - //~^ ERROR expected string literal - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "")] -struct SuggestionStyleDefault { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "short")] -struct SuggestionStyleShort { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "hidden")] -struct SuggestionStyleHidden { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "verbose")] -struct SuggestionStyleVerbose { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "tool-only")] -struct SuggestionStyleToolOnly { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] -//~^ ERROR specified multiple times -//~| NOTE previously specified here -struct SuggestionStyleTwice { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion_hidden(no_crate_example, code = "")] -//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute -struct SuggestionStyleOldSyntax { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion_hidden(no_crate_example, code = "", style = "normal")] -//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute -struct SuggestionStyleOldAndNewSyntax { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "foo")] -//~^ ERROR invalid suggestion style -struct SuggestionStyleInvalid1 { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = 42)] -//~^ ERROR expected string literal -struct SuggestionStyleInvalid2 { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style)] -//~^ ERROR a diagnostic slug must be the first argument to the attribute -struct SuggestionStyleInvalid3 { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style("foo"))] -//~^ ERROR expected `=` -struct SuggestionStyleInvalid4 { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "")] -//~^ ERROR suggestion without `#[primary_span]` field -struct PrimarySpanOnVec { - #[primary_span] - //~^ ERROR `#[primary_span]` is not a valid attribute - //~| NOTE there must be exactly one primary span - sub: Vec, -} - -#[derive(Subdiagnostic)] -struct NestedParent { - #[subdiagnostic] - single_sub: A, - #[subdiagnostic] - option_sub: Option, - #[subdiagnostic] - vec_sub: Vec, -} diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr deleted file mode 100644 index 9f18f7ffabcc..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ /dev/null @@ -1,549 +0,0 @@ -error: derive(Diagnostic): label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:52:1 - | -LL | #[label(no_crate_example)] - | ^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:59:1 - | -LL | #[label] - | ^ - -error: derive(Diagnostic): `#[foo]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:68:1 - | -LL | #[foo] - | ^ - -error: derive(Diagnostic): `#[label = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:78:1 - | -LL | #[label = "..."] - | ^ - -error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive.rs:87:9 - | -LL | #[label(bug = "...")] - | ^^^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:87:1 - | -LL | #[label(bug = "...")] - | ^ - -error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive.rs:97:9 - | -LL | #[label(slug = 4)] - | ^^^^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:97:1 - | -LL | #[label(slug = 4)] - | ^ - -error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive.rs:107:9 - | -LL | #[label(slug("..."))] - | ^^^^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:107:1 - | -LL | #[label(slug("..."))] - | ^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:117:1 - | -LL | #[label()] - | ^ - -error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive.rs:126:27 - | -LL | #[label(no_crate_example, code = "...")] - | ^^^^ - -error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive.rs:135:27 - | -LL | #[label(no_crate_example, applicability = "machine-applicable")] - | ^^^^^^^^^^^^^ - -error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:144:1 - | -LL | #[foo] - | ^ - -error: derive(Diagnostic): `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:158:5 - | -LL | #[bar] - | ^ - -error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:170:5 - | -LL | #[bar = "..."] - | ^ - -error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:182:5 - | -LL | #[bar = 4] - | ^ - -error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:194:5 - | -LL | #[bar("...")] - | ^ - -error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive.rs:206:13 - | -LL | #[label(code = "...")] - | ^^^^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:206:5 - | -LL | #[label(code = "...")] - | ^ - -error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:235:5 - | -LL | #[primary_span] - | ^ - -error: derive(Diagnostic): label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:232:1 - | -LL | #[label(no_crate_example)] - | ^ - -error: derive(Diagnostic): `#[applicability]` is only valid on suggestions - --> $DIR/subdiagnostic-derive.rs:245:5 - | -LL | #[applicability] - | ^ - -error: derive(Diagnostic): `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:255:5 - | -LL | #[bar] - | ^ - | - = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes - -error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:266:5 - | -LL | #[bar = "..."] - | ^ - -error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:277:5 - | -LL | #[bar("...")] - | ^ - | - = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes - -error: unexpected unsupported untagged union - --> $DIR/subdiagnostic-derive.rs:293:1 - | -LL | / union AC { -LL | | -LL | | span: u32, -LL | | b: u64, -LL | | } - | |_^ - -error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:308:27 - | -LL | #[label(no_crate_example, no_crate::example)] - | ^^^^^^^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:321:5 - | -LL | #[primary_span] - | ^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:318:5 - | -LL | #[primary_span] - | ^ - -error: derive(Diagnostic): subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive.rs:327:8 - | -LL | struct AG { - | ^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:364:46 - | -LL | #[suggestion(no_crate_example, code = "...", code = "...")] - | ^^^^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:364:32 - | -LL | #[suggestion(no_crate_example, code = "...", code = "...")] - | ^^^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:382:5 - | -LL | #[applicability] - | ^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:379:5 - | -LL | #[applicability] - | ^ - -error: derive(Diagnostic): the `#[applicability]` attribute can only be applied to fields of type `Applicability` - --> $DIR/subdiagnostic-derive.rs:392:5 - | -LL | #[applicability] - | ^ - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:405:1 - | -LL | #[suggestion(no_crate_example)] - | ^ - -error: derive(Diagnostic): invalid applicability - --> $DIR/subdiagnostic-derive.rs:415:62 - | -LL | #[suggestion(no_crate_example, code = "...", applicability = "foo")] - | ^^^^^ - -error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:433:1 - | -LL | #[suggestion(no_crate_example, code = "...")] - | ^ - -error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:447:1 - | -LL | #[label] - | ^ - -error: derive(Diagnostic): `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:467:39 - | -LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] - | ^^^^^^^ - -error: derive(Diagnostic): `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:486:43 - | -LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] - | ^^^^^^^ - -error: derive(Diagnostic): `#[suggestion_part]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:509:5 - | -LL | #[suggestion_part] - | ^ - | - = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead - -error: derive(Diagnostic): `#[suggestion_part(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:512:5 - | -LL | #[suggestion_part(code = "...")] - | ^ - | - = help: `#[suggestion_part(...)]` is only valid in multipart suggestions - -error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:506:1 - | -LL | #[suggestion(no_crate_example, code = "...")] - | ^ - -error: derive(Diagnostic): invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:521:42 - | -LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] - | ^^^^ - | - = help: only `style` and `applicability` are valid nested attributes - -error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:521:1 - | -LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] - | ^ - -error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:531:5 - | -LL | #[suggestion_part] - | ^ - -error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:539:5 - | -LL | #[suggestion_part()] - | ^ - -error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:548:5 - | -LL | #[primary_span] - | ^ - | - = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` - -error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:545:1 - | -LL | #[multipart_suggestion(no_crate_example)] - | ^ - -error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:556:5 - | -LL | #[suggestion_part] - | ^ - -error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:559:5 - | -LL | #[suggestion_part()] - | ^ - -error: derive(Diagnostic): `code` is the only valid nested attribute - --> $DIR/subdiagnostic-derive.rs:562:23 - | -LL | #[suggestion_part(foo = "bar")] - | ^^^ - -error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:566:5 - | -LL | #[suggestion_part(code = "...")] - | ^ - -error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:569:5 - | -LL | #[suggestion_part()] - | ^ - -error: expected `,` - --> $DIR/subdiagnostic-derive.rs:562:27 - | -LL | #[suggestion_part(foo = "bar")] - | ^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:577:37 - | -LL | #[suggestion_part(code = "...", code = ",,,")] - | ^^^^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:577:23 - | -LL | #[suggestion_part(code = "...", code = ",,,")] - | ^^^^ - -error: derive(Diagnostic): `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."` - --> $DIR/subdiagnostic-derive.rs:606:5 - | -LL | #[applicability] - | ^ - -error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:654:28 - | -LL | #[suggestion_part(code("foo"))] - | ^^^^^ - -error: unexpected token, expected `)` - --> $DIR/subdiagnostic-derive.rs:654:28 - | -LL | #[suggestion_part(code("foo"))] - | ^^^^^ - -error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:664:28 - | -LL | #[suggestion_part(code("foo", "bar"))] - | ^^^^^ - -error: unexpected token, expected `)` - --> $DIR/subdiagnostic-derive.rs:664:28 - | -LL | #[suggestion_part(code("foo", "bar"))] - | ^^^^^ - -error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:674:28 - | -LL | #[suggestion_part(code(3))] - | ^ - -error: unexpected token, expected `)` - --> $DIR/subdiagnostic-derive.rs:674:28 - | -LL | #[suggestion_part(code(3))] - | ^ - -error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:684:28 - | -LL | #[suggestion_part(code())] - | ^ - -error: expected string literal - --> $DIR/subdiagnostic-derive.rs:693:30 - | -LL | #[suggestion_part(code = 3)] - | ^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:735:1 - | -LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] - | ^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:735:1 - | -LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] - | ^ - -error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:744:1 - | -LL | #[suggestion_hidden(no_crate_example, code = "")] - | ^ - | - = help: Use `#[suggestion(..., style = "hidden")]` instead - -error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:752:1 - | -LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] - | ^ - | - = help: Use `#[suggestion(..., style = "hidden")]` instead - -error: derive(Diagnostic): invalid suggestion style - --> $DIR/subdiagnostic-derive.rs:760:51 - | -LL | #[suggestion(no_crate_example, code = "", style = "foo")] - | ^^^^^ - | - = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` - -error: expected string literal - --> $DIR/subdiagnostic-derive.rs:768:51 - | -LL | #[suggestion(no_crate_example, code = "", style = 42)] - | ^^ - -error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:776:43 - | -LL | #[suggestion(no_crate_example, code = "", style)] - | ^^^^^ - -error: expected `=` - --> $DIR/subdiagnostic-derive.rs:784:48 - | -LL | #[suggestion(no_crate_example, code = "", style("foo"))] - | ^ - -error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:795:5 - | -LL | #[primary_span] - | ^ - | - = note: there must be exactly one primary span - = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead - -error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:792:1 - | -LL | #[suggestion(no_crate_example, code = "")] - | ^ - -error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:68:3 - | -LL | #[foo] - | ^^^ - -error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:144:3 - | -LL | #[foo] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:158:7 - | -LL | #[bar] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:170:7 - | -LL | #[bar = "..."] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:182:7 - | -LL | #[bar = 4] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:194:7 - | -LL | #[bar("...")] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:255:7 - | -LL | #[bar] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:266:7 - | -LL | #[bar = "..."] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:277:7 - | -LL | #[bar("...")] - | ^^^ - -error: aborting due to 82 previous errors - From 580c8d3c20ca3b363ece4ec34a9db1194bb9940d Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 7 Feb 2026 15:09:34 +0100 Subject: [PATCH 3375/3801] Update remaining session-diagnostics tests --- .../diagnostic-derive-doc-comment-field.rs | 7 +- ...diagnostic-derive-doc-comment-field.stderr | 8 +- .../diagnostic-derive-inline.rs | 1 - .../diagnostic-derive-inline.stderr | 174 +++++++++--------- .../subdiagnostic-derive-inline.rs | 1 - .../subdiagnostic-derive-inline.stderr | 174 +++++++++--------- 6 files changed, 180 insertions(+), 185 deletions(-) diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs index 4f08c5327c15..e63ab03cda47 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs @@ -14,7 +14,6 @@ #![crate_type = "lib"] extern crate rustc_errors; -extern crate rustc_fluent_macro; extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; @@ -24,12 +23,10 @@ use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; -rustc_fluent_macro::fluent_messages! { "./example.ftl" } - struct NotIntoDiagArg; #[derive(Diagnostic)] -#[diag(no_crate_example)] +#[diag("example message")] struct Test { #[primary_span] span: Span, @@ -39,7 +36,7 @@ struct Test { } #[derive(Subdiagnostic)] -#[label(no_crate_example)] +#[label("example message")] struct SubTest { #[primary_span] span: Span, diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr index 0b00e098f6d4..2d90b2a96b01 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `NotIntoDiagArg: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive-doc-comment-field.rs:37:10 + --> $DIR/diagnostic-derive-doc-comment-field.rs:34:10 | LL | #[derive(Diagnostic)] | ---------- required by a bound introduced by this call @@ -8,7 +8,7 @@ LL | arg: NotIntoDiagArg, | ^^^^^^^^^^^^^^ unsatisfied trait bound | help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg` - --> $DIR/diagnostic-derive-doc-comment-field.rs:29:1 + --> $DIR/diagnostic-derive-doc-comment-field.rs:26:1 | LL | struct NotIntoDiagArg; | ^^^^^^^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ note: required by a bound in `Diag::<'a, G>::arg` = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `NotIntoDiagArg: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive-doc-comment-field.rs:47:10 + --> $DIR/diagnostic-derive-doc-comment-field.rs:44:10 | LL | #[derive(Subdiagnostic)] | ------------- required by a bound introduced by this call @@ -30,7 +30,7 @@ LL | arg: NotIntoDiagArg, | ^^^^^^^^^^^^^^ unsatisfied trait bound | help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg` - --> $DIR/diagnostic-derive-doc-comment-field.rs:29:1 + --> $DIR/diagnostic-derive-doc-comment-field.rs:26:1 | LL | struct NotIntoDiagArg; | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs index babe3813e40b..1d2bfc66aaff 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs @@ -19,7 +19,6 @@ extern crate rustc_span; use rustc_span::symbol::Ident; use rustc_span::Span; -extern crate rustc_fluent_macro; extern crate rustc_macros; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr index 2ba307940280..71ed77804a6c 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr @@ -1,11 +1,11 @@ error: derive(Diagnostic): unsupported type attribute for diagnostic derive enum - --> $DIR/diagnostic-derive-inline.rs:45:1 + --> $DIR/diagnostic-derive-inline.rs:44:1 | LL | #[diag("this is an example message", code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:48:5 + --> $DIR/diagnostic-derive-inline.rs:47:5 | LL | Foo, | ^^^ @@ -13,7 +13,7 @@ LL | Foo, = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:50:5 + --> $DIR/diagnostic-derive-inline.rs:49:5 | LL | Bar, | ^^^ @@ -21,19 +21,19 @@ LL | Bar, = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: expected parentheses: #[diag(...)] - --> $DIR/diagnostic-derive-inline.rs:56:8 + --> $DIR/diagnostic-derive-inline.rs:55:8 | LL | #[diag = "E0123"] | ^ error: derive(Diagnostic): `#[nonsense(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:61:1 + --> $DIR/diagnostic-derive-inline.rs:60:1 | LL | #[nonsense("this is an example message", code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:61:1 + --> $DIR/diagnostic-derive-inline.rs:60:1 | LL | #[nonsense("this is an example message", code = E0123)] | ^ @@ -41,7 +41,7 @@ LL | #[nonsense("this is an example message", code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:68:1 + --> $DIR/diagnostic-derive-inline.rs:67:1 | LL | #[diag(code = E0123)] | ^ @@ -49,7 +49,7 @@ LL | #[diag(code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:73:1 + --> $DIR/diagnostic-derive-inline.rs:72:1 | LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] | ^ @@ -57,7 +57,7 @@ LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:78:1 + --> $DIR/diagnostic-derive-inline.rs:77:1 | LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] | ^ @@ -65,7 +65,7 @@ LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:83:1 + --> $DIR/diagnostic-derive-inline.rs:82:1 | LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] | ^ @@ -73,7 +73,7 @@ LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): unknown argument - --> $DIR/diagnostic-derive-inline.rs:88:52 + --> $DIR/diagnostic-derive-inline.rs:87:52 | LL | #[diag("this is an example message", code = E0123, slug = "foo")] | ^^^^ @@ -81,43 +81,43 @@ LL | #[diag("this is an example message", code = E0123, slug = "foo")] = note: only the `code` parameter is valid after the slug error: derive(Diagnostic): `#[suggestion = ...]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:95:5 + --> $DIR/diagnostic-derive-inline.rs:94:5 | LL | #[suggestion = "bar"] | ^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive-inline.rs:102:38 + --> $DIR/diagnostic-derive-inline.rs:101:38 | LL | #[diag("this is an example message", code = E0456)] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive-inline.rs:101:38 + --> $DIR/diagnostic-derive-inline.rs:100:38 | LL | #[diag("this is an example message", code = E0123)] | ^^^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive-inline.rs:107:52 + --> $DIR/diagnostic-derive-inline.rs:106:52 | LL | #[diag("this is an example message", code = E0123, code = E0456)] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive-inline.rs:107:38 + --> $DIR/diagnostic-derive-inline.rs:106:38 | LL | #[diag("this is an example message", code = E0123, code = E0456)] | ^^^^ error: derive(Diagnostic): diagnostic slug must be the first argument - --> $DIR/diagnostic-derive-inline.rs:112:38 + --> $DIR/diagnostic-derive-inline.rs:111:38 | LL | #[diag("this is an example message", no_crate::example, code = E0123)] | ^^^^^^^^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:117:1 + --> $DIR/diagnostic-derive-inline.rs:116:1 | LL | struct KindNotProvided {} | ^^^^^^ @@ -125,7 +125,7 @@ LL | struct KindNotProvided {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:120:1 + --> $DIR/diagnostic-derive-inline.rs:119:1 | LL | #[diag(code = E0123)] | ^ @@ -133,31 +133,31 @@ LL | #[diag(code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive-inline.rs:131:5 + --> $DIR/diagnostic-derive-inline.rs:130:5 | LL | #[primary_span] | ^ error: derive(Diagnostic): `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:139:5 + --> $DIR/diagnostic-derive-inline.rs:138:5 | LL | #[nonsense] | ^ error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive-inline.rs:156:5 + --> $DIR/diagnostic-derive-inline.rs:155:5 | LL | #[label("with a label")] | ^ error: derive(Diagnostic): `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive-inline.rs:164:46 + --> $DIR/diagnostic-derive-inline.rs:163:46 | LL | #[suggestion("with a suggestion", code = "{name}")] | ^^^^^^^^ error: invalid format string: expected `}` but string was terminated - --> $DIR/diagnostic-derive-inline.rs:169:10 + --> $DIR/diagnostic-derive-inline.rs:168:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ expected `}` in format string @@ -166,7 +166,7 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive-inline.rs:179:10 + --> $DIR/diagnostic-derive-inline.rs:178:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ unmatched `}` in format string @@ -175,19 +175,19 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive-inline.rs:199:5 + --> $DIR/diagnostic-derive-inline.rs:198:5 | LL | #[label("with a label")] | ^ error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive-inline.rs:218:5 + --> $DIR/diagnostic-derive-inline.rs:217:5 | LL | #[suggestion("with a suggestion")] | ^ error: derive(Diagnostic): invalid nested attribute - --> $DIR/diagnostic-derive-inline.rs:226:39 + --> $DIR/diagnostic-derive-inline.rs:225:39 | LL | #[suggestion("with a suggestion", nonsense = "bar")] | ^^^^^^^^ @@ -195,13 +195,13 @@ LL | #[suggestion("with a suggestion", nonsense = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive-inline.rs:226:5 + --> $DIR/diagnostic-derive-inline.rs:225:5 | LL | #[suggestion("with a suggestion", nonsense = "bar")] | ^ error: derive(Diagnostic): invalid nested attribute - --> $DIR/diagnostic-derive-inline.rs:235:39 + --> $DIR/diagnostic-derive-inline.rs:234:39 | LL | #[suggestion("with a suggestion", msg = "bar")] | ^^^ @@ -209,13 +209,13 @@ LL | #[suggestion("with a suggestion", msg = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive-inline.rs:235:5 + --> $DIR/diagnostic-derive-inline.rs:234:5 | LL | #[suggestion("with a suggestion", msg = "bar")] | ^ error: derive(Diagnostic): wrong field type for suggestion - --> $DIR/diagnostic-derive-inline.rs:258:5 + --> $DIR/diagnostic-derive-inline.rs:257:5 | LL | #[suggestion("with a suggestion", code = "This is suggested code")] | ^ @@ -223,79 +223,79 @@ LL | #[suggestion("with a suggestion", code = "This is suggested code")] = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive-inline.rs:274:24 + --> $DIR/diagnostic-derive-inline.rs:273:24 | LL | suggestion: (Span, Span, Applicability), | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive-inline.rs:274:18 + --> $DIR/diagnostic-derive-inline.rs:273:18 | LL | suggestion: (Span, Span, Applicability), | ^^^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive-inline.rs:282:33 + --> $DIR/diagnostic-derive-inline.rs:281:33 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive-inline.rs:282:18 + --> $DIR/diagnostic-derive-inline.rs:281:18 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ error: derive(Diagnostic): `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:289:5 + --> $DIR/diagnostic-derive-inline.rs:288:5 | LL | #[label = "bar"] | ^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive-inline.rs:390:5 + --> $DIR/diagnostic-derive-inline.rs:389:5 | LL | #[suggestion("with a suggestion", code = "...", applicability = "maybe-incorrect")] | ^ | note: previously specified here - --> $DIR/diagnostic-derive-inline.rs:392:24 + --> $DIR/diagnostic-derive-inline.rs:391:24 | LL | suggestion: (Span, Applicability), | ^^^^^^^^^^^^^ error: derive(Diagnostic): invalid applicability - --> $DIR/diagnostic-derive-inline.rs:398:69 + --> $DIR/diagnostic-derive-inline.rs:397:69 | LL | #[suggestion("with a suggestion", code = "...", applicability = "batman")] | ^^^^^^^^ error: derive(Diagnostic): the `#[help(...)]` attribute can only be applied to fields of type `Span`, `MultiSpan`, `bool` or `()` - --> $DIR/diagnostic-derive-inline.rs:461:5 + --> $DIR/diagnostic-derive-inline.rs:460:5 | LL | #[help("with a help")] | ^ error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/diagnostic-derive-inline.rs:470:29 + --> $DIR/diagnostic-derive-inline.rs:469:29 | LL | #[label("with a label", foo)] | ^^^ error: derive(Diagnostic): no nested attribute expected here - --> $DIR/diagnostic-derive-inline.rs:478:29 + --> $DIR/diagnostic-derive-inline.rs:477:29 | LL | #[label("with a label", foo = "...")] | ^^^ error: derive(Diagnostic): no nested attribute expected here - --> $DIR/diagnostic-derive-inline.rs:486:29 + --> $DIR/diagnostic-derive-inline.rs:485:29 | LL | #[label("with a label", foo("..."))] | ^^^ error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:498:5 + --> $DIR/diagnostic-derive-inline.rs:497:5 | LL | #[primary_span] | ^ @@ -303,13 +303,13 @@ LL | #[primary_span] = help: the `primary_span` field attribute is not valid for lint diagnostics error: derive(Diagnostic): `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:518:1 + --> $DIR/diagnostic-derive-inline.rs:517:1 | LL | #[error("this is an example message", code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:518:1 + --> $DIR/diagnostic-derive-inline.rs:517:1 | LL | #[error("this is an example message", code = E0123)] | ^ @@ -317,13 +317,13 @@ LL | #[error("this is an example message", code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:525:1 + --> $DIR/diagnostic-derive-inline.rs:524:1 | LL | #[warn_("this is an example message", code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:525:1 + --> $DIR/diagnostic-derive-inline.rs:524:1 | LL | #[warn_("this is an example message", code = E0123)] | ^ @@ -331,13 +331,13 @@ LL | #[warn_("this is an example message", code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:532:1 + --> $DIR/diagnostic-derive-inline.rs:531:1 | LL | #[lint("this is an example message", code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:532:1 + --> $DIR/diagnostic-derive-inline.rs:531:1 | LL | #[lint("this is an example message", code = E0123)] | ^ @@ -345,13 +345,13 @@ LL | #[lint("this is an example message", code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:539:1 + --> $DIR/diagnostic-derive-inline.rs:538:1 | LL | #[lint("this is an example message", code = E0123)] | ^ error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:539:1 + --> $DIR/diagnostic-derive-inline.rs:538:1 | LL | #[lint("this is an example message", code = E0123)] | ^ @@ -359,19 +359,19 @@ LL | #[lint("this is an example message", code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive-inline.rs:548:53 + --> $DIR/diagnostic-derive-inline.rs:547:53 | LL | #[suggestion("with a suggestion", code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive-inline.rs:548:39 + --> $DIR/diagnostic-derive-inline.rs:547:39 | LL | #[suggestion("with a suggestion", code = "...", code = ",,,")] | ^^^^ error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive-inline.rs:557:24 + --> $DIR/diagnostic-derive-inline.rs:556:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -379,7 +379,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive-inline.rs:565:17 + --> $DIR/diagnostic-derive-inline.rs:564:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -387,13 +387,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive-inline.rs:572:5 + --> $DIR/diagnostic-derive-inline.rs:571:5 | LL | #[suggestion("with a suggestion")] | ^ error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:579:1 + --> $DIR/diagnostic-derive-inline.rs:578:1 | LL | #[multipart_suggestion("with a suggestion")] | ^ @@ -401,7 +401,7 @@ LL | #[multipart_suggestion("with a suggestion")] = help: consider creating a `Subdiagnostic` instead error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:582:1 + --> $DIR/diagnostic-derive-inline.rs:581:1 | LL | #[multipart_suggestion()] | ^ @@ -409,7 +409,7 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:586:5 + --> $DIR/diagnostic-derive-inline.rs:585:5 | LL | #[multipart_suggestion("with a suggestion")] | ^ @@ -417,7 +417,7 @@ LL | #[multipart_suggestion("with a suggestion")] = help: consider creating a `Subdiagnostic` instead error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:594:1 + --> $DIR/diagnostic-derive-inline.rs:593:1 | LL | #[suggestion("with a suggestion", code = "...")] | ^ @@ -425,7 +425,7 @@ LL | #[suggestion("with a suggestion", code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: derive(Diagnostic): `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:603:1 + --> $DIR/diagnostic-derive-inline.rs:602:1 | LL | #[label] | ^ @@ -433,73 +433,73 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:637:5 + --> $DIR/diagnostic-derive-inline.rs:636:5 | LL | #[subdiagnostic(bad)] | ^ error: derive(Diagnostic): `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:645:5 + --> $DIR/diagnostic-derive-inline.rs:644:5 | LL | #[subdiagnostic = "bad"] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:653:5 + --> $DIR/diagnostic-derive-inline.rs:652:5 | LL | #[subdiagnostic(bad, bad)] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:661:5 + --> $DIR/diagnostic-derive-inline.rs:660:5 | LL | #[subdiagnostic("bad")] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:669:5 + --> $DIR/diagnostic-derive-inline.rs:668:5 | LL | #[subdiagnostic(eager)] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:677:5 + --> $DIR/diagnostic-derive-inline.rs:676:5 | LL | #[subdiagnostic(eager)] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:698:5 + --> $DIR/diagnostic-derive-inline.rs:697:5 | LL | #[subdiagnostic(eager)] | ^ error: derive(Diagnostic): expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive-inline.rs:729:44 + --> $DIR/diagnostic-derive-inline.rs:728:44 | LL | #[suggestion("with a suggestion", code())] | ^ error: derive(Diagnostic): `code(...)` must contain only string literals - --> $DIR/diagnostic-derive-inline.rs:737:44 + --> $DIR/diagnostic-derive-inline.rs:736:44 | LL | #[suggestion("with a suggestion", code(foo))] | ^^^ error: unexpected token, expected `)` - --> $DIR/diagnostic-derive-inline.rs:737:44 + --> $DIR/diagnostic-derive-inline.rs:736:44 | LL | #[suggestion("with a suggestion", code(foo))] | ^^^ error: expected string literal - --> $DIR/diagnostic-derive-inline.rs:746:46 + --> $DIR/diagnostic-derive-inline.rs:745:46 | LL | #[suggestion("with a suggestion", code = 3)] | ^ error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:761:5 + --> $DIR/diagnostic-derive-inline.rs:760:5 | LL | #[suggestion("with a suggestion", code = "")] | ^ @@ -509,7 +509,7 @@ LL | #[suggestion("with a suggestion", code = "")] = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` error: derive(Diagnostic): Variable `nosub` not found in diagnostic - --> $DIR/diagnostic-derive-inline.rs:773:8 + --> $DIR/diagnostic-derive-inline.rs:772:8 | LL | #[diag("does not exist: {$nosub}")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -517,19 +517,19 @@ LL | #[diag("does not exist: {$nosub}")] = help: Available fields: "sub" error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive-inline.rs:61:3 + --> $DIR/diagnostic-derive-inline.rs:60:3 | LL | #[nonsense("this is an example message", code = E0123)] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive-inline.rs:139:7 + --> $DIR/diagnostic-derive-inline.rs:138:7 | LL | #[nonsense] | ^^^^^^^^ error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive-inline.rs:518:3 + --> $DIR/diagnostic-derive-inline.rs:517:3 | LL | #[error("this is an example message", code = E0123)] | ^^^^^ @@ -541,7 +541,7 @@ LL | struct ErrorAttribute {} | error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive-inline.rs:525:3 + --> $DIR/diagnostic-derive-inline.rs:524:3 | LL | #[warn_("this is an example message", code = E0123)] | ^^^^^ @@ -553,7 +553,7 @@ LL + #[warn("this is an example message", code = E0123)] | error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive-inline.rs:532:3 + --> $DIR/diagnostic-derive-inline.rs:531:3 | LL | #[lint("this is an example message", code = E0123)] | ^^^^ @@ -565,7 +565,7 @@ LL + #[link("this is an example message", code = E0123)] | error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive-inline.rs:539:3 + --> $DIR/diagnostic-derive-inline.rs:538:3 | LL | #[lint("this is an example message", code = E0123)] | ^^^^ @@ -577,7 +577,7 @@ LL + #[link("this is an example message", code = E0123)] | error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive-inline.rs:579:3 + --> $DIR/diagnostic-derive-inline.rs:578:3 | LL | #[multipart_suggestion("with a suggestion")] | ^^^^^^^^^^^^^^^^^^^^ @@ -589,7 +589,7 @@ LL | struct MultipartSuggestion { | error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive-inline.rs:582:3 + --> $DIR/diagnostic-derive-inline.rs:581:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ @@ -601,7 +601,7 @@ LL | struct MultipartSuggestion { | error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive-inline.rs:586:7 + --> $DIR/diagnostic-derive-inline.rs:585:7 | LL | #[multipart_suggestion("with a suggestion")] | ^^^^^^^^^^^^^^^^^^^^ @@ -609,7 +609,7 @@ LL | #[multipart_suggestion("with a suggestion")] = note: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute error[E0277]: the trait bound `Hello: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive-inline.rs:330:12 + --> $DIR/diagnostic-derive-inline.rs:329:12 | LL | #[derive(Diagnostic)] | ---------- required by a bound introduced by this call @@ -618,7 +618,7 @@ LL | other: Hello, | ^^^^^ unsatisfied trait bound | help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `Hello` - --> $DIR/diagnostic-derive-inline.rs:42:1 + --> $DIR/diagnostic-derive-inline.rs:41:1 | LL | struct Hello {} | ^^^^^^^^^^^^ diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs index eaa681d40be5..079c2a74c4a1 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs @@ -12,7 +12,6 @@ #![crate_type = "lib"] extern crate rustc_errors; -extern crate rustc_fluent_macro; extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr index 11753b949bc7..8ff5ed00d0ba 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr @@ -1,143 +1,143 @@ error: derive(Diagnostic): label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive-inline.rs:50:1 + --> $DIR/subdiagnostic-derive-inline.rs:49:1 | LL | #[label("example message")] | ^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive-inline.rs:57:1 + --> $DIR/subdiagnostic-derive-inline.rs:56:1 | LL | #[label] | ^ error: derive(Diagnostic): `#[foo]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:66:1 + --> $DIR/subdiagnostic-derive-inline.rs:65:1 | LL | #[foo] | ^ error: derive(Diagnostic): `#[label = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:76:1 + --> $DIR/subdiagnostic-derive-inline.rs:75:1 | LL | #[label = "..."] | ^ error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive-inline.rs:85:9 + --> $DIR/subdiagnostic-derive-inline.rs:84:9 | LL | #[label(bug = "...")] | ^^^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive-inline.rs:85:1 + --> $DIR/subdiagnostic-derive-inline.rs:84:1 | LL | #[label(bug = "...")] | ^ error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive-inline.rs:95:9 + --> $DIR/subdiagnostic-derive-inline.rs:94:9 | LL | #[label(slug = 4)] | ^^^^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive-inline.rs:95:1 + --> $DIR/subdiagnostic-derive-inline.rs:94:1 | LL | #[label(slug = 4)] | ^ error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive-inline.rs:105:9 + --> $DIR/subdiagnostic-derive-inline.rs:104:9 | LL | #[label(slug("..."))] | ^^^^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive-inline.rs:105:1 + --> $DIR/subdiagnostic-derive-inline.rs:104:1 | LL | #[label(slug("..."))] | ^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive-inline.rs:115:1 + --> $DIR/subdiagnostic-derive-inline.rs:114:1 | LL | #[label()] | ^ error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive-inline.rs:124:28 + --> $DIR/subdiagnostic-derive-inline.rs:123:28 | LL | #[label("example message", code = "...")] | ^^^^ error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive-inline.rs:133:28 + --> $DIR/subdiagnostic-derive-inline.rs:132:28 | LL | #[label("example message", applicability = "machine-applicable")] | ^^^^^^^^^^^^^ error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive-inline.rs:142:1 + --> $DIR/subdiagnostic-derive-inline.rs:141:1 | LL | #[foo] | ^ error: derive(Diagnostic): `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:156:5 + --> $DIR/subdiagnostic-derive-inline.rs:155:5 | LL | #[bar] | ^ error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:168:5 + --> $DIR/subdiagnostic-derive-inline.rs:167:5 | LL | #[bar = "..."] | ^ error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:180:5 + --> $DIR/subdiagnostic-derive-inline.rs:179:5 | LL | #[bar = 4] | ^ error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:192:5 + --> $DIR/subdiagnostic-derive-inline.rs:191:5 | LL | #[bar("...")] | ^ error: derive(Diagnostic): no nested attribute expected here - --> $DIR/subdiagnostic-derive-inline.rs:204:13 + --> $DIR/subdiagnostic-derive-inline.rs:203:13 | LL | #[label(code = "...")] | ^^^^ error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive-inline.rs:204:5 + --> $DIR/subdiagnostic-derive-inline.rs:203:5 | LL | #[label(code = "...")] | ^ error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive-inline.rs:233:5 + --> $DIR/subdiagnostic-derive-inline.rs:232:5 | LL | #[primary_span] | ^ error: derive(Diagnostic): label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive-inline.rs:230:1 + --> $DIR/subdiagnostic-derive-inline.rs:229:1 | LL | #[label("example message")] | ^ error: derive(Diagnostic): `#[applicability]` is only valid on suggestions - --> $DIR/subdiagnostic-derive-inline.rs:243:5 + --> $DIR/subdiagnostic-derive-inline.rs:242:5 | LL | #[applicability] | ^ error: derive(Diagnostic): `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:253:5 + --> $DIR/subdiagnostic-derive-inline.rs:252:5 | LL | #[bar] | ^ @@ -145,13 +145,13 @@ LL | #[bar] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:264:5 + --> $DIR/subdiagnostic-derive-inline.rs:263:5 | LL | #[bar = "..."] | ^ error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:275:5 + --> $DIR/subdiagnostic-derive-inline.rs:274:5 | LL | #[bar("...")] | ^ @@ -159,7 +159,7 @@ LL | #[bar("...")] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: unexpected unsupported untagged union - --> $DIR/subdiagnostic-derive-inline.rs:291:1 + --> $DIR/subdiagnostic-derive-inline.rs:290:1 | LL | / union AC { LL | | @@ -169,97 +169,97 @@ LL | | } | |_^ error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive-inline.rs:306:28 + --> $DIR/subdiagnostic-derive-inline.rs:305:28 | LL | #[label("example message", no_crate::example)] | ^^^^^^^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive-inline.rs:319:5 + --> $DIR/subdiagnostic-derive-inline.rs:318:5 | LL | #[primary_span] | ^ | note: previously specified here - --> $DIR/subdiagnostic-derive-inline.rs:316:5 + --> $DIR/subdiagnostic-derive-inline.rs:315:5 | LL | #[primary_span] | ^ error: derive(Diagnostic): subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive-inline.rs:325:8 + --> $DIR/subdiagnostic-derive-inline.rs:324:8 | LL | struct AG { | ^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive-inline.rs:362:47 + --> $DIR/subdiagnostic-derive-inline.rs:361:47 | LL | #[suggestion("example message", code = "...", code = "...")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive-inline.rs:362:33 + --> $DIR/subdiagnostic-derive-inline.rs:361:33 | LL | #[suggestion("example message", code = "...", code = "...")] | ^^^^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive-inline.rs:380:5 + --> $DIR/subdiagnostic-derive-inline.rs:379:5 | LL | #[applicability] | ^ | note: previously specified here - --> $DIR/subdiagnostic-derive-inline.rs:377:5 + --> $DIR/subdiagnostic-derive-inline.rs:376:5 | LL | #[applicability] | ^ error: derive(Diagnostic): the `#[applicability]` attribute can only be applied to fields of type `Applicability` - --> $DIR/subdiagnostic-derive-inline.rs:390:5 + --> $DIR/subdiagnostic-derive-inline.rs:389:5 | LL | #[applicability] | ^ error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/subdiagnostic-derive-inline.rs:403:1 + --> $DIR/subdiagnostic-derive-inline.rs:402:1 | LL | #[suggestion("example message")] | ^ error: derive(Diagnostic): invalid applicability - --> $DIR/subdiagnostic-derive-inline.rs:413:63 + --> $DIR/subdiagnostic-derive-inline.rs:412:63 | LL | #[suggestion("example message", code = "...", applicability = "foo")] | ^^^^^ error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive-inline.rs:431:1 + --> $DIR/subdiagnostic-derive-inline.rs:430:1 | LL | #[suggestion("example message", code = "...")] | ^ error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive-inline.rs:445:1 + --> $DIR/subdiagnostic-derive-inline.rs:444:1 | LL | #[label] | ^ error: derive(Diagnostic): `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive-inline.rs:465:40 + --> $DIR/subdiagnostic-derive-inline.rs:464:40 | LL | #[suggestion("example message", code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: derive(Diagnostic): `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive-inline.rs:484:44 + --> $DIR/subdiagnostic-derive-inline.rs:483:44 | LL | #[suggestion("example message", code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: derive(Diagnostic): `#[suggestion_part]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:507:5 + --> $DIR/subdiagnostic-derive-inline.rs:506:5 | LL | #[suggestion_part] | ^ @@ -267,7 +267,7 @@ LL | #[suggestion_part] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead error: derive(Diagnostic): `#[suggestion_part(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:510:5 + --> $DIR/subdiagnostic-derive-inline.rs:509:5 | LL | #[suggestion_part(code = "...")] | ^ @@ -275,13 +275,13 @@ LL | #[suggestion_part(code = "...")] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive-inline.rs:504:1 + --> $DIR/subdiagnostic-derive-inline.rs:503:1 | LL | #[suggestion("example message", code = "...")] | ^ error: derive(Diagnostic): invalid nested attribute - --> $DIR/subdiagnostic-derive-inline.rs:519:43 + --> $DIR/subdiagnostic-derive-inline.rs:518:43 | LL | #[multipart_suggestion("example message", code = "...", applicability = "machine-applicable")] | ^^^^ @@ -289,25 +289,25 @@ LL | #[multipart_suggestion("example message", code = "...", applicability = "ma = help: only `style` and `applicability` are valid nested attributes error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive-inline.rs:519:1 + --> $DIR/subdiagnostic-derive-inline.rs:518:1 | LL | #[multipart_suggestion("example message", code = "...", applicability = "machine-applicable")] | ^ error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive-inline.rs:529:5 + --> $DIR/subdiagnostic-derive-inline.rs:528:5 | LL | #[suggestion_part] | ^ error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive-inline.rs:537:5 + --> $DIR/subdiagnostic-derive-inline.rs:536:5 | LL | #[suggestion_part()] | ^ error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:546:5 + --> $DIR/subdiagnostic-derive-inline.rs:545:5 | LL | #[primary_span] | ^ @@ -315,127 +315,127 @@ LL | #[primary_span] = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive-inline.rs:543:1 + --> $DIR/subdiagnostic-derive-inline.rs:542:1 | LL | #[multipart_suggestion("example message")] | ^ error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive-inline.rs:554:5 + --> $DIR/subdiagnostic-derive-inline.rs:553:5 | LL | #[suggestion_part] | ^ error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive-inline.rs:557:5 + --> $DIR/subdiagnostic-derive-inline.rs:556:5 | LL | #[suggestion_part()] | ^ error: derive(Diagnostic): `code` is the only valid nested attribute - --> $DIR/subdiagnostic-derive-inline.rs:560:23 + --> $DIR/subdiagnostic-derive-inline.rs:559:23 | LL | #[suggestion_part(foo = "bar")] | ^^^ error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive-inline.rs:564:5 + --> $DIR/subdiagnostic-derive-inline.rs:563:5 | LL | #[suggestion_part(code = "...")] | ^ error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive-inline.rs:567:5 + --> $DIR/subdiagnostic-derive-inline.rs:566:5 | LL | #[suggestion_part()] | ^ error: expected `,` - --> $DIR/subdiagnostic-derive-inline.rs:560:27 + --> $DIR/subdiagnostic-derive-inline.rs:559:27 | LL | #[suggestion_part(foo = "bar")] | ^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive-inline.rs:575:37 + --> $DIR/subdiagnostic-derive-inline.rs:574:37 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive-inline.rs:575:23 + --> $DIR/subdiagnostic-derive-inline.rs:574:23 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ error: derive(Diagnostic): `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."` - --> $DIR/subdiagnostic-derive-inline.rs:604:5 + --> $DIR/subdiagnostic-derive-inline.rs:603:5 | LL | #[applicability] | ^ error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive-inline.rs:652:28 + --> $DIR/subdiagnostic-derive-inline.rs:651:28 | LL | #[suggestion_part(code("foo"))] | ^^^^^ error: unexpected token, expected `)` - --> $DIR/subdiagnostic-derive-inline.rs:652:28 + --> $DIR/subdiagnostic-derive-inline.rs:651:28 | LL | #[suggestion_part(code("foo"))] | ^^^^^ error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive-inline.rs:662:28 + --> $DIR/subdiagnostic-derive-inline.rs:661:28 | LL | #[suggestion_part(code("foo", "bar"))] | ^^^^^ error: unexpected token, expected `)` - --> $DIR/subdiagnostic-derive-inline.rs:662:28 + --> $DIR/subdiagnostic-derive-inline.rs:661:28 | LL | #[suggestion_part(code("foo", "bar"))] | ^^^^^ error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive-inline.rs:672:28 + --> $DIR/subdiagnostic-derive-inline.rs:671:28 | LL | #[suggestion_part(code(3))] | ^ error: unexpected token, expected `)` - --> $DIR/subdiagnostic-derive-inline.rs:672:28 + --> $DIR/subdiagnostic-derive-inline.rs:671:28 | LL | #[suggestion_part(code(3))] | ^ error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive-inline.rs:682:28 + --> $DIR/subdiagnostic-derive-inline.rs:681:28 | LL | #[suggestion_part(code())] | ^ error: expected string literal - --> $DIR/subdiagnostic-derive-inline.rs:691:30 + --> $DIR/subdiagnostic-derive-inline.rs:690:30 | LL | #[suggestion_part(code = 3)] | ^ error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive-inline.rs:733:1 + --> $DIR/subdiagnostic-derive-inline.rs:732:1 | LL | #[suggestion("example message", code = "", style = "hidden", style = "normal")] | ^ | note: previously specified here - --> $DIR/subdiagnostic-derive-inline.rs:733:1 + --> $DIR/subdiagnostic-derive-inline.rs:732:1 | LL | #[suggestion("example message", code = "", style = "hidden", style = "normal")] | ^ error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:742:1 + --> $DIR/subdiagnostic-derive-inline.rs:741:1 | LL | #[suggestion_hidden("example message", code = "")] | ^ @@ -443,7 +443,7 @@ LL | #[suggestion_hidden("example message", code = "")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:750:1 + --> $DIR/subdiagnostic-derive-inline.rs:749:1 | LL | #[suggestion_hidden("example message", code = "", style = "normal")] | ^ @@ -451,7 +451,7 @@ LL | #[suggestion_hidden("example message", code = "", style = "normal")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: derive(Diagnostic): invalid suggestion style - --> $DIR/subdiagnostic-derive-inline.rs:758:52 + --> $DIR/subdiagnostic-derive-inline.rs:757:52 | LL | #[suggestion("example message", code = "", style = "foo")] | ^^^^^ @@ -459,25 +459,25 @@ LL | #[suggestion("example message", code = "", style = "foo")] = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` error: expected string literal - --> $DIR/subdiagnostic-derive-inline.rs:766:52 + --> $DIR/subdiagnostic-derive-inline.rs:765:52 | LL | #[suggestion("example message", code = "", style = 42)] | ^^ error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive-inline.rs:774:44 + --> $DIR/subdiagnostic-derive-inline.rs:773:44 | LL | #[suggestion("example message", code = "", style)] | ^^^^^ error: expected `=` - --> $DIR/subdiagnostic-derive-inline.rs:782:49 + --> $DIR/subdiagnostic-derive-inline.rs:781:49 | LL | #[suggestion("example message", code = "", style("foo"))] | ^ error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive-inline.rs:793:5 + --> $DIR/subdiagnostic-derive-inline.rs:792:5 | LL | #[primary_span] | ^ @@ -486,61 +486,61 @@ LL | #[primary_span] = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive-inline.rs:790:1 + --> $DIR/subdiagnostic-derive-inline.rs:789:1 | LL | #[suggestion("example message", code = "")] | ^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive-inline.rs:66:3 + --> $DIR/subdiagnostic-derive-inline.rs:65:3 | LL | #[foo] | ^^^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive-inline.rs:142:3 + --> $DIR/subdiagnostic-derive-inline.rs:141:3 | LL | #[foo] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive-inline.rs:156:7 + --> $DIR/subdiagnostic-derive-inline.rs:155:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive-inline.rs:168:7 + --> $DIR/subdiagnostic-derive-inline.rs:167:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive-inline.rs:180:7 + --> $DIR/subdiagnostic-derive-inline.rs:179:7 | LL | #[bar = 4] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive-inline.rs:192:7 + --> $DIR/subdiagnostic-derive-inline.rs:191:7 | LL | #[bar("...")] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive-inline.rs:253:7 + --> $DIR/subdiagnostic-derive-inline.rs:252:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive-inline.rs:264:7 + --> $DIR/subdiagnostic-derive-inline.rs:263:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive-inline.rs:275:7 + --> $DIR/subdiagnostic-derive-inline.rs:274:7 | LL | #[bar("...")] | ^^^ From 236dac8d0e41ae9d4e31908c9a0a3fdf2789f5f6 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sat, 7 Feb 2026 14:02:33 -0500 Subject: [PATCH 3376/3801] fix: remove unnecessary trailing commas in format strings This PR makes the new comma-removing lint PR less noisy, allowing it focus only on the new functionality --- clippy_dev/src/new_lint.rs | 4 ++-- clippy_lints/src/cargo/lint_groups_priority.rs | 2 +- clippy_lints/src/casts/cast_possible_truncation.rs | 2 +- clippy_lints/src/doc/doc_suspicious_footnotes.rs | 2 +- clippy_lints/src/formatting.rs | 2 +- clippy_lints/src/implicit_hasher.rs | 4 ++-- clippy_lints/src/matches/manual_unwrap_or.rs | 2 +- clippy_lints/src/matches/match_like_matches.rs | 2 +- clippy_lints/src/methods/bytes_nth.rs | 2 +- clippy_lints/src/methods/into_iter_on_ref.rs | 2 +- clippy_lints/src/methods/manual_try_fold.rs | 2 +- clippy_lints/src/methods/unit_hash.rs | 2 +- clippy_lints/src/missing_asserts_for_indexing.rs | 6 +++--- clippy_lints/src/missing_enforced_import_rename.rs | 2 +- clippy_lints/src/ptr/cmp_null.rs | 2 +- clippy_lints/src/toplevel_ref_arg.rs | 2 +- clippy_lints/src/zero_div_zero.rs | 2 +- clippy_lints/src/zero_repeat_side_effects.rs | 2 +- rustc_tools_util/src/lib.rs | 2 +- 19 files changed, 23 insertions(+), 23 deletions(-) diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index 0b6d702d7721..72f281ca4d9d 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -167,9 +167,9 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> { let camel_name = to_camel_case(lint.name); let new_lint = if enable_msrv { - format!("Box::new(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(conf))),\n ",) + format!("Box::new(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(conf))),\n ") } else { - format!("Box::new(|{ctor_arg}| Box::new({module_name}::{camel_name})),\n ",) + format!("Box::new(|{ctor_arg}| Box::new({module_name}::{camel_name})),\n ") }; lib_rs.insert_str(comment_start, &new_lint); diff --git a/clippy_lints/src/cargo/lint_groups_priority.rs b/clippy_lints/src/cargo/lint_groups_priority.rs index 14c5e22fb9cd..f937f065d6e0 100644 --- a/clippy_lints/src/cargo/lint_groups_priority.rs +++ b/clippy_lints/src/cargo/lint_groups_priority.rs @@ -100,7 +100,7 @@ fn check_table(cx: &LateContext<'_>, table: &DeTable<'_>, known_groups: &FxHashS "to have lints override the group set `{}` to a lower priority", group.as_ref() ), - format!("{{ level = {:?}, priority = {low_priority} }}", group_config.level,), + format!("{{ level = {:?}, priority = {low_priority} }}", group_config.level), Applicability::MaybeIncorrect, ); }, diff --git a/clippy_lints/src/casts/cast_possible_truncation.rs b/clippy_lints/src/casts/cast_possible_truncation.rs index 2eebe8492327..0591afaa6c58 100644 --- a/clippy_lints/src/casts/cast_possible_truncation.rs +++ b/clippy_lints/src/casts/cast_possible_truncation.rs @@ -117,7 +117,7 @@ pub(super) fn check( return; } - format!("casting `{cast_from}` to `{cast_to}` may truncate the value{suffix}",) + format!("casting `{cast_from}` to `{cast_to}` may truncate the value{suffix}") }, (ty::Adt(def, _), Some(to_nbits)) if def.is_enum() => { diff --git a/clippy_lints/src/doc/doc_suspicious_footnotes.rs b/clippy_lints/src/doc/doc_suspicious_footnotes.rs index deca29a1885f..dfa6c9637864 100644 --- a/clippy_lints/src/doc/doc_suspicious_footnotes.rs +++ b/clippy_lints/src/doc/doc_suspicious_footnotes.rs @@ -91,7 +91,7 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range, fragments: &F diag.span_suggestion_verbose( this_fragment.span.shrink_to_hi(), "add footnote definition", - format!("\n\n{label}: ", label = &doc[start..end],), + format!("\n\n{label}: ", label = &doc[start..end]), Applicability::HasPlaceholders, ); } else { diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 3b9c70e23e20..7a64d3135fa5 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -337,7 +337,7 @@ fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) { else_span, format!("this looks like {looks_like} but the `else` is missing"), None, - format!("to remove this lint, add the missing `else` or add a new line before {next_thing}",), + format!("to remove this lint, add the missing `else` or add a new line before {next_thing}"), ); } } diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 9dc74a157cbf..70176c62772b 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { ), ( target.span(), - format!("{}<{}, S>", target.type_name(), target.type_arguments(),), + format!("{}<{}, S>", target.type_name(), target.type_arguments()), ), ]; suggestions.extend(vis.suggestions); @@ -352,7 +352,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> { ); self.suggestions.insert( e.span, - format!("{container_name}::with_capacity_and_hasher({arg_snippet}, Default::default())",), + format!("{container_name}::with_capacity_and_hasher({arg_snippet}, Default::default())"), ); }, _ => {}, diff --git a/clippy_lints/src/matches/manual_unwrap_or.rs b/clippy_lints/src/matches/manual_unwrap_or.rs index abbc43d8e9b0..421c6064284d 100644 --- a/clippy_lints/src/matches/manual_unwrap_or.rs +++ b/clippy_lints/src/matches/manual_unwrap_or.rs @@ -173,7 +173,7 @@ fn handle( expr.span, format!("this pattern reimplements `{ty_name}::unwrap_or`"), "replace with", - format!("{suggestion}.unwrap_or({reindented_or_body})",), + format!("{suggestion}.unwrap_or({reindented_or_body})"), app, ); } diff --git a/clippy_lints/src/matches/match_like_matches.rs b/clippy_lints/src/matches/match_like_matches.rs index c26b2dbde7fc..347560b14eea 100644 --- a/clippy_lints/src/matches/match_like_matches.rs +++ b/clippy_lints/src/matches/match_like_matches.rs @@ -187,7 +187,7 @@ pub(super) fn check_match<'tcx>( diag.span_suggestion_verbose( e.span, "use `matches!` directly", - format!("{}matches!({snippet}, {pat_and_guard})", if b0 { "" } else { "!" },), + format!("{}matches!({snippet}, {pat_and_guard})", if b0 { "" } else { "!" }), applicability, ); }, diff --git a/clippy_lints/src/methods/bytes_nth.rs b/clippy_lints/src/methods/bytes_nth.rs index 40d521d61c11..0a3ea3005e72 100644 --- a/clippy_lints/src/methods/bytes_nth.rs +++ b/clippy_lints/src/methods/bytes_nth.rs @@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E parent.span, format!("called `.bytes().nth().unwrap()` on a `{caller_type}`"), "try", - format!("{receiver}.as_bytes()[{n}]",), + format!("{receiver}.as_bytes()[{n}]"), applicability, ); } else { diff --git a/clippy_lints/src/methods/into_iter_on_ref.rs b/clippy_lints/src/methods/into_iter_on_ref.rs index c4b116af4871..5a062732721e 100644 --- a/clippy_lints/src/methods/into_iter_on_ref.rs +++ b/clippy_lints/src/methods/into_iter_on_ref.rs @@ -20,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_span: Spa cx, INTO_ITER_ON_REF, method_span, - format!("this `.into_iter()` call is equivalent to `.{method_name}()` and will not consume the `{kind}`",), + format!("this `.into_iter()` call is equivalent to `.{method_name}()` and will not consume the `{kind}`"), "call directly", method_name.to_string(), Applicability::MachineApplicable, diff --git a/clippy_lints/src/methods/manual_try_fold.rs b/clippy_lints/src/methods/manual_try_fold.rs index f2e127bedde5..5f5944d5d423 100644 --- a/clippy_lints/src/methods/manual_try_fold.rs +++ b/clippy_lints/src/methods/manual_try_fold.rs @@ -47,7 +47,7 @@ pub(super) fn check<'tcx>( fold_span, "usage of `Iterator::fold` on a type that implements `Try`", "use `try_fold` instead", - format!("try_fold({init_snip}, {args_snip} ...)",), + format!("try_fold({init_snip}, {args_snip} ...)"), Applicability::HasPlaceholders, ); } diff --git a/clippy_lints/src/methods/unit_hash.rs b/clippy_lints/src/methods/unit_hash.rs index 9defd5626eb4..fb447a99abdc 100644 --- a/clippy_lints/src/methods/unit_hash.rs +++ b/clippy_lints/src/methods/unit_hash.rs @@ -19,7 +19,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &' diag.span_suggestion( expr.span, "remove the call to `hash` or consider using", - format!("0_u8.hash({})", snippet(cx, arg.span, ".."),), + format!("0_u8.hash({})", snippet(cx, arg.span, "..")), Applicability::MaybeIncorrect, ); diag.note("the implementation of `Hash` for `()` is a no-op"); diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index 87ee164a1760..651382fb4bfe 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -364,15 +364,15 @@ fn report_indexes(cx: &LateContext<'_>, map: UnindexMap> // `v.len() < 5` and `v.len() <= 5` does nothing in terms of bounds checks. // The user probably meant `v.len() > 5` LengthComparison::LengthLessThanInt | LengthComparison::LengthLessThanOrEqualInt => { - Some(format!("assert!({slice_str}.len() > {highest_index})",)) + Some(format!("assert!({slice_str}.len() > {highest_index})")) }, // `5 < v.len()` == `v.len() > 5` LengthComparison::IntLessThanLength if asserted_len < highest_index => { - Some(format!("assert!({slice_str}.len() > {highest_index})",)) + Some(format!("assert!({slice_str}.len() > {highest_index})")) }, // `5 <= v.len() == `v.len() >= 5` LengthComparison::IntLessThanOrEqualLength if asserted_len <= highest_index => { - Some(format!("assert!({slice_str}.len() > {highest_index})",)) + Some(format!("assert!({slice_str}.len() > {highest_index})")) }, // `highest_index` here is rather a length, so we need to add 1 to it LengthComparison::LengthEqualInt if asserted_len < highest_index + 1 => match macro_call { diff --git a/clippy_lints/src/missing_enforced_import_rename.rs b/clippy_lints/src/missing_enforced_import_rename.rs index 5dd38cf059c2..1f9652a2bd38 100644 --- a/clippy_lints/src/missing_enforced_import_rename.rs +++ b/clippy_lints/src/missing_enforced_import_rename.rs @@ -97,7 +97,7 @@ impl LateLintPass<'_> for ImportRename { span_without_semi, "this import should be renamed", "try", - format!("{import} as {name}",), + format!("{import} as {name}"), Applicability::MachineApplicable, ); } diff --git a/clippy_lints/src/ptr/cmp_null.rs b/clippy_lints/src/ptr/cmp_null.rs index f2d1c855eddd..5e1c62316b7d 100644 --- a/clippy_lints/src/ptr/cmp_null.rs +++ b/clippy_lints/src/ptr/cmp_null.rs @@ -32,7 +32,7 @@ pub(super) fn check<'tcx>( expr.span, "comparing with null is better expressed by the `.is_null()` method", "try", - format!("{invert}{non_null_path_snippet}.is_null()",), + format!("{invert}{non_null_path_snippet}.is_null()"), applicability, ); true diff --git a/clippy_lints/src/toplevel_ref_arg.rs b/clippy_lints/src/toplevel_ref_arg.rs index 250c277ab5e1..bce2ede6589b 100644 --- a/clippy_lints/src/toplevel_ref_arg.rs +++ b/clippy_lints/src/toplevel_ref_arg.rs @@ -109,7 +109,7 @@ impl<'tcx> LateLintPass<'tcx> for ToplevelRefArg { diag.span_suggestion( stmt.span, "try", - format!("let {name}{tyopt} = {initref};", name = snippet(cx, name.span, ".."),), + format!("let {name}{tyopt} = {initref};", name = snippet(cx, name.span, "..")), app, ); }, diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs index bb0cab3a3075..e44c4dc9776e 100644 --- a/clippy_lints/src/zero_div_zero.rs +++ b/clippy_lints/src/zero_div_zero.rs @@ -56,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for ZeroDiv { expr.span, "constant division of `0.0` with `0.0` will always result in NaN", None, - format!("consider using `{float_type}::NAN` if you would like a constant representing NaN",), + format!("consider using `{float_type}::NAN` if you would like a constant representing NaN"), ); } } diff --git a/clippy_lints/src/zero_repeat_side_effects.rs b/clippy_lints/src/zero_repeat_side_effects.rs index 95085161c09c..cb254cc15629 100644 --- a/clippy_lints/src/zero_repeat_side_effects.rs +++ b/clippy_lints/src/zero_repeat_side_effects.rs @@ -168,7 +168,7 @@ fn assign_expr_suggestion( let indent = snippet_indent(cx, outer_expr.span).unwrap_or_default(); let var_name = snippet(cx, assign_expr_span.source_callsite(), ".."); if needs_curly { - format!("{{\n {indent}{inner_expr};\n {indent}{var_name} = {vec_str}[] as {return_type}\n{indent}}}",) + format!("{{\n {indent}{inner_expr};\n {indent}{var_name} = {vec_str}[] as {return_type}\n{indent}}}") } else { format!("{inner_expr};\n{indent}{var_name} = {vec_str}[] as {return_type}") } diff --git a/rustc_tools_util/src/lib.rs b/rustc_tools_util/src/lib.rs index 194ed84d04c2..3b7d2d4085d9 100644 --- a/rustc_tools_util/src/lib.rs +++ b/rustc_tools_util/src/lib.rs @@ -91,7 +91,7 @@ impl std::fmt::Debug for VersionInfo { self.crate_name, self.major, self.minor, self.patch, )?; if let Some(ref commit_hash) = self.commit_hash { - write!(f, ", commit_hash: \"{}\"", commit_hash.trim(),)?; + write!(f, ", commit_hash: \"{}\"", commit_hash.trim())?; } if let Some(ref commit_date) = self.commit_date { write!(f, ", commit_date: \"{}\"", commit_date.trim())?; From d53133eec22e1e7fc6c25dc595708500f36e9ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 7 Feb 2026 22:03:40 +0100 Subject: [PATCH 3377/3801] Remove rustdoc adhoc group --- triagebot.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 0ee3d0853034..4a4054391ce7 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1488,11 +1488,6 @@ infra-ci = [ "@jdno", "@jieyouxu", ] -rustdoc = [ - "@GuillaumeGomez", - "@notriddle", - "@fmease", -] docs = [ "@ehuss", "@GuillaumeGomez", From d5c6866dbadbf4c410faf6ab8b01c0f88631e171 Mon Sep 17 00:00:00 2001 From: ia0 Date: Sat, 7 Feb 2026 22:06:55 +0100 Subject: [PATCH 3378/3801] improve tests --- src/tools/rustfmt/tests/source/try_block.rs | 1 + src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs | 5 +++++ src/tools/rustfmt/tests/target/try_block.rs | 1 + src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs | 5 +++++ 4 files changed, 12 insertions(+) diff --git a/src/tools/rustfmt/tests/source/try_block.rs b/src/tools/rustfmt/tests/source/try_block.rs index 2e8d61f7e66a..e324a1331758 100644 --- a/src/tools/rustfmt/tests/source/try_block.rs +++ b/src/tools/rustfmt/tests/source/try_block.rs @@ -1,4 +1,5 @@ // rustfmt-edition: 2018 +#![feature(try_blocks)] fn main() -> Result<(), !> { let _x: Option<_> = try { diff --git a/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs b/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs index bae0060374d8..7a1135cfbc76 100644 --- a/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs +++ b/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs @@ -1,4 +1,5 @@ // rustfmt-edition: 2018 +#![feature(try_blocks_heterogeneous)] fn main() -> Result<(), !> { let _x = try bikeshed Option<_> { @@ -24,6 +25,10 @@ fn baz() -> Option { 6 }; // comment + let x = try /* Invisible comment */ bikeshed Option<()> {}; + let x = try bikeshed /* Invisible comment */ Option<()> {}; + let x = try bikeshed Option<()> /* Invisible comment */ {}; + let x = try bikeshed Option { baz()?; baz()?; baz()?; 7 }; let x = try bikeshed Foo { 1 + 1 + 1 }; diff --git a/src/tools/rustfmt/tests/target/try_block.rs b/src/tools/rustfmt/tests/target/try_block.rs index 19a3f3e14876..61da123b735d 100644 --- a/src/tools/rustfmt/tests/target/try_block.rs +++ b/src/tools/rustfmt/tests/target/try_block.rs @@ -1,4 +1,5 @@ // rustfmt-edition: 2018 +#![feature(try_blocks)] fn main() -> Result<(), !> { let _x: Option<_> = try { 4 }; diff --git a/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs b/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs index 6f910ed5d051..018d53ed35e4 100644 --- a/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs +++ b/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs @@ -1,4 +1,5 @@ // rustfmt-edition: 2018 +#![feature(try_blocks_heterogeneous)] fn main() -> Result<(), !> { let _x = try bikeshed Option<_> { 4 }; @@ -18,6 +19,10 @@ fn baz() -> Option { let y = try bikeshed Option { 6 }; // comment + let x = try /* Invisible comment */ bikeshed Option<()> {}; + let x = try bikeshed /* Invisible comment */ Option<()> {}; + let x = try bikeshed Option<()> /* Invisible comment */ {}; + let x = try bikeshed Option { baz()?; baz()?; From d0b3a0bdc02924cdd28e37f6209ddea0b6bd4727 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Mon, 2 Feb 2026 22:01:10 -0500 Subject: [PATCH 3379/3801] Add some conversion trait impls - `impl From<[MaybeUninit; N]> for MaybeUninit<[T; N]>` - `impl AsRef<[MaybeUninit; N]> for MaybeUninit<[T; N]>` - `impl AsRef<[MaybeUninit]> for MaybeUninit<[T; N]>` - `impl AsMut<[MaybeUninit; N]> for MaybeUninit<[T; N]>` - `impl AsMut<[MaybeUninit]> for MaybeUninit<[T; N]>` - `impl From> for [MaybeUninit; N]` - `impl AsRef<[Cell; N]> for Cell<[T; N]>` - `impl AsRef<[Cell]> for Cell<[T; N]>` - `impl AsRef<[Cell]> for Cell<[T]>` --- library/core/src/cell.rs | 24 +++++++++ library/core/src/mem/maybe_uninit.rs | 50 +++++++++++++++++++ .../issue-71394-no-from-impl.stderr | 2 +- 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 661ea4ab6a27..a9e7c49515c7 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -689,6 +689,30 @@ impl, U> CoerceUnsized> for Cell {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl, U> DispatchFromDyn> for Cell {} +#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")] +impl AsRef<[Cell; N]> for Cell<[T; N]> { + #[inline] + fn as_ref(&self) -> &[Cell; N] { + self.as_array_of_cells() + } +} + +#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")] +impl AsRef<[Cell]> for Cell<[T; N]> { + #[inline] + fn as_ref(&self) -> &[Cell] { + &*self.as_array_of_cells() + } +} + +#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")] +impl AsRef<[Cell]> for Cell<[T]> { + #[inline] + fn as_ref(&self) -> &[Cell] { + self.as_slice_of_cells() + } +} + impl Cell<[T]> { /// Returns a `&[Cell]` from a `&Cell<[T]>` /// diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 320eb97f83a4..594147720193 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -1532,6 +1532,56 @@ impl MaybeUninit<[T; N]> { } } +#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")] +impl From<[MaybeUninit; N]> for MaybeUninit<[T; N]> { + #[inline] + fn from(arr: [MaybeUninit; N]) -> Self { + arr.transpose() + } +} + +#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")] +impl AsRef<[MaybeUninit; N]> for MaybeUninit<[T; N]> { + #[inline] + fn as_ref(&self) -> &[MaybeUninit; N] { + // SAFETY: T and MaybeUninit have the same layout + unsafe { &*ptr::from_ref(self).cast() } + } +} + +#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")] +impl AsRef<[MaybeUninit]> for MaybeUninit<[T; N]> { + #[inline] + fn as_ref(&self) -> &[MaybeUninit] { + &*AsRef::<[MaybeUninit; N]>::as_ref(self) + } +} + +#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")] +impl AsMut<[MaybeUninit; N]> for MaybeUninit<[T; N]> { + #[inline] + fn as_mut(&mut self) -> &mut [MaybeUninit; N] { + // SAFETY: T and MaybeUninit have the same layout + unsafe { &mut *ptr::from_mut(self).cast() } + } +} + +#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")] +impl AsMut<[MaybeUninit]> for MaybeUninit<[T; N]> { + #[inline] + fn as_mut(&mut self) -> &mut [MaybeUninit] { + &mut *AsMut::<[MaybeUninit; N]>::as_mut(self) + } +} + +#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")] +impl From> for [MaybeUninit; N] { + #[inline] + fn from(arr: MaybeUninit<[T; N]>) -> Self { + arr.transpose() + } +} + impl [MaybeUninit; N] { /// Transposes a `[MaybeUninit; N]` into a `MaybeUninit<[T; N]>`. /// diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr index 9e068c311ae0..b8a240f7f07c 100644 --- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr +++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr @@ -13,7 +13,7 @@ LL | let _: &[i8] = data.into(); `[T; 6]` implements `From<(T, T, T, T, T, T)>` `[T; 7]` implements `From<(T, T, T, T, T, T, T)>` `[T; 8]` implements `From<(T, T, T, T, T, T, T, T)>` - and 6 others + and 7 others = note: required for `&[u8]` to implement `Into<&[i8]>` error: aborting due to 1 previous error From 6de0591c0b62f23ebe8413de465540771ed80074 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Sat, 7 Feb 2026 17:34:39 -0800 Subject: [PATCH 3380/3801] Split ol mapper into more specific to/kernel/from mapper and move init_all_rtls into global ctor --- .../src/builder/gpu_offload.rs | 88 ++++++++++++------- .../codegen-llvm/gpu_offload/control_flow.rs | 4 +- tests/codegen-llvm/gpu_offload/gpu_host.rs | 53 ++++++----- 3 files changed, 92 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index 16ab18a568e8..a60e2d1f0ab0 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -1,12 +1,13 @@ use std::ffi::CString; +use bitflags::Flags; use llvm::Linkage::*; use rustc_abi::Align; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods}; use rustc_middle::bug; -use rustc_middle::ty::offload_meta::OffloadMetadata; +use rustc_middle::ty::offload_meta::{MappingFlags, OffloadMetadata}; use crate::builder::Builder; use crate::common::CodegenCx; @@ -28,10 +29,6 @@ pub(crate) struct OffloadGlobals<'ll> { pub mapper_fn_ty: &'ll llvm::Type, pub ident_t_global: &'ll llvm::Value, - - // FIXME(offload): Drop this, once we fully automated our offload compilation pipeline, since - // LLVM will initialize them for us if it sees gpu kernels being registered. - pub init_rtls: &'ll llvm::Value, } impl<'ll> OffloadGlobals<'ll> { @@ -42,9 +39,6 @@ impl<'ll> OffloadGlobals<'ll> { let (begin_mapper, _, end_mapper, mapper_fn_ty) = gen_tgt_data_mappers(cx); let ident_t_global = generate_at_one(cx); - let init_ty = cx.type_func(&[], cx.type_void()); - let init_rtls = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); - // We want LLVM's openmp-opt pass to pick up and optimize this module, since it covers both // openmp and offload optimizations. llvm::add_module_flag_u32(cx.llmod(), llvm::ModuleFlagMergeBehavior::Max, "openmp", 51); @@ -58,7 +52,6 @@ impl<'ll> OffloadGlobals<'ll> { end_mapper, mapper_fn_ty, ident_t_global, - init_rtls, } } } @@ -91,6 +84,11 @@ pub(crate) fn register_offload<'ll>(cx: &CodegenCx<'ll, '_>) { let atexit = cx.type_func(&[cx.type_ptr()], cx.type_i32()); let atexit_fn = declare_offload_fn(cx, "atexit", atexit); + // FIXME(offload): Drop this, once we fully automated our offload compilation pipeline, since + // LLVM will initialize them for us if it sees gpu kernels being registered. + let init_ty = cx.type_func(&[], cx.type_void()); + let init_rtls = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); + let desc_ty = cx.type_func(&[], cx.type_void()); let reg_name = ".omp_offloading.descriptor_reg"; let unreg_name = ".omp_offloading.descriptor_unreg"; @@ -104,12 +102,14 @@ pub(crate) fn register_offload<'ll>(cx: &CodegenCx<'ll, '_>) { // define internal void @.omp_offloading.descriptor_reg() section ".text.startup" { // entry: // call void @__tgt_register_lib(ptr @.omp_offloading.descriptor) + // call void @__tgt_init_all_rtls() // %0 = call i32 @atexit(ptr @.omp_offloading.descriptor_unreg) // ret void // } let bb = Builder::append_block(cx, desc_reg_fn, "entry"); let mut a = Builder::build(cx, bb); a.call(reg_lib_decl, None, None, register_lib, &[omp_descriptor], None, None); + a.call(init_ty, None, None, init_rtls, &[], None, None); a.call(atexit, None, None, atexit_fn, &[desc_unreg_fn], None, None); a.ret_void(); @@ -345,7 +345,9 @@ impl KernelArgsTy { #[derive(Copy, Clone)] pub(crate) struct OffloadKernelGlobals<'ll> { pub offload_sizes: &'ll llvm::Value, - pub memtransfer_types: &'ll llvm::Value, + pub memtransfer_begin: &'ll llvm::Value, + pub memtransfer_kernel: &'ll llvm::Value, + pub memtransfer_end: &'ll llvm::Value, pub region_id: &'ll llvm::Value, } @@ -423,18 +425,38 @@ pub(crate) fn gen_define_handling<'ll>( let offload_entry_ty = offload_globals.offload_entry_ty; - // FIXME(Sa4dUs): add `OMP_MAP_TARGET_PARAM = 0x20` only if necessary let (sizes, transfer): (Vec<_>, Vec<_>) = - metadata.iter().map(|m| (m.payload_size, m.mode.bits() | 0x20)).unzip(); + metadata.iter().map(|m| (m.payload_size, m.mode)).unzip(); + // Our begin mapper should only see simplified information about which args have to be + // transferred to the device, the end mapper only about which args should be transferred back. + // Any information beyond that makes it harder for LLVM's opt pass to evaluate whether it can + // safely move (=optimize) the LLVM-IR location of this data transfer. Only the mapping types + // mentioned below are handled, so make sure that we don't generate any other ones. + let handled_mappings = MappingFlags::TO + | MappingFlags::FROM + | MappingFlags::TARGET_PARAM + | MappingFlags::LITERAL + | MappingFlags::IMPLICIT; + for arg in &transfer { + debug_assert!(!arg.contains_unknown_bits()); + debug_assert!(handled_mappings.contains(*arg)); + } + + let valid_begin_mappings = MappingFlags::TO | MappingFlags::LITERAL | MappingFlags::IMPLICIT; + let transfer_to: Vec = + transfer.iter().map(|m| m.intersection(valid_begin_mappings).bits()).collect(); + let transfer_from: Vec = + transfer.iter().map(|m| m.intersection(MappingFlags::FROM).bits()).collect(); + // FIXME(offload): add `OMP_MAP_TARGET_PARAM = 0x20` only if necessary + let transfer_kernel = vec![MappingFlags::TARGET_PARAM.bits(); transfer_to.len()]; let offload_sizes = add_priv_unnamed_arr(&cx, &format!(".offload_sizes.{symbol}"), &sizes); - // Here we figure out whether something needs to be copied to the gpu (=1), from the gpu (=2), - // or both to and from the gpu (=3). Other values shouldn't affect us for now. - // A non-mutable reference or pointer will be 1, an array that's not read, but fully overwritten - // will be 2. For now, everything is 3, until we have our frontend set up. - // 1+2+32: 1 (MapTo), 2 (MapFrom), 32 (Add one extra input ptr per function, to be used later). - let memtransfer_types = - add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{symbol}"), &transfer); + let memtransfer_begin = + add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{symbol}.begin"), &transfer_to); + let memtransfer_kernel = + add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{symbol}.kernel"), &transfer_kernel); + let memtransfer_end = + add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{symbol}.end"), &transfer_from); // Next: For each function, generate these three entries. A weak constant, // the llvm.rodata entry name, and the llvm_offload_entries value @@ -469,7 +491,13 @@ pub(crate) fn gen_define_handling<'ll>( cx.add_compiler_used_global(offload_entry); - let result = OffloadKernelGlobals { offload_sizes, memtransfer_types, region_id }; + let result = OffloadKernelGlobals { + offload_sizes, + memtransfer_begin, + memtransfer_kernel, + memtransfer_end, + region_id, + }; // FIXME(Sa4dUs): use this global for constant offload sizes cx.add_compiler_used_global(result.offload_sizes); @@ -535,7 +563,13 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( offload_dims: &OffloadKernelDims<'ll>, ) { let cx = builder.cx; - let OffloadKernelGlobals { memtransfer_types, region_id, .. } = offload_data; + let OffloadKernelGlobals { + memtransfer_begin, + memtransfer_kernel, + memtransfer_end, + region_id, + .. + } = offload_data; let OffloadKernelDims { num_workgroups, threads_per_block, workgroup_dims, thread_dims } = offload_dims; @@ -608,12 +642,6 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( geps.push(gep); } - let init_ty = cx.type_func(&[], cx.type_void()); - let init_rtls_decl = offload_globals.init_rtls; - - // call void @__tgt_init_all_rtls() - builder.call(init_ty, None, None, init_rtls_decl, &[], None, None); - for i in 0..num_args { let idx = cx.get_const_i32(i); let gep1 = builder.inbounds_gep(ty, a1, &[i32_0, idx]); @@ -668,14 +696,14 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( generate_mapper_call( builder, geps, - memtransfer_types, + memtransfer_begin, begin_mapper_decl, fn_ty, num_args, s_ident_t, ); let values = - KernelArgsTy::new(&cx, num_args, memtransfer_types, geps, workgroup_dims, thread_dims); + KernelArgsTy::new(&cx, num_args, memtransfer_kernel, geps, workgroup_dims, thread_dims); // Step 3) // Here we fill the KernelArgsTy, see the documentation above @@ -701,7 +729,7 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>( generate_mapper_call( builder, geps, - memtransfer_types, + memtransfer_end, end_mapper_decl, fn_ty, num_args, diff --git a/tests/codegen-llvm/gpu_offload/control_flow.rs b/tests/codegen-llvm/gpu_offload/control_flow.rs index 1a3d3cd7a778..fb483db667b2 100644 --- a/tests/codegen-llvm/gpu_offload/control_flow.rs +++ b/tests/codegen-llvm/gpu_offload/control_flow.rs @@ -19,9 +19,9 @@ // CHECK: br label %bb3 // CHECK-NOT define // CHECK: bb3 -// CHECK: call void @__tgt_target_data_begin_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.foo, ptr null, ptr null) +// CHECK: call void @__tgt_target_data_begin_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.foo.begin, ptr null, ptr null) // CHECK: %10 = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 256, i32 32, ptr nonnull @.foo.region_id, ptr nonnull %kernel_args) -// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.foo, ptr null, ptr null) +// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.foo.end, ptr null, ptr null) #[unsafe(no_mangle)] unsafe fn main() { let A = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]; diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index e12d7c792ae7..f25ba679abbd 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -14,19 +14,20 @@ #[unsafe(no_mangle)] fn main() { let mut x = [3.0; 256]; - kernel_1(&mut x); + let y = [1.0; 256]; + kernel_1(&mut x, &y); core::hint::black_box(&x); + core::hint::black_box(&y); } -pub fn kernel_1(x: &mut [f32; 256]) { - core::intrinsics::offload(kernel_1, [256, 1, 1], [32, 1, 1], (x,)) +pub fn kernel_1(x: &mut [f32; 256], y: &[f32; 256]) { + core::intrinsics::offload(_kernel_1, [256, 1, 1], [32, 1, 1], (x, y)) } -#[unsafe(no_mangle)] #[inline(never)] -pub fn _kernel_1(x: &mut [f32; 256]) { +pub fn _kernel_1(x: &mut [f32; 256], y: &[f32; 256]) { for i in 0..256 { - x[i] = 21.0; + x[i] = 21.0 + y[i]; } } @@ -39,8 +40,10 @@ pub fn _kernel_1(x: &mut [f32; 256]) { // CHECK-DAG: @.omp_offloading.descriptor = internal constant { i32, ptr, ptr, ptr } zeroinitializer // CHECK-DAG: @llvm.global_ctors = appending constant [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @.omp_offloading.descriptor_reg, ptr null }] -// CHECK-DAG: @.offload_sizes.[[K:[^ ]*kernel_1]] = private unnamed_addr constant [1 x i64] [i64 1024] -// CHECK-DAG: @.offload_maptypes.[[K]] = private unnamed_addr constant [1 x i64] [i64 35] +// CHECK-DAG: @.offload_sizes.[[K:[^ ]*kernel_1]] = private unnamed_addr constant [2 x i64] [i64 1024, i64 1024] +// CHECK-DAG: @.offload_maptypes.[[K]].begin = private unnamed_addr constant [2 x i64] [i64 1, i64 1] +// CHECK-DAG: @.offload_maptypes.[[K]].kernel = private unnamed_addr constant [2 x i64] [i64 32, i64 32] +// CHECK-DAG: @.offload_maptypes.[[K]].end = private unnamed_addr constant [2 x i64] [i64 2, i64 0] // CHECK-DAG: @.[[K]].region_id = internal constant i8 0 // CHECK-DAG: @.offloading.entry_name.[[K]] = internal unnamed_addr constant [{{[0-9]+}} x i8] c"[[K]]{{\\00}}", section ".llvm.rodata.offloading", align 1 // CHECK-DAG: @.offloading.entry.[[K]] = internal constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr @.[[K]].region_id, ptr @.offloading.entry_name.[[K]], i64 0, i64 0, ptr null }, section "llvm_offload_entries", align 8 @@ -49,20 +52,27 @@ pub fn _kernel_1(x: &mut [f32; 256]) { // CHECK-LABEL: define{{( dso_local)?}} void @main() // CHECK-NEXT: start: -// CHECK-NEXT: %0 = alloca [8 x i8], align 8 -// CHECK-NEXT: %x = alloca [1024 x i8], align 16 -// CHECK-NEXT: %.offload_baseptrs = alloca [1 x ptr], align 8 -// CHECK-NEXT: %.offload_ptrs = alloca [1 x ptr], align 8 -// CHECK-NEXT: %.offload_sizes = alloca [1 x i64], align 8 +// CHECK-NEXT: %0 = alloca [8 x i8], align 8 +// CHECK-NEXT: %1 = alloca [8 x i8], align 8 +// CHECK-NEXT: %y = alloca [1024 x i8], align 16 +// CHECK-NEXT: %x = alloca [1024 x i8], align 16 +// CHECK-NEXT: %.offload_baseptrs = alloca [2 x ptr], align 8 +// CHECK-NEXT: %.offload_ptrs = alloca [2 x ptr], align 8 +// CHECK-NEXT: %.offload_sizes = alloca [2 x i64], align 8 // CHECK-NEXT: %kernel_args = alloca %struct.__tgt_kernel_arguments, align 8 -// CHECK: call void @__tgt_init_all_rtls() -// CHECK-NEXT: store ptr %x, ptr %.offload_baseptrs, align 8 +// CHECK: store ptr %x, ptr %.offload_baseptrs, align 8 // CHECK-NEXT: store ptr %x, ptr %.offload_ptrs, align 8 // CHECK-NEXT: store i64 1024, ptr %.offload_sizes, align 8 -// CHECK-NEXT: call void @__tgt_target_data_begin_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.[[K]], ptr null, ptr null) +// CHECK-NEXT: [[BPTRS_1:%.*]] = getelementptr inbounds nuw i8, ptr %.offload_baseptrs, i64 8 +// CHECK-NEXT: store ptr %y, ptr [[BPTRS_1]], align 8 +// CHECK-NEXT: [[PTRS_1:%.*]] = getelementptr inbounds nuw i8, ptr %.offload_ptrs, i64 8 +// CHECK-NEXT: store ptr %y, ptr [[PTRS_1]], align 8 +// CHECK-NEXT: [[SIZES_1:%.*]] = getelementptr inbounds nuw i8, ptr %.offload_sizes, i64 8 +// CHECK-NEXT: store i64 1024, ptr [[SIZES_1]], align 8 +// CHECK-NEXT: call void @__tgt_target_data_begin_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 2, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.[[K]].begin, ptr null, ptr null) // CHECK-NEXT: store i32 3, ptr %kernel_args, align 8 // CHECK-NEXT: [[P4:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 4 -// CHECK-NEXT: store i32 1, ptr [[P4]], align 4 +// CHECK-NEXT: store i32 2, ptr [[P4]], align 4 // CHECK-NEXT: [[P8:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 8 // CHECK-NEXT: store ptr %.offload_baseptrs, ptr [[P8]], align 8 // CHECK-NEXT: [[P16:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 16 @@ -70,7 +80,7 @@ pub fn _kernel_1(x: &mut [f32; 256]) { // CHECK-NEXT: [[P24:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 24 // CHECK-NEXT: store ptr %.offload_sizes, ptr [[P24]], align 8 // CHECK-NEXT: [[P32:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 32 -// CHECK-NEXT: store ptr @.offload_maptypes.[[K]], ptr [[P32]], align 8 +// CHECK-NEXT: store ptr @.offload_maptypes.[[K]].kernel, ptr [[P32]], align 8 // CHECK-NEXT: [[P40:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 40 // CHECK-NEXT: [[P72:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 72 // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(32) [[P40]], i8 0, i64 32, i1 false) @@ -81,9 +91,9 @@ pub fn _kernel_1(x: &mut [f32; 256]) { // CHECK-NEXT: store i32 1, ptr [[P92]], align 4 // CHECK-NEXT: [[P96:%[^ ]+]] = getelementptr inbounds nuw i8, ptr %kernel_args, i64 96 // CHECK-NEXT: store i32 0, ptr [[P96]], align 8 -// CHECK-NEXT: {{%[^ ]+}} = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 256, i32 32, ptr nonnull @.[[K]].region_id, ptr nonnull %kernel_args) -// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 1, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.[[K]], ptr null, ptr null) -// CHECK: ret void +// CHECK-NEXT: [[TGT_RET:%.*]] = call i32 @__tgt_target_kernel(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 256, i32 32, ptr nonnull @.[[K]].region_id, ptr nonnull %kernel_args) +// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr nonnull @anon.{{.*}}.1, i64 -1, i32 2, ptr nonnull %.offload_baseptrs, ptr nonnull %.offload_ptrs, ptr nonnull %.offload_sizes, ptr nonnull @.offload_maptypes.[[K]].end, ptr null, ptr null) +// CHECK: ret void // CHECK-NEXT: } // CHECK: declare void @__tgt_register_lib(ptr) local_unnamed_addr @@ -92,6 +102,7 @@ pub fn _kernel_1(x: &mut [f32; 256]) { // CHECK-LABEL: define internal void @.omp_offloading.descriptor_reg() section ".text.startup" { // CHECK-NEXT: entry: // CHECK-NEXT: call void @__tgt_register_lib(ptr nonnull @.omp_offloading.descriptor) +// CHECK-NEXT: call void @__tgt_init_all_rtls() // CHECK-NEXT: %0 = {{tail }}call i32 @atexit(ptr nonnull @.omp_offloading.descriptor_unreg) // CHECK-NEXT: ret void // CHECK-NEXT: } From 7c5ea7ffd648cb1170510a7b50b0294a30891ffd Mon Sep 17 00:00:00 2001 From: Ruiyang Wang Date: Sat, 7 Feb 2026 17:57:53 +0000 Subject: [PATCH 3381/3801] Fix bound var resolution for trait aliases Handle DefKind::TraitAlias in resolve_bound_vars so that associated item constraints and return type notation work through trait aliases. --- .../src/collect/resolve_bound_vars.rs | 5 +++-- .../return-type-notation/trait-alias.rs | 13 +++++++++++++ .../trait-alias-bound-vars.rs | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tests/ui/associated-type-bounds/return-type-notation/trait-alias.rs create mode 100644 tests/ui/associated-type-bounds/trait-alias-bound-vars.rs 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 26f79d374075..d4a01d26a1fc 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1695,7 +1695,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { | DefKind::Union | DefKind::Enum | DefKind::TyAlias - | DefKind::Trait, + | DefKind::Trait + | DefKind::TraitAlias, def_id, ) if depth == 0 => Some(def_id), _ => None, @@ -1865,7 +1866,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { if constraint.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation { let bound_vars = if let Some(type_def_id) = type_def_id - && self.tcx.def_kind(type_def_id) == DefKind::Trait + && let DefKind::Trait | DefKind::TraitAlias = self.tcx.def_kind(type_def_id) && let Some((mut bound_vars, assoc_fn)) = BoundVarContext::supertrait_hrtb_vars( self.tcx, type_def_id, diff --git a/tests/ui/associated-type-bounds/return-type-notation/trait-alias.rs b/tests/ui/associated-type-bounds/return-type-notation/trait-alias.rs new file mode 100644 index 000000000000..88f60a72afa1 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/trait-alias.rs @@ -0,0 +1,13 @@ +// Regression test for . +//@ check-pass +#![feature(return_type_notation, trait_alias)] + +trait Tr { + fn f() -> impl Sized; +} + +trait Al = Tr; + +fn f>() {} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/trait-alias-bound-vars.rs b/tests/ui/associated-type-bounds/trait-alias-bound-vars.rs new file mode 100644 index 000000000000..4644cee21008 --- /dev/null +++ b/tests/ui/associated-type-bounds/trait-alias-bound-vars.rs @@ -0,0 +1,14 @@ +// Check that we're successfully collecting bound vars behind trait aliases. +// Regression test for . +//@ check-pass +//@ needs-rustc-debug-assertions +#![feature(trait_alias)] + +trait A<'a> { type X; } +trait B: for<'a> A<'a> {} +trait C = B; + +fn f() where T: C {} +fn g() where T: C A<'r>> {} + +fn main() {} From 58e4a341b634f21cf164e7636f4b8d63432dae7b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 5 Feb 2026 14:24:39 +1100 Subject: [PATCH 3382/3801] Move `try_get_cached` from `rustc_query_system` to `rustc_middle`. That's the only place it's used, so it no longer needs to be `pub`. --- compiler/rustc_middle/src/query/inner.rs | 21 ++++++++++++++++++- .../rustc_query_system/src/query/plumbing.rs | 20 ------------------ 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_middle/src/query/inner.rs b/compiler/rustc_middle/src/query/inner.rs index 32fe0737ec12..594286bfa574 100644 --- a/compiler/rustc_middle/src/query/inner.rs +++ b/compiler/rustc_middle/src/query/inner.rs @@ -2,7 +2,7 @@ //! `tcx.$query(..)` and its variations. use rustc_query_system::dep_graph::{DepKind, DepNodeKey}; -use rustc_query_system::query::{QueryCache, QueryMode, try_get_cached}; +use rustc_query_system::query::{QueryCache, QueryMode}; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; use crate::dep_graph; @@ -10,6 +10,25 @@ use crate::query::erase::{self, Erasable, Erased}; use crate::query::plumbing::QueryVTable; use crate::ty::TyCtxt; +/// Checks whether there is already a value for this key in the in-memory +/// query cache, returning that value if present. +/// +/// (Also performs some associated bookkeeping, if a value was found.) +#[inline(always)] +fn try_get_cached<'tcx, C>(tcx: TyCtxt<'tcx>, cache: &C, key: &C::Key) -> Option +where + C: QueryCache, +{ + match cache.lookup(key) { + Some((value, index)) => { + tcx.prof.query_cache_hit(index.into()); + tcx.dep_graph.read_index(index); + Some(value) + } + None => None, + } +} + /// Shared implementation of `tcx.$query(..)` and `tcx.at(span).$query(..)` /// for all queries. #[inline(always)] diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 32c4f6e1c847..795d36c7b808 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -266,26 +266,6 @@ impl<'tcx> CycleError> { } } -/// Checks whether there is already a value for this key in the in-memory -/// query cache, returning that value if present. -/// -/// (Also performs some associated bookkeeping, if a value was found.) -#[inline(always)] -pub fn try_get_cached(tcx: Tcx, cache: &C, key: &C::Key) -> Option -where - C: QueryCache, - Tcx: DepContext, -{ - match cache.lookup(key) { - Some((value, index)) => { - tcx.profiler().query_cache_hit(index.into()); - tcx.dep_graph().read_index(index); - Some(value) - } - None => None, - } -} - #[cold] #[inline(never)] fn cycle_error<'tcx, Q>( From 25df79ea5d5a9cc03d13018d7a3f86190c35dc2c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 5 Feb 2026 15:15:13 +1100 Subject: [PATCH 3383/3801] Derive `Clone` for `QueryJob`. Instead of writing it by hand. --- compiler/rustc_query_system/src/query/job.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 50cb58f0b4d5..0fd50128b544 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -65,7 +65,7 @@ pub struct QueryJobInfo<'tcx> { } /// Represents an active query job. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct QueryJob<'tcx> { pub id: QueryJobId, @@ -79,12 +79,6 @@ pub struct QueryJob<'tcx> { latch: Option>, } -impl<'tcx> Clone for QueryJob<'tcx> { - fn clone(&self) -> Self { - Self { id: self.id, span: self.span, parent: self.parent, latch: self.latch.clone() } - } -} - impl<'tcx> QueryJob<'tcx> { /// Creates a new query job. #[inline] From d3ec6a351a027a71bdfbd36429288c1357ccdbea Mon Sep 17 00:00:00 2001 From: Weixie Cui Date: Sun, 8 Feb 2026 11:40:56 +0800 Subject: [PATCH 3384/3801] fix: add continue --- compiler/rustc_borrowck/src/diagnostics/region_errors.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index ae389d1a6e10..6e35cf0ea28b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -872,6 +872,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { for alias_ty in alias_tys { if alias_ty.span.desugaring_kind().is_some() { // Skip `async` desugaring `impl Future`. + continue; } if let TyKind::TraitObject(_, lt) = alias_ty.kind { if lt.kind == hir::LifetimeKind::ImplicitObjectLifetimeDefault { From 6527b3404c7ce641d50f4bda7711903f30b3e34c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 8 Feb 2026 15:14:17 +1100 Subject: [PATCH 3385/3801] Move a lot of `rustc_query_system::plumbing` to `rustc_query_impl::execution` (part 1). [Note: this commit conceptually moves 75% of a file to another location, and leaves 25% of it behind. It's impossible to preserve all the git history. To preserve git history of the moved 75%, in this commit we rename the file and remove the 25% from it, leaving the code in an incomplete (uncompilable) state. In the next commit we add back the 25% in the old location.] We are in the process of eliminating `rustc_query_system`. Chunks of it are unused by `rustc_middle`, and so can be moved into `rustc_query_impl`. This commit does some of that. Mostly it's just moving code from one file to a new file. There are a couple of non-trivial changes. - `QueryState` and `ActiveKeyStatus` must remain in `rustc_query_system` because they are used by `rustc_middle`. But their inherent methods are not used by `rustc_middle`. So these methods are moved and converted to free functions. - The visibility of some things must increase. This includes `DepGraphData` and some of its methods, which are now used in `rustc_query_impl`. This is a bit annoying but seems hard to avoid. What little is left behind in `compiler/rustc_query_system/src/query/plumbing.rs` will be able to moved into `rustc_query_impl` or `rustc_middle` in the future. --- .../src/execution.rs} | 284 +++++------------- compiler/rustc_query_impl/src/lib.rs | 16 +- compiler/rustc_query_impl/src/plumbing.rs | 11 +- .../rustc_query_system/src/dep_graph/graph.rs | 18 +- .../rustc_query_system/src/dep_graph/mod.rs | 5 +- compiler/rustc_query_system/src/lib.rs | 1 - compiler/rustc_query_system/src/query/job.rs | 8 +- compiler/rustc_query_system/src/query/mod.rs | 6 +- 8 files changed, 100 insertions(+), 249 deletions(-) rename compiler/{rustc_query_system/src/query/plumbing.rs => rustc_query_impl/src/execution.rs} (73%) diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_impl/src/execution.rs similarity index 73% rename from compiler/rustc_query_system/src/query/plumbing.rs rename to compiler/rustc_query_impl/src/execution.rs index 795d36c7b808..9fa41f741e08 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -1,133 +1,83 @@ -//! The implementation of the query system itself. This defines the macros that -//! generate the actual methods on tcx which find and execute the provider, -//! manage the caches, and so forth. - -use std::cell::Cell; -use std::fmt::Debug; use std::hash::Hash; use std::mem; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::hash_table::{self, Entry, HashTable}; -use rustc_data_structures::sharded::{self, Sharded}; +use rustc_data_structures::hash_table::{Entry, HashTable}; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_data_structures::{outline, sync}; +use rustc_data_structures::{outline, sharded, sync}; use rustc_errors::{Diag, FatalError, StashKey}; +use rustc_query_system::dep_graph::{DepGraphData, DepNodeKey, HasDepContext}; +use rustc_query_system::query::{ + ActiveKeyStatus, CycleError, CycleErrorHandling, QueryCache, QueryContext, QueryDispatcher, + QueryJob, QueryJobId, QueryJobInfo, QueryLatch, QueryMap, QueryMode, QueryStackDeferred, + QueryStackFrame, QueryState, incremental_verify_ich, report_cycle, +}; use rustc_span::{DUMMY_SP, Span}; -use tracing::instrument; -use super::{QueryDispatcher, QueryStackDeferred, QueryStackFrameExtra}; -use crate::dep_graph::{ - DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeKey, HasDepContext, -}; -use crate::ich::StableHashingContext; -use crate::query::caches::QueryCache; -use crate::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, report_cycle}; -use crate::query::{ - CycleErrorHandling, QueryContext, QueryMap, QueryStackFrame, SerializedDepNodeIndex, -}; +use crate::dep_graph::{DepContext, DepNode, DepNodeIndex}; #[inline] fn equivalent_key(k: &K) -> impl Fn(&(K, V)) -> bool + '_ { move |x| x.0 == *k } -/// For a particular query, keeps track of "active" keys, i.e. keys whose -/// evaluation has started but has not yet finished successfully. +/// Obtains the enclosed [`QueryJob`], or panics if this query evaluation +/// was poisoned by a panic. +fn expect_job<'tcx>(status: ActiveKeyStatus<'tcx>) -> QueryJob<'tcx> { + match status { + ActiveKeyStatus::Started(job) => job, + ActiveKeyStatus::Poisoned => { + panic!("job for query failed to start and was poisoned") + } + } +} + +pub(crate) fn all_inactive<'tcx, K>(state: &QueryState<'tcx, K>) -> bool { + state.active.lock_shards().all(|shard| shard.is_empty()) +} + +/// Internal plumbing for collecting the set of active jobs for this query. /// -/// (Successful query evaluation for a key is represented by an entry in the -/// query's in-memory cache.) -pub struct QueryState<'tcx, K> { - active: Sharded)>>, -} +/// Should only be called from `gather_active_jobs`. +pub(crate) fn gather_active_jobs_inner<'tcx, Qcx: Copy, K: Copy>( + state: &QueryState<'tcx, K>, + qcx: Qcx, + make_frame: fn(Qcx, K) -> QueryStackFrame>, + jobs: &mut QueryMap<'tcx>, + require_complete: bool, +) -> Option<()> { + let mut active = Vec::new(); -/// For a particular query and key, tracks the status of a query evaluation -/// that has started, but has not yet finished successfully. -/// -/// (Successful query evaluation for a key is represented by an entry in the -/// query's in-memory cache.) -enum ActiveKeyStatus<'tcx> { - /// Some thread is already evaluating the query for this key. - /// - /// The enclosed [`QueryJob`] can be used to wait for it to finish. - Started(QueryJob<'tcx>), - - /// The query panicked. Queries trying to wait on this will raise a fatal error which will - /// silently panic. - Poisoned, -} - -impl<'tcx> ActiveKeyStatus<'tcx> { - /// Obtains the enclosed [`QueryJob`], or panics if this query evaluation - /// was poisoned by a panic. - fn expect_job(self) -> QueryJob<'tcx> { - match self { - Self::Started(job) => job, - Self::Poisoned => { - panic!("job for query failed to start and was poisoned") + // Helper to gather active jobs from a single shard. + let mut gather_shard_jobs = |shard: &HashTable<(K, ActiveKeyStatus<'tcx>)>| { + for (k, v) in shard.iter() { + if let ActiveKeyStatus::Started(ref job) = *v { + active.push((*k, job.clone())); } } - } -} + }; -impl<'tcx, K> QueryState<'tcx, K> -where - K: Eq + Hash + Copy + Debug, -{ - pub fn all_inactive(&self) -> bool { - self.active.lock_shards().all(|shard| shard.is_empty()) - } - - /// Internal plumbing for collecting the set of active jobs for this query. - /// - /// Should only be called from `gather_active_jobs`. - pub fn gather_active_jobs_inner( - &self, - qcx: Qcx, - make_frame: fn(Qcx, K) -> QueryStackFrame>, - jobs: &mut QueryMap<'tcx>, - require_complete: bool, - ) -> Option<()> { - let mut active = Vec::new(); - - // Helper to gather active jobs from a single shard. - let mut gather_shard_jobs = |shard: &HashTable<(K, ActiveKeyStatus<'tcx>)>| { - for (k, v) in shard.iter() { - if let ActiveKeyStatus::Started(ref job) = *v { - active.push((*k, job.clone())); - } - } - }; - - // Lock shards and gather jobs from each shard. - if require_complete { - for shard in self.active.lock_shards() { - gather_shard_jobs(&shard); - } - } else { - // We use try_lock_shards here since we are called from the - // deadlock handler, and this shouldn't be locked. - for shard in self.active.try_lock_shards() { - let shard = shard?; - gather_shard_jobs(&shard); - } + // Lock shards and gather jobs from each shard. + if require_complete { + for shard in state.active.lock_shards() { + gather_shard_jobs(&shard); } - - // Call `make_frame` while we're not holding a `self.active` lock as `make_frame` may call - // queries leading to a deadlock. - for (key, job) in active { - let frame = make_frame(qcx, key); - jobs.insert(job.id, QueryJobInfo { frame, job }); + } else { + // We use try_lock_shards here since we are called from the + // deadlock handler, and this shouldn't be locked. + for shard in state.active.try_lock_shards() { + let shard = shard?; + gather_shard_jobs(&shard); } - - Some(()) } -} -impl<'tcx, K> Default for QueryState<'tcx, K> { - fn default() -> QueryState<'tcx, K> { - QueryState { active: Default::default() } + // Call `make_frame` while we're not holding a `state.active` lock as `make_frame` may call + // queries leading to a deadlock. + for (key, job) in active { + let frame = make_frame(qcx, key); + jobs.insert(job.id, QueryJobInfo { frame, job }); } + + Some(()) } /// A type representing the responsibility to execute the job in the `job` field. @@ -217,7 +167,7 @@ where Ok(occupied) => Some(occupied.remove().0.1), } }; - let job = job.expect("active query job entry").expect_job(); + let job = expect_job(job.expect("active query job entry")); job.signal_complete(); } @@ -240,7 +190,7 @@ where Ok(occupied) => { let ((key, value), vacant) = occupied.remove(); vacant.insert((key, ActiveKeyStatus::Poisoned)); - value.expect_job() + expect_job(value) } } }; @@ -250,22 +200,6 @@ where } } -#[derive(Clone, Debug)] -pub struct CycleError { - /// The query and related span that uses the cycle. - pub usage: Option<(Span, QueryStackFrame)>, - pub cycle: Vec>, -} - -impl<'tcx> CycleError> { - fn lift(&self) -> CycleError { - CycleError { - usage: self.usage.as_ref().map(|(span, frame)| (*span, frame.lift())), - cycle: self.cycle.iter().map(|info| info.lift()).collect(), - } - } -} - #[cold] #[inline(never)] fn cycle_error<'tcx, Q>( @@ -664,89 +598,6 @@ where Some((result, dep_node_index)) } -#[inline] -#[instrument(skip(tcx, dep_graph_data, result, hash_result, format_value), level = "debug")] -pub(crate) fn incremental_verify_ich( - tcx: Tcx, - dep_graph_data: &DepGraphData, - result: &V, - prev_index: SerializedDepNodeIndex, - hash_result: Option, &V) -> Fingerprint>, - format_value: fn(&V) -> String, -) where - Tcx: DepContext, -{ - if !dep_graph_data.is_index_green(prev_index) { - incremental_verify_ich_not_green(tcx, prev_index) - } - - let new_hash = hash_result.map_or(Fingerprint::ZERO, |f| { - tcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result)) - }); - - let old_hash = dep_graph_data.prev_fingerprint_of(prev_index); - - if new_hash != old_hash { - incremental_verify_ich_failed(tcx, prev_index, &|| format_value(result)); - } -} - -#[cold] -#[inline(never)] -fn incremental_verify_ich_not_green(tcx: Tcx, prev_index: SerializedDepNodeIndex) -where - Tcx: DepContext, -{ - panic!( - "fingerprint for green query instance not loaded from cache: {:?}", - tcx.dep_graph().data().unwrap().prev_node_of(prev_index) - ) -} - -// Note that this is marked #[cold] and intentionally takes `dyn Debug` for `result`, -// as we want to avoid generating a bunch of different implementations for LLVM to -// chew on (and filling up the final binary, too). -#[cold] -#[inline(never)] -fn incremental_verify_ich_failed( - tcx: Tcx, - prev_index: SerializedDepNodeIndex, - result: &dyn Fn() -> String, -) where - Tcx: DepContext, -{ - // When we emit an error message and panic, we try to debug-print the `DepNode` - // and query result. Unfortunately, this can cause us to run additional queries, - // which may result in another fingerprint mismatch while we're in the middle - // of processing this one. To avoid a double-panic (which kills the process - // before we can print out the query static), we print out a terse - // but 'safe' message if we detect a reentrant call to this method. - thread_local! { - static INSIDE_VERIFY_PANIC: Cell = const { Cell::new(false) }; - }; - - let old_in_panic = INSIDE_VERIFY_PANIC.replace(true); - - if old_in_panic { - tcx.sess().dcx().emit_err(crate::error::Reentrant); - } else { - let run_cmd = if let Some(crate_name) = &tcx.sess().opts.crate_name { - format!("`cargo clean -p {crate_name}` or `cargo clean`") - } else { - "`cargo clean`".to_string() - }; - - let dep_node = tcx.dep_graph().data().unwrap().prev_node_of(prev_index); - tcx.sess().dcx().emit_err(crate::error::IncrementCompilation { - run_cmd, - dep_node: format!("{dep_node:?}"), - }); - panic!("Found unstable fingerprints for {dep_node:?}: {}", result()); - } - - INSIDE_VERIFY_PANIC.set(old_in_panic); -} - /// Ensure that either this query has all green inputs or been executed. /// Executing `query::ensure(D)` is considered a read of the dep-node `D`. /// Returns true if the query should still run. @@ -801,14 +652,13 @@ where (!loadable, Some(dep_node)) } -#[derive(Debug)] -pub enum QueryMode { - Get, - Ensure { check_cache: bool }, -} - #[inline(always)] -pub fn get_query_non_incr<'tcx, Q>(query: Q, qcx: Q::Qcx, span: Span, key: Q::Key) -> Q::Value +pub(super) fn get_query_non_incr<'tcx, Q>( + query: Q, + qcx: Q::Qcx, + span: Span, + key: Q::Key, +) -> Q::Value where Q: QueryDispatcher<'tcx>, { @@ -818,7 +668,7 @@ where } #[inline(always)] -pub fn get_query_incr<'tcx, Q>( +pub(super) fn get_query_incr<'tcx, Q>( query: Q, qcx: Q::Qcx, span: Span, @@ -848,7 +698,7 @@ where Some(result) } -pub fn force_query<'tcx, Q>(query: Q, qcx: Q::Qcx, key: Q::Key, dep_node: DepNode) +pub(super) fn force_query<'tcx, Q>(query: Q, qcx: Q::Qcx, key: Q::Key, dep_node: DepNode) where Q: QueryDispatcher<'tcx>, { diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 19d43e9bb93d..228d0070b55b 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -3,6 +3,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![feature(adt_const_params)] +#![feature(core_intrinsics)] #![feature(min_specialization)] #![feature(rustc_attrs)] // tidy-alphabetical-end @@ -25,21 +26,20 @@ use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ CycleError, CycleErrorHandling, HashResult, QueryCache, QueryDispatcher, QueryMap, QueryMode, - QueryState, get_query_incr, get_query_non_incr, + QueryState, }; use rustc_span::{ErrorGuaranteed, Span}; +pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all}; use crate::plumbing::{encode_all_query_results, try_mark_green}; use crate::profiling_support::QueryKeyStringCache; - -#[macro_use] -mod plumbing; -pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all}; - -mod profiling_support; -pub use self::profiling_support::alloc_self_profile_query_strings; +pub use crate::profiling_support::alloc_self_profile_query_strings; mod error; +mod execution; +#[macro_use] +mod plumbing; +mod profiling_support; #[derive(ConstParamTy)] // Allow this struct to be used for const-generic values. #[derive(Clone, Copy, Debug, PartialEq, Eq)] diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index a71acae3096e..8738370dd1e7 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -29,13 +29,14 @@ use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle, HasDepContext} use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ QueryCache, QueryContext, QueryDispatcher, QueryJobId, QueryMap, QuerySideEffect, - QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, force_query, + QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, }; use rustc_serialize::{Decodable, Encodable}; use rustc_span::def_id::LOCAL_CRATE; use crate::QueryDispatcherUnerased; use crate::error::{QueryOverflow, QueryOverflowNote}; +use crate::execution::{all_inactive, force_query}; /// Implements [`QueryContext`] for use by [`rustc_query_system`], since that /// crate does not have direct access to [`TyCtxt`]. @@ -387,7 +388,7 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>( { let _timer = qcx.tcx.prof.generic_activity_with_arg("encode_query_results_for", query.name()); - assert!(query.query_state(qcx).all_inactive()); + assert!(all_inactive(query.query_state(qcx))); let cache = query.query_cache(qcx); cache.iter(&mut |key, value, dep_node| { if query.will_cache_on_disk_for_key(qcx.tcx, key) { @@ -594,7 +595,7 @@ macro_rules! define_queries { ) -> Option>> { #[cfg(debug_assertions)] let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); - get_query_incr( + execution::get_query_incr( QueryType::query_dispatcher(tcx), QueryCtxt::new(tcx), span, @@ -614,7 +615,7 @@ macro_rules! define_queries { key: queries::$name::Key<'tcx>, __mode: QueryMode, ) -> Option>> { - Some(get_query_non_incr( + Some(execution::get_query_non_incr( QueryType::query_dispatcher(tcx), QueryCtxt::new(tcx), span, @@ -748,7 +749,7 @@ macro_rules! define_queries { }; // Call `gather_active_jobs_inner` to do the actual work. - let res = tcx.query_system.states.$name.gather_active_jobs_inner( + let res = crate::execution::gather_active_jobs_inner(&tcx.query_system.states.$name, tcx, make_frame, qmap, diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 06e576baf22a..31aafaea6450 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -82,7 +82,7 @@ pub(super) enum DepNodeColor { Unknown, } -pub(crate) struct DepGraphData { +pub struct DepGraphData { /// The new encoding of the dependency graph, optimized for red/green /// tracking. The `current` field is the dependency graph of only the /// current compilation session: We don't merge the previous dep-graph into @@ -171,7 +171,7 @@ impl DepGraph { } #[inline] - pub(crate) fn data(&self) -> Option<&DepGraphData> { + pub fn data(&self) -> Option<&DepGraphData> { self.data.as_deref() } @@ -323,7 +323,7 @@ impl DepGraphData { /// /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation.html #[inline(always)] - pub(crate) fn with_task, A: Debug, R>( + pub fn with_task, A: Debug, R>( &self, key: DepNode, cx: Ctxt, @@ -373,7 +373,7 @@ impl DepGraphData { /// FIXME: This could perhaps return a `WithDepNode` to ensure that the /// user of this function actually performs the read; we'll have to see /// how to make that work with `anon` in `execute_job_incr`, though. - pub(crate) fn with_anon_task_inner, OP, R>( + pub fn with_anon_task_inner, OP, R>( &self, cx: Tcx, dep_kind: DepKind, @@ -653,12 +653,12 @@ impl DepGraphData { /// Returns true if the given node has been marked as green during the /// current compilation session. Used in various assertions #[inline] - pub(crate) fn is_index_green(&self, prev_index: SerializedDepNodeIndex) -> bool { + pub fn is_index_green(&self, prev_index: SerializedDepNodeIndex) -> bool { matches!(self.colors.get(prev_index), DepNodeColor::Green(_)) } #[inline] - pub(crate) fn prev_fingerprint_of(&self, prev_index: SerializedDepNodeIndex) -> Fingerprint { + pub fn prev_fingerprint_of(&self, prev_index: SerializedDepNodeIndex) -> Fingerprint { self.previous.fingerprint_by_index(prev_index) } @@ -667,7 +667,7 @@ impl DepGraphData { self.previous.index_to_node(prev_index) } - pub(crate) fn mark_debug_loaded_from_disk(&self, dep_node: DepNode) { + pub fn mark_debug_loaded_from_disk(&self, dep_node: DepNode) { self.debug_loaded_from_disk.lock().insert(dep_node); } @@ -863,7 +863,7 @@ impl DepGraphData { /// A node will have an index, when it's already been marked green, or when we can mark it /// green. This function will mark the current task as a reader of the specified node, when /// a node index can be found for that node. - pub(crate) fn try_mark_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>( + pub fn try_mark_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>( &self, qcx: Qcx, dep_node: &DepNode, @@ -1074,7 +1074,7 @@ impl DepGraph { if let Some(data) = &self.data { data.current.encoder.finish(&data.current) } else { Ok(0) } } - pub(crate) fn next_virtual_depnode_index(&self) -> DepNodeIndex { + pub fn next_virtual_depnode_index(&self) -> DepNodeIndex { debug_assert!(self.data.is_none()); let index = self.virtual_dep_node_index.fetch_add(1, Ordering::Relaxed); DepNodeIndex::from_u32(index) diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index f2cb01d5e9b4..da110ad2c77c 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -8,8 +8,9 @@ mod serialized; use std::panic; pub use dep_node::{DepKind, DepKindVTable, DepNode, DepNodeKey, WorkProductId}; -pub(crate) use graph::DepGraphData; -pub use graph::{DepGraph, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result}; +pub use graph::{ + DepGraph, DepGraphData, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result, +}; pub use query::DepGraphQuery; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::DynSync; diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index b61b9b71b528..7f6426e395f9 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -1,7 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![feature(assert_matches)] -#![feature(core_intrinsics)] #![feature(min_specialization)] // tidy-alphabetical-end diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 0fd50128b544..bf7c480b05dd 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -86,7 +86,7 @@ impl<'tcx> QueryJob<'tcx> { QueryJob { id, span, parent, latch: None } } - pub(super) fn latch(&mut self) -> QueryLatch<'tcx> { + pub fn latch(&mut self) -> QueryLatch<'tcx> { if self.latch.is_none() { self.latch = Some(QueryLatch::new()); } @@ -106,7 +106,7 @@ impl<'tcx> QueryJob<'tcx> { } impl QueryJobId { - pub(super) fn find_cycle_in_stack<'tcx>( + pub fn find_cycle_in_stack<'tcx>( &self, query_map: QueryMap<'tcx>, current_job: &Option, @@ -182,7 +182,7 @@ struct QueryLatchInfo<'tcx> { } #[derive(Debug)] -pub(super) struct QueryLatch<'tcx> { +pub struct QueryLatch<'tcx> { info: Arc>>, } @@ -200,7 +200,7 @@ impl<'tcx> QueryLatch<'tcx> { } /// Awaits for the query job to complete. - pub(super) fn wait_on( + pub fn wait_on( &self, qcx: impl QueryContext<'tcx>, query: Option, diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index dbf7395bd61a..3eea0717f409 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -15,8 +15,8 @@ use rustc_span::def_id::DefId; pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; pub use self::dispatcher::{HashResult, QueryDispatcher}; pub use self::job::{ - QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap, break_query_cycles, print_query_stack, - report_cycle, + QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, QueryMap, break_query_cycles, + print_query_stack, report_cycle, }; pub use self::plumbing::*; use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; @@ -84,7 +84,7 @@ impl<'tcx> QueryStackFrame> { #[derive(Clone, Debug)] pub struct QueryStackFrameExtra { pub description: String, - span: Option, + pub span: Option, pub def_kind: Option, } From 563a2f04c7091335c508cddbf56b11f29b2a5ed5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 8 Feb 2026 15:25:49 +1100 Subject: [PATCH 3386/3801] Move a lot of `rustc_query_system::plumbing` to `rustc_query_impl::execution` (part 2). [Note: see the previous commit to understand this commit.] --- .../rustc_query_system/src/query/plumbing.rs | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 compiler/rustc_query_system/src/query/plumbing.rs diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs new file mode 100644 index 000000000000..d7a24d613583 --- /dev/null +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -0,0 +1,150 @@ +use std::cell::Cell; +use std::fmt::Debug; + +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::hash_table::HashTable; +use rustc_data_structures::sharded::Sharded; +use rustc_span::Span; +use tracing::instrument; + +use super::{QueryStackDeferred, QueryStackFrameExtra}; +use crate::dep_graph::{DepContext, DepGraphData}; +use crate::ich::StableHashingContext; +use crate::query::job::{QueryInfo, QueryJob}; +use crate::query::{QueryStackFrame, SerializedDepNodeIndex}; + +/// For a particular query, keeps track of "active" keys, i.e. keys whose +/// evaluation has started but has not yet finished successfully. +/// +/// (Successful query evaluation for a key is represented by an entry in the +/// query's in-memory cache.) +pub struct QueryState<'tcx, K> { + pub active: Sharded)>>, +} + +/// For a particular query and key, tracks the status of a query evaluation +/// that has started, but has not yet finished successfully. +/// +/// (Successful query evaluation for a key is represented by an entry in the +/// query's in-memory cache.) +pub enum ActiveKeyStatus<'tcx> { + /// Some thread is already evaluating the query for this key. + /// + /// The enclosed [`QueryJob`] can be used to wait for it to finish. + Started(QueryJob<'tcx>), + + /// The query panicked. Queries trying to wait on this will raise a fatal error which will + /// silently panic. + Poisoned, +} + +impl<'tcx, K> Default for QueryState<'tcx, K> { + fn default() -> QueryState<'tcx, K> { + QueryState { active: Default::default() } + } +} + +#[derive(Clone, Debug)] +pub struct CycleError { + /// The query and related span that uses the cycle. + pub usage: Option<(Span, QueryStackFrame)>, + pub cycle: Vec>, +} + +impl<'tcx> CycleError> { + pub fn lift(&self) -> CycleError { + CycleError { + usage: self.usage.as_ref().map(|(span, frame)| (*span, frame.lift())), + cycle: self.cycle.iter().map(|info| info.lift()).collect(), + } + } +} + +#[inline] +#[instrument(skip(tcx, dep_graph_data, result, hash_result, format_value), level = "debug")] +pub fn incremental_verify_ich( + tcx: Tcx, + dep_graph_data: &DepGraphData, + result: &V, + prev_index: SerializedDepNodeIndex, + hash_result: Option, &V) -> Fingerprint>, + format_value: fn(&V) -> String, +) where + Tcx: DepContext, +{ + if !dep_graph_data.is_index_green(prev_index) { + incremental_verify_ich_not_green(tcx, prev_index) + } + + let new_hash = hash_result.map_or(Fingerprint::ZERO, |f| { + tcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result)) + }); + + let old_hash = dep_graph_data.prev_fingerprint_of(prev_index); + + if new_hash != old_hash { + incremental_verify_ich_failed(tcx, prev_index, &|| format_value(result)); + } +} + +#[cold] +#[inline(never)] +fn incremental_verify_ich_not_green(tcx: Tcx, prev_index: SerializedDepNodeIndex) +where + Tcx: DepContext, +{ + panic!( + "fingerprint for green query instance not loaded from cache: {:?}", + tcx.dep_graph().data().unwrap().prev_node_of(prev_index) + ) +} + +// Note that this is marked #[cold] and intentionally takes `dyn Debug` for `result`, +// as we want to avoid generating a bunch of different implementations for LLVM to +// chew on (and filling up the final binary, too). +#[cold] +#[inline(never)] +fn incremental_verify_ich_failed( + tcx: Tcx, + prev_index: SerializedDepNodeIndex, + result: &dyn Fn() -> String, +) where + Tcx: DepContext, +{ + // When we emit an error message and panic, we try to debug-print the `DepNode` + // and query result. Unfortunately, this can cause us to run additional queries, + // which may result in another fingerprint mismatch while we're in the middle + // of processing this one. To avoid a double-panic (which kills the process + // before we can print out the query static), we print out a terse + // but 'safe' message if we detect a reentrant call to this method. + thread_local! { + static INSIDE_VERIFY_PANIC: Cell = const { Cell::new(false) }; + }; + + let old_in_panic = INSIDE_VERIFY_PANIC.replace(true); + + if old_in_panic { + tcx.sess().dcx().emit_err(crate::error::Reentrant); + } else { + let run_cmd = if let Some(crate_name) = &tcx.sess().opts.crate_name { + format!("`cargo clean -p {crate_name}` or `cargo clean`") + } else { + "`cargo clean`".to_string() + }; + + let dep_node = tcx.dep_graph().data().unwrap().prev_node_of(prev_index); + tcx.sess().dcx().emit_err(crate::error::IncrementCompilation { + run_cmd, + dep_node: format!("{dep_node:?}"), + }); + panic!("Found unstable fingerprints for {dep_node:?}: {}", result()); + } + + INSIDE_VERIFY_PANIC.set(old_in_panic); +} + +#[derive(Debug)] +pub enum QueryMode { + Get, + Ensure { check_cache: bool }, +} From a6dd4d870ac48290294f7342366f2ff4cd031d97 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 8 Feb 2026 15:56:56 +1100 Subject: [PATCH 3387/3801] Remove now-unnecessary indirection. The previous commit moved some code from `rustc_query_system`, which doesn't have access to `TyCtxt` and `QueryCtxt`, to `rustc_query_impl`, which does. We can now remove quite a bit of indirection. - Three methods in `trait QueryContext` are no longer needed (`next_job_id`, `current_query_job`, `start_query`). As a result, `QueryCtxt`'s trait impls of these methods are changed to inherent methods. - `qcx: Q::Qcx` parameters are simplified to `qcx: QueryCtxt<'tcx>`. - `*qcx.dep_context()` occurrences are simplified to `qcx.tcx`, and things like `qcx.dep_context().profiler()` become `qcx.tcx.prof`. - `DepGraphData<::Deps>` becomes `DepGraphData`. In short, various layers of indirection and abstraction are cut away. The resulting code is simpler, more concrete, and easier to understand. It's a good demonstration of the benefits of eliminating `rustc_query_system`, and there will be more to come. --- compiler/rustc_query_impl/src/execution.rs | 149 +++++++++---------- compiler/rustc_query_impl/src/plumbing.rs | 99 ++++++------ compiler/rustc_query_system/src/query/mod.rs | 10 -- 3 files changed, 120 insertions(+), 138 deletions(-) diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 9fa41f741e08..e58e626a7dfa 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -5,6 +5,8 @@ use rustc_data_structures::hash_table::{Entry, HashTable}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::{outline, sharded, sync}; use rustc_errors::{Diag, FatalError, StashKey}; +use rustc_middle::dep_graph::DepsType; +use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::{DepGraphData, DepNodeKey, HasDepContext}; use rustc_query_system::query::{ ActiveKeyStatus, CycleError, CycleErrorHandling, QueryCache, QueryContext, QueryDispatcher, @@ -14,6 +16,7 @@ use rustc_query_system::query::{ use rustc_span::{DUMMY_SP, Span}; use crate::dep_graph::{DepContext, DepNode, DepNodeIndex}; +use crate::plumbing::QueryCtxt; #[inline] fn equivalent_key(k: &K) -> impl Fn(&(K, V)) -> bool + '_ { @@ -38,10 +41,10 @@ pub(crate) fn all_inactive<'tcx, K>(state: &QueryState<'tcx, K>) -> bool { /// Internal plumbing for collecting the set of active jobs for this query. /// /// Should only be called from `gather_active_jobs`. -pub(crate) fn gather_active_jobs_inner<'tcx, Qcx: Copy, K: Copy>( +pub(crate) fn gather_active_jobs_inner<'tcx, K: Copy>( state: &QueryState<'tcx, K>, - qcx: Qcx, - make_frame: fn(Qcx, K) -> QueryStackFrame>, + tcx: TyCtxt<'tcx>, + make_frame: fn(TyCtxt<'tcx>, K) -> QueryStackFrame>, jobs: &mut QueryMap<'tcx>, require_complete: bool, ) -> Option<()> { @@ -73,7 +76,7 @@ pub(crate) fn gather_active_jobs_inner<'tcx, Qcx: Copy, K: Copy>( // Call `make_frame` while we're not holding a `state.active` lock as `make_frame` may call // queries leading to a deadlock. for (key, job) in active { - let frame = make_frame(qcx, key); + let frame = make_frame(tcx, key); jobs.insert(job.id, QueryJobInfo { frame, job }); } @@ -92,36 +95,36 @@ where #[cold] #[inline(never)] -fn mk_cycle<'tcx, Q>(query: Q, qcx: Q::Qcx, cycle_error: CycleError) -> Q::Value +fn mk_cycle<'tcx, Q>(query: Q, qcx: QueryCtxt<'tcx>, cycle_error: CycleError) -> Q::Value where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { - let error = report_cycle(qcx.dep_context().sess(), &cycle_error); + let error = report_cycle(qcx.tcx.sess, &cycle_error); handle_cycle_error(query, qcx, &cycle_error, error) } fn handle_cycle_error<'tcx, Q>( query: Q, - qcx: Q::Qcx, + qcx: QueryCtxt<'tcx>, cycle_error: &CycleError, error: Diag<'_>, ) -> Q::Value where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { match query.cycle_error_handling() { CycleErrorHandling::Error => { let guar = error.emit(); - query.value_from_cycle_error(*qcx.dep_context(), cycle_error, guar) + query.value_from_cycle_error(qcx.tcx, cycle_error, guar) } CycleErrorHandling::Fatal => { error.emit(); - qcx.dep_context().sess().dcx().abort_if_errors(); + qcx.tcx.dcx().abort_if_errors(); unreachable!() } CycleErrorHandling::DelayBug => { let guar = error.delay_as_bug(); - query.value_from_cycle_error(*qcx.dep_context(), cycle_error, guar) + query.value_from_cycle_error(qcx.tcx, cycle_error, guar) } CycleErrorHandling::Stash => { let guar = if let Some(root) = cycle_error.cycle.first() @@ -131,7 +134,7 @@ where } else { error.emit() }; - query.value_from_cycle_error(*qcx.dep_context(), cycle_error, guar) + query.value_from_cycle_error(qcx.tcx, cycle_error, guar) } } } @@ -204,12 +207,12 @@ where #[inline(never)] fn cycle_error<'tcx, Q>( query: Q, - qcx: Q::Qcx, + qcx: QueryCtxt<'tcx>, try_execute: QueryJobId, span: Span, ) -> (Q::Value, Option) where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { // Ensure there was no errors collecting all active jobs. // We need the complete map to ensure we find a cycle to break. @@ -225,19 +228,19 @@ where #[inline(always)] fn wait_for_query<'tcx, Q>( query: Q, - qcx: Q::Qcx, + qcx: QueryCtxt<'tcx>, span: Span, key: Q::Key, latch: QueryLatch<'tcx>, current: Option, ) -> (Q::Value, Option) where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { // For parallel queries, we'll block and wait until the query running // in another thread has completed. Record how long we wait in the // self-profiler. - let query_blocked_prof_timer = qcx.dep_context().profiler().query_blocked(); + let query_blocked_prof_timer = qcx.tcx.prof.query_blocked(); // With parallel queries we might just have to wait on some other // thread. @@ -262,7 +265,7 @@ where }) }; - qcx.dep_context().profiler().query_cache_hit(index.into()); + qcx.tcx.prof.query_cache_hit(index.into()); query_blocked_prof_timer.finish_with_query_invocation_id(index.into()); (v, Some(index)) @@ -274,13 +277,13 @@ where #[inline(never)] fn try_execute_query<'tcx, Q, const INCR: bool>( query: Q, - qcx: Q::Qcx, + qcx: QueryCtxt<'tcx>, span: Span, key: Q::Key, dep_node: Option, ) -> (Q::Value, Option) where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { let state = query.query_state(qcx); let key_hash = sharded::make_hash(&key); @@ -292,9 +295,9 @@ where // re-executing the query since `try_start` only checks that the query is not currently // executing, but another thread may have already completed the query and stores it result // in the query cache. - if qcx.dep_context().sess().threads() > 1 { + if qcx.tcx.sess.threads() > 1 { if let Some((value, index)) = query.query_cache(qcx).lookup(&key) { - qcx.dep_context().profiler().query_cache_hit(index.into()); + qcx.tcx.prof.query_cache_hit(index.into()); return (value, Some(index)); } } @@ -343,7 +346,7 @@ where #[inline(always)] fn execute_job<'tcx, Q, const INCR: bool>( query: Q, - qcx: Q::Qcx, + qcx: QueryCtxt<'tcx>, state: &'tcx QueryState<'tcx, Q::Key>, key: Q::Key, key_hash: u64, @@ -351,22 +354,15 @@ fn execute_job<'tcx, Q, const INCR: bool>( dep_node: Option, ) -> (Q::Value, Option) where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { // Use `JobOwner` so the query will be poisoned if executing it panics. let job_owner = JobOwner { state, key }; - debug_assert_eq!(qcx.dep_context().dep_graph().is_fully_enabled(), INCR); + debug_assert_eq!(qcx.tcx.dep_graph.is_fully_enabled(), INCR); let (result, dep_node_index) = if INCR { - execute_job_incr( - query, - qcx, - qcx.dep_context().dep_graph().data().unwrap(), - key, - dep_node, - id, - ) + execute_job_incr(query, qcx, qcx.tcx.dep_graph.data().unwrap(), key, dep_node, id) } else { execute_job_non_incr(query, qcx, key, id) }; @@ -395,7 +391,7 @@ where // We have an inconsistency. This can happen if one of the two // results is tainted by errors. assert!( - qcx.dep_context().sess().dcx().has_errors().is_some(), + qcx.tcx.dcx().has_errors().is_some(), "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ computed={:#?}\nfed={:#?}", query.dep_kind(), @@ -415,24 +411,24 @@ where #[inline(always)] fn execute_job_non_incr<'tcx, Q>( query: Q, - qcx: Q::Qcx, + qcx: QueryCtxt<'tcx>, key: Q::Key, job_id: QueryJobId, ) -> (Q::Value, DepNodeIndex) where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { - debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled()); + debug_assert!(!qcx.tcx.dep_graph.is_fully_enabled()); // Fingerprint the key, just to assert that it doesn't // have anything we don't consider hashable if cfg!(debug_assertions) { - let _ = key.to_fingerprint(*qcx.dep_context()); + let _ = key.to_fingerprint(qcx.tcx); } - let prof_timer = qcx.dep_context().profiler().query_provider(); + let prof_timer = qcx.tcx.prof.query_provider(); let result = qcx.start_query(job_id, query.depth_limit(), || query.compute(qcx, key)); - let dep_node_index = qcx.dep_context().dep_graph().next_virtual_depnode_index(); + let dep_node_index = qcx.tcx.dep_graph.next_virtual_depnode_index(); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); // Similarly, fingerprint the result to assert that @@ -451,19 +447,18 @@ where #[inline(always)] fn execute_job_incr<'tcx, Q>( query: Q, - qcx: Q::Qcx, - dep_graph_data: &DepGraphData<::Deps>, + qcx: QueryCtxt<'tcx>, + dep_graph_data: &DepGraphData, key: Q::Key, mut dep_node_opt: Option, job_id: QueryJobId, ) -> (Q::Value, DepNodeIndex) where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { if !query.anon() && !query.eval_always() { // `to_dep_node` is expensive for some `DepKind`s. - let dep_node = - dep_node_opt.get_or_insert_with(|| query.construct_dep_node(*qcx.dep_context(), &key)); + let dep_node = dep_node_opt.get_or_insert_with(|| query.construct_dep_node(qcx.tcx, &key)); // The diagnostics for this query will be promoted to the current session during // `try_mark_green()`, so we can ignore them here. @@ -474,20 +469,16 @@ where } } - let prof_timer = qcx.dep_context().profiler().query_provider(); + let prof_timer = qcx.tcx.prof.query_provider(); let (result, dep_node_index) = qcx.start_query(job_id, query.depth_limit(), || { if query.anon() { - return dep_graph_data.with_anon_task_inner( - *qcx.dep_context(), - query.dep_kind(), - || query.compute(qcx, key), - ); + return dep_graph_data + .with_anon_task_inner(qcx.tcx, query.dep_kind(), || query.compute(qcx, key)); } // `to_dep_node` is expensive for some `DepKind`s. - let dep_node = - dep_node_opt.unwrap_or_else(|| query.construct_dep_node(*qcx.dep_context(), &key)); + let dep_node = dep_node_opt.unwrap_or_else(|| query.construct_dep_node(qcx.tcx, &key)); dep_graph_data.with_task( dep_node, @@ -506,13 +497,13 @@ where #[inline(always)] fn try_load_from_disk_and_cache_in_memory<'tcx, Q>( query: Q, - dep_graph_data: &DepGraphData<::Deps>, - qcx: Q::Qcx, + dep_graph_data: &DepGraphData, + qcx: QueryCtxt<'tcx>, key: &Q::Key, dep_node: &DepNode, ) -> Option<(Q::Value, DepNodeIndex)> where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { // Note this function can be called concurrently from the same query // We must ensure that this is handled correctly. @@ -524,7 +515,7 @@ where // First we try to load the result from the on-disk cache. // Some things are never cached on disk. if let Some(result) = query.try_load_from_disk(qcx, key, prev_dep_node_index, dep_node_index) { - if std::intrinsics::unlikely(qcx.dep_context().sess().opts.unstable_opts.query_dep_graph) { + if std::intrinsics::unlikely(qcx.tcx.sess.opts.unstable_opts.query_dep_graph) { dep_graph_data.mark_debug_loaded_from_disk(*dep_node) } @@ -538,10 +529,10 @@ where // give us some coverage of potential bugs though. let try_verify = prev_fingerprint.split().1.as_u64().is_multiple_of(32); if std::intrinsics::unlikely( - try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich, + try_verify || qcx.tcx.sess.opts.unstable_opts.incremental_verify_ich, ) { incremental_verify_ich( - *qcx.dep_context(), + qcx.tcx, dep_graph_data, &result, prev_dep_node_index, @@ -556,7 +547,7 @@ where // We always expect to find a cached result for things that // can be forced from `DepNode`. debug_assert!( - !query.will_cache_on_disk_for_key(*qcx.dep_context(), key) + !query.will_cache_on_disk_for_key(qcx.tcx, key) || !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(), "missing on-disk cache entry for {dep_node:?}" ); @@ -570,10 +561,10 @@ where // We could not load a result from the on-disk cache, so // recompute. - let prof_timer = qcx.dep_context().profiler().query_provider(); + let prof_timer = qcx.tcx.prof.query_provider(); // The dep-graph for this computation is already in-place. - let result = qcx.dep_context().dep_graph().with_ignore(|| query.compute(qcx, *key)); + let result = qcx.tcx.dep_graph.with_ignore(|| query.compute(qcx, *key)); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -587,7 +578,7 @@ where // See issue #82920 for an example of a miscompilation that would get turned into // an ICE by this check incremental_verify_ich( - *qcx.dep_context(), + qcx.tcx, dep_graph_data, &result, prev_dep_node_index, @@ -609,12 +600,12 @@ where #[inline(never)] fn ensure_must_run<'tcx, Q>( query: Q, - qcx: Q::Qcx, + qcx: QueryCtxt<'tcx>, key: &Q::Key, check_cache: bool, ) -> (bool, Option) where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { if query.eval_always() { return (true, None); @@ -623,9 +614,9 @@ where // Ensuring an anonymous query makes no sense assert!(!query.anon()); - let dep_node = query.construct_dep_node(*qcx.dep_context(), key); + let dep_node = query.construct_dep_node(qcx.tcx, key); - let dep_graph = qcx.dep_context().dep_graph(); + let dep_graph = &qcx.tcx.dep_graph; let serialized_dep_node_index = match dep_graph.try_mark_green(qcx, &dep_node) { None => { // A None return from `try_mark_green` means that this is either @@ -638,7 +629,7 @@ where } Some((serialized_dep_node_index, dep_node_index)) => { dep_graph.read_index(dep_node_index); - qcx.dep_context().profiler().query_cache_hit(dep_node_index.into()); + qcx.tcx.prof.query_cache_hit(dep_node_index.into()); serialized_dep_node_index } }; @@ -655,14 +646,14 @@ where #[inline(always)] pub(super) fn get_query_non_incr<'tcx, Q>( query: Q, - qcx: Q::Qcx, + qcx: QueryCtxt<'tcx>, span: Span, key: Q::Key, ) -> Q::Value where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { - debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled()); + debug_assert!(!qcx.tcx.dep_graph.is_fully_enabled()); ensure_sufficient_stack(|| try_execute_query::(query, qcx, span, key, None).0) } @@ -670,15 +661,15 @@ where #[inline(always)] pub(super) fn get_query_incr<'tcx, Q>( query: Q, - qcx: Q::Qcx, + qcx: QueryCtxt<'tcx>, span: Span, key: Q::Key, mode: QueryMode, ) -> Option where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { - debug_assert!(qcx.dep_context().dep_graph().is_fully_enabled()); + debug_assert!(qcx.tcx.dep_graph.is_fully_enabled()); let dep_node = if let QueryMode::Ensure { check_cache } = mode { let (must_run, dep_node) = ensure_must_run(query, qcx, &key, check_cache); @@ -693,19 +684,19 @@ where let (result, dep_node_index) = ensure_sufficient_stack(|| try_execute_query::(query, qcx, span, key, dep_node)); if let Some(dep_node_index) = dep_node_index { - qcx.dep_context().dep_graph().read_index(dep_node_index) + qcx.tcx.dep_graph.read_index(dep_node_index) } Some(result) } -pub(super) fn force_query<'tcx, Q>(query: Q, qcx: Q::Qcx, key: Q::Key, dep_node: DepNode) +pub(super) fn force_query<'tcx, Q>(query: Q, qcx: QueryCtxt<'tcx>, key: Q::Key, dep_node: DepNode) where - Q: QueryDispatcher<'tcx>, + Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, { // We may be concurrently trying both execute and force a query. // Ensure that only one of them runs the query. if let Some((_, index)) = query.query_cache(qcx).lookup(&key) { - qcx.dep_context().profiler().query_cache_hit(index.into()); + qcx.tcx.prof.query_cache_hit(index.into()); return; } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 8738370dd1e7..676d01be3385 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -14,7 +14,8 @@ use rustc_hir::limit::Limit; use rustc_index::Idx; use rustc_middle::bug; use rustc_middle::dep_graph::{ - self, DepContext, DepKindVTable, DepNode, DepNodeIndex, SerializedDepNodeIndex, dep_kinds, + self, DepContext, DepKindVTable, DepNode, DepNodeIndex, DepsType, SerializedDepNodeIndex, + dep_kinds, }; use rustc_middle::query::Key; use rustc_middle::query::on_disk_cache::{ @@ -69,10 +70,57 @@ impl<'tcx> QueryCtxt<'tcx> { crate_name: self.tcx.crate_name(LOCAL_CRATE), }); } + + #[inline] + pub(crate) fn next_job_id(self) -> QueryJobId { + QueryJobId( + NonZero::new( + self.tcx.query_system.jobs.fetch_add(1, std::sync::atomic::Ordering::Relaxed), + ) + .unwrap(), + ) + } + + #[inline] + pub(crate) fn current_query_job(self) -> Option { + tls::with_related_context(self.tcx, |icx| icx.query) + } + + /// Executes a job by changing the `ImplicitCtxt` to point to the + /// new query job while it executes. + #[inline(always)] + pub(crate) fn start_query( + self, + token: QueryJobId, + depth_limit: bool, + compute: impl FnOnce() -> R, + ) -> R { + // The `TyCtxt` stored in TLS has the same global interner lifetime + // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes + // when accessing the `ImplicitCtxt`. + tls::with_related_context(self.tcx, move |current_icx| { + if depth_limit + && !self.tcx.recursion_limit().value_within_limit(current_icx.query_depth) + { + self.depth_limit_error(token); + } + + // Update the `ImplicitCtxt` to point to our new query job. + let new_icx = ImplicitCtxt { + tcx: self.tcx, + query: Some(token), + query_depth: current_icx.query_depth + depth_limit as usize, + task_deps: current_icx.task_deps, + }; + + // Use the `ImplicitCtxt` while we execute the query. + tls::enter_context(&new_icx, compute) + }) + } } impl<'tcx> HasDepContext for QueryCtxt<'tcx> { - type Deps = rustc_middle::dep_graph::DepsType; + type Deps = DepsType; type DepContext = TyCtxt<'tcx>; #[inline] @@ -87,21 +135,6 @@ impl<'tcx> QueryContext<'tcx> for QueryCtxt<'tcx> { &self.tcx.jobserver_proxy } - #[inline] - fn next_job_id(self) -> QueryJobId { - QueryJobId( - NonZero::new( - self.tcx.query_system.jobs.fetch_add(1, std::sync::atomic::Ordering::Relaxed), - ) - .unwrap(), - ) - } - - #[inline] - fn current_query_job(self) -> Option { - tls::with_related_context(self.tcx, |icx| icx.query) - } - /// Returns a map of currently active query jobs, collected from all queries. /// /// If `require_complete` is `true`, this function locks all shards of the @@ -147,38 +180,6 @@ impl<'tcx> QueryContext<'tcx> for QueryCtxt<'tcx> { c.store_side_effect(dep_node_index, side_effect) } } - - /// Executes a job by changing the `ImplicitCtxt` to point to the - /// new query job while it executes. - #[inline(always)] - fn start_query( - self, - token: QueryJobId, - depth_limit: bool, - compute: impl FnOnce() -> R, - ) -> R { - // The `TyCtxt` stored in TLS has the same global interner lifetime - // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes - // when accessing the `ImplicitCtxt`. - tls::with_related_context(self.tcx, move |current_icx| { - if depth_limit - && !self.tcx.recursion_limit().value_within_limit(current_icx.query_depth) - { - self.depth_limit_error(token); - } - - // Update the `ImplicitCtxt` to point to our new query job. - let new_icx = ImplicitCtxt { - tcx: self.tcx, - query: Some(token), - query_depth: current_icx.query_depth + depth_limit as usize, - task_deps: current_icx.task_deps, - }; - - // Use the `ImplicitCtxt` while we execute the query. - tls::enter_context(&new_icx, compute) - }) - } } pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool { diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 3eea0717f409..29a572b726f0 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -161,11 +161,6 @@ pub trait QueryContext<'tcx>: HasDepContext { /// a token while waiting on a query. fn jobserver_proxy(&self) -> &Proxy; - fn next_job_id(self) -> QueryJobId; - - /// Get the query information from the TLS context. - fn current_query_job(self) -> Option; - fn collect_active_jobs_from_all_queries( self, require_complete: bool, @@ -179,9 +174,4 @@ pub trait QueryContext<'tcx>: HasDepContext { /// Register a side effect for the given node, for use in next session. fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect); - - /// Executes a job by changing the `ImplicitCtxt` to point to the - /// new query job while it executes. - fn start_query(self, token: QueryJobId, depth_limit: bool, compute: impl FnOnce() -> R) - -> R; } From 118372ed1325f07ebc4ec9c3f28e3f00d4519a05 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 8 Feb 2026 18:15:53 +1100 Subject: [PATCH 3388/3801] Replace some `feature(core_intrinsics)` with stable hints --- compiler/rustc_arena/src/lib.rs | 5 ++--- compiler/rustc_data_structures/src/lib.rs | 2 +- compiler/rustc_data_structures/src/profiling.rs | 9 +++++---- compiler/rustc_data_structures/src/sync/freeze.rs | 5 +++-- compiler/rustc_data_structures/src/sync/lock.rs | 9 +++++---- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 6217bf46a942..97dd21db07e7 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -13,7 +13,6 @@ #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] #![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))] -#![feature(core_intrinsics)] #![feature(decl_macro)] #![feature(dropck_eyepatch)] #![feature(never_type)] @@ -26,7 +25,7 @@ use std::cell::{Cell, RefCell}; use std::marker::PhantomData; use std::mem::{self, MaybeUninit}; use std::ptr::{self, NonNull}; -use std::{cmp, intrinsics, slice}; +use std::{cmp, hint, slice}; use smallvec::SmallVec; @@ -452,7 +451,7 @@ impl DroplessArena { let bytes = align_up(layout.size(), DROPLESS_ALIGNMENT); // Tell LLVM that `end` is aligned to DROPLESS_ALIGNMENT. - unsafe { intrinsics::assume(end == align_down(end, DROPLESS_ALIGNMENT)) }; + unsafe { hint::assert_unchecked(end == align_down(end, DROPLESS_ALIGNMENT)) }; if let Some(sub) = end.checked_sub(bytes) { let new_end = align_down(sub, layout.align()); diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 4467a2811181..bef19d77d1e7 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -10,6 +10,7 @@ #![allow(internal_features)] #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] +#![cfg_attr(bootstrap, feature(cold_path))] #![deny(unsafe_op_in_unsafe_fn)] #![feature(allocator_api)] #![feature(ascii_char)] @@ -19,7 +20,6 @@ #![feature(cfg_select)] #![feature(const_default)] #![feature(const_trait_impl)] -#![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(extend_one)] #![feature(file_buffered)] diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index b04caa69adfb..cab57edb8946 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -85,12 +85,11 @@ use std::borrow::Borrow; use std::collections::hash_map::Entry; use std::error::Error; use std::fmt::Display; -use std::intrinsics::unlikely; use std::path::Path; use std::sync::Arc; use std::sync::atomic::Ordering; use std::time::{Duration, Instant}; -use std::{fs, process}; +use std::{fs, hint, process}; pub use measureme::EventId; use measureme::{EventIdBuilder, Profiler, SerializableString, StringId}; @@ -427,7 +426,8 @@ impl SelfProfilerRef { .unwrap() .increment_query_cache_hit_counters(QueryInvocationId(query_invocation_id.0)); } - if unlikely(profiler_ref.event_filter_mask.contains(EventFilter::QUERY_CACHE_HITS)) { + if profiler_ref.event_filter_mask.contains(EventFilter::QUERY_CACHE_HITS) { + hint::cold_path(); profiler_ref.instant_query_event( |profiler| profiler.query_cache_hit_event_kind, query_invocation_id, @@ -437,7 +437,8 @@ impl SelfProfilerRef { // We check both kinds of query cache hit events at once, to reduce overhead in the // common case (with self-profile disabled). - if unlikely(self.event_filter_mask.intersects(EventFilter::QUERY_CACHE_HIT_COMBINED)) { + if self.event_filter_mask.intersects(EventFilter::QUERY_CACHE_HIT_COMBINED) { + hint::cold_path(); cold_call(self, query_invocation_id); } } diff --git a/compiler/rustc_data_structures/src/sync/freeze.rs b/compiler/rustc_data_structures/src/sync/freeze.rs index 6338afb92c34..fb2dcb25556a 100644 --- a/compiler/rustc_data_structures/src/sync/freeze.rs +++ b/compiler/rustc_data_structures/src/sync/freeze.rs @@ -1,5 +1,5 @@ use std::cell::UnsafeCell; -use std::intrinsics::likely; +use std::hint; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::ptr::NonNull; @@ -60,10 +60,11 @@ impl FreezeLock { /// Get the inner value if frozen. #[inline] pub fn get(&self) -> Option<&T> { - if likely(self.frozen.load(Ordering::Acquire)) { + if self.frozen.load(Ordering::Acquire) { // SAFETY: This is frozen so the data cannot be modified. unsafe { Some(&*self.data.get()) } } else { + hint::cold_path(); None } } diff --git a/compiler/rustc_data_structures/src/sync/lock.rs b/compiler/rustc_data_structures/src/sync/lock.rs index a8161c515115..f183af0c0dab 100644 --- a/compiler/rustc_data_structures/src/sync/lock.rs +++ b/compiler/rustc_data_structures/src/sync/lock.rs @@ -1,7 +1,7 @@ //! This module implements a lock which only uses synchronization if `might_be_dyn_thread_safe` is true. //! It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync` traits. -use std::fmt; +use std::{fmt, hint}; #[derive(Clone, Copy, PartialEq)] pub enum Mode { @@ -10,7 +10,6 @@ pub enum Mode { } use std::cell::{Cell, UnsafeCell}; -use std::intrinsics::unlikely; use std::marker::PhantomData; use std::mem::ManuallyDrop; use std::ops::{Deref, DerefMut}; @@ -92,7 +91,8 @@ pub struct Lock { impl Lock { #[inline(always)] pub fn new(inner: T) -> Self { - let (mode, mode_union) = if unlikely(mode::might_be_dyn_thread_safe()) { + let (mode, mode_union) = if mode::might_be_dyn_thread_safe() { + hint::cold_path(); // Create the lock with synchronization enabled using the `RawMutex` type. (Mode::Sync, ModeUnion { sync: ManuallyDrop::new(RawMutex::INIT) }) } else { @@ -150,7 +150,8 @@ impl Lock { unsafe { match mode { Mode::NoSync => { - if unlikely(self.mode_union.no_sync.replace(LOCKED) == LOCKED) { + if self.mode_union.no_sync.replace(LOCKED) == LOCKED { + hint::cold_path(); lock_held() } } From 7c95f57bc95c36f44a50fffb07cb2b933184ee2b Mon Sep 17 00:00:00 2001 From: mikhailofff Date: Sun, 8 Feb 2026 11:25:51 +0400 Subject: [PATCH 3389/3801] fix outdated doc comments --- book/src/development/type_checking.md | 2 +- tests/ui/unconditional_recursion.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/development/type_checking.md b/book/src/development/type_checking.md index 578836ecc568..d1c88619d598 100644 --- a/book/src/development/type_checking.md +++ b/book/src/development/type_checking.md @@ -154,7 +154,7 @@ in this chapter: [expr_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.expr_ty [node_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.node_type [is_char]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.is_char -[is_char_source]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_middle/ty/sty.rs.html#1831-1834 +[is_char_source]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_middle/ty/sty.rs.html#1429-1432 [kind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.kind [LateContext]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LateContext.html [LateLintPass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html diff --git a/tests/ui/unconditional_recursion.rs b/tests/ui/unconditional_recursion.rs index d9f4c07dc902..09a0de21ccd0 100644 --- a/tests/ui/unconditional_recursion.rs +++ b/tests/ui/unconditional_recursion.rs @@ -334,7 +334,7 @@ mod issue12154 { } // Not necessarily related to the issue but another FP from the http crate that was fixed with it: - // https://docs.rs/http/latest/src/http/header/name.rs.html#1424 + // https://docs.rs/http/latest/src/http/header/name.rs.html#1408 // We used to simply peel refs from the LHS and RHS, so we couldn't differentiate // between `PartialEq for &T` and `PartialEq<&T> for T` impls. #[derive(PartialEq)] From 6b1ed212b70be56296d3aadba518028e6049eb56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 8 Feb 2026 09:16:31 +0100 Subject: [PATCH 3390/3801] Remove types adhoc group --- triagebot.toml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 4a4054391ce7..43db49873c4d 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1536,13 +1536,6 @@ mir-opt = [ "@wesleywiser", "@saethlin", ] -types = [ - "@jackh726", - "@lcnr", - "@oli-obk", - "@spastorino", - "@BoxyUwU", -] borrowck = [ "@davidtwco", "@matthewjasper" From c19c780d4557f4d1e2ee285c08184e9c37070c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 8 Feb 2026 09:22:24 +0100 Subject: [PATCH 3391/3801] Remove project-const-traits adhoc group --- triagebot.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 43db49873c4d..d6106024a1fd 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1555,11 +1555,6 @@ style-team = [ "@joshtriplett", "@traviscross", ] -project-const-traits = [ - "@fee1-dead", - "@fmease", - "@oli-obk", -] project-stable-mir = [ "@celinval", "@oli-obk", From 5e33ea7b926a8ed4f6228588564e036fba792897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 8 Feb 2026 09:23:04 +0100 Subject: [PATCH 3392/3801] Remove project-stable-mir adhoc group --- triagebot.toml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index d6106024a1fd..f2e69b625a81 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1555,12 +1555,6 @@ style-team = [ "@joshtriplett", "@traviscross", ] -project-stable-mir = [ - "@celinval", - "@oli-obk", - "@scottmcm", - "@makai410", -] project-exploit-mitigations = [ "@cuviper", "@rcvalle", From f46032089a94f7185823b0b519529d50311ff489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 8 Feb 2026 09:24:38 +0100 Subject: [PATCH 3393/3801] Remove project-exploit-mitigations adhoc group --- triagebot.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index f2e69b625a81..98e88f4e2e9b 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1555,10 +1555,6 @@ style-team = [ "@joshtriplett", "@traviscross", ] -project-exploit-mitigations = [ - "@cuviper", - "@rcvalle", -] compiletest = [ "@jieyouxu", ] From 5862618fab1bd3e6c904914db953bdf56720c28e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 8 Feb 2026 09:52:34 +0100 Subject: [PATCH 3394/3801] Remove the compiler adhoc group --- triagebot.toml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 4a4054391ce7..43f56a71cf4e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1449,29 +1449,6 @@ compiler_leads = [ "@davidtwco", "@wesleywiser", ] -compiler = [ - "@BoxyUwU", - "@chenyukang", - "@davidtwco", - "@eholk", - "@fee1-dead", - "@fmease", - "@jackh726", - "@jieyouxu", - "@jdonszelmann", - "@JonathanBrouwer", - "@madsmtm", - "@mati865", - "@Nadrieril", - "@nnethercote", - "@oli-obk", - "@petrochenkov", - "@SparrowLii", - "@TaKO8Ki", - "@tiif", - "@WaffleLapkin", - "@wesleywiser", -] libs = [ "@Mark-Simulacrum", "@workingjubilee", From 953aa57c7503177f494dfb168306503867aa26fc Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 8 Feb 2026 10:23:31 +0100 Subject: [PATCH 3395/3801] Fix suggestion on `AutoTraitItems` diagnostic --- compiler/rustc_ast_passes/src/errors.rs | 2 +- tests/ui/auto-traits/assoc-ty.current.stderr | 9 +++++---- tests/ui/auto-traits/assoc-ty.next.stderr | 11 ++++++----- tests/ui/auto-traits/assoc-ty.rs | 5 ++++- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index baf6f6beaeed..9f66641b550c 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -503,7 +503,7 @@ pub(crate) struct AutoTraitItems { #[primary_span] pub spans: Vec, #[suggestion( - "remove the super traits or lifetime bounds", + "remove the associated items", code = "", applicability = "machine-applicable", style = "tool-only" diff --git a/tests/ui/auto-traits/assoc-ty.current.stderr b/tests/ui/auto-traits/assoc-ty.current.stderr index d793ae665267..5d3df17d26b1 100644 --- a/tests/ui/auto-traits/assoc-ty.current.stderr +++ b/tests/ui/auto-traits/assoc-ty.current.stderr @@ -1,9 +1,9 @@ error[E0380]: auto traits cannot have associated items - --> $DIR/assoc-ty.rs:10:10 + --> $DIR/assoc-ty.rs:11:10 | LL | auto trait Trait { | ----- auto traits cannot have associated items -LL | +... LL | type Output; | ^^^^^^ @@ -12,8 +12,9 @@ error[E0658]: auto traits are experimental and possibly buggy | LL | / auto trait Trait { LL | | -LL | | type Output; LL | | +LL | | type Output; +... | LL | | } | |_^ | @@ -22,7 +23,7 @@ LL | | } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0308]: mismatched types - --> $DIR/assoc-ty.rs:15:36 + --> $DIR/assoc-ty.rs:17:36 | LL | let _: <() as Trait>::Output = (); | --------------------- ^^ expected associated type, found `()` diff --git a/tests/ui/auto-traits/assoc-ty.next.stderr b/tests/ui/auto-traits/assoc-ty.next.stderr index a41f7d992785..19621064aa42 100644 --- a/tests/ui/auto-traits/assoc-ty.next.stderr +++ b/tests/ui/auto-traits/assoc-ty.next.stderr @@ -1,9 +1,9 @@ error[E0380]: auto traits cannot have associated items - --> $DIR/assoc-ty.rs:10:10 + --> $DIR/assoc-ty.rs:11:10 | LL | auto trait Trait { | ----- auto traits cannot have associated items -LL | +... LL | type Output; | ^^^^^^ @@ -12,8 +12,9 @@ error[E0658]: auto traits are experimental and possibly buggy | LL | / auto trait Trait { LL | | -LL | | type Output; LL | | +LL | | type Output; +... | LL | | } | |_^ | @@ -22,13 +23,13 @@ LL | | } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _` - --> $DIR/assoc-ty.rs:15:12 + --> $DIR/assoc-ty.rs:17:12 | LL | let _: <() as Trait>::Output = (); | ^^^^^^^^^^^^^^^^^^^^^ types differ error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _` - --> $DIR/assoc-ty.rs:15:12 + --> $DIR/assoc-ty.rs:17:12 | LL | let _: <() as Trait>::Output = (); | ^^^^^^^^^^^^^^^^^^^^^ types differ diff --git a/tests/ui/auto-traits/assoc-ty.rs b/tests/ui/auto-traits/assoc-ty.rs index efbfead9cd03..98a86d9a7540 100644 --- a/tests/ui/auto-traits/assoc-ty.rs +++ b/tests/ui/auto-traits/assoc-ty.rs @@ -7,13 +7,16 @@ auto trait Trait { //~^ ERROR auto traits are experimental and possibly buggy + //~| HELP add `#![feature(auto_traits)]` to the crate attributes to enable type Output; //~^ ERROR auto traits cannot have associated items + //~| HELP remove the associated items } fn main() { let _: <() as Trait>::Output = (); //[current]~^ ERROR mismatched types - //[next]~^^ ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _` + //[current]~| HELP consider constraining the associated type `<() as Trait>::Output` to `()` or calling a method that returns `<() as Trait>::Output` + //[next]~^^^ ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _` //[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _` } From ea8733133cacf4496a2766b3d002492cc29ea7bf Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 18:27:38 +0100 Subject: [PATCH 3396/3801] Remove `DiagMessage::FluentIdentifier` --- compiler/rustc_error_messages/src/lib.rs | 41 ++------------ compiler/rustc_errors/src/translation.rs | 72 ++---------------------- 2 files changed, 8 insertions(+), 105 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 641defd1eabf..916a370659aa 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -230,9 +230,6 @@ pub fn fallback_fluent_bundle( }))) } -/// Identifier for the Fluent message/attribute corresponding to a diagnostic message. -type FluentId = Cow<'static, str>; - /// Abstraction over a message in a subdiagnostic (i.e. label, note, help, etc) to support both /// translatable and non-translatable diagnostic messages. /// @@ -244,18 +241,9 @@ type FluentId = Cow<'static, str>; pub enum SubdiagMessage { /// Non-translatable diagnostic message. Str(Cow<'static, str>), - /// Identifier of a Fluent message. Instances of this variant are generated by the - /// `Subdiagnostic` derive. - FluentIdentifier(FluentId), /// An inline Fluent message. Instances of this variant are generated by the /// `Subdiagnostic` derive. Inline(Cow<'static, str>), - /// Attribute of a Fluent message. Needs to be combined with a Fluent identifier to produce an - /// actual translated message. Instances of this variant are generated by the `fluent_messages` - /// macro. - /// - /// - FluentAttr(FluentId), } impl From for SubdiagMessage { @@ -288,12 +276,6 @@ pub enum DiagMessage { /// are translated when they are added to the parent diagnostic. This is one of the ways /// this variant of `DiagMessage` is produced. Str(Cow<'static, str>), - /// Identifier for a Fluent message (with optional attribute) corresponding to the diagnostic - /// message. Yet to be translated. - /// - /// - /// - FluentIdentifier(FluentId, Option), /// An inline Fluent message, containing the to be translated diagnostic message. Inline(Cow<'static, str>), } @@ -305,27 +287,16 @@ impl DiagMessage { /// - If the `SubdiagMessage` is non-translatable then return the message as a `DiagMessage`. /// - If `self` is non-translatable then return `self`'s message. pub fn with_subdiagnostic_message(&self, sub: SubdiagMessage) -> Self { - let attr = match sub { - SubdiagMessage::Str(s) => return DiagMessage::Str(s), - SubdiagMessage::FluentIdentifier(id) => { - return DiagMessage::FluentIdentifier(id, None); - } - SubdiagMessage::Inline(s) => return DiagMessage::Inline(s), - SubdiagMessage::FluentAttr(attr) => attr, - }; - - match self { - DiagMessage::FluentIdentifier(id, _) => { - DiagMessage::FluentIdentifier(id.clone(), Some(attr)) - } - _ => panic!("Tried to add a subdiagnostic to a message without a fluent identifier"), + match sub { + SubdiagMessage::Str(s) => DiagMessage::Str(s), + SubdiagMessage::Inline(s) => DiagMessage::Inline(s), } } pub fn as_str(&self) -> Option<&str> { match self { DiagMessage::Str(s) => Some(s), - DiagMessage::FluentIdentifier(_, _) | DiagMessage::Inline(_) => None, + DiagMessage::Inline(_) => None, } } } @@ -355,10 +326,6 @@ impl From for SubdiagMessage { fn from(val: DiagMessage) -> Self { match val { DiagMessage::Str(s) => SubdiagMessage::Str(s), - DiagMessage::FluentIdentifier(id, None) => SubdiagMessage::FluentIdentifier(id), - // There isn't really a sensible behaviour for this because it loses information but - // this is the most sensible of the behaviours. - DiagMessage::FluentIdentifier(_, Some(attr)) => SubdiagMessage::FluentAttr(attr), DiagMessage::Inline(s) => SubdiagMessage::Inline(s), } } diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index ed3f9a405342..0b9845772590 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::env; use std::error::Report; use std::sync::Arc; @@ -7,7 +6,7 @@ pub use rustc_error_messages::{FluentArgs, LazyFallbackBundle}; use rustc_error_messages::{langid, register_functions}; use tracing::{debug, trace}; -use crate::error::{TranslateError, TranslateErrorKind}; +use crate::error::TranslateError; use crate::fluent_bundle::FluentResource; use crate::{DiagArg, DiagMessage, FluentBundle, Style, fluent_bundle}; @@ -76,11 +75,8 @@ impl Translator { args: &'a FluentArgs<'_>, ) -> Result, TranslateError<'a>> { trace!(?message, ?args); - let (identifier, attr) = match message { - DiagMessage::Str(msg) => { - return Ok(Cow::Borrowed(msg)); - } - DiagMessage::FluentIdentifier(identifier, attr) => (identifier, attr), + match message { + DiagMessage::Str(msg) => Ok(Cow::Borrowed(msg)), // This translates an inline fluent diagnostic message // It does this by creating a new `FluentBundle` with only one message, // and then translating using this bundle. @@ -98,71 +94,11 @@ impl Translator { let mut errs = vec![]; let translated = bundle.format_pattern(value, Some(args), &mut errs).to_string(); debug!(?translated, ?errs); - return if errs.is_empty() { + if errs.is_empty() { Ok(Cow::Owned(translated)) } else { Err(TranslateError::fluent(&Cow::Borrowed(GENERATED_MSG_ID), args, errs)) - }; - } - }; - let translate_with_bundle = - |bundle: &'a FluentBundle| -> Result, TranslateError<'_>> { - let message = bundle - .get_message(identifier) - .ok_or(TranslateError::message(identifier, args))?; - let value = match attr { - Some(attr) => message - .get_attribute(attr) - .ok_or(TranslateError::attribute(identifier, args, attr))? - .value(), - None => message.value().ok_or(TranslateError::value(identifier, args))?, - }; - debug!(?message, ?value); - - let mut errs = vec![]; - let translated = bundle.format_pattern(value, Some(args), &mut errs); - debug!(?translated, ?errs); - if errs.is_empty() { - Ok(translated) - } else { - Err(TranslateError::fluent(identifier, args, errs)) } - }; - - try { - match self.fluent_bundle.as_ref().map(|b| translate_with_bundle(b)) { - // The primary bundle was present and translation succeeded - Some(Ok(t)) => t, - - // If `translate_with_bundle` returns `Err` with the primary bundle, this is likely - // just that the primary bundle doesn't contain the message being translated, so - // proceed to the fallback bundle. - Some(Err( - primary @ TranslateError::One { - kind: TranslateErrorKind::MessageMissing, .. - }, - )) => translate_with_bundle(&self.fallback_fluent_bundle) - .map_err(|fallback| primary.and(fallback))?, - - // Always yeet out for errors on debug (unless - // `RUSTC_TRANSLATION_NO_DEBUG_ASSERT` is set in the environment - this allows - // local runs of the test suites, of builds with debug assertions, to test the - // behaviour in a normal build). - Some(Err(primary)) - if cfg!(debug_assertions) - && env::var("RUSTC_TRANSLATION_NO_DEBUG_ASSERT").is_err() => - { - do yeet primary - } - - // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so - // just hide it and try with the fallback bundle. - Some(Err(primary)) => translate_with_bundle(&self.fallback_fluent_bundle) - .map_err(|fallback| primary.and(fallback))?, - - // The primary bundle is missing, proceed to the fallback bundle - None => translate_with_bundle(&self.fallback_fluent_bundle) - .map_err(|fallback| TranslateError::primary(identifier, args).and(fallback))?, } } } From 62dd37131f6f43d0dab3e26cf125cd841a08e003 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 19:04:18 +0100 Subject: [PATCH 3397/3801] Remove slugs from the `#[derive(Diagnostic)]` macro --- .../src/diagnostics/diagnostic.rs | 27 +---- .../src/diagnostics/diagnostic_builder.rs | 98 +++++-------------- .../rustc_macros/src/diagnostics/message.rs | 75 ++------------ .../src/diagnostics/subdiagnostic.rs | 22 ++--- .../rustc_macros/src/diagnostics/utils.rs | 43 +++----- 5 files changed, 60 insertions(+), 205 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index e8356655dd9f..dc8231e5f0b0 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -1,7 +1,5 @@ #![deny(unused_must_use)] -use std::cell::RefCell; - use proc_macro2::TokenStream; use quote::quote; use synstructure::Structure; @@ -22,7 +20,6 @@ impl<'a> DiagnosticDerive<'a> { pub(crate) fn into_tokens(self) -> TokenStream { let DiagnosticDerive { mut structure } = self; let kind = DiagnosticDeriveKind::Diagnostic; - let messages = RefCell::new(Vec::new()); let implementation = kind.each_variant(&mut structure, |mut builder, variant| { let preamble = builder.preamble(variant); let body = builder.body(variant); @@ -30,7 +27,6 @@ impl<'a> DiagnosticDerive<'a> { let Some(message) = builder.primary_message() else { return DiagnosticDeriveError::ErrorHandled.to_compile_error(); }; - messages.borrow_mut().push(message.clone()); let message = message.diag_message(Some(variant)); let init = quote! { @@ -52,9 +48,7 @@ impl<'a> DiagnosticDerive<'a> { }); // A lifetime of `'a` causes conflicts, but `_sess` is fine. - // FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here? - #[allow(keyword_idents_2024)] - let mut imp = structure.gen_impl(quote! { + structure.gen_impl(quote! { gen impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for @Self where G: rustc_errors::EmissionGuarantee { @@ -67,11 +61,7 @@ impl<'a> DiagnosticDerive<'a> { #implementation } } - }); - for test in messages.borrow().iter().map(|s| s.generate_test(&structure)) { - imp.extend(test); - } - imp + }) } } @@ -88,7 +78,6 @@ impl<'a> LintDiagnosticDerive<'a> { pub(crate) fn into_tokens(self) -> TokenStream { let LintDiagnosticDerive { mut structure } = self; let kind = DiagnosticDeriveKind::LintDiagnostic; - let messages = RefCell::new(Vec::new()); let implementation = kind.each_variant(&mut structure, |mut builder, variant| { let preamble = builder.preamble(variant); let body = builder.body(variant); @@ -96,7 +85,6 @@ impl<'a> LintDiagnosticDerive<'a> { let Some(message) = builder.primary_message() else { return DiagnosticDeriveError::ErrorHandled.to_compile_error(); }; - messages.borrow_mut().push(message.clone()); let message = message.diag_message(Some(variant)); let primary_message = quote! { diag.primary_message(#message); @@ -112,9 +100,7 @@ impl<'a> LintDiagnosticDerive<'a> { } }); - // FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here? - #[allow(keyword_idents_2024)] - let mut imp = structure.gen_impl(quote! { + structure.gen_impl(quote! { gen impl<'__a> rustc_errors::LintDiagnostic<'__a, ()> for @Self { #[track_caller] fn decorate_lint<'__b>( @@ -124,11 +110,6 @@ impl<'a> LintDiagnosticDerive<'a> { #implementation; } } - }); - for test in messages.borrow().iter().map(|s| s.generate_test(&structure)) { - imp.extend(test); - } - - imp + }) } } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 6107b181eea2..b386408a1918 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -4,7 +4,7 @@ use proc_macro2::{Ident, Span, TokenStream}; use quote::{format_ident, quote, quote_spanned}; use syn::parse::ParseStream; use syn::spanned::Spanned; -use syn::{Attribute, LitStr, Meta, Path, Token, Type, parse_quote}; +use syn::{Attribute, LitStr, Meta, Path, Token, Type}; use synstructure::{BindingInfo, Structure, VariantInfo}; use super::utils::SubdiagnosticVariant; @@ -109,24 +109,14 @@ impl DiagnosticDeriveVariantBuilder { pub(crate) fn primary_message(&self) -> Option<&Message> { match self.message.as_ref() { None => { - span_err(self.span, "diagnostic slug not specified") + span_err(self.span, "diagnostic message not specified") .help( - "specify the slug as the first argument to the `#[diag(...)]` \ - attribute, such as `#[diag(hir_analysis_example_error)]`", + "specify the message as the first argument to the `#[diag(...)]` \ + attribute, such as `#[diag(\"Example error\")]`", ) .emit(); None } - Some(Message::Slug(slug)) - if let Some(Mismatch { slug_name, crate_name, slug_prefix }) = - Mismatch::check(slug) => - { - span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") - .note(format!("slug is `{slug_name}` but the crate name is `{crate_name}`")) - .help(format!("expected a slug starting with `{slug_prefix}_...`")) - .emit(); - None - } Some(msg) => Some(msg), } } @@ -177,25 +167,15 @@ impl DiagnosticDeriveVariantBuilder { .help("consider creating a `Subdiagnostic` instead")); } - // For subdiagnostics without a message specified, insert a placeholder slug - let slug = subdiag.slug.unwrap_or_else(|| { - Message::Slug(match subdiag.kind { - SubdiagnosticKind::Label => parse_quote! { _subdiag::label }, - SubdiagnosticKind::Note => parse_quote! { _subdiag::note }, - SubdiagnosticKind::NoteOnce => parse_quote! { _subdiag::note_once }, - SubdiagnosticKind::Help => parse_quote! { _subdiag::help }, - SubdiagnosticKind::HelpOnce => parse_quote! { _subdiag::help_once }, - SubdiagnosticKind::Warn => parse_quote! { _subdiag::warn }, - SubdiagnosticKind::Suggestion { .. } => parse_quote! { _subdiag::suggestion }, - SubdiagnosticKind::MultipartSuggestion { .. } => unreachable!(), - }) - }); + let Some(message) = subdiag.message else { + throw_invalid_attr!(attr, |diag| diag.help("subdiagnostic message is missing")) + }; - Ok(Some((subdiag.kind, slug, false))) + Ok(Some((subdiag.kind, message, false))) } /// Establishes state in the `DiagnosticDeriveBuilder` resulting from the struct - /// attributes like `#[diag(..)]`, such as the slug and error code. Generates + /// attributes like `#[diag(..)]`, such as the message and error code. Generates /// diagnostic builder calls for setting error code and creating note/help messages. fn generate_structure_code_for_attr( &mut self, @@ -213,9 +193,6 @@ impl DiagnosticDeriveVariantBuilder { if name == "diag" { let mut tokens = TokenStream::new(); attr.parse_args_with(|input: ParseStream<'_>| { - let mut input = &*input; - let slug_recovery_point = input.fork(); - if input.peek(LitStr) { // Parse an inline message let message = input.parse::()?; @@ -226,15 +203,8 @@ impl DiagnosticDeriveVariantBuilder { ) .emit(); } - self.message = Some(Message::Inline(message.span(), message.value())); - } else { - // Parse a slug - let slug = input.parse::()?; - if input.is_empty() || input.peek(Token![,]) { - self.message = Some(Message::Slug(slug)); - } else { - input = &slug_recovery_point; - } + self.message = + Some(Message { message_span: message.span(), value: message.value() }); } // Parse arguments @@ -248,7 +218,7 @@ impl DiagnosticDeriveVariantBuilder { if input.peek(Token![,]) { span_err( arg_name.span().unwrap(), - "diagnostic slug must be the first argument", + "diagnostic message must be the first argument", ) .emit(); continue; @@ -265,7 +235,7 @@ impl DiagnosticDeriveVariantBuilder { } _ => { span_err(arg_name.span().unwrap(), "unknown argument") - .note("only the `code` parameter is valid after the slug") + .note("only the `code` parameter is valid after the message") .emit(); } } @@ -276,7 +246,7 @@ impl DiagnosticDeriveVariantBuilder { return Ok(tokens); } - let Some((subdiag, slug, _no_span)) = self.parse_subdiag_attribute(attr)? else { + let Some((subdiag, message, _no_span)) = self.parse_subdiag_attribute(attr)? else { // Some attributes aren't errors - like documentation comments - but also aren't // subdiagnostics. return Ok(quote! {}); @@ -287,7 +257,7 @@ impl DiagnosticDeriveVariantBuilder { | SubdiagnosticKind::NoteOnce | SubdiagnosticKind::Help | SubdiagnosticKind::HelpOnce - | SubdiagnosticKind::Warn => Ok(self.add_subdiagnostic(&fn_ident, slug, variant)), + | SubdiagnosticKind::Warn => Ok(self.add_subdiagnostic(&fn_ident, message, variant)), SubdiagnosticKind::Label | SubdiagnosticKind::Suggestion { .. } => { throw_invalid_attr!(attr, |diag| diag .help("`#[label]` and `#[suggestion]` can only be applied to fields")); @@ -406,7 +376,7 @@ impl DiagnosticDeriveVariantBuilder { _ => (), } - let Some((subdiag, slug, _no_span)) = self.parse_subdiag_attribute(attr)? else { + let Some((subdiag, message, _no_span)) = self.parse_subdiag_attribute(attr)? else { // Some attributes aren't errors - like documentation comments - but also aren't // subdiagnostics. return Ok(quote! {}); @@ -415,7 +385,7 @@ impl DiagnosticDeriveVariantBuilder { match subdiag { SubdiagnosticKind::Label => { report_error_if_not_applied_to_span(attr, &info)?; - Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug, variant)) + Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, message, variant)) } SubdiagnosticKind::Note | SubdiagnosticKind::NoteOnce @@ -426,11 +396,11 @@ impl DiagnosticDeriveVariantBuilder { if type_matches_path(inner, &["rustc_span", "Span"]) || type_matches_path(inner, &["rustc_span", "MultiSpan"]) { - Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug, variant)) + Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, message, variant)) } else if type_is_unit(inner) || (matches!(info.ty, FieldInnerTy::Plain(_)) && type_is_bool(inner)) { - Ok(self.add_subdiagnostic(&fn_ident, slug, variant)) + Ok(self.add_subdiagnostic(&fn_ident, message, variant)) } else { report_type_error(attr, "`Span`, `MultiSpan`, `bool` or `()`")? } @@ -456,7 +426,7 @@ impl DiagnosticDeriveVariantBuilder { applicability.set_once(quote! { #static_applicability }, span); } - let message = slug.diag_message(Some(variant)); + let message = message.diag_message(Some(variant)); let applicability = applicability .value() .unwrap_or_else(|| quote! { rustc_errors::Applicability::Unspecified }); @@ -477,7 +447,7 @@ impl DiagnosticDeriveVariantBuilder { } } - /// Adds a spanned subdiagnostic by generating a `diag.span_$kind` call with the current slug + /// Adds a spanned subdiagnostic by generating a `diag.span_$kind` call with the current message /// and `fluent_attr_identifier`. fn add_spanned_subdiagnostic( &self, @@ -496,7 +466,7 @@ impl DiagnosticDeriveVariantBuilder { } } - /// Adds a subdiagnostic by generating a `diag.span_$kind` call with the current slug + /// Adds a subdiagnostic by generating a `diag.span_$kind` call with the current message /// and `fluent_attr_identifier`. fn add_subdiagnostic( &self, @@ -567,27 +537,3 @@ impl DiagnosticDeriveVariantBuilder { } } } - -struct Mismatch { - slug_name: String, - crate_name: String, - slug_prefix: String, -} - -impl Mismatch { - /// Checks whether the slug starts with the crate name it's in. - fn check(slug: &syn::Path) -> Option { - // If this is missing we're probably in a test, so bail. - let crate_name = std::env::var("CARGO_CRATE_NAME").ok()?; - - // If we're not in a "rustc_" crate, bail. - let Some(("rustc", slug_prefix)) = crate_name.split_once('_') else { return None }; - - let slug_name = slug.segments.first()?.ident.to_string(); - if slug_name.starts_with(slug_prefix) { - return None; - } - - Some(Mismatch { slug_name, slug_prefix: slug_prefix.to_string(), crate_name }) - } -} diff --git a/compiler/rustc_macros/src/diagnostics/message.rs b/compiler/rustc_macros/src/diagnostics/message.rs index 2db8df2f69ae..18d4d60dde3e 100644 --- a/compiler/rustc_macros/src/diagnostics/message.rs +++ b/compiler/rustc_macros/src/diagnostics/message.rs @@ -2,16 +2,15 @@ use fluent_bundle::FluentResource; use fluent_syntax::ast::{Expression, InlineExpression, Pattern, PatternElement}; use proc_macro2::{Span, TokenStream}; use quote::quote; -use syn::Path; use syn::ext::IdentExt; -use synstructure::{Structure, VariantInfo}; +use synstructure::VariantInfo; use crate::diagnostics::error::span_err; #[derive(Clone)] -pub(crate) enum Message { - Slug(Path), - Inline(Span, String), +pub(crate) struct Message { + pub message_span: Span, + pub value: String, } impl Message { @@ -19,69 +18,9 @@ impl Message { /// The passed `variant` is used to check whether all variables in the message are used. /// For subdiagnostics, we cannot check this. pub(crate) fn diag_message(&self, variant: Option<&VariantInfo<'_>>) -> TokenStream { - match self { - Message::Slug(slug) => { - quote! { crate::fluent_generated::#slug } - } - Message::Inline(message_span, message) => { - verify_fluent_message(*message_span, &message, variant); - quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) } - } - } - } - - /// Generates a `#[test]` that verifies that all referenced variables - /// exist on this structure. - pub(crate) fn generate_test(&self, structure: &Structure<'_>) -> TokenStream { - match self { - Message::Slug(slug) => { - // FIXME: We can't identify variables in a subdiagnostic - for field in structure.variants().iter().flat_map(|v| v.ast().fields.iter()) { - for attr_name in field.attrs.iter().filter_map(|at| at.path().get_ident()) { - if attr_name == "subdiagnostic" { - return quote!(); - } - } - } - use std::sync::atomic::{AtomicUsize, Ordering}; - // We need to make sure that the same diagnostic slug can be used multiple times without - // causing an error, so just have a global counter here. - static COUNTER: AtomicUsize = AtomicUsize::new(0); - let slug = slug.get_ident().unwrap(); - let ident = quote::format_ident!( - "verify_{slug}_{}", - COUNTER.fetch_add(1, Ordering::Relaxed) - ); - let ref_slug = quote::format_ident!("{slug}_refs"); - let struct_name = &structure.ast().ident; - let variables: Vec<_> = structure - .variants() - .iter() - .flat_map(|v| { - v.ast() - .fields - .iter() - .filter_map(|f| f.ident.as_ref().map(|i| i.to_string())) - }) - .collect(); - // tidy errors on `#[test]` outside of test files, so we use `#[test ]` to work around this - quote! { - #[cfg(test)] - #[test ] - fn #ident() { - let variables = [#(#variables),*]; - for vref in crate::fluent_generated::#ref_slug { - assert!(variables.contains(vref), "{}: variable `{vref}` not found ({})", stringify!(#struct_name), stringify!(#slug)); - } - } - } - } - Message::Inline(..) => { - // We don't generate a test for inline diagnostics, we can verify these at compile-time! - // This verification is done in the `diag_message` function above - quote! {} - } - } + let message = &self.value; + verify_fluent_message(self.message_span, &message, variant); + quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) } } } diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index ac1fa984664c..7eb170ec236a 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -186,10 +186,10 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { fn identify_kind( &mut self, ) -> Result, DiagnosticDeriveError> { - let mut kind_slugs = vec![]; + let mut kind_messages = vec![]; for attr in self.variant.ast().attrs { - let Some(SubdiagnosticVariant { kind, slug }) = + let Some(SubdiagnosticVariant { kind, message }) = SubdiagnosticVariant::from_attr(attr, &self.fields)? else { // Some attributes aren't errors - like documentation comments - but also aren't @@ -197,22 +197,22 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { continue; }; - let Some(slug) = slug else { + let Some(message) = message else { let name = attr.path().segments.last().unwrap().ident.to_string(); let name = name.as_str(); throw_span_err!( attr.span().unwrap(), format!( - "diagnostic slug must be first argument of a `#[{name}(...)]` attribute" + "diagnostic message must be first argument of a `#[{name}(...)]` attribute" ) ); }; - kind_slugs.push((kind, slug)); + kind_messages.push((kind, message)); } - Ok(kind_slugs) + Ok(kind_messages) } /// Generates the code for a field with no attributes. @@ -498,9 +498,9 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { } pub(crate) fn into_tokens(&mut self) -> Result { - let kind_slugs = self.identify_kind()?; + let kind_messages = self.identify_kind()?; - let kind_stats: KindsStatistics = kind_slugs.iter().map(|(kind, _slug)| kind).collect(); + let kind_stats: KindsStatistics = kind_messages.iter().map(|(kind, _msg)| kind).collect(); let init = if kind_stats.has_multipart_suggestion { quote! { let mut suggestions = Vec::new(); } @@ -516,7 +516,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { .map(|binding| self.generate_field_attr_code(binding, kind_stats)) .collect(); - if kind_slugs.is_empty() && !self.has_subdiagnostic { + if kind_messages.is_empty() && !self.has_subdiagnostic { if self.is_enum { // It's okay for a variant to not be a subdiagnostic at all.. return Ok(quote! {}); @@ -533,9 +533,9 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { let diag = &self.parent.diag; let mut calls = TokenStream::new(); - for (kind, slug) in kind_slugs { + for (kind, messages) in kind_messages { let message = format_ident!("__message"); - let message_stream = slug.diag_message(None); + let message_stream = messages.diag_message(None); calls.extend(quote! { let #message = #diag.eagerly_translate(#message_stream); }); let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind); diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index a5265a847a9c..c308f6126325 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -267,7 +267,7 @@ pub(super) type FieldMap = HashMap; /// /// ```ignore (not-usage-example) /// /// Suggest `==` when users wrote `===`. -/// #[suggestion(slug = "parser-not-javascript-eq", code = "{lhs} == {rhs}")] +/// #[suggestion("example message", code = "{lhs} == {rhs}")] /// struct NotJavaScriptEq { /// #[primary_span] /// span: Span, @@ -588,13 +588,13 @@ pub(super) enum SubdiagnosticKind { pub(super) struct SubdiagnosticVariant { pub(super) kind: SubdiagnosticKind, - pub(super) slug: Option, + pub(super) message: Option, } impl SubdiagnosticVariant { /// Constructs a `SubdiagnosticVariant` from a field or type attribute such as `#[note]`, - /// `#[error(parser::add_paren)]` or `#[suggestion(code = "...")]`. Returns the - /// `SubdiagnosticKind` and the diagnostic slug, if specified. + /// `#[error("add parenthesis")]` or `#[suggestion(code = "...")]`. Returns the + /// `SubdiagnosticKind` and the diagnostic message, if specified. pub(super) fn from_attr( attr: &Attribute, fields: &FieldMap, @@ -660,11 +660,11 @@ impl SubdiagnosticVariant { let list = match &attr.meta { Meta::List(list) => { // An attribute with properties, such as `#[suggestion(code = "...")]` or - // `#[error(some::slug)]` + // `#[error("message")]` list } Meta::Path(_) => { - // An attribute without a slug or other properties, such as `#[note]` - return + // An attribute without a message or other properties, such as `#[note]` - return // without further processing. // // Only allow this if there are no mandatory properties, such as `code = "..."` in @@ -677,7 +677,7 @@ impl SubdiagnosticVariant { | SubdiagnosticKind::HelpOnce | SubdiagnosticKind::Warn | SubdiagnosticKind::MultipartSuggestion { .. } => { - return Ok(Some(SubdiagnosticVariant { kind, slug: None })); + return Ok(Some(SubdiagnosticVariant { kind, message: None })); } SubdiagnosticKind::Suggestion { .. } => { throw_span_err!(span, "suggestion without `code = \"...\"`") @@ -692,45 +692,34 @@ impl SubdiagnosticVariant { let mut code = None; let mut suggestion_kind = None; - let mut slug = None; + let mut message = None; list.parse_args_with(|input: ParseStream<'_>| { let mut is_first = true; while !input.is_empty() { // Try to parse an inline diagnostic message if input.peek(LitStr) { - let message = input.parse::()?; - if !message.suffix().is_empty() { + let inline_message = input.parse::()?; + if !inline_message.suffix().is_empty() { span_err( - message.span().unwrap(), + inline_message.span().unwrap(), "Inline message is not allowed to have a suffix", ).emit(); } if !input.is_empty() { input.parse::()?; } if is_first { - slug = Some(Message::Inline(message.span(), message.value())); + message = Some(Message { message_span: inline_message.span(), value: inline_message.value() }); is_first = false; } else { - span_err(message.span().unwrap(), "a diagnostic message must be the first argument to the attribute").emit(); - } - continue - } - - // Try to parse a slug instead - let arg_name: Path = input.parse::()?; - let arg_name_span = arg_name.span().unwrap(); - if input.is_empty() || input.parse::().is_ok() { - if is_first { - slug = Some(Message::Slug(arg_name)); - is_first = false; - } else { - span_err(arg_name_span, "a diagnostic slug must be the first argument to the attribute").emit(); + span_err(inline_message.span().unwrap(), "a diagnostic message must be the first argument to the attribute").emit(); } continue } is_first = false; // Try to parse an argument + let arg_name: Path = input.parse::()?; + let arg_name_span = arg_name.span().unwrap(); match (arg_name.require_ident()?.to_string().as_str(), &mut kind) { ("code", SubdiagnosticKind::Suggestion { code_field, .. }) => { let code_init = build_suggestion_code( @@ -836,7 +825,7 @@ impl SubdiagnosticVariant { | SubdiagnosticKind::Warn => {} } - Ok(Some(SubdiagnosticVariant { kind, slug })) + Ok(Some(SubdiagnosticVariant { kind, message })) } } From 2289e6cfb7e379eba777a10df0a6f474f9450b02 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 8 Feb 2026 11:04:30 +0100 Subject: [PATCH 3398/3801] Adjust expected uitests results for the updated `derive(Diagnostic)` macro --- .../diagnostic-derive-inline.rs | 38 +++-- .../diagnostic-derive-inline.stderr | 158 +++++++++--------- .../subdiagnostic-derive-inline.rs | 16 +- .../subdiagnostic-derive-inline.stderr | 22 +-- 4 files changed, 124 insertions(+), 110 deletions(-) diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs index 1d2bfc66aaff..ca803d450b92 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs @@ -45,9 +45,9 @@ struct Hello {} //~^ ERROR unsupported type attribute for diagnostic derive enum enum DiagnosticOnEnum { Foo, - //~^ ERROR diagnostic slug not specified + //~^ ERROR diagnostic message not specified Bar, - //~^ ERROR diagnostic slug not specified + //~^ ERROR diagnostic message not specified } #[derive(Diagnostic)] @@ -59,28 +59,28 @@ struct WrongStructAttrStyle {} #[derive(Diagnostic)] #[nonsense("this is an example message", code = E0123)] //~^ ERROR `#[nonsense(...)]` is not a valid attribute -//~^^ ERROR diagnostic slug not specified +//~^^ ERROR diagnostic message not specified //~^^^ ERROR cannot find attribute `nonsense` in this scope struct InvalidStructAttr {} #[derive(Diagnostic)] #[diag(code = E0123)] -//~^ ERROR diagnostic slug not specified +//~^ ERROR diagnostic message not specified struct InvalidLitNestedAttr {} #[derive(Diagnostic)] #[diag(nonsense("foo"), code = E0123, slug = "foo")] -//~^ ERROR derive(Diagnostic): diagnostic slug not specified +//~^ ERROR derive(Diagnostic): diagnostic message not specified struct InvalidNestedStructAttr1 {} #[derive(Diagnostic)] #[diag(nonsense = "...", code = E0123, slug = "foo")] -//~^ ERROR diagnostic slug not specified +//~^ ERROR diagnostic message not specified struct InvalidNestedStructAttr2 {} #[derive(Diagnostic)] #[diag(nonsense = 4, code = E0123, slug = "foo")] -//~^ ERROR diagnostic slug not specified +//~^ ERROR diagnostic message not specified struct InvalidNestedStructAttr3 {} #[derive(Diagnostic)] @@ -109,15 +109,15 @@ struct CodeSpecifiedTwice {} #[derive(Diagnostic)] #[diag("this is an example message", no_crate::example, code = E0123)] -//~^ ERROR diagnostic slug must be the first argument +//~^ ERROR diagnostic message must be the first argument struct SlugSpecifiedTwice {} #[derive(Diagnostic)] -struct KindNotProvided {} //~ ERROR diagnostic slug not specified +struct KindNotProvided {} //~ ERROR diagnostic message not specified #[derive(Diagnostic)] #[diag(code = E0123)] -//~^ ERROR diagnostic slug not specified +//~^ ERROR diagnostic message not specified struct SlugNotProvided {} #[derive(Diagnostic)] @@ -467,7 +467,15 @@ struct BoolField { #[diag("this is an example message", code = E0123)] struct LabelWithTrailingPath { #[label("with a label", foo)] - //~^ ERROR a diagnostic slug must be the first argument to the attribute + //~^ ERROR derive(Diagnostic): no nested attribute expected here + span: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct LabelWithTrailingMessage { + #[label("with a label", "and another one?")] + //~^ ERROR derive(Diagnostic): a diagnostic message must be the first argument to the attribute span: Span, } @@ -516,28 +524,28 @@ struct ErrorWithWarn { #[derive(Diagnostic)] #[error("this is an example message", code = E0123)] //~^ ERROR `#[error(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified +//~| ERROR diagnostic message not specified //~| ERROR cannot find attribute `error` in this scope struct ErrorAttribute {} #[derive(Diagnostic)] #[warn_("this is an example message", code = E0123)] //~^ ERROR `#[warn_(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified +//~| ERROR diagnostic message not specified //~| ERROR cannot find attribute `warn_` in this scope struct WarnAttribute {} #[derive(Diagnostic)] #[lint("this is an example message", code = E0123)] //~^ ERROR `#[lint(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified +//~| ERROR diagnostic message not specified //~| ERROR cannot find attribute `lint` in this scope struct LintAttributeOnSessionDiag {} #[derive(LintDiagnostic)] #[lint("this is an example message", code = E0123)] //~^ ERROR `#[lint(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified +//~| ERROR diagnostic message not specified //~| ERROR cannot find attribute `lint` in this scope struct LintAttributeOnLintDiag {} diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr index 71ed77804a6c..b32235c02b07 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr @@ -4,21 +4,21 @@ error: derive(Diagnostic): unsupported type attribute for diagnostic derive enum LL | #[diag("this is an example message", code = E0123)] | ^ -error: derive(Diagnostic): diagnostic slug not specified +error: derive(Diagnostic): diagnostic message not specified --> $DIR/diagnostic-derive-inline.rs:47:5 | LL | Foo, | ^^^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` -error: derive(Diagnostic): diagnostic slug not specified +error: derive(Diagnostic): diagnostic message not specified --> $DIR/diagnostic-derive-inline.rs:49:5 | LL | Bar, | ^^^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` error: expected parentheses: #[diag(...)] --> $DIR/diagnostic-derive-inline.rs:55:8 @@ -32,45 +32,45 @@ error: derive(Diagnostic): `#[nonsense(...)]` is not a valid attribute LL | #[nonsense("this is an example message", code = E0123)] | ^ -error: derive(Diagnostic): diagnostic slug not specified +error: derive(Diagnostic): diagnostic message not specified --> $DIR/diagnostic-derive-inline.rs:60:1 | LL | #[nonsense("this is an example message", code = E0123)] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` -error: derive(Diagnostic): diagnostic slug not specified +error: derive(Diagnostic): diagnostic message not specified --> $DIR/diagnostic-derive-inline.rs:67:1 | LL | #[diag(code = E0123)] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` -error: derive(Diagnostic): diagnostic slug not specified +error: derive(Diagnostic): diagnostic message not specified --> $DIR/diagnostic-derive-inline.rs:72:1 | LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` -error: derive(Diagnostic): diagnostic slug not specified +error: derive(Diagnostic): diagnostic message not specified --> $DIR/diagnostic-derive-inline.rs:77:1 | LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` -error: derive(Diagnostic): diagnostic slug not specified +error: derive(Diagnostic): diagnostic message not specified --> $DIR/diagnostic-derive-inline.rs:82:1 | LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` error: derive(Diagnostic): unknown argument --> $DIR/diagnostic-derive-inline.rs:87:52 @@ -78,7 +78,7 @@ error: derive(Diagnostic): unknown argument LL | #[diag("this is an example message", code = E0123, slug = "foo")] | ^^^^ | - = note: only the `code` parameter is valid after the slug + = note: only the `code` parameter is valid after the message error: derive(Diagnostic): `#[suggestion = ...]` is not a valid attribute --> $DIR/diagnostic-derive-inline.rs:94:5 @@ -110,27 +110,27 @@ note: previously specified here LL | #[diag("this is an example message", code = E0123, code = E0456)] | ^^^^ -error: derive(Diagnostic): diagnostic slug must be the first argument +error: derive(Diagnostic): diagnostic message must be the first argument --> $DIR/diagnostic-derive-inline.rs:111:38 | LL | #[diag("this is an example message", no_crate::example, code = E0123)] | ^^^^^^^^ -error: derive(Diagnostic): diagnostic slug not specified +error: derive(Diagnostic): diagnostic message not specified --> $DIR/diagnostic-derive-inline.rs:116:1 | LL | struct KindNotProvided {} | ^^^^^^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` -error: derive(Diagnostic): diagnostic slug not specified +error: derive(Diagnostic): diagnostic message not specified --> $DIR/diagnostic-derive-inline.rs:119:1 | LL | #[diag(code = E0123)] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/diagnostic-derive-inline.rs:130:5 @@ -276,26 +276,32 @@ error: derive(Diagnostic): the `#[help(...)]` attribute can only be applied to f LL | #[help("with a help")] | ^ -error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute +error: derive(Diagnostic): no nested attribute expected here --> $DIR/diagnostic-derive-inline.rs:469:29 | LL | #[label("with a label", foo)] | ^^^ -error: derive(Diagnostic): no nested attribute expected here +error: derive(Diagnostic): a diagnostic message must be the first argument to the attribute --> $DIR/diagnostic-derive-inline.rs:477:29 | +LL | #[label("with a label", "and another one?")] + | ^^^^^^^^^^^^^^^^^^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/diagnostic-derive-inline.rs:485:29 + | LL | #[label("with a label", foo = "...")] | ^^^ error: derive(Diagnostic): no nested attribute expected here - --> $DIR/diagnostic-derive-inline.rs:485:29 + --> $DIR/diagnostic-derive-inline.rs:493:29 | LL | #[label("with a label", foo("..."))] | ^^^ error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:497:5 + --> $DIR/diagnostic-derive-inline.rs:505:5 | LL | #[primary_span] | ^ @@ -303,75 +309,75 @@ LL | #[primary_span] = help: the `primary_span` field attribute is not valid for lint diagnostics error: derive(Diagnostic): `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:517:1 + --> $DIR/diagnostic-derive-inline.rs:525:1 | LL | #[error("this is an example message", code = E0123)] | ^ -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:517:1 +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:525:1 | LL | #[error("this is an example message", code = E0123)] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` error: derive(Diagnostic): `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:524:1 + --> $DIR/diagnostic-derive-inline.rs:532:1 | LL | #[warn_("this is an example message", code = E0123)] | ^ -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:524:1 +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:532:1 | LL | #[warn_("this is an example message", code = E0123)] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:531:1 + --> $DIR/diagnostic-derive-inline.rs:539:1 | LL | #[lint("this is an example message", code = E0123)] | ^ -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:531:1 +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:539:1 | LL | #[lint("this is an example message", code = E0123)] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:538:1 + --> $DIR/diagnostic-derive-inline.rs:546:1 | LL | #[lint("this is an example message", code = E0123)] | ^ -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive-inline.rs:538:1 +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:546:1 | LL | #[lint("this is an example message", code = E0123)] | ^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive-inline.rs:547:53 + --> $DIR/diagnostic-derive-inline.rs:555:53 | LL | #[suggestion("with a suggestion", code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive-inline.rs:547:39 + --> $DIR/diagnostic-derive-inline.rs:555:39 | LL | #[suggestion("with a suggestion", code = "...", code = ",,,")] | ^^^^ error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive-inline.rs:556:24 + --> $DIR/diagnostic-derive-inline.rs:564:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -379,7 +385,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive-inline.rs:564:17 + --> $DIR/diagnostic-derive-inline.rs:572:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -387,13 +393,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive-inline.rs:571:5 + --> $DIR/diagnostic-derive-inline.rs:579:5 | LL | #[suggestion("with a suggestion")] | ^ error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:578:1 + --> $DIR/diagnostic-derive-inline.rs:586:1 | LL | #[multipart_suggestion("with a suggestion")] | ^ @@ -401,7 +407,7 @@ LL | #[multipart_suggestion("with a suggestion")] = help: consider creating a `Subdiagnostic` instead error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:581:1 + --> $DIR/diagnostic-derive-inline.rs:589:1 | LL | #[multipart_suggestion()] | ^ @@ -409,7 +415,7 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:585:5 + --> $DIR/diagnostic-derive-inline.rs:593:5 | LL | #[multipart_suggestion("with a suggestion")] | ^ @@ -417,7 +423,7 @@ LL | #[multipart_suggestion("with a suggestion")] = help: consider creating a `Subdiagnostic` instead error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:593:1 + --> $DIR/diagnostic-derive-inline.rs:601:1 | LL | #[suggestion("with a suggestion", code = "...")] | ^ @@ -425,41 +431,35 @@ LL | #[suggestion("with a suggestion", code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: derive(Diagnostic): `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:602:1 + --> $DIR/diagnostic-derive-inline.rs:610:1 | LL | #[label] | ^ | - = help: `#[label]` and `#[suggestion]` can only be applied to fields + = help: subdiagnostic message is missing error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:636:5 + --> $DIR/diagnostic-derive-inline.rs:644:5 | LL | #[subdiagnostic(bad)] | ^ error: derive(Diagnostic): `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:644:5 + --> $DIR/diagnostic-derive-inline.rs:652:5 | LL | #[subdiagnostic = "bad"] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:652:5 + --> $DIR/diagnostic-derive-inline.rs:660:5 | LL | #[subdiagnostic(bad, bad)] | ^ -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:660:5 - | -LL | #[subdiagnostic("bad")] - | ^ - error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute --> $DIR/diagnostic-derive-inline.rs:668:5 | -LL | #[subdiagnostic(eager)] +LL | #[subdiagnostic("bad")] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute @@ -469,37 +469,43 @@ LL | #[subdiagnostic(eager)] | ^ error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:697:5 + --> $DIR/diagnostic-derive-inline.rs:684:5 + | +LL | #[subdiagnostic(eager)] + | ^ + +error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:705:5 | LL | #[subdiagnostic(eager)] | ^ error: derive(Diagnostic): expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive-inline.rs:728:44 + --> $DIR/diagnostic-derive-inline.rs:736:44 | LL | #[suggestion("with a suggestion", code())] | ^ error: derive(Diagnostic): `code(...)` must contain only string literals - --> $DIR/diagnostic-derive-inline.rs:736:44 + --> $DIR/diagnostic-derive-inline.rs:744:44 | LL | #[suggestion("with a suggestion", code(foo))] | ^^^ error: unexpected token, expected `)` - --> $DIR/diagnostic-derive-inline.rs:736:44 + --> $DIR/diagnostic-derive-inline.rs:744:44 | LL | #[suggestion("with a suggestion", code(foo))] | ^^^ error: expected string literal - --> $DIR/diagnostic-derive-inline.rs:745:46 + --> $DIR/diagnostic-derive-inline.rs:753:46 | LL | #[suggestion("with a suggestion", code = 3)] | ^ error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive-inline.rs:760:5 + --> $DIR/diagnostic-derive-inline.rs:768:5 | LL | #[suggestion("with a suggestion", code = "")] | ^ @@ -509,7 +515,7 @@ LL | #[suggestion("with a suggestion", code = "")] = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` error: derive(Diagnostic): Variable `nosub` not found in diagnostic - --> $DIR/diagnostic-derive-inline.rs:772:8 + --> $DIR/diagnostic-derive-inline.rs:780:8 | LL | #[diag("does not exist: {$nosub}")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -529,7 +535,7 @@ LL | #[nonsense] | ^^^^^^^^ error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive-inline.rs:517:3 + --> $DIR/diagnostic-derive-inline.rs:525:3 | LL | #[error("this is an example message", code = E0123)] | ^^^^^ @@ -541,7 +547,7 @@ LL | struct ErrorAttribute {} | error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive-inline.rs:524:3 + --> $DIR/diagnostic-derive-inline.rs:532:3 | LL | #[warn_("this is an example message", code = E0123)] | ^^^^^ @@ -553,7 +559,7 @@ LL + #[warn("this is an example message", code = E0123)] | error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive-inline.rs:531:3 + --> $DIR/diagnostic-derive-inline.rs:539:3 | LL | #[lint("this is an example message", code = E0123)] | ^^^^ @@ -565,7 +571,7 @@ LL + #[link("this is an example message", code = E0123)] | error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive-inline.rs:538:3 + --> $DIR/diagnostic-derive-inline.rs:546:3 | LL | #[lint("this is an example message", code = E0123)] | ^^^^ @@ -577,7 +583,7 @@ LL + #[link("this is an example message", code = E0123)] | error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive-inline.rs:578:3 + --> $DIR/diagnostic-derive-inline.rs:586:3 | LL | #[multipart_suggestion("with a suggestion")] | ^^^^^^^^^^^^^^^^^^^^ @@ -589,7 +595,7 @@ LL | struct MultipartSuggestion { | error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive-inline.rs:581:3 + --> $DIR/diagnostic-derive-inline.rs:589:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ @@ -601,7 +607,7 @@ LL | struct MultipartSuggestion { | error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive-inline.rs:585:7 + --> $DIR/diagnostic-derive-inline.rs:593:7 | LL | #[multipart_suggestion("with a suggestion")] | ^^^^^^^^^^^^^^^^^^^^ @@ -630,6 +636,6 @@ note: required by a bound in `Diag::<'a, G>::arg` = note: in this macro invocation = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 80 previous errors +error: aborting due to 81 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs index 079c2a74c4a1..99b2cba89da4 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs @@ -54,7 +54,7 @@ struct C { #[derive(Subdiagnostic)] #[label] -//~^ ERROR diagnostic slug must be first argument +//~^ ERROR diagnostic message must be first argument struct D { #[primary_span] span: Span, @@ -83,7 +83,7 @@ struct F { #[derive(Subdiagnostic)] #[label(bug = "...")] //~^ ERROR no nested attribute expected here -//~| ERROR diagnostic slug must be first argument +//~| ERROR diagnostic message must be first argument struct G { #[primary_span] span: Span, @@ -93,7 +93,7 @@ struct G { #[derive(Subdiagnostic)] #[label(slug = 4)] //~^ ERROR no nested attribute expected here -//~| ERROR diagnostic slug must be first argument +//~| ERROR diagnostic message must be first argument struct J { #[primary_span] span: Span, @@ -103,7 +103,7 @@ struct J { #[derive(Subdiagnostic)] #[label(slug("..."))] //~^ ERROR no nested attribute expected here -//~| ERROR diagnostic slug must be first argument +//~| ERROR diagnostic message must be first argument struct K { #[primary_span] span: Span, @@ -112,7 +112,7 @@ struct K { #[derive(Subdiagnostic)] #[label()] -//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute +//~^ ERROR diagnostic message must be first argument of a `#[label(...)]` attribute struct M { #[primary_span] span: Span, @@ -201,7 +201,7 @@ enum T { #[derive(Subdiagnostic)] enum U { #[label(code = "...")] - //~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute + //~^ ERROR diagnostic message must be first argument of a `#[label(...)]` attribute //~| ERROR no nested attribute expected here A { #[primary_span] @@ -303,7 +303,7 @@ struct AD { #[derive(Subdiagnostic)] #[label("example message", no_crate::example)] -//~^ ERROR a diagnostic slug must be the first argument to the attribute +//~^ ERROR expected this path to be an identifier struct AE { #[primary_span] span: Span, @@ -771,7 +771,7 @@ struct SuggestionStyleInvalid2 { #[derive(Subdiagnostic)] #[suggestion("example message", code = "", style)] -//~^ ERROR a diagnostic slug must be the first argument to the attribute +//~^ ERROR expected `=` struct SuggestionStyleInvalid3 { #[primary_span] sub: Span, diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr index 8ff5ed00d0ba..90e0c285ee74 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr @@ -4,7 +4,7 @@ error: derive(Diagnostic): label without `#[primary_span]` field LL | #[label("example message")] | ^ -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive-inline.rs:56:1 | LL | #[label] @@ -28,7 +28,7 @@ error: derive(Diagnostic): no nested attribute expected here LL | #[label(bug = "...")] | ^^^ -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive-inline.rs:84:1 | LL | #[label(bug = "...")] @@ -40,7 +40,7 @@ error: derive(Diagnostic): no nested attribute expected here LL | #[label(slug = 4)] | ^^^^ -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive-inline.rs:94:1 | LL | #[label(slug = 4)] @@ -52,13 +52,13 @@ error: derive(Diagnostic): no nested attribute expected here LL | #[label(slug("..."))] | ^^^^ -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive-inline.rs:104:1 | LL | #[label(slug("..."))] | ^ -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive-inline.rs:114:1 | LL | #[label()] @@ -112,7 +112,7 @@ error: derive(Diagnostic): no nested attribute expected here LL | #[label(code = "...")] | ^^^^ -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute --> $DIR/subdiagnostic-derive-inline.rs:203:5 | LL | #[label(code = "...")] @@ -168,11 +168,11 @@ LL | | b: u64, LL | | } | |_^ -error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute +error: expected this path to be an identifier --> $DIR/subdiagnostic-derive-inline.rs:305:28 | LL | #[label("example message", no_crate::example)] - | ^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ error: derive(Diagnostic): attribute specified multiple times --> $DIR/subdiagnostic-derive-inline.rs:318:5 @@ -464,11 +464,11 @@ error: expected string literal LL | #[suggestion("example message", code = "", style = 42)] | ^^ -error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive-inline.rs:773:44 +error: expected `=` + --> $DIR/subdiagnostic-derive-inline.rs:773:49 | LL | #[suggestion("example message", code = "", style)] - | ^^^^^ + | ^ error: expected `=` --> $DIR/subdiagnostic-derive-inline.rs:781:49 From 0db0acd6993cbdf84384b00773d7509df6bc20fb Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 20:08:45 +0100 Subject: [PATCH 3399/3801] Remove the fallback bundle --- compiler/rustc_driver_impl/src/lib.rs | 7 ++----- compiler/rustc_errors/src/json/tests.rs | 2 +- compiler/rustc_errors/src/translation.rs | 17 ++-------------- compiler/rustc_interface/src/interface.rs | 4 ---- compiler/rustc_interface/src/tests.rs | 1 - compiler/rustc_parse/src/parser/tests.rs | 20 +++++++++---------- compiler/rustc_session/src/parse.rs | 6 +++--- compiler/rustc_session/src/session.rs | 13 +++--------- src/librustdoc/clean/render_macro_matchers.rs | 2 +- src/librustdoc/core.rs | 1 - src/librustdoc/doctest.rs | 1 - .../ui-fulldeps/mod_dir_path_canonicalized.rs | 2 +- tests/ui-fulldeps/pprust-expr-roundtrip.rs | 2 +- .../pprust-parenthesis-insertion.rs | 2 +- tests/ui-fulldeps/run-compiler-twice.rs | 1 - 15 files changed, 25 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index d72913764e9d..83b27520457b 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -108,11 +108,9 @@ use crate::session_diagnostics::{ }; pub fn default_translator() -> Translator { - Translator::with_fallback_bundle(DEFAULT_LOCALE_RESOURCES.to_vec(), false) + Translator::new() } -pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[]; - /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; @@ -219,7 +217,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) output_dir: odir, ice_file, file_loader: None, - locale_resources: DEFAULT_LOCALE_RESOURCES.to_vec(), lint_caps: Default::default(), psess_created: None, hash_untracked_state: None, @@ -1528,7 +1525,7 @@ fn report_ice( extra_info: fn(&DiagCtxt), using_internal_features: &AtomicBool, ) { - let translator = default_translator(); + let translator = Translator::new(); let emitter = Box::new(rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter::new( stderr_destination(rustc_errors::ColorConfig::Auto), diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 6f99930c433b..ffcf9947a7a8 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -45,7 +45,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { rustc_span::create_default_session_globals_then(|| { let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); sm.new_source_file(filename(&sm, "test.rs"), code.to_owned()); - let translator = Translator::with_fallback_bundle(vec![], false); + let translator = Translator::new(); let output = Arc::new(Mutex::new(Vec::new())); let je = JsonEmitter::new( diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index 0b9845772590..b5de3f87e9f3 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -34,24 +34,11 @@ pub struct Translator { /// Localized diagnostics for the locale requested by the user. If no language was requested by /// the user then this will be `None` and `fallback_fluent_bundle` should be used. pub fluent_bundle: Option>, - /// Return `FluentBundle` with localized diagnostics for the default locale of the compiler. - /// Used when the user has not requested a specific language or when a localized diagnostic is - /// unavailable for the requested locale. - pub fallback_fluent_bundle: LazyFallbackBundle, } impl Translator { - pub fn with_fallback_bundle( - resources: Vec<&'static str>, - with_directionality_markers: bool, - ) -> Translator { - Translator { - fluent_bundle: None, - fallback_fluent_bundle: crate::fallback_fluent_bundle( - resources, - with_directionality_markers, - ), - } + pub fn new() -> Translator { + Translator { fluent_bundle: None } } /// Convert `DiagMessage`s to a string, performing translation if necessary. diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 722e9a420540..72080c5f5369 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -332,9 +332,6 @@ pub struct Config { /// bjorn3 for "hooking rust-analyzer's VFS into rustc at some point for /// running rustc without having to save". (See #102759.) pub file_loader: Option>, - /// The list of fluent resources, used for lints declared with - /// [`Diagnostic`](rustc_errors::Diagnostic) and [`LintDiagnostic`](rustc_errors::LintDiagnostic). - pub locale_resources: Vec<&'static str>, pub lint_caps: FxHashMap, @@ -458,7 +455,6 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se temps_dir, }, bundle, - config.locale_resources, config.lint_caps, target, util::rustc_version_str().unwrap_or("unknown"), diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 4241af244941..5ebf898f45a3 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -72,7 +72,6 @@ where sessopts, io, None, - vec![], Default::default(), target, "", diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 1b17f422345f..ac9c3e63e853 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -42,7 +42,7 @@ fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> { fn create_test_handler(theme: OutputTheme) -> (DiagCtxt, Arc, Arc>>) { let output = Arc::new(Mutex::new(Vec::new())); let source_map = Arc::new(SourceMap::new(FilePathMapping::empty())); - let translator = Translator::with_fallback_bundle(vec![], false); + let translator = Translator::new(); let shared: Box = Box::new(Shared { data: output.clone() }); let auto_stream = AutoStream::never(shared); let dcx = DiagCtxt::new(Box::new( @@ -89,7 +89,7 @@ where /// Maps a string to tts, using a made-up filename. pub(crate) fn string_to_stream(source_str: String) -> TokenStream { - let psess = ParseSess::new(vec![]); + let psess = ParseSess::new(); unwrap_or_emit_fatal(source_str_to_stream( &psess, filename(psess.source_map(), "bogofile"), @@ -2239,12 +2239,12 @@ fn sp(a: u32, b: u32) -> Span { /// Parses a string, return an expression. fn string_to_expr(source_str: String) -> Box { - with_error_checking_parse(source_str, &ParseSess::new(vec![]), |p| p.parse_expr()) + with_error_checking_parse(source_str, &ParseSess::new(), |p| p.parse_expr()) } /// Parses a string, returns an item. fn string_to_item(source_str: String) -> Option> { - with_error_checking_parse(source_str, &ParseSess::new(vec![]), |p| { + with_error_checking_parse(source_str, &ParseSess::new(), |p| { p.parse_item(ForceCollect::No, AllowConstBlockItems::Yes) }) } @@ -2480,7 +2480,7 @@ let mut fflags: c_int = wb(); #[test] fn crlf_doc_comments() { create_default_session_globals_then(|| { - let psess = ParseSess::new(vec![]); + let psess = ParseSess::new(); let name_1 = FileName::Custom("crlf_source_1".to_string()); let source = "/// doc comment\r\nfn foo() {}".to_string(); @@ -2515,7 +2515,7 @@ fn ttdelim_span() { } create_default_session_globals_then(|| { - let psess = ParseSess::new(vec![]); + let psess = ParseSess::new(); let expr = parse_expr_from_source_str( filename(psess.source_map(), "foo"), "foo!( fn main() { body } )".to_string(), @@ -2551,7 +2551,7 @@ fn look_ahead() { let sym_S = Symbol::intern("S"); let raw_no = IdentIsRaw::No; - let psess = ParseSess::new(vec![]); + let psess = ParseSess::new(); let mut p = string_to_parser(&psess, "fn f(x: u32) { x } struct S;".to_string()); // Current position is the `fn`. @@ -2626,7 +2626,7 @@ fn look_ahead_non_outermost_stream() { let sym_S = Symbol::intern("S"); let raw_no = IdentIsRaw::No; - let psess = ParseSess::new(vec![]); + let psess = ParseSess::new(); let mut p = string_to_parser(&psess, "mod m { fn f(x: u32) { x } struct S; }".to_string()); // Move forward to the `fn`, which is not within the outermost token @@ -2658,7 +2658,7 @@ fn look_ahead_non_outermost_stream() { #[test] fn debug_lookahead() { create_default_session_globals_then(|| { - let psess = ParseSess::new(vec![]); + let psess = ParseSess::new(); let mut p = string_to_parser(&psess, "fn f(x: u32) { x } struct S;".to_string()); // Current position is the `fn`. @@ -2879,7 +2879,7 @@ fn debug_lookahead() { #[test] fn out_of_line_mod() { create_default_session_globals_then(|| { - let psess = ParseSess::new(vec![]); + let psess = ParseSess::new(); let item = parse_item_from_source_str( filename(psess.source_map(), "foo"), "mod foo { struct S; mod this_does_not_exist; }".to_owned(), diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 7bebbc579c43..62c23424f371 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -280,8 +280,8 @@ pub struct ParseSess { impl ParseSess { /// Used for testing. - pub fn new(locale_resources: Vec<&'static str>) -> Self { - let translator = Translator::with_fallback_bundle(locale_resources, false); + pub fn new() -> Self { + let translator = Translator::new(); let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); let emitter = Box::new( AnnotateSnippetEmitter::new(stderr_destination(ColorConfig::Auto), translator) @@ -314,7 +314,7 @@ impl ParseSess { } pub fn emitter_with_note(note: String) -> Self { - let translator = Translator::with_fallback_bundle(vec![], false); + let translator = Translator::new(); let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); let emitter = Box::new(AnnotateSnippetEmitter::new( stderr_destination(ColorConfig::Auto), diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 92c47e3bfb36..ed37e9e960cd 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -19,7 +19,7 @@ use rustc_errors::timings::TimingSectionHandler; use rustc_errors::translation::Translator; use rustc_errors::{ Diag, DiagCtxt, DiagCtxtHandle, DiagMessage, Diagnostic, ErrorGuaranteed, FatalAbort, - TerminalUrl, fallback_fluent_bundle, + TerminalUrl, }; use rustc_hir::limit::Limit; use rustc_macros::HashStable_Generic; @@ -967,7 +967,6 @@ pub fn build_session( sopts: config::Options, io: CompilerIO, fluent_bundle: Option>, - fluent_resources: Vec<&'static str>, driver_lint_caps: FxHashMap, target: Target, cfg_version: &'static str, @@ -985,13 +984,7 @@ pub fn build_session( let cap_lints_allow = sopts.lint_cap.is_some_and(|cap| cap == lint::Allow); let can_emit_warnings = !(warnings_allow || cap_lints_allow); - let translator = Translator { - fluent_bundle, - fallback_fluent_bundle: fallback_fluent_bundle( - fluent_resources, - sopts.unstable_opts.translate_directionality_markers, - ), - }; + let translator = Translator { fluent_bundle }; let source_map = rustc_span::source_map::get_source_map().unwrap(); let emitter = default_emitter(&sopts, Arc::clone(&source_map), translator); @@ -1430,7 +1423,7 @@ impl EarlyDiagCtxt { fn mk_emitter(output: ErrorOutputType) -> Box { // FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will // need to reference every crate that might emit an early error for translation to work. - let translator = Translator::with_fallback_bundle(vec![], false); + let translator = Translator::new(); let emitter: Box = match output { config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { HumanReadableErrorType { short, unicode } => Box::new( diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index b5a8d64ff4f5..a69e3808bd7f 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -63,7 +63,7 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option, input: Input, options: RustdocOptions output_file: None, output_dir: None, file_loader: None, - locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), lint_caps, psess_created: None, hash_untracked_state: None, diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs index 894fec248f1f..806d395a90ad 100644 --- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs +++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs @@ -29,7 +29,7 @@ pub fn main() { } fn parse() { - let psess = ParseSess::new(vec![]); + let psess = ParseSess::new(); let path = Path::new(file!()); let path = path.canonicalize().unwrap(); diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs index 7fe71004522a..8d7425186680 100644 --- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs @@ -219,7 +219,7 @@ fn main() { } fn run() { - let psess = ParseSess::new(vec![]); + let psess = ParseSess::new(); iter_exprs(2, &mut |mut e| { // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`, diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 90cf9b89a293..85ee87155a7a 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -196,7 +196,7 @@ fn main() -> ExitCode { }; rustc_span::create_default_session_globals_then(|| { - let psess = &ParseSess::new(vec![]); + let psess = &ParseSess::new(); for &source_code in EXPRS { let Some(expr) = parse_expr(psess, source_code) else { diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs index 8b5e99cbee8d..bd92cc6218f1 100644 --- a/tests/ui-fulldeps/run-compiler-twice.rs +++ b/tests/ui-fulldeps/run-compiler-twice.rs @@ -64,7 +64,6 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path output_dir: None, ice_file: None, file_loader: None, - locale_resources: Vec::new(), lint_caps: Default::default(), psess_created: None, hash_untracked_state: None, From 81d42146040c4a6b3d252e3dc3ac32e563694796 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 6 Feb 2026 20:09:13 +0100 Subject: [PATCH 3400/3801] Remove fluent tests in `rustc_error` --- compiler/rustc_errors/src/lib.rs | 2 - compiler/rustc_errors/src/tests.rs | 182 ----------------------------- 2 files changed, 184 deletions(-) delete mode 100644 compiler/rustc_errors/src/tests.rs diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 534fe32a897f..2e0afb8fc4c2 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -83,8 +83,6 @@ pub mod error; pub mod json; mod lock; pub mod markdown; -#[cfg(test)] -mod tests; pub mod timings; pub mod translation; diff --git a/compiler/rustc_errors/src/tests.rs b/compiler/rustc_errors/src/tests.rs deleted file mode 100644 index 34ebac0fde11..000000000000 --- a/compiler/rustc_errors/src/tests.rs +++ /dev/null @@ -1,182 +0,0 @@ -use std::sync::{Arc, LazyLock}; - -use rustc_data_structures::sync::IntoDynSyncSend; -use rustc_error_messages::fluent_bundle::resolver::errors::{ReferenceKind, ResolverError}; -use rustc_error_messages::{DiagMessage, langid}; - -use crate::FluentBundle; -use crate::error::{TranslateError, TranslateErrorKind}; -use crate::fluent_bundle::*; -use crate::translation::Translator; - -fn make_translator(ftl: &'static str) -> Translator { - let resource = FluentResource::try_new(ftl.into()).expect("Failed to parse an FTL string."); - - let langid_en = langid!("en-US"); - - let mut bundle: FluentBundle = - IntoDynSyncSend(crate::fluent_bundle::bundle::FluentBundle::new_concurrent(vec![ - langid_en, - ])); - - bundle.add_resource(resource).expect("Failed to add FTL resources to the bundle."); - - Translator { - fluent_bundle: None, - fallback_fluent_bundle: Arc::new(LazyLock::new(Box::new(|| bundle))), - } -} - -#[test] -fn wellformed_fluent() { - let translator = make_translator("mir_build_borrow_of_moved_value = borrow of moved value - .label = value moved into `{$name}` here - .occurs_because_label = move occurs because `{$name}` has type `{$ty}` which does not implement the `Copy` trait - .value_borrowed_label = value borrowed here after move - .suggestion = borrow this binding in the pattern to avoid moving the value"); - - let mut args = FluentArgs::new(); - args.set("name", "Foo"); - args.set("ty", "std::string::String"); - { - let message = DiagMessage::FluentIdentifier( - "mir_build_borrow_of_moved_value".into(), - Some("suggestion".into()), - ); - - assert_eq!( - translator.translate_message(&message, &args).unwrap(), - "borrow this binding in the pattern to avoid moving the value" - ); - } - - { - let message = DiagMessage::FluentIdentifier( - "mir_build_borrow_of_moved_value".into(), - Some("value_borrowed_label".into()), - ); - - assert_eq!( - translator.translate_message(&message, &args).unwrap(), - "value borrowed here after move" - ); - } - - { - let message = DiagMessage::FluentIdentifier( - "mir_build_borrow_of_moved_value".into(), - Some("occurs_because_label".into()), - ); - - assert_eq!( - translator.translate_message(&message, &args).unwrap(), - "move occurs because `\u{2068}Foo\u{2069}` has type `\u{2068}std::string::String\u{2069}` which does not implement the `Copy` trait" - ); - - { - let message = DiagMessage::FluentIdentifier( - "mir_build_borrow_of_moved_value".into(), - Some("label".into()), - ); - - assert_eq!( - translator.translate_message(&message, &args).unwrap(), - "value moved into `\u{2068}Foo\u{2069}` here" - ); - } - } -} - -#[test] -fn misformed_fluent() { - let translator = make_translator("mir_build_borrow_of_moved_value = borrow of moved value - .label = value moved into `{name}` here - .occurs_because_label = move occurs because `{$oops}` has type `{$ty}` which does not implement the `Copy` trait - .suggestion = borrow this binding in the pattern to avoid moving the value"); - - let mut args = FluentArgs::new(); - args.set("name", "Foo"); - args.set("ty", "std::string::String"); - { - let message = DiagMessage::FluentIdentifier( - "mir_build_borrow_of_moved_value".into(), - Some("value_borrowed_label".into()), - ); - - let err = translator.translate_message(&message, &args).unwrap_err(); - assert!( - matches!( - &err, - TranslateError::Two { - primary: box TranslateError::One { - kind: TranslateErrorKind::PrimaryBundleMissing, - .. - }, - fallback: box TranslateError::One { - kind: TranslateErrorKind::AttributeMissing { attr: "value_borrowed_label" }, - .. - } - } - ), - "{err:#?}" - ); - assert_eq!( - format!("{err}"), - "failed while formatting fluent string `mir_build_borrow_of_moved_value`: \nthe attribute `value_borrowed_label` was missing\nhelp: add `.value_borrowed_label = `\n" - ); - } - - { - let message = DiagMessage::FluentIdentifier( - "mir_build_borrow_of_moved_value".into(), - Some("label".into()), - ); - - let err = translator.translate_message(&message, &args).unwrap_err(); - if let TranslateError::Two { - primary: box TranslateError::One { kind: TranslateErrorKind::PrimaryBundleMissing, .. }, - fallback: box TranslateError::One { kind: TranslateErrorKind::Fluent { errs }, .. }, - } = &err - && let [ - FluentError::ResolverError(ResolverError::Reference( - ReferenceKind::Message { id, .. } | ReferenceKind::Variable { id, .. }, - )), - ] = &**errs - && id == "name" - { - } else { - panic!("{err:#?}") - }; - assert_eq!( - format!("{err}"), - "failed while formatting fluent string `mir_build_borrow_of_moved_value`: \nargument `name` exists but was not referenced correctly\nhelp: try using `{$name}` instead\n" - ); - } - - { - let message = DiagMessage::FluentIdentifier( - "mir_build_borrow_of_moved_value".into(), - Some("occurs_because_label".into()), - ); - - let err = translator.translate_message(&message, &args).unwrap_err(); - if let TranslateError::Two { - primary: box TranslateError::One { kind: TranslateErrorKind::PrimaryBundleMissing, .. }, - fallback: box TranslateError::One { kind: TranslateErrorKind::Fluent { errs }, .. }, - } = &err - && let [ - FluentError::ResolverError(ResolverError::Reference( - ReferenceKind::Message { id, .. } | ReferenceKind::Variable { id, .. }, - )), - ] = &**errs - && id == "oops" - { - } else { - panic!("{err:#?}") - }; - assert_eq!( - format!("{err}"), - "failed while formatting fluent string `mir_build_borrow_of_moved_value`: \nthe fluent string has an argument `oops` that was not found.\nhelp: the arguments `name` and `ty` are available\n" - ); - } -} From 0f3108327b7679e13da6e07957508a1ab3ce2043 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 4 Feb 2026 13:53:29 +1100 Subject: [PATCH 3401/3801] Streamline `rustc_span::HashStableContext`. Currently this trait has five methods. But it only really needs three. For example, currently stable hashing of spans is implemented in `rustc_span`, except a couple of sub-operations are delegated to `rustc_query_system`: `def_span` and `span_data_to_lines_and_cols`. These two delegated sub-operations can be reduced to a single delegated operation that does the full hash computation. Likewise, `assert_default_hashing_controls` depends on two delegated sub-operations, `hashing_controls` and `unstable_opts_incremental_ignore_spans`, and can be simplified. I find the resulting code simpler and clearer -- when necessary, we do a whole operation in `rustc_query_system` instead of doing it partly in `rustc_span` and partly in `rustc_query_system`. --- compiler/rustc_query_system/src/ich/hcx.rs | 126 ++++++++++++++++++--- compiler/rustc_span/src/hygiene.rs | 29 +---- compiler/rustc_span/src/lib.rs | 102 ++--------------- 3 files changed, 121 insertions(+), 136 deletions(-) diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index 397ec7994f18..2e118dc3359f 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -1,10 +1,12 @@ -use rustc_data_structures::stable_hasher::HashingControls; +use std::hash::Hash; + +use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::definitions::DefPathHash; use rustc_session::Session; use rustc_session::cstore::Untracked; use rustc_span::source_map::SourceMap; -use rustc_span::{BytePos, CachingSourceMapView, DUMMY_SP, SourceFile, Span, SpanData}; +use rustc_span::{CachingSourceMapView, DUMMY_SP, Pos, Span}; // Very often, we are hashing something that does not need the `CachingSourceMapView`, so we // initialize it lazily. @@ -60,6 +62,11 @@ impl<'a> StableHashingContext<'a> { } } + #[inline] + fn def_span(&self, def_id: LocalDefId) -> Span { + self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP) + } + #[inline] pub fn hashing_controls(&self) -> HashingControls { self.hashing_controls @@ -67,9 +74,88 @@ impl<'a> StableHashingContext<'a> { } impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { + /// Hashes a span in a stable way. We can't directly hash the span's `BytePos` fields (that + /// would be similar to hashing pointers, since those are just offsets into the `SourceMap`). + /// Instead, we hash the (file name, line, column) triple, which stays the same even if the + /// containing `SourceFile` has moved within the `SourceMap`. + /// + /// Also note that we are hashing byte offsets for the column, not unicode codepoint offsets. + /// For the purpose of the hash that's sufficient. Also, hashing filenames is expensive so we + /// avoid doing it twice when the span starts and ends in the same file, which is almost always + /// the case. + /// + /// IMPORTANT: changes to this method should be reflected in implementations of `SpanEncoder`. #[inline] - fn unstable_opts_incremental_ignore_spans(&self) -> bool { - self.incremental_ignore_spans + fn span_hash_stable(&mut self, span: Span, hasher: &mut StableHasher) { + const TAG_VALID_SPAN: u8 = 0; + const TAG_INVALID_SPAN: u8 = 1; + const TAG_RELATIVE_SPAN: u8 = 2; + + if !self.hashing_controls().hash_spans { + return; + } + + let span = span.data_untracked(); + span.ctxt.hash_stable(self, hasher); + span.parent.hash_stable(self, hasher); + + if span.is_dummy() { + Hash::hash(&TAG_INVALID_SPAN, hasher); + return; + } + + let parent = span.parent.map(|parent| self.def_span(parent).data_untracked()); + if let Some(parent) = parent + && parent.contains(span) + { + // This span is enclosed in a definition: only hash the relative position. This catches + // a subset of the cases from the `file.contains(parent.lo)`. But we can do this check + // cheaply without the expensive `span_data_to_lines_and_cols` query. + Hash::hash(&TAG_RELATIVE_SPAN, hasher); + (span.lo - parent.lo).to_u32().hash_stable(self, hasher); + (span.hi - parent.lo).to_u32().hash_stable(self, hasher); + return; + } + + // If this is not an empty or invalid span, we want to hash the last position that belongs + // to it, as opposed to hashing the first position past it. + let Some((file, line_lo, col_lo, line_hi, col_hi)) = + self.source_map().span_data_to_lines_and_cols(&span) + else { + Hash::hash(&TAG_INVALID_SPAN, hasher); + return; + }; + + if let Some(parent) = parent + && file.contains(parent.lo) + { + // This span is relative to another span in the same file, + // only hash the relative position. + Hash::hash(&TAG_RELATIVE_SPAN, hasher); + Hash::hash(&(span.lo.0.wrapping_sub(parent.lo.0)), hasher); + Hash::hash(&(span.hi.0.wrapping_sub(parent.lo.0)), hasher); + return; + } + + Hash::hash(&TAG_VALID_SPAN, hasher); + Hash::hash(&file.stable_id, hasher); + + // Hash both the length and the end location (line/column) of a span. If we hash only the + // length, for example, then two otherwise equal spans with different end locations will + // have the same hash. This can cause a problem during incremental compilation wherein a + // previous result for a query that depends on the end location of a span will be + // incorrectly reused when the end location of the span it depends on has changed (see + // issue #74890). A similar analysis applies if some query depends specifically on the + // length of the span, but we only hash the end location. So hash both. + + let col_lo_trunc = (col_lo.0 as u64) & 0xFF; + let line_lo_trunc = ((line_lo as u64) & 0xFF_FF_FF) << 8; + let col_hi_trunc = (col_hi.0 as u64) & 0xFF << 32; + let line_hi_trunc = ((line_hi as u64) & 0xFF_FF_FF) << 40; + let col_line = col_lo_trunc | line_lo_trunc | col_hi_trunc | line_hi_trunc; + let len = (span.hi - span.lo).0; + Hash::hash(&col_line, hasher); + Hash::hash(&len, hasher); } #[inline] @@ -81,22 +167,26 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { } } + /// Assert that the provided `HashStableContext` is configured with the default + /// `HashingControls`. We should always have bailed out before getting to here with a + /// non-default mode. With this check in place, we can avoid the need to maintain separate + /// versions of `ExpnData` hashes for each permutation of `HashingControls` settings. #[inline] - fn def_span(&self, def_id: LocalDefId) -> Span { - self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP) - } + fn assert_default_hashing_controls(&self, msg: &str) { + let hashing_controls = self.hashing_controls; + let HashingControls { hash_spans } = hashing_controls; - #[inline] - fn span_data_to_lines_and_cols( - &mut self, - span: &SpanData, - ) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)> { - self.source_map().span_data_to_lines_and_cols(span) - } - - #[inline] - fn hashing_controls(&self) -> HashingControls { - self.hashing_controls + // Note that we require that `hash_spans` be the inverse of the global `-Z + // incremental-ignore-spans` option. Normally, this option is disabled, in which case + // `hash_spans` must be true. + // + // Span hashing can also be disabled without `-Z incremental-ignore-spans`. This is the + // case for instance when building a hash for name mangling. Such configuration must not be + // used for metadata. + assert_eq!( + hash_spans, !self.incremental_ignore_spans, + "Attempted hashing of {msg} with non-default HashingControls: {hashing_controls:?}" + ); } } diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 07a85ad75daa..25834f03af5e 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -30,7 +30,7 @@ use std::{fmt, iter, mem}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lock; use rustc_data_structures::unhash::UnhashMap; use rustc_hashes::Hash64; @@ -126,29 +126,6 @@ rustc_index::newtype_index! { impl !Ord for LocalExpnId {} impl !PartialOrd for LocalExpnId {} -/// Assert that the provided `HashStableContext` is configured with the 'default' -/// `HashingControls`. We should always have bailed out before getting to here -/// with a non-default mode. With this check in place, we can avoid the need -/// to maintain separate versions of `ExpnData` hashes for each permutation -/// of `HashingControls` settings. -fn assert_default_hashing_controls(ctx: &impl HashStableContext, msg: &str) { - let hashing_controls = ctx.hashing_controls(); - let HashingControls { hash_spans } = hashing_controls; - - // Note that we require that `hash_spans` be the inverse of the global - // `-Z incremental-ignore-spans` option. Normally, this option is disabled, - // in which case `hash_spans` must be true. - // - // Span hashing can also be disabled without `-Z incremental-ignore-spans`. - // This is the case for instance when building a hash for name mangling. - // Such configuration must not be used for metadata. - assert_eq!( - hash_spans, - !ctx.unstable_opts_incremental_ignore_spans(), - "Attempted hashing of {msg} with non-default HashingControls: {hashing_controls:?}" - ); -} - /// A unique hash value associated to an expansion. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)] pub struct ExpnHash(Fingerprint); @@ -1508,7 +1485,7 @@ pub fn raw_encode_syntax_context( fn update_disambiguator(expn_data: &mut ExpnData, mut ctx: impl HashStableContext) -> ExpnHash { // This disambiguator should not have been set yet. assert_eq!(expn_data.disambiguator, 0, "Already set disambiguator for ExpnData: {expn_data:?}"); - assert_default_hashing_controls(&ctx, "ExpnData (disambiguator)"); + ctx.assert_default_hashing_controls("ExpnData (disambiguator)"); let mut expn_hash = expn_data.hash_expn(&mut ctx); let disambiguator = HygieneData::with(|data| { @@ -1558,7 +1535,7 @@ impl HashStable for SyntaxContext { impl HashStable for ExpnId { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - assert_default_hashing_controls(ctx, "ExpnId"); + ctx.assert_default_hashing_controls("ExpnId"); let hash = if *self == ExpnId::root() { // Avoid fetching TLS storage for a trivial often-used value. Fingerprint::ZERO diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 0ad80b9d7879..bececc548494 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -54,7 +54,6 @@ use hygiene::Transparency; pub use hygiene::{ DesugaringKind, ExpnData, ExpnHash, ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext, }; -use rustc_data_structures::stable_hasher::HashingControls; pub mod def_id; use def_id::{CrateNum, DefId, DefIndex, DefPathHash, LOCAL_CRATE, LocalDefId, StableCrateId}; pub mod edit_distance; @@ -2798,105 +2797,24 @@ impl InnerSpan { /// This is a hack to allow using the [`HashStable_Generic`] derive macro /// instead of implementing everything in rustc_middle. pub trait HashStableContext { + /// The main event: stable hashing of a span. + fn span_hash_stable(&mut self, span: Span, hasher: &mut StableHasher); + + /// Compute a `DefPathHash`. fn def_path_hash(&self, def_id: DefId) -> DefPathHash; - /// Accesses `sess.opts.unstable_opts.incremental_ignore_spans` since - /// we don't have easy access to a `Session` - fn unstable_opts_incremental_ignore_spans(&self) -> bool; - fn def_span(&self, def_id: LocalDefId) -> Span; - fn span_data_to_lines_and_cols( - &mut self, - span: &SpanData, - ) -> Option<(&SourceFile, usize, BytePos, usize, BytePos)>; - fn hashing_controls(&self) -> HashingControls; + + /// Assert that the provided `HashStableContext` is configured with the default + /// `HashingControls`. We should always have bailed out before getting to here with a + fn assert_default_hashing_controls(&self, msg: &str); } impl HashStable for Span where CTX: HashStableContext, { - /// Hashes a span in a stable way. We can't directly hash the span's `BytePos` - /// fields (that would be similar to hashing pointers, since those are just - /// offsets into the `SourceMap`). Instead, we hash the (file name, line, column) - /// triple, which stays the same even if the containing `SourceFile` has moved - /// within the `SourceMap`. - /// - /// Also note that we are hashing byte offsets for the column, not unicode - /// codepoint offsets. For the purpose of the hash that's sufficient. - /// Also, hashing filenames is expensive so we avoid doing it twice when the - /// span starts and ends in the same file, which is almost always the case. - /// - /// IMPORTANT: changes to this method should be reflected in implementations of `SpanEncoder`. fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - const TAG_VALID_SPAN: u8 = 0; - const TAG_INVALID_SPAN: u8 = 1; - const TAG_RELATIVE_SPAN: u8 = 2; - - if !ctx.hashing_controls().hash_spans { - return; - } - - let span = self.data_untracked(); - span.ctxt.hash_stable(ctx, hasher); - span.parent.hash_stable(ctx, hasher); - - if span.is_dummy() { - Hash::hash(&TAG_INVALID_SPAN, hasher); - return; - } - - let parent = span.parent.map(|parent| ctx.def_span(parent).data_untracked()); - if let Some(parent) = parent - && parent.contains(span) - { - // This span is enclosed in a definition: only hash the relative position. - // This catches a subset of the cases from the `file.contains(parent.lo)`, - // But we can do this check cheaply without the expensive `span_data_to_lines_and_cols` query. - Hash::hash(&TAG_RELATIVE_SPAN, hasher); - (span.lo - parent.lo).to_u32().hash_stable(ctx, hasher); - (span.hi - parent.lo).to_u32().hash_stable(ctx, hasher); - return; - } - - // If this is not an empty or invalid span, we want to hash the last - // position that belongs to it, as opposed to hashing the first - // position past it. - let Some((file, line_lo, col_lo, line_hi, col_hi)) = ctx.span_data_to_lines_and_cols(&span) - else { - Hash::hash(&TAG_INVALID_SPAN, hasher); - return; - }; - - if let Some(parent) = parent - && file.contains(parent.lo) - { - // This span is relative to another span in the same file, - // only hash the relative position. - Hash::hash(&TAG_RELATIVE_SPAN, hasher); - Hash::hash(&(span.lo.0.wrapping_sub(parent.lo.0)), hasher); - Hash::hash(&(span.hi.0.wrapping_sub(parent.lo.0)), hasher); - return; - } - - Hash::hash(&TAG_VALID_SPAN, hasher); - Hash::hash(&file.stable_id, hasher); - - // Hash both the length and the end location (line/column) of a span. If we - // hash only the length, for example, then two otherwise equal spans with - // different end locations will have the same hash. This can cause a problem - // during incremental compilation wherein a previous result for a query that - // depends on the end location of a span will be incorrectly reused when the - // end location of the span it depends on has changed (see issue #74890). A - // similar analysis applies if some query depends specifically on the length - // of the span, but we only hash the end location. So hash both. - - let col_lo_trunc = (col_lo.0 as u64) & 0xFF; - let line_lo_trunc = ((line_lo as u64) & 0xFF_FF_FF) << 8; - let col_hi_trunc = (col_hi.0 as u64) & 0xFF << 32; - let line_hi_trunc = ((line_hi as u64) & 0xFF_FF_FF) << 40; - let col_line = col_lo_trunc | line_lo_trunc | col_hi_trunc | line_hi_trunc; - let len = (span.hi - span.lo).0; - Hash::hash(&col_line, hasher); - Hash::hash(&len, hasher); + // `span_hash_stable` does all the work. + ctx.span_hash_stable(*self, hasher) } } From 842bed6f939f74c8c005bc223acb50e22464d108 Mon Sep 17 00:00:00 2001 From: Oscar Bray Date: Wed, 4 Feb 2026 20:32:49 +0000 Subject: [PATCH 3402/3801] Parse #[rustc_delayed_bug_from_inside_query] --- compiler/rustc_attr_parsing/src/attributes/test_attrs.rs | 9 +++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_interface/src/passes.rs | 4 ++-- compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index 908941c2b335..504466d3795a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -190,3 +190,12 @@ impl SingleAttributeParser for RustcAbiParser { Some(AttributeKind::RustcAbi { attr_span: cx.attr_span, kind }) } } + +pub(crate) struct RustcDelayedBugFromInsideQueryParser; + +impl NoArgsAttributeParser for RustcDelayedBugFromInsideQueryParser { + const PATH: &[Symbol] = &[sym::rustc_delayed_bug_from_inside_query]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDelayedBugFromInsideQuery; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index ad39b0ec26d9..704a2f3c8d10 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -262,6 +262,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 79452913c259..ca1913faeea1 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1084,6 +1084,9 @@ pub enum AttributeKind { /// Represents `#[rustc_def_path]` RustcDefPath(Span), + /// Represents `#[rustc_delayed_bug_from_inside_query]` + RustcDelayedBugFromInsideQuery, + /// Represents `#[rustc_deny_explicit_impl]`. RustcDenyExplicitImpl(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index ba351d80544c..33661807e1a9 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -106,6 +106,7 @@ impl AttributeKind { RustcConstStabilityIndirect => No, RustcDeallocator => No, RustcDefPath(..) => No, + RustcDelayedBugFromInsideQuery => No, RustcDenyExplicitImpl(..) => No, RustcDummy => No, RustcDumpDefParents => No, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index f5fb8031ab0f..fe406f79f8dc 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -18,11 +18,11 @@ use rustc_errors::timings::TimingSection; use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_feature::Features; use rustc_fs_util::try_canonicalize; -use rustc_hir::Attribute; use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap}; use rustc_hir::definitions::Definitions; use rustc_hir::limit::Limit; +use rustc_hir::{Attribute, find_attr}; use rustc_incremental::setup_dep_graph; use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store}; use rustc_metadata::EncodedMetadata; @@ -1227,7 +1227,7 @@ pub(crate) fn start_codegen<'tcx>( // Hook for tests. if let Some((def_id, _)) = tcx.entry_fn(()) - && tcx.has_attr(def_id, sym::rustc_delayed_bug_from_inside_query) + && find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcDelayedBugFromInsideQuery) { tcx.ensure_ok().trigger_delayed_bug(def_id); } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 6c4b76a08ad2..a67ee43a9b2e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -301,6 +301,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcConstStabilityIndirect | AttributeKind::RustcDeallocator | AttributeKind::RustcDefPath(..) + | AttributeKind::RustcDelayedBugFromInsideQuery | AttributeKind::RustcDenyExplicitImpl(..) | AttributeKind::RustcDummy | AttributeKind::RustcDumpDefParents @@ -406,7 +407,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_mir | sym::rustc_outlives | sym::rustc_evaluate_where_clauses - | sym::rustc_delayed_bug_from_inside_query | sym::rustc_partition_reused | sym::rustc_partition_codegened | sym::rustc_expected_cgu_reuse From 76684962741d4647638d61b5466a4f0e4ca76258 Mon Sep 17 00:00:00 2001 From: Oscar Bray Date: Wed, 4 Feb 2026 20:51:17 +0000 Subject: [PATCH 3403/3801] Parse #[rustc_evaluate_where_clauses] --- .../src/attributes/test_attrs.rs | 15 +++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_hir_typeck/src/callee.rs | 8 ++++++-- compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 27 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index 504466d3795a..9effba39571c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -199,3 +199,18 @@ impl NoArgsAttributeParser for RustcDelayedBugFromInsideQueryParser const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDelayedBugFromInsideQuery; } + +pub(crate) struct RustcEvaluateWhereClausesParser; + +impl NoArgsAttributeParser for RustcEvaluateWhereClausesParser { + const PATH: &[Symbol] = &[sym::rustc_evaluate_where_clauses]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Method(MethodKind::Trait { body: false })), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEvaluateWhereClauses; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 704a2f3c8d10..d714a6399b82 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -269,6 +269,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index ca1913faeea1..39f76002c419 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1114,6 +1114,9 @@ pub enum AttributeKind { /// Represents `#[rustc_effective_visibility]`. RustcEffectiveVisibility, + /// Represents `#[rustc_evaluate_where_clauses]` + RustcEvaluateWhereClauses, + /// Represents `#[rustc_has_incoherent_inherent_impls]` RustcHasIncoherentInherentImpls, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 33661807e1a9..0b223c82c9b7 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -116,6 +116,7 @@ impl AttributeKind { RustcDumpVtable(..) => No, RustcDynIncompatibleTrait(..) => No, RustcEffectiveVisibility => Yes, + RustcEvaluateWhereClauses => Yes, RustcHasIncoherentInherentImpls => Yes, RustcHiddenTypeOfOpaques => No, RustcIfThisChanged(..) => No, diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index d04bd6f2295a..e20d5cdf2889 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -3,9 +3,10 @@ use std::iter; use rustc_abi::{CanonAbi, ExternAbi}; use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey, inline_fluent}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{self, CtorKind, Namespace, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, HirId, LangItem}; +use rustc_hir::{self as hir, HirId, LangItem, find_attr}; use rustc_hir_analysis::autoderef::Autoderef; use rustc_infer::infer::BoundRegionConversionTime; use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode}; @@ -526,7 +527,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // `#[rustc_evaluate_where_clauses]` trigger special output // to let us test the trait evaluation system. if self.has_rustc_attrs - && self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) + && find_attr!( + self.tcx.get_all_attrs(def_id), + AttributeKind::RustcEvaluateWhereClauses + ) { let predicates = self.tcx.predicates_of(def_id); let predicates = predicates.instantiate(self.tcx, args); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a67ee43a9b2e..47dce81b8f5a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -311,6 +311,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDumpVtable(..) | AttributeKind::RustcDynIncompatibleTrait(..) | AttributeKind::RustcEffectiveVisibility + | AttributeKind::RustcEvaluateWhereClauses | AttributeKind::RustcHasIncoherentInherentImpls | AttributeKind::RustcHiddenTypeOfOpaques | AttributeKind::RustcIfThisChanged(..) @@ -406,7 +407,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_strict_coherence | sym::rustc_mir | sym::rustc_outlives - | sym::rustc_evaluate_where_clauses | sym::rustc_partition_reused | sym::rustc_partition_codegened | sym::rustc_expected_cgu_reuse From 6361d5f279058c287d8684b232df512fe2562512 Mon Sep 17 00:00:00 2001 From: Oscar Bray Date: Wed, 4 Feb 2026 21:32:14 +0000 Subject: [PATCH 3404/3801] Parse #[rustc_outlives] --- .../src/attributes/test_attrs.rs | 14 ++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_hir_analysis/src/outlives/dump.rs | 4 +++- compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index 9effba39571c..18d700a20d31 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -214,3 +214,17 @@ impl NoArgsAttributeParser for RustcEvaluateWhereClausesParser { ]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEvaluateWhereClauses; } + +pub(crate) struct RustcOutlivesParser; + +impl NoArgsAttributeParser for RustcOutlivesParser { + const PATH: &[Symbol] = &[sym::rustc_outlives]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Struct), + Allow(Target::Enum), + Allow(Target::Union), + Allow(Target::TyAlias), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOutlives; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index d714a6399b82..f2d5d1c8c37e 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -283,6 +283,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 39f76002c419..4208da6ce722 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1192,6 +1192,9 @@ pub enum AttributeKind { /// Represents `#[rustc_offload_kernel]` RustcOffloadKernel, + /// Represents `#[rustc_outlives]` + RustcOutlives, + /// Represents `#[rustc_paren_sugar]`. RustcParenSugar(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 0b223c82c9b7..c87f31209ce5 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -142,6 +142,7 @@ impl AttributeKind { RustcObjcSelector { .. } => No, RustcObjectLifetimeDefault => No, RustcOffloadKernel => Yes, + RustcOutlives => No, RustcParenSugar(..) => No, RustcPassByValue(..) => Yes, RustcPassIndirectlyInNonRusticAbis(..) => No, diff --git a/compiler/rustc_hir_analysis/src/outlives/dump.rs b/compiler/rustc_hir_analysis/src/outlives/dump.rs index 4233896c3720..cf770a2561db 100644 --- a/compiler/rustc_hir_analysis/src/outlives/dump.rs +++ b/compiler/rustc_hir_analysis/src/outlives/dump.rs @@ -1,10 +1,12 @@ +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; use rustc_middle::bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::sym; pub(crate) fn inferred_outlives(tcx: TyCtxt<'_>) { for id in tcx.hir_free_items() { - if !tcx.has_attr(id.owner_id, sym::rustc_outlives) { + if !find_attr!(tcx.get_all_attrs(id.owner_id), AttributeKind::RustcOutlives) { continue; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 47dce81b8f5a..5f8e887675d0 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -334,6 +334,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcObjcClass { .. } | AttributeKind::RustcObjcSelector { .. } | AttributeKind::RustcOffloadKernel + | AttributeKind::RustcOutlives | AttributeKind::RustcParenSugar(..) | AttributeKind::RustcPassByValue (..) | AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) @@ -406,7 +407,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_capture_analysis | sym::rustc_strict_coherence | sym::rustc_mir - | sym::rustc_outlives | sym::rustc_partition_reused | sym::rustc_partition_codegened | sym::rustc_expected_cgu_reuse From fb55b5dcf33c3f134a41851771c3b13710a8a048 Mon Sep 17 00:00:00 2001 From: Jonatan Lindh Date: Sun, 8 Feb 2026 13:20:13 +0100 Subject: [PATCH 3405/3801] diagnostics: fix ICE in closure signature mismatch This fixes the ICE by renaming conflicting arguments in the diagnostic. --- compiler/rustc_trait_selection/src/errors.rs | 8 ++--- .../closure-arg-borrow-ice-issue-152331.rs | 10 ++++++ ...closure-arg-borrow-ice-issue-152331.stderr | 32 +++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 tests/ui/closures/closure-arg-borrow-ice-issue-152331.rs create mode 100644 tests/ui/closures/closure-arg-borrow-ice-issue-152331.stderr diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index e0690b8a6245..c904eb83896d 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -153,10 +153,10 @@ impl Subdiagnostic for AdjustSignatureBorrow { fn add_to_diag(self, diag: &mut Diag<'_, G>) { match self { AdjustSignatureBorrow::Borrow { to_borrow } => { - diag.arg("len", to_borrow.len()); + diag.arg("borrow_len", to_borrow.len()); diag.multipart_suggestion_verbose( inline_fluent!( - "consider adjusting the signature so it borrows its {$len -> + "consider adjusting the signature so it borrows its {$borrow_len -> [one] argument *[other] arguments }" @@ -166,10 +166,10 @@ impl Subdiagnostic for AdjustSignatureBorrow { ); } AdjustSignatureBorrow::RemoveBorrow { remove_borrow } => { - diag.arg("len", remove_borrow.len()); + diag.arg("remove_borrow_len", remove_borrow.len()); diag.multipart_suggestion_verbose( inline_fluent!( - "consider adjusting the signature so it does not borrow its {$len -> + "consider adjusting the signature so it does not borrow its {$remove_borrow_len -> [one] argument *[other] arguments }" diff --git a/tests/ui/closures/closure-arg-borrow-ice-issue-152331.rs b/tests/ui/closures/closure-arg-borrow-ice-issue-152331.rs new file mode 100644 index 000000000000..261f8fedc38f --- /dev/null +++ b/tests/ui/closures/closure-arg-borrow-ice-issue-152331.rs @@ -0,0 +1,10 @@ +fn main() { + h2(|_: (), _: (), _: (), x: &_| {}); + //~^ ERROR type mismatch in closure arguments +} + +fn h2(_: F) +where + F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())), +{ +} diff --git a/tests/ui/closures/closure-arg-borrow-ice-issue-152331.stderr b/tests/ui/closures/closure-arg-borrow-ice-issue-152331.stderr new file mode 100644 index 000000000000..7cfc9f0576ec --- /dev/null +++ b/tests/ui/closures/closure-arg-borrow-ice-issue-152331.stderr @@ -0,0 +1,32 @@ +error[E0631]: type mismatch in closure arguments + --> $DIR/closure-arg-borrow-ice-issue-152331.rs:2:5 + | +LL | h2(|_: (), _: (), _: (), x: &_| {}); + | ^^^----------------------------^^^^ + | | | + | | found signature defined here + | expected due to this + | + = note: expected closure signature `for<'a, 't0> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'t0 (), for<'a, 'b> fn(&'a (), &'b ())) -> _` + found closure signature `fn((), (), (), &_) -> _` +note: required by a bound in `h2` + --> $DIR/closure-arg-borrow-ice-issue-152331.rs:8:8 + | +LL | fn h2(_: F) + | -- required by a bound in this function +LL | where +LL | F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `h2` +help: consider adjusting the signature so it borrows its arguments + | +LL | h2(|_: &(), _: (), _: &(), x: &_| {}); + | + + +help: consider adjusting the signature so it does not borrow its argument + | +LL - h2(|_: (), _: (), _: (), x: &_| {}); +LL + h2(|_: (), _: (), _: (), x: _| {}); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0631`. From 053f76e9f07c1e307cd343a59cff6ed3276fc4ad Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 8 Feb 2026 13:46:29 +0100 Subject: [PATCH 3406/3801] `cfg_select!`: allow optional comma after { /* ... */ } --- compiler/rustc_parse/src/parser/cfg_select.rs | 13 +++++--- tests/ui/macros/cfg_select.rs | 7 ++-- tests/ui/macros/cfg_select.stderr | 32 +++++++++---------- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_parse/src/parser/cfg_select.rs b/compiler/rustc_parse/src/parser/cfg_select.rs index 9692d2c70893..b12209f0b92e 100644 --- a/compiler/rustc_parse/src/parser/cfg_select.rs +++ b/compiler/rustc_parse/src/parser/cfg_select.rs @@ -7,14 +7,19 @@ use crate::exp; use crate::parser::{AttrWrapper, ForceCollect, Parser, Restrictions, Trailing, UsePreAttrPos}; impl<'a> Parser<'a> { - /// Parses a `TokenTree` consisting either of `{ /* ... */ }` (and strip the braces) or an - /// expression followed by a comma (and strip the comma). + /// Parses a `TokenTree` consisting either of `{ /* ... */ }` optionally followed by a comma + /// (and strip the braces and the optional comma) or an expression followed by a comma + /// (and strip the comma). pub fn parse_delimited_token_tree(&mut self) -> PResult<'a, TokenStream> { if self.token == token::OpenBrace { // Strip the outer '{' and '}'. match self.parse_token_tree() { - TokenTree::Token(..) => unreachable!("because of the expect above"), - TokenTree::Delimited(.., tts) => return Ok(tts), + TokenTree::Token(..) => unreachable!("because the current token is a '{{'"), + TokenTree::Delimited(.., tts) => { + // Optionally end with a comma. + let _ = self.eat(exp!(Comma)); + return Ok(tts); + } } } let expr = self.collect_tokens(None, AttrWrapper::empty(), ForceCollect::Yes, |p, _| { diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index 0f009756e211..693e27daad7a 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -34,6 +34,7 @@ fn arm_rhs_expr_3() -> i32 { any(true) => 1, any(false) => 2, any(true) => { 42 } + any(true) => { 42 }, any(false) => -1 as i32, any(true) => 2 + 2, any(false) => "", @@ -62,7 +63,7 @@ fn expand_to_statements() -> i32 { } type ExpandToType = cfg_select! { - unix => u32, + unix => { u32 }, _ => i32, }; @@ -113,7 +114,7 @@ impl T for S { cfg_select! { false => { fn a() {} - } + }, _ => { fn b() {} } @@ -145,7 +146,7 @@ cfg_select! { cfg_select! { unix => {} - not(unix) => {} + not(unix) => {}, _ => {} //~^ WARN unreachable configuration predicate } diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 5878708668d3..2da0c2169497 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -1,5 +1,5 @@ error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:161:1 + --> $DIR/cfg_select.rs:162:1 | LL | / cfg_select! { LL | | @@ -8,55 +8,55 @@ LL | | } | |_^ error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:166:1 + --> $DIR/cfg_select.rs:167:1 | LL | cfg_select! {} | ^^^^^^^^^^^^^^ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `=>` - --> $DIR/cfg_select.rs:170:5 + --> $DIR/cfg_select.rs:171:5 | LL | => {} | ^^ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression - --> $DIR/cfg_select.rs:175:5 + --> $DIR/cfg_select.rs:176:5 | LL | () => {} | ^^ expressions are not allowed here error[E0539]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:180:5 + --> $DIR/cfg_select.rs:181:5 | LL | "str" => {} | ^^^^^ expected a valid identifier here error[E0539]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:185:5 + --> $DIR/cfg_select.rs:186:5 | LL | a::b => {} | ^^^^ expected a valid identifier here error[E0537]: invalid predicate `a` - --> $DIR/cfg_select.rs:190:5 + --> $DIR/cfg_select.rs:191:5 | LL | a() => {} | ^^^ error: expected one of `(`, `::`, `=>`, or `=`, found `+` - --> $DIR/cfg_select.rs:195:7 + --> $DIR/cfg_select.rs:196:7 | LL | a + 1 => {} | ^ expected one of `(`, `::`, `=>`, or `=` error: expected one of `(`, `::`, `=>`, or `=`, found `!` - --> $DIR/cfg_select.rs:201:8 + --> $DIR/cfg_select.rs:202:8 | LL | cfg!() => {} | ^ expected one of `(`, `::`, `=>`, or `=` warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:136:5 + --> $DIR/cfg_select.rs:137:5 | LL | _ => {} | - always matches @@ -70,7 +70,7 @@ LL | #![warn(unreachable_cfg_select_predicates)] // Unused warnings are disabled | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:142:5 + --> $DIR/cfg_select.rs:143:5 | LL | true => {} | ---- always matches @@ -78,25 +78,25 @@ LL | _ => {} | ^ this configuration predicate is never reached warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:149:5 + --> $DIR/cfg_select.rs:150:5 | LL | _ => {} | ^ this configuration predicate is never reached warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:155:5 + --> $DIR/cfg_select.rs:156:5 | LL | test => {} | ^^^^ this configuration predicate is never reached warning: unreachable configuration predicate - --> $DIR/cfg_select.rs:157:5 + --> $DIR/cfg_select.rs:158:5 | LL | _ => {} | ^ this configuration predicate is never reached warning: unexpected `cfg` condition name: `a` - --> $DIR/cfg_select.rs:195:5 + --> $DIR/cfg_select.rs:196:5 | LL | a + 1 => {} | ^ help: found config with similar value: `target_feature = "a"` @@ -107,7 +107,7 @@ LL | a + 1 => {} = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `cfg` - --> $DIR/cfg_select.rs:201:5 + --> $DIR/cfg_select.rs:202:5 | LL | cfg!() => {} | ^^^ From f693a1df2b5fd345f73f78ac674c6b8c67314d61 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 8 Feb 2026 14:12:42 +0100 Subject: [PATCH 3407/3801] Update diagnostics documentation --- .../src/diagnostics/diagnostic-structs.md | 173 ++++++------------ 1 file changed, 53 insertions(+), 120 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md index 4e5c3413cb8a..2260b1ec4df1 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md @@ -12,7 +12,7 @@ customizing the rendering logic, or selecting messages at runtime, you will need the corresponding trait (`Diagnostic`, `LintDiagnostic`, or `Subdiagnostic`). This approach provides greater flexibility and is recommended for diagnostics that go beyond simple, static structures. -Diagnostic can be translated into different languages and each has a slug that uniquely identifies the diagnostic. +Diagnostic can be translated into different languages. ## `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` @@ -21,13 +21,13 @@ shown below: ```rust,ignore #[derive(Diagnostic)] -#[diag(hir_analysis_field_already_declared, code = E0124)] +#[diag("field `{$field_name}` is already declared", code = E0124)] pub struct FieldAlreadyDeclared { pub field_name: Ident, #[primary_span] - #[label] + #[label("field already declared")] pub span: Span, - #[label(previous_decl_label)] + #[label("`{$field_name}` first declared here")] pub prev_span: Span, } ``` @@ -42,25 +42,10 @@ the `code` sub-attribute. Specifying a `code` isn't mandatory, but if you are porting a diagnostic that uses `Diag` to use `Diagnostic` then you should keep the code if there was one. -`#[diag(..)]` must provide a slug as the first positional argument (a path to an -item in `rustc_errors::fluent::*`). A slug uniquely identifies the diagnostic -and is also how the compiler knows what error message to emit (in the default -locale of the compiler, or in the locale requested by the user). See +`#[diag(..)]` must provide a message as the first positional argument. +The message is written in English, but might be translated to the locale requested by the user. See [translation documentation](./translation.md) to learn more about how -translatable error messages are written and how slug items are generated. - -In our example, the Fluent message for the "field already declared" diagnostic -looks like this: - -```fluent -hir_analysis_field_already_declared = - field `{$field_name}` is already declared - .label = field already declared - .previous_decl_label = `{$field_name}` first declared here -``` - -`hir_analysis_field_already_declared` is the slug from our example and is followed -by the diagnostic message. +translatable error messages are written and how they are generated. Every field of the `Diagnostic` which does not have an annotation is available in Fluent messages as a variable, like `field_name` in the example @@ -76,13 +61,7 @@ specified on a `Diagnostic`. `#[label]`, `#[help]`, `#[warning]` and `#[note]` can all be applied to fields which have the type `Span`. Applying any of these attributes will create the corresponding -subdiagnostic with that `Span`. These attributes will look for their -diagnostic message in a Fluent attribute attached to the primary Fluent -message. In our example, `#[label]` will look for -`hir_analysis_field_already_declared.label` (which has the message "field already -declared"). If there is more than one subdiagnostic of the same type, then -these attributes can also take a value that is the attribute name to look for -(e.g. `previous_decl_label` in our example). +subdiagnostic with that `Span`. These attributes take a diagnostic message as an argument. Other types have special behavior when used in a `Diagnostic` derive: @@ -99,17 +78,17 @@ represent optional `#[note]`/`#[help]`/`#[warning]` subdiagnostics. Suggestions can be emitted using one of four field attributes: -- `#[suggestion(slug, code = "...", applicability = "...")]` -- `#[suggestion_hidden(slug, code = "...", applicability = "...")]` -- `#[suggestion_short(slug, code = "...", applicability = "...")]` -- `#[suggestion_verbose(slug, code = "...", applicability = "...")]` +- `#[suggestion("message", code = "...", applicability = "...")]` +- `#[suggestion_hidden("message", code = "...", applicability = "...")]` +- `#[suggestion_short("message", code = "...", applicability = "...")]` +- `#[suggestion_verbose("message", code = "...", applicability = "...")]` Suggestions must be applied on either a `Span` field or a `(Span, -MachineApplicability)` field. Similarly to other field attributes, the slug -specifies the Fluent attribute with the message and defaults to the equivalent -of `.suggestion`. `code` specifies the code that should be suggested as a +MachineApplicability)` field. Similarly to other field attributes, a message +needs to be provided which will be shown to the user. +`code` specifies the code that should be suggested as a replacement and is a format string (e.g. `{field_name}` would be replaced by -the value of the `field_name` field of the struct), not a Fluent identifier. +the value of the `field_name` field of the struct). `applicability` can be used to specify the applicability in the attribute, it cannot be used when the field's type contains an `Applicability`. @@ -119,15 +98,15 @@ In the end, the `Diagnostic` derive will generate an implementation of ```rust,ignore impl<'a, G: EmissionGuarantee> Diagnostic<'a> for FieldAlreadyDeclared { fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> { - let mut diag = Diag::new(dcx, level, fluent::hir_analysis_field_already_declared); + let mut diag = Diag::new(dcx, level, "field `{$field_name}` is already declared"); diag.set_span(self.span); diag.span_label( self.span, - fluent::hir_analysis_label + "field already declared" ); diag.span_label( self.prev_span, - fluent::hir_analysis_previous_decl_label + "`{$field_name}` first declared here" ); diag } @@ -150,60 +129,40 @@ tcx.dcx().emit_err(FieldAlreadyDeclared { `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` support the following attributes: -- `#[diag(slug, code = "...")]` +- `#[diag("message", code = "...")]` - _Applied to struct or enum variant._ - _Mandatory_ - Defines the text and error code to be associated with the diagnostic. - - Slug (_Mandatory_) - - Uniquely identifies the diagnostic and corresponds to its Fluent message, - mandatory. - - A path to an item in `rustc_errors::fluent`, e.g. - `rustc_errors::fluent::hir_analysis_field_already_declared` - (`rustc_errors::fluent` is implicit in the attribute, so just - `hir_analysis_field_already_declared`). + - Message (_Mandatory_) + - The diagnostic message which will be shown to the user. - See [translation documentation](./translation.md). - `code = "..."` (_Optional_) - Specifies the error code. -- `#[note]` or `#[note(slug)]` (_Optional_) +- `#[note("message")]` (_Optional_) - _Applied to struct or struct fields of type `Span`, `Option<()>` or `()`._ - Adds a note subdiagnostic. - - Value is a path to an item in `rustc_errors::fluent` for the note's - message. - - Defaults to equivalent of `.note`. + - Value is the note's message. - If applied to a `Span` field, creates a spanned note. -- `#[help]` or `#[help(slug)]` (_Optional_) +- `#[help("message")]` (_Optional_) - _Applied to struct or struct fields of type `Span`, `Option<()>` or `()`._ - Adds a help subdiagnostic. - - Value is a path to an item in `rustc_errors::fluent` for the note's - message. - - Defaults to equivalent of `.help`. + - Value is the help message. - If applied to a `Span` field, creates a spanned help. -- `#[label]` or `#[label(slug)]` (_Optional_) +- `#[label("message")]` (_Optional_) - _Applied to `Span` fields._ - Adds a label subdiagnostic. - - Value is a path to an item in `rustc_errors::fluent` for the note's - message. - - Defaults to equivalent of `.label`. -- `#[warning]` or `#[warning(slug)]` (_Optional_) + - Value is the label's message. +- `#[warning("message")]` (_Optional_) - _Applied to struct or struct fields of type `Span`, `Option<()>` or `()`._ - Adds a warning subdiagnostic. - - Value is a path to an item in `rustc_errors::fluent` for the note's - message. - - Defaults to equivalent of `.warn`. -- `#[suggestion{,_hidden,_short,_verbose}(slug, code = "...", applicability = "...")]` + - Value is the warning's message. +- `#[suggestion{,_hidden,_short,_verbose}("message", code = "...", applicability = "...")]` (_Optional_) - _Applied to `(Span, MachineApplicability)` or `Span` fields._ - Adds a suggestion subdiagnostic. - - Slug (_Mandatory_) - - A path to an item in `rustc_errors::fluent`, e.g. - `rustc_errors::fluent::hir_analysis_field_already_declared` - (`rustc_errors::fluent` is implicit in the attribute, so just - `hir_analysis_field_already_declared`). Fluent attributes for all messages - exist as top-level items in that module (so `hir_analysis_message.attr` is just - `attr`). + - Message (_Mandatory_) + - Value is the suggestion message that will be shown to the user. - See [translation documentation](./translation.md). - - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or - - `.suggestion` in Fluent). - `code = "..."`/`code("...", ...)` (_Mandatory_) - One or multiple format strings indicating the code to be suggested as a replacement. Multiple values signify multiple possible replacements. @@ -235,12 +194,12 @@ shown below: ```rust #[derive(Subdiagnostic)] pub enum ExpectedReturnTypeLabel<'tcx> { - #[label(hir_analysis_expected_default_return_type)] + #[label("expected `()` because of default return type")] Unit { #[primary_span] span: Span, }, - #[label(hir_analysis_expected_return_type)] + #[label("expected `{$expected}` because of return type")] Other { #[primary_span] span: Span, @@ -260,21 +219,9 @@ attribute applied to the struct or each variant, one of: - `#[warning(..)]` for defining a warning - `#[suggestion{,_hidden,_short,_verbose}(..)]` for defining a suggestion -All of the above must provide a slug as the first positional argument (a path -to an item in `rustc_errors::fluent::*`). A slug uniquely identifies the -diagnostic and is also how the compiler knows what error message to emit (in -the default locale of the compiler, or in the locale requested by the user). +All of the above must provide a diagnostic message as the first positional argument. See [translation documentation](./translation.md) to learn more about how -translatable error messages are written and how slug items are generated. - -In our example, the Fluent message for the "expected return type" label -looks like this: - -```fluent -hir_analysis_expected_default_return_type = expected `()` because of default return type - -hir_analysis_expected_return_type = expected `{$expected}` because of return type -``` +translatable error messages are generated. Using the `#[primary_span]` attribute on a field (with type `Span`) will denote the primary span of the subdiagnostic. A primary span is only necessary for a @@ -289,17 +236,15 @@ Like `Diagnostic`, `Subdiagnostic` supports `Option` and Suggestions can be emitted using one of four attributes on the type/variant: -- `#[suggestion(..., code = "...", applicability = "...")]` -- `#[suggestion_hidden(..., code = "...", applicability = "...")]` -- `#[suggestion_short(..., code = "...", applicability = "...")]` -- `#[suggestion_verbose(..., code = "...", applicability = "...")]` +- `#[suggestion("...", code = "...", applicability = "...")]` +- `#[suggestion_hidden("...", code = "...", applicability = "...")]` +- `#[suggestion_short("...", code = "...", applicability = "...")]` +- `#[suggestion_verbose("...", code = "...", applicability = "...")]` Suggestions require `#[primary_span]` be set on a field and can have the following sub-attributes: -- The first positional argument specifies the path to a item in - `rustc_errors::fluent` corresponding to the Fluent attribute with the message - and defaults to the equivalent of `.suggestion`. +- The first positional argument specifies the message which will be shown to the user. - `code` specifies the code that should be suggested as a replacement and is a format string (e.g. `{field_name}` would be replaced by the value of the `field_name` field of the struct), not a Fluent identifier. @@ -318,11 +263,11 @@ impl<'tcx> Subdiagnostic for ExpectedReturnTypeLabel<'tcx> { use rustc_errors::{Applicability, IntoDiagArg}; match self { ExpectedReturnTypeLabel::Unit { span } => { - diag.span_label(span, rustc_errors::fluent::hir_analysis_expected_default_return_type) + diag.span_label(span, "expected `()` because of default return type") } ExpectedReturnTypeLabel::Other { span, expected } => { diag.set_arg("expected", expected); - diag.span_label(span, rustc_errors::fluent::hir_analysis_expected_return_type) + diag.span_label(span, "expected `{$expected}` because of return type") } } } @@ -354,7 +299,7 @@ If a subdiagnostic sets a argument with the same name as a arguments already in it will report an error at runtime unless both have exactly the same value. It has two benefits: - preserves the flexibility that arguments in the main diagnostic are allowed to appear in the attributes of the subdiagnostic. -For example, There is an attribute `#[suggestion(code = "{new_vis}")]` in the subdiagnostic, but `new_vis` is the field in the main diagnostic struct. +For example, There is an attribute `#[suggestion("...", code = "{new_vis}")]` in the subdiagnostic, but `new_vis` is the field in the main diagnostic struct. - prevents accidental overwriting or deletion of arguments required by the main diagnostic or other subdiagnostics. These rules guarantee that arguments injected by subdiagnostics are strictly scoped to their own rendering. @@ -364,32 +309,20 @@ Additionally, subdiagnostics can access arguments from the main diagnostic with ### Reference for `#[derive(Subdiagnostic)]` `#[derive(Subdiagnostic)]` supports the following attributes: -- `#[label(slug)]`, `#[help(slug)]`, `#[warning(slug)]` or `#[note(slug)]` +- `#[label("message")]`, `#[help("message")]`, `#[warning("message")]` or `#[note("message")]` - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ - _Mandatory_ - Defines the type to be representing a label, help or note. - - Slug (_Mandatory_) - - Uniquely identifies the diagnostic and corresponds to its Fluent message, - mandatory. - - A path to an item in `rustc_errors::fluent`, e.g. - `rustc_errors::fluent::hir_analysis_field_already_declared` - (`rustc_errors::fluent` is implicit in the attribute, so just - `hir_analysis_field_already_declared`). + - Message (_Mandatory_) + - The diagnostic message that will be shown to the user. - See [translation documentation](./translation.md). -- `#[suggestion{,_hidden,_short,_verbose}(slug, code = "...", applicability = "...")]` +- `#[suggestion{,_hidden,_short,_verbose}("message", code = "...", applicability = "...")]` - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ - _Mandatory_ - Defines the type to be representing a suggestion. - - Slug (_Mandatory_) - - A path to an item in `rustc_errors::fluent`, e.g. - `rustc_errors::fluent::hir_analysis_field_already_declared` - (`rustc_errors::fluent` is implicit in the attribute, so just - `hir_analysis::field_already_declared`). Fluent attributes for all messages - exist as top-level items in that module (so `hir_analysis_message.attr` is just - `hir_analysis::attr`). + - Message (_Mandatory_) + - The diagnostic message that will be shown to the user. - See [translation documentation](./translation.md). - - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or - - `.suggestion` in Fluent). - `code = "..."`/`code("...", ...)` (_Mandatory_) - One or multiple format strings indicating the code to be suggested as a replacement. Multiple values signify multiple possible replacements. @@ -401,11 +334,11 @@ Additionally, subdiagnostics can access arguments from the main diagnostic with - `maybe-incorrect` - `has-placeholders` - `unspecified` -- `#[multipart_suggestion{,_hidden,_short,_verbose}(slug, applicability = "...")]` +- `#[multipart_suggestion{,_hidden,_short,_verbose}("message", applicability = "...")]` - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ - _Mandatory_ - Defines the type to be representing a multipart suggestion. - - Slug (_Mandatory_): see `#[suggestion]` + - Message (_Mandatory_): see `#[suggestion]` - `applicability = "..."` (_Optional_): see `#[suggestion]` - `#[primary_span]` (_Mandatory_ for labels and suggestions; _optional_ otherwise; not applicable to multipart suggestions) From 37a314b719af622c982c29fad4aeb992f5068035 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 8 Feb 2026 14:12:46 +0100 Subject: [PATCH 3408/3801] Update translation documentation --- .../src/diagnostics/translation.md | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/diagnostics/translation.md b/src/doc/rustc-dev-guide/src/diagnostics/translation.md index 58d75f54a005..fcb26fab667c 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/translation.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/translation.md @@ -13,10 +13,7 @@ active redesign proposals (as of Please see the tracking issue for status updates. -We have downgraded the internal lints `untranslatable_diagnostic` and -`diagnostic_outside_of_impl`. Those internal lints previously required new code -to use the current translation infrastructure. However, because the translation -infra is waiting for a yet-to-be-proposed redesign and thus rework, we are not +The translation infra is waiting for a yet-to-be-proposed redesign and thus rework, we are not mandating usage of current translation infra. Use the infra if you *want to* or otherwise makes the code cleaner, but otherwise sidestep the translation infra if you need more flexibility. @@ -40,11 +37,6 @@ There are two ways of writing translatable diagnostics: When adding or changing a translatable diagnostic, you don't need to worry about the translations. Only updating the original English message is required. -Currently, -each crate which defines translatable diagnostics has its own Fluent resource, -which is a file named `messages.ftl`, -located in the root of the crate -(such as`compiler/rustc_expand/messages.ftl`). ## Fluent @@ -118,11 +110,8 @@ information that needs to be provided by the code to do so. ### Compile-time validation and typed identifiers -rustc's `fluent_messages` macro performs compile-time validation of Fluent -resources and generates code to make it easier to refer to Fluent messages in -diagnostics. - -Compile-time validation of Fluent resources will emit any parsing errors +rustc's `#[derive(Diagnostic)]` macro performs compile-time validation of Fluent +messages. Compile-time validation of Fluent resources will emit any parsing errors from Fluent resources while building the compiler, preventing invalid Fluent resources from causing panics in the compiler. Compile-time validation also emits an error if multiple Fluent messages have the same identifier. From d8ff397cd69c50d735e3ff6e7e4cbfe18c1b01dc Mon Sep 17 00:00:00 2001 From: Adwin White Date: Sun, 8 Feb 2026 12:38:02 +0800 Subject: [PATCH 3409/3801] check stalled coroutine obligations eagerly --- compiler/rustc_borrowck/src/lib.rs | 5 +++++ compiler/rustc_interface/src/passes.rs | 18 +++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 361e98454e83..38b73a07a689 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -121,6 +121,11 @@ fn mir_borrowck( let (input_body, _) = tcx.mir_promoted(def); debug!("run query mir_borrowck: {}", tcx.def_path_str(def)); + // We should eagerly check stalled coroutine obligations from HIR typeck. + // Not doing so leads to silent normalization failures later, which will + // fail to register opaque types in the next solver. + tcx.check_coroutine_obligations(def)?; + let input_body: &Body<'_> = &input_body.borrow(); if let Some(guar) = input_body.tainted_by_errors { debug!("Skipping borrowck because of tainted body"); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 35f8c44b685d..23c59602d296 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1116,18 +1116,14 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { { tcx.ensure_ok().mir_drops_elaborated_and_const_checked(def_id); } - if tcx.is_coroutine(def_id.to_def_id()) { - tcx.ensure_ok().mir_coroutine_witnesses(def_id); - let _ = tcx.ensure_ok().check_coroutine_obligations( - tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(), + if tcx.is_coroutine(def_id.to_def_id()) + && (!tcx.is_async_drop_in_place_coroutine(def_id.to_def_id())) + { + // Eagerly check the unsubstituted layout for cycles. + tcx.ensure_ok().layout_of( + ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) + .as_query_input(tcx.type_of(def_id).instantiate_identity()), ); - if !tcx.is_async_drop_in_place_coroutine(def_id.to_def_id()) { - // Eagerly check the unsubstituted layout for cycles. - tcx.ensure_ok().layout_of( - ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) - .as_query_input(tcx.type_of(def_id).instantiate_identity()), - ); - } } }); }); From 8aa0e905f4a1806a9406eb7c34e0c58157dc2856 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 8 Feb 2026 10:23:58 +0100 Subject: [PATCH 3410/3801] Fix suggestion on `CallToDeprecatedSafeFnRequiresUnsafe` diagnostic --- compiler/rustc_mir_build/src/errors.rs | 2 +- .../unsafe-before_exec-suggestion.fixed | 18 ++++++++++++++++ .../unsafe-before_exec-suggestion.rs | 17 +++++++++++++++ .../unsafe-before_exec-suggestion.stderr | 21 +++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/ui/rust-2024/unsafe-before_exec-suggestion.fixed create mode 100644 tests/ui/rust-2024/unsafe-before_exec-suggestion.rs create mode 100644 tests/ui/rust-2024/unsafe-before_exec-suggestion.stderr diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 13d8211999e6..2474b3c49a61 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -22,7 +22,7 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe { #[derive(Subdiagnostic)] #[multipart_suggestion( - "you can wrap the call in an `unsafe` block if you can guarantee that the environment access only happens in single-threaded code", + "you can wrap the call in an `unsafe` block if you can guarantee {$guarantee}", applicability = "machine-applicable" )] pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub { diff --git a/tests/ui/rust-2024/unsafe-before_exec-suggestion.fixed b/tests/ui/rust-2024/unsafe-before_exec-suggestion.fixed new file mode 100644 index 000000000000..d850428cc1a5 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-before_exec-suggestion.fixed @@ -0,0 +1,18 @@ +//@ edition:2015 +//@ only-unix +//@ run-rustfix + +#![deny(deprecated_safe_2024)] + +use std::process::Command; +use std::os::unix::process::CommandExt; + +#[allow(deprecated)] +fn main() { + let mut cmd = Command::new("sleep"); + // TODO: Audit that the closure is async-signal-safe. + unsafe { cmd.before_exec(|| Ok(())) }; + //~^ ERROR call to deprecated safe function + //~| WARN this is accepted in the current edition + drop(cmd); +} diff --git a/tests/ui/rust-2024/unsafe-before_exec-suggestion.rs b/tests/ui/rust-2024/unsafe-before_exec-suggestion.rs new file mode 100644 index 000000000000..c6894ea631ae --- /dev/null +++ b/tests/ui/rust-2024/unsafe-before_exec-suggestion.rs @@ -0,0 +1,17 @@ +//@ edition:2015 +//@ only-unix +//@ run-rustfix + +#![deny(deprecated_safe_2024)] + +use std::process::Command; +use std::os::unix::process::CommandExt; + +#[allow(deprecated)] +fn main() { + let mut cmd = Command::new("sleep"); + cmd.before_exec(|| Ok(())); + //~^ ERROR call to deprecated safe function + //~| WARN this is accepted in the current edition + drop(cmd); +} diff --git a/tests/ui/rust-2024/unsafe-before_exec-suggestion.stderr b/tests/ui/rust-2024/unsafe-before_exec-suggestion.stderr new file mode 100644 index 000000000000..33893f30ceca --- /dev/null +++ b/tests/ui/rust-2024/unsafe-before_exec-suggestion.stderr @@ -0,0 +1,21 @@ +error: call to deprecated safe function `std::os::unix::process::CommandExt::before_exec` is unsafe and requires unsafe block + --> $DIR/unsafe-before_exec-suggestion.rs:13:5 + | +LL | cmd.before_exec(|| Ok(())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see +note: the lint level is defined here + --> $DIR/unsafe-before_exec-suggestion.rs:5:9 + | +LL | #![deny(deprecated_safe_2024)] + | ^^^^^^^^^^^^^^^^^^^^ +help: you can wrap the call in an `unsafe` block if you can guarantee that the closure is async-signal-safe + | +LL + // TODO: Audit that the closure is async-signal-safe. +LL ~ unsafe { cmd.before_exec(|| Ok(())) }; + | + +error: aborting due to 1 previous error + From d14c26f45a84eff6eabddd8c0e0580d851ade217 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 8 Feb 2026 10:24:07 +0100 Subject: [PATCH 3411/3801] Fix help on `AmbiguousMissingKwForItemSub` diagnostic --- compiler/rustc_parse/src/errors.rs | 4 +++- tests/ui/macros/metavar-expressions/usage-errors.rs | 2 ++ tests/ui/macros/metavar-expressions/usage-errors.stderr | 8 ++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 418d56f632bd..b54782ec592c 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2266,7 +2266,9 @@ pub(crate) enum AmbiguousMissingKwForItemSub { span: Span, snippet: String, }, - #[help("you likely meant to define an item, e.g., `{$vis} fn foo() {\"{}\"}`")] + #[help( + "if you meant to call a macro, remove the `pub` and add a trailing `!` after the identifier" + )] HelpMacro, } diff --git a/tests/ui/macros/metavar-expressions/usage-errors.rs b/tests/ui/macros/metavar-expressions/usage-errors.rs index feff02e2ce47..966ffadb32af 100644 --- a/tests/ui/macros/metavar-expressions/usage-errors.rs +++ b/tests/ui/macros/metavar-expressions/usage-errors.rs @@ -27,6 +27,7 @@ curly__rhs_dollar__no_round !(a); macro_rules! no_curly__no_rhs_dollar__round { ( $( $i:ident ),* ) => { count(i) }; //~^ ERROR missing `fn` or `struct` for function or struct definition + //~| HELP if you meant to call a macro, try } no_curly__no_rhs_dollar__round !(a, b, c); @@ -34,6 +35,7 @@ no_curly__no_rhs_dollar__round !(a, b, c); macro_rules! no_curly__no_rhs_dollar__no_round { ( $i:ident ) => { count(i) }; //~^ ERROR missing `fn` or `struct` for function or struct definition + //~| HELP if you meant to call a macro, try } no_curly__no_rhs_dollar__no_round !(a); diff --git a/tests/ui/macros/metavar-expressions/usage-errors.stderr b/tests/ui/macros/metavar-expressions/usage-errors.stderr index f66f522e23b9..3d22e3ac4b30 100644 --- a/tests/ui/macros/metavar-expressions/usage-errors.stderr +++ b/tests/ui/macros/metavar-expressions/usage-errors.stderr @@ -26,7 +26,7 @@ LL | ( $( $i:ident ),* ) => { count!(i) }; | + error: missing `fn` or `struct` for function or struct definition - --> $DIR/usage-errors.rs:35:23 + --> $DIR/usage-errors.rs:36:23 | LL | ( $i:ident ) => { count(i) }; | ^^^^^ @@ -41,13 +41,13 @@ LL | ( $i:ident ) => { count!(i) }; | + error: variable `i` is still repeating at this depth - --> $DIR/usage-errors.rs:42:36 + --> $DIR/usage-errors.rs:44:36 | LL | ( $( $i:ident ),* ) => { count($i) }; | ^^ error[E0425]: cannot find value `a` in this scope - --> $DIR/usage-errors.rs:52:49 + --> $DIR/usage-errors.rs:54:49 | LL | ( $i:ident ) => { count($i) }; | -- due to this macro variable @@ -56,7 +56,7 @@ LL | const _: u32 = no_curly__rhs_dollar__no_round! (a); | ^ not found in this scope error[E0425]: cannot find function `count` in this scope - --> $DIR/usage-errors.rs:49:23 + --> $DIR/usage-errors.rs:51:23 | LL | ( $i:ident ) => { count($i) }; | ^^^^^ not found in this scope From f605c0ab7c66506172600ad37a05be3603a20dd2 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 8 Feb 2026 22:14:06 +0530 Subject: [PATCH 3412/3801] self_param and impl_ implementation in syntax_factory --- .../src/ast/syntax_factory/constructors.rs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 5fe419ad4eb7..ad9b9054a8f5 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -1590,6 +1590,65 @@ impl SyntaxFactory { ast } + pub fn self_param(&self) -> ast::SelfParam { + let ast = make::self_param().clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn impl_( + &self, + attrs: impl IntoIterator, + generic_params: Option, + generic_args: Option, + path_type: ast::Type, + where_clause: Option, + body: Option, + ) -> ast::Impl { + let (attrs, attrs_input) = iterator_input(attrs); + let ast = make::impl_( + attrs, + generic_params.clone(), + generic_args.clone(), + path_type.clone(), + where_clause.clone(), + body.clone(), + ) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(attrs_input, ast.attrs().map(|attr| attr.syntax().clone())); + if let Some(generic_params) = generic_params { + builder.map_node( + generic_params.syntax().clone(), + ast.generic_param_list().unwrap().syntax().clone(), + ); + } + builder.map_node(path_type.syntax().clone(), ast.self_ty().unwrap().syntax().clone()); + if let Some(where_clause) = where_clause { + builder.map_node( + where_clause.syntax().clone(), + ast.where_clause().unwrap().syntax().clone(), + ); + } + if let Some(body) = body { + builder.map_node( + body.syntax().clone(), + ast.assoc_item_list().unwrap().syntax().clone(), + ); + } + builder.finish(&mut mapping); + } + + ast + } + pub fn ret_type(&self, ty: ast::Type) -> ast::RetType { let ast = make::ret_type(ty.clone()).clone_for_update(); From fa31e1759a65a3689a6a9ed23eff65da9cc8ce76 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 8 Feb 2026 22:14:30 +0530 Subject: [PATCH 3413/3801] migrate generate_getter_or_setter to syntaxeditor api --- .../src/handlers/generate_getter_or_setter.rs | 161 +++++++++++------- 1 file changed, 100 insertions(+), 61 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs index 73e93a3fbf52..2db5e46bb093 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_getter_or_setter.rs @@ -2,13 +2,16 @@ use ide_db::{famous_defs::FamousDefs, source_change::SourceChangeBuilder}; use stdx::{format_to, to_lower_snake_case}; use syntax::{ TextRange, - ast::{self, AstNode, HasName, HasVisibility, edit_in_place::Indent, make}, - ted, + ast::{ + self, AstNode, HasGenericParams, HasName, HasVisibility, edit_in_place::Indent, + syntax_factory::SyntaxFactory, + }, + syntax_editor::Position, }; use crate::{ AssistContext, AssistId, Assists, GroupLabel, - utils::{convert_reference_type, find_struct_impl, generate_impl}, + utils::{convert_reference_type, find_struct_impl}, }; // Assist: generate_setter @@ -215,12 +218,14 @@ fn generate_getter_from_info( ctx: &AssistContext<'_>, info: &AssistInfo, record_field_info: &RecordFieldInfo, + syntax_factory: &SyntaxFactory, ) -> ast::Fn { let (ty, body) = if matches!(info.assist_type, AssistType::MutGet) { + let self_expr = syntax_factory.expr_path(syntax_factory.ident_path("self")); ( - make::ty_ref(record_field_info.field_ty.clone(), true), - make::expr_ref( - make::expr_field(make::ext::expr_self(), &record_field_info.field_name.text()), + syntax_factory.ty_ref(record_field_info.field_ty.clone(), true), + syntax_factory.expr_ref( + syntax_factory.expr_field(self_expr, &record_field_info.field_name.text()).into(), true, ), ) @@ -241,9 +246,14 @@ fn generate_getter_from_info( })() .unwrap_or_else(|| { ( - make::ty_ref(record_field_info.field_ty.clone(), false), - make::expr_ref( - make::expr_field(make::ext::expr_self(), &record_field_info.field_name.text()), + syntax_factory.ty_ref(record_field_info.field_ty.clone(), false), + syntax_factory.expr_ref( + syntax_factory + .expr_field( + syntax_factory.expr_path(syntax_factory.ident_path("self")), + &record_field_info.field_name.text(), + ) + .into(), false, ), ) @@ -251,18 +261,18 @@ fn generate_getter_from_info( }; let self_param = if matches!(info.assist_type, AssistType::MutGet) { - make::mut_self_param() + syntax_factory.mut_self_param() } else { - make::self_param() + syntax_factory.self_param() }; let strukt = &info.strukt; - let fn_name = make::name(&record_field_info.fn_name); - let params = make::param_list(Some(self_param), []); - let ret_type = Some(make::ret_type(ty)); - let body = make::block_expr([], Some(body)); + let fn_name = syntax_factory.name(&record_field_info.fn_name); + let params = syntax_factory.param_list(Some(self_param), []); + let ret_type = Some(syntax_factory.ret_type(ty)); + let body = syntax_factory.block_expr([], Some(body)); - make::fn_( + syntax_factory.fn_( None, strukt.visibility(), fn_name, @@ -278,28 +288,35 @@ fn generate_getter_from_info( ) } -fn generate_setter_from_info(info: &AssistInfo, record_field_info: &RecordFieldInfo) -> ast::Fn { +fn generate_setter_from_info( + info: &AssistInfo, + record_field_info: &RecordFieldInfo, + syntax_factory: &SyntaxFactory, +) -> ast::Fn { let strukt = &info.strukt; let field_name = &record_field_info.fn_name; - let fn_name = make::name(&format!("set_{field_name}")); + let fn_name = syntax_factory.name(&format!("set_{field_name}")); let field_ty = &record_field_info.field_ty; // Make the param list // `(&mut self, $field_name: $field_ty)` - let field_param = - make::param(make::ident_pat(false, false, make::name(field_name)).into(), field_ty.clone()); - let params = make::param_list(Some(make::mut_self_param()), [field_param]); + let field_param = syntax_factory.param( + syntax_factory.ident_pat(false, false, syntax_factory.name(field_name)).into(), + field_ty.clone(), + ); + let params = syntax_factory.param_list(Some(syntax_factory.mut_self_param()), [field_param]); // Make the assignment body // `self.$field_name = $field_name` - let self_expr = make::ext::expr_self(); - let lhs = make::expr_field(self_expr, field_name); - let rhs = make::expr_path(make::ext::ident_path(field_name)); - let assign_stmt = make::expr_stmt(make::expr_assignment(lhs, rhs).into()); - let body = make::block_expr([assign_stmt.into()], None); + let self_expr = syntax_factory.expr_path(syntax_factory.ident_path("self")); + let lhs = syntax_factory.expr_field(self_expr, field_name); + let rhs = syntax_factory.expr_path(syntax_factory.ident_path(field_name)); + let assign_stmt = + syntax_factory.expr_stmt(syntax_factory.expr_assignment(lhs.into(), rhs).into()); + let body = syntax_factory.block_expr([assign_stmt.into()], None); // Make the setter fn - make::fn_( + syntax_factory.fn_( None, strukt.visibility(), fn_name, @@ -403,47 +420,69 @@ fn build_source_change( info_of_record_fields: Vec, assist_info: AssistInfo, ) { - let record_fields_count = info_of_record_fields.len(); + let syntax_factory = SyntaxFactory::without_mappings(); - let impl_def = if let Some(impl_def) = &assist_info.impl_def { + let items: Vec = info_of_record_fields + .iter() + .map(|record_field_info| { + let method = match assist_info.assist_type { + AssistType::Set => { + generate_setter_from_info(&assist_info, record_field_info, &syntax_factory) + } + _ => { + generate_getter_from_info(ctx, &assist_info, record_field_info, &syntax_factory) + } + }; + let new_fn = method.clone_for_update(); + new_fn.indent(1.into()); + new_fn.into() + }) + .collect(); + + if let Some(impl_def) = &assist_info.impl_def { // We have an existing impl to add to - builder.make_mut(impl_def.clone()) - } else { - // Generate a new impl to add the methods to - let impl_def = generate_impl(&ast::Adt::Struct(assist_info.strukt.clone())); + let mut editor = builder.make_editor(impl_def.syntax()); + impl_def.assoc_item_list().unwrap().add_items(&mut editor, items.clone()); - // Insert it after the adt - let strukt = builder.make_mut(assist_info.strukt.clone()); - - ted::insert_all_raw( - ted::Position::after(strukt.syntax()), - vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()], - ); - - impl_def - }; - - let assoc_item_list = impl_def.get_or_create_assoc_item_list(); - - for (i, record_field_info) in info_of_record_fields.iter().enumerate() { - // Make the new getter or setter fn - let new_fn = match assist_info.assist_type { - AssistType::Set => generate_setter_from_info(&assist_info, record_field_info), - _ => generate_getter_from_info(ctx, &assist_info, record_field_info), - } - .clone_for_update(); - new_fn.indent(1.into()); - - // Insert a tabstop only for last method we generate - if i == record_fields_count - 1 - && let Some(cap) = ctx.config.snippet_cap - && let Some(name) = new_fn.name() + if let Some(cap) = ctx.config.snippet_cap + && let Some(ast::AssocItem::Fn(fn_)) = items.last() + && let Some(name) = fn_.name() { - builder.add_tabstop_before(cap, name); + let tabstop = builder.make_tabstop_before(cap); + editor.add_annotation(name.syntax(), tabstop); } - assoc_item_list.add_item(new_fn.clone().into()); + builder.add_file_edits(ctx.vfs_file_id(), editor); + return; } + let ty_params = assist_info.strukt.generic_param_list(); + let ty_args = ty_params.as_ref().map(|it| it.to_generic_args()); + let impl_def = syntax_factory.impl_( + None, + ty_params, + ty_args, + syntax_factory + .ty_path(syntax_factory.ident_path(&assist_info.strukt.name().unwrap().to_string())) + .into(), + None, + Some(syntax_factory.assoc_item_list(items)), + ); + let mut editor = builder.make_editor(assist_info.strukt.syntax()); + editor.insert_all( + Position::after(assist_info.strukt.syntax()), + vec![syntax_factory.whitespace("\n\n").into(), impl_def.syntax().clone().into()], + ); + + if let Some(cap) = ctx.config.snippet_cap + && let Some(assoc_list) = impl_def.assoc_item_list() + && let Some(ast::AssocItem::Fn(fn_)) = assoc_list.assoc_items().last() + && let Some(name) = fn_.name() + { + let tabstop = builder.make_tabstop_before(cap); + editor.add_annotation(name.syntax().clone(), tabstop); + } + + builder.add_file_edits(ctx.vfs_file_id(), editor); } #[cfg(test)] From 4d07a8f24c42c4cb7362ea8c4db8cfca62a846b2 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sun, 8 Feb 2026 12:29:59 -0500 Subject: [PATCH 3414/3801] std: Don't panic when removing a nonexistent UEFI var `std::env::remove_var` does not say that deleting a nonexistent variable is an error (and at least on Linux, it indeed does not cause an error). The UEFI Shell Protocol spec also doesn't say it's an error, but the edk2 implementation delegates to the UEFI runtime `SetVariable` function, which returns `EFI_NOT_FOUND` when trying to delete a nonexistent variable. Change the UEFI implementation to check for a `NotFound` error and treat it as success. --- library/std/src/sys/env/uefi.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/env/uefi.rs b/library/std/src/sys/env/uefi.rs index af16a02642a4..bc2aed423179 100644 --- a/library/std/src/sys/env/uefi.rs +++ b/library/std/src/sys/env/uefi.rs @@ -43,7 +43,20 @@ mod uefi_env { pub(crate) fn unset(key: &OsStr) -> io::Result<()> { let mut key_ptr = helpers::os_string_to_raw(key) .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid key"))?; - unsafe { set_raw(key_ptr.as_mut_ptr(), crate::ptr::null_mut()) } + let r = unsafe { set_raw(key_ptr.as_mut_ptr(), crate::ptr::null_mut()) }; + + // The UEFI Shell spec only lists `EFI_SUCCESS` as a possible return value for + // `SetEnv`, but the edk2 implementation can return errors. Allow most of these + // errors to bubble up to the caller, but ignore `NotFound` errors; deleting a + // nonexistent variable is not listed as an error condition of + // `std::env::remove_var`. + if let Err(err) = &r + && err.kind() == io::ErrorKind::NotFound + { + Ok(()) + } else { + r + } } pub(crate) fn get_all() -> io::Result> { From 9a30ec81498592914950d7a63253965e61d8cc05 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 7 Jan 2026 15:22:47 -0800 Subject: [PATCH 3415/3801] Implement MVP for opaque generic const arguments This is meant to be the interim successor to generic const expressions. Essentially, const item RHS's will be allowed to do arbitrary const operations using generics. The limitation is that these const items will be treated opaquely, like ADTs in nominal typing, such that uses of them will only be equal if the same const item is referenced. In other words, two const items with the exact same RHS will not be considered equal. I also added some logic to check feature gates that depend on others being enabled (like oGCA depending on mGCA). = Coherence = During coherence, OGCA consts should be normalized ambiguously because they are opaque but eventually resolved to a real value. We don't want two OGCAs that have the same value to be treated as distinct for coherence purposes. (Just like opaque types.) This actually doesn't work yet because there are pre-existing fundamental issues with equate relations involving consts that need to be normalized. The problem is that we normalize only one layer of the const item and don't actually process the resulting anon const. Normally the created inference variable should be handled, which in this case would cause us to hit the anon const, but that's not happening. Specifically, `visit_const` on `Generalizer` should be updated to be similar to `visit_ty`. --- compiler/rustc_ast_passes/src/errors.rs | 10 +++ compiler/rustc_ast_passes/src/feature_gate.rs | 22 +++++++ compiler/rustc_ast_passes/src/lib.rs | 1 + compiler/rustc_feature/src/lib.rs | 3 +- compiler/rustc_feature/src/unstable.rs | 8 +++ compiler/rustc_hir_analysis/src/collect.rs | 64 ++++++++++++++++++- .../src/collect/generics_of.rs | 2 + .../src/hir_ty_lowering/mod.rs | 5 ++ compiler/rustc_middle/src/ty/consts.rs | 15 +---- compiler/rustc_middle/src/ty/context.rs | 3 + compiler/rustc_middle/src/ty/mod.rs | 4 +- .../src/solve/normalizes_to/anon_const.rs | 15 ++++- compiler/rustc_parse/src/parser/item.rs | 4 +- compiler/rustc_span/src/symbol.rs | 1 + .../rustc_trait_selection/src/traits/mod.rs | 14 ++++ compiler/rustc_type_ir/src/const_kind.rs | 20 ++++++ compiler/rustc_type_ir/src/interner.rs | 1 + .../non_valtreeable_const_arg-2.rs | 2 +- .../non_valtreeable_const_arg-2.stderr | 6 +- .../associated-const-bindings/ambiguity.rs | 2 +- .../coexisting-with-type-binding.rs | 2 +- ...dyn-compat-assoc-const-ty-mentions-self.rs | 1 + ...compat-assoc-const-ty-mentions-self.stderr | 4 +- ...elf-const-projections-in-assoc-const-ty.rs | 13 +++- ...const-projections-in-assoc-const-ty.stderr | 8 +-- .../esc-bound-var-in-ty.rs | 1 + .../esc-bound-var-in-ty.stderr | 2 +- .../mgca/adt_expr_arg_simple.stderr | 2 + .../mgca/early-bound-param-lt-bad.stderr | 2 + .../mgca/explicit_anon_consts.stderr | 14 ++++ .../mgca/selftyalias-containing-param.stderr | 1 + .../ui/const-generics/mgca/selftyparam.stderr | 2 + .../size-of-generic-ptr-in-array-len.stderr | 2 + .../mgca/tuple_ctor_complex_args.stderr | 2 + .../mgca/tuple_expr_arg_complex.stderr | 2 + .../mgca/type_const-on-generic-expr.stderr | 4 ++ .../mgca/type_const-on-generic_expr-2.stderr | 6 ++ .../unbraced_const_block_const_arg_gated.rs | 1 - ...nbraced_const_block_const_arg_gated.stderr | 12 +--- tests/ui/const-generics/ogca/basic-fail.rs | 22 +++++++ .../ui/const-generics/ogca/basic-fail.stderr | 9 +++ tests/ui/const-generics/ogca/basic.rs | 22 +++++++ .../ogca/coherence-ambiguous.rs | 21 ++++++ .../const-generics/ogca/rhs-but-not-root.rs | 14 ++++ .../ogca/rhs-but-not-root.stderr | 8 +++ .../feature-gate-opaque-generic-const-args.rs | 9 +++ ...ture-gate-opaque-generic-const-args.stderr | 10 +++ .../assoc-const-no-infer-ice-115806.rs | 2 +- 48 files changed, 347 insertions(+), 53 deletions(-) create mode 100644 tests/ui/const-generics/ogca/basic-fail.rs create mode 100644 tests/ui/const-generics/ogca/basic-fail.stderr create mode 100644 tests/ui/const-generics/ogca/basic.rs create mode 100644 tests/ui/const-generics/ogca/coherence-ambiguous.rs create mode 100644 tests/ui/const-generics/ogca/rhs-but-not-root.rs create mode 100644 tests/ui/const-generics/ogca/rhs-but-not-root.stderr create mode 100644 tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs create mode 100644 tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index baf6f6beaeed..7282a5168213 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -950,6 +950,16 @@ pub(crate) struct IncompatibleFeatures { pub f2: Symbol, } +#[derive(Diagnostic)] +#[diag("`{$parent}` requires {$missing} to be enabled")] +#[help("enable all of these features")] +pub(crate) struct MissingDependentFeatures { + #[primary_span] + pub parent_span: Span, + pub parent: Symbol, + pub missing: String, +} + #[derive(Diagnostic)] #[diag("negative bounds are not supported")] pub(crate) struct NegativeBoundUnsupported { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 1b1bbb1564c4..ce9001d65931 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -441,6 +441,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { maybe_stage_features(sess, features, krate); check_incompatible_features(sess, features); + check_dependent_features(sess, features); check_new_solver_banned_features(sess, features); let mut visitor = PostExpansionVisitor { sess, features }; @@ -649,6 +650,27 @@ fn check_incompatible_features(sess: &Session, features: &Features) { } } +fn check_dependent_features(sess: &Session, features: &Features) { + for &(parent, children) in + rustc_feature::DEPENDENT_FEATURES.iter().filter(|(parent, _)| features.enabled(*parent)) + { + if children.iter().any(|f| !features.enabled(*f)) { + let parent_span = features + .enabled_features_iter_stable_order() + .find_map(|(name, span)| (name == parent).then_some(span)) + .unwrap(); + // FIXME: should probably format this in fluent instead of here + let missing = children + .iter() + .filter(|f| !features.enabled(**f)) + .map(|s| format!("`{}`", s.as_str())) + .intersperse(String::from(", ")) + .collect(); + sess.dcx().emit_err(errors::MissingDependentFeatures { parent_span, parent, missing }); + } + } +} + fn check_new_solver_banned_features(sess: &Session, features: &Features) { if !sess.opts.unstable_opts.next_solver.globally { return; diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 2630348c49c1..7793f786cefe 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -5,6 +5,7 @@ // tidy-alphabetical-start #![feature(box_patterns)] #![feature(if_let_guard)] +#![feature(iter_intersperse)] #![feature(iter_is_partitioned)] // tidy-alphabetical-end diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 4ba50d03d707..619726f0d5d8 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -136,5 +136,6 @@ pub use builtin_attrs::{ }; pub use removed::REMOVED_LANG_FEATURES; pub use unstable::{ - EnabledLangFeature, EnabledLibFeature, Features, INCOMPATIBLE_FEATURES, UNSTABLE_LANG_FEATURES, + DEPENDENT_FEATURES, EnabledLangFeature, EnabledLibFeature, Features, INCOMPATIBLE_FEATURES, + UNSTABLE_LANG_FEATURES, }; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 2ab7714f22ca..a941eb1f459e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -605,6 +605,8 @@ declare_features! ( (unstable, offset_of_enum, "1.75.0", Some(120141)), /// Allows using fields with slice type in offset_of! (unstable, offset_of_slice, "1.81.0", Some(126151)), + /// Allows using generics in more complex const expressions, based on definitional equality. + (unstable, opaque_generic_const_args, "CURRENT_RUSTC_VERSION", Some(151972)), /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows specifying nop padding on functions for dynamic patching. @@ -782,3 +784,9 @@ pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = &[ // boolean logic required to tell which typing rules to use. (sym::ref_pat_eat_one_layer_2024, sym::ref_pat_eat_one_layer_2024_structural), ]; + +/// Some features require one or more other features to be enabled. +pub const DEPENDENT_FEATURES: &[(Symbol, &[Symbol])] = &[ + (sym::opaque_generic_const_args, &[sym::min_generic_const_args]), + (sym::unsized_const_params, &[sym::adt_const_params]), +]; diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f50aff187f25..f3086266eec0 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -16,7 +16,7 @@ use std::cell::Cell; use std::iter; -use std::ops::Bound; +use std::ops::{Bound, ControlFlow}; use rustc_abi::{ExternAbi, Size}; use rustc_ast::Recovered; @@ -26,12 +26,13 @@ use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey, struct_span_code_err, }; use rustc_hir::attrs::AttributeKind; -use rustc_hir::def::DefKind; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt}; +use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt}; use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind, find_attr}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause}; +use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{ @@ -1511,6 +1512,20 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin let parent_hir_node = tcx.hir_node(tcx.parent_hir_id(const_arg_id)); if tcx.features().generic_const_exprs() { ty::AnonConstKind::GCE + } else if tcx.features().opaque_generic_const_args() { + // Only anon consts that are the RHS of a const item can be OGCA. + // Note: We can't just check tcx.parent because it needs to be EXACTLY + // the RHS, not just part of the RHS. + if !is_anon_const_rhs_of_const_item(tcx, def) { + return ty::AnonConstKind::MCG; + } + + let body = tcx.hir_body_owned_by(def); + let mut visitor = OGCAParamVisitor(tcx); + match visitor.visit_body(body) { + ControlFlow::Break(UsesParam) => ty::AnonConstKind::OGCA, + ControlFlow::Continue(()) => ty::AnonConstKind::MCG, + } } else if tcx.features().min_generic_const_args() { ty::AnonConstKind::MCG } else if let hir::Node::Expr(hir::Expr { @@ -1528,6 +1543,49 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin } } +fn is_anon_const_rhs_of_const_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { + let hir_id = tcx.local_def_id_to_hir_id(def_id); + let Some((_, grandparent_node)) = tcx.hir_parent_iter(hir_id).nth(1) else { return false }; + let (Node::Item(hir::Item { kind: hir::ItemKind::Const(_, _, _, ct_rhs), .. }) + | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(_, ct_rhs), .. }) + | Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Const(_, Some(ct_rhs)), .. + })) = grandparent_node + else { + return false; + }; + let hir::ConstItemRhs::TypeConst(hir::ConstArg { + kind: hir::ConstArgKind::Anon(rhs_anon), .. + }) = ct_rhs + else { + return false; + }; + def_id == rhs_anon.def_id +} + +struct OGCAParamVisitor<'tcx>(TyCtxt<'tcx>); + +struct UsesParam; + +impl<'tcx> Visitor<'tcx> for OGCAParamVisitor<'tcx> { + type NestedFilter = nested_filter::OnlyBodies; + type Result = ControlFlow; + + fn maybe_tcx(&mut self) -> TyCtxt<'tcx> { + self.0 + } + + fn visit_path(&mut self, path: &hir::Path<'tcx>, _id: HirId) -> ControlFlow { + if let Res::Def(DefKind::TyParam | DefKind::ConstParam | DefKind::LifetimeParam, _) = + path.res + { + return ControlFlow::Break(UsesParam); + } + + intravisit::walk_path(self, path) + } +} + #[instrument(level = "debug", skip(tcx), ret)] fn const_of_item<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 511d513216eb..0723418d8ddf 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -92,6 +92,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { match tcx.anon_const_kind(def_id) { // Stable: anon consts are not able to use any generic parameters... ty::AnonConstKind::MCG => None, + // OGCA anon consts inherit their parent's generics. + ty::AnonConstKind::OGCA => Some(parent_did), // we provide generics to repeat expr counts as a backwards compatibility hack. #76200 ty::AnonConstKind::RepeatExprCount => Some(parent_did), 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 a79170452fae..7a03d8b220c5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -404,6 +404,11 @@ impl<'tcx> ForbidMCGParamUsesFolder<'tcx> { diag.span_note(impl_.self_ty.span, "not a concrete type"); } } + if self.tcx.features().min_generic_const_args() + && !self.tcx.features().opaque_generic_const_args() + { + diag.help("add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items"); + } diag.emit() } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 5581ad5669aa..3e17943a8857 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use rustc_data_structures::intern::Interned; use rustc_error_messages::MultiSpan; -use rustc_macros::{HashStable, TyDecodable, TyEncodable}; +use rustc_macros::HashStable; use rustc_type_ir::walk::TypeWalker; use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo}; @@ -335,16 +335,3 @@ impl<'tcx> Const<'tcx> { TypeWalker::new(self.into()) } } - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable, HashStable)] -pub enum AnonConstKind { - /// `feature(generic_const_exprs)` anon consts are allowed to use arbitrary generic parameters in scope - GCE, - /// stable `min_const_generics` anon consts are not allowed to use any generic parameters - MCG, - /// anon consts used as the length of a repeat expr are syntactically allowed to use generic parameters - /// but must not depend on the actual instantiation. See #76200 for more information - RepeatExprCount, - /// anon consts outside of the type system, e.g. enum discriminants - NonTypeSystem, -} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e43a30091f50..1bb83530487d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -238,6 +238,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn const_of_item(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Const<'tcx>> { self.const_of_item(def_id) } + fn anon_const_kind(self, def_id: DefId) -> ty::AnonConstKind { + self.anon_const_kind(def_id) + } type AdtDef = ty::AdtDef<'tcx>; fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0220531b09fa..37871aad4a77 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -76,8 +76,8 @@ pub use self::closure::{ place_to_string_for_capture, }; pub use self::consts::{ - AnonConstKind, AtomicOrdering, Const, ConstInt, ConstKind, ConstToValTreeResult, Expr, - ExprKind, ScalarInt, SimdAlign, UnevaluatedConst, ValTree, ValTreeKindExt, Value, + AtomicOrdering, Const, ConstInt, ConstKind, ConstToValTreeResult, Expr, ExprKind, ScalarInt, + SimdAlign, UnevaluatedConst, ValTree, ValTreeKindExt, Value, }; pub use self::context::{ CtxtInterners, CurrentGcx, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls, diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs index 46312be5ea9a..eb6a1b51421c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs @@ -1,4 +1,4 @@ -use rustc_type_ir::{self as ty, Interner}; +use rustc_type_ir::{self as ty, Interner, TypingMode}; use tracing::instrument; use crate::delegate::SolverDelegate; @@ -14,7 +14,18 @@ where &mut self, goal: Goal>, ) -> QueryResult { - if let Some(normalized_const) = self.evaluate_const( + if self.typing_mode() == TypingMode::Coherence + && self.cx().anon_const_kind(goal.predicate.alias.def_id) == ty::AnonConstKind::OGCA + { + // During coherence, OGCA consts should be normalized ambiguously + // because they are opaque but eventually resolved to a real value. + // We don't want two OGCAs that have the same value to be treated + // as distinct for coherence purposes. (Just like opaque types.) + // + // We can't rely on evaluate_const below because that particular wrapper + // treats too-generic consts as a successful evaluation. + self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } else if let Some(normalized_const) = self.evaluate_const( goal.param_env, ty::UnevaluatedConst::new( goal.predicate.alias.def_id.try_into().unwrap(), diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index c35ddc4dc943..9ac9bd5c0e46 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1551,7 +1551,9 @@ impl<'a> Parser<'a> { let rhs = if self.eat(exp!(Eq)) { if attr::contains_name(attrs, sym::type_const) { - Some(ConstItemRhs::TypeConst(self.parse_const_arg()?)) + let ct = + self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?; + Some(ConstItemRhs::TypeConst(ct)) } else { Some(ConstItemRhs::Body(self.parse_expr()?)) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1915ff0380fd..6aa2eae556e2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1628,6 +1628,7 @@ symbols! { on_const, on_unimplemented, opaque, + opaque_generic_const_args, opaque_module_name_placeholder: "", open_options_new, ops, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 4e027a301cc8..08f1d947dfb5 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -681,6 +681,20 @@ pub fn try_evaluate_const<'tcx>( (args, typing_env) } + Some(ty::AnonConstKind::OGCA) => { + if infcx.typing_mode() != TypingMode::PostAnalysis { + // OGCA anon consts should be treated as always having generics + // during anything before codegen (or maybe MIR opts too). + return Err(EvaluateConstErr::HasGenericsOrInfers); + } + + if uv.args.has_non_region_param() || uv.args.has_non_region_infer() { + return Err(EvaluateConstErr::HasGenericsOrInfers); + } + + let typing_env = ty::TypingEnv::fully_monomorphized(); + (uv.args, typing_env) + } Some(ty::AnonConstKind::MCG) | Some(ty::AnonConstKind::NonTypeSystem) | None => { // We are only dealing with "truly" generic/uninferred constants here: // - GCEConsts have been handled separately diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index b215230ea443..1c39f31469b1 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -200,3 +200,23 @@ impl ValTreeKind { } } } + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[cfg_attr( + feature = "nightly", + derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) +)] +pub enum AnonConstKind { + /// `feature(generic_const_exprs)` anon consts are allowed to use arbitrary generic parameters in scope + GCE, + /// stable `min_const_generics` anon consts are not allowed to use any generic parameters + MCG, + /// `feature(opaque_generic_const_args)` anon consts are allowed to use arbitrary + /// generic parameters in scope, but only if they syntactically reference them. + OGCA, + /// anon consts used as the length of a repeat expr are syntactically allowed to use generic parameters + /// but must not depend on the actual instantiation. See #76200 for more information + RepeatExprCount, + /// anon consts outside of the type system, e.g. enum discriminants + NonTypeSystem, +} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 59ae6733fb84..8f446cdfba6d 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -205,6 +205,7 @@ pub trait Interner: fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId) -> ty::EarlyBinder; fn const_of_item(self, def_id: Self::DefId) -> ty::EarlyBinder; + fn anon_const_kind(self, def_id: Self::DefId) -> ty::AnonConstKind; type AdtDef: AdtDef; fn adt_def(self, adt_def_id: Self::AdtId) -> Self::AdtDef; diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs index 6b87ad86d4bc..e364368b8a4c 100644 --- a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs +++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs @@ -1,4 +1,4 @@ -#![feature(generic_const_exprs, unsized_const_params)] +#![feature(adt_const_params, generic_const_exprs, unsized_const_params)] #![allow(incomplete_features)] // Regression test for 128232 diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr index 72dfda50ea5c..b13f76eabadb 100644 --- a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr +++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr @@ -9,13 +9,11 @@ help: you might be missing a const parameter LL | impl Wrapper<{ bar() }> { | +++++++++++++++++++++++ -error: using function pointers as const generic parameters is forbidden +error[E0741]: using function pointers as const generic parameters is forbidden --> $DIR/non_valtreeable_const_arg-2.rs:8:25 | LL | struct Wrapper; | ^^^^ - | - = note: the only supported types are integers, `bool`, and `char` error[E0599]: the function or associated item `call` exists for struct `Wrapper`, but its trait bounds were not satisfied --> $DIR/non_valtreeable_const_arg-2.rs:17:26 @@ -37,5 +35,5 @@ note: the trait `Fn` must be implemented error: aborting due to 3 previous errors -Some errors have detailed explanations: E0425, E0599. +Some errors have detailed explanations: E0425, E0599, E0741. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/const-generics/associated-const-bindings/ambiguity.rs b/tests/ui/const-generics/associated-const-bindings/ambiguity.rs index 6bc2a6d5d153..785d43e51b3d 100644 --- a/tests/ui/const-generics/associated-const-bindings/ambiguity.rs +++ b/tests/ui/const-generics/associated-const-bindings/ambiguity.rs @@ -1,7 +1,7 @@ // We used to say "ambiguous associated type" on ambiguous associated consts. // Ensure that we now use the correct label. -#![feature(min_generic_const_args, unsized_const_params)] +#![feature(adt_const_params, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait0: Parent0 + Parent0 {} diff --git a/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs b/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs index 004215986711..0af91bfe7da8 100644 --- a/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs +++ b/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs @@ -5,7 +5,7 @@ //@ check-pass -#![feature(min_generic_const_args, unsized_const_params)] +#![feature(adt_const_params, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait: SuperTrait { diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs index d19e7acbaff0..bd26acce681f 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs @@ -3,6 +3,7 @@ //@ dont-require-annotations: NOTE +#![feature(adt_const_params)] #![feature(generic_const_items)] #![feature(generic_const_parameter_types)] #![feature(min_generic_const_args)] diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr index dba1643d2c5c..dedbdd7f82bb 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr @@ -1,12 +1,12 @@ error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:37:16 + --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:38:16 | LL | let _: dyn Trait; | ^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:17:11 + --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:18:11 | LL | trait Trait { | ----- this trait is not dyn compatible... diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs index 936556e957ca..fc3bd1d2e753 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs @@ -4,17 +4,24 @@ // to the rest of the compiler and by extension the user via diagnostics. //@ known-bug: unknown -#![feature(min_generic_const_args, unsized_const_params, generic_const_parameter_types)] +#![feature( + adt_const_params, + min_generic_const_args, + unsized_const_params, + generic_const_parameter_types +)] #![expect(incomplete_features)] trait A { type Ty: std::marker::ConstParamTy_; - #[type_const] const CT: Self::Ty; + #[type_const] + const CT: Self::Ty; } impl A for () { type Ty = i32; - #[type_const] const CT: i32 = 0; + #[type_const] + const CT: i32 = 0; } fn main() { diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr index 8ee231ec070f..0b8dae1aac43 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr @@ -1,23 +1,23 @@ error[E0277]: the trait bound `FreshTy(0): A` is not satisfied - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:27:33 + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:34:33 | LL | let _: dyn A; | ^ the trait `A` is not implemented for `FreshTy(0)` | help: the trait `A` is implemented for `()` - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:15:1 + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:21:1 | LL | impl A for () { | ^^^^^^^^^^^^^ error[E0277]: the trait bound `FreshTy(0): A` is not satisfied - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:29:34 + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:36:34 | LL | let _: &dyn A = &(); | ^ the trait `A` is not implemented for `FreshTy(0)` | help: the trait `A` is implemented for `()` - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:15:1 + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:21:1 | LL | impl A for () { | ^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs index d32737fcb62f..4d06cdc7620f 100644 --- a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs +++ b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs @@ -1,6 +1,7 @@ // Detect and reject escaping late-bound generic params in // the type of assoc consts used in an equality bound. #![feature( + adt_const_params, min_generic_const_args, unsized_const_params, generic_const_parameter_types, diff --git a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr index 122893662933..3966483aa600 100644 --- a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr +++ b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` cannot capture late-bound generic parameters - --> $DIR/esc-bound-var-in-ty.rs:15:35 + --> $DIR/esc-bound-var-in-ty.rs:16:35 | LL | fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} | -- ^ its type cannot capture the late-bound lifetime parameter `'r` diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr index 8b9c228c1ee5..f1d5e5c67475 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr @@ -9,6 +9,8 @@ error: generic parameters may not be used in const operations | LL | foo::<{ Some:: { 0: const { N + 1 } } }>(); | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr index 461a26e33a3c..e0804158952d 100644 --- a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr +++ b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr @@ -3,6 +3,8 @@ error: generic parameters may not be used in const operations | LL | T: Trait | ^^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index 551815c4c31a..1251f4415171 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -39,42 +39,56 @@ error: generic parameters may not be used in const operations | LL | const ITEM3: usize = const { N }; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:60:31 | LL | T3: Trait, | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:69:58 | LL | struct Default3; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:28:27 | LL | let _3 = [(); const { N }]; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:33:26 | LL | let _6: [(); const { N }] = todo!(); | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:11:41 | LL | type Adt3 = Foo; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:19:42 | LL | type Arr3 = [(); const { N }]; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 13 previous errors diff --git a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr index fdd3e6efdf65..1c841e39e673 100644 --- a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr +++ b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr @@ -9,6 +9,7 @@ note: not a concrete type | LL | impl S { | ^^^^ + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/selftyparam.stderr b/tests/ui/const-generics/mgca/selftyparam.stderr index 376e63da9a75..c3e0770fb978 100644 --- a/tests/ui/const-generics/mgca/selftyparam.stderr +++ b/tests/ui/const-generics/mgca/selftyparam.stderr @@ -3,6 +3,8 @@ error: generic parameters may not be used in const operations | LL | fn foo() -> [(); const { let _: Self; 1 }]; | ^^^^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr index 913d8195fe21..6d8d3b4054d3 100644 --- a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr @@ -9,6 +9,8 @@ error: generic parameters may not be used in const operations | LL | [0; const { size_of::<*mut T>() }]; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr index e0ea3fd5560c..2961c714d141 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr @@ -9,6 +9,8 @@ error: generic parameters may not be used in const operations | LL | with_point::<{ Point(const { N + 1 }, N) }>(); | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr index b294e1032ce8..b4853d3c2e38 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr @@ -21,6 +21,8 @@ error: generic parameters may not be used in const operations | LL | takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr index f339e82beeed..8d43f2177562 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -3,12 +3,16 @@ error: generic parameters may not be used in const operations | LL | const FREE1: usize = const { std::mem::size_of::() }; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic-expr.rs:8:46 | LL | const FREE2: usize = const { I + 1 }; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr index 9d4e99ca0aaf..1a6097752e33 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr @@ -3,18 +3,24 @@ error: generic parameters may not be used in const operations | LL | const N1: usize = const { std::mem::size_of::() }; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic_expr-2.rs:20:47 | LL | const N2: usize = const { I + 1 }; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic_expr-2.rs:23:35 | LL | const N3: usize = const { 2 & X }; | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs index 588fa2f913b6..c01fb47002b2 100644 --- a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs +++ b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs @@ -35,7 +35,6 @@ const NON_TYPE_CONST: usize = const { 1 }; #[type_const] //~^ ERROR: the `#[type_const]` attribute is an experimental feature const TYPE_CONST: usize = const { 1 }; -//~^ ERROR: unbraced const blocks as const args are experimental static STATIC: usize = const { 1 }; diff --git a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr index 00db630c27e9..bbcd9f9897a6 100644 --- a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr +++ b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr @@ -48,16 +48,6 @@ LL | generic::(); = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental - --> $DIR/unbraced_const_block_const_arg_gated.rs:37:27 - | -LL | const TYPE_CONST: usize = const { 1 }; - | ^^^^^^^^^^^ - | - = note: see issue #132980 for more information - = help: add `#![feature(min_generic_const_args)]` 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[E0658]: the `#[type_const]` attribute is an experimental feature --> $DIR/unbraced_const_block_const_arg_gated.rs:35:1 | @@ -68,6 +58,6 @@ LL | #[type_const] = help: add `#![feature(min_generic_const_args)]` 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 7 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/ogca/basic-fail.rs b/tests/ui/const-generics/ogca/basic-fail.rs new file mode 100644 index 000000000000..87176c7b067e --- /dev/null +++ b/tests/ui/const-generics/ogca/basic-fail.rs @@ -0,0 +1,22 @@ +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(opaque_generic_const_args)] +#![expect(incomplete_features)] + +#[type_const] +const ADD1: usize = const { N + 1 }; + +#[type_const] +const INC: usize = const { N + 1 }; + +#[type_const] +const ONE: usize = ADD1::<0>; + +#[type_const] +const OTHER_ONE: usize = INC::<0>; + +// Not definitionally equal. +const ARR: [(); ADD1::<0>] = [(); INC::<0>]; +//~^ ERROR mismatched types + +fn main() {} diff --git a/tests/ui/const-generics/ogca/basic-fail.stderr b/tests/ui/const-generics/ogca/basic-fail.stderr new file mode 100644 index 000000000000..05de01b132c6 --- /dev/null +++ b/tests/ui/const-generics/ogca/basic-fail.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/basic-fail.rs:19:30 + | +LL | const ARR: [(); ADD1::<0>] = [(); INC::<0>]; + | ^^^^^^^^^^^^^^ expected an array with a size of const { N + 1 }, found one with a size of const { N + 1 } + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/ogca/basic.rs b/tests/ui/const-generics/ogca/basic.rs new file mode 100644 index 000000000000..c8aec9ee24ce --- /dev/null +++ b/tests/ui/const-generics/ogca/basic.rs @@ -0,0 +1,22 @@ +//@ check-pass + +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(opaque_generic_const_args)] +#![expect(incomplete_features)] + +#[type_const] +const ADD1: usize = const { N + 1 }; + +#[type_const] +const INC: usize = ADD1::; + +#[type_const] +const ONE: usize = ADD1::<0>; + +#[type_const] +const OTHER_ONE: usize = INC::<0>; + +const ARR: [(); ADD1::<0>] = [(); INC::<0>]; + +fn main() {} diff --git a/tests/ui/const-generics/ogca/coherence-ambiguous.rs b/tests/ui/const-generics/ogca/coherence-ambiguous.rs new file mode 100644 index 000000000000..c8c088b1e8fc --- /dev/null +++ b/tests/ui/const-generics/ogca/coherence-ambiguous.rs @@ -0,0 +1,21 @@ +// FIXME(ogca): this should ERROR not pass!! +//@ check-pass + +#![feature(generic_const_items, min_generic_const_args, opaque_generic_const_args)] +#![expect(incomplete_features)] + +#[type_const] +const FOO: usize = const { N + 1 }; + +#[type_const] +const BAR: usize = const { N + 1 }; + +trait Trait {} + +impl Trait for [(); FOO::<1>] {} +impl Trait for [(); BAR::<1>] {} +// FIXME(ogca): this should ERROR! +impl Trait for [(); BAR::<2>] {} +// FIXME(ogca): this should ERROR! + +fn main() {} diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.rs b/tests/ui/const-generics/ogca/rhs-but-not-root.rs new file mode 100644 index 000000000000..4ed136f04ced --- /dev/null +++ b/tests/ui/const-generics/ogca/rhs-but-not-root.rs @@ -0,0 +1,14 @@ +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(opaque_generic_const_args)] +#![expect(incomplete_features)] + +// Anon consts must be the root of the RHS to be OGCA. +#[type_const] +const FOO: usize = ID::; +//~^ ERROR generic parameters may not be used in const operations + +#[type_const] +const ID: usize = N; + +fn main() {} diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.stderr b/tests/ui/const-generics/ogca/rhs-but-not-root.stderr new file mode 100644 index 000000000000..f4fdf5fb981b --- /dev/null +++ b/tests/ui/const-generics/ogca/rhs-but-not-root.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/rhs-but-not-root.rs:8:49 + | +LL | const FOO: usize = ID::; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs b/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs new file mode 100644 index 000000000000..0b78911158ba --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs @@ -0,0 +1,9 @@ +#![feature(generic_const_items, min_generic_const_args)] +#![expect(incomplete_features)] + +#[type_const] +const INC: usize = const { N + 1 }; +//~^ ERROR generic parameters may not be used in const operations +//~| HELP add `#![feature(opaque_generic_const_args)]` + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr new file mode 100644 index 000000000000..1b87443aa3cb --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr @@ -0,0 +1,10 @@ +error: generic parameters may not be used in const operations + --> $DIR/feature-gate-opaque-generic-const-args.rs:5:44 + | +LL | const INC: usize = const { N + 1 }; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 1 previous error + diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index fb2506daf078..518ed6452369 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -1,6 +1,6 @@ // ICE: assertion failed: !value.has_infer() // issue: rust-lang/rust#115806 -#![feature(min_generic_const_args, unsized_const_params)] +#![feature(adt_const_params, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] pub struct NoPin; From 875c5908c747f5e97227aab367d4bcc7c161c892 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 8 Feb 2026 20:39:02 +0100 Subject: [PATCH 3416/3801] Update examples for diagnostics changes Co-authored-by: bjorn3 --- .../examples/rustc-interface-example.rs | 15 +++++---------- .../rustc-interface-getting-diagnostics.rs | 8 +++----- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/doc/rustc-dev-guide/examples/rustc-interface-example.rs b/src/doc/rustc-dev-guide/examples/rustc-interface-example.rs index 360f70c8e865..b4439504650a 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-interface-example.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-interface-example.rs @@ -4,14 +4,12 @@ extern crate rustc_driver; extern crate rustc_error_codes; -extern crate rustc_errors; extern crate rustc_hash; extern crate rustc_hir; extern crate rustc_interface; extern crate rustc_session; extern crate rustc_span; -use rustc_errors::registry; use rustc_hash::FxHashMap; use rustc_session::config; @@ -30,12 +28,11 @@ fn main() { println!("{HELLO}"); } "# - .into(), + .into(), }, - output_dir: None, // Option - output_file: None, // Option - file_loader: None, // Option> - locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES.to_owned(), + output_dir: None, // Option + output_file: None, // Option + file_loader: None, // Option> lint_caps: FxHashMap::default(), // FxHashMap // This is a callback from the driver that is called when [`ParseSess`] is created. psess_created: None, //Option> @@ -50,8 +47,6 @@ fn main() { // // The second parameter is local providers and the third parameter is external providers. override_queries: None, // Option, &mut ty::query::Providers<'_>)> - // Registry of diagnostics codes. - registry: registry::Registry::new(rustc_errors::codes::DIAGNOSTICS), make_codegen_backend: None, expanded_args: Vec::new(), ice_file: None, @@ -77,4 +72,4 @@ fn main() { } }); }); -} +} \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs b/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs index 2512ba3c3f92..342316ba670a 100644 --- a/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs +++ b/src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs @@ -15,7 +15,7 @@ extern crate rustc_span; use std::sync::{Arc, Mutex}; use rustc_errors::emitter::Emitter; -use rustc_errors::registry::{self, Registry}; +use rustc_errors::registry::Registry; use rustc_errors::translation::Translate; use rustc_errors::{DiagInner, FluentBundle}; use rustc_session::config; @@ -59,14 +59,13 @@ fn main() { let x: &str = 1; } " - .into(), + .into(), }, crate_cfg: Vec::new(), crate_check_cfg: Vec::new(), output_dir: None, output_file: None, file_loader: None, - locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES.to_owned(), lint_caps: rustc_hash::FxHashMap::default(), psess_created: Some(Box::new(|parse_sess| { parse_sess.dcx().set_emitter(Box::new(DebugEmitter { @@ -76,7 +75,6 @@ fn main() { })), register_lints: None, override_queries: None, - registry: registry::Registry::new(rustc_errors::codes::DIAGNOSTICS), make_codegen_backend: None, expanded_args: Vec::new(), ice_file: None, @@ -99,4 +97,4 @@ fn main() { buffer.lock().unwrap().iter().for_each(|diagnostic| { println!("{diagnostic:#?}"); }); -} +} \ No newline at end of file From 4a979d546bc779f97e6224e8ab3d26f8bd69a6e9 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 8 Feb 2026 19:54:03 +0000 Subject: [PATCH 3417/3801] Stop having two different alignment constants * Stop having two different alignment constants * Update library/core/src/alloc/global.rs --- library/core/src/alloc/global.rs | 7 ++++--- library/core/src/mem/mod.rs | 5 ++++- library/core/src/ptr/alignment.rs | 3 +-- .../default_boxed_slice.main.GVN.32bit.panic-abort.diff | 2 +- .../default_boxed_slice.main.GVN.32bit.panic-unwind.diff | 2 +- .../default_boxed_slice.main.GVN.64bit.panic-abort.diff | 2 +- .../default_boxed_slice.main.GVN.64bit.panic-unwind.diff | 2 +- tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff | 2 +- 8 files changed, 14 insertions(+), 11 deletions(-) diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs index d18e1f525d10..bf3d3e0a5aca 100644 --- a/library/core/src/alloc/global.rs +++ b/library/core/src/alloc/global.rs @@ -284,9 +284,10 @@ pub unsafe trait GlobalAlloc { /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html #[stable(feature = "global_alloc", since = "1.28.0")] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - // SAFETY: the caller must ensure that the `new_size` does not overflow. - // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid. - let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; + let alignment = layout.alignment(); + // SAFETY: the caller must ensure that the `new_size` does not overflow + // when rounded up to the next multiple of `alignment`. + let new_layout = unsafe { Layout::from_size_alignment_unchecked(new_size, alignment) }; // SAFETY: the caller must ensure that `new_layout` is greater than zero. let new_ptr = unsafe { self.alloc(new_layout) }; if !new_ptr.is_null() { diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 7c486875a826..eb6f8f975721 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1260,7 +1260,10 @@ pub trait SizedTypeProperties: Sized { #[doc(hidden)] #[unstable(feature = "ptr_alignment_type", issue = "102070")] - const ALIGNMENT: Alignment = Alignment::of::(); + const ALIGNMENT: Alignment = { + // This can't panic since type alignment is always a power of two. + Alignment::new(Self::ALIGN).unwrap() + }; /// `true` if this type requires no storage. /// `false` if its [size](size_of) is greater than zero. diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 7c34b026e14b..b27930de4e66 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -52,8 +52,7 @@ impl Alignment { #[inline] #[must_use] pub const fn of() -> Self { - // This can't actually panic since type alignment is always a power of two. - const { Alignment::new(align_of::()).unwrap() } + ::ALIGNMENT } /// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to. diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff index 7d66d3129115..308f19ea759d 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff @@ -44,7 +44,7 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute); +- _6 = const <[bool; 0] as std::mem::SizedTypeProperties>::ALIGNMENT as *const [bool; 0] (Transmute); - _5 = NonNull::<[bool; 0]> { pointer: copy _6 }; + _6 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff index cc00bd300a3c..819ad6054df8 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff @@ -44,7 +44,7 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute); +- _6 = const <[bool; 0] as std::mem::SizedTypeProperties>::ALIGNMENT as *const [bool; 0] (Transmute); - _5 = NonNull::<[bool; 0]> { pointer: copy _6 }; + _6 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff index 9380cdd6ccb4..7029e02a857a 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff @@ -44,7 +44,7 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute); +- _6 = const <[bool; 0] as std::mem::SizedTypeProperties>::ALIGNMENT as *const [bool; 0] (Transmute); - _5 = NonNull::<[bool; 0]> { pointer: copy _6 }; + _6 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff index bea564376274..23a134f3666b 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff @@ -44,7 +44,7 @@ StorageLive(_4); StorageLive(_5); StorageLive(_6); -- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute); +- _6 = const <[bool; 0] as std::mem::SizedTypeProperties>::ALIGNMENT as *const [bool; 0] (Transmute); - _5 = NonNull::<[bool; 0]> { pointer: copy _6 }; + _6 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff index 9e543699da70..23889b266e4a 100644 --- a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff +++ b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff @@ -40,7 +40,7 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); -- _3 = const std::ptr::Alignment::of::::{constant#0}; +- _3 = const ::ALIGNMENT; - _2 = copy _3 as *mut u8 (Transmute); + _3 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }}; + _2 = const {0x1 as *mut u8}; From 59111f7a73fda12e0401cb35ccab7fbcd80ad272 Mon Sep 17 00:00:00 2001 From: Vincent Esche Date: Wed, 4 Feb 2026 09:01:24 +0100 Subject: [PATCH 3418/3801] Add `expression_types()`, `pattern_types()`, `binding_types()` to `DefWithBody` --- src/tools/rust-analyzer/crates/hir/src/lib.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 4b615665167c..0167ccaa1002 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -2244,6 +2244,39 @@ impl DefWithBody { acc.push(diag.into()) } } + + /// Returns an iterator over the inferred types of all expressions in this body. + pub fn expression_types<'db>( + self, + db: &'db dyn HirDatabase, + ) -> impl Iterator> { + self.id().into_iter().flat_map(move |def_id| { + let infer = InferenceResult::for_body(db, def_id); + let resolver = def_id.resolver(db); + + infer.expression_types().map(move |(_, ty)| Type::new_with_resolver(db, &resolver, ty)) + }) + } + + /// Returns an iterator over the inferred types of all patterns in this body. + pub fn pattern_types<'db>(self, db: &'db dyn HirDatabase) -> impl Iterator> { + self.id().into_iter().flat_map(move |def_id| { + let infer = InferenceResult::for_body(db, def_id); + let resolver = def_id.resolver(db); + + infer.pattern_types().map(move |(_, ty)| Type::new_with_resolver(db, &resolver, ty)) + }) + } + + /// Returns an iterator over the inferred types of all bindings in this body. + pub fn binding_types<'db>(self, db: &'db dyn HirDatabase) -> impl Iterator> { + self.id().into_iter().flat_map(move |def_id| { + let infer = InferenceResult::for_body(db, def_id); + let resolver = def_id.resolver(db); + + infer.binding_types().map(move |(_, ty)| Type::new_with_resolver(db, &resolver, ty)) + }) + } } fn expr_store_diagnostics<'db>( From f1b4c2a0e64ccb5c1b4b2b2391ac91f40d143302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 14:42:17 +0100 Subject: [PATCH 3419/3801] Port rustc_insignificant_dtor to the new attribute parser --- .../src/attributes/rustc_internal.rs | 13 +++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_ty_utils/src/needs_drop.rs | 6 +++--- 6 files changed, 22 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index a8a0ee3e5e22..4740cc107353 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -739,6 +739,19 @@ impl CombineAttributeParser for RustcThenThisWouldNeedParser { } } +pub(crate) struct RustcInsignificantDtorParser; + +impl NoArgsAttributeParser for RustcInsignificantDtorParser { + const PATH: &[Symbol] = &[sym::rustc_insignificant_dtor]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Enum), + Allow(Target::Struct), + Allow(Target::ForeignTy), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcInsignificantDtor; +} + pub(crate) struct RustcEffectiveVisibilityParser; impl NoArgsAttributeParser for RustcEffectiveVisibilityParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index ad39b0ec26d9..7921928ce7c5 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -270,6 +270,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 79452913c259..aaeebcc5c66d 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1120,6 +1120,9 @@ pub enum AttributeKind { /// Represents `#[rustc_if_this_changed]` RustcIfThisChanged(Span, Option), + /// Represents `#[rustc_insignificant_dtor]` + RustcInsignificantDtor, + /// Represents `#[rustc_intrinsic]` RustcIntrinsic, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index ba351d80544c..4fb20599a026 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -118,6 +118,7 @@ impl AttributeKind { RustcHasIncoherentInherentImpls => Yes, RustcHiddenTypeOfOpaques => No, RustcIfThisChanged(..) => No, + RustcInsignificantDtor => Yes, RustcIntrinsic => Yes, RustcIntrinsicConstStableIndirect => No, RustcLayout(..) => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 6c4b76a08ad2..2f1695f0712a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -313,6 +313,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcHasIncoherentInherentImpls | AttributeKind::RustcHiddenTypeOfOpaques | AttributeKind::RustcIfThisChanged(..) + | AttributeKind::RustcInsignificantDtor | AttributeKind::RustcIntrinsic | AttributeKind::RustcIntrinsicConstStableIndirect | AttributeKind::RustcLayout(..) @@ -386,7 +387,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::default_lib_allocator | sym::rustc_diagnostic_item | sym::rustc_no_mir_inline - | sym::rustc_insignificant_dtor | sym::rustc_nonnull_optimization_guaranteed | sym::rustc_inherit_overflow_checks | sym::rustc_trivial_field_reads diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 0ef435b1a0e2..06eef7e95145 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -1,13 +1,14 @@ //! Check whether a type has (potentially) non-trivial drop glue. use rustc_data_structures::fx::FxHashSet; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::DefId; +use rustc_hir::find_attr; use rustc_hir::limit::Limit; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::util::{AlwaysRequiresDrop, needs_drop_components}; use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt}; -use rustc_span::sym; use tracing::{debug, instrument}; use crate::errors::NeedsDropOverflow; @@ -396,8 +397,7 @@ fn adt_consider_insignificant_dtor<'tcx>( tcx: TyCtxt<'tcx>, ) -> impl Fn(ty::AdtDef<'tcx>) -> Option { move |adt_def: ty::AdtDef<'tcx>| { - let is_marked_insig = tcx.has_attr(adt_def.did(), sym::rustc_insignificant_dtor); - if is_marked_insig { + if find_attr!(tcx.get_all_attrs(adt_def.did()), AttributeKind::RustcInsignificantDtor) { // In some cases like `std::collections::HashMap` where the struct is a wrapper around // a type that is a Drop type, and the wrapped type (eg: `hashbrown::HashMap`) lies // outside stdlib, we might choose to still annotate the wrapper (std HashMap) with From 9d6e120939cad8e87c3ccd4e2f33d3591b82edf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 15:06:32 +0100 Subject: [PATCH 3420/3801] remove from impl block in std --- library/alloc/src/ffi/c_str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index d6dcba7107a9..fba967c04895 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -103,6 +103,7 @@ use crate::vec::Vec; /// and other memory errors. #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] #[rustc_diagnostic_item = "cstring_type"] +#[rustc_insignificant_dtor] #[stable(feature = "alloc_c_string", since = "1.64.0")] pub struct CString { // Invariant 1: the slice ends with a zero byte and has a length of at least one. @@ -694,7 +695,6 @@ impl CString { // memory-unsafe code from working by accident. Inline // to prevent LLVM from optimizing it away in debug builds. #[stable(feature = "cstring_drop", since = "1.13.0")] -#[rustc_insignificant_dtor] impl Drop for CString { #[inline] fn drop(&mut self) { From 2dda303229b936641c29db1f277a9940473ebc70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 5 Feb 2026 15:12:05 +0100 Subject: [PATCH 3421/3801] Port rustc_strict_coherence to the new attribute parser --- .../src/attributes/rustc_internal.rs | 15 +++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + .../rustc_hir/src/attrs/data_structures.rs | 4 ++++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_middle/src/error.rs | 2 +- .../src/traits/specialization_graph.rs | 19 ++++++------------- compiler/rustc_passes/src/check_attr.rs | 2 +- 7 files changed, 29 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index a8a0ee3e5e22..c4c0a04c44e4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -845,3 +845,18 @@ impl NoArgsAttributeParser for RustcIntrinsicConstStableIndirectPar const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsicConstStableIndirect; } + +pub(crate) struct RustcStrictCoherenceParser; + +impl NoArgsAttributeParser for RustcStrictCoherenceParser { + const PATH: &[Symbol] = &[sym::rustc_strict_coherence]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Trait), + Allow(Target::Struct), + Allow(Target::Enum), + Allow(Target::Union), + Allow(Target::ForeignTy), + ]); + const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcStrictCoherence; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index ad39b0ec26d9..16a3403b5243 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -286,6 +286,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 79452913c259..de7b2bd06546 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1230,6 +1230,9 @@ pub enum AttributeKind { /// Represents `#[rustc_std_internal_symbol]`. RustcStdInternalSymbol(Span), + /// Represents `#[rustc_strict_coherence]`. + RustcStrictCoherence(Span), + /// Represents `#[rustc_symbol_name]` RustcSymbolName(Span), @@ -1266,6 +1269,7 @@ pub enum AttributeKind { /// Span of the attribute. span: Span, }, + /// Represents `#[target_feature(enable = "...")]` and /// `#[unsafe(force_target_feature(enable = "...")]`. TargetFeature { features: ThinVec<(Symbol, Span)>, attr_span: Span, was_forced: bool }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index ba351d80544c..954c72ca86fe 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -153,6 +153,7 @@ impl AttributeKind { RustcSkipDuringMethodDispatch { .. } => No, RustcSpecializationTrait(..) => No, RustcStdInternalSymbol(..) => No, + RustcStrictCoherence(..) => Yes, RustcSymbolName(..) => Yes, RustcThenThisWouldNeed(..) => No, RustcUnsafeSpecializationMarker(..) => No, diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index a5d5978916eb..d487caf4d3ac 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -93,7 +93,7 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence { #[primary_span] pub span: Span, #[label("due to this attribute")] - pub attr_span: Option, + pub attr_span: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 05c19db4caa8..84415a592a2e 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -1,8 +1,9 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{DefId, DefIdMap}; +use rustc_hir::find_attr; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; -use rustc_span::sym; use crate::error::StrictCoherenceNeedsNegativeCoherence; use crate::ty::fast_reject::SimplifiedType; @@ -61,23 +62,15 @@ pub enum OverlapMode { impl OverlapMode { pub fn get(tcx: TyCtxt<'_>, trait_id: DefId) -> OverlapMode { let with_negative_coherence = tcx.features().with_negative_coherence(); - let strict_coherence = tcx.has_attr(trait_id, sym::rustc_strict_coherence); + let strict_coherence = find_attr!(tcx.get_all_attrs(trait_id), AttributeKind::RustcStrictCoherence(span) => *span); if with_negative_coherence { - if strict_coherence { OverlapMode::Strict } else { OverlapMode::WithNegative } + if strict_coherence.is_some() { OverlapMode::Strict } else { OverlapMode::WithNegative } } else { - if strict_coherence { - let attr_span = trait_id - .as_local() - .into_iter() - .flat_map(|local_def_id| { - tcx.hir_attrs(tcx.local_def_id_to_hir_id(local_def_id)) - }) - .find(|attr| attr.has_name(sym::rustc_strict_coherence)) - .map(|attr| attr.span()); + if let Some(span) = strict_coherence { tcx.dcx().emit_err(StrictCoherenceNeedsNegativeCoherence { span: tcx.def_span(trait_id), - attr_span, + attr_span: span, }); } OverlapMode::Stable diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 6c4b76a08ad2..c29e4b2b1afe 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -344,6 +344,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcSkipDuringMethodDispatch { .. } | AttributeKind::RustcSpecializationTrait(..) | AttributeKind::RustcStdInternalSymbol (..) + | AttributeKind::RustcStrictCoherence(..) | AttributeKind::RustcSymbolName(..) | AttributeKind::RustcThenThisWouldNeed(..) | AttributeKind::RustcUnsafeSpecializationMarker(..) @@ -402,7 +403,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_never_type_options | sym::rustc_autodiff | sym::rustc_capture_analysis - | sym::rustc_strict_coherence | sym::rustc_mir | sym::rustc_outlives | sym::rustc_evaluate_where_clauses From dfef1209b1ed4d4bb9eee0d00fe3df1154e3edf7 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 31 Jan 2026 22:33:56 +0100 Subject: [PATCH 3422/3801] x86: use `intrinsics::simd` for masked truncated saturating stores --- .../crates/core_arch/src/x86/avx512bw.rs | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 8e074fdcfa48..3ba171c0fa50 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -12476,7 +12476,14 @@ pub unsafe fn _mm512_mask_cvtsepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask32, #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] pub unsafe fn _mm256_mask_cvtsepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask16, a: __m256i) { - vpmovswbmem256(mem_addr, a.as_i16x16(), k); + let mask = simd_select_bitmask(k, i16x16::splat(!0), i16x16::ZERO); + + let max = simd_splat(i16::from(i8::MAX)); + let min = simd_splat(i16::from(i8::MIN)); + + let v = simd_imax(simd_imin(a.as_i16x16(), max), min); + let truncated: i8x16 = simd_cast(v); + simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, truncated); } /// Convert packed signed 16-bit integers in a to packed 8-bit integers with signed saturation, and store the active results (those with their respective bit set in writemask k) to unaligned memory at base_addr. @@ -12487,7 +12494,14 @@ pub unsafe fn _mm256_mask_cvtsepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask16, #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovswb))] pub unsafe fn _mm_mask_cvtsepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask8, a: __m128i) { - vpmovswbmem128(mem_addr, a.as_i16x8(), k); + let mask = simd_select_bitmask(k, i16x8::splat(!0), i16x8::ZERO); + + let max = simd_splat(i16::from(i8::MAX)); + let min = simd_splat(i16::from(i8::MIN)); + + let v = simd_imax(simd_imin(a.as_i16x8(), max), min); + let truncated: i8x8 = simd_cast(v); + simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, truncated); } /// Convert packed 16-bit integers in a to packed 8-bit integers with truncation, and store the active results (those with their respective bit set in writemask k) to unaligned memory at base_addr. @@ -12555,7 +12569,12 @@ pub unsafe fn _mm512_mask_cvtusepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask32 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] pub unsafe fn _mm256_mask_cvtusepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask16, a: __m256i) { - vpmovuswbmem256(mem_addr, a.as_i16x16(), k); + let mask = simd_select_bitmask(k, i16x16::splat(!0), i16x16::ZERO); + let mem_addr = mem_addr.cast::(); + let max = simd_splat(u16::from(u8::MAX)); + + let truncated: u8x16 = simd_cast(simd_imin(a.as_u16x16(), max)); + simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, truncated); } /// Convert packed unsigned 16-bit integers in a to packed unsigned 8-bit integers with unsigned saturation, and store the active results (those with their respective bit set in writemask k) to unaligned memory at base_addr. @@ -12566,7 +12585,15 @@ pub unsafe fn _mm256_mask_cvtusepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask16 #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpmovuswb))] pub unsafe fn _mm_mask_cvtusepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask8, a: __m128i) { - vpmovuswbmem128(mem_addr, a.as_i16x8(), k); + let mask = simd_select_bitmask(k, i16x8::splat(!0), i16x8::ZERO); + let mem_addr = mem_addr.cast::(); + let max = simd_splat(u16::from(u8::MAX)); + + let v = a.as_u16x8(); + let v = simd_imin(v, max); + + let truncated: u8x8 = simd_cast(v); + simd_masked_store!(SimdAlign::Unaligned, mask, mem_addr, truncated); } #[allow(improper_ctypes)] @@ -12632,17 +12659,9 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.mask.pmovs.wb.mem.512"] fn vpmovswbmem(mem_addr: *mut i8, a: i16x32, mask: u32); - #[link_name = "llvm.x86.avx512.mask.pmovs.wb.mem.256"] - fn vpmovswbmem256(mem_addr: *mut i8, a: i16x16, mask: u16); - #[link_name = "llvm.x86.avx512.mask.pmovs.wb.mem.128"] - fn vpmovswbmem128(mem_addr: *mut i8, a: i16x8, mask: u8); #[link_name = "llvm.x86.avx512.mask.pmovus.wb.mem.512"] fn vpmovuswbmem(mem_addr: *mut i8, a: i16x32, mask: u32); - #[link_name = "llvm.x86.avx512.mask.pmovus.wb.mem.256"] - fn vpmovuswbmem256(mem_addr: *mut i8, a: i16x16, mask: u16); - #[link_name = "llvm.x86.avx512.mask.pmovus.wb.mem.128"] - fn vpmovuswbmem128(mem_addr: *mut i8, a: i16x8, mask: u8); } #[cfg(test)] From 2d65a33c612cf85e9a0b80e73c870520eb289008 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 7 Feb 2026 00:01:35 +0100 Subject: [PATCH 3423/3801] Implement indent check --- .../src/diagnostics/diagnostic_builder.rs | 7 +++- .../rustc_macros/src/diagnostics/message.rs | 39 +++++++++++++++++-- .../rustc_macros/src/diagnostics/utils.rs | 2 +- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index b386408a1918..de8ee42caf45 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -203,8 +203,11 @@ impl DiagnosticDeriveVariantBuilder { ) .emit(); } - self.message = - Some(Message { message_span: message.span(), value: message.value() }); + self.message = Some(Message { + attr_span: attr.span(), + message_span: message.span(), + value: message.value(), + }); } // Parse arguments diff --git a/compiler/rustc_macros/src/diagnostics/message.rs b/compiler/rustc_macros/src/diagnostics/message.rs index 18d4d60dde3e..3276abfce413 100644 --- a/compiler/rustc_macros/src/diagnostics/message.rs +++ b/compiler/rustc_macros/src/diagnostics/message.rs @@ -9,6 +9,7 @@ use crate::diagnostics::error::span_err; #[derive(Clone)] pub(crate) struct Message { + pub attr_span: Span, pub message_span: Span, pub value: String, } @@ -19,12 +20,18 @@ impl Message { /// For subdiagnostics, we cannot check this. pub(crate) fn diag_message(&self, variant: Option<&VariantInfo<'_>>) -> TokenStream { let message = &self.value; - verify_fluent_message(self.message_span, &message, variant); + self.verify(variant); quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) } } + + fn verify(&self, variant: Option<&VariantInfo<'_>>) { + verify_variables_used(self.message_span, &self.value, variant); + verify_message_style(self.message_span, &self.value); + verify_message_formatting(self.attr_span, self.message_span, &self.value); + } } -fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&VariantInfo<'_>>) { +fn verify_variables_used(msg_span: Span, message_str: &str, variant: Option<&VariantInfo<'_>>) { // Parse the fluent message const GENERATED_MSG_ID: &str = "generated_msg"; let resource = @@ -53,8 +60,6 @@ fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&Var } } } - - verify_message_style(msg_span, message_str); } fn variable_references<'a>(msg: &fluent_syntax::ast::Message<&'a str>) -> Vec<&'a str> { @@ -120,3 +125,29 @@ fn verify_message_style(msg_span: Span, message: &str) { return; } } + +/// Verifies that the message is properly indented into the code +fn verify_message_formatting(attr_span: Span, msg_span: Span, message: &str) { + // Find the indent at the start of the message (`column()` is one-indexed) + let start = attr_span.unwrap().column() - 1; + + for line in message.lines().skip(1) { + if line.is_empty() { + continue; + } + let indent = line.chars().take_while(|c| *c == ' ').count(); + if indent < start { + span_err( + msg_span.unwrap(), + format!("message is not properly indented. {indent} < {start}"), + ) + .emit(); + return; + } + if indent % 4 != 0 { + span_err(msg_span.unwrap(), "message is not indented with a multiple of 4 spaces") + .emit(); + return; + } + } +} diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index c308f6126325..55a8445744cb 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -708,7 +708,7 @@ impl SubdiagnosticVariant { } if !input.is_empty() { input.parse::()?; } if is_first { - message = Some(Message { message_span: inline_message.span(), value: inline_message.value() }); + message = Some(Message { attr_span: attr.span(), message_span: inline_message.span(), value: inline_message.value() }); is_first = false; } else { span_err(inline_message.span().unwrap(), "a diagnostic message must be the first argument to the attribute").emit(); From 99c6009c45fd2c1b7f4740b96d9c634d83ad4a5a Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 7 Feb 2026 10:25:00 +0100 Subject: [PATCH 3424/3801] Reformat existing messages --- compiler/rustc_const_eval/src/errors.rs | 46 +++--- compiler/rustc_mir_build/src/errors.rs | 34 ++--- compiler/rustc_monomorphize/src/errors.rs | 6 +- compiler/rustc_parse/src/errors.rs | 2 +- compiler/rustc_passes/src/errors.rs | 4 +- compiler/rustc_trait_selection/src/errors.rs | 150 ++++++++++--------- 6 files changed, 122 insertions(+), 120 deletions(-) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 3b49dbd907c8..a673e0cb1efb 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -106,9 +106,9 @@ pub(crate) struct UnstableInStableExposed { pub is_function_call2: bool, #[suggestion( "if the {$is_function_call2 -> - [true] caller - *[false] function -} is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]`", + [true] caller + *[false] function + } is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]`", code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n", applicability = "has-placeholders" )] @@ -300,11 +300,11 @@ pub(crate) struct UnallowedHeapAllocations { #[primary_span] #[label( r#"allocation not allowed in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"# + [const] constant + [static] static + [const_fn] constant function + *[other] {""} + }s"# )] pub span: Span, pub kind: ConstContext, @@ -539,20 +539,20 @@ pub enum NonConstClosureNote { }, #[note( r#"function pointers need an RFC before allowed to be called in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"# + [const] constant + [static] static + [const_fn] constant function + *[other] {""} + }s"# )] FnPtr, #[note( r#"closures need an RFC before allowed to be called in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"# + [const] constant + [static] static + [const_fn] constant function + *[other] {""} + }s"# )] Closure, } @@ -608,11 +608,11 @@ pub struct LiveDrop<'tcx> { #[primary_span] #[label( r#"the destructor for this type cannot be evaluated in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"# + [const] constant + [static] static + [const_fn] constant function + *[other] {""} + }s"# )] pub span: Span, pub kind: ConstContext, diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 2474b3c49a61..fed0435f59a0 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -198,12 +198,12 @@ pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { pub(crate) missing_target_features: DiagArgValue, pub(crate) missing_target_features_count: usize, #[note("the {$build_target_features} target {$build_target_features_count -> - [1] feature - *[count] features + [1] feature + *[count] features } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> - [1] it -*[count] them -} in `#[target_feature]`")] + [1] it + *[count] them + } in `#[target_feature]`")] pub(crate) note: bool, pub(crate) build_target_features: DiagArgValue, pub(crate) build_target_features_count: usize, @@ -532,12 +532,12 @@ pub(crate) struct CallToFunctionWithRequiresUnsafe { pub(crate) missing_target_features: DiagArgValue, pub(crate) missing_target_features_count: usize, #[note("the {$build_target_features} target {$build_target_features_count -> - [1] feature - *[count] features -} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> - [1] it - *[count] them -} in `#[target_feature]`")] + [1] feature + *[count] features + } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> + [1] it + *[count] them + } in `#[target_feature]`")] pub(crate) note: bool, pub(crate) build_target_features: DiagArgValue, pub(crate) build_target_features_count: usize, @@ -1264,9 +1264,9 @@ pub(crate) struct InterpretedAsConstSugg { pub(crate) enum SuggestLet { #[multipart_suggestion( "you might want to use `if let` to ignore the {$count -> -[one] variant that isn't -*[other] variants that aren't -} matched", + [one] variant that isn't + *[other] variants that aren't + } matched", applicability = "has-placeholders" )] If { @@ -1278,9 +1278,9 @@ pub(crate) enum SuggestLet { }, #[suggestion( "you might want to use `let...else` to handle the {$count -> -[one] variant that isn't -*[other] variants that aren't -} matched", + [one] variant that isn't + *[other] variants that aren't + } matched", code = " else {{ todo!() }}", applicability = "has-placeholders" )] diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index d045ae0b92cb..62a8743873bd 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -162,9 +162,9 @@ pub(crate) struct AbiRequiredTargetFeature<'a> { #[primary_span] #[label( "function {$is_call -> -[true] called -*[false] defined -} here" + [true] called + *[false] defined + } here" )] pub span: Span, pub required_feature: &'a str, diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index b54782ec592c..fb77af1c1948 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1151,7 +1151,7 @@ pub(crate) enum MatchArmBodyWithoutBracesSugg { #[multipart_suggestion( "surround the {$num_statements -> [one] statement - *[other] statements + *[other] statements } with a body", applicability = "machine-applicable" )] diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 90b4d1b32bf7..f420bba9b4e9 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1417,8 +1417,8 @@ pub(crate) struct DuplicateEiiImpls { pub second_crate: Symbol, #[note("in addition to these two, { $num_additional_crates -> - [one] another implementation was found in crate {$additional_crate_names} - *[other] more implementations were also found in the following crates: {$additional_crate_names} + [one] another implementation was found in crate {$additional_crate_names} + *[other] more implementations were also found in the following crates: {$additional_crate_names} }")] pub additional_crates: Option<()>, diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index c904eb83896d..013e4b522fb5 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -327,18 +327,18 @@ pub struct InferenceBadError<'a> { pub enum SourceKindSubdiag<'a> { #[suggestion( "{$kind -> -[with_pattern] consider giving `{$name}` an explicit type -[closure] consider giving this closure parameter an explicit type -*[other] consider giving this pattern a type -}{$x_kind -> -[has_name] , where the {$prefix_kind -> -*[type] type for {$prefix} -[const_with_param] value of const parameter -[const] value of the constant -} `{$arg_name}` is specified -[underscore] , where the placeholders `_` are specified -*[empty] {\"\"} -}", + [with_pattern] consider giving `{$name}` an explicit type + [closure] consider giving this closure parameter an explicit type + *[other] consider giving this pattern a type + }{$x_kind -> + [has_name] , where the {$prefix_kind -> + *[type] type for {$prefix} + [const_with_param] value of const parameter + [const] value of the constant + } `{$arg_name}` is specified + [underscore] , where the placeholders `_` are specified + *[empty] {\"\"} + }", style = "verbose", code = ": {type_name}", applicability = "has-placeholders" @@ -356,15 +356,15 @@ pub enum SourceKindSubdiag<'a> { }, #[label( "cannot infer {$is_type -> -[true] type -*[false] the value -} of the {$is_type -> -[true] type -*[false] const -} {$parent_exists -> -[true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}` -*[false] parameter {$param_name} -}" + [true] type + *[false] the value + } of the {$is_type -> + [true] type + *[false] const + } {$parent_exists -> + [true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}` + *[false] parameter {$param_name} + }" )] GenericLabel { #[primary_span] @@ -377,9 +377,9 @@ pub enum SourceKindSubdiag<'a> { }, #[suggestion( "consider specifying the generic {$arg_count -> -[one] argument -*[other] arguments -}", + [one] argument + *[other] arguments + }", style = "verbose", code = "::<{args}>", applicability = "has-placeholders" @@ -945,9 +945,9 @@ impl IntoDiagArg for TyOrSig<'_> { #[derive(Subdiagnostic)] pub enum ActualImplExplNotes<'tcx> { #[note("{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")] + [true] ... + *[false] {\"\"} + }closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")] ExpectedSignatureTwo { leading_ellipsis: bool, ty_or_sig: TyOrSig<'tcx>, @@ -956,9 +956,9 @@ pub enum ActualImplExplNotes<'tcx> { lifetime_2: usize, }, #[note("{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...")] + [true] ... + *[false] {\"\"} + }closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...")] ExpectedSignatureAny { leading_ellipsis: bool, ty_or_sig: TyOrSig<'tcx>, @@ -966,9 +966,9 @@ pub enum ActualImplExplNotes<'tcx> { lifetime_1: usize, }, #[note("{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...")] + [true] ... + *[false] {\"\"} + }closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...")] ExpectedSignatureSome { leading_ellipsis: bool, ty_or_sig: TyOrSig<'tcx>, @@ -977,9 +977,9 @@ pub enum ActualImplExplNotes<'tcx> { }, #[note( "{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`" + [true] ... + *[false] {\"\"} + }closure with signature `{$ty_or_sig}` must implement `{$trait_path}`" )] ExpectedSignatureNothing { leading_ellipsis: bool, @@ -987,9 +987,9 @@ pub enum ActualImplExplNotes<'tcx> { trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, }, #[note("{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")] + [true] ... + *[false] {\"\"} + }`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")] ExpectedPassiveTwo { leading_ellipsis: bool, ty_or_sig: TyOrSig<'tcx>, @@ -998,9 +998,9 @@ pub enum ActualImplExplNotes<'tcx> { lifetime_2: usize, }, #[note("{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any lifetime `'{$lifetime_1}`...")] + [true] ... + *[false] {\"\"} + }`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any lifetime `'{$lifetime_1}`...")] ExpectedPassiveAny { leading_ellipsis: bool, ty_or_sig: TyOrSig<'tcx>, @@ -1008,9 +1008,9 @@ pub enum ActualImplExplNotes<'tcx> { lifetime_1: usize, }, #[note("{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some specific lifetime `'{$lifetime_1}`...")] + [true] ... + *[false] {\"\"} + }`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some specific lifetime `'{$lifetime_1}`...")] ExpectedPassiveSome { leading_ellipsis: bool, ty_or_sig: TyOrSig<'tcx>, @@ -1019,9 +1019,9 @@ pub enum ActualImplExplNotes<'tcx> { }, #[note( "{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`" + [true] ... + *[false] {\"\"} + }`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`" )] ExpectedPassiveNothing { leading_ellipsis: bool, @@ -1029,9 +1029,9 @@ pub enum ActualImplExplNotes<'tcx> { trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, }, #[note("{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")] + [true] ... + *[false] {\"\"} + }`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")] ExpectedOtherTwo { leading_ellipsis: bool, ty_or_sig: TyOrSig<'tcx>, @@ -1041,9 +1041,9 @@ pub enum ActualImplExplNotes<'tcx> { }, #[note( "{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`..." + [true] ... + *[false] {\"\"} + }`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`..." )] ExpectedOtherAny { leading_ellipsis: bool, @@ -1053,9 +1053,9 @@ pub enum ActualImplExplNotes<'tcx> { }, #[note( "{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}`{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`..." + [true] ... + *[false] {\"\"} + }`{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`..." )] ExpectedOtherSome { leading_ellipsis: bool, @@ -1065,9 +1065,9 @@ pub enum ActualImplExplNotes<'tcx> { }, #[note( "{$leading_ellipsis -> -[true] ... -*[false] {\"\"} -}`{$ty_or_sig}` must implement `{$trait_path}`" + [true] ... + *[false] {\"\"} + }`{$ty_or_sig}` must implement `{$trait_path}`" )] ExpectedOtherNothing { leading_ellipsis: bool, @@ -1076,9 +1076,9 @@ pub enum ActualImplExplNotes<'tcx> { }, #[note( "...but it actually implements `{$trait_path}`{$has_lifetime -> -[true] , for some specific lifetime `'{$lifetime}` -*[false] {\"\"} -}" + [true] , for some specific lifetime `'{$lifetime}` + *[false] {\"\"} + }" )] ButActuallyImplementsTrait { trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, @@ -1087,9 +1087,9 @@ pub enum ActualImplExplNotes<'tcx> { }, #[note( "...but `{$trait_path}` is actually implemented for the type `{$ty}`{$has_lifetime -> -[true] , for some specific lifetime `'{$lifetime}` -*[false] {\"\"} -}" + [true] , for some specific lifetime `'{$lifetime}` + *[false] {\"\"} + }" )] ButActuallyImplementedForTy { trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, @@ -1099,9 +1099,9 @@ pub enum ActualImplExplNotes<'tcx> { }, #[note( "...but `{$ty}` actually implements `{$trait_path}`{$has_lifetime -> -[true] , for some specific lifetime `'{$lifetime}` -*[false] {\"\"} -}" + [true] , for some specific lifetime `'{$lifetime}` + *[false] {\"\"} + }" )] ButActuallyTyImplements { trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, @@ -1246,7 +1246,7 @@ pub struct TraitImplDiff { pub trait_sp: Span, #[note( "expected signature `{$expected}` - {\" \"}found signature `{$found}`" + {\" \"}found signature `{$found}`" )] pub note: (), #[subdiagnostic] @@ -1940,10 +1940,12 @@ pub enum ObligationCauseFailureCode { #[primary_span] span: Span, }, - #[diag("{$lang_item_name -> -[panic_impl] `#[panic_handler]` -*[lang_item_name] lang item `{$lang_item_name}` -} function has wrong type", code = E0308)] + #[diag( + "{$lang_item_name -> + [panic_impl] `#[panic_handler]` + *[lang_item_name] lang item `{$lang_item_name}` + } function has wrong type" + , code = E0308)] FnLangCorrectType { #[primary_span] span: Span, From d3d4fd9312da82cbb0b17a597f458b282febfea7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 9 Feb 2026 10:14:40 +1100 Subject: [PATCH 3425/3801] Tweak query key trait bounds. Query keys must be stably hashable. Currently this requirement is expressed as a where-clause on `impl QueryDispatcher for SemiDynamicQueryDispatcher` and a where-clause on `create_deferred_query_stack_frame`. This commit removes those where-clause bounds and adds a single bound to `QueryCache::Key`, which already has some other bounds. I.e. it consolidates the bounds. It also gives them a name (`QueryCacheKey`) to avoid repeating them. There is also a related `Key` trait in `rustc_middle`; it should probably be merged with `QueryCacheKey` in the future, but not today. This cleanup helps with the next two commits, which do bigger rearrangements, and where the where-clauses caused me some difficulties. --- compiler/rustc_query_impl/src/lib.rs | 4 ---- compiler/rustc_query_impl/src/plumbing.rs | 3 +-- compiler/rustc_query_system/src/lib.rs | 1 + compiler/rustc_query_system/src/query/caches.rs | 11 ++++++++--- compiler/rustc_query_system/src/query/mod.rs | 4 +++- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 228d0070b55b..7e12365fc2ac 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -10,7 +10,6 @@ use std::marker::ConstParamTy; -use rustc_data_structures::stable_hasher::HashStable; use rustc_data_structures::sync::AtomicU64; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::{self, DepKind, DepKindVTable, DepNodeIndex}; @@ -23,7 +22,6 @@ use rustc_middle::query::plumbing::{QuerySystem, QuerySystemFns, QueryVTable}; use rustc_middle::query::values::Value; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; -use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ CycleError, CycleErrorHandling, HashResult, QueryCache, QueryDispatcher, QueryMap, QueryMode, QueryState, @@ -78,8 +76,6 @@ impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> Clone // This is `impl QueryDispatcher for SemiDynamicQueryDispatcher`. impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> QueryDispatcher<'tcx> for SemiDynamicQueryDispatcher<'tcx, C, FLAGS> -where - for<'a> C::Key: HashStable>, { type Qcx = QueryCtxt<'tcx>; type Key = C::Key; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 676d01be3385..dd8ea35019a4 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -27,7 +27,6 @@ use rustc_middle::ty::print::with_reduced_queries; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle, HasDepContext}; -use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ QueryCache, QueryContext, QueryDispatcher, QueryJobId, QueryMap, QuerySideEffect, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, @@ -360,7 +359,7 @@ pub(crate) fn create_deferred_query_stack_frame<'tcx, Cache>( ) -> QueryStackFrame> where Cache: QueryCache, - Cache::Key: Key + DynSend + DynSync + for<'a> HashStable> + 'tcx, + Cache::Key: Key + DynSend + DynSync, { let kind = vtable.dep_kind; diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 7f6426e395f9..fc63df3595c4 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -2,6 +2,7 @@ #![allow(internal_features)] #![feature(assert_matches)] #![feature(min_specialization)] +#![feature(trait_alias)] // tidy-alphabetical-end pub mod dep_graph; diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 67ad767d4d31..c1f5e5b67085 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -3,12 +3,17 @@ use std::hash::Hash; use std::sync::OnceLock; use rustc_data_structures::sharded::ShardedHashMap; +use rustc_data_structures::stable_hasher::HashStable; pub use rustc_data_structures::vec_cache::VecCache; use rustc_hir::def_id::LOCAL_CRATE; use rustc_index::Idx; use rustc_span::def_id::{DefId, DefIndex}; use crate::dep_graph::DepNodeIndex; +use crate::ich::StableHashingContext; + +/// Traits that all query keys must satisfy. +pub trait QueryCacheKey = Hash + Eq + Copy + Debug + for<'a> HashStable>; /// Trait for types that serve as an in-memory cache for query results, /// for a given key (argument) type and value (return) type. @@ -16,7 +21,7 @@ use crate::dep_graph::DepNodeIndex; /// Types implementing this trait are associated with actual key/value types /// by the `Cache` associated type of the `rustc_middle::query::Key` trait. pub trait QueryCache: Sized { - type Key: Hash + Eq + Copy + Debug; + type Key: QueryCacheKey; type Value: Copy; /// Returns the cached value (and other information) associated with the @@ -48,7 +53,7 @@ impl Default for DefaultCache { impl QueryCache for DefaultCache where - K: Eq + Hash + Copy + Debug, + K: QueryCacheKey, V: Copy, { type Key = K; @@ -175,7 +180,7 @@ where impl QueryCache for VecCache where - K: Idx + Eq + Hash + Copy + Debug, + K: Idx + QueryCacheKey, V: Copy, { type Key = K; diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 29a572b726f0..01bb6ff09fa1 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -12,7 +12,9 @@ use rustc_macros::{Decodable, Encodable}; use rustc_span::Span; use rustc_span::def_id::DefId; -pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; +pub use self::caches::{ + DefIdCache, DefaultCache, QueryCache, QueryCacheKey, SingleCache, VecCache, +}; pub use self::dispatcher::{HashResult, QueryDispatcher}; pub use self::job::{ QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, QueryMap, break_query_cycles, From 52caa7ae6d06a43f9fb07d37ba39c233e9273455 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 9 Feb 2026 10:38:44 +1100 Subject: [PATCH 3426/3801] Remove `QueryDispatcherUnerased::Dispatcher` associated type. It's always `SemiDynamicQueryDispatcher`, so we can just use that type directly. (This requires adding some explicit generic params to `QueryDispatcherUnerased`.) Less indirection makes the code clearer, and this is a prerequisite for the next commit, which is a much bigger simplification. --- compiler/rustc_query_impl/src/lib.rs | 9 ++--- compiler/rustc_query_impl/src/plumbing.rs | 44 ++++++++++++++--------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 7e12365fc2ac..327a8f4bc6c4 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -207,17 +207,14 @@ impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> QueryDispatcher<'tcx> /// /// There is one macro-generated implementation of this trait for each query, /// on the type `rustc_query_impl::query_impl::$name::QueryType`. -trait QueryDispatcherUnerased<'tcx> { +trait QueryDispatcherUnerased<'tcx, C: QueryCache, const FLAGS: QueryFlags> { type UnerasedValue; - type Dispatcher: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>; const NAME: &'static &'static str; - fn query_dispatcher(tcx: TyCtxt<'tcx>) -> Self::Dispatcher; + fn query_dispatcher(tcx: TyCtxt<'tcx>) -> SemiDynamicQueryDispatcher<'tcx, C, FLAGS>; - fn restore_val( - value: >::Value, - ) -> Self::UnerasedValue; + fn restore_val(value: C::Value) -> Self::UnerasedValue; } pub fn query_system<'tcx>( diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index dd8ea35019a4..bbda716eadb0 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -34,9 +34,9 @@ use rustc_query_system::query::{ use rustc_serialize::{Decodable, Encodable}; use rustc_span::def_id::LOCAL_CRATE; -use crate::QueryDispatcherUnerased; use crate::error::{QueryOverflow, QueryOverflowNote}; use crate::execution::{all_inactive, force_query}; +use crate::{QueryDispatcherUnerased, QueryFlags, SemiDynamicQueryDispatcher}; /// Implements [`QueryContext`] for use by [`rustc_query_system`], since that /// crate does not have direct access to [`TyCtxt`]. @@ -377,13 +377,13 @@ where QueryStackFrame::new(info, kind, hash, def_id, def_id_for_ty_in_cycle) } -pub(crate) fn encode_query_results<'a, 'tcx, Q>( - query: Q::Dispatcher, +pub(crate) fn encode_query_results<'a, 'tcx, Q, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, encoder: &mut CacheEncoder<'a, 'tcx>, query_result_index: &mut EncodedDepNodeIndex, ) where - Q: QueryDispatcherUnerased<'tcx>, + Q: QueryDispatcherUnerased<'tcx, C, FLAGS>, Q::UnerasedValue: Encodable>, { let _timer = qcx.tcx.prof.generic_activity_with_arg("encode_query_results_for", query.name()); @@ -506,17 +506,22 @@ where } } -pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q>( +pub(crate) fn make_dep_kind_vtable_for_query< + 'tcx, + Q, + C: QueryCache + 'tcx, + const FLAGS: QueryFlags, +>( is_anon: bool, is_eval_always: bool, ) -> DepKindVTable<'tcx> where - Q: QueryDispatcherUnerased<'tcx>, + Q: QueryDispatcherUnerased<'tcx, C, FLAGS>, { let fingerprint_style = if is_anon { FingerprintStyle::Opaque } else { - ::Key::fingerprint_style() + >>::fingerprint_style() }; if is_anon || !fingerprint_style.reconstructible() { @@ -712,25 +717,26 @@ macro_rules! define_queries { is_feedable: feedable!([$($modifiers)*]), }; - impl<'tcx> QueryDispatcherUnerased<'tcx> for QueryType<'tcx> { + impl<'tcx> QueryDispatcherUnerased<'tcx, queries::$name::Storage<'tcx>, FLAGS> + for QueryType<'tcx> + { type UnerasedValue = queries::$name::Value<'tcx>; - type Dispatcher = SemiDynamicQueryDispatcher< - 'tcx, - queries::$name::Storage<'tcx>, - FLAGS, - >; const NAME: &'static &'static str = &stringify!($name); #[inline(always)] - fn query_dispatcher(tcx: TyCtxt<'tcx>) -> Self::Dispatcher { + fn query_dispatcher(tcx: TyCtxt<'tcx>) + -> SemiDynamicQueryDispatcher<'tcx, queries::$name::Storage<'tcx>, FLAGS> + { SemiDynamicQueryDispatcher { vtable: &tcx.query_system.query_vtables.$name, } } #[inline(always)] - fn restore_val(value: >::Value) -> Self::UnerasedValue { + fn restore_val(value: as QueryCache>::Value) + -> Self::UnerasedValue + { erase::restore_val::>(value) } } @@ -786,7 +792,11 @@ macro_rules! define_queries { encoder: &mut CacheEncoder<'_, 'tcx>, query_result_index: &mut EncodedDepNodeIndex ) { - $crate::plumbing::encode_query_results::>( + $crate::plumbing::encode_query_results::< + query_impl::$name::QueryType<'tcx>, + _, + _ + > ( query_impl::$name::QueryType::query_dispatcher(tcx), QueryCtxt::new(tcx), encoder, @@ -958,7 +968,7 @@ macro_rules! define_queries { $(pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> { use $crate::query_impl::$name::QueryType; - $crate::plumbing::make_dep_kind_vtable_for_query::>( + $crate::plumbing::make_dep_kind_vtable_for_query::, _, _>( is_anon!([$($modifiers)*]), is_eval_always!([$($modifiers)*]), ) From 1fa165deeeff28e9b8b4a2de16b92c0844059f69 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sun, 8 Feb 2026 22:01:24 -0500 Subject: [PATCH 3427/3801] style: remove unneeded trailing commas Make format-like macro calls look similar to what `cargo fmt` does automatically - remove trailing commas. When removing a comma, I also inlined some variables for consistency and clarity. --- .../infer/nice_region_error/find_anon_type.rs | 4 ++-- .../infer/nice_region_error/static_impl_trait.rs | 6 +++--- .../src/error_reporting/traits/ambiguity.rs | 6 +++--- .../src/error_reporting/traits/fulfillment_errors.rs | 2 +- .../src/error_reporting/traits/on_unimplemented.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 8 ++++---- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs index 8fe4ffebd865..7d061e65df80 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs @@ -190,8 +190,8 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { } Some(rbv::ResolvedArg::LateBound(debruijn_index, _, id)) => { - debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index,); - debug!("id={:?}", id); + debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {debruijn_index:?}"); + debug!("id={id:?}"); if debruijn_index == self.current_index && id.to_def_id() == self.region_def_id { return ControlFlow::Break(()); } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index 3ee6e6b739c0..3ed1f7c3481f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -239,14 +239,14 @@ pub fn suggest_new_region_bound( }; spans_suggs.push((fn_return.span.shrink_to_hi(), format!(" + {name} "))); err.multipart_suggestion_verbose( - format!("{declare} `{ty}` {captures}, {use_lt}",), + format!("{declare} `{ty}` {captures}, {use_lt}"), spans_suggs, Applicability::MaybeIncorrect, ); } else { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), - format!("{declare} `{ty}` {captures}, {explicit}",), + format!("{declare} `{ty}` {captures}, {explicit}"), &plus_lt, Applicability::MaybeIncorrect, ); @@ -257,7 +257,7 @@ pub fn suggest_new_region_bound( if let LifetimeKind::ImplicitObjectLifetimeDefault = lt.kind { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), - format!("{declare} the trait object {captures}, {explicit}",), + format!("{declare} the trait object {captures}, {explicit}"), &plus_lt, Applicability::MaybeIncorrect, ); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index eb72f71382ef..16c4ac68cdf0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -710,7 +710,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { predicate ); let post = if post.len() > 1 || (post.len() == 1 && post[0].contains('\n')) { - format!(":\n{}", post.iter().map(|p| format!("- {p}")).collect::>().join("\n"),) + format!(":\n{}", post.iter().map(|p| format!("- {p}")).collect::>().join("\n")) } else if post.len() == 1 { format!(": `{}`", post[0]) } else { @@ -722,7 +722,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.note(format!("cannot satisfy `{predicate}`")); } (0, _, 1) => { - err.note(format!("{} in the `{}` crate{}", msg, crates[0], post,)); + err.note(format!("{msg} in the `{}` crate{post}", crates[0])); } (0, _, _) => { err.note(format!( @@ -739,7 +739,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (_, 1, 1) => { let span: MultiSpan = spans.into(); err.span_note(span, msg); - err.note(format!("and another `impl` found in the `{}` crate{}", crates[0], post,)); + err.note(format!("and another `impl` found in the `{}` crate{post}", crates[0])); } _ => { let span: MultiSpan = spans.into(); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 3cb3224302b6..18597e001c9f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2241,7 +2241,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.highlighted_span_help( self.tcx.def_span(def_id), vec![ - StringPart::normal(format!("the trait `{trait_}` ",)), + StringPart::normal(format!("the trait `{trait_}` ")), StringPart::highlighted("is"), StringPart::normal(desc), StringPart::highlighted(self_ty), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 5eff7bba7c63..a98f952d55a3 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -888,7 +888,7 @@ impl<'tcx> OnUnimplementedFormatString { } } else { let reported = - struct_span_code_err!(tcx.dcx(), self.span, E0231, "{}", e.description,) + struct_span_code_err!(tcx.dcx(), self.span, E0231, "{}", e.description) .emit(); result = Err(reported); } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index f5bf74a79919..935834b832f2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -312,7 +312,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `async`/`gen` constructs get lowered to a special kind of coroutine that // should *not* `impl Coroutine`. ty::Coroutine(did, ..) if self.tcx().is_general_coroutine(*did) => { - debug!(?self_ty, ?obligation, "assemble_coroutine_candidates",); + debug!(?self_ty, ?obligation, "assemble_coroutine_candidates"); candidates.vec.push(CoroutineCandidate); } @@ -334,7 +334,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // async constructs get lowered to a special kind of coroutine that // should directly `impl Future`. if self.tcx().coroutine_is_async(*did) { - debug!(?self_ty, ?obligation, "assemble_future_candidates",); + debug!(?self_ty, ?obligation, "assemble_future_candidates"); candidates.vec.push(FutureCandidate); } @@ -352,7 +352,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let ty::Coroutine(did, ..) = self_ty.kind() && self.tcx().coroutine_is_gen(*did) { - debug!(?self_ty, ?obligation, "assemble_iterator_candidates",); + debug!(?self_ty, ?obligation, "assemble_iterator_candidates"); candidates.vec.push(IteratorCandidate); } @@ -378,7 +378,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // gen constructs get lowered to a special kind of coroutine that // should directly `impl AsyncIterator`. if self.tcx().coroutine_is_async_gen(did) { - debug!(?self_ty, ?obligation, "assemble_iterator_candidates",); + debug!(?self_ty, ?obligation, "assemble_iterator_candidates"); // Can only confirm this candidate if we have constrained // the `Yield` type to at least `Poll>`.. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 787dd4ea6254..2233fb4f90e4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1223,7 +1223,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { && self.match_fresh_trait_preds(stack.fresh_trait_pred, prev.fresh_trait_pred) }) { - debug!("evaluate_stack --> unbound argument, recursive --> giving up",); + debug!("evaluate_stack --> unbound argument, recursive --> giving up"); return Ok(EvaluatedToAmbigStackDependent); } From 81fb703664280626c03428c384695d766be10031 Mon Sep 17 00:00:00 2001 From: Weixie Cui Date: Sun, 8 Feb 2026 11:44:50 +0800 Subject: [PATCH 3428/3801] Fix copy-paste bug: use sub_trace.cause instead of sup_trace.cause in report_sub_sup_conflict In `report_sub_sup_conflict`, when calling `values_str` for `sub_trace.values`, the code was incorrectly passing `sup_trace.cause` instead of `sub_trace.cause`. This is a copy-paste error from the preceding line which correctly uses `sup_trace.cause` for `sup_trace.values`. The `cause` parameter matters for `ValuePairs::PolySigs` comparisons, where `values_str` inspects `cause.code()` to extract `impl_item_def_id` and `trait_item_def_id` for richer function signature diagnostics. Using the wrong trace's cause could produce incorrect function def IDs, leading to misleading diagnostic output when the sub and sup traces originate from different obligations. Even for non-PolySigs variants where `cause` is currently unused by `values_str`, passing the semantically correct cause is the right thing to do for correctness and maintainability. --- .../rustc_trait_selection/src/error_reporting/infer/region.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index d15fb40dd1cb..81cca3dd67ac 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -1020,7 +1020,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let Some((sup_expected, sup_found)) = self.values_str(sup_trace.values, &sup_trace.cause, err.long_ty_path()) && let Some((sub_expected, sub_found)) = - self.values_str(sub_trace.values, &sup_trace.cause, err.long_ty_path()) + self.values_str(sub_trace.values, &sub_trace.cause, err.long_ty_path()) && sub_expected == sup_expected && sub_found == sup_found { From f394d1e6c617439e027fe2fae2b9d581709639db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 9 Feb 2026 07:21:53 +0200 Subject: [PATCH 3429/3801] Fix lockfile --- src/tools/rust-analyzer/Cargo.lock | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 18c53986a012..755ae55eea46 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -3754,15 +3754,3 @@ dependencies = [ "memchr", "time", ] - -[[patch.unused]] -name = "salsa" -version = "0.25.2" - -[[patch.unused]] -name = "salsa-macro-rules" -version = "0.25.2" - -[[patch.unused]] -name = "salsa-macros" -version = "0.25.2" From 3b705eae4fe9f16efd8193fc5dc822fc9e66e5da Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 9 Feb 2026 14:24:59 +0800 Subject: [PATCH 3430/3801] Add ui test insufficient-suggestion-issue-141679.rs --- .../insufficient-suggestion-issue-141679.rs | 8 ++++++++ .../insufficient-suggestion-issue-141679.stderr | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs create mode 100644 tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr diff --git a/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs new file mode 100644 index 000000000000..daf8693b5264 --- /dev/null +++ b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs @@ -0,0 +1,8 @@ +use std::rc::Rc; +pub struct Foo; + +pub type Function = Rc; + +impl Function {} +//~^ ERROR cannot define inherent `impl` for a type outside of the crate where the type is defined [E0116] +fn main(){} \ No newline at end of file diff --git a/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr new file mode 100644 index 000000000000..cbb94ea4d367 --- /dev/null +++ b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr @@ -0,0 +1,11 @@ +error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined + --> $DIR/insufficient-suggestion-issue-141679.rs:6:1 + | +LL | impl Function {} + | ^^^^^^^^^^^^^ impl for type defined outside of crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0116`. From 91a612620822993435a49c288256c1028351a236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 9 Feb 2026 07:36:48 +0100 Subject: [PATCH 3431/3801] Use `scope` for `par_slice` instead of `join` --- .../src/sync/parallel.rs | 41 +++++++------------ 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index b515c0bee8a6..552d02b8b91d 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs @@ -138,34 +138,21 @@ fn par_slice( guard: &ParallelGuard, for_each: impl Fn(&mut I) + DynSync + DynSend, ) { - struct State<'a, F> { - for_each: FromDyn, - guard: &'a ParallelGuard, - group: usize, - } - - fn par_rec( - items: &mut [I], - state: &State<'_, F>, - ) { - if items.len() <= state.group { - for item in items { - state.guard.run(|| (state.for_each)(item)); - } - } else { - let (left, right) = items.split_at_mut(items.len() / 2); - let mut left = state.for_each.derive(left); - let mut right = state.for_each.derive(right); - rustc_thread_pool::join(move || par_rec(*left, state), move || par_rec(*right, state)); + let for_each = FromDyn::from(for_each); + let mut items = for_each.derive(items); + rustc_thread_pool::scope(|s| { + let proof = items.derive(()); + let group_size = std::cmp::max(items.len() / 128, 1); + for group in items.chunks_exact_mut(group_size) { + let group = proof.derive(group); + s.spawn(|_| { + let mut group = group; + for i in group.iter_mut() { + guard.run(|| for_each(i)); + } + }); } - } - - let state = State { - for_each: FromDyn::from(for_each), - guard, - group: std::cmp::max(items.len() / 128, 1), - }; - par_rec(items, &state) + }); } pub fn par_for_each_in>( From f24839539428bca14becbf813d0352e1aff17c18 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Sun, 8 Feb 2026 17:00:47 +0800 Subject: [PATCH 3432/3801] bless tests --- tests/crashes/137916.rs | 13 ---- tests/crashes/138274.rs | 18 ------ tests/ui/async-await/issue-70818.rs | 3 +- tests/ui/async-await/issue-70818.stderr | 23 +------ .../async-await/issue-70935-complex-spans.rs | 1 - .../issue-70935-complex-spans.stderr | 47 +------------- tests/ui/coroutine/issue-105084.rs | 1 - tests/ui/coroutine/issue-105084.stderr | 29 +-------- .../stalled-coroutine-obligations.rs | 32 ++++++++++ .../stalled-coroutine-obligations.stderr | 40 ++++++++++++ .../stalled-coroutine-obligations.rs | 50 +++++++++++++++ .../stalled-coroutine-obligations.stderr | 62 +++++++++++++++++++ 12 files changed, 190 insertions(+), 129 deletions(-) delete mode 100644 tests/crashes/137916.rs delete mode 100644 tests/crashes/138274.rs create mode 100644 tests/ui/coroutine/stalled-coroutine-obligations.rs create mode 100644 tests/ui/coroutine/stalled-coroutine-obligations.stderr create mode 100644 tests/ui/traits/next-solver/stalled-coroutine-obligations.rs create mode 100644 tests/ui/traits/next-solver/stalled-coroutine-obligations.stderr diff --git a/tests/crashes/137916.rs b/tests/crashes/137916.rs deleted file mode 100644 index b25e7b200d95..000000000000 --- a/tests/crashes/137916.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #137916 -//@ edition: 2021 -use std::ptr::null; - -async fn a() -> Box { - Box::new(async { - let non_send = null::<()>(); - &non_send; - async {}.await - }) -} - -fn main() {} diff --git a/tests/crashes/138274.rs b/tests/crashes/138274.rs deleted file mode 100644 index d657b27e46f3..000000000000 --- a/tests/crashes/138274.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ known-bug: #138274 -//@ edition: 2021 -//@ compile-flags: --crate-type=lib -trait Trait {} - -fn foo() -> Box { - todo!() -} - -fn fetch() { - async { - let fut = async { - let _x = foo(); - async {}.await; - }; - let _: Box = Box::new(fut); - }; -} diff --git a/tests/ui/async-await/issue-70818.rs b/tests/ui/async-await/issue-70818.rs index c11332fe7d84..af9f33d9050b 100644 --- a/tests/ui/async-await/issue-70818.rs +++ b/tests/ui/async-await/issue-70818.rs @@ -2,9 +2,8 @@ use std::future::Future; fn foo(ty: T, ty1: U) -> impl Future + Send { - //~^ ERROR future cannot be sent between threads safely + //~^ ERROR: future cannot be sent between threads safely async { (ty, ty1) } - //~^ ERROR future cannot be sent between threads safely } fn main() {} diff --git a/tests/ui/async-await/issue-70818.stderr b/tests/ui/async-await/issue-70818.stderr index 07fd20cdd77e..8de6a825042b 100644 --- a/tests/ui/async-await/issue-70818.stderr +++ b/tests/ui/async-await/issue-70818.stderr @@ -1,24 +1,3 @@ -error: future cannot be sent between threads safely - --> $DIR/issue-70818.rs:6:5 - | -LL | async { (ty, ty1) } - | ^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` - | -note: captured value is not `Send` - --> $DIR/issue-70818.rs:6:18 - | -LL | async { (ty, ty1) } - | ^^^ has type `U` which is not `Send` -note: required by a bound in an opaque type - --> $DIR/issue-70818.rs:4:69 - | -LL | fn foo(ty: T, ty1: U) -> impl Future + Send { - | ^^^^ -help: consider restricting type parameter `U` with trait `Send` - | -LL | fn foo(ty: T, ty1: U) -> impl Future + Send { - | +++++++++++++++++++ - error: future cannot be sent between threads safely --> $DIR/issue-70818.rs:4:38 | @@ -35,5 +14,5 @@ help: consider restricting type parameter `U` with trait `Send` LL | fn foo(ty: T, ty1: U) -> impl Future + Send { | +++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/async-await/issue-70935-complex-spans.rs b/tests/ui/async-await/issue-70935-complex-spans.rs index 2851637ae78f..27826f79dcd9 100644 --- a/tests/ui/async-await/issue-70935-complex-spans.rs +++ b/tests/ui/async-await/issue-70935-complex-spans.rs @@ -15,7 +15,6 @@ async fn baz(_c: impl FnMut() -> T) where T: Future { fn foo(x: NotSync) -> impl Future + Send { //~^ ERROR `*mut ()` cannot be shared between threads safely async move { - //~^ ERROR `*mut ()` cannot be shared between threads safely baz(|| async { foo(x.clone()); }).await; diff --git a/tests/ui/async-await/issue-70935-complex-spans.stderr b/tests/ui/async-await/issue-70935-complex-spans.stderr index 31d15c459217..b9180c620b0d 100644 --- a/tests/ui/async-await/issue-70935-complex-spans.stderr +++ b/tests/ui/async-await/issue-70935-complex-spans.stderr @@ -1,46 +1,3 @@ -error[E0277]: `*mut ()` cannot be shared between threads safely - --> $DIR/issue-70935-complex-spans.rs:17:5 - | -LL | / async move { -LL | | -LL | | baz(|| async { -LL | | foo(x.clone()); -LL | | }).await; -LL | | } - | |_____^ `*mut ()` cannot be shared between threads safely - | - = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()` -note: required because it appears within the type `PhantomData<*mut ()>` - --> $SRC_DIR/core/src/marker.rs:LL:COL -note: required because it appears within the type `NotSync` - --> $DIR/issue-70935-complex-spans.rs:9:8 - | -LL | struct NotSync(PhantomData<*mut ()>); - | ^^^^^^^ - = note: required for `&NotSync` to implement `Send` -note: required because it's used within this closure - --> $DIR/issue-70935-complex-spans.rs:19:13 - | -LL | baz(|| async { - | ^^ -note: required because it's used within this `async` fn body - --> $DIR/issue-70935-complex-spans.rs:12:67 - | -LL | async fn baz(_c: impl FnMut() -> T) where T: Future { - | ___________________________________________________________________^ -LL | | } - | |_^ -note: required because it's used within this `async` block - --> $DIR/issue-70935-complex-spans.rs:17:5 - | -LL | async move { - | ^^^^^^^^^^ -note: required by a bound in an opaque type - --> $DIR/issue-70935-complex-spans.rs:15:37 - | -LL | fn foo(x: NotSync) -> impl Future + Send { - | ^^^^ - error[E0277]: `*mut ()` cannot be shared between threads safely --> $DIR/issue-70935-complex-spans.rs:15:23 | @@ -57,7 +14,7 @@ LL | struct NotSync(PhantomData<*mut ()>); | ^^^^^^^ = note: required for `&NotSync` to implement `Send` note: required because it's used within this closure - --> $DIR/issue-70935-complex-spans.rs:19:13 + --> $DIR/issue-70935-complex-spans.rs:18:13 | LL | baz(|| async { | ^^ @@ -74,6 +31,6 @@ note: required because it's used within this `async` block LL | async move { | ^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coroutine/issue-105084.rs b/tests/ui/coroutine/issue-105084.rs index cddee4990175..4e9f6ee3a595 100644 --- a/tests/ui/coroutine/issue-105084.rs +++ b/tests/ui/coroutine/issue-105084.rs @@ -36,7 +36,6 @@ fn main() { // one inside `g` and one inside `h`. // Proceed and drop `t` in `g`. Pin::new(&mut g).resume(()); - //~^ ERROR borrow of moved value: `g` // Proceed and drop `t` in `h` -> double free! Pin::new(&mut h).resume(()); diff --git a/tests/ui/coroutine/issue-105084.stderr b/tests/ui/coroutine/issue-105084.stderr index 23c1fdc54592..a69d20e607a4 100644 --- a/tests/ui/coroutine/issue-105084.stderr +++ b/tests/ui/coroutine/issue-105084.stderr @@ -1,27 +1,3 @@ -error[E0382]: borrow of moved value: `g` - --> $DIR/issue-105084.rs:38:14 - | -LL | let mut g = #[coroutine] - | ----- move occurs because `g` has type `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, which does not implement the `Copy` trait -... -LL | let mut h = copy(g); - | - value moved here -... -LL | Pin::new(&mut g).resume(()); - | ^^^^^^ value borrowed here after move - | -note: consider changing this parameter type in function `copy` to borrow instead if owning the value isn't necessary - --> $DIR/issue-105084.rs:10:21 - | -LL | fn copy(x: T) -> T { - | ---- ^ this parameter takes ownership of the value - | | - | in this function -help: consider cloning the value if the performance cost is acceptable - | -LL | let mut h = copy(g.clone()); - | ++++++++ - error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}` --> $DIR/issue-105084.rs:32:17 | @@ -45,7 +21,6 @@ note: required by a bound in `copy` LL | fn copy(x: T) -> T { | ^^^^ required by this bound in `copy` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0382. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coroutine/stalled-coroutine-obligations.rs b/tests/ui/coroutine/stalled-coroutine-obligations.rs new file mode 100644 index 000000000000..89af3c9a583c --- /dev/null +++ b/tests/ui/coroutine/stalled-coroutine-obligations.rs @@ -0,0 +1,32 @@ +//@ edition: 2021 + +// Regression tests for #137916 and #138274 +// We now check stalled coroutine obligations eagerly at the start of `mir_borrowck`. +// So these unsatisfied bounds are caught before causing ICEs. +use std::ptr::null; + +async fn a() -> Box { + Box::new(async { + //~^ ERROR: future cannot be sent between threads safely + let non_send = null::<()>(); + &non_send; + async {}.await + }) +} + + +trait Trait {} +fn foo() -> Box { todo!() } + +fn fetch() { + async { + let fut = async { + let _x = foo(); + async {}.await; + }; + let _: Box = Box::new(fut); + //~^ ERROR: future cannot be sent between threads safely + }; +} + +fn main() {} diff --git a/tests/ui/coroutine/stalled-coroutine-obligations.stderr b/tests/ui/coroutine/stalled-coroutine-obligations.stderr new file mode 100644 index 000000000000..cbf395dd6cfb --- /dev/null +++ b/tests/ui/coroutine/stalled-coroutine-obligations.stderr @@ -0,0 +1,40 @@ +error: future cannot be sent between threads safely + --> $DIR/stalled-coroutine-obligations.rs:9:5 + | +LL | / Box::new(async { +LL | | +LL | | let non_send = null::<()>(); +LL | | &non_send; +LL | | async {}.await +LL | | }) + | |______^ future created by async block is not `Send` + | + = help: within `{async block@$DIR/stalled-coroutine-obligations.rs:9:14: 9:19}`, the trait `Send` is not implemented for `*const ()` +note: future is not `Send` as this value is used across an await + --> $DIR/stalled-coroutine-obligations.rs:13:18 + | +LL | let non_send = null::<()>(); + | -------- has type `*const ()` which is not `Send` +LL | &non_send; +LL | async {}.await + | ^^^^^ await occurs here, with `non_send` maybe used later + = note: required for the cast from `Box<{async block@$DIR/stalled-coroutine-obligations.rs:9:14: 9:19}>` to `Box` + +error: future cannot be sent between threads safely + --> $DIR/stalled-coroutine-obligations.rs:27:32 + | +LL | let _: Box = Box::new(fut); + | ^^^^^^^^^^^^^ future created by async block is not `Send` + | + = help: the trait `Send` is not implemented for `dyn Trait` +note: future is not `Send` as this value is used across an await + --> $DIR/stalled-coroutine-obligations.rs:25:22 + | +LL | let _x = foo(); + | -- has type `Box` which is not `Send` +LL | async {}.await; + | ^^^^^ await occurs here, with `_x` maybe used later + = note: required for the cast from `Box<{async block@$DIR/stalled-coroutine-obligations.rs:23:19: 23:24}>` to `Box` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/traits/next-solver/stalled-coroutine-obligations.rs b/tests/ui/traits/next-solver/stalled-coroutine-obligations.rs new file mode 100644 index 000000000000..7c789af9e4cc --- /dev/null +++ b/tests/ui/traits/next-solver/stalled-coroutine-obligations.rs @@ -0,0 +1,50 @@ +//@ edition: 2024 +//@ compile-flags: -Znext-solver --diagnostic-width=300 + +// Previously we check stalled coroutine obligations after borrowck pass. +// And we wrongly assume that these obligations hold in borrowck which leads to +// silent normalization failures. +// In the next solver, we register opaques types via `NormalizesTo` goals. +// So these failures also cause those opaques types not registered in storage. +// +// Regression test for #151322 and #151323. + +#![feature(type_alias_impl_trait)] +#![feature(negative_impls)] +#![feature(auto_traits)] + +fn stalled_copy_clone() { + type T = impl Copy; + let foo: T = async {}; + //~^ ERROR: the trait bound + + type U = impl Clone; + let bar: U = async {}; + //~^ ERROR: the trait bound +} + +auto trait Valid {} +struct False; +impl !Valid for False {} + +fn stalled_auto_traits() { + type T = impl Valid; + let a = False; + let foo: T = async { a }; + //~^ ERROR: the trait bound `False: Valid` is not satisfied +} + + +trait Trait { + fn stalled_send(&self, b: *mut ()) -> impl Future + Send { + //~^ ERROR: type mismatch resolving + //~| ERROR: type mismatch resolving + async move { + //~^ ERROR: type mismatch resolving + b + } + } +} + + +fn main() {} diff --git a/tests/ui/traits/next-solver/stalled-coroutine-obligations.stderr b/tests/ui/traits/next-solver/stalled-coroutine-obligations.stderr new file mode 100644 index 000000000000..6afa406bf367 --- /dev/null +++ b/tests/ui/traits/next-solver/stalled-coroutine-obligations.stderr @@ -0,0 +1,62 @@ +error[E0277]: the trait bound `{async block@$DIR/stalled-coroutine-obligations.rs:18:18: 18:23}: Copy` is not satisfied + --> $DIR/stalled-coroutine-obligations.rs:18:14 + | +LL | let foo: T = async {}; + | ^ the trait `Copy` is not implemented for `{async block@$DIR/stalled-coroutine-obligations.rs:18:18: 18:23}` + +error[E0277]: the trait bound `{async block@$DIR/stalled-coroutine-obligations.rs:22:18: 22:23}: Clone` is not satisfied + --> $DIR/stalled-coroutine-obligations.rs:22:14 + | +LL | let bar: U = async {}; + | ^ the trait `Clone` is not implemented for `{async block@$DIR/stalled-coroutine-obligations.rs:22:18: 22:23}` + +error[E0277]: the trait bound `False: Valid` is not satisfied in `{async block@$DIR/stalled-coroutine-obligations.rs:33:18: 33:23}` + --> $DIR/stalled-coroutine-obligations.rs:33:14 + | +LL | let foo: T = async { a }; + | ^ ----- within this `{async block@$DIR/stalled-coroutine-obligations.rs:33:18: 33:23}` + | | + | unsatisfied trait bound + | +help: within `{async block@$DIR/stalled-coroutine-obligations.rs:33:18: 33:23}`, the trait `Valid` is not implemented for `False` + --> $DIR/stalled-coroutine-obligations.rs:27:1 + | +LL | struct False; + | ^^^^^^^^^^^^ +note: captured value does not implement `Valid` + --> $DIR/stalled-coroutine-obligations.rs:33:26 + | +LL | let foo: T = async { a }; + | ^ has type `False` which does not implement `Valid` + +error[E0271]: type mismatch resolving `impl Future + Send == {async block@$DIR/stalled-coroutine-obligations.rs:42:9: 42:19}` + --> $DIR/stalled-coroutine-obligations.rs:39:5 + | +LL | fn stalled_send(&self, b: *mut ()) -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `impl Future + Send == {async block@$DIR/stalled-coroutine-obligations.rs:42:9: 42:19}` + --> $DIR/stalled-coroutine-obligations.rs:42:9 + | +LL | / async move { +LL | | +LL | | b +LL | | } + | |_________^ types differ + +error[E0271]: type mismatch resolving `{async block@$DIR/stalled-coroutine-obligations.rs:42:9: 42:19} <: impl Future + Send` + --> $DIR/stalled-coroutine-obligations.rs:39:62 + | +LL | fn stalled_send(&self, b: *mut ()) -> impl Future + Send { + | ______________________________________________________________^ +LL | | +LL | | +LL | | async move { +... | +LL | | } + | |_____^ types differ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. From ed90b3566960797ca7afbeca6c64ff042bf52158 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 9 Feb 2026 15:06:55 +0800 Subject: [PATCH 3433/3801] Add note when inherent impl for a alias type defined outside of the crate --- .../src/coherence/inherent_impls.rs | 17 ++++++++++++++++- compiler/rustc_hir_analysis/src/errors.rs | 18 +++++++++++++++++- tests/ui/error-codes/E0116.stderr | 3 ++- .../insufficient-suggestion-issue-141679.rs | 2 +- ...insufficient-suggestion-issue-141679.stderr | 8 +++++++- .../no-attr-empty-impl.stderr | 12 ++++++++---- .../no-other-unrelated-errors.stderr | 3 ++- .../ui/traits/trait-or-new-type-instead.stderr | 3 ++- 8 files changed, 55 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index edaf33e493c0..588747f46d17 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -110,7 +110,22 @@ impl<'tcx> InherentCollect<'tcx> { Ok(()) } else { let impl_span = self.tcx.def_span(impl_def_id); - Err(self.tcx.dcx().emit_err(errors::InherentTyOutsideNew { span: impl_span })) + let mut err = errors::InherentTyOutsideNew { span: impl_span, note: None }; + + if let hir::TyKind::Path(rustc_hir::QPath::Resolved(_, path)) = + self.tcx.hir_node_by_def_id(impl_def_id).expect_item().expect_impl().self_ty.kind + && let rustc_hir::def::Res::Def(DefKind::TyAlias, def_id) = path.res + { + let ty_name = self.tcx.def_path_str(def_id); + let alias_ty_name = self.tcx.type_of(def_id).skip_binder().to_string(); + err.note = Some(errors::InherentTyOutsideNewAliasNote { + span: self.tcx.def_span(def_id), + ty_name, + alias_ty_name, + }); + } + + Err(self.tcx.dcx().emit_err(err)) } } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 6a23b42ae098..fb79789df76e 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1223,11 +1223,27 @@ pub(crate) struct InherentTyOutsideRelevant { #[derive(Diagnostic)] #[diag("cannot define inherent `impl` for a type outside of the crate where the type is defined", code = E0116)] -#[note("define and implement a trait or new type instead")] +#[help( + "consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it" +)] +#[note( + "for more details about the orphan rules, see " +)] pub(crate) struct InherentTyOutsideNew { #[primary_span] #[label("impl for type defined outside of crate")] pub span: Span, + #[subdiagnostic] + pub note: Option, +} + +#[derive(Subdiagnostic)] +#[note("`{$ty_name}` does not define a new type, only an alias of `{$alias_ty_name}` defined here")] +pub(crate) struct InherentTyOutsideNewAliasNote { + #[primary_span] + pub span: Span, + pub ty_name: String, + pub alias_ty_name: String, } #[derive(Diagnostic)] diff --git a/tests/ui/error-codes/E0116.stderr b/tests/ui/error-codes/E0116.stderr index 1ea5a57f46db..20e3b196226a 100644 --- a/tests/ui/error-codes/E0116.stderr +++ b/tests/ui/error-codes/E0116.stderr @@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl Vec {} | ^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error: aborting due to 1 previous error diff --git a/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs index daf8693b5264..b13b6f418d42 100644 --- a/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs +++ b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs @@ -5,4 +5,4 @@ pub type Function = Rc; impl Function {} //~^ ERROR cannot define inherent `impl` for a type outside of the crate where the type is defined [E0116] -fn main(){} \ No newline at end of file +fn main(){} diff --git a/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr index cbb94ea4d367..a62f7f82ba9d 100644 --- a/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr +++ b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr @@ -4,7 +4,13 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl Function {} | ^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see +note: `Function` does not define a new type, only an alias of `Rc` defined here + --> $DIR/insufficient-suggestion-issue-141679.rs:4:1 + | +LL | pub type Function = Rc; + | ^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr b/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr index f8491697910c..de61c3900d46 100644 --- a/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr +++ b/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr @@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl extern_crate::StructWithAttr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/no-attr-empty-impl.rs:7:1 @@ -12,7 +13,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl extern_crate::StructNoAttr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/no-attr-empty-impl.rs:10:1 @@ -20,7 +22,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl extern_crate::EnumWithAttr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/no-attr-empty-impl.rs:13:1 @@ -28,7 +31,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl extern_crate::EnumNoAttr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error[E0390]: cannot define inherent `impl` for primitive types --> $DIR/no-attr-empty-impl.rs:16:1 diff --git a/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr index 2a33262f8389..f01817e29443 100644 --- a/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr +++ b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr @@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl Vec {} | ^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error: aborting due to 1 previous error diff --git a/tests/ui/traits/trait-or-new-type-instead.stderr b/tests/ui/traits/trait-or-new-type-instead.stderr index 5f5aa3ac5698..ad12a84a4b80 100644 --- a/tests/ui/traits/trait-or-new-type-instead.stderr +++ b/tests/ui/traits/trait-or-new-type-instead.stderr @@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl Option { | ^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error: aborting due to 1 previous error From 2b1dc3144bd38e3f655bcc991b685d824f4176f6 Mon Sep 17 00:00:00 2001 From: "Eddy (Eduard) Stefes" Date: Wed, 14 Jan 2026 13:08:10 +0100 Subject: [PATCH 3434/3801] add a new s390x-unknown-none-softfloat target This target is intended to be used for kernel development. Becasue on s390x float and vector registers overlap we have to disable the vector extension. The default s390x-unknown-gnu-linux target will not allow use of softfloat. Co-authored-by: Jubilee --- compiler/rustc_target/src/spec/mod.rs | 8 ++ .../targets/s390x_unknown_none_softfloat.rs | 39 ++++++++++ compiler/rustc_target/src/target_features.rs | 29 +++++-- src/bootstrap/src/core/sanity.rs | 1 + src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 1 + .../s390x-unknown-none-softfloat.md | 77 +++++++++++++++++++ tests/assembly-llvm/targets/targets-elf.rs | 3 + 8 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs create mode 100644 src/doc/rustc/src/platform-support/s390x-unknown-none-softfloat.md diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 9799f3e50ae2..eabfda35028d 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1007,6 +1007,8 @@ crate::target_spec_enum! { X86Sse2 = "x86-sse2", /// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI. X86Softfloat = "x86-softfloat", + // On S390x only: do not use any FPU or Vector registers for the ABI. + S390xSoftFloat = "s390x-softfloat", } parse_error_type = "rustc abi"; @@ -1460,6 +1462,7 @@ supported_targets! { ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), ("powerpc64le-unknown-linux-musl", powerpc64le_unknown_linux_musl), ("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu), + ("s390x-unknown-none-softfloat", s390x_unknown_none_softfloat), ("s390x-unknown-linux-musl", s390x_unknown_linux_musl), ("sparc-unknown-linux-gnu", sparc_unknown_linux_gnu), ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu), @@ -3209,6 +3212,11 @@ impl Target { Arch::X86 | Arch::X86_64, "`x86-softfloat` ABI is only valid for x86 targets" ), + RustcAbi::S390xSoftFloat => check_matches!( + self.arch, + Arch::S390x, + "`s390x-softfloat` ABI is only valid for s390x targets" + ), } } diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs new file mode 100644 index 000000000000..1453a3d6c9b3 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs @@ -0,0 +1,39 @@ +use rustc_abi::{Align, Endian}; + +use crate::spec::{ + Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet, + StackProbeType, Target, TargetMetadata, TargetOptions, +}; + +pub(crate) fn target() -> Target { + let opts = TargetOptions { + abi: Abi::SoftFloat, + cpu: "z10".into(), + endian: Endian::Big, + features: "+soft-float,-vector".into(), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + linker: Some("rust-lld".into()), + max_atomic_width: Some(128), + min_global_align: Some(Align::from_bits(16).unwrap()), + panic_strategy: PanicStrategy::Abort, + relocation_model: RelocModel::Static, + rustc_abi: Some(RustcAbi::S390xSoftFloat), + stack_probes: StackProbeType::Inline, + supported_sanitizers: SanitizerSet::KERNELADDRESS, + ..Default::default() + }; + + Target { + llvm_target: "s390x-unknown-linux-gnu".into(), + metadata: TargetMetadata { + description: Some("S390x Linux".into()), + host_tools: Some(false), + std: Some(false), + tier: Some(2), + }, + arch: Arch::S390x, + data_layout: "E-S64-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(), + options: opts, + pointer_width: 64, + } +} diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index bc12e1eb9737..671761a4edd4 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -863,7 +863,7 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("miscellaneous-extensions-3", Stable, &[]), ("miscellaneous-extensions-4", Stable, &[]), ("nnp-assist", Stable, &["vector"]), - ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]), + ("soft-float", Forbidden { reason: "unsupported ABI-configuration feature" }, &[]), ("transactional-execution", Unstable(sym::s390x_target_feature), &[]), ("vector", Stable, &[]), ("vector-enhancements-1", Stable, &["vector"]), @@ -1105,6 +1105,7 @@ impl Target { // LLVM handles the rest. FeatureConstraints { required: &["soft-float"], incompatible: &[] } } + Some(r) => panic!("invalid Rust ABI for x86: {r:?}"), } } Arch::X86_64 => { @@ -1218,11 +1219,27 @@ impl Target { } } Arch::S390x => { - // We don't currently support a softfloat target on this architecture. - // As usual, we have to reject swapping the `soft-float` target feature. - // The "vector" target feature does not affect the ABI for floats - // because the vector and float registers overlap. - FeatureConstraints { required: &[], incompatible: &["soft-float"] } + // Same as x86, We use our own ABI indicator here; + // LLVM does not have anything native and will switch ABI based + // on the soft-float target feature. + // Every case should require or forbid `soft-float`! + // The "vector" target feature may only be used without soft-float + // because the float and vector registers overlap and the + // standard s390x C ABI may pass vectors via these registers. + match self.rustc_abi { + None => { + // Default hardfloat ABI. + FeatureConstraints { required: &[], incompatible: &["soft-float"] } + } + Some(RustcAbi::S390xSoftFloat) => { + // Softfloat ABI, requires corresponding target feature. + // llvm will switch to soft-float ABI just based on this feature. + FeatureConstraints { required: &["soft-float"], incompatible: &["vector"] } + } + Some(r) => { + panic!("invalid Rust ABI for s390x: {r:?}"); + } + } } _ => NOTHING, } diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 8b6405afa892..e5327ab79ee2 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -48,6 +48,7 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[ "thumbv6-none-eabi", "aarch64v8r-unknown-none", "aarch64v8r-unknown-none-softfloat", + "s390x-unknown-none-softfloat", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 2ec0c3648bdf..9049828c8b12 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -120,6 +120,7 @@ - [riscv64a23-unknown-linux-gnu](platform-support/riscv64a23-unknown-linux-gnu.md) - [s390x-unknown-linux-gnu](platform-support/s390x-unknown-linux-gnu.md) - [s390x-unknown-linux-musl](platform-support/s390x-unknown-linux-musl.md) + - [s390x-unknown-none-softfloat](platform-support/s390x-unknown-none-softfloat.md) - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md) - [solaris](platform-support/solaris.md) - [\*-nto-qnx-\*](platform-support/nto-qnx.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 114f66282afd..29553f9c2a00 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -188,6 +188,7 @@ target | std | notes [`riscv64im-unknown-none-elf`](platform-support/riscv64im-unknown-none-elf.md) | * | Bare RISC-V (RV64IM ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4+, glibc 2.23) +[`s390x-unknown-none-softfloat`](platform-support/s390x-unknown-none-softfloat.md) | * | Bare S390x (softfloat ABI) [`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M [`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M [`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M, hardfloat diff --git a/src/doc/rustc/src/platform-support/s390x-unknown-none-softfloat.md b/src/doc/rustc/src/platform-support/s390x-unknown-none-softfloat.md new file mode 100644 index 000000000000..39a1a7c52c39 --- /dev/null +++ b/src/doc/rustc/src/platform-support/s390x-unknown-none-softfloat.md @@ -0,0 +1,77 @@ +# `s390x-unknown-none-softfloat` + +**Tier: 2** + +IBM z/Architecture (s390x) code in ELF format for kernels, etc. + +## Target maintainers + +[@uweigand](https://github.com/uweigand) +[@cuviper](https://github.com/cuviper) + +## Requirements + +This target is intended for kernel development on s390x only. This target is +cross-compiled. There is no support for `std`.There is no default allocator, +but it's possible to use `alloc` by supplying an allocator. + +The target does not assume existence of a FPU and does not make use of any +non-GPR register. This allows the generated code to run in environments, such +as kernels, which may need to avoid the use of such registers or which may have +special considerations about the use of such registers (e.g. saving and +restoring them to avoid breaking userspace code using the same registers). You +can change code generation to use additional CPU features via the +`-C target-feature=` codegen options to rustc, or via the `#[target_feature]` +mechanism within Rust code. + +By default, code generated with the soft-float target should run on any Z System +starting at [Z10][s390x-isa]. Enabling additional target features or changing the +`-Ctarget-cpu` may raise the ISA required from the `z10` baseline. + +`extern "C"` does not use a stable ABI and is subject to change between compiler +or codegen backend versions. + +The target only generates object files in the ELF format. Any alternate formats +or special considerations for binary layout will require linker options or linker +scripts. + +* [z/Architecture Principles of Operation][s390x-isa] + +[s390x-isa]: https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf +[s390x-abi]: https://github.com/IBM/s390x-abi + +## Building the target + +You can build Rust with support for the target by adding it to the `target` +list in `bootstrap.toml`: + +```toml +[build] +target = ["s390x-unknown-none-softfloat"] +``` + +## Building Rust programs + +This target is not intended to build stand-alone binaries. You should only use +it in conjunction with the kernel build toolchain. + +## Testing + +As code generated by this target is intended to always be part of the kernel, +there are no additional requirements for testing. + +If you want to do native testing but do not have your own s390x +machine, there are several options how to get access to one: + +* The [IBM LinuxONE Community Cloud][cloud-community] provides a + self-service portal where you can create s390x virtual machine + instances. These are intended for temporary use (limited to 120 days). + +* The [IBM LinuxONE Open Source Cloud][cloud-opensource] provides + permanent access to s390x machines. This requires approval by IBM, + which will normally be granted if you're planning to use the machine + to work on an open-source project that is relevant to the IBM Z + ecosystem - the Rust compiler would certainly qualify. + +[cloud-community]: https://linuxone.cloud.marist.edu/ +[cloud-opensource]: https://community.ibm.com/zsystems/form/l1cc-oss-vm-request/ diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index c38e86315b27..b7deb6686cfe 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -544,6 +544,9 @@ //@ revisions: s390x_unknown_linux_musl //@ [s390x_unknown_linux_musl] compile-flags: --target s390x-unknown-linux-musl //@ [s390x_unknown_linux_musl] needs-llvm-components: systemz +//@ revisions: s390x_unknown_none_softfloat +//@ [s390x_unknown_none_softfloat] compile-flags: --target s390x-unknown-none-softfloat +//@ [s390x_unknown_none_softfloat] needs-llvm-components: systemz //@ revisions: sparc64_unknown_helenos //@ [sparc64_unknown_helenos] compile-flags: --target sparc64-unknown-helenos //@ [sparc64_unknown_helenos] needs-llvm-components: sparc From 51affa03942074a84ccce448ea6b7b9e02a4f4a6 Mon Sep 17 00:00:00 2001 From: "Eddy (Eduard) Stefes" Date: Thu, 22 Jan 2026 13:50:54 +0100 Subject: [PATCH 3435/3801] add tests for s390x-unknown-none-softfloat tests will check: - correct emit of assembly for softfloat target - incompatible set features will emit warnings/errors - incompatible target tripples in crates will not link --- tests/assembly-llvm/s390x-softfloat-abi.rs | 64 +++++++++++++++++++ ...0x-softfloat-gate.disable-softfloat.stderr | 12 ++++ ...90x-softfloat-gate.enable-softfloat.stderr | 7 ++ tests/ui/abi/s390x-softfloat-gate.rs | 38 +++++++++++ ...imd-abi-checks-s390x.z13_soft_float.stderr | 2 +- .../auxiliary/disabled_softfloat.rs | 8 +++ .../auxiliary/enabled_softfloat.rs | 8 +++ ...softfloat_targets.disable-softfloat.stderr | 12 ++++ ..._softfloat_targets.enable-softfloat.stderr | 12 ++++ .../incompatible_softfloat_targets.rs | 20 ++++++ 10 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 tests/assembly-llvm/s390x-softfloat-abi.rs create mode 100644 tests/ui/abi/s390x-softfloat-gate.disable-softfloat.stderr create mode 100644 tests/ui/abi/s390x-softfloat-gate.enable-softfloat.stderr create mode 100644 tests/ui/abi/s390x-softfloat-gate.rs create mode 100644 tests/ui/target_modifiers/auxiliary/disabled_softfloat.rs create mode 100644 tests/ui/target_modifiers/auxiliary/enabled_softfloat.rs create mode 100644 tests/ui/target_modifiers/incompatible_softfloat_targets.disable-softfloat.stderr create mode 100644 tests/ui/target_modifiers/incompatible_softfloat_targets.enable-softfloat.stderr create mode 100644 tests/ui/target_modifiers/incompatible_softfloat_targets.rs diff --git a/tests/assembly-llvm/s390x-softfloat-abi.rs b/tests/assembly-llvm/s390x-softfloat-abi.rs new file mode 100644 index 000000000000..e2d9d013d201 --- /dev/null +++ b/tests/assembly-llvm/s390x-softfloat-abi.rs @@ -0,0 +1,64 @@ +//@ add-minicore +//@ revisions: enable-softfloat disable-softfloat +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 --crate-type=lib +//@[enable-softfloat] compile-flags: --target=s390x-unknown-none-softfloat +//@[enable-softfloat] needs-llvm-components: systemz +//@[disable-softfloat] compile-flags: --target=s390x-unknown-linux-gnu +//@[disable-softfloat] needs-llvm-components: systemz +//@ ignore-backends: gcc + +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +extern "C" { + fn extern_func(value: f64) -> f64; +} + +// CHECK-LABEL: test_softfloat +#[no_mangle] +extern "C" fn test_softfloat() -> f64 { + let value = 3.141_f64; + + // without softfloat we load the value direct to the first float register + // we do NOT construct a softfloat in r2 (first non-float arg register) + // disable-softfloat: ld %f{{.*}}, 0(%r{{.*}}) + // disable-softfloat-NOT: llihf %r{{.*}}, 1074340036 + // disable-softfloat-NOT: oilf %r{{.*}}, 2611340116 + + // with softfloat we construct the softfloat arg in r2 + // we do NOT pass anything by f0 (first float arg register) + // float registers can not be accessed + // enable-softfloat: llihf %r{{.*}}, 1074340036 + // enable-softfloat-NEXT: oilf %r{{.*}}, 2611340116 + // enable-softfloat-NOT: ld %f{{.*}}, 0(%r{{.*}}) + + unsafe { extern_func(value) }; + // disable-softfloat-NEXT: brasl %r{{.*}}, extern_func@PLT + // enable-softfloat-NEXT: brasl %r{{.*}}, extern_func@PLT + + // for return we check that without softfloat we write to float register + // disable-softfloat: ld %f{{.*}}, 0(%r{{.*}}) + // disable-softfloat-NOT: llihf %r{{.*}}, 1072841097 + // disable-softfloat-NOT: oilf %r{{.*}}, 927712936 + + #[cfg(not(target_feature = "soft-float"))] + { + 1.141_f64 + } + + // for return we check that WITH softfloat we write to genral purpose register + // enable-softfloat: llihf %r{{.*}}, 1072841097 + // enable-softfloat-NEXT: oilf %r{{.*}}, 927712936 + // enable-softfloat-NOT: ld %f{{.*}}, 0(%r{{.*}}) + #[cfg(target_feature = "soft-float")] + { + 2.718_f64 + } + // enable-softfloat: br %r{{.*}} + // disable-softfloat: br %r{{.*}} +} diff --git a/tests/ui/abi/s390x-softfloat-gate.disable-softfloat.stderr b/tests/ui/abi/s390x-softfloat-gate.disable-softfloat.stderr new file mode 100644 index 000000000000..e82d5b744a26 --- /dev/null +++ b/tests/ui/abi/s390x-softfloat-gate.disable-softfloat.stderr @@ -0,0 +1,12 @@ +warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: unsupported ABI-configuration feature + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: 2 warnings emitted + diff --git a/tests/ui/abi/s390x-softfloat-gate.enable-softfloat.stderr b/tests/ui/abi/s390x-softfloat-gate.enable-softfloat.stderr new file mode 100644 index 000000000000..ecc96e448dcf --- /dev/null +++ b/tests/ui/abi/s390x-softfloat-gate.enable-softfloat.stderr @@ -0,0 +1,7 @@ +warning: target feature `vector` must be disabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: 1 warning emitted + diff --git a/tests/ui/abi/s390x-softfloat-gate.rs b/tests/ui/abi/s390x-softfloat-gate.rs new file mode 100644 index 000000000000..496929eb0955 --- /dev/null +++ b/tests/ui/abi/s390x-softfloat-gate.rs @@ -0,0 +1,38 @@ +//@ add-minicore +//@ revisions: disable-softfloat enable-softfloat +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 --crate-type=lib + +// we expect the build to fail in the feature +//@ build-pass +//@ [enable-softfloat] compile-flags: --target=s390x-unknown-none-softfloat +//@ [enable-softfloat] compile-flags: -C target-feature=+vector +//@ [enable-softfloat] needs-llvm-components: systemz +//@ [disable-softfloat] compile-flags: --target=s390x-unknown-linux-gnu +//@ [disable-softfloat] compile-flags: -C target-feature=+soft-float +//@ [disable-softfloat] needs-llvm-components: systemz +//@ ignore-backends: gcc + +//[disable-softfloat]~? WARN target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctly +//[disable-softfloat]~? WARN target feature `soft-float` cannot be enabled with `-Ctarget-feature` +//[enable-softfloat]~? WARN target feature `vector` must be disabled to ensure that the ABI of the current target can be implemented correctly + +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +extern "C" { + fn extern_func(value: f64) -> f64; +} + +#[no_mangle] +extern "C" fn test_softfloat() -> f64 { + let value = 3.141_f64; + + unsafe { extern_func(value) } ; + + 2.718_f64 +} diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr index 0e8e6637507d..cda51a211324 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr @@ -1,4 +1,4 @@ -warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: currently unsupported ABI-configuration feature +warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: unsupported ABI-configuration feature | = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116344 diff --git a/tests/ui/target_modifiers/auxiliary/disabled_softfloat.rs b/tests/ui/target_modifiers/auxiliary/disabled_softfloat.rs new file mode 100644 index 000000000000..0063d925deca --- /dev/null +++ b/tests/ui/target_modifiers/auxiliary/disabled_softfloat.rs @@ -0,0 +1,8 @@ +//@ add-minicore +//@ no-prefer-dynamic +//@ compile-flags: --target=s390x-unknown-linux-gnu +//@ needs-llvm-components: systemz + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/ui/target_modifiers/auxiliary/enabled_softfloat.rs b/tests/ui/target_modifiers/auxiliary/enabled_softfloat.rs new file mode 100644 index 000000000000..7439a1eb69b5 --- /dev/null +++ b/tests/ui/target_modifiers/auxiliary/enabled_softfloat.rs @@ -0,0 +1,8 @@ +//@ add-minicore +//@ no-prefer-dynamic +//@ compile-flags: --target=s390x-unknown-none-softfloat +//@ needs-llvm-components: systemz + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/ui/target_modifiers/incompatible_softfloat_targets.disable-softfloat.stderr b/tests/ui/target_modifiers/incompatible_softfloat_targets.disable-softfloat.stderr new file mode 100644 index 000000000000..090ebe6ca14c --- /dev/null +++ b/tests/ui/target_modifiers/incompatible_softfloat_targets.disable-softfloat.stderr @@ -0,0 +1,12 @@ +error[E0461]: couldn't find crate `enabled_softfloat` with expected target triple s390x-unknown-linux-gnu + --> $DIR/incompatible_softfloat_targets.rs:17:1 + | +LL | extern crate enabled_softfloat; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the following crate versions were found: + crate `enabled_softfloat`, target triple s390x-unknown-none-softfloat: $TEST_BUILD_DIR/auxiliary/libenabled_softfloat.rlib + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0461`. diff --git a/tests/ui/target_modifiers/incompatible_softfloat_targets.enable-softfloat.stderr b/tests/ui/target_modifiers/incompatible_softfloat_targets.enable-softfloat.stderr new file mode 100644 index 000000000000..9adb6d265651 --- /dev/null +++ b/tests/ui/target_modifiers/incompatible_softfloat_targets.enable-softfloat.stderr @@ -0,0 +1,12 @@ +error[E0461]: couldn't find crate `disabled_softfloat` with expected target triple s390x-unknown-none-softfloat + --> $DIR/incompatible_softfloat_targets.rs:19:1 + | +LL | extern crate disabled_softfloat; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the following crate versions were found: + crate `disabled_softfloat`, target triple s390x-unknown-linux-gnu: $TEST_BUILD_DIR/auxiliary/libdisabled_softfloat.rlib + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0461`. diff --git a/tests/ui/target_modifiers/incompatible_softfloat_targets.rs b/tests/ui/target_modifiers/incompatible_softfloat_targets.rs new file mode 100644 index 000000000000..3d253c5f0c78 --- /dev/null +++ b/tests/ui/target_modifiers/incompatible_softfloat_targets.rs @@ -0,0 +1,20 @@ +//@ add-minicore +//@ aux-build: disabled_softfloat.rs +//@ aux-build: enabled_softfloat.rs +//@ revisions: disable-softfloat enable-softfloat +//@ check-fail +//@ [enable-softfloat] compile-flags: --target=s390x-unknown-none-softfloat +//@ [enable-softfloat] needs-llvm-components: systemz +//@ [disable-softfloat] compile-flags: --target=s390x-unknown-linux-gnu +//@ [disable-softfloat] needs-llvm-components: systemz +//@ ignore-backends: gcc + + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] + +extern crate enabled_softfloat; +//[disable-softfloat]~^ ERROR couldn't find crate `enabled_softfloat` with expected target triple s390x-unknown-linux-gnu +extern crate disabled_softfloat; +//[enable-softfloat]~^ ERROR couldn't find crate `disabled_softfloat` with expected target triple s390x-unknown-none-softfloat From 7c3d096b0dcb39ad23b42394d889ec8177f7ce26 Mon Sep 17 00:00:00 2001 From: "Eddy (Eduard) Stefes" Date: Fri, 6 Feb 2026 10:53:59 +0100 Subject: [PATCH 3436/3801] allow for variant aliases in target_spec_enum! --- compiler/rustc_target/src/lib.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index dfa1b2320718..1dc62cb3659c 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -76,7 +76,7 @@ macro_rules! target_spec_enum { pub enum $Name:ident { $( $( #[$variant_attr:meta] )* - $Variant:ident = $string:literal, + $Variant:ident = $string:literal $(,$alias:literal)* , )* } parse_error_type = $parse_error_type:literal; @@ -88,6 +88,7 @@ macro_rules! target_spec_enum { $( $( #[$variant_attr] )* #[serde(rename = $string)] // for JSON schema generation only + $( #[serde(alias = $alias)] )* $Variant, )* } @@ -97,7 +98,10 @@ macro_rules! target_spec_enum { fn from_str(s: &str) -> Result { Ok(match s { - $( $string => Self::$Variant, )* + $( + $string => Self::$Variant, + $($alias => Self::$Variant,)* + )* _ => { let all = [$( concat!("'", $string, "'") ),*].join(", "); return Err(format!("invalid {}: '{s}'. allowed values: {all}", $parse_error_type)); @@ -123,7 +127,7 @@ macro_rules! target_spec_enum { pub enum $Name:ident { $( $( #[$variant_attr:meta] )* - $Variant:ident = $string:literal, + $Variant:ident = $string:literal $(,$alias:literal)* , )* } $( #[$other_variant_attr:meta] )* @@ -134,6 +138,7 @@ macro_rules! target_spec_enum { pub enum $Name { $( $( #[$variant_attr:meta] )* + $( #[serde(alias = $alias)] )* $Variant, )* /// The vast majority of the time, the compiler deals with a fixed @@ -165,7 +170,10 @@ macro_rules! target_spec_enum { fn from_str(s: &str) -> Result { Ok(match s { - $( $string => Self::$Variant, )* + $( + $string => Self::$Variant, + $($alias => Self::$Variant,)* + )* _ => Self::$OtherVariant(s.to_owned().into()), }) } From 83dba5b430160bee94e5cc9514993fea4bfa0d96 Mon Sep 17 00:00:00 2001 From: "Eddy (Eduard) Stefes" Date: Thu, 22 Jan 2026 13:20:52 +0100 Subject: [PATCH 3437/3801] renamed RustcAbi::X86Softfloat to Softfloat an made an alias to the old string --- compiler/rustc_target/src/callconv/x86_win64.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 17 +++++------------ .../src/spec/targets/i686_unknown_uefi.rs | 2 +- .../targets/s390x_unknown_none_softfloat.rs | 2 +- .../src/spec/targets/x86_64_unknown_none.rs | 2 +- .../src/spec/targets/x86_64_unknown_uefi.rs | 2 +- compiler/rustc_target/src/target_features.rs | 7 +++---- 7 files changed, 13 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs index 48f7700a86d5..4026c4f471a7 100644 --- a/compiler/rustc_target/src/callconv/x86_win64.rs +++ b/compiler/rustc_target/src/callconv/x86_win64.rs @@ -28,7 +28,7 @@ where BackendRepr::ScalableVector { .. } => panic!("scalable vectors are unsupported"), BackendRepr::Scalar(scalar) => { if is_ret && matches!(scalar.primitive(), Primitive::Int(Integer::I128, _)) { - if cx.target_spec().rustc_abi == Some(RustcAbi::X86Softfloat) { + if cx.target_spec().rustc_abi == Some(RustcAbi::Softfloat) { // Use the native `i128` LLVM type for the softfloat ABI -- in other words, adjust nothing. } else { // `i128` is returned in xmm0 by Clang and GCC diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index eabfda35028d..537185f536ab 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1005,10 +1005,8 @@ crate::target_spec_enum! { pub enum RustcAbi { /// On x86-32 only: make use of SSE and SSE2 for ABI purposes. X86Sse2 = "x86-sse2", - /// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI. - X86Softfloat = "x86-softfloat", - // On S390x only: do not use any FPU or Vector registers for the ABI. - S390xSoftFloat = "s390x-softfloat", + /// On x86-32/64 and S390x: do not use any FPU or SIMD registers for the ABI. + Softfloat = "softfloat", "x86-softfloat", } parse_error_type = "rustc abi"; @@ -3207,15 +3205,10 @@ impl Target { Arch::X86, "`x86-sse2` ABI is only valid for x86-32 targets" ), - RustcAbi::X86Softfloat => check_matches!( + RustcAbi::Softfloat => check_matches!( self.arch, - Arch::X86 | Arch::X86_64, - "`x86-softfloat` ABI is only valid for x86 targets" - ), - RustcAbi::S390xSoftFloat => check_matches!( - self.arch, - Arch::S390x, - "`s390x-softfloat` ABI is only valid for s390x targets" + Arch::X86 | Arch::X86_64 | Arch::S390x, + "`softfloat` ABI is only valid for x86 and s390x targets" ), } } diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs index 37b202097b46..7696edd5ba71 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { // If you initialize FP units yourself, you can override these flags with custom linker // arguments, thus giving you access to full MMX/SSE acceleration. base.features = "-mmx,-sse,+soft-float".into(); - base.rustc_abi = Some(RustcAbi::X86Softfloat); + base.rustc_abi = Some(RustcAbi::Softfloat); // Turn off DWARF. This fixes an lld warning, "section name .debug_frame is longer than 8 // characters and will use a non-standard string table". That section will not be created if diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs index 1453a3d6c9b3..7d42c1fd9244 100644 --- a/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { min_global_align: Some(Align::from_bits(16).unwrap()), panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, - rustc_abi: Some(RustcAbi::S390xSoftFloat), + rustc_abi: Some(RustcAbi::Softfloat), stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::KERNELADDRESS, ..Default::default() diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs index 520a59d6a6f6..0afe7a0b68b0 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { relro_level: RelroLevel::Full, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), - rustc_abi: Some(RustcAbi::X86Softfloat), + rustc_abi: Some(RustcAbi::Softfloat), features: "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float".into(), supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS, disable_redzone: true, diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs index 8a494d0e56dd..333e20bd0ac1 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs @@ -27,7 +27,7 @@ pub(crate) fn target() -> Target { // If you initialize FP units yourself, you can override these flags with custom linker // arguments, thus giving you access to full MMX/SSE acceleration. base.features = "-mmx,-sse,+soft-float".into(); - base.rustc_abi = Some(RustcAbi::X86Softfloat); + base.rustc_abi = Some(RustcAbi::Softfloat); Target { llvm_target: "x86_64-unknown-windows".into(), diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 671761a4edd4..dfa2b839a4c0 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -1098,14 +1098,13 @@ impl Target { incompatible: &["soft-float"], } } - Some(RustcAbi::X86Softfloat) => { + Some(RustcAbi::Softfloat) => { // Softfloat ABI, requires corresponding target feature. That feature trumps // `x87` and all other FPU features so those do not matter. // Note that this one requirement is the entire implementation of the ABI! // LLVM handles the rest. FeatureConstraints { required: &["soft-float"], incompatible: &[] } } - Some(r) => panic!("invalid Rust ABI for x86: {r:?}"), } } Arch::X86_64 => { @@ -1119,7 +1118,7 @@ impl Target { incompatible: &["soft-float"], } } - Some(RustcAbi::X86Softfloat) => { + Some(RustcAbi::Softfloat) => { // Softfloat ABI, requires corresponding target feature. That feature trumps // `x87` and all other FPU features so those do not matter. // Note that this one requirement is the entire implementation of the ABI! @@ -1231,7 +1230,7 @@ impl Target { // Default hardfloat ABI. FeatureConstraints { required: &[], incompatible: &["soft-float"] } } - Some(RustcAbi::S390xSoftFloat) => { + Some(RustcAbi::Softfloat) => { // Softfloat ABI, requires corresponding target feature. // llvm will switch to soft-float ABI just based on this feature. FeatureConstraints { required: &["soft-float"], incompatible: &["vector"] } From f91c8083d8a90d6a275584389e853cccb0b45b08 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 9 Feb 2026 11:01:03 +1100 Subject: [PATCH 3438/3801] Adjust `make_dep_kind_vtable_for_query`. It takes an `is_anon` argument, but it's now generic over `QueryFlags`, which contains the same `is_anon` field. So the argument is no longer necessary. --- compiler/rustc_query_impl/src/plumbing.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index bbda716eadb0..aefd4418e192 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -512,12 +512,12 @@ pub(crate) fn make_dep_kind_vtable_for_query< C: QueryCache + 'tcx, const FLAGS: QueryFlags, >( - is_anon: bool, is_eval_always: bool, ) -> DepKindVTable<'tcx> where Q: QueryDispatcherUnerased<'tcx, C, FLAGS>, { + let is_anon = FLAGS.is_anon; let fingerprint_style = if is_anon { FingerprintStyle::Opaque } else { @@ -969,7 +969,6 @@ macro_rules! define_queries { $(pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> { use $crate::query_impl::$name::QueryType; $crate::plumbing::make_dep_kind_vtable_for_query::, _, _>( - is_anon!([$($modifiers)*]), is_eval_always!([$($modifiers)*]), ) })* From 541d7fc19d14c64a1490c065a73986f9e018b3d6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 9 Feb 2026 13:02:06 +1100 Subject: [PATCH 3439/3801] Remove `trait QueryDispatcher`. It existed only to bridge the divide between `rustc_query_system` and `rustc_query_impl`. But enough pieces have been moved from the former to the latter that the trait is no longer needed. Less indirection and abstraction makes the code easier to understand. --- compiler/rustc_query_impl/src/execution.rs | 157 +++++++----------- compiler/rustc_query_impl/src/lib.rs | 55 +++--- compiler/rustc_query_impl/src/plumbing.rs | 30 ++-- .../rustc_query_system/src/query/caches.rs | 3 + .../src/query/dispatcher.rs | 87 ---------- compiler/rustc_query_system/src/query/mod.rs | 2 +- 6 files changed, 111 insertions(+), 223 deletions(-) diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index e58e626a7dfa..ba442d8a0081 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -9,14 +9,14 @@ use rustc_middle::dep_graph::DepsType; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::{DepGraphData, DepNodeKey, HasDepContext}; use rustc_query_system::query::{ - ActiveKeyStatus, CycleError, CycleErrorHandling, QueryCache, QueryContext, QueryDispatcher, - QueryJob, QueryJobId, QueryJobInfo, QueryLatch, QueryMap, QueryMode, QueryStackDeferred, - QueryStackFrame, QueryState, incremental_verify_ich, report_cycle, + ActiveKeyStatus, CycleError, CycleErrorHandling, QueryCache, QueryContext, QueryJob, + QueryJobId, QueryJobInfo, QueryLatch, QueryMap, QueryMode, QueryStackDeferred, QueryStackFrame, + QueryState, incremental_verify_ich, report_cycle, }; use rustc_span::{DUMMY_SP, Span}; use crate::dep_graph::{DepContext, DepNode, DepNodeIndex}; -use crate::plumbing::QueryCtxt; +use crate::{QueryCtxt, QueryFlags, SemiDynamicQueryDispatcher}; #[inline] fn equivalent_key(k: &K) -> impl Fn(&(K, V)) -> bool + '_ { @@ -95,23 +95,21 @@ where #[cold] #[inline(never)] -fn mk_cycle<'tcx, Q>(query: Q, qcx: QueryCtxt<'tcx>, cycle_error: CycleError) -> Q::Value -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +fn mk_cycle<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, + qcx: QueryCtxt<'tcx>, + cycle_error: CycleError, +) -> C::Value { let error = report_cycle(qcx.tcx.sess, &cycle_error); handle_cycle_error(query, qcx, &cycle_error, error) } -fn handle_cycle_error<'tcx, Q>( - query: Q, +fn handle_cycle_error<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, cycle_error: &CycleError, error: Diag<'_>, -) -> Q::Value -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> C::Value { match query.cycle_error_handling() { CycleErrorHandling::Error => { let guar = error.emit(); @@ -205,15 +203,12 @@ where #[cold] #[inline(never)] -fn cycle_error<'tcx, Q>( - query: Q, +fn cycle_error<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, try_execute: QueryJobId, span: Span, -) -> (Q::Value, Option) -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> (C::Value, Option) { // Ensure there was no errors collecting all active jobs. // We need the complete map to ensure we find a cycle to break. let query_map = qcx @@ -226,17 +221,14 @@ where } #[inline(always)] -fn wait_for_query<'tcx, Q>( - query: Q, +fn wait_for_query<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, span: Span, - key: Q::Key, + key: C::Key, latch: QueryLatch<'tcx>, current: Option, -) -> (Q::Value, Option) -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> (C::Value, Option) { // For parallel queries, we'll block and wait until the query running // in another thread has completed. Record how long we wait in the // self-profiler. @@ -275,16 +267,13 @@ where } #[inline(never)] -fn try_execute_query<'tcx, Q, const INCR: bool>( - query: Q, +fn try_execute_query<'tcx, C: QueryCache, const FLAGS: QueryFlags, const INCR: bool>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, span: Span, - key: Q::Key, + key: C::Key, dep_node: Option, -) -> (Q::Value, Option) -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> (C::Value, Option) { let state = query.query_state(qcx); let key_hash = sharded::make_hash(&key); let mut state_lock = state.active.lock_shard_by_hash(key_hash); @@ -315,7 +304,7 @@ where // Drop the lock before we start executing the query drop(state_lock); - execute_job::(query, qcx, state, key, key_hash, id, dep_node) + execute_job::(query, qcx, state, key, key_hash, id, dep_node) } Entry::Occupied(mut entry) => { match &mut entry.get_mut().1 { @@ -344,18 +333,15 @@ where } #[inline(always)] -fn execute_job<'tcx, Q, const INCR: bool>( - query: Q, +fn execute_job<'tcx, C: QueryCache, const FLAGS: QueryFlags, const INCR: bool>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, - state: &'tcx QueryState<'tcx, Q::Key>, - key: Q::Key, + state: &'tcx QueryState<'tcx, C::Key>, + key: C::Key, key_hash: u64, id: QueryJobId, dep_node: Option, -) -> (Q::Value, Option) -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> (C::Value, Option) { // Use `JobOwner` so the query will be poisoned if executing it panics. let job_owner = JobOwner { state, key }; @@ -409,15 +395,12 @@ where // Fast path for when incr. comp. is off. #[inline(always)] -fn execute_job_non_incr<'tcx, Q>( - query: Q, +fn execute_job_non_incr<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, - key: Q::Key, + key: C::Key, job_id: QueryJobId, -) -> (Q::Value, DepNodeIndex) -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> (C::Value, DepNodeIndex) { debug_assert!(!qcx.tcx.dep_graph.is_fully_enabled()); // Fingerprint the key, just to assert that it doesn't @@ -445,17 +428,14 @@ where } #[inline(always)] -fn execute_job_incr<'tcx, Q>( - query: Q, +fn execute_job_incr<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, dep_graph_data: &DepGraphData, - key: Q::Key, + key: C::Key, mut dep_node_opt: Option, job_id: QueryJobId, -) -> (Q::Value, DepNodeIndex) -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> (C::Value, DepNodeIndex) { if !query.anon() && !query.eval_always() { // `to_dep_node` is expensive for some `DepKind`s. let dep_node = dep_node_opt.get_or_insert_with(|| query.construct_dep_node(qcx.tcx, &key)); @@ -495,16 +475,13 @@ where } #[inline(always)] -fn try_load_from_disk_and_cache_in_memory<'tcx, Q>( - query: Q, +fn try_load_from_disk_and_cache_in_memory<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, dep_graph_data: &DepGraphData, qcx: QueryCtxt<'tcx>, - key: &Q::Key, + key: &C::Key, dep_node: &DepNode, -) -> Option<(Q::Value, DepNodeIndex)> -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> Option<(C::Value, DepNodeIndex)> { // Note this function can be called concurrently from the same query // We must ensure that this is handled correctly. @@ -598,15 +575,12 @@ where /// /// Note: The optimization is only available during incr. comp. #[inline(never)] -fn ensure_must_run<'tcx, Q>( - query: Q, +fn ensure_must_run<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, - key: &Q::Key, + key: &C::Key, check_cache: bool, -) -> (bool, Option) -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> (bool, Option) { if query.eval_always() { return (true, None); } @@ -644,31 +618,25 @@ where } #[inline(always)] -pub(super) fn get_query_non_incr<'tcx, Q>( - query: Q, +pub(super) fn get_query_non_incr<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, span: Span, - key: Q::Key, -) -> Q::Value -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ + key: C::Key, +) -> C::Value { debug_assert!(!qcx.tcx.dep_graph.is_fully_enabled()); - ensure_sufficient_stack(|| try_execute_query::(query, qcx, span, key, None).0) + ensure_sufficient_stack(|| try_execute_query::(query, qcx, span, key, None).0) } #[inline(always)] -pub(super) fn get_query_incr<'tcx, Q>( - query: Q, +pub(super) fn get_query_incr<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, span: Span, - key: Q::Key, + key: C::Key, mode: QueryMode, -) -> Option -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +) -> Option { debug_assert!(qcx.tcx.dep_graph.is_fully_enabled()); let dep_node = if let QueryMode::Ensure { check_cache } = mode { @@ -681,18 +649,21 @@ where None }; - let (result, dep_node_index) = - ensure_sufficient_stack(|| try_execute_query::(query, qcx, span, key, dep_node)); + let (result, dep_node_index) = ensure_sufficient_stack(|| { + try_execute_query::(query, qcx, span, key, dep_node) + }); if let Some(dep_node_index) = dep_node_index { qcx.tcx.dep_graph.read_index(dep_node_index) } Some(result) } -pub(super) fn force_query<'tcx, Q>(query: Q, qcx: QueryCtxt<'tcx>, key: Q::Key, dep_node: DepNode) -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +pub(crate) fn force_query<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, + qcx: QueryCtxt<'tcx>, + key: C::Key, + dep_node: DepNode, +) { // We may be concurrently trying both execute and force a query. // Ensure that only one of them runs the query. if let Some((_, index)) = query.query_cache(qcx).lookup(&key) { @@ -703,6 +674,6 @@ where debug_assert!(!query.anon()); ensure_sufficient_stack(|| { - try_execute_query::(query, qcx, DUMMY_SP, key, Some(dep_node)) + try_execute_query::(query, qcx, DUMMY_SP, key, Some(dep_node)) }); } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 327a8f4bc6c4..7ca4a1300fe6 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -12,7 +12,7 @@ use std::marker::ConstParamTy; use rustc_data_structures::sync::AtomicU64; use rustc_middle::arena::Arena; -use rustc_middle::dep_graph::{self, DepKind, DepKindVTable, DepNodeIndex}; +use rustc_middle::dep_graph::{self, DepKind, DepKindVTable, DepNode, DepNodeIndex}; use rustc_middle::queries::{ self, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, }; @@ -23,8 +23,7 @@ use rustc_middle::query::values::Value; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::query::{ - CycleError, CycleErrorHandling, HashResult, QueryCache, QueryDispatcher, QueryMap, QueryMode, - QueryState, + CycleError, CycleErrorHandling, HashResult, QueryCache, QueryMap, QueryMode, QueryState, }; use rustc_span::{ErrorGuaranteed, Span}; @@ -50,8 +49,8 @@ struct QueryFlags { is_feedable: bool, } -/// Combines a [`QueryVTable`] with some additional compile-time booleans -/// to implement [`QueryDispatcher`], for use by code in [`rustc_query_system`]. +/// Combines a [`QueryVTable`] with some additional compile-time booleans. +/// "Dispatcher" should be understood as a near-synonym of "vtable". /// /// Baking these boolean flags into the type gives a modest but measurable /// improvement to compiler perf and compiler code size; see @@ -73,54 +72,49 @@ impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> Clone } } -// This is `impl QueryDispatcher for SemiDynamicQueryDispatcher`. -impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> QueryDispatcher<'tcx> - for SemiDynamicQueryDispatcher<'tcx, C, FLAGS> -{ - type Qcx = QueryCtxt<'tcx>; - type Key = C::Key; - type Value = C::Value; - type Cache = C; - +impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> SemiDynamicQueryDispatcher<'tcx, C, FLAGS> { #[inline(always)] fn name(self) -> &'static str { self.vtable.name } #[inline(always)] - fn will_cache_on_disk_for_key(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool { + fn will_cache_on_disk_for_key(self, tcx: TyCtxt<'tcx>, key: &C::Key) -> bool { self.vtable.will_cache_on_disk_for_key_fn.map_or(false, |f| f(tcx, key)) } + // Don't use this method to access query results, instead use the methods on TyCtxt. #[inline(always)] - fn query_state(self, qcx: QueryCtxt<'tcx>) -> &'tcx QueryState<'tcx, Self::Key> { + fn query_state(self, qcx: QueryCtxt<'tcx>) -> &'tcx QueryState<'tcx, C::Key> { // Safety: // This is just manually doing the subfield referencing through pointer math. unsafe { &*(&qcx.tcx.query_system.states as *const QueryStates<'tcx>) .byte_add(self.vtable.query_state) - .cast::>() + .cast::>() } } + // Don't use this method to access query results, instead use the methods on TyCtxt. #[inline(always)] - fn query_cache(self, qcx: QueryCtxt<'tcx>) -> &'tcx Self::Cache { + fn query_cache(self, qcx: QueryCtxt<'tcx>) -> &'tcx C { // Safety: // This is just manually doing the subfield referencing through pointer math. unsafe { &*(&qcx.tcx.query_system.caches as *const QueryCaches<'tcx>) .byte_add(self.vtable.query_cache) - .cast::() + .cast::() } } + // Don't use this method to compute query results, instead use the methods on TyCtxt. #[inline(always)] - fn execute_query(self, tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { + fn execute_query(self, tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value { (self.vtable.execute_query)(tcx, key) } #[inline(always)] - fn compute(self, qcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value { + fn compute(self, qcx: QueryCtxt<'tcx>, key: C::Key) -> C::Value { (self.vtable.compute_fn)(qcx.tcx, key) } @@ -128,10 +122,10 @@ impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> QueryDispatcher<'tcx> fn try_load_from_disk( self, qcx: QueryCtxt<'tcx>, - key: &Self::Key, + key: &C::Key, prev_index: SerializedDepNodeIndex, index: DepNodeIndex, - ) -> Option { + ) -> Option { // `?` will return None immediately for queries that never cache to disk. self.vtable.try_load_from_disk_fn?(qcx.tcx, key, prev_index, index) } @@ -140,23 +134,24 @@ impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> QueryDispatcher<'tcx> fn is_loadable_from_disk( self, qcx: QueryCtxt<'tcx>, - key: &Self::Key, + key: &C::Key, index: SerializedDepNodeIndex, ) -> bool { self.vtable.is_loadable_from_disk_fn.map_or(false, |f| f(qcx.tcx, key, index)) } + /// Synthesize an error value to let compilation continue after a cycle. fn value_from_cycle_error( self, tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed, - ) -> Self::Value { + ) -> C::Value { (self.vtable.value_from_cycle_error)(tcx, cycle_error, guar) } #[inline(always)] - fn format_value(self) -> fn(&Self::Value) -> String { + fn format_value(self) -> fn(&C::Value) -> String { self.vtable.format_value } @@ -191,13 +186,17 @@ impl<'tcx, C: QueryCache, const FLAGS: QueryFlags> QueryDispatcher<'tcx> } #[inline(always)] - fn hash_result(self) -> HashResult { + fn hash_result(self) -> HashResult { self.vtable.hash_result } + + fn construct_dep_node(self, tcx: TyCtxt<'tcx>, key: &C::Key) -> DepNode { + DepNode::construct(tcx, self.dep_kind(), key) + } } /// Provides access to vtable-like operations for a query -/// (by creating a [`QueryDispatcher`]), +/// (by creating a [`SemiDynamicQueryDispatcher`]), /// but also keeps track of the "unerased" value type of the query /// (i.e. the actual result type in the query declaration). /// diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index aefd4418e192..776d720f500b 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -28,8 +28,8 @@ use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle, HasDepContext}; use rustc_query_system::query::{ - QueryCache, QueryContext, QueryDispatcher, QueryJobId, QueryMap, QuerySideEffect, - QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, + QueryCache, QueryContext, QueryJobId, QueryMap, QuerySideEffect, QueryStackDeferred, + QueryStackFrame, QueryStackFrameExtra, }; use rustc_serialize::{Decodable, Encodable}; use rustc_span::def_id::LOCAL_CRATE; @@ -404,8 +404,8 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q, C: QueryCache, const FLAGS: Quer }); } -pub(crate) fn query_key_hash_verify<'tcx>( - query: impl QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, +pub(crate) fn query_key_hash_verify<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, qcx: QueryCtxt<'tcx>, ) { let _timer = qcx.tcx.prof.generic_activity_with_arg("query_key_hash_verify_for", query.name()); @@ -430,13 +430,14 @@ pub(crate) fn query_key_hash_verify<'tcx>( }); } -fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +fn try_load_from_on_disk_cache<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, + tcx: TyCtxt<'tcx>, + dep_node: DepNode, +) { debug_assert!(tcx.dep_graph.is_green(&dep_node)); - let key = Q::Key::recover(tcx, &dep_node).unwrap_or_else(|| { + let key = C::Key::recover(tcx, &dep_node).unwrap_or_else(|| { panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash) }); if query.will_cache_on_disk_for_key(tcx, &key) { @@ -476,10 +477,11 @@ where value } -fn force_from_dep_node<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool -where - Q: QueryDispatcher<'tcx, Qcx = QueryCtxt<'tcx>>, -{ +fn force_from_dep_node<'tcx, C: QueryCache, const FLAGS: QueryFlags>( + query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, + tcx: TyCtxt<'tcx>, + dep_node: DepNode, +) -> bool { // We must avoid ever having to call `force_from_dep_node()` for a // `DepNode::codegen_unit`: // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we @@ -498,7 +500,7 @@ where "calling force_from_dep_node() on dep_kinds::codegen_unit" ); - if let Some(key) = Q::Key::recover(tcx, &dep_node) { + if let Some(key) = C::Key::recover(tcx, &dep_node) { force_query(query, QueryCtxt::new(tcx), key, dep_node); true } else { diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index c1f5e5b67085..eea1c5872290 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -21,6 +21,9 @@ pub trait QueryCacheKey = Hash + Eq + Copy + Debug + for<'a> HashStable = Option, &V) -> Fingerprint>; - -/// Unambiguous shorthand for `::DepContext`. -#[expect(type_alias_bounds)] -type DepContextOf<'tcx, This: QueryDispatcher<'tcx>> = - <>::Qcx as HasDepContext>::DepContext; - -/// Trait that can be used as a vtable for a single query, providing operations -/// and metadata for that query. -/// -/// Implemented by `rustc_query_impl::SemiDynamicQueryDispatcher`, which -/// mostly delegates to `rustc_middle::query::plumbing::QueryVTable`. -/// Those types are not visible from this `rustc_query_system` crate. -/// -/// "Dispatcher" should be understood as a near-synonym of "vtable". -pub trait QueryDispatcher<'tcx>: Copy + 'tcx { - fn name(self) -> &'static str; - - /// Query context used by this dispatcher, i.e. `rustc_query_impl::QueryCtxt`. - type Qcx: QueryContext<'tcx>; - - // `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap, - // but it isn't necessary. - type Key: DepNodeKey> + Eq + Hash + Copy + Debug; - type Value: Copy; - - type Cache: QueryCache; - - fn format_value(self) -> fn(&Self::Value) -> String; - - // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_state(self, tcx: Self::Qcx) -> &'tcx QueryState<'tcx, Self::Key>; - - // Don't use this method to access query results, instead use the methods on TyCtxt - fn query_cache(self, tcx: Self::Qcx) -> &'tcx Self::Cache; - - fn will_cache_on_disk_for_key(self, tcx: DepContextOf<'tcx, Self>, key: &Self::Key) -> bool; - - // Don't use this method to compute query results, instead use the methods on TyCtxt - fn execute_query(self, tcx: DepContextOf<'tcx, Self>, k: Self::Key) -> Self::Value; - - fn compute(self, tcx: Self::Qcx, key: Self::Key) -> Self::Value; - - fn try_load_from_disk( - self, - tcx: Self::Qcx, - key: &Self::Key, - prev_index: SerializedDepNodeIndex, - index: DepNodeIndex, - ) -> Option; - - fn is_loadable_from_disk( - self, - qcx: Self::Qcx, - key: &Self::Key, - idx: SerializedDepNodeIndex, - ) -> bool; - - /// Synthesize an error value to let compilation continue after a cycle. - fn value_from_cycle_error( - self, - tcx: DepContextOf<'tcx, Self>, - cycle_error: &CycleError, - guar: ErrorGuaranteed, - ) -> Self::Value; - - fn anon(self) -> bool; - fn eval_always(self) -> bool; - fn depth_limit(self) -> bool; - fn feedable(self) -> bool; - - fn dep_kind(self) -> DepKind; - fn cycle_error_handling(self) -> CycleErrorHandling; - fn hash_result(self) -> HashResult; - - // Just here for convenience and checking that the key matches the kind, don't override this. - fn construct_dep_node(self, tcx: DepContextOf<'tcx, Self>, key: &Self::Key) -> DepNode { - DepNode::construct(tcx, self.dep_kind(), key) - } -} diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 01bb6ff09fa1..828502b47d4c 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -15,7 +15,7 @@ use rustc_span::def_id::DefId; pub use self::caches::{ DefIdCache, DefaultCache, QueryCache, QueryCacheKey, SingleCache, VecCache, }; -pub use self::dispatcher::{HashResult, QueryDispatcher}; +pub use self::dispatcher::HashResult; pub use self::job::{ QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, QueryMap, break_query_cycles, print_query_stack, report_cycle, From f9958048e0e9a969848dfd24a9432a40de054429 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 9 Feb 2026 13:28:44 +1100 Subject: [PATCH 3440/3801] Move `HashResult`. It's the only thing left in `rustc_query_system::query::dispatcher`. --- compiler/rustc_middle/src/query/plumbing.rs | 6 +++++- compiler/rustc_query_impl/src/lib.rs | 4 ++-- compiler/rustc_query_system/src/query/dispatcher.rs | 5 ----- compiler/rustc_query_system/src/query/mod.rs | 2 -- 4 files changed, 7 insertions(+), 10 deletions(-) delete mode 100644 compiler/rustc_query_system/src/query/dispatcher.rs diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index abb02caef25d..04a3ceb0918a 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -1,12 +1,14 @@ use std::ops::Deref; +use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sync::{AtomicU64, WorkerLocal}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::OwnerId; use rustc_macros::HashStable; use rustc_query_system::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; +use rustc_query_system::ich::StableHashingContext; pub(crate) use rustc_query_system::query::QueryJobId; -use rustc_query_system::query::{CycleError, CycleErrorHandling, HashResult, QueryCache}; +use rustc_query_system::query::{CycleError, CycleErrorHandling, QueryCache}; use rustc_span::{ErrorGuaranteed, Span}; pub use sealed::IntoQueryParam; @@ -30,6 +32,8 @@ pub type TryLoadFromDiskFn<'tcx, Key, Value> = fn( pub type IsLoadableFromDiskFn<'tcx, Key> = fn(tcx: TyCtxt<'tcx>, key: &Key, index: SerializedDepNodeIndex) -> bool; +pub type HashResult = Option, &V) -> Fingerprint>; + /// Stores function pointers and other metadata for a particular query. /// /// Used indirectly by query plumbing in `rustc_query_system` via a trait, diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 7ca4a1300fe6..a33bdd22a797 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -18,12 +18,12 @@ use rustc_middle::queries::{ }; use rustc_middle::query::AsLocalKey; use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; -use rustc_middle::query::plumbing::{QuerySystem, QuerySystemFns, QueryVTable}; +use rustc_middle::query::plumbing::{HashResult, QuerySystem, QuerySystemFns, QueryVTable}; use rustc_middle::query::values::Value; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::query::{ - CycleError, CycleErrorHandling, HashResult, QueryCache, QueryMap, QueryMode, QueryState, + CycleError, CycleErrorHandling, QueryCache, QueryMap, QueryMode, QueryState, }; use rustc_span::{ErrorGuaranteed, Span}; diff --git a/compiler/rustc_query_system/src/query/dispatcher.rs b/compiler/rustc_query_system/src/query/dispatcher.rs deleted file mode 100644 index 3ef8295a07c3..000000000000 --- a/compiler/rustc_query_system/src/query/dispatcher.rs +++ /dev/null @@ -1,5 +0,0 @@ -use rustc_data_structures::fingerprint::Fingerprint; - -use crate::ich::StableHashingContext; - -pub type HashResult = Option, &V) -> Fingerprint>; diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 828502b47d4c..f4a3fda7e372 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -15,7 +15,6 @@ use rustc_span::def_id::DefId; pub use self::caches::{ DefIdCache, DefaultCache, QueryCache, QueryCacheKey, SingleCache, VecCache, }; -pub use self::dispatcher::HashResult; pub use self::job::{ QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, QueryMap, break_query_cycles, print_query_stack, report_cycle, @@ -24,7 +23,6 @@ pub use self::plumbing::*; use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; mod caches; -mod dispatcher; mod job; mod plumbing; From eb2ba7d6b9429297c582fed42fd5da5e5a51cd8f Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Mon, 9 Feb 2026 18:18:24 +0900 Subject: [PATCH 3441/3801] fix ICE in supertrait_vtable_slot when supertrait has missing generics --- .../src/traits/vtable.rs | 11 +++- .../vtable/missing-generics-issue-151330.rs | 23 ++++++++ .../missing-generics-issue-151330.stderr | 53 +++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/vtable/missing-generics-issue-151330.rs create mode 100644 tests/ui/traits/vtable/missing-generics-issue-151330.stderr diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 584c8e2a27c8..539c1d3a35ba 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -434,7 +434,16 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( } }; - prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap() + prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap_or_else(|| { + // This can happen if the trait hierarchy is malformed (e.g., due to + // missing generics on a supertrait bound). There should already be an error + // emitted for this, so we just delay the ICE. + tcx.dcx().delayed_bug(format!( + "could not find the supertrait vtable slot for `{}` -> `{}`", + source, target + )); + None + }) } pub(super) fn provide(providers: &mut Providers) { diff --git a/tests/ui/traits/vtable/missing-generics-issue-151330.rs b/tests/ui/traits/vtable/missing-generics-issue-151330.rs new file mode 100644 index 000000000000..352ad7be3d3a --- /dev/null +++ b/tests/ui/traits/vtable/missing-generics-issue-151330.rs @@ -0,0 +1,23 @@ +//@ compile-flags: -Znext-solver=globally +// Regression test for issue https://github.com/rust-lang/rust/issues/151330 + +trait Supertrait {} + +trait Trait

    : Supertrait {} +//~^ ERROR missing generics for trait `Supertrait` +//~| ERROR missing generics for trait `Supertrait` +//~| ERROR missing generics for trait `Supertrait` + +impl

    Trait

    for () {} + +const fn upcast

    (x: &dyn Trait

    ) -> &dyn Trait

    { + x +} + +const fn foo() -> &'static dyn Supertrait<()> { + upcast::<()>(&()) +} + +const _: &'static dyn Supertrait<()> = foo(); + +fn main() {} diff --git a/tests/ui/traits/vtable/missing-generics-issue-151330.stderr b/tests/ui/traits/vtable/missing-generics-issue-151330.stderr new file mode 100644 index 000000000000..65ef08cad32a --- /dev/null +++ b/tests/ui/traits/vtable/missing-generics-issue-151330.stderr @@ -0,0 +1,53 @@ +error[E0107]: missing generics for trait `Supertrait` + --> $DIR/missing-generics-issue-151330.rs:6:17 + | +LL | trait Trait

    : Supertrait {} + | ^^^^^^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `T` + --> $DIR/missing-generics-issue-151330.rs:4:7 + | +LL | trait Supertrait {} + | ^^^^^^^^^^ - +help: add missing generic argument + | +LL | trait Trait

    : Supertrait {} + | +++ + +error[E0107]: missing generics for trait `Supertrait` + --> $DIR/missing-generics-issue-151330.rs:6:17 + | +LL | trait Trait

    : Supertrait {} + | ^^^^^^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `T` + --> $DIR/missing-generics-issue-151330.rs:4:7 + | +LL | trait Supertrait {} + | ^^^^^^^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | trait Trait

    : Supertrait {} + | +++ + +error[E0107]: missing generics for trait `Supertrait` + --> $DIR/missing-generics-issue-151330.rs:6:17 + | +LL | trait Trait

    : Supertrait {} + | ^^^^^^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `T` + --> $DIR/missing-generics-issue-151330.rs:4:7 + | +LL | trait Supertrait {} + | ^^^^^^^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | trait Trait

    : Supertrait {} + | +++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0107`. From 3339b061af6a9c37ae326f60895048ddbbf3cd6d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Sat, 7 Feb 2026 19:24:59 +0000 Subject: [PATCH 3442/3801] Do not require `'static` for obtaining reflection information. --- library/core/src/intrinsics/mod.rs | 2 +- library/core/src/mem/type_info.rs | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 051dda731881..094def9796db 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2887,7 +2887,7 @@ pub const fn type_name() -> &'static str; #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -pub const fn type_id() -> crate::any::TypeId; +pub const fn type_id() -> crate::any::TypeId; /// Tests (at compile-time) if two [`crate::any::TypeId`] instances identify the /// same type. This is necessary because at const-eval time the actual discriminating diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 8b30803c97c9..d3a7421ff2ee 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -2,7 +2,7 @@ //! runtime or const-eval processable way. use crate::any::TypeId; -use crate::intrinsics::type_of; +use crate::intrinsics::{type_id, type_of}; /// Compile-time type information. #[derive(Debug)] @@ -28,11 +28,17 @@ impl TypeId { impl Type { /// Returns the type information of the generic type parameter. + /// + /// Note: Unlike `TypeId`s obtained via `TypeId::of`, the `Type` + /// struct and its fields contain `TypeId`s that are not necessarily + /// derived from types that outlive `'static`. This means that using + /// the `TypeId`s (transitively) obtained from this function will + /// be able to break invariants that other `TypeId` consuming crates + /// may have assumed to hold. #[unstable(feature = "type_info", issue = "146922")] #[rustc_const_unstable(feature = "type_info", issue = "146922")] - // FIXME(reflection): don't require the 'static bound - pub const fn of() -> Self { - const { TypeId::of::().info() } + pub const fn of() -> Self { + const { type_id::().info() } } } From 6babe687a50440ae6a1d60a748f6a1f809b56d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 5 Feb 2026 15:57:14 +0100 Subject: [PATCH 3443/3801] Port rustc_reservation_impl to the new attribute parser --- .../src/attributes/rustc_internal.rs | 26 +++++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_hir_analysis/src/collect.rs | 3 ++- compiler/rustc_passes/src/check_attr.rs | 2 +- .../src/traits/coherence.rs | 9 +++---- .../src/traits/select/mod.rs | 9 +++---- 8 files changed, 42 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index cbf4af8ce4f4..0fd8c8a04a57 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -873,3 +873,29 @@ impl NoArgsAttributeParser for RustcStrictCoherenceParser { ]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcStrictCoherence; } + +pub(crate) struct RustcReservationImplParser; + +impl SingleAttributeParser for RustcReservationImplParser { + const PATH: &[Symbol] = &[sym::rustc_reservation_impl]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]); + + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "reservation message"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(nv) = args.name_value() else { + cx.expected_name_value(args.span().unwrap_or(cx.attr_span), None); + return None; + }; + + let Some(value_str) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return None; + }; + + Some(AttributeKind::RustcReservationImpl(cx.attr_span, value_str)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index afbb70654f4d..ddb5ae33bc98 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -209,6 +209,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index ef790fe76b74..d9c4179cca83 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1219,6 +1219,9 @@ pub enum AttributeKind { /// Represents `#[rustc_regions]` RustcRegions, + /// Represents `#[rustc_reservation_impl]` + RustcReservationImpl(Span, Symbol), + /// Represents `#[rustc_scalable_vector(N)]` RustcScalableVector { /// The base multiple of lanes that are in a scalable vector, if provided. `element_count` diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index cba7679d2df3..d55cb1d6f66a 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -151,6 +151,7 @@ impl AttributeKind { RustcPubTransparent(..) => Yes, RustcReallocator => No, RustcRegions => No, + RustcReservationImpl(..) => Yes, RustcScalableVector { .. } => Yes, RustcShouldNotBeCalledOnConstItems(..) => Yes, RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f3086266eec0..219e44cd2e27 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1275,7 +1275,8 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader .of_trait .unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}")); let selfty = tcx.type_of(def_id).instantiate_identity(); - let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); + let is_rustc_reservation = + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(..)); check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index dd0de90d575b..3f89ff577d59 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -342,6 +342,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcPreserveUbChecks | AttributeKind::RustcReallocator | AttributeKind::RustcRegions + | AttributeKind::RustcReservationImpl(..) | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcShouldNotBeCalledOnConstItems(..) | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) @@ -396,7 +397,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_trivial_field_reads | sym::rustc_on_unimplemented | sym::rustc_do_not_const_check - | sym::rustc_reservation_impl | sym::rustc_doc_primitive | sym::rustc_conversion_suggestion | sym::rustc_deprecated_safe_2024 diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 9f59f6c59250..fc628e78a3e2 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -8,8 +8,10 @@ use std::fmt::Debug; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{Diag, EmissionGuarantee}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; +use rustc_hir::find_attr; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::PredicateObligations; use rustc_macros::{TypeFoldable, TypeVisitable}; @@ -23,7 +25,7 @@ use rustc_middle::ty::{ }; pub use rustc_next_trait_solver::coherence::*; use rustc_next_trait_solver::solve::SolverDelegateEvalExt; -use rustc_span::{DUMMY_SP, Span, sym}; +use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument, warn}; use super::ObligationCtxt; @@ -758,10 +760,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { } = cand.kind() && let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id) { - let message = infcx - .tcx - .get_attr(def_id, sym::rustc_reservation_impl) - .and_then(|a| a.value_str()); + let message = find_attr!(infcx.tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(_, message) => *message); if let Some(message) = message { self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message }); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 787dd4ea6254..4469afc3a4eb 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -12,9 +12,9 @@ use rustc_data_structures::assert_matches; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Diag, EmissionGuarantee}; -use rustc_hir as hir; -use rustc_hir::LangItem; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, LangItem, find_attr}; use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::at::ToTrace; @@ -33,7 +33,7 @@ use rustc_middle::ty::{ may_use_unstable_feature, }; use rustc_next_trait_solver::solve::AliasBoundKind; -use rustc_span::{Symbol, sym}; +use rustc_span::Symbol; use tracing::{debug, instrument, trace}; use self::EvaluationResult::*; @@ -1445,8 +1445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { && let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) { if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes { - let message = - tcx.get_attr(def_id, sym::rustc_reservation_impl).and_then(|a| a.value_str()); + let message = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(_, message) => *message); if let Some(message) = message { debug!( "filter_reservation_impls: \ From 88c296a19fb205e08edd9636a7ccf94b0346720c Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 9 Feb 2026 18:24:11 +0800 Subject: [PATCH 3444/3801] std: introduce path normalize methods at top of std::path --- library/std/src/path.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 25bd7005b994..14b41a427f1e 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -19,6 +19,20 @@ //! matter the platform or filesystem. An exception to this is made for Windows //! drive letters. //! +//! ## Path normalization +//! +//! Several methods in this module perform basic path normalization by disregarding +//! repeated separators, non-leading `.` components, and trailing separators. These include: +//! - Methods for iteration, such as [`Path::components`] and [`Path::iter`] +//! - Methods for inspection, such as [`Path::has_root`] +//! - Comparisons using [`PartialEq`], [`PartialOrd`], and [`Ord`] +//! +//! [`Path::join`] and [`PathBuf::push`] also disregard trailing slashes. +//! +// FIXME(normalize_lexically): mention normalize_lexically once stable +//! These methods **do not** resolve `..` components or symlinks. For full normalization +//! including `..` resolution, use [`Path::canonicalize`] (which does access the filesystem). +//! //! ## Simple usage //! //! Path manipulation includes both parsing components from slices and building From 8cd47adab253c6ec0eea949563215fa7fdbc7241 Mon Sep 17 00:00:00 2001 From: Juho Kahala <57393910+quaternic@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:32:04 +0200 Subject: [PATCH 3445/3801] libm: Fix tests for lgamma The tests were using `rug::ln_gamma` as a reference for `libm::lgamma`, which actually computes the natural logarithm *of the absolute value* of the Gamma function. This changes the range of inputs used for the icount-benchmarks of these functions, which causes false regressions in [1]. [1]: https://github.com/rust-lang/compiler-builtins/actions/runs/21788698368/job/62864230903?pr=1075#step:7:2710. Fixes: a1a066611dc2 ("Create interfaces for testing against MPFR") --- .../compiler-builtins/libm-test/src/domain.rs | 2 +- .../libm-test/src/mpfloat.rs | 27 +++++++++++++- .../libm-test/src/precision.rs | 36 +++++++++---------- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/library/compiler-builtins/libm-test/src/domain.rs b/library/compiler-builtins/libm-test/src/domain.rs index 94641be9b548..eb009bfa093f 100644 --- a/library/compiler-builtins/libm-test/src/domain.rs +++ b/library/compiler-builtins/libm-test/src/domain.rs @@ -207,7 +207,7 @@ impl EitherPrim, Domain> { .into_prim_float()]; /// Domain for `loggamma` - const LGAMMA: [Self; 1] = Self::STRICTLY_POSITIVE; + const LGAMMA: [Self; 1] = Self::UNBOUNDED1; /// Domain for `jn` and `yn`. // FIXME: the domain should provide some sort of "reasonable range" so we don't actually test diff --git a/library/compiler-builtins/libm-test/src/mpfloat.rs b/library/compiler-builtins/libm-test/src/mpfloat.rs index 9b51dc6051d0..85f0a4da4a6e 100644 --- a/library/compiler-builtins/libm-test/src/mpfloat.rs +++ b/library/compiler-builtins/libm-test/src/mpfloat.rs @@ -170,7 +170,9 @@ libm_macros::for_each_function! { ldexpf, ldexpf128, ldexpf16, + lgamma, lgamma_r, + lgammaf, lgammaf_r, modf, modff, @@ -213,7 +215,6 @@ libm_macros::for_each_function! { fmaximum_num | fmaximum_numf | fmaximum_numf16 | fmaximum_numf128 => max, fmin | fminf | fminf16 | fminf128 | fminimum_num | fminimum_numf | fminimum_numf16 | fminimum_numf128 => min, - lgamma | lgammaf => ln_gamma, log | logf => ln, log1p | log1pf => ln_1p, tgamma | tgammaf => gamma, @@ -576,6 +577,30 @@ impl MpOp for crate::op::lgammaf_r::Routine { } } +impl MpOp for crate::op::lgamma::Routine { + type MpTy = MpFloat; + + fn new_mp() -> Self::MpTy { + new_mpfloat::() + } + + fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet { + ::run(this, input).0 + } +} + +impl MpOp for crate::op::lgammaf::Routine { + type MpTy = MpFloat; + + fn new_mp() -> Self::MpTy { + new_mpfloat::() + } + + fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet { + ::run(this, input).0 + } +} + /* stub implementations so we don't need to special case them */ impl MpOp for crate::op::nextafter::Routine { diff --git a/library/compiler-builtins/libm-test/src/precision.rs b/library/compiler-builtins/libm-test/src/precision.rs index a94fe429f5f3..5d52da168fe7 100644 --- a/library/compiler-builtins/libm-test/src/precision.rs +++ b/library/compiler-builtins/libm-test/src/precision.rs @@ -67,7 +67,7 @@ pub fn default_ulp(ctx: &CheckCtx) -> u32 { Bn::Exp2 => 1, Bn::Expm1 => 1, Bn::Hypot => 1, - Bn::Lgamma | Bn::LgammaR => 16, + Bn::Lgamma | Bn::LgammaR => 4, Bn::Log => 1, Bn::Log10 => 1, Bn::Log1p => 1, @@ -102,7 +102,6 @@ pub fn default_ulp(ctx: &CheckCtx) -> u32 { match ctx.base_name { Bn::Cosh => ulp = 2, Bn::Exp10 if usize::BITS < 64 => ulp = 4, - Bn::Lgamma | Bn::LgammaR => ulp = 400, Bn::Tanh => ulp = 4, _ => (), } @@ -218,17 +217,17 @@ impl MaybeOverride<(f16,)> for SpecialCase {} impl MaybeOverride<(f32,)> for SpecialCase { fn check_float(input: (f32,), actual: F, expected: F, ctx: &CheckCtx) -> CheckAction { - if (ctx.base_name == BaseName::Lgamma || ctx.base_name == BaseName::LgammaR) - && input.0 > 4e36 - && expected.is_infinite() - && !actual.is_infinite() - { - // This result should saturate but we return a finite value. + if ctx.base_name == BaseName::J0 && input.0 < -1e34 { + // Errors get huge close to -inf return XFAIL_NOCHECK; } - if ctx.base_name == BaseName::J0 && input.0 < -1e34 { - // Errors get huge close to -inf + // FIXME(correctness): lgammaf has high relative inaccuracy near its zeroes + if matches!(ctx.base_name, BaseName::Lgamma | BaseName::LgammaR) + && input.0 > -13.0625 + && input.0 < -2.0 + && (expected.abs() < F::ONE || (input.0 - input.0.round()).abs() < 0.02) + { return XFAIL_NOCHECK; } @@ -275,6 +274,15 @@ impl MaybeOverride<(f64,)> for SpecialCase { return XFAIL_NOCHECK; } + // FIXME(correctness): lgamma has high relative inaccuracy near its zeroes + if matches!(ctx.base_name, BaseName::Lgamma | BaseName::LgammaR) + && input.0 > -32.0 + && input.0 < -2.0 + && (expected.abs() < F::ONE || (input.0 - input.0.round()).abs() < 0.02) + { + return XFAIL_NOCHECK; + } + // maybe_check_nan_bits(actual, expected, ctx) unop_common(input, actual, expected, ctx) } @@ -304,14 +312,6 @@ fn unop_common( expected: F2, ctx: &CheckCtx, ) -> CheckAction { - if (ctx.base_name == BaseName::Lgamma || ctx.base_name == BaseName::LgammaR) - && input.0 < F1::ZERO - && !input.0.is_infinite() - { - // loggamma should not be defined for x < 0, yet we both return results - return XFAIL_NOCHECK; - } - // fabs and copysign must leave NaNs untouched. if ctx.base_name == BaseName::Fabs && input.0.is_nan() { // LLVM currently uses x87 instructions which quieten signalling NaNs to handle the i686 From 8c0a493e358a27f1dea9888f85680c613e41903f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 9 Feb 2026 12:03:29 +0100 Subject: [PATCH 3446/3801] BikeshedGuaranteedNoDrop trait: add comments indicating that it can be observed on stable --- compiler/rustc_next_trait_solver/src/solve/trait_goals.rs | 3 +++ .../rustc_trait_selection/src/traits/select/confirmation.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 003841f3af3f..dd012a5146e6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -687,6 +687,9 @@ where /// /// because these impls overlap, and I'd rather not build a coherence hack for /// this harmless overlap. + /// + /// This trait is indirectly exposed on stable, so do *not* extend the set of types that + /// implement the trait without FCP! fn consider_builtin_bikeshed_guaranteed_no_drop_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4f65b30775ed..b0e045274d0d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1246,6 +1246,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) } + /// This trait is indirectly exposed on stable, so do *not* extend the set of types that + /// implement the trait without FCP! fn confirm_bikeshed_guaranteed_no_drop_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, From ae24fdaccc71600ec540ff018208c5d592ad016a Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 9 Feb 2026 12:45:01 +0100 Subject: [PATCH 3447/3801] fix: Fix `set_top_subtree_delimiter_span` using wrong index for close span --- src/tools/rust-analyzer/crates/tt/src/storage.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/tt/src/storage.rs b/src/tools/rust-analyzer/crates/tt/src/storage.rs index 4dd02d875a29..50a1106175ab 100644 --- a/src/tools/rust-analyzer/crates/tt/src/storage.rs +++ b/src/tools/rust-analyzer/crates/tt/src/storage.rs @@ -488,7 +488,7 @@ impl TopSubtree { unreachable!() }; *open_span = S::new(span.open.range, 0); - *close_span = S::new(span.close.range, 0); + *close_span = S::new(span.close.range, 1); } dispatch! { match &mut self.repr => tt => do_it(tt, span) From 0cf7b94bf52f45996776d8b27708516928b12e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 13 Nov 2025 15:44:20 +0100 Subject: [PATCH 3448/3801] fix Nix setup description --- src/doc/rustc-dev-guide/src/building/suggested.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 3ed4f129d144..ac8f15db7751 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -426,7 +426,7 @@ You can then use that rust2 folder as a separate workspace for modifying and bui Several nix configurations are defined in `src/tools/nix-dev-shell`. -If you're using direnv, you can create a symbol link to `src/tools/nix-dev-shell/envrc-flake` or `src/tools/nix-dev-shell/envrc-shell` +If you're using direnv, you can create a symbolic link to `src/tools/nix-dev-shell/envrc-flake` or `src/tools/nix-dev-shell/envrc-shell` ```bash ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc # Use flake @@ -436,6 +436,12 @@ or ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc # Use nix-shell ``` +If you're using the flake, make sure to also update it with the following command: + +``` +nix flake update --flake ./src/tools/nix-dev-shell +``` + ### Note Note that when using nix on a not-NixOS distribution, it may be necessary to set From 389294dcde4f50e9c910e5da6aca0582ced13796 Mon Sep 17 00:00:00 2001 From: Nora Breitmoser-Widdecke <23097564+puzzlewolf@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:35:09 +0100 Subject: [PATCH 3449/3801] Fix documentation for `indexing_slicing` Replace typo'd name with link to the lint. --- clippy_lints/src/indexing_slicing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index a2fcdb4a54b4..e9ddd3ca8ede 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -44,7 +44,7 @@ declare_clippy_lint! { /// Checks for usage of indexing or slicing that may panic at runtime. /// /// This lint does not report on indexing or slicing operations - /// that always panic, clippy's `out_of_bound_indexing` already + /// that always panic, [out_of_bounds_indexing](#out_of_bounds_indexing) already /// handles those cases. /// /// ### Why restrict this? From e04ae80c5ac7fab7d01aee9ad97ef109fe7f024d Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 9 Feb 2026 17:32:48 +1100 Subject: [PATCH 3450/3801] Rename `JobOwner` to `ActiveJobGuard` This commit also adds and updates some relevant comments. --- compiler/rustc_middle/src/ty/context/tls.rs | 3 +-- compiler/rustc_query_impl/src/execution.rs | 25 +++++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index fa9995898ac2..a06f92792820 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -16,8 +16,7 @@ pub struct ImplicitCtxt<'a, 'tcx> { /// The current `TyCtxt`. pub tcx: TyCtxt<'tcx>, - /// The current query job, if any. This is updated by `JobOwner::start` in - /// `ty::query::plumbing` when executing a query. + /// The current query job, if any. pub query: Option, /// Used to prevent queries from calling too deeply. diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index ba442d8a0081..7bed6ee937db 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -83,9 +83,12 @@ pub(crate) fn gather_active_jobs_inner<'tcx, K: Copy>( Some(()) } -/// A type representing the responsibility to execute the job in the `job` field. -/// This will poison the relevant query if dropped. -struct JobOwner<'tcx, K> +/// Guard object representing the responsibility to execute a query job and +/// mark it as completed. +/// +/// This will poison the relevant query key if it is dropped without calling +/// [`Self::complete`]. +struct ActiveJobGuard<'tcx, K> where K: Eq + Hash + Copy, { @@ -137,12 +140,12 @@ fn handle_cycle_error<'tcx, C: QueryCache, const FLAGS: QueryFlags>( } } -impl<'tcx, K> JobOwner<'tcx, K> +impl<'tcx, K> ActiveJobGuard<'tcx, K> where K: Eq + Hash + Copy, { /// Completes the query by updating the query cache with the `result`, - /// signals the waiter and forgets the JobOwner, so it won't poison the query + /// signals the waiter, and forgets the guard so it won't poison the query. fn complete(self, cache: &C, key_hash: u64, result: C::Value, dep_node_index: DepNodeIndex) where C: QueryCache, @@ -174,7 +177,7 @@ where } } -impl<'tcx, K> Drop for JobOwner<'tcx, K> +impl<'tcx, K> Drop for ActiveJobGuard<'tcx, K> where K: Eq + Hash + Copy, { @@ -342,11 +345,13 @@ fn execute_job<'tcx, C: QueryCache, const FLAGS: QueryFlags, const INCR: bool>( id: QueryJobId, dep_node: Option, ) -> (C::Value, Option) { - // Use `JobOwner` so the query will be poisoned if executing it panics. - let job_owner = JobOwner { state, key }; + // Set up a guard object that will automatically poison the query if a + // panic occurs while executing the query (or any intermediate plumbing). + let job_guard = ActiveJobGuard { state, key }; debug_assert_eq!(qcx.tcx.dep_graph.is_fully_enabled(), INCR); + // Delegate to another function to actually execute the query job. let (result, dep_node_index) = if INCR { execute_job_incr(query, qcx, qcx.tcx.dep_graph.data().unwrap(), key, dep_node, id) } else { @@ -388,7 +393,9 @@ fn execute_job<'tcx, C: QueryCache, const FLAGS: QueryFlags, const INCR: bool>( } } } - job_owner.complete(cache, key_hash, result, dep_node_index); + + // Tell the guard to perform completion bookkeeping, and also to not poison the query. + job_guard.complete(cache, key_hash, result, dep_node_index); (result, Some(dep_node_index)) } From c475bdaa53441f52977ce79ac2e16b807dcb006d Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 9 Feb 2026 17:36:29 +1100 Subject: [PATCH 3451/3801] Include `key_hash` in `ActiveJobGuard` This value is a previously-computed hash of the key, so it makes sense to bundle it with the key inside the guard, since the guard will need it on completion anyway. --- compiler/rustc_query_impl/src/execution.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 7bed6ee937db..88604c91d025 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -94,6 +94,7 @@ where { state: &'tcx QueryState<'tcx, K>, key: K, + key_hash: u64, } #[cold] @@ -146,14 +147,13 @@ where { /// Completes the query by updating the query cache with the `result`, /// signals the waiter, and forgets the guard so it won't poison the query. - fn complete(self, cache: &C, key_hash: u64, result: C::Value, dep_node_index: DepNodeIndex) + fn complete(self, cache: &C, result: C::Value, dep_node_index: DepNodeIndex) where C: QueryCache, { - let key = self.key; - let state = self.state; - - // Forget ourself so our destructor won't poison the query + // Forget ourself so our destructor won't poison the query. + // (Extract fields by value first to make sure we don't leak anything.) + let Self { state, key, key_hash }: Self = self; mem::forget(self); // Mark as complete before we remove the job from the active state @@ -185,11 +185,10 @@ where #[cold] fn drop(&mut self) { // Poison the query so jobs waiting on it panic. - let state = self.state; + let Self { state, key, key_hash } = *self; let job = { - let key_hash = sharded::make_hash(&self.key); let mut shard = state.active.lock_shard_by_hash(key_hash); - match shard.find_entry(key_hash, equivalent_key(&self.key)) { + match shard.find_entry(key_hash, equivalent_key(&key)) { Err(_) => panic!(), Ok(occupied) => { let ((key, value), vacant) = occupied.remove(); @@ -347,7 +346,7 @@ fn execute_job<'tcx, C: QueryCache, const FLAGS: QueryFlags, const INCR: bool>( ) -> (C::Value, Option) { // Set up a guard object that will automatically poison the query if a // panic occurs while executing the query (or any intermediate plumbing). - let job_guard = ActiveJobGuard { state, key }; + let job_guard = ActiveJobGuard { state, key, key_hash }; debug_assert_eq!(qcx.tcx.dep_graph.is_fully_enabled(), INCR); @@ -395,7 +394,7 @@ fn execute_job<'tcx, C: QueryCache, const FLAGS: QueryFlags, const INCR: bool>( } // Tell the guard to perform completion bookkeeping, and also to not poison the query. - job_guard.complete(cache, key_hash, result, dep_node_index); + job_guard.complete(cache, result, dep_node_index); (result, Some(dep_node_index)) } From 2b22150c1802bd5833492e263745a9037f1a190a Mon Sep 17 00:00:00 2001 From: Oscar Bray Date: Wed, 4 Feb 2026 18:37:10 +0000 Subject: [PATCH 3452/3801] Port rustc_no_implicit_bounds attribute to parser. --- .../rustc_attr_parsing/src/attributes/crate_level.rs | 9 +++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_hir_analysis/src/hir_ty_lowering/bounds.rs | 10 ++++++---- compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 557dfe09853b..bdfe7bfb8f1f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -283,3 +283,12 @@ impl NoArgsAttributeParser for RustcPreserveUbChecksParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcPreserveUbChecks; } + +pub(crate) struct RustcNoImplicitBoundsParser; + +impl NoArgsAttributeParser for RustcNoImplicitBoundsParser { + const PATH: &[Symbol] = &[sym::rustc_no_implicit_bounds]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitBounds; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index afbb70654f4d..573e14786abf 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -281,6 +281,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index ef790fe76b74..869e3f43ea71 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1177,6 +1177,9 @@ pub enum AttributeKind { /// Represents `#[rustc_no_implicit_autorefs]` RustcNoImplicitAutorefs, + /// Represents `#[rustc_no_implicit_bounds]` + RustcNoImplicitBounds, + /// Represents `#[rustc_non_const_trait_method]`. RustcNonConstTraitMethod, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index cba7679d2df3..001448b3e72e 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -137,6 +137,7 @@ impl AttributeKind { RustcMustImplementOneOf { .. } => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes, + RustcNoImplicitBounds => No, RustcNonConstTraitMethod => No, // should be reported via other queries like `constness` RustcNounwind => No, RustcObjcClass { .. } => No, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index a1c3af5f999d..85e96e200c2e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -4,15 +4,16 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; -use rustc_hir::PolyTraitRef; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; +use rustc_hir::{PolyTraitRef, find_attr}; use rustc_middle::bug; use rustc_middle::ty::{ self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, Upcast, }; -use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; +use rustc_span::{ErrorGuaranteed, Ident, Span, kw}; use rustc_trait_selection::traits; use smallvec::SmallVec; use tracing::{debug, instrument}; @@ -170,7 +171,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); // Skip adding any default bounds if `#![rustc_no_implicit_bounds]` - if tcx.has_attr(CRATE_DEF_ID, sym::rustc_no_implicit_bounds) { + if find_attr!(tcx.get_all_attrs(CRATE_DEF_ID), AttributeKind::RustcNoImplicitBounds) { return; } @@ -284,7 +285,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { context: ImpliedBoundsContext<'tcx>, ) -> bool { let collected = collect_bounds(hir_bounds, context, trait_def_id); - !self.tcx().has_attr(CRATE_DEF_ID, sym::rustc_no_implicit_bounds) && !collected.any() + !find_attr!(self.tcx().get_all_attrs(CRATE_DEF_ID), AttributeKind::RustcNoImplicitBounds) + && !collected.any() } fn reject_duplicate_relaxed_bounds(&self, relaxed_bounds: SmallVec<[&PolyTraitRef<'_>; 1]>) { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index dd0de90d575b..2dcfbaaef579 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -330,6 +330,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcMir(_) | AttributeKind::RustcNeverReturnsNullPointer | AttributeKind::RustcNoImplicitAutorefs + | AttributeKind::RustcNoImplicitBounds | AttributeKind::RustcNonConstTraitMethod | AttributeKind::RustcNounwind | AttributeKind::RustcObjcClass { .. } @@ -413,7 +414,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // crate-level attrs, are checked below | sym::feature | sym::register_tool - | sym::rustc_no_implicit_bounds | sym::test_runner, .. ] => {} From 43e5203a8cc1d10f12895475069c216db4d2dd95 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 6 Feb 2026 16:16:17 +0000 Subject: [PATCH 3453/3801] compiletest: `-Zunstable-options` for json targets --- src/tools/compiletest/src/common.rs | 4 +++- src/tools/compiletest/src/runtest.rs | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index c71a350ffd30..54c0f2ec7430 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -949,7 +949,9 @@ impl TargetCfgs { // actually be changed with `-C` flags. for config in query_rustc_output( config, - &["--print=cfg", "--target", &config.target], + // `-Zunstable-options` is necessary when compiletest is running with custom targets + // (such as synthetic targets used to bless mir-opt tests). + &["-Zunstable-options", "--print=cfg", "--target", &config.target], Default::default(), ) .trim() diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1804490a5f12..742790a50fce 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1670,6 +1670,11 @@ impl<'test> TestCx<'test> { if self.props.force_host { &*self.config.host } else { &*self.config.target }; compiler.arg(&format!("--target={}", target)); + if target.ends_with(".json") { + // `-Zunstable-options` is necessary when compiletest is running with custom targets + // (such as synthetic targets used to bless mir-opt tests). + compiler.arg("-Zunstable-options"); + } } self.set_revision_flags(&mut compiler); From 40a264cd454e791f478dae1488bb67ed7d7d058d Mon Sep 17 00:00:00 2001 From: Weixie Cui Date: Mon, 9 Feb 2026 22:16:36 +0800 Subject: [PATCH 3454/3801] fix: rhs_span to rhs_span_new --- compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 4fb739403ced..853ecd3c91f7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1695,7 +1695,7 @@ fn suggest_ampmut<'tcx>( && let Either::Left(rhs_stmt_new) = body.stmt_at(*assign) && let StatementKind::Assign(box (_, rvalue_new)) = &rhs_stmt_new.kind && let rhs_span_new = rhs_stmt_new.source_info.span - && let Ok(rhs_str_new) = tcx.sess.source_map().span_to_snippet(rhs_span) + && let Ok(rhs_str_new) = tcx.sess.source_map().span_to_snippet(rhs_span_new) { (rvalue, rhs_span, rhs_str) = (rvalue_new, rhs_span_new, rhs_str_new); } From e7855f5bfaf5d0d568f1fe4d9c07aec1144f405d Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Tue, 3 Feb 2026 15:59:46 +0000 Subject: [PATCH 3455/3801] internal: Run clippy as a separate CI step Currently clippy is run in CI as part of the macOS build. This is a little confusing, because clippy failures just show as "Rust (macos-latest)" which make it look like a macOS build failure. Instead, treat clippy as a separate build step, like miri and rustfmt. This should also make CI a little faster, because it reduces macOS runner usage (which tend to be slower than Linux on GitHub actions), and it reduces the number of steps where we need to install clippy. --- .../rust-analyzer/.github/workflows/ci.yaml | 30 +++++++++++++++---- .../crates/hir-ty/src/mir/eval.rs | 2 +- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index 1a0deee564ae..c3a5017d72d7 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -96,7 +96,7 @@ jobs: run: | rustup update --no-self-update stable rustup default stable - rustup component add --toolchain stable rust-src clippy rustfmt + rustup component add --toolchain stable rust-src rustfmt # We also install a nightly rustfmt, because we use `--file-lines` in # a test. rustup toolchain install nightly --profile minimal --component rustfmt @@ -128,10 +128,6 @@ jobs: - name: Run cargo-machete run: cargo machete - - name: Run Clippy - if: matrix.os == 'macos-latest' - run: cargo clippy --all-targets -- -D clippy::disallowed_macros -D clippy::dbg_macro -D clippy::todo -D clippy::print_stdout -D clippy::print_stderr - analysis-stats: if: github.repository == 'rust-lang/rust-analyzer' runs-on: ubuntu-latest @@ -178,6 +174,28 @@ jobs: - run: cargo fmt -- --check + clippy: + if: github.repository == 'rust-lang/rust-analyzer' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Note that clippy output is currently dependent on whether rust-src is installed, + # https://github.com/rust-lang/rust-clippy/issues/14625 + - name: Install Rust toolchain + run: | + rustup update --no-self-update stable + rustup default stable + rustup component add --toolchain stable rust-src clippy + + # https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/rust.json + - name: Install Rust Problem Matcher + run: echo "::add-matcher::.github/rust.json" + + - run: cargo clippy --all-targets -- -D clippy::disallowed_macros -D clippy::dbg_macro -D clippy::todo -D clippy::print_stdout -D clippy::print_stderr + miri: if: github.repository == 'rust-lang/rust-analyzer' runs-on: ubuntu-latest @@ -309,7 +327,7 @@ jobs: run: typos conclusion: - needs: [rust, rust-cross, typescript, typo-check, proc-macro-srv, miri, rustfmt, analysis-stats] + needs: [rust, rust-cross, typescript, typo-check, proc-macro-srv, miri, rustfmt, clippy, analysis-stats] # We need to ensure this job does *not* get skipped if its dependencies fail, # because a skipped job is considered a success by GitHub. So we have to # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index 5de08313f418..ec0723c3f8c3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -1625,7 +1625,7 @@ impl<'db> Evaluator<'db> { }; match target_ty { rustc_type_ir::FloatTy::F32 => Owned((value as f32).to_le_bytes().to_vec()), - rustc_type_ir::FloatTy::F64 => Owned((value as f64).to_le_bytes().to_vec()), + rustc_type_ir::FloatTy::F64 => Owned(value.to_le_bytes().to_vec()), rustc_type_ir::FloatTy::F16 | rustc_type_ir::FloatTy::F128 => { not_supported!("unstable floating point type f16 and f128"); } From 00432c0b85ecd3a099fbe4b0f867f3929b099366 Mon Sep 17 00:00:00 2001 From: mikhailofff Date: Mon, 9 Feb 2026 18:54:17 +0400 Subject: [PATCH 3456/3801] fix dead links in type checking section of the doc --- book/src/development/type_checking.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/development/type_checking.md b/book/src/development/type_checking.md index 578836ecc568..55adb0aceadd 100644 --- a/book/src/development/type_checking.md +++ b/book/src/development/type_checking.md @@ -146,7 +146,7 @@ in this chapter: - [Stages of compilation](https://rustc-dev-guide.rust-lang.org/compiler-src.html#the-main-stages-of-compilation) - [Diagnostic items](https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-items.html) -- [Type checking](https://rustc-dev-guide.rust-lang.org/type-checking.html) +- [Type checking](https://rustc-dev-guide.rust-lang.org/hir-typeck/summary.html) - [Ty module](https://rustc-dev-guide.rust-lang.org/ty.html) [Adt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html#variant.Adt @@ -163,5 +163,5 @@ in this chapter: [TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html [TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html [middle_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html -[hir_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.Ty.html +[hir_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Ty.html [lower_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/fn.lower_ty.html From 6494dabc33a27dafd61b98dca55915b5cb7f60de Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 10 Feb 2026 00:57:41 +0900 Subject: [PATCH 3457/3801] fix: Sync `allow_normalize` to rustc --- .../hir-ty/src/next_solver/predicate.rs | 7 +- .../crates/hir-ty/src/tests/regression.rs | 70 +++++++++++++++++++ .../crates/test-utils/src/minicore.rs | 24 ++++++- 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs index 6f4fae707317..8658d03a9e3e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs @@ -714,9 +714,9 @@ impl<'db> rustc_type_ir::inherent::Predicate> for Predicate<'db> fn allow_normalization(self) -> bool { // TODO: this should probably live in rustc_type_ir match self.inner().as_ref().skip_binder() { - PredicateKind::Clause(ClauseKind::WellFormed(_)) - | PredicateKind::AliasRelate(..) - | PredicateKind::NormalizesTo(..) => false, + PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => { + false + } PredicateKind::Clause(ClauseKind::Trait(_)) | PredicateKind::Clause(ClauseKind::RegionOutlives(_)) | PredicateKind::Clause(ClauseKind::TypeOutlives(_)) @@ -729,6 +729,7 @@ impl<'db> rustc_type_ir::inherent::Predicate> for Predicate<'db> | PredicateKind::Coerce(_) | PredicateKind::Clause(ClauseKind::ConstEvaluatable(_)) | PredicateKind::ConstEquate(_, _) + | PredicateKind::NormalizesTo(..) | PredicateKind::Ambiguous => true, } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 3b5b4e4fa540..fba582f880fd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -2688,3 +2688,73 @@ pub trait FilterT = Self> { "#, ); } + +#[test] +fn regression_21605() { + check_infer( + r#" +//- minicore: fn, coerce_unsized, dispatch_from_dyn, iterator, iterators +pub struct Filter<'a, 'b, T> +where + T: 'b, + 'a: 'b, +{ + filter_fn: dyn Fn(&'a T) -> bool, + t: Option, + b: &'b (), +} + +impl<'a, 'b, T> Filter<'a, 'b, T> +where + T: 'b, + 'a: 'b, +{ + pub fn new(filter_fn: dyn Fn(&T) -> bool) -> Self { + Self { + filter_fn: filter_fn, + t: None, + b: &(), + } + } +} + +pub trait FilterExt { + type Output; + fn filter(&self, filter: &Filter) -> Self::Output; +} + +impl FilterExt for [T; N] +where + T: IntoIterator, +{ + type Output = T; + fn filter(&self, filter: &Filter) -> Self::Output { + let _ = self.into_iter().filter(filter.filter_fn); + loop {} + } +} +"#, + expect![[r#" + 214..223 'filter_fn': dyn Fn(&'? T) -> bool + 'static + 253..360 '{ ... }': Filter<'a, 'b, T> + 263..354 'Self {... }': Filter<'a, 'b, T> + 293..302 'filter_fn': dyn Fn(&'? T) -> bool + 'static + 319..323 'None': Option + 340..343 '&()': &'? () + 341..343 '()': () + 421..425 'self': &'? Self + 427..433 'filter': &'? Filter<'?, '?, T> + 580..584 'self': &'? [T; N] + 586..592 'filter': &'? Filter<'?, '?, T> + 622..704 '{ ... }': T + 636..637 '_': Filter, dyn Fn(&'? T) -> bool + '?> + 640..644 'self': &'? [T; N] + 640..656 'self.i...iter()': Iter<'?, T> + 640..681 'self.i...er_fn)': Filter, dyn Fn(&'? T) -> bool + '?> + 664..670 'filter': &'? Filter<'?, '?, T> + 664..680 'filter...ter_fn': dyn Fn(&'? T) -> bool + 'static + 691..698 'loop {}': ! + 696..698 '{}': () + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index 7d95043867ee..c34475bbdf01 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs @@ -1689,6 +1689,21 @@ pub mod iter { } } + pub struct Filter { + iter: I, + predicate: P, + } + impl Iterator for Filter + where + P: FnMut(&I::Item) -> bool, + { + type Item = I::Item; + + fn next(&mut self) -> Option { + loop {} + } + } + pub struct FilterMap { iter: I, f: F, @@ -1705,7 +1720,7 @@ pub mod iter { } } } - pub use self::adapters::{FilterMap, Take}; + pub use self::adapters::{Filter, FilterMap, Take}; mod sources { mod repeat { @@ -1756,6 +1771,13 @@ pub mod iter { { loop {} } + fn filter

    (self, predicate: P) -> crate::iter::Filter + where + Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + loop {} + } fn filter_map(self, _f: F) -> crate::iter::FilterMap where Self: Sized, From 73a991fb9d7f68f497f047d4e948bde463f2f6eb Mon Sep 17 00:00:00 2001 From: Keith-Cancel Date: Thu, 5 Feb 2026 22:01:57 -0800 Subject: [PATCH 3458/3801] Allow provisional mgca syntax of type const = to be reconized. Revert, but without type const. Update symbol for feature err, then update suggestion output, and lastly update tests that change because of those. Update these new tests with the correct syntax, and few existing tests with the new outputs the merge with main added. Fix for tidyfmt and some errors when manually resolving a merge conflicts. Update these tests to use update error messages and type const syntax. Update comments and error message to use new syntax instead of old type_const attribute. Remove the type_const attribute update some more tests to use the new syntax. Update these test cases. update feature gate test Change gate logic for `mgca_type_const_syntax` to work also if `min_generic_const_args` is enabled. Create a new feature gate that checks for the feature before expansion. Make rustfmt handle the `type const` syntax correctly. Add a convience method to check if a RhsKind is type const. Rename `Const` discriminant to `Body` for `ConstItemRhsKind` Give the `TraitItemKind` flag an enum instead of a simple bool to better describe what the flag is for. Update formatting for these match statements. Update clippy test to use type const syntax. Update test to use type const syntax. update rustfmt to match ast items. Update clippy to match ast and hir items. Few more test cases that used old attribute, instead of 'type const' Update to match the output from the feature gate checks. tidyfmt adjustments. Update the is_type_const, so I can constrain record!(..) in encoder.rs Update conditional compilation test. Move the feature gate to after expansion to allow for cfg(...) to work. Update some more tests to use the new syntax. Update type const tests in associated-const-bindings to use new syntax. Don't check based off the attribute, but the item here. Update some tests outside of the const_generics folder that were using #[type_const] update the tests in associated consts that use #[type_const] to use type const Update these mgca tests with the type const syntax. Add a flag to TraitItemKind for detecting type const for now. Maybe later change ItemConstRhs to have optional consts but that touches a lot more lines of code. Don't need into for these now that it's a query. Add is_type_const query to handle foreign def ids. update this test to use type const syntax. Fix logic here, we only want to lower if there is expression in this case. Update built-in macros to use ConstItemRhsKind Update more instance of the old ConstItemRhs. Rename ConstItemKind to ConstItemRhsKind, I noticed there is a typed called ConstantItemKind, so add the Rhs to the name to avoid confusion. Update lower to use ConstItemKind Add an other helper method to check if the rhs kinda has an expr. Update item parse to use ConstItemKind enum. Felt the field name could a be little clear when editing a few other things. Change the ConstItem struct see know if we have a type const or regular const. Make sure this syntax is properly feature gated. --- compiler/rustc_ast/src/ast.rs | 37 ++++++--- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 35 +++++--- compiler/rustc_ast_lowering/src/lib.rs | 19 ++--- .../rustc_ast_passes/src/ast_validation.rs | 16 ++-- compiler/rustc_ast_passes/src/feature_gate.rs | 43 ++++++++++ .../rustc_ast_pretty/src/pprust/state/item.rs | 8 +- .../src/attributes/traits.rs | 9 --- compiler/rustc_attr_parsing/src/context.rs | 1 - .../src/alloc_error_handler.rs | 2 +- compiler/rustc_builtin_macros/src/eii.rs | 2 +- .../src/global_allocator.rs | 2 +- .../src/proc_macro_harness.rs | 2 +- compiler/rustc_builtin_macros/src/test.rs | 4 +- .../src/check_consts/qualifs.rs | 2 +- .../src/const_eval/eval_queries.rs | 2 +- compiler/rustc_expand/src/build.rs | 4 +- compiler/rustc_feature/src/builtin_attrs.rs | 7 -- compiler/rustc_feature/src/unstable.rs | 2 + .../rustc_hir/src/attrs/data_structures.rs | 3 - .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 - compiler/rustc_hir/src/hir.rs | 31 +++++-- compiler/rustc_hir/src/intravisit.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 2 +- .../src/check/compare_impl_item.rs | 4 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 25 +++++- .../src/collect/resolve_bound_vars.rs | 2 +- .../rustc_hir_analysis/src/collect/type_of.rs | 8 +- .../src/hir_ty_lowering/bounds.rs | 6 +- .../src/hir_ty_lowering/mod.rs | 13 +-- .../rustc_hir_analysis/src/hir_wf_check.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_lint/src/unused.rs | 4 +- .../src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 3 + compiler/rustc_metadata/src/rmeta/mod.rs | 1 + compiler/rustc_middle/src/queries.rs | 10 ++- compiler/rustc_middle/src/traits/mod.rs | 4 +- compiler/rustc_middle/src/ty/context.rs | 22 +++-- compiler/rustc_mir_build/src/builder/mod.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 80 ++++++++++++------- compiler/rustc_passes/src/check_attr.rs | 1 - compiler/rustc_passes/src/reachable.rs | 8 +- compiler/rustc_resolve/src/late.rs | 63 +++++++-------- compiler/rustc_span/src/symbol.rs | 2 +- .../src/traits/normalize.rs | 2 +- src/librustdoc/clean/mod.rs | 4 +- .../clippy/clippy_lints/src/non_copy_const.rs | 4 +- .../clippy/clippy_lints/src/types/mod.rs | 2 +- .../clippy/clippy_utils/src/ast_utils/mod.rs | 28 ++++--- ...duplication_in_bounds_assoc_const_eq.fixed | 4 +- ...it_duplication_in_bounds_assoc_const_eq.rs | 4 +- src/tools/rustfmt/src/items.rs | 56 ++++++++----- tests/crashes/149809.rs | 3 +- tests/debuginfo/associated-const-bindings.rs | 6 +- .../ice-associated-const-equality-105952.rs | 3 +- .../auxiliary/assoc-const-equality.rs | 3 +- .../associated-constant-not-allowed-102467.rs | 3 +- tests/ui/associated-consts/issue-110933.rs | 3 +- .../type-const-in-array-len-wrong-type.rs | 3 +- .../type-const-in-array-len-wrong-type.stderr | 2 +- .../type-const-in-array-len.rs | 9 +-- .../duplicate-bound-err.rs | 12 +-- .../duplicate-bound-err.stderr | 42 +++++----- .../associated-type-bounds/duplicate-bound.rs | 6 +- .../type-const-inherent-impl-normalize.rs | 6 +- .../type-const-inherent-impl-normalize.stderr | 18 ++++- tests/ui/attributes/malformed-attrs.rs | 2 - tests/ui/attributes/malformed-attrs.stderr | 61 ++++++-------- .../associated-const-bindings/ambiguity.rs | 9 +-- .../ambiguity.stderr | 16 ++-- .../associated-const-bindings/assoc-const.rs | 6 +- .../bound-var-in-ty-not-wf.rs | 3 +- .../bound-var-in-ty-not-wf.stderr | 4 +- .../bound-var-in-ty.rs | 3 +- .../coexisting-with-type-binding.rs | 6 +- .../associated-const-bindings/coherence.rs | 6 +- .../coherence.stderr | 2 +- .../const-projection-err.rs | 3 +- .../const-projection-err.stderr | 4 +- .../const_evaluatable_unchecked.rs | 3 +- ...dyn-compat-assoc-const-ty-mentions-self.rs | 6 +- ...compat-assoc-const-ty-mentions-self.stderr | 12 +-- .../dyn-compat-basic.rs | 15 ++-- .../dyn-compat-const-mismatch.rs | 6 +- .../dyn-compat-const-mismatch.stderr | 2 +- ...ompat-const-param-default-mentions-self.rs | 6 +- ...t-const-param-default-mentions-self.stderr | 2 +- ...ection-behind-trait-alias-mentions-self.rs | 3 +- ...on-behind-trait-alias-mentions-self.stderr | 2 +- ...rojection-from-supertrait-mentions-self.rs | 6 +- ...ction-from-supertrait-mentions-self.stderr | 6 +- .../dyn-compat-non-type-assoc-const.rs | 4 +- .../dyn-compat-non-type-assoc-const.stderr | 8 +- ...und-on-assoc-const-allowed-and-enforced.rs | 6 +- ...on-assoc-const-allowed-and-enforced.stderr | 10 +-- ...elf-const-projections-in-assoc-const-ty.rs | 6 +- ...const-projections-in-assoc-const-ty.stderr | 8 +- ...ompat-self-const-projections-in-methods.rs | 9 +-- ...-const-projections-in-supertrait-bounds.rs | 3 +- ...st-projections-in-supertrait-bounds.stderr | 2 +- .../dyn-compat-symbol-mangling.rs | 3 +- .../dyn-compat-symbol-mangling.v0.stderr | 6 +- .../dyn-compat-unspecified-assoc-consts.rs | 3 +- ...dyn-compat-unspecified-assoc-consts.stderr | 18 ++--- .../equality-unused-issue-126729.rs | 24 ++---- .../equality_bound_with_infer.rs | 6 +- .../esc-bound-var-in-ty.rs | 3 +- .../esc-bound-var-in-ty.stderr | 2 +- .../issue-102335-const.rs | 3 +- .../mismatched-types-with-generic-in-ace.rs | 6 +- ...ismatched-types-with-generic-in-ace.stderr | 16 ++-- .../normalization-via-param-env.rs | 3 +- .../associated-const-bindings/param-in-ty.rs | 6 +- .../param-in-ty.stderr | 22 ++--- .../projection-unspecified-but-bounded.rs | 3 +- .../projection-unspecified-but-bounded.stderr | 4 +- .../associated-const-bindings/supertraits.rs | 3 +- .../using-fnptr-as-type_const.rs | 3 +- .../using-fnptr-as-type_const.stderr | 6 +- .../auxiliary/non_local_type_const.rs | 3 +- .../mgca/adt_expr_arg_simple.rs | 4 +- .../mgca/adt_expr_arg_tuple_expr_fail.rs | 4 +- .../mgca/adt_expr_infers_from_value.rs | 3 +- .../mgca/array-expr-with-assoc-const.rs | 3 +- .../mgca/assoc-const-projection-in-bound.rs | 6 +- .../mgca/assoc-const-without-type_const.rs | 4 +- .../assoc-const-without-type_const.stderr | 22 ++--- tests/ui/const-generics/mgca/assoc-const.rs | 3 +- .../mgca/bad-type_const-syntax.rs | 14 ++-- .../mgca/bad-type_const-syntax.stderr | 40 ++++++---- .../concrete-expr-with-generics-in-env.rs | 18 ++--- ...const-arg-coherence-conflicting-methods.rs | 4 +- .../mgca/cyclic-type-const-151251.rs | 3 +- .../mgca/cyclic-type-const-151251.stderr | 6 +- .../mgca/explicit_anon_consts.rs | 24 +++--- .../mgca/explicit_anon_consts.stderr | 12 +-- .../explicit_anon_consts_literals_hack.rs | 3 +- .../mgca/multi_braced_direct_const_args.rs | 3 +- .../non-local-const-without-type_const.rs | 2 +- .../non-local-const-without-type_const.stderr | 4 +- .../printing_valtrees_supports_non_values.rs | 4 +- .../const-generics/mgca/projection-error.rs | 4 +- .../mgca/projection-error.stderr | 4 +- .../mgca/tuple_ctor_arg_simple.rs | 3 +- .../mgca/tuple_ctor_erroneous.rs | 4 +- .../mgca/tuple_expr_arg_complex.rs | 4 +- .../mgca/tuple_expr_arg_simple.rs | 3 +- .../type-const-assoc-const-without-body.rs | 6 +- ...type-const-assoc-const-without-body.stderr | 10 +-- ...const-inherent-assoc-const-without-body.rs | 3 +- ...t-inherent-assoc-const-without-body.stderr | 10 +-- .../mgca/type-const-used-in-trait.rs | 3 +- .../mgca/type_const-array-return.rs | 6 +- ...pe_const-generic-param-in-type.gate.stderr | 36 ++++----- ..._const-generic-param-in-type.nogate.stderr | 54 ++++++------- .../mgca/type_const-generic-param-in-type.rs | 27 +++---- .../mgca/type_const-incemental-compile.rs | 3 +- .../type_const-inherent-const-omitted-type.rs | 3 +- ...e_const-inherent-const-omitted-type.stderr | 10 +-- .../mgca/type_const-mismatched-types.rs | 12 +-- .../mgca/type_const-mismatched-types.stderr | 22 ++--- .../mgca/type_const-not-constparamty.rs | 9 +-- .../mgca/type_const-not-constparamty.stderr | 18 ++--- .../mgca/type_const-on-generic-expr.rs | 8 +- .../mgca/type_const-on-generic-expr.stderr | 12 +-- .../mgca/type_const-on-generic_expr-2.rs | 18 ++--- .../mgca/type_const-on-generic_expr-2.stderr | 18 ++--- .../type_const-only-in-impl-omitted-type.rs | 5 +- ...ype_const-only-in-impl-omitted-type.stderr | 12 +-- .../mgca/type_const-only-in-impl.rs | 5 +- .../mgca/type_const-only-in-impl.stderr | 6 +- .../mgca/type_const-only-in-trait.rs | 5 +- .../mgca/type_const-only-in-trait.stderr | 12 ++- .../ui/const-generics/mgca/type_const-pub.rs | 3 +- .../mgca/type_const-recursive.rs | 4 +- .../mgca/type_const-recursive.stderr | 4 +- .../ui/const-generics/mgca/type_const-use.rs | 3 +- .../unbraced_const_block_const_arg_gated.rs | 7 +- ...nbraced_const_block_const_arg_gated.stderr | 20 +++-- .../mgca/unmarked-free-const.rs | 2 +- .../mgca/unmarked-free-const.stderr | 11 +-- .../mgca/wrong_type_const_arr_diag_trait.rs | 4 +- tests/ui/const-generics/ogca/basic-fail.rs | 12 +-- .../ui/const-generics/ogca/basic-fail.stderr | 2 +- tests/ui/const-generics/ogca/basic.rs | 12 +-- .../ogca/coherence-ambiguous.rs | 6 +- .../const-generics/ogca/rhs-but-not-root.rs | 6 +- .../ogca/rhs-but-not-root.stderr | 6 +- .../type-relative-path-144547.rs | 14 ++-- .../feature-gate-mgca-type-const-syntax.rs | 17 ++++ ...feature-gate-mgca-type-const-syntax.stderr | 63 +++++++++++++++ .../feature-gate-min-generic-const-args.rs | 6 +- ...feature-gate-min-generic-const-args.stderr | 18 ++++- .../feature-gate-opaque-generic-const-args.rs | 3 +- ...ture-gate-opaque-generic-const-args.stderr | 6 +- .../assoc-const-bindings.rs | 12 +-- .../assoc-const-no-infer-ice-115806.rs | 3 +- .../assoc-const-no-infer-ice-115806.stderr | 2 +- .../assoc-const-projection-issue-151878.rs | 3 +- .../overlap-due-to-unsatisfied-const-bound.rs | 7 +- ...rlap-due-to-unsatisfied-const-bound.stderr | 2 +- 204 files changed, 1014 insertions(+), 906 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-mgca-type-const-syntax.rs create mode 100644 tests/ui/feature-gates/feature-gate-mgca-type-const-syntax.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fea87c2360f1..fa323b7cf581 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3869,27 +3869,44 @@ pub struct ConstItem { pub ident: Ident, pub generics: Generics, pub ty: Box, - pub rhs: Option, + pub rhs_kind: ConstItemRhsKind, pub define_opaque: Option>, } #[derive(Clone, Encodable, Decodable, Debug, Walkable)] -pub enum ConstItemRhs { - TypeConst(AnonConst), - Body(Box), +pub enum ConstItemRhsKind { + Body { rhs: Option> }, + TypeConst { rhs: Option }, } -impl ConstItemRhs { - pub fn span(&self) -> Span { - self.expr().span +impl ConstItemRhsKind { + pub fn new_body(rhs: Box) -> Self { + Self::Body { rhs: Some(rhs) } } - pub fn expr(&self) -> &Expr { + pub fn span(&self) -> Option { + Some(self.expr()?.span) + } + + pub fn expr(&self) -> Option<&Expr> { match self { - ConstItemRhs::TypeConst(anon_const) => &anon_const.value, - ConstItemRhs::Body(expr) => expr, + Self::Body { rhs: Some(body) } => Some(&body), + Self::TypeConst { rhs: Some(anon) } => Some(&anon.value), + _ => None, } } + + pub fn has_expr(&self) -> bool { + match self { + Self::Body { rhs: Some(_) } => true, + Self::TypeConst { rhs: Some(_) } => true, + _ => false, + } + } + + pub fn is_type_const(&self) -> bool { + matches!(self, &Self::TypeConst { .. }) + } } #[derive(Clone, Encodable, Decodable, Debug, Walkable)] diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 51614460d3c4..8556e8288670 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -427,7 +427,7 @@ macro_rules! common_visitor_and_walkers { Const, ConstBlockItem, ConstItem, - ConstItemRhs, + ConstItemRhsKind, Defaultness, Delegation, DelegationMac, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 12eaa99143e9..9922ed8a5c58 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -288,7 +288,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ident, generics, ty, - rhs, + rhs_kind, define_opaque, }) => { let ident = self.lower_ident(*ident); @@ -301,7 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy), ); - let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), span); + let rhs = this.lower_const_item_rhs(rhs_kind, span); (ty, rhs) }, ); @@ -941,7 +941,12 @@ impl<'hir> LoweringContext<'_, 'hir> { let (ident, generics, kind, has_default) = match &i.kind { AssocItemKind::Const(box ConstItem { - ident, generics, ty, rhs, define_opaque, .. + ident, + generics, + ty, + rhs_kind, + define_opaque, + .. }) => { let (generics, kind) = self.lower_generics( generics, @@ -952,15 +957,18 @@ impl<'hir> LoweringContext<'_, 'hir> { ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy), ); - let rhs = rhs - .as_ref() - .map(|rhs| this.lower_const_item_rhs(attrs, Some(rhs), i.span)); - hir::TraitItemKind::Const(ty, rhs) + // Trait associated consts don't need an expression/body. + let rhs = if rhs_kind.has_expr() { + Some(this.lower_const_item_rhs(rhs_kind, i.span)) + } else { + None + }; + hir::TraitItemKind::Const(ty, rhs, rhs_kind.is_type_const().into()) }, ); if define_opaque.is_some() { - if rhs.is_some() { + if rhs_kind.has_expr() { self.lower_define_opaque(hir_id, &define_opaque); } else { self.dcx().span_err( @@ -970,7 +978,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - (*ident, generics, kind, rhs.is_some()) + (*ident, generics, kind, rhs_kind.has_expr()) } AssocItemKind::Fn(box Fn { sig, ident, generics, body: None, define_opaque, .. @@ -1154,7 +1162,12 @@ impl<'hir> LoweringContext<'_, 'hir> { let (ident, (generics, kind)) = match &i.kind { AssocItemKind::Const(box ConstItem { - ident, generics, ty, rhs, define_opaque, .. + ident, + generics, + ty, + rhs_kind, + define_opaque, + .. }) => ( *ident, self.lower_generics( @@ -1167,7 +1180,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy), ); this.lower_define_opaque(hir_id, &define_opaque); - let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), i.span); + let rhs = this.lower_const_item_rhs(rhs_kind, i.span); hir::ImplItemKind::Const(ty, rhs) }, ), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 6dded9936fba..ff5edfc79943 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2374,15 +2374,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_const_item_rhs( &mut self, - attrs: &[hir::Attribute], - rhs: Option<&ConstItemRhs>, + rhs_kind: &ConstItemRhsKind, span: Span, ) -> hir::ConstItemRhs<'hir> { - match rhs { - Some(ConstItemRhs::TypeConst(anon)) => { + match rhs_kind { + ConstItemRhsKind::Body { rhs: Some(body) } => { + hir::ConstItemRhs::Body(self.lower_const_body(span, Some(body))) + } + ConstItemRhsKind::Body { rhs: None } => { + hir::ConstItemRhs::Body(self.lower_const_body(span, None)) + } + ConstItemRhsKind::TypeConst { rhs: Some(anon) } => { hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg_and_alloc(anon)) } - None if find_attr!(attrs, AttributeKind::TypeConst(_)) => { + ConstItemRhsKind::TypeConst { rhs: None } => { let const_arg = ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Error( @@ -2392,10 +2397,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg)) } - Some(ConstItemRhs::Body(body)) => { - hir::ConstItemRhs::Body(self.lower_const_body(span, Some(body))) - } - None => hir::ConstItemRhs::Body(self.lower_const_body(span, None)), } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 2457e0a777e4..b9fb20b68971 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1361,9 +1361,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } }); } - ItemKind::Const(box ConstItem { defaultness, ident, rhs, .. }) => { + ItemKind::Const(box ConstItem { defaultness, ident, rhs_kind, .. }) => { self.check_defaultness(item.span, *defaultness); - if rhs.is_none() { + if !rhs_kind.has_expr() { self.dcx().emit_err(errors::ConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), @@ -1715,11 +1715,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let AssocCtxt::Impl { .. } = ctxt { match &item.kind { - AssocItemKind::Const(box ConstItem { rhs: None, .. }) => { - self.dcx().emit_err(errors::AssocConstWithoutBody { - span: item.span, - replace_span: self.ending_semi_or_hi(item.span), - }); + AssocItemKind::Const(box ConstItem { rhs_kind, .. }) => { + if !rhs_kind.has_expr() { + self.dcx().emit_err(errors::AssocConstWithoutBody { + span: item.span, + replace_span: self.ending_semi_or_hi(item.span), + }); + } } AssocItemKind::Fn(box Fn { body, .. }) => { if body.is_none() && !self.is_sdylib_interface { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index ce9001d65931..eac7f03d8450 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -249,6 +249,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => { self.check_impl_trait(ty, false) } + ast::ItemKind::Const(box ast::ConstItem { + rhs_kind: ast::ConstItemRhsKind::TypeConst { .. }, + .. + }) => { + // Make sure this is only allowed if the feature gate is enabled. + // #![feature(min_generic_const_args)] + gate!(&self, min_generic_const_args, i.span, "top-level `type const` are unstable"); + } _ => {} } @@ -422,6 +430,20 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } false } + ast::AssocItemKind::Const(box ast::ConstItem { + rhs_kind: ast::ConstItemRhsKind::TypeConst { .. }, + .. + }) => { + // Make sure this is only allowed if the feature gate is enabled. + // #![feature(min_generic_const_args)] + gate!( + &self, + min_generic_const_args, + i.span, + "associated `type const` are unstable" + ); + false + } _ => false, }; if let ast::Defaultness::Default(_) = i.kind.defaultness() { @@ -528,6 +550,27 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { } } } + // `mgca_type_const_syntax` is part of `min_generic_const_args` so either + // or both are enabled we don't need to emit a feature error. + if let Some(spans) = spans.get(&sym::mgca_type_const_syntax) { + for span in spans { + if visitor.features.min_generic_const_args() + || visitor.features.mgca_type_const_syntax() + || span.allows_unstable(sym::min_generic_const_args) + || span.allows_unstable(sym::mgca_type_const_syntax) + { + continue; + } + feature_err( + &visitor.sess, + sym::min_generic_const_args, + *span, + "`type const` syntax is experimental", + ) + .emit(); + } + } + gate_all!(global_registration, "global registration is experimental"); gate_all!(return_type_notation, "return type notation is experimental"); gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 68054b06e39f..c7f110a2e003 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -221,7 +221,7 @@ impl<'a> State<'a> { ident, generics, ty, - rhs, + rhs_kind, define_opaque, }) => { self.print_item_const( @@ -229,7 +229,7 @@ impl<'a> State<'a> { None, generics, ty, - rhs.as_ref().map(|ct| ct.expr()), + rhs_kind.expr(), &item.vis, ast::Safety::Default, *defaultness, @@ -573,7 +573,7 @@ impl<'a> State<'a> { ident, generics, ty, - rhs, + rhs_kind, define_opaque, }) => { self.print_item_const( @@ -581,7 +581,7 @@ impl<'a> State<'a> { None, generics, ty, - rhs.as_ref().map(|ct| ct.expr()), + rhs_kind.expr(), vis, ast::Safety::Default, *defaultness, diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index bfea02e789a0..ceaa43948d67 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -66,15 +66,6 @@ impl NoArgsAttributeParser for ParenSugarParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcParenSugar; } -pub(crate) struct TypeConstParser; -impl NoArgsAttributeParser for TypeConstParser { - const PATH: &[Symbol] = &[sym::type_const]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets = - AllowedTargets::AllowList(&[Allow(Target::Const), Allow(Target::AssocConst)]); - const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst; -} - // Markers pub(crate) struct MarkerParser; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index afbb70654f4d..5c3368e4c930 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -297,7 +297,6 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, Single>, // tidy-alphabetical-end ]; diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 12ccc4a6de04..c87f1e41043d 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -43,7 +43,7 @@ pub(crate) fn expand( // Generate anonymous constant serving as container for the allocator methods. let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new())); - let const_body = ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))); + let const_body = ast::ConstItemRhsKind::new_body(ecx.expr_block(ecx.block(span, stmts))); let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 538f5afae5fc..7b651ed84828 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -232,7 +232,7 @@ fn generate_default_impl( span, underscore, unit, - ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))), + ast::ConstItemRhsKind::new_body(ecx.expr_block(ecx.block(span, stmts))), ) }; diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index bb031dafdcfd..9e22d408c125 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -47,7 +47,7 @@ pub(crate) fn expand( // Generate anonymous constant serving as container for the allocator methods. let const_ty = ecx.ty(ty_span, TyKind::Tup(ThinVec::new())); - let const_body = ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))); + let const_body = ast::ConstItemRhsKind::new_body(ecx.expr_block(ecx.block(span, stmts))); let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index e30d506a31b9..24a5d79958c6 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -385,7 +385,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box { cx.attr_nested_word(sym::allow, sym::deprecated, span), ]); - let block = ast::ConstItemRhs::Body(cx.expr_block( + let block = ast::ConstItemRhsKind::new_body(cx.expr_block( cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]), )); diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index d5f774865a9e..a9718d53ac49 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -289,7 +289,7 @@ pub(crate) fn expand_test_or_bench( ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), define_opaque: None, // test::TestDescAndFn { - rhs: Some(ast::ConstItemRhs::Body( + rhs_kind: ast::ConstItemRhsKind::new_body( cx.expr_struct( sp, test_path("TestDescAndFn"), @@ -371,7 +371,7 @@ pub(crate) fn expand_test_or_bench( field("testfn", test_fn), // } ], ), // } - )), + ), } .into(), ), diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index fe3891d0dd7e..462254f064cf 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -345,7 +345,7 @@ where let uneval = match constant.const_ { Const::Ty(_, ct) => match ct.kind() { ty::ConstKind::Param(_) | ty::ConstKind::Error(_) => None, - // Unevaluated consts in MIR bodies don't have associated MIR (e.g. `#[type_const]`). + // Unevaluated consts in MIR bodies don't have associated MIR (e.g. `type const`). ty::ConstKind::Unevaluated(_) => None, // FIXME(mgca): Investigate whether using `None` for `ConstKind::Value` is overly // strict, and if instead we should be doing some kind of value-based analysis. diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 25da90298791..9f39750d8125 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -394,7 +394,7 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>( typing_env: ty::TypingEnv<'tcx>, ) -> Result { let def = cid.instance.def.def_id(); - // #[type_const] don't have bodys + // `type const` don't have bodys debug_assert!(!tcx.is_type_const(def), "CTFE tried to evaluate type-const: {:?}", def); let is_static = tcx.is_static(def); diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index e5c06889f3e0..7320ee12abe3 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -727,7 +727,7 @@ impl<'a> ExtCtxt<'a> { span: Span, ident: Ident, ty: Box, - rhs: ast::ConstItemRhs, + rhs_kind: ast::ConstItemRhsKind, ) -> Box { let defaultness = ast::Defaultness::Final; self.item( @@ -740,7 +740,7 @@ impl<'a> ExtCtxt<'a> { // FIXME(generic_const_items): Pass the generics as a parameter. generics: ast::Generics::default(), ty, - rhs: Some(rhs), + rhs_kind, define_opaque: None, } .into(), diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 182ef6816337..d74e8442545b 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -888,13 +888,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::Yes, experimental!(patchable_function_entry) ), - // Probably temporary component of min_generic_const_args. - // `#[type_const] const ASSOC: usize;` - gated!( - type_const, Normal, template!(Word), ErrorFollowing, - EncodeCrossCrate::Yes, min_generic_const_args, experimental!(type_const), - ), - // The `#[loop_match]` and `#[const_continue]` attributes are part of the // lang experiment for RFC 3720 tracked in: // diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index a941eb1f459e..add09c3ea58b 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -561,6 +561,8 @@ declare_features! ( (unstable, macro_metavar_expr_concat, "1.81.0", Some(124225)), /// Allows `#[marker]` on certain traits allowing overlapping implementations. (unstable, marker_trait_attr, "1.30.0", Some(29864)), + /// Enable mgca `type const` syntax before expansion. + (incomplete, mgca_type_const_syntax, "CURRENT_RUSTC_VERSION", Some(132980)), /// Enables the generic const args MVP (only bare paths, not arbitrary computation). (incomplete, min_generic_const_args, "1.84.0", Some(132980)), /// A minimal, sound subset of specialization intended to be used by the diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index ef790fe76b74..58a748b9568a 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1292,9 +1292,6 @@ pub enum AttributeKind { /// Represents `#[track_caller]` TrackCaller(Span), - /// Represents `#[type_const]`. - TypeConst(Span), - /// Represents `#[type_length_limit]` TypeLengthLimit { attr_span: Span, limit_span: Span, limit: Limit }, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index cba7679d2df3..7d8ac6df9e3a 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -169,7 +169,6 @@ impl AttributeKind { TargetFeature { .. } => No, ThreadLocal => No, TrackCaller(..) => Yes, - TypeConst(..) => Yes, TypeLengthLimit { .. } => No, UnstableFeatureBound(..) => No, Used { .. } => No, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index cf96f33e9891..68fc7653b636 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3199,7 +3199,7 @@ impl<'hir> TraitItem<'hir> { expect_methods_self_kind! { expect_const, (&'hir Ty<'hir>, Option>), - TraitItemKind::Const(ty, rhs), (ty, *rhs); + TraitItemKind::Const(ty, rhs, _), (ty, *rhs); expect_fn, (&FnSig<'hir>, &TraitFn<'hir>), TraitItemKind::Fn(ty, trfn), (ty, trfn); @@ -3219,11 +3219,32 @@ pub enum TraitFn<'hir> { Provided(BodyId), } +#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)] +pub enum IsTypeConst { + No, + Yes, +} + +impl From for IsTypeConst { + fn from(value: bool) -> Self { + if value { Self::Yes } else { Self::No } + } +} + +impl From for bool { + fn from(value: IsTypeConst) -> Self { + matches!(value, IsTypeConst::Yes) + } +} + /// Represents a trait method or associated constant or type #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TraitItemKind<'hir> { + // FIXME(mgca) eventually want to move the option that is around `ConstItemRhs<'hir>` + // into `ConstItemRhs`, much like `ast::ConstItemRhsKind`, but for now mark whether + // this node is a TypeConst with a flag. /// An associated constant with an optional value (otherwise `impl`s must contain a value). - Const(&'hir Ty<'hir>, Option>), + Const(&'hir Ty<'hir>, Option>, IsTypeConst), /// An associated function with an optional body. Fn(FnSig<'hir>, TraitFn<'hir>), /// An associated type with (possibly empty) bounds and optional concrete @@ -4686,7 +4707,7 @@ impl<'hir> OwnerNode<'hir> { | OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(_, TraitFn::Provided(body)) - | TraitItemKind::Const(_, Some(ConstItemRhs::Body(body))), + | TraitItemKind::Const(_, Some(ConstItemRhs::Body(body)), _), .. }) | OwnerNode::ImplItem(ImplItem { @@ -4913,7 +4934,7 @@ impl<'hir> Node<'hir> { _ => None, }, Node::TraitItem(it) => match it.kind { - TraitItemKind::Const(ty, _) => Some(ty), + TraitItemKind::Const(ty, _, _) => Some(ty), TraitItemKind::Type(_, ty) => ty, _ => None, }, @@ -4956,7 +4977,7 @@ impl<'hir> Node<'hir> { | Node::TraitItem(TraitItem { owner_id, kind: - TraitItemKind::Const(.., Some(ConstItemRhs::Body(body))) + TraitItemKind::Const(_, Some(ConstItemRhs::Body(body)), _) | TraitItemKind::Fn(_, TraitFn::Provided(body)), .. }) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index bd863abaceb4..21bcf53b5619 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1271,7 +1271,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>( try_visit!(visitor.visit_defaultness(&defaultness)); try_visit!(visitor.visit_id(hir_id)); match *kind { - TraitItemKind::Const(ref ty, default) => { + TraitItemKind::Const(ref ty, default, _) => { try_visit!(visitor.visit_ty_unambig(ty)); visit_opt!(visitor, visit_const_item_rhs, default); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index e0bfae9617ff..1bee7a72229a 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -923,7 +923,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ); check_where_clauses(wfcx, def_id); - if tcx.is_type_const(def_id.into()) { + if tcx.is_type_const(def_id) { wfcheck::check_type_const(wfcx, def_id, ty, true)?; } Ok(()) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index cd9fdcb59fb5..c29ebe67a158 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2060,14 +2060,14 @@ fn compare_type_const<'tcx>( .dcx() .struct_span_err( tcx.def_span(impl_const_item.def_id), - "implementation of `#[type_const]` const must be marked with `#[type_const]`", + "implementation of a `type const` must also be marked as `type const`", ) .with_span_note( MultiSpan::from_spans(vec![ tcx.def_span(trait_const_item.def_id), trait_type_const_span, ]), - "trait declaration of const is marked with `#[type_const]`", + "trait declaration of const is marked as `type const`", ) .emit()); } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index f917c799ef5a..ceb0e138a0da 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -955,7 +955,7 @@ pub(crate) fn check_associated_item( wfcx.register_wf_obligation(span, loc, ty.into()); let has_value = item.defaultness(tcx).has_value(); - if tcx.is_type_const(def_id.into()) { + if tcx.is_type_const(def_id) { check_type_const(wfcx, def_id, ty, has_value)?; } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f3086266eec0..e72fde9f0568 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -95,6 +95,7 @@ pub(crate) fn provide(providers: &mut Providers) { const_param_default, anon_const_kind, const_of_item, + is_rhs_type_const, ..*providers }; } @@ -1549,7 +1550,8 @@ fn is_anon_const_rhs_of_const_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) let (Node::Item(hir::Item { kind: hir::ItemKind::Const(_, _, _, ct_rhs), .. }) | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(_, ct_rhs), .. }) | Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Const(_, Some(ct_rhs)), .. + kind: hir::TraitItemKind::Const(_, Some(ct_rhs), _), + .. })) = grandparent_node else { return false; @@ -1594,7 +1596,7 @@ fn const_of_item<'tcx>( let ct_rhs = match tcx.hir_node_by_def_id(def_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(.., ct), .. }) => *ct, hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Const(.., ct), .. + kind: hir::TraitItemKind::Const(_, ct, _), .. }) => ct.expect("no default value for trait assoc const"), hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(.., ct), .. }) => *ct, _ => { @@ -1624,3 +1626,22 @@ fn const_of_item<'tcx>( ty::EarlyBinder::bind(ct) } } + +/// Check if a Const or AssocConst is a type const (mgca) +fn is_rhs_type_const<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> bool { + match tcx.hir_node_by_def_id(def) { + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Const(_, _, _, hir::ConstItemRhs::TypeConst(_)), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Const(_, hir::ConstItemRhs::TypeConst(_)), + .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Const(_, _, hir::IsTypeConst::Yes), + .. + }) => return true, + _ => return false, + } +} 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 d4a01d26a1fc..3e687700f11c 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -859,7 +859,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } }) } - Const(_, _) => self.visit_early(trait_item.hir_id(), trait_item.generics, |this| { + Const(_, _, _) => self.visit_early(trait_item.hir_id(), trait_item.generics, |this| { intravisit::walk_trait_item(this, trait_item) }), } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 910176a0689c..23df419d06a7 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -63,7 +63,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, def_id.to_def_id(), args) } - TraitItemKind::Const(ty, rhs) => rhs + TraitItemKind::Const(ty, rhs, _) => rhs .and_then(|rhs| { ty.is_suggestable_infer_ty().then(|| { infer_placeholder_type( @@ -420,9 +420,9 @@ fn infer_placeholder_type<'tcx>( kind: &'static str, ) -> Ty<'tcx> { let tcx = cx.tcx(); - // If the type is omitted on a #[type_const] we can't run + // If the type is omitted on a `type const` we can't run // type check on since that requires the const have a body - // which type_consts don't. + // which `type const`s don't. let ty = if tcx.is_type_const(def_id.to_def_id()) { if let Some(trait_item_def_id) = tcx.trait_item_of(def_id.to_def_id()) { tcx.type_of(trait_item_def_id).instantiate_identity() @@ -430,7 +430,7 @@ fn infer_placeholder_type<'tcx>( Ty::new_error_with_message( tcx, ty_span, - "constant with #[type_const] requires an explicit type", + "constant with `type const` requires an explicit type", ) } } else { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index a1c3af5f999d..4a03b290c33d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -607,14 +607,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if tcx.features().min_generic_const_args() { let mut err = self.dcx().struct_span_err( constraint.span, - "use of trait associated const without `#[type_const]`", + "use of trait associated const not defined as `type const`", ); - err.note("the declaration in the trait must be marked with `#[type_const]`"); + err.note("the declaration in the trait must begin with `type const` not just `const` alone"); return Err(err.emit()); } else { let err = self.dcx().span_delayed_bug( constraint.span, - "use of trait associated const without `#[type_const]`", + "use of trait associated const defined as `type const`", ); return Err(err); } 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 7a03d8b220c5..f58461e5d0e1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2849,19 +2849,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if tcx.is_type_const(def_id) { Ok(()) } else { - let mut err = self - .dcx() - .struct_span_err(span, "use of `const` in the type system without `#[type_const]`"); + let mut err = self.dcx().struct_span_err( + span, + "use of `const` in the type system not defined as `type const`", + ); if def_id.is_local() { let name = tcx.def_path_str(def_id); err.span_suggestion( tcx.def_span(def_id).shrink_to_lo(), - format!("add `#[type_const]` attribute to `{name}`"), - format!("#[type_const]\n"), + format!("add `type` before `const` for `{name}`"), + format!("type "), Applicability::MaybeIncorrect, ); } else { - err.note("only consts marked with `#[type_const]` may be used in types"); + err.note("only consts marked defined as `type const` may be used in types"); } Err(err.emit()) } diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index d414f4dbcc24..08da8d19344d 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -139,7 +139,7 @@ pub(super) fn diagnostic_hir_wf_check<'tcx>( }, hir::Node::TraitItem(item) => match item.kind { hir::TraitItemKind::Type(_, ty) => ty.into_iter().collect(), - hir::TraitItemKind::Const(ty, _) => vec![ty], + hir::TraitItemKind::Const(ty, _, _) => vec![ty], ref item => bug!("Unexpected TraitItem {:?}", item), }, hir::Node::Item(item) => match item.kind { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 28130383e94c..6214106d422b 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -233,7 +233,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { } DefKind::Const if !tcx.generics_of(item_def_id).own_requires_monomorphization() - && !tcx.is_type_const(item_def_id.into()) => + && !tcx.is_type_const(item_def_id) => { // FIXME(generic_const_items): Passing empty instead of identity args is fishy but // seems to be fine for now. Revisit this! diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index d045ec0eb6c7..fc6cc4e67251 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -937,7 +937,7 @@ impl<'a> State<'a> { self.maybe_print_comment(ti.span.lo()); self.print_attrs(self.attrs(ti.hir_id())); match ti.kind { - hir::TraitItemKind::Const(ty, default) => { + hir::TraitItemKind::Const(ty, default, _) => { self.print_associated_const(ti.ident, ti.generics, ty, default); } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(arg_idents)) => { diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 51d9a4641cd5..8b2a6d1d2ab5 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1058,8 +1058,8 @@ trait UnusedDelimLint { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { use ast::ItemKind::*; - let expr = if let Const(box ast::ConstItem { rhs: Some(rhs), .. }) = &item.kind { - rhs.expr() + let expr = if let Const(box ast::ConstItem { rhs_kind, .. }) = &item.kind { + if let Some(e) = rhs_kind.expr() { e } else { return } } else if let Static(box ast::StaticItem { expr: Some(expr), .. }) = &item.kind { expr } else { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index c6c87534851c..6ea9a2852804 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -418,6 +418,7 @@ provide! { tcx, def_id, other, cdata, } anon_const_kind => { table } const_of_item => { table } + is_rhs_type_const => { table } } pub(in crate::rmeta) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d8652539d0c5..4988cafdd363 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1630,6 +1630,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let table = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id); record!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table); } + if let DefKind::AssocConst | DefKind::Const = def_kind { + record!(self.tables.is_rhs_type_const[def_id] <- self.tcx.is_rhs_type_const(def_id)); + } } for (def_id, impls) in &tcx.crate_inherent_impls(()).0.inherent_impls { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index af6df0cd6eb6..408b50ae48df 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -476,6 +476,7 @@ define_tables! { anon_const_kind: Table>, const_of_item: Table>>>, associated_types_for_impl_traits_in_trait_or_impl: Table>>>, + is_rhs_type_const: Table>, } #[derive(TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index de2298914438..771c300989f2 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -293,13 +293,13 @@ rustc_queries! { separate_provide_extern } - /// Returns the const of the RHS of a (free or assoc) const item, if it is a `#[type_const]`. + /// Returns the const of the RHS of a (free or assoc) const item, if it is a `type const`. /// /// When a const item is used in a type-level expression, like in equality for an assoc const /// projection, this allows us to retrieve the typesystem-appropriate representation of the /// const value. /// - /// This query will ICE if given a const that is not marked with `#[type_const]`. + /// This query will ICE if given a const that is not marked with `type const`. query const_of_item(def_id: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { desc { |tcx| "computing the type-level value for `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } @@ -2764,6 +2764,12 @@ rustc_queries! { cache_on_disk_if { *cnum == LOCAL_CRATE } separate_provide_extern } + + query is_rhs_type_const(def_id: DefId) -> bool { + desc { |tcx| "checking whether `{}` is a rhs type const", tcx.def_path_str(def_id) } + cache_on_disk_if { def_id.is_local() } + separate_provide_extern + } } rustc_with_all_queries! { define_callbacks! } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 75323bf5c8cc..2fca85c9f2f1 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -845,7 +845,7 @@ impl DynCompatibilityViolation { format!("it contains generic associated const `{name}`").into() } Self::AssocConst(name, AssocConstViolation::NonType, _) => { - format!("it contains associated const `{name}` that's not marked `#[type_const]`") + format!("it contains associated const `{name}` that's not defined as `type const`") .into() } Self::AssocConst(name, AssocConstViolation::TypeReferencesSelf, _) => format!( @@ -999,7 +999,7 @@ pub enum AssocConstViolation { /// Has own generic parameters (GAC). Generic, - /// Isn't marked `#[type_const]`. + /// Isn't defined as `type const`. NonType, /// Its type mentions the `Self` type parameter. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1bb83530487d..45bb584bf595 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1890,14 +1890,22 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn type_const_span(self, def_id: DefId) -> Option { - matches!(self.def_kind(def_id), DefKind::Const | DefKind::AssocConst) - .then(|| find_attr!(self.get_all_attrs(def_id), AttributeKind::TypeConst(sp) => *sp)) - .flatten() + if !self.is_type_const(def_id) { + return None; + } + Some(self.def_span(def_id)) } - /// Check if the given `def_id` is a const with the `#[type_const]` attribute. - pub fn is_type_const(self, def_id: DefId) -> bool { - self.type_const_span(def_id).is_some() + /// Check if the given `def_id` is a `type const` (mgca) + pub fn is_type_const>(self, def_id: I) -> bool { + // No need to call the query directly in this case always false. + if !(matches!( + self.def_kind(def_id.into_query_param()), + DefKind::Const | DefKind::AssocConst + )) { + return false; + } + self.is_rhs_type_const(def_id) } /// Returns the movability of the coroutine of `def_id`, or panics @@ -2923,7 +2931,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> bool { let generics = self.generics_of(def_id); - // IATs and IACs (inherent associated types/consts with #[type_const]) themselves have a + // IATs and IACs (inherent associated types/consts with `type const`) themselves have a // weird arg setup (self + own args), but nested items *in* IATs (namely: opaques, i.e. // ATPITs) do not. let is_inherent_assoc_ty = matches!(self.def_kind(def_id), DefKind::AssocTy) diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 317df4e64fdb..fbd7aa90f49c 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -578,7 +578,7 @@ fn construct_const<'a, 'tcx>( }) | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(ty, _), span, .. }) | Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Const(ty, Some(_)), + kind: hir::TraitItemKind::Const(ty, Some(_), _), span, .. }) => (*span, ty.span), diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 9ac9bd5c0e46..5b81acb0f91f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -6,9 +6,7 @@ use rustc_ast::ast::*; use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::util::case::Case; -use rustc_ast::{ - attr, {self as ast}, -}; +use rustc_ast::{self as ast}; use rustc_ast_pretty::pprust; use rustc_errors::codes::*; use rustc_errors::{Applicability, PResult, StashKey, inline_fluent, struct_span_code_err}; @@ -286,13 +284,13 @@ impl<'a> Parser<'a> { // CONST ITEM self.recover_const_mut(const_span); self.recover_missing_kw_before_item()?; - let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?; + let (ident, generics, ty, rhs_kind) = self.parse_const_item(false)?; ItemKind::Const(Box::new(ConstItem { defaultness: def_(), ident, generics, ty, - rhs, + rhs_kind, define_opaque: None, })) } else if let Some(kind) = self.is_reuse_item() { @@ -303,8 +301,26 @@ impl<'a> Parser<'a> { // MODULE ITEM self.parse_item_mod(attrs)? } else if self.eat_keyword_case(exp!(Type), case) { - // TYPE ITEM - self.parse_type_alias(def_())? + if let Const::Yes(const_span) = self.parse_constness(case) { + // TYPE CONST (mgca) + self.recover_const_mut(const_span); + self.recover_missing_kw_before_item()?; + let (ident, generics, ty, rhs_kind) = self.parse_const_item(true)?; + // Make sure this is only allowed if the feature gate is enabled. + // #![feature(mgca_type_const_syntax)] + self.psess.gated_spans.gate(sym::mgca_type_const_syntax, lo.to(const_span)); + ItemKind::Const(Box::new(ConstItem { + defaultness: def_(), + ident, + generics, + ty, + rhs_kind, + define_opaque: None, + })) + } else { + // TYPE ITEM + self.parse_type_alias(def_())? + } } else if self.eat_keyword_case(exp!(Enum), case) { // ENUM ITEM self.parse_item_enum()? @@ -1113,13 +1129,12 @@ impl<'a> Parser<'a> { define_opaque, }) => { self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span }); - let rhs = expr.map(ConstItemRhs::Body); AssocItemKind::Const(Box::new(ConstItem { defaultness: Defaultness::Final, ident, generics: Generics::default(), ty, - rhs, + rhs_kind: ConstItemRhsKind::Body { rhs: expr }, define_opaque, })) } @@ -1360,7 +1375,7 @@ impl<'a> Parser<'a> { let kind = match ForeignItemKind::try_from(kind) { Ok(kind) => kind, Err(kind) => match kind { - ItemKind::Const(box ConstItem { ident, ty, rhs, .. }) => { + ItemKind::Const(box ConstItem { ident, ty, rhs_kind, .. }) => { let const_span = Some(span.with_hi(ident.span.lo())) .filter(|span| span.can_be_used_for_suggestions()); self.dcx().emit_err(errors::ExternItemCannotBeConst { @@ -1371,10 +1386,13 @@ impl<'a> Parser<'a> { ident, ty, mutability: Mutability::Not, - expr: rhs.map(|b| match b { - ConstItemRhs::TypeConst(anon_const) => anon_const.value, - ConstItemRhs::Body(expr) => expr, - }), + expr: match rhs_kind { + ConstItemRhsKind::Body { rhs } => rhs, + ConstItemRhsKind::TypeConst { rhs: Some(anon) } => { + Some(anon.value) + } + ConstItemRhsKind::TypeConst { rhs: None } => None, + }, safety: Safety::Default, define_opaque: None, })) @@ -1516,13 +1534,16 @@ impl<'a> Parser<'a> { /// Parse a constant item with the prefix `"const"` already parsed. /// + /// If `const_arg` is true, any expression assigned to the const will be parsed + /// as a const_arg instead of a body expression. + /// /// ```ebnf /// Const = "const" ($ident | "_") Generics ":" $ty (= $expr)? WhereClause ";" ; /// ``` fn parse_const_item( &mut self, - attrs: &[Attribute], - ) -> PResult<'a, (Ident, Generics, Box, Option)> { + const_arg: bool, + ) -> PResult<'a, (Ident, Generics, Box, ConstItemRhsKind)> { let ident = self.parse_ident_or_underscore()?; let mut generics = self.parse_generics()?; @@ -1549,16 +1570,15 @@ impl<'a> Parser<'a> { let before_where_clause = if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() }; - let rhs = if self.eat(exp!(Eq)) { - if attr::contains_name(attrs, sym::type_const) { - let ct = - self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?; - Some(ConstItemRhs::TypeConst(ct)) - } else { - Some(ConstItemRhs::Body(self.parse_expr()?)) - } - } else { - None + let rhs = match (self.eat(exp!(Eq)), const_arg) { + (true, true) => ConstItemRhsKind::TypeConst { + rhs: Some( + self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))?, + ), + }, + (true, false) => ConstItemRhsKind::Body { rhs: Some(self.parse_expr()?) }, + (false, true) => ConstItemRhsKind::TypeConst { rhs: None }, + (false, false) => ConstItemRhsKind::Body { rhs: None }, }; let after_where_clause = self.parse_where_clause()?; @@ -1567,18 +1587,18 @@ impl<'a> Parser<'a> { // Users may be tempted to write such code if they are still used to the deprecated // where-clause location on type aliases and associated types. See also #89122. if before_where_clause.has_where_token - && let Some(rhs) = &rhs + && let Some(rhs_span) = rhs.span() { self.dcx().emit_err(errors::WhereClauseBeforeConstBody { span: before_where_clause.span, name: ident.span, - body: rhs.span(), + body: rhs_span, sugg: if !after_where_clause.has_where_token { - self.psess.source_map().span_to_snippet(rhs.span()).ok().map(|body_s| { + self.psess.source_map().span_to_snippet(rhs_span).ok().map(|body_s| { errors::WhereClauseBeforeConstBodySugg { left: before_where_clause.span.shrink_to_lo(), snippet: body_s, - right: before_where_clause.span.shrink_to_hi().to(rhs.span()), + right: before_where_clause.span.shrink_to_hi().to(rhs_span), } }) } else { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index dd0de90d575b..e53922e3734b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -356,7 +356,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcVarianceOfOpaques | AttributeKind::ShouldPanic { .. } | AttributeKind::ThreadLocal - | AttributeKind::TypeConst{..} | AttributeKind::TypeLengthLimit { .. } | AttributeKind::UnstableFeatureBound(..) | AttributeKind::Used { .. } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index d9565e2dae0e..225487cc989f 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -145,7 +145,7 @@ impl<'tcx> ReachableContext<'tcx> { _ => false, }, Node::TraitItem(trait_method) => match trait_method.kind { - hir::TraitItemKind::Const(_, ref default) => default.is_some(), + hir::TraitItemKind::Const(_, ref default, _) => default.is_some(), hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => true, hir::TraitItemKind::Fn(_, hir::TraitFn::Required(_)) | hir::TraitItemKind::Type(..) => false, @@ -209,7 +209,7 @@ impl<'tcx> ReachableContext<'tcx> { self.visit_nested_body(body); } } - // For #[type_const] we want to evaluate the RHS. + // For `type const` we want to evaluate the RHS. hir::ItemKind::Const(_, _, _, init @ hir::ConstItemRhs::TypeConst(_)) => { self.visit_const_item_rhs(init); } @@ -258,11 +258,11 @@ impl<'tcx> ReachableContext<'tcx> { } Node::TraitItem(trait_method) => { match trait_method.kind { - hir::TraitItemKind::Const(_, None) + hir::TraitItemKind::Const(_, None, _) | hir::TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => { // Keep going, nothing to get exported } - hir::TraitItemKind::Const(_, Some(rhs)) => self.visit_const_item_rhs(rhs), + hir::TraitItemKind::Const(_, Some(rhs), _) => self.visit_const_item_rhs(rhs), hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)) => { self.visit_nested_body(body_id); } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 4faf7715de6e..fe6346f6c6e9 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2847,11 +2847,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ident, generics, ty, - rhs, + rhs_kind, define_opaque, defaultness: _, }) => { - let is_type_const = attr::contains_name(&item.attrs, sym::type_const); self.with_generic_param_rib( &generics.params, RibKind::Item( @@ -2871,7 +2870,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.with_lifetime_rib( LifetimeRibKind::Elided(LifetimeRes::Static), |this| { - if is_type_const + if rhs_kind.is_type_const() && !this.r.tcx.features().generic_const_parameter_types() { this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { @@ -2888,12 +2887,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, ); - if let Some(rhs) = rhs { - this.resolve_const_item_rhs( - rhs, - Some((*ident, ConstantItemKind::Const)), - ); - } + this.resolve_const_item_rhs( + rhs_kind, + Some((*ident, ConstantItemKind::Const)), + ); }, ); self.resolve_define_opaques(define_opaque); @@ -3242,11 +3239,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { AssocItemKind::Const(box ast::ConstItem { generics, ty, - rhs, + rhs_kind, define_opaque, .. }) => { - let is_type_const = attr::contains_name(&item.attrs, sym::type_const); self.with_generic_param_rib( &generics.params, RibKind::AssocItem, @@ -3261,7 +3257,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, |this| { this.visit_generics(generics); - if is_type_const + if rhs_kind.is_type_const() && !this.r.tcx.features().generic_const_parameter_types() { this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { @@ -3278,14 +3274,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Only impose the restrictions of `ConstRibKind` for an // actual constant expression in a provided default. - if let Some(rhs) = rhs { - // We allow arbitrary const expressions inside of associated consts, - // even if they are potentially not const evaluatable. - // - // Type parameters can already be used and as associated consts are - // not used as part of the type system, this is far less surprising. - this.resolve_const_item_rhs(rhs, None); - } + // + // We allow arbitrary const expressions inside of associated consts, + // even if they are potentially not const evaluatable. + // + // Type parameters can already be used and as associated consts are + // not used as part of the type system, this is far less surprising. + this.resolve_const_item_rhs(rhs_kind, None); }, ) }, @@ -3463,12 +3458,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ident, generics, ty, - rhs, + rhs_kind, define_opaque, .. }) => { debug!("resolve_implementation AssocItemKind::Const"); - let is_type_const = attr::contains_name(&item.attrs, sym::type_const); self.with_generic_param_rib( &generics.params, RibKind::AssocItem, @@ -3505,7 +3499,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); this.visit_generics(generics); - if is_type_const + if rhs_kind.is_type_const() && !this .r .tcx @@ -3527,14 +3521,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } else { this.visit_ty(ty); } - if let Some(rhs) = rhs { - // We allow arbitrary const expressions inside of associated consts, - // even if they are potentially not const evaluatable. - // - // Type parameters can already be used and as associated consts are - // not used as part of the type system, this is far less surprising. - this.resolve_const_item_rhs(rhs, None); - } + // We allow arbitrary const expressions inside of associated consts, + // even if they are potentially not const evaluatable. + // + // Type parameters can already be used and as associated consts are + // not used as part of the type system, this is far less surprising. + this.resolve_const_item_rhs(rhs_kind, None); }, ) }, @@ -3756,18 +3748,19 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { fn resolve_const_item_rhs( &mut self, - rhs: &'ast ConstItemRhs, + rhs_kind: &'ast ConstItemRhsKind, item: Option<(Ident, ConstantItemKind)>, ) { - self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| match rhs { - ConstItemRhs::TypeConst(anon_const) => { + self.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| match rhs_kind { + ConstItemRhsKind::TypeConst { rhs: Some(anon_const) } => { this.resolve_anon_const(anon_const, AnonConstKind::ConstArg(IsRepeatExpr::No)); } - ConstItemRhs::Body(expr) => { + ConstItemRhsKind::Body { rhs: Some(expr) } => { this.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, item, |this| { this.visit_expr(expr) }); } + _ => (), }) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6aa2eae556e2..2c34c99b0539 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1453,6 +1453,7 @@ symbols! { meta, meta_sized, metadata_type, + mgca_type_const_syntax, min_const_fn, min_const_generics, min_const_unsafe_fn, @@ -2339,7 +2340,6 @@ symbols! { type_ascribe, type_ascription, type_changing_struct_update, - type_const, type_id, type_id_eq, type_info, diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 46d95fdfabfe..3f4c75a5b133 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -453,7 +453,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx // been emitted earlier in compilation. // // That's because we can only end up with an Unevaluated ty::Const for a const item - // if it was marked with `#[type_const]`. Using this attribute without the mgca + // if it was marked with `type const`. Using this attribute without the mgca // feature gate causes a parse error. let ct = match tcx.def_kind(uv.def) { DefKind::AssocConst => match tcx.def_kind(tcx.parent(uv.def)) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 753fba3ed482..c09e17d3787e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1209,14 +1209,14 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext let local_did = trait_item.owner_id.to_def_id(); cx.with_param_env(local_did, |cx| { let inner = match trait_item.kind { - hir::TraitItemKind::Const(ty, Some(default)) => { + hir::TraitItemKind::Const(ty, Some(default), _) => { ProvidedAssocConstItem(Box::new(Constant { generics: enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)), kind: clean_const_item_rhs(default, local_did), type_: clean_ty(ty, cx), })) } - hir::TraitItemKind::Const(ty, None) => { + hir::TraitItemKind::Const(ty, None, _) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); RequiredAssocConstItem(generics, Box::new(clean_ty(ty, cx))) } diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index f99748127a8f..e09fc0a76366 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -739,7 +739,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { - if let TraitItemKind::Const(_, ct_rhs_opt) = item.kind + if let TraitItemKind::Const(_, ct_rhs_opt, _) = item.kind && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::No => true, @@ -931,7 +931,7 @@ fn get_const_hir_value<'tcx>( { match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) { Node::ImplItem(item) if let ImplItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs), - Node::TraitItem(item) if let TraitItemKind::Const(.., Some(ct_rhs)) = item.kind => (did, ct_rhs), + Node::TraitItem(item) if let TraitItemKind::Const(_, Some(ct_rhs), _) = item.kind => (did, ct_rhs), _ => return None, } }, diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index 7018146f184b..7d97ce97f487 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -514,7 +514,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { }; match item.kind { - TraitItemKind::Const(ty, _) | TraitItemKind::Type(_, Some(ty)) => { + TraitItemKind::Const(ty, _, _) | TraitItemKind::Type(_, Some(ty)) => { self.check_ty(cx, ty, context); }, TraitItemKind::Fn(ref sig, trait_method) => { diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index cf8716398efb..3b043f7565ef 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -355,7 +355,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: li, generics: lg, ty: lt, - rhs: lb, + rhs_kind: lb, define_opaque: _, }), Const(box ConstItem { @@ -363,7 +363,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: ri, generics: rg, ty: rt, - rhs: rb, + rhs_kind: rb, define_opaque: _, }), ) => { @@ -371,7 +371,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && both(lb.as_ref(), rb.as_ref(), eq_const_item_rhs) + && both(Some(lb), Some(rb), eq_const_item_rhs) }, ( Fn(box ast::Fn { @@ -615,7 +615,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: li, generics: lg, ty: lt, - rhs: lb, + rhs_kind: lb, define_opaque: _, }), Const(box ConstItem { @@ -623,7 +623,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: ri, generics: rg, ty: rt, - rhs: rb, + rhs_kind: rb, define_opaque: _, }), ) => { @@ -631,7 +631,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && both(lb.as_ref(), rb.as_ref(), eq_const_item_rhs) + && both(Some(lb), Some(rb), eq_const_item_rhs) }, ( Fn(box ast::Fn { @@ -791,12 +791,18 @@ pub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool { eq_expr(&l.value, &r.value) } -pub fn eq_const_item_rhs(l: &ConstItemRhs, r: &ConstItemRhs) -> bool { - use ConstItemRhs::*; +pub fn eq_const_item_rhs(l: &ConstItemRhsKind, r: &ConstItemRhsKind) -> bool { + use ConstItemRhsKind::*; match (l, r) { - (TypeConst(l), TypeConst(r)) => eq_anon_const(l, r), - (Body(l), Body(r)) => eq_expr(l, r), - (TypeConst(..), Body(..)) | (Body(..), TypeConst(..)) => false, + (TypeConst { rhs: Some(l) }, TypeConst { rhs: Some(r) }) => eq_anon_const(l, r), + (TypeConst { rhs: None }, TypeConst { rhs: None }) => true, + (TypeConst { rhs: Some(..) }, TypeConst { rhs: None }) => false, + (TypeConst { rhs: None }, TypeConst { rhs: Some(..) }) => false, + (Body { rhs: Some(l) }, Body { rhs: Some(r) }) => eq_expr(l, r), + (Body { rhs: None }, Body { rhs: None }) => true, + (Body { rhs: None }, Body { rhs: Some(..) }) => false, + (Body { rhs: Some(..) }, Body { rhs: None }) => false, + (TypeConst {..}, Body { .. }) | ( Body { .. }, TypeConst { .. }) => false, } } diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed index f8be3331317c..8d63fc44e7f8 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed @@ -3,8 +3,8 @@ #![feature(min_generic_const_args)] trait AssocConstTrait { - #[type_const] - const ASSOC: usize; + + type const ASSOC: usize; } fn assoc_const_args() where diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs index a0d7a653993f..36a83619c0f9 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs @@ -3,8 +3,8 @@ #![feature(min_generic_const_args)] trait AssocConstTrait { - #[type_const] - const ASSOC: usize; + + type const ASSOC: usize; } fn assoc_const_args() where diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index c9e32492c50b..1aa85ce2ce55 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -2028,12 +2028,16 @@ impl<'a> StaticParts<'a> { ), ast::ItemKind::Const(c) => ( Some(c.defaultness), - "const", + if c.rhs_kind.is_type_const() { + "type const" + } else { + "const" + }, ast::Safety::Default, c.ident, &c.ty, ast::Mutability::Not, - c.rhs.as_ref().map(|rhs| rhs.expr()), + c.rhs_kind.expr(), Some(&c.generics), ), _ => unreachable!(), @@ -2053,17 +2057,25 @@ impl<'a> StaticParts<'a> { } pub(crate) fn from_trait_item(ti: &'a ast::AssocItem, ident: Ident) -> Self { - let (defaultness, ty, expr_opt, generics) = match &ti.kind { - ast::AssocItemKind::Const(c) => ( - c.defaultness, - &c.ty, - c.rhs.as_ref().map(|rhs| rhs.expr()), - Some(&c.generics), - ), + let (defaultness, ty, expr_opt, generics, prefix) = match &ti.kind { + ast::AssocItemKind::Const(c) => { + let prefix = if c.rhs_kind.is_type_const() { + "type const" + } else { + "const" + }; + ( + c.defaultness, + &c.ty, + c.rhs_kind.expr(), + Some(&c.generics), + prefix, + ) + } _ => unreachable!(), }; StaticParts { - prefix: "const", + prefix, safety: ast::Safety::Default, vis: &ti.vis, ident, @@ -2077,17 +2089,25 @@ impl<'a> StaticParts<'a> { } pub(crate) fn from_impl_item(ii: &'a ast::AssocItem, ident: Ident) -> Self { - let (defaultness, ty, expr_opt, generics) = match &ii.kind { - ast::AssocItemKind::Const(c) => ( - c.defaultness, - &c.ty, - c.rhs.as_ref().map(|rhs| rhs.expr()), - Some(&c.generics), - ), + let (defaultness, ty, expr_opt, generics, prefix) = match &ii.kind { + ast::AssocItemKind::Const(c) => { + let prefix = if c.rhs_kind.is_type_const() { + "type const" + } else { + "const" + }; + ( + c.defaultness, + &c.ty, + c.rhs_kind.expr(), + Some(&c.generics), + prefix, + ) + } _ => unreachable!(), }; StaticParts { - prefix: "const", + prefix, safety: ast::Safety::Default, vis: &ii.vis, ident, diff --git a/tests/crashes/149809.rs b/tests/crashes/149809.rs index 2b948e9079c3..f70498f11c87 100644 --- a/tests/crashes/149809.rs +++ b/tests/crashes/149809.rs @@ -5,8 +5,7 @@ struct Qux<'a> { x: &'a (), } impl<'a> Qux<'a> { - #[type_const] - const LEN: usize = 4; + type const LEN: usize = 4; fn foo(_: [u8; Qux::LEN]) {} } diff --git a/tests/debuginfo/associated-const-bindings.rs b/tests/debuginfo/associated-const-bindings.rs index b60fd66235af..88c17cee8025 100644 --- a/tests/debuginfo/associated-const-bindings.rs +++ b/tests/debuginfo/associated-const-bindings.rs @@ -14,12 +14,10 @@ #![expect(unused_variables, incomplete_features)] trait Trait { - #[type_const] - const N: usize; + type const N: usize; } impl Trait for () { - #[type_const] - const N: usize = 101; + type const N: usize = 101; } fn main() { diff --git a/tests/rustdoc-html/constant/ice-associated-const-equality-105952.rs b/tests/rustdoc-html/constant/ice-associated-const-equality-105952.rs index 310e56b917fc..bdb82b91ec27 100644 --- a/tests/rustdoc-html/constant/ice-associated-const-equality-105952.rs +++ b/tests/rustdoc-html/constant/ice-associated-const-equality-105952.rs @@ -10,8 +10,7 @@ pub enum ParseMode { Raw, } pub trait Parse { - #[type_const] - const PARSE_MODE: ParseMode; + type const PARSE_MODE: ParseMode; } pub trait RenderRaw {} diff --git a/tests/rustdoc-html/inline_cross/auxiliary/assoc-const-equality.rs b/tests/rustdoc-html/inline_cross/auxiliary/assoc-const-equality.rs index 598d2b5bf29d..939740d8f918 100644 --- a/tests/rustdoc-html/inline_cross/auxiliary/assoc-const-equality.rs +++ b/tests/rustdoc-html/inline_cross/auxiliary/assoc-const-equality.rs @@ -4,6 +4,5 @@ pub fn accept(_: impl Trait) {} pub trait Trait { - #[type_const] - const K: i32; + type const K: i32; } diff --git a/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs index 5b8a90d64121..4168a5653dd5 100644 --- a/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs +++ b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs @@ -11,8 +11,7 @@ trait T { } trait S { - #[type_const] - const C: i32; + type const C: i32; } fn main() {} diff --git a/tests/ui/associated-consts/issue-110933.rs b/tests/ui/associated-consts/issue-110933.rs index 9a013ee71274..0115fb7d6e65 100644 --- a/tests/ui/associated-consts/issue-110933.rs +++ b/tests/ui/associated-consts/issue-110933.rs @@ -4,8 +4,7 @@ #![allow(incomplete_features)] pub trait Trait { - #[type_const] - const ASSOC: usize; + type const ASSOC: usize; } pub fn foo< diff --git a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs index 1a37f5957f25..cb0b8a102eb4 100644 --- a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs +++ b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs @@ -8,8 +8,7 @@ struct OnDiskDirEntry<'a>(&'a ()); impl<'a> OnDiskDirEntry<'a> { - #[type_const] - const LFN_FRAGMENT_LEN: i64 = 2; + type const LFN_FRAGMENT_LEN: i64 = 2; fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] { //~^ ERROR the constant `2` is not of type `usize` diff --git a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr index 607b7789ae67..b69a1b7fd7de 100644 --- a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr +++ b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr @@ -24,7 +24,7 @@ LL | #![feature(inherent_associated_types)] = note: see issue #8995 for more information error: the constant `2` is not of type `usize` - --> $DIR/type-const-in-array-len-wrong-type.rs:14:26 + --> $DIR/type-const-in-array-len-wrong-type.rs:13:26 | LL | fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i64` diff --git a/tests/ui/associated-consts/type-const-in-array-len.rs b/tests/ui/associated-consts/type-const-in-array-len.rs index 69dd3f443b87..d33eacaade2d 100644 --- a/tests/ui/associated-consts/type-const-in-array-len.rs +++ b/tests/ui/associated-consts/type-const-in-array-len.rs @@ -8,8 +8,7 @@ // Test case from #138226: generic impl with multiple type parameters struct Foo(A, B); impl Foo { - #[type_const] - const LEN: usize = 4; + type const LEN: usize = 4; fn foo() { let _ = [5; Self::LEN]; @@ -19,8 +18,7 @@ impl Foo { // Test case from #138226: generic impl with const parameter struct Bar; impl Bar { - #[type_const] - const LEN: usize = 4; + type const LEN: usize = 4; fn bar() { let _ = [0; Self::LEN]; @@ -30,8 +28,7 @@ impl Bar { // Test case from #150960: non-generic impl with const block struct Baz; impl Baz { - #[type_const] - const LEN: usize = 4; + type const LEN: usize = 4; fn baz() { let _ = [0; { Self::LEN }]; diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.rs b/tests/ui/associated-type-bounds/duplicate-bound-err.rs index 07eb86108bff..56403fdf6630 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.rs @@ -50,8 +50,7 @@ fn mismatch_2() -> impl Iterator { trait Trait { type Gat; - #[type_const] - const ASSOC: i32; + type const ASSOC: i32; fn foo() -> impl Sized; } @@ -59,8 +58,7 @@ trait Trait { impl Trait for () { type Gat = (); - #[type_const] - const ASSOC: i32 = 3; + type const ASSOC: i32 = 3; fn foo() {} } @@ -68,8 +66,7 @@ impl Trait for () { impl Trait for u32 { type Gat = (); - #[type_const] - const ASSOC: i32 = 4; + type const ASSOC: i32 = 4; fn foo() -> u32 { 42 @@ -89,8 +86,7 @@ type MustFail = dyn Iterator; //~| ERROR conflicting associated type bindings trait Trait2 { - #[type_const] - const ASSOC: u32; + type const ASSOC: u32; } type MustFail2 = dyn Trait2; diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr index 695bb8ad6066..e6bf93970d0a 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr @@ -100,7 +100,7 @@ LL | iter::empty::() | ----------------------- return type was inferred to be `std::iter::Empty` here error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:111:17 + --> $DIR/duplicate-bound-err.rs:107:17 | LL | fn foo() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -109,19 +109,19 @@ LL | [2u32].into_iter() | ------------------ return type was inferred to be `std::array::IntoIter` here error[E0271]: expected `impl Iterator` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:111:17 + --> $DIR/duplicate-bound-err.rs:107:17 | LL | fn foo() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` | note: required by a bound in `Trait3::foo::{anon_assoc#0}` - --> $DIR/duplicate-bound-err.rs:107:31 + --> $DIR/duplicate-bound-err.rs:103:31 | LL | fn foo() -> impl Iterator; | ^^^^^^^^^^ required by this bound in `Trait3::foo::{anon_assoc#0}` error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:87:42 + --> $DIR/duplicate-bound-err.rs:84:42 | LL | type MustFail = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -129,7 +129,7 @@ LL | type MustFail = dyn Iterator; | `Item` bound here first error: conflicting associated type bindings for `Item` - --> $DIR/duplicate-bound-err.rs:87:17 + --> $DIR/duplicate-bound-err.rs:84:17 | LL | type MustFail = dyn Iterator; | ^^^^^^^^^^^^^----------^^----------^ @@ -138,7 +138,7 @@ LL | type MustFail = dyn Iterator; | `Item` is specified to be `i32` here error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:96:43 + --> $DIR/duplicate-bound-err.rs:92:43 | LL | type MustFail2 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here @@ -146,7 +146,7 @@ LL | type MustFail2 = dyn Trait2; | `ASSOC` bound here first error: conflicting associated constant bindings for `ASSOC` - --> $DIR/duplicate-bound-err.rs:96:18 + --> $DIR/duplicate-bound-err.rs:92:18 | LL | type MustFail2 = dyn Trait2; | ^^^^^^^^^^^------------^^------------^ @@ -155,7 +155,7 @@ LL | type MustFail2 = dyn Trait2; | `ASSOC` is specified to be `3` here error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:100:43 + --> $DIR/duplicate-bound-err.rs:96:43 | LL | type MustFail3 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -163,7 +163,7 @@ LL | type MustFail3 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:103:43 + --> $DIR/duplicate-bound-err.rs:99:43 | LL | type MustFail4 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here @@ -171,7 +171,7 @@ LL | type MustFail4 = dyn Trait2; | `ASSOC` bound here first error[E0271]: expected `Empty` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:119:16 + --> $DIR/duplicate-bound-err.rs:115:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -179,13 +179,13 @@ LL | uncallable(iter::empty::()); | required by a bound introduced by this call | note: required by a bound in `uncallable` - --> $DIR/duplicate-bound-err.rs:79:32 + --> $DIR/duplicate-bound-err.rs:76:32 | LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: expected `Empty` to be an iterator that yields `u32`, but it yields `i32` - --> $DIR/duplicate-bound-err.rs:120:16 + --> $DIR/duplicate-bound-err.rs:116:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `i32` @@ -193,13 +193,13 @@ LL | uncallable(iter::empty::()); | required by a bound introduced by this call | note: required by a bound in `uncallable` - --> $DIR/duplicate-bound-err.rs:79:44 + --> $DIR/duplicate-bound-err.rs:76:44 | LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:121:22 + --> $DIR/duplicate-bound-err.rs:117:22 | LL | uncallable_const(()); | ---------------- ^^ expected `4`, found `3` @@ -209,13 +209,13 @@ LL | uncallable_const(()); = note: expected constant `4` found constant `3` note: required by a bound in `uncallable_const` - --> $DIR/duplicate-bound-err.rs:81:46 + --> $DIR/duplicate-bound-err.rs:78:46 | LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:122:22 + --> $DIR/duplicate-bound-err.rs:118:22 | LL | uncallable_const(4u32); | ---------------- ^^^^ expected `3`, found `4` @@ -225,13 +225,13 @@ LL | uncallable_const(4u32); = note: expected constant `3` found constant `4` note: required by a bound in `uncallable_const` - --> $DIR/duplicate-bound-err.rs:81:35 + --> $DIR/duplicate-bound-err.rs:78:35 | LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:123:20 + --> $DIR/duplicate-bound-err.rs:119:20 | LL | uncallable_rtn(()); | -------------- ^^ expected `4`, found `3` @@ -241,7 +241,7 @@ LL | uncallable_rtn(()); = note: expected constant `4` found constant `3` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:84:61 + --> $DIR/duplicate-bound-err.rs:81:61 | LL | fn uncallable_rtn( | -------------- required by a bound in this function @@ -249,7 +249,7 @@ LL | _: impl Trait, foo(..): Trait> | ^^^^^^^^^ required by this bound in `uncallable_rtn` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:124:20 + --> $DIR/duplicate-bound-err.rs:120:20 | LL | uncallable_rtn(17u32); | -------------- ^^^^^ expected `3`, found `4` @@ -259,7 +259,7 @@ LL | uncallable_rtn(17u32); = note: expected constant `3` found constant `4` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:84:34 + --> $DIR/duplicate-bound-err.rs:81:34 | LL | fn uncallable_rtn( | -------------- required by a bound in this function diff --git a/tests/ui/associated-type-bounds/duplicate-bound.rs b/tests/ui/associated-type-bounds/duplicate-bound.rs index 1aeb0022a04f..39cfa9db072c 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound.rs @@ -189,8 +189,7 @@ trait Tra3 { trait Trait { type Gat; - #[type_const] - const ASSOC: i32; + type const ASSOC: i32; fn foo() -> impl Sized; } @@ -198,8 +197,7 @@ trait Trait { impl Trait for () { type Gat = (); - #[type_const] - const ASSOC: i32 = 3; + type const ASSOC: i32 = 3; fn foo() {} } diff --git a/tests/ui/associated-types/type-const-inherent-impl-normalize.rs b/tests/ui/associated-types/type-const-inherent-impl-normalize.rs index 70eea70db4c6..a9c7373b4f44 100644 --- a/tests/ui/associated-types/type-const-inherent-impl-normalize.rs +++ b/tests/ui/associated-types/type-const-inherent-impl-normalize.rs @@ -1,8 +1,8 @@ struct S; impl S { - #[type_const] - //~^ ERROR: the `#[type_const]` attribute is an experimental feature - const LEN: usize = 1; + type const LEN: usize = 1; + //~^ ERROR: associated `type const` are unstable [E0658] + //~| ERROR: `type const` syntax is experimental [E0658] fn arr() { [8; Self::LEN] //~^ WARN: cannot use constants which depend on generic parameters in types diff --git a/tests/ui/associated-types/type-const-inherent-impl-normalize.stderr b/tests/ui/associated-types/type-const-inherent-impl-normalize.stderr index 958d38e855ea..b86859f4a993 100644 --- a/tests/ui/associated-types/type-const-inherent-impl-normalize.stderr +++ b/tests/ui/associated-types/type-const-inherent-impl-normalize.stderr @@ -1,8 +1,18 @@ -error[E0658]: the `#[type_const]` attribute is an experimental feature +error[E0658]: `type const` syntax is experimental --> $DIR/type-const-inherent-impl-normalize.rs:3:5 | -LL | #[type_const] - | ^^^^^^^^^^^^^ +LL | type const LEN: usize = 1; + | ^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated `type const` are unstable + --> $DIR/type-const-inherent-impl-normalize.rs:3:5 + | +LL | type const LEN: usize = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable @@ -36,7 +46,7 @@ LL | fn arr() { LL | [8; Self::LEN] | ^^^^^^^^^^^^^^ expected `()`, found `[{integer}; 1]` -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 3 previous errors; 2 warnings emitted Some errors have detailed explanations: E0308, E0658. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 6dc3086b63e1..489c8bf9f495 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -145,8 +145,6 @@ struct Test; #[diagnostic::on_unimplemented = 1] //~^ WARN malformed trait Hey { - #[type_const = 1] - //~^ ERROR malformed const HEY: usize = 5; } diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 22e222efa435..009da1d12a16 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -21,13 +21,13 @@ LL | #[cfg_attr] = note: for more information, visit error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:217:1 + --> $DIR/malformed-attrs.rs:215:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:183:1 + --> $DIR/malformed-attrs.rs:181:1 | LL | #[allow] | ^^^^^^^^ @@ -43,7 +43,7 @@ LL | #[allow(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:185:1 + --> $DIR/malformed-attrs.rs:183:1 | LL | #[expect] | ^^^^^^^^^ @@ -59,7 +59,7 @@ LL | #[expect(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:187:1 + --> $DIR/malformed-attrs.rs:185:1 | LL | #[warn] | ^^^^^^^ @@ -75,7 +75,7 @@ LL | #[warn(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:189:1 + --> $DIR/malformed-attrs.rs:187:1 | LL | #[deny] | ^^^^^^^ @@ -91,7 +91,7 @@ LL | #[deny(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:191:1 + --> $DIR/malformed-attrs.rs:189:1 | LL | #[forbid] | ^^^^^^^^^ @@ -125,7 +125,7 @@ LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:222:1 + --> $DIR/malformed-attrs.rs:220:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -541,7 +541,7 @@ LL | #[cfi_encoding = ""] | help: must be of the form: `#[cfi_encoding = "encoding"]` error[E0565]: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:160:1 + --> $DIR/malformed-attrs.rs:158:1 | LL | #[marker = 3] | ^^^^^^^^^---^ @@ -550,7 +550,7 @@ LL | #[marker = 3] | help: must be of the form: `#[marker]` error[E0565]: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:162:1 + --> $DIR/malformed-attrs.rs:160:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^--^ @@ -559,7 +559,7 @@ LL | #[fundamental()] | help: must be of the form: `#[fundamental]` error[E0565]: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:170:5 + --> $DIR/malformed-attrs.rs:168:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^---^^ @@ -568,7 +568,7 @@ LL | #[unsafe(ffi_pure = 1)] | help: must be of the form: `#[ffi_pure]` error[E0539]: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:172:5 + --> $DIR/malformed-attrs.rs:170:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ @@ -579,7 +579,7 @@ LL | #[link_ordinal] = note: for more information, visit error[E0565]: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:176:5 + --> $DIR/malformed-attrs.rs:174:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^---^^ @@ -588,13 +588,13 @@ LL | #[unsafe(ffi_const = 1)] | help: must be of the form: `#[ffi_const]` error[E0539]: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:178:5 + --> $DIR/malformed-attrs.rs:176:5 | LL | #[linkage] | ^^^^^^^^^^ expected this to be of the form `linkage = "..."` error[E0539]: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:193:1 + --> $DIR/malformed-attrs.rs:191:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -605,7 +605,7 @@ LL | #[debugger_visualizer] = note: for more information, visit error[E0565]: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:195:1 + --> $DIR/malformed-attrs.rs:193:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -614,7 +614,7 @@ LL | #[automatically_derived = 18] | help: must be of the form: `#[automatically_derived]` error[E0565]: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:203:1 + --> $DIR/malformed-attrs.rs:201:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^---^ @@ -623,7 +623,7 @@ LL | #[non_exhaustive = 1] | help: must be of the form: `#[non_exhaustive]` error[E0565]: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:209:1 + --> $DIR/malformed-attrs.rs:207:1 | LL | #[thread_local()] | ^^^^^^^^^^^^^^--^ @@ -632,7 +632,7 @@ LL | #[thread_local()] | help: must be of the form: `#[thread_local]` error[E0565]: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:213:1 + --> $DIR/malformed-attrs.rs:211:1 | LL | #[no_link()] | ^^^^^^^^^--^ @@ -641,7 +641,7 @@ LL | #[no_link()] | help: must be of the form: `#[no_link]` error[E0539]: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:215:1 + --> $DIR/malformed-attrs.rs:213:1 | LL | #[macro_use = 1] | ^^^^^^^^^^^^---^ @@ -659,7 +659,7 @@ LL + #[macro_use] | error[E0539]: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:220:1 + --> $DIR/malformed-attrs.rs:218:1 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^^^----^ @@ -676,7 +676,7 @@ LL + #[macro_export] | error[E0565]: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:222:1 + --> $DIR/malformed-attrs.rs:220:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^---^ @@ -684,15 +684,6 @@ LL | #[allow_internal_unsafe = 1] | | didn't expect any arguments here | help: must be of the form: `#[allow_internal_unsafe]` -error[E0565]: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:148:5 - | -LL | #[type_const = 1] - | ^^^^^^^^^^^^^---^ - | | | - | | didn't expect any arguments here - | help: must be of the form: `#[type_const]` - error: attribute should be applied to `const fn` --> $DIR/malformed-attrs.rs:32:1 | @@ -820,13 +811,13 @@ LL | #[no_implicit_prelude = 23] = help: `#[no_implicit_prelude]` can be applied to crates and modules warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:154:1 + --> $DIR/malformed-attrs.rs:152:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[automatically_derived]` attribute cannot be used on modules - --> $DIR/malformed-attrs.rs:195:1 + --> $DIR/malformed-attrs.rs:193:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -835,7 +826,7 @@ LL | #[automatically_derived = 18] = help: `#[automatically_derived]` can only be applied to trait impl blocks error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:229:1 + --> $DIR/malformed-attrs.rs:227:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ @@ -854,7 +845,7 @@ LL | #[coroutine = 63] || {} = note: expected unit type `()` found coroutine `{coroutine@$DIR/malformed-attrs.rs:116:23: 116:25}` -error: aborting due to 76 previous errors; 8 warnings emitted +error: aborting due to 75 previous errors; 8 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. @@ -882,7 +873,7 @@ LL | #[ignore()] Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:229:1 + --> $DIR/malformed-attrs.rs:227:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/associated-const-bindings/ambiguity.rs b/tests/ui/const-generics/associated-const-bindings/ambiguity.rs index 785d43e51b3d..6871a028de5f 100644 --- a/tests/ui/const-generics/associated-const-bindings/ambiguity.rs +++ b/tests/ui/const-generics/associated-const-bindings/ambiguity.rs @@ -6,8 +6,7 @@ trait Trait0: Parent0 + Parent0 {} trait Parent0 { - #[type_const] - const K: (); + type const K: (); } fn take0(_: impl Trait0) {} @@ -15,12 +14,10 @@ fn take0(_: impl Trait0) {} trait Trait1: Parent1 + Parent2 {} trait Parent1 { - #[type_const] - const C: i32; + type const C: i32; } trait Parent2 { - #[type_const] - const C: &'static str; + type const C: &'static str; } fn take1(_: impl Trait1) {} diff --git a/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr b/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr index 806708f18d65..9dcb30d6b737 100644 --- a/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr +++ b/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr @@ -1,8 +1,8 @@ error[E0222]: ambiguous associated constant `K` in bounds of `Trait0` - --> $DIR/ambiguity.rs:13:25 + --> $DIR/ambiguity.rs:12:25 | -LL | const K: (); - | ----------- +LL | type const K: (); + | ---------------- | | | ambiguous `K` from `Parent0` | ambiguous `K` from `Parent0` @@ -17,13 +17,13 @@ LL | fn take0(_: impl Trait0) {} T: Parent0::K = const { } error[E0222]: ambiguous associated constant `C` in bounds of `Trait1` - --> $DIR/ambiguity.rs:26:25 + --> $DIR/ambiguity.rs:23:25 | -LL | const C: i32; - | ------------ ambiguous `C` from `Parent1` +LL | type const C: i32; + | ----------------- ambiguous `C` from `Parent1` ... -LL | const C: &'static str; - | --------------------- ambiguous `C` from `Parent2` +LL | type const C: &'static str; + | -------------------------- ambiguous `C` from `Parent2` ... LL | fn take1(_: impl Trait1) {} | ^^^^^^^ ambiguous associated constant `C` diff --git a/tests/ui/const-generics/associated-const-bindings/assoc-const.rs b/tests/ui/const-generics/associated-const-bindings/assoc-const.rs index ac9f7e53b3cb..3f8353b6914d 100644 --- a/tests/ui/const-generics/associated-const-bindings/assoc-const.rs +++ b/tests/ui/const-generics/associated-const-bindings/assoc-const.rs @@ -3,15 +3,13 @@ #![allow(unused, incomplete_features)] pub trait Foo { - #[type_const] - const N: usize; + type const N: usize; } pub struct Bar; impl Foo for Bar { - #[type_const] - const N: usize = 3; + type const N: usize = 3; } const TEST: usize = 3; diff --git a/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs index 803cc59cc93d..53f65319db9d 100644 --- a/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs +++ b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs @@ -11,8 +11,7 @@ use std::marker::ConstParamTy_; trait Trait { - #[type_const] - const K: T; + type const K: T; } fn take( diff --git a/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr index a4f97525b515..f2f69aad4ee6 100644 --- a/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr +++ b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/bound-var-in-ty-not-wf.rs:21:13 + --> $DIR/bound-var-in-ty-not-wf.rs:20:13 | LL | K = const { () } | ^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/bound-var-in-ty-not-wf.rs:21:13 + --> $DIR/bound-var-in-ty-not-wf.rs:20:13 | LL | K = const { () } | ^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty.rs index e6fd5bdad002..a509fe0d52e3 100644 --- a/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty.rs +++ b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty.rs @@ -14,8 +14,7 @@ use std::marker::ConstParamTy_; trait Trait { - #[type_const] - const K: T; + type const K: T; } fn take( diff --git a/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs b/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs index 0af91bfe7da8..149755bad4ca 100644 --- a/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs +++ b/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs @@ -12,13 +12,11 @@ trait Trait: SuperTrait { type N; type Q; - #[type_const] - const N: usize; + type const N: usize; } trait SuperTrait { - #[type_const] - const Q: &'static str; + type const Q: &'static str; } fn take0(_: impl Trait) {} diff --git a/tests/ui/const-generics/associated-const-bindings/coherence.rs b/tests/ui/const-generics/associated-const-bindings/coherence.rs index f4081fae6144..e9296f3a8df0 100644 --- a/tests/ui/const-generics/associated-const-bindings/coherence.rs +++ b/tests/ui/const-generics/associated-const-bindings/coherence.rs @@ -2,12 +2,10 @@ #![expect(incomplete_features)] pub trait IsVoid { - #[type_const] - const IS_VOID: bool; + type const IS_VOID: bool; } impl IsVoid for () { - #[type_const] - const IS_VOID: bool = true; + type const IS_VOID: bool = true; } pub trait Maybe {} diff --git a/tests/ui/const-generics/associated-const-bindings/coherence.stderr b/tests/ui/const-generics/associated-const-bindings/coherence.stderr index 23d6495a16a4..df6781f2f9a2 100644 --- a/tests/ui/const-generics/associated-const-bindings/coherence.stderr +++ b/tests/ui/const-generics/associated-const-bindings/coherence.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Maybe` for type `()` - --> $DIR/coherence.rs:15:1 + --> $DIR/coherence.rs:13:1 | LL | impl Maybe for () {} | ----------------- first implementation here diff --git a/tests/ui/const-generics/associated-const-bindings/const-projection-err.rs b/tests/ui/const-generics/associated-const-bindings/const-projection-err.rs index d485316ce371..8e871ddf90ce 100644 --- a/tests/ui/const-generics/associated-const-bindings/const-projection-err.rs +++ b/tests/ui/const-generics/associated-const-bindings/const-projection-err.rs @@ -2,8 +2,7 @@ #![allow(incomplete_features)] trait TraitWAssocConst { - #[type_const] - const A: usize; + type const A: usize; } fn foo>() {} diff --git a/tests/ui/const-generics/associated-const-bindings/const-projection-err.stderr b/tests/ui/const-generics/associated-const-bindings/const-projection-err.stderr index 552b1579e618..c533a7d65b90 100644 --- a/tests/ui/const-generics/associated-const-bindings/const-projection-err.stderr +++ b/tests/ui/const-generics/associated-const-bindings/const-projection-err.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `::A == 1` - --> $DIR/const-projection-err.rs:12:11 + --> $DIR/const-projection-err.rs:11:11 | LL | foo::(); | ^ expected `1`, found `0` @@ -7,7 +7,7 @@ LL | foo::(); = note: expected constant `1` found constant `0` note: required by a bound in `foo` - --> $DIR/const-projection-err.rs:9:28 + --> $DIR/const-projection-err.rs:8:28 | LL | fn foo>() {} | ^^^^^ required by this bound in `foo` diff --git a/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs b/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs index 161eef63d36f..578904ea1891 100644 --- a/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs +++ b/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs @@ -8,8 +8,7 @@ #![allow(incomplete_features)] pub trait TraitA { - #[type_const] - const K: u8 = 0; + type const K: u8 = 0; } pub trait TraitB {} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs index bd26acce681f..771f48cba068 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs @@ -14,14 +14,12 @@ trait Trait { // NOTE: The `ConstParamTy_` bound is intentionally on the assoc const and not on the trait as // doing the latter would already render the trait dyn incompatible due to it being // bounded by `PartialEq` and supertrait bounds cannot mention `Self` like this. - #[type_const] - const K: Self where Self: std::marker::ConstParamTy_; + type const K: Self where Self: std::marker::ConstParamTy_; //~^ NOTE it contains associated const `K` whose type references the `Self` type // This is not a "`Self` projection" in our sense (which would be allowed) // since the trait is not the principal trait or a supertrait thereof. - #[type_const] - const Q: ::Output; + type const Q: ::Output; //~^ NOTE it contains associated const `Q` whose type references the `Self` type } diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr index dedbdd7f82bb..19cd8bf5af99 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr @@ -1,21 +1,21 @@ error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:38:16 + --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:36:16 | LL | let _: dyn Trait; | ^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:18:11 + --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:17:16 | LL | trait Trait { | ----- this trait is not dyn compatible... ... -LL | const K: Self where Self: std::marker::ConstParamTy_; - | ^ ...because it contains associated const `K` whose type references the `Self` type +LL | type const K: Self where Self: std::marker::ConstParamTy_; + | ^ ...because it contains associated const `K` whose type references the `Self` type ... -LL | const Q: ::Output; - | ^ ...because it contains associated const `Q` whose type references the `Self` type +LL | type const Q: ::Output; + | ^ ...because it contains associated const `Q` whose type references the `Self` type = help: consider moving `K` to another trait = help: consider moving `Q` to another trait diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-basic.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-basic.rs index 6e35d56dc6e7..8de8cb1a60db 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-basic.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-basic.rs @@ -7,25 +7,20 @@ #![expect(incomplete_features)] trait Trait: SuperTrait { - #[type_const] - const K: usize; + type const K: usize; } trait SuperTrait { - #[type_const] - const Q: usize; - #[type_const] - const C: usize; + type const Q: usize; + type const C: usize; } trait Bound { - #[type_const] - const N: usize; + type const N: usize; } impl Bound for () { - #[type_const] - const N: usize = 10; + type const N: usize = 10; } fn main() { diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.rs index be41906a4f2f..ad5c4b679117 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.rs @@ -4,13 +4,11 @@ #![expect(incomplete_features)] trait Trait { - #[type_const] - const N: usize; + type const N: usize; } impl Trait for () { - #[type_const] - const N: usize = 1; + type const N: usize = 1; } fn main() { diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.stderr index 2ab02068eb34..282504e3bc35 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `<() as Trait>::N == 0` - --> $DIR/dyn-compat-const-mismatch.rs:17:32 + --> $DIR/dyn-compat-const-mismatch.rs:15:32 | LL | let _: &dyn Trait = &(); | ^^^ expected `0`, found `1` diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.rs index 30e7a78c2a85..8130960195d9 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.rs @@ -7,13 +7,11 @@ trait X::N }> {} trait Y { - #[type_const] - const N: usize; + type const N: usize; } impl Y for T { - #[type_const] - const N: usize = 1; + type const N: usize = 1; } fn main() { diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.stderr index d92fd620f0ea..a22545fcd8d2 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.stderr @@ -1,5 +1,5 @@ error[E0393]: the const parameter `N` must be explicitly specified - --> $DIR/dyn-compat-const-param-default-mentions-self.rs:20:16 + --> $DIR/dyn-compat-const-param-default-mentions-self.rs:18:16 | LL | trait X::N }> {} | -------------------------------------------- const parameter `N` must be specified for this diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs index 93036fbc01a8..415d7bda347b 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs @@ -9,8 +9,7 @@ #![expect(incomplete_features)] trait Trait { - #[type_const] - const Y: i32; + type const Y: i32; } struct Hold(T); diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr index 109cb7602dcd..576d4c3230ee 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr @@ -1,5 +1,5 @@ error: associated constant binding in trait object type mentions `Self` - --> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:21:12 + --> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:20:12 | LL | trait Bound = Trait }>; | -------------------- this binding mentions `Self` diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.rs index aa93edd02531..560a1b7f3f7a 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.rs @@ -5,13 +5,11 @@ #![expect(incomplete_features)] trait X: Y { - #[type_const] - const Q: usize; + type const Q: usize; } trait Y { - #[type_const] - const K: usize; + type const K: usize; } fn main() { diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.stderr index 373c4f0e6611..dae9e3d8c22b 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.stderr @@ -1,8 +1,8 @@ error[E0191]: the value of the associated constant `K` in `Y` must be specified - --> $DIR/dyn-compat-const-projection-from-supertrait-mentions-self.rs:18:16 + --> $DIR/dyn-compat-const-projection-from-supertrait-mentions-self.rs:16:16 | -LL | const K: usize; - | -------------- `K` defined here +LL | type const K: usize; + | ------------------- `K` defined here ... LL | let _: dyn X; | ^^^^^^^^^ help: specify the associated constant: `X` diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.rs index 67650bce8c89..38d593984724 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.rs @@ -7,7 +7,7 @@ trait Trait { const K: usize; - //~^ NOTE it contains associated const `K` that's not marked `#[type_const]` + //~^ NOTE it contains associated const `K` that's not defined as `type const` } fn main() { @@ -16,5 +16,5 @@ fn main() { // Check that specifying the non-type assoc const doesn't "magically make it work". let _: dyn Trait; //~^ ERROR the trait `Trait` is not dyn compatible - //~| ERROR use of trait associated const without `#[type_const]` + //~| ERROR use of trait associated const not defined as `type const` } diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.stderr index c579cd312f1f..5bc072e98c0f 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.stderr @@ -11,16 +11,16 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Trait { | ----- this trait is not dyn compatible... LL | const K: usize; - | ^ ...because it contains associated const `K` that's not marked `#[type_const]` + | ^ ...because it contains associated const `K` that's not defined as `type const` = help: consider moving `K` to another trait -error: use of trait associated const without `#[type_const]` +error: use of trait associated const not defined as `type const` --> $DIR/dyn-compat-non-type-assoc-const.rs:17:22 | LL | let _: dyn Trait; | ^^^^^ | - = note: the declaration in the trait must be marked with `#[type_const]` + = note: the declaration in the trait must begin with `type const` not just `const` alone error[E0038]: the trait `Trait` is not dyn compatible --> $DIR/dyn-compat-non-type-assoc-const.rs:17:16 @@ -35,7 +35,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Trait { | ----- this trait is not dyn compatible... LL | const K: usize; - | ^ ...because it contains associated const `K` that's not marked `#[type_const]` + | ^ ...because it contains associated const `K` that's not defined as `type const` = help: consider moving `K` to another trait error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs index 07ce629ab7be..03f1a526b73a 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs @@ -6,13 +6,11 @@ #![expect(incomplete_features)] trait Trait { - #[type_const] - const N: i32 where Self: Bound; + type const N: i32 where Self: Bound; } impl Trait for () { - #[type_const] - const N: i32 = 0; + type const N: i32 = 0; } trait Bound {} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.stderr index 8eeb60d55c38..21e407f8a861 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.stderr @@ -1,19 +1,19 @@ error[E0277]: the trait bound `(): Bound` is not satisfied - --> $DIR/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs:23:32 + --> $DIR/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs:21:32 | LL | let _: &dyn Trait = &(); | ^^^ the trait `Bound` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs:18:1 + --> $DIR/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs:16:1 | LL | trait Bound {} | ^^^^^^^^^^^ note: required by a bound in `Trait::N` - --> $DIR/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs:10:30 + --> $DIR/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs:9:35 | -LL | const N: i32 where Self: Bound; - | ^^^^^ required by this bound in `Trait::N` +LL | type const N: i32 where Self: Bound; + | ^^^^^ required by this bound in `Trait::N` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs index fc3bd1d2e753..623769f5d12f 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs @@ -14,14 +14,12 @@ trait A { type Ty: std::marker::ConstParamTy_; - #[type_const] - const CT: Self::Ty; + type const CT: Self::Ty; } impl A for () { type Ty = i32; - #[type_const] - const CT: i32 = 0; + type const CT: i32 = 0; } fn main() { diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr index 0b8dae1aac43..cc08c25906b6 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr @@ -1,23 +1,23 @@ error[E0277]: the trait bound `FreshTy(0): A` is not satisfied - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:34:33 + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:32:33 | LL | let _: dyn A; | ^ the trait `A` is not implemented for `FreshTy(0)` | help: the trait `A` is implemented for `()` - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:21:1 + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:20:1 | LL | impl A for () { | ^^^^^^^^^^^^^ error[E0277]: the trait bound `FreshTy(0): A` is not satisfied - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:36:34 + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:34:34 | LL | let _: &dyn A = &(); | ^ the trait `A` is not implemented for `FreshTy(0)` | help: the trait `A` is implemented for `()` - --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:21:1 + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:20:1 | LL | impl A for () { | ^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-methods.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-methods.rs index f5a5fbc8188c..9886213743c8 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-methods.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-methods.rs @@ -15,15 +15,13 @@ #![expect(incomplete_features)] trait Trait { - #[type_const] - const N: usize; + type const N: usize; fn process(&self, _: [u8; Self::N]) -> [u8; Self::N]; } impl Trait for u8 { - #[type_const] - const N: usize = 2; + type const N: usize = 2; fn process(&self, [x, y]: [u8; Self::N]) -> [u8; Self::N] { [self * x, self + y] @@ -31,8 +29,7 @@ impl Trait for u8 { } impl Trait for [u8; N] { - #[type_const] - const N: usize = N; + type const N: usize = N; fn process(&self, other: [u8; Self::N]) -> [u8; Self::N] { let mut result = [0; _]; diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.rs index c8929750f61c..f2ae98accda5 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.rs @@ -9,8 +9,7 @@ trait Trait: SuperTrait<{ Self::N }> { //~^ NOTE it uses `Self` as a type parameter - #[type_const] - const N: usize; + type const N: usize; } trait SuperTrait {} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.stderr index 33edc96117d5..38c928fd58d7 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/dyn-compat-self-const-projections-in-supertrait-bounds.rs:19:16 + --> $DIR/dyn-compat-self-const-projections-in-supertrait-bounds.rs:18:16 | LL | let _: dyn Trait; | ^^^^^ `Trait` is not dyn compatible diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.rs index 18be0fccc051..52ecd42b191d 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.rs @@ -15,8 +15,7 @@ #![crate_name = "sym"] trait Trait { - #[type_const] - const N: usize; + type const N: usize; } #[rustc_symbol_name] diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.v0.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.v0.stderr index 424251acc3e9..8ca0f73494d3 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.v0.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.v0.stderr @@ -1,17 +1,17 @@ error: symbol-name(_RMCsCRATE_HASH_3symDNtB_5Traitp1NKj0_EL_) - --> $DIR/dyn-compat-symbol-mangling.rs:22:1 + --> $DIR/dyn-compat-symbol-mangling.rs:21:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(>) - --> $DIR/dyn-compat-symbol-mangling.rs:22:1 + --> $DIR/dyn-compat-symbol-mangling.rs:21:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(>) - --> $DIR/dyn-compat-symbol-mangling.rs:22:1 + --> $DIR/dyn-compat-symbol-mangling.rs:21:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs index 3525cbceb87b..5bd8aa609420 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs @@ -6,8 +6,7 @@ #![expect(incomplete_features)] trait Trait { - #[type_const] - const K: usize; + type const K: usize; } // fn ctxt / body diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.stderr index 68658a5711cb..35fdd7f2751e 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.stderr @@ -1,26 +1,26 @@ error[E0191]: the value of the associated constant `K` in `Trait` must be specified - --> $DIR/dyn-compat-unspecified-assoc-consts.rs:20:18 + --> $DIR/dyn-compat-unspecified-assoc-consts.rs:19:18 | -LL | const K: usize; - | -------------- `K` defined here +LL | type const K: usize; + | ------------------- `K` defined here ... LL | struct Store(dyn Trait); | ^^^^^ help: specify the associated constant: `Trait` error[E0191]: the value of the associated constant `K` in `Trait` must be specified - --> $DIR/dyn-compat-unspecified-assoc-consts.rs:24:21 + --> $DIR/dyn-compat-unspecified-assoc-consts.rs:23:21 | -LL | const K: usize; - | -------------- `K` defined here +LL | type const K: usize; + | ------------------- `K` defined here ... LL | type DynTrait = dyn Trait; | ^^^^^ help: specify the associated constant: `Trait` error[E0191]: the value of the associated constant `K` in `Trait` must be specified - --> $DIR/dyn-compat-unspecified-assoc-consts.rs:15:16 + --> $DIR/dyn-compat-unspecified-assoc-consts.rs:14:16 | -LL | const K: usize; - | -------------- `K` defined here +LL | type const K: usize; + | ------------------- `K` defined here ... LL | let _: dyn Trait; | ^^^^^ help: specify the associated constant: `Trait` diff --git a/tests/ui/const-generics/associated-const-bindings/equality-unused-issue-126729.rs b/tests/ui/const-generics/associated-const-bindings/equality-unused-issue-126729.rs index 614ed8c803d4..f42589f91d15 100644 --- a/tests/ui/const-generics/associated-const-bindings/equality-unused-issue-126729.rs +++ b/tests/ui/const-generics/associated-const-bindings/equality-unused-issue-126729.rs @@ -5,42 +5,34 @@ #![deny(dead_code)] trait Tr { - #[type_const] - const I: i32; + type const I: i32; } impl Tr for () { - #[type_const] - const I: i32 = 1; + type const I: i32 = 1; } fn foo() -> impl Tr {} trait Tr2 { - #[type_const] - const J: i32; - #[type_const] - const K: i32; + type const J: i32; + type const K: i32; } impl Tr2 for () { - #[type_const] - const J: i32 = 1; - #[type_const] - const K: i32 = 1; + type const J: i32 = 1; + type const K: i32 = 1; } fn foo2() -> impl Tr2 {} mod t { pub trait Tr3 { - #[type_const] - const L: i32; + type const L: i32; } impl Tr3 for () { - #[type_const] - const L: i32 = 1; + type const L: i32 = 1; } } diff --git a/tests/ui/const-generics/associated-const-bindings/equality_bound_with_infer.rs b/tests/ui/const-generics/associated-const-bindings/equality_bound_with_infer.rs index b7ed8ee39f87..e50c13b5d3b5 100644 --- a/tests/ui/const-generics/associated-const-bindings/equality_bound_with_infer.rs +++ b/tests/ui/const-generics/associated-const-bindings/equality_bound_with_infer.rs @@ -7,13 +7,11 @@ // though it contained inference variables, which would cause ICEs. trait Foo { - #[type_const] - const ASSOC: u32; + type const ASSOC: u32; } impl Foo for () { - #[type_const] - const ASSOC: u32 = N; + type const ASSOC: u32 = N; } fn bar = 10>>() {} diff --git a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs index 4d06cdc7620f..de888c5a7939 100644 --- a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs +++ b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs @@ -9,8 +9,7 @@ #![allow(incomplete_features)] trait Trait<'a> { - #[type_const] - const K: &'a (); + type const K: &'a (); } fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} diff --git a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr index 3966483aa600..122893662933 100644 --- a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr +++ b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` cannot capture late-bound generic parameters - --> $DIR/esc-bound-var-in-ty.rs:16:35 + --> $DIR/esc-bound-var-in-ty.rs:15:35 | LL | fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} | -- ^ its type cannot capture the late-bound lifetime parameter `'r` diff --git a/tests/ui/const-generics/associated-const-bindings/issue-102335-const.rs b/tests/ui/const-generics/associated-const-bindings/issue-102335-const.rs index a88a3abf0a12..1663cad13c7c 100644 --- a/tests/ui/const-generics/associated-const-bindings/issue-102335-const.rs +++ b/tests/ui/const-generics/associated-const-bindings/issue-102335-const.rs @@ -8,8 +8,7 @@ trait T { } trait S { - #[type_const] - const C: i32; + type const C: i32; } fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.rs b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.rs index 77f0f06f8040..1c6e873b98c3 100644 --- a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.rs +++ b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.rs @@ -2,13 +2,11 @@ #![expect(incomplete_features)] trait Foo { - #[type_const] - const ASSOC: u32; + type const ASSOC: u32; } impl Foo for () { - #[type_const] - const ASSOC: u32 = N; + type const ASSOC: u32 = N; } fn bar = { N }>>() {} diff --git a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr index c2fb7faa3a3a..b447cd08a214 100644 --- a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr +++ b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr @@ -1,26 +1,26 @@ error: the constant `N` is not of type `u32` - --> $DIR/mismatched-types-with-generic-in-ace.rs:14:29 + --> $DIR/mismatched-types-with-generic-in-ace.rs:12:29 | LL | fn bar = { N }>>() {} | ^^^^^^^^^^^^^^^^ expected `u32`, found `u64` | note: required by a const generic parameter in `Foo::ASSOC` - --> $DIR/mismatched-types-with-generic-in-ace.rs:6:17 + --> $DIR/mismatched-types-with-generic-in-ace.rs:5:22 | -LL | const ASSOC: u32; - | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` +LL | type const ASSOC: u32; + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` error: the constant `10` is not of type `u32` - --> $DIR/mismatched-types-with-generic-in-ace.rs:18:5 + --> $DIR/mismatched-types-with-generic-in-ace.rs:16:5 | LL | bar::<10_u64, ()>(); | ^^^^^^^^^^^^^^^^^^^ expected `u32`, found `u64` | note: required by a const generic parameter in `Foo::ASSOC` - --> $DIR/mismatched-types-with-generic-in-ace.rs:6:17 + --> $DIR/mismatched-types-with-generic-in-ace.rs:5:22 | -LL | const ASSOC: u32; - | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` +LL | type const ASSOC: u32; + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs b/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs index c7bb5bccedb3..a1efa74090bb 100644 --- a/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs +++ b/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs @@ -6,8 +6,7 @@ // with associated const equality bounds. trait Trait { - #[type_const] - const C: usize; + type const C: usize; } fn f>() { diff --git a/tests/ui/const-generics/associated-const-bindings/param-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/param-in-ty.rs index 44e7e3f19ef2..4d67186f71f9 100644 --- a/tests/ui/const-generics/associated-const-bindings/param-in-ty.rs +++ b/tests/ui/const-generics/associated-const-bindings/param-in-ty.rs @@ -11,8 +11,7 @@ use std::marker::ConstParamTy_; trait Trait<'a, T: 'a + ConstParamTy_, const N: usize> { - #[type_const] - const K: &'a [T; N]; + type const K: &'a [T; N]; } fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( @@ -32,8 +31,7 @@ fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( ) {} trait Project: ConstParamTy_ { - #[type_const] - const SELF: Self; + type const SELF: Self; } fn take1(_: impl Project) {} diff --git a/tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr b/tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr index 719dad816a6f..2ef3fab7e5ff 100644 --- a/tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr +++ b/tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr @@ -1,5 +1,5 @@ error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/param-in-ty.rs:22:29 + --> $DIR/param-in-ty.rs:21:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | -- the lifetime parameter `'r` is defined here @@ -10,7 +10,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/param-in-ty.rs:22:29 + --> $DIR/param-in-ty.rs:21:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | - the type parameter `A` is defined here @@ -21,7 +21,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/param-in-ty.rs:22:29 + --> $DIR/param-in-ty.rs:21:29 | LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( | - the const parameter `Q` is defined here @@ -32,7 +32,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }> = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/param-in-ty.rs:39:26 + --> $DIR/param-in-ty.rs:37:26 | LL | fn take1(_: impl Project) {} | -------------^^^^------------ @@ -41,7 +41,7 @@ LL | fn take1(_: impl Project) {} | the `impl Trait` is specified here error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/param-in-ty.rs:44:21 + --> $DIR/param-in-ty.rs:42:21 | LL | fn take2>(_: P) {} | - ^^^^ its type must not depend on the type parameter `P` @@ -51,7 +51,7 @@ LL | fn take2>(_: P) {} = note: `SELF` has type `P` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:51:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here @@ -62,7 +62,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -70,7 +70,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` @@ -80,7 +80,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:51:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here @@ -92,7 +92,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -101,7 +101,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/param-in-ty.rs:53:52 + --> $DIR/param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` diff --git a/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.rs b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.rs index 8a78b26dbc5d..dbfbba9b7cbd 100644 --- a/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.rs +++ b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.rs @@ -4,8 +4,7 @@ // Issue 110549 pub trait TraitWAssocConst { - #[type_const] - const A: usize; + type const A: usize; } fn foo>() {} diff --git a/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.stderr b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.stderr index 232b15b7e981..11490a044091 100644 --- a/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.stderr +++ b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/projection-unspecified-but-bounded.rs:14:11 + --> $DIR/projection-unspecified-but-bounded.rs:13:11 | LL | foo::(); | ^ expected `32`, found `::A` @@ -7,7 +7,7 @@ LL | foo::(); = note: expected constant `32` found constant `::A` note: required by a bound in `foo` - --> $DIR/projection-unspecified-but-bounded.rs:11:28 + --> $DIR/projection-unspecified-but-bounded.rs:10:28 | LL | fn foo>() {} | ^^^^^^ required by this bound in `foo` diff --git a/tests/ui/const-generics/associated-const-bindings/supertraits.rs b/tests/ui/const-generics/associated-const-bindings/supertraits.rs index a5f8859c92bd..cdceb682a854 100644 --- a/tests/ui/const-generics/associated-const-bindings/supertraits.rs +++ b/tests/ui/const-generics/associated-const-bindings/supertraits.rs @@ -16,8 +16,7 @@ use std::marker::ConstParamTy_; trait Trait: SuperTrait {} trait SuperTrait: SuperSuperTrait {} trait SuperSuperTrait { - #[type_const] - const K: T; + type const K: T; } fn take(_: impl Trait) {} diff --git a/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.rs b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.rs index 5c494031d4fa..95f81323acf4 100644 --- a/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.rs +++ b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.rs @@ -4,8 +4,7 @@ #![feature(min_generic_const_args)] trait Trait { - #[type_const] - const F: fn(); + type const F: fn(); //~^ ERROR using function pointers as const generic parameters is forbidden } diff --git a/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.stderr b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.stderr index 09d1063081fe..333dd1b89e9b 100644 --- a/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.stderr +++ b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.stderr @@ -1,8 +1,8 @@ error[E0741]: using function pointers as const generic parameters is forbidden - --> $DIR/using-fnptr-as-type_const.rs:8:14 + --> $DIR/using-fnptr-as-type_const.rs:7:19 | -LL | const F: fn(); - | ^^^^ +LL | type const F: fn(); + | ^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs b/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs index 6ec1071461c5..8cd46783d4fd 100644 --- a/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs +++ b/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs @@ -1,5 +1,4 @@ #![feature(min_generic_const_args)] #![allow(incomplete_features)] -#[type_const] -pub const NON_LOCAL_CONST: char = 'a'; +pub type const NON_LOCAL_CONST: char = 'a'; diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs index 16479ba3f64f..8470b933cadd 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs @@ -10,9 +10,9 @@ use Option::Some; fn foo>() {} + trait Trait { - #[type_const] - const ASSOC: u32; + type const ASSOC: u32; } fn bar() { diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs index 5f0d6c924bd1..68f999fb76fa 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs @@ -1,9 +1,9 @@ #![feature(min_generic_const_args, adt_const_params, unsized_const_params)] #![expect(incomplete_features)] + trait Trait { - #[type_const] - const ASSOC: usize; + type const ASSOC: usize; } fn takes_tuple() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs b/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs index d3c9b655a9e5..5def3cbb829b 100644 --- a/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs +++ b/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs @@ -16,8 +16,7 @@ struct Foo { field: T, } -#[type_const] -const WRAP: Foo = { Foo:: { +type const WRAP: Foo = { Foo:: { field: N, } }; diff --git a/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs b/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs index 47ecbfa6b7e1..7401181962bb 100644 --- a/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs +++ b/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs @@ -6,8 +6,7 @@ fn takes_array() {} trait Trait { - #[type_const] - const ASSOC: u32; + type const ASSOC: u32; } fn generic_caller() { diff --git a/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs b/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs index 460e14359483..13b2e031b118 100644 --- a/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs +++ b/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs @@ -7,13 +7,11 @@ trait Abc {} trait A { - #[type_const] - const VALUE: usize; + type const VALUE: usize; } impl A for T { - #[type_const] - const VALUE: usize = 0; + type const VALUE: usize = 0; } trait S {} diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs b/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs index a11314c11aae..ca7299e7690b 100644 --- a/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs +++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs @@ -6,9 +6,9 @@ pub trait Tr { } fn mk_array(_x: T) -> [(); T::SIZE] { - //~^ ERROR type_const + //~^ ERROR: use of `const` in the type system not defined as `type const` [(); T::SIZE] - //~^ ERROR type_const + //~^ ERROR: use of `const` in the type system not defined as `type const` } fn main() {} diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr index e06850747ff3..759a40cc0675 100644 --- a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr +++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr @@ -1,26 +1,20 @@ -error: use of `const` in the type system without `#[type_const]` +error: use of `const` in the type system not defined as `type const` --> $DIR/assoc-const-without-type_const.rs:8:35 | +LL | const SIZE: usize; + | - help: add `type` before `const` for `Tr::SIZE`: `type` +... LL | fn mk_array(_x: T) -> [(); T::SIZE] { | ^^^^^^^ - | -help: add `#[type_const]` attribute to `Tr::SIZE` - | -LL + #[type_const] -LL | const SIZE: usize; - | -error: use of `const` in the type system without `#[type_const]` +error: use of `const` in the type system not defined as `type const` --> $DIR/assoc-const-without-type_const.rs:10:10 | +LL | const SIZE: usize; + | - help: add `type` before `const` for `Tr::SIZE`: `type` +... LL | [(); T::SIZE] | ^^^^^^^ - | -help: add `#[type_const]` attribute to `Tr::SIZE` - | -LL + #[type_const] -LL | const SIZE: usize; - | error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/assoc-const.rs b/tests/ui/const-generics/mgca/assoc-const.rs index fb5b4308a7f8..c49b84edba10 100644 --- a/tests/ui/const-generics/mgca/assoc-const.rs +++ b/tests/ui/const-generics/mgca/assoc-const.rs @@ -4,8 +4,7 @@ #![allow(incomplete_features)] pub trait Tr { - #[type_const] - const SIZE: usize; + type const SIZE: usize; } fn mk_array>(_x: T) -> [(); >::SIZE] { diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.rs b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs index bb5bdb8d7c4c..81be1ca4eb88 100644 --- a/tests/ui/const-generics/mgca/bad-type_const-syntax.rs +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs @@ -1,16 +1,16 @@ trait Tr { - #[type_const()] - //~^ ERROR malformed - //~| ERROR experimental - const N: usize; + type const N: usize; + //~^ ERROR: `type const` syntax is experimental [E0658] + //~| ERROR: associated `type const` are unstable [E0658] } struct S; impl Tr for S { - #[type_const] - //~^ ERROR experimental - const N: usize = 0; + + type const N: usize = 0; + //~^ ERROR: `type const` syntax is experimental [E0658] + //~| ERROR: associated `type const` are unstable [E0658] } fn main() {} diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr index df442c22241b..7bb2adf27199 100644 --- a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr @@ -1,33 +1,43 @@ -error[E0658]: the `#[type_const]` attribute is an experimental feature +error[E0658]: `type const` syntax is experimental --> $DIR/bad-type_const-syntax.rs:2:5 | -LL | #[type_const()] - | ^^^^^^^^^^^^^^^ +LL | type const N: usize; + | ^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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[E0658]: the `#[type_const]` attribute is an experimental feature +error[E0658]: `type const` syntax is experimental --> $DIR/bad-type_const-syntax.rs:11:5 | -LL | #[type_const] - | ^^^^^^^^^^^^^ +LL | type const N: usize = 0; + | ^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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[E0565]: malformed `type_const` attribute input +error[E0658]: associated `type const` are unstable --> $DIR/bad-type_const-syntax.rs:2:5 | -LL | #[type_const()] - | ^^^^^^^^^^^^--^ - | | | - | | didn't expect any arguments here - | help: must be of the form: `#[type_const]` +LL | type const N: usize; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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 3 previous errors +error[E0658]: associated `type const` are unstable + --> $DIR/bad-type_const-syntax.rs:11:5 + | +LL | type const N: usize = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -Some errors have detailed explanations: E0565, E0658. -For more information about an error, try `rustc --explain E0565`. +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs b/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs index 37f9c31feaa5..69d16993a7e0 100644 --- a/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs +++ b/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs @@ -4,23 +4,17 @@ #![feature(min_generic_const_args, generic_const_items)] pub trait Tr { - #[type_const] - const N1: usize; - #[type_const] - const N2: usize; - #[type_const] - const N3: usize; + type const N1: usize; + type const N2: usize; + type const N3: usize; } pub struct S; impl Tr for S { - #[type_const] - const N1: usize = 0; - #[type_const] - const N2: usize = 1; - #[type_const] - const N3: usize = 2; + type const N1: usize = 0; + type const N2: usize = 1; + type const N3: usize = 2; } fn main() {} diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs index efab01489404..9d475f8224fa 100644 --- a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs @@ -3,8 +3,8 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args)] -#[type_const] -const C: usize = 0; + +type const C: usize = 0; pub struct A {} impl A { fn fun1() {} diff --git a/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs b/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs index 823a6d58bf47..a7e46ad877e7 100644 --- a/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs +++ b/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs @@ -4,8 +4,7 @@ #![feature(generic_const_exprs)] #![expect(incomplete_features)] -#[type_const] -const A: u8 = A; +type const A: u8 = A; //~^ ERROR overflow normalizing the unevaluated constant `A` fn main() {} diff --git a/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr b/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr index 1ce2af817277..47653dd1896f 100644 --- a/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr +++ b/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow normalizing the unevaluated constant `A` - --> $DIR/cyclic-type-const-151251.rs:8:1 + --> $DIR/cyclic-type-const-151251.rs:7:1 | -LL | const A: u8 = A; - | ^^^^^^^^^^^ +LL | type const A: u8 = A; + | ^^^^^^^^^^^^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs index bf825a44b1c0..2b9909b43dfb 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -34,22 +34,22 @@ fn repeats() -> [(); N] { //~^ ERROR: generic parameters may not be used in const operations } -#[type_const] -const ITEM1: usize = N; -#[type_const] -const ITEM2: usize = { N }; -#[type_const] -const ITEM3: usize = const { N }; + +type const ITEM1: usize = N; + +type const ITEM2: usize = { N }; + +type const ITEM3: usize = const { N }; //~^ ERROR: generic parameters may not be used in const operations -#[type_const] -const ITEM4: usize = { 1 + 1 }; + +type const ITEM4: usize = { 1 + 1 }; //~^ ERROR: complex const arguments must be placed inside of a `const` block -#[type_const] -const ITEM5: usize = const { 1 + 1}; + +type const ITEM5: usize = const { 1 + 1}; trait Trait { - #[type_const] - const ASSOC: usize; + + type const ASSOC: usize; } fn ace_bounds< diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index 1251f4415171..714d7a804d11 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -17,10 +17,10 @@ LL | let _4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:45:38 + --> $DIR/explicit_anon_consts.rs:45:43 | -LL | const ITEM4: usize = { 1 + 1 }; - | ^^^^^^^^^ +LL | type const ITEM4: usize = { 1 + 1 }; + | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block --> $DIR/explicit_anon_consts.rs:62:23 @@ -35,10 +35,10 @@ LL | struct Default4; | ^^^^^^^^^ error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:42:46 + --> $DIR/explicit_anon_consts.rs:42:51 | -LL | const ITEM3: usize = const { N }; - | ^ +LL | type const ITEM3: usize = const { N }; + | ^ | = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs index 8131a5b72343..be853bb87a37 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs @@ -4,8 +4,7 @@ #![expect(incomplete_features)] trait Trait { - #[type_const] - const ASSOC: isize; + type const ASSOC: isize; } fn ace>() {} diff --git a/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs b/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs index 31f54abf31ef..bbe624269672 100644 --- a/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs +++ b/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs @@ -6,8 +6,7 @@ struct Foo; trait Trait { - #[type_const] - const ASSOC: usize; + type const ASSOC: usize; } type Arr = [(); {{{ N }}}]; diff --git a/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs b/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs index e98cbdf8e617..6f1235269dfc 100644 --- a/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs +++ b/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs @@ -5,5 +5,5 @@ extern crate non_local_const; fn main() { let x = [(); non_local_const::N]; - //~^ ERROR use of `const` in the type system without `#[type_const]` + //~^ ERROR: use of `const` in the type system not defined as `type const` } diff --git a/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr b/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr index 671dfa5fbb9e..3c10b78eb3e1 100644 --- a/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr +++ b/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr @@ -1,10 +1,10 @@ -error: use of `const` in the type system without `#[type_const]` +error: use of `const` in the type system not defined as `type const` --> $DIR/non-local-const-without-type_const.rs:7:18 | LL | let x = [(); non_local_const::N]; | ^^^^^^^^^^^^^^^^^^ | - = note: only consts marked with `#[type_const]` may be used in types + = note: only consts marked defined as `type const` may be used in types error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs index 819323d9cbec..16ed24a7b287 100644 --- a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs @@ -8,8 +8,8 @@ struct Foo; trait Trait { - #[type_const] - const ASSOC: u32; + + type const ASSOC: u32; } fn foo() {} diff --git a/tests/ui/const-generics/mgca/projection-error.rs b/tests/ui/const-generics/mgca/projection-error.rs index edb6db098084..d3bd520297e1 100644 --- a/tests/ui/const-generics/mgca/projection-error.rs +++ b/tests/ui/const-generics/mgca/projection-error.rs @@ -5,10 +5,8 @@ // containing erroneous types normalizes to a const error instead of // a type error. - pub trait Tr { - #[type_const] - const SIZE: usize; + type const SIZE: usize; } fn mk_array(_x: T) -> [(); >::SIZE] {} diff --git a/tests/ui/const-generics/mgca/projection-error.stderr b/tests/ui/const-generics/mgca/projection-error.stderr index 9357600a5e11..94e6bbcdd87f 100644 --- a/tests/ui/const-generics/mgca/projection-error.stderr +++ b/tests/ui/const-generics/mgca/projection-error.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find type `T` in this scope - --> $DIR/projection-error.rs:14:17 + --> $DIR/projection-error.rs:12:17 | LL | pub trait Tr { | --------------- similarly named trait `Tr` defined here @@ -17,7 +17,7 @@ LL | fn mk_array(_x: T) -> [(); >::SIZE] {} | +++ error[E0425]: cannot find type `T` in this scope - --> $DIR/projection-error.rs:14:29 + --> $DIR/projection-error.rs:12:29 | LL | pub trait Tr { | --------------- similarly named trait `Tr` defined here diff --git a/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs b/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs index a5b3d3d0d5b6..e946441453d8 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs +++ b/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs @@ -15,8 +15,7 @@ enum MyEnum { } trait Trait { - #[type_const] - const ASSOC: u32; + type const ASSOC: u32; } fn with_point() -> Point { diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs index ebbe097c226e..95ee42d93d73 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs @@ -12,8 +12,8 @@ enum MyEnum { Unit, } -#[type_const] -const CONST_ITEM: u32 = 42; + +type const CONST_ITEM: u32 = 42; fn accepts_point() {} fn accepts_enum>() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs index e47052523fa3..5a40c1b14c2d 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs @@ -2,8 +2,8 @@ #![expect(incomplete_features)] trait Trait { - #[type_const] - const ASSOC: usize; + + type const ASSOC: usize; } fn takes_tuple() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_simple.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_simple.rs index 3fde431e27e2..4c040bcaa945 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_simple.rs +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_simple.rs @@ -4,8 +4,7 @@ #![expect(incomplete_features)] trait Trait { - #[type_const] - const ASSOC: u32; + type const ASSOC: u32; } fn takes_tuple() {} diff --git a/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs index 158a7addd10d..e98b1ad4fe37 100644 --- a/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs +++ b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs @@ -4,15 +4,13 @@ #![expect(incomplete_features)] trait Tr { - #[type_const] - const SIZE: usize; + type const SIZE: usize; } struct T; impl Tr for T { - #[type_const] - const SIZE: usize; + type const SIZE: usize; //~^ ERROR associated constant in `impl` without body } diff --git a/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr index 2db677aa0ca6..ba01456ee040 100644 --- a/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr +++ b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr @@ -1,10 +1,10 @@ error: associated constant in `impl` without body - --> $DIR/type-const-assoc-const-without-body.rs:15:5 + --> $DIR/type-const-assoc-const-without-body.rs:13:5 | -LL | const SIZE: usize; - | ^^^^^^^^^^^^^^^^^- - | | - | help: provide a definition for the constant: `= ;` +LL | type const SIZE: usize; + | ^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs index 85b2327d3351..9fa417637295 100644 --- a/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs +++ b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs @@ -4,8 +4,7 @@ #![expect(incomplete_features)] impl S { //~ ERROR cannot find type `S` in this scope - #[type_const] - const SIZE: usize; + type const SIZE: usize; //~^ ERROR associated constant in `impl` without body } diff --git a/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr index ac520a4e6946..b1e1edfa70d6 100644 --- a/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr +++ b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr @@ -1,10 +1,10 @@ error: associated constant in `impl` without body - --> $DIR/type-const-inherent-assoc-const-without-body.rs:8:5 + --> $DIR/type-const-inherent-assoc-const-without-body.rs:7:5 | -LL | const SIZE: usize; - | ^^^^^^^^^^^^^^^^^- - | | - | help: provide a definition for the constant: `= ;` +LL | type const SIZE: usize; + | ^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` error[E0425]: cannot find type `S` in this scope --> $DIR/type-const-inherent-assoc-const-without-body.rs:6:6 diff --git a/tests/ui/const-generics/mgca/type-const-used-in-trait.rs b/tests/ui/const-generics/mgca/type-const-used-in-trait.rs index c98c14775a0f..1efc65bd7018 100644 --- a/tests/ui/const-generics/mgca/type-const-used-in-trait.rs +++ b/tests/ui/const-generics/mgca/type-const-used-in-trait.rs @@ -3,8 +3,7 @@ #![feature(min_generic_const_args)] #![expect(incomplete_features)] -#[type_const] -const N: usize = 2; +type const N: usize = 2; trait CollectArray { fn inner_array(&mut self) -> [A; N]; diff --git a/tests/ui/const-generics/mgca/type_const-array-return.rs b/tests/ui/const-generics/mgca/type_const-array-return.rs index 5375e4fded6d..43db35966a45 100644 --- a/tests/ui/const-generics/mgca/type_const-array-return.rs +++ b/tests/ui/const-generics/mgca/type_const-array-return.rs @@ -6,14 +6,12 @@ pub struct A; pub trait Array { - #[type_const] - const LEN: usize; + type const LEN: usize; fn arr() -> [u8; Self::LEN]; } impl Array for A { - #[type_const] - const LEN: usize = 4; + type const LEN: usize = 4; #[allow(unused_braces)] fn arr() -> [u8; const { Self::LEN }] { diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr index 8a64af285da5..095f42355c77 100644 --- a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr @@ -1,38 +1,38 @@ error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:9:53 + --> $DIR/type_const-generic-param-in-type.rs:8:58 | -LL | const FOO: [T; 0] = const { [] }; - | ^^^^^^^^^^^^ +LL | type const FOO: [T; 0] = const { [] }; + | ^^^^^^^^^^^^ error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:14:38 + --> $DIR/type_const-generic-param-in-type.rs:12:43 | -LL | const BAR: [(); N] = const { [] }; - | ^^^^^^^^^^^^ +LL | type const BAR: [(); N] = const { [] }; + | ^^^^^^^^^^^^ error: anonymous constants with lifetimes in their type are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:19:30 + --> $DIR/type_const-generic-param-in-type.rs:16:35 | -LL | const BAZ<'a>: [&'a (); 0] = const { [] }; - | ^^^^^^^^^^^^ +LL | type const BAZ<'a>: [&'a (); 0] = const { [] }; + | ^^^^^^^^^^^^ error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:39:59 + --> $DIR/type_const-generic-param-in-type.rs:32:64 | -LL | const ASSOC: [T; 0] = const { [] }; - | ^^^^^^^^^^^^ +LL | type const ASSOC: [T; 0] = const { [] }; + | ^^^^^^^^^^^^ error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:44:50 + --> $DIR/type_const-generic-param-in-type.rs:36:55 | -LL | const ASSOC_CONST: [(); N] = const { [] }; - | ^^^^^^^^^^^^ +LL | type const ASSOC_CONST: [(); N] = const { [] }; + | ^^^^^^^^^^^^ error: anonymous constants with lifetimes in their type are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:49:39 + --> $DIR/type_const-generic-param-in-type.rs:40:44 | -LL | const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; - | ^^^^^^^^^^^^ +LL | type const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; + | ^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr index 14ae276324ad..b18bd678973a 100644 --- a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr @@ -1,56 +1,56 @@ error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/type_const-generic-param-in-type.rs:9:45 + --> $DIR/type_const-generic-param-in-type.rs:8:50 | -LL | const FOO: [T; 0] = const { [] }; - | ^ the type must not depend on the parameter `T` +LL | type const FOO: [T; 0] = const { [] }; + | ^ the type must not depend on the parameter `T` error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/type_const-generic-param-in-type.rs:14:33 + --> $DIR/type_const-generic-param-in-type.rs:12:38 | -LL | const BAR: [(); N] = const { [] }; - | ^ the type must not depend on the parameter `N` +LL | type const BAR: [(); N] = const { [] }; + | ^ the type must not depend on the parameter `N` error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/type_const-generic-param-in-type.rs:19:18 + --> $DIR/type_const-generic-param-in-type.rs:16:23 | -LL | const BAZ<'a>: [&'a (); 0] = const { [] }; - | ^^ the type must not depend on the parameter `'a` +LL | type const BAZ<'a>: [&'a (); 0] = const { [] }; + | ^^ the type must not depend on the parameter `'a` error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/type_const-generic-param-in-type.rs:25:51 + --> $DIR/type_const-generic-param-in-type.rs:21:56 | -LL | const ASSOC: [T; 0]; - | ^ the type must not depend on the parameter `T` +LL | type const ASSOC: [T; 0]; + | ^ the type must not depend on the parameter `T` error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/type_const-generic-param-in-type.rs:29:45 + --> $DIR/type_const-generic-param-in-type.rs:24:50 | -LL | const ASSOC_CONST: [(); N]; - | ^ the type must not depend on the parameter `N` +LL | type const ASSOC_CONST: [(); N]; + | ^ the type must not depend on the parameter `N` error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/type_const-generic-param-in-type.rs:33:27 + --> $DIR/type_const-generic-param-in-type.rs:27:32 | -LL | const ASSOC_LT<'a>: [&'a (); 0]; - | ^^ the type must not depend on the parameter `'a` +LL | type const ASSOC_LT<'a>: [&'a (); 0]; + | ^^ the type must not depend on the parameter `'a` error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/type_const-generic-param-in-type.rs:39:51 + --> $DIR/type_const-generic-param-in-type.rs:32:56 | -LL | const ASSOC: [T; 0] = const { [] }; - | ^ the type must not depend on the parameter `T` +LL | type const ASSOC: [T; 0] = const { [] }; + | ^ the type must not depend on the parameter `T` error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/type_const-generic-param-in-type.rs:44:45 + --> $DIR/type_const-generic-param-in-type.rs:36:50 | -LL | const ASSOC_CONST: [(); N] = const { [] }; - | ^ the type must not depend on the parameter `N` +LL | type const ASSOC_CONST: [(); N] = const { [] }; + | ^ the type must not depend on the parameter `N` error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/type_const-generic-param-in-type.rs:49:27 + --> $DIR/type_const-generic-param-in-type.rs:40:32 | -LL | const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; - | ^^ the type must not depend on the parameter `'a` +LL | type const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; + | ^^ the type must not depend on the parameter `'a` error: aborting due to 9 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs index f1a4aba9bcee..72ae464822e4 100644 --- a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs @@ -5,48 +5,39 @@ #![feature(adt_const_params, unsized_const_params, min_generic_const_args, generic_const_items)] #![cfg_attr(gate, feature(generic_const_parameter_types))] -#[type_const] -const FOO: [T; 0] = const { [] }; +type const FOO: [T; 0] = const { [] }; //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters //[gate]~^^ ERROR anonymous constants referencing generics are not yet supported -#[type_const] -const BAR: [(); N] = const { [] }; +type const BAR: [(); N] = const { [] }; //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters //[gate]~^^ ERROR anonymous constants referencing generics are not yet supported -#[type_const] -const BAZ<'a>: [&'a (); 0] = const { [] }; +type const BAZ<'a>: [&'a (); 0] = const { [] }; //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters //[gate]~^^ ERROR anonymous constants with lifetimes in their type are not yet supported trait Tr { - #[type_const] - const ASSOC: [T; 0]; + type const ASSOC: [T; 0]; //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters - #[type_const] - const ASSOC_CONST: [(); N]; + type const ASSOC_CONST: [(); N]; //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters - #[type_const] - const ASSOC_LT<'a>: [&'a (); 0]; + type const ASSOC_LT<'a>: [&'a (); 0]; //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters } impl Tr for () { - #[type_const] - const ASSOC: [T; 0] = const { [] }; + type const ASSOC: [T; 0] = const { [] }; //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters //[gate]~^^ ERROR anonymous constants referencing generics are not yet supported - #[type_const] - const ASSOC_CONST: [(); N] = const { [] }; + type const ASSOC_CONST: [(); N] = const { [] }; //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters //[gate]~^^ ERROR anonymous constants referencing generics are not yet supported - #[type_const] - const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; + type const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters //[gate]~^^ ERROR anonymous constants with lifetimes in their type are not yet supported } diff --git a/tests/ui/const-generics/mgca/type_const-incemental-compile.rs b/tests/ui/const-generics/mgca/type_const-incemental-compile.rs index 60e6968363db..7094d89d5062 100644 --- a/tests/ui/const-generics/mgca/type_const-incemental-compile.rs +++ b/tests/ui/const-generics/mgca/type_const-incemental-compile.rs @@ -6,6 +6,5 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args)] -#[type_const] -const TYPE_CONST: usize = 0; +type const TYPE_CONST: usize = 0; fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs index b2c734098009..3262e79478bd 100644 --- a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs @@ -4,8 +4,7 @@ struct A; impl A { - #[type_const] - const B = 4; + type const B = 4; //~^ ERROR: missing type for `const` item } diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr index b44e47cd7e61..77e54ab2f2e9 100644 --- a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr @@ -1,13 +1,13 @@ error: missing type for `const` item - --> $DIR/type_const-inherent-const-omitted-type.rs:8:12 + --> $DIR/type_const-inherent-const-omitted-type.rs:7:17 | -LL | const B = 4; - | ^ +LL | type const B = 4; + | ^ | help: provide a type for the item | -LL | const B: = 4; - | ++++++++ +LL | type const B: = 4; + | ++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs index 8d2eae71d330..460c5d7b2199 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs @@ -1,22 +1,18 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args)] -#[type_const] -const FREE: u32 = 5_usize; +type const FREE: u32 = 5_usize; //~^ ERROR mismatched types -#[type_const] -const FREE2: isize = FREE; +type const FREE2: isize = FREE; //~^ ERROR the constant `5` is not of type `isize` trait Tr { - #[type_const] - const N: usize; + type const N: usize; } impl Tr for () { - #[type_const] - const N: usize = false; + type const N: usize = false; //~^ ERROR mismatched types } diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr index 4029bb7b6bff..152dd9ec0cca 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr @@ -1,26 +1,26 @@ error: the constant `5` is not of type `isize` - --> $DIR/type_const-mismatched-types.rs:9:1 + --> $DIR/type_const-mismatched-types.rs:7:1 | -LL | const FREE2: isize = FREE; - | ^^^^^^^^^^^^^^^^^^ expected `isize`, found `u32` +LL | type const FREE2: isize = FREE; + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `u32` error[E0308]: mismatched types - --> $DIR/type_const-mismatched-types.rs:5:19 + --> $DIR/type_const-mismatched-types.rs:4:24 | -LL | const FREE: u32 = 5_usize; - | ^^^^^^^ expected `u32`, found `usize` +LL | type const FREE: u32 = 5_usize; + | ^^^^^^^ expected `u32`, found `usize` | help: change the type of the numeric literal from `usize` to `u32` | -LL - const FREE: u32 = 5_usize; -LL + const FREE: u32 = 5_u32; +LL - type const FREE: u32 = 5_usize; +LL + type const FREE: u32 = 5_u32; | error[E0308]: mismatched types - --> $DIR/type_const-mismatched-types.rs:19:22 + --> $DIR/type_const-mismatched-types.rs:15:27 | -LL | const N: usize = false; - | ^^^^^ expected `usize`, found `bool` +LL | type const N: usize = false; + | ^^^^^ expected `usize`, found `bool` error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-not-constparamty.rs b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs index 11db82187b84..b78bb4ca599d 100644 --- a/tests/ui/const-generics/mgca/type_const-not-constparamty.rs +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs @@ -5,21 +5,18 @@ struct S; // FIXME(mgca): need support for ctors without anon const // (we use a const-block to trigger an anon const here) -#[type_const] -const FREE: S = const { S }; +type const FREE: S = const { S }; //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter trait Tr { - #[type_const] - const N: S; + type const N: S; //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter } impl Tr for S { // FIXME(mgca): need support for ctors without anon const // (we use a const-block to trigger an anon const here) - #[type_const] - const N: S = const { S }; + type const N: S = const { S }; //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter } diff --git a/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr index d07bbde1e62e..2cbb644f2c71 100644 --- a/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr @@ -1,8 +1,8 @@ error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/type_const-not-constparamty.rs:9:13 + --> $DIR/type_const-not-constparamty.rs:8:18 | -LL | const FREE: S = const { S }; - | ^ +LL | type const FREE: S = const { S }; + | ^ | help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct | @@ -11,10 +11,10 @@ LL | struct S; | error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/type_const-not-constparamty.rs:22:14 + --> $DIR/type_const-not-constparamty.rs:19:19 | -LL | const N: S = const { S }; - | ^ +LL | type const N: S = const { S }; + | ^ | help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct | @@ -23,10 +23,10 @@ LL | struct S; | error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/type_const-not-constparamty.rs:14:14 + --> $DIR/type_const-not-constparamty.rs:12:19 | -LL | const N: S; - | ^ +LL | type const N: S; + | ^ | help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct | diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs index ac4c4fb59419..f4cf3a4c5ce9 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs @@ -1,11 +1,11 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args, generic_const_items)] -#[type_const] -const FREE1: usize = const { std::mem::size_of::() }; + +type const FREE1: usize = const { std::mem::size_of::() }; //~^ ERROR generic parameters may not be used in const operations -#[type_const] -const FREE2: usize = const { I + 1 }; + +type const FREE2: usize = const { I + 1 }; //~^ ERROR generic parameters may not be used in const operations fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr index 8d43f2177562..475d2cf312d6 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -1,16 +1,16 @@ error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:5:53 + --> $DIR/type_const-on-generic-expr.rs:5:58 | -LL | const FREE1: usize = const { std::mem::size_of::() }; - | ^ +LL | type const FREE1: usize = const { std::mem::size_of::() }; + | ^ | = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:8:46 + --> $DIR/type_const-on-generic-expr.rs:8:51 | -LL | const FREE2: usize = const { I + 1 }; - | ^ +LL | type const FREE2: usize = const { I + 1 }; + | ^ | = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs index 37de4d4a4abb..2a26138d373f 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs @@ -2,25 +2,19 @@ #![feature(min_generic_const_args, generic_const_items)] pub trait Tr { - #[type_const] - const N1: usize; - #[type_const] - const N2: usize; - #[type_const] - const N3: usize; + type const N1: usize; + type const N2: usize; + type const N3: usize; } pub struct S; impl Tr for S { - #[type_const] - const N1: usize = const { std::mem::size_of::() }; + type const N1: usize = const { std::mem::size_of::() }; //~^ ERROR generic parameters may not be used in const operations - #[type_const] - const N2: usize = const { I + 1 }; + type const N2: usize = const { I + 1 }; //~^ ERROR generic parameters may not be used in const operations - #[type_const] - const N3: usize = const { 2 & X }; + type const N3: usize = const { 2 & X }; //~^ ERROR generic parameters may not be used in const operations } diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr index 1a6097752e33..e13d6fbcdd82 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr @@ -1,24 +1,24 @@ error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic_expr-2.rs:17:54 + --> $DIR/type_const-on-generic_expr-2.rs:13:59 | -LL | const N1: usize = const { std::mem::size_of::() }; - | ^ +LL | type const N1: usize = const { std::mem::size_of::() }; + | ^ | = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic_expr-2.rs:20:47 + --> $DIR/type_const-on-generic_expr-2.rs:15:52 | -LL | const N2: usize = const { I + 1 }; - | ^ +LL | type const N2: usize = const { I + 1 }; + | ^ | = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic_expr-2.rs:23:35 + --> $DIR/type_const-on-generic_expr-2.rs:17:40 | -LL | const N3: usize = const { 2 & X }; - | ^ +LL | type const N3: usize = const { 2 & X }; + | ^ | = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs index ab613859aa5c..a7ff9f0ce03f 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs @@ -8,14 +8,13 @@ trait BadTr { struct GoodS; impl BadTr for GoodS { - #[type_const] - const NUM: = 84; + type const NUM: = 84; //~^ ERROR: missing type for `const` item } fn accept_bad_tr>(_x: &T) {} -//~^ ERROR use of trait associated const without `#[type_const]` +//~^ ERROR use of trait associated const not defined as `type const` fn main() { accept_bad_tr::<84, _>(&GoodS); diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr index 16f312454ed2..11a60246f6a6 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr @@ -1,16 +1,16 @@ error: missing type for `const` item - --> $DIR/type_const-only-in-impl-omitted-type.rs:12:15 + --> $DIR/type_const-only-in-impl-omitted-type.rs:11:20 | -LL | const NUM: = 84; - | ^ help: provide a type for the associated constant: `usize` +LL | type const NUM: = 84; + | ^ help: provide a type for the associated constant: `usize` -error: use of trait associated const without `#[type_const]` - --> $DIR/type_const-only-in-impl-omitted-type.rs:17:43 +error: use of trait associated const not defined as `type const` + --> $DIR/type_const-only-in-impl-omitted-type.rs:16:43 | LL | fn accept_bad_tr>(_x: &T) {} | ^^^^^^^^^^^ | - = note: the declaration in the trait must be marked with `#[type_const]` + = note: the declaration in the trait must begin with `type const` not just `const` alone error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl.rs b/tests/ui/const-generics/mgca/type_const-only-in-impl.rs index 1887f511bd62..e016908b3cc3 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl.rs @@ -8,12 +8,11 @@ trait BadTr { struct GoodS; impl BadTr for GoodS { - #[type_const] - const NUM: usize = 84; + type const NUM: usize = 84; } fn accept_bad_tr>(_x: &T) {} -//~^ ERROR use of trait associated const without `#[type_const]` +//~^ ERROR use of trait associated const not defined as `type const` fn main() { accept_bad_tr::<84, _>(&GoodS); diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr b/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr index 44632e46fb07..55d5cca6ba69 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr @@ -1,10 +1,10 @@ -error: use of trait associated const without `#[type_const]` - --> $DIR/type_const-only-in-impl.rs:15:43 +error: use of trait associated const not defined as `type const` + --> $DIR/type_const-only-in-impl.rs:14:43 | LL | fn accept_bad_tr>(_x: &T) {} | ^^^^^^^^^^^ | - = note: the declaration in the trait must be marked with `#[type_const]` + = note: the declaration in the trait must begin with `type const` not just `const` alone error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/type_const-only-in-trait.rs b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs index 2ff38648206a..1def66a1ba68 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-trait.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs @@ -2,15 +2,14 @@ #![feature(min_generic_const_args)] trait GoodTr { - #[type_const] - const NUM: usize; + type const NUM: usize; } struct BadS; impl GoodTr for BadS { const NUM: usize = 42; - //~^ ERROR implementation of `#[type_const]` const must be marked with `#[type_const]` + //~^ ERROR implementation of a `type const` must also be marked as `type const` } fn accept_good_tr>(_x: &T) {} diff --git a/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr b/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr index 29f1b724960a..f98b4d9cbbfd 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr +++ b/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr @@ -1,16 +1,14 @@ -error: implementation of `#[type_const]` const must be marked with `#[type_const]` - --> $DIR/type_const-only-in-trait.rs:12:5 +error: implementation of a `type const` must also be marked as `type const` + --> $DIR/type_const-only-in-trait.rs:11:5 | LL | const NUM: usize = 42; | ^^^^^^^^^^^^^^^^ | -note: trait declaration of const is marked with `#[type_const]` +note: trait declaration of const is marked as `type const` --> $DIR/type_const-only-in-trait.rs:5:5 | -LL | #[type_const] - | ^^^^^^^^^^^^^ -LL | const NUM: usize; - | ^^^^^^^^^^^^^^^^ +LL | type const NUM: usize; + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/type_const-pub.rs b/tests/ui/const-generics/mgca/type_const-pub.rs index f443562394df..70fab75901b9 100644 --- a/tests/ui/const-generics/mgca/type_const-pub.rs +++ b/tests/ui/const-generics/mgca/type_const-pub.rs @@ -5,8 +5,7 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args)] -#[type_const] -pub const TYPE_CONST : usize = 1; +pub type const TYPE_CONST : usize = 1; fn main() { print!("{}", TYPE_CONST) } diff --git a/tests/ui/const-generics/mgca/type_const-recursive.rs b/tests/ui/const-generics/mgca/type_const-recursive.rs index 15e49f747ed6..ebaab51bbc3b 100644 --- a/tests/ui/const-generics/mgca/type_const-recursive.rs +++ b/tests/ui/const-generics/mgca/type_const-recursive.rs @@ -1,8 +1,8 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args)] -#[type_const] -const A: u8 = A; + +type const A: u8 = A; //~^ ERROR: overflow normalizing the unevaluated constant `A` [E0275] fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-recursive.stderr b/tests/ui/const-generics/mgca/type_const-recursive.stderr index 947319ec7eda..d21ccb22bc90 100644 --- a/tests/ui/const-generics/mgca/type_const-recursive.stderr +++ b/tests/ui/const-generics/mgca/type_const-recursive.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow normalizing the unevaluated constant `A` --> $DIR/type_const-recursive.rs:5:1 | -LL | const A: u8 = A; - | ^^^^^^^^^^^ +LL | type const A: u8 = A; + | ^^^^^^^^^^^^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead diff --git a/tests/ui/const-generics/mgca/type_const-use.rs b/tests/ui/const-generics/mgca/type_const-use.rs index 04362cd28538..f295bf465e30 100644 --- a/tests/ui/const-generics/mgca/type_const-use.rs +++ b/tests/ui/const-generics/mgca/type_const-use.rs @@ -3,8 +3,7 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args)] -#[type_const] -const CONST: usize = 1; +type const CONST: usize = 1; fn uses_const() { CONST; diff --git a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs index c01fb47002b2..cf75b45b9ff0 100644 --- a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs +++ b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs @@ -32,9 +32,10 @@ fn generic() { const NON_TYPE_CONST: usize = const { 1 }; -#[type_const] -//~^ ERROR: the `#[type_const]` attribute is an experimental feature -const TYPE_CONST: usize = const { 1 }; + +type const TYPE_CONST: usize = const { 1 }; +//~^ ERROR: `type const` syntax is experimental [E0658] +//~| ERROR: top-level `type const` are unstable [E0658] static STATIC: usize = const { 1 }; diff --git a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr index bbcd9f9897a6..dbcb8c56ac5b 100644 --- a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr +++ b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr @@ -48,16 +48,26 @@ LL | generic::(); = help: add `#![feature(min_generic_const_args)]` 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[E0658]: the `#[type_const]` attribute is an experimental feature - --> $DIR/unbraced_const_block_const_arg_gated.rs:35:1 +error[E0658]: `type const` syntax is experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:36:1 | -LL | #[type_const] - | ^^^^^^^^^^^^^ +LL | type const TYPE_CONST: usize = const { 1 }; + | ^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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 6 previous errors +error[E0658]: top-level `type const` are unstable + --> $DIR/unbraced_const_block_const_arg_gated.rs:36:1 + | +LL | type const TYPE_CONST: usize = const { 1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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 7 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/mgca/unmarked-free-const.rs b/tests/ui/const-generics/mgca/unmarked-free-const.rs index a517231facb7..d6d9b936d95b 100644 --- a/tests/ui/const-generics/mgca/unmarked-free-const.rs +++ b/tests/ui/const-generics/mgca/unmarked-free-const.rs @@ -7,5 +7,5 @@ const N: usize = 4; fn main() { let x = [(); N]; - //~^ ERROR use of `const` in the type system without `#[type_const]` + //~^ ERROR use of `const` in the type system not defined as `type const` } diff --git a/tests/ui/const-generics/mgca/unmarked-free-const.stderr b/tests/ui/const-generics/mgca/unmarked-free-const.stderr index 052ae39fdf67..76875d8db0ef 100644 --- a/tests/ui/const-generics/mgca/unmarked-free-const.stderr +++ b/tests/ui/const-generics/mgca/unmarked-free-const.stderr @@ -1,14 +1,11 @@ -error: use of `const` in the type system without `#[type_const]` +error: use of `const` in the type system not defined as `type const` --> $DIR/unmarked-free-const.rs:9:18 | +LL | const N: usize = 4; + | - help: add `type` before `const` for `N`: `type` +... LL | let x = [(); N]; | ^ - | -help: add `#[type_const]` attribute to `N` - | -LL + #[type_const] -LL | const N: usize = 4; - | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.rs b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.rs index d290619a04ff..909189ae4875 100644 --- a/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.rs +++ b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.rs @@ -4,8 +4,8 @@ #![allow(incomplete_features)] trait Trait { - #[type_const] - const ASSOC: u8; + + type const ASSOC: u8; } struct TakesArr; diff --git a/tests/ui/const-generics/ogca/basic-fail.rs b/tests/ui/const-generics/ogca/basic-fail.rs index 87176c7b067e..e3db3dea3735 100644 --- a/tests/ui/const-generics/ogca/basic-fail.rs +++ b/tests/ui/const-generics/ogca/basic-fail.rs @@ -3,17 +3,13 @@ #![feature(opaque_generic_const_args)] #![expect(incomplete_features)] -#[type_const] -const ADD1: usize = const { N + 1 }; +type const ADD1: usize = const { N + 1 }; -#[type_const] -const INC: usize = const { N + 1 }; +type const INC: usize = const { N + 1 }; -#[type_const] -const ONE: usize = ADD1::<0>; +type const ONE: usize = ADD1::<0>; -#[type_const] -const OTHER_ONE: usize = INC::<0>; +type const OTHER_ONE: usize = INC::<0>; // Not definitionally equal. const ARR: [(); ADD1::<0>] = [(); INC::<0>]; diff --git a/tests/ui/const-generics/ogca/basic-fail.stderr b/tests/ui/const-generics/ogca/basic-fail.stderr index 05de01b132c6..ce4e8eb1471c 100644 --- a/tests/ui/const-generics/ogca/basic-fail.stderr +++ b/tests/ui/const-generics/ogca/basic-fail.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/basic-fail.rs:19:30 + --> $DIR/basic-fail.rs:15:30 | LL | const ARR: [(); ADD1::<0>] = [(); INC::<0>]; | ^^^^^^^^^^^^^^ expected an array with a size of const { N + 1 }, found one with a size of const { N + 1 } diff --git a/tests/ui/const-generics/ogca/basic.rs b/tests/ui/const-generics/ogca/basic.rs index c8aec9ee24ce..e736484b5c3c 100644 --- a/tests/ui/const-generics/ogca/basic.rs +++ b/tests/ui/const-generics/ogca/basic.rs @@ -5,17 +5,13 @@ #![feature(opaque_generic_const_args)] #![expect(incomplete_features)] -#[type_const] -const ADD1: usize = const { N + 1 }; +type const ADD1: usize = const { N + 1 }; -#[type_const] -const INC: usize = ADD1::; +type const INC: usize = ADD1::; -#[type_const] -const ONE: usize = ADD1::<0>; +type const ONE: usize = ADD1::<0>; -#[type_const] -const OTHER_ONE: usize = INC::<0>; +type const OTHER_ONE: usize = INC::<0>; const ARR: [(); ADD1::<0>] = [(); INC::<0>]; diff --git a/tests/ui/const-generics/ogca/coherence-ambiguous.rs b/tests/ui/const-generics/ogca/coherence-ambiguous.rs index c8c088b1e8fc..21efe4cfe981 100644 --- a/tests/ui/const-generics/ogca/coherence-ambiguous.rs +++ b/tests/ui/const-generics/ogca/coherence-ambiguous.rs @@ -4,11 +4,9 @@ #![feature(generic_const_items, min_generic_const_args, opaque_generic_const_args)] #![expect(incomplete_features)] -#[type_const] -const FOO: usize = const { N + 1 }; +type const FOO: usize = const { N + 1 }; -#[type_const] -const BAR: usize = const { N + 1 }; +type const BAR: usize = const { N + 1 }; trait Trait {} diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.rs b/tests/ui/const-generics/ogca/rhs-but-not-root.rs index 4ed136f04ced..2897b16d493f 100644 --- a/tests/ui/const-generics/ogca/rhs-but-not-root.rs +++ b/tests/ui/const-generics/ogca/rhs-but-not-root.rs @@ -4,11 +4,9 @@ #![expect(incomplete_features)] // Anon consts must be the root of the RHS to be OGCA. -#[type_const] -const FOO: usize = ID::; +type const FOO: usize = ID::; //~^ ERROR generic parameters may not be used in const operations -#[type_const] -const ID: usize = N; +type const ID: usize = N; fn main() {} diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.stderr b/tests/ui/const-generics/ogca/rhs-but-not-root.stderr index f4fdf5fb981b..c720b58b9bde 100644 --- a/tests/ui/const-generics/ogca/rhs-but-not-root.stderr +++ b/tests/ui/const-generics/ogca/rhs-but-not-root.stderr @@ -1,8 +1,8 @@ error: generic parameters may not be used in const operations - --> $DIR/rhs-but-not-root.rs:8:49 + --> $DIR/rhs-but-not-root.rs:7:54 | -LL | const FOO: usize = ID::; - | ^ +LL | type const FOO: usize = ID::; + | ^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/type-relative-path-144547.rs b/tests/ui/const-generics/type-relative-path-144547.rs index b268055e1f7d..e3532fe635c2 100644 --- a/tests/ui/const-generics/type-relative-path-144547.rs +++ b/tests/ui/const-generics/type-relative-path-144547.rs @@ -2,20 +2,21 @@ //@ revisions: min mgca //@[mgca] check-pass - +#![allow(incomplete_features)] +#![feature(mgca_type_const_syntax)] #![cfg_attr(mgca, feature(min_generic_const_args))] -#![cfg_attr(mgca, expect(incomplete_features))] +// FIXME(mgca) syntax is it's own feature flag before +// expansion and is also an incomplete feature. +//#![cfg_attr(mgca, expect(incomplete_features))] trait UnderlyingImpl { type InfoType: LevelInfo; type SupportedArray; } -// FIXME: cfg_attr(..., type_const) is broken (search for sym::type_const in compiler/) trait LevelInfo { #[cfg(mgca)] - #[type_const] - const SUPPORTED_SLOTS: usize; + type const SUPPORTED_SLOTS: usize; #[cfg(not(mgca))] const SUPPORTED_SLOTS: usize; @@ -25,8 +26,7 @@ struct Info; impl LevelInfo for Info { #[cfg(mgca)] - #[type_const] - const SUPPORTED_SLOTS: usize = 1; + type const SUPPORTED_SLOTS: usize = 1; #[cfg(not(mgca))] const SUPPORTED_SLOTS: usize = 1; diff --git a/tests/ui/feature-gates/feature-gate-mgca-type-const-syntax.rs b/tests/ui/feature-gates/feature-gate-mgca-type-const-syntax.rs new file mode 100644 index 000000000000..eea1c798fd20 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-mgca-type-const-syntax.rs @@ -0,0 +1,17 @@ +type const FOO: u8 = 10; +//~^ ERROR `type const` syntax is experimental [E0658] +//~| ERROR top-level `type const` are unstable [E0658] + +trait Bar { + type const BAR: bool; + //~^ ERROR `type const` syntax is experimental [E0658] + //~| ERROR associated `type const` are unstable [E0658] +} + +impl Bar for bool { + type const BAR: bool = false; + //~^ ERROR `type const` syntax is experimental [E0658] + //~| ERROR associated `type const` are unstable [E0658] +} + +fn main() { } diff --git a/tests/ui/feature-gates/feature-gate-mgca-type-const-syntax.stderr b/tests/ui/feature-gates/feature-gate-mgca-type-const-syntax.stderr new file mode 100644 index 000000000000..15db8b87d661 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-mgca-type-const-syntax.stderr @@ -0,0 +1,63 @@ +error[E0658]: `type const` syntax is experimental + --> $DIR/feature-gate-mgca-type-const-syntax.rs:1:1 + | +LL | type const FOO: u8 = 10; + | ^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: `type const` syntax is experimental + --> $DIR/feature-gate-mgca-type-const-syntax.rs:6:5 + | +LL | type const BAR: bool; + | ^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: `type const` syntax is experimental + --> $DIR/feature-gate-mgca-type-const-syntax.rs:12:5 + | +LL | type const BAR: bool = false; + | ^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: top-level `type const` are unstable + --> $DIR/feature-gate-mgca-type-const-syntax.rs:1:1 + | +LL | type const FOO: u8 = 10; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated `type const` are unstable + --> $DIR/feature-gate-mgca-type-const-syntax.rs:6:5 + | +LL | type const BAR: bool; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated `type const` are unstable + --> $DIR/feature-gate-mgca-type-const-syntax.rs:12:5 + | +LL | type const BAR: bool = false; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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 6 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs b/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs index 1cf755b2c565..49916736d46e 100644 --- a/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs +++ b/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs @@ -1,7 +1,7 @@ trait Trait { - #[type_const] - //~^ ERROR experimental - const ASSOC: usize; + type const ASSOC: usize; + //~^ ERROR: associated `type const` are unstable [E0658] + //~| ERROR: `type const` syntax is experimental [E0658] } // FIXME(mgca): add suggestion for mgca to this error diff --git a/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr index af528a3c1b79..05166b4857fb 100644 --- a/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr +++ b/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr @@ -7,16 +7,26 @@ LL | fn foo() -> [u8; ::ASSOC] { = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: the `#[type_const]` attribute is an experimental feature +error[E0658]: `type const` syntax is experimental --> $DIR/feature-gate-min-generic-const-args.rs:2:5 | -LL | #[type_const] - | ^^^^^^^^^^^^^ +LL | type const ASSOC: usize; + | ^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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 2 previous errors +error[E0658]: associated `type const` are unstable + --> $DIR/feature-gate-min-generic-const-args.rs:2:5 + | +LL | type const ASSOC: usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs b/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs index 0b78911158ba..f18f59cf60bd 100644 --- a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs +++ b/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.rs @@ -1,8 +1,7 @@ #![feature(generic_const_items, min_generic_const_args)] #![expect(incomplete_features)] -#[type_const] -const INC: usize = const { N + 1 }; +type const INC: usize = const { N + 1 }; //~^ ERROR generic parameters may not be used in const operations //~| HELP add `#![feature(opaque_generic_const_args)]` diff --git a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr index 1b87443aa3cb..ef771e77f692 100644 --- a/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr +++ b/tests/ui/feature-gates/feature-gate-opaque-generic-const-args.stderr @@ -1,8 +1,8 @@ error: generic parameters may not be used in const operations - --> $DIR/feature-gate-opaque-generic-const-args.rs:5:44 + --> $DIR/feature-gate-opaque-generic-const-args.rs:4:49 | -LL | const INC: usize = const { N + 1 }; - | ^ +LL | type const INC: usize = const { N + 1 }; + | ^ | = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items diff --git a/tests/ui/generic-const-items/assoc-const-bindings.rs b/tests/ui/generic-const-items/assoc-const-bindings.rs index d0301b920e27..2bf4bea16deb 100644 --- a/tests/ui/generic-const-items/assoc-const-bindings.rs +++ b/tests/ui/generic-const-items/assoc-const-bindings.rs @@ -5,19 +5,15 @@ #![allow(incomplete_features)] trait Owner { - #[type_const] - const C: u32; - #[type_const] - const K: u32; + type const C: u32; + type const K: u32; // #[type_const] // const Q: Maybe; } impl Owner for () { - #[type_const] - const C: u32 = N; - #[type_const] - const K: u32 = const { 99 + 1 }; + type const C: u32 = N; + type const K: u32 = const { 99 + 1 }; // FIXME(mgca): re-enable once we properly support ctors and generics on paths // #[type_const] // const Q: Maybe = Maybe::Nothing; diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index 518ed6452369..df680f30fed9 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -8,8 +8,7 @@ pub struct NoPin; impl Pins for NoPin {} pub trait PinA { - #[type_const] - const A: &'static () = const { &() }; + type const A: &'static () = const { &() }; } pub trait Pins {} diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr index f57fd74ad99d..b719ebe0664f 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Pins<_>` for type `NoPin` - --> $DIR/assoc-const-no-infer-ice-115806.rs:17:1 + --> $DIR/assoc-const-no-infer-ice-115806.rs:16:1 | LL | impl Pins for NoPin {} | --------------------------- first implementation here diff --git a/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs b/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs index 50530e4f0db0..6bd995449fc6 100644 --- a/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs +++ b/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs @@ -8,8 +8,7 @@ #![expect(incomplete_features)] trait Trait { - #[type_const] - const N: usize = 0; + type const N: usize = 0; fn process(&self, _: [u8; Self::N]) {} } diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs index 538b0c2b1d46..578a46c67400 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs @@ -5,12 +5,11 @@ //~| WARN the feature `min_generic_const_args` is incomplete pub trait IsVoid { - #[type_const] - const IS_VOID: bool; + + type const IS_VOID: bool; } impl IsVoid for T { - #[type_const] - default const IS_VOID: bool = false; + default type const IS_VOID: bool = false; } pub trait NotVoid {} diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr index 6159c2ed331a..9361f7d6222f 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr @@ -17,7 +17,7 @@ LL | #![feature(min_generic_const_args, specialization)] = help: consider using `min_specialization` instead, which is more stable and complete error[E0119]: conflicting implementations of trait `Maybe<()>` for type `()` - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:21:1 + --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:20:1 | LL | impl Maybe for T {} | ---------------------- first implementation here From 9bf9a12381bfab41c5d7c7a1d3f5c1457064575d Mon Sep 17 00:00:00 2001 From: Keith-Cancel Date: Thu, 5 Feb 2026 22:01:57 -0800 Subject: [PATCH 3459/3801] Allow provisional mgca syntax of type const = to be reconized. Revert, but without type const. Update symbol for feature err, then update suggestion output, and lastly update tests that change because of those. Update these new tests with the correct syntax, and few existing tests with the new outputs the merge with main added. Fix for tidyfmt and some errors when manually resolving a merge conflicts. Update these tests to use update error messages and type const syntax. Update comments and error message to use new syntax instead of old type_const attribute. Remove the type_const attribute update some more tests to use the new syntax. Update these test cases. update feature gate test Change gate logic for `mgca_type_const_syntax` to work also if `min_generic_const_args` is enabled. Create a new feature gate that checks for the feature before expansion. Make rustfmt handle the `type const` syntax correctly. Add a convience method to check if a RhsKind is type const. Rename `Const` discriminant to `Body` for `ConstItemRhsKind` Give the `TraitItemKind` flag an enum instead of a simple bool to better describe what the flag is for. Update formatting for these match statements. Update clippy test to use type const syntax. Update test to use type const syntax. update rustfmt to match ast items. Update clippy to match ast and hir items. Few more test cases that used old attribute, instead of 'type const' Update to match the output from the feature gate checks. tidyfmt adjustments. Update the is_type_const, so I can constrain record!(..) in encoder.rs Update conditional compilation test. Move the feature gate to after expansion to allow for cfg(...) to work. Update some more tests to use the new syntax. Update type const tests in associated-const-bindings to use new syntax. Don't check based off the attribute, but the item here. Update some tests outside of the const_generics folder that were using #[type_const] update the tests in associated consts that use #[type_const] to use type const Update these mgca tests with the type const syntax. Add a flag to TraitItemKind for detecting type const for now. Maybe later change ItemConstRhs to have optional consts but that touches a lot more lines of code. Don't need into for these now that it's a query. Add is_type_const query to handle foreign def ids. update this test to use type const syntax. Fix logic here, we only want to lower if there is expression in this case. Update built-in macros to use ConstItemRhsKind Update more instance of the old ConstItemRhs. Rename ConstItemKind to ConstItemRhsKind, I noticed there is a typed called ConstantItemKind, so add the Rhs to the name to avoid confusion. Update lower to use ConstItemKind Add an other helper method to check if the rhs kinda has an expr. Update item parse to use ConstItemKind enum. Felt the field name could a be little clear when editing a few other things. Change the ConstItem struct see know if we have a type const or regular const. Make sure this syntax is properly feature gated. --- clippy_lints/src/non_copy_const.rs | 4 +-- clippy_lints/src/types/mod.rs | 2 +- clippy_utils/src/ast_utils/mod.rs | 28 +++++++++++-------- ...duplication_in_bounds_assoc_const_eq.fixed | 4 +-- ...it_duplication_in_bounds_assoc_const_eq.rs | 4 +-- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index f99748127a8f..e09fc0a76366 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -739,7 +739,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { - if let TraitItemKind::Const(_, ct_rhs_opt) = item.kind + if let TraitItemKind::Const(_, ct_rhs_opt, _) = item.kind && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::No => true, @@ -931,7 +931,7 @@ fn get_const_hir_value<'tcx>( { match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) { Node::ImplItem(item) if let ImplItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs), - Node::TraitItem(item) if let TraitItemKind::Const(.., Some(ct_rhs)) = item.kind => (did, ct_rhs), + Node::TraitItem(item) if let TraitItemKind::Const(_, Some(ct_rhs), _) = item.kind => (did, ct_rhs), _ => return None, } }, diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 7018146f184b..7d97ce97f487 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -514,7 +514,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { }; match item.kind { - TraitItemKind::Const(ty, _) | TraitItemKind::Type(_, Some(ty)) => { + TraitItemKind::Const(ty, _, _) | TraitItemKind::Type(_, Some(ty)) => { self.check_ty(cx, ty, context); }, TraitItemKind::Fn(ref sig, trait_method) => { diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index cf8716398efb..3b043f7565ef 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -355,7 +355,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: li, generics: lg, ty: lt, - rhs: lb, + rhs_kind: lb, define_opaque: _, }), Const(box ConstItem { @@ -363,7 +363,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { ident: ri, generics: rg, ty: rt, - rhs: rb, + rhs_kind: rb, define_opaque: _, }), ) => { @@ -371,7 +371,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && both(lb.as_ref(), rb.as_ref(), eq_const_item_rhs) + && both(Some(lb), Some(rb), eq_const_item_rhs) }, ( Fn(box ast::Fn { @@ -615,7 +615,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: li, generics: lg, ty: lt, - rhs: lb, + rhs_kind: lb, define_opaque: _, }), Const(box ConstItem { @@ -623,7 +623,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { ident: ri, generics: rg, ty: rt, - rhs: rb, + rhs_kind: rb, define_opaque: _, }), ) => { @@ -631,7 +631,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { && eq_id(*li, *ri) && eq_generics(lg, rg) && eq_ty(lt, rt) - && both(lb.as_ref(), rb.as_ref(), eq_const_item_rhs) + && both(Some(lb), Some(rb), eq_const_item_rhs) }, ( Fn(box ast::Fn { @@ -791,12 +791,18 @@ pub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool { eq_expr(&l.value, &r.value) } -pub fn eq_const_item_rhs(l: &ConstItemRhs, r: &ConstItemRhs) -> bool { - use ConstItemRhs::*; +pub fn eq_const_item_rhs(l: &ConstItemRhsKind, r: &ConstItemRhsKind) -> bool { + use ConstItemRhsKind::*; match (l, r) { - (TypeConst(l), TypeConst(r)) => eq_anon_const(l, r), - (Body(l), Body(r)) => eq_expr(l, r), - (TypeConst(..), Body(..)) | (Body(..), TypeConst(..)) => false, + (TypeConst { rhs: Some(l) }, TypeConst { rhs: Some(r) }) => eq_anon_const(l, r), + (TypeConst { rhs: None }, TypeConst { rhs: None }) => true, + (TypeConst { rhs: Some(..) }, TypeConst { rhs: None }) => false, + (TypeConst { rhs: None }, TypeConst { rhs: Some(..) }) => false, + (Body { rhs: Some(l) }, Body { rhs: Some(r) }) => eq_expr(l, r), + (Body { rhs: None }, Body { rhs: None }) => true, + (Body { rhs: None }, Body { rhs: Some(..) }) => false, + (Body { rhs: Some(..) }, Body { rhs: None }) => false, + (TypeConst {..}, Body { .. }) | ( Body { .. }, TypeConst { .. }) => false, } } diff --git a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed index f8be3331317c..8d63fc44e7f8 100644 --- a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed +++ b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed @@ -3,8 +3,8 @@ #![feature(min_generic_const_args)] trait AssocConstTrait { - #[type_const] - const ASSOC: usize; + + type const ASSOC: usize; } fn assoc_const_args() where diff --git a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs index a0d7a653993f..36a83619c0f9 100644 --- a/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs +++ b/tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs @@ -3,8 +3,8 @@ #![feature(min_generic_const_args)] trait AssocConstTrait { - #[type_const] - const ASSOC: usize; + + type const ASSOC: usize; } fn assoc_const_args() where From 6546a98d90bf1a95a9d02432bab2d8550d4e980e Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 9 Feb 2026 18:00:54 +0100 Subject: [PATCH 3460/3801] Update books --- src/doc/book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/book b/src/doc/book index 39aeceaa3aea..05d114287b7d 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 39aeceaa3aeab845bc4517e7a44e48727d3b9dbe +Subproject commit 05d114287b7d6f6c9253d5242540f00fbd6172ab diff --git a/src/doc/nomicon b/src/doc/nomicon index 050c002a360f..b8f254a991b8 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 050c002a360fa45b701ea34feed7a860dc8a41bf +Subproject commit b8f254a991b8b7e8f704527f0d4f343a4697dfa9 diff --git a/src/doc/reference b/src/doc/reference index 990819b86c22..addd0602c819 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 990819b86c22bbf538c0526f0287670f3dc1a67a +Subproject commit addd0602c819b6526b9cc97653b0fadca395528c From 41e0e0690f74685f094d88ae2a0f05379e38873f Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Mon, 9 Feb 2026 19:12:13 +0100 Subject: [PATCH 3461/3801] Move `inline_fluent` to a proc macro --- compiler/rustc_macros/src/diagnostics/inline_fluent.rs | 10 ++++++++++ compiler/rustc_macros/src/diagnostics/mod.rs | 2 ++ compiler/rustc_macros/src/lib.rs | 9 +++++++++ 3 files changed, 21 insertions(+) create mode 100644 compiler/rustc_macros/src/diagnostics/inline_fluent.rs diff --git a/compiler/rustc_macros/src/diagnostics/inline_fluent.rs b/compiler/rustc_macros/src/diagnostics/inline_fluent.rs new file mode 100644 index 000000000000..ab0ed6aa6e0e --- /dev/null +++ b/compiler/rustc_macros/src/diagnostics/inline_fluent.rs @@ -0,0 +1,10 @@ +use syn::{LitStr, parse_macro_input}; + +use crate::diagnostics::message::Message; + +pub(crate) fn inline_fluent(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let inline = parse_macro_input!(input as LitStr); + let message = + Message { attr_span: inline.span(), message_span: inline.span(), value: inline.value() }; + message.diag_message(None).into() +} diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 09f05ce972f1..d9168939dd48 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -1,11 +1,13 @@ mod diagnostic; mod diagnostic_builder; mod error; +mod inline_fluent; mod message; mod subdiagnostic; mod utils; use diagnostic::{DiagnosticDerive, LintDiagnosticDerive}; +pub(super) use inline_fluent::inline_fluent; use proc_macro2::TokenStream; use subdiagnostic::SubdiagnosticDerive; use synstructure::Structure; diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 8cd6c0264448..3d2111b86881 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -241,6 +241,15 @@ decl_derive!( applicability)] => diagnostics::subdiagnostic_derive ); +/// This macro creates a translatable `DiagMessage` from a fluent format string. +/// It should be used in places where a translatable message is needed, but struct diagnostics are undesired. +/// +/// This macro statically checks that the message is valid Fluent, but not that variables in the Fluent message actually exist. +#[proc_macro] +pub fn inline_fluent(input: TokenStream) -> TokenStream { + diagnostics::inline_fluent(input) +} + decl_derive! { [PrintAttribute] => /// Derives `PrintAttribute` for `AttributeKind`. From 6eb2a8fa9ef2b35d34b021550942cc327fa93b3a Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Mon, 9 Feb 2026 19:12:22 +0100 Subject: [PATCH 3462/3801] Reformat existing error messages --- .../src/const_eval/eval_queries.rs | 6 +- .../src/const_eval/machine.rs | 16 +- compiler/rustc_const_eval/src/errors.rs | 212 +++++++++--------- .../src/interpret/intrinsics.rs | 10 +- .../rustc_const_eval/src/interpret/memory.rs | 56 ++--- compiler/rustc_errors/src/diagnostic_impls.rs | 12 +- compiler/rustc_errors/src/lib.rs | 3 +- compiler/rustc_errors/src/translation.rs | 11 - .../rustc_lint/src/impl_trait_overcaptures.rs | 2 +- compiler/rustc_lint/src/lints.rs | 16 +- compiler/rustc_lint/src/non_fmt_panic.rs | 10 +- compiler/rustc_middle/src/middle/stability.rs | 28 ++- .../src/lint_tail_expr_drop_order.rs | 10 +- compiler/rustc_passes/src/errors.rs | 6 +- .../src/error_reporting/infer/region.rs | 10 +- compiler/rustc_trait_selection/src/errors.rs | 104 +++++---- .../src/errors/note_and_explain.rs | 62 ++--- 17 files changed, 299 insertions(+), 275 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 25da90298791..131e17ac3173 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -471,9 +471,9 @@ fn report_eval_error<'tcx>( span, inline_fluent!( "evaluation of `{$instance}` failed {$num_frames -> - [0] here - *[other] inside this call -}" + [0] here + *[other] inside this call + }" ), ); for frame in frames { diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index da4f97db1c59..8bc515a8b1b5 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -491,10 +491,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { Err(err) => throw_ub_custom!( inline_fluent!( "invalid align passed to `{$name}`: {$align} is {$err_kind -> - [not_power_of_two] not a power of 2 - [too_large] too large - *[other] {\"\"} -}" + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }" ), name = "const_allocate", err_kind = err.diag_ident(), @@ -521,10 +521,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { Err(err) => throw_ub_custom!( inline_fluent!( "invalid align passed to `{$name}`: {$align} is {$err_kind -> - [not_power_of_two] not a power of 2 - [too_large] too large - *[other] {\"\"} -}" + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }" ), name = "const_deallocate", err_kind = err.diag_ident(), diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index a673e0cb1efb..cba2c462bf22 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -393,16 +393,17 @@ impl Subdiagnostic for FrameNote { } let msg = diag.eagerly_translate(inline_fluent!( r#"{$times -> - [0] {const_eval_frame_note_inner} - *[other] [... {$times} additional calls {const_eval_frame_note_inner} ...] -} - -const_eval_frame_note_inner = inside {$where_ -> - [closure] closure - [instance] `{$instance}` - *[other] {""} -} -"# + [0] inside {$where_ -> + [closure] closure + [instance] `{$instance}` + *[other] {""} + } + *[other] [... {$times} additional calls inside {$where_ -> + [closure] closure + [instance] `{$instance}` + *[other] {""} + } ...] + }"# )); diag.remove_arg("times"); diag.remove_arg("where_"); @@ -663,89 +664,96 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { InvalidMeta(InvalidMetaKind::SliceTooBig) => "invalid metadata in wide pointer: slice is bigger than largest supported object".into(), InvalidMeta(InvalidMetaKind::TooBig) => "invalid metadata in wide pointer: total size is bigger than largest supported object".into(), UnterminatedCString(_) => "reading a null-terminated string starting at {$pointer} with no null found before end of allocation".into(), - PointerUseAfterFree(_, _) => inline_fluent!("{$operation -> - [MemoryAccess] memory access failed - [InboundsPointerArithmetic] in-bounds pointer arithmetic failed - *[Dereferenceable] pointer not dereferenceable -}: {$alloc_id} has been freed, so this pointer is dangling"), - PointerOutOfBounds { .. } => inline_fluent!("{$operation -> - [MemoryAccess] memory access failed - [InboundsPointerArithmetic] in-bounds pointer arithmetic failed - *[Dereferenceable] pointer not dereferenceable -}: {$operation -> - [MemoryAccess] attempting to access {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - *[Dereferenceable] pointer must {$inbounds_size -> - [0] point to some allocation - [1] be dereferenceable for 1 byte - *[x] be dereferenceable for {$inbounds_size} bytes - } -}, but got {$pointer} which {$ptr_offset_is_neg -> - [true] points to before the beginning of the allocation - *[false] {$inbounds_size_is_neg -> - [false] {$alloc_size_minus_ptr_offset -> - [0] is at or beyond the end of the allocation of size {$alloc_size -> - [1] 1 byte - *[x] {$alloc_size} bytes - } - [1] is only 1 byte from the end of the allocation - *[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation - } - *[true] {$ptr_offset_abs -> - [0] is at the beginning of the allocation - *[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation - } - } -} -"), - DanglingIntPointer { addr: 0, .. } => inline_fluent!("{$operation -> - [MemoryAccess] memory access failed - [InboundsPointerArithmetic] in-bounds pointer arithmetic failed - *[Dereferenceable] pointer not dereferenceable -}: {$operation -> - [MemoryAccess] attempting to access {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - *[Dereferenceable] pointer must {$inbounds_size -> - [0] point to some allocation - [1] be dereferenceable for 1 byte - *[x] be dereferenceable for {$inbounds_size} bytes - } -}, but got null pointer"), - DanglingIntPointer { .. } => inline_fluent!("{$operation -> - [MemoryAccess] memory access failed - [InboundsPointerArithmetic] in-bounds pointer arithmetic failed - *[Dereferenceable] pointer not dereferenceable -}: {$operation -> - [MemoryAccess] attempting to access {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - *[Dereferenceable] pointer must {$inbounds_size -> - [0] point to some allocation - [1] be dereferenceable for 1 byte - *[x] be dereferenceable for {$inbounds_size} bytes - } -}, but got {$pointer} which is a dangling pointer (it has no provenance)"), - AlignmentCheckFailed { .. } => inline_fluent!("{$msg -> - [AccessedPtr] accessing memory - *[other] accessing memory based on pointer -} with alignment {$has}, but alignment {$required} is required"), + PointerUseAfterFree(_, _) => inline_fluent!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$alloc_id} has been freed, so this pointer is dangling" + ), + PointerOutOfBounds { .. } => inline_fluent!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$operation -> + [MemoryAccess] attempting to access {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + *[Dereferenceable] pointer must {$inbounds_size -> + [0] point to some allocation + [1] be dereferenceable for 1 byte + *[x] be dereferenceable for {$inbounds_size} bytes + } + }, but got {$pointer} which {$ptr_offset_is_neg -> + [true] points to before the beginning of the allocation + *[false] {$inbounds_size_is_neg -> + [false] {$alloc_size_minus_ptr_offset -> + [0] is at or beyond the end of the allocation of size {$alloc_size -> + [1] 1 byte + *[x] {$alloc_size} bytes + } + [1] is only 1 byte from the end of the allocation + *[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation + } + *[true] {$ptr_offset_abs -> + [0] is at the beginning of the allocation + *[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation + } + } + }" + ), + DanglingIntPointer { addr: 0, .. } => inline_fluent!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$operation -> + [MemoryAccess] attempting to access {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + *[Dereferenceable] pointer must {$inbounds_size -> + [0] point to some allocation + [1] be dereferenceable for 1 byte + *[x] be dereferenceable for {$inbounds_size} bytes + } + }, but got null pointer"), + DanglingIntPointer { .. } => inline_fluent!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$operation -> + [MemoryAccess] attempting to access {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + *[Dereferenceable] pointer must {$inbounds_size -> + [0] point to some allocation + [1] be dereferenceable for 1 byte + *[x] be dereferenceable for {$inbounds_size} bytes + } + }, but got {$pointer} which is a dangling pointer (it has no provenance)"), + AlignmentCheckFailed { .. } => inline_fluent!( + "{$msg -> + [AccessedPtr] accessing memory + *[other] accessing memory based on pointer + } with alignment {$has}, but alignment {$required} is required" + ), WriteToReadOnly(_) => inline_fluent!("writing to {$allocation} which is read-only"), DerefFunctionPointer(_) => inline_fluent!("accessing {$allocation} which contains a function"), DerefVTablePointer(_) => inline_fluent!("accessing {$allocation} which contains a vtable"), @@ -936,9 +944,9 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { NullFnPtr { .. } => { inline_fluent!( "{$front_matter}: encountered a {$maybe -> - [true] maybe-null - *[false] null -} function pointer" + [true] maybe-null + *[false] null + } function pointer" ) } NeverVal => { @@ -1021,17 +1029,17 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { NullPtr { ptr_kind: PointerKind::Box, .. } => { inline_fluent!( "{$front_matter}: encountered a {$maybe -> - [true] maybe-null - *[false] null -} box" + [true] maybe-null + *[false] null + } box" ) } NullPtr { ptr_kind: PointerKind::Ref(_), .. } => { inline_fluent!( "{$front_matter}: encountered a {$maybe -> - [true] maybe-null - *[false] null -} reference" + [true] maybe-null + *[false] null + } reference" ) } DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 2ea5e4a25c11..7c49ba79a342 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -461,10 +461,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // a < b if intrinsic_name == sym::ptr_offset_from_unsigned { throw_ub_custom!( - inline_fluent!("`ptr_offset_from_unsigned` called when first pointer has smaller {$is_addr -> - [true] address - *[false] offset -} than second: {$a_offset} < {$b_offset}"), + inline_fluent!( + "`ptr_offset_from_unsigned` called when first pointer has smaller {$is_addr -> + [true] address + *[false] offset + } than second: {$a_offset} < {$b_offset}" + ), a_offset = a_offset, b_offset = b_offset, is_addr = is_addr, diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 28dae2ef3b8b..200155ab010e 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -293,10 +293,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { throw_ub_custom!( inline_fluent!( "{$kind -> - [dealloc] deallocating - [realloc] reallocating - *[other] {\"\"} -} {$ptr} which does not point to the beginning of an object" + [dealloc] deallocating + [realloc] reallocating + *[other] {\"\"} + } {$ptr} which does not point to the beginning of an object" ), ptr = format!("{ptr:?}"), kind = "realloc" @@ -379,10 +379,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { throw_ub_custom!( inline_fluent!( "{$kind -> - [dealloc] deallocating - [realloc] reallocating - *[other] {\"\"} -} {$ptr} which does not point to the beginning of an object" + [dealloc] deallocating + [realloc] reallocating + *[other] {\"\"} + } {$ptr} which does not point to the beginning of an object" ), ptr = format!("{ptr:?}"), kind = "dealloc", @@ -396,11 +396,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { err_ub_custom!( inline_fluent!( "deallocating {$alloc_id}, which is {$kind -> - [fn] a function - [vtable] a vtable - [static_mem] static memory - *[other] {\"\"} -}" + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" ), alloc_id = alloc_id, kind = "fn", @@ -410,11 +410,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { err_ub_custom!( inline_fluent!( "deallocating {$alloc_id}, which is {$kind -> - [fn] a function - [vtable] a vtable - [static_mem] static memory - *[other] {\"\"} -}" + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" ), alloc_id = alloc_id, kind = "vtable", @@ -424,11 +424,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { err_ub_custom!( inline_fluent!( "deallocating {$alloc_id}, which is {$kind -> - [fn] a function - [vtable] a vtable - [static_mem] static memory - *[other] {\"\"} -}" + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" ), alloc_id = alloc_id, kind = "typeid", @@ -438,11 +438,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { err_ub_custom!( inline_fluent!( "deallocating {$alloc_id}, which is {$kind -> - [fn] a function - [vtable] a vtable - [static_mem] static memory - *[other] {\"\"} -}" + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" ), alloc_id = alloc_id, kind = "static_mem" diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index c36afc6fc889..ae3e33498ea1 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -60,11 +60,13 @@ impl Diagnostic<'_, G> for TargetDataLayoutErrors<'_> { .with_arg("cause", cause) } TargetDataLayoutErrors::InvalidAlignment { cause, err } => { - Diag::new(dcx, level, inline_fluent!("invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind -> - [not_power_of_two] not a power of 2 - [too_large] too large - *[other] {\"\"} - }")) + Diag::new(dcx, level, inline_fluent!( + "invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind -> + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }" + )) .with_arg("cause", cause) .with_arg("err_kind", err.diag_ident()) .with_arg("align", err.align()) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 2e0afb8fc4c2..4eadb8249405 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -63,6 +63,7 @@ pub use rustc_error_messages::{ use rustc_hashes::Hash128; use rustc_lint_defs::LintExpectationId; pub use rustc_lint_defs::{Applicability, listify, pluralize}; +pub use rustc_macros::inline_fluent; use rustc_macros::{Decodable, Encodable}; pub use rustc_span::ErrorGuaranteed; pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors}; @@ -1562,7 +1563,7 @@ impl DelayedDiagInner { let msg = match self.note.status() { BacktraceStatus::Captured => inline_fluent!( "delayed at {$emitted_at} -{$note}" + {$note}" ), // Avoid the needless newline when no backtrace has been captured, // the display impl should just be a single line. diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index b5de3f87e9f3..c6d30032f1af 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -90,14 +90,3 @@ impl Translator { } } } - -/// This macro creates a translatable `DiagMessage` from a literal string. -/// It should be used in places where a translatable message is needed, but struct diagnostics are undesired. -/// -/// This is a macro because in the future we may want to globally register these messages. -#[macro_export] -macro_rules! inline_fluent { - ($inline: literal) => { - rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed($inline)) - }; -} diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 087403719968..aef0021d0660 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -446,7 +446,7 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { "specifically, {$num_captured -> [one] this lifetime is *[other] these lifetimes are - } in scope but not mentioned in the type's bounds" + } in scope but not mentioned in the type's bounds" ), ) .note(inline_fluent!( diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 0aa5199cffc6..4ec59a3cb98f 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -353,8 +353,10 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> { self.label, inline_fluent!("will not be checked at usage sites of the type alias"), ); - diag.note(inline_fluent!("this is a known limitation of the type checker that may be lifted in a future edition. - see issue #112792 for more information")); + diag.note(inline_fluent!( + "this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information" + )); if self.enable_feat_help { diag.help(inline_fluent!("add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics")); } @@ -1748,10 +1750,12 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { if doctest { diag.help(inline_fluent!(r#"remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`"#)); } else { - diag.help(inline_fluent!("remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth -> - [one] `{$body_name}` - *[other] `{$body_name}` and up {$depth} bodies - }")); + diag.help(inline_fluent!( + "remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth -> + [one] `{$body_name}` + *[other] `{$body_name}` and up {$depth} bodies + }" + )); } diag.note(inline_fluent!("a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute")); diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index daf62277693a..10a37637400b 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -196,10 +196,12 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc if let Some((open, close, del)) = find_delimiters(cx, span) { lint.arg("already_suggested", suggest_display || suggest_debug); lint.multipart_suggestion( - inline_fluent!("{$already_suggested -> - [true] or use - *[false] use - } std::panic::panic_any instead"), + inline_fluent!( + "{$already_suggested -> + [true] or use + *[false] use + } std::panic::panic_any instead" + ), if del == '(' { vec![(span.until(open), "std::panic::panic_any".into())] } else { diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index fce0158aa511..903ef645207d 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -128,19 +128,25 @@ pub struct Deprecated { impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { diag.primary_message(match &self.since_kind { - DeprecatedSinceKind::InEffect => inline_fluent!("use of deprecated {$kind} `{$path}`{$has_note -> - [true] : {$note} - *[other] {\"\"} - }"), - DeprecatedSinceKind::InFuture => inline_fluent!("use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note -> - [true] : {$note} - *[other] {\"\"} - }"), - DeprecatedSinceKind::InVersion(_) => { - inline_fluent!("use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note -> + DeprecatedSinceKind::InEffect => inline_fluent!( + "use of deprecated {$kind} `{$path}`{$has_note -> [true] : {$note} *[other] {\"\"} - }") + }" + ), + DeprecatedSinceKind::InFuture => inline_fluent!( + "use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note -> + [true] : {$note} + *[other] {\"\"} + }" + ), + DeprecatedSinceKind::InVersion(_) => { + inline_fluent!( + "use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note -> + [true] : {$note} + *[other] {\"\"} + }" + ) } }); diag.arg("kind", self.kind); diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 789398c58880..448ed78702b7 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -542,10 +542,12 @@ impl Subdiagnostic for LocalLabel<'_> { dtor.add_to_diag(diag); } let msg = - diag.eagerly_translate(inline_fluent!("{$is_dropped_first_edition_2024 -> - [true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024 - *[false] `{$name}` will be dropped later as of Edition 2024 - }")); + diag.eagerly_translate(inline_fluent!( + "{$is_dropped_first_edition_2024 -> + [true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024 + *[false] `{$name}` will be dropped later as of Edition 2024 + }" + )); diag.span_label(self.span, msg); } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index f420bba9b4e9..8a70302c4c4e 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -684,9 +684,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NoMainErr { // There were some functions named `main` though. Try to give the user a hint. inline_fluent!( "the main function must be defined at the crate level{$has_filename -> - [true] {\" \"}(in `{$filename}`) - *[false] {\"\"} - }" + [true] {\" \"}(in `{$filename}`) + *[false] {\"\"} + }" ) } else if self.has_filename { inline_fluent!("consider adding a `main` function to `{$filename}`") diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index d15fb40dd1cb..c99dde6d45b9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -252,10 +252,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { SubregionOrigin::RelateParamBound(span, ty, opt_span) => { RegionOriginNote::WithName { span, - msg: inline_fluent!("...so that the type `{$name}` will meet its required lifetime bounds{$continues -> -[true] ... -*[false] {\"\"} -}"), + msg: inline_fluent!( + "...so that the type `{$name}` will meet its required lifetime bounds{$continues -> + [true] ... + *[false] {\"\"} + }" + ), name: &self.ty_to_string(ty), continues: opt_span.is_some(), } diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 013e4b522fb5..529a7fcf5f1c 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -102,10 +102,16 @@ pub struct NegativePositiveConflict<'tcx> { impl Diagnostic<'_, G> for NegativePositiveConflict<'_> { #[track_caller] fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, inline_fluent!("found both positive and negative implementation of trait `{$trait_desc}`{$self_desc -> -[none] {\"\"} -*[default] {\" \"}for type `{$self_desc}` -}:")); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!( + "found both positive and negative implementation of trait `{$trait_desc}`{$self_desc -> + [none] {\"\"} + *[default] {\" \"}for type `{$self_desc}` + }:" + ), + ); diag.arg("trait_desc", self.trait_desc.print_only_trait_path().to_string()); diag.arg("self_desc", self.self_ty.map_or_else(|| "none".to_string(), |ty| ty.to_string())); diag.span(self.impl_span); @@ -157,9 +163,9 @@ impl Subdiagnostic for AdjustSignatureBorrow { diag.multipart_suggestion_verbose( inline_fluent!( "consider adjusting the signature so it borrows its {$borrow_len -> -[one] argument -*[other] arguments -}" + [one] argument + *[other] arguments + }" ), to_borrow, Applicability::MaybeIncorrect, @@ -170,9 +176,9 @@ impl Subdiagnostic for AdjustSignatureBorrow { diag.multipart_suggestion_verbose( inline_fluent!( "consider adjusting the signature so it does not borrow its {$remove_borrow_len -> -[one] argument -*[other] arguments -}" + [one] argument + *[other] arguments + }" ), remove_borrow, Applicability::MaybeIncorrect, @@ -505,18 +511,18 @@ impl Subdiagnostic for RegionOriginNote<'_> { span, inline_fluent!( "...so that the {$requirement -> -[method_compat] method type is compatible with trait -[type_compat] associated type is compatible with trait -[const_compat] const is compatible with trait -[expr_assignable] expression is assignable -[if_else_different] `if` and `else` have incompatible types -[no_else] `if` missing an `else` returns `()` -[fn_main_correct_type] `main` function has the correct type -[fn_lang_correct_type] lang item function has the correct type -[intrinsic_correct_type] intrinsic has the correct type -[method_correct_type] method receiver has the correct type -*[other] types are compatible -}" + [method_compat] method type is compatible with trait + [type_compat] associated type is compatible with trait + [const_compat] const is compatible with trait + [expr_assignable] expression is assignable + [if_else_different] `if` and `else` have incompatible types + [no_else] `if` missing an `else` returns `()` + [fn_main_correct_type] `main` function has the correct type + [fn_lang_correct_type] lang item function has the correct type + [intrinsic_correct_type] intrinsic has the correct type + [method_correct_type] method receiver has the correct type + *[other] types are compatible + }" ), ); diag.arg("requirement", requirement); @@ -531,18 +537,18 @@ impl Subdiagnostic for RegionOriginNote<'_> { span, inline_fluent!( "...so that {$requirement -> -[method_compat] method type is compatible with trait -[type_compat] associated type is compatible with trait -[const_compat] const is compatible with trait -[expr_assignable] expression is assignable -[if_else_different] `if` and `else` have incompatible types -[no_else] `if` missing an `else` returns `()` -[fn_main_correct_type] `main` function has the correct type -[fn_lang_correct_type] lang item function has the correct type -[intrinsic_correct_type] intrinsic has the correct type -[method_correct_type] method receiver has the correct type -*[other] types are compatible -}" + [method_compat] method type is compatible with trait + [type_compat] associated type is compatible with trait + [const_compat] const is compatible with trait + [expr_assignable] expression is assignable + [if_else_different] `if` and `else` have incompatible types + [no_else] `if` missing an `else` returns `()` + [fn_main_correct_type] `main` function has the correct type + [fn_lang_correct_type] lang item function has the correct type + [intrinsic_correct_type] intrinsic has the correct type + [method_correct_type] method receiver has the correct type + *[other] types are compatible + }" ), ); diag.arg("requirement", requirement); @@ -578,9 +584,9 @@ impl Subdiagnostic for LifetimeMismatchLabels { span, inline_fluent!( "...but data{$label_var1_exists -> -[true] {\" \"}from `{$label_var1}` -*[false] {\"\"} -} is returned here" + [true] {\" \"}from `{$label_var1}` + *[false] {\"\"} + } is returned here" ), ); diag.arg("label_var1_exists", label_var1.is_some()); @@ -614,12 +620,12 @@ impl Subdiagnostic for LifetimeMismatchLabels { span, inline_fluent!( "...but data{$label_var1_exists -> -[true] {\" \"}from `{$label_var1}` -*[false] {\"\"} -} flows{$label_var2_exists -> -[true] {\" \"}into `{$label_var2}` -*[false] {\"\"} -} here" + [true] {\" \"}from `{$label_var1}` + *[false] {\"\"} + } flows{$label_var2_exists -> + [true] {\" \"}into `{$label_var2}` + *[false] {\"\"} + } here" ), ); diag.arg("label_var1_exists", label_var1.is_some()); @@ -789,12 +795,12 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { diag.multipart_suggestion_verbose( inline_fluent!( "consider {$is_reuse -> -[true] reusing -*[false] introducing -} a named lifetime parameter{$is_impl -> -[true] {\" \"}and update trait if needed -*[false] {\"\"} -}" + [true] reusing + *[false] introducing + } a named lifetime parameter{$is_impl -> + [true] {\" \"}and update trait if needed + *[false] {\"\"} + }" ), visitor.suggestions, Applicability::MaybeIncorrect, diff --git a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs index 8e86b8fae157..6a7e1d252806 100644 --- a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs @@ -171,37 +171,37 @@ impl Subdiagnostic for RegionExplanation<'_> { let msg = diag.eagerly_translate(inline_fluent!( "{$pref_kind -> -*[should_not_happen] [{$pref_kind}] -[ref_valid_for] ...the reference is valid for -[content_valid_for] ...but the borrowed content is only valid for -[type_obj_valid_for] object type is valid for -[source_pointer_valid_for] source pointer is only valid for -[type_satisfy] type must satisfy -[type_outlive] type must outlive -[lf_param_instantiated_with] lifetime parameter instantiated with -[lf_param_must_outlive] but lifetime parameter must outlive -[lf_instantiated_with] lifetime instantiated with -[lf_must_outlive] but lifetime must outlive -[pointer_valid_for] the pointer is valid for -[data_valid_for] but the referenced data is only valid for -[empty] {\"\"} -}{$pref_kind -> -[empty] {\"\"} -*[other] {\" \"} -}{$desc_kind -> -*[should_not_happen] [{$desc_kind}] -[restatic] the static lifetime -[revar] lifetime {$desc_arg} -[as_defined] the lifetime `{$desc_arg}` as defined here -[as_defined_anon] the anonymous lifetime as defined here -[defined_here] the anonymous lifetime defined here -[defined_here_reg] the lifetime `{$desc_arg}` as defined here -}{$suff_kind -> -*[should_not_happen] [{$suff_kind}] -[empty]{\"\"} -[continues] ... -[req_by_binding] {\" \"}as required by this binding -}" + *[should_not_happen] [{$pref_kind}] + [ref_valid_for] ...the reference is valid for + [content_valid_for] ...but the borrowed content is only valid for + [type_obj_valid_for] object type is valid for + [source_pointer_valid_for] source pointer is only valid for + [type_satisfy] type must satisfy + [type_outlive] type must outlive + [lf_param_instantiated_with] lifetime parameter instantiated with + [lf_param_must_outlive] but lifetime parameter must outlive + [lf_instantiated_with] lifetime instantiated with + [lf_must_outlive] but lifetime must outlive + [pointer_valid_for] the pointer is valid for + [data_valid_for] but the referenced data is only valid for + [empty] {\"\"} + }{$pref_kind -> + [empty] {\"\"} + *[other] {\" \"} + }{$desc_kind -> + *[should_not_happen] [{$desc_kind}] + [restatic] the static lifetime + [revar] lifetime {$desc_arg} + [as_defined] the lifetime `{$desc_arg}` as defined here + [as_defined_anon] the anonymous lifetime as defined here + [defined_here] the anonymous lifetime defined here + [defined_here_reg] the lifetime `{$desc_arg}` as defined here + }{$suff_kind -> + *[should_not_happen] [{$suff_kind}] + [empty]{\"\"} + [continues] ... + [req_by_binding] {\" \"}as required by this binding + }" )); diag.restore_args(); if let Some(span) = self.desc.span { From 61b5382ad8972cf0c218b2eb2ebc88a78b741d03 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 9 Feb 2026 16:16:31 +0100 Subject: [PATCH 3463/3801] Correctly check if a macro call is actually a macro call in rustdoc highlighter --- src/librustdoc/html/highlight.rs | 39 ++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index f70b350de283..1c162a79c4c4 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -1246,7 +1246,7 @@ impl<'src> Classifier<'src> { LiteralKind::Float { .. } | LiteralKind::Int { .. } => Class::Number, }, TokenKind::GuardedStrPrefix => return no_highlight(sink), - TokenKind::RawIdent if let Some((TokenKind::Bang, _)) = self.peek_non_trivia() => { + TokenKind::RawIdent if self.check_if_macro_call("") => { self.new_macro_span(text, sink, before, file_span); return; } @@ -1268,9 +1268,7 @@ impl<'src> Classifier<'src> { // So if it's not a keyword which can be followed by a value (like `if` or // `return`) and the next non-whitespace token is a `!`, then we consider // it's a macro. - if !NON_MACRO_KEYWORDS.contains(&text) - && matches!(self.peek_non_trivia(), Some((TokenKind::Bang, _))) - { + if !NON_MACRO_KEYWORDS.contains(&text) && self.check_if_macro_call(text) { self.new_macro_span(text, sink, before, file_span); return; } @@ -1278,7 +1276,7 @@ impl<'src> Classifier<'src> { } // If it's not a keyword and the next non whitespace token is a `!`, then // we consider it's a macro. - _ if matches!(self.peek_non_trivia(), Some((TokenKind::Bang, _))) => { + _ if self.check_if_macro_call(text) => { self.new_macro_span(text, sink, before, file_span); return; } @@ -1339,6 +1337,37 @@ impl<'src> Classifier<'src> { self.tokens.stop_peeking(); None } + + fn check_if_macro_call(&mut self, ident: &str) -> bool { + let mut has_bang = false; + let is_macro_rule_ident = ident == "macro_rules"; + + while let Some((kind, _)) = self.tokens.peek_next() { + if let TokenKind::Whitespace + | TokenKind::LineComment { doc_style: None } + | TokenKind::BlockComment { doc_style: None, .. } = kind + { + continue; + } + if !has_bang { + if kind != TokenKind::Bang { + break; + } + has_bang = true; + continue; + } + self.tokens.stop_peeking(); + if is_macro_rule_ident { + return matches!(kind, TokenKind::Ident | TokenKind::RawIdent); + } + return matches!( + kind, + TokenKind::OpenParen | TokenKind::OpenBracket | TokenKind::OpenBrace + ); + } + self.tokens.stop_peeking(); + false + } } fn is_keyword(symbol: Symbol) -> bool { From 31c4ad33cc3c4b56a63657408842af4f628bfa59 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 9 Feb 2026 16:17:09 +0100 Subject: [PATCH 3464/3801] Add regression test for macro call highlighting --- .../source-code-pages/macro-call.rs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/rustdoc-html/source-code-pages/macro-call.rs diff --git a/tests/rustdoc-html/source-code-pages/macro-call.rs b/tests/rustdoc-html/source-code-pages/macro-call.rs new file mode 100644 index 000000000000..df2d22aa9b60 --- /dev/null +++ b/tests/rustdoc-html/source-code-pages/macro-call.rs @@ -0,0 +1,29 @@ +// This is yet another test to ensure that only macro calls are considered as such +// by the rustdoc highlighter. +// This is a regression test for . + +#![crate_name = "foo"] + +//@ has src/foo/macro-call.rs.html +//@ count - '//code/span[@class="macro"]' 2 +//@ has - '//code/span[@class="macro"]' 'panic!' +//@ has - '//code/span[@class="macro"]' 'macro_rules!' + +pub struct Layout; + +impl Layout { + pub fn new() {} +} + +pub fn bar() { + let layout = Layout::new::(); + if layout != Layout::new::() { + panic!(); + } + let macro_rules = 3; + if macro_rules != 3 {} +} + +macro_rules! blob { + () => {} +} From 5a721a117ff8c94dd5083b28027dfa6b83a3aa72 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 10 Feb 2026 04:13:05 +0800 Subject: [PATCH 3465/3801] Improve variable name --- src/tools/rust-analyzer/crates/ide-assists/src/utils.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 1732d8c2018e..dd4bbd145537 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -767,7 +767,7 @@ fn generate_impl_inner( }); let generic_args = generic_params.as_ref().map(|params| params.to_generic_args().clone_for_update()); - let trait_where_clause = trait_ + let adt_assoc_bounds = trait_ .as_ref() .zip(generic_params.as_ref()) .and_then(|(trait_, params)| generic_param_associated_bounds(adt, trait_, params)); @@ -787,7 +787,7 @@ fn generate_impl_inner( false, trait_, ty, - trait_where_clause, + adt_assoc_bounds, adt.where_clause(), body, ), From aefb9a9ae261dae8d84b801c9396dd571a75339a Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Mon, 9 Feb 2026 14:07:30 -0500 Subject: [PATCH 3466/3801] tests: adapt align-offset.rs for InstCombine improvements in LLVM 23 Upstream has improved InstCombine so that it can shrink added constants using known zeroes, which caused a little bit of change in this test. As far as I can tell either output is fine, so we just accept both. --- tests/assembly-llvm/align_offset.rs | 8 ++++---- tests/codegen-llvm/align-offset.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/assembly-llvm/align_offset.rs b/tests/assembly-llvm/align_offset.rs index d9902ce336b0..5663dca30b25 100644 --- a/tests/assembly-llvm/align_offset.rs +++ b/tests/assembly-llvm/align_offset.rs @@ -4,7 +4,7 @@ #![crate_type = "rlib"] // CHECK-LABEL: align_offset_byte_ptr -// CHECK: leaq 31 +// CHECK: leaq {{31|28}} // CHECK: andq $-32 // CHECK: subq #[no_mangle] @@ -13,7 +13,7 @@ pub fn align_offset_byte_ptr(ptr: *const u8) -> usize { } // CHECK-LABEL: align_offset_byte_slice -// CHECK: leaq 31 +// CHECK: leaq {{31|28}} // CHECK: andq $-32 // CHECK: subq #[no_mangle] @@ -22,7 +22,7 @@ pub fn align_offset_byte_slice(slice: &[u8]) -> usize { } // CHECK-LABEL: align_offset_word_ptr -// CHECK: leaq 31 +// CHECK: leaq {{31|28}} // CHECK: andq $-32 // CHECK: subq // CHECK: shrq @@ -35,7 +35,7 @@ pub fn align_offset_word_ptr(ptr: *const u32) -> usize { } // CHECK-LABEL: align_offset_word_slice -// CHECK: leaq 31 +// CHECK: leaq {{31|28}} // CHECK: andq $-32 // CHECK: subq // CHECK: shrq diff --git a/tests/codegen-llvm/align-offset.rs b/tests/codegen-llvm/align-offset.rs index 21062cc0a914..383e9dd45dab 100644 --- a/tests/codegen-llvm/align-offset.rs +++ b/tests/codegen-llvm/align-offset.rs @@ -24,7 +24,7 @@ pub fn align_to4(x: &[u8]) -> bool { #[no_mangle] pub fn align_offset_byte_ptr(ptr: *const u8) -> usize { // CHECK: %[[ADDR:.+]] = ptrtoint ptr %ptr to [[USIZE:i[0-9]+]] - // CHECK: %[[UP:.+]] = add [[USIZE]] %[[ADDR]], 31 + // CHECK: %[[UP:.+]] = add [[USIZE]] %[[ADDR]], {{31|28}} // CHECK: %[[ALIGNED:.+]] = and [[USIZE]] %[[UP]], -32 // CHECK: %[[OFFSET:.+]] = sub [[USIZE]] %[[ALIGNED]], %[[ADDR]] @@ -41,7 +41,7 @@ pub fn align_offset_byte_ptr(ptr: *const u8) -> usize { #[no_mangle] pub fn align_offset_word_slice(slice: &[Align4]) -> usize { // CHECK: %[[ADDR:.+]] = ptrtoint ptr %slice.0 to [[USIZE]] - // CHECK: %[[UP:.+]] = add [[USIZE]] %[[ADDR]], 31 + // CHECK: %[[UP:.+]] = add [[USIZE]] %[[ADDR]], {{31|28}} // CHECK: %[[ALIGNED:.+]] = and [[USIZE]] %[[UP]], -32 // CHECK: %[[BOFFSET:.+]] = sub [[USIZE]] %[[ALIGNED]], %[[ADDR]] // CHECK: %[[OFFSET:.+]] = lshr exact [[USIZE]] %[[BOFFSET]], 2 @@ -57,7 +57,7 @@ pub fn align_offset_word_slice(slice: &[Align4]) -> usize { #[no_mangle] pub fn align_offset_word_ptr(ptr: *const Align4) -> usize { // CHECK: %[[ADDR:.+]] = ptrtoint ptr %ptr to [[USIZE]] - // CHECK: %[[UP:.+]] = add [[USIZE]] %[[ADDR]], 31 + // CHECK: %[[UP:.+]] = add [[USIZE]] %[[ADDR]], {{31|28}} // CHECK: %[[ALIGNED:.+]] = and [[USIZE]] %[[UP]], -32 // CHECK: %[[BOFFSET:.+]] = sub [[USIZE]] %[[ALIGNED]], %[[ADDR]] From 34ed98677513c81efa3fa7cf5948a810ac4c9e48 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Mon, 9 Feb 2026 16:31:39 -0500 Subject: [PATCH 3467/3801] improve build docs --- src/doc/rustc-dev-guide/src/offload/internals.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/offload/internals.md b/src/doc/rustc-dev-guide/src/offload/internals.md index 520c48d95896..836fd7ad2670 100644 --- a/src/doc/rustc-dev-guide/src/offload/internals.md +++ b/src/doc/rustc-dev-guide/src/offload/internals.md @@ -8,9 +8,15 @@ also offer more advanced, possibly unsafe, interfaces which allow a higher degre The implementation is based on LLVM's "offload" project, which is already used by OpenMP to run Fortran or C++ code on GPUs. While the project is under development, users will need to call other compilers like clang to finish the compilation process. -## High-level design: +## High-level compilation design: We use a single-source, two-pass compilation approach. First we compile all functions that should be offloaded for the device (e.g nvptx64, amdgcn-amd-amdhsa, intel in the future). Currently we require cumbersome `#cfg(target_os="")` annotations, but we intend to recognize those in the future based on our offload intrinsic. +This first compilation currently does not leverage rustc's internal Query system, so it will always recompile your kernels at the moment. This should be easy to fix, but we prioritize features and runtime performance improvements at the moment. Please reach out if you want to implement it, though! We then compile the code for the host (e.g. x86-64), where most of the offloading logic happens. On the host side, we generate calls to the openmp offload runtime, to inform it about the layout of the types (a simplified version of the autodiff TypeTrees). We also use the type system to figure out whether kernel arguments have to be moved only to the device (e.g. `&[f32;1024]`), from the device, or both (e.g. `&mut [f64]`). We then launch the kernel, after which we inform the runtime to end this environment and move data back (as far as needed). + +The second pass for the host will load the kernel artifacts from the previous compilation. rustc in general may not "guess" or hardcode the build directory layout, and as such it must be told the path to the kernel artifacts in the second invocation. The logic for this could be integrated into cargo, but it also only requires a trivial cargo wrapper, which we could trivially provide via crates.io till we see larger adoption. + +It might seem tempting to think about a single-source, single pass compilation approach. However, a lot of the rustc frontend (e.g. AST) will drop any dead code (e.g. code behind an inactive `cfg`). Getting the frontend to expand and lower code for two targets naively will result in multiple definitions of the same symbol (and other issues). Trying to teach the whole rustc middle and backend to be aware that any symbol now might contain two implementations is a large undertaking, and it is questionable why we should make the whole compiler more complex, if the alternative is a ~5 line cargo wrapper. We still control the full compilation pipeline and have both host and device code available, therefore there shouldn't be a runtime performance difference between the two approaches. + From 90fd76845cc73288f680f0d14d55f511bfe41fac Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 4 Jan 2026 16:52:51 +1100 Subject: [PATCH 3468/3801] Make it clearer that `check_pat_lit` only handles literal patterns --- compiler/rustc_hir_typeck/src/pat.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index f054145dc7e9..13f87c092352 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -3,6 +3,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant}; use rustc_abi::FieldIdx; use rustc_ast as ast; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxHashMap; use rustc_errors::codes::*; use rustc_errors::{ @@ -24,7 +25,6 @@ use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; -use rustc_span::source_map::Spanned; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode}; @@ -611,7 +611,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_ty(*hir_id, ty); ty } - PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, &pat_info.top_info), + PatKind::Expr(expr @ PatExpr { kind: PatExprKind::Lit { lit, .. }, .. }) => { + self.check_pat_lit(pat.span, expr, &lit.node, expected, &pat_info.top_info) + } PatKind::Range(lhs, rhs, _) => { self.check_pat_range(pat.span, lhs, rhs, expected, &pat_info.top_info) } @@ -938,23 +940,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_pat_lit( &self, span: Span, - lt: &hir::PatExpr<'tcx>, + expr: &hir::PatExpr<'tcx>, + lit_kind: &ast::LitKind, expected: Ty<'tcx>, ti: &TopInfo<'tcx>, ) -> Ty<'tcx> { + assert_matches!(expr.kind, hir::PatExprKind::Lit { .. }); + // We've already computed the type above (when checking for a non-ref pat), // so avoid computing it again. - let ty = self.node_ty(lt.hir_id); + let ty = self.node_ty(expr.hir_id); // Byte string patterns behave the same way as array patterns // They can denote both statically and dynamically-sized byte arrays. // Additionally, when `deref_patterns` is enabled, byte string literal patterns may have // types `[u8]` or `[u8; N]`, in order to type, e.g., `deref!(b"..."): Vec`. let mut pat_ty = ty; - if let hir::PatExprKind::Lit { - lit: Spanned { node: ast::LitKind::ByteStr(..), .. }, .. - } = lt.kind - { + if matches!(lit_kind, ast::LitKind::ByteStr(..)) { let tcx = self.tcx; let expected = self.structurally_resolve_type(span, expected); match *expected.kind() { @@ -962,7 +964,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Ref(_, inner_ty, _) if self.try_structurally_resolve_type(span, inner_ty).is_slice() => { - trace!(?lt.hir_id.local_id, "polymorphic byte string lit"); + trace!(?expr.hir_id.local_id, "polymorphic byte string lit"); pat_ty = Ty::new_imm_ref( tcx, tcx.lifetimes.re_static, @@ -988,9 +990,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // When `deref_patterns` is enabled, in order to allow `deref!("..."): String`, we allow // string literal patterns to have type `str`. This is accounted for when lowering to MIR. if self.tcx.features().deref_patterns() - && let hir::PatExprKind::Lit { - lit: Spanned { node: ast::LitKind::Str(..), .. }, .. - } = lt.kind + && matches!(lit_kind, ast::LitKind::Str(..)) && self.try_structurally_resolve_type(span, expected).is_str() { pat_ty = self.tcx.types.str_; From 91d47a5c0d82cce04c1e4aef2eacad4f8c9b7e8b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 8 Feb 2026 13:40:20 +1100 Subject: [PATCH 3469/3801] Don't import `TyCtxt` from `crate::ty::context` --- .../rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs | 3 +-- compiler/rustc_middle/src/ty/inhabitedness/mod.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index d03e593e37b9..c935869b504c 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -2,8 +2,7 @@ use rustc_macros::HashStable; use smallvec::SmallVec; use tracing::instrument; -use crate::ty::context::TyCtxt; -use crate::ty::{self, DefId, OpaqueTypeKey, Ty, TypingEnv}; +use crate::ty::{self, DefId, OpaqueTypeKey, Ty, TyCtxt, TypingEnv}; /// Represents whether some type is inhabited in a given context. /// Examples of uninhabited types are `!`, `enum Void {}`, or a struct diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 7eb74b52b44c..5c4c1733be29 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -47,8 +47,7 @@ use rustc_type_ir::TyKind::*; use tracing::instrument; use crate::query::Providers; -use crate::ty::context::TyCtxt; -use crate::ty::{self, DefId, Ty, TypeVisitableExt, VariantDef, Visibility}; +use crate::ty::{self, DefId, Ty, TyCtxt, TypeVisitableExt, VariantDef, Visibility}; pub mod inhabited_predicate; From 4234d2dd72b38069981a6ba0c4c6befb22d3276b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 8 Feb 2026 13:40:20 +1100 Subject: [PATCH 3470/3801] Move `impl Interner for TyCtxt` to its own submodule --- compiler/rustc_middle/src/ty/context.rs | 808 +----------------- .../src/ty/context/impl_interner.rs | 804 +++++++++++++++++ 2 files changed, 815 insertions(+), 797 deletions(-) create mode 100644 compiler/rustc_middle/src/ty/context/impl_interner.rs diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1bb83530487d..fbb959ce710d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2,6 +2,7 @@ #![allow(rustc::usage_of_ty_tykind)] +mod impl_interner; pub mod tls; use std::borrow::{Borrow, Cow}; @@ -16,6 +17,7 @@ use std::{fmt, iter, mem}; use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx}; use rustc_ast as ast; +use rustc_data_structures::defer; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; @@ -27,12 +29,9 @@ use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{ self, DynSend, DynSync, FreezeReadGuard, Lock, RwLock, WorkerLocal, }; -use rustc_data_structures::{debug_assert_matches, defer}; -use rustc_errors::{ - Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan, -}; +use rustc_errors::{Applicability, Diag, DiagCtxtHandle, LintDiagnostic, MultiSpan}; use rustc_hir::attrs::AttributeKind; -use rustc_hir::def::{CtorKind, CtorOf, DefKind}; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState}; use rustc_hir::intravisit::VisitorExt; @@ -50,16 +49,13 @@ use rustc_session::lint::Lint; use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw}; use rustc_type_ir::TyKind::*; -use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; pub use rustc_type_ir::lift::Lift; -use rustc_type_ir::{ - CollectAndApply, Interner, TypeFlags, TypeFoldable, WithCachedTypeInfo, elaborate, search_graph, -}; +use rustc_type_ir::{CollectAndApply, TypeFlags, WithCachedTypeInfo, elaborate, search_graph}; use tracing::{debug, instrument}; use crate::arena::Arena; use crate::dep_graph::{DepGraph, DepKindVTable}; -use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind, CanonicalVarKinds}; +use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind}; use crate::lint::lint_level; use crate::metadata::ModChild; use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature}; @@ -70,798 +66,16 @@ use crate::query::plumbing::QuerySystem; use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt}; use crate::thir::Thir; use crate::traits; -use crate::traits::cache::WithDepNode; -use crate::traits::solve::{ - self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, - QueryResult, inspect, -}; +use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques}; use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs, - GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, ParamTy, - Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, - PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, - ValTree, ValTreeKind, Visibility, + GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, Pattern, + PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity, + Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, ValTree, ValTreeKind, + Visibility, }; -#[allow(rustc::usage_of_ty_tykind)] -impl<'tcx> Interner for TyCtxt<'tcx> { - fn next_trait_solver_globally(self) -> bool { - self.next_trait_solver_globally() - } - - type DefId = DefId; - type LocalDefId = LocalDefId; - type TraitId = DefId; - type ForeignId = DefId; - type FunctionId = DefId; - type ClosureId = DefId; - type CoroutineClosureId = DefId; - type CoroutineId = DefId; - type AdtId = DefId; - type ImplId = DefId; - type UnevaluatedConstId = DefId; - type Span = Span; - - type GenericArgs = ty::GenericArgsRef<'tcx>; - - type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>]; - type GenericArg = ty::GenericArg<'tcx>; - type Term = ty::Term<'tcx>; - type BoundVarKinds = &'tcx List>; - - type PredefinedOpaques = solve::PredefinedOpaques<'tcx>; - - fn mk_predefined_opaques_in_body( - self, - data: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)], - ) -> Self::PredefinedOpaques { - self.mk_predefined_opaques_in_body(data) - } - type LocalDefIds = &'tcx ty::List; - type CanonicalVarKinds = CanonicalVarKinds<'tcx>; - fn mk_canonical_var_kinds( - self, - kinds: &[ty::CanonicalVarKind], - ) -> Self::CanonicalVarKinds { - self.mk_canonical_var_kinds(kinds) - } - - type ExternalConstraints = ExternalConstraints<'tcx>; - fn mk_external_constraints( - self, - data: ExternalConstraintsData, - ) -> ExternalConstraints<'tcx> { - self.mk_external_constraints(data) - } - type DepNodeIndex = DepNodeIndex; - fn with_cached_task(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) { - self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task) - } - type Ty = Ty<'tcx>; - type Tys = &'tcx List>; - - type FnInputTys = &'tcx [Ty<'tcx>]; - type ParamTy = ParamTy; - type Symbol = Symbol; - - type ErrorGuaranteed = ErrorGuaranteed; - type BoundExistentialPredicates = &'tcx List>; - - type AllocId = crate::mir::interpret::AllocId; - type Pat = Pattern<'tcx>; - type PatList = &'tcx List>; - type Safety = hir::Safety; - type Abi = ExternAbi; - type Const = ty::Const<'tcx>; - - type ParamConst = ty::ParamConst; - type ValueConst = ty::Value<'tcx>; - type ExprConst = ty::Expr<'tcx>; - type ValTree = ty::ValTree<'tcx>; - type ScalarInt = ty::ScalarInt; - - type Region = Region<'tcx>; - type EarlyParamRegion = ty::EarlyParamRegion; - type LateParamRegion = ty::LateParamRegion; - - type RegionAssumptions = &'tcx ty::List>; - - type ParamEnv = ty::ParamEnv<'tcx>; - type Predicate = Predicate<'tcx>; - - type Clause = Clause<'tcx>; - type Clauses = ty::Clauses<'tcx>; - - type Tracked = WithDepNode; - fn mk_tracked( - self, - data: T, - dep_node: DepNodeIndex, - ) -> Self::Tracked { - WithDepNode::new(dep_node, data) - } - fn get_tracked(self, tracked: &Self::Tracked) -> T { - tracked.get(self) - } - - fn with_global_cache(self, f: impl FnOnce(&mut search_graph::GlobalCache) -> R) -> R { - f(&mut *self.new_solver_evaluation_cache.lock()) - } - - fn canonical_param_env_cache_get_or_insert( - self, - param_env: ty::ParamEnv<'tcx>, - f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry, - from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry) -> R, - ) -> R { - let mut cache = self.new_solver_canonical_param_env_cache.lock(); - let entry = cache.entry(param_env).or_insert_with(f); - from_entry(entry) - } - - fn assert_evaluation_is_concurrent(&self) { - // Turns out, the assumption for this function isn't perfect. - // See trait-system-refactor-initiative#234. - } - - fn expand_abstract_consts>>(self, t: T) -> T { - self.expand_abstract_consts(t) - } - - type GenericsOf = &'tcx ty::Generics; - - fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics { - self.generics_of(def_id) - } - - type VariancesOf = &'tcx [ty::Variance]; - - fn variances_of(self, def_id: DefId) -> Self::VariancesOf { - self.variances_of(def_id) - } - - fn opt_alias_variances( - self, - kind: impl Into, - def_id: DefId, - ) -> Option<&'tcx [ty::Variance]> { - self.opt_alias_variances(kind, def_id) - } - - fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { - self.type_of(def_id) - } - fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { - self.type_of_opaque_hir_typeck(def_id) - } - fn const_of_item(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Const<'tcx>> { - self.const_of_item(def_id) - } - fn anon_const_kind(self, def_id: DefId) -> ty::AnonConstKind { - self.anon_const_kind(def_id) - } - - type AdtDef = ty::AdtDef<'tcx>; - fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef { - self.adt_def(adt_def_id) - } - - fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind { - match self.def_kind(alias.def_id) { - DefKind::AssocTy => { - if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id)) - { - ty::Inherent - } else { - ty::Projection - } - } - DefKind::OpaqueTy => ty::Opaque, - DefKind::TyAlias => ty::Free, - kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), - } - } - - fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind { - match self.def_kind(alias.def_id) { - DefKind::AssocTy => { - if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id)) - { - ty::AliasTermKind::InherentTy - } else { - ty::AliasTermKind::ProjectionTy - } - } - DefKind::AssocConst => { - if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id)) - { - ty::AliasTermKind::InherentConst - } else { - ty::AliasTermKind::ProjectionConst - } - } - DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy, - DefKind::TyAlias => ty::AliasTermKind::FreeTy, - DefKind::Const => ty::AliasTermKind::FreeConst, - DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => { - ty::AliasTermKind::UnevaluatedConst - } - kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), - } - } - - fn trait_ref_and_own_args_for_alias( - self, - def_id: DefId, - args: ty::GenericArgsRef<'tcx>, - ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { - debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst); - let trait_def_id = self.parent(def_id); - debug_assert_matches!(self.def_kind(trait_def_id), DefKind::Trait); - let trait_ref = ty::TraitRef::from_assoc(self, trait_def_id, args); - (trait_ref, &args[trait_ref.args.len()..]) - } - - fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> { - self.mk_args(args) - } - - fn mk_args_from_iter(self, args: I) -> T::Output - where - I: Iterator, - T: CollectAndApply>, - { - self.mk_args_from_iter(args) - } - - fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool { - self.check_args_compatible(def_id, args) - } - - fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) { - self.debug_assert_args_compatible(def_id, args); - } - - /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection` - /// are compatible with the `DefId`. Since we're missing a `Self` type, stick on - /// a dummy self type and forward to `debug_assert_args_compatible`. - fn debug_assert_existential_args_compatible( - self, - def_id: Self::DefId, - args: Self::GenericArgs, - ) { - // FIXME: We could perhaps add a `skip: usize` to `debug_assert_args_compatible` - // to avoid needing to reintern the set of args... - if cfg!(debug_assertions) { - self.debug_assert_args_compatible( - def_id, - self.mk_args_from_iter( - [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()), - ), - ); - } - } - - fn mk_type_list_from_iter(self, args: I) -> T::Output - where - I: Iterator, - T: CollectAndApply, &'tcx List>>, - { - self.mk_type_list_from_iter(args) - } - - fn parent(self, def_id: DefId) -> DefId { - self.parent(def_id) - } - - fn recursion_limit(self) -> usize { - self.recursion_limit().0 - } - - type Features = &'tcx rustc_feature::Features; - - fn features(self) -> Self::Features { - self.features() - } - - fn coroutine_hidden_types( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes>>> { - self.coroutine_hidden_types(def_id) - } - - fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { - self.fn_sig(def_id) - } - - fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability { - self.coroutine_movability(def_id) - } - - fn coroutine_for_closure(self, def_id: DefId) -> DefId { - self.coroutine_for_closure(def_id) - } - - fn generics_require_sized_self(self, def_id: DefId) -> bool { - self.generics_require_sized_self(def_id) - } - - fn item_bounds( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { - self.item_bounds(def_id).map_bound(IntoIterator::into_iter) - } - - fn item_self_bounds( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { - self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter) - } - - fn item_non_self_bounds( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { - self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter) - } - - fn predicates_of( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { - ty::EarlyBinder::bind( - self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(), - ) - } - - fn own_predicates_of( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { - ty::EarlyBinder::bind( - self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause), - ) - } - - fn explicit_super_predicates_of( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator, Span)>> { - self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied()) - } - - fn explicit_implied_predicates_of( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator, Span)>> { - self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied()) - } - - fn impl_super_outlives( - self, - impl_def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { - self.impl_super_outlives(impl_def_id) - } - - fn impl_is_const(self, def_id: DefId) -> bool { - debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true }); - self.is_conditionally_const(def_id) - } - - fn fn_is_const(self, def_id: DefId) -> bool { - debug_assert_matches!( - self.def_kind(def_id), - DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) - ); - self.is_conditionally_const(def_id) - } - - fn alias_has_const_conditions(self, def_id: DefId) -> bool { - debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy); - self.is_conditionally_const(def_id) - } - - fn const_conditions( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { - ty::EarlyBinder::bind( - self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c), - ) - } - - fn explicit_implied_const_bounds( - self, - def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { - ty::EarlyBinder::bind( - self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c), - ) - } - - fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool { - self.impl_self_is_guaranteed_unsized(impl_def_id) - } - - fn has_target_features(self, def_id: DefId) -> bool { - !self.codegen_fn_attrs(def_id).target_features.is_empty() - } - - fn require_lang_item(self, lang_item: SolverLangItem) -> DefId { - self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP) - } - - fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> DefId { - self.require_lang_item(solver_trait_lang_item_to_lang_item(lang_item), DUMMY_SP) - } - - fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> DefId { - self.require_lang_item(solver_adt_lang_item_to_lang_item(lang_item), DUMMY_SP) - } - - fn is_lang_item(self, def_id: DefId, lang_item: SolverLangItem) -> bool { - self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item)) - } - - fn is_trait_lang_item(self, def_id: DefId, lang_item: SolverTraitLangItem) -> bool { - self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item)) - } - - fn is_adt_lang_item(self, def_id: DefId, lang_item: SolverAdtLangItem) -> bool { - self.is_lang_item(def_id, solver_adt_lang_item_to_lang_item(lang_item)) - } - - fn is_default_trait(self, def_id: DefId) -> bool { - self.is_default_trait(def_id) - } - - fn is_sizedness_trait(self, def_id: DefId) -> bool { - self.is_sizedness_trait(def_id) - } - - fn as_lang_item(self, def_id: DefId) -> Option { - lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?) - } - - fn as_trait_lang_item(self, def_id: DefId) -> Option { - lang_item_to_solver_trait_lang_item(self.lang_items().from_def_id(def_id)?) - } - - fn as_adt_lang_item(self, def_id: DefId) -> Option { - lang_item_to_solver_adt_lang_item(self.lang_items().from_def_id(def_id)?) - } - - fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator { - self.associated_items(def_id) - .in_definition_order() - .filter(|assoc_item| assoc_item.is_type()) - .map(|assoc_item| assoc_item.def_id) - } - - // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`, - // since we want to skip over blanket impls for non-rigid aliases, and also we - // only want to consider types that *actually* unify with float/int vars. - fn for_each_relevant_impl( - self, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - mut f: impl FnMut(DefId), - ) { - let tcx = self; - let trait_impls = tcx.trait_impls_of(trait_def_id); - let mut consider_impls_for_simplified_type = |simp| { - if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) { - for &impl_def_id in impls_for_type { - f(impl_def_id); - } - } - }; - - match self_ty.kind() { - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Adt(_, _) - | ty::Foreign(_) - | ty::Str - | ty::Array(_, _) - | ty::Pat(_, _) - | ty::Slice(_) - | ty::RawPtr(_, _) - | ty::Ref(_, _, _) - | ty::FnDef(_, _) - | ty::FnPtr(..) - | ty::Dynamic(_, _) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Coroutine(_, _) - | ty::Never - | ty::Tuple(_) - | ty::UnsafeBinder(_) => { - if let Some(simp) = ty::fast_reject::simplify_type( - tcx, - self_ty, - ty::fast_reject::TreatParams::AsRigid, - ) { - consider_impls_for_simplified_type(simp); - } - } - - // HACK: For integer and float variables we have to manually look at all impls - // which have some integer or float as a self type. - ty::Infer(ty::IntVar(_)) => { - use ty::IntTy::*; - use ty::UintTy::*; - // This causes a compiler error if any new integer kinds are added. - let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy; - let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy; - let possible_integers = [ - // signed integers - ty::SimplifiedType::Int(I8), - ty::SimplifiedType::Int(I16), - ty::SimplifiedType::Int(I32), - ty::SimplifiedType::Int(I64), - ty::SimplifiedType::Int(I128), - ty::SimplifiedType::Int(Isize), - // unsigned integers - ty::SimplifiedType::Uint(U8), - ty::SimplifiedType::Uint(U16), - ty::SimplifiedType::Uint(U32), - ty::SimplifiedType::Uint(U64), - ty::SimplifiedType::Uint(U128), - ty::SimplifiedType::Uint(Usize), - ]; - for simp in possible_integers { - consider_impls_for_simplified_type(simp); - } - } - - ty::Infer(ty::FloatVar(_)) => { - // This causes a compiler error if any new float kinds are added. - let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128); - let possible_floats = [ - ty::SimplifiedType::Float(ty::FloatTy::F16), - ty::SimplifiedType::Float(ty::FloatTy::F32), - ty::SimplifiedType::Float(ty::FloatTy::F64), - ty::SimplifiedType::Float(ty::FloatTy::F128), - ]; - - for simp in possible_floats { - consider_impls_for_simplified_type(simp); - } - } - - // The only traits applying to aliases and placeholders are blanket impls. - // - // Impls which apply to an alias after normalization are handled by - // `assemble_candidates_after_normalizing_self_ty`. - ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (), - - // FIXME: These should ideally not exist as a self type. It would be nice for - // the builtin auto trait impls of coroutines to instead directly recurse - // into the witness. - ty::CoroutineWitness(..) => (), - - // These variants should not exist as a self type. - ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) - | ty::Param(_) - | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"), - } - - #[allow(rustc::usage_of_type_ir_traits)] - self.for_each_blanket_impl(trait_def_id, f) - } - fn for_each_blanket_impl(self, trait_def_id: DefId, mut f: impl FnMut(DefId)) { - let trait_impls = self.trait_impls_of(trait_def_id); - for &impl_def_id in trait_impls.blanket_impls() { - f(impl_def_id); - } - } - - fn has_item_definition(self, def_id: DefId) -> bool { - self.defaultness(def_id).has_value() - } - - fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool { - self.specializes((impl_def_id, victim_def_id)) - } - - fn impl_is_default(self, impl_def_id: DefId) -> bool { - self.defaultness(impl_def_id).is_default() - } - - fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> { - self.impl_trait_ref(impl_def_id) - } - - fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity { - self.impl_polarity(impl_def_id) - } - - fn trait_is_auto(self, trait_def_id: DefId) -> bool { - self.trait_is_auto(trait_def_id) - } - - fn trait_is_coinductive(self, trait_def_id: DefId) -> bool { - self.trait_is_coinductive(trait_def_id) - } - - fn trait_is_alias(self, trait_def_id: DefId) -> bool { - self.trait_is_alias(trait_def_id) - } - - fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool { - self.is_dyn_compatible(trait_def_id) - } - - fn trait_is_fundamental(self, def_id: DefId) -> bool { - self.trait_def(def_id).is_fundamental - } - - fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool { - self.trait_def(trait_def_id).safety.is_unsafe() - } - - fn is_impl_trait_in_trait(self, def_id: DefId) -> bool { - self.is_impl_trait_in_trait(def_id) - } - - fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed { - self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string()) - } - - fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool { - self.is_general_coroutine(coroutine_def_id) - } - - fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool { - self.coroutine_is_async(coroutine_def_id) - } - - fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool { - self.coroutine_is_gen(coroutine_def_id) - } - - fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool { - self.coroutine_is_async_gen(coroutine_def_id) - } - - type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet; - fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams { - self.unsizing_params_for_adt(adt_def_id) - } - - fn anonymize_bound_vars>>( - self, - binder: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { - self.anonymize_bound_vars(binder) - } - - fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds { - self.opaque_types_defined_by(defining_anchor) - } - - fn opaque_types_and_coroutines_defined_by( - self, - defining_anchor: Self::LocalDefId, - ) -> Self::LocalDefIds { - let coroutines_defined_by = self - .nested_bodies_within(defining_anchor) - .iter() - .filter(|def_id| self.is_coroutine(def_id.to_def_id())); - self.mk_local_def_ids_from_iter( - self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by), - ) - } - - type Probe = &'tcx inspect::Probe>; - fn mk_probe(self, probe: inspect::Probe) -> &'tcx inspect::Probe> { - self.arena.alloc(probe) - } - fn evaluate_root_goal_for_proof_tree_raw( - self, - canonical_goal: CanonicalInput<'tcx>, - ) -> (QueryResult<'tcx>, &'tcx inspect::Probe>) { - self.evaluate_root_goal_for_proof_tree_raw(canonical_goal) - } - - fn item_name(self, id: DefId) -> Symbol { - let id = id.into_query_param(); - self.opt_item_name(id).unwrap_or_else(|| { - bug!("item_name: no name for {:?}", self.def_path(id)); - }) - } -} - -macro_rules! bidirectional_lang_item_map { - ( - $solver_ty:ident, $to_solver:ident, $from_solver:ident; - $($name:ident),+ $(,)? - ) => { - fn $from_solver(lang_item: $solver_ty) -> LangItem { - match lang_item { - $($solver_ty::$name => LangItem::$name,)+ - } - } - - fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> { - Some(match lang_item { - $(LangItem::$name => $solver_ty::$name,)+ - _ => return None, - }) - } - } -} - -bidirectional_lang_item_map! { - SolverLangItem, lang_item_to_solver_lang_item, solver_lang_item_to_lang_item; - -// tidy-alphabetical-start - AsyncFnKindUpvars, - AsyncFnOnceOutput, - CallOnceFuture, - CallRefFuture, - CoroutineReturn, - CoroutineYield, - DynMetadata, - FutureOutput, - Metadata, -// tidy-alphabetical-end -} - -bidirectional_lang_item_map! { - SolverAdtLangItem, lang_item_to_solver_adt_lang_item, solver_adt_lang_item_to_lang_item; - -// tidy-alphabetical-start - Option, - Poll, -// tidy-alphabetical-end -} - -bidirectional_lang_item_map! { - SolverTraitLangItem, lang_item_to_solver_trait_lang_item, solver_trait_lang_item_to_lang_item; - -// tidy-alphabetical-start - AsyncFn, - AsyncFnKindHelper, - AsyncFnMut, - AsyncFnOnce, - AsyncFnOnceOutput, - AsyncIterator, - BikeshedGuaranteedNoDrop, - Clone, - Copy, - Coroutine, - Destruct, - DiscriminantKind, - Drop, - Fn, - FnMut, - FnOnce, - FnPtrTrait, - FusedIterator, - Future, - Iterator, - MetaSized, - PointeeSized, - PointeeTrait, - Sized, - TransmuteTrait, - TrivialClone, - Tuple, - Unpin, - Unsize, -// tidy-alphabetical-end -} - impl<'tcx> rustc_type_ir::inherent::DefId> for DefId { fn is_local(self) -> bool { self.is_local() diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs new file mode 100644 index 000000000000..c449f29634e2 --- /dev/null +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -0,0 +1,804 @@ +//! Implementation of [`rustc_type_ir::Interner`] for [`TyCtxt`]. + +use std::fmt; + +use rustc_abi::ExternAbi; +use rustc_data_structures::debug_assert_matches; +use rustc_errors::ErrorGuaranteed; +use rustc_hir::def::{CtorKind, CtorOf, DefKind}; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::lang_items::LangItem; +use rustc_hir::{self as hir}; +use rustc_query_system::dep_graph::DepNodeIndex; +use rustc_span::{DUMMY_SP, Span, Symbol}; +use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; +use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, search_graph}; + +use crate::infer::canonical::CanonicalVarKinds; +use crate::query::IntoQueryParam; +use crate::traits::cache::WithDepNode; +use crate::traits::solve::{ + self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect, +}; +use crate::ty::{ + self, Clause, Const, List, ParamTy, Pattern, PolyExistentialPredicate, Predicate, Region, Ty, + TyCtxt, +}; + +#[allow(rustc::usage_of_ty_tykind)] +impl<'tcx> Interner for TyCtxt<'tcx> { + fn next_trait_solver_globally(self) -> bool { + self.next_trait_solver_globally() + } + + type DefId = DefId; + type LocalDefId = LocalDefId; + type TraitId = DefId; + type ForeignId = DefId; + type FunctionId = DefId; + type ClosureId = DefId; + type CoroutineClosureId = DefId; + type CoroutineId = DefId; + type AdtId = DefId; + type ImplId = DefId; + type UnevaluatedConstId = DefId; + type Span = Span; + + type GenericArgs = ty::GenericArgsRef<'tcx>; + + type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>]; + type GenericArg = ty::GenericArg<'tcx>; + type Term = ty::Term<'tcx>; + type BoundVarKinds = &'tcx List>; + + type PredefinedOpaques = solve::PredefinedOpaques<'tcx>; + + fn mk_predefined_opaques_in_body( + self, + data: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)], + ) -> Self::PredefinedOpaques { + self.mk_predefined_opaques_in_body(data) + } + type LocalDefIds = &'tcx ty::List; + type CanonicalVarKinds = CanonicalVarKinds<'tcx>; + fn mk_canonical_var_kinds( + self, + kinds: &[ty::CanonicalVarKind], + ) -> Self::CanonicalVarKinds { + self.mk_canonical_var_kinds(kinds) + } + + type ExternalConstraints = ExternalConstraints<'tcx>; + fn mk_external_constraints( + self, + data: ExternalConstraintsData, + ) -> ExternalConstraints<'tcx> { + self.mk_external_constraints(data) + } + type DepNodeIndex = DepNodeIndex; + fn with_cached_task(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) { + self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task) + } + type Ty = Ty<'tcx>; + type Tys = &'tcx List>; + + type FnInputTys = &'tcx [Ty<'tcx>]; + type ParamTy = ParamTy; + type Symbol = Symbol; + + type ErrorGuaranteed = ErrorGuaranteed; + type BoundExistentialPredicates = &'tcx List>; + + type AllocId = crate::mir::interpret::AllocId; + type Pat = Pattern<'tcx>; + type PatList = &'tcx List>; + type Safety = hir::Safety; + type Abi = ExternAbi; + type Const = ty::Const<'tcx>; + + type ParamConst = ty::ParamConst; + type ValueConst = ty::Value<'tcx>; + type ExprConst = ty::Expr<'tcx>; + type ValTree = ty::ValTree<'tcx>; + type ScalarInt = ty::ScalarInt; + + type Region = Region<'tcx>; + type EarlyParamRegion = ty::EarlyParamRegion; + type LateParamRegion = ty::LateParamRegion; + + type RegionAssumptions = &'tcx ty::List>; + + type ParamEnv = ty::ParamEnv<'tcx>; + type Predicate = Predicate<'tcx>; + + type Clause = Clause<'tcx>; + type Clauses = ty::Clauses<'tcx>; + + type Tracked = WithDepNode; + fn mk_tracked( + self, + data: T, + dep_node: DepNodeIndex, + ) -> Self::Tracked { + WithDepNode::new(dep_node, data) + } + fn get_tracked(self, tracked: &Self::Tracked) -> T { + tracked.get(self) + } + + fn with_global_cache(self, f: impl FnOnce(&mut search_graph::GlobalCache) -> R) -> R { + f(&mut *self.new_solver_evaluation_cache.lock()) + } + + fn canonical_param_env_cache_get_or_insert( + self, + param_env: ty::ParamEnv<'tcx>, + f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry, + from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry) -> R, + ) -> R { + let mut cache = self.new_solver_canonical_param_env_cache.lock(); + let entry = cache.entry(param_env).or_insert_with(f); + from_entry(entry) + } + + fn assert_evaluation_is_concurrent(&self) { + // Turns out, the assumption for this function isn't perfect. + // See trait-system-refactor-initiative#234. + } + + fn expand_abstract_consts>>(self, t: T) -> T { + self.expand_abstract_consts(t) + } + + type GenericsOf = &'tcx ty::Generics; + + fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics { + self.generics_of(def_id) + } + + type VariancesOf = &'tcx [ty::Variance]; + + fn variances_of(self, def_id: DefId) -> Self::VariancesOf { + self.variances_of(def_id) + } + + fn opt_alias_variances( + self, + kind: impl Into, + def_id: DefId, + ) -> Option<&'tcx [ty::Variance]> { + self.opt_alias_variances(kind, def_id) + } + + fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { + self.type_of(def_id) + } + fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { + self.type_of_opaque_hir_typeck(def_id) + } + fn const_of_item(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Const<'tcx>> { + self.const_of_item(def_id) + } + fn anon_const_kind(self, def_id: DefId) -> ty::AnonConstKind { + self.anon_const_kind(def_id) + } + + type AdtDef = ty::AdtDef<'tcx>; + fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef { + self.adt_def(adt_def_id) + } + + fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind { + match self.def_kind(alias.def_id) { + DefKind::AssocTy => { + if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id)) + { + ty::Inherent + } else { + ty::Projection + } + } + DefKind::OpaqueTy => ty::Opaque, + DefKind::TyAlias => ty::Free, + kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), + } + } + + fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind { + match self.def_kind(alias.def_id) { + DefKind::AssocTy => { + if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id)) + { + ty::AliasTermKind::InherentTy + } else { + ty::AliasTermKind::ProjectionTy + } + } + DefKind::AssocConst => { + if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id)) + { + ty::AliasTermKind::InherentConst + } else { + ty::AliasTermKind::ProjectionConst + } + } + DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy, + DefKind::TyAlias => ty::AliasTermKind::FreeTy, + DefKind::Const => ty::AliasTermKind::FreeConst, + DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => { + ty::AliasTermKind::UnevaluatedConst + } + kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), + } + } + + fn trait_ref_and_own_args_for_alias( + self, + def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { + debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst); + let trait_def_id = self.parent(def_id); + debug_assert_matches!(self.def_kind(trait_def_id), DefKind::Trait); + let trait_ref = ty::TraitRef::from_assoc(self, trait_def_id, args); + (trait_ref, &args[trait_ref.args.len()..]) + } + + fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> { + self.mk_args(args) + } + + fn mk_args_from_iter(self, args: I) -> T::Output + where + I: Iterator, + T: CollectAndApply>, + { + self.mk_args_from_iter(args) + } + + fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool { + self.check_args_compatible(def_id, args) + } + + fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) { + self.debug_assert_args_compatible(def_id, args); + } + + /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection` + /// are compatible with the `DefId`. Since we're missing a `Self` type, stick on + /// a dummy self type and forward to `debug_assert_args_compatible`. + fn debug_assert_existential_args_compatible( + self, + def_id: Self::DefId, + args: Self::GenericArgs, + ) { + // FIXME: We could perhaps add a `skip: usize` to `debug_assert_args_compatible` + // to avoid needing to reintern the set of args... + if cfg!(debug_assertions) { + self.debug_assert_args_compatible( + def_id, + self.mk_args_from_iter( + [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()), + ), + ); + } + } + + fn mk_type_list_from_iter(self, args: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + self.mk_type_list_from_iter(args) + } + + fn parent(self, def_id: DefId) -> DefId { + self.parent(def_id) + } + + fn recursion_limit(self) -> usize { + self.recursion_limit().0 + } + + type Features = &'tcx rustc_feature::Features; + + fn features(self) -> Self::Features { + self.features() + } + + fn coroutine_hidden_types( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes>>> { + self.coroutine_hidden_types(def_id) + } + + fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { + self.fn_sig(def_id) + } + + fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability { + self.coroutine_movability(def_id) + } + + fn coroutine_for_closure(self, def_id: DefId) -> DefId { + self.coroutine_for_closure(def_id) + } + + fn generics_require_sized_self(self, def_id: DefId) -> bool { + self.generics_require_sized_self(def_id) + } + + fn item_bounds( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { + self.item_bounds(def_id).map_bound(IntoIterator::into_iter) + } + + fn item_self_bounds( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { + self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter) + } + + fn item_non_self_bounds( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { + self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter) + } + + fn predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { + ty::EarlyBinder::bind( + self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(), + ) + } + + fn own_predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { + ty::EarlyBinder::bind( + self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause), + ) + } + + fn explicit_super_predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator, Span)>> { + self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied()) + } + + fn explicit_implied_predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator, Span)>> { + self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied()) + } + + fn impl_super_outlives( + self, + impl_def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { + self.impl_super_outlives(impl_def_id) + } + + fn impl_is_const(self, def_id: DefId) -> bool { + debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true }); + self.is_conditionally_const(def_id) + } + + fn fn_is_const(self, def_id: DefId) -> bool { + debug_assert_matches!( + self.def_kind(def_id), + DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) + ); + self.is_conditionally_const(def_id) + } + + fn alias_has_const_conditions(self, def_id: DefId) -> bool { + debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy); + self.is_conditionally_const(def_id) + } + + fn const_conditions( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { + ty::EarlyBinder::bind( + self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c), + ) + } + + fn explicit_implied_const_bounds( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { + ty::EarlyBinder::bind( + self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c), + ) + } + + fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool { + self.impl_self_is_guaranteed_unsized(impl_def_id) + } + + fn has_target_features(self, def_id: DefId) -> bool { + !self.codegen_fn_attrs(def_id).target_features.is_empty() + } + + fn require_lang_item(self, lang_item: SolverLangItem) -> DefId { + self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP) + } + + fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> DefId { + self.require_lang_item(solver_trait_lang_item_to_lang_item(lang_item), DUMMY_SP) + } + + fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> DefId { + self.require_lang_item(solver_adt_lang_item_to_lang_item(lang_item), DUMMY_SP) + } + + fn is_lang_item(self, def_id: DefId, lang_item: SolverLangItem) -> bool { + self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item)) + } + + fn is_trait_lang_item(self, def_id: DefId, lang_item: SolverTraitLangItem) -> bool { + self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item)) + } + + fn is_adt_lang_item(self, def_id: DefId, lang_item: SolverAdtLangItem) -> bool { + self.is_lang_item(def_id, solver_adt_lang_item_to_lang_item(lang_item)) + } + + fn is_default_trait(self, def_id: DefId) -> bool { + self.is_default_trait(def_id) + } + + fn is_sizedness_trait(self, def_id: DefId) -> bool { + self.is_sizedness_trait(def_id) + } + + fn as_lang_item(self, def_id: DefId) -> Option { + lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?) + } + + fn as_trait_lang_item(self, def_id: DefId) -> Option { + lang_item_to_solver_trait_lang_item(self.lang_items().from_def_id(def_id)?) + } + + fn as_adt_lang_item(self, def_id: DefId) -> Option { + lang_item_to_solver_adt_lang_item(self.lang_items().from_def_id(def_id)?) + } + + fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator { + self.associated_items(def_id) + .in_definition_order() + .filter(|assoc_item| assoc_item.is_type()) + .map(|assoc_item| assoc_item.def_id) + } + + // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`, + // since we want to skip over blanket impls for non-rigid aliases, and also we + // only want to consider types that *actually* unify with float/int vars. + fn for_each_relevant_impl( + self, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + mut f: impl FnMut(DefId), + ) { + let tcx = self; + let trait_impls = tcx.trait_impls_of(trait_def_id); + let mut consider_impls_for_simplified_type = |simp| { + if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) { + for &impl_def_id in impls_for_type { + f(impl_def_id); + } + } + }; + + match self_ty.kind() { + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Adt(_, _) + | ty::Foreign(_) + | ty::Str + | ty::Array(_, _) + | ty::Pat(_, _) + | ty::Slice(_) + | ty::RawPtr(_, _) + | ty::Ref(_, _, _) + | ty::FnDef(_, _) + | ty::FnPtr(..) + | ty::Dynamic(_, _) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(_, _) + | ty::Never + | ty::Tuple(_) + | ty::UnsafeBinder(_) => { + if let Some(simp) = ty::fast_reject::simplify_type( + tcx, + self_ty, + ty::fast_reject::TreatParams::AsRigid, + ) { + consider_impls_for_simplified_type(simp); + } + } + + // HACK: For integer and float variables we have to manually look at all impls + // which have some integer or float as a self type. + ty::Infer(ty::IntVar(_)) => { + use ty::IntTy::*; + use ty::UintTy::*; + // This causes a compiler error if any new integer kinds are added. + let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy; + let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy; + let possible_integers = [ + // signed integers + ty::SimplifiedType::Int(I8), + ty::SimplifiedType::Int(I16), + ty::SimplifiedType::Int(I32), + ty::SimplifiedType::Int(I64), + ty::SimplifiedType::Int(I128), + ty::SimplifiedType::Int(Isize), + // unsigned integers + ty::SimplifiedType::Uint(U8), + ty::SimplifiedType::Uint(U16), + ty::SimplifiedType::Uint(U32), + ty::SimplifiedType::Uint(U64), + ty::SimplifiedType::Uint(U128), + ty::SimplifiedType::Uint(Usize), + ]; + for simp in possible_integers { + consider_impls_for_simplified_type(simp); + } + } + + ty::Infer(ty::FloatVar(_)) => { + // This causes a compiler error if any new float kinds are added. + let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128); + let possible_floats = [ + ty::SimplifiedType::Float(ty::FloatTy::F16), + ty::SimplifiedType::Float(ty::FloatTy::F32), + ty::SimplifiedType::Float(ty::FloatTy::F64), + ty::SimplifiedType::Float(ty::FloatTy::F128), + ]; + + for simp in possible_floats { + consider_impls_for_simplified_type(simp); + } + } + + // The only traits applying to aliases and placeholders are blanket impls. + // + // Impls which apply to an alias after normalization are handled by + // `assemble_candidates_after_normalizing_self_ty`. + ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (), + + // FIXME: These should ideally not exist as a self type. It would be nice for + // the builtin auto trait impls of coroutines to instead directly recurse + // into the witness. + ty::CoroutineWitness(..) => (), + + // These variants should not exist as a self type. + ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) + | ty::Param(_) + | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"), + } + + #[allow(rustc::usage_of_type_ir_traits)] + self.for_each_blanket_impl(trait_def_id, f) + } + fn for_each_blanket_impl(self, trait_def_id: DefId, mut f: impl FnMut(DefId)) { + let trait_impls = self.trait_impls_of(trait_def_id); + for &impl_def_id in trait_impls.blanket_impls() { + f(impl_def_id); + } + } + + fn has_item_definition(self, def_id: DefId) -> bool { + self.defaultness(def_id).has_value() + } + + fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool { + self.specializes((impl_def_id, victim_def_id)) + } + + fn impl_is_default(self, impl_def_id: DefId) -> bool { + self.defaultness(impl_def_id).is_default() + } + + fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> { + self.impl_trait_ref(impl_def_id) + } + + fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity { + self.impl_polarity(impl_def_id) + } + + fn trait_is_auto(self, trait_def_id: DefId) -> bool { + self.trait_is_auto(trait_def_id) + } + + fn trait_is_coinductive(self, trait_def_id: DefId) -> bool { + self.trait_is_coinductive(trait_def_id) + } + + fn trait_is_alias(self, trait_def_id: DefId) -> bool { + self.trait_is_alias(trait_def_id) + } + + fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool { + self.is_dyn_compatible(trait_def_id) + } + + fn trait_is_fundamental(self, def_id: DefId) -> bool { + self.trait_def(def_id).is_fundamental + } + + fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool { + self.trait_def(trait_def_id).safety.is_unsafe() + } + + fn is_impl_trait_in_trait(self, def_id: DefId) -> bool { + self.is_impl_trait_in_trait(def_id) + } + + fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed { + self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string()) + } + + fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool { + self.is_general_coroutine(coroutine_def_id) + } + + fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool { + self.coroutine_is_async(coroutine_def_id) + } + + fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool { + self.coroutine_is_gen(coroutine_def_id) + } + + fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool { + self.coroutine_is_async_gen(coroutine_def_id) + } + + type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet; + fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams { + self.unsizing_params_for_adt(adt_def_id) + } + + fn anonymize_bound_vars>>( + self, + binder: ty::Binder<'tcx, T>, + ) -> ty::Binder<'tcx, T> { + self.anonymize_bound_vars(binder) + } + + fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds { + self.opaque_types_defined_by(defining_anchor) + } + + fn opaque_types_and_coroutines_defined_by( + self, + defining_anchor: Self::LocalDefId, + ) -> Self::LocalDefIds { + let coroutines_defined_by = self + .nested_bodies_within(defining_anchor) + .iter() + .filter(|def_id| self.is_coroutine(def_id.to_def_id())); + self.mk_local_def_ids_from_iter( + self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by), + ) + } + + type Probe = &'tcx inspect::Probe>; + fn mk_probe(self, probe: inspect::Probe) -> &'tcx inspect::Probe> { + self.arena.alloc(probe) + } + fn evaluate_root_goal_for_proof_tree_raw( + self, + canonical_goal: CanonicalInput<'tcx>, + ) -> (QueryResult<'tcx>, &'tcx inspect::Probe>) { + self.evaluate_root_goal_for_proof_tree_raw(canonical_goal) + } + + fn item_name(self, id: DefId) -> Symbol { + let id = id.into_query_param(); + self.opt_item_name(id).unwrap_or_else(|| { + bug!("item_name: no name for {:?}", self.def_path(id)); + }) + } +} + +macro_rules! bidirectional_lang_item_map { + ( + $solver_ty:ident, $to_solver:ident, $from_solver:ident; + $($name:ident),+ $(,)? + ) => { + fn $from_solver(lang_item: $solver_ty) -> LangItem { + match lang_item { + $($solver_ty::$name => LangItem::$name,)+ + } + } + + fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> { + Some(match lang_item { + $(LangItem::$name => $solver_ty::$name,)+ + _ => return None, + }) + } + } +} + +bidirectional_lang_item_map! { + SolverLangItem, lang_item_to_solver_lang_item, solver_lang_item_to_lang_item; + +// tidy-alphabetical-start + AsyncFnKindUpvars, + AsyncFnOnceOutput, + CallOnceFuture, + CallRefFuture, + CoroutineReturn, + CoroutineYield, + DynMetadata, + FutureOutput, + Metadata, +// tidy-alphabetical-end +} + +bidirectional_lang_item_map! { + SolverAdtLangItem, lang_item_to_solver_adt_lang_item, solver_adt_lang_item_to_lang_item; + +// tidy-alphabetical-start + Option, + Poll, +// tidy-alphabetical-end +} + +bidirectional_lang_item_map! { + SolverTraitLangItem, lang_item_to_solver_trait_lang_item, solver_trait_lang_item_to_lang_item; + +// tidy-alphabetical-start + AsyncFn, + AsyncFnKindHelper, + AsyncFnMut, + AsyncFnOnce, + AsyncFnOnceOutput, + AsyncIterator, + BikeshedGuaranteedNoDrop, + Clone, + Copy, + Coroutine, + Destruct, + DiscriminantKind, + Drop, + Fn, + FnMut, + FnOnce, + FnPtrTrait, + FusedIterator, + Future, + Iterator, + MetaSized, + PointeeSized, + PointeeTrait, + Sized, + TransmuteTrait, + TrivialClone, + Tuple, + Unpin, + Unsize, +// tidy-alphabetical-end +} From b7bfb768d0f9da6a90c32ad596fd17f57935ae87 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 8 Feb 2026 13:40:20 +1100 Subject: [PATCH 3471/3801] Indicate that `bidirectional_lang_item_map!` declares functions Requiring `fn` in the macro syntax makes it a little more obvious that the macro declares functions with those names, and makes them easier to grep for. --- compiler/rustc_middle/src/ty/context/impl_interner.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index c449f29634e2..5a15d132048d 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -722,9 +722,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } } +/// Defines trivial conversion functions between the main [`LangItem`] enum, +/// and some other lang-item enum that is a subset of it. macro_rules! bidirectional_lang_item_map { ( - $solver_ty:ident, $to_solver:ident, $from_solver:ident; + $solver_ty:ident, fn $to_solver:ident, fn $from_solver:ident; $($name:ident),+ $(,)? ) => { fn $from_solver(lang_item: $solver_ty) -> LangItem { @@ -743,7 +745,7 @@ macro_rules! bidirectional_lang_item_map { } bidirectional_lang_item_map! { - SolverLangItem, lang_item_to_solver_lang_item, solver_lang_item_to_lang_item; + SolverLangItem, fn lang_item_to_solver_lang_item, fn solver_lang_item_to_lang_item; // tidy-alphabetical-start AsyncFnKindUpvars, @@ -759,7 +761,7 @@ bidirectional_lang_item_map! { } bidirectional_lang_item_map! { - SolverAdtLangItem, lang_item_to_solver_adt_lang_item, solver_adt_lang_item_to_lang_item; + SolverAdtLangItem, fn lang_item_to_solver_adt_lang_item, fn solver_adt_lang_item_to_lang_item; // tidy-alphabetical-start Option, @@ -768,7 +770,7 @@ bidirectional_lang_item_map! { } bidirectional_lang_item_map! { - SolverTraitLangItem, lang_item_to_solver_trait_lang_item, solver_trait_lang_item_to_lang_item; + SolverTraitLangItem, fn lang_item_to_solver_trait_lang_item, fn solver_trait_lang_item_to_lang_item; // tidy-alphabetical-start AsyncFn, From e1ed3bf01d602fefe6797fb56b52de5161fe64c4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Feb 2026 12:22:40 +1100 Subject: [PATCH 3472/3801] Remove out-of-date comment. Keys and values now must be `Copy` due to erasing. --- compiler/rustc_query_system/src/query/caches.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index eea1c5872290..c1f5e5b67085 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -21,9 +21,6 @@ pub trait QueryCacheKey = Hash + Eq + Copy + Debug + for<'a> HashStable Date: Tue, 10 Feb 2026 10:16:56 +1100 Subject: [PATCH 3473/3801] Derive `Clone` for `QueryLatch`. The derived version is equivalent to the hand-written version. --- compiler/rustc_query_system/src/query/job.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index bf7c480b05dd..c77ae38ba96f 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -181,17 +181,11 @@ struct QueryLatchInfo<'tcx> { waiters: Vec>>, } -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct QueryLatch<'tcx> { info: Arc>>, } -impl<'tcx> Clone for QueryLatch<'tcx> { - fn clone(&self) -> Self { - Self { info: Arc::clone(&self.info) } - } -} - impl<'tcx> QueryLatch<'tcx> { fn new() -> Self { QueryLatch { From 4dc82e99efad0d0fbb91218b82394a48fcd0ed87 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 5 Feb 2026 18:21:27 +1100 Subject: [PATCH 3474/3801] Move the needs-drop check for `arena_cache` queries out of macro code --- compiler/rustc_middle/src/queries.rs | 1 - .../rustc_middle/src/query/arena_cached.rs | 33 +++++++++----- compiler/rustc_middle/src/query/plumbing.rs | 44 ++++++++----------- 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index de2298914438..2fdc44ecd269 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -63,7 +63,6 @@ #![allow(unused_parens)] use std::ffi::OsStr; -use std::mem; use std::path::PathBuf; use std::sync::Arc; diff --git a/compiler/rustc_middle/src/query/arena_cached.rs b/compiler/rustc_middle/src/query/arena_cached.rs index ec6e466ff688..7c7ad1262260 100644 --- a/compiler/rustc_middle/src/query/arena_cached.rs +++ b/compiler/rustc_middle/src/query/arena_cached.rs @@ -1,3 +1,9 @@ +use std::mem; + +use rustc_arena::TypedArena; + +use crate::ty::TyCtxt; + /// Helper trait that allows `arena_cache` queries to return `Option<&T>` /// instead of `&Option`, and avoid allocating `None` in the arena. /// @@ -11,10 +17,11 @@ pub trait ArenaCached<'tcx>: Sized { /// Type that is stored in the arena. type Allocated: 'tcx; - /// Takes a provided value, and allocates it in the arena (if appropriate) - /// with the help of the given `arena_alloc` closure. + /// Takes a provided value, and allocates it in an appropriate arena, + /// unless the particular value doesn't need allocation (e.g. `None`). fn alloc_in_arena( - arena_alloc: impl Fn(Self::Allocated) -> &'tcx Self::Allocated, + tcx: TyCtxt<'tcx>, + typed_arena: &'tcx TypedArena, value: Self::Provided, ) -> Self; } @@ -23,12 +30,9 @@ impl<'tcx, T> ArenaCached<'tcx> for &'tcx T { type Provided = T; type Allocated = T; - fn alloc_in_arena( - arena_alloc: impl Fn(Self::Allocated) -> &'tcx Self::Allocated, - value: Self::Provided, - ) -> Self { + fn alloc_in_arena(tcx: TyCtxt<'tcx>, typed_arena: &'tcx TypedArena, value: T) -> Self { // Just allocate in the arena normally. - arena_alloc(value) + do_alloc(tcx, typed_arena, value) } } @@ -38,10 +42,17 @@ impl<'tcx, T> ArenaCached<'tcx> for Option<&'tcx T> { type Allocated = T; fn alloc_in_arena( - arena_alloc: impl Fn(Self::Allocated) -> &'tcx Self::Allocated, - value: Self::Provided, + tcx: TyCtxt<'tcx>, + typed_arena: &'tcx TypedArena, + value: Option, ) -> Self { // Don't store None in the arena, and wrap the allocated reference in Some. - value.map(arena_alloc) + try { do_alloc(tcx, typed_arena, value?) } } } + +/// Allocates a value in either its dedicated arena, or in the common dropless +/// arena, depending on whether it needs to be dropped. +fn do_alloc<'tcx, T>(tcx: TyCtxt<'tcx>, typed_arena: &'tcx TypedArena, value: T) -> &'tcx T { + if mem::needs_drop::() { typed_arena.alloc(value) } else { tcx.arena.dropless.alloc(value) } +} diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 04a3ceb0918a..b80f096ec993 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -295,36 +295,28 @@ macro_rules! define_callbacks { ($V) ); - /// This function takes `ProvidedValue` and converts it to an erased `Value` by - /// allocating it on an arena if the query has the `arena_cache` modifier. The - /// value is then erased and returned. This will happen when computing the query - /// using a provider or decoding a stored result. + /// This helper function takes a value returned by the query provider + /// (or loaded from disk, or supplied by query feeding), allocates + /// it in an arena if requested by the `arena_cache` modifier, and + /// then returns an erased copy of it. #[inline(always)] pub fn provided_to_erased<'tcx>( - _tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'tcx>, provided_value: ProvidedValue<'tcx>, ) -> Erased> { - // Store the provided value in an arena and get a reference - // to it, for queries with `arena_cache`. - let value: Value<'tcx> = query_if_arena!([$($modifiers)*] - { - use $crate::query::arena_cached::ArenaCached; - - if mem::needs_drop::<<$V as ArenaCached<'tcx>>::Allocated>() { - <$V as ArenaCached>::alloc_in_arena( - |v| _tcx.query_system.arenas.$name.alloc(v), - provided_value, - ) - } else { - <$V as ArenaCached>::alloc_in_arena( - |v| _tcx.arena.dropless.alloc(v), - provided_value, - ) - } - } - // Otherwise, the provided value is the value. - (provided_value) - ); + // For queries with the `arena_cache` modifier, store the + // provided value in an arena and get a reference to it. + let value: Value<'tcx> = query_if_arena!([$($modifiers)*] { + <$V as $crate::query::arena_cached::ArenaCached>::alloc_in_arena( + tcx, + &tcx.query_system.arenas.$name, + provided_value, + ) + } { + // Otherwise, the provided value is the value (and `tcx` is unused). + let _ = tcx; + provided_value + }); erase::erase_val(value) } From b6b6dc0b8260bacc01304c230e53b4328ae4ce23 Mon Sep 17 00:00:00 2001 From: zedddie Date: Thu, 5 Feb 2026 18:54:59 +0100 Subject: [PATCH 3475/3801] mGCA: add associated const type check in dyn arm --- .../rustc_trait_selection/src/traits/wf.rs | 28 +++++++++++++++++++ .../wf-mismatch-1.rs | 12 ++++++++ .../wf-mismatch-2.rs | 12 ++++++++ .../wf-mismatch-3.rs | 15 ++++++++++ 4 files changed, 67 insertions(+) create mode 100644 tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs create mode 100644 tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs create mode 100644 tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index d383cb9d91dd..358f14221a0d 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -951,6 +951,34 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)), )); } + + if !t.has_escaping_bound_vars() { + for projection in data.projection_bounds() { + let pred_binder = projection + .with_self_ty(tcx, t) + .map_bound(|p| { + p.term.as_const().map(|ct| { + let assoc_const_ty = tcx + .type_of(p.projection_term.def_id) + .instantiate(tcx, p.projection_term.args); + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType( + ct, + assoc_const_ty, + )) + }) + }) + .transpose(); + if let Some(pred_binder) = pred_binder { + self.out.push(traits::Obligation::with_depth( + tcx, + self.cause(ObligationCauseCode::WellFormed(None)), + self.recursion_depth, + self.param_env, + pred_binder, + )); + } + } + } } // Inference variables are the complicated case, since we don't diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs new file mode 100644 index 000000000000..319e3421a4cd --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs @@ -0,0 +1,12 @@ +//@ known-bug: unknown +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { #[type_const] const CT: bool; } + +// FIXME: this should yield a type mismatch (`bool` v `i32`) +fn f(_: impl Trait) {} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs new file mode 100644 index 000000000000..2adaaa3dd050 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs @@ -0,0 +1,12 @@ +//@ known-bug: unknown +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { #[type_const] const CT: bool; } + +fn f() { + let _: dyn Trait; // FIXME: this should yield a type mismatch (`bool` v `i32`) +} +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs new file mode 100644 index 000000000000..29d089bf9d2b --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs @@ -0,0 +1,15 @@ +//@ known-bug: unknown +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { #[type_const] const CT: bool; } + +trait Bound { #[type_const] const N: u32; } +impl Bound for () { #[type_const] const N: u32 = 0; } + +fn f() { let _: dyn Trait::N }>; } // FIXME +fn g(_: impl Trait::N }>) {} // FIXME + +fn main() {} From 963f82d3224ea0b1f7b1ca182b67af3e9293e89f Mon Sep 17 00:00:00 2001 From: zedddie Date: Sat, 7 Feb 2026 07:15:24 +0100 Subject: [PATCH 3476/3801] mGCA: add associated const obligations in wfck --- .../rustc_hir_analysis/src/check/wfcheck.rs | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index ceb0e138a0da..32af13b88a1a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1569,11 +1569,40 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: let predicates = predicates.instantiate_identity(tcx); + let assoc_const_obligations: Vec<_> = predicates + .predicates + .iter() + .copied() + .zip(predicates.spans.iter().copied()) + .filter_map(|(clause, sp)| { + let proj = clause.as_projection_clause()?; + let pred_binder = proj + .map_bound(|pred| { + pred.term.as_const().map(|ct| { + let assoc_const_ty = tcx + .type_of(pred.projection_term.def_id) + .instantiate(tcx, pred.projection_term.args); + ty::ClauseKind::ConstArgHasType(ct, assoc_const_ty) + }) + }) + .transpose(); + pred_binder.map(|pred_binder| { + let cause = traits::ObligationCause::new( + sp, + wfcx.body_def_id, + ObligationCauseCode::WhereClause(def_id.to_def_id(), sp), + ); + Obligation::new(tcx, cause, wfcx.param_env, pred_binder) + }) + }) + .collect(); + assert_eq!(predicates.predicates.len(), predicates.spans.len()); let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| { traits::wf::clause_obligations(infcx, wfcx.param_env, wfcx.body_def_id, p, sp) }); - let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect(); + let obligations: Vec<_> = + wf_obligations.chain(default_obligations).chain(assoc_const_obligations).collect(); wfcx.register_obligations(obligations); } From 20f65fc537e26bd92e0da4088c27e5905c3fc52a Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 10 Feb 2026 01:31:48 +0900 Subject: [PATCH 3477/3801] Uplift `Predicate::allow_normalization` to `rustc_type_ir` --- compiler/rustc_middle/src/ty/predicate.rs | 24 +--------------------- compiler/rustc_type_ir/src/inherent.rs | 25 ++++++++++++++++++++--- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 69dcca54f469..3baeb7141de5 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -49,10 +49,6 @@ impl<'tcx> rustc_type_ir::inherent::Predicate> for Predicate<'tcx> fn as_clause(self) -> Option> { self.as_clause() } - - fn allow_normalization(self) -> bool { - self.allow_normalization() - } } impl<'tcx> rustc_type_ir::inherent::IntoKind for Predicate<'tcx> { @@ -121,25 +117,7 @@ impl<'tcx> Predicate<'tcx> { /// unsoundly accept some programs. See #91068. #[inline] pub fn allow_normalization(self) -> bool { - match self.kind().skip_binder() { - PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => { - false - } - PredicateKind::Clause(ClauseKind::Trait(_)) - | PredicateKind::Clause(ClauseKind::HostEffect(..)) - | PredicateKind::Clause(ClauseKind::RegionOutlives(_)) - | PredicateKind::Clause(ClauseKind::TypeOutlives(_)) - | PredicateKind::Clause(ClauseKind::Projection(_)) - | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) - | PredicateKind::Clause(ClauseKind::UnstableFeature(_)) - | PredicateKind::DynCompatible(_) - | PredicateKind::Subtype(_) - | PredicateKind::Coerce(_) - | PredicateKind::Clause(ClauseKind::ConstEvaluatable(_)) - | PredicateKind::ConstEquate(_, _) - | PredicateKind::NormalizesTo(..) - | PredicateKind::Ambiguous => true, - } + rustc_type_ir::inherent::Predicate::allow_normalization(self) } } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 89cb236d38c6..c9580d589d21 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -13,7 +13,7 @@ use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; use crate::solve::{AdtDestructorKind, SizedTraitKind}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; -use crate::{self as ty, CollectAndApply, Interner, UpcastFrom}; +use crate::{self as ty, ClauseKind, CollectAndApply, Interner, PredicateKind, UpcastFrom}; pub trait Ty>: Copy @@ -478,8 +478,27 @@ pub trait Predicate>: } } - // FIXME: Eventually uplift the impl out of rustc and make this defaulted. - fn allow_normalization(self) -> bool; + fn allow_normalization(self) -> bool { + match self.kind().skip_binder() { + PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => { + false + } + PredicateKind::Clause(ClauseKind::Trait(_)) + | PredicateKind::Clause(ClauseKind::HostEffect(..)) + | PredicateKind::Clause(ClauseKind::RegionOutlives(_)) + | PredicateKind::Clause(ClauseKind::TypeOutlives(_)) + | PredicateKind::Clause(ClauseKind::Projection(_)) + | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) + | PredicateKind::Clause(ClauseKind::UnstableFeature(_)) + | PredicateKind::DynCompatible(_) + | PredicateKind::Subtype(_) + | PredicateKind::Coerce(_) + | PredicateKind::Clause(ClauseKind::ConstEvaluatable(_)) + | PredicateKind::ConstEquate(_, _) + | PredicateKind::NormalizesTo(..) + | PredicateKind::Ambiguous => true, + } + } } pub trait Clause>: From ec03e39afd210cff8516b14b92dc259f61d303c5 Mon Sep 17 00:00:00 2001 From: zedddie Date: Mon, 9 Feb 2026 10:40:42 +0100 Subject: [PATCH 3478/3801] bless tests --- ...ection-behind-trait-alias-mentions-self.rs | 1 + ...on-behind-trait-alias-mentions-self.stderr | 16 +++++++++++++-- ...yn-const-projection-escaping-bound-vars.rs | 11 ++++++++++ .../wf-mismatch-1.rs | 9 ++++----- .../wf-mismatch-1.stderr | 14 +++++++++++++ .../wf-mismatch-2.rs | 9 +++++---- .../wf-mismatch-2.stderr | 8 ++++++++ .../wf-mismatch-3.rs | 16 ++++++++------- .../wf-mismatch-3.stderr | 20 +++++++++++++++++++ 9 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 tests/ui/const-generics/associated-const-bindings/dyn-const-projection-escaping-bound-vars.rs create mode 100644 tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr create mode 100644 tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr create mode 100644 tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.stderr diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs index 415d7bda347b..9564903dce5b 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs @@ -15,6 +15,7 @@ trait Trait { struct Hold(T); trait Bound = Trait }>; +//~^ ERROR the constant `Hold::` is not of type `i32` fn main() { let _: dyn Bound; //~ ERROR associated constant binding in trait object type mentions `Self` diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr index 576d4c3230ee..699b9192cf93 100644 --- a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr @@ -1,5 +1,17 @@ +error: the constant `Hold::` is not of type `i32` + --> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:17:21 + | +LL | trait Bound = Trait }>; + | ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct constructor + | +note: required by a const generic parameter in `Bound` + --> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:17:21 + | +LL | trait Bound = Trait }>; + | ^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `Bound` + error: associated constant binding in trait object type mentions `Self` - --> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:20:12 + --> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:21:12 | LL | trait Bound = Trait }>; | -------------------- this binding mentions `Self` @@ -7,5 +19,5 @@ LL | trait Bound = Trait }>; LL | let _: dyn Bound; | ^^^^^^^^^ contains a mention of `Self` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-const-projection-escaping-bound-vars.rs b/tests/ui/const-generics/associated-const-bindings/dyn-const-projection-escaping-bound-vars.rs new file mode 100644 index 000000000000..c2ae86232a02 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-const-projection-escaping-bound-vars.rs @@ -0,0 +1,11 @@ +//! Check associated const binding with escaping bound vars doesn't cause ICE +//! (#151642) +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait2<'a> { type const ASSOC: i32; } +fn g(_: for<'a> fn(Box>)) {} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs index 319e3421a4cd..1beeb07e995a 100644 --- a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs @@ -1,12 +1,11 @@ -//@ known-bug: unknown -//@ check-pass +//! Check that we correctly handle associated const bindings +//! in `impl Trait` where the RHS is a const param (#151642). #![feature(min_generic_const_args)] #![expect(incomplete_features)] -trait Trait { #[type_const] const CT: bool; } +trait Trait { type const CT: bool; } -// FIXME: this should yield a type mismatch (`bool` v `i32`) fn f(_: impl Trait) {} - +//~^ ERROR the constant `N` is not of type `bool` fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr new file mode 100644 index 000000000000..56e01e640078 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr @@ -0,0 +1,14 @@ +error: the constant `N` is not of type `bool` + --> $DIR/wf-mismatch-1.rs:9:34 + | +LL | fn f(_: impl Trait) {} + | ^^^^^^^^^^ expected `bool`, found `i32` + | +note: required by a const generic parameter in `f` + --> $DIR/wf-mismatch-1.rs:9:34 + | +LL | fn f(_: impl Trait) {} + | ^^^^^^^^^^ required by this const generic parameter in `f` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs index 2adaaa3dd050..7a75b6da78c5 100644 --- a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs @@ -1,12 +1,13 @@ -//@ known-bug: unknown -//@ check-pass +//! Check that we correctly handle associated const bindings +//! in `dyn Trait` where the RHS is a const param (#151642). #![feature(min_generic_const_args)] #![expect(incomplete_features)] -trait Trait { #[type_const] const CT: bool; } +trait Trait { type const CT: bool; } fn f() { - let _: dyn Trait; // FIXME: this should yield a type mismatch (`bool` v `i32`) + let _: dyn Trait; + //~^ ERROR the constant `N` is not of type `bool` } fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr new file mode 100644 index 000000000000..8169cc07fc5f --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr @@ -0,0 +1,8 @@ +error: the constant `N` is not of type `bool` + --> $DIR/wf-mismatch-2.rs:10:12 + | +LL | let _: dyn Trait; + | ^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs index 29d089bf9d2b..3eeb7703aa2b 100644 --- a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs @@ -1,15 +1,17 @@ -//@ known-bug: unknown -//@ check-pass +//! Check that we correctly handle associated const bindings +//! where the RHS is a normalizable const projection (#151642). #![feature(min_generic_const_args)] #![expect(incomplete_features)] -trait Trait { #[type_const] const CT: bool; } +trait Trait { type const CT: bool; } -trait Bound { #[type_const] const N: u32; } -impl Bound for () { #[type_const] const N: u32 = 0; } +trait Bound { type const N: u32; } +impl Bound for () { type const N: u32 = 0; } -fn f() { let _: dyn Trait::N }>; } // FIXME -fn g(_: impl Trait::N }>) {} // FIXME +fn f() { let _: dyn Trait::N }>; } +//~^ ERROR the constant `0` is not of type `bool` +fn g(_: impl Trait::N }>) {} +//~^ ERROR the constant `0` is not of type `bool` fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.stderr new file mode 100644 index 000000000000..ac21527e04ed --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.stderr @@ -0,0 +1,20 @@ +error: the constant `0` is not of type `bool` + --> $DIR/wf-mismatch-3.rs:14:20 + | +LL | fn g(_: impl Trait::N }>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `u32` + | +note: required by a const generic parameter in `g` + --> $DIR/wf-mismatch-3.rs:14:20 + | +LL | fn g(_: impl Trait::N }>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `g` + +error: the constant `0` is not of type `bool` + --> $DIR/wf-mismatch-3.rs:12:17 + | +LL | fn f() { let _: dyn Trait::N }>; } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `u32` + +error: aborting due to 2 previous errors + From 066a935b0c25608db20da43951def47f3b1539e6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Feb 2026 10:17:13 +1100 Subject: [PATCH 3479/3801] Move parts of `rustc_query_system::query::job` to `rustc_middle::job`. The latter is a new module. As well as the code motion, some other changes were required. - `QueryJobId` methods became free functions so they could move while `QueryJobId` itself stayed put. This was so `QueryMap` and `QueryJobInfo` could be moved. - Some visibilities in `rustc_query_system` required changing. - `collect_active_jobs_from_all_queries` is no longer required in `trait QueryContext`. --- Cargo.lock | 1 + compiler/rustc_interface/src/interface.rs | 3 +- compiler/rustc_interface/src/util.rs | 3 +- compiler/rustc_query_impl/Cargo.toml | 1 + compiler/rustc_query_impl/src/execution.rs | 9 +- compiler/rustc_query_impl/src/job.rs | 446 ++++++++++++++++++ compiler/rustc_query_impl/src/lib.rs | 4 +- compiler/rustc_query_impl/src/plumbing.rs | 59 +-- compiler/rustc_query_system/src/query/job.rs | 460 +------------------ compiler/rustc_query_system/src/query/mod.rs | 12 +- 10 files changed, 504 insertions(+), 494 deletions(-) create mode 100644 compiler/rustc_query_impl/src/job.rs diff --git a/Cargo.lock b/Cargo.lock index 545c776b4805..7230d633602d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4503,6 +4503,7 @@ dependencies = [ "rustc_query_system", "rustc_serialize", "rustc_span", + "rustc_thread_pool", "tracing", ] diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 72080c5f5369..6cbc184e8f1b 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -16,8 +16,7 @@ use rustc_parse::lexer::StripTokens; use rustc_parse::new_parser_from_source_str; use rustc_parse::parser::Recovery; use rustc_parse::parser::attr::AllowLeadingUnsafe; -use rustc_query_impl::QueryCtxt; -use rustc_query_system::query::print_query_stack; +use rustc_query_impl::{QueryCtxt, print_query_stack}; use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName}; use rustc_session::parse::ParseSess; use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint}; diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 458e7ad32143..59f0b67d6729 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -184,8 +184,7 @@ pub(crate) fn run_in_thread_pool_with_globals< use rustc_data_structures::defer; use rustc_data_structures::sync::FromDyn; use rustc_middle::ty::tls; - use rustc_query_impl::QueryCtxt; - use rustc_query_system::query::{QueryContext, break_query_cycles}; + use rustc_query_impl::{QueryCtxt, break_query_cycles}; let thread_stack_size = init_stack_size(thread_builder_diag); diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index d611629671a0..511337090d7f 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -16,5 +16,6 @@ rustc_middle = { path = "../rustc_middle" } rustc_query_system = { path = "../rustc_query_system" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } +rustc_thread_pool = { path = "../rustc_thread_pool" } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 88604c91d025..6f16932cb2eb 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -9,13 +9,14 @@ use rustc_middle::dep_graph::DepsType; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::{DepGraphData, DepNodeKey, HasDepContext}; use rustc_query_system::query::{ - ActiveKeyStatus, CycleError, CycleErrorHandling, QueryCache, QueryContext, QueryJob, - QueryJobId, QueryJobInfo, QueryLatch, QueryMap, QueryMode, QueryStackDeferred, QueryStackFrame, - QueryState, incremental_verify_ich, report_cycle, + ActiveKeyStatus, CycleError, CycleErrorHandling, QueryCache, QueryJob, QueryJobId, QueryLatch, + QueryMode, QueryStackDeferred, QueryStackFrame, QueryState, incremental_verify_ich, + report_cycle, }; use rustc_span::{DUMMY_SP, Span}; use crate::dep_graph::{DepContext, DepNode, DepNodeIndex}; +use crate::job::{QueryJobInfo, QueryMap, find_cycle_in_stack}; use crate::{QueryCtxt, QueryFlags, SemiDynamicQueryDispatcher}; #[inline] @@ -218,7 +219,7 @@ fn cycle_error<'tcx, C: QueryCache, const FLAGS: QueryFlags>( .ok() .expect("failed to collect active queries"); - let error = try_execute.find_cycle_in_stack(query_map, &qcx.current_query_job(), span); + let error = find_cycle_in_stack(try_execute, query_map, &qcx.current_query_job(), span); (mk_cycle(query, qcx, error.lift()), None) } diff --git a/compiler/rustc_query_impl/src/job.rs b/compiler/rustc_query_impl/src/job.rs new file mode 100644 index 000000000000..cb0a13d32ad2 --- /dev/null +++ b/compiler/rustc_query_impl/src/job.rs @@ -0,0 +1,446 @@ +use std::io::Write; +use std::iter; +use std::sync::Arc; + +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::DiagCtxtHandle; +use rustc_query_system::query::{ + CycleError, QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryStackDeferred, QueryStackFrame, + QueryWaiter, +}; +use rustc_span::{DUMMY_SP, Span}; + +use crate::QueryCtxt; +use crate::dep_graph::DepContext; + +/// Map from query job IDs to job information collected by +/// `collect_active_jobs_from_all_queries`. +pub type QueryMap<'tcx> = FxHashMap>; + +fn query_job_id_frame<'a, 'tcx>( + id: QueryJobId, + map: &'a QueryMap<'tcx>, +) -> QueryStackFrame> { + map.get(&id).unwrap().frame.clone() +} + +fn query_job_id_span<'a, 'tcx>(id: QueryJobId, map: &'a QueryMap<'tcx>) -> Span { + map.get(&id).unwrap().job.span +} + +fn query_job_id_parent<'a, 'tcx>(id: QueryJobId, map: &'a QueryMap<'tcx>) -> Option { + map.get(&id).unwrap().job.parent +} + +fn query_job_id_latch<'a, 'tcx>( + id: QueryJobId, + map: &'a QueryMap<'tcx>, +) -> Option<&'a QueryLatch<'tcx>> { + map.get(&id).unwrap().job.latch.as_ref() +} + +#[derive(Clone, Debug)] +pub struct QueryJobInfo<'tcx> { + pub frame: QueryStackFrame>, + pub job: QueryJob<'tcx>, +} + +pub(crate) fn find_cycle_in_stack<'tcx>( + id: QueryJobId, + query_map: QueryMap<'tcx>, + current_job: &Option, + span: Span, +) -> CycleError> { + // Find the waitee amongst `current_job` parents + let mut cycle = Vec::new(); + let mut current_job = Option::clone(current_job); + + while let Some(job) = current_job { + let info = query_map.get(&job).unwrap(); + cycle.push(QueryInfo { span: info.job.span, frame: info.frame.clone() }); + + if job == id { + cycle.reverse(); + + // This is the end of the cycle + // The span entry we included was for the usage + // of the cycle itself, and not part of the cycle + // Replace it with the span which caused the cycle to form + cycle[0].span = span; + // Find out why the cycle itself was used + let usage = info + .job + .parent + .as_ref() + .map(|parent| (info.job.span, query_job_id_frame(*parent, &query_map))); + return CycleError { usage, cycle }; + } + + current_job = info.job.parent; + } + + panic!("did not find a cycle") +} + +#[cold] +#[inline(never)] +pub(crate) fn find_dep_kind_root<'tcx>( + id: QueryJobId, + query_map: QueryMap<'tcx>, +) -> (QueryJobInfo<'tcx>, usize) { + let mut depth = 1; + let info = query_map.get(&id).unwrap(); + let dep_kind = info.frame.dep_kind; + let mut current_id = info.job.parent; + let mut last_layout = (info.clone(), depth); + + while let Some(id) = current_id { + let info = query_map.get(&id).unwrap(); + if info.frame.dep_kind == dep_kind { + depth += 1; + last_layout = (info.clone(), depth); + } + current_id = info.job.parent; + } + last_layout +} + +/// A resumable waiter of a query. The usize is the index into waiters in the query's latch +type Waiter = (QueryJobId, usize); + +/// Visits all the non-resumable and resumable waiters of a query. +/// Only waiters in a query are visited. +/// `visit` is called for every waiter and is passed a query waiting on `query_ref` +/// and a span indicating the reason the query waited on `query_ref`. +/// If `visit` returns Some, this function returns. +/// For visits of non-resumable waiters it returns the return value of `visit`. +/// For visits of resumable waiters it returns Some(Some(Waiter)) which has the +/// required information to resume the waiter. +/// If all `visit` calls returns None, this function also returns None. +fn visit_waiters<'tcx, F>( + query_map: &QueryMap<'tcx>, + query: QueryJobId, + mut visit: F, +) -> Option> +where + F: FnMut(Span, QueryJobId) -> Option>, +{ + // Visit the parent query which is a non-resumable waiter since it's on the same stack + if let Some(parent) = query_job_id_parent(query, query_map) + && let Some(cycle) = visit(query_job_id_span(query, query_map), parent) + { + return Some(cycle); + } + + // Visit the explicit waiters which use condvars and are resumable + if let Some(latch) = query_job_id_latch(query, query_map) { + for (i, waiter) in latch.info.lock().waiters.iter().enumerate() { + if let Some(waiter_query) = waiter.query { + if visit(waiter.span, waiter_query).is_some() { + // Return a value which indicates that this waiter can be resumed + return Some(Some((query, i))); + } + } + } + } + + None +} + +/// Look for query cycles by doing a depth first search starting at `query`. +/// `span` is the reason for the `query` to execute. This is initially DUMMY_SP. +/// If a cycle is detected, this initial value is replaced with the span causing +/// the cycle. +fn cycle_check<'tcx>( + query_map: &QueryMap<'tcx>, + query: QueryJobId, + span: Span, + stack: &mut Vec<(Span, QueryJobId)>, + visited: &mut FxHashSet, +) -> Option> { + if !visited.insert(query) { + return if let Some(p) = stack.iter().position(|q| q.1 == query) { + // We detected a query cycle, fix up the initial span and return Some + + // Remove previous stack entries + stack.drain(0..p); + // Replace the span for the first query with the cycle cause + stack[0].0 = span; + Some(None) + } else { + None + }; + } + + // Query marked as visited is added it to the stack + stack.push((span, query)); + + // Visit all the waiters + let r = visit_waiters(query_map, query, |span, successor| { + cycle_check(query_map, successor, span, stack, visited) + }); + + // Remove the entry in our stack if we didn't find a cycle + if r.is_none() { + stack.pop(); + } + + r +} + +/// Finds out if there's a path to the compiler root (aka. code which isn't in a query) +/// from `query` without going through any of the queries in `visited`. +/// This is achieved with a depth first search. +fn connected_to_root<'tcx>( + query_map: &QueryMap<'tcx>, + query: QueryJobId, + visited: &mut FxHashSet, +) -> bool { + // We already visited this or we're deliberately ignoring it + if !visited.insert(query) { + return false; + } + + // This query is connected to the root (it has no query parent), return true + if query_job_id_parent(query, query_map).is_none() { + return true; + } + + visit_waiters(query_map, query, |_, successor| { + connected_to_root(query_map, successor, visited).then_some(None) + }) + .is_some() +} + +// Deterministically pick an query from a list +fn pick_query<'a, 'tcx, T, F>(query_map: &QueryMap<'tcx>, queries: &'a [T], f: F) -> &'a T +where + F: Fn(&T) -> (Span, QueryJobId), +{ + // Deterministically pick an entry point + // FIXME: Sort this instead + queries + .iter() + .min_by_key(|v| { + let (span, query) = f(v); + let hash = query_job_id_frame(query, query_map).hash; + // Prefer entry points which have valid spans for nicer error messages + // We add an integer to the tuple ensuring that entry points + // with valid spans are picked first + let span_cmp = if span == DUMMY_SP { 1 } else { 0 }; + (span_cmp, hash) + }) + .unwrap() +} + +/// Looks for query cycles starting from the last query in `jobs`. +/// If a cycle is found, all queries in the cycle is removed from `jobs` and +/// the function return true. +/// If a cycle was not found, the starting query is removed from `jobs` and +/// the function returns false. +fn remove_cycle<'tcx>( + query_map: &QueryMap<'tcx>, + jobs: &mut Vec, + wakelist: &mut Vec>>, +) -> bool { + let mut visited = FxHashSet::default(); + let mut stack = Vec::new(); + // Look for a cycle starting with the last query in `jobs` + if let Some(waiter) = + cycle_check(query_map, jobs.pop().unwrap(), DUMMY_SP, &mut stack, &mut visited) + { + // The stack is a vector of pairs of spans and queries; reverse it so that + // the earlier entries require later entries + let (mut spans, queries): (Vec<_>, Vec<_>) = stack.into_iter().rev().unzip(); + + // Shift the spans so that queries are matched with the span for their waitee + spans.rotate_right(1); + + // Zip them back together + let mut stack: Vec<_> = iter::zip(spans, queries).collect(); + + // Remove the queries in our cycle from the list of jobs to look at + for r in &stack { + if let Some(pos) = jobs.iter().position(|j| j == &r.1) { + jobs.remove(pos); + } + } + + // Find the queries in the cycle which are + // connected to queries outside the cycle + let entry_points = stack + .iter() + .filter_map(|&(span, query)| { + if query_job_id_parent(query, query_map).is_none() { + // This query is connected to the root (it has no query parent) + Some((span, query, None)) + } else { + let mut waiters = Vec::new(); + // Find all the direct waiters who lead to the root + visit_waiters(query_map, query, |span, waiter| { + // Mark all the other queries in the cycle as already visited + let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1)); + + if connected_to_root(query_map, waiter, &mut visited) { + waiters.push((span, waiter)); + } + + None + }); + if waiters.is_empty() { + None + } else { + // Deterministically pick one of the waiters to show to the user + let waiter = *pick_query(query_map, &waiters, |s| *s); + Some((span, query, Some(waiter))) + } + } + }) + .collect::)>>(); + + // Deterministically pick an entry point + let (_, entry_point, usage) = pick_query(query_map, &entry_points, |e| (e.0, e.1)); + + // Shift the stack so that our entry point is first + let entry_point_pos = stack.iter().position(|(_, query)| query == entry_point); + if let Some(pos) = entry_point_pos { + stack.rotate_left(pos); + } + + let usage = + usage.as_ref().map(|(span, query)| (*span, query_job_id_frame(*query, query_map))); + + // Create the cycle error + let error = CycleError { + usage, + cycle: stack + .iter() + .map(|&(s, ref q)| QueryInfo { span: s, frame: query_job_id_frame(*q, query_map) }) + .collect(), + }; + + // We unwrap `waiter` here since there must always be one + // edge which is resumable / waited using a query latch + let (waitee_query, waiter_idx) = waiter.unwrap(); + + // Extract the waiter we want to resume + let waiter = + query_job_id_latch(waitee_query, query_map).unwrap().extract_waiter(waiter_idx); + + // Set the cycle error so it will be picked up when resumed + *waiter.cycle.lock() = Some(error); + + // Put the waiter on the list of things to resume + wakelist.push(waiter); + + true + } else { + false + } +} + +/// Detects query cycles by using depth first search over all active query jobs. +/// If a query cycle is found it will break the cycle by finding an edge which +/// uses a query latch and then resuming that waiter. +/// There may be multiple cycles involved in a deadlock, so this searches +/// all active queries for cycles before finally resuming all the waiters at once. +pub fn break_query_cycles<'tcx>(query_map: QueryMap<'tcx>, registry: &rustc_thread_pool::Registry) { + let mut wakelist = Vec::new(); + // It is OK per the comments: + // - https://github.com/rust-lang/rust/pull/131200#issuecomment-2798854932 + // - https://github.com/rust-lang/rust/pull/131200#issuecomment-2798866392 + #[allow(rustc::potential_query_instability)] + let mut jobs: Vec = query_map.keys().cloned().collect(); + + let mut found_cycle = false; + + while jobs.len() > 0 { + if remove_cycle(&query_map, &mut jobs, &mut wakelist) { + found_cycle = true; + } + } + + // Check that a cycle was found. It is possible for a deadlock to occur without + // a query cycle if a query which can be waited on uses Rayon to do multithreading + // internally. Such a query (X) may be executing on 2 threads (A and B) and A may + // wait using Rayon on B. Rayon may then switch to executing another query (Y) + // which in turn will wait on X causing a deadlock. We have a false dependency from + // X to Y due to Rayon waiting and a true dependency from Y to X. The algorithm here + // only considers the true dependency and won't detect a cycle. + if !found_cycle { + panic!( + "deadlock detected as we're unable to find a query cycle to break\n\ + current query map:\n{:#?}", + query_map + ); + } + + // Mark all the thread we're about to wake up as unblocked. This needs to be done before + // we wake the threads up as otherwise Rayon could detect a deadlock if a thread we + // resumed fell asleep and this thread had yet to mark the remaining threads as unblocked. + for _ in 0..wakelist.len() { + rustc_thread_pool::mark_unblocked(registry); + } + + for waiter in wakelist.into_iter() { + waiter.condvar.notify_one(); + } +} + +pub fn print_query_stack<'tcx>( + qcx: QueryCtxt<'tcx>, + mut current_query: Option, + dcx: DiagCtxtHandle<'_>, + limit_frames: Option, + mut file: Option, +) -> usize { + // Be careful relying on global state here: this code is called from + // a panic hook, which means that the global `DiagCtxt` may be in a weird + // state if it was responsible for triggering the panic. + let mut count_printed = 0; + let mut count_total = 0; + + // Make use of a partial query map if we fail to take locks collecting active queries. + let query_map = match qcx.collect_active_jobs_from_all_queries(false) { + Ok(query_map) => query_map, + Err(query_map) => query_map, + }; + + if let Some(ref mut file) = file { + let _ = writeln!(file, "\n\nquery stack during panic:"); + } + while let Some(query) = current_query { + let Some(query_info) = query_map.get(&query) else { + break; + }; + let query_extra = query_info.frame.info.extract(); + if Some(count_printed) < limit_frames || limit_frames.is_none() { + // Only print to stderr as many stack frames as `num_frames` when present. + dcx.struct_failure_note(format!( + "#{} [{:?}] {}", + count_printed, query_info.frame.dep_kind, query_extra.description + )) + .with_span(query_info.job.span) + .emit(); + count_printed += 1; + } + + if let Some(ref mut file) = file { + let _ = writeln!( + file, + "#{} [{}] {}", + count_total, + qcx.tcx.dep_kind_vtable(query_info.frame.dep_kind).name, + query_extra.description + ); + } + + current_query = query_info.job.parent; + count_total += 1; + } + + if let Some(ref mut file) = file { + let _ = writeln!(file, "end of query stack"); + } + count_total +} diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index a33bdd22a797..c1ead8da344b 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -23,10 +23,11 @@ use rustc_middle::query::values::Value; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::query::{ - CycleError, CycleErrorHandling, QueryCache, QueryMap, QueryMode, QueryState, + CycleError, CycleErrorHandling, QueryCache, QueryMode, QueryState, }; use rustc_span::{ErrorGuaranteed, Span}; +pub use crate::job::{QueryMap, break_query_cycles, print_query_stack}; pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all}; use crate::plumbing::{encode_all_query_results, try_mark_green}; use crate::profiling_support::QueryKeyStringCache; @@ -34,6 +35,7 @@ pub use crate::profiling_support::alloc_self_profile_query_strings; mod error; mod execution; +mod job; #[macro_use] mod plumbing; mod profiling_support; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 776d720f500b..5fba9dd4a68a 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -28,14 +28,15 @@ use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle, HasDepContext}; use rustc_query_system::query::{ - QueryCache, QueryContext, QueryJobId, QueryMap, QuerySideEffect, QueryStackDeferred, - QueryStackFrame, QueryStackFrameExtra, + QueryCache, QueryContext, QueryJobId, QuerySideEffect, QueryStackDeferred, QueryStackFrame, + QueryStackFrameExtra, }; use rustc_serialize::{Decodable, Encodable}; use rustc_span::def_id::LOCAL_CRATE; use crate::error::{QueryOverflow, QueryOverflowNote}; use crate::execution::{all_inactive, force_query}; +use crate::job::{QueryMap, find_dep_kind_root}; use crate::{QueryDispatcherUnerased, QueryFlags, SemiDynamicQueryDispatcher}; /// Implements [`QueryContext`] for use by [`rustc_query_system`], since that @@ -55,7 +56,7 @@ impl<'tcx> QueryCtxt<'tcx> { let query_map = self .collect_active_jobs_from_all_queries(true) .expect("failed to collect active queries"); - let (info, depth) = job.find_dep_kind_root(query_map); + let (info, depth) = find_dep_kind_root(job, query_map); let suggested_limit = match self.tcx.recursion_limit() { Limit(0) => Limit(2), @@ -116,6 +117,32 @@ impl<'tcx> QueryCtxt<'tcx> { tls::enter_context(&new_icx, compute) }) } + + /// Returns a map of currently active query jobs, collected from all queries. + /// + /// If `require_complete` is `true`, this function locks all shards of the + /// query results to produce a complete map, which always returns `Ok`. + /// Otherwise, it may return an incomplete map as an error if any shard + /// lock cannot be acquired. + /// + /// Prefer passing `false` to `require_complete` to avoid potential deadlocks, + /// especially when called from within a deadlock handler, unless a + /// complete map is needed and no deadlock is possible at this call site. + pub fn collect_active_jobs_from_all_queries( + self, + require_complete: bool, + ) -> Result, QueryMap<'tcx>> { + let mut jobs = QueryMap::default(); + let mut complete = true; + + for gather_fn in crate::PER_QUERY_GATHER_ACTIVE_JOBS_FNS.iter() { + if gather_fn(self.tcx, &mut jobs, require_complete).is_none() { + complete = false; + } + } + + if complete { Ok(jobs) } else { Err(jobs) } + } } impl<'tcx> HasDepContext for QueryCtxt<'tcx> { @@ -134,32 +161,6 @@ impl<'tcx> QueryContext<'tcx> for QueryCtxt<'tcx> { &self.tcx.jobserver_proxy } - /// Returns a map of currently active query jobs, collected from all queries. - /// - /// If `require_complete` is `true`, this function locks all shards of the - /// query results to produce a complete map, which always returns `Ok`. - /// Otherwise, it may return an incomplete map as an error if any shard - /// lock cannot be acquired. - /// - /// Prefer passing `false` to `require_complete` to avoid potential deadlocks, - /// especially when called from within a deadlock handler, unless a - /// complete map is needed and no deadlock is possible at this call site. - fn collect_active_jobs_from_all_queries( - self, - require_complete: bool, - ) -> Result, QueryMap<'tcx>> { - let mut jobs = QueryMap::default(); - let mut complete = true; - - for gather_fn in crate::PER_QUERY_GATHER_ACTIVE_JOBS_FNS.iter() { - if gather_fn(self.tcx, &mut jobs, require_complete).is_none() { - complete = false; - } - } - - if complete { Ok(jobs) } else { Err(jobs) } - } - // Interactions with on_disk_cache fn load_side_effect( self, diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index c77ae38ba96f..e8acb8064f7e 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -1,19 +1,15 @@ use std::fmt::Debug; use std::hash::Hash; -use std::io::Write; -use std::iter; use std::num::NonZero; use std::sync::Arc; use parking_lot::{Condvar, Mutex}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{Diag, DiagCtxtHandle}; +use rustc_errors::Diag; use rustc_hir::def::DefKind; use rustc_session::Session; -use rustc_span::{DUMMY_SP, Span}; +use rustc_span::Span; use super::{QueryStackDeferred, QueryStackFrameExtra}; -use crate::dep_graph::DepContext; use crate::error::CycleStack; use crate::query::plumbing::CycleError; use crate::query::{QueryContext, QueryStackFrame}; @@ -32,38 +28,10 @@ impl<'tcx> QueryInfo> { } } -/// Map from query job IDs to job information collected by -/// [`QueryContext::collect_active_jobs_from_all_queries`]. -pub type QueryMap<'tcx> = FxHashMap>; - /// A value uniquely identifying an active query job. #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct QueryJobId(pub NonZero); -impl QueryJobId { - fn frame<'a, 'tcx>(self, map: &'a QueryMap<'tcx>) -> QueryStackFrame> { - map.get(&self).unwrap().frame.clone() - } - - fn span<'a, 'tcx>(self, map: &'a QueryMap<'tcx>) -> Span { - map.get(&self).unwrap().job.span - } - - fn parent<'a, 'tcx>(self, map: &'a QueryMap<'tcx>) -> Option { - map.get(&self).unwrap().job.parent - } - - fn latch<'a, 'tcx>(self, map: &'a QueryMap<'tcx>) -> Option<&'a QueryLatch<'tcx>> { - map.get(&self).unwrap().job.latch.as_ref() - } -} - -#[derive(Clone, Debug)] -pub struct QueryJobInfo<'tcx> { - pub frame: QueryStackFrame>, - pub job: QueryJob<'tcx>, -} - /// Represents an active query job. #[derive(Clone, Debug)] pub struct QueryJob<'tcx> { @@ -76,7 +44,7 @@ pub struct QueryJob<'tcx> { pub parent: Option, /// The latch that is used to wait on this job. - latch: Option>, + pub latch: Option>, } impl<'tcx> QueryJob<'tcx> { @@ -105,85 +73,23 @@ impl<'tcx> QueryJob<'tcx> { } } -impl QueryJobId { - pub fn find_cycle_in_stack<'tcx>( - &self, - query_map: QueryMap<'tcx>, - current_job: &Option, - span: Span, - ) -> CycleError> { - // Find the waitee amongst `current_job` parents - let mut cycle = Vec::new(); - let mut current_job = Option::clone(current_job); - - while let Some(job) = current_job { - let info = query_map.get(&job).unwrap(); - cycle.push(QueryInfo { span: info.job.span, frame: info.frame.clone() }); - - if job == *self { - cycle.reverse(); - - // This is the end of the cycle - // The span entry we included was for the usage - // of the cycle itself, and not part of the cycle - // Replace it with the span which caused the cycle to form - cycle[0].span = span; - // Find out why the cycle itself was used - let usage = info - .job - .parent - .as_ref() - .map(|parent| (info.job.span, parent.frame(&query_map))); - return CycleError { usage, cycle }; - } - - current_job = info.job.parent; - } - - panic!("did not find a cycle") - } - - #[cold] - #[inline(never)] - pub fn find_dep_kind_root<'tcx>( - &self, - query_map: QueryMap<'tcx>, - ) -> (QueryJobInfo<'tcx>, usize) { - let mut depth = 1; - let info = query_map.get(&self).unwrap(); - let dep_kind = info.frame.dep_kind; - let mut current_id = info.job.parent; - let mut last_layout = (info.clone(), depth); - - while let Some(id) = current_id { - let info = query_map.get(&id).unwrap(); - if info.frame.dep_kind == dep_kind { - depth += 1; - last_layout = (info.clone(), depth); - } - current_id = info.job.parent; - } - last_layout - } +#[derive(Debug)] +pub struct QueryWaiter<'tcx> { + pub query: Option, + pub condvar: Condvar, + pub span: Span, + pub cycle: Mutex>>>, } #[derive(Debug)] -struct QueryWaiter<'tcx> { - query: Option, - condvar: Condvar, - span: Span, - cycle: Mutex>>>, -} - -#[derive(Debug)] -struct QueryLatchInfo<'tcx> { - complete: bool, - waiters: Vec>>, +pub struct QueryLatchInfo<'tcx> { + pub complete: bool, + pub waiters: Vec>>, } #[derive(Clone, Debug)] pub struct QueryLatch<'tcx> { - info: Arc>>, + pub info: Arc>>, } impl<'tcx> QueryLatch<'tcx> { @@ -250,7 +156,7 @@ impl<'tcx> QueryLatch<'tcx> { /// Removes a single waiter from the list of waiters. /// This is used to break query cycles. - fn extract_waiter(&self, waiter: usize) -> Arc> { + pub fn extract_waiter(&self, waiter: usize) -> Arc> { let mut info = self.info.lock(); debug_assert!(!info.complete); // Remove the waiter from the list of waiters @@ -258,286 +164,6 @@ impl<'tcx> QueryLatch<'tcx> { } } -/// A resumable waiter of a query. The usize is the index into waiters in the query's latch -type Waiter = (QueryJobId, usize); - -/// Visits all the non-resumable and resumable waiters of a query. -/// Only waiters in a query are visited. -/// `visit` is called for every waiter and is passed a query waiting on `query_ref` -/// and a span indicating the reason the query waited on `query_ref`. -/// If `visit` returns Some, this function returns. -/// For visits of non-resumable waiters it returns the return value of `visit`. -/// For visits of resumable waiters it returns Some(Some(Waiter)) which has the -/// required information to resume the waiter. -/// If all `visit` calls returns None, this function also returns None. -fn visit_waiters<'tcx, F>( - query_map: &QueryMap<'tcx>, - query: QueryJobId, - mut visit: F, -) -> Option> -where - F: FnMut(Span, QueryJobId) -> Option>, -{ - // Visit the parent query which is a non-resumable waiter since it's on the same stack - if let Some(parent) = query.parent(query_map) - && let Some(cycle) = visit(query.span(query_map), parent) - { - return Some(cycle); - } - - // Visit the explicit waiters which use condvars and are resumable - if let Some(latch) = query.latch(query_map) { - for (i, waiter) in latch.info.lock().waiters.iter().enumerate() { - if let Some(waiter_query) = waiter.query { - if visit(waiter.span, waiter_query).is_some() { - // Return a value which indicates that this waiter can be resumed - return Some(Some((query, i))); - } - } - } - } - - None -} - -/// Look for query cycles by doing a depth first search starting at `query`. -/// `span` is the reason for the `query` to execute. This is initially DUMMY_SP. -/// If a cycle is detected, this initial value is replaced with the span causing -/// the cycle. -fn cycle_check<'tcx>( - query_map: &QueryMap<'tcx>, - query: QueryJobId, - span: Span, - stack: &mut Vec<(Span, QueryJobId)>, - visited: &mut FxHashSet, -) -> Option> { - if !visited.insert(query) { - return if let Some(p) = stack.iter().position(|q| q.1 == query) { - // We detected a query cycle, fix up the initial span and return Some - - // Remove previous stack entries - stack.drain(0..p); - // Replace the span for the first query with the cycle cause - stack[0].0 = span; - Some(None) - } else { - None - }; - } - - // Query marked as visited is added it to the stack - stack.push((span, query)); - - // Visit all the waiters - let r = visit_waiters(query_map, query, |span, successor| { - cycle_check(query_map, successor, span, stack, visited) - }); - - // Remove the entry in our stack if we didn't find a cycle - if r.is_none() { - stack.pop(); - } - - r -} - -/// Finds out if there's a path to the compiler root (aka. code which isn't in a query) -/// from `query` without going through any of the queries in `visited`. -/// This is achieved with a depth first search. -fn connected_to_root<'tcx>( - query_map: &QueryMap<'tcx>, - query: QueryJobId, - visited: &mut FxHashSet, -) -> bool { - // We already visited this or we're deliberately ignoring it - if !visited.insert(query) { - return false; - } - - // This query is connected to the root (it has no query parent), return true - if query.parent(query_map).is_none() { - return true; - } - - visit_waiters(query_map, query, |_, successor| { - connected_to_root(query_map, successor, visited).then_some(None) - }) - .is_some() -} - -// Deterministically pick an query from a list -fn pick_query<'a, 'tcx, T, F>(query_map: &QueryMap<'tcx>, queries: &'a [T], f: F) -> &'a T -where - F: Fn(&T) -> (Span, QueryJobId), -{ - // Deterministically pick an entry point - // FIXME: Sort this instead - queries - .iter() - .min_by_key(|v| { - let (span, query) = f(v); - let hash = query.frame(query_map).hash; - // Prefer entry points which have valid spans for nicer error messages - // We add an integer to the tuple ensuring that entry points - // with valid spans are picked first - let span_cmp = if span == DUMMY_SP { 1 } else { 0 }; - (span_cmp, hash) - }) - .unwrap() -} - -/// Looks for query cycles starting from the last query in `jobs`. -/// If a cycle is found, all queries in the cycle is removed from `jobs` and -/// the function return true. -/// If a cycle was not found, the starting query is removed from `jobs` and -/// the function returns false. -fn remove_cycle<'tcx>( - query_map: &QueryMap<'tcx>, - jobs: &mut Vec, - wakelist: &mut Vec>>, -) -> bool { - let mut visited = FxHashSet::default(); - let mut stack = Vec::new(); - // Look for a cycle starting with the last query in `jobs` - if let Some(waiter) = - cycle_check(query_map, jobs.pop().unwrap(), DUMMY_SP, &mut stack, &mut visited) - { - // The stack is a vector of pairs of spans and queries; reverse it so that - // the earlier entries require later entries - let (mut spans, queries): (Vec<_>, Vec<_>) = stack.into_iter().rev().unzip(); - - // Shift the spans so that queries are matched with the span for their waitee - spans.rotate_right(1); - - // Zip them back together - let mut stack: Vec<_> = iter::zip(spans, queries).collect(); - - // Remove the queries in our cycle from the list of jobs to look at - for r in &stack { - if let Some(pos) = jobs.iter().position(|j| j == &r.1) { - jobs.remove(pos); - } - } - - // Find the queries in the cycle which are - // connected to queries outside the cycle - let entry_points = stack - .iter() - .filter_map(|&(span, query)| { - if query.parent(query_map).is_none() { - // This query is connected to the root (it has no query parent) - Some((span, query, None)) - } else { - let mut waiters = Vec::new(); - // Find all the direct waiters who lead to the root - visit_waiters(query_map, query, |span, waiter| { - // Mark all the other queries in the cycle as already visited - let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1)); - - if connected_to_root(query_map, waiter, &mut visited) { - waiters.push((span, waiter)); - } - - None - }); - if waiters.is_empty() { - None - } else { - // Deterministically pick one of the waiters to show to the user - let waiter = *pick_query(query_map, &waiters, |s| *s); - Some((span, query, Some(waiter))) - } - } - }) - .collect::)>>(); - - // Deterministically pick an entry point - let (_, entry_point, usage) = pick_query(query_map, &entry_points, |e| (e.0, e.1)); - - // Shift the stack so that our entry point is first - let entry_point_pos = stack.iter().position(|(_, query)| query == entry_point); - if let Some(pos) = entry_point_pos { - stack.rotate_left(pos); - } - - let usage = usage.as_ref().map(|(span, query)| (*span, query.frame(query_map))); - - // Create the cycle error - let error = CycleError { - usage, - cycle: stack - .iter() - .map(|&(s, ref q)| QueryInfo { span: s, frame: q.frame(query_map) }) - .collect(), - }; - - // We unwrap `waiter` here since there must always be one - // edge which is resumable / waited using a query latch - let (waitee_query, waiter_idx) = waiter.unwrap(); - - // Extract the waiter we want to resume - let waiter = waitee_query.latch(query_map).unwrap().extract_waiter(waiter_idx); - - // Set the cycle error so it will be picked up when resumed - *waiter.cycle.lock() = Some(error); - - // Put the waiter on the list of things to resume - wakelist.push(waiter); - - true - } else { - false - } -} - -/// Detects query cycles by using depth first search over all active query jobs. -/// If a query cycle is found it will break the cycle by finding an edge which -/// uses a query latch and then resuming that waiter. -/// There may be multiple cycles involved in a deadlock, so this searches -/// all active queries for cycles before finally resuming all the waiters at once. -pub fn break_query_cycles<'tcx>(query_map: QueryMap<'tcx>, registry: &rustc_thread_pool::Registry) { - let mut wakelist = Vec::new(); - // It is OK per the comments: - // - https://github.com/rust-lang/rust/pull/131200#issuecomment-2798854932 - // - https://github.com/rust-lang/rust/pull/131200#issuecomment-2798866392 - #[allow(rustc::potential_query_instability)] - let mut jobs: Vec = query_map.keys().cloned().collect(); - - let mut found_cycle = false; - - while jobs.len() > 0 { - if remove_cycle(&query_map, &mut jobs, &mut wakelist) { - found_cycle = true; - } - } - - // Check that a cycle was found. It is possible for a deadlock to occur without - // a query cycle if a query which can be waited on uses Rayon to do multithreading - // internally. Such a query (X) may be executing on 2 threads (A and B) and A may - // wait using Rayon on B. Rayon may then switch to executing another query (Y) - // which in turn will wait on X causing a deadlock. We have a false dependency from - // X to Y due to Rayon waiting and a true dependency from Y to X. The algorithm here - // only considers the true dependency and won't detect a cycle. - if !found_cycle { - panic!( - "deadlock detected as we're unable to find a query cycle to break\n\ - current query map:\n{:#?}", - query_map - ); - } - - // Mark all the thread we're about to wake up as unblocked. This needs to be done before - // we wake the threads up as otherwise Rayon could detect a deadlock if a thread we - // resumed fell asleep and this thread had yet to mark the remaining threads as unblocked. - for _ in 0..wakelist.len() { - rustc_thread_pool::mark_unblocked(registry); - } - - for waiter in wakelist.into_iter() { - waiter.condvar.notify_one(); - } -} - #[inline(never)] #[cold] pub fn report_cycle<'a>( @@ -588,61 +214,3 @@ pub fn report_cycle<'a>( sess.dcx().create_err(cycle_diag) } - -pub fn print_query_stack<'tcx, Qcx: QueryContext<'tcx>>( - qcx: Qcx, - mut current_query: Option, - dcx: DiagCtxtHandle<'_>, - limit_frames: Option, - mut file: Option, -) -> usize { - // Be careful relying on global state here: this code is called from - // a panic hook, which means that the global `DiagCtxt` may be in a weird - // state if it was responsible for triggering the panic. - let mut count_printed = 0; - let mut count_total = 0; - - // Make use of a partial query map if we fail to take locks collecting active queries. - let query_map = match qcx.collect_active_jobs_from_all_queries(false) { - Ok(query_map) => query_map, - Err(query_map) => query_map, - }; - - if let Some(ref mut file) = file { - let _ = writeln!(file, "\n\nquery stack during panic:"); - } - while let Some(query) = current_query { - let Some(query_info) = query_map.get(&query) else { - break; - }; - let query_extra = query_info.frame.info.extract(); - if Some(count_printed) < limit_frames || limit_frames.is_none() { - // Only print to stderr as many stack frames as `num_frames` when present. - dcx.struct_failure_note(format!( - "#{} [{:?}] {}", - count_printed, query_info.frame.dep_kind, query_extra.description - )) - .with_span(query_info.job.span) - .emit(); - count_printed += 1; - } - - if let Some(ref mut file) = file { - let _ = writeln!( - file, - "#{} [{}] {}", - count_total, - qcx.dep_context().dep_kind_vtable(query_info.frame.dep_kind).name, - query_extra.description - ); - } - - current_query = query_info.job.parent; - count_total += 1; - } - - if let Some(ref mut file) = file { - let _ = writeln!(file, "end of query stack"); - } - count_total -} diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index f4a3fda7e372..6067f7dafd5c 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -15,10 +15,7 @@ use rustc_span::def_id::DefId; pub use self::caches::{ DefIdCache, DefaultCache, QueryCache, QueryCacheKey, SingleCache, VecCache, }; -pub use self::job::{ - QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, QueryMap, break_query_cycles, - print_query_stack, report_cycle, -}; +pub use self::job::{QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryWaiter, report_cycle}; pub use self::plumbing::*; use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; @@ -52,7 +49,7 @@ pub struct QueryStackFrame { pub dep_kind: DepKind, /// This hash is used to deterministically pick /// a query to remove cycles in the parallel compiler. - hash: Hash64, + pub hash: Hash64, pub def_id: Option, /// A def-id that is extracted from a `Ty` in a query key pub def_id_for_ty_in_cycle: Option, @@ -161,11 +158,6 @@ pub trait QueryContext<'tcx>: HasDepContext { /// a token while waiting on a query. fn jobserver_proxy(&self) -> &Proxy; - fn collect_active_jobs_from_all_queries( - self, - require_complete: bool, - ) -> Result, QueryMap<'tcx>>; - /// Load a side effect associated to the node in the previous session. fn load_side_effect( self, From c750a1f5c49ba99f15de43fb651c7958012a12f2 Mon Sep 17 00:00:00 2001 From: AprilNEA Date: Mon, 9 Feb 2026 19:31:25 +0000 Subject: [PATCH 3480/3801] Add regression test for type_const with unit struct ctor under mGCA Unit struct constructors used as the RHS of a `type const` associated const used to ICE during normalization because they were lowered as `Const::new_unevaluated` with a Ctor def_id. The compiler now properly constructs a concrete ValTree value for const constructors. --- .../mgca/type-const-ctor-148953.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/ui/const-generics/mgca/type-const-ctor-148953.rs diff --git a/tests/ui/const-generics/mgca/type-const-ctor-148953.rs b/tests/ui/const-generics/mgca/type-const-ctor-148953.rs new file mode 100644 index 000000000000..bdd3dcf8618f --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-ctor-148953.rs @@ -0,0 +1,31 @@ +//! Regression test for +//! +//! Unit struct constructors used as the RHS of a `type const` associated +//! const used to ICE during normalization because they were lowered as +//! `Const::new_unevaluated` with a Ctor def_id. Fixed by adding proper const +//! constructor support that produces a concrete ValTree value instead. + +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(ConstParamTy, PartialEq, Eq)] +struct S; + +impl S { + type const N: S = S; +} + +#[derive(ConstParamTy, PartialEq, Eq)] +enum E { + V, +} + +impl E { + type const M: E = { E::V }; +} + +fn main() {} From 923de04f6a032ccd475dd271287db8faebf42c3f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Feb 2026 11:53:47 +1100 Subject: [PATCH 3481/3801] Move `rustc_middle::query::values` to `rustc_query_impl`. Because all uses are now in `rustc_query_impl`. This was made possible by the previous commit. Less code in `rustc_middle`, hooray. --- Cargo.lock | 1 + compiler/rustc_middle/src/query/mod.rs | 1 - compiler/rustc_query_impl/Cargo.toml | 1 + compiler/rustc_query_impl/src/lib.rs | 3 ++- .../src/query => rustc_query_impl/src}/values.rs | 10 +++++----- 5 files changed, 9 insertions(+), 7 deletions(-) rename compiler/{rustc_middle/src/query => rustc_query_impl/src}/values.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 7230d633602d..741c51dcb3e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4493,6 +4493,7 @@ name = "rustc_query_impl" version = "0.0.0" dependencies = [ "measureme", + "rustc_abi", "rustc_data_structures", "rustc_errors", "rustc_hashes", diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index a7707cf48c49..24a38e70ff6f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -13,7 +13,6 @@ mod keys; pub mod on_disk_cache; #[macro_use] pub mod plumbing; -pub mod values; pub fn describe_as_module(def_id: impl Into, tcx: TyCtxt<'_>) -> String { let def_id = def_id.into(); diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 511337090d7f..ee50ec073bc8 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start measureme = "12.0.1" +rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hashes = { path = "../rustc_hashes" } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index c1ead8da344b..2241c3f44087 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -19,7 +19,6 @@ use rustc_middle::queries::{ use rustc_middle::query::AsLocalKey; use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; use rustc_middle::query::plumbing::{HashResult, QuerySystem, QuerySystemFns, QueryVTable}; -use rustc_middle::query::values::Value; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::query::{ @@ -32,6 +31,7 @@ pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all}; use crate::plumbing::{encode_all_query_results, try_mark_green}; use crate::profiling_support::QueryKeyStringCache; pub use crate::profiling_support::alloc_self_profile_query_strings; +use crate::values::Value; mod error; mod execution; @@ -39,6 +39,7 @@ mod job; #[macro_use] mod plumbing; mod profiling_support; +mod values; #[derive(ConstParamTy)] // Allow this struct to be used for const-generic values. #[derive(Clone, Copy, Debug, PartialEq, Eq)] diff --git a/compiler/rustc_middle/src/query/values.rs b/compiler/rustc_query_impl/src/values.rs similarity index 98% rename from compiler/rustc_middle/src/query/values.rs rename to compiler/rustc_query_impl/src/values.rs index 0828758cc94e..2fe3808f3d6e 100644 --- a/compiler/rustc_middle/src/query/values.rs +++ b/compiler/rustc_query_impl/src/values.rs @@ -7,15 +7,15 @@ use rustc_errors::codes::*; use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; +use rustc_middle::dep_graph::dep_kinds; +use rustc_middle::query::plumbing::CyclePlaceholder; +use rustc_middle::ty::{self, Representability, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_query_system::query::{CycleError, report_cycle}; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span}; -use crate::dep_graph::dep_kinds; -use crate::query::plumbing::CyclePlaceholder; -use crate::ty::{self, Representability, Ty, TyCtxt}; - -pub trait Value<'tcx>: Sized { +pub(crate) trait Value<'tcx>: Sized { fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> Self; } From a34317e5a5641385706926b109bd259cbc8ec9b7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 10 Feb 2026 14:05:13 +1100 Subject: [PATCH 3482/3801] Move `report_cycle`. From `rustc_query_system::query::job` to `rustc_query_impl::job`. --- Cargo.lock | 1 + compiler/rustc_query_impl/Cargo.toml | 1 + compiler/rustc_query_impl/src/error.rs | 57 +++++++++++++++++++ compiler/rustc_query_impl/src/execution.rs | 3 +- compiler/rustc_query_impl/src/job.rs | 56 +++++++++++++++++- compiler/rustc_query_impl/src/values.rs | 4 +- compiler/rustc_query_system/src/error.rs | 60 +------------------- compiler/rustc_query_system/src/query/job.rs | 55 ------------------ compiler/rustc_query_system/src/query/mod.rs | 2 +- 9 files changed, 120 insertions(+), 119 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 741c51dcb3e7..3019ff581f37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4503,6 +4503,7 @@ dependencies = [ "rustc_middle", "rustc_query_system", "rustc_serialize", + "rustc_session", "rustc_span", "rustc_thread_pool", "tracing", diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index ee50ec073bc8..a8edc1129481 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -16,6 +16,7 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_query_system = { path = "../rustc_query_system" } rustc_serialize = { path = "../rustc_serialize" } +rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_thread_pool = { path = "../rustc_thread_pool" } tracing = "0.1" diff --git a/compiler/rustc_query_impl/src/error.rs b/compiler/rustc_query_impl/src/error.rs index b109172d8e49..6d3eb2950982 100644 --- a/compiler/rustc_query_impl/src/error.rs +++ b/compiler/rustc_query_impl/src/error.rs @@ -1,3 +1,4 @@ +use rustc_errors::codes::*; use rustc_hir::limit::Limit; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; @@ -22,3 +23,59 @@ pub(crate) struct QueryOverflowNote { pub desc: String, pub depth: usize, } + +#[derive(Subdiagnostic)] +#[note("...which requires {$desc}...")] +pub(crate) struct CycleStack { + #[primary_span] + pub span: Span, + pub desc: String, +} + +#[derive(Subdiagnostic)] +pub(crate) enum StackCount { + #[note("...which immediately requires {$stack_bottom} again")] + Single, + #[note("...which again requires {$stack_bottom}, completing the cycle")] + Multiple, +} + +#[derive(Subdiagnostic)] +pub(crate) enum Alias { + #[note("type aliases cannot be recursive")] + #[help("consider using a struct, enum, or union instead to break the cycle")] + #[help( + "see for more information" + )] + Ty, + #[note("trait aliases cannot be recursive")] + Trait, +} + +#[derive(Subdiagnostic)] +#[note("cycle used when {$usage}")] +pub(crate) struct CycleUsage { + #[primary_span] + pub span: Span, + pub usage: String, +} + +#[derive(Diagnostic)] +#[diag("cycle detected when {$stack_bottom}", code = E0391)] +pub(crate) struct Cycle { + #[primary_span] + pub span: Span, + pub stack_bottom: String, + #[subdiagnostic] + pub cycle_stack: Vec, + #[subdiagnostic] + pub stack_count: StackCount, + #[subdiagnostic] + pub alias: Option, + #[subdiagnostic] + pub cycle_usage: Option, + #[note( + "see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information" + )] + pub note_span: (), +} diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 6f16932cb2eb..d7e95d43ecaa 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -11,12 +11,11 @@ use rustc_query_system::dep_graph::{DepGraphData, DepNodeKey, HasDepContext}; use rustc_query_system::query::{ ActiveKeyStatus, CycleError, CycleErrorHandling, QueryCache, QueryJob, QueryJobId, QueryLatch, QueryMode, QueryStackDeferred, QueryStackFrame, QueryState, incremental_verify_ich, - report_cycle, }; use rustc_span::{DUMMY_SP, Span}; use crate::dep_graph::{DepContext, DepNode, DepNodeIndex}; -use crate::job::{QueryJobInfo, QueryMap, find_cycle_in_stack}; +use crate::job::{QueryJobInfo, QueryMap, find_cycle_in_stack, report_cycle}; use crate::{QueryCtxt, QueryFlags, SemiDynamicQueryDispatcher}; #[inline] diff --git a/compiler/rustc_query_impl/src/job.rs b/compiler/rustc_query_impl/src/job.rs index cb0a13d32ad2..f1eba0f76d17 100644 --- a/compiler/rustc_query_impl/src/job.rs +++ b/compiler/rustc_query_impl/src/job.rs @@ -3,11 +3,13 @@ use std::iter; use std::sync::Arc; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::DiagCtxtHandle; +use rustc_errors::{Diag, DiagCtxtHandle}; +use rustc_hir::def::DefKind; use rustc_query_system::query::{ CycleError, QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryStackDeferred, QueryStackFrame, QueryWaiter, }; +use rustc_session::Session; use rustc_span::{DUMMY_SP, Span}; use crate::QueryCtxt; @@ -444,3 +446,55 @@ pub fn print_query_stack<'tcx>( } count_total } + +#[inline(never)] +#[cold] +pub(crate) fn report_cycle<'a>( + sess: &'a Session, + CycleError { usage, cycle: stack }: &CycleError, +) -> Diag<'a> { + assert!(!stack.is_empty()); + + let span = stack[0].frame.info.default_span(stack[1 % stack.len()].span); + + let mut cycle_stack = Vec::new(); + + use crate::error::StackCount; + let stack_count = if stack.len() == 1 { StackCount::Single } else { StackCount::Multiple }; + + for i in 1..stack.len() { + let frame = &stack[i].frame; + let span = frame.info.default_span(stack[(i + 1) % stack.len()].span); + cycle_stack + .push(crate::error::CycleStack { span, desc: frame.info.description.to_owned() }); + } + + let mut cycle_usage = None; + if let Some((span, ref query)) = *usage { + cycle_usage = Some(crate::error::CycleUsage { + span: query.info.default_span(span), + usage: query.info.description.to_string(), + }); + } + + let alias = + if stack.iter().all(|entry| matches!(entry.frame.info.def_kind, Some(DefKind::TyAlias))) { + Some(crate::error::Alias::Ty) + } else if stack.iter().all(|entry| entry.frame.info.def_kind == Some(DefKind::TraitAlias)) { + Some(crate::error::Alias::Trait) + } else { + None + }; + + let cycle_diag = crate::error::Cycle { + span, + cycle_stack, + stack_bottom: stack[0].frame.info.description.to_owned(), + alias, + cycle_usage, + stack_count, + note_span: (), + }; + + sess.dcx().create_err(cycle_diag) +} diff --git a/compiler/rustc_query_impl/src/values.rs b/compiler/rustc_query_impl/src/values.rs index 2fe3808f3d6e..783e7a10d12a 100644 --- a/compiler/rustc_query_impl/src/values.rs +++ b/compiler/rustc_query_impl/src/values.rs @@ -11,10 +11,12 @@ use rustc_middle::dep_graph::dep_kinds; use rustc_middle::query::plumbing::CyclePlaceholder; use rustc_middle::ty::{self, Representability, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; -use rustc_query_system::query::{CycleError, report_cycle}; +use rustc_query_system::query::CycleError; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span}; +use crate::job::report_cycle; + pub(crate) trait Value<'tcx>: Sized { fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> Self; diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs index adce85bf31be..f48afe6f75fa 100644 --- a/compiler/rustc_query_system/src/error.rs +++ b/compiler/rustc_query_system/src/error.rs @@ -1,62 +1,4 @@ -use rustc_errors::codes::*; -use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_span::Span; - -#[derive(Subdiagnostic)] -#[note("...which requires {$desc}...")] -pub(crate) struct CycleStack { - #[primary_span] - pub span: Span, - pub desc: String, -} - -#[derive(Subdiagnostic)] -pub(crate) enum StackCount { - #[note("...which immediately requires {$stack_bottom} again")] - Single, - #[note("...which again requires {$stack_bottom}, completing the cycle")] - Multiple, -} - -#[derive(Subdiagnostic)] -pub(crate) enum Alias { - #[note("type aliases cannot be recursive")] - #[help("consider using a struct, enum, or union instead to break the cycle")] - #[help( - "see for more information" - )] - Ty, - #[note("trait aliases cannot be recursive")] - Trait, -} - -#[derive(Subdiagnostic)] -#[note("cycle used when {$usage}")] -pub(crate) struct CycleUsage { - #[primary_span] - pub span: Span, - pub usage: String, -} - -#[derive(Diagnostic)] -#[diag("cycle detected when {$stack_bottom}", code = E0391)] -pub(crate) struct Cycle { - #[primary_span] - pub span: Span, - pub stack_bottom: String, - #[subdiagnostic] - pub cycle_stack: Vec, - #[subdiagnostic] - pub stack_count: StackCount, - #[subdiagnostic] - pub alias: Option, - #[subdiagnostic] - pub cycle_usage: Option, - #[note( - "see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information" - )] - pub note_span: (), -} +use rustc_macros::Diagnostic; #[derive(Diagnostic)] #[diag("internal compiler error: reentrant incremental verify failure, suppressing message")] diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index e8acb8064f7e..7349fe223ef9 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -4,13 +4,9 @@ use std::num::NonZero; use std::sync::Arc; use parking_lot::{Condvar, Mutex}; -use rustc_errors::Diag; -use rustc_hir::def::DefKind; -use rustc_session::Session; use rustc_span::Span; use super::{QueryStackDeferred, QueryStackFrameExtra}; -use crate::error::CycleStack; use crate::query::plumbing::CycleError; use crate::query::{QueryContext, QueryStackFrame}; @@ -163,54 +159,3 @@ impl<'tcx> QueryLatch<'tcx> { info.waiters.remove(waiter) } } - -#[inline(never)] -#[cold] -pub fn report_cycle<'a>( - sess: &'a Session, - CycleError { usage, cycle: stack }: &CycleError, -) -> Diag<'a> { - assert!(!stack.is_empty()); - - let span = stack[0].frame.info.default_span(stack[1 % stack.len()].span); - - let mut cycle_stack = Vec::new(); - - use crate::error::StackCount; - let stack_count = if stack.len() == 1 { StackCount::Single } else { StackCount::Multiple }; - - for i in 1..stack.len() { - let frame = &stack[i].frame; - let span = frame.info.default_span(stack[(i + 1) % stack.len()].span); - cycle_stack.push(CycleStack { span, desc: frame.info.description.to_owned() }); - } - - let mut cycle_usage = None; - if let Some((span, ref query)) = *usage { - cycle_usage = Some(crate::error::CycleUsage { - span: query.info.default_span(span), - usage: query.info.description.to_string(), - }); - } - - let alias = - if stack.iter().all(|entry| matches!(entry.frame.info.def_kind, Some(DefKind::TyAlias))) { - Some(crate::error::Alias::Ty) - } else if stack.iter().all(|entry| entry.frame.info.def_kind == Some(DefKind::TraitAlias)) { - Some(crate::error::Alias::Trait) - } else { - None - }; - - let cycle_diag = crate::error::Cycle { - span, - cycle_stack, - stack_bottom: stack[0].frame.info.description.to_owned(), - alias, - cycle_usage, - stack_count, - note_span: (), - }; - - sess.dcx().create_err(cycle_diag) -} diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 6067f7dafd5c..c33af941f802 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -15,7 +15,7 @@ use rustc_span::def_id::DefId; pub use self::caches::{ DefIdCache, DefaultCache, QueryCache, QueryCacheKey, SingleCache, VecCache, }; -pub use self::job::{QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryWaiter, report_cycle}; +pub use self::job::{QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryWaiter}; pub use self::plumbing::*; use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; From 0ebd56ebbbf3e392c4fc81865ce89fc6f765a885 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 4 Dec 2025 11:49:56 +0000 Subject: [PATCH 3483/3801] Remove accidental const stability marker on a struct --- library/core/src/array/drain.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/core/src/array/drain.rs b/library/core/src/array/drain.rs index 1c6137191324..17792dca583d 100644 --- a/library/core/src/array/drain.rs +++ b/library/core/src/array/drain.rs @@ -31,7 +31,6 @@ impl<'l, 'f, T, U, const N: usize, F: FnMut(T) -> U> Drain<'l, 'f, T, N, F> { } /// See [`Drain::new`]; this is our fake iterator. -#[rustc_const_unstable(feature = "array_try_map", issue = "79711")] #[unstable(feature = "array_try_map", issue = "79711")] pub(super) struct Drain<'l, 'f, T, const N: usize, F> { // FIXME(const-hack): This is essentially a slice::IterMut<'static>, replace when possible. From 00fef81964699283c09a244c6fb53840eada28e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 17:57:43 +0100 Subject: [PATCH 3484/3801] Port `rustc_expected_cgu_reuse` to the new attribute parser --- Cargo.lock | 1 - .../src/attributes/rustc_internal.rs | 145 +++++++++++++++- compiler/rustc_attr_parsing/src/context.rs | 1 + .../src/session_diagnostics.rs | 9 + compiler/rustc_codegen_ssa/Cargo.toml | 1 - .../src/assert_module_sources.rs | 160 ++++++++---------- compiler/rustc_codegen_ssa/src/errors.rs | 30 +--- .../rustc_hir/src/attrs/data_structures.rs | 16 ++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 4 +- 10 files changed, 244 insertions(+), 124 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 545c776b4805..1a930b64f458 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3687,7 +3687,6 @@ dependencies = [ "serde_json", "smallvec", "tempfile", - "thin-vec", "thorin-dwp", "tracing", "wasm-encoder 0.219.2", diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 0fd8c8a04a57..e5ea7fde3954 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -2,7 +2,8 @@ use std::path::PathBuf; use rustc_ast::{LitIntType, LitKind, MetaItemLit}; use rustc_hir::attrs::{ - BorrowckGraphvizFormatKind, RustcCleanAttribute, RustcCleanQueries, RustcLayoutType, + BorrowckGraphvizFormatKind, CguFields, CguKind, DivergingBlockBehavior, + DivergingFallbackBehavior, RustcCleanAttribute, RustcCleanQueries, RustcLayoutType, RustcMirKind, }; use rustc_session::errors; @@ -10,7 +11,9 @@ use rustc_span::Symbol; use super::prelude::*; use super::util::parse_single_integer; -use crate::session_diagnostics::{AttributeRequiresOpt, RustcScalableVectorCountOutOfRange}; +use crate::session_diagnostics::{ + AttributeRequiresOpt, CguFieldsMissing, RustcScalableVectorCountOutOfRange, +}; pub(crate) struct RustcMainParser; @@ -204,6 +207,144 @@ impl NoArgsAttributeParser for RustcLintOptTyParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy; } +fn parse_cgu_fields( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + accepts_kind: bool, +) -> Option<(Symbol, Symbol, Option)> { + let Some(args) = args.list() else { + cx.expected_list(cx.attr_span, args); + return None; + }; + + let mut cfg = None::<(Symbol, Span)>; + let mut module = None::<(Symbol, Span)>; + let mut kind = None::<(Symbol, Span)>; + + for arg in args.mixed() { + let Some(arg) = arg.meta_item() else { + cx.expected_name_value(args.span, None); + continue; + }; + + let res = match arg.ident().map(|i| i.name) { + Some(sym::cfg) => &mut cfg, + Some(sym::module) => &mut module, + Some(sym::kind) if accepts_kind => &mut kind, + _ => { + cx.expected_specific_argument( + arg.path().span(), + if accepts_kind { + &[sym::cfg, sym::module, sym::kind] + } else { + &[sym::cfg, sym::module] + }, + ); + continue; + } + }; + + let Some(i) = arg.args().name_value() else { + cx.expected_name_value(arg.span(), None); + continue; + }; + + let Some(str) = i.value_as_str() else { + cx.expected_string_literal(i.value_span, Some(i.value_as_lit())); + continue; + }; + + if res.is_some() { + cx.duplicate_key(arg.span(), arg.ident().unwrap().name); + continue; + } + + *res = Some((str, i.value_span)); + } + + let Some((cfg, _)) = cfg else { + cx.emit_err(CguFieldsMissing { span: args.span, name: &cx.attr_path, field: sym::cfg }); + return None; + }; + let Some((module, _)) = module else { + cx.emit_err(CguFieldsMissing { span: args.span, name: &cx.attr_path, field: sym::module }); + return None; + }; + let kind = if let Some((kind, span)) = kind { + Some(match kind { + sym::no => CguKind::No, + sym::pre_dash_lto => CguKind::PreDashLto, + sym::post_dash_lto => CguKind::PostDashLto, + sym::any => CguKind::Any, + _ => { + cx.expected_specific_argument_strings( + span, + &[sym::no, sym::pre_dash_lto, sym::post_dash_lto, sym::any], + ); + return None; + } + }) + } else { + // return None so that an unwrap for the attributes that need it is ok. + if accepts_kind { + cx.emit_err(CguFieldsMissing { + span: args.span, + name: &cx.attr_path, + field: sym::kind, + }); + return None; + }; + + None + }; + + Some((cfg, module, kind)) +} + +#[derive(Default)] +pub(crate) struct RustcCguTestAttributeParser { + items: ThinVec<(Span, CguFields)>, +} + +impl AttributeParser for RustcCguTestAttributeParser { + const ATTRIBUTES: AcceptMapping = &[ + ( + &[sym::rustc_partition_reused], + template!(List: &[r#"cfg = "...", module = "...""#]), + |this, cx, args| { + this.items.extend(parse_cgu_fields(cx, args, false).map(|(cfg, module, _)| { + (cx.attr_span, CguFields::PartitionReused { cfg, module }) + })); + }, + ), + ( + &[sym::rustc_partition_codegened], + template!(List: &[r#"cfg = "...", module = "...""#]), + |this, cx, args| { + this.items.extend(parse_cgu_fields(cx, args, false).map(|(cfg, module, _)| { + (cx.attr_span, CguFields::PartitionCodegened { cfg, module }) + })); + }, + ), + ( + &[sym::rustc_expected_cgu_reuse], + template!(List: &[r#"cfg = "...", module = "...", kind = "...""#]), + |this, cx, args| { + this.items.extend(parse_cgu_fields(cx, args, true).map(|(cfg, module, kind)| { + // unwrap ok because if not given, we return None in `parse_cgu_fields`. + (cx.attr_span, CguFields::ExpectedCguReuse { cfg, module, kind: kind.unwrap() }) + })); + }, + ), + ]; + + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]); + + fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { + Some(AttributeKind::RustcCguTestAttr(self.items)) + } +} pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 412f960fb7cf..f53f48b337b5 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -149,6 +149,7 @@ attribute_parsers!( NakedParser, StabilityParser, UsedParser, + RustcCguTestAttributeParser, // tidy-alphabetical-end // tidy-alphabetical-start diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 6ca47e8d698b..2eb585671fff 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -45,6 +45,15 @@ pub(crate) struct DocAliasStartEnd<'a> { pub attr_str: &'a str, } +#[derive(Diagnostic)] +#[diag("`#[{$name})]` is missing a `{$field}` argument")] +pub(crate) struct CguFieldsMissing<'a> { + #[primary_span] + pub span: Span, + pub name: &'a AttrPath, + pub field: Symbol, +} + #[derive(Diagnostic)] #[diag("`#![doc({$attr_name} = \"...\")]` isn't allowed as a crate-level attribute")] pub(crate) struct DocAttrNotCrateLevel { diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 864220635120..c7d7b7429f34 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -36,7 +36,6 @@ rustc_trait_selection = { path = "../rustc_trait_selection" } serde_json = "1.0.59" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tempfile = "3.2" -thin-vec = "0.2.12" thorin-dwp = "0.9" tracing = "0.1" wasm-encoder = "0.219" diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 43e1e135a666..081fe0aa91aa 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -28,13 +28,13 @@ use std::fmt; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{DiagArgValue, IntoDiagArg}; -use rustc_hir as hir; +use rustc_hir::attrs::{AttributeKind, CguFields, CguKind}; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::{self as hir, find_attr}; use rustc_middle::mir::mono::CodegenUnitNameBuilder; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_span::{Span, Symbol, sym}; -use thin_vec::ThinVec; +use rustc_span::{Span, Symbol}; use tracing::debug; use crate::errors; @@ -63,9 +63,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&mut CguReuseTr }, }; - for attr in tcx.hir_attrs(rustc_hir::CRATE_HIR_ID) { - ams.check_attr(attr); - } + ams.check_attrs(tcx.hir_attrs(rustc_hir::CRATE_HIR_ID)); set_reuse(&mut ams.cgu_reuse_tracker); @@ -89,109 +87,91 @@ struct AssertModuleSource<'tcx> { } impl<'tcx> AssertModuleSource<'tcx> { - fn check_attr(&mut self, attr: &hir::Attribute) { - let (expected_reuse, comp_kind) = if attr.has_name(sym::rustc_partition_reused) { - (CguReuse::PreLto, ComparisonKind::AtLeast) - } else if attr.has_name(sym::rustc_partition_codegened) { - (CguReuse::No, ComparisonKind::Exact) - } else if attr.has_name(sym::rustc_expected_cgu_reuse) { - match self.field(attr, sym::kind) { - sym::no => (CguReuse::No, ComparisonKind::Exact), - sym::pre_dash_lto => (CguReuse::PreLto, ComparisonKind::Exact), - sym::post_dash_lto => (CguReuse::PostLto, ComparisonKind::Exact), - sym::any => (CguReuse::PreLto, ComparisonKind::AtLeast), - other => { - self.tcx - .dcx() - .emit_fatal(errors::UnknownReuseKind { span: attr.span(), kind: other }); - } + fn check_attrs(&mut self, attrs: &[hir::Attribute]) { + for &(span, cgu_fields) in find_attr!(attrs, + AttributeKind::RustcCguTestAttr(e) => e) + .into_iter() + .flatten() + { + let (expected_reuse, comp_kind) = match cgu_fields { + CguFields::PartitionReused { .. } => (CguReuse::PreLto, ComparisonKind::AtLeast), + CguFields::PartitionCodegened { .. } => (CguReuse::No, ComparisonKind::Exact), + CguFields::ExpectedCguReuse { kind, .. } => match kind { + CguKind::No => (CguReuse::No, ComparisonKind::Exact), + CguKind::PreDashLto => (CguReuse::PreLto, ComparisonKind::Exact), + CguKind::PostDashLto => (CguReuse::PostLto, ComparisonKind::Exact), + CguKind::Any => (CguReuse::PreLto, ComparisonKind::AtLeast), + }, + }; + let (CguFields::ExpectedCguReuse { cfg, module, .. } + | CguFields::PartitionCodegened { cfg, module } + | CguFields::PartitionReused { cfg, module }) = cgu_fields; + + if !self.tcx.sess.opts.unstable_opts.query_dep_graph { + self.tcx.dcx().emit_fatal(errors::MissingQueryDepGraph { span }); } - } else { - return; - }; - if !self.tcx.sess.opts.unstable_opts.query_dep_graph { - self.tcx.dcx().emit_fatal(errors::MissingQueryDepGraph { span: attr.span() }); - } + if !self.check_config(cfg) { + debug!("check_attr: config does not match, ignoring attr"); + return; + } - if !self.check_config(attr) { - debug!("check_attr: config does not match, ignoring attr"); - return; - } + let user_path = module.as_str(); + let crate_name = self.tcx.crate_name(LOCAL_CRATE); + let crate_name = crate_name.as_str(); - let user_path = self.field(attr, sym::module).to_string(); - let crate_name = self.tcx.crate_name(LOCAL_CRATE).to_string(); + if !user_path.starts_with(&crate_name) { + self.tcx.dcx().emit_fatal(errors::MalformedCguName { span, user_path, crate_name }); + } - if !user_path.starts_with(&crate_name) { - self.tcx.dcx().emit_fatal(errors::MalformedCguName { - span: attr.span(), - user_path, - crate_name, - }); - } + // Split of the "special suffix" if there is one. + let (user_path, cgu_special_suffix) = if let Some(index) = user_path.rfind('.') { + (&user_path[..index], Some(&user_path[index + 1..])) + } else { + (&user_path[..], None) + }; - // Split of the "special suffix" if there is one. - let (user_path, cgu_special_suffix) = if let Some(index) = user_path.rfind('.') { - (&user_path[..index], Some(&user_path[index + 1..])) - } else { - (&user_path[..], None) - }; + let mut iter = user_path.split('-'); - let mut iter = user_path.split('-'); + // Remove the crate name + assert_eq!(iter.next().unwrap(), crate_name); - // Remove the crate name - assert_eq!(iter.next().unwrap(), crate_name); + let cgu_path_components = iter.collect::>(); - let cgu_path_components = iter.collect::>(); + let cgu_name_builder = &mut CodegenUnitNameBuilder::new(self.tcx); + let cgu_name = cgu_name_builder.build_cgu_name( + LOCAL_CRATE, + cgu_path_components, + cgu_special_suffix, + ); - let cgu_name_builder = &mut CodegenUnitNameBuilder::new(self.tcx); - let cgu_name = - cgu_name_builder.build_cgu_name(LOCAL_CRATE, cgu_path_components, cgu_special_suffix); + debug!("mapping '{user_path}' to cgu name '{cgu_name}'"); - debug!("mapping '{}' to cgu name '{}'", self.field(attr, sym::module), cgu_name); + if !self.available_cgus.contains(&cgu_name) { + let cgu_names: Vec<&str> = + self.available_cgus.items().map(|cgu| cgu.as_str()).into_sorted_stable_ord(); + self.tcx.dcx().emit_err(errors::NoModuleNamed { + span, + user_path, + cgu_name, + cgu_names: cgu_names.join(", "), + }); + } - if !self.available_cgus.contains(&cgu_name) { - let cgu_names: Vec<&str> = - self.available_cgus.items().map(|cgu| cgu.as_str()).into_sorted_stable_ord(); - self.tcx.dcx().emit_err(errors::NoModuleNamed { - span: attr.span(), - user_path, + self.cgu_reuse_tracker.set_expectation( cgu_name, - cgu_names: cgu_names.join(", "), - }); + user_path, + span, + expected_reuse, + comp_kind, + ); } - - self.cgu_reuse_tracker.set_expectation( - cgu_name, - user_path, - attr.span(), - expected_reuse, - comp_kind, - ); - } - - fn field(&self, attr: &hir::Attribute, name: Symbol) -> Symbol { - for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { - if item.has_name(name) { - if let Some(value) = item.value_str() { - return value; - } else { - self.tcx.dcx().emit_fatal(errors::FieldAssociatedValueExpected { - span: item.span(), - name, - }); - } - } - } - - self.tcx.dcx().emit_fatal(errors::NoField { span: attr.span(), name }); } /// Scan for a `cfg="foo"` attribute and check whether we have a /// cfg flag called `foo`. - fn check_config(&self, attr: &hir::Attribute) -> bool { + fn check_config(&self, value: Symbol) -> bool { let config = &self.tcx.sess.psess.config; - let value = self.field(attr, sym::cfg); debug!("check_config(config={:?}, value={:?})", config, value); if config.iter().any(|&(name, _)| name == value) { debug!("check_config: matched"); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 82a6525adcc9..897b5f957e15 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -42,14 +42,6 @@ pub(crate) struct CguNotRecorded<'a> { pub cgu_name: &'a str, } -#[derive(Diagnostic)] -#[diag("unknown cgu-reuse-kind `{$kind}` specified")] -pub(crate) struct UnknownReuseKind { - #[primary_span] - pub span: Span, - pub kind: Symbol, -} - #[derive(Diagnostic)] #[diag("found CGU-reuse attribute but `-Zquery-dep-graph` was not specified")] pub(crate) struct MissingQueryDepGraph { @@ -61,11 +53,11 @@ pub(crate) struct MissingQueryDepGraph { #[diag( "found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case)" )] -pub(crate) struct MalformedCguName { +pub(crate) struct MalformedCguName<'a> { #[primary_span] pub span: Span, - pub user_path: String, - pub crate_name: String, + pub user_path: &'a str, + pub crate_name: &'a str, } #[derive(Diagnostic)] @@ -78,22 +70,6 @@ pub(crate) struct NoModuleNamed<'a> { pub cgu_names: String, } -#[derive(Diagnostic)] -#[diag("associated value expected for `{$name}`")] -pub(crate) struct FieldAssociatedValueExpected { - #[primary_span] - pub span: Span, - pub name: Symbol, -} - -#[derive(Diagnostic)] -#[diag("no field `{$name}`")] -pub(crate) struct NoField { - #[primary_span] - pub span: Span, - pub name: Symbol, -} - #[derive(Diagnostic)] #[diag("failed to write lib.def file: {$error}")] pub(crate) struct LibDefWriteFailure { diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 2d3825ccd024..982c69c38afb 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -50,6 +50,19 @@ pub struct EiiDecl { } #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)] +pub enum CguKind { + No, + PreDashLto, + PostDashLto, + Any, +} + +#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)] +pub enum CguFields { + PartitionReused { cfg: Symbol, module: Symbol }, + PartitionCodegened { cfg: Symbol, module: Symbol }, + ExpectedCguReuse { cfg: Symbol, module: Symbol, kind: CguKind }, +} pub enum InlineAttr { None, Hint, @@ -1117,6 +1130,9 @@ pub enum AttributeKind { /// Represents `#[rustc_evaluate_where_clauses]` RustcEvaluateWhereClauses, + /// Represents `#[rustc_expected_cgu_reuse]`, `#[rustc_partition_codegened]` and `#[rustc_partition_reused]`. + RustcCguTestAttr(ThinVec<(Span, CguFields)>), + /// Represents `#[rustc_has_incoherent_inherent_impls]` RustcHasIncoherentInherentImpls, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index ac9ef79e9ab9..116cda09657a 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -146,6 +146,7 @@ impl AttributeKind { RustcOffloadKernel => Yes, RustcOutlives => No, RustcParenSugar(..) => No, + RustcCguTestAttr { .. } => No, RustcPassByValue(..) => Yes, RustcPassIndirectlyInNonRusticAbis(..) => No, RustcPreserveUbChecks => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0ba4450b1722..c8047e517616 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -338,6 +338,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcOffloadKernel | AttributeKind::RustcOutlives | AttributeKind::RustcParenSugar(..) + | AttributeKind::RustcCguTestAttr(..) | AttributeKind::RustcPassByValue (..) | AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) | AttributeKind::RustcPreserveUbChecks @@ -407,9 +408,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_autodiff | sym::rustc_capture_analysis | sym::rustc_mir - | sym::rustc_partition_reused - | sym::rustc_partition_codegened - | sym::rustc_expected_cgu_reuse // crate-level attrs, are checked below | sym::feature | sym::register_tool From 9cc2924959717d5ef9db5c9cdb1060a6ac4cd9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 17:57:43 +0100 Subject: [PATCH 3485/3801] Port `rustc_deprecated_safe_2024` to the new attribute parser --- .../src/attributes/rustc_internal.rs | 50 +++++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + .../rustc_hir/src/attrs/data_structures.rs | 3 ++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_mir_build/src/check_unsafety.rs | 29 +++-------- compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 63 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index e5ea7fde3954..96f386639803 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -345,6 +345,56 @@ impl AttributeParser for RustcCguTestAttributeParser { Some(AttributeKind::RustcCguTestAttr(self.items)) } } + +pub(crate) struct RustcDeprecatedSafe2024Parser; + +impl SingleAttributeParser for RustcDeprecatedSafe2024Parser { + const PATH: &[Symbol] = &[sym::rustc_deprecated_safe_2024]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const TEMPLATE: AttributeTemplate = template!(List: &[r#"audit_that = "...""#]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(args) = args.list() else { + cx.expected_list(cx.attr_span, args); + return None; + }; + + let Some(single) = args.single() else { + cx.expected_single_argument(args.span); + return None; + }; + + let Some(arg) = single.meta_item() else { + cx.expected_name_value(args.span, None); + return None; + }; + + let Some(args) = arg.word_is(sym::audit_that) else { + cx.expected_specific_argument(arg.span(), &[sym::audit_that]); + return None; + }; + + let Some(nv) = args.name_value() else { + cx.expected_name_value(arg.span(), Some(sym::audit_that)); + return None; + }; + + let Some(suggestion) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return None; + }; + + Some(AttributeKind::RustcDeprecatedSafe2024 { suggestion }) + } +} pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index f53f48b337b5..75f48bb39528 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -202,6 +202,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 982c69c38afb..d9da0633365e 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1103,6 +1103,9 @@ pub enum AttributeKind { /// Represents `#[rustc_deny_explicit_impl]`. RustcDenyExplicitImpl(Span), + /// Represents `#[rustc_deprecated_safe_2024]` + RustcDeprecatedSafe2024 { suggestion: Symbol }, + /// Represents `#[rustc_dummy]`. RustcDummy, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 116cda09657a..f26c5a07d430 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -108,6 +108,7 @@ impl AttributeKind { RustcDefPath(..) => No, RustcDelayedBugFromInsideQuery => No, RustcDenyExplicitImpl(..) => No, + RustcDeprecatedSafe2024 { .. } => Yes, RustcDummy => No, RustcDumpDefParents => No, RustcDumpItemBounds => No, diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 4a20b05d1fc2..7bced8168bd1 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint::Level; use rustc_session::lint::builtin::{DEPRECATED_SAFE_2024, UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; use rustc_span::def_id::{DefId, LocalDefId}; -use rustc_span::{Span, Symbol, sym}; +use rustc_span::{Span, Symbol}; use crate::builder::ExprCategory; use crate::errors::*; @@ -98,29 +98,14 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { // from an edition before 2024. &UnsafeOpKind::CallToUnsafeFunction(Some(id)) if !span.at_least_rust_2024() - && let Some(attr) = self.tcx.get_attr(id, sym::rustc_deprecated_safe_2024) => + && let Some(suggestion) = find_attr!(self.tcx.get_all_attrs(id), AttributeKind::RustcDeprecatedSafe2024{suggestion} => suggestion) => { - let suggestion = attr - .meta_item_list() - .unwrap_or_default() - .into_iter() - .find(|item| item.has_name(sym::audit_that)) - .map(|item| { - item.value_str().expect( - "`#[rustc_deprecated_safe_2024(audit_that)]` must have a string value", - ) - }); - let sm = self.tcx.sess.source_map(); - let guarantee = suggestion - .as_ref() - .map(|suggestion| format!("that {}", suggestion)) - .unwrap_or_else(|| String::from("its unsafe preconditions")); - let suggestion = suggestion - .and_then(|suggestion| { - sm.indentation_before(span).map(|indent| { - format!("{}// TODO: Audit that {}.\n", indent, suggestion) // ignore-tidy-todo - }) + let guarantee = format!("that {}", suggestion); + let suggestion = sm + .indentation_before(span) + .map(|indent| { + format!("{}// TODO: Audit that {}.\n", indent, suggestion) // ignore-tidy-todo }) .unwrap_or_default(); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c8047e517616..738a8aaeaf7a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -303,6 +303,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDefPath(..) | AttributeKind::RustcDelayedBugFromInsideQuery | AttributeKind::RustcDenyExplicitImpl(..) + | AttributeKind::RustcDeprecatedSafe2024 {..} | AttributeKind::RustcDummy | AttributeKind::RustcDumpDefParents | AttributeKind::RustcDumpItemBounds @@ -400,7 +401,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_do_not_const_check | sym::rustc_doc_primitive | sym::rustc_conversion_suggestion - | sym::rustc_deprecated_safe_2024 | sym::rustc_test_marker | sym::rustc_layout | sym::rustc_proc_macro_decls From 9d10b2ff370b0711bec5b542fa837a4f9f15400d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 17:57:43 +0100 Subject: [PATCH 3486/3801] Port `rustc_conversion_suggestion` to the new attribute parser --- .../src/attributes/rustc_internal.rs | 16 +++++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_hir_typeck/src/demand.rs | 27 +++++++++---------- compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 96f386639803..73b8b2824b1a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -395,6 +395,22 @@ impl SingleAttributeParser for RustcDeprecatedSafe2024Parser { Some(AttributeKind::RustcDeprecatedSafe2024 { suggestion }) } } + +pub(crate) struct RustcConversionSuggestionParser; + +impl NoArgsAttributeParser for RustcConversionSuggestionParser { + const PATH: &[Symbol] = &[sym::rustc_conversion_suggestion]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcConversionSuggestion; +} + pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 75f48bb39528..c1889e9ec0e7 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -264,6 +264,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index d9da0633365e..0c5cb8e4ebff 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1091,6 +1091,9 @@ pub enum AttributeKind { /// Represents `#[rustc_const_stable_indirect]`. RustcConstStabilityIndirect, + /// Represents `#[rustc_conversion_suggestion]` + RustcConversionSuggestion, + /// Represents `#[rustc_deallocator]` RustcDeallocator, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index f26c5a07d430..3c81abdf3891 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -104,6 +104,7 @@ impl AttributeKind { RustcConfusables { .. } => Yes, RustcConstStability { .. } => Yes, RustcConstStabilityIndirect => No, + RustcConversionSuggestion => Yes, RustcDeallocator => No, RustcDefPath(..) => No, RustcDelayedBugFromInsideQuery => No, diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 84663ff884b4..68cbfa728058 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1,7 +1,8 @@ use rustc_errors::{Applicability, Diag, MultiSpan, listify}; -use rustc_hir as hir; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::Res; use rustc_hir::intravisit::Visitor; +use rustc_hir::{self as hir, find_attr}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_middle::bug; use rustc_middle::ty::adjustment::AllowTwoPhase; @@ -1081,19 +1082,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id, |m| { self.has_only_self_parameter(m) - && self - .tcx - // This special internal attribute is used to permit - // "identity-like" conversion methods to be suggested here. - // - // FIXME (#46459 and #46460): ideally - // `std::convert::Into::into` and `std::borrow:ToOwned` would - // also be `#[rustc_conversion_suggestion]`, if not for - // method-probing false-positives and -negatives (respectively). - // - // FIXME? Other potential candidate methods: `as_ref` and - // `as_mut`? - .has_attr(m.def_id, sym::rustc_conversion_suggestion) + // This special internal attribute is used to permit + // "identity-like" conversion methods to be suggested here. + // + // FIXME (#46459 and #46460): ideally + // `std::convert::Into::into` and `std::borrow:ToOwned` would + // also be `#[rustc_conversion_suggestion]`, if not for + // method-probing false-positives and -negatives (respectively). + // + // FIXME? Other potential candidate methods: `as_ref` and + // `as_mut`? + && find_attr!(self.tcx.get_all_attrs(m.def_id), AttributeKind::RustcConversionSuggestion) }, ); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 738a8aaeaf7a..8ca32179a445 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -299,6 +299,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcCoinductive(..) | AttributeKind::RustcConfusables { .. } | AttributeKind::RustcConstStabilityIndirect + | AttributeKind::RustcConversionSuggestion | AttributeKind::RustcDeallocator | AttributeKind::RustcDefPath(..) | AttributeKind::RustcDelayedBugFromInsideQuery @@ -400,7 +401,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_on_unimplemented | sym::rustc_do_not_const_check | sym::rustc_doc_primitive - | sym::rustc_conversion_suggestion | sym::rustc_test_marker | sym::rustc_layout | sym::rustc_proc_macro_decls From a17eb934db482303db43a78023e2e8e56e8e600b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 17:57:43 +0100 Subject: [PATCH 3487/3801] Port `rustc_capture_analysis` to the new attribute parser --- .../src/attributes/rustc_internal.rs | 9 +++++++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_hir_typeck/src/upvar.rs | 10 +++++++--- compiler/rustc_passes/src/check_attr.rs | 1 + 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 73b8b2824b1a..52268def8718 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -411,6 +411,15 @@ impl NoArgsAttributeParser for RustcConversionSuggestionParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcConversionSuggestion; } +pub(crate) struct RustcCaptureAnalysisParser; + +impl NoArgsAttributeParser for RustcCaptureAnalysisParser { + const PATH: &[Symbol] = &[sym::rustc_capture_analysis]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCaptureAnalysis; +} + pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index c1889e9ec0e7..16e4a6452210 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -263,6 +263,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 0c5cb8e4ebff..09b51cef3c1a 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1066,6 +1066,9 @@ pub enum AttributeKind { /// Represents `#[rustc_builtin_macro]`. RustcBuiltinMacro { builtin_name: Option, helper_attrs: ThinVec, span: Span }, + /// Represents `#[rustc_capture_analysis]` + RustcCaptureAnalysis, + /// Represents `#[rustc_clean]` RustcClean(ThinVec), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 3c81abdf3891..4c68d51e6334 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -98,6 +98,7 @@ impl AttributeKind { RustcAsPtr(..) => Yes, RustcBodyStability { .. } => No, RustcBuiltinMacro { .. } => Yes, + RustcCaptureAnalysis => No, RustcClean { .. } => No, RustcCoherenceIsCore(..) => No, RustcCoinductive(..) => No, diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 1a2b76485f35..767913ba5261 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -36,10 +36,10 @@ use rustc_abi::FIRST_VARIANT; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::{ExtendUnord, UnordSet}; use rustc_errors::{Applicability, MultiSpan}; -use rustc_hir as hir; -use rustc_hir::HirId; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::{self as hir, HirId, find_attr}; use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind}; use rustc_middle::mir::FakeReadCause; use rustc_middle::traits::ObligationCauseCode; @@ -1743,7 +1743,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn should_log_capture_analysis(&self, closure_def_id: LocalDefId) -> bool { - self.has_rustc_attrs && self.tcx.has_attr(closure_def_id, sym::rustc_capture_analysis) + self.has_rustc_attrs + && find_attr!( + self.tcx.get_all_attrs(closure_def_id), + AttributeKind::RustcCaptureAnalysis + ) } fn log_capture_analysis_first_pass( diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8ca32179a445..db5c33fcb17c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -294,6 +294,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcAsPtr(..) | AttributeKind::RustcBodyStability { .. } | AttributeKind::RustcBuiltinMacro { .. } + | AttributeKind::RustcCaptureAnalysis | AttributeKind::RustcClean(..) | AttributeKind::RustcCoherenceIsCore(..) | AttributeKind::RustcCoinductive(..) From 1c45618335efce02aaf1bcc7235aedff7eae3629 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 10 Feb 2026 10:11:25 +0100 Subject: [PATCH 3488/3801] Update to LLVM 22 rc 3 --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 41256ab128f2..a306f6a8c534 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 41256ab128f2af613b4a16771cda6baa36b55f45 +Subproject commit a306f6a8c53494d32c171c346c6809c97124c697 From ea361287be9aa101d7ad50b81d216edc5222ce6f Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 10 Feb 2026 09:13:45 +0000 Subject: [PATCH 3489/3801] Remove SubdiagMessage in favour of the identical DiagMessage --- compiler/rustc_error_messages/src/lib.rs | 58 ---------- compiler/rustc_errors/src/diagnostic.rs | 108 ++++++------------ compiler/rustc_errors/src/lib.rs | 21 ++-- compiler/rustc_hir_typeck/src/method/mod.rs | 4 +- compiler/rustc_span/src/symbol.rs | 1 - .../src/diagnostics/translation.md | 12 +- .../clippy/clippy_utils/src/diagnostics.rs | 8 +- .../diagnostic-derive-doc-comment-field.rs | 2 +- .../diagnostic-derive-inline.rs | 2 +- .../subdiagnostic-derive-inline.rs | 2 +- 10 files changed, 56 insertions(+), 162 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 916a370659aa..0b30102eb992 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -230,38 +230,6 @@ pub fn fallback_fluent_bundle( }))) } -/// Abstraction over a message in a subdiagnostic (i.e. label, note, help, etc) to support both -/// translatable and non-translatable diagnostic messages. -/// -/// Translatable messages for subdiagnostics are typically attributes attached to a larger Fluent -/// message so messages of this type must be combined with a `DiagMessage` (using -/// `DiagMessage::with_subdiagnostic_message`) before rendering. However, subdiagnostics from -/// the `Subdiagnostic` derive refer to Fluent identifiers directly. -#[rustc_diagnostic_item = "SubdiagMessage"] -pub enum SubdiagMessage { - /// Non-translatable diagnostic message. - Str(Cow<'static, str>), - /// An inline Fluent message. Instances of this variant are generated by the - /// `Subdiagnostic` derive. - Inline(Cow<'static, str>), -} - -impl From for SubdiagMessage { - fn from(s: String) -> Self { - SubdiagMessage::Str(Cow::Owned(s)) - } -} -impl From<&'static str> for SubdiagMessage { - fn from(s: &'static str) -> Self { - SubdiagMessage::Str(Cow::Borrowed(s)) - } -} -impl From> for SubdiagMessage { - fn from(s: Cow<'static, str>) -> Self { - SubdiagMessage::Str(s) - } -} - /// Abstraction over a message in a diagnostic to support both translatable and non-translatable /// diagnostic messages. /// @@ -281,18 +249,6 @@ pub enum DiagMessage { } impl DiagMessage { - /// Given a `SubdiagMessage` which may contain a Fluent attribute, create a new - /// `DiagMessage` that combines that attribute with the Fluent identifier of `self`. - /// - /// - If the `SubdiagMessage` is non-translatable then return the message as a `DiagMessage`. - /// - If `self` is non-translatable then return `self`'s message. - pub fn with_subdiagnostic_message(&self, sub: SubdiagMessage) -> Self { - match sub { - SubdiagMessage::Str(s) => DiagMessage::Str(s), - SubdiagMessage::Inline(s) => DiagMessage::Inline(s), - } - } - pub fn as_str(&self) -> Option<&str> { match self { DiagMessage::Str(s) => Some(s), @@ -317,20 +273,6 @@ impl From> for DiagMessage { } } -/// Translating *into* a subdiagnostic message from a diagnostic message is a little strange - but -/// the subdiagnostic functions (e.g. `span_label`) take a `SubdiagMessage` and the -/// subdiagnostic derive refers to typed identifiers that are `DiagMessage`s, so need to be -/// able to convert between these, as much as they'll be converted back into `DiagMessage` -/// using `with_subdiagnostic_message` eventually. Don't use this other than for the derive. -impl From for SubdiagMessage { - fn from(val: DiagMessage) -> Self { - match val { - DiagMessage::Str(s) => SubdiagMessage::Str(s), - DiagMessage::Inline(s) => SubdiagMessage::Inline(s), - } - } -} - /// A span together with some additional data. #[derive(Clone, Debug)] pub struct SpanLabel { diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index a9e81354fc6a..087c5e700df0 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -17,8 +17,7 @@ use tracing::debug; use crate::{ CodeSuggestion, DiagCtxtHandle, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level, - MultiSpan, StashKey, Style, SubdiagMessage, Substitution, SubstitutionPart, SuggestionStyle, - Suggestions, + MultiSpan, StashKey, Style, Substitution, SubstitutionPart, SuggestionStyle, Suggestions, }; pub type DiagArgMap = FxIndexMap; @@ -325,30 +324,8 @@ impl DiagInner { } } - // See comment on `Diag::subdiagnostic_message_to_diagnostic_message`. - pub(crate) fn subdiagnostic_message_to_diagnostic_message( - &self, - attr: impl Into, - ) -> DiagMessage { - let msg = - self.messages.iter().map(|(msg, _)| msg).next().expect("diagnostic with no messages"); - msg.with_subdiagnostic_message(attr.into()) - } - - pub(crate) fn sub( - &mut self, - level: Level, - message: impl Into, - span: MultiSpan, - ) { - let sub = Subdiag { - level, - messages: vec![( - self.subdiagnostic_message_to_diagnostic_message(message), - Style::NoStyle, - )], - span, - }; + pub(crate) fn sub(&mut self, level: Level, message: impl Into, span: MultiSpan) { + let sub = Subdiag { level, messages: vec![(message.into(), Style::NoStyle)], span }; self.children.push(sub); } @@ -609,9 +586,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// the diagnostic was constructed. However, the label span is *not* considered a /// ["primary span"][`MultiSpan`]; only the `Span` supplied when creating the diagnostic is /// primary. - pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { - let msg = self.subdiagnostic_message_to_diagnostic_message(label); - self.span.push_span_label(span, msg); + pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { + self.span.push_span_label(span, label.into()); self } } @@ -713,7 +689,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_note, /// Add a note attached to this diagnostic. - pub fn note(&mut self, msg: impl Into) -> &mut Self { + pub fn note(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Note, msg, MultiSpan::new()); self } } @@ -733,7 +709,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { } /// This is like [`Diag::note()`], but it's only printed once. - pub fn note_once(&mut self, msg: impl Into) -> &mut Self { + pub fn note_once(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::OnceNote, msg, MultiSpan::new()); self } @@ -744,7 +720,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_note( &mut self, sp: impl Into, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::Note, msg, sp.into()); self @@ -755,7 +731,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_note_once>( &mut self, sp: S, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::OnceNote, msg, sp.into()); self @@ -763,7 +739,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_warn, /// Add a warning attached to this diagnostic. - pub fn warn(&mut self, msg: impl Into) -> &mut Self { + pub fn warn(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Warning, msg, MultiSpan::new()); self } } @@ -773,7 +749,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_warn>( &mut self, sp: S, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::Warning, msg, sp.into()); self @@ -781,13 +757,13 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_help, /// Add a help message attached to this diagnostic. - pub fn help(&mut self, msg: impl Into) -> &mut Self { + pub fn help(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Help, msg, MultiSpan::new()); self } } /// This is like [`Diag::help()`], but it's only printed once. - pub fn help_once(&mut self, msg: impl Into) -> &mut Self { + pub fn help_once(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::OnceHelp, msg, MultiSpan::new()); self } @@ -814,7 +790,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_help( &mut self, sp: impl Into, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::Help, msg, sp.into()); self @@ -866,7 +842,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// In other words, multiple changes need to be applied as part of this suggestion. pub fn multipart_suggestion( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -882,7 +858,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// In other words, multiple changes need to be applied as part of this suggestion. pub fn multipart_suggestion_verbose( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -897,7 +873,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// [`Diag::multipart_suggestion()`] but you can set the [`SuggestionStyle`]. pub fn multipart_suggestion_with_style( &mut self, - msg: impl Into, + msg: impl Into, mut suggestion: Vec<(Span, String)>, applicability: Applicability, style: SuggestionStyle, @@ -924,7 +900,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self.push_suggestion(CodeSuggestion { substitutions: vec![Substitution { parts }], - msg: self.subdiagnostic_message_to_diagnostic_message(msg), + msg: msg.into(), style, applicability, }); @@ -939,7 +915,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// improve understandability. pub fn tool_only_multipart_suggestion( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -972,7 +948,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -990,7 +966,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_suggestion_with_style( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, style: SuggestionStyle, @@ -1003,7 +979,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { substitutions: vec![Substitution { parts: vec![SubstitutionPart { snippet: suggestion.to_string(), span: sp }], }], - msg: self.subdiagnostic_message_to_diagnostic_message(msg), + msg: msg.into(), style, applicability, }); @@ -1015,7 +991,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_suggestion_verbose( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -1035,7 +1011,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_suggestions( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestions: impl IntoIterator, applicability: Applicability, ) -> &mut Self { @@ -1051,7 +1027,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_suggestions_with_style( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestions: impl IntoIterator, applicability: Applicability, style: SuggestionStyle, @@ -1068,7 +1044,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { .collect(); self.push_suggestion(CodeSuggestion { substitutions, - msg: self.subdiagnostic_message_to_diagnostic_message(msg), + msg: msg.into(), style, applicability, }); @@ -1080,7 +1056,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// See also [`Diag::multipart_suggestion()`]. pub fn multipart_suggestions( &mut self, - msg: impl Into, + msg: impl Into, suggestions: impl IntoIterator>, applicability: Applicability, ) -> &mut Self { @@ -1112,7 +1088,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self.push_suggestion(CodeSuggestion { substitutions, - msg: self.subdiagnostic_message_to_diagnostic_message(msg), + msg: msg.into(), style: SuggestionStyle::ShowAlways, applicability, }); @@ -1127,7 +1103,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_suggestion_short( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -1150,7 +1126,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn span_suggestion_hidden( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -1172,7 +1148,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { pub fn tool_only_span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -1200,10 +1176,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// one value will clobber the other. Eagerly translating the /// diagnostic uses the variables defined right then, before the /// clobbering occurs. - pub fn eagerly_translate(&self, msg: impl Into) -> SubdiagMessage { + pub fn eagerly_translate(&self, msg: impl Into) -> DiagMessage { let args = self.args.iter(); - let msg = self.subdiagnostic_message_to_diagnostic_message(msg.into()); - self.dcx.eagerly_translate(msg, args) + self.dcx.eagerly_translate(msg.into(), args) } with_fn! { with_span, @@ -1256,31 +1231,18 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self } } - /// Helper function that takes a `SubdiagMessage` and returns a `DiagMessage` by - /// combining it with the primary message of the diagnostic (if translatable, otherwise it just - /// passes the user's string along). - pub(crate) fn subdiagnostic_message_to_diagnostic_message( - &self, - attr: impl Into, - ) -> DiagMessage { - self.deref().subdiagnostic_message_to_diagnostic_message(attr) - } - /// Convenience function for internal use, clients should use one of the /// public methods above. /// /// Used by `proc_macro_server` for implementing `server::Diagnostic`. - pub fn sub(&mut self, level: Level, message: impl Into, span: MultiSpan) { + pub fn sub(&mut self, level: Level, message: impl Into, span: MultiSpan) { self.deref_mut().sub(level, message, span); } /// Convenience function for internal use, clients should use one of the /// public methods above. fn sub_with_highlights(&mut self, level: Level, messages: Vec, span: MultiSpan) { - let messages = messages - .into_iter() - .map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.content), m.style)) - .collect(); + let messages = messages.into_iter().map(|m| (m.content.into(), m.style)).collect(); let sub = Subdiag { level, messages, span }; self.children.push(sub); } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 2e0afb8fc4c2..c0398b3e8da0 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -57,8 +57,8 @@ use rustc_data_structures::sync::{DynSend, Lock}; use rustc_data_structures::{AtomicRef, assert_matches}; pub use rustc_error_messages::{ DiagArg, DiagArgFromDisplay, DiagArgName, DiagArgValue, DiagMessage, FluentBundle, IntoDiagArg, - LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage, - fallback_fluent_bundle, fluent_bundle, into_diag_arg_using_display, + LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, fallback_fluent_bundle, + fluent_bundle, into_diag_arg_using_display, }; use rustc_hashes::Hash128; use rustc_lint_defs::LintExpectationId; @@ -488,12 +488,12 @@ impl DiagCtxt { self.inner.borrow_mut().emitter = emitter; } - /// Translate `message` eagerly with `args` to `SubdiagMessage::Eager`. + /// Translate `message` eagerly with `args` to `DiagMessage::Eager`. pub fn eagerly_translate<'a>( &self, message: DiagMessage, args: impl Iterator>, - ) -> SubdiagMessage { + ) -> DiagMessage { let inner = self.inner.borrow(); inner.eagerly_translate(message, args) } @@ -1423,13 +1423,13 @@ impl DiagCtxtInner { self.has_errors().or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied()) } - /// Translate `message` eagerly with `args` to `SubdiagMessage::Eager`. + /// Translate `message` eagerly with `args` to `DiagMessage::Eager`. fn eagerly_translate<'a>( &self, message: DiagMessage, args: impl Iterator>, - ) -> SubdiagMessage { - SubdiagMessage::Str(Cow::from(self.eagerly_translate_to_string(message, args))) + ) -> DiagMessage { + DiagMessage::Str(Cow::from(self.eagerly_translate_to_string(message, args))) } /// Translate `message` eagerly with `args` to `String`. @@ -1450,10 +1450,9 @@ impl DiagCtxtInner { fn eagerly_translate_for_subdiag( &self, diag: &DiagInner, - msg: impl Into, - ) -> SubdiagMessage { - let msg = diag.subdiagnostic_message_to_diagnostic_message(msg); - self.eagerly_translate(msg, diag.args.iter()) + msg: impl Into, + ) -> DiagMessage { + self.eagerly_translate(msg.into(), diag.args.iter()) } fn flush_delayed(&mut self) { diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index bf829c2d645d..746678e2865f 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -7,7 +7,7 @@ mod prelude_edition_lints; pub(crate) mod probe; mod suggest; -use rustc_errors::{Applicability, Diag, SubdiagMessage}; +use rustc_errors::{Applicability, Diag, DiagMessage}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def_id::DefId; @@ -127,7 +127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn suggest_method_call( &self, err: &mut Diag<'_>, - msg: impl Into + std::fmt::Debug, + msg: impl Into + std::fmt::Debug, method_name: Ident, self_ty: Ty<'tcx>, call_expr: &hir::Expr<'tcx>, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6aa2eae556e2..4b1faf718cd5 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -373,7 +373,6 @@ symbols! { Str, String, StructuralPartialEq, - SubdiagMessage, Subdiagnostic, SymbolIntern, Sync, diff --git a/src/doc/rustc-dev-guide/src/diagnostics/translation.md b/src/doc/rustc-dev-guide/src/diagnostics/translation.md index 58d75f54a005..e66c9430914a 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/translation.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/translation.md @@ -135,8 +135,7 @@ translation. ### Messages All of rustc's traditional diagnostic APIs (e.g. `struct_span_err` or `note`) -take any message that can be converted into a `DiagMessage` (or -`SubdiagMessage`). +take any message that can be converted into a `DiagMessage`. [`rustc_error_messages::DiagMessage`] can represent legacy non-translatable diagnostic messages and translatable messages. Non-translatable messages are @@ -149,14 +148,7 @@ with an attribute). Fluent resource (described in more detail below), or `DiagMessage`s will either be created in the macro-generated code of a diagnostic derive. -`rustc_error_messages::SubdiagMessage` is similar, it can correspond to a -legacy non-translatable diagnostic message or the name of an attribute to a -Fluent message. Translatable `SubdiagMessage`s must be combined with a -`DiagMessage` (using `DiagMessage::with_subdiagnostic_message`) to -be emitted (an attribute name on its own is meaningless without a corresponding -message identifier, which is what `DiagMessage` provides). - -Both `DiagMessage` and `SubdiagMessage` implement `Into` for any +`DiagMessage` implements `Into` for any type that can be converted into a string, and converts these into non-translatable diagnostics - this keeps all existing diagnostic calls working. diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs index 8a19039a7fe7..4ba9af58f90a 100644 --- a/src/tools/clippy/clippy_utils/src/diagnostics.rs +++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs @@ -8,7 +8,7 @@ //! Thank you! //! ~The `INTERNAL_METADATA_COLLECTOR` lint -use rustc_errors::{Applicability, Diag, DiagMessage, MultiSpan, SubdiagMessage}; +use rustc_errors::{Applicability, Diag, DiagMessage, MultiSpan}; #[cfg(debug_assertions)] use rustc_errors::{EmissionGuarantee, SubstitutionPart, Suggestions}; use rustc_hir::HirId; @@ -155,7 +155,7 @@ pub fn span_lint_and_help( span: impl Into, msg: impl Into, help_span: Option, - help: impl Into, + help: impl Into, ) { #[expect(clippy::disallowed_methods)] cx.span_lint(lint, span, |diag| { @@ -216,7 +216,7 @@ pub fn span_lint_and_note( span: impl Into, msg: impl Into, note_span: Option, - note: impl Into, + note: impl Into, ) { #[expect(clippy::disallowed_methods)] cx.span_lint(lint, span, |diag| { @@ -390,7 +390,7 @@ pub fn span_lint_and_sugg( lint: &'static Lint, sp: Span, msg: impl Into, - help: impl Into, + help: impl Into, sugg: String, applicability: Applicability, ) { diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs index e63ab03cda47..c1146de0fef1 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs @@ -19,7 +19,7 @@ extern crate rustc_session; extern crate rustc_span; extern crate core; -use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; +use rustc_errors::{Applicability, DiagMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs index ca803d450b92..fa2b6e907a26 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs @@ -26,7 +26,7 @@ extern crate rustc_middle; use rustc_middle::ty::Ty; extern crate rustc_errors; -use rustc_errors::{Applicability, DiagMessage, ErrCode, MultiSpan, SubdiagMessage}; +use rustc_errors::{Applicability, DiagMessage, ErrCode, MultiSpan}; extern crate rustc_session; diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs index 99b2cba89da4..c7636bca80b5 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs @@ -17,7 +17,7 @@ extern crate rustc_session; extern crate rustc_span; extern crate core; -use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; +use rustc_errors::{Applicability, DiagMessage}; use rustc_macros::Subdiagnostic; use rustc_span::Span; From b1847b59cc0fecb8973d82366b72f994e8841331 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 10 Feb 2026 09:13:45 +0000 Subject: [PATCH 3490/3801] Remove SubdiagMessage in favour of the identical DiagMessage --- clippy_utils/src/diagnostics.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_utils/src/diagnostics.rs b/clippy_utils/src/diagnostics.rs index 8a19039a7fe7..4ba9af58f90a 100644 --- a/clippy_utils/src/diagnostics.rs +++ b/clippy_utils/src/diagnostics.rs @@ -8,7 +8,7 @@ //! Thank you! //! ~The `INTERNAL_METADATA_COLLECTOR` lint -use rustc_errors::{Applicability, Diag, DiagMessage, MultiSpan, SubdiagMessage}; +use rustc_errors::{Applicability, Diag, DiagMessage, MultiSpan}; #[cfg(debug_assertions)] use rustc_errors::{EmissionGuarantee, SubstitutionPart, Suggestions}; use rustc_hir::HirId; @@ -155,7 +155,7 @@ pub fn span_lint_and_help( span: impl Into, msg: impl Into, help_span: Option, - help: impl Into, + help: impl Into, ) { #[expect(clippy::disallowed_methods)] cx.span_lint(lint, span, |diag| { @@ -216,7 +216,7 @@ pub fn span_lint_and_note( span: impl Into, msg: impl Into, note_span: Option, - note: impl Into, + note: impl Into, ) { #[expect(clippy::disallowed_methods)] cx.span_lint(lint, span, |diag| { @@ -390,7 +390,7 @@ pub fn span_lint_and_sugg( lint: &'static Lint, sp: Span, msg: impl Into, - help: impl Into, + help: impl Into, sugg: String, applicability: Applicability, ) { From 954f483557e24c8559bde3d4b2ef4c48f2b34651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 17:57:43 +0100 Subject: [PATCH 3491/3801] Port `rustc_never_type_options` to the new attribute parser --- .../src/attributes/rustc_internal.rs | 82 +++++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 3 +- .../rustc_hir/src/attrs/data_structures.rs | 50 ++++++++++- .../rustc_hir/src/attrs/encode_cross_crate.rs | 3 +- compiler/rustc_hir_typeck/src/fallback.rs | 12 +-- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 24 +----- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 55 +------------ compiler/rustc_passes/src/check_attr.rs | 4 +- .../malformed-never-type-options.rs | 2 +- .../malformed-never-type-options.stderr | 12 +-- 10 files changed, 148 insertions(+), 99 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 52268def8718..218488898e4b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -420,6 +420,88 @@ impl NoArgsAttributeParser for RustcCaptureAnalysisParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCaptureAnalysis; } +pub(crate) struct RustcNeverTypeOptionsParser; + +impl SingleAttributeParser for RustcNeverTypeOptionsParser { + const PATH: &[Symbol] = &[sym::rustc_never_type_options]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const TEMPLATE: AttributeTemplate = template!(List: &[ + r#"fallback = "unit", "never", "no""#, + r#"diverging_block_default = "unit", "never""#, + ]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(list) = args.list() else { + cx.expected_list(cx.attr_span, args); + return None; + }; + + let mut fallback = None::; + let mut diverging_block_default = None::; + + for arg in list.mixed() { + let Some(meta) = arg.meta_item() else { + cx.expected_name_value(arg.span(), None); + continue; + }; + + let res = match meta.ident().map(|i| i.name) { + Some(sym::fallback) => &mut fallback, + Some(sym::diverging_block_default) => &mut diverging_block_default, + _ => { + cx.expected_specific_argument( + meta.path().span(), + &[sym::fallback, sym::diverging_block_default], + ); + continue; + } + }; + + let Some(nv) = meta.args().name_value() else { + cx.expected_name_value(meta.span(), None); + continue; + }; + + let Some(field) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + continue; + }; + + if res.is_some() { + cx.duplicate_key(meta.span(), meta.ident().unwrap().name); + continue; + } + + *res = Some(Ident { name: field, span: nv.value_span }); + } + + let fallback = match fallback { + None => None, + Some(Ident { name: sym::unit, .. }) => Some(DivergingFallbackBehavior::ToUnit), + Some(Ident { name: sym::never, .. }) => Some(DivergingFallbackBehavior::ToNever), + Some(Ident { name: sym::no, .. }) => Some(DivergingFallbackBehavior::NoFallback), + Some(Ident { span, .. }) => { + cx.expected_specific_argument_strings(span, &[sym::unit, sym::never, sym::no]); + return None; + } + }; + + let diverging_block_default = match diverging_block_default { + None => None, + Some(Ident { name: sym::unit, .. }) => Some(DivergingBlockBehavior::Unit), + Some(Ident { name: sym::never, .. }) => Some(DivergingBlockBehavior::Never), + Some(Ident { span, .. }) => { + cx.expected_specific_argument_strings(span, &[sym::unit, sym::no]); + return None; + } + }; + + Some(AttributeKind::RustcNeverTypeOptions { fallback, diverging_block_default }) + } +} + pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 16e4a6452210..4d7dc41f1546 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -147,9 +147,9 @@ attribute_parsers!( DocParser, MacroUseParser, NakedParser, + RustcCguTestAttributeParser, StabilityParser, UsedParser, - RustcCguTestAttributeParser, // tidy-alphabetical-end // tidy-alphabetical-start @@ -210,6 +210,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 09b51cef3c1a..e5f45928fe7b 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -63,6 +63,44 @@ pub enum CguFields { PartitionCodegened { cfg: Symbol, module: Symbol }, ExpectedCguReuse { cfg: Symbol, module: Symbol, kind: CguKind }, } + +#[derive(Copy, Clone, PartialEq, Debug, PrintAttribute)] +#[derive(HashStable_Generic, Encodable, Decodable)] +pub enum DivergingFallbackBehavior { + /// Always fallback to `()` (aka "always spontaneous decay") + ToUnit, + /// Always fallback to `!` (which should be equivalent to never falling back + not making + /// never-to-any coercions unless necessary) + ToNever, + /// Don't fallback at all + NoFallback, +} + +#[derive(Copy, Clone, PartialEq, Debug, PrintAttribute, Default)] +#[derive(HashStable_Generic, Encodable, Decodable)] +pub enum DivergingBlockBehavior { + /// This is the current stable behavior: + /// + /// ```rust + /// { + /// return; + /// } // block has type = !, even though we are supposedly dropping it with `;` + /// ``` + #[default] + Never, + + /// Alternative behavior: + /// + /// ```ignore (very-unstable-new-attribute) + /// #![rustc_never_type_options(diverging_block_default = "unit")] + /// { + /// return; + /// } // block has type = (), since we are dropping `!` from `return` with `;` + /// ``` + Unit, +} + +#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)] pub enum InlineAttr { None, Hint, @@ -1069,6 +1107,9 @@ pub enum AttributeKind { /// Represents `#[rustc_capture_analysis]` RustcCaptureAnalysis, + /// Represents `#[rustc_expected_cgu_reuse]`, `#[rustc_partition_codegened]` and `#[rustc_partition_reused]`. + RustcCguTestAttr(ThinVec<(Span, CguFields)>), + /// Represents `#[rustc_clean]` RustcClean(ThinVec), @@ -1139,9 +1180,6 @@ pub enum AttributeKind { /// Represents `#[rustc_evaluate_where_clauses]` RustcEvaluateWhereClauses, - /// Represents `#[rustc_expected_cgu_reuse]`, `#[rustc_partition_codegened]` and `#[rustc_partition_reused]`. - RustcCguTestAttr(ThinVec<(Span, CguFields)>), - /// Represents `#[rustc_has_incoherent_inherent_impls]` RustcHasIncoherentInherentImpls, @@ -1199,6 +1237,12 @@ pub enum AttributeKind { /// Represents `#[rustc_never_returns_null_ptr]` RustcNeverReturnsNullPointer, + /// Represents `#[rustc_never_type_options]`. + RustcNeverTypeOptions { + fallback: Option, + diverging_block_default: Option, + }, + /// Represents `#[rustc_no_implicit_autorefs]` RustcNoImplicitAutorefs, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 4c68d51e6334..5384a12a0ffb 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -99,6 +99,7 @@ impl AttributeKind { RustcBodyStability { .. } => No, RustcBuiltinMacro { .. } => Yes, RustcCaptureAnalysis => No, + RustcCguTestAttr { .. } => No, RustcClean { .. } => No, RustcCoherenceIsCore(..) => No, RustcCoinductive(..) => No, @@ -139,6 +140,7 @@ impl AttributeKind { RustcMir(..) => Yes, RustcMustImplementOneOf { .. } => No, RustcNeverReturnsNullPointer => Yes, + RustcNeverTypeOptions { .. } => No, RustcNoImplicitAutorefs => Yes, RustcNoImplicitBounds => No, RustcNonConstTraitMethod => No, // should be reported via other queries like `constness` @@ -149,7 +151,6 @@ impl AttributeKind { RustcOffloadKernel => Yes, RustcOutlives => No, RustcParenSugar(..) => No, - RustcCguTestAttr { .. } => No, RustcPassByValue(..) => Yes, RustcPassIndirectlyInNonRusticAbis(..) => No, RustcPreserveUbChecks => No, diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 727666de3c47..2e421c610e7a 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -7,6 +7,7 @@ use rustc_data_structures::graph::{self}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::HirId; +use rustc_hir::attrs::DivergingFallbackBehavior; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{InferKind, Visitor}; @@ -19,17 +20,6 @@ use tracing::debug; use crate::{FnCtxt, errors}; -#[derive(Copy, Clone)] -pub(crate) enum DivergingFallbackBehavior { - /// Always fallback to `()` (aka "always spontaneous decay") - ToUnit, - /// Always fallback to `!` (which should be equivalent to never falling back + not making - /// never-to-any coercions unless necessary) - ToNever, - /// Don't fallback at all - NoFallback, -} - impl<'tcx> FnCtxt<'_, 'tcx> { /// Performs type inference fallback, setting [`FnCtxt::diverging_fallback_has_occurred`] /// if the never type fallback has occurred. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 2e85410c8960..54d8306936dd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -5,6 +5,7 @@ use itertools::Itertools; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, a_or_an, listify, pluralize}; +use rustc_hir::attrs::DivergingBlockBehavior; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; @@ -47,29 +48,6 @@ rustc_index::newtype_index! { pub(crate) struct GenericIdx {} } -#[derive(Clone, Copy, Default)] -pub(crate) enum DivergingBlockBehavior { - /// This is the current stable behavior: - /// - /// ```rust - /// { - /// return; - /// } // block has type = !, even though we are supposedly dropping it with `;` - /// ``` - #[default] - Never, - - /// Alternative behavior: - /// - /// ```ignore (very-unstable-new-attribute) - /// #![rustc_never_type_options(diverging_block_default = "unit")] - /// { - /// return; - /// } // block has type = (), since we are dropping `!` from `return` with `;` - /// ``` - Unit, -} - impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn check_casts(&mut self) { let mut deferred_cast_checks = self.root_ctxt.deferred_cast_checks.borrow_mut(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index c875e2e50d70..412df9162e9f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -10,8 +10,9 @@ use std::ops::Deref; use hir::def_id::CRATE_DEF_ID; use rustc_errors::DiagCtxtHandle; +use rustc_hir::attrs::{AttributeKind, DivergingBlockBehavior, DivergingFallbackBehavior}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, HirId, ItemLocalMap}; +use rustc_hir::{self as hir, HirId, ItemLocalMap, find_attr}; use rustc_hir_analysis::hir_ty_lowering::{ HirTyLowerer, InherentAssocCandidate, RegionInferReason, }; @@ -19,15 +20,13 @@ use rustc_infer::infer::{self, RegionVariableOrigin}; use rustc_infer::traits::{DynCompatibilityViolation, Obligation}; use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Session; -use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym}; +use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span}; use rustc_trait_selection::error_reporting::TypeErrCtxt; use rustc_trait_selection::traits::{ self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, }; use crate::coercion::CoerceMany; -use crate::fallback::DivergingFallbackBehavior; -use crate::fn_ctxt::checks::DivergingBlockBehavior; use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt}; /// The `FnCtxt` stores type-checking context needed to type-check bodies of @@ -517,51 +516,5 @@ fn parse_never_type_options_attr( // Error handling is dubious here (unwraps), but that's probably fine for an internal attribute. // Just don't write incorrect attributes <3 - let mut fallback = None; - let mut block = None; - - let items = if tcx.features().rustc_attrs() { - tcx.get_attr(CRATE_DEF_ID, sym::rustc_never_type_options) - .map(|attr| attr.meta_item_list().unwrap()) - } else { - None - }; - let items = items.unwrap_or_default(); - - for item in items { - if item.has_name(sym::fallback) && fallback.is_none() { - let mode = item.value_str().unwrap(); - match mode { - sym::unit => fallback = Some(DivergingFallbackBehavior::ToUnit), - sym::never => fallback = Some(DivergingFallbackBehavior::ToNever), - sym::no => fallback = Some(DivergingFallbackBehavior::NoFallback), - _ => { - tcx.dcx().span_err(item.span(), format!("unknown never type fallback mode: `{mode}` (supported: `unit`, `niko`, `never` and `no`)")); - } - }; - continue; - } - - if item.has_name(sym::diverging_block_default) && block.is_none() { - let default = item.value_str().unwrap(); - match default { - sym::unit => block = Some(DivergingBlockBehavior::Unit), - sym::never => block = Some(DivergingBlockBehavior::Never), - _ => { - tcx.dcx().span_err(item.span(), format!("unknown diverging block default: `{default}` (supported: `unit` and `never`)")); - } - }; - continue; - } - - tcx.dcx().span_err( - item.span(), - format!( - "unknown or duplicate never type option: `{}` (supported: `fallback`, `diverging_block_default`)", - item.name().unwrap() - ), - ); - } - - (fallback, block) + find_attr!(tcx.get_all_attrs(CRATE_DEF_ID), AttributeKind::RustcNeverTypeOptions {fallback, diverging_block_default} => (*fallback, *diverging_block_default)).unwrap_or_default() } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index db5c33fcb17c..4f29b5e715d6 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -295,6 +295,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcBodyStability { .. } | AttributeKind::RustcBuiltinMacro { .. } | AttributeKind::RustcCaptureAnalysis + | AttributeKind::RustcCguTestAttr(..) | AttributeKind::RustcClean(..) | AttributeKind::RustcCoherenceIsCore(..) | AttributeKind::RustcCoinductive(..) @@ -332,6 +333,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcMain | AttributeKind::RustcMir(_) | AttributeKind::RustcNeverReturnsNullPointer + | AttributeKind::RustcNeverTypeOptions {..} | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcNoImplicitBounds | AttributeKind::RustcNonConstTraitMethod @@ -341,7 +343,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcOffloadKernel | AttributeKind::RustcOutlives | AttributeKind::RustcParenSugar(..) - | AttributeKind::RustcCguTestAttr(..) | AttributeKind::RustcPassByValue (..) | AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) | AttributeKind::RustcPreserveUbChecks @@ -405,7 +406,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_test_marker | sym::rustc_layout | sym::rustc_proc_macro_decls - | sym::rustc_never_type_options | sym::rustc_autodiff | sym::rustc_capture_analysis | sym::rustc_mir diff --git a/tests/ui/attributes/malformed-never-type-options.rs b/tests/ui/attributes/malformed-never-type-options.rs index 0c384be0e226..7dd7a854ed2e 100644 --- a/tests/ui/attributes/malformed-never-type-options.rs +++ b/tests/ui/attributes/malformed-never-type-options.rs @@ -2,7 +2,7 @@ //! The `rustc_*` attribute is malformed, but ICEing without a `feature(rustc_attrs)` is still bad. #![rustc_never_type_options(: Unsize = "hi")] -//~^ ERROR expected unsuffixed literal, found `:` +//~^ ERROR expected a literal //~| ERROR use of an internal attribute fn main() {} diff --git a/tests/ui/attributes/malformed-never-type-options.stderr b/tests/ui/attributes/malformed-never-type-options.stderr index 0d2ff4881f2a..98870c8bdded 100644 --- a/tests/ui/attributes/malformed-never-type-options.stderr +++ b/tests/ui/attributes/malformed-never-type-options.stderr @@ -1,9 +1,3 @@ -error: expected unsuffixed literal, found `:` - --> $DIR/malformed-never-type-options.rs:4:29 - | -LL | #![rustc_never_type_options(: Unsize = "hi")] - | ^ - error[E0658]: use of an internal attribute --> $DIR/malformed-never-type-options.rs:4:1 | @@ -14,6 +8,12 @@ LL | #![rustc_never_type_options(: Unsize = "hi")] = note: the `#[rustc_never_type_options]` attribute is an internal implementation detail that will never be stable = note: `rustc_never_type_options` is used to experiment with never type fallback and work on never type stabilization +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `:` + --> $DIR/malformed-never-type-options.rs:4:29 + | +LL | #![rustc_never_type_options(: Unsize = "hi")] + | ^ + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. From 2377d355ad61ce1bf5cb33632e101d3016cf152e Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 10 Feb 2026 10:17:59 +0100 Subject: [PATCH 3492/3801] Update documentation of rustc_macros --- compiler/rustc_macros/src/diagnostics/mod.rs | 115 ++++++------------- 1 file changed, 35 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 09f05ce972f1..a036e61c3789 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -21,36 +21,25 @@ use synstructure::Structure; /// # extern crate rust_middle; /// # use rustc_middle::ty::Ty; /// #[derive(Diagnostic)] -/// #[diag(borrowck_move_out_of_borrow, code = E0505)] -/// pub struct MoveOutOfBorrowError<'tcx> { +/// #[diag("this is an example message", code = E0123)] +/// pub(crate) struct ExampleError<'tcx> { /// pub name: Ident, /// pub ty: Ty<'tcx>, /// #[primary_span] -/// #[label] +/// #[label("with a label")] /// pub span: Span, -/// #[label(first_borrow_label)] -/// pub first_borrow_span: Span, -/// #[suggestion(code = "{name}.clone()")] -/// pub clone_sugg: Option<(Span, Applicability)> +/// #[label("with a label")] +/// pub other_span: Span, +/// #[suggestion("with a suggestion", code = "{name}.clone()")] +/// pub opt_sugg: Option<(Span, Applicability)>, /// } /// ``` /// -/// ```fluent -/// move_out_of_borrow = cannot move out of {$name} because it is borrowed -/// .label = cannot move out of borrow -/// .first_borrow_label = `{$ty}` first borrowed here -/// .suggestion = consider cloning here -/// ``` -/// /// Then, later, to emit the error: /// /// ```ignore (rust) -/// sess.emit_err(MoveOutOfBorrowError { -/// expected, -/// actual, -/// span, -/// first_borrow_span, -/// clone_sugg: Some(suggestion, Applicability::MachineApplicable), +/// sess.emit_err(ExampleError { +/// name, ty, span, other_span, opt_sugg /// }); /// ``` /// @@ -65,38 +54,24 @@ pub(super) fn diagnostic_derive(s: Structure<'_>) -> TokenStream { /// /// ```ignore (rust) /// #[derive(LintDiagnostic)] -/// #[diag(lint_atomic_ordering_invalid_fail_success)] -/// pub struct AtomicOrderingInvalidLint { -/// method: Symbol, -/// success_ordering: Symbol, -/// fail_ordering: Symbol, -/// #[label(fail_label)] -/// fail_order_arg_span: Span, -/// #[label(success_label)] -/// #[suggestion( -/// code = "std::sync::atomic::Ordering::{success_suggestion}", -/// applicability = "maybe-incorrect" +/// #[diag("unused attribute")] +/// pub(crate) struct UnusedAttribute { +/// #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] +/// pub this: Span, +/// #[note("attribute also specified here")] +/// pub other: Span, +/// #[warning( +/// "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" /// )] -/// success_order_arg_span: Span, +/// pub warning: bool, /// } /// ``` /// -/// ```fluent -/// lint_atomic_ordering_invalid_fail_success = `{$method}`'s success ordering must be at least as strong as its failure ordering -/// .fail_label = `{$fail_ordering}` failure ordering -/// .success_label = `{$success_ordering}` success ordering -/// .suggestion = consider using `{$success_suggestion}` success ordering instead -/// ``` -/// /// Then, later, to emit the error: /// /// ```ignore (rust) -/// cx.emit_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { -/// method, -/// success_ordering, -/// fail_ordering, -/// fail_order_arg_span, -/// success_order_arg_span, +/// cx.emit_span_lint(UNUSED_ATTRIBUTES, span, UnusedAttribute { +/// ... /// }); /// ``` /// @@ -112,45 +87,25 @@ pub(super) fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream { /// /// ```ignore (rust) /// #[derive(Subdiagnostic)] -/// pub enum ExpectedIdentifierLabel<'tcx> { -/// #[label(expected_identifier)] -/// WithoutFound { -/// #[primary_span] -/// span: Span, -/// } -/// #[label(expected_identifier_found)] -/// WithFound { -/// #[primary_span] -/// span: Span, -/// found: String, -/// } -/// } -/// -/// #[derive(Subdiagnostic)] -/// #[suggestion(style = "verbose",parser::raw_identifier)] -/// pub struct RawIdentifierSuggestion<'tcx> { -/// #[primary_span] -/// span: Span, -/// #[applicability] -/// applicability: Applicability, -/// ident: Ident, +/// pub(crate) enum BuiltinUnusedDocCommentSub { +/// #[help("use `//` for a plain comment")] +/// PlainHelp, +/// #[help("use `/* */` for a plain comment")] +/// BlockHelp, /// } /// ``` -/// -/// ```fluent -/// parser_expected_identifier = expected identifier -/// -/// parser_expected_identifier_found = expected identifier, found {$found} -/// -/// parser_raw_identifier = escape `{$ident}` to use it as an identifier -/// ``` -/// -/// Then, later, to add the subdiagnostic: +/// Then, later, use the subdiagnostic in a diagnostic: /// /// ```ignore (rust) -/// diag.subdiagnostic(ExpectedIdentifierLabel::WithoutFound { span }); -/// -/// diag.subdiagnostic(RawIdentifierSuggestion { span, applicability, ident }); +/// #[derive(LintDiagnostic)] +/// #[diag("unused doc comment")] +/// pub(crate) struct BuiltinUnusedDocComment<'a> { +/// pub kind: &'a str, +/// #[label("rustdoc does not generate documentation for {$kind}")] +/// pub label: Span, +/// #[subdiagnostic] +/// pub sub: BuiltinUnusedDocCommentSub, +/// } /// ``` pub(super) fn subdiagnostic_derive(s: Structure<'_>) -> TokenStream { SubdiagnosticDerive::new().into_tokens(s) From f4c135f91bfd13920faf671f044ea037ab7f7ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 17:57:43 +0100 Subject: [PATCH 3493/3801] Port `rustc_trivial_field_reads` to the new attribute parser --- .../src/attributes/rustc_internal.rs | 9 +++++ compiler/rustc_attr_parsing/src/context.rs | 36 ++++++++++++++----- .../rustc_hir/src/attrs/data_structures.rs | 3 ++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_passes/src/dead.rs | 8 +++-- 6 files changed, 48 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 218488898e4b..09d0cffe3966 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -502,6 +502,15 @@ impl SingleAttributeParser for RustcNeverTypeOptionsParser { } } +pub(crate) struct RustcTrivialFieldReadsParser; + +impl NoArgsAttributeParser for RustcTrivialFieldReadsParser { + const PATH: &[Symbol] = &[sym::rustc_trivial_field_reads]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads; +} + pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 4d7dc41f1546..c42a9c6031b4 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -169,6 +169,32 @@ attribute_parsers!( // tidy-alphabetical-end // tidy-alphabetical-start +%%%%%%% Changes from base to side #1 +%%%%%%%%%%% Changes from base to side #1 + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, ++ Single>, ++++++++ Contents of side #2 + Single>, ++++++++++++ Contents of side #2 +- Single>, + Single>, +<<<<<<< Conflict 1 of 1 +<<<<<<<<<<< Conflict 2 of 2 +>>>>>>> Conflict 1 of 1 ends + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, Single, Single, Single, @@ -213,6 +239,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, @@ -297,14 +324,7 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, - Single>, - Single>, - Single>, - Single>, - Single>, - Single>, - Single>, +>>>>>>>>>>> Conflict 2 of 2 ends // tidy-alphabetical-end ]; ); diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index e5f45928fe7b..123a38131ecd 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1326,6 +1326,9 @@ pub enum AttributeKind { /// Represents `#[rustc_then_this_would_need]` RustcThenThisWouldNeed(Span, ThinVec), + /// Represents `#[rustc_trivial_field_reads]` + RustcTrivialFieldReads, + /// Represents `#[rustc_unsafe_specialization_marker]`. RustcUnsafeSpecializationMarker(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 5384a12a0ffb..9d7483dab125 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -167,6 +167,7 @@ impl AttributeKind { RustcStrictCoherence(..) => Yes, RustcSymbolName(..) => Yes, RustcThenThisWouldNeed(..) => No, + RustcTrivialFieldReads => Yes, RustcUnsafeSpecializationMarker(..) => No, RustcVariance => No, RustcVarianceOfOpaques => No, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4f29b5e715d6..a9d044ec9ecc 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -358,6 +358,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcStrictCoherence(..) | AttributeKind::RustcSymbolName(..) | AttributeKind::RustcThenThisWouldNeed(..) + | AttributeKind::RustcTrivialFieldReads | AttributeKind::RustcUnsafeSpecializationMarker(..) | AttributeKind::RustcVariance | AttributeKind::RustcVarianceOfOpaques @@ -399,7 +400,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_no_mir_inline | sym::rustc_nonnull_optimization_guaranteed | sym::rustc_inherit_overflow_checks - | sym::rustc_trivial_field_reads | sym::rustc_on_unimplemented | sym::rustc_do_not_const_check | sym::rustc_doc_primitive diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 3294b6802a71..75bac9eff2c7 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -10,10 +10,11 @@ use hir::def_id::{LocalDefIdMap, LocalDefIdSet}; use rustc_abi::FieldIdx; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{ErrorGuaranteed, MultiSpan}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{self as hir, Node, PatKind, QPath}; +use rustc_hir::{self as hir, Node, PatKind, QPath, find_attr}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::privacy::Level; use rustc_middle::query::Providers; @@ -380,7 +381,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { && let impl_of = self.tcx.parent(impl_item.owner_id.to_def_id()) && self.tcx.is_automatically_derived(impl_of) && let trait_ref = self.tcx.impl_trait_ref(impl_of).instantiate_identity() - && self.tcx.has_attr(trait_ref.def_id, sym::rustc_trivial_field_reads) + && find_attr!( + self.tcx.get_all_attrs(trait_ref.def_id), + AttributeKind::RustcTrivialFieldReads + ) { if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() && let Some(adt_def_id) = adt_def.did().as_local() From eab26e329b246f98f86f64f935c9ef49d85ade04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 17:57:43 +0100 Subject: [PATCH 3494/3801] Port `rustc_no_mir_inline` to the new attribute parser --- .../src/attributes/rustc_internal.rs | 15 ++++++ compiler/rustc_attr_parsing/src/context.rs | 47 ++++++++----------- .../rustc_hir/src/attrs/data_structures.rs | 3 ++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_mir_transform/src/check_inline.rs | 4 +- compiler/rustc_passes/src/check_attr.rs | 2 +- 6 files changed, 41 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 09d0cffe3966..d71fa791193f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -511,6 +511,21 @@ impl NoArgsAttributeParser for RustcTrivialFieldReadsParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads; } +pub(crate) struct RustcNoMirInlineParser; + +impl NoArgsAttributeParser for RustcNoMirInlineParser { + const PATH: &[Symbol] = &[sym::rustc_no_mir_inline]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoMirInline; +} + pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index c42a9c6031b4..d6e9caeafc8a 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -169,32 +169,6 @@ attribute_parsers!( // tidy-alphabetical-end // tidy-alphabetical-start -%%%%%%% Changes from base to side #1 -%%%%%%%%%%% Changes from base to side #1 - Single>, - Single>, - Single>, - Single>, - Single>, - Single>, - Single>, -+ Single>, -+++++++ Contents of side #2 - Single>, -+++++++++++ Contents of side #2 -- Single>, - Single>, -<<<<<<< Conflict 1 of 1 -<<<<<<<<<<< Conflict 2 of 2 ->>>>>>> Conflict 1 of 1 ends - Single>, - Single>, - Single>, - Single>, - Single>, - Single>, - Single>, - Single>, Single, Single, Single, @@ -237,9 +211,9 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, - Single, Single, Single, Single, @@ -315,6 +289,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, @@ -324,7 +299,23 @@ attribute_parsers!( Single>, Single>, Single>, ->>>>>>>>>>> Conflict 2 of 2 ends + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, + Single>, // tidy-alphabetical-end ]; ); diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 123a38131ecd..7050bb6ea70d 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1249,6 +1249,9 @@ pub enum AttributeKind { /// Represents `#[rustc_no_implicit_bounds]` RustcNoImplicitBounds, + /// Represents `#[rustc_no_mir_inline]` + RustcNoMirInline, + /// Represents `#[rustc_non_const_trait_method]`. RustcNonConstTraitMethod, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 9d7483dab125..73ac1533cef5 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -143,6 +143,7 @@ impl AttributeKind { RustcNeverTypeOptions { .. } => No, RustcNoImplicitAutorefs => Yes, RustcNoImplicitBounds => No, + RustcNoMirInline => Yes, RustcNonConstTraitMethod => No, // should be reported via other queries like `constness` RustcNounwind => No, RustcObjcClass { .. } => No, diff --git a/compiler/rustc_mir_transform/src/check_inline.rs b/compiler/rustc_mir_transform/src/check_inline.rs index 2d1876426727..1f65bd1ba69b 100644 --- a/compiler/rustc_mir_transform/src/check_inline.rs +++ b/compiler/rustc_mir_transform/src/check_inline.rs @@ -8,7 +8,6 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::{Body, TerminatorKind}; use rustc_middle::ty; use rustc_middle::ty::TyCtxt; -use rustc_span::sym; use crate::pass_manager::MirLint; @@ -42,7 +41,8 @@ pub(super) fn is_inline_valid_on_fn<'tcx>( def_id: DefId, ) -> Result<(), &'static str> { let codegen_attrs = tcx.codegen_fn_attrs(def_id); - if tcx.has_attr(def_id, sym::rustc_no_mir_inline) { + + if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcNoMirInline) { return Err("#[rustc_no_mir_inline]"); } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a9d044ec9ecc..2287b8bf483f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -336,6 +336,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcNeverTypeOptions {..} | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcNoImplicitBounds + | AttributeKind::RustcNoMirInline | AttributeKind::RustcNonConstTraitMethod | AttributeKind::RustcNounwind | AttributeKind::RustcObjcClass { .. } @@ -397,7 +398,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::lang | sym::default_lib_allocator | sym::rustc_diagnostic_item - | sym::rustc_no_mir_inline | sym::rustc_nonnull_optimization_guaranteed | sym::rustc_inherit_overflow_checks | sym::rustc_on_unimplemented From fe7530cad2736e1cb841793c20a23a2d3d3ab2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 7 Feb 2026 17:57:43 +0100 Subject: [PATCH 3495/3801] Make `rustc_object_lifetime_default` use NoArgsAttributeParser --- .../src/attributes/rustc_internal.rs | 14 ++------------ compiler/rustc_attr_parsing/src/context.rs | 11 ++++++++++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index d71fa791193f..fa1a43058561 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -575,21 +575,11 @@ impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationPa pub(crate) struct RustcObjectLifetimeDefaultParser; -impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { +impl NoArgsAttributeParser for RustcObjectLifetimeDefaultParser { const PATH: &[Symbol] = &[sym::rustc_object_lifetime_default]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); - const TEMPLATE: AttributeTemplate = template!(Word); - - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { - if let Err(span) = args.no_args() { - cx.expected_no_args(span); - return None; - } - - Some(AttributeKind::RustcObjectLifetimeDefault) - } + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcObjectLifetimeDefault; } pub(crate) struct RustcSimdMonomorphizeLaneLimitParser; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index d6e9caeafc8a..5906d7a4d513 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -212,7 +212,6 @@ attribute_parsers!( Single, Single, Single, - Single, Single, Single, Single, @@ -292,6 +291,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, @@ -301,19 +301,28 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, + Single>, Single>, Single>, Single>, + Single>, + Single>, Single>, Single>, Single>, Single>, + Single>, + Single>, Single>, Single>, Single>, Single>, + Single>, Single>, Single>, + Single>, + Single>, Single>, Single>, // tidy-alphabetical-end From 628c37afadaea6702f95fef3b086e99980afb7ce Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 4 Dec 2025 08:55:33 +0000 Subject: [PATCH 3496/3801] Restrict the set of things that const stability can be applied --- .../src/attributes/stability.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index 1f01cadcb43e..fb204e77abc8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -244,7 +244,21 @@ impl AttributeParser for ConstStabilityParser { this.promotable = true; }), ]; - const ALLOWED_TARGETS: AllowedTargets = ALLOWED_TARGETS; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Impl { of_trait: false }), + Allow(Target::Impl { of_trait: true }), + Allow(Target::Use), // FIXME I don't think this does anything? + Allow(Target::Const), + Allow(Target::AssocConst), + Allow(Target::Trait), + Allow(Target::Static), + Allow(Target::Crate), + Allow(Target::MacroDef), // FIXME(oli-obk): remove this and eliminate the manual check for it + ]); fn finalize(mut self, cx: &FinalizeContext<'_, '_, S>) -> Option { if self.promotable { From 475b9d9819a092e1820a07c688fdc7cd7b26c6aa Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 10 Feb 2026 09:37:30 +0000 Subject: [PATCH 3497/3801] Prevent const stability attrs from being applied to macros via the normal attribute logic instead of special cased checks --- .../src/attributes/stability.rs | 1 - compiler/rustc_expand/src/base.rs | 9 --------- compiler/rustc_expand/src/errors.rs | 10 ---------- .../ui/attributes/const-stability-on-macro.rs | 6 +++--- .../const-stability-on-macro.stderr | 20 +++++++++---------- 5 files changed, 12 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index fb204e77abc8..a2be2d42b3e1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -257,7 +257,6 @@ impl AttributeParser for ConstStabilityParser { Allow(Target::Trait), Allow(Target::Static), Allow(Target::Crate), - Allow(Target::MacroDef), // FIXME(oli-obk): remove this and eliminate the manual check for it ]); fn finalize(mut self, cx: &FinalizeContext<'_, '_, S>) -> Option { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 6b3c7fe97932..91f98d475f00 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -962,15 +962,6 @@ impl SyntaxExtension { let stability = find_attr!(attrs, AttributeKind::Stability { stability, .. } => *stability); - // FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem - if let Some(sp) = - find_attr!(attrs, AttributeKind::RustcConstStability { span, .. } => *span) - { - sess.dcx().emit_err(errors::MacroConstStability { - span: sp, - head_span: sess.source_map().guess_head_span(span), - }); - } if let Some(sp) = find_attr!(attrs, AttributeKind::RustcBodyStability{ span, .. } => *span) { sess.dcx().emit_err(errors::MacroBodyStability { diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index e64bfc136d16..b6fcc13321ee 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -80,16 +80,6 @@ pub(crate) struct ResolveRelativePath { pub path: String, } -#[derive(Diagnostic)] -#[diag("macros cannot have const stability attributes")] -pub(crate) struct MacroConstStability { - #[primary_span] - #[label("invalid const stability attribute")] - pub span: Span, - #[label("const stability attribute affects this macro")] - pub head_span: Span, -} - #[derive(Diagnostic)] #[diag("macros cannot have body stability attributes")] pub(crate) struct MacroBodyStability { diff --git a/tests/ui/attributes/const-stability-on-macro.rs b/tests/ui/attributes/const-stability-on-macro.rs index af268ccd5366..4336370430d4 100644 --- a/tests/ui/attributes/const-stability-on-macro.rs +++ b/tests/ui/attributes/const-stability-on-macro.rs @@ -2,13 +2,13 @@ #![stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "foo", since = "3.3.3")] -//~^ ERROR macros cannot have const stability attributes +//~^ ERROR attribute cannot be used on macro defs macro_rules! foo { () => {}; } -#[rustc_const_unstable(feature = "bar", issue="none")] -//~^ ERROR macros cannot have const stability attributes +#[rustc_const_unstable(feature = "bar", issue = "none")] +//~^ ERROR attribute cannot be used on macro defs macro_rules! bar { () => {}; } diff --git a/tests/ui/attributes/const-stability-on-macro.stderr b/tests/ui/attributes/const-stability-on-macro.stderr index 28f31e3d4f61..a8b56edfa59d 100644 --- a/tests/ui/attributes/const-stability-on-macro.stderr +++ b/tests/ui/attributes/const-stability-on-macro.stderr @@ -1,20 +1,18 @@ -error: macros cannot have const stability attributes +error: `#[rustc_const_stable]` attribute cannot be used on macro defs --> $DIR/const-stability-on-macro.rs:4:1 | LL | #[rustc_const_stable(feature = "foo", since = "3.3.3")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute -LL | -LL | macro_rules! foo { - | ---------------- const stability attribute affects this macro + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_const_stable]` can be applied to associated consts, constants, crates, functions, impl blocks, statics, traits, and use statements -error: macros cannot have const stability attributes +error: `#[rustc_const_unstable]` attribute cannot be used on macro defs --> $DIR/const-stability-on-macro.rs:10:1 | -LL | #[rustc_const_unstable(feature = "bar", issue="none")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute -LL | -LL | macro_rules! bar { - | ---------------- const stability attribute affects this macro +LL | #[rustc_const_unstable(feature = "bar", issue = "none")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_const_unstable]` can be applied to associated consts, constants, crates, functions, impl blocks, statics, traits, and use statements error: aborting due to 2 previous errors From 12dbc1bc635f6b4c86e1316a2bf4ca59749f9f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sun, 8 Feb 2026 22:14:00 +0100 Subject: [PATCH 3498/3801] remove 'static in many places --- .../src/attributes/allow_unstable.rs | 2 +- .../src/attributes/inline.rs | 4 ++-- .../rustc_attr_parsing/src/attributes/repr.rs | 4 ++-- .../src/attributes/rustc_internal.rs | 10 +++++----- compiler/rustc_attr_parsing/src/context.rs | 18 ------------------ 5 files changed, 10 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index d825d770fa35..4f1a8cd8b403 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -29,7 +29,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser { pub(crate) struct UnstableFeatureBoundParser; impl CombineAttributeParser for UnstableFeatureBoundParser { - const PATH: &'static [rustc_span::Symbol] = &[sym::unstable_feature_bound]; + const PATH: &[rustc_span::Symbol] = &[sym::unstable_feature_bound]; type Item = (Symbol, Span); const CONVERT: ConvertFn = |items, _| AttributeKind::UnstableFeatureBound(items); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index f6aab9ea0ee2..767200bfa9bf 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -10,7 +10,7 @@ use super::prelude::*; pub(crate) struct InlineParser; impl SingleAttributeParser for InlineParser { - const PATH: &'static [Symbol] = &[sym::inline]; + const PATH: &[Symbol] = &[sym::inline]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ @@ -67,7 +67,7 @@ impl SingleAttributeParser for InlineParser { pub(crate) struct RustcForceInlineParser; impl SingleAttributeParser for RustcForceInlineParser { - const PATH: &'static [Symbol] = &[sym::rustc_force_inline]; + const PATH: &[Symbol] = &[sym::rustc_force_inline]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 34d4957edc70..fb0b8df65284 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -272,7 +272,7 @@ fn parse_alignment(node: &LitKind) -> Result { pub(crate) struct AlignParser(Option<(Align, Span)>); impl AlignParser { - const PATH: &'static [Symbol] = &[sym::rustc_align]; + const PATH: &[Symbol] = &[sym::rustc_align]; const TEMPLATE: AttributeTemplate = template!(List: &[""]); fn parse(&mut self, cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) { @@ -329,7 +329,7 @@ impl AttributeParser for AlignParser { pub(crate) struct AlignStaticParser(AlignParser); impl AlignStaticParser { - const PATH: &'static [Symbol] = &[sym::rustc_align_static]; + const PATH: &[Symbol] = &[sym::rustc_align_static]; const TEMPLATE: AttributeTemplate = AlignParser::TEMPLATE; fn parse(&mut self, cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) { diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index fa1a43058561..0d19dc25d402 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -18,7 +18,7 @@ use crate::session_diagnostics::{ pub(crate) struct RustcMainParser; impl NoArgsAttributeParser for RustcMainParser { - const PATH: &'static [Symbol] = &[sym::rustc_main]; + const PATH: &[Symbol] = &[sym::rustc_main]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain; @@ -103,7 +103,7 @@ impl NoArgsAttributeParser for RustcNoImplicitAutorefsParser { pub(crate) struct RustcLayoutScalarValidRangeStartParser; impl SingleAttributeParser for RustcLayoutScalarValidRangeStartParser { - const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_start]; + const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_start]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); @@ -118,7 +118,7 @@ impl SingleAttributeParser for RustcLayoutScalarValidRangeStartPars pub(crate) struct RustcLayoutScalarValidRangeEndParser; impl SingleAttributeParser for RustcLayoutScalarValidRangeEndParser { - const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_end]; + const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_end]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); @@ -822,7 +822,7 @@ impl CombineAttributeParser for RustcMirParser { pub(crate) struct RustcNonConstTraitMethodParser; impl NoArgsAttributeParser for RustcNonConstTraitMethodParser { - const PATH: &'static [Symbol] = &[sym::rustc_non_const_trait_method]; + const PATH: &[Symbol] = &[sym::rustc_non_const_trait_method]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Method(MethodKind::Trait { body: true })), @@ -1067,7 +1067,7 @@ impl NoArgsAttributeParser for RustcInsignificantDtorParser { pub(crate) struct RustcEffectiveVisibilityParser; impl NoArgsAttributeParser for RustcEffectiveVisibilityParser { - const PATH: &'static [Symbol] = &[sym::rustc_effective_visibility]; + const PATH: &[Symbol] = &[sym::rustc_effective_visibility]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Use), diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 5906d7a4d513..47b988bcf338 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -211,7 +211,6 @@ attribute_parsers!( Single, Single, Single, - Single, Single, Single, Single, @@ -300,30 +299,13 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, - Single>, - Single>, Single>, Single>, - Single>, - Single>, - Single>, - Single>, Single>, Single>, - Single>, - Single>, - Single>, - Single>, Single>, Single>, - Single>, - Single>, Single>, - Single>, - Single>, - Single>, - Single>, Single>, // tidy-alphabetical-end ]; From 32e49a8b4016265459a39ca0c7cf193a76dfe814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Tue, 10 Feb 2026 12:04:09 +0100 Subject: [PATCH 3499/3801] Reenable a GCI+mGCA+GCPT test case --- .../assoc-const-bindings.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/ui/generic-const-items/assoc-const-bindings.rs b/tests/ui/generic-const-items/assoc-const-bindings.rs index 2bf4bea16deb..c187c87c7763 100644 --- a/tests/ui/generic-const-items/assoc-const-bindings.rs +++ b/tests/ui/generic-const-items/assoc-const-bindings.rs @@ -1,35 +1,33 @@ //@ check-pass #![feature(generic_const_items, min_generic_const_args)] -#![feature(adt_const_params)] -#![allow(incomplete_features)] +#![feature(adt_const_params, unsized_const_params, generic_const_parameter_types)] +#![expect(incomplete_features)] + +use std::marker::{ConstParamTy, ConstParamTy_}; trait Owner { type const C: u32; type const K: u32; - // #[type_const] - // const Q: Maybe; + type const Q: Maybe; } impl Owner for () { type const C: u32 = N; type const K: u32 = const { 99 + 1 }; - // FIXME(mgca): re-enable once we properly support ctors and generics on paths - // #[type_const] - // const Q: Maybe = Maybe::Nothing; + type const Q: Maybe = Maybe::Nothing::; } fn take0(_: impl Owner = { N }>) {} fn take1(_: impl Owner = 100>) {} -// FIXME(mgca): re-enable once we properly support ctors and generics on paths -// fn take2(_: impl Owner = { Maybe::Just(()) }>) {} +fn take2(_: impl Owner = { Maybe::Just::<()>(()) }>) {} fn main() { take0::<128>(()); take1(()); } -#[derive(PartialEq, Eq, std::marker::ConstParamTy)] +#[derive(PartialEq, Eq, ConstParamTy)] enum Maybe { Nothing, Just(T), From 85e8282fabe0beb071aca75a2c3a51068eaa1c12 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 24 Jan 2025 15:57:13 +0000 Subject: [PATCH 3500/3801] Start using pattern types in libcore --- .../src/debuginfo/metadata.rs | 13 ++- .../rustc_const_eval/src/interpret/call.rs | 3 + library/core/src/num/niche_types.rs | 103 +++++++----------- src/bootstrap/src/core/build_steps/test.rs | 3 + .../cast_fn_ptr_invalid_callee_ret.stderr | 2 +- .../cast_fn_ptr_invalid_caller_arg.stderr | 2 +- .../consts/const-eval/raw-bytes.32bit.stderr | 4 +- .../consts/const-eval/raw-bytes.64bit.stderr | 4 +- tests/ui/consts/const-eval/ub-nonnull.stderr | 4 +- tests/ui/lint/invalid_value.stderr | 2 - 10 files changed, 65 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 1c674f0e8a85..c759d46b7d2f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -479,7 +479,18 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>( AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span), }, ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id), - _ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t), + ty::Pat(base, _) => return type_di_node(cx, base), + // FIXME(unsafe_binders): impl debug info + ty::UnsafeBinder(_) => unimplemented!(), + ty::Alias(..) + | ty::Param(_) + | ty::Bound(..) + | ty::Infer(_) + | ty::Placeholder(_) + | ty::CoroutineWitness(..) + | ty::Error(_) => { + bug!("debuginfo: unexpected type in type_di_node(): {:?}", t) + } }; { diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index c7ddcaa73157..ffa7b09205d5 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -91,6 +91,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let (_, field) = layout.non_1zst_field(self).unwrap(); self.unfold_transparent(field, may_unfold) } + ty::Pat(base, _) => self.layout_of(*base).expect( + "if the layout of a pattern type could be computed, so can the layout of its base", + ), // Not a transparent type, no further unfolding. _ => layout, } diff --git a/library/core/src/num/niche_types.rs b/library/core/src/num/niche_types.rs index 9ac0eb72bdcb..33b2a6741abd 100644 --- a/library/core/src/num/niche_types.rs +++ b/library/core/src/num/niche_types.rs @@ -5,45 +5,33 @@ )] use crate::cmp::Ordering; -use crate::fmt; use crate::hash::{Hash, Hasher}; use crate::marker::StructuralPartialEq; +use crate::{fmt, pattern_type}; macro_rules! define_valid_range_type { ($( $(#[$m:meta])* - $vis:vis struct $name:ident($int:ident as $uint:ident in $low:literal..=$high:literal); + $vis:vis struct $name:ident($int:ident is $pat:pat); )+) => {$( - #[derive(Clone, Copy, Eq)] + #[derive(Clone, Copy)] #[repr(transparent)] - #[rustc_layout_scalar_valid_range_start($low)] - #[rustc_layout_scalar_valid_range_end($high)] $(#[$m])* - $vis struct $name($int); - - const _: () = { - // With the `valid_range` attributes, it's always specified as unsigned - assert!(<$uint>::MIN == 0); - let ulow: $uint = $low; - let uhigh: $uint = $high; - assert!(ulow <= uhigh); - - assert!(size_of::<$int>() == size_of::<$uint>()); - }; - + $vis struct $name(pattern_type!($int is $pat)); impl $name { #[inline] pub const fn new(val: $int) -> Option { - if (val as $uint) >= ($low as $uint) && (val as $uint) <= ($high as $uint) { - // SAFETY: just checked the inclusive range - Some(unsafe { $name(val) }) + #[allow(non_contiguous_range_endpoints)] + if let $pat = val { + // SAFETY: just checked that the value matches the pattern + Some(unsafe { $name(crate::mem::transmute(val)) }) } else { None } } /// Constructs an instance of this type from the underlying integer - /// primitive without checking whether its zero. + /// primitive without checking whether its valid. /// /// # Safety /// Immediate language UB if `val` is not within the valid range for this @@ -51,13 +39,13 @@ macro_rules! define_valid_range_type { #[inline] pub const unsafe fn new_unchecked(val: $int) -> Self { // SAFETY: Caller promised that `val` is within the valid range. - unsafe { $name(val) } + unsafe { crate::mem::transmute(val) } } #[inline] pub const fn as_inner(self) -> $int { - // SAFETY: This is a transparent wrapper, so unwrapping it is sound - // (Not using `.0` due to MCP#807.) + // SAFETY: pattern types are always legal values of their base type + // (Not using `.0` because that has perf regressions.) unsafe { crate::mem::transmute(self) } } } @@ -67,6 +55,8 @@ macro_rules! define_valid_range_type { // by . impl StructuralPartialEq for $name {} + impl Eq for $name {} + impl PartialEq for $name { #[inline] fn eq(&self, other: &Self) -> bool { @@ -104,7 +94,7 @@ macro_rules! define_valid_range_type { } define_valid_range_type! { - pub struct Nanoseconds(u32 as u32 in 0..=999_999_999); + pub struct Nanoseconds(u32 is 0..=999_999_999); } impl Nanoseconds { @@ -120,47 +110,32 @@ impl const Default for Nanoseconds { } } -define_valid_range_type! { - pub struct NonZeroU8Inner(u8 as u8 in 1..=0xff); - pub struct NonZeroU16Inner(u16 as u16 in 1..=0xff_ff); - pub struct NonZeroU32Inner(u32 as u32 in 1..=0xffff_ffff); - pub struct NonZeroU64Inner(u64 as u64 in 1..=0xffffffff_ffffffff); - pub struct NonZeroU128Inner(u128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff); - - pub struct NonZeroI8Inner(i8 as u8 in 1..=0xff); - pub struct NonZeroI16Inner(i16 as u16 in 1..=0xff_ff); - pub struct NonZeroI32Inner(i32 as u32 in 1..=0xffff_ffff); - pub struct NonZeroI64Inner(i64 as u64 in 1..=0xffffffff_ffffffff); - pub struct NonZeroI128Inner(i128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff); - - pub struct NonZeroCharInner(char as u32 in 1..=0x10ffff); -} - -#[cfg(target_pointer_width = "16")] -define_valid_range_type! { - pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff); - pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff); - pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff); -} -#[cfg(target_pointer_width = "32")] -define_valid_range_type! { - pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff_ffff); - pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff_ffff); - pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff_ffff); -} -#[cfg(target_pointer_width = "64")] -define_valid_range_type! { - pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff_ffff_ffff_ffff); - pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff_ffff_ffff_ffff); - pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff_ffff_ffff_ffff); -} +const HALF_USIZE: usize = usize::MAX >> 1; define_valid_range_type! { - pub struct U32NotAllOnes(u32 as u32 in 0..=0xffff_fffe); - pub struct I32NotAllOnes(i32 as u32 in 0..=0xffff_fffe); + pub struct NonZeroU8Inner(u8 is 1..); + pub struct NonZeroU16Inner(u16 is 1..); + pub struct NonZeroU32Inner(u32 is 1..); + pub struct NonZeroU64Inner(u64 is 1..); + pub struct NonZeroU128Inner(u128 is 1..); - pub struct U64NotAllOnes(u64 as u64 in 0..=0xffff_ffff_ffff_fffe); - pub struct I64NotAllOnes(i64 as u64 in 0..=0xffff_ffff_ffff_fffe); + pub struct NonZeroI8Inner(i8 is ..0 | 1..); + pub struct NonZeroI16Inner(i16 is ..0 | 1..); + pub struct NonZeroI32Inner(i32 is ..0 | 1..); + pub struct NonZeroI64Inner(i64 is ..0 | 1..); + pub struct NonZeroI128Inner(i128 is ..0 | 1..); + + pub struct UsizeNoHighBit(usize is 0..=HALF_USIZE); + pub struct NonZeroUsizeInner(usize is 1..); + pub struct NonZeroIsizeInner(isize is ..0 | 1..); + + pub struct U32NotAllOnes(u32 is 0..u32::MAX); + pub struct I32NotAllOnes(i32 is ..-1 | 0..); + + pub struct U64NotAllOnes(u64 is 0..u64::MAX); + pub struct I64NotAllOnes(i64 is ..-1 | 0..); + + pub struct NonZeroCharInner(char is '\u{1}' ..= '\u{10ffff}'); } pub trait NotAllOnesHelper { @@ -181,7 +156,7 @@ impl NotAllOnesHelper for i64 { } define_valid_range_type! { - pub struct CodePointInner(u32 as u32 in 0..=0x10ffff); + pub struct CodePointInner(u32 is 0..=0x10ffff); } impl CodePointInner { diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 1ab76ef8f91d..fda9f3bbba3a 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2184,6 +2184,9 @@ Please disable assertions with `rust.debug-assertions = false`. for flag in targetflags { cmd.arg("--target-rustcflags").arg(flag); } + if target.is_synthetic() { + cmd.arg("--target-rustcflags").arg("-Zunstable-options"); + } cmd.arg("--python").arg( builder.config.python.as_ref().expect("python is required for running rustdoc tests"), diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr index a00d167df2f7..6fc1bc01655c 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error: Undefined Behavior: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> tests/fail/validity/cast_fn_ptr_invalid_callee_ret.rs:LL:CC | LL | f(); diff --git a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr index c2e647aa18fc..3b23a6cc4e85 100644 --- a/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr +++ b/src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error: Undefined Behavior: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC | LL | Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue()) diff --git a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr index 2861f82ec53b..be3b539b269a 100644 --- a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr @@ -64,7 +64,7 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; 00 00 00 00 │ .... } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; @@ -75,7 +75,7 @@ LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; 00 │ . } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:63:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; diff --git a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr index 8e6dc66a40ee..9950ac726ca7 100644 --- a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr @@ -64,7 +64,7 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; 00 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; @@ -75,7 +75,7 @@ LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; 00 │ . } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:63:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr index e4486e3c500b..be5c6f77a087 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.stderr +++ b/tests/ui/consts/const-eval/ub-nonnull.stderr @@ -15,7 +15,7 @@ error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer LL | let out_of_bounds_ptr = &ptr[255]; | ^^^^^^^^^ evaluation of `OUT_OF_BOUNDS_PTR` failed here -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/ub-nonnull.rs:26:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; @@ -26,7 +26,7 @@ LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; HEX_DUMP } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/ub-nonnull.rs:28:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; diff --git a/tests/ui/lint/invalid_value.stderr b/tests/ui/lint/invalid_value.stderr index cc6a2a1c8e53..3dd2a521ff2e 100644 --- a/tests/ui/lint/invalid_value.stderr +++ b/tests/ui/lint/invalid_value.stderr @@ -333,7 +333,6 @@ LL | let _val: (NonZero, i32) = mem::uninitialized(); | = note: `std::num::NonZero` must be non-null = note: because `core::num::niche_types::NonZeroU32Inner` must be non-null - = note: integers must be initialized error: the type `*const dyn Send` does not permit zero-initialization --> $DIR/invalid_value.rs:97:37 @@ -430,7 +429,6 @@ note: because `std::num::NonZero` must be non-null (in this field of the on LL | Banana(NonZero), | ^^^^^^^^^^^^ = note: because `core::num::niche_types::NonZeroU32Inner` must be non-null - = note: integers must be initialized error: the type `bool` does not permit being left uninitialized --> $DIR/invalid_value.rs:111:26 From c9b5c934ca7acc33ff4aebbe1630cb02bb4c0f1f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 10 Feb 2026 11:39:06 +0100 Subject: [PATCH 3501/3801] Fix passing/returning structs with the 64-bit SPARC ABI Co-authored-by: beetrees --- compiler/rustc_abi/src/callconv/reg.rs | 1 + compiler/rustc_target/src/callconv/sparc64.rs | 342 +++++++++--------- tests/assembly-llvm/sparc-struct-abi.rs | 193 +++++++++- tests/codegen-llvm/cast-target-abi.rs | 16 +- 4 files changed, 366 insertions(+), 186 deletions(-) diff --git a/compiler/rustc_abi/src/callconv/reg.rs b/compiler/rustc_abi/src/callconv/reg.rs index 66c8056d0c2a..66d4dca00726 100644 --- a/compiler/rustc_abi/src/callconv/reg.rs +++ b/compiler/rustc_abi/src/callconv/reg.rs @@ -35,6 +35,7 @@ impl Reg { reg_ctor!(f32, Float, 32); reg_ctor!(f64, Float, 64); + reg_ctor!(f128, Float, 128); } impl Reg { diff --git a/compiler/rustc_target/src/callconv/sparc64.rs b/compiler/rustc_target/src/callconv/sparc64.rs index fc732170dcb7..f55d03d89e8f 100644 --- a/compiler/rustc_target/src/callconv/sparc64.rs +++ b/compiler/rustc_target/src/callconv/sparc64.rs @@ -1,214 +1,203 @@ -// FIXME: This needs an audit for correctness and completeness. - use rustc_abi::{ - BackendRepr, FieldsShape, Float, HasDataLayout, Primitive, Reg, Scalar, Size, TyAbiInterface, - TyAndLayout, + Align, BackendRepr, FieldsShape, Float, HasDataLayout, Primitive, Reg, Size, TyAbiInterface, + TyAndLayout, Variants, }; use crate::callconv::{ArgAbi, ArgAttribute, CastTarget, FnAbi, Uniform}; -use crate::spec::{Env, HasTargetSpec, Os}; +use crate::spec::{HasTargetSpec, Os}; -#[derive(Clone, Debug)] -struct Sdata { - pub prefix: [Option; 8], - pub prefix_index: usize, - pub last_offset: Size, - pub has_float: bool, - pub arg_attribute: ArgAttribute, +// NOTE: GCC and Clang/LLVM have disagreements that the ABI doesn't resolve, we match the +// Clang/LLVM behavior in these cases. + +#[derive(Copy, Clone)] +enum DoubleWord { + F64, + F128Start, + F128End, + Words([Word; 2]), } -fn arg_scalar(cx: &C, scalar: &Scalar, offset: Size, mut data: Sdata) -> Sdata -where - C: HasDataLayout, -{ - let dl = cx.data_layout(); - - if !matches!(scalar.primitive(), Primitive::Float(Float::F32 | Float::F64)) { - return data; - } - - data.has_float = true; - - if !data.last_offset.is_aligned(dl.f64_align) && data.last_offset < offset { - if data.prefix_index == data.prefix.len() { - return data; - } - data.prefix[data.prefix_index] = Some(Reg::i32()); - data.prefix_index += 1; - data.last_offset = data.last_offset + Reg::i32().size; - } - - for _ in 0..((offset - data.last_offset).bits() / 64) - .min((data.prefix.len() - data.prefix_index) as u64) - { - data.prefix[data.prefix_index] = Some(Reg::i64()); - data.prefix_index += 1; - data.last_offset = data.last_offset + Reg::i64().size; - } - - if data.last_offset < offset { - if data.prefix_index == data.prefix.len() { - return data; - } - data.prefix[data.prefix_index] = Some(Reg::i32()); - data.prefix_index += 1; - data.last_offset = data.last_offset + Reg::i32().size; - } - - if data.prefix_index == data.prefix.len() { - return data; - } - - if scalar.primitive() == Primitive::Float(Float::F32) { - data.arg_attribute = ArgAttribute::InReg; - data.prefix[data.prefix_index] = Some(Reg::f32()); - data.last_offset = offset + Reg::f32().size; - } else { - data.prefix[data.prefix_index] = Some(Reg::f64()); - data.last_offset = offset + Reg::f64().size; - } - data.prefix_index += 1; - data +#[derive(Copy, Clone)] +enum Word { + F32, + Integer, } -fn arg_scalar_pair( +fn classify<'a, Ty, C>( cx: &C, - scalar1: &Scalar, - scalar2: &Scalar, - mut offset: Size, - mut data: Sdata, -) -> Sdata -where - C: HasDataLayout, -{ - data = arg_scalar(cx, scalar1, offset, data); - match (scalar1.primitive(), scalar2.primitive()) { - (Primitive::Float(Float::F32), _) => offset += Reg::f32().size, - (_, Primitive::Float(Float::F64)) => offset += Reg::f64().size, - (Primitive::Int(i, _signed), _) => offset += i.size(), - (Primitive::Pointer(_), _) => offset += Reg::i64().size, - _ => {} - } - - if !offset.bytes().is_multiple_of(4) - && matches!(scalar2.primitive(), Primitive::Float(Float::F32 | Float::F64)) - { - offset += Size::from_bytes(4 - (offset.bytes() % 4)); - } - data = arg_scalar(cx, scalar2, offset, data); - data -} - -fn parse_structure<'a, Ty, C>( - cx: &C, - layout: TyAndLayout<'a, Ty>, - mut data: Sdata, - mut offset: Size, -) -> Sdata -where + arg_layout: &TyAndLayout<'a, Ty>, + offset: Size, + double_words: &mut [DoubleWord; 4], +) where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { - if let FieldsShape::Union(_) = layout.fields { - return data; - } + // If this function does not update the `double_words` array, the value will be passed via + // integer registers. The array is initialized with `DoubleWord::Words([Word::Integer; 2])`. - match layout.backend_repr { - BackendRepr::Scalar(scalar) => { - data = arg_scalar(cx, &scalar, offset, data); - } - BackendRepr::Memory { .. } => { - for i in 0..layout.fields.count() { - if offset < layout.fields.offset(i) { - offset = layout.fields.offset(i); + match arg_layout.backend_repr { + BackendRepr::Scalar(scalar) => match scalar.primitive() { + Primitive::Float(float) => { + if offset.is_aligned(Ord::min(*float.align(cx), Align::EIGHT)) { + let index = offset.bytes_usize() / 8; + match float { + Float::F128 => { + double_words[index] = DoubleWord::F128Start; + double_words[index + 1] = DoubleWord::F128End; + } + Float::F64 => { + double_words[index] = DoubleWord::F64; + } + Float::F32 => match &mut double_words[index] { + DoubleWord::Words(words) => { + words[(offset.bytes_usize() % 8) / 4] = Word::F32; + } + _ => unreachable!(), + }, + Float::F16 => { + // Match LLVM by passing `f16` in integer registers. + } + } + } else { + /* pass unaligned floats in integer registers */ } - data = parse_structure(cx, layout.field(cx, i), data.clone(), offset); } - } - _ => { - if let BackendRepr::ScalarPair(scalar1, scalar2) = &layout.backend_repr { - data = arg_scalar_pair(cx, scalar1, scalar2, offset, data); + Primitive::Int(_, _) | Primitive::Pointer(_) => { /* pass in integer registers */ } + }, + BackendRepr::SimdVector { .. } => {} + BackendRepr::ScalableVector { .. } => {} + BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { + FieldsShape::Primitive => { + unreachable!("aggregates can't have `FieldsShape::Primitive`") } - } + FieldsShape::Union(_) => { + if !arg_layout.is_zst() { + if arg_layout.is_transparent() { + let non_1zst_elem = arg_layout.non_1zst_field(cx).expect("not exactly one non-1-ZST field in non-ZST repr(transparent) union").1; + classify(cx, &non_1zst_elem, offset, double_words); + } + } + } + FieldsShape::Array { .. } => {} + FieldsShape::Arbitrary { .. } => match arg_layout.variants { + Variants::Multiple { .. } => {} + Variants::Single { .. } | Variants::Empty => { + // Match Clang by ignoring whether a struct is packed and just considering + // whether individual fields are aligned. GCC currently uses only integer + // registers when passing packed structs. + for i in arg_layout.fields.index_by_increasing_offset() { + classify( + cx, + &arg_layout.field(cx, i), + offset + arg_layout.fields.offset(i), + double_words, + ); + } + } + }, + }, } - - data } -fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, in_registers_max: Size) -where +fn classify_arg<'a, Ty, C>( + cx: &C, + arg: &mut ArgAbi<'a, Ty>, + in_registers_max: Size, + total_double_word_count: &mut usize, +) where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout, { + // 64-bit SPARC allocates argument stack space in 64-bit chunks (double words), some of which + // are promoted to registers based on their position on the stack. + + // Keep track of the total number of double words used by arguments so far. This allows padding + // arguments to be inserted where necessary to ensure that 16-aligned arguments are passed in an + // aligned set of registers. + + let pad = !total_double_word_count.is_multiple_of(2) && arg.layout.align.abi.bytes() == 16; + // The number of double words used by this argument. + let double_word_count = arg.layout.size.bytes_usize().div_ceil(8); + // The number of double words before this argument, including any padding. + let start_double_word_count = *total_double_word_count + usize::from(pad); + if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { arg.make_indirect(); + *total_double_word_count += 1; return; } + if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); + *total_double_word_count = start_double_word_count + double_word_count; return; } let total = arg.layout.size; if total > in_registers_max { arg.make_indirect(); + *total_double_word_count += 1; return; } - match arg.layout.fields { - FieldsShape::Primitive => unreachable!(), - FieldsShape::Array { .. } => { - // Arrays are passed indirectly - arg.make_indirect(); - return; + *total_double_word_count = start_double_word_count + double_word_count; + + const ARGUMENT_REGISTERS: usize = 8; + + let mut double_words = [DoubleWord::Words([Word::Integer; 2]); ARGUMENT_REGISTERS / 2]; + classify(cx, &arg.layout, Size::ZERO, &mut double_words); + + let mut regs = [None; ARGUMENT_REGISTERS]; + let mut i = 0; + let mut push = |reg| { + regs[i] = Some(reg); + i += 1; + }; + let mut attrs = ArgAttribute::empty(); + + for (index, double_word) in double_words.into_iter().enumerate() { + if arg.layout.size.bytes_usize() <= index * 8 { + break; } - FieldsShape::Union(_) => { - // Unions and are always treated as a series of 64-bit integer chunks - } - FieldsShape::Arbitrary { .. } => { - // Structures with floating point numbers need special care. - - let mut data = parse_structure( - cx, - arg.layout, - Sdata { - prefix: [None; 8], - prefix_index: 0, - last_offset: Size::ZERO, - has_float: false, - arg_attribute: ArgAttribute::default(), - }, - Size::ZERO, - ); - - if data.has_float { - // Structure { float, int, int } doesn't like to be handled like - // { float, long int }. Other way around it doesn't mind. - if data.last_offset < arg.layout.size - && !data.last_offset.bytes().is_multiple_of(8) - && data.prefix_index < data.prefix.len() - { - data.prefix[data.prefix_index] = Some(Reg::i32()); - data.prefix_index += 1; - data.last_offset += Reg::i32().size; + match double_word { + // `f128` must be aligned to be assigned a float register. + DoubleWord::F128Start if (start_double_word_count + index).is_multiple_of(2) => { + push(Reg::f128()); + } + DoubleWord::F128Start => { + // Clang currently handles this case nonsensically, always returning a packed + // `struct { long double x; }` in an aligned quad floating-point register even when + // the `long double` isn't aligned on the stack, which also makes all future + // arguments get passed in the wrong registers. This passes the `f128` in integer + // registers when it is unaligned, same as with `f32` and `f64`. + push(Reg::i64()); + push(Reg::i64()); + } + DoubleWord::F128End => {} // Already handled by `F128Start` + DoubleWord::F64 => push(Reg::f64()), + DoubleWord::Words([Word::Integer, Word::Integer]) => push(Reg::i64()), + DoubleWord::Words(words) => { + attrs |= ArgAttribute::InReg; + for word in words { + match word { + Word::F32 => push(Reg::f32()), + Word::Integer => push(Reg::i32()), + } } - - let mut rest_size = arg.layout.size - data.last_offset; - if !rest_size.bytes().is_multiple_of(8) && data.prefix_index < data.prefix.len() { - data.prefix[data.prefix_index] = Some(Reg::i32()); - rest_size = rest_size - Reg::i32().size; - } - - arg.cast_to( - CastTarget::prefixed(data.prefix, Uniform::new(Reg::i64(), rest_size)) - .with_attrs(data.arg_attribute.into()), - ); - return; } } } - arg.cast_to(Uniform::new(Reg::i64(), total)); + let cast_target = match regs { + [Some(reg), None, rest @ ..] => { + // Just a single register is needed for this value. + debug_assert!(rest.iter().all(|x| x.is_none())); + CastTarget::from(reg) + } + _ => CastTarget::prefixed(regs, Uniform::new(Reg::i8(), Size::ZERO)), + }; + + arg.cast_to_and_pad_i32(cast_target.with_attrs(attrs.into()), pad); } pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) @@ -217,23 +206,26 @@ where C: HasDataLayout + HasTargetSpec, { if !fn_abi.ret.is_ignore() && fn_abi.ret.layout.is_sized() { - classify_arg(cx, &mut fn_abi.ret, Size::from_bytes(32)); + // A return value of 32 bytes or smaller is passed via registers. + classify_arg(cx, &mut fn_abi.ret, Size::from_bytes(32), &mut 0); } + // sparc64-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs. + let passes_zsts = matches!(cx.target_spec().os, Os::Linux); + + let mut double_word_count = 0; for arg in fn_abi.args.iter_mut() { if !arg.layout.is_sized() { continue; } if arg.is_ignore() { - // sparc64-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs. - if cx.target_spec().os == Os::Linux - && matches!(cx.target_spec().env, Env::Gnu | Env::Musl | Env::Uclibc) - && arg.layout.is_zst() - { + if passes_zsts && arg.layout.is_zst() { arg.make_indirect_from_ignore(); + double_word_count += 1; } - return; + continue; } - classify_arg(cx, arg, Size::from_bytes(16)); + // An argument of 16 bytes or smaller is passed via registers. + classify_arg(cx, arg, Size::from_bytes(16), &mut double_word_count); } } diff --git a/tests/assembly-llvm/sparc-struct-abi.rs b/tests/assembly-llvm/sparc-struct-abi.rs index c6e83b6f8dab..41ac2be09b65 100644 --- a/tests/assembly-llvm/sparc-struct-abi.rs +++ b/tests/assembly-llvm/sparc-struct-abi.rs @@ -9,6 +9,7 @@ #![crate_type = "lib"] #![feature(no_core, lang_items)] #![no_core] +#![feature(f128)] extern crate minicore; use minicore::*; @@ -21,8 +22,33 @@ pub struct Franta { d: f32, } +#[repr(C, packed)] +struct Misaligned(i32, f64); + +#[repr(C)] +struct AlignToMakeAssemblyShorter(T, f64); + +#[repr(C)] +pub struct Floats(i32, f32, f64, f128); + +#[repr(C)] +pub struct LessFloats(f32, i32, f64); + +#[repr(C)] +pub struct NotMisaligned(i32, Misaligned); + +#[repr(C, align(16))] +pub struct Align16(f64, i32, i32); + +impl Copy for Misaligned {} +impl Copy for AlignToMakeAssemblyShorter {} +impl Copy for Floats {} +impl Copy for LessFloats {} +impl Copy for NotMisaligned {} +impl Copy for Align16 {} + // NB: due to delay slots the `ld` following the call is actually executed before the call. -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn callee(arg: Franta) { // CHECK-LABEL: callee: // CHECK: st %f3, [[PLACE_D:.*]] @@ -54,7 +80,7 @@ extern "C" { fn tail_call_avoidance_fn(); } -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn caller() { // CHECK-LABEL: caller: // CHECK: ld [{{.*}}], %f0 @@ -62,7 +88,168 @@ pub unsafe extern "C" fn caller() { // CHECK: ld [{{.*}}], %f2 // CHECK: ld [{{.*}}], %f3 // CHECK: call opaque_callee - // CHECK: mov 3, %o2 + // CHECK: mov 3, %o2 opaque_callee(Franta { a: 1.0, b: 2.0, c: 3.0, d: 4.0 }, 3); tail_call_avoidance_fn(); } + +// Check that misaligned floats aren't promoted to floating point registers. +// CHECK-LABEL: misaligned_arg: +#[unsafe(no_mangle)] +extern "C" fn misaligned_arg(x: &mut AlignToMakeAssemblyShorter, value: Misaligned) { + // CHECK: srlx %o2, 32, %o2 + // CHECK-NEXT: stx %o1, [%o0] + // CHECK-NEXT: retl + // CHECK-NEXT: st %o2, [%o0+8] + x.0 = value; +} + +// CHECK-LABEL: misaligned_ret: +#[unsafe(no_mangle)] +extern "C" fn misaligned_ret(x: &AlignToMakeAssemblyShorter) -> Misaligned { + // CHECK: ld [%o0+8], %o1 + // CHECK-NEXT: ldx [%o0], %o0 + // CHECK-NEXT: retl + // CHECK-NEXT: sllx %o1, 32, %o1 + x.0 +} + +// Check structs where 32 >= size > 16 are promoted to register only as an argument. +// Also check that the various floating-point types are promoted to the correct registers. +// CHECK-LABEL: floats_arg: +#[unsafe(no_mangle)] +extern "C" fn floats_arg(x: &mut Floats, value: Floats) { + // CHECK: ldx [%o1+24], %o2 + // CHECK-NEXT: ldx [%o1+16], %o3 + // CHECK-NEXT: ldx [%o1+8], %o4 + // CHECK-NEXT: ldx [%o1], %o1 + // CHECK-NEXT: stx %o2, [%o0+24] + // CHECK-NEXT: stx %o3, [%o0+16] + // CHECK-NEXT: stx %o4, [%o0+8] + // CHECK-NEXT: retl + // CHECK-NEXT: stx %o1, [%o0] + *x = value; +} + +// CHECK-LABEL: floats_ret: +#[unsafe(no_mangle)] +extern "C" fn floats_ret(x: &Floats) -> Floats { + // CHECK: ld [%o0+4], %f1 + // CHECK-NEXT: ldd [%o0+8], %f2 + // CHECK-NEXT: ldd [%o0+16], %f4 + // CHECK-NEXT: ld [%o0], %o1 + // CHECK-NEXT: ldd [%o0+24], %f6 + // CHECK-NEXT: retl + // CHECK-NEXT: sllx %o1, 32, %o0 + *x +} + +// Check float promotion when passing as an argument with a struct where size <= 16. +// CHECK-LABEL: less_floats_arg: +#[unsafe(no_mangle)] +extern "C" fn less_floats_arg(x: &mut LessFloats, value: LessFloats) { + // CHECK: st %f2, [%o0] + // CHECK-NEXT: st %o1, [%o0+4] + // CHECK-NEXT: retl + // CHECK-NEXT: std %f4, [%o0+8] + *x = value; +} + +// CHECK-LABEL: less_floats_ret: +#[unsafe(no_mangle)] +extern "C" fn less_floats_ret(x: &LessFloats) -> LessFloats { + // CHECK: ld [%o0], %f0 + // CHECK-NEXT: ldd [%o0+8], %f2 + // CHECK-NEXT: retl + // CHECK-NEXT: ld [%o0+4], %o0 + *x +} + +// Check fields are promoted if they are aligned in the overall structure. +// This matches Clang's behaviour but not GCC's. +// CHECK-LABEL: not_misaligned_arg: +#[unsafe(no_mangle)] +extern "C" fn not_misaligned_arg( + x: &mut AlignToMakeAssemblyShorter, + value: NotMisaligned, +) { + // CHECK: stx %o1, [%o0] + // CHECK-NEXT: retl + // CHECK-NEXT: std %f4, [%o0+8] + x.0 = value; +} + +// CHECK-LABEL: not_misaligned_ret: +#[unsafe(no_mangle)] +extern "C" fn not_misaligned_ret(x: &AlignToMakeAssemblyShorter) -> NotMisaligned { + // CHECK: ldx [%o0], %o1 + // CHECK-NEXT: ldd [%o0+8], %f2 + // CHECK-NEXT: retl + // CHECK-NEXT: mov %o1, %o0 + x.0 +} + +// Check that 16-aligned structs are allocated the correct registers. +// CHECK-LABEL: align_16_arg: +#[unsafe(no_mangle)] +extern "C" fn align_16_arg(x: &mut Align16, value: Align16) { + // CHECK: std %f4, [%o0] + // CHECK-NEXT: retl + // CHECK-NEXT: stx %o3, [%o0+8] + *x = value; +} + +// CHECK-LABEL: align_16_ret: +#[unsafe(no_mangle)] +extern "C" fn align_16_ret(x: &Align16) -> Align16 { + // CHECK: ldd [%o0], %f0 + // CHECK-NEXT: retl + // CHECK-NEXT: ldx [%o0+8], %o1 + *x +} + +// Check ZST args don't prevent further arguments from being processed. +// CHECK-LABEL: zst_arg: +#[unsafe(no_mangle)] +extern "C" fn zst_arg(_: (), value: LessFloats, x: &mut LessFloats) { + // CHECK: st %f0, [%o2] + // CHECK-NEXT: st %o0, [%o2+4] + // CHECK-NEXT: retl + // CHECK-NEXT: std %f2, [%o2+8] + *x = value; +} + +#[repr(C)] +struct I32F32Input { + a: i32, + b: f32, +} + +#[repr(C)] +struct I32F32Output { + b: f32, + a: i32, +} + +// The clang/LLVM implementation mentions that this case requires special handling. +// CHECK-LABEL: i32_f32: +#[unsafe(no_mangle)] +extern "C" fn i32_f32(input: I32F32Input) -> I32F32Output { + // CHECK: srlx %o0, 32, %o0 + // CHECK-NEXT: fmovs %f1, %f0 + // CHECK-NEXT: retl + // CHECK-NEXT: nop + I32F32Output { a: input.a, b: input.b } +} + +#[repr(C)] +pub struct C { + a: f64, + b: f32, +} + +// regression test for https://github.com/rust-lang/rust/issues/147883. +#[unsafe(no_mangle)] +pub extern "C" fn foo(c: C) -> C { + c +} diff --git a/tests/codegen-llvm/cast-target-abi.rs b/tests/codegen-llvm/cast-target-abi.rs index 101e73e33c91..6f1ab4572ee0 100644 --- a/tests/codegen-llvm/cast-target-abi.rs +++ b/tests/codegen-llvm/cast-target-abi.rs @@ -119,7 +119,7 @@ pub extern "C" fn returns_twou16s() -> TwoU16s { // aarch64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) // loongarch64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) // powerpc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) -// sparc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// sparc64-SAME: ([[ABI_TYPE:{ i64, i64 }]] {{.*}}[[ABI_VALUE:%.+]]) // x86_64-SAME: ([[ABI_TYPE:{ i64, i16 }]] {{.*}}[[ABI_VALUE:%.+]]) #[no_mangle] #[inline(never)] @@ -148,7 +148,7 @@ pub extern "C" fn returns_fiveu16s() -> FiveU16s { // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] - // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i64 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i16 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // aarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] @@ -217,7 +217,7 @@ pub extern "C" fn returns_doubledouble() -> DoubleDouble { // aarch64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) // loongarch64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) // powerpc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) -// sparc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// sparc64-SAME: ([[ABI_TYPE:{ i64, i64 }]] {{.*}}[[ABI_VALUE:%.+]]) // x86_64-SAME: ([[ABI_TYPE:{ i64, i32 }]] {{.*}}[[ABI_VALUE:%.+]]) #[no_mangle] #[inline(never)] @@ -246,7 +246,7 @@ pub extern "C" fn returns_three32s() -> Three32s { // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] - // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i64 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i32 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // aarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] @@ -399,7 +399,7 @@ pub fn call_fiveu16s() { // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] - // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i64 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i16 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // CHECK: call void @receives_fiveu16s([[ABI_TYPE]] [[ABI_VALUE]]) @@ -424,7 +424,7 @@ pub fn return_fiveu16s() -> FiveU16s { // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() - // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() + // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ i64, i64 }]] @returns_fiveu16s() // x86_64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ i64, i16 }]] @returns_fiveu16s() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] @@ -595,7 +595,7 @@ pub fn call_three32s() { // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] - // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i64 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i32 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // CHECK: call void @receives_three32s([[ABI_TYPE]] [[ABI_VALUE]]) @@ -619,7 +619,7 @@ pub fn return_three32s() -> Three32s { // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s() // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s() - // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s() + // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ i64, i64 }]] @returns_three32s() // x86_64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ i64, i32 }]] @returns_three32s() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] From b23d30885308fadf851af7fc3134d129731b6417 Mon Sep 17 00:00:00 2001 From: Asuna Date: Wed, 14 Jan 2026 22:19:12 +0100 Subject: [PATCH 3502/3801] Support structs in type info reflection --- .../src/const_eval/type_info.rs | 177 ++++++++++++++---- compiler/rustc_span/src/symbol.rs | 2 + library/core/src/mem/type_info.rs | 15 ++ library/coretests/tests/mem/type_info.rs | 51 +++++ .../missing-trait-bounds/issue-69725.stderr | 8 +- tests/ui/reflection/dump.bit32.run.stdout | 55 +++++- tests/ui/reflection/dump.bit64.run.stdout | 55 +++++- tests/ui/reflection/dump.rs | 9 +- 8 files changed, 333 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index f8881f0968bb..5b96856b253f 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -1,18 +1,36 @@ -use rustc_abi::FieldIdx; +use std::borrow::Cow; + +use rustc_abi::{FieldIdx, VariantIdx}; use rustc_ast::Mutability; use rustc_hir::LangItem; use rustc_middle::span_bug; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{self, Const, ScalarInt, Ty}; +use rustc_middle::ty::{self, AdtDef, AdtKind, Const, GenericArgs, ScalarInt, Ty, VariantDef}; use rustc_span::{Symbol, sym}; use crate::const_eval::CompileTimeMachine; use crate::interpret::{ - CtfeProvenance, Immediate, InterpCx, InterpResult, MPlaceTy, MemoryKind, Scalar, Writeable, - interp_ok, + CtfeProvenance, Immediate, InterpCx, InterpResult, MPlaceTy, MemoryKind, Projectable, Scalar, + Writeable, interp_ok, }; impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { + /// Equivalent to `project_downcast`, but identifies the variant by name instead of index. + fn downcast<'a>( + &self, + place: &(impl Writeable<'tcx, CtfeProvenance> + 'a), + name: Symbol, + ) -> InterpResult<'tcx, (VariantIdx, impl Writeable<'tcx, CtfeProvenance> + 'a)> { + let variants = place.layout().ty.ty_adt_def().unwrap().variants(); + let variant_idx = variants + .iter_enumerated() + .find(|(_idx, var)| var.name == name) + .unwrap_or_else(|| panic!("got {name} but expected one of {variants:#?}")) + .0; + + interp_ok((variant_idx, self.project_downcast(place, variant_idx)?)) + } + /// Writes a `core::mem::type_info::TypeInfo` for a given type, `ty` to the given place. pub(crate) fn write_type_info( &mut self, @@ -26,22 +44,13 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { // Fill all fields of the `TypeInfo` struct. for (idx, field) in ty_struct.fields.iter_enumerated() { let field_dest = self.project_field(dest, idx)?; - let downcast = |name: Symbol| { - let variants = field_dest.layout().ty.ty_adt_def().unwrap().variants(); - let variant_id = variants - .iter_enumerated() - .find(|(_idx, var)| var.name == name) - .unwrap_or_else(|| panic!("got {name} but expected one of {variants:#?}")) - .0; - - interp_ok((variant_id, self.project_downcast(&field_dest, variant_id)?)) - }; let ptr_bit_width = || self.tcx.data_layout.pointer_size().bits(); match field.name { sym::kind => { let variant_index = match ty.kind() { ty::Tuple(fields) => { - let (variant, variant_place) = downcast(sym::Tuple)?; + let (variant, variant_place) = + self.downcast(&field_dest, sym::Tuple)?; // project to the single tuple variant field of `type_info::Tuple` struct type let tuple_place = self.project_field(&variant_place, FieldIdx::ZERO)?; assert_eq!( @@ -59,7 +68,8 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::Array(ty, len) => { - let (variant, variant_place) = downcast(sym::Array)?; + let (variant, variant_place) = + self.downcast(&field_dest, sym::Array)?; let array_place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_array_type_info(array_place, *ty, *len)?; @@ -67,23 +77,38 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::Slice(ty) => { - let (variant, variant_place) = downcast(sym::Slice)?; + let (variant, variant_place) = + self.downcast(&field_dest, sym::Slice)?; let slice_place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_slice_type_info(slice_place, *ty)?; variant } + ty::Adt(adt_def, generics) => { + // TODO(type_info): Handle enum and union + if !adt_def.is_struct() { + self.downcast(&field_dest, sym::Other)?.0 + } else { + let (variant, variant_place) = + self.downcast(&field_dest, sym::Struct)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_adt_type_info(place, (ty, *adt_def), generics)?; + variant + } + } ty::Bool => { - let (variant, _variant_place) = downcast(sym::Bool)?; + let (variant, _variant_place) = + self.downcast(&field_dest, sym::Bool)?; variant } ty::Char => { - let (variant, _variant_place) = downcast(sym::Char)?; + let (variant, _variant_place) = + self.downcast(&field_dest, sym::Char)?; variant } ty::Int(int_ty) => { - let (variant, variant_place) = downcast(sym::Int)?; + let (variant, variant_place) = self.downcast(&field_dest, sym::Int)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_int_type_info( place, @@ -93,7 +118,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::Uint(uint_ty) => { - let (variant, variant_place) = downcast(sym::Int)?; + let (variant, variant_place) = self.downcast(&field_dest, sym::Int)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_int_type_info( place, @@ -103,17 +128,19 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::Float(float_ty) => { - let (variant, variant_place) = downcast(sym::Float)?; + let (variant, variant_place) = + self.downcast(&field_dest, sym::Float)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_float_type_info(place, float_ty.bit_width())?; variant } ty::Str => { - let (variant, _variant_place) = downcast(sym::Str)?; + let (variant, _variant_place) = self.downcast(&field_dest, sym::Str)?; variant } ty::Ref(_, ty, mutability) => { - let (variant, variant_place) = downcast(sym::Reference)?; + let (variant, variant_place) = + self.downcast(&field_dest, sym::Reference)?; let reference_place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_reference_type_info(reference_place, *ty, *mutability)?; @@ -121,7 +148,8 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::RawPtr(ty, mutability) => { - let (variant, variant_place) = downcast(sym::Pointer)?; + let (variant, variant_place) = + self.downcast(&field_dest, sym::Pointer)?; let pointer_place = self.project_field(&variant_place, FieldIdx::ZERO)?; @@ -130,13 +158,13 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::Dynamic(predicates, region) => { - let (variant, variant_place) = downcast(sym::DynTrait)?; + let (variant, variant_place) = + self.downcast(&field_dest, sym::DynTrait)?; let dyn_place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_dyn_trait_type_info(dyn_place, *predicates, *region)?; variant } - ty::Adt(_, _) - | ty::Foreign(_) + ty::Foreign(_) | ty::Pat(_, _) | ty::FnDef(..) | ty::FnPtr(..) @@ -151,14 +179,14 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(..) - | ty::Error(_) => downcast(sym::Other)?.0, + | ty::Error(_) => self.downcast(&field_dest, sym::Other)?.0, }; self.write_discriminant(variant_index, &field_dest)? } sym::size => { let layout = self.layout_of(ty)?; let variant_index = if layout.is_sized() { - let (variant, variant_place) = downcast(sym::Some)?; + let (variant, variant_place) = self.downcast(&field_dest, sym::Some)?; let size_field_place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_scalar( @@ -168,7 +196,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { )?; variant } else { - downcast(sym::None)?.0 + self.downcast(&field_dest, sym::None)?.0 }; self.write_discriminant(variant_index, &field_dest)?; } @@ -204,7 +232,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { while let Some((i, place)) = fields_places.next(self)? { let field_ty = fields[i as usize]; - self.write_field(field_ty, place, tuple_layout, i)?; + self.write_field(field_ty, place, tuple_layout, None, i)?; } let fields_place = fields_place.map_provenance(CtfeProvenance::as_immutable); @@ -219,6 +247,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { field_ty: Ty<'tcx>, place: MPlaceTy<'tcx>, layout: TyAndLayout<'tcx>, + name: Option, idx: u64, ) -> InterpResult<'tcx> { for (field_idx, field_ty_field) in @@ -226,6 +255,15 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { { let field_place = self.project_field(&place, field_idx)?; match field_ty_field.name { + sym::name => { + let name = match name.as_ref() { + Some(name) => Cow::Borrowed(name.as_str()), + None => Cow::Owned(idx.to_string()), // For tuples + }; + let name_place = self.allocate_str_dedup(&name)?; + let ptr = self.mplace_to_ref(&name_place)?; + self.write_immediate(*ptr, &field_place)? + } sym::ty => self.write_type_id(field_ty, &field_place)?, sym::offset => { let offset = layout.fields.offset(idx as usize); @@ -287,6 +325,81 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } + // FIXME(type_info): No semver considerations for now + pub(crate) fn write_adt_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + adt: (Ty<'tcx>, AdtDef<'tcx>), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (adt_ty, adt_def) = adt; + match adt_def.adt_kind() { + AdtKind::Struct => self.write_struct_type_info( + place, + (adt_ty, adt_def.variant(VariantIdx::ZERO)), + generics, + ), + AdtKind::Union => todo!(), + AdtKind::Enum => todo!(), + } + } + + pub(crate) fn write_struct_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + struct_: (Ty<'tcx>, &'tcx VariantDef), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (struct_ty, struct_def) = struct_; + let struct_layout = self.layout_of(struct_ty)?; + + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + sym::fields => { + let fields_slice_place = field_place; + let field_type = fields_slice_place + .layout() + .ty + .builtin_deref(false) + .unwrap() + .sequence_element_type(self.tcx.tcx); + let fields_layout = self.layout_of(Ty::new_array( + self.tcx.tcx, + field_type, + struct_def.fields.len() as u64, + ))?; + let fields_place = self.allocate(fields_layout, MemoryKind::Stack)?; + let mut fields_places = self.project_array_fields(&fields_place)?; + + for field_def in &struct_def.fields { + let (i, place) = fields_places.next(self)?.unwrap(); + let field_ty = field_def.ty(*self.tcx, generics); + self.write_field(field_ty, place, struct_layout, Some(field_def.name), i)?; + } + + let fields_place = fields_place.map_provenance(CtfeProvenance::as_immutable); + let ptr = Immediate::new_slice( + fields_place.ptr(), + struct_def.fields.len() as u64, + self, + ); + self.write_immediate(ptr, &fields_slice_place)? + } + sym::non_exhaustive => { + let is_non_exhaustive = struct_def.is_field_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + fn write_int_type_info( &mut self, place: impl Writeable<'tcx, CtfeProvenance>, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6aa2eae556e2..271124a4c372 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -372,6 +372,7 @@ symbols! { Stdin, Str, String, + Struct, StructuralPartialEq, SubdiagMessage, Subdiagnostic, @@ -1086,6 +1087,7 @@ symbols! { ffi_returns_twice, field, field_init_shorthand, + fields, file, file_options, flags, diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 8b30803c97c9..0e87b9d9cbb7 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -49,6 +49,8 @@ pub enum TypeKind { Slice(Slice), /// Dynamic Traits. DynTrait(DynTrait), + /// Structs. + Struct(Struct), /// Primitive boolean type. Bool(Bool), /// Primitive character type. @@ -81,6 +83,8 @@ pub struct Tuple { #[non_exhaustive] #[unstable(feature = "type_info", issue = "146922")] pub struct Field { + /// The name of the field. + pub name: &'static str, /// The field's type. pub ty: TypeId, /// Offset in bytes from the parent type @@ -137,6 +141,17 @@ pub struct Trait { pub is_auto: bool, } +/// Compile-time type information about arrays. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Struct { + /// All fields of the struct. + pub fields: &'static [Field], + /// Whether the struct field list is non-exhaustive. + pub non_exhaustive: bool, +} + /// Compile-time type information about `bool`. #[derive(Debug)] #[non_exhaustive] diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 87f2d5dd8289..03ff5f55c4f7 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -1,4 +1,7 @@ +#![allow(dead_code)] + use std::any::{Any, TypeId}; +use std::mem::offset_of; use std::mem::type_info::{Type, TypeKind}; #[test] @@ -66,6 +69,54 @@ fn test_tuples() { } } +#[test] +fn test_structs() { + use TypeKind::*; + + const { + struct TestStruct { + first: u8, + second: u16, + reference: &'static u16, + } + + let Type { kind: Struct(ty), size, .. } = Type::of::() else { panic!() }; + assert!(size == Some(size_of::())); + assert!(!ty.non_exhaustive); + assert!(ty.fields.len() == 3); + assert!(ty.fields[0].name == "first"); + assert!(ty.fields[0].ty == TypeId::of::()); + assert!(ty.fields[0].offset == offset_of!(TestStruct, first)); + assert!(ty.fields[1].name == "second"); + assert!(ty.fields[1].ty == TypeId::of::()); + assert!(ty.fields[1].offset == offset_of!(TestStruct, second)); + assert!(ty.fields[2].name == "reference"); + assert!(ty.fields[2].ty != TypeId::of::<&'static u16>()); // FIXME(type_info): should be == + assert!(ty.fields[2].offset == offset_of!(TestStruct, reference)); + } + + const { + #[non_exhaustive] + struct NonExhaustive { + a: u8, + } + + let Type { kind: Struct(ty), .. } = Type::of::() else { panic!() }; + assert!(ty.non_exhaustive); + } + + const { + struct TupleStruct(u8, u16); + + let Type { kind: Struct(ty), .. } = Type::of::() else { panic!() }; + assert!(ty.fields.len() == 2); + assert!(ty.fields[0].name == "0"); + assert!(ty.fields[0].ty == TypeId::of::()); + assert!(ty.fields[1].name == "1"); + assert!(ty.fields[1].ty == TypeId::of::()); + } +} + #[test] fn test_primitives() { use TypeKind::*; diff --git a/tests/ui/missing-trait-bounds/issue-69725.stderr b/tests/ui/missing-trait-bounds/issue-69725.stderr index f483ea849b0e..20d2213f4f5f 100644 --- a/tests/ui/missing-trait-bounds/issue-69725.stderr +++ b/tests/ui/missing-trait-bounds/issue-69725.stderr @@ -1,17 +1,17 @@ -error[E0599]: the method `clone` exists for struct `Struct`, but its trait bounds were not satisfied +error[E0599]: the method `clone` exists for struct `issue_69725::Struct`, but its trait bounds were not satisfied --> $DIR/issue-69725.rs:9:32 | LL | let _ = Struct::::new().clone(); - | ^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds + | ^^^^^ method cannot be called on `issue_69725::Struct` due to unsatisfied trait bounds | ::: $DIR/auxiliary/issue-69725.rs:2:1 | LL | pub struct Struct(A); - | -------------------- doesn't satisfy `Struct: Clone` + | -------------------- doesn't satisfy `issue_69725::Struct: Clone` | = note: the following trait bounds were not satisfied: `A: Clone` - which is required by `Struct: Clone` + which is required by `issue_69725::Struct: Clone` help: consider restricting the type parameter to satisfy the trait bound | LL | fn crash() where A: Clone { diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout index d15b46509ff2..feda3401e462 100644 --- a/tests/ui/reflection/dump.bit32.run.stdout +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -3,14 +3,17 @@ Type { Tuple { fields: [ Field { + name: "0", ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), offset: 0, }, Field { + name: "1", ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), offset: 1, }, Field { + name: "2", ty: TypeId(0x41223169ff28813ba79b7268a2a968d9), offset: 2, }, @@ -143,7 +146,18 @@ Type { ), } Type { - kind: Other, + kind: Struct( + Struct { + fields: [ + Field { + name: "a", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 0, + }, + ], + non_exhaustive: false, + }, + ), size: Some( 4, ), @@ -154,6 +168,45 @@ Type { 12, ), } +Type { + kind: Struct( + Struct { + fields: [ + Field { + name: "a", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 0, + }, + ], + non_exhaustive: true, + }, + ), + size: Some( + 4, + ), +} +Type { + kind: Struct( + Struct { + fields: [ + Field { + name: "0", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 8, + }, + Field { + name: "1", + ty: TypeId(0x9ed91be891e304132cb86891e578f4a5), + offset: 0, + }, + ], + non_exhaustive: false, + }, + ), + size: Some( + 12, + ), +} Type { kind: Reference( Reference { diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout index efae22653951..d9fef71f619c 100644 --- a/tests/ui/reflection/dump.bit64.run.stdout +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -3,14 +3,17 @@ Type { Tuple { fields: [ Field { + name: "0", ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), offset: 0, }, Field { + name: "1", ty: TypeId(0x0596b48cc04376e64d5c788c2aa46bdb), offset: 1, }, Field { + name: "2", ty: TypeId(0x41223169ff28813ba79b7268a2a968d9), offset: 2, }, @@ -143,7 +146,18 @@ Type { ), } Type { - kind: Other, + kind: Struct( + Struct { + fields: [ + Field { + name: "a", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 0, + }, + ], + non_exhaustive: false, + }, + ), size: Some( 4, ), @@ -154,6 +168,45 @@ Type { 24, ), } +Type { + kind: Struct( + Struct { + fields: [ + Field { + name: "a", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 0, + }, + ], + non_exhaustive: true, + }, + ), + size: Some( + 4, + ), +} +Type { + kind: Struct( + Struct { + fields: [ + Field { + name: "0", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 8, + }, + Field { + name: "1", + ty: TypeId(0x9ed91be891e304132cb86891e578f4a5), + offset: 0, + }, + ], + non_exhaustive: false, + }, + ), + size: Some( + 16, + ), +} Type { kind: Reference( Reference { diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs index d42216a62fdc..fefaad325aea 100644 --- a/tests/ui/reflection/dump.rs +++ b/tests/ui/reflection/dump.rs @@ -14,6 +14,13 @@ struct Foo { a: u32, } +#[non_exhaustive] +struct NonExhaustiveStruct { + a: u32, +} + +struct TupleStruct(u32, u64); + enum Bar { Some(u32), None, @@ -37,7 +44,7 @@ fn main() { [u8; 2], i8, i32, i64, i128, isize, u8, u32, u64, u128, usize, - Foo, Bar, + Foo, Bar, NonExhaustiveStruct, TupleStruct, &Unsized, &str, &[u8], str, [u8], &u8, &mut u8, From 870fd9070b5d98422107b8c748f7c7d084d4d037 Mon Sep 17 00:00:00 2001 From: Asuna Date: Mon, 19 Jan 2026 01:07:51 +0100 Subject: [PATCH 3503/3801] Add generics info for structs in type info --- .../src/const_eval/type_info.rs | 153 ++++++++++++++---- compiler/rustc_span/src/symbol.rs | 4 + library/core/src/mem/type_info.rs | 41 +++++ library/coretests/tests/mem/type_info.rs | 20 ++- tests/ui/generics/wrong-number-of-args.rs | 2 +- tests/ui/generics/wrong-number-of-args.stderr | 2 +- tests/ui/reflection/dump.bit32.run.stdout | 50 ++++++ tests/ui/reflection/dump.bit64.run.stdout | 50 ++++++ tests/ui/reflection/dump.rs | 8 +- .../resolve/resolve-assoc-suggestions.stderr | 10 ++ 10 files changed, 304 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 5b96856b253f..9fb01b1f5c5c 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -3,9 +3,12 @@ use std::borrow::Cow; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_ast::Mutability; use rustc_hir::LangItem; -use rustc_middle::span_bug; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{self, AdtDef, AdtKind, Const, GenericArgs, ScalarInt, Ty, VariantDef}; +use rustc_middle::ty::{ + self, AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, ScalarInt, Ty, + VariantDef, +}; +use rustc_middle::{bug, span_bug}; use rustc_span::{Symbol, sym}; use crate::const_eval::CompileTimeMachine; @@ -31,6 +34,37 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok((variant_idx, self.project_downcast(place, variant_idx)?)) } + // A general method to write an array to a static slice place. + fn allocate_fill_and_write_slice_ptr( + &mut self, + slice_place: impl Writeable<'tcx, CtfeProvenance>, + len: u64, + writer: impl Fn(&mut Self, /* index */ u64, MPlaceTy<'tcx>) -> InterpResult<'tcx>, + ) -> InterpResult<'tcx> { + // Array element type + let field_ty = slice_place + .layout() + .ty + .builtin_deref(false) + .unwrap() + .sequence_element_type(self.tcx.tcx); + + // Allocate an array + let array_layout = self.layout_of(Ty::new_array(self.tcx.tcx, field_ty, len))?; + let array_place = self.allocate(array_layout, MemoryKind::Stack)?; + + // Fill the array fields + let mut field_places = self.project_array_fields(&array_place)?; + while let Some((i, place)) = field_places.next(self)? { + writer(self, i, place)?; + } + + // Write the slice pointing to the array + let array_place = array_place.map_provenance(CtfeProvenance::as_immutable); + let ptr = Immediate::new_slice(array_place.ptr(), len, self); + self.write_immediate(ptr, &slice_place) + } + /// Writes a `core::mem::type_info::TypeInfo` for a given type, `ty` to the given place. pub(crate) fn write_type_info( &mut self, @@ -207,6 +241,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } + // TODO(type_info): Remove this method, use `allocate_fill_and_write_slice_ptr` as it's more general. pub(crate) fn write_tuple_fields( &mut self, tuple_place: impl Writeable<'tcx, CtfeProvenance>, @@ -359,36 +394,16 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { let field_place = self.project_field(&place, field_idx)?; match field.name { - sym::fields => { - let fields_slice_place = field_place; - let field_type = fields_slice_place - .layout() - .ty - .builtin_deref(false) - .unwrap() - .sequence_element_type(self.tcx.tcx); - let fields_layout = self.layout_of(Ty::new_array( - self.tcx.tcx, - field_type, - struct_def.fields.len() as u64, - ))?; - let fields_place = self.allocate(fields_layout, MemoryKind::Stack)?; - let mut fields_places = self.project_array_fields(&fields_place)?; - - for field_def in &struct_def.fields { - let (i, place) = fields_places.next(self)?.unwrap(); - let field_ty = field_def.ty(*self.tcx, generics); - self.write_field(field_ty, place, struct_layout, Some(field_def.name), i)?; - } - - let fields_place = fields_place.map_provenance(CtfeProvenance::as_immutable); - let ptr = Immediate::new_slice( - fields_place.ptr(), - struct_def.fields.len() as u64, - self, - ); - self.write_immediate(ptr, &fields_slice_place)? - } + sym::generics => self.write_generics(field_place, generics)?, + sym::fields => self.allocate_fill_and_write_slice_ptr( + field_place, + struct_def.fields.len() as u64, + |this, i, place| { + let field_def = &struct_def.fields[FieldIdx::from_usize(i as usize)]; + let field_ty = field_def.ty(*this.tcx, generics); + this.write_field(field_ty, place, struct_layout, Some(field_def.name), i) + }, + )?, sym::non_exhaustive => { let is_non_exhaustive = struct_def.is_field_list_non_exhaustive(); self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? @@ -400,6 +415,80 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } + fn write_generics( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + self.allocate_fill_and_write_slice_ptr(place, generics.len() as u64, |this, i, place| { + match generics[i as usize].kind() { + GenericArgKind::Lifetime(region) => this.write_generic_lifetime(region, place), + GenericArgKind::Type(ty) => this.write_generic_type(ty, place), + GenericArgKind::Const(c) => this.write_generic_const(c, place), + } + }) + } + + fn write_generic_lifetime( + &mut self, + _region: Region<'tcx>, + place: MPlaceTy<'tcx>, + ) -> InterpResult<'tcx> { + let (variant_idx, _) = self.downcast(&place, sym::Lifetime)?; + self.write_discriminant(variant_idx, &place)?; + interp_ok(()) + } + + fn write_generic_type(&mut self, ty: Ty<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { + let (variant_idx, variant_place) = self.downcast(&place, sym::Type)?; + let generic_type_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + for (field_idx, field_def) in generic_type_place + .layout() + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .iter_enumerated() + { + let field_place = self.project_field(&generic_type_place, field_idx)?; + match field_def.name { + sym::ty => self.write_type_id(ty, &field_place)?, + other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), + } + } + + self.write_discriminant(variant_idx, &place)?; + interp_ok(()) + } + + fn write_generic_const(&mut self, c: Const<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { + let ConstKind::Value(c) = c.kind() else { bug!("expected a computed const, got {c:?}") }; + + let (variant_idx, variant_place) = self.downcast(&place, sym::Const)?; + let const_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + for (field_idx, field_def) in const_place + .layout() + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .iter_enumerated() + { + let field_place = self.project_field(&const_place, field_idx)?; + match field_def.name { + sym::ty => self.write_type_id(c.ty, &field_place)?, + other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), + } + } + + self.write_discriminant(variant_idx, &place)?; + interp_ok(()) + } + fn write_int_type_info( &mut self, place: impl Writeable<'tcx, CtfeProvenance>, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 271124a4c372..70f5c1d0c472 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -211,6 +211,7 @@ symbols! { CoercePointeeValidated, CoerceUnsized, Command, + Const, ConstParamTy, ConstParamTy_, Context, @@ -292,6 +293,7 @@ symbols! { IteratorMap, Layout, Left, + Lifetime, LinkedList, LintDiagnostic, LintPass, @@ -396,6 +398,7 @@ symbols! { Ty, TyCtxt, TyKind, + Type, Unknown, Unsize, UnsizedConstParamTy, @@ -1176,6 +1179,7 @@ symbols! { generic_const_parameter_types, generic_param_attrs, generic_pattern_types, + generics, get_context, global_alloc_ty, global_allocator, diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 0e87b9d9cbb7..8b11e5bd7035 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -146,12 +146,53 @@ pub struct Trait { #[non_exhaustive] #[unstable(feature = "type_info", issue = "146922")] pub struct Struct { + /// Instantiated generics of the struct. + pub generics: &'static [Generic], /// All fields of the struct. pub fields: &'static [Field], /// Whether the struct field list is non-exhaustive. pub non_exhaustive: bool, } +/// Compile-time type information about instantiated generics of structs, enum and union variants. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub enum Generic { + /// Lifetimes. + Lifetime(Lifetime), + /// Types. + Type(GenericType), + /// Const parameters. + Const(Const), +} + +/// Compile-time type information about generic lifetimes. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Lifetime { + // No additional information to provide for now. +} + +/// Compile-time type information about instantiated generic types. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct GenericType { + /// The type itself. + pub ty: TypeId, +} + +/// Compile-time type information about generic const parameters. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Const { + /// The const's type. + pub ty: TypeId, +} + /// Compile-time type information about `bool`. #[derive(Debug)] #[non_exhaustive] diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 03ff5f55c4f7..9daf31029af6 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -2,7 +2,7 @@ use std::any::{Any, TypeId}; use std::mem::offset_of; -use std::mem::type_info::{Type, TypeKind}; +use std::mem::type_info::{Const, Generic, GenericType, Type, TypeKind}; #[test] fn test_arrays() { @@ -115,6 +115,24 @@ fn test_structs() { assert!(ty.fields[1].name == "1"); assert!(ty.fields[1].ty == TypeId::of::()); } + + const { + struct Generics<'a, T, const C: u64> { + a: &'a T, + } + + let Type { kind: Struct(ty), .. } = Type::of::>() else { + panic!() + }; + assert!(ty.fields.len() == 1); + assert!(ty.generics.len() == 3); + + let Generic::Lifetime(_) = ty.generics[0] else { panic!() }; + let Generic::Type(GenericType { ty: generic_ty, .. }) = ty.generics[1] else { panic!() }; + assert!(generic_ty == TypeId::of::()); + let Generic::Const(Const { ty: const_ty, .. }) = ty.generics[2] else { panic!() }; + assert!(const_ty == TypeId::of::()); + } } #[test] diff --git a/tests/ui/generics/wrong-number-of-args.rs b/tests/ui/generics/wrong-number-of-args.rs index 8bc384a3d817..9af16567cd75 100644 --- a/tests/ui/generics/wrong-number-of-args.rs +++ b/tests/ui/generics/wrong-number-of-args.rs @@ -127,7 +127,7 @@ mod r#trait { //~| HELP remove type D = Box; - //~^ ERROR missing generics for trait `GenericType` + //~^ ERROR missing generics for trait `r#trait::GenericType` //~| HELP add missing type E = Box>; diff --git a/tests/ui/generics/wrong-number-of-args.stderr b/tests/ui/generics/wrong-number-of-args.stderr index bedeeb812fc9..554d017d67e3 100644 --- a/tests/ui/generics/wrong-number-of-args.stderr +++ b/tests/ui/generics/wrong-number-of-args.stderr @@ -469,7 +469,7 @@ note: trait defined here, with 1 lifetime parameter: `'a` LL | trait GenericLifetime<'a> { | ^^^^^^^^^^^^^^^ -- -error[E0107]: missing generics for trait `GenericType` +error[E0107]: missing generics for trait `r#trait::GenericType` --> $DIR/wrong-number-of-args.rs:129:22 | LL | type D = Box; diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout index feda3401e462..e80cea8ece2f 100644 --- a/tests/ui/reflection/dump.bit32.run.stdout +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -148,6 +148,7 @@ Type { Type { kind: Struct( Struct { + generics: [], fields: [ Field { name: "a", @@ -171,6 +172,7 @@ Type { Type { kind: Struct( Struct { + generics: [], fields: [ Field { name: "a", @@ -188,6 +190,7 @@ Type { Type { kind: Struct( Struct { + generics: [], fields: [ Field { name: "0", @@ -207,6 +210,53 @@ Type { 12, ), } +Type { + kind: Struct( + Struct { + generics: [ + Lifetime( + Lifetime, + ), + Type( + GenericType { + ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013), + }, + ), + Type( + GenericType { + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + }, + ), + Const( + Const { + ty: TypeId(0x9ed91be891e304132cb86891e578f4a5), + }, + ), + ], + fields: [ + Field { + name: "a", + ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013), + offset: 4, + }, + Field { + name: "b", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 8, + }, + Field { + name: "l", + ty: TypeId(0x5d686ae9be5f6232dca1f88c0b941fd9), + offset: 0, + }, + ], + non_exhaustive: false, + }, + ), + size: Some( + 12, + ), +} Type { kind: Reference( Reference { diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout index d9fef71f619c..812a918e519d 100644 --- a/tests/ui/reflection/dump.bit64.run.stdout +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -148,6 +148,7 @@ Type { Type { kind: Struct( Struct { + generics: [], fields: [ Field { name: "a", @@ -171,6 +172,7 @@ Type { Type { kind: Struct( Struct { + generics: [], fields: [ Field { name: "a", @@ -188,6 +190,7 @@ Type { Type { kind: Struct( Struct { + generics: [], fields: [ Field { name: "0", @@ -207,6 +210,53 @@ Type { 16, ), } +Type { + kind: Struct( + Struct { + generics: [ + Lifetime( + Lifetime, + ), + Type( + GenericType { + ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013), + }, + ), + Type( + GenericType { + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + }, + ), + Const( + Const { + ty: TypeId(0x9ed91be891e304132cb86891e578f4a5), + }, + ), + ], + fields: [ + Field { + name: "a", + ty: TypeId(0x56ced5e4a15bd89050bb9674fa2df013), + offset: 8, + }, + Field { + name: "b", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 12, + }, + Field { + name: "l", + ty: TypeId(0x5d686ae9be5f6232dca1f88c0b941fd9), + offset: 0, + }, + ], + non_exhaustive: false, + }, + ), + size: Some( + 16, + ), +} Type { kind: Reference( Reference { diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs index fefaad325aea..d0da0582fb51 100644 --- a/tests/ui/reflection/dump.rs +++ b/tests/ui/reflection/dump.rs @@ -27,6 +27,12 @@ enum Bar { Foomp { a: (), b: &'static str }, } +struct Generics<'a, A, B, const C: u64> { + a: A, + b: B, + l: &'a (), +} + struct Unsized { x: u16, s: str, @@ -44,7 +50,7 @@ fn main() { [u8; 2], i8, i32, i64, i128, isize, u8, u32, u64, u128, usize, - Foo, Bar, NonExhaustiveStruct, TupleStruct, + Foo, Bar, NonExhaustiveStruct, TupleStruct, Generics, &Unsized, &str, &[u8], str, [u8], &u8, &mut u8, diff --git a/tests/ui/resolve/resolve-assoc-suggestions.stderr b/tests/ui/resolve/resolve-assoc-suggestions.stderr index 7d94fb5ca35f..e6311962884f 100644 --- a/tests/ui/resolve/resolve-assoc-suggestions.stderr +++ b/tests/ui/resolve/resolve-assoc-suggestions.stderr @@ -41,12 +41,22 @@ error[E0531]: cannot find tuple struct or tuple variant `Type` in this scope | LL | let Type(..); | ^^^^ not found in this scope + | +help: consider importing this tuple variant + | +LL + use std::mem::type_info::Generic::Type; + | error[E0425]: cannot find value `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:27:9 | LL | Type; | ^^^^ not found in this scope + | +help: consider importing this tuple variant + | +LL + use std::mem::type_info::Generic::Type; + | error[E0425]: cannot find type `method` in this scope --> $DIR/resolve-assoc-suggestions.rs:30:16 From e9037882c17d7ebd017c7403c934a5a5ef2d8488 Mon Sep 17 00:00:00 2001 From: Asuna Date: Tue, 20 Jan 2026 08:46:33 +0100 Subject: [PATCH 3504/3801] Support enums in type info reflection --- .../src/const_eval/type_info.rs | 142 ++++++++++++++---- compiler/rustc_span/src/symbol.rs | 2 + library/core/src/mem/type_info.rs | 28 ++++ library/coretests/tests/mem/type_info.rs | 42 ++++++ tests/ui/privacy/issue-79593.rs | 6 +- tests/ui/privacy/issue-79593.stderr | 6 +- tests/ui/reflection/dump.bit32.run.stdout | 41 ++++- tests/ui/reflection/dump.bit64.run.stdout | 41 ++++- tests/ui/reflection/dump.rs | 6 +- 9 files changed, 279 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 9fb01b1f5c5c..701adc7f732b 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -120,15 +120,11 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::Adt(adt_def, generics) => { - // TODO(type_info): Handle enum and union - if !adt_def.is_struct() { + // TODO(type_info): Handle union + if !adt_def.is_struct() && !adt_def.is_enum() { self.downcast(&field_dest, sym::Other)?.0 } else { - let (variant, variant_place) = - self.downcast(&field_dest, sym::Struct)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_adt_type_info(place, (ty, *adt_def), generics)?; - variant + self.write_adt_type_info(&field_dest, (ty, *adt_def), generics)? } } ty::Bool => { @@ -277,6 +273,25 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { self.write_immediate(ptr, &fields_slice_place) } + // Write fields for struct, enum variants + fn write_variant_fields( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + variant_def: &'tcx VariantDef, + variant_layout: TyAndLayout<'tcx>, + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + self.allocate_fill_and_write_slice_ptr( + place, + variant_def.fields.len() as u64, + |this, i, place| { + let field_def = &variant_def.fields[FieldIdx::from_usize(i as usize)]; + let field_ty = field_def.ty(*this.tcx, generics); + this.write_field(field_ty, place, variant_layout, Some(field_def.name), i) + }, + ) + } + fn write_field( &mut self, field_ty: Ty<'tcx>, @@ -363,20 +378,31 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { // FIXME(type_info): No semver considerations for now pub(crate) fn write_adt_type_info( &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, + place: &impl Writeable<'tcx, CtfeProvenance>, adt: (Ty<'tcx>, AdtDef<'tcx>), generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { + ) -> InterpResult<'tcx, VariantIdx> { let (adt_ty, adt_def) = adt; - match adt_def.adt_kind() { - AdtKind::Struct => self.write_struct_type_info( - place, - (adt_ty, adt_def.variant(VariantIdx::ZERO)), - generics, - ), + let variant_idx = match adt_def.adt_kind() { + AdtKind::Struct => { + let (variant, variant_place) = self.downcast(place, sym::Struct)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_struct_type_info( + place, + (adt_ty, adt_def.variant(VariantIdx::ZERO)), + generics, + )?; + variant + } + AdtKind::Enum => { + let (variant, variant_place) = self.downcast(place, sym::Enum)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_enum_type_info(place, adt, generics)?; + variant + } AdtKind::Union => todo!(), - AdtKind::Enum => todo!(), - } + }; + interp_ok(variant_idx) } pub(crate) fn write_struct_type_info( @@ -395,15 +421,9 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { match field.name { sym::generics => self.write_generics(field_place, generics)?, - sym::fields => self.allocate_fill_and_write_slice_ptr( - field_place, - struct_def.fields.len() as u64, - |this, i, place| { - let field_def = &struct_def.fields[FieldIdx::from_usize(i as usize)]; - let field_ty = field_def.ty(*this.tcx, generics); - this.write_field(field_ty, place, struct_layout, Some(field_def.name), i) - }, - )?, + sym::fields => { + self.write_variant_fields(field_place, struct_def, struct_layout, generics)? + } sym::non_exhaustive => { let is_non_exhaustive = struct_def.is_field_list_non_exhaustive(); self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? @@ -415,6 +435,76 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } + pub(crate) fn write_enum_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + enum_: (Ty<'tcx>, AdtDef<'tcx>), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (enum_ty, enum_def) = enum_; + let enum_layout = self.layout_of(enum_ty)?; + + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + sym::generics => self.write_generics(field_place, generics)?, + sym::variants => { + self.allocate_fill_and_write_slice_ptr( + field_place, + enum_def.variants().len() as u64, + |this, i, place| { + let variant_idx = VariantIdx::from_usize(i as usize); + let variant_def = &enum_def.variants()[variant_idx]; + let variant_layout = enum_layout.for_variant(this, variant_idx); + this.write_enum_variant(place, (variant_layout, &variant_def), generics) + }, + )?; + } + sym::non_exhaustive => { + let is_non_exhaustive = enum_def.is_variant_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + + fn write_enum_variant( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + variant: (TyAndLayout<'tcx>, &'tcx VariantDef), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (variant_layout, variant_def) = variant; + + for (field_idx, field_def) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + match field_def.name { + sym::name => { + let name_place = self.allocate_str_dedup(variant_def.name.as_str())?; + let ptr = self.mplace_to_ref(&name_place)?; + self.write_immediate(*ptr, &field_place)? + } + sym::fields => { + self.write_variant_fields(field_place, &variant_def, variant_layout, generics)? + } + sym::non_exhaustive => { + let is_non_exhaustive = variant_def.is_field_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), + } + } + interp_ok(()) + } + fn write_generics( &mut self, place: impl Writeable<'tcx, CtfeProvenance>, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 70f5c1d0c472..a3576b9a4437 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -235,6 +235,7 @@ symbols! { DynTrait, Encodable, Encoder, + Enum, Enumerate, Eq, Equal, @@ -2480,6 +2481,7 @@ symbols! { values, var, variant_count, + variants, vec, vec_as_mut_slice, vec_as_slice, diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 8b11e5bd7035..b66a836c4bd4 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -51,6 +51,8 @@ pub enum TypeKind { DynTrait(DynTrait), /// Structs. Struct(Struct), + /// Enums. + Enum(Enum), /// Primitive boolean type. Bool(Bool), /// Primitive character type. @@ -154,6 +156,32 @@ pub struct Struct { pub non_exhaustive: bool, } +/// Compile-time type information about enums. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Enum { + /// Instantiated generics of the enum. + pub generics: &'static [Generic], + /// All variants of the enum. + pub variants: &'static [Variant], + /// Whether the enum variant list is non-exhaustive. + pub non_exhaustive: bool, +} + +/// Compile-time type information about variants of enums. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Variant { + /// The name of the variant. + pub name: &'static str, + /// All fields of the variant. + pub fields: &'static [Field], + /// Whether the enum variant fields is non-exhaustive. + pub non_exhaustive: bool, +} + /// Compile-time type information about instantiated generics of structs, enum and union variants. #[derive(Debug)] #[non_exhaustive] diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 9daf31029af6..09e3a50d374c 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -135,6 +135,48 @@ fn test_structs() { } } +#[test] +fn test_enums() { + use TypeKind::*; + + const { + enum E { + Some(u32), + None, + #[non_exhaustive] + Foomp { + a: (), + b: &'static str, + }, + } + + let Type { kind: Enum(ty), size, .. } = Type::of::() else { panic!() }; + assert!(size == Some(size_of::())); + assert!(ty.variants.len() == 3); + + assert!(ty.variants[0].name == "Some"); + assert!(!ty.variants[0].non_exhaustive); + assert!(ty.variants[0].fields.len() == 1); + + assert!(ty.variants[1].name == "None"); + assert!(!ty.variants[1].non_exhaustive); + assert!(ty.variants[1].fields.len() == 0); + + assert!(ty.variants[2].name == "Foomp"); + assert!(ty.variants[2].non_exhaustive); + assert!(ty.variants[2].fields.len() == 2); + } + + const { + let Type { kind: Enum(ty), size, .. } = Type::of::>() else { panic!() }; + assert!(size == Some(size_of::>())); + assert!(ty.variants.len() == 2); + assert!(ty.generics.len() == 1); + let Generic::Type(GenericType { ty: generic_ty, .. }) = ty.generics[0] else { panic!() }; + assert!(generic_ty == TypeId::of::()); + } +} + #[test] fn test_primitives() { use TypeKind::*; diff --git a/tests/ui/privacy/issue-79593.rs b/tests/ui/privacy/issue-79593.rs index 39c222f7c341..663dd67fcdb1 100644 --- a/tests/ui/privacy/issue-79593.rs +++ b/tests/ui/privacy/issue-79593.rs @@ -10,7 +10,7 @@ mod foo { Pub {}; //~^ ERROR missing field `private` in initializer of `Pub` Enum::Variant { x: () }; - //~^ ERROR missing field `y` in initializer of `Enum` + //~^ ERROR missing field `y` in initializer of `foo::Enum` } } @@ -21,9 +21,9 @@ fn correct() { fn wrong() { foo::Enum::Variant { x: () }; - //~^ ERROR missing field `y` in initializer of `Enum` + //~^ ERROR missing field `y` in initializer of `foo::Enum` foo::Enum::Variant { }; - //~^ ERROR missing fields `x` and `y` in initializer of `Enum` + //~^ ERROR missing fields `x` and `y` in initializer of `foo::Enum` } fn main() {} diff --git a/tests/ui/privacy/issue-79593.stderr b/tests/ui/privacy/issue-79593.stderr index 5bb69836f609..74fea1a3ab76 100644 --- a/tests/ui/privacy/issue-79593.stderr +++ b/tests/ui/privacy/issue-79593.stderr @@ -4,7 +4,7 @@ error[E0063]: missing field `private` in initializer of `Pub` LL | Pub {}; | ^^^ missing `private` -error[E0063]: missing field `y` in initializer of `Enum` +error[E0063]: missing field `y` in initializer of `foo::Enum` --> $DIR/issue-79593.rs:12:9 | LL | Enum::Variant { x: () }; @@ -18,13 +18,13 @@ LL | foo::Pub {}; | = note: private field `private` that was not provided -error[E0063]: missing field `y` in initializer of `Enum` +error[E0063]: missing field `y` in initializer of `foo::Enum` --> $DIR/issue-79593.rs:23:5 | LL | foo::Enum::Variant { x: () }; | ^^^^^^^^^^^^^^^^^^ missing `y` -error[E0063]: missing fields `x` and `y` in initializer of `Enum` +error[E0063]: missing fields `x` and `y` in initializer of `foo::Enum` --> $DIR/issue-79593.rs:25:5 | LL | foo::Enum::Variant { }; diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout index e80cea8ece2f..a6ad84f5fef1 100644 --- a/tests/ui/reflection/dump.bit32.run.stdout +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -164,7 +164,46 @@ Type { ), } Type { - kind: Other, + kind: Enum( + Enum { + generics: [], + variants: [ + Variant { + name: "Some", + fields: [ + Field { + name: "0", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 4, + }, + ], + non_exhaustive: false, + }, + Variant { + name: "None", + fields: [], + non_exhaustive: false, + }, + Variant { + name: "Foomp", + fields: [ + Field { + name: "a", + ty: TypeId(0x41223169ff28813ba79b7268a2a968d9), + offset: 4, + }, + Field { + name: "b", + ty: TypeId(0xb98b1b7157a6417863eb502cd6cb5d6d), + offset: 4, + }, + ], + non_exhaustive: true, + }, + ], + non_exhaustive: false, + }, + ), size: Some( 12, ), diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout index 812a918e519d..45f0a2e2f063 100644 --- a/tests/ui/reflection/dump.bit64.run.stdout +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -164,7 +164,46 @@ Type { ), } Type { - kind: Other, + kind: Enum( + Enum { + generics: [], + variants: [ + Variant { + name: "Some", + fields: [ + Field { + name: "0", + ty: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7), + offset: 4, + }, + ], + non_exhaustive: false, + }, + Variant { + name: "None", + fields: [], + non_exhaustive: false, + }, + Variant { + name: "Foomp", + fields: [ + Field { + name: "a", + ty: TypeId(0x41223169ff28813ba79b7268a2a968d9), + offset: 4, + }, + Field { + name: "b", + ty: TypeId(0xb98b1b7157a6417863eb502cd6cb5d6d), + offset: 8, + }, + ], + non_exhaustive: true, + }, + ], + non_exhaustive: false, + }, + ), size: Some( 24, ), diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs index d0da0582fb51..755f0c900e33 100644 --- a/tests/ui/reflection/dump.rs +++ b/tests/ui/reflection/dump.rs @@ -24,7 +24,11 @@ struct TupleStruct(u32, u64); enum Bar { Some(u32), None, - Foomp { a: (), b: &'static str }, + #[non_exhaustive] + Foomp { + a: (), + b: &'static str, + }, } struct Generics<'a, A, B, const C: u64> { From 98e0c34f7f5ba6d68a6e3506d1569939fbf14627 Mon Sep 17 00:00:00 2001 From: Asuna Date: Thu, 5 Feb 2026 19:28:55 +0100 Subject: [PATCH 3505/3801] Support unions in type info reflection --- .../src/const_eval/type_info.rs | 48 ++++++++++++++++--- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/mem/type_info.rs | 13 +++++ library/coretests/tests/mem/type_info.rs | 41 ++++++++++++++++ tests/ui/reflection/dump.bit32.run.stdout | 22 +++++++++ tests/ui/reflection/dump.bit64.run.stdout | 22 +++++++++ tests/ui/reflection/dump.rs | 7 ++- 7 files changed, 146 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 701adc7f732b..0529d452626b 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -120,12 +120,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { variant } ty::Adt(adt_def, generics) => { - // TODO(type_info): Handle union - if !adt_def.is_struct() && !adt_def.is_enum() { - self.downcast(&field_dest, sym::Other)?.0 - } else { - self.write_adt_type_info(&field_dest, (ty, *adt_def), generics)? - } + self.write_adt_type_info(&field_dest, (ty, *adt_def), generics)? } ty::Bool => { let (variant, _variant_place) = @@ -394,13 +389,22 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { )?; variant } + AdtKind::Union => { + let (variant, variant_place) = self.downcast(place, sym::Union)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_union_type_info( + place, + (adt_ty, adt_def.variant(VariantIdx::ZERO)), + generics, + )?; + variant + } AdtKind::Enum => { let (variant, variant_place) = self.downcast(place, sym::Enum)?; let place = self.project_field(&variant_place, FieldIdx::ZERO)?; self.write_enum_type_info(place, adt, generics)?; variant } - AdtKind::Union => todo!(), }; interp_ok(variant_idx) } @@ -435,6 +439,36 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } + pub(crate) fn write_union_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + union_: (Ty<'tcx>, &'tcx VariantDef), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (union_ty, union_def) = union_; + let union_layout = self.layout_of(union_ty)?; + + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + sym::generics => self.write_generics(field_place, generics)?, + sym::fields => { + self.write_variant_fields(field_place, union_def, union_layout, generics)? + } + sym::non_exhaustive => { + let is_non_exhaustive = union_def.is_field_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + pub(crate) fn write_enum_type_info( &mut self, place: impl Writeable<'tcx, CtfeProvenance>, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a3576b9a4437..1a099f0cd70f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -400,6 +400,7 @@ symbols! { TyCtxt, TyKind, Type, + Union, Unknown, Unsize, UnsizedConstParamTy, diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index b66a836c4bd4..c2b2cf2f270d 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -53,6 +53,8 @@ pub enum TypeKind { Struct(Struct), /// Enums. Enum(Enum), + /// Unions. + Union(Union), /// Primitive boolean type. Bool(Bool), /// Primitive character type. @@ -156,6 +158,17 @@ pub struct Struct { pub non_exhaustive: bool, } +/// Compile-time type information about unions. +#[derive(Debug)] +#[non_exhaustive] +#[unstable(feature = "type_info", issue = "146922")] +pub struct Union { + /// Instantiated generics of the union. + pub generics: &'static [Generic], + /// All fields of the union. + pub fields: &'static [Field], +} + /// Compile-time type information about enums. #[derive(Debug)] #[non_exhaustive] diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 09e3a50d374c..808ef68783af 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -135,6 +135,47 @@ fn test_structs() { } } +#[test] +fn test_unions() { + use TypeKind::*; + + const { + union TestUnion { + first: i16, + second: u16, + } + + let Type { kind: Union(ty), size, .. } = Type::of::() else { panic!() }; + assert!(size == Some(size_of::())); + assert!(ty.fields.len() == 2); + assert!(ty.fields[0].name == "first"); + assert!(ty.fields[0].offset == offset_of!(TestUnion, first)); + assert!(ty.fields[1].name == "second"); + assert!(ty.fields[1].offset == offset_of!(TestUnion, second)); + } + + const { + union Generics<'a, T: Copy, const C: u64> { + a: T, + z: &'a (), + } + + let Type { kind: Union(ty), .. } = Type::of::>() else { + panic!() + }; + assert!(ty.fields.len() == 2); + assert!(ty.fields[0].offset == offset_of!(Generics<'static, i32, 1_u64>, a)); + assert!(ty.fields[1].offset == offset_of!(Generics<'static, i32, 1_u64>, z)); + + assert!(ty.generics.len() == 3); + let Generic::Lifetime(_) = ty.generics[0] else { panic!() }; + let Generic::Type(GenericType { ty: generic_ty, .. }) = ty.generics[1] else { panic!() }; + assert!(generic_ty == TypeId::of::()); + let Generic::Const(Const { ty: const_ty, .. }) = ty.generics[2] else { panic!() }; + assert!(const_ty == TypeId::of::()); + } +} + #[test] fn test_enums() { use TypeKind::*; diff --git a/tests/ui/reflection/dump.bit32.run.stdout b/tests/ui/reflection/dump.bit32.run.stdout index a6ad84f5fef1..24a467775725 100644 --- a/tests/ui/reflection/dump.bit32.run.stdout +++ b/tests/ui/reflection/dump.bit32.run.stdout @@ -296,6 +296,28 @@ Type { 12, ), } +Type { + kind: Union( + Union { + generics: [], + fields: [ + Field { + name: "first", + ty: TypeId(0xdeb66dd04fa9db03298cc77926096aae), + offset: 0, + }, + Field { + name: "second", + ty: TypeId(0xc50c4a8d8e150aa67101203f1fab1cd7), + offset: 0, + }, + ], + }, + ), + size: Some( + 2, + ), +} Type { kind: Reference( Reference { diff --git a/tests/ui/reflection/dump.bit64.run.stdout b/tests/ui/reflection/dump.bit64.run.stdout index 45f0a2e2f063..15f40d944173 100644 --- a/tests/ui/reflection/dump.bit64.run.stdout +++ b/tests/ui/reflection/dump.bit64.run.stdout @@ -296,6 +296,28 @@ Type { 16, ), } +Type { + kind: Union( + Union { + generics: [], + fields: [ + Field { + name: "first", + ty: TypeId(0xdeb66dd04fa9db03298cc77926096aae), + offset: 0, + }, + Field { + name: "second", + ty: TypeId(0xc50c4a8d8e150aa67101203f1fab1cd7), + offset: 0, + }, + ], + }, + ), + size: Some( + 2, + ), +} Type { kind: Reference( Reference { diff --git a/tests/ui/reflection/dump.rs b/tests/ui/reflection/dump.rs index 755f0c900e33..57669ca85f30 100644 --- a/tests/ui/reflection/dump.rs +++ b/tests/ui/reflection/dump.rs @@ -42,6 +42,11 @@ struct Unsized { s: str, } +union Union { + first: i16, + second: u16, +} + macro_rules! dump_types { ($($ty:ty),+ $(,)?) => { $(println!("{:#?}", const { Type::of::<$ty>() });)+ @@ -54,7 +59,7 @@ fn main() { [u8; 2], i8, i32, i64, i128, isize, u8, u32, u64, u128, usize, - Foo, Bar, NonExhaustiveStruct, TupleStruct, Generics, + Foo, Bar, NonExhaustiveStruct, TupleStruct, Generics, Union, &Unsized, &str, &[u8], str, [u8], &u8, &mut u8, From b410cb01fe86d992a97f6316a7265716d0e3f851 Mon Sep 17 00:00:00 2001 From: Asuna Date: Sat, 7 Feb 2026 19:03:34 +0100 Subject: [PATCH 3506/3801] Simplify the writing of tuple type info --- .../src/const_eval/type_info.rs | 56 +++++++------------ 1 file changed, 19 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 0529d452626b..97206e138697 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -98,7 +98,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { .fields .len() ); - self.write_tuple_fields(tuple_place, fields, ty)?; + self.write_tuple_type_info(tuple_place, fields, ty)?; variant } ty::Array(ty, len) => { @@ -232,42 +232,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } - // TODO(type_info): Remove this method, use `allocate_fill_and_write_slice_ptr` as it's more general. - pub(crate) fn write_tuple_fields( - &mut self, - tuple_place: impl Writeable<'tcx, CtfeProvenance>, - fields: &[Ty<'tcx>], - tuple_ty: Ty<'tcx>, - ) -> InterpResult<'tcx> { - // project into the `type_info::Tuple::fields` field - let fields_slice_place = self.project_field(&tuple_place, FieldIdx::ZERO)?; - // get the `type_info::Field` type from `fields: &[Field]` - let field_type = fields_slice_place - .layout() - .ty - .builtin_deref(false) - .unwrap() - .sequence_element_type(self.tcx.tcx); - // Create an array with as many elements as the number of fields in the inspected tuple - let fields_layout = - self.layout_of(Ty::new_array(self.tcx.tcx, field_type, fields.len() as u64))?; - let fields_place = self.allocate(fields_layout, MemoryKind::Stack)?; - let mut fields_places = self.project_array_fields(&fields_place)?; - - let tuple_layout = self.layout_of(tuple_ty)?; - - while let Some((i, place)) = fields_places.next(self)? { - let field_ty = fields[i as usize]; - self.write_field(field_ty, place, tuple_layout, None, i)?; - } - - let fields_place = fields_place.map_provenance(CtfeProvenance::as_immutable); - - let ptr = Immediate::new_slice(fields_place.ptr(), fields.len() as u64, self); - - self.write_immediate(ptr, &fields_slice_place) - } - // Write fields for struct, enum variants fn write_variant_fields( &mut self, @@ -325,6 +289,24 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } + pub(crate) fn write_tuple_type_info( + &mut self, + tuple_place: impl Writeable<'tcx, CtfeProvenance>, + fields: &[Ty<'tcx>], + tuple_ty: Ty<'tcx>, + ) -> InterpResult<'tcx> { + let tuple_layout = self.layout_of(tuple_ty)?; + let fields_slice_place = self.project_field(&tuple_place, FieldIdx::ZERO)?; + self.allocate_fill_and_write_slice_ptr( + fields_slice_place, + fields.len() as u64, + |this, i, place| { + let field_ty = fields[i as usize]; + this.write_field(field_ty, place, tuple_layout, None, i) + }, + ) + } + pub(crate) fn write_array_type_info( &mut self, place: impl Writeable<'tcx, CtfeProvenance>, From a575fe168f2293a9c8c2945f5c5795eaec2f4d34 Mon Sep 17 00:00:00 2001 From: Asuna Date: Tue, 10 Feb 2026 01:28:35 +0100 Subject: [PATCH 3507/3801] Erase type lifetime before writing type ID --- compiler/rustc_const_eval/src/const_eval/type_info.rs | 5 ++++- compiler/rustc_const_eval/src/interpret/intrinsics.rs | 7 ++++++- library/coretests/tests/mem/type_info.rs | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 97206e138697..7741027981d0 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -273,7 +273,10 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { let ptr = self.mplace_to_ref(&name_place)?; self.write_immediate(*ptr, &field_place)? } - sym::ty => self.write_type_id(field_ty, &field_place)?, + sym::ty => { + let field_ty = self.tcx.erase_and_anonymize_regions(field_ty); + self.write_type_id(field_ty, &field_place)? + } sym::offset => { let offset = layout.fields.offset(idx as usize); self.write_scalar( diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 2ea5e4a25c11..49038315b546 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -13,7 +13,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint}; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug, ty}; use rustc_span::{Symbol, sym}; use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; @@ -73,6 +73,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ty: Ty<'tcx>, dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx, ()> { + debug_assert!( + !ty.has_erasable_regions(), + "type {ty:?} has regions that need erasing before writing a TypeId", + ); + let tcx = self.tcx; let type_id_hash = tcx.type_id_hash(ty).as_u128(); let op = self.const_val_to_op( diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 808ef68783af..2483b4c2aacd 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -91,7 +91,7 @@ fn test_structs() { assert!(ty.fields[1].ty == TypeId::of::()); assert!(ty.fields[1].offset == offset_of!(TestStruct, second)); assert!(ty.fields[2].name == "reference"); - assert!(ty.fields[2].ty != TypeId::of::<&'static u16>()); // FIXME(type_info): should be == + assert!(ty.fields[2].ty == TypeId::of::<&'static u16>()); assert!(ty.fields[2].offset == offset_of!(TestStruct, reference)); } From 6ab6734d4badb8fb8956873df1c3e2e2389a42f4 Mon Sep 17 00:00:00 2001 From: Asuna Date: Tue, 10 Feb 2026 02:09:07 +0100 Subject: [PATCH 3508/3801] Move ADT related code to a sub module for type info --- .../src/const_eval/type_info.rs | 271 +---------------- .../src/const_eval/type_info/adt.rs | 276 ++++++++++++++++++ 2 files changed, 280 insertions(+), 267 deletions(-) create mode 100644 compiler/rustc_const_eval/src/const_eval/type_info/adt.rs diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 7741027981d0..0fd70d784d4f 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -1,14 +1,13 @@ +mod adt; + use std::borrow::Cow; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_ast::Mutability; use rustc_hir::LangItem; +use rustc_middle::span_bug; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{ - self, AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, ScalarInt, Ty, - VariantDef, -}; -use rustc_middle::{bug, span_bug}; +use rustc_middle::ty::{self, Const, ScalarInt, Ty}; use rustc_span::{Symbol, sym}; use crate::const_eval::CompileTimeMachine; @@ -232,25 +231,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } - // Write fields for struct, enum variants - fn write_variant_fields( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - variant_def: &'tcx VariantDef, - variant_layout: TyAndLayout<'tcx>, - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - self.allocate_fill_and_write_slice_ptr( - place, - variant_def.fields.len() as u64, - |this, i, place| { - let field_def = &variant_def.fields[FieldIdx::from_usize(i as usize)]; - let field_ty = field_def.ty(*this.tcx, generics); - this.write_field(field_ty, place, variant_layout, Some(field_def.name), i) - }, - ) - } - fn write_field( &mut self, field_ty: Ty<'tcx>, @@ -355,249 +335,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { interp_ok(()) } - // FIXME(type_info): No semver considerations for now - pub(crate) fn write_adt_type_info( - &mut self, - place: &impl Writeable<'tcx, CtfeProvenance>, - adt: (Ty<'tcx>, AdtDef<'tcx>), - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx, VariantIdx> { - let (adt_ty, adt_def) = adt; - let variant_idx = match adt_def.adt_kind() { - AdtKind::Struct => { - let (variant, variant_place) = self.downcast(place, sym::Struct)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_struct_type_info( - place, - (adt_ty, adt_def.variant(VariantIdx::ZERO)), - generics, - )?; - variant - } - AdtKind::Union => { - let (variant, variant_place) = self.downcast(place, sym::Union)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_union_type_info( - place, - (adt_ty, adt_def.variant(VariantIdx::ZERO)), - generics, - )?; - variant - } - AdtKind::Enum => { - let (variant, variant_place) = self.downcast(place, sym::Enum)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_enum_type_info(place, adt, generics)?; - variant - } - }; - interp_ok(variant_idx) - } - - pub(crate) fn write_struct_type_info( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - struct_: (Ty<'tcx>, &'tcx VariantDef), - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - let (struct_ty, struct_def) = struct_; - let struct_layout = self.layout_of(struct_ty)?; - - for (field_idx, field) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - - match field.name { - sym::generics => self.write_generics(field_place, generics)?, - sym::fields => { - self.write_variant_fields(field_place, struct_def, struct_layout, generics)? - } - sym::non_exhaustive => { - let is_non_exhaustive = struct_def.is_field_list_non_exhaustive(); - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? - } - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), - } - } - - interp_ok(()) - } - - pub(crate) fn write_union_type_info( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - union_: (Ty<'tcx>, &'tcx VariantDef), - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - let (union_ty, union_def) = union_; - let union_layout = self.layout_of(union_ty)?; - - for (field_idx, field) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - - match field.name { - sym::generics => self.write_generics(field_place, generics)?, - sym::fields => { - self.write_variant_fields(field_place, union_def, union_layout, generics)? - } - sym::non_exhaustive => { - let is_non_exhaustive = union_def.is_field_list_non_exhaustive(); - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? - } - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), - } - } - - interp_ok(()) - } - - pub(crate) fn write_enum_type_info( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - enum_: (Ty<'tcx>, AdtDef<'tcx>), - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - let (enum_ty, enum_def) = enum_; - let enum_layout = self.layout_of(enum_ty)?; - - for (field_idx, field) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - - match field.name { - sym::generics => self.write_generics(field_place, generics)?, - sym::variants => { - self.allocate_fill_and_write_slice_ptr( - field_place, - enum_def.variants().len() as u64, - |this, i, place| { - let variant_idx = VariantIdx::from_usize(i as usize); - let variant_def = &enum_def.variants()[variant_idx]; - let variant_layout = enum_layout.for_variant(this, variant_idx); - this.write_enum_variant(place, (variant_layout, &variant_def), generics) - }, - )?; - } - sym::non_exhaustive => { - let is_non_exhaustive = enum_def.is_variant_list_non_exhaustive(); - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? - } - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), - } - } - - interp_ok(()) - } - - fn write_enum_variant( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - variant: (TyAndLayout<'tcx>, &'tcx VariantDef), - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - let (variant_layout, variant_def) = variant; - - for (field_idx, field_def) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - match field_def.name { - sym::name => { - let name_place = self.allocate_str_dedup(variant_def.name.as_str())?; - let ptr = self.mplace_to_ref(&name_place)?; - self.write_immediate(*ptr, &field_place)? - } - sym::fields => { - self.write_variant_fields(field_place, &variant_def, variant_layout, generics)? - } - sym::non_exhaustive => { - let is_non_exhaustive = variant_def.is_field_list_non_exhaustive(); - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? - } - other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), - } - } - interp_ok(()) - } - - fn write_generics( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - self.allocate_fill_and_write_slice_ptr(place, generics.len() as u64, |this, i, place| { - match generics[i as usize].kind() { - GenericArgKind::Lifetime(region) => this.write_generic_lifetime(region, place), - GenericArgKind::Type(ty) => this.write_generic_type(ty, place), - GenericArgKind::Const(c) => this.write_generic_const(c, place), - } - }) - } - - fn write_generic_lifetime( - &mut self, - _region: Region<'tcx>, - place: MPlaceTy<'tcx>, - ) -> InterpResult<'tcx> { - let (variant_idx, _) = self.downcast(&place, sym::Lifetime)?; - self.write_discriminant(variant_idx, &place)?; - interp_ok(()) - } - - fn write_generic_type(&mut self, ty: Ty<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { - let (variant_idx, variant_place) = self.downcast(&place, sym::Type)?; - let generic_type_place = self.project_field(&variant_place, FieldIdx::ZERO)?; - - for (field_idx, field_def) in generic_type_place - .layout() - .ty - .ty_adt_def() - .unwrap() - .non_enum_variant() - .fields - .iter_enumerated() - { - let field_place = self.project_field(&generic_type_place, field_idx)?; - match field_def.name { - sym::ty => self.write_type_id(ty, &field_place)?, - other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), - } - } - - self.write_discriminant(variant_idx, &place)?; - interp_ok(()) - } - - fn write_generic_const(&mut self, c: Const<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { - let ConstKind::Value(c) = c.kind() else { bug!("expected a computed const, got {c:?}") }; - - let (variant_idx, variant_place) = self.downcast(&place, sym::Const)?; - let const_place = self.project_field(&variant_place, FieldIdx::ZERO)?; - - for (field_idx, field_def) in const_place - .layout() - .ty - .ty_adt_def() - .unwrap() - .non_enum_variant() - .fields - .iter_enumerated() - { - let field_place = self.project_field(&const_place, field_idx)?; - match field_def.name { - sym::ty => self.write_type_id(c.ty, &field_place)?, - other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), - } - } - - self.write_discriminant(variant_idx, &place)?; - interp_ok(()) - } - fn write_int_type_info( &mut self, place: impl Writeable<'tcx, CtfeProvenance>, diff --git a/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs b/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs new file mode 100644 index 000000000000..60f7b95e799a --- /dev/null +++ b/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs @@ -0,0 +1,276 @@ +use rustc_abi::{FieldIdx, VariantIdx}; +use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::{ + AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, Ty, VariantDef, +}; +use rustc_middle::{bug, span_bug}; +use rustc_span::sym; + +use crate::const_eval::CompileTimeMachine; +use crate::interpret::{ + CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Projectable, Scalar, Writeable, interp_ok, +}; + +impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { + // FIXME(type_info): No semver considerations for now + pub(crate) fn write_adt_type_info( + &mut self, + place: &impl Writeable<'tcx, CtfeProvenance>, + adt: (Ty<'tcx>, AdtDef<'tcx>), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx, VariantIdx> { + let (adt_ty, adt_def) = adt; + let variant_idx = match adt_def.adt_kind() { + AdtKind::Struct => { + let (variant, variant_place) = self.downcast(place, sym::Struct)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_struct_type_info( + place, + (adt_ty, adt_def.variant(VariantIdx::ZERO)), + generics, + )?; + variant + } + AdtKind::Union => { + let (variant, variant_place) = self.downcast(place, sym::Union)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_union_type_info( + place, + (adt_ty, adt_def.variant(VariantIdx::ZERO)), + generics, + )?; + variant + } + AdtKind::Enum => { + let (variant, variant_place) = self.downcast(place, sym::Enum)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_enum_type_info(place, adt, generics)?; + variant + } + }; + interp_ok(variant_idx) + } + + pub(crate) fn write_struct_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + struct_: (Ty<'tcx>, &'tcx VariantDef), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (struct_ty, struct_def) = struct_; + let struct_layout = self.layout_of(struct_ty)?; + + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + sym::generics => self.write_generics(field_place, generics)?, + sym::fields => { + self.write_variant_fields(field_place, struct_def, struct_layout, generics)? + } + sym::non_exhaustive => { + let is_non_exhaustive = struct_def.is_field_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + + pub(crate) fn write_union_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + union_: (Ty<'tcx>, &'tcx VariantDef), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (union_ty, union_def) = union_; + let union_layout = self.layout_of(union_ty)?; + + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + sym::generics => self.write_generics(field_place, generics)?, + sym::fields => { + self.write_variant_fields(field_place, union_def, union_layout, generics)? + } + sym::non_exhaustive => { + let is_non_exhaustive = union_def.is_field_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + + pub(crate) fn write_enum_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + enum_: (Ty<'tcx>, AdtDef<'tcx>), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (enum_ty, enum_def) = enum_; + let enum_layout = self.layout_of(enum_ty)?; + + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + sym::generics => self.write_generics(field_place, generics)?, + sym::variants => { + self.allocate_fill_and_write_slice_ptr( + field_place, + enum_def.variants().len() as u64, + |this, i, place| { + let variant_idx = VariantIdx::from_usize(i as usize); + let variant_def = &enum_def.variants()[variant_idx]; + let variant_layout = enum_layout.for_variant(this, variant_idx); + this.write_enum_variant(place, (variant_layout, &variant_def), generics) + }, + )?; + } + sym::non_exhaustive => { + let is_non_exhaustive = enum_def.is_variant_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + + fn write_enum_variant( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + variant: (TyAndLayout<'tcx>, &'tcx VariantDef), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (variant_layout, variant_def) = variant; + + for (field_idx, field_def) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + match field_def.name { + sym::name => { + let name_place = self.allocate_str_dedup(variant_def.name.as_str())?; + let ptr = self.mplace_to_ref(&name_place)?; + self.write_immediate(*ptr, &field_place)? + } + sym::fields => { + self.write_variant_fields(field_place, &variant_def, variant_layout, generics)? + } + sym::non_exhaustive => { + let is_non_exhaustive = variant_def.is_field_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), + } + } + interp_ok(()) + } + + // Write fields for struct, enum variants + fn write_variant_fields( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + variant_def: &'tcx VariantDef, + variant_layout: TyAndLayout<'tcx>, + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + self.allocate_fill_and_write_slice_ptr( + place, + variant_def.fields.len() as u64, + |this, i, place| { + let field_def = &variant_def.fields[FieldIdx::from_usize(i as usize)]; + let field_ty = field_def.ty(*this.tcx, generics); + this.write_field(field_ty, place, variant_layout, Some(field_def.name), i) + }, + ) + } + + fn write_generics( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + self.allocate_fill_and_write_slice_ptr(place, generics.len() as u64, |this, i, place| { + match generics[i as usize].kind() { + GenericArgKind::Lifetime(region) => this.write_generic_lifetime(region, place), + GenericArgKind::Type(ty) => this.write_generic_type(ty, place), + GenericArgKind::Const(c) => this.write_generic_const(c, place), + } + }) + } + + fn write_generic_lifetime( + &mut self, + _region: Region<'tcx>, + place: MPlaceTy<'tcx>, + ) -> InterpResult<'tcx> { + let (variant_idx, _) = self.downcast(&place, sym::Lifetime)?; + self.write_discriminant(variant_idx, &place)?; + interp_ok(()) + } + + fn write_generic_type(&mut self, ty: Ty<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { + let (variant_idx, variant_place) = self.downcast(&place, sym::Type)?; + let generic_type_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + for (field_idx, field_def) in generic_type_place + .layout() + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .iter_enumerated() + { + let field_place = self.project_field(&generic_type_place, field_idx)?; + match field_def.name { + sym::ty => self.write_type_id(ty, &field_place)?, + other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), + } + } + + self.write_discriminant(variant_idx, &place)?; + interp_ok(()) + } + + fn write_generic_const(&mut self, c: Const<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { + let ConstKind::Value(c) = c.kind() else { bug!("expected a computed const, got {c:?}") }; + + let (variant_idx, variant_place) = self.downcast(&place, sym::Const)?; + let const_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + for (field_idx, field_def) in const_place + .layout() + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .iter_enumerated() + { + let field_place = self.project_field(&const_place, field_idx)?; + match field_def.name { + sym::ty => self.write_type_id(c.ty, &field_place)?, + other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), + } + } + + self.write_discriminant(variant_idx, &place)?; + interp_ok(()) + } +} From 78dc744e93028188c66d92dc2064b2107dd9992c Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Tue, 10 Feb 2026 22:20:02 +0900 Subject: [PATCH 3509/3801] unwind/wasm: fix compile error by wrapping wasm_throw in unsafe block --- library/unwind/src/wasm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/unwind/src/wasm.rs b/library/unwind/src/wasm.rs index 2bff306af293..cb6e90ba180b 100644 --- a/library/unwind/src/wasm.rs +++ b/library/unwind/src/wasm.rs @@ -73,7 +73,7 @@ pub unsafe fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwi // corresponds with llvm::WebAssembly::Tag::CPP_EXCEPTION // in llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h const CPP_EXCEPTION_TAG: i32 = 0; - wasm_throw(CPP_EXCEPTION_TAG, exception.cast()) + unsafe { wasm_throw(CPP_EXCEPTION_TAG, exception.cast()) } } _ => { let _ = exception; From 11e4873b96961d14202a8c63d83a21be5b7f7b82 Mon Sep 17 00:00:00 2001 From: ron Date: Tue, 10 Feb 2026 10:22:05 -0500 Subject: [PATCH 3510/3801] Fix typos and grammar in compiler and build documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - compiler/rustc_codegen_llvm/src/debuginfo/doc.md: fix 5 issues (adaption → adaptation, "allow to" → "allow V-ing" x3, later → latter + plural) - compiler/rustc_thread_pool/src/sleep/README.md: fix 2 issues (idle → active per context, then → than) - src/bootstrap/README.md: fix 2 issues (rust → Rust, add missing article "the") - src/ci/docker/README.md: fix 2 issues ("come form" → "come from", grammar) --- compiler/rustc_codegen_llvm/src/debuginfo/doc.md | 10 +++++----- compiler/rustc_thread_pool/src/sleep/README.md | 4 ++-- src/bootstrap/README.md | 4 ++-- src/ci/docker/README.md | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/doc.md b/compiler/rustc_codegen_llvm/src/debuginfo/doc.md index aaec4e68c174..f5ea5ea77c4b 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/doc.md +++ b/compiler/rustc_codegen_llvm/src/debuginfo/doc.md @@ -16,7 +16,7 @@ module to generate correct metadata and insert it into the LLVM IR. As the exact format of metadata trees may change between different LLVM versions, we now use LLVM [DIBuilder](https://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) -to create metadata where possible. This will hopefully ease the adaption of +to create metadata where possible. This will hopefully ease the adaptation of this module to future LLVM versions. The public API of the module is a set of functions that will insert the @@ -87,19 +87,19 @@ describe the type anew. This behavior is encapsulated in the ## Source Locations and Line Information In addition to data type descriptions the debugging information must also -allow to map machine code locations back to source code locations in order +allow mapping machine code locations back to source code locations in order to be useful. This functionality is also handled in this module. The -following functions allow to control source mappings: +following functions allow controlling source mappings: + `set_source_location()` + `clear_source_location()` + `start_emitting_source_locations()` -`set_source_location()` allows to set the current source location. All IR +`set_source_location()` allows setting the current source location. All IR instructions created after a call to this function will be linked to the given source location, until another location is specified with `set_source_location()` or the source location is cleared with -`clear_source_location()`. In the later case, subsequent IR instruction +`clear_source_location()`. In the latter case, subsequent IR instructions will not be linked to any source location. As you can see, this is a stateful API (mimicking the one in LLVM), so be careful with source locations set by previous calls. It's probably best to not rely on any diff --git a/compiler/rustc_thread_pool/src/sleep/README.md b/compiler/rustc_thread_pool/src/sleep/README.md index 1e11da55f4a4..948c2922a434 100644 --- a/compiler/rustc_thread_pool/src/sleep/README.md +++ b/compiler/rustc_thread_pool/src/sleep/README.md @@ -32,7 +32,7 @@ There are three main thread states: waiting to be awoken. We sometimes refer to the final two states collectively as **inactive**. -Threads begin as idle but transition to idle and finally sleeping when +Threads begin as active but transition to idle and finally sleeping when they're unable to find work to do. ## Sleepy threads @@ -160,7 +160,7 @@ not complete. It is possible -- if unlikely -- that enough activity occurs for Thread A to observe the same JEC value that it saw when getting sleepy. If the new work being published came from *inside* the thread-pool, then this race condition isn't too harmful. It means that we have fewer workers processing the -work then we should, but we won't deadlock. This seems like an acceptable risk +work than we should, but we won't deadlock. This seems like an acceptable risk given that this is unlikely in practice. However, if the work was posted as an *external* job, that is a problem. In that diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index e46fed7c426a..ef2de9b37ed0 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -175,8 +175,8 @@ When you use bootstrap, you'll call it through the entry point script (`x`, `x.ps1`, or `x.py`). However, most of the code lives in `src/bootstrap`. `bootstrap` has a difficult problem: it is written in Rust, but yet it is run before the Rust compiler is built! To work around this, there are two components -of bootstrap: the main one written in rust, and `bootstrap.py`. `bootstrap.py` -is what gets run by entry point script. It takes care of downloading the prebuilt +of bootstrap: the main one written in Rust, and `bootstrap.py`. `bootstrap.py` +is what gets run by the entry point script. It takes care of downloading the prebuilt stage 0 compiler, std and Cargo binaries, which are then used to build the bootstrap binary. diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 4ee02e9bf005..5d3a74edc995 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -48,7 +48,7 @@ Refer to the [dev guide](https://rustc-dev-guide.rust-lang.org/tests/docker.html ## Docker Toolbox on Windows For Windows before Windows 10, the docker images can be run on Windows via -[Docker Toolbox]. There are several preparation needs to be made before running +[Docker Toolbox]. There are several preparations that need to be made before running a Docker image. 1. Stop the virtual machine from the terminal with `docker-machine stop` @@ -92,7 +92,7 @@ To run the image, A number of these images take quite a long time to compile as they're building whole gcc toolchains to do cross builds with. Much of this is relatively self-explanatory but some images use [crosstool-ng] which isn't quite as self -explanatory. Below is a description of where these `*.defconfig` files come form, +explanatory. Below is a description of where these `*.defconfig` files come from, how to generate them, and how the existing ones were generated. [crosstool-ng]: https://github.com/crosstool-ng/crosstool-ng From da80677d6a84c1a3ea3e22785392c91ccae6a69b Mon Sep 17 00:00:00 2001 From: ron Date: Tue, 10 Feb 2026 10:22:19 -0500 Subject: [PATCH 3511/3801] Fix typos and grammar in top-level and src/doc documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CONTRIBUTING.md: add missing verb "is" - INSTALL.md: fix subject-verb agreement ("requires" → "require") - RELEASES.md: fix 4 issues (previous → previously, remove extra "is", add hyphen in Rust-for-Linux, results → result) - src/doc/not_found.md: fix misspelling ("Standary" → "Standard") - src/doc/index.md: fix awkward grammar in Embedded Rust Book description --- CONTRIBUTING.md | 2 +- INSTALL.md | 2 +- RELEASES.md | 8 ++++---- src/doc/index.md | 5 ++--- src/doc/not_found.md | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2b5699dcd098..3f052eca48e6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ the Zulip stream is the best place to *ask* for help. Documentation for contributing to the compiler or tooling is located in the [Guide to Rustc Development][rustc-dev-guide], commonly known as the [rustc-dev-guide]. Documentation for the -standard library in the [Standard library developers Guide][std-dev-guide], commonly known as the [std-dev-guide]. +standard library is in the [Standard library developers Guide][std-dev-guide], commonly known as the [std-dev-guide]. ## Making changes to subtrees and submodules diff --git a/INSTALL.md b/INSTALL.md index dd6c64b3df5f..0e998101fcd1 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -233,7 +233,7 @@ itself back on after some time). ### MSVC -MSVC builds of Rust additionally requires an installation of: +MSVC builds of Rust additionally require an installation of: - Visual Studio 2022 (or later) build tools so `rustc` can use its linker. Older Visual Studio versions such as 2019 *may* work but aren't actively tested. diff --git a/RELEASES.md b/RELEASES.md index 424e12ceec05..3c0a95f8462b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1546,7 +1546,7 @@ Compatibility Notes - [Check well-formedness of the source type's signature in fn pointer casts.](https://github.com/rust-lang/rust/pull/129021) This partly closes a soundness hole that comes when casting a function item to function pointer - [Use equality instead of subtyping when resolving type dependent paths.](https://github.com/rust-lang/rust/pull/129073) - Linking on macOS now correctly includes Rust's default deployment target. Due to a linker bug, you might have to pass `MACOSX_DEPLOYMENT_TARGET` or fix your `#[link]` attributes to point to the correct frameworks. See . -- [Rust will now correctly raise an error for `repr(Rust)` written on non-`struct`/`enum`/`union` items, since it previous did not have any effect.](https://github.com/rust-lang/rust/pull/129422) +- [Rust will now correctly raise an error for `repr(Rust)` written on non-`struct`/`enum`/`union` items, since it previously did not have any effect.](https://github.com/rust-lang/rust/pull/129422) - The future incompatibility lint `deprecated_cfg_attr_crate_type_name` [has been made into a hard error](https://github.com/rust-lang/rust/pull/129670). It was used to deny usage of `#![crate_type]` and `#![crate_name]` attributes in `#![cfg_attr]`, which required a hack in the compiler to be able to change the used crate type and crate name after cfg expansion. Users can use `--crate-type` instead of `#![cfg_attr(..., crate_type = "...")]` and `--crate-name` instead of `#![cfg_attr(..., crate_name = "...")]` when running `rustc`/`cargo rustc` on the command line. Use of those two attributes outside of `#![cfg_attr]` continue to be fully supported. @@ -1722,7 +1722,7 @@ Cargo Compatibility Notes ------------------- - We now [disallow setting some built-in cfgs via the command-line](https://github.com/rust-lang/rust/pull/126158) with the newly added [`explicit_builtin_cfgs_in_flags`](https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#explicit-builtin-cfgs-in-flags) lint in order to prevent incoherent state, eg. `windows` cfg active but target is Linux based. The appropriate [`rustc` flag](https://doc.rust-lang.org/rustc/command-line-arguments.html) should be used instead. -- The standard library has a new implementation of `binary_search` which is significantly improves performance ([#128254](https://github.com/rust-lang/rust/pull/128254)). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation. +- The standard library has a new implementation of `binary_search` which significantly improves performance ([#128254](https://github.com/rust-lang/rust/pull/128254)). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation. - [illumos/Solaris now sets `MSG_NOSIGNAL` when writing to sockets](https://github.com/rust-lang/rust/pull/128259). This avoids killing the process with SIGPIPE when writing to a closed socket, which matches the existing behavior on other UNIX targets. - [Removes a problematic hack that always passed the --whole-archive linker flag for tests, which may cause linker errors for code accidentally relying on it.](https://github.com/rust-lang/rust/pull/128400) - The WebAssembly target features `multivalue` and `reference-types` are now @@ -1872,7 +1872,7 @@ These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. -- [Add a Rust-for Linux `auto` CI job to check kernel builds.](https://github.com/rust-lang/rust/pull/125209/) +- [Add a Rust-for-Linux `auto` CI job to check kernel builds.](https://github.com/rust-lang/rust/pull/125209/) Version 1.80.1 (2024-08-08) =========================== @@ -4510,7 +4510,7 @@ Compatibility Notes saturating to `0` instead][89926]. In the real world the panic happened mostly on platforms with buggy monotonic clock implementations rather than catching programming errors like reversing the start and end times. Such programming - errors will now results in `0` rather than a panic. + errors will now result in `0` rather than a panic. - In a future release we're planning to increase the baseline requirements for the Linux kernel to version 3.2, and for glibc to version 2.17. We'd love your feedback in [PR #95026][95026]. diff --git a/src/doc/index.md b/src/doc/index.md index 892057a8f4db..418939353975 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -194,9 +194,8 @@ resources maintained by the [Embedded Working Group] useful. #### The Embedded Rust Book -[The Embedded Rust Book] is targeted at developers familiar with embedded -development and familiar with Rust, but have not used Rust for embedded -development. +[The Embedded Rust Book] is targeted at developers who are familiar with embedded +development and Rust, but who have not used Rust for embedded development. [The Embedded Rust Book]: embedded-book/index.html [Rust project]: https://www.rust-lang.org diff --git a/src/doc/not_found.md b/src/doc/not_found.md index 9552759d2b8b..69e6ae3e2d03 100644 --- a/src/doc/not_found.md +++ b/src/doc/not_found.md @@ -41,7 +41,7 @@ Some things that might be helpful to you though:

  • { pub fn get_attribute_path(&self) -> hir::AttrPath { AttrPath { - segments: self.segments().copied().collect::>().into_boxed_slice(), + segments: self.segments().map(|s| s.name).collect::>().into_boxed_slice(), span: self.span(), } } diff --git a/compiler/rustc_attr_parsing/src/safety.rs b/compiler/rustc_attr_parsing/src/safety.rs index 817785108a1e..68aeca2bbda9 100644 --- a/compiler/rustc_attr_parsing/src/safety.rs +++ b/compiler/rustc_attr_parsing/src/safety.rs @@ -22,7 +22,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { return; } - let name = (attr_path.segments.len() == 1).then_some(attr_path.segments[0].name); + let name = (attr_path.segments.len() == 1).then_some(attr_path.segments[0]); if let Some(name) = name && [sym::cfg_trace, sym::cfg_attr_trace].contains(&name) { diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index 88efb910c160..e86ecb451fc2 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -104,7 +104,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { let (applied, only) = allowed_targets_applied(allowed_targets, target, cx.features); let name = cx.attr_path.clone(); - let lint = if name.segments[0].name == sym::deprecated + let lint = if name.segments[0] == sym::deprecated && ![ Target::Closure, Target::Expression, diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index e69ed0eea6b0..4879646a1107 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -27,7 +27,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { return; } - let builtin_attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); + let builtin_attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)); // Check input tokens for built-in and key-value attributes. match builtin_attr_info { diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 7bc9080ba022..557daa94b98e 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -13,7 +13,7 @@ use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpa use rustc_hir::AttrPath; use rustc_hir::attrs::CfgEntry; use rustc_parse::exp; -use rustc_span::{ErrorGuaranteed, Ident, Span}; +use rustc_span::{ErrorGuaranteed, Span, sym}; use crate::errors; @@ -47,7 +47,7 @@ fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result bool { impl<'ast> visit::Visitor<'ast> for CfgFinder { type Result = ControlFlow<()>; fn visit_attribute(&mut self, attr: &'ast Attribute) -> ControlFlow<()> { - if attr - .ident() - .is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr) - { + if attr.name().is_some_and(|name| name == sym::cfg || name == sym::cfg_attr) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 8135fd43dd93..93043c69579a 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -18,7 +18,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self as ty, Instance, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; -use rustc_span::{Ident, Span, Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; use rustc_target::spec::Os; use crate::errors; @@ -357,7 +357,7 @@ fn process_builtin_attrs( } } - let Some(Ident { name, .. }) = attr.ident() else { + let Some(name) = attr.name() else { continue; }; diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 6422779e13c9..52b7339e0140 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2110,7 +2110,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { let mut attr_pos = None; for (pos, attr) in item.attrs().iter().enumerate() { if !attr.is_doc_comment() && !self.cx.expanded_inert_attrs.is_marked(attr) { - let name = attr.ident().map(|ident| ident.name); + let name = attr.name(); if name == Some(sym::cfg) || name == Some(sym::cfg_attr) { cfg_pos = Some(pos); // a cfg attr found, no need to search anymore break; @@ -2187,7 +2187,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { } else if rustc_attr_parsing::is_builtin_attr(attr) && !AttributeParser::::is_parsed_attribute(&attr.path()) { - let attr_name = attr.ident().unwrap().name; + let attr_name = attr.name().unwrap(); // `#[cfg]` and `#[cfg_attr]` are special - they are // eagerly evaluated. if attr_name != sym::cfg_trace && attr_name != sym::cfg_attr_trace { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index c60471848c89..483e864f69d4 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1182,7 +1182,7 @@ pub enum AttrArgs { #[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)] pub struct AttrPath { - pub segments: Box<[Ident]>, + pub segments: Box<[Symbol]>, pub span: Span, } @@ -1198,7 +1198,7 @@ impl AttrPath { segments: path .segments .iter() - .map(|i| Ident { name: i.ident.name, span: lower_span(i.ident.span) }) + .map(|i| i.ident.name) .collect::>() .into_boxed_slice(), span: lower_span(path.span), @@ -1208,7 +1208,11 @@ impl AttrPath { impl fmt::Display for AttrPath { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", join_path_idents(&self.segments)) + write!( + f, + "{}", + join_path_idents(self.segments.iter().map(|i| Ident { name: *i, span: DUMMY_SP })) + ) } } @@ -1313,7 +1317,7 @@ impl AttributeExt for Attribute { /// For a single-segment attribute, returns its name; otherwise, returns `None`. #[inline] - fn ident(&self) -> Option { + fn name(&self) -> Option { match &self { Attribute::Unparsed(n) => { if let [ident] = n.path.segments.as_ref() { @@ -1329,7 +1333,7 @@ impl AttributeExt for Attribute { #[inline] fn path_matches(&self, name: &[Symbol]) -> bool { match &self { - Attribute::Unparsed(n) => n.path.segments.iter().map(|ident| &ident.name).eq(name), + Attribute::Unparsed(n) => n.path.segments.iter().eq(name), _ => false, } } @@ -1365,13 +1369,20 @@ impl AttributeExt for Attribute { } #[inline] - fn ident_path(&self) -> Option> { + fn symbol_path(&self) -> Option> { match &self { Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()), _ => None, } } + fn path_span(&self) -> Option { + match &self { + Attribute::Unparsed(attr) => Some(attr.path.span), + Attribute::Parsed(_) => None, + } + } + #[inline] fn doc_str(&self) -> Option { match &self { @@ -1451,11 +1462,6 @@ impl Attribute { AttributeExt::value_span(self) } - #[inline] - pub fn ident(&self) -> Option { - AttributeExt::ident(self) - } - #[inline] pub fn path_matches(&self, name: &[Symbol]) -> bool { AttributeExt::path_matches(self, name) @@ -1491,11 +1497,6 @@ impl Attribute { AttributeExt::path(self) } - #[inline] - pub fn ident_path(&self) -> Option> { - AttributeExt::ident_path(self) - } - #[inline] pub fn doc_str(&self) -> Option { AttributeExt::doc_str(self) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index b3b416955230..80e8bcb9a93a 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -22,7 +22,7 @@ use rustc_hir::{ TyPatKind, }; use rustc_span::source_map::SourceMap; -use rustc_span::{FileName, Ident, Span, Symbol, kw, sym}; +use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym}; use {rustc_ast as ast, rustc_hir as hir}; pub fn id_to_string(cx: &dyn rustc_hir::intravisit::HirTyCtxt<'_>, hir_id: HirId) -> String { @@ -136,7 +136,11 @@ impl<'a> State<'a> { .path .segments .iter() - .map(|i| ast::PathSegment { ident: *i, args: None, id: DUMMY_NODE_ID }) + .map(|i| ast::PathSegment { + ident: Ident { name: *i, span: DUMMY_SP }, + args: None, + id: DUMMY_NODE_ID, + }) .collect(), tokens: None, }; diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 44fdf146f9c7..e04178645fdd 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -86,9 +86,9 @@ fn has_cfg_or_cfg_attr(attrs: &[Attribute]) -> bool { // NOTE: Builtin attributes like `cfg` and `cfg_attr` cannot be renamed via imports. // Therefore, the absence of a literal `cfg` or `cfg_attr` guarantees that // we don't need to do any eager expansion. - attrs.iter().any(|attr| { - attr.ident().is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr) - }) + attrs + .iter() + .any(|attr| attr.name().is_some_and(|ident| ident == sym::cfg || ident == sym::cfg_attr)) } impl<'a> Parser<'a> { @@ -398,10 +398,8 @@ impl<'a> Parser<'a> { /// - any single-segment, non-builtin attributes are present, e.g. `derive`, /// `test`, `global_allocator`. fn needs_tokens(attrs: &[ast::Attribute]) -> bool { - attrs.iter().any(|attr| match attr.ident() { + attrs.iter().any(|attr| match attr.name() { None => !attr.is_doc_comment(), - Some(ident) => { - ident.name == sym::cfg_attr || !rustc_feature::is_builtin_attr_name(ident.name) - } + Some(name) => name == sym::cfg_attr || !rustc_feature::is_builtin_attr_name(name), }) } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7822614a05cb..eb551201b083 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -388,7 +388,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr.path .segments .first() - .and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) + .and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)) { match attr.style { ast::AttrStyle::Outer => { @@ -425,7 +425,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Attribute::Unparsed(unparsed_attr) = attr && let Some(BuiltinAttribute { duplicates, .. }) = - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) + attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)) { check_duplicates( self.tcx, diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 118229ffc990..fe6fb3d65194 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -24,7 +24,7 @@ impl<'a> HashStable> for [hir::Attribute] { .filter(|attr| { attr.is_doc_comment().is_none() // FIXME(jdonszelmann) have a better way to handle ignored attrs - && !attr.ident().is_some_and(|ident| hcx.is_ignored_attr(ident.name)) + && !attr.name().is_some_and(|ident| hcx.is_ignored_attr(ident)) }) .collect(); diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 7ab2a72d75b5..61ebc73182c0 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -859,8 +859,8 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator } continue; } else if !cfg_info.parent_is_doc_cfg - && let Some(ident) = attr.ident() - && matches!(ident.name, sym::cfg | sym::cfg_trace) + && let Some(name) = attr.name() + && matches!(name, sym::cfg | sym::cfg_trace) && let Some(attr) = single(attr.meta_item_list()?) && let Ok(new_cfg) = Cfg::parse(&attr) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 764b3a0acdb6..72996cc4f21e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2673,8 +2673,8 @@ fn add_without_unwanted_attributes<'hir>( import_parent, )); } - hir::Attribute::Unparsed(normal) if let [ident] = &*normal.path.segments => { - if is_inline || ident.name != sym::cfg_trace { + hir::Attribute::Unparsed(normal) if let [name] = &*normal.path.segments => { + if is_inline || *name != sym::cfg_trace { // If it's not a `cfg()` attribute, we keep it. attrs.push((Cow::Borrowed(attr), import_parent)); } diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 95f5537f394c..d4bf74c29514 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -40,8 +40,8 @@ fn add_only_cfg_attributes(attrs: &mut Vec, new_attrs: &[Attribute]) new_attr.cfg = d.cfg.clone(); attrs.push(Attribute::Parsed(AttributeKind::Doc(Box::new(new_attr)))); } else if let Attribute::Unparsed(normal) = attr - && let [ident] = &*normal.path.segments - && ident.name == sym::cfg_trace + && let [name] = &*normal.path.segments + && *name == sym::cfg_trace { // If it's a `cfg()` attribute, we keep it. attrs.push(attr.clone()); diff --git a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs index 53d9725703c3..84b65d3185e3 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs @@ -4,18 +4,19 @@ use clippy_utils::is_from_proc_macro; use rustc_ast::{AttrStyle, Attribute}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, LintContext}; +use rustc_ast::attr::AttributeExt; // Separate each crate's features. pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) { if !attr.span.in_external_macro(cx.sess().source_map()) && let AttrStyle::Outer = attr.style - && let Some(ident) = attr.ident() + && let Some(path_span) = attr.path_span() && !is_from_proc_macro(cx, attr) { #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] - span_lint_and_then(cx, ALLOW_ATTRIBUTES, ident.span, "#[allow] attribute found", |diag| { + span_lint_and_then(cx, ALLOW_ATTRIBUTES, path_span, "#[allow] attribute found", |diag| { diag.span_suggestion( - ident.span, + path_span, "replace it with", "expect", Applicability::MachineApplicable, diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index 91c2dc7f3dc6..679ccfb8de3a 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -574,16 +574,16 @@ impl EarlyLintPass for PostExpansionEarlyAttributes { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) { if let Some(items) = &attr.meta_item_list() - && let Some(ident) = attr.ident() + && let Some(name) = attr.name() { - if matches!(ident.name, sym::allow) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { + if matches!(name, sym::allow) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { allow_attributes::check(cx, attr); } - if matches!(ident.name, sym::allow | sym::expect) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { - allow_attributes_without_reason::check(cx, ident.name, items, attr); + if matches!(name, sym::allow | sym::expect) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { + allow_attributes_without_reason::check(cx, name, items, attr); } - if is_lint_level(ident.name, attr.id) { - blanket_clippy_restriction_lints::check(cx, ident.name, items); + if is_lint_level(name, attr.id) { + blanket_clippy_restriction_lints::check(cx, name, items); } if items.is_empty() || !attr.has_name(sym::deprecated) { return; diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs index 1cebc18edc90..aa9a6654bee3 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs @@ -15,7 +15,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) { return; } if let Some(lint_list) = &attr.meta_item_list() - && attr.ident().is_some_and(|ident| is_lint_level(ident.name, attr.id)) + && attr.name().is_some_and(|name| is_lint_level(name, attr.id)) { for lint in lint_list { match item.kind { diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs index c3bc9048c23a..28ea2e4fa1f0 100644 --- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs +++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs @@ -270,7 +270,7 @@ fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool { cx.tcx.hir_parent_id_iter(hir_id).any(|id| { cx.tcx.hir_attrs(id).iter().any(|attr| { matches!( - attr.ident().map(|ident| ident.name), + attr.name(), Some(sym::cfg_trace | sym::cfg_attr_trace) ) }) diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index ac221743cfd6..375b275cd113 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -287,8 +287,8 @@ fn is_doc_attr(attr: &Attribute) -> bool { match attr { Attribute::Parsed(AttributeKind::DocComment { .. }) => true, Attribute::Unparsed(attr) - if let [ident] = &*attr.path.segments - && ident.name == sym::doc => + if let [name] = &*attr.path.segments + && *name == sym::doc => { matches!(attr.args, AttrArgs::Eq { .. }) }, diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index 2fd773b06781..94e4ede14048 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -20,10 +20,11 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( name: Symbol, ) -> impl Iterator { attrs.iter().filter(move |attr| { - if let Some([clippy, segment2]) = attr.ident_path().as_deref() - && clippy.name == sym::clippy + if let [clippy, segment2] = &*attr.path() + && *clippy == sym::clippy { - let new_name = match segment2.name { + let path_span = attr.path_span().expect("Clippy attributes are unparsed and have a span"); + let new_name = match *segment2 { sym::cyclomatic_complexity => Some("cognitive_complexity"), sym::author | sym::version @@ -35,7 +36,7 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( | sym::has_significant_drop | sym::format_args => None, _ => { - sess.dcx().span_err(segment2.span, "usage of unknown attribute"); + sess.dcx().span_err(path_span, "usage of unknown attribute"); return false; }, }; @@ -43,17 +44,17 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( match new_name { Some(new_name) => { sess.dcx() - .struct_span_err(segment2.span, "usage of deprecated attribute") + .struct_span_err(path_span, "usage of deprecated attribute") .with_span_suggestion( - segment2.span, + path_span, "consider using", - new_name, + format!("clippy::{}", new_name), Applicability::MachineApplicable, ) .emit(); false }, - None => segment2.name == name, + None => *segment2 == name, } } else { false 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 d9254fca9453..7fb8616072a5 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -348,9 +348,9 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) { match attr.kind { AttrKind::Normal(..) => { - if let Some(ident) = attr.ident() { + if let Some(name) = attr.name() { // NOTE: This will likely have false positives, like `allow = 1` - let ident_string = ident.to_string(); + let ident_string = name.to_string(); if attr.style == AttrStyle::Outer { ( Pat::OwnedMultiStr(vec!["#[".to_owned() + &ident_string, ident_string]), diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr index fb51313dab69..0ebc43739d6b 100644 --- a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr +++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr @@ -1,8 +1,8 @@ error: usage of deprecated attribute - --> tests/ui/renamed_builtin_attr.rs:3:11 + --> tests/ui/renamed_builtin_attr.rs:3:3 | LL | #[clippy::cyclomatic_complexity = "1"] - | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `cognitive_complexity` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `clippy::cognitive_complexity` error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/unknown_attribute.stderr b/src/tools/clippy/tests/ui/unknown_attribute.stderr index b306abe0a9d1..1d4d50ffc02a 100644 --- a/src/tools/clippy/tests/ui/unknown_attribute.stderr +++ b/src/tools/clippy/tests/ui/unknown_attribute.stderr @@ -1,8 +1,8 @@ error: usage of unknown attribute - --> tests/ui/unknown_attribute.rs:3:11 + --> tests/ui/unknown_attribute.rs:3:3 | LL | #[clippy::unknown] - | ^^^^^^^ + | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs index 381c938ae806..d03d33514046 100644 --- a/src/tools/rustfmt/src/attr.rs +++ b/src/tools/rustfmt/src/attr.rs @@ -336,8 +336,8 @@ impl Rewrite for ast::Attribute { rewrite_doc_comment(snippet, shape.comment(context.config), context.config) } else { let should_skip = self - .ident() - .map(|s| context.skip_context.attributes.skip(s.name.as_str())) + .name() + .map(|s| context.skip_context.attributes.skip(s.as_str())) .unwrap_or(false); let prefix = attr_prefix(self); From 4d0dbee8362a6b2f46526a8050ca8b6e658bfc38 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 9 Dec 2025 09:49:50 +0100 Subject: [PATCH 1151/3801] Make attr path symbols rather than idents --- clippy_lints/src/attrs/allow_attributes.rs | 7 ++++--- clippy_lints/src/attrs/mod.rs | 12 ++++++------ clippy_lints/src/attrs/useless_attribute.rs | 2 +- clippy_lints/src/incompatible_msrv.rs | 2 +- clippy_lints/src/missing_doc.rs | 4 ++-- clippy_utils/src/attrs.rs | 17 +++++++++-------- clippy_utils/src/check_proc_macro.rs | 4 ++-- tests/ui/renamed_builtin_attr.stderr | 4 ++-- tests/ui/unknown_attribute.stderr | 4 ++-- 9 files changed, 29 insertions(+), 27 deletions(-) diff --git a/clippy_lints/src/attrs/allow_attributes.rs b/clippy_lints/src/attrs/allow_attributes.rs index 53d9725703c3..84b65d3185e3 100644 --- a/clippy_lints/src/attrs/allow_attributes.rs +++ b/clippy_lints/src/attrs/allow_attributes.rs @@ -4,18 +4,19 @@ use clippy_utils::is_from_proc_macro; use rustc_ast::{AttrStyle, Attribute}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, LintContext}; +use rustc_ast::attr::AttributeExt; // Separate each crate's features. pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) { if !attr.span.in_external_macro(cx.sess().source_map()) && let AttrStyle::Outer = attr.style - && let Some(ident) = attr.ident() + && let Some(path_span) = attr.path_span() && !is_from_proc_macro(cx, attr) { #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] - span_lint_and_then(cx, ALLOW_ATTRIBUTES, ident.span, "#[allow] attribute found", |diag| { + span_lint_and_then(cx, ALLOW_ATTRIBUTES, path_span, "#[allow] attribute found", |diag| { diag.span_suggestion( - ident.span, + path_span, "replace it with", "expect", Applicability::MachineApplicable, diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index 91c2dc7f3dc6..679ccfb8de3a 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -574,16 +574,16 @@ impl EarlyLintPass for PostExpansionEarlyAttributes { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) { if let Some(items) = &attr.meta_item_list() - && let Some(ident) = attr.ident() + && let Some(name) = attr.name() { - if matches!(ident.name, sym::allow) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { + if matches!(name, sym::allow) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { allow_attributes::check(cx, attr); } - if matches!(ident.name, sym::allow | sym::expect) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { - allow_attributes_without_reason::check(cx, ident.name, items, attr); + if matches!(name, sym::allow | sym::expect) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { + allow_attributes_without_reason::check(cx, name, items, attr); } - if is_lint_level(ident.name, attr.id) { - blanket_clippy_restriction_lints::check(cx, ident.name, items); + if is_lint_level(name, attr.id) { + blanket_clippy_restriction_lints::check(cx, name, items); } if items.is_empty() || !attr.has_name(sym::deprecated) { return; diff --git a/clippy_lints/src/attrs/useless_attribute.rs b/clippy_lints/src/attrs/useless_attribute.rs index 1cebc18edc90..aa9a6654bee3 100644 --- a/clippy_lints/src/attrs/useless_attribute.rs +++ b/clippy_lints/src/attrs/useless_attribute.rs @@ -15,7 +15,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) { return; } if let Some(lint_list) = &attr.meta_item_list() - && attr.ident().is_some_and(|ident| is_lint_level(ident.name, attr.id)) + && attr.name().is_some_and(|name| is_lint_level(name, attr.id)) { for lint in lint_list { match item.kind { diff --git a/clippy_lints/src/incompatible_msrv.rs b/clippy_lints/src/incompatible_msrv.rs index c3bc9048c23a..28ea2e4fa1f0 100644 --- a/clippy_lints/src/incompatible_msrv.rs +++ b/clippy_lints/src/incompatible_msrv.rs @@ -270,7 +270,7 @@ fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool { cx.tcx.hir_parent_id_iter(hir_id).any(|id| { cx.tcx.hir_attrs(id).iter().any(|attr| { matches!( - attr.ident().map(|ident| ident.name), + attr.name(), Some(sym::cfg_trace | sym::cfg_attr_trace) ) }) diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index ac221743cfd6..375b275cd113 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -287,8 +287,8 @@ fn is_doc_attr(attr: &Attribute) -> bool { match attr { Attribute::Parsed(AttributeKind::DocComment { .. }) => true, Attribute::Unparsed(attr) - if let [ident] = &*attr.path.segments - && ident.name == sym::doc => + if let [name] = &*attr.path.segments + && *name == sym::doc => { matches!(attr.args, AttrArgs::Eq { .. }) }, diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs index 2fd773b06781..94e4ede14048 100644 --- a/clippy_utils/src/attrs.rs +++ b/clippy_utils/src/attrs.rs @@ -20,10 +20,11 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( name: Symbol, ) -> impl Iterator { attrs.iter().filter(move |attr| { - if let Some([clippy, segment2]) = attr.ident_path().as_deref() - && clippy.name == sym::clippy + if let [clippy, segment2] = &*attr.path() + && *clippy == sym::clippy { - let new_name = match segment2.name { + let path_span = attr.path_span().expect("Clippy attributes are unparsed and have a span"); + let new_name = match *segment2 { sym::cyclomatic_complexity => Some("cognitive_complexity"), sym::author | sym::version @@ -35,7 +36,7 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( | sym::has_significant_drop | sym::format_args => None, _ => { - sess.dcx().span_err(segment2.span, "usage of unknown attribute"); + sess.dcx().span_err(path_span, "usage of unknown attribute"); return false; }, }; @@ -43,17 +44,17 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( match new_name { Some(new_name) => { sess.dcx() - .struct_span_err(segment2.span, "usage of deprecated attribute") + .struct_span_err(path_span, "usage of deprecated attribute") .with_span_suggestion( - segment2.span, + path_span, "consider using", - new_name, + format!("clippy::{}", new_name), Applicability::MachineApplicable, ) .emit(); false }, - None => segment2.name == name, + None => *segment2 == name, } } else { false diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index d9254fca9453..7fb8616072a5 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -348,9 +348,9 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) { match attr.kind { AttrKind::Normal(..) => { - if let Some(ident) = attr.ident() { + if let Some(name) = attr.name() { // NOTE: This will likely have false positives, like `allow = 1` - let ident_string = ident.to_string(); + let ident_string = name.to_string(); if attr.style == AttrStyle::Outer { ( Pat::OwnedMultiStr(vec!["#[".to_owned() + &ident_string, ident_string]), diff --git a/tests/ui/renamed_builtin_attr.stderr b/tests/ui/renamed_builtin_attr.stderr index fb51313dab69..0ebc43739d6b 100644 --- a/tests/ui/renamed_builtin_attr.stderr +++ b/tests/ui/renamed_builtin_attr.stderr @@ -1,8 +1,8 @@ error: usage of deprecated attribute - --> tests/ui/renamed_builtin_attr.rs:3:11 + --> tests/ui/renamed_builtin_attr.rs:3:3 | LL | #[clippy::cyclomatic_complexity = "1"] - | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `cognitive_complexity` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `clippy::cognitive_complexity` error: aborting due to 1 previous error diff --git a/tests/ui/unknown_attribute.stderr b/tests/ui/unknown_attribute.stderr index b306abe0a9d1..1d4d50ffc02a 100644 --- a/tests/ui/unknown_attribute.stderr +++ b/tests/ui/unknown_attribute.stderr @@ -1,8 +1,8 @@ error: usage of unknown attribute - --> tests/ui/unknown_attribute.rs:3:11 + --> tests/ui/unknown_attribute.rs:3:3 | LL | #[clippy::unknown] - | ^^^^^^^ + | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error From 7c50ee61160b8a69581ca628864a7e73f7c95750 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 22 Dec 2025 20:56:16 +0530 Subject: [PATCH 1152/3801] rename PostcardNew to bidirectional-postcard-prototype --- .../crates/proc-macro-srv-cli/src/main.rs | 10 +++++----- .../crates/proc-macro-srv-cli/src/main_loop.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index 01b261dab748..7e50888114ba 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -31,7 +31,7 @@ fn main() -> std::io::Result<()> { clap::Arg::new("format") .long("format") .action(clap::ArgAction::Set) - .default_value("postcard-new") + .default_value("bidirectional-postcard-prototype") .value_parser(clap::builder::EnumValueParser::::new()), clap::Arg::new("version") .long("version") @@ -52,12 +52,12 @@ fn main() -> std::io::Result<()> { enum ProtocolFormat { JsonLegacy, PostcardLegacy, - PostcardNew, + BidirectionalPostcardPrototype, } impl ValueEnum for ProtocolFormat { fn value_variants<'a>() -> &'a [Self] { - &[ProtocolFormat::JsonLegacy, ProtocolFormat::PostcardLegacy, ProtocolFormat::PostcardNew] + &[ProtocolFormat::JsonLegacy, ProtocolFormat::PostcardLegacy, ProtocolFormat::BidirectionalPostcardPrototype] } fn to_possible_value(&self) -> Option { @@ -66,14 +66,14 @@ impl ValueEnum for ProtocolFormat { ProtocolFormat::PostcardLegacy => { Some(clap::builder::PossibleValue::new("postcard-legacy")) } - ProtocolFormat::PostcardNew => Some(clap::builder::PossibleValue::new("postcard-new")), + ProtocolFormat::BidirectionalPostcardPrototype => Some(clap::builder::PossibleValue::new("postcard-new")), } } fn from_str(input: &str, _ignore_case: bool) -> Result { match input { "json-legacy" => Ok(ProtocolFormat::JsonLegacy), "postcard-legacy" => Ok(ProtocolFormat::PostcardLegacy), - "postcard-new" => Ok(ProtocolFormat::PostcardNew), + "bidirectional-postcard-prototype" => Ok(ProtocolFormat::BidirectionalPostcardPrototype), _ => Err(format!("unknown protocol format: {input}")), } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 9c66a308b18e..8666c1367717 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -38,7 +38,7 @@ pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> { match format { ProtocolFormat::JsonLegacy => run_::(), ProtocolFormat::PostcardLegacy => run_::(), - ProtocolFormat::PostcardNew => run_new::(), + ProtocolFormat::BidirectionalPostcardPrototype => run_new::(), } } From 26ef77a94a1ae929c80573509c69117e5b2c3c2b Mon Sep 17 00:00:00 2001 From: Roy Ammerschuber Date: Tue, 2 Dec 2025 17:46:44 +0100 Subject: [PATCH 1153/3801] tree borrows: detect no_valid_exposed_references errors accurately --- .../src/borrow_tracker/tree_borrows/perms.rs | 12 ++--- .../src/borrow_tracker/tree_borrows/tree.rs | 33 +++++++++++-- .../borrow_tracker/tree_borrows/wildcard.rs | 14 +++++- ...cross_tree_update_main_invalid_exposed2.rs | 48 +++++++++++++++++++ ...s_tree_update_main_invalid_exposed2.stderr | 14 ++++++ 5 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed2.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed2.stderr diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs index bd4573f94013..064c1cc5b95f 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs @@ -374,9 +374,9 @@ impl Permission { self.inner.strongest_idempotent_foreign_access(prot) } - /// Returns the strongest access allowed from a child to this node without + /// Returns the strongest access allowed that is local to this node without /// causing UB (only considers possible transitions to this permission). - pub fn strongest_allowed_child_access(&self, protected: bool) -> WildcardAccessLevel { + pub fn strongest_allowed_local_access(&self, protected: bool) -> WildcardAccessLevel { match self.inner { // Everything except disabled can be accessed by read access. Disabled => WildcardAccessLevel::None, @@ -794,9 +794,9 @@ mod propagation_optimization_checks { /// Checks that `strongest_allowed_child_access` correctly /// represents which transitions are possible. #[test] - fn strongest_allowed_child_access() { + fn strongest_allowed_local_access() { for (permission, protected) in <(Permission, bool)>::exhaustive() { - let strongest_child_access = permission.strongest_allowed_child_access(protected); + let strongest_local_access = permission.strongest_allowed_local_access(protected); let is_read_valid = Permission::perform_access( AccessKind::Read, @@ -814,8 +814,8 @@ mod propagation_optimization_checks { ) .is_some(); - assert_eq!(is_read_valid, strongest_child_access >= WildcardAccessLevel::Read); - assert_eq!(is_write_valid, strongest_child_access >= WildcardAccessLevel::Write); + assert_eq!(is_read_valid, strongest_local_access >= WildcardAccessLevel::Read); + assert_eq!(is_write_valid, strongest_local_access >= WildcardAccessLevel::Write); } } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 900e9c3729c8..c8e27ebf0ff3 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -111,7 +111,7 @@ impl LocationState { // We need to update the wildcard state, if the permission // of an exposed pointer changes. if node.is_exposed { - let access_type = self.permission.strongest_allowed_child_access(protected); + let access_type = self.permission.strongest_allowed_local_access(protected); WildcardState::update_exposure(idx, access_type, nodes, wildcard_accesses); } } @@ -1034,6 +1034,9 @@ impl<'tcx> LocationTree { wildcard_state.access_relatedness(access_kind, only_foreign) }; + // Whether there is an exposed node in this tree that allows this access. + let mut has_valid_exposed = false; + // This does a traversal across the tree updating children before their parents. The // difference to `perform_normal_access` is that we take the access relatedness from // the wildcard tracking state of the node instead of from the visitor itself. @@ -1082,6 +1085,17 @@ impl<'tcx> LocationTree { return Err(no_valid_exposed_references_error(diagnostics)); }; + let mut entry = args.data.perms.entry(args.idx); + let perm = entry.or_insert(node.default_location_state()); + + // We only count exposed nodes through which an access could happen. + if node.is_exposed + && perm.permission.strongest_allowed_local_access(protected).allows(access_kind) + && max_local_tag.is_none_or(|max_local_tag| max_local_tag >= node.tag) + { + has_valid_exposed = true; + } + let Some(relatedness) = wildcard_relatedness.to_relatedness() else { // If the access type is Either, then we do not apply any transition // to this node, but we still update each of its children. @@ -1090,8 +1104,6 @@ impl<'tcx> LocationTree { return Ok(()); }; - let mut entry = args.data.perms.entry(args.idx); - let perm = entry.or_insert(node.default_location_state()); // We know the exact relatedness, so we can actually do precise checks. perm.perform_transition( args.idx, @@ -1115,6 +1127,21 @@ impl<'tcx> LocationTree { }) }, )?; + // If there is no exposed node in this tree that allows this access, then the + // access *must* be foreign. So we check if the root of this tree would allow this + // as a foreign access, and if not, then we can error. + // In practice, all wildcard trees accept foreign accesses, but the main tree does + // not, so this catches UB when none of the nodes in the main tree allows this access. + if !has_valid_exposed + && self + .wildcard_accesses + .get(root) + .unwrap() + .access_relatedness(access_kind, /* only_foreign */ true) + .is_none() + { + return Err(no_valid_exposed_references_error(diagnostics)).into(); + } interp_ok(()) } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs index 3b55a9e36ea6..b5ae0ee4c7d3 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs @@ -20,6 +20,16 @@ pub enum WildcardAccessLevel { Read, Write, } +impl WildcardAccessLevel { + /// Weather this access kind is allowed at this level. + pub fn allows(self, kind: AccessKind) -> bool { + let required_level = match kind { + AccessKind::Read => Self::Read, + AccessKind::Write => Self::Write, + }; + required_level <= self + } +} /// Where the access happened relative to the current node. #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -430,7 +440,7 @@ impl Tree { .map(|p| p.permission()) .unwrap_or_else(|| node.default_location_state().permission()); - let access_type = perm.strongest_allowed_child_access(protected); + let access_type = perm.strongest_allowed_local_access(protected); WildcardState::update_exposure( id, access_type, @@ -480,7 +490,7 @@ impl Tree { perms.get(id).copied().unwrap_or_else(|| node.default_location_state()); perm.permission() - .strongest_allowed_child_access(protected_tags.contains_key(&node.tag)) + .strongest_allowed_local_access(protected_tags.contains_key(&node.tag)) } else { WildcardAccessLevel::None }; diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed2.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed2.rs new file mode 100644 index 000000000000..ca430cad1670 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed2.rs @@ -0,0 +1,48 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance +use std::cell::Cell; + +/// Checks how accesses from one subtree affect other subtrees. +/// This test checks that an access from a subtree performs a +/// wildcard access on all earlier trees, and that local +/// accesses are treated as access errors for tags that are +/// larger than the root of the accessed subtree. +/// This tests the case were we have multiple exposed nodes on +/// the main tree that are invalid because their tag is too large. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let int1 = ref1 as *mut u32 as usize; + let wild = int1 as *mut u32; + + // Activates ref1. + *ref1 = 4; + + let ref2 = unsafe { &mut *wild }; + + // Freezes ref1. + let ref3 = unsafe { &mut *(ptr_base as *mut Cell) }; + let _int3 = ref3 as *mut Cell as usize; + let ref4 = unsafe { &mut *(ptr_base as *mut Cell) }; + let _int4 = ref4 as *mut Cell as usize; + + // ┌──────────────┐ + // │ │ + // │ptr_base(Act) ├───────────┬──────────────────┐ * + // │ │ │ │ │ + // └──────┬───────┘ │ │ │ + // │ │ │ │ + // │ │ │ │ + // ▼ ▼ ▼ ▼ + // ┌─────────────┐ ┌────────────┐ ┌────────────┐ ┌───────────┐ + // │ │ │ │ │ │ │ │ + // │ ref1(Frz)* │ │ ref3(ReIM)*│ │ ref4(ReIM)*│ │ ref2(Res) │ + // │ │ │ │ │ │ │ │ + // └─────────────┘ └────────────┘ └────────────┘ └───────────┘ + + // Performs a wildcard access on the main root. However, as there are + // no exposed tags with write permissions and a tag smaller than ref2 + // this access fails. + *ref2 = 13; //~ ERROR: /write access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed2.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed2.stderr new file mode 100644 index 000000000000..1f7a3d61829c --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed2.stderr @@ -0,0 +1,14 @@ +error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/cross_tree_update_main_invalid_exposed2.rs:LL:CC + | +LL | *ref2 = 13; + | ^^^^^^^^^^ 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: there are no exposed tags which may perform this access here + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From 3f8b25771d1074abb391c55dc2c33df3a8278043 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova <58857108+ada4a@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:50:41 +0100 Subject: [PATCH 1154/3801] Fix typo --- compiler/rustc_ast/src/ast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 1ea9e0ae7718..7c922417ee29 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1810,7 +1810,7 @@ pub enum ExprKind { /// or a `gen` block (`gen move { ... }`). /// /// The span is the "decl", which is the header before the body `{ }` - /// including the `asyng`/`gen` keywords and possibly `move`. + /// including the `async`/`gen` keywords and possibly `move`. Gen(CaptureBy, Box, GenBlockKind, Span), /// An await expression (`my_future.await`). Span is of await keyword. Await(Box, Span), From 9ae46aa9a3fd63877b04d2d240fc6ff5fe20a38b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 22 Dec 2025 17:23:53 +0100 Subject: [PATCH 1155/3801] readme: update android state --- src/tools/miri/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 86f190134d45..2832ef50adef 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -219,7 +219,7 @@ degree documented below): - We have unofficial support (not maintained by the Miri team itself) for some further operating systems. - `solaris` / `illumos`: maintained by @devnexen. Supports the entire test suite. - `freebsd`: maintained by @YohDeadfall and @LorrensP-2158466. Supports the entire test suite. - - `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works. + - `android`: **maintainer wanted**. Basic OS APIs and concurrency work, but file system access is not supported. - For targets on other operating systems, Miri might fail before even reaching the `main` function. However, even for targets that we do support, the degree of support for accessing platform APIs From 1b8ee46683206a1fe52dd8a7dcdeb8adfc9dc309 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 22 Dec 2025 17:41:53 +0100 Subject: [PATCH 1156/3801] Add `needs-std-remap-debuginfo` directive to `compiletest` & run-make --- src/bootstrap/src/core/build_steps/test.rs | 4 ++++ .../rustc-dev-guide/src/tests/directives.md | 4 ++++ src/tools/compiletest/src/common.rs | 5 +++++ src/tools/compiletest/src/directives/cfg.rs | 5 +++++ .../src/directives/directive_names.rs | 1 + src/tools/compiletest/src/directives/needs.rs | 5 +++++ src/tools/compiletest/src/directives/tests.rs | 22 +++++++++++++++++++ src/tools/compiletest/src/lib.rs | 3 +++ src/tools/compiletest/src/runtest/run_make.rs | 6 +++++ src/tools/compiletest/src/rustdoc_gui_test.rs | 1 + src/tools/run-make-support/src/env.rs | 8 +++++++ 11 files changed, 64 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 7ca6ae46a8f8..a58739c9e65c 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2257,6 +2257,10 @@ Please disable assertions with `rust.debug-assertions = false`. cmd.arg("--with-std-debug-assertions"); } + if builder.config.rust_remap_debuginfo { + cmd.arg("--with-std-remap-debuginfo"); + } + let mut llvm_components_passed = false; let mut copts_passed = false; if builder.config.llvm_enabled(test_compiler.host) { diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 7cf5869b719c..c8b0072dc101 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -189,6 +189,10 @@ settings: assertions. - `needs-std-debug-assertions` — ignores if std was not built with debug assertions. +- `ignore-std-remap-debuginfo` — ignores if std was built with remapping of + it's sources. +- `needs-std-remap-debugino` — ignores if std was not built with remapping of + it's sources. - `ignore-rustc-debug-assertions` — ignores if rustc was built with debug assertions. - `needs-rustc-debug-assertions` — ignores if rustc was not built with debug diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index cd0e79f5ab3f..9473e51688cb 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -438,6 +438,11 @@ pub struct Config { /// FIXME: make it clearer that this refers to the staged `std`, not stage 0 `std`. pub with_std_debug_assertions: bool, + /// Whether *staged* `std` was built with remapping of debuginfo. + /// + /// FIXME: make it clearer that this refers to the staged `std`, not stage 0 `std`. + pub with_std_remap_debuginfo: bool, + /// Only run tests that match these filters (using `libtest` "test name contains" filter logic). /// /// FIXME(#139660): the current hand-rolled test executor intentionally mimics the `libtest` diff --git a/src/tools/compiletest/src/directives/cfg.rs b/src/tools/compiletest/src/directives/cfg.rs index 62d10f14b98f..e89c1330f467 100644 --- a/src/tools/compiletest/src/directives/cfg.rs +++ b/src/tools/compiletest/src/directives/cfg.rs @@ -202,6 +202,11 @@ pub(crate) fn prepare_conditions(config: &Config) -> PreparedConditions { config.with_std_debug_assertions, "when std is built with debug assertions", ); + builder.cond( + "std-remap-debuginfo", + config.with_std_remap_debuginfo, + "when std is built with remapping of debuginfo", + ); for &debugger in Debugger::STR_VARIANTS { builder.cond( diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index e9824edfef60..282e2a131d93 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -184,6 +184,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-sanitizer-support", "needs-sanitizer-thread", "needs-std-debug-assertions", + "needs-std-remap-debuginfo", "needs-subprocess", "needs-symlink", "needs-target-has-atomic", diff --git a/src/tools/compiletest/src/directives/needs.rs b/src/tools/compiletest/src/directives/needs.rs index 92b596c70ae9..36c2ca62cd87 100644 --- a/src/tools/compiletest/src/directives/needs.rs +++ b/src/tools/compiletest/src/directives/needs.rs @@ -181,6 +181,11 @@ pub(super) fn handle_needs( condition: config.with_std_debug_assertions, ignore_reason: "ignored if std wasn't built with debug assertions", }, + Need { + name: "needs-std-remap-debuginfo", + condition: config.with_std_remap_debuginfo, + ignore_reason: "ignored if std wasn't built with remapping of debuginfo", + }, Need { name: "needs-target-std", condition: build_helper::targets::target_supports_std(&config.target), diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 90e2cb77e304..93f1041a8f41 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -117,6 +117,7 @@ struct ConfigBuilder { profiler_runtime: bool, rustc_debug_assertions: bool, std_debug_assertions: bool, + std_remap_debuginfo: bool, } impl ConfigBuilder { @@ -185,6 +186,11 @@ impl ConfigBuilder { self } + fn std_remap_debuginfo(&mut self, is_enabled: bool) -> &mut Self { + self.std_remap_debuginfo = is_enabled; + self + } + fn build(&mut self) -> Config { let args = &[ "compiletest", @@ -246,6 +252,9 @@ impl ConfigBuilder { if self.std_debug_assertions { args.push("--with-std-debug-assertions".to_owned()); } + if self.std_remap_debuginfo { + args.push("--with-std-remap-debuginfo".to_owned()); + } args.push("--rustc-path".to_string()); args.push(std::env::var("TEST_RUSTC").expect("must be configured by bootstrap")); @@ -400,6 +409,19 @@ fn std_debug_assertions() { assert!(check_ignore(&config, "//@ ignore-std-debug-assertions")); } +#[test] +fn std_remap_debuginfo() { + let config: Config = cfg().std_remap_debuginfo(false).build(); + + assert!(check_ignore(&config, "//@ needs-std-remap-debuginfo")); + assert!(!check_ignore(&config, "//@ ignore-std-remap-debuginfo")); + + let config: Config = cfg().std_remap_debuginfo(true).build(); + + assert!(!check_ignore(&config, "//@ needs-std-remap-debuginfo")); + assert!(check_ignore(&config, "//@ ignore-std-remap-debuginfo")); +} + #[test] fn stage() { let config: Config = cfg().stage(1).stage_id("stage1-x86_64-unknown-linux-gnu").build(); diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 90b1c10308a2..83aee865e010 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -106,6 +106,7 @@ fn parse_config(args: Vec) -> Config { .optflag("", "has-enzyme", "run tests that require enzyme") .optflag("", "with-rustc-debug-assertions", "whether rustc was built with debug assertions") .optflag("", "with-std-debug-assertions", "whether std was built with debug assertions") + .optflag("", "with-std-remap-debuginfo", "whether std was built with remapping") .optmulti( "", "skip", @@ -295,6 +296,7 @@ fn parse_config(args: Vec) -> Config { let run_ignored = matches.opt_present("ignored"); let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions"); let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions"); + let with_std_remap_debuginfo = matches.opt_present("with-std-remap-debuginfo"); let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode"); let has_enzyme = matches.opt_present("has-enzyme"); let filters = if mode == TestMode::RunMake { @@ -402,6 +404,7 @@ fn parse_config(args: Vec) -> Config { run_ignored, with_rustc_debug_assertions, with_std_debug_assertions, + with_std_remap_debuginfo, filters, skip: matches.opt_strs("skip"), filter_exact: matches.opt_present("exact"), diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 68574eb4bfd6..ba3a12347367 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -243,6 +243,12 @@ impl TestCx<'_> { cmd.env("__STD_DEBUG_ASSERTIONS_ENABLED", "1"); } + cmd.env_remove("__STD_REMAP_DEBUGINFO_ENABLED"); + if self.config.with_std_remap_debuginfo { + // Used for `run_make_support::env::std_remap_debuginfo_enabled`. + cmd.env("__STD_REMAP_DEBUGINFO_ENABLED", "1"); + } + // We don't want RUSTFLAGS set from the outside to interfere with // compiler flags set in the test cases: cmd.env_remove("RUSTFLAGS"); diff --git a/src/tools/compiletest/src/rustdoc_gui_test.rs b/src/tools/compiletest/src/rustdoc_gui_test.rs index c30f3d1e10ea..2b057bb35519 100644 --- a/src/tools/compiletest/src/rustdoc_gui_test.rs +++ b/src/tools/compiletest/src/rustdoc_gui_test.rs @@ -83,6 +83,7 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { run_ignored: Default::default(), with_rustc_debug_assertions: Default::default(), with_std_debug_assertions: Default::default(), + with_std_remap_debuginfo: Default::default(), filters: Default::default(), skip: Default::default(), filter_exact: Default::default(), diff --git a/src/tools/run-make-support/src/env.rs b/src/tools/run-make-support/src/env.rs index cf1a6f7351a7..507d51471df0 100644 --- a/src/tools/run-make-support/src/env.rs +++ b/src/tools/run-make-support/src/env.rs @@ -34,6 +34,14 @@ pub fn std_debug_assertions_enabled() -> bool { std::env::var_os("__STD_DEBUG_ASSERTIONS_ENABLED").is_some() } +/// Check if staged `std`-under-test was built with remapping of it's sources. +#[track_caller] +#[must_use] +pub fn std_remap_debuginfo_enabled() -> bool { + // Note: we assume this env var is set when the test recipe is being executed. + std::env::var_os("__STD_REMAP_DEBUGINFO_ENABLED").is_some() +} + /// A wrapper around [`std::env::set_current_dir`] which includes the directory /// path in the panic message. #[track_caller] From 4d839da22bd6c543eed854ba048df97ebd2b2150 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 22 Dec 2025 17:41:13 +0100 Subject: [PATCH 1157/3801] Remap both absolute and relative paths when building rustc and std --- src/bootstrap/src/bin/rustc.rs | 7 ++- src/bootstrap/src/core/builder/cargo.rs | 26 +++++++-- tests/run-make/remap-path-prefix-std/rmake.rs | 53 +++++++++++++++++++ 3 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 tests/run-make/remap-path-prefix-std/rmake.rs diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index f15b76fa85c9..bb974e4645ea 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -168,8 +168,11 @@ fn main() { } } - if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") { - cmd.arg("--remap-path-prefix").arg(&map); + // The remap flags for the compiler and standard library sources. + if let Ok(maps) = env::var("RUSTC_DEBUGINFO_MAP") { + for map in maps.split('\t') { + cmd.arg("--remap-path-prefix").arg(map); + } } // The remap flags for Cargo registry sources need to be passed after the remapping for the // Rust source code directory, to handle cases when $CARGO_HOME is inside the source directory. diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 4697de7ffe0d..b0a8ce77efe7 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -1025,15 +1025,26 @@ impl Builder<'_> { if let Some(ref map_to) = self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler) { + // Tell the compiler which prefix was used for remapping the standard library cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to); } if let Some(ref map_to) = self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::Compiler) { - // When building compiler sources, we want to apply the compiler remap scheme. - cargo.env("RUSTC_DEBUGINFO_MAP", format!("compiler/={map_to}/compiler")); + // Tell the compiler which prefix was used for remapping the compiler it-self cargo.env("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR", map_to); + + // When building compiler sources, we want to apply the compiler remap scheme. + let map = [ + // Cargo use relative paths for workspace members, so let's remap those. + format!("compiler/={map_to}/compiler"), + // rustc creates absolute paths (in part bc of the `rust-src` unremap + // and for working directory) so let's remap the build directory as well. + format!("{}={map_to}", self.build.src.display()), + ] + .join("\t"); + cargo.env("RUSTC_DEBUGINFO_MAP", map); } } Mode::Std @@ -1044,7 +1055,16 @@ impl Builder<'_> { if let Some(ref map_to) = self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler) { - cargo.env("RUSTC_DEBUGINFO_MAP", format!("library/={map_to}/library")); + // When building the standard library sources, we want to apply the std remap scheme. + let map = [ + // Cargo use relative paths for workspace members, so let's remap those. + format!("library/={map_to}/library"), + // rustc creates absolute paths (in part bc of the `rust-src` unremap + // and for working directory) so let's remap the build directory as well. + format!("{}={map_to}", self.build.src.display()), + ] + .join("\t"); + cargo.env("RUSTC_DEBUGINFO_MAP", map); } } } diff --git a/tests/run-make/remap-path-prefix-std/rmake.rs b/tests/run-make/remap-path-prefix-std/rmake.rs new file mode 100644 index 000000000000..f5179038a9b1 --- /dev/null +++ b/tests/run-make/remap-path-prefix-std/rmake.rs @@ -0,0 +1,53 @@ +// This test makes sure that we do not leak paths to the checkout +// (ie. /checkout in CI) in the distributed `libstd` debuginfo. +// +// This test only runs on Linux and dist builder (or with `rust.remap-debuginfo = true` +// set in your `bootstrap.toml`). + +//@ needs-std-remap-debuginfo +//@ only-linux + +use std::path::PathBuf; + +use run_make_support::{llvm_dwarfdump, rfs, rustc, shallow_find_files, source_root}; + +fn main() { + // Find the target libdir for the current target + let target_libdir = { + let output = rustc().print("target-libdir").run(); + let stdout = output.stdout_utf8(); + let path = PathBuf::from(stdout.trim()); + + // Assert that the target-libdir path exists + assert!(path.exists(), "target-libdir: {path:?} does not exists"); + + path + }; + + // Find all the `libstd-.*.rlib` files under the libdir + let libstd_rlibs = shallow_find_files(&target_libdir, |p| { + if let Some(filename) = p.file_name() + && let filename = filename.to_string_lossy() + { + filename.starts_with("libstd-") && filename.ends_with(".rlib") + } else { + false + } + }); + + // Assert that there is only one rlib for the `libstd` + let [libstd_rlib] = &libstd_rlibs[..] else { + unreachable!("multiple libstd rlib: {libstd_rlibs:?} in {target_libdir:?}"); + }; + + // Symlink the libstd rlib here to avoid absolute paths from llvm-dwarfdump own output + // and not from the debuginfo it-self + rfs::symlink_file(libstd_rlib, "libstd.rlib"); + + // Check that there is only `/rustc/` paths and no `/checkout`, `/home`, or whatever + llvm_dwarfdump() + .input("libstd.rlib") + .run() + .assert_stdout_contains("/rustc/") + .assert_stdout_not_contains(source_root().to_string_lossy()); +} From e8a63124746761e743d69ea510194de2ada4034f Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Mon, 22 Dec 2025 11:18:35 -0800 Subject: [PATCH 1158/3801] add new configure_cmake option to let projects set cc/cxx flags --- src/bootstrap/src/core/build_steps/llvm.rs | 60 ++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 51a791daef28..8bf8f6f56c73 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -63,6 +63,25 @@ impl LlvmBuildStatus { } } +/// Allows each step to add C/Cxx flags which are only used for a specific cmake invocation. +#[derive(Debug, Clone, Default)] +struct CcFlags { + /// Additional values for CMAKE_CC_FLAGS, to be added before all other values. + cflags: OsString, + /// Additional values for CMAKE_CXX_FLAGS, to be added before all other values. + cxxflags: OsString, +} + +impl CcFlags { + fn push_all(&mut self, s: impl AsRef) { + let s = s.as_ref(); + self.cflags.push(" "); + self.cflags.push(s); + self.cxxflags.push(" "); + self.cxxflags.push(s); + } +} + /// Linker flags to pass to LLVM's CMake invocation. #[derive(Debug, Clone, Default)] struct LdFlags { @@ -527,7 +546,7 @@ impl Step for Llvm { cfg.define("LLVM_VERSION_SUFFIX", suffix); } - configure_cmake(builder, target, &mut cfg, true, ldflags, &[]); + configure_cmake(builder, target, &mut cfg, true, ldflags, CcFlags::default(), &[]); configure_llvm(builder, target, &mut cfg); for (key, val) in &builder.config.llvm_build_config { @@ -633,6 +652,7 @@ fn configure_cmake( cfg: &mut cmake::Config, use_compiler_launcher: bool, mut ldflags: LdFlags, + ccflags: CcFlags, suppressed_compiler_flag_prefixes: &[&str], ) { // Do not print installation messages for up-to-date files. @@ -761,23 +781,21 @@ fn configure_cmake( .define("CMAKE_ASM_COMPILER", sanitize_cc(&cc)); cfg.build_arg("-j").build_arg(builder.jobs().to_string()); + let mut cflags = ccflags.cflags.clone(); // FIXME(madsmtm): Allow `cmake-rs` to select flags by itself by passing // our flags via `.cflag`/`.cxxflag` instead. // // Needs `suppressed_compiler_flag_prefixes` to be gone, and hence // https://github.com/llvm/llvm-project/issues/88780 to be fixed. - let mut cflags: OsString = builder + for flag in builder .cc_handled_clags(target, CLang::C) .into_iter() .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::C)) - .filter(|flag| { - !suppressed_compiler_flag_prefixes - .iter() - .any(|suppressed_prefix| flag.starts_with(suppressed_prefix)) - }) - .collect::>() - .join(" ") - .into(); + .filter(|flag| !suppressed_compiler_flag_prefixes.iter().any(|p| flag.starts_with(p))) + { + cflags.push(" "); + cflags.push(flag); + } if let Some(ref s) = builder.config.llvm_cflags { cflags.push(" "); cflags.push(s); @@ -789,7 +807,8 @@ fn configure_cmake( cflags.push(format!(" --target={target}")); } cfg.define("CMAKE_C_FLAGS", cflags); - let mut cxxflags: OsString = builder + let mut cxxflags = ccflags.cxxflags.clone(); + for flag in builder .cc_handled_clags(target, CLang::Cxx) .into_iter() .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::Cxx)) @@ -798,9 +817,10 @@ fn configure_cmake( .iter() .any(|suppressed_prefix| flag.starts_with(suppressed_prefix)) }) - .collect::>() - .join(" ") - .into(); + { + cxxflags.push(" "); + cxxflags.push(flag); + } if let Some(ref s) = builder.config.llvm_cxxflags { cxxflags.push(" "); cxxflags.push(s); @@ -811,6 +831,7 @@ fn configure_cmake( if builder.config.llvm_clang_cl.is_some() { cxxflags.push(format!(" --target={target}")); } + cfg.define("CMAKE_CXX_FLAGS", cxxflags); if let Some(ar) = builder.ar(target) && ar.is_absolute() @@ -970,7 +991,13 @@ impl Step for Enzyme { builder.config.update_submodule("src/tools/enzyme"); let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/")); - configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]); + + let mut cflags = CcFlags::default(); + // Enzyme devs maintain upstream compability, but only fix deprecations when they are about + // to turn into a hard error. As such, Enzyme generates various warnings which could make it + // hard to spot more relevant issues. + cflags.push_all("-Wno-deprecated"); + configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), cflags, &[]); // Re-use the same flags as llvm to control the level of debug information // generated by Enzyme. @@ -1090,7 +1117,7 @@ impl Step for Lld { ldflags.push_all("-Wl,-rpath,'$ORIGIN/../../../'"); } - configure_cmake(builder, target, &mut cfg, true, ldflags, &[]); + configure_cmake(builder, target, &mut cfg, true, ldflags, CcFlags::default(), &[]); configure_llvm(builder, target, &mut cfg); // Re-use the same flags as llvm to control the level of debug information @@ -1213,6 +1240,7 @@ impl Step for Sanitizers { &mut cfg, use_compiler_launcher, LdFlags::default(), + CcFlags::default(), suppressed_compiler_flag_prefixes, ); From a182874cc17634d36ba922a543733193bd31bdba Mon Sep 17 00:00:00 2001 From: rami3l Date: Mon, 22 Dec 2025 21:23:20 +0100 Subject: [PATCH 1159/3801] fix(bootstrap/dist)!: change dist path for `rustc-docs` to avoid clashing --- src/bootstrap/src/core/build_steps/dist.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index cbbdc7e02419..c5ad87604e74 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -181,7 +181,7 @@ impl Step for RustcDocs { let mut tarball = Tarball::new(builder, "rustc-docs", &target.triple); tarball.set_product_name("Rustc Documentation"); - tarball.add_bulk_dir(builder.compiler_doc_out(target), "share/doc/rust/html/rustc"); + tarball.add_bulk_dir(builder.compiler_doc_out(target), "share/doc/rust/html/rustc-docs"); tarball.generate() } } From ec5e96e58b55e1161f69e6515bb3f070f41c57ec Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 23 Dec 2025 07:46:12 +1100 Subject: [PATCH 1160/3801] Remove `Option` from `fold_infer_ty` return type. It's no longer needed. --- compiler/rustc_infer/src/infer/freshen.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 1a2e5e93c864..c058bebddcf0 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -120,7 +120,7 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { t } else { match *t.kind() { - ty::Infer(v) => self.fold_infer_ty(v).unwrap_or(t), + ty::Infer(v) => self.fold_infer_ty(v), // This code is hot enough that a non-debug assertion here makes a noticeable // difference on benchmarks like `wg-grammar`. @@ -168,18 +168,18 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { // This is separate from `fold_ty` to keep that method small and inlinable. #[inline(never)] - fn fold_infer_ty(&mut self, ty: ty::InferTy) -> Option> { + fn fold_infer_ty(&mut self, ty: ty::InferTy) -> Ty<'tcx> { match ty { ty::TyVar(v) => { let mut inner = self.infcx.inner.borrow_mut(); match inner.type_variables().probe(v).known() { Some(ty) => { drop(inner); - Some(ty.fold_with(self)) + ty.fold_with(self) } None => { let input = ty::TyVar(inner.type_variables().root_var(v)); - Some(self.freshen_ty(input, |n| Ty::new_fresh(self.infcx.tcx, n))) + self.freshen_ty(input, |n| Ty::new_fresh(self.infcx.tcx, n)) } } } @@ -188,11 +188,11 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { let mut inner = self.infcx.inner.borrow_mut(); let value = inner.int_unification_table().probe_value(v); match value { - ty::IntVarValue::IntType(ty) => Some(Ty::new_int(self.infcx.tcx, ty)), - ty::IntVarValue::UintType(ty) => Some(Ty::new_uint(self.infcx.tcx, ty)), + ty::IntVarValue::IntType(ty) => Ty::new_int(self.infcx.tcx, ty), + ty::IntVarValue::UintType(ty) => Ty::new_uint(self.infcx.tcx, ty), ty::IntVarValue::Unknown => { let input = ty::IntVar(inner.int_unification_table().find(v)); - Some(self.freshen_ty(input, |n| Ty::new_fresh_int(self.infcx.tcx, n))) + self.freshen_ty(input, |n| Ty::new_fresh_int(self.infcx.tcx, n)) } } } @@ -201,10 +201,10 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { let mut inner = self.infcx.inner.borrow_mut(); let value = inner.float_unification_table().probe_value(v); match value { - ty::FloatVarValue::Known(ty) => Some(Ty::new_float(self.infcx.tcx, ty)), + ty::FloatVarValue::Known(ty) => Ty::new_float(self.infcx.tcx, ty), ty::FloatVarValue::Unknown => { let input = ty::FloatVar(inner.float_unification_table().find(v)); - Some(self.freshen_ty(input, |n| Ty::new_fresh_float(self.infcx.tcx, n))) + self.freshen_ty(input, |n| Ty::new_fresh_float(self.infcx.tcx, n)) } } } From dfbb0fd7dc3e4f02e4102cf0b7f87958a8ca4d0e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 22 Dec 2025 13:13:50 -0800 Subject: [PATCH 1161/3801] std: Use `usleep` temporarily on WASI targets This fixes some fallout from 147572 where the `thread::sleep` function is is broken on `wasm32-wasip2` after that PR. The cause for this is a broken implementation of `nanosleep` in wasi-libc itself which is being fixed in WebAssembly/wasi-libc/696. Similar to 149999 this avoids the problematic function for now while the wasi-libc changes take some time to propagate into a wasi-sdk release. --- library/std/src/sys/thread/unix.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 18cdea0e1b1b..d0396ed71300 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -520,7 +520,7 @@ pub fn set_name(name: &CStr) { debug_assert_eq!(res, libc::OK); } -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] pub fn sleep(dur: Duration) { let mut secs = dur.as_secs(); let mut nsecs = dur.subsec_nanos() as _; @@ -546,7 +546,13 @@ pub fn sleep(dur: Duration) { } } -#[cfg(target_os = "espidf")] +#[cfg(any( + target_os = "espidf", + // wasi-libc prior to WebAssembly/wasi-libc#696 has a broken implementation + // of `nanosleep`, used above by most platforms, so use `usleep` until + // that fix propagates throughout the ecosystem. + target_os = "wasi", +))] pub fn sleep(dur: Duration) { // ESP-IDF does not have `nanosleep`, so we use `usleep` instead. // As per the documentation of `usleep`, it is expected to support From f3b16d833f816d37213e6a1a839d34ceeb97d430 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Mon, 22 Dec 2025 11:20:15 -0800 Subject: [PATCH 1162/3801] Change how we build offload as a single Step --- bootstrap.example.toml | 3 + src/bootstrap/configure.py | 5 + src/bootstrap/src/core/build_steps/compile.rs | 22 ++- src/bootstrap/src/core/build_steps/llvm.rs | 185 ++++++++++++++++-- src/bootstrap/src/core/config/config.rs | 3 + src/bootstrap/src/core/config/toml/llvm.rs | 2 + src/bootstrap/src/lib.rs | 4 + src/bootstrap/src/utils/change_tracker.rs | 5 + 8 files changed, 215 insertions(+), 14 deletions(-) diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 63bf50722ca0..e0cbb0c0e747 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -106,6 +106,9 @@ # Whether to build LLVM with support for it's gpu offload runtime. #llvm.offload = false +# Absolute path to the directory containing ClangConfig.cmake +#llvm.offload-clang-dir = "" + # When true, link libstdc++ statically into the rustc_llvm. # This is useful if you don't want to use the dynamic version of that # library provided by LLVM. diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index e3895d4e0a18..fda8f004eff4 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -120,6 +120,11 @@ o("optimize-llvm", "llvm.optimize", "build optimized LLVM") o("llvm-assertions", "llvm.assertions", "build LLVM with assertions") o("llvm-enzyme", "llvm.enzyme", "build LLVM with enzyme") o("llvm-offload", "llvm.offload", "build LLVM with gpu offload support") +o( + "llvm-offload-clang-dir", + "llvm.offload-clang-dir", + "pass the absolute directory of ClangConfig.cmake", +) o("llvm-plugins", "llvm.plugins", "build LLVM with plugin interface") o("debug-assertions", "rust.debug-assertions", "build with debugging assertions") o( diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index ed154133dec2..d6aae06d089d 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1427,10 +1427,12 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect if builder.config.llvm_enzyme { cargo.env("LLVM_ENZYME", "1"); } + let llvm::LlvmResult { host_llvm_config, .. } = builder.ensure(llvm::Llvm { target }); if builder.config.llvm_offload { + builder.ensure(llvm::OmpOffload { target }); cargo.env("LLVM_OFFLOAD", "1"); } - let llvm::LlvmResult { host_llvm_config, .. } = builder.ensure(llvm::Llvm { target }); + cargo.env("LLVM_CONFIG", &host_llvm_config); // Some LLVM linker flags (-L and -l) may be needed to link `rustc_llvm`. Its build script @@ -2293,6 +2295,24 @@ impl Step for Assemble { } } + if builder.config.llvm_offload && !builder.config.dry_run() { + debug!("`llvm_offload` requested"); + let offload_install = builder.ensure(llvm::OmpOffload { target: build_compiler.host }); + if let Some(_llvm_config) = builder.llvm_config(builder.config.host_target) { + let target_libdir = + builder.sysroot_target_libdir(target_compiler, target_compiler.host); + for p in offload_install.offload_paths() { + let libname = p.file_name().unwrap(); + let dst_lib = target_libdir.join(libname); + builder.resolve_symlink_and_copy(&p, &dst_lib); + } + // FIXME(offload): Add amdgcn-amd-amdhsa and nvptx64-nvidia-cuda folder + // This one is slightly more tricky, since we have the same file twice, in two + // subfolders for amdgcn and nvptx64. We'll likely find two more in the future, once + // Intel and Spir-V support lands in offload. + } + } + // Build the libraries for this compiler to link to (i.e., the libraries // it uses at runtime). debug!( diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 8bf8f6f56c73..c3935d9810e9 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -14,6 +14,7 @@ use std::path::{Path, PathBuf}; use std::sync::OnceLock; use std::{env, fs}; +use build_helper::exit; use build_helper::git::PathFreshness; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step, StepMetadata}; @@ -473,16 +474,6 @@ impl Step for Llvm { enabled_llvm_runtimes.push("compiler-rt"); } - // This is an experimental flag, which likely builds more than necessary. - // We will optimize it when we get closer to releasing it on nightly. - if builder.config.llvm_offload { - enabled_llvm_runtimes.push("offload"); - //FIXME(ZuseZ4): LLVM intends to drop the offload dependency on openmp. - //Remove this line once they achieved it. - enabled_llvm_runtimes.push("openmp"); - enabled_llvm_projects.push("compiler-rt"); - } - if !enabled_llvm_projects.is_empty() { enabled_llvm_projects.sort(); enabled_llvm_projects.dedup(); @@ -917,6 +908,175 @@ fn get_var(var_base: &str, host: &str, target: &str) -> Option { .or_else(|| env::var_os(var_base)) } +#[derive(Clone)] +pub struct BuiltOmpOffload { + /// Path to the omp and offload dylibs. + offload: Vec, +} + +impl BuiltOmpOffload { + pub fn offload_paths(&self) -> Vec { + self.offload.clone() + } +} + +// FIXME(offload): In an ideal world, we would just enable the offload runtime in our previous LLVM +// build step. For now, we still depend on the openmp runtime since we use some of it's API, so we +// build both. However, when building those runtimes as part of the LLVM step, then LLVM's cmake +// implicitly assumes that Clang has also been build and will try to use it. In the Rust CI, we +// don't always build clang (due to compile times), but instead use a slightly older external clang. +// LLVM tries to remove this build dependency of offload/openmp on Clang for LLVM-22, so in the +// future we might be able to integrate this step into the LLVM step. For now, we instead introduce +// a Clang_DIR bootstrap option, which allows us tell CMake to use an external clang for these two +// runtimes. This external clang will try to use it's own (older) include dirs when building our +// in-tree LLVM submodule, which will cause build failures. To prevent those, we now also +// explicitly set our include dirs. +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct OmpOffload { + pub target: TargetSelection, +} + +impl Step for OmpOffload { + type Output = BuiltOmpOffload; + const IS_HOST: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/llvm-project/offload") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(OmpOffload { target: run.target }); + } + + /// Compile OpenMP offload runtimes for `target`. + #[allow(unused)] + fn run(self, builder: &Builder<'_>) -> Self::Output { + if builder.config.dry_run() { + return BuiltOmpOffload { + offload: vec![builder.config.tempdir().join("llvm-offload-dry-run")], + }; + } + let target = self.target; + + let LlvmResult { host_llvm_config, llvm_cmake_dir } = + builder.ensure(Llvm { target: self.target }); + + // Running cmake twice in the same folder is known to cause issues, like deleting existing + // binaries. We therefore write our offload artifacts into it's own folder, instead of + // using the llvm build dir. + let out_dir = builder.offload_out(target); + + let mut files = vec![]; + let lib_ext = std::env::consts::DLL_EXTENSION; + files.push(out_dir.join("lib").join("libLLVMOffload").with_extension(lib_ext)); + files.push(out_dir.join("lib").join("libomp").with_extension(lib_ext)); + files.push(out_dir.join("lib").join("libomptarget").with_extension(lib_ext)); + + // Offload/OpenMP are just subfolders of LLVM, so we can use the LLVM sha. + static STAMP_HASH_MEMO: OnceLock = OnceLock::new(); + let smart_stamp_hash = STAMP_HASH_MEMO.get_or_init(|| { + generate_smart_stamp_hash( + builder, + &builder.config.src.join("src/llvm-project/offload"), + builder.in_tree_llvm_info.sha().unwrap_or_default(), + ) + }); + let stamp = BuildStamp::new(&out_dir).with_prefix("offload").add_stamp(smart_stamp_hash); + + trace!("checking build stamp to see if we need to rebuild offload/openmp artifacts"); + if stamp.is_up_to_date() { + trace!(?out_dir, "offload/openmp build artifacts are up to date"); + if stamp.stamp().is_empty() { + builder.info( + "Could not determine the Offload submodule commit hash. \ + Assuming that an Offload rebuild is not necessary.", + ); + builder.info(&format!( + "To force Offload/OpenMP to rebuild, remove the file `{}`", + stamp.path().display() + )); + } + return BuiltOmpOffload { offload: files }; + } + + trace!(?target, "(re)building offload/openmp artifacts"); + builder.info(&format!("Building OpenMP/Offload for {target}")); + t!(stamp.remove()); + let _time = helpers::timeit(builder); + t!(fs::create_dir_all(&out_dir)); + + builder.config.update_submodule("src/llvm-project"); + let mut cfg = cmake::Config::new(builder.src.join("src/llvm-project/runtimes/")); + + // If we use an external clang as opposed to building our own llvm_clang, than that clang will + // come with it's own set of default include directories, which are based on a potentially older + // LLVM. This can cause issues, so we overwrite it to include headers based on our + // `src/llvm-project` submodule instead. + // FIXME(offload): With LLVM-22 we hopefully won't need an external clang anymore. + let mut cflags = CcFlags::default(); + if !builder.config.llvm_clang { + let base = builder.llvm_out(target).join("include"); + let inc_dir = base.display(); + cflags.push_all(format!(" -I {inc_dir}")); + } + + configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), cflags, &[]); + + // Re-use the same flags as llvm to control the level of debug information + // generated for offload. + let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) { + (false, _) => "Debug", + (true, false) => "Release", + (true, true) => "RelWithDebInfo", + }; + trace!(?profile); + + // OpenMP/Offload builds currently (LLVM-21) still depend on Clang, although there are + // intentions to loosen this requirement for LLVM-22. If we were to + let clang_dir = if !builder.config.llvm_clang { + // We must have an external clang to use. + assert!(&builder.build.config.llvm_clang_dir.is_some()); + builder.build.config.llvm_clang_dir.clone() + } else { + // No need to specify it, since we use the in-tree clang + None + }; + + // FIXME(offload): Once we move from OMP to Offload (Ol) APIs, we should drop the openmp + // runtime to simplify our build. We should also re-evaluate the LLVM_Root and try to get + // rid of the Clang_DIR, once we upgrade to LLVM-22. + cfg.out_dir(&out_dir) + .profile(profile) + .env("LLVM_CONFIG_REAL", &host_llvm_config) + .define("LLVM_ENABLE_ASSERTIONS", "ON") + .define("LLVM_ENABLE_RUNTIMES", "openmp;offload") + .define("LLVM_INCLUDE_TESTS", "OFF") + .define("OFFLOAD_INCLUDE_TESTS", "OFF") + .define("OPENMP_STANDALONE_BUILD", "ON") + .define("LLVM_ROOT", builder.llvm_out(target).join("build")) + .define("LLVM_DIR", llvm_cmake_dir); + if let Some(p) = clang_dir { + cfg.define("Clang_DIR", p); + } + cfg.build(); + + t!(stamp.write()); + + for p in &files { + // At this point, `out_dir` should contain the built . + // files. + if !p.exists() { + eprintln!( + "`{p:?}` not found in `{}`. Either the build has failed or Offload was built with a wrong version of LLVM", + out_dir.display() + ); + exit!(1); + } + } + BuiltOmpOffload { offload: files } + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Enzyme { pub target: TargetSelection, @@ -991,11 +1151,10 @@ impl Step for Enzyme { builder.config.update_submodule("src/tools/enzyme"); let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/")); - - let mut cflags = CcFlags::default(); - // Enzyme devs maintain upstream compability, but only fix deprecations when they are about + // Enzyme devs maintain upstream compatibility, but only fix deprecations when they are about // to turn into a hard error. As such, Enzyme generates various warnings which could make it // hard to spot more relevant issues. + let mut cflags = CcFlags::default(); cflags.push_all("-Wno-deprecated"); configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), cflags, &[]); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index a81b8ccb9140..0a329c93bc7d 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -169,6 +169,7 @@ pub struct Config { pub llvm_link_jobs: Option, pub llvm_version_suffix: Option, pub llvm_use_linker: Option, + pub llvm_clang_dir: Option, pub llvm_allow_old_toolchain: bool, pub llvm_polly: bool, pub llvm_clang: bool, @@ -604,6 +605,7 @@ impl Config { use_linker: llvm_use_linker, allow_old_toolchain: llvm_allow_old_toolchain, offload: llvm_offload, + offload_clang_dir: llvm_clang_dir, polly: llvm_polly, clang: llvm_clang, enable_warnings: llvm_enable_warnings, @@ -1361,6 +1363,7 @@ impl Config { llvm_cflags, llvm_clang: llvm_clang.unwrap_or(false), llvm_clang_cl, + llvm_clang_dir: llvm_clang_dir.map(PathBuf::from), llvm_cxxflags, llvm_enable_warnings: llvm_enable_warnings.unwrap_or(false), llvm_enzyme: llvm_enzyme.unwrap_or(false), diff --git a/src/bootstrap/src/core/config/toml/llvm.rs b/src/bootstrap/src/core/config/toml/llvm.rs index 9751837a8879..5f08884e4ef7 100644 --- a/src/bootstrap/src/core/config/toml/llvm.rs +++ b/src/bootstrap/src/core/config/toml/llvm.rs @@ -35,6 +35,7 @@ define_config! { allow_old_toolchain: Option = "allow-old-toolchain", offload: Option = "offload", polly: Option = "polly", + offload_clang_dir: Option = "offload-clang-dir", clang: Option = "clang", enable_warnings: Option = "enable-warnings", download_ci_llvm: Option = "download-ci-llvm", @@ -112,6 +113,7 @@ pub fn check_incompatible_options_for_ci_llvm( use_linker, allow_old_toolchain, offload, + offload_clang_dir: _, polly, clang, enable_warnings, diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index adae9a1b8b08..be459653cd65 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -975,6 +975,10 @@ impl Build { self.out.join(&*target.triple).join("enzyme") } + fn offload_out(&self, target: TargetSelection) -> PathBuf { + self.out.join(&*target.triple).join("offload") + } + fn lld_out(&self, target: TargetSelection) -> PathBuf { self.out.join(target).join("lld") } diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index d7990c2316d1..1077077cb97a 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -606,4 +606,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "New option `gcc.libgccjit-libs-dir` to specify which libgccjit.so to use per target.", }, + ChangeInfo { + change_id: 148671, + severity: ChangeSeverity::Info, + summary: "New option `llvm.offload-clang-dir` to allow building an in-tree llvm offload and openmp runtime with an external clang.", + }, ]; From 6c525fa2d93e92261f5c5a3da0c227af3833b018 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 23 Dec 2025 06:03:06 +0530 Subject: [PATCH 1163/3801] remove internal callbacks, and move callback to rust-analyzer level --- .../rust-analyzer/.github/workflows/ci.yaml | 5 +- src/tools/rust-analyzer/Cargo.lock | 1 - .../crates/load-cargo/src/lib.rs | 22 ++++- .../crates/proc-macro-api/Cargo.toml | 1 - .../src/bidirectional_protocol.rs | 85 +++++-------------- .../proc-macro-api/src/legacy_protocol.rs | 2 - .../crates/proc-macro-api/src/lib.rs | 15 ++-- .../crates/proc-macro-api/src/process.rs | 36 ++++---- .../crates/proc-macro-srv-cli/src/main.rs | 14 ++- 9 files changed, 83 insertions(+), 98 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index 81ca0254982d..e817f770a417 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -71,9 +71,8 @@ jobs: - name: Test run: cargo test --features sysroot-abi -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api -- --quiet - # FIXME: This is temporarily disable, more info: https://rust-lang.zulipchat.com/#narrow/channel/185405-t-compiler.2Frust-analyzer/topic/Non-generic.20spans/with/564604549 - # - name: Check salsa dependency - # run: "! (cargo tree -p proc-macro-srv-cli | grep -q salsa)" + - name: Check salsa dependency + run: "! (cargo tree -p proc-macro-srv-cli | grep -q salsa)" rust: if: github.repository == 'rust-lang/rust-analyzer' diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 060a62b112b7..7d133f99498b 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1836,7 +1836,6 @@ dependencies = [ name = "proc-macro-api" version = "0.0.0" dependencies = [ - "base-db", "indexmap", "intern", "paths", diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index e043e4ac7634..a7b22b0d6a04 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -23,11 +23,17 @@ use ide_db::{ prime_caches, }; use itertools::Itertools; -use proc_macro_api::{MacroDylib, ProcMacroClient}; +use proc_macro_api::{ + MacroDylib, ProcMacroClient, + bidirectional_protocol::{ + msg::{SubRequest, SubResponse}, + reject_subrequests, + }, +}; use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace}; use span::Span; use vfs::{ - AbsPath, AbsPathBuf, VfsPath, + AbsPath, AbsPathBuf, FileId, VfsPath, file_set::FileSetConfig, loader::{Handle, LoadingProgress}, }; @@ -427,7 +433,7 @@ pub fn load_proc_macro( ) -> ProcMacroLoadResult { let res: Result, _> = (|| { let dylib = MacroDylib::new(path.to_path_buf()); - let vec = server.load_dylib(dylib).map_err(|e| { + let vec = server.load_dylib(dylib, Some(&mut reject_subrequests)).map_err(|e| { ProcMacroLoadingError::ProcMacroSrvError(format!("{e}").into_boxed_str()) })?; if vec.is_empty() { @@ -533,8 +539,15 @@ impl ProcMacroExpander for Expander { mixed_site: Span, current_dir: String, ) -> Result, ProcMacroExpansionError> { + let mut cb = |req| match req { + SubRequest::SourceText { file_id, start, end } => { + let file = FileId::from_raw(file_id); + let text = db.file_text(file).text(db); + let slice = text.get(start as usize..end as usize).map(ToOwned::to_owned); + Ok(SubResponse::SourceTextResult { text: slice }) + } + }; match self.0.expand( - db, subtree.view(), attrs.map(|attrs| attrs.view()), env.clone().into(), @@ -542,6 +555,7 @@ impl ProcMacroExpander for Expander { call_site, mixed_site, current_dir, + Some(&mut cb), ) { Ok(Ok(subtree)) => Ok(subtree), Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err)), diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml index 7e56d68964ce..4de1a3e5dd7d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml @@ -19,7 +19,6 @@ serde_json = { workspace = true, features = ["unbounded_depth"] } tracing.workspace = true rustc-hash.workspace = true indexmap.workspace = true -base-db.workspace = true # local deps paths = { workspace = true, features = ["serde1"] } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index 4cb6a1d90f19..bd74738bbdf5 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -5,9 +5,8 @@ use std::{ sync::Arc, }; -use base_db::SourceDatabase; use paths::AbsPath; -use span::{FileId, Span}; +use span::Span; use crate::{ Codec, ProcMacro, ProcMacroKind, ServerError, @@ -29,16 +28,14 @@ use crate::{ pub mod msg; -pub trait ClientCallbacks { - fn handle_sub_request(&mut self, req: SubRequest) -> Result; -} +pub type SubCallback<'a> = &'a mut dyn FnMut(SubRequest) -> Result; pub fn run_conversation( writer: &mut dyn Write, reader: &mut dyn BufRead, buf: &mut C::Buf, msg: BidirectionalMessage, - callbacks: &mut dyn ClientCallbacks, + callback: SubCallback<'_>, ) -> Result { let encoded = C::encode(&msg).map_err(wrap_encode)?; C::write(writer, &encoded).map_err(wrap_io("failed to write initial request"))?; @@ -59,7 +56,7 @@ pub fn run_conversation( return Ok(BidirectionalMessage::Response(response)); } BidirectionalMessage::SubRequest(sr) => { - let resp = callbacks.handle_sub_request(sr)?; + let resp = callback(sr)?; let reply = BidirectionalMessage::SubResponse(resp); let encoded = C::encode(&reply).map_err(wrap_encode)?; C::write(writer, &encoded).map_err(wrap_io("failed to write sub-response"))?; @@ -86,19 +83,13 @@ fn wrap_decode(err: io::Error) -> ServerError { ServerError { message: "failed to decode message".into(), io: Some(Arc::new(err)) } } -pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result { +pub(crate) fn version_check( + srv: &ProcMacroServerProcess, + callback: SubCallback<'_>, +) -> Result { let request = BidirectionalMessage::Request(Request::ApiVersionCheck {}); - struct NoCallbacks; - impl ClientCallbacks for NoCallbacks { - fn handle_sub_request(&mut self, _req: SubRequest) -> Result { - Err(ServerError { message: "sub-request not supported here".into(), io: None }) - } - } - - let mut callbacks = NoCallbacks; - - let response_payload = run_request(srv, request, &mut callbacks)?; + let response_payload = run_request(srv, request, callback)?; match response_payload { BidirectionalMessage::Response(Response::ApiVersionCheck(version)) => Ok(version), @@ -111,21 +102,13 @@ pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result, ) -> Result { let request = BidirectionalMessage::Request(Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer, })); - struct NoCallbacks; - impl ClientCallbacks for NoCallbacks { - fn handle_sub_request(&mut self, _req: SubRequest) -> Result { - Err(ServerError { message: "sub-request not supported here".into(), io: None }) - } - } - - let mut callbacks = NoCallbacks; - - let response_payload = run_request(srv, request, &mut callbacks)?; + let response_payload = run_request(srv, request, callback)?; match response_payload { BidirectionalMessage::Response(Response::SetConfig(ServerConfig { span_mode })) => { @@ -139,21 +122,13 @@ pub(crate) fn enable_rust_analyzer_spans( pub(crate) fn find_proc_macros( srv: &ProcMacroServerProcess, dylib_path: &AbsPath, + callback: SubCallback<'_>, ) -> Result, String>, ServerError> { let request = BidirectionalMessage::Request(Request::ListMacros { dylib_path: dylib_path.to_path_buf().into(), }); - struct NoCallbacks; - impl ClientCallbacks for NoCallbacks { - fn handle_sub_request(&mut self, _req: SubRequest) -> Result { - Err(ServerError { message: "sub-request not supported here".into(), io: None }) - } - } - - let mut callbacks = NoCallbacks; - - let response_payload = run_request(srv, request, &mut callbacks)?; + let response_payload = run_request(srv, request, callback)?; match response_payload { BidirectionalMessage::Response(Response::ListMacros(it)) => Ok(it), @@ -163,7 +138,6 @@ pub(crate) fn find_proc_macros( pub(crate) fn expand( proc_macro: &ProcMacro, - db: &dyn SourceDatabase, subtree: tt::SubtreeView<'_, Span>, attr: Option>, env: Vec<(String, String)>, @@ -171,6 +145,7 @@ pub(crate) fn expand( call_site: Span, mixed_site: Span, current_dir: String, + callback: SubCallback<'_>, ) -> Result>, String>, crate::ServerError> { let version = proc_macro.process.version(); @@ -201,27 +176,7 @@ pub(crate) fn expand( current_dir: Some(current_dir), }))); - struct Callbacks<'de> { - db: &'de dyn SourceDatabase, - } - impl<'db> ClientCallbacks for Callbacks<'db> { - fn handle_sub_request(&mut self, req: SubRequest) -> Result { - match req { - SubRequest::SourceText { file_id, start, end } => { - let file = FileId::from_raw(file_id); - let text = self.db.file_text(file).text(self.db); - - let slice = text.get(start as usize..end as usize).map(|s| s.to_owned()); - - Ok(SubResponse::SourceTextResult { text: slice }) - } - } - } - } - - let mut callbacks = Callbacks { db }; - - let response_payload = run_request(&proc_macro.process, task, &mut callbacks)?; + let response_payload = run_request(&proc_macro.process, task, callback)?; match response_payload { BidirectionalMessage::Response(Response::ExpandMacro(it)) => Ok(it @@ -253,15 +208,19 @@ pub(crate) fn expand( fn run_request( srv: &ProcMacroServerProcess, msg: BidirectionalMessage, - callbacks: &mut dyn ClientCallbacks, + callback: SubCallback<'_>, ) -> Result { if let Some(server_error) = srv.exited() { return Err(server_error.clone()); } if srv.use_postcard() { - srv.run_bidirectional::(msg, callbacks) + srv.run_bidirectional::(msg, callback) } else { - srv.run_bidirectional::(msg, callbacks) + srv.run_bidirectional::(msg, callback) } } + +pub fn reject_subrequests(req: SubRequest) -> Result { + Err(ServerError { message: format!("{req:?} sub-request not supported here"), io: None }) +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs index 81a9f391812c..0d16b60025d2 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs @@ -7,7 +7,6 @@ use std::{ sync::Arc, }; -use base_db::SourceDatabase; use paths::AbsPath; use span::Span; @@ -78,7 +77,6 @@ pub(crate) fn find_proc_macros( pub(crate) fn expand( proc_macro: &ProcMacro, - _db: &dyn SourceDatabase, subtree: tt::SubtreeView<'_, Span>, attr: Option>, env: Vec<(String, String)>, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 7b9b5b39ab1c..0ee0c3afb584 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -21,14 +21,13 @@ pub mod legacy_protocol; mod process; pub mod transport; -use base_db::SourceDatabase; use paths::{AbsPath, AbsPathBuf}; use semver::Version; use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span}; use std::{fmt, io, sync::Arc, time::SystemTime}; -use crate::process::ProcMacroServerProcess; pub use crate::transport::codec::Codec; +use crate::{bidirectional_protocol::SubCallback, process::ProcMacroServerProcess}; /// The versions of the server protocol pub mod version { @@ -143,9 +142,13 @@ impl ProcMacroClient { } /// Loads a proc-macro dylib into the server process returning a list of `ProcMacro`s loaded. - pub fn load_dylib(&self, dylib: MacroDylib) -> Result, ServerError> { + pub fn load_dylib( + &self, + dylib: MacroDylib, + callback: Option>, + ) -> Result, ServerError> { let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); - let macros = self.process.find_proc_macros(&dylib.path)?; + let macros = self.process.find_proc_macros(&dylib.path, callback)?; let dylib_path = Arc::new(dylib.path); let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) @@ -219,7 +222,6 @@ impl ProcMacro { /// This includes span information and environmental context. pub fn expand( &self, - db: &dyn SourceDatabase, subtree: tt::SubtreeView<'_, Span>, attr: Option>, env: Vec<(String, String)>, @@ -227,6 +229,7 @@ impl ProcMacro { call_site: Span, mixed_site: Span, current_dir: String, + callback: Option>, ) -> Result, String>, ServerError> { let (mut subtree, mut attr) = (subtree, attr); let (mut subtree_changed, mut attr_changed); @@ -243,7 +246,6 @@ impl ProcMacro { } self.process.expand( - db, self, subtree, attr, @@ -252,6 +254,7 @@ impl ProcMacro { call_site, mixed_site, current_dir, + callback, ) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index 6d4025001212..01de8e98ff56 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -7,7 +7,6 @@ use std::{ sync::{Arc, Mutex, OnceLock}, }; -use base_db::SourceDatabase; use paths::AbsPath; use semver::Version; use span::Span; @@ -15,7 +14,7 @@ use stdx::JodChild; use crate::{ Codec, ProcMacro, ProcMacroKind, ServerError, - bidirectional_protocol::{self, ClientCallbacks, msg::BidirectionalMessage}, + bidirectional_protocol::{self, SubCallback, msg::BidirectionalMessage, reject_subrequests}, legacy_protocol::{self, SpanMode}, version, }; @@ -67,7 +66,7 @@ impl ProcMacroServerProcess { { &[ ( - Some("postcard-new"), + Some("bidirectional-postcard-prototype"), Protocol::BidirectionalPostcardPrototype { mode: SpanMode::Id }, ), (Some("postcard-legacy"), Protocol::LegacyPostcard { mode: SpanMode::Id }), @@ -92,7 +91,7 @@ impl ProcMacroServerProcess { }; let mut srv = create_srv()?; tracing::info!("sending proc-macro server version check"); - match srv.version_check() { + match srv.version_check(Some(&mut reject_subrequests)) { Ok(v) if v > version::CURRENT_API_VERSION => { #[allow(clippy::disallowed_methods)] let process_version = Command::new(process_path) @@ -110,7 +109,8 @@ impl ProcMacroServerProcess { tracing::info!("Proc-macro server version: {v}"); srv.version = v; if srv.version >= version::RUST_ANALYZER_SPAN_SUPPORT - && let Ok(new_mode) = srv.enable_rust_analyzer_spans() + && let Ok(new_mode) = + srv.enable_rust_analyzer_spans(Some(&mut reject_subrequests)) { match &mut srv.protocol { Protocol::LegacyJson { mode } @@ -156,25 +156,30 @@ impl ProcMacroServerProcess { } /// Checks the API version of the running proc-macro server. - fn version_check(&self) -> Result { + fn version_check(&self, callback: Option>) -> Result { match self.protocol { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::version_check(self) } Protocol::BidirectionalPostcardPrototype { .. } => { - bidirectional_protocol::version_check(self) + let cb = callback.expect("callback required for bidirectional protocol"); + bidirectional_protocol::version_check(self, cb) } } } /// Enable support for rust-analyzer span mode if the server supports it. - fn enable_rust_analyzer_spans(&self) -> Result { + fn enable_rust_analyzer_spans( + &self, + callback: Option>, + ) -> Result { match self.protocol { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::enable_rust_analyzer_spans(self) } Protocol::BidirectionalPostcardPrototype { .. } => { - bidirectional_protocol::enable_rust_analyzer_spans(self) + let cb = callback.expect("callback required for bidirectional protocol"); + bidirectional_protocol::enable_rust_analyzer_spans(self, cb) } } } @@ -183,20 +188,21 @@ impl ProcMacroServerProcess { pub(crate) fn find_proc_macros( &self, dylib_path: &AbsPath, + callback: Option>, ) -> Result, String>, ServerError> { match self.protocol { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::find_proc_macros(self, dylib_path) } Protocol::BidirectionalPostcardPrototype { .. } => { - bidirectional_protocol::find_proc_macros(self, dylib_path) + let cb = callback.expect("callback required for bidirectional protocol"); + bidirectional_protocol::find_proc_macros(self, dylib_path, cb) } } } pub(crate) fn expand( &self, - db: &dyn SourceDatabase, proc_macro: &ProcMacro, subtree: tt::SubtreeView<'_, Span>, attr: Option>, @@ -205,12 +211,12 @@ impl ProcMacroServerProcess { call_site: Span, mixed_site: Span, current_dir: String, + callback: Option>, ) -> Result, String>, ServerError> { match self.protocol { Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { legacy_protocol::expand( proc_macro, - db, subtree, attr, env, @@ -222,7 +228,6 @@ impl ProcMacroServerProcess { } Protocol::BidirectionalPostcardPrototype { .. } => bidirectional_protocol::expand( proc_macro, - db, subtree, attr, env, @@ -230,6 +235,7 @@ impl ProcMacroServerProcess { call_site, mixed_site, current_dir, + callback.expect("callback required for bidirectional protocol"), ), } } @@ -297,10 +303,10 @@ impl ProcMacroServerProcess { pub(crate) fn run_bidirectional( &self, initial: BidirectionalMessage, - callbacks: &mut dyn ClientCallbacks, + callback: SubCallback<'_>, ) -> Result { self.with_locked_io::(|writer, reader, buf| { - bidirectional_protocol::run_conversation::(writer, reader, buf, initial, callbacks) + bidirectional_protocol::run_conversation::(writer, reader, buf, initial, callback) }) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index 7e50888114ba..d73d20b58422 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -57,7 +57,11 @@ enum ProtocolFormat { impl ValueEnum for ProtocolFormat { fn value_variants<'a>() -> &'a [Self] { - &[ProtocolFormat::JsonLegacy, ProtocolFormat::PostcardLegacy, ProtocolFormat::BidirectionalPostcardPrototype] + &[ + ProtocolFormat::JsonLegacy, + ProtocolFormat::PostcardLegacy, + ProtocolFormat::BidirectionalPostcardPrototype, + ] } fn to_possible_value(&self) -> Option { @@ -66,14 +70,18 @@ impl ValueEnum for ProtocolFormat { ProtocolFormat::PostcardLegacy => { Some(clap::builder::PossibleValue::new("postcard-legacy")) } - ProtocolFormat::BidirectionalPostcardPrototype => Some(clap::builder::PossibleValue::new("postcard-new")), + ProtocolFormat::BidirectionalPostcardPrototype => { + Some(clap::builder::PossibleValue::new("postcard-new")) + } } } fn from_str(input: &str, _ignore_case: bool) -> Result { match input { "json-legacy" => Ok(ProtocolFormat::JsonLegacy), "postcard-legacy" => Ok(ProtocolFormat::PostcardLegacy), - "bidirectional-postcard-prototype" => Ok(ProtocolFormat::BidirectionalPostcardPrototype), + "bidirectional-postcard-prototype" => { + Ok(ProtocolFormat::BidirectionalPostcardPrototype) + } _ => Err(format!("unknown protocol format: {input}")), } } From 54062cff4cf06334bc49288afc2391b7dc204e65 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 22 Dec 2025 12:51:59 -0500 Subject: [PATCH 1164/3801] move a ui test to coretests unit test It only tests the usage and formatting of `fmt::Pointer`. --- library/coretests/tests/fmt/mod.rs | 19 +++++++++++++++++++ tests/ui/traits/fmt-pointer-trait.rs | 24 ------------------------ 2 files changed, 19 insertions(+), 24 deletions(-) delete mode 100644 tests/ui/traits/fmt-pointer-trait.rs diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index 0fb099ef4191..67ba49db4d91 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -76,6 +76,25 @@ fn test_fmt_debug_of_mut_reference() { assert_eq!(format!("{:?}", &mut x), "0"); } +#[test] +fn test_fmt_pointer() { + use std::rc::Rc; + use std::sync::Arc; + let p: *const u8 = std::ptr::null(); + let rc = Rc::new(1usize); + let arc = Arc::new(1usize); + let b = Box::new("hi"); + + let _ = format!("{rc:p}{arc:p}{b:p}"); + + if cfg!(target_pointer_width = "32") { + assert_eq!(format!("{:#p}", p), "0x00000000"); + } else { + assert_eq!(format!("{:#p}", p), "0x0000000000000000"); + } + assert_eq!(format!("{:p}", p), "0x0"); +} + #[test] fn test_default_write_impls() { use core::fmt::Write; diff --git a/tests/ui/traits/fmt-pointer-trait.rs b/tests/ui/traits/fmt-pointer-trait.rs deleted file mode 100644 index edf734597f50..000000000000 --- a/tests/ui/traits/fmt-pointer-trait.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ run-pass -use std::ptr; -use std::rc::Rc; -use std::sync::Arc; - -fn main() { - let p: *const u8 = ptr::null(); - let rc = Rc::new(1usize); - let arc = Arc::new(1usize); - let b = Box::new("hi"); - - let _ = format!("{:p}{:p}{:p}", - rc, arc, b); - - if cfg!(target_pointer_width = "32") { - assert_eq!(format!("{:#p}", p), - "0x00000000"); - } else { - assert_eq!(format!("{:#p}", p), - "0x0000000000000000"); - } - assert_eq!(format!("{:p}", p), - "0x0"); -} From 2c0f14cb0c108ac72ea23645694a4abee75babd8 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Tue, 23 Dec 2025 03:33:20 +0000 Subject: [PATCH 1165/3801] bugfix: Fix compilation error in hermit-abi time.rs Fixes time.rs by updating the MIN and MAX structs appropriately. Signed-off-by: John Nunley --- library/std/src/sys/pal/hermit/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs index 53b1f9292b3d..734ad2540a18 100644 --- a/library/std/src/sys/pal/hermit/time.rs +++ b/library/std/src/sys/pal/hermit/time.rs @@ -213,9 +213,9 @@ pub struct SystemTime(Timespec); pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero()); impl SystemTime { - pub const MAX: SystemTime = SystemTime { t: Timespec::MAX }; + pub const MAX: SystemTime = SystemTime(Timespec::MAX); - pub const MIN: SystemTime = SystemTime { t: Timespec::MIN }; + pub const MIN: SystemTime = SystemTime(Timespec::MIN); pub fn new(tv_sec: i64, tv_nsec: i32) -> SystemTime { SystemTime(Timespec::new(tv_sec, tv_nsec)) From d2f42b0ab7c5df475788f908b55e01dbaeff6681 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Mon, 22 Dec 2025 19:58:33 -0800 Subject: [PATCH 1166/3801] bugfix: Fix compile issue in Vita libstd Unfortunately it looks like the Vita libc does not support the "utimensat" function, which is needed for setting file times. To fix the build, this commit marks Vita as unsupported for the function that sets the file times. Signed-off-by: John Nunley --- library/std/src/sys/fs/unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index ee3cb54a5ee6..de80f2ed053f 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -2166,7 +2166,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> fn set_times_impl(p: &CStr, times: FileTimes, follow_symlinks: bool) -> io::Result<()> { cfg_select! { - any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx") => { + any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "vita") => { let _ = (p, times, follow_symlinks); Err(io::const_error!( io::ErrorKind::Unsupported, From f379b40190c8469e2bd6646aa60bee9fb4756b6d Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 23 Dec 2025 04:59:25 +0000 Subject: [PATCH 1167/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to a0c97e3255e2b9140f131baec1c93eef57640d21. --- 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 024cbd285207..596e757d3fcc 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -cb79c42008b970269f6a06b257e5f04b93f24d03 +a0c97e3255e2b9140f131baec1c93eef57640d21 From 12610b2ce87a85ab53e2971f9e8e480659a6967c Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Tue, 23 Dec 2025 05:01:10 +0000 Subject: [PATCH 1168/3801] fix: `obfuscated_if_else` wrongly unmangled macros --- clippy_lints/src/methods/obfuscated_if_else.rs | 16 +++++++++------- tests/ui/obfuscated_if_else.fixed | 6 ++++++ tests/ui/obfuscated_if_else.rs | 6 ++++++ tests/ui/obfuscated_if_else.stderr | 8 +++++++- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/methods/obfuscated_if_else.rs b/clippy_lints/src/methods/obfuscated_if_else.rs index b2466bbd982d..69d851e81600 100644 --- a/clippy_lints/src/methods/obfuscated_if_else.rs +++ b/clippy_lints/src/methods/obfuscated_if_else.rs @@ -1,7 +1,7 @@ use super::OBFUSCATED_IF_ELSE; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::eager_or_lazy::switch_to_eager_eval; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::{get_parent_expr, sym}; use rustc_errors::Applicability; @@ -33,20 +33,22 @@ pub(super) fn check<'tcx>( let if_then = match then_method_name { sym::then if let ExprKind::Closure(closure) = then_arg.kind => { let body = cx.tcx.hir_body(closure.body); - snippet_with_applicability(cx, body.value.span, "..", &mut applicability) + snippet_with_context(cx, body.value.span, expr.span.ctxt(), "..", &mut applicability).0 }, - sym::then_some => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability), + sym::then_some => snippet_with_context(cx, then_arg.span, expr.span.ctxt(), "..", &mut applicability).0, _ => return, }; let els = match unwrap { - Unwrap::Or(arg) => snippet_with_applicability(cx, arg.span, "..", &mut applicability), + Unwrap::Or(arg) => snippet_with_context(cx, arg.span, expr.span.ctxt(), "..", &mut applicability).0, Unwrap::OrElse(arg) => match arg.kind { ExprKind::Closure(closure) => { let body = cx.tcx.hir_body(closure.body); - snippet_with_applicability(cx, body.value.span, "..", &mut applicability) + snippet_with_context(cx, body.value.span, expr.span.ctxt(), "..", &mut applicability).0 + }, + ExprKind::Path(_) => { + snippet_with_context(cx, arg.span, expr.span.ctxt(), "_", &mut applicability).0 + "()" }, - ExprKind::Path(_) => snippet_with_applicability(cx, arg.span, "_", &mut applicability) + "()", _ => return, }, Unwrap::OrDefault => "Default::default()".into(), @@ -54,7 +56,7 @@ pub(super) fn check<'tcx>( let sugg = format!( "if {} {{ {} }} else {{ {} }}", - Sugg::hir_with_applicability(cx, then_recv, "..", &mut applicability), + Sugg::hir_with_context(cx, then_recv, expr.span.ctxt(), "..", &mut applicability), if_then, els ); diff --git a/tests/ui/obfuscated_if_else.fixed b/tests/ui/obfuscated_if_else.fixed index 70ae090626b9..6bdb170a4aa9 100644 --- a/tests/ui/obfuscated_if_else.fixed +++ b/tests/ui/obfuscated_if_else.fixed @@ -87,3 +87,9 @@ fn issue11141() { let _ = *if true { &42 } else { &17 } as u8; //~^ obfuscated_if_else } + +#[allow(clippy::useless_format)] +fn issue16288() { + if true { format!("this is a test") } else { Default::default() }; + //~^ obfuscated_if_else +} diff --git a/tests/ui/obfuscated_if_else.rs b/tests/ui/obfuscated_if_else.rs index 8e1f57ca2c02..f7b5ea8c0135 100644 --- a/tests/ui/obfuscated_if_else.rs +++ b/tests/ui/obfuscated_if_else.rs @@ -87,3 +87,9 @@ fn issue11141() { let _ = *true.then_some(&42).unwrap_or(&17) as u8; //~^ obfuscated_if_else } + +#[allow(clippy::useless_format)] +fn issue16288() { + true.then(|| format!("this is a test")).unwrap_or_default(); + //~^ obfuscated_if_else +} diff --git a/tests/ui/obfuscated_if_else.stderr b/tests/ui/obfuscated_if_else.stderr index 0de7259d8bb8..865dca56b97a 100644 --- a/tests/ui/obfuscated_if_else.stderr +++ b/tests/ui/obfuscated_if_else.stderr @@ -139,5 +139,11 @@ error: this method chain can be written more clearly with `if .. else ..` LL | let _ = *true.then_some(&42).unwrap_or(&17) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` -error: aborting due to 23 previous errors +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:93:5 + | +LL | true.then(|| format!("this is a test")).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { format!("this is a test") } else { Default::default() }` + +error: aborting due to 24 previous errors From ffd4da296e9238db0379433f111de2a38a50200f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Mon, 22 Dec 2025 23:33:04 -0600 Subject: [PATCH 1169/3801] remove unsupported pipe module from VEXos pal --- library/std/src/sys/pal/vexos/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/std/src/sys/pal/vexos/mod.rs b/library/std/src/sys/pal/vexos/mod.rs index 3a37c8f2d488..049b435905d4 100644 --- a/library/std/src/sys/pal/vexos/mod.rs +++ b/library/std/src/sys/pal/vexos/mod.rs @@ -1,6 +1,4 @@ pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; pub mod time; #[expect(dead_code)] From cf02cff2cf3865d78013e58f9749bc112a5e33c4 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 23 Dec 2025 11:59:56 +0530 Subject: [PATCH 1170/3801] remove channels with callbacks in proc-macro-srv --- .../proc-macro-srv-cli/src/main_loop.rs | 133 ++++++++---------- .../crates/proc-macro-srv/src/dylib.rs | 31 +--- .../proc-macro-srv/src/dylib/proc_macros.rs | 80 +---------- .../crates/proc-macro-srv/src/lib.rs | 69 ++------- .../src/server_impl/rust_analyzer_span.rs | 31 ++-- .../src/server_impl/token_id.rs | 5 +- .../crates/proc-macro-srv/src/tests/utils.rs | 8 +- 7 files changed, 98 insertions(+), 259 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index 8666c1367717..99e3d79ef29a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -1,7 +1,6 @@ //! The main loop of the proc-macro server. use std::io; -use crossbeam_channel::unbounded; use proc_macro_api::{ Codec, bidirectional_protocol::msg as bidirectional, @@ -82,6 +81,7 @@ fn run_new() -> io::Result<()> { } bidirectional::Request::ApiVersionCheck {} => { + // bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION).write::<_, C>(stdout) send_response::<_, C>( &mut stdout, bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), @@ -160,6 +160,7 @@ fn handle_expand_id( def_site, call_site, mixed_site, + None, ) .map(|it| { legacy::FlatTree::from_tokenstream_raw::(it, call_site, CURRENT_API_VERSION) @@ -169,7 +170,7 @@ fn handle_expand_id( send_response::<_, C>(stdout, bidirectional::Response::ExpandMacro(res)) } -fn handle_expand_ra( +fn handle_expand_ra( srv: &proc_macro_srv::ProcMacroSrv<'_>, stdin: &mut R, stdout: &mut W, @@ -185,74 +186,69 @@ fn handle_expand_ra( macro_body, macro_name, attributes, - has_global_spans: - bidirectional::ExpnGlobals { serialize: _, def_site, call_site, mixed_site }, + has_global_spans: bidirectional::ExpnGlobals { def_site, call_site, mixed_site, .. }, span_data_table, }, } = task; let mut span_data_table = legacy::deserialize_span_data_index_map(&span_data_table); - let def_site_span = span_data_table[def_site]; - let call_site_span = span_data_table[call_site]; - let mixed_site_span = span_data_table[mixed_site]; + let def_site = span_data_table[def_site]; + let call_site = span_data_table[call_site]; + let mixed_site = span_data_table[mixed_site]; - let macro_body_ts = + let macro_body = macro_body.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| { srv.join_spans(a, b).unwrap_or(b) }); - let attributes_ts = attributes.map(|it| { + let attributes = attributes.map(|it| { it.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| { srv.join_spans(a, b).unwrap_or(b) }) }); - let (subreq_tx, subreq_rx) = unbounded::(); - let (subresp_tx, subresp_rx) = unbounded::(); + let (subreq_tx, subreq_rx) = crossbeam_channel::unbounded(); + let (subresp_tx, subresp_rx) = crossbeam_channel::unbounded(); let (result_tx, result_rx) = crossbeam_channel::bounded(1); std::thread::scope(|scope| { - let srv_ref = &srv; + scope.spawn(|| { + let callback = Box::new(move |req: proc_macro_srv::SubRequest| { + subreq_tx.send(req).unwrap(); + subresp_rx.recv().unwrap() + }); - scope.spawn({ - let lib = lib.clone(); - let env = env.clone(); - let current_dir = current_dir.clone(); - let macro_name = macro_name.clone(); - move || { - let res = srv_ref - .expand_with_channels( - lib, - &env, - current_dir, - ¯o_name, - macro_body_ts, - attributes_ts, - def_site_span, - call_site_span, - mixed_site_span, - subresp_rx, - subreq_tx, + let res = srv + .expand( + lib, + &env, + current_dir, + ¯o_name, + macro_body, + attributes, + def_site, + call_site, + mixed_site, + Some(callback), + ) + .map(|it| { + ( + legacy::FlatTree::from_tokenstream( + it, + CURRENT_API_VERSION, + call_site, + &mut span_data_table, + ), + legacy::serialize_span_data_index_map(&span_data_table), ) - .map(|it| { - ( - legacy::FlatTree::from_tokenstream( - it, - CURRENT_API_VERSION, - call_site_span, - &mut span_data_table, - ), - legacy::serialize_span_data_index_map(&span_data_table), - ) - }) - .map(|(tree, span_data_table)| bidirectional::ExpandMacroExtended { - tree, - span_data_table, - }) - .map_err(|e| e.into_string().unwrap_or_default()) - .map_err(legacy::PanicMessage); - let _ = result_tx.send(res); - } + }) + .map(|(tree, span_data_table)| bidirectional::ExpandMacroExtended { + tree, + span_data_table, + }) + .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); + + let _ = result_tx.send(res); }); loop { @@ -264,31 +260,26 @@ fn handle_expand_ra( let subreq = match subreq_rx.recv() { Ok(r) => r, - Err(_) => { - break; - } + Err(_) => break, }; - send_subrequest::<_, C>(stdout, from_srv_req(subreq)).unwrap(); + let api_req = from_srv_req(subreq); + bidirectional::BidirectionalMessage::SubRequest(api_req).write::<_, C>(stdout).unwrap(); - let resp_opt = bidirectional::BidirectionalMessage::read::<_, C>(stdin, buf).unwrap(); - let resp = match resp_opt { - Some(env) => env, - None => { - break; - } - }; + let resp = bidirectional::BidirectionalMessage::read::<_, C>(stdin, buf) + .unwrap() + .expect("client closed connection"); match resp { - bidirectional::BidirectionalMessage::SubResponse(subresp) => { - let _ = subresp_tx.send(from_client_res(subresp)); - } - _ => { - break; + bidirectional::BidirectionalMessage::SubResponse(api_resp) => { + let srv_resp = from_client_res(api_resp); + subresp_tx.send(srv_resp).unwrap(); } + other => panic!("expected SubResponse, got {other:?}"), } } }); + Ok(()) } @@ -356,6 +347,7 @@ fn run_() -> io::Result<()> { def_site, call_site, mixed_site, + None, ) .map(|it| { legacy::FlatTree::from_tokenstream_raw::( @@ -397,6 +389,7 @@ fn run_() -> io::Result<()> { def_site, call_site, mixed_site, + None, ) .map(|it| { ( @@ -455,11 +448,3 @@ fn send_response( let resp = bidirectional::BidirectionalMessage::Response(resp); resp.write::(stdout) } - -fn send_subrequest( - stdout: &mut W, - resp: bidirectional::SubRequest, -) -> io::Result<()> { - let resp = bidirectional::BidirectionalMessage::SubRequest(resp); - resp.write::(stdout) -} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index ba089c9549d3..082a1d77b5aa 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -12,7 +12,7 @@ use object::Object; use paths::{Utf8Path, Utf8PathBuf}; use crate::{ - PanicMessage, ProcMacroKind, ProcMacroSrvSpan, dylib::proc_macros::ProcMacros, + PanicMessage, ProcMacroKind, ProcMacroSrvSpan, SubCallback, dylib::proc_macros::ProcMacros, token_stream::TokenStream, }; @@ -45,39 +45,14 @@ impl Expander { def_site: S, call_site: S, mixed_site: S, + callback: Option, ) -> Result, PanicMessage> where ::TokenStream: Default, { self.inner .proc_macros - .expand(macro_name, macro_body, attribute, def_site, call_site, mixed_site) - } - - pub(crate) fn expand_with_channels( - &self, - macro_name: &str, - macro_body: crate::token_stream::TokenStream, - attribute: Option>, - def_site: S, - call_site: S, - mixed_site: S, - cli_to_server: crossbeam_channel::Receiver, - server_to_cli: crossbeam_channel::Sender, - ) -> Result, crate::PanicMessage> - where - ::TokenStream: Default, - { - self.inner.proc_macros.expand_with_channels( - macro_name, - macro_body, - attribute, - def_site, - call_site, - mixed_site, - cli_to_server, - server_to_cli, - ) + .expand(macro_name, macro_body, attribute, def_site, call_site, mixed_site, callback) } pub(crate) fn list_macros(&self) -> impl Iterator { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs index 5b6f1cf2f332..6f6bd086de64 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs @@ -1,8 +1,7 @@ //! Proc macro ABI +use crate::{ProcMacroKind, ProcMacroSrvSpan, SubCallback, token_stream::TokenStream}; use proc_macro::bridge; -use crate::{ProcMacroKind, ProcMacroSrvSpan, token_stream::TokenStream}; - #[repr(transparent)] pub(crate) struct ProcMacros([bridge::client::ProcMacro]); @@ -21,6 +20,7 @@ impl ProcMacros { def_site: S, call_site: S, mixed_site: S, + callback: Option, ) -> Result, crate::PanicMessage> { let parsed_attributes = attribute.unwrap_or_default(); @@ -31,7 +31,7 @@ impl ProcMacros { { let res = client.run( &bridge::server::SameThread, - S::make_server(call_site, def_site, mixed_site, None, None), + S::make_server(call_site, def_site, mixed_site, callback), macro_body, cfg!(debug_assertions), ); @@ -40,7 +40,7 @@ impl ProcMacros { bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { let res = client.run( &bridge::server::SameThread, - S::make_server(call_site, def_site, mixed_site, None, None), + S::make_server(call_site, def_site, mixed_site, callback), macro_body, cfg!(debug_assertions), ); @@ -49,77 +49,7 @@ impl ProcMacros { bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { let res = client.run( &bridge::server::SameThread, - S::make_server(call_site, def_site, mixed_site, None, None), - parsed_attributes, - macro_body, - cfg!(debug_assertions), - ); - return res.map_err(crate::PanicMessage::from); - } - _ => continue, - } - } - - Err(bridge::PanicMessage::String(format!("proc-macro `{macro_name}` is missing")).into()) - } - - pub(crate) fn expand_with_channels( - &self, - macro_name: &str, - macro_body: TokenStream, - attribute: Option>, - def_site: S, - call_site: S, - mixed_site: S, - cli_to_server: crossbeam_channel::Receiver, - server_to_cli: crossbeam_channel::Sender, - ) -> Result, crate::PanicMessage> { - let parsed_attributes = attribute.unwrap_or_default(); - - for proc_macro in &self.0 { - match proc_macro { - bridge::client::ProcMacro::CustomDerive { trait_name, client, .. } - if *trait_name == macro_name => - { - let res = client.run( - &bridge::server::SameThread, - S::make_server( - call_site, - def_site, - mixed_site, - Some(cli_to_server), - Some(server_to_cli), - ), - macro_body, - cfg!(debug_assertions), - ); - return res.map_err(crate::PanicMessage::from); - } - bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { - let res = client.run( - &bridge::server::SameThread, - S::make_server( - call_site, - def_site, - mixed_site, - Some(cli_to_server), - Some(server_to_cli), - ), - macro_body, - cfg!(debug_assertions), - ); - return res.map_err(crate::PanicMessage::from); - } - bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { - let res = client.run( - &bridge::server::SameThread, - S::make_server( - call_site, - def_site, - mixed_site, - Some(cli_to_server), - Some(server_to_cli), - ), + S::make_server(call_site, def_site, mixed_site, callback), parsed_attributes, macro_body, cfg!(debug_assertions), diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index f369ab93a2a3..705ac930ed9c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -91,6 +91,8 @@ impl<'env> ProcMacroSrv<'env> { } } +pub type SubCallback = Box SubResponse + Send + Sync + 'static>; + pub enum SubRequest { SourceText { file_id: EditionedFileId, start: u32, end: u32 }, } @@ -113,6 +115,7 @@ impl ProcMacroSrv<'_> { def_site: S, call_site: S, mixed_site: S, + callback: Option, ) -> Result, PanicMessage> { let snapped_env = self.env; let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage { @@ -128,54 +131,9 @@ impl ProcMacroSrv<'_> { .stack_size(EXPANDER_STACK_SIZE) .name(macro_name.to_owned()) .spawn_scoped(s, move || { - expander - .expand(macro_name, macro_body, attribute, def_site, call_site, mixed_site) - }); - match thread.unwrap().join() { - Ok(res) => res, - Err(e) => std::panic::resume_unwind(e), - } - }); - prev_env.rollback(); - - result - } - - pub fn expand_with_channels( - &self, - lib: impl AsRef, - env: &[(String, String)], - current_dir: Option>, - macro_name: &str, - macro_body: token_stream::TokenStream, - attribute: Option>, - def_site: S, - call_site: S, - mixed_site: S, - cli_to_server: crossbeam_channel::Receiver, - server_to_cli: crossbeam_channel::Sender, - ) -> Result, PanicMessage> { - let snapped_env = self.env; - let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage { - message: Some(format!("failed to load macro: {err}")), - })?; - - let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref)); - - let result = thread::scope(|s| { - let thread = thread::Builder::new() - .stack_size(EXPANDER_STACK_SIZE) - .name(macro_name.to_owned()) - .spawn_scoped(s, move || { - expander.expand_with_channels( - macro_name, - macro_body, - attribute, - def_site, - call_site, - mixed_site, - cli_to_server, - server_to_cli, + expander.expand( + macro_name, macro_body, attribute, def_site, call_site, mixed_site, + callback, ) }); match thread.unwrap().join() { @@ -229,8 +187,7 @@ pub trait ProcMacroSrvSpan: Copy + Send + Sync { call_site: Self, def_site: Self, mixed_site: Self, - cli_to_server: Option>, - server_to_cli: Option>, + callback: Option, ) -> Self::Server; } @@ -241,15 +198,13 @@ impl ProcMacroSrvSpan for SpanId { call_site: Self, def_site: Self, mixed_site: Self, - cli_to_server: Option>, - server_to_cli: Option>, + callback: Option, ) -> Self::Server { Self::Server { call_site, def_site, mixed_site, - cli_to_server, - server_to_cli, + callback, tracked_env_vars: Default::default(), tracked_paths: Default::default(), } @@ -262,17 +217,15 @@ impl ProcMacroSrvSpan for Span { call_site: Self, def_site: Self, mixed_site: Self, - cli_to_server: Option>, - server_to_cli: Option>, + callback: Option, ) -> Self::Server { Self::Server { call_site, def_site, mixed_site, + callback, tracked_env_vars: Default::default(), tracked_paths: Default::default(), - cli_to_server, - server_to_cli, } } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index cccb74429dd6..0bce67fcd9fe 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -14,7 +14,7 @@ use proc_macro::bridge::server; use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TextRange, TextSize}; use crate::{ - SubRequest, SubResponse, + SubCallback, SubRequest, SubResponse, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; @@ -29,8 +29,7 @@ pub struct RaSpanServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, - pub cli_to_server: Option>, - pub server_to_cli: Option>, + pub callback: Option, } impl server::Types for RaSpanServer { @@ -153,21 +152,17 @@ impl server::Span for RaSpanServer { /// See PR: /// https://github.com/rust-lang/rust/pull/55780 fn source_text(&mut self, span: Self::Span) -> Option { - // FIXME requires db, needs special handling wrt fixup spans - if self.server_to_cli.is_some() && self.cli_to_server.is_some() { - let file_id = span.anchor.file_id; - let start: u32 = span.range.start().into(); - let end: u32 = span.range.end().into(); - let _ = self.server_to_cli.clone().unwrap().send(SubRequest::SourceText { - file_id, - start, - end, - }); - match self.cli_to_server.as_ref()?.recv().ok()? { - SubResponse::SourceTextResult { text } => text, - } - } else { - None + let file_id = span.anchor.file_id; + let start: u32 = span.range.start().into(); + let end: u32 = span.range.end().into(); + + let req = SubRequest::SourceText { file_id, start, end }; + + let cb = self.callback.as_mut()?; + let response = cb(req); + + match response { + SubResponse::SourceTextResult { text } => text, } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index 268042b3bc07..3b12644ec34a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -9,7 +9,7 @@ use intern::Symbol; use proc_macro::bridge::server; use crate::{ - SubRequest, SubResponse, + SubCallback, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; @@ -35,8 +35,7 @@ pub struct SpanIdServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, - pub cli_to_server: Option>, - pub server_to_cli: Option>, + pub callback: Option, } impl server::Types for SpanIdServer { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs index 1b12308ad6c5..61fcd810b1d9 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs @@ -59,8 +59,9 @@ fn assert_expand_impl( let input_ts_string = format!("{input_ts:?}"); let attr_ts_string = attr_ts.as_ref().map(|it| format!("{it:?}")); - let res = - expander.expand(macro_name, input_ts, attr_ts, def_site, call_site, mixed_site).unwrap(); + let res = expander + .expand(macro_name, input_ts, attr_ts, def_site, call_site, mixed_site, None) + .unwrap(); expect.assert_eq(&format!( "{input_ts_string}{}{}{}", if attr_ts_string.is_some() { "\n\n" } else { "" }, @@ -91,7 +92,8 @@ fn assert_expand_impl( let fixture_string = format!("{fixture:?}"); let attr_string = attr.as_ref().map(|it| format!("{it:?}")); - let res = expander.expand(macro_name, fixture, attr, def_site, call_site, mixed_site).unwrap(); + let res = + expander.expand(macro_name, fixture, attr, def_site, call_site, mixed_site, None).unwrap(); expect_spanned.assert_eq(&format!( "{fixture_string}{}{}{}", if attr_string.is_some() { "\n\n" } else { "" }, From ffbb9a59322f57f1e38fe7b992e7b03ad2d00edd Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 20 Dec 2025 18:42:41 +0100 Subject: [PATCH 1171/3801] compiletest: Add `LineNumber` newtype to avoid `+1` magic here and there Start small. If it works well we can increase usage bit by bit as time passes. Note that we keep using "0" to represent "no specific line" because changing to `Option` everywhere is much bigger and noisier change. That can be done later if wanted. --- src/tools/compiletest/src/directives.rs | 4 +++- src/tools/compiletest/src/directives/file.rs | 3 ++- src/tools/compiletest/src/directives/line.rs | 6 ++++-- .../compiletest/src/directives/line_number.rs | 21 +++++++++++++++++++ src/tools/compiletest/src/directives/tests.rs | 7 ++++--- src/tools/compiletest/src/runtest/debugger.rs | 18 +++++++--------- 6 files changed, 42 insertions(+), 17 deletions(-) create mode 100644 src/tools/compiletest/src/directives/line_number.rs diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index c154886ebcde..d1e0c5d95001 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -29,6 +29,8 @@ mod directive_names; mod file; mod handlers; mod line; +mod line_number; +pub(crate) use line_number::LineNumber; mod needs; #[cfg(test)] mod tests; @@ -591,7 +593,7 @@ fn iter_directives( ]; // Process the extra implied directives, with a dummy line number of 0. for directive_str in extra_directives { - let directive_line = line_directive(testfile, 0, directive_str) + let directive_line = line_directive(testfile, LineNumber::ZERO, directive_str) .unwrap_or_else(|| panic!("bad extra-directive line: {directive_str:?}")); it(&directive_line); } diff --git a/src/tools/compiletest/src/directives/file.rs b/src/tools/compiletest/src/directives/file.rs index 82819ac0c8f0..57186faa56b8 100644 --- a/src/tools/compiletest/src/directives/file.rs +++ b/src/tools/compiletest/src/directives/file.rs @@ -1,5 +1,6 @@ use camino::Utf8Path; +use crate::directives::LineNumber; use crate::directives::line::{DirectiveLine, line_directive}; pub(crate) struct FileDirectives<'a> { @@ -11,7 +12,7 @@ impl<'a> FileDirectives<'a> { pub(crate) fn from_file_contents(path: &'a Utf8Path, file_contents: &'a str) -> Self { let mut lines = vec![]; - for (line_number, ln) in (1..).zip(file_contents.lines()) { + for (line_number, ln) in LineNumber::enumerate().zip(file_contents.lines()) { let ln = ln.trim(); if let Some(directive_line) = line_directive(path, line_number, ln) { diff --git a/src/tools/compiletest/src/directives/line.rs b/src/tools/compiletest/src/directives/line.rs index 16dd9a8de1c0..9cc24c98a859 100644 --- a/src/tools/compiletest/src/directives/line.rs +++ b/src/tools/compiletest/src/directives/line.rs @@ -2,13 +2,15 @@ use std::fmt; use camino::Utf8Path; +use crate::directives::LineNumber; + const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@"; /// If the given line begins with the appropriate comment prefix for a directive, /// returns a struct containing various parts of the directive. pub(crate) fn line_directive<'a>( file_path: &'a Utf8Path, - line_number: usize, + line_number: LineNumber, original_line: &'a str, ) -> Option> { // Ignore lines that don't start with the comment prefix. @@ -60,7 +62,7 @@ pub(crate) struct DirectiveLine<'a> { /// Mostly used for diagnostics, but some directives (e.g. `//@ pp-exact`) /// also use it to compute a value based on the filename. pub(crate) file_path: &'a Utf8Path, - pub(crate) line_number: usize, + pub(crate) line_number: LineNumber, /// Some test directives start with a revision name in square brackets /// (e.g. `[foo]`), and only apply to that revision of the test. diff --git a/src/tools/compiletest/src/directives/line_number.rs b/src/tools/compiletest/src/directives/line_number.rs new file mode 100644 index 000000000000..ce5f200f470c --- /dev/null +++ b/src/tools/compiletest/src/directives/line_number.rs @@ -0,0 +1,21 @@ +/// A line number in a file. Internally the first line has index 1. +/// If it is 0 it means "no specific line" (used e.g. for implied directives). +/// When `Display`:ed, the first line is `1`. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub(crate) struct LineNumber(usize); + +impl LineNumber { + /// This represents "no specific line" (used e.g. for implied directives). + pub(crate) const ZERO: Self = Self(0); + + /// A never ending iterator over line numbers starting from the first line. + pub(crate) fn enumerate() -> impl Iterator { + (1..).map(LineNumber) + } +} + +impl std::fmt::Display for LineNumber { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 90e2cb77e304..dfc733cf4e32 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -6,8 +6,8 @@ use semver::Version; use crate::common::{Config, Debugger, TestMode}; use crate::directives::{ self, AuxProps, DIRECTIVE_HANDLERS_MAP, DirectivesCache, EarlyProps, Edition, EditionRange, - FileDirectives, KNOWN_DIRECTIVE_NAMES_SET, extract_llvm_version, extract_version_range, - line_directive, parse_edition, parse_normalize_rule, + FileDirectives, KNOWN_DIRECTIVE_NAMES_SET, LineNumber, extract_llvm_version, + extract_version_range, line_directive, parse_edition, parse_normalize_rule, }; use crate::executor::{CollectedTestDesc, ShouldFail}; @@ -1000,7 +1000,8 @@ fn parse_edition_range(line: &str) -> Option { let config = cfg().build(); let line_with_comment = format!("//@ {line}"); - let line = line_directive(Utf8Path::new("tmp.rs"), 0, &line_with_comment).unwrap(); + let line = + line_directive(Utf8Path::new("tmp.rs"), LineNumber::ZERO, &line_with_comment).unwrap(); super::parse_edition_range(&config, &line) } diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs index 00935ab57d1c..c83e00c1006e 100644 --- a/src/tools/compiletest/src/runtest/debugger.rs +++ b/src/tools/compiletest/src/runtest/debugger.rs @@ -4,6 +4,7 @@ use std::io::{BufRead, BufReader}; use camino::{Utf8Path, Utf8PathBuf}; +use crate::directives::LineNumber; use crate::runtest::ProcRes; /// Representation of information to invoke a debugger and check its output @@ -11,9 +12,9 @@ pub(super) struct DebuggerCommands { /// Commands for the debuuger pub commands: Vec, /// Lines to insert breakpoints at - pub breakpoint_lines: Vec, + pub breakpoint_lines: Vec, /// Contains the source line number to check and the line itself - check_lines: Vec<(usize, String)>, + check_lines: Vec<(LineNumber, String)>, /// Source file name file: Utf8PathBuf, } @@ -26,15 +27,13 @@ impl DebuggerCommands { let mut breakpoint_lines = vec![]; let mut commands = vec![]; let mut check_lines = vec![]; - let mut counter = 0; let reader = BufReader::new(File::open(file.as_std_path()).unwrap()); - for (line_no, line) in reader.lines().enumerate() { - counter += 1; + for (line_number, line) in LineNumber::enumerate().zip(reader.lines()) { let line = line.map_err(|e| format!("Error while parsing debugger commands: {}", e))?; // Breakpoints appear on lines with actual code, typically at the end of the line. if line.contains("#break") { - breakpoint_lines.push(counter); + breakpoint_lines.push(line_number); continue; } @@ -46,7 +45,7 @@ impl DebuggerCommands { commands.push(command); } if let Some(pattern) = parse_name_value(&line, &check_directive) { - check_lines.push((line_no, pattern)); + check_lines.push((line_number, pattern)); } } @@ -88,15 +87,14 @@ impl DebuggerCommands { ); for (src_lineno, err_line) in missing { - write!(msg, "\n ({fname}:{num}) `{err_line}`", num = src_lineno + 1).unwrap(); + write!(msg, "\n ({fname}:{src_lineno}) `{err_line}`").unwrap(); } if !found.is_empty() { let init = "\nthe following subset of check directive(s) was found successfully:"; msg.push_str(init); for (src_lineno, found_line) in found { - write!(msg, "\n ({fname}:{num}) `{found_line}`", num = src_lineno + 1) - .unwrap(); + write!(msg, "\n ({fname}:{src_lineno}) `{found_line}`").unwrap(); } } From 1de1885a63804bd5e0538ba76ab27278b6acf01f Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Tue, 23 Dec 2025 10:34:23 +0300 Subject: [PATCH 1172/3801] Support syntax for one-line trait reuse --- compiler/rustc_parse/messages.ftl | 2 + compiler/rustc_parse/src/errors.rs | 7 + compiler/rustc_parse/src/parser/item.rs | 144 +++++++-- tests/pretty/delegation-impl-reuse.pp | 46 +++ tests/pretty/delegation-impl-reuse.rs | 18 ++ tests/ui/delegation/impl-reuse-bad-path.rs | 31 ++ .../ui/delegation/impl-reuse-bad-path.stderr | 52 ++++ tests/ui/delegation/impl-reuse-empty-glob.rs | 14 + .../delegation/impl-reuse-empty-glob.stderr | 8 + .../delegation/impl-reuse-illegal-places.rs | 51 +++ .../impl-reuse-illegal-places.stderr | 92 ++++++ .../delegation/impl-reuse-negative-traits.rs | 19 ++ .../impl-reuse-negative-traits.stderr | 9 + .../delegation/impl-reuse-non-reuse-items.rs | 32 ++ .../impl-reuse-non-reuse-items.stderr | 60 ++++ .../impl-reuse-non-trait-impl-cfg-false.rs | 10 + ...impl-reuse-non-trait-impl-cfg-false.stderr | 8 + .../delegation/impl-reuse-non-trait-impl.rs | 9 + .../impl-reuse-non-trait-impl.stderr | 8 + tests/ui/delegation/impl-reuse-pass.rs | 292 ++++++++++++++++++ 20 files changed, 879 insertions(+), 33 deletions(-) create mode 100644 tests/pretty/delegation-impl-reuse.pp create mode 100644 tests/pretty/delegation-impl-reuse.rs create mode 100644 tests/ui/delegation/impl-reuse-bad-path.rs create mode 100644 tests/ui/delegation/impl-reuse-bad-path.stderr create mode 100644 tests/ui/delegation/impl-reuse-empty-glob.rs create mode 100644 tests/ui/delegation/impl-reuse-empty-glob.stderr create mode 100644 tests/ui/delegation/impl-reuse-illegal-places.rs create mode 100644 tests/ui/delegation/impl-reuse-illegal-places.stderr create mode 100644 tests/ui/delegation/impl-reuse-negative-traits.rs create mode 100644 tests/ui/delegation/impl-reuse-negative-traits.stderr create mode 100644 tests/ui/delegation/impl-reuse-non-reuse-items.rs create mode 100644 tests/ui/delegation/impl-reuse-non-reuse-items.stderr create mode 100644 tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.rs create mode 100644 tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.stderr create mode 100644 tests/ui/delegation/impl-reuse-non-trait-impl.rs create mode 100644 tests/ui/delegation/impl-reuse-non-trait-impl.stderr create mode 100644 tests/ui/delegation/impl-reuse-pass.rs diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 87d1173c0d48..747895c80469 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -162,6 +162,8 @@ parse_default_not_followed_by_item = `default` is not followed by an item .label = the `default` qualifier .note = only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` +parse_delegation_non_trait_impl_reuse = only trait impls can be reused + parse_do_catch_syntax_removed = found removed `do catch` syntax .note = following RFC #2388, the new non-placeholder syntax is `try` .suggestion = replace with the new syntax diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 698d8f76aaa6..3b72c9802afd 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -3671,3 +3671,10 @@ pub(crate) struct VarargsWithoutPattern { #[suggestion(code = "_: ...", applicability = "machine-applicable")] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(parse_delegation_non_trait_impl_reuse)] +pub(crate) struct ImplReuseInherentImpl { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 33913fd351a1..fb8b76e32209 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -117,6 +117,11 @@ impl<'a> Parser<'a> { } } +enum ReuseKind { + Path, + Impl, +} + impl<'a> Parser<'a> { pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option>> { let fn_parse_mode = @@ -249,9 +254,9 @@ impl<'a> Parser<'a> { } else if self.check_keyword_case(exp!(Trait), case) || self.check_trait_front_matter() { // TRAIT ITEM self.parse_item_trait(attrs, lo)? - } else if self.check_impl_frontmatter() { + } else if self.check_impl_frontmatter(0) { // IMPL ITEM - self.parse_item_impl(attrs, def_())? + self.parse_item_impl(attrs, def_(), false)? } else if let Const::Yes(const_span) = self.parse_constness(case) { // CONST ITEM self.recover_const_mut(const_span); @@ -265,8 +270,8 @@ impl<'a> Parser<'a> { rhs, define_opaque: None, })) - } else if self.is_reuse_path_item() { - self.parse_item_delegation()? + } else if let Some(kind) = self.is_reuse_item() { + self.parse_item_delegation(attrs, def_(), kind)? } else if self.check_keyword_case(exp!(Mod), case) || self.check_keyword_case(exp!(Unsafe), case) && self.is_keyword_ahead(1, &[kw::Mod]) { @@ -367,16 +372,25 @@ impl<'a> Parser<'a> { /// When parsing a statement, would the start of a path be an item? pub(super) fn is_path_start_item(&mut self) -> bool { self.is_kw_followed_by_ident(kw::Union) // no: `union::b`, yes: `union U { .. }` - || self.is_reuse_path_item() + || self.is_reuse_item().is_some() // yes: `reuse impl Trait for Struct { self.0 }`, yes: `reuse some_path::foo;` || self.check_trait_front_matter() // no: `auto::b`, yes: `auto trait X { .. }` || self.is_async_fn() // no(2015): `async::b`, yes: `async fn` || matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) // no: `macro_rules::b`, yes: `macro_rules! mac` } - fn is_reuse_path_item(&mut self) -> bool { + fn is_reuse_item(&mut self) -> Option { + if !self.token.is_keyword(kw::Reuse) { + return None; + } + // no: `reuse ::path` for compatibility reasons with macro invocations - self.token.is_keyword(kw::Reuse) - && self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep) + if self.look_ahead(1, |t| t.is_path_start() && *t != token::PathSep) { + Some(ReuseKind::Path) + } else if self.check_impl_frontmatter(1) { + Some(ReuseKind::Impl) + } else { + None + } } /// Are we sure this could not possibly be a macro invocation? @@ -560,6 +574,7 @@ impl<'a> Parser<'a> { &mut self, attrs: &mut AttrVec, defaultness: Defaultness, + is_reuse: bool, ) -> PResult<'a, ItemKind> { let mut constness = self.parse_constness(Case::Sensitive); let safety = self.parse_safety(Case::Sensitive); @@ -628,7 +643,11 @@ impl<'a> Parser<'a> { generics.where_clause = self.parse_where_clause()?; - let impl_items = self.parse_item_list(attrs, |p| p.parse_impl_item(ForceCollect::No))?; + let impl_items = if is_reuse { + Default::default() + } else { + self.parse_item_list(attrs, |p| p.parse_impl_item(ForceCollect::No))? + }; let (of_trait, self_ty) = match ty_second { Some(ty_second) => { @@ -699,10 +718,76 @@ impl<'a> Parser<'a> { Ok(ItemKind::Impl(Impl { generics, of_trait, self_ty, items: impl_items, constness })) } - fn parse_item_delegation(&mut self) -> PResult<'a, ItemKind> { + fn parse_item_delegation( + &mut self, + attrs: &mut AttrVec, + defaultness: Defaultness, + kind: ReuseKind, + ) -> PResult<'a, ItemKind> { let span = self.token.span; self.expect_keyword(exp!(Reuse))?; + let item_kind = match kind { + ReuseKind::Path => self.parse_path_like_delegation(), + ReuseKind::Impl => self.parse_impl_delegation(span, attrs, defaultness), + }?; + + self.psess.gated_spans.gate(sym::fn_delegation, span.to(self.prev_token.span)); + + Ok(item_kind) + } + + fn parse_delegation_body(&mut self) -> PResult<'a, Option>> { + Ok(if self.check(exp!(OpenBrace)) { + Some(self.parse_block()?) + } else { + self.expect(exp!(Semi))?; + None + }) + } + + fn parse_impl_delegation( + &mut self, + span: Span, + attrs: &mut AttrVec, + defaultness: Defaultness, + ) -> PResult<'a, ItemKind> { + let mut impl_item = self.parse_item_impl(attrs, defaultness, true)?; + let ItemKind::Impl(Impl { items, of_trait, .. }) = &mut impl_item else { unreachable!() }; + + let until_expr_span = span.to(self.prev_token.span); + + let Some(of_trait) = of_trait else { + return Err(self + .dcx() + .create_err(errors::ImplReuseInherentImpl { span: until_expr_span })); + }; + + let body = self.parse_delegation_body()?; + let whole_reuse_span = span.to(self.prev_token.span); + + items.push(Box::new(AssocItem { + id: DUMMY_NODE_ID, + attrs: Default::default(), + span: whole_reuse_span, + tokens: None, + vis: Visibility { + kind: VisibilityKind::Inherited, + span: whole_reuse_span, + tokens: None, + }, + kind: AssocItemKind::DelegationMac(Box::new(DelegationMac { + qself: None, + prefix: of_trait.trait_ref.path.clone(), + suffixes: None, + body, + })), + })); + + Ok(impl_item) + } + + fn parse_path_like_delegation(&mut self) -> PResult<'a, ItemKind> { let (qself, path) = if self.eat_lt() { let (qself, path) = self.parse_qpath(PathStyle::Expr)?; (Some(qself), path) @@ -713,43 +798,35 @@ impl<'a> Parser<'a> { let rename = |this: &mut Self| { Ok(if this.eat_keyword(exp!(As)) { Some(this.parse_ident()?) } else { None }) }; - let body = |this: &mut Self| { - Ok(if this.check(exp!(OpenBrace)) { - Some(this.parse_block()?) - } else { - this.expect(exp!(Semi))?; - None - }) - }; - let item_kind = if self.eat_path_sep() { + Ok(if self.eat_path_sep() { let suffixes = if self.eat(exp!(Star)) { None } else { let parse_suffix = |p: &mut Self| Ok((p.parse_path_segment_ident()?, rename(p)?)); Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0) }; - let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? }; - ItemKind::DelegationMac(Box::new(deleg)) + + ItemKind::DelegationMac(Box::new(DelegationMac { + qself, + prefix: path, + suffixes, + body: self.parse_delegation_body()?, + })) } else { let rename = rename(self)?; let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident); - let deleg = Delegation { + + ItemKind::Delegation(Box::new(Delegation { id: DUMMY_NODE_ID, qself, path, ident, rename, - body: body(self)?, + body: self.parse_delegation_body()?, from_glob: false, - }; - ItemKind::Delegation(Box::new(deleg)) - }; - - let span = span.to(self.prev_token.span); - self.psess.gated_spans.gate(sym::fn_delegation, span); - - Ok(item_kind) + })) + }) } fn parse_item_list( @@ -2594,7 +2671,7 @@ impl<'a> Parser<'a> { Ok(body) } - fn check_impl_frontmatter(&mut self) -> bool { + fn check_impl_frontmatter(&mut self, look_ahead: usize) -> bool { const ALL_QUALS: &[Symbol] = &[kw::Const, kw::Unsafe]; // In contrast to the loop below, this call inserts `impl` into the // list of expected tokens shown in diagnostics. @@ -2603,7 +2680,7 @@ impl<'a> Parser<'a> { } let mut i = 0; while i < ALL_QUALS.len() { - let action = self.look_ahead(i, |token| { + let action = self.look_ahead(i + look_ahead, |token| { if token.is_keyword(kw::Impl) { return Some(true); } @@ -2618,6 +2695,7 @@ impl<'a> Parser<'a> { } i += 1; } + self.is_keyword_ahead(i, &[kw::Impl]) } diff --git a/tests/pretty/delegation-impl-reuse.pp b/tests/pretty/delegation-impl-reuse.pp new file mode 100644 index 000000000000..72f62de0eacb --- /dev/null +++ b/tests/pretty/delegation-impl-reuse.pp @@ -0,0 +1,46 @@ +#![feature(prelude_import)] +#![no_std] +//@ pretty-compare-only +//@ pretty-mode:expanded +//@ pp-exact:delegation-impl-reuse.pp + +#![allow(incomplete_features)] +#![feature(fn_delegation)] +#[macro_use] +extern crate std; +#[prelude_import] +use ::std::prelude::rust_2015::*; + +trait Trait { + fn foo(&self) {} + fn bar(&self) {} + fn baz(&self) {} +} + +struct S; + +impl Trait<{ + struct S; + 0 + }> for S { + reuse Trait<{ + struct S; + 0 + }>::foo { + self.0 + } + reuse Trait<{ + struct S; + 0 + }>::bar { + self.0 + } + reuse Trait<{ + struct S; + 0 + }>::baz { + self.0 + } +} + +fn main() {} diff --git a/tests/pretty/delegation-impl-reuse.rs b/tests/pretty/delegation-impl-reuse.rs new file mode 100644 index 000000000000..9265ea18a76f --- /dev/null +++ b/tests/pretty/delegation-impl-reuse.rs @@ -0,0 +1,18 @@ +//@ pretty-compare-only +//@ pretty-mode:expanded +//@ pp-exact:delegation-impl-reuse.pp + +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +trait Trait { + fn foo(&self) {} + fn bar(&self) {} + fn baz(&self) {} +} + +struct S; + +reuse impl Trait<{ struct S; 0 }> for S { self.0 } + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-bad-path.rs b/tests/ui/delegation/impl-reuse-bad-path.rs new file mode 100644 index 000000000000..19eb51153468 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-bad-path.rs @@ -0,0 +1,31 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +mod unresolved { + struct S; + reuse impl unresolved for S { self.0 } + //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `unresolved` + //~| ERROR cannot find trait `unresolved` in this scope + + trait T {} + reuse impl T for unresolved { self.0 } + //~^ ERROR empty glob delegation is not supported + //~| ERROR cannot find type `unresolved` in this scope +} + +mod wrong_entities { + trait T {} + struct Trait; + struct S; + + reuse impl Trait for S { self.0 } + //~^ ERROR expected trait, found struct `Trait` + //~| ERROR expected trait, found struct `Trait` + + mod TraitModule {} + reuse impl TraitModule for S { self.0 } + //~^ ERROR expected trait, found module `TraitModule` + //~| ERROR expected trait, found module `TraitModule` +} + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-bad-path.stderr b/tests/ui/delegation/impl-reuse-bad-path.stderr new file mode 100644 index 000000000000..5fadd719ae4d --- /dev/null +++ b/tests/ui/delegation/impl-reuse-bad-path.stderr @@ -0,0 +1,52 @@ +error: empty glob delegation is not supported + --> $DIR/impl-reuse-bad-path.rs:11:5 + | +LL | reuse impl T for unresolved { self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected trait, found struct `Trait` + --> $DIR/impl-reuse-bad-path.rs:21:16 + | +LL | reuse impl Trait for S { self.0 } + | ^^^^^ not a trait + +error: expected trait, found module `TraitModule` + --> $DIR/impl-reuse-bad-path.rs:26:16 + | +LL | reuse impl TraitModule for S { self.0 } + | ^^^^^^^^^^^ not a trait + +error[E0433]: failed to resolve: use of unresolved module or unlinked crate `unresolved` + --> $DIR/impl-reuse-bad-path.rs:6:16 + | +LL | reuse impl unresolved for S { self.0 } + | ^^^^^^^^^^ use of unresolved module or unlinked crate `unresolved` + +error[E0405]: cannot find trait `unresolved` in this scope + --> $DIR/impl-reuse-bad-path.rs:6:16 + | +LL | reuse impl unresolved for S { self.0 } + | ^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find type `unresolved` in this scope + --> $DIR/impl-reuse-bad-path.rs:11:22 + | +LL | reuse impl T for unresolved { self.0 } + | ^^^^^^^^^^ not found in this scope + +error[E0404]: expected trait, found struct `Trait` + --> $DIR/impl-reuse-bad-path.rs:21:16 + | +LL | reuse impl Trait for S { self.0 } + | ^^^^^ not a trait + +error[E0404]: expected trait, found module `TraitModule` + --> $DIR/impl-reuse-bad-path.rs:26:16 + | +LL | reuse impl TraitModule for S { self.0 } + | ^^^^^^^^^^^ not a trait + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0404, E0405, E0425, E0433. +For more information about an error, try `rustc --explain E0404`. diff --git a/tests/ui/delegation/impl-reuse-empty-glob.rs b/tests/ui/delegation/impl-reuse-empty-glob.rs new file mode 100644 index 000000000000..3f1314c47da6 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-empty-glob.rs @@ -0,0 +1,14 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +mod empty_glob { + trait T {} + + struct S; + + reuse impl T for S { self.0 } + //~^ ERROR empty glob delegation is not supported +} + + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-empty-glob.stderr b/tests/ui/delegation/impl-reuse-empty-glob.stderr new file mode 100644 index 000000000000..bf6bb5876351 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-empty-glob.stderr @@ -0,0 +1,8 @@ +error: empty glob delegation is not supported + --> $DIR/impl-reuse-empty-glob.rs:9:5 + | +LL | reuse impl T for S { self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/impl-reuse-illegal-places.rs b/tests/ui/delegation/impl-reuse-illegal-places.rs new file mode 100644 index 000000000000..361331d41315 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-illegal-places.rs @@ -0,0 +1,51 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +trait T { + fn f(&self) {} +} + +struct S; +impl T for S {} + +struct F(S); + +struct X { + reuse impl T for F { self.0 } + //~^ ERROR expected `:`, found keyword `impl` +} + +impl X { + reuse impl T for F { self.0 } + //~^ ERROR implementation is not supported in `trait`s or `impl`s +} + +trait Trait { + reuse impl T for F { self.0 } + //~^ ERROR implementation is not supported in `trait`s or `impl`s +} + +extern "C" { + reuse impl T for F { self.0 } + //~^ ERROR implementation is not supported in `extern` blocks +} + +mod m { + mod inner { + pub fn foo() {} + } + + reuse inner::{ + reuse impl T for F { self.0 } + //~^ ERROR expected identifier, found keyword `impl` + //~| ERROR expected one of `,`, `as`, or `}`, found keyword `impl` + //~| ERROR expected one of `,`, `as`, or `}`, found `T` + //~| ERROR expected identifier, found keyword `for` + //~| ERROR expected one of `,`, `as`, or `}`, found keyword `for` + //~| ERROR expected one of `,`, `as`, or `}`, found `F` + //~| ERROR expected one of `,`, `as`, or `}`, found `{` + } +} +//~^ ERROR expected item, found `}` + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-illegal-places.stderr b/tests/ui/delegation/impl-reuse-illegal-places.stderr new file mode 100644 index 000000000000..fb17ebdd6cee --- /dev/null +++ b/tests/ui/delegation/impl-reuse-illegal-places.stderr @@ -0,0 +1,92 @@ +error: expected `:`, found keyword `impl` + --> $DIR/impl-reuse-illegal-places.rs:14:11 + | +LL | struct X { + | - while parsing this struct +LL | reuse impl T for F { self.0 } + | ^^^^ expected `:` + +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/impl-reuse-illegal-places.rs:19:5 + | +LL | reuse impl T for F { self.0 } + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/impl-reuse-illegal-places.rs:24:5 + | +LL | reuse impl T for F { self.0 } + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: implementation is not supported in `extern` blocks + --> $DIR/impl-reuse-illegal-places.rs:29:5 + | +LL | reuse impl T for F { self.0 } + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: expected identifier, found keyword `impl` + --> $DIR/impl-reuse-illegal-places.rs:39:15 + | +LL | reuse impl T for F { self.0 } + | ^^^^ expected identifier, found keyword + +error: expected one of `,`, `as`, or `}`, found keyword `impl` + --> $DIR/impl-reuse-illegal-places.rs:39:15 + | +LL | reuse impl T for F { self.0 } + | -^^^^ expected one of `,`, `as`, or `}` + | | + | help: missing `,` + +error: expected one of `,`, `as`, or `}`, found `T` + --> $DIR/impl-reuse-illegal-places.rs:39:20 + | +LL | reuse impl T for F { self.0 } + | -^ expected one of `,`, `as`, or `}` + | | + | help: missing `,` + +error: expected identifier, found keyword `for` + --> $DIR/impl-reuse-illegal-places.rs:39:22 + | +LL | reuse impl T for F { self.0 } + | ^^^ expected identifier, found keyword + +error: expected one of `,`, `as`, or `}`, found keyword `for` + --> $DIR/impl-reuse-illegal-places.rs:39:22 + | +LL | reuse impl T for F { self.0 } + | -^^^ expected one of `,`, `as`, or `}` + | | + | help: missing `,` + +error: expected one of `,`, `as`, or `}`, found `F` + --> $DIR/impl-reuse-illegal-places.rs:39:26 + | +LL | reuse impl T for F { self.0 } + | -^ expected one of `,`, `as`, or `}` + | | + | help: missing `,` + +error: expected one of `,`, `as`, or `}`, found `{` + --> $DIR/impl-reuse-illegal-places.rs:39:28 + | +LL | reuse impl T for F { self.0 } + | ^ expected one of `,`, `as`, or `}` + +error: expected item, found `}` + --> $DIR/impl-reuse-illegal-places.rs:48:1 + | +LL | } + | ^ expected item + | + = note: for a full list of items that can appear in modules, see + +error: aborting due to 12 previous errors + diff --git a/tests/ui/delegation/impl-reuse-negative-traits.rs b/tests/ui/delegation/impl-reuse-negative-traits.rs new file mode 100644 index 000000000000..7bcbc82f03db --- /dev/null +++ b/tests/ui/delegation/impl-reuse-negative-traits.rs @@ -0,0 +1,19 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] +#![feature(negative_impls)] + +trait Trait { + fn foo(&self); + //~^ ERROR negative impls cannot have any items [E0749] +} + +struct S; +impl Trait for S { + fn foo(&self) {} +} + +struct F(S); + +reuse impl !Trait for F { &self.0 } + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-negative-traits.stderr b/tests/ui/delegation/impl-reuse-negative-traits.stderr new file mode 100644 index 000000000000..1be6ef715920 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-negative-traits.stderr @@ -0,0 +1,9 @@ +error[E0749]: negative impls cannot have any items + --> $DIR/impl-reuse-negative-traits.rs:6:8 + | +LL | fn foo(&self); + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0749`. diff --git a/tests/ui/delegation/impl-reuse-non-reuse-items.rs b/tests/ui/delegation/impl-reuse-non-reuse-items.rs new file mode 100644 index 000000000000..de7c92279218 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-reuse-items.rs @@ -0,0 +1,32 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +mod non_delegatable_items { + trait Trait { + fn method(&self); + const CONST: u8; + type Type; + #[allow(non_camel_case_types)] + type method; + } + + struct F; + impl Trait for F { + fn method(&self) {} + const CONST: u8 = 0; + type Type = u8; + type method = u8; + } + + struct S(F); + + reuse impl Trait for S { &self.0 } + //~^ ERROR item `CONST` is an associated method, which doesn't match its trait `Trait` + //~| ERROR item `Type` is an associated method, which doesn't match its trait `Trait` + //~| ERROR duplicate definitions with name `method` + //~| ERROR expected function, found associated constant `Trait::CONST` + //~| ERROR expected function, found associated type `Trait::Type` + //~| ERROR not all trait items implemented, missing: `CONST`, `Type`, `method` +} + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-non-reuse-items.stderr b/tests/ui/delegation/impl-reuse-non-reuse-items.stderr new file mode 100644 index 000000000000..9d6b0f638136 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-reuse-items.stderr @@ -0,0 +1,60 @@ +error[E0324]: item `CONST` is an associated method, which doesn't match its trait `Trait` + --> $DIR/impl-reuse-non-reuse-items.rs:23:5 + | +LL | const CONST: u8; + | ---------------- item in trait +... +LL | reuse impl Trait for S { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ does not match trait + +error[E0324]: item `Type` is an associated method, which doesn't match its trait `Trait` + --> $DIR/impl-reuse-non-reuse-items.rs:23:5 + | +LL | type Type; + | ---------- item in trait +... +LL | reuse impl Trait for S { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ does not match trait + +error[E0201]: duplicate definitions with name `method`: + --> $DIR/impl-reuse-non-reuse-items.rs:23:5 + | +LL | fn method(&self); + | ----------------- item in trait +... +LL | reuse impl Trait for S { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | duplicate definition + | previous definition here + +error[E0423]: expected function, found associated constant `Trait::CONST` + --> $DIR/impl-reuse-non-reuse-items.rs:23:16 + | +LL | reuse impl Trait for S { &self.0 } + | ^^^^^ not a function + +error[E0423]: expected function, found associated type `Trait::Type` + --> $DIR/impl-reuse-non-reuse-items.rs:23:16 + | +LL | reuse impl Trait for S { &self.0 } + | ^^^^^ not a function + +error[E0046]: not all trait items implemented, missing: `CONST`, `Type`, `method` + --> $DIR/impl-reuse-non-reuse-items.rs:23:5 + | +LL | const CONST: u8; + | --------------- `CONST` from trait +LL | type Type; + | --------- `Type` from trait +LL | #[allow(non_camel_case_types)] +LL | type method; + | ----------- `method` from trait +... +LL | reuse impl Trait for S { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^ missing `CONST`, `Type`, `method` in implementation + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0046, E0201, E0324, E0423. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.rs b/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.rs new file mode 100644 index 000000000000..51ef1dc14ba8 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.rs @@ -0,0 +1,10 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +struct Trait(usize); + +#[cfg(false)] +reuse impl Trait { self.0 } +//~^ ERROR only trait impls can be reused + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.stderr b/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.stderr new file mode 100644 index 000000000000..24a138016116 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.stderr @@ -0,0 +1,8 @@ +error: only trait impls can be reused + --> $DIR/impl-reuse-non-trait-impl-cfg-false.rs:7:1 + | +LL | reuse impl Trait { self.0 } + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/impl-reuse-non-trait-impl.rs b/tests/ui/delegation/impl-reuse-non-trait-impl.rs new file mode 100644 index 000000000000..c7a9813250db --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-trait-impl.rs @@ -0,0 +1,9 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +struct Trait(usize); + +reuse impl Trait { self.0 } +//~^ ERROR only trait impls can be reused + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-non-trait-impl.stderr b/tests/ui/delegation/impl-reuse-non-trait-impl.stderr new file mode 100644 index 000000000000..3987042104c3 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-trait-impl.stderr @@ -0,0 +1,8 @@ +error: only trait impls can be reused + --> $DIR/impl-reuse-non-trait-impl.rs:6:1 + | +LL | reuse impl Trait { self.0 } + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/impl-reuse-pass.rs b/tests/ui/delegation/impl-reuse-pass.rs new file mode 100644 index 000000000000..90060b03f9ef --- /dev/null +++ b/tests/ui/delegation/impl-reuse-pass.rs @@ -0,0 +1,292 @@ +//@ check-pass + +#![allow(incomplete_features)] +#![feature(fn_delegation)] +#![feature(const_trait_impl)] +#![allow(warnings)] + +mod default { + trait T { + fn foo(&self) {} + fn bar(&self) {} + fn goo(&self) {} + } + + struct S; + impl T for S {} + + struct F(S); + reuse impl T for F { self.0 } + + fn f() { + let f = F(S{}); + + f.foo(); + f.bar(); + f.goo(); + } +} + +mod dyn_traits { + trait T { + fn foo(&self) -> Box; + } + + trait SecondTrait { + fn bar(&self); + } + + reuse impl SecondTrait for dyn T { self.foo().as_ref() } +} + +mod complex_path { + pub mod first { + pub mod second { + pub trait T { + fn foo(&self, x: usize); + } + } + } + + struct S; + impl first::second::T for S { + fn foo(&self, x: usize) { } + } + + struct F(S); + reuse impl first::second::T for F { self.0 } + + fn f() { + use complex_path::first::second::T; + + let f = F(S{}); + + f.foo(1); + } +} + +mod no_body_reuse { + trait T { + fn foo(&self) {} + fn bar(&mut self) {} + } + + struct F; + + reuse impl T for F; + + fn foo() { + let mut f = F{}; + + f.foo(); + f.bar(); + } +} + +mod unsafe_trait { + unsafe trait UnsafeTrait { + fn foo(&self) {} + fn bar(&self) {} + fn goo(&self) {} + } + + struct S; + unsafe impl UnsafeTrait for S {} + + struct F(S); + reuse unsafe impl UnsafeTrait for F { self.0 } + + fn f() { + let f = F(S{}); + + f.foo(); + f.bar(); + f.goo(); + } +} + +mod const_trait { + const trait ConstTrait { + fn foo(&self) -> usize { 0 } + fn bar(&self) -> usize { 1 } + } + + struct S; + const impl ConstTrait for S {} + + struct F(S); + reuse const impl ConstTrait for F { self.0 } + + fn f() { + let f = F(S{}); + + f.foo(); + f.bar(); + } +} + +mod different_selves { + trait T: Sized { + fn foo(&self) {} + fn boo(self) {} + fn goo(&mut self) {} + } + + struct S; + impl T for S {} + + struct F(S); + reuse impl T for F { self.0 } + + struct D(S); + macro_rules! self_0 { ($self:ident) => { $self.0 } } + + reuse impl T for D { self_0!(self) } + + fn f() { + let mut f = F(S{}); + f.foo(); + f.goo(); + f.boo(); + + let mut d = D(S{}); + d.foo(); + d.goo(); + d.boo(); + } +} + +mod macros { + trait Trait { + fn foo(&self) -> u8 { 0 } + fn bar(&self) -> u8 { 1 } + } + + impl Trait for u8 {} + struct S(u8); + + macro_rules! self_0_ref { ($self:ident) => { &$self.0 } } + + reuse impl Trait for S { self_0_ref!(self) } + + struct M(u8); + macro_rules! m { () => { M } } + reuse impl Trait for m!() { self_0_ref!(self) } + + struct S1(u8); + macro_rules! one_line_reuse { ($self:ident) => { reuse impl Trait for S1 { $self.0 } } } + one_line_reuse!(self); + + struct S2(u8); + macro_rules! one_line_reuse_expr { ($x:expr) => { reuse impl Trait for S2 { $x } } } + one_line_reuse_expr!(self.0); + + struct S3(u8); + macro_rules! s3 { () => { S3 } } + macro_rules! one_line_reuse_expr2 { ($x:expr) => { reuse impl Trait for s3!() { $x } } } + one_line_reuse_expr2!(self.0); + + fn f() { + let s = S(1); + s.foo(); + s.bar(); + + let m = M(41); + m.foo(); + m.bar(); + + let s1 = S1(2); + s1.foo(); + s1.bar(); + + let s2 = S2(4); + s2.foo(); + s2.bar(); + + let s3 = S3(5); + s3.foo(); + s3.bar(); + } +} + +mod generics { + trait Trait<'a, 'b, A, B, C> { + fn foo(&self, a: &A) {} + fn bar(&self, b: &B) {} + fn goo(&self, c: &C) {} + } + + struct S; + impl<'a, 'b, A, B, C> Trait<'a, 'b, A, B, C> for S {} + + struct F(S); + reuse impl<'a, 'b, A, B, C> Trait<'a, 'b, A, B, C> for F { &self.0 } + + struct S1; + struct F1(S1); + impl<'c, B> Trait<'static, 'c, usize, B, String> for S1 {} + reuse impl<'d, B> Trait<'static, 'd, usize, B, String> for F1 { &self.0 } + + struct S2; + struct F2(S2); + impl Trait<'static, 'static, u8, u16, u32> for S2 {} + reuse impl Trait<'static, 'static, u8, u16, u32> for F2 { &self.0 } + + fn f<'a, 'b, 'c, A, B, C>(a: A, b: B, c: C) { + let f = F(S{}); + + >::foo(&f, &a); + >::bar(&f, &b); + >::goo(&f, &c); + + let f = F1(S1{}); + >::foo(&f, &123); + >::bar(&f, &b); + >::goo(&f, &"s".to_string()); + + let f = F2(S2{}); + >::foo(&f, &1); + >::bar(&f, &2); + >::goo(&f, &3); + } +} + +mod reuse_in_different_places { + trait T { + fn foo(&self, x: usize) {} + } + + struct S; + impl T for S {} + + struct F1(S); + reuse impl T for F1 { + struct F2(S, S, S); + reuse impl T for F2 { self.1 } + + let f2 = F2(S{}, S{}, S{}); + f2.foo(123); + + &self.0 + } + + fn foo() { + struct F(S); + reuse impl T for F { self.0 } + + let f = F(S{}); + f.foo(1); + } + + fn bar() { + || { + struct F(S); + reuse impl T for F { self.0 } + + let f = F(S{}); + f.foo(1); + }; + } +} + +fn main() {} From f289ccf207ede543f23d5998bf5ee6a0b793bdf2 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Mon, 22 Dec 2025 23:49:11 -0800 Subject: [PATCH 1173/3801] `target_features::Stability`: tweak docs of `requires_nightly()` * No method named `allow_toggle()` exists on the type, but based on the documentation of both `requires_nightly()` and `toggle_allowed()` it seems that `toggle_allowed()` is the intended method to mention. * Add `()` to the mention of `in_cfg()` to make it clear that a method is being referred to, and to match the presence of `()` in the mention of `toggle_allowed()`. --- compiler/rustc_target/src/target_features.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 35cfeba2bffd..85c473c5abb2 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -62,8 +62,8 @@ impl Stability { /// the feature gate to actually be enabled when using a nightly compiler.) /// /// Before calling this, ensure the feature is even permitted for this use: - /// - for `#[target_feature]`/`-Ctarget-feature`, check `allow_toggle()` - /// - for `cfg(target_feature)`, check `in_cfg` + /// - for `#[target_feature]`/`-Ctarget-feature`, check `toggle_allowed()` + /// - for `cfg(target_feature)`, check `in_cfg()` pub fn requires_nightly(&self) -> Option { match *self { Stability::Unstable(nightly_feature) => Some(nightly_feature), From 01c23c67be4d11e09d434de31a07c34d962eb980 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 15 Dec 2025 14:20:35 +0000 Subject: [PATCH 1174/3801] several `proc_macro` cleanups --- library/proc_macro/src/bridge/symbol.rs | 5 +---- library/proc_macro/src/escape.rs | 3 +-- library/proc_macro/src/lib.rs | 9 +++------ 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs index 0d6a725fddd9..e070ec07681d 100644 --- a/library/proc_macro/src/bridge/symbol.rs +++ b/library/proc_macro/src/bridge/symbol.rs @@ -77,10 +77,7 @@ impl Symbol { // Mimics the behavior of `Symbol::can_be_raw` from `rustc_span` fn can_be_raw(string: &str) -> bool { - match string { - "_" | "super" | "self" | "Self" | "crate" | "$crate" => false, - _ => true, - } + !matches!(string, "_" | "super" | "self" | "Self" | "crate" | "$crate") } } diff --git a/library/proc_macro/src/escape.rs b/library/proc_macro/src/escape.rs index 87a4d1d50fd4..1f11a6633ff1 100644 --- a/library/proc_macro/src/escape.rs +++ b/library/proc_macro/src/escape.rs @@ -17,8 +17,7 @@ pub(crate) fn escape_bytes(bytes: &[u8], opt: EscapeOptions) -> String { escape_single_byte(byte, opt, &mut repr); } } else { - let mut chunks = bytes.utf8_chunks(); - while let Some(chunk) = chunks.next() { + for chunk in bytes.utf8_chunks() { for ch in chunk.valid().chars() { escape_single_char(ch, opt, &mut repr); } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index a0b6656c8ded..735986683d11 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -3,7 +3,7 @@ //! This library, provided by the standard distribution, provides the types //! consumed in the interfaces of procedurally defined macro definitions such as //! function-like macros `#[proc_macro]`, macro attributes `#[proc_macro_attribute]` and -//! custom derive attributes`#[proc_macro_derive]`. +//! custom derive attributes `#[proc_macro_derive]`. //! //! See [the book] for more. //! @@ -210,7 +210,6 @@ impl FromStr for TokenStream { /// `TokenTree::Punct`, or `TokenTree::Literal`. #[stable(feature = "proc_macro_lib", since = "1.15.0")] impl fmt::Display for TokenStream { - #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.0 { Some(ts) => write!(f, "{}", ts.to_string()), @@ -219,7 +218,7 @@ impl fmt::Display for TokenStream { } } -/// Prints token in a form convenient for debugging. +/// Prints tokens in a form convenient for debugging. #[stable(feature = "proc_macro_lib", since = "1.15.0")] impl fmt::Debug for TokenStream { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -571,7 +570,7 @@ impl Span { /// This path should not be embedded in the output of the macro; prefer `file()` instead. #[stable(feature = "proc_macro_span_file", since = "1.88.0")] pub fn local_file(&self) -> Option { - self.0.local_file().map(|s| PathBuf::from(s)) + self.0.local_file().map(PathBuf::from) } /// Creates a new span encompassing `self` and `other`. @@ -750,7 +749,6 @@ impl From for TokenTree { /// `TokenTree::Punct`, or `TokenTree::Literal`. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Display for TokenTree { - #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { TokenTree::Group(t) => write!(f, "{t}"), @@ -888,7 +886,6 @@ impl Group { /// with `Delimiter::None` delimiters. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl fmt::Display for Group { - #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", TokenStream::from(TokenTree::from(self.clone()))) } From 82499bac52fe6367b0da4a161d6cc9b6b49d2cc4 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Tue, 23 Dec 2025 10:06:02 +0000 Subject: [PATCH 1175/3801] Correct terminology in Clone --- library/core/src/clone.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index bf8875098edf..e3d4b5c3331c 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -52,12 +52,12 @@ mod uninit; /// original. /// /// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while -/// `Clone` is always explicit and may or may not be expensive. In order to enforce -/// these characteristics, Rust does not allow you to reimplement [`Copy`], but you -/// may reimplement `Clone` and run arbitrary code. +/// `Clone` is always explicit and may or may not be expensive. [`Copy`] has no methods, so you +/// cannot change its behavior, but when implementing `Clone`, the `clone` method you provide +/// may run arbitrary code. /// -/// Since `Clone` is more general than [`Copy`], you can automatically make anything -/// [`Copy`] be `Clone` as well. +/// Since `Clone` is a supertrait of [`Copy`], any type that implements `Copy` must also implement +/// `Clone`. /// /// ## Derivable /// From 7ca2eb9c6f67e694cfc7d762f722c3a510fe59b0 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sat, 20 Dec 2025 23:37:09 +0900 Subject: [PATCH 1176/3801] moved test --- .../issue-50581.rs => array-slice-vec/array-break-length-2.rs} | 0 .../array-break-length-2.stderr} | 0 .../issue-36400.rs => borrowck/borrow-immutable-deref-box.rs} | 0 .../borrow-immutable-deref-box.stderr} | 0 .../issue-18423.rs => box/box-lifetime-argument-not-allowed.rs} | 0 .../box-lifetime-argument-not-allowed.stderr} | 0 .../cast-rfc0401.rs => cast/cast-rfc0401-fail.rs} | 0 .../cast-rfc0401.stderr => cast/cast-rfc0401-fail.stderr} | 0 tests/ui/{issues/issue-22289.rs => cast/cast-to-dyn-any.rs} | 0 .../ui/{issues/issue-22289.stderr => cast/cast-to-dyn-any.stderr} | 0 .../closure-array-break-length-2.rs} | 0 .../closure-array-break-length-2.stderr} | 0 .../closure-move-use-after-move-diagnostic.rs} | 0 .../closure-move-use-after-move-diagnostic.stderr} | 0 .../{issues/issue-38458.rs => consts/const-return-outside-fn.rs} | 0 .../issue-38458.stderr => consts/const-return-outside-fn.stderr} | 0 .../ui/{issues/issue-28568.rs => drop/drop-conflicting-impls.rs} | 0 .../issue-28568.stderr => drop/drop-conflicting-impls.stderr} | 0 .../issue-23217.rs => enum/enum-discriminant-missing-variant.rs} | 0 .../enum-discriminant-missing-variant.stderr} | 0 .../{issues/issue-21554.rs => mismatched_types/cast-rfc0401-2.rs} | 0 .../issue-21554.stderr => mismatched_types/cast-rfc0401-2.stderr} | 0 .../issue-47184.rs => nll/borrowck-annotate-static-lifetime.rs} | 0 .../borrowck-annotate-static-lifetime.stderr} | 0 tests/ui/{issues/issue-46983.rs => nll/nll-anon-to-static.rs} | 0 .../{issues/issue-46983.stderr => nll/nll-anon-to-static.stderr} | 0 .../issue-45965.rs => parser/missing-operator-after-float.rs} | 0 .../missing-operator-after-float.stderr} | 0 .../{issues/issue-44078.rs => parser/unbalanced-doublequote-2.rs} | 0 .../issue-44078.stderr => parser/unbalanced-doublequote-2.stderr} | 0 .../issue-23173.rs => resolve/missing-associated-items.rs} | 0 .../missing-associated-items.stderr} | 0 tests/ui/{issues/issue-50582.rs => typeck/for-in-const-eval.rs} | 0 .../issue-50582.stderr => typeck/for-in-const-eval.stderr} | 0 34 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-50581.rs => array-slice-vec/array-break-length-2.rs} (100%) rename tests/ui/{issues/issue-50581.stderr => array-slice-vec/array-break-length-2.stderr} (100%) rename tests/ui/{issues/issue-36400.rs => borrowck/borrow-immutable-deref-box.rs} (100%) rename tests/ui/{issues/issue-36400.stderr => borrowck/borrow-immutable-deref-box.stderr} (100%) rename tests/ui/{issues/issue-18423.rs => box/box-lifetime-argument-not-allowed.rs} (100%) rename tests/ui/{issues/issue-18423.stderr => box/box-lifetime-argument-not-allowed.stderr} (100%) rename tests/ui/{mismatched_types/cast-rfc0401.rs => cast/cast-rfc0401-fail.rs} (100%) rename tests/ui/{mismatched_types/cast-rfc0401.stderr => cast/cast-rfc0401-fail.stderr} (100%) rename tests/ui/{issues/issue-22289.rs => cast/cast-to-dyn-any.rs} (100%) rename tests/ui/{issues/issue-22289.stderr => cast/cast-to-dyn-any.stderr} (100%) rename tests/ui/{array-slice-vec/array-break-length.rs => closures/closure-array-break-length-2.rs} (100%) rename tests/ui/{array-slice-vec/array-break-length.stderr => closures/closure-array-break-length-2.stderr} (100%) rename tests/ui/{issues/issue-24357.rs => closures/closure-move-use-after-move-diagnostic.rs} (100%) rename tests/ui/{issues/issue-24357.stderr => closures/closure-move-use-after-move-diagnostic.stderr} (100%) rename tests/ui/{issues/issue-38458.rs => consts/const-return-outside-fn.rs} (100%) rename tests/ui/{issues/issue-38458.stderr => consts/const-return-outside-fn.stderr} (100%) rename tests/ui/{issues/issue-28568.rs => drop/drop-conflicting-impls.rs} (100%) rename tests/ui/{issues/issue-28568.stderr => drop/drop-conflicting-impls.stderr} (100%) rename tests/ui/{issues/issue-23217.rs => enum/enum-discriminant-missing-variant.rs} (100%) rename tests/ui/{issues/issue-23217.stderr => enum/enum-discriminant-missing-variant.stderr} (100%) rename tests/ui/{issues/issue-21554.rs => mismatched_types/cast-rfc0401-2.rs} (100%) rename tests/ui/{issues/issue-21554.stderr => mismatched_types/cast-rfc0401-2.stderr} (100%) rename tests/ui/{issues/issue-47184.rs => nll/borrowck-annotate-static-lifetime.rs} (100%) rename tests/ui/{issues/issue-47184.stderr => nll/borrowck-annotate-static-lifetime.stderr} (100%) rename tests/ui/{issues/issue-46983.rs => nll/nll-anon-to-static.rs} (100%) rename tests/ui/{issues/issue-46983.stderr => nll/nll-anon-to-static.stderr} (100%) rename tests/ui/{issues/issue-45965.rs => parser/missing-operator-after-float.rs} (100%) rename tests/ui/{issues/issue-45965.stderr => parser/missing-operator-after-float.stderr} (100%) rename tests/ui/{issues/issue-44078.rs => parser/unbalanced-doublequote-2.rs} (100%) rename tests/ui/{issues/issue-44078.stderr => parser/unbalanced-doublequote-2.stderr} (100%) rename tests/ui/{issues/issue-23173.rs => resolve/missing-associated-items.rs} (100%) rename tests/ui/{issues/issue-23173.stderr => resolve/missing-associated-items.stderr} (100%) rename tests/ui/{issues/issue-50582.rs => typeck/for-in-const-eval.rs} (100%) rename tests/ui/{issues/issue-50582.stderr => typeck/for-in-const-eval.stderr} (100%) diff --git a/tests/ui/issues/issue-50581.rs b/tests/ui/array-slice-vec/array-break-length-2.rs similarity index 100% rename from tests/ui/issues/issue-50581.rs rename to tests/ui/array-slice-vec/array-break-length-2.rs diff --git a/tests/ui/issues/issue-50581.stderr b/tests/ui/array-slice-vec/array-break-length-2.stderr similarity index 100% rename from tests/ui/issues/issue-50581.stderr rename to tests/ui/array-slice-vec/array-break-length-2.stderr diff --git a/tests/ui/issues/issue-36400.rs b/tests/ui/borrowck/borrow-immutable-deref-box.rs similarity index 100% rename from tests/ui/issues/issue-36400.rs rename to tests/ui/borrowck/borrow-immutable-deref-box.rs diff --git a/tests/ui/issues/issue-36400.stderr b/tests/ui/borrowck/borrow-immutable-deref-box.stderr similarity index 100% rename from tests/ui/issues/issue-36400.stderr rename to tests/ui/borrowck/borrow-immutable-deref-box.stderr diff --git a/tests/ui/issues/issue-18423.rs b/tests/ui/box/box-lifetime-argument-not-allowed.rs similarity index 100% rename from tests/ui/issues/issue-18423.rs rename to tests/ui/box/box-lifetime-argument-not-allowed.rs diff --git a/tests/ui/issues/issue-18423.stderr b/tests/ui/box/box-lifetime-argument-not-allowed.stderr similarity index 100% rename from tests/ui/issues/issue-18423.stderr rename to tests/ui/box/box-lifetime-argument-not-allowed.stderr diff --git a/tests/ui/mismatched_types/cast-rfc0401.rs b/tests/ui/cast/cast-rfc0401-fail.rs similarity index 100% rename from tests/ui/mismatched_types/cast-rfc0401.rs rename to tests/ui/cast/cast-rfc0401-fail.rs diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/cast/cast-rfc0401-fail.stderr similarity index 100% rename from tests/ui/mismatched_types/cast-rfc0401.stderr rename to tests/ui/cast/cast-rfc0401-fail.stderr diff --git a/tests/ui/issues/issue-22289.rs b/tests/ui/cast/cast-to-dyn-any.rs similarity index 100% rename from tests/ui/issues/issue-22289.rs rename to tests/ui/cast/cast-to-dyn-any.rs diff --git a/tests/ui/issues/issue-22289.stderr b/tests/ui/cast/cast-to-dyn-any.stderr similarity index 100% rename from tests/ui/issues/issue-22289.stderr rename to tests/ui/cast/cast-to-dyn-any.stderr diff --git a/tests/ui/array-slice-vec/array-break-length.rs b/tests/ui/closures/closure-array-break-length-2.rs similarity index 100% rename from tests/ui/array-slice-vec/array-break-length.rs rename to tests/ui/closures/closure-array-break-length-2.rs diff --git a/tests/ui/array-slice-vec/array-break-length.stderr b/tests/ui/closures/closure-array-break-length-2.stderr similarity index 100% rename from tests/ui/array-slice-vec/array-break-length.stderr rename to tests/ui/closures/closure-array-break-length-2.stderr diff --git a/tests/ui/issues/issue-24357.rs b/tests/ui/closures/closure-move-use-after-move-diagnostic.rs similarity index 100% rename from tests/ui/issues/issue-24357.rs rename to tests/ui/closures/closure-move-use-after-move-diagnostic.rs diff --git a/tests/ui/issues/issue-24357.stderr b/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr similarity index 100% rename from tests/ui/issues/issue-24357.stderr rename to tests/ui/closures/closure-move-use-after-move-diagnostic.stderr diff --git a/tests/ui/issues/issue-38458.rs b/tests/ui/consts/const-return-outside-fn.rs similarity index 100% rename from tests/ui/issues/issue-38458.rs rename to tests/ui/consts/const-return-outside-fn.rs diff --git a/tests/ui/issues/issue-38458.stderr b/tests/ui/consts/const-return-outside-fn.stderr similarity index 100% rename from tests/ui/issues/issue-38458.stderr rename to tests/ui/consts/const-return-outside-fn.stderr diff --git a/tests/ui/issues/issue-28568.rs b/tests/ui/drop/drop-conflicting-impls.rs similarity index 100% rename from tests/ui/issues/issue-28568.rs rename to tests/ui/drop/drop-conflicting-impls.rs diff --git a/tests/ui/issues/issue-28568.stderr b/tests/ui/drop/drop-conflicting-impls.stderr similarity index 100% rename from tests/ui/issues/issue-28568.stderr rename to tests/ui/drop/drop-conflicting-impls.stderr diff --git a/tests/ui/issues/issue-23217.rs b/tests/ui/enum/enum-discriminant-missing-variant.rs similarity index 100% rename from tests/ui/issues/issue-23217.rs rename to tests/ui/enum/enum-discriminant-missing-variant.rs diff --git a/tests/ui/issues/issue-23217.stderr b/tests/ui/enum/enum-discriminant-missing-variant.stderr similarity index 100% rename from tests/ui/issues/issue-23217.stderr rename to tests/ui/enum/enum-discriminant-missing-variant.stderr diff --git a/tests/ui/issues/issue-21554.rs b/tests/ui/mismatched_types/cast-rfc0401-2.rs similarity index 100% rename from tests/ui/issues/issue-21554.rs rename to tests/ui/mismatched_types/cast-rfc0401-2.rs diff --git a/tests/ui/issues/issue-21554.stderr b/tests/ui/mismatched_types/cast-rfc0401-2.stderr similarity index 100% rename from tests/ui/issues/issue-21554.stderr rename to tests/ui/mismatched_types/cast-rfc0401-2.stderr diff --git a/tests/ui/issues/issue-47184.rs b/tests/ui/nll/borrowck-annotate-static-lifetime.rs similarity index 100% rename from tests/ui/issues/issue-47184.rs rename to tests/ui/nll/borrowck-annotate-static-lifetime.rs diff --git a/tests/ui/issues/issue-47184.stderr b/tests/ui/nll/borrowck-annotate-static-lifetime.stderr similarity index 100% rename from tests/ui/issues/issue-47184.stderr rename to tests/ui/nll/borrowck-annotate-static-lifetime.stderr diff --git a/tests/ui/issues/issue-46983.rs b/tests/ui/nll/nll-anon-to-static.rs similarity index 100% rename from tests/ui/issues/issue-46983.rs rename to tests/ui/nll/nll-anon-to-static.rs diff --git a/tests/ui/issues/issue-46983.stderr b/tests/ui/nll/nll-anon-to-static.stderr similarity index 100% rename from tests/ui/issues/issue-46983.stderr rename to tests/ui/nll/nll-anon-to-static.stderr diff --git a/tests/ui/issues/issue-45965.rs b/tests/ui/parser/missing-operator-after-float.rs similarity index 100% rename from tests/ui/issues/issue-45965.rs rename to tests/ui/parser/missing-operator-after-float.rs diff --git a/tests/ui/issues/issue-45965.stderr b/tests/ui/parser/missing-operator-after-float.stderr similarity index 100% rename from tests/ui/issues/issue-45965.stderr rename to tests/ui/parser/missing-operator-after-float.stderr diff --git a/tests/ui/issues/issue-44078.rs b/tests/ui/parser/unbalanced-doublequote-2.rs similarity index 100% rename from tests/ui/issues/issue-44078.rs rename to tests/ui/parser/unbalanced-doublequote-2.rs diff --git a/tests/ui/issues/issue-44078.stderr b/tests/ui/parser/unbalanced-doublequote-2.stderr similarity index 100% rename from tests/ui/issues/issue-44078.stderr rename to tests/ui/parser/unbalanced-doublequote-2.stderr diff --git a/tests/ui/issues/issue-23173.rs b/tests/ui/resolve/missing-associated-items.rs similarity index 100% rename from tests/ui/issues/issue-23173.rs rename to tests/ui/resolve/missing-associated-items.rs diff --git a/tests/ui/issues/issue-23173.stderr b/tests/ui/resolve/missing-associated-items.stderr similarity index 100% rename from tests/ui/issues/issue-23173.stderr rename to tests/ui/resolve/missing-associated-items.stderr diff --git a/tests/ui/issues/issue-50582.rs b/tests/ui/typeck/for-in-const-eval.rs similarity index 100% rename from tests/ui/issues/issue-50582.rs rename to tests/ui/typeck/for-in-const-eval.rs diff --git a/tests/ui/issues/issue-50582.stderr b/tests/ui/typeck/for-in-const-eval.stderr similarity index 100% rename from tests/ui/issues/issue-50582.stderr rename to tests/ui/typeck/for-in-const-eval.stderr From 4578082361406cdf6836301c127534f1a2317135 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sun, 21 Dec 2025 09:13:49 +0900 Subject: [PATCH 1177/3801] Cleaned up some tests add comment to closure-move-use-after-move-diagnostic.rs add comment to missing-operator-after-float.rs add comment to closure-array-break-length.rs add comment to box-lifetime-argument-not-allowed.rs add comment to const-return-outside-fn.rs add comment to drop-conflicting-impls.rs add comment to unbalanced-doublequote-2.rs add comment to borrow-immutable-deref-box.rs add comment to for-in-const-eval.rs add comment to borrowck-annotated-static-lifetime.rs cleaned up cast-rfc0401.rs add comment to nll-anon-to-static.rs add comment to cast-to-dyn-any.rs add comment to missing-associated-items.rs add comment to enum-discriminant-missing-variant.rs --- .../array-slice-vec/array-break-length-2.rs | 3 - .../array-break-length-2.stderr | 9 --- .../ui/borrowck/borrow-immutable-deref-box.rs | 1 + .../borrow-immutable-deref-box.stderr | 2 +- .../box/box-lifetime-argument-not-allowed.rs | 7 +- .../box-lifetime-argument-not-allowed.stderr | 4 +- tests/ui/cast/cast-rfc0401-2.rs | 8 -- tests/ui/cast/cast-rfc0401-2.stderr | 15 ---- tests/ui/cast/cast-rfc0401-fail.rs | 29 ++++--- tests/ui/cast/cast-rfc0401-fail.stderr | 76 ++++++++++--------- tests/ui/cast/cast-to-dyn-any.rs | 1 + tests/ui/cast/cast-to-dyn-any.stderr | 2 +- .../closures/closure-array-break-length-2.rs | 9 --- .../closure-array-break-length-2.stderr | 15 ---- .../ui/closures/closure-array-break-length.rs | 11 +++ .../closure-array-break-length.stderr | 26 ++++++- .../closure-move-use-after-move-diagnostic.rs | 21 ++--- ...sure-move-use-after-move-diagnostic.stderr | 25 +++--- tests/ui/consts/const-return-outside-fn.rs | 1 + .../ui/consts/const-return-outside-fn.stderr | 2 +- tests/ui/drop/drop-conflicting-impls.rs | 7 +- tests/ui/drop/drop-conflicting-impls.stderr | 2 +- .../enum/enum-discriminant-missing-variant.rs | 1 + .../enum-discriminant-missing-variant.stderr | 2 +- tests/ui/mismatched_types/cast-rfc0401-2.rs | 6 -- .../ui/mismatched_types/cast-rfc0401-2.stderr | 9 --- .../nll/borrowck-annotate-static-lifetime.rs | 1 + .../borrowck-annotate-static-lifetime.stderr | 2 +- tests/ui/nll/nll-anon-to-static.rs | 1 + tests/ui/nll/nll-anon-to-static.stderr | 2 +- .../ui/parser/missing-operator-after-float.rs | 1 + .../missing-operator-after-float.stderr | 2 +- tests/ui/parser/unbalanced-doublequote-2.rs | 1 + .../ui/parser/unbalanced-doublequote-2.stderr | 2 +- tests/ui/resolve/missing-associated-items.rs | 12 ++- .../resolve/missing-associated-items.stderr | 10 +-- tests/ui/typeck/for-in-const-eval.rs | 1 + tests/ui/typeck/for-in-const-eval.stderr | 2 +- 38 files changed, 160 insertions(+), 171 deletions(-) delete mode 100644 tests/ui/array-slice-vec/array-break-length-2.rs delete mode 100644 tests/ui/array-slice-vec/array-break-length-2.stderr delete mode 100644 tests/ui/cast/cast-rfc0401-2.rs delete mode 100644 tests/ui/cast/cast-rfc0401-2.stderr delete mode 100644 tests/ui/closures/closure-array-break-length-2.rs delete mode 100644 tests/ui/closures/closure-array-break-length-2.stderr delete mode 100644 tests/ui/mismatched_types/cast-rfc0401-2.rs delete mode 100644 tests/ui/mismatched_types/cast-rfc0401-2.stderr diff --git a/tests/ui/array-slice-vec/array-break-length-2.rs b/tests/ui/array-slice-vec/array-break-length-2.rs deleted file mode 100644 index 12bb9930eca4..000000000000 --- a/tests/ui/array-slice-vec/array-break-length-2.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - |_: [u8; break]| (); //~ ERROR [E0268] -} diff --git a/tests/ui/array-slice-vec/array-break-length-2.stderr b/tests/ui/array-slice-vec/array-break-length-2.stderr deleted file mode 100644 index bac1ade3b0c8..000000000000 --- a/tests/ui/array-slice-vec/array-break-length-2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/issue-50581.rs:2:14 - | -LL | |_: [u8; break]| (); - | ^^^^^ cannot `break` outside of a loop or labeled block - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/borrowck/borrow-immutable-deref-box.rs b/tests/ui/borrowck/borrow-immutable-deref-box.rs index a405f9b11352..6d4932b5b4b5 100644 --- a/tests/ui/borrowck/borrow-immutable-deref-box.rs +++ b/tests/ui/borrowck/borrow-immutable-deref-box.rs @@ -1,3 +1,4 @@ +//! regression test for issue fn f(x: &mut u32) {} fn main() { diff --git a/tests/ui/borrowck/borrow-immutable-deref-box.stderr b/tests/ui/borrowck/borrow-immutable-deref-box.stderr index 522fb36e1434..6456dc8a0e5a 100644 --- a/tests/ui/borrowck/borrow-immutable-deref-box.stderr +++ b/tests/ui/borrowck/borrow-immutable-deref-box.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable - --> $DIR/issue-36400.rs:5:7 + --> $DIR/borrow-immutable-deref-box.rs:6:7 | LL | f(&mut *x); | ^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/box/box-lifetime-argument-not-allowed.rs b/tests/ui/box/box-lifetime-argument-not-allowed.rs index 675fd041154b..647fe0917d0a 100644 --- a/tests/ui/box/box-lifetime-argument-not-allowed.rs +++ b/tests/ui/box/box-lifetime-argument-not-allowed.rs @@ -1,8 +1,9 @@ -// Test that `Box` cannot be used with a lifetime argument. +//! Test that `Box` cannot be used with a lifetime argument. +//! regression test for issue struct Foo<'a> { - x: Box<'a, isize> + x: Box<'a, isize>, //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied } -fn main() { } +fn main() {} diff --git a/tests/ui/box/box-lifetime-argument-not-allowed.stderr b/tests/ui/box/box-lifetime-argument-not-allowed.stderr index b5f19b5c9b23..a597a03023af 100644 --- a/tests/ui/box/box-lifetime-argument-not-allowed.stderr +++ b/tests/ui/box/box-lifetime-argument-not-allowed.stderr @@ -1,7 +1,7 @@ error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/issue-18423.rs:4:8 + --> $DIR/box-lifetime-argument-not-allowed.rs:5:8 | -LL | x: Box<'a, isize> +LL | x: Box<'a, isize>, | ^^^ -- help: remove the lifetime argument | | | expected 0 lifetime arguments diff --git a/tests/ui/cast/cast-rfc0401-2.rs b/tests/ui/cast/cast-rfc0401-2.rs deleted file mode 100644 index 70604a587ea1..000000000000 --- a/tests/ui/cast/cast-rfc0401-2.rs +++ /dev/null @@ -1,8 +0,0 @@ -// RFC 401 test extracted into distinct file. This is because some the -// change to suppress "derived" errors wound up suppressing this error -// message, since the fallback for `3` doesn't occur. - -fn main() { - let _ = 3 as bool; - //~^ ERROR cannot cast `i32` as `bool` -} diff --git a/tests/ui/cast/cast-rfc0401-2.stderr b/tests/ui/cast/cast-rfc0401-2.stderr deleted file mode 100644 index f2956cdfa335..000000000000 --- a/tests/ui/cast/cast-rfc0401-2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0054]: cannot cast `i32` as `bool` - --> $DIR/cast-rfc0401-2.rs:6:13 - | -LL | let _ = 3 as bool; - | ^^^^^^^^^ - | -help: compare with zero instead - | -LL - let _ = 3 as bool; -LL + let _ = 3 != 0; - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0054`. diff --git a/tests/ui/cast/cast-rfc0401-fail.rs b/tests/ui/cast/cast-rfc0401-fail.rs index b2ff5b4a0c06..fb04e3f5f9a0 100644 --- a/tests/ui/cast/cast-rfc0401-fail.rs +++ b/tests/ui/cast/cast-rfc0401-fail.rs @@ -1,29 +1,33 @@ -fn illegal_cast(u: *const U) -> *const V -{ +fn illegal_cast(u: *const U) -> *const V { u as *const V //~ ERROR is invalid } -fn illegal_cast_2(u: *const U) -> *const str -{ +fn illegal_cast_2(u: *const U) -> *const str { u as *const str //~ ERROR is invalid } -trait Foo { fn foo(&self) {} } +trait Foo { + fn foo(&self) {} +} impl Foo for T {} -trait Bar { fn foo(&self) {} } +trait Bar { + fn foo(&self) {} +} impl Bar for T {} enum E { - A, B + A, + B, } -fn main() -{ +struct Inches(i32); + +fn main() { let f: f32 = 1.2; let v = core::ptr::null::(); - let fat_v : *const [u8] = unsafe { &*core::ptr::null::<[u8; 1]>()}; - let fat_sv : *const [i8] = unsafe { &*core::ptr::null::<[i8; 1]>()}; + let fat_v: *const [u8] = unsafe { &*core::ptr::null::<[u8; 1]>() }; + let fat_sv: *const [i8] = unsafe { &*core::ptr::null::<[i8; 1]>() }; let foo: &dyn Foo = &f; let _ = v as &u8; //~ ERROR non-primitive cast @@ -39,6 +43,7 @@ fn main() let _ = 3_i32 as bool; //~ ERROR cannot cast let _ = E::A as bool; //~ ERROR cannot cast let _ = 0x61u32 as char; //~ ERROR can be cast as + let _ = Inches as f32; //~ ERROR is invalid let _ = false as f32; //~ ERROR is invalid let _ = E::A as f32; //~ ERROR is invalid @@ -58,7 +63,7 @@ fn main() let _ = &f as *const f64; //~ ERROR is invalid let _ = fat_sv as usize; //~ ERROR is invalid - let a : *const str = "hello"; + let a: *const str = "hello"; let _ = a as *const dyn Foo; //~ ERROR the size for values of type // check no error cascade diff --git a/tests/ui/cast/cast-rfc0401-fail.stderr b/tests/ui/cast/cast-rfc0401-fail.stderr index a188b7791fdc..c41e6e3612dd 100644 --- a/tests/ui/cast/cast-rfc0401-fail.stderr +++ b/tests/ui/cast/cast-rfc0401-fail.stderr @@ -1,5 +1,5 @@ error[E0606]: casting `*const U` as `*const V` is invalid - --> $DIR/cast-rfc0401.rs:3:5 + --> $DIR/cast-rfc0401-fail.rs:2:5 | LL | u as *const V | ^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | u as *const V = note: the pointers may have different metadata error[E0606]: casting `*const U` as `*const str` is invalid - --> $DIR/cast-rfc0401.rs:8:5 + --> $DIR/cast-rfc0401-fail.rs:6:5 | LL | u as *const str | ^^^^^^^^^^^^^^^ @@ -15,13 +15,13 @@ LL | u as *const str = note: the pointers may have different metadata error[E0609]: no field `f` on type `fn() {main}` - --> $DIR/cast-rfc0401.rs:65:18 + --> $DIR/cast-rfc0401-fail.rs:70:18 | LL | let _ = main.f as *const u32; | ^ unknown field error[E0605]: non-primitive cast: `*const u8` as `&u8` - --> $DIR/cast-rfc0401.rs:29:13 + --> $DIR/cast-rfc0401-fail.rs:33:13 | LL | let _ = v as &u8; | ^^^^^^^^ invalid cast @@ -33,43 +33,43 @@ LL + let _ = &*v; | error[E0605]: non-primitive cast: `*const u8` as `E` - --> $DIR/cast-rfc0401.rs:30:13 + --> $DIR/cast-rfc0401-fail.rs:34:13 | LL | let _ = v as E; | ^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object error[E0605]: non-primitive cast: `*const u8` as `fn()` - --> $DIR/cast-rfc0401.rs:31:13 + --> $DIR/cast-rfc0401-fail.rs:35:13 | LL | let _ = v as fn(); | ^^^^^^^^^ invalid cast error[E0605]: non-primitive cast: `*const u8` as `(u32,)` - --> $DIR/cast-rfc0401.rs:32:13 + --> $DIR/cast-rfc0401-fail.rs:36:13 | LL | let _ = v as (u32,); | ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object error[E0605]: non-primitive cast: `Option<&*const u8>` as `*const u8` - --> $DIR/cast-rfc0401.rs:33:13 + --> $DIR/cast-rfc0401-fail.rs:37:13 | LL | let _ = Some(&v) as *const u8; | ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object error[E0606]: casting `*const u8` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:35:13 + --> $DIR/cast-rfc0401-fail.rs:39:13 | LL | let _ = v as f32; | ^^^^^^^^ error[E0606]: casting `fn() {main}` as `f64` is invalid - --> $DIR/cast-rfc0401.rs:36:13 + --> $DIR/cast-rfc0401-fail.rs:40:13 | LL | let _ = main as f64; | ^^^^^^^^^^^ error[E0606]: casting `&*const u8` as `usize` is invalid - --> $DIR/cast-rfc0401.rs:37:13 + --> $DIR/cast-rfc0401-fail.rs:41:13 | LL | let _ = &v as usize; | ^^^^^^^^^^^ @@ -77,13 +77,13 @@ LL | let _ = &v as usize; = help: cast through a raw pointer first error[E0606]: casting `f32` as `*const u8` is invalid - --> $DIR/cast-rfc0401.rs:38:13 + --> $DIR/cast-rfc0401-fail.rs:42:13 | LL | let _ = f as *const u8; | ^^^^^^^^^^^^^^ error[E0054]: cannot cast `i32` as `bool` - --> $DIR/cast-rfc0401.rs:39:13 + --> $DIR/cast-rfc0401-fail.rs:43:13 | LL | let _ = 3_i32 as bool; | ^^^^^^^^^^^^^ @@ -95,13 +95,13 @@ LL + let _ = 3_i32 != 0; | error[E0054]: cannot cast `E` as `bool` - --> $DIR/cast-rfc0401.rs:40:13 + --> $DIR/cast-rfc0401-fail.rs:44:13 | LL | let _ = E::A as bool; | ^^^^^^^^^^^^ unsupported cast error[E0604]: only `u8` can be cast as `char`, not `u32` - --> $DIR/cast-rfc0401.rs:41:13 + --> $DIR/cast-rfc0401-fail.rs:45:13 | LL | let _ = 0x61u32 as char; | ^^^^^^^^^^^^^^^ invalid cast @@ -112,8 +112,14 @@ LL - let _ = 0x61u32 as char; LL + let _ = char::from_u32(0x61u32); | +error[E0606]: casting `fn(i32) -> Inches {Inches}` as `f32` is invalid + --> $DIR/cast-rfc0401-fail.rs:46:13 + | +LL | let _ = Inches as f32; + | ^^^^^^^^^^^^^ + error[E0606]: casting `bool` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:43:13 + --> $DIR/cast-rfc0401-fail.rs:48:13 | LL | let _ = false as f32; | ^^^^^^^^^^^^ @@ -121,7 +127,7 @@ LL | let _ = false as f32; = help: cast through an integer first error[E0606]: casting `E` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:44:13 + --> $DIR/cast-rfc0401-fail.rs:49:13 | LL | let _ = E::A as f32; | ^^^^^^^^^^^ @@ -129,7 +135,7 @@ LL | let _ = E::A as f32; = help: cast through an integer first error[E0606]: casting `char` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:45:13 + --> $DIR/cast-rfc0401-fail.rs:50:13 | LL | let _ = 'a' as f32; | ^^^^^^^^^^ @@ -137,25 +143,25 @@ LL | let _ = 'a' as f32; = help: cast through an integer first error[E0606]: casting `bool` as `*const u8` is invalid - --> $DIR/cast-rfc0401.rs:47:13 + --> $DIR/cast-rfc0401-fail.rs:52:13 | LL | let _ = false as *const u8; | ^^^^^^^^^^^^^^^^^^ error[E0606]: casting `E` as `*const u8` is invalid - --> $DIR/cast-rfc0401.rs:48:13 + --> $DIR/cast-rfc0401-fail.rs:53:13 | LL | let _ = E::A as *const u8; | ^^^^^^^^^^^^^^^^^ error[E0606]: casting `char` as `*const u8` is invalid - --> $DIR/cast-rfc0401.rs:49:13 + --> $DIR/cast-rfc0401-fail.rs:54:13 | LL | let _ = 'a' as *const u8; | ^^^^^^^^^^^^^^^^ error[E0606]: cannot cast `usize` to a pointer that is wide - --> $DIR/cast-rfc0401.rs:51:24 + --> $DIR/cast-rfc0401-fail.rs:56:24 | LL | let _ = 42usize as *const [u8]; | ------- ^^^^^^^^^^^ creating a `*const [u8]` requires both an address and a length @@ -163,43 +169,43 @@ LL | let _ = 42usize as *const [u8]; | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` error[E0607]: cannot cast thin pointer `*const u8` to wide pointer `*const [u8]` - --> $DIR/cast-rfc0401.rs:52:13 + --> $DIR/cast-rfc0401-fail.rs:57:13 | LL | let _ = v as *const [u8]; | ^^^^^^^^^^^^^^^^ error[E0606]: casting `&dyn Foo` as `*const str` is invalid - --> $DIR/cast-rfc0401.rs:54:13 + --> $DIR/cast-rfc0401-fail.rs:59:13 | LL | let _ = foo as *const str; | ^^^^^^^^^^^^^^^^^ error[E0606]: casting `&dyn Foo` as `*mut str` is invalid - --> $DIR/cast-rfc0401.rs:55:13 + --> $DIR/cast-rfc0401-fail.rs:60:13 | LL | let _ = foo as *mut str; | ^^^^^^^^^^^^^^^ error[E0606]: casting `fn() {main}` as `*mut str` is invalid - --> $DIR/cast-rfc0401.rs:56:13 + --> $DIR/cast-rfc0401-fail.rs:61:13 | LL | let _ = main as *mut str; | ^^^^^^^^^^^^^^^^ error[E0606]: casting `&f32` as `*mut f32` is invalid - --> $DIR/cast-rfc0401.rs:57:13 + --> $DIR/cast-rfc0401-fail.rs:62:13 | LL | let _ = &f as *mut f32; | ^^^^^^^^^^^^^^ error[E0606]: casting `&f32` as `*const f64` is invalid - --> $DIR/cast-rfc0401.rs:58:13 + --> $DIR/cast-rfc0401-fail.rs:63:13 | LL | let _ = &f as *const f64; | ^^^^^^^^^^^^^^^^ error[E0606]: casting `*const [i8]` as `usize` is invalid - --> $DIR/cast-rfc0401.rs:59:13 + --> $DIR/cast-rfc0401-fail.rs:64:13 | LL | let _ = fat_sv as usize; | ^^^^^^^^^^^^^^^ @@ -207,7 +213,7 @@ LL | let _ = fat_sv as usize; = help: cast through a thin pointer first error[E0606]: casting `*const dyn Foo` as `*const [u16]` is invalid - --> $DIR/cast-rfc0401.rs:68:13 + --> $DIR/cast-rfc0401-fail.rs:73:13 | LL | let _ = cf as *const [u16]; | ^^^^^^^^^^^^^^^^^^ @@ -215,7 +221,7 @@ LL | let _ = cf as *const [u16]; = note: the pointers have different metadata error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid - --> $DIR/cast-rfc0401.rs:69:13 + --> $DIR/cast-rfc0401-fail.rs:74:13 | LL | let _ = cf as *const dyn Bar; | ^^^^^^^^^^^^^^^^^^^^ @@ -223,7 +229,7 @@ LL | let _ = cf as *const dyn Bar; = note: the trait objects may have different vtables error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/cast-rfc0401.rs:53:13 + --> $DIR/cast-rfc0401-fail.rs:58:13 | LL | let _ = fat_v as *const dyn Foo; | ^^^^^ doesn't have a size known at compile-time @@ -232,7 +238,7 @@ LL | let _ = fat_v as *const dyn Foo; = note: required for the cast from `*const [u8]` to `*const dyn Foo` error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/cast-rfc0401.rs:62:13 + --> $DIR/cast-rfc0401-fail.rs:67:13 | LL | let _ = a as *const dyn Foo; | ^ doesn't have a size known at compile-time @@ -241,7 +247,7 @@ LL | let _ = a as *const dyn Foo; = note: required for the cast from `*const str` to `*const dyn Foo` error[E0606]: casting `&{float}` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:71:30 + --> $DIR/cast-rfc0401-fail.rs:76:30 | LL | vec![0.0].iter().map(|s| s as f32).collect::>(); | ^^^^^^^^ @@ -251,7 +257,7 @@ help: dereference the expression LL | vec![0.0].iter().map(|s| *s as f32).collect::>(); | + -error: aborting due to 34 previous errors +error: aborting due to 35 previous errors Some errors have detailed explanations: E0054, E0277, E0604, E0605, E0606, E0607, E0609. For more information about an error, try `rustc --explain E0054`. diff --git a/tests/ui/cast/cast-to-dyn-any.rs b/tests/ui/cast/cast-to-dyn-any.rs index e1b3dfe5b61b..3180c530209e 100644 --- a/tests/ui/cast/cast-to-dyn-any.rs +++ b/tests/ui/cast/cast-to-dyn-any.rs @@ -1,3 +1,4 @@ +//! regression test for issue fn main() { 0 as &dyn std::any::Any; //~ ERROR non-primitive cast } diff --git a/tests/ui/cast/cast-to-dyn-any.stderr b/tests/ui/cast/cast-to-dyn-any.stderr index 560fbc73bbdc..6ee1098fcf40 100644 --- a/tests/ui/cast/cast-to-dyn-any.stderr +++ b/tests/ui/cast/cast-to-dyn-any.stderr @@ -1,5 +1,5 @@ error[E0605]: non-primitive cast: `i32` as `&(dyn Any + 'static)` - --> $DIR/issue-22289.rs:2:5 + --> $DIR/cast-to-dyn-any.rs:3:5 | LL | 0 as &dyn std::any::Any; | ^^^^^^^^^^^^^^^^^^^^^^^ invalid cast diff --git a/tests/ui/closures/closure-array-break-length-2.rs b/tests/ui/closures/closure-array-break-length-2.rs deleted file mode 100644 index 60589f7c264a..000000000000 --- a/tests/ui/closures/closure-array-break-length-2.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - loop { - |_: [_; break]| {} //~ ERROR: `break` outside of a loop - } - - loop { - |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop - } -} diff --git a/tests/ui/closures/closure-array-break-length-2.stderr b/tests/ui/closures/closure-array-break-length-2.stderr deleted file mode 100644 index 2df7b6d7f63c..000000000000 --- a/tests/ui/closures/closure-array-break-length-2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/array-break-length.rs:3:17 - | -LL | |_: [_; break]| {} - | ^^^^^ cannot `break` outside of a loop or labeled block - -error[E0268]: `continue` outside of a loop - --> $DIR/array-break-length.rs:7:17 - | -LL | |_: [_; continue]| {} - | ^^^^^^^^ cannot `continue` outside of a loop - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/closures/closure-array-break-length.rs b/tests/ui/closures/closure-array-break-length.rs index fda590fda022..c90ae6585dca 100644 --- a/tests/ui/closures/closure-array-break-length.rs +++ b/tests/ui/closures/closure-array-break-length.rs @@ -1,7 +1,18 @@ +//! regression test for issue fn main() { |_: [_; continue]| {}; //~ ERROR: `continue` outside of a loop + |_: [_; break]| (); //~ ERROR: `break` outside of a loop or labeled block + while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of a loop while |_: [_; break]| {} {} //~ ERROR: `break` outside of a loop + + loop { + |_: [_; break]| {} //~ ERROR: `break` outside of a loop + } + + loop { + |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop + } } diff --git a/tests/ui/closures/closure-array-break-length.stderr b/tests/ui/closures/closure-array-break-length.stderr index 7e0b0027a6f0..3256c50bb906 100644 --- a/tests/ui/closures/closure-array-break-length.stderr +++ b/tests/ui/closures/closure-array-break-length.stderr @@ -1,21 +1,39 @@ error[E0268]: `continue` outside of a loop - --> $DIR/closure-array-break-length.rs:2:13 + --> $DIR/closure-array-break-length.rs:3:13 | LL | |_: [_; continue]| {}; | ^^^^^^^^ cannot `continue` outside of a loop +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/closure-array-break-length.rs:5:13 + | +LL | |_: [_; break]| (); + | ^^^^^ cannot `break` outside of a loop or labeled block + error[E0268]: `continue` outside of a loop - --> $DIR/closure-array-break-length.rs:4:19 + --> $DIR/closure-array-break-length.rs:7:19 | LL | while |_: [_; continue]| {} {} | ^^^^^^^^ cannot `continue` outside of a loop error[E0268]: `break` outside of a loop or labeled block - --> $DIR/closure-array-break-length.rs:6:19 + --> $DIR/closure-array-break-length.rs:9:19 | LL | while |_: [_; break]| {} {} | ^^^^^ cannot `break` outside of a loop or labeled block -error: aborting due to 3 previous errors +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/closure-array-break-length.rs:12:17 + | +LL | |_: [_; break]| {} + | ^^^^^ cannot `break` outside of a loop or labeled block + +error[E0268]: `continue` outside of a loop + --> $DIR/closure-array-break-length.rs:16:17 + | +LL | |_: [_; continue]| {} + | ^^^^^^^^ cannot `continue` outside of a loop + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/closures/closure-move-use-after-move-diagnostic.rs b/tests/ui/closures/closure-move-use-after-move-diagnostic.rs index 63c061594d87..3326af7486c5 100644 --- a/tests/ui/closures/closure-move-use-after-move-diagnostic.rs +++ b/tests/ui/closures/closure-move-use-after-move-diagnostic.rs @@ -1,13 +1,16 @@ +//! regression test for struct NoCopy; //~ NOTE if `NoCopy` implemented `Clone`, you could clone the value //~^ NOTE consider implementing `Clone` for this type fn main() { - let x = NoCopy; - //~^ NOTE move occurs because `x` has type `NoCopy` - let f = move || { let y = x; }; - //~^ NOTE value moved into closure here - //~| NOTE variable moved due to use in closure - //~| NOTE you could clone this value - let z = x; - //~^ ERROR use of moved value: `x` - //~| NOTE value used here after move + let x = NoCopy; + //~^ NOTE move occurs because `x` has type `NoCopy` + let f = move || { + //~^ NOTE value moved into closure here + let y = x; + //~^ NOTE variable moved due to use in closure + //~| NOTE you could clone this value + }; + let z = x; + //~^ ERROR use of moved value: `x` + //~| NOTE value used here after move } diff --git a/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr b/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr index 2d85077fe4c2..94f80da1b10a 100644 --- a/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr +++ b/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr @@ -1,25 +1,26 @@ error[E0382]: use of moved value: `x` - --> $DIR/issue-24357.rs:10:12 + --> $DIR/closure-move-use-after-move-diagnostic.rs:13:13 | -LL | let x = NoCopy; - | - move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait +LL | let x = NoCopy; + | - move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait LL | -LL | let f = move || { let y = x; }; - | ------- - variable moved due to use in closure - | | - | value moved into closure here +LL | let f = move || { + | ------- value moved into closure here +LL | +LL | let y = x; + | - variable moved due to use in closure ... -LL | let z = x; - | ^ value used here after move +LL | let z = x; + | ^ value used here after move | note: if `NoCopy` implemented `Clone`, you could clone the value - --> $DIR/issue-24357.rs:1:1 + --> $DIR/closure-move-use-after-move-diagnostic.rs:2:1 | LL | struct NoCopy; | ^^^^^^^^^^^^^ consider implementing `Clone` for this type ... -LL | let f = move || { let y = x; }; - | - you could clone this value +LL | let y = x; + | - you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-return-outside-fn.rs b/tests/ui/consts/const-return-outside-fn.rs index 665a8fdf8e26..c2ee8642bf4b 100644 --- a/tests/ui/consts/const-return-outside-fn.rs +++ b/tests/ui/consts/const-return-outside-fn.rs @@ -1,3 +1,4 @@ +//! regression test for issue const x: () = { return; //~ ERROR return statement outside of function body }; diff --git a/tests/ui/consts/const-return-outside-fn.stderr b/tests/ui/consts/const-return-outside-fn.stderr index fbf88d503397..131d577a2547 100644 --- a/tests/ui/consts/const-return-outside-fn.stderr +++ b/tests/ui/consts/const-return-outside-fn.stderr @@ -1,5 +1,5 @@ error[E0572]: return statement outside of function body - --> $DIR/issue-38458.rs:2:5 + --> $DIR/const-return-outside-fn.rs:3:5 | LL | return; | ^^^^^^ diff --git a/tests/ui/drop/drop-conflicting-impls.rs b/tests/ui/drop/drop-conflicting-impls.rs index ce511158f005..fba3462a24b2 100644 --- a/tests/ui/drop/drop-conflicting-impls.rs +++ b/tests/ui/drop/drop-conflicting-impls.rs @@ -1,12 +1,13 @@ +//! regression test for issue struct MyStruct; impl Drop for MyStruct { - fn drop(&mut self) { } + fn drop(&mut self) {} } impl Drop for MyStruct { -//~^ ERROR conflicting implementations of trait - fn drop(&mut self) { } + //~^ ERROR conflicting implementations of trait + fn drop(&mut self) {} } fn main() {} diff --git a/tests/ui/drop/drop-conflicting-impls.stderr b/tests/ui/drop/drop-conflicting-impls.stderr index c8db0403e59a..ee310f498d37 100644 --- a/tests/ui/drop/drop-conflicting-impls.stderr +++ b/tests/ui/drop/drop-conflicting-impls.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Drop` for type `MyStruct` - --> $DIR/issue-28568.rs:7:1 + --> $DIR/drop-conflicting-impls.rs:8:1 | LL | impl Drop for MyStruct { | ---------------------- first implementation here diff --git a/tests/ui/enum/enum-discriminant-missing-variant.rs b/tests/ui/enum/enum-discriminant-missing-variant.rs index 09f9ebccf250..1bdbfb1fbcd4 100644 --- a/tests/ui/enum/enum-discriminant-missing-variant.rs +++ b/tests/ui/enum/enum-discriminant-missing-variant.rs @@ -1,3 +1,4 @@ +//! regression test for issue pub enum SomeEnum { B = SomeEnum::A, //~ ERROR no variant or associated item named `A` found } diff --git a/tests/ui/enum/enum-discriminant-missing-variant.stderr b/tests/ui/enum/enum-discriminant-missing-variant.stderr index 830d260f99d7..ef98a93e86f6 100644 --- a/tests/ui/enum/enum-discriminant-missing-variant.stderr +++ b/tests/ui/enum/enum-discriminant-missing-variant.stderr @@ -1,5 +1,5 @@ error[E0599]: no variant or associated item named `A` found for enum `SomeEnum` in the current scope - --> $DIR/issue-23217.rs:2:19 + --> $DIR/enum-discriminant-missing-variant.rs:3:19 | LL | pub enum SomeEnum { | ----------------- variant or associated item `A` not found for this enum diff --git a/tests/ui/mismatched_types/cast-rfc0401-2.rs b/tests/ui/mismatched_types/cast-rfc0401-2.rs deleted file mode 100644 index c176b1247cea..000000000000 --- a/tests/ui/mismatched_types/cast-rfc0401-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -struct Inches(i32); - -fn main() { - Inches as f32; - //~^ ERROR casting -} diff --git a/tests/ui/mismatched_types/cast-rfc0401-2.stderr b/tests/ui/mismatched_types/cast-rfc0401-2.stderr deleted file mode 100644 index b1b59af6ec2b..000000000000 --- a/tests/ui/mismatched_types/cast-rfc0401-2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0606]: casting `fn(i32) -> Inches {Inches}` as `f32` is invalid - --> $DIR/issue-21554.rs:4:5 - | -LL | Inches as f32; - | ^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0606`. diff --git a/tests/ui/nll/borrowck-annotate-static-lifetime.rs b/tests/ui/nll/borrowck-annotate-static-lifetime.rs index 2f78ce0002ba..9d849db9b4f3 100644 --- a/tests/ui/nll/borrowck-annotate-static-lifetime.rs +++ b/tests/ui/nll/borrowck-annotate-static-lifetime.rs @@ -1,3 +1,4 @@ +//! regression test for issue fn main() { let _vec: Vec<&'static String> = vec![&String::new()]; //~^ ERROR temporary value dropped while borrowed [E0716] diff --git a/tests/ui/nll/borrowck-annotate-static-lifetime.stderr b/tests/ui/nll/borrowck-annotate-static-lifetime.stderr index d25c6eda9c34..9cb9007d9131 100644 --- a/tests/ui/nll/borrowck-annotate-static-lifetime.stderr +++ b/tests/ui/nll/borrowck-annotate-static-lifetime.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-47184.rs:2:44 + --> $DIR/borrowck-annotate-static-lifetime.rs:3:44 | LL | let _vec: Vec<&'static String> = vec![&String::new()]; | -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement diff --git a/tests/ui/nll/nll-anon-to-static.rs b/tests/ui/nll/nll-anon-to-static.rs index 4bd49a8796b3..3dc79950056c 100644 --- a/tests/ui/nll/nll-anon-to-static.rs +++ b/tests/ui/nll/nll-anon-to-static.rs @@ -1,3 +1,4 @@ +//! regression test for issue fn foo(x: &u32) -> &'static u32 { &*x //~^ ERROR lifetime may not live long enough diff --git a/tests/ui/nll/nll-anon-to-static.stderr b/tests/ui/nll/nll-anon-to-static.stderr index f47df306ab84..e431dfd992e1 100644 --- a/tests/ui/nll/nll-anon-to-static.stderr +++ b/tests/ui/nll/nll-anon-to-static.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-46983.rs:2:5 + --> $DIR/nll-anon-to-static.rs:3:5 | LL | fn foo(x: &u32) -> &'static u32 { | - let's call the lifetime of this reference `'1` diff --git a/tests/ui/parser/missing-operator-after-float.rs b/tests/ui/parser/missing-operator-after-float.rs index 15649f777e09..8868689ff81f 100644 --- a/tests/ui/parser/missing-operator-after-float.rs +++ b/tests/ui/parser/missing-operator-after-float.rs @@ -1,3 +1,4 @@ +//! regression test for issue fn main() { let a = |r: f64| if r != 0.0(r != 0.0) { 1.0 } else { 0.0 }; //~^ ERROR expected function, found `{float}` diff --git a/tests/ui/parser/missing-operator-after-float.stderr b/tests/ui/parser/missing-operator-after-float.stderr index 95a39b1d1980..08878cf098a7 100644 --- a/tests/ui/parser/missing-operator-after-float.stderr +++ b/tests/ui/parser/missing-operator-after-float.stderr @@ -1,5 +1,5 @@ error[E0618]: expected function, found `{float}` - --> $DIR/issue-45965.rs:2:30 + --> $DIR/missing-operator-after-float.rs:3:30 | LL | let a = |r: f64| if r != 0.0(r != 0.0) { 1.0 } else { 0.0 }; | ^^^---------- diff --git a/tests/ui/parser/unbalanced-doublequote-2.rs b/tests/ui/parser/unbalanced-doublequote-2.rs index b8c0e285ffca..1906f96f6c9b 100644 --- a/tests/ui/parser/unbalanced-doublequote-2.rs +++ b/tests/ui/parser/unbalanced-doublequote-2.rs @@ -1,3 +1,4 @@ +//! regression test for issue fn main() { "😊""; //~ ERROR unterminated double quote } diff --git a/tests/ui/parser/unbalanced-doublequote-2.stderr b/tests/ui/parser/unbalanced-doublequote-2.stderr index 3e12de34e11e..3a6efaf7d4ec 100644 --- a/tests/ui/parser/unbalanced-doublequote-2.stderr +++ b/tests/ui/parser/unbalanced-doublequote-2.stderr @@ -1,5 +1,5 @@ error[E0765]: unterminated double quote string - --> $DIR/issue-44078.rs:2:8 + --> $DIR/unbalanced-doublequote-2.rs:3:8 | LL | "😊""; | _________^ diff --git a/tests/ui/resolve/missing-associated-items.rs b/tests/ui/resolve/missing-associated-items.rs index 92f4c546440a..72d6cbb3f149 100644 --- a/tests/ui/resolve/missing-associated-items.rs +++ b/tests/ui/resolve/missing-associated-items.rs @@ -1,9 +1,17 @@ -enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } +//! regression test for issue +enum Token { + LeftParen, + RightParen, + Plus, + Minus, /* etc */ +} struct Struct { a: usize, } -fn use_token(token: &Token) { unimplemented!() } +fn use_token(token: &Token) { + unimplemented!() +} fn main() { use_token(&Token::Homura); //~ ERROR no variant or associated item named `Homura` diff --git a/tests/ui/resolve/missing-associated-items.stderr b/tests/ui/resolve/missing-associated-items.stderr index d07d1a7caaf2..d27a3a644aee 100644 --- a/tests/ui/resolve/missing-associated-items.stderr +++ b/tests/ui/resolve/missing-associated-items.stderr @@ -1,14 +1,14 @@ error[E0599]: no variant or associated item named `Homura` found for enum `Token` in the current scope - --> $DIR/issue-23173.rs:9:23 + --> $DIR/missing-associated-items.rs:17:23 | -LL | enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } +LL | enum Token { | ---------- variant or associated item `Homura` not found for this enum ... LL | use_token(&Token::Homura); | ^^^^^^ variant or associated item not found in `Token` error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope - --> $DIR/issue-23173.rs:10:13 + --> $DIR/missing-associated-items.rs:18:13 | LL | struct Struct { | ------------- function or associated item `method` not found for this struct @@ -17,7 +17,7 @@ LL | Struct::method(); | ^^^^^^ function or associated item not found in `Struct` error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope - --> $DIR/issue-23173.rs:11:13 + --> $DIR/missing-associated-items.rs:19:13 | LL | struct Struct { | ------------- function or associated item `method` not found for this struct @@ -26,7 +26,7 @@ LL | Struct::method; | ^^^^^^ function or associated item not found in `Struct` error[E0599]: no associated item named `Assoc` found for struct `Struct` in the current scope - --> $DIR/issue-23173.rs:12:13 + --> $DIR/missing-associated-items.rs:20:13 | LL | struct Struct { | ------------- associated item `Assoc` not found for this struct diff --git a/tests/ui/typeck/for-in-const-eval.rs b/tests/ui/typeck/for-in-const-eval.rs index 1358e0bde4c8..f187a9ef3077 100644 --- a/tests/ui/typeck/for-in-const-eval.rs +++ b/tests/ui/typeck/for-in-const-eval.rs @@ -1,3 +1,4 @@ +//! regression test for issue fn main() { Vec::<[(); 1 + for x in 0..1 {}]>::new(); //~^ ERROR cannot add diff --git a/tests/ui/typeck/for-in-const-eval.stderr b/tests/ui/typeck/for-in-const-eval.stderr index 168f5894fb03..e7a255849581 100644 --- a/tests/ui/typeck/for-in-const-eval.stderr +++ b/tests/ui/typeck/for-in-const-eval.stderr @@ -1,5 +1,5 @@ error[E0277]: cannot add `()` to `{integer}` - --> $DIR/issue-50582.rs:2:18 + --> $DIR/for-in-const-eval.rs:3:18 | LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); | ^ no implementation for `{integer} + ()` From d0e14f1885eb13ae9ea453817575428f0731b456 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 23 Dec 2025 13:11:53 +0100 Subject: [PATCH 1178/3801] fix: Fix flycheck generations not being synced for multiple workspaces The diagnostics collection globally tracks the generation for all loaded workspaces as its shared between them, yet the flycheck actors track their own separate generations per workspace. This mismatch could cause flycheck to not work correctly when multiple workspaces were loaded. --- .../rust-analyzer/crates/rust-analyzer/src/flycheck.rs | 8 ++++---- .../rust-analyzer/crates/rust-analyzer/src/reload.rs | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 14a4a1752f41..b06264169188 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -147,13 +147,13 @@ pub(crate) struct FlycheckHandle { sender: Sender, _thread: stdx::thread::JoinHandle, id: usize, - generation: AtomicUsize, + generation: Arc, } impl FlycheckHandle { pub(crate) fn spawn( id: usize, - generation: DiagnosticsGeneration, + generation: Arc, sender: Sender, config: FlycheckConfig, sysroot_root: Option, @@ -163,7 +163,7 @@ impl FlycheckHandle { ) -> FlycheckHandle { let actor = FlycheckActor::new( id, - generation, + generation.load(Ordering::Relaxed), sender, config, sysroot_root, @@ -176,7 +176,7 @@ impl FlycheckHandle { stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, format!("Flycheck{id}")) .spawn(move || actor.run(receiver)) .expect("failed to spawn thread"); - FlycheckHandle { id, generation: generation.into(), sender, _thread: thread } + FlycheckHandle { id, generation, sender, _thread: thread } } /// Schedule a re-start of the cargo check worker to do a workspace wide check. diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 317c1123659e..e3a5ee221973 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -13,7 +13,7 @@ //! project is currently loading and we don't have a full project model, we //! still want to respond to various requests. // FIXME: This is a mess that needs some untangling work -use std::{iter, mem}; +use std::{iter, mem, sync::atomic::AtomicUsize}; use hir::{ChangeWithProcMacros, ProcMacrosBuilder, db::DefDatabase}; use ide_db::{ @@ -866,12 +866,13 @@ impl GlobalState { let invocation_strategy = config.invocation_strategy(); let next_gen = self.flycheck.iter().map(FlycheckHandle::generation).max().unwrap_or_default() + 1; + let generation = Arc::new(AtomicUsize::new(next_gen)); self.flycheck = match invocation_strategy { crate::flycheck::InvocationStrategy::Once => { vec![FlycheckHandle::spawn( 0, - next_gen, + generation.clone(), sender.clone(), config, None, @@ -915,7 +916,7 @@ impl GlobalState { .map(|(id, (root, manifest_path, target_dir), sysroot_root)| { FlycheckHandle::spawn( id, - next_gen, + generation.clone(), sender.clone(), config.clone(), sysroot_root, From ac448c987d2ed4b8ef50bb2f5422c093c1e161a5 Mon Sep 17 00:00:00 2001 From: delta17920 Date: Tue, 9 Dec 2025 09:36:58 +0000 Subject: [PATCH 1179/3801] Fix ICE in normalization during closure capture analysis --- compiler/rustc_middle/src/ty/util.rs | 6 +- .../normalization-ice-issue-149746.rs | 17 ++++ .../normalization-ice-issue-149746.stderr | 80 +++++++++++++++++++ 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 tests/ui/associated-types/normalization-ice-issue-149746.rs create mode 100644 tests/ui/associated-types/normalization-ice-issue-149746.stderr diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index fc03ad52b4bf..2797f2fcdb72 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1394,8 +1394,10 @@ impl<'tcx> Ty<'tcx> { // This doesn't depend on regions, so try to minimize distinct // query keys used. - let erased = tcx.normalize_erasing_regions(typing_env, query_ty); - tcx.has_significant_drop_raw(typing_env.as_query_input(erased)) + // FIX: Use try_normalize to avoid crashing. If it fails, return true. + tcx.try_normalize_erasing_regions(typing_env, query_ty) + .map(|erased| tcx.has_significant_drop_raw(typing_env.as_query_input(erased))) + .unwrap_or(true) } } } diff --git a/tests/ui/associated-types/normalization-ice-issue-149746.rs b/tests/ui/associated-types/normalization-ice-issue-149746.rs new file mode 100644 index 000000000000..8932d321b7e5 --- /dev/null +++ b/tests/ui/associated-types/normalization-ice-issue-149746.rs @@ -0,0 +1,17 @@ +//@ edition: 2015..2021 +#![warn(rust_2021_incompatible_closure_captures)] +trait Owner { type Ty; } +impl Owner for () { type Ty = T; } +pub struct Warns { + _significant_drop: <() as Owner>::Ty, + //~^ ERROR expected a `FnMut()` closure, found `T` + field: String, +} +pub fn test(w: Warns) { + //~^ ERROR expected a `FnMut()` closure, found `T` + _ = || w.field + //~^ ERROR expected a `FnMut()` closure, found `T` + //~| ERROR expected a `FnMut()` closure, found `T` + //~| WARN: changes to closure capture in Rust 2021 will affect drop order +} +fn main() {} diff --git a/tests/ui/associated-types/normalization-ice-issue-149746.stderr b/tests/ui/associated-types/normalization-ice-issue-149746.stderr new file mode 100644 index 000000000000..7f983d6e14ae --- /dev/null +++ b/tests/ui/associated-types/normalization-ice-issue-149746.stderr @@ -0,0 +1,80 @@ +error[E0277]: expected a `FnMut()` closure, found `T` + --> $DIR/normalization-ice-issue-149746.rs:6:24 + | +LL | _significant_drop: <() as Owner>::Ty, + | ^^^^^^^^^^^^^^^^^^^^ expected an `FnMut()` closure, found `T` + | + = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Owner::Ty` + --> $DIR/normalization-ice-issue-149746.rs:3:26 + | +LL | trait Owner { type Ty; } + | ^^^^^^^ required by this bound in `Owner::Ty` +help: consider restricting type parameter `T` with trait `FnMut` + | +LL | pub struct Warns { + | +++++++++ + +warning: changes to closure capture in Rust 2021 will affect drop order + --> $DIR/normalization-ice-issue-149746.rs:12:9 + | +LL | _ = || w.field + | ^^ ------- + | | | + | | in Rust 2018, `w` is dropped here, but in Rust 2021, only `w.field` will be dropped here as part of the closure + | in Rust 2018, this closure captures all of `w`, but in Rust 2021, it will only capture `w.field` + | + = note: for more information, see +note: the lint level is defined here + --> $DIR/normalization-ice-issue-149746.rs:2:9 + | +LL | #![warn(rust_2021_incompatible_closure_captures)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a dummy let to cause `w` to be fully captured + | +LL | _ = || { let _ = &w; w.field } + | +++++++++++++ + + +error[E0277]: expected a `FnMut()` closure, found `T` + --> $DIR/normalization-ice-issue-149746.rs:12:9 + | +LL | _ = || w.field + | ^^^^^^^^^^ expected an `FnMut()` closure, found `T` + | + = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Owner::Ty` + --> $DIR/normalization-ice-issue-149746.rs:3:26 + | +LL | trait Owner { type Ty; } + | ^^^^^^^ required by this bound in `Owner::Ty` + +error[E0277]: expected a `FnMut()` closure, found `T` + --> $DIR/normalization-ice-issue-149746.rs:10:16 + | +LL | pub fn test(w: Warns) { + | ^ expected an `FnMut()` closure, found `T` + | + = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Owner::Ty` + --> $DIR/normalization-ice-issue-149746.rs:3:26 + | +LL | trait Owner { type Ty; } + | ^^^^^^^ required by this bound in `Owner::Ty` + +error[E0277]: expected a `FnMut()` closure, found `T` + --> $DIR/normalization-ice-issue-149746.rs:12:9 + | +LL | _ = || w.field + | ^^^^^^^^^^ expected an `FnMut()` closure, found `T` + | + = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Owner::Ty` + --> $DIR/normalization-ice-issue-149746.rs:3:26 + | +LL | trait Owner { type Ty; } + | ^^^^^^^ required by this bound in `Owner::Ty` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. From 184e06223f3ada29d140d1e2559142ead18cfff2 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 23 Dec 2025 18:25:21 +0530 Subject: [PATCH 1180/3801] chore: remove unwanted comments, extra lines and putting cli srv on default --- src/tools/rust-analyzer/.github/workflows/ci.yaml | 2 +- src/tools/rust-analyzer/Cargo.lock | 1 - src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs | 4 ++-- src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml | 1 - .../crates/proc-macro-srv/src/server_impl/token_id.rs | 1 - 5 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index e817f770a417..5975272d871a 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -70,7 +70,7 @@ jobs: - name: Test run: cargo test --features sysroot-abi -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api -- --quiet - + - name: Check salsa dependency run: "! (cargo tree -p proc-macro-srv-cli | grep -q salsa)" diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 7d133f99498b..10cd6cd43c20 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1856,7 +1856,6 @@ dependencies = [ name = "proc-macro-srv" version = "0.0.0" dependencies = [ - "crossbeam-channel", "expect-test", "intern", "libc", diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index d73d20b58422..bdfdb50002e1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -31,7 +31,7 @@ fn main() -> std::io::Result<()> { clap::Arg::new("format") .long("format") .action(clap::ArgAction::Set) - .default_value("bidirectional-postcard-prototype") + .default_value("json-legacy") .value_parser(clap::builder::EnumValueParser::::new()), clap::Arg::new("version") .long("version") @@ -71,7 +71,7 @@ impl ValueEnum for ProtocolFormat { Some(clap::builder::PossibleValue::new("postcard-legacy")) } ProtocolFormat::BidirectionalPostcardPrototype => { - Some(clap::builder::PossibleValue::new("postcard-new")) + Some(clap::builder::PossibleValue::new("bidirectional-postcard-prototype")) } } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml index b2abda0bfd7f..361017178409 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml @@ -22,7 +22,6 @@ paths.workspace = true # span = {workspace = true, default-features = false} does not work span = { path = "../span", version = "0.0.0", default-features = false} intern.workspace = true -crossbeam-channel.workspace = true ra-ap-rustc_lexer.workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index 3b12644ec34a..9db7597d849f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -141,7 +141,6 @@ impl server::Span for SpanIdServer { /// See PR: /// https://github.com/rust-lang/rust/pull/55780 fn source_text(&mut self, _span: Self::Span) -> Option { - // FIXME requires db, needs special handling wrt fixup spans None } From 75f53dd70e23b09e2557ca7c73bcaa22b9d1a8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 23 Dec 2025 14:16:25 +0100 Subject: [PATCH 1181/3801] Update bors configuration --- rust-bors.toml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/rust-bors.toml b/rust-bors.toml index e813c6c4b116..996b50b2ea27 100644 --- a/rust-bors.toml +++ b/rust-bors.toml @@ -25,3 +25,42 @@ labels_blocking_approval = [ "S-waiting-on-t-rustdoc-frontend", "S-waiting-on-t-clippy" ] + +# If CI runs quicker than this duration, consider it to be a failure +min_ci_time = 600 + +[labels] +approved = [ + "+S-waiting-on-bors", + "-S-blocked", + "-S-waiting-on-author", + "-S-waiting-on-crater", + "-S-waiting-on-review", + "-S-waiting-on-team" +] +unapproved = [ + "+S-waiting-on-author", + "-S-blocked", + "-S-waiting-on-bors", + "-S-waiting-on-crater", + "-S-waiting-on-review", + "-S-waiting-on-team" +] +try_failed = [ + "+S-waiting-on-author", + "-S-waiting-on-review", + "-S-waiting-on-crater" +] +auto_build_succeeded = ["+merged-by-bors"] +auto_build_failed = [ + "+S-waiting-on-review", + "-S-blocked", + "-S-waiting-on-bors", + "-S-waiting-on-author", + "-S-waiting-on-crater", + "-S-waiting-on-team" +] + +# Flip this two once new bors is used for actual merges on this repository +merge_queue_enabled = false +report_merge_conflicts = true From dfef2e96fe0216e243f458b8fe04a8b82a07065a Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 9 Dec 2025 07:50:30 -0800 Subject: [PATCH 1182/3801] Remove the need to call clang for std::offload usages --- compiler/rustc_codegen_llvm/src/back/write.rs | 74 ++++++++++++++++++- compiler/rustc_codegen_llvm/src/base.rs | 6 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 8 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 22 +++++- compiler/rustc_interface/src/tests.rs | 2 +- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 32 ++++++-- compiler/rustc_session/src/config.rs | 12 +-- compiler/rustc_session/src/options.rs | 23 +++++- 8 files changed, 149 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index e8da7f68136d..a649ee4bff1c 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -703,10 +703,9 @@ pub(crate) unsafe fn llvm_optimize( llvm::set_value_name(new_fn, &name); } - if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Enable) { + if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Device) { let cx = SimpleCx::new(module.module_llvm.llmod(), module.module_llvm.llcx, cgcx.pointer_size); - for func in cx.get_functions() { let offload_kernel = "offload-kernel"; if attributes::has_string_attr(func, offload_kernel) { @@ -775,12 +774,79 @@ pub(crate) unsafe fn llvm_optimize( ) }; - if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Enable) { + if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Device) { + let device_path = cgcx.output_filenames.path(OutputType::Object); + let device_dir = device_path.parent().unwrap(); + let device_out = device_dir.join("host.out"); + let device_out_c = path_to_c_string(device_out.as_path()); unsafe { - llvm::LLVMRustBundleImages(module.module_llvm.llmod(), module.module_llvm.tm.raw()); + // 1) Bundle device module into offload image host.out (device TM) + let ok = llvm::LLVMRustBundleImages( + module.module_llvm.llmod(), + module.module_llvm.tm.raw(), + device_out_c.as_ptr(), + ); + assert!(ok, "LLVMRustBundleImages (device -> host.out) failed"); + if !device_out.exists() { + panic!("BundleImages failed, `host.out` was not created!"); + } } } + // This assumes that we previously compiled our kernels for a gpu target, which created a + // `host.out` artifact. The user is supposed to provide us with a path to this artifact, we + // don't need any other artifacts from the previous run. We will embed this artifact into our + // LLVM-IR host module, to create a `host.o` ObjectFile, which we will write to disk. + // The last, not yet automated steps uses the `clang-linker-wrapper` to process `host.o`. + if !cgcx.target_is_like_gpu { + if let Some(device_path) = config + .offload + .iter() + .find_map(|o| if let config::Offload::Host(path) = o { Some(path) } else { None }) + { + let device_pathbuf = PathBuf::from(device_path); + if device_pathbuf.is_relative() { + panic!("Absolute path is needed"); + } else if device_pathbuf + .file_name() + .and_then(|n| n.to_str()) + .is_some_and(|n| n != "host.out") + { + panic!("Need path to the host.out file"); + } + assert!(device_pathbuf.exists()); + let host_path = cgcx.output_filenames.path(OutputType::Object); + let host_dir = host_path.parent().unwrap(); + let out_obj = host_dir.join("host.o"); + let host_out_c = path_to_c_string(device_pathbuf.as_path()); + + // 2) Finalize host: lib.bc + host.out -> host.o (host TM) + // We create a full clone of our LLVM host module, since we will embed the device IR + // into it, and this might break caching or incremental compilation otherwise. + let llmod2 = llvm::LLVMCloneModule(module.module_llvm.llmod()); + let ok = + unsafe { llvm::LLVMRustOffloadEmbedBufferInModule(llmod2, host_out_c.as_ptr()) }; + assert!(ok, "LLVMRustOffloadEmbedBufferInModule failed"); + write_output_file( + dcx, + module.module_llvm.tm.raw(), + config.no_builtins, + llmod2, + &out_obj, + None, + llvm::FileType::ObjectFile, + &cgcx.prof, + true, + ); + if !out_obj.exists() { + dbg!("{:?} does not exist!", out_obj); + panic!("FinalizeOffload failed!"); + } + // We ignore cgcx.save_temps here and unconditionally always keep our `host.out` artifact. + // Otherwise, recompiling the host code would fail since we deleted that device artifact + // in the previous host compilation, which would be confusing at best. + } + } result.into_result().unwrap_or_else(|()| llvm_err(dcx, LlvmError::RunLlvmPasses)) } diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 16455b4c79cd..388118f9b4f1 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -93,9 +93,9 @@ pub(crate) fn compile_codegen_unit( // They are necessary for correct offload execution. We do this here to simplify the // `offload` intrinsic, avoiding the need for tracking whether it's the first // intrinsic call or not. - if cx.sess().opts.unstable_opts.offload.contains(&Offload::Enable) - && !cx.sess().target.is_like_gpu - { + let has_host_offload = + cx.sess().opts.unstable_opts.offload.iter().any(|o| matches!(o, Offload::Host(_))); + if has_host_offload && !cx.sess().target.is_like_gpu { cx.offload_globals.replace(Some(OffloadGlobals::declare(&cx))); } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 3bc890310cc8..f3d919207477 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -202,13 +202,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { return Ok(()); } sym::offload => { - if !tcx - .sess - .opts - .unstable_opts - .offload - .contains(&rustc_session::config::Offload::Enable) - { + if tcx.sess.opts.unstable_opts.offload.is_empty() { let _ = tcx.dcx().emit_almost_fatal(OffloadWithoutEnable); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index a86b4cc38915..75b3e5955b78 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1666,7 +1666,15 @@ mod Offload { use super::*; unsafe extern "C" { /// Processes the module and writes it in an offload compatible way into a "host.out" file. - pub(crate) fn LLVMRustBundleImages<'a>(M: &'a Module, TM: &'a TargetMachine) -> bool; + pub(crate) fn LLVMRustBundleImages<'a>( + M: &'a Module, + TM: &'a TargetMachine, + host_out: *const c_char, + ) -> bool; + pub(crate) unsafe fn LLVMRustOffloadEmbedBufferInModule<'a>( + _M: &'a Module, + _host_out: *const c_char, + ) -> bool; pub(crate) fn LLVMRustOffloadMapper<'a>(OldFn: &'a Value, NewFn: &'a Value); } } @@ -1680,7 +1688,17 @@ mod Offload_fallback { /// Processes the module and writes it in an offload compatible way into a "host.out" file. /// Marked as unsafe to match the real offload wrapper which is unsafe due to FFI. #[allow(unused_unsafe)] - pub(crate) unsafe fn LLVMRustBundleImages<'a>(_M: &'a Module, _TM: &'a TargetMachine) -> bool { + pub(crate) unsafe fn LLVMRustBundleImages<'a>( + _M: &'a Module, + _TM: &'a TargetMachine, + _host_out: *const c_char, + ) -> bool { + unimplemented!("This rustc version was not built with LLVM Offload support!"); + } + pub(crate) unsafe fn LLVMRustOffloadEmbedBufferInModule<'a>( + _M: &'a Module, + _host_out: *const c_char, + ) -> bool { unimplemented!("This rustc version was not built with LLVM Offload support!"); } #[allow(unused_unsafe)] diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8dab3a7f37f5..d075f94ef850 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -837,7 +837,7 @@ fn test_unstable_options_tracking_hash() { tracked!(no_profiler_runtime, true); tracked!(no_trait_vptr, true); tracked!(no_unique_section_names, true); - tracked!(offload, vec![Offload::Enable]); + tracked!(offload, vec![Offload::Device]); tracked!(on_broken_pipe, OnBrokenPipe::Kill); tracked!(osx_rpath_install_name, true); tracked!(packed_bundled_libs, true); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 0720af0eb7e0..02e6abf24627 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -43,8 +43,10 @@ // available. As such, we only try to build it in the first place, if // llvm.offload is enabled. #ifdef OFFLOAD +#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Object/OffloadBinary.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #endif // for raw `write` in the bad-alloc handler @@ -174,12 +176,13 @@ static Error writeFile(StringRef Filename, StringRef Data) { // --image=file=device.bc,triple=amdgcn-amd-amdhsa,arch=gfx90a,kind=openmp // The input module is the rust code compiled for a gpu target like amdgpu. // Based on clang/tools/clang-offload-packager/ClangOffloadPackager.cpp -extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) { +extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM, + const char *HostOutPath) { std::string Storage; llvm::raw_string_ostream OS1(Storage); llvm::WriteBitcodeToFile(*unwrap(M), OS1); OS1.flush(); - auto MB = llvm::MemoryBuffer::getMemBufferCopy(Storage, "module.bc"); + auto MB = llvm::MemoryBuffer::getMemBufferCopy(Storage, "device.bc"); SmallVector BinaryData; raw_svector_ostream OS2(BinaryData); @@ -188,19 +191,38 @@ extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) { ImageBinary.TheImageKind = object::IMG_Bitcode; ImageBinary.Image = std::move(MB); ImageBinary.TheOffloadKind = object::OFK_OpenMP; - ImageBinary.StringData["triple"] = TM.getTargetTriple().str(); - ImageBinary.StringData["arch"] = TM.getTargetCPU(); + + std::string TripleStr = TM.getTargetTriple().str(); + llvm::StringRef CPURef = TM.getTargetCPU(); + ImageBinary.StringData["triple"] = TripleStr; + ImageBinary.StringData["arch"] = CPURef; llvm::SmallString<0> Buffer = OffloadBinary::write(ImageBinary); if (Buffer.size() % OffloadBinary::getAlignment() != 0) // Offload binary has invalid size alignment return false; OS2 << Buffer; - if (Error E = writeFile("host.out", + if (Error E = writeFile(HostOutPath, StringRef(BinaryData.begin(), BinaryData.size()))) return false; return true; } +extern "C" bool LLVMRustOffloadEmbedBufferInModule(LLVMModuleRef HostM, + const char *HostOutPath) { + auto MBOrErr = MemoryBuffer::getFile(HostOutPath); + if (!MBOrErr) { + auto E = MBOrErr.getError(); + auto _B = errorCodeToError(E); + return false; + } + MemoryBufferRef Buf = (*MBOrErr)->getMemBufferRef(); + Module *M = unwrap(HostM); + StringRef SectionName = ".llvm.offloading"; + Align Alignment = Align(8); + llvm::embedBufferInModule(*M, Buf, SectionName, Alignment); + return true; +} + extern "C" void LLVMRustOffloadMapper(LLVMValueRef OldFn, LLVMValueRef NewFn) { llvm::Function *oldFn = llvm::unwrap(OldFn); llvm::Function *newFn = llvm::unwrap(NewFn); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a3a97dfec61d..2774333573f6 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -190,10 +190,12 @@ pub enum CoverageLevel { } // The different settings that the `-Z offload` flag can have. -#[derive(Clone, Copy, PartialEq, Hash, Debug)] +#[derive(Clone, PartialEq, Hash, Debug)] pub enum Offload { - /// Enable the llvm offload pipeline - Enable, + /// Entry point for `std::offload`, enables kernel compilation for a gpu device + Device, + /// Second step in the offload pipeline, generates the host code to call kernels. + Host(String), } /// The different settings that the `-Z autodiff` flag can have. @@ -2578,9 +2580,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M ) } - if !nightly_options::is_unstable_enabled(matches) - && unstable_opts.offload.contains(&Offload::Enable) - { + if !nightly_options::is_unstable_enabled(matches) && !unstable_opts.offload.is_empty() { early_dcx.early_fatal( "`-Zoffload=Enable` also requires `-Zunstable-options` \ and a nightly compiler", diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index aea0b73ee927..2b83d1225c97 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1451,8 +1451,27 @@ pub mod parse { let mut v: Vec<&str> = v.split(",").collect(); v.sort_unstable(); for &val in v.iter() { - let variant = match val { - "Enable" => Offload::Enable, + // Split each entry on '=' if it has an argument + let (key, arg) = match val.split_once('=') { + Some((k, a)) => (k, Some(a)), + None => (val, None), + }; + + let variant = match key { + "Host" => { + if let Some(p) = arg { + Offload::Host(p.to_string()) + } else { + return false; + } + } + "Device" => { + if let Some(_) = arg { + // Device does not accept a value + return false; + } + Offload::Device + } _ => { // FIXME(ZuseZ4): print an error saying which value is not recognized return false; From 3fdc6da2aad13909f02754d32db85ac69ca86102 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 9 Dec 2025 07:51:04 -0800 Subject: [PATCH 1183/3801] adding proper error handling for offload --- compiler/rustc_codegen_llvm/messages.ftl | 7 ++++++- compiler/rustc_codegen_llvm/src/back/write.rs | 20 +++++++++---------- compiler/rustc_codegen_llvm/src/errors.rs | 20 +++++++++++++++++++ 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index b3ef9840f5dc..a637ae8184b4 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -19,7 +19,12 @@ codegen_llvm_lto_bitcode_from_rlib = failed to get bitcode from object file for codegen_llvm_mismatch_data_layout = data-layout for target `{$rustc_target}`, `{$rustc_layout}`, differs from LLVM target's `{$llvm_target}` default layout, `{$llvm_layout}` -codegen_llvm_offload_without_enable = using the offload feature requires -Z offload=Enable +codegen_llvm_offload_bundleimages_failed = call to BundleImages failed, `host.out` was not created +codegen_llvm_offload_embed_failed = call to EmbedBufferInModule failed, `host.o` was not created +codegen_llvm_offload_no_abs_path = using the `-Z offload=Host=/absolute/path/to/host.out` flag requires an absolute path +codegen_llvm_offload_no_host_out = using the `-Z offload=Host=/absolute/path/to/host.out` flag must point to a `host.out` file +codegen_llvm_offload_nonexisting = the given path/file to `host.out` does not exist. Did you forget to run the device compilation first? +codegen_llvm_offload_without_enable = using the offload feature requires -Z offload= codegen_llvm_offload_without_fat_lto = using the offload feature requires -C lto=fat codegen_llvm_parse_bitcode = failed to parse bitcode for LTO module diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a649ee4bff1c..d87de8b38467 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -786,9 +786,8 @@ pub(crate) unsafe fn llvm_optimize( module.module_llvm.tm.raw(), device_out_c.as_ptr(), ); - assert!(ok, "LLVMRustBundleImages (device -> host.out) failed"); - if !device_out.exists() { - panic!("BundleImages failed, `host.out` was not created!"); + if !ok || !device_out.exists() { + dcx.emit_err(crate::errors::OffloadBundleImagesFailed); } } } @@ -806,15 +805,16 @@ pub(crate) unsafe fn llvm_optimize( { let device_pathbuf = PathBuf::from(device_path); if device_pathbuf.is_relative() { - panic!("Absolute path is needed"); + dcx.emit_err(crate::errors::OffloadWithoutAbsPath); } else if device_pathbuf .file_name() .and_then(|n| n.to_str()) .is_some_and(|n| n != "host.out") { - panic!("Need path to the host.out file"); + dcx.emit_err(crate::errors::OffloadWrongFileName); + } else if !device_pathbuf.exists() { + dcx.emit_err(crate::errors::OffloadNonexistingPath); } - assert!(device_pathbuf.exists()); let host_path = cgcx.output_filenames.path(OutputType::Object); let host_dir = host_path.parent().unwrap(); let out_obj = host_dir.join("host.o"); @@ -826,7 +826,9 @@ pub(crate) unsafe fn llvm_optimize( let llmod2 = llvm::LLVMCloneModule(module.module_llvm.llmod()); let ok = unsafe { llvm::LLVMRustOffloadEmbedBufferInModule(llmod2, host_out_c.as_ptr()) }; - assert!(ok, "LLVMRustOffloadEmbedBufferInModule failed"); + if !ok { + dcx.emit_err(crate::errors::OffloadEmbedFailed); + } write_output_file( dcx, module.module_llvm.tm.raw(), @@ -838,10 +840,6 @@ pub(crate) unsafe fn llvm_optimize( &cgcx.prof, true, ); - if !out_obj.exists() { - dbg!("{:?} does not exist!", out_obj); - panic!("FinalizeOffload failed!"); - } // We ignore cgcx.save_temps here and unconditionally always keep our `host.out` artifact. // Otherwise, recompiling the host code would fail since we deleted that device artifact // in the previous host compilation, which would be confusing at best. diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index b59067b9745b..c73140e041b6 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -52,6 +52,26 @@ pub(crate) struct OffloadWithoutEnable; #[diag(codegen_llvm_offload_without_fat_lto)] pub(crate) struct OffloadWithoutFatLTO; +#[derive(Diagnostic)] +#[diag(codegen_llvm_offload_no_abs_path)] +pub(crate) struct OffloadWithoutAbsPath; + +#[derive(Diagnostic)] +#[diag(codegen_llvm_offload_no_host_out)] +pub(crate) struct OffloadWrongFileName; + +#[derive(Diagnostic)] +#[diag(codegen_llvm_offload_nonexisting)] +pub(crate) struct OffloadNonexistingPath; + +#[derive(Diagnostic)] +#[diag(codegen_llvm_offload_bundleimages_failed)] +pub(crate) struct OffloadBundleImagesFailed; + +#[derive(Diagnostic)] +#[diag(codegen_llvm_offload_embed_failed)] +pub(crate) struct OffloadEmbedFailed; + #[derive(Diagnostic)] #[diag(codegen_llvm_lto_bitcode_from_rlib)] pub(crate) struct LtoBitcodeFromRlib { From 8e1d80305fd98ee7da1cb422d5da2495502e995d Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 9 Dec 2025 07:50:48 -0800 Subject: [PATCH 1184/3801] Update offloading docs to account for simplified usage --- src/doc/rustc-dev-guide/src/offload/usage.md | 23 +++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/offload/usage.md b/src/doc/rustc-dev-guide/src/offload/usage.md index d934de9049be..062534a4b655 100644 --- a/src/doc/rustc-dev-guide/src/offload/usage.md +++ b/src/doc/rustc-dev-guide/src/offload/usage.md @@ -77,28 +77,25 @@ pub extern "gpu-kernel" fn kernel_1(x: *mut [f64; 256]) { ## Compile instructions It is important to use a clang compiler build on the same llvm as rustc. Just calling clang without the full path will likely use your system clang, which probably will be incompatible. So either substitute clang/lld invocations below with absolute path, or set your `PATH` accordingly. -First we generate the host (cpu) code. The first build is just to compile libc, take note of the hashed path. Then we call rustc directly to build our host code, while providing the libc artifact to rustc. +First we generate the device (gpu) code. Replace the target-cpu with the right code for your gpu. ``` -cargo +offload build -r -v -rustc +offload --edition 2024 src/lib.rs -g --crate-type cdylib -C opt-level=3 -C panic=abort -C lto=fat -L dependency=/absolute_path_to/target/release/deps --extern libc=/absolute_path_to/target/release/deps/liblibc-.rlib --emit=llvm-bc,llvm-ir -Zoffload=Enable -Zunstable-options +RUSTFLAGS="-Ctarget-cpu=gfx90a --emit=llvm-bc,llvm-ir -Zoffload=Device -Csave-temps -Zunstable-options" cargo +offload build -Zunstable-options -r -v --target amdgcn-amd-amdhsa -Zbuild-std=core ``` +You might afterwards need to copy your target/release/deps/.bc to lib.bc for now, before the next step. -Now we generate the device code. Replace the target-cpu with the right code for your gpu. +Now we generate the host (cpu) code. ``` -RUSTFLAGS="-Ctarget-cpu=gfx90a --emit=llvm-bc,llvm-ir -Zoffload=Enable -Zunstable-options" cargo +offload build -Zunstable-options -r -v --target amdgcn-amd-amdhsa -Zbuild-std=core +RUSTFLAGS="--emit=llvm-bc,llvm-ir -Csave-temps -Zoffload=Host=/p/lustre1/drehwald1/prog/offload/r/target/amdgcn-amd-amdhsa/release/deps/host.out -Zunstable-options" cargo +offload build -r ``` - +This call also does a lot of work and generates multiple intermediate files for llvm offload. +While we integrated most offload steps into rustc by now, one binary invocation still remains for now: ``` -"clang-21" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-S" "-save-temps=cwd" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "lib.rs" "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-funwind-tables=2" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-resource-dir" "//rust/build/x86_64-unknown-linux-gnu/llvm/lib/clang/21" "-ferror-limit" "19" "-fopenmp" "-fopenmp-offload-mandatory" "-fgnuc-version=4.2.1" "-fskip-odr-check-in-gmf" "-fembed-offload-object=host.out" "-fopenmp-targets=amdgcn-amd-amdhsa" "-faddrsig" "-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o" "host.s" "-x" "ir" "lib.bc" - -"clang-21" "-cc1as" "-triple" "x86_64-unknown-linux-gnu" "-filetype" "obj" "-main-file-name" "lib.rs" "-target-cpu" "x86-64" "-mrelocation-model" "pic" "-o" "host.o" "host.s" - -"clang-linker-wrapper" "--should-extract=gfx90a" "--device-compiler=amdgcn-amd-amdhsa=-g" "--device-compiler=amdgcn-amd-amdhsa=-save-temps=cwd" "--device-linker=amdgcn-amd-amdhsa=-lompdevice" "--host-triple=x86_64-unknown-linux-gnu" "--save-temps" "--linker-path=/ABSOlUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/lld/bin/ld.lld" "--hash-style=gnu" "--eh-frame-hdr" "-m" "elf_x86_64" "-pie" "-dynamic-linker" "/lib64/ld-linux-x86-64.so.2" "-o" "bare" "/lib/../lib64/Scrt1.o" "/lib/../lib64/crti.o" "/ABSOLUTE_PATH_TO/crtbeginS.o" "-L/ABSOLUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/llvm/bin/../lib/x86_64-unknown-linux-gnu" "-L/ABSOLUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/llvm/lib/clang/21/lib/x86_64-unknown-linux-gnu" "-L/lib/../lib64" "-L/usr/lib64" "-L/lib" "-L/usr/lib" "host.o" "-lstdc++" "-lm" "-lomp" "-lomptarget" "-L/ABSOLUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/llvm/lib" "-lgcc_s" "-lgcc" "-lpthread" "-lc" "-lgcc_s" "-lgcc" "/ABSOLUTE_PATH_TO/crtendS.o" "/lib/../lib64/crtn.o" +"clang-linker-wrapper" "--should-extract=gfx90a" "--device-compiler=amdgcn-amd-amdhsa=-g" "--device-compiler=amdgcn-amd-amdhsa=-save-temps=cwd" "--device-linker=amdgcn-amd-amdhsa=-lompdevice" "--host-triple=x86_64-unknown-linux-gnu" "--save-temps" "--linker-path=/ABSOlUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/lld/bin/ld.lld" "--hash-style=gnu" "--eh-frame-hdr" "-m" "elf_x86_64" "-pie" "-dynamic-linker" "/lib64/ld-linux-x86-64.so.2" "-o" "bare" "/lib/../lib64/Scrt1.o" "/lib/../lib64/crti.o" "/ABSOLUTE_PATH_TO/crtbeginS.o" "-L/ABSOLUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/llvm/bin/../lib/x86_64-unknown-linux-gnu" "-L/ABSOLUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/llvm/lib/clang/21/lib/x86_64-unknown-linux-gnu" "-L/lib/../lib64" "-L/usr/lib64" "-L/lib" "-L/usr/lib" "target//release/host.o" "-lstdc++" "-lm" "-lomp" "-lomptarget" "-L/ABSOLUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/llvm/lib" "-lgcc_s" "-lgcc" "-lpthread" "-lc" "-lgcc_s" "-lgcc" "/ABSOLUTE_PATH_TO/crtendS.o" "/lib/../lib64/crtn.o" ``` -Especially for the last three commands I recommend to not fix the paths, but rather just re-generate them by copying a bare-mode openmp example and compiling it with your clang. By adding `-###` to your clang invocation, you can see the invidual steps. -You can ignore other steps, e.g. the invocation of a "clang-offload-packager". +You can try to find the paths to those files on your system. However, I recommend to not fix the paths, but rather just re-generate them by copying a bare-mode openmp example and compiling it with your clang. By adding `-###` to your clang invocation, you can see the invidual steps. +It will show multiple steps, just look for the clang-linker-wrapper example. Make sure to still include the path to the `host.o` file, and not whatever tmp file you got when compiling your c++ example with the following call. ``` myclang++ -fuse-ld=lld -O3 -fopenmp -fopenmp-offload-mandatory --offload-arch=gfx90a omp_bare.cpp -o main -### ``` From 8f3a76bd38f903503f29e895c78bab4a685d64ec Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Fri, 14 Nov 2025 08:57:41 +0000 Subject: [PATCH 1185/3801] mgca always resolve params --- .../src/hir_ty_lowering/mod.rs | 10 ++ compiler/rustc_hir_typeck/src/lib.rs | 12 ++ compiler/rustc_middle/src/hir/map.rs | 48 ++++++++ compiler/rustc_resolve/src/late.rs | 12 +- .../mgca/explicit_anon_consts.rs | 1 + .../mgca/explicit_anon_consts.stderr | 112 ++++++++---------- .../mgca/type_const-on-generic-expr.rs | 1 + .../mgca/type_const-on-generic-expr.stderr | 41 +++---- 8 files changed, 145 insertions(+), 92 deletions(-) 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 4db9a4c2bcdd..f7c7cf6634fd 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2378,6 +2378,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let expr = &tcx.hir_body(anon.body).value; debug!(?expr); + // If the rhs is an anon const naming generics it shouldn't have + // access to then we lower to `ConstKind::Error`. This prevents + // `try_lower_anon_const_lit` from ICEing on anon consts such as + // `const { N }` which aren't supposed to be legal. + if let ty::AnonConstKind::MCG = tcx.anon_const_kind(anon.def_id) + && let Err(e) = tcx.check_anon_const_invalid_param_uses(anon.def_id) + { + return ty::Const::new_error(tcx, e); + } + // FIXME(generic_const_parameter_types): We should use the proper generic args // here. It's only used as a hint for literals so doesn't matter too much to use the right // generic arguments, just weaker type inference. diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 39c28c4f4e99..b8a587016427 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -115,6 +115,18 @@ fn typeck_with_inspect<'tcx>( return tcx.typeck(typeck_root_def_id); } + // We can't handle bodies containing generic parameters even though + // these generic parameters aren't part of its `generics_of` right now. + // + // See the FIXME on `check_anon_const_invalid_param_uses`. + if tcx.features().min_generic_const_args() + && let DefKind::AnonConst = tcx.def_kind(def_id) + && let ty::AnonConstKind::MCG = tcx.anon_const_kind(def_id) + && let Err(e) = tcx.check_anon_const_invalid_param_uses(def_id) + { + e.raise_fatal(); + } + let id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(id); let span = tcx.def_span(def_id); diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 5da762ef8565..9e639b243f28 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -2,6 +2,8 @@ //! eliminated, and all its methods are now on `TyCtxt`. But the module name //! stays as `map` because there isn't an obviously better name for it. +use std::ops::ControlFlow; + use rustc_abi::ExternAbi; use rustc_ast::visit::{VisitorResult, walk_list}; use rustc_data_structures::fingerprint::Fingerprint; @@ -1086,6 +1088,52 @@ impl<'tcx> TyCtxt<'tcx> { None } + + // FIXME(mgca): this is pretty iffy. In the long term we should make + // HIR ty lowering able to return `Error` versions of types/consts when + // lowering them in contexts that aren't supposed to use generic parameters. + // + // This current impl strategy is incomplete and doesn't handle `Self` ty aliases. + pub fn check_anon_const_invalid_param_uses( + self, + anon: LocalDefId, + ) -> Result<(), ErrorGuaranteed> { + struct GenericParamVisitor<'tcx>(TyCtxt<'tcx>); + impl<'tcx> Visitor<'tcx> for GenericParamVisitor<'tcx> { + type NestedFilter = nested_filter::OnlyBodies; + type Result = ControlFlow; + + fn maybe_tcx(&mut self) -> TyCtxt<'tcx> { + self.0 + } + + fn visit_path( + &mut self, + path: &crate::hir::Path<'tcx>, + _id: HirId, + ) -> ControlFlow { + if let Res::Def( + DefKind::TyParam | DefKind::ConstParam | DefKind::LifetimeParam, + _, + ) = path.res + { + let e = self.0.dcx().struct_span_err( + path.span, + "generic parameters may not be used in const operations", + ); + return ControlFlow::Break(e.emit()); + } + + intravisit::walk_path(self, path) + } + } + + let body = self.hir_maybe_body_owned_by(anon).unwrap(); + match GenericParamVisitor(self).visit_expr(&body.value) { + ControlFlow::Break(e) => Err(e), + ControlFlow::Continue(()) => Ok(()), + } + } } impl<'tcx> intravisit::HirTyCtxt<'tcx> for TyCtxt<'tcx> { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d3428a4af348..4fefcc66b588 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4879,12 +4879,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { constant, anon_const_kind ); - let is_trivial_const_arg = if self.r.tcx.features().min_generic_const_args() { - matches!(constant.mgca_disambiguation, MgcaDisambiguation::Direct) - } else { - constant.value.is_potential_trivial_const_arg() - }; - + let is_trivial_const_arg = constant.value.is_potential_trivial_const_arg(); self.resolve_anon_const_manual(is_trivial_const_arg, anon_const_kind, |this| { this.resolve_expr(&constant.value, None) }) @@ -4914,7 +4909,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes, AnonConstKind::InlineConst => ConstantHasGenerics::Yes, AnonConstKind::ConstArg(_) => { - if self.r.tcx.features().generic_const_exprs() || is_trivial_const_arg { + if self.r.tcx.features().generic_const_exprs() + || self.r.tcx.features().min_generic_const_args() + || is_trivial_const_arg + { ConstantHasGenerics::Yes } else { ConstantHasGenerics::No(NoConstantGenericsReason::NonTrivialConstArg) diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs index 31391b023bfe..ef17222ebc91 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -10,6 +10,7 @@ type Adt1 = Foo; type Adt2 = Foo<{ N }>; type Adt3 = Foo; //~^ ERROR: generic parameters may not be used in const operations +//~^^ ERROR generic parameters may not be used in const operations type Adt4 = Foo<{ 1 + 1 }>; //~^ ERROR: complex const arguments must be placed inside of a `const` block type Adt5 = Foo; diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index b3d960e315ea..eb200aae3396 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -1,92 +1,82 @@ -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:11:41 - | -LL | type Adt3 = Foo; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments here, i.e. `N` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:19:42 - | -LL | type Arr3 = [(); const { N }]; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments here, i.e. `N` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:28:27 - | -LL | let _3 = [(); const { N }]; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments here, i.e. `N` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:40:46 - | -LL | const ITEM3: usize = const { N }; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments here, i.e. `N` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:58:31 - | -LL | T3: Trait, - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments here, i.e. `N` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:67:58 - | -LL | struct Default3; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments here, i.e. `N` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:13:33 + --> $DIR/explicit_anon_consts.rs:14:33 | LL | type Adt4 = Foo<{ 1 + 1 }>; | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:21:34 + --> $DIR/explicit_anon_consts.rs:22:34 | LL | type Arr4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:30:19 + --> $DIR/explicit_anon_consts.rs:31:19 | LL | let _4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:43:38 + --> $DIR/explicit_anon_consts.rs:44:38 | LL | const ITEM4: usize = { 1 + 1 }; | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:60:23 + --> $DIR/explicit_anon_consts.rs:61:23 | LL | T4: Trait, | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:69:50 + --> $DIR/explicit_anon_consts.rs:70:50 | LL | struct Default4; | ^^^^^^^^^ -error: aborting due to 12 previous errors +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:11:41 + | +LL | type Adt3 = Foo; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:20:42 + | +LL | type Arr3 = [(); const { N }]; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:41:46 + | +LL | const ITEM3: usize = const { N }; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:59:31 + | +LL | T3: Trait, + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:68:58 + | +LL | struct Default3; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:29:27 + | +LL | let _3 = [(); const { N }]; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:11:41 + | +LL | type Adt3 = Foo; + | ^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 13 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs index 577fee084dbd..a1008fae9d16 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs @@ -4,6 +4,7 @@ #[type_const] const FREE1: usize = const { std::mem::size_of::() }; //~^ ERROR generic parameters may not be used in const operations +//~^^ ERROR generic parameters may not be used in const operations #[type_const] const FREE2: usize = const { I + 1 }; //~^ ERROR generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr index 8cef77e5b229..c77be158d0ef 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -2,46 +2,39 @@ error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic-expr.rs:5:53 | LL | const FREE1: usize = const { std::mem::size_of::() }; - | ^ cannot perform const operation using `T` - | - = note: type parameters may not be used in const expressions - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + | ^ error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:8:46 + --> $DIR/type_const-on-generic-expr.rs:9:46 | LL | const FREE2: usize = const { I + 1 }; - | ^ cannot perform const operation using `I` - | - = help: const parameters may only be used as standalone arguments here, i.e. `I` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + | ^ error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:24:54 + --> $DIR/type_const-on-generic-expr.rs:25:54 | LL | const N1: usize = const { std::mem::size_of::() }; - | ^ cannot perform const operation using `T` - | - = note: type parameters may not be used in const expressions - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + | ^ error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:27:47 + --> $DIR/type_const-on-generic-expr.rs:28:47 | LL | const N2: usize = const { I + 1 }; - | ^ cannot perform const operation using `I` - | - = help: const parameters may only be used as standalone arguments here, i.e. `I` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + | ^ error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:30:35 + --> $DIR/type_const-on-generic-expr.rs:31:35 | LL | const N3: usize = const { 2 & X }; - | ^ cannot perform const operation using `X` + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:5:53 | - = help: const parameters may only be used as standalone arguments here, i.e. `X` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions +LL | const FREE1: usize = const { std::mem::size_of::() }; + | ^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors From c65551e835f42d6b3cc28ebe37257ae7cfcbfe06 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 20 Nov 2025 02:16:43 +0000 Subject: [PATCH 1186/3801] Introduce `hir::ConstArgKind::Struct` --- compiler/rustc_ast_lowering/src/index.rs | 7 ++ compiler/rustc_ast_lowering/src/lib.rs | 41 +++++++++ compiler/rustc_hir/src/hir.rs | 13 +++ compiler/rustc_hir/src/intravisit.rs | 23 +++++ .../src/hir_ty_lowering/mod.rs | 3 + compiler/rustc_hir_pretty/src/lib.rs | 4 + compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + compiler/rustc_middle/src/hir/map.rs | 2 + compiler/rustc_middle/src/hir/mod.rs | 1 + compiler/rustc_resolve/src/def_collector.rs | 89 +++++++++++++++---- compiler/rustc_resolve/src/lib.rs | 9 ++ .../mgca/struct_expr_with_macros.rs | 31 +++++++ 12 files changed, 205 insertions(+), 19 deletions(-) create mode 100644 tests/ui/const-generics/mgca/struct_expr_with_macros.rs diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 8d7351d3a510..f6edcaa64dfe 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -281,6 +281,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { }); } + fn visit_const_arg_expr_field(&mut self, field: &'hir ConstArgExprField<'hir>) { + self.insert(field.span, field.hir_id, Node::ConstArgExprField(field)); + self.with_parent(field.hir_id, |this| { + intravisit::walk_const_arg_expr_field(this, field); + }) + } + fn visit_stmt(&mut self, stmt: &'hir Stmt<'hir>) { self.insert(stmt.span, stmt.hir_id, Node::Stmt(stmt)); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1bc8d7c25bb5..416fef8e3af3 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2410,6 +2410,47 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath) } } + ExprKind::Struct(se) => { + let path = self.lower_qpath( + expr.id, + &se.qself, + &se.path, + // FIXME(mgca): we may want this to be `Optional` instead, but + // we would also need to make sure that HIR ty lowering errors + // when these paths wind up in signatures. + ParamMode::Explicit, + AllowReturnTypeNotation::No, + ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, + ); + + let fields = self.arena.alloc_from_iter(se.fields.iter().map(|f| { + let hir_id = self.lower_node_id(f.id); + // FIXME(mgca): This might result in lowering attributes that + // then go unused as the `Target::ExprField` is not actually + // corresponding to `Node::ExprField`. + self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField); + + let expr = if let ExprKind::ConstBlock(anon_const) = &f.expr.kind { + let def_id = self.local_def_id(anon_const.id); + let def_kind = self.tcx.def_kind(def_id); + assert_eq!(DefKind::AnonConst, def_kind); + + self.lower_anon_const_to_const_arg_direct(anon_const) + } else { + self.lower_expr_to_const_arg_direct(&f.expr) + }; + + &*self.arena.alloc(hir::ConstArgExprField { + hir_id, + field: self.lower_ident(f.ident), + expr: self.arena.alloc(expr), + span: self.lower_span(f.span), + }) + })); + + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Struct(path, fields) } + } ExprKind::Underscore => ConstArg { hir_id: self.lower_node_id(expr.id), kind: hir::ConstArgKind::Infer(expr.span, ()), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index c60471848c89..e176c703b33e 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -494,6 +494,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> { pub fn span(&self) -> Span { match self.kind { + ConstArgKind::Struct(path, _) => path.span(), ConstArgKind::Path(path) => path.span(), ConstArgKind::Anon(anon) => anon.span, ConstArgKind::Error(span, _) => span, @@ -513,6 +514,8 @@ pub enum ConstArgKind<'hir, Unambig = ()> { /// However, in the future, we'll be using it for all of those. Path(QPath<'hir>), Anon(&'hir AnonConst), + /// Represents construction of struct/struct variants + Struct(QPath<'hir>, &'hir [&'hir ConstArgExprField<'hir>]), /// Error const Error(Span, ErrorGuaranteed), /// This variant is not always used to represent inference consts, sometimes @@ -520,6 +523,14 @@ pub enum ConstArgKind<'hir, Unambig = ()> { Infer(Span, Unambig), } +#[derive(Clone, Copy, Debug, HashStable_Generic)] +pub struct ConstArgExprField<'hir> { + pub hir_id: HirId, + pub span: Span, + pub field: Ident, + pub expr: &'hir ConstArg<'hir>, +} + #[derive(Clone, Copy, Debug, HashStable_Generic)] pub struct InferArg { #[stable_hasher(ignore)] @@ -4714,6 +4725,7 @@ pub enum Node<'hir> { ConstArg(&'hir ConstArg<'hir>), Expr(&'hir Expr<'hir>), ExprField(&'hir ExprField<'hir>), + ConstArgExprField(&'hir ConstArgExprField<'hir>), Stmt(&'hir Stmt<'hir>), PathSegment(&'hir PathSegment<'hir>), Ty(&'hir Ty<'hir>), @@ -4773,6 +4785,7 @@ impl<'hir> Node<'hir> { Node::AssocItemConstraint(c) => Some(c.ident), Node::PatField(f) => Some(f.ident), Node::ExprField(f) => Some(f.ident), + Node::ConstArgExprField(f) => Some(f.field), Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident), Node::Param(..) | Node::AnonConst(..) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index be3cab6461ef..e63f51f8e6a4 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -396,6 +396,9 @@ pub trait Visitor<'v>: Sized { fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result { walk_expr_field(self, field) } + fn visit_const_arg_expr_field(&mut self, field: &'v ConstArgExprField<'v>) -> Self::Result { + walk_const_arg_expr_field(self, field) + } fn visit_pattern_type_pattern(&mut self, p: &'v TyPat<'v>) -> Self::Result { walk_ty_pat(self, p) } @@ -954,6 +957,17 @@ pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField try_visit!(visitor.visit_ident(*ident)); visitor.visit_expr(*expr) } + +pub fn walk_const_arg_expr_field<'v, V: Visitor<'v>>( + visitor: &mut V, + field: &'v ConstArgExprField<'v>, +) -> V::Result { + let ConstArgExprField { hir_id, field, expr, span: _ } = field; + try_visit!(visitor.visit_id(*hir_id)); + try_visit!(visitor.visit_ident(*field)); + visitor.visit_const_arg_unambig(*expr) +} + /// We track whether an infer var is from a [`Ty`], [`ConstArg`], or [`GenericArg`] so that /// HIR visitors overriding [`Visitor::visit_infer`] can determine what kind of infer is being visited pub enum InferKind<'hir> { @@ -1068,6 +1082,15 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( let ConstArg { hir_id, kind } = const_arg; try_visit!(visitor.visit_id(*hir_id)); match kind { + ConstArgKind::Struct(qpath, field_exprs) => { + try_visit!(visitor.visit_qpath(qpath, *hir_id, qpath.span())); + + for field_expr in *field_exprs { + try_visit!(visitor.visit_const_arg_expr_field(field_expr)); + } + + V::Result::output() + } ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), ConstArgKind::Error(_, _) => V::Result::output(), // errors and spans are not important 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 f7c7cf6634fd..3c1200c812bc 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2263,6 +2263,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) .unwrap_or_else(|guar| Const::new_error(tcx, guar)) } + hir::ConstArgKind::Struct(..) => { + span_bug!(const_arg.span(), "lowering `{:?}` is not yet implemented", const_arg) + } hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon), hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span), hir::ConstArgKind::Error(_, e) => ty::Const::new_error(tcx, e), diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index b3b416955230..f99533922110 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -180,6 +180,8 @@ impl<'a> State<'a> { Node::ConstArg(a) => self.print_const_arg(a), Node::Expr(a) => self.print_expr(a), Node::ExprField(a) => self.print_expr_field(a), + // FIXME(mgca): proper printing for struct exprs + Node::ConstArgExprField(_) => self.word("/* STRUCT EXPR */"), Node::Stmt(a) => self.print_stmt(a), Node::PathSegment(a) => self.print_path_segment(a), Node::Ty(a) => self.print_type(a), @@ -1135,6 +1137,8 @@ impl<'a> State<'a> { fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) { match &const_arg.kind { + // FIXME(mgca): proper printing for struct exprs + ConstArgKind::Struct(..) => self.word("/* STRUCT EXPR */"), ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), ConstArgKind::Anon(anon) => self.print_anon_const(anon), ConstArgKind::Error(_, _) => self.word("/*ERROR*/"), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 94bc4d3fa530..920c896d5a47 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1440,6 +1440,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::Node::ConstArg(hir::ConstArg { kind, .. }) => match kind { // Skip encoding defs for these as they should not have had a `DefId` created hir::ConstArgKind::Error(..) + | hir::ConstArgKind::Struct(..) | hir::ConstArgKind::Path(..) | hir::ConstArgKind::Infer(..) => true, hir::ConstArgKind::Anon(..) => false, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 9e639b243f28..d62ddc915d17 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -739,6 +739,7 @@ impl<'tcx> TyCtxt<'tcx> { Node::ConstArg(_) => node_str("const"), Node::Expr(_) => node_str("expr"), Node::ExprField(_) => node_str("expr field"), + Node::ConstArgExprField(_) => node_str("const arg expr field"), Node::Stmt(_) => node_str("stmt"), Node::PathSegment(_) => node_str("path segment"), Node::Ty(_) => node_str("type"), @@ -1007,6 +1008,7 @@ impl<'tcx> TyCtxt<'tcx> { Node::ConstArg(const_arg) => const_arg.span(), Node::Expr(expr) => expr.span, Node::ExprField(field) => field.span, + Node::ConstArgExprField(field) => field.span, Node::Stmt(stmt) => stmt.span, Node::PathSegment(seg) => { let ident_span = seg.ident.span; diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 217ecbab059e..ba2d8febad7c 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -359,6 +359,7 @@ impl<'tcx> TyCtxt<'tcx> { | Node::Infer(_) | Node::WherePredicate(_) | Node::PreciseCapturingNonLifetimeArg(_) + | Node::ConstArgExprField(_) | Node::OpaqueTy(_) => { unreachable!("no sub-expr expected for {parent_node:?}") } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 71bbd64ddc6c..b50fc201bdb8 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -11,9 +11,9 @@ use rustc_hir::def_id::LocalDefId; use rustc_middle::span_bug; use rustc_span::hygiene::LocalExpnId; use rustc_span::{Span, Symbol, sym}; -use tracing::debug; +use tracing::{debug, instrument}; -use crate::{ImplTraitContext, InvocationParent, Resolver}; +use crate::{ConstArgContext, ImplTraitContext, InvocationParent, Resolver}; pub(crate) fn collect_definitions( resolver: &mut Resolver<'_, '_>, @@ -21,6 +21,7 @@ pub(crate) fn collect_definitions( expansion: LocalExpnId, ) { let invocation_parent = resolver.invocation_parents[&expansion]; + debug!("new fragment to visit with invocation_parent: {invocation_parent:?}"); let mut visitor = DefCollector { resolver, expansion, invocation_parent }; fragment.visit_with(&mut visitor); } @@ -74,6 +75,12 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { self.invocation_parent.impl_trait_context = orig_itc; } + fn with_const_arg(&mut self, ctxt: ConstArgContext, f: F) { + let orig = mem::replace(&mut self.invocation_parent.const_arg_context, ctxt); + f(self); + self.invocation_parent.const_arg_context = orig; + } + fn collect_field(&mut self, field: &'a FieldDef, index: Option) { let index = |this: &Self| { index.unwrap_or_else(|| { @@ -93,7 +100,10 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { } } + #[instrument(level = "debug", skip(self))] fn visit_macro_invoc(&mut self, id: NodeId) { + debug!(?self.invocation_parent); + let id = id.placeholder_to_expn_id(); let old_parent = self.resolver.invocation_parents.insert(id, self.invocation_parent); assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation"); @@ -360,36 +370,77 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so // to avoid affecting stable we have to feature gate the not creating // anon consts - if let MgcaDisambiguation::Direct = constant.mgca_disambiguation - && self.resolver.tcx.features().min_generic_const_args() - { - visit::walk_anon_const(self, constant); - return; + if !self.resolver.tcx.features().min_generic_const_args() { + let parent = + self.create_def(constant.id, None, DefKind::AnonConst, constant.value.span); + return self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); } - let parent = self.create_def(constant.id, None, DefKind::AnonConst, constant.value.span); - self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); + match constant.mgca_disambiguation { + MgcaDisambiguation::Direct => self.with_const_arg(ConstArgContext::Direct, |this| { + visit::walk_anon_const(this, constant); + }), + MgcaDisambiguation::AnonConst => { + self.with_const_arg(ConstArgContext::NonDirect, |this| { + let parent = + this.create_def(constant.id, None, DefKind::AnonConst, constant.value.span); + this.with_parent(parent, |this| visit::walk_anon_const(this, constant)); + }) + } + }; } + #[instrument(level = "debug", skip(self))] fn visit_expr(&mut self, expr: &'a Expr) { - let parent_def = match expr.kind { + debug!(?self.invocation_parent); + + let parent_def = match &expr.kind { ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id), ExprKind::Closure(..) | ExprKind::Gen(..) => { self.create_def(expr.id, None, DefKind::Closure, expr.span) } - ExprKind::ConstBlock(ref constant) => { - for attr in &expr.attrs { - visit::walk_attribute(self, attr); - } - let def = - self.create_def(constant.id, None, DefKind::InlineConst, constant.value.span); - self.with_parent(def, |this| visit::walk_anon_const(this, constant)); - return; + ExprKind::ConstBlock(constant) => { + // Under `min_generic_const_args` a `const { }` block sometimes + // corresponds to an anon const rather than an inline const. + let def_kind = match self.invocation_parent.const_arg_context { + ConstArgContext::Direct => DefKind::AnonConst, + ConstArgContext::NonDirect => DefKind::InlineConst, + }; + + return self.with_const_arg(ConstArgContext::NonDirect, |this| { + for attr in &expr.attrs { + visit::walk_attribute(this, attr); + } + + let def = this.create_def(constant.id, None, def_kind, constant.value.span); + this.with_parent(def, |this| visit::walk_anon_const(this, constant)); + }); } + + // Avoid overwriting `const_arg_context` as we may want to treat const blocks + // as being anon consts if we are inside a const argument. + ExprKind::Struct(_) => return visit::walk_expr(self, expr), + // FIXME(mgca): we may want to handle block labels in some manner + ExprKind::Block(block, _) if let [stmt] = block.stmts.as_slice() => match stmt.kind { + // FIXME(mgca): this probably means that mac calls that expand + // to semi'd const blocks are handled differently to just writing + // out a semi'd const block. + StmtKind::Expr(..) | StmtKind::MacCall(..) => return visit::walk_expr(self, expr), + + // Fallback to normal behaviour + StmtKind::Let(..) | StmtKind::Item(..) | StmtKind::Semi(..) | StmtKind::Empty => { + self.invocation_parent.parent_def + } + }, + _ => self.invocation_parent.parent_def, }; - self.with_parent(parent_def, |this| visit::walk_expr(this, expr)) + self.with_const_arg(ConstArgContext::NonDirect, |this| { + // Note in some cases the `parent_def` here may be the existing parent + // and this is actually a no-op `with_parent` call. + this.with_parent(parent_def, |this| visit::walk_expr(this, expr)) + }) } fn visit_ty(&mut self, ty: &'a Ty) { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index c981abe67c1f..57f19f7ea398 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -187,6 +187,7 @@ struct InvocationParent { parent_def: LocalDefId, impl_trait_context: ImplTraitContext, in_attr: bool, + const_arg_context: ConstArgContext, } impl InvocationParent { @@ -194,6 +195,7 @@ impl InvocationParent { parent_def: CRATE_DEF_ID, impl_trait_context: ImplTraitContext::Existential, in_attr: false, + const_arg_context: ConstArgContext::NonDirect, }; } @@ -204,6 +206,13 @@ enum ImplTraitContext { InBinding, } +#[derive(Copy, Clone, Debug)] +enum ConstArgContext { + Direct, + /// Either inside of an `AnonConst` or not inside a const argument at all. + NonDirect, +} + /// Used for tracking import use types which will be used for redundant import checking. /// /// ### Used::Scope Example diff --git a/tests/ui/const-generics/mgca/struct_expr_with_macros.rs b/tests/ui/const-generics/mgca/struct_expr_with_macros.rs new file mode 100644 index 000000000000..b59a73066488 --- /dev/null +++ b/tests/ui/const-generics/mgca/struct_expr_with_macros.rs @@ -0,0 +1,31 @@ +//@ check-pass + +// Test that the def collector makes `AnonConst`s not `InlineConst`s even +// when the const block is obscured via macros. + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +macro_rules! const_block { + ($e:expr) => { const { + $e + } } +} + +macro_rules! foo_expr { + ($e:expr) => { Foo { + field: $e, + } } +} + +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct Foo { field: u32 } + +fn foo() {} + +fn main() { + foo::<{ Foo { field: const_block!{ 1 + 1 }} }>(); + foo::<{ foo_expr! { const_block! { 1 + 1 }} }>(); +} From 6722805cdc9f0a73aaad56729383510047788320 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 19 Nov 2025 19:30:09 +0000 Subject: [PATCH 1187/3801] Make `ValTree` recurse through `ty::Const` --- .../src/intrinsics/simd.rs | 17 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 14 +- .../rustc_codegen_ssa/src/mir/constant.rs | 19 +-- .../rustc_codegen_ssa/src/mir/intrinsic.rs | 2 +- .../src/const_eval/valtrees.rs | 31 ++-- .../src/interpret/intrinsics/simd.rs | 12 +- compiler/rustc_middle/src/arena.rs | 2 +- compiler/rustc_middle/src/mir/consts.rs | 27 +-- compiler/rustc_middle/src/thir.rs | 8 +- compiler/rustc_middle/src/ty/consts.rs | 42 ++++- .../rustc_middle/src/ty/consts/valtree.rs | 157 +++++++++--------- compiler/rustc_middle/src/ty/context.rs | 5 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/pattern.rs | 2 +- .../rustc_middle/src/ty/structural_impls.rs | 33 +++- .../src/builder/custom/parse/instruction.rs | 2 +- .../src/builder/matches/mod.rs | 15 +- .../src/builder/matches/test.rs | 2 +- compiler/rustc_mir_build/src/builder/scope.rs | 9 +- compiler/rustc_mir_build/src/thir/constant.rs | 2 +- .../src/thir/pattern/const_to_pat.rs | 28 ++-- compiler/rustc_pattern_analysis/src/rustc.rs | 20 +-- compiler/rustc_symbol_mangling/src/legacy.rs | 2 +- compiler/rustc_transmute/src/lib.rs | 9 +- compiler/rustc_ty_utils/src/consts.rs | 14 +- compiler/rustc_type_ir/src/const_kind.rs | 73 ++++++++ compiler/rustc_type_ir/src/flags.rs | 12 +- compiler/rustc_type_ir/src/inherent.rs | 6 + compiler/rustc_type_ir/src/interner.rs | 3 +- compiler/rustc_type_ir/src/relate.rs | 16 +- ...transmute_infinitely_recursive_type.stderr | 2 +- 31 files changed, 371 insertions(+), 217 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 0bce31beb8b8..38e8d2fa9368 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -143,7 +143,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let total_len = lane_count * 2; - let indexes = idx.iter().map(|idx| idx.unwrap_leaf().to_u32()).collect::>(); + let indexes = idx.iter().map(|idx| idx.to_leaf().to_u32()).collect::>(); for &idx in &indexes { assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len); @@ -961,9 +961,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ptr_val = ptr.load_scalar(fx); - let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); + let alignment = + generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); let memflags = match alignment { SimdAlign::Unaligned => MemFlags::new().with_notrap(), @@ -1006,9 +1005,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ret_lane_layout = fx.layout_of(ret_lane_ty); - let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); + let alignment = + generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); let memflags = match alignment { SimdAlign::Unaligned => MemFlags::new().with_notrap(), @@ -1059,9 +1057,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let ret_lane_layout = fx.layout_of(ret_lane_ty); let ptr_val = ptr.load_scalar(fx); - let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); + let alignment = + generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); let memflags = match alignment { SimdAlign::Unaligned => MemFlags::new().with_notrap(), diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 3bc890310cc8..215738828c98 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -351,7 +351,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { _ => bug!(), }; let ptr = args[0].immediate(); - let locality = fn_args.const_at(1).to_value().valtree.unwrap_leaf().to_i32(); + let locality = fn_args.const_at(1).to_leaf().to_i32(); self.call_intrinsic( "llvm.prefetch", &[self.val_ty(ptr)], @@ -1533,7 +1533,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } if name == sym::simd_shuffle_const_generic { - let idx = fn_args[2].expect_const().to_value().valtree.unwrap_branch(); + let idx = fn_args[2].expect_const().to_branch(); let n = idx.len() as u64; let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn); @@ -1552,7 +1552,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( .iter() .enumerate() .map(|(arg_idx, val)| { - let idx = val.unwrap_leaf().to_i32(); + let idx = val.to_leaf().to_i32(); if idx >= i32::try_from(total_len).unwrap() { bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds { span, @@ -1964,9 +1964,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // those lanes whose `mask` bit is enabled. // The memory addresses corresponding to the “off” lanes are not accessed. - let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); + let alignment = fn_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); // The element type of the "mask" argument must be a signed integer type of any width let mask_ty = in_ty; @@ -2059,9 +2057,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // those lanes whose `mask` bit is enabled. // The memory addresses corresponding to the “off” lanes are not accessed. - let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); + let alignment = fn_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); // The element type of the "mask" argument must be a signed integer type of any width let mask_ty = in_ty; diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 11b6ab3cdf1a..abdac4c7c372 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -77,22 +77,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .flatten() .map(|val| { // A SIMD type has a single field, which is an array. - let fields = val.unwrap_branch(); + let fields = val.to_branch(); assert_eq!(fields.len(), 1); - let array = fields[0].unwrap_branch(); + let array = fields[0].to_branch(); // Iterate over the array elements to obtain the values in the vector. let values: Vec<_> = array .iter() .map(|field| { - if let Some(prim) = field.try_to_scalar() { - let layout = bx.layout_of(field_ty); - let BackendRepr::Scalar(scalar) = layout.backend_repr else { - bug!("from_const: invalid ByVal layout: {:#?}", layout); - }; - bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout)) - } else { + let Some(prim) = field.try_to_scalar() else { bug!("field is not a scalar {:?}", field) - } + }; + let layout = bx.layout_of(field_ty); + let BackendRepr::Scalar(scalar) = layout.backend_repr else { + bug!("from_const: invalid ByVal layout: {:#?}", layout); + }; + bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout)) }) .collect(); bx.const_vector(&values) diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index aeb740118234..f4fae40d8828 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -102,7 +102,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let parse_atomic_ordering = |ord: ty::Value<'tcx>| { - let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf(); + let discr = ord.to_branch()[0].to_leaf(); discr.to_atomic_ordering() }; diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 7c41258ebfe5..b771addb8df5 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -36,13 +36,17 @@ fn branches<'tcx>( // For enums, we prepend their variant index before the variant's fields so we can figure out // the variant again when just seeing a valtree. if let Some(variant) = variant { - branches.push(ty::ValTree::from_scalar_int(*ecx.tcx, variant.as_u32().into())); + branches.push(ty::Const::new_value( + *ecx.tcx, + ty::ValTree::from_scalar_int(*ecx.tcx, variant.as_u32().into()), + ecx.tcx.types.u32, + )); } for i in 0..field_count { let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap(); let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?; - branches.push(valtree); + branches.push(ty::Const::new_value(*ecx.tcx, valtree, field.layout.ty)); } // Have to account for ZSTs here @@ -65,7 +69,7 @@ fn slice_branches<'tcx>( for i in 0..n { let place_elem = ecx.project_index(place, i).unwrap(); let valtree = const_to_valtree_inner(ecx, &place_elem, num_nodes)?; - elems.push(valtree); + elems.push(ty::Const::new_value(*ecx.tcx, valtree, place_elem.layout.ty)); } Ok(ty::ValTree::from_branches(*ecx.tcx, elems)) @@ -200,8 +204,8 @@ fn reconstruct_place_meta<'tcx>( &ObligationCause::dummy(), |ty| ty, || { - let branches = last_valtree.unwrap_branch(); - last_valtree = *branches.last().unwrap(); + let branches = last_valtree.to_branch(); + last_valtree = branches.last().unwrap().to_value().valtree; debug!(?branches, ?last_valtree); }, ); @@ -212,7 +216,7 @@ fn reconstruct_place_meta<'tcx>( }; // Get the number of elements in the unsized field. - let num_elems = last_valtree.unwrap_branch().len(); + let num_elems = last_valtree.to_branch().len(); MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx)) } @@ -274,7 +278,7 @@ pub fn valtree_to_const_value<'tcx>( mir::ConstValue::ZeroSized } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(_, _) => { - mir::ConstValue::Scalar(Scalar::Int(cv.valtree.unwrap_leaf())) + mir::ConstValue::Scalar(Scalar::Int(cv.to_leaf())) } ty::Pat(ty, _) => { let cv = ty::Value { valtree: cv.valtree, ty }; @@ -301,12 +305,13 @@ pub fn valtree_to_const_value<'tcx>( || matches!(cv.ty.kind(), ty::Adt(def, _) if def.is_struct())) { // A Scalar tuple/struct; we can avoid creating an allocation. - let branches = cv.valtree.unwrap_branch(); + let branches = cv.to_branch(); // Find the non-ZST field. (There can be aligned ZST!) for (i, &inner_valtree) in branches.iter().enumerate() { let field = layout.field(&LayoutCx::new(tcx, typing_env), i); if !field.is_zst() { - let cv = ty::Value { valtree: inner_valtree, ty: field.ty }; + let cv = + ty::Value { valtree: inner_valtree.to_value().valtree, ty: field.ty }; return valtree_to_const_value(tcx, typing_env, cv); } } @@ -381,7 +386,7 @@ fn valtree_into_mplace<'tcx>( // Zero-sized type, nothing to do. } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(..) => { - let scalar_int = valtree.unwrap_leaf(); + let scalar_int = valtree.to_leaf(); debug!("writing trivial valtree {:?} to place {:?}", scalar_int, place); ecx.write_immediate(Immediate::Scalar(scalar_int.into()), place).unwrap(); } @@ -391,13 +396,13 @@ fn valtree_into_mplace<'tcx>( ecx.write_immediate(imm, place).unwrap(); } ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Str | ty::Slice(_) => { - let branches = valtree.unwrap_branch(); + let branches = valtree.to_branch(); // Need to downcast place for enums let (place_adjusted, branches, variant_idx) = match ty.kind() { ty::Adt(def, _) if def.is_enum() => { // First element of valtree corresponds to variant - let scalar_int = branches[0].unwrap_leaf(); + let scalar_int = branches[0].to_leaf(); let variant_idx = VariantIdx::from_u32(scalar_int.to_u32()); let variant = def.variant(variant_idx); debug!(?variant); @@ -425,7 +430,7 @@ fn valtree_into_mplace<'tcx>( }; debug!(?place_inner); - valtree_into_mplace(ecx, &place_inner, *inner_valtree); + valtree_into_mplace(ecx, &place_inner, inner_valtree.to_value().valtree); dump_place(ecx, &place_inner); } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index 20de47683122..33a115384a88 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -545,7 +545,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let (right, right_len) = self.project_to_simd(&args[1])?; let (dest, dest_len) = self.project_to_simd(&dest)?; - let index = generic_args[2].expect_const().to_value().valtree.unwrap_branch(); + let index = generic_args[2].expect_const().to_branch(); let index_len = index.len(); assert_eq!(left_len, right_len); @@ -553,7 +553,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { for i in 0..dest_len { let src_index: u64 = - index[usize::try_from(i).unwrap()].unwrap_leaf().to_u32().into(); + index[usize::try_from(i).unwrap()].to_leaf().to_u32().into(); let dest = self.project_index(&dest, i)?; let val = if src_index < left_len { @@ -657,9 +657,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.check_simd_ptr_alignment( ptr, dest_layout, - generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(), + generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(), )?; for i in 0..dest_len { @@ -689,9 +687,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.check_simd_ptr_alignment( ptr, args[2].layout, - generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(), + generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(), )?; for i in 0..vals_len { diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index d1d4c32184ee..4fa39eb83e9e 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -92,7 +92,7 @@ macro_rules! arena_types { [] name_set: rustc_data_structures::unord::UnordSet, [] autodiff_item: rustc_ast::expand::autodiff_attrs::AutoDiffItem, [] ordered_name_set: rustc_data_structures::fx::FxIndexSet, - [] valtree: rustc_middle::ty::ValTreeKind<'tcx>, + [] valtree: rustc_middle::ty::ValTreeKind>, [] stable_order_of_exportable_impls: rustc_data_structures::fx::FxIndexMap, diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index fe352df3b9f0..afe39e4481ef 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -302,15 +302,7 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn try_to_scalar(self) -> Option { match self { - Const::Ty(_, c) => match c.kind() { - ty::ConstKind::Value(cv) if cv.ty.is_primitive() => { - // A valtree of a type where leaves directly represent the scalar const value. - // Just checking whether it is a leaf is insufficient as e.g. references are leafs - // but the leaf value is the value they point to, not the reference itself! - Some(cv.valtree.unwrap_leaf().into()) - } - _ => None, - }, + Const::Ty(_, c) => c.try_to_scalar(), Const::Val(val, _) => val.try_to_scalar(), Const::Unevaluated(..) => None, } @@ -321,10 +313,7 @@ impl<'tcx> Const<'tcx> { // This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster. match self { Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x), - Const::Ty(_, c) => match c.kind() { - ty::ConstKind::Value(cv) if cv.ty.is_primitive() => Some(cv.valtree.unwrap_leaf()), - _ => None, - }, + Const::Ty(_, c) => c.try_to_leaf(), _ => None, } } @@ -377,14 +366,10 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ) -> Option { - if let Const::Ty(_, c) = self - && let ty::ConstKind::Value(cv) = c.kind() - && cv.ty.is_primitive() - { - // Avoid the `valtree_to_const_val` query. Can only be done on primitive types that - // are valtree leaves, and *not* on references. (References should return the - // pointer here, which valtrees don't represent.) - Some(cv.valtree.unwrap_leaf().into()) + if let Const::Ty(_, c) = self { + // We don't evaluate anything for type system constants as normalizing + // the MIR will handle this for us + c.try_to_scalar() } else { self.eval(tcx, typing_env, DUMMY_SP).ok()?.try_to_scalar() } diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 3d893bf75e0b..31745cae3c06 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -928,7 +928,7 @@ impl<'tcx> PatRange<'tcx> { let lo_is_min = match self.lo { PatRangeBoundary::NegInfinity => true, PatRangeBoundary::Finite(value) => { - let lo = value.try_to_scalar_int().unwrap().to_bits(size) ^ bias; + let lo = value.to_leaf().to_bits(size) ^ bias; lo <= min } PatRangeBoundary::PosInfinity => false, @@ -937,7 +937,7 @@ impl<'tcx> PatRange<'tcx> { let hi_is_max = match self.hi { PatRangeBoundary::NegInfinity => false, PatRangeBoundary::Finite(value) => { - let hi = value.try_to_scalar_int().unwrap().to_bits(size) ^ bias; + let hi = value.to_leaf().to_bits(size) ^ bias; hi > max || hi == max && self.end == RangeEnd::Included } PatRangeBoundary::PosInfinity => true, @@ -1029,7 +1029,7 @@ impl<'tcx> PatRangeBoundary<'tcx> { } pub fn to_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> u128 { match self { - Self::Finite(value) => value.try_to_scalar_int().unwrap().to_bits_unchecked(), + Self::Finite(value) => value.to_leaf().to_bits_unchecked(), Self::NegInfinity => { // Unwrap is ok because the type is known to be numeric. ty.numeric_min_and_max_as_bits(tcx).unwrap().0 @@ -1057,7 +1057,7 @@ impl<'tcx> PatRangeBoundary<'tcx> { // many ranges such as '\u{037A}'..='\u{037F}', and chars can be compared // in this way. (Finite(a), Finite(b)) if matches!(ty.kind(), ty::Int(_) | ty::Uint(_) | ty::Char) => { - if let (Some(a), Some(b)) = (a.try_to_scalar_int(), b.try_to_scalar_int()) { + if let (Some(a), Some(b)) = (a.try_to_leaf(), b.try_to_leaf()) { let sz = ty.primitive_size(tcx); let cmp = match ty.kind() { ty::Uint(_) | ty::Char => a.to_uint(sz).cmp(&b.to_uint(sz)), diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 787ea5f9363d..da3caf0bb210 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -6,6 +6,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_type_ir::walk::TypeWalker; use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo}; +use crate::mir::interpret::Scalar; use crate::ty::{self, Ty, TyCtxt}; mod int; @@ -260,7 +261,7 @@ impl<'tcx> Const<'tcx> { /// Attempts to convert to a value. /// - /// Note that this does not evaluate the constant. + /// Note that this does not normalize the constant. pub fn try_to_value(self) -> Option> { match self.kind() { ty::ConstKind::Value(cv) => Some(cv), @@ -268,6 +269,45 @@ impl<'tcx> Const<'tcx> { } } + /// Converts to a `ValTreeKind::Leaf` value, `panic`'ing + /// if this constant is some other kind. + /// + /// Note that this does not normalize the constant. + #[inline] + pub fn to_leaf(self) -> ScalarInt { + self.to_value().to_leaf() + } + + /// Converts to a `ValTreeKind::Branch` value, `panic`'ing + /// if this constant is some other kind. + /// + /// Note that this does not normalize the constant. + #[inline] + pub fn to_branch(self) -> &'tcx [ty::Const<'tcx>] { + self.to_value().to_branch() + } + + /// Attempts to convert to a `ValTreeKind::Leaf` value. + /// + /// Note that this does not normalize the constant. + pub fn try_to_leaf(self) -> Option { + self.try_to_value()?.try_to_leaf() + } + + /// Attempts to convert to a `ValTreeKind::Leaf` value. + /// + /// Note that this does not normalize the constant. + pub fn try_to_scalar(self) -> Option { + self.try_to_leaf().map(Scalar::Int) + } + + /// Attempts to convert to a `ValTreeKind::Branch` value. + /// + /// Note that this does not normalize the constant. + pub fn try_to_branch(self) -> Option<&'tcx [ty::Const<'tcx>]> { + self.try_to_value()?.try_to_branch() + } + /// Convenience method to extract the value of a usize constant, /// useful to get the length of an array type. /// diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index a14e47d70821..8afee2dfe3bc 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -3,89 +3,38 @@ use std::ops::Deref; use rustc_data_structures::intern::Interned; use rustc_hir::def::Namespace; -use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; +use rustc_macros::{ + HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, extension, +}; use super::ScalarInt; use crate::mir::interpret::{ErrorHandled, Scalar}; use crate::ty::print::{FmtPrinter, PrettyPrinter}; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt, ValTreeKind}; -/// This datastructure is used to represent the value of constants used in the type system. -/// -/// We explicitly choose a different datastructure from the way values are processed within -/// CTFE, as in the type system equal values (according to their `PartialEq`) must also have -/// equal representation (`==` on the rustc data structure, e.g. `ValTree`) and vice versa. -/// Since CTFE uses `AllocId` to represent pointers, it often happens that two different -/// `AllocId`s point to equal values. So we may end up with different representations for -/// two constants whose value is `&42`. Furthermore any kind of struct that has padding will -/// have arbitrary values within that padding, even if the values of the struct are the same. -/// -/// `ValTree` does not have this problem with representation, as it only contains integers or -/// lists of (nested) `ValTree`. -#[derive(Clone, Debug, Hash, Eq, PartialEq)] -#[derive(HashStable, TyEncodable, TyDecodable)] -pub enum ValTreeKind<'tcx> { - /// integers, `bool`, `char` are represented as scalars. - /// See the `ScalarInt` documentation for how `ScalarInt` guarantees that equal values - /// of these types have the same representation. - Leaf(ScalarInt), - - //SliceOrStr(ValSlice<'tcx>), - // don't use SliceOrStr for now - /// The fields of any kind of aggregate. Structs, tuples and arrays are represented by - /// listing their fields' values in order. - /// - /// Enums are represented by storing their variant index as a u32 field, followed by all - /// the fields of the variant. - /// - /// ZST types are represented as an empty slice. - Branch(Box<[ValTree<'tcx>]>), -} - -impl<'tcx> ValTreeKind<'tcx> { - #[inline] - pub fn unwrap_leaf(&self) -> ScalarInt { - match self { - Self::Leaf(s) => *s, - _ => bug!("expected leaf, got {:?}", self), - } - } - - #[inline] - pub fn unwrap_branch(&self) -> &[ValTree<'tcx>] { - match self { - Self::Branch(branch) => &**branch, - _ => bug!("expected branch, got {:?}", self), - } - } - - pub fn try_to_scalar(&self) -> Option { - self.try_to_scalar_int().map(Scalar::Int) - } - - pub fn try_to_scalar_int(&self) -> Option { - match self { - Self::Leaf(s) => Some(*s), - Self::Branch(_) => None, - } - } - - pub fn try_to_branch(&self) -> Option<&[ValTree<'tcx>]> { - match self { - Self::Branch(branch) => Some(&**branch), - Self::Leaf(_) => None, - } +#[extension(pub trait ValTreeKindExt<'tcx>)] +impl<'tcx> ty::ValTreeKind> { + fn try_to_scalar(&self) -> Option { + self.try_to_leaf().map(Scalar::Int) } } /// An interned valtree. Use this rather than `ValTreeKind`, whenever possible. /// -/// See the docs of [`ValTreeKind`] or the [dev guide] for an explanation of this type. +/// See the docs of [`ty::ValTreeKind`] or the [dev guide] for an explanation of this type. /// /// [dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html#valtrees #[derive(Copy, Clone, Hash, Eq, PartialEq)] #[derive(HashStable)] -pub struct ValTree<'tcx>(pub(crate) Interned<'tcx, ValTreeKind<'tcx>>); +// FIXME(mgca): Try not interning here. We already intern `ty::Const` which `ValTreeKind` +// recurses through +pub struct ValTree<'tcx>(pub(crate) Interned<'tcx, ty::ValTreeKind>>); + +impl<'tcx> rustc_type_ir::inherent::ValTree> for ValTree<'tcx> { + fn kind(&self) -> &ty::ValTreeKind> { + &self + } +} impl<'tcx> ValTree<'tcx> { /// Returns the zero-sized valtree: `Branch([])`. @@ -94,28 +43,33 @@ impl<'tcx> ValTree<'tcx> { } pub fn is_zst(self) -> bool { - matches!(*self, ValTreeKind::Branch(box [])) + matches!(*self, ty::ValTreeKind::Branch(box [])) } pub fn from_raw_bytes(tcx: TyCtxt<'tcx>, bytes: &[u8]) -> Self { - let branches = bytes.iter().map(|&b| Self::from_scalar_int(tcx, b.into())); + let branches = bytes.iter().map(|&b| { + ty::Const::new_value(tcx, Self::from_scalar_int(tcx, b.into()), tcx.types.u8) + }); Self::from_branches(tcx, branches) } - pub fn from_branches(tcx: TyCtxt<'tcx>, branches: impl IntoIterator) -> Self { - tcx.intern_valtree(ValTreeKind::Branch(branches.into_iter().collect())) + pub fn from_branches( + tcx: TyCtxt<'tcx>, + branches: impl IntoIterator>, + ) -> Self { + tcx.intern_valtree(ty::ValTreeKind::Branch(branches.into_iter().collect())) } pub fn from_scalar_int(tcx: TyCtxt<'tcx>, i: ScalarInt) -> Self { - tcx.intern_valtree(ValTreeKind::Leaf(i)) + tcx.intern_valtree(ty::ValTreeKind::Leaf(i)) } } impl<'tcx> Deref for ValTree<'tcx> { - type Target = &'tcx ValTreeKind<'tcx>; + type Target = &'tcx ty::ValTreeKind>; #[inline] - fn deref(&self) -> &&'tcx ValTreeKind<'tcx> { + fn deref(&self) -> &&'tcx ty::ValTreeKind> { &self.0.0 } } @@ -154,7 +108,7 @@ impl<'tcx> Value<'tcx> { let (ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Float(_)) = self.ty.kind() else { return None; }; - let scalar = self.valtree.try_to_scalar_int()?; + let scalar = self.try_to_leaf()?; let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(self.ty); let size = tcx.layout_of(input).ok()?.size; Some(scalar.to_bits(size)) @@ -164,14 +118,14 @@ impl<'tcx> Value<'tcx> { if !self.ty.is_bool() { return None; } - self.valtree.try_to_scalar_int()?.try_to_bool().ok() + self.try_to_leaf()?.try_to_bool().ok() } pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { if !self.ty.is_usize() { return None; } - self.valtree.try_to_scalar_int().map(|s| s.to_target_usize(tcx)) + self.try_to_leaf().map(|s| s.to_target_usize(tcx)) } /// Get the values inside the ValTree as a slice of bytes. This only works for @@ -192,9 +146,48 @@ impl<'tcx> Value<'tcx> { _ => return None, } - Some(tcx.arena.alloc_from_iter( - self.valtree.unwrap_branch().into_iter().map(|v| v.unwrap_leaf().to_u8()), - )) + Some(tcx.arena.alloc_from_iter(self.to_branch().into_iter().map(|ct| ct.to_leaf().to_u8()))) + } + + /// Converts to a `ValTreeKind::Leaf` value, `panic`'ing + /// if this constant is some other kind. + #[inline] + pub fn to_leaf(self) -> ScalarInt { + match &**self.valtree { + ValTreeKind::Leaf(s) => *s, + ValTreeKind::Branch(..) => bug!("expected leaf, got {:?}", self), + } + } + + /// Converts to a `ValTreeKind::Branch` value, `panic`'ing + /// if this constant is some other kind. + #[inline] + pub fn to_branch(self) -> &'tcx [ty::Const<'tcx>] { + match &**self.valtree { + ValTreeKind::Branch(branch) => &**branch, + ValTreeKind::Leaf(..) => bug!("expected branch, got {:?}", self), + } + } + + /// Attempts to convert to a `ValTreeKind::Leaf` value. + pub fn try_to_leaf(self) -> Option { + match &**self.valtree { + ValTreeKind::Leaf(s) => Some(*s), + ValTreeKind::Branch(_) => None, + } + } + + /// Attempts to convert to a `ValTreeKind::Leaf` value. + pub fn try_to_scalar(&self) -> Option { + self.try_to_leaf().map(Scalar::Int) + } + + /// Attempts to convert to a `ValTreeKind::Branch` value. + pub fn try_to_branch(self) -> Option<&'tcx [ty::Const<'tcx>]> { + match &**self.valtree { + ValTreeKind::Branch(branch) => Some(&**branch), + ValTreeKind::Leaf(_) => None, + } } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9e4692b96418..000e7c16098e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -165,6 +165,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type ValueConst = ty::Value<'tcx>; type ExprConst = ty::Expr<'tcx>; type ValTree = ty::ValTree<'tcx>; + type ScalarInt = ty::ScalarInt; type Region = Region<'tcx>; type EarlyParamRegion = ty::EarlyParamRegion; @@ -954,7 +955,7 @@ pub struct CtxtInterners<'tcx> { fields: InternedSet<'tcx, List>, local_def_ids: InternedSet<'tcx, List>, captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>, - valtree: InternedSet<'tcx, ty::ValTreeKind<'tcx>>, + valtree: InternedSet<'tcx, ty::ValTreeKind>>, patterns: InternedSet<'tcx, List>>, outlives: InternedSet<'tcx, List>>, } @@ -2777,7 +2778,7 @@ macro_rules! direct_interners { // crate only, and have a corresponding `mk_` function. direct_interners! { region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>, - valtree: pub(crate) intern_valtree(ValTreeKind<'tcx>): ValTree -> ValTree<'tcx>, + valtree: pub(crate) intern_valtree(ValTreeKind>): ValTree -> ValTree<'tcx>, pat: pub mk_pat(PatternKind<'tcx>): Pattern -> Pattern<'tcx>, const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, layout: pub mk_layout(LayoutData): Layout -> Layout<'tcx>, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 60b6b7024dcd..5cc5ab0d5268 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -77,7 +77,7 @@ pub use self::closure::{ }; pub use self::consts::{ AnonConstKind, AtomicOrdering, Const, ConstInt, ConstKind, ConstToValTreeResult, Expr, - ExprKind, ScalarInt, SimdAlign, UnevaluatedConst, ValTree, ValTreeKind, Value, + ExprKind, ScalarInt, SimdAlign, UnevaluatedConst, ValTree, ValTreeKindExt, Value, }; pub use self::context::{ CtxtInterners, CurrentGcx, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls, diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index 335e5c064743..6acf0aff800f 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -72,7 +72,7 @@ impl<'tcx> IrPrint> for TyCtxt<'tcx> { write!(f, "{start}")?; if let Some(c) = end.try_to_value() { - let end = c.valtree.unwrap_leaf(); + let end = c.to_leaf(); let size = end.size(); let max = match c.ty.kind() { ty::Int(_) => { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 5126d902a6d5..1a5a3f3965fa 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -256,8 +256,8 @@ TrivialTypeTraversalImpls! { crate::ty::AssocItem, crate::ty::AssocKind, crate::ty::BoundRegion, + crate::ty::ScalarInt, crate::ty::UserTypeAnnotationIndex, - crate::ty::ValTree<'tcx>, crate::ty::abstract_const::NotConstEvaluatable, crate::ty::adjustment::AutoBorrowMutability, crate::ty::adjustment::PointerCoercion, @@ -697,6 +697,37 @@ impl<'tcx> TypeSuperVisitable> for ty::Const<'tcx> { } } +impl<'tcx> TypeVisitable> for ty::ValTree<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> V::Result { + let inner: &ty::ValTreeKind> = &*self; + inner.visit_with(visitor) + } +} + +impl<'tcx> TypeFoldable> for ty::ValTree<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { + let inner: &ty::ValTreeKind> = &*self; + let new_inner = inner.clone().try_fold_with(folder)?; + + if inner == &new_inner { + Ok(self) + } else { + let valtree = folder.cx().intern_valtree(new_inner); + Ok(valtree) + } + } + + fn fold_with>>(self, folder: &mut F) -> Self { + let inner: &ty::ValTreeKind> = &*self; + let new_inner = inner.clone().fold_with(folder); + + if inner == &new_inner { self } else { folder.cx().intern_valtree(new_inner) } + } +} + impl<'tcx> TypeVisitable> for rustc_span::ErrorGuaranteed { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_error(*self) diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index b221318bf0b1..ddaa61c6cc91 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -157,7 +157,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { }); } }; - values.push(value.valtree.unwrap_leaf().to_bits_unchecked()); + values.push(value.to_leaf().to_bits_unchecked()); targets.push(self.parse_block(arm.body)?); } diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 8897ca7c7210..465b1db9a164 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -2935,7 +2935,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { bug!("malformed valtree for an enum") }; - let ValTreeKind::Leaf(actual_variant_idx) = ***actual_variant_idx else { + let ValTreeKind::Leaf(actual_variant_idx) = *actual_variant_idx.to_value().valtree + else { bug!("malformed valtree for an enum") }; @@ -2943,7 +2944,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } Constructor::IntRange(int_range) => { let size = pat.ty().primitive_size(self.tcx); - let actual_int = valtree.unwrap_leaf().to_bits(size); + let actual_int = valtree.to_leaf().to_bits(size); let actual_int = if pat.ty().is_signed() { MaybeInfiniteInt::new_finite_int(actual_int, size.bits()) } else { @@ -2951,33 +2952,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; IntRange::from_singleton(actual_int).is_subrange(int_range) } - Constructor::Bool(pattern_value) => match valtree.unwrap_leaf().try_to_bool() { + Constructor::Bool(pattern_value) => match valtree.to_leaf().try_to_bool() { Ok(actual_value) => *pattern_value == actual_value, Err(()) => bug!("bool value with invalid bits"), }, Constructor::F16Range(l, h, end) => { - let actual = valtree.unwrap_leaf().to_f16(); + let actual = valtree.to_leaf().to_f16(); match end { RangeEnd::Included => (*l..=*h).contains(&actual), RangeEnd::Excluded => (*l..*h).contains(&actual), } } Constructor::F32Range(l, h, end) => { - let actual = valtree.unwrap_leaf().to_f32(); + let actual = valtree.to_leaf().to_f32(); match end { RangeEnd::Included => (*l..=*h).contains(&actual), RangeEnd::Excluded => (*l..*h).contains(&actual), } } Constructor::F64Range(l, h, end) => { - let actual = valtree.unwrap_leaf().to_f64(); + let actual = valtree.to_leaf().to_f64(); match end { RangeEnd::Included => (*l..=*h).contains(&actual), RangeEnd::Excluded => (*l..*h).contains(&actual), } } Constructor::F128Range(l, h, end) => { - let actual = valtree.unwrap_leaf().to_f128(); + let actual = valtree.to_leaf().to_f128(); match end { RangeEnd::Included => (*l..=*h).contains(&actual), RangeEnd::Excluded => (*l..*h).contains(&actual), diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 402587bff7e8..2401bc6648ed 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -116,7 +116,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let switch_targets = SwitchTargets::new( target_blocks.iter().filter_map(|(&branch, &block)| { if let TestBranch::Constant(value) = branch { - let bits = value.valtree.unwrap_leaf().to_bits_unchecked(); + let bits = value.to_leaf().to_bits_unchecked(); Some((bits, block)) } else { None diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index a176f3e49a50..981704052536 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -897,7 +897,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.tcx, ValTree::from_branches( self.tcx, - [ValTree::from_scalar_int(self.tcx, variant_index.as_u32().into())], + [ty::Const::new_value( + self.tcx, + ValTree::from_scalar_int( + self.tcx, + variant_index.as_u32().into(), + ), + self.tcx.types.u32, + )], ), self.thir[value].ty, ), diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 6e071fb344c4..563212a51f31 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -63,7 +63,7 @@ pub(crate) fn lit_to_const<'tcx>( // A CStr is a newtype around a byte slice, so we create the inner slice here. // We need a branch for each "level" of the data structure. let bytes = ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()); - ty::ValTree::from_branches(tcx, [bytes]) + ty::ValTree::from_branches(tcx, [ty::Const::new_value(tcx, bytes, *inner_ty)]) } (ast::LitKind::Int(n, _), ty::Uint(ui)) if !neg => { let scalar_int = trunc(n.get(), *ui); diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index c3c4c455b965..ce4c89a8eb2e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -239,14 +239,14 @@ impl<'tcx> ConstToPat<'tcx> { return self.mk_err(tcx.dcx().create_err(err), ty); } ty::Adt(adt_def, args) if adt_def.is_enum() => { - let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap(); - let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().to_u32()); + let (&variant_index, fields) = cv.to_branch().split_first().unwrap(); + let variant_index = VariantIdx::from_u32(variant_index.to_leaf().to_u32()); PatKind::Variant { adt_def: *adt_def, args, variant_index, subpatterns: self.field_pats( - fields.iter().copied().zip( + fields.iter().map(|ct| ct.to_value().valtree).zip( adt_def.variants()[variant_index] .fields .iter() @@ -258,28 +258,32 @@ impl<'tcx> ConstToPat<'tcx> { ty::Adt(def, args) => { assert!(!def.is_union()); // Valtree construction would never succeed for unions. PatKind::Leaf { - subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip( - def.non_enum_variant().fields.iter().map(|field| field.ty(tcx, args)), - )), + subpatterns: self.field_pats( + cv.to_branch().iter().map(|ct| ct.to_value().valtree).zip( + def.non_enum_variant().fields.iter().map(|field| field.ty(tcx, args)), + ), + ), } } ty::Tuple(fields) => PatKind::Leaf { - subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(fields.iter())), + subpatterns: self.field_pats( + cv.to_branch().iter().map(|ct| ct.to_value().valtree).zip(fields.iter()), + ), }, ty::Slice(elem_ty) => PatKind::Slice { prefix: cv - .unwrap_branch() + .to_branch() .iter() - .map(|val| *self.valtree_to_pat(*val, *elem_ty)) + .map(|val| *self.valtree_to_pat(val.to_value().valtree, *elem_ty)) .collect(), slice: None, suffix: Box::new([]), }, ty::Array(elem_ty, _) => PatKind::Array { prefix: cv - .unwrap_branch() + .to_branch() .iter() - .map(|val| *self.valtree_to_pat(*val, *elem_ty)) + .map(|val| *self.valtree_to_pat(val.to_value().valtree, *elem_ty)) .collect(), slice: None, suffix: Box::new([]), @@ -312,7 +316,7 @@ impl<'tcx> ConstToPat<'tcx> { } }, ty::Float(flt) => { - let v = cv.unwrap_leaf(); + let v = cv.to_leaf(); let is_nan = match flt { ty::FloatTy::F16 => v.to_f16().is_nan(), ty::FloatTy::F32 => v.to_f32().is_nan(), diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index df86233c2b05..d66c303b1726 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -440,7 +440,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { match bdy { PatRangeBoundary::NegInfinity => MaybeInfiniteInt::NegInfinity, PatRangeBoundary::Finite(value) => { - let bits = value.try_to_scalar_int().unwrap().to_bits_unchecked(); + let bits = value.to_leaf().to_bits_unchecked(); match *ty.kind() { ty::Int(ity) => { let size = Integer::from_int_ty(&self.tcx, ity).size().bits(); @@ -540,7 +540,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } ty::Char | ty::Int(_) | ty::Uint(_) => { ctor = { - let bits = value.valtree.unwrap_leaf().to_bits_unchecked(); + let bits = value.to_leaf().to_bits_unchecked(); let x = match *ty.kind() { ty::Int(ity) => { let size = Integer::from_int_ty(&cx.tcx, ity).size().bits(); @@ -555,7 +555,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } ty::Float(ty::FloatTy::F16) => { use rustc_apfloat::Float; - let bits = value.valtree.unwrap_leaf().to_u16(); + let bits = value.to_leaf().to_u16(); let value = rustc_apfloat::ieee::Half::from_bits(bits.into()); ctor = F16Range(value, value, RangeEnd::Included); fields = vec![]; @@ -563,7 +563,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } ty::Float(ty::FloatTy::F32) => { use rustc_apfloat::Float; - let bits = value.valtree.unwrap_leaf().to_u32(); + let bits = value.to_leaf().to_u32(); let value = rustc_apfloat::ieee::Single::from_bits(bits.into()); ctor = F32Range(value, value, RangeEnd::Included); fields = vec![]; @@ -571,7 +571,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } ty::Float(ty::FloatTy::F64) => { use rustc_apfloat::Float; - let bits = value.valtree.unwrap_leaf().to_u64(); + let bits = value.to_leaf().to_u64(); let value = rustc_apfloat::ieee::Double::from_bits(bits.into()); ctor = F64Range(value, value, RangeEnd::Included); fields = vec![]; @@ -579,7 +579,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } ty::Float(ty::FloatTy::F128) => { use rustc_apfloat::Float; - let bits = value.valtree.unwrap_leaf().to_u128(); + let bits = value.to_leaf().to_u128(); let value = rustc_apfloat::ieee::Quad::from_bits(bits); ctor = F128Range(value, value, RangeEnd::Included); fields = vec![]; @@ -623,12 +623,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } ty::Float(fty) => { use rustc_apfloat::Float; - let lo = lo - .as_finite() - .map(|c| c.try_to_scalar_int().unwrap().to_bits_unchecked()); - let hi = hi - .as_finite() - .map(|c| c.try_to_scalar_int().unwrap().to_bits_unchecked()); + let lo = lo.as_finite().map(|c| c.to_leaf().to_bits_unchecked()); + let hi = hi.as_finite().map(|c| c.to_leaf().to_bits_unchecked()); match fty { ty::FloatTy::F16 => { use rustc_apfloat::ieee::Half; diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index ee2621af8428..ea16231880e2 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -293,7 +293,7 @@ impl<'tcx> Printer<'tcx> for LegacySymbolMangler<'tcx> { ty::ConstKind::Value(cv) if cv.ty.is_integral() => { // The `pretty_print_const` formatting depends on -Zverbose-internals // flag, so we cannot reuse it here. - let scalar = cv.valtree.unwrap_leaf(); + let scalar = cv.to_leaf(); let signed = matches!(cv.ty.kind(), ty::Int(_)); write!( self, diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 36281ff16bce..58cb2eb6556e 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -129,10 +129,7 @@ mod rustc { use rustc_middle::ty::ScalarInt; use rustc_span::sym; - let Some(cv) = ct.try_to_value() else { - return None; - }; - + let cv = ct.try_to_value()?; let adt_def = cv.ty.ty_adt_def()?; if !tcx.is_lang_item(adt_def.did(), LangItem::TransmuteOpts) { @@ -149,7 +146,7 @@ mod rustc { } let variant = adt_def.non_enum_variant(); - let fields = cv.valtree.unwrap_branch(); + let fields = cv.to_branch(); let get_field = |name| { let (field_idx, _) = variant @@ -158,7 +155,7 @@ mod rustc { .enumerate() .find(|(_, field_def)| name == field_def.name) .unwrap_or_else(|| panic!("There were no fields named `{name}`.")); - fields[field_idx].unwrap_leaf() == ScalarInt::TRUE + fields[field_idx].to_leaf() == ScalarInt::TRUE }; Some(Self { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 4b19d0f16d78..d8d5b7fc75cc 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -25,15 +25,14 @@ fn destructure_const<'tcx>( let ty::ConstKind::Value(cv) = const_.kind() else { bug!("cannot destructure constant {:?}", const_) }; - - let branches = cv.valtree.unwrap_branch(); + let branches = cv.to_branch(); let (fields, variant) = match cv.ty.kind() { ty::Array(inner_ty, _) | ty::Slice(inner_ty) => { // construct the consts for the elements of the array/slice let field_consts = branches .iter() - .map(|b| ty::Const::new_value(tcx, *b, *inner_ty)) + .map(|b| ty::Const::new_value(tcx, b.to_value().valtree, *inner_ty)) .collect::>(); debug!(?field_consts); @@ -43,7 +42,7 @@ fn destructure_const<'tcx>( ty::Adt(def, args) => { let (variant_idx, branches) = if def.is_enum() { let (head, rest) = branches.split_first().unwrap(); - (VariantIdx::from_u32(head.unwrap_leaf().to_u32()), rest) + (VariantIdx::from_u32(head.to_leaf().to_u32()), rest) } else { (FIRST_VARIANT, branches) }; @@ -52,7 +51,8 @@ fn destructure_const<'tcx>( for (field, field_valtree) in iter::zip(fields, branches) { let field_ty = field.ty(tcx, args); - let field_const = ty::Const::new_value(tcx, *field_valtree, field_ty); + let field_const = + ty::Const::new_value(tcx, field_valtree.to_value().valtree, field_ty); field_consts.push(field_const); } debug!(?field_consts); @@ -61,7 +61,9 @@ fn destructure_const<'tcx>( } ty::Tuple(elem_tys) => { let fields = iter::zip(*elem_tys, branches) - .map(|(elem_ty, elem_valtree)| ty::Const::new_value(tcx, *elem_valtree, elem_ty)) + .map(|(elem_ty, elem_valtree)| { + ty::Const::new_value(tcx, elem_valtree.to_value().valtree, elem_ty) + }) .collect::>(); (fields, None) diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index f315e8b3e11c..a5c40d4eb199 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -127,3 +127,76 @@ impl HashStable for InferConst { } } } + +/// This datastructure is used to represent the value of constants used in the type system. +/// +/// We explicitly choose a different datastructure from the way values are processed within +/// CTFE, as in the type system equal values (according to their `PartialEq`) must also have +/// equal representation (`==` on the rustc data structure, e.g. `ValTree`) and vice versa. +/// Since CTFE uses `AllocId` to represent pointers, it often happens that two different +/// `AllocId`s point to equal values. So we may end up with different representations for +/// two constants whose value is `&42`. Furthermore any kind of struct that has padding will +/// have arbitrary values within that padding, even if the values of the struct are the same. +/// +/// `ValTree` does not have this problem with representation, as it only contains integers or +/// lists of (nested) `ty::Const`s (which may indirectly contain more `ValTree`s). +#[derive_where(Clone, Debug, Hash, Eq, PartialEq; I: Interner)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[cfg_attr( + feature = "nightly", + derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) +)] +pub enum ValTreeKind { + /// integers, `bool`, `char` are represented as scalars. + /// See the `ScalarInt` documentation for how `ScalarInt` guarantees that equal values + /// of these types have the same representation. + Leaf(I::ScalarInt), + + /// The fields of any kind of aggregate. Structs, tuples and arrays are represented by + /// listing their fields' values in order. + /// + /// Enums are represented by storing their variant index as a u32 field, followed by all + /// the fields of the variant. + /// + /// ZST types are represented as an empty slice. + // FIXME(mgca): Use a `List` here instead of a boxed slice + Branch(Box<[I::Const]>), +} + +impl ValTreeKind { + /// Converts to a `ValTreeKind::Leaf` value, `panic`'ing + /// if this valtree is some other kind. + #[inline] + pub fn to_leaf(&self) -> I::ScalarInt { + match self { + ValTreeKind::Leaf(s) => *s, + ValTreeKind::Branch(..) => panic!("expected leaf, got {:?}", self), + } + } + + /// Converts to a `ValTreeKind::Branch` value, `panic`'ing + /// if this valtree is some other kind. + #[inline] + pub fn to_branch(&self) -> &[I::Const] { + match self { + ValTreeKind::Branch(branch) => &**branch, + ValTreeKind::Leaf(..) => panic!("expected branch, got {:?}", self), + } + } + + /// Attempts to convert to a `ValTreeKind::Leaf` value. + pub fn try_to_leaf(&self) -> Option { + match self { + ValTreeKind::Leaf(s) => Some(*s), + ValTreeKind::Branch(_) => None, + } + } + + /// Attempts to convert to a `ValTreeKind::Branch` value. + pub fn try_to_branch(&self) -> Option<&[I::Const]> { + match self { + ValTreeKind::Branch(branch) => Some(&**branch), + ValTreeKind::Leaf(_) => None, + } + } +} diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 34b030ee768b..2c1fc7decc3e 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -477,7 +477,17 @@ impl FlagComputation { ty::ConstKind::Placeholder(_) => { self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER); } - ty::ConstKind::Value(cv) => self.add_ty(cv.ty()), + ty::ConstKind::Value(cv) => { + self.add_ty(cv.ty()); + match cv.valtree().kind() { + ty::ValTreeKind::Leaf(_) => (), + ty::ValTreeKind::Branch(cts) => { + for ct in cts { + self.add_const(*ct); + } + } + } + } ty::ConstKind::Expr(e) => self.add_args(e.args().as_slice()), ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 75ba0231d98c..16f837141e97 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -292,6 +292,12 @@ pub trait ValueConst>: Copy + Debug + Hash + Eq { fn valtree(self) -> I::ValTree; } +// FIXME(mgca): This trait can be removed once we're not using a `Box` in `Branch` +pub trait ValTree>: Copy + Debug + Hash + Eq { + // This isnt' `IntoKind` because then we can't return a reference + fn kind(&self) -> &ty::ValTreeKind; +} + pub trait ExprConst>: Copy + Debug + Hash + Eq + Relate { fn args(self) -> I::GenericArgs; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 3884f29a4fc8..03cf738c0598 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -153,7 +153,8 @@ pub trait Interner: type PlaceholderConst: PlaceholderConst; type ValueConst: ValueConst; type ExprConst: ExprConst; - type ValTree: Copy + Debug + Hash + Eq; + type ValTree: ValTree; + type ScalarInt: Copy + Debug + Hash + Eq; // Kinds of regions type Region: Region; diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 4f843503d1af..4954ebc51cfc 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -582,13 +582,27 @@ pub fn structurally_relate_consts>( } (ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2, (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => { - a_val.valtree() == b_val.valtree() + match (a_val.valtree().kind(), b_val.valtree().kind()) { + (ty::ValTreeKind::Leaf(scalar_a), ty::ValTreeKind::Leaf(scalar_b)) => { + scalar_a == scalar_b + } + (ty::ValTreeKind::Branch(branches_a), ty::ValTreeKind::Branch(branches_b)) + if branches_a.len() == branches_b.len() => + { + branches_a + .into_iter() + .zip(branches_b) + .all(|(a, b)| relation.relate(*a, *b).is_ok()) + } + _ => false, + } } // While this is slightly incorrect, it shouldn't matter for `min_const_generics` // and is the better alternative to waiting until `generic_const_exprs` can // be stabilized. (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => { + // FIXME(mgca): remove this if cfg!(debug_assertions) { let a_ty = cx.type_of(au.def.into()).instantiate(cx, au.args); let b_ty = cx.type_of(bu.def.into()).instantiate(cx, bu.args); diff --git a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr index 1a0563b469c1..a96876a2c25a 100644 --- a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr +++ b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr @@ -12,7 +12,7 @@ LL | struct ExplicitlyPadded(Box); error[E0391]: cycle detected when computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded` | = note: ...which immediately requires computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded` again - = note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::TransmuteFrom` + = note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::TransmuteFrom` = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 2 previous errors From 484480412e7779d364a4d28be0f4ca6c50d9492b Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 19 Nov 2025 19:31:11 +0000 Subject: [PATCH 1188/3801] Lower `hir::ConstArgKind::Struct` to a `ValTree` --- .../src/hir_ty_lowering/mod.rs | 134 +++++++++++++++--- tests/crashes/127972.rs | 6 - tests/crashes/137888.rs | 11 -- tests/crashes/140275.rs | 5 - .../mgca/adt_expr_arg_simple.rs | 38 +++++ .../mgca/adt_expr_arg_simple.stderr | 14 ++ .../mgca/adt_expr_erroneuous_inits.rs | 26 ++++ .../mgca/adt_expr_erroneuous_inits.stderr | 49 +++++++ .../mgca/adt_expr_fields_type_check.rs | 17 +++ .../mgca/adt_expr_infers_from_value.rs | 45 ++++++ .../mgca/explicit_anon_consts-2.rs | 10 ++ .../mgca/explicit_anon_consts-2.stderr | 8 ++ .../mgca/explicit_anon_consts-3.rs | 10 ++ .../mgca/explicit_anon_consts-3.stderr | 8 ++ .../mgca/explicit_anon_consts-4.rs | 9 ++ .../mgca/explicit_anon_consts-4.stderr | 8 ++ .../mgca/explicit_anon_consts-5.rs | 16 +++ .../mgca/explicit_anon_consts-5.stderr | 8 ++ .../mgca/explicit_anon_consts-6.rs | 8 ++ .../mgca/explicit_anon_consts-6.stderr | 8 ++ .../mgca/explicit_anon_consts.rs | 25 ++-- .../mgca/explicit_anon_consts.stderr | 54 ++----- .../explicit_anon_consts_literals_hack.rs | 18 ++- .../explicit_anon_consts_literals_hack.stderr | 8 ++ .../mgca/type_const-on-generic-expr.rs | 24 ---- .../mgca/type_const-on-generic-expr.stderr | 30 +--- .../mgca/type_const-on-generic_expr-2.rs | 27 ++++ .../mgca/type_const-on-generic_expr-2.stderr | 20 +++ .../bad_const_generics_args_on_const_param.rs | 15 -- ..._const_generics_args_on_const_param.stderr | 21 --- 30 files changed, 491 insertions(+), 189 deletions(-) delete mode 100644 tests/crashes/127972.rs delete mode 100644 tests/crashes/137888.rs delete mode 100644 tests/crashes/140275.rs create mode 100644 tests/ui/const-generics/mgca/adt_expr_arg_simple.rs create mode 100644 tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr create mode 100644 tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.rs create mode 100644 tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr create mode 100644 tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs create mode 100644 tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-2.rs create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-2.stderr create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-3.rs create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-3.stderr create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-4.rs create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-4.stderr create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-5.rs create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-5.stderr create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-6.rs create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts-6.stderr create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.stderr create mode 100644 tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs create mode 100644 tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr delete mode 100644 tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs delete mode 100644 tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr 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 3c1200c812bc..23110d2c5c87 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2263,15 +2263,120 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) .unwrap_or_else(|guar| Const::new_error(tcx, guar)) } - hir::ConstArgKind::Struct(..) => { - span_bug!(const_arg.span(), "lowering `{:?}` is not yet implemented", const_arg) + hir::ConstArgKind::Struct(qpath, inits) => { + self.lower_const_arg_struct(hir_id, qpath, inits, const_arg.span()) } - hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon), + hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span), hir::ConstArgKind::Error(_, e) => ty::Const::new_error(tcx, e), } } + fn lower_const_arg_struct( + &self, + hir_id: HirId, + qpath: hir::QPath<'tcx>, + inits: &'tcx [&'tcx hir::ConstArgExprField<'tcx>], + span: Span, + ) -> Const<'tcx> { + // FIXME(mgca): try to deduplicate this function with + // the equivalent HIR typeck logic. + let tcx = self.tcx(); + + let non_adt_or_variant_res = || { + let e = tcx.dcx().span_err(span, "struct expression with invalid base path"); + ty::Const::new_error(tcx, e) + }; + + let (ty, variant_did) = match qpath { + hir::QPath::Resolved(maybe_qself, path) => { + debug!(?maybe_qself, ?path); + let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself)); + let ty = + self.lower_resolved_ty_path(opt_self_ty, path, hir_id, PermitVariants::Yes); + let variant_did = match path.res { + Res::Def(DefKind::Variant | DefKind::Struct, did) => did, + _ => return non_adt_or_variant_res(), + }; + + (ty, variant_did) + } + hir::QPath::TypeRelative(hir_self_ty, segment) => { + debug!(?hir_self_ty, ?segment); + let self_ty = self.lower_ty(hir_self_ty); + let opt_res = self.lower_type_relative_ty_path( + self_ty, + hir_self_ty, + segment, + hir_id, + span, + PermitVariants::Yes, + ); + + let (ty, _, res_def_id) = match opt_res { + Ok(r @ (_, DefKind::Variant | DefKind::Struct, _)) => r, + Ok(_) => return non_adt_or_variant_res(), + Err(e) => return ty::Const::new_error(tcx, e), + }; + + (ty, res_def_id) + } + }; + + let ty::Adt(adt_def, adt_args) = ty.kind() else { unreachable!() }; + + let variant_def = adt_def.variant_with_id(variant_did); + let variant_idx = adt_def.variant_index_with_id(variant_did).as_u32(); + + let fields = variant_def + .fields + .iter() + .map(|field_def| { + // FIXME(mgca): we aren't really handling privacy, stability, + // or macro hygeniene but we should. + let mut init_expr = + inits.iter().filter(|init_expr| init_expr.field.name == field_def.name); + + match init_expr.next() { + Some(expr) => { + if let Some(expr) = init_expr.next() { + let e = tcx.dcx().span_err( + expr.span, + format!( + "struct expression with multiple initialisers for `{}`", + field_def.name, + ), + ); + return ty::Const::new_error(tcx, e); + } + + self.lower_const_arg(expr.expr, FeedConstTy::Param(field_def.did, adt_args)) + } + None => { + let e = tcx.dcx().span_err( + span, + format!( + "struct expression with missing field initialiser for `{}`", + field_def.name + ), + ); + ty::Const::new_error(tcx, e) + } + } + }) + .collect::>(); + + let opt_discr_const = if adt_def.is_enum() { + let valtree = ty::ValTree::from_scalar_int(tcx, variant_idx.into()); + Some(ty::Const::new_value(tcx, valtree, tcx.types.u32)) + } else { + None + }; + + let valtree = ty::ValTree::from_branches(tcx, opt_discr_const.into_iter().chain(fields)); + ty::Const::new_value(tcx, valtree, ty) + } + /// Lower a [resolved][hir::QPath::Resolved] path to a (type-level) constant. fn lower_resolved_const_path( &self, @@ -2375,22 +2480,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Literals are eagerly converted to a constant, everything else becomes `Unevaluated`. #[instrument(skip(self), level = "debug")] - fn lower_anon_const(&self, anon: &AnonConst) -> Const<'tcx> { + fn lower_const_arg_anon(&self, anon: &AnonConst) -> Const<'tcx> { let tcx = self.tcx(); let expr = &tcx.hir_body(anon.body).value; debug!(?expr); - // If the rhs is an anon const naming generics it shouldn't have - // access to then we lower to `ConstKind::Error`. This prevents - // `try_lower_anon_const_lit` from ICEing on anon consts such as - // `const { N }` which aren't supposed to be legal. - if let ty::AnonConstKind::MCG = tcx.anon_const_kind(anon.def_id) - && let Err(e) = tcx.check_anon_const_invalid_param_uses(anon.def_id) - { - return ty::Const::new_error(tcx, e); - } - // FIXME(generic_const_parameter_types): We should use the proper generic args // here. It's only used as a hint for literals so doesn't matter too much to use the right // generic arguments, just weaker type inference. @@ -2416,8 +2511,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) -> Option> { let tcx = self.tcx(); - // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments - // currently have to be wrapped in curly brackets, so it's necessary to special-case. + // Unwrap a block, so that e.g. `{ 1 }` is recognised as a literal. This makes the + // performance optimisation of directly lowering anon consts occur more often. let expr = match &expr.kind { hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => { block.expr.as_ref().unwrap() @@ -2425,15 +2520,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { _ => expr, }; + // FIXME(mgca): remove this delayed bug once we start checking this + // when lowering `Ty/ConstKind::Param`s more generally. if let hir::ExprKind::Path(hir::QPath::Resolved( _, &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. }, )) = expr.kind { - span_bug!( + let e = tcx.dcx().span_delayed_bug( expr.span, - "try_lower_anon_const_lit: received const param which shouldn't be possible" + "try_lower_anon_const_lit: received const param which shouldn't be possible", ); + return Some(ty::Const::new_error(tcx, e)); }; let lit_input = match expr.kind { diff --git a/tests/crashes/127972.rs b/tests/crashes/127972.rs deleted file mode 100644 index 797dd7e60209..000000000000 --- a/tests/crashes/127972.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #127962 -#![feature(generic_const_exprs, const_arg_path)] - -fn zero_init() -> Substs1<{ (N) }> { - Substs1([0; { (usize) }]) -} diff --git a/tests/crashes/137888.rs b/tests/crashes/137888.rs deleted file mode 100644 index 6c13ae5fa916..000000000000 --- a/tests/crashes/137888.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #137888 -#![feature(generic_const_exprs)] -macro_rules! empty { - () => (); -} -fn bar() -> [(); { - empty! {}; - N - }] { -} -fn main() {} diff --git a/tests/crashes/140275.rs b/tests/crashes/140275.rs deleted file mode 100644 index 5ea04af0c8e0..000000000000 --- a/tests/crashes/140275.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ known-bug: #140275 -#![feature(generic_const_exprs)] -trait T{} -trait V{} -impl T for [i32; N::<&mut V>] {} diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs new file mode 100644 index 000000000000..ffb763da325c --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs @@ -0,0 +1,38 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +enum Option { + Some(T), + None, +} +use Option::Some; + +fn foo>() {} + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +fn bar() { + // the initializer of `_0` is a `N` which is a legal const argument + // so this is ok. + foo::<{ Some:: { 0: N } }>(); + + // this is allowed as mgca supports uses of assoc consts in the + // type system. ie `::ASSOC` is a legal const argument + foo::<{ Some:: { 0: ::ASSOC } }>(); + + // this on the other hand is not allowed as `N + 1` is not a legal + // const argument + foo::<{ Some:: { 0: N + 1 } }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + + // this also is not allowed as generic parameters cannot be used + // in anon const const args + foo::<{ Some:: { 0: const { N + 1 } } }>(); + //~^ ERROR: generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr new file mode 100644 index 000000000000..8b9c228c1ee5 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr @@ -0,0 +1,14 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/adt_expr_arg_simple.rs:29:30 + | +LL | foo::<{ Some:: { 0: N + 1 } }>(); + | ^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/adt_expr_arg_simple.rs:34:38 + | +LL | foo::<{ Some:: { 0: const { N + 1 } } }>(); + | ^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.rs b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.rs new file mode 100644 index 000000000000..752844e4328f --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.rs @@ -0,0 +1,26 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![crate_type = "lib"] + +// Miscellaneous assortment of invalid cases of directly represented +// `ConstArgKind::Struct`'s under mgca. + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct Foo { field: T } + +fn NonStruct() {} + +fn accepts>() {} + +fn bar() { + accepts::<{ Foo:: { }}>(); + //~^ ERROR: struct expression with missing field initialiser for `field` + accepts::<{ Foo:: { field: const { 1 }, field: const { 2} }}>(); + //~^ ERROR: struct expression with multiple initialisers for `field` + accepts::<{ Fooo:: { field: const { 1 } }}>(); + //~^ ERROR: cannot find struct, variant or union type `Fooo` in this scope + //~| ERROR: struct expression with invalid base path + accepts::<{ NonStruct { }}>(); + //~^ ERROR: expected struct, variant or union type, found function `NonStruct` + //~| ERROR: struct expression with invalid base path +} diff --git a/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr new file mode 100644 index 000000000000..49d3f67003dc --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr @@ -0,0 +1,49 @@ +error[E0422]: cannot find struct, variant or union type `Fooo` in this scope + --> $DIR/adt_expr_erroneuous_inits.rs:20:17 + | +LL | struct Foo { field: T } + | ------------- similarly named struct `Foo` defined here +... +LL | accepts::<{ Fooo:: { field: const { 1 } }}>(); + | ^^^^ + | +help: a struct with a similar name exists + | +LL - accepts::<{ Fooo:: { field: const { 1 } }}>(); +LL + accepts::<{ Foo:: { field: const { 1 } }}>(); + | + +error[E0574]: expected struct, variant or union type, found function `NonStruct` + --> $DIR/adt_expr_erroneuous_inits.rs:23:17 + | +LL | accepts::<{ NonStruct { }}>(); + | ^^^^^^^^^ not a struct, variant or union type + +error: struct expression with missing field initialiser for `field` + --> $DIR/adt_expr_erroneuous_inits.rs:16:17 + | +LL | accepts::<{ Foo:: { }}>(); + | ^^^^^^^^^ + +error: struct expression with multiple initialisers for `field` + --> $DIR/adt_expr_erroneuous_inits.rs:18:49 + | +LL | accepts::<{ Foo:: { field: const { 1 }, field: const { 2} }}>(); + | ^^^^^^^^^^^^^^^^^ + +error: struct expression with invalid base path + --> $DIR/adt_expr_erroneuous_inits.rs:20:17 + | +LL | accepts::<{ Fooo:: { field: const { 1 } }}>(); + | ^^^^^^^^^^ + +error: struct expression with invalid base path + --> $DIR/adt_expr_erroneuous_inits.rs:23:17 + | +LL | accepts::<{ NonStruct { }}>(); + | ^^^^^^^^^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0422, E0574. +For more information about an error, try `rustc --explain E0422`. diff --git a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs new file mode 100644 index 000000000000..eafc8382966b --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs @@ -0,0 +1,17 @@ +//@ check-pass +// FIXME(mgca): This should error + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct Foo { field: T } + +fn accepts>() {} + +fn bar() { + // `N` is not of type `u8` but we don't actually check this anywhere yet + accepts::<{ Foo:: { field: N }}>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs b/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs new file mode 100644 index 000000000000..d3c9b655a9e5 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs @@ -0,0 +1,45 @@ +//@ check-pass + +#![feature( + generic_const_items, + min_generic_const_args, + adt_const_params, + generic_const_parameter_types, + unsized_const_params, +)] +#![expect(incomplete_features)] + +use std::marker::{PhantomData, ConstParamTy, ConstParamTy_}; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct Foo { + field: T, +} + +#[type_const] +const WRAP: Foo = { Foo:: { + field: N, +} }; + +fn main() { + // What we're trying to accomplish here is winding up with an equality relation + // between two `ty::Const` that looks something like: + // + // ``` + // Foo { field: const { 1 + 2 } } + // eq + // Foo { field: ?x } + // ``` + // + // Note that the `field: _` here means a const argument `_` not a wildcard pattern. + // This tests that we are able to infer `?x=3` even though the first `ty::Const` + // may be a fully evaluated constant, and the latter is not fully evaluatable due + // to inference variables. + let _: PC<_, { WRAP:: }> + = PC::<_, { Foo:: { field: _ }}>; +} + +// "PhantomConst" helper equivalent to "PhantomData" used for testing equalities +// of arbitrarily typed const arguments. +struct PC { _0: PhantomData } +const PC: PC = PC { _0: PhantomData:: }; diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-2.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-2.rs new file mode 100644 index 000000000000..37a3321a291e --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-2.rs @@ -0,0 +1,10 @@ +#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] +#![expect(incomplete_features)] +// library crates exercise weirder code paths around +// DefIds which were created for const args. +#![crate_type = "lib"] + +struct Foo; + +type Alias = Foo; +//~^ ERROR: generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-2.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-2.stderr new file mode 100644 index 000000000000..8d8abd9ef313 --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-2.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts-2.rs:9:42 + | +LL | type Alias = Foo; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-3.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-3.rs new file mode 100644 index 000000000000..ad7ae7c511ff --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-3.rs @@ -0,0 +1,10 @@ +#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] +#![expect(incomplete_features)] +// library crates exercise weirder code paths around +// DefIds which were created for const args. +#![crate_type = "lib"] + +struct Foo; + +type Alias = [(); const { N }]; +//~^ ERROR: generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-3.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-3.stderr new file mode 100644 index 000000000000..fe2c40486aeb --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-3.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts-3.rs:9:43 + | +LL | type Alias = [(); const { N }]; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-4.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-4.rs new file mode 100644 index 000000000000..bcf34bdb13ee --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-4.rs @@ -0,0 +1,9 @@ +#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] +#![expect(incomplete_features)] +// library crates exercise weirder code paths around +// DefIds which were created for const args. +#![crate_type = "lib"] + +#[type_const] +const ITEM3: usize = const { N }; +//~^ ERROR: generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-4.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-4.stderr new file mode 100644 index 000000000000..7fc78257aa2c --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-4.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts-4.rs:8:46 + | +LL | const ITEM3: usize = const { N }; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-5.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-5.rs new file mode 100644 index 000000000000..aa14ec4275e4 --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-5.rs @@ -0,0 +1,16 @@ +#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] +#![expect(incomplete_features)] +// library crates exercise weirder code paths around +// DefIds which were created for const args. +#![crate_type = "lib"] + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +fn ace_bounds< + const N: usize, + T: Trait, + //~^ ERROR: generic parameters may not be used in const operations +>() {} diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-5.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-5.stderr new file mode 100644 index 000000000000..6d2ab078c8cf --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-5.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts-5.rs:14:30 + | +LL | T: Trait, + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-6.rs b/tests/ui/const-generics/mgca/explicit_anon_consts-6.rs new file mode 100644 index 000000000000..600f4b9cd7f9 --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-6.rs @@ -0,0 +1,8 @@ +#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] +#![expect(incomplete_features)] +// library crates exercise weirder code paths around +// DefIds which were created for const args. +#![crate_type = "lib"] + +struct Default3; +//~^ ERROR: generic parameters may not be used in const operations diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts-6.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts-6.stderr new file mode 100644 index 000000000000..727e478bee8e --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts-6.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts-6.rs:7:58 + | +LL | struct Default3; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs index ef17222ebc91..f7df3eddfa64 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -4,21 +4,22 @@ // DefIds which were created for const args. #![crate_type = "lib"] +// FIXME(mgca): merge the split out parts of this test back in + struct Foo; type Adt1 = Foo; type Adt2 = Foo<{ N }>; -type Adt3 = Foo; -//~^ ERROR: generic parameters may not be used in const operations -//~^^ ERROR generic parameters may not be used in const operations +// explicit_anon_consts-2.rs +// type Adt3 = Foo; type Adt4 = Foo<{ 1 + 1 }>; //~^ ERROR: complex const arguments must be placed inside of a `const` block type Adt5 = Foo; type Arr = [(); N]; type Arr2 = [(); { N }]; -type Arr3 = [(); const { N }]; -//~^ ERROR: generic parameters may not be used in const operations +// explicit_anon_consts-3.rs +// type Arr3 = [(); const { N }]; type Arr4 = [(); 1 + 1]; //~^ ERROR: complex const arguments must be placed inside of a `const` block type Arr5 = [(); const { 1 + 1 }]; @@ -37,9 +38,9 @@ fn repeats() { const ITEM1: usize = N; #[type_const] const ITEM2: usize = { N }; -#[type_const] -const ITEM3: usize = const { N }; -//~^ ERROR: generic parameters may not be used in const operations +// explicit_anon_consts-4.rs +// #[type_const] +// const ITEM3: usize = const { N }; #[type_const] const ITEM4: usize = { 1 + 1 }; //~^ ERROR: complex const arguments must be placed inside of a `const` block @@ -56,8 +57,8 @@ fn ace_bounds< // We skip the T1 case because it doesn't resolve // T1: Trait, T2: Trait, - T3: Trait, - //~^ ERROR: generic parameters may not be used in const operations + // explicit_anon_consts-5.rs + // T3: Trait, T4: Trait, //~^ ERROR: complex const arguments must be placed inside of a `const` block T5: Trait, @@ -65,8 +66,8 @@ fn ace_bounds< struct Default1; struct Default2; -struct Default3; -//~^ ERROR: generic parameters may not be used in const operations +// explicit_anon_consts-6.rs +// struct Default3; struct Default4; //~^ ERROR: complex const arguments must be placed inside of a `const` block struct Default5; diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index eb200aae3396..1605dd8069d0 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -1,82 +1,44 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:14:33 + --> $DIR/explicit_anon_consts.rs:15:33 | LL | type Adt4 = Foo<{ 1 + 1 }>; | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:22:34 + --> $DIR/explicit_anon_consts.rs:23:34 | LL | type Arr4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:31:19 + --> $DIR/explicit_anon_consts.rs:32:19 | LL | let _4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:44:38 + --> $DIR/explicit_anon_consts.rs:45:38 | LL | const ITEM4: usize = { 1 + 1 }; | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:61:23 + --> $DIR/explicit_anon_consts.rs:62:23 | LL | T4: Trait, | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:70:50 + --> $DIR/explicit_anon_consts.rs:71:50 | LL | struct Default4; | ^^^^^^^^^ error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:11:41 - | -LL | type Adt3 = Foo; - | ^ - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:20:42 - | -LL | type Arr3 = [(); const { N }]; - | ^ - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:41:46 - | -LL | const ITEM3: usize = const { N }; - | ^ - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:59:31 - | -LL | T3: Trait, - | ^ - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:68:58 - | -LL | struct Default3; - | ^ - -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:29:27 + --> $DIR/explicit_anon_consts.rs:30:27 | LL | let _3 = [(); const { N }]; | ^ -error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:11:41 - | -LL | type Adt3 = Foo; - | ^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 13 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs index 979d10331a59..8c8c5c8e8f88 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs @@ -1,9 +1,10 @@ -//@ check-pass - // We allow for literals to implicitly be anon consts still regardless // of whether a const block is placed around them or not +// +// However, we don't allow so for const arguments in field init positions. +// This is just harder to implement so we did not do so. -#![feature(min_generic_const_args, associated_const_equality)] +#![feature(min_generic_const_args, adt_const_params, associated_const_equality)] #![expect(incomplete_features)] trait Trait { @@ -19,4 +20,15 @@ type ArrLen = [(); 1]; struct Foo; type NormalArg = (Foo<1>, Foo<-1>); +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct ADT { field: u8 } + +fn struct_expr() { + fn takes_n() {} + + takes_n::<{ ADT { field: 1 } }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + takes_n::<{ ADT { field: const { 1 } } }>(); +} + fn main() {} diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.stderr new file mode 100644 index 000000000000..02647fd808cc --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.stderr @@ -0,0 +1,8 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts_literals_hack.rs:29:30 + | +LL | takes_n::<{ ADT { field: 1 } }>(); + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs index a1008fae9d16..ac4c4fb59419 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs @@ -4,32 +4,8 @@ #[type_const] const FREE1: usize = const { std::mem::size_of::() }; //~^ ERROR generic parameters may not be used in const operations -//~^^ ERROR generic parameters may not be used in const operations #[type_const] const FREE2: usize = const { I + 1 }; //~^ ERROR generic parameters may not be used in const operations -pub trait Tr { - #[type_const] - const N1: usize; - #[type_const] - const N2: usize; - #[type_const] - const N3: usize; -} - -pub struct S; - -impl Tr for S { - #[type_const] - const N1: usize = const { std::mem::size_of::() }; - //~^ ERROR generic parameters may not be used in const operations - #[type_const] - const N2: usize = const { I + 1 }; - //~^ ERROR generic parameters may not be used in const operations - #[type_const] - const N3: usize = const { 2 & X }; - //~^ ERROR generic parameters may not be used in const operations -} - fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr index c77be158d0ef..f339e82beeed 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -5,36 +5,10 @@ LL | const FREE1: usize = const { std::mem::size_of::() }; | ^ error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:9:46 + --> $DIR/type_const-on-generic-expr.rs:8:46 | LL | const FREE2: usize = const { I + 1 }; | ^ -error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:25:54 - | -LL | const N1: usize = const { std::mem::size_of::() }; - | ^ - -error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:28:47 - | -LL | const N2: usize = const { I + 1 }; - | ^ - -error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:31:35 - | -LL | const N3: usize = const { 2 & X }; - | ^ - -error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:5:53 - | -LL | const FREE1: usize = const { std::mem::size_of::() }; - | ^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs new file mode 100644 index 000000000000..37de4d4a4abb --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs @@ -0,0 +1,27 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args, generic_const_items)] + +pub trait Tr { + #[type_const] + const N1: usize; + #[type_const] + const N2: usize; + #[type_const] + const N3: usize; +} + +pub struct S; + +impl Tr for S { + #[type_const] + const N1: usize = const { std::mem::size_of::() }; + //~^ ERROR generic parameters may not be used in const operations + #[type_const] + const N2: usize = const { I + 1 }; + //~^ ERROR generic parameters may not be used in const operations + #[type_const] + const N3: usize = const { 2 & X }; + //~^ ERROR generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr new file mode 100644 index 000000000000..9d4e99ca0aaf --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr @@ -0,0 +1,20 @@ +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic_expr-2.rs:17:54 + | +LL | const N1: usize = const { std::mem::size_of::() }; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic_expr-2.rs:20:47 + | +LL | const N2: usize = const { I + 1 }; + | ^ + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic_expr-2.rs:23:35 + | +LL | const N3: usize = const { 2 & X }; + | ^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs deleted file mode 100644 index 29f193a4d7f3..000000000000 --- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@known-bug: #127972 -//@ failure-status: 101 -//@ normalize-stderr: "note: .*\n\n" -> "" -//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" -//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" -//@ rustc-env:RUST_BACKTRACE=0 - -#![feature(pattern_types, pattern_type_macro, generic_const_exprs)] -#![allow(internal_features)] - -type Pat = - std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>); - -fn main() {} diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr deleted file mode 100644 index d053d8aed062..000000000000 --- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr +++ /dev/null @@ -1,21 +0,0 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad_const_generics_args_on_const_param.rs:9:47 - | -LL | #![feature(pattern_types, pattern_type_macro, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = error: internal compiler error: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs:LL:CC: try_lower_anon_const_lit: received const param which shouldn't be possible - --> $DIR/bad_const_generics_args_on_const_param.rs:13:36 - | -LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>); - | ^^^^^^^^^^^^^^^^^^^ - - -Box -query stack during panic: -#0 [type_of] expanding type alias `Pat` -#1 [check_well_formed] checking that `Pat` is well-formed -... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack -error: aborting due to 1 previous error; 1 warning emitted - From 79fd535473f9a2025ee5d09ce9465969da90ae33 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 19 Nov 2025 23:28:50 +0000 Subject: [PATCH 1189/3801] Fix tools --- .../src/intrinsics/simd.rs | 2 +- src/librustdoc/clean/mod.rs | 6 +++++- src/librustdoc/clean/utils.rs | 2 +- .../clippy/clippy_lints/src/utils/author.rs | 1 + src/tools/clippy/clippy_utils/src/consts.rs | 2 +- .../clippy/clippy_utils/src/hir_utils.rs | 21 +++++++++++++++---- src/tools/miri/src/intrinsics/atomic.rs | 2 +- 7 files changed, 27 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 38e8d2fa9368..15aef60c5af3 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -130,7 +130,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( return; } - let idx = generic_args[2].expect_const().to_value().valtree.unwrap_branch(); + let idx = generic_args[2].expect_const().to_branch(); assert_eq!(x.layout(), y.layout()); let layout = x.layout(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 764b3a0acdb6..707b48b355ba 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -319,6 +319,10 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind hir::ConstArgKind::Path(qpath) => { ConstantKind::Path { path: qpath_to_string(qpath).into() } } + hir::ConstArgKind::Struct(..) => { + // FIXME(mgca): proper printing :3 + ConstantKind::Path { path: "/* STRUCT EXPR */".to_string().into() } + } hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer, } @@ -1800,7 +1804,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T let ct = cx.tcx.normalize_erasing_regions(typing_env, ct); print_const(cx, ct) } - hir::ConstArgKind::Path(..) => { + hir::ConstArgKind::Struct(..) | hir::ConstArgKind::Path(..) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); print_const(cx, ct) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 4c3f26701bab..0f75a332ad6b 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -357,7 +357,7 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { } // array lengths are obviously usize ty::ConstKind::Value(cv) if *cv.ty.kind() == ty::Uint(ty::UintTy::Usize) => { - cv.valtree.unwrap_leaf().to_string() + cv.to_leaf().to_string() } _ => n.to_string(), } diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 03cbb0311c6c..685b0a9c0d60 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -319,6 +319,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { chain!(self, "let ConstArgKind::Anon({anon_const}) = {const_arg}.kind"); self.body(field!(anon_const.body)); }, + ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 7e3fa4f9909b..e43b0b95d9f7 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1139,7 +1139,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, + ConstArgKind::Struct(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, }, } } diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index c6d82c0e63fa..5cadf5fbb869 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -477,11 +477,18 @@ impl HirEqInterExpr<'_, '_, '_> { (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true, + (ConstArgKind::Struct(path_a, inits_a), ConstArgKind::Struct(path_b, inits_b)) => { + self.eq_qpath(path_a, path_b) + && inits_a.iter().zip(*inits_b).all(|(init_a, init_b)| { + self.eq_const_arg(init_a.expr, init_b.expr) + }) + } // Use explicit match for now since ConstArg is undergoing flux. - (ConstArgKind::Path(..), ConstArgKind::Anon(..)) - | (ConstArgKind::Anon(..), ConstArgKind::Path(..)) - | (ConstArgKind::Infer(..) | ConstArgKind::Error(..), _) - | (_, ConstArgKind::Infer(..) | ConstArgKind::Error(..)) => false, + (ConstArgKind::Path(..), _) + | (ConstArgKind::Anon(..), _) + | (ConstArgKind::Infer(..), _) + | (ConstArgKind::Struct(..), _) + | (ConstArgKind::Error(..), _) => false, } } @@ -1332,6 +1339,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { match &const_arg.kind { ConstArgKind::Path(path) => self.hash_qpath(path), ConstArgKind::Anon(anon) => self.hash_body(anon.body), + ConstArgKind::Struct(path, inits) => { + self.hash_qpath(path); + for init in *inits { + self.hash_const_arg(init.expr); + } + } ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } diff --git a/src/tools/miri/src/intrinsics/atomic.rs b/src/tools/miri/src/intrinsics/atomic.rs index 9bb0ab70de23..481b6716c70c 100644 --- a/src/tools/miri/src/intrinsics/atomic.rs +++ b/src/tools/miri/src/intrinsics/atomic.rs @@ -31,7 +31,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let get_ord_at = |i: usize| { let ordering = generic_args.const_at(i).to_value(); - ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering() + ordering.to_branch()[0].to_value().to_leaf().to_atomic_ordering() }; fn read_ord(ord: AtomicOrdering) -> AtomicReadOrd { From 7a3097f18d704f46572166daedf20c25a237a4c5 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 19 Nov 2025 23:28:50 +0000 Subject: [PATCH 1190/3801] Fix tools --- clippy_lints/src/utils/author.rs | 1 + clippy_utils/src/consts.rs | 2 +- clippy_utils/src/hir_utils.rs | 21 +++++++++++++++++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 03cbb0311c6c..685b0a9c0d60 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -319,6 +319,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { chain!(self, "let ConstArgKind::Anon({anon_const}) = {const_arg}.kind"); self.body(field!(anon_const.body)); }, + ConstArgKind::Struct(..) => chain!(self, "let ConstArgKind::Struct(..) = {const_arg}.kind"), ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), } diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 7e3fa4f9909b..e43b0b95d9f7 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1139,7 +1139,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, + ConstArgKind::Struct(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, }, } } diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index c6d82c0e63fa..5cadf5fbb869 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -477,11 +477,18 @@ impl HirEqInterExpr<'_, '_, '_> { (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true, + (ConstArgKind::Struct(path_a, inits_a), ConstArgKind::Struct(path_b, inits_b)) => { + self.eq_qpath(path_a, path_b) + && inits_a.iter().zip(*inits_b).all(|(init_a, init_b)| { + self.eq_const_arg(init_a.expr, init_b.expr) + }) + } // Use explicit match for now since ConstArg is undergoing flux. - (ConstArgKind::Path(..), ConstArgKind::Anon(..)) - | (ConstArgKind::Anon(..), ConstArgKind::Path(..)) - | (ConstArgKind::Infer(..) | ConstArgKind::Error(..), _) - | (_, ConstArgKind::Infer(..) | ConstArgKind::Error(..)) => false, + (ConstArgKind::Path(..), _) + | (ConstArgKind::Anon(..), _) + | (ConstArgKind::Infer(..), _) + | (ConstArgKind::Struct(..), _) + | (ConstArgKind::Error(..), _) => false, } } @@ -1332,6 +1339,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { match &const_arg.kind { ConstArgKind::Path(path) => self.hash_qpath(path), ConstArgKind::Anon(anon) => self.hash_body(anon.body), + ConstArgKind::Struct(path, inits) => { + self.hash_qpath(path); + for init in *inits { + self.hash_const_arg(init.expr); + } + } ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } From f186dadb0dee2a1065743e76bf0be99dd4046926 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 20 Dec 2025 11:22:16 +0100 Subject: [PATCH 1191/3801] compiletest: Use `DirectiveLine` also for debuginfo (read: debugger) tests This not only reduces code duplication already, it also gives us revision parsing for free which we need in an upcoming commit. --- src/tools/compiletest/src/directives.rs | 3 +- src/tools/compiletest/src/runtest/debugger.rs | 28 +++++++------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index d1e0c5d95001..5865954558d8 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -15,7 +15,7 @@ use crate::directives::directive_names::{ }; pub(crate) use crate::directives::file::FileDirectives; use crate::directives::handlers::DIRECTIVE_HANDLERS_MAP; -use crate::directives::line::{DirectiveLine, line_directive}; +use crate::directives::line::DirectiveLine; use crate::directives::needs::CachedNeedsConditions; use crate::edition::{Edition, parse_edition}; use crate::errors::ErrorKind; @@ -29,6 +29,7 @@ mod directive_names; mod file; mod handlers; mod line; +pub(crate) use line::line_directive; mod line_number; pub(crate) use line_number::LineNumber; mod needs; diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs index c83e00c1006e..64b969f11059 100644 --- a/src/tools/compiletest/src/runtest/debugger.rs +++ b/src/tools/compiletest/src/runtest/debugger.rs @@ -4,7 +4,7 @@ use std::io::{BufRead, BufReader}; use camino::{Utf8Path, Utf8PathBuf}; -use crate::directives::LineNumber; +use crate::directives::{LineNumber, line_directive}; use crate::runtest::ProcRes; /// Representation of information to invoke a debugger and check its output @@ -37,15 +37,19 @@ impl DebuggerCommands { continue; } - let Some(line) = line.trim_start().strip_prefix("//@").map(str::trim_start) else { + let Some(directive) = line_directive(file, line_number, &line) else { continue; }; - if let Some(command) = parse_name_value(&line, &command_directive) { - commands.push(command); + if directive.name == command_directive + && let Some(command) = directive.value_after_colon() + { + commands.push(command.to_string()); } - if let Some(pattern) = parse_name_value(&line, &check_directive) { - check_lines.push((line_number, pattern)); + if directive.name == check_directive + && let Some(pattern) = directive.value_after_colon() + { + check_lines.push((line_number, pattern.to_string())); } } @@ -103,18 +107,6 @@ impl DebuggerCommands { } } -/// Split off from the main `parse_name_value_directive`, so that improvements -/// to directive handling aren't held back by debuginfo test commands. -fn parse_name_value(line: &str, name: &str) -> Option { - if let Some(after_name) = line.strip_prefix(name) - && let Some(value) = after_name.strip_prefix(':') - { - Some(value.to_owned()) - } else { - None - } -} - /// Check that the pattern in `check_line` applies to `line`. Returns `true` if they do match. fn check_single_line(line: &str, check_line: &str) -> bool { // Allow check lines to leave parts unspecified (e.g., uninitialized From 4516daccb36711f2d4536561762ed49281c2a0e8 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 20 Dec 2025 11:41:05 +0100 Subject: [PATCH 1192/3801] compiletest: Support revisions in debuginfo (read: debugger) tests --- src/tools/compiletest/src/runtest/debugger.rs | 26 ++++++++++++++++--- .../compiletest/src/runtest/debuginfo.rs | 6 ++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs index 64b969f11059..70996004a336 100644 --- a/src/tools/compiletest/src/runtest/debugger.rs +++ b/src/tools/compiletest/src/runtest/debugger.rs @@ -17,10 +17,16 @@ pub(super) struct DebuggerCommands { check_lines: Vec<(LineNumber, String)>, /// Source file name file: Utf8PathBuf, + /// The revision being tested, if any + revision: Option, } impl DebuggerCommands { - pub fn parse_from(file: &Utf8Path, debugger_prefix: &str) -> Result { + pub fn parse_from( + file: &Utf8Path, + debugger_prefix: &str, + test_revision: Option<&str>, + ) -> Result { let command_directive = format!("{debugger_prefix}-command"); let check_directive = format!("{debugger_prefix}-check"); @@ -41,6 +47,10 @@ impl DebuggerCommands { continue; }; + if !directive.applies_to_test_revision(test_revision) { + continue; + } + if directive.name == command_directive && let Some(command) = directive.value_after_colon() { @@ -53,7 +63,13 @@ impl DebuggerCommands { } } - Ok(Self { commands, breakpoint_lines, check_lines, file: file.to_path_buf() }) + Ok(Self { + commands, + breakpoint_lines, + check_lines, + file: file.to_path_buf(), + revision: test_revision.map(str::to_owned), + }) } /// Given debugger output and lines to check, ensure that every line is @@ -85,9 +101,11 @@ impl DebuggerCommands { Ok(()) } else { let fname = self.file.file_name().unwrap(); + let revision_suffix = + self.revision.as_ref().map_or(String::new(), |r| format!("#{}", r)); let mut msg = format!( - "check directive(s) from `{}` not found in debugger output. errors:", - self.file + "check directive(s) from `{}{}` not found in debugger output. errors:", + self.file, revision_suffix ); for (src_lineno, err_line) in missing { diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index 83b61b9be57d..9d6edaddc1b7 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -46,7 +46,7 @@ impl TestCx<'_> { } // Parse debugger commands etc from test files - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "cdb") + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "cdb", self.revision) .unwrap_or_else(|e| self.fatal(&e)); // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands @@ -105,7 +105,7 @@ impl TestCx<'_> { } fn run_debuginfo_gdb_test(&self) { - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "gdb") + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "gdb", self.revision) .unwrap_or_else(|e| self.fatal(&e)); let mut cmds = dbg_cmds.commands.join("\n"); @@ -366,7 +366,7 @@ impl TestCx<'_> { } // Parse debugger commands etc from test files - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "lldb") + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "lldb", self.revision) .unwrap_or_else(|e| self.fatal(&e)); // Write debugger script: From 423a8dc4090a47589a61e30a139731eb500892db Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 20 Dec 2025 11:49:04 +0100 Subject: [PATCH 1193/3801] tests/debuginfo/macro-stepping.rs: Add revisions `default-mir-passes`, `no-SingleUseConsts-mir-pass` To prevent the test from regressing both with and without `SingleUseConsts` MIR pass. --- tests/debuginfo/macro-stepping.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/debuginfo/macro-stepping.rs b/tests/debuginfo/macro-stepping.rs index 0dff383be825..ba3a4452041a 100644 --- a/tests/debuginfo/macro-stepping.rs +++ b/tests/debuginfo/macro-stepping.rs @@ -14,8 +14,10 @@ #[macro_use] extern crate macro_stepping; // exports new_scope!() -//@ compile-flags:-g -Zmir-enable-passes=-SingleUseConsts -// SingleUseConsts shouldn't need to be disabled, see #128945 +//@ compile-flags: -g +// FIXME(#128945): SingleUseConsts shouldn't need to be disabled. +//@ revisions: default-mir-passes no-SingleUseConsts-mir-pass +//@ [no-SingleUseConsts-mir-pass] compile-flags: -Zmir-enable-passes=-SingleUseConsts // === GDB TESTS =================================================================================== @@ -48,7 +50,7 @@ extern crate macro_stepping; // exports new_scope!() //@ gdb-check:[...]#inc-loc2[...] //@ gdb-command:next //@ gdb-command:frame -//@ gdb-check:[...]#inc-loc3[...] +//@ [no-SingleUseConsts-mir-pass] gdb-check:[...]#inc-loc3[...] // === LLDB TESTS ================================================================================== From bbf4ec3b0fd31a813208791dcce4264ed6bdbae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 23 Dec 2025 15:47:03 +0100 Subject: [PATCH 1194/3801] Add support for `automation/bors/auto` merge branch --- .github/workflows/ci.yml | 7 ++++--- src/ci/citool/src/main.rs | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05aa600e649e..bb6bc325a3bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,7 @@ on: - try - try-perf - automation/bors/try + - automation/bors/auto pull_request: branches: - "**" @@ -56,7 +57,7 @@ jobs: - name: Test citool # Only test citool on the auto branch, to reduce latency of the calculate matrix job # on PR/try builds. - if: ${{ github.ref == 'refs/heads/auto' }} + if: ${{ github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto' }} run: | cd src/ci/citool CARGO_INCREMENTAL=0 cargo test @@ -79,7 +80,7 @@ jobs: # access the environment. # # We only enable the environment for the rust-lang/rust repository, so that CI works on forks. - environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto')) && 'bors') || '' }} + environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} env: CI_JOB_NAME: ${{ matrix.name }} CI_JOB_DOC_URL: ${{ matrix.doc_url }} @@ -313,7 +314,7 @@ jobs: needs: [ calculate_matrix, job ] # !cancelled() executes the job regardless of whether the previous jobs passed or failed if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }} - environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto')) && 'bors') || '' }} + environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }} steps: - name: checkout the source code uses: actions/checkout@v5 diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 4fe9cee900ca..d7b491d38f41 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -46,7 +46,9 @@ impl GitHubContext { let patterns = if !patterns.is_empty() { Some(patterns) } else { None }; Some(RunType::TryJob { job_patterns: patterns }) } - ("push", "refs/heads/auto") => Some(RunType::AutoJob), + ("push", "refs/heads/auto" | "refs/heads/automation/bors/auto") => { + Some(RunType::AutoJob) + } ("push", "refs/heads/main") => Some(RunType::MainJob), _ => None, } From c252af5cbbe576acf5ffefa44687c8cf27a5c294 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Dec 2025 15:30:38 +0000 Subject: [PATCH 1195/3801] Fix audit workflow --- .github/workflows/audit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 27c95572ef87..274b9504beb0 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v4 - run: | - sed -i 's/components.*/components = []/' rust-toolchain + sed -i 's/components.*/components = []/' rust-toolchain.toml - uses: rustsec/audit-check@v1.4.1 with: token: ${{ secrets.GITHUB_TOKEN }} From 6bb3a40d535634d9004db49d639d900ecf66fc7f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:48:27 +0000 Subject: [PATCH 1196/3801] Update to Cranelift 0.127 --- Cargo.lock | 173 ++++++++++++++++------------------------------------- Cargo.toml | 24 ++++---- 2 files changed, 63 insertions(+), 134 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 617c7f0e34cd..3d13b5540e19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,42 +43,42 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cranelift-assembler-x64" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7631e609c97f063f9777aae405e8492abf9bf92336d7aa3f875403dd4ffd7d" +checksum = "8bd963a645179fa33834ba61fa63353998543b07f877e208da9eb47d4a70d1e7" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c030edccdc4a5bbf28fbfe7701b5cd1f9854b4445184dd34af2a7e8f8db6f45" +checksum = "3f6d5739c9dc6b5553ca758d78d87d127dd19f397f776efecf817b8ba8d0bb01" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb544c1242d0ca98baf01873ebba96c79d5df155d5108d9bb699aefc741f5e6d" +checksum = "ff402c11bb1c9652b67a3e885e84b1b8d00c13472c8fd85211e06a41a63c3e03" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0325aecbafec053d3d3f082edfdca7937e2945e7f09c5ff9672e05198312282" +checksum = "769a0d88c2f5539e9c5536a93a7bf164b0dc68d91e3d00723e5b4ffc1440afdc" [[package]] name = "cranelift-codegen" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb3236fd319ae897ba00c8a25105081de5c1348576def0e96c062ad259f87a7" +checksum = "d4351f721fb3b26add1c180f0a75c7474bab2f903c8b777c6ca65238ded59a78" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b8791c911a361c539130ace34fb726b16aca4216470ec75d75264b1495c8a3a" +checksum = "61f86c0ba5b96713643f4dd0de0df12844de9c7bb137d6829b174b706939aa74" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -114,33 +114,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ead718c2a10990870c19b2497b5a04b8aae6024485e33da25b5d02e35819e0" +checksum = "f08605eee8d51fd976a970bd5b16c9529b51b624f8af68f80649ffb172eb85a4" [[package]] name = "cranelift-control" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0a57fc972b5651047efddccb99440d103d9d8c13393ccebde15ddd5b6a1181b" +checksum = "623aab0a09e40f0cf0b5d35eb7832bae4c4f13e3768228e051a6c1a60e88ef5f" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aae980b4a1678b601eab2f52e372ed0b3c9565a31c17f380008cb97b3a699c5" +checksum = "ea0f066e07e3bcbe38884cc5c94c32c7a90267d69df80f187d9dfe421adaa7c4" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78877016b607982ca1708c0dd4ce23bde04581a39854c9b43a1dca43625b54c" +checksum = "40865b02a0e52ca8e580ad64feef530cb1d05f6bb4972b4eef05e3eaeae81701" dependencies = [ "cranelift-codegen", "log", @@ -150,15 +150,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc46a68b46d4f53f9f2f02ab8d3a34b00f03a21c124a7a965b8cbf5fdb6773b" +checksum = "104b3c117ae513e9af1d90679842101193a5ccb96ac9f997966d85ea25be2852" [[package]] name = "cranelift-jit" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df920009af919ad9df52eb7b47b1895145822e0c29da9b715a876fc8ecc6d82" +checksum = "3aa5f855cfb8e4253ed2d0dfc1a0b6ebe4912e67aa8b7ee14026ff55ca17f1fe" dependencies = [ "anyhow", "cranelift-codegen", @@ -171,14 +171,14 @@ dependencies = [ "region", "target-lexicon", "wasmtime-internal-jit-icache-coherence", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "cranelift-module" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddcf313629071ce74de8e59f02092f5453d1a01047607fc4ad36886b8bd1486c" +checksum = "b1d01806b191b59f4fc4680293dd5f554caf2de5b62f95eff5beef7acb46c29c" dependencies = [ "anyhow", "cranelift-codegen", @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03faa07ec8cf373250a8252eb773d098ff88259fa1c19ee1ecde8012839f4097" +checksum = "e5c54e0a358bc05b48f2032e1c320e7f468da068604f2869b77052eab68eb0fe" dependencies = [ "cranelift-codegen", "libc", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cca62c14f3c2e4f438192562bbf82d1a98a59543cc66ba04fb658ba99f515a6" +checksum = "3d17e0216be5daabab616647c1918e06dae0708474ba5f7b7762ac24ea5eb126" dependencies = [ "anyhow", "cranelift-codegen", @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.126.0" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0484cb32c527a742e1bba09ef174acac0afb1dcf623ef1adda42849200edcd2e" +checksum = "cc6f4b039f453b66c75e9f7886e5a2af96276e151f44dc19b24b58f9a0c98009" [[package]] name = "crc32fast" @@ -293,7 +293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" dependencies = [ "cfg-if", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -469,31 +469,25 @@ checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "39.0.0" +version = "40.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f67986f5c499274ae5b2ba5b173bba0b95d1381f5ca70d8eec657f2392117d8" +checksum = "0858b470463f3e7c73acd6049046049e64be17b98901c2db5047450cf83df1fe" dependencies = [ "anyhow", "cfg-if", "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "wasmtime-internal-math" -version = "39.0.0" +version = "40.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a681733e9b5d5d8804ee6cacd59f92c0d87ba2274f42ee1d4e5a943828d0075d" +checksum = "222e1a590ece4e898f20af1e541b61d2cb803f2557e7eaff23e6c1db5434454a" dependencies = [ "libm", ] -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" @@ -506,16 +500,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] name = "windows-sys" -version = "0.60.2" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.53.3", + "windows-link", ] [[package]] @@ -524,31 +518,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" -dependencies = [ - "windows-link 0.1.3", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -557,92 +534,44 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" diff --git a/Cargo.toml b/Cargo.toml index 58e61cd0b9d7..ee4bde477c47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,12 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.126.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.126.0" } -cranelift-module = { version = "0.126.0" } -cranelift-native = { version = "0.126.0" } -cranelift-jit = { version = "0.126.0", optional = true } -cranelift-object = { version = "0.126.0" } +cranelift-codegen = { version = "0.127.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.127.0" } +cranelift-module = { version = "0.127.0" } +cranelift-native = { version = "0.127.0" } +cranelift-jit = { version = "0.127.0", optional = true } +cranelift-object = { version = "0.127.0" } target-lexicon = "0.13" gimli = { version = "0.32", default-features = false, features = ["write"] } object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } @@ -24,12 +24,12 @@ smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-39.0.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } From 6f3f6bdacb75571a87f08e0920d9c191b3d65ded Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:22:22 +0000 Subject: [PATCH 1197/3801] Rustup to rustc 1.94.0-nightly (4f14395c3 2025-12-22) --- rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 6ce49eb4ccf0..b157c5879ba7 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-12-18" +channel = "nightly-2025-12-23" components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] profile = "minimal" From d6a2a52883d5b47cb7232466a3e1911a1d46680e Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 23 Dec 2025 22:30:00 +0530 Subject: [PATCH 1198/3801] return error on combination of bidirectional message and json framing --- .../proc-macro-api/src/bidirectional_protocol.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index bd74738bbdf5..e919ff48fe4c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -22,7 +22,7 @@ use crate::{ }, }, process::ProcMacroServerProcess, - transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, + transport::codec::postcard::PostcardProtocol, version, }; @@ -210,14 +210,16 @@ fn run_request( msg: BidirectionalMessage, callback: SubCallback<'_>, ) -> Result { - if let Some(server_error) = srv.exited() { - return Err(server_error.clone()); + if let Some(err) = srv.exited() { + return Err(err.clone()); } - if srv.use_postcard() { - srv.run_bidirectional::(msg, callback) - } else { - srv.run_bidirectional::(msg, callback) + match srv.use_postcard() { + true => srv.run_bidirectional::(msg, callback), + false => Err(ServerError { + message: "bidirectional messaging does not support JSON".to_owned(), + io: None, + }), } } From 16b219ab3b183795069b4c07d18448c2f919ba6e Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Mon, 22 Dec 2025 12:15:35 +0000 Subject: [PATCH 1199/3801] cleanup slice iter 2 --- library/core/src/slice/iter.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index cfcb51dd2577..0ddf94559e80 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -2495,19 +2495,13 @@ impl<'a, T> Iterator for RChunksMut<'a, T> { && end < self.v.len() { let end = self.v.len() - end; - let start = match end.checked_sub(self.chunk_size) { - Some(sum) => sum, - None => 0, - }; - // SAFETY: This type ensures that self.v is a valid pointer with a correct len. - // Therefore the bounds check in split_at_mut guarantees the split point is inbounds. - let (head, tail) = unsafe { self.v.split_at_mut(start) }; - // SAFETY: This type ensures that self.v is a valid pointer with a correct len. - // Therefore the bounds check in split_at_mut guarantees the split point is inbounds. - let (nth, _) = unsafe { tail.split_at_mut(end - start) }; - self.v = head; + // SAFETY: The self.v contract ensures that any split_at_mut is valid. + let (rest, _) = unsafe { self.v.split_at_mut(end) }; + // SAFETY: The self.v contract ensures that any split_at_mut is valid. + let (rest, chunk) = unsafe { rest.split_at_mut(end.saturating_sub(self.chunk_size)) }; + self.v = rest; // SAFETY: Nothing else points to or will point to the contents of this slice. - Some(unsafe { &mut *nth }) + Some(unsafe { &mut *chunk }) } else { self.v = &mut []; None From df2833d5d34aafcd6adc3a91ca297795a0b830ac Mon Sep 17 00:00:00 2001 From: Ada Alakbarova <58857108+ada4a@users.noreply.github.com> Date: Tue, 23 Dec 2025 21:20:11 +0100 Subject: [PATCH 1200/3801] Fix typo in a URL --- .../rust-analyzer/docs/book/src/contributing/architecture.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/architecture.md b/src/tools/rust-analyzer/docs/book/src/contributing/architecture.md index 67653ebd7437..50f60bcdccc1 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/architecture.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/architecture.md @@ -10,7 +10,7 @@ See also these implementation-related blog posts: * * -* +* * * From e7965821e8bb671937e59f99894537d436060fc0 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 23 Dec 2025 23:35:58 +0200 Subject: [PATCH 1201/3801] use new term in description of --target --- compiler/rustc_session/src/config.rs | 2 +- src/doc/man/rustc.1 | 4 ++-- src/doc/rustc/src/command-line-arguments.md | 2 +- tests/run-make/rustc-help/help-v.stdout | 2 +- tests/run-make/rustc-help/help.stdout | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2774333573f6..f326442c0879 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1798,7 +1798,7 @@ pub fn rustc_optgroups() -> Vec { "", ), opt(Stable, Flag, "", "test", "Build a test harness", ""), - opt(Stable, Opt, "", "target", "Target triple for which the code is compiled", ""), + opt(Stable, Opt, "", "target", "Target tuple for which the code is compiled", ""), opt(Stable, Multi, "A", "allow", "Set lint allowed", ""), opt(Stable, Multi, "W", "warn", "Set lint warnings", ""), opt(Stable, Multi, "", "force-warn", "Set lint force-warn", ""), diff --git a/src/doc/man/rustc.1 b/src/doc/man/rustc.1 index 534af3f85bb9..2a91774d671a 100644 --- a/src/doc/man/rustc.1 +++ b/src/doc/man/rustc.1 @@ -79,8 +79,8 @@ Provide a detailed explanation of an error message. Build a test harness. .TP \fB\-\-target\fR \fITARGET\fR -Target triple for which the code is compiled. This option defaults to the host’s target -triple. The target triple has the general format \-\-\-, where: +Target tuple for which the code is compiled. This option defaults to the host’s target +tuple. The target tuple has the general format \-\-\-, where: .RS .TP .B diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 0b15fbc24dfc..507af9e2ffef 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -284,7 +284,7 @@ and instead produce a test harness. See the [Tests chapter](tests/index.md) for more information about tests. -## `--target`: select a target triple to build +## `--target`: select a target tuple to build This controls which [target](targets/index.md) to produce. diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout index c41cb5e3bde8..cf055e220c0d 100644 --- a/tests/run-make/rustc-help/help-v.stdout +++ b/tests/run-make/rustc-help/help-v.stdout @@ -51,7 +51,7 @@ Options: --explain Provide a detailed explanation of an error message --test Build a test harness --target - Target triple for which the code is compiled + Target tuple for which the code is compiled -A, --allow Set lint allowed -W, --warn Set lint warnings --force-warn diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout index 5e13a900484d..4075dd028299 100644 --- a/tests/run-make/rustc-help/help.stdout +++ b/tests/run-make/rustc-help/help.stdout @@ -51,7 +51,7 @@ Options: --explain Provide a detailed explanation of an error message --test Build a test harness --target - Target triple for which the code is compiled + Target tuple for which the code is compiled -A, --allow Set lint allowed -W, --warn Set lint warnings --force-warn From bc943aa8ea5aad5690eef4594ad50da949c181fb Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Tue, 23 Dec 2025 22:55:19 +0000 Subject: [PATCH 1202/3801] fix: `checked_conversions` wrongly unmangled macros --- clippy_lints/src/checked_conversions.rs | 5 +-- tests/ui/checked_conversions.fixed | 16 ++++++++++ tests/ui/checked_conversions.rs | 16 ++++++++++ tests/ui/checked_conversions.stderr | 42 ++++++++++++++----------- 4 files changed, 59 insertions(+), 20 deletions(-) diff --git a/clippy_lints/src/checked_conversions.rs b/clippy_lints/src/checked_conversions.rs index 9b3822f9d8f0..8303897d1294 100644 --- a/clippy_lints/src/checked_conversions.rs +++ b/clippy_lints/src/checked_conversions.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal, sym}; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, TyKind}; @@ -80,7 +80,8 @@ impl LateLintPass<'_> for CheckedConversions { && self.msrv.meets(cx, msrvs::TRY_FROM) { let mut applicability = Applicability::MachineApplicable; - let snippet = snippet_with_applicability(cx, cv.expr_to_cast.span, "_", &mut applicability); + let (snippet, _) = + snippet_with_context(cx, cv.expr_to_cast.span, item.span.ctxt(), "_", &mut applicability); span_lint_and_sugg( cx, CHECKED_CONVERSIONS, diff --git a/tests/ui/checked_conversions.fixed b/tests/ui/checked_conversions.fixed index 6175275ef047..2309a053146f 100644 --- a/tests/ui/checked_conversions.fixed +++ b/tests/ui/checked_conversions.fixed @@ -1,6 +1,7 @@ #![allow( clippy::cast_lossless, clippy::legacy_numeric_constants, + clippy::no_effect, unused, // Int::max_value will be deprecated in the future deprecated, @@ -105,4 +106,19 @@ fn msrv_1_34() { //~^ checked_conversions } +fn issue16293() { + struct Outer { + inner: u32, + } + let outer = Outer { inner: 42 }; + macro_rules! dot_inner { + ($obj:expr) => { + $obj.inner + }; + } + + i32::try_from(dot_inner!(outer)).is_ok(); + //~^ checked_conversions +} + fn main() {} diff --git a/tests/ui/checked_conversions.rs b/tests/ui/checked_conversions.rs index 9ed0e8f660d0..dabb552eba27 100644 --- a/tests/ui/checked_conversions.rs +++ b/tests/ui/checked_conversions.rs @@ -1,6 +1,7 @@ #![allow( clippy::cast_lossless, clippy::legacy_numeric_constants, + clippy::no_effect, unused, // Int::max_value will be deprecated in the future deprecated, @@ -105,4 +106,19 @@ fn msrv_1_34() { //~^ checked_conversions } +fn issue16293() { + struct Outer { + inner: u32, + } + let outer = Outer { inner: 42 }; + macro_rules! dot_inner { + ($obj:expr) => { + $obj.inner + }; + } + + dot_inner!(outer) <= i32::MAX as u32; + //~^ checked_conversions +} + fn main() {} diff --git a/tests/ui/checked_conversions.stderr b/tests/ui/checked_conversions.stderr index 624876dacb26..6018dacace39 100644 --- a/tests/ui/checked_conversions.stderr +++ b/tests/ui/checked_conversions.stderr @@ -1,5 +1,5 @@ error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:15:13 + --> tests/ui/checked_conversions.rs:16:13 | LL | let _ = value <= (u32::max_value() as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` @@ -8,100 +8,106 @@ LL | let _ = value <= (u32::max_value() as i64) && value >= 0; = help: to override `-D warnings` add `#[allow(clippy::checked_conversions)]` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:17:13 + --> tests/ui/checked_conversions.rs:18:13 | LL | let _ = value <= (u32::MAX as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:22:13 + --> tests/ui/checked_conversions.rs:23:13 | LL | let _ = value <= i64::from(u16::max_value()) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:24:13 + --> tests/ui/checked_conversions.rs:25:13 | LL | let _ = value <= i64::from(u16::MAX) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:29:13 + --> tests/ui/checked_conversions.rs:30:13 | LL | let _ = value <= (u8::max_value() as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:31:13 + --> tests/ui/checked_conversions.rs:32:13 | LL | let _ = value <= (u8::MAX as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:38:13 + --> tests/ui/checked_conversions.rs:39:13 | LL | let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:40:13 + --> tests/ui/checked_conversions.rs:41:13 | LL | let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:45:13 + --> tests/ui/checked_conversions.rs:46:13 | LL | let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:47:13 + --> tests/ui/checked_conversions.rs:48:13 | LL | let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:54:13 + --> tests/ui/checked_conversions.rs:55:13 | LL | let _ = value <= i32::max_value() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:56:13 + --> tests/ui/checked_conversions.rs:57:13 | LL | let _ = value <= i32::MAX as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:61:13 + --> tests/ui/checked_conversions.rs:62:13 | LL | let _ = value <= isize::max_value() as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:63:13 + --> tests/ui/checked_conversions.rs:64:13 | LL | let _ = value <= isize::MAX as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:68:13 + --> tests/ui/checked_conversions.rs:69:13 | LL | let _ = value <= u16::max_value() as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:70:13 + --> tests/ui/checked_conversions.rs:71:13 | LL | let _ = value <= u16::MAX as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> tests/ui/checked_conversions.rs:104:13 + --> tests/ui/checked_conversions.rs:105:13 | LL | let _ = value <= (u32::max_value() as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` -error: aborting due to 17 previous errors +error: checked cast can be simplified + --> tests/ui/checked_conversions.rs:120:5 + | +LL | dot_inner!(outer) <= i32::MAX as u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(dot_inner!(outer)).is_ok()` + +error: aborting due to 18 previous errors From ffbdb578b0e6e9d4657abbd3d6454bde4bed1869 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Tue, 23 Dec 2025 23:08:32 +0000 Subject: [PATCH 1203/3801] fix: `manual_ignore_case_cmp` wrongly unmangled macros --- clippy_lints/src/manual_ignore_case_cmp.rs | 10 ++++----- tests/ui/manual_ignore_case_cmp.fixed | 20 +++++++++++++++++ tests/ui/manual_ignore_case_cmp.rs | 20 +++++++++++++++++ tests/ui/manual_ignore_case_cmp.stderr | 26 +++++++++++++++++++++- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/manual_ignore_case_cmp.rs b/clippy_lints/src/manual_ignore_case_cmp.rs index 25057b4aeaa2..1c20a8f81efb 100644 --- a/clippy_lints/src/manual_ignore_case_cmp.rs +++ b/clippy_lints/src/manual_ignore_case_cmp.rs @@ -1,7 +1,7 @@ use crate::manual_ignore_case_cmp::MatchType::{Literal, ToAscii}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeDef; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sym; use rustc_ast::LitKind; use rustc_errors::Applicability; @@ -111,14 +111,12 @@ impl LateLintPass<'_> for ManualIgnoreCaseCmp { "manual case-insensitive ASCII comparison", |diag| { let mut app = Applicability::MachineApplicable; + let (left_snip, _) = snippet_with_context(cx, left_span, expr.span.ctxt(), "..", &mut app); + let (right_snip, _) = snippet_with_context(cx, right_span, expr.span.ctxt(), "..", &mut app); diag.span_suggestion_verbose( expr.span, "consider using `.eq_ignore_ascii_case()` instead", - format!( - "{neg}{}.eq_ignore_ascii_case({deref}{})", - snippet_with_applicability(cx, left_span, "_", &mut app), - snippet_with_applicability(cx, right_span, "_", &mut app) - ), + format!("{neg}{left_snip}.eq_ignore_ascii_case({deref}{right_snip})"), app, ); }, diff --git a/tests/ui/manual_ignore_case_cmp.fixed b/tests/ui/manual_ignore_case_cmp.fixed index cd7adc20b127..f0e413aaec0d 100644 --- a/tests/ui/manual_ignore_case_cmp.fixed +++ b/tests/ui/manual_ignore_case_cmp.fixed @@ -160,3 +160,23 @@ fn ref_osstring(a: OsString, b: &OsString) { b.eq_ignore_ascii_case(a); //~^ manual_ignore_case_cmp } + +fn wrongly_unmangled_macros(a: &str, b: &str) -> bool { + struct S<'a> { + inner: &'a str, + } + + let a = S { inner: a }; + let b = S { inner: b }; + + macro_rules! dot_inner { + ($s:expr) => { + $s.inner + }; + } + + dot_inner!(a).eq_ignore_ascii_case(dot_inner!(b)) + //~^ manual_ignore_case_cmp + || dot_inner!(a).eq_ignore_ascii_case("abc") + //~^ manual_ignore_case_cmp +} diff --git a/tests/ui/manual_ignore_case_cmp.rs b/tests/ui/manual_ignore_case_cmp.rs index 85f6719827c9..9802e87cd233 100644 --- a/tests/ui/manual_ignore_case_cmp.rs +++ b/tests/ui/manual_ignore_case_cmp.rs @@ -160,3 +160,23 @@ fn ref_osstring(a: OsString, b: &OsString) { b.to_ascii_lowercase() == a.to_ascii_lowercase(); //~^ manual_ignore_case_cmp } + +fn wrongly_unmangled_macros(a: &str, b: &str) -> bool { + struct S<'a> { + inner: &'a str, + } + + let a = S { inner: a }; + let b = S { inner: b }; + + macro_rules! dot_inner { + ($s:expr) => { + $s.inner + }; + } + + dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase() + //~^ manual_ignore_case_cmp + || dot_inner!(a).to_ascii_lowercase() == "abc" + //~^ manual_ignore_case_cmp +} diff --git a/tests/ui/manual_ignore_case_cmp.stderr b/tests/ui/manual_ignore_case_cmp.stderr index fa7fadd91076..2f698e076ed3 100644 --- a/tests/ui/manual_ignore_case_cmp.stderr +++ b/tests/ui/manual_ignore_case_cmp.stderr @@ -588,5 +588,29 @@ LL - b.to_ascii_lowercase() == a.to_ascii_lowercase(); LL + b.eq_ignore_ascii_case(a); | -error: aborting due to 49 previous errors +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:178:5 + | +LL | dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL - dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase() +LL + dot_inner!(a).eq_ignore_ascii_case(dot_inner!(b)) + | + +error: manual case-insensitive ASCII comparison + --> tests/ui/manual_ignore_case_cmp.rs:180:12 + | +LL | || dot_inner!(a).to_ascii_lowercase() == "abc" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `.eq_ignore_ascii_case()` instead + | +LL - || dot_inner!(a).to_ascii_lowercase() == "abc" +LL + || dot_inner!(a).eq_ignore_ascii_case("abc") + | + +error: aborting due to 51 previous errors From d30647b7f2085dd073f756aca40cf965b060921a Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Tue, 23 Dec 2025 23:13:13 +0000 Subject: [PATCH 1204/3801] fix: `manual_ilog2` wrongly unmangled macros --- clippy_lints/src/manual_ilog2.rs | 4 ++-- tests/ui/manual_ilog2.fixed | 17 +++++++++++++++++ tests/ui/manual_ilog2.rs | 17 +++++++++++++++++ tests/ui/manual_ilog2.stderr | 14 +++++++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/manual_ilog2.rs b/clippy_lints/src/manual_ilog2.rs index 1c61db530606..4b411a60f3bf 100644 --- a/clippy_lints/src/manual_ilog2.rs +++ b/clippy_lints/src/manual_ilog2.rs @@ -1,7 +1,7 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::{is_from_proc_macro, sym}; use rustc_ast::LitKind; use rustc_data_structures::packed::Pu128; @@ -102,7 +102,7 @@ impl LateLintPass<'_> for ManualIlog2 { fn emit(cx: &LateContext<'_>, recv: &Expr<'_>, full_expr: &Expr<'_>) { let mut app = Applicability::MachineApplicable; - let recv = snippet_with_applicability(cx, recv.span, "_", &mut app); + let (recv, _) = snippet_with_context(cx, recv.span, full_expr.span.ctxt(), "_", &mut app); span_lint_and_sugg( cx, MANUAL_ILOG2, diff --git a/tests/ui/manual_ilog2.fixed b/tests/ui/manual_ilog2.fixed index a0f6d9392c30..ea86fc927c7c 100644 --- a/tests/ui/manual_ilog2.fixed +++ b/tests/ui/manual_ilog2.fixed @@ -30,3 +30,20 @@ fn foo(a: u32, b: u64) { external!($a.ilog(2)); with_span!(span; a.ilog(2)); } + +fn wrongly_unmangled_macros() { + struct S { + inner: u32, + } + + let x = S { inner: 42 }; + macro_rules! access { + ($s:expr) => { + $s.inner + }; + } + let log = access!(x).ilog2(); + //~^ manual_ilog2 + let log = access!(x).ilog2(); + //~^ manual_ilog2 +} diff --git a/tests/ui/manual_ilog2.rs b/tests/ui/manual_ilog2.rs index bd4b5d9d3c0d..8cb0e12d7361 100644 --- a/tests/ui/manual_ilog2.rs +++ b/tests/ui/manual_ilog2.rs @@ -30,3 +30,20 @@ fn foo(a: u32, b: u64) { external!($a.ilog(2)); with_span!(span; a.ilog(2)); } + +fn wrongly_unmangled_macros() { + struct S { + inner: u32, + } + + let x = S { inner: 42 }; + macro_rules! access { + ($s:expr) => { + $s.inner + }; + } + let log = 31 - access!(x).leading_zeros(); + //~^ manual_ilog2 + let log = access!(x).ilog(2); + //~^ manual_ilog2 +} diff --git a/tests/ui/manual_ilog2.stderr b/tests/ui/manual_ilog2.stderr index 7c9694f35330..d0ef8378081a 100644 --- a/tests/ui/manual_ilog2.stderr +++ b/tests/ui/manual_ilog2.stderr @@ -19,5 +19,17 @@ error: manually reimplementing `ilog2` LL | 63 - b.leading_zeros(); | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `b.ilog2()` -error: aborting due to 3 previous errors +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:45:15 + | +LL | let log = 31 - access!(x).leading_zeros(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `access!(x).ilog2()` + +error: manually reimplementing `ilog2` + --> tests/ui/manual_ilog2.rs:47:15 + | +LL | let log = access!(x).ilog(2); + | ^^^^^^^^^^^^^^^^^^ help: try: `access!(x).ilog2()` + +error: aborting due to 5 previous errors From 01b39655df52597ddf31c0e243d3bfbdbf3a0be0 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Tue, 23 Dec 2025 23:53:17 +0000 Subject: [PATCH 1205/3801] fix: `needless_bool_assign` wrongly unmangled macros --- clippy_lints/src/needless_bool.rs | 6 +++--- tests/ui/needless_bool_assign.fixed | 19 +++++++++++++++++++ tests/ui/needless_bool_assign.rs | 23 +++++++++++++++++++++++ tests/ui/needless_bool_assign.stderr | 12 +++++++++++- 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 854e927aa2f7..6b5db9dcf3e2 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::{ SpanlessEq, get_parent_expr, higher, is_block_like, is_else_clause, is_parent_stmt, is_receiver_of_method_call, @@ -171,8 +171,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool { && SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b) { let mut applicability = Applicability::MachineApplicable; - let cond = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability); - let lhs = snippet_with_applicability(cx, lhs_a.span, "..", &mut applicability); + let cond = Sugg::hir_with_context(cx, cond, e.span.ctxt(), "..", &mut applicability); + let (lhs, _) = snippet_with_context(cx, lhs_a.span, e.span.ctxt(), "..", &mut applicability); let mut sugg = if a == b { format!("{cond}; {lhs} = {a:?};") } else { diff --git a/tests/ui/needless_bool_assign.fixed b/tests/ui/needless_bool_assign.fixed index d6fab4c51b53..8fd572038140 100644 --- a/tests/ui/needless_bool_assign.fixed +++ b/tests/ui/needless_bool_assign.fixed @@ -42,3 +42,22 @@ fn issue15063(x: bool, y: bool) { } else { z = x || y; } //~^^^^^ needless_bool_assign } + +fn wrongly_unmangled_macros(must_keep: fn(usize, usize) -> bool, x: usize, y: usize) { + struct Wrapper(T); + let mut skip = Wrapper(false); + + macro_rules! invoke { + ($func:expr, $a:expr, $b:expr) => { + $func($a, $b) + }; + } + macro_rules! dot_0 { + ($w:expr) => { + $w.0 + }; + } + + dot_0!(skip) = !invoke!(must_keep, x, y); + //~^^^^^ needless_bool_assign +} diff --git a/tests/ui/needless_bool_assign.rs b/tests/ui/needless_bool_assign.rs index c504f61f4dd1..4721ab433b32 100644 --- a/tests/ui/needless_bool_assign.rs +++ b/tests/ui/needless_bool_assign.rs @@ -58,3 +58,26 @@ fn issue15063(x: bool, y: bool) { } //~^^^^^ needless_bool_assign } + +fn wrongly_unmangled_macros(must_keep: fn(usize, usize) -> bool, x: usize, y: usize) { + struct Wrapper(T); + let mut skip = Wrapper(false); + + macro_rules! invoke { + ($func:expr, $a:expr, $b:expr) => { + $func($a, $b) + }; + } + macro_rules! dot_0 { + ($w:expr) => { + $w.0 + }; + } + + if invoke!(must_keep, x, y) { + dot_0!(skip) = false; + } else { + dot_0!(skip) = true; + } + //~^^^^^ needless_bool_assign +} diff --git a/tests/ui/needless_bool_assign.stderr b/tests/ui/needless_bool_assign.stderr index 1d09b8b25a09..34ff782f34a3 100644 --- a/tests/ui/needless_bool_assign.stderr +++ b/tests/ui/needless_bool_assign.stderr @@ -62,5 +62,15 @@ LL | | z = false; LL | | } | |_____^ help: you can reduce it to: `{ z = x || y; }` -error: aborting due to 5 previous errors +error: this if-then-else expression assigns a bool literal + --> tests/ui/needless_bool_assign.rs:77:5 + | +LL | / if invoke!(must_keep, x, y) { +LL | | dot_0!(skip) = false; +LL | | } else { +LL | | dot_0!(skip) = true; +LL | | } + | |_____^ help: you can reduce it to: `dot_0!(skip) = !invoke!(must_keep, x, y);` + +error: aborting due to 6 previous errors From 21eaa04df821f0c716a9cbca2e502aef50e4d2e3 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Wed, 24 Dec 2025 00:09:43 +0000 Subject: [PATCH 1206/3801] fix: `needless_for_each` FN when `for_each` is in the expr of a block --- clippy_lints/src/needless_for_each.rs | 125 ++++++++++++---------- tests/ui/needless_for_each_fixable.fixed | 8 ++ tests/ui/needless_for_each_fixable.rs | 8 ++ tests/ui/needless_for_each_fixable.stderr | 19 +++- 4 files changed, 105 insertions(+), 55 deletions(-) diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs index d03188f1d39b..55a5a16c0099 100644 --- a/clippy_lints/src/needless_for_each.rs +++ b/clippy_lints/src/needless_for_each.rs @@ -56,8 +56,20 @@ declare_lint_pass!(NeedlessForEach => [NEEDLESS_FOR_EACH]); impl<'tcx> LateLintPass<'tcx> for NeedlessForEach { fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { - if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind - && let ExprKind::MethodCall(method_name, for_each_recv, [for_each_arg], _) = expr.kind + if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind { + check_expr(cx, expr, stmt.span); + } + } + + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) { + if let Some(expr) = block.expr { + check_expr(cx, expr, expr.span); + } + } +} + +fn check_expr(cx: &LateContext<'_>, expr: &Expr<'_>, outer_span: Span) { + if let ExprKind::MethodCall(method_name, for_each_recv, [for_each_arg], _) = expr.kind && let ExprKind::MethodCall(_, iter_recv, [], _) = for_each_recv.kind // Skip the lint if the call chain is too long. e.g. `v.field.iter().for_each()` or // `v.foo().iter().for_each()` must be skipped. @@ -76,69 +88,74 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach { // Skip the lint if the body is not safe, so as not to suggest `for … in … unsafe {}` // and suggesting `for … in … { unsafe { } }` is a little ugly. && !matches!(body.value.kind, ExprKind::Block(Block { rules: BlockCheckMode::UnsafeBlock(_), .. }, ..)) + { + let mut applicability = Applicability::MachineApplicable; + + // If any closure parameter has an explicit type specified, applying the lint would necessarily + // remove that specification, possibly breaking type inference + if fn_decl + .inputs + .iter() + .any(|input| matches!(input.kind, TyKind::Infer(..))) { - let mut applicability = Applicability::MachineApplicable; + applicability = Applicability::MaybeIncorrect; + } - // If any closure parameter has an explicit type specified, applying the lint would necessarily - // remove that specification, possibly breaking type inference - if fn_decl - .inputs - .iter() - .any(|input| matches!(input.kind, TyKind::Infer(..))) - { - applicability = Applicability::MaybeIncorrect; - } + let mut ret_collector = RetCollector::default(); + ret_collector.visit_expr(body.value); - let mut ret_collector = RetCollector::default(); - ret_collector.visit_expr(body.value); + // Skip the lint if `return` is used in `Loop` in order not to suggest using `'label`. + if ret_collector.ret_in_loop { + return; + } - // Skip the lint if `return` is used in `Loop` in order not to suggest using `'label`. - if ret_collector.ret_in_loop { - return; - } + let ret_suggs = if ret_collector.spans.is_empty() { + None + } else { + applicability = Applicability::MaybeIncorrect; + Some( + ret_collector + .spans + .into_iter() + .map(|span| (span, "continue".to_string())) + .collect(), + ) + }; - let ret_suggs = if ret_collector.spans.is_empty() { - None + let body_param_sugg = snippet_with_applicability(cx, body.params[0].pat.span, "..", &mut applicability); + let for_each_rev_sugg = snippet_with_applicability(cx, for_each_recv.span, "..", &mut applicability); + let (body_value_sugg, is_macro_call) = + snippet_with_context(cx, body.value.span, for_each_recv.span.ctxt(), "..", &mut applicability); + + let sugg = format!( + "for {} in {} {}", + body_param_sugg, + for_each_rev_sugg, + if is_macro_call { + format!("{{ {body_value_sugg}; }}") } else { - applicability = Applicability::MaybeIncorrect; - Some( - ret_collector - .spans - .into_iter() - .map(|span| (span, "continue".to_string())) - .collect(), - ) - }; - - let body_param_sugg = snippet_with_applicability(cx, body.params[0].pat.span, "..", &mut applicability); - let for_each_rev_sugg = snippet_with_applicability(cx, for_each_recv.span, "..", &mut applicability); - let (body_value_sugg, is_macro_call) = - snippet_with_context(cx, body.value.span, for_each_recv.span.ctxt(), "..", &mut applicability); - - let sugg = format!( - "for {} in {} {}", - body_param_sugg, - for_each_rev_sugg, - if is_macro_call { - format!("{{ {body_value_sugg}; }}") - } else { - match body.value.kind { - ExprKind::Block(block, _) if is_let_desugar(block) => { - format!("{{ {body_value_sugg} }}") - }, - ExprKind::Block(_, _) => body_value_sugg.to_string(), - _ => format!("{{ {body_value_sugg}; }}"), - } + match body.value.kind { + ExprKind::Block(block, _) if is_let_desugar(block) => { + format!("{{ {body_value_sugg} }}") + }, + ExprKind::Block(_, _) => body_value_sugg.to_string(), + _ => format!("{{ {body_value_sugg}; }}"), } - ); + } + ); - span_lint_and_then(cx, NEEDLESS_FOR_EACH, stmt.span, "needless use of `for_each`", |diag| { - diag.span_suggestion(stmt.span, "try", sugg, applicability); + span_lint_and_then( + cx, + NEEDLESS_FOR_EACH, + outer_span, + "needless use of `for_each`", + |diag| { + diag.span_suggestion(outer_span, "try", sugg, applicability); if let Some(ret_suggs) = ret_suggs { diag.multipart_suggestion("...and replace `return` with `continue`", ret_suggs, applicability); } - }); - } + }, + ); } } diff --git a/tests/ui/needless_for_each_fixable.fixed b/tests/ui/needless_for_each_fixable.fixed index a6d64d9afc1a..19b34f42af24 100644 --- a/tests/ui/needless_for_each_fixable.fixed +++ b/tests/ui/needless_for_each_fixable.fixed @@ -149,3 +149,11 @@ fn issue15256() { for v in vec.iter() { println!("{v}"); } //~^ needless_for_each } + +fn issue16294() { + let vec: Vec = Vec::new(); + for elem in vec.iter() { + //~^ needless_for_each + println!("{elem}"); + } +} diff --git a/tests/ui/needless_for_each_fixable.rs b/tests/ui/needless_for_each_fixable.rs index 7e74d2b428fd..f04e2555a370 100644 --- a/tests/ui/needless_for_each_fixable.rs +++ b/tests/ui/needless_for_each_fixable.rs @@ -149,3 +149,11 @@ fn issue15256() { vec.iter().for_each(|v| println!("{v}")); //~^ needless_for_each } + +fn issue16294() { + let vec: Vec = Vec::new(); + vec.iter().for_each(|elem| { + //~^ needless_for_each + println!("{elem}"); + }) +} diff --git a/tests/ui/needless_for_each_fixable.stderr b/tests/ui/needless_for_each_fixable.stderr index 204cfa36b022..121669d15072 100644 --- a/tests/ui/needless_for_each_fixable.stderr +++ b/tests/ui/needless_for_each_fixable.stderr @@ -154,5 +154,22 @@ error: needless use of `for_each` LL | vec.iter().for_each(|v| println!("{v}")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in vec.iter() { println!("{v}"); }` -error: aborting due to 11 previous errors +error: needless use of `for_each` + --> tests/ui/needless_for_each_fixable.rs:155:5 + | +LL | / vec.iter().for_each(|elem| { +LL | | +LL | | println!("{elem}"); +LL | | }) + | |______^ + | +help: try + | +LL ~ for elem in vec.iter() { +LL + +LL + println!("{elem}"); +LL + } + | + +error: aborting due to 12 previous errors From 6bc65090756d6d81d3414fdc50f856ea45a24046 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Wed, 24 Dec 2025 00:21:23 +0000 Subject: [PATCH 1207/3801] fix: `manual_is_multiple_of` wrongly unmangled macros --- .../src/operators/manual_is_multiple_of.rs | 4 ++-- tests/ui/manual_is_multiple_of.fixed | 16 ++++++++++++++++ tests/ui/manual_is_multiple_of.rs | 16 ++++++++++++++++ tests/ui/manual_is_multiple_of.stderr | 8 +++++++- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/operators/manual_is_multiple_of.rs b/clippy_lints/src/operators/manual_is_multiple_of.rs index 0b9bd4fb6d32..291d81097b51 100644 --- a/clippy_lints/src/operators/manual_is_multiple_of.rs +++ b/clippy_lints/src/operators/manual_is_multiple_of.rs @@ -35,7 +35,7 @@ pub(super) fn check<'tcx>( { let mut app = Applicability::MachineApplicable; let divisor = deref_sugg( - Sugg::hir_with_applicability(cx, operand_right, "_", &mut app), + Sugg::hir_with_context(cx, operand_right, expr.span.ctxt(), "_", &mut app), cx.typeck_results().expr_ty_adjusted(operand_right), ); span_lint_and_sugg( @@ -47,7 +47,7 @@ pub(super) fn check<'tcx>( format!( "{}{}.is_multiple_of({divisor})", if op == BinOpKind::Eq { "" } else { "!" }, - Sugg::hir_with_applicability(cx, operand_left, "_", &mut app).maybe_paren() + Sugg::hir_with_context(cx, operand_left, expr.span.ctxt(), "_", &mut app).maybe_paren() ), app, ); diff --git a/tests/ui/manual_is_multiple_of.fixed b/tests/ui/manual_is_multiple_of.fixed index 03f75e725ed5..82e0684e5e57 100644 --- a/tests/ui/manual_is_multiple_of.fixed +++ b/tests/ui/manual_is_multiple_of.fixed @@ -101,3 +101,19 @@ mod issue15103 { (1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum() } } + +fn wrongly_unmangled_macros(a: u32, b: u32) { + struct Wrapper(u32); + let a = Wrapper(a); + let b = Wrapper(b); + macro_rules! dot_0 { + ($x:expr) => { + $x.0 + }; + } + + if dot_0!(a).is_multiple_of(dot_0!(b)) { + //~^ manual_is_multiple_of + todo!() + } +} diff --git a/tests/ui/manual_is_multiple_of.rs b/tests/ui/manual_is_multiple_of.rs index 7b6fa64c843d..82a492e24092 100644 --- a/tests/ui/manual_is_multiple_of.rs +++ b/tests/ui/manual_is_multiple_of.rs @@ -101,3 +101,19 @@ mod issue15103 { (1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum() } } + +fn wrongly_unmangled_macros(a: u32, b: u32) { + struct Wrapper(u32); + let a = Wrapper(a); + let b = Wrapper(b); + macro_rules! dot_0 { + ($x:expr) => { + $x.0 + }; + } + + if dot_0!(a) % dot_0!(b) == 0 { + //~^ manual_is_multiple_of + todo!() + } +} diff --git a/tests/ui/manual_is_multiple_of.stderr b/tests/ui/manual_is_multiple_of.stderr index 8523599ec402..3aba869c9111 100644 --- a/tests/ui/manual_is_multiple_of.stderr +++ b/tests/ui/manual_is_multiple_of.stderr @@ -67,5 +67,11 @@ error: manual implementation of `.is_multiple_of()` LL | let d = |n: u32| -> u32 { (1..=n / 2).filter(|i| n % i == 0).sum() }; | ^^^^^^^^^^ help: replace with: `n.is_multiple_of(*i)` -error: aborting due to 11 previous errors +error: manual implementation of `.is_multiple_of()` + --> tests/ui/manual_is_multiple_of.rs:115:8 + | +LL | if dot_0!(a) % dot_0!(b) == 0 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `dot_0!(a).is_multiple_of(dot_0!(b))` + +error: aborting due to 12 previous errors From b7729998d25a158a6925f737f4c164ec0572ff10 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 20 Dec 2025 14:08:21 +1100 Subject: [PATCH 1208/3801] Classify `TestableCase::Constant` into multiple sub-kinds --- .../src/builder/matches/buckets.rs | 21 ++++++++------- .../src/builder/matches/match_pair.rs | 26 +++++++++++++++++-- .../src/builder/matches/mod.rs | 21 ++++++++++++++- .../src/builder/matches/test.rs | 15 +++++------ 4 files changed, 61 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs index 8cbbb8e14095..5275a1bb620e 100644 --- a/compiler/rustc_mir_build/src/builder/matches/buckets.rs +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -6,8 +6,7 @@ use rustc_middle::span_bug; use tracing::debug; use crate::builder::Builder; -use crate::builder::matches::test::is_switch_ty; -use crate::builder::matches::{Candidate, Test, TestBranch, TestKind, TestableCase}; +use crate::builder::matches::{Candidate, PatConstKind, Test, TestBranch, TestKind, TestableCase}; /// Output of [`Builder::partition_candidates_into_buckets`]. pub(crate) struct PartitionedCandidates<'tcx, 'b, 'c> { @@ -157,11 +156,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // FIXME(#29623) we could use PatKind::Range to rule // things out here, in some cases. - // - // FIXME(Zalathar): Is the `is_switch_ty` test unnecessary? - (TestKind::SwitchInt, &TestableCase::Constant { value }) - if is_switch_ty(match_pair.pattern_ty) => - { + ( + TestKind::SwitchInt, + &TestableCase::Constant { value, kind: PatConstKind::IntOrChar }, + ) => { // An important invariant of candidate bucketing is that a candidate // must not match in multiple branches. For `SwitchInt` tests, adding // a new value might invalidate that property for range patterns that @@ -206,7 +204,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) } - (TestKind::If, TestableCase::Constant { value }) => { + (TestKind::If, TestableCase::Constant { value, kind: PatConstKind::Bool }) => { fully_matched = true; let value = value.try_to_bool().unwrap_or_else(|| { span_bug!(test.span, "expected boolean value but got {value:?}") @@ -291,7 +289,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if !test.overlaps(pat, self.tcx)? { Some(TestBranch::Failure) } else { None } } } - (TestKind::Range(range), &TestableCase::Constant { value }) => { + (TestKind::Range(range), &TestableCase::Constant { value, kind: _ }) => { fully_matched = false; if !range.contains(value, self.tcx)? { // `value` is not contained in the testing range, @@ -302,7 +300,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - (TestKind::Eq { value: test_val, .. }, TestableCase::Constant { value: case_val }) => { + ( + TestKind::Eq { value: test_val, .. }, + TestableCase::Constant { value: case_val, kind: _ }, + ) => { if test_val == case_val { fully_matched = true; Some(TestBranch::Success) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 9b9ee1836956..c8e3628ae346 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -7,7 +7,9 @@ use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use crate::builder::Builder; use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder}; -use crate::builder::matches::{FlatPat, MatchPairTree, PatternExtraData, TestableCase}; +use crate::builder::matches::{ + FlatPat, MatchPairTree, PatConstKind, PatternExtraData, TestableCase, +}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in @@ -156,7 +158,27 @@ impl<'tcx> MatchPairTree<'tcx> { } } - PatKind::Constant { value } => Some(TestableCase::Constant { value }), + PatKind::Constant { value } => { + // CAUTION: The type of the pattern node (`pattern.ty`) is + // _often_ the same as the type of the const value (`value.ty`), + // but there are some cases where those types differ + // (e.g. when `deref!(..)` patterns interact with `String`). + + // Classify the constant-pattern into further kinds, to + // reduce the number of ad-hoc type tests needed later on. + let pat_ty = pattern.ty; + let const_kind = if pat_ty.is_bool() { + PatConstKind::Bool + } else if pat_ty.is_integral() || pat_ty.is_char() { + PatConstKind::IntOrChar + } else { + // FIXME(Zalathar): This still covers several different + // categories (e.g. raw pointer, string, pattern-type) + // which could be split out into their own kinds. + PatConstKind::Other + }; + Some(TestableCase::Constant { value, kind: const_kind }) + } PatKind::AscribeUserType { ascription: Ascription { ref annotation, variance }, diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 8897ca7c7210..04722bf690c4 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1262,7 +1262,7 @@ struct Ascription<'tcx> { #[derive(Debug, Clone)] enum TestableCase<'tcx> { Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx }, - Constant { value: ty::Value<'tcx> }, + Constant { value: ty::Value<'tcx>, kind: PatConstKind }, Range(Arc>), Slice { len: u64, variable_length: bool }, Deref { temp: Place<'tcx>, mutability: Mutability }, @@ -1276,6 +1276,25 @@ impl<'tcx> TestableCase<'tcx> { } } +/// Sub-classification of [`TestableCase::Constant`], which helps to avoid +/// some redundant ad-hoc checks when preparing and lowering tests. +#[derive(Debug, Clone)] +enum PatConstKind { + /// The primitive `bool` type, which is like an integer but simpler, + /// having only two values. + Bool, + /// Primitive unsigned/signed integer types, plus `char`. + /// These types interact nicely with `SwitchInt`. + IntOrChar, + /// Any other constant-pattern is usually tested via some kind of equality + /// check. Types that might be encountered here include: + /// - `&str` + /// - floating-point primitives, e.g. `f32`, `f64` + /// - raw pointers derived from integer values + /// - pattern types, e.g. `pattern_type!(u32 is 1..)` + Other, +} + /// Node in a tree of "match pairs", where each pair consists of a place to be /// tested, and a test to perform on that place. /// diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 402587bff7e8..bc4966404ced 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -19,7 +19,9 @@ use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use tracing::{debug, instrument}; use crate::builder::Builder; -use crate::builder::matches::{MatchPairTree, Test, TestBranch, TestKind, TestableCase}; +use crate::builder::matches::{ + MatchPairTree, PatConstKind, Test, TestBranch, TestKind, TestableCase, +}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Identifies what test is needed to decide if `match_pair` is applicable. @@ -32,11 +34,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let kind = match match_pair.testable_case { TestableCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def }, - TestableCase::Constant { .. } if match_pair.pattern_ty.is_bool() => TestKind::If, - TestableCase::Constant { .. } if is_switch_ty(match_pair.pattern_ty) => { + TestableCase::Constant { value: _, kind: PatConstKind::Bool } => TestKind::If, + TestableCase::Constant { value: _, kind: PatConstKind::IntOrChar } => { TestKind::SwitchInt } - TestableCase::Constant { value } => { + TestableCase::Constant { value, kind: PatConstKind::Other } => { TestKind::Eq { value, cast_ty: match_pair.pattern_ty } } @@ -491,11 +493,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } -/// Returns true if this type be used with [`TestKind::SwitchInt`]. -pub(crate) fn is_switch_ty(ty: Ty<'_>) -> bool { - ty.is_integral() || ty.is_char() -} - fn trait_method<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, From 1296925d1b71fa9dbf636aa540bd7cced80c3054 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 24 Dec 2025 13:38:07 +1100 Subject: [PATCH 1209/3801] Split out a separate `PatConstKind::Float` Unlike the other types covered by `PatConstKind::Other`, const-float patterns can also interact with range patterns. --- .../rustc_mir_build/src/builder/matches/buckets.rs | 13 +++++++++++-- .../src/builder/matches/match_pair.rs | 2 ++ compiler/rustc_mir_build/src/builder/matches/mod.rs | 5 ++++- .../rustc_mir_build/src/builder/matches/test.rs | 3 +++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs index 5275a1bb620e..f8af50ee52fe 100644 --- a/compiler/rustc_mir_build/src/builder/matches/buckets.rs +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -289,7 +289,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if !test.overlaps(pat, self.tcx)? { Some(TestBranch::Failure) } else { None } } } - (TestKind::Range(range), &TestableCase::Constant { value, kind: _ }) => { + ( + TestKind::Range(range), + &TestableCase::Constant { + value, + kind: PatConstKind::Bool | PatConstKind::IntOrChar | PatConstKind::Float, + }, + ) => { fully_matched = false; if !range.contains(value, self.tcx)? { // `value` is not contained in the testing range, @@ -302,7 +308,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ( TestKind::Eq { value: test_val, .. }, - TestableCase::Constant { value: case_val, kind: _ }, + TestableCase::Constant { + value: case_val, + kind: PatConstKind::Float | PatConstKind::Other, + }, ) => { if test_val == case_val { fully_matched = true; diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index c8e3628ae346..798110c8b090 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -171,6 +171,8 @@ impl<'tcx> MatchPairTree<'tcx> { PatConstKind::Bool } else if pat_ty.is_integral() || pat_ty.is_char() { PatConstKind::IntOrChar + } else if pat_ty.is_floating_point() { + PatConstKind::Float } else { // FIXME(Zalathar): This still covers several different // categories (e.g. raw pointer, string, pattern-type) diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 04722bf690c4..8128ea946f08 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1286,10 +1286,13 @@ enum PatConstKind { /// Primitive unsigned/signed integer types, plus `char`. /// These types interact nicely with `SwitchInt`. IntOrChar, + /// Floating-point primitives, e.g. `f32`, `f64`. + /// These types don't support `SwitchInt` and require an equality test, + /// but can also interact with range pattern tests. + Float, /// Any other constant-pattern is usually tested via some kind of equality /// check. Types that might be encountered here include: /// - `&str` - /// - floating-point primitives, e.g. `f32`, `f64` /// - raw pointers derived from integer values /// - pattern types, e.g. `pattern_type!(u32 is 1..)` Other, diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index bc4966404ced..f292a8e79d9d 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -38,6 +38,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TestableCase::Constant { value: _, kind: PatConstKind::IntOrChar } => { TestKind::SwitchInt } + TestableCase::Constant { value, kind: PatConstKind::Float } => { + TestKind::Eq { value, cast_ty: match_pair.pattern_ty } + } TestableCase::Constant { value, kind: PatConstKind::Other } => { TestKind::Eq { value, cast_ty: match_pair.pattern_ty } } From b1dbc2403e2e8aeaf558d5ca2afcd5da2bc9ef84 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Wed, 24 Dec 2025 04:59:20 +0000 Subject: [PATCH 1210/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 8796b3b8b4ac6f38a80bf80ce89dd7bd7f92edd7. --- 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 596e757d3fcc..329ee6a1bad5 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -a0c97e3255e2b9140f131baec1c93eef57640d21 +8796b3b8b4ac6f38a80bf80ce89dd7bd7f92edd7 From 5fbb39c036c8620d2d8efa54b6e1bfc5bd664008 Mon Sep 17 00:00:00 2001 From: Redddy Date: Tue, 23 Dec 2025 15:22:59 +0900 Subject: [PATCH 1211/3801] Fix function formatting in src/overview.md --- src/doc/rustc-dev-guide/src/overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md index 23cc94d41846..1200a854f8ed 100644 --- a/src/doc/rustc-dev-guide/src/overview.md +++ b/src/doc/rustc-dev-guide/src/overview.md @@ -50,10 +50,10 @@ preserves full fidelity information for both IDEs and procedural macros The *parser* [translates the token stream from the `lexer` into an Abstract Syntax Tree (AST)][parser]. It uses a recursive descent (top-down) approach to syntax analysis. The crate entry points for the `parser` are the -[`Parser::parse_crate_mod()`][parse_crate_mod] and [`Parser::parse_mod()`][parse_mod] +[`Parser::parse_crate_mod`][parse_crate_mod] and [`Parser::parse_mod`][parse_mod] methods found in [`rustc_parse::parser::Parser`]. The external module parsing entry point is [`rustc_expand::module::parse_external_mod`][parse_external_mod]. -And the macro-`parser` entry point is [`Parser::parse_nonterminal()`][parse_nonterminal]. +And the macro-`parser` entry point is [`Parser::parse_nonterminal`][parse_nonterminal]. Parsing is performed with a set of [`parser`] utility methods including [`bump`], [`check`], [`eat`], [`expect`], [`look_ahead`]. From b5c473e4141c6b1bc7a1babec3e01f894442f436 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 23 Dec 2025 15:50:33 +0000 Subject: [PATCH 1212/3801] Avoid using env::temp when linking a binary This keeps all build artefacts (even temporary ones) within the build directory. --- compiler/rustc_codegen_ssa/src/back/link.rs | 11 ++++++----- compiler/rustc_fs_util/src/lib.rs | 6 +----- tests/run-make/invalid-tmpdir-env-var/rmake.rs | 8 ++++---- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 70db6794742d..ba07345dd43f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -103,17 +103,18 @@ pub fn link_binary( }); if outputs.outputs.should_link() { - let tmpdir = TempDirBuilder::new() - .prefix("rustc") - .tempdir() - .unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error })); - let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps); let output = out_filename( sess, crate_type, outputs, codegen_results.crate_info.local_crate_name, ); + let tmpdir = TempDirBuilder::new() + .prefix("rustc") + .tempdir_in(output.parent().unwrap_or_else(|| Path::new("."))) + .unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error })); + let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps); + let crate_name = format!("{}", codegen_results.crate_info.local_crate_name); let out_filename = output.file_for_writing( outputs, diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs index 7a883a13b72d..e21da4cdddf7 100644 --- a/compiler/rustc_fs_util/src/lib.rs +++ b/compiler/rustc_fs_util/src/lib.rs @@ -1,6 +1,6 @@ use std::ffi::{CString, OsStr}; use std::path::{Path, PathBuf, absolute}; -use std::{env, fs, io}; +use std::{fs, io}; use tempfile::TempDir; @@ -139,8 +139,4 @@ impl<'a, 'b> TempDirBuilder<'a, 'b> { } self.builder.tempdir_in(dir) } - - pub fn tempdir(&self) -> io::Result { - self.tempdir_in(env::temp_dir()) - } } diff --git a/tests/run-make/invalid-tmpdir-env-var/rmake.rs b/tests/run-make/invalid-tmpdir-env-var/rmake.rs index c5b9dca33a94..a62592757879 100644 --- a/tests/run-make/invalid-tmpdir-env-var/rmake.rs +++ b/tests/run-make/invalid-tmpdir-env-var/rmake.rs @@ -1,9 +1,7 @@ //@ needs-target-std // // When the TMP (on Windows) or TMPDIR (on Unix) variable is set to an invalid -// or non-existing directory, this used to cause an internal compiler error (ICE). After the -// addition of proper error handling in #28430, this test checks that the expected message is -// printed. +// or non-existing directory, this used to cause an internal compiler error (ICE). // See https://github.com/rust-lang/rust/issues/14698 use run_make_support::{is_windows, rustc}; @@ -18,5 +16,7 @@ fn main() { } else { rustc.env("TMPDIR", "fake"); } - rustc.input("foo.rs").run_fail().assert_stderr_contains("couldn't create a temp dir"); + let result = rustc.input("foo.rs").run_unchecked(); + // Ensure that rustc doesn't ICE by checking the exit code isn't 101. + assert_ne!(result.status().code(), Some(101)); } From 6e354544bfe4bc6ce17265bfb8013631d505f1ac Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 23 Dec 2025 17:46:09 +0000 Subject: [PATCH 1213/3801] Rename invalid-tmpdir-env-var to invalid-tmpdir-no-ice --- .../{invalid-tmpdir-env-var => invalid-tmpdir-no-ice}/foo.rs | 0 .../{invalid-tmpdir-env-var => invalid-tmpdir-no-ice}/rmake.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/run-make/{invalid-tmpdir-env-var => invalid-tmpdir-no-ice}/foo.rs (100%) rename tests/run-make/{invalid-tmpdir-env-var => invalid-tmpdir-no-ice}/rmake.rs (100%) diff --git a/tests/run-make/invalid-tmpdir-env-var/foo.rs b/tests/run-make/invalid-tmpdir-no-ice/foo.rs similarity index 100% rename from tests/run-make/invalid-tmpdir-env-var/foo.rs rename to tests/run-make/invalid-tmpdir-no-ice/foo.rs diff --git a/tests/run-make/invalid-tmpdir-env-var/rmake.rs b/tests/run-make/invalid-tmpdir-no-ice/rmake.rs similarity index 100% rename from tests/run-make/invalid-tmpdir-env-var/rmake.rs rename to tests/run-make/invalid-tmpdir-no-ice/rmake.rs From 855281c8871e43980fc41b54d1d5949a9863103d Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Wed, 24 Dec 2025 16:04:58 +0800 Subject: [PATCH 1214/3801] Disable f16 on LoongArch for LLVM < 21 The `f16` type works on the LoongArch target starting from LLVM 21. However, the current minimum supported external LLVM version is 20, so `f16` must not be enabled on LoongArch for LLVM version < 21. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index a5a8f8e6a25e..01181ce26184 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -383,6 +383,7 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // Infinite recursion (Arch::CSky, _) => false, (Arch::Hexagon, _) if major < 21 => false, // (fixed in llvm21) + (Arch::LoongArch32 | Arch::LoongArch64, _) if major < 21 => false, // (fixed in llvm21) (Arch::PowerPC | Arch::PowerPC64, _) => false, (Arch::Sparc | Arch::Sparc64, _) => false, (Arch::Wasm32 | Arch::Wasm64, _) => false, From 13c6256efe7d426abeb7c86a20b14ba38dc7ad4e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:21:07 +0000 Subject: [PATCH 1215/3801] Include rustc version in ICE messages Rather than only including them in the ICE file. Not every user includes the ICE file in their bug reports, nor do they always list the rustc version. --- compiler/rustc_driver_impl/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 63fc9c96f450..7820198f2dcf 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1531,15 +1531,15 @@ fn report_ice( .map(PathBuf::from) .map(|env_var| session_diagnostics::IcePathErrorEnv { env_var }), }); - dcx.emit_note(session_diagnostics::IceVersion { version, triple: tuple }); None } } } else { - dcx.emit_note(session_diagnostics::IceVersion { version, triple: tuple }); None }; + dcx.emit_note(session_diagnostics::IceVersion { version, triple: tuple }); + if let Some((flags, excluded_cargo_defaults)) = rustc_session::utils::extra_compiler_flags() { dcx.emit_note(session_diagnostics::IceFlags { flags: flags.join(" ") }); if excluded_cargo_defaults { From 9b2d03bd60b38c48ddc412963d6c1ea309d196ce Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Wed, 24 Dec 2025 11:37:54 +0000 Subject: [PATCH 1216/3801] =?UTF-8?q?.checked=5Fsub(1).unwrap=5For(0)=20?= =?UTF-8?q?=E2=86=92=20.saturating=5Fsub(1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/alloc/src/collections/linked_list.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index e738c29c237f..c98aeb80628e 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -597,7 +597,7 @@ impl LinkedList { #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn cursor_back(&self) -> Cursor<'_, T, A> { - Cursor { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } + Cursor { index: self.len.saturating_sub(1), current: self.tail, list: self } } /// Provides a cursor with editing operations at the back element. @@ -607,7 +607,7 @@ impl LinkedList { #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T, A> { - CursorMut { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } + CursorMut { index: self.len.saturating_sub(1), current: self.tail, list: self } } /// Returns `true` if the `LinkedList` is empty. @@ -1432,7 +1432,7 @@ impl<'a, T, A: Allocator> Cursor<'a, T, A> { // No current. We're at the start of the list. Yield None and jump to the end. None => { self.current = self.list.tail; - self.index = self.list.len().checked_sub(1).unwrap_or(0); + self.index = self.list.len().saturating_sub(1); } // Have a prev. Yield it and go to the previous element. Some(current) => unsafe { @@ -1559,7 +1559,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { // No current. We're at the start of the list. Yield None and jump to the end. None => { self.current = self.list.tail; - self.index = self.list.len().checked_sub(1).unwrap_or(0); + self.index = self.list.len().saturating_sub(1); } // Have a prev. Yield it and go to the previous element. Some(current) => unsafe { From 611becee8ca44af529774b34fd6c7dac537ed553 Mon Sep 17 00:00:00 2001 From: Redddy Date: Wed, 24 Dec 2025 21:58:59 +0900 Subject: [PATCH 1217/3801] Update 'Working groups' to 'Working areas' in docs --- src/doc/rustc-dev-guide/src/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 36d19e6c570e..6ccc5a75497a 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -179,7 +179,7 @@ The following tasks are doable without much background knowledge but are incredi to read a part of the code and write doc comments for it. This will help you to learn some part of the compiler while also producing a useful artifact! - [Triaging issues][triage]: categorizing, replicating, and minimizing issues is very helpful to the Rust maintainers. -- [Working groups][wg]: there are a bunch of working groups on a wide variety +- [Working areas][wa]: there are a bunch of working areas on a wide variety of rust-related things. - Answer questions on [users.rust-lang.org][users], or on [Stack Overflow][so]. - Participate in the [RFC process](https://github.com/rust-lang/rfcs). @@ -191,7 +191,7 @@ The following tasks are doable without much background knowledge but are incredi [so]: http://stackoverflow.com/questions/tagged/rust [community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library [wd]: ./contributing.md#writing-documentation -[wg]: https://rust-lang.github.io/compiler-team/working-groups/ +[wa]: https://forge.rust-lang.org/compiler/working-areas.html [triage]: ./contributing.md#issue-triage ## Cloning and Building From 5c99ebf42c004696e8dbae8c24dd481d00f180f0 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 24 Dec 2025 21:46:57 +0800 Subject: [PATCH 1218/3801] Fix indent for convert_to_guarded_return --- .../src/handlers/convert_to_guarded_return.rs | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index 05ccd5b9bff6..08b114072fd9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -218,7 +218,7 @@ fn let_stmt_to_guarded_return( let let_else_stmt = make::let_else_stmt( happy_pattern, let_stmt.ty(), - expr, + expr.reset_indent(), ast::make::tail_only_block_expr(early_expression), ); let let_else_stmt = let_else_stmt.indent(let_indent_level); @@ -275,11 +275,11 @@ fn flat_let_chain(mut expr: ast::Expr) -> Vec { && bin_expr.op_kind() == Some(ast::BinaryOp::LogicOp(ast::LogicOp::And)) && let (Some(lhs), Some(rhs)) = (bin_expr.lhs(), bin_expr.rhs()) { - reduce_cond(rhs); + reduce_cond(rhs.reset_indent()); expr = lhs; } - reduce_cond(expr); + reduce_cond(expr.reset_indent()); chains.reverse(); chains } @@ -1019,6 +1019,63 @@ fn main() { ); } + #[test] + fn indentations() { + check_assist( + convert_to_guarded_return, + r#" +mod indent { + fn main() { + $0if let None = Some( + 92 + ) { + foo( + 93 + ); + } + } +} +"#, + r#" +mod indent { + fn main() { + let None = Some( + 92 + ) else { return }; + foo( + 93 + ); + } +} +"#, + ); + + check_assist( + convert_to_guarded_return, + r#" +//- minicore: option +mod indent { + fn foo(_: i32) -> Option { None } + fn main() { + $0let x = foo( + 2 + ); + } +} +"#, + r#" +mod indent { + fn foo(_: i32) -> Option { None } + fn main() { + let Some(x) = foo( + 2 + ) else { return }; + } +} +"#, + ); + } + #[test] fn ignore_already_converted_if() { check_assist_not_applicable( From 0e0911b5d8261e1a74158b0a611875521704b0cc Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 18 Dec 2025 18:50:27 +0000 Subject: [PATCH 1219/3801] Misc cleanups --- compiler/rustc_borrowck/src/lib.rs | 8 +- compiler/rustc_borrowck/src/root_cx.rs | 2 +- .../rustc_borrowck/src/universal_regions.rs | 47 ++--- .../rustc_hir_analysis/src/collect/type_of.rs | 160 +++++++++--------- 4 files changed, 99 insertions(+), 118 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8d61ffde116c..fa78fb623596 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1,4 +1,4 @@ -//! This query borrow-checks the MIR to (further) ensure it is not broken. +//! This crate implemens MIR typeck and MIR borrowck. // tidy-alphabetical-start #![allow(internal_features)] @@ -111,9 +111,9 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { mir_borrowck, ..*providers }; } -/// Provider for `query mir_borrowck`. Similar to `typeck`, this must -/// only be called for typeck roots which will then borrowck all -/// nested bodies as well. +/// Provider for `query mir_borrowck`. Unlike `typeck`, this must +/// only be called for typeck roots which *similar* to `typeck` will +/// then borrowck all nested bodies as well. fn mir_borrowck( tcx: TyCtxt<'_>, def: LocalDefId, diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs index c3ff8cba9472..4d42055df168 100644 --- a/compiler/rustc_borrowck/src/root_cx.rs +++ b/compiler/rustc_borrowck/src/root_cx.rs @@ -255,7 +255,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { } // We now apply the closure requirements of nested bodies modulo - // regions. In case a body does not depend on opaque types, we + // opaques. In case a body does not depend on opaque types, we // eagerly check its region constraints and use the final closure // requirements. // diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index aee1eb94dc81..a0d5e1ce780d 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -1,13 +1,12 @@ //! Code to extract the universally quantified regions declared on a -//! function and the relationships between them. For example: +//! function. For example: //! //! ``` //! fn foo<'a, 'b, 'c: 'b>() { } //! ``` //! //! here we would return a map assigning each of `{'a, 'b, 'c}` -//! to an index, as well as the `FreeRegionMap` which can compute -//! relationships between them. +//! to an index. //! //! The code in this file doesn't *do anything* with those results; it //! just returns them for other code to use. @@ -271,8 +270,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// Creates a new and fully initialized `UniversalRegions` that /// contains indices for all the free regions found in the given /// MIR -- that is, all the regions that appear in the function's - /// signature. This will also compute the relationships that are - /// known between those regions. + /// signature. pub(crate) fn new(infcx: &BorrowckInferCtxt<'tcx>, mir_def: LocalDefId) -> Self { UniversalRegionsBuilder { infcx, mir_def }.build() } @@ -648,17 +646,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => { let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); - if self.mir_def.to_def_id() == typeck_root_def_id - // Do not ICE when checking default_field_values consts with lifetimes (#135649) - && DefKind::Field != tcx.def_kind(tcx.parent(typeck_root_def_id)) - { + if self.mir_def.to_def_id() == typeck_root_def_id { let args = self.infcx.replace_free_regions_with_nll_infer_vars( NllRegionVariableOrigin::FreeRegion, identity_args, ); DefiningTy::Const(self.mir_def.to_def_id(), args) } else { - // FIXME this line creates a dependency between borrowck and typeck. + // FIXME: this line creates a query dependency between borrowck and typeck. // // This is required for `AscribeUserType` canonical query, which will call // `type_of(inline_const_def_id)`. That `type_of` would inject erased lifetimes @@ -699,30 +694,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let tcx = self.infcx.tcx; let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); - let fr_args = match defining_ty { - DefiningTy::Closure(_, args) - | DefiningTy::CoroutineClosure(_, args) - | DefiningTy::Coroutine(_, args) - | DefiningTy::InlineConst(_, args) => { - // In the case of closures, we rely on the fact that - // the first N elements in the ClosureArgs are - // inherited from the `typeck_root_def_id`. - // Therefore, when we zip together (below) with - // `identity_args`, we will get only those regions - // that correspond to early-bound regions declared on - // the `typeck_root_def_id`. - assert!(args.len() >= identity_args.len()); - assert_eq!(args.regions().count(), identity_args.regions().count()); - args - } - - DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args, - - DefiningTy::GlobalAsm(_) => ty::List::empty(), - }; + let renumbered_args = defining_ty.args(); let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); - let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var())); + // This relies on typeck roots being generics_of parents with their + // parameters at the start of nested bodies' generics. + assert!(renumbered_args.len() >= identity_args.len()); + let arg_mapping = + iter::zip(identity_args.regions(), renumbered_args.regions().map(|r| r.as_var())); UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), @@ -862,8 +841,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { }; // FIXME(#129952): We probably want a more principled approach here. - if let Err(terr) = inputs_and_output.skip_binder().error_reported() { - self.infcx.set_tainted_by_errors(terr); + if let Err(e) = inputs_and_output.error_reported() { + self.infcx.set_tainted_by_errors(e); } inputs_and_output diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 180589340b4c..aa0e5c7fd710 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -10,6 +10,7 @@ use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, DefiningScopeKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span}; +use tracing::instrument; use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder}; use crate::check::wfcheck::check_static_item; @@ -17,85 +18,7 @@ use crate::hir_ty_lowering::HirTyLowerer; mod opaque; -fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { - use hir::*; - use rustc_middle::ty::Ty; - let tcx = icx.tcx; - let hir_id = tcx.local_def_id_to_hir_id(def_id); - - let node = tcx.hir_node(hir_id); - let Node::AnonConst(&AnonConst { span, .. }) = node else { - span_bug!( - tcx.def_span(def_id), - "expected anon const in `anon_const_type_of`, got {node:?}" - ); - }; - - let parent_node_id = tcx.parent_hir_id(hir_id); - let parent_node = tcx.hir_node(parent_node_id); - - match parent_node { - // Anon consts "inside" the type system. - Node::ConstArg(&ConstArg { - hir_id: arg_hir_id, - kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }), - .. - }) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span), - - Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => { - tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) - } - - Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. }) - if c.hir_id == hir_id => - { - tcx.type_of(field_def_id).instantiate_identity() - } - - _ => Ty::new_error_with_message( - tcx, - span, - format!("unexpected anon const parent in type_of(): {parent_node:?}"), - ), - } -} - -fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> { - use hir::*; - use rustc_middle::ty::Ty; - - let tcx = icx.tcx; - - match tcx.parent_hir_node(arg_hir_id) { - // Array length const arguments do not have `type_of` fed as there is never a corresponding - // generic parameter definition. - Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. }) - | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) - if constant.hir_id == arg_hir_id => - { - tcx.types.usize - } - - Node::TyPat(pat) => { - let node = match tcx.parent_hir_node(pat.hir_id) { - // Or patterns can be nested one level deep - Node::TyPat(p) => tcx.parent_hir_node(p.hir_id), - other => other, - }; - let hir::TyKind::Pat(ty, _) = node.expect_ty().kind else { bug!() }; - icx.lower_ty(ty) - } - - // This is not a `bug!` as const arguments in path segments that did not resolve to anything - // will result in `type_of` never being fed. - _ => Ty::new_error_with_message( - tcx, - span, - "`type_of` called on const argument's anon const before the const argument was lowered", - ), - } -} - +#[instrument(level = "debug", skip(tcx), ret)] pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, Ty<'_>> { use rustc_hir::*; use rustc_middle::ty::Ty; @@ -408,6 +331,85 @@ pub(super) fn type_of_opaque_hir_typeck( } } +fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { + use hir::*; + use rustc_middle::ty::Ty; + let tcx = icx.tcx; + let hir_id = tcx.local_def_id_to_hir_id(def_id); + + let node = tcx.hir_node(hir_id); + let Node::AnonConst(&AnonConst { span, .. }) = node else { + span_bug!( + tcx.def_span(def_id), + "expected anon const in `anon_const_type_of`, got {node:?}" + ); + }; + + let parent_node_id = tcx.parent_hir_id(hir_id); + let parent_node = tcx.hir_node(parent_node_id); + + match parent_node { + // Anon consts "inside" the type system. + Node::ConstArg(&ConstArg { + hir_id: arg_hir_id, + kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }), + .. + }) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span), + + Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => { + tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) + } + + Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. }) + if c.hir_id == hir_id => + { + tcx.type_of(field_def_id).instantiate_identity() + } + + _ => Ty::new_error_with_message( + tcx, + span, + format!("unexpected anon const parent in type_of(): {parent_node:?}"), + ), + } +} + +fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> { + use hir::*; + use rustc_middle::ty::Ty; + + let tcx = icx.tcx; + + match tcx.parent_hir_node(arg_hir_id) { + // Array length const arguments do not have `type_of` fed as there is never a corresponding + // generic parameter definition. + Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. }) + | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) + if constant.hir_id == arg_hir_id => + { + tcx.types.usize + } + + Node::TyPat(pat) => { + let node = match tcx.parent_hir_node(pat.hir_id) { + // Or patterns can be nested one level deep + Node::TyPat(p) => tcx.parent_hir_node(p.hir_id), + other => other, + }; + let hir::TyKind::Pat(ty, _) = node.expect_ty().kind else { bug!() }; + icx.lower_ty(ty) + } + + // This is not a `bug!` as const arguments in path segments that did not resolve to anything + // will result in `type_of` never being fed. + _ => Ty::new_error_with_message( + tcx, + span, + "`type_of` called on const argument's anon const before the const argument was lowered", + ), + } +} + fn infer_placeholder_type<'tcx>( cx: &dyn HirTyLowerer<'tcx>, def_id: LocalDefId, From a8c9cb5f77f2d66f85758703610b55a2ae8865e0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:25:30 +0000 Subject: [PATCH 1220/3801] Fix some divergences with the cg_clif subtree For some reason git-subtree incorrectly synced those changes. --- .../rustc_codegen_cranelift/src/intrinsics/simd.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 15aef60c5af3..bef9c6747457 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -1005,14 +1005,6 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ret_lane_layout = fx.layout_of(ret_lane_ty); - let alignment = - generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); - - let memflags = match alignment { - SimdAlign::Unaligned => MemFlags::new().with_notrap(), - _ => MemFlags::trusted(), - }; - for lane_idx in 0..ptr_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let ptr_lane = ptr.value_lane(fx, lane_idx).load_scalar(fx); @@ -1028,7 +1020,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.seal_block(if_disabled); fx.bcx.switch_to_block(if_enabled); - let res = fx.bcx.ins().load(lane_clif_ty, memflags, ptr_lane, 0); + let res = fx.bcx.ins().load(lane_clif_ty, MemFlags::trusted(), ptr_lane, 0); fx.bcx.ins().jump(next, &[res.into()]); fx.bcx.switch_to_block(if_disabled); From 851a98e17efa2c3524b761beda8110925f7f3819 Mon Sep 17 00:00:00 2001 From: irelaxcn Date: Thu, 25 Dec 2025 00:44:17 +0800 Subject: [PATCH 1221/3801] Fix `assertions_on_constants` false positive when there is non-constant value in the condition expr --- clippy_lints/src/assertions_on_constants.rs | 2 ++ tests/ui/assertions_on_constants.rs | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs index 2586c89bc868..4aa55e53445c 100644 --- a/clippy_lints/src/assertions_on_constants.rs +++ b/clippy_lints/src/assertions_on_constants.rs @@ -3,6 +3,7 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::macros::{find_assert_args, root_macro_call_first_node}; use clippy_utils::msrvs::Msrv; +use clippy_utils::visitors::is_const_evaluatable; use clippy_utils::{is_inside_always_const_context, msrvs}; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; @@ -50,6 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants { _ => return, } && let Some((condition, _)) = find_assert_args(cx, e, macro_call.expn) + && is_const_evaluatable(cx, condition) && let Some((Constant::Bool(assert_val), const_src)) = ConstEvalCtxt::new(cx).eval_with_source(condition, macro_call.span.ctxt()) && let in_const_context = is_inside_always_const_context(cx.tcx, e.hir_id) diff --git a/tests/ui/assertions_on_constants.rs b/tests/ui/assertions_on_constants.rs index f467d4966aef..1c49b6e6b7b1 100644 --- a/tests/ui/assertions_on_constants.rs +++ b/tests/ui/assertions_on_constants.rs @@ -96,3 +96,8 @@ fn _f4() { assert!(C); //~^ assertions_on_constants } + +fn issue_16242(var: bool) { + // should not lint + assert!(cfg!(feature = "hey") && var); +} From 69f987dbe8a03c8dfef081aa490a15b9e4c0c695 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 24 Dec 2025 19:53:06 -0700 Subject: [PATCH 1222/3801] Bump stringdex, fix compiler-docs Fixes https://github.com/rust-lang/rust/issues/150346 --- Cargo.lock | 4 ++-- src/librustdoc/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c5053f0c2b7..870259429742 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5357,9 +5357,9 @@ dependencies = [ [[package]] name = "stringdex" -version = "0.0.4" +version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6204af9e1e433f1ef9b6d44475c7089be33c91111d896463b9dfa20464b87f1" +checksum = "07ab85c3f308f022ce6861ab57576b5b6ebc4835f9577e67e0f35f6c351e3f0a" dependencies = [ "stacker", ] diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index ab75d2dfa429..34b22acdbf72 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -22,7 +22,7 @@ rustdoc-json-types = { path = "../rustdoc-json-types" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" smallvec = "1.8.1" -stringdex = "=0.0.4" +stringdex = "=0.0.5" tempfile = "3" threadpool = "1.8.1" tracing = "0.1" From 83749a4dd447d04cc52ed0524d89a0d5a1408b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heath=20Dutton=F0=9F=95=B4=EF=B8=8F?= Date: Wed, 24 Dec 2025 22:52:34 -0500 Subject: [PATCH 1223/3801] rustdoc: fix incorrect type filter name in help popup --- src/librustdoc/html/static/js/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 476ecd42d6f9..a2bcdeb5d4b0 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1669,7 +1669,7 @@ function preLoadCss(cssUrl) { restrict the search to a given item kind.", "Accepted kinds are: fn, mod, struct, \ enum, trait, type, macro, \ - and const.", + and constant.", "Search functions by type signature (e.g., vec -> usize or \ -> vec or String, enum:Cow -> bool)", "You can look for items with an exact name by putting double quotes around \ From faac1b517f59e92b51b176fb0bbec26b82a2a0d6 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 25 Dec 2025 04:19:22 +0000 Subject: [PATCH 1224/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to e7d44143a12a526488e4f0c0d7ea8e62a4fe9354. --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 95e1cd0db37c..5ffe95a0b54f 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -f41f40408d719aa9ae0c6bfa17619d8f3f9e5b99 +e7d44143a12a526488e4f0c0d7ea8e62a4fe9354 From 68adc1910bb5ce00cbeab933042e9f89a37549fc Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Tue, 28 Oct 2025 13:21:37 +0800 Subject: [PATCH 1225/3801] xous: fix unwinding and unused symbol errors The unwinding feature is called `panic-unwind` and not `panic_unwind`. Adjust the feature gate to look for these values. Additionally, the `abort_internal()` call is no longer used. Signed-off-by: Sean Cross --- library/std/src/sys/pal/xous/mod.rs | 6 ------ library/std/src/sys/pal/xous/os.rs | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs index 077cff1ee0f2..19575220b22e 100644 --- a/library/std/src/sys/pal/xous/mod.rs +++ b/library/std/src/sys/pal/xous/mod.rs @@ -1,14 +1,8 @@ #![forbid(unsafe_op_in_unsafe_fn)] -use crate::os::xous::ffi::exit; - pub mod os; pub mod time; #[path = "../unsupported/common.rs"] mod common; pub use common::*; - -pub fn abort_internal() -> ! { - exit(101); -} diff --git a/library/std/src/sys/pal/xous/os.rs b/library/std/src/sys/pal/xous/os.rs index d9b8418e6c33..2da711f89dfa 100644 --- a/library/std/src/sys/pal/xous/os.rs +++ b/library/std/src/sys/pal/xous/os.rs @@ -11,7 +11,7 @@ pub(crate) mod params; static PARAMS_ADDRESS: Atomic<*mut u8> = AtomicPtr::new(core::ptr::null_mut()); #[cfg(not(test))] -#[cfg(feature = "panic_unwind")] +#[cfg(feature = "panic-unwind")] mod eh_unwinding { pub(crate) struct EhFrameFinder; pub(crate) static mut EH_FRAME_ADDRESS: usize = 0; @@ -45,7 +45,7 @@ mod c_compat { #[unsafe(no_mangle)] pub extern "C" fn _start(eh_frame: usize, params_address: usize) { - #[cfg(feature = "panic_unwind")] + #[cfg(feature = "panic-unwind")] { unsafe { super::eh_unwinding::EH_FRAME_ADDRESS = eh_frame }; unwind::set_custom_eh_frame_finder(&super::eh_unwinding::EH_FRAME_SETTINGS).ok(); From 41fe03affae87f3c372b6f8ccd250df8396f24f6 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Mon, 1 Dec 2025 21:59:50 +0800 Subject: [PATCH 1226/3801] xous: fix calling of rust_main_thread_not_inlined This function was incorrectly called run_main_thread_not_inlined when invoked. Signed-off-by: Sean Cross --- library/std/src/sys/thread/xous.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/thread/xous.rs b/library/std/src/sys/thread/xous.rs index 6c2cdfa4acdd..208d43bb2c06 100644 --- a/library/std/src/sys/thread/xous.rs +++ b/library/std/src/sys/thread/xous.rs @@ -87,7 +87,7 @@ impl Thread { // dealloc calls from being reordered to after the TLS has been destroyed. // See https://github.com/rust-lang/rust/pull/144465#pullrequestreview-3289729950 // for more context. - run_main_thread_not_inlined(init); + rust_main_thread_not_inlined(init); // Destroy TLS, which will free the TLS page and call the destructor for // any thread local storage (if any). From b22b089751099bc9b23ccc35c746c6896dc35a2d Mon Sep 17 00:00:00 2001 From: cuiweixie Date: Thu, 25 Dec 2025 17:09:48 +0800 Subject: [PATCH 1227/3801] refactor: simplify code --- compiler/rustc_parse/src/lexer/tokentrees.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 634f4c30b260..f3415aa47d33 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -117,7 +117,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { candidate = Some(*delimiter_span); } } - let (_, _) = self.diag_info.open_delimiters.pop().unwrap(); + self.diag_info.open_delimiters.pop().unwrap(); self.diag_info.unmatched_delims.push(UnmatchedDelim { found_delim: Some(close_delim), found_span: self.token.span, From 38ff5a7a5e45457d99f0dde0ffeeecfcdf703f1e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 25 Dec 2025 10:38:05 +0100 Subject: [PATCH 1228/3801] Introduce cargo-machete ci step --- src/tools/rust-analyzer/.github/workflows/ci.yaml | 6 ++++++ src/tools/rust-analyzer/Cargo.lock | 4 ---- src/tools/rust-analyzer/crates/hir-def/Cargo.toml | 1 - src/tools/rust-analyzer/crates/intern/Cargo.toml | 1 - .../rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml | 1 - src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml | 1 - src/tools/rust-analyzer/crates/test-fixture/Cargo.toml | 1 - 7 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index 5975272d871a..1a0deee564ae 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -122,6 +122,12 @@ jobs: - name: Run tests run: cargo nextest run --no-fail-fast --hide-progress-bar --status-level fail + - name: Install cargo-machete + uses: taiki-e/install-action@cargo-machete + + - name: Run cargo-machete + run: cargo machete + - name: Run Clippy if: matrix.os == 'macos-latest' run: cargo clippy --all-targets -- -D clippy::disallowed_macros -D clippy::dbg_macro -D clippy::todo -D clippy::print_stdout -D clippy::print_stderr diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 1e924d92f424..a2eb8b1397b8 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -821,7 +821,6 @@ dependencies = [ "intern", "itertools 0.14.0", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mbe", "query-group-macro", "ra-ap-rustc_abi", "ra-ap-rustc_parse_format", @@ -1219,7 +1218,6 @@ dependencies = [ "hashbrown 0.14.5", "rayon", "rustc-hash 2.1.1", - "smallvec", "triomphe", ] @@ -1882,7 +1880,6 @@ dependencies = [ "postcard", "proc-macro-api", "proc-macro-srv", - "tt", ] [[package]] @@ -2782,7 +2779,6 @@ dependencies = [ "hir-expand", "intern", "paths", - "rustc-hash 2.1.1", "span", "stdx", "test-utils", diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml index a9b51e347d60..46acf3de6264 100644 --- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml @@ -40,7 +40,6 @@ intern.workspace = true base-db.workspace = true syntax.workspace = true hir-expand.workspace = true -mbe.workspace = true cfg.workspace = true tt.workspace = true span.workspace = true diff --git a/src/tools/rust-analyzer/crates/intern/Cargo.toml b/src/tools/rust-analyzer/crates/intern/Cargo.toml index 6414f091783c..ad73c191c047 100644 --- a/src/tools/rust-analyzer/crates/intern/Cargo.toml +++ b/src/tools/rust-analyzer/crates/intern/Cargo.toml @@ -18,7 +18,6 @@ dashmap.workspace = true hashbrown.workspace = true rustc-hash.workspace = true triomphe.workspace = true -smallvec.workspace = true rayon.workspace = true [lints] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml index aa153897fa96..2c6e5a16ee06 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml @@ -13,7 +13,6 @@ publish = false [dependencies] proc-macro-srv.workspace = true proc-macro-api.workspace = true -tt.workspace = true postcard.workspace = true clap = {version = "4.5.42", default-features = false, features = ["std"]} diff --git a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml index 8910911ff025..b2f238efc025 100644 --- a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml +++ b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml @@ -10,7 +10,6 @@ cargo-fuzz = true [dependencies] syntax = { path = "..", version = "0.0.0" } -text-edit = { path = "../../text-edit", version = "0.0.0" } libfuzzer-sys = "0.4.5" # Prevent this from interfering with workspaces diff --git a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml index 7760ae7aa045..74a4f8363248 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml +++ b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml @@ -14,7 +14,6 @@ test-utils.workspace = true tt.workspace = true cfg.workspace = true base-db.workspace = true -rustc-hash.workspace = true span.workspace = true stdx.workspace = true intern.workspace = true From 3f477dd71082c6342ae34d32b49a63735ce0bc6f Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Thu, 25 Dec 2025 14:49:01 +0300 Subject: [PATCH 1229/3801] Recursive delegation improvements --- compiler/rustc_ast_lowering/src/delegation.rs | 240 +++++++++++------- compiler/rustc_middle/src/ty/mod.rs | 22 +- compiler/rustc_resolve/src/late.rs | 76 +++--- compiler/rustc_resolve/src/lib.rs | 10 +- tests/pretty/delegation-inherit-attributes.pp | 64 +++++ tests/pretty/delegation-inherit-attributes.rs | 45 ++++ ...bute.pp => delegation-inline-attribute.pp} | 2 +- ...bute.rs => delegation-inline-attribute.rs} | 2 +- .../recursive-delegation-ice-150152.rs | 31 +++ .../recursive-delegation-ice-150152.stderr | 74 ++++++ .../delegation/recursive-delegation-pass.rs | 98 ++++++- 11 files changed, 522 insertions(+), 142 deletions(-) rename tests/pretty/{delegation_inline_attribute.pp => delegation-inline-attribute.pp} (98%) rename tests/pretty/{delegation_inline_attribute.rs => delegation-inline-attribute.rs} (98%) create mode 100644 tests/ui/delegation/recursive-delegation-ice-150152.rs create mode 100644 tests/ui/delegation/recursive-delegation-ice-150152.stderr diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 532a0ce520cd..5d2531e50393 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -48,11 +48,12 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::ErrorGuaranteed; use rustc_hir::Target; use rustc_hir::attrs::{AttributeKind, InlineAttr}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::span_bug; -use rustc_middle::ty::{Asyncness, DelegationFnSigAttrs, ResolverAstLowering}; +use rustc_middle::ty::{Asyncness, DelegationAttrs, DelegationFnSigAttrs, ResolverAstLowering}; use rustc_span::symbol::kw; use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; +use smallvec::SmallVec; use {rustc_ast as ast, rustc_hir as hir}; use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode}; @@ -66,24 +67,24 @@ pub(crate) struct DelegationResults<'hir> { pub generics: &'hir hir::Generics<'hir>, } -struct AttributeAdditionInfo { +struct AttrAdditionInfo { pub equals: fn(&hir::Attribute) -> bool, - pub kind: AttributeAdditionKind, + pub kind: AttrAdditionKind, } -enum AttributeAdditionKind { +enum AttrAdditionKind { Default { factory: fn(Span) -> hir::Attribute }, Inherit { flag: DelegationFnSigAttrs, factory: fn(Span, &hir::Attribute) -> hir::Attribute }, } const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO; -static ATTRIBUTES_ADDITIONS: &[AttributeAdditionInfo] = &[ - AttributeAdditionInfo { +static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[ + AttrAdditionInfo { equals: |a| matches!(a, hir::Attribute::Parsed(AttributeKind::MustUse { .. })), - kind: AttributeAdditionKind::Inherit { - factory: |span, original_attribute| { - let reason = match original_attribute { + kind: AttrAdditionKind::Inherit { + factory: |span, original_attr| { + let reason = match original_attr { hir::Attribute::Parsed(AttributeKind::MustUse { reason, .. }) => *reason, _ => None, }; @@ -93,14 +94,41 @@ static ATTRIBUTES_ADDITIONS: &[AttributeAdditionInfo] = &[ flag: DelegationFnSigAttrs::MUST_USE, }, }, - AttributeAdditionInfo { + AttrAdditionInfo { equals: |a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))), - kind: AttributeAdditionKind::Default { + kind: AttrAdditionKind::Default { factory: |span| hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span)), }, }, ]; +type DelegationIdsVec = SmallVec<[DefId; 1]>; + +// As delegations can now refer to another delegation, we have a delegation path +// of the following type: reuse (current delegation) <- reuse (delegee_id) <- ... <- reuse <- function (root_function_id). +// In its most basic and widely used form: reuse (current delegation) <- function (delegee_id, root_function_id) +struct DelegationIds { + path: DelegationIdsVec, +} + +impl DelegationIds { + fn new(path: DelegationIdsVec) -> Self { + assert!(!path.is_empty()); + Self { path } + } + + // Id of the first function in (non)local crate that is being reused + fn root_function_id(&self) -> DefId { + *self.path.last().expect("Ids vector can't be empty") + } + + // Id of the first definition which is being reused, + // can be either function, in this case `root_id == delegee_id`, or other delegation + fn delegee_id(&self) -> DefId { + *self.path.first().expect("Ids vector can't be empty") + } +} + impl<'hir> LoweringContext<'_, 'hir> { fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { @@ -124,19 +152,36 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> DelegationResults<'hir> { let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span); - let sig_id = self.get_delegation_sig_id( - self.resolver.delegation_sig_resolution_nodes[&self.local_def_id(item_id)], + let ids = self.get_delegation_ids( + self.resolver.delegation_infos[&self.local_def_id(item_id)].resolution_node, span, ); - match sig_id { - Ok(sig_id) => { - self.add_attributes_if_needed(span, sig_id); + match ids { + Ok(ids) => { + self.add_attrs_if_needed(span, &ids); + + let delegee_id = ids.delegee_id(); + let root_function_id = ids.root_function_id(); + + // `is_method` is used to choose the name of the first parameter (`self` or `arg0`), + // if the original function is not a method (without `self`), then it can not be added + // during chain of reuses, so we use `root_function_id` here + let is_method = self.is_method(root_function_id, span); + + // Here we use `root_function_id` as we can not get params information out of potential delegation reuse, + // we need a function to extract this information + let (param_count, c_variadic) = self.param_count(root_function_id); + + // Here we use `delegee_id`, as this id will then be used to calculate parent for generics + // inheritance, and we want this id to point on a delegee, not on the original + // function (see https://github.com/rust-lang/rust/issues/150152#issuecomment-3674834654) + let decl = self.lower_delegation_decl(delegee_id, param_count, c_variadic, span); + + // Here we pass `root_function_id` as we want to inherit signature (including consts, async) + // from the root function that started delegation + let sig = self.lower_delegation_sig(root_function_id, decl, span); - let is_method = self.is_method(sig_id, span); - let (param_count, c_variadic) = self.param_count(sig_id); - let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span); - let sig = self.lower_delegation_sig(sig_id, decl, span); let body_id = self.lower_delegation_body(delegation, is_method, param_count, span); let ident = self.lower_ident(delegation.ident); let generics = self.lower_delegation_generics(span); @@ -146,36 +191,36 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn add_attributes_if_needed(&mut self, span: Span, sig_id: DefId) { - let new_attributes = self.create_new_attributes( - ATTRIBUTES_ADDITIONS, - span, - sig_id, - self.attrs.get(&PARENT_ID), - ); + fn add_attrs_if_needed(&mut self, span: Span, ids: &DelegationIds) { + let new_attrs = + self.create_new_attrs(ATTRS_ADDITIONS, span, ids, self.attrs.get(&PARENT_ID)); - if new_attributes.is_empty() { + if new_attrs.is_empty() { return; } - let new_arena_allocated_attributes = match self.attrs.get(&PARENT_ID) { + let new_arena_allocated_attrs = match self.attrs.get(&PARENT_ID) { Some(existing_attrs) => self.arena.alloc_from_iter( - existing_attrs.iter().map(|a| a.clone()).chain(new_attributes.into_iter()), + existing_attrs.iter().map(|a| a.clone()).chain(new_attrs.into_iter()), ), - None => self.arena.alloc_from_iter(new_attributes.into_iter()), + None => self.arena.alloc_from_iter(new_attrs.into_iter()), }; - self.attrs.insert(PARENT_ID, new_arena_allocated_attributes); + self.attrs.insert(PARENT_ID, new_arena_allocated_attrs); } - fn create_new_attributes( + fn create_new_attrs( &self, - candidate_additions: &[AttributeAdditionInfo], + candidate_additions: &[AttrAdditionInfo], span: Span, - sig_id: DefId, + ids: &DelegationIds, existing_attrs: Option<&&[hir::Attribute]>, ) -> Vec { - let local_original_attributes = self.parse_local_original_attributes(sig_id); + let defs_orig_attrs = ids + .path + .iter() + .map(|def_id| (*def_id, self.parse_local_original_attrs(*def_id))) + .collect::>(); candidate_additions .iter() @@ -189,65 +234,81 @@ impl<'hir> LoweringContext<'_, 'hir> { } match addition_info.kind { - AttributeAdditionKind::Default { factory } => Some(factory(span)), - AttributeAdditionKind::Inherit { flag, factory } => { - let original_attribute = match sig_id.as_local() { - Some(local_id) => self - .resolver - .delegation_fn_sigs - .get(&local_id) - .is_some_and(|sig| sig.attrs_flags.contains(flag)) - .then(|| { - local_original_attributes - .as_ref() - .map(|attrs| { - attrs - .iter() - .find(|base_attr| (addition_info.equals)(base_attr)) - }) - .flatten() - }) - .flatten(), - None => self - .tcx - .get_all_attrs(sig_id) - .iter() - .find(|base_attr| (addition_info.equals)(base_attr)), - }; + AttrAdditionKind::Default { factory } => Some(factory(span)), + AttrAdditionKind::Inherit { flag, factory } => { + for (def_id, orig_attrs) in &defs_orig_attrs { + let original_attr = match def_id.as_local() { + Some(local_id) => self + .get_attrs(local_id) + .flags + .contains(flag) + .then(|| { + orig_attrs + .as_ref() + .map(|attrs| { + attrs.iter().find(|base_attr| { + (addition_info.equals)(base_attr) + }) + }) + .flatten() + }) + .flatten(), + None => self + .tcx + .get_all_attrs(*def_id) + .iter() + .find(|base_attr| (addition_info.equals)(base_attr)), + }; - original_attribute.map(|a| factory(span, a)) + if let Some(original_attr) = original_attr { + return Some(factory(span, original_attr)); + } + } + + None } } }) .collect::>() } - fn parse_local_original_attributes(&self, sig_id: DefId) -> Option> { - if let Some(local_id) = sig_id.as_local() - && let Some(info) = self.resolver.delegation_fn_sigs.get(&local_id) - && !info.to_inherit_attrs.is_empty() - { - Some(AttributeParser::parse_limited_all( - self.tcx.sess, - info.to_inherit_attrs.as_slice(), - None, - Target::Fn, - DUMMY_SP, - DUMMY_NODE_ID, - Some(self.tcx.features()), - ShouldEmit::Nothing, - )) + fn parse_local_original_attrs(&self, def_id: DefId) -> Option> { + if let Some(local_id) = def_id.as_local() { + let attrs = &self.get_attrs(local_id).to_inherit; + + if !attrs.is_empty() { + return Some(AttributeParser::parse_limited_all( + self.tcx.sess, + attrs, + None, + Target::Fn, + DUMMY_SP, + DUMMY_NODE_ID, + Some(self.tcx.features()), + ShouldEmit::Nothing, + )); + } + } + + None + } + + fn get_attrs(&self, local_id: LocalDefId) -> &DelegationAttrs { + // local_id can correspond either to a function or other delegation + if let Some(fn_sig) = self.resolver.delegation_fn_sigs.get(&local_id) { + &fn_sig.attrs } else { - None + &self.resolver.delegation_infos[&local_id].attrs } } - fn get_delegation_sig_id( + fn get_delegation_ids( &self, mut node_id: NodeId, span: Span, - ) -> Result { + ) -> Result { let mut visited: FxHashSet = Default::default(); + let mut path: DelegationIdsVec = Default::default(); loop { visited.insert(node_id); @@ -262,14 +323,15 @@ impl<'hir> LoweringContext<'_, 'hir> { )); }; + path.push(def_id); + // If def_id is in local crate and it corresponds to another delegation // it means that we refer to another delegation as a callee, so in order to obtain // a signature DefId we obtain NodeId of the callee delegation and try to get signature from it. if let Some(local_id) = def_id.as_local() - && let Some(next_node_id) = - self.resolver.delegation_sig_resolution_nodes.get(&local_id) + && let Some(delegation_info) = self.resolver.delegation_infos.get(&local_id) { - node_id = *next_node_id; + node_id = delegation_info.resolution_node; if visited.contains(&node_id) { // We encountered a cycle in the resolution, or delegation callee refers to non-existent // entity, in this case emit an error. @@ -279,7 +341,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }); } } else { - return Ok(def_id); + return Ok(DelegationIds::new(path)); } } } @@ -299,14 +361,14 @@ impl<'hir> LoweringContext<'_, 'hir> { } // Function parameter count, including C variadic `...` if present. - fn param_count(&self, sig_id: DefId) -> (usize, bool /*c_variadic*/) { - if let Some(local_sig_id) = sig_id.as_local() { + fn param_count(&self, def_id: DefId) -> (usize, bool /*c_variadic*/) { + if let Some(local_sig_id) = def_id.as_local() { match self.resolver.delegation_fn_sigs.get(&local_sig_id) { Some(sig) => (sig.param_count, sig.c_variadic), None => (0, false), } } else { - let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder(); + let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder(); (sig.inputs().len() + usize::from(sig.c_variadic), sig.c_variadic) } } @@ -356,7 +418,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // We are not forwarding the attributes, as the delegation fn sigs are collected on the ast, // and here we need the hir attributes. let default_safety = - if sig.attrs_flags.contains(DelegationFnSigAttrs::TARGET_FEATURE) + if sig.attrs.flags.contains(DelegationFnSigAttrs::TARGET_FEATURE) || self.tcx.def_kind(parent) == DefKind::ForeignMod { hir::Safety::Unsafe diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 5cc5ab0d5268..cb47869a1351 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -220,9 +220,8 @@ pub struct ResolverAstLowering { /// Information about functions signatures for delegation items expansion pub delegation_fn_sigs: LocalDefIdMap, - // NodeIds (either delegation.id or item_id in case of a trait impl) for signature resolution, - // for details see https://github.com/rust-lang/rust/issues/118212#issuecomment-2160686914 - pub delegation_sig_resolution_nodes: LocalDefIdMap, + // Information about delegations which is used when handling recursive delegations + pub delegation_infos: LocalDefIdMap, } bitflags::bitflags! { @@ -235,14 +234,27 @@ bitflags::bitflags! { pub const DELEGATION_INHERIT_ATTRS_START: DelegationFnSigAttrs = DelegationFnSigAttrs::MUST_USE; +#[derive(Debug)] +pub struct DelegationInfo { + // NodeId (either delegation.id or item_id in case of a trait impl) for signature resolution, + // for details see https://github.com/rust-lang/rust/issues/118212#issuecomment-2160686914 + pub resolution_node: ast::NodeId, + pub attrs: DelegationAttrs, +} + +#[derive(Debug)] +pub struct DelegationAttrs { + pub flags: DelegationFnSigAttrs, + pub to_inherit: AttrVec, +} + #[derive(Debug)] pub struct DelegationFnSig { pub header: ast::FnHeader, pub param_count: usize, pub has_self: bool, pub c_variadic: bool, - pub attrs_flags: DelegationFnSigAttrs, - pub to_inherit_attrs: AttrVec, + pub attrs: DelegationAttrs, } #[derive(Clone, Copy, Debug, HashStable)] diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 4fefcc66b588..dd80f5da508c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -29,7 +29,8 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate}; use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::ty::{ - AssocTag, DELEGATION_INHERIT_ATTRS_START, DelegationFnSig, DelegationFnSigAttrs, Visibility, + AssocTag, DELEGATION_INHERIT_ATTRS_START, DelegationAttrs, DelegationFnSig, + DelegationFnSigAttrs, DelegationInfo, Visibility, }; use rustc_middle::{bug, span_bug}; use rustc_session::config::{CrateType, ResolveDocLinks}; @@ -2928,7 +2929,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { item.id, LifetimeBinderKind::Function, span, - |this| this.resolve_delegation(delegation, item.id, false), + |this| this.resolve_delegation(delegation, item.id, false, &item.attrs), ); } @@ -3257,7 +3258,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { item.id, LifetimeBinderKind::Function, delegation.path.segments.last().unwrap().ident.span, - |this| this.resolve_delegation(delegation, item.id, false), + |this| this.resolve_delegation(delegation, item.id, false, &item.attrs), ); } AssocItemKind::Type(box TyAlias { generics, .. }) => self @@ -3386,7 +3387,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)"); let mut seen_trait_items = Default::default(); for item in impl_items { - this.resolve_impl_item(&**item, &mut seen_trait_items, trait_id); + this.resolve_impl_item(&**item, &mut seen_trait_items, trait_id, of_trait.is_some()); } }); }); @@ -3405,6 +3406,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { item: &'ast AssocItem, seen_trait_items: &mut FxHashMap, trait_id: Option, + is_in_trait_impl: bool, ) { use crate::ResolutionError::*; self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis))); @@ -3550,7 +3552,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |i, s, c| MethodNotMemberOfTrait(i, s, c), ); - this.resolve_delegation(delegation, item.id, trait_id.is_some()); + // Here we don't use `trait_id`, as we can process unresolved trait, however + // in this case we are still in a trait impl, https://github.com/rust-lang/rust/issues/150152 + this.resolve_delegation(delegation, item.id, is_in_trait_impl, &item.attrs); }, ); } @@ -3704,6 +3708,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { delegation: &'ast Delegation, item_id: NodeId, is_in_trait_impl: bool, + attrs: &[Attribute], ) { self.smart_resolve_path( delegation.id, @@ -3718,9 +3723,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.visit_path(&delegation.path); - self.r.delegation_sig_resolution_nodes.insert( + self.r.delegation_infos.insert( self.r.local_def_id(item_id), - if is_in_trait_impl { item_id } else { delegation.id }, + DelegationInfo { + attrs: create_delegation_attrs(attrs), + resolution_node: if is_in_trait_impl { item_id } else { delegation.id }, + }, ); let Some(body) = &delegation.body else { return }; @@ -5334,39 +5342,43 @@ impl ItemInfoCollector<'_, '_, '_> { id: NodeId, attrs: &[Attribute], ) { - static NAMES_TO_FLAGS: &[(Symbol, DelegationFnSigAttrs)] = &[ - (sym::target_feature, DelegationFnSigAttrs::TARGET_FEATURE), - (sym::must_use, DelegationFnSigAttrs::MUST_USE), - ]; + self.r.delegation_fn_sigs.insert( + self.r.local_def_id(id), + DelegationFnSig { + header, + param_count: decl.inputs.len(), + has_self: decl.has_self(), + c_variadic: decl.c_variadic(), + attrs: create_delegation_attrs(attrs), + }, + ); + } +} - let mut to_inherit_attrs = AttrVec::new(); - let mut attrs_flags = DelegationFnSigAttrs::empty(); +fn create_delegation_attrs(attrs: &[Attribute]) -> DelegationAttrs { + static NAMES_TO_FLAGS: &[(Symbol, DelegationFnSigAttrs)] = &[ + (sym::target_feature, DelegationFnSigAttrs::TARGET_FEATURE), + (sym::must_use, DelegationFnSigAttrs::MUST_USE), + ]; - 'attrs_loop: for attr in attrs { - for &(name, flag) in NAMES_TO_FLAGS { - if attr.has_name(name) { - attrs_flags.set(flag, true); + let mut to_inherit_attrs = AttrVec::new(); + let mut flags = DelegationFnSigAttrs::empty(); - if flag.bits() >= DELEGATION_INHERIT_ATTRS_START.bits() { - to_inherit_attrs.push(attr.clone()); - } + 'attrs_loop: for attr in attrs { + for &(name, flag) in NAMES_TO_FLAGS { + if attr.has_name(name) { + flags.set(flag, true); - continue 'attrs_loop; + if flag.bits() >= DELEGATION_INHERIT_ATTRS_START.bits() { + to_inherit_attrs.push(attr.clone()); } + + continue 'attrs_loop; } } - - let sig = DelegationFnSig { - header, - param_count: decl.inputs.len(), - has_self: decl.has_self(), - c_variadic: decl.c_variadic(), - attrs_flags, - to_inherit_attrs, - }; - - self.r.delegation_fn_sigs.insert(self.r.local_def_id(id), sig); } + + DelegationAttrs { flags, to_inherit: to_inherit_attrs } } impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 57f19f7ea398..ec030ecf8e13 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -69,8 +69,8 @@ use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::{ - self, DelegationFnSig, Feed, MainDefinition, RegisteredTools, ResolverAstLowering, - ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, + self, DelegationFnSig, DelegationInfo, Feed, MainDefinition, RegisteredTools, + ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, }; use rustc_query_system::ich::StableHashingContext; use rustc_session::config::CrateType; @@ -1283,7 +1283,7 @@ pub struct Resolver<'ra, 'tcx> { /// Amount of lifetime parameters for each item in the crate. item_generics_num_lifetimes: FxHashMap, delegation_fn_sigs: LocalDefIdMap, - delegation_sig_resolution_nodes: LocalDefIdMap, + delegation_infos: LocalDefIdMap, main_def: Option = None, trait_impls: FxIndexMap>, @@ -1701,7 +1701,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { current_crate_outer_attr_insert_span, mods_with_parse_errors: Default::default(), impl_trait_names: Default::default(), - delegation_sig_resolution_nodes: Default::default(), + delegation_infos: Default::default(), .. }; @@ -1829,7 +1829,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), delegation_fn_sigs: self.delegation_fn_sigs, - delegation_sig_resolution_nodes: self.delegation_sig_resolution_nodes, + delegation_infos: self.delegation_infos, }; ResolverOutputs { global_ctxt, ast_lowering } } diff --git a/tests/pretty/delegation-inherit-attributes.pp b/tests/pretty/delegation-inherit-attributes.pp index 772e177b8883..8e30da1ad589 100644 --- a/tests/pretty/delegation-inherit-attributes.pp +++ b/tests/pretty/delegation-inherit-attributes.pp @@ -57,5 +57,69 @@ const fn const_fn_extern() -> _ { to_reuse_functions::const_fn_extern() } #[attr = Inline(Hint)] async fn async_fn_extern() -> _ { to_reuse_functions::async_fn_extern() } +mod recursive { + // Check that `baz` inherit attribute from `foo` + mod first { + fn bar() { } + #[attr = MustUse {reason: "some reason"}] + #[attr = Inline(Hint)] + fn foo() -> _ { bar() } + #[attr = MustUse {reason: "some reason"}] + #[attr = Inline(Hint)] + fn baz() -> _ { foo() } + } + + // Check that `baz` inherit attribute from `bar` + mod second { + #[attr = MustUse {reason: "some reason"}] + fn bar() { } + + #[attr = MustUse {reason: "some reason"}] + #[attr = Inline(Hint)] + fn foo() -> _ { bar() } + #[attr = MustUse {reason: "some reason"}] + #[attr = Inline(Hint)] + fn baz() -> _ { foo() } + } + + // Check that `foo5` don't inherit attribute from `bar` + // and inherit attribute from foo4, check that foo1, foo2 and foo3 + // inherit attribute from bar + mod third { + #[attr = MustUse {reason: "some reason"}] + fn bar() { } + #[attr = MustUse {reason: "some reason"}] + #[attr = Inline(Hint)] + fn foo1() -> _ { bar() } + #[attr = MustUse {reason: "some reason"}] + #[attr = Inline(Hint)] + fn foo2() -> _ { foo1() } + #[attr = MustUse {reason: "some reason"}] + #[attr = Inline(Hint)] + fn foo3() -> _ { foo2() } + #[attr = MustUse {reason: "foo4"}] + #[attr = Inline(Hint)] + fn foo4() -> _ { foo3() } + #[attr = MustUse {reason: "foo4"}] + #[attr = Inline(Hint)] + fn foo5() -> _ { foo4() } + } + + mod fourth { + trait T { + fn foo(&self, x: usize) -> usize { x + 1 } + } + + struct X; + impl T for X { } + + #[attr = MustUse {reason: "some reason"}] + #[attr = Inline(Hint)] + fn foo(self: _, arg1: _) -> _ { ::foo(self + 1, arg1) } + #[attr = MustUse {reason: "some reason"}] + #[attr = Inline(Hint)] + fn bar(self: _, arg1: _) -> _ { foo(self + 1, arg1) } + } +} fn main() { } diff --git a/tests/pretty/delegation-inherit-attributes.rs b/tests/pretty/delegation-inherit-attributes.rs index fe74b9a55a7d..581294d472a3 100644 --- a/tests/pretty/delegation-inherit-attributes.rs +++ b/tests/pretty/delegation-inherit-attributes.rs @@ -52,5 +52,50 @@ reuse to_reuse_functions::const_fn_extern; #[must_use = "some reason"] reuse to_reuse_functions::async_fn_extern; +mod recursive { + // Check that `baz` inherit attribute from `foo` + mod first { + fn bar() {} + #[must_use = "some reason"] + reuse bar as foo; + reuse foo as baz; + } + + // Check that `baz` inherit attribute from `bar` + mod second { + #[must_use = "some reason"] + fn bar() {} + + reuse bar as foo; + reuse foo as baz; + } + + // Check that `foo5` don't inherit attribute from `bar` + // and inherit attribute from foo4, check that foo1, foo2 and foo3 + // inherit attribute from bar + mod third { + #[must_use = "some reason"] + fn bar() {} + reuse bar as foo1; + reuse foo1 as foo2; + reuse foo2 as foo3; + #[must_use = "foo4"] + reuse foo3 as foo4; + reuse foo4 as foo5; + } + + mod fourth { + trait T { + fn foo(&self, x: usize) -> usize { x + 1 } + } + + struct X; + impl T for X {} + + #[must_use = "some reason"] + reuse ::foo { self + 1 } + reuse foo as bar { self + 1 } + } +} fn main() {} diff --git a/tests/pretty/delegation_inline_attribute.pp b/tests/pretty/delegation-inline-attribute.pp similarity index 98% rename from tests/pretty/delegation_inline_attribute.pp rename to tests/pretty/delegation-inline-attribute.pp index 4b3b2aa8f80a..826d099e8155 100644 --- a/tests/pretty/delegation_inline_attribute.pp +++ b/tests/pretty/delegation-inline-attribute.pp @@ -1,6 +1,6 @@ //@ pretty-compare-only //@ pretty-mode:hir -//@ pp-exact:delegation_inline_attribute.pp +//@ pp-exact:delegation-inline-attribute.pp #![allow(incomplete_features)] #![feature(fn_delegation)] diff --git a/tests/pretty/delegation_inline_attribute.rs b/tests/pretty/delegation-inline-attribute.rs similarity index 98% rename from tests/pretty/delegation_inline_attribute.rs rename to tests/pretty/delegation-inline-attribute.rs index 0716cfc51f5d..c79f68f8942d 100644 --- a/tests/pretty/delegation_inline_attribute.rs +++ b/tests/pretty/delegation-inline-attribute.rs @@ -1,6 +1,6 @@ //@ pretty-compare-only //@ pretty-mode:hir -//@ pp-exact:delegation_inline_attribute.pp +//@ pp-exact:delegation-inline-attribute.pp #![allow(incomplete_features)] #![feature(fn_delegation)] diff --git a/tests/ui/delegation/recursive-delegation-ice-150152.rs b/tests/ui/delegation/recursive-delegation-ice-150152.rs new file mode 100644 index 000000000000..565563c9d03d --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-ice-150152.rs @@ -0,0 +1,31 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod first_example { + mod to_reuse { pub fn foo() {} } + struct S< S >; + //~^ ERROR type parameter `S` is never used + + impl Item for S { + //~^ ERROR cannot find trait `Item` in this scope + //~| ERROR missing generics for struct `S` + reuse to_reuse::foo; + } +} + +mod second_example { + trait Trait { + reuse to_reuse::foo; + //~^ ERROR function `foo` is private + } + mod to_reuse { + fn foo() {} + } + impl Trait for S { + //~^ ERROR cannot find type `S` in this scope + reuse foo; + //~^ ERROR cannot find function `foo` in this scope + } +} + +fn main() {} diff --git a/tests/ui/delegation/recursive-delegation-ice-150152.stderr b/tests/ui/delegation/recursive-delegation-ice-150152.stderr new file mode 100644 index 000000000000..c58f0ff09291 --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-ice-150152.stderr @@ -0,0 +1,74 @@ +error[E0405]: cannot find trait `Item` in this scope + --> $DIR/recursive-delegation-ice-150152.rs:9:10 + | +LL | impl Item for S { + | ^^^^ not found in this scope + +error[E0425]: cannot find type `S` in this scope + --> $DIR/recursive-delegation-ice-150152.rs:24:20 + | +LL | impl Trait for S { + | ^ not found in this scope + | +note: struct `first_example::S` exists but is inaccessible + --> $DIR/recursive-delegation-ice-150152.rs:6:5 + | +LL | struct S< S >; + | ^^^^^^^^^^^^^^ not accessible + +error[E0425]: cannot find function `foo` in this scope + --> $DIR/recursive-delegation-ice-150152.rs:26:15 + | +LL | reuse foo; + | ^^^ not found in this scope + | +note: these functions exist but are inaccessible + --> $DIR/recursive-delegation-ice-150152.rs:5:20 + | +LL | mod to_reuse { pub fn foo() {} } + | ^^^^^^^^^^^^ `first_example::to_reuse::foo`: not accessible +... +LL | fn foo() {} + | ^^^^^^^^ `second_example::to_reuse::foo`: not accessible + +error[E0603]: function `foo` is private + --> $DIR/recursive-delegation-ice-150152.rs:18:25 + | +LL | reuse to_reuse::foo; + | ^^^ private function + | +note: the function `foo` is defined here + --> $DIR/recursive-delegation-ice-150152.rs:22:9 + | +LL | fn foo() {} + | ^^^^^^^^ + +error[E0392]: type parameter `S` is never used + --> $DIR/recursive-delegation-ice-150152.rs:6:15 + | +LL | struct S< S >; + | ^ unused type parameter + | + = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead + +error[E0107]: missing generics for struct `S` + --> $DIR/recursive-delegation-ice-150152.rs:9:21 + | +LL | impl Item for S { + | ^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `S` + --> $DIR/recursive-delegation-ice-150152.rs:6:12 + | +LL | struct S< S >; + | ^ - +help: add missing generic argument + | +LL | impl Item for S> { + | +++ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0107, E0392, E0405, E0425, E0603. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/delegation/recursive-delegation-pass.rs b/tests/ui/delegation/recursive-delegation-pass.rs index 93f8fa401b55..2a40986d352a 100644 --- a/tests/ui/delegation/recursive-delegation-pass.rs +++ b/tests/ui/delegation/recursive-delegation-pass.rs @@ -1,9 +1,10 @@ -//@ check-pass +//@ run-pass //@ edition:2018 //@ aux-crate:recursive_delegation_aux=recursive-delegation-aux.rs #![feature(fn_delegation)] #![allow(incomplete_features)] +#![allow(warnings)] mod first_mod { pub mod to_reuse { @@ -12,18 +13,35 @@ mod first_mod { } } - mod single_reuse { - reuse crate::first_mod::to_reuse::foo; - reuse foo as bar; - reuse foo as bar1; - reuse bar as goo; - reuse goo as koo; - reuse koo as too; + pub mod single_reuse { + reuse crate::first_mod::to_reuse::foo { self + 1 } + reuse foo as bar { self + 1 } + reuse foo as bar1 { self + 1 } + reuse bar as goo { self + 1 } + reuse goo as koo { self + 1 } + pub reuse koo as too { self + 1 } + + pub fn check() { + assert_eq!(foo(1), 3); + assert_eq!(bar(1), 4); + assert_eq!(bar1(1), 4); + assert_eq!(goo(1), 5); + assert_eq!(koo(1), 6); + assert_eq!(too(1), 7); + } } mod glob_reuse { reuse super::to_reuse::{foo as bar, foo as bar1} { self } reuse super::glob_reuse::{bar as goo, goo as koo, koo as too} { self } + + fn check() { + bar(1); + bar1(1); + goo(1); + koo(1); + too(1); + } } } @@ -44,6 +62,29 @@ mod second_mod { reuse TGlob::{foo1 as bar1, foo3 as bar3, bar1 as bar11, bar11 as bar111} { self.xd() } } + + fn check() { + struct X; + impl T for X { + fn foo(&self) {} + fn bar(&self) {} + fn goo(&self) {} + fn poo(&self) {} + } + + impl TGlob for X { + fn xd(&self) -> &Self { &self } + fn foo1(&self) {} + fn foo2(&self) {} + fn foo3(&self) {} + fn foo4(&self) {} + + fn bar1(&self) {} + fn bar3(&self) {} + fn bar11(&self) {} + fn bar111(&self) {} + } + } } mod third_mod { @@ -63,6 +104,45 @@ mod third_mod { mod fourth_mod { reuse recursive_delegation_aux::goo as bar; reuse bar as foo; + + fn check() { + bar(); + foo(); + } } -fn main() {} +mod fifth_mod { + mod m { + fn foo() { } + pub reuse foo as bar; + } + + trait T { + reuse m::bar as foo; + } + + struct X; + impl T for X {} + + trait T1 { + reuse ::foo as baz; + } + + impl T1 for X {} + + struct Y; + impl T1 for Y { + reuse ::foo as baz; + } + + fn check() { + m::bar(); + ::foo(); + ::baz(); + ::baz(); + } +} + +fn main() { + first_mod::single_reuse::check(); +} From 519e57d78ea4c49d39d1251a204465611c8b6727 Mon Sep 17 00:00:00 2001 From: Roy Ammerschuber Date: Tue, 2 Dec 2025 09:57:12 +0100 Subject: [PATCH 1230/3801] Tree Visitor: only skip possible children during protector end access --- .../src/borrow_tracker/tree_borrows/tree.rs | 56 ++++++++++++- .../wildcard/protector_release.rs | 79 ++++++++++++++++++ .../wildcard/protector_release.stderr | 25 ++++++ .../wildcard/protector_release2.rs | 81 +++++++++++++++++++ .../wildcard/protector_release2.stderr | 25 ++++++ 5 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release2.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release2.stderr diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 900e9c3729c8..2e96c0c61cdb 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -661,6 +661,7 @@ impl<'tcx> Tree { global, ChildrenVisitMode::VisitChildrenOfAccessed, &diagnostics, + /* min_exposed_child */ None, // only matters for protector end access, )?; } interp_ok(()) @@ -686,6 +687,13 @@ impl<'tcx> Tree { let source_idx = self.tag_mapping.get(&tag).unwrap(); + let min_exposed_child = if self.roots.len() > 1 { + LocationTree::get_min_exposed_child(source_idx, &self.nodes) + } else { + // There's no point in computing this when there is just one tree. + None + }; + // This is a special access through the entire allocation. // It actually only affects `accessed` locations, so we need // to filter on those before initiating the traversal. @@ -716,6 +724,7 @@ impl<'tcx> Tree { global, ChildrenVisitMode::SkipChildrenOfAccessed, &diagnostics, + min_exposed_child, )?; } } @@ -876,9 +885,36 @@ impl Tree { } impl<'tcx> LocationTree { + /// Returns the smallest exposed tag, if any, that is a transitive child of `root`. + fn get_min_exposed_child(root: UniIndex, nodes: &UniValMap) -> Option { + // We cannot use the wildcard datastructure to improve this lookup. This is because + // the datastructure only tracks enabled nodes and we need to also consider disabled ones. + let mut stack = vec![root]; + let mut min_tag = None; + while let Some(idx) = stack.pop() { + let node = nodes.get(idx).unwrap(); + if min_tag.is_some_and(|min| min < node.tag) { + // The minimum we found before is bigger than this tag, and therefore + // also bigger than all its children, so we can skip this subtree. + continue; + } + stack.extend_from_slice(node.children.as_slice()); + if node.is_exposed { + min_tag = match min_tag { + Some(prev) if prev < node.tag => Some(prev), + _ => Some(node.tag), + }; + } + } + min_tag + } + /// Performs an access on this location. /// * `access_source`: The index, if any, where the access came from. /// * `visit_children`: Whether to skip updating the children of `access_source`. + /// * `min_exposed_child`: The tag of the smallest exposed (transitive) child of the accessed node. + /// This is only used with `visit_children == SkipChildrenOfAccessed`, where we need to skip children + /// of the accessed node. fn perform_access( &mut self, roots: impl Iterator, @@ -888,6 +924,7 @@ impl<'tcx> LocationTree { global: &GlobalState, visit_children: ChildrenVisitMode, diagnostics: &DiagnosticInfo, + min_exposed_child: Option, ) -> InterpResult<'tcx> { let accessed_root = if let Some(idx) = access_source { Some(self.perform_normal_access( @@ -906,11 +943,22 @@ impl<'tcx> LocationTree { }; let accessed_root_tag = accessed_root.map(|idx| nodes.get(idx).unwrap().tag); - if matches!(visit_children, ChildrenVisitMode::SkipChildrenOfAccessed) { - // FIXME: approximate which roots could be children of the accessed node and only skip them instead of all other trees. - return interp_ok(()); - } for root in roots { + let tag = nodes.get(root).unwrap().tag; + // On a protector release access we have to skip the children of the accessed tag. + // However, if the tag has exposed children then some of the wildcard subtrees could + // also be children of the accessed node and would also need to be skipped. We can + // narrow down which wildcard trees might be children by comparing their root tag to the + // minimum exposed child of the accessed node. As the parent tag is always smaller + // than the child tag this means we only need to skip subtrees with a root tag larger + // than `min_exposed_child`. Once we find such a root, we can leave the loop because roots + // are sorted by tag. + if matches!(visit_children, ChildrenVisitMode::SkipChildrenOfAccessed) + && let Some(min_exposed_child) = min_exposed_child + && tag > min_exposed_child + { + break; + } // We don't perform a wildcard access on the tree we already performed a // normal access on. if Some(root) == accessed_root { diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release.rs new file mode 100644 index 000000000000..d1bb9d781575 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release.rs @@ -0,0 +1,79 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance +use std::cell::UnsafeCell; + +/// This is a variant of the test in `../protector-write-lazy.rs`, but with +/// wildcard references. +/// Checks that a protector release access correctly determines that certain tags +/// cannot be children of the protected tag and that it updates them accordingly. +/// +/// For this version we know the tag is not a child because its wildcard root has +/// a smaller tag then the released reference. +pub fn main() { + // We need two locations so that we can create a new reference + // that is foreign to an already active tag. + let mut x: UnsafeCell<[u32; 2]> = UnsafeCell::new([32, 33]); + let ref1 = &mut x; + let cell_ptr = ref1.get() as *mut u32; + + let int = ref1 as *mut UnsafeCell<[u32; 2]> as usize; + let wild = int as *mut UnsafeCell; + + let ref2 = unsafe { &mut *cell_ptr }; + + // `ref3` gets created before the protected ref `arg4`. + let ref3 = unsafe { &mut *wild.wrapping_add(1) }; + + let protect = |arg4: &mut u32| { + // Activates arg4. This would disable ref3 at [0] if it wasn't a cell. + *arg4 = 41; + + // Creates an exposed child of arg4. + let ref5 = &mut *arg4; + let _int = ref5 as *mut u32 as usize; + + // This creates ref6 from ref3 at [1], so that it doesn't disable arg4 at [0]. + let ref6 = unsafe { &mut *ref3.get() }; + + // ┌───────────┐ + // │ ref1* │ + // │ Cel │ Cel │ * + // └─────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌───────────┐ ┌───────────┐ + // │ ref2│ │ │ │ ref3│ + // │ Act │ Res │ │ Cel │ Cel │ + // └─────┬─────┘ └─────┬─────┘ + // │ │ + // │ │ + // ▼ ▼ + // ┌───────────┐ ┌───────────┐ + // │ arg4│ │ │ │ ref6│ + // │ Act │ Res │ │ Res │ Res │ + // └─────┬─────┘ └───────────┘ + // │ + // │ + // ▼ + // ┌───────────┐ + // │ref5*| │ + // │ Res │ Res │ + // └───────────┘ + + // Creates a pointer to [0] with the provenance of ref6. + return (ref6 as *mut u32).wrapping_sub(1); + + // Protector release on arg4 happens here. + // This should cause a foreign write on all foreign nodes, + // unless they could be a child of arg4. + // arg4 has an exposed child, so some tags with a wildcard + // ancestor could be its children. + // However, the root of ref6 was created before arg4, so it + // cannot be a child of it. So it should get disabled + // (at location [0]). + }; + // ptr has provenance of ref6 + let ptr = protect(ref2); + // ref6 is disabled at [0]. + let _fail = unsafe { *ptr }; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release.stderr new file mode 100644 index 000000000000..cd25ef40aad1 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/protector_release.rs:LL:CC + | +LL | let _fail = unsafe { *ptr }; + | ^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/protector_release.rs:LL:CC + | +LL | let ref6 = unsafe { &mut *ref3.get() }; + | ^^^^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a protector release (acting as a foreign write access) on every location previously accessed by this tag + --> tests/fail/tree_borrows/wildcard/protector_release.rs:LL:CC + | +LL | }; + | ^ + = help: this transition corresponds to a loss of read and write permissions + +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/tree_borrows/wildcard/protector_release2.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release2.rs new file mode 100644 index 000000000000..7bef1cb2665e --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release2.rs @@ -0,0 +1,81 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance +use std::cell::UnsafeCell; + +/// This is a variant of the test in `../protector-write-lazy.rs`, but with +/// wildcard references. +/// Checks that a protector release access correctly determines that certain tags +/// cannot be children of the protected tag and that it updates them accordingly. +/// +/// For this version we know the tag is not a child because its wildcard root has +/// a smaller tag then the exposed child of the protected tag. +/// So this test checks that we don't just compare with the accessed tag but instead +/// find the smallest exposed child. +pub fn main() { + // We need two locations so that we can create a new reference + // that is foreign to an already active tag. + let mut x: UnsafeCell<[u32; 2]> = UnsafeCell::new([32, 33]); + let ref1 = &mut x; + let cell_ptr = ref1.get() as *mut u32; + + let int = ref1 as *mut UnsafeCell<[u32; 2]> as usize; + let wild = int as *mut UnsafeCell; + + let ref2 = unsafe { &mut *cell_ptr }; + + let protect = |arg3: &mut u32| { + // `ref4` gets created after the protected ref `arg3` but before the exposed `ref5`. + let ref4 = unsafe { &mut *wild.wrapping_add(1) }; + + // Activates arg4. This would disable ref3 at [0] if it wasn't a cell. + *arg3 = 41; + + // Creates an exposed child of arg3. + let ref5 = &mut *arg3; + let _int = ref5 as *mut u32 as usize; + + // This creates ref6 from ref4 at [1], so that it doesn't disable arg3 at [0]. + let ref6 = unsafe { &mut *ref4.get() }; + + // ┌───────────┐ + // │ ref1* │ + // │ Cel │ Cel │ * + // └─────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌───────────┐ ┌───────────┐ + // │ ref2| │ │ | ref4│ + // │ Act │ Res │ │ Cel │ Cel │ + // └─────┬─────┘ └─────┬─────┘ + // │ │ + // │ │ + // ▼ ▼ + // ┌───────────┐ ┌───────────┐ + // │ arg3| │ │ | ref6│ + // │ Act │ Res │ │ Res │ Res │ + // └─────┬─────┘ └───────────┘ + // │ + // │ + // ▼ + // ┌───────────┐ + // │ref5*| │ + // │ Res │ Res │ + // └───────────┘ + + // Creates a pointer to [0] with the provenance of ref6. + return (ref6 as *mut u32).wrapping_sub(1); + + // Protector release on arg3 happens here. + // This should cause a foreign write on all foreign nodes, + // unless they could be a child of arg3. + // arg3 has an exposed child, so some tags with a wildcard + // ancestor could be its children. + // However, the root of ref6 was created before the exposed + // child ref5, so it cannot be a child of it. So it should + // get disabled (at location [0]). + }; + // ptr has provenance of ref6 + let ptr = protect(ref2); + // ref6 is disabled at [0]. + let _fail = unsafe { *ptr }; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release2.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release2.stderr new file mode 100644 index 000000000000..cd5f42aa0484 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_release2.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/protector_release2.rs:LL:CC + | +LL | let _fail = unsafe { *ptr }; + | ^^^^ 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 has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/protector_release2.rs:LL:CC + | +LL | let ref6 = unsafe { &mut *ref4.get() }; + | ^^^^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a protector release (acting as a foreign write access) on every location previously accessed by this tag + --> tests/fail/tree_borrows/wildcard/protector_release2.rs:LL:CC + | +LL | }; + | ^ + = help: this transition corresponds to a loss of read and write permissions + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From 9f7dc2e474081a2a79c756abddf4dc367cc1d8cf Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sun, 21 Dec 2025 20:49:36 +0000 Subject: [PATCH 1231/3801] Extract version check from ensure_version_or_cargo_install Define a new function ensure_version which is extracted (and modified) from ensure_version_or_cargo_install. --- src/tools/tidy/src/lib.rs | 47 ++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 756f9790e04a..1bbea81ff0fb 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -158,6 +158,27 @@ pub fn files_modified(ci_info: &CiInfo, pred: impl Fn(&str) -> bool) -> bool { !v.is_empty() } +/// Check if the given executable is installed and the version is expected. +pub fn ensure_version(build_dir: &Path, bin_name: &str, version: &str) -> io::Result { + let bin_path = build_dir.join("misc-tools").join("bin").join(bin_name); + + match Command::new(&bin_path).arg("--version").output() { + Ok(output) => { + let Some(v) = str::from_utf8(&output.stdout).unwrap().trim().split_whitespace().last() else { + return Err(io::Error::other("version check failed")); + }; + + if v != version { + eprintln!( + "warning: the tool `{bin_name}` is detected, but version {v} doesn't match with the expected version {version}" + ); + } + Ok(bin_path) + } + Err(e) => Err(e), + } +} + /// If the given executable is installed with the given version, use that, /// otherwise install via cargo. pub fn ensure_version_or_cargo_install( @@ -167,30 +188,16 @@ pub fn ensure_version_or_cargo_install( bin_name: &str, version: &str, ) -> io::Result { + if let Ok(bin_path) = ensure_version(build_dir, bin_name, version) { + return Ok(bin_path); + } + + eprintln!("building external tool {bin_name} from package {pkg_name}@{version}"); + let tool_root_dir = build_dir.join("misc-tools"); let tool_bin_dir = tool_root_dir.join("bin"); let bin_path = tool_bin_dir.join(bin_name).with_extension(env::consts::EXE_EXTENSION); - // ignore the process exit code here and instead just let the version number check fail. - // we also importantly don't return if the program wasn't installed, - // instead we want to continue to the fallback. - 'ck: { - // FIXME: rewrite as if-let chain once this crate is 2024 edition. - let Ok(output) = Command::new(&bin_path).arg("--version").output() else { - break 'ck; - }; - let Ok(s) = str::from_utf8(&output.stdout) else { - break 'ck; - }; - let Some(v) = s.trim().split_whitespace().last() else { - break 'ck; - }; - if v == version { - return Ok(bin_path); - } - } - - eprintln!("building external tool {bin_name} from package {pkg_name}@{version}"); // use --force to ensure that if the required version is bumped, we update it. // use --target-dir to ensure we have a build cache so repeated invocations aren't slow. // modify PATH so that cargo doesn't print a warning telling the user to modify the path. From b305a98349e2d661bc6169b33cdc1699557de8df Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Sun, 21 Dec 2025 20:49:41 +0000 Subject: [PATCH 1232/3801] implpement if_installed for spellcheck for other extra checks, it is WIP. --- src/tools/tidy/src/extra_checks/mod.rs | 65 ++++++++++++++++++++++---- src/tools/tidy/src/lib.rs | 3 +- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index a45af7fcf158..1304de16874d 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -23,8 +23,8 @@ use std::process::Command; use std::str::FromStr; use std::{fmt, fs, io}; -use crate::CiInfo; use crate::diagnostics::TidyCtx; +use crate::{CiInfo, ensure_version}; mod rustdoc_js; @@ -43,6 +43,7 @@ const RUFF_CACHE_PATH: &[&str] = &["cache", "ruff_cache"]; const PIP_REQ_PATH: &[&str] = &["src", "tools", "tidy", "config", "requirements.txt"]; const SPELLCHECK_DIRS: &[&str] = &["compiler", "library", "src/bootstrap", "src/librustdoc"]; +const SPELLCHECK_VER: &str = "1.38.1"; pub fn check( root_path: &Path, @@ -120,6 +121,9 @@ fn check_impl( ck.is_non_auto_or_matches(path) }); } + if lint_args.iter().any(|ck| ck.if_installed) { + lint_args.retain(|ck| ck.is_non_if_installed_or_matches(outdir)); + } macro_rules! extra_check { ($lang:ident, $kind:ident) => { @@ -620,8 +624,13 @@ fn spellcheck_runner( cargo: &Path, args: &[&str], ) -> Result<(), Error> { - let bin_path = - crate::ensure_version_or_cargo_install(outdir, cargo, "typos-cli", "typos", "1.38.1")?; + let bin_path = crate::ensure_version_or_cargo_install( + outdir, + cargo, + "typos-cli", + "typos", + SPELLCHECK_VER, + )?; match Command::new(bin_path).current_dir(src_root).args(args).status() { Ok(status) => { if status.success() { @@ -736,10 +745,14 @@ enum ExtraCheckParseError { Empty, /// `auto` specified without lang part. AutoRequiresLang, + /// `if-installed` specified without lang part. + IfInsatlledRequiresLang, } struct ExtraCheckArg { auto: bool, + /// Only run the check if the requisite software is already installed. + if_installed: bool, lang: ExtraCheckLang, /// None = run all extra checks for the given lang kind: Option, @@ -750,6 +763,19 @@ impl ExtraCheckArg { self.lang == lang && self.kind.map(|k| k == kind).unwrap_or(true) } + fn is_non_if_installed_or_matches(&self, build_dir: &Path) -> bool { + if !self.if_installed { + return true; + } + + match self.lang { + ExtraCheckLang::Spellcheck => { + ensure_version(build_dir, "typos", SPELLCHECK_VER).is_ok() + } + _ => todo!("implement other checks"), + } + } + /// Returns `false` if this is an auto arg and the passed filename does not trigger the auto rule fn is_non_auto_or_matches(&self, filepath: &str) -> bool { if !self.auto { @@ -792,22 +818,41 @@ impl FromStr for ExtraCheckArg { fn from_str(s: &str) -> Result { let mut auto = false; + let mut if_installed = false; let mut parts = s.split(':'); let Some(mut first) = parts.next() else { return Err(ExtraCheckParseError::Empty); }; - if first == "auto" { - let Some(part) = parts.next() else { - return Err(ExtraCheckParseError::AutoRequiresLang); - }; - auto = true; - first = part; + loop { + if !auto && first == "auto" { + let Some(part) = parts.next() else { + return Err(ExtraCheckParseError::AutoRequiresLang); + }; + auto = true; + first = part; + continue; + } + + if !if_installed && first == "if-installed" { + let Some(part) = parts.next() else { + return Err(ExtraCheckParseError::IfInsatlledRequiresLang); + }; + if_installed = true; + first = part; + continue; + } + break; } let second = parts.next(); if parts.next().is_some() { return Err(ExtraCheckParseError::TooManyParts); } - let arg = Self { auto, lang: first.parse()?, kind: second.map(|s| s.parse()).transpose()? }; + let arg = Self { + auto, + if_installed, + lang: first.parse()?, + kind: second.map(|s| s.parse()).transpose()?, + }; if !arg.has_supported_kind() { return Err(ExtraCheckParseError::UnsupportedKindForLang); } diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 1bbea81ff0fb..62da0191da9e 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -164,7 +164,8 @@ pub fn ensure_version(build_dir: &Path, bin_name: &str, version: &str) -> io::Re match Command::new(&bin_path).arg("--version").output() { Ok(output) => { - let Some(v) = str::from_utf8(&output.stdout).unwrap().trim().split_whitespace().last() else { + let Some(v) = str::from_utf8(&output.stdout).unwrap().trim().split_whitespace().last() + else { return Err(io::Error::other("version check failed")); }; From 053597f464e2c35b6549b0ced021a06894724295 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 25 Dec 2025 12:27:17 +0000 Subject: [PATCH 1233/3801] add several older crashtests --- tests/crashes/114880.rs | 7 +++++++ tests/crashes/119940.rs | 27 +++++++++++++++++++++++++++ tests/crashes/138274.rs | 18 ++++++++++++++++++ tests/crashes/138660.rs | 7 +++++++ tests/crashes/auxiliary/aux114880.rs | 13 +++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 tests/crashes/114880.rs create mode 100644 tests/crashes/119940.rs create mode 100644 tests/crashes/138274.rs create mode 100644 tests/crashes/138660.rs create mode 100644 tests/crashes/auxiliary/aux114880.rs diff --git a/tests/crashes/114880.rs b/tests/crashes/114880.rs new file mode 100644 index 000000000000..c05f7ed4ff64 --- /dev/null +++ b/tests/crashes/114880.rs @@ -0,0 +1,7 @@ +//@ known-bug: #114880 +//@ proc-macro: aux114880.rs +//@ ignore-backends: gcc + +aux114880::expand!(); + +fn main() {} diff --git a/tests/crashes/119940.rs b/tests/crashes/119940.rs new file mode 100644 index 000000000000..af259b023c94 --- /dev/null +++ b/tests/crashes/119940.rs @@ -0,0 +1,27 @@ +//@ known-bug: #119940 +//@ compile-flags: -Zvalidate-mir + +#![feature(custom_mir, core_intrinsics)] +extern crate core; +use core::intrinsics::mir::*; + +pub enum E { + V0 { fld0: &'static u64 }, +} + +#[custom_mir(dialect = "runtime", phase = "initial")] +pub fn fn0() { + mir! { + let e: E; + let n: u64; + { + n = 0; + place!(Field::<&u64>(Variant(e, 0), 0)) = &n; + Return() + } + + } +} +pub fn main() { + fn0(); +} diff --git a/tests/crashes/138274.rs b/tests/crashes/138274.rs new file mode 100644 index 000000000000..d657b27e46f3 --- /dev/null +++ b/tests/crashes/138274.rs @@ -0,0 +1,18 @@ +//@ known-bug: #138274 +//@ edition: 2021 +//@ compile-flags: --crate-type=lib +trait Trait {} + +fn foo() -> Box { + todo!() +} + +fn fetch() { + async { + let fut = async { + let _x = foo(); + async {}.await; + }; + let _: Box = Box::new(fut); + }; +} diff --git a/tests/crashes/138660.rs b/tests/crashes/138660.rs new file mode 100644 index 000000000000..90eb8026f072 --- /dev/null +++ b/tests/crashes/138660.rs @@ -0,0 +1,7 @@ +//@ known-bug: #138660 +enum A { + V1(isize) = 1..=10, + V0 = 1..=10, +} +const B: &'static [A] = &[A::V0, A::V1(111)]; +fn main() {} diff --git a/tests/crashes/auxiliary/aux114880.rs b/tests/crashes/auxiliary/aux114880.rs new file mode 100644 index 000000000000..244396fdd9ef --- /dev/null +++ b/tests/crashes/auxiliary/aux114880.rs @@ -0,0 +1,13 @@ +#![feature(proc_macro_expand)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use std::str::FromStr; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn expand(_: TokenStream) -> TokenStream { + dbg!(TokenStream::from_str("include!(\"./doesnt_exist\")").unwrap().expand_expr()) + .unwrap_or_default() +} From fc6df9cec751da81c2b76b9a7f2647a93800a246 Mon Sep 17 00:00:00 2001 From: maradini77 <140460067+maradini77@users.noreply.github.com> Date: Thu, 25 Dec 2025 11:24:20 +0100 Subject: [PATCH 1234/3801] fix: typos and grammar errors in README files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix `FIMXE`/`FXIME` typos → `FIXME` - fix grammar: `these terminology are` → `this terminology is` - fix apostrophe: `it's data` → `its data` - remove duplicate word: `less less` → `less` --- src/tools/rust-installer/README.md | 2 +- src/tools/test-float-parse/README.md | 2 +- tests/ui/README.md | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-installer/README.md b/src/tools/rust-installer/README.md index 505ffe4093fc..1f71d45a434c 100644 --- a/src/tools/rust-installer/README.md +++ b/src/tools/rust-installer/README.md @@ -49,7 +49,7 @@ To combine installers. # Future work -* Make install.sh not have to be customized, pull it's data from a +* Make install.sh not have to be customized, pull its data from a config file. * Be more resilient to installation failures, particularly if the disk is full. diff --git a/src/tools/test-float-parse/README.md b/src/tools/test-float-parse/README.md index 5e2c43d1cad6..ac9cbe5d28a2 100644 --- a/src/tools/test-float-parse/README.md +++ b/src/tools/test-float-parse/README.md @@ -36,7 +36,7 @@ For each test case, the following is done: representation with infinite precision. - The rational value then gets checked that it is within the float's representable values (absolute value greater than the smallest number to round - to zero, but less less than the first value to round to infinity). If these + to zero, but less than the first value to round to infinity). If these limits are exceeded, check that the parsed float reflects that. - For real nonzero numbers, the parsed float is converted into a rational using `significand * 2^exponent`. It is then checked against the actual rational diff --git a/tests/ui/README.md b/tests/ui/README.md index da9be2e209ac..b1c813cce93f 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -328,7 +328,7 @@ Tests for crate resolution and loading behavior, including `extern crate` declar ## `tests/ui/cross/`: Various tests related to the concept of "cross" -**FIXME**: The unifying topic of these tests appears to be that their filenames begin with the word "cross". The similarities end there - one test is about "cross-borrowing" a `Box` into `&T`, while another is about a global trait used "across" files. Some of these terminology are really outdated and does not match the current terminology. Additionally, "cross" is also way too generic, it's easy to confuse with cross-compile. +**FIXME**: The unifying topic of these tests appears to be that their filenames begin with the word "cross". The similarities end there - one test is about "cross-borrowing" a `Box` into `&T`, while another is about a global trait used "across" files. Some of this terminology is really outdated and does not match the current terminology. Additionally, "cross" is also way too generic, it's easy to confuse with cross-compile. ## `tests/ui/cross-crate/`: Cross-Crate Interaction @@ -911,7 +911,7 @@ Something is missing which could be added to fix (e.g. suggestions). Tests for checking missing trait bounds, and their diagnostics. -**FIMXE**: Maybe a subdirectory of `ui/trait-bounds` would be more appropriate. +**FIXME**: Maybe a subdirectory of `ui/trait-bounds` would be more appropriate. ## `tests/ui/modules/` @@ -957,7 +957,7 @@ Despite the size of the directory, this is a single test, spawning a sprawling ` A very similar principle as `non_modrs_mods`, but with an added inline `mod` statement inside another `mod`'s code block. -**FXIME**: Consider merge with `tests/ui/modules/`, keeping the directory structure. +**FIXME**: Consider merge with `tests/ui/modules/`, keeping the directory structure. ## `tests/ui/no_std/` From 2c7bd6d46206b5477a26c1b98b2ac09cfa9cb07b Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 25 Dec 2025 15:44:56 +0200 Subject: [PATCH 1235/3801] Store closures with "tupled" inputs And remove it when needed, the opposite of what was previously, where we stored without a tuple and tupled for the solver (because it requires that). Because this is what rustc does, and generally, the closer we follow rustc, the easier our lives become. The weird name `signature_unclosure()` also comes from rustc. --- .../crates/hir-ty/src/display.rs | 53 ++++++++--------- .../crates/hir-ty/src/infer/closure.rs | 11 +++- .../hir-ty/src/infer/closure/analysis.rs | 4 +- .../crates/hir-ty/src/infer/coerce.rs | 38 +++++++----- .../rust-analyzer/crates/hir-ty/src/layout.rs | 10 ++-- .../crates/hir-ty/src/mir/borrowck.rs | 3 +- .../crates/hir-ty/src/mir/eval.rs | 6 +- .../crates/hir-ty/src/mir/lower.rs | 9 +-- .../hir-ty/src/next_solver/generic_arg.rs | 58 ++----------------- .../crates/hir-ty/src/next_solver/ty.rs | 27 +++++++-- 10 files changed, 99 insertions(+), 120 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index b9e23464e980..0f989d6c5851 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -1383,37 +1383,30 @@ impl<'db> HirDisplay<'db> for Ty<'db> { } _ => (), } - let sig = substs - .split_closure_args_untupled() - .closure_sig_as_fn_ptr_ty - .callable_sig(interner); - if let Some(sig) = sig { - let sig = sig.skip_binder(); - let InternedClosure(def, _) = db.lookup_intern_closure(id); - let infer = InferenceResult::for_body(db, def); - let (_, kind) = infer.closure_info(id); - match f.closure_style { - ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?, - ClosureStyle::RANotation => write!(f, "|")?, - _ => unreachable!(), - } - if sig.inputs().is_empty() { - } else if f.should_truncate() { - write!(f, "{TYPE_HINT_TRUNCATION}")?; - } else { - f.write_joined(sig.inputs(), ", ")?; - }; - match f.closure_style { - ClosureStyle::ImplFn => write!(f, ")")?, - ClosureStyle::RANotation => write!(f, "|")?, - _ => unreachable!(), - } - if f.closure_style == ClosureStyle::RANotation || !sig.output().is_unit() { - write!(f, " -> ")?; - sig.output().hir_fmt(f)?; - } + let sig = interner.signature_unclosure(substs.as_closure().sig(), Safety::Safe); + let sig = sig.skip_binder(); + let InternedClosure(def, _) = db.lookup_intern_closure(id); + let infer = InferenceResult::for_body(db, def); + let (_, kind) = infer.closure_info(id); + match f.closure_style { + ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?, + ClosureStyle::RANotation => write!(f, "|")?, + _ => unreachable!(), + } + if sig.inputs().is_empty() { + } else if f.should_truncate() { + write!(f, "{TYPE_HINT_TRUNCATION}")?; } else { - write!(f, "{{closure}}")?; + f.write_joined(sig.inputs(), ", ")?; + }; + match f.closure_style { + ClosureStyle::ImplFn => write!(f, ")")?, + ClosureStyle::RANotation => write!(f, "|")?, + _ => unreachable!(), + } + if f.closure_style == ClosureStyle::RANotation || !sig.output().is_unit() { + write!(f, " -> ")?; + sig.output().hir_fmt(f)?; } } TyKind::CoroutineClosure(id, args) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index 19ffa3a9398a..d1391ad24e4d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -68,7 +68,6 @@ impl<'db> InferenceContext<'_, 'db> { let ClosureSignatures { bound_sig, liberated_sig } = self.sig_of_closure(arg_types, ret_type, expected_sig); let body_ret_ty = bound_sig.output().skip_binder(); - let sig_ty = Ty::new_fn_ptr(interner, bound_sig); let parent_args = GenericArgs::identity_for_item(interner, self.generic_def.into()); // FIXME: Make this an infer var and infer it later. @@ -117,6 +116,16 @@ impl<'db> InferenceContext<'_, 'db> { } None => {} }; + let sig = bound_sig.map_bound(|sig| { + interner.mk_fn_sig( + [Ty::new_tup(interner, sig.inputs())], + sig.output(), + sig.c_variadic, + sig.safety, + sig.abi, + ) + }); + let sig_ty = Ty::new_fn_ptr(interner, sig); // FIXME: Infer the kind later if needed. let parts = ClosureArgsParts { parent_args: parent_args.as_slice(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs index 5b0360071d9d..6ae6f7552502 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure/analysis.rs @@ -15,7 +15,7 @@ use hir_def::{ }; use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; -use rustc_type_ir::inherent::{IntoKind, Ty as _}; +use rustc_type_ir::inherent::{GenericArgs as _, IntoKind, Ty as _}; use smallvec::{SmallVec, smallvec}; use stdx::{format_to, never}; use syntax::utils::is_raw_identifier; @@ -103,7 +103,7 @@ impl CapturedItem { pub fn ty<'db>(&self, db: &'db dyn HirDatabase, subst: GenericArgs<'db>) -> Ty<'db> { let interner = DbInterner::new_no_crate(db); - self.ty.get().instantiate(interner, subst.split_closure_args_untupled().parent_args) + self.ty.get().instantiate(interner, subst.as_closure().parent_args()) } pub fn kind(&self) -> CaptureKind { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs index bb9cb1c1ca09..ec7dad0fa08c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/coerce.rs @@ -46,7 +46,9 @@ use rustc_type_ir::{ BoundVar, DebruijnIndex, TyVid, TypeAndMut, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, error::TypeError, - inherent::{Const as _, GenericArg as _, IntoKind, Safety, SliceLike, Ty as _}, + inherent::{ + Const as _, GenericArg as _, GenericArgs as _, IntoKind, Safety as _, SliceLike, Ty as _, + }, }; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; @@ -63,6 +65,7 @@ use crate::{ Canonical, ClauseKind, CoercePredicate, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, PolyFnSig, PredicateKind, Region, RegionKind, TraitRef, Ty, TyKind, TypingMode, + abi::Safety, infer::{ DbInternerInferExt, InferCtxt, InferOk, InferResult, relate::RelateResult, @@ -921,10 +924,8 @@ where // or // `unsafe fn(arg0,arg1,...) -> _` let safety = hdr.safety; - let closure_sig = args_a.closure_sig_untupled().map_bound(|mut sig| { - sig.safety = hdr.safety; - sig - }); + let closure_sig = + self.interner().signature_unclosure(args_a.as_closure().sig(), safety); let pointer_ty = Ty::new_fn_ptr(self.interner(), closure_sig); debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})", a, b, pointer_ty); self.unify_and( @@ -1125,23 +1126,28 @@ impl<'db> InferenceContext<'_, 'db> { } (TyKind::Closure(_, args), TyKind::FnDef(..)) => { let b_sig = new_ty.fn_sig(self.table.interner()); - let a_sig = args.closure_sig_untupled().map_bound(|mut sig| { - sig.safety = b_sig.safety(); - sig - }); + let a_sig = self + .interner() + .signature_unclosure(args.as_closure().sig(), b_sig.safety()); (Some(a_sig), Some(b_sig)) } (TyKind::FnDef(..), TyKind::Closure(_, args)) => { let a_sig = prev_ty.fn_sig(self.table.interner()); - let b_sig = args.closure_sig_untupled().map_bound(|mut sig| { - sig.safety = a_sig.safety(); - sig - }); + let b_sig = self + .interner() + .signature_unclosure(args.as_closure().sig(), a_sig.safety()); (Some(a_sig), Some(b_sig)) } - (TyKind::Closure(_, args_a), TyKind::Closure(_, args_b)) => { - (Some(args_a.closure_sig_untupled()), Some(args_b.closure_sig_untupled())) - } + (TyKind::Closure(_, args_a), TyKind::Closure(_, args_b)) => ( + Some( + self.interner() + .signature_unclosure(args_a.as_closure().sig(), Safety::Safe), + ), + Some( + self.interner() + .signature_unclosure(args_b.as_closure().sig(), Safety::Safe), + ), + ), _ => (None, None), } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index b6ad3624ae28..525100439f5b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -14,7 +14,10 @@ use rustc_abi::{ TargetDataLayout, WrappingRange, }; use rustc_index::IndexVec; -use rustc_type_ir::{FloatTy, IntTy, UintTy, inherent::IntoKind}; +use rustc_type_ir::{ + FloatTy, IntTy, UintTy, + inherent::{GenericArgs as _, IntoKind}, +}; use triomphe::Arc; use crate::{ @@ -335,10 +338,7 @@ pub fn layout_of_ty_query( let fields = captures .iter() .map(|it| { - let ty = it - .ty - .get() - .instantiate(interner, args.split_closure_args_untupled().parent_args); + let ty = it.ty.get().instantiate(interner, args.as_closure().parent_args()); db.layout_of_ty(ty.store(), trait_env.clone()) }) .collect::, _>>()?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs index 941b6c75bfe7..dece61a57df5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs @@ -8,6 +8,7 @@ use std::iter; use hir_def::{DefWithBodyId, HasModule}; use la_arena::ArenaMap; use rustc_hash::FxHashMap; +use rustc_type_ir::inherent::GenericArgs as _; use stdx::never; use triomphe::Arc; @@ -123,7 +124,7 @@ fn make_fetch_closure_field<'db>( let InternedClosure(def, _) = db.lookup_intern_closure(c); let infer = InferenceResult::for_body(db, def); let (captures, _) = infer.closure_info(c); - let parent_subst = subst.split_closure_args_untupled().parent_args; + let parent_subst = subst.as_closure().parent_args(); let interner = DbInterner::new_no_crate(db); captures.get(f).expect("broken closure field").ty.get().instantiate(interner, parent_subst) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index c7156bb11ed6..2d1368858bcf 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -27,7 +27,7 @@ use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; use rustc_type_ir::{ AliasTyKind, - inherent::{AdtDef, IntoKind, Region as _, SliceLike, Ty as _}, + inherent::{AdtDef, GenericArgs as _, IntoKind, Region as _, SliceLike, Ty as _}, }; use span::FileId; use stdx::never; @@ -731,7 +731,7 @@ impl<'db> Evaluator<'db> { let InternedClosure(def, _) = self.db.lookup_intern_closure(c); let infer = InferenceResult::for_body(self.db, def); let (captures, _) = infer.closure_info(c); - let parent_subst = subst.split_closure_args_untupled().parent_args; + let parent_subst = subst.as_closure().parent_args(); captures .get(f) .expect("broken closure field") @@ -2771,7 +2771,7 @@ impl<'db> Evaluator<'db> { TyKind::Closure(closure, subst) => self.exec_closure( closure.0, func_data, - GenericArgs::new_from_slice(subst.split_closure_args_untupled().parent_args), + GenericArgs::new_from_slice(subst.as_closure().parent_args()), destination, &args[1..], locals, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index e8d42bed9fa7..762f91fb0d99 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -19,7 +19,7 @@ use hir_expand::name::Name; use la_arena::ArenaMap; use rustc_apfloat::Float; use rustc_hash::FxHashMap; -use rustc_type_ir::inherent::{Const as _, IntoKind, Ty as _}; +use rustc_type_ir::inherent::{Const as _, GenericArgs as _, IntoKind, Ty as _}; use span::{Edition, FileId}; use syntax::TextRange; use triomphe::Arc; @@ -44,6 +44,7 @@ use crate::{ next_solver::{ Const, DbInterner, ParamConst, ParamEnv, Region, StoredGenericArgs, StoredTy, TyKind, TypingMode, UnevaluatedConst, + abi::Safety, infer::{DbInternerInferExt, InferCtxt}, }, traits::FnTrait, @@ -2138,11 +2139,7 @@ pub fn mir_body_for_closure_query<'db>( .store(), }); ctx.result.param_locals.push(closure_local); - let Some(sig) = - substs.split_closure_args_untupled().closure_sig_as_fn_ptr_ty.callable_sig(ctx.interner()) - else { - implementation_error!("closure has not callable sig"); - }; + let sig = ctx.interner().signature_unclosure(substs.as_closure().sig(), Safety::Safe); let resolver_guard = ctx.resolver.update_to_inner_scope(db, owner, expr); let current = ctx.lower_params_and_bindings( args.iter().zip(sig.skip_binder().inputs().iter()).map(|(it, y)| (*it, *y)), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs index 9936e443210a..72cf2f9f07f2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generic_arg.rs @@ -11,9 +11,9 @@ use std::{hint::unreachable_unchecked, marker::PhantomData, ptr::NonNull}; use hir_def::{GenericDefId, GenericParamId}; use intern::InternedRef; use rustc_type_ir::{ - ClosureArgs, ConstVid, CoroutineArgs, CoroutineClosureArgs, FallibleTypeFolder, FnSigTys, - GenericTypeVisitable, Interner, TyKind, TyVid, TypeFoldable, TypeFolder, TypeVisitable, - TypeVisitor, Variance, + ClosureArgs, ConstVid, CoroutineArgs, CoroutineClosureArgs, FallibleTypeFolder, + GenericTypeVisitable, Interner, TyVid, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, + Variance, inherent::{GenericArg as _, GenericsOf, IntoKind, SliceLike, Term as _, Ty as _}, relate::{Relate, VarianceDiagInfo}, walk::TypeWalker, @@ -21,12 +21,11 @@ use rustc_type_ir::{ use smallvec::SmallVec; use crate::next_solver::{ - ConstInterned, PolyFnSig, RegionInterned, TyInterned, impl_foldable_for_interned_slice, - interned_slice, + ConstInterned, RegionInterned, TyInterned, impl_foldable_for_interned_slice, interned_slice, }; use super::{ - Const, DbInterner, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, SolverDefId, Ty, Tys, + Const, DbInterner, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, SolverDefId, Ty, generics::Generics, }; @@ -566,33 +565,6 @@ impl<'db> GenericArgs<'db> { } } - pub fn closure_sig_untupled(self) -> PolyFnSig<'db> { - let TyKind::FnPtr(inputs_and_output, hdr) = - self.split_closure_args_untupled().closure_sig_as_fn_ptr_ty.kind() - else { - unreachable!("not a function pointer") - }; - inputs_and_output.with(hdr) - } - - /// A "sensible" `.split_closure_args()`, where the arguments are not in a tuple. - pub fn split_closure_args_untupled(self) -> rustc_type_ir::ClosureArgsParts> { - // FIXME: should use `ClosureSubst` when possible - match self.as_slice() { - [parent_args @ .., closure_kind_ty, sig_ty, tupled_upvars_ty] => { - rustc_type_ir::ClosureArgsParts { - parent_args, - closure_sig_as_fn_ptr_ty: sig_ty.expect_ty(), - closure_kind_ty: closure_kind_ty.expect_ty(), - tupled_upvars_ty: tupled_upvars_ty.expect_ty(), - } - } - _ => { - unreachable!("unexpected closure sig"); - } - } - } - pub fn types(self) -> impl Iterator> { self.iter().filter_map(|it| it.as_type()) } @@ -688,27 +660,9 @@ impl<'db> rustc_type_ir::inherent::GenericArgs> for GenericArgs< // FIXME: should use `ClosureSubst` when possible match self.as_slice() { [parent_args @ .., closure_kind_ty, sig_ty, tupled_upvars_ty] => { - let interner = DbInterner::conjure(); - // This is stupid, but the next solver expects the first input to actually be a tuple - let sig_ty = match sig_ty.expect_ty().kind() { - TyKind::FnPtr(sig_tys, header) => Ty::new( - interner, - TyKind::FnPtr( - sig_tys.map_bound(|s| { - let inputs = Ty::new_tup(interner, s.inputs()); - let output = s.output(); - FnSigTys { - inputs_and_output: Tys::new_from_slice(&[inputs, output]), - } - }), - header, - ), - ), - _ => unreachable!("sig_ty should be last"), - }; rustc_type_ir::ClosureArgsParts { parent_args, - closure_sig_as_fn_ptr_ty: sig_ty, + closure_sig_as_fn_ptr_ty: sig_ty.expect_ty(), closure_kind_ty: closure_kind_ty.expect_ty(), tupled_upvars_ty: tupled_upvars_ty.expect_ty(), } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs index c89831bd4077..030ba37015f2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs @@ -26,6 +26,7 @@ use rustc_type_ir::{ }; use crate::{ + FnAbi, db::{HirDatabase, InternedCoroutine}, lower::GenericPredicates, next_solver::{ @@ -495,10 +496,9 @@ impl<'db> Ty<'db> { Some(interner.fn_sig(callable).instantiate(interner, args)) } TyKind::FnPtr(sig, hdr) => Some(sig.with(hdr)), - TyKind::Closure(_, closure_args) => closure_args - .split_closure_args_untupled() - .closure_sig_as_fn_ptr_ty - .callable_sig(interner), + TyKind::Closure(_, closure_args) => { + Some(interner.signature_unclosure(closure_args.as_closure().sig(), Safety::Safe)) + } TyKind::CoroutineClosure(coroutine_id, args) => { Some(args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| { let unit_ty = Ty::new_unit(interner); @@ -1426,3 +1426,22 @@ impl<'db> PlaceholderLike> for PlaceholderTy { Placeholder { universe: ui, bound: BoundTy { var, kind: BoundTyKind::Anon } } } } + +impl<'db> DbInterner<'db> { + /// Given a closure signature, returns an equivalent fn signature. Detuples + /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then + /// you would get a `fn(u32, i32)`. + /// `unsafety` determines the unsafety of the fn signature. If you pass + /// `Safety::Unsafe` in the previous example, then you would get + /// an `unsafe fn (u32, i32)`. + /// It cannot convert a closure that requires unsafe. + pub fn signature_unclosure(self, sig: PolyFnSig<'db>, safety: Safety) -> PolyFnSig<'db> { + sig.map_bound(|s| { + let params = match s.inputs()[0].kind() { + TyKind::Tuple(params) => params, + _ => panic!(), + }; + self.mk_fn_sig(params, s.output(), s.c_variadic, safety, FnAbi::Rust) + }) + } +} From ebb0d0b7bd58510f6dd2bc21d411f5aec3116040 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 2 Dec 2025 13:54:28 +0200 Subject: [PATCH 1236/3801] Make builtin derives cheaper, by not really expanding them, instead store them unexpanded --- .../rust-analyzer/crates/hir-def/src/attrs.rs | 2 + .../crates/hir-def/src/builtin_derive.rs | 61 ++ .../crates/hir-def/src/item_scope.rs | 15 +- .../crates/hir-def/src/lang_item.rs | 51 +- .../rust-analyzer/crates/hir-def/src/lib.rs | 29 + .../crates/hir-def/src/nameres/collector.rs | 213 +++++-- .../hir-def/src/nameres/tests/macros.rs | 8 +- .../hir-expand/src/builtin/derive_macro.rs | 5 +- .../crates/hir-ty/src/builtin_derive.rs | 575 ++++++++++++++++++ .../rust-analyzer/crates/hir-ty/src/drop.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/lib.rs | 1 + .../rust-analyzer/crates/hir-ty/src/lower.rs | 7 + .../crates/hir-ty/src/method_resolution.rs | 54 +- .../hir-ty/src/method_resolution/probe.rs | 6 +- .../crates/hir-ty/src/next_solver/def_id.rs | 74 ++- .../crates/hir-ty/src/next_solver/generics.rs | 18 +- .../hir-ty/src/next_solver/infer/select.rs | 8 +- .../crates/hir-ty/src/next_solver/interner.rs | 113 ++-- .../crates/hir-ty/src/next_solver/solver.rs | 10 +- .../crates/hir-ty/src/tests/incremental.rs | 40 +- .../crates/intern/src/symbol/symbols.rs | 2 + 21 files changed, 1143 insertions(+), 151 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs create mode 100644 src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs index 34a9230794d1..e91d72a701cf 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs @@ -188,6 +188,7 @@ fn match_attr_flags(attr_flags: &mut AttrFlags, attr: Meta) -> ControlFlow attr_flags.insert(AttrFlags::IS_DEPRECATED), "macro_export" => attr_flags.insert(AttrFlags::IS_MACRO_EXPORT), "no_mangle" => attr_flags.insert(AttrFlags::NO_MANGLE), + "pointee" => attr_flags.insert(AttrFlags::IS_POINTEE), "non_exhaustive" => attr_flags.insert(AttrFlags::NON_EXHAUSTIVE), "ignore" => attr_flags.insert(AttrFlags::IS_IGNORE), "bench" => attr_flags.insert(AttrFlags::IS_BENCH), @@ -289,6 +290,7 @@ bitflags::bitflags! { const RUSTC_PAREN_SUGAR = 1 << 42; const RUSTC_COINDUCTIVE = 1 << 43; const RUSTC_FORCE_INLINE = 1 << 44; + const IS_POINTEE = 1 << 45; } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs new file mode 100644 index 000000000000..e0e163783f43 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs @@ -0,0 +1,61 @@ +//! Definition of builtin derive impls. +//! +//! To save time and memory, builtin derives are not really expanded. Instead, we record them +//! and create their impls based on lowered data, see crates/hir-ty/src/builtin_derive.rs. + +use hir_expand::builtin::BuiltinDeriveExpander; + +macro_rules! declare_enum { + ( $( $trait:ident ),* $(,)? ) => { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum BuiltinDeriveImplTrait { + $( $trait, )* + } + + impl BuiltinDeriveImplTrait { + #[inline] + pub fn get_id(self, lang_items: &crate::lang_item::LangItems) -> Option { + match self { + $( Self::$trait => lang_items.$trait, )* + } + } + } + }; +} + +declare_enum!( + Copy, + Clone, + Default, + Debug, + Hash, + Ord, + PartialOrd, + Eq, + PartialEq, + CoerceUnsized, + DispatchFromDyn, +); + +pub(crate) fn with_derive_traits( + derive: BuiltinDeriveExpander, + mut f: impl FnMut(BuiltinDeriveImplTrait), +) { + let trait_ = match derive { + BuiltinDeriveExpander::Copy => BuiltinDeriveImplTrait::Copy, + BuiltinDeriveExpander::Clone => BuiltinDeriveImplTrait::Clone, + BuiltinDeriveExpander::Default => BuiltinDeriveImplTrait::Default, + BuiltinDeriveExpander::Debug => BuiltinDeriveImplTrait::Debug, + BuiltinDeriveExpander::Hash => BuiltinDeriveImplTrait::Hash, + BuiltinDeriveExpander::Ord => BuiltinDeriveImplTrait::Ord, + BuiltinDeriveExpander::PartialOrd => BuiltinDeriveImplTrait::PartialOrd, + BuiltinDeriveExpander::Eq => BuiltinDeriveImplTrait::Eq, + BuiltinDeriveExpander::PartialEq => BuiltinDeriveImplTrait::PartialEq, + BuiltinDeriveExpander::CoercePointee => { + f(BuiltinDeriveImplTrait::CoerceUnsized); + f(BuiltinDeriveImplTrait::DispatchFromDyn); + return; + } + }; + f(trait_); +} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index 3ffeebfaf2c9..4f3700e8e41c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -16,8 +16,8 @@ use syntax::ast; use thin_vec::ThinVec; use crate::{ - AdtId, BuiltinType, ConstId, ExternBlockId, ExternCrateId, FxIndexMap, HasModule, ImplId, - Lookup, MacroCallStyles, MacroId, ModuleDefId, ModuleId, TraitId, UseId, + AdtId, BuiltinDeriveImplId, BuiltinType, ConstId, ExternBlockId, ExternCrateId, FxIndexMap, + HasModule, ImplId, Lookup, MacroCallStyles, MacroId, ModuleDefId, ModuleId, TraitId, UseId, db::DefDatabase, per_ns::{Item, MacrosItem, PerNs, TypesItem, ValuesItem}, visibility::Visibility, @@ -159,6 +159,7 @@ pub struct ItemScope { declarations: ThinVec, impls: ThinVec, + builtin_derive_impls: ThinVec, extern_blocks: ThinVec, unnamed_consts: ThinVec, /// Traits imported via `use Trait as _;`. @@ -329,6 +330,10 @@ impl ItemScope { self.impls.iter().copied() } + pub fn builtin_derive_impls(&self) -> impl ExactSizeIterator + '_ { + self.builtin_derive_impls.iter().copied() + } + pub fn all_macro_calls(&self) -> impl Iterator + '_ { self.macro_invocations.values().copied().chain(self.attr_macros.values().copied()).chain( self.derive_macros.values().flat_map(|it| { @@ -471,6 +476,10 @@ impl ItemScope { self.impls.push(imp); } + pub(crate) fn define_builtin_derive_impl(&mut self, imp: BuiltinDeriveImplId) { + self.builtin_derive_impls.push(imp); + } + pub(crate) fn define_extern_block(&mut self, extern_block: ExternBlockId) { self.extern_blocks.push(extern_block); } @@ -811,6 +820,7 @@ impl ItemScope { unresolved, declarations, impls, + builtin_derive_impls, unnamed_consts, unnamed_trait_imports, legacy_macros, @@ -834,6 +844,7 @@ impl ItemScope { unresolved.shrink_to_fit(); declarations.shrink_to_fit(); impls.shrink_to_fit(); + builtin_derive_impls.shrink_to_fit(); unnamed_consts.shrink_to_fit(); unnamed_trait_imports.shrink_to_fit(); legacy_macros.shrink_to_fit(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index fd693477a4b4..41d69c1fd624 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -2,6 +2,7 @@ //! //! This attribute to tell the compiler about semi built-in std library //! features, such as Fn family of traits. +use hir_expand::name::Name; use intern::{Symbol, sym}; use stdx::impl_from; @@ -10,7 +11,7 @@ use crate::{ StaticId, StructId, TraitId, TypeAliasId, UnionId, attrs::AttrFlags, db::DefDatabase, - nameres::{assoc::TraitItems, crate_def_map, crate_local_def_map}, + nameres::{DefMap, assoc::TraitItems, crate_def_map, crate_local_def_map}, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -93,6 +94,10 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option Option { + let mut current = &core_def_map[core_def_map.root]; + for module in modules { + let Some((ModuleDefId::ModuleId(cur), _)) = + current.scope.type_(&Name::new_symbol_root(module.clone())) + else { + return None; + }; + if cur.krate(db) != core_def_map.krate() || cur.block(db) != core_def_map.block_id() { + return None; + } + current = &core_def_map[cur]; + } + let Some((ModuleDefId::TraitId(trait_), _)) = current.scope.type_(&Name::new_symbol_root(name)) + else { + return None; + }; + Some(trait_) +} + #[salsa::tracked(returns(as_deref))] pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option> { let mut traits = Vec::new(); @@ -158,6 +188,10 @@ macro_rules! language_item_table { ( $LangItems:ident => $( $(#[$attr:meta])* $lang_item:ident, $module:ident :: $name:ident, $target:ident; )* + + @non_lang_core_traits: + + $( core::$($non_lang_module:ident)::*, $non_lang_trait:ident; )* ) => { #[allow(non_snake_case)] // FIXME: Should we remove this? #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] @@ -166,6 +200,9 @@ macro_rules! language_item_table { $(#[$attr])* pub $lang_item: Option<$target>, )* + $( + pub $non_lang_trait: Option, + )* } impl LangItems { @@ -176,6 +213,7 @@ macro_rules! language_item_table { /// Merges `self` with `other`, with preference to `self` items. fn merge_prefer_self(&mut self, other: &Self) { $( self.$lang_item = self.$lang_item.or(other.$lang_item); )* + $( self.$non_lang_trait = self.$non_lang_trait.or(other.$non_lang_trait); )* } fn assign_lang_item(&mut self, name: Symbol, target: LangItemTarget) { @@ -190,6 +228,10 @@ macro_rules! language_item_table { _ => {} } } + + fn fill_non_lang_core_traits(&mut self, db: &dyn DefDatabase, core_def_map: &DefMap) { + $( self.$non_lang_trait = resolve_core_trait(db, core_def_map, &[ $(sym::$non_lang_module),* ], sym::$non_lang_trait); )* + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -426,4 +468,11 @@ language_item_table! { LangItems => String, sym::String, StructId; CStr, sym::CStr, StructId; Ordering, sym::Ordering, EnumId; + + @non_lang_core_traits: + core::default, Default; + core::fmt, Debug; + core::hash, Hash; + core::cmp, Ord; + core::cmp, Eq; } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 97af8ad93def..fde1e6ca17ee 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -30,6 +30,7 @@ pub mod dyn_map; pub mod item_tree; +pub mod builtin_derive; pub mod lang_item; pub mod hir; @@ -80,6 +81,7 @@ pub use hir_expand::{Intern, Lookup, tt}; use crate::{ attrs::AttrFlags, + builtin_derive::BuiltinDeriveImplTrait, builtin_type::BuiltinType, db::DefDatabase, expr_store::ExpressionStoreSourceMap, @@ -331,6 +333,19 @@ impl ImplId { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct BuiltinDeriveImplLoc { + pub adt: AdtId, + pub trait_: BuiltinDeriveImplTrait, +} + +#[salsa::interned(debug, no_lifetime)] +#[derive(PartialOrd, Ord)] +pub struct BuiltinDeriveImplId { + #[returns(ref)] + pub loc: BuiltinDeriveImplLoc, +} + type UseLoc = ItemLoc; impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use); @@ -1009,6 +1024,20 @@ fn module_for_assoc_item_loc<'db>( id.lookup(db).container.module(db) } +impl HasModule for BuiltinDeriveImplLoc { + #[inline] + fn module(&self, db: &dyn DefDatabase) -> ModuleId { + self.adt.module(db) + } +} + +impl HasModule for BuiltinDeriveImplId { + #[inline] + fn module(&self, db: &dyn DefDatabase) -> ModuleId { + self.loc(db).module(db) + } +} + impl HasModule for FunctionId { #[inline] fn module(&self, db: &dyn DefDatabase) -> ModuleId { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 7e1ec526a7bc..2fac0837de22 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -12,7 +12,7 @@ use hir_expand::{ AttrMacroAttrIds, EditionedFileId, ErasedAstId, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, attrs::{Attr, AttrId}, - builtin::{find_builtin_attr, find_builtin_derive, find_builtin_macro}, + builtin::{BuiltinDeriveExpander, find_builtin_attr, find_builtin_derive, find_builtin_macro}, mod_path::{ModPath, PathKind}, name::{AsName, Name}, proc_macro::CustomProcMacroExpander, @@ -23,15 +23,17 @@ use la_arena::Idx; use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::SmallVec; use span::{Edition, FileAstId, SyntaxContext}; +use stdx::always; use syntax::ast; use triomphe::Arc; use crate::{ - AdtId, AssocItemId, AstId, AstIdWithPath, ConstLoc, EnumLoc, ExternBlockLoc, ExternCrateId, - ExternCrateLoc, FunctionId, FunctionLoc, FxIndexMap, ImplLoc, Intern, ItemContainerId, Lookup, - Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, - ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, - UnionLoc, UnresolvedMacro, UseId, UseLoc, + AdtId, AssocItemId, AstId, AstIdWithPath, BuiltinDeriveImplId, BuiltinDeriveImplLoc, ConstLoc, + EnumLoc, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, FxIndexMap, + ImplLoc, Intern, ItemContainerId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, + MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId, + ProcMacroLoc, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, + UseLoc, db::DefDatabase, item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports}, item_tree::{ @@ -104,6 +106,7 @@ pub(super) fn collect_defs( prev_active_attrs: Default::default(), unresolved_extern_crates: Default::default(), is_proc_macro: krate.is_proc_macro, + deferred_builtin_derives: Default::default(), }; if tree_id.is_block() { collector.seed_with_inner(tree_id); @@ -214,6 +217,15 @@ enum MacroDirectiveKind<'db> { }, } +#[derive(Debug)] +struct DeferredBuiltinDerive { + call_id: MacroCallId, + derive: BuiltinDeriveExpander, + module_id: ModuleId, + depth: usize, + container: ItemContainerId, +} + /// Walks the tree of module recursively struct DefCollector<'db> { db: &'db dyn DefDatabase, @@ -252,6 +264,11 @@ struct DefCollector<'db> { /// on the same item. Therefore, this holds all active attributes that we already /// expanded. prev_active_attrs: FxHashMap, SmallVec<[AttrId; 1]>>, + /// To save memory, we do not really expand builtin derives. Instead, we save them as a `BuiltinDeriveImplId`. + /// + /// However, we can only do that when the derive is directly above the item, and there is no attribute in between. + /// Otherwise, all sorts of weird things can happen, like the item name resolving to something else. + deferred_builtin_derives: FxHashMap, Vec>, } impl<'db> DefCollector<'db> { @@ -1241,7 +1258,7 @@ impl<'db> DefCollector<'db> { fn resolve_macros(&mut self) -> ReachedFixedPoint { let mut macros = mem::take(&mut self.unresolved_macros); let mut resolved = Vec::new(); - let mut push_resolved = |directive: &MacroDirective<'_>, call_id| { + let push_resolved = |resolved: &mut Vec<_>, directive: &MacroDirective<'_>, call_id| { let attr_macro_item = match &directive.kind { MacroDirectiveKind::Attr { ast_id, .. } => Some(ast_id.ast_id), MacroDirectiveKind::FnLike { .. } | MacroDirectiveKind::Derive { .. } => None, @@ -1271,8 +1288,8 @@ impl<'db> DefCollector<'db> { MacroSubNs::Attr } }; - let resolver = |path: &_| { - let resolved_res = self.def_map.resolve_path_fp_with_macro( + let resolver = |def_map: &DefMap, path: &_| { + let resolved_res = def_map.resolve_path_fp_with_macro( self.crate_local_def_map.unwrap_or(&self.local_def_map), self.db, ResolveMode::Other, @@ -1283,7 +1300,7 @@ impl<'db> DefCollector<'db> { ); resolved_res.resolved_def.take_macros().map(|it| (it, self.db.macro_def(it))) }; - let resolver_def_id = |path: &_| resolver(path).map(|(_, it)| it); + let resolver_def_id = |path: &_| resolver(&self.def_map, path).map(|(_, it)| it); match &directive.kind { MacroDirectiveKind::FnLike { ast_id, expand_to, ctxt: call_site } => { @@ -1306,7 +1323,7 @@ impl<'db> DefCollector<'db> { .scope .add_macro_invoc(ast_id.ast_id, call_id); - push_resolved(directive, call_id); + push_resolved(&mut resolved, directive, call_id); res = ReachedFixedPoint::No; return Resolved::Yes; @@ -1320,6 +1337,7 @@ impl<'db> DefCollector<'db> { ctxt: call_site, derive_macro_id, } => { + // FIXME: This code is almost duplicate below. let id = derive_macro_as_call_id( self.db, ast_id, @@ -1327,7 +1345,7 @@ impl<'db> DefCollector<'db> { *derive_pos as u32, *call_site, self.def_map.krate, - resolver, + |path| resolver(&self.def_map, path), *derive_macro_id, ); @@ -1354,7 +1372,8 @@ impl<'db> DefCollector<'db> { } } - push_resolved(directive, call_id); + push_resolved(&mut resolved, directive, call_id); + res = ReachedFixedPoint::No; return Resolved::Yes; } @@ -1470,18 +1489,78 @@ impl<'db> DefCollector<'db> { ast_id.value, Interned::new(path), ); - self.unresolved_macros.push(MacroDirective { - module_id: directive.module_id, - depth: directive.depth + 1, - kind: MacroDirectiveKind::Derive { - ast_id, - derive_attr: *attr_id, - derive_pos: idx, - ctxt: call_site.ctx, - derive_macro_id: call_id, - }, - container: directive.container, - }); + + // Try to resolve the derive immediately. If we succeed, we can also use the fast path + // for builtin derives. If not, we cannot use it, as it can cause the ADT to become + // interned while the derive is still unresolved, which will cause it to get forgotten. + let id = derive_macro_as_call_id( + self.db, + &ast_id, + *attr_id, + idx as u32, + call_site.ctx, + self.def_map.krate, + |path| resolver(&self.def_map, path), + call_id, + ); + + if let Ok((macro_id, def_id, call_id)) = id { + self.def_map.modules[directive.module_id] + .scope + .set_derive_macro_invoc( + ast_id.ast_id, + call_id, + *attr_id, + idx, + ); + // Record its helper attributes. + if def_id.krate != self.def_map.krate { + let def_map = crate_def_map(self.db, def_id.krate); + if let Some(helpers) = + def_map.data.exported_derives.get(¯o_id) + { + self.def_map + .derive_helpers_in_scope + .entry(ast_id.ast_id.map(|it| it.upcast())) + .or_default() + .extend(izip!( + helpers.iter().cloned(), + iter::repeat(macro_id), + iter::repeat(call_id), + )); + } + } + + if let MacroDefKind::BuiltInDerive(_, builtin_derive) = + def_id.kind + { + self.deferred_builtin_derives + .entry(ast_id.ast_id.upcast()) + .or_default() + .push(DeferredBuiltinDerive { + call_id, + derive: builtin_derive, + module_id: directive.module_id, + container: directive.container, + depth: directive.depth, + }); + } else { + push_resolved(&mut resolved, directive, call_id); + } + } else { + self.unresolved_macros.push(MacroDirective { + module_id: directive.module_id, + depth: directive.depth + 1, + kind: MacroDirectiveKind::Derive { + ast_id, + derive_attr: *attr_id, + derive_pos: idx, + ctxt: call_site.ctx, + derive_macro_id: call_id, + }, + container: directive.container, + }); + } len = idx; } @@ -1522,12 +1601,25 @@ impl<'db> DefCollector<'db> { } } + // Clear deferred derives for this item, unfortunately we cannot use them due to the attribute. + if let Some(deferred_derives) = self.deferred_builtin_derives.remove(&ast_id) { + resolved.extend(deferred_derives.into_iter().map(|derive| { + ( + derive.module_id, + derive.depth, + derive.container, + derive.call_id, + Some(ast_id), + ) + })); + } + let call_id = call_id(); self.def_map.modules[directive.module_id] .scope .add_attr_macro_invoc(ast_id, call_id); - push_resolved(directive, call_id); + push_resolved(&mut resolved, directive, call_id); res = ReachedFixedPoint::No; return Resolved::Yes; } @@ -1709,6 +1801,12 @@ impl<'db> DefCollector<'db> { )); } + always!( + self.deferred_builtin_derives.is_empty(), + "self.deferred_builtin_derives={:#?}", + self.deferred_builtin_derives, + ); + (self.def_map, self.local_def_map) } } @@ -1751,6 +1849,26 @@ impl ModCollector<'_, '_> { } let db = self.def_collector.db; let module_id = self.module_id; + let consider_deferred_derives = + |file_id: HirFileId, + deferred_derives: &mut FxHashMap<_, Vec>, + ast_id: FileAstId, + id: AdtId, + def_map: &mut DefMap| { + let Some(deferred_derives) = + deferred_derives.remove(&InFile::new(file_id, ast_id.upcast())) + else { + return; + }; + let module = &mut def_map.modules[module_id]; + for deferred_derive in deferred_derives { + crate::builtin_derive::with_derive_traits(deferred_derive.derive, |trait_| { + let impl_id = + BuiltinDeriveImplId::new(db, BuiltinDeriveImplLoc { adt: id, trait_ }); + module.scope.define_builtin_derive_impl(impl_id); + }); + } + }; let update_def = |def_collector: &mut DefCollector<'_>, id, name: &Name, vis, has_constructor| { def_collector.def_map.modules[module_id].scope.declare(id); @@ -1928,11 +2046,21 @@ impl ModCollector<'_, '_> { let it = &self.item_tree[id]; let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); + let interned = StructLoc { + container: module_id, + id: InFile::new(self.tree_id.file_id(), id), + } + .intern(db); + consider_deferred_derives( + self.tree_id.file_id(), + &mut self.def_collector.deferred_builtin_derives, + id.upcast(), + interned.into(), + def_map, + ); update_def( self.def_collector, - StructLoc { container: module_id, id: InFile::new(self.file_id(), id) } - .intern(db) - .into(), + interned.into(), &it.name, vis, !matches!(it.shape, FieldsShape::Record), @@ -1942,15 +2070,19 @@ impl ModCollector<'_, '_> { let it = &self.item_tree[id]; let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); - update_def( - self.def_collector, - UnionLoc { container: module_id, id: InFile::new(self.file_id(), id) } - .intern(db) - .into(), - &it.name, - vis, - false, + let interned = UnionLoc { + container: module_id, + id: InFile::new(self.tree_id.file_id(), id), + } + .intern(db); + consider_deferred_derives( + self.tree_id.file_id(), + &mut self.def_collector.deferred_builtin_derives, + id.upcast(), + interned.into(), + def_map, ); + update_def(self.def_collector, interned.into(), &it.name, vis, false); } ModItemId::Enum(id) => { let it = &self.item_tree[id]; @@ -1960,6 +2092,13 @@ impl ModCollector<'_, '_> { } .intern(db); + consider_deferred_derives( + self.tree_id.file_id(), + &mut self.def_collector.deferred_builtin_derives, + id.upcast(), + enum_.into(), + def_map, + ); let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]); update_def(self.def_collector, enum_.into(), &it.name, vis, false); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs index c8eb968b3587..a943f6f0ac01 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs @@ -784,7 +784,7 @@ macro_rules! foo { pub use core::clone::Clone; "#, - |map| assert_eq!(map.modules[map.root].scope.impls().len(), 1), + |map| assert_eq!(map.modules[map.root].scope.builtin_derive_impls().len(), 1), ); } @@ -806,7 +806,7 @@ pub macro Copy {} #[rustc_builtin_macro] pub macro Clone {} "#, - |map| assert_eq!(map.modules[map.root].scope.impls().len(), 2), + |map| assert_eq!(map.modules[map.root].scope.builtin_derive_impls().len(), 2), ); } @@ -849,7 +849,7 @@ pub macro derive($item:item) {} #[rustc_builtin_macro] pub macro Clone {} "#, - |map| assert_eq!(map.modules[map.root].scope.impls().len(), 1), + |map| assert_eq!(map.modules[map.root].scope.builtin_derive_impls().len(), 1), ); } @@ -1609,7 +1609,7 @@ macro_rules! derive { () => {} } #[derive(Clone)] struct S; "#, - |map| assert_eq!(map.modules[map.root].scope.impls().len(), 1), + |map| assert_eq!(map.modules[map.root].scope.builtin_derive_impls().len(), 1), ); } diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs index 6582f4b07574..c80519742585 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/derive_macro.rs @@ -28,7 +28,7 @@ use syntax::{ }; macro_rules! register_builtin { - ( $($trait:ident => $expand:ident),* ) => { + ( $($trait:ident => $expand:ident),* $(,)? ) => { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinDeriveExpander { $($trait),* @@ -48,7 +48,6 @@ macro_rules! register_builtin { } } } - }; } @@ -75,7 +74,7 @@ register_builtin! { PartialOrd => partial_ord_expand, Eq => eq_expand, PartialEq => partial_eq_expand, - CoercePointee => coerce_pointee_expand + CoercePointee => coerce_pointee_expand, } pub fn find_builtin_derive(ident: &name::Name) -> Option { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs b/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs new file mode 100644 index 000000000000..15d9634cfab6 --- /dev/null +++ b/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs @@ -0,0 +1,575 @@ +//! Implementation of builtin derive impls. + +use std::ops::ControlFlow; + +use hir_def::{ + AdtId, BuiltinDeriveImplId, BuiltinDeriveImplLoc, HasModule, LocalFieldId, TraitId, + TypeOrConstParamId, TypeParamId, + attrs::AttrFlags, + builtin_derive::BuiltinDeriveImplTrait, + hir::generics::{GenericParams, TypeOrConstParamData}, +}; +use itertools::Itertools; +use la_arena::ArenaMap; +use rustc_type_ir::{ + AliasTyKind, Interner, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, + inherent::{GenericArgs as _, IntoKind}, +}; + +use crate::{ + GenericPredicates, + db::HirDatabase, + next_solver::{ + Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, StoredEarlyBinder, StoredTy, + TraitRef, Ty, TyKind, fold::fold_tys, generics::Generics, + }, +}; + +fn fake_type_param(adt: AdtId) -> TypeParamId { + // HACK: Fake the param. + TypeParamId::from_unchecked(TypeOrConstParamId { + parent: adt.into(), + local_id: la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(u32::MAX)), + }) +} + +pub(crate) fn generics_of<'db>(interner: DbInterner<'db>, id: BuiltinDeriveImplId) -> Generics { + let db = interner.db; + let loc = id.loc(db); + match loc.trait_ { + BuiltinDeriveImplTrait::Copy + | BuiltinDeriveImplTrait::Clone + | BuiltinDeriveImplTrait::Default + | BuiltinDeriveImplTrait::Debug + | BuiltinDeriveImplTrait::Hash + | BuiltinDeriveImplTrait::Ord + | BuiltinDeriveImplTrait::PartialOrd + | BuiltinDeriveImplTrait::Eq + | BuiltinDeriveImplTrait::PartialEq => interner.generics_of(loc.adt.into()), + BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { + let mut generics = interner.generics_of(loc.adt.into()); + generics.push_param(fake_type_param(loc.adt).into()); + generics + } + } +} + +pub(crate) fn impl_trait<'db>( + interner: DbInterner<'db>, + id: BuiltinDeriveImplId, +) -> EarlyBinder<'db, TraitRef<'db>> { + let db = interner.db; + let loc = id.loc(db); + let trait_id = loc + .trait_ + .get_id(interner.lang_items()) + .expect("we don't pass the impl to the solver if we can't resolve the trait"); + match loc.trait_ { + BuiltinDeriveImplTrait::Copy + | BuiltinDeriveImplTrait::Clone + | BuiltinDeriveImplTrait::Default + | BuiltinDeriveImplTrait::Debug + | BuiltinDeriveImplTrait::Hash + | BuiltinDeriveImplTrait::Ord + | BuiltinDeriveImplTrait::Eq => { + let self_ty = Ty::new_adt( + interner, + loc.adt, + GenericArgs::identity_for_item(interner, loc.adt.into()), + ); + EarlyBinder::bind(TraitRef::new(interner, trait_id.into(), [self_ty])) + } + BuiltinDeriveImplTrait::PartialOrd | BuiltinDeriveImplTrait::PartialEq => { + let self_ty = Ty::new_adt( + interner, + loc.adt, + GenericArgs::identity_for_item(interner, loc.adt.into()), + ); + EarlyBinder::bind(TraitRef::new(interner, trait_id.into(), [self_ty, self_ty])) + } + BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { + let generic_params = GenericParams::new(db, loc.adt.into()); + let interner = DbInterner::new_no_crate(db); + let args = GenericArgs::identity_for_item(interner, loc.adt.into()); + let self_ty = Ty::new_adt(interner, loc.adt, args); + let Some((pointee_param_idx, _, new_param_ty)) = + coerce_pointee_params(interner, loc, &generic_params) + else { + // Malformed derive. + return EarlyBinder::bind(TraitRef::new( + interner, + trait_id.into(), + [self_ty, self_ty], + )); + }; + let changed_args = replace_pointee(interner, pointee_param_idx, new_param_ty, args); + let changed_self_ty = Ty::new_adt(interner, loc.adt, changed_args); + EarlyBinder::bind(TraitRef::new(interner, trait_id.into(), [self_ty, changed_self_ty])) + } + } +} + +#[salsa::tracked(returns(ref), unsafe(non_update_types))] +pub(crate) fn builtin_derive_predicates<'db>( + db: &'db dyn HirDatabase, + impl_: BuiltinDeriveImplId, +) -> GenericPredicates { + let loc = impl_.loc(db); + let generic_params = GenericParams::new(db, loc.adt.into()); + let interner = DbInterner::new_with(db, loc.module(db).krate(db)); + let adt_predicates = GenericPredicates::query(db, loc.adt.into()); + match loc.trait_ { + BuiltinDeriveImplTrait::Copy + | BuiltinDeriveImplTrait::Clone + | BuiltinDeriveImplTrait::Debug + | BuiltinDeriveImplTrait::Hash + | BuiltinDeriveImplTrait::Ord + | BuiltinDeriveImplTrait::PartialOrd + | BuiltinDeriveImplTrait::Eq + | BuiltinDeriveImplTrait::PartialEq => { + simple_trait_predicates(interner, loc, &generic_params, adt_predicates) + } + BuiltinDeriveImplTrait::Default => { + if matches!(loc.adt, AdtId::EnumId(_)) { + // Enums don't have extra bounds. + GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind( + Clauses::new_from_slice(adt_predicates.explicit_predicates().skip_binder()) + .store(), + )) + } else { + simple_trait_predicates(interner, loc, &generic_params, adt_predicates) + } + } + BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { + let Some((pointee_param_idx, pointee_param_id, new_param_ty)) = + coerce_pointee_params(interner, loc, &generic_params) + else { + // Malformed derive. + return GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind( + Clauses::default().store(), + )); + }; + let duplicated_bounds = + adt_predicates.explicit_predicates().iter_identity_copied().filter_map(|pred| { + let mentions_pointee = + pred.visit_with(&mut MentionsPointee { pointee_param_idx }).is_break(); + if !mentions_pointee { + return None; + } + let transformed = + replace_pointee(interner, pointee_param_idx, new_param_ty, pred); + Some(transformed) + }); + let unsize_trait = interner.lang_items().Unsize; + let unsize_bound = unsize_trait.map(|unsize_trait| { + let pointee_param_ty = Ty::new_param(interner, pointee_param_id, pointee_param_idx); + TraitRef::new(interner, unsize_trait.into(), [pointee_param_ty, new_param_ty]) + .upcast(interner) + }); + GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind( + Clauses::new_from_iter( + interner, + adt_predicates + .explicit_predicates() + .iter_identity_copied() + .chain(duplicated_bounds) + .chain(unsize_bound), + ) + .store(), + )) + } + } +} + +struct MentionsPointee { + pointee_param_idx: u32, +} + +impl<'db> TypeVisitor> for MentionsPointee { + type Result = ControlFlow<()>; + + fn visit_ty(&mut self, t: Ty<'db>) -> Self::Result { + if let TyKind::Param(param) = t.kind() + && param.index == self.pointee_param_idx + { + ControlFlow::Break(()) + } else { + t.super_visit_with(self) + } + } +} + +fn replace_pointee<'db, T: TypeFoldable>>( + interner: DbInterner<'db>, + pointee_param_idx: u32, + new_param_ty: Ty<'db>, + t: T, +) -> T { + fold_tys(interner, t, |ty| match ty.kind() { + TyKind::Param(param) if param.index == pointee_param_idx => new_param_ty, + _ => ty, + }) +} + +fn simple_trait_predicates<'db>( + interner: DbInterner<'db>, + loc: &BuiltinDeriveImplLoc, + generic_params: &GenericParams, + adt_predicates: &GenericPredicates, +) -> GenericPredicates { + let trait_id = loc + .trait_ + .get_id(interner.lang_items()) + .expect("we don't pass the impl to the solver if we can't resolve the trait"); + let extra_predicates = generic_params + .iter_type_or_consts() + .filter(|(_, data)| matches!(data, TypeOrConstParamData::TypeParamData(_))) + .map(|(param_idx, _)| { + let param_id = TypeParamId::from_unchecked(TypeOrConstParamId { + parent: loc.adt.into(), + local_id: param_idx, + }); + let param_idx = + param_idx.into_raw().into_u32() + (generic_params.len_lifetimes() as u32); + let param_ty = Ty::new_param(interner, param_id, param_idx); + let trait_ref = TraitRef::new(interner, trait_id.into(), [param_ty]); + trait_ref.upcast(interner) + }); + let mut assoc_type_bounds = Vec::new(); + match loc.adt { + AdtId::StructId(id) => extend_assoc_type_bounds( + interner, + &mut assoc_type_bounds, + interner.db.field_types(id.into()), + trait_id, + ), + AdtId::UnionId(id) => extend_assoc_type_bounds( + interner, + &mut assoc_type_bounds, + interner.db.field_types(id.into()), + trait_id, + ), + AdtId::EnumId(id) => { + for &(variant_id, _, _) in &id.enum_variants(interner.db).variants { + extend_assoc_type_bounds( + interner, + &mut assoc_type_bounds, + interner.db.field_types(variant_id.into()), + trait_id, + ) + } + } + } + GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind( + Clauses::new_from_iter( + interner, + adt_predicates + .explicit_predicates() + .iter_identity_copied() + .chain(extra_predicates) + .chain(assoc_type_bounds), + ) + .store(), + )) +} + +fn extend_assoc_type_bounds<'db>( + interner: DbInterner<'db>, + assoc_type_bounds: &mut Vec>, + fields: &ArenaMap>, + trait_: TraitId, +) { + struct ProjectionFinder<'a, 'db> { + interner: DbInterner<'db>, + assoc_type_bounds: &'a mut Vec>, + trait_: TraitId, + } + + impl<'db> TypeVisitor> for ProjectionFinder<'_, 'db> { + type Result = (); + + fn visit_ty(&mut self, t: Ty<'db>) -> Self::Result { + if let TyKind::Alias(AliasTyKind::Projection, _) = t.kind() { + self.assoc_type_bounds.push( + TraitRef::new(self.interner, self.trait_.into(), [t]).upcast(self.interner), + ); + } + + t.super_visit_with(self) + } + } + + let mut visitor = ProjectionFinder { interner, assoc_type_bounds, trait_ }; + for (_, field) in fields.iter() { + field.get().instantiate_identity().visit_with(&mut visitor); + } +} + +fn coerce_pointee_params<'db>( + interner: DbInterner<'db>, + loc: &BuiltinDeriveImplLoc, + generic_params: &GenericParams, +) -> Option<(u32, TypeParamId, Ty<'db>)> { + let pointee_param = { + if let Ok((pointee_param, _)) = generic_params + .iter_type_or_consts() + .filter(|param| matches!(param.1, TypeOrConstParamData::TypeParamData(_))) + .exactly_one() + { + pointee_param + } else { + let (_, generic_param_attrs) = + AttrFlags::query_generic_params(interner.db, loc.adt.into()); + generic_param_attrs + .iter() + .find(|param| param.1.contains(AttrFlags::IS_POINTEE)) + .map(|(param, _)| param) + .or_else(|| { + generic_params + .iter_type_or_consts() + .find(|param| matches!(param.1, TypeOrConstParamData::TypeParamData(_))) + .map(|(idx, _)| idx) + })? + } + }; + let pointee_param_id = TypeParamId::from_unchecked(TypeOrConstParamId { + parent: loc.adt.into(), + local_id: pointee_param, + }); + let pointee_param_idx = + pointee_param.into_raw().into_u32() + (generic_params.len_lifetimes() as u32); + let new_param_idx = generic_params.len() as u32; + let new_param_id = fake_type_param(loc.adt); + let new_param_ty = Ty::new_param(interner, new_param_id, new_param_idx); + Some((pointee_param_idx, pointee_param_id, new_param_ty)) +} + +#[cfg(test)] +mod tests { + use expect_test::{Expect, expect}; + use hir_def::nameres::crate_def_map; + use itertools::Itertools; + use stdx::format_to; + use test_fixture::WithFixture; + + use crate::{ + builtin_derive::{builtin_derive_predicates, impl_trait}, + next_solver::DbInterner, + test_db::TestDB, + }; + + fn check_trait_refs(#[rust_analyzer::rust_fixture] ra_fixture: &str, expectation: Expect) { + let db = TestDB::with_files(ra_fixture); + let def_map = crate_def_map(&db, db.test_crate()); + + let interner = DbInterner::new_with(&db, db.test_crate()); + crate::attach_db(&db, || { + let mut trait_refs = Vec::new(); + for (_, module) in def_map.modules() { + for derive in module.scope.builtin_derive_impls() { + let trait_ref = impl_trait(interner, derive).skip_binder(); + trait_refs.push(format!("{trait_ref:?}")); + } + } + + expectation.assert_eq(&trait_refs.join("\n")); + }); + } + + fn check_predicates(#[rust_analyzer::rust_fixture] ra_fixture: &str, expectation: Expect) { + let db = TestDB::with_files(ra_fixture); + let def_map = crate_def_map(&db, db.test_crate()); + + crate::attach_db(&db, || { + let mut predicates = String::new(); + for (_, module) in def_map.modules() { + for derive in module.scope.builtin_derive_impls() { + let preds = + builtin_derive_predicates(&db, derive).all_predicates().skip_binder(); + format_to!( + predicates, + "{}\n\n", + preds.iter().format_with("\n", |pred, formatter| formatter(&format_args!( + "{pred:?}" + ))), + ); + } + } + + expectation.assert_eq(&predicates); + }); + } + + #[test] + fn simple_macros_trait_ref() { + check_trait_refs( + r#" +//- minicore: derive, clone, copy, eq, ord, hash, fmt + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct Simple; + +trait Trait {} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct WithGenerics<'a, T: Trait, const N: usize>(&'a [T; N]); + "#, + expect![[r#" + Simple: Debug + Simple: Clone + Simple: Copy + Simple: PartialEq<[Simple]> + Simple: Eq + Simple: PartialOrd<[Simple]> + Simple: Ord + Simple: Hash + WithGenerics<#0, #1, #2>: Debug + WithGenerics<#0, #1, #2>: Clone + WithGenerics<#0, #1, #2>: Copy + WithGenerics<#0, #1, #2>: PartialEq<[WithGenerics<#0, #1, #2>]> + WithGenerics<#0, #1, #2>: Eq + WithGenerics<#0, #1, #2>: PartialOrd<[WithGenerics<#0, #1, #2>]> + WithGenerics<#0, #1, #2>: Ord + WithGenerics<#0, #1, #2>: Hash"#]], + ); + } + + #[test] + fn coerce_pointee_trait_ref() { + check_trait_refs( + r#" +//- minicore: derive, coerce_pointee +use core::marker::CoercePointee; + +#[derive(CoercePointee)] +struct Simple(*const T); + +#[derive(CoercePointee)] +struct MultiGenericParams<'a, T, #[pointee] U: ?Sized, const N: usize>(*const U); + "#, + expect![[r#" + Simple<#0>: CoerceUnsized<[Simple<#1>]> + Simple<#0>: DispatchFromDyn<[Simple<#1>]> + MultiGenericParams<#0, #1, #2, #3>: CoerceUnsized<[MultiGenericParams<#0, #1, #4, #3>]> + MultiGenericParams<#0, #1, #2, #3>: DispatchFromDyn<[MultiGenericParams<#0, #1, #4, #3>]>"#]], + ); + } + + #[test] + fn simple_macros_predicates() { + check_predicates( + r#" +//- minicore: derive, clone, copy, eq, ord, hash, fmt + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct Simple; + +trait Trait {} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct WithGenerics<'a, T: Trait, const N: usize>(&'a [T; N]); + "#, + expect![[r#" + + + + + + + + + + + + + + + + + Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Debug, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Clone, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Copy, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: PartialEq, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Eq, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: PartialOrd, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Ord, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Hash, polarity:Positive), bound_vars: [] }) + + "#]], + ); + } + + #[test] + fn coerce_pointee_predicates() { + check_predicates( + r#" +//- minicore: derive, coerce_pointee +use core::marker::CoercePointee; + +#[derive(CoercePointee)] +struct Simple(*const T); + +trait Trait {} + +#[derive(CoercePointee)] +struct MultiGenericParams<'a, T, #[pointee] U: ?Sized, const N: usize>(*const U) +where + T: Trait, + U: Trait; + "#, + expect![[r#" + Clause(Binder { value: TraitPredicate(#0: Unsize<[#1]>, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#0: Unsize<[#1]>, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#1: Trait<[#2]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#2: Trait<[#2]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#3, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Trait<[#4]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#4: Trait<[#4]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#2: Unsize<[#4]>, polarity:Positive), bound_vars: [] }) + + Clause(Binder { value: TraitPredicate(#1: Trait<[#2]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#2: Trait<[#2]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: ConstArgHasType(#3, usize), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#1: Trait<[#4]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#4: Trait<[#4]>, polarity:Positive), bound_vars: [] }) + Clause(Binder { value: TraitPredicate(#2: Unsize<[#4]>, polarity:Positive), bound_vars: [] }) + + "#]], + ); + } +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs index 66692143bc1a..9d6869eee9b8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs @@ -32,7 +32,7 @@ fn has_destructor(interner: DbInterner<'_>, adt: AdtId) -> bool { }, None => TraitImpls::for_crate(db, module.krate(db)), }; - !impls.for_trait_and_self_ty(drop_trait, &SimplifiedType::Adt(adt.into())).is_empty() + !impls.for_trait_and_self_ty(drop_trait, &SimplifiedType::Adt(adt.into())).0.is_empty() } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 1674771413f2..7b414cd55174 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -25,6 +25,7 @@ extern crate ra_ap_rustc_next_trait_solver as rustc_next_trait_solver; extern crate self as hir_ty; +mod builtin_derive; mod infer; mod inhabitedness; mod lower; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 62a5837f349d..ebbf29e6ff46 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -1790,6 +1790,13 @@ impl<'db> GenericPredicates { } impl GenericPredicates { + #[inline] + pub(crate) fn from_explicit_own_predicates( + predicates: StoredEarlyBinder, + ) -> Self { + Self { predicates, own_predicates_start: 0, is_trait: false, parent_is_trait: false } + } + #[inline] pub fn query(db: &dyn HirDatabase, def: GenericDefId) -> &GenericPredicates { &Self::query_with_diagnostics(db, def).0 diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index c370330a8717..88f48fdbc67a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -13,11 +13,12 @@ use tracing::{debug, instrument}; use base_db::Crate; use hir_def::{ - AssocItemId, BlockId, ConstId, FunctionId, GenericParamId, HasModule, ImplId, ItemContainerId, - ModuleId, TraitId, + AssocItemId, BlockId, BuiltinDeriveImplId, ConstId, FunctionId, GenericParamId, HasModule, + ImplId, ItemContainerId, ModuleId, TraitId, attrs::AttrFlags, expr_store::path::GenericArgs as HirGenericArgs, hir::ExprId, + lang_item::LangItems, nameres::{DefMap, block_def_map, crate_def_map}, resolver::Resolver, }; @@ -37,7 +38,7 @@ use crate::{ infer::{InferenceContext, unify::InferenceTable}, lower::GenericPredicates, next_solver::{ - Binder, ClauseKind, DbInterner, FnSig, GenericArgs, ParamEnv, PredicateKind, + AnyImplId, Binder, ClauseKind, DbInterner, FnSig, GenericArgs, ParamEnv, PredicateKind, SimplifiedType, SolverDefId, TraitRef, Ty, TyKind, TypingMode, infer::{ BoundRegionConversionTime, DbInternerInferExt, InferCtxt, InferOk, @@ -132,7 +133,7 @@ pub enum MethodError<'db> { // candidate can arise. Used for error reporting only. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum CandidateSource { - Impl(ImplId), + Impl(AnyImplId), Trait(TraitId), } @@ -462,6 +463,10 @@ fn lookup_impl_assoc_item_for_trait_ref<'db>( name: &Name, ) -> Option<(AssocItemId, GenericArgs<'db>)> { let (impl_id, impl_subst) = find_matching_impl(infcx, env, trait_ref)?; + let AnyImplId::ImplId(impl_id) = impl_id else { + // FIXME: Handle resolution to builtin derive. + return None; + }; let item = impl_id.impl_items(infcx.interner.db).items.iter().find_map(|(n, it)| match *it { AssocItemId::FunctionId(f) => (n == name).then_some(AssocItemId::FunctionId(f)), @@ -475,7 +480,7 @@ pub(crate) fn find_matching_impl<'db>( infcx: &InferCtxt<'db>, env: ParamEnv<'db>, trait_ref: TraitRef<'db>, -) -> Option<(ImplId, GenericArgs<'db>)> { +) -> Option<(AnyImplId, GenericArgs<'db>)> { let trait_ref = infcx.at(&ObligationCause::dummy(), env).deeply_normalize(trait_ref).ok()?; let obligation = Obligation::new(infcx.interner, ObligationCause::dummy(), env, trait_ref); @@ -635,13 +640,13 @@ impl InherentImpls { #[derive(Debug, PartialEq)] struct OneTraitImpls { - non_blanket_impls: FxHashMap>, + non_blanket_impls: FxHashMap, Box<[BuiltinDeriveImplId]>)>, blanket_impls: Box<[ImplId]>, } #[derive(Default)] struct OneTraitImplsBuilder { - non_blanket_impls: FxHashMap>, + non_blanket_impls: FxHashMap, Vec)>, blanket_impls: Vec, } @@ -650,7 +655,9 @@ impl OneTraitImplsBuilder { let mut non_blanket_impls = self .non_blanket_impls .into_iter() - .map(|(self_ty, impls)| (self_ty, impls.into_boxed_slice())) + .map(|(self_ty, (impls, builtin_derive_impls))| { + (self_ty, (impls.into_boxed_slice(), builtin_derive_impls.into_boxed_slice())) + }) .collect::>(); non_blanket_impls.shrink_to_fit(); let blanket_impls = self.blanket_impls.into_boxed_slice(); @@ -691,8 +698,9 @@ impl TraitImpls { impl TraitImpls { fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap) -> Self { + let lang_items = hir_def::lang_item::lang_items(db, def_map.krate()); let mut map = FxHashMap::default(); - collect(db, def_map, &mut map); + collect(db, def_map, lang_items, &mut map); let mut map = map .into_iter() .map(|(trait_id, trait_map)| (trait_id, trait_map.finish())) @@ -703,6 +711,7 @@ impl TraitImpls { fn collect( db: &dyn HirDatabase, def_map: &DefMap, + lang_items: &LangItems, map: &mut FxHashMap, ) { for (_module_id, module_data) in def_map.modules() { @@ -727,18 +736,29 @@ impl TraitImpls { let entry = map.entry(trait_ref.def_id.0).or_default(); match simplify_type(interner, self_ty, TreatParams::InstantiateWithInfer) { Some(self_ty) => { - entry.non_blanket_impls.entry(self_ty).or_default().push(impl_id) + entry.non_blanket_impls.entry(self_ty).or_default().0.push(impl_id) } None => entry.blanket_impls.push(impl_id), } } + for impl_id in module_data.scope.builtin_derive_impls() { + let loc = impl_id.loc(db); + let Some(trait_id) = loc.trait_.get_id(lang_items) else { continue }; + let entry = map.entry(trait_id).or_default(); + let entry = entry + .non_blanket_impls + .entry(SimplifiedType::Adt(loc.adt.into())) + .or_default(); + entry.1.push(impl_id); + } + // To better support custom derives, collect impls in all unnamed const items. // const _: () = { ... }; for konst in module_data.scope.unnamed_consts() { let body = db.body(konst.into()); for (_, block_def_map) in body.blocks(db) { - collect(db, block_def_map, map); + collect(db, block_def_map, lang_items, map); } } } @@ -761,11 +781,15 @@ impl TraitImpls { }) } - pub fn for_trait_and_self_ty(&self, trait_: TraitId, self_ty: &SimplifiedType) -> &[ImplId] { + pub fn for_trait_and_self_ty( + &self, + trait_: TraitId, + self_ty: &SimplifiedType, + ) -> (&[ImplId], &[BuiltinDeriveImplId]) { self.map .get(&trait_) .and_then(|map| map.non_blanket_impls.get(self_ty)) - .map(|it| &**it) + .map(|it| (&*it.0, &*it.1)) .unwrap_or_default() } @@ -773,7 +797,7 @@ impl TraitImpls { if let Some(impls) = self.map.get(&trait_) { callback(&impls.blanket_impls); for impls in impls.non_blanket_impls.values() { - callback(impls); + callback(&impls.0); } } } @@ -781,7 +805,7 @@ impl TraitImpls { pub fn for_self_ty(&self, self_ty: &SimplifiedType, mut callback: impl FnMut(&[ImplId])) { for for_trait in self.map.values() { if let Some(for_ty) = for_trait.non_blanket_impls.get(self_ty) { - callback(for_ty); + callback(&for_ty.0); } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs index cb9b810686e3..4a7c7d93539e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs @@ -1001,7 +1001,7 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { self.with_impl_item(impl_def_id, |this, item| { if !this.has_applicable_self(item) { // No receiver declared. Not a candidate. - this.record_static_candidate(CandidateSource::Impl(impl_def_id)); + this.record_static_candidate(CandidateSource::Impl(impl_def_id.into())); return; } this.push_candidate( @@ -1490,7 +1490,7 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { /// so do not use to make a decision that may lead to a successful compilation. fn candidate_source(&self, candidate: &Candidate<'db>, self_ty: Ty<'db>) -> CandidateSource { match candidate.kind { - InherentImplCandidate { impl_def_id, .. } => CandidateSource::Impl(impl_def_id), + InherentImplCandidate { impl_def_id, .. } => CandidateSource::Impl(impl_def_id.into()), ObjectCandidate(trait_ref) | WhereClauseCandidate(trait_ref) => { CandidateSource::Trait(trait_ref.def_id().0) } @@ -1524,7 +1524,7 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { fn candidate_source_from_pick(&self, pick: &Pick<'db>) -> CandidateSource { match pick.kind { - InherentImplPick(impl_) => CandidateSource::Impl(impl_), + InherentImplPick(impl_) => CandidateSource::Impl(impl_.into()), ObjectPick(trait_) | TraitPick(trait_) => CandidateSource::Trait(trait_), WhereClausePick(trait_ref) => CandidateSource::Trait(trait_ref.skip_binder().def_id.0), } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs index b6167b4a097c..aa6caefc4a06 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/def_id.rs @@ -1,9 +1,9 @@ //! Definition of `SolverDefId` use hir_def::{ - AdtId, AttrDefId, CallableDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, - GeneralConstId, GenericDefId, HasModule, ImplId, ModuleId, StaticId, StructId, TraitId, - TypeAliasId, UnionId, db::DefDatabase, + AdtId, AttrDefId, BuiltinDeriveImplId, CallableDefId, ConstId, DefWithBodyId, EnumId, + EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId, StaticId, StructId, TraitId, + TypeAliasId, UnionId, }; use rustc_type_ir::inherent; use stdx::impl_from; @@ -24,6 +24,7 @@ pub enum SolverDefId { ConstId(ConstId), FunctionId(FunctionId), ImplId(ImplId), + BuiltinDeriveImplId(BuiltinDeriveImplId), StaticId(StaticId), TraitId(TraitId), TypeAliasId(TypeAliasId), @@ -57,6 +58,7 @@ impl std::fmt::Debug for SolverDefId { f.debug_tuple("FunctionId").field(&db.function_signature(id).name.as_str()).finish() } SolverDefId::ImplId(id) => f.debug_tuple("ImplId").field(&id).finish(), + SolverDefId::BuiltinDeriveImplId(id) => f.debug_tuple("ImplId").field(&id).finish(), SolverDefId::StaticId(id) => { f.debug_tuple("StaticId").field(&db.static_signature(id).name.as_str()).finish() } @@ -108,6 +110,7 @@ impl_from!( ConstId, FunctionId, ImplId, + BuiltinDeriveImplId, StaticId, TraitId, TypeAliasId, @@ -170,7 +173,8 @@ impl TryFrom for AttrDefId { SolverDefId::EnumVariantId(it) => Ok(it.into()), SolverDefId::Ctor(Ctor::Struct(it)) => Ok(it.into()), SolverDefId::Ctor(Ctor::Enum(it)) => Ok(it.into()), - SolverDefId::InternedClosureId(_) + SolverDefId::BuiltinDeriveImplId(_) + | SolverDefId::InternedClosureId(_) | SolverDefId::InternedCoroutineId(_) | SolverDefId::InternedOpaqueTyId(_) => Err(()), } @@ -191,6 +195,7 @@ impl TryFrom for DefWithBodyId { | SolverDefId::TraitId(_) | SolverDefId::TypeAliasId(_) | SolverDefId::ImplId(_) + | SolverDefId::BuiltinDeriveImplId(_) | SolverDefId::InternedClosureId(_) | SolverDefId::InternedCoroutineId(_) | SolverDefId::Ctor(Ctor::Struct(_)) @@ -216,6 +221,7 @@ impl TryFrom for GenericDefId { | SolverDefId::InternedCoroutineId(_) | SolverDefId::InternedOpaqueTyId(_) | SolverDefId::EnumVariantId(_) + | SolverDefId::BuiltinDeriveImplId(_) | SolverDefId::Ctor(_) => return Err(()), }) } @@ -241,28 +247,6 @@ impl SolverDefId { } } -impl HasModule for SolverDefId { - fn module(&self, db: &dyn DefDatabase) -> ModuleId { - match *self { - SolverDefId::AdtId(id) => id.module(db), - SolverDefId::ConstId(id) => id.module(db), - SolverDefId::FunctionId(id) => id.module(db), - SolverDefId::ImplId(id) => id.module(db), - SolverDefId::StaticId(id) => id.module(db), - SolverDefId::TraitId(id) => id.module(db), - SolverDefId::TypeAliasId(id) => id.module(db), - SolverDefId::InternedClosureId(id) => id.loc(db).0.module(db), - SolverDefId::InternedCoroutineId(id) => id.loc(db).0.module(db), - SolverDefId::InternedOpaqueTyId(id) => match id.loc(db) { - crate::ImplTraitId::ReturnTypeImplTrait(owner, _) => owner.module(db), - crate::ImplTraitId::TypeAliasImplTrait(owner, _) => owner.module(db), - }, - SolverDefId::Ctor(Ctor::Enum(id)) | SolverDefId::EnumVariantId(id) => id.module(db), - SolverDefId::Ctor(Ctor::Struct(id)) => id.module(db), - } - } -} - impl<'db> inherent::DefId> for SolverDefId { fn as_local(self) -> Option { Some(self) @@ -332,7 +316,6 @@ declare_id_wrapper!(TypeAliasIdWrapper, TypeAliasId); declare_id_wrapper!(ClosureIdWrapper, InternedClosureId); declare_id_wrapper!(CoroutineIdWrapper, InternedCoroutineId); declare_id_wrapper!(AdtIdWrapper, AdtId); -declare_id_wrapper!(ImplIdWrapper, ImplId); #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct GeneralConstIdWrapper(pub GeneralConstId); @@ -433,3 +416,40 @@ impl<'db> inherent::DefId> for CallableIdWrapper { true } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum AnyImplId { + ImplId(ImplId), + BuiltinDeriveImplId(BuiltinDeriveImplId), +} + +impl_from!(ImplId, BuiltinDeriveImplId for AnyImplId); + +impl From for SolverDefId { + #[inline] + fn from(value: AnyImplId) -> SolverDefId { + match value { + AnyImplId::ImplId(it) => it.into(), + AnyImplId::BuiltinDeriveImplId(it) => it.into(), + } + } +} +impl TryFrom for AnyImplId { + type Error = (); + #[inline] + fn try_from(value: SolverDefId) -> Result { + match value { + SolverDefId::ImplId(it) => Ok(it.into()), + SolverDefId::BuiltinDeriveImplId(it) => Ok(it.into()), + _ => Err(()), + } + } +} +impl<'db> inherent::DefId> for AnyImplId { + fn as_local(self) -> Option { + Some(self.into()) + } + fn is_local(self) -> bool { + true + } +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs index 4d164a7e3bc5..a8288b4e8259 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/generics.rs @@ -4,14 +4,15 @@ use hir_def::{ ConstParamId, GenericDefId, GenericParamId, LifetimeParamId, TypeOrConstParamId, TypeParamId, hir::generics::{GenericParams, TypeOrConstParamData}, }; +use rustc_type_ir::inherent::GenericsOf; -use crate::{db::HirDatabase, generics::parent_generic_def}; +use crate::generics::parent_generic_def; use super::SolverDefId; use super::DbInterner; -pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics { +pub(crate) fn generics(interner: DbInterner<'_>, def: SolverDefId) -> Generics { let mk_lt = |parent, index, local_id| { let id = GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id }); GenericParamDef { index, id } @@ -50,6 +51,7 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics { result }; + let db = interner.db; let (parent, own_params) = match (def.try_into(), def) { (Ok(def), _) => ( parent_generic_def(db, def), @@ -66,9 +68,12 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics { } } } + (_, SolverDefId::BuiltinDeriveImplId(id)) => { + return crate::builtin_derive::generics_of(interner, id); + } _ => panic!("No generics for {def:?}"), }; - let parent_generics = parent.map(|def| Box::new(generics(db, def.into()))); + let parent_generics = parent.map(|def| Box::new(generics(interner, def.into()))); Generics { parent, @@ -84,6 +89,13 @@ pub struct Generics { pub own_params: Vec, } +impl Generics { + pub(crate) fn push_param(&mut self, id: GenericParamId) { + let index = self.count() as u32; + self.own_params.push(GenericParamDef { index, id }); + } +} + #[derive(Debug)] pub struct GenericParamDef { index: u32, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/select.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/select.rs index 52ad410df6be..bd407fd15718 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/select.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/select.rs @@ -2,7 +2,7 @@ use std::ops::ControlFlow; -use hir_def::{ImplId, TraitId}; +use hir_def::TraitId; use macros::{TypeFoldable, TypeVisitable}; use rustc_type_ir::{ Interner, @@ -12,7 +12,7 @@ use rustc_type_ir::{ use crate::{ db::InternedOpaqueTyId, next_solver::{ - Const, ErrorGuaranteed, GenericArgs, Goal, TraitRef, Ty, TypeError, + AnyImplId, Const, ErrorGuaranteed, GenericArgs, Goal, TraitRef, Ty, TypeError, infer::{ InferCtxt, select::EvaluationResult::*, @@ -249,7 +249,7 @@ impl<'db, N> ImplSource<'db, N> { pub(crate) struct ImplSourceUserDefinedData<'db, N> { #[type_visitable(ignore)] #[type_foldable(identity)] - pub(crate) impl_def_id: ImplId, + pub(crate) impl_def_id: AnyImplId, pub(crate) args: GenericArgs<'db>, pub(crate) nested: Vec, } @@ -395,7 +395,7 @@ fn to_selection<'db>(cand: InspectCandidate<'_, 'db>) -> Option> // FIXME: Remove this in favor of storing this in the tree // For impl candidates, we do the rematch manually to compute the args. ImplSource::UserDefined(ImplSourceUserDefinedData { - impl_def_id: impl_def_id.0, + impl_def_id, args: cand.instantiate_impl_args(), nested, }) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 2ebc5b81ba5c..269474e0153e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -38,10 +38,10 @@ use crate::{ lower::GenericPredicates, method_resolution::TraitImpls, next_solver::{ - AdtIdWrapper, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper, - CoroutineIdWrapper, Ctor, FnSig, FxIndexMap, GeneralConstIdWrapper, ImplIdWrapper, - OpaqueTypeKey, RegionAssumptions, SimplifiedType, SolverContext, SolverDefIds, - TraitIdWrapper, TypeAliasIdWrapper, UnevaluatedConst, util::explicit_item_bounds, + AdtIdWrapper, AnyImplId, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper, + CoroutineIdWrapper, Ctor, FnSig, FxIndexMap, GeneralConstIdWrapper, OpaqueTypeKey, + RegionAssumptions, SimplifiedType, SolverContext, SolverDefIds, TraitIdWrapper, + TypeAliasIdWrapper, UnevaluatedConst, util::explicit_item_bounds, }, }; @@ -1020,7 +1020,7 @@ impl<'db> Interner for DbInterner<'db> { type CoroutineClosureId = CoroutineIdWrapper; type CoroutineId = CoroutineIdWrapper; type AdtId = AdtIdWrapper; - type ImplId = ImplIdWrapper; + type ImplId = AnyImplId; type UnevaluatedConstId = GeneralConstIdWrapper; type Span = Span; @@ -1164,7 +1164,7 @@ impl<'db> Interner for DbInterner<'db> { } fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf { - generics(self.db(), def_id) + generics(self, def_id) } fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf { @@ -1190,6 +1190,7 @@ impl<'db> Interner for DbInterner<'db> { | SolverDefId::TraitId(_) | SolverDefId::TypeAliasId(_) | SolverDefId::ImplId(_) + | SolverDefId::BuiltinDeriveImplId(_) | SolverDefId::InternedClosureId(_) | SolverDefId::InternedCoroutineId(_) => { return VariancesOf::empty(self); @@ -1327,6 +1328,7 @@ impl<'db> Interner for DbInterner<'db> { | SolverDefId::AdtId(_) | SolverDefId::TraitId(_) | SolverDefId::ImplId(_) + | SolverDefId::BuiltinDeriveImplId(_) | SolverDefId::EnumVariantId(..) | SolverDefId::Ctor(..) | SolverDefId::InternedOpaqueTyId(..) => panic!(), @@ -1445,8 +1447,7 @@ impl<'db> Interner for DbInterner<'db> { self, def_id: Self::DefId, ) -> EarlyBinder> { - GenericPredicates::query_all(self.db, def_id.try_into().unwrap()) - .map_bound(|it| it.iter().copied()) + predicates_of(self.db, def_id).all_predicates().map_bound(|it| it.iter().copied()) } #[tracing::instrument(level = "debug", skip(self), ret)] @@ -1454,8 +1455,7 @@ impl<'db> Interner for DbInterner<'db> { self, def_id: Self::DefId, ) -> EarlyBinder> { - GenericPredicates::query_own(self.db, def_id.try_into().unwrap()) - .map_bound(|it| it.iter().copied()) + predicates_of(self.db, def_id).own_predicates().map_bound(|it| it.iter().copied()) } #[tracing::instrument(skip(self), ret)] @@ -1500,32 +1500,30 @@ impl<'db> Interner for DbInterner<'db> { } } - GenericPredicates::query_explicit(self.db, def_id.try_into().unwrap()).map_bound( - |predicates| { - predicates - .iter() - .copied() - .filter(|p| match p.kind().skip_binder() { - ClauseKind::Trait(it) => is_self_or_assoc(it.self_ty()), - ClauseKind::TypeOutlives(it) => is_self_or_assoc(it.0), - ClauseKind::Projection(it) => is_self_or_assoc(it.self_ty()), - ClauseKind::HostEffect(it) => is_self_or_assoc(it.self_ty()), - // FIXME: Not sure is this correct to allow other clauses but we might replace - // `generic_predicates_ns` query here with something closer to rustc's - // `implied_bounds_with_filter`, which is more granular lowering than this - // "lower at once and then filter" implementation. - _ => true, - }) - .map(|p| (p, Span::dummy())) - }, - ) + predicates_of(self.db, def_id).explicit_predicates().map_bound(|predicates| { + predicates + .iter() + .copied() + .filter(|p| match p.kind().skip_binder() { + ClauseKind::Trait(it) => is_self_or_assoc(it.self_ty()), + ClauseKind::TypeOutlives(it) => is_self_or_assoc(it.0), + ClauseKind::Projection(it) => is_self_or_assoc(it.self_ty()), + ClauseKind::HostEffect(it) => is_self_or_assoc(it.self_ty()), + // FIXME: Not sure is this correct to allow other clauses but we might replace + // `generic_predicates_ns` query here with something closer to rustc's + // `implied_bounds_with_filter`, which is more granular lowering than this + // "lower at once and then filter" implementation. + _ => true, + }) + .map(|p| (p, Span::dummy())) + }) } fn impl_super_outlives( self, impl_id: Self::ImplId, ) -> EarlyBinder> { - let trait_ref = self.db().impl_trait(impl_id.0).expect("expected an impl of trait"); + let trait_ref = self.impl_trait_ref(impl_id); trait_ref.map_bound(|trait_ref| { let clause: Clause<'_> = trait_ref.upcast(self); elaborate(self, [clause]).filter(|clause| { @@ -1790,6 +1788,7 @@ impl<'db> Interner for DbInterner<'db> { SolverDefId::ConstId(_) | SolverDefId::FunctionId(_) | SolverDefId::ImplId(_) + | SolverDefId::BuiltinDeriveImplId(_) | SolverDefId::StaticId(_) | SolverDefId::InternedClosureId(_) | SolverDefId::InternedCoroutineId(_) @@ -1805,7 +1804,12 @@ impl<'db> Interner for DbInterner<'db> { type_block, trait_block, &mut |impls| { - for &impl_ in impls.for_trait_and_self_ty(trait_def_id.0, &simp) { + let (regular_impls, builtin_derive_impls) = + impls.for_trait_and_self_ty(trait_def_id.0, &simp); + for &impl_ in regular_impls { + f(impl_.into()); + } + for &impl_ in builtin_derive_impls { f(impl_.into()); } }, @@ -1927,7 +1931,10 @@ impl<'db> Interner for DbInterner<'db> { } fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool { - self.db.impl_signature(impl_def_id.0).is_default() + match impl_def_id { + AnyImplId::ImplId(impl_id) => self.db.impl_signature(impl_id).is_default(), + AnyImplId::BuiltinDeriveImplId(_) => false, + } } #[tracing::instrument(skip(self), ret)] @@ -1935,14 +1942,24 @@ impl<'db> Interner for DbInterner<'db> { self, impl_id: Self::ImplId, ) -> EarlyBinder> { - let db = self.db(); - db.impl_trait(impl_id.0) - // ImplIds for impls where the trait ref can't be resolved should never reach trait solving - .expect("invalid impl passed to trait solver") + match impl_id { + AnyImplId::ImplId(impl_id) => { + let db = self.db(); + db.impl_trait(impl_id) + // ImplIds for impls where the trait ref can't be resolved should never reach trait solving + .expect("invalid impl passed to trait solver") + } + AnyImplId::BuiltinDeriveImplId(impl_id) => { + crate::builtin_derive::impl_trait(self, impl_id) + } + } } fn impl_polarity(self, impl_id: Self::ImplId) -> rustc_type_ir::ImplPolarity { - let impl_data = self.db().impl_signature(impl_id.0); + let AnyImplId::ImplId(impl_id) = impl_id else { + return ImplPolarity::Positive; + }; + let impl_data = self.db().impl_signature(impl_id); if impl_data.flags.contains(ImplFlags::NEGATIVE) { ImplPolarity::Negative } else { @@ -2230,11 +2247,13 @@ impl<'db> Interner for DbInterner<'db> { specializing_impl_def_id: Self::ImplId, parent_impl_def_id: Self::ImplId, ) -> bool { - crate::specialization::specializes( - self.db, - specializing_impl_def_id.0, - parent_impl_def_id.0, - ) + let (AnyImplId::ImplId(specializing_impl_def_id), AnyImplId::ImplId(parent_impl_def_id)) = + (specializing_impl_def_id, parent_impl_def_id) + else { + // No builtin derive allow specialization currently. + return false; + }; + crate::specialization::specializes(self.db, specializing_impl_def_id, parent_impl_def_id) } fn next_trait_solver_globally(self) -> bool { @@ -2349,6 +2368,14 @@ impl<'db> DbInterner<'db> { } } +fn predicates_of(db: &dyn HirDatabase, def_id: SolverDefId) -> &GenericPredicates { + if let SolverDefId::BuiltinDeriveImplId(impl_) = def_id { + crate::builtin_derive::builtin_derive_predicates(db, impl_) + } else { + GenericPredicates::query(db, def_id.try_into().unwrap()) + } +} + macro_rules! TrivialTypeTraversalImpls { ($($ty:ty,)+) => { $( @@ -2396,7 +2423,7 @@ TrivialTypeTraversalImpls! { ClosureIdWrapper, CoroutineIdWrapper, AdtIdWrapper, - ImplIdWrapper, + AnyImplId, GeneralConstIdWrapper, Safety, FnAbi, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs index d800925ba4e9..21fbd64dd066 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/solver.rs @@ -12,7 +12,7 @@ use rustc_type_ir::{ use tracing::debug; use crate::next_solver::{ - AliasTy, CanonicalVarKind, Clause, ClauseKind, CoercePredicate, GenericArgs, ImplIdWrapper, + AliasTy, AnyImplId, CanonicalVarKind, Clause, ClauseKind, CoercePredicate, GenericArgs, ParamEnv, Predicate, PredicateKind, SubtypePredicate, Ty, TyKind, fold::fold_tys, util::sizedness_fast_path, }; @@ -174,9 +174,13 @@ impl<'db> SolverDelegate for SolverContext<'db> { &self, _goal_trait_ref: rustc_type_ir::TraitRef, trait_assoc_def_id: SolverDefId, - impl_id: ImplIdWrapper, + impl_id: AnyImplId, ) -> Result, ErrorGuaranteed> { - let impl_items = impl_id.0.impl_items(self.0.interner.db()); + let AnyImplId::ImplId(impl_id) = impl_id else { + // Builtin derive traits don't have type/consts assoc items. + return Ok(None); + }; + let impl_items = impl_id.impl_items(self.0.interner.db()); let id = match trait_assoc_def_id { SolverDefId::TypeAliasId(trait_assoc_id) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index 6558d2179fba..ea33c9bcd4f1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -243,6 +243,10 @@ $0", "parse_shim", "real_span_map_shim", "TraitImpls::for_crate_", + "lang_items", + "crate_lang_items", + "AttrFlags::query_", + "AttrFlags::query_", ] "#]], ); @@ -279,6 +283,10 @@ pub struct NewStruct { "real_span_map_shim", "crate_local_def_map", "TraitImpls::for_crate_", + "crate_lang_items", + "AttrFlags::query_", + "AttrFlags::query_", + "AttrFlags::query_", ] "#]], ); @@ -314,6 +322,10 @@ $0", "parse_shim", "real_span_map_shim", "TraitImpls::for_crate_", + "lang_items", + "crate_lang_items", + "AttrFlags::query_", + "AttrFlags::query_", ] "#]], ); @@ -351,6 +363,13 @@ pub enum SomeEnum { "real_span_map_shim", "crate_local_def_map", "TraitImpls::for_crate_", + "crate_lang_items", + "AttrFlags::query_", + "AttrFlags::query_", + "AttrFlags::query_", + "EnumVariants::of_", + "AttrFlags::query_", + "AttrFlags::query_", ] "#]], ); @@ -386,6 +405,10 @@ $0", "parse_shim", "real_span_map_shim", "TraitImpls::for_crate_", + "lang_items", + "crate_lang_items", + "AttrFlags::query_", + "AttrFlags::query_", ] "#]], ); @@ -420,6 +443,9 @@ fn bar() -> f32 { "real_span_map_shim", "crate_local_def_map", "TraitImpls::for_crate_", + "crate_lang_items", + "AttrFlags::query_", + "AttrFlags::query_", ] "#]], ); @@ -459,6 +485,11 @@ $0", "parse_shim", "real_span_map_shim", "TraitImpls::for_crate_", + "lang_items", + "crate_lang_items", + "AttrFlags::query_", + "AttrFlags::query_", + "AttrFlags::query_", ] "#]], ); @@ -501,17 +532,16 @@ impl SomeStruct { "real_span_map_shim", "crate_local_def_map", "TraitImpls::for_crate_", - "AttrFlags::query_", - "impl_trait_with_diagnostics_query", - "impl_signature_shim", - "impl_signature_with_source_map_shim", - "lang_items", "crate_lang_items", + "AttrFlags::query_", "ImplItems::of_", "AttrFlags::query_", "AttrFlags::query_", "AttrFlags::query_", "AttrFlags::query_", + "impl_trait_with_diagnostics_shim", + "impl_signature_shim", + "impl_signature_with_source_map_shim", "impl_self_ty_with_diagnostics_query", "struct_signature_shim", "struct_signature_with_source_map_shim", diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 6e9c6d26b5b1..aa7e40c65848 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -525,5 +525,7 @@ define_symbols! { arbitrary_self_types, arbitrary_self_types_pointers, supertrait_item_shadowing, + hash, + cmp, define_opaque, } From b2f19eac2f139d35d9398ba2e90c2c424e84792b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heath=20Dutton=F0=9F=95=B4=EF=B8=8F?= Date: Wed, 24 Dec 2025 23:41:40 -0500 Subject: [PATCH 1237/3801] rustdoc: fix duplicate Re-exports sections When a module contains both `pub extern crate` and `pub use` items, they were being rendered under two separate "Re-exports" section headers instead of one. This happened because the code iterated over each ItemType separately and rendered a section header for each, even though both ExternCrate and Import map to the same ItemSection. This fix tracks the current section and only renders a new header when the section actually changes, consolidating items that belong to the same section under a single header. --- src/librustdoc/html/render/print_item.rs | 39 ++++++++++++++----- .../duplicate-reexports-section-150211.rs | 19 +++++++++ 2 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 tests/rustdoc/extern/duplicate-reexports-section-150211.rs diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 0b52c0b56b82..ccf6490877d6 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -398,18 +398,34 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i let mut types = not_stripped_items.keys().copied().collect::>(); types.sort_unstable_by(|a, b| reorder(*a).cmp(&reorder(*b))); + let mut last_section: Option = None; + for type_ in types { let my_section = item_ty_to_section(type_); - let tag = if my_section == super::ItemSection::Reexports { - REEXPORTS_TABLE_OPEN - } else { - ITEM_TABLE_OPEN - }; - write!( - w, - "{}", - write_section_heading(my_section.name(), &cx.derive_id(my_section.id()), None, tag) - )?; + + // Only render section heading if the section changed + if last_section != Some(my_section) { + // Close the previous section if there was one + if last_section.is_some() { + w.write_str(ITEM_TABLE_CLOSE)?; + } + let tag = if my_section == super::ItemSection::Reexports { + REEXPORTS_TABLE_OPEN + } else { + ITEM_TABLE_OPEN + }; + write!( + w, + "{}", + write_section_heading( + my_section.name(), + &cx.derive_id(my_section.id()), + None, + tag + ) + )?; + last_section = Some(my_section); + } for (_, myitem) in ¬_stripped_items[&type_] { match myitem.kind { @@ -526,6 +542,9 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i } } } + } + // Close the final section + if last_section.is_some() { w.write_str(ITEM_TABLE_CLOSE)?; } diff --git a/tests/rustdoc/extern/duplicate-reexports-section-150211.rs b/tests/rustdoc/extern/duplicate-reexports-section-150211.rs new file mode 100644 index 000000000000..41f80cc6ab75 --- /dev/null +++ b/tests/rustdoc/extern/duplicate-reexports-section-150211.rs @@ -0,0 +1,19 @@ +//@ aux-build:pub-extern-crate.rs + +// Regression test for issue . +// When a module has both `pub extern crate` and `pub use` items, +// they should both appear under a single "Re-exports" section, +// not two separate sections. + +//@ has duplicate_reexports_section_150211/index.html +// Verify there's exactly one Re-exports section header +//@ count - '//h2[@id="reexports"]' 1 +//@ has - '//h2[@id="reexports"]' 'Re-exports' +// Verify both the extern crate and the use item are present +//@ has - '//code' 'pub extern crate inner;' +//@ has - '//code' 'pub use inner::SomeStruct;' + +pub extern crate inner; + +#[doc(no_inline)] +pub use inner::SomeStruct; From 328adc4d8b1c3c51eddfdd2bd12bed7a4c203981 Mon Sep 17 00:00:00 2001 From: jyn Date: Thu, 25 Dec 2025 13:10:17 -0500 Subject: [PATCH 1238/3801] rustdoc shim respects RUSTC_HOST_FLAGS --- src/bootstrap/src/bin/rustdoc.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/src/bin/rustdoc.rs b/src/bootstrap/src/bin/rustdoc.rs index 784041985b72..2925892fed28 100644 --- a/src/bootstrap/src/bin/rustdoc.rs +++ b/src/bootstrap/src/bin/rustdoc.rs @@ -40,6 +40,12 @@ fn main() { if !args.iter().any(|arg| arg == "--sysroot") { cmd.arg("--sysroot").arg(&sysroot); } + } else { + // Find any host flags that were passed by bootstrap. + // The flags are stored in a RUSTC_HOST_FLAGS variable, separated by spaces. + if let Ok(flags) = std::env::var("RUSTC_HOST_FLAGS") { + cmd.args(flags.split(' ')); + } } cmd.args(&args); From b460a1d5e2b6124596f37b49647d7da1aa21f8aa Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 25 Dec 2025 20:50:52 +0100 Subject: [PATCH 1239/3801] Bump nightly version -> 2025-12-25 --- clippy_utils/README.md | 2 +- rust-toolchain.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_utils/README.md b/clippy_utils/README.md index dc8695fef9f5..01257c1a3059 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-12-11 +nightly-2025-12-25 ``` diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 1384f4078ebe..dbec79e111fb 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-12-11" +channel = "nightly-2025-12-25" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" From 28d62f083376f956f28b6b3910446a2f171959b8 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 25 Dec 2025 20:51:01 +0100 Subject: [PATCH 1240/3801] Don't take rustc-literal-escaper from sysroot This resulted in the following error for me: error[E0464]: multiple candidates for `rlib` dependency `rustc_literal_escaper` found --> clippy_dev/src/lib.rs:25:1 | 25 | extern crate rustc_literal_escaper; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: candidate #1: /home/pkrones/.rustup/toolchains/nightly-2025-12-25-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_literal_escaper-4f30574e01c3dad1.rlib = note: candidate #2: /home/pkrones/.rustup/toolchains/nightly-2025-12-25-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_literal_escaper-c8a0e29ad1040cee.rmeta Other tools in the Rust repo also take that as an explicit dependency, like rust-analyzer or lint-docs. --- clippy_dev/Cargo.toml | 1 + clippy_dev/src/lib.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml index 10c08dba50b9..c2abbac37535 100644 --- a/clippy_dev/Cargo.toml +++ b/clippy_dev/Cargo.toml @@ -10,6 +10,7 @@ clap = { version = "4.4", features = ["derive"] } indoc = "1.0" itertools = "0.12" opener = "0.7" +rustc-literal-escaper = "0.0.5" walkdir = "2.3" [package.metadata.rust-analyzer] diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs index dcca08aee7e6..cd103908be03 100644 --- a/clippy_dev/src/lib.rs +++ b/clippy_dev/src/lib.rs @@ -22,7 +22,6 @@ extern crate rustc_arena; #[expect(unused_extern_crates, reason = "required to link to rustc crates")] extern crate rustc_driver; extern crate rustc_lexer; -extern crate rustc_literal_escaper; pub mod deprecate_lint; pub mod dogfood; From 40be1f8bc53e7815b7a229e8b3a2945353de3207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 25 Dec 2025 20:56:03 +0000 Subject: [PATCH 1241/3801] Tweak wording of diff marker diagnostic --- .../rustc_parse/src/parser/diagnostics.rs | 35 ++++++++++--------- tests/ui/parser/diff-markers/enum-2.stderr | 11 +++--- tests/ui/parser/diff-markers/enum.stderr | 11 +++--- tests/ui/parser/diff-markers/fn-arg.stderr | 11 +++--- .../parser/diff-markers/item-with-attr.stderr | 11 +++--- tests/ui/parser/diff-markers/item.stderr | 11 +++--- tests/ui/parser/diff-markers/statement.stderr | 11 +++--- .../ui/parser/diff-markers/struct-expr.stderr | 11 +++--- tests/ui/parser/diff-markers/struct.stderr | 11 +++--- .../ui/parser/diff-markers/trait-item.stderr | 11 +++--- .../parser/diff-markers/tuple-struct.stderr | 11 +++--- .../parser/diff-markers/use-statement.stderr | 11 +++--- 12 files changed, 62 insertions(+), 94 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index d7d343ac16b4..70ec80a50812 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -3084,22 +3084,24 @@ impl<'a> Parser<'a> { } let mut err = self.dcx().struct_span_fatal(spans, "encountered diff marker"); - match middlediff3 { + let middle_marker = match middlediff3 { // We're using diff3 Some(middlediff3) => { err.span_label( - start, - "between this marker and `|||||||` is the code that we're merging into", - ); - err.span_label(middlediff3, "between this marker and `=======` is the base code (what the two refs diverged from)"); - } - None => { - err.span_label( - start, - "between this marker and `=======` is the code that we're merging into", + middlediff3, + "between this marker and `=======` is the base code (what the two refs \ + diverged from)", ); + "|||||||" } + None => "=======", }; + err.span_label( + start, + format!( + "between this marker and `{middle_marker}` is the code that you are merging into", + ), + ); if let Some(middle) = middle { err.span_label(middle, "between this marker and `>>>>>>>` is the incoming code"); @@ -3114,16 +3116,15 @@ impl<'a> Parser<'a> { containing conflict markers", ); err.help( - "if you're having merge conflicts after pulling new code:\n\ - the top section is the code you already had and the bottom section is the remote code\n\ - if you're in the middle of a rebase:\n\ - the top section is the code being rebased onto and the bottom section is the code \ - coming from the current commit being rebased", + "if you are in a merge, the top section is the code you already had checked out and \ + the bottom section is the new code\n\ + if you are in a rebase, the top section is the code being rebased onto and the bottom \ + section is the code you had checked out which is being rebased", ); err.note( - "for an explanation on these markers from the `git` documentation:\n\ - visit ", + "for an explanation on these markers from the `git` documentation, visit \ + ", ); err.emit(); diff --git a/tests/ui/parser/diff-markers/enum-2.stderr b/tests/ui/parser/diff-markers/enum-2.stderr index b76cf5d5a01e..8f20e70922f9 100644 --- a/tests/ui/parser/diff-markers/enum-2.stderr +++ b/tests/ui/parser/diff-markers/enum-2.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/enum-2.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `|||||||` is the code that we're merging into + | ^^^^^^^ between this marker and `|||||||` is the code that you are merging into LL | x: u8, LL | ||||||| | ------- between this marker and `=======` is the base code (what the two refs diverged from) @@ -15,12 +15,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/enum.stderr b/tests/ui/parser/diff-markers/enum.stderr index 0ce473bc7023..67f7561fd77b 100644 --- a/tests/ui/parser/diff-markers/enum.stderr +++ b/tests/ui/parser/diff-markers/enum.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/enum.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | Foo(u8), LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/fn-arg.stderr b/tests/ui/parser/diff-markers/fn-arg.stderr index 24521ffa6262..e63592ecf426 100644 --- a/tests/ui/parser/diff-markers/fn-arg.stderr +++ b/tests/ui/parser/diff-markers/fn-arg.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/fn-arg.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | x: u8, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/item-with-attr.stderr b/tests/ui/parser/diff-markers/item-with-attr.stderr index 432673cd5518..29dbfab16fda 100644 --- a/tests/ui/parser/diff-markers/item-with-attr.stderr +++ b/tests/ui/parser/diff-markers/item-with-attr.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/item-with-attr.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | fn foo() {} LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/item.stderr b/tests/ui/parser/diff-markers/item.stderr index 180c74e5d696..8de41123c9e9 100644 --- a/tests/ui/parser/diff-markers/item.stderr +++ b/tests/ui/parser/diff-markers/item.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/item.rs:1:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | fn foo() {} LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/statement.stderr b/tests/ui/parser/diff-markers/statement.stderr index 6dccce4a48ee..5b5da0ede615 100644 --- a/tests/ui/parser/diff-markers/statement.stderr +++ b/tests/ui/parser/diff-markers/statement.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/statement.rs:10:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | S::foo(); LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/struct-expr.stderr b/tests/ui/parser/diff-markers/struct-expr.stderr index 3733cdd34964..d094cbcc9e8c 100644 --- a/tests/ui/parser/diff-markers/struct-expr.stderr +++ b/tests/ui/parser/diff-markers/struct-expr.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/struct-expr.rs:6:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | x: 42, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/struct.stderr b/tests/ui/parser/diff-markers/struct.stderr index 44f8346613e6..33999ff92b93 100644 --- a/tests/ui/parser/diff-markers/struct.stderr +++ b/tests/ui/parser/diff-markers/struct.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/struct.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | x: u8, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/trait-item.stderr b/tests/ui/parser/diff-markers/trait-item.stderr index 4361542c7743..6b89b800790c 100644 --- a/tests/ui/parser/diff-markers/trait-item.stderr +++ b/tests/ui/parser/diff-markers/trait-item.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/trait-item.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | fn foo() {} LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/tuple-struct.stderr b/tests/ui/parser/diff-markers/tuple-struct.stderr index 7fda24ba4853..a0c8b7f3700a 100644 --- a/tests/ui/parser/diff-markers/tuple-struct.stderr +++ b/tests/ui/parser/diff-markers/tuple-struct.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/tuple-struct.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | u8, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/use-statement.stderr b/tests/ui/parser/diff-markers/use-statement.stderr index 3eac7bebb5af..640f88f98057 100644 --- a/tests/ui/parser/diff-markers/use-statement.stderr +++ b/tests/ui/parser/diff-markers/use-statement.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/use-statement.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | bar, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error From 54e9e8cd3872be7ccf9e3b04559ea61441f258a8 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 25 Dec 2025 23:24:43 +0100 Subject: [PATCH 1242/3801] Merge commit '99edcadfd5f6f6e8da34b1ba62774b53f5ca3863' into clippy-subtree-update --- .github/workflows/clippy_dev.yml | 2 +- .github/workflows/clippy_pr.yml | 2 +- .github/workflows/remark.yml | 4 +- CHANGELOG.md | 1 + clippy_dev/Cargo.toml | 1 + clippy_dev/src/lib.rs | 1 - clippy_lints/src/assertions_on_constants.rs | 2 + clippy_lints/src/booleans.rs | 2 +- clippy_lints/src/casts/cast_precision_loss.rs | 22 +- clippy_lints/src/casts/mod.rs | 2 +- clippy_lints/src/casts/needless_type_cast.rs | 66 ++- clippy_lints/src/casts/ref_as_ptr.rs | 16 +- clippy_lints/src/collapsible_if.rs | 18 +- clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/disallowed_methods.rs | 3 + clippy_lints/src/empty_with_brackets.rs | 202 ++++--- clippy_lints/src/entry.rs | 8 +- clippy_lints/src/fallible_impl_from.rs | 2 +- clippy_lints/src/format_push_string.rs | 209 +++++-- clippy_lints/src/functions/mod.rs | 4 + clippy_lints/src/functions/result.rs | 43 +- clippy_lints/src/if_not_else.rs | 37 +- clippy_lints/src/if_then_some_else_none.rs | 32 +- clippy_lints/src/ifs/branches_sharing_code.rs | 75 ++- clippy_lints/src/implicit_hasher.rs | 23 +- clippy_lints/src/lib.rs | 7 +- clippy_lints/src/loops/for_kv_map.rs | 2 +- clippy_lints/src/loops/mod.rs | 46 +- clippy_lints/src/loops/never_loop.rs | 33 +- .../src/loops/unused_enumerate_index.rs | 12 +- clippy_lints/src/manual_let_else.rs | 2 +- .../src/matches/match_like_matches.rs | 18 +- clippy_lints/src/matches/match_wild_enum.rs | 2 +- clippy_lints/src/methods/expect_fun_call.rs | 10 +- clippy_lints/src/methods/iter_count.rs | 31 +- clippy_lints/src/methods/iter_kv_map.rs | 2 +- .../src/methods/join_absolute_paths.rs | 2 +- clippy_lints/src/methods/map_clone.rs | 2 +- clippy_lints/src/methods/map_unwrap_or.rs | 12 +- clippy_lints/src/methods/needless_collect.rs | 4 +- .../src/methods/obfuscated_if_else.rs | 16 +- clippy_lints/src/methods/or_then_unwrap.rs | 38 +- clippy_lints/src/methods/unnecessary_fold.rs | 179 +++--- .../src/methods/unnecessary_get_then_check.rs | 4 +- .../src/methods/unwrap_expect_used.rs | 24 +- clippy_lints/src/missing_fields_in_debug.rs | 12 +- .../src/multiple_unsafe_ops_per_block.rs | 70 ++- clippy_lints/src/needless_pass_by_ref_mut.rs | 21 +- clippy_lints/src/ptr/cmp_null.rs | 7 +- clippy_lints/src/ptr/mod.rs | 4 +- clippy_lints/src/same_length_and_capacity.rs | 105 ++++ clippy_lints/src/set_contains_or_insert.rs | 21 +- clippy_lints/src/time_subtraction.rs | 65 +- .../src/transmute/transmuting_null.rs | 9 +- clippy_lints/src/use_self.rs | 36 +- clippy_lints/src/write/empty_string.rs | 42 +- clippy_lints/src/zero_sized_map_values.rs | 2 +- .../src/almost_standard_lint_formulation.rs | 35 +- clippy_lints_internal/src/internal_paths.rs | 1 + clippy_lints_internal/src/lib.rs | 2 + .../src/repeated_is_diagnostic_item.rs | 561 ++++++++++++++++++ clippy_utils/README.md | 2 +- clippy_utils/src/attrs.rs | 2 +- clippy_utils/src/consts.rs | 14 +- clippy_utils/src/hir_utils.rs | 233 +++++++- clippy_utils/src/lib.rs | 3 +- clippy_utils/src/source.rs | 4 +- clippy_utils/src/sym.rs | 7 + rust-toolchain.toml | 2 +- .../repeated_is_diagnostic_item.fixed | 77 +++ .../repeated_is_diagnostic_item.rs | 77 +++ .../repeated_is_diagnostic_item.stderr | 82 +++ .../repeated_is_diagnostic_item_unfixable.rs | 213 +++++++ ...peated_is_diagnostic_item_unfixable.stderr | 374 ++++++++++++ .../collapsible_if/collapsible_else_if.fixed | 2 +- .../collapsible_if/collapsible_else_if.rs | 2 +- .../needless_pass_by_ref_mut.fixed | 2 +- .../needless_pass_by_ref_mut.rs | 2 +- .../needless_pass_by_ref_mut.stderr | 6 +- .../toml_disallowed_methods/clippy.toml | 2 + .../conf_disallowed_methods.rs | 16 + .../conf_disallowed_methods.stderr | 8 +- tests/ui/assertions_on_constants.rs | 5 + .../branches_sharing_code/shared_at_bottom.rs | 62 ++ .../shared_at_bottom.stderr | 70 ++- tests/ui/cast.stderr | 12 +- tests/ui/cast_size.r32bit.stderr | 12 +- tests/ui/cast_size.r64bit.stderr | 12 +- tests/ui/cmp_null.fixed | 20 + tests/ui/cmp_null.rs | 20 + tests/ui/cmp_null.stderr | 8 +- tests/ui/collapsible_else_if.fixed | 48 +- tests/ui/collapsible_else_if.rs | 50 +- tests/ui/collapsible_else_if.stderr | 24 +- tests/ui/crashes/ice-10148.stderr | 2 +- tests/ui/crashes/ice-7410.rs | 2 +- tests/ui/def_id_nocore.rs | 2 - tests/ui/def_id_nocore.stderr | 2 +- .../empty_enum_variants_with_brackets.fixed | 59 ++ tests/ui/empty_enum_variants_with_brackets.rs | 59 ++ .../empty_enum_variants_with_brackets.stderr | 67 ++- tests/ui/empty_loop_no_std.rs | 2 - tests/ui/empty_loop_no_std.stderr | 2 +- tests/ui/entry.fixed | 10 + tests/ui/entry.rs | 10 + tests/ui/entry.stderr | 23 +- tests/ui/format_push_string.fixed | 132 +++++ tests/ui/format_push_string.rs | 140 ++++- tests/ui/format_push_string.stderr | 205 +++++-- tests/ui/format_push_string_no_core.rs | 15 + tests/ui/format_push_string_no_std.fixed | 15 + tests/ui/format_push_string_no_std.rs | 15 + tests/ui/format_push_string_no_std.stderr | 17 + .../ui/format_push_string_no_std_unfixable.rs | 13 + ...format_push_string_no_std_unfixable.stderr | 17 + tests/ui/format_push_string_unfixable.rs | 144 +++++ tests/ui/format_push_string_unfixable.stderr | 233 ++++++++ tests/ui/if_not_else.fixed | 17 + tests/ui/if_not_else.rs | 17 + tests/ui/if_not_else.stderr | 44 +- tests/ui/if_then_some_else_none.fixed | 52 +- tests/ui/if_then_some_else_none.rs | 23 + tests/ui/if_then_some_else_none.stderr | 78 ++- tests/ui/manual_instant_elapsed.fixed | 16 + tests/ui/manual_instant_elapsed.rs | 16 + tests/ui/manual_instant_elapsed.stderr | 14 +- tests/ui/map_unwrap_or.stderr | 29 + tests/ui/match_like_matches_macro.fixed | 22 + tests/ui/match_like_matches_macro.rs | 25 + tests/ui/match_like_matches_macro.stderr | 62 +- tests/ui/multiple_unsafe_ops_per_block.rs | 133 +++++ tests/ui/multiple_unsafe_ops_per_block.stderr | 257 ++++++-- tests/ui/needless_collect.fixed | 5 + tests/ui/needless_collect.rs | 5 + tests/ui/needless_pass_by_ref_mut.stderr | 204 ++++--- tests/ui/needless_pass_by_ref_mut2.fixed | 6 + tests/ui/needless_pass_by_ref_mut2.rs | 6 + tests/ui/needless_pass_by_ref_mut2.stderr | 22 +- tests/ui/needless_type_cast.fixed | 87 +++ tests/ui/needless_type_cast.rs | 87 +++ tests/ui/needless_type_cast.stderr | 114 +++- tests/ui/needless_type_cast_unfixable.rs | 20 + tests/ui/needless_type_cast_unfixable.stderr | 17 + tests/ui/never_loop_iterator_reduction.rs | 17 + tests/ui/never_loop_iterator_reduction.stderr | 27 + tests/ui/obfuscated_if_else.fixed | 6 + tests/ui/obfuscated_if_else.rs | 6 + tests/ui/obfuscated_if_else.stderr | 8 +- tests/ui/println_empty_string.fixed | 20 + tests/ui/println_empty_string.rs | 24 + tests/ui/println_empty_string.stderr | 39 +- tests/ui/println_empty_string_unfixable.rs | 30 + .../ui/println_empty_string_unfixable.stderr | 85 +++ tests/ui/ref_as_ptr.fixed | 10 + tests/ui/ref_as_ptr.rs | 10 + tests/ui/ref_as_ptr.stderr | 60 +- tests/ui/result_large_err.rs | 9 + tests/ui/result_large_err.stderr | 18 +- tests/ui/same_length_and_capacity.rs | 27 + tests/ui/same_length_and_capacity.stderr | 20 + tests/ui/set_contains_or_insert.rs | 21 + tests/ui/set_contains_or_insert.stderr | 11 +- tests/ui/track-diagnostics.rs | 1 + tests/ui/transmuting_null.rs | 8 + tests/ui/transmuting_null.stderr | 8 +- tests/ui/unchecked_time_subtraction.fixed | 25 + tests/ui/unchecked_time_subtraction.rs | 25 + tests/ui/unchecked_time_subtraction.stderr | 26 +- tests/ui/unnecessary_fold.fixed | 85 +++ tests/ui/unnecessary_fold.rs | 85 +++ tests/ui/unnecessary_fold.stderr | 130 +++- tests/ui/use_self.fixed | 25 + tests/ui/use_self.rs | 25 + tests/ui/use_self.stderr | 84 +-- tests/ui/writeln_empty_string_unfixable.rs | 26 + .../ui/writeln_empty_string_unfixable.stderr | 47 ++ triagebot.toml | 1 + 177 files changed, 6336 insertions(+), 967 deletions(-) create mode 100644 clippy_lints/src/same_length_and_capacity.rs create mode 100644 clippy_lints_internal/src/repeated_is_diagnostic_item.rs create mode 100644 tests/ui-internal/repeated_is_diagnostic_item.fixed create mode 100644 tests/ui-internal/repeated_is_diagnostic_item.rs create mode 100644 tests/ui-internal/repeated_is_diagnostic_item.stderr create mode 100644 tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs create mode 100644 tests/ui-internal/repeated_is_diagnostic_item_unfixable.stderr create mode 100644 tests/ui/format_push_string.fixed create mode 100644 tests/ui/format_push_string_no_core.rs create mode 100644 tests/ui/format_push_string_no_std.fixed create mode 100644 tests/ui/format_push_string_no_std.rs create mode 100644 tests/ui/format_push_string_no_std.stderr create mode 100644 tests/ui/format_push_string_no_std_unfixable.rs create mode 100644 tests/ui/format_push_string_no_std_unfixable.stderr create mode 100644 tests/ui/format_push_string_unfixable.rs create mode 100644 tests/ui/format_push_string_unfixable.stderr create mode 100644 tests/ui/needless_type_cast_unfixable.rs create mode 100644 tests/ui/needless_type_cast_unfixable.stderr create mode 100644 tests/ui/never_loop_iterator_reduction.rs create mode 100644 tests/ui/never_loop_iterator_reduction.stderr create mode 100644 tests/ui/println_empty_string_unfixable.rs create mode 100644 tests/ui/println_empty_string_unfixable.stderr create mode 100644 tests/ui/same_length_and_capacity.rs create mode 100644 tests/ui/same_length_and_capacity.stderr create mode 100644 tests/ui/writeln_empty_string_unfixable.rs create mode 100644 tests/ui/writeln_empty_string_unfixable.stderr diff --git a/.github/workflows/clippy_dev.yml b/.github/workflows/clippy_dev.yml index d530eb6c73a3..3a99d65233d3 100644 --- a/.github/workflows/clippy_dev.yml +++ b/.github/workflows/clippy_dev.yml @@ -16,7 +16,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: # Unsetting this would make so that any malicious package could get our Github Token persist-credentials: false diff --git a/.github/workflows/clippy_pr.yml b/.github/workflows/clippy_pr.yml index d91c638a8fb5..f9e882d9757c 100644 --- a/.github/workflows/clippy_pr.yml +++ b/.github/workflows/clippy_pr.yml @@ -24,7 +24,7 @@ jobs: steps: # Setup - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: # Unsetting this would make so that any malicious package could get our Github Token persist-credentials: false diff --git a/.github/workflows/remark.yml b/.github/workflows/remark.yml index 03641a9aa62f..d4dc80efe79d 100644 --- a/.github/workflows/remark.yml +++ b/.github/workflows/remark.yml @@ -20,9 +20,9 @@ jobs: persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: - node-version: '20.x' + node-version: '24.x' - name: Install remark run: npm install remark-cli remark-lint remark-lint-maximum-line-length@^3.1.3 remark-preset-lint-recommended remark-gfm diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f666caf306f..91d793489be2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6916,6 +6916,7 @@ Released 2018-09-13 [`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#reversed_empty_ranges [`same_functions_in_if_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_functions_in_if_condition [`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push +[`same_length_and_capacity`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_length_and_capacity [`same_name_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_name_method [`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some [`seek_from_current`]: https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml index 10c08dba50b9..c2abbac37535 100644 --- a/clippy_dev/Cargo.toml +++ b/clippy_dev/Cargo.toml @@ -10,6 +10,7 @@ clap = { version = "4.4", features = ["derive"] } indoc = "1.0" itertools = "0.12" opener = "0.7" +rustc-literal-escaper = "0.0.5" walkdir = "2.3" [package.metadata.rust-analyzer] diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs index dcca08aee7e6..cd103908be03 100644 --- a/clippy_dev/src/lib.rs +++ b/clippy_dev/src/lib.rs @@ -22,7 +22,6 @@ extern crate rustc_arena; #[expect(unused_extern_crates, reason = "required to link to rustc crates")] extern crate rustc_driver; extern crate rustc_lexer; -extern crate rustc_literal_escaper; pub mod deprecate_lint; pub mod dogfood; diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs index 2586c89bc868..4aa55e53445c 100644 --- a/clippy_lints/src/assertions_on_constants.rs +++ b/clippy_lints/src/assertions_on_constants.rs @@ -3,6 +3,7 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::macros::{find_assert_args, root_macro_call_first_node}; use clippy_utils::msrvs::Msrv; +use clippy_utils::visitors::is_const_evaluatable; use clippy_utils::{is_inside_always_const_context, msrvs}; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; @@ -50,6 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants { _ => return, } && let Some((condition, _)) = find_assert_args(cx, e, macro_call.expn) + && is_const_evaluatable(cx, condition) && let Some((Constant::Bool(assert_val), const_src)) = ConstEvalCtxt::new(cx).eval_with_source(condition, macro_call.span.ctxt()) && let in_const_context = is_inside_always_const_context(cx.tcx, e.hir_id) diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index 902ba70577b9..a04a56d72bc0 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -433,7 +433,7 @@ fn simplify_not(cx: &LateContext<'_>, curr_msrv: Msrv, expr: &Expr<'_>) -> Optio }, ExprKind::MethodCall(path, receiver, args, _) => { let type_of_receiver = cx.typeck_results().expr_ty(receiver); - if !type_of_receiver.is_diag_item(cx, sym::Option) && !type_of_receiver.is_diag_item(cx, sym::Result) { + if !matches!(type_of_receiver.opt_diag_name(cx), Some(sym::Option | sym::Result)) { return None; } METHODS_WITH_NEGATION diff --git a/clippy_lints/src/casts/cast_precision_loss.rs b/clippy_lints/src/casts/cast_precision_loss.rs index 712e38db499f..748ab3163496 100644 --- a/clippy_lints/src/casts/cast_precision_loss.rs +++ b/clippy_lints/src/casts/cast_precision_loss.rs @@ -23,15 +23,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, ca let cast_to_f64 = to_nbits == 64; let mantissa_nbits = if cast_to_f64 { 52 } else { 23 }; - let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64; - let arch_dependent_str = "on targets with 64-bit wide pointers "; - let from_nbits_str = if arch_dependent { - "64".to_owned() - } else if is_isize_or_usize(cast_from) { - // FIXME: handle 16 bits `usize` type - "32 or 64".to_owned() + + let has_width = if is_isize_or_usize(cast_from) { + "can be up to 64 bits wide depending on the target architecture".to_owned() } else { - from_nbits.to_string() + format!("is {from_nbits} bits wide") }; span_lint( @@ -39,13 +35,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, ca CAST_PRECISION_LOSS, expr.span, format!( - "casting `{0}` to `{1}` causes a loss of precision {2}(`{0}` is {3} bits wide, \ - but `{1}`'s mantissa is only {4} bits wide)", - cast_from, - if cast_to_f64 { "f64" } else { "f32" }, - if arch_dependent { arch_dependent_str } else { "" }, - from_nbits_str, - mantissa_nbits + "casting `{cast_from}` to `{cast_to}` may cause a loss of precision \ + (`{cast_from}` {has_width}, \ + but `{cast_to}`'s mantissa is only {mantissa_nbits} bits wide)", ), ); } diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 494d6180d3cb..7220a8a80066 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -836,7 +836,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.93.0"] pub NEEDLESS_TYPE_CAST, - pedantic, + nursery, "binding defined with one type but always cast to another" } diff --git a/clippy_lints/src/casts/needless_type_cast.rs b/clippy_lints/src/casts/needless_type_cast.rs index ca6aa0f87bbf..1d899a21c229 100644 --- a/clippy_lints/src/casts/needless_type_cast.rs +++ b/clippy_lints/src/casts/needless_type_cast.rs @@ -1,6 +1,8 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::sugg::Sugg; use clippy_utils::visitors::{Descend, for_each_expr, for_each_expr_without_closures}; use core::ops::ControlFlow; +use rustc_ast::ast::{LitFloatType, LitIntType, LitKind}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; @@ -14,6 +16,7 @@ use super::NEEDLESS_TYPE_CAST; struct BindingInfo<'a> { source_ty: Ty<'a>, ty_span: Span, + init: Option<&'a Expr<'a>>, } struct UsageInfo<'a> { @@ -73,6 +76,7 @@ fn collect_binding_from_let<'a>( BindingInfo { source_ty: ty, ty_span: ty_hir.span, + init: Some(let_expr.init), }, ); } @@ -103,6 +107,7 @@ fn collect_binding_from_local<'a>( BindingInfo { source_ty: ty, ty_span: ty_hir.span, + init: let_stmt.init, }, ); } @@ -182,12 +187,7 @@ fn is_generic_res(cx: &LateContext<'_>, res: Res) -> bool { .iter() .any(|p| p.kind.is_ty_or_const()) }; - match res { - Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => has_type_params(def_id), - // Ctor → Variant → ADT: constructor's parent is variant, variant's parent is the ADT - Res::Def(DefKind::Ctor(..), def_id) => has_type_params(cx.tcx.parent(cx.tcx.parent(def_id))), - _ => false, - } + cx.tcx.res_generics_def_id(res).is_some_and(has_type_params) } fn is_cast_in_generic_context<'a>(cx: &LateContext<'a>, cast_expr: &Expr<'a>) -> bool { @@ -234,6 +234,18 @@ fn is_cast_in_generic_context<'a>(cx: &LateContext<'a>, cast_expr: &Expr<'a>) -> } } +fn can_coerce_to_target_type(expr: &Expr<'_>) -> bool { + match expr.kind { + ExprKind::Lit(lit) => matches!( + lit.node, + LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed) + ), + ExprKind::Unary(rustc_hir::UnOp::Neg, inner) => can_coerce_to_target_type(inner), + ExprKind::Binary(_, lhs, rhs) => can_coerce_to_target_type(lhs) && can_coerce_to_target_type(rhs), + _ => false, + } +} + fn check_binding_usages<'a>(cx: &LateContext<'a>, body: &Body<'a>, hir_id: HirId, binding_info: &BindingInfo<'a>) { let mut usages = Vec::new(); @@ -274,7 +286,19 @@ fn check_binding_usages<'a>(cx: &LateContext<'a>, body: &Body<'a>, hir_id: HirId return; }; - span_lint_and_sugg( + // Don't lint if there's exactly one use and the initializer cannot be coerced to the + // target type (i.e., would require an explicit cast). In such cases, the fix would add + // a cast to the initializer rather than eliminating one - the cast isn't truly "needless." + // See: https://github.com/rust-lang/rust-clippy/issues/16240 + if usages.len() == 1 + && binding_info + .init + .is_some_and(|init| !can_coerce_to_target_type(init) && !init.span.from_expansion()) + { + return; + } + + span_lint_and_then( cx, NEEDLESS_TYPE_CAST, binding_info.ty_span, @@ -282,8 +306,28 @@ fn check_binding_usages<'a>(cx: &LateContext<'a>, body: &Body<'a>, hir_id: HirId "this binding is defined as `{}` but is always cast to `{}`", binding_info.source_ty, first_target ), - "consider defining it as", - first_target.to_string(), - Applicability::MaybeIncorrect, + |diag| { + if let Some(init) = binding_info + .init + .filter(|i| !can_coerce_to_target_type(i) && !i.span.from_expansion()) + { + let sugg = Sugg::hir(cx, init, "..").as_ty(first_target); + diag.multipart_suggestion( + format!("consider defining it as `{first_target}` and casting the initializer"), + vec![ + (binding_info.ty_span, first_target.to_string()), + (init.span, sugg.to_string()), + ], + Applicability::MachineApplicable, + ); + } else { + diag.span_suggestion( + binding_info.ty_span, + "consider defining it as", + first_target.to_string(), + Applicability::MachineApplicable, + ); + } + }, ); } diff --git a/clippy_lints/src/casts/ref_as_ptr.rs b/clippy_lints/src/casts/ref_as_ptr.rs index 592c820a25e1..b3805c678174 100644 --- a/clippy_lints/src/casts/ref_as_ptr.rs +++ b/clippy_lints/src/casts/ref_as_ptr.rs @@ -1,9 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; -use clippy_utils::{ExprUseNode, expr_use_ctxt, std_or_core}; +use clippy_utils::{ExprUseNode, expr_use_ctxt, is_expr_temporary_value, std_or_core}; use rustc_errors::Applicability; -use rustc_hir::{Expr, Mutability, Ty, TyKind}; +use rustc_hir::{Expr, ExprKind, Mutability, Ty, TyKind}; use rustc_lint::LateContext; use rustc_middle::ty; @@ -23,10 +23,18 @@ pub(super) fn check<'tcx>( if matches!(cast_from.kind(), ty::Ref(..)) && let ty::RawPtr(_, to_mutbl) = cast_to.kind() && let use_cx = expr_use_ctxt(cx, expr) - // TODO: only block the lint if `cast_expr` is a temporary - && !matches!(use_cx.use_node(cx), ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_)) && let Some(std_or_core) = std_or_core(cx) { + if let ExprKind::AddrOf(_, _, addr_inner) = cast_expr.kind + && is_expr_temporary_value(cx, addr_inner) + && matches!( + use_cx.use_node(cx), + ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_) + ) + { + return; + } + let fn_name = match to_mutbl { Mutability::Not => "from_ref", Mutability::Mut => "from_mut", diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index b13e307a3f9c..be07ce1272bd 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -76,7 +76,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.51.0"] pub COLLAPSIBLE_ELSE_IF, - style, + pedantic, "nested `else`-`if` expressions that can be collapsed (e.g., `else { if x { ... } }`)" } @@ -267,6 +267,9 @@ impl LateLintPass<'_> for CollapsibleIf { && !expr.span.from_expansion() { if let Some(else_) = else_ + // Short circuit if both `if` branches contain only a single `if {..} else {}`, as + // collapsing such blocks can lead to less readable code (#4971) + && !(single_inner_if_else(then) && single_inner_if_else(else_)) && let ExprKind::Block(else_, None) = else_.kind { self.check_collapsible_else_if(cx, then.span, else_); @@ -280,6 +283,19 @@ impl LateLintPass<'_> for CollapsibleIf { } } +/// Returns true if `expr` is a block that contains only one `if {..} else {}` statement +fn single_inner_if_else(expr: &Expr<'_>) -> bool { + if let ExprKind::Block(block, None) = expr.kind + && let Some(inner_expr) = expr_block(block) + && let ExprKind::If(_, _, else_) = inner_expr.kind + && else_.is_some() + { + true + } else { + false + } +} + /// If `block` is a block with either one expression or a statement containing an expression, /// return the expression. We don't peel blocks recursively, as extra blocks might be intentional. fn expr_block<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> { diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 87d75234ebc0..6b68940c6423 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -667,6 +667,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::returns::LET_AND_RETURN_INFO, crate::returns::NEEDLESS_RETURN_INFO, crate::returns::NEEDLESS_RETURN_WITH_QUESTION_MARK_INFO, + crate::same_length_and_capacity::SAME_LENGTH_AND_CAPACITY_INFO, crate::same_name_method::SAME_NAME_METHOD_INFO, crate::self_named_constructors::SELF_NAMED_CONSTRUCTORS_INFO, crate::semicolon_block::SEMICOLON_INSIDE_BLOCK_INFO, diff --git a/clippy_lints/src/disallowed_methods.rs b/clippy_lints/src/disallowed_methods.rs index 8c067432cb4e..58403ad19235 100644 --- a/clippy_lints/src/disallowed_methods.rs +++ b/clippy_lints/src/disallowed_methods.rs @@ -88,6 +88,9 @@ impl_lint_pass!(DisallowedMethods => [DISALLOWED_METHODS]); impl<'tcx> LateLintPass<'tcx> for DisallowedMethods { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if expr.span.desugaring_kind().is_some() { + return; + } let (id, span) = match &expr.kind { ExprKind::Path(path) if let Res::Def(_, id) = cx.qpath_res(path, expr.hir_id) => (id, expr.span), ExprKind::MethodCall(name, ..) if let Some(id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => { diff --git a/clippy_lints/src/empty_with_brackets.rs b/clippy_lints/src/empty_with_brackets.rs index e7230ebf8cba..7e335d5c9809 100644 --- a/clippy_lints/src/empty_with_brackets.rs +++ b/clippy_lints/src/empty_with_brackets.rs @@ -1,16 +1,18 @@ use clippy_utils::attrs::span_contains_cfg; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; -use rustc_data_structures::fx::FxIndexMap; +use clippy_utils::source::SpanRangeExt; +use clippy_utils::span_contains_non_whitespace; +use rustc_data_structures::fx::{FxIndexMap, IndexEntry}; use rustc_errors::Applicability; -use rustc_hir::def::CtorOf; use rustc_hir::def::DefKind::Ctor; use rustc_hir::def::Res::Def; +use rustc_hir::def::{CtorOf, DefKind}; use rustc_hir::def_id::LocalDefId; -use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node, Path, QPath, Variant, VariantData}; +use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node, Pat, PatKind, Path, QPath, Variant, VariantData}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{self, TyCtxt}; use rustc_session::impl_lint_pass; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does @@ -118,7 +120,6 @@ impl LateLintPass<'_> for EmptyWithBrackets { } fn check_variant(&mut self, cx: &LateContext<'_>, variant: &Variant<'_>) { - // FIXME: handle `$name {}` if !variant.span.from_expansion() && !variant.ident.span.from_expansion() && let span_after_ident = variant.span.with_lo(variant.ident.span.hi()) @@ -126,44 +127,14 @@ impl LateLintPass<'_> for EmptyWithBrackets { { match variant.data { VariantData::Struct { .. } => { - // Empty struct variants can be linted immediately - span_lint_and_then( - cx, - EMPTY_ENUM_VARIANTS_WITH_BRACKETS, - span_after_ident, - "enum variant has empty brackets", - |diagnostic| { - diagnostic.span_suggestion_hidden( - span_after_ident, - "remove the brackets", - "", - Applicability::MaybeIncorrect, - ); - }, - ); + self.add_enum_variant(variant.def_id); }, VariantData::Tuple(.., local_def_id) => { // Don't lint reachable tuple enums if cx.effective_visibilities.is_reachable(variant.def_id) { return; } - if let Some(entry) = self.empty_tuple_enum_variants.get_mut(&local_def_id) { - // empty_tuple_enum_variants contains Usage::NoDefinition if the variant was called before the - // definition was encountered. Now that there's a definition, convert it - // to Usage::Unused. - if let Usage::NoDefinition { redundant_use_sites } = entry { - *entry = Usage::Unused { - redundant_use_sites: redundant_use_sites.clone(), - }; - } - } else { - self.empty_tuple_enum_variants.insert( - local_def_id, - Usage::Unused { - redundant_use_sites: vec![], - }, - ); - } + self.add_enum_variant(local_def_id); }, VariantData::Unit(..) => {}, } @@ -171,56 +142,58 @@ impl LateLintPass<'_> for EmptyWithBrackets { } fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if let Some(def_id) = check_expr_for_enum_as_function(expr) { - if let Some(parentheses_span) = call_parentheses_span(cx.tcx, expr) { + if let Some((def_id, mut span)) = check_expr_for_enum_as_function(cx, expr) { + if span.is_empty() + && let Some(parentheses_span) = call_parentheses_span(cx.tcx, expr) + { + span = parentheses_span; + } + + if span.is_empty() { + // The parentheses are not redundant. + self.empty_tuple_enum_variants.insert(def_id, Usage::Used); + } else { // Do not count expressions from macro expansion as a redundant use site. if expr.span.from_expansion() { return; } - match self.empty_tuple_enum_variants.get_mut(&def_id) { - Some( - &mut (Usage::Unused { - ref mut redundant_use_sites, - } - | Usage::NoDefinition { - ref mut redundant_use_sites, - }), - ) => { - redundant_use_sites.push(parentheses_span); - }, - None => { - // The variant isn't in the IndexMap which means its definition wasn't encountered yet. - self.empty_tuple_enum_variants.insert( - def_id, - Usage::NoDefinition { - redundant_use_sites: vec![parentheses_span], - }, - ); - }, - _ => {}, - } - } else { - // The parentheses are not redundant. - self.empty_tuple_enum_variants.insert(def_id, Usage::Used); + self.update_enum_variant_usage(def_id, span); } } } + fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) { + if !pat.span.from_expansion() + && let Some((def_id, span)) = check_pat_for_enum_as_function(cx, pat) + { + self.update_enum_variant_usage(def_id, span); + } + } + fn check_crate_post(&mut self, cx: &LateContext<'_>) { - for (local_def_id, usage) in &self.empty_tuple_enum_variants { + for (&local_def_id, usage) in &self.empty_tuple_enum_variants { // Ignore all variants with Usage::Used or Usage::NoDefinition let Usage::Unused { redundant_use_sites } = usage else { continue; }; + // Attempt to fetch the Variant from LocalDefId. - let Node::Variant(variant) = cx.tcx.hir_node( - cx.tcx - .local_def_id_to_hir_id(cx.tcx.parent(local_def_id.to_def_id()).expect_local()), - ) else { + let variant = if let Node::Variant(variant) = cx.tcx.hir_node_by_def_id(local_def_id) { + variant + } else if let Node::Variant(variant) = cx.tcx.hir_node_by_def_id(cx.tcx.local_parent(local_def_id)) { + variant + } else { continue; }; + // Span of the parentheses in variant definition let span = variant.span.with_lo(variant.ident.span.hi()); + let span_inner = span + .with_lo(SpanRangeExt::trim_start(span, cx).start + BytePos(1)) + .with_hi(span.hi() - BytePos(1)); + if span_contains_non_whitespace(cx, span_inner, false) { + continue; + } span_lint_hir_and_then( cx, EMPTY_ENUM_VARIANTS_WITH_BRACKETS, @@ -252,6 +225,43 @@ impl LateLintPass<'_> for EmptyWithBrackets { } } +impl EmptyWithBrackets { + fn add_enum_variant(&mut self, local_def_id: LocalDefId) { + self.empty_tuple_enum_variants + .entry(local_def_id) + .and_modify(|entry| { + // empty_tuple_enum_variants contains Usage::NoDefinition if the variant was called before + // the definition was encountered. Now that there's a + // definition, convert it to Usage::Unused. + if let Usage::NoDefinition { redundant_use_sites } = entry { + *entry = Usage::Unused { + redundant_use_sites: redundant_use_sites.clone(), + }; + } + }) + .or_insert_with(|| Usage::Unused { + redundant_use_sites: vec![], + }); + } + + fn update_enum_variant_usage(&mut self, def_id: LocalDefId, parentheses_span: Span) { + match self.empty_tuple_enum_variants.entry(def_id) { + IndexEntry::Occupied(mut e) => { + if let Usage::Unused { redundant_use_sites } | Usage::NoDefinition { redundant_use_sites } = e.get_mut() + { + redundant_use_sites.push(parentheses_span); + } + }, + IndexEntry::Vacant(e) => { + // The variant isn't in the IndexMap which means its definition wasn't encountered yet. + e.insert(Usage::NoDefinition { + redundant_use_sites: vec![parentheses_span], + }); + }, + } + } +} + fn has_brackets(var_data: &VariantData<'_>) -> bool { !matches!(var_data, VariantData::Unit(..)) } @@ -277,17 +287,47 @@ fn call_parentheses_span(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> Option { } // Returns the LocalDefId of the variant being called as a function if it exists. -fn check_expr_for_enum_as_function(expr: &Expr<'_>) -> Option { - if let ExprKind::Path(QPath::Resolved( - _, - Path { - res: Def(Ctor(CtorOf::Variant, _), def_id), - .. +fn check_expr_for_enum_as_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(LocalDefId, Span)> { + match expr.kind { + ExprKind::Path(QPath::Resolved( + _, + Path { + res: Def(Ctor(CtorOf::Variant, _), def_id), + span, + .. + }, + )) => def_id.as_local().map(|id| (id, span.with_lo(expr.span.hi()))), + ExprKind::Struct(qpath, ..) + if let Def(DefKind::Variant, mut def_id) = cx.typeck_results().qpath_res(qpath, expr.hir_id) => + { + let ty = cx.tcx.type_of(def_id).instantiate_identity(); + if let ty::FnDef(ctor_def_id, _) = ty.kind() { + def_id = *ctor_def_id; + } + + def_id.as_local().map(|id| (id, qpath.span().with_lo(expr.span.hi()))) }, - )) = expr.kind - { - def_id.as_local() - } else { - None + _ => None, + } +} + +fn check_pat_for_enum_as_function(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(LocalDefId, Span)> { + match pat.kind { + PatKind::TupleStruct(qpath, ..) + if let Def(Ctor(CtorOf::Variant, _), def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) => + { + def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi()))) + }, + PatKind::Struct(qpath, ..) + if let Def(DefKind::Variant, mut def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) => + { + let ty = cx.tcx.type_of(def_id).instantiate_identity(); + if let ty::FnDef(ctor_def_id, _) = ty.kind() { + def_id = *ctor_def_id; + } + + def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi()))) + }, + _ => None, } } diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index bdfe2e49e66e..75ab890a8a7f 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -4,7 +4,7 @@ use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_expr; use clippy_utils::{ SpanlessEq, can_move_expr_to_closure_no_visit, desugar_await, higher, is_expr_final_block_expr, - is_expr_used_or_unified, paths, peel_hir_expr_while, + is_expr_used_or_unified, paths, peel_hir_expr_while, span_contains_non_whitespace, }; use core::fmt::{self, Write}; use rustc_errors::Applicability; @@ -167,7 +167,11 @@ impl<'tcx> LateLintPass<'tcx> for HashMapPass { "if let {}::{entry_kind} = {map_str}.entry({key_str}) {body_str}", map_ty.entry_path(), )) - } else if let Some(insertion) = then_search.as_single_insertion() { + } else if let Some(insertion) = then_search.as_single_insertion() + && let span_in_between = then_expr.span.shrink_to_lo().between(insertion.call.span) + && let span_in_between = span_in_between.split_at(1).1 + && !span_contains_non_whitespace(cx, span_in_between, true) + { let value_str = snippet_with_context(cx, insertion.value.span, then_expr.span.ctxt(), "..", &mut app).0; if contains_expr.negated { if insertion.value.can_have_side_effects() { diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index c42998ffc3f5..bd2bd6628464 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -82,7 +82,7 @@ fn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Sp // check for `unwrap` if let Some(arglists) = method_chain_args(expr, &[sym::unwrap]) { let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs(); - if receiver_ty.is_diag_item(self.lcx, sym::Option) || receiver_ty.is_diag_item(self.lcx, sym::Result) { + if matches!(receiver_ty.opt_diag_name(self.lcx), Some(sym::Option | sym::Result)) { self.result.push(expr.span); } } diff --git a/clippy_lints/src/format_push_string.rs b/clippy_lints/src/format_push_string.rs index a23ba9ab837a..fea55f91bce7 100644 --- a/clippy_lints/src/format_push_string.rs +++ b/clippy_lints/src/format_push_string.rs @@ -1,10 +1,13 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::higher; +use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span, root_macro_call_first_node}; use clippy_utils::res::MaybeDef; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; +use clippy_utils::std_or_core; +use rustc_errors::Applicability; use rustc_hir::{AssignOpKind, Expr, ExprKind, LangItem, MatchSource}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::declare_lint_pass; -use rustc_span::sym; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_session::impl_lint_pass; +use rustc_span::{Span, sym}; declare_clippy_lint! { /// ### What it does @@ -38,7 +41,152 @@ declare_clippy_lint! { pedantic, "`format!(..)` appended to existing `String`" } -declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]); +impl_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]); + +pub(crate) struct FormatPushString { + format_args: FormatArgsStorage, +} + +enum FormatSearchResults { + /// The expression is itself a `format!()` invocation -- we can make a suggestion to replace it + Direct(Span), + /// The expression contains zero or more `format!()`s, e.g.: + /// ```ignore + /// if true { + /// format!("hello") + /// } else { + /// format!("world") + /// } + /// ``` + /// or + /// ```ignore + /// match true { + /// true => format!("hello"), + /// false => format!("world"), + /// } + Nested(Vec), +} + +impl FormatPushString { + pub(crate) fn new(format_args: FormatArgsStorage) -> Self { + Self { format_args } + } + + fn find_formats<'tcx>(&self, cx: &LateContext<'_>, e: &'tcx Expr<'tcx>) -> FormatSearchResults { + let expr_as_format = |e| { + if let Some(macro_call) = root_macro_call_first_node(cx, e) + && cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) + && let Some(format_args) = self.format_args.get(cx, e, macro_call.expn) + { + Some(format_args_inputs_span(format_args)) + } else { + None + } + }; + + let e = e.peel_blocks().peel_borrows(); + if let Some(fmt) = expr_as_format(e) { + FormatSearchResults::Direct(fmt) + } else { + fn inner<'tcx>( + e: &'tcx Expr<'tcx>, + expr_as_format: &impl Fn(&'tcx Expr<'tcx>) -> Option, + out: &mut Vec, + ) { + let e = e.peel_blocks().peel_borrows(); + + match e.kind { + _ if expr_as_format(e).is_some() => out.push(e.span), + ExprKind::Match(_, arms, MatchSource::Normal) => { + for arm in arms { + inner(arm.body, expr_as_format, out); + } + }, + ExprKind::If(_, then, els) => { + inner(then, expr_as_format, out); + if let Some(els) = els { + inner(els, expr_as_format, out); + } + }, + _ => {}, + } + } + let mut spans = vec![]; + inner(e, &expr_as_format, &mut spans); + FormatSearchResults::Nested(spans) + } + } +} + +impl<'tcx> LateLintPass<'tcx> for FormatPushString { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + let (recv, arg) = match expr.kind { + ExprKind::MethodCall(_, recv, [arg], _) => { + if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) + && cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id) + { + (recv, arg) + } else { + return; + } + }, + ExprKind::AssignOp(op, recv, arg) if op.node == AssignOpKind::AddAssign && is_string(cx, recv) => { + (recv, arg) + }, + _ => return, + }; + let Some(std_or_core) = std_or_core(cx) else { + // not even `core` is available, so can't suggest `write!` + return; + }; + match self.find_formats(cx, arg) { + FormatSearchResults::Direct(format_args) => { + span_lint_and_then( + cx, + FORMAT_PUSH_STRING, + expr.span, + "`format!(..)` appended to existing `String`", + |diag| { + let mut app = Applicability::MaybeIncorrect; + let msg = "consider using `write!` to avoid the extra allocation"; + + let sugg = format!( + "let _ = write!({recv}, {format_args})", + recv = snippet_with_context(cx.sess(), recv.span, expr.span.ctxt(), "_", &mut app).0, + format_args = snippet_with_applicability(cx.sess(), format_args, "..", &mut app), + ); + diag.span_suggestion_verbose(expr.span, msg, sugg, app); + + // TODO: omit the note if the `Write` trait is imported at point + // Tip: `TyCtxt::in_scope_traits` isn't it -- it returns a non-empty list only when called on + // the `HirId` of a `ExprKind::MethodCall` that is a call of a _trait_ method. + diag.note(format!("you may need to import the `{std_or_core}::fmt::Write` trait")); + }, + ); + }, + FormatSearchResults::Nested(spans) => { + if !spans.is_empty() { + span_lint_and_then( + cx, + FORMAT_PUSH_STRING, + expr.span, + "`format!(..)` appended to existing `String`", + |diag| { + diag.help("consider using `write!` to avoid the extra allocation"); + diag.span_labels(spans, "`format!` used here"); + + // TODO: omit the note if the `Write` trait is imported at point + // Tip: `TyCtxt::in_scope_traits` isn't it -- it returns a non-empty list only when called + // on the `HirId` of a `ExprKind::MethodCall` that is a call of + // a _trait_ method. + diag.note(format!("you may need to import the `{std_or_core}::fmt::Write` trait")); + }, + ); + } + }, + } + } +} fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { cx.typeck_results() @@ -46,54 +194,3 @@ fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { .peel_refs() .is_lang_item(cx, LangItem::String) } -fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - let e = e.peel_blocks().peel_borrows(); - - if e.span.from_expansion() - && let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id - { - cx.tcx.get_diagnostic_name(macro_def_id) == Some(sym::format_macro) - } else if let Some(higher::If { then, r#else, .. }) = higher::If::hir(e) { - is_format(cx, then) || r#else.is_some_and(|e| is_format(cx, e)) - } else { - match higher::IfLetOrMatch::parse(cx, e) { - Some(higher::IfLetOrMatch::Match(_, arms, MatchSource::Normal)) => { - arms.iter().any(|arm| is_format(cx, arm.body)) - }, - Some(higher::IfLetOrMatch::IfLet(_, _, then, r#else, _)) => { - is_format(cx, then) || r#else.is_some_and(|e| is_format(cx, e)) - }, - _ => false, - } - } -} - -impl<'tcx> LateLintPass<'tcx> for FormatPushString { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - let arg = match expr.kind { - ExprKind::MethodCall(_, _, [arg], _) => { - if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) - && cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id) - { - arg - } else { - return; - } - }, - ExprKind::AssignOp(op, left, arg) if op.node == AssignOpKind::AddAssign && is_string(cx, left) => arg, - _ => return, - }; - if is_format(cx, arg) { - #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")] - span_lint_and_then( - cx, - FORMAT_PUSH_STRING, - expr.span, - "`format!(..)` appended to existing `String`", - |diag| { - diag.help("consider using `write!` to avoid the extra allocation"); - }, - ); - } - } -} diff --git a/clippy_lints/src/functions/mod.rs b/clippy_lints/src/functions/mod.rs index bdc366f6878a..9a7427ea1447 100644 --- a/clippy_lints/src/functions/mod.rs +++ b/clippy_lints/src/functions/mod.rs @@ -596,4 +596,8 @@ impl<'tcx> LateLintPass<'tcx> for Functions { impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api); ref_option::check_trait_item(cx, item, self.avoid_breaking_exported_api); } + + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + result::check_expr(cx, expr, self.large_error_threshold, &self.large_error_ignored); + } } diff --git a/clippy_lints/src/functions/result.rs b/clippy_lints/src/functions/result.rs index 04e15a1d8a0e..77fec9371425 100644 --- a/clippy_lints/src/functions/result.rs +++ b/clippy_lints/src/functions/result.rs @@ -50,7 +50,7 @@ pub(super) fn check_item<'tcx>( let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); check_result_unit_err(cx, err_ty, fn_header_span, msrv); } - check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored); + check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false); } } @@ -70,7 +70,7 @@ pub(super) fn check_impl_item<'tcx>( let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); check_result_unit_err(cx, err_ty, fn_header_span, msrv); } - check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored); + check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false); } } @@ -87,7 +87,7 @@ pub(super) fn check_trait_item<'tcx>( if cx.effective_visibilities.is_exported(item.owner_id.def_id) { check_result_unit_err(cx, err_ty, fn_header_span, msrv); } - check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored); + check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false); } } } @@ -111,12 +111,15 @@ fn check_result_large_err<'tcx>( hir_ty_span: Span, large_err_threshold: u64, large_err_ignored: &DefIdSet, + is_closure: bool, ) { if let ty::Adt(adt, _) = err_ty.kind() && large_err_ignored.contains(&adt.did()) { return; } + + let subject = if is_closure { "closure" } else { "function" }; if let ty::Adt(adt, subst) = err_ty.kind() && let Some(local_def_id) = adt.did().as_local() && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_def_id) @@ -130,7 +133,7 @@ fn check_result_large_err<'tcx>( cx, RESULT_LARGE_ERR, hir_ty_span, - "the `Err`-variant returned from this function is very large", + format!("the `Err`-variant returned from this {subject} is very large"), |diag| { diag.span_label( def.variants[first_variant.ind].span, @@ -161,7 +164,7 @@ fn check_result_large_err<'tcx>( cx, RESULT_LARGE_ERR, hir_ty_span, - "the `Err`-variant returned from this function is very large", + format!("the `Err`-variant returned from this {subject} is very large"), |diag: &mut Diag<'_, ()>| { diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes")); diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`")); @@ -170,3 +173,33 @@ fn check_result_large_err<'tcx>( } } } + +pub(super) fn check_expr<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'tcx>, + large_err_threshold: u64, + large_err_ignored: &DefIdSet, +) { + if let hir::ExprKind::Closure(closure) = expr.kind + && let ty::Closure(_, args) = cx.typeck_results().expr_ty(expr).kind() + && let closure_sig = args.as_closure().sig() + && let Ok(err_binder) = closure_sig.output().try_map_bound(|output_ty| { + if let ty::Adt(adt, args) = output_ty.kind() + && let [_, err_arg] = args.as_slice() + && let Some(err_ty) = err_arg.as_type() + && adt.is_diag_item(cx, sym::Result) + { + return Ok(err_ty); + } + + Err(()) + }) + { + let err_ty = cx.tcx.instantiate_bound_regions_with_erased(err_binder); + let hir_ty_span = match closure.fn_decl.output { + hir::FnRetTy::Return(hir_ty) => hir_ty.span, + hir::FnRetTy::DefaultReturn(_) => expr.span, + }; + check_result_large_err(cx, err_ty, hir_ty_span, large_err_threshold, large_err_ignored, true); + } +} diff --git a/clippy_lints/src/if_not_else.rs b/clippy_lints/src/if_not_else.rs index 54e9538fcb99..ff22ba4fcd0d 100644 --- a/clippy_lints/src/if_not_else.rs +++ b/clippy_lints/src/if_not_else.rs @@ -1,7 +1,7 @@ use clippy_utils::consts::is_zero_integer_const; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::is_else_clause; -use clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet}; +use clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet_with_context}; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; @@ -78,6 +78,7 @@ impl LateLintPass<'_> for IfNotElse { // } // ``` if !e.span.from_expansion() && !is_else_clause(cx.tcx, e) { + let mut applicability = Applicability::MachineApplicable; match cond.kind { ExprKind::Unary(UnOp::Not, _) | ExprKind::Binary(_, _, _) => span_lint_and_sugg( cx, @@ -85,8 +86,16 @@ impl LateLintPass<'_> for IfNotElse { e.span, msg, "try", - make_sugg(cx, &cond.kind, cond_inner.span, els.span, "..", Some(e.span)), - Applicability::MachineApplicable, + make_sugg( + cx, + e.span, + &cond.kind, + cond_inner.span, + els.span, + "..", + &mut applicability, + ), + applicability, ), _ => span_lint_and_help(cx, IF_NOT_ELSE, e.span, msg, None, help), } @@ -97,28 +106,26 @@ impl LateLintPass<'_> for IfNotElse { fn make_sugg<'a>( sess: &impl HasSession, + expr_span: Span, cond_kind: &'a ExprKind<'a>, cond_inner: Span, els_span: Span, default: &'a str, - indent_relative_to: Option, + applicability: &mut Applicability, ) -> String { - let cond_inner_snip = snippet(sess, cond_inner, default); - let els_snip = snippet(sess, els_span, default); - let indent = indent_relative_to.and_then(|s| indent_of(sess, s)); + let (cond_inner_snip, _) = snippet_with_context(sess, cond_inner, expr_span.ctxt(), default, applicability); + let (els_snip, _) = snippet_with_context(sess, els_span, expr_span.ctxt(), default, applicability); + let indent = indent_of(sess, expr_span); let suggestion = match cond_kind { ExprKind::Unary(UnOp::Not, cond_rest) => { - format!( - "if {} {} else {}", - snippet(sess, cond_rest.span, default), - els_snip, - cond_inner_snip - ) + let (cond_rest_snip, _) = + snippet_with_context(sess, cond_rest.span, expr_span.ctxt(), default, applicability); + format!("if {cond_rest_snip} {els_snip} else {cond_inner_snip}") }, ExprKind::Binary(_, lhs, rhs) => { - let lhs_snip = snippet(sess, lhs.span, default); - let rhs_snip = snippet(sess, rhs.span, default); + let (lhs_snip, _) = snippet_with_context(sess, lhs.span, expr_span.ctxt(), default, applicability); + let (rhs_snip, _) = snippet_with_context(sess, rhs.span, expr_span.ctxt(), default, applicability); format!("if {lhs_snip} == {rhs_snip} {els_snip} else {cond_inner_snip}") }, diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs index 7f3ef58c93d1..9e5e4fa58d2f 100644 --- a/clippy_lints/src/if_then_some_else_none.rs +++ b/clippy_lints/src/if_then_some_else_none.rs @@ -4,10 +4,12 @@ use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context}; use clippy_utils::sugg::Sugg; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{ - as_some_expr, contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, - is_none_expr, peel_blocks, sym, + as_some_expr, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, is_none_expr, + peel_blocks, sym, }; +use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -76,8 +78,14 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { && !is_else_clause(cx.tcx, expr) && !is_in_const_context(cx) && self.msrv.meets(cx, msrvs::BOOL_THEN) - && !contains_return(then_block.stmts) - && then_block.expr.is_none_or(|expr| !contains_return(expr)) + && for_each_expr_without_closures(then_block, |e| { + if matches!(e.kind, ExprKind::Ret(..) | ExprKind::Yield(..)) { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + }) + .is_none() { let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) { sym::then_some @@ -101,13 +109,19 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { .maybe_paren() .to_string(); let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0; - let method_body = if let Some(first_stmt) = then_block.stmts.first() - && let Some(first_stmt_span) = walk_span_to_context(first_stmt.span, ctxt) + let method_body = if let Some(_) = then_block.stmts.first() + && let Some(then_span) = walk_span_to_context(then.span, ctxt) { - let block_snippet = - snippet_with_applicability(cx, first_stmt_span.until(then_expr.span), "..", &mut app); + let block_before_snippet = + snippet_with_applicability(cx, then_span.until(then_expr.span), "..", &mut app); + let block_after_snippet = snippet_with_applicability( + cx, + then_expr.span.shrink_to_hi().until(then_span.shrink_to_hi()), + "..", + &mut app, + ); let closure = if method_name == sym::then { "|| " } else { "" }; - format!("{closure} {{ {} {arg_snip} }}", block_snippet.trim_end()) + format!("{closure}{block_before_snippet}{arg_snip}{block_after_snippet}") } else if method_name == sym::then { (std::borrow::Cow::Borrowed("|| ") + arg_snip).into_owned() } else { diff --git a/clippy_lints/src/ifs/branches_sharing_code.rs b/clippy_lints/src/ifs/branches_sharing_code.rs index b3f597cc8736..b6e8d047c5cd 100644 --- a/clippy_lints/src/ifs/branches_sharing_code.rs +++ b/clippy_lints/src/ifs/branches_sharing_code.rs @@ -9,7 +9,7 @@ use clippy_utils::{ use core::iter; use core::ops::ControlFlow; use rustc_errors::Applicability; -use rustc_hir::{Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Node, Stmt, StmtKind, intravisit}; +use rustc_hir::{Block, Expr, ExprKind, HirId, HirIdSet, ItemKind, LetStmt, Node, Stmt, StmtKind, UseKind, intravisit}; use rustc_lint::LateContext; use rustc_span::hygiene::walk_chain; use rustc_span::source_map::SourceMap; @@ -108,6 +108,7 @@ struct BlockEq { /// The name and id of every local which can be moved at the beginning and the end. moved_locals: Vec<(HirId, Symbol)>, } + impl BlockEq { fn start_span(&self, b: &Block<'_>, sm: &SourceMap) -> Option { match &b.stmts[..self.start_end_eq] { @@ -129,20 +130,33 @@ impl BlockEq { } /// If the statement is a local, checks if the bound names match the expected list of names. -fn eq_binding_names(s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool { - if let StmtKind::Let(l) = s.kind { - let mut i = 0usize; - let mut res = true; - l.pat.each_binding_or_first(&mut |_, _, _, name| { - if names.get(i).is_some_and(|&(_, n)| n == name.name) { - i += 1; - } else { - res = false; - } - }); - res && i == names.len() - } else { - false +fn eq_binding_names(cx: &LateContext<'_>, s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool { + match s.kind { + StmtKind::Let(l) => { + let mut i = 0usize; + let mut res = true; + l.pat.each_binding_or_first(&mut |_, _, _, name| { + if names.get(i).is_some_and(|&(_, n)| n == name.name) { + i += 1; + } else { + res = false; + } + }); + res && i == names.len() + }, + StmtKind::Item(item_id) + if let [(_, name)] = names + && let item = cx.tcx.hir_item(item_id) + && let ItemKind::Static(_, ident, ..) + | ItemKind::Const(ident, ..) + | ItemKind::Fn { ident, .. } + | ItemKind::TyAlias(ident, ..) + | ItemKind::Use(_, UseKind::Single(ident)) + | ItemKind::Mod(ident, _) = item.kind => + { + *name == ident.name + }, + _ => false, } } @@ -164,6 +178,7 @@ fn modifies_any_local<'tcx>(cx: &LateContext<'tcx>, s: &'tcx Stmt<'_>, locals: & /// Checks if the given statement should be considered equal to the statement in the same /// position for each block. fn eq_stmts( + cx: &LateContext<'_>, stmt: &Stmt<'_>, blocks: &[&Block<'_>], get_stmt: impl for<'a> Fn(&'a Block<'a>) -> Option<&'a Stmt<'a>>, @@ -178,7 +193,7 @@ fn eq_stmts( let new_bindings = &moved_bindings[old_count..]; blocks .iter() - .all(|b| get_stmt(b).is_some_and(|s| eq_binding_names(s, new_bindings))) + .all(|b| get_stmt(b).is_some_and(|s| eq_binding_names(cx, s, new_bindings))) } else { true }) && blocks.iter().all(|b| get_stmt(b).is_some_and(|s| eq.eq_stmt(s, stmt))) @@ -218,7 +233,7 @@ fn scan_block_for_eq<'tcx>( return true; } modifies_any_local(cx, stmt, &cond_locals) - || !eq_stmts(stmt, blocks, |b| b.stmts.get(i), &mut eq, &mut moved_locals) + || !eq_stmts(cx, stmt, blocks, |b| b.stmts.get(i), &mut eq, &mut moved_locals) }) .map_or(block.stmts.len(), |(i, stmt)| { adjust_by_closest_callsite(i, stmt, block.stmts[..i].iter().enumerate().rev()) @@ -279,6 +294,7 @@ fn scan_block_for_eq<'tcx>( })) .fold(end_search_start, |init, (stmt, offset)| { if eq_stmts( + cx, stmt, blocks, |b| b.stmts.get(b.stmts.len() - offset), @@ -290,11 +306,26 @@ fn scan_block_for_eq<'tcx>( // Clear out all locals seen at the end so far. None of them can be moved. let stmts = &blocks[0].stmts; for stmt in &stmts[stmts.len() - init..=stmts.len() - offset] { - if let StmtKind::Let(l) = stmt.kind { - l.pat.each_binding_or_first(&mut |_, id, _, _| { - // FIXME(rust/#120456) - is `swap_remove` correct? - eq.locals.swap_remove(&id); - }); + match stmt.kind { + StmtKind::Let(l) => { + l.pat.each_binding_or_first(&mut |_, id, _, _| { + // FIXME(rust/#120456) - is `swap_remove` correct? + eq.locals.swap_remove(&id); + }); + }, + StmtKind::Item(item_id) => { + let item = cx.tcx.hir_item(item_id); + if let ItemKind::Static(..) + | ItemKind::Const(..) + | ItemKind::Fn { .. } + | ItemKind::TyAlias(..) + | ItemKind::Use(..) + | ItemKind::Mod(..) = item.kind + { + eq.local_items.swap_remove(&item.owner_id.to_def_id()); + } + }, + _ => {}, } } moved_locals.truncate(moved_locals_at_start); diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 638a08b096db..9dc74a157cbf 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -223,25 +223,20 @@ impl<'tcx> ImplicitHasherType<'tcx> { _ => None, }) .collect(); - let params_len = params.len(); let ty = lower_ty(cx.tcx, hir_ty); - if ty.is_diag_item(cx, sym::HashMap) && params_len == 2 { - Some(ImplicitHasherType::HashMap( + match (ty.opt_diag_name(cx), ¶ms[..]) { + (Some(sym::HashMap), [k, v]) => Some(ImplicitHasherType::HashMap( hir_ty.span, ty, - snippet(cx, params[0].span, "K"), - snippet(cx, params[1].span, "V"), - )) - } else if ty.is_diag_item(cx, sym::HashSet) && params_len == 1 { - Some(ImplicitHasherType::HashSet( - hir_ty.span, - ty, - snippet(cx, params[0].span, "T"), - )) - } else { - None + snippet(cx, k.span, "K"), + snippet(cx, v.span, "V"), + )), + (Some(sym::HashSet), [t]) => { + Some(ImplicitHasherType::HashSet(hir_ty.span, ty, snippet(cx, t.span, "T"))) + }, + _ => None, } } else { None diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 40487fe48f22..a957afdb1910 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -318,6 +318,7 @@ mod replace_box; mod reserve_after_initialization; mod return_self_not_must_use; mod returns; +mod same_length_and_capacity; mod same_name_method; mod self_named_constructors; mod semicolon_block; @@ -739,7 +740,10 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(move |_| Box::new(cargo::Cargo::new(conf))), Box::new(|_| Box::new(empty_with_brackets::EmptyWithBrackets::default())), Box::new(|_| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings)), - Box::new(|_| Box::new(format_push_string::FormatPushString)), + { + let format_args = format_args_storage.clone(); + Box::new(move |_| Box::new(format_push_string::FormatPushString::new(format_args.clone()))) + }, Box::new(move |_| Box::new(large_include_file::LargeIncludeFile::new(conf))), Box::new(|_| Box::new(strings::TrimSplitWhitespace)), Box::new(|_| Box::new(rc_clone_in_vec_init::RcCloneInVecInit)), @@ -852,6 +856,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co Box::new(|_| Box::new(volatile_composites::VolatileComposites)), Box::new(|_| Box::::default()), Box::new(move |_| Box::new(manual_ilog2::ManualIlog2::new(conf))), + Box::new(|_| Box::new(same_length_and_capacity::SameLengthAndCapacity)), // add late passes here, used by `cargo dev new_lint` ]; store.late_passes.extend(late_lints); diff --git a/clippy_lints/src/loops/for_kv_map.rs b/clippy_lints/src/loops/for_kv_map.rs index c6b650a1a88b..39b2391c98ec 100644 --- a/clippy_lints/src/loops/for_kv_map.rs +++ b/clippy_lints/src/loops/for_kv_map.rs @@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx _ => arg, }; - if ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap) { + if matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) { span_lint_and_then( cx, FOR_KV_MAP, diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 21198c3c8bc2..ddc783069385 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -26,6 +26,7 @@ mod while_let_on_iterator; use clippy_config::Conf; use clippy_utils::msrvs::Msrv; +use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; use clippy_utils::{higher, sym}; use rustc_ast::Label; use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; @@ -881,13 +882,44 @@ impl<'tcx> LateLintPass<'tcx> for Loops { manual_while_let_some::check(cx, condition, body, span); } - if let ExprKind::MethodCall(path, recv, [arg], _) = expr.kind - && matches!( - path.ident.name, - sym::all | sym::any | sym::filter_map | sym::find_map | sym::flat_map | sym::for_each | sym::map - ) - { - unused_enumerate_index::check_method(cx, expr, recv, arg); + if let ExprKind::MethodCall(path, recv, args, _) = expr.kind { + let name = path.ident.name; + + let is_iterator_method = || { + cx.ty_based_def(expr) + .assoc_fn_parent(cx) + .is_diag_item(cx, sym::Iterator) + }; + + // is_iterator_method is a bit expensive, so we call it last in each match arm + match (name, args) { + (sym::for_each | sym::all | sym::any, [arg]) => { + if let ExprKind::Closure(closure) = arg.kind + && is_iterator_method() + { + unused_enumerate_index::check_method(cx, recv, arg, closure); + never_loop::check_iterator_reduction(cx, expr, recv, closure); + } + }, + + (sym::filter_map | sym::find_map | sym::flat_map | sym::map, [arg]) => { + if let ExprKind::Closure(closure) = arg.kind + && is_iterator_method() + { + unused_enumerate_index::check_method(cx, recv, arg, closure); + } + }, + + (sym::try_for_each | sym::reduce, [arg]) | (sym::fold | sym::try_fold, [_, arg]) => { + if let ExprKind::Closure(closure) = arg.kind + && is_iterator_method() + { + never_loop::check_iterator_reduction(cx, expr, recv, closure); + } + }, + + _ => {}, + } } } } diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index 0d37be17689a..a037af3433c3 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -3,14 +3,16 @@ use super::utils::make_iterator_snippet; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::ForLoop; use clippy_utils::macros::root_macro_call_first_node; -use clippy_utils::source::snippet; +use clippy_utils::source::{snippet, snippet_with_context}; +use clippy_utils::sym; use clippy_utils::visitors::{Descend, for_each_expr_without_closures}; use rustc_errors::Applicability; use rustc_hir::{ - Block, Destination, Expr, ExprKind, HirId, InlineAsm, InlineAsmOperand, Node, Pat, Stmt, StmtKind, StructTailExpr, + Block, Closure, Destination, Expr, ExprKind, HirId, InlineAsm, InlineAsmOperand, Node, Pat, Stmt, StmtKind, + StructTailExpr, }; use rustc_lint::LateContext; -use rustc_span::{BytePos, Span, sym}; +use rustc_span::{BytePos, Span}; use std::iter::once; use std::ops::ControlFlow; @@ -72,6 +74,31 @@ pub(super) fn check<'tcx>( } } +pub(super) fn check_iterator_reduction<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'tcx>, + recv: &'tcx Expr<'tcx>, + closure: &'tcx Closure<'tcx>, +) { + let closure_body = cx.tcx.hir_body(closure.body).value; + let body_ty = cx.typeck_results().expr_ty(closure_body); + if body_ty.is_never() { + span_lint_and_then( + cx, + NEVER_LOOP, + expr.span, + "this iterator reduction never loops (closure always diverges)", + |diag| { + let mut app = Applicability::HasPlaceholders; + let recv_snip = snippet_with_context(cx, recv.span, expr.span.ctxt(), "", &mut app).0; + diag.note("if you only need one element, `if let Some(x) = iter.next()` is clearer"); + let sugg = format!("if let Some(x) = {recv_snip}.next() {{ ... }}"); + diag.span_suggestion_verbose(expr.span, "consider this pattern", sugg, app); + }, + ); + } +} + fn contains_any_break_or_continue(block: &Block<'_>) -> bool { for_each_expr_without_closures(block, |e| match e.kind { ExprKind::Break(..) | ExprKind::Continue(..) => ControlFlow::Break(()), diff --git a/clippy_lints/src/loops/unused_enumerate_index.rs b/clippy_lints/src/loops/unused_enumerate_index.rs index 82ded453616d..816273c7ba8b 100644 --- a/clippy_lints/src/loops/unused_enumerate_index.rs +++ b/clippy_lints/src/loops/unused_enumerate_index.rs @@ -1,10 +1,10 @@ use super::UNUSED_ENUMERATE_INDEX; use clippy_utils::diagnostics::span_lint_hir_and_then; -use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; +use clippy_utils::res::MaybeDef; use clippy_utils::source::{SpanRangeExt, walk_span_to_context}; use clippy_utils::{expr_or_init, pat_is_wild}; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, Pat, PatKind, TyKind}; +use rustc_hir::{Closure, Expr, ExprKind, Pat, PatKind, TyKind}; use rustc_lint::LateContext; use rustc_span::{Span, SyntaxContext, sym}; @@ -60,14 +60,12 @@ pub(super) fn check<'tcx>( pub(super) fn check_method<'tcx>( cx: &LateContext<'tcx>, - e: &'tcx Expr<'tcx>, recv: &'tcx Expr<'tcx>, arg: &'tcx Expr<'tcx>, + closure: &'tcx Closure<'tcx>, ) { - if let ExprKind::Closure(closure) = arg.kind - && let body = cx.tcx.hir_body(closure.body) - && let [param] = body.params - && cx.ty_based_def(e).opt_parent(cx).is_diag_item(cx, sym::Iterator) + let body = cx.tcx.hir_body(closure.body); + if let [param] = body.params && let [input] = closure.fn_decl.inputs && !arg.span.from_expansion() && !input.span.from_expansion() diff --git a/clippy_lints/src/manual_let_else.rs b/clippy_lints/src/manual_let_else.rs index 0f3d8b336675..38ee4ce104a5 100644 --- a/clippy_lints/src/manual_let_else.rs +++ b/clippy_lints/src/manual_let_else.rs @@ -374,7 +374,7 @@ fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: boo } let ty = typeck_results.pat_ty(pat); // Option and Result are allowed, everything else isn't. - if !(ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result)) { + if !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) { has_disallowed = true; } }); diff --git a/clippy_lints/src/matches/match_like_matches.rs b/clippy_lints/src/matches/match_like_matches.rs index 89411115f730..c26b2dbde7fc 100644 --- a/clippy_lints/src/matches/match_like_matches.rs +++ b/clippy_lints/src/matches/match_like_matches.rs @@ -3,7 +3,7 @@ use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::has_let_expr; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment}; use rustc_ast::LitKind; use rustc_errors::Applicability; @@ -44,6 +44,8 @@ pub(crate) fn check_if_let<'tcx>( { ex_new = ex_inner; } + + let (snippet, _) = snippet_with_context(cx, ex_new.span, expr.span.ctxt(), "..", &mut applicability); span_lint_and_then( cx, MATCH_LIKE_MATCHES_MACRO, @@ -53,11 +55,7 @@ pub(crate) fn check_if_let<'tcx>( diag.span_suggestion_verbose( expr.span, "use `matches!` directly", - format!( - "{}matches!({}, {pat})", - if b0 { "" } else { "!" }, - snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), - ), + format!("{}matches!({snippet}, {pat})", if b0 { "" } else { "!" }), applicability, ); }, @@ -178,6 +176,8 @@ pub(super) fn check_match<'tcx>( { ex_new = ex_inner; } + + let (snippet, _) = snippet_with_context(cx, ex_new.span, e.span.ctxt(), "..", &mut applicability); span_lint_and_then( cx, MATCH_LIKE_MATCHES_MACRO, @@ -187,11 +187,7 @@ pub(super) fn check_match<'tcx>( diag.span_suggestion_verbose( e.span, "use `matches!` directly", - format!( - "{}matches!({}, {pat_and_guard})", - if b0 { "" } else { "!" }, - snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), - ), + format!("{}matches!({snippet}, {pat_and_guard})", if b0 { "" } else { "!" },), applicability, ); }, diff --git a/clippy_lints/src/matches/match_wild_enum.rs b/clippy_lints/src/matches/match_wild_enum.rs index fa44a56af182..00bd1c2ca698 100644 --- a/clippy_lints/src/matches/match_wild_enum.rs +++ b/clippy_lints/src/matches/match_wild_enum.rs @@ -16,7 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { let ty = cx.typeck_results().expr_ty(ex).peel_refs(); let adt_def = match ty.kind() { ty::Adt(adt_def, _) - if adt_def.is_enum() && !(ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result)) => + if adt_def.is_enum() && !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) => { adt_def }, diff --git a/clippy_lints/src/methods/expect_fun_call.rs b/clippy_lints/src/methods/expect_fun_call.rs index 288f966991ac..e891b2ac6d64 100644 --- a/clippy_lints/src/methods/expect_fun_call.rs +++ b/clippy_lints/src/methods/expect_fun_call.rs @@ -26,12 +26,10 @@ pub(super) fn check<'tcx>( let arg_root = get_arg_root(cx, arg); if contains_call(cx, arg_root) && !contains_return(arg_root) { let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver); - let closure_args = if receiver_type.is_diag_item(cx, sym::Option) { - "||" - } else if receiver_type.is_diag_item(cx, sym::Result) { - "|_|" - } else { - return; + let closure_args = match receiver_type.opt_diag_name(cx) { + Some(sym::Option) => "||", + Some(sym::Result) => "|_|", + _ => return, }; let span_replace_word = method_span.with_hi(expr.span.hi()); diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs index ea2508cd7f38..8b303c0ca5b2 100644 --- a/clippy_lints/src/methods/iter_count.rs +++ b/clippy_lints/src/methods/iter_count.rs @@ -11,26 +11,17 @@ use super::ITER_COUNT; pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, iter_method: Symbol) { let ty = cx.typeck_results().expr_ty(recv); - let caller_type = if derefs_to_slice(cx, recv, ty).is_some() { - "slice" - } else if ty.is_diag_item(cx, sym::Vec) { - "Vec" - } else if ty.is_diag_item(cx, sym::VecDeque) { - "VecDeque" - } else if ty.is_diag_item(cx, sym::HashSet) { - "HashSet" - } else if ty.is_diag_item(cx, sym::HashMap) { - "HashMap" - } else if ty.is_diag_item(cx, sym::BTreeMap) { - "BTreeMap" - } else if ty.is_diag_item(cx, sym::BTreeSet) { - "BTreeSet" - } else if ty.is_diag_item(cx, sym::LinkedList) { - "LinkedList" - } else if ty.is_diag_item(cx, sym::BinaryHeap) { - "BinaryHeap" - } else { - return; + let caller_type = match ty.opt_diag_name(cx) { + _ if derefs_to_slice(cx, recv, ty).is_some() => "slice", + Some(sym::Vec) => "Vec", + Some(sym::VecDeque) => "VecDeque", + Some(sym::HashSet) => "HashSet", + Some(sym::HashMap) => "HashMap", + Some(sym::BTreeMap) => "BTreeMap", + Some(sym::BTreeSet) => "BTreeSet", + Some(sym::LinkedList) => "LinkedList", + Some(sym::BinaryHeap) => "BinaryHeap", + _ => return, }; let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index 2d6bc36dc535..16db8663941e 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -38,7 +38,7 @@ pub(super) fn check<'tcx>( _ => return, } && let ty = cx.typeck_results().expr_ty_adjusted(recv).peel_refs() - && (ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap)) + && matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) { let mut applicability = rustc_errors::Applicability::MachineApplicable; let recv_snippet = snippet_with_applicability(cx, recv.span, "map", &mut applicability); diff --git a/clippy_lints/src/methods/join_absolute_paths.rs b/clippy_lints/src/methods/join_absolute_paths.rs index e84b7452c758..905a58afa795 100644 --- a/clippy_lints/src/methods/join_absolute_paths.rs +++ b/clippy_lints/src/methods/join_absolute_paths.rs @@ -13,7 +13,7 @@ use super::JOIN_ABSOLUTE_PATHS; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx Expr<'tcx>, join_arg: &'tcx Expr<'tcx>, expr_span: Span) { let ty = cx.typeck_results().expr_ty(recv).peel_refs(); - if (ty.is_diag_item(cx, sym::Path) || ty.is_diag_item(cx, sym::PathBuf)) + if matches!(ty.opt_diag_name(cx), Some(sym::Path | sym::PathBuf)) && let ExprKind::Lit(spanned) = expr_or_init(cx, join_arg).kind && let LitKind::Str(symbol, _) = spanned.node && let sym_str = symbol.as_str() diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs index a1aac96ccf86..8a1cc664ac60 100644 --- a/clippy_lints/src/methods/map_clone.rs +++ b/clippy_lints/src/methods/map_clone.rs @@ -25,7 +25,7 @@ fn should_run_lint(cx: &LateContext<'_>, e: &hir::Expr<'_>, method_parent_id: De } // We check if it's an `Option` or a `Result`. if let Some(ty) = method_parent_id.opt_impl_ty(cx) { - if !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result) { + if !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) { return false; } } else { diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs index 62bdc4a3e411..8eb26fb50747 100644 --- a/clippy_lints/src/methods/map_unwrap_or.rs +++ b/clippy_lints/src/methods/map_unwrap_or.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::res::MaybeDef; use clippy_utils::source::snippet; @@ -51,11 +51,8 @@ pub(super) fn check<'tcx>( // get snippets for args to map() and unwrap_or_else() let map_snippet = snippet(cx, map_arg.span, ".."); let unwrap_snippet = snippet(cx, unwrap_arg.span, ".."); - // lint, with note if neither arg is > 1 line and both map() and - // unwrap_or_else() have the same span - let multiline = map_snippet.lines().count() > 1 || unwrap_snippet.lines().count() > 1; - let same_span = map_arg.span.eq_ctxt(unwrap_arg.span); - if same_span && !multiline { + // lint, with note if both map() and unwrap_or_else() have the same span + if map_arg.span.eq_ctxt(unwrap_arg.span) { let var_snippet = snippet(cx, recv.span, ".."); span_lint_and_sugg( cx, @@ -67,9 +64,6 @@ pub(super) fn check<'tcx>( Applicability::MachineApplicable, ); return true; - } else if same_span && multiline { - span_lint(cx, MAP_UNWRAP_OR, expr.span, msg); - return true; } } diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 055fdcabdd21..0e2012319147 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -81,7 +81,9 @@ pub(super) fn check<'tcx>( }, _ => return, }; - } else if let ExprKind::Index(_, index, _) = parent.kind { + } else if let ExprKind::Index(_, index, _) = parent.kind + && cx.typeck_results().expr_ty(index).is_usize() + { app = Applicability::MaybeIncorrect; let snip = snippet_with_applicability(cx, index.span, "_", &mut app); sugg = format!("nth({snip}).unwrap()"); diff --git a/clippy_lints/src/methods/obfuscated_if_else.rs b/clippy_lints/src/methods/obfuscated_if_else.rs index b2466bbd982d..69d851e81600 100644 --- a/clippy_lints/src/methods/obfuscated_if_else.rs +++ b/clippy_lints/src/methods/obfuscated_if_else.rs @@ -1,7 +1,7 @@ use super::OBFUSCATED_IF_ELSE; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::eager_or_lazy::switch_to_eager_eval; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::{get_parent_expr, sym}; use rustc_errors::Applicability; @@ -33,20 +33,22 @@ pub(super) fn check<'tcx>( let if_then = match then_method_name { sym::then if let ExprKind::Closure(closure) = then_arg.kind => { let body = cx.tcx.hir_body(closure.body); - snippet_with_applicability(cx, body.value.span, "..", &mut applicability) + snippet_with_context(cx, body.value.span, expr.span.ctxt(), "..", &mut applicability).0 }, - sym::then_some => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability), + sym::then_some => snippet_with_context(cx, then_arg.span, expr.span.ctxt(), "..", &mut applicability).0, _ => return, }; let els = match unwrap { - Unwrap::Or(arg) => snippet_with_applicability(cx, arg.span, "..", &mut applicability), + Unwrap::Or(arg) => snippet_with_context(cx, arg.span, expr.span.ctxt(), "..", &mut applicability).0, Unwrap::OrElse(arg) => match arg.kind { ExprKind::Closure(closure) => { let body = cx.tcx.hir_body(closure.body); - snippet_with_applicability(cx, body.value.span, "..", &mut applicability) + snippet_with_context(cx, body.value.span, expr.span.ctxt(), "..", &mut applicability).0 + }, + ExprKind::Path(_) => { + snippet_with_context(cx, arg.span, expr.span.ctxt(), "_", &mut applicability).0 + "()" }, - ExprKind::Path(_) => snippet_with_applicability(cx, arg.span, "_", &mut applicability) + "()", _ => return, }, Unwrap::OrDefault => "Default::default()".into(), @@ -54,7 +56,7 @@ pub(super) fn check<'tcx>( let sugg = format!( "if {} {{ {} }} else {{ {} }}", - Sugg::hir_with_applicability(cx, then_recv, "..", &mut applicability), + Sugg::hir_with_context(cx, then_recv, expr.span.ctxt(), "..", &mut applicability), if_then, els ); diff --git a/clippy_lints/src/methods/or_then_unwrap.rs b/clippy_lints/src/methods/or_then_unwrap.rs index 07199b84f39e..448ab621a7ce 100644 --- a/clippy_lints/src/methods/or_then_unwrap.rs +++ b/clippy_lints/src/methods/or_then_unwrap.rs @@ -20,24 +20,28 @@ pub(super) fn check<'tcx>( let title; let or_arg_content: Span; - if ty.is_diag_item(cx, sym::Option) { - title = "found `.or(Some(…)).unwrap()`"; - if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::OptionSome) { - or_arg_content = content; - } else { + match ty.opt_diag_name(cx) { + Some(sym::Option) => { + title = "found `.or(Some(…)).unwrap()`"; + if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::OptionSome) { + or_arg_content = content; + } else { + return; + } + }, + Some(sym::Result) => { + title = "found `.or(Ok(…)).unwrap()`"; + if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::ResultOk) { + or_arg_content = content; + } else { + return; + } + }, + _ => { + // Someone has implemented a struct with .or(...).unwrap() chaining, + // but it's not an Option or a Result, so bail return; - } - } else if ty.is_diag_item(cx, sym::Result) { - title = "found `.or(Ok(…)).unwrap()`"; - if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::ResultOk) { - or_arg_content = content; - } else { - return; - } - } else { - // Someone has implemented a struct with .or(...).unwrap() chaining, - // but it's not an Option or a Result, so bail - return; + }, } let mut applicability = Applicability::MachineApplicable; diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index bd471e0b18e3..9dae6fbb48dd 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -1,44 +1,52 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes}; +use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath, MaybeTypeckRes}; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{peel_blocks, strip_pat_refs}; +use clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_blocks, strip_pat_refs}; use rustc_ast::ast; use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::PatKind; +use rustc_hir::def::{DefKind, Res}; use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_span::{Span, sym}; +use rustc_middle::ty::{self, Ty}; +use rustc_span::{Span, Symbol, sym}; use super::UNNECESSARY_FOLD; /// Do we need to suggest turbofish when suggesting a replacement method? /// Changing `fold` to `sum` needs it sometimes when the return type can't be /// inferred. This checks for some common cases where it can be safely omitted -fn needs_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { - let parent = cx.tcx.parent_hir_node(expr.hir_id); - - // some common cases where turbofish isn't needed: - // - assigned to a local variable with a type annotation - if let hir::Node::LetStmt(local) = parent - && local.ty.is_some() +fn needs_turbofish<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) -> bool { + let use_cx = expr_use_ctxt(cx, expr); + if use_cx.same_ctxt + && let use_node = use_cx.use_node(cx) + && let Some(ty) = use_node.defined_ty(cx) { - return false; - } + // some common cases where turbofish isn't needed: + match (use_node, ty) { + // - assigned to a local variable with a type annotation + (ExprUseNode::LetStmt(_), _) => return false, - // - part of a function call argument, can be inferred from the function signature (provided that - // the parameter is not a generic type parameter) - if let hir::Node::Expr(parent_expr) = parent - && let hir::ExprKind::Call(recv, args) = parent_expr.kind - && let hir::ExprKind::Path(ref qpath) = recv.kind - && let Some(fn_def_id) = cx.qpath_res(qpath, recv.hir_id).opt_def_id() - && let fn_sig = cx.tcx.fn_sig(fn_def_id).skip_binder().skip_binder() - && let Some(arg_pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id) - && let Some(ty) = fn_sig.inputs().get(arg_pos) - && !matches!(ty.kind(), ty::Param(_)) - { - return false; + // - part of a function call argument, can be inferred from the function signature (provided that the + // parameter is not a generic type parameter) + (ExprUseNode::FnArg(..), DefinedTy::Mir { ty: arg_ty, .. }) + if !matches!(arg_ty.skip_binder().kind(), ty::Param(_)) => + { + return false; + }, + + // - the final expression in the body of a function with a simple return type + (ExprUseNode::Return(_), DefinedTy::Mir { ty: fn_return_ty, .. }) + if !fn_return_ty + .skip_binder() + .walk() + .any(|generic| generic.as_type().is_some_and(Ty::is_impl_trait)) => + { + return false; + }, + _ => {}, + } } // if it's neither of those, stay on the safe side and suggest turbofish, @@ -60,7 +68,7 @@ fn check_fold_with_op( fold_span: Span, op: hir::BinOpKind, replacement: Replacement, -) { +) -> bool { if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = acc.kind // Extract the body of the closure passed to fold && let closure_body = cx.tcx.hir_body(body) @@ -93,7 +101,7 @@ fn check_fold_with_op( r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability), ) } else { - format!("{method}{turbofish}()", method = replacement.method_name,) + format!("{method}{turbofish}()", method = replacement.method_name) }; span_lint_and_sugg( @@ -105,12 +113,47 @@ fn check_fold_with_op( sugg, applicability, ); + return true; + } + false +} + +fn check_fold_with_method( + cx: &LateContext<'_>, + expr: &hir::Expr<'_>, + acc: &hir::Expr<'_>, + fold_span: Span, + method: Symbol, + replacement: Replacement, +) { + // Extract the name of the function passed to `fold` + if let Res::Def(DefKind::AssocFn, fn_did) = acc.res_if_named(cx, method) + // Check if the function belongs to the operator + && cx.tcx.is_diagnostic_item(method, fn_did) + { + let applicability = Applicability::MachineApplicable; + + let turbofish = if replacement.has_generic_return { + format!("::<{}>", cx.typeck_results().expr_ty(expr)) + } else { + String::new() + }; + + span_lint_and_sugg( + cx, + UNNECESSARY_FOLD, + fold_span.with_hi(expr.span.hi()), + "this `.fold` can be written more succinctly using another method", + "try", + format!("{method}{turbofish}()", method = replacement.method_name), + applicability, + ); } } -pub(super) fn check( - cx: &LateContext<'_>, - expr: &hir::Expr<'_>, +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &hir::Expr<'tcx>, init: &hir::Expr<'_>, acc: &hir::Expr<'_>, fold_span: Span, @@ -124,60 +167,40 @@ pub(super) fn check( if let hir::ExprKind::Lit(lit) = init.kind { match lit.node { ast::LitKind::Bool(false) => { - check_fold_with_op( - cx, - expr, - acc, - fold_span, - hir::BinOpKind::Or, - Replacement { - method_name: "any", - has_args: true, - has_generic_return: false, - }, - ); + let replacement = Replacement { + method_name: "any", + has_args: true, + has_generic_return: false, + }; + check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Or, replacement); }, ast::LitKind::Bool(true) => { - check_fold_with_op( - cx, - expr, - acc, - fold_span, - hir::BinOpKind::And, - Replacement { - method_name: "all", - has_args: true, - has_generic_return: false, - }, - ); + let replacement = Replacement { + method_name: "all", + has_args: true, + has_generic_return: false, + }; + check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, replacement); }, ast::LitKind::Int(Pu128(0), _) => { - check_fold_with_op( - cx, - expr, - acc, - fold_span, - hir::BinOpKind::Add, - Replacement { - method_name: "sum", - has_args: false, - has_generic_return: needs_turbofish(cx, expr), - }, - ); + let replacement = Replacement { + method_name: "sum", + has_args: false, + has_generic_return: needs_turbofish(cx, expr), + }; + if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Add, replacement) { + check_fold_with_method(cx, expr, acc, fold_span, sym::add, replacement); + } }, ast::LitKind::Int(Pu128(1), _) => { - check_fold_with_op( - cx, - expr, - acc, - fold_span, - hir::BinOpKind::Mul, - Replacement { - method_name: "product", - has_args: false, - has_generic_return: needs_turbofish(cx, expr), - }, - ); + let replacement = Replacement { + method_name: "product", + has_args: false, + has_generic_return: needs_turbofish(cx, expr), + }; + if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, replacement) { + check_fold_with_method(cx, expr, acc, fold_span, sym::mul, replacement); + } }, _ => (), } diff --git a/clippy_lints/src/methods/unnecessary_get_then_check.rs b/clippy_lints/src/methods/unnecessary_get_then_check.rs index 10ea0c0c3e23..3207c4207fc0 100644 --- a/clippy_lints/src/methods/unnecessary_get_then_check.rs +++ b/clippy_lints/src/methods/unnecessary_get_then_check.rs @@ -11,11 +11,11 @@ use rustc_span::{Span, sym}; use super::UNNECESSARY_GET_THEN_CHECK; fn is_a_std_set_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - ty.is_diag_item(cx, sym::HashSet) || ty.is_diag_item(cx, sym::BTreeSet) + matches!(ty.opt_diag_name(cx), Some(sym::HashSet | sym::BTreeSet)) } fn is_a_std_map_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap) + matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) } pub(super) fn check( diff --git a/clippy_lints/src/methods/unwrap_expect_used.rs b/clippy_lints/src/methods/unwrap_expect_used.rs index 73a407be4f21..30db2a75df57 100644 --- a/clippy_lints/src/methods/unwrap_expect_used.rs +++ b/clippy_lints/src/methods/unwrap_expect_used.rs @@ -46,19 +46,19 @@ pub(super) fn check( ) { let ty = cx.typeck_results().expr_ty(recv).peel_refs(); - let (kind, none_value, none_prefix) = if ty.is_diag_item(cx, sym::Option) && !is_err { - ("an `Option`", "None", "") - } else if ty.is_diag_item(cx, sym::Result) - && let ty::Adt(_, substs) = ty.kind() - && let Some(t_or_e_ty) = substs[usize::from(!is_err)].as_type() - { - if is_never_like(t_or_e_ty) { - return; - } + let (kind, none_value, none_prefix) = match ty.opt_diag_name(cx) { + Some(sym::Option) if !is_err => ("an `Option`", "None", ""), + Some(sym::Result) + if let ty::Adt(_, substs) = ty.kind() + && let Some(t_or_e_ty) = substs[usize::from(!is_err)].as_type() => + { + if is_never_like(t_or_e_ty) { + return; + } - ("a `Result`", if is_err { "Ok" } else { "Err" }, "an ") - } else { - return; + ("a `Result`", if is_err { "Ok" } else { "Err" }, "an ") + }, + _ => return, }; let method_suffix = if is_err { "_err" } else { "" }; diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs index 15b773c2c64f..a26f24d15247 100644 --- a/clippy_lints/src/missing_fields_in_debug.rs +++ b/clippy_lints/src/missing_fields_in_debug.rs @@ -112,10 +112,14 @@ fn should_lint<'tcx>( if let ExprKind::MethodCall(path, recv, ..) = &expr.kind { let recv_ty = typeck_results.expr_ty(recv).peel_refs(); - if path.ident.name == sym::debug_struct && recv_ty.is_diag_item(cx, sym::Formatter) { - has_debug_struct = true; - } else if path.ident.name == sym::finish_non_exhaustive && recv_ty.is_diag_item(cx, sym::DebugStruct) { - has_finish_non_exhaustive = true; + match (path.ident.name, recv_ty.opt_diag_name(cx)) { + (sym::debug_struct, Some(sym::Formatter)) => { + has_debug_struct = true; + }, + (sym::finish_non_exhaustive, Some(sym::DebugStruct)) => { + has_finish_non_exhaustive = true; + }, + _ => {}, } } ControlFlow::::Continue(()) diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 80cf081992cc..42dc9f2f1fa8 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -3,13 +3,14 @@ use clippy_utils::diagnostics::span_lint_and_then; use hir::def::{DefKind, Res}; use hir::{BlockCheckMode, ExprKind, QPath, UnOp}; use rustc_ast::{BorrowKind, Mutability}; +use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::intravisit::{Visitor, walk_body, walk_expr}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt, TypeckResults}; use rustc_session::declare_lint_pass; -use rustc_span::{DesugaringKind, Span}; +use rustc_span::Span; declare_clippy_lint! { /// ### What it does @@ -56,12 +57,16 @@ declare_clippy_lint! { /// } /// ``` /// - /// ### Note + /// ### Notes /// - /// Taking a raw pointer to a union field is always safe and will - /// not be considered unsafe by this lint, even when linting code written - /// with a specified Rust version of 1.91 or earlier (which required - /// using an `unsafe` block). + /// - Unsafe operations only count towards the total for the innermost + /// enclosing `unsafe` block. + /// - Each call to a macro expanding to unsafe operations count for one + /// unsafe operation. + /// - Taking a raw pointer to a union field is always safe and will + /// not be considered unsafe by this lint, even when linting code written + /// with a specified Rust version of 1.91 or earlier (which required + /// using an `unsafe` block). #[clippy::version = "1.69.0"] pub MULTIPLE_UNSAFE_OPS_PER_BLOCK, restriction, @@ -71,10 +76,7 @@ declare_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK]) impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock { fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) { - if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) - || block.span.in_external_macro(cx.tcx.sess.source_map()) - || block.span.is_desugaring(DesugaringKind::Await) - { + if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) || block.span.from_expansion() { return; } let unsafe_ops = UnsafeExprCollector::collect_unsafe_exprs(cx, block); @@ -100,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock { struct UnsafeExprCollector<'tcx> { tcx: TyCtxt<'tcx>, typeck_results: &'tcx TypeckResults<'tcx>, - unsafe_ops: Vec<(&'static str, Span)>, + unsafe_ops: FxHashMap, } impl<'tcx> UnsafeExprCollector<'tcx> { @@ -108,10 +110,33 @@ impl<'tcx> UnsafeExprCollector<'tcx> { let mut collector = Self { tcx: cx.tcx, typeck_results: cx.typeck_results(), - unsafe_ops: vec![], + unsafe_ops: FxHashMap::default(), }; collector.visit_block(block); - collector.unsafe_ops + #[allow( + rustc::potential_query_instability, + reason = "span ordering only needed inside the one expression being walked" + )] + let mut unsafe_ops = collector + .unsafe_ops + .into_iter() + .map(|(span, msg)| (msg, span)) + .collect::>(); + unsafe_ops.sort_unstable(); + unsafe_ops + } +} + +impl UnsafeExprCollector<'_> { + fn insert_span(&mut self, span: Span, message: &'static str) { + if span.from_expansion() { + self.unsafe_ops.insert( + span.source_callsite(), + "this macro call expands into one or more unsafe operations", + ); + } else { + self.unsafe_ops.insert(span, message); + } } } @@ -126,7 +151,10 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { return self.visit_expr(e); }, - ExprKind::InlineAsm(_) => self.unsafe_ops.push(("inline assembly used here", expr.span)), + // Do not recurse inside an inner `unsafe` block, it will be checked on its own + ExprKind::Block(block, _) if matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) => return, + + ExprKind::InlineAsm(_) => self.insert_span(expr.span, "inline assembly used here"), ExprKind::AddrOf(BorrowKind::Raw, _, mut inner) => { while let ExprKind::Field(prefix, _) = inner.kind @@ -139,7 +167,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { ExprKind::Field(e, _) => { if self.typeck_results.expr_ty(e).is_union() { - self.unsafe_ops.push(("union field access occurs here", expr.span)); + self.insert_span(expr.span, "union field access occurs here"); } }, @@ -157,12 +185,11 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { .. }, )) => { - self.unsafe_ops - .push(("access of a mutable static occurs here", expr.span)); + self.insert_span(expr.span, "access of a mutable static occurs here"); }, ExprKind::Unary(UnOp::Deref, e) if self.typeck_results.expr_ty(e).is_raw_ptr() => { - self.unsafe_ops.push(("raw pointer dereference occurs here", expr.span)); + self.insert_span(expr.span, "raw pointer dereference occurs here"); }, ExprKind::Call(path_expr, _) => { @@ -172,7 +199,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { _ => None, }; if opt_sig.is_some_and(|sig| sig.safety().is_unsafe()) { - self.unsafe_ops.push(("unsafe function call occurs here", expr.span)); + self.insert_span(expr.span, "unsafe function call occurs here"); } }, @@ -182,7 +209,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { .type_dependent_def_id(expr.hir_id) .map(|def_id| self.tcx.fn_sig(def_id)); if opt_sig.is_some_and(|sig| sig.skip_binder().safety().is_unsafe()) { - self.unsafe_ops.push(("unsafe method call occurs here", expr.span)); + self.insert_span(expr.span, "unsafe method call occurs here"); } }, @@ -203,8 +230,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> { } )) ) { - self.unsafe_ops - .push(("modification of a mutable static occurs here", expr.span)); + self.insert_span(expr.span, "modification of a mutable static occurs here"); return self.visit_expr(rhs); } }, diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 3d2285efbe18..f3e42b1c58f8 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -1,7 +1,7 @@ use super::needless_pass_by_value::requires_exact_signature; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_hir_and_then; -use clippy_utils::source::snippet; +use clippy_utils::source::HasSession as _; use clippy_utils::visitors::for_each_expr; use clippy_utils::{inherits_cfg, is_from_proc_macro, is_self}; use core::ops::ControlFlow; @@ -18,9 +18,9 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath}; use rustc_session::impl_lint_pass; -use rustc_span::Span; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does @@ -269,18 +269,27 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { // If the argument is never used mutably, we emit the warning. let sp = input.span; if let rustc_hir::TyKind::Ref(_, inner_ty) = input.kind { + let Some(after_mut_span) = cx.sess().source_map().span_extend_to_prev_str( + inner_ty.ty.span.shrink_to_lo(), + "mut", + true, + true, + ) else { + return; + }; + let mut_span = after_mut_span.with_lo(after_mut_span.lo() - BytePos(3)); let is_cfged = is_cfged.get_or_insert_with(|| inherits_cfg(cx.tcx, *fn_def_id)); span_lint_hir_and_then( cx, NEEDLESS_PASS_BY_REF_MUT, cx.tcx.local_def_id_to_hir_id(*fn_def_id), sp, - "this argument is a mutable reference, but not used mutably", + "this parameter is a mutable reference but is not used mutably", |diag| { diag.span_suggestion( - sp, - "consider changing to".to_string(), - format!("&{}", snippet(cx, cx.tcx.hir_span(inner_ty.ty.hir_id), "_"),), + mut_span, + "consider removing this `mut`", + "", Applicability::Unspecified, ); if cx.effective_visibilities.is_exported(*fn_def_id) { diff --git a/clippy_lints/src/ptr/cmp_null.rs b/clippy_lints/src/ptr/cmp_null.rs index 905b48e6d1d4..f2d1c855eddd 100644 --- a/clippy_lints/src/ptr/cmp_null.rs +++ b/clippy_lints/src/ptr/cmp_null.rs @@ -14,13 +14,14 @@ pub(super) fn check<'tcx>( l: &Expr<'_>, r: &Expr<'_>, ) -> bool { + let mut applicability = Applicability::MachineApplicable; let non_null_path_snippet = match ( is_lint_allowed(cx, CMP_NULL, expr.hir_id), is_null_path(cx, l), is_null_path(cx, r), ) { - (false, true, false) if let Some(sugg) = Sugg::hir_opt(cx, r) => sugg.maybe_paren(), - (false, false, true) if let Some(sugg) = Sugg::hir_opt(cx, l) => sugg.maybe_paren(), + (false, true, false) => Sugg::hir_with_context(cx, r, expr.span.ctxt(), "..", &mut applicability).maybe_paren(), + (false, false, true) => Sugg::hir_with_context(cx, l, expr.span.ctxt(), "..", &mut applicability).maybe_paren(), _ => return false, }; let invert = if op == BinOpKind::Eq { "" } else { "!" }; @@ -32,7 +33,7 @@ pub(super) fn check<'tcx>( "comparing with null is better expressed by the `.is_null()` method", "try", format!("{invert}{non_null_path_snippet}.is_null()",), - Applicability::MachineApplicable, + applicability, ); true } diff --git a/clippy_lints/src/ptr/mod.rs b/clippy_lints/src/ptr/mod.rs index 6b2647e7b0a2..c4f40a7ffcaa 100644 --- a/clippy_lints/src/ptr/mod.rs +++ b/clippy_lints/src/ptr/mod.rs @@ -45,7 +45,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// This lint checks for equality comparisons with `ptr::null` + /// This lint checks for equality comparisons with `ptr::null` or `ptr::null_mut` /// /// ### Why is this bad? /// It's easier and more readable to use the inherent @@ -56,7 +56,7 @@ declare_clippy_lint! { /// ```rust,ignore /// use std::ptr; /// - /// if x == ptr::null { + /// if x == ptr::null() { /// // .. /// } /// ``` diff --git a/clippy_lints/src/same_length_and_capacity.rs b/clippy_lints/src/same_length_and_capacity.rs new file mode 100644 index 000000000000..042dec35f7c9 --- /dev/null +++ b/clippy_lints/src/same_length_and_capacity.rs @@ -0,0 +1,105 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::res::MaybeDef; +use clippy_utils::{eq_expr_value, sym}; +use rustc_hir::{Expr, ExprKind, LangItem, QPath}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; +use rustc_span::symbol::sym as rustc_sym; + +declare_clippy_lint! { + /// ### What it does + /// + /// Checks for usages of `Vec::from_raw_parts` and `String::from_raw_parts` + /// where the same expression is used for the length and the capacity. + /// + /// ### Why is this bad? + /// + /// If the same expression is being passed for the length and + /// capacity, it is most likely a semantic error. In the case of a + /// Vec, for example, the only way to end up with one that has + /// the same length and capacity is by going through a boxed slice, + /// e.g. `Box::from(some_vec)`, which shrinks the capacity to match + /// the length. + /// + /// ### Example + /// + /// ```no_run + /// #![feature(vec_into_raw_parts)] + /// let mut original: Vec:: = Vec::with_capacity(20); + /// original.extend([1, 2, 3, 4, 5]); + /// + /// let (ptr, mut len, cap) = original.into_raw_parts(); + /// + /// // I will add three more integers: + /// unsafe { + /// let ptr = ptr as *mut i32; + /// + /// for i in 6..9 { + /// *ptr.add(i - 1) = i as i32; + /// len += 1; + /// } + /// } + /// + /// // But I forgot the capacity was separate from the length: + /// let reconstructed = unsafe { Vec::from_raw_parts(ptr, len, len) }; + /// ``` + /// + /// Use instead: + /// ```no_run + /// #![feature(vec_into_raw_parts)] + /// let mut original: Vec:: = Vec::with_capacity(20); + /// original.extend([1, 2, 3, 4, 5]); + /// + /// let (ptr, mut len, cap) = original.into_raw_parts(); + /// + /// // I will add three more integers: + /// unsafe { + /// let ptr = ptr as *mut i32; + /// + /// for i in 6..9 { + /// *ptr.add(i - 1) = i as i32; + /// len += 1; + /// } + /// } + /// + /// // This time, leverage the previously saved capacity: + /// let reconstructed = unsafe { Vec::from_raw_parts(ptr, len, cap) }; + /// ``` + #[clippy::version = "1.93.0"] + pub SAME_LENGTH_AND_CAPACITY, + pedantic, + "`from_raw_parts` with same length and capacity" +} +declare_lint_pass!(SameLengthAndCapacity => [SAME_LENGTH_AND_CAPACITY]); + +impl<'tcx> LateLintPass<'tcx> for SameLengthAndCapacity { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::Call(path_expr, args) = expr.kind + && let ExprKind::Path(QPath::TypeRelative(ty, fn_path)) = path_expr.kind + && fn_path.ident.name == sym::from_raw_parts + && args.len() >= 3 + && eq_expr_value(cx, &args[1], &args[2]) + { + let middle_ty = cx.typeck_results().node_type(ty.hir_id); + if middle_ty.is_diag_item(cx, rustc_sym::Vec) { + span_lint_and_help( + cx, + SAME_LENGTH_AND_CAPACITY, + expr.span, + "usage of `Vec::from_raw_parts` with the same expression for length and capacity", + None, + "try `Box::from(slice::from_raw_parts(...)).into::>()`", + ); + } else if middle_ty.is_lang_item(cx, LangItem::String) { + span_lint_and_help( + cx, + SAME_LENGTH_AND_CAPACITY, + expr.span, + "usage of `String::from_raw_parts` with the same expression for length and capacity", + None, + "try `String::from(str::from_utf8_unchecked(slice::from_raw_parts(...)))`", + ); + } + } + } +} diff --git a/clippy_lints/src/set_contains_or_insert.rs b/clippy_lints/src/set_contains_or_insert.rs index 688da33a1777..7482bac4c7b4 100644 --- a/clippy_lints/src/set_contains_or_insert.rs +++ b/clippy_lints/src/set_contains_or_insert.rs @@ -112,6 +112,16 @@ fn try_parse_op_call<'tcx>( None } +fn is_set_mutated<'tcx>(cx: &LateContext<'tcx>, contains_expr: &OpExpr<'tcx>, expr: &'tcx Expr<'_>) -> bool { + // Guard on type to avoid useless potentially expansive `SpanlessEq` checks + cx.typeck_results().expr_ty_adjusted(expr).is_mutable_ptr() + && matches!( + cx.typeck_results().expr_ty(expr).peel_refs().opt_diag_name(cx), + Some(sym::HashSet | sym::BTreeSet) + ) + && SpanlessEq::new(cx).eq_expr(contains_expr.receiver, expr.peel_borrows()) +} + fn find_insert_calls<'tcx>( cx: &LateContext<'tcx>, contains_expr: &OpExpr<'tcx>, @@ -122,9 +132,14 @@ fn find_insert_calls<'tcx>( && SpanlessEq::new(cx).eq_expr(contains_expr.receiver, insert_expr.receiver) && SpanlessEq::new(cx).eq_expr(contains_expr.value, insert_expr.value) { - ControlFlow::Break(insert_expr) - } else { - ControlFlow::Continue(()) + return ControlFlow::Break(Some(insert_expr)); } + + if is_set_mutated(cx, contains_expr, e) { + return ControlFlow::Break(None); + } + + ControlFlow::Continue(()) }) + .flatten() } diff --git a/clippy_lints/src/time_subtraction.rs b/clippy_lints/src/time_subtraction.rs index e0fdca97dbee..3ba59aefea06 100644 --- a/clippy_lints/src/time_subtraction.rs +++ b/clippy_lints/src/time_subtraction.rs @@ -8,7 +8,6 @@ use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::impl_lint_pass; -use rustc_span::source_map::Spanned; use rustc_span::sym; declare_clippy_lint! { @@ -84,43 +83,38 @@ impl_lint_pass!(UncheckedTimeSubtraction => [MANUAL_INSTANT_ELAPSED, UNCHECKED_T impl LateLintPass<'_> for UncheckedTimeSubtraction { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) { - if let ExprKind::Binary( - Spanned { - node: BinOpKind::Sub, .. + let (lhs, rhs) = match expr.kind { + ExprKind::Binary(op, lhs, rhs) if matches!(op.node, BinOpKind::Sub,) => (lhs, rhs), + ExprKind::MethodCall(fn_name, lhs, [rhs], _) if cx.ty_based_def(expr).is_diag_item(cx, sym::sub) => { + (lhs, rhs) }, - lhs, - rhs, - ) = expr.kind - { - let typeck = cx.typeck_results(); - let lhs_ty = typeck.expr_ty(lhs); - let rhs_ty = typeck.expr_ty(rhs); + _ => return, + }; + let typeck = cx.typeck_results(); + let lhs_name = typeck.expr_ty(lhs).opt_diag_name(cx); + let rhs_name = typeck.expr_ty(rhs).opt_diag_name(cx); - if lhs_ty.is_diag_item(cx, sym::Instant) { - // Instant::now() - instant - if is_instant_now_call(cx, lhs) - && rhs_ty.is_diag_item(cx, sym::Instant) - && let Some(sugg) = Sugg::hir_opt(cx, rhs) - { - print_manual_instant_elapsed_sugg(cx, expr, sugg); - } - // instant - duration - else if rhs_ty.is_diag_item(cx, sym::Duration) - && !expr.span.from_expansion() - && self.msrv.meets(cx, msrvs::TRY_FROM) - { - print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); - } + if lhs_name == Some(sym::Instant) { + // Instant::now() - instant + if is_instant_now_call(cx, lhs) && rhs_name == Some(sym::Instant) { + print_manual_instant_elapsed_sugg(cx, expr, rhs); } - // duration - duration - else if lhs_ty.is_diag_item(cx, sym::Duration) - && rhs_ty.is_diag_item(cx, sym::Duration) + // instant - duration + else if rhs_name == Some(sym::Duration) && !expr.span.from_expansion() && self.msrv.meets(cx, msrvs::TRY_FROM) { print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); } } + // duration - duration + else if lhs_name == Some(sym::Duration) + && rhs_name == Some(sym::Duration) + && !expr.span.from_expansion() + && self.msrv.meets(cx, msrvs::TRY_FROM) + { + print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); + } } } @@ -150,10 +144,12 @@ fn is_chained_time_subtraction(cx: &LateContext<'_>, lhs: &Expr<'_>) -> bool { /// Returns true if the type is Duration or Instant fn is_time_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - ty.is_diag_item(cx, sym::Duration) || ty.is_diag_item(cx, sym::Instant) + matches!(ty.opt_diag_name(cx), Some(sym::Duration | sym::Instant)) } -fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, sugg: Sugg<'_>) { +fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, rhs: &Expr<'_>) { + let mut applicability = Applicability::MachineApplicable; + let sugg = Sugg::hir_with_context(cx, rhs, expr.span.ctxt(), "", &mut applicability); span_lint_and_sugg( cx, MANUAL_INSTANT_ELAPSED, @@ -161,7 +157,7 @@ fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, sugg "manual implementation of `Instant::elapsed`", "try", format!("{}.elapsed()", sugg.maybe_paren()), - Applicability::MachineApplicable, + applicability, ); } @@ -181,8 +177,9 @@ fn print_unchecked_duration_subtraction_sugg( // avoid suggestions if !is_chained_time_subtraction(cx, left_expr) { let mut applicability = Applicability::MachineApplicable; - let left_sugg = Sugg::hir_with_applicability(cx, left_expr, "", &mut applicability); - let right_sugg = Sugg::hir_with_applicability(cx, right_expr, "", &mut applicability); + let left_sugg = Sugg::hir_with_context(cx, left_expr, expr.span.ctxt(), "", &mut applicability); + let right_sugg = + Sugg::hir_with_context(cx, right_expr, expr.span.ctxt(), "", &mut applicability); diag.span_suggestion( expr.span, diff --git a/clippy_lints/src/transmute/transmuting_null.rs b/clippy_lints/src/transmute/transmuting_null.rs index 1a6262f2ff76..31e770f421e1 100644 --- a/clippy_lints/src/transmute/transmuting_null.rs +++ b/clippy_lints/src/transmute/transmuting_null.rs @@ -1,6 +1,6 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint; -use clippy_utils::is_integer_literal; +use clippy_utils::is_integer_const; use clippy_utils::res::{MaybeDef, MaybeResPath}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; @@ -27,7 +27,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t // Catching: // `std::mem::transmute(0 as *const i32)` if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind - && is_integer_literal(inner_expr, 0) + && is_integer_const(cx, inner_expr, 0) { span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG); return true; @@ -42,10 +42,5 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t return true; } - // FIXME: - // Also catch transmutations of variables which are known nulls. - // To do this, MIR const propagation seems to be the better tool. - // Whenever MIR const prop routines are more developed, this will - // become available. As of this writing (25/03/19) it is not yet. false } diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index eba60501ae21..38ce9dc3f916 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -10,13 +10,14 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty}; use rustc_hir::{ self as hir, AmbigArg, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParamKind, HirId, Impl, - ImplItemImplKind, ImplItemKind, Item, ItemKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind, + ImplItemImplKind, ImplItemKind, Item, ItemKind, Node, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty as MiddleTy; use rustc_session::impl_lint_pass; use rustc_span::Span; use std::iter; +use std::ops::ControlFlow; declare_clippy_lint! { /// ### What it does @@ -213,6 +214,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { path.res, Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Def(DefKind::TyParam, _) ) + && !ty_is_in_generic_args(cx, hir_ty) && !types_to_skip.contains(&hir_ty.hir_id) && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty()) && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity() @@ -312,6 +314,38 @@ fn lint_path_to_variant(cx: &LateContext<'_>, path: &Path<'_>) { } } +fn ty_is_in_generic_args<'tcx>(cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) -> bool { + cx.tcx.hir_parent_iter(hir_ty.hir_id).any(|(_, parent)| { + matches!(parent, Node::ImplItem(impl_item) if impl_item.generics.params.iter().any(|param| { + let GenericParamKind::Const { ty: const_ty, .. } = ¶m.kind else { + return false; + }; + ty_contains_ty(const_ty, hir_ty) + })) + }) +} + +fn ty_contains_ty<'tcx>(outer: &Ty<'tcx>, inner: &Ty<'tcx, AmbigArg>) -> bool { + struct ContainsVisitor<'tcx> { + inner: &'tcx Ty<'tcx, AmbigArg>, + } + + impl<'tcx> Visitor<'tcx> for ContainsVisitor<'tcx> { + type Result = ControlFlow<()>; + + fn visit_ty(&mut self, t: &'tcx Ty<'tcx, AmbigArg>) -> Self::Result { + if t.hir_id == self.inner.hir_id { + return ControlFlow::Break(()); + } + + walk_ty(self, t) + } + } + + let mut visitor = ContainsVisitor { inner }; + visitor.visit_ty_unambig(outer).is_break() +} + /// Checks whether types `a` and `b` have the same lifetime parameters. /// /// This function does not check that types `a` and `b` are the same types. diff --git a/clippy_lints/src/write/empty_string.rs b/clippy_lints/src/write/empty_string.rs index e7eb99eb34ec..1291f2489a21 100644 --- a/clippy_lints/src/write/empty_string.rs +++ b/clippy_lints/src/write/empty_string.rs @@ -1,37 +1,43 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::MacroCall; use clippy_utils::source::expand_past_previous_comma; -use clippy_utils::sym; +use clippy_utils::{span_extract_comments, sym}; use rustc_ast::{FormatArgs, FormatArgsPiece}; use rustc_errors::Applicability; -use rustc_lint::LateContext; +use rustc_lint::{LateContext, LintContext}; use super::{PRINTLN_EMPTY_STRING, WRITELN_EMPTY_STRING}; pub(super) fn check(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &MacroCall, name: &str) { if let [FormatArgsPiece::Literal(sym::LF)] = &format_args.template[..] { - let mut span = format_args.span; - - let lint = if name == "writeln" { - span = expand_past_previous_comma(cx, span); - - WRITELN_EMPTY_STRING - } else { - PRINTLN_EMPTY_STRING - }; + let is_writeln = name == "writeln"; span_lint_and_then( cx, - lint, + if is_writeln { + WRITELN_EMPTY_STRING + } else { + PRINTLN_EMPTY_STRING + }, macro_call.span, format!("empty string literal in `{name}!`"), |diag| { - diag.span_suggestion( - span, - "remove the empty string", - String::new(), - Applicability::MachineApplicable, - ); + if span_extract_comments(cx.sess().source_map(), macro_call.span).is_empty() { + let closing_paren = cx.sess().source_map().span_extend_to_prev_char_before( + macro_call.span.shrink_to_hi(), + ')', + false, + ); + let mut span = format_args.span.with_hi(closing_paren.lo()); + if is_writeln { + span = expand_past_previous_comma(cx, span); + } + + diag.span_suggestion(span, "remove the empty string", "", Applicability::MachineApplicable); + } else { + // If there is a comment in the span of macro call, we don't provide an auto-fix suggestion. + diag.span_note(format_args.span, "remove the empty string"); + } }, ); } diff --git a/clippy_lints/src/zero_sized_map_values.rs b/clippy_lints/src/zero_sized_map_values.rs index bf133d26ed9d..94c2fb20d5f5 100644 --- a/clippy_lints/src/zero_sized_map_values.rs +++ b/clippy_lints/src/zero_sized_map_values.rs @@ -49,7 +49,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues { && !in_trait_impl(cx, hir_ty.hir_id) // We don't care about infer vars && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty()) - && (ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap)) + && matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) && let ty::Adt(_, args) = ty.kind() && let ty = args.type_at(1) // Ensure that no type information is missing, to avoid a delayed bug in the compiler if this is not the case. diff --git a/clippy_lints_internal/src/almost_standard_lint_formulation.rs b/clippy_lints_internal/src/almost_standard_lint_formulation.rs index 7eeec84720f7..b5a12606fb3e 100644 --- a/clippy_lints_internal/src/almost_standard_lint_formulation.rs +++ b/clippy_lints_internal/src/almost_standard_lint_formulation.rs @@ -1,9 +1,11 @@ use crate::lint_without_lint_pass::is_lint_ref_type; use clippy_utils::diagnostics::span_lint_and_help; use regex::Regex; +use rustc_ast::token::DocFragmentKind; use rustc_hir::{Attribute, Item, ItemKind, Mutability}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::{Span, Symbol}; declare_tool_lint! { /// ### What it does @@ -46,28 +48,22 @@ impl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { let mut check_next = false; if let ItemKind::Static(Mutability::Not, _, ty, _) = item.kind { - let lines = cx - .tcx - .hir_attrs(item.hir_id()) - .iter() - .filter_map(|attr| Attribute::doc_str(attr).map(|sym| (sym, attr))); + let lines = cx.tcx.hir_attrs(item.hir_id()).iter().filter_map(doc_attr); if is_lint_ref_type(cx, ty) { - for (line, attr) in lines { + for (line, span) in lines { let cur_line = line.as_str().trim(); if check_next && !cur_line.is_empty() { for formulation in &self.standard_formulations { let starts_with_correct_formulation = cur_line.starts_with(formulation.correction); if !starts_with_correct_formulation && formulation.wrong_pattern.is_match(cur_line) { - if let Some(ident) = attr.ident() { - span_lint_and_help( - cx, - ALMOST_STANDARD_LINT_FORMULATION, - ident.span, - "non-standard lint formulation", - None, - format!("consider using `{}`", formulation.correction), - ); - } + span_lint_and_help( + cx, + ALMOST_STANDARD_LINT_FORMULATION, + span, + "non-standard lint formulation", + None, + format!("consider using `{}`", formulation.correction), + ); return; } } @@ -84,3 +80,10 @@ impl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation { } } } + +fn doc_attr(attr: &Attribute) -> Option<(Symbol, Span)> { + match Attribute::doc_str_and_fragment_kind(attr) { + Some((symbol, DocFragmentKind::Raw(span))) => Some((symbol, span)), + _ => None, + } +} diff --git a/clippy_lints_internal/src/internal_paths.rs b/clippy_lints_internal/src/internal_paths.rs index 95bdf27b019c..14d4139a0065 100644 --- a/clippy_lints_internal/src/internal_paths.rs +++ b/clippy_lints_internal/src/internal_paths.rs @@ -17,6 +17,7 @@ pub static TY_CTXT: PathLookup = type_path!(rustc_middle::ty::TyCtxt); // Paths in clippy itself pub static CLIPPY_SYM_MODULE: PathLookup = type_path!(clippy_utils::sym); +pub static MAYBE_DEF: PathLookup = type_path!(clippy_utils::res::MaybeDef); pub static MSRV_STACK: PathLookup = type_path!(clippy_utils::msrvs::MsrvStack); pub static PATH_LOOKUP_NEW: PathLookup = value_path!(clippy_utils::paths::PathLookup::new); pub static SPAN_LINT_AND_THEN: PathLookup = value_path!(clippy_utils::diagnostics::span_lint_and_then); diff --git a/clippy_lints_internal/src/lib.rs b/clippy_lints_internal/src/lib.rs index d686ba73387c..cca5608fa6be 100644 --- a/clippy_lints_internal/src/lib.rs +++ b/clippy_lints_internal/src/lib.rs @@ -38,6 +38,7 @@ mod lint_without_lint_pass; mod msrv_attr_impl; mod outer_expn_data_pass; mod produce_ice; +mod repeated_is_diagnostic_item; mod symbols; mod unnecessary_def_path; mod unsorted_clippy_utils_paths; @@ -77,4 +78,5 @@ pub fn register_lints(store: &mut LintStore) { store.register_late_pass(|_| Box::new(msrv_attr_impl::MsrvAttrImpl)); store.register_late_pass(|_| Box::new(almost_standard_lint_formulation::AlmostStandardFormulation::new())); store.register_late_pass(|_| Box::new(unusual_names::UnusualNames)); + store.register_late_pass(|_| Box::new(repeated_is_diagnostic_item::RepeatedIsDiagnosticItem)); } diff --git a/clippy_lints_internal/src/repeated_is_diagnostic_item.rs b/clippy_lints_internal/src/repeated_is_diagnostic_item.rs new file mode 100644 index 000000000000..55fb78b1e296 --- /dev/null +++ b/clippy_lints_internal/src/repeated_is_diagnostic_item.rs @@ -0,0 +1,561 @@ +use std::iter; +use std::ops::ControlFlow; + +use crate::internal_paths::MAYBE_DEF; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; +use clippy_utils::source::{snippet_indent, snippet_with_applicability}; +use clippy_utils::visitors::for_each_expr; +use clippy_utils::{eq_expr_value, if_sequence, sym}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Node, StmtKind, UnOp}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::print::with_forced_trimmed_paths; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::Span; + +declare_tool_lint! { + /// ### What it does + /// Checks for repeated use of `MaybeDef::is_diag_item`/`TyCtxt::is_diagnostic_item`; + /// suggests to first call `MaybDef::opt_diag_name`/`TyCtxt::get_diagnostic_name` and then + /// compare the output with all the `Symbol`s. + /// + /// ### Why is this bad? + /// Each of such calls ultimately invokes the `diagnostic_items` query. + /// While the query is cached, it's still better to avoid calling it multiple times if possible. + /// + /// ### Example + /// ```no_run + /// ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result) + /// cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did) + /// + /// if ty.is_diag_item(cx, sym::Option) { + /// .. + /// } else if ty.is_diag_item(cx, sym::Result) { + /// .. + /// } else { + /// .. + /// } + /// + /// if cx.tcx.is_diagnostic_item(sym::Option, did) { + /// .. + /// } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + /// .. + /// } else { + /// .. + /// } + /// + /// { + /// if ty.is_diag_item(cx, sym::Option) { + /// .. + /// } + /// if ty.is_diag_item(cx, sym::Result) { + /// .. + /// } + /// } + /// + /// { + /// if cx.tcx.is_diagnostic_item(sym::Option, did) { + /// .. + /// } + /// if cx.tcx.is_diagnostic_item(sym::Result, did) { + /// .. + /// } + /// } + /// ``` + /// Use instead: + /// ```no_run + /// matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) + /// matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)) + /// + /// match ty.opt_diag_name(cx) { + /// Some(sym::Option) => { + /// .. + /// } + /// Some(sym::Result) => { + /// .. + /// } + /// _ => { + /// .. + /// } + /// } + /// + /// match cx.tcx.get_diagnostic_name(did) { + /// Some(sym::Option) => { + /// .. + /// } + /// Some(sym::Result) => { + /// .. + /// } + /// _ => { + /// .. + /// } + /// } + /// + /// { + /// let name = ty.opt_diag_name(cx); + /// if name == Some(sym::Option) { + /// .. + /// } + /// if name == Some(sym::Result) { + /// .. + /// } + /// } + /// + /// { + /// let name = cx.tcx.get_diagnostic_name(did); + /// if name == Some(sym::Option) { + /// .. + /// } + /// if name == Some(sym::Result) { + /// .. + /// } + /// } + /// ``` + pub clippy::REPEATED_IS_DIAGNOSTIC_ITEM, + Warn, + "repeated use of `MaybeDef::is_diag_item`/`TyCtxt::is_diagnostic_item`" +} +declare_lint_pass!(RepeatedIsDiagnosticItem => [REPEATED_IS_DIAGNOSTIC_ITEM]); + +const NOTE: &str = "each call performs the same compiler query -- it's faster to query once, and reuse the results"; + +impl<'tcx> LateLintPass<'tcx> for RepeatedIsDiagnosticItem { + #[expect(clippy::too_many_lines)] + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) { + for [(cond1, stmt1_span), (cond2, stmt2_span)] in block + .stmts + .windows(2) + .filter_map(|pair| { + if let [if1, if2] = pair + && let StmtKind::Expr(e1) | StmtKind::Semi(e1) = if1.kind + && let ExprKind::If(cond1, ..) = e1.kind + && let StmtKind::Expr(e2) | StmtKind::Semi(e2) = if2.kind + && let ExprKind::If(cond2, ..) = e2.kind + { + Some([(cond1, if1.span), (cond2, if2.span)]) + } else { + None + } + }) + .chain( + if let Some(if1) = block.stmts.last() + && let StmtKind::Expr(e1) | StmtKind::Semi(e1) = if1.kind + && let ExprKind::If(cond1, ..) = e1.kind + && let Some(e2) = block.expr + && let ExprKind::If(cond2, ..) = e2.kind + { + Some([(cond1, if1.span), (cond2, e2.span)]) + } else { + None + }, + ) + { + let lint_span = stmt1_span.to(stmt2_span); + + // if recv1.is_diag_item(cx, sym1) && .. { + // .. + // } + // if recv2.is_diag_item(cx, sym2) && .. { + // .. + // } + if let Some(first @ (span1, (cx1, recv1, _))) = extract_nested_is_diag_item(cx, cond1) + && let Some(second @ (span2, (cx2, recv2, _))) = extract_nested_is_diag_item(cx, cond2) + && eq_expr_value(cx, cx1, cx2) + && eq_expr_value(cx, recv1, recv2) + { + let recv_ty = + with_forced_trimmed_paths!(format!("{}", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs())); + let recv_ty = recv_ty.trim_end_matches("<'_>"); + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + lint_span, + format!("repeated calls to `{recv_ty}::is_diag_item`"), + |diag| { + diag.span_labels([span1, span2], "called here"); + diag.note(NOTE); + + let mut app = Applicability::HasPlaceholders; + let cx_str = snippet_with_applicability(cx, cx1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, recv1.span, "_", &mut app); + let indent = snippet_indent(cx, stmt1_span).unwrap_or_default(); + let sugg: Vec<_> = iter::once(( + stmt1_span.shrink_to_lo(), + format!("let /* name */ = {recv}.opt_diag_name({cx_str});\n{indent}"), + )) // call `opt_diag_name` once + .chain([first, second].into_iter().map(|(expr_span, (_, _, sym))| { + let sym = snippet_with_applicability(cx, sym.span, "_", &mut app); + (expr_span, format!("/* name */ == Some({sym})")) + })) + .collect(); + + diag.multipart_suggestion_verbose( + format!("call `{recv_ty}::opt_diag_name`, and reuse the results"), + sugg, + app, + ); + }, + ); + return; + } + + // if cx.tcx.is_diagnostic_item(sym1, did) && .. { + // .. + // } + // if cx.tcx.is_diagnostic_item(sym2, did) && .. { + // .. + // } + if let Some(first @ (span1, (tcx1, did1, _))) = extract_nested_is_diagnostic_item(cx, cond1) + && let Some(second @ (span2, (tcx2, did2, _))) = extract_nested_is_diagnostic_item(cx, cond2) + && eq_expr_value(cx, tcx1, tcx2) + && eq_expr_value(cx, did1, did2) + { + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + lint_span, + "repeated calls to `TyCtxt::is_diagnostic_item`", + |diag| { + diag.span_labels([span1, span2], "called here"); + diag.note(NOTE); + + let mut app = Applicability::HasPlaceholders; + let tcx = snippet_with_applicability(cx, tcx1.span, "_", &mut app); + let did = snippet_with_applicability(cx, did1.span, "_", &mut app); + let indent = snippet_indent(cx, stmt1_span).unwrap_or_default(); + let sugg: Vec<_> = iter::once(( + stmt1_span.shrink_to_lo(), + format!("let /* name */ = {tcx}.get_diagnostic_name({did});\n{indent}"), + )) // call `get_diagnostic_name` once + .chain([first, second].into_iter().map(|(expr_span, (_, _, sym))| { + let sym = snippet_with_applicability(cx, sym.span, "_", &mut app); + (expr_span, format!("/* name */ == Some({sym})")) + })) + .collect(); + + diag.multipart_suggestion_verbose( + "call `TyCtxt::get_diagnostic_name`, and reuse the results", + sugg, + app, + ); + }, + ); + } + } + } + + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::Binary(op, left, right) = expr.kind { + if op.node == BinOpKind::Or { + check_ors(cx, expr.span, left, right); + } else if op.node == BinOpKind::And + && let ExprKind::Unary(UnOp::Not, left) = left.kind + && let ExprKind::Unary(UnOp::Not, right) = right.kind + { + check_ands(cx, expr.span, left, right); + } + } else if let (conds, _) = if_sequence(expr) + && !conds.is_empty() + { + check_if_chains(cx, expr, conds); + } + } +} + +fn check_ors(cx: &LateContext<'_>, span: Span, left: &Expr<'_>, right: &Expr<'_>) { + // recv1.is_diag_item(cx, sym1) || recv2.is_diag_item(cx, sym2) + if let Some((cx1, recv1, sym1)) = extract_is_diag_item(cx, left) + && let Some((cx2, recv2, sym2)) = extract_is_diag_item(cx, right) + && eq_expr_value(cx, cx1, cx2) + && eq_expr_value(cx, recv1, recv2) + { + let recv_ty = + with_forced_trimmed_paths!(format!("{}", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs())); + let recv_ty = recv_ty.trim_end_matches("<'_>"); + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + span, + format!("repeated calls to `{recv_ty}::is_diag_item`"), + |diag| { + diag.note(NOTE); + + let mut app = Applicability::MachineApplicable; + let cx_str = snippet_with_applicability(cx, cx1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, recv1.span, "_", &mut app); + let sym1 = snippet_with_applicability(cx, sym1.span, "_", &mut app); + let sym2 = snippet_with_applicability(cx, sym2.span, "_", &mut app); + diag.span_suggestion_verbose( + span, + format!("call `{recv_ty}::opt_diag_name`, and reuse the results"), + format!("matches!({recv}.opt_diag_name({cx_str}), Some({sym1} | {sym2}))"), + app, + ); + }, + ); + return; + } + + // cx.tcx.is_diagnostic_item(sym1, did) || cx.tcx.is_diagnostic_item(sym2, did) + if let Some((tcx1, did1, sym1)) = extract_is_diagnostic_item(cx, left) + && let Some((tcx2, did2, sym2)) = extract_is_diagnostic_item(cx, right) + && eq_expr_value(cx, tcx1, tcx2) + && eq_expr_value(cx, did1, did2) + { + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + span, + "repeated calls to `TyCtxt::is_diagnostic_item`", + |diag| { + diag.note(NOTE); + + let mut app = Applicability::MachineApplicable; + let tcx = snippet_with_applicability(cx, tcx1.span, "_", &mut app); + let did = snippet_with_applicability(cx, did1.span, "_", &mut app); + let sym1 = snippet_with_applicability(cx, sym1.span, "_", &mut app); + let sym2 = snippet_with_applicability(cx, sym2.span, "_", &mut app); + diag.span_suggestion_verbose( + span, + "call `TyCtxt::get_diagnostic_name`, and reuse the results", + format!("matches!({tcx}.get_diagnostic_name({did}), Some({sym1} | {sym2}))"), + app, + ); + }, + ); + } +} + +fn check_ands(cx: &LateContext<'_>, span: Span, left: &Expr<'_>, right: &Expr<'_>) { + // !recv1.is_diag_item(cx, sym1) && !recv2.is_diag_item(cx, sym2) + if let Some((cx1, recv1, sym1)) = extract_is_diag_item(cx, left) + && let Some((cx2, recv2, sym2)) = extract_is_diag_item(cx, right) + && eq_expr_value(cx, cx1, cx2) + && eq_expr_value(cx, recv1, recv2) + { + let recv_ty = + with_forced_trimmed_paths!(format!("{}", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs())); + let recv_ty = recv_ty.trim_end_matches("<'_>"); + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + span, + format!("repeated calls to `{recv_ty}::is_diag_item`"), + |diag| { + diag.note(NOTE); + + let mut app = Applicability::MachineApplicable; + let cx_str = snippet_with_applicability(cx, cx1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, recv1.span, "_", &mut app); + let sym1 = snippet_with_applicability(cx, sym1.span, "_", &mut app); + let sym2 = snippet_with_applicability(cx, sym2.span, "_", &mut app); + diag.span_suggestion_verbose( + span, + format!("call `{recv_ty}::opt_diag_name`, and reuse the results"), + format!("!matches!({recv}.opt_diag_name({cx_str}), Some({sym1} | {sym2}))"), + app, + ); + }, + ); + return; + } + + // !cx.tcx.is_diagnostic_item(sym1, did) && !cx.tcx.is_diagnostic_item(sym2, did) + if let Some((tcx1, did1, sym1)) = extract_is_diagnostic_item(cx, left) + && let Some((tcx2, did2, sym2)) = extract_is_diagnostic_item(cx, right) + && eq_expr_value(cx, tcx1, tcx2) + && eq_expr_value(cx, did1, did2) + { + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + span, + "repeated calls to `TyCtxt::is_diagnostic_item`", + |diag| { + diag.note(NOTE); + + let mut app = Applicability::MachineApplicable; + let tcx = snippet_with_applicability(cx, tcx1.span, "_", &mut app); + let did = snippet_with_applicability(cx, did1.span, "_", &mut app); + let sym1 = snippet_with_applicability(cx, sym1.span, "_", &mut app); + let sym2 = snippet_with_applicability(cx, sym2.span, "_", &mut app); + diag.span_suggestion_verbose( + span, + "call `TyCtxt::get_diagnostic_name`, and reuse the results", + format!("!matches!({tcx}.get_diagnostic_name({did}), Some({sym1} | {sym2}))"), + app, + ); + }, + ); + } +} + +fn check_if_chains<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, conds: Vec<&'tcx Expr<'_>>) { + // if ty.is_diag_item(cx, sym1) { + // .. + // } else if ty.is_diag_item(cx, sym2) { + // .. + // } else { + // .. + // } + let mut found = conds.iter().filter_map(|cond| extract_nested_is_diag_item(cx, cond)); + if let Some(first @ (_, (cx_1, recv1, _))) = found.next() + && let other = + found.filter(|(_, (cx_, recv, _))| eq_expr_value(cx, cx_, cx_1) && eq_expr_value(cx, recv, recv1)) + && let results = iter::once(first).chain(other).collect::>() + && results.len() > 1 + { + let recv_ty = + with_forced_trimmed_paths!(format!("{}", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs())); + let recv_ty = recv_ty.trim_end_matches("<'_>"); + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + expr.span, + format!("repeated calls to `{recv_ty}::is_diag_item`"), + |diag| { + diag.span_labels(results.iter().map(|(span, _)| *span), "called here"); + diag.note(NOTE); + + let mut app = Applicability::HasPlaceholders; + let cx_str = snippet_with_applicability(cx, cx_1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, recv1.span, "_", &mut app); + let span_before = if let Node::LetStmt(let_stmt) = cx.tcx.parent_hir_node(expr.hir_id) { + let_stmt.span + } else { + expr.span + }; + let indent = snippet_indent(cx, span_before).unwrap_or_default(); + let sugg: Vec<_> = iter::once(( + span_before.shrink_to_lo(), + format!("let /* name */ = {recv}.opt_diag_name({cx_str});\n{indent}"), + )) // call `opt_diag_name` once + .chain(results.into_iter().map(|(expr_span, (_, _, sym))| { + let sym = snippet_with_applicability(cx, sym.span, "_", &mut app); + (expr_span, format!("/* name */ == Some({sym})")) + })) + .collect(); + + diag.multipart_suggestion_verbose( + format!("call `{recv_ty}::opt_diag_name`, and reuse the results"), + sugg, + app, + ); + }, + ); + } + + // if cx.tcx.is_diagnostic_item(sym1, did) { + // .. + // } else if cx.tcx.is_diagnostic_item(sym2, did) { + // .. + // } else { + // .. + // } + let mut found = conds + .into_iter() + .filter_map(|cond| extract_nested_is_diagnostic_item(cx, cond)); + if let Some(first @ (_, (tcx1, did1, _))) = found.next() + && let other = found.filter(|(_, (tcx, did, _))| eq_expr_value(cx, tcx, tcx1) && eq_expr_value(cx, did, did1)) + && let results = iter::once(first).chain(other).collect::>() + && results.len() > 1 + { + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + expr.span, + "repeated calls to `TyCtxt::is_diagnostic_item`", + |diag| { + diag.span_labels(results.iter().map(|(span, _)| *span), "called here"); + diag.note(NOTE); + + let mut app = Applicability::HasPlaceholders; + let tcx = snippet_with_applicability(cx, tcx1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, did1.span, "_", &mut app); + let span_before = if let Node::LetStmt(let_stmt) = cx.tcx.parent_hir_node(expr.hir_id) { + let_stmt.span + } else { + expr.span + }; + let indent = snippet_indent(cx, span_before).unwrap_or_default(); + let sugg: Vec<_> = iter::once(( + span_before.shrink_to_lo(), + format!("let /* name */ = {tcx}.get_diagnostic_name({recv});\n{indent}"), + )) // call `get_diagnostic_name` once + .chain(results.into_iter().map(|(expr_span, (_, _, sym))| { + let sym = snippet_with_applicability(cx, sym.span, "_", &mut app); + (expr_span, format!("/* name */ == Some({sym})")) + })) + .collect(); + + diag.multipart_suggestion_verbose( + "call `TyCtxt::get_diagnostic_name`, and reuse the results", + sugg, + app, + ); + }, + ); + } +} + +fn extract_is_diag_item<'tcx>( + cx: &LateContext<'_>, + expr: &'tcx Expr<'tcx>, +) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> { + if let ExprKind::MethodCall(is_diag_item, recv, [cx_, sym], _) = expr.kind + && is_diag_item.ident.name == sym::is_diag_item + // Whether this a method from the `MaybeDef` trait + && let Some(did) = cx.ty_based_def(expr).opt_parent(cx).opt_def_id() + && MAYBE_DEF.matches(cx, did) + { + Some((cx_, recv, sym)) + } else { + None + } +} + +fn extract_is_diagnostic_item<'tcx>( + cx: &LateContext<'_>, + expr: &'tcx Expr<'tcx>, +) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> { + if let ExprKind::MethodCall(is_diag_item, tcx, [sym, did], _) = expr.kind + && is_diag_item.ident.name == sym::is_diagnostic_item + // Whether this is an inherent method on `TyCtxt` + && cx + .ty_based_def(expr) + .opt_parent(cx) + .opt_impl_ty(cx) + .is_diag_item(cx, sym::TyCtxt) + { + Some((tcx, did, sym)) + } else { + None + } +} + +fn extract_nested_is_diag_item<'tcx>( + cx: &LateContext<'tcx>, + cond: &'tcx Expr<'_>, +) -> Option<(Span, (&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>))> { + for_each_expr(cx, cond, |cond_part| { + if let Some(res) = extract_is_diag_item(cx, cond_part) { + ControlFlow::Break((cond_part.span, res)) + } else { + ControlFlow::Continue(()) + } + }) +} + +fn extract_nested_is_diagnostic_item<'tcx>( + cx: &LateContext<'tcx>, + cond: &'tcx Expr<'_>, +) -> Option<(Span, (&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>))> { + for_each_expr(cx, cond, |cond_part| { + if let Some(res) = extract_is_diagnostic_item(cx, cond_part) { + ControlFlow::Break((cond_part.span, res)) + } else { + ControlFlow::Continue(()) + } + }) +} diff --git a/clippy_utils/README.md b/clippy_utils/README.md index dc8695fef9f5..01257c1a3059 100644 --- a/clippy_utils/README.md +++ b/clippy_utils/README.md @@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain: ``` -nightly-2025-12-11 +nightly-2025-12-25 ``` diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs index 2fd773b06781..8820801853e0 100644 --- a/clippy_utils/src/attrs.rs +++ b/clippy_utils/src/attrs.rs @@ -86,7 +86,7 @@ pub fn is_proc_macro(attrs: &[impl AttributeExt]) -> bool { /// Checks whether `attrs` contain `#[doc(hidden)]` pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool { - attrs.iter().any(|attr| attr.is_doc_hidden()) + attrs.iter().any(AttributeExt::is_doc_hidden) } /// Checks whether the given ADT, or any of its fields/variants, are marked as `#[non_exhaustive]` diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index e43b0b95d9f7..9574e6fa40b0 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -809,10 +809,12 @@ impl<'tcx> ConstEvalCtxt<'tcx> { | sym::i128_legacy_const_max ) ) || self.tcx.opt_parent(did).is_some_and(|parent| { - parent.is_diag_item(&self.tcx, sym::f16_consts_mod) - || parent.is_diag_item(&self.tcx, sym::f32_consts_mod) - || parent.is_diag_item(&self.tcx, sym::f64_consts_mod) - || parent.is_diag_item(&self.tcx, sym::f128_consts_mod) + matches!( + parent.opt_diag_name(&self.tcx), + Some( + sym::f16_consts_mod | sym::f32_consts_mod | sym::f64_consts_mod | sym::f128_consts_mod + ) + ) })) => { did @@ -1139,7 +1141,9 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), - ConstArgKind::Struct(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => None, + ConstArgKind::Struct(..) | ConstArgKind::Path(_) | ConstArgKind::Error(..) | ConstArgKind::Infer(..) => { + None + }, }, } } diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 5cadf5fbb869..055f6d03eff0 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -4,14 +4,17 @@ use crate::source::{SpanRange, SpanRangeExt, walk_span_to_context}; use crate::tokenize_with_text; use rustc_ast::ast; use rustc_ast::ast::InlineAsmTemplatePiece; -use rustc_data_structures::fx::FxHasher; +use rustc_data_structures::fx::{FxHasher, FxIndexMap}; use rustc_hir::MatchSource::TryDesugar; use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id::DefId; use rustc_hir::{ - AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, ByRef, Closure, ConstArg, ConstArgKind, Expr, - ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, - LifetimeKind, Node, Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, - StructTailExpr, TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind, + AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, ByRef, Closure, ConstArg, ConstArgKind, ConstItemRhs, + Expr, ExprField, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericArgs, GenericBound, GenericBounds, + GenericParam, GenericParamKind, GenericParamSource, Generics, HirId, HirIdMap, InlineAsmOperand, ItemId, ItemKind, + LetExpr, Lifetime, LifetimeKind, LifetimeParamKind, Node, ParamName, Pat, PatExpr, PatExprKind, PatField, PatKind, + Path, PathSegment, PreciseCapturingArgKind, PrimTy, QPath, Stmt, StmtKind, StructTailExpr, TraitBoundModifiers, Ty, + TyKind, TyPat, TyPatKind, UseKind, WherePredicate, WherePredicateKind, }; use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize}; use rustc_lint::LateContext; @@ -106,6 +109,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { left_ctxt: SyntaxContext::root(), right_ctxt: SyntaxContext::root(), locals: HirIdMap::default(), + local_items: FxIndexMap::default(), } } @@ -144,6 +148,7 @@ pub struct HirEqInterExpr<'a, 'b, 'tcx> { // right. For example, when comparing `{ let x = 1; x + 2 }` and `{ let y = 1; y + 2 }`, // these blocks are considered equal since `x` is mapped to `y`. pub locals: HirIdMap, + pub local_items: FxIndexMap, } impl HirEqInterExpr<'_, '_, '_> { @@ -168,6 +173,189 @@ impl HirEqInterExpr<'_, '_, '_> { && self.eq_pat(l.pat, r.pat) }, (StmtKind::Expr(l), StmtKind::Expr(r)) | (StmtKind::Semi(l), StmtKind::Semi(r)) => self.eq_expr(l, r), + (StmtKind::Item(l), StmtKind::Item(r)) => self.eq_item(*l, *r), + _ => false, + } + } + + pub fn eq_item(&mut self, l: ItemId, r: ItemId) -> bool { + let left = self.inner.cx.tcx.hir_item(l); + let right = self.inner.cx.tcx.hir_item(r); + let eq = match (left.kind, right.kind) { + ( + ItemKind::Const(l_ident, l_generics, l_ty, ConstItemRhs::Body(l_body)), + ItemKind::Const(r_ident, r_generics, r_ty, ConstItemRhs::Body(r_body)), + ) => { + l_ident.name == r_ident.name + && self.eq_generics(l_generics, r_generics) + && self.eq_ty(l_ty, r_ty) + && self.eq_body(l_body, r_body) + }, + (ItemKind::Static(l_mut, l_ident, l_ty, l_body), ItemKind::Static(r_mut, r_ident, r_ty, r_body)) => { + l_mut == r_mut && l_ident.name == r_ident.name && self.eq_ty(l_ty, r_ty) && self.eq_body(l_body, r_body) + }, + ( + ItemKind::Fn { + sig: l_sig, + ident: l_ident, + generics: l_generics, + body: l_body, + has_body: l_has_body, + }, + ItemKind::Fn { + sig: r_sig, + ident: r_ident, + generics: r_generics, + body: r_body, + has_body: r_has_body, + }, + ) => { + l_ident.name == r_ident.name + && (l_has_body == r_has_body) + && self.eq_fn_sig(&l_sig, &r_sig) + && self.eq_generics(l_generics, r_generics) + && self.eq_body(l_body, r_body) + }, + (ItemKind::TyAlias(l_ident, l_generics, l_ty), ItemKind::TyAlias(r_ident, r_generics, r_ty)) => { + l_ident.name == r_ident.name && self.eq_generics(l_generics, r_generics) && self.eq_ty(l_ty, r_ty) + }, + (ItemKind::Use(l_path, l_kind), ItemKind::Use(r_path, r_kind)) => { + self.eq_path_segments(l_path.segments, r_path.segments) + && match (l_kind, r_kind) { + (UseKind::Single(l_ident), UseKind::Single(r_ident)) => l_ident.name == r_ident.name, + (UseKind::Glob, UseKind::Glob) | (UseKind::ListStem, UseKind::ListStem) => true, + _ => false, + } + }, + (ItemKind::Mod(l_ident, l_mod), ItemKind::Mod(r_ident, r_mod)) => { + l_ident.name == r_ident.name && over(l_mod.item_ids, r_mod.item_ids, |l, r| self.eq_item(*l, *r)) + }, + _ => false, + }; + if eq { + self.local_items.insert(l.owner_id.to_def_id(), r.owner_id.to_def_id()); + } + eq + } + + fn eq_fn_sig(&mut self, left: &FnSig<'_>, right: &FnSig<'_>) -> bool { + left.header.safety == right.header.safety + && left.header.constness == right.header.constness + && left.header.asyncness == right.header.asyncness + && left.header.abi == right.header.abi + && self.eq_fn_decl(left.decl, right.decl) + } + + fn eq_fn_decl(&mut self, left: &FnDecl<'_>, right: &FnDecl<'_>) -> bool { + over(left.inputs, right.inputs, |l, r| self.eq_ty(l, r)) + && (match (left.output, right.output) { + (FnRetTy::DefaultReturn(_), FnRetTy::DefaultReturn(_)) => true, + (FnRetTy::Return(l_ty), FnRetTy::Return(r_ty)) => self.eq_ty(l_ty, r_ty), + _ => false, + }) + && left.c_variadic == right.c_variadic + && left.implicit_self == right.implicit_self + && left.lifetime_elision_allowed == right.lifetime_elision_allowed + } + + fn eq_generics(&mut self, left: &Generics<'_>, right: &Generics<'_>) -> bool { + self.eq_generics_param(left.params, right.params) + && self.eq_generics_predicate(left.predicates, right.predicates) + } + + fn eq_generics_predicate(&mut self, left: &[WherePredicate<'_>], right: &[WherePredicate<'_>]) -> bool { + over(left, right, |l, r| match (l.kind, r.kind) { + (WherePredicateKind::BoundPredicate(l_bound), WherePredicateKind::BoundPredicate(r_bound)) => { + l_bound.origin == r_bound.origin + && self.eq_ty(l_bound.bounded_ty, r_bound.bounded_ty) + && self.eq_generics_param(l_bound.bound_generic_params, r_bound.bound_generic_params) + && self.eq_generics_bound(l_bound.bounds, r_bound.bounds) + }, + (WherePredicateKind::RegionPredicate(l_region), WherePredicateKind::RegionPredicate(r_region)) => { + Self::eq_lifetime(l_region.lifetime, r_region.lifetime) + && self.eq_generics_bound(l_region.bounds, r_region.bounds) + }, + (WherePredicateKind::EqPredicate(l_eq), WherePredicateKind::EqPredicate(r_eq)) => { + self.eq_ty(l_eq.lhs_ty, r_eq.lhs_ty) + }, + _ => false, + }) + } + + fn eq_generics_bound(&mut self, left: GenericBounds<'_>, right: GenericBounds<'_>) -> bool { + over(left, right, |l, r| match (l, r) { + (GenericBound::Trait(l_trait), GenericBound::Trait(r_trait)) => { + l_trait.modifiers == r_trait.modifiers + && self.eq_path(l_trait.trait_ref.path, r_trait.trait_ref.path) + && self.eq_generics_param(l_trait.bound_generic_params, r_trait.bound_generic_params) + }, + (GenericBound::Outlives(l_lifetime), GenericBound::Outlives(r_lifetime)) => { + Self::eq_lifetime(l_lifetime, r_lifetime) + }, + (GenericBound::Use(l_capture, _), GenericBound::Use(r_capture, _)) => { + over(l_capture, r_capture, |l, r| match (l, r) { + (PreciseCapturingArgKind::Lifetime(l_lifetime), PreciseCapturingArgKind::Lifetime(r_lifetime)) => { + Self::eq_lifetime(l_lifetime, r_lifetime) + }, + (PreciseCapturingArgKind::Param(l_param), PreciseCapturingArgKind::Param(r_param)) => { + l_param.ident == r_param.ident && l_param.res == r_param.res + }, + _ => false, + }) + }, + _ => false, + }) + } + + fn eq_generics_param(&mut self, left: &[GenericParam<'_>], right: &[GenericParam<'_>]) -> bool { + over(left, right, |l, r| { + (match (l.name, r.name) { + (ParamName::Plain(l_ident), ParamName::Plain(r_ident)) + | (ParamName::Error(l_ident), ParamName::Error(r_ident)) => l_ident.name == r_ident.name, + (ParamName::Fresh, ParamName::Fresh) => true, + _ => false, + }) && l.pure_wrt_drop == r.pure_wrt_drop + && self.eq_generics_param_kind(&l.kind, &r.kind) + && (matches!( + (l.source, r.source), + (GenericParamSource::Generics, GenericParamSource::Generics) + | (GenericParamSource::Binder, GenericParamSource::Binder) + )) + }) + } + + fn eq_generics_param_kind(&mut self, left: &GenericParamKind<'_>, right: &GenericParamKind<'_>) -> bool { + match (left, right) { + (GenericParamKind::Lifetime { kind: l_kind }, GenericParamKind::Lifetime { kind: r_kind }) => { + match (l_kind, r_kind) { + (LifetimeParamKind::Explicit, LifetimeParamKind::Explicit) + | (LifetimeParamKind::Error, LifetimeParamKind::Error) => true, + (LifetimeParamKind::Elided(l_lifetime_kind), LifetimeParamKind::Elided(r_lifetime_kind)) => { + l_lifetime_kind == r_lifetime_kind + }, + _ => false, + } + }, + ( + GenericParamKind::Type { + default: l_default, + synthetic: l_synthetic, + }, + GenericParamKind::Type { + default: r_default, + synthetic: r_synthetic, + }, + ) => both(*l_default, *r_default, |l, r| self.eq_ty(l, r)) && l_synthetic == r_synthetic, + ( + GenericParamKind::Const { + ty: l_ty, + default: l_default, + }, + GenericParamKind::Const { + ty: r_ty, + default: r_default, + }, + ) => self.eq_ty(l_ty, r_ty) && both(*l_default, *r_default, |l, r| self.eq_const_arg(l, r)), _ => false, } } @@ -479,16 +667,20 @@ impl HirEqInterExpr<'_, '_, '_> { (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true, (ConstArgKind::Struct(path_a, inits_a), ConstArgKind::Struct(path_b, inits_b)) => { self.eq_qpath(path_a, path_b) - && inits_a.iter().zip(*inits_b).all(|(init_a, init_b)| { - self.eq_const_arg(init_a.expr, init_b.expr) - }) - } + && inits_a + .iter() + .zip(*inits_b) + .all(|(init_a, init_b)| self.eq_const_arg(init_a.expr, init_b.expr)) + }, // Use explicit match for now since ConstArg is undergoing flux. - (ConstArgKind::Path(..), _) - | (ConstArgKind::Anon(..), _) - | (ConstArgKind::Infer(..), _) - | (ConstArgKind::Struct(..), _) - | (ConstArgKind::Error(..), _) => false, + ( + ConstArgKind::Path(..) + | ConstArgKind::Anon(..) + | ConstArgKind::Infer(..) + | ConstArgKind::Struct(..) + | ConstArgKind::Error(..), + _, + ) => false, } } @@ -570,6 +762,17 @@ impl HirEqInterExpr<'_, '_, '_> { match (left.res, right.res) { (Res::Local(l), Res::Local(r)) => l == r || self.locals.get(&l) == Some(&r), (Res::Local(_), _) | (_, Res::Local(_)) => false, + (Res::Def(l_kind, l), Res::Def(r_kind, r)) + if l_kind == r_kind + && let DefKind::Const + | DefKind::Static { .. } + | DefKind::Fn + | DefKind::TyAlias + | DefKind::Use + | DefKind::Mod = l_kind => + { + (l == r || self.local_items.get(&l) == Some(&r)) && self.eq_path_segments(left.segments, right.segments) + }, _ => self.eq_path_segments(left.segments, right.segments), } } @@ -1344,7 +1547,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { for init in *inits { self.hash_const_arg(init.expr); } - } + }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, } } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 409f13013489..954c32687af6 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -2490,7 +2490,7 @@ pub enum DefinedTy<'tcx> { /// in the context of its definition site. We also track the `def_id` of its /// definition site. /// - /// WARNING: As the `ty` in in the scope of the definition, not of the function + /// WARNING: As the `ty` is in the scope of the definition, not of the function /// using it, you must be very careful with how you use it. Using it in the wrong /// scope easily results in ICEs. Mir { @@ -2719,7 +2719,6 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'tcx>) -> ExprUseCtx moved_before_use, same_ctxt, }, - Some(ControlFlow::Break(_)) => unreachable!("type of node is ControlFlow"), None => ExprUseCtxt { node: Node::Crate(cx.tcx.hir_root_module()), child_id: HirId::INVALID, diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index b48d17863aa3..f30f26f3a70b 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -13,8 +13,8 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::source_map::{SourceMap, original_sp}; use rustc_span::{ - BytePos, DUMMY_SP, DesugaringKind, Pos, RelativeBytePos, SourceFile, SourceFileAndLine, - Span, SpanData, SyntaxContext, hygiene, + BytePos, DUMMY_SP, DesugaringKind, Pos, RelativeBytePos, SourceFile, SourceFileAndLine, Span, SpanData, + SyntaxContext, hygiene, }; use std::borrow::Cow; use std::fmt; diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 00f4a9c7e586..a0d2e8673fe6 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -58,6 +58,7 @@ generate! { LowerHex, MAX, MIN, + MaybeDef, MsrvStack, Octal, OpenOptions, @@ -167,6 +168,7 @@ generate! { from_ne_bytes, from_ptr, from_raw, + from_raw_parts, from_str_radix, fs, fuse, @@ -192,6 +194,8 @@ generate! { io, is_ascii, is_char_boundary, + is_diag_item, + is_diagnostic_item, is_digit, is_empty, is_err, @@ -275,6 +279,7 @@ generate! { read_to_string, read_unaligned, read_volatile, + reduce, redundant_imports, redundant_pub_crate, regex, @@ -282,6 +287,7 @@ generate! { repeat, replace, replacen, + res, reserve, resize, restriction, @@ -364,6 +370,7 @@ generate! { trim_start, trim_start_matches, truncate, + try_fold, try_for_each, unreachable_pub, unsafe_removed_from_name, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 1384f4078ebe..dbec79e111fb 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] # begin autogenerated nightly -channel = "nightly-2025-12-11" +channel = "nightly-2025-12-25" # end autogenerated nightly components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] profile = "minimal" diff --git a/tests/ui-internal/repeated_is_diagnostic_item.fixed b/tests/ui-internal/repeated_is_diagnostic_item.fixed new file mode 100644 index 000000000000..fcacf504804c --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item.fixed @@ -0,0 +1,77 @@ +#![feature(rustc_private)] + +extern crate rustc_hir; +extern crate rustc_lint; +extern crate rustc_middle; +extern crate rustc_span; + +use clippy_utils::res::MaybeDef; +use clippy_utils::sym; +use rustc_hir::def_id::DefId; +use rustc_lint::LateContext; +use rustc_middle::ty::{AdtDef, Ty, TyCtxt}; +use rustc_span::Symbol; + +fn binops(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) { + let did = ty.opt_def_id().unwrap(); + + let _ = matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = !matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = !matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + + // Don't lint: `is_diagnostic_item` is called not on `TyCtxt` + struct FakeTyCtxt; + impl FakeTyCtxt { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool { + unimplemented!() + } + } + let f = FakeTyCtxt; + let _ = f.is_diagnostic_item(sym::Option, did) || f.is_diagnostic_item(sym::Result, did); + + // Don't lint: `is_diagnostic_item` on `TyCtxt` comes from a(n unrelated) trait + trait IsDiagnosticItem { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool; + } + impl IsDiagnosticItem for TyCtxt<'_> { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool { + unimplemented!() + } + } + let _ = IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Option, did) + || IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Result, did); + + // Don't lint: `is_diag_item` is an inherent method + struct DoesntImplMaybeDef; + impl DoesntImplMaybeDef { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool { + unimplemented!() + } + } + let d = DoesntImplMaybeDef; + let _ = d.is_diag_item(cx, sym::Option) || d.is_diag_item(cx, sym::Result); + + // Don't lint: `is_diag_item` comes from a trait other than `MaybeDef` + trait FakeMaybeDef { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool; + } + struct Bar; + impl FakeMaybeDef for Bar { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool { + unimplemented!() + } + } + let b = Bar; + let _ = b.is_diag_item(cx, sym::Option) || b.is_diag_item(cx, sym::Result); +} + +fn main() {} diff --git a/tests/ui-internal/repeated_is_diagnostic_item.rs b/tests/ui-internal/repeated_is_diagnostic_item.rs new file mode 100644 index 000000000000..7ccbbfd94029 --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item.rs @@ -0,0 +1,77 @@ +#![feature(rustc_private)] + +extern crate rustc_hir; +extern crate rustc_lint; +extern crate rustc_middle; +extern crate rustc_span; + +use clippy_utils::res::MaybeDef; +use clippy_utils::sym; +use rustc_hir::def_id::DefId; +use rustc_lint::LateContext; +use rustc_middle::ty::{AdtDef, Ty, TyCtxt}; +use rustc_span::Symbol; + +fn binops(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) { + let did = ty.opt_def_id().unwrap(); + + let _ = ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result); + //~^ repeated_is_diagnostic_item + let _ = !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result); + //~^ repeated_is_diagnostic_item + let _ = adt_def.is_diag_item(cx, sym::Option) || adt_def.is_diag_item(cx, sym::Result); + //~^ repeated_is_diagnostic_item + let _ = !adt_def.is_diag_item(cx, sym::Option) && !adt_def.is_diag_item(cx, sym::Result); + //~^ repeated_is_diagnostic_item + let _ = cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did); + //~^ repeated_is_diagnostic_item + let _ = !cx.tcx.is_diagnostic_item(sym::Option, did) && !cx.tcx.is_diagnostic_item(sym::Result, did); + //~^ repeated_is_diagnostic_item + + // Don't lint: `is_diagnostic_item` is called not on `TyCtxt` + struct FakeTyCtxt; + impl FakeTyCtxt { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool { + unimplemented!() + } + } + let f = FakeTyCtxt; + let _ = f.is_diagnostic_item(sym::Option, did) || f.is_diagnostic_item(sym::Result, did); + + // Don't lint: `is_diagnostic_item` on `TyCtxt` comes from a(n unrelated) trait + trait IsDiagnosticItem { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool; + } + impl IsDiagnosticItem for TyCtxt<'_> { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool { + unimplemented!() + } + } + let _ = IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Option, did) + || IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Result, did); + + // Don't lint: `is_diag_item` is an inherent method + struct DoesntImplMaybeDef; + impl DoesntImplMaybeDef { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool { + unimplemented!() + } + } + let d = DoesntImplMaybeDef; + let _ = d.is_diag_item(cx, sym::Option) || d.is_diag_item(cx, sym::Result); + + // Don't lint: `is_diag_item` comes from a trait other than `MaybeDef` + trait FakeMaybeDef { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool; + } + struct Bar; + impl FakeMaybeDef for Bar { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool { + unimplemented!() + } + } + let b = Bar; + let _ = b.is_diag_item(cx, sym::Option) || b.is_diag_item(cx, sym::Result); +} + +fn main() {} diff --git a/tests/ui-internal/repeated_is_diagnostic_item.stderr b/tests/ui-internal/repeated_is_diagnostic_item.stderr new file mode 100644 index 000000000000..8c52ba561d79 --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item.stderr @@ -0,0 +1,82 @@ +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:18:13 + | +LL | let _ = ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results + = note: `-D clippy::repeated-is-diagnostic-item` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::repeated_is_diagnostic_item)]` +help: call `Ty::opt_diag_name`, and reuse the results + | +LL - let _ = ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result); +LL + let _ = matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:20:13 + | +LL | let _ = !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL - let _ = !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result); +LL + let _ = !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `AdtDef::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:22:13 + | +LL | let _ = adt_def.is_diag_item(cx, sym::Option) || adt_def.is_diag_item(cx, sym::Result); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `AdtDef::opt_diag_name`, and reuse the results + | +LL - let _ = adt_def.is_diag_item(cx, sym::Option) || adt_def.is_diag_item(cx, sym::Result); +LL + let _ = matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `AdtDef::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:24:13 + | +LL | let _ = !adt_def.is_diag_item(cx, sym::Option) && !adt_def.is_diag_item(cx, sym::Result); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `AdtDef::opt_diag_name`, and reuse the results + | +LL - let _ = !adt_def.is_diag_item(cx, sym::Option) && !adt_def.is_diag_item(cx, sym::Result); +LL + let _ = !matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:26:13 + | +LL | let _ = cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL - let _ = cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did); +LL + let _ = matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:28:13 + | +LL | let _ = !cx.tcx.is_diagnostic_item(sym::Option, did) && !cx.tcx.is_diagnostic_item(sym::Result, did); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL - let _ = !cx.tcx.is_diagnostic_item(sym::Option, did) && !cx.tcx.is_diagnostic_item(sym::Result, did); +LL + let _ = !matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)); + | + +error: aborting due to 6 previous errors + diff --git a/tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs b/tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs new file mode 100644 index 000000000000..807da07ce8aa --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs @@ -0,0 +1,213 @@ +//@no-rustfix +#![feature(rustc_private)] + +extern crate rustc_hir; +extern crate rustc_lint; +extern crate rustc_middle; +extern crate rustc_span; + +use clippy_utils::res::MaybeDef; +use clippy_utils::sym; +use rustc_hir::def_id::DefId; +use rustc_lint::LateContext; +use rustc_middle::ty::{AdtDef, Ty, TyCtxt}; +use rustc_span::Symbol; + +fn main() {} + +// if-chains with repeated calls on the same `ty` +fn if_chains(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) { + let did = ty.opt_def_id().unwrap(); + + let _ = if ty.is_diag_item(cx, sym::Option) { + //~^ repeated_is_diagnostic_item + "Option" + } else if ty.is_diag_item(cx, sym::Result) { + "Result" + } else { + return; + }; + // should ideally suggest the following: + // let _ = match ty.opt_diag_name() { + // Some(sym::Option) => { + // "Option" + // } + // Some(sym::Result) => { + // "Result" + // } + // _ => { + // return; + // } + // }; + + // same but in a stmt + if ty.is_diag_item(cx, sym::Option) { + //~^ repeated_is_diagnostic_item + eprintln!("Option"); + } else if ty.is_diag_item(cx, sym::Result) { + eprintln!("Result"); + } + // should ideally suggest the following: + // match ty.opt_diag_name() { + // Some(sym::Option) => { + // "Option" + // } + // Some(sym::Result) => { + // "Result" + // } + // _ => {} + // }; + + // nested conditions + let _ = if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + //~^ repeated_is_diagnostic_item + "Option" + } else if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + "Result" + } else { + return; + }; + + let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) { + //~^ repeated_is_diagnostic_item + "Option" + } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + "Result" + } else { + return; + }; + // should ideally suggest the following: + // let _ = match cx.get_diagnostic_name(did) { + // Some(sym::Option) => { + // "Option" + // } + // Some(sym::Result) => { + // "Result" + // } + // _ => { + // return; + // } + // }; + + // same but in a stmt + if cx.tcx.is_diagnostic_item(sym::Option, did) { + //~^ repeated_is_diagnostic_item + eprintln!("Option"); + } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + eprintln!("Result"); + } + // should ideally suggest the following: + // match cx.tcx.get_diagnostic_name(did) { + // Some(sym::Option) => { + // "Option" + // } + // Some(sym::Result) => { + // "Result" + // } + // _ => {} + // }; + + // nested conditions + let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + //~^ repeated_is_diagnostic_item + "Option" + } else if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + "Result" + } else { + return; + }; +} + +// if-chains with repeated calls on the same `ty` +fn consecutive_ifs(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) { + let did = ty.opt_def_id().unwrap(); + + { + if ty.is_diag_item(cx, sym::Option) { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if ty.is_diag_item(cx, sym::Result) { + println!("Result"); + } + println!("done!") + } + + // nested conditions + { + if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + println!("Result"); + } + println!("done!") + } + + { + if cx.tcx.is_diagnostic_item(sym::Option, did) { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if cx.tcx.is_diagnostic_item(sym::Result, did) { + println!("Result"); + } + println!("done!") + } + + // nested conditions + { + if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + println!("Result"); + } + println!("done!") + } + + // All the same, but the second if is the final expression + { + if ty.is_diag_item(cx, sym::Option) { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if ty.is_diag_item(cx, sym::Result) { + println!("Result"); + } + } + + // nested conditions + { + if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + println!("Result"); + } + } + + { + if cx.tcx.is_diagnostic_item(sym::Option, did) { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if cx.tcx.is_diagnostic_item(sym::Result, did) { + println!("Result"); + } + } + + // nested conditions + { + if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + println!("Result"); + } + } +} diff --git a/tests/ui-internal/repeated_is_diagnostic_item_unfixable.stderr b/tests/ui-internal/repeated_is_diagnostic_item_unfixable.stderr new file mode 100644 index 000000000000..890817da5235 --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item_unfixable.stderr @@ -0,0 +1,374 @@ +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:22:13 + | +LL | let _ = if ty.is_diag_item(cx, sym::Option) { + | ^ -------------------------------- called here + | _____________| + | | +LL | | +LL | | "Option" +LL | | } else if ty.is_diag_item(cx, sym::Result) { + | | -------------------------------- called here +... | +LL | | return; +LL | | }; + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results + = note: `-D clippy::repeated-is-diagnostic-item` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::repeated_is_diagnostic_item)]` +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ let _ = if /* name */ == Some(sym::Option) { +LL | +LL | "Option" +LL ~ } else if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:44:5 + | +LL | if ty.is_diag_item(cx, sym::Option) { + | ^ -------------------------------- called here + | _____| + | | +LL | | +LL | | eprintln!("Option"); +LL | | } else if ty.is_diag_item(cx, sym::Result) { + | | -------------------------------- called here +LL | | eprintln!("Result"); +LL | | } + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | eprintln!("Option"); +LL ~ } else if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:62:13 + | +LL | let _ = if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + | ^ -------------------------------- called here + | _____________| + | | +LL | | +LL | | "Option" +LL | | } else if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + | | -------------------------------- called here +... | +LL | | return; +LL | | }; + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ let _ = if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | "Option" +LL ~ } else if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:71:13 + | +LL | let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) { + | ^ ------------------------------------------- called here + | _____________| + | | +LL | | +LL | | "Option" +LL | | } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + | | ------------------------------------------- called here +... | +LL | | return; +LL | | }; + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ let _ = if /* name */ == Some(sym::Option) { +LL | +LL | "Option" +LL ~ } else if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:93:5 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) { + | ^ ------------------------------------------- called here + | _____| + | | +LL | | +LL | | eprintln!("Option"); +LL | | } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + | | ------------------------------------------- called here +LL | | eprintln!("Result"); +LL | | } + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | eprintln!("Option"); +LL ~ } else if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:111:13 + | +LL | let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + | ^ ------------------------------------------- called here + | _____________| + | | +LL | | +LL | | "Option" +LL | | } else if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + | | ------------------------------------------- called here +... | +LL | | return; +LL | | }; + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ let _ = if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | "Option" +LL ~ } else if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:126:9 + | +LL | if ty.is_diag_item(cx, sym::Option) { + | ^ -------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if ty.is_diag_item(cx, sym::Result) { + | | -------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:138:9 + | +LL | if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + | ^ -------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + | | -------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:149:9 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) { + | ^ ------------------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if cx.tcx.is_diagnostic_item(sym::Result, did) { + | | ------------------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:161:9 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + | ^ ------------------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + | | ------------------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:173:9 + | +LL | if ty.is_diag_item(cx, sym::Option) { + | ^ -------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if ty.is_diag_item(cx, sym::Result) { + | | -------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:184:9 + | +LL | if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + | ^ -------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + | | -------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:194:9 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) { + | ^ ------------------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if cx.tcx.is_diagnostic_item(sym::Result, did) { + | | ------------------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:205:9 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + | ^ ------------------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + | | ------------------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: aborting due to 14 previous errors + diff --git a/tests/ui-toml/collapsible_if/collapsible_else_if.fixed b/tests/ui-toml/collapsible_if/collapsible_else_if.fixed index ec45dfd2033a..213b56b786b1 100644 --- a/tests/ui-toml/collapsible_if/collapsible_else_if.fixed +++ b/tests/ui-toml/collapsible_if/collapsible_else_if.fixed @@ -1,5 +1,5 @@ #![allow(clippy::eq_op, clippy::nonminimal_bool)] -#![warn(clippy::collapsible_if)] +#![warn(clippy::collapsible_else_if)] #[rustfmt::skip] fn main() { diff --git a/tests/ui-toml/collapsible_if/collapsible_else_if.rs b/tests/ui-toml/collapsible_if/collapsible_else_if.rs index 54315a3c32bf..2d4c2c54031e 100644 --- a/tests/ui-toml/collapsible_if/collapsible_else_if.rs +++ b/tests/ui-toml/collapsible_if/collapsible_else_if.rs @@ -1,5 +1,5 @@ #![allow(clippy::eq_op, clippy::nonminimal_bool)] -#![warn(clippy::collapsible_if)] +#![warn(clippy::collapsible_else_if)] #[rustfmt::skip] fn main() { diff --git a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed index 40556ca5410f..962a4e00d86e 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed @@ -3,7 +3,7 @@ // Should warn pub fn pub_foo(s: &Vec, b: &u32, x: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut *x += *b + s.len() as u32; } diff --git a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs index bbc63ceb15a3..5f584c6704f2 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs @@ -3,7 +3,7 @@ // Should warn pub fn pub_foo(s: &mut Vec, b: &u32, x: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut *x += *b + s.len() as u32; } diff --git a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr index c10607bf4bab..57137ab08d1e 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr @@ -1,8 +1,10 @@ -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs:5:19 | LL | pub fn pub_foo(s: &mut Vec, b: &u32, x: &mut u32) { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` | = warning: changing this function will impact semver compatibility = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` diff --git a/tests/ui-toml/toml_disallowed_methods/clippy.toml b/tests/ui-toml/toml_disallowed_methods/clippy.toml index c7a326f28295..2c54b73d72d7 100644 --- a/tests/ui-toml/toml_disallowed_methods/clippy.toml +++ b/tests/ui-toml/toml_disallowed_methods/clippy.toml @@ -17,4 +17,6 @@ disallowed-methods = [ # re-exports "conf_disallowed_methods::identity", "conf_disallowed_methods::renamed", + # also used in desugaring + "std::future::Future::poll", ] diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs index 2dac01649a0f..621317246d6d 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs @@ -80,3 +80,19 @@ fn main() { renamed(1); //~^ disallowed_methods } + +mod issue16185 { + use std::pin::Pin; + use std::task::Context; + + async fn test(f: impl Future) { + // Should not lint even though desugaring uses + // disallowed method `std::future::Future::poll()`. + f.await + } + + fn explicit>(f: Pin<&mut F>, cx: &mut Context<'_>) { + f.poll(cx); + //~^ disallowed_methods + } +} diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr index 20474ad6e927..8e7e112a93f3 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr @@ -99,5 +99,11 @@ error: use of a disallowed method `conf_disallowed_methods::renamed` LL | renamed(1); | ^^^^^^^ -error: aborting due to 16 previous errors +error: use of a disallowed method `std::future::Future::poll` + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:95:11 + | +LL | f.poll(cx); + | ^^^^ + +error: aborting due to 17 previous errors diff --git a/tests/ui/assertions_on_constants.rs b/tests/ui/assertions_on_constants.rs index f467d4966aef..1c49b6e6b7b1 100644 --- a/tests/ui/assertions_on_constants.rs +++ b/tests/ui/assertions_on_constants.rs @@ -96,3 +96,8 @@ fn _f4() { assert!(C); //~^ assertions_on_constants } + +fn issue_16242(var: bool) { + // should not lint + assert!(cfg!(feature = "hey") && var); +} diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.rs b/tests/ui/branches_sharing_code/shared_at_bottom.rs index fa322dc28a78..a7f950b44caf 100644 --- a/tests/ui/branches_sharing_code/shared_at_bottom.rs +++ b/tests/ui/branches_sharing_code/shared_at_bottom.rs @@ -300,3 +300,65 @@ fn issue15004() { //~^ branches_sharing_code }; } + +pub fn issue15347() -> isize { + if false { + static A: isize = 4; + return A; + } else { + static A: isize = 5; + return A; + } + + if false { + //~^ branches_sharing_code + type ISize = isize; + return ISize::MAX; + } else { + type ISize = isize; + return ISize::MAX; + } + + if false { + //~^ branches_sharing_code + fn foo() -> isize { + 4 + } + return foo(); + } else { + fn foo() -> isize { + 4 + } + return foo(); + } + + if false { + //~^ branches_sharing_code + use std::num::NonZeroIsize; + return NonZeroIsize::new(4).unwrap().get(); + } else { + use std::num::NonZeroIsize; + return NonZeroIsize::new(4).unwrap().get(); + } + + if false { + //~^ branches_sharing_code + const B: isize = 5; + return B; + } else { + const B: isize = 5; + return B; + } + + // Should not lint! + const A: isize = 1; + if false { + const B: isize = A; + return B; + } else { + const C: isize = A; + return C; + } + + todo!() +} diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/tests/ui/branches_sharing_code/shared_at_bottom.stderr index 1c470fb0da5e..4ff3990232a5 100644 --- a/tests/ui/branches_sharing_code/shared_at_bottom.stderr +++ b/tests/ui/branches_sharing_code/shared_at_bottom.stderr @@ -202,5 +202,73 @@ LL ~ } LL ~ 1; | -error: aborting due to 12 previous errors +error: all if blocks contain the same code at the start + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:313:5 + | +LL | / if false { +LL | | +LL | | type ISize = isize; +LL | | return ISize::MAX; + | |__________________________^ + | +help: consider moving these statements before the if + | +LL ~ type ISize = isize; +LL + return ISize::MAX; +LL + if false { + | + +error: all if blocks contain the same code at the start + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:322:5 + | +LL | / if false { +LL | | +LL | | fn foo() -> isize { +LL | | 4 +LL | | } +LL | | return foo(); + | |_____________________^ + | +help: consider moving these statements before the if + | +LL ~ fn foo() -> isize { +LL + 4 +LL + } +LL + return foo(); +LL + if false { + | + +error: all if blocks contain the same code at the start + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:335:5 + | +LL | / if false { +LL | | +LL | | use std::num::NonZeroIsize; +LL | | return NonZeroIsize::new(4).unwrap().get(); + | |___________________________________________________^ + | +help: consider moving these statements before the if + | +LL ~ use std::num::NonZeroIsize; +LL + return NonZeroIsize::new(4).unwrap().get(); +LL + if false { + | + +error: all if blocks contain the same code at the start + --> tests/ui/branches_sharing_code/shared_at_bottom.rs:344:5 + | +LL | / if false { +LL | | +LL | | const B: isize = 5; +LL | | return B; + | |_________________^ + | +help: consider moving these statements before the if + | +LL ~ const B: isize = 5; +LL + return B; +LL + if false { + | + +error: aborting due to 16 previous errors diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 0ff1dc11c3ac..14b84b1ff1ef 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -1,4 +1,4 @@ -error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `i32` to `f32` may cause a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast.rs:23:5 | LL | x0 as f32; @@ -7,31 +7,31 @@ LL | x0 as f32; = note: `-D clippy::cast-precision-loss` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` -error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `i64` to `f32` may cause a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast.rs:27:5 | LL | x1 as f32; | ^^^^^^^^^ -error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `i64` to `f64` may cause a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast.rs:30:5 | LL | x1 as f64; | ^^^^^^^^^ -error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `u32` to `f32` may cause a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast.rs:34:5 | LL | x2 as f32; | ^^^^^^^^^ -error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `u64` to `f32` may cause a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast.rs:38:5 | LL | x3 as f32; | ^^^^^^^^^ -error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `u64` to `f64` may cause a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast.rs:41:5 | LL | x3 as f64; diff --git a/tests/ui/cast_size.r32bit.stderr b/tests/ui/cast_size.r32bit.stderr index 5811cb3607ba..2f7eeda385e5 100644 --- a/tests/ui/cast_size.r32bit.stderr +++ b/tests/ui/cast_size.r32bit.stderr @@ -13,7 +13,7 @@ LL - 1isize as i8; LL + i8::try_from(1isize); | -error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `isize` to `f32` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:24:5 | LL | x0 as f32; @@ -22,19 +22,19 @@ LL | x0 as f32; = note: `-D clippy::cast-precision-loss` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` -error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `usize` to `f32` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:26:5 | LL | x1 as f32; | ^^^^^^^^^ -error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `isize` to `f64` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:28:5 | LL | x0 as f64; | ^^^^^^^^^ -error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:30:5 | LL | x1 as f64; @@ -165,13 +165,13 @@ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit LL | 1u32 as isize; | ^^^^^^^^^^^^^ -error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `i32` to `f32` may cause a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:61:5 | LL | 999_999_999 as f32; | ^^^^^^^^^^^^^^^^^^ -error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:63:5 | LL | 9_999_999_999_999_999usize as f64; diff --git a/tests/ui/cast_size.r64bit.stderr b/tests/ui/cast_size.r64bit.stderr index ba1419583aeb..8e5f38137602 100644 --- a/tests/ui/cast_size.r64bit.stderr +++ b/tests/ui/cast_size.r64bit.stderr @@ -13,7 +13,7 @@ LL - 1isize as i8; LL + i8::try_from(1isize); | -error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `isize` to `f32` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:24:5 | LL | x0 as f32; @@ -22,19 +22,19 @@ LL | x0 as f32; = note: `-D clippy::cast-precision-loss` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` -error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `usize` to `f32` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:26:5 | LL | x1 as f32; | ^^^^^^^^^ -error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `isize` to `f64` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:28:5 | LL | x0 as f64; | ^^^^^^^^^ -error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:30:5 | LL | x1 as f64; @@ -165,13 +165,13 @@ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit LL | 1u32 as isize; | ^^^^^^^^^^^^^ -error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) +error: casting `i32` to `f32` may cause a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) --> tests/ui/cast_size.rs:61:5 | LL | 999_999_999 as f32; | ^^^^^^^^^^^^^^^^^^ -error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) +error: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide) --> tests/ui/cast_size.rs:63:5 | LL | 9_999_999_999_999_999usize as f64; diff --git a/tests/ui/cmp_null.fixed b/tests/ui/cmp_null.fixed index c12279cf12e6..4a0ee439e94a 100644 --- a/tests/ui/cmp_null.fixed +++ b/tests/ui/cmp_null.fixed @@ -38,3 +38,23 @@ fn issue15010() { debug_assert!(!f.is_null()); //~^ cmp_null } + +fn issue16281() { + use std::ptr; + + struct Container { + value: *const i32, + } + let x = Container { value: ptr::null() }; + + macro_rules! dot_value { + ($obj:expr) => { + $obj.value + }; + } + + if dot_value!(x).is_null() { + //~^ cmp_null + todo!() + } +} diff --git a/tests/ui/cmp_null.rs b/tests/ui/cmp_null.rs index 2771a16e00c5..26ea8960e5fb 100644 --- a/tests/ui/cmp_null.rs +++ b/tests/ui/cmp_null.rs @@ -38,3 +38,23 @@ fn issue15010() { debug_assert!(f != std::ptr::null_mut()); //~^ cmp_null } + +fn issue16281() { + use std::ptr; + + struct Container { + value: *const i32, + } + let x = Container { value: ptr::null() }; + + macro_rules! dot_value { + ($obj:expr) => { + $obj.value + }; + } + + if dot_value!(x) == ptr::null() { + //~^ cmp_null + todo!() + } +} diff --git a/tests/ui/cmp_null.stderr b/tests/ui/cmp_null.stderr index 381747cb3c65..51b98d2a2320 100644 --- a/tests/ui/cmp_null.stderr +++ b/tests/ui/cmp_null.stderr @@ -37,5 +37,11 @@ error: comparing with null is better expressed by the `.is_null()` method LL | debug_assert!(f != std::ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!f.is_null()` -error: aborting due to 6 previous errors +error: comparing with null is better expressed by the `.is_null()` method + --> tests/ui/cmp_null.rs:56:8 + | +LL | if dot_value!(x) == ptr::null() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dot_value!(x).is_null()` + +error: aborting due to 7 previous errors diff --git a/tests/ui/collapsible_else_if.fixed b/tests/ui/collapsible_else_if.fixed index e7439beef186..cd2d9be9f433 100644 --- a/tests/ui/collapsible_else_if.fixed +++ b/tests/ui/collapsible_else_if.fixed @@ -1,5 +1,5 @@ #![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_ifs)] -#![warn(clippy::collapsible_if, clippy::collapsible_else_if)] +#![warn(clippy::collapsible_else_if)] #[rustfmt::skip] fn main() { @@ -70,6 +70,17 @@ fn main() { } //~^^^^^^^^ collapsible_else_if + if x == "hello" { + if y == "world" { + print!("Hello "); + } else { + println!("world"); + } + } else if let Some(42) = Some(42) { + println!("42"); + } + //~^^^^^ collapsible_else_if + if x == "hello" { print!("Hello "); } else { @@ -78,6 +89,21 @@ fn main() { println!("world!") } } + + if x == "hello" { + if y == "world" { + print!("Hello "); + } else { + println!("world"); + } + } else { + if let Some(42) = Some(42) { + println!("42"); + } else { + println!("!"); + } + } + } #[rustfmt::skip] @@ -88,30 +114,12 @@ fn issue_7318() { } fn issue_13365() { - // all the `expect`s that we should fulfill + // ensure we fulfill `#[expect]` if true { } else { #[expect(clippy::collapsible_else_if)] if false {} } - - if true { - } else { - #[expect(clippy::style)] - if false {} - } - - if true { - } else { - #[expect(clippy::all)] - if false {} - } - - if true { - } else { - #[expect(warnings)] - if false {} - } } fn issue14799() { diff --git a/tests/ui/collapsible_else_if.rs b/tests/ui/collapsible_else_if.rs index 434ba3654f98..75f204328538 100644 --- a/tests/ui/collapsible_else_if.rs +++ b/tests/ui/collapsible_else_if.rs @@ -1,5 +1,5 @@ #![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_ifs)] -#![warn(clippy::collapsible_if, clippy::collapsible_else_if)] +#![warn(clippy::collapsible_else_if)] #[rustfmt::skip] fn main() { @@ -84,6 +84,19 @@ fn main() { } //~^^^^^^^^ collapsible_else_if + if x == "hello" { + if y == "world" { + print!("Hello "); + } else { + println!("world"); + } + } else { + if let Some(42) = Some(42) { + println!("42"); + } + } + //~^^^^^ collapsible_else_if + if x == "hello" { print!("Hello "); } else { @@ -92,6 +105,21 @@ fn main() { println!("world!") } } + + if x == "hello" { + if y == "world" { + print!("Hello "); + } else { + println!("world"); + } + } else { + if let Some(42) = Some(42) { + println!("42"); + } else { + println!("!"); + } + } + } #[rustfmt::skip] @@ -104,30 +132,12 @@ fn issue_7318() { } fn issue_13365() { - // all the `expect`s that we should fulfill + // ensure we fulfill `#[expect]` if true { } else { #[expect(clippy::collapsible_else_if)] if false {} } - - if true { - } else { - #[expect(clippy::style)] - if false {} - } - - if true { - } else { - #[expect(clippy::all)] - if false {} - } - - if true { - } else { - #[expect(warnings)] - if false {} - } } fn issue14799() { diff --git a/tests/ui/collapsible_else_if.stderr b/tests/ui/collapsible_else_if.stderr index ce1da593a8e9..ebd78d2b1ffe 100644 --- a/tests/ui/collapsible_else_if.stderr +++ b/tests/ui/collapsible_else_if.stderr @@ -142,7 +142,25 @@ LL + } | error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:100:10 + --> tests/ui/collapsible_else_if.rs:93:12 + | +LL | } else { + | ____________^ +LL | | if let Some(42) = Some(42) { +LL | | println!("42"); +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else if let Some(42) = Some(42) { +LL + println!("42"); +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:128:10 | LL | }else{ | __________^ @@ -151,7 +169,7 @@ LL | | } | |_____^ help: collapse nested if block: `if false {}` error: this `else { if .. }` block can be collapsed - --> tests/ui/collapsible_else_if.rs:157:12 + --> tests/ui/collapsible_else_if.rs:167:12 | LL | } else { | ____________^ @@ -159,5 +177,5 @@ LL | | (if y == "world" { println!("world") } else { println!("!") }) LL | | } | |_____^ help: collapse nested if block: `if y == "world" { println!("world") } else { println!("!") }` -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors diff --git a/tests/ui/crashes/ice-10148.stderr b/tests/ui/crashes/ice-10148.stderr index 639cf2dd442b..e91fb3778a31 100644 --- a/tests/ui/crashes/ice-10148.stderr +++ b/tests/ui/crashes/ice-10148.stderr @@ -2,7 +2,7 @@ error: empty string literal in `println!` --> tests/ui/crashes/ice-10148.rs:8:5 | LL | println!(with_span!(""something "")); - | ^^^^^^^^^^^^^^^^^^^^-----------^^^^^ + | ^^^^^^^^^^^^^^^^^^^^---------------^ | | | help: remove the empty string | diff --git a/tests/ui/crashes/ice-7410.rs b/tests/ui/crashes/ice-7410.rs index 71f00fb9aede..7b39f7ffc01a 100644 --- a/tests/ui/crashes/ice-7410.rs +++ b/tests/ui/crashes/ice-7410.rs @@ -1,6 +1,6 @@ //@ check-pass //@compile-flags: -Clink-arg=-nostartfiles -//@ignore-target: apple windows +//@ignore-target: windows #![crate_type = "lib"] #![no_std] diff --git a/tests/ui/def_id_nocore.rs b/tests/ui/def_id_nocore.rs index 5c13d8622767..6aa023a8d450 100644 --- a/tests/ui/def_id_nocore.rs +++ b/tests/ui/def_id_nocore.rs @@ -1,5 +1,3 @@ -//@ignore-target: apple - #![feature(no_core, lang_items)] #![no_core] #![allow(clippy::missing_safety_doc)] diff --git a/tests/ui/def_id_nocore.stderr b/tests/ui/def_id_nocore.stderr index 175dd0754081..bf022fb56a36 100644 --- a/tests/ui/def_id_nocore.stderr +++ b/tests/ui/def_id_nocore.stderr @@ -1,5 +1,5 @@ error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/def_id_nocore.rs:33:19 + --> tests/ui/def_id_nocore.rs:31:19 | LL | pub fn as_ref(self) -> &'static str { | ^^^^ diff --git a/tests/ui/empty_enum_variants_with_brackets.fixed b/tests/ui/empty_enum_variants_with_brackets.fixed index abdf6ca5cb61..caf34eaefab9 100644 --- a/tests/ui/empty_enum_variants_with_brackets.fixed +++ b/tests/ui/empty_enum_variants_with_brackets.fixed @@ -1,5 +1,6 @@ #![warn(clippy::empty_enum_variants_with_brackets)] #![allow(dead_code)] +#![feature(more_qualified_paths)] pub enum PublicTestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error @@ -102,4 +103,62 @@ pub enum PubFoo { Variant3(), } +fn issue16157() { + enum E { + V, + //~^ empty_enum_variants_with_brackets + } + + let E::V = E::V; + + ::V = E::V; + ::V = E::V; +} + +fn variant_with_braces() { + enum E { + V, + //~^ empty_enum_variants_with_brackets + } + E::V = E::V; + E::V = E::V; + ::V = ::V; + + enum F { + U, + //~^ empty_enum_variants_with_brackets + } + F::U = F::U; + ::U = F::U; +} + +fn variant_with_comments_and_cfg() { + enum E { + V( + // This is a comment + ), + } + E::V() = E::V(); + + enum F { + U { + // This is a comment + }, + } + F::U {} = F::U {}; + + enum G { + V(#[cfg(target_os = "cuda")] String), + } + G::V() = G::V(); + + enum H { + U { + #[cfg(target_os = "cuda")] + value: String, + }, + } + H::U {} = H::U {}; +} + fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.rs b/tests/ui/empty_enum_variants_with_brackets.rs index 63a5a8e9143e..f7ab062edd1e 100644 --- a/tests/ui/empty_enum_variants_with_brackets.rs +++ b/tests/ui/empty_enum_variants_with_brackets.rs @@ -1,5 +1,6 @@ #![warn(clippy::empty_enum_variants_with_brackets)] #![allow(dead_code)] +#![feature(more_qualified_paths)] pub enum PublicTestEnum { NonEmptyBraces { x: i32, y: i32 }, // No error @@ -102,4 +103,62 @@ pub enum PubFoo { Variant3(), } +fn issue16157() { + enum E { + V(), + //~^ empty_enum_variants_with_brackets + } + + let E::V() = E::V(); + + ::V() = E::V(); + ::V {} = E::V(); +} + +fn variant_with_braces() { + enum E { + V(), + //~^ empty_enum_variants_with_brackets + } + E::V() = E::V(); + E::V() = E::V {}; + ::V {} = ::V {}; + + enum F { + U {}, + //~^ empty_enum_variants_with_brackets + } + F::U {} = F::U {}; + ::U {} = F::U {}; +} + +fn variant_with_comments_and_cfg() { + enum E { + V( + // This is a comment + ), + } + E::V() = E::V(); + + enum F { + U { + // This is a comment + }, + } + F::U {} = F::U {}; + + enum G { + V(#[cfg(target_os = "cuda")] String), + } + G::V() = G::V(); + + enum H { + U { + #[cfg(target_os = "cuda")] + value: String, + }, + } + H::U {} = H::U {}; +} + fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.stderr b/tests/ui/empty_enum_variants_with_brackets.stderr index 7fe85e829a35..d50b07036a94 100644 --- a/tests/ui/empty_enum_variants_with_brackets.stderr +++ b/tests/ui/empty_enum_variants_with_brackets.stderr @@ -1,5 +1,5 @@ error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:7:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:8:16 | LL | EmptyBraces {}, | ^^^ @@ -9,7 +9,7 @@ LL | EmptyBraces {}, = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:15:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:16:16 | LL | EmptyBraces {}, | ^^^ @@ -17,7 +17,7 @@ LL | EmptyBraces {}, = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:17:21 + --> tests/ui/empty_enum_variants_with_brackets.rs:18:21 | LL | EmptyParentheses(), | ^^ @@ -25,7 +25,7 @@ LL | EmptyParentheses(), = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:28:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:29:16 | LL | Unknown(), | ^^ @@ -33,7 +33,7 @@ LL | Unknown(), = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:47:16 + --> tests/ui/empty_enum_variants_with_brackets.rs:48:16 | LL | Unknown(), | ^^ @@ -41,7 +41,7 @@ LL | Unknown(), = help: remove the brackets error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:53:20 + --> tests/ui/empty_enum_variants_with_brackets.rs:54:20 | LL | Parentheses(), | ^^ @@ -56,7 +56,7 @@ LL ~ RedundantParenthesesFunctionCall::Parentheses; | error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:76:20 + --> tests/ui/empty_enum_variants_with_brackets.rs:77:20 | LL | Parentheses(), | ^^ @@ -71,12 +71,61 @@ LL ~ Parentheses, | error: enum variant has empty brackets - --> tests/ui/empty_enum_variants_with_brackets.rs:95:13 + --> tests/ui/empty_enum_variants_with_brackets.rs:96:13 | LL | Variant3(), | ^^ | = help: remove the brackets -error: aborting due to 8 previous errors +error: enum variant has empty brackets + --> tests/ui/empty_enum_variants_with_brackets.rs:108:10 + | +LL | V(), + | ^^ + | +help: remove the brackets + | +LL ~ V, +LL | +LL | } +LL | +LL ~ let E::V = E::V; +LL | +LL ~ ::V = E::V; +LL ~ ::V = E::V; + | + +error: enum variant has empty brackets + --> tests/ui/empty_enum_variants_with_brackets.rs:120:10 + | +LL | V(), + | ^^ + | +help: remove the brackets + | +LL ~ V, +LL | +LL | } +LL ~ E::V = E::V; +LL ~ E::V = E::V; +LL ~ ::V = ::V; + | + +error: enum variant has empty brackets + --> tests/ui/empty_enum_variants_with_brackets.rs:128:10 + | +LL | U {}, + | ^^^ + | +help: remove the brackets + | +LL ~ U, +LL | +LL | } +LL ~ F::U = F::U; +LL ~ ::U = F::U; + | + +error: aborting due to 11 previous errors diff --git a/tests/ui/empty_loop_no_std.rs b/tests/ui/empty_loop_no_std.rs index 6407bd678f9c..1ea96abbcd8b 100644 --- a/tests/ui/empty_loop_no_std.rs +++ b/tests/ui/empty_loop_no_std.rs @@ -1,6 +1,4 @@ //@compile-flags: -Clink-arg=-nostartfiles -//@ignore-target: apple - #![warn(clippy::empty_loop)] #![crate_type = "lib"] #![no_std] diff --git a/tests/ui/empty_loop_no_std.stderr b/tests/ui/empty_loop_no_std.stderr index f36fb9d9e3f2..e34b50ed1aef 100644 --- a/tests/ui/empty_loop_no_std.stderr +++ b/tests/ui/empty_loop_no_std.stderr @@ -1,5 +1,5 @@ error: empty `loop {}` wastes CPU cycles - --> tests/ui/empty_loop_no_std.rs:10:5 + --> tests/ui/empty_loop_no_std.rs:8:5 | LL | loop {} | ^^^^^^^ diff --git a/tests/ui/entry.fixed b/tests/ui/entry.fixed index 1e36ca4f1f09..75e173b9a84d 100644 --- a/tests/ui/entry.fixed +++ b/tests/ui/entry.fixed @@ -273,3 +273,13 @@ mod issue_16173 { } fn main() {} + +fn issue15781(m: &mut std::collections::HashMap, k: i32, v: i32) { + fn very_important_fn() {} + m.entry(k).or_insert_with(|| { + //~^ map_entry + #[cfg(test)] + very_important_fn(); + v + }); +} diff --git a/tests/ui/entry.rs b/tests/ui/entry.rs index b3da0ef3ffd6..7e3308c87356 100644 --- a/tests/ui/entry.rs +++ b/tests/ui/entry.rs @@ -279,3 +279,13 @@ mod issue_16173 { } fn main() {} + +fn issue15781(m: &mut std::collections::HashMap, k: i32, v: i32) { + fn very_important_fn() {} + if !m.contains_key(&k) { + //~^ map_entry + #[cfg(test)] + very_important_fn(); + m.insert(k, v); + } +} diff --git a/tests/ui/entry.stderr b/tests/ui/entry.stderr index 009b78d29073..4a29b3860e89 100644 --- a/tests/ui/entry.stderr +++ b/tests/ui/entry.stderr @@ -246,5 +246,26 @@ LL + e.insert(42); LL + } | -error: aborting due to 11 previous errors +error: usage of `contains_key` followed by `insert` on a `HashMap` + --> tests/ui/entry.rs:285:5 + | +LL | / if !m.contains_key(&k) { +LL | | +LL | | #[cfg(test)] +LL | | very_important_fn(); +LL | | m.insert(k, v); +LL | | } + | |_____^ + | +help: try + | +LL ~ m.entry(k).or_insert_with(|| { +LL + +LL + #[cfg(test)] +LL + very_important_fn(); +LL + v +LL + }); + | + +error: aborting due to 12 previous errors diff --git a/tests/ui/format_push_string.fixed b/tests/ui/format_push_string.fixed new file mode 100644 index 000000000000..f6396d9982a3 --- /dev/null +++ b/tests/ui/format_push_string.fixed @@ -0,0 +1,132 @@ +#![warn(clippy::format_push_string)] + +fn main() { + use std::fmt::Write; + + let mut string = String::new(); + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + + let _ = write!(string, "{:?}", 5678); + //~^ format_push_string + + macro_rules! string { + () => { + String::new() + }; + } + let _ = write!(string!(), "{:?}", 5678); + //~^ format_push_string +} + +// TODO: recognize the already imported `fmt::Write`, and don't add a note suggesting to import it +// again +mod import_write { + mod push_str { + mod imported_anonymously { + fn main(string: &mut String) { + use std::fmt::Write as _; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported { + fn main(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_anonymously_in_module { + use std::fmt::Write as _; + + fn main(string: &mut String) { + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_in_module { + use std::fmt::Write; + + fn main(string: &mut String) { + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_and_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + } + + mod add_assign { + mod imported_anonymously { + fn main(string: &mut String) { + use std::fmt::Write as _; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported { + fn main(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_anonymously_in_module { + use std::fmt::Write as _; + + fn main(string: &mut String) { + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_in_module { + use std::fmt::Write; + + fn main(string: &mut String) { + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + + mod imported_and_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string + } + } + } +} diff --git a/tests/ui/format_push_string.rs b/tests/ui/format_push_string.rs index 056ef59ff0e2..1ed0f5b3ac59 100644 --- a/tests/ui/format_push_string.rs +++ b/tests/ui/format_push_string.rs @@ -1,44 +1,132 @@ #![warn(clippy::format_push_string)] fn main() { + use std::fmt::Write; + let mut string = String::new(); string += &format!("{:?}", 1234); //~^ format_push_string string.push_str(&format!("{:?}", 5678)); //~^ format_push_string + + macro_rules! string { + () => { + String::new() + }; + } + string!().push_str(&format!("{:?}", 5678)); + //~^ format_push_string } -mod issue9493 { - pub fn u8vec_to_hex(vector: &Vec, upper: bool) -> String { - let mut hex = String::with_capacity(vector.len() * 2); - for byte in vector { - hex += &(if upper { +// TODO: recognize the already imported `fmt::Write`, and don't add a note suggesting to import it +// again +mod import_write { + mod push_str { + mod imported_anonymously { + fn main(string: &mut String) { + use std::fmt::Write as _; + + string.push_str(&format!("{:?}", 1234)); //~^ format_push_string - - format!("{byte:02X}") - } else { - format!("{byte:02x}") - }); + } + } + + mod imported { + fn main(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_anonymously_in_module { + use std::fmt::Write as _; + + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_in_module { + use std::fmt::Write; + + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_and_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } } - hex } - pub fn other_cases() { - let mut s = String::new(); - // if let - s += &(if let Some(_a) = Some(1234) { - //~^ format_push_string + mod add_assign { + mod imported_anonymously { + fn main(string: &mut String) { + use std::fmt::Write as _; - format!("{}", 1234) - } else { - format!("{}", 1234) - }); - // match - s += &(match Some(1234) { - //~^ format_push_string - Some(_) => format!("{}", 1234), - None => format!("{}", 1234), - }); + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported { + fn main(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_anonymously_in_module { + use std::fmt::Write as _; + + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_in_module { + use std::fmt::Write; + + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + mod imported_and_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } } } diff --git a/tests/ui/format_push_string.stderr b/tests/ui/format_push_string.stderr index bba2a8947c43..05e26fcbfc2b 100644 --- a/tests/ui/format_push_string.stderr +++ b/tests/ui/format_push_string.stderr @@ -1,60 +1,199 @@ error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:5:5 + --> tests/ui/format_push_string.rs:7:5 | LL | string += &format!("{:?}", 1234); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait = note: `-D clippy::format-push-string` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]` +help: consider using `write!` to avoid the extra allocation + | +LL - string += &format!("{:?}", 1234); +LL + let _ = write!(string, "{:?}", 1234); + | error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:8:5 + --> tests/ui/format_push_string.rs:10:5 | LL | string.push_str(&format!("{:?}", 5678)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 5678)); +LL + let _ = write!(string, "{:?}", 5678); + | error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:16:13 + --> tests/ui/format_push_string.rs:18:5 | -LL | / hex += &(if upper { -LL | | -LL | | -LL | | format!("{byte:02X}") -LL | | } else { -LL | | format!("{byte:02x}") -LL | | }); - | |______________^ +LL | string!().push_str(&format!("{:?}", 5678)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string!().push_str(&format!("{:?}", 5678)); +LL + let _ = write!(string!(), "{:?}", 5678); | - = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:30:9 + --> tests/ui/format_push_string.rs:30:17 | -LL | / s += &(if let Some(_a) = Some(1234) { -LL | | -LL | | -LL | | format!("{}", 1234) -LL | | } else { -LL | | format!("{}", 1234) -LL | | }); - | |__________^ +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); | - = help: consider using `write!` to avoid the extra allocation error: `format!(..)` appended to existing `String` - --> tests/ui/format_push_string.rs:38:9 + --> tests/ui/format_push_string.rs:39:17 | -LL | / s += &(match Some(1234) { -LL | | -LL | | Some(_) => format!("{}", 1234), -LL | | None => format!("{}", 1234), -LL | | }); - | |__________^ +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); | - = help: consider using `write!` to avoid the extra allocation -error: aborting due to 5 previous errors +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:48:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:57:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:66:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:73:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:84:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:93:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:102:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:111:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:120:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string.rs:127:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: aborting due to 15 previous errors diff --git a/tests/ui/format_push_string_no_core.rs b/tests/ui/format_push_string_no_core.rs new file mode 100644 index 000000000000..4bc45906fa78 --- /dev/null +++ b/tests/ui/format_push_string_no_core.rs @@ -0,0 +1,15 @@ +//@check-pass +#![warn(clippy::format_push_string)] +#![no_std] +#![feature(no_core)] +#![no_core] + +extern crate alloc; + +use alloc::format; +use alloc::string::String; + +fn foo(string: &mut String) { + // can't suggest even `core::fmt::Write` because of `#![no_core]` + string.push_str(&format!("{:?}", 1234)); +} diff --git a/tests/ui/format_push_string_no_std.fixed b/tests/ui/format_push_string_no_std.fixed new file mode 100644 index 000000000000..32d8659dcbd5 --- /dev/null +++ b/tests/ui/format_push_string_no_std.fixed @@ -0,0 +1,15 @@ +#![warn(clippy::format_push_string)] +#![no_std] + +extern crate alloc; + +use alloc::format; +use alloc::string::String; + +fn foo(string: &mut String) { + use core::fmt::Write; + + // TODO: recognize the already imported `fmt::Write`, and don't suggest importing it again + let _ = write!(string, "{:?}", 1234); + //~^ format_push_string +} diff --git a/tests/ui/format_push_string_no_std.rs b/tests/ui/format_push_string_no_std.rs new file mode 100644 index 000000000000..a74189abe528 --- /dev/null +++ b/tests/ui/format_push_string_no_std.rs @@ -0,0 +1,15 @@ +#![warn(clippy::format_push_string)] +#![no_std] + +extern crate alloc; + +use alloc::format; +use alloc::string::String; + +fn foo(string: &mut String) { + use core::fmt::Write; + + // TODO: recognize the already imported `fmt::Write`, and don't suggest importing it again + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string +} diff --git a/tests/ui/format_push_string_no_std.stderr b/tests/ui/format_push_string_no_std.stderr new file mode 100644 index 000000000000..30fd42ac71b2 --- /dev/null +++ b/tests/ui/format_push_string_no_std.stderr @@ -0,0 +1,17 @@ +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_no_std.rs:13:5 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `core::fmt::Write` trait + = note: `-D clippy::format-push-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]` +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/format_push_string_no_std_unfixable.rs b/tests/ui/format_push_string_no_std_unfixable.rs new file mode 100644 index 000000000000..f5ed5e435b5a --- /dev/null +++ b/tests/ui/format_push_string_no_std_unfixable.rs @@ -0,0 +1,13 @@ +//@no-rustfix +#![warn(clippy::format_push_string)] +#![no_std] + +extern crate alloc; + +use alloc::format; +use alloc::string::String; + +fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string +} diff --git a/tests/ui/format_push_string_no_std_unfixable.stderr b/tests/ui/format_push_string_no_std_unfixable.stderr new file mode 100644 index 000000000000..cc716c84efe2 --- /dev/null +++ b/tests/ui/format_push_string_no_std_unfixable.stderr @@ -0,0 +1,17 @@ +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_no_std_unfixable.rs:11:5 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `core::fmt::Write` trait + = note: `-D clippy::format-push-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]` +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/format_push_string_unfixable.rs b/tests/ui/format_push_string_unfixable.rs new file mode 100644 index 000000000000..ff6c13fe4a49 --- /dev/null +++ b/tests/ui/format_push_string_unfixable.rs @@ -0,0 +1,144 @@ +//@no-rustfix +#![warn(clippy::format_push_string)] + +mod issue9493 { + pub fn u8vec_to_hex(vector: &Vec, upper: bool) -> String { + let mut hex = String::with_capacity(vector.len() * 2); + for byte in vector { + hex += &(if upper { + format!("{byte:02X}") + //~^ format_push_string + } else { + format!("{byte:02x}") + }); + } + hex + } + + pub fn other_cases() { + let mut s = String::new(); + // if let + s += &(if let Some(_a) = Some(1234) { + format!("{}", 1234) + //~^ format_push_string + } else { + format!("{}", 1234) + }); + // match + s += &(match Some(1234) { + Some(_) => format!("{}", 1234), + //~^ format_push_string + None => format!("{}", 1234), + }); + } +} + +mod import_write { + mod push_str { + // TODO: suggest importing `std::fmt::Write`; + mod not_imported { + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing the first time, but not again + mod not_imported_and_not_imported { + fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing the first time, but not again + mod not_imported_and_imported { + fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing, but only for `bar` + mod imported_and_not_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + } + + mod add_assign { + // TODO: suggest importing `std::fmt::Write`; + mod not_imported { + fn main(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing the first time, but not again + mod not_imported_and_not_imported { + fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing the first time, but not again + mod not_imported_and_imported { + fn foo(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + + // TODO: suggest importing, but only for `bar` + mod imported_and_not_imported { + fn foo(string: &mut String) { + use std::fmt::Write; + + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + + fn bar(string: &mut String) { + string.push_str(&format!("{:?}", 1234)); + //~^ format_push_string + } + } + } +} + +fn main() {} diff --git a/tests/ui/format_push_string_unfixable.stderr b/tests/ui/format_push_string_unfixable.stderr new file mode 100644 index 000000000000..145e7fcc440d --- /dev/null +++ b/tests/ui/format_push_string_unfixable.stderr @@ -0,0 +1,233 @@ +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:8:13 + | +LL | / hex += &(if upper { +LL | | format!("{byte:02X}") + | | --------------------- `format!` used here +LL | | +LL | | } else { +LL | | format!("{byte:02x}") + | | --------------------- `format!` used here +LL | | }); + | |______________^ + | + = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait + = note: `-D clippy::format-push-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]` + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:21:9 + | +LL | / s += &(if let Some(_a) = Some(1234) { +LL | | format!("{}", 1234) + | | ------------------- `format!` used here +LL | | +LL | | } else { +LL | | format!("{}", 1234) + | | ------------------- `format!` used here +LL | | }); + | |__________^ + | + = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:28:9 + | +LL | / s += &(match Some(1234) { +LL | | Some(_) => format!("{}", 1234), + | | ------------------- `format!` used here +LL | | +LL | | None => format!("{}", 1234), + | | ------------------- `format!` used here +LL | | }); + | |__________^ + | + = help: consider using `write!` to avoid the extra allocation + = note: you may need to import the `std::fmt::Write` trait + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:41:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:49:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:54:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:62:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:69:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:79:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:84:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:94:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:102:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:107:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:115:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:122:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:132:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: `format!(..)` appended to existing `String` + --> tests/ui/format_push_string_unfixable.rs:137:17 + | +LL | string.push_str(&format!("{:?}", 1234)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: you may need to import the `std::fmt::Write` trait +help: consider using `write!` to avoid the extra allocation + | +LL - string.push_str(&format!("{:?}", 1234)); +LL + let _ = write!(string, "{:?}", 1234); + | + +error: aborting due to 17 previous errors + diff --git a/tests/ui/if_not_else.fixed b/tests/ui/if_not_else.fixed index 4e6f43e5671e..a29847f0cf97 100644 --- a/tests/ui/if_not_else.fixed +++ b/tests/ui/if_not_else.fixed @@ -76,3 +76,20 @@ fn with_annotations() { println!("foo is false"); } } + +fn issue15924() { + let x = 0; + if matches!(x, 0..10) { + println!(":("); + } else { + //~^ if_not_else + println!(":)"); + } + + if dbg!(x) == 1 { + println!(":("); + } else { + //~^ if_not_else + println!(":)"); + } +} diff --git a/tests/ui/if_not_else.rs b/tests/ui/if_not_else.rs index 6cd2e3bd63fe..4ae11d6ad90e 100644 --- a/tests/ui/if_not_else.rs +++ b/tests/ui/if_not_else.rs @@ -76,3 +76,20 @@ fn with_annotations() { println!("foo"); /* foo */ } } + +fn issue15924() { + let x = 0; + if !matches!(x, 0..10) { + //~^ if_not_else + println!(":)"); + } else { + println!(":("); + } + + if dbg!(x) != 1 { + //~^ if_not_else + println!(":)"); + } else { + println!(":("); + } +} diff --git a/tests/ui/if_not_else.stderr b/tests/ui/if_not_else.stderr index 824837bd52bb..0682bf80da55 100644 --- a/tests/ui/if_not_else.stderr +++ b/tests/ui/if_not_else.stderr @@ -147,5 +147,47 @@ LL + println!("foo is false"); LL + } | -error: aborting due to 6 previous errors +error: unnecessary boolean `not` operation + --> tests/ui/if_not_else.rs:82:5 + | +LL | / if !matches!(x, 0..10) { +LL | | +LL | | println!(":)"); +LL | | } else { +LL | | println!(":("); +LL | | } + | |_____^ + | +help: try + | +LL ~ if matches!(x, 0..10) { +LL + println!(":("); +LL + } else { +LL + +LL + println!(":)"); +LL + } + | + +error: unnecessary `!=` operation + --> tests/ui/if_not_else.rs:89:5 + | +LL | / if dbg!(x) != 1 { +LL | | +LL | | println!(":)"); +LL | | } else { +LL | | println!(":("); +LL | | } + | |_____^ + | +help: try + | +LL ~ if dbg!(x) == 1 { +LL + println!(":("); +LL + } else { +LL + +LL + println!(":)"); +LL + } + | + +error: aborting due to 8 previous errors diff --git a/tests/ui/if_then_some_else_none.fixed b/tests/ui/if_then_some_else_none.fixed index 7da9401a308f..ce122ac69b12 100644 --- a/tests/ui/if_then_some_else_none.fixed +++ b/tests/ui/if_then_some_else_none.fixed @@ -3,10 +3,20 @@ fn main() { // Should issue an error. - let _ = foo().then(|| { println!("true!"); "foo" }); + let _ = foo().then(|| { + //~^ if_then_some_else_none + + println!("true!"); + "foo" + }); // Should issue an error when macros are used. - let _ = matches!(true, true).then(|| { println!("true!"); matches!(true, false) }); + let _ = matches!(true, true).then(|| { + //~^ if_then_some_else_none + + println!("true!"); + matches!(true, false) + }); // Should issue an error. Binary expression `o < 32` should be parenthesized. let x = Some(5); @@ -71,7 +81,12 @@ fn _msrv_1_49() { #[clippy::msrv = "1.50"] fn _msrv_1_50() { - let _ = foo().then(|| { println!("true!"); 150 }); + let _ = foo().then(|| { + //~^ if_then_some_else_none + + println!("true!"); + 150 + }); } fn foo() -> bool { @@ -182,7 +197,10 @@ fn issue15005() { fn next(&mut self) -> Option { //~v if_then_some_else_none - (self.count < 5).then(|| { self.count += 1; self.count }) + (self.count < 5).then(|| { + self.count += 1; + self.count + }) } } } @@ -195,7 +213,10 @@ fn statements_from_macro() { }; } //~v if_then_some_else_none - let _ = true.then(|| { mac!(); 42 }); + let _ = true.then(|| { + mac!(); + 42 + }); } fn dont_lint_inside_macros() { @@ -218,3 +239,24 @@ mod issue15770 { Ok(()) } } + +mod issue16176 { + pub async fn foo() -> u32 { + todo!() + } + + pub async fn bar(cond: bool) -> Option { + if cond { Some(foo().await) } else { None } // OK + } +} + +fn issue16269() -> Option { + use std::cell::UnsafeCell; + + //~v if_then_some_else_none + (1 <= 3).then(|| { + let a = UnsafeCell::new(1); + // SAFETY: `bytes` bytes starting at `new_end` were just reserved. + unsafe { *a.get() } + }) +} diff --git a/tests/ui/if_then_some_else_none.rs b/tests/ui/if_then_some_else_none.rs index 02962f83ce8a..1d6c86d94492 100644 --- a/tests/ui/if_then_some_else_none.rs +++ b/tests/ui/if_then_some_else_none.rs @@ -274,3 +274,26 @@ mod issue15770 { Ok(()) } } + +mod issue16176 { + pub async fn foo() -> u32 { + todo!() + } + + pub async fn bar(cond: bool) -> Option { + if cond { Some(foo().await) } else { None } // OK + } +} + +fn issue16269() -> Option { + use std::cell::UnsafeCell; + + //~v if_then_some_else_none + if 1 <= 3 { + let a = UnsafeCell::new(1); + // SAFETY: `bytes` bytes starting at `new_end` were just reserved. + Some(unsafe { *a.get() }) + } else { + None + } +} diff --git a/tests/ui/if_then_some_else_none.stderr b/tests/ui/if_then_some_else_none.stderr index 58651a055942..eff5f8c82dcb 100644 --- a/tests/ui/if_then_some_else_none.stderr +++ b/tests/ui/if_then_some_else_none.stderr @@ -9,10 +9,19 @@ LL | | println!("true!"); ... | LL | | None LL | | }; - | |_____^ help: try: `foo().then(|| { println!("true!"); "foo" })` + | |_____^ | = note: `-D clippy::if-then-some-else-none` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::if_then_some_else_none)]` +help: try + | +LL ~ let _ = foo().then(|| { +LL + +LL + +LL + println!("true!"); +LL + "foo" +LL ~ }); + | error: this could be simplified with `bool::then` --> tests/ui/if_then_some_else_none.rs:16:13 @@ -25,7 +34,17 @@ LL | | println!("true!"); ... | LL | | None LL | | }; - | |_____^ help: try: `matches!(true, true).then(|| { println!("true!"); matches!(true, false) })` + | |_____^ + | +help: try + | +LL ~ let _ = matches!(true, true).then(|| { +LL + +LL + +LL + println!("true!"); +LL + matches!(true, false) +LL ~ }); + | error: this could be simplified with `bool::then_some` --> tests/ui/if_then_some_else_none.rs:27:28 @@ -50,7 +69,17 @@ LL | | println!("true!"); ... | LL | | None LL | | }; - | |_____^ help: try: `foo().then(|| { println!("true!"); 150 })` + | |_____^ + | +help: try + | +LL ~ let _ = foo().then(|| { +LL + +LL + +LL + println!("true!"); +LL + 150 +LL ~ }); + | error: this could be simplified with `bool::then` --> tests/ui/if_then_some_else_none.rs:138:5 @@ -125,7 +154,15 @@ LL | | Some(self.count) LL | | } else { LL | | None LL | | } - | |_____________^ help: try: `(self.count < 5).then(|| { self.count += 1; self.count })` + | |_____________^ + | +help: try + | +LL ~ (self.count < 5).then(|| { +LL + self.count += 1; +LL + self.count +LL + }) + | error: this could be simplified with `bool::then` --> tests/ui/if_then_some_else_none.rs:249:13 @@ -137,7 +174,36 @@ LL | | Some(42) LL | | } else { LL | | None LL | | }; - | |_____^ help: try: `true.then(|| { mac!(); 42 })` + | |_____^ + | +help: try + | +LL ~ let _ = true.then(|| { +LL + mac!(); +LL + 42 +LL ~ }); + | -error: aborting due to 13 previous errors +error: this could be simplified with `bool::then` + --> tests/ui/if_then_some_else_none.rs:292:5 + | +LL | / if 1 <= 3 { +LL | | let a = UnsafeCell::new(1); +LL | | // SAFETY: `bytes` bytes starting at `new_end` were just reserved. +LL | | Some(unsafe { *a.get() }) +LL | | } else { +LL | | None +LL | | } + | |_____^ + | +help: try + | +LL ~ (1 <= 3).then(|| { +LL + let a = UnsafeCell::new(1); +LL + // SAFETY: `bytes` bytes starting at `new_end` were just reserved. +LL + unsafe { *a.get() } +LL + }) + | + +error: aborting due to 14 previous errors diff --git a/tests/ui/manual_instant_elapsed.fixed b/tests/ui/manual_instant_elapsed.fixed index a04c601e08c1..2fa5702f8a04 100644 --- a/tests/ui/manual_instant_elapsed.fixed +++ b/tests/ui/manual_instant_elapsed.fixed @@ -28,3 +28,19 @@ fn main() { // //~^^ manual_instant_elapsed } + +fn issue16236() { + use std::ops::Sub as _; + macro_rules! deref { + ($e:expr) => { + *$e + }; + } + + let start = &Instant::now(); + let _ = deref!(start).elapsed(); + //~^ manual_instant_elapsed + + deref!(start).elapsed(); + //~^ manual_instant_elapsed +} diff --git a/tests/ui/manual_instant_elapsed.rs b/tests/ui/manual_instant_elapsed.rs index 7c67f6acf85d..e7a0e6499e74 100644 --- a/tests/ui/manual_instant_elapsed.rs +++ b/tests/ui/manual_instant_elapsed.rs @@ -28,3 +28,19 @@ fn main() { // //~^^ manual_instant_elapsed } + +fn issue16236() { + use std::ops::Sub as _; + macro_rules! deref { + ($e:expr) => { + *$e + }; + } + + let start = &Instant::now(); + let _ = Instant::now().sub(deref!(start)); + //~^ manual_instant_elapsed + + Instant::now() - deref!(start); + //~^ manual_instant_elapsed +} diff --git a/tests/ui/manual_instant_elapsed.stderr b/tests/ui/manual_instant_elapsed.stderr index e84f3126f707..e42ac5739a29 100644 --- a/tests/ui/manual_instant_elapsed.stderr +++ b/tests/ui/manual_instant_elapsed.stderr @@ -13,5 +13,17 @@ error: manual implementation of `Instant::elapsed` LL | Instant::now() - *ref_to_instant; // to ensure parens are added correctly | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*ref_to_instant).elapsed()` -error: aborting due to 2 previous errors +error: manual implementation of `Instant::elapsed` + --> tests/ui/manual_instant_elapsed.rs:41:13 + | +LL | let _ = Instant::now().sub(deref!(start)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `deref!(start).elapsed()` + +error: manual implementation of `Instant::elapsed` + --> tests/ui/manual_instant_elapsed.rs:44:5 + | +LL | Instant::now() - deref!(start); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `deref!(start).elapsed()` + +error: aborting due to 4 previous errors diff --git a/tests/ui/map_unwrap_or.stderr b/tests/ui/map_unwrap_or.stderr index b0b02f3f8d6b..df0207c420e6 100644 --- a/tests/ui/map_unwrap_or.stderr +++ b/tests/ui/map_unwrap_or.stderr @@ -127,6 +127,14 @@ LL | | x + 1 LL | | } LL | | ).unwrap_or_else(|| 0); | |__________________________^ + | +help: try + | +LL ~ let _ = opt.map_or_else(|| 0, |x| { +LL + +LL + x + 1 +LL ~ }); + | error: called `map().unwrap_or_else()` on an `Option` value --> tests/ui/map_unwrap_or.rs:63:13 @@ -138,6 +146,12 @@ LL | | .unwrap_or_else(|| LL | | 0 LL | | ); | |_________^ + | +help: try + | +LL ~ let _ = opt.map_or_else(|| +LL ~ 0, |x| x + 1); + | error: called `map().unwrap_or(false)` on an `Option` value --> tests/ui/map_unwrap_or.rs:70:13 @@ -161,6 +175,14 @@ LL | | x + 1 LL | | } LL | | ).unwrap_or_else(|_e| 0); | |____________________________^ + | +help: try + | +LL ~ let _ = res.map_or_else(|_e| 0, |x| { +LL + +LL + x + 1 +LL ~ }); + | error: called `map().unwrap_or_else()` on a `Result` value --> tests/ui/map_unwrap_or.rs:86:13 @@ -172,6 +194,13 @@ LL | | .unwrap_or_else(|_e| { LL | | 0 LL | | }); | |__________^ + | +help: try + | +LL ~ let _ = res.map_or_else(|_e| { +LL + 0 +LL ~ }, |x| x + 1); + | error: called `map().unwrap_or_else()` on a `Result` value --> tests/ui/map_unwrap_or.rs:111:13 diff --git a/tests/ui/match_like_matches_macro.fixed b/tests/ui/match_like_matches_macro.fixed index dad59c1ce6e4..045ee32bd8bb 100644 --- a/tests/ui/match_like_matches_macro.fixed +++ b/tests/ui/match_like_matches_macro.fixed @@ -1,6 +1,7 @@ #![warn(clippy::match_like_matches_macro)] #![allow( unreachable_patterns, + irrefutable_let_patterns, clippy::equatable_if_let, clippy::needless_borrowed_reference, clippy::redundant_guards @@ -230,3 +231,24 @@ fn issue15841(opt: Option>>, value: i32) { let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() })); //~^^^^ match_like_matches_macro } + +fn issue16015() -> bool { + use std::any::{TypeId, type_name}; + pub struct GetTypeId(T); + + impl GetTypeId { + pub const VALUE: TypeId = TypeId::of::(); + } + + macro_rules! typeid { + ($t:ty) => { + GetTypeId::<$t>::VALUE + }; + } + + matches!(typeid!(T), _); + //~^^^^ match_like_matches_macro + + matches!(typeid!(U), _) + //~^ match_like_matches_macro +} diff --git a/tests/ui/match_like_matches_macro.rs b/tests/ui/match_like_matches_macro.rs index 94bc6433e5cb..231e1ae98f86 100644 --- a/tests/ui/match_like_matches_macro.rs +++ b/tests/ui/match_like_matches_macro.rs @@ -1,6 +1,7 @@ #![warn(clippy::match_like_matches_macro)] #![allow( unreachable_patterns, + irrefutable_let_patterns, clippy::equatable_if_let, clippy::needless_borrowed_reference, clippy::redundant_guards @@ -277,3 +278,27 @@ fn issue15841(opt: Option>>, value: i32) { }; //~^^^^ match_like_matches_macro } + +fn issue16015() -> bool { + use std::any::{TypeId, type_name}; + pub struct GetTypeId(T); + + impl GetTypeId { + pub const VALUE: TypeId = TypeId::of::(); + } + + macro_rules! typeid { + ($t:ty) => { + GetTypeId::<$t>::VALUE + }; + } + + match typeid!(T) { + _ => true, + _ => false, + }; + //~^^^^ match_like_matches_macro + + if let _ = typeid!(U) { true } else { false } + //~^ match_like_matches_macro +} diff --git a/tests/ui/match_like_matches_macro.stderr b/tests/ui/match_like_matches_macro.stderr index a8e352461dbb..bc3e3584938e 100644 --- a/tests/ui/match_like_matches_macro.stderr +++ b/tests/ui/match_like_matches_macro.stderr @@ -1,5 +1,5 @@ error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:13:14 + --> tests/ui/match_like_matches_macro.rs:14:14 | LL | let _y = match x { | ______________^ @@ -20,7 +20,7 @@ LL + let _y = matches!(x, Some(0)); | error: redundant pattern matching, consider using `is_some()` - --> tests/ui/match_like_matches_macro.rs:20:14 + --> tests/ui/match_like_matches_macro.rs:21:14 | LL | let _w = match x { | ______________^ @@ -33,7 +33,7 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]` error: redundant pattern matching, consider using `is_none()` - --> tests/ui/match_like_matches_macro.rs:27:14 + --> tests/ui/match_like_matches_macro.rs:28:14 | LL | let _z = match x { | ______________^ @@ -43,7 +43,7 @@ LL | | }; | |_____^ help: try: `x.is_none()` error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:34:15 + --> tests/ui/match_like_matches_macro.rs:35:15 | LL | let _zz = match x { | _______________^ @@ -62,7 +62,7 @@ LL + let _zz = !matches!(x, Some(r) if r == 0); | error: `if let .. else` expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:41:16 + --> tests/ui/match_like_matches_macro.rs:42:16 | LL | let _zzz = if let Some(5) = x { true } else { false }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL + let _zzz = matches!(x, Some(5)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:66:20 + --> tests/ui/match_like_matches_macro.rs:67:20 | LL | let _ans = match x { | ____________________^ @@ -95,7 +95,7 @@ LL + let _ans = matches!(x, E::A(_) | E::B(_)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:77:20 + --> tests/ui/match_like_matches_macro.rs:78:20 | LL | let _ans = match x { | ____________________^ @@ -119,7 +119,7 @@ LL + let _ans = matches!(x, E::A(_) | E::B(_)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:88:20 + --> tests/ui/match_like_matches_macro.rs:89:20 | LL | let _ans = match x { | ____________________^ @@ -140,7 +140,7 @@ LL + let _ans = !matches!(x, E::B(_) | E::C); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:149:18 + --> tests/ui/match_like_matches_macro.rs:150:18 | LL | let _z = match &z { | __________________^ @@ -159,7 +159,7 @@ LL + let _z = matches!(z, Some(3)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:159:18 + --> tests/ui/match_like_matches_macro.rs:160:18 | LL | let _z = match &z { | __________________^ @@ -178,7 +178,7 @@ LL + let _z = matches!(&z, Some(3)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:177:21 + --> tests/ui/match_like_matches_macro.rs:178:21 | LL | let _ = match &z { | _____________________^ @@ -197,7 +197,7 @@ LL + let _ = matches!(&z, AnEnum::X); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:192:20 + --> tests/ui/match_like_matches_macro.rs:193:20 | LL | let _res = match &val { | ____________________^ @@ -216,7 +216,7 @@ LL + let _res = matches!(&val, &Some(ref _a)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:205:20 + --> tests/ui/match_like_matches_macro.rs:206:20 | LL | let _res = match &val { | ____________________^ @@ -235,7 +235,7 @@ LL + let _res = matches!(&val, &Some(ref _a)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:264:14 + --> tests/ui/match_like_matches_macro.rs:265:14 | LL | let _y = match Some(5) { | ______________^ @@ -254,7 +254,7 @@ LL + let _y = matches!(Some(5), Some(0)); | error: match expression looks like `matches!` macro - --> tests/ui/match_like_matches_macro.rs:274:13 + --> tests/ui/match_like_matches_macro.rs:275:13 | LL | let _ = match opt { | _____________^ @@ -272,5 +272,35 @@ LL - }; LL + let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() })); | -error: aborting due to 15 previous errors +error: match expression looks like `matches!` macro + --> tests/ui/match_like_matches_macro.rs:296:5 + | +LL | / match typeid!(T) { +LL | | _ => true, +LL | | _ => false, +LL | | }; + | |_____^ + | +help: use `matches!` directly + | +LL - match typeid!(T) { +LL - _ => true, +LL - _ => false, +LL - }; +LL + matches!(typeid!(T), _); + | + +error: `if let .. else` expression looks like `matches!` macro + --> tests/ui/match_like_matches_macro.rs:302:5 + | +LL | if let _ = typeid!(U) { true } else { false } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `matches!` directly + | +LL - if let _ = typeid!(U) { true } else { false } +LL + matches!(typeid!(U), _) + | + +error: aborting due to 17 previous errors diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index c1512ba3e269..0ff881472cbb 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -312,4 +312,137 @@ fn check_closures() { } } +fn issue16116() { + unsafe fn foo() -> u32 { + 0 + } + + // Do not lint even though `format!` expansion + // contains unsafe calls. + unsafe { + let _ = format!("{}", foo()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + let _ = format!("{}", foo()); + let _ = format!("{}", foo()); + } + + // Do not lint: only one `assert!()` argument is unsafe + unsafe { + assert_eq!(foo(), 0, "{}", 1 + 2); + } + + // Each argument of a macro call may count as an unsafe operation. + unsafe { + //~^ multiple_unsafe_ops_per_block + assert_eq!(foo(), 0, "{}", foo()); // One unsafe operation + } + + macro_rules! twice { + ($e:expr) => {{ + $e; + $e; + }}; + } + + // Do not lint, a repeated argument used twice by a macro counts + // as at most one unsafe operation. + unsafe { + twice!(foo()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + twice!(foo()); + twice!(foo()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + assert_eq!(foo(), 0, "{}", 1 + 2); + assert_eq!(foo(), 0, "{}", 1 + 2); + } + + macro_rules! unsafe_twice { + ($e:expr) => { + unsafe { + $e; + $e; + } + }; + }; + + // A macro whose expansion contains unsafe blocks will not + // check inside the blocks. + unsafe { + unsafe_twice!(foo()); + } + + macro_rules! double_non_arg_unsafe { + () => {{ + _ = str::from_utf8_unchecked(&[]); + _ = str::from_utf8_unchecked(&[]); + }}; + } + + // Do not lint: each unsafe expression contained in the + // macro expansion will count towards the macro call. + unsafe { + double_non_arg_unsafe!(); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + double_non_arg_unsafe!(); + double_non_arg_unsafe!(); + } + + // Do not lint: the inner macro call counts as one unsafe op. + unsafe { + assert_eq!(double_non_arg_unsafe!(), ()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + assert_eq!(double_non_arg_unsafe!(), ()); + assert_eq!(double_non_arg_unsafe!(), ()); + } + + unsafe { + //~^ multiple_unsafe_ops_per_block + assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ())); + } + + macro_rules! unsafe_with_arg { + ($e:expr) => {{ + _ = str::from_utf8_unchecked(&[]); + $e; + }}; + } + + // A confusing situation: the macro call counts towards two unsafe calls, + // one coming from inside the macro itself, and one coming from its argument. + // The error message may seem a bit strange as both the macro call and its + // argument will be marked as counting as unsafe ops, but a short investigation + // in those rare situations should sort it out easily. + unsafe { + //~^ multiple_unsafe_ops_per_block + unsafe_with_arg!(foo()); + } + + macro_rules! ignore { + ($e: expr) => {}; + } + + // Another surprising case is when the macro argument is not + // used in the expansion, but in this case we won't see the + // unsafe operation at all. + unsafe { + ignore!(foo()); + ignore!(foo()); + } +} + fn main() {} diff --git a/tests/ui/multiple_unsafe_ops_per_block.stderr b/tests/ui/multiple_unsafe_ops_per_block.stderr index 63f7742b734b..185225bd28c8 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.stderr +++ b/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -31,16 +31,16 @@ LL | | *raw_ptr(); LL | | } | |_____^ | -note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:50:14 - | -LL | drop(u.u); - | ^^^ note: raw pointer dereference occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:51:9 | LL | *raw_ptr(); | ^^^^^^^^^^ +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:50:14 + | +LL | drop(u.u); + | ^^^ error: this `unsafe` block contains 3 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:56:5 @@ -58,16 +58,16 @@ note: inline assembly used here | LL | asm!("nop"); | ^^^^^^^^^^^ -note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:59:9 - | -LL | sample.not_very_safe(); - | ^^^^^^^^^^^^^^^^^^^^^^ note: modification of a mutable static occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:60:9 | LL | STATIC = 0; | ^^^^^^^^^^ +note: unsafe method call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:59:9 + | +LL | sample.not_very_safe(); + | ^^^^^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 6 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:66:5 @@ -81,36 +81,36 @@ LL | | asm!("nop"); LL | | } | |_____^ | -note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:68:14 - | -LL | drop(u.u); - | ^^^ note: access of a mutable static occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:69:14 | LL | drop(STATIC); | ^^^^^^ -note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:70:9 - | -LL | sample.not_very_safe(); - | ^^^^^^^^^^^^^^^^^^^^^^ -note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:71:9 - | -LL | not_very_safe(); - | ^^^^^^^^^^^^^^^ -note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:72:9 - | -LL | *raw_ptr(); - | ^^^^^^^^^^ note: inline assembly used here --> tests/ui/multiple_unsafe_ops_per_block.rs:73:9 | LL | asm!("nop"); | ^^^^^^^^^^^ +note: raw pointer dereference occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:72:9 + | +LL | *raw_ptr(); + | ^^^^^^^^^^ +note: union field access occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:68:14 + | +LL | drop(u.u); + | ^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:71:9 + | +LL | not_very_safe(); + | ^^^^^^^^^^^^^^^ +note: unsafe method call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:70:9 + | +LL | sample.not_very_safe(); + | ^^^^^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:109:5 @@ -139,16 +139,16 @@ error: this `unsafe` block contains 2 unsafe operations, expected only one LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:118:18 - | -LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:118:43 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:118:18 + | +LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:139:9 @@ -224,16 +224,16 @@ LL | | foo().await; LL | | } | |_____^ | -note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:194:9 - | -LL | not_very_safe(); - | ^^^^^^^^^^^^^^^ note: modification of a mutable static occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:195:9 | LL | STATIC += 1; | ^^^^^^^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:194:9 + | +LL | not_very_safe(); + | ^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:207:5 @@ -265,16 +265,16 @@ LL | | Some(foo_unchecked()).unwrap_unchecked().await; LL | | } | |_____^ | -note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:216:9 - | -LL | Some(foo_unchecked()).unwrap_unchecked().await; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: unsafe function call occurs here --> tests/ui/multiple_unsafe_ops_per_block.rs:216:14 | LL | Some(foo_unchecked()).unwrap_unchecked().await; | ^^^^^^^^^^^^^^^ +note: unsafe method call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:216:9 + | +LL | Some(foo_unchecked()).unwrap_unchecked().await; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one --> tests/ui/multiple_unsafe_ops_per_block.rs:236:5 @@ -359,5 +359,170 @@ note: unsafe function call occurs here LL | apply(|| f(0)); | ^^^^ -error: aborting due to 16 previous errors +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:326:5 + | +LL | / unsafe { +LL | | +LL | | let _ = format!("{}", foo()); +LL | | let _ = format!("{}", foo()); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:328:31 + | +LL | let _ = format!("{}", foo()); + | ^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:329:31 + | +LL | let _ = format!("{}", foo()); + | ^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:338:5 + | +LL | / unsafe { +LL | | +LL | | assert_eq!(foo(), 0, "{}", foo()); // One unsafe operation +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:340:20 + | +LL | assert_eq!(foo(), 0, "{}", foo()); // One unsafe operation + | ^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:340:36 + | +LL | assert_eq!(foo(), 0, "{}", foo()); // One unsafe operation + | ^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:356:5 + | +LL | / unsafe { +LL | | +LL | | twice!(foo()); +LL | | twice!(foo()); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:358:16 + | +LL | twice!(foo()); + | ^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:359:16 + | +LL | twice!(foo()); + | ^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:362:5 + | +LL | / unsafe { +LL | | +LL | | assert_eq!(foo(), 0, "{}", 1 + 2); +LL | | assert_eq!(foo(), 0, "{}", 1 + 2); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:364:20 + | +LL | assert_eq!(foo(), 0, "{}", 1 + 2); + | ^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:365:20 + | +LL | assert_eq!(foo(), 0, "{}", 1 + 2); + | ^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:396:5 + | +LL | / unsafe { +LL | | +LL | | double_non_arg_unsafe!(); +LL | | double_non_arg_unsafe!(); +LL | | } + | |_____^ + | +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:398:9 + | +LL | double_non_arg_unsafe!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:399:9 + | +LL | double_non_arg_unsafe!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:407:5 + | +LL | / unsafe { +LL | | +LL | | assert_eq!(double_non_arg_unsafe!(), ()); +LL | | assert_eq!(double_non_arg_unsafe!(), ()); +LL | | } + | |_____^ + | +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:409:20 + | +LL | assert_eq!(double_non_arg_unsafe!(), ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:410:20 + | +LL | assert_eq!(double_non_arg_unsafe!(), ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:413:5 + | +LL | / unsafe { +LL | | +LL | | assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ())); +LL | | } + | |_____^ + | +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:415:21 + | +LL | assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ())); + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:415:47 + | +LL | assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ())); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> tests/ui/multiple_unsafe_ops_per_block.rs:430:5 + | +LL | / unsafe { +LL | | +LL | | unsafe_with_arg!(foo()); +LL | | } + | |_____^ + | +note: this macro call expands into one or more unsafe operations + --> tests/ui/multiple_unsafe_ops_per_block.rs:432:9 + | +LL | unsafe_with_arg!(foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: unsafe function call occurs here + --> tests/ui/multiple_unsafe_ops_per_block.rs:432:26 + | +LL | unsafe_with_arg!(foo()); + | ^^^^^ + +error: aborting due to 24 previous errors diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index ba1451bf9704..99027e79b664 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -214,3 +214,8 @@ mod issue8055_regression { .len(); } } + +fn issue16270() { + // Do not lint, `..` implements `Index` but is not `usize` + _ = &(1..3).collect::>()[..]; +} diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index e054cd01e6f5..683cc49c9af3 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -214,3 +214,8 @@ mod issue8055_regression { .len(); } } + +fn issue16270() { + // Do not lint, `..` implements `Index` but is not `usize` + _ = &(1..3).collect::>()[..]; +} diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr index 94d98f0e9b12..c427f4c3e42c 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -1,213 +1,281 @@ -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:12:11 | LL | fn foo(s: &mut Vec, b: &u32, x: &mut u32) { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` | = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:38:12 | LL | fn foo6(s: &mut Vec) { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:49:12 | LL | fn bar(&mut self) {} - | ^^^^^^^^^ help: consider changing to: `&self` + | ^----^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:52:29 | LL | fn mushroom(&self, vec: &mut Vec) -> usize { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:130:16 | LL | async fn a1(x: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:135:16 | LL | async fn a2(x: &mut i32, y: String) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:140:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:145:16 | LL | async fn a4(x: &mut i32, y: i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:150:24 | LL | async fn a5(x: i32, y: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:155:24 | LL | async fn a6(x: i32, y: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:160:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:165:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:165:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:201:16 | LL | fn cfg_warn(s: &mut u32) {} - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` | = note: this is cfg-gated and may require further changes -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:206:20 | LL | fn cfg_warn(s: &mut u32) {} - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` | = note: this is cfg-gated and may require further changes -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:219:39 | LL | async fn inner_async2(x: &mut i32, y: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:228:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:248:30 | LL | async fn call_in_closure1(n: &mut str) { - | ^^^^^^^^ help: consider changing to: `&str` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:268:16 | LL | fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { - | ^^^^^^^^^^ help: consider changing to: `&usize` + | ^----^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:280:22 | LL | async fn closure4(n: &mut usize) { - | ^^^^^^^^^^ help: consider changing to: `&usize` + | ^----^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:335:12 | LL | fn bar(&mut self) {} - | ^^^^^^^^^ help: consider changing to: `&self` + | ^----^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:338:18 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { - | ^^^^^^^^^ help: consider changing to: `&self` + | ^----^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:338:45 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:347:46 | LL | async fn foo2(&mut self, u: &mut i32, v: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:364:18 | LL | fn _empty_tup(x: &mut (())) {} - | ^^^^^^^^^ help: consider changing to: `&()` + | ^^----^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:366:19 | LL | fn _single_tup(x: &mut ((i32,))) {} - | ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)` + | ^^----^^^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:368:18 | LL | fn _multi_tup(x: &mut ((i32, u32))) {} - | ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)` + | ^^----^^^^^^^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:370:11 | LL | fn _fn(x: &mut (fn())) {} - | ^^^^^^^^^^^ help: consider changing to: `&fn()` + | ^^----^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:373:23 | LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()` + | ^----^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:375:20 | LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} - | ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()` + | ^----^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:377:18 | LL | fn _unsafe_fn(x: &mut unsafe fn()) {} - | ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()` + | ^----^^^^^^^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:379:25 | LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()` + | ^----^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:381:20 | LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)` + | ^----^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:383:20 | LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)` + | ^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: aborting due to 34 previous errors diff --git a/tests/ui/needless_pass_by_ref_mut2.fixed b/tests/ui/needless_pass_by_ref_mut2.fixed index 0e2ac0202364..c462f1cc8d87 100644 --- a/tests/ui/needless_pass_by_ref_mut2.fixed +++ b/tests/ui/needless_pass_by_ref_mut2.fixed @@ -24,3 +24,9 @@ async fn inner_async4(u: &mut i32, v: &u32) { } fn main() {} + +//~v needless_pass_by_ref_mut +fn issue16267<'a>(msg: &str, slice: &'a [i32]) -> &'a [i32] { + println!("{msg}"); + &slice[0..5] +} diff --git a/tests/ui/needless_pass_by_ref_mut2.rs b/tests/ui/needless_pass_by_ref_mut2.rs index 9201d9a27298..b00f294c57f0 100644 --- a/tests/ui/needless_pass_by_ref_mut2.rs +++ b/tests/ui/needless_pass_by_ref_mut2.rs @@ -24,3 +24,9 @@ async fn inner_async4(u: &mut i32, v: &mut u32) { } fn main() {} + +//~v needless_pass_by_ref_mut +fn issue16267<'a>(msg: &str, slice: &'a mut [i32]) -> &'a [i32] { + println!("{msg}"); + &slice[0..5] +} diff --git a/tests/ui/needless_pass_by_ref_mut2.stderr b/tests/ui/needless_pass_by_ref_mut2.stderr index 9876a6b50718..aa5c412adb4d 100644 --- a/tests/ui/needless_pass_by_ref_mut2.stderr +++ b/tests/ui/needless_pass_by_ref_mut2.stderr @@ -1,17 +1,29 @@ -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut2.rs:8:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` | = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is not used mutably --> tests/ui/needless_pass_by_ref_mut2.rs:17:39 | LL | async fn inner_async4(u: &mut i32, v: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: aborting due to 2 previous errors +error: this parameter is a mutable reference but is not used mutably + --> tests/ui/needless_pass_by_ref_mut2.rs:29:37 + | +LL | fn issue16267<'a>(msg: &str, slice: &'a mut [i32]) -> &'a [i32] { + | ^^^^----^^^^^ + | | + | help: consider removing this `mut` + +error: aborting due to 3 previous errors diff --git a/tests/ui/needless_type_cast.fixed b/tests/ui/needless_type_cast.fixed index 32c348d3ca3a..72eed32c4d73 100644 --- a/tests/ui/needless_type_cast.fixed +++ b/tests/ui/needless_type_cast.fixed @@ -9,6 +9,10 @@ fn generic(x: T) -> T { x } +fn returns_u8() -> u8 { + 10 +} + fn main() { let a: i32 = 10; //~^ needless_type_cast @@ -180,3 +184,86 @@ fn test_loop_with_generic() { }; let _ = x as i32; } + +fn test_size_of_cast() { + use std::mem::size_of; + // Should lint: suggest casting the initializer + let size: u64 = size_of::() as u64; + //~^ needless_type_cast + let _ = size as u64; + let _ = size as u64; +} + +fn test_suffixed_literal_cast() { + // Should lint: suggest casting the initializer + let a: i32 = 10u8 as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_negative_literal() { + // Negative literal - should just change type, not add cast + let a: i32 = -10; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_suffixed_negative_literal() { + // Suffixed negative - needs cast + let a: i32 = -10i8 as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_binary_op() { + // Binary op needs parens in cast + let a: i32 = 10 + 5; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_fn_return_as_init() { + let a: i32 = returns_u8() as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_method_as_init() { + let a: i32 = 2u8.saturating_add(3) as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_const_as_init() { + const X: u8 = 10; + let a: i32 = X as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_single_use_fn_call() { + // Should not lint: only one use, and fixing would just move the cast + // to the initializer rather than eliminating it + let a: u8 = returns_u8(); + let _ = a as i32; +} + +fn test_single_use_suffixed_literal() { + // Should not lint: only one use with a suffixed literal + let a: u8 = 10u8; + let _ = a as i32; +} + +fn test_single_use_binary_op() { + // Should lint: binary op of unsuffixed literals can be coerced + let a: i32 = 10 + 5; + //~^ needless_type_cast + let _ = a as i32; +} diff --git a/tests/ui/needless_type_cast.rs b/tests/ui/needless_type_cast.rs index e28f620e035f..31337575fcc3 100644 --- a/tests/ui/needless_type_cast.rs +++ b/tests/ui/needless_type_cast.rs @@ -9,6 +9,10 @@ fn generic(x: T) -> T { x } +fn returns_u8() -> u8 { + 10 +} + fn main() { let a: u8 = 10; //~^ needless_type_cast @@ -180,3 +184,86 @@ fn test_loop_with_generic() { }; let _ = x as i32; } + +fn test_size_of_cast() { + use std::mem::size_of; + // Should lint: suggest casting the initializer + let size: usize = size_of::(); + //~^ needless_type_cast + let _ = size as u64; + let _ = size as u64; +} + +fn test_suffixed_literal_cast() { + // Should lint: suggest casting the initializer + let a: u8 = 10u8; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_negative_literal() { + // Negative literal - should just change type, not add cast + let a: i8 = -10; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_suffixed_negative_literal() { + // Suffixed negative - needs cast + let a: i8 = -10i8; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_binary_op() { + // Binary op needs parens in cast + let a: u8 = 10 + 5; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_fn_return_as_init() { + let a: u8 = returns_u8(); + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_method_as_init() { + let a: u8 = 2u8.saturating_add(3); + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_const_as_init() { + const X: u8 = 10; + let a: u8 = X; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_single_use_fn_call() { + // Should not lint: only one use, and fixing would just move the cast + // to the initializer rather than eliminating it + let a: u8 = returns_u8(); + let _ = a as i32; +} + +fn test_single_use_suffixed_literal() { + // Should not lint: only one use with a suffixed literal + let a: u8 = 10u8; + let _ = a as i32; +} + +fn test_single_use_binary_op() { + // Should lint: binary op of unsuffixed literals can be coerced + let a: u8 = 10 + 5; + //~^ needless_type_cast + let _ = a as i32; +} diff --git a/tests/ui/needless_type_cast.stderr b/tests/ui/needless_type_cast.stderr index 3ee9df1043e7..56d9e978d05c 100644 --- a/tests/ui/needless_type_cast.stderr +++ b/tests/ui/needless_type_cast.stderr @@ -1,5 +1,5 @@ error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:13:12 + --> tests/ui/needless_type_cast.rs:17:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` @@ -8,64 +8,154 @@ LL | let a: u8 = 10; = help: to override `-D warnings` add `#[allow(clippy::needless_type_cast)]` error: this binding is defined as `u8` but is always cast to `usize` - --> tests/ui/needless_type_cast.rs:33:12 + --> tests/ui/needless_type_cast.rs:37:12 | LL | let f: u8 = 1; | ^^ help: consider defining it as: `usize` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:39:12 + --> tests/ui/needless_type_cast.rs:43:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:52:12 + --> tests/ui/needless_type_cast.rs:56:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:59:12 + --> tests/ui/needless_type_cast.rs:63:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:66:12 + --> tests/ui/needless_type_cast.rs:70:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:77:12 + --> tests/ui/needless_type_cast.rs:81:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:99:16 + --> tests/ui/needless_type_cast.rs:103:16 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:107:12 + --> tests/ui/needless_type_cast.rs:111:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:116:12 + --> tests/ui/needless_type_cast.rs:120:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:122:12 + --> tests/ui/needless_type_cast.rs:126:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` -error: aborting due to 11 previous errors +error: this binding is defined as `usize` but is always cast to `u64` + --> tests/ui/needless_type_cast.rs:191:15 + | +LL | let size: usize = size_of::(); + | ^^^^^ + | +help: consider defining it as `u64` and casting the initializer + | +LL - let size: usize = size_of::(); +LL + let size: u64 = size_of::() as u64; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:199:12 + | +LL | let a: u8 = 10u8; + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: u8 = 10u8; +LL + let a: i32 = 10u8 as i32; + | + +error: this binding is defined as `i8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:207:12 + | +LL | let a: i8 = -10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `i8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:215:12 + | +LL | let a: i8 = -10i8; + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: i8 = -10i8; +LL + let a: i32 = -10i8 as i32; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:223:12 + | +LL | let a: u8 = 10 + 5; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:230:12 + | +LL | let a: u8 = returns_u8(); + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: u8 = returns_u8(); +LL + let a: i32 = returns_u8() as i32; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:237:12 + | +LL | let a: u8 = 2u8.saturating_add(3); + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: u8 = 2u8.saturating_add(3); +LL + let a: i32 = 2u8.saturating_add(3) as i32; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:245:12 + | +LL | let a: u8 = X; + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: u8 = X; +LL + let a: i32 = X as i32; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:266:12 + | +LL | let a: u8 = 10 + 5; + | ^^ help: consider defining it as: `i32` + +error: aborting due to 20 previous errors diff --git a/tests/ui/needless_type_cast_unfixable.rs b/tests/ui/needless_type_cast_unfixable.rs new file mode 100644 index 000000000000..bbea9bd24296 --- /dev/null +++ b/tests/ui/needless_type_cast_unfixable.rs @@ -0,0 +1,20 @@ +//@no-rustfix +#![warn(clippy::needless_type_cast)] + +struct Foo(*mut core::ffi::c_void); + +enum Bar { + Variant(*mut core::ffi::c_void), +} + +// Suggestions will not compile directly, as `123` is a literal which +// is not compatible with the suggested `*mut core::ffi::c_void` type +fn issue_16243() { + let underlying: isize = 123; + //~^ needless_type_cast + let handle: Foo = Foo(underlying as _); + + let underlying: isize = 123; + //~^ needless_type_cast + let handle: Bar = Bar::Variant(underlying as _); +} diff --git a/tests/ui/needless_type_cast_unfixable.stderr b/tests/ui/needless_type_cast_unfixable.stderr new file mode 100644 index 000000000000..b71f8a09c40f --- /dev/null +++ b/tests/ui/needless_type_cast_unfixable.stderr @@ -0,0 +1,17 @@ +error: this binding is defined as `isize` but is always cast to `*mut std::ffi::c_void` + --> tests/ui/needless_type_cast_unfixable.rs:13:21 + | +LL | let underlying: isize = 123; + | ^^^^^ help: consider defining it as: `*mut std::ffi::c_void` + | + = note: `-D clippy::needless-type-cast` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_type_cast)]` + +error: this binding is defined as `isize` but is always cast to `*mut std::ffi::c_void` + --> tests/ui/needless_type_cast_unfixable.rs:17:21 + | +LL | let underlying: isize = 123; + | ^^^^^ help: consider defining it as: `*mut std::ffi::c_void` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/never_loop_iterator_reduction.rs b/tests/ui/never_loop_iterator_reduction.rs new file mode 100644 index 000000000000..6b07b91db29a --- /dev/null +++ b/tests/ui/never_loop_iterator_reduction.rs @@ -0,0 +1,17 @@ +//@no-rustfix +#![warn(clippy::never_loop)] + +fn main() { + // diverging closure: should trigger + [0, 1].into_iter().for_each(|x| { + //~^ never_loop + + let _ = x; + panic!("boom"); + }); + + // benign closure: should NOT trigger + [0, 1].into_iter().for_each(|x| { + let _ = x + 1; + }); +} diff --git a/tests/ui/never_loop_iterator_reduction.stderr b/tests/ui/never_loop_iterator_reduction.stderr new file mode 100644 index 000000000000..b76ee283146c --- /dev/null +++ b/tests/ui/never_loop_iterator_reduction.stderr @@ -0,0 +1,27 @@ +error: this iterator reduction never loops (closure always diverges) + --> tests/ui/never_loop_iterator_reduction.rs:6:5 + | +LL | / [0, 1].into_iter().for_each(|x| { +LL | | +LL | | +LL | | let _ = x; +LL | | panic!("boom"); +LL | | }); + | |______^ + | + = note: if you only need one element, `if let Some(x) = iter.next()` is clearer + = note: `-D clippy::never-loop` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::never_loop)]` +help: consider this pattern + | +LL - [0, 1].into_iter().for_each(|x| { +LL - +LL - +LL - let _ = x; +LL - panic!("boom"); +LL - }); +LL + if let Some(x) = [0, 1].into_iter().next() { ... }; + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/obfuscated_if_else.fixed b/tests/ui/obfuscated_if_else.fixed index 70ae090626b9..6bdb170a4aa9 100644 --- a/tests/ui/obfuscated_if_else.fixed +++ b/tests/ui/obfuscated_if_else.fixed @@ -87,3 +87,9 @@ fn issue11141() { let _ = *if true { &42 } else { &17 } as u8; //~^ obfuscated_if_else } + +#[allow(clippy::useless_format)] +fn issue16288() { + if true { format!("this is a test") } else { Default::default() }; + //~^ obfuscated_if_else +} diff --git a/tests/ui/obfuscated_if_else.rs b/tests/ui/obfuscated_if_else.rs index 8e1f57ca2c02..f7b5ea8c0135 100644 --- a/tests/ui/obfuscated_if_else.rs +++ b/tests/ui/obfuscated_if_else.rs @@ -87,3 +87,9 @@ fn issue11141() { let _ = *true.then_some(&42).unwrap_or(&17) as u8; //~^ obfuscated_if_else } + +#[allow(clippy::useless_format)] +fn issue16288() { + true.then(|| format!("this is a test")).unwrap_or_default(); + //~^ obfuscated_if_else +} diff --git a/tests/ui/obfuscated_if_else.stderr b/tests/ui/obfuscated_if_else.stderr index 0de7259d8bb8..865dca56b97a 100644 --- a/tests/ui/obfuscated_if_else.stderr +++ b/tests/ui/obfuscated_if_else.stderr @@ -139,5 +139,11 @@ error: this method chain can be written more clearly with `if .. else ..` LL | let _ = *true.then_some(&42).unwrap_or(&17) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }` -error: aborting due to 23 previous errors +error: this method chain can be written more clearly with `if .. else ..` + --> tests/ui/obfuscated_if_else.rs:93:5 + | +LL | true.then(|| format!("this is a test")).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { format!("this is a test") } else { Default::default() }` + +error: aborting due to 24 previous errors diff --git a/tests/ui/println_empty_string.fixed b/tests/ui/println_empty_string.fixed index 05e262ec7786..6b1039ee8020 100644 --- a/tests/ui/println_empty_string.fixed +++ b/tests/ui/println_empty_string.fixed @@ -19,3 +19,23 @@ fn main() { //~^ println_empty_string } } + +#[rustfmt::skip] +fn issue_16167() { + //~v println_empty_string + println!( + ); + + match "a" { + _ => println!(), // there is a space between "" and comma + //~^ println_empty_string + } + + eprintln!(); // there is a tab between "" and comma + //~^ println_empty_string + + match "a" { + _ => eprintln!(), // tab and space between "" and comma + //~^ println_empty_string + } +} diff --git a/tests/ui/println_empty_string.rs b/tests/ui/println_empty_string.rs index 028ddb60dbce..db3b8e1a0eac 100644 --- a/tests/ui/println_empty_string.rs +++ b/tests/ui/println_empty_string.rs @@ -19,3 +19,27 @@ fn main() { //~^ println_empty_string } } + +#[rustfmt::skip] +fn issue_16167() { + //~v println_empty_string + println!( + "\ + \ + " + , + ); + + match "a" { + _ => println!("" ,), // there is a space between "" and comma + //~^ println_empty_string + } + + eprintln!("" ,); // there is a tab between "" and comma + //~^ println_empty_string + + match "a" { + _ => eprintln!("" ,), // tab and space between "" and comma + //~^ println_empty_string + } +} diff --git a/tests/ui/println_empty_string.stderr b/tests/ui/println_empty_string.stderr index 8b997aef9069..bdac1bb3b8ef 100644 --- a/tests/ui/println_empty_string.stderr +++ b/tests/ui/println_empty_string.stderr @@ -33,5 +33,42 @@ LL | _ => eprintln!(""), | | | help: remove the empty string -error: aborting due to 4 previous errors +error: empty string literal in `println!` + --> tests/ui/println_empty_string.rs:26:5 + | +LL | / println!( +LL | |/ "\ +LL | || \ +LL | || " +LL | || , +LL | || ); + | ||____-^ + | |____| + | help: remove the empty string + +error: empty string literal in `println!` + --> tests/ui/println_empty_string.rs:34:14 + | +LL | _ => println!("" ,), // there is a space between "" and comma + | ^^^^^^^^^----^ + | | + | help: remove the empty string + +error: empty string literal in `eprintln!` + --> tests/ui/println_empty_string.rs:38:5 + | +LL | eprintln!("" ,); // there is a tab between "" and comma + | ^^^^^^^^^^-------^ + | | + | help: remove the empty string + +error: empty string literal in `eprintln!` + --> tests/ui/println_empty_string.rs:42:14 + | +LL | _ => eprintln!("" ,), // tab and space between "" and comma + | ^^^^^^^^^^--------^ + | | + | help: remove the empty string + +error: aborting due to 8 previous errors diff --git a/tests/ui/println_empty_string_unfixable.rs b/tests/ui/println_empty_string_unfixable.rs new file mode 100644 index 000000000000..d6c30f627a58 --- /dev/null +++ b/tests/ui/println_empty_string_unfixable.rs @@ -0,0 +1,30 @@ +#![allow(clippy::match_single_binding)] + +// If there is a comment in the span of macro call, we don't provide an auto-fix suggestion. +#[rustfmt::skip] +fn issue_16167() { + //~v println_empty_string + println!("" /* comment */); + //~v println_empty_string + eprintln!("" /* comment */); + + //~v println_empty_string + println!( // comment + ""); + //~v println_empty_string + eprintln!( // comment + ""); + + //~v println_empty_string + println!("", /* comment */); + + //~v println_empty_string + println!( + "\ + \ + ", + + // there is a comment in the macro span regardless of its position + + ); +} diff --git a/tests/ui/println_empty_string_unfixable.stderr b/tests/ui/println_empty_string_unfixable.stderr new file mode 100644 index 000000000000..648fd7cdbccd --- /dev/null +++ b/tests/ui/println_empty_string_unfixable.stderr @@ -0,0 +1,85 @@ +error: empty string literal in `println!` + --> tests/ui/println_empty_string_unfixable.rs:7:5 + | +LL | println!("" /* comment */); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:7:14 + | +LL | println!("" /* comment */); + | ^^ + = note: `-D clippy::println-empty-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::println_empty_string)]` + +error: empty string literal in `eprintln!` + --> tests/ui/println_empty_string_unfixable.rs:9:5 + | +LL | eprintln!("" /* comment */); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:9:15 + | +LL | eprintln!("" /* comment */); + | ^^ + +error: empty string literal in `println!` + --> tests/ui/println_empty_string_unfixable.rs:12:5 + | +LL | / println!( // comment +LL | | ""); + | |___________________^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:13:17 + | +LL | ""); + | ^^ + +error: empty string literal in `eprintln!` + --> tests/ui/println_empty_string_unfixable.rs:15:5 + | +LL | / eprintln!( // comment +LL | | ""); + | |___________________^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:16:17 + | +LL | ""); + | ^^ + +error: empty string literal in `println!` + --> tests/ui/println_empty_string_unfixable.rs:19:5 + | +LL | println!("", /* comment */); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:19:14 + | +LL | println!("", /* comment */); + | ^^ + +error: empty string literal in `println!` + --> tests/ui/println_empty_string_unfixable.rs:22:5 + | +LL | / println!( +LL | | "\ +LL | | \ +LL | | ", +... | +LL | | ); + | |_____^ + | +note: remove the empty string + --> tests/ui/println_empty_string_unfixable.rs:23:9 + | +LL | / "\ +LL | | \ +LL | | ", + | |_____________^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/ref_as_ptr.fixed b/tests/ui/ref_as_ptr.fixed index ce144508581e..eadbb7c36415 100644 --- a/tests/ui/ref_as_ptr.fixed +++ b/tests/ui/ref_as_ptr.fixed @@ -86,6 +86,16 @@ fn main() { f(std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i))); //~^ ref_as_ptr + let x = (10, 20); + let _ = std::ptr::from_ref(&x); + //~^ ref_as_ptr + let _ = std::ptr::from_ref(&x.0); + //~^ ref_as_ptr + + let x = Box::new(10); + let _ = std::ptr::from_ref(&*x); + //~^ ref_as_ptr + let _ = &String::new() as *const _; let _ = &mut String::new() as *mut _; const FOO: *const String = &String::new() as *const _; diff --git a/tests/ui/ref_as_ptr.rs b/tests/ui/ref_as_ptr.rs index acdff2c2ba29..ef96a3ff5693 100644 --- a/tests/ui/ref_as_ptr.rs +++ b/tests/ui/ref_as_ptr.rs @@ -86,6 +86,16 @@ fn main() { f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]); //~^ ref_as_ptr + let x = (10, 20); + let _ = &x as *const _; + //~^ ref_as_ptr + let _ = &x.0 as *const _; + //~^ ref_as_ptr + + let x = Box::new(10); + let _ = &*x as *const _; + //~^ ref_as_ptr + let _ = &String::new() as *const _; let _ = &mut String::new() as *mut _; const FOO: *const String = &String::new() as *const _; diff --git a/tests/ui/ref_as_ptr.stderr b/tests/ui/ref_as_ptr.stderr index 79db29e596bd..587e4fb809cd 100644 --- a/tests/ui/ref_as_ptr.stderr +++ b/tests/ui/ref_as_ptr.stderr @@ -200,61 +200,67 @@ LL | f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i))` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:109:7 + --> tests/ui/ref_as_ptr.rs:90:13 + | +LL | let _ = &x as *const _; + | ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&x)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:92:13 + | +LL | let _ = &x.0 as *const _; + | ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&x.0)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:96:13 + | +LL | let _ = &*x as *const _; + | ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&*x)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:119:7 | LL | f(val as *const i32); | ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:111:7 + --> tests/ui/ref_as_ptr.rs:121:7 | LL | f(mut_val as *mut i32); | ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(mut_val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:116:7 + --> tests/ui/ref_as_ptr.rs:126:7 | LL | f(val as *const _); | ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:118:7 + --> tests/ui/ref_as_ptr.rs:128:7 | LL | f(val as *const [u8]); | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[u8]>(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:123:7 + --> tests/ui/ref_as_ptr.rs:133:7 | LL | f(val as *mut _); | ^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:125:7 + --> tests/ui/ref_as_ptr.rs:135:7 | LL | f(val as *mut str); | ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:133:9 + --> tests/ui/ref_as_ptr.rs:143:9 | LL | self.0 as *const _ as *const _ | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:138:9 - | -LL | self.0 as *const _ as *const _ - | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` - -error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:147:9 - | -LL | self.0 as *const _ as *const _ - | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` - -error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:152:9 + --> tests/ui/ref_as_ptr.rs:148:9 | LL | self.0 as *const _ as *const _ | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` @@ -262,8 +268,20 @@ LL | self.0 as *const _ as *const _ error: reference as raw pointer --> tests/ui/ref_as_ptr.rs:157:9 | +LL | self.0 as *const _ as *const _ + | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:162:9 + | +LL | self.0 as *const _ as *const _ + | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:167:9 + | LL | self.0 as *mut _ as *mut _ | ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(self.0)` -error: aborting due to 44 previous errors +error: aborting due to 47 previous errors diff --git a/tests/ui/result_large_err.rs b/tests/ui/result_large_err.rs index fa57b3f553fc..b4ad050df3b7 100644 --- a/tests/ui/result_large_err.rs +++ b/tests/ui/result_large_err.rs @@ -141,3 +141,12 @@ fn _empty_error() -> Result<(), Empty> { } fn main() {} + +fn issue16249() { + type Large = [u8; 1024]; + + let closure = || -> Result<(), Large> { Ok(()) }; + //~^ result_large_err + let closure = || Ok::<(), Large>(()); + //~^ result_large_err +} diff --git a/tests/ui/result_large_err.stderr b/tests/ui/result_large_err.stderr index 72fbc3f58961..fd39179c61cb 100644 --- a/tests/ui/result_large_err.stderr +++ b/tests/ui/result_large_err.stderr @@ -104,5 +104,21 @@ LL | pub fn array_error() -> Result<(), ArrayError<(i32, T), U>> { | = help: try reducing the size of `ArrayError<(i32, T), U>`, for example by boxing large elements or replacing it with `Box>` -error: aborting due to 12 previous errors +error: the `Err`-variant returned from this closure is very large + --> tests/ui/result_large_err.rs:148:25 + | +LL | let closure = || -> Result<(), Large> { Ok(()) }; + | ^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 1024 bytes + | + = help: try reducing the size of `[u8; 1024]`, for example by boxing large elements or replacing it with `Box<[u8; 1024]>` + +error: the `Err`-variant returned from this closure is very large + --> tests/ui/result_large_err.rs:150:19 + | +LL | let closure = || Ok::<(), Large>(()); + | ^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 1024 bytes + | + = help: try reducing the size of `[u8; 1024]`, for example by boxing large elements or replacing it with `Box<[u8; 1024]>` + +error: aborting due to 14 previous errors diff --git a/tests/ui/same_length_and_capacity.rs b/tests/ui/same_length_and_capacity.rs new file mode 100644 index 000000000000..999fcf89881d --- /dev/null +++ b/tests/ui/same_length_and_capacity.rs @@ -0,0 +1,27 @@ +#![warn(clippy::same_length_and_capacity)] + +fn main() { + let mut my_vec: Vec = Vec::with_capacity(20); + my_vec.extend([1, 2, 3, 4, 5]); + let (ptr, mut len, cap) = my_vec.into_raw_parts(); + len = 8; + + let _reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len, len) }; + //~^ same_length_and_capacity + + // Don't want to lint different expressions for len and cap + let _properly_reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len, cap) }; + + // Don't want to lint if len and cap are distinct variables but happen to be equal + let len_from_cap = cap; + let _another_properly_reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len_from_cap, cap) }; + + let my_string = String::from("hello"); + let (string_ptr, string_len, string_cap) = my_string.into_raw_parts(); + + let _reconstructed_string = unsafe { String::from_raw_parts(string_ptr, string_len, string_len) }; + //~^ same_length_and_capacity + + // Don't want to lint different expressions for len and cap + let _properly_reconstructed_string = unsafe { String::from_raw_parts(string_ptr, string_len, string_cap) }; +} diff --git a/tests/ui/same_length_and_capacity.stderr b/tests/ui/same_length_and_capacity.stderr new file mode 100644 index 000000000000..6fc852831269 --- /dev/null +++ b/tests/ui/same_length_and_capacity.stderr @@ -0,0 +1,20 @@ +error: usage of `Vec::from_raw_parts` with the same expression for length and capacity + --> tests/ui/same_length_and_capacity.rs:9:39 + | +LL | let _reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len, len) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try `Box::from(slice::from_raw_parts(...)).into::>()` + = note: `-D clippy::same-length-and-capacity` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::same_length_and_capacity)]` + +error: usage of `String::from_raw_parts` with the same expression for length and capacity + --> tests/ui/same_length_and_capacity.rs:22:42 + | +LL | let _reconstructed_string = unsafe { String::from_raw_parts(string_ptr, string_len, string_len) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try `String::from(str::from_utf8_unchecked(slice::from_raw_parts(...)))` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/set_contains_or_insert.rs b/tests/ui/set_contains_or_insert.rs index 575cfda139a4..ac1d74f8afa4 100644 --- a/tests/ui/set_contains_or_insert.rs +++ b/tests/ui/set_contains_or_insert.rs @@ -164,3 +164,24 @@ fn main() { should_not_warn_hashset(); should_not_warn_btreeset(); } + +fn issue15990(s: &mut HashSet, v: usize) { + if !s.contains(&v) { + s.clear(); + s.insert(v); + } + + fn borrow_as_mut(v: usize, s: &mut HashSet) { + s.clear(); + } + if !s.contains(&v) { + borrow_as_mut(v, s); + s.insert(v); + } + + if !s.contains(&v) { + //~^ set_contains_or_insert + let _readonly_access = s.contains(&v); + s.insert(v); + } +} diff --git a/tests/ui/set_contains_or_insert.stderr b/tests/ui/set_contains_or_insert.stderr index 3152b1136458..3b06b63182ab 100644 --- a/tests/ui/set_contains_or_insert.stderr +++ b/tests/ui/set_contains_or_insert.stderr @@ -127,5 +127,14 @@ LL | LL | borrow_set.insert(value); | ^^^^^^^^^^^^^ -error: aborting due to 14 previous errors +error: usage of `HashSet::insert` after `HashSet::contains` + --> tests/ui/set_contains_or_insert.rs:182:11 + | +LL | if !s.contains(&v) { + | ^^^^^^^^^^^^ +... +LL | s.insert(v); + | ^^^^^^^^^ + +error: aborting due to 15 previous errors diff --git a/tests/ui/track-diagnostics.rs b/tests/ui/track-diagnostics.rs index 0fbde867390d..1cd37e0570d7 100644 --- a/tests/ui/track-diagnostics.rs +++ b/tests/ui/track-diagnostics.rs @@ -3,6 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@normalize-stderr-test: "/rustc-dev/[0-9a-f]+/" -> "" struct A; struct B; diff --git a/tests/ui/transmuting_null.rs b/tests/ui/transmuting_null.rs index f3eb5060cd0d..0d3b26673452 100644 --- a/tests/ui/transmuting_null.rs +++ b/tests/ui/transmuting_null.rs @@ -30,7 +30,15 @@ fn transmute_const() { } } +fn transmute_const_int() { + unsafe { + let _: &u64 = std::mem::transmute(u64::MIN as *const u64); + //~^ transmuting_null + } +} + fn main() { one_liners(); transmute_const(); + transmute_const_int(); } diff --git a/tests/ui/transmuting_null.stderr b/tests/ui/transmuting_null.stderr index c68e4102e405..ed7c3396a243 100644 --- a/tests/ui/transmuting_null.stderr +++ b/tests/ui/transmuting_null.stderr @@ -19,5 +19,11 @@ error: transmuting a known null pointer into a reference LL | let _: &u64 = std::mem::transmute(ZPTR); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: transmuting a known null pointer into a reference + --> tests/ui/transmuting_null.rs:35:23 + | +LL | let _: &u64 = std::mem::transmute(u64::MIN as *const u64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors diff --git a/tests/ui/unchecked_time_subtraction.fixed b/tests/ui/unchecked_time_subtraction.fixed index 2f923fef4c25..830b737f18e7 100644 --- a/tests/ui/unchecked_time_subtraction.fixed +++ b/tests/ui/unchecked_time_subtraction.fixed @@ -35,3 +35,28 @@ fn main() { let _ = (2 * dur1).checked_sub(dur2).unwrap(); //~^ unchecked_time_subtraction } + +fn issue16230() { + use std::ops::Sub as _; + + Duration::ZERO.checked_sub(Duration::MAX).unwrap(); + //~^ unchecked_time_subtraction + + let _ = Duration::ZERO.checked_sub(Duration::MAX).unwrap(); + //~^ unchecked_time_subtraction +} + +fn issue16234() { + use std::ops::Sub as _; + + macro_rules! duration { + ($secs:expr) => { + Duration::from_secs($secs) + }; + } + + duration!(0).checked_sub(duration!(1)).unwrap(); + //~^ unchecked_time_subtraction + let _ = duration!(0).checked_sub(duration!(1)).unwrap(); + //~^ unchecked_time_subtraction +} diff --git a/tests/ui/unchecked_time_subtraction.rs b/tests/ui/unchecked_time_subtraction.rs index cf727f62aafa..e41860157c41 100644 --- a/tests/ui/unchecked_time_subtraction.rs +++ b/tests/ui/unchecked_time_subtraction.rs @@ -35,3 +35,28 @@ fn main() { let _ = 2 * dur1 - dur2; //~^ unchecked_time_subtraction } + +fn issue16230() { + use std::ops::Sub as _; + + Duration::ZERO.sub(Duration::MAX); + //~^ unchecked_time_subtraction + + let _ = Duration::ZERO - Duration::MAX; + //~^ unchecked_time_subtraction +} + +fn issue16234() { + use std::ops::Sub as _; + + macro_rules! duration { + ($secs:expr) => { + Duration::from_secs($secs) + }; + } + + duration!(0).sub(duration!(1)); + //~^ unchecked_time_subtraction + let _ = duration!(0) - duration!(1); + //~^ unchecked_time_subtraction +} diff --git a/tests/ui/unchecked_time_subtraction.stderr b/tests/ui/unchecked_time_subtraction.stderr index c129497447fc..fa4bd1db81ae 100644 --- a/tests/ui/unchecked_time_subtraction.stderr +++ b/tests/ui/unchecked_time_subtraction.stderr @@ -49,5 +49,29 @@ error: unchecked subtraction of a `Duration` LL | let _ = 2 * dur1 - dur2; | ^^^^^^^^^^^^^^^ help: try: `(2 * dur1).checked_sub(dur2).unwrap()` -error: aborting due to 8 previous errors +error: unchecked subtraction of a `Duration` + --> tests/ui/unchecked_time_subtraction.rs:42:5 + | +LL | Duration::ZERO.sub(Duration::MAX); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::ZERO.checked_sub(Duration::MAX).unwrap()` + +error: unchecked subtraction of a `Duration` + --> tests/ui/unchecked_time_subtraction.rs:45:13 + | +LL | let _ = Duration::ZERO - Duration::MAX; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::ZERO.checked_sub(Duration::MAX).unwrap()` + +error: unchecked subtraction of a `Duration` + --> tests/ui/unchecked_time_subtraction.rs:58:5 + | +LL | duration!(0).sub(duration!(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `duration!(0).checked_sub(duration!(1)).unwrap()` + +error: unchecked subtraction of a `Duration` + --> tests/ui/unchecked_time_subtraction.rs:60:13 + | +LL | let _ = duration!(0) - duration!(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `duration!(0).checked_sub(duration!(1)).unwrap()` + +error: aborting due to 12 previous errors diff --git a/tests/ui/unnecessary_fold.fixed b/tests/ui/unnecessary_fold.fixed index 1c331be75094..c3eeafbc39cd 100644 --- a/tests/ui/unnecessary_fold.fixed +++ b/tests/ui/unnecessary_fold.fixed @@ -6,21 +6,35 @@ fn is_any(acc: bool, x: usize) -> bool { /// Calls which should trigger the `UNNECESSARY_FOLD` lint fn unnecessary_fold() { + use std::ops::{Add, Mul}; + // Can be replaced by .any let _ = (0..3).any(|x| x > 2); //~^ unnecessary_fold + // Can be replaced by .any (checking suggestion) let _ = (0..3).fold(false, is_any); //~^ redundant_closure + // Can be replaced by .all let _ = (0..3).all(|x| x > 2); //~^ unnecessary_fold + // Can be replaced by .sum let _: i32 = (0..3).sum(); //~^ unnecessary_fold + let _: i32 = (0..3).sum(); + //~^ unnecessary_fold + let _: i32 = (0..3).sum(); + //~^ unnecessary_fold + // Can be replaced by .product let _: i32 = (0..3).product(); //~^ unnecessary_fold + let _: i32 = (0..3).product(); + //~^ unnecessary_fold + let _: i32 = (0..3).product(); + //~^ unnecessary_fold } /// Should trigger the `UNNECESSARY_FOLD` lint, with an error span including exactly `.fold(...)` @@ -37,6 +51,43 @@ fn unnecessary_fold_should_ignore() { let _ = (0..3).fold(0, |acc, x| acc * x); let _ = (0..3).fold(0, |acc, x| 1 + acc + x); + struct Adder; + impl Adder { + fn add(lhs: i32, rhs: i32) -> i32 { + unimplemented!() + } + fn mul(lhs: i32, rhs: i32) -> i32 { + unimplemented!() + } + } + // `add`/`mul` are inherent methods + let _: i32 = (0..3).fold(0, Adder::add); + let _: i32 = (0..3).fold(1, Adder::mul); + + trait FakeAdd { + type Output; + fn add(self, other: Rhs) -> Self::Output; + } + impl FakeAdd for i32 { + type Output = Self; + fn add(self, other: i32) -> Self::Output { + self + other + } + } + trait FakeMul { + type Output; + fn mul(self, other: Rhs) -> Self::Output; + } + impl FakeMul for i32 { + type Output = Self; + fn mul(self, other: i32) -> Self::Output { + self * other + } + } + // `add`/`mul` come from an unrelated trait + let _: i32 = (0..3).fold(0, FakeAdd::add); + let _: i32 = (0..3).fold(1, FakeMul::mul); + // We only match against an accumulator on the left // hand side. We could lint for .sum and .product when // it's on the right, but don't for now (and this wouldn't @@ -63,6 +114,7 @@ fn unnecessary_fold_over_multiple_lines() { fn issue10000() { use std::collections::HashMap; use std::hash::BuildHasher; + use std::ops::{Add, Mul}; fn anything(_: T) {} fn num(_: i32) {} @@ -74,23 +126,56 @@ fn issue10000() { // more cases: let _ = map.values().sum::(); //~^ unnecessary_fold + let _ = map.values().sum::(); + //~^ unnecessary_fold let _ = map.values().product::(); //~^ unnecessary_fold + let _ = map.values().product::(); + //~^ unnecessary_fold + let _: i32 = map.values().sum(); + //~^ unnecessary_fold let _: i32 = map.values().sum(); //~^ unnecessary_fold let _: i32 = map.values().product(); //~^ unnecessary_fold + let _: i32 = map.values().product(); + //~^ unnecessary_fold + anything(map.values().sum::()); + //~^ unnecessary_fold anything(map.values().sum::()); //~^ unnecessary_fold anything(map.values().product::()); //~^ unnecessary_fold + anything(map.values().product::()); + //~^ unnecessary_fold num(map.values().sum()); //~^ unnecessary_fold + num(map.values().sum()); + //~^ unnecessary_fold + num(map.values().product()); + //~^ unnecessary_fold num(map.values().product()); //~^ unnecessary_fold } smoketest_map(HashMap::new()); + + fn add_turbofish_not_necessary() -> i32 { + (0..3).sum() + //~^ unnecessary_fold + } + fn mul_turbofish_not_necessary() -> i32 { + (0..3).product() + //~^ unnecessary_fold + } + fn add_turbofish_necessary() -> impl Add { + (0..3).sum::() + //~^ unnecessary_fold + } + fn mul_turbofish_necessary() -> impl Mul { + (0..3).product::() + //~^ unnecessary_fold + } } fn main() {} diff --git a/tests/ui/unnecessary_fold.rs b/tests/ui/unnecessary_fold.rs index e2050e37e3b1..6ab41a942625 100644 --- a/tests/ui/unnecessary_fold.rs +++ b/tests/ui/unnecessary_fold.rs @@ -6,21 +6,35 @@ fn is_any(acc: bool, x: usize) -> bool { /// Calls which should trigger the `UNNECESSARY_FOLD` lint fn unnecessary_fold() { + use std::ops::{Add, Mul}; + // Can be replaced by .any let _ = (0..3).fold(false, |acc, x| acc || x > 2); //~^ unnecessary_fold + // Can be replaced by .any (checking suggestion) let _ = (0..3).fold(false, |acc, x| is_any(acc, x)); //~^ redundant_closure + // Can be replaced by .all let _ = (0..3).fold(true, |acc, x| acc && x > 2); //~^ unnecessary_fold + // Can be replaced by .sum let _: i32 = (0..3).fold(0, |acc, x| acc + x); //~^ unnecessary_fold + let _: i32 = (0..3).fold(0, Add::add); + //~^ unnecessary_fold + let _: i32 = (0..3).fold(0, i32::add); + //~^ unnecessary_fold + // Can be replaced by .product let _: i32 = (0..3).fold(1, |acc, x| acc * x); //~^ unnecessary_fold + let _: i32 = (0..3).fold(1, Mul::mul); + //~^ unnecessary_fold + let _: i32 = (0..3).fold(1, i32::mul); + //~^ unnecessary_fold } /// Should trigger the `UNNECESSARY_FOLD` lint, with an error span including exactly `.fold(...)` @@ -37,6 +51,43 @@ fn unnecessary_fold_should_ignore() { let _ = (0..3).fold(0, |acc, x| acc * x); let _ = (0..3).fold(0, |acc, x| 1 + acc + x); + struct Adder; + impl Adder { + fn add(lhs: i32, rhs: i32) -> i32 { + unimplemented!() + } + fn mul(lhs: i32, rhs: i32) -> i32 { + unimplemented!() + } + } + // `add`/`mul` are inherent methods + let _: i32 = (0..3).fold(0, Adder::add); + let _: i32 = (0..3).fold(1, Adder::mul); + + trait FakeAdd { + type Output; + fn add(self, other: Rhs) -> Self::Output; + } + impl FakeAdd for i32 { + type Output = Self; + fn add(self, other: i32) -> Self::Output { + self + other + } + } + trait FakeMul { + type Output; + fn mul(self, other: Rhs) -> Self::Output; + } + impl FakeMul for i32 { + type Output = Self; + fn mul(self, other: i32) -> Self::Output { + self * other + } + } + // `add`/`mul` come from an unrelated trait + let _: i32 = (0..3).fold(0, FakeAdd::add); + let _: i32 = (0..3).fold(1, FakeMul::mul); + // We only match against an accumulator on the left // hand side. We could lint for .sum and .product when // it's on the right, but don't for now (and this wouldn't @@ -63,6 +114,7 @@ fn unnecessary_fold_over_multiple_lines() { fn issue10000() { use std::collections::HashMap; use std::hash::BuildHasher; + use std::ops::{Add, Mul}; fn anything(_: T) {} fn num(_: i32) {} @@ -74,23 +126,56 @@ fn issue10000() { // more cases: let _ = map.values().fold(0, |x, y| x + y); //~^ unnecessary_fold + let _ = map.values().fold(0, Add::add); + //~^ unnecessary_fold let _ = map.values().fold(1, |x, y| x * y); //~^ unnecessary_fold + let _ = map.values().fold(1, Mul::mul); + //~^ unnecessary_fold let _: i32 = map.values().fold(0, |x, y| x + y); //~^ unnecessary_fold + let _: i32 = map.values().fold(0, Add::add); + //~^ unnecessary_fold let _: i32 = map.values().fold(1, |x, y| x * y); //~^ unnecessary_fold + let _: i32 = map.values().fold(1, Mul::mul); + //~^ unnecessary_fold anything(map.values().fold(0, |x, y| x + y)); //~^ unnecessary_fold + anything(map.values().fold(0, Add::add)); + //~^ unnecessary_fold anything(map.values().fold(1, |x, y| x * y)); //~^ unnecessary_fold + anything(map.values().fold(1, Mul::mul)); + //~^ unnecessary_fold num(map.values().fold(0, |x, y| x + y)); //~^ unnecessary_fold + num(map.values().fold(0, Add::add)); + //~^ unnecessary_fold num(map.values().fold(1, |x, y| x * y)); //~^ unnecessary_fold + num(map.values().fold(1, Mul::mul)); + //~^ unnecessary_fold } smoketest_map(HashMap::new()); + + fn add_turbofish_not_necessary() -> i32 { + (0..3).fold(0, |acc, x| acc + x) + //~^ unnecessary_fold + } + fn mul_turbofish_not_necessary() -> i32 { + (0..3).fold(1, |acc, x| acc * x) + //~^ unnecessary_fold + } + fn add_turbofish_necessary() -> impl Add { + (0..3).fold(0, |acc, x| acc + x) + //~^ unnecessary_fold + } + fn mul_turbofish_necessary() -> impl Mul { + (0..3).fold(1, |acc, x| acc * x) + //~^ unnecessary_fold + } } fn main() {} diff --git a/tests/ui/unnecessary_fold.stderr b/tests/ui/unnecessary_fold.stderr index d82b1f39b48b..bb8aa7e18d34 100644 --- a/tests/ui/unnecessary_fold.stderr +++ b/tests/ui/unnecessary_fold.stderr @@ -1,5 +1,5 @@ error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:10:20 + --> tests/ui/unnecessary_fold.rs:12:20 | LL | let _ = (0..3).fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` @@ -8,7 +8,7 @@ LL | let _ = (0..3).fold(false, |acc, x| acc || x > 2); = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fold)]` error: redundant closure - --> tests/ui/unnecessary_fold.rs:13:32 + --> tests/ui/unnecessary_fold.rs:16:32 | LL | let _ = (0..3).fold(false, |acc, x| is_any(acc, x)); | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `is_any` @@ -17,88 +17,184 @@ LL | let _ = (0..3).fold(false, |acc, x| is_any(acc, x)); = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:16:20 + --> tests/ui/unnecessary_fold.rs:20:20 | LL | let _ = (0..3).fold(true, |acc, x| acc && x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `all(|x| x > 2)` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:19:25 + --> tests/ui/unnecessary_fold.rs:24:25 | LL | let _: i32 = (0..3).fold(0, |acc, x| acc + x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:22:25 + --> tests/ui/unnecessary_fold.rs:26:25 + | +LL | let _: i32 = (0..3).fold(0, Add::add); + | ^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:28:25 + | +LL | let _: i32 = (0..3).fold(0, i32::add); + | ^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:32:25 | LL | let _: i32 = (0..3).fold(1, |acc, x| acc * x); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:28:41 + --> tests/ui/unnecessary_fold.rs:34:25 + | +LL | let _: i32 = (0..3).fold(1, Mul::mul); + | ^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:36:25 + | +LL | let _: i32 = (0..3).fold(1, i32::mul); + | ^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:42:41 | LL | let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:59:10 + --> tests/ui/unnecessary_fold.rs:110:10 | LL | .fold(false, |acc, x| acc || x > 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:71:33 + --> tests/ui/unnecessary_fold.rs:123:33 | LL | assert_eq!(map.values().fold(0, |x, y| x + y), 0); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:75:30 + --> tests/ui/unnecessary_fold.rs:127:30 | LL | let _ = map.values().fold(0, |x, y| x + y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:77:30 + --> tests/ui/unnecessary_fold.rs:129:30 + | +LL | let _ = map.values().fold(0, Add::add); + | ^^^^^^^^^^^^^^^^^ help: try: `sum::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:131:30 | LL | let _ = map.values().fold(1, |x, y| x * y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:79:35 + --> tests/ui/unnecessary_fold.rs:133:30 + | +LL | let _ = map.values().fold(1, Mul::mul); + | ^^^^^^^^^^^^^^^^^ help: try: `product::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:135:35 | LL | let _: i32 = map.values().fold(0, |x, y| x + y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:81:35 + --> tests/ui/unnecessary_fold.rs:137:35 + | +LL | let _: i32 = map.values().fold(0, Add::add); + | ^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:139:35 | LL | let _: i32 = map.values().fold(1, |x, y| x * y); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:83:31 + --> tests/ui/unnecessary_fold.rs:141:35 + | +LL | let _: i32 = map.values().fold(1, Mul::mul); + | ^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:143:31 | LL | anything(map.values().fold(0, |x, y| x + y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:85:31 + --> tests/ui/unnecessary_fold.rs:145:31 + | +LL | anything(map.values().fold(0, Add::add)); + | ^^^^^^^^^^^^^^^^^ help: try: `sum::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:147:31 | LL | anything(map.values().fold(1, |x, y| x * y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:87:26 + --> tests/ui/unnecessary_fold.rs:149:31 + | +LL | anything(map.values().fold(1, Mul::mul)); + | ^^^^^^^^^^^^^^^^^ help: try: `product::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:151:26 | LL | num(map.values().fold(0, |x, y| x + y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` error: this `.fold` can be written more succinctly using another method - --> tests/ui/unnecessary_fold.rs:89:26 + --> tests/ui/unnecessary_fold.rs:153:26 + | +LL | num(map.values().fold(0, Add::add)); + | ^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:155:26 | LL | num(map.values().fold(1, |x, y| x * y)); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` -error: aborting due to 16 previous errors +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:157:26 + | +LL | num(map.values().fold(1, Mul::mul)); + | ^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:164:16 + | +LL | (0..3).fold(0, |acc, x| acc + x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:168:16 + | +LL | (0..3).fold(1, |acc, x| acc * x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:172:16 + | +LL | (0..3).fold(0, |acc, x| acc + x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::()` + +error: this `.fold` can be written more succinctly using another method + --> tests/ui/unnecessary_fold.rs:176:16 + | +LL | (0..3).fold(1, |acc, x| acc * x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product::()` + +error: aborting due to 32 previous errors diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index 075e31d202b0..37559f9a2367 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -10,6 +10,9 @@ clippy::needless_lifetimes, clippy::missing_transmute_annotations )] +#![allow(incomplete_features)] +#![feature(adt_const_params)] +#![feature(unsized_const_params)] #[macro_use] extern crate proc_macro_derive; @@ -769,3 +772,25 @@ mod issue_13277 { type Item<'foo> = Option>; } } + +mod issue16164 { + trait Bits { + fn bit(self) -> bool; + } + + impl Bits for u8 { + fn bit(self) -> bool { + todo!() + } + } + + trait T { + fn f(self) -> bool; + } + + impl T for u8 { + fn f(self) -> bool { + todo!() + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 6fbba0bbc550..74abd2f61bf9 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -10,6 +10,9 @@ clippy::needless_lifetimes, clippy::missing_transmute_annotations )] +#![allow(incomplete_features)] +#![feature(adt_const_params)] +#![feature(unsized_const_params)] #[macro_use] extern crate proc_macro_derive; @@ -769,3 +772,25 @@ mod issue_13277 { type Item<'foo> = Option>; } } + +mod issue16164 { + trait Bits { + fn bit(self) -> bool; + } + + impl Bits for u8 { + fn bit(self) -> bool { + todo!() + } + } + + trait T { + fn f(self) -> bool; + } + + impl T for u8 { + fn f(self) -> bool { + todo!() + } + } +} diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index 5f65c53ea25c..8ce341d22d4f 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -1,5 +1,5 @@ error: unnecessary structure name repetition - --> tests/ui/use_self.rs:23:21 + --> tests/ui/use_self.rs:26:21 | LL | fn new() -> Foo { | ^^^ help: use the applicable keyword: `Self` @@ -8,247 +8,247 @@ LL | fn new() -> Foo { = help: to override `-D warnings` add `#[allow(clippy::use_self)]` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:25:13 + --> tests/ui/use_self.rs:28:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:28:22 + --> tests/ui/use_self.rs:31:22 | LL | fn test() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:30:13 + --> tests/ui/use_self.rs:33:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:36:25 + --> tests/ui/use_self.rs:39:25 | LL | fn default() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:38:13 + --> tests/ui/use_self.rs:41:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:80:28 + --> tests/ui/use_self.rs:83:28 | LL | fn clone(&self) -> Foo<'a> { | ^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:114:24 + --> tests/ui/use_self.rs:117:24 | LL | fn bad(foos: &[Foo]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:114:55 + --> tests/ui/use_self.rs:117:55 | LL | fn bad(foos: &[Foo]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:131:13 + --> tests/ui/use_self.rs:134:13 | LL | TS(0) | ^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:167:29 + --> tests/ui/use_self.rs:170:29 | LL | fn bar() -> Bar { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:169:21 + --> tests/ui/use_self.rs:172:21 | LL | Bar { foo: Foo {} } | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:181:21 + --> tests/ui/use_self.rs:184:21 | LL | fn baz() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:183:13 + --> tests/ui/use_self.rs:186:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:201:21 + --> tests/ui/use_self.rs:204:21 | LL | let _ = Enum::B(42); | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:203:21 + --> tests/ui/use_self.rs:206:21 | LL | let _ = Enum::C { field: true }; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:205:21 + --> tests/ui/use_self.rs:208:21 | LL | let _ = Enum::A; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:248:13 + --> tests/ui/use_self.rs:251:13 | LL | nested::A::fun_1(); | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:250:13 + --> tests/ui/use_self.rs:253:13 | LL | nested::A::A; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:253:13 + --> tests/ui/use_self.rs:256:13 | LL | nested::A {}; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:273:13 + --> tests/ui/use_self.rs:276:13 | LL | TestStruct::from_something() | ^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:288:25 + --> tests/ui/use_self.rs:291:25 | LL | async fn g() -> S { | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:290:13 + --> tests/ui/use_self.rs:293:13 | LL | S {} | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:295:16 + --> tests/ui/use_self.rs:298:16 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:295:22 + --> tests/ui/use_self.rs:298:22 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:320:29 + --> tests/ui/use_self.rs:323:29 | LL | fn foo(value: T) -> Foo { | ^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:322:13 + --> tests/ui/use_self.rs:325:13 | LL | Foo:: { value } | ^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:495:13 + --> tests/ui/use_self.rs:498:13 | LL | A::new::(submod::B {}) | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:571:17 + --> tests/ui/use_self.rs:574:17 | LL | Foo::Bar => unimplemented!(), | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:573:17 + --> tests/ui/use_self.rs:576:17 | LL | Foo::Baz => unimplemented!(), | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:580:20 + --> tests/ui/use_self.rs:583:20 | LL | if let Foo::Bar = self { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:605:17 + --> tests/ui/use_self.rs:608:17 | LL | Something::Num(n) => *n, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:607:17 + --> tests/ui/use_self.rs:610:17 | LL | Something::TupleNums(n, _m) => *n, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:609:17 + --> tests/ui/use_self.rs:612:17 | LL | Something::StructNums { one, two: _ } => *one, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:616:17 + --> tests/ui/use_self.rs:619:17 | LL | crate::issue8845::Something::Num(n) => *n, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:618:17 + --> tests/ui/use_self.rs:621:17 | LL | crate::issue8845::Something::TupleNums(n, _m) => *n, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:620:17 + --> tests/ui/use_self.rs:623:17 | LL | crate::issue8845::Something::StructNums { one, two: _ } => *one, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:637:17 + --> tests/ui/use_self.rs:640:17 | LL | let Foo(x) = self; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:643:17 + --> tests/ui/use_self.rs:646:17 | LL | let crate::issue8845::Foo(x) = self; | ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:651:17 + --> tests/ui/use_self.rs:654:17 | LL | let Bar { x, .. } = self; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:657:17 + --> tests/ui/use_self.rs:660:17 | LL | let crate::issue8845::Bar { x, .. } = self; | ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:697:17 + --> tests/ui/use_self.rs:700:17 | LL | E::A => {}, | ^ help: use the applicable keyword: `Self` diff --git a/tests/ui/writeln_empty_string_unfixable.rs b/tests/ui/writeln_empty_string_unfixable.rs new file mode 100644 index 000000000000..ca570fd1fc7b --- /dev/null +++ b/tests/ui/writeln_empty_string_unfixable.rs @@ -0,0 +1,26 @@ +#![allow(unused_must_use)] +#![warn(clippy::writeln_empty_string)] + +use std::io::Write; + +// If there is a comment in the span of macro call, we don't provide an auto-fix suggestion. +#[rustfmt::skip] +fn issue_16251() { + let mut v = Vec::new(); + + writeln!(v, /* comment */ ""); + //~^ writeln_empty_string + + writeln!(v, "" /* comment */); + //~^ writeln_empty_string + + //~v writeln_empty_string + writeln!(v, + "\ + \ + " + + // there is a comment in the macro span regardless of its position + + ); +} diff --git a/tests/ui/writeln_empty_string_unfixable.stderr b/tests/ui/writeln_empty_string_unfixable.stderr new file mode 100644 index 000000000000..0ed802ba84ba --- /dev/null +++ b/tests/ui/writeln_empty_string_unfixable.stderr @@ -0,0 +1,47 @@ +error: empty string literal in `writeln!` + --> tests/ui/writeln_empty_string_unfixable.rs:11:5 + | +LL | writeln!(v, /* comment */ ""); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/writeln_empty_string_unfixable.rs:11:31 + | +LL | writeln!(v, /* comment */ ""); + | ^^ + = note: `-D clippy::writeln-empty-string` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::writeln_empty_string)]` + +error: empty string literal in `writeln!` + --> tests/ui/writeln_empty_string_unfixable.rs:14:5 + | +LL | writeln!(v, "" /* comment */); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: remove the empty string + --> tests/ui/writeln_empty_string_unfixable.rs:14:17 + | +LL | writeln!(v, "" /* comment */); + | ^^ + +error: empty string literal in `writeln!` + --> tests/ui/writeln_empty_string_unfixable.rs:18:5 + | +LL | / writeln!(v, +LL | | "\ +LL | | \ +LL | | " +... | +LL | | ); + | |_____^ + | +note: remove the empty string + --> tests/ui/writeln_empty_string_unfixable.rs:19:9 + | +LL | / "\ +LL | | \ +LL | | " + | |_____________^ + +error: aborting due to 3 previous errors + diff --git a/triagebot.toml b/triagebot.toml index 09dec7675e7e..5f637205fa65 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -63,6 +63,7 @@ users_on_vacation = [ "Alexendoo", "y21", "blyxyas", + "samueltardieu", ] [assign.owners] From b04a3dce20881d4e846289f5cf34febcaf04a29f Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 25 Dec 2025 23:25:04 +0100 Subject: [PATCH 1243/3801] Update Cargo.lock --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 870259429742..9e4b2915feff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -666,6 +666,7 @@ dependencies = [ "indoc", "itertools", "opener", + "rustc-literal-escaper", "walkdir", ] From 70d8c6163b81d354b2ee8fcf1fc54aa11e358085 Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Thu, 25 Dec 2025 13:04:23 +0000 Subject: [PATCH 1244/3801] implement shellcheck --- src/tools/tidy/src/extra_checks/mod.rs | 21 ++++++++++++++++--- src/tools/tidy/src/extra_checks/rustdoc_js.rs | 5 +++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index 1304de16874d..1997adeda6f1 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -595,10 +595,9 @@ fn install_requirements( Ok(()) } -/// Check that shellcheck is installed then run it at the given path -fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> { +fn has_shellcheck() -> Result<(), Error> { match Command::new("shellcheck").arg("--version").status() { - Ok(_) => (), + Ok(_) => Ok(()), Err(e) if e.kind() == io::ErrorKind::NotFound => { return Err(Error::MissingReq( "shellcheck", @@ -612,6 +611,13 @@ fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> { } Err(e) => return Err(e.into()), } +} + +/// Check that shellcheck is installed then run it at the given path +fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> { + if let Err(err) = has_shellcheck() { + return Err(err); + } let status = Command::new("shellcheck").args(args).status()?; if status.success() { Ok(()) } else { Err(Error::FailedCheck("shellcheck")) } @@ -772,6 +778,15 @@ impl ExtraCheckArg { ExtraCheckLang::Spellcheck => { ensure_version(build_dir, "typos", SPELLCHECK_VER).is_ok() } + ExtraCheckLang::Shell => { + has_shellcheck().is_ok() + } + ExtraCheckLang::Js => { + // implement detailed check + rustdoc_js::has_tool(build_dir, "eslint") + && rustdoc_js::has_tool(build_dir, "jslint") + && rustdoc_js::has_tool(build_dir, "tsc") + } _ => todo!("implement other checks"), } } diff --git a/src/tools/tidy/src/extra_checks/rustdoc_js.rs b/src/tools/tidy/src/extra_checks/rustdoc_js.rs index 944d8a44112f..6ad5a6665071 100644 --- a/src/tools/tidy/src/extra_checks/rustdoc_js.rs +++ b/src/tools/tidy/src/extra_checks/rustdoc_js.rs @@ -21,6 +21,11 @@ fn spawn_cmd(cmd: &mut Command) -> Result { }) } +pub(super) fn has_tool(outdir: &Path, name: &str) -> bool { + let bin_path = node_module_bin(outdir, name); + Command::new(bin_path).arg("--version").status().is_ok() +} + /// install all js dependencies from package.json. pub(super) fn npm_install(root_path: &Path, outdir: &Path, npm: &Path) -> Result<(), super::Error> { npm::install(root_path, outdir, npm)?; From 258708fa6d1fc680ff06124cbf4455e3c3d83edd Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Thu, 25 Dec 2025 23:41:37 +0000 Subject: [PATCH 1245/3801] implement js check --- src/tools/tidy/src/extra_checks/mod.rs | 29 +++++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index 1997adeda6f1..5c83a12e1e5c 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -322,7 +322,7 @@ fn check_impl( } let res = spellcheck_runner(root_path, &outdir, &cargo, &args); if res.is_err() { - rerun_with_bless("spellcheck", "fix typos"); + rerun_with_bless("spellcheck", "fix typechecktypos"); } res?; } @@ -778,14 +778,27 @@ impl ExtraCheckArg { ExtraCheckLang::Spellcheck => { ensure_version(build_dir, "typos", SPELLCHECK_VER).is_ok() } - ExtraCheckLang::Shell => { - has_shellcheck().is_ok() - } + ExtraCheckLang::Shell => has_shellcheck().is_ok(), ExtraCheckLang::Js => { - // implement detailed check - rustdoc_js::has_tool(build_dir, "eslint") - && rustdoc_js::has_tool(build_dir, "jslint") - && rustdoc_js::has_tool(build_dir, "tsc") + match self.kind { + Some(ExtraCheckKind::Lint) => { + // If Lint is enabled, check both eslint and es-check. + rustdoc_js::has_tool(build_dir, "eslint") + && rustdoc_js::has_tool(build_dir, "es-check") + } + Some(ExtraCheckKind::Typecheck) => { + // If Typecheck is enabled, check tsc. + rustdoc_js::has_tool(build_dir, "tsc") + } + None => { + // No kind means it will check both Lint and Typecheck. + rustdoc_js::has_tool(build_dir, "eslint") + && rustdoc_js::has_tool(build_dir, "es-check") + && rustdoc_js::has_tool(build_dir, "tsc") + } + // Unreachable. + Some(_) => false, + } } _ => todo!("implement other checks"), } From a6b005a0c82c223c1f6c8e6d2d11f1f1a211a703 Mon Sep 17 00:00:00 2001 From: andjsrk Date: Fri, 26 Dec 2025 10:12:18 +0900 Subject: [PATCH 1246/3801] fix `Expr::can_have_side_effects` for repeat and binary expressions --- compiler/rustc_hir/src/hir.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e176c703b33e..0898afef47e5 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2618,6 +2618,12 @@ impl Expr<'_> { // them being used only for its side-effects. base.can_have_side_effects() } + ExprKind::Binary(_, lhs, rhs) => { + // This isn't exactly true for all `Binary`, but we are using this + // method exclusively for diagnostics and there's a *cultural* pressure against + // them being used only for its side-effects. + lhs.can_have_side_effects() || rhs.can_have_side_effects() + } ExprKind::Struct(_, fields, init) => { let init_side_effects = match init { StructTailExpr::Base(init) => init.can_have_side_effects(), @@ -2640,13 +2646,13 @@ impl Expr<'_> { }, args, ) => args.iter().any(|arg| arg.can_have_side_effects()), + ExprKind::Repeat(arg, _) => arg.can_have_side_effects(), ExprKind::If(..) | ExprKind::Match(..) | ExprKind::MethodCall(..) | ExprKind::Call(..) | ExprKind::Closure { .. } | ExprKind::Block(..) - | ExprKind::Repeat(..) | ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) @@ -2657,7 +2663,6 @@ impl Expr<'_> { | ExprKind::InlineAsm(..) | ExprKind::AssignOp(..) | ExprKind::ConstBlock(..) - | ExprKind::Binary(..) | ExprKind::Yield(..) | ExprKind::DropTemps(..) | ExprKind::Err(_) => true, From ec9174248dbcd6bbce4512b6455c99aa714e3c1c Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 22 Dec 2025 03:20:08 +0100 Subject: [PATCH 1247/3801] Fix `multiple_inherent_impl` false negatives for generic impl blocks --- clippy_lints/src/inherent_impl.rs | 23 +++++--- tests/ui/impl.rs | 42 +++++++++++++-- tests/ui/impl.stderr | 90 ++++++++++++++++++++++++++++--- 3 files changed, 138 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs index f59c7615d745..14928a1be13b 100644 --- a/clippy_lints/src/inherent_impl.rs +++ b/clippy_lints/src/inherent_impl.rs @@ -101,7 +101,21 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { InherentImplLintScope::Crate => Criterion::Crate, }; let is_test = is_cfg_test(cx.tcx, hir_id) || is_in_cfg_test(cx.tcx, hir_id); - match type_map.entry((impl_ty, criterion, is_test)) { + let predicates = { + // Gets the predicates (bounds) for the given impl block, + // sorted for consistent comparison to allow distinguishing between impl blocks + // with different generic bounds. + let mut predicates = cx + .tcx + .predicates_of(impl_id) + .predicates + .iter() + .map(|(clause, _)| *clause) + .collect::>(); + predicates.sort_by_key(|c| format!("{c:?}")); + predicates + }; + match type_map.entry((impl_ty, predicates, criterion, is_test)) { Entry::Vacant(e) => { // Store the id for the first impl block of this type. The span is retrieved lazily. e.insert(IdOrSpan::Id(impl_id)); @@ -152,15 +166,12 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { fn get_impl_span(cx: &LateContext<'_>, id: LocalDefId) -> Option { let id = cx.tcx.local_def_id_to_hir_id(id); if let Node::Item(&Item { - kind: ItemKind::Impl(impl_item), + kind: ItemKind::Impl(_), span, .. }) = cx.tcx.hir_node(id) { - (!span.from_expansion() - && impl_item.generics.params.is_empty() - && !fulfill_or_allowed(cx, MULTIPLE_INHERENT_IMPL, [id])) - .then_some(span) + (!span.from_expansion() && !fulfill_or_allowed(cx, MULTIPLE_INHERENT_IMPL, [id])).then_some(span) } else { None } diff --git a/tests/ui/impl.rs b/tests/ui/impl.rs index e6044cc50781..75761a34c86e 100644 --- a/tests/ui/impl.rs +++ b/tests/ui/impl.rs @@ -14,6 +14,7 @@ impl MyStruct { } impl<'a> MyStruct { + //~^ multiple_inherent_impl fn lifetimed() {} } @@ -90,10 +91,12 @@ struct Lifetime<'s> { } impl Lifetime<'_> {} -impl Lifetime<'_> {} // false negative +impl Lifetime<'_> {} +//~^ multiple_inherent_impl impl<'a> Lifetime<'a> {} -impl<'a> Lifetime<'a> {} // false negative +impl<'a> Lifetime<'a> {} +//~^ multiple_inherent_impl impl<'b> Lifetime<'b> {} // false negative? @@ -104,6 +107,39 @@ struct Generic { } impl Generic {} -impl Generic {} // false negative +impl Generic {} +//~^ multiple_inherent_impl + +use std::fmt::Debug; + +#[derive(Debug)] +struct GenericWithBounds(T); + +impl GenericWithBounds { + fn make_one(_one: T) -> Self { + todo!() + } +} + +impl GenericWithBounds { + //~^ multiple_inherent_impl + fn make_two(_two: T) -> Self { + todo!() + } +} + +struct MultipleTraitBounds(T); + +impl MultipleTraitBounds { + fn debug_fn() {} +} + +impl MultipleTraitBounds { + fn clone_fn() {} +} + +impl MultipleTraitBounds { + fn debug_clone_fn() {} +} fn main() {} diff --git a/tests/ui/impl.stderr b/tests/ui/impl.stderr index 93d4b3998f90..9c4aaf183d70 100644 --- a/tests/ui/impl.stderr +++ b/tests/ui/impl.stderr @@ -19,7 +19,24 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::multiple_inherent_impl)]` error: multiple implementations of this structure - --> tests/ui/impl.rs:26:5 + --> tests/ui/impl.rs:16:1 + | +LL | / impl<'a> MyStruct { +LL | | +LL | | fn lifetimed() {} +LL | | } + | |_^ + | +note: first implementation here + --> tests/ui/impl.rs:6:1 + | +LL | / impl MyStruct { +LL | | fn first() {} +LL | | } + | |_^ + +error: multiple implementations of this structure + --> tests/ui/impl.rs:27:5 | LL | / impl super::MyStruct { LL | | @@ -37,7 +54,7 @@ LL | | } | |_^ error: multiple implementations of this structure - --> tests/ui/impl.rs:48:1 + --> tests/ui/impl.rs:49:1 | LL | / impl WithArgs { LL | | @@ -47,7 +64,7 @@ LL | | } | |_^ | note: first implementation here - --> tests/ui/impl.rs:45:1 + --> tests/ui/impl.rs:46:1 | LL | / impl WithArgs { LL | | fn f2() {} @@ -55,28 +72,85 @@ LL | | } | |_^ error: multiple implementations of this structure - --> tests/ui/impl.rs:71:1 + --> tests/ui/impl.rs:72:1 | LL | impl OneAllowedImpl {} | ^^^^^^^^^^^^^^^^^^^^^^ | note: first implementation here - --> tests/ui/impl.rs:68:1 + --> tests/ui/impl.rs:69:1 | LL | impl OneAllowedImpl {} | ^^^^^^^^^^^^^^^^^^^^^^ error: multiple implementations of this structure - --> tests/ui/impl.rs:84:1 + --> tests/ui/impl.rs:85:1 | LL | impl OneExpected {} | ^^^^^^^^^^^^^^^^^^^ | note: first implementation here - --> tests/ui/impl.rs:81:1 + --> tests/ui/impl.rs:82:1 | LL | impl OneExpected {} | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: multiple implementations of this structure + --> tests/ui/impl.rs:94:1 + | +LL | impl Lifetime<'_> {} + | ^^^^^^^^^^^^^^^^^^^^ + | +note: first implementation here + --> tests/ui/impl.rs:93:1 + | +LL | impl Lifetime<'_> {} + | ^^^^^^^^^^^^^^^^^^^^ + +error: multiple implementations of this structure + --> tests/ui/impl.rs:98:1 + | +LL | impl<'a> Lifetime<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first implementation here + --> tests/ui/impl.rs:97:1 + | +LL | impl<'a> Lifetime<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: multiple implementations of this structure + --> tests/ui/impl.rs:110:1 + | +LL | impl Generic {} + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: first implementation here + --> tests/ui/impl.rs:109:1 + | +LL | impl Generic {} + | ^^^^^^^^^^^^^^^^^^^^^ + +error: multiple implementations of this structure + --> tests/ui/impl.rs:124:1 + | +LL | / impl GenericWithBounds { +LL | | +LL | | fn make_two(_two: T) -> Self { +LL | | todo!() +LL | | } +LL | | } + | |_^ + | +note: first implementation here + --> tests/ui/impl.rs:118:1 + | +LL | / impl GenericWithBounds { +LL | | fn make_one(_one: T) -> Self { +LL | | todo!() +LL | | } +LL | | } + | |_^ + +error: aborting due to 10 previous errors From e12e19d98c1206f44dbf1ade6debf53f15f9ad66 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 26 Dec 2025 03:44:09 +0100 Subject: [PATCH 1248/3801] fix double_parens FP on macro repetition patterns --- clippy_lints/src/double_parens.rs | 2 ++ tests/ui/double_parens.fixed | 16 ++++++++++++++++ tests/ui/double_parens.rs | 16 ++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/clippy_lints/src/double_parens.rs b/clippy_lints/src/double_parens.rs index 8defbeeaa5f2..351d29d87432 100644 --- a/clippy_lints/src/double_parens.rs +++ b/clippy_lints/src/double_parens.rs @@ -114,6 +114,8 @@ fn check_source(cx: &EarlyContext<'_>, inner: &Expr) -> bool { && inner.starts_with('(') && inner.ends_with(')') && outer_after_inner.trim_start().starts_with(')') + // Don't lint macro repetition patterns like `($($result),*)` where parens are necessary + && !inner.trim_start_matches('(').trim_start().starts_with("$(") { true } else { diff --git a/tests/ui/double_parens.fixed b/tests/ui/double_parens.fixed index 024af6840132..ef7838491f8f 100644 --- a/tests/ui/double_parens.fixed +++ b/tests/ui/double_parens.fixed @@ -161,4 +161,20 @@ fn issue15940() { pub struct Person; } +fn issue16224() { + fn test() -> i32 { 42 } + + macro_rules! call { + ($matcher:pat $(=> $result:expr)?) => { + match test() { + $matcher => Result::Ok(($($result),*)), + _ => Result::Err("No match".to_string()), + } + }; + } + + let _: Result<(), String> = call!(_); + let _: Result = call!(_ => 42); +} + fn main() {} diff --git a/tests/ui/double_parens.rs b/tests/ui/double_parens.rs index 8a76f2837f35..07eafdf69575 100644 --- a/tests/ui/double_parens.rs +++ b/tests/ui/double_parens.rs @@ -161,4 +161,20 @@ fn issue15940() { pub struct Person; } +fn issue16224() { + fn test() -> i32 { 42 } + + macro_rules! call { + ($matcher:pat $(=> $result:expr)?) => { + match test() { + $matcher => Result::Ok(($($result),*)), + _ => Result::Err("No match".to_string()), + } + }; + } + + let _: Result<(), String> = call!(_); + let _: Result = call!(_ => 42); +} + fn main() {} From 4d43e7808292a687716bfd64c5e90b9862e5ab85 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Oct 2025 09:25:24 +0200 Subject: [PATCH 1249/3801] Add `dead-code/unused-fn-with-check-pass` UI test --- tests/ui/lint/dead-code/unused-fn-with-check-pass.rs | 8 ++++++++ .../lint/dead-code/unused-fn-with-check-pass.stderr | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/ui/lint/dead-code/unused-fn-with-check-pass.rs create mode 100644 tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr diff --git a/tests/ui/lint/dead-code/unused-fn-with-check-pass.rs b/tests/ui/lint/dead-code/unused-fn-with-check-pass.rs new file mode 100644 index 000000000000..a4853e125a1a --- /dev/null +++ b/tests/ui/lint/dead-code/unused-fn-with-check-pass.rs @@ -0,0 +1,8 @@ +//@ check-pass +//@ compile-flags: -Wunused + +fn foo() -> &'static str { //~ WARN function `foo` is never used + "hello" +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr b/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr new file mode 100644 index 000000000000..0c95c40e5122 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr @@ -0,0 +1,11 @@ +warning: function `foo` is never used + --> $DIR/unused-fn-with-check-pass.rs:4:4 + | +LL | fn foo() -> &'static str { + | ^^^ + | + = note: `-W dead-code` implied by `-W unused` + = help: to override `-W unused` add `#[allow(dead_code)]` + +warning: 1 warning emitted + From d81ff8588cd06e3e10000b4fedd1101175cbe561 Mon Sep 17 00:00:00 2001 From: Redddy Date: Fri, 26 Dec 2025 16:34:49 +0900 Subject: [PATCH 1250/3801] Update links in compiler/rustc_hir_analysis/README.md for type checking --- compiler/rustc_hir_analysis/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/README.md b/compiler/rustc_hir_analysis/README.md index b61dbd8c9648..c47271dbdf2b 100644 --- a/compiler/rustc_hir_analysis/README.md +++ b/compiler/rustc_hir_analysis/README.md @@ -1,5 +1,5 @@ For high-level intro to how type checking works in rustc, see the -[type checking] chapter of the [rustc dev guide]. +[hir typeck] chapter of the [rustc dev guide]. -[type checking]: https://rustc-dev-guide.rust-lang.org/type-checking.html +[hir typeck]: https://rustc-dev-guide.rust-lang.org/hir-typeck/summary.html [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ From 2f3a23c7e9250d87b7d0013f841de3e9cf03d6f2 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 26 Dec 2025 09:35:55 +0200 Subject: [PATCH 1251/3801] =?UTF-8?q?Stabilize=20type=20mismatch=20diagnos?= =?UTF-8?q?tic=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crates/ide-diagnostics/src/handlers/type_mismatch.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs index e6702ccf1399..f443dc08f5fd 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -52,6 +52,7 @@ pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch< ), display_range, ) + .stable() .with_fixes(fixes(ctx, d)) } From 86cef2ff98bfd4aed625cb11229bf9ea70163bb5 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Wed, 15 Oct 2025 09:36:04 +0200 Subject: [PATCH 1252/3801] compiler/middle/lint: Suggest `#[expect(dead_code)]` as alternative to `#[allow(dead_code)]` --- compiler/rustc_middle/src/lint.rs | 13 ++++++++++--- .../ui/derives/derive-debug-uninhabited-enum.stderr | 2 +- .../lint/dead-code/unused-fn-with-check-pass.stderr | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index bed902e8334b..e4715f6e2c10 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -265,9 +265,16 @@ fn explain_lint_level_source( "`{flag} {hyphen_case_lint_name}` implied by `{flag} {hyphen_case_flag_val}`" )); if matches!(orig_level, Level::Warn | Level::Deny) { - err.help_once(format!( - "to override `{flag} {hyphen_case_flag_val}` add `#[allow({name})]`" - )); + let help = if name == "dead_code" { + format!( + "to override `{flag} {hyphen_case_flag_val}` add `#[expect({name})]` or `#[allow({name})]`" + ) + } else { + format!( + "to override `{flag} {hyphen_case_flag_val}` add `#[allow({name})]`" + ) + }; + err.help_once(help); } } } diff --git a/tests/ui/derives/derive-debug-uninhabited-enum.stderr b/tests/ui/derives/derive-debug-uninhabited-enum.stderr index 4911b6b6cded..90f4d34b1c5c 100644 --- a/tests/ui/derives/derive-debug-uninhabited-enum.stderr +++ b/tests/ui/derives/derive-debug-uninhabited-enum.stderr @@ -9,7 +9,7 @@ LL | Void(Void), | = note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis = note: `-W dead-code` implied by `-W unused` - = help: to override `-W unused` add `#[allow(dead_code)]` + = help: to override `-W unused` add `#[expect(dead_code)]` or `#[allow(dead_code)]` warning: 1 warning emitted diff --git a/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr b/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr index 0c95c40e5122..add938553563 100644 --- a/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr +++ b/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr @@ -5,7 +5,7 @@ LL | fn foo() -> &'static str { | ^^^ | = note: `-W dead-code` implied by `-W unused` - = help: to override `-W unused` add `#[allow(dead_code)]` + = help: to override `-W unused` add `#[expect(dead_code)]` or `#[allow(dead_code)]` warning: 1 warning emitted From 6f06d386b82295b3e19d5bdfb559611b052d03ef Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 26 Dec 2025 08:46:49 +0100 Subject: [PATCH 1253/3801] cpuid is safe since the stdarch sync, so remove unsafe from usages --- .../libm/src/math/arch/x86/detect.rs | 12 +++++----- library/std/src/sys/pal/uefi/time.rs | 4 ++-- library/std/src/sys/random/uefi.rs | 4 ++-- library/std_detect/src/detect/os/x86.rs | 23 +++++++++---------- .../src/bin/log/tracing_chrome_instant.rs | 2 +- .../tests/source/cfg_if/detect/os/x86.rs | 10 ++++---- .../tests/target/cfg_if/detect/os/x86.rs | 10 ++++---- 7 files changed, 32 insertions(+), 33 deletions(-) diff --git a/library/compiler-builtins/libm/src/math/arch/x86/detect.rs b/library/compiler-builtins/libm/src/math/arch/x86/detect.rs index e6d9b040bfaf..5391a68228ed 100644 --- a/library/compiler-builtins/libm/src/math/arch/x86/detect.rs +++ b/library/compiler-builtins/libm/src/math/arch/x86/detect.rs @@ -57,7 +57,7 @@ fn load_x86_features() -> Flags { // (in that order) let mut vendor_id = [0u8; 12]; let max_basic_leaf; - unsafe { + { let CpuidResult { eax, ebx, ecx, edx } = __cpuid(0); max_basic_leaf = eax; vendor_id[0..4].copy_from_slice(&ebx.to_ne_bytes()); @@ -72,7 +72,7 @@ fn load_x86_features() -> Flags { // EAX = 1, ECX = 0: Queries "Processor Info and Feature Bits"; // Contains information about most x86 features. - let CpuidResult { ecx, edx, .. } = unsafe { __cpuid(0x0000_0001_u32) }; + let CpuidResult { ecx, edx, .. } = __cpuid(0x0000_0001_u32); let proc_info_ecx = Flags::from_bits(ecx); let proc_info_edx = Flags::from_bits(edx); @@ -82,23 +82,23 @@ fn load_x86_features() -> Flags { let mut extended_features_edx = Flags::empty(); let mut extended_features_eax_leaf_1 = Flags::empty(); if max_basic_leaf >= 7 { - let CpuidResult { ebx, edx, .. } = unsafe { __cpuid(0x0000_0007_u32) }; + let CpuidResult { ebx, edx, .. } = __cpuid(0x0000_0007_u32); extended_features_ebx = Flags::from_bits(ebx); extended_features_edx = Flags::from_bits(edx); - let CpuidResult { eax, .. } = unsafe { __cpuid_count(0x0000_0007_u32, 0x0000_0001_u32) }; + let CpuidResult { eax, .. } = __cpuid_count(0x0000_0007_u32, 0x0000_0001_u32); extended_features_eax_leaf_1 = Flags::from_bits(eax) } // EAX = 0x8000_0000, ECX = 0: Get Highest Extended Function Supported // - EAX returns the max leaf value for extended information, that is, // `cpuid` calls in range [0x8000_0000; u32::MAX]: - let extended_max_basic_leaf = unsafe { __cpuid(0x8000_0000_u32) }.eax; + let extended_max_basic_leaf = __cpuid(0x8000_0000_u32).eax; // EAX = 0x8000_0001, ECX=0: Queries "Extended Processor Info and Feature Bits" let mut extended_proc_info_ecx = Flags::empty(); if extended_max_basic_leaf >= 1 { - let CpuidResult { ecx, .. } = unsafe { __cpuid(0x8000_0001_u32) }; + let CpuidResult { ecx, .. } = __cpuid(0x8000_0001_u32); extended_proc_info_ecx = Flags::from_bits(ecx); } diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs index 861b98da18da..06809dc5bac4 100644 --- a/library/std/src/sys/pal/uefi/time.rs +++ b/library/std/src/sys/pal/uefi/time.rs @@ -297,7 +297,7 @@ pub(crate) mod instant_internal { // Inspired by [`edk2/UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c`](https://github.com/tianocore/edk2/blob/master/UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c) let freq = FREQUENCY .get_or_try_init(|| { - let cpuid = unsafe { crate::arch::x86_64::__cpuid(0x15) }; + let cpuid = crate::arch::x86_64::__cpuid(0x15); if cpuid.eax == 0 || cpuid.ebx == 0 || cpuid.ecx == 0 { return Err(()); } @@ -316,7 +316,7 @@ pub(crate) mod instant_internal { let freq = FREQUENCY .get_or_try_init(|| { - let cpuid = unsafe { crate::arch::x86::__cpuid(0x15) }; + let cpuid = crate::arch::x86::__cpuid(0x15); if cpuid.eax == 0 || cpuid.ebx == 0 || cpuid.ecx == 0 { return Err(()); } diff --git a/library/std/src/sys/random/uefi.rs b/library/std/src/sys/random/uefi.rs index 697933f197b7..f7a760083519 100644 --- a/library/std/src/sys/random/uefi.rs +++ b/library/std/src/sys/random/uefi.rs @@ -107,11 +107,11 @@ mod rdrand { { // SAFETY: All Rust x86 targets are new enough to have CPUID, and we // check that leaf 1 is supported before using it. - let cpuid0 = unsafe { arch::__cpuid(0) }; + let cpuid0 = arch::__cpuid(0); if cpuid0.eax < 1 { return false; } - let cpuid1 = unsafe { arch::__cpuid(1) }; + let cpuid1 = arch::__cpuid(1); let vendor_id = [cpuid0.ebx.to_le_bytes(), cpuid0.edx.to_le_bytes(), cpuid0.ecx.to_le_bytes()]; diff --git a/library/std_detect/src/detect/os/x86.rs b/library/std_detect/src/detect/os/x86.rs index 18925da2b275..f2205ba07dd4 100644 --- a/library/std_detect/src/detect/os/x86.rs +++ b/library/std_detect/src/detect/os/x86.rs @@ -40,10 +40,10 @@ pub(crate) fn detect_features() -> cache::Initializer { // leaf value for subsequent calls of `cpuinfo` in range [0, // 0x8000_0000]. - The vendor ID is stored in 12 u8 ascii chars, // returned in EBX, EDX, and ECX (in that order): - let (max_basic_leaf, vendor_id) = unsafe { + let (max_basic_leaf, vendor_id) = { let CpuidResult { eax: max_basic_leaf, ebx, ecx, edx } = __cpuid(0); let vendor_id: [[u8; 4]; 3] = [ebx.to_ne_bytes(), edx.to_ne_bytes(), ecx.to_ne_bytes()]; - let vendor_id: [u8; 12] = mem::transmute(vendor_id); + let vendor_id: [u8; 12] = unsafe { mem::transmute(vendor_id) }; (max_basic_leaf, vendor_id) }; @@ -54,8 +54,7 @@ pub(crate) fn detect_features() -> cache::Initializer { // EAX = 1, ECX = 0: Queries "Processor Info and Feature Bits"; // Contains information about most x86 features. - let CpuidResult { ecx: proc_info_ecx, edx: proc_info_edx, .. } = - unsafe { __cpuid(0x0000_0001_u32) }; + let CpuidResult { ecx: proc_info_ecx, edx: proc_info_edx, .. } = __cpuid(0x0000_0001_u32); // EAX = 7: Queries "Extended Features"; // Contains information about bmi,bmi2, and avx2 support. @@ -66,9 +65,9 @@ pub(crate) fn detect_features() -> cache::Initializer { extended_features_eax_leaf_1, extended_features_edx_leaf_1, ) = if max_basic_leaf >= 7 { - let CpuidResult { ebx, ecx, edx, .. } = unsafe { __cpuid(0x0000_0007_u32) }; + let CpuidResult { ebx, ecx, edx, .. } = __cpuid(0x0000_0007_u32); let CpuidResult { eax: eax_1, edx: edx_1, .. } = - unsafe { __cpuid_count(0x0000_0007_u32, 0x0000_0001_u32) }; + __cpuid_count(0x0000_0007_u32, 0x0000_0001_u32); (ebx, ecx, edx, eax_1, edx_1) } else { (0, 0, 0, 0, 0) // CPUID does not support "Extended Features" @@ -77,12 +76,12 @@ pub(crate) fn detect_features() -> cache::Initializer { // EAX = 0x8000_0000, ECX = 0: Get Highest Extended Function Supported // - EAX returns the max leaf value for extended information, that is, // `cpuid` calls in range [0x8000_0000; u32::MAX]: - let CpuidResult { eax: extended_max_basic_leaf, .. } = unsafe { __cpuid(0x8000_0000_u32) }; + let CpuidResult { eax: extended_max_basic_leaf, .. } = __cpuid(0x8000_0000_u32); // EAX = 0x8000_0001, ECX=0: Queries "Extended Processor Info and Feature // Bits" let extended_proc_info_ecx = if extended_max_basic_leaf >= 1 { - let CpuidResult { ecx, .. } = unsafe { __cpuid(0x8000_0001_u32) }; + let CpuidResult { ecx, .. } = __cpuid(0x8000_0001_u32); ecx } else { 0 @@ -132,7 +131,7 @@ pub(crate) fn detect_features() -> cache::Initializer { // Detect if CPUID.19h available if bit::test(extended_features_ecx as usize, 23) { - let CpuidResult { ebx, .. } = unsafe { __cpuid(0x19) }; + let CpuidResult { ebx, .. } = __cpuid(0x19); enable(ebx, 0, Feature::kl); enable(ebx, 2, Feature::widekl); } @@ -223,7 +222,7 @@ pub(crate) fn detect_features() -> cache::Initializer { // ECX = 1): if max_basic_leaf >= 0xd { let CpuidResult { eax: proc_extended_state1_eax, .. } = - unsafe { __cpuid_count(0xd_u32, 1) }; + __cpuid_count(0xd_u32, 1); enable(proc_extended_state1_eax, 0, Feature::xsaveopt); enable(proc_extended_state1_eax, 1, Feature::xsavec); enable(proc_extended_state1_eax, 3, Feature::xsaves); @@ -282,7 +281,7 @@ pub(crate) fn detect_features() -> cache::Initializer { if max_basic_leaf >= 0x1e { let CpuidResult { eax: amx_feature_flags_eax, .. } = - unsafe { __cpuid_count(0x1e_u32, 1) }; + __cpuid_count(0x1e_u32, 1); enable(amx_feature_flags_eax, 4, Feature::amx_fp8); enable(amx_feature_flags_eax, 6, Feature::amx_tf32); @@ -297,7 +296,7 @@ pub(crate) fn detect_features() -> cache::Initializer { let avx10_1 = enable(extended_features_edx_leaf_1, 19, Feature::avx10_1); if avx10_1 { - let CpuidResult { ebx, .. } = unsafe { __cpuid(0x24) }; + let CpuidResult { ebx, .. } = __cpuid(0x24); let avx10_version = ebx & 0xff; if avx10_version >= 2 { value.set(Feature::avx10_2 as u32); diff --git a/src/tools/miri/src/bin/log/tracing_chrome_instant.rs b/src/tools/miri/src/bin/log/tracing_chrome_instant.rs index f400bc20a7b5..b5f00852b82f 100644 --- a/src/tools/miri/src/bin/log/tracing_chrome_instant.rs +++ b/src/tools/miri/src/bin/log/tracing_chrome_instant.rs @@ -151,7 +151,7 @@ mod tsc { // implemented like https://docs.rs/raw-cpuid/latest/src/raw_cpuid/extended.rs.html#965-967 const LEAF: u32 = 0x80000007; // this is the leaf for "advanced power management info" - let cpuid = unsafe { __cpuid(LEAF) }; + let cpuid = __cpuid(LEAF); (cpuid.edx & (1 << 8)) != 0 // EDX bit 8 indicates invariant TSC } diff --git a/src/tools/rustfmt/tests/source/cfg_if/detect/os/x86.rs b/src/tools/rustfmt/tests/source/cfg_if/detect/os/x86.rs index b9adc67221ae..8b45a5bbd269 100644 --- a/src/tools/rustfmt/tests/source/cfg_if/detect/os/x86.rs +++ b/src/tools/rustfmt/tests/source/cfg_if/detect/os/x86.rs @@ -66,13 +66,13 @@ fn detect_features() -> cache::Initializer { ecx: proc_info_ecx, edx: proc_info_edx, .. - } = unsafe { __cpuid(0x0000_0001_u32) }; + } = __cpuid(0x0000_0001_u32); // EAX = 7, ECX = 0: Queries "Extended Features"; // Contains information about bmi,bmi2, and avx2 support. let (extended_features_ebx, extended_features_ecx) = if max_basic_leaf >= 7 { - let CpuidResult { ebx, ecx, .. } = unsafe { __cpuid(0x0000_0007_u32) }; + let CpuidResult { ebx, ecx, .. } = __cpuid(0x0000_0007_u32); (ebx, ecx) } else { (0, 0) // CPUID does not support "Extended Features" @@ -84,12 +84,12 @@ fn detect_features() -> cache::Initializer { let CpuidResult { eax: extended_max_basic_leaf, .. - } = unsafe { __cpuid(0x8000_0000_u32) }; + } = __cpuid(0x8000_0000_u32); // EAX = 0x8000_0001, ECX=0: Queries "Extended Processor Info and Feature // Bits" let extended_proc_info_ecx = if extended_max_basic_leaf >= 1 { - let CpuidResult { ecx, .. } = unsafe { __cpuid(0x8000_0001_u32) }; + let CpuidResult { ecx, .. } = __cpuid(0x8000_0001_u32); ecx } else { 0 @@ -182,7 +182,7 @@ fn detect_features() -> cache::Initializer { let CpuidResult { eax: proc_extended_state1_eax, .. - } = unsafe { __cpuid_count(0xd_u32, 1) }; + } = __cpuid_count(0xd_u32, 1); enable(proc_extended_state1_eax, 0, Feature::xsaveopt); enable(proc_extended_state1_eax, 1, Feature::xsavec); enable(proc_extended_state1_eax, 3, Feature::xsaves); diff --git a/src/tools/rustfmt/tests/target/cfg_if/detect/os/x86.rs b/src/tools/rustfmt/tests/target/cfg_if/detect/os/x86.rs index 944b51615f8e..fb7136d83911 100644 --- a/src/tools/rustfmt/tests/target/cfg_if/detect/os/x86.rs +++ b/src/tools/rustfmt/tests/target/cfg_if/detect/os/x86.rs @@ -66,12 +66,12 @@ fn detect_features() -> cache::Initializer { ecx: proc_info_ecx, edx: proc_info_edx, .. - } = unsafe { __cpuid(0x0000_0001_u32) }; + } = __cpuid(0x0000_0001_u32); // EAX = 7, ECX = 0: Queries "Extended Features"; // Contains information about bmi,bmi2, and avx2 support. let (extended_features_ebx, extended_features_ecx) = if max_basic_leaf >= 7 { - let CpuidResult { ebx, ecx, .. } = unsafe { __cpuid(0x0000_0007_u32) }; + let CpuidResult { ebx, ecx, .. } = __cpuid(0x0000_0007_u32); (ebx, ecx) } else { (0, 0) // CPUID does not support "Extended Features" @@ -83,12 +83,12 @@ fn detect_features() -> cache::Initializer { let CpuidResult { eax: extended_max_basic_leaf, .. - } = unsafe { __cpuid(0x8000_0000_u32) }; + } = __cpuid(0x8000_0000_u32); // EAX = 0x8000_0001, ECX=0: Queries "Extended Processor Info and Feature // Bits" let extended_proc_info_ecx = if extended_max_basic_leaf >= 1 { - let CpuidResult { ecx, .. } = unsafe { __cpuid(0x8000_0001_u32) }; + let CpuidResult { ecx, .. } = __cpuid(0x8000_0001_u32); ecx } else { 0 @@ -181,7 +181,7 @@ fn detect_features() -> cache::Initializer { let CpuidResult { eax: proc_extended_state1_eax, .. - } = unsafe { __cpuid_count(0xd_u32, 1) }; + } = __cpuid_count(0xd_u32, 1); enable(proc_extended_state1_eax, 0, Feature::xsaveopt); enable(proc_extended_state1_eax, 1, Feature::xsavec); enable(proc_extended_state1_eax, 3, Feature::xsaves); From a9442b4a2ab42d9456eef32990791297942fa780 Mon Sep 17 00:00:00 2001 From: Shinonn Date: Fri, 5 Dec 2025 11:02:17 +0700 Subject: [PATCH 1254/3801] Fix ICE by rejecting const blocks in patterns during AST lowering This fixes the ICE reported by rejecting `const` blocks in pattern position during AST lowering. Previously, `ExprKind::ConstBlock` could reach HIR as `PatExprKind::ConstBlock`, allowing invalid patterns to be type-checked and triggering an ICE. This patch removes the lowering path for const blocks in patterns and emits a proper diagnostic instead. A new UI test is added to ensure the compiler reports a regular error and to prevent regressions. --- compiler/rustc_ast_lowering/messages.ftl | 1 + compiler/rustc_ast_lowering/src/errors.rs | 2 + compiler/rustc_ast_lowering/src/pat.rs | 3 +- compiler/rustc_hir/src/hir.rs | 1 - compiler/rustc_hir/src/intravisit.rs | 1 - compiler/rustc_hir_pretty/src/lib.rs | 1 - compiler/rustc_hir_typeck/src/pat.rs | 3 - .../rustc_mir_build/src/thir/pattern/mod.rs | 52 +---------- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/mod.rs | 15 +--- compiler/rustc_parse/src/parser/pat.rs | 8 +- .../clippy/clippy_lints/src/utils/author.rs | 1 - src/tools/clippy/clippy_utils/src/consts.rs | 1 - .../clippy/clippy_utils/src/hir_utils.rs | 4 +- tests/ui/inline-const/in-pat-recovery.rs | 57 +++++++++++- tests/ui/inline-const/in-pat-recovery.stderr | 88 ++++++++++++++++++- ...djust-mode-unimplemented-for-constblock.rs | 10 +++ ...t-mode-unimplemented-for-constblock.stderr | 41 +++++++++ 18 files changed, 206 insertions(+), 85 deletions(-) create mode 100644 tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.rs create mode 100644 tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.stderr diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 370b15d2871a..8c7acf18ec42 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -6,6 +6,7 @@ ast_lowering_abi_specified_multiple_times = ast_lowering_arbitrary_expression_in_pattern = arbitrary expressions aren't allowed in patterns .pattern_from_macro_note = the `expr` fragment specifier forces the metavariable's content to be an expression + .const_block_in_pattern_help = use a named `const`-item or an `if`-guard (`x if x == const {"{ ... }"}`) instead ast_lowering_argument = argument diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 83f3a976e83f..79e2d74a8b5a 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -357,6 +357,8 @@ pub(crate) struct ArbitraryExpressionInPattern { pub span: Span, #[note(ast_lowering_pattern_from_macro_note)] pub pattern_from_macro_note: bool, + #[help(ast_lowering_const_block_in_pattern_help)] + pub const_block_in_pattern_help: bool, } #[derive(Diagnostic)] diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 3571fd652397..7a5d8d9847a1 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -399,7 +399,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ExprKind::Lit(lit) => { hir::PatExprKind::Lit { lit: self.lower_lit(lit, span), negated: false } } - ExprKind::ConstBlock(c) => hir::PatExprKind::ConstBlock(self.lower_const_block(c)), ExprKind::IncludedBytes(byte_sym) => hir::PatExprKind::Lit { lit: respan(span, LitKind::ByteStr(*byte_sym, StrStyle::Cooked)), negated: false, @@ -419,10 +418,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::PatExprKind::Lit { lit: self.lower_lit(lit, span), negated: true } } _ => { + let is_const_block = matches!(expr.kind, ExprKind::ConstBlock(_)); let pattern_from_macro = expr.is_approximately_pattern(); let guar = self.dcx().emit_err(ArbitraryExpressionInPattern { span, pattern_from_macro_note: pattern_from_macro, + const_block_in_pattern_help: is_const_block, }); err(guar) } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 77e86fdce38d..e5a646e3116d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1921,7 +1921,6 @@ pub enum PatExprKind<'hir> { // once instead of matching on unop neg expressions everywhere. negated: bool, }, - ConstBlock(ConstBlock), /// A path pattern for a unit struct/variant or a (maybe-associated) constant. Path(QPath<'hir>), } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 625766f8bd3d..b6a0591d2c63 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -789,7 +789,6 @@ pub fn walk_pat_expr<'v, V: Visitor<'v>>(visitor: &mut V, expr: &'v PatExpr<'v>) try_visit!(visitor.visit_id(*hir_id)); match kind { PatExprKind::Lit { lit, negated } => visitor.visit_lit(*hir_id, *lit, *negated), - PatExprKind::ConstBlock(c) => visitor.visit_inline_const(c), PatExprKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, *span), } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index b3b416955230..5db40615998f 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1876,7 +1876,6 @@ impl<'a> State<'a> { } self.print_literal(lit); } - hir::PatExprKind::ConstBlock(c) => self.print_inline_const(c), hir::PatExprKind::Path(qpath) => self.print_qpath(qpath, true), } } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 0e9ff962435f..52bb76a5550f 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -925,9 +925,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty } - rustc_hir::PatExprKind::ConstBlock(c) => { - self.check_expr_const_block(c, Expectation::NoExpectation) - } rustc_hir::PatExprKind::Path(qpath) => { let (res, opt_ty, segments) = self.resolve_ty_and_res_fully_qualified_call(qpath, lt.hir_id, lt.span); diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 02e6f8d6ce71..7e274fcf994e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -13,14 +13,13 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::{self as hir, ByRef, LangItem, Mutability, Pinnedness, RangeEnd}; use rustc_index::Idx; -use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::LitToConstInput; use rustc_middle::thir::{ Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary, }; use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment}; use rustc_middle::ty::layout::IntegerExt; -use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypingMode}; +use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use rustc_span::{ErrorGuaranteed, Span}; @@ -621,54 +620,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { pattern } - /// Lowers an inline const block (e.g. `const { 1 + 1 }`) to a pattern. - fn lower_inline_const( - &mut self, - block: &'tcx hir::ConstBlock, - id: hir::HirId, - span: Span, - ) -> PatKind<'tcx> { - let tcx = self.tcx; - let def_id = block.def_id; - let ty = tcx.typeck(def_id).node_type(block.hir_id); - - let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()); - let parent_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id); - let args = ty::InlineConstArgs::new(tcx, ty::InlineConstArgsParts { parent_args, ty }).args; - - let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args }; - let c = ty::Const::new_unevaluated(self.tcx, ct); - let pattern = self.const_to_pat(c, ty, id, span); - - // Apply a type ascription for the inline constant. - let annotation = { - let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); - let args = ty::InlineConstArgs::new( - tcx, - ty::InlineConstArgsParts { parent_args, ty: infcx.next_ty_var(span) }, - ) - .args; - infcx.canonicalize_user_type_annotation(ty::UserType::new(ty::UserTypeKind::TypeOf( - def_id.to_def_id(), - ty::UserArgs { args, user_self_ty: None }, - ))) - }; - let annotation = - CanonicalUserTypeAnnotation { user_ty: Box::new(annotation), span, inferred_ty: ty }; - PatKind::AscribeUserType { - subpattern: pattern, - ascription: Ascription { - annotation, - // Note that we use `Contravariant` here. See the `variance` field documentation - // for details. - variance: ty::Contravariant, - }, - } - } - /// Lowers the kinds of "expression" that can appear in a HIR pattern: /// - Paths (e.g. `FOO`, `foo::BAR`, `Option::None`) - /// - Inline const blocks (e.g. `const { 1 + 1 }`) /// - Literals, possibly negated (e.g. `-128u8`, `"hello"`) fn lower_pat_expr( &mut self, @@ -677,9 +630,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ) -> PatKind<'tcx> { match &expr.kind { hir::PatExprKind::Path(qpath) => self.lower_path(qpath, expr.hir_id, expr.span).kind, - hir::PatExprKind::ConstBlock(anon_const) => { - self.lower_inline_const(anon_const, expr.hir_id, expr.span) - } hir::PatExprKind::Lit { lit, negated } => { // We handle byte string literal patterns by using the pattern's type instead of the // literal's type in `const_to_pat`: if the literal `b"..."` matches on a slice reference, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 9e7d4bca37d0..a5f8145bee8f 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1514,7 +1514,7 @@ impl<'a> Parser<'a> { }, ) } else if this.check_inline_const(0) { - this.parse_const_block(lo, false) + this.parse_const_block(lo) } else if this.may_recover() && this.is_do_catch_block() { this.recover_do_catch() } else if this.is_try_block() { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 8577ea40589a..97cb77ab13d2 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1300,7 +1300,7 @@ impl<'a> Parser<'a> { } /// Parses inline const expressions. - fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, Box> { + fn parse_const_block(&mut self, span: Span) -> PResult<'a, Box> { self.expect_keyword(exp!(Const))?; let (attrs, blk) = self.parse_inner_attrs_and_block(None)?; let anon_const = AnonConst { @@ -1308,18 +1308,7 @@ impl<'a> Parser<'a> { value: self.mk_expr(blk.span, ExprKind::Block(blk, None)), }; let blk_span = anon_const.value.span; - let kind = if pat { - let guar = self - .dcx() - .struct_span_err(blk_span, "const blocks cannot be used as patterns") - .with_help( - "use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead", - ) - .emit(); - ExprKind::Err(guar) - } else { - ExprKind::ConstBlock(anon_const) - }; + let kind = ExprKind::ConstBlock(anon_const); Ok(self.mk_expr_with_attrs(span.to(blk_span), kind, attrs)) } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 0e9796c04c8a..d7f3a36122e5 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -785,8 +785,10 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(exp!(Box)) { self.parse_pat_box()? } else if self.check_inline_const(0) { - // Parse `const pat` - let const_expr = self.parse_const_block(lo.to(self.token.span), true)?; + // Parse `const pat`. + // NOTE: This will always error later during AST lowering because + // inline const cannot be used as patterns. + let const_expr = self.parse_const_block(lo.to(self.token.span))?; if let Some(re) = self.parse_range_end() { self.parse_pat_range_begin_with(const_expr, re)? @@ -1281,7 +1283,7 @@ impl<'a> Parser<'a> { .then_some(self.prev_token.span); let bound = if self.check_inline_const(0) { - self.parse_const_block(self.token.span, true) + self.parse_const_block(self.token.span) } else if self.check_path() { let lo = self.token.span; let (qself, path) = if self.eat_lt() { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 03cbb0311c6c..9a5fd125a400 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -723,7 +723,6 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("Lit {{ ref {lit}, {negated} }}"); self.lit(lit); }, - PatExprKind::ConstBlock(_) => kind!("ConstBlock(_)"), PatExprKind::Path(_) => self.maybe_path(pat), } } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 7e3fa4f9909b..325fc85baa4e 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -578,7 +578,6 @@ impl<'tcx> ConstEvalCtxt<'tcx> { Some(val) } }, - PatExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir_body(*body).value), PatExprKind::Path(qpath) => self.qpath(qpath, pat_expr.hir_id), } } diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index c6d82c0e63fa..581209c68f18 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -506,9 +506,8 @@ impl HirEqInterExpr<'_, '_, '_> { negated: right_neg, }, ) => left_neg == right_neg && left.node == right.node, - (PatExprKind::ConstBlock(left), PatExprKind::ConstBlock(right)) => self.eq_body(left.body, right.body), (PatExprKind::Path(left), PatExprKind::Path(right)) => self.eq_qpath(left, right), - (PatExprKind::Lit { .. } | PatExprKind::ConstBlock(..) | PatExprKind::Path(..), _) => false, + (PatExprKind::Lit { .. } | PatExprKind::Path(..), _) => false, } } @@ -1102,7 +1101,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { lit.node.hash(&mut self.s); negated.hash(&mut self.s); }, - PatExprKind::ConstBlock(c) => self.hash_body(c.body), PatExprKind::Path(qpath) => self.hash_qpath(qpath), } } diff --git a/tests/ui/inline-const/in-pat-recovery.rs b/tests/ui/inline-const/in-pat-recovery.rs index a46e56e3be64..d519217fad3b 100644 --- a/tests/ui/inline-const/in-pat-recovery.rs +++ b/tests/ui/inline-const/in-pat-recovery.rs @@ -4,8 +4,63 @@ fn main() { match 1 { const { 1 + 7 } => {} - //~^ ERROR const blocks cannot be used as patterns + //~^ ERROR arbitrary expressions aren't allowed in patterns 2 => {} _ => {} } + + match 5 { + const { 1 } ..= 10 => {} + //~^ ERROR arbitrary expressions aren't allowed in patterns + _ => {} + } + + match 5 { + 1 ..= const { 10 } => {} + //~^ ERROR arbitrary expressions aren't allowed in patterns + _ => {} + } + + match 5 { + const { 1 } ..= const { 10 } => {} + //~^ ERROR arbitrary expressions aren't allowed in patterns + //~| ERROR arbitrary expressions aren't allowed in patterns + _ => {} + } + + match 5 { + const { 1 } .. 10 => {} + //~^ ERROR arbitrary expressions aren't allowed in patterns + _ => {} + } + + match 5 { + 1 .. const { 10 } => {} + //~^ ERROR arbitrary expressions aren't allowed in patterns + _ => {} + } + + match 5 { + const { 1 + 2 } ..= 10 => {} + //~^ ERROR arbitrary expressions aren't allowed in patterns + _ => {} + } + + match 5 { + 1 ..= const { 5 + 5 } => {} + //~^ ERROR arbitrary expressions aren't allowed in patterns + _ => {} + } + + match 5 { + const { 3 } .. => {} + //~^ ERROR arbitrary expressions aren't allowed in patterns + _ => {} + } + + match 5 { + ..= const { 7 } => {} + //~^ ERROR arbitrary expressions aren't allowed in patterns + _ => {} + } } diff --git a/tests/ui/inline-const/in-pat-recovery.stderr b/tests/ui/inline-const/in-pat-recovery.stderr index 0698cff1480d..376c43aaecca 100644 --- a/tests/ui/inline-const/in-pat-recovery.stderr +++ b/tests/ui/inline-const/in-pat-recovery.stderr @@ -1,10 +1,90 @@ -error: const blocks cannot be used as patterns - --> $DIR/in-pat-recovery.rs:6:15 +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:6:9 | LL | const { 1 + 7 } => {} - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: aborting due to 1 previous error +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:13:9 + | +LL | const { 1 } ..= 10 => {} + | ^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:19:15 + | +LL | 1 ..= const { 10 } => {} + | ^^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:25:9 + | +LL | const { 1 } ..= const { 10 } => {} + | ^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:25:25 + | +LL | const { 1 } ..= const { 10 } => {} + | ^^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:32:9 + | +LL | const { 1 } .. 10 => {} + | ^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:38:14 + | +LL | 1 .. const { 10 } => {} + | ^^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:44:9 + | +LL | const { 1 + 2 } ..= 10 => {} + | ^^^^^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:50:15 + | +LL | 1 ..= const { 5 + 5 } => {} + | ^^^^^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:56:9 + | +LL | const { 3 } .. => {} + | ^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/in-pat-recovery.rs:62:13 + | +LL | ..= const { 7 } => {} + | ^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: aborting due to 11 previous errors diff --git a/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.rs b/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.rs new file mode 100644 index 000000000000..fac8684ef094 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.rs @@ -0,0 +1,10 @@ +#![feature(deref_patterns)] +#![expect(incomplete_features)] + +fn main() { + let vec![const { vec![] }]: Vec = vec![]; + //~^ ERROR expected a pattern, found a function call + //~| ERROR usage of qualified paths in this context is experimental + //~| ERROR expected tuple struct or tuple variant + //~| ERROR arbitrary expressions aren't allowed in patterns +} diff --git a/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.stderr b/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.stderr new file mode 100644 index 000000000000..43b0ad18a79b --- /dev/null +++ b/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.stderr @@ -0,0 +1,41 @@ +error[E0532]: expected a pattern, found a function call + --> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9 + | +LL | let vec![const { vec![] }]: Vec = vec![]; + | ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant + | + = note: function calls are not allowed in patterns: + = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0658]: usage of qualified paths in this context is experimental + --> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9 + | +LL | let vec![const { vec![] }]: Vec = vec![]; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #86935 for more information + = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:14 + | +LL | let vec![const { vec![] }]: Vec = vec![]; + | ^^^^^^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error[E0164]: expected tuple struct or tuple variant, found associated function `<[_]>::into_vec` + --> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9 + | +LL | let vec![const { vec![] }]: Vec = vec![]; + | ^^^^^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns + | + = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html + = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0164, E0532, E0658. +For more information about an error, try `rustc --explain E0164`. From 86405fb507bef835470b0c678de80bc35d7ea514 Mon Sep 17 00:00:00 2001 From: Shinonn Date: Fri, 5 Dec 2025 11:02:17 +0700 Subject: [PATCH 1255/3801] Fix ICE by rejecting const blocks in patterns during AST lowering This fixes the ICE reported by rejecting `const` blocks in pattern position during AST lowering. Previously, `ExprKind::ConstBlock` could reach HIR as `PatExprKind::ConstBlock`, allowing invalid patterns to be type-checked and triggering an ICE. This patch removes the lowering path for const blocks in patterns and emits a proper diagnostic instead. A new UI test is added to ensure the compiler reports a regular error and to prevent regressions. --- clippy_lints/src/utils/author.rs | 1 - clippy_utils/src/consts.rs | 1 - clippy_utils/src/hir_utils.rs | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 03cbb0311c6c..9a5fd125a400 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -723,7 +723,6 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("Lit {{ ref {lit}, {negated} }}"); self.lit(lit); }, - PatExprKind::ConstBlock(_) => kind!("ConstBlock(_)"), PatExprKind::Path(_) => self.maybe_path(pat), } } diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 7e3fa4f9909b..325fc85baa4e 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -578,7 +578,6 @@ impl<'tcx> ConstEvalCtxt<'tcx> { Some(val) } }, - PatExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir_body(*body).value), PatExprKind::Path(qpath) => self.qpath(qpath, pat_expr.hir_id), } } diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index c6d82c0e63fa..581209c68f18 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -506,9 +506,8 @@ impl HirEqInterExpr<'_, '_, '_> { negated: right_neg, }, ) => left_neg == right_neg && left.node == right.node, - (PatExprKind::ConstBlock(left), PatExprKind::ConstBlock(right)) => self.eq_body(left.body, right.body), (PatExprKind::Path(left), PatExprKind::Path(right)) => self.eq_qpath(left, right), - (PatExprKind::Lit { .. } | PatExprKind::ConstBlock(..) | PatExprKind::Path(..), _) => false, + (PatExprKind::Lit { .. } | PatExprKind::Path(..), _) => false, } } @@ -1102,7 +1101,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { lit.node.hash(&mut self.s); negated.hash(&mut self.s); }, - PatExprKind::ConstBlock(c) => self.hash_body(c.body), PatExprKind::Path(qpath) => self.hash_qpath(qpath), } } From 04529b2e8332b9d49c6b4b205458400c61dc7e11 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Wed, 3 Dec 2025 19:09:42 +0200 Subject: [PATCH 1256/3801] Allow IDE layer to "see" fake builtin derive impls It sees them as regular impls; the details are abstracted. It's beautiful for the IDE layer, and less beautiful for `hir`, so this is a big change. Some small differences still exist: - We show builtin derives impl (to the IDE layer) as if they have had no generic parameters. It is possible to show the parameters, but that means also having to handle fake impls in `TypeParam` etc., and the benefit is questionable. - Getting the fn *def* type of a method of a builtin derive impl is not supported, as there is no real `FunctionId`, therefore no `CallableDefId`. The trait method is returned instead. Note: getting the fn *ptr* type of the method is supported well. - Builtin derive impls and their methods do not fully support `HasSource`, because, well, they have no source (at least, not in the form of `ast::Impl` and `ast::Fn`). To support them, we use the derive's `TextRange` where possible, and the trait method's source when not. It's important to note that the def map still records the `MacroCallId`. I have doubts over this, as this means it's very easy to create the queries we don't want to create, but it does make things more convenient. In particular, a nicety of this setup is that even "Expand macro recursively" works (it creates the macro input/output query, but given that they will only be created when the user invokes the command, that does not seem to be a problem). --- .../crates/hir-def/src/builtin_derive.rs | 114 +- .../crates/hir-def/src/item_scope.rs | 7 +- .../rust-analyzer/crates/hir-def/src/lib.rs | 15 + .../builtin_derive_macro.rs | 1657 +++++++++-------- .../src/macro_expansion_tests/proc_macros.rs | 8 +- .../crates/hir-def/src/nameres/collector.rs | 35 +- .../crates/hir-ty/src/builtin_derive.rs | 78 +- .../crates/hir-ty/src/consteval/tests.rs | 1 + .../rust-analyzer/crates/hir-ty/src/db.rs | 10 +- .../crates/hir-ty/src/display.rs | 49 +- .../rust-analyzer/crates/hir-ty/src/lib.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/lower.rs | 23 +- .../crates/hir-ty/src/method_resolution.rs | 75 +- .../crates/hir-ty/src/mir/eval.rs | 7 +- .../crates/hir-ty/src/mir/eval/shim.rs | 19 +- .../crates/hir-ty/src/mir/eval/shim/simd.rs | 15 - .../src/next_solver/format_proof_tree.rs | 31 +- .../crates/hir-ty/src/next_solver/interner.rs | 2 +- .../crates/hir-ty/src/tests/incremental.rs | 2 +- .../rust-analyzer/crates/hir/src/attrs.rs | 45 +- .../rust-analyzer/crates/hir/src/display.rs | 355 ++-- .../rust-analyzer/crates/hir/src/from_id.rs | 102 +- .../crates/hir/src/has_source.rs | 72 +- src/tools/rust-analyzer/crates/hir/src/lib.rs | 962 +++++++--- .../rust-analyzer/crates/hir/src/semantics.rs | 82 +- .../crates/hir/src/source_analyzer.rs | 54 +- .../test_symbol_index_collection.txt | 24 +- .../crates/ide/src/inlay_hints.rs | 28 +- .../ide/src/inlay_hints/implicit_drop.rs | 5 +- .../crates/ide/src/navigation_target.rs | 62 +- .../crates/ide/src/references.rs | 2 +- .../rust-analyzer/crates/ide/src/runnables.rs | 8 +- .../crates/intern/src/symbol/symbols.rs | 3 + .../rust-analyzer/src/cli/analysis_stats.rs | 32 +- 34 files changed, 2451 insertions(+), 1535 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs index e0e163783f43..32385516ab58 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_derive.rs @@ -3,40 +3,102 @@ //! To save time and memory, builtin derives are not really expanded. Instead, we record them //! and create their impls based on lowered data, see crates/hir-ty/src/builtin_derive.rs. -use hir_expand::builtin::BuiltinDeriveExpander; +use hir_expand::{InFile, builtin::BuiltinDeriveExpander, name::Name}; +use intern::{Symbol, sym}; +use tt::TextRange; + +use crate::{ + AdtId, BuiltinDeriveImplId, BuiltinDeriveImplLoc, FunctionId, HasModule, db::DefDatabase, +}; macro_rules! declare_enum { - ( $( $trait:ident ),* $(,)? ) => { + ( $( $trait:ident => [ $( $method:ident ),* ] ),* $(,)? ) => { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinDeriveImplTrait { $( $trait, )* } + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + #[allow(non_camel_case_types)] + pub enum BuiltinDeriveImplMethod { + $( $( $method, )* )* + } + impl BuiltinDeriveImplTrait { + #[inline] + pub fn name(self) -> Symbol { + match self { + $( Self::$trait => sym::$trait, )* + } + } + #[inline] pub fn get_id(self, lang_items: &crate::lang_item::LangItems) -> Option { match self { $( Self::$trait => lang_items.$trait, )* } } + + #[inline] + pub fn get_method(self, method_name: &Symbol) -> Option { + match self { + $( + Self::$trait => { + match method_name { + $( _ if *method_name == sym::$method => Some(BuiltinDeriveImplMethod::$method), )* + _ => None, + } + } + )* + } + } + + #[inline] + pub fn all_methods(self) -> &'static [BuiltinDeriveImplMethod] { + match self { + $( Self::$trait => &[ $(BuiltinDeriveImplMethod::$method),* ], )* + } + } + } + + impl BuiltinDeriveImplMethod { + #[inline] + pub fn name(self) -> Symbol { + match self { + $( $( BuiltinDeriveImplMethod::$method => sym::$method, )* )* + } + } } }; } declare_enum!( - Copy, - Clone, - Default, - Debug, - Hash, - Ord, - PartialOrd, - Eq, - PartialEq, - CoerceUnsized, - DispatchFromDyn, + Copy => [], + Clone => [clone], + Default => [default], + Debug => [fmt], + Hash => [hash], + Ord => [cmp], + PartialOrd => [partial_cmp], + Eq => [], + PartialEq => [eq], + CoerceUnsized => [], + DispatchFromDyn => [], ); +impl BuiltinDeriveImplMethod { + pub fn trait_method( + self, + db: &dyn DefDatabase, + impl_: BuiltinDeriveImplId, + ) -> Option { + let loc = impl_.loc(db); + let lang_items = crate::lang_item::lang_items(db, loc.krate(db)); + let trait_ = impl_.loc(db).trait_.get_id(lang_items)?; + trait_.trait_items(db).method_by_name(&Name::new_symbol_root(self.name())) + } +} + pub(crate) fn with_derive_traits( derive: BuiltinDeriveExpander, mut f: impl FnMut(BuiltinDeriveImplTrait), @@ -59,3 +121,29 @@ pub(crate) fn with_derive_traits( }; f(trait_); } + +impl BuiltinDeriveImplLoc { + pub fn source(&self, db: &dyn DefDatabase) -> InFile { + let (adt_ast_id, module) = match self.adt { + AdtId::StructId(adt) => { + let adt_loc = adt.loc(db); + (adt_loc.id.upcast(), adt_loc.container) + } + AdtId::UnionId(adt) => { + let adt_loc = adt.loc(db); + (adt_loc.id.upcast(), adt_loc.container) + } + AdtId::EnumId(adt) => { + let adt_loc = adt.loc(db); + (adt_loc.id.upcast(), adt_loc.container) + } + }; + let derive_range = self.derive_attr_id.find_derive_range( + db, + module.krate(db), + adt_ast_id, + self.derive_index, + ); + adt_ast_id.with_value(derive_range) + } +} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index 4f3700e8e41c..9e7868b273ef 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -9,7 +9,7 @@ use indexmap::map::Entry; use itertools::Itertools; use la_arena::Idx; use rustc_hash::{FxHashMap, FxHashSet}; -use smallvec::{SmallVec, smallvec}; +use smallvec::SmallVec; use span::Edition; use stdx::format_to; use syntax::ast; @@ -531,12 +531,13 @@ impl ItemScope { adt: AstId, attr_id: AttrId, attr_call_id: MacroCallId, - len: usize, + mut derive_call_ids: SmallVec<[Option; 4]>, ) { + derive_call_ids.shrink_to_fit(); self.derive_macros.entry(adt).or_default().push(DeriveMacroInvocation { attr_id, attr_call_id, - derive_call_ids: smallvec![None; len], + derive_call_ids, }); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index fde1e6ca17ee..8d6c418d75dc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -64,6 +64,7 @@ use base_db::{Crate, impl_intern_key}; use hir_expand::{ AstId, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroCallStyles, MacroDefId, MacroDefKind, + attrs::AttrId, builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander}, db::ExpandDatabase, eager::expand_eager_macro_input, @@ -337,6 +338,8 @@ impl ImplId { pub struct BuiltinDeriveImplLoc { pub adt: AdtId, pub trait_: BuiltinDeriveImplTrait, + pub derive_attr_id: AttrId, + pub derive_index: u32, } #[salsa::interned(debug, no_lifetime)] @@ -675,6 +678,18 @@ impl_from!( for ModuleDefId ); +impl From for ModuleDefId { + #[inline] + fn from(value: DefWithBodyId) -> Self { + match value { + DefWithBodyId::FunctionId(id) => id.into(), + DefWithBodyId::StaticId(id) => id.into(), + DefWithBodyId::ConstId(id) => id.into(), + DefWithBodyId::VariantId(id) => id.into(), + } + } +} + /// A constant, which might appears as a const item, an anonymous const block in expressions /// or patterns, or as a constant in types with const generics. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs index 0013c2a25679..814afdd16cf9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs @@ -1,828 +1,833 @@ //! Tests for `builtin_derive_macro.rs` from `hir_expand`. -use expect_test::expect; - -use crate::macro_expansion_tests::{check, check_errors}; - -#[test] -fn test_copy_expand_simple() { - check( - r#" -//- minicore: derive, copy -#[derive(Copy)] -struct Foo; -"#, - expect![[r#" -#[derive(Copy)] -struct Foo; - -impl <> $crate::marker::Copy for Foo< > where {}"#]], - ); -} - -#[test] -fn test_copy_expand_in_core() { - check( - r#" -//- /lib.rs crate:core -#[rustc_builtin_macro] -macro derive {} -#[rustc_builtin_macro] -macro Copy {} -#[derive(Copy)] -struct Foo; -"#, - expect![[r#" -#[rustc_builtin_macro] -macro derive {} -#[rustc_builtin_macro] -macro Copy {} -#[derive(Copy)] -struct Foo; - -impl <> $crate::marker::Copy for Foo< > where {}"#]], - ); -} - -#[test] -fn test_copy_expand_with_type_params() { - check( - r#" -//- minicore: derive, copy -#[derive(Copy)] -struct Foo; -"#, - expect![[r#" -#[derive(Copy)] -struct Foo; - -impl $crate::marker::Copy for Foo where {}"#]], - ); -} - -#[test] -fn test_copy_expand_with_lifetimes() { - // We currently just ignore lifetimes - check( - r#" -//- minicore: derive, copy -#[derive(Copy)] -struct Foo; -"#, - expect![[r#" -#[derive(Copy)] -struct Foo; - -impl $crate::marker::Copy for Foo where {}"#]], - ); -} - -#[test] -fn test_clone_expand() { - check( - r#" -//- minicore: derive, clone -#[derive(Clone)] -enum Command { - Move { x: A, y: B }, - Do(&'static str), - Jump, -} -"#, - expect![[r#" -#[derive(Clone)] -enum Command { - Move { x: A, y: B }, - Do(&'static str), - Jump, -} - -impl $crate::clone::Clone for Command where { - fn clone(&self ) -> Self { - match self { - Command::Move { - x: x, y: y, - } - =>Command::Move { - x: x.clone(), y: y.clone(), - } - , Command::Do(f0, )=>Command::Do(f0.clone(), ), Command::Jump=>Command::Jump, - } - } -}"#]], - ); -} - -#[test] -fn test_clone_expand_with_associated_types() { - check( - r#" -//- minicore: derive, clone -trait Trait { - type InWc; - type InFieldQualified; - type InFieldShorthand; - type InGenericArg; -} -trait Marker {} -struct Vec(T); - -#[derive(Clone)] -struct Foo -where - ::InWc: Marker, -{ - qualified: ::InFieldQualified, - shorthand: T::InFieldShorthand, - generic: Vec, -} -"#, - expect![[r#" -trait Trait { - type InWc; - type InFieldQualified; - type InFieldShorthand; - type InGenericArg; -} -trait Marker {} -struct Vec(T); - -#[derive(Clone)] -struct Foo -where - ::InWc: Marker, -{ - qualified: ::InFieldQualified, - shorthand: T::InFieldShorthand, - generic: Vec, -} - -impl $crate::clone::Clone for Foo where ::InWc: Marker, T: Trait, T::InFieldShorthand: $crate::clone::Clone, T::InGenericArg: $crate::clone::Clone, { - fn clone(&self ) -> Self { - match self { - Foo { - qualified: qualified, shorthand: shorthand, generic: generic, - } - =>Foo { - qualified: qualified.clone(), shorthand: shorthand.clone(), generic: generic.clone(), - } - , - } - } -}"#]], - ); -} - -#[test] -fn test_clone_expand_with_const_generics() { - check( - r#" -//- minicore: derive, clone -#[derive(Clone)] -struct Foo(u32); -"#, - expect![[r#" -#[derive(Clone)] -struct Foo(u32); - -impl $crate::clone::Clone for Foo where { - fn clone(&self ) -> Self { - match self { - Foo(f0, )=>Foo(f0.clone(), ), - } - } -}"#]], - ); -} - -#[test] -fn test_default_expand() { - check( - r#" -//- minicore: derive, default -#[derive(Default)] -struct Foo { - field1: i32, - field2: (), -} -#[derive(Default)] -enum Bar { - Foo(u8), - #[default] - Bar, -} -"#, - expect![[r#" -#[derive(Default)] -struct Foo { - field1: i32, - field2: (), -} -#[derive(Default)] -enum Bar { - Foo(u8), - #[default] - Bar, -} - -impl <> $crate::default::Default for Foo< > where { - fn default() -> Self { - Foo { - field1: $crate::default::Default::default(), field2: $crate::default::Default::default(), - } - } -} -impl <> $crate::default::Default for Bar< > where { - fn default() -> Self { - Bar::Bar - } -}"#]], - ); -} - -#[test] -fn test_partial_eq_expand() { - check( - r#" -//- minicore: derive, eq -#[derive(PartialEq, Eq)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} -"#, - expect![[r#" -#[derive(PartialEq, Eq)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} - -impl <> $crate::cmp::PartialEq for Command< > where { - fn eq(&self , other: &Self ) -> bool { - match (self , other) { - (Command::Move { - x: x_self, y: y_self, - } - , Command::Move { - x: x_other, y: y_other, - } - )=>x_self.eq(x_other) && y_self.eq(y_other), (Command::Do(f0_self, ), Command::Do(f0_other, ))=>f0_self.eq(f0_other), (Command::Jump, Command::Jump)=>true , _unused=>false - } - } -} -impl <> $crate::cmp::Eq for Command< > where {}"#]], - ); -} - -#[test] -fn test_partial_eq_expand_with_derive_const() { - // FIXME: actually expand with const - check( - r#" -//- minicore: derive, eq -#[derive_const(PartialEq, Eq)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} -"#, - expect![[r#" -#[derive_const(PartialEq, Eq)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} - -impl <> $crate::cmp::PartialEq for Command< > where { - fn eq(&self , other: &Self ) -> bool { - match (self , other) { - (Command::Move { - x: x_self, y: y_self, - } - , Command::Move { - x: x_other, y: y_other, - } - )=>x_self.eq(x_other) && y_self.eq(y_other), (Command::Do(f0_self, ), Command::Do(f0_other, ))=>f0_self.eq(f0_other), (Command::Jump, Command::Jump)=>true , _unused=>false - } - } -} -impl <> $crate::cmp::Eq for Command< > where {}"#]], - ); -} - -#[test] -fn test_partial_ord_expand() { - check( - r#" -//- minicore: derive, ord -#[derive(PartialOrd, Ord)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} -"#, - expect![[r#" -#[derive(PartialOrd, Ord)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} - -impl <> $crate::cmp::PartialOrd for Command< > where { - fn partial_cmp(&self , other: &Self ) -> $crate::option::Option<$crate::cmp::Ordering> { - match $crate::intrinsics::discriminant_value(self ).partial_cmp(&$crate::intrinsics::discriminant_value(other)) { - $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { - match (self , other) { - (Command::Move { - x: x_self, y: y_self, - } - , Command::Move { - x: x_other, y: y_other, - } - )=>match x_self.partial_cmp(&x_other) { - $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { - match y_self.partial_cmp(&y_other) { - $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { - $crate::option::Option::Some($crate::cmp::Ordering::Equal) - } - c=>return c, - } - } - c=>return c, - } - , (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.partial_cmp(&f0_other) { - $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { - $crate::option::Option::Some($crate::cmp::Ordering::Equal) - } - c=>return c, - } - , (Command::Jump, Command::Jump)=>$crate::option::Option::Some($crate::cmp::Ordering::Equal), _unused=>$crate::option::Option::Some($crate::cmp::Ordering::Equal) - } - } - c=>return c, - } - } -} -impl <> $crate::cmp::Ord for Command< > where { - fn cmp(&self , other: &Self ) -> $crate::cmp::Ordering { - match $crate::intrinsics::discriminant_value(self ).cmp(&$crate::intrinsics::discriminant_value(other)) { - $crate::cmp::Ordering::Equal=> { - match (self , other) { - (Command::Move { - x: x_self, y: y_self, - } - , Command::Move { - x: x_other, y: y_other, - } - )=>match x_self.cmp(&x_other) { - $crate::cmp::Ordering::Equal=> { - match y_self.cmp(&y_other) { - $crate::cmp::Ordering::Equal=> { - $crate::cmp::Ordering::Equal - } - c=>return c, - } - } - c=>return c, - } - , (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.cmp(&f0_other) { - $crate::cmp::Ordering::Equal=> { - $crate::cmp::Ordering::Equal - } - c=>return c, - } - , (Command::Jump, Command::Jump)=>$crate::cmp::Ordering::Equal, _unused=>$crate::cmp::Ordering::Equal - } - } - c=>return c, - } - } -}"#]], - ); -} - -#[test] -fn test_hash_expand() { - check( - r#" -//- minicore: derive, hash -use core::hash::Hash; - -#[derive(Hash)] -struct Foo { - x: i32, - y: u64, - z: (i32, u64), -} -"#, - expect![[r#" -use core::hash::Hash; - -#[derive(Hash)] -struct Foo { - x: i32, - y: u64, - z: (i32, u64), -} - -impl <> $crate::hash::Hash for Foo< > where { - fn hash(&self , ra_expand_state: &mut H) { - match self { - Foo { - x: x, y: y, z: z, - } - => { - x.hash(ra_expand_state); - y.hash(ra_expand_state); - z.hash(ra_expand_state); - } - , - } - } -}"#]], - ); - check( - r#" -//- minicore: derive, hash -use core::hash::Hash; - -#[derive(Hash)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} -"#, - expect![[r#" -use core::hash::Hash; - -#[derive(Hash)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} - -impl <> $crate::hash::Hash for Command< > where { - fn hash(&self , ra_expand_state: &mut H) { - $crate::mem::discriminant(self ).hash(ra_expand_state); - match self { - Command::Move { - x: x, y: y, - } - => { - x.hash(ra_expand_state); - y.hash(ra_expand_state); - } - , Command::Do(f0, )=> { - f0.hash(ra_expand_state); - } - , Command::Jump=> {} - , - } - } -}"#]], - ); -} - -#[test] -fn test_debug_expand() { - check( - r#" -//- minicore: derive, fmt -use core::fmt::Debug; - -#[derive(Debug)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} -"#, - expect![[r#" -use core::fmt::Debug; - -#[derive(Debug)] -enum Command { - Move { x: i32, y: i32 }, - Do(&'static str), - Jump, -} - -impl <> $crate::fmt::Debug for Command< > where { - fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { - match self { - Command::Move { - x: x, y: y, - } - =>f.debug_struct("Move").field("x", &x).field("y", &y).finish(), Command::Do(f0, )=>f.debug_tuple("Do").field(&f0).finish(), Command::Jump=>f.write_str("Jump"), - } - } -}"#]], - ); -} -#[test] -fn test_debug_expand_with_cfg() { - check( - r#" - //- minicore: derive, fmt - use core::fmt::Debug; - - #[derive(Debug)] - struct HideAndShow { - #[cfg(never)] - always_hide: u32, - #[cfg(not(never))] - always_show: u32, - } - #[derive(Debug)] - enum HideAndShowEnum { - #[cfg(never)] - AlwaysHide, - #[cfg(not(never))] - AlwaysShow{ - #[cfg(never)] - always_hide: u32, - #[cfg(not(never))] - always_show: u32, - } - } - "#, - expect![[r#" -use core::fmt::Debug; - -#[derive(Debug)] -struct HideAndShow { - #[cfg(never)] - always_hide: u32, - #[cfg(not(never))] - always_show: u32, -} -#[derive(Debug)] -enum HideAndShowEnum { - #[cfg(never)] - AlwaysHide, - #[cfg(not(never))] - AlwaysShow{ - #[cfg(never)] - always_hide: u32, - #[cfg(not(never))] - always_show: u32, - } -} - -impl <> $crate::fmt::Debug for HideAndShow< > where { - fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { - match self { - HideAndShow { - always_show: always_show, - } - =>f.debug_struct("HideAndShow").field("always_show", &always_show).finish() - } - } -} -impl <> $crate::fmt::Debug for HideAndShowEnum< > where { - fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { - match self { - HideAndShowEnum::AlwaysShow { - always_show: always_show, - } - =>f.debug_struct("AlwaysShow").field("always_show", &always_show).finish(), - } - } -}"#]], - ); -} -#[test] -fn test_default_expand_with_cfg() { - check( - r#" -//- minicore: derive, default -#[derive(Default)] -struct Foo { - field1: i32, - #[cfg(never)] - field2: (), - #[cfg(feature = "never")] - field3: (), - #[cfg(not(feature = "never"))] - field4: (), -} -#[derive(Default)] -enum Bar { - Foo, - #[cfg_attr(not(never), default)] - Bar, -} -"#, - expect![[r##" -#[derive(Default)] -struct Foo { - field1: i32, - #[cfg(never)] - field2: (), - #[cfg(feature = "never")] - field3: (), - #[cfg(not(feature = "never"))] - field4: (), -} -#[derive(Default)] -enum Bar { - Foo, - #[cfg_attr(not(never), default)] - Bar, -} - -impl <> $crate::default::Default for Foo< > where { - fn default() -> Self { - Foo { - field1: $crate::default::Default::default(), field4: $crate::default::Default::default(), - } - } -} -impl <> $crate::default::Default for Bar< > where { - fn default() -> Self { - Bar::Bar - } -}"##]], - ); -} - -#[test] -fn coerce_pointee_expansion() { - check( - r#" -//- minicore: coerce_pointee - -use core::marker::CoercePointee; - -pub trait Trait {} - -#[derive(CoercePointee)] -#[repr(transparent)] -pub struct Foo<'a, T: ?Sized + Trait, #[pointee] U: ?Sized, const N: u32>(T) -where - U: Trait + ToString;"#, - expect![[r#" - -use core::marker::CoercePointee; - -pub trait Trait {} - -#[derive(CoercePointee)] -#[repr(transparent)] -pub struct Foo<'a, T: ?Sized + Trait, #[pointee] U: ?Sized, const N: u32>(T) -where - U: Trait + ToString; -impl $crate::ops::DispatchFromDyn> for Foo where U: Trait +ToString, T: Trait<__S>, __S: ?Sized, __S: Trait<__S> +ToString, U: ::core::marker::Unsize<__S>, T:?Sized+Trait, U:?Sized, {} -impl $crate::ops::CoerceUnsized> for Foo where U: Trait +ToString, T: Trait<__S>, __S: ?Sized, __S: Trait<__S> +ToString, U: ::core::marker::Unsize<__S>, T:?Sized+Trait, U:?Sized, {}"#]], - ); -} - -#[test] -fn coerce_pointee_errors() { - check_errors( - r#" -//- minicore: coerce_pointee - -use core::marker::CoercePointee; - -#[derive(CoercePointee)] -enum Enum {} - -#[derive(CoercePointee)] -struct Struct1; - -#[derive(CoercePointee)] -struct Struct2(); - -#[derive(CoercePointee)] -struct Struct3 {} - -#[derive(CoercePointee)] -struct Struct4(T); - -#[derive(CoercePointee)] -#[repr(transparent)] -struct Struct5(i32); - -#[derive(CoercePointee)] -#[repr(transparent)] -struct Struct6<#[pointee] T: ?Sized, #[pointee] U: ?Sized>(T, U); - -#[derive(CoercePointee)] -#[repr(transparent)] -struct Struct7(T, U); - -#[derive(CoercePointee)] -#[repr(transparent)] -struct Struct8<#[pointee] T, U: ?Sized>(T); - -#[derive(CoercePointee)] -#[repr(transparent)] -struct Struct9(T); - -#[derive(CoercePointee)] -#[repr(transparent)] -struct Struct9<#[pointee] T, U>(T) where T: ?Sized; -"#, - expect![[r#" - 35..72: `CoercePointee` can only be derived on `struct`s - 74..114: `CoercePointee` can only be derived on `struct`s with at least one field - 116..158: `CoercePointee` can only be derived on `struct`s with at least one field - 160..202: `CoercePointee` can only be derived on `struct`s with at least one field - 204..258: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]` - 260..326: `CoercePointee` can only be derived on `struct`s that are generic over at least one type - 328..439: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits - 441..530: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits - 532..621: `derive(CoercePointee)` requires `T` to be marked `?Sized` - 623..690: `derive(CoercePointee)` requires `T` to be marked `?Sized`"#]], - ); -} - -#[test] -fn union_derive() { - check_errors( - r#" -//- minicore: clone, copy, default, fmt, hash, ord, eq, derive - -#[derive(Copy)] -union Foo1 { _v: () } -#[derive(Clone)] -union Foo2 { _v: () } -#[derive(Default)] -union Foo3 { _v: () } -#[derive(Debug)] -union Foo4 { _v: () } -#[derive(Hash)] -union Foo5 { _v: () } -#[derive(Ord)] -union Foo6 { _v: () } -#[derive(PartialOrd)] -union Foo7 { _v: () } -#[derive(Eq)] -union Foo8 { _v: () } -#[derive(PartialEq)] -union Foo9 { _v: () } - "#, - expect![[r#" - 78..118: this trait cannot be derived for unions - 119..157: this trait cannot be derived for unions - 158..195: this trait cannot be derived for unions - 196..232: this trait cannot be derived for unions - 233..276: this trait cannot be derived for unions - 313..355: this trait cannot be derived for unions"#]], - ); -} - -#[test] -fn default_enum_without_default_attr() { - check_errors( - r#" -//- minicore: default, derive - -#[derive(Default)] -enum Foo { - Bar, -} - "#, - expect!["1..41: `#[derive(Default)]` on enum with no `#[default]`"], - ); -} - -#[test] -fn generic_enum_default() { - check( - r#" -//- minicore: default, derive - -#[derive(Default)] -enum Foo { - Bar(T), - #[default] - Baz, -} -"#, - expect![[r#" - -#[derive(Default)] -enum Foo { - Bar(T), - #[default] - Baz, -} - -impl $crate::default::Default for Foo where { - fn default() -> Self { - Foo::Baz - } -}"#]], - ); -} +// FIXME: This file is commented out because due to the fast path for builtin derives, +// the macros do not really get expanded, and we cannot check their expansion. +// It's not removed because we still need to find some way to do that nevertheless. +// Maybe going through the list of registered derive calls in the def map? + +// use expect_test::expect; + +// use crate::macro_expansion_tests::{check, check_errors}; + +// #[test] +// fn test_copy_expand_simple() { +// check( +// r#" +// //- minicore: derive, copy +// #[derive(Copy)] +// struct Foo; +// "#, +// expect![[r#" +// #[derive(Copy)] +// struct Foo; + +// impl <> $crate::marker::Copy for Foo< > where {}"#]], +// ); +// } + +// #[test] +// fn test_copy_expand_in_core() { +// check( +// r#" +// //- /lib.rs crate:core +// #[rustc_builtin_macro] +// macro derive {} +// #[rustc_builtin_macro] +// macro Copy {} +// #[derive(Copy)] +// struct Foo; +// "#, +// expect![[r#" +// #[rustc_builtin_macro] +// macro derive {} +// #[rustc_builtin_macro] +// macro Copy {} +// #[derive(Copy)] +// struct Foo; + +// impl <> $crate::marker::Copy for Foo< > where {}"#]], +// ); +// } + +// #[test] +// fn test_copy_expand_with_type_params() { +// check( +// r#" +// //- minicore: derive, copy +// #[derive(Copy)] +// struct Foo; +// "#, +// expect![[r#" +// #[derive(Copy)] +// struct Foo; + +// impl $crate::marker::Copy for Foo where {}"#]], +// ); +// } + +// #[test] +// fn test_copy_expand_with_lifetimes() { +// // We currently just ignore lifetimes +// check( +// r#" +// //- minicore: derive, copy +// #[derive(Copy)] +// struct Foo; +// "#, +// expect![[r#" +// #[derive(Copy)] +// struct Foo; + +// impl $crate::marker::Copy for Foo where {}"#]], +// ); +// } + +// #[test] +// fn test_clone_expand() { +// check( +// r#" +// //- minicore: derive, clone +// #[derive(Clone)] +// enum Command { +// Move { x: A, y: B }, +// Do(&'static str), +// Jump, +// } +// "#, +// expect![[r#" +// #[derive(Clone)] +// enum Command { +// Move { x: A, y: B }, +// Do(&'static str), +// Jump, +// } + +// impl $crate::clone::Clone for Command where { +// fn clone(&self ) -> Self { +// match self { +// Command::Move { +// x: x, y: y, +// } +// =>Command::Move { +// x: x.clone(), y: y.clone(), +// } +// , Command::Do(f0, )=>Command::Do(f0.clone(), ), Command::Jump=>Command::Jump, +// } +// } +// }"#]], +// ); +// } + +// #[test] +// fn test_clone_expand_with_associated_types() { +// check( +// r#" +// //- minicore: derive, clone +// trait Trait { +// type InWc; +// type InFieldQualified; +// type InFieldShorthand; +// type InGenericArg; +// } +// trait Marker {} +// struct Vec(T); + +// #[derive(Clone)] +// struct Foo +// where +// ::InWc: Marker, +// { +// qualified: ::InFieldQualified, +// shorthand: T::InFieldShorthand, +// generic: Vec, +// } +// "#, +// expect![[r#" +// trait Trait { +// type InWc; +// type InFieldQualified; +// type InFieldShorthand; +// type InGenericArg; +// } +// trait Marker {} +// struct Vec(T); + +// #[derive(Clone)] +// struct Foo +// where +// ::InWc: Marker, +// { +// qualified: ::InFieldQualified, +// shorthand: T::InFieldShorthand, +// generic: Vec, +// } + +// impl $crate::clone::Clone for Foo where ::InWc: Marker, T: Trait, T::InFieldShorthand: $crate::clone::Clone, T::InGenericArg: $crate::clone::Clone, { +// fn clone(&self ) -> Self { +// match self { +// Foo { +// qualified: qualified, shorthand: shorthand, generic: generic, +// } +// =>Foo { +// qualified: qualified.clone(), shorthand: shorthand.clone(), generic: generic.clone(), +// } +// , +// } +// } +// }"#]], +// ); +// } + +// #[test] +// fn test_clone_expand_with_const_generics() { +// check( +// r#" +// //- minicore: derive, clone +// #[derive(Clone)] +// struct Foo(u32); +// "#, +// expect![[r#" +// #[derive(Clone)] +// struct Foo(u32); + +// impl $crate::clone::Clone for Foo where { +// fn clone(&self ) -> Self { +// match self { +// Foo(f0, )=>Foo(f0.clone(), ), +// } +// } +// }"#]], +// ); +// } + +// #[test] +// fn test_default_expand() { +// check( +// r#" +// //- minicore: derive, default +// #[derive(Default)] +// struct Foo { +// field1: i32, +// field2: (), +// } +// #[derive(Default)] +// enum Bar { +// Foo(u8), +// #[default] +// Bar, +// } +// "#, +// expect![[r#" +// #[derive(Default)] +// struct Foo { +// field1: i32, +// field2: (), +// } +// #[derive(Default)] +// enum Bar { +// Foo(u8), +// #[default] +// Bar, +// } + +// impl <> $crate::default::Default for Foo< > where { +// fn default() -> Self { +// Foo { +// field1: $crate::default::Default::default(), field2: $crate::default::Default::default(), +// } +// } +// } +// impl <> $crate::default::Default for Bar< > where { +// fn default() -> Self { +// Bar::Bar +// } +// }"#]], +// ); +// } + +// #[test] +// fn test_partial_eq_expand() { +// check( +// r#" +// //- minicore: derive, eq +// #[derive(PartialEq, Eq)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } +// "#, +// expect![[r#" +// #[derive(PartialEq, Eq)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } + +// impl <> $crate::cmp::PartialEq for Command< > where { +// fn eq(&self , other: &Self ) -> bool { +// match (self , other) { +// (Command::Move { +// x: x_self, y: y_self, +// } +// , Command::Move { +// x: x_other, y: y_other, +// } +// )=>x_self.eq(x_other) && y_self.eq(y_other), (Command::Do(f0_self, ), Command::Do(f0_other, ))=>f0_self.eq(f0_other), (Command::Jump, Command::Jump)=>true , _unused=>false +// } +// } +// } +// impl <> $crate::cmp::Eq for Command< > where {}"#]], +// ); +// } + +// #[test] +// fn test_partial_eq_expand_with_derive_const() { +// // FIXME: actually expand with const +// check( +// r#" +// //- minicore: derive, eq +// #[derive_const(PartialEq, Eq)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } +// "#, +// expect![[r#" +// #[derive_const(PartialEq, Eq)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } + +// impl <> $crate::cmp::PartialEq for Command< > where { +// fn eq(&self , other: &Self ) -> bool { +// match (self , other) { +// (Command::Move { +// x: x_self, y: y_self, +// } +// , Command::Move { +// x: x_other, y: y_other, +// } +// )=>x_self.eq(x_other) && y_self.eq(y_other), (Command::Do(f0_self, ), Command::Do(f0_other, ))=>f0_self.eq(f0_other), (Command::Jump, Command::Jump)=>true , _unused=>false +// } +// } +// } +// impl <> $crate::cmp::Eq for Command< > where {}"#]], +// ); +// } + +// #[test] +// fn test_partial_ord_expand() { +// check( +// r#" +// //- minicore: derive, ord +// #[derive(PartialOrd, Ord)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } +// "#, +// expect![[r#" +// #[derive(PartialOrd, Ord)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } + +// impl <> $crate::cmp::PartialOrd for Command< > where { +// fn partial_cmp(&self , other: &Self ) -> $crate::option::Option<$crate::cmp::Ordering> { +// match $crate::intrinsics::discriminant_value(self ).partial_cmp(&$crate::intrinsics::discriminant_value(other)) { +// $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { +// match (self , other) { +// (Command::Move { +// x: x_self, y: y_self, +// } +// , Command::Move { +// x: x_other, y: y_other, +// } +// )=>match x_self.partial_cmp(&x_other) { +// $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { +// match y_self.partial_cmp(&y_other) { +// $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { +// $crate::option::Option::Some($crate::cmp::Ordering::Equal) +// } +// c=>return c, +// } +// } +// c=>return c, +// } +// , (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.partial_cmp(&f0_other) { +// $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { +// $crate::option::Option::Some($crate::cmp::Ordering::Equal) +// } +// c=>return c, +// } +// , (Command::Jump, Command::Jump)=>$crate::option::Option::Some($crate::cmp::Ordering::Equal), _unused=>$crate::option::Option::Some($crate::cmp::Ordering::Equal) +// } +// } +// c=>return c, +// } +// } +// } +// impl <> $crate::cmp::Ord for Command< > where { +// fn cmp(&self , other: &Self ) -> $crate::cmp::Ordering { +// match $crate::intrinsics::discriminant_value(self ).cmp(&$crate::intrinsics::discriminant_value(other)) { +// $crate::cmp::Ordering::Equal=> { +// match (self , other) { +// (Command::Move { +// x: x_self, y: y_self, +// } +// , Command::Move { +// x: x_other, y: y_other, +// } +// )=>match x_self.cmp(&x_other) { +// $crate::cmp::Ordering::Equal=> { +// match y_self.cmp(&y_other) { +// $crate::cmp::Ordering::Equal=> { +// $crate::cmp::Ordering::Equal +// } +// c=>return c, +// } +// } +// c=>return c, +// } +// , (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.cmp(&f0_other) { +// $crate::cmp::Ordering::Equal=> { +// $crate::cmp::Ordering::Equal +// } +// c=>return c, +// } +// , (Command::Jump, Command::Jump)=>$crate::cmp::Ordering::Equal, _unused=>$crate::cmp::Ordering::Equal +// } +// } +// c=>return c, +// } +// } +// }"#]], +// ); +// } + +// #[test] +// fn test_hash_expand() { +// check( +// r#" +// //- minicore: derive, hash +// use core::hash::Hash; + +// #[derive(Hash)] +// struct Foo { +// x: i32, +// y: u64, +// z: (i32, u64), +// } +// "#, +// expect![[r#" +// use core::hash::Hash; + +// #[derive(Hash)] +// struct Foo { +// x: i32, +// y: u64, +// z: (i32, u64), +// } + +// impl <> $crate::hash::Hash for Foo< > where { +// fn hash(&self , ra_expand_state: &mut H) { +// match self { +// Foo { +// x: x, y: y, z: z, +// } +// => { +// x.hash(ra_expand_state); +// y.hash(ra_expand_state); +// z.hash(ra_expand_state); +// } +// , +// } +// } +// }"#]], +// ); +// check( +// r#" +// //- minicore: derive, hash +// use core::hash::Hash; + +// #[derive(Hash)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } +// "#, +// expect![[r#" +// use core::hash::Hash; + +// #[derive(Hash)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } + +// impl <> $crate::hash::Hash for Command< > where { +// fn hash(&self , ra_expand_state: &mut H) { +// $crate::mem::discriminant(self ).hash(ra_expand_state); +// match self { +// Command::Move { +// x: x, y: y, +// } +// => { +// x.hash(ra_expand_state); +// y.hash(ra_expand_state); +// } +// , Command::Do(f0, )=> { +// f0.hash(ra_expand_state); +// } +// , Command::Jump=> {} +// , +// } +// } +// }"#]], +// ); +// } + +// #[test] +// fn test_debug_expand() { +// check( +// r#" +// //- minicore: derive, fmt +// use core::fmt::Debug; + +// #[derive(Debug)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } +// "#, +// expect![[r#" +// use core::fmt::Debug; + +// #[derive(Debug)] +// enum Command { +// Move { x: i32, y: i32 }, +// Do(&'static str), +// Jump, +// } + +// impl <> $crate::fmt::Debug for Command< > where { +// fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { +// match self { +// Command::Move { +// x: x, y: y, +// } +// =>f.debug_struct("Move").field("x", &x).field("y", &y).finish(), Command::Do(f0, )=>f.debug_tuple("Do").field(&f0).finish(), Command::Jump=>f.write_str("Jump"), +// } +// } +// }"#]], +// ); +// } +// #[test] +// fn test_debug_expand_with_cfg() { +// check( +// r#" +// //- minicore: derive, fmt +// use core::fmt::Debug; + +// #[derive(Debug)] +// struct HideAndShow { +// #[cfg(never)] +// always_hide: u32, +// #[cfg(not(never))] +// always_show: u32, +// } +// #[derive(Debug)] +// enum HideAndShowEnum { +// #[cfg(never)] +// AlwaysHide, +// #[cfg(not(never))] +// AlwaysShow{ +// #[cfg(never)] +// always_hide: u32, +// #[cfg(not(never))] +// always_show: u32, +// } +// } +// "#, +// expect![[r#" +// use core::fmt::Debug; + +// #[derive(Debug)] +// struct HideAndShow { +// #[cfg(never)] +// always_hide: u32, +// #[cfg(not(never))] +// always_show: u32, +// } +// #[derive(Debug)] +// enum HideAndShowEnum { +// #[cfg(never)] +// AlwaysHide, +// #[cfg(not(never))] +// AlwaysShow{ +// #[cfg(never)] +// always_hide: u32, +// #[cfg(not(never))] +// always_show: u32, +// } +// } + +// impl <> $crate::fmt::Debug for HideAndShow< > where { +// fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { +// match self { +// HideAndShow { +// always_show: always_show, +// } +// =>f.debug_struct("HideAndShow").field("always_show", &always_show).finish() +// } +// } +// } +// impl <> $crate::fmt::Debug for HideAndShowEnum< > where { +// fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { +// match self { +// HideAndShowEnum::AlwaysShow { +// always_show: always_show, +// } +// =>f.debug_struct("AlwaysShow").field("always_show", &always_show).finish(), +// } +// } +// }"#]], +// ); +// } +// #[test] +// fn test_default_expand_with_cfg() { +// check( +// r#" +// //- minicore: derive, default +// #[derive(Default)] +// struct Foo { +// field1: i32, +// #[cfg(never)] +// field2: (), +// #[cfg(feature = "never")] +// field3: (), +// #[cfg(not(feature = "never"))] +// field4: (), +// } +// #[derive(Default)] +// enum Bar { +// Foo, +// #[cfg_attr(not(never), default)] +// Bar, +// } +// "#, +// expect![[r##" +// #[derive(Default)] +// struct Foo { +// field1: i32, +// #[cfg(never)] +// field2: (), +// #[cfg(feature = "never")] +// field3: (), +// #[cfg(not(feature = "never"))] +// field4: (), +// } +// #[derive(Default)] +// enum Bar { +// Foo, +// #[cfg_attr(not(never), default)] +// Bar, +// } + +// impl <> $crate::default::Default for Foo< > where { +// fn default() -> Self { +// Foo { +// field1: $crate::default::Default::default(), field4: $crate::default::Default::default(), +// } +// } +// } +// impl <> $crate::default::Default for Bar< > where { +// fn default() -> Self { +// Bar::Bar +// } +// }"##]], +// ); +// } + +// #[test] +// fn coerce_pointee_expansion() { +// check( +// r#" +// //- minicore: coerce_pointee + +// use core::marker::CoercePointee; + +// pub trait Trait {} + +// #[derive(CoercePointee)] +// #[repr(transparent)] +// pub struct Foo<'a, T: ?Sized + Trait, #[pointee] U: ?Sized, const N: u32>(T) +// where +// U: Trait + ToString;"#, +// expect![[r#" + +// use core::marker::CoercePointee; + +// pub trait Trait {} + +// #[derive(CoercePointee)] +// #[repr(transparent)] +// pub struct Foo<'a, T: ?Sized + Trait, #[pointee] U: ?Sized, const N: u32>(T) +// where +// U: Trait + ToString; +// impl $crate::ops::DispatchFromDyn> for Foo where U: Trait +ToString, T: Trait<__S>, __S: ?Sized, __S: Trait<__S> +ToString, U: ::core::marker::Unsize<__S>, T:?Sized+Trait, U:?Sized, {} +// impl $crate::ops::CoerceUnsized> for Foo where U: Trait +ToString, T: Trait<__S>, __S: ?Sized, __S: Trait<__S> +ToString, U: ::core::marker::Unsize<__S>, T:?Sized+Trait, U:?Sized, {}"#]], +// ); +// } + +// #[test] +// fn coerce_pointee_errors() { +// check_errors( +// r#" +// //- minicore: coerce_pointee + +// use core::marker::CoercePointee; + +// #[derive(CoercePointee)] +// enum Enum {} + +// #[derive(CoercePointee)] +// struct Struct1; + +// #[derive(CoercePointee)] +// struct Struct2(); + +// #[derive(CoercePointee)] +// struct Struct3 {} + +// #[derive(CoercePointee)] +// struct Struct4(T); + +// #[derive(CoercePointee)] +// #[repr(transparent)] +// struct Struct5(i32); + +// #[derive(CoercePointee)] +// #[repr(transparent)] +// struct Struct6<#[pointee] T: ?Sized, #[pointee] U: ?Sized>(T, U); + +// #[derive(CoercePointee)] +// #[repr(transparent)] +// struct Struct7(T, U); + +// #[derive(CoercePointee)] +// #[repr(transparent)] +// struct Struct8<#[pointee] T, U: ?Sized>(T); + +// #[derive(CoercePointee)] +// #[repr(transparent)] +// struct Struct9(T); + +// #[derive(CoercePointee)] +// #[repr(transparent)] +// struct Struct9<#[pointee] T, U>(T) where T: ?Sized; +// "#, +// expect![[r#" +// 35..72: `CoercePointee` can only be derived on `struct`s +// 74..114: `CoercePointee` can only be derived on `struct`s with at least one field +// 116..158: `CoercePointee` can only be derived on `struct`s with at least one field +// 160..202: `CoercePointee` can only be derived on `struct`s with at least one field +// 204..258: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]` +// 260..326: `CoercePointee` can only be derived on `struct`s that are generic over at least one type +// 328..439: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits +// 441..530: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits +// 532..621: `derive(CoercePointee)` requires `T` to be marked `?Sized` +// 623..690: `derive(CoercePointee)` requires `T` to be marked `?Sized`"#]], +// ); +// } + +// #[test] +// fn union_derive() { +// check_errors( +// r#" +// //- minicore: clone, copy, default, fmt, hash, ord, eq, derive + +// #[derive(Copy)] +// union Foo1 { _v: () } +// #[derive(Clone)] +// union Foo2 { _v: () } +// #[derive(Default)] +// union Foo3 { _v: () } +// #[derive(Debug)] +// union Foo4 { _v: () } +// #[derive(Hash)] +// union Foo5 { _v: () } +// #[derive(Ord)] +// union Foo6 { _v: () } +// #[derive(PartialOrd)] +// union Foo7 { _v: () } +// #[derive(Eq)] +// union Foo8 { _v: () } +// #[derive(PartialEq)] +// union Foo9 { _v: () } +// "#, +// expect![[r#" +// 78..118: this trait cannot be derived for unions +// 119..157: this trait cannot be derived for unions +// 158..195: this trait cannot be derived for unions +// 196..232: this trait cannot be derived for unions +// 233..276: this trait cannot be derived for unions +// 313..355: this trait cannot be derived for unions"#]], +// ); +// } + +// #[test] +// fn default_enum_without_default_attr() { +// check_errors( +// r#" +// //- minicore: default, derive + +// #[derive(Default)] +// enum Foo { +// Bar, +// } +// "#, +// expect!["1..41: `#[derive(Default)]` on enum with no `#[default]`"], +// ); +// } + +// #[test] +// fn generic_enum_default() { +// check( +// r#" +// //- minicore: default, derive + +// #[derive(Default)] +// enum Foo { +// Bar(T), +// #[default] +// Baz, +// } +// "#, +// expect![[r#" + +// #[derive(Default)] +// enum Foo { +// Bar(T), +// #[default] +// Baz, +// } + +// impl $crate::default::Default for Foo where { +// fn default() -> Self { +// Foo::Baz +// } +// }"#]], +// ); +// } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs index 6f30ca04af8c..bf04a500a57d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs @@ -122,16 +122,16 @@ struct Foo { v4: bool // No comma here } +#[attr1] +#[derive(Bar)] +#[attr2] struct S; #[attr1] #[my_cool_derive()] struct Foo { v1: i32, #[attr3]v2: fn(#[attr4]param2: u32), v3: Foo< { 456 } >, -} -#[attr1] -#[derive(Bar)] -#[attr2] struct S;"#]], +}"#]], ); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 2fac0837de22..8694ebe4e40a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -224,6 +224,8 @@ struct DeferredBuiltinDerive { module_id: ModuleId, depth: usize, container: ItemContainerId, + derive_attr_id: AttrId, + derive_index: u32, } /// Walks the tree of module recursively @@ -1479,10 +1481,10 @@ impl<'db> DefCollector<'db> { let ast_id = ast_id.with_value(ast_adt_id); + let mut derive_call_ids = SmallVec::new(); match attr.parse_path_comma_token_tree(self.db) { Some(derive_macros) => { let call_id = call_id(); - let mut len = 0; for (idx, (path, call_site, _)) in derive_macros.enumerate() { let ast_id = AstIdWithPath::new( file_id, @@ -1505,14 +1507,7 @@ impl<'db> DefCollector<'db> { ); if let Ok((macro_id, def_id, call_id)) = id { - self.def_map.modules[directive.module_id] - .scope - .set_derive_macro_invoc( - ast_id.ast_id, - call_id, - *attr_id, - idx, - ); + derive_call_ids.push(Some(call_id)); // Record its helper attributes. if def_id.krate != self.def_map.krate { let def_map = crate_def_map(self.db, def_id.krate); @@ -1543,11 +1538,14 @@ impl<'db> DefCollector<'db> { module_id: directive.module_id, container: directive.container, depth: directive.depth, + derive_attr_id: *attr_id, + derive_index: idx as u32, }); } else { push_resolved(&mut resolved, directive, call_id); } } else { + derive_call_ids.push(None); self.unresolved_macros.push(MacroDirective { module_id: directive.module_id, depth: directive.depth + 1, @@ -1561,7 +1559,6 @@ impl<'db> DefCollector<'db> { container: directive.container, }); } - len = idx; } // We treat the #[derive] macro as an attribute call, but we do not resolve it for nameres collection. @@ -1570,7 +1567,12 @@ impl<'db> DefCollector<'db> { // Check the comment in [`builtin_attr_macro`]. self.def_map.modules[directive.module_id] .scope - .init_derive_attribute(ast_id, *attr_id, call_id, len + 1); + .init_derive_attribute( + ast_id, + *attr_id, + call_id, + derive_call_ids, + ); } None => { let diag = DefDiagnostic::malformed_derive( @@ -1863,8 +1865,15 @@ impl ModCollector<'_, '_> { let module = &mut def_map.modules[module_id]; for deferred_derive in deferred_derives { crate::builtin_derive::with_derive_traits(deferred_derive.derive, |trait_| { - let impl_id = - BuiltinDeriveImplId::new(db, BuiltinDeriveImplLoc { adt: id, trait_ }); + let impl_id = BuiltinDeriveImplId::new( + db, + BuiltinDeriveImplLoc { + adt: id, + trait_, + derive_attr_id: deferred_derive.derive_attr_id, + derive_index: deferred_derive.derive_index, + }, + ); module.scope.define_builtin_derive_impl(impl_id); }); } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs b/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs index 15d9634cfab6..f3e67d01e566 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/builtin_derive.rs @@ -20,16 +20,18 @@ use crate::{ GenericPredicates, db::HirDatabase, next_solver::{ - Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, StoredEarlyBinder, StoredTy, - TraitRef, Ty, TyKind, fold::fold_tys, generics::Generics, + Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, ParamEnv, StoredEarlyBinder, + StoredTy, TraitRef, Ty, TyKind, fold::fold_tys, generics::Generics, }, }; -fn fake_type_param(adt: AdtId) -> TypeParamId { +fn coerce_pointee_new_type_param(trait_id: TraitId) -> TypeParamId { // HACK: Fake the param. + // We cannot use a dummy param here, because it can leak into the IDE layer and that'll cause panics + // when e.g. trying to display it. So we use an existing param. TypeParamId::from_unchecked(TypeOrConstParamId { - parent: adt.into(), - local_id: la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(u32::MAX)), + parent: trait_id.into(), + local_id: la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(1)), }) } @@ -48,13 +50,35 @@ pub(crate) fn generics_of<'db>(interner: DbInterner<'db>, id: BuiltinDeriveImplI | BuiltinDeriveImplTrait::PartialEq => interner.generics_of(loc.adt.into()), BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { let mut generics = interner.generics_of(loc.adt.into()); - generics.push_param(fake_type_param(loc.adt).into()); + let trait_id = loc + .trait_ + .get_id(interner.lang_items()) + .expect("we don't pass the impl to the solver if we can't resolve the trait"); + generics.push_param(coerce_pointee_new_type_param(trait_id).into()); generics } } } -pub(crate) fn impl_trait<'db>( +pub fn generic_params_count(db: &dyn HirDatabase, id: BuiltinDeriveImplId) -> usize { + let loc = id.loc(db); + let adt_params = GenericParams::new(db, loc.adt.into()); + let extra_params_count = match loc.trait_ { + BuiltinDeriveImplTrait::Copy + | BuiltinDeriveImplTrait::Clone + | BuiltinDeriveImplTrait::Default + | BuiltinDeriveImplTrait::Debug + | BuiltinDeriveImplTrait::Hash + | BuiltinDeriveImplTrait::Ord + | BuiltinDeriveImplTrait::PartialOrd + | BuiltinDeriveImplTrait::Eq + | BuiltinDeriveImplTrait::PartialEq => 0, + BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => 1, + }; + adt_params.len() + extra_params_count +} + +pub fn impl_trait<'db>( interner: DbInterner<'db>, id: BuiltinDeriveImplId, ) -> EarlyBinder<'db, TraitRef<'db>> { @@ -93,7 +117,7 @@ pub(crate) fn impl_trait<'db>( let args = GenericArgs::identity_for_item(interner, loc.adt.into()); let self_ty = Ty::new_adt(interner, loc.adt, args); let Some((pointee_param_idx, _, new_param_ty)) = - coerce_pointee_params(interner, loc, &generic_params) + coerce_pointee_params(interner, loc, &generic_params, trait_id) else { // Malformed derive. return EarlyBinder::bind(TraitRef::new( @@ -110,14 +134,15 @@ pub(crate) fn impl_trait<'db>( } #[salsa::tracked(returns(ref), unsafe(non_update_types))] -pub(crate) fn builtin_derive_predicates<'db>( - db: &'db dyn HirDatabase, - impl_: BuiltinDeriveImplId, -) -> GenericPredicates { +pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) -> GenericPredicates { let loc = impl_.loc(db); let generic_params = GenericParams::new(db, loc.adt.into()); let interner = DbInterner::new_with(db, loc.module(db).krate(db)); let adt_predicates = GenericPredicates::query(db, loc.adt.into()); + let trait_id = loc + .trait_ + .get_id(interner.lang_items()) + .expect("we don't pass the impl to the solver if we can't resolve the trait"); match loc.trait_ { BuiltinDeriveImplTrait::Copy | BuiltinDeriveImplTrait::Clone @@ -127,7 +152,7 @@ pub(crate) fn builtin_derive_predicates<'db>( | BuiltinDeriveImplTrait::PartialOrd | BuiltinDeriveImplTrait::Eq | BuiltinDeriveImplTrait::PartialEq => { - simple_trait_predicates(interner, loc, &generic_params, adt_predicates) + simple_trait_predicates(interner, loc, &generic_params, adt_predicates, trait_id) } BuiltinDeriveImplTrait::Default => { if matches!(loc.adt, AdtId::EnumId(_)) { @@ -137,12 +162,12 @@ pub(crate) fn builtin_derive_predicates<'db>( .store(), )) } else { - simple_trait_predicates(interner, loc, &generic_params, adt_predicates) + simple_trait_predicates(interner, loc, &generic_params, adt_predicates, trait_id) } } BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => { let Some((pointee_param_idx, pointee_param_id, new_param_ty)) = - coerce_pointee_params(interner, loc, &generic_params) + coerce_pointee_params(interner, loc, &generic_params, trait_id) else { // Malformed derive. return GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind( @@ -181,6 +206,12 @@ pub(crate) fn builtin_derive_predicates<'db>( } } +/// Not cached in a query, currently used in `hir` only. If you need this in `hir-ty` consider introducing a query. +pub fn param_env<'db>(interner: DbInterner<'db>, id: BuiltinDeriveImplId) -> ParamEnv<'db> { + let predicates = predicates(interner.db, id); + crate::lower::param_env_from_predicates(interner, predicates) +} + struct MentionsPointee { pointee_param_idx: u32, } @@ -216,11 +247,8 @@ fn simple_trait_predicates<'db>( loc: &BuiltinDeriveImplLoc, generic_params: &GenericParams, adt_predicates: &GenericPredicates, + trait_id: TraitId, ) -> GenericPredicates { - let trait_id = loc - .trait_ - .get_id(interner.lang_items()) - .expect("we don't pass the impl to the solver if we can't resolve the trait"); let extra_predicates = generic_params .iter_type_or_consts() .filter(|(_, data)| matches!(data, TypeOrConstParamData::TypeParamData(_))) @@ -309,6 +337,7 @@ fn coerce_pointee_params<'db>( interner: DbInterner<'db>, loc: &BuiltinDeriveImplLoc, generic_params: &GenericParams, + trait_id: TraitId, ) -> Option<(u32, TypeParamId, Ty<'db>)> { let pointee_param = { if let Ok((pointee_param, _)) = generic_params @@ -339,7 +368,7 @@ fn coerce_pointee_params<'db>( let pointee_param_idx = pointee_param.into_raw().into_u32() + (generic_params.len_lifetimes() as u32); let new_param_idx = generic_params.len() as u32; - let new_param_id = fake_type_param(loc.adt); + let new_param_id = coerce_pointee_new_type_param(trait_id); let new_param_ty = Ty::new_param(interner, new_param_id, new_param_idx); Some((pointee_param_idx, pointee_param_id, new_param_ty)) } @@ -352,11 +381,7 @@ mod tests { use stdx::format_to; use test_fixture::WithFixture; - use crate::{ - builtin_derive::{builtin_derive_predicates, impl_trait}, - next_solver::DbInterner, - test_db::TestDB, - }; + use crate::{builtin_derive::impl_trait, next_solver::DbInterner, test_db::TestDB}; fn check_trait_refs(#[rust_analyzer::rust_fixture] ra_fixture: &str, expectation: Expect) { let db = TestDB::with_files(ra_fixture); @@ -384,8 +409,7 @@ mod tests { let mut predicates = String::new(); for (_, module) in def_map.modules() { for derive in module.scope.builtin_derive_impls() { - let preds = - builtin_derive_predicates(&db, derive).all_predicates().skip_binder(); + let preds = super::predicates(&db, derive).all_predicates().skip_binder(); format_to!( predicates, "{}\n\n", diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs index 8816e13ba7b6..08f201fea90b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs @@ -1568,6 +1568,7 @@ const GOAL: u8 = { } #[test] +#[ignore = "builtin derive macros are currently not working with MIR eval"] fn builtin_derive_macro() { check_number( r#" diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index f0f65eedbce9..70474fc46919 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -2,10 +2,12 @@ //! type inference-related queries. use base_db::{Crate, target::TargetLoadError}; +use either::Either; use hir_def::{ - AdtId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, - GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, VariantId, - db::DefDatabase, hir::ExprId, layout::TargetDataLayout, + AdtId, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId, + FunctionId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, + TypeAliasId, VariantId, builtin_derive::BuiltinDeriveImplMethod, db::DefDatabase, hir::ExprId, + layout::TargetDataLayout, }; use la_arena::ArenaMap; use salsa::plumbing::AsId; @@ -83,7 +85,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { env: ParamEnvAndCrate<'db>, func: FunctionId, fn_subst: GenericArgs<'db>, - ) -> (FunctionId, GenericArgs<'db>); + ) -> (Either, GenericArgs<'db>); // endregion:mir diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index b9e23464e980..efce9ab1f126 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -7,7 +7,7 @@ use std::{ mem, }; -use base_db::Crate; +use base_db::{Crate, FxIndexMap}; use either::Either; use hir_def::{ FindPathConfig, GenericDefId, HasModule, LocalFieldId, Lookup, ModuleDefId, ModuleId, TraitId, @@ -143,11 +143,11 @@ impl<'db> BoundsFormattingCtx<'db> { } impl<'db> HirFormatter<'_, 'db> { - fn start_location_link(&mut self, location: ModuleDefId) { + pub fn start_location_link(&mut self, location: ModuleDefId) { self.fmt.start_location_link(location); } - fn end_location_link(&mut self) { + pub fn end_location_link(&mut self) { self.fmt.end_location_link(); } @@ -1978,6 +1978,49 @@ fn write_bounds_like_dyn_trait<'db>( Ok(()) } +pub fn write_params_bounds<'db>( + f: &mut HirFormatter<'_, 'db>, + predicates: &[Clause<'db>], +) -> Result { + // Use an FxIndexMap to keep user's order, as far as possible. + let mut per_type = FxIndexMap::<_, Vec<_>>::default(); + for &predicate in predicates { + let base_ty = match predicate.kind().skip_binder() { + ClauseKind::Trait(clause) => Either::Left(clause.self_ty()), + ClauseKind::RegionOutlives(clause) => Either::Right(clause.0), + ClauseKind::TypeOutlives(clause) => Either::Left(clause.0), + ClauseKind::Projection(clause) => Either::Left(clause.self_ty()), + ClauseKind::ConstArgHasType(..) + | ClauseKind::WellFormed(_) + | ClauseKind::ConstEvaluatable(_) + | ClauseKind::HostEffect(..) + | ClauseKind::UnstableFeature(_) => continue, + }; + per_type.entry(base_ty).or_default().push(predicate); + } + + for (base_ty, clauses) in per_type { + f.write_str(" ")?; + match base_ty { + Either::Left(it) => it.hir_fmt(f)?, + Either::Right(it) => it.hir_fmt(f)?, + } + f.write_str(": ")?; + // Rudimentary approximation: type params are `Sized` by default, everything else not. + // FIXME: This is not correct, really. But I'm not sure how we can from the ty representation + // to extract the default sizedness, and if it's possible at all. + let default_sized = match base_ty { + Either::Left(ty) if matches!(ty.kind(), TyKind::Param(_)) => { + SizedByDefault::Sized { anchor: f.krate() } + } + _ => SizedByDefault::NotSized, + }; + write_bounds_like_dyn_trait(f, base_ty, &clauses, default_sized)?; + f.write_str(",\n")?; + } + Ok(()) +} + impl<'db> HirDisplay<'db> for TraitRef<'db> { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { let trait_ = self.def_id.0; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 7b414cd55174..373862229bd1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -25,7 +25,7 @@ extern crate ra_ap_rustc_next_trait_solver as rustc_next_trait_solver; extern crate self as hir_ty; -mod builtin_derive; +pub mod builtin_derive; mod infer; mod inhabitedness; mod lower; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index ebbf29e6ff46..9307868f3982 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -1855,6 +1855,20 @@ pub(crate) fn trait_environment_for_body_query( db.trait_environment(def) } +pub(crate) fn param_env_from_predicates<'db>( + interner: DbInterner<'db>, + predicates: &'db GenericPredicates, +) -> ParamEnv<'db> { + let clauses = rustc_type_ir::elaborate::elaborate( + interner, + predicates.all_predicates().iter_identity_copied(), + ); + let clauses = Clauses::new_from_iter(interner, clauses); + + // FIXME: We should normalize projections here, like rustc does. + ParamEnv { clauses } +} + pub(crate) fn trait_environment<'db>(db: &'db dyn HirDatabase, def: GenericDefId) -> ParamEnv<'db> { return ParamEnv { clauses: trait_environment_query(db, def).as_ref() }; @@ -1865,13 +1879,8 @@ pub(crate) fn trait_environment<'db>(db: &'db dyn HirDatabase, def: GenericDefId ) -> StoredClauses { let module = def.module(db); let interner = DbInterner::new_with(db, module.krate(db)); - let predicates = GenericPredicates::query_all(db, def); - let clauses = - rustc_type_ir::elaborate::elaborate(interner, predicates.iter_identity_copied()); - let clauses = Clauses::new_from_iter(interner, clauses); - - // FIXME: We should normalize projections here, like rustc does. - clauses.store() + let predicates = GenericPredicates::query(db, def); + param_env_from_predicates(interner, predicates).clauses.store() } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index 88f48fdbc67a..50dbd87d693e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -16,6 +16,7 @@ use hir_def::{ AssocItemId, BlockId, BuiltinDeriveImplId, ConstId, FunctionId, GenericParamId, HasModule, ImplId, ItemContainerId, ModuleId, TraitId, attrs::AttrFlags, + builtin_derive::BuiltinDeriveImplMethod, expr_store::path::GenericArgs as HirGenericArgs, hir::ExprId, lang_item::LangItems, @@ -372,9 +373,13 @@ pub fn lookup_impl_const<'db>( }; lookup_impl_assoc_item_for_trait_ref(infcx, trait_ref, env, name) - .and_then( - |assoc| if let (AssocItemId::ConstId(id), s) = assoc { Some((id, s)) } else { None }, - ) + .and_then(|assoc| { + if let (Either::Left(AssocItemId::ConstId(id)), s) = assoc { + Some((id, s)) + } else { + None + } + }) .unwrap_or((const_id, subs)) } @@ -420,12 +425,12 @@ pub(crate) fn lookup_impl_method_query<'db>( env: ParamEnvAndCrate<'db>, func: FunctionId, fn_subst: GenericArgs<'db>, -) -> (FunctionId, GenericArgs<'db>) { +) -> (Either, GenericArgs<'db>) { let interner = DbInterner::new_with(db, env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let ItemContainerId::TraitId(trait_id) = func.loc(db).container else { - return (func, fn_subst); + return (Either::Left(func), fn_subst); }; let trait_params = db.generic_params(trait_id.into()).len(); let trait_ref = TraitRef::new_from_args( @@ -435,16 +440,19 @@ pub(crate) fn lookup_impl_method_query<'db>( ); let name = &db.function_signature(func).name; - let Some((impl_fn, impl_subst)) = lookup_impl_assoc_item_for_trait_ref( - &infcx, - trait_ref, - env.param_env, - name, - ) - .and_then(|assoc| { - if let (AssocItemId::FunctionId(id), subst) = assoc { Some((id, subst)) } else { None } - }) else { - return (func, fn_subst); + let Some((impl_fn, impl_subst)) = + lookup_impl_assoc_item_for_trait_ref(&infcx, trait_ref, env.param_env, name).and_then( + |(assoc, impl_args)| { + let assoc = match assoc { + Either::Left(AssocItemId::FunctionId(id)) => Either::Left(id), + Either::Right(it) => Either::Right(it), + _ => return None, + }; + Some((assoc, impl_args)) + }, + ) + else { + return (Either::Left(func), fn_subst); }; ( @@ -461,11 +469,18 @@ fn lookup_impl_assoc_item_for_trait_ref<'db>( trait_ref: TraitRef<'db>, env: ParamEnv<'db>, name: &Name, -) -> Option<(AssocItemId, GenericArgs<'db>)> { +) -> Option<(Either, GenericArgs<'db>)> +{ let (impl_id, impl_subst) = find_matching_impl(infcx, env, trait_ref)?; - let AnyImplId::ImplId(impl_id) = impl_id else { - // FIXME: Handle resolution to builtin derive. - return None; + let impl_id = match impl_id { + AnyImplId::ImplId(it) => it, + AnyImplId::BuiltinDeriveImplId(impl_) => { + return impl_ + .loc(infcx.interner.db) + .trait_ + .get_method(name.symbol()) + .map(|method| (Either::Right((impl_, method)), impl_subst)); + } }; let item = impl_id.impl_items(infcx.interner.db).items.iter().find_map(|(n, it)| match *it { @@ -473,7 +488,7 @@ fn lookup_impl_assoc_item_for_trait_ref<'db>( AssocItemId::ConstId(c) => (n == name).then_some(AssocItemId::ConstId(c)), AssocItemId::TypeAliasId(_) => None, })?; - Some((item, impl_subst)) + Some((Either::Left(item), impl_subst)) } pub(crate) fn find_matching_impl<'db>( @@ -793,19 +808,29 @@ impl TraitImpls { .unwrap_or_default() } - pub fn for_trait(&self, trait_: TraitId, mut callback: impl FnMut(&[ImplId])) { + pub fn for_trait( + &self, + trait_: TraitId, + mut callback: impl FnMut(Either<&[ImplId], &[BuiltinDeriveImplId]>), + ) { if let Some(impls) = self.map.get(&trait_) { - callback(&impls.blanket_impls); + callback(Either::Left(&impls.blanket_impls)); for impls in impls.non_blanket_impls.values() { - callback(&impls.0); + callback(Either::Left(&impls.0)); + callback(Either::Right(&impls.1)); } } } - pub fn for_self_ty(&self, self_ty: &SimplifiedType, mut callback: impl FnMut(&[ImplId])) { + pub fn for_self_ty( + &self, + self_ty: &SimplifiedType, + mut callback: impl FnMut(Either<&[ImplId], &[BuiltinDeriveImplId]>), + ) { for for_trait in self.map.values() { if let Some(for_ty) = for_trait.non_blanket_impls.get(self_ty) { - callback(&for_ty.0); + callback(Either::Left(&for_ty.0)); + callback(Either::Right(&for_ty.1)); } } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs index c7156bb11ed6..cd860700c12f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs @@ -77,12 +77,14 @@ macro_rules! from_bytes { }).into()) }; } +use from_bytes; macro_rules! not_supported { ($it: expr) => { - return Err(MirEvalError::NotSupported(format!($it))) + return Err($crate::mir::eval::MirEvalError::NotSupported(format!($it))) }; } +use not_supported; #[derive(Debug, Default, Clone, PartialEq, Eq, GenericTypeVisitable)] pub struct VTableMap<'db> { @@ -2622,6 +2624,9 @@ impl<'db> Evaluator<'db> { def, generic_args, ); + let Either::Left(imp) = imp else { + not_supported!("evaluating builtin derive impls is not supported") + }; let mir_body = self .db diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs index a47a8c440007..76c8701ea209 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs @@ -16,29 +16,14 @@ use crate::{ mir::eval::{ Address, AdtId, Arc, Evaluator, FunctionId, GenericArgs, HasModule, HirDisplay, InternedClosure, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, Layout, Locals, - Lookup, MirEvalError, MirSpan, Mutability, Result, Ty, TyKind, pad16, + Lookup, MirEvalError, MirSpan, Mutability, Result, Ty, TyKind, from_bytes, not_supported, + pad16, }, next_solver::Region, }; mod simd; -macro_rules! from_bytes { - ($ty:tt, $value:expr) => { - ($ty::from_le_bytes(match ($value).try_into() { - Ok(it) => it, - #[allow(unreachable_patterns)] - Err(_) => return Err(MirEvalError::InternalError("mismatched size".into())), - })) - }; -} - -macro_rules! not_supported { - ($it: expr) => { - return Err(MirEvalError::NotSupported(format!($it))) - }; -} - #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum EvalLangItem { BeginPanic, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs index 3896917cab1a..e0b3e571b856 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs @@ -6,21 +6,6 @@ use crate::consteval::try_const_usize; use super::*; -macro_rules! from_bytes { - ($ty:tt, $value:expr) => { - ($ty::from_le_bytes(match ($value).try_into() { - Ok(it) => it, - Err(_) => return Err(MirEvalError::InternalError("mismatched size".into())), - })) - }; -} - -macro_rules! not_supported { - ($it: expr) => { - return Err(MirEvalError::NotSupported(format!($it))) - }; -} - impl<'db> Evaluator<'db> { fn detect_simd_ty(&self, ty: Ty<'db>) -> Result<'db, (usize, Ty<'db>)> { match ty.kind() { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/format_proof_tree.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/format_proof_tree.rs index 59fb0d65c5e2..66da6d540082 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/format_proof_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/format_proof_tree.rs @@ -1,8 +1,8 @@ use rustc_type_ir::{solve::GoalSource, solve::inspect::GoalEvaluation}; use serde_derive::{Deserialize, Serialize}; -use crate::next_solver::infer::InferCtxt; use crate::next_solver::inspect::{InspectCandidate, InspectGoal}; +use crate::next_solver::{AnyImplId, infer::InferCtxt}; use crate::next_solver::{DbInterner, Span}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -76,14 +76,31 @@ impl<'a, 'db> ProofTreeSerializer<'a, 'db> { use rustc_type_ir::solve::inspect::ProbeKind; match candidate.kind() { ProbeKind::TraitCandidate { source, .. } => { + use hir_def::{Lookup, src::HasSource}; use rustc_type_ir::solve::CandidateSource; + let db = self.infcx.interner.db; match source { - CandidateSource::Impl(impl_def_id) => { - use hir_def::{Lookup, src::HasSource}; - let db = self.infcx.interner.db; - let impl_src = impl_def_id.0.lookup(db).source(db); - Some(impl_src.value.to_string()) - } + CandidateSource::Impl(impl_def_id) => match impl_def_id { + AnyImplId::ImplId(impl_def_id) => { + let impl_src = impl_def_id.lookup(db).source(db); + Some(impl_src.value.to_string()) + } + AnyImplId::BuiltinDeriveImplId(impl_id) => { + let impl_loc = impl_id.loc(db); + let adt_src = match impl_loc.adt { + hir_def::AdtId::StructId(adt) => { + adt.loc(db).source(db).value.to_string() + } + hir_def::AdtId::UnionId(adt) => { + adt.loc(db).source(db).value.to_string() + } + hir_def::AdtId::EnumId(adt) => { + adt.loc(db).source(db).value.to_string() + } + }; + Some(format!("#[derive(${})]\n{}", impl_loc.trait_.name(), adt_src)) + } + }, _ => None, } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 269474e0153e..2a3df1d32a30 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -2370,7 +2370,7 @@ impl<'db> DbInterner<'db> { fn predicates_of(db: &dyn HirDatabase, def_id: SolverDefId) -> &GenericPredicates { if let SolverDefId::BuiltinDeriveImplId(impl_) = def_id { - crate::builtin_derive::builtin_derive_predicates(db, impl_) + crate::builtin_derive::predicates(db, impl_) } else { GenericPredicates::query(db, def_id.try_into().unwrap()) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index ea33c9bcd4f1..1457bb2e1017 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -539,7 +539,7 @@ impl SomeStruct { "AttrFlags::query_", "AttrFlags::query_", "AttrFlags::query_", - "impl_trait_with_diagnostics_shim", + "impl_trait_with_diagnostics_query", "impl_signature_shim", "impl_signature_with_source_map_shim", "impl_self_ty_with_diagnostics_query", diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs index d1056f31e19e..cba1b39e5254 100644 --- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs @@ -35,6 +35,8 @@ pub enum AttrsOwner { Field(FieldId), LifetimeParam(LifetimeParamId), TypeOrConstParam(TypeOrConstParamId), + /// Things that do not have attributes. Used for builtin derives. + Dummy, } impl AttrsOwner { @@ -123,7 +125,9 @@ impl AttrsWithOwner { let owner = match self.owner { AttrsOwner::AttrDef(it) => Either::Left(it), AttrsOwner::Field(it) => Either::Right(it), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => return &[], + AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) | AttrsOwner::Dummy => { + return &[]; + } }; self.attrs.doc_aliases(db, owner) } @@ -133,7 +137,9 @@ impl AttrsWithOwner { let owner = match self.owner { AttrsOwner::AttrDef(it) => Either::Left(it), AttrsOwner::Field(it) => Either::Right(it), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => return None, + AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) | AttrsOwner::Dummy => { + return None; + } }; self.attrs.cfgs(db, owner) } @@ -143,7 +149,9 @@ impl AttrsWithOwner { match self.owner { AttrsOwner::AttrDef(it) => AttrFlags::docs(db, it).as_deref(), AttrsOwner::Field(it) => AttrFlags::field_docs(db, it), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => None, + AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) | AttrsOwner::Dummy => { + None + } } } } @@ -156,6 +164,9 @@ pub trait HasAttrs: Sized { AttrsOwner::Field(it) => AttrsWithOwner::new_field(db, it), AttrsOwner::LifetimeParam(it) => AttrsWithOwner::new_lifetime_param(db, it), AttrsOwner::TypeOrConstParam(it) => AttrsWithOwner::new_type_or_const_param(db, it), + AttrsOwner::Dummy => { + AttrsWithOwner { attrs: AttrFlags::empty(), owner: AttrsOwner::Dummy } + } } } @@ -167,7 +178,9 @@ pub trait HasAttrs: Sized { match self.attr_id(db) { AttrsOwner::AttrDef(it) => AttrFlags::docs(db, it).as_deref(), AttrsOwner::Field(it) => AttrFlags::field_docs(db, it), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => None, + AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) | AttrsOwner::Dummy => { + None + } } } } @@ -190,12 +203,28 @@ impl_has_attrs![ (Trait, TraitId), (TypeAlias, TypeAliasId), (Macro, MacroId), - (Function, FunctionId), (Adt, AdtId), - (Impl, ImplId), (ExternCrateDecl, ExternCrateId), ]; +impl HasAttrs for Function { + fn attr_id(self, _db: &dyn HirDatabase) -> AttrsOwner { + match self.id { + crate::AnyFunctionId::FunctionId(id) => AttrsOwner::AttrDef(id.into()), + crate::AnyFunctionId::BuiltinDeriveImplMethod { .. } => AttrsOwner::Dummy, + } + } +} + +impl HasAttrs for Impl { + fn attr_id(self, _db: &dyn HirDatabase) -> AttrsOwner { + match self.id { + hir_ty::next_solver::AnyImplId::ImplId(id) => AttrsOwner::AttrDef(id.into()), + hir_ty::next_solver::AnyImplId::BuiltinDeriveImplId(..) => AttrsOwner::Dummy, + } + } +} + macro_rules! impl_has_attrs_enum { ($($variant:ident),* for $enum:ident) => {$( impl HasAttrs for $variant { @@ -294,7 +323,9 @@ fn resolve_doc_path_on_( AttrsOwner::AttrDef(AttrDefId::MacroId(it)) => it.resolver(db), AttrsOwner::AttrDef(AttrDefId::ExternCrateId(it)) => it.resolver(db), AttrsOwner::Field(it) => it.parent.resolver(db), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => return None, + AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) | AttrsOwner::Dummy => { + return None; + } }; let mut modpath = doc_modpath_from_str(link)?; diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index d0d8c4877d21..1f9af564c359 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir/src/display.rs @@ -2,19 +2,22 @@ use either::Either; use hir_def::{ - AdtId, GenericDefId, + AdtId, BuiltinDeriveImplId, FunctionId, GenericDefId, ImplId, ItemContainerId, + builtin_derive::BuiltinDeriveImplMethod, expr_store::ExpressionStore, hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate}, item_tree::FieldsShape, signatures::{StaticFlags, TraitFlags}, type_ref::{TypeBound, TypeRef, TypeRefId}, }; +use hir_expand::name::Name; use hir_ty::{ GenericPredicates, db::HirDatabase, display::{ HirDisplay, HirDisplayWithExpressionStore, HirFormatter, Result, SizedByDefault, - hir_display_with_store, write_bounds_like_dyn_trait_with_prefix, write_visibility, + hir_display_with_store, write_bounds_like_dyn_trait_with_prefix, write_params_bounds, + write_visibility, }, next_solver::ClauseKind, }; @@ -22,25 +25,78 @@ use itertools::Itertools; use rustc_type_ir::inherent::IntoKind; use crate::{ - Adt, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum, + Adt, AnyFunctionId, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum, ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, LifetimeParam, Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, TupleField, Type, TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, Variant, }; +fn write_builtin_derive_impl_method<'db>( + f: &mut HirFormatter<'_, 'db>, + impl_: BuiltinDeriveImplId, + method: BuiltinDeriveImplMethod, +) -> Result { + let db = f.db; + let loc = impl_.loc(db); + let (adt_params, _adt_params_store) = db.generic_params_and_store(loc.adt.into()); + + if f.show_container_bounds() && !adt_params.is_empty() { + f.write_str("impl")?; + write_generic_params(loc.adt.into(), f)?; + f.write_char(' ')?; + let trait_id = loc.trait_.get_id(f.lang_items()); + if let Some(trait_id) = trait_id { + f.start_location_link(trait_id.into()); + } + write!(f, "{}", Name::new_symbol_root(loc.trait_.name()).display(db, f.edition()))?; + if trait_id.is_some() { + f.end_location_link(); + } + f.write_str(" for ")?; + f.start_location_link(loc.adt.into()); + write!(f, "{}", Adt::from(loc.adt).name(db).display(db, f.edition()))?; + f.end_location_link(); + write_generic_args(loc.adt.into(), f)?; + f.write_char('\n')?; + } + + let Some(trait_method) = method.trait_method(db, impl_) else { + return write!(f, "fn {}(…)", method.name()); + }; + let has_written_where = write_function(f, trait_method)?; + + if f.show_container_bounds() && !adt_params.is_empty() { + if !has_written_where { + f.write_str("\nwhere")? + } + write!(f, "\n // Bounds from impl:")?; + + let predicates = + hir_ty::builtin_derive::predicates(db, impl_).explicit_predicates().skip_binder(); + write_params_bounds(f, predicates)?; + } + + Ok(()) +} + impl<'db> HirDisplay<'db> for Function { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { + let id = match self.id { + AnyFunctionId::FunctionId(id) => id, + AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } => { + return write_builtin_derive_impl_method(f, impl_, method); + } + }; + let db = f.db; - let data = db.function_signature(self.id); - let container = self.as_assoc_item(db).map(|it| it.container(db)); - let mut module = self.module(db); + let container = id.loc(db).container; // Write container (trait or impl) let container_params = match container { - Some(AssocItemContainer::Trait(trait_)) => { - let (params, params_store) = f.db.generic_params_and_store(trait_.id.into()); + ItemContainerId::TraitId(trait_) => { + let (params, params_store) = f.db.generic_params_and_store(trait_.into()); if f.show_container_bounds() && !params.is_empty() { - write_trait_header(&trait_, f)?; + write_trait_header(trait_.into(), f)?; f.write_char('\n')?; has_disaplayable_predicates(f.db, ¶ms, ¶ms_store) .then_some((params, params_store)) @@ -48,10 +104,10 @@ impl<'db> HirDisplay<'db> for Function { None } } - Some(AssocItemContainer::Impl(impl_)) => { - let (params, params_store) = f.db.generic_params_and_store(impl_.id.into()); + ItemContainerId::ImplId(impl_) => { + let (params, params_store) = f.db.generic_params_and_store(impl_.into()); if f.show_container_bounds() && !params.is_empty() { - write_impl_header(&impl_, f)?; + write_impl_header(impl_, f)?; f.write_char('\n')?; has_disaplayable_predicates(f.db, ¶ms, ¶ms_store) .then_some((params, params_store)) @@ -59,124 +115,20 @@ impl<'db> HirDisplay<'db> for Function { None } } - None => None, + _ => None, }; // Write signature of the function - // Block-local impls are "hoisted" to the nearest (non-block) module. - if let Some(AssocItemContainer::Impl(_)) = container { - module = module.nearest_non_block_module(db); - } - let module_id = module.id; - - write_visibility(module_id, self.visibility(db), f)?; - - if data.is_default() { - f.write_str("default ")?; - } - if data.is_const() { - f.write_str("const ")?; - } - if data.is_async() { - f.write_str("async ")?; - } - // FIXME: This will show `unsafe` for functions that are `#[target_feature]` but not unsafe - // (they are conditionally unsafe to call). We probably should show something else. - if self.is_unsafe_to_call(db, None, f.edition()) { - f.write_str("unsafe ")?; - } - if let Some(abi) = &data.abi { - write!(f, "extern \"{}\" ", abi.as_str())?; - } - write!(f, "fn {}", data.name.display(f.db, f.edition()))?; - - write_generic_params(GenericDefId::FunctionId(self.id), f)?; - - f.write_char('(')?; - - let mut first = true; - let mut skip_self = 0; - if let Some(self_param) = self.self_param(db) { - self_param.hir_fmt(f)?; - first = false; - skip_self = 1; - } - - // FIXME: Use resolved `param.ty` once we no longer discard lifetimes - let body = db.body(self.id.into()); - for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) { - if !first { - f.write_str(", ")?; - } else { - first = false; - } - - let pat_id = body.params[param.idx - body.self_param.is_some() as usize]; - let pat_str = body.pretty_print_pat(db, self.id.into(), pat_id, true, f.edition()); - f.write_str(&pat_str)?; - - f.write_str(": ")?; - type_ref.hir_fmt(f, &data.store)?; - } - - if data.is_varargs() { - if !first { - f.write_str(", ")?; - } - f.write_str("...")?; - } - - f.write_char(')')?; - - // `FunctionData::ret_type` will be `::core::future::Future` for async fns. - // Use ugly pattern match to strip the Future trait. - // Better way? - let ret_type = if !data.is_async() { - data.ret_type - } else if let Some(ret_type) = data.ret_type { - match &data.store[ret_type] { - TypeRef::ImplTrait(bounds) => match &bounds[0] { - &TypeBound::Path(path, _) => Some( - *data.store[path] - .segments() - .iter() - .last() - .unwrap() - .args_and_bindings - .unwrap() - .bindings[0] - .type_ref - .as_ref() - .unwrap(), - ), - _ => None, - }, - _ => None, - } - } else { - None - }; - - if let Some(ret_type) = ret_type { - match &data.store[ret_type] { - TypeRef::Tuple(tup) if tup.is_empty() => {} - _ => { - f.write_str(" -> ")?; - ret_type.hir_fmt(f, &data.store)?; - } - } - } - - // Write where clauses - let has_written_where = write_where_clause(GenericDefId::FunctionId(self.id), f)?; + let has_written_where = write_function(f, id)?; if let Some((container_params, container_params_store)) = container_params { if !has_written_where { f.write_str("\nwhere")?; } - let container_name = match container.unwrap() { - AssocItemContainer::Trait(_) => "trait", - AssocItemContainer::Impl(_) => "impl", + let container_name = match container { + ItemContainerId::TraitId(_) => "trait", + ItemContainerId::ImplId(_) => "impl", + _ => unreachable!(), }; write!(f, "\n // Bounds from {container_name}:",)?; write_where_predicates(&container_params, &container_params_store, f)?; @@ -185,14 +137,129 @@ impl<'db> HirDisplay<'db> for Function { } } -fn write_impl_header<'db>(impl_: &Impl, f: &mut HirFormatter<'_, 'db>) -> Result { +fn write_function<'db>(f: &mut HirFormatter<'_, 'db>, func_id: FunctionId) -> Result { + let db = f.db; + let func = Function::from(func_id); + let data = db.function_signature(func_id); + + let mut module = func.module(db); + // Block-local impls are "hoisted" to the nearest (non-block) module. + if let ItemContainerId::ImplId(_) = func_id.loc(db).container { + module = module.nearest_non_block_module(db); + } + let module_id = module.id; + + write_visibility(module_id, func.visibility(db), f)?; + + if data.is_default() { + f.write_str("default ")?; + } + if data.is_const() { + f.write_str("const ")?; + } + if data.is_async() { + f.write_str("async ")?; + } + // FIXME: This will show `unsafe` for functions that are `#[target_feature]` but not unsafe + // (they are conditionally unsafe to call). We probably should show something else. + if func.is_unsafe_to_call(db, None, f.edition()) { + f.write_str("unsafe ")?; + } + if let Some(abi) = &data.abi { + write!(f, "extern \"{}\" ", abi.as_str())?; + } + write!(f, "fn {}", data.name.display(f.db, f.edition()))?; + + write_generic_params(GenericDefId::FunctionId(func_id), f)?; + + f.write_char('(')?; + + let mut first = true; + let mut skip_self = 0; + if let Some(self_param) = func.self_param(db) { + self_param.hir_fmt(f)?; + first = false; + skip_self = 1; + } + + // FIXME: Use resolved `param.ty` once we no longer discard lifetimes + let body = db.body(func_id.into()); + for (type_ref, param) in data.params.iter().zip(func.assoc_fn_params(db)).skip(skip_self) { + if !first { + f.write_str(", ")?; + } else { + first = false; + } + + let pat_id = body.params[param.idx - body.self_param.is_some() as usize]; + let pat_str = body.pretty_print_pat(db, func_id.into(), pat_id, true, f.edition()); + f.write_str(&pat_str)?; + + f.write_str(": ")?; + type_ref.hir_fmt(f, &data.store)?; + } + + if data.is_varargs() { + if !first { + f.write_str(", ")?; + } + f.write_str("...")?; + } + + f.write_char(')')?; + + // `FunctionData::ret_type` will be `::core::future::Future` for async fns. + // Use ugly pattern match to strip the Future trait. + // Better way? + let ret_type = if !data.is_async() { + data.ret_type + } else if let Some(ret_type) = data.ret_type { + match &data.store[ret_type] { + TypeRef::ImplTrait(bounds) => match &bounds[0] { + &TypeBound::Path(path, _) => Some( + *data.store[path] + .segments() + .iter() + .last() + .unwrap() + .args_and_bindings + .unwrap() + .bindings[0] + .type_ref + .as_ref() + .unwrap(), + ), + _ => None, + }, + _ => None, + } + } else { + None + }; + + if let Some(ret_type) = ret_type { + match &data.store[ret_type] { + TypeRef::Tuple(tup) if tup.is_empty() => {} + _ => { + f.write_str(" -> ")?; + ret_type.hir_fmt(f, &data.store)?; + } + } + } + + // Write where clauses + let has_written_where = write_where_clause(GenericDefId::FunctionId(func_id), f)?; + Ok(has_written_where) +} + +fn write_impl_header<'db>(impl_: ImplId, f: &mut HirFormatter<'_, 'db>) -> Result { let db = f.db; f.write_str("impl")?; - let def_id = GenericDefId::ImplId(impl_.id); + let def_id = GenericDefId::ImplId(impl_); write_generic_params(def_id, f)?; - let impl_data = db.impl_signature(impl_.id); + let impl_data = db.impl_signature(impl_); if let Some(target_trait) = &impl_data.target_trait { f.write_char(' ')?; hir_display_with_store(&impl_data.store[target_trait.path], &impl_data.store).hir_fmt(f)?; @@ -200,14 +267,28 @@ fn write_impl_header<'db>(impl_: &Impl, f: &mut HirFormatter<'_, 'db>) -> Result } f.write_char(' ')?; - impl_.self_ty(db).hir_fmt(f)?; + Impl::from(impl_).self_ty(db).hir_fmt(f)?; Ok(()) } impl<'db> HirDisplay<'db> for SelfParam { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { - let data = f.db.function_signature(self.func); + let func = match self.func.id { + AnyFunctionId::FunctionId(id) => id, + AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => match method { + BuiltinDeriveImplMethod::clone + | BuiltinDeriveImplMethod::fmt + | BuiltinDeriveImplMethod::hash + | BuiltinDeriveImplMethod::cmp + | BuiltinDeriveImplMethod::partial_cmp + | BuiltinDeriveImplMethod::eq => return f.write_str("&self"), + BuiltinDeriveImplMethod::default => { + unreachable!("this trait method does not have a self param") + } + }, + }; + let data = f.db.function_signature(func); let param = *data.params.first().unwrap(); match &data.store[param] { TypeRef::Path(p) if p.is_self_type() => f.write_str("self"), @@ -553,6 +634,18 @@ impl<'db> HirDisplay<'db> for ConstParam { } fn write_generic_params<'db>(def: GenericDefId, f: &mut HirFormatter<'_, 'db>) -> Result { + write_generic_params_or_args(def, f, true) +} + +fn write_generic_args<'db>(def: GenericDefId, f: &mut HirFormatter<'_, 'db>) -> Result { + write_generic_params_or_args(def, f, false) +} + +fn write_generic_params_or_args<'db>( + def: GenericDefId, + f: &mut HirFormatter<'_, 'db>, + include_defaults: bool, +) -> Result { let (params, store) = f.db.generic_params_and_store(def); if params.iter_lt().next().is_none() && params.iter_type_or_consts().all(|it| it.1.const_param().is_none()) @@ -587,7 +680,7 @@ fn write_generic_params<'db>(def: GenericDefId, f: &mut HirFormatter<'_, 'db>) - } delim(f)?; write!(f, "{}", name.display(f.db, f.edition()))?; - if let Some(default) = &ty.default { + if include_defaults && let Some(default) = &ty.default { f.write_str(" = ")?; default.hir_fmt(f, &store)?; } @@ -597,7 +690,7 @@ fn write_generic_params<'db>(def: GenericDefId, f: &mut HirFormatter<'_, 'db>) - write!(f, "const {}: ", name.display(f.db, f.edition()))?; c.ty.hir_fmt(f, &store)?; - if let Some(default) = &c.default { + if include_defaults && let Some(default) = &c.default { f.write_str(" = ")?; default.hir_fmt(f, &store)?; } @@ -746,7 +839,7 @@ impl<'db> HirDisplay<'db> for TraitRef<'db> { impl<'db> HirDisplay<'db> for Trait { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { // FIXME(trait-alias) needs special handling to print the equal sign - write_trait_header(self, f)?; + write_trait_header(*self, f)?; let def_id = GenericDefId::TraitId(self.id); let has_where_clause = write_where_clause(def_id, f)?; @@ -783,7 +876,7 @@ impl<'db> HirDisplay<'db> for Trait { } } -fn write_trait_header<'db>(trait_: &Trait, f: &mut HirFormatter<'_, 'db>) -> Result { +fn write_trait_header<'db>(trait_: Trait, f: &mut HirFormatter<'_, 'db>) -> Result { write_visibility(trait_.module(f.db).id, trait_.visibility(f.db), f)?; let data = f.db.trait_signature(trait_.id); if data.flags.contains(TraitFlags::UNSAFE) { diff --git a/src/tools/rust-analyzer/crates/hir/src/from_id.rs b/src/tools/rust-analyzer/crates/hir/src/from_id.rs index bc025c5ef5cf..fc20f4b46bb9 100644 --- a/src/tools/rust-analyzer/crates/hir/src/from_id.rs +++ b/src/tools/rust-analyzer/crates/hir/src/from_id.rs @@ -4,14 +4,15 @@ //! are splitting the hir. use hir_def::{ - AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, GenericDefId, GenericParamId, - ModuleDefId, VariantId, + AdtId, AssocItemId, BuiltinDeriveImplId, DefWithBodyId, EnumVariantId, FieldId, GenericDefId, + GenericParamId, ModuleDefId, VariantId, hir::{BindingId, LabelId}, }; +use hir_ty::next_solver::AnyImplId; use crate::{ - Adt, AssocItem, BuiltinType, DefWithBody, Field, GenericDef, GenericParam, ItemInNs, Label, - Local, ModuleDef, Variant, VariantDef, + Adt, AnyFunctionId, AssocItem, BuiltinType, DefWithBody, Field, GenericDef, GenericParam, + ItemInNs, Label, Local, ModuleDef, Variant, VariantDef, }; macro_rules! from_id { @@ -39,8 +40,8 @@ from_id![ (hir_def::TraitId, crate::Trait), (hir_def::StaticId, crate::Static), (hir_def::ConstId, crate::Const), - (hir_def::FunctionId, crate::Function), - (hir_def::ImplId, crate::Impl), + (crate::AnyFunctionId, crate::Function), + (hir_ty::next_solver::AnyImplId, crate::Impl), (hir_def::TypeOrConstParamId, crate::TypeOrConstParam), (hir_def::TypeParamId, crate::TypeParam), (hir_def::ConstParamId, crate::ConstParam), @@ -119,11 +120,15 @@ impl From for ModuleDef { } } -impl From for ModuleDefId { - fn from(id: ModuleDef) -> Self { - match id { +impl TryFrom for ModuleDefId { + type Error = (); + fn try_from(id: ModuleDef) -> Result { + Ok(match id { ModuleDef::Module(it) => ModuleDefId::ModuleId(it.into()), - ModuleDef::Function(it) => ModuleDefId::FunctionId(it.into()), + ModuleDef::Function(it) => match it.id { + AnyFunctionId::FunctionId(it) => it.into(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Err(()), + }, ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()), ModuleDef::Variant(it) => ModuleDefId::EnumVariantId(it.into()), ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()), @@ -132,18 +137,22 @@ impl From for ModuleDefId { ModuleDef::TypeAlias(it) => ModuleDefId::TypeAliasId(it.into()), ModuleDef::BuiltinType(it) => ModuleDefId::BuiltinType(it.into()), ModuleDef::Macro(it) => ModuleDefId::MacroId(it.into()), - } + }) } } -impl From for DefWithBodyId { - fn from(def: DefWithBody) -> Self { - match def { - DefWithBody::Function(it) => DefWithBodyId::FunctionId(it.id), +impl TryFrom for DefWithBodyId { + type Error = (); + fn try_from(def: DefWithBody) -> Result { + Ok(match def { + DefWithBody::Function(it) => match it.id { + AnyFunctionId::FunctionId(it) => it.into(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Err(()), + }, DefWithBody::Static(it) => DefWithBodyId::StaticId(it.id), DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id), DefWithBody::Variant(it) => DefWithBodyId::VariantId(it.into()), - } + }) } } @@ -168,17 +177,11 @@ impl From for AssocItem { } } -impl From for GenericDefId { - fn from(def: GenericDef) -> Self { - match def { - GenericDef::Function(it) => GenericDefId::FunctionId(it.id), - GenericDef::Adt(it) => GenericDefId::AdtId(it.into()), - GenericDef::Trait(it) => GenericDefId::TraitId(it.id), - GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id), - GenericDef::Impl(it) => GenericDefId::ImplId(it.id), - GenericDef::Const(it) => GenericDefId::ConstId(it.id), - GenericDef::Static(it) => GenericDefId::StaticId(it.id), - } +impl TryFrom for GenericDefId { + type Error = (); + + fn try_from(def: GenericDef) -> Result { + def.id().ok_or(()) } } @@ -238,13 +241,17 @@ impl From for Field { } } -impl From for GenericDefId { - fn from(item: AssocItem) -> Self { - match item { - AssocItem::Function(f) => f.id.into(), +impl TryFrom for GenericDefId { + type Error = (); + fn try_from(item: AssocItem) -> Result { + Ok(match item { + AssocItem::Function(f) => match f.id { + AnyFunctionId::FunctionId(it) => it.into(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Err(()), + }, AssocItem::Const(c) => c.id.into(), AssocItem::TypeAlias(t) => t.id.into(), - } + }) } } @@ -270,13 +277,14 @@ impl From for ItemInNs { } } -impl From for hir_def::item_scope::ItemInNs { - fn from(it: ItemInNs) -> Self { - match it { - ItemInNs::Types(it) => Self::Types(it.into()), - ItemInNs::Values(it) => Self::Values(it.into()), +impl TryFrom for hir_def::item_scope::ItemInNs { + type Error = (); + fn try_from(it: ItemInNs) -> Result { + Ok(match it { + ItemInNs::Types(it) => Self::Types(it.try_into()?), + ItemInNs::Values(it) => Self::Values(it.try_into()?), ItemInNs::Macros(it) => Self::Macros(it.into()), - } + }) } } @@ -291,3 +299,21 @@ impl From for hir_def::builtin_type::BuiltinType { it.inner } } + +impl From for crate::Impl { + fn from(value: hir_def::ImplId) -> Self { + crate::Impl { id: AnyImplId::ImplId(value) } + } +} + +impl From for crate::Impl { + fn from(value: BuiltinDeriveImplId) -> Self { + crate::Impl { id: AnyImplId::BuiltinDeriveImplId(value) } + } +} + +impl From for crate::Function { + fn from(value: hir_def::FunctionId) -> Self { + crate::Function { id: AnyFunctionId::FunctionId(value) } + } +} diff --git a/src/tools/rust-analyzer/crates/hir/src/has_source.rs b/src/tools/rust-analyzer/crates/hir/src/has_source.rs index 1aa799400106..09c5b1cca7f3 100644 --- a/src/tools/rust-analyzer/crates/hir/src/has_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/has_source.rs @@ -7,18 +7,18 @@ use hir_def::{ src::{HasChildSource, HasSource as _}, }; use hir_expand::{EditionedFileId, HirFileId, InFile}; -use hir_ty::db::InternedClosure; -use syntax::ast; +use hir_ty::{db::InternedClosure, next_solver::AnyImplId}; +use syntax::{AstNode, ast}; use tt::TextRange; use crate::{ - Adt, Callee, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl, + Adt, AnyFunctionId, Callee, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl, InlineAsmOperand, Label, LifetimeParam, LocalSource, Macro, Module, Param, SelfParam, Static, Struct, Trait, TypeAlias, TypeOrConstParam, Union, Variant, VariantDef, db::HirDatabase, }; -pub trait HasSource { - type Ast; +pub trait HasSource: Sized { + type Ast: AstNode; /// Fetches the definition's source node. /// Using [`crate::SemanticsImpl::source`] is preferred when working with [`crate::Semantics`], /// as that caches the parsed file in the semantics' cache. @@ -27,6 +27,20 @@ pub trait HasSource { /// But we made this method `Option` to support rlib in the future /// by fn source(self, db: &dyn HirDatabase) -> Option>; + + /// Fetches the source node, along with its full range. + /// + /// The reason for the separate existence of this method is that some things, notably builtin derive impls, + /// do not really have a source node, at least not of the correct type. But we still can trace them + /// to source code (the derive producing them). So this method will return the range if it is supported, + /// and if the node is supported too it will return it as well. + fn source_with_range( + self, + db: &dyn HirDatabase, + ) -> Option)>> { + let source = self.source(db)?; + Some(source.map(|node| (node.syntax().text_range(), Some(node)))) + } } /// NB: Module is !HasSource, because it has two source nodes at the same time: @@ -146,7 +160,30 @@ impl HasSource for Variant { impl HasSource for Function { type Ast = ast::Fn; fn source(self, db: &dyn HirDatabase) -> Option> { - Some(self.id.lookup(db).source(db)) + match self.id { + AnyFunctionId::FunctionId(id) => Some(id.loc(db).source(db)), + // When calling `source()`, we use the trait method source, but when calling `source_with_range()`, + // we return `None` as the syntax node source. This is relying on the assumption that if you are calling + // `source_with_range()` (e.g. in navigation) you're prepared to deal with no source node, while if + // you call `source()` maybe you don't - therefore we fall back to the trait method, to not lose features. + AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } => method + .trait_method(db, impl_) + .and_then(|trait_method| Function::from(trait_method).source(db)), + } + } + + fn source_with_range( + self, + db: &dyn HirDatabase, + ) -> Option)>> { + match self.id { + AnyFunctionId::FunctionId(id) => Some( + id.loc(db).source(db).map(|source| (source.syntax().text_range(), Some(source))), + ), + AnyFunctionId::BuiltinDeriveImplMethod { impl_, .. } => { + Some(impl_.loc(db).source(db).map(|range| (range, None))) + } + } } } impl HasSource for Const { @@ -190,7 +227,24 @@ impl HasSource for Macro { impl HasSource for Impl { type Ast = ast::Impl; fn source(self, db: &dyn HirDatabase) -> Option> { - Some(self.id.lookup(db).source(db)) + match self.id { + AnyImplId::ImplId(id) => Some(id.loc(db).source(db)), + AnyImplId::BuiltinDeriveImplId(_) => None, + } + } + + fn source_with_range( + self, + db: &dyn HirDatabase, + ) -> Option)>> { + match self.id { + AnyImplId::ImplId(id) => Some( + id.loc(db).source(db).map(|source| (source.syntax().text_range(), Some(source))), + ), + AnyImplId::BuiltinDeriveImplId(impl_) => { + Some(impl_.loc(db).source(db).map(|range| (range, None))) + } + } } } @@ -224,7 +278,7 @@ impl HasSource for Param<'_> { fn source(self, db: &dyn HirDatabase) -> Option> { match self.func { Callee::Def(CallableDefId::FunctionId(func)) => { - let InFile { file_id, value } = Function { id: func }.source(db)?; + let InFile { file_id, value } = Function::from(func).source(db)?; let params = value.param_list()?; if let Some(self_param) = params.self_param() { if let Some(idx) = self.idx.checked_sub(1) { @@ -261,7 +315,7 @@ impl HasSource for SelfParam { type Ast = ast::SelfParam; fn source(self, db: &dyn HirDatabase) -> Option> { - let InFile { file_id, value } = Function::from(self.func).source(db)?; + let InFile { file_id, value } = self.func.source(db)?; value .param_list() .and_then(|params| params.self_param()) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 9fc29de4a11c..6a19603923c3 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -48,12 +48,13 @@ use arrayvec::ArrayVec; use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin}; use either::Either; use hir_def::{ - AdtId, AssocItemId, AssocItemLoc, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, - EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, - HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, - MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, TypeOrConstParamId, - TypeParamId, UnionId, + AdtId, AssocItemId, AssocItemLoc, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, + DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, + GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, + MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, + TypeOrConstParamId, TypeParamId, UnionId, attrs::AttrFlags, + builtin_derive::BuiltinDeriveImplMethod, expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, hir::{ BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat, @@ -73,7 +74,8 @@ use hir_def::{ visibility::visibility_from_ast, }; use hir_expand::{ - AstId, MacroCallKind, RenderedExpandError, ValueResult, proc_macro::ProcMacroKind, + AstId, MacroCallKind, RenderedExpandError, ValueResult, builtin::BuiltinDeriveExpander, + proc_macro::ProcMacroKind, }; use hir_ty::{ GenericPredicates, InferenceResult, ParamEnvAndCrate, TyDefId, TyLoweringDiagnostic, @@ -88,8 +90,9 @@ use hir_ty::{ }, mir::{MutBorrowKind, interpret_mir}, next_solver::{ - AliasTy, ClauseKind, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, - ParamEnv, PolyFnSig, Region, SolverDefId, Ty, TyKind, TypingMode, + AliasTy, AnyImplId, ClauseKind, ConstKind, DbInterner, EarlyBinder, EarlyParamRegion, + ErrorGuaranteed, GenericArg, GenericArgs, ParamConst, ParamEnv, PolyFnSig, Region, + RegionKind, SolverDefId, Ty, TyKind, TypingMode, infer::{DbInternerInferExt, InferCtxt}, }, traits::{self, is_inherent_impl_coherent, structurally_normalize_ty}, @@ -97,7 +100,8 @@ use hir_ty::{ use itertools::Itertools; use rustc_hash::FxHashSet; use rustc_type_ir::{ - AliasTyKind, TypeSuperVisitable, TypeVisitable, TypeVisitor, fast_reject, + AliasTyKind, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, + TypeVisitor, fast_reject, inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _}, }; use smallvec::SmallVec; @@ -105,7 +109,7 @@ use span::{AstIdNode, Edition, FileId}; use stdx::{format_to, impl_from, never, variance::PhantomCovariantLifetime}; use syntax::{ AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, - ast::{self, HasName, HasVisibility as _}, + ast::{self, HasName as _, HasVisibility as _}, format_smolstr, }; use triomphe::{Arc, ThinArc}; @@ -440,7 +444,10 @@ impl ModuleDef { Adt::Union(it) => it.id.into(), }, ModuleDef::Trait(it) => it.id.into(), - ModuleDef::Function(it) => it.id.into(), + ModuleDef::Function(it) => match it.id { + AnyFunctionId::FunctionId(it) => it.into(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Vec::new(), + }, ModuleDef::TypeAlias(it) => it.id.into(), ModuleDef::Module(it) => it.id.into(), ModuleDef::Const(it) => it.id.into(), @@ -504,7 +511,7 @@ impl ModuleDef { pub fn attrs(&self, db: &dyn HirDatabase) -> Option { Some(match self { ModuleDef::Module(it) => it.attrs(db), - ModuleDef::Function(it) => it.attrs(db), + ModuleDef::Function(it) => HasAttrs::attrs(*it, db), ModuleDef::Adt(it) => it.attrs(db), ModuleDef::Variant(it) => it.attrs(db), ModuleDef::Const(it) => it.attrs(db), @@ -772,8 +779,11 @@ impl Module { for impl_def in self.impl_defs(db) { GenericDef::Impl(impl_def).diagnostics(db, acc); - let loc = impl_def.id.lookup(db); - let (impl_signature, source_map) = db.impl_signature_with_source_map(impl_def.id); + let AnyImplId::ImplId(impl_id) = impl_def.id else { + continue; + }; + let loc = impl_id.lookup(db); + let (impl_signature, source_map) = db.impl_signature_with_source_map(impl_id); expr_store_diagnostics(db, acc, &source_map); let file_id = loc.id.file_id; @@ -789,12 +799,12 @@ impl Module { let ast_id_map = db.ast_id_map(file_id); - for diag in impl_def.id.impl_items_with_diagnostics(db).1.iter() { + for diag in impl_id.impl_items_with_diagnostics(db).1.iter() { emit_def_diagnostic(db, acc, diag, edition, loc.container.krate(db)); } if impl_signature.target_trait.is_none() - && !is_inherent_impl_coherent(db, def_map, impl_def.id) + && !is_inherent_impl_coherent(db, def_map, impl_id) { acc.push(IncoherentImpl { impl_: ast_id_map.get(loc.id.value), file_id }.into()) } @@ -822,7 +832,7 @@ impl Module { if drop_trait != trait_.into() { return None; } - let parent = impl_def.id.into(); + let parent = impl_id.into(); let (lifetimes_attrs, type_and_consts_attrs) = AttrFlags::query_generic_params(db, parent); let res = lifetimes_attrs.values().any(|it| it.contains(AttrFlags::MAY_DANGLE)) @@ -851,7 +861,7 @@ impl Module { AssocItemId::ConstId(id) => !db.const_signature(id).has_body(), AssocItemId::TypeAliasId(it) => db.type_alias_signature(it).ty.is_none(), }); - impl_assoc_items_scratch.extend(impl_def.id.impl_items(db).items.iter().cloned()); + impl_assoc_items_scratch.extend(impl_id.impl_items(db).items.iter().cloned()); let redundant = impl_assoc_items_scratch .iter() @@ -883,11 +893,11 @@ impl Module { .collect(); if !missing.is_empty() { - let self_ty = db.impl_self_ty(impl_def.id).instantiate_identity(); + let self_ty = db.impl_self_ty(impl_id).instantiate_identity(); let self_ty = structurally_normalize_ty( &infcx, self_ty, - db.trait_environment(impl_def.id.into()), + db.trait_environment(impl_id.into()), ); let self_ty_is_guaranteed_unsized = matches!( self_ty.kind(), @@ -896,7 +906,13 @@ impl Module { if self_ty_is_guaranteed_unsized { missing.retain(|(_, assoc_item)| { let assoc_item = match *assoc_item { - AssocItem::Function(it) => it.id.into(), + AssocItem::Function(it) => match it.id { + AnyFunctionId::FunctionId(id) => id.into(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => { + never!("should not have an `AnyFunctionId::BuiltinDeriveImplMethod` here"); + return false; + }, + }, AssocItem::Const(it) => it.id.into(), AssocItem::TypeAlias(it) => it.id.into(), }; @@ -918,20 +934,15 @@ impl Module { impl_assoc_items_scratch.clear(); } + push_ty_diagnostics(db, acc, db.impl_self_ty_with_diagnostics(impl_id).1, &source_map); push_ty_diagnostics( db, acc, - db.impl_self_ty_with_diagnostics(impl_def.id).1, - &source_map, - ); - push_ty_diagnostics( - db, - acc, - db.impl_trait_with_diagnostics(impl_def.id).and_then(|it| it.1), + db.impl_trait_with_diagnostics(impl_id).and_then(|it| it.1), &source_map, ); - for &(_, item) in impl_def.id.impl_items(db).items.iter() { + for &(_, item) in impl_id.impl_items(db).items.iter() { AssocItem::from(item).diagnostics(db, acc, style_lints); } } @@ -955,7 +966,8 @@ impl Module { pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec { let def_map = self.id.def_map(db); - def_map[self.id].scope.impls().map(Impl::from).collect() + let scope = &def_map[self.id].scope; + scope.impls().map(Impl::from).chain(scope.builtin_derive_impls().map(Impl::from)).collect() } /// Finds a path that can be used to refer to the given item from within @@ -968,7 +980,7 @@ impl Module { ) -> Option { hir_def::find_path::find_path( db, - item.into().into(), + item.into().try_into().ok()?, self.into(), PrefixKind::Plain, false, @@ -985,7 +997,14 @@ impl Module { prefix_kind: PrefixKind, cfg: FindPathConfig, ) -> Option { - hir_def::find_path::find_path(db, item.into().into(), self.into(), prefix_kind, true, cfg) + hir_def::find_path::find_path( + db, + item.into().try_into().ok()?, + self.into(), + prefix_kind, + true, + cfg, + ) } #[inline] @@ -1863,9 +1882,9 @@ impl VariantDef { pub fn name(&self, db: &dyn HirDatabase) -> Name { match self { - VariantDef::Struct(s) => s.name(db), - VariantDef::Union(u) => u.name(db), - VariantDef::Variant(e) => e.name(db), + VariantDef::Struct(s) => (*s).name(db), + VariantDef::Union(u) => (*u).name(db), + VariantDef::Variant(e) => (*e).name(db), } } } @@ -1909,24 +1928,33 @@ impl DefWithBody { } } - fn id(&self) -> DefWithBodyId { - match self { - DefWithBody::Function(it) => it.id.into(), + fn id(&self) -> Option { + Some(match self { + DefWithBody::Function(it) => match it.id { + AnyFunctionId::FunctionId(id) => id.into(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => return None, + }, DefWithBody::Static(it) => it.id.into(), DefWithBody::Const(it) => it.id.into(), DefWithBody::Variant(it) => it.into(), - } + }) } /// A textual representation of the HIR of this def's body for debugging purposes. pub fn debug_hir(self, db: &dyn HirDatabase) -> String { - let body = db.body(self.id()); - body.pretty_print(db, self.id(), Edition::CURRENT) + let Some(id) = self.id() else { + return String::new(); + }; + let body = db.body(id); + body.pretty_print(db, id, Edition::CURRENT) } /// A textual representation of the MIR of this def's body for debugging purposes. pub fn debug_mir(self, db: &dyn HirDatabase) -> String { - let body = db.mir_body(self.id()); + let Some(id) = self.id() else { + return String::new(); + }; + let body = db.mir_body(id); match body { Ok(body) => body.pretty_print(db, self.module(db).krate(db).to_display_target(db)), Err(e) => format!("error:\n{e:?}"), @@ -1939,11 +1967,17 @@ impl DefWithBody { acc: &mut Vec>, style_lints: bool, ) { + let Ok(id) = self.try_into() else { + return; + }; let krate = self.module(db).id.krate(db); - let (body, source_map) = db.body_with_source_map(self.into()); + let (body, source_map) = db.body_with_source_map(id); let sig_source_map = match self { - DefWithBody::Function(id) => db.function_signature_with_source_map(id.into()).1, + DefWithBody::Function(id) => match id.id { + AnyFunctionId::FunctionId(id) => db.function_signature_with_source_map(id).1, + AnyFunctionId::BuiltinDeriveImplMethod { .. } => return, + }, DefWithBody::Static(id) => db.static_signature_with_source_map(id.into()).1, DefWithBody::Const(id) => db.const_signature_with_source_map(id.into()).1, DefWithBody::Variant(variant) => { @@ -1958,11 +1992,11 @@ impl DefWithBody { expr_store_diagnostics(db, acc, &source_map); - let infer = InferenceResult::for_body(db, self.into()); + let infer = InferenceResult::for_body(db, id); for d in infer.diagnostics() { acc.extend(AnyDiagnostic::inference_diagnostic( db, - self.into(), + id, d, &source_map, &sig_source_map, @@ -1989,14 +2023,14 @@ impl DefWithBody { acc.push( TypeMismatch { expr_or_pat, - expected: Type::new(db, DefWithBodyId::from(self), mismatch.expected.as_ref()), - actual: Type::new(db, DefWithBodyId::from(self), mismatch.actual.as_ref()), + expected: Type::new(db, id, mismatch.expected.as_ref()), + actual: Type::new(db, id, mismatch.actual.as_ref()), } .into(), ); } - let missing_unsafe = hir_ty::diagnostics::missing_unsafe(db, self.into()); + let missing_unsafe = hir_ty::diagnostics::missing_unsafe(db, id); for (node, reason) in missing_unsafe.unsafe_exprs { match source_map.expr_or_pat_syntax(node) { Ok(node) => acc.push( @@ -2031,7 +2065,7 @@ impl DefWithBody { } } - if let Ok(borrowck_results) = db.borrowck(self.into()) { + if let Ok(borrowck_results) = db.borrowck(id) { for borrowck_result in borrowck_results.iter() { let mir_body = &borrowck_result.mir_body; for moof in &borrowck_result.moved_out_of_ref { @@ -2088,7 +2122,7 @@ impl DefWithBody { { need_mut = &mir::MutabilityReason::Not; } - let local = Local { parent: self.into(), binding_id }; + let local = Local { parent: id, binding_id }; let is_mut = body[binding_id].mode == BindingAnnotation::Mutable; match (need_mut, is_mut) { @@ -2144,17 +2178,11 @@ impl DefWithBody { } } - for diagnostic in BodyValidationDiagnostic::collect(db, self.into(), style_lints) { + for diagnostic in BodyValidationDiagnostic::collect(db, id, style_lints) { acc.extend(AnyDiagnostic::body_validation_diagnostic(db, diagnostic, &source_map)); } - let def: ModuleDef = match self { - DefWithBody::Function(it) => it.into(), - DefWithBody::Static(it) => it.into(), - DefWithBody::Const(it) => it.into(), - DefWithBody::Variant(it) => it.into(), - }; - for diag in hir_ty::diagnostics::incorrect_case(db, def.into()) { + for diag in hir_ty::diagnostics::incorrect_case(db, id.into()) { acc.push(diag.into()) } } @@ -2192,45 +2220,181 @@ fn expr_store_diagnostics<'db>( .macro_calls() .for_each(|(_ast_id, call_id)| macro_call_diagnostics(db, call_id, acc)); } + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum AnyFunctionId { + FunctionId(FunctionId), + BuiltinDeriveImplMethod { method: BuiltinDeriveImplMethod, impl_: BuiltinDeriveImplId }, +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Function { - pub(crate) id: FunctionId, + pub(crate) id: AnyFunctionId, +} + +impl fmt::Debug for Function { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.id, f) + } } impl Function { pub fn module(self, db: &dyn HirDatabase) -> Module { - self.id.module(db).into() + match self.id { + AnyFunctionId::FunctionId(id) => id.module(db).into(), + AnyFunctionId::BuiltinDeriveImplMethod { impl_, .. } => impl_.module(db).into(), + } } pub fn name(self, db: &dyn HirDatabase) -> Name { - db.function_signature(self.id).name.clone() + match self.id { + AnyFunctionId::FunctionId(id) => db.function_signature(id).name.clone(), + AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => { + Name::new_symbol_root(method.name()) + } + } } pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { - Type::from_value_def(db, self.id) + match self.id { + AnyFunctionId::FunctionId(id) => Type::from_value_def(db, id), + AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } => { + // Get the type for the trait function, as we can't get the type for the impl function + // because it has not `CallableDefId`. + let krate = impl_.module(db).krate(db); + let interner = DbInterner::new_with(db, krate); + let param_env = hir_ty::builtin_derive::param_env(interner, impl_); + let env = ParamEnvAndCrate { param_env, krate }; + let Some(trait_method) = method.trait_method(db, impl_) else { + return Type { env, ty: Ty::new_error(interner, ErrorGuaranteed) }; + }; + Function::from(trait_method).ty(db) + } + } } pub fn fn_ptr_type(self, db: &dyn HirDatabase) -> Type<'_> { - let resolver = self.id.resolver(db); - let interner = DbInterner::new_no_crate(db); - // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. - let callable_sig = db.callable_item_signature(self.id.into()).instantiate_identity(); - let ty = Ty::new_fn_ptr(interner, callable_sig); - Type::new_with_resolver_inner(db, &resolver, ty) + match self.id { + AnyFunctionId::FunctionId(id) => { + let resolver = id.resolver(db); + let interner = DbInterner::new_no_crate(db); + // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. + let callable_sig = db.callable_item_signature(id.into()).instantiate_identity(); + let ty = Ty::new_fn_ptr(interner, callable_sig); + Type::new_with_resolver_inner(db, &resolver, ty) + } + AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } => { + struct ParamsShifter<'db> { + interner: DbInterner<'db>, + shift_by: i32, + } + + impl<'db> TypeFolder> for ParamsShifter<'db> { + fn cx(&self) -> DbInterner<'db> { + self.interner + } + + fn fold_ty(&mut self, ty: Ty<'db>) -> Ty<'db> { + if let TyKind::Param(param) = ty.kind() { + Ty::new_param( + self.interner, + param.id, + param.index.checked_add_signed(self.shift_by).unwrap(), + ) + } else { + ty.super_fold_with(self) + } + } + + fn fold_const( + &mut self, + ct: hir_ty::next_solver::Const<'db>, + ) -> hir_ty::next_solver::Const<'db> { + if let ConstKind::Param(param) = ct.kind() { + hir_ty::next_solver::Const::new_param( + self.interner, + ParamConst { + id: param.id, + index: param.index.checked_add_signed(self.shift_by).unwrap(), + }, + ) + } else { + ct.super_fold_with(self) + } + } + + fn fold_region(&mut self, r: Region<'db>) -> Region<'db> { + if let RegionKind::ReEarlyParam(param) = r.kind() { + Region::new_early_param( + self.interner, + EarlyParamRegion { + id: param.id, + index: param.index.checked_add_signed(self.shift_by).unwrap(), + }, + ) + } else { + r + } + } + } + + // Get the type for the trait function, as we can't get the type for the impl function + // because it has not `CallableDefId`. + let krate = impl_.module(db).krate(db); + let interner = DbInterner::new_with(db, krate); + let param_env = hir_ty::builtin_derive::param_env(interner, impl_); + let env = ParamEnvAndCrate { param_env, krate }; + let Some(trait_method) = method.trait_method(db, impl_) else { + return Type { env, ty: Ty::new_error(interner, ErrorGuaranteed) }; + }; + // The procedure works as follows: the method may have additional generic parameters (e.g. `Hash::hash()`), + // and we want them to be params of the impl method as well. So we start with the trait method identity + // args and extract from them the trait method own args. In parallel, we retrieve the impl trait ref. + // Now we can put our args as [...impl_trait_ref.args, ...trait_method_own_args], but we have one problem: + // the args in `trait_method_own_args` use indices appropriate for the trait method, which are not necessarily + // good for the impl method. So we shift them by `impl_generics_len - trait_generics_len`, which is essentially + // `impl_generics_len - impl_trait_ref.args.len()`. + let trait_method_fn_ptr = Ty::new_fn_ptr( + interner, + db.callable_item_signature(trait_method.into()).instantiate_identity(), + ); + let impl_trait_ref = + hir_ty::builtin_derive::impl_trait(interner, impl_).instantiate_identity(); + let trait_method_args = + GenericArgs::identity_for_item(interner, trait_method.into()); + let trait_method_own_args = GenericArgs::new_from_iter( + interner, + trait_method_args.iter().skip(impl_trait_ref.args.len()), + ); + let impl_params_count = hir_ty::builtin_derive::generic_params_count(db, impl_); + let shift_args_by = impl_params_count as i32 - impl_trait_ref.args.len() as i32; + let shifted_trait_method_own_args = trait_method_own_args + .fold_with(&mut ParamsShifter { interner, shift_by: shift_args_by }); + let impl_method_args = GenericArgs::new_from_iter( + interner, + impl_trait_ref.args.iter().chain(shifted_trait_method_own_args), + ); + let impl_method_fn_ptr = + EarlyBinder::bind(trait_method_fn_ptr).instantiate(interner, impl_method_args); + Type { env, ty: impl_method_fn_ptr } + } + } + } + + fn fn_sig<'db>(self, db: &'db dyn HirDatabase) -> (ParamEnvAndCrate<'db>, PolyFnSig<'db>) { + let fn_ptr = self.fn_ptr_type(db); + let TyKind::FnPtr(sig_tys, hdr) = fn_ptr.ty.kind() else { + unreachable!(); + }; + (fn_ptr.env, sig_tys.with(hdr)) } // FIXME: Find a better API to express all combinations here, perhaps we should have `PreInstantiationType`? /// Get this function's return type pub fn ret_type(self, db: &dyn HirDatabase) -> Type<'_> { - let resolver = self.id.resolver(db); - // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. - let ty = db - .callable_item_signature(self.id.into()) - .instantiate_identity() - .skip_binder() - .output(); - Type::new_with_resolver_inner(db, &resolver, ty) + let (env, sig) = self.fn_sig(db); + Type { env, ty: sig.skip_binder().output() } } // FIXME: Find better API to also handle const generics @@ -2239,30 +2403,41 @@ impl Function { db: &'db dyn HirDatabase, generics: impl Iterator>, ) -> Type<'db> { - let resolver = self.id.resolver(db); + let ret_type = self.ret_type(db); let interner = DbInterner::new_no_crate(db); - let args = generic_args_from_tys(interner, self.id.into(), generics.map(|ty| ty.ty)); + let args = self.adapt_generic_args(interner, generics); + ret_type.derived(EarlyBinder::bind(ret_type.ty).instantiate(interner, args)) + } - let interner = DbInterner::new_no_crate(db); - let ty = db - .callable_item_signature(self.id.into()) - .instantiate(interner, args) - .skip_binder() - .output(); - Type::new_with_resolver_inner(db, &resolver, ty) + fn adapt_generic_args<'db>( + self, + interner: DbInterner<'db>, + generics: impl Iterator>, + ) -> GenericArgs<'db> { + let generics = generics.map(|ty| ty.ty); + match self.id { + AnyFunctionId::FunctionId(id) => generic_args_from_tys(interner, id.into(), generics), + AnyFunctionId::BuiltinDeriveImplMethod { impl_, .. } => { + let impl_args = GenericArgs::identity_for_item(interner, impl_.into()); + GenericArgs::new_from_iter( + interner, + impl_args.iter().chain(generics.map(Into::into)), + ) + } + } } pub fn async_ret_type<'db>(self, db: &'db dyn HirDatabase) -> Option> { + let AnyFunctionId::FunctionId(id) = self.id else { + return None; + }; if !self.is_async(db) { return None; } - let resolver = self.id.resolver(db); + let resolver = id.resolver(db); // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. - let ret_ty = db - .callable_item_signature(self.id.into()) - .instantiate_identity() - .skip_binder() - .output(); + let ret_ty = + db.callable_item_signature(id.into()).instantiate_identity().skip_binder().output(); for pred in ret_ty.impl_trait_bounds(db).into_iter().flatten() { if let ClauseKind::Projection(projection) = pred.kind().skip_binder() && let Some(output_ty) = projection.term.as_type() @@ -2274,31 +2449,47 @@ impl Function { } pub fn has_self_param(self, db: &dyn HirDatabase) -> bool { - db.function_signature(self.id).has_self_param() + match self.id { + AnyFunctionId::FunctionId(id) => db.function_signature(id).has_self_param(), + AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => match method { + BuiltinDeriveImplMethod::clone + | BuiltinDeriveImplMethod::fmt + | BuiltinDeriveImplMethod::hash + | BuiltinDeriveImplMethod::cmp + | BuiltinDeriveImplMethod::partial_cmp + | BuiltinDeriveImplMethod::eq => true, + BuiltinDeriveImplMethod::default => false, + }, + } } pub fn self_param(self, db: &dyn HirDatabase) -> Option { - self.has_self_param(db).then_some(SelfParam { func: self.id }) + self.has_self_param(db).then_some(SelfParam { func: self }) } pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec> { - let environment = param_env_from_has_crate(db, self.id); - // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. - let callable_sig = - db.callable_item_signature(self.id.into()).instantiate_identity().skip_binder(); - callable_sig + let (env, sig) = self.fn_sig(db); + let func = match self.id { + AnyFunctionId::FunctionId(id) => Callee::Def(CallableDefId::FunctionId(id)), + AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } => { + Callee::BuiltinDeriveImplMethod { method, impl_ } + } + }; + sig.skip_binder() .inputs() .iter() .enumerate() - .map(|(idx, &ty)| { - let ty = Type { env: environment, ty }; - Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } - }) + .map(|(idx, &ty)| Param { func: func.clone(), ty: Type { env, ty }, idx }) .collect() } pub fn num_params(self, db: &dyn HirDatabase) -> usize { - db.function_signature(self.id).params.len() + match self.id { + AnyFunctionId::FunctionId(id) => db.function_signature(id).params.len(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => { + self.fn_sig(db).1.skip_binder().inputs().len() + } + } } pub fn method_params(self, db: &dyn HirDatabase) -> Option>> { @@ -2307,21 +2498,11 @@ impl Function { } pub fn params_without_self(self, db: &dyn HirDatabase) -> Vec> { - let environment = param_env_from_has_crate(db, self.id); - // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. - let callable_sig = - db.callable_item_signature(self.id.into()).instantiate_identity().skip_binder(); - let skip = if db.function_signature(self.id).has_self_param() { 1 } else { 0 }; - callable_sig - .inputs() - .iter() - .enumerate() - .skip(skip) - .map(|(idx, &ty)| { - let ty = Type { env: environment, ty }; - Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } - }) - .collect() + let mut params = self.assoc_fn_params(db); + if self.has_self_param(db) { + params.remove(0); + } + params } // FIXME: Find better API to also handle const generics @@ -2330,40 +2511,50 @@ impl Function { db: &'db dyn HirDatabase, generics: impl Iterator>, ) -> Vec> { - let environment = param_env_from_has_crate(db, self.id); let interner = DbInterner::new_no_crate(db); - let args = generic_args_from_tys(interner, self.id.into(), generics.map(|ty| ty.ty)); - let callable_sig = - db.callable_item_signature(self.id.into()).instantiate(interner, args).skip_binder(); - let skip = if db.function_signature(self.id).has_self_param() { 1 } else { 0 }; - callable_sig - .inputs() - .iter() - .enumerate() - .skip(skip) - .map(|(idx, &ty)| { - let ty = Type { env: environment, ty }; - Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } + let args = self.adapt_generic_args(interner, generics); + let params = self.params_without_self(db); + params + .into_iter() + .map(|param| Param { + func: param.func, + idx: param.idx, + ty: Type { + env: param.ty.env, + ty: EarlyBinder::bind(param.ty.ty).instantiate(interner, args), + }, }) .collect() } pub fn is_const(self, db: &dyn HirDatabase) -> bool { - db.function_signature(self.id).is_const() + match self.id { + AnyFunctionId::FunctionId(id) => db.function_signature(id).is_const(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, + } } pub fn is_async(self, db: &dyn HirDatabase) -> bool { - db.function_signature(self.id).is_async() + match self.id { + AnyFunctionId::FunctionId(id) => db.function_signature(id).is_async(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, + } } pub fn is_varargs(self, db: &dyn HirDatabase) -> bool { - db.function_signature(self.id).is_varargs() + match self.id { + AnyFunctionId::FunctionId(id) => db.function_signature(id).is_varargs(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, + } } pub fn extern_block(self, db: &dyn HirDatabase) -> Option { - match self.id.lookup(db).container { - ItemContainerId::ExternBlockId(id) => Some(ExternBlock { id }), - _ => None, + match self.id { + AnyFunctionId::FunctionId(id) => match id.lookup(db).container { + ItemContainerId::ExternBlockId(id) => Some(ExternBlock { id }), + _ => None, + }, + AnyFunctionId::BuiltinDeriveImplMethod { .. } => None, } } @@ -2396,33 +2587,46 @@ impl Function { /// Does this function have `#[test]` attribute? pub fn is_test(self, db: &dyn HirDatabase) -> bool { - self.attrs(db).is_test() + self.attrs(db).contains(AttrFlags::IS_TEST) } /// is this a `fn main` or a function with an `export_name` of `main`? pub fn is_main(self, db: &dyn HirDatabase) -> bool { - self.exported_main(db) - || self.module(db).is_crate_root(db) && db.function_signature(self.id).name == sym::main + match self.id { + AnyFunctionId::FunctionId(id) => { + self.exported_main(db) + || self.module(db).is_crate_root(db) + && db.function_signature(id).name == sym::main + } + AnyFunctionId::BuiltinDeriveImplMethod { .. } => false, + } + } + + fn attrs(self, db: &dyn HirDatabase) -> AttrFlags { + match self.id { + AnyFunctionId::FunctionId(id) => AttrFlags::query(db, id.into()), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => AttrFlags::empty(), + } } /// Is this a function with an `export_name` of `main`? pub fn exported_main(self, db: &dyn HirDatabase) -> bool { - AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_EXPORT_NAME_MAIN) + self.attrs(db).contains(AttrFlags::IS_EXPORT_NAME_MAIN) } /// Does this function have the ignore attribute? pub fn is_ignore(self, db: &dyn HirDatabase) -> bool { - AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_IGNORE) + self.attrs(db).contains(AttrFlags::IS_IGNORE) } /// Does this function have `#[bench]` attribute? pub fn is_bench(self, db: &dyn HirDatabase) -> bool { - AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_BENCH) + self.attrs(db).contains(AttrFlags::IS_BENCH) } /// Is this function marked as unstable with `#[feature]` attribute? pub fn is_unstable(self, db: &dyn HirDatabase) -> bool { - AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE) + self.attrs(db).contains(AttrFlags::IS_UNSTABLE) } pub fn is_unsafe_to_call( @@ -2431,9 +2635,17 @@ impl Function { caller: Option, call_edition: Edition, ) -> bool { + let AnyFunctionId::FunctionId(id) = self.id else { + return false; + }; let (target_features, target_feature_is_safe_in_target) = caller .map(|caller| { - let target_features = hir_ty::TargetFeatures::from_fn(db, caller.id); + let target_features = match caller.id { + AnyFunctionId::FunctionId(id) => hir_ty::TargetFeatures::from_fn(db, id), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => { + hir_ty::TargetFeatures::default() + } + }; let target_feature_is_safe_in_target = match &caller.krate(db).id.workspace_data(db).target { Ok(target) => hir_ty::target_feature_is_safe_in_target(target), @@ -2447,7 +2659,7 @@ impl Function { matches!( hir_ty::is_fn_unsafe_to_call( db, - self.id, + id, &target_features, call_edition, target_feature_is_safe_in_target @@ -2460,12 +2672,18 @@ impl Function { /// /// This is false in the case of required (not provided) trait methods. pub fn has_body(self, db: &dyn HirDatabase) -> bool { - db.function_signature(self.id).has_body() + match self.id { + AnyFunctionId::FunctionId(id) => db.function_signature(id).has_body(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => true, + } } pub fn as_proc_macro(self, db: &dyn HirDatabase) -> Option { - let def_map = crate_def_map(db, HasModule::krate(&self.id, db)); - def_map.fn_as_proc_macro(self.id).map(|id| Macro { id: id.into() }) + let AnyFunctionId::FunctionId(id) = self.id else { + return None; + }; + let def_map = crate_def_map(db, HasModule::krate(&id, db)); + def_map.fn_as_proc_macro(id).map(|id| Macro { id: id.into() }) } pub fn eval( @@ -2473,13 +2691,18 @@ impl Function { db: &dyn HirDatabase, span_formatter: impl Fn(FileId, TextRange) -> String, ) -> Result { + let AnyFunctionId::FunctionId(id) = self.id else { + return Err(ConstEvalError::MirEvalError(MirEvalError::NotSupported( + "evaluation of builtin derive impl methods is not supported".to_owned(), + ))); + }; let interner = DbInterner::new_no_crate(db); let body = db.monomorphized_mir_body( - self.id.into(), + id.into(), GenericArgs::empty(interner).store(), ParamEnvAndCrate { - param_env: db.trait_environment(self.id.into()), - krate: self.id.module(db).krate(db), + param_env: db.trait_environment(id.into()), + krate: id.module(db).krate(db), } .store(), )?; @@ -2596,36 +2819,47 @@ impl<'db> Param<'db> { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct SelfParam { - func: FunctionId, + func: Function, } impl SelfParam { pub fn access(self, db: &dyn HirDatabase) -> Access { - let func_data = db.function_signature(self.func); - func_data - .params - .first() - .map(|¶m| match &func_data.store[param] { - TypeRef::Reference(ref_) => match ref_.mutability { - hir_def::type_ref::Mutability::Shared => Access::Shared, - hir_def::type_ref::Mutability::Mut => Access::Exclusive, - }, - _ => Access::Owned, - }) - .unwrap_or(Access::Owned) + match self.func.id { + AnyFunctionId::FunctionId(id) => { + let func_data = db.function_signature(id); + func_data + .params + .first() + .map(|¶m| match &func_data.store[param] { + TypeRef::Reference(ref_) => match ref_.mutability { + hir_def::type_ref::Mutability::Shared => Access::Shared, + hir_def::type_ref::Mutability::Mut => Access::Exclusive, + }, + _ => Access::Owned, + }) + .unwrap_or(Access::Owned) + } + AnyFunctionId::BuiltinDeriveImplMethod { method, .. } => match method { + BuiltinDeriveImplMethod::clone + | BuiltinDeriveImplMethod::fmt + | BuiltinDeriveImplMethod::hash + | BuiltinDeriveImplMethod::cmp + | BuiltinDeriveImplMethod::partial_cmp + | BuiltinDeriveImplMethod::eq => Access::Shared, + BuiltinDeriveImplMethod::default => { + unreachable!("this function does not have a self param") + } + }, + } } pub fn parent_fn(&self) -> Function { - Function::from(self.func) + self.func } pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> { - // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. - let callable_sig = - db.callable_item_signature(self.func.into()).instantiate_identity().skip_binder(); - let environment = param_env_from_has_crate(db, self.func); - let ty = rustc_type_ir::inherent::SliceLike::as_slice(&callable_sig.inputs())[0]; - Type { env: environment, ty } + let (env, sig) = self.func.fn_sig(db); + Type { env, ty: sig.skip_binder().inputs()[0] } } // FIXME: Find better API to also handle const generics @@ -2635,18 +2869,18 @@ impl SelfParam { generics: impl Iterator>, ) -> Type<'db> { let interner = DbInterner::new_no_crate(db); - let args = generic_args_from_tys(interner, self.func.into(), generics.map(|ty| ty.ty)); - let callable_sig = - db.callable_item_signature(self.func.into()).instantiate(interner, args).skip_binder(); - let environment = param_env_from_has_crate(db, self.func); - let ty = rustc_type_ir::inherent::SliceLike::as_slice(&callable_sig.inputs())[0]; - Type { env: environment, ty } + let args = self.func.adapt_generic_args(interner, generics); + let Type { env, ty } = self.ty(db); + Type { env, ty: EarlyBinder::bind(ty).instantiate(interner, args) } } } impl HasVisibility for Function { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { - db.assoc_visibility(self.id.into()) + match self.id { + AnyFunctionId::FunctionId(id) => db.assoc_visibility(id.into()), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => Visibility::Public, + } } } @@ -2870,7 +3104,7 @@ impl Trait { pub fn function(self, db: &dyn HirDatabase, name: impl PartialEq) -> Option { self.id.trait_items(db).items.iter().find(|(n, _)| name == *n).and_then(|&(_, it)| match it { - AssocItemId::FunctionId(id) => Some(Function { id }), + AssocItemId::FunctionId(id) => Some(id.into()), _ => None, }) } @@ -3151,15 +3385,15 @@ impl Macro { ) } - pub fn is_builtin_derive(&self, db: &dyn HirDatabase) -> bool { - match self.id { - MacroId::Macro2Id(it) => { - matches!(it.lookup(db).expander, MacroExpander::BuiltInDerive(_)) - } - MacroId::MacroRulesId(it) => { - matches!(it.lookup(db).expander, MacroExpander::BuiltInDerive(_)) - } - MacroId::ProcMacroId(_) => false, + pub fn builtin_derive_kind(&self, db: &dyn HirDatabase) -> Option { + let expander = match self.id { + MacroId::Macro2Id(it) => it.lookup(db).expander, + MacroId::MacroRulesId(it) => it.lookup(db).expander, + MacroId::ProcMacroId(_) => return None, + }; + match expander { + MacroExpander::BuiltInDerive(kind) => Some(BuiltinDeriveMacroKind(kind)), + _ => None, } } @@ -3197,6 +3431,9 @@ impl Macro { } } +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub struct BuiltinDeriveMacroKind(BuiltinDeriveExpander); + impl HasVisibility for Macro { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { match self.id { @@ -3275,7 +3512,10 @@ pub trait AsExternAssocItem { impl AsExternAssocItem for Function { fn as_extern_assoc_item(self, db: &dyn HirDatabase) -> Option { - as_extern_assoc_item(db, ExternAssocItem::Function, self.id) + let AnyFunctionId::FunctionId(id) = self.id else { + return None; + }; + as_extern_assoc_item(db, ExternAssocItem::Function, id) } } @@ -3303,7 +3543,7 @@ pub enum AssocItem { impl From for AssocItem { fn from(value: method_resolution::CandidateId) -> Self { match value { - method_resolution::CandidateId::FunctionId(id) => AssocItem::Function(Function { id }), + method_resolution::CandidateId::FunctionId(id) => AssocItem::Function(id.into()), method_resolution::CandidateId::ConstId(id) => AssocItem::Const(Const { id }), } } @@ -3321,7 +3561,10 @@ pub trait AsAssocItem { impl AsAssocItem for Function { fn as_assoc_item(self, db: &dyn HirDatabase) -> Option { - as_assoc_item(db, AssocItem::Function, self.id) + match self.id { + AnyFunctionId::FunctionId(id) => as_assoc_item(db, AssocItem::Function, id), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => Some(AssocItem::Function(self)), + } } } @@ -3450,7 +3693,14 @@ impl AssocItem { pub fn container(self, db: &dyn HirDatabase) -> AssocItemContainer { let container = match self { - AssocItem::Function(it) => it.id.lookup(db).container, + AssocItem::Function(it) => match it.id { + AnyFunctionId::FunctionId(id) => id.lookup(db).container, + AnyFunctionId::BuiltinDeriveImplMethod { impl_, .. } => { + return AssocItemContainer::Impl(Impl { + id: AnyImplId::BuiltinDeriveImplId(impl_), + }); + } + }, AssocItem::Const(it) => it.id.lookup(db).container, AssocItem::TypeAlias(it) => it.id.lookup(db).container, }; @@ -3587,9 +3837,13 @@ impl_from!( impl GenericDef { pub fn params(self, db: &dyn HirDatabase) -> Vec { - let generics = db.generic_params(self.into()); + let Ok(id) = self.try_into() else { + // Let's pretend builtin derive impls don't have generic parameters. + return Vec::new(); + }; + let generics = db.generic_params(id); let ty_params = generics.iter_type_or_consts().map(|(local_id, _)| { - let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: self.into(), local_id } }; + let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: id, local_id } }; match toc.split(db) { Either::Left(it) => GenericParam::ConstParam(it), Either::Right(it) => GenericParam::TypeParam(it), @@ -3603,39 +3857,51 @@ impl GenericDef { } pub fn lifetime_params(self, db: &dyn HirDatabase) -> Vec { - let generics = db.generic_params(self.into()); + let Ok(id) = self.try_into() else { + // Let's pretend builtin derive impls don't have generic parameters. + return Vec::new(); + }; + let generics = db.generic_params(id); generics .iter_lt() - .map(|(local_id, _)| LifetimeParam { - id: LifetimeParamId { parent: self.into(), local_id }, - }) + .map(|(local_id, _)| LifetimeParam { id: LifetimeParamId { parent: id, local_id } }) .collect() } pub fn type_or_const_params(self, db: &dyn HirDatabase) -> Vec { - let generics = db.generic_params(self.into()); + let Ok(id) = self.try_into() else { + // Let's pretend builtin derive impls don't have generic parameters. + return Vec::new(); + }; + let generics = db.generic_params(id); generics .iter_type_or_consts() .map(|(local_id, _)| TypeOrConstParam { - id: TypeOrConstParamId { parent: self.into(), local_id }, + id: TypeOrConstParamId { parent: id, local_id }, }) .collect() } - fn id(self) -> GenericDefId { - match self { - GenericDef::Function(it) => it.id.into(), + fn id(self) -> Option { + Some(match self { + GenericDef::Function(it) => match it.id { + AnyFunctionId::FunctionId(it) => it.into(), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => return None, + }, GenericDef::Adt(it) => it.into(), GenericDef::Trait(it) => it.id.into(), GenericDef::TypeAlias(it) => it.id.into(), - GenericDef::Impl(it) => it.id.into(), + GenericDef::Impl(it) => match it.id { + AnyImplId::ImplId(it) => it.into(), + AnyImplId::BuiltinDeriveImplId(_) => return None, + }, GenericDef::Const(it) => it.id.into(), GenericDef::Static(it) => it.id.into(), - } + }) } pub fn diagnostics<'db>(self, db: &'db dyn HirDatabase, acc: &mut Vec>) { - let def = self.id(); + let Some(def) = self.id() else { return }; let generics = db.generic_params(def); @@ -3708,6 +3974,17 @@ impl<'db> GenericSubstitution<'db> { Self { def, subst, env } } + fn new_from_fn( + def: Function, + subst: GenericArgs<'db>, + env: ParamEnvAndCrate<'db>, + ) -> Option { + match def.id { + AnyFunctionId::FunctionId(def) => Some(Self::new(def.into(), subst, env)), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => None, + } + } + pub fn types(&self, db: &'db dyn HirDatabase) -> Vec<(Symbol, Type<'db>)> { let container = match self.def { GenericDefId::ConstId(id) => Some(id.lookup(db).container), @@ -3820,7 +4097,9 @@ impl Local { pub fn as_self_param(self, db: &dyn HirDatabase) -> Option { match self.parent { - DefWithBodyId::FunctionId(func) if self.is_self(db) => Some(SelfParam { func }), + DefWithBodyId::FunctionId(func) if self.is_self(db) => { + Some(SelfParam { func: func.into() }) + } _ => None, } } @@ -4308,7 +4587,7 @@ impl TypeOrConstParam { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Impl { - pub(crate) id: ImplId, + pub(crate) id: AnyImplId, } impl Impl { @@ -4320,6 +4599,7 @@ impl Impl { fn extend_with_def_map(db: &dyn HirDatabase, def_map: &DefMap, result: &mut Vec) { for (_, module) in def_map.modules() { result.extend(module.scope.impls().map(Impl::from)); + result.extend(module.scope.builtin_derive_impls().map(Impl::from)); for unnamed_const in module.scope.unnamed_consts() { for (_, block_def_map) in db.body(unnamed_const.into()).blocks(db) { @@ -4331,7 +4611,7 @@ impl Impl { } pub fn all_in_module(db: &dyn HirDatabase, module: Module) -> Vec { - module.id.def_map(db)[module.id].scope.impls().map(Into::into).collect() + module.impl_defs(db) } /// **Note:** This is an **approximation** that strives to give the *human-perceived notion* of an "impl for type", @@ -4347,20 +4627,19 @@ impl Impl { else { return Vec::new(); }; - let mut extend_with_impls = - |impls: &[ImplId]| result.extend(impls.iter().copied().map(Impl::from)); - method_resolution::with_incoherent_inherent_impls( - db, - env.krate, - &simplified_ty, - &mut extend_with_impls, - ); + let mut extend_with_impls = |impls: Either<&[ImplId], &[BuiltinDeriveImplId]>| match impls { + Either::Left(impls) => result.extend(impls.iter().copied().map(Impl::from)), + Either::Right(impls) => result.extend(impls.iter().copied().map(Impl::from)), + }; + method_resolution::with_incoherent_inherent_impls(db, env.krate, &simplified_ty, |impls| { + extend_with_impls(Either::Left(impls)) + }); if let Some(module) = method_resolution::simplified_type_module(db, &simplified_ty) { InherentImpls::for_each_crate_and_block( db, module.krate(db), module.block(db), - &mut |impls| extend_with_impls(impls.for_self_ty(&simplified_ty)), + &mut |impls| extend_with_impls(Either::Left(impls.for_self_ty(&simplified_ty))), ); std::iter::successors(module.block(db), |block| block.loc(db).module.block(db)) .filter_map(|block| TraitImpls::for_block(db, block).as_deref()) @@ -4382,7 +4661,10 @@ impl Impl { let module = trait_.module(db).id; let mut all = Vec::new(); let mut handle_impls = |impls: &TraitImpls| { - impls.for_trait(trait_.id, |impls| all.extend(impls.iter().copied().map(Impl::from))); + impls.for_trait(trait_.id, |impls| match impls { + Either::Left(impls) => all.extend(impls.iter().copied().map(Impl::from)), + Either::Right(impls) => all.extend(impls.iter().copied().map(Impl::from)), + }); }; for krate in module.krate(db).transitive_rev_deps(db) { handle_impls(TraitImpls::for_crate(db, krate)); @@ -4396,75 +4678,118 @@ impl Impl { } pub fn trait_(self, db: &dyn HirDatabase) -> Option { - let trait_ref = db.impl_trait(self.id)?; - let id = trait_ref.skip_binder().def_id; - Some(Trait { id: id.0 }) + match self.id { + AnyImplId::ImplId(id) => { + let trait_ref = db.impl_trait(id)?; + let id = trait_ref.skip_binder().def_id; + Some(Trait { id: id.0 }) + } + AnyImplId::BuiltinDeriveImplId(id) => { + let loc = id.loc(db); + let lang_items = hir_def::lang_item::lang_items(db, loc.adt.module(db).krate(db)); + loc.trait_.get_id(lang_items).map(Trait::from) + } + } } pub fn trait_ref(self, db: &dyn HirDatabase) -> Option> { - let trait_ref = db.impl_trait(self.id)?.instantiate_identity(); - let resolver = self.id.resolver(db); - Some(TraitRef::new_with_resolver(db, &resolver, trait_ref)) + match self.id { + AnyImplId::ImplId(id) => { + let trait_ref = db.impl_trait(id)?.instantiate_identity(); + let resolver = id.resolver(db); + Some(TraitRef::new_with_resolver(db, &resolver, trait_ref)) + } + AnyImplId::BuiltinDeriveImplId(id) => { + let loc = id.loc(db); + let krate = loc.module(db).krate(db); + let interner = DbInterner::new_with(db, krate); + let env = ParamEnvAndCrate { + param_env: hir_ty::builtin_derive::param_env(interner, id), + krate, + }; + let trait_ref = + hir_ty::builtin_derive::impl_trait(interner, id).instantiate_identity(); + Some(TraitRef { env, trait_ref }) + } + } } pub fn self_ty(self, db: &dyn HirDatabase) -> Type<'_> { - let resolver = self.id.resolver(db); - // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. - let ty = db.impl_self_ty(self.id).instantiate_identity(); - Type::new_with_resolver_inner(db, &resolver, ty) + match self.id { + AnyImplId::ImplId(id) => { + let resolver = id.resolver(db); + // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. + let ty = db.impl_self_ty(id).instantiate_identity(); + Type::new_with_resolver_inner(db, &resolver, ty) + } + AnyImplId::BuiltinDeriveImplId(id) => { + let loc = id.loc(db); + let krate = loc.module(db).krate(db); + let interner = DbInterner::new_with(db, krate); + let env = ParamEnvAndCrate { + param_env: hir_ty::builtin_derive::param_env(interner, id), + krate, + }; + let ty = hir_ty::builtin_derive::impl_trait(interner, id) + .instantiate_identity() + .self_ty(); + Type { env, ty } + } + } } pub fn items(self, db: &dyn HirDatabase) -> Vec { - self.id.impl_items(db).items.iter().map(|&(_, it)| it.into()).collect() + match self.id { + AnyImplId::ImplId(id) => { + id.impl_items(db).items.iter().map(|&(_, it)| it.into()).collect() + } + AnyImplId::BuiltinDeriveImplId(impl_) => impl_ + .loc(db) + .trait_ + .all_methods() + .iter() + .map(|&method| { + AssocItem::Function(Function { + id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ }, + }) + }) + .collect(), + } } pub fn is_negative(self, db: &dyn HirDatabase) -> bool { - db.impl_signature(self.id).flags.contains(ImplFlags::NEGATIVE) + match self.id { + AnyImplId::ImplId(id) => db.impl_signature(id).flags.contains(ImplFlags::NEGATIVE), + AnyImplId::BuiltinDeriveImplId(_) => false, + } } pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { - db.impl_signature(self.id).flags.contains(ImplFlags::UNSAFE) + match self.id { + AnyImplId::ImplId(id) => db.impl_signature(id).flags.contains(ImplFlags::UNSAFE), + AnyImplId::BuiltinDeriveImplId(_) => false, + } } pub fn module(self, db: &dyn HirDatabase) -> Module { - self.id.lookup(db).container.into() - } - - pub fn as_builtin_derive_path(self, db: &dyn HirDatabase) -> Option> { - let src = self.source(db)?; - - let macro_file = src.file_id.macro_file()?; - let loc = macro_file.lookup(db); - let (derive_attr, derive_index) = match loc.kind { - MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, .. } => { - let module_id = self.id.lookup(db).container; - ( - module_id.def_map(db)[module_id] - .scope - .derive_macro_invoc(ast_id, derive_attr_index)?, - derive_index, - ) - } - _ => return None, - }; - let path = db - .parse_macro_expansion(derive_attr) - .value - .0 - .syntax_node() - .children() - .nth(derive_index as usize) - .and_then(::cast) - .and_then(|it| it.path())?; - Some(InMacroFile { file_id: derive_attr, value: path }) + match self.id { + AnyImplId::ImplId(id) => id.module(db).into(), + AnyImplId::BuiltinDeriveImplId(id) => id.module(db).into(), + } } pub fn check_orphan_rules(self, db: &dyn HirDatabase) -> bool { - check_orphan_rules(db, self.id) + match self.id { + AnyImplId::ImplId(id) => check_orphan_rules(db, id), + AnyImplId::BuiltinDeriveImplId(_) => true, + } } fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId, MacroCallId)]> { - self.id.impl_items(db).macro_calls.to_vec().into_boxed_slice() + match self.id { + AnyImplId::ImplId(id) => id.impl_items(db).macro_calls.to_vec().into_boxed_slice(), + AnyImplId::BuiltinDeriveImplId(_) => Box::default(), + } } } @@ -5540,7 +5865,7 @@ impl<'db> Type<'db> { else { unreachable!("`Mode::MethodCall` can only return functions"); }; - let id = Function { id }; + let id = Function { id: AnyFunctionId::FunctionId(id) }; match candidate.kind { method_resolution::PickKind::InherentImplPick(_) | method_resolution::PickKind::ObjectPick(..) @@ -5564,7 +5889,7 @@ impl<'db> Type<'db> { else { unreachable!("`Mode::MethodCall` can only return functions"); }; - let id = Function { id }; + let id = Function { id: AnyFunctionId::FunctionId(id) }; match candidate.candidate.kind { method_resolution::CandidateKind::InherentImplCandidate { .. @@ -5919,6 +6244,7 @@ enum Callee<'db> { CoroutineClosure(InternedCoroutineId, GenericArgs<'db>), FnPtr, FnImpl(traits::FnTrait), + BuiltinDeriveImplMethod { method: BuiltinDeriveImplMethod, impl_: BuiltinDeriveImplId }, } pub enum CallableKind<'db> { @@ -5934,6 +6260,9 @@ impl<'db> Callable<'db> { pub fn kind(&self) -> CallableKind<'db> { match self.callee { Callee::Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()), + Callee::BuiltinDeriveImplMethod { method, impl_ } => CallableKind::Function(Function { + id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ }, + }), Callee::Def(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()), Callee::Def(CallableDefId::EnumVariantId(it)) => { CallableKind::TupleEnumVariant(it.into()) @@ -5948,12 +6277,22 @@ impl<'db> Callable<'db> { Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_.into()), } } + + fn as_function(&self) -> Option { + match self.callee { + Callee::Def(CallableDefId::FunctionId(it)) => Some(it.into()), + Callee::BuiltinDeriveImplMethod { method, impl_ } => { + Some(Function { id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } }) + } + _ => None, + } + } + pub fn receiver_param(&self, db: &'db dyn HirDatabase) -> Option<(SelfParam, Type<'db>)> { - let func = match self.callee { - Callee::Def(CallableDefId::FunctionId(it)) if self.is_bound_method => it, - _ => return None, - }; - let func = Function { id: func }; + if !self.is_bound_method { + return None; + } + let func = self.as_function()?; Some(( func.self_param(db)?, self.ty.derived(self.sig.skip_binder().inputs_and_output.inputs()[0]), @@ -6350,7 +6689,12 @@ impl HasContainer for Module { impl HasContainer for Function { fn container(&self, db: &dyn HirDatabase) -> ItemContainer { - container_id_to_hir(self.id.lookup(db).container) + match self.id { + AnyFunctionId::FunctionId(id) => container_id_to_hir(id.lookup(db).container), + AnyFunctionId::BuiltinDeriveImplMethod { impl_, .. } => { + ItemContainer::Impl(Impl { id: AnyImplId::BuiltinDeriveImplId(impl_) }) + } + } } } @@ -6402,11 +6746,79 @@ impl HasContainer for ExternBlock { } } +pub trait HasName { + fn name(&self, db: &dyn HirDatabase) -> Option; +} + +macro_rules! impl_has_name { + ( $( $ty:ident ),* $(,)? ) => { + $( + impl HasName for $ty { + fn name(&self, db: &dyn HirDatabase) -> Option { + (*self).name(db).into() + } + } + )* + }; +} + +impl_has_name!( + ModuleDef, + Module, + Field, + Struct, + Union, + Enum, + Variant, + Adt, + VariantDef, + DefWithBody, + Function, + ExternCrateDecl, + Const, + Static, + Trait, + TypeAlias, + Macro, + ExternAssocItem, + AssocItem, + Local, + DeriveHelper, + ToolModule, + Label, + GenericParam, + TypeParam, + LifetimeParam, + ConstParam, + TypeOrConstParam, + InlineAsmOperand, +); + +macro_rules! impl_has_name_no_db { + ( $( $ty:ident ),* $(,)? ) => { + $( + impl HasName for $ty { + fn name(&self, _db: &dyn HirDatabase) -> Option { + (*self).name().into() + } + } + )* + }; +} + +impl_has_name_no_db!(TupleField, StaticLifetime, BuiltinType, BuiltinAttr); + +impl HasName for Param<'_> { + fn name(&self, db: &dyn HirDatabase) -> Option { + self.name(db) + } +} + fn container_id_to_hir(c: ItemContainerId) -> ItemContainer { match c { ItemContainerId::ExternBlockId(id) => ItemContainer::ExternBlock(ExternBlock { id }), ItemContainerId::ModuleId(id) => ItemContainer::Module(Module { id }), - ItemContainerId::ImplId(id) => ItemContainer::Impl(Impl { id }), + ItemContainerId::ImplId(id) => ItemContainer::Impl(id.into()), ItemContainerId::TraitId(id) => ItemContainer::Trait(Trait { id }), } } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index fcb97ab34e93..485011c38d7e 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -13,7 +13,7 @@ use std::{ use base_db::FxIndexSet; use either::Either; use hir_def::{ - DefWithBodyId, FunctionId, MacroId, StructId, TraitId, VariantId, + DefWithBodyId, MacroId, StructId, TraitId, VariantId, attrs::parse_extra_crate_attrs, expr_store::{Body, ExprOrPatSource, HygieneId, path::Path}, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, @@ -34,7 +34,7 @@ use hir_ty::{ diagnostics::{unsafe_operations, unsafe_operations_for_body}, infer_query_with_inspect, next_solver::{ - DbInterner, Span, + AnyImplId, DbInterner, Span, format_proof_tree::{ProofTreeData, dump_proof_tree_structured}, }, }; @@ -53,11 +53,11 @@ use syntax::{ }; use crate::{ - Adjust, Adjustment, Adt, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const, ConstParam, - Crate, DefWithBody, DeriveHelper, Enum, Field, Function, GenericSubstitution, HasSource, Impl, - InFile, InlineAsmOperand, ItemInNs, Label, LifetimeParam, Local, Macro, Module, ModuleDef, - Name, OverloadedDeref, ScopeDef, Static, Struct, ToolModule, Trait, TupleField, Type, - TypeAlias, TypeParam, Union, Variant, VariantDef, + Adjust, Adjustment, Adt, AnyFunctionId, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const, + ConstParam, Crate, DefWithBody, DeriveHelper, Enum, Field, Function, GenericSubstitution, + HasSource, Impl, InFile, InlineAsmOperand, ItemInNs, Label, LifetimeParam, Local, Macro, + Module, ModuleDef, Name, OverloadedDeref, ScopeDef, Static, Struct, ToolModule, Trait, + TupleField, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, db::HirDatabase, semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{SourceAnalyzer, resolve_hir_path}, @@ -106,7 +106,10 @@ impl PathResolution { | PathResolution::DeriveHelper(_) | PathResolution::ConstParam(_) => None, PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())), - PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())), + PathResolution::SelfType(impl_def) => match impl_def.id { + AnyImplId::ImplId(id) => Some(TypeNs::SelfType(id)), + AnyImplId::BuiltinDeriveImplId(_) => None, + }, } } } @@ -345,23 +348,23 @@ impl Semantics<'_, DB> { } pub fn resolve_await_to_poll(&self, await_expr: &ast::AwaitExpr) -> Option { - self.imp.resolve_await_to_poll(await_expr).map(Function::from) + self.imp.resolve_await_to_poll(await_expr) } pub fn resolve_prefix_expr(&self, prefix_expr: &ast::PrefixExpr) -> Option { - self.imp.resolve_prefix_expr(prefix_expr).map(Function::from) + self.imp.resolve_prefix_expr(prefix_expr) } pub fn resolve_index_expr(&self, index_expr: &ast::IndexExpr) -> Option { - self.imp.resolve_index_expr(index_expr).map(Function::from) + self.imp.resolve_index_expr(index_expr) } pub fn resolve_bin_expr(&self, bin_expr: &ast::BinExpr) -> Option { - self.imp.resolve_bin_expr(bin_expr).map(Function::from) + self.imp.resolve_bin_expr(bin_expr) } pub fn resolve_try_expr(&self, try_expr: &ast::TryExpr) -> Option { - self.imp.resolve_try_expr(try_expr).map(Function::from) + self.imp.resolve_try_expr(try_expr) } pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option { @@ -1749,6 +1752,7 @@ impl<'db> SemanticsImpl<'db> { func: Function, subst: impl IntoIterator>, ) -> Option { + let AnyFunctionId::FunctionId(func) = func.id else { return Some(func) }; let interner = DbInterner::new_no_crate(self.db); let mut subst = subst.into_iter(); let substs = @@ -1757,7 +1761,12 @@ impl<'db> SemanticsImpl<'db> { subst.next().expect("too few subst").ty.into() }); assert!(subst.next().is_none(), "too many subst"); - Some(self.db.lookup_impl_method(env.env, func.into(), substs).0.into()) + Some(match self.db.lookup_impl_method(env.env, func, substs).0 { + Either::Left(it) => it.into(), + Either::Right((impl_, method)) => { + Function { id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } } + } + }) } fn resolve_range_pat(&self, range_pat: &ast::RangePat) -> Option { @@ -1768,23 +1777,23 @@ impl<'db> SemanticsImpl<'db> { self.analyze(range_expr.syntax())?.resolve_range_expr(self.db, range_expr) } - fn resolve_await_to_poll(&self, await_expr: &ast::AwaitExpr) -> Option { + fn resolve_await_to_poll(&self, await_expr: &ast::AwaitExpr) -> Option { self.analyze(await_expr.syntax())?.resolve_await_to_poll(self.db, await_expr) } - fn resolve_prefix_expr(&self, prefix_expr: &ast::PrefixExpr) -> Option { + fn resolve_prefix_expr(&self, prefix_expr: &ast::PrefixExpr) -> Option { self.analyze(prefix_expr.syntax())?.resolve_prefix_expr(self.db, prefix_expr) } - fn resolve_index_expr(&self, index_expr: &ast::IndexExpr) -> Option { + fn resolve_index_expr(&self, index_expr: &ast::IndexExpr) -> Option { self.analyze(index_expr.syntax())?.resolve_index_expr(self.db, index_expr) } - fn resolve_bin_expr(&self, bin_expr: &ast::BinExpr) -> Option { + fn resolve_bin_expr(&self, bin_expr: &ast::BinExpr) -> Option { self.analyze(bin_expr.syntax())?.resolve_bin_expr(self.db, bin_expr) } - fn resolve_try_expr(&self, try_expr: &ast::TryExpr) -> Option { + fn resolve_try_expr(&self, try_expr: &ast::TryExpr) -> Option { self.analyze(try_expr.syntax())?.resolve_try_expr(self.db, try_expr) } @@ -1861,7 +1870,9 @@ impl<'db> SemanticsImpl<'db> { } pub fn get_unsafe_ops(&self, def: DefWithBody) -> FxHashSet { - let def = DefWithBodyId::from(def); + let Ok(def) = DefWithBodyId::try_from(def) else { + return FxHashSet::default(); + }; let (body, source_map) = self.db.body_with_source_map(def); let infer = InferenceResult::for_body(self.db, def); let mut res = FxHashSet::default(); @@ -1877,7 +1888,9 @@ impl<'db> SemanticsImpl<'db> { always!(block.unsafe_token().is_some()); let block = self.wrap_node_infile(ast::Expr::from(block)); let Some(def) = self.body_for(block.syntax()) else { return Vec::new() }; - let def = def.into(); + let Ok(def) = def.try_into() else { + return Vec::new(); + }; let (body, source_map) = self.db.body_with_source_map(def); let infer = InferenceResult::for_body(self.db, def); let Some(ExprOrPatId::ExprId(block)) = source_map.node_expr(block.as_ref()) else { @@ -2023,16 +2036,22 @@ impl<'db> SemanticsImpl<'db> { } /// Search for a definition's source and cache its syntax tree - pub fn source(&self, def: Def) -> Option> - where - Def::Ast: AstNode, - { + pub fn source(&self, def: Def) -> Option> { // FIXME: source call should go through the parse cache let res = def.source(self.db)?; self.cache(find_root(res.value.syntax()), res.file_id); Some(res) } + pub fn source_with_range( + &self, + def: Def, + ) -> Option)>> { + let res = def.source_with_range(self.db)?; + self.parse_or_expand(res.file_id); + Some(res) + } + pub fn body_for(&self, node: InFile<&SyntaxNode>) -> Option { let container = self.with_ctx(|ctx| ctx.find_container(node))?; @@ -2162,9 +2181,10 @@ impl<'db> SemanticsImpl<'db> { let def = match &enclosing_item { Either::Left(ast::Item::Fn(it)) if it.unsafe_token().is_some() => return true, - Either::Left(ast::Item::Fn(it)) => { - self.to_def(it).map(<_>::into).map(DefWithBodyId::FunctionId) - } + Either::Left(ast::Item::Fn(it)) => (|| match self.to_def(it)?.id { + AnyFunctionId::FunctionId(id) => Some(DefWithBodyId::FunctionId(id)), + AnyFunctionId::BuiltinDeriveImplMethod { .. } => None, + })(), Either::Left(ast::Item::Const(it)) => { self.to_def(it).map(<_>::into).map(DefWithBodyId::ConstId) } @@ -2201,7 +2221,11 @@ impl<'db> SemanticsImpl<'db> { } pub fn impl_generated_from_derive(&self, impl_: Impl) -> Option { - let source = hir_def::src::HasSource::ast_ptr(&impl_.id.loc(self.db), self.db); + let id = match impl_.id { + AnyImplId::ImplId(id) => id, + AnyImplId::BuiltinDeriveImplId(id) => return Some(id.loc(self.db).adt.into()), + }; + let source = hir_def::src::HasSource::ast_ptr(&id.loc(self.db), self.db); let mut file_id = source.file_id; let adt_ast_id = loop { let macro_call = file_id.macro_file()?; diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 848ad3380133..bf123e13f94d 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -57,9 +57,9 @@ use syntax::{ use triomphe::Arc; use crate::{ - Adt, AssocItem, BindingMode, BuiltinAttr, BuiltinType, Callable, Const, DeriveHelper, Field, - Function, GenericSubstitution, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait, - TupleField, Type, TypeAlias, Variant, + Adt, AnyFunctionId, AssocItem, BindingMode, BuiltinAttr, BuiltinType, Callable, Const, + DeriveHelper, Field, Function, GenericSubstitution, Local, Macro, ModuleDef, Static, Struct, + ToolModule, Trait, TupleField, Type, TypeAlias, Variant, db::HirDatabase, semantics::{PathResolution, PathResolutionPerNs}, }; @@ -431,7 +431,7 @@ impl<'db> SourceAnalyzer<'db> { let expr_id = self.expr_id(call.clone().into())?.as_expr()?; let (f_in_trait, substs) = self.infer()?.method_resolution(expr_id)?; - Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs).into()) + Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs)) } pub(crate) fn resolve_method_call_fallback( @@ -446,8 +446,8 @@ impl<'db> SourceAnalyzer<'db> { let (fn_, subst) = self.resolve_impl_method_or_trait_def_with_subst(db, f_in_trait, substs); Some(( - Either::Left(fn_.into()), - Some(GenericSubstitution::new(fn_.into(), subst, self.trait_environment(db))), + Either::Left(fn_), + GenericSubstitution::new_from_fn(fn_, subst, self.trait_environment(db)), )) } None => { @@ -519,8 +519,8 @@ impl<'db> SourceAnalyzer<'db> { None => inference_result.method_resolution(expr_id).map(|(f, substs)| { let (f, subst) = self.resolve_impl_method_or_trait_def_with_subst(db, f, substs); ( - Either::Right(f.into()), - Some(GenericSubstitution::new(f.into(), subst, self.trait_environment(db))), + Either::Right(f), + GenericSubstitution::new_from_fn(f, subst, self.trait_environment(db)), ) }), } @@ -569,7 +569,7 @@ impl<'db> SourceAnalyzer<'db> { &self, db: &'db dyn HirDatabase, await_expr: &ast::AwaitExpr, - ) -> Option { + ) -> Option { let mut ty = self.ty_of_expr(await_expr.expr()?)?; let into_future_trait = self @@ -605,7 +605,7 @@ impl<'db> SourceAnalyzer<'db> { &self, db: &'db dyn HirDatabase, prefix_expr: &ast::PrefixExpr, - ) -> Option { + ) -> Option { let (_op_trait, op_fn) = match prefix_expr.op_kind()? { ast::UnaryOp::Deref => { // This can be either `Deref::deref` or `DerefMut::deref_mut`. @@ -650,7 +650,7 @@ impl<'db> SourceAnalyzer<'db> { &self, db: &'db dyn HirDatabase, index_expr: &ast::IndexExpr, - ) -> Option { + ) -> Option { let base_ty = self.ty_of_expr(index_expr.base()?)?; let index_ty = self.ty_of_expr(index_expr.index()?)?; @@ -679,7 +679,7 @@ impl<'db> SourceAnalyzer<'db> { &self, db: &'db dyn HirDatabase, binop_expr: &ast::BinExpr, - ) -> Option { + ) -> Option { let op = binop_expr.op_kind()?; let lhs = self.ty_of_expr(binop_expr.lhs()?)?; let rhs = self.ty_of_expr(binop_expr.rhs()?)?; @@ -699,7 +699,7 @@ impl<'db> SourceAnalyzer<'db> { &self, db: &'db dyn HirDatabase, try_expr: &ast::TryExpr, - ) -> Option { + ) -> Option { let ty = self.ty_of_expr(try_expr.expr()?)?; let op_fn = self.lang_items(db).TryTraitBranch?; @@ -905,7 +905,7 @@ impl<'db> SourceAnalyzer<'db> { subs, self.trait_environment(db), ); - (AssocItemId::from(f_in_trait), subst) + (AssocItem::Function(f_in_trait.into()), Some(subst)) } Some(func_ty) => { if let TyKind::FnDef(_fn_def, subs) = func_ty.kind() { @@ -913,19 +913,19 @@ impl<'db> SourceAnalyzer<'db> { .resolve_impl_method_or_trait_def_with_subst( db, f_in_trait, subs, ); - let subst = GenericSubstitution::new( - fn_.into(), + let subst = GenericSubstitution::new_from_fn( + fn_, subst, self.trait_environment(db), ); - (fn_.into(), subst) + (AssocItem::Function(fn_), subst) } else { let subst = GenericSubstitution::new( f_in_trait.into(), subs, self.trait_environment(db), ); - (f_in_trait.into(), subst) + (AssocItem::Function(f_in_trait.into()), Some(subst)) } } } @@ -938,11 +938,11 @@ impl<'db> SourceAnalyzer<'db> { subst, self.trait_environment(db), ); - (konst.into(), subst) + (AssocItem::Const(konst.into()), Some(subst)) } }; - return Some((PathResolution::Def(AssocItem::from(assoc).into()), Some(subst))); + return Some((PathResolution::Def(assoc.into()), subst)); } if let Some(VariantId::EnumVariantId(variant)) = infer.variant_resolution_for_expr_or_pat(expr_id) @@ -1401,7 +1401,7 @@ impl<'db> SourceAnalyzer<'db> { db: &'db dyn HirDatabase, func: FunctionId, substs: GenericArgs<'db>, - ) -> FunctionId { + ) -> Function { self.resolve_impl_method_or_trait_def_with_subst(db, func, substs).0 } @@ -1410,13 +1410,19 @@ impl<'db> SourceAnalyzer<'db> { db: &'db dyn HirDatabase, func: FunctionId, substs: GenericArgs<'db>, - ) -> (FunctionId, GenericArgs<'db>) { + ) -> (Function, GenericArgs<'db>) { let owner = match self.resolver.body_owner() { Some(it) => it, - None => return (func, substs), + None => return (func.into(), substs), }; let env = self.param_and(db.trait_environment_for_body(owner)); - db.lookup_impl_method(env, func, substs) + let (func, args) = db.lookup_impl_method(env, func, substs); + match func { + Either::Left(func) => (func.into(), args), + Either::Right((impl_, method)) => { + (Function { id: AnyFunctionId::BuiltinDeriveImplMethod { method, impl_ } }, args) + } + } } fn resolve_impl_const_or_trait_def_with_subst( diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 953bc73da9d8..7692a7d61abf 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -734,11 +734,11 @@ FileSymbol { name: "generic_impl_fn", def: Function( - Function { - id: FunctionId( + FunctionId( + FunctionId( 6402, ), - }, + ), ), loc: DeclarationLocation { hir_file_id: FileId( @@ -769,11 +769,11 @@ FileSymbol { name: "impl_fn", def: Function( - Function { - id: FunctionId( + FunctionId( + FunctionId( 6401, ), - }, + ), ), loc: DeclarationLocation { hir_file_id: FileId( @@ -839,11 +839,11 @@ FileSymbol { name: "main", def: Function( - Function { - id: FunctionId( + FunctionId( + FunctionId( 6400, ), - }, + ), ), loc: DeclarationLocation { hir_file_id: FileId( @@ -907,11 +907,11 @@ FileSymbol { name: "trait_fn", def: Function( - Function { - id: FunctionId( + FunctionId( + FunctionId( 6403, ), - }, + ), ), loc: DeclarationLocation { hir_file_id: FileId( diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index f57f2883b1c3..06ae0b1d73d1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -767,14 +767,30 @@ fn label_of_ty( ) }); + let module_def_location = |label_builder: &mut InlayHintLabelBuilder<'_>, + def: ModuleDef, + name| { + let def = def.try_into(); + if let Ok(def) = def { + label_builder.start_location_link(def); + } + #[expect( + clippy::question_mark, + reason = "false positive; replacing with `?` leads to 'type annotations needed' error" + )] + if let Err(err) = label_builder.write_str(name) { + return Err(err); + } + if def.is_ok() { + label_builder.end_location_link(); + } + Ok(()) + }; + label_builder.write_str(LABEL_START)?; - label_builder.start_location_link(ModuleDef::from(iter_trait).into()); - label_builder.write_str(LABEL_ITERATOR)?; - label_builder.end_location_link(); + module_def_location(label_builder, ModuleDef::from(iter_trait), LABEL_ITERATOR)?; label_builder.write_str(LABEL_MIDDLE)?; - label_builder.start_location_link(ModuleDef::from(item).into()); - label_builder.write_str(LABEL_ITEM)?; - label_builder.end_location_link(); + module_def_location(label_builder, ModuleDef::from(item), LABEL_ITEM)?; label_builder.write_str(LABEL_MIDDLE2)?; rec(sema, famous_defs, max_length, &ty, label_builder, config, display_target)?; label_builder.write_str(LABEL_END)?; diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs index 1317684a0877..e5e4c899ec03 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs @@ -34,9 +34,10 @@ pub(super) fn hints( let def = sema.to_def(node)?; let def: DefWithBody = def.into(); - let (hir, source_map) = sema.db.body_with_source_map(def.into()); + let def = def.try_into().ok()?; + let (hir, source_map) = sema.db.body_with_source_map(def); - let mir = sema.db.mir_body(def.into()).ok()?; + let mir = sema.db.mir_body(def).ok()?; let local_to_binding = mir.local_to_binding_map(); diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index 020f235d3a92..a271cac6fcd0 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -6,7 +6,7 @@ use arrayvec::ArrayVec; use either::Either; use hir::{ AssocItem, Crate, FieldSource, HasContainer, HasCrate, HasSource, HirDisplay, HirFileId, - InFile, LocalSource, ModuleSource, Semantics, Symbol, db::ExpandDatabase, sym, + InFile, LocalSource, ModuleSource, Name, Semantics, Symbol, db::ExpandDatabase, sym, symbols::FileSymbol, }; use ide_db::{ @@ -204,6 +204,22 @@ impl NavigationTarget { ) } + pub(crate) fn from_named_with_range( + db: &RootDatabase, + ranges: InFile<(TextRange, Option)>, + name: Option, + kind: SymbolKind, + ) -> UpmappingResult { + let InFile { file_id, value: (full_range, focus_range) } = ranges; + let name = name.map(|name| name.symbol().clone()).unwrap_or_else(|| sym::underscore); + + orig_range_with_focus_r(db, file_id, full_range, focus_range).map( + |(FileRange { file_id, range: full_range }, focus_range)| { + NavigationTarget::from_syntax(file_id, name.clone(), focus_range, full_range, kind) + }, + ) + } + pub(crate) fn from_syntax( file_id: FileId, name: Symbol, @@ -414,7 +430,13 @@ impl ToNavFromAst for hir::Trait { impl TryToNav for D where - D: HasSource + ToNavFromAst + Copy + HasDocs + for<'db> HirDisplay<'db> + HasCrate, + D: HasSource + + ToNavFromAst + + Copy + + HasDocs + + for<'db> HirDisplay<'db> + + HasCrate + + hir::HasName, D::Ast: ast::HasName, { fn try_to_nav( @@ -422,11 +444,19 @@ where sema: &Semantics<'_, RootDatabase>, ) -> Option> { let db = sema.db; - let src = self.source(db)?; + let src = self.source_with_range(db)?; Some( - NavigationTarget::from_named( + NavigationTarget::from_named_with_range( db, - src.as_ref().map(|it| it as &dyn ast::HasName), + src.map(|(full_range, node)| { + ( + full_range, + node.and_then(|node| { + Some(ast::HasName::name(&node)?.syntax().text_range()) + }), + ) + }), + self.name(db), D::KIND, ) .map(|mut res| { @@ -477,16 +507,16 @@ impl TryToNav for hir::Impl { sema: &Semantics<'_, RootDatabase>, ) -> Option> { let db = sema.db; - let InFile { file_id, value } = self.source(db)?; - let derive_path = self.as_builtin_derive_path(db); + let InFile { file_id, value: (full_range, source) } = self.source_with_range(db)?; - let (file_id, focus, syntax) = match &derive_path { - Some(attr) => (attr.file_id.into(), None, attr.value.syntax()), - None => (file_id, value.self_ty(), value.syntax()), - }; - - Some(orig_range_with_focus(db, file_id, syntax, focus).map( - |(FileRange { file_id, range: full_range }, focus_range)| { + Some( + orig_range_with_focus_r( + db, + file_id, + full_range, + source.and_then(|source| Some(source.self_ty()?.syntax().text_range())), + ) + .map(|(FileRange { file_id, range: full_range }, focus_range)| { NavigationTarget::from_syntax( file_id, sym::kw_impl, @@ -494,8 +524,8 @@ impl TryToNav for hir::Impl { full_range, SymbolKind::Impl, ) - }, - )) + }), + ) } } diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs index 0738b7fadcc1..ffae7bf6c7c5 100644 --- a/src/tools/rust-analyzer/crates/ide/src/references.rs +++ b/src/tools/rust-analyzer/crates/ide/src/references.rs @@ -2503,7 +2503,7 @@ fn r#fn$0() {} fn main() { r#fn(); } "#, expect![[r#" - r#fn Function FileId(0) 0..12 3..7 + fn Function FileId(0) 0..12 3..7 FileId(0) 25..29 "#]], diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index c562a9b30b04..6cec91250351 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -1679,11 +1679,11 @@ mod r#mod { [ "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 1..461, focus_range: 5..10, name: \"mod\", kind: Module, description: \"mod r#mod\" })", "(Test, NavigationTarget { file_id: FileId(0), full_range: 17..41, focus_range: 32..36, name: \"r#fn\", kind: Function })", - "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 47..84, name: \"r#for\", container_name: \"mod\" })", - "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 90..146, name: \"r#struct\", container_name: \"mod\" })", + "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 47..84, name: \"for\", container_name: \"mod\" })", + "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 90..146, name: \"struct\", container_name: \"mod\" })", "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 152..266, focus_range: 189..205, name: \"impl\", kind: Impl })", - "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 216..260, name: \"r#fn\" })", - "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 323..367, name: \"r#fn\" })", + "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 216..260, name: \"fn\" })", + "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 323..367, name: \"fn\" })", "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 401..459, focus_range: 445..456, name: \"impl\", kind: Impl })", ] "#]], diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index aa7e40c65848..3e325b2f990d 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -526,6 +526,9 @@ define_symbols! { arbitrary_self_types_pointers, supertrait_item_shadowing, hash, + partial_cmp, cmp, + CoerceUnsized, + DispatchFromDyn, define_opaque, } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 76256b0a2253..9374d97d83fb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -693,21 +693,24 @@ impl flags::AnalysisStats { let mut sw = self.stop_watch(); let mut all = 0; let mut fail = 0; - for &body_id in bodies { + for &body in bodies { bar.set_message(move || { - format!("mir lowering: {}", full_name(db, body_id, body_id.module(db))) + format!("mir lowering: {}", full_name(db, body, body.module(db))) }); bar.inc(1); - if matches!(body_id, DefWithBody::Variant(_)) { + if matches!(body, DefWithBody::Variant(_)) { continue; } - let module = body_id.module(db); - if !self.should_process(db, body_id, module) { + let module = body.module(db); + if !self.should_process(db, body, module) { continue; } all += 1; - let Err(e) = db.mir_body(body_id.into()) else { + let Ok(body_id) = body.try_into() else { + continue; + }; + let Err(e) = db.mir_body(body_id) else { continue; }; if verbosity.is_spammy() { @@ -716,7 +719,7 @@ impl flags::AnalysisStats { .into_iter() .rev() .filter_map(|it| it.name(db)) - .chain(Some(body_id.name(db).unwrap_or_else(Name::missing))) + .chain(Some(body.name(db).unwrap_or_else(Name::missing))) .map(|it| it.display(db, Edition::LATEST).to_string()) .join("::"); bar.println(format!("Mir body for {full_name} failed due {e:?}")); @@ -747,11 +750,12 @@ impl flags::AnalysisStats { if self.parallel { let mut inference_sw = self.stop_watch(); + let bodies = bodies.iter().filter_map(|&body| body.try_into().ok()).collect::>(); bodies .par_iter() .map_with(db.clone(), |snap, &body| { - snap.body(body.into()); - InferenceResult::for_body(snap, body.into()); + snap.body(body); + InferenceResult::for_body(snap, body); }) .count(); eprintln!("{:<20} {}", "Parallel Inference:", inference_sw.elapsed()); @@ -769,6 +773,7 @@ impl flags::AnalysisStats { let mut num_pat_type_mismatches = 0; let mut panics = 0; for &body_id in bodies { + let Ok(body_def_id) = body_id.try_into() else { continue }; let name = body_id.name(db).unwrap_or_else(Name::missing); let module = body_id.module(db); let display_target = module.krate(db).to_display_target(db); @@ -807,9 +812,9 @@ impl flags::AnalysisStats { bar.println(msg()); } bar.set_message(msg); - let body = db.body(body_id.into()); + let body = db.body(body_def_id); let inference_result = - catch_unwind(AssertUnwindSafe(|| InferenceResult::for_body(db, body_id.into()))); + catch_unwind(AssertUnwindSafe(|| InferenceResult::for_body(db, body_def_id))); let inference_result = match inference_result { Ok(inference_result) => inference_result, Err(p) => { @@ -826,7 +831,7 @@ impl flags::AnalysisStats { } }; // This query is LRU'd, so actually calling it will skew the timing results. - let sm = || db.body_with_source_map(body_id.into()).1; + let sm = || db.body_with_source_map(body_def_id).1; // region:expressions let (previous_exprs, previous_unknown, previous_partially_unknown) = @@ -1081,6 +1086,7 @@ impl flags::AnalysisStats { let mut sw = self.stop_watch(); bar.tick(); for &body_id in bodies { + let Ok(body_def_id) = body_id.try_into() else { continue }; let module = body_id.module(db); if !self.should_process(db, body_id, module) { continue; @@ -1114,7 +1120,7 @@ impl flags::AnalysisStats { bar.println(msg()); } bar.set_message(msg); - db.body(body_id.into()); + db.body(body_def_id); bar.inc(1); } From 02763ff0ec8ac3e60a2c5508dbc7fda2b8900fee Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 26 Dec 2025 15:00:27 +0200 Subject: [PATCH 1257/3801] Test builtin derives expansions Via a hack to disable their fast path. --- .../builtin_derive_macro.rs | 1657 ++++++++--------- .../hir-def/src/macro_expansion_tests/mod.rs | 9 + .../crates/hir-def/src/nameres.rs | 19 + .../crates/hir-def/src/nameres/collector.rs | 5 +- 4 files changed, 857 insertions(+), 833 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs index 814afdd16cf9..0013c2a25679 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs @@ -1,833 +1,828 @@ //! Tests for `builtin_derive_macro.rs` from `hir_expand`. -// FIXME: This file is commented out because due to the fast path for builtin derives, -// the macros do not really get expanded, and we cannot check their expansion. -// It's not removed because we still need to find some way to do that nevertheless. -// Maybe going through the list of registered derive calls in the def map? - -// use expect_test::expect; - -// use crate::macro_expansion_tests::{check, check_errors}; - -// #[test] -// fn test_copy_expand_simple() { -// check( -// r#" -// //- minicore: derive, copy -// #[derive(Copy)] -// struct Foo; -// "#, -// expect![[r#" -// #[derive(Copy)] -// struct Foo; - -// impl <> $crate::marker::Copy for Foo< > where {}"#]], -// ); -// } - -// #[test] -// fn test_copy_expand_in_core() { -// check( -// r#" -// //- /lib.rs crate:core -// #[rustc_builtin_macro] -// macro derive {} -// #[rustc_builtin_macro] -// macro Copy {} -// #[derive(Copy)] -// struct Foo; -// "#, -// expect![[r#" -// #[rustc_builtin_macro] -// macro derive {} -// #[rustc_builtin_macro] -// macro Copy {} -// #[derive(Copy)] -// struct Foo; - -// impl <> $crate::marker::Copy for Foo< > where {}"#]], -// ); -// } - -// #[test] -// fn test_copy_expand_with_type_params() { -// check( -// r#" -// //- minicore: derive, copy -// #[derive(Copy)] -// struct Foo; -// "#, -// expect![[r#" -// #[derive(Copy)] -// struct Foo; - -// impl $crate::marker::Copy for Foo where {}"#]], -// ); -// } - -// #[test] -// fn test_copy_expand_with_lifetimes() { -// // We currently just ignore lifetimes -// check( -// r#" -// //- minicore: derive, copy -// #[derive(Copy)] -// struct Foo; -// "#, -// expect![[r#" -// #[derive(Copy)] -// struct Foo; - -// impl $crate::marker::Copy for Foo where {}"#]], -// ); -// } - -// #[test] -// fn test_clone_expand() { -// check( -// r#" -// //- minicore: derive, clone -// #[derive(Clone)] -// enum Command { -// Move { x: A, y: B }, -// Do(&'static str), -// Jump, -// } -// "#, -// expect![[r#" -// #[derive(Clone)] -// enum Command { -// Move { x: A, y: B }, -// Do(&'static str), -// Jump, -// } - -// impl $crate::clone::Clone for Command where { -// fn clone(&self ) -> Self { -// match self { -// Command::Move { -// x: x, y: y, -// } -// =>Command::Move { -// x: x.clone(), y: y.clone(), -// } -// , Command::Do(f0, )=>Command::Do(f0.clone(), ), Command::Jump=>Command::Jump, -// } -// } -// }"#]], -// ); -// } - -// #[test] -// fn test_clone_expand_with_associated_types() { -// check( -// r#" -// //- minicore: derive, clone -// trait Trait { -// type InWc; -// type InFieldQualified; -// type InFieldShorthand; -// type InGenericArg; -// } -// trait Marker {} -// struct Vec(T); - -// #[derive(Clone)] -// struct Foo -// where -// ::InWc: Marker, -// { -// qualified: ::InFieldQualified, -// shorthand: T::InFieldShorthand, -// generic: Vec, -// } -// "#, -// expect![[r#" -// trait Trait { -// type InWc; -// type InFieldQualified; -// type InFieldShorthand; -// type InGenericArg; -// } -// trait Marker {} -// struct Vec(T); - -// #[derive(Clone)] -// struct Foo -// where -// ::InWc: Marker, -// { -// qualified: ::InFieldQualified, -// shorthand: T::InFieldShorthand, -// generic: Vec, -// } - -// impl $crate::clone::Clone for Foo where ::InWc: Marker, T: Trait, T::InFieldShorthand: $crate::clone::Clone, T::InGenericArg: $crate::clone::Clone, { -// fn clone(&self ) -> Self { -// match self { -// Foo { -// qualified: qualified, shorthand: shorthand, generic: generic, -// } -// =>Foo { -// qualified: qualified.clone(), shorthand: shorthand.clone(), generic: generic.clone(), -// } -// , -// } -// } -// }"#]], -// ); -// } - -// #[test] -// fn test_clone_expand_with_const_generics() { -// check( -// r#" -// //- minicore: derive, clone -// #[derive(Clone)] -// struct Foo(u32); -// "#, -// expect![[r#" -// #[derive(Clone)] -// struct Foo(u32); - -// impl $crate::clone::Clone for Foo where { -// fn clone(&self ) -> Self { -// match self { -// Foo(f0, )=>Foo(f0.clone(), ), -// } -// } -// }"#]], -// ); -// } - -// #[test] -// fn test_default_expand() { -// check( -// r#" -// //- minicore: derive, default -// #[derive(Default)] -// struct Foo { -// field1: i32, -// field2: (), -// } -// #[derive(Default)] -// enum Bar { -// Foo(u8), -// #[default] -// Bar, -// } -// "#, -// expect![[r#" -// #[derive(Default)] -// struct Foo { -// field1: i32, -// field2: (), -// } -// #[derive(Default)] -// enum Bar { -// Foo(u8), -// #[default] -// Bar, -// } - -// impl <> $crate::default::Default for Foo< > where { -// fn default() -> Self { -// Foo { -// field1: $crate::default::Default::default(), field2: $crate::default::Default::default(), -// } -// } -// } -// impl <> $crate::default::Default for Bar< > where { -// fn default() -> Self { -// Bar::Bar -// } -// }"#]], -// ); -// } - -// #[test] -// fn test_partial_eq_expand() { -// check( -// r#" -// //- minicore: derive, eq -// #[derive(PartialEq, Eq)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } -// "#, -// expect![[r#" -// #[derive(PartialEq, Eq)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } - -// impl <> $crate::cmp::PartialEq for Command< > where { -// fn eq(&self , other: &Self ) -> bool { -// match (self , other) { -// (Command::Move { -// x: x_self, y: y_self, -// } -// , Command::Move { -// x: x_other, y: y_other, -// } -// )=>x_self.eq(x_other) && y_self.eq(y_other), (Command::Do(f0_self, ), Command::Do(f0_other, ))=>f0_self.eq(f0_other), (Command::Jump, Command::Jump)=>true , _unused=>false -// } -// } -// } -// impl <> $crate::cmp::Eq for Command< > where {}"#]], -// ); -// } - -// #[test] -// fn test_partial_eq_expand_with_derive_const() { -// // FIXME: actually expand with const -// check( -// r#" -// //- minicore: derive, eq -// #[derive_const(PartialEq, Eq)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } -// "#, -// expect![[r#" -// #[derive_const(PartialEq, Eq)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } - -// impl <> $crate::cmp::PartialEq for Command< > where { -// fn eq(&self , other: &Self ) -> bool { -// match (self , other) { -// (Command::Move { -// x: x_self, y: y_self, -// } -// , Command::Move { -// x: x_other, y: y_other, -// } -// )=>x_self.eq(x_other) && y_self.eq(y_other), (Command::Do(f0_self, ), Command::Do(f0_other, ))=>f0_self.eq(f0_other), (Command::Jump, Command::Jump)=>true , _unused=>false -// } -// } -// } -// impl <> $crate::cmp::Eq for Command< > where {}"#]], -// ); -// } - -// #[test] -// fn test_partial_ord_expand() { -// check( -// r#" -// //- minicore: derive, ord -// #[derive(PartialOrd, Ord)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } -// "#, -// expect![[r#" -// #[derive(PartialOrd, Ord)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } - -// impl <> $crate::cmp::PartialOrd for Command< > where { -// fn partial_cmp(&self , other: &Self ) -> $crate::option::Option<$crate::cmp::Ordering> { -// match $crate::intrinsics::discriminant_value(self ).partial_cmp(&$crate::intrinsics::discriminant_value(other)) { -// $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { -// match (self , other) { -// (Command::Move { -// x: x_self, y: y_self, -// } -// , Command::Move { -// x: x_other, y: y_other, -// } -// )=>match x_self.partial_cmp(&x_other) { -// $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { -// match y_self.partial_cmp(&y_other) { -// $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { -// $crate::option::Option::Some($crate::cmp::Ordering::Equal) -// } -// c=>return c, -// } -// } -// c=>return c, -// } -// , (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.partial_cmp(&f0_other) { -// $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { -// $crate::option::Option::Some($crate::cmp::Ordering::Equal) -// } -// c=>return c, -// } -// , (Command::Jump, Command::Jump)=>$crate::option::Option::Some($crate::cmp::Ordering::Equal), _unused=>$crate::option::Option::Some($crate::cmp::Ordering::Equal) -// } -// } -// c=>return c, -// } -// } -// } -// impl <> $crate::cmp::Ord for Command< > where { -// fn cmp(&self , other: &Self ) -> $crate::cmp::Ordering { -// match $crate::intrinsics::discriminant_value(self ).cmp(&$crate::intrinsics::discriminant_value(other)) { -// $crate::cmp::Ordering::Equal=> { -// match (self , other) { -// (Command::Move { -// x: x_self, y: y_self, -// } -// , Command::Move { -// x: x_other, y: y_other, -// } -// )=>match x_self.cmp(&x_other) { -// $crate::cmp::Ordering::Equal=> { -// match y_self.cmp(&y_other) { -// $crate::cmp::Ordering::Equal=> { -// $crate::cmp::Ordering::Equal -// } -// c=>return c, -// } -// } -// c=>return c, -// } -// , (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.cmp(&f0_other) { -// $crate::cmp::Ordering::Equal=> { -// $crate::cmp::Ordering::Equal -// } -// c=>return c, -// } -// , (Command::Jump, Command::Jump)=>$crate::cmp::Ordering::Equal, _unused=>$crate::cmp::Ordering::Equal -// } -// } -// c=>return c, -// } -// } -// }"#]], -// ); -// } - -// #[test] -// fn test_hash_expand() { -// check( -// r#" -// //- minicore: derive, hash -// use core::hash::Hash; - -// #[derive(Hash)] -// struct Foo { -// x: i32, -// y: u64, -// z: (i32, u64), -// } -// "#, -// expect![[r#" -// use core::hash::Hash; - -// #[derive(Hash)] -// struct Foo { -// x: i32, -// y: u64, -// z: (i32, u64), -// } - -// impl <> $crate::hash::Hash for Foo< > where { -// fn hash(&self , ra_expand_state: &mut H) { -// match self { -// Foo { -// x: x, y: y, z: z, -// } -// => { -// x.hash(ra_expand_state); -// y.hash(ra_expand_state); -// z.hash(ra_expand_state); -// } -// , -// } -// } -// }"#]], -// ); -// check( -// r#" -// //- minicore: derive, hash -// use core::hash::Hash; - -// #[derive(Hash)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } -// "#, -// expect![[r#" -// use core::hash::Hash; - -// #[derive(Hash)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } - -// impl <> $crate::hash::Hash for Command< > where { -// fn hash(&self , ra_expand_state: &mut H) { -// $crate::mem::discriminant(self ).hash(ra_expand_state); -// match self { -// Command::Move { -// x: x, y: y, -// } -// => { -// x.hash(ra_expand_state); -// y.hash(ra_expand_state); -// } -// , Command::Do(f0, )=> { -// f0.hash(ra_expand_state); -// } -// , Command::Jump=> {} -// , -// } -// } -// }"#]], -// ); -// } - -// #[test] -// fn test_debug_expand() { -// check( -// r#" -// //- minicore: derive, fmt -// use core::fmt::Debug; - -// #[derive(Debug)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } -// "#, -// expect![[r#" -// use core::fmt::Debug; - -// #[derive(Debug)] -// enum Command { -// Move { x: i32, y: i32 }, -// Do(&'static str), -// Jump, -// } - -// impl <> $crate::fmt::Debug for Command< > where { -// fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { -// match self { -// Command::Move { -// x: x, y: y, -// } -// =>f.debug_struct("Move").field("x", &x).field("y", &y).finish(), Command::Do(f0, )=>f.debug_tuple("Do").field(&f0).finish(), Command::Jump=>f.write_str("Jump"), -// } -// } -// }"#]], -// ); -// } -// #[test] -// fn test_debug_expand_with_cfg() { -// check( -// r#" -// //- minicore: derive, fmt -// use core::fmt::Debug; - -// #[derive(Debug)] -// struct HideAndShow { -// #[cfg(never)] -// always_hide: u32, -// #[cfg(not(never))] -// always_show: u32, -// } -// #[derive(Debug)] -// enum HideAndShowEnum { -// #[cfg(never)] -// AlwaysHide, -// #[cfg(not(never))] -// AlwaysShow{ -// #[cfg(never)] -// always_hide: u32, -// #[cfg(not(never))] -// always_show: u32, -// } -// } -// "#, -// expect![[r#" -// use core::fmt::Debug; - -// #[derive(Debug)] -// struct HideAndShow { -// #[cfg(never)] -// always_hide: u32, -// #[cfg(not(never))] -// always_show: u32, -// } -// #[derive(Debug)] -// enum HideAndShowEnum { -// #[cfg(never)] -// AlwaysHide, -// #[cfg(not(never))] -// AlwaysShow{ -// #[cfg(never)] -// always_hide: u32, -// #[cfg(not(never))] -// always_show: u32, -// } -// } - -// impl <> $crate::fmt::Debug for HideAndShow< > where { -// fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { -// match self { -// HideAndShow { -// always_show: always_show, -// } -// =>f.debug_struct("HideAndShow").field("always_show", &always_show).finish() -// } -// } -// } -// impl <> $crate::fmt::Debug for HideAndShowEnum< > where { -// fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { -// match self { -// HideAndShowEnum::AlwaysShow { -// always_show: always_show, -// } -// =>f.debug_struct("AlwaysShow").field("always_show", &always_show).finish(), -// } -// } -// }"#]], -// ); -// } -// #[test] -// fn test_default_expand_with_cfg() { -// check( -// r#" -// //- minicore: derive, default -// #[derive(Default)] -// struct Foo { -// field1: i32, -// #[cfg(never)] -// field2: (), -// #[cfg(feature = "never")] -// field3: (), -// #[cfg(not(feature = "never"))] -// field4: (), -// } -// #[derive(Default)] -// enum Bar { -// Foo, -// #[cfg_attr(not(never), default)] -// Bar, -// } -// "#, -// expect![[r##" -// #[derive(Default)] -// struct Foo { -// field1: i32, -// #[cfg(never)] -// field2: (), -// #[cfg(feature = "never")] -// field3: (), -// #[cfg(not(feature = "never"))] -// field4: (), -// } -// #[derive(Default)] -// enum Bar { -// Foo, -// #[cfg_attr(not(never), default)] -// Bar, -// } - -// impl <> $crate::default::Default for Foo< > where { -// fn default() -> Self { -// Foo { -// field1: $crate::default::Default::default(), field4: $crate::default::Default::default(), -// } -// } -// } -// impl <> $crate::default::Default for Bar< > where { -// fn default() -> Self { -// Bar::Bar -// } -// }"##]], -// ); -// } - -// #[test] -// fn coerce_pointee_expansion() { -// check( -// r#" -// //- minicore: coerce_pointee - -// use core::marker::CoercePointee; - -// pub trait Trait {} - -// #[derive(CoercePointee)] -// #[repr(transparent)] -// pub struct Foo<'a, T: ?Sized + Trait, #[pointee] U: ?Sized, const N: u32>(T) -// where -// U: Trait + ToString;"#, -// expect![[r#" - -// use core::marker::CoercePointee; - -// pub trait Trait {} - -// #[derive(CoercePointee)] -// #[repr(transparent)] -// pub struct Foo<'a, T: ?Sized + Trait, #[pointee] U: ?Sized, const N: u32>(T) -// where -// U: Trait + ToString; -// impl $crate::ops::DispatchFromDyn> for Foo where U: Trait +ToString, T: Trait<__S>, __S: ?Sized, __S: Trait<__S> +ToString, U: ::core::marker::Unsize<__S>, T:?Sized+Trait, U:?Sized, {} -// impl $crate::ops::CoerceUnsized> for Foo where U: Trait +ToString, T: Trait<__S>, __S: ?Sized, __S: Trait<__S> +ToString, U: ::core::marker::Unsize<__S>, T:?Sized+Trait, U:?Sized, {}"#]], -// ); -// } - -// #[test] -// fn coerce_pointee_errors() { -// check_errors( -// r#" -// //- minicore: coerce_pointee - -// use core::marker::CoercePointee; - -// #[derive(CoercePointee)] -// enum Enum {} - -// #[derive(CoercePointee)] -// struct Struct1; - -// #[derive(CoercePointee)] -// struct Struct2(); - -// #[derive(CoercePointee)] -// struct Struct3 {} - -// #[derive(CoercePointee)] -// struct Struct4(T); - -// #[derive(CoercePointee)] -// #[repr(transparent)] -// struct Struct5(i32); - -// #[derive(CoercePointee)] -// #[repr(transparent)] -// struct Struct6<#[pointee] T: ?Sized, #[pointee] U: ?Sized>(T, U); - -// #[derive(CoercePointee)] -// #[repr(transparent)] -// struct Struct7(T, U); - -// #[derive(CoercePointee)] -// #[repr(transparent)] -// struct Struct8<#[pointee] T, U: ?Sized>(T); - -// #[derive(CoercePointee)] -// #[repr(transparent)] -// struct Struct9(T); - -// #[derive(CoercePointee)] -// #[repr(transparent)] -// struct Struct9<#[pointee] T, U>(T) where T: ?Sized; -// "#, -// expect![[r#" -// 35..72: `CoercePointee` can only be derived on `struct`s -// 74..114: `CoercePointee` can only be derived on `struct`s with at least one field -// 116..158: `CoercePointee` can only be derived on `struct`s with at least one field -// 160..202: `CoercePointee` can only be derived on `struct`s with at least one field -// 204..258: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]` -// 260..326: `CoercePointee` can only be derived on `struct`s that are generic over at least one type -// 328..439: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits -// 441..530: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits -// 532..621: `derive(CoercePointee)` requires `T` to be marked `?Sized` -// 623..690: `derive(CoercePointee)` requires `T` to be marked `?Sized`"#]], -// ); -// } - -// #[test] -// fn union_derive() { -// check_errors( -// r#" -// //- minicore: clone, copy, default, fmt, hash, ord, eq, derive - -// #[derive(Copy)] -// union Foo1 { _v: () } -// #[derive(Clone)] -// union Foo2 { _v: () } -// #[derive(Default)] -// union Foo3 { _v: () } -// #[derive(Debug)] -// union Foo4 { _v: () } -// #[derive(Hash)] -// union Foo5 { _v: () } -// #[derive(Ord)] -// union Foo6 { _v: () } -// #[derive(PartialOrd)] -// union Foo7 { _v: () } -// #[derive(Eq)] -// union Foo8 { _v: () } -// #[derive(PartialEq)] -// union Foo9 { _v: () } -// "#, -// expect![[r#" -// 78..118: this trait cannot be derived for unions -// 119..157: this trait cannot be derived for unions -// 158..195: this trait cannot be derived for unions -// 196..232: this trait cannot be derived for unions -// 233..276: this trait cannot be derived for unions -// 313..355: this trait cannot be derived for unions"#]], -// ); -// } - -// #[test] -// fn default_enum_without_default_attr() { -// check_errors( -// r#" -// //- minicore: default, derive - -// #[derive(Default)] -// enum Foo { -// Bar, -// } -// "#, -// expect!["1..41: `#[derive(Default)]` on enum with no `#[default]`"], -// ); -// } - -// #[test] -// fn generic_enum_default() { -// check( -// r#" -// //- minicore: default, derive - -// #[derive(Default)] -// enum Foo { -// Bar(T), -// #[default] -// Baz, -// } -// "#, -// expect![[r#" - -// #[derive(Default)] -// enum Foo { -// Bar(T), -// #[default] -// Baz, -// } - -// impl $crate::default::Default for Foo where { -// fn default() -> Self { -// Foo::Baz -// } -// }"#]], -// ); -// } +use expect_test::expect; + +use crate::macro_expansion_tests::{check, check_errors}; + +#[test] +fn test_copy_expand_simple() { + check( + r#" +//- minicore: derive, copy +#[derive(Copy)] +struct Foo; +"#, + expect![[r#" +#[derive(Copy)] +struct Foo; + +impl <> $crate::marker::Copy for Foo< > where {}"#]], + ); +} + +#[test] +fn test_copy_expand_in_core() { + check( + r#" +//- /lib.rs crate:core +#[rustc_builtin_macro] +macro derive {} +#[rustc_builtin_macro] +macro Copy {} +#[derive(Copy)] +struct Foo; +"#, + expect![[r#" +#[rustc_builtin_macro] +macro derive {} +#[rustc_builtin_macro] +macro Copy {} +#[derive(Copy)] +struct Foo; + +impl <> $crate::marker::Copy for Foo< > where {}"#]], + ); +} + +#[test] +fn test_copy_expand_with_type_params() { + check( + r#" +//- minicore: derive, copy +#[derive(Copy)] +struct Foo; +"#, + expect![[r#" +#[derive(Copy)] +struct Foo; + +impl $crate::marker::Copy for Foo where {}"#]], + ); +} + +#[test] +fn test_copy_expand_with_lifetimes() { + // We currently just ignore lifetimes + check( + r#" +//- minicore: derive, copy +#[derive(Copy)] +struct Foo; +"#, + expect![[r#" +#[derive(Copy)] +struct Foo; + +impl $crate::marker::Copy for Foo where {}"#]], + ); +} + +#[test] +fn test_clone_expand() { + check( + r#" +//- minicore: derive, clone +#[derive(Clone)] +enum Command { + Move { x: A, y: B }, + Do(&'static str), + Jump, +} +"#, + expect![[r#" +#[derive(Clone)] +enum Command { + Move { x: A, y: B }, + Do(&'static str), + Jump, +} + +impl $crate::clone::Clone for Command where { + fn clone(&self ) -> Self { + match self { + Command::Move { + x: x, y: y, + } + =>Command::Move { + x: x.clone(), y: y.clone(), + } + , Command::Do(f0, )=>Command::Do(f0.clone(), ), Command::Jump=>Command::Jump, + } + } +}"#]], + ); +} + +#[test] +fn test_clone_expand_with_associated_types() { + check( + r#" +//- minicore: derive, clone +trait Trait { + type InWc; + type InFieldQualified; + type InFieldShorthand; + type InGenericArg; +} +trait Marker {} +struct Vec(T); + +#[derive(Clone)] +struct Foo +where + ::InWc: Marker, +{ + qualified: ::InFieldQualified, + shorthand: T::InFieldShorthand, + generic: Vec, +} +"#, + expect![[r#" +trait Trait { + type InWc; + type InFieldQualified; + type InFieldShorthand; + type InGenericArg; +} +trait Marker {} +struct Vec(T); + +#[derive(Clone)] +struct Foo +where + ::InWc: Marker, +{ + qualified: ::InFieldQualified, + shorthand: T::InFieldShorthand, + generic: Vec, +} + +impl $crate::clone::Clone for Foo where ::InWc: Marker, T: Trait, T::InFieldShorthand: $crate::clone::Clone, T::InGenericArg: $crate::clone::Clone, { + fn clone(&self ) -> Self { + match self { + Foo { + qualified: qualified, shorthand: shorthand, generic: generic, + } + =>Foo { + qualified: qualified.clone(), shorthand: shorthand.clone(), generic: generic.clone(), + } + , + } + } +}"#]], + ); +} + +#[test] +fn test_clone_expand_with_const_generics() { + check( + r#" +//- minicore: derive, clone +#[derive(Clone)] +struct Foo(u32); +"#, + expect![[r#" +#[derive(Clone)] +struct Foo(u32); + +impl $crate::clone::Clone for Foo where { + fn clone(&self ) -> Self { + match self { + Foo(f0, )=>Foo(f0.clone(), ), + } + } +}"#]], + ); +} + +#[test] +fn test_default_expand() { + check( + r#" +//- minicore: derive, default +#[derive(Default)] +struct Foo { + field1: i32, + field2: (), +} +#[derive(Default)] +enum Bar { + Foo(u8), + #[default] + Bar, +} +"#, + expect![[r#" +#[derive(Default)] +struct Foo { + field1: i32, + field2: (), +} +#[derive(Default)] +enum Bar { + Foo(u8), + #[default] + Bar, +} + +impl <> $crate::default::Default for Foo< > where { + fn default() -> Self { + Foo { + field1: $crate::default::Default::default(), field2: $crate::default::Default::default(), + } + } +} +impl <> $crate::default::Default for Bar< > where { + fn default() -> Self { + Bar::Bar + } +}"#]], + ); +} + +#[test] +fn test_partial_eq_expand() { + check( + r#" +//- minicore: derive, eq +#[derive(PartialEq, Eq)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} +"#, + expect![[r#" +#[derive(PartialEq, Eq)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} + +impl <> $crate::cmp::PartialEq for Command< > where { + fn eq(&self , other: &Self ) -> bool { + match (self , other) { + (Command::Move { + x: x_self, y: y_self, + } + , Command::Move { + x: x_other, y: y_other, + } + )=>x_self.eq(x_other) && y_self.eq(y_other), (Command::Do(f0_self, ), Command::Do(f0_other, ))=>f0_self.eq(f0_other), (Command::Jump, Command::Jump)=>true , _unused=>false + } + } +} +impl <> $crate::cmp::Eq for Command< > where {}"#]], + ); +} + +#[test] +fn test_partial_eq_expand_with_derive_const() { + // FIXME: actually expand with const + check( + r#" +//- minicore: derive, eq +#[derive_const(PartialEq, Eq)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} +"#, + expect![[r#" +#[derive_const(PartialEq, Eq)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} + +impl <> $crate::cmp::PartialEq for Command< > where { + fn eq(&self , other: &Self ) -> bool { + match (self , other) { + (Command::Move { + x: x_self, y: y_self, + } + , Command::Move { + x: x_other, y: y_other, + } + )=>x_self.eq(x_other) && y_self.eq(y_other), (Command::Do(f0_self, ), Command::Do(f0_other, ))=>f0_self.eq(f0_other), (Command::Jump, Command::Jump)=>true , _unused=>false + } + } +} +impl <> $crate::cmp::Eq for Command< > where {}"#]], + ); +} + +#[test] +fn test_partial_ord_expand() { + check( + r#" +//- minicore: derive, ord +#[derive(PartialOrd, Ord)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} +"#, + expect![[r#" +#[derive(PartialOrd, Ord)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} + +impl <> $crate::cmp::PartialOrd for Command< > where { + fn partial_cmp(&self , other: &Self ) -> $crate::option::Option<$crate::cmp::Ordering> { + match $crate::intrinsics::discriminant_value(self ).partial_cmp(&$crate::intrinsics::discriminant_value(other)) { + $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { + match (self , other) { + (Command::Move { + x: x_self, y: y_self, + } + , Command::Move { + x: x_other, y: y_other, + } + )=>match x_self.partial_cmp(&x_other) { + $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { + match y_self.partial_cmp(&y_other) { + $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { + $crate::option::Option::Some($crate::cmp::Ordering::Equal) + } + c=>return c, + } + } + c=>return c, + } + , (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.partial_cmp(&f0_other) { + $crate::option::Option::Some($crate::cmp::Ordering::Equal)=> { + $crate::option::Option::Some($crate::cmp::Ordering::Equal) + } + c=>return c, + } + , (Command::Jump, Command::Jump)=>$crate::option::Option::Some($crate::cmp::Ordering::Equal), _unused=>$crate::option::Option::Some($crate::cmp::Ordering::Equal) + } + } + c=>return c, + } + } +} +impl <> $crate::cmp::Ord for Command< > where { + fn cmp(&self , other: &Self ) -> $crate::cmp::Ordering { + match $crate::intrinsics::discriminant_value(self ).cmp(&$crate::intrinsics::discriminant_value(other)) { + $crate::cmp::Ordering::Equal=> { + match (self , other) { + (Command::Move { + x: x_self, y: y_self, + } + , Command::Move { + x: x_other, y: y_other, + } + )=>match x_self.cmp(&x_other) { + $crate::cmp::Ordering::Equal=> { + match y_self.cmp(&y_other) { + $crate::cmp::Ordering::Equal=> { + $crate::cmp::Ordering::Equal + } + c=>return c, + } + } + c=>return c, + } + , (Command::Do(f0_self, ), Command::Do(f0_other, ))=>match f0_self.cmp(&f0_other) { + $crate::cmp::Ordering::Equal=> { + $crate::cmp::Ordering::Equal + } + c=>return c, + } + , (Command::Jump, Command::Jump)=>$crate::cmp::Ordering::Equal, _unused=>$crate::cmp::Ordering::Equal + } + } + c=>return c, + } + } +}"#]], + ); +} + +#[test] +fn test_hash_expand() { + check( + r#" +//- minicore: derive, hash +use core::hash::Hash; + +#[derive(Hash)] +struct Foo { + x: i32, + y: u64, + z: (i32, u64), +} +"#, + expect![[r#" +use core::hash::Hash; + +#[derive(Hash)] +struct Foo { + x: i32, + y: u64, + z: (i32, u64), +} + +impl <> $crate::hash::Hash for Foo< > where { + fn hash(&self , ra_expand_state: &mut H) { + match self { + Foo { + x: x, y: y, z: z, + } + => { + x.hash(ra_expand_state); + y.hash(ra_expand_state); + z.hash(ra_expand_state); + } + , + } + } +}"#]], + ); + check( + r#" +//- minicore: derive, hash +use core::hash::Hash; + +#[derive(Hash)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} +"#, + expect![[r#" +use core::hash::Hash; + +#[derive(Hash)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} + +impl <> $crate::hash::Hash for Command< > where { + fn hash(&self , ra_expand_state: &mut H) { + $crate::mem::discriminant(self ).hash(ra_expand_state); + match self { + Command::Move { + x: x, y: y, + } + => { + x.hash(ra_expand_state); + y.hash(ra_expand_state); + } + , Command::Do(f0, )=> { + f0.hash(ra_expand_state); + } + , Command::Jump=> {} + , + } + } +}"#]], + ); +} + +#[test] +fn test_debug_expand() { + check( + r#" +//- minicore: derive, fmt +use core::fmt::Debug; + +#[derive(Debug)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} +"#, + expect![[r#" +use core::fmt::Debug; + +#[derive(Debug)] +enum Command { + Move { x: i32, y: i32 }, + Do(&'static str), + Jump, +} + +impl <> $crate::fmt::Debug for Command< > where { + fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { + match self { + Command::Move { + x: x, y: y, + } + =>f.debug_struct("Move").field("x", &x).field("y", &y).finish(), Command::Do(f0, )=>f.debug_tuple("Do").field(&f0).finish(), Command::Jump=>f.write_str("Jump"), + } + } +}"#]], + ); +} +#[test] +fn test_debug_expand_with_cfg() { + check( + r#" + //- minicore: derive, fmt + use core::fmt::Debug; + + #[derive(Debug)] + struct HideAndShow { + #[cfg(never)] + always_hide: u32, + #[cfg(not(never))] + always_show: u32, + } + #[derive(Debug)] + enum HideAndShowEnum { + #[cfg(never)] + AlwaysHide, + #[cfg(not(never))] + AlwaysShow{ + #[cfg(never)] + always_hide: u32, + #[cfg(not(never))] + always_show: u32, + } + } + "#, + expect![[r#" +use core::fmt::Debug; + +#[derive(Debug)] +struct HideAndShow { + #[cfg(never)] + always_hide: u32, + #[cfg(not(never))] + always_show: u32, +} +#[derive(Debug)] +enum HideAndShowEnum { + #[cfg(never)] + AlwaysHide, + #[cfg(not(never))] + AlwaysShow{ + #[cfg(never)] + always_hide: u32, + #[cfg(not(never))] + always_show: u32, + } +} + +impl <> $crate::fmt::Debug for HideAndShow< > where { + fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { + match self { + HideAndShow { + always_show: always_show, + } + =>f.debug_struct("HideAndShow").field("always_show", &always_show).finish() + } + } +} +impl <> $crate::fmt::Debug for HideAndShowEnum< > where { + fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result { + match self { + HideAndShowEnum::AlwaysShow { + always_show: always_show, + } + =>f.debug_struct("AlwaysShow").field("always_show", &always_show).finish(), + } + } +}"#]], + ); +} +#[test] +fn test_default_expand_with_cfg() { + check( + r#" +//- minicore: derive, default +#[derive(Default)] +struct Foo { + field1: i32, + #[cfg(never)] + field2: (), + #[cfg(feature = "never")] + field3: (), + #[cfg(not(feature = "never"))] + field4: (), +} +#[derive(Default)] +enum Bar { + Foo, + #[cfg_attr(not(never), default)] + Bar, +} +"#, + expect![[r##" +#[derive(Default)] +struct Foo { + field1: i32, + #[cfg(never)] + field2: (), + #[cfg(feature = "never")] + field3: (), + #[cfg(not(feature = "never"))] + field4: (), +} +#[derive(Default)] +enum Bar { + Foo, + #[cfg_attr(not(never), default)] + Bar, +} + +impl <> $crate::default::Default for Foo< > where { + fn default() -> Self { + Foo { + field1: $crate::default::Default::default(), field4: $crate::default::Default::default(), + } + } +} +impl <> $crate::default::Default for Bar< > where { + fn default() -> Self { + Bar::Bar + } +}"##]], + ); +} + +#[test] +fn coerce_pointee_expansion() { + check( + r#" +//- minicore: coerce_pointee + +use core::marker::CoercePointee; + +pub trait Trait {} + +#[derive(CoercePointee)] +#[repr(transparent)] +pub struct Foo<'a, T: ?Sized + Trait, #[pointee] U: ?Sized, const N: u32>(T) +where + U: Trait + ToString;"#, + expect![[r#" + +use core::marker::CoercePointee; + +pub trait Trait {} + +#[derive(CoercePointee)] +#[repr(transparent)] +pub struct Foo<'a, T: ?Sized + Trait, #[pointee] U: ?Sized, const N: u32>(T) +where + U: Trait + ToString; +impl $crate::ops::DispatchFromDyn> for Foo where U: Trait +ToString, T: Trait<__S>, __S: ?Sized, __S: Trait<__S> +ToString, U: ::core::marker::Unsize<__S>, T:?Sized+Trait, U:?Sized, {} +impl $crate::ops::CoerceUnsized> for Foo where U: Trait +ToString, T: Trait<__S>, __S: ?Sized, __S: Trait<__S> +ToString, U: ::core::marker::Unsize<__S>, T:?Sized+Trait, U:?Sized, {}"#]], + ); +} + +#[test] +fn coerce_pointee_errors() { + check_errors( + r#" +//- minicore: coerce_pointee + +use core::marker::CoercePointee; + +#[derive(CoercePointee)] +enum Enum {} + +#[derive(CoercePointee)] +struct Struct1; + +#[derive(CoercePointee)] +struct Struct2(); + +#[derive(CoercePointee)] +struct Struct3 {} + +#[derive(CoercePointee)] +struct Struct4(T); + +#[derive(CoercePointee)] +#[repr(transparent)] +struct Struct5(i32); + +#[derive(CoercePointee)] +#[repr(transparent)] +struct Struct6<#[pointee] T: ?Sized, #[pointee] U: ?Sized>(T, U); + +#[derive(CoercePointee)] +#[repr(transparent)] +struct Struct7(T, U); + +#[derive(CoercePointee)] +#[repr(transparent)] +struct Struct8<#[pointee] T, U: ?Sized>(T); + +#[derive(CoercePointee)] +#[repr(transparent)] +struct Struct9(T); + +#[derive(CoercePointee)] +#[repr(transparent)] +struct Struct9<#[pointee] T, U>(T) where T: ?Sized; +"#, + expect![[r#" + 35..72: `CoercePointee` can only be derived on `struct`s + 74..114: `CoercePointee` can only be derived on `struct`s with at least one field + 116..158: `CoercePointee` can only be derived on `struct`s with at least one field + 160..202: `CoercePointee` can only be derived on `struct`s with at least one field + 204..258: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]` + 260..326: `CoercePointee` can only be derived on `struct`s that are generic over at least one type + 328..439: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits + 441..530: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits + 532..621: `derive(CoercePointee)` requires `T` to be marked `?Sized` + 623..690: `derive(CoercePointee)` requires `T` to be marked `?Sized`"#]], + ); +} + +#[test] +fn union_derive() { + check_errors( + r#" +//- minicore: clone, copy, default, fmt, hash, ord, eq, derive + +#[derive(Copy)] +union Foo1 { _v: () } +#[derive(Clone)] +union Foo2 { _v: () } +#[derive(Default)] +union Foo3 { _v: () } +#[derive(Debug)] +union Foo4 { _v: () } +#[derive(Hash)] +union Foo5 { _v: () } +#[derive(Ord)] +union Foo6 { _v: () } +#[derive(PartialOrd)] +union Foo7 { _v: () } +#[derive(Eq)] +union Foo8 { _v: () } +#[derive(PartialEq)] +union Foo9 { _v: () } + "#, + expect![[r#" + 78..118: this trait cannot be derived for unions + 119..157: this trait cannot be derived for unions + 158..195: this trait cannot be derived for unions + 196..232: this trait cannot be derived for unions + 233..276: this trait cannot be derived for unions + 313..355: this trait cannot be derived for unions"#]], + ); +} + +#[test] +fn default_enum_without_default_attr() { + check_errors( + r#" +//- minicore: default, derive + +#[derive(Default)] +enum Foo { + Bar, +} + "#, + expect!["1..41: `#[derive(Default)]` on enum with no `#[default]`"], + ); +} + +#[test] +fn generic_enum_default() { + check( + r#" +//- minicore: default, derive + +#[derive(Default)] +enum Foo { + Bar(T), + #[default] + Baz, +} +"#, + expect![[r#" + +#[derive(Default)] +enum Foo { + Bar(T), + #[default] + Baz, +} + +impl $crate::default::Default for Foo where { + fn default() -> Self { + Foo::Baz + } +}"#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index 59bd9474a959..fa4409e11760 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -53,6 +53,8 @@ use crate::{ #[track_caller] fn check_errors(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { + crate::nameres::ENABLE_BUILTIN_DERIVE_FAST_PATH.set(false); + let db = TestDB::with_files(ra_fixture); let krate = db.fetch_test_crate(); let def_map = crate_def_map(&db, krate); @@ -80,10 +82,15 @@ fn check_errors(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) .sorted_unstable_by_key(|(range, _)| range.start()) .format_with("\n", |(range, err), format| format(&format_args!("{range:?}: {err}"))) .to_string(); + + crate::nameres::ENABLE_BUILTIN_DERIVE_FAST_PATH.set(true); + expect.assert_eq(&errors); } fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, mut expect: Expect) { + crate::nameres::ENABLE_BUILTIN_DERIVE_FAST_PATH.set(false); + let extra_proc_macros = vec![( r#" #[proc_macro_attribute] @@ -246,6 +253,8 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream } } + crate::nameres::ENABLE_BUILTIN_DERIVE_FAST_PATH.set(true); + expect.indent(false); expect.assert_eq(&expanded_text); } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 3f29619bcb62..59ca38c7c087 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -87,6 +87,25 @@ use crate::{ pub use self::path_resolution::ResolvePathResultPrefixInfo; +#[cfg(test)] +thread_local! { + /// HACK: In order to test builtin derive expansion, we gate their fast path with this atomic when cfg(test). + pub(crate) static ENABLE_BUILTIN_DERIVE_FAST_PATH: std::cell::Cell = + const { std::cell::Cell::new(true) }; +} + +#[inline] +#[cfg(test)] +fn enable_builtin_derive_fast_path() -> bool { + ENABLE_BUILTIN_DERIVE_FAST_PATH.get() +} + +#[inline(always)] +#[cfg(not(test))] +fn enable_builtin_derive_fast_path() -> bool { + true +} + const PREDEFINED_TOOLS: &[SmolStr] = &[ SmolStr::new_static("clippy"), SmolStr::new_static("rustfmt"), diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 8694ebe4e40a..a7f687a3168b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -1526,8 +1526,9 @@ impl<'db> DefCollector<'db> { } } - if let MacroDefKind::BuiltInDerive(_, builtin_derive) = - def_id.kind + if super::enable_builtin_derive_fast_path() + && let MacroDefKind::BuiltInDerive(_, builtin_derive) = + def_id.kind { self.deferred_builtin_derives .entry(ast_id.ast_id.upcast()) From 517411f143f43689add7f5739a200fbdf8e2d03a Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Thu, 25 Dec 2025 19:18:32 +0000 Subject: [PATCH 1258/3801] add const kind match --- compiler/rustc_ty_utils/src/consts.rs | 15 +++-------- .../printing_valtrees_supports_non_values.rs | 27 +++++++++++++++++++ ...inting_valtrees_supports_non_values.stderr | 26 ++++++++++++++++++ 3 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs create mode 100644 tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index d8d5b7fc75cc..9be8a48c740a 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -39,25 +39,16 @@ fn destructure_const<'tcx>( (field_consts, None) } ty::Adt(def, _) if def.variants().is_empty() => bug!("unreachable"), - ty::Adt(def, args) => { - let (variant_idx, branches) = if def.is_enum() { + ty::Adt(def, _) => { + let (variant_idx, field_consts) = if def.is_enum() { let (head, rest) = branches.split_first().unwrap(); (VariantIdx::from_u32(head.to_leaf().to_u32()), rest) } else { (FIRST_VARIANT, branches) }; - let fields = &def.variant(variant_idx).fields; - let mut field_consts = Vec::with_capacity(fields.len()); - - for (field, field_valtree) in iter::zip(fields, branches) { - let field_ty = field.ty(tcx, args); - let field_const = - ty::Const::new_value(tcx, field_valtree.to_value().valtree, field_ty); - field_consts.push(field_const); - } debug!(?field_consts); - (field_consts, Some(variant_idx)) + (field_consts.to_vec(), Some(variant_idx)) } ty::Tuple(elem_tys) => { let fields = iter::zip(*elem_tys, branches) diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs new file mode 100644 index 000000000000..fbe310f7de4c --- /dev/null +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs @@ -0,0 +1,27 @@ +//! Regression test for +//@ edition 2024 + +#![allow(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] + +#[derive(Eq, PartialEq, core::marker::ConstParamTy)] +struct Foo; + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +fn foo() {} + +fn bar() { + foo::<{ Option::Some:: { 0: N } }>; + //~^ ERROR the constant `Option::::Some(N)` is not of type `Foo` +} + +fn baz() { + foo::<{ Option::Some:: { 0: ::ASSOC } }>(); + //~^ ERROR the constant `Option::::Some(::ASSOC)` is not of type `Foo` +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr new file mode 100644 index 000000000000..8b2871f2b6d3 --- /dev/null +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr @@ -0,0 +1,26 @@ +error: the constant `Option::::Some(N)` is not of type `Foo` + --> $DIR/printing_valtrees_supports_non_values.rs:18:13 + | +LL | foo::<{ Option::Some:: { 0: N } }>; + | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | +note: required by a const generic parameter in `foo` + --> $DIR/printing_valtrees_supports_non_values.rs:15:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: the constant `Option::::Some(::ASSOC)` is not of type `Foo` + --> $DIR/printing_valtrees_supports_non_values.rs:23:13 + | +LL | foo::<{ Option::Some:: { 0: ::ASSOC } }>(); + | ^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | +note: required by a const generic parameter in `foo` + --> $DIR/printing_valtrees_supports_non_values.rs:15:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: aborting due to 2 previous errors + From 90e80f5b81976be03d46264a1b77625b55ae8c22 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 26 Dec 2025 16:38:46 +0100 Subject: [PATCH 1259/3801] Document relative and absolute paths handling in `--remap-path-prefix` --- src/doc/rustc/src/remap-source-paths.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/doc/rustc/src/remap-source-paths.md b/src/doc/rustc/src/remap-source-paths.md index 03f5d98091cc..ebe92d71158a 100644 --- a/src/doc/rustc/src/remap-source-paths.md +++ b/src/doc/rustc/src/remap-source-paths.md @@ -17,6 +17,20 @@ The replacement is purely textual, with no consideration of the current system's When multiple remappings are given and several of them match, the **last** matching one is applied. +### Relative paths + +Some build systems, such as Cargo, may compile crates using relative paths (for example, +`src/main.rs` instead of `/home/user/project/src/main.rs)`. + +`rustc` preserves these relative paths where possible. However, certain inputs +(like `#[path = "..."]`) and outputs (such as debug information) may still contain absolute paths. + +To ensure consistency, it’s recommended to remap both relative and absolute paths. + +```bash +rustc --remap-path-prefix "src/=/redacted/src" --remap-path-prefix "/home/user/project=/redacted" +``` + ### Example ```bash From 634251cba8edb4ebcd01e330c7241e14d76322a1 Mon Sep 17 00:00:00 2001 From: Devon Loehr Date: Fri, 26 Dec 2025 15:40:40 +0000 Subject: [PATCH 1260/3801] Accommodate upstream PassPlugin rename --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 95cbec1b37b4..733f5fd0df0a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -23,7 +23,11 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Passes/PassBuilder.h" +#if LLVM_VERSION_GE(22, 0) +#include "llvm/Plugins/PassPlugin.h" +#else #include "llvm/Passes/PassPlugin.h" +#endif #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/FileSystem.h" From e3185276936821063e1c4384083edc6dccd785cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Tue, 16 Dec 2025 08:38:45 +0100 Subject: [PATCH 1261/3801] Enable file locking support for Hurd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit like Illumos and AIX, Hurd was missed when originally introducing locking gates per target OS. building rustc on Hurd was broken as a result since 1.91. Signed-off-by: Fabian Grünbichler --- library/std/src/fs/tests.rs | 4 ++++ library/std/src/sys/fs/unix.rs | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index bcaafcfee787..ec2f2307ca30 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -212,6 +212,7 @@ fn file_test_io_seek_and_write() { target_os = "cygwin", target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "illumos", target_os = "linux", target_os = "netbsd", @@ -244,6 +245,7 @@ fn file_lock_multiple_shared() { target_os = "cygwin", target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "illumos", target_os = "linux", target_os = "netbsd", @@ -277,6 +279,7 @@ fn file_lock_blocking() { target_os = "cygwin", target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "illumos", target_os = "linux", target_os = "netbsd", @@ -307,6 +310,7 @@ fn file_lock_drop() { target_os = "cygwin", target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "illumos", target_os = "linux", target_os = "netbsd", diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index ee3cb54a5ee6..670bb425c0a2 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1305,6 +1305,7 @@ impl File { #[cfg(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -1330,6 +1331,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -1346,6 +1348,7 @@ impl File { #[cfg(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -1371,6 +1374,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -1387,6 +1391,7 @@ impl File { #[cfg(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -1428,6 +1433,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -1447,6 +1453,7 @@ impl File { #[cfg(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -1488,6 +1495,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -1507,6 +1515,7 @@ impl File { #[cfg(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", @@ -1532,6 +1541,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", target_os = "fuchsia", + target_os = "hurd", target_os = "linux", target_os = "netbsd", target_os = "openbsd", From 3d928721704670a5d11335688e5b4d958ae52756 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Dec 2025 17:20:55 +0100 Subject: [PATCH 1262/3801] Clean up `utils.goml` file --- tests/rustdoc-gui/sidebar-mobile.goml | 2 +- tests/rustdoc-gui/utils.goml | 47 +++++++++++++-------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index f828516d7624..b3ca6e023637 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -65,7 +65,7 @@ define-function: ( "check-colors", [theme, color, background], block { - call-function: ("switch-theme-mobile", {"theme": |theme|}) + call-function: ("switch-theme", {"theme": |theme|}) reload: // Open the sidebar menu. diff --git a/tests/rustdoc-gui/utils.goml b/tests/rustdoc-gui/utils.goml index e13aef6712f3..6addda4f33ff 100644 --- a/tests/rustdoc-gui/utils.goml +++ b/tests/rustdoc-gui/utils.goml @@ -1,35 +1,34 @@ // This file contains code to be re-used by other tests. + +define-function: ( + "open-settings-menu", + [], + block { + // Open the settings menu. + click: "rustdoc-toolbar .settings-menu" + // Wait for the popover to appear... + wait-for-css: ("#settings", {"display": "block"}) + } +) + +define-function: ( + "close-settings-menu", + [], + block { + click: "rustdoc-toolbar .settings-menu" + wait-for-css-false: ("#settings", {"display": "block"}) + } +) + define-function: ( "switch-theme", [theme], block { // Set the theme. - // Open the settings menu. - click: "rustdoc-toolbar .settings-menu" - // Wait for the popover to appear... - wait-for: "#settings" + call-function: ("open-settings-menu", {}) // Change the setting. click: "#theme-"+ |theme| - // Close the popover. - click: "rustdoc-toolbar .settings-menu" - // Ensure that the local storage was correctly updated. - assert-local-storage: {"rustdoc-theme": |theme|} - }, -) - -define-function: ( - "switch-theme-mobile", - [theme], - block { - // Set the theme. - // Open the settings menu. - click: "rustdoc-topbar .settings-menu" - // Wait for the popover to appear... - wait-for: "#settings" - // Change the setting. - click: "#theme-"+ |theme| - // Close the popover. - click: "rustdoc-topbar .settings-menu" + call-function: ("close-settings-menu", {}) // Ensure that the local storage was correctly updated. assert-local-storage: {"rustdoc-theme": |theme|} }, From f4e2f4991f0a04a761bcca2449665eec0a0007ff Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Dec 2025 17:52:35 +0100 Subject: [PATCH 1263/3801] If line number setting is disabled, do not make line numbers take space --- src/librustdoc/html/static/css/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 69a79f2736e7..b93e921dd5b7 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -997,7 +997,7 @@ rustdoc-topbar { .example-wrap [data-nosnippet] { width: calc(var(--example-wrap-digits-count) + var(--line-number-padding) * 2); } -.example-wrap pre > code { +.example-wrap:not(.hide-lines) pre > code { padding-left: calc( var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + var(--line-number-right-margin)); From 09f57eb96f8a7652eebae41a870e7af0f3fd65e6 Mon Sep 17 00:00:00 2001 From: BioTomateHP Date: Fri, 26 Dec 2025 18:05:59 +0100 Subject: [PATCH 1264/3801] Update hir.rs: fix typo, conform to max_width --- compiler/rustc_hir/src/hir.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e176c703b33e..a1fdb81f0ab3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -150,10 +150,13 @@ impl From for LifetimeSyntax { /// `LifetimeSource::OutlivesBound` or `LifetimeSource::PreciseCapturing` /// — there's no way to "elide" these lifetimes. #[derive(Debug, Copy, Clone, HashStable_Generic)] -// Raise the aligement to at least 4 bytes - this is relied on in other parts of the compiler(for pointer tagging): -// https://github.com/rust-lang/rust/blob/ce5fdd7d42aba9a2925692e11af2bd39cf37798a/compiler/rustc_data_structures/src/tagged_ptr.rs#L163 -// Removing this `repr(4)` will cause the compiler to not build on platforms like `m68k` Linux, where the aligement of u32 and usize is only 2. -// Since `repr(align)` may only raise aligement, this has no effect on platforms where the aligement is already sufficient. +// Raise the alignment to at least 4 bytes. +// This is relied on in other parts of the compiler (for pointer tagging): +// +// Removing this `repr(4)` will cause the compiler to not build on platforms +// like `m68k` Linux, where the alignment of u32 and usize is only 2. +// Since `repr(align)` may only raise alignment, this has no effect on +// platforms where the alignment is already sufficient. #[repr(align(4))] pub struct Lifetime { #[stable_hasher(ignore)] From abf22599e3fbe5898ea646b94f64ef888937641d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 26 Dec 2025 23:03:42 +0530 Subject: [PATCH 1265/3801] add bidirectionalHandler trait --- src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 705ac930ed9c..c35bb2ba8dde 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -93,12 +93,8 @@ impl<'env> ProcMacroSrv<'env> { pub type SubCallback = Box SubResponse + Send + Sync + 'static>; -pub enum SubRequest { - SourceText { file_id: EditionedFileId, start: u32, end: u32 }, -} - -pub enum SubResponse { - SourceTextResult { text: Option }, +pub trait BidirectionalHandler { + fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; From 8f141eaab3a9f95988e9d90a6bb68ae30e7d1004 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 26 Dec 2025 23:04:04 +0530 Subject: [PATCH 1266/3801] remove old subreq/resp constructs --- src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index c35bb2ba8dde..5f0273d7bc5b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -47,7 +47,7 @@ use std::{ }; use paths::{Utf8Path, Utf8PathBuf}; -use span::{EditionedFileId, Span}; +use span::Span; use temp_dir::TempDir; pub use crate::server_impl::token_id::SpanId; @@ -91,7 +91,7 @@ impl<'env> ProcMacroSrv<'env> { } } -pub type SubCallback = Box SubResponse + Send + Sync + 'static>; +pub type SubCallback = Box; pub trait BidirectionalHandler { fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option; From 8aa859476c5d2f878ac45049c864eee6d16ddbef Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 26 Dec 2025 23:04:19 +0530 Subject: [PATCH 1267/3801] adapt source_text to new handler --- .../src/server_impl/rust_analyzer_span.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 0bce67fcd9fe..ee834e37c15c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -14,7 +14,7 @@ use proc_macro::bridge::server; use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TextRange, TextSize}; use crate::{ - SubCallback, SubRequest, SubResponse, + SubCallback, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; @@ -156,14 +156,7 @@ impl server::Span for RaSpanServer { let start: u32 = span.range.start().into(); let end: u32 = span.range.end().into(); - let req = SubRequest::SourceText { file_id, start, end }; - - let cb = self.callback.as_mut()?; - let response = cb(req); - - match response { - SubResponse::SourceTextResult { text } => text, - } + self.callback.as_mut()?.source_text(file_id.file_id().index(), start, end) } fn parent(&mut self, _span: Self::Span) -> Option { From 94e16291e00883a9c8324f700460f76c9db4fe85 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Mon, 22 Dec 2025 00:16:21 +0100 Subject: [PATCH 1268/3801] Port `#[rustc_must_implement_one_of]` to attribute parser --- .../src/attributes/rustc_internal.rs | 47 ++++++++++ compiler/rustc_attr_parsing/src/context.rs | 17 +++- compiler/rustc_attr_parsing/src/parser.rs | 9 +- .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_hir_analysis/messages.ftl | 18 ---- .../rustc_hir_analysis/src/check/check.rs | 4 +- compiler/rustc_hir_analysis/src/collect.rs | 86 ++----------------- compiler/rustc_hir_analysis/src/errors.rs | 60 ------------- compiler/rustc_passes/messages.ftl | 18 +++- compiler/rustc_passes/src/check_attr.rs | 74 +++++++++++++--- compiler/rustc_passes/src/errors.rs | 55 ++++++++++-- compiler/rustc_session/messages.ftl | 2 + compiler/rustc_session/src/errors.rs | 7 ++ .../rustc_must_implement_one_of_misuse.rs | 6 +- .../rustc_must_implement_one_of_misuse.stderr | 37 ++++---- 16 files changed, 236 insertions(+), 208 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index be4e2210c5ee..922a5bd297ac 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1,4 +1,5 @@ use rustc_ast::{LitIntType, LitKind, MetaItemLit}; +use rustc_session::errors; use super::prelude::*; use super::util::parse_single_integer; @@ -13,6 +14,52 @@ impl NoArgsAttributeParser for RustcMainParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain; } +pub(crate) struct RustcMustImplementOneOfParser; + +impl SingleAttributeParser for RustcMustImplementOneOfParser { + const PATH: &[Symbol] = &[sym::rustc_must_implement_one_of]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const TEMPLATE: AttributeTemplate = template!(List: &["function1, function2, ..."]); + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(list) = args.list() else { + cx.expected_list(cx.attr_span, args); + return None; + }; + + let mut fn_names = ThinVec::new(); + + let inputs: Vec<_> = list.mixed().collect(); + + if inputs.len() < 2 { + cx.expected_list_with_num_args_or_more(2, list.span); + return None; + } + + let mut errored = false; + for argument in inputs { + let Some(meta) = argument.meta_item() else { + cx.expected_identifier(argument.span()); + return None; + }; + + let Some(ident) = meta.ident() else { + cx.dcx().emit_err(errors::MustBeNameOfAssociatedFunction { span: meta.span() }); + errored = true; + continue; + }; + + fn_names.push(ident); + } + if errored { + return None; + } + + Some(AttributeKind::RustcMustImplementOneOf { attr_span: cx.attr_span, fn_names }) + } +} + pub(crate) struct RustcNeverReturnsNullPointerParser; impl NoArgsAttributeParser for RustcNeverReturnsNullPointerParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index af0aee0b1e0b..1113da0dd5db 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -63,8 +63,9 @@ use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser, RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser, - RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcNeverReturnsNullPointerParser, - RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, + RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser, + RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, + RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; @@ -215,6 +216,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, @@ -490,8 +492,15 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedList) } - pub(crate) fn expected_list_with_num_args_or_more(&self, args: usize, span: Span) -> ErrorGuaranteed { - self.emit_parse_error(span, AttributeParseErrorReason::ExpectedListWithNumArgsOrMore { args}) + pub(crate) fn expected_list_with_num_args_or_more( + &self, + args: usize, + span: Span, + ) -> ErrorGuaranteed { + self.emit_parse_error( + span, + AttributeParseErrorReason::ExpectedListWithNumArgsOrMore { args }, + ) } pub(crate) fn expected_list_or_no_args(&self, span: Span) -> ErrorGuaranteed { diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 9551744d5ec5..474f848038d1 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -8,7 +8,9 @@ use std::fmt::{Debug, Display}; use rustc_ast::token::{self, Delimiter, MetaVarKind}; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, Path, StmtKind, UnOp}; +use rustc_ast::{ + AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, Path, PathSegment, StmtKind, UnOp, +}; use rustc_ast_pretty::pprust; use rustc_errors::{Diag, PResult}; use rustc_hir::{self as hir, AttrPath}; @@ -256,6 +258,11 @@ impl Debug for MetaItemParser { } impl MetaItemParser { + /// For a single-segment meta item, returns its name; otherwise, returns `None`. + pub fn ident(&self) -> Option { + if let [PathSegment { ident, .. }] = self.path.0.segments[..] { Some(ident) } else { None } + } + pub fn span(&self) -> Span { if let Some(other) = self.args.span() { self.path.borrow().span().with_hi(other.hi()) diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index e9f9b2445deb..2c6c0d59b978 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -949,6 +949,9 @@ pub enum AttributeKind { /// Represents `#[rustc_main]`. RustcMain, + /// Represents `#[rustc_must_implement_one_of]` + RustcMustImplementOneOf { attr_span: Span, fn_names: ThinVec }, + /// Represents `#[rustc_never_returns_null_ptr]` RustcNeverReturnsNullPointer, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 68456dfe4c29..7ab23c6207d6 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -100,6 +100,7 @@ impl AttributeKind { RustcLintQueryInstability => Yes, RustcLintUntrackedQueryInformation => Yes, RustcMain => No, + RustcMustImplementOneOf { .. } => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes, RustcObjectLifetimeDefault => No, diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 8022a48ee137..416a6b19edfc 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -208,14 +208,6 @@ hir_analysis_field_already_declared_previous_nested = .previous_decl_label = `{$field_name}` first declared here in this unnamed field .previous_nested_field_decl_note = field `{$field_name}` first declared here -hir_analysis_function_not_found_in_trait = function not found in this trait - -hir_analysis_function_not_have_default_implementation = function doesn't have a default implementation - .note = required by this annotation - -hir_analysis_functions_names_duplicated = functions names are duplicated - .note = all `#[rustc_must_implement_one_of]` arguments must be unique - hir_analysis_generic_args_on_overridden_impl = could not resolve generic parameters on overridden impl hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default` @@ -381,16 +373,6 @@ hir_analysis_missing_type_params = *[other] parameters } must be specified on the object type -hir_analysis_must_be_name_of_associated_function = must be a name of an associated function - -hir_analysis_must_implement_not_function = not a function - -hir_analysis_must_implement_not_function_note = all `#[rustc_must_implement_one_of]` arguments must be associated function names - -hir_analysis_must_implement_not_function_span_note = required by this annotation - -hir_analysis_must_implement_one_of_attribute = the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args - hir_analysis_no_variant_named = no variant named `{$ident}` found for enum `{$ty}` hir_analysis_not_supported_delegation = {$descr} diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index a81df02f023f..ad66003a6bf9 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1340,9 +1340,7 @@ fn check_impl_items_against_trait<'tcx>( } if let Some(missing_items) = must_implement_one_of { - let attr_span = tcx - .get_attr(trait_ref.def_id, sym::rustc_must_implement_one_of) - .map(|attr| attr.span()); + let attr_span = find_attr!(tcx.get_all_attrs(trait_ref.def_id), AttributeKind::RustcMustImplementOneOf {attr_span, ..} => *attr_span); missing_items_must_implement_one_of_err( tcx, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 2e06684e0c7a..9343bcd27a33 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -22,7 +22,6 @@ use std::ops::Bound; use rustc_abi::{ExternAbi, Size}; use rustc_ast::Recovered; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; -use rustc_data_structures::unord::UnordMap; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey, struct_span_code_err, }; @@ -916,84 +915,15 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { } else { ty::trait_def::TraitSpecializationKind::None }; - let must_implement_one_of = attrs - .iter() - .find(|attr| attr.has_name(sym::rustc_must_implement_one_of)) - // Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]` - // and that they are all identifiers - .and_then(|attr| match attr.meta_item_list() { - Some(items) if items.len() < 2 => { - tcx.dcx().emit_err(errors::MustImplementOneOfAttribute { span: attr.span() }); - None - } - Some(items) => items - .into_iter() - .map(|item| item.ident().ok_or(item.span())) - .collect::, _>>() - .map_err(|span| { - tcx.dcx().emit_err(errors::MustBeNameOfAssociatedFunction { span }); - }) - .ok() - .zip(Some(attr.span())), - // Error is reported by `rustc_attr!` - None => None, - }) - // Check that all arguments of `#[rustc_must_implement_one_of]` reference - // functions in the trait with default implementations - .and_then(|(list, attr_span)| { - let errors = list.iter().filter_map(|ident| { - let item = tcx - .associated_items(def_id) - .filter_by_name_unhygienic(ident.name) - .find(|item| item.ident(tcx) == *ident); - - match item { - Some(item) if matches!(item.kind, ty::AssocKind::Fn { .. }) => { - if !item.defaultness(tcx).has_value() { - tcx.dcx().emit_err(errors::FunctionNotHaveDefaultImplementation { - span: tcx.def_span(item.def_id), - note_span: attr_span, - }); - - return Some(()); - } - - return None; - } - Some(item) => { - tcx.dcx().emit_err(errors::MustImplementNotFunction { - span: tcx.def_span(item.def_id), - span_note: errors::MustImplementNotFunctionSpanNote { span: attr_span }, - note: errors::MustImplementNotFunctionNote {}, - }); - } - None => { - tcx.dcx().emit_err(errors::FunctionNotFoundInTrait { span: ident.span }); - } - } - - Some(()) - }); - - (errors.count() == 0).then_some(list) - }) - // Check for duplicates - .and_then(|list| { - let mut set: UnordMap = Default::default(); - let mut no_dups = true; - - for ident in &*list { - if let Some(dup) = set.insert(ident.name, ident.span) { - tcx.dcx() - .emit_err(errors::FunctionNamesDuplicated { spans: vec![dup, ident.span] }); - - no_dups = false; - } - } - - no_dups.then_some(list) - }); + let must_implement_one_of = find_attr!( + attrs, + AttributeKind::RustcMustImplementOneOf { fn_names, .. } => + fn_names + .iter() + .cloned() + .collect::>() + ); let deny_explicit_impl = find_attr!(attrs, AttributeKind::DenyExplicitImpl(_)); let implement_via_object = !find_attr!(attrs, AttributeKind::DoNotImplementViaObject(_)); diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 8e17a4962520..b388396ac4fc 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -741,66 +741,6 @@ pub(crate) struct ParenSugarAttribute { pub span: Span, } -#[derive(Diagnostic)] -#[diag(hir_analysis_must_implement_one_of_attribute)] -pub(crate) struct MustImplementOneOfAttribute { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(hir_analysis_must_be_name_of_associated_function)] -pub(crate) struct MustBeNameOfAssociatedFunction { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(hir_analysis_function_not_have_default_implementation)] -pub(crate) struct FunctionNotHaveDefaultImplementation { - #[primary_span] - pub span: Span, - #[note] - pub note_span: Span, -} - -#[derive(Diagnostic)] -#[diag(hir_analysis_must_implement_not_function)] -pub(crate) struct MustImplementNotFunction { - #[primary_span] - pub span: Span, - #[subdiagnostic] - pub span_note: MustImplementNotFunctionSpanNote, - #[subdiagnostic] - pub note: MustImplementNotFunctionNote, -} - -#[derive(Subdiagnostic)] -#[note(hir_analysis_must_implement_not_function_span_note)] -pub(crate) struct MustImplementNotFunctionSpanNote { - #[primary_span] - pub span: Span, -} - -#[derive(Subdiagnostic)] -#[note(hir_analysis_must_implement_not_function_note)] -pub(crate) struct MustImplementNotFunctionNote {} - -#[derive(Diagnostic)] -#[diag(hir_analysis_function_not_found_in_trait)] -pub(crate) struct FunctionNotFoundInTrait { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(hir_analysis_functions_names_duplicated)] -#[note] -pub(crate) struct FunctionNamesDuplicated { - #[primary_span] - pub spans: Vec, -} - #[derive(Diagnostic)] #[diag(hir_analysis_simd_ffi_highly_experimental)] #[help] diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index cf069b364be8..94996c0adb47 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -236,6 +236,14 @@ passes_feature_previously_declared = passes_feature_stable_twice = feature `{$feature}` is declared stable since {$since}, but was previously declared stable since {$prev_since} +passes_function_not_found_in_trait = function not found in this trait + +passes_function_not_have_default_implementation = function doesn't have a default implementation + .note = required by this annotation + +passes_functions_names_duplicated = functions names are duplicated + .note = all `#[rustc_must_implement_one_of]` arguments must be unique + passes_has_incoherent_inherent_impl = `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits .label = only adts, extern types and traits are supported @@ -370,6 +378,12 @@ passes_multiple_rustc_main = .first = first `#[rustc_main]` function .additional = additional `#[rustc_main]` function +passes_must_implement_not_function = not a function + +passes_must_implement_not_function_note = all `#[rustc_must_implement_one_of]` arguments must be associated function names + +passes_must_implement_not_function_span_note = required by this annotation + passes_must_not_suspend = `must_not_suspend` attribute should be applied to a struct, enum, union, or trait .label = is not a struct, enum, union, or trait @@ -484,10 +498,6 @@ passes_sanitize_attribute_not_allowed = .no_body = function has no body .help = sanitize attribute can be applied to a function (with body), impl block, or module -passes_should_be_applied_to_trait = - attribute should be applied to a trait - .label = not a trait - passes_trait_impl_const_stability_mismatch = const stability on the impl does not match the const stability on the trait passes_trait_impl_const_stability_mismatch_impl_stable = this impl is (implicitly) stable... passes_trait_impl_const_stability_mismatch_impl_unstable = this impl is unstable... diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7822614a05cb..f422a7939636 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -14,6 +14,7 @@ use rustc_ast::{AttrStyle, MetaItemKind, ast}; use rustc_attr_parsing::{AttributeParser, Late}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::thin_vec::ThinVec; +use rustc_data_structures::unord::UnordMap; use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; use rustc_feature::{ ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, @@ -47,7 +48,7 @@ use rustc_session::lint::builtin::{ }; use rustc_session::parse::feature_err; use rustc_span::edition::Edition; -use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, sym}; +use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; use rustc_trait_selection::traits::ObligationCtxt; @@ -219,6 +220,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::EiiImpls(impls)) => { self.check_eii_impl(impls, target) }, + Attribute::Parsed(AttributeKind::RustcMustImplementOneOf { attr_span, fn_names }) => { + self.check_rustc_must_implement_one_of(*attr_span, fn_names, hir_id,target) + }, Attribute::Parsed( AttributeKind::EiiExternTarget { .. } | AttributeKind::EiiExternItem @@ -315,7 +319,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), - [sym::rustc_must_implement_one_of, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), [sym::rustc_has_incoherent_inherent_impls, ..] => { @@ -445,6 +448,63 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_mix_no_mangle_export(hir_id, attrs); } + fn check_rustc_must_implement_one_of( + &self, + attr_span: Span, + list: &ThinVec, + hir_id: HirId, + target: Target, + ) { + // Ignoring invalid targets because TyCtxt::associated_items emits bug if the target isn't valid + // the parser has already produced an error for the target being invalid + if !matches!(target, Target::Trait) { + return; + } + + let def_id = hir_id.owner.def_id; + + let items = self.tcx.associated_items(def_id); + // Check that all arguments of `#[rustc_must_implement_one_of]` reference + // functions in the trait with default implementations + for ident in list { + let item = items + .filter_by_name_unhygienic(ident.name) + .find(|item| item.ident(self.tcx) == *ident); + + match item { + Some(item) if matches!(item.kind, ty::AssocKind::Fn { .. }) => { + if !item.defaultness(self.tcx).has_value() { + self.tcx.dcx().emit_err(errors::FunctionNotHaveDefaultImplementation { + span: self.tcx.def_span(item.def_id), + note_span: attr_span, + }); + } + } + Some(item) => { + self.dcx().emit_err(errors::MustImplementNotFunction { + span: self.tcx.def_span(item.def_id), + span_note: errors::MustImplementNotFunctionSpanNote { span: attr_span }, + note: errors::MustImplementNotFunctionNote {}, + }); + } + None => { + self.dcx().emit_err(errors::FunctionNotFoundInTrait { span: ident.span }); + } + } + } + // Check for duplicates + + let mut set: UnordMap = Default::default(); + + for ident in &*list { + if let Some(dup) = set.insert(ident.name, ident.span) { + self.tcx + .dcx() + .emit_err(errors::FunctionNamesDuplicated { spans: vec![dup, ident.span] }); + } + } + } + fn check_eii_impl(&self, impls: &[EiiImpl], target: Target) { for EiiImpl { span, inner_span, eii_macro, impl_marked_unsafe, is_default: _ } in impls { match target { @@ -1221,16 +1281,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks if the attribute is applied to a trait. - fn check_must_be_applied_to_trait(&self, attr_span: Span, defn_span: Span, target: Target) { - match target { - Target::Trait => {} - _ => { - self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait { attr_span, defn_span }); - } - } - } - /// Checks if the `#[repr]` attributes on `item` are valid. fn check_repr( &self, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 2b817c6dd106..af5cb29b83d0 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -89,15 +89,6 @@ pub(crate) struct NonExhaustiveWithDefaultFieldValues { pub defn_span: Span, } -#[derive(Diagnostic)] -#[diag(passes_should_be_applied_to_trait)] -pub(crate) struct AttrShouldBeAppliedToTrait { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, -} - #[derive(Diagnostic)] #[diag(passes_doc_alias_bad_location)] pub(crate) struct DocAliasBadLocation<'a> { @@ -1323,3 +1314,49 @@ pub(crate) struct DuplicateEiiImpls { #[help] pub help: (), } + +#[derive(Diagnostic)] +#[diag(passes_function_not_have_default_implementation)] +pub(crate) struct FunctionNotHaveDefaultImplementation { + #[primary_span] + pub span: Span, + #[note] + pub note_span: Span, +} + +#[derive(Diagnostic)] +#[diag(passes_must_implement_not_function)] +pub(crate) struct MustImplementNotFunction { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub span_note: MustImplementNotFunctionSpanNote, + #[subdiagnostic] + pub note: MustImplementNotFunctionNote, +} + +#[derive(Subdiagnostic)] +#[note(passes_must_implement_not_function_span_note)] +pub(crate) struct MustImplementNotFunctionSpanNote { + #[primary_span] + pub span: Span, +} + +#[derive(Subdiagnostic)] +#[note(passes_must_implement_not_function_note)] +pub(crate) struct MustImplementNotFunctionNote {} + +#[derive(Diagnostic)] +#[diag(passes_function_not_found_in_trait)] +pub(crate) struct FunctionNotFoundInTrait { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(passes_functions_names_duplicated)] +#[note] +pub(crate) struct FunctionNamesDuplicated { + #[primary_span] + pub spans: Vec, +} diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index 2fdce628f0c9..eff55e8e02a2 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -81,6 +81,8 @@ session_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number liter session_linker_plugin_lto_windows_not_supported = linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets +session_must_be_name_of_associated_function = must be a name of an associated function + session_not_circumvent_feature = `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine session_not_supported = not supported diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 1f2d386a23cb..6fd86aec7ad9 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -82,6 +82,13 @@ pub(crate) struct CliFeatureDiagnosticHelp { pub(crate) feature: Symbol, } +#[derive(Diagnostic)] +#[diag(session_must_be_name_of_associated_function)] +pub struct MustBeNameOfAssociatedFunction { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(session_not_circumvent_feature)] pub(crate) struct NotCircumventFeature; diff --git a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs index 9b2e489c5425..82d0fa36d7ec 100644 --- a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs +++ b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs @@ -12,7 +12,7 @@ trait Tr1 { } #[rustc_must_implement_one_of(a)] -//~^ ERROR the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args +//~^ ERROR malformed trait Tr2 { fn a() {} } @@ -36,11 +36,11 @@ trait Tr5 { } #[rustc_must_implement_one_of(abc, xyz)] -//~^ ERROR attribute should be applied to a trait +//~^ ERROR `#[rustc_must_implement_one_of]` attribute cannot be used on functions fn function() {} #[rustc_must_implement_one_of(abc, xyz)] -//~^ ERROR attribute should be applied to a trait +//~^ ERROR `#[rustc_must_implement_one_of]` attribute cannot be used on structs struct Struct {} fn main() {} diff --git a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr index cf197d035b38..0d854b4594fa 100644 --- a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr +++ b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr @@ -1,26 +1,36 @@ -error: malformed `rustc_must_implement_one_of` attribute input +error[E0539]: malformed `rustc_must_implement_one_of` attribute input + --> $DIR/rustc_must_implement_one_of_misuse.rs:14:1 + | +LL | #[rustc_must_implement_one_of(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | expected 2 or more items + | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` + +error[E0539]: malformed `rustc_must_implement_one_of` attribute input --> $DIR/rustc_must_implement_one_of_misuse.rs:20:1 | LL | #[rustc_must_implement_one_of] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` -error: attribute should be applied to a trait +error: `#[rustc_must_implement_one_of]` attribute cannot be used on functions --> $DIR/rustc_must_implement_one_of_misuse.rs:38:1 | LL | #[rustc_must_implement_one_of(abc, xyz)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | fn function() {} - | ---------------- not a trait + | + = help: `#[rustc_must_implement_one_of]` can only be applied to traits -error: attribute should be applied to a trait +error: `#[rustc_must_implement_one_of]` attribute cannot be used on structs --> $DIR/rustc_must_implement_one_of_misuse.rs:42:1 | LL | #[rustc_must_implement_one_of(abc, xyz)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | struct Struct {} - | ---------------- not a trait + | + = help: `#[rustc_must_implement_one_of]` can only be applied to traits error: function not found in this trait --> $DIR/rustc_must_implement_one_of_misuse.rs:3:31 @@ -40,12 +50,6 @@ error: function not found in this trait LL | #[rustc_must_implement_one_of(a, b)] | ^ -error: the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args - --> $DIR/rustc_must_implement_one_of_misuse.rs:14:1 - | -LL | #[rustc_must_implement_one_of(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: not a function --> $DIR/rustc_must_implement_one_of_misuse.rs:26:5 | @@ -98,3 +102,4 @@ LL | #[rustc_must_implement_one_of(a, b)] error: aborting due to 11 previous errors +For more information about this error, try `rustc --explain E0539`. From 99836fc6d47fbf296c2dc0383dd20455082ba657 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Dec 2025 17:53:20 +0100 Subject: [PATCH 1269/3801] Add GUI regression test for disabled line numbers --- .../docblock-code-block-line-number.goml | 80 ++++++++----------- tests/rustdoc-gui/sidebar-mobile.goml | 2 +- tests/rustdoc-gui/utils.goml | 30 +++++++ 3 files changed, 65 insertions(+), 47 deletions(-) diff --git a/tests/rustdoc-gui/docblock-code-block-line-number.goml b/tests/rustdoc-gui/docblock-code-block-line-number.goml index a182124aced2..92ec0eb43a31 100644 --- a/tests/rustdoc-gui/docblock-code-block-line-number.goml +++ b/tests/rustdoc-gui/docblock-code-block-line-number.goml @@ -1,9 +1,14 @@ // Checks that the setting "line numbers" is working as expected. include: "utils.goml" + go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" +// Otherwise, we can't check text color +show-text: true + +store-value: (line_numbers_selector, ".example-wrap pre.rust code [data-nosnippet]") // We check that without this setting, there is no line number displayed. -assert-false: "pre.example-line-numbers" +assert-count: (|line_numbers_selector|, 0) // All corners should be rounded. assert-css: ( @@ -17,14 +22,16 @@ assert-css: ( ALL, ) -// We set the setting to show the line numbers on code examples. -set-local-storage: {"rustdoc-line-numbers": "true"} -reload: -// We wait for the line numbers to be added into the DOM by the JS... -wait-for: ".digits-1 pre" +// Before we add line numbers, we get the X position of a span in a code example that we will +// use later on to ensure that when we disable the line numbers, it goes back to its original +// position. +store-position: (".example-wrap code .macro", {"x": span_x_pos}) -// Otherwise, we can't check text color -show-text: true +// We enable the setting to show the line numbers on code examples. +call-function: ("switch-line-numbers-setting", {"expected_status": "true"}) +// We ensure that there are actually line numbers generated in the DOM. +assert-text: (".example-wrap pre.rust code span[data-nosnippet]", "1") +assert-position-false: (".example-wrap code .macro", {"x": |span_x_pos|}) // Let's now check some CSS properties... define-function: ( @@ -68,20 +75,18 @@ call-function: ("check-colors", { // Now, try changing the setting dynamically. We'll turn it off, using the settings menu, // and make sure it goes away. -// First, open the settings menu. -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" -assert-css: ("#settings", {"display": "block"}) +call-function: ("switch-line-numbers-setting", {"expected_status": "false"}) +assert: ".digits-1.hide-lines" -// Then, click the toggle button. -click: "input#line-numbers" -wait-for: ".digits-1.hide-lines" -assert-local-storage: {"rustdoc-line-numbers": "false" } +// The line numbers not being displayed, their "space" should have disappear as well. +assert-position: (".example-wrap code .macro", {"x": |span_x_pos|}) // Finally, turn it on again. -click: "input#line-numbers" +call-function: ("switch-line-numbers-setting", {"expected_status": "true"}) wait-for: ".digits-1:not(.hide-lines)" -assert-local-storage: {"rustdoc-line-numbers": "true" } + +// The line numbers are being displayed, their "space" should be back. +assert-position-false: (".example-wrap code .macro", {"x": |span_x_pos|}) // Same check with scraped examples line numbers. go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html" @@ -119,26 +124,14 @@ call-function: ("check-padding", { }) define-function: ("check-line-numbers-existence", [], block { - assert-local-storage: {"rustdoc-line-numbers": "true" } - assert-false: ".example-line-numbers" - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" - - // Then, click the toggle button. - click: "input#line-numbers" - wait-for-local-storage-false: {"rustdoc-line-numbers": "true" } - assert-false: ".example-line-numbers" + assert-local-storage: {"rustdoc-line-numbers": "true"} + assert-count-false: (|line_numbers_selector|, 0) + call-function: ("switch-line-numbers-setting", {"expected_status": "false"}) // Line numbers should still be there. - assert-css: ("[data-nosnippet]", { "display": "block"}) - // Now disabling the setting. - click: "input#line-numbers" - wait-for-local-storage: {"rustdoc-line-numbers": "true" } - assert-false: ".example-line-numbers" - // Line numbers should still be there. - assert-css: ("[data-nosnippet]", { "display": "block"}) - // Closing settings menu. - click: "rustdoc-toolbar .settings-menu" - wait-for-css: ("#settings", {"display": "none"}) + assert-count-false: (|line_numbers_selector|, 0) + assert-css: (|line_numbers_selector|, {"display": "block"}) + // Now re-enabling the setting. + call-function: ("switch-line-numbers-setting", {"expected_status": "true"}) }) // Checking that turning off the line numbers setting won't remove line numbers from scraped @@ -168,16 +161,11 @@ assert: ".example-wrap > pre.rust" assert-count: (".example-wrap", 2) assert-count: (".example-wrap.digits-1", 2) -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" - -// Then, click the toggle button. -click: "input#line-numbers" +// Disabling the line numbers setting. +call-function: ("switch-line-numbers-setting", {"expected_status": "false"}) wait-for-count: (".example-wrap.digits-1.hide-lines", 2) -assert-local-storage-false: {"rustdoc-line-numbers": "true" } -// Now turning off the setting. -click: "input#line-numbers" +// Now re-enabling the setting. +call-function: ("switch-line-numbers-setting", {"expected_status": "true"}) wait-for-count: (".example-wrap.digits-1", 2) wait-for-count: (".example-wrap.digits-1.hide-lines", 0) -assert-local-storage: {"rustdoc-line-numbers": "true" } diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index b3ca6e023637..f828516d7624 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -65,7 +65,7 @@ define-function: ( "check-colors", [theme, color, background], block { - call-function: ("switch-theme", {"theme": |theme|}) + call-function: ("switch-theme-mobile", {"theme": |theme|}) reload: // Open the sidebar menu. diff --git a/tests/rustdoc-gui/utils.goml b/tests/rustdoc-gui/utils.goml index 6addda4f33ff..a40f9fc6fdd7 100644 --- a/tests/rustdoc-gui/utils.goml +++ b/tests/rustdoc-gui/utils.goml @@ -34,6 +34,24 @@ define-function: ( }, ) +// FIXME: To be removed once `browser-ui-test` has conditions. +define-function: ( + "switch-theme-mobile", + [theme], + block { + // Open the settings menu. + click: "rustdoc-topbar .settings-menu" + // Wait for the popover to appear... + wait-for-css: ("#settings", {"display": "block"}) + // Change the setting. + click: "#theme-"+ |theme| + click: "rustdoc-topbar .settings-menu" + wait-for-css-false: ("#settings", {"display": "block"}) + // Ensure that the local storage was correctly updated. + assert-local-storage: {"rustdoc-theme": |theme|} + }, +) + define-function: ( "perform-search", [query], @@ -55,3 +73,15 @@ define-function: ( wait-for-false: "#search-tabs .count.loading" } ) + +define-function: ( + "switch-line-numbers-setting", + [expected_status], + block { + call-function: ("open-settings-menu", {}) + // We change the line numbers setting. + click: "#line-numbers" + call-function: ("close-settings-menu", {}) + assert-local-storage: {"rustdoc-line-numbers": |expected_status|} + } +) From 7f550f6f37aece6fbf5a8c31beb13d38996f56d7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Dec 2025 16:23:40 +0100 Subject: [PATCH 1270/3801] Fix "copy code" button --- src/librustdoc/html/static/js/main.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 476ecd42d6f9..72bf816e64bd 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -2163,7 +2163,15 @@ function preLoadCss(cssUrl) { // Should never happen, but the world is a dark and dangerous place. return; } - copyContentToClipboard(codeElem.textContent); + let content = ""; + for (const node of codeElem.childNodes) { + // We exclude line numbers. + if (node instanceof HTMLElement && node.hasAttribute("data-nosnippet")) { + continue; + } + content += node.textContent; + } + copyContentToClipboard(content); } /** From c054e52bc9e092dab9a627fea0ad46d08931e881 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Dec 2025 16:57:35 +0100 Subject: [PATCH 1271/3801] Add GUI test for copying code when line numbers are displayed in code examples --- tests/rustdoc-gui/copy-code.goml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/rustdoc-gui/copy-code.goml b/tests/rustdoc-gui/copy-code.goml index a6fb816c4bd6..14421ab746f5 100644 --- a/tests/rustdoc-gui/copy-code.goml +++ b/tests/rustdoc-gui/copy-code.goml @@ -42,7 +42,31 @@ store-size: (".example-wrap:nth-of-type(1) .copy-button", { }) assert: |copy_height| > 0 && |copy_width| > 0 -// Checking same things for the copy button when there is no run button. + +// We now check that copying code when line numbers are displayed don't include these line numbers. + +// First we ensure that the clipboard is empty. +assert-clipboard: "" +// We make the line numbers appear. +click: "rustdoc-toolbar .settings-menu" +wait-for-css: ("#settings", {"display": "block"}) +// We make the line numbers appear. +click: "#line-numbers" +wait-for-local-storage: {"rustdoc-line-numbers": "true" } +// We close the settings menu. +click: "rustdoc-toolbar .settings-menu" +wait-for-css-false: ("#settings", {"display": "block"}) +// We ensure that there are actually line numbers generated in the DOM. +assert-text: (".example-wrap pre.rust code span[data-nosnippet]", "1") +// We make the copy button appear. +move-cursor-to: ".example-wrap pre.rust code" +wait-for-css: (".example-wrap .button-holder", {"visibility": "visible"}) +// We click on the copy button. +click: ".example-wrap .button-holder .copy-button" +assert-clipboard: 'println!("nothing fancy"); +println!("but with two lines!");' + +// Back to UI checks, checking same things for the copy button when there is no run button. go-to: "file://" + |DOC_PATH| + "/lib2/sub_mod/struct.Foo.html" call-function: ("check-copy-button", {}) // Ensure there is no run button. From 5642a2d322937b2ea85856f0c4e0949d63f41d8c Mon Sep 17 00:00:00 2001 From: Shunpoco Date: Fri, 26 Dec 2025 14:28:05 +0000 Subject: [PATCH 1272/3801] implement py and cpp --- src/tools/tidy/src/extra_checks/mod.rs | 43 ++++++++++++++++---------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index 5c83a12e1e5c..d5b360cbe549 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -122,7 +122,7 @@ fn check_impl( }); } if lint_args.iter().any(|ck| ck.if_installed) { - lint_args.retain(|ck| ck.is_non_if_installed_or_matches(outdir)); + lint_args.retain(|ck| ck.is_non_if_installed_or_matches(root_path, outdir)); } macro_rules! extra_check { @@ -322,7 +322,7 @@ fn check_impl( } let res = spellcheck_runner(root_path, &outdir, &cargo, &args); if res.is_err() { - rerun_with_bless("spellcheck", "fix typechecktypos"); + rerun_with_bless("spellcheck", "fix typos"); } res?; } @@ -425,21 +425,11 @@ fn py_runner( /// Create a virtuaenv at a given path if it doesn't already exist, or validate /// the install if it does. Returns the path to that venv's python executable. fn get_or_create_venv(venv_path: &Path, src_reqs_path: &Path) -> Result { - let mut should_create = true; - let dst_reqs_path = venv_path.join("requirements.txt"); let mut py_path = venv_path.to_owned(); py_path.extend(REL_PY_PATH); - if let Ok(req) = fs::read_to_string(&dst_reqs_path) { - if req == fs::read_to_string(src_reqs_path)? { - // found existing environment - should_create = false; - } else { - eprintln!("requirements.txt file mismatch, recreating environment"); - } - } - - if should_create { + if !has_py_tools(venv_path, src_reqs_path)? { + let dst_reqs_path = venv_path.join("requirements.txt"); eprintln!("removing old virtual environment"); if venv_path.is_dir() { fs::remove_dir_all(venv_path).unwrap_or_else(|_| { @@ -454,6 +444,18 @@ fn get_or_create_venv(venv_path: &Path, src_reqs_path: &Path) -> Result Result { + let dst_reqs_path = venv_path.join("requirements.txt"); + if let Ok(req) = fs::read_to_string(&dst_reqs_path) { + if req == fs::read_to_string(src_reqs_path)? { + return Ok(true); + } + eprintln!("requirements.txt file mismatch"); + } + + Ok(false) +} + /// Attempt to create a virtualenv at this path. Cycles through all expected /// valid python versions to find one that is installed. fn create_venv_at_path(path: &Path) -> Result<(), Error> { @@ -769,7 +771,7 @@ impl ExtraCheckArg { self.lang == lang && self.kind.map(|k| k == kind).unwrap_or(true) } - fn is_non_if_installed_or_matches(&self, build_dir: &Path) -> bool { + fn is_non_if_installed_or_matches(&self, root_path: &Path, build_dir: &Path) -> bool { if !self.if_installed { return true; } @@ -800,7 +802,16 @@ impl ExtraCheckArg { Some(_) => false, } } - _ => todo!("implement other checks"), + ExtraCheckLang::Py | ExtraCheckLang::Cpp => { + let venv_path = build_dir.join("venv"); + let mut reqs_path = root_path.to_owned(); + reqs_path.extend(PIP_REQ_PATH); + let Ok(v) = has_py_tools(&venv_path, &reqs_path) else { + return false; + }; + + v + } } } From 9f566f2463ed1b7ec7160d0ab9fda0fba61c8fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 26 Dec 2025 20:08:23 +0000 Subject: [PATCH 1273/3801] Don't use `matches!` when `==` suffices In the codebase we sometimes use `matches!` for values that can actually just be compared. Replace them with `==`. --- compiler/rustc_const_eval/src/check_consts/check.rs | 2 +- compiler/rustc_const_eval/src/check_consts/qualifs.rs | 2 +- compiler/rustc_const_eval/src/interpret/call.rs | 2 +- compiler/rustc_const_eval/src/interpret/intrinsics.rs | 2 +- compiler/rustc_const_eval/src/interpret/memory.rs | 8 ++++---- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- compiler/rustc_middle/src/mir/statement.rs | 2 +- .../src/ty/inhabitedness/inhabited_predicate.rs | 4 ++-- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 4 ++-- compiler/rustc_parse/src/parser/asm.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 2 +- compiler/rustc_parse/src/parser/mod.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 4 +--- compiler/rustc_passes/src/check_attr.rs | 8 +++----- compiler/rustc_passes/src/dead.rs | 4 ++-- compiler/rustc_target/src/target_features.rs | 2 +- .../src/error_reporting/infer/mod.rs | 2 +- compiler/rustc_trait_selection/src/traits/effects.rs | 2 +- compiler/rustc_trait_selection/src/traits/select/mod.rs | 4 ++-- 23 files changed, 32 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index ed2c0bd6f98e..b06b407a6085 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -251,7 +251,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { let mut transient = DenseBitSet::new_filled(ccx.body.local_decls.len()); // Make sure to only visit reachable blocks, the dataflow engine can ICE otherwise. for (bb, data) in traversal::reachable(&ccx.body) { - if matches!(data.terminator().kind, TerminatorKind::Return) { + if data.terminator().kind == TerminatorKind::Return { let location = ccx.body.terminator_loc(bb); maybe_storage_live.seek_after_primary_effect(location); // If a local may be live here, it is definitely not transient. diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 42943648ffdd..113e0d66c48a 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -312,7 +312,7 @@ where // i.e., we treat all qualifs as non-structural for deref projections. Generally, // we can say very little about `*ptr` even if we know that `ptr` satisfies all // sorts of properties. - if matches!(elem, ProjectionElem::Deref) { + if elem == ProjectionElem::Deref { // We have to assume that this qualifies. return true; } diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 312ebe7ddd09..94c6fd1b3238 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -283,7 +283,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { 'tcx: 'y, { assert_eq!(callee_ty, callee_abi.layout.ty); - if matches!(callee_abi.mode, PassMode::Ignore) { + if callee_abi.mode == PassMode::Ignore { // This one is skipped. Still must be made live though! if !already_live { self.storage_live(callee_arg.as_local().unwrap())?; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 44c817b33184..d70d157d8808 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -861,7 +861,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } else { // unsigned - if matches!(mir_op, BinOp::Add) { + if mir_op == BinOp::Add { // max unsigned Scalar::from_uint(size.unsigned_int_max(), size) } else { diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index bac3a9da48d9..862fe4779080 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -327,7 +327,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return Err(ConstEvalErrKind::ConstMakeGlobalWithOffset(ptr)).into(); } - if matches!(self.tcx.try_get_global_alloc(alloc_id), Some(_)) { + if self.tcx.try_get_global_alloc(alloc_id).is_some() { // This points to something outside the current interpreter. return Err(ConstEvalErrKind::ConstMakeGlobalPtrIsNonHeap(ptr)).into(); } @@ -981,7 +981,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { msg: CheckInAllocMsg, ) -> InterpResult<'tcx, (Size, Align)> { let info = self.get_alloc_info(id); - if matches!(info.kind, AllocKind::Dead) { + if info.kind == AllocKind::Dead { throw_ub!(PointerUseAfterFree(id, msg)) } interp_ok((info.size, info.align)) @@ -1072,7 +1072,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Recurse, if there is data here. // Do this *before* invoking the callback, as the callback might mutate the // allocation and e.g. replace all provenance by wildcards! - if matches!(info.kind, AllocKind::LiveData) { + if info.kind == AllocKind::LiveData { let alloc = self.get_alloc_raw(id)?; for prov in alloc.provenance().provenances() { if let Some(id) = prov.get_alloc_id() { @@ -1605,7 +1605,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { match self.ptr_try_get_alloc_id(ptr, 0) { Ok((alloc_id, offset, _)) => { let info = self.get_alloc_info(alloc_id); - if matches!(info.kind, AllocKind::TypeId) { + if info.kind == AllocKind::TypeId { // We *could* actually precisely answer this question since here, // the offset *is* the integer value. But the entire point of making // this a pointer is not to leak the integer value, so we say everything diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 16f5222f621c..725294dfd377 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -327,7 +327,7 @@ pub(crate) fn check_trait_item<'tcx>( let mut res = Ok(()); - if matches!(tcx.def_kind(def_id), DefKind::AssocFn) { + if tcx.def_kind(def_id) == DefKind::AssocFn { for &assoc_ty_def_id in tcx.associated_types_for_impl_traits_in_associated_fn(def_id.to_def_id()) { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 2eefe1eb3e92..178c47b09c84 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -543,7 +543,7 @@ pub(super) fn explicit_predicates_of<'tcx>( } } } else { - if matches!(def_kind, DefKind::AnonConst) + if def_kind == DefKind::AnonConst && tcx.features().generic_const_exprs() && let Some(defaulted_param_def_id) = tcx.hir_opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id)) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index da719e615fd7..ff85f53ddf30 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -216,7 +216,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Don't write user type annotations for const param types, since we give them // identity args just so that we can trivially substitute their `EarlyBinder`. // We enforce that they match their type in MIR later on. - if matches!(self.tcx.def_kind(def_id), DefKind::ConstParam) { + if self.tcx.def_kind(def_id) == DefKind::ConstParam { return; } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 1ba1ae3e1531..c1f8c46baddb 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -25,7 +25,7 @@ impl<'tcx> Statement<'tcx> { /// Changes a statement to a nop. This is both faster than deleting instructions and avoids /// invalidating statement indices in `Location`s. pub fn make_nop(&mut self, drop_debuginfo: bool) { - if matches!(self.kind, StatementKind::Nop) { + if self.kind == StatementKind::Nop { return; } let replaced_stmt = std::mem::replace(&mut self.kind, StatementKind::Nop); diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 953ad62be0a8..d03e593e37b9 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -160,7 +160,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { pub fn all(tcx: TyCtxt<'tcx>, iter: impl IntoIterator) -> Self { let mut result = Self::True; for pred in iter { - if matches!(pred, Self::False) { + if pred == Self::False { return Self::False; } result = result.and(tcx, pred); @@ -171,7 +171,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { pub fn any(tcx: TyCtxt<'tcx>, iter: impl IntoIterator) -> Self { let mut result = Self::False; for pred in iter { - if matches!(pred, Self::True) { + if pred == Self::True { return Self::True; } result = result.or(tcx, pred); diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c4f2917ad9e5..f0d5ce492a39 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3381,7 +3381,7 @@ define_print_and_forward_display! { fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) { // Iterate all (non-anonymous) local crate items no matter where they are defined. for id in tcx.hir_free_items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Use) { + if tcx.def_kind(id.owner_id) == DefKind::Use { continue; } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index cd699436e012..4b2f8e03afc1 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1582,7 +1582,7 @@ impl<'v> RootCollector<'_, 'v> { } fn process_impl_item(&mut self, id: hir::ImplItemId) { - if matches!(self.tcx.def_kind(id.owner_id), DefKind::AssocFn) { + if self.tcx.def_kind(id.owner_id) == DefKind::AssocFn { self.push_if_root(id.owner_id.def_id); } } @@ -1720,7 +1720,7 @@ fn create_mono_items_for_default_impls<'tcx>( ) { let impl_ = tcx.impl_trait_header(item.owner_id); - if matches!(impl_.polarity, ty::ImplPolarity::Negative) { + if impl_.polarity == ty::ImplPolarity::Negative { return; } diff --git a/compiler/rustc_parse/src/parser/asm.rs b/compiler/rustc_parse/src/parser/asm.rs index caec877232a6..3fab234adaad 100644 --- a/compiler/rustc_parse/src/parser/asm.rs +++ b/compiler/rustc_parse/src/parser/asm.rs @@ -77,7 +77,7 @@ fn eat_operand_keyword<'a>( exp: ExpKeywordPair, asm_macro: AsmMacro, ) -> PResult<'a, bool> { - if matches!(asm_macro, AsmMacro::Asm) { + if asm_macro == AsmMacro::Asm { Ok(p.eat_keyword(exp)) } else { let span = p.token.span; diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 3f0853a3c54d..efa1027deffd 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3100,7 +3100,7 @@ impl<'a> Parser<'a> { pub(crate) fn eat_label(&mut self) -> Option

    { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", pprust::path_to_string(&self.0)) + write!(f, "{}", pprust::path_to_string(self.0.borrow())) } } #[derive(Clone, Debug)] #[must_use] -pub enum ArgParser<'a> { +pub enum ArgParser { NoArgs, - List(MetaItemListParser<'a>), + List(MetaItemListParser), NameValue(NameValueParser), } -impl<'a> ArgParser<'a> { +impl ArgParser { pub fn span(&self) -> Option { match self { Self::NoArgs => None, @@ -100,7 +103,7 @@ impl<'a> ArgParser<'a> { } pub fn from_attr_args<'sess>( - value: &'a AttrArgs, + value: &AttrArgs, parts: &[Symbol], psess: &'sess ParseSess, should_emit: ShouldEmit, @@ -144,7 +147,7 @@ impl<'a> ArgParser<'a> { /// /// - `#[allow(clippy::complexity)]`: `(clippy::complexity)` is a list /// - `#[rustfmt::skip::macros(target_macro_name)]`: `(target_macro_name)` is a list - pub fn list(&self) -> Option<&MetaItemListParser<'a>> { + pub fn list(&self) -> Option<&MetaItemListParser> { match self { Self::List(l) => Some(l), Self::NameValue(_) | Self::NoArgs => None, @@ -184,17 +187,17 @@ impl<'a> ArgParser<'a> { /// /// Choose which one you want using the provided methods. #[derive(Debug, Clone)] -pub enum MetaItemOrLitParser<'a> { - MetaItemParser(MetaItemParser<'a>), +pub enum MetaItemOrLitParser { + MetaItemParser(MetaItemParser), Lit(MetaItemLit), Err(Span, ErrorGuaranteed), } -impl<'sess> MetaItemOrLitParser<'sess> { - pub fn parse_single( +impl MetaItemOrLitParser { + pub fn parse_single<'sess>( parser: &mut Parser<'sess>, should_emit: ShouldEmit, - ) -> PResult<'sess, MetaItemOrLitParser<'static>> { + ) -> PResult<'sess, MetaItemOrLitParser> { let mut this = MetaItemListParserContext { parser, should_emit }; this.parse_meta_item_inner() } @@ -216,7 +219,7 @@ impl<'sess> MetaItemOrLitParser<'sess> { } } - pub fn meta_item(&self) -> Option<&MetaItemParser<'sess>> { + pub fn meta_item(&self) -> Option<&MetaItemParser> { match self { MetaItemOrLitParser::MetaItemParser(parser) => Some(parser), _ => None, @@ -238,12 +241,12 @@ impl<'sess> MetaItemOrLitParser<'sess> { /// /// The syntax of MetaItems can be found at #[derive(Clone)] -pub struct MetaItemParser<'a> { - path: PathParser<'a>, - args: ArgParser<'a>, +pub struct MetaItemParser { + path: OwnedPathParser, + args: ArgParser, } -impl<'a> Debug for MetaItemParser<'a> { +impl Debug for MetaItemParser { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("MetaItemParser") .field("path", &self.path) @@ -252,12 +255,12 @@ impl<'a> Debug for MetaItemParser<'a> { } } -impl<'a> MetaItemParser<'a> { +impl MetaItemParser { pub fn span(&self) -> Span { if let Some(other) = self.args.span() { - self.path.span().with_hi(other.hi()) + self.path.borrow().span().with_hi(other.hi()) } else { - self.path.span() + self.path.borrow().span() } } @@ -266,12 +269,12 @@ impl<'a> MetaItemParser<'a> { /// - `#[rustfmt::skip]`: `rustfmt::skip` is a path /// - `#[allow(clippy::complexity)]`: `clippy::complexity` is a path /// - `#[inline]`: `inline` is a single segment path - pub fn path(&self) -> &PathParser<'a> { + pub fn path(&self) -> &OwnedPathParser { &self.path } /// Gets just the args parser, without caring about the path. - pub fn args(&self) -> &ArgParser<'a> { + pub fn args(&self) -> &ArgParser { &self.args } @@ -281,7 +284,7 @@ impl<'a> MetaItemParser<'a> { /// - `#[inline]`: `inline` is a word /// - `#[rustfmt::skip]`: `rustfmt::skip` is a path, /// and not a word and should instead be parsed using [`path`](Self::path) - pub fn word_is(&self, sym: Symbol) -> Option<&ArgParser<'a>> { + pub fn word_is(&self, sym: Symbol) -> Option<&ArgParser> { self.path().word_is(sym).then(|| self.args()) } } @@ -405,7 +408,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { Ok(lit) } - fn parse_attr_item(&mut self) -> PResult<'sess, MetaItemParser<'static>> { + fn parse_attr_item(&mut self) -> PResult<'sess, MetaItemParser> { if let Some(MetaVarKind::Meta { has_meta_form }) = self.parser.token.is_metavar_seq() { return if has_meta_form { let attr_item = self @@ -441,10 +444,10 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { ArgParser::NoArgs }; - Ok(MetaItemParser { path: PathParser(Cow::Owned(path)), args }) + Ok(MetaItemParser { path: PathParser(path), args }) } - fn parse_meta_item_inner(&mut self) -> PResult<'sess, MetaItemOrLitParser<'static>> { + fn parse_meta_item_inner(&mut self) -> PResult<'sess, MetaItemOrLitParser> { if let Some(token_lit) = self.parser.eat_token_lit() { // If a literal token is parsed, we commit to parsing a MetaItemLit for better errors Ok(MetaItemOrLitParser::Lit(self.unsuffixed_meta_item_from_lit(token_lit)?)) @@ -531,7 +534,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { psess: &'sess ParseSess, span: Span, should_emit: ShouldEmit, - ) -> PResult<'sess, MetaItemListParser<'static>> { + ) -> PResult<'sess, MetaItemListParser> { let mut parser = Parser::new(psess, tokens, None); let mut this = MetaItemListParserContext { parser: &mut parser, should_emit }; @@ -554,14 +557,14 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { } #[derive(Debug, Clone)] -pub struct MetaItemListParser<'a> { - sub_parsers: ThinVec>, +pub struct MetaItemListParser { + sub_parsers: ThinVec, pub span: Span, } -impl<'a> MetaItemListParser<'a> { +impl MetaItemListParser { pub(crate) fn new<'sess>( - tokens: &'a TokenStream, + tokens: &TokenStream, span: Span, psess: &'sess ParseSess, should_emit: ShouldEmit, @@ -570,7 +573,7 @@ impl<'a> MetaItemListParser<'a> { } /// Lets you pick and choose as what you want to parse each element in the list - pub fn mixed(&self) -> impl Iterator> { + pub fn mixed(&self) -> impl Iterator { self.sub_parsers.iter() } @@ -585,7 +588,7 @@ impl<'a> MetaItemListParser<'a> { /// Returns Some if the list contains only a single element. /// /// Inside the Some is the parser to parse this single element. - pub fn single(&self) -> Option<&MetaItemOrLitParser<'a>> { + pub fn single(&self) -> Option<&MetaItemOrLitParser> { let mut iter = self.mixed(); iter.next().filter(|_| iter.next().is_none()) } From aa6db80ab20f8b3b0a8bb51217b412ec4f426b3b Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Mon, 8 Dec 2025 22:56:09 +0100 Subject: [PATCH 0642/3801] Remove lifetime param from parser functions --- .../src/attributes/allow_unstable.rs | 20 +++--- .../rustc_attr_parsing/src/attributes/cfg.rs | 6 +- .../src/attributes/codegen_attrs.rs | 24 +++---- .../src/attributes/debugger.rs | 8 +-- .../rustc_attr_parsing/src/attributes/doc.rs | 62 +++++++++---------- .../src/attributes/link_attrs.rs | 8 +-- .../rustc_attr_parsing/src/attributes/mod.rs | 8 +-- .../rustc_attr_parsing/src/attributes/repr.rs | 12 ++-- compiler/rustc_attr_parsing/src/interface.rs | 2 +- 9 files changed, 73 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index faa366a62831..79f7171cc0c8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -17,9 +17,9 @@ impl CombineAttributeParser for AllowInternalUnstableParser { ]); const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]); - fn extend<'c>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, ) -> impl IntoIterator { parse_unstable(cx, args, >::PATH[0]) .into_iter() @@ -39,9 +39,9 @@ impl CombineAttributeParser for UnstableFeatureBoundParser { ]); const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]); - fn extend<'c>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, ) -> impl IntoIterator { if !cx.features().staged_api() { cx.emit_err(session_diagnostics::StabilityOutsideStd { span: cx.attr_span }); @@ -67,10 +67,10 @@ impl CombineAttributeParser for AllowConstFnUnstableParser { ]); const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]); - fn extend<'c>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, - ) -> impl IntoIterator + 'c { + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { parse_unstable(cx, args, >::PATH[0]) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 61c314b41b65..8c3896975201 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -35,9 +35,9 @@ const CFG_ATTR_TEMPLATE: AttributeTemplate = template!( "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute" ); -pub fn parse_cfg<'c, S: Stage>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, +pub fn parse_cfg( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, ) -> Option { let ArgParser::List(list) = args else { cx.expected_list(cx.attr_span); diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index ce208203ec5e..7d3a7418f06c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -472,10 +472,10 @@ impl AttributeParser for UsedParser { } } -fn parse_tf_attribute<'c, S: Stage>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, -) -> impl IntoIterator + 'c { +fn parse_tf_attribute( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, +) -> impl IntoIterator { let mut features = Vec::new(); let ArgParser::List(list) = args else { cx.expected_list(cx.attr_span); @@ -529,10 +529,10 @@ impl CombineAttributeParser for TargetFeatureParser { }; const TEMPLATE: AttributeTemplate = template!(List: &["enable = \"feat1, feat2\""]); - fn extend<'c>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, - ) -> impl IntoIterator + 'c { + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { parse_tf_attribute(cx, args) } @@ -567,10 +567,10 @@ impl CombineAttributeParser for ForceTargetFeatureParser { Allow(Target::Method(MethodKind::TraitImpl)), ]); - fn extend<'c>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, - ) -> impl IntoIterator + 'c { + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { parse_tf_attribute(cx, args) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/debugger.rs b/compiler/rustc_attr_parsing/src/attributes/debugger.rs index dfb3b914e189..c88b795aab03 100644 --- a/compiler/rustc_attr_parsing/src/attributes/debugger.rs +++ b/compiler/rustc_attr_parsing/src/attributes/debugger.rs @@ -16,10 +16,10 @@ impl CombineAttributeParser for DebuggerViualizerParser { type Item = DebugVisualizer; const CONVERT: ConvertFn = |v, _| AttributeKind::DebuggerVisualizer(v); - fn extend<'c>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, - ) -> impl IntoIterator + 'c { + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { let Some(l) = args.list() else { cx.expected_list(args.span().unwrap_or(cx.attr_span)); return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 547f00d14041..b6fea37c92aa 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -10,7 +10,7 @@ use thin_vec::ThinVec; use super::prelude::{ALL_TARGETS, AllowedTargets}; use super::{AcceptMapping, AttributeParser}; use crate::context::{AcceptContext, FinalizeContext, Stage}; -use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, PathParser}; +use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, OwnedPathParser}; use crate::session_diagnostics::{ DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttributeNotAttribute, DocKeywordNotKeyword, @@ -43,10 +43,10 @@ fn check_attribute( false } -fn parse_keyword_and_attribute<'c, S, F>( - cx: &'c mut AcceptContext<'_, '_, S>, - path: &PathParser<'_>, - args: &ArgParser<'_>, +fn parse_keyword_and_attribute( + cx: &mut AcceptContext<'_, '_, S>, + path: &OwnedPathParser, + args: &ArgParser, attr_value: &mut Option<(Symbol, Span)>, callback: F, ) where @@ -82,10 +82,10 @@ pub(crate) struct DocParser { } impl DocParser { - fn parse_single_test_doc_attr_item<'c, S: Stage>( + fn parse_single_test_doc_attr_item( &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - mip: &'c MetaItemParser<'_>, + cx: &mut AcceptContext<'_, '_, S>, + mip: &MetaItemParser, ) { let path = mip.path(); let args = mip.args(); @@ -132,9 +132,9 @@ impl DocParser { } } - fn add_alias<'c, S: Stage>( + fn add_alias( &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, + cx: &mut AcceptContext<'_, '_, S>, alias: Symbol, span: Span, ) { @@ -167,11 +167,11 @@ impl DocParser { self.attribute.aliases.insert(alias, span); } - fn parse_alias<'c, S: Stage>( + fn parse_alias( &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - path: &PathParser<'_>, - args: &ArgParser<'_>, + cx: &mut AcceptContext<'_, '_, S>, + path: &OwnedPathParser, + args: &ArgParser, ) { match args { ArgParser::NoArgs => { @@ -197,11 +197,11 @@ impl DocParser { } } - fn parse_inline<'c, S: Stage>( + fn parse_inline( &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - path: &PathParser<'_>, - args: &ArgParser<'_>, + cx: &mut AcceptContext<'_, '_, S>, + path: &OwnedPathParser, + args: &ArgParser, inline: DocInline, ) { if let Err(span) = args.no_args() { @@ -212,11 +212,7 @@ impl DocParser { self.attribute.inline.push((inline, path.span())); } - fn parse_cfg<'c, S: Stage>( - &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - args: &ArgParser<'_>, - ) { + fn parse_cfg(&mut self, cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) { // This function replaces cases like `cfg(all())` with `true`. fn simplify_cfg(cfg_entry: &mut CfgEntry) { match cfg_entry { @@ -236,11 +232,11 @@ impl DocParser { } } - fn parse_auto_cfg<'c, S: Stage>( + fn parse_auto_cfg( &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - path: &PathParser<'_>, - args: &ArgParser<'_>, + cx: &mut AcceptContext<'_, '_, S>, + path: &OwnedPathParser, + args: &ArgParser, ) { match args { ArgParser::NoArgs => { @@ -343,10 +339,10 @@ impl DocParser { } } - fn parse_single_doc_attr_item<'c, S: Stage>( + fn parse_single_doc_attr_item( &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - mip: &MetaItemParser<'_>, + cx: &mut AcceptContext<'_, '_, S>, + mip: &MetaItemParser, ) { let path = mip.path(); let args = mip.args(); @@ -506,10 +502,10 @@ impl DocParser { } } - fn accept_single_doc_attr<'c, S: Stage>( + fn accept_single_doc_attr( &mut self, - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser<'_>, + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, ) { match args { ArgParser::NoArgs => { diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 67471e31b105..fe8f3578fe14 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -62,10 +62,10 @@ impl CombineAttributeParser for LinkParser { ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs` - fn extend<'c>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, - ) -> impl IntoIterator + 'c { + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { let items = match args { ArgParser::List(list) => list, // This is an edgecase added because making this a hard error would break too many crates diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index a26159cb09e7..bd58c44214a2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -315,10 +315,10 @@ pub(crate) trait CombineAttributeParser: 'static { const TEMPLATE: AttributeTemplate; /// Converts a single syntactical attribute to a number of elements of the semantic attribute, or [`AttributeKind`] - fn extend<'c>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, - ) -> impl IntoIterator + 'c; + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator; } /// Use in combination with [`CombineAttributeParser`]. diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index c7320bf5d96f..4520e4f5dbac 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -26,10 +26,10 @@ impl CombineAttributeParser for ReprParser { "https://doc.rust-lang.org/reference/type-layout.html#representations" ); - fn extend<'c>( - cx: &'c mut AcceptContext<'_, '_, S>, - args: &'c ArgParser, - ) -> impl IntoIterator + 'c { + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { let mut reprs = Vec::new(); let Some(list) = args.list() else { @@ -275,7 +275,7 @@ impl AlignParser { const PATH: &'static [Symbol] = &[sym::rustc_align]; const TEMPLATE: AttributeTemplate = template!(List: &[""]); - fn parse<'c, S: Stage>(&mut self, cx: &'c mut AcceptContext<'_, '_, S>, args: &'c ArgParser) { + fn parse(&mut self, cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) { match args { ArgParser::NoArgs | ArgParser::NameValue(_) => { cx.expected_list(cx.attr_span); @@ -332,7 +332,7 @@ impl AlignStaticParser { const PATH: &'static [Symbol] = &[sym::rustc_align_static]; const TEMPLATE: AttributeTemplate = AlignParser::TEMPLATE; - fn parse<'c, S: Stage>(&mut self, cx: &'c mut AcceptContext<'_, '_, S>, args: &'c ArgParser) { + fn parse(&mut self, cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) { self.0.parse(cx, args) } } diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 732f8d6e3a2a..91596ff0de60 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -342,7 +342,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { // blob // a if is_doc_attribute - && let ArgParser::NameValue(nv) = args + && let ArgParser::NameValue(nv) = &args // If not a string key/value, it should emit an error, but to make // things simpler, it's handled in `DocParser` because it's simpler to // emit an error with `AcceptContext`. From 04fedf71738c44e716b01480550787d99c47a254 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 12 Dec 2025 09:12:31 +0100 Subject: [PATCH 0643/3801] Remove unused code in `cfg_old` --- compiler/rustc_attr_parsing/messages.ftl | 10 - .../rustc_attr_parsing/src/attributes/cfg.rs | 22 +- .../src/attributes/cfg_old.rs | 210 ------------------ .../rustc_attr_parsing/src/attributes/mod.rs | 1 - .../src/attributes/stability.rs | 4 +- compiler/rustc_attr_parsing/src/lib.rs | 1 - .../src/session_diagnostics.rs | 37 +-- 7 files changed, 22 insertions(+), 263 deletions(-) delete mode 100644 compiler/rustc_attr_parsing/src/attributes/cfg_old.rs diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index f2642838b3c8..deebc25c8259 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -6,9 +6,6 @@ attr_parsing_bundle_needs_static = attr_parsing_cfg_attr_bad_delim = wrong `cfg_attr` delimiters -attr_parsing_cfg_predicate_identifier = - `cfg` predicate key must be an identifier - attr_parsing_deprecated_item_suggestion = suggestions on deprecated items are unstable .help = add `#![feature(deprecated_suggestion)]` to the crate root @@ -41,9 +38,6 @@ attr_parsing_empty_link_name = link name must not be empty .label = empty link name -attr_parsing_expected_one_cfg_pattern = - expected 1 cfg-pattern - attr_parsing_expected_single_version_literal = expected single version literal @@ -241,10 +235,6 @@ attr_parsing_unstable_cfg_target_compact = attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable .help = If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` -attr_parsing_unsupported_literal_cfg_boolean = - literal in `cfg` predicate value must be a boolean -attr_parsing_unsupported_literal_cfg_string = - literal in `cfg` predicate value must be a string attr_parsing_unsupported_literal_generic = unsupported literal attr_parsing_unsupported_literal_suggestion = diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 6ffe25098308..93f425530941 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -4,7 +4,9 @@ use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, ast, token}; use rustc_errors::{Applicability, PResult}; -use rustc_feature::{AttrSuggestionStyle, AttributeTemplate, Features, template}; +use rustc_feature::{ + AttrSuggestionStyle, AttributeTemplate, Features, GatedCfg, find_gated_cfg, template, +}; use rustc_hir::attrs::CfgEntry; use rustc_hir::lints::AttributeLintKind; use rustc_hir::{AttrPath, RustcVersion}; @@ -23,7 +25,7 @@ use crate::session_diagnostics::{ AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg, ParsedDescription, }; -use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics, try_gate_cfg}; +use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics}; pub const CFG_TEMPLATE: AttributeTemplate = template!( List: &["predicate"], @@ -410,3 +412,19 @@ fn parse_cfg_attr_internal<'a>( Ok((cfg_predicate, expanded_attrs)) } + +fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) { + let gate = find_gated_cfg(|sym| sym == name); + if let (Some(feats), Some(gated_cfg)) = (features, gate) { + gate_cfg(gated_cfg, span, sess, feats); + } +} + +#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable +fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) { + let (cfg, feature, has_feature) = gated_cfg; + if !has_feature(features) && !cfg_span.allows_unstable(*feature) { + let explain = format!("`cfg({cfg})` is experimental and subject to change"); + feature_err(sess, *feature, cfg_span, explain).emit(); + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs deleted file mode 100644 index acb234480d5d..000000000000 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_old.rs +++ /dev/null @@ -1,210 +0,0 @@ -use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId}; -use rustc_ast_pretty::pprust; -use rustc_feature::{Features, GatedCfg, find_gated_cfg}; -use rustc_hir::RustcVersion; -use rustc_session::Session; -use rustc_session::lint::{BuiltinLintDiag, Lint}; -use rustc_session::parse::feature_err; -use rustc_span::{Span, Symbol, sym}; - -use crate::session_diagnostics::{self, UnsupportedLiteralReason}; -use crate::{fluent_generated, parse_version}; - -/// Emitter of a builtin lint from `cfg_matches`. -/// -/// Used to support emitting a lint (currently on check-cfg), either: -/// - as an early buffered lint (in `rustc`) -/// - or has a "normal" lint from HIR (in `rustdoc`) -pub trait CfgMatchesLintEmitter { - fn emit_span_lint(&self, sess: &Session, lint: &'static Lint, sp: Span, diag: BuiltinLintDiag); -} - -impl CfgMatchesLintEmitter for NodeId { - fn emit_span_lint(&self, sess: &Session, lint: &'static Lint, sp: Span, diag: BuiltinLintDiag) { - sess.psess.buffer_lint(lint, sp, *self, diag); - } -} - -#[derive(Clone, Debug)] -pub struct Condition { - pub name: Symbol, - pub name_span: Span, - pub value: Option, - pub value_span: Option, - pub span: Span, -} - -pub fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) { - let gate = find_gated_cfg(|sym| sym == name); - if let (Some(feats), Some(gated_cfg)) = (features, gate) { - gate_cfg(gated_cfg, span, sess, feats); - } -} - -#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable -fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) { - let (cfg, feature, has_feature) = gated_cfg; - if !has_feature(features) && !cfg_span.allows_unstable(*feature) { - let explain = format!("`cfg({cfg})` is experimental and subject to change"); - feature_err(sess, *feature, cfg_span, explain).emit(); - } -} - -/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to -/// evaluate individual items. -pub fn eval_condition( - cfg: &MetaItemInner, - sess: &Session, - features: Option<&Features>, - eval: &mut impl FnMut(Condition) -> bool, -) -> bool { - let dcx = sess.dcx(); - - let cfg = match cfg { - MetaItemInner::MetaItem(meta_item) => meta_item, - MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => { - return *b; - } - _ => { - dcx.emit_err(session_diagnostics::UnsupportedLiteral { - span: cfg.span(), - reason: UnsupportedLiteralReason::CfgBoolean, - is_bytestr: false, - start_point_span: sess.source_map().start_point(cfg.span()), - }); - return false; - } - }; - - match &cfg.kind { - MetaItemKind::List(mis) if cfg.has_name(sym::version) => { - try_gate_cfg(sym::version, cfg.span, sess, features); - let (min_version, span) = match &mis[..] { - [MetaItemInner::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => { - (sym, span) - } - [ - MetaItemInner::Lit(MetaItemLit { span, .. }) - | MetaItemInner::MetaItem(MetaItem { span, .. }), - ] => { - dcx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span }); - return false; - } - [..] => { - dcx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { - span: cfg.span, - }); - return false; - } - }; - let Some(min_version) = parse_version(*min_version) else { - dcx.emit_warn(session_diagnostics::UnknownVersionLiteral { span: *span }); - return false; - }; - - // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details - if sess.psess.assume_incomplete_release { - RustcVersion::current_overridable() > min_version - } else { - RustcVersion::current_overridable() >= min_version - } - } - MetaItemKind::List(mis) => { - for mi in mis.iter() { - if mi.meta_item_or_bool().is_none() { - dcx.emit_err(session_diagnostics::UnsupportedLiteral { - span: mi.span(), - reason: UnsupportedLiteralReason::Generic, - is_bytestr: false, - start_point_span: sess.source_map().start_point(mi.span()), - }); - return false; - } - } - - // The unwraps below may look dangerous, but we've already asserted - // that they won't fail with the loop above. - match cfg.name() { - Some(sym::any) => mis - .iter() - // We don't use any() here, because we want to evaluate all cfg condition - // as eval_condition can (and does) extra checks - .fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)), - Some(sym::all) => mis - .iter() - // We don't use all() here, because we want to evaluate all cfg condition - // as eval_condition can (and does) extra checks - .fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)), - Some(sym::not) => { - let [mi] = mis.as_slice() else { - dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span }); - return false; - }; - - !eval_condition(mi, sess, features, eval) - } - Some(sym::target) => { - if let Some(features) = features - && !features.cfg_target_compact() - { - feature_err( - sess, - sym::cfg_target_compact, - cfg.span, - fluent_generated::attr_parsing_unstable_cfg_target_compact, - ) - .emit(); - } - - mis.iter().fold(true, |res, mi| { - let Some(mut mi) = mi.meta_item().cloned() else { - dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { - span: mi.span(), - }); - return false; - }; - - if let [seg, ..] = &mut mi.path.segments[..] { - seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name)); - } - - res & eval_condition(&MetaItemInner::MetaItem(mi), sess, features, eval) - }) - } - _ => { - dcx.emit_err(session_diagnostics::InvalidPredicate { - span: cfg.span, - predicate: pprust::path_to_string(&cfg.path), - }); - false - } - } - } - MetaItemKind::Word | MetaItemKind::NameValue(..) - if cfg.path.segments.len() != 1 - || cfg.path.segments[0].ident.is_path_segment_keyword() => - { - dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span }); - true - } - MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { - dcx.emit_err(session_diagnostics::UnsupportedLiteral { - span: lit.span, - reason: UnsupportedLiteralReason::CfgString, - is_bytestr: lit.kind.is_bytestr(), - start_point_span: sess.source_map().start_point(lit.span), - }); - true - } - MetaItemKind::Word | MetaItemKind::NameValue(..) => { - let ident = cfg.ident().expect("multi-segment cfg predicate"); - eval(Condition { - name: ident.name, - name_span: ident.span, - value: cfg.value_str(), - value_span: cfg.name_value_literal_span(), - span: cfg.span, - }) - } - } -} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 64bcb02b0b74..385003a35927 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -32,7 +32,6 @@ mod prelude; pub(crate) mod allow_unstable; pub(crate) mod body; pub(crate) mod cfg; -pub(crate) mod cfg_old; pub(crate) mod cfg_select; pub(crate) mod codegen_attrs; pub(crate) mod confusables; diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index b94e23477ffe..b97095893b8e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -8,7 +8,7 @@ use rustc_hir::{ use super::prelude::*; use super::util::parse_version; -use crate::session_diagnostics::{self, UnsupportedLiteralReason}; +use crate::session_diagnostics::{self}; macro_rules! reject_outside_std { ($cx: ident) => { @@ -304,7 +304,6 @@ pub(crate) fn parse_stability( let Some(param) = param.meta_item() else { cx.emit_err(session_diagnostics::UnsupportedLiteral { span: param_span, - reason: UnsupportedLiteralReason::Generic, is_bytestr: false, start_point_span: cx.sess().source_map().start_point(param_span), }); @@ -384,7 +383,6 @@ pub(crate) fn parse_unstability( let Some(param) = param.meta_item() else { cx.emit_err(session_diagnostics::UnsupportedLiteral { span: param.span(), - reason: UnsupportedLiteralReason::Generic, is_bytestr: false, start_point_span: cx.sess().source_map().start_point(param.span()), }); diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index cb02bb9d501f..411b4dd75e66 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -107,7 +107,6 @@ pub mod validate_attr; pub use attributes::cfg::{ CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr, parse_cfg_entry, }; -pub use attributes::cfg_old::*; pub use attributes::cfg_select::*; pub use attributes::util::{is_builtin_attr, parse_version}; pub use context::{Early, Late, OmitDoc, ShouldEmit}; diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 7bb55d2a6de5..df555a33f816 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -12,19 +12,6 @@ use rustc_span::{Span, Symbol}; use crate::fluent_generated as fluent; -pub(crate) enum UnsupportedLiteralReason { - Generic, - CfgString, - CfgBoolean, -} - -#[derive(Diagnostic)] -#[diag(attr_parsing_expected_one_cfg_pattern, code = E0536)] -pub(crate) struct ExpectedOneCfgPattern { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(attr_parsing_invalid_predicate, code = E0537)] pub(crate) struct InvalidPredicate { @@ -234,28 +221,13 @@ pub(crate) struct InvalidReprHintNoValue { // FIXME(jdonszelmann): slowly phased out pub(crate) struct UnsupportedLiteral { pub span: Span, - pub reason: UnsupportedLiteralReason, pub is_bytestr: bool, pub start_point_span: Span, } impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - let mut diag = Diag::new( - dcx, - level, - match self.reason { - UnsupportedLiteralReason::Generic => { - fluent::attr_parsing_unsupported_literal_generic - } - UnsupportedLiteralReason::CfgString => { - fluent::attr_parsing_unsupported_literal_cfg_string - } - UnsupportedLiteralReason::CfgBoolean => { - fluent::attr_parsing_unsupported_literal_cfg_boolean - } - }, - ); + let mut diag = Diag::new(dcx, level, fluent::attr_parsing_unsupported_literal_generic); diag.span(self.span); diag.code(E0565); if self.is_bytestr { @@ -375,13 +347,6 @@ pub(crate) struct RustcAllowedUnstablePairing { pub span: Span, } -#[derive(Diagnostic)] -#[diag(attr_parsing_cfg_predicate_identifier)] -pub(crate) struct CfgPredicateIdentifier { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(attr_parsing_deprecated_item_suggestion)] pub(crate) struct DeprecatedItemSuggestion { From acea7df0b4fdba04f94528f19ea1333cd68d2670 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 12 Dec 2025 09:24:49 +0100 Subject: [PATCH 0644/3801] Remove last remaining usages of `UnsupportedLiteral` --- compiler/rustc_attr_parsing/messages.ftl | 2 -- .../src/attributes/stability.rs | 12 ++------- .../src/session_diagnostics.rs | 25 ------------------- 3 files changed, 2 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index deebc25c8259..61f816f0baf8 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -235,8 +235,6 @@ attr_parsing_unstable_cfg_target_compact = attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable .help = If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` -attr_parsing_unsupported_literal_generic = - unsupported literal attr_parsing_unsupported_literal_suggestion = consider removing the prefix diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index b97095893b8e..fede424c3af7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -302,11 +302,7 @@ pub(crate) fn parse_stability( for param in list.mixed() { let param_span = param.span(); let Some(param) = param.meta_item() else { - cx.emit_err(session_diagnostics::UnsupportedLiteral { - span: param_span, - is_bytestr: false, - start_point_span: cx.sess().source_map().start_point(param_span), - }); + cx.unexpected_literal(param.span()); return None; }; @@ -381,11 +377,7 @@ pub(crate) fn parse_unstability( for param in list.mixed() { let Some(param) = param.meta_item() else { - cx.emit_err(session_diagnostics::UnsupportedLiteral { - span: param.span(), - is_bytestr: false, - start_point_span: cx.sess().source_map().start_point(param.span()), - }); + cx.unexpected_literal(param.span()); return None; }; diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index df555a33f816..3adbe115b23b 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -217,31 +217,6 @@ pub(crate) struct InvalidReprHintNoValue { pub name: Symbol, } -/// Error code: E0565 -// FIXME(jdonszelmann): slowly phased out -pub(crate) struct UnsupportedLiteral { - pub span: Span, - pub is_bytestr: bool, - pub start_point_span: Span, -} - -impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral { - fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - let mut diag = Diag::new(dcx, level, fluent::attr_parsing_unsupported_literal_generic); - diag.span(self.span); - diag.code(E0565); - if self.is_bytestr { - diag.span_suggestion( - self.start_point_span, - fluent::attr_parsing_unsupported_literal_suggestion, - "", - Applicability::MaybeIncorrect, - ); - } - diag - } -} - #[derive(Diagnostic)] #[diag(attr_parsing_invalid_repr_align_need_arg, code = E0589)] pub(crate) struct InvalidReprAlignNeedArg { From 9e638455220c0c67393cfb1ed14cc3f0c23bf8f0 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Fri, 12 Dec 2025 18:26:16 +0900 Subject: [PATCH 0645/3801] `-Znext-solver` Remove the forced ambiguity hack from search graph --- .../rustc_type_ir/src/search_graph/mod.rs | 31 ++----------- .../global-where-bound-normalization.rs | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+), 28 deletions(-) create mode 100644 tests/ui/traits/next-solver/global-where-bound-normalization.rs diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 8e6376b22ce6..7c58cd7303eb 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -916,10 +916,9 @@ impl, X: Cx> SearchGraph { /// heads from the stack. This may not necessarily mean that we've actually /// reached a fixpoint for that cycle head, which impacts the way we rebase /// provisional cache entries. -#[derive_where(Debug; X: Cx)] -enum RebaseReason { +#[derive(Debug)] +enum RebaseReason { NoCycleUsages, - Ambiguity(X::AmbiguityInfo), Overflow, /// We've actually reached a fixpoint. /// @@ -956,7 +955,7 @@ impl, X: Cx> SearchGraph { &mut self, cx: X, stack_entry: &StackEntry, - rebase_reason: RebaseReason, + rebase_reason: RebaseReason, ) { let popped_head_index = self.stack.next_index(); #[allow(rustc::potential_query_instability)] @@ -1035,9 +1034,6 @@ impl, X: Cx> SearchGraph { // is not actually equal to the final provisional result. We // need to discard the provisional cache entry in this case. RebaseReason::NoCycleUsages => return false, - RebaseReason::Ambiguity(info) => { - *result = D::propagate_ambiguity(cx, input, info); - } RebaseReason::Overflow => *result = D::fixpoint_overflow_result(cx, input), RebaseReason::ReachedFixpoint(None) => {} RebaseReason::ReachedFixpoint(Some(path_kind)) => { @@ -1352,27 +1348,6 @@ impl, X: Cx> SearchGraph { return EvaluationResult::finalize(stack_entry, encountered_overflow, result); } - // If computing this goal results in ambiguity with no constraints, - // we do not rerun it. It's incredibly difficult to get a different - // response in the next iteration in this case. These changes would - // likely either be caused by incompleteness or can change the maybe - // cause from ambiguity to overflow. Returning ambiguity always - // preserves soundness and completeness even if the goal is be known - // to succeed or fail. - // - // This prevents exponential blowup affecting multiple major crates. - // As we only get to this branch if we haven't yet reached a fixpoint, - // we also taint all provisional cache entries which depend on the - // current goal. - if let Some(info) = D::is_ambiguous_result(result) { - self.rebase_provisional_cache_entries( - cx, - &stack_entry, - RebaseReason::Ambiguity(info), - ); - return EvaluationResult::finalize(stack_entry, encountered_overflow, result); - }; - // If we've reached the fixpoint step limit, we bail with overflow and taint all // provisional cache entries which depend on the current goal. i += 1; diff --git a/tests/ui/traits/next-solver/global-where-bound-normalization.rs b/tests/ui/traits/next-solver/global-where-bound-normalization.rs new file mode 100644 index 000000000000..e57fbf378a0d --- /dev/null +++ b/tests/ui/traits/next-solver/global-where-bound-normalization.rs @@ -0,0 +1,45 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +// Regression test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/257. + +#![feature(rustc_attrs)] +#![expect(internal_features)] +#![rustc_no_implicit_bounds] + +pub trait Bound {} +impl Bound for u8 {} + +pub trait Proj { + type Assoc; +} +impl Proj for U { + type Assoc = U; +} +impl Proj for MyField { + type Assoc = u8; +} + +// While wf-checking the global bounds of `fn foo`, elaborating this outlives predicate triggered a +// cycle in the search graph along a particular probe path, which was not an actual solution. +// That cycle then resulted in a forced false-positive ambiguity due to a performance hack in the +// search graph and then ended up floundering the root goal evaluation. +pub trait Field: Proj {} + +struct MyField; +impl Field for MyField {} + +trait IdReqField { + type This; +} +impl IdReqField for F { + type This = F; +} + +fn foo() +where + ::This: Field, +{ +} + +fn main() {} From 0ac215aabefcc1e5b782caf788b061d8ae8b9e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 28 Jul 2025 10:35:42 +0200 Subject: [PATCH 0646/3801] EII tests --- tests/ui/eii/auxiliary/codegen1.rs | 18 +++ tests/ui/eii/auxiliary/codegen2.rs | 6 + tests/ui/eii/auxiliary/codegen3.rs | 22 ++++ .../auxiliary/cross_crate_eii_declaration.rs | 16 +++ tests/ui/eii/codegen_cross_crate.rs | 21 ++++ tests/ui/eii/codegen_cross_crate.run.stdout | 2 + tests/ui/eii/codegen_single_crate.rs | 20 ++++ tests/ui/eii/codegen_single_crate.run.stdout | 2 + tests/ui/eii/cross_crate.rs | 19 +++ tests/ui/eii/cross_crate_wrong_ty.rs | 19 +++ tests/ui/eii/cross_crate_wrong_ty.stderr | 16 +++ .../default/auxiliary/decl_with_default.rs | 8 ++ tests/ui/eii/default/auxiliary/impl1.rs | 12 ++ tests/ui/eii/default/call_default.rs | 13 +++ tests/ui/eii/default/call_default.run.stdout | 1 + tests/ui/eii/default/call_impl.rs | 16 +++ tests/ui/eii/default/call_impl.run.stdout | 1 + tests/ui/eii/default/local_crate.rs | 14 +++ tests/ui/eii/default/local_crate.run.stdout | 1 + tests/ui/eii/default/local_crate_explicit.rs | 20 ++++ .../default/local_crate_explicit.run.stdout | 1 + .../eii/default/local_crate_explicit.stderr | 10 ++ tests/ui/eii/duplicate/auxiliary/decl.rs | 6 + tests/ui/eii/duplicate/auxiliary/impl1.rs | 12 ++ tests/ui/eii/duplicate/auxiliary/impl2.rs | 12 ++ tests/ui/eii/duplicate/auxiliary/impl3.rs | 12 ++ tests/ui/eii/duplicate/auxiliary/impl4.rs | 12 ++ tests/ui/eii/duplicate/duplicate1.rs | 13 +++ tests/ui/eii/duplicate/duplicate1.stderr | 15 +++ tests/ui/eii/duplicate/duplicate2.rs | 15 +++ tests/ui/eii/duplicate/duplicate2.stderr | 16 +++ tests/ui/eii/duplicate/duplicate3.rs | 17 +++ tests/ui/eii/duplicate/duplicate3.stderr | 16 +++ tests/ui/eii/errors.rs | 45 +++++++ tests/ui/eii/errors.stderr | 98 ++++++++++++++++ tests/ui/eii/privacy1.rs | 31 +++++ tests/ui/eii/privacy1.run.stdout | 4 + tests/ui/eii/privacy2.rs | 27 +++++ tests/ui/eii/privacy2.stderr | 38 ++++++ tests/ui/eii/subtype_1.rs | 27 +++++ tests/ui/eii/subtype_1.stderr | 13 +++ tests/ui/eii/subtype_2.rs | 27 +++++ tests/ui/eii/subtype_2.stderr | 13 +++ tests/ui/eii/subtype_3.rs | 27 +++++ tests/ui/eii/subtype_4.rs | 27 +++++ tests/ui/eii/unsafe_impl_err.rs | 25 ++++ tests/ui/eii/unsafe_impl_err.stderr | 13 +++ tests/ui/eii/unsafe_impl_ok.rs | 27 +++++ tests/ui/eii/wrong_ret_ty.rs | 26 +++++ tests/ui/eii/wrong_ret_ty.stderr | 26 +++++ tests/ui/eii/wrong_target.rs | 63 ++++++++++ tests/ui/eii/wrong_target.stderr | 110 ++++++++++++++++++ tests/ui/eii/wrong_ty.rs | 26 +++++ tests/ui/eii/wrong_ty.stderr | 27 +++++ tests/ui/eii/wrong_ty_2.rs | 26 +++++ tests/ui/eii/wrong_ty_2.stderr | 14 +++ 56 files changed, 1164 insertions(+) create mode 100644 tests/ui/eii/auxiliary/codegen1.rs create mode 100644 tests/ui/eii/auxiliary/codegen2.rs create mode 100644 tests/ui/eii/auxiliary/codegen3.rs create mode 100644 tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs create mode 100644 tests/ui/eii/codegen_cross_crate.rs create mode 100644 tests/ui/eii/codegen_cross_crate.run.stdout create mode 100644 tests/ui/eii/codegen_single_crate.rs create mode 100644 tests/ui/eii/codegen_single_crate.run.stdout create mode 100644 tests/ui/eii/cross_crate.rs create mode 100644 tests/ui/eii/cross_crate_wrong_ty.rs create mode 100644 tests/ui/eii/cross_crate_wrong_ty.stderr create mode 100644 tests/ui/eii/default/auxiliary/decl_with_default.rs create mode 100644 tests/ui/eii/default/auxiliary/impl1.rs create mode 100644 tests/ui/eii/default/call_default.rs create mode 100644 tests/ui/eii/default/call_default.run.stdout create mode 100644 tests/ui/eii/default/call_impl.rs create mode 100644 tests/ui/eii/default/call_impl.run.stdout create mode 100644 tests/ui/eii/default/local_crate.rs create mode 100644 tests/ui/eii/default/local_crate.run.stdout create mode 100644 tests/ui/eii/default/local_crate_explicit.rs create mode 100644 tests/ui/eii/default/local_crate_explicit.run.stdout create mode 100644 tests/ui/eii/default/local_crate_explicit.stderr create mode 100644 tests/ui/eii/duplicate/auxiliary/decl.rs create mode 100644 tests/ui/eii/duplicate/auxiliary/impl1.rs create mode 100644 tests/ui/eii/duplicate/auxiliary/impl2.rs create mode 100644 tests/ui/eii/duplicate/auxiliary/impl3.rs create mode 100644 tests/ui/eii/duplicate/auxiliary/impl4.rs create mode 100644 tests/ui/eii/duplicate/duplicate1.rs create mode 100644 tests/ui/eii/duplicate/duplicate1.stderr create mode 100644 tests/ui/eii/duplicate/duplicate2.rs create mode 100644 tests/ui/eii/duplicate/duplicate2.stderr create mode 100644 tests/ui/eii/duplicate/duplicate3.rs create mode 100644 tests/ui/eii/duplicate/duplicate3.stderr create mode 100644 tests/ui/eii/errors.rs create mode 100644 tests/ui/eii/errors.stderr create mode 100644 tests/ui/eii/privacy1.rs create mode 100644 tests/ui/eii/privacy1.run.stdout create mode 100644 tests/ui/eii/privacy2.rs create mode 100644 tests/ui/eii/privacy2.stderr create mode 100644 tests/ui/eii/subtype_1.rs create mode 100644 tests/ui/eii/subtype_1.stderr create mode 100644 tests/ui/eii/subtype_2.rs create mode 100644 tests/ui/eii/subtype_2.stderr create mode 100644 tests/ui/eii/subtype_3.rs create mode 100644 tests/ui/eii/subtype_4.rs create mode 100644 tests/ui/eii/unsafe_impl_err.rs create mode 100644 tests/ui/eii/unsafe_impl_err.stderr create mode 100644 tests/ui/eii/unsafe_impl_ok.rs create mode 100644 tests/ui/eii/wrong_ret_ty.rs create mode 100644 tests/ui/eii/wrong_ret_ty.stderr create mode 100644 tests/ui/eii/wrong_target.rs create mode 100644 tests/ui/eii/wrong_target.stderr create mode 100644 tests/ui/eii/wrong_ty.rs create mode 100644 tests/ui/eii/wrong_ty.stderr create mode 100644 tests/ui/eii/wrong_ty_2.rs create mode 100644 tests/ui/eii/wrong_ty_2.stderr diff --git a/tests/ui/eii/auxiliary/codegen1.rs b/tests/ui/eii/auxiliary/codegen1.rs new file mode 100644 index 000000000000..93c5df2d41c0 --- /dev/null +++ b/tests/ui/eii/auxiliary/codegen1.rs @@ -0,0 +1,18 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(eii)] + +#[eii(eii1)] +fn decl1(x: u64); + +mod private { + #[eii(eii2)] + pub fn decl2(x: u64); +} + +pub use private::eii2 as eii3; +pub use private::decl2 as decl3; + +pub fn local_call_decl1(x: u64) { + decl1(x) +} diff --git a/tests/ui/eii/auxiliary/codegen2.rs b/tests/ui/eii/auxiliary/codegen2.rs new file mode 100644 index 000000000000..9545ad007c57 --- /dev/null +++ b/tests/ui/eii/auxiliary/codegen2.rs @@ -0,0 +1,6 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(eii)] + +#[eii(eii1)] +pub fn decl1(x: u64); diff --git a/tests/ui/eii/auxiliary/codegen3.rs b/tests/ui/eii/auxiliary/codegen3.rs new file mode 100644 index 000000000000..2b882c48d829 --- /dev/null +++ b/tests/ui/eii/auxiliary/codegen3.rs @@ -0,0 +1,22 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(eii)] + +// does have an impl but can't be called +#[eii(eii1)] +fn decl1(x: u64); + +#[eii(eii2)] +pub fn decl2(x: u64); + +mod private { + #[eii(eii3)] + pub fn decl3(x: u64); +} + +pub use private::eii3 as eii4; +pub use private::decl3 as decl4; + +pub fn local_call_decl1(x: u64) { + decl1(x) +} diff --git a/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs b/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs new file mode 100644 index 000000000000..36a42ad199b0 --- /dev/null +++ b/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs @@ -0,0 +1,16 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar)] +#[rustc_builtin_macro(eii_macro)] +pub macro foo() { + +} + +unsafe extern "Rust" { + pub safe fn bar(x: u64) -> u64; +} diff --git a/tests/ui/eii/codegen_cross_crate.rs b/tests/ui/eii/codegen_cross_crate.rs new file mode 100644 index 000000000000..b5b2d940b730 --- /dev/null +++ b/tests/ui/eii/codegen_cross_crate.rs @@ -0,0 +1,21 @@ +//@ run-pass +//@ check-run-results +//@ aux-build: codegen2.rs +//@ compile-flags: -O +// Tests whether calling EIIs works with the declaration in another crate. +#![feature(eii)] + +extern crate codegen2 as codegen; + +#[codegen::eii1] +fn eii1_impl(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + // directly + eii1_impl(21); + // through the alias + codegen::decl1(42); +} diff --git a/tests/ui/eii/codegen_cross_crate.run.stdout b/tests/ui/eii/codegen_cross_crate.run.stdout new file mode 100644 index 000000000000..960b54672100 --- /dev/null +++ b/tests/ui/eii/codegen_cross_crate.run.stdout @@ -0,0 +1,2 @@ +21 +42 diff --git a/tests/ui/eii/codegen_single_crate.rs b/tests/ui/eii/codegen_single_crate.rs new file mode 100644 index 000000000000..c2d986d12c1a --- /dev/null +++ b/tests/ui/eii/codegen_single_crate.rs @@ -0,0 +1,20 @@ +//@ run-pass +//@ check-run-results +// Tests whether calling EIIs works with the declaration in the same crate. +#![feature(eii)] + +#[eii] +fn hello(x: u64); + +#[hello] +fn hello_impl(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + // directly + hello_impl(21); + // through the alias + hello(42); +} diff --git a/tests/ui/eii/codegen_single_crate.run.stdout b/tests/ui/eii/codegen_single_crate.run.stdout new file mode 100644 index 000000000000..960b54672100 --- /dev/null +++ b/tests/ui/eii/codegen_single_crate.run.stdout @@ -0,0 +1,2 @@ +21 +42 diff --git a/tests/ui/eii/cross_crate.rs b/tests/ui/eii/cross_crate.rs new file mode 100644 index 000000000000..72f1533587bf --- /dev/null +++ b/tests/ui/eii/cross_crate.rs @@ -0,0 +1,19 @@ +//@ compile-flags: --crate-type rlib +//@ check-pass +//@ aux-build: cross_crate_eii_declaration.rs +// Tests whether calling EIIs works with the declaration in another crate. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +extern crate cross_crate_eii_declaration; + +#[unsafe(cross_crate_eii_declaration::foo)] +fn other(x: u64) -> u64 { + x +} + +fn main() { + cross_crate_eii_declaration::bar(0); +} diff --git a/tests/ui/eii/cross_crate_wrong_ty.rs b/tests/ui/eii/cross_crate_wrong_ty.rs new file mode 100644 index 000000000000..f99b812b6c50 --- /dev/null +++ b/tests/ui/eii/cross_crate_wrong_ty.rs @@ -0,0 +1,19 @@ +//@ compile-flags: --crate-type rlib +//@ aux-build: cross_crate_eii_declaration.rs +// Tests whether the type checking still works properly when the declaration is in another crate. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +extern crate cross_crate_eii_declaration; + +#[unsafe(cross_crate_eii_declaration::foo)] +fn other() -> u64 { +//~^ ERROR `other` has 0 parameters but #[foo] requires it to have 1 + 0 +} + +fn main() { + cross_crate_eii_declaration::bar(0); +} diff --git a/tests/ui/eii/cross_crate_wrong_ty.stderr b/tests/ui/eii/cross_crate_wrong_ty.stderr new file mode 100644 index 000000000000..c85974f78206 --- /dev/null +++ b/tests/ui/eii/cross_crate_wrong_ty.stderr @@ -0,0 +1,16 @@ +error[E0050]: `other` has 0 parameters but #[foo] requires it to have 1 + --> $DIR/cross_crate_wrong_ty.rs:12:1 + | +LL | #[unsafe(cross_crate_eii_declaration::foo)] + | ------------------------------------------- required because of this attribute +LL | fn other() -> u64 { + | ^^^^^^^^^^^^^^^^^ expected 1 parameter, found 0 + | + ::: $DIR/auxiliary/cross_crate_eii_declaration.rs:15:5 + | +LL | pub safe fn bar(x: u64) -> u64; + | ------------------------------- requires 1 parameter + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0050`. diff --git a/tests/ui/eii/default/auxiliary/decl_with_default.rs b/tests/ui/eii/default/auxiliary/decl_with_default.rs new file mode 100644 index 000000000000..b1811b07eb17 --- /dev/null +++ b/tests/ui/eii/default/auxiliary/decl_with_default.rs @@ -0,0 +1,8 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(eii)] + +#[eii(eii1)] +pub fn decl1(x: u64) { + println!("default {x}"); +} diff --git a/tests/ui/eii/default/auxiliary/impl1.rs b/tests/ui/eii/default/auxiliary/impl1.rs new file mode 100644 index 000000000000..4d627a5f68a6 --- /dev/null +++ b/tests/ui/eii/default/auxiliary/impl1.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl_with_default.rs +#![crate_type = "rlib"] +#![feature(eii)] + +extern crate decl_with_default as decl; + + +#[unsafe(decl::eii1)] //~ ERROR multiple implementations of `#[eii1]` +fn other(x: u64) { + println!("1{x}"); +} diff --git a/tests/ui/eii/default/call_default.rs b/tests/ui/eii/default/call_default.rs new file mode 100644 index 000000000000..520863f1d3e9 --- /dev/null +++ b/tests/ui/eii/default/call_default.rs @@ -0,0 +1,13 @@ +//@ no-prefer-dynamic +//@ aux-build: decl_with_default.rs +//@ run-pass +//@ check-run-results +// Tests EIIs with default implementations. +// When there's no explicit declaration, the default should be called from the declaring crate. +#![feature(eii)] + +extern crate decl_with_default; + +fn main() { + decl_with_default::decl1(10); +} diff --git a/tests/ui/eii/default/call_default.run.stdout b/tests/ui/eii/default/call_default.run.stdout new file mode 100644 index 000000000000..1e49486f6aaf --- /dev/null +++ b/tests/ui/eii/default/call_default.run.stdout @@ -0,0 +1 @@ +default 10 diff --git a/tests/ui/eii/default/call_impl.rs b/tests/ui/eii/default/call_impl.rs new file mode 100644 index 000000000000..b81e604238ec --- /dev/null +++ b/tests/ui/eii/default/call_impl.rs @@ -0,0 +1,16 @@ +//@ no-prefer-dynamic +//@ aux-build: decl_with_default.rs +//@ aux-build: impl1.rs +//@ run-pass +//@ check-run-results +// Tests EIIs with default implementations. +// When an explicit implementation is given in one dependency, and the declaration is in another, +// the explicit implementation is preferred. +#![feature(eii)] + +extern crate decl_with_default; +extern crate impl1; + +fn main() { + decl_with_default::decl1(10); +} diff --git a/tests/ui/eii/default/call_impl.run.stdout b/tests/ui/eii/default/call_impl.run.stdout new file mode 100644 index 000000000000..bc6298e80ad4 --- /dev/null +++ b/tests/ui/eii/default/call_impl.run.stdout @@ -0,0 +1 @@ +110 diff --git a/tests/ui/eii/default/local_crate.rs b/tests/ui/eii/default/local_crate.rs new file mode 100644 index 000000000000..9ae471d90cbc --- /dev/null +++ b/tests/ui/eii/default/local_crate.rs @@ -0,0 +1,14 @@ +//@ run-pass +//@ check-run-results +// Tests EIIs with default implementations. +// In the same crate, when there's no explicit declaration, the default should be called. +#![feature(eii)] + +#[eii(eii1)] +pub fn decl1(x: u64) { + println!("default {x}"); +} + +fn main() { + decl1(4); +} diff --git a/tests/ui/eii/default/local_crate.run.stdout b/tests/ui/eii/default/local_crate.run.stdout new file mode 100644 index 000000000000..032082d92b72 --- /dev/null +++ b/tests/ui/eii/default/local_crate.run.stdout @@ -0,0 +1 @@ +default 4 diff --git a/tests/ui/eii/default/local_crate_explicit.rs b/tests/ui/eii/default/local_crate_explicit.rs new file mode 100644 index 000000000000..844d1d2911af --- /dev/null +++ b/tests/ui/eii/default/local_crate_explicit.rs @@ -0,0 +1,20 @@ +//@ run-pass +//@ check-run-results +// Tests EIIs with default implementations. +// In the same crate, the explicit implementation should get priority. +#![feature(eii)] + +#[eii(eii1)] +pub fn decl1(x: u64) { + //~^ WARN function `decl1` is never used + println!("default {x}"); +} + +#[eii1] +pub fn decl2(x: u64) { + println!("explicit {x}"); +} + +fn main() { + decl1(4); +} diff --git a/tests/ui/eii/default/local_crate_explicit.run.stdout b/tests/ui/eii/default/local_crate_explicit.run.stdout new file mode 100644 index 000000000000..d7ce3a9fb8ba --- /dev/null +++ b/tests/ui/eii/default/local_crate_explicit.run.stdout @@ -0,0 +1 @@ +explicit 4 diff --git a/tests/ui/eii/default/local_crate_explicit.stderr b/tests/ui/eii/default/local_crate_explicit.stderr new file mode 100644 index 000000000000..4102b35bcb5e --- /dev/null +++ b/tests/ui/eii/default/local_crate_explicit.stderr @@ -0,0 +1,10 @@ +warning: function `decl1` is never used + --> $DIR/local_crate_explicit.rs:9:8 + | +LL | pub fn decl1(x: u64) { + | ^^^^^ + | + = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/eii/duplicate/auxiliary/decl.rs b/tests/ui/eii/duplicate/auxiliary/decl.rs new file mode 100644 index 000000000000..81557fa6891b --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/decl.rs @@ -0,0 +1,6 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(eii)] + +#[eii(eii1)] +fn decl1(x: u64); diff --git a/tests/ui/eii/duplicate/auxiliary/impl1.rs b/tests/ui/eii/duplicate/auxiliary/impl1.rs new file mode 100644 index 000000000000..d7c27f4dfde9 --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/impl1.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl.rs +#![crate_type = "rlib"] +#![feature(eii)] + +extern crate decl; + + +#[unsafe(decl::eii1)] +fn other(x: u64) { + println!("1{x}"); +} diff --git a/tests/ui/eii/duplicate/auxiliary/impl2.rs b/tests/ui/eii/duplicate/auxiliary/impl2.rs new file mode 100644 index 000000000000..bce6f11b89c4 --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/impl2.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl.rs +#![crate_type = "rlib"] +#![feature(eii)] + +extern crate decl; + + +#[unsafe(decl::eii1)] +fn other(x: u64) { + println!("2{x}"); +} diff --git a/tests/ui/eii/duplicate/auxiliary/impl3.rs b/tests/ui/eii/duplicate/auxiliary/impl3.rs new file mode 100644 index 000000000000..82ba5af09863 --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/impl3.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl.rs +#![crate_type = "rlib"] +#![feature(eii)] + +extern crate decl; + + +#[unsafe(decl::eii1)] +fn other(x: u64) { + println!("3{x}"); +} diff --git a/tests/ui/eii/duplicate/auxiliary/impl4.rs b/tests/ui/eii/duplicate/auxiliary/impl4.rs new file mode 100644 index 000000000000..5275da1b1433 --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/impl4.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl.rs +#![crate_type = "rlib"] +#![feature(eii)] + +extern crate decl; + + +#[unsafe(decl::eii1)] +fn other(x: u64) { + println!("4{x}"); +} diff --git a/tests/ui/eii/duplicate/duplicate1.rs b/tests/ui/eii/duplicate/duplicate1.rs new file mode 100644 index 000000000000..921270fe3d48 --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate1.rs @@ -0,0 +1,13 @@ +//@ no-prefer-dynamic +//@ aux-build: impl1.rs +//@ aux-build: impl2.rs +// tests that EIIs error properly, even if the conflicting implementations live in another crate. +#![feature(eii)] + +// has a span but in the other crate +//~? ERROR multiple implementations of `#[eii1]` + +extern crate impl1; +extern crate impl2; + +fn main() {} diff --git a/tests/ui/eii/duplicate/duplicate1.stderr b/tests/ui/eii/duplicate/duplicate1.stderr new file mode 100644 index 000000000000..54cc141f8869 --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate1.stderr @@ -0,0 +1,15 @@ +error: multiple implementations of `#[eii1]` + --> $DIR/auxiliary/impl1.rs:10:1 + | +LL | fn other(x: u64) { + | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` + | + ::: $DIR/auxiliary/impl2.rs:10:1 + | +LL | fn other(x: u64) { + | ---------------- also implemented here in crate `impl2` + | + = help: an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/duplicate/duplicate2.rs b/tests/ui/eii/duplicate/duplicate2.rs new file mode 100644 index 000000000000..8355b8f7bc70 --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate2.rs @@ -0,0 +1,15 @@ +//@ no-prefer-dynamic +//@ aux-build: impl1.rs +//@ aux-build: impl2.rs +//@ aux-build: impl3.rs +// Tests the error message when there are multiple implementations of an EII in many crates. +#![feature(eii)] + +// has a span but in the other crate +//~? ERROR multiple implementations of `#[eii1]` + +extern crate impl1; +extern crate impl2; +extern crate impl3; + +fn main() {} diff --git a/tests/ui/eii/duplicate/duplicate2.stderr b/tests/ui/eii/duplicate/duplicate2.stderr new file mode 100644 index 000000000000..033e43c8b2fb --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate2.stderr @@ -0,0 +1,16 @@ +error: multiple implementations of `#[eii1]` + --> $DIR/auxiliary/impl1.rs:10:1 + | +LL | fn other(x: u64) { + | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` + | + ::: $DIR/auxiliary/impl2.rs:10:1 + | +LL | fn other(x: u64) { + | ---------------- also implemented here in crate `impl2` + | + = note: in addition to these two, another implementation was found in crate `impl3` + = help: an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/duplicate/duplicate3.rs b/tests/ui/eii/duplicate/duplicate3.rs new file mode 100644 index 000000000000..b967fb8b4903 --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate3.rs @@ -0,0 +1,17 @@ +//@ no-prefer-dynamic +//@ aux-build: impl1.rs +//@ aux-build: impl2.rs +//@ aux-build: impl3.rs +//@ aux-build: impl4.rs +// Tests the error message when there are multiple implementations of an EII in many crates. +#![feature(eii)] + +// has a span but in the other crate +//~? ERROR multiple implementations of `#[eii1]` + +extern crate impl1; +extern crate impl2; +extern crate impl3; +extern crate impl4; + +fn main() {} diff --git a/tests/ui/eii/duplicate/duplicate3.stderr b/tests/ui/eii/duplicate/duplicate3.stderr new file mode 100644 index 000000000000..801d40e69c55 --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate3.stderr @@ -0,0 +1,16 @@ +error: multiple implementations of `#[eii1]` + --> $DIR/auxiliary/impl1.rs:10:1 + | +LL | fn other(x: u64) { + | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` + | + ::: $DIR/auxiliary/impl2.rs:10:1 + | +LL | fn other(x: u64) { + | ---------------- also implemented here in crate `impl2` + | + = note: in addition to these two, more implementations were also found in the following crates: `impl3`, `impl4` + = help: an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/errors.rs b/tests/ui/eii/errors.rs new file mode 100644 index 000000000000..920ed1a529d5 --- /dev/null +++ b/tests/ui/eii/errors.rs @@ -0,0 +1,45 @@ +//@ compile-flags: --crate-type rlib +// Tests all the kinds of errors when EII attributes are used with wrong syntax. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar)] //~ ERROR `#[eii_macro_for(...)]` is only valid on macros +fn hello() { + #[eii_macro_for(bar)] //~ ERROR `#[eii_macro_for(...)]` is only valid on macros + let x = 3 + 3; +} + +#[eii_macro_for] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements +#[eii_macro_for()] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements +#[eii_macro_for(bar, hello)] //~ ERROR expected this argument to be "unsafe" +#[eii_macro_for(bar, "unsafe", hello)] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements +#[eii_macro_for(bar, hello, "unsafe")] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements +#[eii_macro_for = "unsafe"] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements +#[eii_macro_for(bar)] +#[rustc_builtin_macro(eii_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] //~ ERROR `#[foo]` is only valid on functions +static X: u64 = 4; +#[foo] //~ ERROR `#[foo]` is only valid on functions +const Y: u64 = 4; +#[foo] //~ ERROR `#[foo]` is only valid on functions +macro bar() {} + +#[foo()] +//~^ ERROR `#[foo]` expected no arguments or a single argument: `#[foo(default)]` +#[foo(default, bar)] +//~^ ERROR `#[foo]` expected no arguments or a single argument: `#[foo(default)]` +#[foo("default")] +//~^ ERROR `#[foo]` expected no arguments or a single argument: `#[foo(default)]` +#[foo = "default"] +//~^ ERROR `#[foo]` expected no arguments or a single argument: `#[foo(default)]` +fn other(x: u64) -> u64 { + x +} diff --git a/tests/ui/eii/errors.stderr b/tests/ui/eii/errors.stderr new file mode 100644 index 000000000000..d02c862ce8fa --- /dev/null +++ b/tests/ui/eii/errors.stderr @@ -0,0 +1,98 @@ +error: `#[eii_extern_target(...)]` is only valid on macros + --> $DIR/errors.rs:8:1 + | +LL | #[eii_macro_for(bar)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: `#[eii_extern_target(...)]` is only valid on macros + --> $DIR/errors.rs:10:5 + | +LL | #[eii_macro_for(bar)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: `#[eii_macro_for(...)]` expects a list of one or two elements + --> $DIR/errors.rs:14:1 + | +LL | #[eii_macro_for] + | ^^^^^^^^^^^^^^^^ + +error: `#[eii_extern_target(...)]` expects a list of one or two elements + --> $DIR/errors.rs:15:1 + | +LL | #[eii_macro_for()] + | ^^^^^^^^^^^^^^^^^^ + +error: expected this argument to be "unsafe" + --> $DIR/errors.rs:15:22 + | +LL | #[eii_macro_for(bar, hello)] + | ^^^^^ + | +note: the second argument is optional + --> $DIR/errors.rs:15:22 + | +LL | #[eii_macro_for(bar, hello)] + | ^^^^^ + +error: `#[eii_macro_for(...)]` expects a list of one or two elements + --> $DIR/errors.rs:17:1 + | +LL | #[eii_macro_for(bar, "unsafe", hello)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[eii_macro_for(...)]` expects a list of one or two elements + --> $DIR/errors.rs:18:1 + | +LL | #[eii_macro_for(bar, hello, "unsafe")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[eii_extern_target(...)]` expects a list of one or two elements + --> $DIR/errors.rs:19:1 + | +LL | #[eii_macro_for = "unsafe"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/errors.rs:28:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/errors.rs:30:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/errors.rs:32:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]` + --> $DIR/errors.rs:35:1 + | +LL | #[foo()] + | ^^^^^^^^ + +error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]` + --> $DIR/errors.rs:37:1 + | +LL | #[foo(default, bar)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]` + --> $DIR/errors.rs:39:1 + | +LL | #[foo("default")] + | ^^^^^^^^^^^^^^^^^ + +error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]` + --> $DIR/errors.rs:41:1 + | +LL | #[foo = "default"] + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 15 previous errors + diff --git a/tests/ui/eii/privacy1.rs b/tests/ui/eii/privacy1.rs new file mode 100644 index 000000000000..7dd87a5b7ce4 --- /dev/null +++ b/tests/ui/eii/privacy1.rs @@ -0,0 +1,31 @@ +//@ run-pass +//@ check-run-results +//@ aux-build: codegen1.rs +// Tests whether re-exports work. +#![feature(eii)] + +extern crate codegen1 as codegen; + +#[codegen::eii1] +fn eii1_impl(x: u64) { + println!("{x:?}") +} + + +#[codegen::eii3] +fn eii3_impl(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + // directly + eii1_impl(21); + // through the alias + codegen::local_call_decl1(42); + + // directly + eii3_impl(12); + // through the alias + codegen::decl3(24); +} diff --git a/tests/ui/eii/privacy1.run.stdout b/tests/ui/eii/privacy1.run.stdout new file mode 100644 index 000000000000..c76239918563 --- /dev/null +++ b/tests/ui/eii/privacy1.run.stdout @@ -0,0 +1,4 @@ +21 +42 +12 +24 diff --git a/tests/ui/eii/privacy2.rs b/tests/ui/eii/privacy2.rs new file mode 100644 index 000000000000..702773fb5c78 --- /dev/null +++ b/tests/ui/eii/privacy2.rs @@ -0,0 +1,27 @@ +//@ aux-build:codegen3.rs +// Tests whether name resulution respects privacy properly. +#![feature(eii)] + +extern crate codegen3 as codegen; + +// has a span but in the other crate +//~? ERROR `#[eii2]` required, but not found +//~? ERROR `#[eii3]` required, but not found + +#[codegen::eii1] +fn eii1_impl(x: u64) { + println!("{x:?}") +} + +#[codegen::eii3] //~ ERROR failed to resolve: could not find `eii3` in `codegen` +fn eii3_impl(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + // directly + eii1_impl(21); + // through the alias + codegen::decl1(42); //~ ERROR function `decl1` is private +} diff --git a/tests/ui/eii/privacy2.stderr b/tests/ui/eii/privacy2.stderr new file mode 100644 index 000000000000..0d44604567e4 --- /dev/null +++ b/tests/ui/eii/privacy2.stderr @@ -0,0 +1,38 @@ +error[E0433]: failed to resolve: could not find `eii3` in `codegen` + --> $DIR/privacy2.rs:16:12 + | +LL | #[codegen::eii3] + | ^^^^ could not find `eii3` in `codegen` + +error[E0603]: function `decl1` is private + --> $DIR/privacy2.rs:26:14 + | +LL | codegen::decl1(42); + | ^^^^^ private function + | +note: the function `decl1` is defined here + --> $DIR/auxiliary/codegen3.rs:7:1 + | +LL | fn decl1(x: u64); + | ^^^^^^^^^^^^^^^^^ + +error: `#[eii2]` required, but not found + --> $DIR/auxiliary/codegen3.rs:9:1 + | +LL | #[eii(eii2)] + | ^^^^^^^^^^^^ expected because `#[eii2]` was declared here in crate `codegen3` + | + = help: expected at least one implementation in crate `privacy2` or any of its dependencies + +error: `#[eii3]` required, but not found + --> $DIR/auxiliary/codegen3.rs:13:5 + | +LL | #[eii(eii3)] + | ^^^^^^^^^^^^ expected because `#[eii3]` was declared here in crate `codegen3` + | + = help: expected at least one implementation in crate `privacy2` or any of its dependencies + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0433, E0603. +For more information about an error, try `rustc --explain E0433`. diff --git a/tests/ui/eii/subtype_1.rs b/tests/ui/eii/subtype_1.rs new file mode 100644 index 000000000000..d19d586d1868 --- /dev/null +++ b/tests/ui/eii/subtype_1.rs @@ -0,0 +1,27 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: +// Tests whether it's not ok when the lifetimes are different between the decl and impl. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar)] +#[rustc_builtin_macro(eii_macro)] +macro foo() { + +} + +unsafe extern "Rust" { + safe fn bar<'a, 'b>(x: &'b u64) -> &'a u64; +} + +#[foo] +fn other<'a, 'b>(x: &'b u64) -> &'b u64 { +//~^ ERROR lifetime parameters or bounds of `other` do not match the declaration + &0 +} + +fn main() { + bar(&0); +} diff --git a/tests/ui/eii/subtype_1.stderr b/tests/ui/eii/subtype_1.stderr new file mode 100644 index 000000000000..6a4ef6e16f9d --- /dev/null +++ b/tests/ui/eii/subtype_1.stderr @@ -0,0 +1,13 @@ +error: lifetime parameters or bounds of `other` do not match the declaration + --> $DIR/subtype_1.rs:18:9 + | +LL | safe fn bar<'a, 'b>(x: &'b u64) -> &'a u64; + | -------- lifetimes in impl do not match this signature +... +LL | #[foo] + | ------ required because of this attribute +LL | fn other<'a, 'b>(x: &'b u64) -> &'b u64 { + | ^^^^^^^^ lifetimes do not match + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/subtype_2.rs b/tests/ui/eii/subtype_2.rs new file mode 100644 index 000000000000..d518143ef99b --- /dev/null +++ b/tests/ui/eii/subtype_2.rs @@ -0,0 +1,27 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: +// Tests whether it's not ok when the implementation is less general. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar)] +#[rustc_builtin_macro(eii_macro)] +macro foo() { + +} + +unsafe extern "Rust" { + safe fn bar<'a>(x: &'static u64) -> &'a u64; +} + +#[foo] +fn other<'a>(x: &'a u64) -> &'static u64 { +//~^ ERROR lifetime parameters or bounds of `other` do not match the declaration + &0 +} + +fn main() { + bar(&0); +} diff --git a/tests/ui/eii/subtype_2.stderr b/tests/ui/eii/subtype_2.stderr new file mode 100644 index 000000000000..5c925ca380e0 --- /dev/null +++ b/tests/ui/eii/subtype_2.stderr @@ -0,0 +1,13 @@ +error: lifetime parameters or bounds of `other` do not match the declaration + --> $DIR/subtype_2.rs:18:9 + | +LL | safe fn bar<'a>(x: &'static u64) -> &'a u64; + | ---- lifetimes in impl do not match this signature +... +LL | #[foo] + | ------ required because of this attribute +LL | fn other<'a>(x: &'a u64) -> &'static u64 { + | ^^^^ lifetimes do not match + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/subtype_3.rs b/tests/ui/eii/subtype_3.rs new file mode 100644 index 000000000000..5d73e63781d0 --- /dev/null +++ b/tests/ui/eii/subtype_3.rs @@ -0,0 +1,27 @@ +//@ compile-flags: --crate-type rlib +//@ check-pass +// Uses manual desugaring of EII internals: +// Tests whether it's ok when the implementation is more general. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar)] +#[rustc_builtin_macro(eii_macro)] +macro foo() { + +} + +unsafe extern "Rust" { + safe fn bar<'a>(x: &'a u64) -> &'a u64; +} + +#[foo] +fn other<'a>(x: &'a u64) -> &'static u64 { + &0 +} + +fn main() { + bar(&0); +} diff --git a/tests/ui/eii/subtype_4.rs b/tests/ui/eii/subtype_4.rs new file mode 100644 index 000000000000..7207a6d73b6a --- /dev/null +++ b/tests/ui/eii/subtype_4.rs @@ -0,0 +1,27 @@ +//@ compile-flags: --crate-type rlib +//@ check-pass +// Uses manual desugaring of EII internals: +// Tests whether it's ok when giving the right types. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar)] +#[rustc_builtin_macro(eii_macro)] +macro foo() { + +} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] +fn other(x: u64) -> u64 { + x +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/unsafe_impl_err.rs b/tests/ui/eii/unsafe_impl_err.rs new file mode 100644 index 000000000000..347bd67f838d --- /dev/null +++ b/tests/ui/eii/unsafe_impl_err.rs @@ -0,0 +1,25 @@ +//@ compile-flags: --crate-type rlib +// Tests whether it's an error to implement an unsafe EII safely. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar, "unsafe")] +#[rustc_builtin_macro(eii_macro)] +macro foo() { + +} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] //~ ERROR `#[foo]` is unsafe to implement +fn other(x: u64) -> u64 { + x +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/unsafe_impl_err.stderr b/tests/ui/eii/unsafe_impl_err.stderr new file mode 100644 index 000000000000..6badcbe17f16 --- /dev/null +++ b/tests/ui/eii/unsafe_impl_err.stderr @@ -0,0 +1,13 @@ +error: `#[foo]` is unsafe to implement + --> $DIR/unsafe_impl_err.rs:17:1 + | +LL | #[foo] + | ^^^^^^ + | +help: wrap the attribute in `unsafe(...)` + | +LL | #[unsafe(foo)] + | +++++++ + + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/unsafe_impl_ok.rs b/tests/ui/eii/unsafe_impl_ok.rs new file mode 100644 index 000000000000..4281ce2feea7 --- /dev/null +++ b/tests/ui/eii/unsafe_impl_ok.rs @@ -0,0 +1,27 @@ +//@ compile-flags: --crate-type rlib +//@ check-pass +// Uses manual desugaring of EII internals: +// Tests whether it's okay to implement an unsafe EII with an unsafe implementation. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar, "unsafe")] +#[rustc_builtin_macro(eii_macro)] +macro foo() { + +} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[unsafe(foo)] +fn other(x: u64) -> u64 { + x +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/wrong_ret_ty.rs b/tests/ui/eii/wrong_ret_ty.rs new file mode 100644 index 000000000000..a9d4c475a70a --- /dev/null +++ b/tests/ui/eii/wrong_ret_ty.rs @@ -0,0 +1,26 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: tests whether the return type matches. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar)] +#[rustc_builtin_macro(eii_macro)] +macro foo() { + +} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] +fn other(_x: u64) { +//~^ ERROR function `other` has a type that is incompatible with the declaration + +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/wrong_ret_ty.stderr b/tests/ui/eii/wrong_ret_ty.stderr new file mode 100644 index 000000000000..2cdd69bbdbdf --- /dev/null +++ b/tests/ui/eii/wrong_ret_ty.stderr @@ -0,0 +1,26 @@ +error[E0053]: function `other` has a type that is incompatible with the declaration of `#[foo]` + --> $DIR/wrong_ret_ty.rs:18:18 + | +LL | fn other(_x: u64) { + | ^ expected `u64`, found `()` + | +note: expected this because of this attribute + --> $DIR/wrong_ret_ty.rs:17:1 + | +LL | #[foo] + | ^^^^^^ +note: type in declaration + --> $DIR/wrong_ret_ty.rs:14:28 + | +LL | safe fn bar(x: u64) -> u64; + | ^^^ + = note: expected signature `fn(_) -> u64` + found signature `fn(_) -> ()` +help: change the output type to match the declaration + | +LL | fn other(_x: u64) -> u64 { + | ++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/eii/wrong_target.rs b/tests/ui/eii/wrong_target.rs new file mode 100644 index 000000000000..2a7fc4420943 --- /dev/null +++ b/tests/ui/eii/wrong_target.rs @@ -0,0 +1,63 @@ +#![feature(eii)] +// Check whether the EII attributes do target checking properly. + +#[eii] +fn foo() {} + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +const A: usize = 3; + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +macro_rules! foo_impl { + () => {}; +} + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +struct Foo; + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +impl Foo { + #[foo] + //~^ ERROR `#[foo]` is only valid on functions + #[eii] + //~^ ERROR `#[eii]` is only valid on functions + fn foo_impl() {} +} + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +trait Bar { + #[foo] + //~^ ERROR `#[foo]` is only valid on functions + #[eii] + //~^ ERROR `#[eii]` is only valid on functions + fn foo_impl(); +} + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +impl Bar for Foo { + #[foo] + //~^ ERROR `#[foo]` is only valid on functions + #[eii] + //~^ ERROR `#[eii]` is only valid on functions + fn foo_impl() {} +} + +fn main() {} diff --git a/tests/ui/eii/wrong_target.stderr b/tests/ui/eii/wrong_target.stderr new file mode 100644 index 000000000000..9b27f49fb302 --- /dev/null +++ b/tests/ui/eii/wrong_target.stderr @@ -0,0 +1,110 @@ +error: `#[foo]` is only valid on functions + --> $DIR/wrong_target.rs:7:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/wrong_target.rs:9:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/wrong_target.rs:13:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/wrong_target.rs:15:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/wrong_target.rs:21:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/wrong_target.rs:23:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/wrong_target.rs:27:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/wrong_target.rs:29:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/wrong_target.rs:32:5 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/wrong_target.rs:34:5 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/wrong_target.rs:39:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/wrong_target.rs:41:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/wrong_target.rs:44:5 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/wrong_target.rs:46:5 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/wrong_target.rs:51:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/wrong_target.rs:53:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/wrong_target.rs:56:5 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/wrong_target.rs:58:5 + | +LL | #[eii] + | ^^^^^^ + +error: aborting due to 18 previous errors + diff --git a/tests/ui/eii/wrong_ty.rs b/tests/ui/eii/wrong_ty.rs new file mode 100644 index 000000000000..45f95c4380d6 --- /dev/null +++ b/tests/ui/eii/wrong_ty.rs @@ -0,0 +1,26 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: tests whether the types of parameters match. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar)] +#[rustc_builtin_macro(eii_macro)] +macro foo() { + +} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] +fn other(x: usize) -> u64 { +//~^ ERROR function `other` has a type that is incompatible with the declaration + 3 +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/wrong_ty.stderr b/tests/ui/eii/wrong_ty.stderr new file mode 100644 index 000000000000..fae713a35aa9 --- /dev/null +++ b/tests/ui/eii/wrong_ty.stderr @@ -0,0 +1,27 @@ +error[E0053]: function `other` has a type that is incompatible with the declaration of `#[foo]` + --> $DIR/wrong_ty.rs:18:13 + | +LL | fn other(x: usize) -> u64 { + | ^^^^^ expected `u64`, found `usize` + | +note: expected this because of this attribute + --> $DIR/wrong_ty.rs:17:1 + | +LL | #[foo] + | ^^^^^^ +note: type in declaration + --> $DIR/wrong_ty.rs:14:20 + | +LL | safe fn bar(x: u64) -> u64; + | ^^^ + = note: expected signature `fn(u64) -> _` + found signature `fn(usize) -> _` +help: change the parameter type to match the declaration + | +LL - fn other(x: usize) -> u64 { +LL + fn other(x: u64) -> u64 { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/eii/wrong_ty_2.rs b/tests/ui/eii/wrong_ty_2.rs new file mode 100644 index 000000000000..a3d6d7e72774 --- /dev/null +++ b/tests/ui/eii/wrong_ty_2.rs @@ -0,0 +1,26 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: tests whether the number of parameters matches. +#![feature(eii)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_macro_for(bar)] +#[rustc_builtin_macro(eii_macro)] +macro foo() { + +} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] +fn other() -> u64 { +//~^ ERROR `other` has 0 parameters but #[foo] requires it to have + 3 +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/wrong_ty_2.stderr b/tests/ui/eii/wrong_ty_2.stderr new file mode 100644 index 000000000000..2ed00f9e55ee --- /dev/null +++ b/tests/ui/eii/wrong_ty_2.stderr @@ -0,0 +1,14 @@ +error[E0050]: `other` has 0 parameters but #[foo] requires it to have 1 + --> $DIR/wrong_ty_2.rs:18:1 + | +LL | safe fn bar(x: u64) -> u64; + | --- requires 1 parameter +... +LL | #[foo] + | ------ required because of this attribute +LL | fn other() -> u64 { + | ^^^^^^^^^^^^^^^^^ expected 1 parameter, found 0 + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0050`. From be9844363902f95a8868aa5b9a35aa7be3c64e8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 25 Aug 2025 13:43:55 +0200 Subject: [PATCH 0647/3801] TEMP: fixes error codes in non-codegen tests. those work after the type checking --- .../auxiliary/cross_crate_eii_declaration.rs | 6 +-- tests/ui/eii/cross_crate_wrong_ty.stderr | 6 +-- tests/ui/eii/errors.rs | 14 +++---- tests/ui/eii/errors.stderr | 40 +++++++++---------- tests/ui/eii/unsafe_impl_err.stderr | 2 +- tests/ui/eii/wrong_ret_ty.stderr | 10 ++--- tests/ui/eii/wrong_ty.stderr | 10 ++--- tests/ui/eii/wrong_ty_2.stderr | 6 +-- 8 files changed, 46 insertions(+), 48 deletions(-) diff --git a/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs b/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs index 36a42ad199b0..bda5c95f512d 100644 --- a/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs +++ b/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs @@ -5,11 +5,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar)] +#[eii_extern_target(bar)] #[rustc_builtin_macro(eii_macro)] -pub macro foo() { - -} +pub macro foo() {} unsafe extern "Rust" { pub safe fn bar(x: u64) -> u64; diff --git a/tests/ui/eii/cross_crate_wrong_ty.stderr b/tests/ui/eii/cross_crate_wrong_ty.stderr index c85974f78206..b2190a075b63 100644 --- a/tests/ui/eii/cross_crate_wrong_ty.stderr +++ b/tests/ui/eii/cross_crate_wrong_ty.stderr @@ -1,4 +1,4 @@ -error[E0050]: `other` has 0 parameters but #[foo] requires it to have 1 +error[E0806]: `other` has 0 parameters but #[foo] requires it to have 1 --> $DIR/cross_crate_wrong_ty.rs:12:1 | LL | #[unsafe(cross_crate_eii_declaration::foo)] @@ -6,11 +6,11 @@ LL | #[unsafe(cross_crate_eii_declaration::foo)] LL | fn other() -> u64 { | ^^^^^^^^^^^^^^^^^ expected 1 parameter, found 0 | - ::: $DIR/auxiliary/cross_crate_eii_declaration.rs:15:5 + ::: $DIR/auxiliary/cross_crate_eii_declaration.rs:13:5 | LL | pub safe fn bar(x: u64) -> u64; | ------------------------------- requires 1 parameter error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0050`. +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/eii/errors.rs b/tests/ui/eii/errors.rs index 920ed1a529d5..587c4e02ce72 100644 --- a/tests/ui/eii/errors.rs +++ b/tests/ui/eii/errors.rs @@ -11,13 +11,13 @@ fn hello() { let x = 3 + 3; } -#[eii_macro_for] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements -#[eii_macro_for()] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements -#[eii_macro_for(bar, hello)] //~ ERROR expected this argument to be "unsafe" -#[eii_macro_for(bar, "unsafe", hello)] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements -#[eii_macro_for(bar, hello, "unsafe")] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements -#[eii_macro_for = "unsafe"] //~ ERROR `#[eii_macro_for(...)]` expects a list of one or two elements -#[eii_macro_for(bar)] +#[eii_extern_target] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements +#[eii_extern_target()] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements +#[eii_extern_target(bar, hello)] //~ ERROR expected this argument to be "unsafe" +#[eii_extern_target(bar, "unsafe", hello)] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements +#[eii_extern_target(bar, hello, "unsafe")] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements +#[eii_extern_target = "unsafe"] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements +#[eii_extern_target(bar)] #[rustc_builtin_macro(eii_macro)] macro foo() {} diff --git a/tests/ui/eii/errors.stderr b/tests/ui/eii/errors.stderr index d02c862ce8fa..c8bdce559722 100644 --- a/tests/ui/eii/errors.stderr +++ b/tests/ui/eii/errors.stderr @@ -1,56 +1,56 @@ error: `#[eii_extern_target(...)]` is only valid on macros --> $DIR/errors.rs:8:1 | -LL | #[eii_macro_for(bar)] - | ^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_extern_target(bar)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[eii_extern_target(...)]` is only valid on macros --> $DIR/errors.rs:10:5 | -LL | #[eii_macro_for(bar)] - | ^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_extern_target(bar)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[eii_macro_for(...)]` expects a list of one or two elements --> $DIR/errors.rs:14:1 | -LL | #[eii_macro_for] - | ^^^^^^^^^^^^^^^^ +LL | #[eii_extern_target] + | ^^^^^^^^^^^^^^^^^^^^ error: `#[eii_extern_target(...)]` expects a list of one or two elements --> $DIR/errors.rs:15:1 | -LL | #[eii_macro_for()] - | ^^^^^^^^^^^^^^^^^^ +LL | #[eii_extern_target()] + | ^^^^^^^^^^^^^^^^^^^^^^ error: expected this argument to be "unsafe" - --> $DIR/errors.rs:15:22 + --> $DIR/errors.rs:16:26 | -LL | #[eii_macro_for(bar, hello)] - | ^^^^^ +LL | #[eii_extern_target(bar, hello)] + | ^^^^^ | note: the second argument is optional - --> $DIR/errors.rs:15:22 + --> $DIR/errors.rs:16:26 | -LL | #[eii_macro_for(bar, hello)] - | ^^^^^ +LL | #[eii_extern_target(bar, hello)] + | ^^^^^ error: `#[eii_macro_for(...)]` expects a list of one or two elements --> $DIR/errors.rs:17:1 | -LL | #[eii_macro_for(bar, "unsafe", hello)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_extern_target(bar, "unsafe", hello)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[eii_macro_for(...)]` expects a list of one or two elements --> $DIR/errors.rs:18:1 | -LL | #[eii_macro_for(bar, hello, "unsafe")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_extern_target(bar, hello, "unsafe")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[eii_extern_target(...)]` expects a list of one or two elements --> $DIR/errors.rs:19:1 | -LL | #[eii_macro_for = "unsafe"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[eii_extern_target = "unsafe"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[foo]` is only valid on functions --> $DIR/errors.rs:28:1 diff --git a/tests/ui/eii/unsafe_impl_err.stderr b/tests/ui/eii/unsafe_impl_err.stderr index 6badcbe17f16..eb917a65bb52 100644 --- a/tests/ui/eii/unsafe_impl_err.stderr +++ b/tests/ui/eii/unsafe_impl_err.stderr @@ -1,5 +1,5 @@ error: `#[foo]` is unsafe to implement - --> $DIR/unsafe_impl_err.rs:17:1 + --> $DIR/unsafe_impl_err.rs:16:1 | LL | #[foo] | ^^^^^^ diff --git a/tests/ui/eii/wrong_ret_ty.stderr b/tests/ui/eii/wrong_ret_ty.stderr index 2cdd69bbdbdf..0f7e9580aa37 100644 --- a/tests/ui/eii/wrong_ret_ty.stderr +++ b/tests/ui/eii/wrong_ret_ty.stderr @@ -1,16 +1,16 @@ -error[E0053]: function `other` has a type that is incompatible with the declaration of `#[foo]` - --> $DIR/wrong_ret_ty.rs:18:18 +error[E0806]: function `other` has a type that is incompatible with the declaration of `#[foo]` + --> $DIR/wrong_ret_ty.rs:17:18 | LL | fn other(_x: u64) { | ^ expected `u64`, found `()` | note: expected this because of this attribute - --> $DIR/wrong_ret_ty.rs:17:1 + --> $DIR/wrong_ret_ty.rs:16:1 | LL | #[foo] | ^^^^^^ note: type in declaration - --> $DIR/wrong_ret_ty.rs:14:28 + --> $DIR/wrong_ret_ty.rs:13:28 | LL | safe fn bar(x: u64) -> u64; | ^^^ @@ -23,4 +23,4 @@ LL | fn other(_x: u64) -> u64 { error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0053`. +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/eii/wrong_ty.stderr b/tests/ui/eii/wrong_ty.stderr index fae713a35aa9..0513cec97fae 100644 --- a/tests/ui/eii/wrong_ty.stderr +++ b/tests/ui/eii/wrong_ty.stderr @@ -1,16 +1,16 @@ -error[E0053]: function `other` has a type that is incompatible with the declaration of `#[foo]` - --> $DIR/wrong_ty.rs:18:13 +error[E0806]: function `other` has a type that is incompatible with the declaration of `#[foo]` + --> $DIR/wrong_ty.rs:17:13 | LL | fn other(x: usize) -> u64 { | ^^^^^ expected `u64`, found `usize` | note: expected this because of this attribute - --> $DIR/wrong_ty.rs:17:1 + --> $DIR/wrong_ty.rs:16:1 | LL | #[foo] | ^^^^^^ note: type in declaration - --> $DIR/wrong_ty.rs:14:20 + --> $DIR/wrong_ty.rs:13:20 | LL | safe fn bar(x: u64) -> u64; | ^^^ @@ -24,4 +24,4 @@ LL + fn other(x: u64) -> u64 { error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0053`. +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/eii/wrong_ty_2.stderr b/tests/ui/eii/wrong_ty_2.stderr index 2ed00f9e55ee..327d28e41370 100644 --- a/tests/ui/eii/wrong_ty_2.stderr +++ b/tests/ui/eii/wrong_ty_2.stderr @@ -1,5 +1,5 @@ -error[E0050]: `other` has 0 parameters but #[foo] requires it to have 1 - --> $DIR/wrong_ty_2.rs:18:1 +error[E0806]: `other` has 0 parameters but #[foo] requires it to have 1 + --> $DIR/wrong_ty_2.rs:17:1 | LL | safe fn bar(x: u64) -> u64; | --- requires 1 parameter @@ -11,4 +11,4 @@ LL | fn other() -> u64 { error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0050`. +For more information about this error, try `rustc --explain E0806`. From 615acd8b4d7b854588ba5a4c4132bd39a78e0a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 27 Oct 2025 14:54:54 +0100 Subject: [PATCH 0648/3801] add tests for using a single impl for two EIIs --- tests/ui/eii/multiple_decls.rs | 17 +++++++++++++++++ tests/ui/eii/multiple_decls.stderr | 14 ++++++++++++++ tests/ui/eii/multiple_impls.rs | 23 +++++++++++++++++++++++ tests/ui/eii/multiple_impls.run.stdout | 2 ++ 4 files changed, 56 insertions(+) create mode 100644 tests/ui/eii/multiple_decls.rs create mode 100644 tests/ui/eii/multiple_decls.stderr create mode 100644 tests/ui/eii/multiple_impls.rs create mode 100644 tests/ui/eii/multiple_impls.run.stdout diff --git a/tests/ui/eii/multiple_decls.rs b/tests/ui/eii/multiple_decls.rs new file mode 100644 index 000000000000..63ef269d7818 --- /dev/null +++ b/tests/ui/eii/multiple_decls.rs @@ -0,0 +1,17 @@ +// Tests whether only one EII attribute cane be applied to a signature. +#![feature(eii)] + +#[eii(a)] +#[eii(b)] +//~^ ERROR `#[eii]` can only be specified once +fn a(x: u64); + +#[a] +fn implementation(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + a(42); +} diff --git a/tests/ui/eii/multiple_decls.stderr b/tests/ui/eii/multiple_decls.stderr new file mode 100644 index 000000000000..e9e68ea74629 --- /dev/null +++ b/tests/ui/eii/multiple_decls.stderr @@ -0,0 +1,14 @@ +error: `#[eii]` can only be specified once + --> $DIR/multiple_decls.rs:5:1 + | +LL | #[eii(b)] + | ^^^^^^^^^ + | +note: specified again here + --> $DIR/multiple_decls.rs:4:1 + | +LL | #[eii(a)] + | ^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/multiple_impls.rs b/tests/ui/eii/multiple_impls.rs new file mode 100644 index 000000000000..7f6691791410 --- /dev/null +++ b/tests/ui/eii/multiple_impls.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ check-run-results +//@ ignore-backends: gcc +// Tests whether one function could implement two EIIs. +#![feature(eii)] + +#[eii] +fn a(x: u64); + +#[eii] +fn b(x: u64); + +#[a] +#[b] +fn implementation(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + a(42); + b(42); +} diff --git a/tests/ui/eii/multiple_impls.run.stdout b/tests/ui/eii/multiple_impls.run.stdout new file mode 100644 index 000000000000..daaac9e30302 --- /dev/null +++ b/tests/ui/eii/multiple_impls.run.stdout @@ -0,0 +1,2 @@ +42 +42 From 2de02ac86e02eaf0b5979ecbb0531db68910d0c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 28 Jul 2025 10:40:21 +0200 Subject: [PATCH 0649/3801] EII ast changes --- compiler/rustc_ast/src/ast.rs | 30 ++++++++++++++++++- compiler/rustc_ast/src/visit.rs | 9 ++++-- compiler/rustc_ast_lowering/src/item.rs | 8 +++-- .../rustc_ast_passes/src/ast_validation.rs | 5 ++++ compiler/rustc_ast_pretty/src/pprust/state.rs | 26 ++++++++++++++++ .../rustc_ast_pretty/src/pprust/state/item.rs | 19 ++++++++++-- .../src/alloc_error_handler.rs | 1 + compiler/rustc_builtin_macros/src/autodiff.rs | 1 + .../src/deriving/generic/mod.rs | 1 + .../src/global_allocator.rs | 1 + .../rustc_builtin_macros/src/test_harness.rs | 1 + compiler/rustc_metadata/src/rmeta/decoder.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 11 +++++-- .../clippy/clippy_utils/src/ast_utils/mod.rs | 6 ++++ 14 files changed, 110 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index e348cc1ab281..ae0ecaccea22 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2109,6 +2109,19 @@ pub struct MacroDef { pub body: Box, /// `true` if macro was defined with `macro_rules`. pub macro_rules: bool, + + /// If this is a macro used for externally implementable items, + /// it refers to an extern item which is its "target". This requires + /// name resolution so can't just be an attribute, so we store it in this field. + pub eii_extern_target: Option, +} + +#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)] +pub struct EiiExternTarget { + /// path to the extern item we're targetting + pub extern_item_path: Path, + pub impl_unsafe: bool, + pub span: Span, } #[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)] @@ -3748,6 +3761,21 @@ pub struct Fn { pub contract: Option>, pub define_opaque: Option>, pub body: Option>, + + /// This function is an implementation of an externally implementable item (EII). + /// This means, there was an EII declared somewhere and this function is the + /// implementation that should be run when the declaration is called. + pub eii_impls: ThinVec, +} + +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub struct EiiImpl { + pub node_id: NodeId, + pub eii_macro_path: Path, + pub impl_safety: Safety, + pub span: Span, + pub inner_span: Span, + pub is_default: bool, } #[derive(Clone, Encodable, Decodable, Debug, Walkable)] @@ -4114,7 +4142,7 @@ mod size_asserts { static_assert_size!(Block, 32); static_assert_size!(Expr, 72); static_assert_size!(ExprKind, 40); - static_assert_size!(Fn, 184); + static_assert_size!(Fn, 192); static_assert_size!(ForeignItem, 80); static_assert_size!(ForeignItemKind, 16); static_assert_size!(GenericArg, 24); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 7a0424d39575..c7156da84dec 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -393,6 +393,7 @@ macro_rules! common_visitor_and_walkers { ThinVec, ThinVec>, ThinVec, + ThinVec, ); // This macro generates `impl Visitable` and `impl MutVisitable` that forward to `Walkable` @@ -485,6 +486,8 @@ macro_rules! common_visitor_and_walkers { WhereEqPredicate, WhereRegionPredicate, YieldKind, + EiiExternTarget, + EiiImpl, ); /// Each method of this trait is a hook to be potentially @@ -919,13 +922,13 @@ macro_rules! common_visitor_and_walkers { _ctxt, // Visibility is visited as a part of the item. _vis, - Fn { defaultness, ident, sig, generics, contract, body, define_opaque }, + Fn { defaultness, ident, sig, generics, contract, body, define_opaque, eii_impls }, ) => { let FnSig { header, decl, span } = sig; visit_visitable!($($mut)? vis, defaultness, ident, header, generics, decl, - contract, body, span, define_opaque - ) + contract, body, span, define_opaque, eii_impls + ); } FnKind::Closure(binder, coroutine_kind, decl, body) => visit_visitable!($($mut)? vis, binder, coroutine_kind, decl, body), diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index f5b7065247a0..1db6a31e305d 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -435,7 +435,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::ItemKind::TraitAlias(constness, ident, generics, bounds) } - ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => { + ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_extern_target: _ }) => { let ident = self.lower_ident(*ident); let body = Box::new(self.lower_delim_args(body)); let def_id = self.local_def_id(id); @@ -446,7 +446,11 @@ impl<'hir> LoweringContext<'_, 'hir> { def_kind.descr(def_id.to_def_id()) ); }; - let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules }); + let macro_def = self.arena.alloc(ast::MacroDef { + body, + macro_rules: *macro_rules, + eii_extern_target: None, + }); hir::ItemKind::Macro(ident, macro_def, macro_kinds) } ItemKind::Delegation(box delegation) => { diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index ddb19f5e7915..0d34ba6c2ca8 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1179,11 +1179,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> { contract: _, body, define_opaque: _, + eii_impls, }, ) => { self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident); self.check_defaultness(item.span, *defaultness); + for EiiImpl { eii_macro_path, .. } in eii_impls { + self.visit_path(eii_macro_path); + } + let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic)); if body.is_none() && !is_intrinsic && !self.is_sdylib_interface { self.dcx().emit_err(errors::FnWithoutBody { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 35e47fed9f7a..1aa08dfd3d5e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -865,6 +865,17 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere sp: Span, print_visibility: impl FnOnce(&mut Self), ) { + if let Some(eii_extern_target) = ¯o_def.eii_extern_target { + self.word("#[eii_extern_target("); + self.print_path(&eii_extern_target.extern_item_path, false, 0); + if eii_extern_target.impl_unsafe { + self.word(","); + self.space(); + self.word("unsafe"); + } + self.word(")]"); + self.hardbreak(); + } let (kw, has_bang) = if macro_def.macro_rules { ("macro_rules", true) } else { @@ -2162,6 +2173,15 @@ impl<'a> State<'a> { fn print_meta_item(&mut self, item: &ast::MetaItem) { let ib = self.ibox(INDENT_UNIT); + + match item.unsafety { + ast::Safety::Unsafe(_) => { + self.word("unsafe"); + self.popen(); + } + ast::Safety::Default | ast::Safety::Safe(_) => {} + } + match &item.kind { ast::MetaItemKind::Word => self.print_path(&item.path, false, 0), ast::MetaItemKind::NameValue(value) => { @@ -2177,6 +2197,12 @@ impl<'a> State<'a> { self.pclose(); } } + + match item.unsafety { + ast::Safety::Unsafe(_) => self.pclose(), + ast::Safety::Default | ast::Safety::Safe(_) => {} + } + self.end(ib); } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index c7cbf34dedb9..3233d8c2c251 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -1,6 +1,6 @@ use ast::StaticItem; use itertools::{Itertools, Position}; -use rustc_ast::{self as ast, ModKind, TraitAlias}; +use rustc_ast::{self as ast, EiiImpl, ModKind, Safety, TraitAlias}; use rustc_span::Ident; use crate::pp::BoxMarker; @@ -671,10 +671,25 @@ impl<'a> State<'a> { } fn print_fn_full(&mut self, vis: &ast::Visibility, attrs: &[ast::Attribute], func: &ast::Fn) { - let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque } = func; + let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque, eii_impls } = + func; self.print_define_opaques(define_opaque.as_deref()); + for EiiImpl { eii_macro_path, impl_safety, .. } in eii_impls { + self.word("#["); + if let Safety::Unsafe(..) = impl_safety { + self.word("unsafe"); + self.popen(); + } + self.print_path(eii_macro_path, false, 0); + if let Safety::Unsafe(..) = impl_safety { + self.pclose(); + } + self.word("]"); + self.hardbreak(); + } + let body_cb_ib = body.as_ref().map(|body| (body, self.head(""))); self.print_visibility(vis); diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index e5d9d2080c08..12ccc4a6de04 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -90,6 +90,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span contract: None, body, define_opaque: None, + eii_impls: ThinVec::new(), })); let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index ddc59bfe1414..7839a75636b6 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -346,6 +346,7 @@ mod llvm_enzyme { contract: None, body: Some(d_body), define_opaque: None, + eii_impls: ThinVec::new(), }); let mut rustc_ad_attr = Box::new(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff))); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index baffc525d95a..bb6557802ece 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -1092,6 +1092,7 @@ impl<'a> MethodDef<'a> { contract: None, body: Some(body_block), define_opaque: None, + eii_impls: ThinVec::new(), })), tokens: None, }) diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index e69f0838f22e..bb031dafdcfd 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -84,6 +84,7 @@ impl AllocFnFactory<'_, '_> { contract: None, body, define_opaque: None, + eii_impls: ThinVec::new(), })); let item = self.cx.item(self.span, self.attrs(method), kind); self.cx.stmt_item(self.ty_span, item) diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 2a6ac5754bfa..8d6969b0ca12 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -345,6 +345,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> Box { contract: None, body: Some(main_body), define_opaque: None, + eii_impls: ThinVec::new(), })); let main = Box::new(ast::Item { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 65cbdc675962..76438f046dd5 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1530,7 +1530,7 @@ impl<'a> CrateMetadataRef<'a> { .get((self, tcx), id) .unwrap() .decode((self, tcx)); - ast::MacroDef { macro_rules, body: Box::new(body) } + ast::MacroDef { macro_rules, body: Box::new(body), eii_extern_target: None } } _ => bug!(), } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index abc0ffa87d3d..f9b95ba192d4 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -227,6 +227,7 @@ impl<'a> Parser<'a> { contract, body, define_opaque: None, + eii_impls: ThinVec::new(), })) } else if self.eat_keyword_case(exp!(Extern), case) { if self.eat_keyword_case(exp!(Crate), case) { @@ -2200,7 +2201,10 @@ impl<'a> Parser<'a> { }; self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span)); - Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: false })) + Ok(ItemKind::MacroDef( + ident, + ast::MacroDef { body, macro_rules: false, eii_extern_target: None }, + )) } /// Is this a possibly malformed start of a `macro_rules! foo` item definition? @@ -2247,7 +2251,10 @@ impl<'a> Parser<'a> { self.eat_semi_for_macro_if_needed(&body); self.complain_if_pub_macro(vis, true); - Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: true })) + Ok(ItemKind::MacroDef( + ident, + ast::MacroDef { body, macro_rules: true, eii_extern_target: None }, + )) } /// Item macro invocations or `macro_rules!` definitions need inherited visibility. diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 08663782a1d5..432d7a251a21 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -382,6 +382,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { contract: lc, body: lb, define_opaque: _, + eii_impls: _, }), Fn(box ast::Fn { defaultness: rd, @@ -391,6 +392,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { contract: rc, body: rb, define_opaque: _, + eii_impls: _, }), ) => { eq_defaultness(*ld, *rd) @@ -554,6 +556,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { contract: lc, body: lb, define_opaque: _, + eii_impls: _, }), Fn(box ast::Fn { defaultness: rd, @@ -563,6 +566,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { contract: rc, body: rb, define_opaque: _, + eii_impls: _, }), ) => { eq_defaultness(*ld, *rd) @@ -638,6 +642,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { contract: lc, body: lb, define_opaque: _, + eii_impls: _, }), Fn(box ast::Fn { defaultness: rd, @@ -647,6 +652,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { contract: rc, body: rb, define_opaque: _, + eii_impls: _, }), ) => { eq_defaultness(*ld, *rd) From 92c03a26fd68a87f72f0b89b387ca0548ab7f1f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 28 Jul 2025 12:46:03 +0200 Subject: [PATCH 0650/3801] EII (builtin) macros in std --- compiler/rustc_builtin_macros/messages.ftl | 11 + compiler/rustc_builtin_macros/src/eii.rs | 429 ++++++++++++++++++ compiler/rustc_builtin_macros/src/errors.rs | 48 ++ compiler/rustc_builtin_macros/src/lib.rs | 5 + compiler/rustc_span/src/symbol.rs | 6 + library/core/src/macros/mod.rs | 25 + library/core/src/prelude/v1.rs | 13 + library/std/src/prelude/v1.rs | 6 + .../auxiliary/cross_crate_eii_declaration.rs | 2 +- tests/ui/eii/errors.rs | 6 +- tests/ui/eii/errors.stderr | 6 +- tests/ui/eii/subtype_1.rs | 10 +- tests/ui/eii/subtype_2.rs | 10 +- tests/ui/eii/subtype_3.rs | 8 +- tests/ui/eii/subtype_4.rs | 8 +- tests/ui/eii/unsafe_impl_err.rs | 8 +- tests/ui/eii/unsafe_impl_ok.rs | 8 +- tests/ui/eii/wrong_ret_ty.rs | 11 +- tests/ui/eii/wrong_ty.rs | 10 +- tests/ui/eii/wrong_ty_2.rs | 10 +- 20 files changed, 582 insertions(+), 58 deletions(-) create mode 100644 compiler/rustc_builtin_macros/src/eii.rs diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 86671d0326da..542f34d9d831 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -152,6 +152,17 @@ builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept builtin_macros_duplicate_macro_attribute = duplicated attribute +builtin_macros_eii_extern_target_expected_list = `#[eii_extern_target(...)]` expects a list of one or two elements +builtin_macros_eii_extern_target_expected_macro = `#[eii_extern_target(...)]` is only valid on macros +builtin_macros_eii_extern_target_expected_unsafe = expected this argument to be "unsafe" + .note = the second argument is optional + +builtin_macros_eii_only_once = `#[{$name}]` can only be specified once + .note = specified again here + +builtin_macros_eii_shared_macro_expected_function = `#[{$name}]` is only valid on functions +builtin_macros_eii_shared_macro_expected_max_one_argument = `#[{$name}]` expected no arguments or a single argument: `#[{$name}(default)]` + builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time .cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead .cargo_typo = there is a similar Cargo environment variable: `{$suggested_var}` diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs new file mode 100644 index 000000000000..f1161c644ef5 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -0,0 +1,429 @@ +use rustc_ast::token::{Delimiter, TokenKind}; +use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; +use rustc_ast::{ + DUMMY_NODE_ID, EiiExternTarget, EiiImpl, ItemKind, Stmt, StmtKind, ast, token, tokenstream, +}; +use rustc_ast_pretty::pprust::path_to_string; +use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_span::{Ident, Span, kw, sym}; +use thin_vec::{ThinVec, thin_vec}; + +use crate::errors::{ + EiiExternTargetExpectedList, EiiExternTargetExpectedMacro, EiiExternTargetExpectedUnsafe, + EiiMacroExpectedMaxOneArgument, EiiOnlyOnce, EiiSharedMacroExpectedFunction, +}; + +/// ```rust +/// #[eii] +/// fn panic_handler(); +/// +/// // or: +/// +/// #[eii(panic_handler)] +/// fn panic_handler(); +/// +/// // expansion: +/// +/// extern "Rust" { +/// fn panic_handler(); +/// } +/// +/// #[rustc_builtin_macro(eii_shared_macro)] +/// #[eii_extern_target(panic_handler)] +/// macro panic_handler() {} +/// ``` +pub(crate) fn eii( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + item: Annotatable, +) -> Vec { + eii_(ecx, span, meta_item, item, false) +} + +pub(crate) fn unsafe_eii( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + item: Annotatable, +) -> Vec { + eii_(ecx, span, meta_item, item, true) +} + +fn eii_( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + item: Annotatable, + impl_unsafe: bool, +) -> Vec { + let span = ecx.with_def_site_ctxt(span); + + let (item, stmt) = if let Annotatable::Item(item) = item { + (item, false) + } else if let Annotatable::Stmt(ref stmt) = item + && let StmtKind::Item(ref item) = stmt.kind + { + (item.clone(), true) + } else { + ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { + span, + name: path_to_string(&meta_item.path), + }); + return vec![item]; + }; + + let orig_item = item.clone(); + + let item = *item; + + let ast::Item { attrs, id: _, span: item_span, vis, kind: ItemKind::Fn(mut func), tokens: _ } = + item + else { + ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { + span, + name: path_to_string(&meta_item.path), + }); + return vec![Annotatable::Item(Box::new(item))]; + }; + + // Detect when this is the *second* eii attribute on an item. + let mut new_attrs = ThinVec::new(); + for i in attrs { + if i.has_name(sym::eii) { + ecx.dcx().emit_err(EiiOnlyOnce { + span: i.span, + first_span: span, + name: path_to_string(&meta_item.path), + }); + } else { + new_attrs.push(i); + } + } + let attrs = new_attrs; + + let macro_name = if meta_item.is_word() { + func.ident + } else if let Some([first]) = meta_item.meta_item_list() + && let Some(m) = first.meta_item() + && m.path.segments.len() == 1 + { + m.path.segments[0].ident + } else { + ecx.dcx().emit_err(EiiMacroExpectedMaxOneArgument { + span: meta_item.span, + name: path_to_string(&meta_item.path), + }); + return vec![Annotatable::Item(orig_item)]; + }; + + let mut return_items = Vec::new(); + + if func.body.is_some() { + let mut default_func = func.clone(); + func.body = None; + default_func.eii_impls.push(ast::EiiImpl { + node_id: DUMMY_NODE_ID, + eii_macro_path: ast::Path::from_ident(macro_name), + impl_safety: if impl_unsafe { ast::Safety::Unsafe(span) } else { ast::Safety::Default }, + span, + inner_span: macro_name.span, + is_default: true, // important! + }); + + return_items.push(Box::new(ast::Item { + attrs: ThinVec::new(), + id: ast::DUMMY_NODE_ID, + span, + vis: ast::Visibility { span, kind: ast::VisibilityKind::Inherited, tokens: None }, + kind: ast::ItemKind::Const(Box::new(ast::ConstItem { + ident: Ident { name: kw::Underscore, span }, + defaultness: ast::Defaultness::Final, + generics: ast::Generics::default(), + ty: Box::new(ast::Ty { + id: DUMMY_NODE_ID, + kind: ast::TyKind::Tup(ThinVec::new()), + span, + tokens: None, + }), + rhs: Some(ast::ConstItemRhs::Body(Box::new(ast::Expr { + id: DUMMY_NODE_ID, + kind: ast::ExprKind::Block( + Box::new(ast::Block { + stmts: thin_vec![ast::Stmt { + id: DUMMY_NODE_ID, + kind: ast::StmtKind::Item(Box::new(ast::Item { + attrs: thin_vec![], // FIXME: re-add some original attrs + id: DUMMY_NODE_ID, + span: item_span, + vis: ast::Visibility { + span, + kind: ast::VisibilityKind::Inherited, + tokens: None + }, + kind: ItemKind::Fn(default_func), + tokens: None, + })), + span + }], + id: DUMMY_NODE_ID, + rules: ast::BlockCheckMode::Default, + span, + tokens: None, + }), + None, + ), + span, + attrs: ThinVec::new(), + tokens: None, + }))), + define_opaque: None, + })), + tokens: None, + })) + } + + let decl_span = span.to(func.sig.span); + + let abi = match func.sig.header.ext { + // extern "X" fn => extern "X" {} + ast::Extern::Explicit(lit, _) => Some(lit), + // extern fn => extern {} + ast::Extern::Implicit(_) => None, + // fn => extern "Rust" {} + ast::Extern::None => Some(ast::StrLit { + symbol: sym::Rust, + suffix: None, + symbol_unescaped: sym::Rust, + style: ast::StrStyle::Cooked, + span, + }), + }; + + // ABI has been moved to the extern {} block, so we remove it from the fn item. + func.sig.header.ext = ast::Extern::None; + + // And mark safe functions explicitly as `safe fn`. + if func.sig.header.safety == ast::Safety::Default { + func.sig.header.safety = ast::Safety::Safe(func.sig.span); + } + + // extern "…" { safe fn item(); } + let extern_block = Box::new(ast::Item { + attrs: ast::AttrVec::default(), + id: ast::DUMMY_NODE_ID, + span, + vis: ast::Visibility { span, kind: ast::VisibilityKind::Inherited, tokens: None }, + kind: ast::ItemKind::ForeignMod(ast::ForeignMod { + extern_span: span, + safety: ast::Safety::Unsafe(span), + abi, + items: From::from([Box::new(ast::ForeignItem { + attrs: attrs.clone(), + id: ast::DUMMY_NODE_ID, + span: item_span, + vis, + kind: ast::ForeignItemKind::Fn(func.clone()), + tokens: None, + })]), + }), + tokens: None, + }); + + let mut macro_attrs = attrs.clone(); + macro_attrs.push( + // #[builtin_macro(eii_shared_macro)] + ast::Attribute { + kind: ast::AttrKind::Normal(Box::new(ast::NormalAttr { + item: ast::AttrItem { + unsafety: ast::Safety::Default, + path: ast::Path::from_ident(Ident::new(sym::rustc_builtin_macro, span)), + args: ast::AttrArgs::Delimited(ast::DelimArgs { + dspan: DelimSpan::from_single(span), + delim: Delimiter::Parenthesis, + tokens: TokenStream::new(vec![tokenstream::TokenTree::token_alone( + token::TokenKind::Ident(sym::eii_shared_macro, token::IdentIsRaw::No), + span, + )]), + }), + tokens: None, + }, + tokens: None, + })), + id: ecx.sess.psess.attr_id_generator.mk_attr_id(), + style: ast::AttrStyle::Outer, + span, + }, + ); + + let macro_def = Box::new(ast::Item { + attrs: macro_attrs, + id: ast::DUMMY_NODE_ID, + span, + // pub + vis: ast::Visibility { span, kind: ast::VisibilityKind::Public, tokens: None }, + kind: ast::ItemKind::MacroDef( + // macro macro_name + macro_name, + ast::MacroDef { + // { () => {} } + body: Box::new(ast::DelimArgs { + dspan: DelimSpan::from_single(span), + delim: Delimiter::Brace, + tokens: TokenStream::from_iter([ + TokenTree::Delimited( + DelimSpan::from_single(span), + DelimSpacing::new(Spacing::Alone, Spacing::Alone), + Delimiter::Parenthesis, + TokenStream::default(), + ), + TokenTree::token_alone(TokenKind::FatArrow, span), + TokenTree::Delimited( + DelimSpan::from_single(span), + DelimSpacing::new(Spacing::Alone, Spacing::Alone), + Delimiter::Brace, + TokenStream::default(), + ), + ]), + }), + macro_rules: false, + // #[eii_extern_target(func.ident)] + eii_extern_target: Some(ast::EiiExternTarget { + extern_item_path: ast::Path::from_ident(func.ident), + impl_unsafe, + span: decl_span, + }), + }, + ), + tokens: None, + }); + + return_items.push(extern_block); + return_items.push(macro_def); + + if stmt { + return_items + .into_iter() + .map(|i| { + Annotatable::Stmt(Box::new(Stmt { + id: DUMMY_NODE_ID, + kind: StmtKind::Item(i), + span, + })) + }) + .collect() + } else { + return_items.into_iter().map(|i| Annotatable::Item(i)).collect() + } +} + +pub(crate) fn eii_extern_target( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + mut item: Annotatable, +) -> Vec { + let i = if let Annotatable::Item(ref mut item) = item { + item + } else if let Annotatable::Stmt(ref mut stmt) = item + && let StmtKind::Item(ref mut item) = stmt.kind + { + item + } else { + ecx.dcx().emit_err(EiiExternTargetExpectedMacro { span }); + return vec![item]; + }; + + let ItemKind::MacroDef(_, d) = &mut i.kind else { + ecx.dcx().emit_err(EiiExternTargetExpectedMacro { span }); + return vec![item]; + }; + + let Some(list) = meta_item.meta_item_list() else { + ecx.dcx().emit_err(EiiExternTargetExpectedList { span: meta_item.span }); + return vec![item]; + }; + + if list.len() > 2 { + ecx.dcx().emit_err(EiiExternTargetExpectedList { span: meta_item.span }); + return vec![item]; + } + + let Some(extern_item_path) = list.get(0).and_then(|i| i.meta_item()).map(|i| i.path.clone()) + else { + ecx.dcx().emit_err(EiiExternTargetExpectedList { span: meta_item.span }); + return vec![item]; + }; + + let impl_unsafe = if let Some(i) = list.get(1) { + if i.lit().and_then(|i| i.kind.str()).is_some_and(|i| i == kw::Unsafe) { + true + } else { + ecx.dcx().emit_err(EiiExternTargetExpectedUnsafe { span: i.span() }); + return vec![item]; + } + } else { + false + }; + + d.eii_extern_target = Some(EiiExternTarget { extern_item_path, impl_unsafe, span }); + + // Return the original item and the new methods. + vec![item] +} + +/// all Eiis share this function as the implementation for their attribute. +pub(crate) fn eii_shared_macro( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + mut item: Annotatable, +) -> Vec { + let i = if let Annotatable::Item(ref mut item) = item { + item + } else if let Annotatable::Stmt(ref mut stmt) = item + && let StmtKind::Item(ref mut item) = stmt.kind + { + item + } else { + ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { + span, + name: path_to_string(&meta_item.path), + }); + return vec![item]; + }; + + let ItemKind::Fn(f) = &mut i.kind else { + ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { + span, + name: path_to_string(&meta_item.path), + }); + return vec![item]; + }; + + let is_default = if meta_item.is_word() { + false + } else if let Some([first]) = meta_item.meta_item_list() + && let Some(m) = first.meta_item() + && m.path.segments.len() == 1 + { + m.path.segments[0].ident.name == kw::Default + } else { + ecx.dcx().emit_err(EiiMacroExpectedMaxOneArgument { + span: meta_item.span, + name: path_to_string(&meta_item.path), + }); + return vec![item]; + }; + + f.eii_impls.push(EiiImpl { + node_id: DUMMY_NODE_ID, + eii_macro_path: meta_item.path.clone(), + impl_safety: meta_item.unsafety, + span, + inner_span: meta_item.path.span, + is_default, + }); + + vec![item] +} diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index dd6a5a20cceb..2a4c499349ad 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -1010,3 +1010,51 @@ pub(crate) struct CfgSelectUnreachable { #[label] pub wildcard_span: Span, } + +#[derive(Diagnostic)] +#[diag(builtin_macros_eii_extern_target_expected_macro)] +pub(crate) struct EiiExternTargetExpectedMacro { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_eii_extern_target_expected_list)] +pub(crate) struct EiiExternTargetExpectedList { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_eii_extern_target_expected_unsafe)] +pub(crate) struct EiiExternTargetExpectedUnsafe { + #[primary_span] + #[note] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_eii_shared_macro_expected_function)] +pub(crate) struct EiiSharedMacroExpectedFunction { + #[primary_span] + pub span: Span, + pub name: String, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_eii_only_once)] +pub(crate) struct EiiOnlyOnce { + #[primary_span] + pub span: Span, + #[note] + pub first_span: Span, + pub name: String, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_eii_shared_macro_expected_max_one_argument)] +pub(crate) struct EiiMacroExpectedMaxOneArgument { + #[primary_span] + pub span: Span, + pub name: String, +} diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 221e7c3d553a..89ac8db76063 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -38,6 +38,7 @@ mod define_opaque; mod derive; mod deriving; mod edition_panic; +mod eii; mod env; mod errors; mod format; @@ -117,9 +118,13 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { define_opaque: define_opaque::expand, derive: derive::Expander { is_const: false }, derive_const: derive::Expander { is_const: true }, + eii: eii::eii, + eii_extern_target: eii::eii_extern_target, + eii_shared_macro: eii::eii_shared_macro, global_allocator: global_allocator::expand, test: test::expand_test, test_case: test::expand_test_case, + unsafe_eii: eii::unsafe_eii, // tidy-alphabetical-end } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c9aaba6cce3b..984ecc772d81 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -929,6 +929,11 @@ symbols! { effects, eh_catch_typeinfo, eh_personality, + eii, + eii_extern_target, + eii_impl, + eii_internals, + eii_shared_macro, emit, emit_enum, emit_enum_variant, @@ -2386,6 +2391,7 @@ symbols! { unsafe_block_in_unsafe_fn, unsafe_cell, unsafe_cell_raw_get, + unsafe_eii, unsafe_extern_blocks, unsafe_fields, unsafe_no_drop_flag, diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index f3386985bdf1..68b5b2d1efc6 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1890,4 +1890,29 @@ pub(crate) mod builtin { pub macro From($item: item) { /* compiler built-in */ } + + /// Externally Implementable Item: Defines an attribute macro that can override the item + /// this is applied to. + #[unstable(feature = "eii", issue = "125418")] + #[rustc_builtin_macro] + #[allow_internal_unstable(eii_internals, decl_macro, rustc_attrs)] + pub macro eii($item:item) { + /* compiler built-in */ + } + + /// Unsafely Externally Implementable Item: Defines an unsafe attribute macro that can override + /// the item this is applied to. + #[unstable(feature = "eii", issue = "125418")] + #[rustc_builtin_macro] + #[allow_internal_unstable(eii_internals, decl_macro, rustc_attrs)] + pub macro unsafe_eii($item:item) { + /* compiler built-in */ + } + + /// Impl detail of EII + #[unstable(feature = "eii_internals", issue = "none")] + #[rustc_builtin_macro] + pub macro eii_extern_target($item:item) { + /* compiler built-in */ + } } diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index a4be66b90cab..3446f04a6429 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -117,3 +117,16 @@ pub use crate::macros::builtin::deref; reason = "`type_alias_impl_trait` has open design concerns" )] pub use crate::macros::builtin::define_opaque; + +#[unstable( + feature = "derive_from", + issue = "144889", + reason = "`derive(From)` is unstable" +)] +pub use crate::macros::builtin::From; + +#[unstable(feature = "eii", issue = "125418")] +pub use crate::macros::builtin::{eii, unsafe_eii}; + +#[unstable(feature = "eii_internals", issue = "none")] +pub use crate::macros::builtin::eii_extern_target; diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 70c111315565..6c2f5f108f1a 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -110,6 +110,12 @@ pub use core::prelude::v1::deref; )] pub use core::prelude::v1::define_opaque; +#[unstable(feature = "eii", issue = "125418")] +pub use core::prelude::v1::{eii, unsafe_eii}; + +#[unstable(feature = "eii_internals", issue = "none")] +pub use core::prelude::v1::eii_extern_target; + // The file so far is equivalent to core/src/prelude/v1.rs. It is duplicated // rather than glob imported because we want docs to show these re-exports as // pointing to within `std`. diff --git a/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs b/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs index bda5c95f512d..3147d91bbee8 100644 --- a/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs +++ b/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs @@ -6,7 +6,7 @@ #![feature(eii_internals)] #[eii_extern_target(bar)] -#[rustc_builtin_macro(eii_macro)] +#[rustc_builtin_macro(eii_shared_macro)] pub macro foo() {} unsafe extern "Rust" { diff --git a/tests/ui/eii/errors.rs b/tests/ui/eii/errors.rs index 587c4e02ce72..ec365b0e9d16 100644 --- a/tests/ui/eii/errors.rs +++ b/tests/ui/eii/errors.rs @@ -5,9 +5,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar)] //~ ERROR `#[eii_macro_for(...)]` is only valid on macros +#[eii_extern_target(bar)] //~ ERROR `#[eii_extern_target(...)]` is only valid on macros fn hello() { - #[eii_macro_for(bar)] //~ ERROR `#[eii_macro_for(...)]` is only valid on macros + #[eii_extern_target(bar)] //~ ERROR `#[eii_extern_target(...)]` is only valid on macros let x = 3 + 3; } @@ -18,7 +18,7 @@ fn hello() { #[eii_extern_target(bar, hello, "unsafe")] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements #[eii_extern_target = "unsafe"] //~ ERROR `#[eii_extern_target(...)]` expects a list of one or two elements #[eii_extern_target(bar)] -#[rustc_builtin_macro(eii_macro)] +#[rustc_builtin_macro(eii_shared_macro)] macro foo() {} unsafe extern "Rust" { diff --git a/tests/ui/eii/errors.stderr b/tests/ui/eii/errors.stderr index c8bdce559722..c3b51421f295 100644 --- a/tests/ui/eii/errors.stderr +++ b/tests/ui/eii/errors.stderr @@ -10,7 +10,7 @@ error: `#[eii_extern_target(...)]` is only valid on macros LL | #[eii_extern_target(bar)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `#[eii_macro_for(...)]` expects a list of one or two elements +error: `#[eii_extern_target(...)]` expects a list of one or two elements --> $DIR/errors.rs:14:1 | LL | #[eii_extern_target] @@ -34,13 +34,13 @@ note: the second argument is optional LL | #[eii_extern_target(bar, hello)] | ^^^^^ -error: `#[eii_macro_for(...)]` expects a list of one or two elements +error: `#[eii_extern_target(...)]` expects a list of one or two elements --> $DIR/errors.rs:17:1 | LL | #[eii_extern_target(bar, "unsafe", hello)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `#[eii_macro_for(...)]` expects a list of one or two elements +error: `#[eii_extern_target(...)]` expects a list of one or two elements --> $DIR/errors.rs:18:1 | LL | #[eii_extern_target(bar, hello, "unsafe")] diff --git a/tests/ui/eii/subtype_1.rs b/tests/ui/eii/subtype_1.rs index d19d586d1868..8c58a5d7fac2 100644 --- a/tests/ui/eii/subtype_1.rs +++ b/tests/ui/eii/subtype_1.rs @@ -6,11 +6,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar)] -#[rustc_builtin_macro(eii_macro)] -macro foo() { - -} +#[eii_extern_target(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} unsafe extern "Rust" { safe fn bar<'a, 'b>(x: &'b u64) -> &'a u64; @@ -18,7 +16,7 @@ unsafe extern "Rust" { #[foo] fn other<'a, 'b>(x: &'b u64) -> &'b u64 { -//~^ ERROR lifetime parameters or bounds of `other` do not match the declaration + //~^ ERROR lifetime parameters or bounds of `other` do not match the declaration &0 } diff --git a/tests/ui/eii/subtype_2.rs b/tests/ui/eii/subtype_2.rs index d518143ef99b..0453286a19c5 100644 --- a/tests/ui/eii/subtype_2.rs +++ b/tests/ui/eii/subtype_2.rs @@ -6,11 +6,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar)] -#[rustc_builtin_macro(eii_macro)] -macro foo() { - -} +#[eii_extern_target(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} unsafe extern "Rust" { safe fn bar<'a>(x: &'static u64) -> &'a u64; @@ -18,7 +16,7 @@ unsafe extern "Rust" { #[foo] fn other<'a>(x: &'a u64) -> &'static u64 { -//~^ ERROR lifetime parameters or bounds of `other` do not match the declaration + //~^ ERROR lifetime parameters or bounds of `other` do not match the declaration &0 } diff --git a/tests/ui/eii/subtype_3.rs b/tests/ui/eii/subtype_3.rs index 5d73e63781d0..39d232e27c5b 100644 --- a/tests/ui/eii/subtype_3.rs +++ b/tests/ui/eii/subtype_3.rs @@ -7,11 +7,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar)] -#[rustc_builtin_macro(eii_macro)] -macro foo() { - -} +#[eii_extern_target(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} unsafe extern "Rust" { safe fn bar<'a>(x: &'a u64) -> &'a u64; diff --git a/tests/ui/eii/subtype_4.rs b/tests/ui/eii/subtype_4.rs index 7207a6d73b6a..c55030238e75 100644 --- a/tests/ui/eii/subtype_4.rs +++ b/tests/ui/eii/subtype_4.rs @@ -7,11 +7,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar)] -#[rustc_builtin_macro(eii_macro)] -macro foo() { - -} +#[eii_extern_target(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} unsafe extern "Rust" { safe fn bar(x: u64) -> u64; diff --git a/tests/ui/eii/unsafe_impl_err.rs b/tests/ui/eii/unsafe_impl_err.rs index 347bd67f838d..cb3eb5a27c63 100644 --- a/tests/ui/eii/unsafe_impl_err.rs +++ b/tests/ui/eii/unsafe_impl_err.rs @@ -5,11 +5,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar, "unsafe")] -#[rustc_builtin_macro(eii_macro)] -macro foo() { - -} +#[eii_extern_target(bar, "unsafe")] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} unsafe extern "Rust" { safe fn bar(x: u64) -> u64; diff --git a/tests/ui/eii/unsafe_impl_ok.rs b/tests/ui/eii/unsafe_impl_ok.rs index 4281ce2feea7..5ffd1ef1321b 100644 --- a/tests/ui/eii/unsafe_impl_ok.rs +++ b/tests/ui/eii/unsafe_impl_ok.rs @@ -7,11 +7,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar, "unsafe")] -#[rustc_builtin_macro(eii_macro)] -macro foo() { - -} +#[eii_extern_target(bar, "unsafe")] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} unsafe extern "Rust" { safe fn bar(x: u64) -> u64; diff --git a/tests/ui/eii/wrong_ret_ty.rs b/tests/ui/eii/wrong_ret_ty.rs index a9d4c475a70a..4a268ca675bc 100644 --- a/tests/ui/eii/wrong_ret_ty.rs +++ b/tests/ui/eii/wrong_ret_ty.rs @@ -5,11 +5,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar)] -#[rustc_builtin_macro(eii_macro)] -macro foo() { - -} +#[eii_extern_target(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} unsafe extern "Rust" { safe fn bar(x: u64) -> u64; @@ -17,8 +15,7 @@ unsafe extern "Rust" { #[foo] fn other(_x: u64) { -//~^ ERROR function `other` has a type that is incompatible with the declaration - + //~^ ERROR function `other` has a type that is incompatible with the declaration } fn main() { diff --git a/tests/ui/eii/wrong_ty.rs b/tests/ui/eii/wrong_ty.rs index 45f95c4380d6..4fb81734c74a 100644 --- a/tests/ui/eii/wrong_ty.rs +++ b/tests/ui/eii/wrong_ty.rs @@ -5,11 +5,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar)] -#[rustc_builtin_macro(eii_macro)] -macro foo() { - -} +#[eii_extern_target(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} unsafe extern "Rust" { safe fn bar(x: u64) -> u64; @@ -17,7 +15,7 @@ unsafe extern "Rust" { #[foo] fn other(x: usize) -> u64 { -//~^ ERROR function `other` has a type that is incompatible with the declaration + //~^ ERROR function `other` has a type that is incompatible with the declaration 3 } diff --git a/tests/ui/eii/wrong_ty_2.rs b/tests/ui/eii/wrong_ty_2.rs index a3d6d7e72774..085b9184caf0 100644 --- a/tests/ui/eii/wrong_ty_2.rs +++ b/tests/ui/eii/wrong_ty_2.rs @@ -5,11 +5,9 @@ #![feature(rustc_attrs)] #![feature(eii_internals)] -#[eii_macro_for(bar)] -#[rustc_builtin_macro(eii_macro)] -macro foo() { - -} +#[eii_extern_target(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} unsafe extern "Rust" { safe fn bar(x: u64) -> u64; @@ -17,7 +15,7 @@ unsafe extern "Rust" { #[foo] fn other() -> u64 { -//~^ ERROR `other` has 0 parameters but #[foo] requires it to have + //~^ ERROR `other` has 0 parameters but #[foo] requires it to have 3 } From 3d38d9fdba183c780d89d5197aaaa66b47927ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 25 Aug 2025 16:50:35 +0200 Subject: [PATCH 0651/3801] EII add feature gate --- compiler/rustc_feature/src/unstable.rs | 4 ++++ compiler/rustc_span/src/symbol.rs | 1 + .../feature-gate-eii-internals.rs | 11 +++++++++++ .../feature-gate-eii-internals.stderr | 18 ++++++++++++++++++ tests/ui/feature-gates/feature-gate-eii.rs | 9 +++++++++ tests/ui/feature-gates/feature-gate-eii.stderr | 13 +++++++++++++ 6 files changed, 56 insertions(+) create mode 100644 tests/ui/feature-gates/feature-gate-eii-internals.rs create mode 100644 tests/ui/feature-gates/feature-gate-eii-internals.stderr create mode 100644 tests/ui/feature-gates/feature-gate-eii.rs create mode 100644 tests/ui/feature-gates/feature-gate-eii.stderr diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index ac01d98b4d1a..1568edd275bb 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -221,6 +221,8 @@ declare_features! ( (internal, compiler_builtins, "1.13.0", None), /// Allows writing custom MIR (internal, custom_mir, "1.65.0", None), + /// Implementation details of externally implementatble items + (internal, eii_internals, "CURRENT_RUSTC_VERSION", None), /// Outputs useful `assert!` messages (unstable, generic_assert, "1.63.0", None), /// Allows using the #[rustc_intrinsic] attribute. @@ -491,6 +493,8 @@ declare_features! ( (unstable, doc_masked, "1.21.0", Some(44027)), /// Allows features to allow target_feature to better interact with traits. (incomplete, effective_target_features, "1.91.0", Some(143352)), + /// Externally implementatble items + (unstable, extern_item_impls, "CURRENT_RUSTC_VERSION", Some(125418)), /// Allows the .use postfix syntax `x.use` and use closures `use |x| { ... }` (incomplete, ergonomic_clones, "1.87.0", Some(132290)), /// Allows exhaustive pattern matching on types that contain uninhabited types. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 984ecc772d81..c609e00b8df7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -933,6 +933,7 @@ symbols! { eii_extern_target, eii_impl, eii_internals, + extern_item_impls, eii_shared_macro, emit, emit_enum, diff --git a/tests/ui/feature-gates/feature-gate-eii-internals.rs b/tests/ui/feature-gates/feature-gate-eii-internals.rs new file mode 100644 index 000000000000..b70e007ed798 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-eii-internals.rs @@ -0,0 +1,11 @@ +#![crate_type = "rlib"] +#![feature(decl_macro)] +#![feature(rustc_attrs)] + +#[eii_extern_target(bar)] //~ ERROR use of unstable library feature `eii_internals` +#[rustc_builtin_macro(eii_macro)] +macro foo() {} //~ ERROR: cannot find a built-in macro with name `foo` + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} diff --git a/tests/ui/feature-gates/feature-gate-eii-internals.stderr b/tests/ui/feature-gates/feature-gate-eii-internals.stderr new file mode 100644 index 000000000000..f08f0a5e65b3 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-eii-internals.stderr @@ -0,0 +1,18 @@ +error[E0658]: use of unstable library feature `eii_internals` + --> $DIR/feature-gate-eii-internals.rs:5:3 + | +LL | #[eii_extern_target(bar)] + | ^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(eii_internals)]` 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: cannot find a built-in macro with name `foo` + --> $DIR/feature-gate-eii-internals.rs:7:1 + | +LL | macro foo() {} + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-eii.rs b/tests/ui/feature-gates/feature-gate-eii.rs new file mode 100644 index 000000000000..3a51c3dd2eae --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-eii.rs @@ -0,0 +1,9 @@ +#![crate_type = "rlib"] + +#[eii] //~ ERROR use of unstable library feature `eii` +fn hello(x: u64); + +#[hello] +fn hello_impl(x: u64) { + println!("{x:?}") +} diff --git a/tests/ui/feature-gates/feature-gate-eii.stderr b/tests/ui/feature-gates/feature-gate-eii.stderr new file mode 100644 index 000000000000..6ec231257ba7 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-eii.stderr @@ -0,0 +1,13 @@ +error[E0658]: use of unstable library feature `eii` + --> $DIR/feature-gate-eii.rs:3:3 + | +LL | #[eii] + | ^^^ + | + = note: see issue #125418 for more information + = help: add `#![feature(eii)]` 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 59d50cd2ad461996d6c9e1c424392235f5e9aca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 21 Aug 2025 15:13:01 +0200 Subject: [PATCH 0652/3801] EII nameres changes --- compiler/rustc_resolve/src/ident.rs | 1 - compiler/rustc_resolve/src/late.rs | 29 +++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index e38d4370d5d2..9253879d2885 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -314,7 +314,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ignore_binding: Option>, diag_metadata: Option<&DiagMetadata<'_>>, ) -> Option> { - assert!(ns == TypeNS || ns == ValueNS); let orig_ident = ident; let (general_span, normalized_span) = if ident.name == kw::SelfUpper { // FIXME(jseyfried) improve `Self` hygiene diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f1a03d5a0610..7a8cd43b0425 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -447,6 +447,8 @@ pub(crate) enum PathSource<'a, 'ast, 'ra> { ReturnTypeNotation, /// Paths from `#[define_opaque]` attributes DefineOpaques, + /// Resolving a macro + Macro, } impl PathSource<'_, '_, '_> { @@ -463,6 +465,7 @@ impl PathSource<'_, '_, '_> { | PathSource::ReturnTypeNotation => ValueNS, PathSource::TraitItem(ns, _) => ns, PathSource::PreciseCapturingArg(ns) => ns, + PathSource::Macro => MacroNS, } } @@ -478,7 +481,8 @@ impl PathSource<'_, '_, '_> { | PathSource::TraitItem(..) | PathSource::DefineOpaques | PathSource::Delegation - | PathSource::PreciseCapturingArg(..) => false, + | PathSource::PreciseCapturingArg(..) + | PathSource::Macro => false, } } @@ -520,6 +524,7 @@ impl PathSource<'_, '_, '_> { }, PathSource::ReturnTypeNotation | PathSource::Delegation => "function", PathSource::PreciseCapturingArg(..) => "type or const parameter", + PathSource::Macro => "macro", } } @@ -614,6 +619,7 @@ impl PathSource<'_, '_, '_> { Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } ), PathSource::PreciseCapturingArg(MacroNS) => false, + PathSource::Macro => matches!(res, Res::Def(DefKind::Macro(_), _)), } } @@ -633,6 +639,7 @@ impl PathSource<'_, '_, '_> { (PathSource::TraitItem(..) | PathSource::ReturnTypeNotation, false) => E0576, (PathSource::PreciseCapturingArg(..), true) => E0799, (PathSource::PreciseCapturingArg(..), false) => E0800, + (PathSource::Macro, _) => E0425, } } } @@ -1058,6 +1065,12 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc }; debug!("(resolving function) entering function"); + if let FnKind::Fn(_, _, f) = fn_kind { + for EiiImpl { node_id, eii_macro_path, .. } in &f.eii_impls { + self.smart_resolve_path(*node_id, &None, &eii_macro_path, PathSource::Macro); + } + } + // Create a value rib for the function. self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| { // Create a label rib for the function. @@ -2130,7 +2143,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { | PathSource::TraitItem(..) | PathSource::Type | PathSource::PreciseCapturingArg(..) - | PathSource::ReturnTypeNotation => false, + | PathSource::ReturnTypeNotation + | PathSource::Macro => false, PathSource::Expr(..) | PathSource::Pat | PathSource::Struct(_) @@ -2887,6 +2901,17 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let def_id = self.r.local_def_id(item.id); self.parent_scope.macro_rules = self.r.macro_rules_scopes[&def_id]; } + + if let Some(EiiExternTarget { extern_item_path, impl_unsafe: _, span: _ }) = + ¯o_def.eii_extern_target + { + self.smart_resolve_path( + item.id, + &None, + extern_item_path, + PathSource::Expr(None), + ); + } } ItemKind::ForeignMod(_) | ItemKind::GlobalAsm(_) => { From 8b69673c41207f2d4eeba0d20762ad9f6ae711ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 28 Jul 2025 10:40:21 +0200 Subject: [PATCH 0653/3801] EII ast changes --- clippy_utils/src/ast_utils/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs index 08663782a1d5..432d7a251a21 100644 --- a/clippy_utils/src/ast_utils/mod.rs +++ b/clippy_utils/src/ast_utils/mod.rs @@ -382,6 +382,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { contract: lc, body: lb, define_opaque: _, + eii_impls: _, }), Fn(box ast::Fn { defaultness: rd, @@ -391,6 +392,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { contract: rc, body: rb, define_opaque: _, + eii_impls: _, }), ) => { eq_defaultness(*ld, *rd) @@ -554,6 +556,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { contract: lc, body: lb, define_opaque: _, + eii_impls: _, }), Fn(box ast::Fn { defaultness: rd, @@ -563,6 +566,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { contract: rc, body: rb, define_opaque: _, + eii_impls: _, }), ) => { eq_defaultness(*ld, *rd) @@ -638,6 +642,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { contract: lc, body: lb, define_opaque: _, + eii_impls: _, }), Fn(box ast::Fn { defaultness: rd, @@ -647,6 +652,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool { contract: rc, body: rb, define_opaque: _, + eii_impls: _, }), ) => { eq_defaultness(*ld, *rd) From 33df6ccb21679fc3bfe479d8a3b7b8301bee4231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 12 Aug 2025 12:26:18 +0200 Subject: [PATCH 0654/3801] EII lowering --- compiler/rustc_ast_lowering/src/item.rs | 97 ++++++++++++++++++- compiler/rustc_ast_lowering/src/lib.rs | 16 ++- .../rustc_hir/src/attrs/data_structures.rs | 23 +++++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 2 + .../rustc_hir/src/attrs/pretty_printing.rs | 2 + compiler/rustc_passes/messages.ftl | 15 +++ compiler/rustc_passes/src/check_attr.rs | 45 ++++++++- compiler/rustc_passes/src/errors.rs | 39 ++++++++ 8 files changed, 232 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 1db6a31e305d..0e0ded0b27a0 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -2,7 +2,7 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err}; -use rustc_hir::attrs::AttributeKind; +use rustc_hir::attrs::{AttributeKind, EiiDecl}; use rustc_hir::def::{DefKind, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::{ @@ -11,6 +11,7 @@ use rustc_hir::{ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; +use rustc_span::def_id::DefId; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; @@ -133,10 +134,92 @@ impl<'hir> LoweringContext<'_, 'hir> { } } + fn generate_extra_attrs_for_item_kind( + &mut self, + id: NodeId, + i: &ItemKind, + ) -> Vec { + match i { + ItemKind::Fn(box Fn { eii_impls, .. }) if eii_impls.is_empty() => Vec::new(), + ItemKind::Fn(box Fn { eii_impls, .. }) => { + vec![hir::Attribute::Parsed(AttributeKind::EiiImpls( + eii_impls + .iter() + .flat_map( + |EiiImpl { + node_id, + eii_macro_path, + impl_safety, + span, + inner_span, + is_default, + }| { + self.lower_path_simple_eii(*node_id, eii_macro_path).map(|did| { + hir::attrs::EiiImpl { + eii_macro: did, + span: self.lower_span(*span), + inner_span: self.lower_span(*inner_span), + impl_marked_unsafe: self + .lower_safety(*impl_safety, hir::Safety::Safe) + .is_unsafe(), + is_default: *is_default, + } + }) + }, + ) + .collect(), + ))] + } + ItemKind::MacroDef( + _, + MacroDef { + eii_extern_target: Some(EiiExternTarget { extern_item_path, impl_unsafe, span }), + .. + }, + ) => self + .lower_path_simple_eii(id, extern_item_path) + .map(|did| { + vec![hir::Attribute::Parsed(AttributeKind::EiiExternTarget(EiiDecl { + eii_extern_target: did, + impl_unsafe: *impl_unsafe, + span: self.lower_span(*span), + }))] + }) + .unwrap_or_default(), + ItemKind::ExternCrate(..) + | ItemKind::Use(..) + | ItemKind::Static(..) + | ItemKind::Const(..) + | ItemKind::Mod(..) + | ItemKind::ForeignMod(..) + | ItemKind::GlobalAsm(..) + | ItemKind::TyAlias(..) + | ItemKind::Enum(..) + | ItemKind::Struct(..) + | ItemKind::Union(..) + | ItemKind::Trait(..) + | ItemKind::TraitAlias(..) + | ItemKind::Impl(..) + | ItemKind::MacCall(..) + | ItemKind::MacroDef(..) + | ItemKind::Delegation(..) + | ItemKind::DelegationMac(..) => Vec::new(), + } + } + fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> { let vis_span = self.lower_span(i.vis.span); let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); - let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_ast_item(i)); + + let extra_hir_attributes = self.generate_extra_attrs_for_item_kind(i.id, &i.kind); + let attrs = self.lower_attrs_with_extra( + hir_id, + &i.attrs, + i.span, + Target::from_ast_item(i), + &extra_hir_attributes, + ); + let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind); let item = hir::Item { owner_id: hir_id.expect_owner(), @@ -469,6 +552,16 @@ impl<'hir> LoweringContext<'_, 'hir> { } } + fn lower_path_simple_eii(&mut self, id: NodeId, path: &Path) -> Option { + let res = self.resolver.get_partial_res(id)?; + let Some(did) = res.expect_full_res().opt_def_id() else { + self.dcx().span_delayed_bug(path.span, "should have errored in resolve"); + return None; + }; + + Some(did) + } + #[instrument(level = "debug", skip(self))] fn lower_use_tree( &mut self, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c20bbcca44f7..a84e795af1be 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -971,11 +971,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { target_span: Span, target: Target, ) -> &'hir [hir::Attribute] { - if attrs.is_empty() { + self.lower_attrs_with_extra(id, attrs, target_span, target, &[]) + } + + fn lower_attrs_with_extra( + &mut self, + id: HirId, + attrs: &[Attribute], + target_span: Span, + target: Target, + extra_hir_attributes: &[hir::Attribute], + ) -> &'hir [hir::Attribute] { + if attrs.is_empty() && extra_hir_attributes.is_empty() { &[] } else { - let lowered_attrs = + let mut lowered_attrs = self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target); + lowered_attrs.extend(extra_hir_attributes.iter().cloned()); assert_eq!(id.owner, self.current_hir_id_owner); let ret = self.arena.alloc_from_iter(lowered_attrs); diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index b7f8be3ec88f..28433f261220 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -19,6 +19,23 @@ use crate::attrs::pretty_printing::PrintAttribute; use crate::limit::Limit; use crate::{DefaultBodyStability, PartialConstStability, RustcVersion, Stability}; +#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub struct EiiImpl { + pub eii_macro: DefId, + pub impl_marked_unsafe: bool, + pub span: Span, + pub inner_span: Span, + pub is_default: bool, +} + +#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub struct EiiDecl { + pub eii_extern_target: DefId, + /// whether or not it is unsafe to implement this EII + pub impl_unsafe: bool, + pub span: Span, +} + #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)] pub enum InlineAttr { None, @@ -692,6 +709,12 @@ pub enum AttributeKind { /// Represents `#[rustc_dummy]`. Dummy, + /// Implementation detail of `#[eii]` + EiiExternTarget(EiiDecl), + + /// Implementation detail of `#[eii]` + EiiImpls(ThinVec), + /// Represents [`#[export_name]`](https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute). ExportName { /// The name to export this item with. diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index ad120648c1ee..e42d511da695 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -43,6 +43,8 @@ impl AttributeKind { Doc(_) => Yes, DocComment { .. } => Yes, Dummy => No, + EiiExternTarget(_) => Yes, + EiiImpls(..) => No, ExportName { .. } => Yes, ExportStable => No, FfiConst(..) => No, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index 29df586ed296..0ad486cef43d 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -5,6 +5,7 @@ use rustc_ast::token::{CommentKind, DocFragmentKind}; use rustc_ast::{AttrStyle, IntTy, UintTy}; use rustc_ast_pretty::pp::Printer; use rustc_data_structures::fx::FxIndexMap; +use rustc_span::def_id::DefId; use rustc_span::hygiene::Transparency; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; use rustc_target::spec::SanitizerSet; @@ -170,4 +171,5 @@ print_debug!( DocFragmentKind, Transparency, SanitizerSet, + DefId, ); diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 4e8973e4928b..43c3b3fb3619 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -590,3 +590,18 @@ passes_useless_stability = this stability annotation is useless .label = useless stability annotation .item = the stability attribute annotates this item + +passes_eii_fn_with_target_feature = + `#[{$name}]` is not allowed to have `#[target_feature]` + .label = `#[{$name}]` is not allowed to have `#[target_feature]` + +passes_eii_fn_with_track_caller = + `#[{$name}]` is not allowed to have `#[track_caller]` + .label = `#[{$name}]` is not allowed to have `#[track_caller]` + +passes_eii_impl_not_function = + `eii_macro_for` is only valid on functions + +passes_eii_impl_requires_unsafe = + `#[{$name}]` is unsafe to implement +passes_eii_impl_requires_unsafe_suggestion = wrap the attribute in `unsafe(...)` diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 030839baad9b..d5d2d64ffaf7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -19,8 +19,8 @@ use rustc_feature::{ BuiltinAttribute, }; use rustc_hir::attrs::{ - AttributeKind, DocAttribute, DocInline, InlineAttr, MirDialect, MirPhase, ReprAttr, - SanitizerSet, + AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, InlineAttr, MirDialect, MirPhase, + ReprAttr, SanitizerSet, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalModDefId; @@ -212,8 +212,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_macro_export(hir_id, *span, target) }, Attribute::Parsed(AttributeKind::Doc(attr)) => self.check_doc_attrs(attr, hir_id, target), + Attribute::Parsed(AttributeKind::EiiImpls(impls)) => { + self.check_eii_impl(impls, target) + }, Attribute::Parsed( - AttributeKind::BodyStability { .. } + AttributeKind::EiiExternTarget { .. } + | AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect | AttributeKind::MacroTransparency(_) | AttributeKind::Pointee(..) @@ -459,6 +463,30 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ); } + fn check_eii_impl(&self, impls: &[EiiImpl], target: Target) { + for EiiImpl { span, inner_span, eii_macro, impl_marked_unsafe, is_default: _ } in impls { + match target { + Target::Fn => {} + _ => { + self.dcx().emit_err(errors::EiiImplNotFunction { span: *span }); + } + } + + if find_attr!(self.tcx.get_all_attrs(*eii_macro), AttributeKind::EiiExternTarget(EiiDecl { impl_unsafe, .. }) if *impl_unsafe) + && !impl_marked_unsafe + { + self.dcx().emit_err(errors::EiiImplRequiresUnsafe { + span: *span, + name: self.tcx.item_name(*eii_macro), + suggestion: errors::EiiImplRequiresUnsafeSuggestion { + left: inner_span.shrink_to_lo(), + right: inner_span.shrink_to_hi(), + }, + }); + } + } + } + /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl and that it has no /// arguments. fn check_do_not_recommend( @@ -684,6 +712,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { sig_span: sig.span, }); } + + if let Some(impls) = find_attr!(attrs, AttributeKind::EiiImpls(impls) => impls) { + let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap(); + for i in impls { + self.dcx().emit_err(errors::EiiWithTrackCaller { + attr_span, + name: self.tcx.item_name(i.eii_macro), + sig_span: sig.span, + }); + } + } } _ => {} } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 3a2908d14184..c8db9efe4773 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1305,3 +1305,42 @@ pub(crate) struct CustomMirIncompatibleDialectAndPhase { #[label] pub phase_span: Span, } + +#[derive(Diagnostic)] +#[diag(passes_eii_impl_not_function)] +pub(crate) struct EiiImplNotFunction { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(passes_eii_impl_requires_unsafe)] +pub(crate) struct EiiImplRequiresUnsafe { + #[primary_span] + pub span: Span, + pub name: Symbol, + #[subdiagnostic] + pub suggestion: EiiImplRequiresUnsafeSuggestion, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + passes_eii_impl_requires_unsafe_suggestion, + applicability = "machine-applicable" +)] +pub(crate) struct EiiImplRequiresUnsafeSuggestion { + #[suggestion_part(code = "unsafe(")] + pub left: Span, + #[suggestion_part(code = ")")] + pub right: Span, +} + +#[derive(Diagnostic)] +#[diag(passes_eii_fn_with_track_caller)] +pub(crate) struct EiiWithTrackCaller { + #[primary_span] + pub attr_span: Span, + pub name: Symbol, + #[label] + pub sig_span: Span, +} From 1cbdaf246bd4d785bab19666e02f9fd4352771a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 12 Aug 2025 14:39:53 +0200 Subject: [PATCH 0655/3801] EII collection queries EII collection queries --- compiler/rustc_interface/src/passes.rs | 3 + compiler/rustc_metadata/src/eii.rs | 48 ++++++ compiler/rustc_metadata/src/lib.rs | 1 + compiler/rustc_metadata/src/rmeta/decoder.rs | 8 + .../src/rmeta/decoder/cstore_impl.rs | 16 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 14 ++ compiler/rustc_metadata/src/rmeta/mod.rs | 2 + .../rustc_metadata/src/rmeta/parameterized.rs | 2 + compiler/rustc_middle/src/query/erase.rs | 2 + compiler/rustc_middle/src/query/mod.rs | 13 +- compiler/rustc_passes/messages.ftl | 42 +++-- compiler/rustc_passes/src/eii.rs | 158 ++++++++++++++++++ compiler/rustc_passes/src/errors.rs | 38 +++++ compiler/rustc_passes/src/lib.rs | 2 + 14 files changed, 332 insertions(+), 17 deletions(-) create mode 100644 compiler/rustc_metadata/src/eii.rs create mode 100644 compiler/rustc_passes/src/eii.rs diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ddfec9f886a6..fe28e5e591e2 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1061,6 +1061,9 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { parallel!( { sess.time("looking_for_entry_point", || tcx.ensure_ok().entry_fn(())); + sess.time("check_externally_implementable_items", || { + tcx.ensure_ok().check_externally_implementable_items(()) + }); sess.time("looking_for_derive_registrar", || { tcx.ensure_ok().proc_macro_decls_static(()) diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs new file mode 100644 index 000000000000..2d99ba516ad4 --- /dev/null +++ b/compiler/rustc_metadata/src/eii.rs @@ -0,0 +1,48 @@ +use rustc_data_structures::fx::FxIndexMap; +use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl}; +use rustc_hir::def_id::DefId; +use rustc_hir::find_attr; +use rustc_middle::query::LocalCrate; +use rustc_middle::ty::TyCtxt; + +// basically the map below but flattened out +pub(crate) type EiiMapEncodedKeyValue = (DefId, (EiiDecl, Vec<(DefId, EiiImpl)>)); + +pub(crate) type EiiMap = FxIndexMap< + DefId, // the defid of the macro that declared the eii + ( + // the corresponding declaration + EiiDecl, + // all the given implementations, indexed by defid. + // We expect there to be only one, but collect them all to give errors if there are more + // (or if there are none) in the final crate we build. + FxIndexMap, + ), +>; + +pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap { + let mut eiis = EiiMap::default(); + + // iterate over all items in the current crate + // FIXME(speed up) + for id in tcx.hir_crate_items(()).definitions() { + for i in + find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiImpls(e) => e).into_iter().flatten() + { + eiis.entry(i.eii_macro) + .or_insert_with(|| { + // find the decl for this one if it wasn't in yet (maybe it's from the local crate? not very useful but not illegal) + (find_attr!(tcx.get_all_attrs(i.eii_macro), AttributeKind::EiiExternTarget(d) => *d).unwrap(), Default::default()) + }).1.insert(id.into(), *i); + } + + // if we find a new declaration, add it to the list without a known implementation + if let Some(decl) = + find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiExternTarget(d) => *d) + { + eiis.entry(id.into()).or_insert((decl, Default::default())); + } + } + + eiis +} diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 114301083883..f31c4938e118 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -16,6 +16,7 @@ pub use rmeta::provide; mod dependency_format; +mod eii; mod foreign_modules; mod native_libs; mod rmeta; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 76438f046dd5..1b9c7b1d8e75 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -39,6 +39,7 @@ use rustc_span::{ use tracing::debug; use crate::creader::CStore; +use crate::eii::EiiMapEncodedKeyValue; use crate::rmeta::table::IsDefault; use crate::rmeta::*; @@ -1487,6 +1488,13 @@ impl<'a> CrateMetadataRef<'a> { ) } + fn get_externally_implementable_items( + self, + tcx: TyCtxt<'_>, + ) -> impl Iterator { + self.root.externally_implementable_items.decode((self, tcx)) + } + fn get_missing_lang_items<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] { tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode((self, tcx))) } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index c48cf36930f4..f441788fdcb6 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -25,7 +25,7 @@ use super::{Decodable, DecodeIterator}; use crate::creader::{CStore, LoadedMacro}; use crate::rmeta::AttrFlags; use crate::rmeta::table::IsDefault; -use crate::{foreign_modules, native_libs}; +use crate::{eii, foreign_modules, native_libs}; trait ProcessQueryValue<'tcx, T> { fn process_decoded(self, _tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> T; @@ -330,9 +330,22 @@ provide! { tcx, def_id, other, cdata, is_private_dep => { cdata.private_dep } is_panic_runtime => { cdata.root.panic_runtime } is_compiler_builtins => { cdata.root.compiler_builtins } + + // FIXME: to be replaced with externally_implementable_items below has_global_allocator => { cdata.root.has_global_allocator } + // FIXME: to be replaced with externally_implementable_items below has_alloc_error_handler => { cdata.root.has_alloc_error_handler } + // FIXME: to be replaced with externally_implementable_items below has_panic_handler => { cdata.root.has_panic_handler } + + externally_implementable_items => { + cdata.get_externally_implementable_items(tcx) + .map(|(decl_did, (decl, impls))| ( + decl_did, + (decl, impls.into_iter().collect()) + )).collect() + } + is_profiler_runtime => { cdata.root.profiler_runtime } required_panic_strategy => { cdata.root.required_panic_strategy } panic_in_drop_strategy => { cdata.root.panic_in_drop_strategy } @@ -430,6 +443,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { }, native_libraries: native_libs::collect, foreign_modules: foreign_modules::collect, + externally_implementable_items: eii::collect, // Returns a map from a sufficiently visible external item (i.e., an // external item that is visible from at least one local module) to a diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 2069c06c3f77..a72e8e514292 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -35,6 +35,7 @@ use rustc_span::{ }; use tracing::{debug, instrument, trace}; +use crate::eii::EiiMapEncodedKeyValue; use crate::errors::{FailCreateFileEncoder, FailWriteFile}; use crate::rmeta::*; @@ -620,6 +621,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // We have already encoded some things. Get their combined size from the current position. stats.push(("preamble", self.position())); + let externally_implementable_items = stat!("externally-implementable-items", || self + .encode_externally_implementable_items()); + let (crate_deps, dylib_dependency_formats) = stat!("dep", || (self.encode_crate_deps(), self.encode_dylib_dependency_formats())); @@ -738,6 +742,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { attrs, sym::default_lib_allocator, ), + externally_implementable_items, proc_macro_data, debugger_visualizers, compiler_builtins: ast::attr::contains_name(attrs, sym::compiler_builtins), @@ -1649,6 +1654,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } + fn encode_externally_implementable_items(&mut self) -> LazyArray { + empty_proc_macro!(self); + let externally_implementable_items = self.tcx.externally_implementable_items(LOCAL_CRATE); + + self.lazy_array(externally_implementable_items.iter().map(|(decl_did, (decl, impls))| { + (*decl_did, (decl.clone(), impls.iter().map(|(impl_did, i)| (*impl_did, *i)).collect())) + })) + } + #[instrument(level = "trace", skip(self))] fn encode_info_for_adt(&mut self, local_def_id: LocalDefId) { let def_id = local_def_id.to_def_id(); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index c5230685bfaf..0de54cf87433 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -44,6 +44,7 @@ use table::TableBuilder; use {rustc_ast as ast, rustc_hir as hir}; use crate::creader::CrateMetadataRef; +use crate::eii::EiiMapEncodedKeyValue; mod decoder; mod def_path_hash_map; @@ -250,6 +251,7 @@ pub(crate) struct CrateRoot { has_alloc_error_handler: bool, has_panic_handler: bool, has_default_lib_allocator: bool, + externally_implementable_items: LazyArray, crate_deps: LazyArray, dylib_dependency_formats: LazyArray>, diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs index d6ccad798112..8a9de07836db 100644 --- a/compiler/rustc_metadata/src/rmeta/parameterized.rs +++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs @@ -87,6 +87,8 @@ trivially_parameterized_over_tcx! { rustc_hir::Safety, rustc_hir::Stability, rustc_hir::attrs::Deprecation, + rustc_hir::attrs::EiiDecl, + rustc_hir::attrs::EiiImpl, rustc_hir::attrs::StrippedCfgItem, rustc_hir::def::DefKind, rustc_hir::def::DocLinkResMap, diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 404330a9a45a..774dd88997f2 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -296,6 +296,8 @@ trivial! { rustc_ast::expand::allocator::AllocatorKind, rustc_hir::DefaultBodyStability, rustc_hir::attrs::Deprecation, + rustc_hir::attrs::EiiDecl, + rustc_hir::attrs::EiiImpl, rustc_data_structures::svh::Svh, rustc_errors::ErrorGuaranteed, rustc_hir::Constness, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 15c84a5b01fb..9b4306f656d6 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -76,7 +76,7 @@ use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::ErrorGuaranteed; -use rustc_hir::attrs::StrippedCfgItem; +use rustc_hir::attrs::{EiiDecl, EiiImpl, StrippedCfgItem}; use rustc_hir::def::{DefKind, DocLinkResMap}; use rustc_hir::def_id::{ CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId, @@ -2753,6 +2753,17 @@ rustc_queries! { desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) } feedable } + + query check_externally_implementable_items(_: ()) { + desc { "check externally implementable items" } + } + + /// Returns a list of all `externally implementable items` crate. + query externally_implementable_items(_: CrateNum) -> &'tcx FxIndexMap)> { + arena_cache + desc { "looking up the externally implementable items of a crate" } + separate_provide_extern + } } rustc_with_all_queries! { define_callbacks! } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 43c3b3fb3619..21191085253b 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -164,6 +164,17 @@ passes_duplicate_diagnostic_item_in_crate = duplicate diagnostic item in crate `{$crate_name}`: `{$name}` .note = the diagnostic item is first defined in crate `{$orig_crate_name}` +passes_duplicate_eii_impls = + multiple implementations of `#[{$name}]` + .first = first implemented here in crate `{$first_crate}` + .second = also implemented here in crate `{$second_crate}` + .note = in addition to these two, { $num_additional_crates -> + [one] another implementation was found in crate {$additional_crate_names} + *[other] more implementations were also found in the following crates: {$additional_crate_names} + } + + .help = an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict + passes_duplicate_feature_err = the feature `{$feature}` has already been enabled @@ -197,6 +208,22 @@ passes_duplicate_lang_item_crate_depends = .first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path} .second_definition_path = second definition in `{$crate_name}` loaded from {$path} +passes_eii_fn_with_track_caller = + `#[{$name}]` is not allowed to have `#[track_caller]` + .label = `#[{$name}]` is not allowed to have `#[track_caller]` + +passes_eii_impl_not_function = + `eii_macro_for` is only valid on functions + +passes_eii_impl_requires_unsafe = + `#[{$name}]` is unsafe to implement +passes_eii_impl_requires_unsafe_suggestion = wrap the attribute in `unsafe(...)` + +passes_eii_without_impl = + `#[{$name}]` required, but not found + .label = expected because `#[{$name}]` was declared here in crate `{$decl_crate_name}` + .help = expected at least one implementation in crate `{$current_crate_name}` or any of its dependencies + passes_enum_variant_same_name = it is impossible to refer to the {$dead_descr} `{$dead_name}` because it is shadowed by this enum variant with the same name @@ -590,18 +617,3 @@ passes_useless_stability = this stability annotation is useless .label = useless stability annotation .item = the stability attribute annotates this item - -passes_eii_fn_with_target_feature = - `#[{$name}]` is not allowed to have `#[target_feature]` - .label = `#[{$name}]` is not allowed to have `#[target_feature]` - -passes_eii_fn_with_track_caller = - `#[{$name}]` is not allowed to have `#[track_caller]` - .label = `#[{$name}]` is not allowed to have `#[track_caller]` - -passes_eii_impl_not_function = - `eii_macro_for` is only valid on functions - -passes_eii_impl_requires_unsafe = - `#[{$name}]` is unsafe to implement -passes_eii_impl_requires_unsafe_suggestion = wrap the attribute in `unsafe(...)` diff --git a/compiler/rustc_passes/src/eii.rs b/compiler/rustc_passes/src/eii.rs new file mode 100644 index 000000000000..691576e6a05f --- /dev/null +++ b/compiler/rustc_passes/src/eii.rs @@ -0,0 +1,158 @@ +//! Checks necessary for externally implementable items: +//! Are all items implemented etc.? + +use std::iter; + +use rustc_data_structures::fx::FxIndexMap; +use rustc_hir::attrs::{EiiDecl, EiiImpl}; +use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use rustc_middle::ty::TyCtxt; +use rustc_session::config::CrateType; + +use crate::errors::{DuplicateEiiImpls, EiiWithoutImpl}; + +#[derive(Clone, Copy, Debug)] +enum CheckingMode { + CheckDuplicates, + CheckExistence, +} + +fn get_checking_mode(tcx: TyCtxt<'_>) -> CheckingMode { + // if any of the crate types is not rlib or dylib, we must check for existence. + if tcx.crate_types().iter().any(|i| !matches!(i, CrateType::Rlib | CrateType::Dylib)) { + CheckingMode::CheckExistence + } else { + CheckingMode::CheckDuplicates + } +} + +/// Checks for a given crate, what EIIs need to be generated in it. +/// This is usually a small subset of all EIIs. +/// +/// EII implementations come in two varieties: explicit and default. +/// This query is called once for every crate, to check whether there aren't any duplicate explicit implementations. +/// A duplicate may be caused by an implementation in the current crate, +/// though it's also entirely possible that the source is two dependencies with an explicit implementation. +/// Those work fine on their own but the combination of the two is a conflict. +/// +/// However, if the current crate is a "root" crate, one that generates a final artifact like a binary, +/// then we check one more thing, namely that every EII actually has an implementation, either default or not. +/// If one EII has no implementation, that's an error at that point. +/// +/// These two behaviors are implemented using `CheckingMode`. +pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): ()) { + let checking_mode = get_checking_mode(tcx); + + #[derive(Debug)] + struct FoundImpl { + imp: EiiImpl, + impl_crate: CrateNum, + } + + #[derive(Debug)] + struct FoundEii { + decl: EiiDecl, + decl_crate: CrateNum, + impls: FxIndexMap, + } + + let mut eiis = FxIndexMap::::default(); + + // collect all the EII declarations, and possibly implementations from all descendent crates + for &cnum in tcx.crates(()).iter().chain(iter::once(&LOCAL_CRATE)) { + // get the eiis for the crate we're currently looking at + let crate_eiis = tcx.externally_implementable_items(cnum); + + // update or insert the corresponding entries + for (did, (decl, impls)) in crate_eiis { + eiis.entry(*did) + .or_insert_with(|| FoundEii { + decl: *decl, + decl_crate: cnum, + impls: Default::default(), + }) + .impls + .extend( + impls + .into_iter() + .map(|(did, i)| (*did, FoundImpl { imp: *i, impl_crate: cnum })), + ); + } + } + + // now we have all eiis! For each of them, choose one we want to actually generate. + for (decl_did, FoundEii { decl, decl_crate, impls }) in eiis { + let mut default_impls = Vec::new(); + let mut explicit_impls = Vec::new(); + + for (impl_did, FoundImpl { imp, impl_crate }) in impls { + if imp.is_default { + default_impls.push((impl_did, impl_crate)); + } else { + explicit_impls.push((impl_did, impl_crate)); + } + } + + // more than one explicit implementation (across all crates) + // is instantly an error. + if explicit_impls.len() > 1 { + tcx.dcx().emit_err(DuplicateEiiImpls { + name: tcx.item_name(decl_did), + first_span: tcx.def_span(explicit_impls[0].0), + first_crate: tcx.crate_name(explicit_impls[0].1), + second_span: tcx.def_span(explicit_impls[1].0), + second_crate: tcx.crate_name(explicit_impls[1].1), + + help: (), + + additional_crates: (explicit_impls.len() > 2).then_some(()), + num_additional_crates: explicit_impls.len() - 2, + additional_crate_names: explicit_impls[2..] + .iter() + .map(|i| format!("`{}`", tcx.crate_name(i.1))) + .collect::>() + .join(", "), + }); + } + + if default_impls.len() > 1 { + panic!("multiple not supported right now"); + } + + let (local_impl, is_default) = + // note, for a single crate we never need to generate both a default and an explicit implementation. + // In that case, generating the explicit implementation is enough! + match (checking_mode, explicit_impls.first(), default_impls.first()) { + // If we find an explicit implementation, it's instantly the chosen implementation. + (_, Some((explicit, _)), _) => (explicit, false), + // if we find a default implementation, we can emit it but the alias should be weak + (_, _, Some((deflt, _))) => (deflt, true), + + // if we find no explicit implementation, + // that's fine if we're only checking for duplicates. + // The existence will be checked somewhere else in a crate downstream. + (CheckingMode::CheckDuplicates, None, _) => continue, + + // We have a target to generate, but no impl to put in it. error! + (CheckingMode::CheckExistence, None, None) => { + tcx.dcx().emit_err(EiiWithoutImpl { + current_crate_name: tcx.crate_name(LOCAL_CRATE), + decl_crate_name: tcx.crate_name(decl_crate), + name: tcx.item_name(decl_did), + span: decl.span, + help: (), + }); + + continue; + } + }; + + // if it's not local, who cares about generating it. + // That's the local crates' responsibility + let Some(chosen_impl) = local_impl.as_local() else { + continue; + }; + + tracing::debug!("generating EII {chosen_impl:?} (default={is_default})"); + } +} diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index c8db9efe4773..7abd2c703aeb 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1344,3 +1344,41 @@ pub(crate) struct EiiWithTrackCaller { #[label] pub sig_span: Span, } + +#[derive(Diagnostic)] +#[diag(passes_eii_without_impl)] +pub(crate) struct EiiWithoutImpl { + #[primary_span] + #[label] + pub span: Span, + pub name: Symbol, + + pub current_crate_name: Symbol, + pub decl_crate_name: Symbol, + #[help] + pub help: (), +} + +#[derive(Diagnostic)] +#[diag(passes_duplicate_eii_impls)] +pub(crate) struct DuplicateEiiImpls { + pub name: Symbol, + + #[primary_span] + #[label(passes_first)] + pub first_span: Span, + pub first_crate: Symbol, + + #[label(passes_second)] + pub second_span: Span, + pub second_crate: Symbol, + + #[note] + pub additional_crates: Option<()>, + + pub num_additional_crates: usize, + pub additional_crate_names: String, + + #[help] + pub help: (), +} diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 149714f943a7..865f2a9c3b8b 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -17,6 +17,7 @@ mod check_export; pub mod dead; mod debugger_visualizer; mod diagnostic_items; +mod eii; pub mod entry; mod errors; pub mod hir_id_validator; @@ -43,4 +44,5 @@ pub fn provide(providers: &mut Providers) { stability::provide(providers); upvars::provide(providers); check_export::provide(providers); + providers.check_externally_implementable_items = eii::check_externally_implementable_items; } From b732030025eb67ff88f942e9b2895042ac6a3e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 10 Sep 2025 13:21:59 -0700 Subject: [PATCH 0656/3801] make EII iteration faster --- compiler/rustc_ast_lowering/src/item.rs | 8 ++++++++ compiler/rustc_hir/src/hir.rs | 3 +++ compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_metadata/src/eii.rs | 3 +-- compiler/rustc_middle/src/hir/map.rs | 12 ++++++++++++ compiler/rustc_middle/src/hir/mod.rs | 7 +++++++ 6 files changed, 32 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 0e0ded0b27a0..a68d63bf1464 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -227,6 +227,10 @@ impl<'hir> LoweringContext<'_, 'hir> { vis_span, span: self.lower_span(i.span), has_delayed_lints: !self.delayed_lints.is_empty(), + eii: find_attr!( + attrs, + AttributeKind::EiiImpls(..) | AttributeKind::EiiExternTarget(..) + ), }; self.arena.alloc(item) } @@ -670,6 +674,10 @@ impl<'hir> LoweringContext<'_, 'hir> { vis_span, span: this.lower_span(use_tree.span), has_delayed_lints: !this.delayed_lints.is_empty(), + eii: find_attr!( + attrs, + AttributeKind::EiiImpls(..) | AttributeKind::EiiExternTarget(..) + ), }; hir::OwnerNode::Item(this.arena.alloc(item)) }); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f5470adb87e0..c60471848c89 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4164,6 +4164,9 @@ pub struct Item<'hir> { pub span: Span, pub vis_span: Span, pub has_delayed_lints: bool, + /// hint to speed up collection: true if the item is a static or function and has + /// either an `EiiImpls` or `EiiExternTarget` attribute + pub eii: bool, } impl<'hir> Item<'hir> { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 625766f8bd3d..be3cab6461ef 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -532,7 +532,7 @@ pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) -> } pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::Result { - let Item { owner_id: _, kind, span: _, vis_span: _, has_delayed_lints: _ } = item; + let Item { owner_id: _, kind, span: _, vis_span: _, has_delayed_lints: _, eii: _ } = item; try_visit!(visitor.visit_id(item.hir_id())); match *kind { ItemKind::ExternCrate(orig_name, ident) => { diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs index 2d99ba516ad4..5558ff930851 100644 --- a/compiler/rustc_metadata/src/eii.rs +++ b/compiler/rustc_metadata/src/eii.rs @@ -24,8 +24,7 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap let mut eiis = EiiMap::default(); // iterate over all items in the current crate - // FIXME(speed up) - for id in tcx.hir_crate_items(()).definitions() { + for id in tcx.hir_crate_items(()).eiis() { for i in find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiImpls(e) => e).into_iter().flatten() { diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index bf3192d9df17..5da762ef8565 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1224,6 +1224,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod body_owners, opaques, nested_bodies, + eiis, .. } = collector; ModuleItems { @@ -1237,6 +1238,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod opaques: opaques.into_boxed_slice(), nested_bodies: nested_bodies.into_boxed_slice(), delayed_lint_items: Box::new([]), + eiis: eiis.into_boxed_slice(), } } @@ -1259,6 +1261,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { opaques, nested_bodies, mut delayed_lint_items, + eiis, .. } = collector; @@ -1281,6 +1284,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { opaques: opaques.into_boxed_slice(), nested_bodies: nested_bodies.into_boxed_slice(), delayed_lint_items: delayed_lint_items.into_boxed_slice(), + eiis: eiis.into_boxed_slice(), } } @@ -1298,6 +1302,7 @@ struct ItemCollector<'tcx> { opaques: Vec, nested_bodies: Vec, delayed_lint_items: Vec, + eiis: Vec, } impl<'tcx> ItemCollector<'tcx> { @@ -1314,6 +1319,7 @@ impl<'tcx> ItemCollector<'tcx> { opaques: Vec::default(), nested_bodies: Vec::default(), delayed_lint_items: Vec::default(), + eiis: Vec::default(), } } } @@ -1335,6 +1341,12 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { self.delayed_lint_items.push(item.item_id().owner_id); } + if let ItemKind::Static(..) | ItemKind::Fn { .. } | ItemKind::Macro(..) = &item.kind + && item.eii + { + self.eiis.push(item.owner_id.def_id) + } + // Items that are modules are handled here instead of in visit_mod. if let ItemKind::Mod(_, module) = &item.kind { self.submodules.push(item.owner_id); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 0ab5a792e040..217ecbab059e 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -37,6 +37,9 @@ pub struct ModuleItems { nested_bodies: Box<[LocalDefId]>, // only filled with hir_crate_items, not with hir_module_items delayed_lint_items: Box<[OwnerId]>, + + /// Statics and functions with an `EiiImpls` or `EiiExternTarget` attribute + eiis: Box<[LocalDefId]>, } impl ModuleItems { @@ -58,6 +61,10 @@ impl ModuleItems { self.delayed_lint_items.iter().copied() } + pub fn eiis(&self) -> impl Iterator { + self.eiis.iter().copied() + } + /// Returns all items that are associated with some `impl` block (both inherent and trait impl /// blocks). pub fn impl_items(&self) -> impl Iterator { From 8dfb2cdecef9dea3a98dde094fcda54fbc23a892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 12 Aug 2025 14:40:05 +0200 Subject: [PATCH 0657/3801] EII type checking --- compiler/rustc_hir_analysis/messages.ftl | 11 + .../src/check/compare_eii.rs | 424 ++++++++++++++++++ compiler/rustc_hir_analysis/src/check/mod.rs | 1 + .../rustc_hir_analysis/src/check/wfcheck.rs | 28 +- compiler/rustc_hir_analysis/src/errors.rs | 25 ++ compiler/rustc_middle/src/traits/mod.rs | 7 + .../src/error_reporting/traits/suggestions.rs | 3 + 7 files changed, 498 insertions(+), 1 deletion(-) create mode 100644 compiler/rustc_hir_analysis/src/check/compare_eii.rs diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index bcf4d7f59e34..8022a48ee137 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -165,6 +165,10 @@ hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice .label = parameter captured again here +hir_analysis_eii_with_generics = + #[{$eii_name}] cannot have generic parameters other than lifetimes + .label = required by this attribute + hir_analysis_empty_specialization = specialization impl does not specialize any associated items .note = impl is a specialization of this impl @@ -300,6 +304,13 @@ hir_analysis_lifetime_not_captured = `impl Trait` captures lifetime parameter, b .label = lifetime captured due to being mentioned in the bounds of the `impl Trait` .param_label = this lifetime parameter is captured +hir_analysis_lifetimes_or_bounds_mismatch_on_eii = + lifetime parameters or bounds of `{$ident}` do not match the declaration + .label = lifetimes do not match + .generics_label = lifetimes in impl do not match this signature + .where_label = this `where` clause might not match the one in the declaration + .bounds_label = this bound might be missing in the implementation + hir_analysis_lifetimes_or_bounds_mismatch_on_trait = lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration .label = lifetimes do not match {$item_kind} in trait diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs new file mode 100644 index 000000000000..06b7f4952957 --- /dev/null +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs @@ -0,0 +1,424 @@ +use std::borrow::Cow; +use std::iter; + +use rustc_data_structures::fx::FxIndexSet; +use rustc_errors::{Applicability, E0805, struct_span_code_err}; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{self as hir, FnSig, HirId, ItemKind}; +use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; +use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; +use rustc_middle::ty::error::{ExpectedFound, TypeError}; +use rustc_middle::ty::{self, TyCtxt, TypingMode}; +use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; +use rustc_trait_selection::error_reporting::InferCtxtErrorExt; +use rustc_trait_selection::regions::InferCtxtRegionExt; +use rustc_trait_selection::traits::ObligationCtxt; +use tracing::{debug, instrument}; + +use super::potentially_plural_count; +use crate::errors::{EiiWithGenerics, LifetimesOrBoundsMismatchOnEii}; + +/// checks whether the signature of some `external_impl`, matches +/// the signature of `declaration`, which it is supposed to be compatible +/// with in order to implement the item. +pub(crate) fn compare_eii_function_types<'tcx>( + tcx: TyCtxt<'tcx>, + external_impl: LocalDefId, + declaration: DefId, + eii_name: Symbol, + eii_attr_span: Span, +) -> Result<(), ErrorGuaranteed> { + check_is_structurally_compatible(tcx, external_impl, declaration, eii_name, eii_attr_span)?; + + let external_impl_span = tcx.def_span(external_impl); + let cause = ObligationCause::new( + external_impl_span, + external_impl, + ObligationCauseCode::CompareEii { external_impl, declaration }, + ); + + // FIXME(eii): even if we don't support generic functions, we should support explicit outlive bounds here + let param_env = tcx.param_env(declaration); + + let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); + + // We now need to check that the signature of the impl method is + // compatible with that of the trait method. We do this by + // checking that `impl_fty <: trait_fty`. + // + // FIXME: We manually instantiate the trait method here as we need + // to manually compute its implied bounds. Otherwise this could just + // be ocx.sub(impl_sig, trait_sig). + + let wf_tys = FxIndexSet::default(); + let norm_cause = ObligationCause::misc(external_impl_span, external_impl); + + let declaration_sig = tcx.fn_sig(declaration).instantiate_identity(); + let declaration_sig = infcx.enter_forall_and_leak_universe(declaration_sig); + let declaration_sig = ocx.normalize(&norm_cause, param_env, declaration_sig); + + let external_impl_sig = infcx.instantiate_binder_with_fresh_vars( + external_impl_span, + infer::BoundRegionConversionTime::HigherRankedType, + tcx.fn_sig(external_impl).instantiate( + tcx, + infcx.fresh_args_for_item(external_impl_span, external_impl.to_def_id()), + ), + ); + let external_impl_sig = ocx.normalize(&norm_cause, param_env, external_impl_sig); + debug!(?external_impl_sig); + + // FIXME: We'd want to keep more accurate spans than "the method signature" when + // processing the comparison between the trait and impl fn, but we sadly lose them + // and point at the whole signature when a trait bound or specific input or output + // type would be more appropriate. In other places we have a `Vec` + // corresponding to their `Vec`, but we don't have that here. + // Fixing this would improve the output of test `issue-83765.rs`. + let result = ocx.sup(&cause, param_env, declaration_sig, external_impl_sig); + + if let Err(terr) = result { + debug!(?external_impl_sig, ?declaration_sig, ?terr, "sub_types failed"); + + let emitted = report_eii_mismatch( + infcx, + cause, + param_env, + terr, + (declaration, declaration_sig), + (external_impl, external_impl_sig), + eii_attr_span, + eii_name, + ); + return Err(emitted); + } + + // Check that all obligations are satisfied by the implementation's + // version. + let errors = ocx.evaluate_obligations_error_on_ambiguity(); + if !errors.is_empty() { + let reported = infcx.err_ctxt().report_fulfillment_errors(errors); + return Err(reported); + } + + // Finally, resolve all regions. This catches wily misuses of + // lifetime parameters. + let errors = infcx.resolve_regions(external_impl, param_env, wf_tys); + if !errors.is_empty() { + return Err(infcx + .tainted_by_errors() + .unwrap_or_else(|| infcx.err_ctxt().report_region_errors(external_impl, &errors))); + } + + Ok(()) +} + +/// Checks a bunch of different properties of the impl/trait methods for +/// compatibility, such as asyncness, number of argument, self receiver kind, +/// and number of early- and late-bound generics. +fn check_is_structurally_compatible<'tcx>( + tcx: TyCtxt<'tcx>, + external_impl: LocalDefId, + declaration: DefId, + eii_name: Symbol, + eii_attr_span: Span, +) -> Result<(), ErrorGuaranteed> { + check_no_generics(tcx, external_impl, declaration, eii_name, eii_attr_span)?; + compare_number_of_method_arguments(tcx, external_impl, declaration, eii_name, eii_attr_span)?; + check_region_bounds_on_impl_item(tcx, external_impl, declaration, eii_attr_span)?; + Ok(()) +} + +fn check_no_generics<'tcx>( + tcx: TyCtxt<'tcx>, + external_impl: LocalDefId, + _declaration: DefId, + eii_name: Symbol, + eii_attr_span: Span, +) -> Result<(), ErrorGuaranteed> { + let generics = tcx.generics_of(external_impl); + if generics.own_requires_monomorphization() { + tcx.dcx().emit_err(EiiWithGenerics { + span: tcx.def_span(external_impl), + attr: eii_attr_span, + eii_name, + }); + } + + Ok(()) +} + +fn compare_number_of_method_arguments<'tcx>( + tcx: TyCtxt<'tcx>, + external_impl: LocalDefId, + declaration: DefId, + eii_name: Symbol, + eii_attr_span: Span, +) -> Result<(), ErrorGuaranteed> { + let external_impl_fty = tcx.fn_sig(external_impl); + let declaration_fty = tcx.fn_sig(declaration); + let declaration_number_args = declaration_fty.skip_binder().inputs().skip_binder().len(); + let external_impl_number_args = external_impl_fty.skip_binder().inputs().skip_binder().len(); + let external_impl_name = tcx.item_name(external_impl.to_def_id()); + + if declaration_number_args != external_impl_number_args { + let declaration_span = declaration + .as_local() + .and_then(|def_id| { + let declaration_sig = get_declaration_sig(tcx, def_id).expect("foreign item sig"); + let pos = declaration_number_args.saturating_sub(1); + declaration_sig.decl.inputs.get(pos).map(|arg| { + if pos == 0 { + arg.span + } else { + arg.span.with_lo(declaration_sig.decl.inputs[0].span.lo()) + } + }) + }) + .or_else(|| tcx.hir_span_if_local(declaration)) + .unwrap_or_else(|| tcx.def_span(declaration)); + + let (_, external_impl_sig, _, _) = &tcx.hir_expect_item(external_impl).expect_fn(); + let pos = external_impl_number_args.saturating_sub(1); + let impl_span = external_impl_sig + .decl + .inputs + .get(pos) + .map(|arg| { + if pos == 0 { + arg.span + } else { + arg.span.with_lo(external_impl_sig.decl.inputs[0].span.lo()) + } + }) + .unwrap_or_else(|| tcx.def_span(external_impl)); + + let mut err = struct_span_code_err!( + tcx.dcx(), + impl_span, + E0805, + "`{external_impl_name}` has {} but #[{eii_name}] requires it to have {}", + potentially_plural_count(external_impl_number_args, "parameter"), + declaration_number_args + ); + + // if let Some(declaration_span) = declaration_span { + err.span_label( + declaration_span, + format!("requires {}", potentially_plural_count(declaration_number_args, "parameter")), + ); + // } + + err.span_label( + impl_span, + format!( + "expected {}, found {}", + potentially_plural_count(declaration_number_args, "parameter"), + external_impl_number_args + ), + ); + + err.span_label(eii_attr_span, format!("required because of this attribute")); + + return Err(err.emit()); + } + + Ok(()) +} + +fn check_region_bounds_on_impl_item<'tcx>( + tcx: TyCtxt<'tcx>, + external_impl: LocalDefId, + declaration: DefId, + eii_attr_span: Span, +) -> Result<(), ErrorGuaranteed> { + let external_impl_generics = tcx.generics_of(external_impl.to_def_id()); + let external_impl_params = external_impl_generics.own_counts().lifetimes; + + let declaration_generics = tcx.generics_of(declaration); + let declaration_params = declaration_generics.own_counts().lifetimes; + + debug!(?declaration_generics, ?external_impl_generics); + + // Must have same number of early-bound lifetime parameters. + // Unfortunately, if the user screws up the bounds, then this + // will change classification between early and late. E.g., + // if in trait we have `<'a,'b:'a>`, and in impl we just have + // `<'a,'b>`, then we have 2 early-bound lifetime parameters + // in trait but 0 in the impl. But if we report "expected 2 + // but found 0" it's confusing, because it looks like there + // are zero. Since I don't quite know how to phrase things at + // the moment, give a kind of vague error message. + if declaration_params != external_impl_params { + let span = tcx + .hir_get_generics(external_impl) + .expect("expected impl item to have generics or else we can't compare them") + .span; + + let mut generics_span = None; + let mut bounds_span = vec![]; + let mut where_span = None; + + if let Some(declaration_node) = tcx.hir_get_if_local(declaration) + && let Some(declaration_generics) = declaration_node.generics() + { + generics_span = Some(declaration_generics.span); + // FIXME: we could potentially look at the impl's bounds to not point at bounds that + // *are* present in the impl. + for p in declaration_generics.predicates { + if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind { + for b in pred.bounds { + if let hir::GenericBound::Outlives(lt) = b { + bounds_span.push(lt.ident.span); + } + } + } + } + if let Some(implementation_generics) = tcx.hir_get_generics(external_impl) { + let mut impl_bounds = 0; + for p in implementation_generics.predicates { + if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind { + for b in pred.bounds { + if let hir::GenericBound::Outlives(_) = b { + impl_bounds += 1; + } + } + } + } + if impl_bounds == bounds_span.len() { + bounds_span = vec![]; + } else if implementation_generics.has_where_clause_predicates { + where_span = Some(implementation_generics.where_clause_span); + } + } + } + let mut diag = tcx.dcx().create_err(LifetimesOrBoundsMismatchOnEii { + span, + ident: tcx.item_name(external_impl.to_def_id()), + generics_span, + bounds_span, + where_span, + }); + + diag.span_label(eii_attr_span, format!("required because of this attribute")); + return Err(diag.emit()); + } + + Ok(()) +} + +fn report_eii_mismatch<'tcx>( + infcx: &InferCtxt<'tcx>, + mut cause: ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + terr: TypeError<'tcx>, + (declaration_did, declaration_sig): (DefId, ty::FnSig<'tcx>), + (external_impl_did, external_impl_sig): (LocalDefId, ty::FnSig<'tcx>), + eii_attr_span: Span, + eii_name: Symbol, +) -> ErrorGuaranteed { + let tcx = infcx.tcx; + let (impl_err_span, trait_err_span, external_impl_name) = + extract_spans_for_error_reporting(infcx, terr, &cause, declaration_did, external_impl_did); + + let mut diag = struct_span_code_err!( + tcx.dcx(), + impl_err_span, + E0805, + "function `{}` has a type that is incompatible with the declaration of `#[{eii_name}]`", + external_impl_name + ); + + diag.span_note(eii_attr_span, "expected this because of this attribute"); + + match &terr { + TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(_, i) => { + if declaration_sig.inputs().len() == *i { + // Suggestion to change output type. We do not suggest in `async` functions + // to avoid complex logic or incorrect output. + if let ItemKind::Fn { sig, .. } = &tcx.hir_expect_item(external_impl_did).kind + && !sig.header.asyncness.is_async() + { + let msg = "change the output type to match the declaration"; + let ap = Applicability::MachineApplicable; + match sig.decl.output { + hir::FnRetTy::DefaultReturn(sp) => { + let sugg = format!(" -> {}", declaration_sig.output()); + diag.span_suggestion_verbose(sp, msg, sugg, ap); + } + hir::FnRetTy::Return(hir_ty) => { + let sugg = declaration_sig.output(); + diag.span_suggestion_verbose(hir_ty.span, msg, sugg, ap); + } + }; + }; + } else if let Some(trait_ty) = declaration_sig.inputs().get(*i) { + diag.span_suggestion_verbose( + impl_err_span, + "change the parameter type to match the declaration", + trait_ty, + Applicability::MachineApplicable, + ); + } + } + _ => {} + } + + cause.span = impl_err_span; + infcx.err_ctxt().note_type_err( + &mut diag, + &cause, + trait_err_span.map(|sp| (sp, Cow::from("type in declaration"), false)), + Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound { + expected: ty::Binder::dummy(declaration_sig), + found: ty::Binder::dummy(external_impl_sig), + }))), + terr, + false, + None, + ); + + diag.emit() +} + +#[instrument(level = "debug", skip(infcx))] +fn extract_spans_for_error_reporting<'tcx>( + infcx: &infer::InferCtxt<'tcx>, + terr: TypeError<'_>, + cause: &ObligationCause<'tcx>, + declaration: DefId, + external_impl: LocalDefId, +) -> (Span, Option, Ident) { + let tcx = infcx.tcx; + let (mut external_impl_args, external_impl_name) = { + let item = tcx.hir_expect_item(external_impl); + let (ident, sig, _, _) = item.expect_fn(); + (sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())), ident) + }; + + let declaration_args = declaration.as_local().map(|def_id| { + if let Some(sig) = get_declaration_sig(tcx, def_id) { + sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())) + } else { + panic!("expected {def_id:?} to be a foreign function"); + } + }); + + match terr { + TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(ExpectedFound { .. }, i) => ( + external_impl_args.nth(i).unwrap(), + declaration_args.and_then(|mut args| args.nth(i)), + external_impl_name, + ), + _ => ( + cause.span, + tcx.hir_span_if_local(declaration).or_else(|| Some(tcx.def_span(declaration))), + external_impl_name, + ), + } +} + +fn get_declaration_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Option<&'tcx FnSig<'tcx>> { + let hir_id: HirId = tcx.local_def_id_to_hir_id(def_id); + tcx.hir_fn_sig_by_hir_id(hir_id) +} diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index f1c84a14de30..d6ae14a7acfe 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -64,6 +64,7 @@ a type parameter). pub mod always_applicable; mod check; +mod compare_eii; mod compare_impl_item; mod entry; pub mod intrinsic; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 0e8859facf58..97097f4a0bfc 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -6,7 +6,7 @@ use rustc_abi::ExternAbi; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; -use rustc_hir::attrs::AttributeKind; +use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; @@ -39,6 +39,7 @@ use rustc_trait_selection::traits::{ use tracing::{debug, instrument}; use {rustc_ast as ast, rustc_hir as hir}; +use super::compare_eii::compare_eii_function_types; use crate::autoderef::Autoderef; use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params}; use crate::errors::InvalidReceiverTyHint; @@ -1171,6 +1172,31 @@ fn check_item_fn( decl: &hir::FnDecl<'_>, ) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + // does the function have an EiiImpl attribute? that contains the defid of a *macro* + // that was used to mark the implementation. This is a two step process. + for EiiImpl { eii_macro, span, .. } in + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::EiiImpls(impls) => impls) + .into_iter() + .flatten() + { + // we expect this macro to have the `EiiMacroFor` attribute, that points to a function + // signature that we'd like to compare the function we're currently checking with + if let Some(eii_extern_target) = find_attr!(tcx.get_all_attrs(*eii_macro), AttributeKind::EiiExternTarget(EiiDecl {eii_extern_target, ..}) => *eii_extern_target) + { + let _ = compare_eii_function_types( + tcx, + def_id, + eii_extern_target, + tcx.item_name(*eii_macro), + *span, + ); + } else { + panic!( + "EII impl macro {eii_macro:?} did not have an eii extern target attribute pointing to a foreign function" + ) + } + } + let sig = tcx.fn_sig(def_id).instantiate_identity(); check_fn_or_method(wfcx, sig, decl, def_id); Ok(()) diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 34ad4e720eb5..865abdbd32c2 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1697,3 +1697,28 @@ pub(crate) struct AsyncDropWithoutSyncDrop { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_lifetimes_or_bounds_mismatch_on_eii)] +pub(crate) struct LifetimesOrBoundsMismatchOnEii { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_analysis_generics_label)] + pub generics_span: Option, + #[label(hir_analysis_where_label)] + pub where_span: Option, + #[label(hir_analysis_bounds_label)] + pub bounds_span: Vec, + pub ident: Symbol, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_eii_with_generics)] +pub(crate) struct EiiWithGenerics { + #[primary_span] + pub span: Span, + #[label] + pub attr: Span, + pub eii_name: Symbol, +} diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 0c7bddf60d97..c064313f67b2 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -420,6 +420,13 @@ pub enum ObligationCauseCode<'tcx> { /// Only reachable if the `unsized_fn_params` feature is used. Unsized function arguments must /// be place expressions because we can't store them in MIR locals as temporaries. UnsizedNonPlaceExpr(Span), + + /// Error derived when checking an impl item is compatible with + /// its corresponding trait item's definition + CompareEii { + external_impl: LocalDefId, + declaration: DefId, + }, } /// Whether a value can be extracted into a const. diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index fd845e31c909..d14ff2c3b7e2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3843,6 +3843,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { "unsized values must be place expressions and cannot be put in temporaries", ); } + ObligationCauseCode::CompareEii { .. } => { + panic!("trait bounds on EII not yet supported ") + } } } From 230ad7f639c5d453eb743cd2b94b1345cb1cab78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 12 Sep 2025 11:21:59 -0700 Subject: [PATCH 0658/3801] fix problems with type checking --- .../src/check/compare_eii.rs | 317 +++++++++--------- .../src/check/compare_impl_item.rs | 81 +++-- .../rustc_hir_analysis/src/check/wfcheck.rs | 52 +-- compiler/rustc_hir_analysis/src/errors.rs | 2 +- 4 files changed, 250 insertions(+), 202 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs index 06b7f4952957..609f29103fdd 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs @@ -1,3 +1,8 @@ +//! This module is very similar to `compare_impl_item`. +//! Most logic is taken from there, +//! since in a very similar way we're comparing some declaration of a signature to an implementation. +//! The major difference is that we don't bother with self types, since for EIIs we're comparing freestanding item. + use std::borrow::Cow; use std::iter; @@ -8,17 +13,20 @@ use rustc_hir::{self as hir, FnSig, HirId, ItemKind}; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, TyCtxt, TypingMode}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode}; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::regions::InferCtxtRegionExt; -use rustc_trait_selection::traits::ObligationCtxt; +use rustc_trait_selection::traits::{self, ObligationCtxt}; use tracing::{debug, instrument}; use super::potentially_plural_count; +use crate::check::compare_impl_item::{ + CheckNumberOfEarlyBoundRegionsError, check_number_of_early_bound_regions, +}; use crate::errors::{EiiWithGenerics, LifetimesOrBoundsMismatchOnEii}; -/// checks whether the signature of some `external_impl`, matches +/// Checks whether the signature of some `external_impl`, matches /// the signature of `declaration`, which it is supposed to be compatible /// with in order to implement the item. pub(crate) fn compare_eii_function_types<'tcx>( @@ -43,22 +51,22 @@ pub(crate) fn compare_eii_function_types<'tcx>( let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(infcx); - // We now need to check that the signature of the impl method is - // compatible with that of the trait method. We do this by + // We now need to check that the signature of the implementation is + // compatible with that of the declaration. We do this by // checking that `impl_fty <: trait_fty`. // - // FIXME: We manually instantiate the trait method here as we need + // FIXME: We manually instantiate the declaration here as we need // to manually compute its implied bounds. Otherwise this could just // be ocx.sub(impl_sig, trait_sig). - let wf_tys = FxIndexSet::default(); + let mut wf_tys = FxIndexSet::default(); let norm_cause = ObligationCause::misc(external_impl_span, external_impl); let declaration_sig = tcx.fn_sig(declaration).instantiate_identity(); - let declaration_sig = infcx.enter_forall_and_leak_universe(declaration_sig); - let declaration_sig = ocx.normalize(&norm_cause, param_env, declaration_sig); + let declaration_sig = tcx.liberate_late_bound_regions(external_impl.into(), declaration_sig); + debug!(?declaration_sig); - let external_impl_sig = infcx.instantiate_binder_with_fresh_vars( + let unnormalized_external_impl_sig = infcx.instantiate_binder_with_fresh_vars( external_impl_span, infer::BoundRegionConversionTime::HigherRankedType, tcx.fn_sig(external_impl).instantiate( @@ -66,10 +74,20 @@ pub(crate) fn compare_eii_function_types<'tcx>( infcx.fresh_args_for_item(external_impl_span, external_impl.to_def_id()), ), ); - let external_impl_sig = ocx.normalize(&norm_cause, param_env, external_impl_sig); + let external_impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_external_impl_sig); debug!(?external_impl_sig); - // FIXME: We'd want to keep more accurate spans than "the method signature" when + // Next, add all inputs and output as well-formed tys. Importantly, + // we have to do this before normalization, since the normalized ty may + // not contain the input parameters. See issue #87748. + wf_tys.extend(declaration_sig.inputs_and_output.iter()); + let declaration_sig = ocx.normalize(&norm_cause, param_env, declaration_sig); + // We also have to add the normalized declaration + // as we don't normalize during implied bounds computation. + wf_tys.extend(external_impl_sig.inputs_and_output.iter()); + + // FIXME: Copied over from compare impl items, same issue: + // We'd want to keep more accurate spans than "the method signature" when // processing the comparison between the trait and impl fn, but we sadly lose them // and point at the whole signature when a trait bound or specific input or output // type would be more appropriate. In other places we have a `Vec` @@ -93,6 +111,17 @@ pub(crate) fn compare_eii_function_types<'tcx>( return Err(emitted); } + if !(declaration_sig, external_impl_sig).references_error() { + for ty in unnormalized_external_impl_sig.inputs_and_output { + ocx.register_obligation(traits::Obligation::new( + infcx.tcx, + cause.clone(), + param_env, + ty::ClauseKind::WellFormed(ty.into()), + )); + } + } + // Check that all obligations are satisfied by the implementation's // version. let errors = ocx.evaluate_obligations_error_on_ambiguity(); @@ -116,6 +145,8 @@ pub(crate) fn compare_eii_function_types<'tcx>( /// Checks a bunch of different properties of the impl/trait methods for /// compatibility, such as asyncness, number of argument, self receiver kind, /// and number of early- and late-bound generics. +/// +/// Corresponds to `check_method_is_structurally_compatible` for impl method compatibility checks. fn check_is_structurally_compatible<'tcx>( tcx: TyCtxt<'tcx>, external_impl: LocalDefId, @@ -124,11 +155,12 @@ fn check_is_structurally_compatible<'tcx>( eii_attr_span: Span, ) -> Result<(), ErrorGuaranteed> { check_no_generics(tcx, external_impl, declaration, eii_name, eii_attr_span)?; - compare_number_of_method_arguments(tcx, external_impl, declaration, eii_name, eii_attr_span)?; - check_region_bounds_on_impl_item(tcx, external_impl, declaration, eii_attr_span)?; + check_number_of_arguments(tcx, external_impl, declaration, eii_name, eii_attr_span)?; + check_early_region_bounds(tcx, external_impl, declaration, eii_attr_span)?; Ok(()) } +/// externally implementable items can't have generics fn check_no_generics<'tcx>( tcx: TyCtxt<'tcx>, external_impl: LocalDefId, @@ -148,85 +180,7 @@ fn check_no_generics<'tcx>( Ok(()) } -fn compare_number_of_method_arguments<'tcx>( - tcx: TyCtxt<'tcx>, - external_impl: LocalDefId, - declaration: DefId, - eii_name: Symbol, - eii_attr_span: Span, -) -> Result<(), ErrorGuaranteed> { - let external_impl_fty = tcx.fn_sig(external_impl); - let declaration_fty = tcx.fn_sig(declaration); - let declaration_number_args = declaration_fty.skip_binder().inputs().skip_binder().len(); - let external_impl_number_args = external_impl_fty.skip_binder().inputs().skip_binder().len(); - let external_impl_name = tcx.item_name(external_impl.to_def_id()); - - if declaration_number_args != external_impl_number_args { - let declaration_span = declaration - .as_local() - .and_then(|def_id| { - let declaration_sig = get_declaration_sig(tcx, def_id).expect("foreign item sig"); - let pos = declaration_number_args.saturating_sub(1); - declaration_sig.decl.inputs.get(pos).map(|arg| { - if pos == 0 { - arg.span - } else { - arg.span.with_lo(declaration_sig.decl.inputs[0].span.lo()) - } - }) - }) - .or_else(|| tcx.hir_span_if_local(declaration)) - .unwrap_or_else(|| tcx.def_span(declaration)); - - let (_, external_impl_sig, _, _) = &tcx.hir_expect_item(external_impl).expect_fn(); - let pos = external_impl_number_args.saturating_sub(1); - let impl_span = external_impl_sig - .decl - .inputs - .get(pos) - .map(|arg| { - if pos == 0 { - arg.span - } else { - arg.span.with_lo(external_impl_sig.decl.inputs[0].span.lo()) - } - }) - .unwrap_or_else(|| tcx.def_span(external_impl)); - - let mut err = struct_span_code_err!( - tcx.dcx(), - impl_span, - E0805, - "`{external_impl_name}` has {} but #[{eii_name}] requires it to have {}", - potentially_plural_count(external_impl_number_args, "parameter"), - declaration_number_args - ); - - // if let Some(declaration_span) = declaration_span { - err.span_label( - declaration_span, - format!("requires {}", potentially_plural_count(declaration_number_args, "parameter")), - ); - // } - - err.span_label( - impl_span, - format!( - "expected {}, found {}", - potentially_plural_count(declaration_number_args, "parameter"), - external_impl_number_args - ), - ); - - err.span_label(eii_attr_span, format!("required because of this attribute")); - - return Err(err.emit()); - } - - Ok(()) -} - -fn check_region_bounds_on_impl_item<'tcx>( +fn check_early_region_bounds<'tcx>( tcx: TyCtxt<'tcx>, external_impl: LocalDefId, declaration: DefId, @@ -238,73 +192,128 @@ fn check_region_bounds_on_impl_item<'tcx>( let declaration_generics = tcx.generics_of(declaration); let declaration_params = declaration_generics.own_counts().lifetimes; - debug!(?declaration_generics, ?external_impl_generics); + let Err(CheckNumberOfEarlyBoundRegionsError { span, generics_span, bounds_span, where_span }) = + check_number_of_early_bound_regions( + tcx, + external_impl, + declaration, + external_impl_generics, + external_impl_params, + declaration_generics, + declaration_params, + ) + else { + return Ok(()); + }; - // Must have same number of early-bound lifetime parameters. - // Unfortunately, if the user screws up the bounds, then this - // will change classification between early and late. E.g., - // if in trait we have `<'a,'b:'a>`, and in impl we just have - // `<'a,'b>`, then we have 2 early-bound lifetime parameters - // in trait but 0 in the impl. But if we report "expected 2 - // but found 0" it's confusing, because it looks like there - // are zero. Since I don't quite know how to phrase things at - // the moment, give a kind of vague error message. - if declaration_params != external_impl_params { - let span = tcx - .hir_get_generics(external_impl) - .expect("expected impl item to have generics or else we can't compare them") - .span; + let mut diag = tcx.dcx().create_err(LifetimesOrBoundsMismatchOnEii { + span, + ident: tcx.item_name(external_impl.to_def_id()), + generics_span, + bounds_span, + where_span, + }); - let mut generics_span = None; - let mut bounds_span = vec![]; - let mut where_span = None; + diag.span_label(eii_attr_span, format!("required because of this attribute")); + return Err(diag.emit()); +} - if let Some(declaration_node) = tcx.hir_get_if_local(declaration) - && let Some(declaration_generics) = declaration_node.generics() - { - generics_span = Some(declaration_generics.span); - // FIXME: we could potentially look at the impl's bounds to not point at bounds that - // *are* present in the impl. - for p in declaration_generics.predicates { - if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind { - for b in pred.bounds { - if let hir::GenericBound::Outlives(lt) = b { - bounds_span.push(lt.ident.span); - } - } - } - } - if let Some(implementation_generics) = tcx.hir_get_generics(external_impl) { - let mut impl_bounds = 0; - for p in implementation_generics.predicates { - if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind { - for b in pred.bounds { - if let hir::GenericBound::Outlives(_) = b { - impl_bounds += 1; - } - } - } - } - if impl_bounds == bounds_span.len() { - bounds_span = vec![]; - } else if implementation_generics.has_where_clause_predicates { - where_span = Some(implementation_generics.where_clause_span); - } - } - } - let mut diag = tcx.dcx().create_err(LifetimesOrBoundsMismatchOnEii { - span, - ident: tcx.item_name(external_impl.to_def_id()), - generics_span, - bounds_span, - where_span, - }); +fn check_number_of_arguments<'tcx>( + tcx: TyCtxt<'tcx>, + external_impl: LocalDefId, + declaration: DefId, + eii_name: Symbol, + eii_attr_span: Span, +) -> Result<(), ErrorGuaranteed> { + let external_impl_fty = tcx.fn_sig(external_impl); + let declaration_fty = tcx.fn_sig(declaration); + let declaration_number_args = declaration_fty.skip_binder().inputs().skip_binder().len(); + let external_impl_number_args = external_impl_fty.skip_binder().inputs().skip_binder().len(); - diag.span_label(eii_attr_span, format!("required because of this attribute")); - return Err(diag.emit()); + // if the number of args are equal, we're trivially done + if declaration_number_args == external_impl_number_args { + Ok(()) + } else { + Err(report_number_of_arguments_mismatch( + tcx, + external_impl, + declaration, + eii_name, + eii_attr_span, + declaration_number_args, + external_impl_number_args, + )) } +} - Ok(()) +fn report_number_of_arguments_mismatch<'tcx>( + tcx: TyCtxt<'tcx>, + external_impl: LocalDefId, + declaration: DefId, + eii_name: Symbol, + eii_attr_span: Span, + declaration_number_args: usize, + external_impl_number_args: usize, +) -> ErrorGuaranteed { + let external_impl_name = tcx.item_name(external_impl.to_def_id()); + + let declaration_span = declaration + .as_local() + .and_then(|def_id| { + let declaration_sig = get_declaration_sig(tcx, def_id).expect("foreign item sig"); + let pos = declaration_number_args.saturating_sub(1); + declaration_sig.decl.inputs.get(pos).map(|arg| { + if pos == 0 { + arg.span + } else { + arg.span.with_lo(declaration_sig.decl.inputs[0].span.lo()) + } + }) + }) + .or_else(|| tcx.hir_span_if_local(declaration)) + .unwrap_or_else(|| tcx.def_span(declaration)); + + let (_, external_impl_sig, _, _) = &tcx.hir_expect_item(external_impl).expect_fn(); + let pos = external_impl_number_args.saturating_sub(1); + let impl_span = external_impl_sig + .decl + .inputs + .get(pos) + .map(|arg| { + if pos == 0 { + arg.span + } else { + arg.span.with_lo(external_impl_sig.decl.inputs[0].span.lo()) + } + }) + .unwrap_or_else(|| tcx.def_span(external_impl)); + + let mut err = struct_span_code_err!( + tcx.dcx(), + impl_span, + E0805, + "`{external_impl_name}` has {} but #[{eii_name}] requires it to have {}", + potentially_plural_count(external_impl_number_args, "parameter"), + declaration_number_args + ); + + err.span_label( + declaration_span, + format!("requires {}", potentially_plural_count(declaration_number_args, "parameter")), + ); + + err.span_label( + impl_span, + format!( + "expected {}, found {}", + potentially_plural_count(declaration_number_args, "parameter"), + external_impl_number_args + ), + ); + + err.span_label(eii_attr_span, format!("required because of this attribute")); + + err.emit() } fn report_eii_mismatch<'tcx>( diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index c18faa785b16..b09e03941725 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -14,8 +14,9 @@ use rustc_infer::infer::{self, BoundRegionConversionTime, InferCtxt, TyCtxtInfer use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ - self, BottomUpFolder, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast, + self, BottomUpFolder, GenericArgs, GenericParamDefKind, Generics, Ty, TyCtxt, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, + Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Span}; @@ -352,6 +353,7 @@ fn compare_method_predicate_entailment<'tcx>( // type would be more appropriate. In other places we have a `Vec` // corresponding to their `Vec`, but we don't have that here. // Fixing this would improve the output of test `issue-83765.rs`. + // There's the same issue in compare_eii code. let result = ocx.sup(&cause, param_env, trait_sig, impl_sig); if let Err(terr) = result { @@ -1093,6 +1095,55 @@ fn check_region_bounds_on_impl_item<'tcx>( let trait_generics = tcx.generics_of(trait_m.def_id); let trait_params = trait_generics.own_counts().lifetimes; + let Err(CheckNumberOfEarlyBoundRegionsError { span, generics_span, bounds_span, where_span }) = + check_number_of_early_bound_regions( + tcx, + impl_m.def_id.expect_local(), + trait_m.def_id, + impl_generics, + impl_params, + trait_generics, + trait_params, + ) + else { + return Ok(()); + }; + + if !delay && let Some(guar) = check_region_late_boundedness(tcx, impl_m, trait_m) { + return Err(guar); + } + + let reported = tcx + .dcx() + .create_err(LifetimesOrBoundsMismatchOnTrait { + span, + item_kind: impl_m.descr(), + ident: impl_m.ident(tcx), + generics_span, + bounds_span, + where_span, + }) + .emit_unless_delay(delay); + + Err(reported) +} + +pub(super) struct CheckNumberOfEarlyBoundRegionsError { + pub(super) span: Span, + pub(super) generics_span: Span, + pub(super) bounds_span: Vec, + pub(super) where_span: Option, +} + +pub(super) fn check_number_of_early_bound_regions<'tcx>( + tcx: TyCtxt<'tcx>, + impl_def_id: LocalDefId, + trait_def_id: DefId, + impl_generics: &Generics, + impl_params: usize, + trait_generics: &Generics, + trait_params: usize, +) -> Result<(), CheckNumberOfEarlyBoundRegionsError> { debug!(?trait_generics, ?impl_generics); // Must have same number of early-bound lifetime parameters. @@ -1108,20 +1159,16 @@ fn check_region_bounds_on_impl_item<'tcx>( return Ok(()); } - if !delay && let Some(guar) = check_region_late_boundedness(tcx, impl_m, trait_m) { - return Err(guar); - } - let span = tcx - .hir_get_generics(impl_m.def_id.expect_local()) + .hir_get_generics(impl_def_id) .expect("expected impl item to have generics or else we can't compare them") .span; - let mut generics_span = tcx.def_span(trait_m.def_id); + let mut generics_span = tcx.def_span(trait_def_id); let mut bounds_span = vec![]; let mut where_span = None; - if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id) + if let Some(trait_node) = tcx.hir_get_if_local(trait_def_id) && let Some(trait_generics) = trait_node.generics() { generics_span = trait_generics.span; @@ -1146,7 +1193,7 @@ fn check_region_bounds_on_impl_item<'tcx>( _ => {} } } - if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id) + if let Some(impl_node) = tcx.hir_get_if_local(impl_def_id.into()) && let Some(impl_generics) = impl_node.generics() { let mut impl_bounds = 0; @@ -1177,19 +1224,7 @@ fn check_region_bounds_on_impl_item<'tcx>( } } - let reported = tcx - .dcx() - .create_err(LifetimesOrBoundsMismatchOnTrait { - span, - item_kind: impl_m.descr(), - ident: impl_m.ident(tcx), - generics_span, - bounds_span, - where_span, - }) - .emit_unless_delay(delay); - - Err(reported) + Err(CheckNumberOfEarlyBoundRegionsError { span, generics_span, bounds_span, where_span }) } #[allow(unused)] diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 97097f4a0bfc..12c5dc8cdf20 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1172,30 +1172,7 @@ fn check_item_fn( decl: &hir::FnDecl<'_>, ) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, def_id, |wfcx| { - // does the function have an EiiImpl attribute? that contains the defid of a *macro* - // that was used to mark the implementation. This is a two step process. - for EiiImpl { eii_macro, span, .. } in - find_attr!(tcx.get_all_attrs(def_id), AttributeKind::EiiImpls(impls) => impls) - .into_iter() - .flatten() - { - // we expect this macro to have the `EiiMacroFor` attribute, that points to a function - // signature that we'd like to compare the function we're currently checking with - if let Some(eii_extern_target) = find_attr!(tcx.get_all_attrs(*eii_macro), AttributeKind::EiiExternTarget(EiiDecl {eii_extern_target, ..}) => *eii_extern_target) - { - let _ = compare_eii_function_types( - tcx, - def_id, - eii_extern_target, - tcx.item_name(*eii_macro), - *span, - ); - } else { - panic!( - "EII impl macro {eii_macro:?} did not have an eii extern target attribute pointing to a foreign function" - ) - } - } + check_eiis(tcx, def_id); let sig = tcx.fn_sig(def_id).instantiate_identity(); check_fn_or_method(wfcx, sig, decl, def_id); @@ -1203,6 +1180,33 @@ fn check_item_fn( }) } +fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) { + // does the function have an EiiImpl attribute? that contains the defid of a *macro* + // that was used to mark the implementation. This is a two step process. + for EiiImpl { eii_macro, span, .. } in + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::EiiImpls(impls) => impls) + .into_iter() + .flatten() + { + // we expect this macro to have the `EiiMacroFor` attribute, that points to a function + // signature that we'd like to compare the function we're currently checking with + if let Some(eii_extern_target) = find_attr!(tcx.get_all_attrs(*eii_macro), AttributeKind::EiiExternTarget(EiiDecl {eii_extern_target, ..}) => *eii_extern_target) + { + let _ = compare_eii_function_types( + tcx, + def_id, + eii_extern_target, + tcx.item_name(*eii_macro), + *span, + ); + } else { + panic!( + "EII impl macro {eii_macro:?} did not have an eii extern target attribute pointing to a foreign function" + ) + } + } +} + #[instrument(level = "debug", skip(tcx))] pub(crate) fn check_static_item<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 865abdbd32c2..8e17a4962520 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1705,7 +1705,7 @@ pub(crate) struct LifetimesOrBoundsMismatchOnEii { #[label] pub span: Span, #[label(hir_analysis_generics_label)] - pub generics_span: Option, + pub generics_span: Span, #[label(hir_analysis_where_label)] pub where_span: Option, #[label(hir_analysis_bounds_label)] From a4abfad99bc742f424253798af5a311286ae21d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 21 Aug 2025 13:30:55 +0200 Subject: [PATCH 0659/3801] EII new error code --- .../src/error_codes/E0806.md | 68 +++++++++++++++++++ compiler/rustc_error_codes/src/lib.rs | 1 + .../src/check/compare_eii.rs | 6 +- tests/ui/error-codes/E0806.rs | 12 ++++ tests/ui/error-codes/E0806.stderr | 14 ++++ 5 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0806.md create mode 100644 tests/ui/error-codes/E0806.rs create mode 100644 tests/ui/error-codes/E0806.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0806.md b/compiler/rustc_error_codes/src/error_codes/E0806.md new file mode 100644 index 000000000000..9de1bb5891fa --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0806.md @@ -0,0 +1,68 @@ +An externally implementable item is not compatible with its declaration. + +Erroneous code example: + +```rust,edition2021,compile_fail,E0806 +#![feature(eii)] + +#[eii(foo)] +fn x(); + +#[foo] +fn y(a: u64) -> u64 { +//~^ ERROR E0806 + a +} + + +fn main() {} +``` + +The error here is caused by the fact that `y` implements the +externally implementable item `foo`. +It can only do so if the signature of the implementation `y` matches +that of the declaration of `foo`. +So, to fix this, `y`'s signature must be changed to match that of `x`: + +```rust,edition2021 +#![feature(eii)] + +#[eii(foo)] +fn x(); + +#[foo] +fn y() {} + + +fn main() {} +``` + +One common way this can be triggered is by using the wrong +signature for `#[panic_handler]`. +The signature is provided by `core`. + +```rust,edition2021,ignore +#![no_std] + +#[panic_handler] +fn on_panic() -> ! { +//~^ ERROR E0806 + + loop {} +} + +fn main() {} +``` + +Should be: + +```rust,edition2021,ignore +#![no_std] + +#[panic_handler] +fn on_panic(info: &core::panic::PanicInfo<'_>) -> ! { + loop {} +} + +fn main() {} +``` diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 6acd0342d2bb..65f1780885ad 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -543,6 +543,7 @@ macro_rules! error_codes { 0803, 0804, 0805, +0806, ); ) } diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs index 609f29103fdd..4e7f47a92108 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs @@ -7,7 +7,7 @@ use std::borrow::Cow; use std::iter; use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::{Applicability, E0805, struct_span_code_err}; +use rustc_errors::{Applicability, E0806, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, FnSig, HirId, ItemKind}; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; @@ -291,7 +291,7 @@ fn report_number_of_arguments_mismatch<'tcx>( let mut err = struct_span_code_err!( tcx.dcx(), impl_span, - E0805, + E0806, "`{external_impl_name}` has {} but #[{eii_name}] requires it to have {}", potentially_plural_count(external_impl_number_args, "parameter"), declaration_number_args @@ -333,7 +333,7 @@ fn report_eii_mismatch<'tcx>( let mut diag = struct_span_code_err!( tcx.dcx(), impl_err_span, - E0805, + E0806, "function `{}` has a type that is incompatible with the declaration of `#[{eii_name}]`", external_impl_name ); diff --git a/tests/ui/error-codes/E0806.rs b/tests/ui/error-codes/E0806.rs new file mode 100644 index 000000000000..168c7120fc17 --- /dev/null +++ b/tests/ui/error-codes/E0806.rs @@ -0,0 +1,12 @@ +#![feature(eii)] + +#[eii(foo)] +fn x(); + +#[foo] +fn y(a: u64) -> u64 { + //~^ ERROR E0806 + a +} + +fn main() {} diff --git a/tests/ui/error-codes/E0806.stderr b/tests/ui/error-codes/E0806.stderr new file mode 100644 index 000000000000..ab6ba45185df --- /dev/null +++ b/tests/ui/error-codes/E0806.stderr @@ -0,0 +1,14 @@ +error[E0806]: `y` has 1 parameter but #[foo] requires it to have 0 + --> $DIR/E0806.rs:7:9 + | +LL | fn x(); + | ------- requires 0 parameters +LL | +LL | #[foo] + | ------ required because of this attribute +LL | fn y(a: u64) -> u64 { + | ^^^ expected 0 parameters, found 1 + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0806`. From a63f10a827bd58c953b97c5d3e9a04173f89127a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 21 Aug 2025 13:30:55 +0200 Subject: [PATCH 0660/3801] EII liveness analysis From 9bd6b7ff7239f55a859552ce69f19bcde475f5ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 29 Aug 2025 08:37:44 +0200 Subject: [PATCH 0661/3801] EII: generate aliases for implementations --- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 8 ++++ compiler/rustc_codegen_llvm/src/llvm/mod.rs | 13 +++++- compiler/rustc_codegen_llvm/src/mono_item.rs | 27 ++++++++++++ .../rustc_codegen_ssa/src/codegen_attrs.rs | 42 +++++++++++++++++-- .../src/middle/codegen_fn_attrs.rs | 8 ++++ compiler/rustc_middle/src/mir/mono.rs | 2 +- 6 files changed, 95 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index c5cbc92ae772..8abf8b24d9d6 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2583,4 +2583,12 @@ unsafe extern "C" { pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value); pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value); + + pub(crate) fn LLVMAddAlias2<'ll>( + M: &'ll Module, + ValueTy: &Type, + AddressSpace: c_uint, + Aliasee: &Value, + Name: *const c_char, + ) -> &'ll Value; } diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 55a4b415a4e2..621004e756ec 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -6,7 +6,7 @@ use std::ptr; use std::string::FromUtf8Error; use libc::c_uint; -use rustc_abi::{Align, Size, WrappingRange}; +use rustc_abi::{AddressSpace, Align, Size, WrappingRange}; use rustc_llvm::RustString; pub(crate) use self::CallConv::*; @@ -452,3 +452,14 @@ pub(crate) fn append_module_inline_asm<'ll>(llmod: &'ll Module, asm: &[u8]) { LLVMAppendModuleInlineAsm(llmod, asm.as_ptr(), asm.len()); } } + +/// Safe wrapper for `LLVMAddAlias2` +pub(crate) fn add_alias<'ll>( + module: &'ll Module, + ty: &Type, + address_space: AddressSpace, + aliasee: &Value, + name: &CStr, +) -> &'ll Value { + unsafe { LLVMAddAlias2(module, ty, address_space.0, aliasee, name.as_ptr()) } +} diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 4184ced74962..41cf92390b0d 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -1,3 +1,6 @@ +use std::ffi::CString; + +use rustc_abi::AddressSpace; use rustc_codegen_ssa::traits::*; use rustc_hir::attrs::Linkage; use rustc_hir::def::DefKind; @@ -7,6 +10,7 @@ use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use rustc_session::config::CrateType; +use rustc_span::Symbol; use rustc_target::spec::{Arch, RelocModel}; use tracing::debug; @@ -41,6 +45,9 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { llvm::set_visibility(g, base::visibility_to_llvm(visibility)); self.assume_dso_local(g, false); + let attrs = self.tcx.codegen_instance_attrs(instance.def); + self.add_aliases(g, &attrs.foreign_item_symbol_aliases); + self.instances.borrow_mut().insert(instance, g); } @@ -78,11 +85,31 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { self.assume_dso_local(lldecl, false); + self.add_aliases(lldecl, &attrs.foreign_item_symbol_aliases); + self.instances.borrow_mut().insert(instance, lldecl); } } impl CodegenCx<'_, '_> { + fn add_aliases(&self, aliasee: &llvm::Value, aliases: &[(Symbol, Linkage, Visibility)]) { + let ty = self.get_type_of_global(aliasee); + + for (alias, linkage, visibility) in aliases { + tracing::debug!("ALIAS: {alias:?} {linkage:?} {visibility:?}"); + let lldecl = llvm::add_alias( + self.llmod, + ty, + AddressSpace::ZERO, + aliasee, + &CString::new(alias.as_str()).unwrap(), + ); + + llvm::set_visibility(lldecl, base::visibility_to_llvm(*visibility)); + llvm::set_linkage(lldecl, base::linkage_to_llvm(*linkage)); + } + } + /// Whether a definition or declaration can be assumed to be local to a group of /// libraries that form a single DSO or executable. /// Marks the local as DSO if so. diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 0ab0cb0ef88a..0c409cef298a 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -3,19 +3,22 @@ use std::str::FromStr; use rustc_abi::{Align, ExternAbi}; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr}; -use rustc_hir::attrs::{AttributeKind, InlineAttr, InstructionSetAttr, RtsanSetting, UsedBy}; +use rustc_hir::attrs::{ + AttributeKind, InlineAttr, InstructionSetAttr, Linkage, RtsanSetting, UsedBy, +}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items}; use rustc_middle::middle::codegen_fn_attrs::{ CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, }; +use rustc_middle::mir::mono::Visibility; use rustc_middle::query::Providers; use rustc_middle::span_bug; -use rustc_middle::ty::{self as ty, TyCtxt}; +use rustc_middle::ty::{self as ty, Instance, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; -use rustc_span::{Ident, Span, sym}; +use rustc_span::{Ident, Span, Symbol, sym}; use rustc_target::spec::Os; use crate::errors; @@ -310,6 +313,39 @@ fn process_builtin_attrs( AttributeKind::ObjcSelector { methname, .. } => { codegen_fn_attrs.objc_selector = Some(*methname); } + AttributeKind::EiiImpls(impls) => { + for i in impls { + let extern_item = find_attr!( + tcx.get_all_attrs(i.eii_macro), + AttributeKind::EiiExternTarget(target) => target.eii_extern_target + ) + .expect("eii should have declaration macro with extern target attribute"); + + let symbol_name = tcx.symbol_name(Instance::mono(tcx, extern_item)); + + // this is to prevent a bug where a single crate defines both the default and explicit implementation + // for an EII. In that case, both of them may be part of the same final object file. I'm not 100% sure + // what happens, either rustc deduplicates the symbol or llvm, or it's random/order-dependent. + // However, the fact that the default one of has weak linkage isn't considered and you sometimes get that + // the default implementation is used while an explicit implementation is given. + if + // if this is a default impl + i.is_default + // iterate over all implementations *in the current crate* + // (this is ok since we generate codegen fn attrs in the local crate) + // if any of them is *not default* then don't emit the alias. + && tcx.externally_implementable_items(LOCAL_CRATE).get(&i.eii_macro).expect("at least one").1.iter().any(|(_, imp)| !imp.is_default) + { + continue; + } + + codegen_fn_attrs.foreign_item_symbol_aliases.push(( + Symbol::intern(symbol_name.name), + if i.is_default { Linkage::LinkOnceAny } else { Linkage::External }, + Visibility::Default, + )); + } + } _ => {} } } diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 9630cfc94b43..7922cc38aaab 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -6,6 +6,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; +use crate::mir::mono::Visibility; use crate::ty::{InstanceKind, TyCtxt}; impl<'tcx> TyCtxt<'tcx> { @@ -62,6 +63,12 @@ pub struct CodegenFnAttrs { /// using the `#[export_name = "..."]` or `#[link_name = "..."]` attribute /// depending on if this is a function definition or foreign function. pub symbol_name: Option, + /// Defids of foreign items somewhere that this function should "satisfy". + /// i.e., if a foreign function has some symbol foo, + /// generate this function under its real name, + /// but *also* under the same name as this foreign function so that the foreign function has an implementation. + // FIXME: make "SymbolName<'tcx>" + pub foreign_item_symbol_aliases: Vec<(Symbol, Linkage, Visibility)>, /// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an /// imported function has in the dynamic library. Note that this must not /// be set when `link_name` is set. This is for foreign items with the @@ -207,6 +214,7 @@ impl CodegenFnAttrs { symbol_name: None, link_ordinal: None, target_features: vec![], + foreign_item_symbol_aliases: vec![], safe_target_features: false, linkage: None, import_linkage: None, diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index a499f149a42b..c7ced84a527f 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -374,7 +374,7 @@ pub struct MonoItemData { /// Visibility doesn't have any effect when linkage is internal. /// /// DSO means dynamic shared object, that is a dynamically linked executable or dylib. -#[derive(Copy, Clone, PartialEq, Debug, HashStable)] +#[derive(Copy, Clone, PartialEq, Debug, HashStable, TyEncodable, TyDecodable)] pub enum Visibility { /// Export the symbol from the DSO and apply overrides of the symbol by outside DSOs to within /// the DSO if the object file format supports this. From f7e453e2fa406d0397712ee36da34d526cb46810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 8 Sep 2025 13:24:42 -0700 Subject: [PATCH 0662/3801] visibility using std_internal_symbol --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 1 + compiler/rustc_passes/src/reachable.rs | 14 +++++++++++++- compiler/rustc_resolve/src/check_unused.rs | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 0c409cef298a..6aea249d6356 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -344,6 +344,7 @@ fn process_builtin_attrs( if i.is_default { Linkage::LinkOnceAny } else { Linkage::External }, Visibility::Default, )); + codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; } } _ => {} diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index acb64bc6990b..b9323e91ca83 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -184,7 +184,13 @@ impl<'tcx> ReachableContext<'tcx> { CodegenFnAttrs::EMPTY }; let is_extern = codegen_attrs.contains_extern_indicator(); - if is_extern { + // Right now, the only way to get "foreign item symbol aliases" is by being an EII-implementation. + // EII implementations will generate under their own name but also under the name of some foreign item + // (hence alias) that may be in another crate. These functions are marked as always-reachable since + // it's very hard to track whether the original foreign item was reachable. It may live in another crate + // and may be reachable from sibling crates. + let has_foreign_aliases_eii = !codegen_attrs.foreign_item_symbol_aliases.is_empty(); + if is_extern || has_foreign_aliases_eii { self.reachable_symbols.insert(search_item); } } else { @@ -429,6 +435,12 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { // `SymbolExportLevel::Rust` export level but may end up being exported in dylibs. || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) + // Right now, the only way to get "foreign item symbol aliases" is by being an EII-implementation. + // EII implementations will generate under their own name but also under the name of some foreign item + // (hence alias) that may be in another crate. These functions are marked as always-reachable since + // it's very hard to track whether the original foreign item was reachable. It may live in another crate + // and may be reachable from sibling crates. + || !codegen_attrs.foreign_item_symbol_aliases.is_empty() } /// See module-level doc comment above. diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 0aaea96348b5..5349cf6d7dbe 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -422,6 +422,7 @@ impl Resolver<'_, '_> { && !tcx.is_panic_runtime(cnum) && !tcx.has_global_allocator(cnum) && !tcx.has_panic_handler(cnum) + && tcx.externally_implementable_items(cnum).is_empty() }) { maybe_unused_extern_crates.insert(id, import.span); } From 3cf74cb2a4e4c00873e31954f849956d49903fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 27 Oct 2025 11:46:02 +0100 Subject: [PATCH 0663/3801] disable gcc for now --- tests/ui/eii/codegen_cross_crate.rs | 1 + tests/ui/eii/codegen_single_crate.rs | 1 + tests/ui/eii/default/call_default.rs | 1 + tests/ui/eii/default/call_impl.rs | 1 + tests/ui/eii/default/local_crate.rs | 1 + tests/ui/eii/default/local_crate_explicit.rs | 1 + tests/ui/eii/duplicate/duplicate1.rs | 1 + tests/ui/eii/duplicate/duplicate2.rs | 1 + tests/ui/eii/duplicate/duplicate3.rs | 1 + tests/ui/eii/privacy1.rs | 1 + 10 files changed, 10 insertions(+) diff --git a/tests/ui/eii/codegen_cross_crate.rs b/tests/ui/eii/codegen_cross_crate.rs index b5b2d940b730..ccce32e0eb3e 100644 --- a/tests/ui/eii/codegen_cross_crate.rs +++ b/tests/ui/eii/codegen_cross_crate.rs @@ -2,6 +2,7 @@ //@ check-run-results //@ aux-build: codegen2.rs //@ compile-flags: -O +//@ ignore-backends: gcc // Tests whether calling EIIs works with the declaration in another crate. #![feature(eii)] diff --git a/tests/ui/eii/codegen_single_crate.rs b/tests/ui/eii/codegen_single_crate.rs index c2d986d12c1a..4172f59b0df6 100644 --- a/tests/ui/eii/codegen_single_crate.rs +++ b/tests/ui/eii/codegen_single_crate.rs @@ -1,5 +1,6 @@ //@ run-pass //@ check-run-results +//@ ignore-backends: gcc // Tests whether calling EIIs works with the declaration in the same crate. #![feature(eii)] diff --git a/tests/ui/eii/default/call_default.rs b/tests/ui/eii/default/call_default.rs index 520863f1d3e9..3557e1cdac12 100644 --- a/tests/ui/eii/default/call_default.rs +++ b/tests/ui/eii/default/call_default.rs @@ -2,6 +2,7 @@ //@ aux-build: decl_with_default.rs //@ run-pass //@ check-run-results +//@ ignore-backends: gcc // Tests EIIs with default implementations. // When there's no explicit declaration, the default should be called from the declaring crate. #![feature(eii)] diff --git a/tests/ui/eii/default/call_impl.rs b/tests/ui/eii/default/call_impl.rs index b81e604238ec..1bb37f30f027 100644 --- a/tests/ui/eii/default/call_impl.rs +++ b/tests/ui/eii/default/call_impl.rs @@ -3,6 +3,7 @@ //@ aux-build: impl1.rs //@ run-pass //@ check-run-results +//@ ignore-backends: gcc // Tests EIIs with default implementations. // When an explicit implementation is given in one dependency, and the declaration is in another, // the explicit implementation is preferred. diff --git a/tests/ui/eii/default/local_crate.rs b/tests/ui/eii/default/local_crate.rs index 9ae471d90cbc..74e90fdc273d 100644 --- a/tests/ui/eii/default/local_crate.rs +++ b/tests/ui/eii/default/local_crate.rs @@ -1,5 +1,6 @@ //@ run-pass //@ check-run-results +//@ ignore-backends: gcc // Tests EIIs with default implementations. // In the same crate, when there's no explicit declaration, the default should be called. #![feature(eii)] diff --git a/tests/ui/eii/default/local_crate_explicit.rs b/tests/ui/eii/default/local_crate_explicit.rs index 844d1d2911af..d671d8e70c97 100644 --- a/tests/ui/eii/default/local_crate_explicit.rs +++ b/tests/ui/eii/default/local_crate_explicit.rs @@ -1,5 +1,6 @@ //@ run-pass //@ check-run-results +//@ ignore-backends: gcc // Tests EIIs with default implementations. // In the same crate, the explicit implementation should get priority. #![feature(eii)] diff --git a/tests/ui/eii/duplicate/duplicate1.rs b/tests/ui/eii/duplicate/duplicate1.rs index 921270fe3d48..5573f47472a7 100644 --- a/tests/ui/eii/duplicate/duplicate1.rs +++ b/tests/ui/eii/duplicate/duplicate1.rs @@ -1,6 +1,7 @@ //@ no-prefer-dynamic //@ aux-build: impl1.rs //@ aux-build: impl2.rs +//@ ignore-backends: gcc // tests that EIIs error properly, even if the conflicting implementations live in another crate. #![feature(eii)] diff --git a/tests/ui/eii/duplicate/duplicate2.rs b/tests/ui/eii/duplicate/duplicate2.rs index 8355b8f7bc70..d2bb1856565a 100644 --- a/tests/ui/eii/duplicate/duplicate2.rs +++ b/tests/ui/eii/duplicate/duplicate2.rs @@ -2,6 +2,7 @@ //@ aux-build: impl1.rs //@ aux-build: impl2.rs //@ aux-build: impl3.rs +//@ ignore-backends: gcc // Tests the error message when there are multiple implementations of an EII in many crates. #![feature(eii)] diff --git a/tests/ui/eii/duplicate/duplicate3.rs b/tests/ui/eii/duplicate/duplicate3.rs index b967fb8b4903..2cd51268a6fb 100644 --- a/tests/ui/eii/duplicate/duplicate3.rs +++ b/tests/ui/eii/duplicate/duplicate3.rs @@ -3,6 +3,7 @@ //@ aux-build: impl2.rs //@ aux-build: impl3.rs //@ aux-build: impl4.rs +//@ ignore-backends: gcc // Tests the error message when there are multiple implementations of an EII in many crates. #![feature(eii)] diff --git a/tests/ui/eii/privacy1.rs b/tests/ui/eii/privacy1.rs index 7dd87a5b7ce4..64b35f7a070d 100644 --- a/tests/ui/eii/privacy1.rs +++ b/tests/ui/eii/privacy1.rs @@ -1,6 +1,7 @@ //@ run-pass //@ check-run-results //@ aux-build: codegen1.rs +//@ ignore-backends: gcc // Tests whether re-exports work. #![feature(eii)] From f4fd8a063369bbadc99cffb0a646deb96c0db151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 3 Nov 2025 16:06:58 +0100 Subject: [PATCH 0664/3801] experiment query caching --- compiler/rustc_middle/src/query/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 9b4306f656d6..676f0d82e4fb 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2759,9 +2759,10 @@ rustc_queries! { } /// Returns a list of all `externally implementable items` crate. - query externally_implementable_items(_: CrateNum) -> &'tcx FxIndexMap)> { + query externally_implementable_items(cnum: CrateNum) -> &'tcx FxIndexMap)> { arena_cache desc { "looking up the externally implementable items of a crate" } + cache_on_disk_if { *cnum == LOCAL_CRATE } separate_provide_extern } } From 52e0bfccb08b5ae9957532518221e7e748ca590c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 1 Dec 2025 17:17:06 +0100 Subject: [PATCH 0665/3801] rename feature gate to extern_item_impls --- compiler/rustc_error_codes/src/error_codes/E0806.md | 4 ++-- compiler/rustc_feature/src/unstable.rs | 4 ++-- compiler/rustc_span/src/symbol.rs | 2 +- library/core/src/macros/mod.rs | 4 ++-- library/core/src/prelude/v1.rs | 2 +- library/std/src/prelude/v1.rs | 2 +- tests/ui/eii/auxiliary/codegen1.rs | 2 +- tests/ui/eii/auxiliary/codegen2.rs | 2 +- tests/ui/eii/auxiliary/codegen3.rs | 2 +- tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs | 2 +- tests/ui/eii/codegen_cross_crate.rs | 2 +- tests/ui/eii/codegen_single_crate.rs | 2 +- tests/ui/eii/cross_crate.rs | 2 +- tests/ui/eii/cross_crate_wrong_ty.rs | 2 +- tests/ui/eii/default/auxiliary/decl_with_default.rs | 2 +- tests/ui/eii/default/auxiliary/impl1.rs | 2 +- tests/ui/eii/default/call_default.rs | 2 +- tests/ui/eii/default/call_impl.rs | 2 +- tests/ui/eii/default/local_crate.rs | 2 +- tests/ui/eii/default/local_crate_explicit.rs | 2 +- tests/ui/eii/duplicate/auxiliary/decl.rs | 2 +- tests/ui/eii/duplicate/auxiliary/impl1.rs | 2 +- tests/ui/eii/duplicate/auxiliary/impl2.rs | 2 +- tests/ui/eii/duplicate/auxiliary/impl3.rs | 2 +- tests/ui/eii/duplicate/auxiliary/impl4.rs | 2 +- tests/ui/eii/duplicate/duplicate1.rs | 2 +- tests/ui/eii/duplicate/duplicate2.rs | 2 +- tests/ui/eii/duplicate/duplicate3.rs | 2 +- tests/ui/eii/errors.rs | 2 +- tests/ui/eii/multiple_decls.rs | 2 +- tests/ui/eii/multiple_impls.rs | 2 +- tests/ui/eii/privacy1.rs | 2 +- tests/ui/eii/privacy2.rs | 2 +- tests/ui/eii/subtype_1.rs | 2 +- tests/ui/eii/subtype_2.rs | 2 +- tests/ui/eii/subtype_3.rs | 2 +- tests/ui/eii/subtype_4.rs | 2 +- tests/ui/eii/unsafe_impl_err.rs | 2 +- tests/ui/eii/unsafe_impl_ok.rs | 2 +- tests/ui/eii/wrong_ret_ty.rs | 2 +- tests/ui/eii/wrong_target.rs | 2 +- tests/ui/eii/wrong_ty.rs | 2 +- tests/ui/eii/wrong_ty_2.rs | 2 +- tests/ui/error-codes/E0806.rs | 2 +- ...eature-gate-eii.rs => feature-gate-extern-item-impls.rs} | 2 +- ...ate-eii.stderr => feature-gate-extern-item-impls.stderr} | 6 +++--- 46 files changed, 51 insertions(+), 51 deletions(-) rename tests/ui/feature-gates/{feature-gate-eii.rs => feature-gate-extern-item-impls.rs} (59%) rename tests/ui/feature-gates/{feature-gate-eii.stderr => feature-gate-extern-item-impls.stderr} (63%) diff --git a/compiler/rustc_error_codes/src/error_codes/E0806.md b/compiler/rustc_error_codes/src/error_codes/E0806.md index 9de1bb5891fa..e4a89b92354f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0806.md +++ b/compiler/rustc_error_codes/src/error_codes/E0806.md @@ -3,7 +3,7 @@ An externally implementable item is not compatible with its declaration. Erroneous code example: ```rust,edition2021,compile_fail,E0806 -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(foo)] fn x(); @@ -25,7 +25,7 @@ that of the declaration of `foo`. So, to fix this, `y`'s signature must be changed to match that of `x`: ```rust,edition2021 -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(foo)] fn x(); diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 1568edd275bb..fe053935f9e6 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -493,8 +493,6 @@ declare_features! ( (unstable, doc_masked, "1.21.0", Some(44027)), /// Allows features to allow target_feature to better interact with traits. (incomplete, effective_target_features, "1.91.0", Some(143352)), - /// Externally implementatble items - (unstable, extern_item_impls, "CURRENT_RUSTC_VERSION", Some(125418)), /// Allows the .use postfix syntax `x.use` and use closures `use |x| { ... }` (incomplete, ergonomic_clones, "1.87.0", Some(132290)), /// Allows exhaustive pattern matching on types that contain uninhabited types. @@ -505,6 +503,8 @@ declare_features! ( (incomplete, explicit_tail_calls, "1.72.0", Some(112788)), /// Allows using `#[export_stable]` which indicates that an item is exportable. (incomplete, export_stable, "1.88.0", Some(139939)), + /// Externally implementatble items + (unstable, extern_item_impls, "CURRENT_RUSTC_VERSION", Some(125418)), /// Allows defining `extern type`s. (unstable, extern_types, "1.23.0", Some(43467)), /// Allow using 128-bit (quad precision) floating point numbers. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c609e00b8df7..8f43a31ea4b1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -933,7 +933,6 @@ symbols! { eii_extern_target, eii_impl, eii_internals, - extern_item_impls, eii_shared_macro, emit, emit_enum, @@ -994,6 +993,7 @@ symbols! { extern_crate_item_prelude, extern_crate_self, extern_in_paths, + extern_item_impls, extern_prelude, extern_system_varargs, extern_types, diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 68b5b2d1efc6..a12ee60277f0 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1893,7 +1893,7 @@ pub(crate) mod builtin { /// Externally Implementable Item: Defines an attribute macro that can override the item /// this is applied to. - #[unstable(feature = "eii", issue = "125418")] + #[unstable(feature = "extern_item_impls", issue = "125418")] #[rustc_builtin_macro] #[allow_internal_unstable(eii_internals, decl_macro, rustc_attrs)] pub macro eii($item:item) { @@ -1902,7 +1902,7 @@ pub(crate) mod builtin { /// Unsafely Externally Implementable Item: Defines an unsafe attribute macro that can override /// the item this is applied to. - #[unstable(feature = "eii", issue = "125418")] + #[unstable(feature = "extern_item_impls", issue = "125418")] #[rustc_builtin_macro] #[allow_internal_unstable(eii_internals, decl_macro, rustc_attrs)] pub macro unsafe_eii($item:item) { diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 3446f04a6429..977fd1926fd0 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -125,7 +125,7 @@ pub use crate::macros::builtin::define_opaque; )] pub use crate::macros::builtin::From; -#[unstable(feature = "eii", issue = "125418")] +#[unstable(feature = "extern_item_impls", issue = "125418")] pub use crate::macros::builtin::{eii, unsafe_eii}; #[unstable(feature = "eii_internals", issue = "none")] diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 6c2f5f108f1a..63f75ea8a881 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -110,7 +110,7 @@ pub use core::prelude::v1::deref; )] pub use core::prelude::v1::define_opaque; -#[unstable(feature = "eii", issue = "125418")] +#[unstable(feature = "extern_item_impls", issue = "125418")] pub use core::prelude::v1::{eii, unsafe_eii}; #[unstable(feature = "eii_internals", issue = "none")] diff --git a/tests/ui/eii/auxiliary/codegen1.rs b/tests/ui/eii/auxiliary/codegen1.rs index 93c5df2d41c0..41160cd1fe39 100644 --- a/tests/ui/eii/auxiliary/codegen1.rs +++ b/tests/ui/eii/auxiliary/codegen1.rs @@ -1,6 +1,6 @@ //@ no-prefer-dynamic #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(eii1)] fn decl1(x: u64); diff --git a/tests/ui/eii/auxiliary/codegen2.rs b/tests/ui/eii/auxiliary/codegen2.rs index 9545ad007c57..7e0ba5f971c3 100644 --- a/tests/ui/eii/auxiliary/codegen2.rs +++ b/tests/ui/eii/auxiliary/codegen2.rs @@ -1,6 +1,6 @@ //@ no-prefer-dynamic #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(eii1)] pub fn decl1(x: u64); diff --git a/tests/ui/eii/auxiliary/codegen3.rs b/tests/ui/eii/auxiliary/codegen3.rs index 2b882c48d829..9fb19298f09f 100644 --- a/tests/ui/eii/auxiliary/codegen3.rs +++ b/tests/ui/eii/auxiliary/codegen3.rs @@ -1,6 +1,6 @@ //@ no-prefer-dynamic #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] // does have an impl but can't be called #[eii(eii1)] diff --git a/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs b/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs index 3147d91bbee8..40d0222082d5 100644 --- a/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs +++ b/tests/ui/eii/auxiliary/cross_crate_eii_declaration.rs @@ -1,6 +1,6 @@ //@ no-prefer-dynamic #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/codegen_cross_crate.rs b/tests/ui/eii/codegen_cross_crate.rs index ccce32e0eb3e..760c960297e0 100644 --- a/tests/ui/eii/codegen_cross_crate.rs +++ b/tests/ui/eii/codegen_cross_crate.rs @@ -4,7 +4,7 @@ //@ compile-flags: -O //@ ignore-backends: gcc // Tests whether calling EIIs works with the declaration in another crate. -#![feature(eii)] +#![feature(extern_item_impls)] extern crate codegen2 as codegen; diff --git a/tests/ui/eii/codegen_single_crate.rs b/tests/ui/eii/codegen_single_crate.rs index 4172f59b0df6..00e0abca65f3 100644 --- a/tests/ui/eii/codegen_single_crate.rs +++ b/tests/ui/eii/codegen_single_crate.rs @@ -2,7 +2,7 @@ //@ check-run-results //@ ignore-backends: gcc // Tests whether calling EIIs works with the declaration in the same crate. -#![feature(eii)] +#![feature(extern_item_impls)] #[eii] fn hello(x: u64); diff --git a/tests/ui/eii/cross_crate.rs b/tests/ui/eii/cross_crate.rs index 72f1533587bf..157d659bfd64 100644 --- a/tests/ui/eii/cross_crate.rs +++ b/tests/ui/eii/cross_crate.rs @@ -2,7 +2,7 @@ //@ check-pass //@ aux-build: cross_crate_eii_declaration.rs // Tests whether calling EIIs works with the declaration in another crate. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/cross_crate_wrong_ty.rs b/tests/ui/eii/cross_crate_wrong_ty.rs index f99b812b6c50..7ae1a5995a86 100644 --- a/tests/ui/eii/cross_crate_wrong_ty.rs +++ b/tests/ui/eii/cross_crate_wrong_ty.rs @@ -1,7 +1,7 @@ //@ compile-flags: --crate-type rlib //@ aux-build: cross_crate_eii_declaration.rs // Tests whether the type checking still works properly when the declaration is in another crate. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/default/auxiliary/decl_with_default.rs b/tests/ui/eii/default/auxiliary/decl_with_default.rs index b1811b07eb17..8d962c19c94d 100644 --- a/tests/ui/eii/default/auxiliary/decl_with_default.rs +++ b/tests/ui/eii/default/auxiliary/decl_with_default.rs @@ -1,6 +1,6 @@ //@ no-prefer-dynamic #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(eii1)] pub fn decl1(x: u64) { diff --git a/tests/ui/eii/default/auxiliary/impl1.rs b/tests/ui/eii/default/auxiliary/impl1.rs index 4d627a5f68a6..3510ea1eb3f2 100644 --- a/tests/ui/eii/default/auxiliary/impl1.rs +++ b/tests/ui/eii/default/auxiliary/impl1.rs @@ -1,7 +1,7 @@ //@ no-prefer-dynamic //@ aux-build: decl_with_default.rs #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] extern crate decl_with_default as decl; diff --git a/tests/ui/eii/default/call_default.rs b/tests/ui/eii/default/call_default.rs index 3557e1cdac12..90c56be78f13 100644 --- a/tests/ui/eii/default/call_default.rs +++ b/tests/ui/eii/default/call_default.rs @@ -5,7 +5,7 @@ //@ ignore-backends: gcc // Tests EIIs with default implementations. // When there's no explicit declaration, the default should be called from the declaring crate. -#![feature(eii)] +#![feature(extern_item_impls)] extern crate decl_with_default; diff --git a/tests/ui/eii/default/call_impl.rs b/tests/ui/eii/default/call_impl.rs index 1bb37f30f027..2e1cd5e7a966 100644 --- a/tests/ui/eii/default/call_impl.rs +++ b/tests/ui/eii/default/call_impl.rs @@ -7,7 +7,7 @@ // Tests EIIs with default implementations. // When an explicit implementation is given in one dependency, and the declaration is in another, // the explicit implementation is preferred. -#![feature(eii)] +#![feature(extern_item_impls)] extern crate decl_with_default; extern crate impl1; diff --git a/tests/ui/eii/default/local_crate.rs b/tests/ui/eii/default/local_crate.rs index 74e90fdc273d..f229f3cabf0c 100644 --- a/tests/ui/eii/default/local_crate.rs +++ b/tests/ui/eii/default/local_crate.rs @@ -3,7 +3,7 @@ //@ ignore-backends: gcc // Tests EIIs with default implementations. // In the same crate, when there's no explicit declaration, the default should be called. -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(eii1)] pub fn decl1(x: u64) { diff --git a/tests/ui/eii/default/local_crate_explicit.rs b/tests/ui/eii/default/local_crate_explicit.rs index d671d8e70c97..e9d879b61c92 100644 --- a/tests/ui/eii/default/local_crate_explicit.rs +++ b/tests/ui/eii/default/local_crate_explicit.rs @@ -3,7 +3,7 @@ //@ ignore-backends: gcc // Tests EIIs with default implementations. // In the same crate, the explicit implementation should get priority. -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(eii1)] pub fn decl1(x: u64) { diff --git a/tests/ui/eii/duplicate/auxiliary/decl.rs b/tests/ui/eii/duplicate/auxiliary/decl.rs index 81557fa6891b..2a0661715bfd 100644 --- a/tests/ui/eii/duplicate/auxiliary/decl.rs +++ b/tests/ui/eii/duplicate/auxiliary/decl.rs @@ -1,6 +1,6 @@ //@ no-prefer-dynamic #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(eii1)] fn decl1(x: u64); diff --git a/tests/ui/eii/duplicate/auxiliary/impl1.rs b/tests/ui/eii/duplicate/auxiliary/impl1.rs index d7c27f4dfde9..e99932c69b90 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl1.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl1.rs @@ -1,7 +1,7 @@ //@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] extern crate decl; diff --git a/tests/ui/eii/duplicate/auxiliary/impl2.rs b/tests/ui/eii/duplicate/auxiliary/impl2.rs index bce6f11b89c4..3a09c824b829 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl2.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl2.rs @@ -1,7 +1,7 @@ //@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] extern crate decl; diff --git a/tests/ui/eii/duplicate/auxiliary/impl3.rs b/tests/ui/eii/duplicate/auxiliary/impl3.rs index 82ba5af09863..09bdd8509da2 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl3.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl3.rs @@ -1,7 +1,7 @@ //@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] extern crate decl; diff --git a/tests/ui/eii/duplicate/auxiliary/impl4.rs b/tests/ui/eii/duplicate/auxiliary/impl4.rs index 5275da1b1433..fd68a83de125 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl4.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl4.rs @@ -1,7 +1,7 @@ //@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] -#![feature(eii)] +#![feature(extern_item_impls)] extern crate decl; diff --git a/tests/ui/eii/duplicate/duplicate1.rs b/tests/ui/eii/duplicate/duplicate1.rs index 5573f47472a7..2e12d700b0a6 100644 --- a/tests/ui/eii/duplicate/duplicate1.rs +++ b/tests/ui/eii/duplicate/duplicate1.rs @@ -3,7 +3,7 @@ //@ aux-build: impl2.rs //@ ignore-backends: gcc // tests that EIIs error properly, even if the conflicting implementations live in another crate. -#![feature(eii)] +#![feature(extern_item_impls)] // has a span but in the other crate //~? ERROR multiple implementations of `#[eii1]` diff --git a/tests/ui/eii/duplicate/duplicate2.rs b/tests/ui/eii/duplicate/duplicate2.rs index d2bb1856565a..157871d2a3db 100644 --- a/tests/ui/eii/duplicate/duplicate2.rs +++ b/tests/ui/eii/duplicate/duplicate2.rs @@ -4,7 +4,7 @@ //@ aux-build: impl3.rs //@ ignore-backends: gcc // Tests the error message when there are multiple implementations of an EII in many crates. -#![feature(eii)] +#![feature(extern_item_impls)] // has a span but in the other crate //~? ERROR multiple implementations of `#[eii1]` diff --git a/tests/ui/eii/duplicate/duplicate3.rs b/tests/ui/eii/duplicate/duplicate3.rs index 2cd51268a6fb..5ac5ae7ff3d4 100644 --- a/tests/ui/eii/duplicate/duplicate3.rs +++ b/tests/ui/eii/duplicate/duplicate3.rs @@ -5,7 +5,7 @@ //@ aux-build: impl4.rs //@ ignore-backends: gcc // Tests the error message when there are multiple implementations of an EII in many crates. -#![feature(eii)] +#![feature(extern_item_impls)] // has a span but in the other crate //~? ERROR multiple implementations of `#[eii1]` diff --git a/tests/ui/eii/errors.rs b/tests/ui/eii/errors.rs index ec365b0e9d16..d59850a7d5f5 100644 --- a/tests/ui/eii/errors.rs +++ b/tests/ui/eii/errors.rs @@ -1,6 +1,6 @@ //@ compile-flags: --crate-type rlib // Tests all the kinds of errors when EII attributes are used with wrong syntax. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/multiple_decls.rs b/tests/ui/eii/multiple_decls.rs index 63ef269d7818..f7646630cab4 100644 --- a/tests/ui/eii/multiple_decls.rs +++ b/tests/ui/eii/multiple_decls.rs @@ -1,5 +1,5 @@ // Tests whether only one EII attribute cane be applied to a signature. -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(a)] #[eii(b)] diff --git a/tests/ui/eii/multiple_impls.rs b/tests/ui/eii/multiple_impls.rs index 7f6691791410..ec3244137390 100644 --- a/tests/ui/eii/multiple_impls.rs +++ b/tests/ui/eii/multiple_impls.rs @@ -2,7 +2,7 @@ //@ check-run-results //@ ignore-backends: gcc // Tests whether one function could implement two EIIs. -#![feature(eii)] +#![feature(extern_item_impls)] #[eii] fn a(x: u64); diff --git a/tests/ui/eii/privacy1.rs b/tests/ui/eii/privacy1.rs index 64b35f7a070d..fc13a27c061e 100644 --- a/tests/ui/eii/privacy1.rs +++ b/tests/ui/eii/privacy1.rs @@ -3,7 +3,7 @@ //@ aux-build: codegen1.rs //@ ignore-backends: gcc // Tests whether re-exports work. -#![feature(eii)] +#![feature(extern_item_impls)] extern crate codegen1 as codegen; diff --git a/tests/ui/eii/privacy2.rs b/tests/ui/eii/privacy2.rs index 702773fb5c78..a4ae188bd0ec 100644 --- a/tests/ui/eii/privacy2.rs +++ b/tests/ui/eii/privacy2.rs @@ -1,6 +1,6 @@ //@ aux-build:codegen3.rs // Tests whether name resulution respects privacy properly. -#![feature(eii)] +#![feature(extern_item_impls)] extern crate codegen3 as codegen; diff --git a/tests/ui/eii/subtype_1.rs b/tests/ui/eii/subtype_1.rs index 8c58a5d7fac2..dfb998aa6f66 100644 --- a/tests/ui/eii/subtype_1.rs +++ b/tests/ui/eii/subtype_1.rs @@ -1,7 +1,7 @@ //@ compile-flags: --crate-type rlib // Uses manual desugaring of EII internals: // Tests whether it's not ok when the lifetimes are different between the decl and impl. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/subtype_2.rs b/tests/ui/eii/subtype_2.rs index 0453286a19c5..5f0c5553fccc 100644 --- a/tests/ui/eii/subtype_2.rs +++ b/tests/ui/eii/subtype_2.rs @@ -1,7 +1,7 @@ //@ compile-flags: --crate-type rlib // Uses manual desugaring of EII internals: // Tests whether it's not ok when the implementation is less general. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/subtype_3.rs b/tests/ui/eii/subtype_3.rs index 39d232e27c5b..269bc84df744 100644 --- a/tests/ui/eii/subtype_3.rs +++ b/tests/ui/eii/subtype_3.rs @@ -2,7 +2,7 @@ //@ check-pass // Uses manual desugaring of EII internals: // Tests whether it's ok when the implementation is more general. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/subtype_4.rs b/tests/ui/eii/subtype_4.rs index c55030238e75..e9194df7584c 100644 --- a/tests/ui/eii/subtype_4.rs +++ b/tests/ui/eii/subtype_4.rs @@ -2,7 +2,7 @@ //@ check-pass // Uses manual desugaring of EII internals: // Tests whether it's ok when giving the right types. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/unsafe_impl_err.rs b/tests/ui/eii/unsafe_impl_err.rs index cb3eb5a27c63..6af7e9724e15 100644 --- a/tests/ui/eii/unsafe_impl_err.rs +++ b/tests/ui/eii/unsafe_impl_err.rs @@ -1,6 +1,6 @@ //@ compile-flags: --crate-type rlib // Tests whether it's an error to implement an unsafe EII safely. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/unsafe_impl_ok.rs b/tests/ui/eii/unsafe_impl_ok.rs index 5ffd1ef1321b..268c5bc16fd8 100644 --- a/tests/ui/eii/unsafe_impl_ok.rs +++ b/tests/ui/eii/unsafe_impl_ok.rs @@ -2,7 +2,7 @@ //@ check-pass // Uses manual desugaring of EII internals: // Tests whether it's okay to implement an unsafe EII with an unsafe implementation. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/wrong_ret_ty.rs b/tests/ui/eii/wrong_ret_ty.rs index 4a268ca675bc..5fe7d2f8bb62 100644 --- a/tests/ui/eii/wrong_ret_ty.rs +++ b/tests/ui/eii/wrong_ret_ty.rs @@ -1,6 +1,6 @@ //@ compile-flags: --crate-type rlib // Uses manual desugaring of EII internals: tests whether the return type matches. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/wrong_target.rs b/tests/ui/eii/wrong_target.rs index 2a7fc4420943..a62915fe2609 100644 --- a/tests/ui/eii/wrong_target.rs +++ b/tests/ui/eii/wrong_target.rs @@ -1,4 +1,4 @@ -#![feature(eii)] +#![feature(extern_item_impls)] // Check whether the EII attributes do target checking properly. #[eii] diff --git a/tests/ui/eii/wrong_ty.rs b/tests/ui/eii/wrong_ty.rs index 4fb81734c74a..ebb756f6a314 100644 --- a/tests/ui/eii/wrong_ty.rs +++ b/tests/ui/eii/wrong_ty.rs @@ -1,6 +1,6 @@ //@ compile-flags: --crate-type rlib // Uses manual desugaring of EII internals: tests whether the types of parameters match. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/eii/wrong_ty_2.rs b/tests/ui/eii/wrong_ty_2.rs index 085b9184caf0..d55f405bf157 100644 --- a/tests/ui/eii/wrong_ty_2.rs +++ b/tests/ui/eii/wrong_ty_2.rs @@ -1,6 +1,6 @@ //@ compile-flags: --crate-type rlib // Uses manual desugaring of EII internals: tests whether the number of parameters matches. -#![feature(eii)] +#![feature(extern_item_impls)] #![feature(decl_macro)] #![feature(rustc_attrs)] #![feature(eii_internals)] diff --git a/tests/ui/error-codes/E0806.rs b/tests/ui/error-codes/E0806.rs index 168c7120fc17..ab6a31673cc0 100644 --- a/tests/ui/error-codes/E0806.rs +++ b/tests/ui/error-codes/E0806.rs @@ -1,4 +1,4 @@ -#![feature(eii)] +#![feature(extern_item_impls)] #[eii(foo)] fn x(); diff --git a/tests/ui/feature-gates/feature-gate-eii.rs b/tests/ui/feature-gates/feature-gate-extern-item-impls.rs similarity index 59% rename from tests/ui/feature-gates/feature-gate-eii.rs rename to tests/ui/feature-gates/feature-gate-extern-item-impls.rs index 3a51c3dd2eae..f70ece554a09 100644 --- a/tests/ui/feature-gates/feature-gate-eii.rs +++ b/tests/ui/feature-gates/feature-gate-extern-item-impls.rs @@ -1,6 +1,6 @@ #![crate_type = "rlib"] -#[eii] //~ ERROR use of unstable library feature `eii` +#[eii] //~ ERROR use of unstable library feature `extern_item_impls` fn hello(x: u64); #[hello] diff --git a/tests/ui/feature-gates/feature-gate-eii.stderr b/tests/ui/feature-gates/feature-gate-extern-item-impls.stderr similarity index 63% rename from tests/ui/feature-gates/feature-gate-eii.stderr rename to tests/ui/feature-gates/feature-gate-extern-item-impls.stderr index 6ec231257ba7..0baace310d42 100644 --- a/tests/ui/feature-gates/feature-gate-eii.stderr +++ b/tests/ui/feature-gates/feature-gate-extern-item-impls.stderr @@ -1,11 +1,11 @@ -error[E0658]: use of unstable library feature `eii` - --> $DIR/feature-gate-eii.rs:3:3 +error[E0658]: use of unstable library feature `extern_item_impls` + --> $DIR/feature-gate-extern-item-impls.rs:3:3 | LL | #[eii] | ^^^ | = note: see issue #125418 for more information - = help: add `#![feature(eii)]` to the crate attributes to enable + = help: add `#![feature(extern_item_impls)]` 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 From 13de732df5d6988a4377247c04b64efed080cae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 8 Dec 2025 11:47:25 +0100 Subject: [PATCH 0666/3801] add test for symbol mangling issue --- tests/ui/eii/same-symbol.rs | 29 +++++++++++++++++++++++++++++ tests/ui/eii/same-symbol.run.stdout | 2 ++ 2 files changed, 31 insertions(+) create mode 100644 tests/ui/eii/same-symbol.rs create mode 100644 tests/ui/eii/same-symbol.run.stdout diff --git a/tests/ui/eii/same-symbol.rs b/tests/ui/eii/same-symbol.rs new file mode 100644 index 000000000000..d24e5c4266bb --- /dev/null +++ b/tests/ui/eii/same-symbol.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ check-run-results +//@ ignore-backends: gcc +#![feature(extern_item_impls)] + +pub mod a { + #[eii(foo)] + pub fn foo(); +} + +pub mod b { + #[eii(foo)] + pub fn foo(); +} + +#[a::foo] +fn a_foo_impl() { + println!("foo1"); +} + +#[b::foo] +fn b_foo_impl() { + println!("foo2"); +} + +fn main() { + a::foo(); + b::foo(); +} diff --git a/tests/ui/eii/same-symbol.run.stdout b/tests/ui/eii/same-symbol.run.stdout new file mode 100644 index 000000000000..873ddc86a9d5 --- /dev/null +++ b/tests/ui/eii/same-symbol.run.stdout @@ -0,0 +1,2 @@ +foo1 +foo1 From 3f63f521c1f611c2d68eaaf1fe5f9a3f08be3ed5 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 12 Dec 2025 22:06:07 +1100 Subject: [PATCH 0667/3801] Don't pass an unused `--color` to compiletest This flag was an artifact of compiletest's old libtest-based test executor, and currently doesn't influence compiletest's output at all. --- src/bootstrap/src/core/build_steps/test.rs | 1 - src/tools/compiletest/src/lib.rs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index a699cd23fb60..f30641d71e83 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2401,7 +2401,6 @@ Please disable assertions with `rust.debug-assertions = false`. let git_config = builder.config.git_config(); cmd.arg("--nightly-branch").arg(git_config.nightly_branch); cmd.arg("--git-merge-commit-email").arg(git_config.git_merge_commit_email); - cmd.force_coloring_in_ci(); #[cfg(feature = "build-metrics")] builder.metrics.begin_test_suite( diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 1fa818df62de..71dad3633793 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -136,8 +136,6 @@ fn parse_config(args: Vec) -> Config { ) .optflag("", "fail-fast", "stop as soon as possible after any test fails") .optopt("", "target", "the target to build for", "TARGET") - // FIXME: Should be removed once `bootstrap` will be updated to not use this option. - .optopt("", "color", "coloring: auto, always, never", "WHEN") .optopt("", "host", "the host to build for", "HOST") .optopt("", "cdb", "path to CDB to use for CDB debuginfo tests", "PATH") .optopt("", "gdb", "path to GDB to use for GDB debuginfo tests", "PATH") From 5768b234de07a3d39bb35deb36d3af92b790bc75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 8 Dec 2025 11:46:59 +0100 Subject: [PATCH 0668/3801] use our own alternative to STD_INTERNAL_SYMBOL and make sure we mangle EIIs properly --- .../src/attributes/codegen_attrs.rs | 9 +++++++++ compiler/rustc_attr_parsing/src/context.rs | 5 +++-- compiler/rustc_builtin_macros/src/eii.rs | 20 ++++++++++++++++++- .../src/back/symbol_export.rs | 9 +++++++-- .../rustc_codegen_ssa/src/codegen_attrs.rs | 11 +++++++++- compiler/rustc_feature/src/builtin_attrs.rs | 5 +++++ .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../src/middle/codegen_fn_attrs.rs | 13 ++++++++++++ .../src/middle/exported_symbols.rs | 1 + compiler/rustc_monomorphize/src/collector.rs | 12 ++++++----- .../rustc_monomorphize/src/partitioning.rs | 12 +++++++++-- compiler/rustc_passes/src/check_attr.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + tests/ui/eii/same-symbol.run.stdout | 2 +- 15 files changed, 91 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index b4ecbe6e4de6..c5800324fa99 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -699,3 +699,12 @@ impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisPa const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis; } + +pub(crate) struct EiiExternItemParser; + +impl NoArgsAttributeParser for EiiExternItemParser { + const PATH: &[Symbol] = &[sym::rustc_eii_extern_item]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::EiiExternItem; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index f41ea3708788..894b4c564ab7 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -20,8 +20,8 @@ use crate::attributes::allow_unstable::{ }; use crate::attributes::body::CoroutineParser; use crate::attributes::codegen_attrs::{ - ColdParser, CoverageParser, ExportNameParser, ForceTargetFeatureParser, NakedParser, - NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser, + ColdParser, CoverageParser, EiiExternItemParser, ExportNameParser, ForceTargetFeatureParser, + NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser, RustcPassIndirectlyInNonRusticAbisParser, SanitizeParser, TargetFeatureParser, TrackCallerParser, UsedParser, }; @@ -227,6 +227,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index f1161c644ef5..b97cb1daec53 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -209,6 +209,24 @@ fn eii_( } // extern "…" { safe fn item(); } + let mut extern_item_attrs = attrs.clone(); + extern_item_attrs.push(ast::Attribute { + kind: ast::AttrKind::Normal(Box::new(ast::NormalAttr { + item: ast::AttrItem { + unsafety: ast::Safety::Default, + // Add the rustc_eii_extern_item on the foreign item. Usually, foreign items are mangled. + // This attribute makes sure that we later know that this foreign item's symbol should not be. + path: ast::Path::from_ident(Ident::new(sym::rustc_eii_extern_item, span)), + args: ast::AttrArgs::Empty, + tokens: None, + }, + tokens: None, + })), + id: ecx.sess.psess.attr_id_generator.mk_attr_id(), + style: ast::AttrStyle::Outer, + span, + }); + let extern_block = Box::new(ast::Item { attrs: ast::AttrVec::default(), id: ast::DUMMY_NODE_ID, @@ -219,7 +237,7 @@ fn eii_( safety: ast::Safety::Unsafe(span), abi, items: From::from([Box::new(ast::ForeignItem { - attrs: attrs.clone(), + attrs: extern_item_attrs, id: ast::DUMMY_NODE_ID, span: item_span, vis, diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 9d06de2b35c2..27989f6f5ea2 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -127,7 +127,10 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap, sym_def_id: DefId) -> SymbolExportLevel let is_extern = codegen_fn_attrs.contains_extern_indicator(); let std_internal = codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); + let eii = codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM); - if is_extern && !std_internal { + if is_extern && !std_internal && !eii { let target = &tcx.sess.target.llvm_target; // WebAssembly cannot export data symbols, so reduce their export level + // FIXME(jdonszelmann) don't do a substring match here. if target.contains("emscripten") { if let DefKind::Static { .. } = tcx.def_kind(sym_def_id) { return SymbolExportLevel::Rust; diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 6aea249d6356..1933947ee0de 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -313,6 +313,9 @@ fn process_builtin_attrs( AttributeKind::ObjcSelector { methname, .. } => { codegen_fn_attrs.objc_selector = Some(*methname); } + AttributeKind::EiiExternItem => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM; + } AttributeKind::EiiImpls(impls) => { for i in impls { let extern_item = find_attr!( @@ -344,7 +347,7 @@ fn process_builtin_attrs( if i.is_default { Linkage::LinkOnceAny } else { Linkage::External }, Visibility::Default, )); - codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; + codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM; } } _ => {} @@ -448,6 +451,12 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way // both for exports and imports through foreign items. This is handled further, // during symbol mangling logic. + } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM) + { + // * externally implementable items keep their mangled symbol name. + // multiple EIIs can have the same name, so not mangling them would be a bug. + // Implementing an EII does the appropriate name resolution to make sure the implementations + // get the same symbol name as the *mangled* foreign item they refer to so that's all good. } else if codegen_fn_attrs.symbol_name.is_some() { // * This can be overridden with the `#[link_name]` attribute } else { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 6eefb2f48d12..c70dbc15e552 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -961,6 +961,11 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ allow_internal_unsafe, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint", ), + gated!( + rustc_eii_extern_item, Normal, template!(Word), + ErrorFollowing, EncodeCrossCrate::Yes, eii_internals, + "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", + ), rustc_attr!( rustc_allowed_through_unstable_modules, Normal, template!(NameValueStr: "deprecation message"), WarnFollowing, EncodeCrossCrate::No, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 28433f261220..34d78afca9b2 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -709,6 +709,9 @@ pub enum AttributeKind { /// Represents `#[rustc_dummy]`. Dummy, + /// Implementation detail of `#[eii]` + EiiExternItem, + /// Implementation detail of `#[eii]` EiiExternTarget(EiiDecl), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index e42d511da695..4cb786f59bfe 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -43,6 +43,7 @@ impl AttributeKind { Doc(_) => Yes, DocComment { .. } => Yes, Dummy => No, + EiiExternItem => No, EiiExternTarget(_) => Yes, EiiImpls(..) => No, ExportName { .. } => Yes, diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 7922cc38aaab..9033d9c46d54 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -43,6 +43,10 @@ impl<'tcx> TyCtxt<'tcx> { attrs.to_mut().flags.remove(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); } + if attrs.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM) { + attrs.to_mut().flags.remove(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM); + } + if attrs.symbol_name.is_some() { attrs.to_mut().symbol_name = None; } @@ -199,6 +203,12 @@ bitflags::bitflags! { const FOREIGN_ITEM = 1 << 16; /// `#[rustc_offload_kernel]`: indicates that this is an offload kernel, an extra ptr arg will be added. const OFFLOAD_KERNEL = 1 << 17; + /// Externally implementable item symbols act a little like `RUSTC_STD_INTERNAL_SYMBOL`. + /// When a crate declares an EII and dependencies expect the symbol to exist, + /// they will refer to this symbol name before a definition is given. + /// As such, we must make sure these symbols really do exist in the final binary/library. + /// This flag is put on both the implementations of EIIs and the foreign item they implement. + const EXTERNALLY_IMPLEMENTABLE_ITEM = 1 << 18; } } rustc_data_structures::external_bitflags_debug! { CodegenFnAttrFlags } @@ -242,6 +252,9 @@ impl CodegenFnAttrs { self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + // note: for these we do also set a symbol name so technically also handled by the + // condition below. However, I think that regardless these should be treated as extern. + || self.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM) || self.symbol_name.is_some() || match self.linkage { // These are private, so make sure we don't try to consider diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index c70ff398ceaf..58fc32078039 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -41,6 +41,7 @@ pub struct SymbolExportInfo { /// Was the symbol marked as `#[used(compiler)]` or `#[used(linker)]`? pub used: bool, /// Was the symbol marked as `#[rustc_std_internal_symbol]`? + /// We also use this for externally implementable items. pub rustc_std_internal_symbol: bool, } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 948f965ed7ad..cd699436e012 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1643,11 +1643,13 @@ impl<'v> RootCollector<'_, 'v> { MonoItemCollectionStrategy::Lazy => { self.entry_fn.and_then(|(id, _)| id.as_local()) == Some(def_id) || self.tcx.is_reachable_non_generic(def_id) - || self - .tcx - .codegen_fn_attrs(def_id) - .flags - .contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + || { + let flags = self.tcx.codegen_fn_attrs(def_id).flags; + flags.intersects( + CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL + | CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM, + ) + } } } } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index b87ab840a32d..1c8d6db08c31 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -872,7 +872,7 @@ fn mono_item_visibility<'tcx>( // visibility. In some situations though we'll want to prevent this // symbol from being internalized. // - // There's two categories of items here: + // There's three categories of items here: // // * First is weak lang items. These are basically mechanisms for // libcore to forward-reference symbols defined later in crates like @@ -902,8 +902,16 @@ fn mono_item_visibility<'tcx>( // visibility below. Like the weak lang items, though, we can't let // LLVM internalize them as this decision is left up to the linker to // omit them, so prevent them from being internalized. + // + // * Externally implementable items. They work (in this case) pretty much the same as + // RUSTC_STD_INTERNAL_SYMBOL in that their implementation is also chosen later in + // the compilation process and we can't let them be internalized and they can't + // show up as an external interface. let attrs = tcx.codegen_fn_attrs(def_id); - if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { + if attrs.flags.intersects( + CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL + | CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM, + ) { *can_be_internalized = false; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d5d2d64ffaf7..34f73212e90b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -217,6 +217,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }, Attribute::Parsed( AttributeKind::EiiExternTarget { .. } + | AttributeKind::EiiExternItem | AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect | AttributeKind::MacroTransparency(_) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8f43a31ea4b1..8e464b55d6c2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1944,6 +1944,7 @@ symbols! { rustc_dump_user_args, rustc_dump_vtable, rustc_effective_visibility, + rustc_eii_extern_item, rustc_evaluate_where_clauses, rustc_expected_cgu_reuse, rustc_force_inline, diff --git a/tests/ui/eii/same-symbol.run.stdout b/tests/ui/eii/same-symbol.run.stdout index 873ddc86a9d5..463021151d29 100644 --- a/tests/ui/eii/same-symbol.run.stdout +++ b/tests/ui/eii/same-symbol.run.stdout @@ -1,2 +1,2 @@ foo1 -foo1 +foo2 From e7b729cd92cae3d93ab70fdb21587d5c326711da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 9 Dec 2025 12:42:32 +0100 Subject: [PATCH 0669/3801] ignore test with defaults on macos --- tests/ui/eii/default/call_default.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/ui/eii/default/call_default.rs b/tests/ui/eii/default/call_default.rs index 90c56be78f13..7b39f6d225af 100644 --- a/tests/ui/eii/default/call_default.rs +++ b/tests/ui/eii/default/call_default.rs @@ -3,6 +3,16 @@ //@ run-pass //@ check-run-results //@ ignore-backends: gcc +// Functions can have target-cpu applied. On apple-darwin this is super important, +// since you can have binaries which mix x86 and aarch64 code that are compatible +// with both architectures. So we can't just reject target_cpu on EIIs since apple +// puts them on by default. The problem: we generate aliases. And aliases cannot +// get target_cpu applied to them. So, instead we should, in the case of functions, +// generate a shim function. For statics aliases should keep working in theory. +// In fact, aliases are only necessary for statics. For functions we could just +// always generate a shim and a previous version of EII did so but I was sad +// that that'd never support statics. +//@ ignore-macos // Tests EIIs with default implementations. // When there's no explicit declaration, the default should be called from the declaring crate. #![feature(extern_item_impls)] From ac5c70ad4d5d8f767237f5b3d28719fbc5d72bc8 Mon Sep 17 00:00:00 2001 From: Clara Engler Date: Tue, 11 Nov 2025 11:46:11 +0100 Subject: [PATCH 0670/3801] time: Implement SystemTime::{MIN, MAX} This commit introduces two new constants to SystemTime: `MIN` and `MAX`, whose value represent the maximum values for the respective data type, depending upon the platform. Technically, this value is already obtainable during runtime with the following algorithm: Use `SystemTime::UNIX_EPOCH` and call `checked_add` (or `checked_sub`) repeatedly with `Duration::new(0, 1)` on it, until it returns None. Mathematically speaking, this algorithm will terminate after a finite amount of steps, yet it is impractical to run it, as it takes practically forever. Besides, this commit also adds a unit test. Concrete implementation depending upon the platform is done in later commits. In the future, the hope of the authors lies within the creation of a `SystemTime::saturating_add` and `SystemTime::saturating_sub`, similar to the functions already present in `std::time::Duration`. However, for those, these constants are crucially required, thereby this should be seen as the initial step towards this direction. Below are platform specifc notes: # Hermit The HermitOS implementation is more or less identitcal to the Unix one. # sgx The implementation uses a `Duration` to store the Unix time, thereby implying `Duration::ZERO` and `Duration::MAX` as the limits. # solid The implementation uses a `time_t` to store the system time within a single value (i.e. no dual secs/nanosecs handling), thereby implying its `::MIN` and `::MAX` values as the respective boundaries. # UEFI UEFI has a weird way to store times, i.e. a very complicated struct. The standard proclaims "1900-01-01T00:00:00+0000" to be the lowest possible value and `MAX_UEFI_TIME` is already present for the upper limit. # Windows Windows is weird. The Win32 documentation makes no statement on a maximum value here. Next to this, there are two conflicting types: `SYSTEMTIME` and `FILETIME`. Rust's Standard Library uses `FILETIME`, whose limit will (probably) be `i64::MAX` packed into two integers. However, `SYSTEMTIME` has a lower-limit. # xous It is similar to sgx in the sense of using a `Duration`. # unsupported Unsupported platforms store a `SystemTime` in a `Duration`, just like sgx, thereby implying `Duration::ZERO` and `Duration::MAX` as the respective limits. --- library/std/src/sys/pal/hermit/time.rs | 8 +++ library/std/src/sys/pal/sgx/time.rs | 4 ++ library/std/src/sys/pal/solid/time.rs | 4 ++ library/std/src/sys/pal/uefi/time.rs | 17 ++++++ library/std/src/sys/pal/unix/time.rs | 11 ++++ library/std/src/sys/pal/unsupported/time.rs | 4 ++ library/std/src/sys/pal/windows/time.rs | 10 ++++ library/std/src/sys/pal/xous/time.rs | 4 ++ library/std/src/time.rs | 63 +++++++++++++++++++++ library/std/tests/time.rs | 19 +++++++ 10 files changed, 144 insertions(+) diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs index bd6fd5a3de42..53b1f9292b3d 100644 --- a/library/std/src/sys/pal/hermit/time.rs +++ b/library/std/src/sys/pal/hermit/time.rs @@ -15,6 +15,10 @@ struct Timespec { } impl Timespec { + const MAX: Timespec = Self::new(i64::MAX, 1_000_000_000 - 1); + + const MIN: Timespec = Self::new(i64::MIN, 0); + const fn zero() -> Timespec { Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } } } @@ -209,6 +213,10 @@ pub struct SystemTime(Timespec); pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero()); impl SystemTime { + pub const MAX: SystemTime = SystemTime { t: Timespec::MAX }; + + pub const MIN: SystemTime = SystemTime { t: Timespec::MIN }; + pub fn new(tv_sec: i64, tv_nsec: i32) -> SystemTime { SystemTime(Timespec::new(tv_sec, tv_nsec)) } diff --git a/library/std/src/sys/pal/sgx/time.rs b/library/std/src/sys/pal/sgx/time.rs index db4cf2804bf1..a9a448226619 100644 --- a/library/std/src/sys/pal/sgx/time.rs +++ b/library/std/src/sys/pal/sgx/time.rs @@ -28,6 +28,10 @@ impl Instant { } impl SystemTime { + pub const MAX: SystemTime = SystemTime(Duration::MAX); + + pub const MIN: SystemTime = SystemTime(Duration::ZERO); + pub fn now() -> SystemTime { SystemTime(usercalls::insecure_time()) } diff --git a/library/std/src/sys/pal/solid/time.rs b/library/std/src/sys/pal/solid/time.rs index c39d715c6a6f..d5cf70f94c98 100644 --- a/library/std/src/sys/pal/solid/time.rs +++ b/library/std/src/sys/pal/solid/time.rs @@ -10,6 +10,10 @@ pub struct SystemTime(abi::time_t); pub const UNIX_EPOCH: SystemTime = SystemTime(0); impl SystemTime { + pub const MAX: SystemTime = SystemTime(abi::time_t::MAX); + + pub const MIN: SystemTime = SystemTime(abi::time_t::MIN); + pub fn now() -> SystemTime { let rtc = unsafe { let mut out = MaybeUninit::zeroed(); diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs index 28dacbe3068a..30df6d93d0ee 100644 --- a/library/std/src/sys/pal/uefi/time.rs +++ b/library/std/src/sys/pal/uefi/time.rs @@ -70,6 +70,23 @@ impl Instant { } impl SystemTime { + pub const MAX: SystemTime = MAX_UEFI_TIME; + + pub const MIN: SystemTime = SystemTime::from_uefi(r_efi::efi::Time { + year: 1900, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + nanosecond: 0, + timezone: -1440, + daylight: 0, + pad1: 0, + pad2: 0, + }) + .unwrap(); + pub(crate) const fn from_uefi(t: r_efi::efi::Time) -> Option { match system_time_internal::from_uefi(&t) { Some(x) => Some(Self(x)), diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 24f13853b96b..1b3fbeee4d90 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -30,6 +30,10 @@ pub(crate) struct Timespec { } impl SystemTime { + pub const MAX: SystemTime = SystemTime { t: Timespec::MAX }; + + pub const MIN: SystemTime = SystemTime { t: Timespec::MIN }; + #[cfg_attr(any(target_os = "horizon", target_os = "hurd"), allow(unused))] pub fn new(tv_sec: i64, tv_nsec: i64) -> Result { Ok(SystemTime { t: Timespec::new(tv_sec, tv_nsec)? }) @@ -62,6 +66,13 @@ impl fmt::Debug for SystemTime { } impl Timespec { + const MAX: Timespec = unsafe { Self::new_unchecked(i64::MAX, 1_000_000_000 - 1) }; + + // As described below, on Apple OS, dates before epoch are represented differently. + // This is not an issue here however, because we are using tv_sec = i64::MIN, + // which will cause the compatibility wrapper to not be executed at all. + const MIN: Timespec = unsafe { Self::new_unchecked(i64::MIN, 0) }; + const unsafe fn new_unchecked(tv_sec: i64, tv_nsec: i64) -> Timespec { Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds::new_unchecked(tv_nsec as u32) } } } diff --git a/library/std/src/sys/pal/unsupported/time.rs b/library/std/src/sys/pal/unsupported/time.rs index 6d67b538a96b..9bdd57268fd5 100644 --- a/library/std/src/sys/pal/unsupported/time.rs +++ b/library/std/src/sys/pal/unsupported/time.rs @@ -27,6 +27,10 @@ impl Instant { } impl SystemTime { + pub const MAX: SystemTime = SystemTime(Duration::MAX); + + pub const MIN: SystemTime = SystemTime(Duration::ZERO); + pub fn now() -> SystemTime { panic!("time not implemented on this platform") } diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs index 0d31b80e56af..88f4d4cdbd61 100644 --- a/library/std/src/sys/pal/windows/time.rs +++ b/library/std/src/sys/pal/windows/time.rs @@ -64,6 +64,16 @@ impl Instant { } impl SystemTime { + pub const MAX: SystemTime = SystemTime { + t: c::FILETIME { + dwLowDateTime: (i64::MAX & 0xFFFFFFFF) as u32, + dwHighDateTime: (i64::MAX >> 32) as u32, + }, + }; + + pub const MIN: SystemTime = + SystemTime { t: c::FILETIME { dwLowDateTime: 0, dwHighDateTime: 0 } }; + pub fn now() -> SystemTime { unsafe { let mut t: SystemTime = mem::zeroed(); diff --git a/library/std/src/sys/pal/xous/time.rs b/library/std/src/sys/pal/xous/time.rs index ae8be81c0b7c..1e7e48183e98 100644 --- a/library/std/src/sys/pal/xous/time.rs +++ b/library/std/src/sys/pal/xous/time.rs @@ -35,6 +35,10 @@ impl Instant { } impl SystemTime { + pub const MAX: SystemTime = SystemTime(Duration::MAX); + + pub const MIN: SystemTime = SystemTime(Duration::ZERO); + pub fn now() -> SystemTime { let result = blocking_scalar(systime_server(), GetUtcTimeMs.into()) .expect("failed to request utc time in ms"); diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 87aaf9091f1b..0bda83af4dfb 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -511,6 +511,69 @@ impl SystemTime { #[stable(feature = "assoc_unix_epoch", since = "1.28.0")] pub const UNIX_EPOCH: SystemTime = UNIX_EPOCH; + /// Represents the maximum value representable by [`SystemTime`] on this platform. + /// + /// This value differs a lot between platforms, but it is always the case + /// that any positive addition to [`SystemTime::MAX`] will fail. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(time_systemtime_limits)] + /// use std::time::{Duration, SystemTime}; + /// + /// // Adding zero will change nothing. + /// assert_eq!(SystemTime::MAX.checked_add(Duration::ZERO), Some(SystemTime::MAX)); + /// + /// // But adding just 1ns will already fail. + /// assert_eq!(SystemTime::MAX.checked_add(Duration::new(0, 1)), None); + /// + /// // Utilize this for saturating arithmetic to improve error handling. + /// // In this case, we will use a certificate with a timestamp in the + /// // future as a practical example. + /// let configured_offset = Duration::from_secs(60 * 60 * 24); + /// let valid_after = + /// SystemTime::now() + /// .checked_add(configured_offset) + /// .unwrap_or(SystemTime::MAX); + /// ``` + #[unstable(feature = "time_systemtime_limits", issue = "149067")] + pub const MAX: SystemTime = SystemTime(time::SystemTime::MAX); + + /// Represents the minimum value representable by [`SystemTime`] on this platform. + /// + /// This value differs a lot between platforms, but it is always the case + /// that any positive subtraction from [`SystemTime::MIN`] will fail. + /// + /// Depending on the platform, this may be either less than or equal to + /// [`SystemTime::UNIX_EPOCH`], depending on whether the operating system + /// supports the representation of timestamps before the Unix epoch or not. + /// However, it is always guaranteed that a [`SystemTime::UNIX_EPOCH`] fits + /// between a [`SystemTime::MIN`] and [`SystemTime::MAX`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(time_systemtime_limits)] + /// use std::time::{Duration, SystemTime}; + /// + /// // Subtracting zero will change nothing. + /// assert_eq!(SystemTime::MIN.checked_sub(Duration::ZERO), Some(SystemTime::MIN)); + /// + /// // But subtracting just 1ns will already fail. + /// assert_eq!(SystemTime::MIN.checked_sub(Duration::new(0, 1)), None); + /// + /// // Utilize this for saturating arithmetic to improve error handling. + /// // In this case, we will use a cache expiry as a practical example. + /// let configured_expiry = Duration::from_secs(60 * 3); + /// let expiry_threshold = + /// SystemTime::now() + /// .checked_sub(configured_expiry) + /// .unwrap_or(SystemTime::MIN); + /// ``` + #[unstable(feature = "time_systemtime_limits", issue = "149067")] + pub const MIN: SystemTime = SystemTime(time::SystemTime::MIN); + /// Returns the system time corresponding to "now". /// /// # Examples diff --git a/library/std/tests/time.rs b/library/std/tests/time.rs index be1948af9156..31cc7171fe52 100644 --- a/library/std/tests/time.rs +++ b/library/std/tests/time.rs @@ -1,4 +1,5 @@ #![feature(duration_constants)] +#![feature(time_systemtime_limits)] use std::fmt::Debug; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; @@ -237,9 +238,27 @@ fn system_time_duration_since_max_range_on_unix() { let min = SystemTime::UNIX_EPOCH - (Duration::new(i64::MAX as u64 + 1, 0)); let max = SystemTime::UNIX_EPOCH + (Duration::new(i64::MAX as u64, 999_999_999)); + assert_eq!(min, SystemTime::MIN); + assert_eq!(max, SystemTime::MAX); + let delta_a = max.duration_since(min).expect("duration_since overflow"); let delta_b = min.duration_since(max).expect_err("duration_since overflow").duration(); assert_eq!(Duration::MAX, delta_a); assert_eq!(Duration::MAX, delta_b); } + +#[test] +fn system_time_max_min() { + // First, test everything with checked_* and Duration::ZERO. + assert_eq!(SystemTime::MAX.checked_add(Duration::ZERO), Some(SystemTime::MAX)); + assert_eq!(SystemTime::MAX.checked_sub(Duration::ZERO), Some(SystemTime::MAX)); + assert_eq!(SystemTime::MIN.checked_add(Duration::ZERO), Some(SystemTime::MIN)); + assert_eq!(SystemTime::MIN.checked_sub(Duration::ZERO), Some(SystemTime::MIN)); + + // Now do the same again with checked_* but try by ± a single nanosecond. + assert!(SystemTime::MAX.checked_add(Duration::new(0, 1)).is_none()); + assert!(SystemTime::MAX.checked_sub(Duration::new(0, 1)).is_some()); + assert!(SystemTime::MIN.checked_add(Duration::new(0, 1)).is_some()); + assert!(SystemTime::MIN.checked_sub(Duration::new(0, 1)).is_none()); +} From 0e7dc328942c05a98f2e49b65692d7e7e70ea9d7 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 12 Dec 2025 22:26:31 +1100 Subject: [PATCH 0671/3801] Inline `BootstrapCommand::force_coloring_in_ci` into its only call site This logic is cargo-specific anyway, so there is no need for it to be a generally-available helper method. --- src/bootstrap/src/core/builder/cargo.rs | 10 +++++++++- src/bootstrap/src/utils/exec.rs | 13 ------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 2ca52c72e5ec..5a6bade59a6a 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -2,6 +2,8 @@ use std::env; use std::ffi::{OsStr, OsString}; use std::path::{Path, PathBuf}; +use build_helper::ci::CiEnv; + use super::{Builder, Kind}; use crate::core::build_steps::test; use crate::core::build_steps::tool::SourceType; @@ -1334,7 +1336,13 @@ impl Builder<'_> { // Try to use a sysroot-relative bindir, in case it was configured absolutely. cargo.env("RUSTC_INSTALL_BINDIR", self.config.bindir_relative()); - cargo.force_coloring_in_ci(); + if CiEnv::is_ci() { + // Tell cargo to use colored output for nicer logs in CI, even + // though CI isn't printing to a terminal. + // Also set an explicit `TERM=xterm` so that cargo doesn't warn + // about TERM not being set. + cargo.env("TERM", "xterm").args(["--color=always"]); + }; // When we build Rust dylibs they're all intended for intermediate // usage, so make sure we pass the -Cprefer-dynamic flag instead of diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index f875e6e1af75..61b8b26dceaf 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -21,7 +21,6 @@ use std::process::{ use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; -use build_helper::ci::CiEnv; use build_helper::drop_bomb::DropBomb; use build_helper::exit; @@ -390,18 +389,6 @@ impl<'a> BootstrapCommand { self.drop_bomb.get_created_location() } - /// If in a CI environment, forces the command to run with colors. - pub fn force_coloring_in_ci(&mut self) { - if CiEnv::is_ci() { - // Due to use of stamp/docker, the output stream of bootstrap is not - // a TTY in CI, so coloring is by-default turned off. - // The explicit `TERM=xterm` environment is needed for - // `--color always` to actually work. This env var was lost when - // compiling through the Makefile. Very strange. - self.env("TERM", "xterm").args(["--color", "always"]); - } - } - pub fn fingerprint(&self) -> CommandFingerprint { let command = &self.command; CommandFingerprint { From a3dd6be7624247174961e8dfe2e3dcb9ce763d70 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Fri, 12 Dec 2025 18:55:49 +0800 Subject: [PATCH 0672/3801] Reorder add_return_type assist This assist is often before inline and is very inconvenient Usually, incomplete expression statements are written at the tail of the block, but they are not the return value of the block ```rust fn foo() { Some(2).$0and(optb) } ``` ```text 1. Add this function's return type 2. Inline `and` 3. Qualify `and` method call 4. Replace and with and_then ``` --- src/tools/rust-analyzer/crates/ide-assists/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index 16b5684c16a4..47cb4c8e74cb 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -247,7 +247,6 @@ mod handlers { add_label_to_loop::add_label_to_loop, add_lifetime_to_type::add_lifetime_to_type, add_missing_match_arms::add_missing_match_arms, - add_return_type::add_return_type, add_turbo_fish::add_turbo_fish, apply_demorgan::apply_demorgan_iterator, apply_demorgan::apply_demorgan, @@ -392,6 +391,7 @@ mod handlers { // used as a tie-breaker. add_missing_impl_members::add_missing_impl_members, add_missing_impl_members::add_missing_default_members, + add_return_type::add_return_type, // replace_string_with_char::replace_string_with_char, replace_string_with_char::replace_char_with_string, From ae85cebffdbeef3068d633d8d03ac3936273b94a Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Fri, 12 Dec 2025 18:55:49 +0800 Subject: [PATCH 0673/3801] Fix not applicable fn in closure for add_return_type Example --- ```rust const _: fn() = || { fn foo() $0{ 45 } } ``` **Before this PR** Assist not applicable **After this PR** ```rust const _: fn() = || { fn foo() -> i32 { 45 } } ``` --- .../src/handlers/add_return_type.rs | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs index c9022f66d1e2..7934a80bfabb 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs @@ -1,3 +1,4 @@ +use either::Either; use hir::HirDisplay; use syntax::{AstNode, SyntaxKind, SyntaxToken, TextRange, TextSize, ast, match_ast}; @@ -133,8 +134,9 @@ fn peel_blocks(mut expr: ast::Expr) -> ast::Expr { } fn extract_tail(ctx: &AssistContext<'_>) -> Option<(FnType, ast::Expr, InsertOrReplace)> { - let (fn_type, tail_expr, return_type_range, action) = - if let Some(closure) = ctx.find_node_at_offset::() { + let node = ctx.find_node_at_offset::>()?; + let (fn_type, tail_expr, return_type_range, action) = match node { + Either::Left(closure) => { let rpipe = closure.param_list()?.syntax().last_token()?; let rpipe_pos = rpipe.text_range().end(); @@ -149,9 +151,8 @@ fn extract_tail(ctx: &AssistContext<'_>) -> Option<(FnType, ast::Expr, InsertOrR let ret_range = TextRange::new(rpipe_pos, body_start); (FnType::Closure { wrap_expr }, tail_expr, ret_range, action) - } else { - let func = ctx.find_node_at_offset::()?; - + } + Either::Right(func) => { let rparen = func.param_list()?.r_paren_token()?; let rparen_pos = rparen.text_range().end(); let action = ret_ty_to_action(func.ret_type(), rparen)?; @@ -163,7 +164,8 @@ fn extract_tail(ctx: &AssistContext<'_>) -> Option<(FnType, ast::Expr, InsertOrR let ret_range_end = stmt_list.l_curly_token()?.text_range().start(); let ret_range = TextRange::new(rparen_pos, ret_range_end); (FnType::Function, tail_expr, ret_range, action) - }; + } + }; let range = ctx.selection_trimmed(); if return_type_range.contains_range(range) { cov_mark::hit!(cursor_in_ret_position); @@ -239,6 +241,24 @@ mod tests { ); } + #[test] + fn infer_return_type_cursor_at_return_type_pos_fn_inside_closure() { + cov_mark::check!(cursor_in_ret_position); + check_assist( + add_return_type, + r#"const _: fn() = || { + fn foo() $0{ + 45 + } +};"#, + r#"const _: fn() = || { + fn foo() -> i32 { + 45 + } +};"#, + ); + } + #[test] fn infer_return_type() { cov_mark::check!(cursor_on_tail); From 93c3ac2868b6823c5fb7c0e1c98f8578fcfe3ad0 Mon Sep 17 00:00:00 2001 From: Jamie Cunliffe Date: Fri, 12 Dec 2025 13:25:21 +0000 Subject: [PATCH 0674/3801] `declare_lint_pass` for `INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES` The `INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES` lint was missing from this causing it to be an unknown lint when attempting to allow it. --- compiler/rustc_lint_defs/src/builtin.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index baecc14424ec..99cce0c44b86 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -48,6 +48,7 @@ declare_lint_pass! { ILL_FORMED_ATTRIBUTE_INPUT, INCOMPLETE_INCLUDE, INEFFECTIVE_UNSTABLE_TRAIT_IMPL, + INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES, INLINE_NO_SANITIZE, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS, From 02bace8476c690a253f2dbdbe0f1fb75d402c8f6 Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Fri, 12 Dec 2025 16:35:48 +0300 Subject: [PATCH 0675/3801] Add a sanity check in case of any duplicate nodes --- compiler/rustc_query_system/src/dep_graph/graph.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index b2c72f19b78b..b85f226d108c 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1384,7 +1384,9 @@ impl DepNodeColorMap { #[inline] pub(super) fn insert_red(&self, index: SerializedDepNodeIndex) { - self.values[index].store(COMPRESSED_RED, Ordering::Release) + let value = self.values[index].swap(COMPRESSED_RED, Ordering::Release); + // Sanity check for duplicate nodes + assert_eq!(value, COMPRESSED_UNKNOWN, "trying to encode a dep node twice"); } } From 0ab4b8b9e0257a15fdf791950f48fa77dc0019b0 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 12 Dec 2025 12:21:15 +0100 Subject: [PATCH 0676/3801] Remove the E0536 error code --- compiler/rustc_error_codes/src/error_codes/E0536.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_error_codes/src/error_codes/E0536.md b/compiler/rustc_error_codes/src/error_codes/E0536.md index c1f43fa741cf..7603be4fcc93 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0536.md +++ b/compiler/rustc_error_codes/src/error_codes/E0536.md @@ -1,3 +1,5 @@ +#### Note: this error code is no longer emitted by the compiler. + The `not` cfg-predicate was malformed. Erroneous code example (using `cargo doc`): From c7b5fb56950c3a7999fa9348096ee55d2773ace2 Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Fri, 12 Dec 2025 16:44:17 +0300 Subject: [PATCH 0677/3801] Also check in case it tries to mark red node as green --- compiler/rustc_query_system/src/dep_graph/graph.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index b85f226d108c..8634274c3a75 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1363,7 +1363,10 @@ impl DepNodeColorMap { Ordering::Relaxed, ) { Ok(_) => Ok(()), - Err(v) => Err(DepNodeIndex::from_u32(v)), + Err(v) => Err({ + assert_ne!(v, COMPRESSED_RED, "tried to mark a red node as green"); + DepNodeIndex::from_u32(v) + }), } } From d025cdef7d9f5214dfffc4425eb1dd2228f8dc6c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 12 Dec 2025 14:47:28 +0100 Subject: [PATCH 0678/3801] If there are too many suggestions for malformed attribute, do not suggest them --- .../src/session_diagnostics.rs | 24 +- .../rustc_attr_parsing/src/validate_attr.rs | 5 + tests/rustdoc-ui/bad-render-options.stderr | 144 --------- tests/rustdoc-ui/check-doc-alias-attr.stderr | 32 -- tests/rustdoc-ui/doc-cfg.stderr | 80 ----- tests/rustdoc-ui/invalid-cfg.stderr | 128 -------- tests/rustdoc-ui/lints/doc-attr.stderr | 48 --- .../ui/attributes/crate-type-delimited.stderr | 14 - tests/ui/attributes/crate-type-empty.stderr | 10 - .../attributes/crate-type-macro-call.stderr | 14 - tests/ui/attributes/doc-attr.stderr | 48 --- tests/ui/attributes/doc-test-literal.stderr | 16 - tests/ui/attributes/malformed-attrs.stderr | 62 ---- tests/ui/attributes/malformed-reprs.stderr | 11 - .../ui/deprecation/deprecation-sanity.stderr | 96 ------ tests/ui/error-codes/E0458.stderr | 15 - tests/ui/error-codes/E0565-1.stderr | 16 - tests/ui/issues/issue-43988.stderr | 22 -- tests/ui/link-native-libs/issue-43925.stderr | 15 - tests/ui/link-native-libs/issue-43926.stderr | 15 - .../link-attr-validation-early.stderr | 26 -- .../link-attr-validation-late.stderr | 279 ------------------ .../modifiers-override-4.stderr | 43 --- tests/ui/linkage-attr/linkage3.stderr | 16 - .../import-name-type-invalid-format.stderr | 15 - .../windows/import-name-type-multiple.stderr | 15 - .../import-name-type-unknown-value.stderr | 15 - .../ui/malformed/malformed-regressions.stderr | 26 -- tests/ui/repr/repr.stderr | 41 --- tests/ui/rustdoc/check-doc-alias-attr.stderr | 32 -- .../ui/sanitize-attr/invalid-sanitize.stderr | 76 ----- tests/ui/wasm/wasm-import-module.stderr | 45 --- 32 files changed, 19 insertions(+), 1425 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 7bb55d2a6de5..2bbdb5c2590b 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -769,16 +769,20 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { diag.note(format!("for more information, visit <{link}>")); } - diag.span_suggestions( - self.attr_span, - if self.suggestions.len() == 1 { - "must be of the form".to_string() - } else { - format!("try changing it to one of the following valid forms of the {description}") - }, - self.suggestions, - Applicability::HasPlaceholders, - ); + if self.suggestions.len() < 4 { + diag.span_suggestions( + self.attr_span, + if self.suggestions.len() == 1 { + "must be of the form".to_string() + } else { + format!( + "try changing it to one of the following valid forms of the {description}" + ) + }, + self.suggestions, + Applicability::HasPlaceholders, + ); + } diag } diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index cd28677b6a8f..e69ed0eea6b0 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -198,6 +198,11 @@ fn emit_malformed_attribute( suggestions.push(format!("#{inner}[{name} = \"{descr}\"]")); } } + // If there are too many suggestions, better remove all of them as it's just noise at this + // point. + if suggestions.len() > 3 { + suggestions.clear(); + } if should_warn(name) { psess.buffer_lint( ILL_FORMED_ATTRIBUTE_INPUT, diff --git a/tests/rustdoc-ui/bad-render-options.stderr b/tests/rustdoc-ui/bad-render-options.stderr index 296a41337f33..28d4533a6edb 100644 --- a/tests/rustdoc-ui/bad-render-options.stderr +++ b/tests/rustdoc-ui/bad-render-options.stderr @@ -5,22 +5,6 @@ LL | #![doc(html_favicon_url)] | ^^^^^^^----------------^^ | | | expected this to be of the form `html_favicon_url = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(html_favicon_url)] -LL + #![doc = "string"] - | -LL - #![doc(html_favicon_url)] -LL + #![doc(alias)] - | -LL - #![doc(html_favicon_url)] -LL + #![doc(attribute)] - | -LL - #![doc(html_favicon_url)] -LL + #![doc(auto_cfg)] - | - = and 21 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:6:1 @@ -29,22 +13,6 @@ LL | #![doc(html_logo_url)] | ^^^^^^^-------------^^ | | | expected this to be of the form `html_logo_url = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(html_logo_url)] -LL + #![doc = "string"] - | -LL - #![doc(html_logo_url)] -LL + #![doc(alias)] - | -LL - #![doc(html_logo_url)] -LL + #![doc(attribute)] - | -LL - #![doc(html_logo_url)] -LL + #![doc(auto_cfg)] - | - = and 21 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:9:1 @@ -53,22 +21,6 @@ LL | #![doc(html_playground_url)] | ^^^^^^^-------------------^^ | | | expected this to be of the form `html_playground_url = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(html_playground_url)] -LL + #![doc = "string"] - | -LL - #![doc(html_playground_url)] -LL + #![doc(alias)] - | -LL - #![doc(html_playground_url)] -LL + #![doc(attribute)] - | -LL - #![doc(html_playground_url)] -LL + #![doc(auto_cfg)] - | - = and 21 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:12:1 @@ -77,22 +29,6 @@ LL | #![doc(issue_tracker_base_url)] | ^^^^^^^----------------------^^ | | | expected this to be of the form `issue_tracker_base_url = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(issue_tracker_base_url)] -LL + #![doc = "string"] - | -LL - #![doc(issue_tracker_base_url)] -LL + #![doc(alias)] - | -LL - #![doc(issue_tracker_base_url)] -LL + #![doc(attribute)] - | -LL - #![doc(issue_tracker_base_url)] -LL + #![doc(auto_cfg)] - | - = and 21 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:15:1 @@ -101,22 +37,6 @@ LL | #![doc(html_favicon_url = 1)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(html_favicon_url = 1)] -LL + #![doc = "string"] - | -LL - #![doc(html_favicon_url = 1)] -LL + #![doc(alias)] - | -LL - #![doc(html_favicon_url = 1)] -LL + #![doc(attribute)] - | -LL - #![doc(html_favicon_url = 1)] -LL + #![doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:18:1 @@ -125,22 +45,6 @@ LL | #![doc(html_logo_url = 2)] | ^^^^^^^^^^^^^^^^^^^^^^^-^^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(html_logo_url = 2)] -LL + #![doc = "string"] - | -LL - #![doc(html_logo_url = 2)] -LL + #![doc(alias)] - | -LL - #![doc(html_logo_url = 2)] -LL + #![doc(attribute)] - | -LL - #![doc(html_logo_url = 2)] -LL + #![doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:21:1 @@ -149,22 +53,6 @@ LL | #![doc(html_playground_url = 3)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(html_playground_url = 3)] -LL + #![doc = "string"] - | -LL - #![doc(html_playground_url = 3)] -LL + #![doc(alias)] - | -LL - #![doc(html_playground_url = 3)] -LL + #![doc(attribute)] - | -LL - #![doc(html_playground_url = 3)] -LL + #![doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:24:1 @@ -173,22 +61,6 @@ LL | #![doc(issue_tracker_base_url = 4)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(issue_tracker_base_url = 4)] -LL + #![doc = "string"] - | -LL - #![doc(issue_tracker_base_url = 4)] -LL + #![doc(alias)] - | -LL - #![doc(issue_tracker_base_url = 4)] -LL + #![doc(attribute)] - | -LL - #![doc(issue_tracker_base_url = 4)] -LL + #![doc(auto_cfg)] - | - = and 22 other candidates error[E0565]: malformed `doc` attribute input --> $DIR/bad-render-options.rs:27:1 @@ -197,22 +69,6 @@ LL | #![doc(html_no_source = "asdf")] | ^^^^^^^^^^^^^^^^^^^^^^--------^^ | | | didn't expect any arguments here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(html_no_source = "asdf")] -LL + #![doc = "string"] - | -LL - #![doc(html_no_source = "asdf")] -LL + #![doc(alias)] - | -LL - #![doc(html_no_source = "asdf")] -LL + #![doc(attribute)] - | -LL - #![doc(html_no_source = "asdf")] -LL + #![doc(auto_cfg)] - | - = and 22 other candidates error: aborting due to 9 previous errors diff --git a/tests/rustdoc-ui/check-doc-alias-attr.stderr b/tests/rustdoc-ui/check-doc-alias-attr.stderr index 6c33f10e8785..d9e785ee0f1f 100644 --- a/tests/rustdoc-ui/check-doc-alias-attr.stderr +++ b/tests/rustdoc-ui/check-doc-alias-attr.stderr @@ -11,22 +11,6 @@ LL | #[doc(alias = 0)] | ^^^^^^^^^^^^^^-^^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(alias = 0)] -LL + #[doc = "string"] - | -LL - #[doc(alias = 0)] -LL + #[doc(alias)] - | -LL - #[doc(alias = 0)] -LL + #[doc(attribute)] - | -LL - #[doc(alias = 0)] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:9:15 @@ -79,22 +63,6 @@ LL | #[doc(alias(0))] | ^^^^^^^^^^^^-^^^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(alias(0))] -LL + #[doc = "string"] - | -LL - #[doc(alias(0))] -LL + #[doc(alias)] - | -LL - #[doc(alias(0))] -LL + #[doc(attribute)] - | -LL - #[doc(alias(0))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:20:13 diff --git a/tests/rustdoc-ui/doc-cfg.stderr b/tests/rustdoc-ui/doc-cfg.stderr index 0efeac66554c..ce16ec31d875 100644 --- a/tests/rustdoc-ui/doc-cfg.stderr +++ b/tests/rustdoc-ui/doc-cfg.stderr @@ -5,22 +5,6 @@ LL | #[doc(cfg(), cfg(foo, bar))] | ^^^^^^^^^--^^^^^^^^^^^^^^^^^ | | | expected a single argument here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc = "string"] - | -LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(alias)] - | -LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(attribute)] - | -LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/doc-cfg.rs:3:1 @@ -29,22 +13,6 @@ LL | #[doc(cfg(), cfg(foo, bar))] | ^^^^^^^^^^^^^^^^----------^^ | | | expected a single argument here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc = "string"] - | -LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(alias)] - | -LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(attribute)] - | -LL - #[doc(cfg(), cfg(foo, bar))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/doc-cfg.rs:6:1 @@ -53,22 +21,6 @@ LL | #[doc(cfg())] | ^^^^^^^^^--^^ | | | expected a single argument here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg())] -LL + #[doc = "string"] - | -LL - #[doc(cfg())] -LL + #[doc(alias)] - | -LL - #[doc(cfg())] -LL + #[doc(attribute)] - | -LL - #[doc(cfg())] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/doc-cfg.rs:7:1 @@ -77,22 +29,6 @@ LL | #[doc(cfg(foo, bar))] | ^^^^^^^^^----------^^ | | | expected a single argument here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg(foo, bar))] -LL + #[doc = "string"] - | -LL - #[doc(cfg(foo, bar))] -LL + #[doc(alias)] - | -LL - #[doc(cfg(foo, bar))] -LL + #[doc(attribute)] - | -LL - #[doc(cfg(foo, bar))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/doc-cfg.rs:8:1 @@ -101,22 +37,6 @@ LL | #[doc(auto_cfg(hide(foo::bar)))] | ^^^^^^^^^^^^^^^^^^^^--------^^^^ | | | expected a valid identifier here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(auto_cfg(hide(foo::bar)))] -LL + #[doc = "string"] - | -LL - #[doc(auto_cfg(hide(foo::bar)))] -LL + #[doc(alias)] - | -LL - #[doc(auto_cfg(hide(foo::bar)))] -LL + #[doc(attribute)] - | -LL - #[doc(auto_cfg(hide(foo::bar)))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error: aborting due to 5 previous errors diff --git a/tests/rustdoc-ui/invalid-cfg.stderr b/tests/rustdoc-ui/invalid-cfg.stderr index 3363dbb56fb4..84f8cea54314 100644 --- a/tests/rustdoc-ui/invalid-cfg.stderr +++ b/tests/rustdoc-ui/invalid-cfg.stderr @@ -3,22 +3,6 @@ error[E0539]: malformed `doc` attribute input | LL | #[doc(cfg = "x")] | ^^^^^^^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg = "x")] -LL + #[doc = "string"] - | -LL - #[doc(cfg = "x")] -LL + #[doc(alias)] - | -LL - #[doc(cfg = "x")] -LL + #[doc(attribute)] - | -LL - #[doc(cfg = "x")] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:3:1 @@ -27,44 +11,12 @@ LL | #[doc(cfg(x, y))] | ^^^^^^^^^------^^ | | | expected a single argument here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg(x, y))] -LL + #[doc = "string"] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(alias)] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(attribute)] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:7:1 | LL | #[doc(cfg = "x")] | ^^^^^^^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg = "x")] -LL + #[doc = "string"] - | -LL - #[doc(cfg = "x")] -LL + #[doc(alias)] - | -LL - #[doc(cfg = "x")] -LL + #[doc(attribute)] - | -LL - #[doc(cfg = "x")] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:8:1 @@ -73,44 +25,12 @@ LL | #[doc(cfg(x, y))] | ^^^^^^^^^------^^ | | | expected a single argument here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg(x, y))] -LL + #[doc = "string"] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(alias)] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(attribute)] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:12:1 | LL | #[doc(cfg = "x")] | ^^^^^^^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg = "x")] -LL + #[doc = "string"] - | -LL - #[doc(cfg = "x")] -LL + #[doc(alias)] - | -LL - #[doc(cfg = "x")] -LL + #[doc(attribute)] - | -LL - #[doc(cfg = "x")] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:13:1 @@ -119,44 +39,12 @@ LL | #[doc(cfg(x, y))] | ^^^^^^^^^------^^ | | | expected a single argument here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg(x, y))] -LL + #[doc = "string"] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(alias)] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(attribute)] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:18:1 | LL | #[doc(cfg = "x")] | ^^^^^^^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg = "x")] -LL + #[doc = "string"] - | -LL - #[doc(cfg = "x")] -LL + #[doc(alias)] - | -LL - #[doc(cfg = "x")] -LL + #[doc(attribute)] - | -LL - #[doc(cfg = "x")] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:19:1 @@ -165,22 +53,6 @@ LL | #[doc(cfg(x, y))] | ^^^^^^^^^------^^ | | | expected a single argument here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(cfg(x, y))] -LL + #[doc = "string"] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(alias)] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(attribute)] - | -LL - #[doc(cfg(x, y))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error: aborting due to 8 previous errors diff --git a/tests/rustdoc-ui/lints/doc-attr.stderr b/tests/rustdoc-ui/lints/doc-attr.stderr index 1201bd5c71f1..8f8c6000b364 100644 --- a/tests/rustdoc-ui/lints/doc-attr.stderr +++ b/tests/rustdoc-ui/lints/doc-attr.stderr @@ -5,22 +5,6 @@ LL | #[doc(123)] | ^^^^^^---^^ | | | expected this to be of the form `... = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(123)] -LL + #[doc = "string"] - | -LL - #[doc(123)] -LL + #[doc(alias)] - | -LL - #[doc(123)] -LL + #[doc(attribute)] - | -LL - #[doc(123)] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/doc-attr.rs:5:1 @@ -29,22 +13,6 @@ LL | #[doc("hello", "bar")] | ^^^^^^-------^^^^^^^^^ | | | expected this to be of the form `... = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc("hello", "bar")] -LL + #[doc = "string"] - | -LL - #[doc("hello", "bar")] -LL + #[doc(alias)] - | -LL - #[doc("hello", "bar")] -LL + #[doc(attribute)] - | -LL - #[doc("hello", "bar")] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/doc-attr.rs:5:1 @@ -53,22 +21,6 @@ LL | #[doc("hello", "bar")] | ^^^^^^^^^^^^^^^-----^^ | | | expected this to be of the form `... = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc("hello", "bar")] -LL + #[doc = "string"] - | -LL - #[doc("hello", "bar")] -LL + #[doc(alias)] - | -LL - #[doc("hello", "bar")] -LL + #[doc(attribute)] - | -LL - #[doc("hello", "bar")] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/crate-type-delimited.stderr b/tests/ui/attributes/crate-type-delimited.stderr index 7f080f748386..23234efe169f 100644 --- a/tests/ui/attributes/crate-type-delimited.stderr +++ b/tests/ui/attributes/crate-type-delimited.stderr @@ -5,21 +5,7 @@ LL | #![crate_type(lib)] | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit -help: the following are the possible correct uses | -LL - #![crate_type(lib)] -LL + #![crate_type = "bin"] - | -LL - #![crate_type(lib)] -LL + #![crate_type = "cdylib"] - | -LL - #![crate_type(lib)] -LL + #![crate_type = "dylib"] - | -LL - #![crate_type(lib)] -LL + #![crate_type = "lib"] - | - = and 4 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/attributes/crate-type-empty.stderr b/tests/ui/attributes/crate-type-empty.stderr index f50bb33d6bb0..c1d474d9f17f 100644 --- a/tests/ui/attributes/crate-type-empty.stderr +++ b/tests/ui/attributes/crate-type-empty.stderr @@ -5,17 +5,7 @@ LL | #![crate_type] | ^^^^^^^^^^^^^^ | = note: for more information, visit -help: the following are the possible correct uses | -LL | #![crate_type = "bin"] - | +++++++ -LL | #![crate_type = "cdylib"] - | ++++++++++ -LL | #![crate_type = "dylib"] - | +++++++++ -LL | #![crate_type = "lib"] - | +++++++ - = and 4 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/attributes/crate-type-macro-call.stderr b/tests/ui/attributes/crate-type-macro-call.stderr index 97938f7af24e..cd17b324041b 100644 --- a/tests/ui/attributes/crate-type-macro-call.stderr +++ b/tests/ui/attributes/crate-type-macro-call.stderr @@ -5,21 +5,7 @@ LL | #![crate_type = foo!()] | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit -help: the following are the possible correct uses | -LL - #![crate_type = foo!()] -LL + #![crate_type = "bin"] - | -LL - #![crate_type = foo!()] -LL + #![crate_type = "cdylib"] - | -LL - #![crate_type = foo!()] -LL + #![crate_type = "dylib"] - | -LL - #![crate_type = foo!()] -LL + #![crate_type = "lib"] - | - = and 4 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/attributes/doc-attr.stderr b/tests/ui/attributes/doc-attr.stderr index 9234c1a0719b..dfc0e8ad5b6f 100644 --- a/tests/ui/attributes/doc-attr.stderr +++ b/tests/ui/attributes/doc-attr.stderr @@ -5,22 +5,6 @@ LL | #[doc(123)] | ^^^^^^---^^ | | | expected this to be of the form `... = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(123)] -LL + #[doc = "string"] - | -LL - #[doc(123)] -LL + #[doc(alias)] - | -LL - #[doc(123)] -LL + #[doc(attribute)] - | -LL - #[doc(123)] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/doc-attr.rs:11:1 @@ -29,22 +13,6 @@ LL | #[doc("hello", "bar")] | ^^^^^^-------^^^^^^^^^ | | | expected this to be of the form `... = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc("hello", "bar")] -LL + #[doc = "string"] - | -LL - #[doc("hello", "bar")] -LL + #[doc(alias)] - | -LL - #[doc("hello", "bar")] -LL + #[doc(attribute)] - | -LL - #[doc("hello", "bar")] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error[E0539]: malformed `doc` attribute input --> $DIR/doc-attr.rs:11:1 @@ -53,22 +21,6 @@ LL | #[doc("hello", "bar")] | ^^^^^^^^^^^^^^^-----^^ | | | expected this to be of the form `... = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc("hello", "bar")] -LL + #[doc = "string"] - | -LL - #[doc("hello", "bar")] -LL + #[doc(alias)] - | -LL - #[doc("hello", "bar")] -LL + #[doc(attribute)] - | -LL - #[doc("hello", "bar")] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error: unknown `doc` attribute `as_ptr` --> $DIR/doc-attr.rs:5:7 diff --git a/tests/ui/attributes/doc-test-literal.stderr b/tests/ui/attributes/doc-test-literal.stderr index 3ffbdcbb9fee..2d70d5d206f0 100644 --- a/tests/ui/attributes/doc-test-literal.stderr +++ b/tests/ui/attributes/doc-test-literal.stderr @@ -5,22 +5,6 @@ LL | #![doc(test(""))] | ^^^^^^^^^^^^--^^^ | | | didn't expect a literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #![doc(test(""))] -LL + #![doc = "string"] - | -LL - #![doc(test(""))] -LL + #![doc(alias)] - | -LL - #![doc(test(""))] -LL + #![doc(attribute)] - | -LL - #![doc(test(""))] -LL + #![doc(auto_cfg)] - | - = and 22 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index a6bd62fa1214..e1ebe4ac9eab 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -240,22 +240,6 @@ LL | #[deprecated = 5] | ^^^^^^^^^^^^^^^-^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated = 5] -LL + #[deprecated = "reason"] - | -LL - #[deprecated = 5] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated = 5] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated = 5] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `rustc_macro_transparency` attribute input --> $DIR/malformed-attrs.rs:44:1 @@ -287,17 +271,6 @@ LL | #[repr] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[repr()] - | ++++++++++++++++ -LL | #[repr(C)] - | +++ -LL | #[repr(Rust)] - | ++++++ -LL | #[repr(align(...))] - | ++++++++++++ - = and 2 other candidates error[E0565]: malformed `rustc_as_ptr` attribute input --> $DIR/malformed-attrs.rs:50:1 @@ -437,17 +410,6 @@ LL | #[link] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[link(name = "...")] - | ++++++++++++++ -LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...")] - | +++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link_name` attribute input --> $DIR/malformed-attrs.rs:88:1 @@ -483,18 +445,6 @@ error[E0539]: malformed `sanitize` attribute input | LL | #[sanitize] | ^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL | #[sanitize(address = "on|off")] - | ++++++++++++++++++++ -LL | #[sanitize(cfi = "on|off")] - | ++++++++++++++++ -LL | #[sanitize(hwaddress = "on|off")] - | ++++++++++++++++++++++ -LL | #[sanitize(kcfi = "on|off")] - | +++++++++++++++++ - = and 6 other candidates error[E0565]: malformed `no_implicit_prelude` attribute input --> $DIR/malformed-attrs.rs:101:1 @@ -634,18 +584,6 @@ error[E0539]: malformed `linkage` attribute input | LL | #[linkage] | ^^^^^^^^^^ expected this to be of the form `linkage = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL | #[linkage = "available_externally"] - | ++++++++++++++++++++++++ -LL | #[linkage = "common"] - | ++++++++++ -LL | #[linkage = "extern_weak"] - | +++++++++++++++ -LL | #[linkage = "external"] - | ++++++++++++ - = and 5 other candidates error[E0539]: malformed `debugger_visualizer` attribute input --> $DIR/malformed-attrs.rs:194:1 diff --git a/tests/ui/attributes/malformed-reprs.stderr b/tests/ui/attributes/malformed-reprs.stderr index 3a788999542b..504ba91aac5f 100644 --- a/tests/ui/attributes/malformed-reprs.stderr +++ b/tests/ui/attributes/malformed-reprs.stderr @@ -5,17 +5,6 @@ LL | #![repr] | ^^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #![repr()] - | ++++++++++++++++ -LL | #![repr(C)] - | +++ -LL | #![repr(Rust)] - | ++++++ -LL | #![repr(align(...))] - | ++++++++++++ - = and 2 other candidates error[E0589]: invalid `repr(align)` attribute: not a power of two --> $DIR/malformed-reprs.rs:9:14 diff --git a/tests/ui/deprecation/deprecation-sanity.stderr b/tests/ui/deprecation/deprecation-sanity.stderr index 48d08b18f8bd..a96d4a0bdea8 100644 --- a/tests/ui/deprecation/deprecation-sanity.stderr +++ b/tests/ui/deprecation/deprecation-sanity.stderr @@ -11,22 +11,6 @@ LL | #[deprecated(since = "a", note)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^----^^ | | | expected this to be of the form `note = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since = "a", note)] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since = "a", note)] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since = "a", note)] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since = "a", note)] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:12:5 @@ -35,22 +19,6 @@ LL | #[deprecated(since, note = "a")] | ^^^^^^^^^^^^^-----^^^^^^^^^^^^^^ | | | expected this to be of the form `since = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since, note = "a")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since, note = "a")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since, note = "a")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since, note = "a")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:15:5 @@ -59,22 +27,6 @@ LL | #[deprecated(since = "a", note(b))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^ | | | expected this to be of the form `note = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since = "a", note(b))] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since = "a", note(b))] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since = "a", note(b))] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since = "a", note(b))] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:18:5 @@ -83,22 +35,6 @@ LL | #[deprecated(since(b), note = "a")] | ^^^^^^^^^^^^^--------^^^^^^^^^^^^^^ | | | expected this to be of the form `since = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since(b), note = "a")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since(b), note = "a")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since(b), note = "a")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since(b), note = "a")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:21:5 @@ -117,22 +53,6 @@ LL | #[deprecated("test")] | ^^^^^^^^^^^^^------^^ | | | didn't expect a literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated("test")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated("test")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated("test")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated("test")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error: multiple `deprecated` attributes --> $DIR/deprecation-sanity.rs:29:1 @@ -153,22 +73,6 @@ LL | #[deprecated(since = "a", since = "b", note = "c")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^ | | | found `since` used as a key more than once - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since = "a", since = "b", note = "c")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since = "a", since = "b", note = "c")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since = "a", since = "b", note = "c")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since = "a", since = "b", note = "c")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error: `#[deprecated]` attribute cannot be used on trait impl blocks --> $DIR/deprecation-sanity.rs:37:1 diff --git a/tests/ui/error-codes/E0458.stderr b/tests/ui/error-codes/E0458.stderr index 524765ea12a1..e56c9473d287 100644 --- a/tests/ui/error-codes/E0458.stderr +++ b/tests/ui/error-codes/E0458.stderr @@ -7,21 +7,6 @@ LL | #[link(kind = "wonderful_unicorn")] extern "C" {} | valid arguments are "static", "dylib", "framework", "raw-dylib" or "link-arg" | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(kind = "wonderful_unicorn")] extern "C" {} -LL + #[link(name = "...")] extern "C" {} - | -LL - #[link(kind = "wonderful_unicorn")] extern "C" {} -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] extern "C" {} - | -LL - #[link(kind = "wonderful_unicorn")] extern "C" {} -LL + #[link(name = "...", kind = "dylib|static|...")] extern "C" {} - | -LL - #[link(kind = "wonderful_unicorn")] extern "C" {} -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] extern "C" {} - | - = and 1 other candidate error[E0459]: `#[link]` attribute requires a `name = "string"` argument --> $DIR/E0458.rs:1:1 diff --git a/tests/ui/error-codes/E0565-1.stderr b/tests/ui/error-codes/E0565-1.stderr index 52daf2a62fcd..d1aff042e8fb 100644 --- a/tests/ui/error-codes/E0565-1.stderr +++ b/tests/ui/error-codes/E0565-1.stderr @@ -5,22 +5,6 @@ LL | #[deprecated("since")] | ^^^^^^^^^^^^^-------^^ | | | didn't expect a literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated("since")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated("since")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated("since")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated("since")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-43988.stderr b/tests/ui/issues/issue-43988.stderr index 0219eeb693e7..d393255e0ee1 100644 --- a/tests/ui/issues/issue-43988.stderr +++ b/tests/ui/issues/issue-43988.stderr @@ -60,17 +60,6 @@ LL | #[repr] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[repr()] - | ++++++++++++++++ -LL | #[repr(C)] - | +++ -LL | #[repr(Rust)] - | ++++++ -LL | #[repr(align(...))] - | ++++++++++++ - = and 2 other candidates error[E0539]: malformed `inline` attribute input --> $DIR/issue-43988.rs:31:5 @@ -108,17 +97,6 @@ LL | let _z = #[repr] 1; | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | let _z = #[repr()] 1; - | ++++++++++++++++ -LL | let _z = #[repr(C)] 1; - | +++ -LL | let _z = #[repr(Rust)] 1; - | ++++++ -LL | let _z = #[repr(align(...))] 1; - | ++++++++++++ - = and 2 other candidates error: aborting due to 9 previous errors diff --git a/tests/ui/link-native-libs/issue-43925.stderr b/tests/ui/link-native-libs/issue-43925.stderr index 68a020546c14..fdc644ed6469 100644 --- a/tests/ui/link-native-libs/issue-43925.stderr +++ b/tests/ui/link-native-libs/issue-43925.stderr @@ -16,21 +16,6 @@ LL | #[link(name = "foo", cfg("rlib"))] | expected a valid identifier here | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", cfg("rlib"))] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", cfg("rlib"))] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", cfg("rlib"))] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", cfg("rlib"))] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 2 previous errors diff --git a/tests/ui/link-native-libs/issue-43926.stderr b/tests/ui/link-native-libs/issue-43926.stderr index 9e3ec21cc945..f7b85788a2a3 100644 --- a/tests/ui/link-native-libs/issue-43926.stderr +++ b/tests/ui/link-native-libs/issue-43926.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "foo", cfg())] | expected a single argument here | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", cfg())] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", cfg())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", cfg())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", cfg())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/link-native-libs/link-attr-validation-early.stderr b/tests/ui/link-native-libs/link-attr-validation-early.stderr index e4799b1a1618..101df0371b54 100644 --- a/tests/ui/link-native-libs/link-attr-validation-early.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-early.stderr @@ -5,17 +5,6 @@ LL | #[link] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[link(name = "...")] - | ++++++++++++++ -LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...")] - | +++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-early.rs:3:1 @@ -24,21 +13,6 @@ LL | #[link = "foo"] | ^^^^^^^^^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link = "foo"] -LL + #[link(name = "...")] - | -LL - #[link = "foo"] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link = "foo"] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link = "foo"] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 2 previous errors diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr index 106b7cebc99f..a5f654ca0aeb 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "...", "literal")] | didn't expect a literal here | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", "literal")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", "literal")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", "literal")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", "literal")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:5:1 @@ -32,21 +17,6 @@ LL | #[link(name = "...", unknown)] | valid arguments are "name", "kind", "modifiers", "cfg", "wasm_import_module" or "import_name_type" | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", unknown)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", unknown)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", unknown)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", unknown)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:9:1 @@ -57,21 +27,6 @@ LL | #[link(name = "foo", name = "bar")] | found `name` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", name = "bar")] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", name = "bar")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", name = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", name = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:10:1 @@ -82,21 +37,6 @@ LL | #[link(name = "...", kind = "dylib", kind = "bar")] | found `kind` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", kind = "dylib", kind = "bar")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", kind = "dylib", kind = "bar")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", kind = "dylib", kind = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", kind = "dylib", kind = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:11:1 @@ -107,21 +47,6 @@ LL | #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] | found `modifiers` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:12:1 @@ -132,21 +57,6 @@ LL | #[link(name = "...", cfg(false), cfg(false))] | found `cfg` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", cfg(false), cfg(false))] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", cfg(false), cfg(false))] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", cfg(false), cfg(false))] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", cfg(false), cfg(false))] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:13:1 @@ -157,21 +67,6 @@ LL | #[link(wasm_import_module = "foo", wasm_import_module = "bar")] | found `wasm_import_module` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")] -LL + #[link(name = "...")] - | -LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:17:1 @@ -182,17 +77,6 @@ LL | #[link(name)] | expected this to be of the form `name = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[link(name = "...")] - | +++++++ -LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...")] - | ++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:18:1 @@ -203,21 +87,6 @@ LL | #[link(name())] | expected this to be of the form `name = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name())] -LL + #[link(name = "...")] - | -LL - #[link(name())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:19:1 @@ -228,19 +97,6 @@ LL | #[link(name = "...", kind)] | expected this to be of the form `kind = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", kind)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", kind)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL | #[link(name = "...", kind = "dylib|static|...")] - | ++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:20:1 @@ -251,21 +107,6 @@ LL | #[link(name = "...", kind())] | expected this to be of the form `kind = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", kind())] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", kind())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", kind())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", kind())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:21:1 @@ -276,21 +117,6 @@ LL | #[link(name = "...", modifiers)] | expected this to be of the form `modifiers = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", modifiers)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", modifiers)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", modifiers)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", modifiers)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:22:1 @@ -301,21 +127,6 @@ LL | #[link(name = "...", modifiers())] | expected this to be of the form `modifiers = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", modifiers())] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", modifiers())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", modifiers())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", modifiers())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:23:1 @@ -326,21 +137,6 @@ LL | #[link(name = "...", cfg)] | expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", cfg)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", cfg)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", cfg)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", cfg)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:24:1 @@ -351,21 +147,6 @@ LL | #[link(name = "...", cfg = "literal")] | expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", cfg = "literal")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", cfg = "literal")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", cfg = "literal")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", cfg = "literal")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:25:1 @@ -376,21 +157,6 @@ LL | #[link(name = "...", cfg("literal"))] | expected a valid identifier here | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", cfg("literal"))] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", cfg("literal"))] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", cfg("literal"))] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", cfg("literal"))] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:26:1 @@ -401,21 +167,6 @@ LL | #[link(name = "...", wasm_import_module)] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:27:1 @@ -426,21 +177,6 @@ LL | #[link(name = "...", wasm_import_module())] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed --> $DIR/link-attr-validation-late.rs:31:34 @@ -463,21 +199,6 @@ LL | #[link(name = "...", modifiers = "+unknown")] | valid arguments are "bundle", "verbatim", "whole-archive" or "as-needed" | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", modifiers = "+unknown")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", modifiers = "+unknown")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", modifiers = "+unknown")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", modifiers = "+unknown")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: multiple `verbatim` modifiers in a single `modifiers` argument --> $DIR/link-attr-validation-late.rs:34:34 diff --git a/tests/ui/link-native-libs/modifiers-override-4.stderr b/tests/ui/link-native-libs/modifiers-override-4.stderr index 317e89cb39cc..12b0d89c79a7 100644 --- a/tests/ui/link-native-libs/modifiers-override-4.stderr +++ b/tests/ui/link-native-libs/modifiers-override-4.stderr @@ -12,49 +12,6 @@ LL | | )] | |__^ | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link( -LL - -LL - name = "bar", -LL - kind = "static", -LL - modifiers = "+whole-archive,-whole-archive", -LL - -LL - modifiers = "+bundle" -LL - )] -LL + #[link(name = "...")] - | -LL - #[link( -LL - -LL - name = "bar", -LL - kind = "static", -LL - modifiers = "+whole-archive,-whole-archive", -LL - -LL - modifiers = "+bundle" -LL - )] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link( -LL - -LL - name = "bar", -LL - kind = "static", -LL - modifiers = "+whole-archive,-whole-archive", -LL - -LL - modifiers = "+bundle" -LL - )] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link( -LL - -LL - name = "bar", -LL - kind = "static", -LL - modifiers = "+whole-archive,-whole-archive", -LL - -LL - modifiers = "+bundle" -LL - )] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: multiple `whole-archive` modifiers in a single `modifiers` argument --> $DIR/modifiers-override-4.rs:6:17 diff --git a/tests/ui/linkage-attr/linkage3.stderr b/tests/ui/linkage-attr/linkage3.stderr index f1215f09aeaf..564090e9538f 100644 --- a/tests/ui/linkage-attr/linkage3.stderr +++ b/tests/ui/linkage-attr/linkage3.stderr @@ -5,22 +5,6 @@ LL | #[linkage = "foo"] | ^^^^^^^^^^^^-----^ | | | valid arguments are `available_externally`, `common`, `extern_weak`, `external`, `internal`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[linkage = "foo"] -LL + #[linkage = "available_externally"] - | -LL - #[linkage = "foo"] -LL + #[linkage = "common"] - | -LL - #[linkage = "foo"] -LL + #[linkage = "extern_weak"] - | -LL - #[linkage = "foo"] -LL + #[linkage = "external"] - | - = and 5 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr index 6b54f3b247d1..86a53a030f50 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] | expected this to be of the form `import_name_type = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr index 35ddb2a7e3d3..ef909ad7278b 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", im | found `import_name_type` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr index b0099675dd23..577ec8e7764c 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] | valid arguments are "decorated", "noprefix" or "undecorated" | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index 29734fd84e6b..f46afda1e477 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr @@ -5,17 +5,6 @@ LL | #[link] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[link(name = "...")] - | ++++++++++++++ -LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...")] - | +++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/malformed-regressions.rs:10:1 @@ -24,21 +13,6 @@ LL | #[link = ""] | ^^^^^^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link = ""] -LL + #[link(name = "...")] - | -LL - #[link = ""] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link = ""] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link = ""] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/malformed-regressions.rs:7:1 diff --git a/tests/ui/repr/repr.stderr b/tests/ui/repr/repr.stderr index d4faea125176..e8168f8f9a58 100644 --- a/tests/ui/repr/repr.stderr +++ b/tests/ui/repr/repr.stderr @@ -5,17 +5,6 @@ LL | #[repr] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[repr()] - | ++++++++++++++++ -LL | #[repr(C)] - | +++ -LL | #[repr(Rust)] - | ++++++ -LL | #[repr(align(...))] - | ++++++++++++ - = and 2 other candidates error[E0539]: malformed `repr` attribute input --> $DIR/repr.rs:4:1 @@ -24,21 +13,6 @@ LL | #[repr = "B"] | ^^^^^^^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[repr = "B"] -LL + #[repr()] - | -LL - #[repr = "B"] -LL + #[repr(C)] - | -LL - #[repr = "B"] -LL + #[repr(Rust)] - | -LL - #[repr = "B"] -LL + #[repr(align(...))] - | - = and 2 other candidates error[E0539]: malformed `repr` attribute input --> $DIR/repr.rs:7:1 @@ -47,21 +21,6 @@ LL | #[repr = "C"] | ^^^^^^^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[repr = "C"] -LL + #[repr()] - | -LL - #[repr = "C"] -LL + #[repr(C)] - | -LL - #[repr = "C"] -LL + #[repr(Rust)] - | -LL - #[repr = "C"] -LL + #[repr(align(...))] - | - = and 2 other candidates error: aborting due to 3 previous errors diff --git a/tests/ui/rustdoc/check-doc-alias-attr.stderr b/tests/ui/rustdoc/check-doc-alias-attr.stderr index 6c33f10e8785..d9e785ee0f1f 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr.stderr +++ b/tests/ui/rustdoc/check-doc-alias-attr.stderr @@ -11,22 +11,6 @@ LL | #[doc(alias = 0)] | ^^^^^^^^^^^^^^-^^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(alias = 0)] -LL + #[doc = "string"] - | -LL - #[doc(alias = 0)] -LL + #[doc(alias)] - | -LL - #[doc(alias = 0)] -LL + #[doc(attribute)] - | -LL - #[doc(alias = 0)] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:9:15 @@ -79,22 +63,6 @@ LL | #[doc(alias(0))] | ^^^^^^^^^^^^-^^^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[doc(alias(0))] -LL + #[doc = "string"] - | -LL - #[doc(alias(0))] -LL + #[doc(alias)] - | -LL - #[doc(alias(0))] -LL + #[doc(attribute)] - | -LL - #[doc(alias(0))] -LL + #[doc(auto_cfg)] - | - = and 22 other candidates error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:20:13 diff --git a/tests/ui/sanitize-attr/invalid-sanitize.stderr b/tests/ui/sanitize-attr/invalid-sanitize.stderr index 9c1a6e5c4528..2a3497678bdc 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.stderr +++ b/tests/ui/sanitize-attr/invalid-sanitize.stderr @@ -5,22 +5,6 @@ LL | #[sanitize(brontosaurus = "off")] | ^^^^^^^^^^^------------^^^^^^^^^^ | | | valid arguments are "address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread", "hwaddress" or "realtime" - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[sanitize(brontosaurus = "off")] -LL + #[sanitize(address = "on|off")] - | -LL - #[sanitize(brontosaurus = "off")] -LL + #[sanitize(cfi = "on|off")] - | -LL - #[sanitize(brontosaurus = "off")] -LL + #[sanitize(hwaddress = "on|off")] - | -LL - #[sanitize(brontosaurus = "off")] -LL + #[sanitize(kcfi = "on|off")] - | - = and 6 other candidates error: multiple `sanitize` attributes --> $DIR/invalid-sanitize.rs:7:1 @@ -53,62 +37,18 @@ LL | #[sanitize(address = "bogus")] | ^^^^^^^^^^^^^^^^^^^^^-------^^ | | | valid arguments are "on" or "off" - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[sanitize(address = "bogus")] -LL + #[sanitize(address = "on|off")] - | -LL - #[sanitize(address = "bogus")] -LL + #[sanitize(cfi = "on|off")] - | -LL - #[sanitize(address = "bogus")] -LL + #[sanitize(hwaddress = "on|off")] - | -LL - #[sanitize(address = "bogus")] -LL + #[sanitize(kcfi = "on|off")] - | - = and 6 other candidates error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:18:1 | LL | #[sanitize = "off"] | ^^^^^^^^^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[sanitize = "off"] -LL + #[sanitize(address = "on|off")] - | -LL - #[sanitize = "off"] -LL + #[sanitize(cfi = "on|off")] - | -LL - #[sanitize = "off"] -LL + #[sanitize(hwaddress = "on|off")] - | -LL - #[sanitize = "off"] -LL + #[sanitize(kcfi = "on|off")] - | - = and 6 other candidates error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:21:1 | LL | #[sanitize] | ^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL | #[sanitize(address = "on|off")] - | ++++++++++++++++++++ -LL | #[sanitize(cfi = "on|off")] - | ++++++++++++++++ -LL | #[sanitize(hwaddress = "on|off")] - | ++++++++++++++++++++++ -LL | #[sanitize(kcfi = "on|off")] - | +++++++++++++++++ - = and 6 other candidates error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:24:1 @@ -117,22 +57,6 @@ LL | #[sanitize(realtime = "on")] | ^^^^^^^^^^^^^^^^^^^^^^----^^ | | | valid arguments are "nonblocking", "blocking" or "caller" - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[sanitize(realtime = "on")] -LL + #[sanitize(address = "on|off")] - | -LL - #[sanitize(realtime = "on")] -LL + #[sanitize(cfi = "on|off")] - | -LL - #[sanitize(realtime = "on")] -LL + #[sanitize(hwaddress = "on|off")] - | -LL - #[sanitize(realtime = "on")] -LL + #[sanitize(kcfi = "on|off")] - | - = and 6 other candidates warning: the async executor can run blocking code, without realtime sanitizer catching it --> $DIR/invalid-sanitize.rs:27:1 diff --git a/tests/ui/wasm/wasm-import-module.stderr b/tests/ui/wasm/wasm-import-module.stderr index f5ea449839bb..6171f04f862c 100644 --- a/tests/ui/wasm/wasm-import-module.stderr +++ b/tests/ui/wasm/wasm-import-module.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "...", wasm_import_module)] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/wasm-import-module.rs:6:1 @@ -32,21 +17,6 @@ LL | #[link(name = "...", wasm_import_module(x))] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module(x))] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module(x))] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module(x))] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module(x))] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/wasm-import-module.rs:9:1 @@ -57,21 +27,6 @@ LL | #[link(name = "...", wasm_import_module())] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: `wasm_import_module` is incompatible with other arguments in `#[link]` attributes --> $DIR/wasm-import-module.rs:12:8 From 8f9a93d0fd9bcfc4a3e1f0837a7a3d8e6d4230f6 Mon Sep 17 00:00:00 2001 From: Coca Date: Fri, 12 Dec 2025 14:26:28 +0000 Subject: [PATCH 0679/3801] `transmuting_null`: Check const integer casts changelog: [`transmuting_null`]: now checks const integers being casted to pointers --- clippy_lints/src/transmute/transmuting_null.rs | 9 ++------- tests/ui/transmuting_null.rs | 8 ++++++++ tests/ui/transmuting_null.stderr | 8 +++++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/transmute/transmuting_null.rs b/clippy_lints/src/transmute/transmuting_null.rs index 1a6262f2ff76..31e770f421e1 100644 --- a/clippy_lints/src/transmute/transmuting_null.rs +++ b/clippy_lints/src/transmute/transmuting_null.rs @@ -1,6 +1,6 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint; -use clippy_utils::is_integer_literal; +use clippy_utils::is_integer_const; use clippy_utils::res::{MaybeDef, MaybeResPath}; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; @@ -27,7 +27,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t // Catching: // `std::mem::transmute(0 as *const i32)` if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind - && is_integer_literal(inner_expr, 0) + && is_integer_const(cx, inner_expr, 0) { span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG); return true; @@ -42,10 +42,5 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t return true; } - // FIXME: - // Also catch transmutations of variables which are known nulls. - // To do this, MIR const propagation seems to be the better tool. - // Whenever MIR const prop routines are more developed, this will - // become available. As of this writing (25/03/19) it is not yet. false } diff --git a/tests/ui/transmuting_null.rs b/tests/ui/transmuting_null.rs index f3eb5060cd0d..0d3b26673452 100644 --- a/tests/ui/transmuting_null.rs +++ b/tests/ui/transmuting_null.rs @@ -30,7 +30,15 @@ fn transmute_const() { } } +fn transmute_const_int() { + unsafe { + let _: &u64 = std::mem::transmute(u64::MIN as *const u64); + //~^ transmuting_null + } +} + fn main() { one_liners(); transmute_const(); + transmute_const_int(); } diff --git a/tests/ui/transmuting_null.stderr b/tests/ui/transmuting_null.stderr index c68e4102e405..ed7c3396a243 100644 --- a/tests/ui/transmuting_null.stderr +++ b/tests/ui/transmuting_null.stderr @@ -19,5 +19,11 @@ error: transmuting a known null pointer into a reference LL | let _: &u64 = std::mem::transmute(ZPTR); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: transmuting a known null pointer into a reference + --> tests/ui/transmuting_null.rs:35:23 + | +LL | let _: &u64 = std::mem::transmute(u64::MIN as *const u64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors From a2cff48048b5090557fbd53931431c73681d0cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 12 Dec 2025 16:13:58 +0100 Subject: [PATCH 0680/3801] Refactor and document `PlainSourceTarball` --- src/bootstrap/src/core/build_steps/dist.rs | 205 ++++++++++----------- 1 file changed, 102 insertions(+), 103 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 40149ee09427..24781083bfab 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1210,6 +1210,8 @@ impl Step for Src { } } +/// Tarball for people who want to build rustc and other components from the source. +/// Does not contain GPL code for licensing reasons. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct PlainSourceTarball; @@ -1232,51 +1234,18 @@ impl Step for PlainSourceTarball { /// Creates the plain source tarball fn run(self, builder: &Builder<'_>) -> GeneratedTarball { - // NOTE: This is a strange component in a lot of ways. It uses `src` as the target, which - // means neither rustup nor rustup-toolchain-install-master know how to download it. - // It also contains symbolic links, unlike other any other dist tarball. - // It's used for distros building rustc from source in a pre-vendored environment. - let mut tarball = Tarball::new(builder, "rustc", "src"); - tarball.permit_symlinks(true); - let plain_dst_src = tarball.image_dir(); - - // This is the set of root paths which will become part of the source package - let src_files = [ - // tidy-alphabetical-start - ".gitmodules", - "CONTRIBUTING.md", - "COPYRIGHT", - "Cargo.lock", - "Cargo.toml", - "LICENSE-APACHE", - "LICENSE-MIT", - "README.md", - "RELEASES.md", - "REUSE.toml", - "bootstrap.example.toml", - "configure", - "license-metadata.json", - "package.json", - "x", - "x.ps1", - "x.py", - "yarn.lock", - // tidy-alphabetical-end - ]; - let src_dirs = ["src", "compiler", "library", "tests", "LICENSES"]; - - copy_src_dirs( + let tarball = prepare_source_tarball( builder, - &builder.src, - &src_dirs, + "src", &[ // We don't currently use the GCC source code for building any official components, // it is very big, and has unclear licensing implications due to being GPL licensed. // We thus exclude it from the source tarball from now. "src/gcc", ], - plain_dst_src, ); + + let plain_dst_src = tarball.image_dir(); // We keep something in src/gcc because it is a registered submodule, // and if it misses completely it can cause issues elsewhere // (see https://github.com/rust-lang/rust/issues/137332). @@ -1288,76 +1257,106 @@ impl Step for PlainSourceTarball { "The GCC source code is not included due to unclear licensing implications\n" )); } - - // Copy the files normally - for item in &src_files { - builder.copy_link( - &builder.src.join(item), - &plain_dst_src.join(item), - FileType::Regular, - ); - } - - // Create the version file - builder.create(&plain_dst_src.join("version"), &builder.rust_version()); - - // Create the files containing git info, to ensure --version outputs the same. - let write_git_info = |info: Option<&Info>, path: &Path| { - if let Some(info) = info { - t!(std::fs::create_dir_all(path)); - channel::write_commit_hash_file(path, &info.sha); - channel::write_commit_info_file(path, info); - } - }; - write_git_info(builder.rust_info().info(), plain_dst_src); - write_git_info(builder.cargo_info.info(), &plain_dst_src.join("./src/tools/cargo")); - - if builder.config.dist_vendor { - builder.require_and_update_all_submodules(); - - // Vendor packages that are required by opt-dist to collect PGO profiles. - let pkgs_for_pgo_training = build_helper::LLVM_PGO_CRATES - .iter() - .chain(build_helper::RUSTC_PGO_CRATES) - .map(|pkg| { - let mut manifest_path = - builder.src.join("./src/tools/rustc-perf/collector/compile-benchmarks"); - manifest_path.push(pkg); - manifest_path.push("Cargo.toml"); - manifest_path - }); - - // Vendor all Cargo dependencies - let vendor = builder.ensure(Vendor { - sync_args: pkgs_for_pgo_training.collect(), - versioned_dirs: true, - root_dir: plain_dst_src.into(), - output_dir: VENDOR_DIR.into(), - }); - - let cargo_config_dir = plain_dst_src.join(".cargo"); - builder.create_dir(&cargo_config_dir); - builder.create(&cargo_config_dir.join("config.toml"), &vendor.config); - } - - // Delete extraneous directories - // FIXME: if we're managed by git, we should probably instead ask git if the given path - // is managed by it? - for entry in walkdir::WalkDir::new(tarball.image_dir()) - .follow_links(true) - .into_iter() - .filter_map(|e| e.ok()) - { - if entry.path().is_dir() && entry.path().file_name() == Some(OsStr::new("__pycache__")) - { - t!(fs::remove_dir_all(entry.path())); - } - } - tarball.bare() } } +fn prepare_source_tarball(builder: &Builder<'_>, name: &str, exclude_dirs: &[&str]) -> Tarball { + // NOTE: This is a strange component in a lot of ways. It uses `src` as the target, which + // means neither rustup nor rustup-toolchain-install-master know how to download it. + // It also contains symbolic links, unlike other any other dist tarball. + // It's used for distros building rustc from source in a pre-vendored environment. + let mut tarball = Tarball::new(builder, "rustc", name); + tarball.permit_symlinks(true); + let plain_dst_src = tarball.image_dir(); + + // This is the set of root paths which will become part of the source package + let src_files = [ + // tidy-alphabetical-start + ".gitmodules", + "CONTRIBUTING.md", + "COPYRIGHT", + "Cargo.lock", + "Cargo.toml", + "LICENSE-APACHE", + "LICENSE-MIT", + "README.md", + "RELEASES.md", + "REUSE.toml", + "bootstrap.example.toml", + "configure", + "license-metadata.json", + "package.json", + "x", + "x.ps1", + "x.py", + "yarn.lock", + // tidy-alphabetical-end + ]; + let src_dirs = ["src", "compiler", "library", "tests", "LICENSES"]; + + copy_src_dirs(builder, &builder.src, &src_dirs, exclude_dirs, plain_dst_src); + + // Copy the files normally + for item in &src_files { + builder.copy_link(&builder.src.join(item), &plain_dst_src.join(item), FileType::Regular); + } + + // Create the version file + builder.create(&plain_dst_src.join("version"), &builder.rust_version()); + + // Create the files containing git info, to ensure --version outputs the same. + let write_git_info = |info: Option<&Info>, path: &Path| { + if let Some(info) = info { + t!(std::fs::create_dir_all(path)); + channel::write_commit_hash_file(path, &info.sha); + channel::write_commit_info_file(path, info); + } + }; + write_git_info(builder.rust_info().info(), plain_dst_src); + write_git_info(builder.cargo_info.info(), &plain_dst_src.join("./src/tools/cargo")); + + if builder.config.dist_vendor { + builder.require_and_update_all_submodules(); + + // Vendor packages that are required by opt-dist to collect PGO profiles. + let pkgs_for_pgo_training = + build_helper::LLVM_PGO_CRATES.iter().chain(build_helper::RUSTC_PGO_CRATES).map(|pkg| { + let mut manifest_path = + builder.src.join("./src/tools/rustc-perf/collector/compile-benchmarks"); + manifest_path.push(pkg); + manifest_path.push("Cargo.toml"); + manifest_path + }); + + // Vendor all Cargo dependencies + let vendor = builder.ensure(Vendor { + sync_args: pkgs_for_pgo_training.collect(), + versioned_dirs: true, + root_dir: plain_dst_src.into(), + output_dir: VENDOR_DIR.into(), + }); + + let cargo_config_dir = plain_dst_src.join(".cargo"); + builder.create_dir(&cargo_config_dir); + builder.create(&cargo_config_dir.join("config.toml"), &vendor.config); + } + + // Delete extraneous directories + // FIXME: if we're managed by git, we should probably instead ask git if the given path + // is managed by it? + for entry in walkdir::WalkDir::new(tarball.image_dir()) + .follow_links(true) + .into_iter() + .filter_map(|e| e.ok()) + { + if entry.path().is_dir() && entry.path().file_name() == Some(OsStr::new("__pycache__")) { + t!(fs::remove_dir_all(entry.path())); + } + } + tarball +} + #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Cargo { pub build_compiler: Compiler, From acc3a0e2da38051690d45e8f2ad620baf4600015 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 19 Nov 2025 20:01:24 +0000 Subject: [PATCH 0681/3801] Syntactically distinguish anon const const args --- compiler/rustc_ast/src/ast.rs | 43 +++++---- compiler/rustc_ast/src/visit.rs | 1 + compiler/rustc_ast_lowering/src/expr.rs | 6 +- compiler/rustc_ast_lowering/src/lib.rs | 80 ++++++++++++++-- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_builtin_macros/src/autodiff.rs | 10 +- .../rustc_builtin_macros/src/pattern_type.rs | 18 +++- compiler/rustc_expand/src/build.rs | 5 +- compiler/rustc_parse/src/parser/asm.rs | 4 +- .../rustc_parse/src/parser/diagnostics.rs | 71 ++++++-------- compiler/rustc_parse/src/parser/expr.rs | 28 +++++- compiler/rustc_parse/src/parser/item.rs | 13 ++- compiler/rustc_parse/src/parser/mod.rs | 26 +++++- compiler/rustc_parse/src/parser/path.rs | 88 ++++++++++++++++-- compiler/rustc_parse/src/parser/ty.rs | 25 +++-- compiler/rustc_resolve/src/late.rs | 17 ++-- .../assoc-const-eq-ambiguity.rs | 2 +- .../assoc-const-eq-ambiguity.stderr | 8 +- .../assoc-const-eq-bound-var-in-ty-not-wf.rs | 2 +- ...soc-const-eq-bound-var-in-ty-not-wf.stderr | 12 +-- .../assoc-const-eq-bound-var-in-ty.rs | 2 +- .../assoc-const-eq-esc-bound-var-in-ty.rs | 2 +- .../assoc-const-eq-esc-bound-var-in-ty.stderr | 2 +- .../assoc-const-eq-param-in-ty.rs | 34 +++---- .../assoc-const-eq-param-in-ty.stderr | 63 +++++++------ tests/ui/associated-consts/assoc-const.rs | 4 +- tests/ui/associated-consts/issue-110933.rs | 2 +- .../const-projection-err.rs | 4 - ...gce.stderr => const-projection-err.stderr} | 8 +- .../duplicate-bound-err.rs | 4 +- .../duplicate-bound-err.stderr | 46 +++++----- .../associated-type-bounds/duplicate-bound.rs | 4 +- .../unconstrained_impl_param.rs | 2 +- .../unconstrained_impl_param.stderr | 6 +- .../mgca/explicit_anon_consts.rs | 70 ++++++++++++++ .../mgca/explicit_anon_consts.stderr | 92 +++++++++++++++++++ .../explicit_anon_consts_literals_hack.rs | 22 +++++ .../mgca/multi_braced_direct_const_args.rs | 25 +++++ .../mgca/type_const-not-constparamty.rs | 8 +- .../mgca/type_const-not-constparamty.stderr | 4 +- .../mgca/type_const-on-generic-expr.rs | 10 +- .../mgca/type_const-on-generic-expr.stderr | 30 +++--- .../unbraced_const_block_const_arg_gated.rs | 42 +++++++++ ...nbraced_const_block_const_arg_gated.stderr | 73 +++++++++++++++ .../mgca/using-fnptr-as-type_const.rs | 2 +- .../assoc-const-no-infer-ice-115806.rs | 4 +- .../assoc-const-no-infer-ice-115806.stderr | 4 +- .../associated-const-equality.rs | 2 +- 48 files changed, 779 insertions(+), 252 deletions(-) rename tests/ui/associated-type-bounds/{const-projection-err.gce.stderr => const-projection-err.stderr} (66%) create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts.rs create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts.stderr create mode 100644 tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs create mode 100644 tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs create mode 100644 tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs create mode 100644 tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index e348cc1ab281..a2975935ef55 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -141,16 +141,11 @@ impl Path { /// Check if this path is potentially a trivial const arg, i.e., one that can _potentially_ /// be represented without an anon const in the HIR. /// - /// If `allow_mgca_arg` is true (as should be the case in most situations when - /// `#![feature(min_generic_const_args)]` is enabled), then this always returns true - /// because all paths are valid. - /// - /// Otherwise, it returns true iff the path has exactly one segment, and it has no generic args + /// Returns true iff the path has exactly one segment, and it has no generic args /// (i.e., it is _potentially_ a const parameter). #[tracing::instrument(level = "debug", ret)] - pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool { - allow_mgca_arg - || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none()) + pub fn is_potential_trivial_const_arg(&self) -> bool { + self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none()) } } @@ -1385,6 +1380,15 @@ pub enum UnsafeSource { UserProvided, } +/// Track whether under `feature(min_generic_const_args)` this anon const +/// was explicitly disambiguated as an anon const or not through the use of +/// `const { ... }` syntax. +#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)] +pub enum MgcaDisambiguation { + AnonConst, + Direct, +} + /// A constant (expression) that's not an item or associated item, /// but needs its own `DefId` for type-checking, const-eval, etc. /// These are usually found nested inside types (e.g., array lengths) @@ -1394,6 +1398,7 @@ pub enum UnsafeSource { pub struct AnonConst { pub id: NodeId, pub value: Box, + pub mgca_disambiguation: MgcaDisambiguation, } /// An expression. @@ -1412,26 +1417,20 @@ impl Expr { /// /// This will unwrap at most one block level (curly braces). After that, if the expression /// is a path, it mostly dispatches to [`Path::is_potential_trivial_const_arg`]. - /// See there for more info about `allow_mgca_arg`. /// - /// The only additional thing to note is that when `allow_mgca_arg` is false, this function - /// will only allow paths with no qself, before dispatching to the `Path` function of - /// the same name. + /// This function will only allow paths with no qself, before dispatching to the `Path` + /// function of the same name. /// /// Does not ensure that the path resolves to a const param/item, the caller should check this. /// This also does not consider macros, so it's only correct after macro-expansion. - pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool { + pub fn is_potential_trivial_const_arg(&self) -> bool { let this = self.maybe_unwrap_block(); - if allow_mgca_arg { - matches!(this.kind, ExprKind::Path(..)) + if let ExprKind::Path(None, path) = &this.kind + && path.is_potential_trivial_const_arg() + { + true } else { - if let ExprKind::Path(None, path) = &this.kind - && path.is_potential_trivial_const_arg(allow_mgca_arg) - { - true - } else { - false - } + false } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 7a0424d39575..49bff8fdd65d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -415,6 +415,7 @@ macro_rules! common_visitor_and_walkers { UnsafeBinderCastKind, BinOpKind, BlockCheckMode, + MgcaDisambiguation, BorrowKind, BoundAsyncness, BoundConstness, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 7230e1c42474..c8a311443a58 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -489,7 +489,11 @@ impl<'hir> LoweringContext<'_, 'hir> { arg }; - let anon_const = AnonConst { id: node_id, value: const_value }; + let anon_const = AnonConst { + id: node_id, + value: const_value, + mgca_disambiguation: MgcaDisambiguation::AnonConst, + }; generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const))); } else { real_args.push(arg); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c20bbcca44f7..47a8f744820f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1219,7 +1219,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .and_then(|partial_res| partial_res.full_res()) { if !res.matches_ns(Namespace::TypeNS) - && path.is_potential_trivial_const_arg(false) + && path.is_potential_trivial_const_arg() { debug!( "lower_generic_arg: Lowering type argument as const argument: {:?}", @@ -2287,11 +2287,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> &'hir hir::ConstArg<'hir> { let tcx = self.tcx; - let ct_kind = if path - .is_potential_trivial_const_arg(tcx.features().min_generic_const_args()) - && (tcx.features().min_generic_const_args() - || matches!(res, Res::Def(DefKind::ConstParam, _))) - { + let is_trivial_path = path.is_potential_trivial_const_arg() + && matches!(res, Res::Def(DefKind::ConstParam, _)); + let ct_kind = if is_trivial_path || tcx.features().min_generic_const_args() { let qpath = self.lower_qpath( ty_id, &None, @@ -2370,6 +2368,53 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } + #[instrument(level = "debug", skip(self), ret)] + fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir> { + let overly_complex_const = |this: &mut Self| { + let e = this.dcx().struct_span_err( + expr.span, + "complex const arguments must be placed inside of a `const` block", + ); + + ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(expr.span, e.emit()) } + }; + + match &expr.kind { + ExprKind::Path(qself, path) => { + let qpath = self.lower_qpath( + expr.id, + qself, + path, + ParamMode::Explicit, + AllowReturnTypeNotation::No, + // FIXME(mgca): update for `fn foo() -> Bar>` support + ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, + ); + + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath) } + } + ExprKind::Underscore => ConstArg { + hir_id: self.lower_node_id(expr.id), + kind: hir::ConstArgKind::Infer(expr.span, ()), + }, + ExprKind::Block(block, _) => { + if let [stmt] = block.stmts.as_slice() + && let StmtKind::Expr(expr) = &stmt.kind + && matches!( + expr.kind, + ExprKind::Block(..) | ExprKind::Path(..) | ExprKind::Struct(..) + ) + { + return self.lower_expr_to_const_arg_direct(expr); + } + + overly_complex_const(self) + } + _ => overly_complex_const(self), + } + } + /// See [`hir::ConstArg`] for when to use this function vs /// [`Self::lower_anon_const_to_anon_const`]. fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> { @@ -2379,6 +2424,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "debug", skip(self))] fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> { let tcx = self.tcx; + + // We cannot change parsing depending on feature gates available, + // we can only require feature gates to be active as a delayed check. + // Thus we just parse anon consts generally and make the real decision + // making in ast lowering. + // FIXME(min_generic_const_args): revisit once stable + if tcx.features().min_generic_const_args() { + return match anon.mgca_disambiguation { + MgcaDisambiguation::AnonConst => { + let lowered_anon = self.lower_anon_const_to_anon_const(anon); + ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) } + } + MgcaDisambiguation::Direct => self.lower_expr_to_const_arg_direct(&anon.value), + }; + } + // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments // currently have to be wrapped in curly brackets, so it's necessary to special-case. let expr = if let ExprKind::Block(block, _) = &anon.value.kind @@ -2390,12 +2451,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { &anon.value }; + let maybe_res = self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res()); if let ExprKind::Path(qself, path) = &expr.kind - && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args()) - && (tcx.features().min_generic_const_args() - || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _)))) + && path.is_potential_trivial_const_arg() + && matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))) { let qpath = self.lower_qpath( expr.id, @@ -2403,7 +2464,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path, ParamMode::Explicit, AllowReturnTypeNotation::No, - // FIXME(mgca): update for `fn foo() -> Bar>` support ImplTraitContext::Disallowed(ImplTraitPosition::Path), None, ); diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 88e9bbd71060..dbbd3906b525 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -517,6 +517,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(fn_delegation, "functions delegation is not yet fully implemented"); gate_all!(postfix_match, "postfix match is experimental"); gate_all!(mut_ref, "mutable by-reference bindings are experimental"); + gate_all!(min_generic_const_args, "unbraced const blocks as const args are experimental"); gate_all!(global_registration, "global registration is experimental"); gate_all!(return_type_notation, "return type notation is experimental"); gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index ddc59bfe1414..9de70b8ced1d 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -17,7 +17,7 @@ mod llvm_enzyme { use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemKind, BindingMode, FnRetTy, FnSig, GenericArg, GenericArgs, GenericParamKind, Generics, ItemKind, - MetaItemInner, PatKind, Path, PathSegment, TyKind, Visibility, + MetaItemInner, MgcaDisambiguation, PatKind, Path, PathSegment, TyKind, Visibility, }; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Ident, Span, Symbol, sym}; @@ -558,7 +558,11 @@ mod llvm_enzyme { } GenericParamKind::Const { .. } => { let expr = ecx.expr_path(ast::Path::from_ident(p.ident)); - let anon_const = AnonConst { id: ast::DUMMY_NODE_ID, value: expr }; + let anon_const = AnonConst { + id: ast::DUMMY_NODE_ID, + value: expr, + mgca_disambiguation: MgcaDisambiguation::Direct, + }; Some(AngleBracketedArg::Arg(GenericArg::Const(anon_const))) } GenericParamKind::Lifetime { .. } => None, @@ -813,6 +817,7 @@ mod llvm_enzyme { let anon_const = rustc_ast::AnonConst { id: ast::DUMMY_NODE_ID, value: ecx.expr_usize(span, 1 + x.width as usize), + mgca_disambiguation: MgcaDisambiguation::Direct, }; TyKind::Array(ty.clone(), anon_const) }; @@ -827,6 +832,7 @@ mod llvm_enzyme { let anon_const = rustc_ast::AnonConst { id: ast::DUMMY_NODE_ID, value: ecx.expr_usize(span, x.width as usize), + mgca_disambiguation: MgcaDisambiguation::Direct, }; let kind = TyKind::Array(ty.clone(), anon_const); let ty = diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs index 87a5a440140e..4126547b0515 100644 --- a/compiler/rustc_builtin_macros/src/pattern_type.rs +++ b/compiler/rustc_builtin_macros/src/pattern_type.rs @@ -1,5 +1,5 @@ use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast, token}; +use rustc_ast::{AnonConst, DUMMY_NODE_ID, MgcaDisambiguation, Ty, TyPat, TyPatKind, ast, token}; use rustc_errors::PResult; use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; use rustc_parse::exp; @@ -60,8 +60,20 @@ fn ty_pat(kind: TyPatKind, span: Span) -> TyPat { fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> TyPat { let kind = match pat.kind { ast::PatKind::Range(start, end, include_end) => TyPatKind::Range( - start.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })), - end.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })), + start.map(|value| { + Box::new(AnonConst { + id: DUMMY_NODE_ID, + value, + mgca_disambiguation: MgcaDisambiguation::Direct, + }) + }), + end.map(|value| { + Box::new(AnonConst { + id: DUMMY_NODE_ID, + value, + mgca_disambiguation: MgcaDisambiguation::Direct, + }) + }), include_end, ), ast::PatKind::Or(variants) => { diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 6be65b0fff16..e5c06889f3e0 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -2,8 +2,8 @@ use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::TokenStream; use rustc_ast::util::literal; use rustc_ast::{ - self as ast, AnonConst, AttrItem, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, - UnOp, attr, token, tokenstream, + self as ast, AnonConst, AttrItem, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, + MgcaDisambiguation, PatKind, UnOp, attr, token, tokenstream, }; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; @@ -101,6 +101,7 @@ impl<'a> ExtCtxt<'a> { attrs: AttrVec::new(), tokens: None, }), + mgca_disambiguation: MgcaDisambiguation::Direct, } } diff --git a/compiler/rustc_parse/src/parser/asm.rs b/compiler/rustc_parse/src/parser/asm.rs index 41c3b0f0b676..caec877232a6 100644 --- a/compiler/rustc_parse/src/parser/asm.rs +++ b/compiler/rustc_parse/src/parser/asm.rs @@ -1,4 +1,4 @@ -use rustc_ast::{self as ast, AsmMacro}; +use rustc_ast::{self as ast, AsmMacro, MgcaDisambiguation}; use rustc_span::{Span, Symbol, kw}; use super::{ExpKeywordPair, ForceCollect, IdentIsRaw, Trailing, UsePreAttrPos}; @@ -149,7 +149,7 @@ fn parse_asm_operand<'a>( let block = p.parse_block()?; ast::InlineAsmOperand::Label { block } } else if p.eat_keyword(exp!(Const)) { - let anon_const = p.parse_expr_anon_const()?; + let anon_const = p.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?; ast::InlineAsmOperand::Const { anon_const } } else if p.eat_keyword(exp!(Sym)) { let expr = p.parse_expr()?; diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 4f6860fead8d..d7d343ac16b4 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -6,8 +6,8 @@ use rustc_ast::token::{self, Lit, LitKind, Token, TokenKind}; use rustc_ast::util::parser::AssocOp; use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, - Block, BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, - PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind, + Block, BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, + MgcaDisambiguation, Param, Pat, PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; @@ -31,16 +31,15 @@ use crate::errors::{ AddParen, AmbiguousPlus, AsyncMoveBlockIn2015, AsyncUseBlockIn2015, AttributeOnParamType, AwaitSuggestion, BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi, ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg, - ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, DocCommentDoesNotDocumentAnything, - DocCommentOnParamType, DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, - GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg, - HelpIdentifierStartsWithNumber, HelpUseLatestEdition, InInTypo, IncorrectAwait, - IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, PatternMethodParamWithoutBody, - QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath, - StructLiteralBodyWithoutPathSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, - TernaryOperator, TernaryOperatorSuggestion, UnexpectedConstInGenericParam, - UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, - UseEqInstead, WrapType, + DocCommentDoesNotDocumentAnything, DocCommentOnParamType, DoubleColonInBound, + ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, GenericParamsWithoutAngleBrackets, + GenericParamsWithoutAngleBracketsSugg, HelpIdentifierStartsWithNumber, HelpUseLatestEdition, + InInTypo, IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, + PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, + StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, SuggAddMissingLetStmt, + SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator, TernaryOperatorSuggestion, + UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration, + UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType, }; use crate::parser::FnContext; use crate::parser::attr::InnerAttrPolicy; @@ -2558,36 +2557,6 @@ impl<'a> Parser<'a> { Ok(false) // Don't continue. } - /// Attempt to parse a generic const argument that has not been enclosed in braces. - /// There are a limited number of expressions that are permitted without being encoded - /// in braces: - /// - Literals. - /// - Single-segment paths (i.e. standalone generic const parameters). - /// All other expressions that can be parsed will emit an error suggesting the expression be - /// wrapped in braces. - pub(super) fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, Box> { - let start = self.token.span; - let attrs = self.parse_outer_attributes()?; - let (expr, _) = - self.parse_expr_res(Restrictions::CONST_EXPR, attrs).map_err(|mut err| { - err.span_label( - start.shrink_to_lo(), - "while parsing a const generic argument starting here", - ); - err - })?; - if !self.expr_is_valid_const_arg(&expr) { - self.dcx().emit_err(ConstGenericWithoutBraces { - span: expr.span, - sugg: ConstGenericWithoutBracesSugg { - left: expr.span.shrink_to_lo(), - right: expr.span.shrink_to_hi(), - }, - }); - } - Ok(expr) - } - fn recover_const_param_decl(&mut self, ty_generics: Option<&Generics>) -> Option { let snapshot = self.create_snapshot_for_diagnostic(); let param = match self.parse_const_param(AttrVec::new()) { @@ -2623,7 +2592,11 @@ impl<'a> Parser<'a> { self.dcx().emit_err(UnexpectedConstParamDeclaration { span: param.span(), sugg }); let value = self.mk_expr_err(param.span(), guar); - Some(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })) + Some(GenericArg::Const(AnonConst { + id: ast::DUMMY_NODE_ID, + value, + mgca_disambiguation: MgcaDisambiguation::Direct, + })) } pub(super) fn recover_const_param_declaration( @@ -2707,7 +2680,11 @@ impl<'a> Parser<'a> { ); let guar = err.emit(); let value = self.mk_expr_err(start.to(expr.span), guar); - return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })); + return Ok(GenericArg::Const(AnonConst { + id: ast::DUMMY_NODE_ID, + value, + mgca_disambiguation: MgcaDisambiguation::Direct, + })); } else if snapshot.token == token::Colon && expr.span.lo() == snapshot.token.span.hi() && matches!(expr.kind, ExprKind::Path(..)) @@ -2776,7 +2753,11 @@ impl<'a> Parser<'a> { ); let guar = err.emit(); let value = self.mk_expr_err(span, guar); - GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }) + GenericArg::Const(AnonConst { + id: ast::DUMMY_NODE_ID, + value, + mgca_disambiguation: MgcaDisambiguation::Direct, + }) } /// Some special error handling for the "top-level" patterns in a match arm, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index fa5e61d24d91..3f0853a3c54d 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -15,8 +15,8 @@ use rustc_ast::visit::{Visitor, walk_expr}; use rustc_ast::{ self as ast, AnonConst, Arm, AssignOp, AssignOpKind, AttrStyle, AttrVec, BinOp, BinOpKind, BlockCheckMode, CaptureBy, ClosureBinder, DUMMY_NODE_ID, Expr, ExprField, ExprKind, FnDecl, - FnRetTy, Label, MacCall, MetaItemLit, Movability, Param, RangeLimits, StmtKind, Ty, TyKind, - UnOp, UnsafeBinderCastKind, YieldKind, + FnRetTy, Label, MacCall, MetaItemLit, MgcaDisambiguation, Movability, Param, RangeLimits, + StmtKind, Ty, TyKind, UnOp, UnsafeBinderCastKind, YieldKind, }; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic}; @@ -85,8 +85,15 @@ impl<'a> Parser<'a> { ) } - pub fn parse_expr_anon_const(&mut self) -> PResult<'a, AnonConst> { - self.parse_expr().map(|value| AnonConst { id: DUMMY_NODE_ID, value }) + pub fn parse_expr_anon_const( + &mut self, + mgca_disambiguation: impl FnOnce(&Self, &Expr) -> MgcaDisambiguation, + ) -> PResult<'a, AnonConst> { + self.parse_expr().map(|value| AnonConst { + id: DUMMY_NODE_ID, + mgca_disambiguation: mgca_disambiguation(self, &value), + value, + }) } fn parse_expr_catch_underscore( @@ -1615,7 +1622,18 @@ impl<'a> Parser<'a> { let first_expr = self.parse_expr()?; if self.eat(exp!(Semi)) { // Repeating array syntax: `[ 0; 512 ]` - let count = self.parse_expr_anon_const()?; + let count = if self.token.is_keyword(kw::Const) + && self.look_ahead(1, |t| *t == token::OpenBrace) + { + // While we could just disambiguate `Direct` from `AnonConst` by + // treating all const block exprs as `AnonConst`, that would + // complicate the DefCollector and likely all other visitors. + // So we strip the const blockiness and just store it as a block + // in the AST with the extra disambiguator on the AnonConst + self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)? + } else { + self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))? + }; self.expect(close)?; ExprKind::Repeat(first_expr, count) } else if self.eat(exp!(Comma)) { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index abc0ffa87d3d..b4ce30767cb8 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1431,7 +1431,7 @@ impl<'a> Parser<'a> { let rhs = if self.eat(exp!(Eq)) { if attr::contains_name(attrs, sym::type_const) { - Some(ConstItemRhs::TypeConst(self.parse_expr_anon_const()?)) + Some(ConstItemRhs::TypeConst(self.parse_const_arg()?)) } else { Some(ConstItemRhs::Body(self.parse_expr()?)) } @@ -1650,8 +1650,11 @@ impl<'a> Parser<'a> { VariantData::Unit(DUMMY_NODE_ID) }; - let disr_expr = - if this.eat(exp!(Eq)) { Some(this.parse_expr_anon_const()?) } else { None }; + let disr_expr = if this.eat(exp!(Eq)) { + Some(this.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?) + } else { + None + }; let vr = ast::Variant { ident, @@ -1864,7 +1867,7 @@ impl<'a> Parser<'a> { if p.token == token::Eq { let mut snapshot = p.create_snapshot_for_diagnostic(); snapshot.bump(); - match snapshot.parse_expr_anon_const() { + match snapshot.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst) { Ok(const_expr) => { let sp = ty.span.shrink_to_hi().to(const_expr.value.span); p.psess.gated_spans.gate(sym::default_field_values, sp); @@ -2066,7 +2069,7 @@ impl<'a> Parser<'a> { } let default = if self.token == token::Eq { self.bump(); - let const_expr = self.parse_expr_anon_const()?; + let const_expr = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?; let sp = ty.span.shrink_to_hi().to(const_expr.value.span); self.psess.gated_spans.gate(sym::default_field_values, sp); Some(const_expr) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 8577ea40589a..c86d586e4783 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -35,9 +35,9 @@ use rustc_ast::tokenstream::{ }; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, AnonConst, AttrArgs, AttrId, ByRef, Const, CoroutineKind, DUMMY_NODE_ID, - DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, - Visibility, VisibilityKind, + self as ast, AnonConst, AttrArgs, AttrId, BlockCheckMode, ByRef, Const, CoroutineKind, + DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, MgcaDisambiguation, + Mutability, Recovered, Safety, StrLit, Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; @@ -727,7 +727,10 @@ impl<'a> Parser<'a> { } fn check_const_arg(&mut self) -> bool { - self.check_or_expected(self.token.can_begin_const_arg(), TokenType::Const) + let is_mcg_arg = self.check_or_expected(self.token.can_begin_const_arg(), TokenType::Const); + let is_mgca_arg = self.is_keyword_ahead(0, &[kw::Const]) + && self.look_ahead(1, |t| *t == token::OpenBrace); + is_mcg_arg || is_mgca_arg } fn check_const_closure(&self) -> bool { @@ -1299,6 +1302,20 @@ impl<'a> Parser<'a> { } } + fn parse_mgca_const_block(&mut self, gate_syntax: bool) -> PResult<'a, AnonConst> { + self.expect_keyword(exp!(Const))?; + let kw_span = self.token.span; + let value = self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)?; + if gate_syntax { + self.psess.gated_spans.gate(sym::min_generic_const_args, kw_span.to(value.span)); + } + Ok(AnonConst { + id: ast::DUMMY_NODE_ID, + value, + mgca_disambiguation: MgcaDisambiguation::AnonConst, + }) + } + /// Parses inline const expressions. fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, Box> { self.expect_keyword(exp!(Const))?; @@ -1306,6 +1323,7 @@ impl<'a> Parser<'a> { let anon_const = AnonConst { id: DUMMY_NODE_ID, value: self.mk_expr(blk.span, ExprKind::Block(blk, None)), + mgca_disambiguation: MgcaDisambiguation::AnonConst, }; let blk_span = anon_const.value.span; let kind = if pat { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 437f6da67b74..ce9e9c73669e 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -4,8 +4,8 @@ use ast::token::IdentIsRaw; use rustc_ast::token::{self, MetaVarKind, Token, TokenKind}; use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemConstraint, - AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs, - Path, PathSegment, QSelf, + AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, MgcaDisambiguation, + ParenthesizedArgs, Path, PathSegment, QSelf, }; use rustc_errors::{Applicability, Diag, PResult}; use rustc_span::{BytePos, Ident, Span, kw, sym}; @@ -16,12 +16,13 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; use crate::ast::{PatKind, TyKind}; use crate::errors::{ - self, AttributeOnEmptyType, AttributeOnGenericArg, FnPathFoundNamedParams, - PathFoundAttributeInParams, PathFoundCVariadicParams, PathSingleColon, PathTripleColon, + self, AttributeOnEmptyType, AttributeOnGenericArg, ConstGenericWithoutBraces, + ConstGenericWithoutBracesSugg, FnPathFoundNamedParams, PathFoundAttributeInParams, + PathFoundCVariadicParams, PathSingleColon, PathTripleColon, }; use crate::exp; use crate::parser::{ - CommaRecoveryMode, ExprKind, FnContext, FnParseMode, RecoverColon, RecoverComma, + CommaRecoveryMode, Expr, ExprKind, FnContext, FnParseMode, RecoverColon, RecoverComma, }; /// Specifies how to parse a path. @@ -870,12 +871,75 @@ impl<'a> Parser<'a> { /// the caller. pub(super) fn parse_const_arg(&mut self) -> PResult<'a, AnonConst> { // Parse const argument. - let value = if self.token.kind == token::OpenBrace { - self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)? + let (value, mgca_disambiguation) = if self.token.kind == token::OpenBrace { + let value = self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)?; + (value, MgcaDisambiguation::Direct) + } else if self.token.is_keyword(kw::Const) { + // While we could just disambiguate `Direct` from `AnonConst` by + // treating all const block exprs as `AnonConst`, that would + // complicate the DefCollector and likely all other visitors. + // So we strip the const blockiness and just store it as a block + // in the AST with the extra disambiguator on the AnonConst + let value = self.parse_mgca_const_block(true)?; + (value.value, MgcaDisambiguation::AnonConst) } else { - self.handle_unambiguous_unbraced_const_arg()? + self.parse_unambiguous_unbraced_const_arg()? }; - Ok(AnonConst { id: ast::DUMMY_NODE_ID, value }) + Ok(AnonConst { id: ast::DUMMY_NODE_ID, value, mgca_disambiguation }) + } + + /// Attempt to parse a const argument that has not been enclosed in braces. + /// There are a limited number of expressions that are permitted without being + /// enclosed in braces: + /// - Literals. + /// - Single-segment paths (i.e. standalone generic const parameters). + /// All other expressions that can be parsed will emit an error suggesting the expression be + /// wrapped in braces. + pub(super) fn parse_unambiguous_unbraced_const_arg( + &mut self, + ) -> PResult<'a, (Box, MgcaDisambiguation)> { + let start = self.token.span; + let attrs = self.parse_outer_attributes()?; + let (expr, _) = + self.parse_expr_res(Restrictions::CONST_EXPR, attrs).map_err(|mut err| { + err.span_label( + start.shrink_to_lo(), + "while parsing a const generic argument starting here", + ); + err + })?; + if !self.expr_is_valid_const_arg(&expr) { + self.dcx().emit_err(ConstGenericWithoutBraces { + span: expr.span, + sugg: ConstGenericWithoutBracesSugg { + left: expr.span.shrink_to_lo(), + right: expr.span.shrink_to_hi(), + }, + }); + } + + let mgca_disambiguation = self.mgca_direct_lit_hack(&expr); + Ok((expr, mgca_disambiguation)) + } + + /// Under `min_generic_const_args` we still allow *some* anon consts to be written without + /// a `const` block as it makes things quite a lot nicer. This function is useful for contexts + /// where we would like to use `MgcaDisambiguation::Direct` but need to fudge it to be `AnonConst` + /// in the presence of literals. + // + /// FIXME(min_generic_const_args): In the long term it would be nice to have a way to directly + /// represent literals in `hir::ConstArgKind` so that we can remove this special case by not + /// needing an anon const. + pub fn mgca_direct_lit_hack(&self, expr: &Expr) -> MgcaDisambiguation { + match &expr.kind { + ast::ExprKind::Lit(_) => MgcaDisambiguation::AnonConst, + ast::ExprKind::Unary(ast::UnOp::Neg, expr) + if matches!(expr.kind, ast::ExprKind::Lit(_)) => + { + MgcaDisambiguation::AnonConst + } + _ => MgcaDisambiguation::Direct, + } } /// Parse a generic argument in a path segment. @@ -976,7 +1040,11 @@ impl<'a> Parser<'a> { GenericArg::Type(_) => GenericArg::Type(self.mk_ty(attr_span, TyKind::Err(guar))), GenericArg::Const(_) => { let error_expr = self.mk_expr(attr_span, ExprKind::Err(guar)); - GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value: error_expr }) + GenericArg::Const(AnonConst { + id: ast::DUMMY_NODE_ID, + value: error_expr, + mgca_disambiguation: MgcaDisambiguation::Direct, + }) } GenericArg::Lifetime(lt) => GenericArg::Lifetime(lt), })); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index c79b99a80e87..676514344586 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -2,9 +2,9 @@ use rustc_ast::token::{self, IdentIsRaw, MetaVarKind, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnPtrTy, FnRetTy, - GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, - Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, - TyKind, UnsafeBinderTy, + GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MgcaDisambiguation, + MutTy, Mutability, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, + TraitObjectSyntax, Ty, TyKind, UnsafeBinderTy, }; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Applicability, Diag, E0516, PResult}; @@ -658,7 +658,19 @@ impl<'a> Parser<'a> { }; let ty = if self.eat(exp!(Semi)) { - let mut length = self.parse_expr_anon_const()?; + let mut length = if self.token.is_keyword(kw::Const) + && self.look_ahead(1, |t| *t == token::OpenBrace) + { + // While we could just disambiguate `Direct` from `AnonConst` by + // treating all const block exprs as `AnonConst`, that would + // complicate the DefCollector and likely all other visitors. + // So we strip the const blockiness and just store it as a block + // in the AST with the extra disambiguator on the AnonConst + self.parse_mgca_const_block(false)? + } else { + self.parse_expr_anon_const(|this, expr| this.mgca_direct_lit_hack(expr))? + }; + if let Err(e) = self.expect(exp!(CloseBracket)) { // Try to recover from `X` when `X::` works self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?; @@ -699,8 +711,9 @@ impl<'a> Parser<'a> { _ = self.eat(exp!(Comma)) || self.eat(exp!(Colon)) || self.eat(exp!(Star)); let suggestion_span = self.prev_token.span.with_lo(hi); + // FIXME(mgca): recovery is broken for `const {` args // we first try to parse pattern like `[u8 5]` - let length = match self.parse_expr_anon_const() { + let length = match self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct) { Ok(length) => length, Err(e) => { e.cancel(); @@ -788,7 +801,7 @@ impl<'a> Parser<'a> { /// an error type. fn parse_typeof_ty(&mut self, lo: Span) -> PResult<'a, TyKind> { self.expect(exp!(OpenParen))?; - let _expr = self.parse_expr_anon_const()?; + let _expr = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?; self.expect(exp!(CloseParen))?; let span = lo.to(self.prev_token.span); let guar = self diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f1a03d5a0610..50e11fdde568 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1222,7 +1222,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc if let TyKind::Path(None, ref path) = ty.kind // We cannot disambiguate multi-segment paths right now as that requires type // checking. - && path.is_potential_trivial_const_arg(false) + && path.is_potential_trivial_const_arg() { let mut check_ns = |ns| { self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns) @@ -4840,9 +4840,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { constant, anon_const_kind ); - let is_trivial_const_arg = constant - .value - .is_potential_trivial_const_arg(self.r.tcx.features().min_generic_const_args()); + let is_trivial_const_arg = if self.r.tcx.features().min_generic_const_args() { + matches!(constant.mgca_disambiguation, MgcaDisambiguation::Direct) + } else { + constant.value.is_potential_trivial_const_arg() + }; + self.resolve_anon_const_manual(is_trivial_const_arg, anon_const_kind, |this| { this.resolve_expr(&constant.value, None) }) @@ -5023,9 +5026,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Constant arguments need to be treated as AnonConst since // that is how they will be later lowered to HIR. if const_args.contains(&idx) { - let is_trivial_const_arg = argument.is_potential_trivial_const_arg( - self.r.tcx.features().min_generic_const_args(), - ); + // FIXME(mgca): legacy const generics doesn't support mgca but maybe + // that's okay. + let is_trivial_const_arg = argument.is_potential_trivial_const_arg(); self.resolve_anon_const_manual( is_trivial_const_arg, AnonConstKind::ConstArg(IsRepeatExpr::No), diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs index 2ff5a0353a0a..27261a4806eb 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs @@ -10,7 +10,7 @@ trait Parent0 { const K: (); } -fn take0(_: impl Trait0) {} +fn take0(_: impl Trait0) {} //~^ ERROR ambiguous associated constant `K` in bounds of `Trait0` trait Trait1: Parent1 + Parent2 {} diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr index 3541664d1c6a..9ab39e6b8a60 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr @@ -7,14 +7,14 @@ LL | const K: (); | ambiguous `K` from `Parent0` | ambiguous `K` from `Parent0` ... -LL | fn take0(_: impl Trait0) {} - | ^^^^^^^^^^ ambiguous associated constant `K` +LL | fn take0(_: impl Trait0) {} + | ^^^^^^^^^^^^^ ambiguous associated constant `K` | = help: consider introducing a new type parameter `T` and adding `where` constraints: where T: Trait0, - T: Parent0::K = { () }, - T: Parent0::K = { () } + T: Parent0::K = { }, + T: Parent0::K = { } error[E0222]: ambiguous associated constant `C` in bounds of `Trait1` --> $DIR/assoc-const-eq-ambiguity.rs:26:25 diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index 8334e67ae9a1..7f8b3036c3e8 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -18,7 +18,7 @@ trait Trait { fn take( _: impl Trait< < fn(&'a str) -> &'a str as Project>::Out as Discard>::Out, - K = { () } + K = const { () } >, ) {} //~^^^ ERROR higher-ranked subtype error diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index 9fac60763dae..4a4c2b285829 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -1,14 +1,14 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:19 | -LL | K = { () } - | ^^^^^^ +LL | K = const { () } + | ^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:19 | -LL | K = { () } - | ^^^^^^ +LL | K = const { () } + | ^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs index ef8077b9f44a..d3975bc19ad3 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs @@ -21,7 +21,7 @@ trait Trait { fn take( _: impl Trait< fn(&'a str) -> &'a str as Discard>::Out, - K = { () } + K = const { } >, ) {} diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs index 1ab93ea596a7..2571af57e66b 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs @@ -8,7 +8,7 @@ trait Trait<'a> { const K: &'a (); } -fn take(_: impl for<'r> Trait<'r, K = { &() }>) {} +fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} //~^ ERROR the type of the associated constant `K` cannot capture late-bound generic parameters //~| NOTE its type cannot capture the late-bound lifetime parameter `'r` //~| NOTE the late-bound lifetime parameter `'r` is defined here diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr index d6a7eb6cfc7d..44304443ac54 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr @@ -1,7 +1,7 @@ error: the type of the associated constant `K` cannot capture late-bound generic parameters --> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:11:35 | -LL | fn take(_: impl for<'r> Trait<'r, K = { &() }>) {} +LL | fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} | -- ^ its type cannot capture the late-bound lifetime parameter `'r` | | | the late-bound lifetime parameter `'r` is defined here diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs index 0afb95a0b033..242ad385947a 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs @@ -15,31 +15,33 @@ trait Trait<'a, T: 'a + ConstParamTy_, const N: usize> { const K: &'a [T; N]; } -fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} -//~^ ERROR the type of the associated constant `K` must not depend on generic parameters -//~| NOTE its type must not depend on the lifetime parameter `'r` -//~| NOTE the lifetime parameter `'r` is defined here -//~| NOTE `K` has type `&'r [A; Q]` -//~| ERROR the type of the associated constant `K` must not depend on generic parameters -//~| NOTE its type must not depend on the type parameter `A` -//~| NOTE the type parameter `A` is defined here -//~| NOTE `K` has type `&'r [A; Q]` -//~| ERROR the type of the associated constant `K` must not depend on generic parameters -//~| NOTE its type must not depend on the const parameter `Q` -//~| NOTE the const parameter `Q` is defined here -//~| NOTE `K` has type `&'r [A; Q]` +fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( + //~^ NOTE the lifetime parameter `'r` is defined here + //~| NOTE the type parameter `A` is defined here + //~| NOTE the const parameter `Q` is defined here + _: impl Trait<'r, A, Q, K = const { loop {} }> + //~^ ERROR the type of the associated constant `K` must not depend on generic parameters + //~| NOTE its type must not depend on the lifetime parameter `'r` + //~| NOTE `K` has type `&'r [A; Q]` + //~| ERROR the type of the associated constant `K` must not depend on generic parameters + //~| NOTE its type must not depend on the type parameter `A` + //~| NOTE `K` has type `&'r [A; Q]` + //~| ERROR the type of the associated constant `K` must not depend on generic parameters + //~| NOTE its type must not depend on the const parameter `Q` + //~| NOTE `K` has type `&'r [A; Q]` +) {} trait Project: ConstParamTy_ { #[type_const] const SELF: Self; } -fn take1(_: impl Project) {} +fn take1(_: impl Project) {} //~^ ERROR the type of the associated constant `SELF` must not depend on `impl Trait` //~| NOTE its type must not depend on `impl Trait` //~| NOTE the `impl Trait` is specified here -fn take2>(_: P) {} +fn take2>(_: P) {} //~^ ERROR the type of the associated constant `SELF` must not depend on generic parameters //~| NOTE its type must not depend on the type parameter `P` //~| NOTE the type parameter `P` is defined here @@ -48,7 +50,7 @@ fn take2>(_: P) {} trait Iface<'r>: ConstParamTy_ { //~^ NOTE the lifetime parameter `'r` is defined here //~| NOTE the lifetime parameter `'r` is defined here - type Assoc: Trait<'r, Self, Q, K = { loop {} }> + type Assoc: Trait<'r, Self, Q, K = const { loop {} }> //~^ ERROR the type of the associated constant `K` must not depend on generic parameters //~| ERROR the type of the associated constant `K` must not depend on generic parameters //~| NOTE its type must not depend on the lifetime parameter `'r` diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr index 229dd10c0beb..b742e68044b0 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr @@ -1,42 +1,49 @@ error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 + --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 | -LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | -- the lifetime parameter `'r` is defined here ^ its type must not depend on the lifetime parameter `'r` +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( + | -- the lifetime parameter `'r` is defined here +... +LL | _: impl Trait<'r, A, Q, K = const { loop {} }> + | ^ its type must not depend on the lifetime parameter `'r` | = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 + --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 | -LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | - the type parameter `A` is defined here ^ its type must not depend on the type parameter `A` +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( + | - the type parameter `A` is defined here +... +LL | _: impl Trait<'r, A, Q, K = const { loop {} }> + | ^ its type must not depend on the type parameter `A` | = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 + --> $DIR/assoc-const-eq-param-in-ty.rs:22:29 | -LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | - ^ its type must not depend on the const parameter `Q` - | | - | the const parameter `Q` is defined here +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( + | - the const parameter `Q` is defined here +... +LL | _: impl Trait<'r, A, Q, K = const { loop {} }> + | ^ its type must not depend on the const parameter `Q` | = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/assoc-const-eq-param-in-ty.rs:37:26 + --> $DIR/assoc-const-eq-param-in-ty.rs:39:26 | -LL | fn take1(_: impl Project) {} - | -------------^^^^------ +LL | fn take1(_: impl Project) {} + | -------------^^^^------------ | | | | | its type must not depend on `impl Trait` | the `impl Trait` is specified here error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:42:21 + --> $DIR/assoc-const-eq-param-in-ty.rs:44:21 | -LL | fn take2>(_: P) {} +LL | fn take2>(_: P) {} | - ^^^^ its type must not depend on the type parameter `P` | | | the type parameter `P` is defined here @@ -44,28 +51,28 @@ LL | fn take2>(_: P) {} = note: `SELF` has type `P` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here ... -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on the lifetime parameter `'r` | = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` | = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` | | | the const parameter `Q` is defined here @@ -73,30 +80,30 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here ... -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on the lifetime parameter `'r` | = note: `K` has type `&'r [Self; Q]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` | = note: `K` has type `&'r [Self; Q]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:53:52 | -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` | | | the const parameter `Q` is defined here diff --git a/tests/ui/associated-consts/assoc-const.rs b/tests/ui/associated-consts/assoc-const.rs index 4eed8bba53b1..6295fd50b8ff 100644 --- a/tests/ui/associated-consts/assoc-const.rs +++ b/tests/ui/associated-consts/assoc-const.rs @@ -14,10 +14,10 @@ impl Foo for Bar { const N: usize = 3; } -const TEST:usize = 3; +const TEST: usize = 3; -fn foo>() {} +fn foo>() {} fn main() { foo::() diff --git a/tests/ui/associated-consts/issue-110933.rs b/tests/ui/associated-consts/issue-110933.rs index 0284369f4d65..731ff1564ce2 100644 --- a/tests/ui/associated-consts/issue-110933.rs +++ b/tests/ui/associated-consts/issue-110933.rs @@ -10,7 +10,7 @@ pub trait Trait { pub fn foo< T: Trait< - ASSOC = { + ASSOC = const { let a = 10_usize; let b: &'_ usize = &a; *b diff --git a/tests/ui/associated-type-bounds/const-projection-err.rs b/tests/ui/associated-type-bounds/const-projection-err.rs index 80845ec3ee86..b230ea77f5fe 100644 --- a/tests/ui/associated-type-bounds/const-projection-err.rs +++ b/tests/ui/associated-type-bounds/const-projection-err.rs @@ -1,10 +1,6 @@ -//@ revisions: stock gce - #![feature(associated_const_equality, min_generic_const_args)] #![allow(incomplete_features)] -#![cfg_attr(gce, feature(generic_const_exprs))] - trait TraitWAssocConst { #[type_const] const A: usize; diff --git a/tests/ui/associated-type-bounds/const-projection-err.gce.stderr b/tests/ui/associated-type-bounds/const-projection-err.stderr similarity index 66% rename from tests/ui/associated-type-bounds/const-projection-err.gce.stderr rename to tests/ui/associated-type-bounds/const-projection-err.stderr index 9ad851d188d3..552b1579e618 100644 --- a/tests/ui/associated-type-bounds/const-projection-err.gce.stderr +++ b/tests/ui/associated-type-bounds/const-projection-err.stderr @@ -1,11 +1,13 @@ error[E0271]: type mismatch resolving `::A == 1` - --> $DIR/const-projection-err.rs:16:11 + --> $DIR/const-projection-err.rs:12:11 | LL | foo::(); - | ^ expected `0`, found `1` + | ^ expected `1`, found `0` | + = note: expected constant `1` + found constant `0` note: required by a bound in `foo` - --> $DIR/const-projection-err.rs:13:28 + --> $DIR/const-projection-err.rs:9:28 | LL | fn foo>() {} | ^^^^^ required by this bound in `foo` diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.rs b/tests/ui/associated-type-bounds/duplicate-bound-err.rs index 72c1ab559bdf..7e86148eb811 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.rs @@ -81,7 +81,9 @@ fn uncallable(_: impl Iterator) {} fn uncallable_const(_: impl Trait) {} -fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} +fn uncallable_rtn( + _: impl Trait, foo(..): Trait> +) {} type MustFail = dyn Iterator; //~^ ERROR [E0719] diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr index a54425c3a295..6484880392d6 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr @@ -100,7 +100,7 @@ LL | iter::empty::() | ----------------------- return type was inferred to be `std::iter::Empty` here error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:110:17 + --> $DIR/duplicate-bound-err.rs:112:17 | LL | fn foo() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -109,7 +109,7 @@ LL | [2u32].into_iter() | ------------------ return type was inferred to be `std::array::IntoIter` here error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:86:42 + --> $DIR/duplicate-bound-err.rs:88:42 | LL | type MustFail = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -117,7 +117,7 @@ LL | type MustFail = dyn Iterator; | `Item` bound here first error: conflicting associated type bounds for `Item` - --> $DIR/duplicate-bound-err.rs:86:17 + --> $DIR/duplicate-bound-err.rs:88:17 | LL | type MustFail = dyn Iterator; | ^^^^^^^^^^^^^----------^^----------^ @@ -126,7 +126,7 @@ LL | type MustFail = dyn Iterator; | `Item` is specified to be `i32` here error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:95:43 + --> $DIR/duplicate-bound-err.rs:97:43 | LL | type MustFail2 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here @@ -134,7 +134,7 @@ LL | type MustFail2 = dyn Trait2; | `ASSOC` bound here first error: conflicting associated type bounds for `ASSOC` - --> $DIR/duplicate-bound-err.rs:95:18 + --> $DIR/duplicate-bound-err.rs:97:18 | LL | type MustFail2 = dyn Trait2; | ^^^^^^^^^^^------------^^------------^ @@ -143,7 +143,7 @@ LL | type MustFail2 = dyn Trait2; | `ASSOC` is specified to be `3` here error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:99:43 + --> $DIR/duplicate-bound-err.rs:101:43 | LL | type MustFail3 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -151,7 +151,7 @@ LL | type MustFail3 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:102:43 + --> $DIR/duplicate-bound-err.rs:104:43 | LL | type MustFail4 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here @@ -159,19 +159,19 @@ LL | type MustFail4 = dyn Trait2; | `ASSOC` bound here first error[E0271]: expected `impl Iterator` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:110:17 + --> $DIR/duplicate-bound-err.rs:112:17 | LL | fn foo() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` | note: required by a bound in `Trait3::foo::{anon_assoc#0}` - --> $DIR/duplicate-bound-err.rs:106:31 + --> $DIR/duplicate-bound-err.rs:108:31 | LL | fn foo() -> impl Iterator; | ^^^^^^^^^^ required by this bound in `Trait3::foo::{anon_assoc#0}` error[E0271]: expected `Empty` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:118:16 + --> $DIR/duplicate-bound-err.rs:120:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -185,7 +185,7 @@ LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: expected `Empty` to be an iterator that yields `u32`, but it yields `i32` - --> $DIR/duplicate-bound-err.rs:119:16 + --> $DIR/duplicate-bound-err.rs:121:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `i32` @@ -199,7 +199,7 @@ LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:120:22 + --> $DIR/duplicate-bound-err.rs:122:22 | LL | uncallable_const(()); | ---------------- ^^ expected `4`, found `3` @@ -215,7 +215,7 @@ LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:121:22 + --> $DIR/duplicate-bound-err.rs:123:22 | LL | uncallable_const(4u32); | ---------------- ^^^^ expected `3`, found `4` @@ -231,7 +231,7 @@ LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:122:20 + --> $DIR/duplicate-bound-err.rs:124:20 | LL | uncallable_rtn(()); | -------------- ^^ expected `4`, found `3` @@ -241,13 +241,15 @@ LL | uncallable_rtn(()); = note: expected constant `4` found constant `3` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:84:75 + --> $DIR/duplicate-bound-err.rs:85:61 | -LL | fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} - | ^^^^^^^^^ required by this bound in `uncallable_rtn` +LL | fn uncallable_rtn( + | -------------- required by a bound in this function +LL | _: impl Trait, foo(..): Trait> + | ^^^^^^^^^ required by this bound in `uncallable_rtn` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:123:20 + --> $DIR/duplicate-bound-err.rs:125:20 | LL | uncallable_rtn(17u32); | -------------- ^^^^^ expected `3`, found `4` @@ -257,10 +259,12 @@ LL | uncallable_rtn(17u32); = note: expected constant `3` found constant `4` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:84:48 + --> $DIR/duplicate-bound-err.rs:85:34 | -LL | fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} - | ^^^^^^^^^ required by this bound in `uncallable_rtn` +LL | fn uncallable_rtn( + | -------------- required by a bound in this function +LL | _: impl Trait, foo(..): Trait> + | ^^^^^^^^^ required by this bound in `uncallable_rtn` error: aborting due to 25 previous errors diff --git a/tests/ui/associated-type-bounds/duplicate-bound.rs b/tests/ui/associated-type-bounds/duplicate-bound.rs index 3f40e429260f..6ea0daeca2c4 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound.rs @@ -224,7 +224,9 @@ fn uncallable_const(_: impl Trait) {} fn callable_const(_: impl Trait) {} -fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} +fn uncallable_rtn( + _: impl Trait, foo(..): Trait> +) {} fn callable_rtn(_: impl Trait) {} diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs index edadcd7c80ed..f28f3f694ff3 100644 --- a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs +++ b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs @@ -12,7 +12,7 @@ impl AssocConst for (T,) { trait Trait {} -impl Trait for () where (U,): AssocConst {} +impl Trait for () where (U,): AssocConst {} //~^ ERROR associated const equality is incomplete //~| ERROR the type parameter `U` is not constrained by the impl trait diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr index 4106c500215b..092faff93511 100644 --- a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr +++ b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr @@ -1,8 +1,8 @@ error[E0658]: associated const equality is incomplete --> $DIR/unconstrained_impl_param.rs:15:45 | -LL | impl Trait for () where (U,): AssocConst {} - | ^^^^^^^^^ +LL | impl Trait for () where (U,): AssocConst {} + | ^^^^^ | = note: see issue #92827 for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable @@ -11,7 +11,7 @@ LL | impl Trait for () where (U,): AssocConst {} error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates --> $DIR/unconstrained_impl_param.rs:15:6 | -LL | impl Trait for () where (U,): AssocConst {} +LL | impl Trait for () where (U,): AssocConst {} | ^ unconstrained type parameter error[E0282]: type annotations needed diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs new file mode 100644 index 000000000000..459282776266 --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -0,0 +1,70 @@ +#![feature(associated_const_equality, generic_const_items, min_generic_const_args)] +#![expect(incomplete_features)] + +struct Foo; + +type Adt1 = Foo; +type Adt2 = Foo<{ N }>; +type Adt3 = Foo; +//~^ ERROR: generic parameters may not be used in const operations +type Adt4 = Foo<{ 1 + 1 }>; +//~^ ERROR: complex const arguments must be placed inside of a `const` block +type Adt5 = Foo; + +type Arr = [(); N]; +type Arr2 = [(); { N }]; +type Arr3 = [(); const { N }]; +//~^ ERROR: generic parameters may not be used in const operations +type Arr4 = [(); 1 + 1]; +//~^ ERROR: complex const arguments must be placed inside of a `const` block +type Arr5 = [(); const { 1 + 1 }]; + +fn repeats() { + let _1 = [(); N]; + let _2 = [(); { N }]; + let _3 = [(); const { N }]; + //~^ ERROR: generic parameters may not be used in const operations + let _4 = [(); 1 + 1]; + //~^ ERROR: complex const arguments must be placed inside of a `const` block + let _5 = [(); const { 1 + 1 }]; +} + +#[type_const] +const ITEM1: usize = N; +#[type_const] +const ITEM2: usize = { N }; +#[type_const] +const ITEM3: usize = const { N }; +//~^ ERROR: generic parameters may not be used in const operations +#[type_const] +const ITEM4: usize = { 1 + 1 }; +//~^ ERROR: complex const arguments must be placed inside of a `const` block +#[type_const] +const ITEM5: usize = const { 1 + 1}; + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +fn ace_bounds< + const N: usize, + // We skip the T1 case because it doesn't resolve + // T1: Trait, + T2: Trait, + T3: Trait, + //~^ ERROR: generic parameters may not be used in const operations + T4: Trait, + //~^ ERROR: complex const arguments must be placed inside of a `const` block + T5: Trait, +>() {} + +struct Default1; +struct Default2; +struct Default3; +//~^ ERROR: generic parameters may not be used in const operations +struct Default4; +//~^ ERROR: complex const arguments must be placed inside of a `const` block +struct Default5; + +fn main() {} diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr new file mode 100644 index 000000000000..e4bf49c71efe --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -0,0 +1,92 @@ +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:8:41 + | +LL | type Adt3 = Foo; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments here, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:16:42 + | +LL | type Arr3 = [(); const { N }]; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments here, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:25:27 + | +LL | let _3 = [(); const { N }]; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments here, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:37:46 + | +LL | const ITEM3: usize = const { N }; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments here, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:55:31 + | +LL | T3: Trait, + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments here, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:64:58 + | +LL | struct Default3; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments here, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:10:33 + | +LL | type Adt4 = Foo<{ 1 + 1 }>; + | ^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:18:34 + | +LL | type Arr4 = [(); 1 + 1]; + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:27:19 + | +LL | let _4 = [(); 1 + 1]; + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:40:38 + | +LL | const ITEM4: usize = { 1 + 1 }; + | ^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:57:23 + | +LL | T4: Trait, + | ^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:66:50 + | +LL | struct Default4; + | ^^^^^^^^^ + +error: aborting due to 12 previous errors + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs new file mode 100644 index 000000000000..979d10331a59 --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs @@ -0,0 +1,22 @@ +//@ check-pass + +// We allow for literals to implicitly be anon consts still regardless +// of whether a const block is placed around them or not + +#![feature(min_generic_const_args, associated_const_equality)] +#![expect(incomplete_features)] + +trait Trait { + #[type_const] + const ASSOC: isize; +} + +fn ace>() {} +fn repeat_count() { + [(); 1]; +} +type ArrLen = [(); 1]; +struct Foo; +type NormalArg = (Foo<1>, Foo<-1>); + +fn main() {} diff --git a/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs b/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs new file mode 100644 index 000000000000..31f54abf31ef --- /dev/null +++ b/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs @@ -0,0 +1,25 @@ +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +struct Foo; + +trait Trait { + #[type_const] + const ASSOC: usize; +} + +type Arr = [(); {{{ N }}}]; +type Arr2 = [(); {{{ ::ASSOC }}}]; +type Ty = Foo<{{{ N }}}>; +type Ty2 = Foo<{{{ ::ASSOC }}}>; +struct Default; +struct Default2::ASSOC }}}>(T); + +fn repeat() { + let _1 = [(); {{{ N }}}]; + let _2 = [(); {{{ ::ASSOC }}}]; +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-not-constparamty.rs b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs index 27b446e6a40d..11db82187b84 100644 --- a/tests/ui/const-generics/mgca/type_const-not-constparamty.rs +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs @@ -4,9 +4,9 @@ struct S; // FIXME(mgca): need support for ctors without anon const -// (we use double-braces to trigger an anon const here) +// (we use a const-block to trigger an anon const here) #[type_const] -const FREE: S = { { S } }; +const FREE: S = const { S }; //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter trait Tr { @@ -17,9 +17,9 @@ trait Tr { impl Tr for S { // FIXME(mgca): need support for ctors without anon const - // (we use double-braces to trigger an anon const here) + // (we use a const-block to trigger an anon const here) #[type_const] - const N: S = { { S } }; + const N: S = const { S }; //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter } diff --git a/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr index 6b13917a95cd..d07bbde1e62e 100644 --- a/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr @@ -1,7 +1,7 @@ error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/type_const-not-constparamty.rs:9:13 | -LL | const FREE: S = { { S } }; +LL | const FREE: S = const { S }; | ^ | help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct @@ -13,7 +13,7 @@ LL | struct S; error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/type_const-not-constparamty.rs:22:14 | -LL | const N: S = { { S } }; +LL | const N: S = const { S }; | ^ | help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs index d38d5ab7a59f..577fee084dbd 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs @@ -2,10 +2,10 @@ #![feature(min_generic_const_args, generic_const_items)] #[type_const] -const FREE1: usize = std::mem::size_of::(); +const FREE1: usize = const { std::mem::size_of::() }; //~^ ERROR generic parameters may not be used in const operations #[type_const] -const FREE2: usize = I + 1; +const FREE2: usize = const { I + 1 }; //~^ ERROR generic parameters may not be used in const operations pub trait Tr { @@ -21,13 +21,13 @@ pub struct S; impl Tr for S { #[type_const] - const N1: usize = std::mem::size_of::(); + const N1: usize = const { std::mem::size_of::() }; //~^ ERROR generic parameters may not be used in const operations #[type_const] - const N2: usize = I + 1; + const N2: usize = const { I + 1 }; //~^ ERROR generic parameters may not be used in const operations #[type_const] - const N3: usize = 2 & X; + const N3: usize = const { 2 & X }; //~^ ERROR generic parameters may not be used in const operations } diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr index 76638f27e96c..8cef77e5b229 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -1,44 +1,44 @@ error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:5:45 + --> $DIR/type_const-on-generic-expr.rs:5:53 | -LL | const FREE1: usize = std::mem::size_of::(); - | ^ cannot perform const operation using `T` +LL | const FREE1: usize = const { std::mem::size_of::() }; + | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:8:38 + --> $DIR/type_const-on-generic-expr.rs:8:46 | -LL | const FREE2: usize = I + 1; - | ^ cannot perform const operation using `I` +LL | const FREE2: usize = const { I + 1 }; + | ^ cannot perform const operation using `I` | = help: const parameters may only be used as standalone arguments here, i.e. `I` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:24:46 + --> $DIR/type_const-on-generic-expr.rs:24:54 | -LL | const N1: usize = std::mem::size_of::(); - | ^ cannot perform const operation using `T` +LL | const N1: usize = const { std::mem::size_of::() }; + | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:27:39 + --> $DIR/type_const-on-generic-expr.rs:27:47 | -LL | const N2: usize = I + 1; - | ^ cannot perform const operation using `I` +LL | const N2: usize = const { I + 1 }; + | ^ cannot perform const operation using `I` | = help: const parameters may only be used as standalone arguments here, i.e. `I` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:30:27 + --> $DIR/type_const-on-generic-expr.rs:30:35 | -LL | const N3: usize = 2 & X; - | ^ cannot perform const operation using `X` +LL | const N3: usize = const { 2 & X }; + | ^ cannot perform const operation using `X` | = help: const parameters may only be used as standalone arguments here, i.e. `X` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions diff --git a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs new file mode 100644 index 000000000000..588fa2f913b6 --- /dev/null +++ b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs @@ -0,0 +1,42 @@ +#![feature(adt_const_params)] + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct Inner; + +struct Foo< + const PARAM_TY: Inner, + //~^ ERROR: unbraced const blocks as const args are experimental + const DEFAULT: usize = const { 1 }, + //~^ ERROR: unbraced const blocks as const args are experimental +>; + +type Array = [(); const { 1 }]; +type NormalTy = Inner; + //~^ ERROR: unbraced const blocks as const args are experimental + +fn repeat() { + [1_u8; const { 1 }]; +} + +fn body_ty() { + let _: Inner; + //~^ ERROR: unbraced const blocks as const args are experimental +} + +fn generic() { + if false { + generic::(); + //~^ ERROR: unbraced const blocks as const args are experimental + } +} + +const NON_TYPE_CONST: usize = const { 1 }; + +#[type_const] +//~^ ERROR: the `#[type_const]` attribute is an experimental feature +const TYPE_CONST: usize = const { 1 }; +//~^ ERROR: unbraced const blocks as const args are experimental + +static STATIC: usize = const { 1 }; + +fn main() {} diff --git a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr new file mode 100644 index 000000000000..30509ddf9b46 --- /dev/null +++ b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr @@ -0,0 +1,73 @@ +error[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:7:33 + | +LL | const PARAM_TY: Inner, + | ^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:9:34 + | +LL | const DEFAULT: usize = const { 1 }, + | ^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:14:29 + | +LL | type NormalTy = Inner; + | ^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:22:24 + | +LL | let _: Inner; + | ^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:28:25 + | +LL | generic::(); + | ^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:37:33 + | +LL | const TYPE_CONST: usize = const { 1 }; + | ^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: the `#[type_const]` attribute is an experimental feature + --> $DIR/unbraced_const_block_const_arg_gated.rs:35:1 + | +LL | #[type_const] + | ^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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 7 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs index 554e078ccd49..d97b3a9f0929 100644 --- a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs +++ b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs @@ -9,6 +9,6 @@ trait Trait { //~^ ERROR using function pointers as const generic parameters is forbidden } -fn take(_: impl Trait) {} +fn take(_: impl Trait) {} fn main() {} diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index 7f4926fa2b71..a72aaedb980e 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -9,12 +9,12 @@ impl Pins for NoPin {} pub trait PinA { #[type_const] - const A: &'static () = &(); + const A: &'static () = const { &() }; } pub trait Pins {} -impl Pins for T where T: PinA {} +impl Pins for T where T: PinA {} //~^ ERROR conflicting implementations of trait `Pins<_>` for type `NoPin` pub fn main() {} diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr index 34546349592f..f57fd74ad99d 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr @@ -4,8 +4,8 @@ error[E0119]: conflicting implementations of trait `Pins<_>` for type `NoPin` LL | impl Pins for NoPin {} | --------------------------- first implementation here ... -LL | impl Pins for T where T: PinA {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `NoPin` +LL | impl Pins for T where T: PinA {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `NoPin` | = note: downstream crates may implement trait `PinA<_>` for type `NoPin` diff --git a/tests/ui/generic-const-items/associated-const-equality.rs b/tests/ui/generic-const-items/associated-const-equality.rs index 6f5d4985ae53..37cf381e6824 100644 --- a/tests/ui/generic-const-items/associated-const-equality.rs +++ b/tests/ui/generic-const-items/associated-const-equality.rs @@ -17,7 +17,7 @@ impl Owner for () { #[type_const] const C: u32 = N; #[type_const] - const K: u32 = 99 + 1; + const K: u32 = const { 99 + 1 }; // FIXME(mgca): re-enable once we properly support ctors and generics on paths // #[type_const] // const Q: Maybe = Maybe::Nothing; From eb8da2f3bab8ca472b180ee060e9787da3fb1ec3 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sat, 13 Dec 2025 00:32:10 +0900 Subject: [PATCH 0682/3801] move tests --- .../anon-params-trait-method-multiple.rs} | 0 .../autoderef-arc-boxed-closure-call.rs} | 0 .../issue-27268.rs => consts/const-closure-fn-trait-object.rs} | 0 .../issue-24161.rs => extern/extern-fn-pointer-clone-copy.rs} | 0 tests/ui/{issues/issue-23036.rs => hashmap/hashmap-path-key.rs} | 0 .../issue-20454.rs => inference/inference-thread-loop-closure.rs} | 0 .../disjoint-ref-mut-method.rs} | 0 .../issue-29540.rs => limits/limit-huge-struct-derive-debug.rs} | 0 .../unused/unused-attr-repr-packed-c-order.rs} | 0 .../issue-37686.rs => match/match-usize-min-max-pattern.rs} | 0 .../i128-min-literal-parses.rs} | 0 .../const-pattern-str-match-lifetime.rs} | 0 .../static-array-shared-slice-references.rs} | 0 .../raw-string-literal-unescaped-unicode.rs} | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-34074.rs => anon-params/anon-params-trait-method-multiple.rs} (100%) rename tests/ui/{issues/issue-21306.rs => autoref-autoderef/autoderef-arc-boxed-closure-call.rs} (100%) rename tests/ui/{issues/issue-27268.rs => consts/const-closure-fn-trait-object.rs} (100%) rename tests/ui/{issues/issue-24161.rs => extern/extern-fn-pointer-clone-copy.rs} (100%) rename tests/ui/{issues/issue-23036.rs => hashmap/hashmap-path-key.rs} (100%) rename tests/ui/{issues/issue-20454.rs => inference/inference-thread-loop-closure.rs} (100%) rename tests/ui/{issues/issue-19097.rs => inherent-impls-overlap-check/disjoint-ref-mut-method.rs} (100%) rename tests/ui/{issues/issue-29540.rs => limits/limit-huge-struct-derive-debug.rs} (100%) rename tests/ui/{issues/issue-26646.rs => lint/unused/unused-attr-repr-packed-c-order.rs} (100%) rename tests/ui/{issues/issue-37686.rs => match/match-usize-min-max-pattern.rs} (100%) rename tests/ui/{issues/issue-38987.rs => numbers-arithmetic/i128-min-literal-parses.rs} (100%) rename tests/ui/{issues/issue-18352.rs => pattern/const-pattern-str-match-lifetime.rs} (100%) rename tests/ui/{issues/issue-21891.rs => static/static-array-shared-slice-references.rs} (100%) rename tests/ui/{issues/issue-50471.rs => str/raw-string-literal-unescaped-unicode.rs} (100%) diff --git a/tests/ui/issues/issue-34074.rs b/tests/ui/anon-params/anon-params-trait-method-multiple.rs similarity index 100% rename from tests/ui/issues/issue-34074.rs rename to tests/ui/anon-params/anon-params-trait-method-multiple.rs diff --git a/tests/ui/issues/issue-21306.rs b/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs similarity index 100% rename from tests/ui/issues/issue-21306.rs rename to tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs diff --git a/tests/ui/issues/issue-27268.rs b/tests/ui/consts/const-closure-fn-trait-object.rs similarity index 100% rename from tests/ui/issues/issue-27268.rs rename to tests/ui/consts/const-closure-fn-trait-object.rs diff --git a/tests/ui/issues/issue-24161.rs b/tests/ui/extern/extern-fn-pointer-clone-copy.rs similarity index 100% rename from tests/ui/issues/issue-24161.rs rename to tests/ui/extern/extern-fn-pointer-clone-copy.rs diff --git a/tests/ui/issues/issue-23036.rs b/tests/ui/hashmap/hashmap-path-key.rs similarity index 100% rename from tests/ui/issues/issue-23036.rs rename to tests/ui/hashmap/hashmap-path-key.rs diff --git a/tests/ui/issues/issue-20454.rs b/tests/ui/inference/inference-thread-loop-closure.rs similarity index 100% rename from tests/ui/issues/issue-20454.rs rename to tests/ui/inference/inference-thread-loop-closure.rs diff --git a/tests/ui/issues/issue-19097.rs b/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs similarity index 100% rename from tests/ui/issues/issue-19097.rs rename to tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs diff --git a/tests/ui/issues/issue-29540.rs b/tests/ui/limits/limit-huge-struct-derive-debug.rs similarity index 100% rename from tests/ui/issues/issue-29540.rs rename to tests/ui/limits/limit-huge-struct-derive-debug.rs diff --git a/tests/ui/issues/issue-26646.rs b/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs similarity index 100% rename from tests/ui/issues/issue-26646.rs rename to tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs diff --git a/tests/ui/issues/issue-37686.rs b/tests/ui/match/match-usize-min-max-pattern.rs similarity index 100% rename from tests/ui/issues/issue-37686.rs rename to tests/ui/match/match-usize-min-max-pattern.rs diff --git a/tests/ui/issues/issue-38987.rs b/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs similarity index 100% rename from tests/ui/issues/issue-38987.rs rename to tests/ui/numbers-arithmetic/i128-min-literal-parses.rs diff --git a/tests/ui/issues/issue-18352.rs b/tests/ui/pattern/const-pattern-str-match-lifetime.rs similarity index 100% rename from tests/ui/issues/issue-18352.rs rename to tests/ui/pattern/const-pattern-str-match-lifetime.rs diff --git a/tests/ui/issues/issue-21891.rs b/tests/ui/static/static-array-shared-slice-references.rs similarity index 100% rename from tests/ui/issues/issue-21891.rs rename to tests/ui/static/static-array-shared-slice-references.rs diff --git a/tests/ui/issues/issue-50471.rs b/tests/ui/str/raw-string-literal-unescaped-unicode.rs similarity index 100% rename from tests/ui/issues/issue-50471.rs rename to tests/ui/str/raw-string-literal-unescaped-unicode.rs From 1f406db0767bffaad1def6ec5fdfb2f4ab874103 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sat, 13 Dec 2025 00:45:22 +0900 Subject: [PATCH 0683/3801] cleaned up some tests --- .../ui/anon-params/anon-params-trait-method-multiple.rs | 4 ++-- .../autoderef-arc-boxed-closure-call.rs | 3 ++- tests/ui/consts/const-closure-fn-trait-object.rs | 3 ++- tests/ui/extern/extern-fn-pointer-clone-copy.rs | 5 +++-- tests/ui/hashmap/hashmap-path-key.rs | 1 + tests/ui/inference/inference-thread-loop-closure.rs | 7 +++++-- .../disjoint-ref-mut-method.rs | 2 +- tests/ui/limits/limit-huge-struct-derive-debug.rs | 1 + tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs | 3 ++- tests/ui/match/match-usize-min-max-pattern.rs | 1 + tests/ui/numbers-arithmetic/i128-min-literal-parses.rs | 1 + tests/ui/pattern/const-pattern-str-match-lifetime.rs | 3 ++- tests/ui/static/static-array-shared-slice-references.rs | 9 ++++----- tests/ui/str/raw-string-literal-unescaped-unicode.rs | 3 ++- 14 files changed, 29 insertions(+), 17 deletions(-) diff --git a/tests/ui/anon-params/anon-params-trait-method-multiple.rs b/tests/ui/anon-params/anon-params-trait-method-multiple.rs index d642c74d412a..ba06aa5115ba 100644 --- a/tests/ui/anon-params/anon-params-trait-method-multiple.rs +++ b/tests/ui/anon-params/anon-params-trait-method-multiple.rs @@ -1,3 +1,4 @@ +//! regression test for //@ edition: 2015 //@ check-pass // Make sure several unnamed function parameters don't conflict with each other @@ -7,5 +8,4 @@ trait Tr { fn f(u8, u8) {} } -fn main() { -} +fn main() {} diff --git a/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs b/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs index bf42e70a5bc0..fb7a8ee103e1 100644 --- a/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs +++ b/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs @@ -1,9 +1,10 @@ +//! regression test for //@ run-pass use std::sync::Arc; fn main() { let x = 5; - let command = Arc::new(Box::new(|| { x*2 })); + let command = Arc::new(Box::new(|| x * 2)); assert_eq!(command(), 10); } diff --git a/tests/ui/consts/const-closure-fn-trait-object.rs b/tests/ui/consts/const-closure-fn-trait-object.rs index e8704d215e88..e47a118dd3f4 100644 --- a/tests/ui/consts/const-closure-fn-trait-object.rs +++ b/tests/ui/consts/const-closure-fn-trait-object.rs @@ -1,4 +1,5 @@ +//! regression test for //@ run-pass fn main() { - const _C: &'static dyn Fn() = &||{}; + const _C: &'static dyn Fn() = &|| {}; } diff --git a/tests/ui/extern/extern-fn-pointer-clone-copy.rs b/tests/ui/extern/extern-fn-pointer-clone-copy.rs index 974add438616..a67e0d1d703a 100644 --- a/tests/ui/extern/extern-fn-pointer-clone-copy.rs +++ b/tests/ui/extern/extern-fn-pointer-clone-copy.rs @@ -1,11 +1,12 @@ +//! regression test for //@ check-pass #![allow(dead_code)] -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] struct Functions { a: fn(u32) -> u32, b: extern "C" fn(u32) -> u32, c: unsafe fn(u32) -> u32, - d: unsafe extern "C" fn(u32) -> u32 + d: unsafe extern "C" fn(u32) -> u32, } pub fn main() {} diff --git a/tests/ui/hashmap/hashmap-path-key.rs b/tests/ui/hashmap/hashmap-path-key.rs index 5186fccd042b..0551ba7ea8ee 100644 --- a/tests/ui/hashmap/hashmap-path-key.rs +++ b/tests/ui/hashmap/hashmap-path-key.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass use std::collections::HashMap; diff --git a/tests/ui/inference/inference-thread-loop-closure.rs b/tests/ui/inference/inference-thread-loop-closure.rs index e56f2ffa371a..78b1b145367e 100644 --- a/tests/ui/inference/inference-thread-loop-closure.rs +++ b/tests/ui/inference/inference-thread-loop-closure.rs @@ -1,13 +1,16 @@ +//! regression test for //@ check-pass #![allow(unused_must_use)] use std::thread; fn _foo() { - thread::spawn(move || { // no need for -> () + thread::spawn(move || { + // no need for -> () loop { println!("hello"); } - }).join(); + }) + .join(); } fn main() {} diff --git a/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs b/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs index a329ba6f073e..d4594b2e2c95 100644 --- a/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs +++ b/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs @@ -1,6 +1,6 @@ +//! regression test for //@ check-pass #![allow(dead_code)] -// regression test for #19097 struct Foo(T); diff --git a/tests/ui/limits/limit-huge-struct-derive-debug.rs b/tests/ui/limits/limit-huge-struct-derive-debug.rs index 6bfeae8559dc..eb793aadd8c6 100644 --- a/tests/ui/limits/limit-huge-struct-derive-debug.rs +++ b/tests/ui/limits/limit-huge-struct-derive-debug.rs @@ -1,3 +1,4 @@ +//! regression test for //@ build-pass #[derive(Debug)] pub struct Config { diff --git a/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs b/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs index b1789b1a91fc..a9da3e4175bd 100644 --- a/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs +++ b/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs @@ -1,3 +1,4 @@ +//! regression test for //@ check-pass #![deny(unused_attributes)] @@ -9,4 +10,4 @@ pub struct Foo; #[repr(C)] pub struct Bar; -fn main() { } +fn main() {} diff --git a/tests/ui/match/match-usize-min-max-pattern.rs b/tests/ui/match/match-usize-min-max-pattern.rs index 5a72f2fc74c2..6a801406895d 100644 --- a/tests/ui/match/match-usize-min-max-pattern.rs +++ b/tests/ui/match/match-usize-min-max-pattern.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass fn main() { match (0, 0) { diff --git a/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs b/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs index 713fd5027918..623a8a92ae62 100644 --- a/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs +++ b/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass fn main() { let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128; diff --git a/tests/ui/pattern/const-pattern-str-match-lifetime.rs b/tests/ui/pattern/const-pattern-str-match-lifetime.rs index 8b6aa82ea8c0..8814d55c63b6 100644 --- a/tests/ui/pattern/const-pattern-str-match-lifetime.rs +++ b/tests/ui/pattern/const-pattern-str-match-lifetime.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass const X: &'static str = "12345"; @@ -5,7 +6,7 @@ const X: &'static str = "12345"; fn test(s: String) -> bool { match &*s { X => true, - _ => false + _ => false, } } diff --git a/tests/ui/static/static-array-shared-slice-references.rs b/tests/ui/static/static-array-shared-slice-references.rs index 0da6071cdac4..a2ef169e2a29 100644 --- a/tests/ui/static/static-array-shared-slice-references.rs +++ b/tests/ui/static/static-array-shared-slice-references.rs @@ -1,11 +1,10 @@ +//! regression test for //@ build-pass #![allow(dead_code)] -#![allow(non_upper_case_globals)] +static FOO: [usize; 3] = [1, 2, 3]; -static foo: [usize; 3] = [1, 2, 3]; - -static slice_1: &'static [usize] = &foo; -static slice_2: &'static [usize] = &foo; +static SLICE_1: &'static [usize] = &FOO; +static SLICE_2: &'static [usize] = &FOO; fn main() {} diff --git a/tests/ui/str/raw-string-literal-unescaped-unicode.rs b/tests/ui/str/raw-string-literal-unescaped-unicode.rs index 1d8bad20377c..c0dc0743a28f 100644 --- a/tests/ui/str/raw-string-literal-unescaped-unicode.rs +++ b/tests/ui/str/raw-string-literal-unescaped-unicode.rs @@ -1,7 +1,8 @@ +//! regression test for //@ check-pass fn main() { - assert!({false}); + assert!({ false }); assert!(r"\u{41}" == "A"); From bf9221458acbc9358c5043208838f18d5f094d92 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sat, 13 Dec 2025 01:04:59 +0900 Subject: [PATCH 0684/3801] Move inherent-impls-overlap-check to duplicate's subdirectory --- tests/ui/README.md | 6 ------ .../inherent-impls-overlap-check/auxiliary/repeat.rs | 0 .../inherent-impls-overlap-check/disjoint-ref-mut-method.rs | 0 .../inherent-impls-overlap-check/no-overlap.rs | 0 .../{ => duplicate}/inherent-impls-overlap-check/overlap.rs | 0 .../inherent-impls-overlap-check/overlap.stderr | 0 6 files changed, 6 deletions(-) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/auxiliary/repeat.rs (100%) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/disjoint-ref-mut-method.rs (100%) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/no-overlap.rs (100%) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/overlap.rs (100%) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/overlap.stderr (100%) diff --git a/tests/ui/README.md b/tests/ui/README.md index 25e870fd8f18..fd77c340b6a9 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -697,12 +697,6 @@ Tests on type inference. Tests for diagnostics on infinitely recursive types without indirection. -## `tests/ui/inherent-impls-overlap-check/` - -Checks that repeating the same function names across separate `impl` blocks triggers an informative error, but not if the `impl` are for different types, such as `Bar` and `Bar`. - -NOTE: This should maybe be a subdirectory within another related to duplicate definitions, such as `tests/ui/duplicate/`. - ## `tests/ui/inline-const/` These tests revolve around the inline `const` block that forces the compiler to const-eval its content. diff --git a/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs b/tests/ui/duplicate/inherent-impls-overlap-check/auxiliary/repeat.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/auxiliary/repeat.rs diff --git a/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs b/tests/ui/duplicate/inherent-impls-overlap-check/disjoint-ref-mut-method.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/disjoint-ref-mut-method.rs diff --git a/tests/ui/inherent-impls-overlap-check/no-overlap.rs b/tests/ui/duplicate/inherent-impls-overlap-check/no-overlap.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/no-overlap.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/no-overlap.rs diff --git a/tests/ui/inherent-impls-overlap-check/overlap.rs b/tests/ui/duplicate/inherent-impls-overlap-check/overlap.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/overlap.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/overlap.rs diff --git a/tests/ui/inherent-impls-overlap-check/overlap.stderr b/tests/ui/duplicate/inherent-impls-overlap-check/overlap.stderr similarity index 100% rename from tests/ui/inherent-impls-overlap-check/overlap.stderr rename to tests/ui/duplicate/inherent-impls-overlap-check/overlap.stderr From 29f688a05ff4306f0a0b322a07b702fe933604f3 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 11 Dec 2025 15:49:36 -0800 Subject: [PATCH 0685/3801] Update to mdbook 0.5 This updates to mdbook 0.5.2 from mdbook 0.4.52. A primary aspect of this change is that it splits the `mdbook` crate into multiple crates, and various API changes and cleanup. There's full release notes and a migration guide at https://github.com/rust-lang/mdBook/blob/master/CHANGELOG.md#mdbook-050. This also includes submodule updates: ## book 2 commits in 8c0eacd5c4acbb650497454f3a58c9e8083202a4..39aeceaa3aeab845bc4517e7a44e48727d3b9dbe 2025-11-18 10:36:41 -0500 to 2025-12-12 11:02:27 -0500 - Synchronize TrplNote name - Update to mdbook 0.5 ## edition-guide 1 commits in 9cf5443d632673c4d41edad5e8ed8be86eeb3b8f..c3c0f0b3da26610138b7ba7663f60cd2c68cf184 2025-11-15 21:51:11 +0000 to 2025-11-28 18:54:18 +0000 - Update to mdbook 0.5 (rust-lang/edition-guide#381) ## nomicon 2 commits in 0fe83ab28985b99aba36a1f0dbde3e08286fefda..9fe8fa599ad228dda74f240cc32b54bc5c1aa3e6 2025-11-15 00:03:14 +0000 to 2025-12-03 11:54:04 +0000 - Remove references to outdated unsafe code guidelines (rust-lang/nomicon#512) - Update to mdbook 0.5 (rust-lang/nomicon#511) ## reference 5 commits in b14b4e40f53ca468beaf2f5d0dfb4f4c4ba6bc7b..50c5de90487b68d429a30cc9466dc8f5b410128f 2025-12-02 21:17:44 +0000 to 2025-12-09 22:19:05 +0000 - UB: update the extra clause for provenance UB during const evaluation (rust-lang/reference#2091) - Remove `[no-mentions]` handler in our triagebot config (rust-lang/reference#2102) - Clarify that omitting `nostack` is a promise from the compiler to the programmer (rust-lang/reference#1999) - Specify that range patterns must be nonempty. (rust-lang/reference#2093) - Update to mdbook 0.5 (rust-lang/reference#2096) ## rust-by-example 1 commits in 111cfae2f9c3a43f7b0ff8fa68c51cc8f930637c..7d21279e40e8f0e91c2a22c5148dd2d745aef8b6 2025-11-27 17:16:42 -0300 to 2025-12-01 15:02:09 -0300 - Update to mdbook 0.5 (rust-lang/rust-by-example#1977) --- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc/book.toml | 4 - src/doc/rustc/theme/pagetoc.css | 84 -- src/doc/rustc/theme/pagetoc.js | 104 -- .../src/read-documentation/in-doc-settings.md | 2 +- src/doc/style-guide/book.toml | 4 +- src/doc/unstable-book/book.toml | 1 - src/tools/error_index_generator/Cargo.toml | 3 +- src/tools/error_index_generator/main.rs | 8 +- src/tools/rustbook/Cargo.lock | 911 ++++++------------ src/tools/rustbook/Cargo.toml | 15 +- src/tools/rustbook/src/main.rs | 116 ++- src/tools/tidy/src/deps.rs | 12 +- 17 files changed, 412 insertions(+), 862 deletions(-) delete mode 100644 src/doc/rustc/theme/pagetoc.css delete mode 100644 src/doc/rustc/theme/pagetoc.js diff --git a/src/doc/book b/src/doc/book index 8c0eacd5c4ac..39aeceaa3aea 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 8c0eacd5c4acbb650497454f3a58c9e8083202a4 +Subproject commit 39aeceaa3aeab845bc4517e7a44e48727d3b9dbe diff --git a/src/doc/edition-guide b/src/doc/edition-guide index 9cf5443d6326..c3c0f0b3da26 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit 9cf5443d632673c4d41edad5e8ed8be86eeb3b8f +Subproject commit c3c0f0b3da26610138b7ba7663f60cd2c68cf184 diff --git a/src/doc/nomicon b/src/doc/nomicon index 0fe83ab28985..9fe8fa599ad2 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 0fe83ab28985b99aba36a1f0dbde3e08286fefda +Subproject commit 9fe8fa599ad228dda74f240cc32b54bc5c1aa3e6 diff --git a/src/doc/reference b/src/doc/reference index b14b4e40f53c..50c5de90487b 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit b14b4e40f53ca468beaf2f5d0dfb4f4c4ba6bc7b +Subproject commit 50c5de90487b68d429a30cc9466dc8f5b410128f diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 111cfae2f9c3..7d21279e40e8 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 111cfae2f9c3a43f7b0ff8fa68c51cc8f930637c +Subproject commit 7d21279e40e8f0e91c2a22c5148dd2d745aef8b6 diff --git a/src/doc/rustc/book.toml b/src/doc/rustc/book.toml index 34c57a63c97b..9a7c28525f0e 100644 --- a/src/doc/rustc/book.toml +++ b/src/doc/rustc/book.toml @@ -1,13 +1,9 @@ [book] -multilingual = false -src = "src" title = "The rustc book" [output.html] git-repository-url = "https://github.com/rust-lang/rust/tree/HEAD/src/doc/rustc" edit-url-template = "https://github.com/rust-lang/rust/edit/HEAD/src/doc/rustc/{path}" -additional-css = ["theme/pagetoc.css"] -additional-js = ["theme/pagetoc.js"] [output.html.search] use-boolean-and = true diff --git a/src/doc/rustc/theme/pagetoc.css b/src/doc/rustc/theme/pagetoc.css deleted file mode 100644 index fa709194f375..000000000000 --- a/src/doc/rustc/theme/pagetoc.css +++ /dev/null @@ -1,84 +0,0 @@ -/* Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL) */ - -:root { - --toc-width: 270px; - --center-content-toc-shift: calc(-1 * var(--toc-width) / 2); -} - -.nav-chapters { - /* adjust width of buttons that bring to the previous or the next page */ - min-width: 50px; -} - -@media only screen { - @media (max-width: 1179px) { - .sidebar-hidden #sidetoc { - display: none; - } - } - - @media (max-width: 1439px) { - .sidebar-visible #sidetoc { - display: none; - } - } - - @media (1180px <= width <= 1439px) { - .sidebar-hidden main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - @media (1440px <= width <= 1700px) { - .sidebar-visible main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - #sidetoc { - margin-left: calc(100% + 20px); - } - #pagetoc { - position: fixed; - /* adjust TOC width */ - width: var(--toc-width); - height: calc(100vh - var(--menu-bar-height) - 0.67em * 4); - overflow: auto; - } - #pagetoc a { - border-left: 1px solid var(--sidebar-bg); - color: var(--fg); - display: block; - padding-bottom: 5px; - padding-top: 5px; - padding-left: 10px; - text-align: left; - text-decoration: none; - } - #pagetoc a:hover, - #pagetoc a.active { - background: var(--sidebar-bg); - color: var(--sidebar-active) !important; - } - #pagetoc .active { - background: var(--sidebar-bg); - color: var(--sidebar-active); - } - #pagetoc .pagetoc-H2 { - padding-left: 20px; - } - #pagetoc .pagetoc-H3 { - padding-left: 40px; - } - #pagetoc .pagetoc-H4 { - padding-left: 60px; - } -} - -@media print { - #sidetoc { - display: none; - } -} diff --git a/src/doc/rustc/theme/pagetoc.js b/src/doc/rustc/theme/pagetoc.js deleted file mode 100644 index 927a5b10749b..000000000000 --- a/src/doc/rustc/theme/pagetoc.js +++ /dev/null @@ -1,104 +0,0 @@ -// Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL) - -let activeHref = location.href; -function updatePageToc(elem = undefined) { - let selectedPageTocElem = elem; - const pagetoc = document.getElementById("pagetoc"); - - function getRect(element) { - return element.getBoundingClientRect(); - } - - function overflowTop(container, element) { - return getRect(container).top - getRect(element).top; - } - - function overflowBottom(container, element) { - return getRect(container).bottom - getRect(element).bottom; - } - - // We've not selected a heading to highlight, and the URL needs updating - // so we need to find a heading based on the URL - if (selectedPageTocElem === undefined && location.href !== activeHref) { - activeHref = location.href; - for (const pageTocElement of pagetoc.children) { - if (pageTocElement.href === activeHref) { - selectedPageTocElem = pageTocElement; - } - } - } - - // We still don't have a selected heading, let's try and find the most - // suitable heading based on the scroll position - if (selectedPageTocElem === undefined) { - const margin = window.innerHeight / 3; - - const headers = document.getElementsByClassName("header"); - for (let i = 0; i < headers.length; i++) { - const header = headers[i]; - if (selectedPageTocElem === undefined && getRect(header).top >= 0) { - if (getRect(header).top < margin) { - selectedPageTocElem = header; - } else { - selectedPageTocElem = headers[Math.max(0, i - 1)]; - } - } - // a very long last section's heading is over the screen - if (selectedPageTocElem === undefined && i === headers.length - 1) { - selectedPageTocElem = header; - } - } - } - - // Remove the active flag from all pagetoc elements - for (const pageTocElement of pagetoc.children) { - pageTocElement.classList.remove("active"); - } - - // If we have a selected heading, set it to active and scroll to it - if (selectedPageTocElem !== undefined) { - for (const pageTocElement of pagetoc.children) { - if (selectedPageTocElem.href.localeCompare(pageTocElement.href) === 0) { - pageTocElement.classList.add("active"); - if (overflowTop(pagetoc, pageTocElement) > 0) { - pagetoc.scrollTop = pageTocElement.offsetTop; - } - if (overflowBottom(pagetoc, pageTocElement) < 0) { - pagetoc.scrollTop -= overflowBottom(pagetoc, pageTocElement); - } - } - } - } -} - -if (document.getElementById("sidetoc") === null && - document.getElementsByClassName("header").length > 0) { - // The sidetoc element doesn't exist yet, let's create it - - // Create the empty sidetoc and pagetoc elements - const sidetoc = document.createElement("div"); - const pagetoc = document.createElement("div"); - sidetoc.id = "sidetoc"; - pagetoc.id = "pagetoc"; - sidetoc.appendChild(pagetoc); - - // And append them to the current DOM - const main = document.querySelector('main'); - main.insertBefore(sidetoc, main.firstChild); - - // Populate sidebar on load - window.addEventListener("load", () => { - for (const header of document.getElementsByClassName("header")) { - const link = document.createElement("a"); - link.innerHTML = header.innerHTML; - link.href = header.hash; - link.classList.add("pagetoc-" + header.parentElement.tagName); - document.getElementById("pagetoc").appendChild(link); - link.onclick = () => updatePageToc(link); - } - updatePageToc(); - }); - - // Update page table of contents selected heading on scroll - window.addEventListener("scroll", () => updatePageToc()); -} diff --git a/src/doc/rustdoc/src/read-documentation/in-doc-settings.md b/src/doc/rustdoc/src/read-documentation/in-doc-settings.md index 12928a4f3692..1bcf74e39cd1 100644 --- a/src/doc/rustdoc/src/read-documentation/in-doc-settings.md +++ b/src/doc/rustdoc/src/read-documentation/in-doc-settings.md @@ -4,7 +4,7 @@ Rustdoc's HTML output includes a settings menu, and this chapter describes what each setting in this menu does. It can be accessed by clicking on the gear button -() in the upper right. +() in the upper right. ## Changing displayed theme diff --git a/src/doc/style-guide/book.toml b/src/doc/style-guide/book.toml index 056aec8cdd4f..1ef0af5fcdbf 100644 --- a/src/doc/style-guide/book.toml +++ b/src/doc/style-guide/book.toml @@ -1,8 +1,6 @@ [book] title = "The Rust Style Guide" -author = "The Rust Style Team" -multilingual = false -src = "src" +authors = ["The Rust Style Team"] [output.html] git-repository-url = "https://github.com/rust-lang/rust/tree/HEAD/src/doc/style-guide/" diff --git a/src/doc/unstable-book/book.toml b/src/doc/unstable-book/book.toml index 5dbe90cd10ec..c357949f6c2e 100644 --- a/src/doc/unstable-book/book.toml +++ b/src/doc/unstable-book/book.toml @@ -1,6 +1,5 @@ [book] title = "The Rust Unstable Book" -author = "The Rust Community" [output.html] git-repository-url = "https://github.com/rust-lang/rust/tree/HEAD/src/doc/unstable-book" diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml index 54fe7f6eb5a9..9d0f3b061d47 100644 --- a/src/tools/error_index_generator/Cargo.toml +++ b/src/tools/error_index_generator/Cargo.toml @@ -5,7 +5,8 @@ edition = "2021" workspace = "../rustbook" [dependencies] -mdbook = { version = "0.4", default-features = false, features = ["search"] } +mdbook-driver = { version = "0.5.1", features = ["search"] } +mdbook-summary = "0.5.1" [[bin]] name = "error_index_generator" diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 58224aed1487..97ac47918c09 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -12,8 +12,10 @@ use std::io::Write; use std::path::{Path, PathBuf}; use std::str::FromStr; -use mdbook::book::{BookItem, Chapter, parse_summary}; -use mdbook::{Config, MDBook}; +use mdbook_driver::MDBook; +use mdbook_driver::book::{BookItem, Chapter}; +use mdbook_driver::config::Config; +use mdbook_summary::parse_summary; use rustc_errors::codes::DIAGNOSTICS; enum OutputFormat { @@ -121,7 +123,7 @@ This page lists all the error codes emitted by the Rust compiler. source_path: None, parent_names: Vec::new(), }; - book.book.sections.push(BookItem::Chapter(chapter)); + book.book.items.push(BookItem::Chapter(chapter)); book.build()?; // The error-index used to be generated manually (without mdbook), and the diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index d5aa7a671636..e7b04260e4a9 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -17,19 +17,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ammonia" -version = "4.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17e913097e1a2124b46746c980134e8c954bc17a6a59bb3fde96f088d126dde6" -dependencies = [ - "cssparser", - "html5ever", - "maplit", - "tendril", - "url", -] - [[package]] name = "android_system_properties" version = "0.1.5" @@ -110,6 +97,21 @@ dependencies = [ "serde", ] +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitflags" version = "2.10.0" @@ -125,17 +127,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bstr" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" -dependencies = [ - "memchr", - "regex-automata", - "serde", -] - [[package]] name = "bumpalo" version = "3.19.0" @@ -191,16 +182,6 @@ dependencies = [ "anstyle", "clap_lex", "strsim", - "terminal_size", -] - -[[package]] -name = "clap_complete" -version = "4.5.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e602857739c5a4291dfa33b5a298aeac9006185229a700e5810a3ef7272d971" -dependencies = [ - "clap", ] [[package]] @@ -261,29 +242,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "cssparser" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e901edd733a1472f944a45116df3f846f54d37e67e68640ac8bb69689aca2aa" -dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa", - "phf 0.11.3", - "smallvec", -] - -[[package]] -name = "cssparser-macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "darling" version = "0.20.11" @@ -372,17 +330,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "doc-comment" version = "0.3.4" @@ -390,19 +337,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9" [[package]] -name = "dtoa" -version = "1.0.10" +name = "ego-tree" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" - -[[package]] -name = "dtoa-short" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" -dependencies = [ - "dtoa", -] +checksum = "b2972feb8dffe7bc8c5463b1dacda1b0dfbed3710e50f977d965429692d74cd8" [[package]] name = "elasticlunr-rs" @@ -416,29 +354,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "env_filter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "jiff", - "log", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -459,7 +374,19 @@ dependencies = [ name = "error_index_generator" version = "0.0.0" dependencies = [ - "mdbook", + "mdbook-driver", + "mdbook-summary", +] + +[[package]] +name = "fancy-regex" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f" +dependencies = [ + "bit-set", + "regex-automata", + "regex-syntax", ] [[package]] @@ -491,13 +418,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "form_urlencoded" -version = "1.2.2" +name = "font-awesome-as-a-crate" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] +checksum = "932dcfbd51320af5f27f1ba02d2e567dec332cac7d2c221ba45d8e767264c4dc" [[package]] name = "futf" @@ -558,9 +482,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "heck" @@ -576,13 +500,12 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "html5ever" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d958c2f74b664487a2035fe1dadb032c48718a03b63f3ab0b8537db8549ed4" +checksum = "6452c4751a24e1b99c3260d505eaeee76a050573e61f30ac2c924ddc7236f01e" dependencies = [ "log", "markup5ever", - "match_token", ] [[package]] @@ -624,119 +547,17 @@ dependencies = [ "cc", ] -[[package]] -name = "icu_collections" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - -[[package]] -name = "icu_properties" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" - -[[package]] -name = "icu_provider" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - [[package]] name = "indexmap" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown", @@ -754,30 +575,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "jiff" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" -dependencies = [ - "jiff-static", - "log", - "portable-atomic", - "portable-atomic-util", - "serde_core", -] - -[[package]] -name = "jiff-static" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "js-sys" version = "0.3.82" @@ -815,12 +612,6 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" -[[package]] -name = "litemap" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" - [[package]] name = "lock_api" version = "0.4.14" @@ -842,17 +633,11 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "markup5ever" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fe69c934650f8f19652b3946075f0fc41ad8757dbb68f1ca14e7900ecc1c3" +checksum = "6c3294c4d74d0742910f8c7b466f44dda9eb2d5742c1e430138df290a1e8451c" dependencies = [ "log", "tendril", @@ -860,58 +645,91 @@ dependencies = [ ] [[package]] -name = "match_token" -version = "0.35.0" +name = "matchers" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac84fd3f360fcc43dc5f5d186f02a94192761a080e8bc58621ad4d12296a58cf" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "proc-macro2", - "quote", - "syn", + "regex-automata", ] [[package]] -name = "mdbook" -version = "0.4.52" +name = "mdbook-core" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c284d2855916af7c5919cf9ad897cfc77d3c2db6f55429c7cfb769182030ec" +checksum = "39a3873d4afac65583f1acb56ff058df989d5b4a2464bb02c785549727d307ee" dependencies = [ - "ammonia", "anyhow", - "chrono", - "clap", - "clap_complete", + "regex", + "serde", + "serde_json", + "toml 0.9.8", + "tracing", +] + +[[package]] +name = "mdbook-driver" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a229930b29a9908560883e1f386eae25d8a971d259a80f49916a50627f04a42d" +dependencies = [ + "anyhow", + "indexmap", + "mdbook-core", + "mdbook-html", + "mdbook-markdown", + "mdbook-preprocessor", + "mdbook-renderer", + "mdbook-summary", + "regex", + "serde", + "serde_json", + "shlex", + "tempfile", + "toml 0.9.8", + "topological-sort", + "tracing", +] + +[[package]] +name = "mdbook-html" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dee80c03c65e3212fb528b8c9be5568a6a85cf795d03cf9fd6ba39ad52069ca" +dependencies = [ + "anyhow", + "ego-tree", "elasticlunr-rs", - "env_logger", + "font-awesome-as-a-crate", "handlebars", "hex", - "log", - "memchr", - "opener", - "pulldown-cmark 0.10.3", + "html5ever", + "indexmap", + "mdbook-core", + "mdbook-markdown", + "mdbook-renderer", + "pulldown-cmark 0.13.0", "regex", "serde", "serde_json", "sha2", - "shlex", - "tempfile", - "toml 0.5.11", - "topological-sort", + "tracing", ] [[package]] name = "mdbook-i18n-helpers" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5644bf29b95683ea60979e30188221c374965c3a1dc0ad2d5c69e867dc0c09dc" +checksum = "82a64b6c27dc99a20968cc85a89dcfe0d36f82e2c9bc3b4342a2ffc55158822f" dependencies = [ "anyhow", "chrono", "dateparser", - "mdbook", + "mdbook-preprocessor", + "mdbook-renderer", "polib", - "pulldown-cmark 0.12.2", - "pulldown-cmark-to-cmark 20.0.1", + "pulldown-cmark 0.13.0", + "pulldown-cmark-to-cmark 21.1.0", "regex", "semver", "serde_json", @@ -919,15 +737,50 @@ dependencies = [ "textwrap", ] +[[package]] +name = "mdbook-markdown" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c41bf35212f5d8b83e543aa6a4887dc5709c8489c5fb9ed00f1b51ce1a2cc6" +dependencies = [ + "pulldown-cmark 0.13.0", + "regex", + "tracing", +] + +[[package]] +name = "mdbook-preprocessor" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d87bf40be0597f26f0822f939a64f02bf92c4655ba04490aadbf83601a013bb" +dependencies = [ + "anyhow", + "mdbook-core", + "serde", + "serde_json", +] + +[[package]] +name = "mdbook-renderer" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ed59f225b3ae4283c56bea633db83184627a090d892908bd66990c68e10b43" +dependencies = [ + "anyhow", + "mdbook-core", + "serde", + "serde_json", +] + [[package]] name = "mdbook-spec" version = "0.1.2" dependencies = [ "anyhow", - "mdbook", + "mdbook-markdown", + "mdbook-preprocessor", "once_cell", "pathdiff", - "pulldown-cmark 0.10.3", "railroad", "regex", "semver", @@ -936,6 +789,20 @@ dependencies = [ "walkdir", ] +[[package]] +name = "mdbook-summary" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00d85b291d67a69c92e939450390fe34d6ea418a868c8f7b42f0b300af35a7b" +dependencies = [ + "anyhow", + "mdbook-core", + "memchr", + "pulldown-cmark 0.13.0", + "serde", + "tracing", +] + [[package]] name = "mdbook-trpl" version = "0.1.0" @@ -943,9 +810,10 @@ dependencies = [ "anyhow", "clap", "html_parser", - "mdbook", + "mdbook-preprocessor", "pulldown-cmark 0.12.2", "pulldown-cmark-to-cmark 19.0.1", + "serde", "serde_json", "thiserror 1.0.69", "toml 0.8.23", @@ -974,10 +842,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] -name = "normpath" -version = "1.5.0" +name = "nu-ansi-term" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ "windows-sys 0.61.2", ] @@ -1018,39 +886,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "onig" -version = "6.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" -dependencies = [ - "bitflags", - "libc", - "once_cell", - "onig_sys", -] - -[[package]] -name = "onig_sys" -version = "69.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f86c6eef3d6df15f23bcfb6af487cbd2fed4e5581d58d5bf1f5f8b7f6727dc" -dependencies = [ - "cc", - "pkg-config", -] - -[[package]] -name = "opener" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb9024962ab91e00c89d2a14352a8d0fc1a64346bf96f1839b45c09149564e47" -dependencies = [ - "bstr", - "normpath", - "windows-sys 0.60.2", -] - [[package]] name = "parking_lot" version = "0.12.5" @@ -1080,12 +915,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - [[package]] name = "pest" version = "2.8.3" @@ -1129,23 +958,13 @@ dependencies = [ "sha2", ] -[[package]] -name = "phf" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_macros", - "phf_shared 0.11.3", -] - [[package]] name = "phf" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "phf_shared 0.13.1", + "phf_shared", "serde", ] @@ -1155,18 +974,8 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" dependencies = [ - "phf_generator 0.13.1", - "phf_shared 0.13.1", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared 0.11.3", - "rand", + "phf_generator", + "phf_shared", ] [[package]] @@ -1176,29 +985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ "fastrand", - "phf_shared 0.13.1", -] - -[[package]] -name = "phf_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", + "phf_shared", ] [[package]] @@ -1211,10 +998,10 @@ dependencies = [ ] [[package]] -name = "pkg-config" -version = "0.3.32" +name = "pin-project-lite" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "polib" @@ -1225,30 +1012,6 @@ dependencies = [ "linereader", ] -[[package]] -name = "portable-atomic" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" - -[[package]] -name = "portable-atomic-util" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "potential_utf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" -dependencies = [ - "zerovec", -] - [[package]] name = "precomputed-hash" version = "0.1.1" @@ -1264,18 +1027,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "pulldown-cmark" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" -dependencies = [ - "bitflags", - "memchr", - "pulldown-cmark-escape 0.10.1", - "unicase", -] - [[package]] name = "pulldown-cmark" version = "0.12.2" @@ -1285,15 +1036,21 @@ dependencies = [ "bitflags", "getopts", "memchr", - "pulldown-cmark-escape 0.11.0", + "pulldown-cmark-escape", "unicase", ] [[package]] -name = "pulldown-cmark-escape" -version = "0.10.1" +name = "pulldown-cmark" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" +checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" +dependencies = [ + "bitflags", + "memchr", + "pulldown-cmark-escape", + "unicase", +] [[package]] name = "pulldown-cmark-escape" @@ -1312,11 +1069,11 @@ dependencies = [ [[package]] name = "pulldown-cmark-to-cmark" -version = "20.0.1" +version = "21.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c0f333311d2d8fda65bcf76af35054e9f38e253332a0289746156a59656988b" +checksum = "8246feae3db61428fd0bb94285c690b460e4517d83152377543ca802357785f1" dependencies = [ - "pulldown-cmark 0.12.2", + "pulldown-cmark 0.13.0", ] [[package]] @@ -1343,21 +1100,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" - [[package]] name = "redox_syscall" version = "0.5.18" @@ -1401,12 +1143,11 @@ name = "rustbook" version = "0.1.0" dependencies = [ "clap", - "env_logger", - "libc", - "mdbook", + "mdbook-driver", "mdbook-i18n-helpers", "mdbook-spec", "mdbook-trpl", + "tracing-subscriber", ] [[package]] @@ -1507,6 +1248,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +dependencies = [ + "serde_core", +] + [[package]] name = "sha2" version = "0.10.9" @@ -1518,6 +1268,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1542,12 +1301,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - [[package]] name = "string_cache" version = "0.9.0" @@ -1556,7 +1309,7 @@ checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" dependencies = [ "new_debug_unreachable", "parking_lot", - "phf_shared 0.13.1", + "phf_shared", "precomputed-hash", "serde", ] @@ -1567,8 +1320,8 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" dependencies = [ - "phf_generator 0.13.1", - "phf_shared 0.13.1", + "phf_generator", + "phf_shared", "proc-macro2", "quote", ] @@ -1590,17 +1343,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "syntect" version = "5.3.0" @@ -1608,10 +1350,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "656b45c05d95a5704399aeef6bd0ddec7b2b3531b7c9e900abbf7c4d2190c925" dependencies = [ "bincode", + "fancy-regex", "flate2", "fnv", "once_cell", - "onig", "regex-syntax", "serde", "serde_derive", @@ -1643,16 +1385,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "terminal_size" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" -dependencies = [ - "rustix", - "windows-sys 0.60.2", -] - [[package]] name = "textwrap" version = "0.16.2" @@ -1700,22 +1432,12 @@ dependencies = [ ] [[package]] -name = "tinystr" -version = "0.8.2" +name = "thread_local" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", + "cfg-if", ] [[package]] @@ -1725,11 +1447,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_edit", ] +[[package]] +name = "toml" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned 1.0.3", + "toml_datetime 0.7.3", + "toml_parser", + "toml_writer", + "winnow", +] + [[package]] name = "toml_datetime" version = "0.6.11" @@ -1739,6 +1476,15 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.22.27" @@ -1747,24 +1493,100 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_write", "winnow", ] +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ + "winnow", +] + [[package]] name = "toml_write" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "toml_writer" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" + [[package]] name = "topological-sort" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" +[[package]] +name = "tracing" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + [[package]] name = "typenum" version = "1.19.0" @@ -1795,36 +1617,24 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" -[[package]] -name = "url" -version = "2.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - [[package]] name = "utf-8" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "version_check" version = "0.9.5" @@ -1897,11 +1707,11 @@ dependencies = [ [[package]] name = "web_atoms" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44b72896d90cfd22c495d0ee4960d3dd20ca64180895cb92cd5342ff7482a579" +checksum = "acd0c322f146d0f8aad130ce6c187953889359584497dac6561204c8e17bb43d" dependencies = [ - "phf 0.13.1", + "phf", "phf_codegen", "string_cache", "string_cache_codegen", @@ -2072,86 +1882,3 @@ name = "wit-bindgen" version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - -[[package]] -name = "yoke" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerotrie" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 1a5b2c29d20b..2815f09105b1 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -8,14 +8,9 @@ license = "MIT OR Apache-2.0" edition = "2021" [dependencies] -clap = "4.0.32" -env_logger = "0.11" -libc = "0.2" -mdbook-trpl = { path = "../../doc/book/packages/mdbook-trpl" } -mdbook-i18n-helpers = "0.3.3" +clap = { version = "4.0.32", features = ["cargo"] } +mdbook-driver = { version = "0.5.2", features = ["search"] } +mdbook-i18n-helpers = "0.4.0" mdbook-spec = { path = "../../doc/reference/mdbook-spec" } - -[dependencies.mdbook] -version = "0.4.52" -default-features = false -features = ["search"] +mdbook-trpl = { path = "../../doc/book/packages/mdbook-trpl" } +tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs index 4b510e308c97..541052402820 100644 --- a/src/tools/rustbook/src/main.rs +++ b/src/tools/rustbook/src/main.rs @@ -2,15 +2,27 @@ use std::env; use std::path::{Path, PathBuf}; use clap::{ArgMatches, Command, arg, crate_version}; -use mdbook::MDBook; -use mdbook::errors::Result as Result3; +use mdbook_driver::MDBook; +use mdbook_driver::errors::Result as Result3; use mdbook_i18n_helpers::preprocessors::Gettext; use mdbook_spec::Spec; use mdbook_trpl::{Figure, Listing, Note}; fn main() { let crate_version = concat!("v", crate_version!()); - env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init(); + let filter = tracing_subscriber::EnvFilter::builder() + .with_env_var("MDBOOK_LOG") + .with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into()) + .from_env_lossy(); + tracing_subscriber::fmt() + .without_time() + .with_ansi(std::io::IsTerminal::is_terminal(&std::io::stderr())) + .with_writer(std::io::stderr) + .with_env_filter(filter) + .with_target(std::env::var_os("MDBOOK_LOG").is_some()) + .init(); + + // env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); let d_arg = arg!(-d --"dest-dir" "The output directory for your book\n(Defaults to ./book when omitted)") .required(false) @@ -82,60 +94,22 @@ fn main() { }; } -// Build command implementation -pub fn build(args: &ArgMatches) -> Result3<()> { +fn build(args: &ArgMatches) -> Result3<()> { let book_dir = get_book_dir(args); - let mut book = load_book(&book_dir)?; - - if let Some(lang) = args.get_one::("lang") { - let gettext = Gettext; - book.with_preprocessor(gettext); - book.config.set("book.language", lang).unwrap(); - } - - // Set this to allow us to catch bugs in advance. - book.config.build.create_missing = false; - - if let Some(dest_dir) = args.get_one::("dest-dir") { - book.config.build.build_dir = dest_dir.into(); - } - - // NOTE: Replacing preprocessors using this technique causes error - // messages to be displayed when the original preprocessor doesn't work - // (but it otherwise succeeds). - // - // This should probably be fixed in mdbook to remove the existing - // preprocessor, or this should modify the config and use - // MDBook::load_with_config. - if book.config.get_preprocessor("trpl-note").is_some() { - book.with_preprocessor(Note); - } - - if book.config.get_preprocessor("trpl-listing").is_some() { - book.with_preprocessor(Listing); - } - - if book.config.get_preprocessor("trpl-figure").is_some() { - book.with_preprocessor(Figure); - } - - if book.config.get_preprocessor("spec").is_some() { - let rust_root = args.get_one::("rust-root").cloned(); - book.with_preprocessor(Spec::new(rust_root)?); - } - - book.build()?; - - Ok(()) + let dest_dir = args.get_one::("dest-dir"); + let lang = args.get_one::("lang"); + let rust_root = args.get_one::("rust-root"); + let book = load_book(&book_dir, dest_dir, lang, rust_root.cloned())?; + book.build() } fn test(args: &ArgMatches) -> Result3<()> { let book_dir = get_book_dir(args); + let mut book = load_book(&book_dir, None, None, None)?; let library_paths = args .try_get_one::>("library-path")? .map(|v| v.iter().map(|s| s.as_str()).collect::>()) .unwrap_or_default(); - let mut book = load_book(&book_dir)?; book.test(library_paths) } @@ -148,10 +122,52 @@ fn get_book_dir(args: &ArgMatches) -> PathBuf { } } -fn load_book(book_dir: &Path) -> Result3 { +fn load_book( + book_dir: &Path, + dest_dir: Option<&PathBuf>, + lang: Option<&String>, + rust_root: Option, +) -> Result3 { let mut book = MDBook::load(book_dir)?; book.config.set("output.html.input-404", "").unwrap(); book.config.set("output.html.hash-files", true).unwrap(); + + if let Some(lang) = lang { + let gettext = Gettext; + book.with_preprocessor(gettext); + book.config.set("book.language", lang).unwrap(); + } + + // Set this to allow us to catch bugs in advance. + book.config.build.create_missing = false; + + if let Some(dest_dir) = dest_dir { + book.config.build.build_dir = dest_dir.into(); + } + + // NOTE: Replacing preprocessors using this technique causes error + // messages to be displayed when the original preprocessor doesn't work + // (but it otherwise succeeds). + // + // This should probably be fixed in mdbook to remove the existing + // preprocessor, or this should modify the config and use + // MDBook::load_with_config. + if book.config.contains_key("preprocessor.trpl-note") { + book.with_preprocessor(Note); + } + + if book.config.contains_key("preprocessor.trpl-listing") { + book.with_preprocessor(Listing); + } + + if book.config.contains_key("preprocessor.trpl-figure") { + book.with_preprocessor(Figure); + } + + if book.config.contains_key("preprocessor.spec") { + book.with_preprocessor(Spec::new(rust_root)?); + } + Ok(book) } @@ -159,7 +175,7 @@ fn parse_library_paths(input: &str) -> Result, String> { Ok(input.split(",").map(String::from).collect()) } -fn handle_error(error: mdbook::errors::Error) -> ! { +fn handle_error(error: mdbook_driver::errors::Error) -> ! { eprintln!("Error: {}", error); for cause in error.chain().skip(1) { diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 592ba9c5c794..f374a1e01496 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -222,10 +222,14 @@ const EXCEPTIONS_RUSTC_PERF: ExceptionList = &[ const EXCEPTIONS_RUSTBOOK: ExceptionList = &[ // tidy-alphabetical-start - ("cssparser", "MPL-2.0"), - ("cssparser-macros", "MPL-2.0"), - ("dtoa-short", "MPL-2.0"), - ("mdbook", "MPL-2.0"), + ("font-awesome-as-a-crate", "CC-BY-4.0 AND MIT"), + ("mdbook-core", "MPL-2.0"), + ("mdbook-driver", "MPL-2.0"), + ("mdbook-html", "MPL-2.0"), + ("mdbook-markdown", "MPL-2.0"), + ("mdbook-preprocessor", "MPL-2.0"), + ("mdbook-renderer", "MPL-2.0"), + ("mdbook-summary", "MPL-2.0"), // tidy-alphabetical-end ]; From 0748492e2bb7d48c4c548729b0593c470bc31155 Mon Sep 17 00:00:00 2001 From: delta17920 Date: Wed, 10 Dec 2025 18:17:03 +0000 Subject: [PATCH 0686/3801] Fix: Prevent macro-expanded extern crates from shadowing extern arguments --- compiler/rustc_resolve/src/ident.rs | 63 ++++++++++--------- compiler/rustc_resolve/src/imports.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 1 + .../ice-inconsistent-resolution-149821.rs | 17 +++++ .../ice-inconsistent-resolution-149821.stderr | 13 ++++ 5 files changed, 65 insertions(+), 31 deletions(-) create mode 100644 tests/ui/resolve/ice-inconsistent-resolution-149821.rs create mode 100644 tests/ui/resolve/ice-inconsistent-resolution-149821.stderr diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index e38d4370d5d2..5587fc91216f 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -771,36 +771,39 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } else { None }; - // Skip ambiguity errors for extern flag bindings "overridden" - // by extern item bindings. - // FIXME: Remove with lang team approval. - let issue_145575_hack = Some(binding) == extern_prelude_flag_binding - && extern_prelude_item_binding.is_some() - && extern_prelude_item_binding != Some(innermost_binding); - if let Some(kind) = ambiguity_error_kind - && !issue_145575_hack - { - let misc = |f: Flags| { - if f.contains(Flags::MISC_SUGGEST_CRATE) { - AmbiguityErrorMisc::SuggestCrate - } else if f.contains(Flags::MISC_SUGGEST_SELF) { - AmbiguityErrorMisc::SuggestSelf - } else if f.contains(Flags::MISC_FROM_PRELUDE) { - AmbiguityErrorMisc::FromPrelude - } else { - AmbiguityErrorMisc::None - } - }; - self.ambiguity_errors.push(AmbiguityError { - kind, - ident: orig_ident, - b1: innermost_binding, - b2: binding, - warning: false, - misc1: misc(innermost_flags), - misc2: misc(flags), - }); - return true; + if let Some(kind) = ambiguity_error_kind { + // Skip ambiguity errors for extern flag bindings "overridden" + // by extern item bindings. + // FIXME: Remove with lang team approval. + let issue_145575_hack = Some(binding) == extern_prelude_flag_binding + && extern_prelude_item_binding.is_some() + && extern_prelude_item_binding != Some(innermost_binding); + + if issue_145575_hack { + self.issue_145575_hack_applied = true; + } else { + let misc = |f: Flags| { + if f.contains(Flags::MISC_SUGGEST_CRATE) { + AmbiguityErrorMisc::SuggestCrate + } else if f.contains(Flags::MISC_SUGGEST_SELF) { + AmbiguityErrorMisc::SuggestSelf + } else if f.contains(Flags::MISC_FROM_PRELUDE) { + AmbiguityErrorMisc::FromPrelude + } else { + AmbiguityErrorMisc::None + } + }; + self.ambiguity_errors.push(AmbiguityError { + kind, + ident: orig_ident, + b1: innermost_binding, + b2: binding, + warning: false, + misc1: misc(innermost_flags), + misc2: misc(flags), + }); + return true; + } } false diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 4ef87af56050..4e0f3db59821 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1170,7 +1170,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return; } if let Some(initial_res) = initial_res { - if res != initial_res { + if res != initial_res && !this.issue_145575_hack_applied { span_bug!(import.span, "inconsistent resolution for an import"); } } else if this.privacy_errors.is_empty() { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 8132bf577d88..7e06b8511e30 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1186,6 +1186,7 @@ pub struct Resolver<'ra, 'tcx> { privacy_errors: Vec> = Vec::new(), /// Ambiguity errors are delayed for deduplication. ambiguity_errors: Vec> = Vec::new(), + issue_145575_hack_applied: bool = false, /// `use` injections are delayed for better placement and deduplication. use_injections: Vec> = Vec::new(), /// Crate-local macro expanded `macro_export` referred to by a module-relative path. diff --git a/tests/ui/resolve/ice-inconsistent-resolution-149821.rs b/tests/ui/resolve/ice-inconsistent-resolution-149821.rs new file mode 100644 index 000000000000..19b8a2f4330c --- /dev/null +++ b/tests/ui/resolve/ice-inconsistent-resolution-149821.rs @@ -0,0 +1,17 @@ +//@ edition: 2024 + +mod m { + use crate::*; + use core; +} + +macro_rules! define_other_core { + () => { + extern crate std as core; + //~^ ERROR macro-expanded `extern crate` items cannot shadow names passed with `--extern` + }; +} + +define_other_core! {} + +fn main() {} diff --git a/tests/ui/resolve/ice-inconsistent-resolution-149821.stderr b/tests/ui/resolve/ice-inconsistent-resolution-149821.stderr new file mode 100644 index 000000000000..cd75a2f3e19b --- /dev/null +++ b/tests/ui/resolve/ice-inconsistent-resolution-149821.stderr @@ -0,0 +1,13 @@ +error: macro-expanded `extern crate` items cannot shadow names passed with `--extern` + --> $DIR/ice-inconsistent-resolution-149821.rs:10:9 + | +LL | extern crate std as core; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | define_other_core! {} + | --------------------- in this macro invocation + | + = note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + From 49db9ec01b894b09d2f592e2ce09884c5a1093f9 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 15 Jun 2025 20:40:13 +0800 Subject: [PATCH 0687/3801] Update and add more details for Providers Signed-off-by: xizheyin Co-authored-by: Boxy --- src/doc/rustc-dev-guide/src/query.md | 142 +++++++++++++++++++++------ 1 file changed, 110 insertions(+), 32 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 8377a7b2f31a..5df9de762038 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -69,22 +69,24 @@ are cheaply cloneable; insert an `Rc` if necessary). If, however, the query is *not* in the cache, then the compiler will call the corresponding **provider** function. A provider is a function -implemented in a specific module and **manually registered** into the -[`Providers`][providers_struct] struct during compiler initialization. -The macro system generates the [`Providers`][providers_struct] struct, -which acts as a function table for all query implementations, where each +implemented in a specific module and **manually registered** into either +the [`Providers`][providers_struct] struct (for local crate queries) or +the [`ExternProviders`][extern_providers_struct] struct (for external crate queries) +during compiler initialization. The macro system generates both structs, +which act as function tables for all query implementations, where each field is a function pointer to the actual provider. -**Note:** The `Providers` struct is generated by macros and acts as a function table for all query implementations. -It is **not** a Rust trait, but a plain struct with function pointer fields. +**Note:** Both the `Providers` and `ExternProviders` structs are generated by macros and act as function tables for all query implementations. +They are **not** Rust traits, but plain structs with function pointer fields. **Providers are defined per-crate.** The compiler maintains, internally, a table of providers for every crate, at least -conceptually. Right now, there are really two sets: the providers for -queries about the **local crate** (that is, the one being compiled) -and providers for queries about **external crates** (that is, -dependencies of the local crate). Note that what determines the crate -that a query is targeting is not the *kind* of query, but the *key*. +conceptually. There are two sets of providers: +- The `Providers` struct for queries about the **local crate** (that is, the one being compiled) +- The `ExternProviders` struct for queries about **external crates** (that is, +dependencies of the local crate) + +Note that what determines the crate that a query is targeting is not the *kind* of query, but the *key*. For example, when you invoke `tcx.type_of(def_id)`, that could be a local query or an external query, depending on what crate the `def_id` is referring to (see the [`self::keys::Key`][Key] trait for more @@ -117,31 +119,31 @@ they define both a `provide` and a `provide_extern` function, through ### How providers are set up -When the tcx is created, it is given the providers by its creator using -the [`Providers`][providers_struct] struct. This struct is generated by -the macros here, but it is basically a big list of function pointers: - -[providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.Providers.html +When the tcx is created, it is given both the local and external providers by its creator using +the `Providers` struct from `rustc_middle::util`. This struct contains both the local and external providers: ```rust,ignore -struct Providers { - type_of: for<'tcx> fn(TyCtxt<'tcx>, DefId) -> Ty<'tcx>, - // ... one field for each query +pub struct Providers { + pub queries: crate::query::Providers, // Local crate providers + pub extern_queries: crate::query::ExternProviders, // External crate providers + pub hooks: crate::hooks::Providers, } ``` +Each of these provider structs is generated by the macros and contains function pointers for their respective queries. + #### How are providers registered? -The `Providers` struct is filled in during compiler initialization, mainly by the `rustc_driver` crate. -But the actual provider functions are implemented in various `rustc_*` crates (like `rustc_middle`, `rustc_hir_analysis`, etc). +The `util::Providers` struct is filled in during compiler initialization, by the `rustc_interface` crate from the `DEFAULT_QUERY_PROVIDERS` static. +The actual provider functions are defined across various `rustc_*` crates (like `rustc_middle`, `rustc_hir_analysis`, etc). To register providers, each crate exposes a [`provide`][provide_fn] function that looks like this: [provide_fn]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/fn.provide.html ```rust,ignore -pub fn provide(providers: &mut Providers) { - *providers = Providers { +pub fn provide(providers: &mut query::Providers) { + *providers = query::Providers { type_of, // ... add more providers here ..*providers @@ -149,27 +151,104 @@ pub fn provide(providers: &mut Providers) { } ``` -- This function takes a mutable reference to the `Providers` struct and sets the fields to point to the correct provider functions. -- You can also assign fields individually, e.g. `providers.type_of = type_of;`. +Note that this function accepts `query::Providers` not `util::Providers`. It is exceedingly rare to need a `provide` function that doesn't just accept `query::Providers`. If more than the `queries` field of `util::Providers` is being updated then `util::Providers` can be accepted instead: +```rust,ignore +pub fn provide(providers: &mut rustc_middle::util::Providers) { + providers.queries.type_of = type_of; + // ... add more local providers here + + providers.extern_queries.type_of = extern_type_of; + // ... add more external providers here + + providers.hooks.some_hook = some_hook; + // ... add more hooks here +} +``` + +Note that `util::Providers` implements `DerefMut` to `query::Providers` so callers of the `provide` functions can pass in a `util::Providers` and it will just work for provider functions that accept `query::Providers` too + +- This function takes a mutable reference to the `query::Providers` struct and sets the fields to point to the correct provider functions. +- You can also assign queries individually, e.g. `providers.type_of = type_of;`. +- You can assign fields individually for each provider type (local, external, and hooks). #### Adding a new provider -Suppose you want to add a new query called `fubar`. You would: +Suppose you want to add a new query called `fubar`. This section focuses on wiring up the providers; for how to declare the query itself in the big `rustc_queries!` macro, see [Adding a new query](#adding-a-new-query) below. -1. Implement the provider function: +In practice you usually: + +1. Decide which crate "owns" the query (for example `rustc_hir_analysis`, `rustc_mir_build`, or another `rustc_*` crate). +2. In that crate, look for an existing `provide` function: ```rust,ignore - fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: DefId) -> Fubar<'tcx> { ... } + pub fn provide(providers: &mut query::Providers) { + // existing assignments + } ``` -2. Register it in the `provide` function: + If it exists, you will extend it to set the field for your new query. If the crate does not yet have a `provide` function, add one and make sure it is included in `DEFAULT_QUERY_PROVIDERS` in the `rustc_interface` crate so that it actually gets called during initialization (see the discussion above). +3. Implement the provider function itself: ```rust,ignore - pub fn provide(providers: &mut Providers) { - *providers = Providers { + fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: LocalDefId) -> Fubar<'tcx> { ... } + ``` +4. Register it in the crate's `provide` function: + ```rust,ignore + pub fn provide(providers: &mut query::Providers) { + *providers = query::Providers { fubar, ..*providers }; } ``` +### How queries interact with external crate metadata + +When a query is made for an external crate (i.e., a dependency), the query system needs to load the information from that crate's metadata. +This is handled by the [`rustc_metadata` crate][rustc_metadata], which is responsible for decoding and providing the information stored in the `.rmeta` files. + +The process works like this: + +1. When a query is made, the query system first checks if the `DefId` refers to a local or external crate by checking if `def_id.krate == LOCAL_CRATE`. + This determines whether to use the local provider from [`Providers`][providers_struct] or the external provider from [`ExternProviders`][extern_providers_struct]. + +2. For external crates, the query system will look for a provider in the [`ExternProviders`][extern_providers_struct] struct. + The `rustc_metadata` crate registers these external providers through the `provide_extern` function in `rustc_metadata/src/rmeta/decoder/cstore_impl.rs`. Just like: + ```rust + pub fn provide_extern(providers: &mut ExternProviders) { + providers.foo = |tcx, def_id| { + // Load and decode metadata for external crate + let cdata = CStore::from_tcx(tcx).get_crate_data(def_id.krate); + cdata.foo(def_id.index) + }; + // Register other external providers... + } + ``` + +3. The metadata is stored in a binary format in `.rmeta` files that contains pre-computed information about the external crate, such as types, function signatures, trait implementations, and other information needed by the compiler. When an external query is made, the `rustc_metadata` crate: + - Loads the `.rmeta` file for the external crate + - Decodes the metadata using the `Decodable` trait + - Returns the decoded information to the query system + +This approach avoids recompiling external crates, allows for faster compilation of dependent crates, and enables incremental compilation to work across crate boundaries. +Here is a simplified example, when you call `tcx.type_of(def_id)` for a type defined in an external crate, the query system will: +1. Detect that the `def_id` refers to an external crate by checking `def_id.krate != LOCAL_CRATE` +2. Call the appropriate provider from `ExternProviders` which was registered by `rustc_metadata` +3. The provider will load and decode the type information from the external crate's metadata +4. Return the decoded type to the caller + +This is why most `rustc_*` crates only need to provide local providers - the external providers are handled by the metadata system. +The only exception is when a crate needs to provide special handling for external queries, in which case it would implement both local and external providers. + +When we define a new query that should work across crates, it does not automatically become cross-crate just because it is listed in `rustc_queries!`. You will typically need to: + +- Add the query to `rustc_queries!` with appropriate modifiers (for example whether it is cached on disk). +- Implement a local provider in the owning crate and register it via that crate's `provide` function. +- Add an external provider in `rustc_metadata` via `provide_extern`, and ensure the query's result is encoded and decoded in the crate metadata. + +An example of introducing such a cross-crate query can be found in commit [`996a185`](https://github.com/rust-lang/rust/commit/996a185) in the `rust-lang/rust` repository. + +[rustc_metadata]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/index.html +[providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.Providers.html +[extern_providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.ExternProviders.html + --- ## Adding a new query @@ -263,4 +342,3 @@ More discussion and issues: [GitHub issue #42633]: https://github.com/rust-lang/rust/issues/42633 [Incremental Compilation Beta]: https://internals.rust-lang.org/t/incremental-compilation-beta/4721 [Incremental Compilation Announcement]: https://blog.rust-lang.org/2016/09/08/incremental.html - From 4d011efb8e418babc9337a24791462608a39d97e Mon Sep 17 00:00:00 2001 From: Urgau <3616612+Urgau@users.noreply.github.com> Date: Fri, 12 Dec 2025 18:13:08 +0100 Subject: [PATCH 0688/3801] Remove `[no-mentions]` handler in the triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- triagebot.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 13da0a87def3..eb0c7b011f60 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -2,6 +2,3 @@ # Prevents un-canonicalized issue links (to avoid wrong issues being linked in r-l/rust) [issue-links] - -# Prevents mentions in commits to avoid users being spammed -[no-mentions] From 0a3fd242879bdd53747289db422c11a403333bcb Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Fri, 12 Dec 2025 20:34:54 +0300 Subject: [PATCH 0689/3801] Support attribute inheritance in delegation --- compiler/rustc_ast_lowering/src/delegation.rs | 156 +++++++++++++++--- compiler/rustc_middle/src/ty/mod.rs | 14 +- compiler/rustc_resolve/src/late.rs | 30 +++- tests/pretty/auxiliary/to-reuse-functions.rs | 14 ++ tests/pretty/delegation-inherit-attributes.pp | 61 +++++++ tests/pretty/delegation-inherit-attributes.rs | 56 +++++++ 6 files changed, 305 insertions(+), 26 deletions(-) create mode 100644 tests/pretty/auxiliary/to-reuse-functions.rs create mode 100644 tests/pretty/delegation-inherit-attributes.pp create mode 100644 tests/pretty/delegation-inherit-attributes.rs diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 0e7db7c9503c..82bade8829a2 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -43,13 +43,15 @@ use hir::def::{DefKind, PartialRes, Res}; use hir::{BodyId, HirId}; use rustc_abi::ExternAbi; use rustc_ast::*; +use rustc_attr_parsing::{AttributeParser, ShouldEmit}; use rustc_errors::ErrorGuaranteed; +use rustc_hir::Target; use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; -use rustc_middle::ty::{Asyncness, ResolverAstLowering}; +use rustc_middle::ty::{Asyncness, DelegationFnSigAttrs, ResolverAstLowering}; use rustc_span::symbol::kw; -use rustc_span::{Ident, Span, Symbol}; +use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; use {rustc_ast as ast, rustc_hir as hir}; use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode}; @@ -62,6 +64,41 @@ pub(crate) struct DelegationResults<'hir> { pub generics: &'hir hir::Generics<'hir>, } +struct AttributeAdditionInfo { + pub equals: fn(&hir::Attribute) -> bool, + pub kind: AttributeAdditionKind, +} + +enum AttributeAdditionKind { + Default { factory: fn(Span) -> hir::Attribute }, + Inherit { flag: DelegationFnSigAttrs, factory: fn(Span, &hir::Attribute) -> hir::Attribute }, +} + +const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO; + +static ATTRIBUTES_ADDITIONS: &[AttributeAdditionInfo] = &[ + AttributeAdditionInfo { + equals: |a| matches!(a, hir::Attribute::Parsed(AttributeKind::MustUse { .. })), + kind: AttributeAdditionKind::Inherit { + factory: |span, original_attribute| { + let reason = match original_attribute { + hir::Attribute::Parsed(AttributeKind::MustUse { reason, .. }) => *reason, + _ => None, + }; + + hir::Attribute::Parsed(AttributeKind::MustUse { span, reason }) + }, + flag: DelegationFnSigAttrs::MUST_USE, + }, + }, + AttributeAdditionInfo { + equals: |a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))), + kind: AttributeAdditionKind::Default { + factory: |span| hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span)), + }, + }, +]; + impl<'hir> LoweringContext<'_, 'hir> { fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { @@ -88,7 +125,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl); match sig_id { Ok(sig_id) => { - self.add_inline_attribute_if_needed(span); + self.add_attributes_if_needed(span, sig_id); let is_method = self.is_method(sig_id, span); let (param_count, c_variadic) = self.param_count(sig_id); @@ -103,29 +140,100 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn add_inline_attribute_if_needed(&mut self, span: Span) { - const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO; - let create_inline_attr_slice = - || [hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span))]; + fn add_attributes_if_needed(&mut self, span: Span, sig_id: DefId) { + let new_attributes = self.create_new_attributes( + ATTRIBUTES_ADDITIONS, + span, + sig_id, + self.attrs.get(&PARENT_ID), + ); - let new_attributes = match self.attrs.get(&PARENT_ID) { - Some(attrs) => { - // Check if reuse already specifies any inline attribute, if so, do nothing - if attrs - .iter() - .any(|a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..)))) - { - return; - } + if new_attributes.is_empty() { + return; + } - self.arena.alloc_from_iter( - attrs.into_iter().map(|a| a.clone()).chain(create_inline_attr_slice()), - ) - } - None => self.arena.alloc_from_iter(create_inline_attr_slice()), + let new_arena_allocated_attributes = match self.attrs.get(&PARENT_ID) { + Some(existing_attrs) => self.arena.alloc_from_iter( + existing_attrs.iter().map(|a| a.clone()).chain(new_attributes.into_iter()), + ), + None => self.arena.alloc_from_iter(new_attributes.into_iter()), }; - self.attrs.insert(PARENT_ID, new_attributes); + self.attrs.insert(PARENT_ID, new_arena_allocated_attributes); + } + + fn create_new_attributes( + &self, + candidate_additions: &[AttributeAdditionInfo], + span: Span, + sig_id: DefId, + existing_attrs: Option<&&[hir::Attribute]>, + ) -> Vec { + let local_original_attributes = self.parse_local_original_attributes(sig_id); + + candidate_additions + .iter() + .filter_map(|addition_info| { + if let Some(existing_attrs) = existing_attrs + && existing_attrs + .iter() + .any(|existing_attr| (addition_info.equals)(existing_attr)) + { + return None; + } + + match addition_info.kind { + AttributeAdditionKind::Default { factory } => Some(factory(span)), + AttributeAdditionKind::Inherit { flag, factory } => { + let original_attribute = match sig_id.as_local() { + Some(local_id) => self + .resolver + .delegation_fn_sigs + .get(&local_id) + .is_some_and(|sig| sig.attrs_flags.contains(flag)) + .then(|| { + local_original_attributes + .as_ref() + .map(|attrs| { + attrs + .iter() + .find(|base_attr| (addition_info.equals)(base_attr)) + }) + .flatten() + }) + .flatten(), + None => self + .tcx + .get_all_attrs(sig_id) + .iter() + .find(|base_attr| (addition_info.equals)(base_attr)), + }; + + original_attribute.map(|a| factory(span, a)) + } + } + }) + .collect::>() + } + + fn parse_local_original_attributes(&self, sig_id: DefId) -> Option> { + if let Some(local_id) = sig_id.as_local() + && let Some(info) = self.resolver.delegation_fn_sigs.get(&local_id) + && !info.to_inherit_attrs.is_empty() + { + Some(AttributeParser::parse_limited_all( + self.tcx.sess, + info.to_inherit_attrs.as_slice(), + None, + Target::Fn, + DUMMY_SP, + DUMMY_NODE_ID, + Some(self.tcx.features()), + ShouldEmit::Nothing, + )) + } else { + None + } } fn get_delegation_sig_id( @@ -220,7 +328,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // We are not forwarding the attributes, as the delegation fn sigs are collected on the ast, // and here we need the hir attributes. let default_safety = - if sig.target_feature || self.tcx.def_kind(parent) == DefKind::ForeignMod { + if sig.attrs_flags.contains(DelegationFnSigAttrs::TARGET_FEATURE) + || self.tcx.def_kind(parent) == DefKind::ForeignMod + { hir::Safety::Unsafe } else { hir::Safety::Safe diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6ca4949910f2..418335a89347 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -25,6 +25,7 @@ pub use generic_args::{GenericArgKind, TermKind, *}; pub use generics::*; pub use intrinsic::IntrinsicDef; use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx}; +use rustc_ast::AttrVec; use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree}; use rustc_ast::node_id::NodeMap; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; @@ -221,13 +222,24 @@ pub struct ResolverAstLowering { pub delegation_fn_sigs: LocalDefIdMap, } +bitflags::bitflags! { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] + pub struct DelegationFnSigAttrs: u8 { + const TARGET_FEATURE = 1 << 0; + const MUST_USE = 1 << 1; + } +} + +pub const DELEGATION_INHERIT_ATTRS_START: DelegationFnSigAttrs = DelegationFnSigAttrs::MUST_USE; + #[derive(Debug)] pub struct DelegationFnSig { pub header: ast::FnHeader, pub param_count: usize, pub has_self: bool, pub c_variadic: bool, - pub target_feature: bool, + pub attrs_flags: DelegationFnSigAttrs, + pub to_inherit_attrs: AttrVec, } #[derive(Clone, Copy, Debug, HashStable)] diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f1a03d5a0610..cc17ca9c026d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -28,7 +28,9 @@ use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, Par use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate}; use rustc_middle::middle::resolve_bound_vars::Set1; -use rustc_middle::ty::{AssocTag, DelegationFnSig, Visibility}; +use rustc_middle::ty::{ + AssocTag, DELEGATION_INHERIT_ATTRS_START, DelegationFnSig, DelegationFnSigAttrs, Visibility, +}; use rustc_middle::{bug, span_bug}; use rustc_session::config::{CrateType, ResolveDocLinks}; use rustc_session::lint; @@ -5294,13 +5296,37 @@ impl ItemInfoCollector<'_, '_, '_> { id: NodeId, attrs: &[Attribute], ) { + static NAMES_TO_FLAGS: &[(Symbol, DelegationFnSigAttrs)] = &[ + (sym::target_feature, DelegationFnSigAttrs::TARGET_FEATURE), + (sym::must_use, DelegationFnSigAttrs::MUST_USE), + ]; + + let mut to_inherit_attrs = AttrVec::new(); + let mut attrs_flags = DelegationFnSigAttrs::empty(); + + 'attrs_loop: for attr in attrs { + for &(name, flag) in NAMES_TO_FLAGS { + if attr.has_name(name) { + attrs_flags.set(flag, true); + + if flag.bits() >= DELEGATION_INHERIT_ATTRS_START.bits() { + to_inherit_attrs.push(attr.clone()); + } + + continue 'attrs_loop; + } + } + } + let sig = DelegationFnSig { header, param_count: decl.inputs.len(), has_self: decl.has_self(), c_variadic: decl.c_variadic(), - target_feature: attrs.iter().any(|attr| attr.has_name(sym::target_feature)), + attrs_flags, + to_inherit_attrs, }; + self.r.delegation_fn_sigs.insert(self.r.local_def_id(id), sig); } } diff --git a/tests/pretty/auxiliary/to-reuse-functions.rs b/tests/pretty/auxiliary/to-reuse-functions.rs new file mode 100644 index 000000000000..55d6ecf035e3 --- /dev/null +++ b/tests/pretty/auxiliary/to-reuse-functions.rs @@ -0,0 +1,14 @@ +//@ edition:2021 + +#[must_use] +#[cold] +pub unsafe fn unsafe_fn_extern() -> usize { 1 } + +#[must_use = "extern_fn_extern: some reason"] +#[deprecated] +pub extern "C" fn extern_fn_extern() -> usize { 1 } + +pub const fn const_fn_extern() -> usize { 1 } + +#[must_use] +pub async fn async_fn_extern() { } diff --git a/tests/pretty/delegation-inherit-attributes.pp b/tests/pretty/delegation-inherit-attributes.pp new file mode 100644 index 000000000000..772e177b8883 --- /dev/null +++ b/tests/pretty/delegation-inherit-attributes.pp @@ -0,0 +1,61 @@ +//@ edition:2021 +//@ aux-crate:to_reuse_functions=to-reuse-functions.rs +//@ pretty-mode:hir +//@ pretty-compare-only +//@ pp-exact:delegation-inherit-attributes.pp + +#![allow(incomplete_features)] +#![feature(fn_delegation)] +#[attr = MacroUse {arguments: UseAll}] +extern crate std; +#[prelude_import] +use std::prelude::rust_2021::*; + +extern crate to_reuse_functions; + +mod to_reuse { + #[attr = MustUse {reason: "foo: some reason"}] + #[attr = Cold] + fn foo(x: usize) -> usize { x } + + #[attr = MustUse] + #[attr = Cold] + fn foo_no_reason(x: usize) -> usize { x } + + #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] + #[attr = Cold] + fn bar(x: usize) -> usize { x } +} + +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] +#[attr = MustUse {reason: "foo: some reason"}] +#[attr = Inline(Hint)] +fn foo1(arg0: _) -> _ { to_reuse::foo(self + 1) } + +#[attr = MustUse] +#[attr = Inline(Hint)] +fn foo_no_reason(arg0: _) -> _ { to_reuse::foo_no_reason(self + 1) } + +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] +#[attr = MustUse {reason: "some reason"}] +#[attr = Inline(Hint)] +fn foo2(arg0: _) -> _ { to_reuse::foo(self + 1) } + +#[attr = Inline(Hint)] +fn bar(arg0: _) -> _ { to_reuse::bar(arg0) } + +#[attr = MustUse] +#[attr = Inline(Hint)] +unsafe fn unsafe_fn_extern() -> _ { to_reuse_functions::unsafe_fn_extern() } +#[attr = MustUse {reason: "extern_fn_extern: some reason"}] +#[attr = Inline(Hint)] +extern "C" fn extern_fn_extern() + -> _ { to_reuse_functions::extern_fn_extern() } +#[attr = Inline(Hint)] +const fn const_fn_extern() -> _ { to_reuse_functions::const_fn_extern() } +#[attr = MustUse {reason: "some reason"}] +#[attr = Inline(Hint)] +async fn async_fn_extern() -> _ { to_reuse_functions::async_fn_extern() } + + +fn main() { } diff --git a/tests/pretty/delegation-inherit-attributes.rs b/tests/pretty/delegation-inherit-attributes.rs new file mode 100644 index 000000000000..fe74b9a55a7d --- /dev/null +++ b/tests/pretty/delegation-inherit-attributes.rs @@ -0,0 +1,56 @@ +//@ edition:2021 +//@ aux-crate:to_reuse_functions=to-reuse-functions.rs +//@ pretty-mode:hir +//@ pretty-compare-only +//@ pp-exact:delegation-inherit-attributes.pp + +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +extern crate to_reuse_functions; + +mod to_reuse { + #[must_use = "foo: some reason"] + #[cold] + pub fn foo(x: usize) -> usize { + x + } + + #[must_use] + #[cold] + pub fn foo_no_reason(x: usize) -> usize { + x + } + + #[cold] + #[deprecated] + pub fn bar(x: usize) -> usize { + x + } +} + +#[deprecated] +reuse to_reuse::foo as foo1 { + self + 1 +} + +reuse to_reuse::foo_no_reason { + self + 1 +} + +#[deprecated] +#[must_use = "some reason"] +reuse to_reuse::foo as foo2 { + self + 1 +} + +reuse to_reuse::bar; + +reuse to_reuse_functions::unsafe_fn_extern; +reuse to_reuse_functions::extern_fn_extern; +reuse to_reuse_functions::const_fn_extern; +#[must_use = "some reason"] +reuse to_reuse_functions::async_fn_extern; + + +fn main() {} From 146711fc249aec2272d565878e9139fa75f81288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Dec 2025 00:43:46 +0000 Subject: [PATCH 0690/3801] Use `let...else` instead of `match foo { ... _ => return };` and `if let ... else return` --- compiler/rustc_ast/src/ast.rs | 7 +- compiler/rustc_ast/src/attr/mod.rs | 19 ++- .../src/diagnostics/conflict_errors.rs | 7 +- .../src/diagnostics/explain_borrow.rs | 14 +-- .../rustc_borrowck/src/diagnostics/mod.rs | 14 +-- .../src/diagnostics/mutability_errors.rs | 9 +- .../src/diagnostics/region_errors.rs | 50 +++----- .../src/polonius/legacy/accesses.rs | 11 +- .../src/debuginfo/unwind.rs | 6 +- .../src/optimize/peephole.rs | 6 +- .../rustc_codegen_gcc/src/intrinsic/simd.rs | 31 +++-- compiler/rustc_codegen_llvm/src/intrinsic.rs | 5 +- .../rustc_codegen_ssa/src/codegen_attrs.rs | 5 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 5 +- compiler/rustc_hir_analysis/src/collect.rs | 14 +-- .../src/collect/item_bounds.rs | 25 ++-- .../errors/wrong_number_of_generic_args.rs | 15 +-- .../src/hir_ty_lowering/errors.rs | 6 +- compiler/rustc_hir_typeck/src/callee.rs | 9 +- compiler/rustc_hir_typeck/src/demand.rs | 7 +- .../rustc_hir_typeck/src/expr_use_visitor.rs | 16 +-- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 23 ++-- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 7 +- .../src/fn_ctxt/suggestions.rs | 20 ++- compiler/rustc_hir_typeck/src/inline_asm.rs | 7 +- .../rustc_hir_typeck/src/method/suggest.rs | 6 +- compiler/rustc_lint/src/builtin.rs | 7 +- ..._expr_fragment_specifier_2024_migration.rs | 6 +- compiler/rustc_middle/src/ty/diagnostics.rs | 9 +- compiler/rustc_middle/src/ty/mod.rs | 4 +- compiler/rustc_middle/src/ty/sty.rs | 15 +-- .../rustc_mir_dataflow/src/move_paths/mod.rs | 14 +-- .../rustc_mir_dataflow/src/value_analysis.rs | 7 +- compiler/rustc_mir_transform/src/gvn.rs | 45 ++++--- .../rustc_mir_transform/src/promote_consts.rs | 10 +- .../src/solve/eval_ctxt/mod.rs | 14 +-- .../src/solve/normalizes_to/mod.rs | 14 +-- .../src/solve/trait_goals.rs | 79 ++++++------ .../rustc_resolve/src/late/diagnostics.rs | 114 +++++++++--------- 39 files changed, 282 insertions(+), 400 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index e348cc1ab281..67152f5d2462 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1534,11 +1534,10 @@ impl Expr { // then type of result is trait object. // Otherwise we don't assume the result type. ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => { - if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) { - TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None) - } else { + let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) else { return None; - } + }; + TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None) } ExprKind::Underscore => TyKind::Infer, diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index a5e630a09afe..c53188a22aed 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -447,20 +447,17 @@ impl MetaItem { thin_vec![PathSegment::path_root(span)] }; loop { - if let Some(&TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) = + let Some(&TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) = iter.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref() - { - segments.push(PathSegment::from_ident(Ident::new(name, span))); - } else { + else { return None; - } - if let Some(TokenTree::Token(Token { kind: token::PathSep, .. }, _)) = - iter.peek() - { - iter.next(); - } else { + }; + segments.push(PathSegment::from_ident(Ident::new(name, span))); + let Some(TokenTree::Token(Token { kind: token::PathSep, .. }, _)) = iter.peek() + else { break; - } + }; + iter.next(); } let span = span.with_hi(segments.last().unwrap().ident.span.hi()); Path { span, segments, tokens: None } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2999d1f2926c..5cfe9db009bf 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -561,11 +561,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { VarDebugInfoContents::Place(ref p) => p == place, _ => false, }); - let arg_name = if let Some(var_info) = var_info { - var_info.name - } else { - return; - }; + let Some(var_info) = var_info else { return }; + let arg_name = var_info.name; struct MatchArgFinder { expr_span: Span, match_arg_span: Option, diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index bfdfa896cd2b..8e18bf557758 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -850,16 +850,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { // will only ever have one item at any given time, but by using a vector, we can pop from // it which simplifies the termination logic. let mut queue = vec![location]; - let mut target = - if let Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) = stmt { - if let Some(local) = place.as_local() { - local - } else { - return false; - } - } else { - return false; - }; + let Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) = stmt else { + return false; + }; + let Some(mut target) = place.as_local() else { return false }; debug!("was_captured_by_trait: target={:?} queue={:?}", target, queue); while let Some(current_location) = queue.pop() { diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index e13c1c712d8d..e725b13434a1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1124,16 +1124,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { use self::UseSpans::*; debug!("borrow_spans: use_span={:?} location={:?}", use_span, location); - let target = match self.body[location.block].statements.get(location.statement_index) { - Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) => { - if let Some(local) = place.as_local() { - local - } else { - return OtherUse(use_span); - } - } - _ => return OtherUse(use_span), + let Some(Statement { kind: StatementKind::Assign(box (place, _)), .. }) = + self.body[location.block].statements.get(location.statement_index) + else { + return OtherUse(use_span); }; + let Some(target) = place.as_local() else { return OtherUse(use_span) }; if self.body.local_kind(target) != LocalKind::Temp { // operands are always temporaries. diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 7d72de7efa4a..e9039d4311b6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -142,12 +142,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } else { item_msg = access_place_desc; let local_info = self.body.local_decls[local].local_info(); - if let LocalInfo::StaticRef { def_id, .. } = *local_info { - let static_name = &self.infcx.tcx.item_name(def_id); - reason = format!(", as `{static_name}` is an immutable static item"); - } else { + let LocalInfo::StaticRef { def_id, .. } = *local_info else { bug!("is_ref_to_static return true, but not ref to static?"); - } + }; + let static_name = &self.infcx.tcx.item_name(def_id); + reason = format!(", as `{static_name}` is an immutable static item"); } } PlaceRef { local, projection: [proj_base @ .., ProjectionElem::Deref] } => { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index f4bbdabf7f21..9c2b9139367a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -847,11 +847,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.scope); - let param = if let Some(param) = + let Some(param) = find_param_with_region(self.infcx.tcx, self.mir_def_id(), f, outlived_f) - { - param - } else { + else { return; }; @@ -930,37 +928,27 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let tcx = self.infcx.tcx; - let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category { - let (fn_did, args) = match func_ty.kind() { - ty::FnDef(fn_did, args) => (fn_did, args), - _ => return, - }; - debug!(?fn_did, ?args); + let ConstraintCategory::CallArgument(Some(func_ty)) = category else { return }; + let ty::FnDef(fn_did, args) = func_ty.kind() else { return }; + debug!(?fn_did, ?args); - // Only suggest this on function calls, not closures - let ty = tcx.type_of(fn_did).instantiate_identity(); - debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind()); - if let ty::Closure(_, _) = ty.kind() { - return; - } - - if let Ok(Some(instance)) = ty::Instance::try_resolve( - tcx, - self.infcx.typing_env(self.infcx.param_env), - *fn_did, - self.infcx.resolve_vars_if_possible(args), - ) { - instance - } else { - return; - } - } else { + // Only suggest this on function calls, not closures + let ty = tcx.type_of(fn_did).instantiate_identity(); + debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind()); + if let ty::Closure(_, _) = ty.kind() { + return; + } + let Ok(Some(instance)) = ty::Instance::try_resolve( + tcx, + self.infcx.typing_env(self.infcx.param_env), + *fn_did, + self.infcx.resolve_vars_if_possible(args), + ) else { return; }; - let param = match find_param_with_region(tcx, self.mir_def_id(), f, o) { - Some(param) => param, - None => return, + let Some(param) = find_param_with_region(tcx, self.mir_def_id(), f, o) else { + return; }; debug!(?param); diff --git a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs index edd7ca578b72..dc174775af2e 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs @@ -67,12 +67,11 @@ impl<'a, 'tcx> Visitor<'tcx> for AccessFactsExtractor<'a, 'tcx> { match context { PlaceContext::NonMutatingUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => { - let path = match self.move_data.rev_lookup.find(place.as_ref()) { - LookupResult::Exact(path) | LookupResult::Parent(Some(path)) => path, - _ => { - // There's no path access to emit. - return; - } + let (LookupResult::Exact(path) | LookupResult::Parent(Some(path))) = + self.move_data.rev_lookup.find(place.as_ref()) + else { + // There's no path access to emit. + return; }; debug!("AccessFactsExtractor - emit path access ({path:?}, {location:?})"); self.facts.path_accessed_at_base.push((path, self.location_to_index(location))); diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs index ecaf88a26259..33ffe4cc4e9c 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs @@ -130,11 +130,9 @@ impl UnwindContext { return; } - let unwind_info = if let Some(unwind_info) = + let Some(unwind_info) = context.compiled_code().unwrap().create_unwind_info(module.isa()).unwrap() - { - unwind_info - } else { + else { return; }; diff --git a/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs b/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs index c93fe9352103..f38c1f96e6ed 100644 --- a/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs +++ b/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs @@ -29,11 +29,7 @@ pub(crate) fn maybe_known_branch_taken( arg: Value, test_zero: bool, ) -> Option { - let arg_inst = if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) { - arg_inst - } else { - return None; - }; + let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) else { return None }; match bcx.func.dfg.insts[arg_inst] { InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => { diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index c7ed887b30d0..39b4bb3ebefa 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -774,24 +774,23 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( return Err(()); }}; } - let (elem_ty_str, elem_ty, cast_type) = if let ty::Float(ref f) = *in_elem.kind() { - let elem_ty = bx.cx.type_float_from_ty(*f); - match f.bit_width() { - 16 => ("", elem_ty, Some(bx.cx.double_type)), - 32 => ("f", elem_ty, None), - 64 => ("", elem_ty, None), - _ => { - return_error!(InvalidMonomorphization::FloatingPointVector { - span, - name, - f_ty: *f, - in_ty - }); - } - } - } else { + let ty::Float(ref f) = *in_elem.kind() else { return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); }; + let elem_ty = bx.cx.type_float_from_ty(*f); + let (elem_ty_str, elem_ty, cast_type) = match f.bit_width() { + 16 => ("", elem_ty, Some(bx.cx.double_type)), + 32 => ("f", elem_ty, None), + 64 => ("", elem_ty, None), + _ => { + return_error!(InvalidMonomorphization::FloatingPointVector { + span, + name, + f_ty: *f, + in_ty + }); + } + }; let vec_ty = bx.cx.type_vector(elem_ty, in_len); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 33541f7b695f..e43bd8c2feef 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1756,11 +1756,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }}; } - let elem_ty = if let ty::Float(f) = in_elem.kind() { - bx.cx.type_float_from_ty(*f) - } else { + let ty::Float(f) = in_elem.kind() else { return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); }; + let elem_ty = bx.cx.type_float_from_ty(*f); let vec_ty = bx.type_vector(elem_ty, in_len); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 0ab0cb0ef88a..bfbe7bc20052 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -721,11 +721,10 @@ pub fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option { }; // First read the ret symbol from the attribute - let ret_symbol = if let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = ret_activity { - p1.segments.first().unwrap().ident - } else { + let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = ret_activity else { span_bug!(attr.span(), "rustc_autodiff attribute must contain the return activity"); }; + let ret_symbol = p1.segments.first().unwrap().ident; // Then parse it into an actual DiffActivity let Ok(ret_activity) = DiffActivity::from_str(ret_symbol.as_str()) else { diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index c548cea537f4..8d2cc23f9763 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -788,11 +788,10 @@ pub fn compile_declarative_macro( let lhs_span = lhs_tt.span(); // Convert the lhs into `MatcherLoc` form, which is better for doing the // actual matching. - let lhs = if let mbe::TokenTree::Delimited(.., delimited) = lhs_tt { - mbe::macro_parser::compute_locs(&delimited.tts) - } else { + let mbe::TokenTree::Delimited(.., delimited) = lhs_tt else { return dummy_syn_ext(guar.unwrap()); }; + let lhs = mbe::macro_parser::compute_locs(&delimited.tts); if let Some(args) = args { let args_span = args.span(); let mbe::TokenTree::Delimited(.., delimited) = args else { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 3cfcac5c7291..2e06684e0c7a 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1551,15 +1551,15 @@ fn const_param_default<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, ) -> ty::EarlyBinder<'tcx, Const<'tcx>> { - let default_ct = match tcx.hir_node_by_def_id(def_id) { - hir::Node::GenericParam(hir::GenericParam { - kind: hir::GenericParamKind::Const { default: Some(ct), .. }, - .. - }) => ct, - _ => span_bug!( + let hir::Node::GenericParam(hir::GenericParam { + kind: hir::GenericParamKind::Const { default: Some(default_ct), .. }, + .. + }) = tcx.hir_node_by_def_id(def_id) + else { + span_bug!( tcx.def_span(def_id), "`const_param_default` expected a generic parameter with a constant" - ), + ) }; let icx = ItemCtxt::new(tcx, def_id); let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 6b51e3157961..7025f7ac84b0 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -188,29 +188,26 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>( for (param, var) in std::iter::zip(&generics.own_params, gat_vars) { let existing = match var.kind() { ty::GenericArgKind::Lifetime(re) => { - if let ty::RegionKind::ReBound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) = + let ty::RegionKind::ReBound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) = re.kind() - { - mapping.insert(bv.var, tcx.mk_param_from_def(param)) - } else { + else { return None; - } + }; + mapping.insert(bv.var, tcx.mk_param_from_def(param)) } ty::GenericArgKind::Type(ty) => { - if let ty::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) = *ty.kind() { - mapping.insert(bv.var, tcx.mk_param_from_def(param)) - } else { + let ty::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) = *ty.kind() else { return None; - } + }; + mapping.insert(bv.var, tcx.mk_param_from_def(param)) } ty::GenericArgKind::Const(ct) => { - if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) = + let ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) = ct.kind() - { - mapping.insert(bv.var, tcx.mk_param_from_def(param)) - } else { + else { return None; - } + }; + mapping.insert(bv.var, tcx.mk_param_from_def(param)) } }; diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 30324da3c651..d835a7bbb8d2 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -763,9 +763,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { &self, err: &mut Diag<'_, impl EmissionGuarantee>, ) { - let trait_ = match self.tcx.trait_of_assoc(self.def_id) { - Some(def_id) => def_id, - None => return, + let Some(trait_) = self.tcx.trait_of_assoc(self.def_id) else { + return; }; // Skip suggestion when the associated function is itself generic, it is unclear @@ -1077,15 +1076,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { /// Builds the `type defined here` message. fn show_definition(&self, err: &mut Diag<'_, impl EmissionGuarantee>) { - let mut spans: MultiSpan = if let Some(def_span) = self.tcx.def_ident_span(self.def_id) { - if self.tcx.sess.source_map().is_span_accessible(def_span) { - def_span.into() - } else { - return; - } - } else { + let Some(def_span) = self.tcx.def_ident_span(self.def_id) else { return }; + if !self.tcx.sess.source_map().is_span_accessible(def_span) { return; }; + let mut spans: MultiSpan = def_span.into(); let msg = { let def_kind = self.tcx.def_descr(self.def_id); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 600684d4f514..5fc201db68e5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1749,10 +1749,8 @@ fn generics_args_err_extend<'a>( GenericsArgsErrExtend::SelfTyAlias { def_id, span } => { let ty = tcx.at(span).type_of(def_id).instantiate_identity(); let span_of_impl = tcx.span_of_impl(def_id); - let def_id = match *ty.kind() { - ty::Adt(self_def, _) => self_def.did(), - _ => return, - }; + let ty::Adt(self_def, _) = *ty.kind() else { return }; + let def_id = self_def.did(); let type_name = tcx.item_name(def_id); let span_of_ty = tcx.def_ident_span(def_id); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index f59fcab46661..714c6a104a9e 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -458,15 +458,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // Actually need to unwrap one more layer of HIR to get to // the _real_ closure... - if let hir::Node::Expr(&hir::Expr { + let hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. }) = self.tcx.parent_hir_node(parent_hir_id) - { - fn_decl_span - } else { + else { return; - } + }; + fn_decl_span } else { return; }; diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index f1e74028f4ce..3f214b4d2fcc 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -415,11 +415,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); Some(self.resolve_vars_if_possible(possible_rcvr_ty)) }); - if let Some(rcvr_ty) = possible_rcvr_ty { - rcvr_ty - } else { - return false; - } + let Some(rcvr_ty) = possible_rcvr_ty else { return false }; + rcvr_ty } }; diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 561230c193ce..27b66d07f98e 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1561,19 +1561,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx base_place: PlaceWithHirId<'tcx>, ) -> Result, Cx::Error> { let base_curr_ty = base_place.place.ty(); - let deref_ty = match self + let Some(deref_ty) = self .cx .structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty) .builtin_deref(true) - { - Some(ty) => ty, - None => { - debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); - return Err(self.cx.report_bug( - self.cx.tcx().hir_span(node), - "explicit deref of non-derefable type", - )); - } + else { + debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); + return Err(self + .cx + .report_bug(self.cx.tcx().hir_span(node), "explicit deref of non-derefable type")); }; let mut projections = base_place.place.projections; projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty }); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 854202c31270..5c04f2b5f63c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -48,33 +48,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let uninstantiated_pred = match flavor { - ClauseFlavor::Where => { + ClauseFlavor::Where if let Some(pred) = self .tcx .predicates_of(def_id) .instantiate_identity(self.tcx) .predicates .into_iter() - .nth(idx) - { - pred - } else { - return false; - } + .nth(idx) => + { + pred } - ClauseFlavor::Const => { + ClauseFlavor::Const if let Some((pred, _)) = self .tcx .const_conditions(def_id) .instantiate_identity(self.tcx) .into_iter() - .nth(idx) - { - pred.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe) - } else { - return false; - } + .nth(idx) => + { + pred.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe) } + _ => return false, }; let generics = self.tcx.generics_of(def_id); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 57da450d832c..d04133ccee97 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1467,11 +1467,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, } }); - if let Some(new_def_id) = new_def_id { - def_id = new_def_id; - } else { - return; - } + let Some(new_def_id) = new_def_id else { return }; + def_id = new_def_id; } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 1adcd91cc3ee..d51b052e0d1b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1795,7 +1795,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(ty), hir::Path { segments: [segment], .. }, )) - | hir::ExprKind::Path(QPath::TypeRelative(ty, segment)) => { + | hir::ExprKind::Path(QPath::TypeRelative(ty, segment)) if let Some(self_ty) = self.typeck_results.borrow().node_type_opt(ty.hir_id) && let Ok(pick) = self.probe_for_name( Mode::Path, @@ -1805,12 +1805,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, expr.hir_id, ProbeScope::TraitsInScope, - ) - { - (pick.item, segment) - } else { - return false; - } + ) => + { + (pick.item, segment) } hir::ExprKind::Path(QPath::Resolved( None, @@ -1821,16 +1818,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if old_item_name != segment.ident.name { return false; } - if let Some(item) = self + let Some(item) = self .tcx .associated_items(self.tcx.parent(old_def_id)) .filter_by_name_unhygienic(capitalized_name) .next() - { - (*item, segment) - } else { + else { return false; - } + }; + (*item, segment) } _ => return false, }; diff --git a/compiler/rustc_hir_typeck/src/inline_asm.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs index 6460bd72c797..6626c3edb546 100644 --- a/compiler/rustc_hir_typeck/src/inline_asm.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -121,13 +121,12 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { len, ) }; - if let Some(len) = len.try_to_target_usize(self.tcx()) { - (len, ty) - } else { + let Some(len) = len.try_to_target_usize(self.tcx()) else { return Err(NonAsmTypeReason::UnevaluatedSIMDArrayLength( field.did, len, )); - } + }; + (len, ty) } _ => (fields.len() as u64, elem_ty), }; diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 4b9ad345210d..d31cd8569bb7 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3543,10 +3543,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, return_type: Option>, ) { - let output_ty = match self.err_ctxt().get_impl_future_output_ty(ty) { - Some(output_ty) => self.resolve_vars_if_possible(output_ty), - _ => return, - }; + let Some(output_ty) = self.err_ctxt().get_impl_future_output_ty(ty) else { return }; + let output_ty = self.resolve_vars_if_possible(output_ty); let method_exists = self.method_exists_for_diagnostic(item_name, output_ty, call.hir_id, return_type); debug!("suggest_await_before_method: is_method_exist={}", method_exists); diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 87b208923ddb..810760e9f53e 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1072,11 +1072,8 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes { cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, ) -> Option<(Ty<'tcx>, Ty<'tcx>)> { - let def = if let hir::ExprKind::Path(ref qpath) = expr.kind { - cx.qpath_res(qpath, expr.hir_id) - } else { - return None; - }; + let hir::ExprKind::Path(ref qpath) = expr.kind else { return None }; + let def = cx.qpath_res(qpath, expr.hir_id); if let Res::Def(DefKind::Fn, did) = def { if !def_id_is_transmute(cx, did) { return None; diff --git a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs index f20605c91495..9220702c21f1 100644 --- a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs +++ b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs @@ -120,10 +120,8 @@ impl Expr2024 { fn check_ident_token(&mut self, cx: &crate::EarlyContext<'_>, token: &Token) { debug!("check_ident_token: {:?}", token); - let (sym, edition) = match token.kind { - TokenKind::Ident(sym, _) => (sym, Edition::Edition2024), - _ => return, - }; + let TokenKind::Ident(sym, _) = token.kind else { return }; + let edition = Edition::Edition2024; debug!("token.span.edition(): {:?}", token.span.edition()); if token.span.edition() >= edition { diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 2e64fc290fcc..279c34cb275d 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -706,12 +706,9 @@ impl<'tcx> FallibleTypeFolder> for MakeSuggestableFolder<'tcx> { | Bound(_, _) | Placeholder(_) | Error(_) => { - if let Some(placeholder) = self.placeholder { - // We replace these with infer (which is passed in from an infcx). - placeholder - } else { - return Err(()); - } + let Some(placeholder) = self.placeholder else { return Err(()) }; + // We replace these with infer (which is passed in from an infcx). + placeholder } Alias(Opaque, AliasTy { def_id, .. }) => { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6ca4949910f2..4e7e1da03e9f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2395,9 +2395,7 @@ fn typetree_from_ty_impl_inner<'tcx>( } if ty.is_ref() || ty.is_raw_ptr() || ty.is_box() { - let inner_ty = if let Some(inner) = ty.builtin_deref(true) { - inner - } else { + let Some(inner_ty) = ty.builtin_deref(true) else { return TypeTree::new(); }; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 72573d96dc54..852a0017687f 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1528,18 +1528,13 @@ impl<'tcx> Ty<'tcx> { let mut cor_ty = self; let mut ty = cor_ty; loop { - if let ty::Coroutine(def_id, args) = ty.kind() { - cor_ty = ty; - f(ty); - if tcx.is_async_drop_in_place_coroutine(*def_id) { - ty = args.first().unwrap().expect_ty(); - continue; - } else { - return cor_ty; - } - } else { + let ty::Coroutine(def_id, args) = ty.kind() else { return cor_ty }; + cor_ty = ty; + f(ty); + if !tcx.is_async_drop_in_place_coroutine(*def_id) { return cor_ty; } + ty = args.first().unwrap().expect_ty(); } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 6faef3e974a0..800d4e406cf0 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -100,11 +100,8 @@ impl<'tcx> MovePath<'tcx> { move_paths: &IndexSlice>, f: impl Fn(MovePathIndex) -> bool, ) -> Option { - let mut todo = if let Some(child) = self.first_child { - vec![child] - } else { - return None; - }; + let Some(child) = self.first_child else { return None }; + let mut todo = vec![child]; while let Some(mpi) = todo.pop() { if f(mpi) { @@ -331,11 +328,10 @@ impl<'tcx> MovePathLookup<'tcx> { MoveSubPathResult::Stop => None, }; - if let Some(&subpath) = subpath { - result = subpath; - } else { + let Some(&subpath) = subpath else { return LookupResult::Parent(Some(result)); - } + }; + result = subpath; } LookupResult::Exact(result) diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index b1ff7ffc60ed..daf304c1bf9d 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -721,11 +721,8 @@ impl<'tcx> Map<'tcx> { // Enum variant fields and enum discriminants alias each another. self.for_each_variant_sibling(index, sub, f); } - if let Some(sub) = sub { - index = sub - } else { - return; - } + let Some(sub) = sub else { return }; + index = sub; } self.for_each_value_inside(index, f); } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index ebfeba5ad225..92c74e7fc276 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -590,31 +590,30 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { let fields = fields.iter().map(|&f| self.eval_to_const(f)).collect::>>()?; let variant = if ty.ty.is_enum() { Some(variant) } else { None }; - if matches!(ty.backend_repr, BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..)) - { - let dest = self.ecx.allocate(ty, MemoryKind::Stack).discard_err()?; - let variant_dest = if let Some(variant) = variant { - self.ecx.project_downcast(&dest, variant).discard_err()? - } else { - dest.clone() - }; - for (field_index, op) in fields.into_iter().enumerate() { - let field_dest = self - .ecx - .project_field(&variant_dest, FieldIdx::from_usize(field_index)) - .discard_err()?; - self.ecx.copy_op(op, &field_dest).discard_err()?; - } - self.ecx - .write_discriminant(variant.unwrap_or(FIRST_VARIANT), &dest) - .discard_err()?; - self.ecx - .alloc_mark_immutable(dest.ptr().provenance.unwrap().alloc_id()) - .discard_err()?; - dest.into() - } else { + let (BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..)) = ty.backend_repr + else { return None; + }; + let dest = self.ecx.allocate(ty, MemoryKind::Stack).discard_err()?; + let variant_dest = if let Some(variant) = variant { + self.ecx.project_downcast(&dest, variant).discard_err()? + } else { + dest.clone() + }; + for (field_index, op) in fields.into_iter().enumerate() { + let field_dest = self + .ecx + .project_field(&variant_dest, FieldIdx::from_usize(field_index)) + .discard_err()?; + self.ecx.copy_op(op, &field_dest).discard_err()?; } + self.ecx + .write_discriminant(variant.unwrap_or(FIRST_VARIANT), &dest) + .discard_err()?; + self.ecx + .alloc_mark_immutable(dest.ptr().provenance.unwrap().alloc_id()) + .discard_err()?; + dest.into() } Union(active_field, field) => { let field = self.eval_to_const(field)?; diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 6b0c331ff541..7d631e96c32a 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -410,14 +410,8 @@ impl<'tcx> Validator<'_, 'tcx> { // In theory, any zero-sized value could be borrowed // mutably without consequences. However, only &mut [] // is allowed right now. - if let ty::Array(_, len) = ty.kind() { - match len.try_to_target_usize(self.tcx) { - Some(0) => {} - _ => return Err(Unpromotable), - } - } else { - return Err(Unpromotable); - } + let ty::Array(_, len) = ty.kind() else { return Err(Unpromotable) }; + let Some(0) = len.try_to_target_usize(self.tcx) else { return Err(Unpromotable) }; } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 8d0a3ac94d5a..1c79a2fd65de 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -810,18 +810,16 @@ where pub(super) fn term_is_fully_unconstrained(&self, goal: Goal>) -> bool { let universe_of_term = match goal.predicate.term.kind() { ty::TermKind::Ty(ty) => { - if let ty::Infer(ty::TyVar(vid)) = ty.kind() { - self.delegate.universe_of_ty(vid).unwrap() - } else { + let ty::Infer(ty::TyVar(vid)) = ty.kind() else { return false; - } + }; + self.delegate.universe_of_ty(vid).unwrap() } ty::TermKind::Const(ct) => { - if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() { - self.delegate.universe_of_ct(vid).unwrap() - } else { + let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() else { return false; - } + }; + self.delegate.universe_of_ct(vid).unwrap() } }; diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index c65e0bb25897..70c28421c57e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -445,17 +445,15 @@ where goal_kind: ty::ClosureKind, ) -> Result, NoSolution> { let cx = ecx.cx(); - let tupled_inputs_and_output = - match structural_traits::extract_tupled_inputs_and_output_from_callable( + let Some(tupled_inputs_and_output) = + structural_traits::extract_tupled_inputs_and_output_from_callable( cx, goal.predicate.self_ty(), goal_kind, - )? { - Some(tupled_inputs_and_output) => tupled_inputs_and_output, - None => { - return ecx.forced_ambiguity(MaybeCause::Ambiguity); - } - }; + )? + else { + return ecx.forced_ambiguity(MaybeCause::Ambiguity); + }; let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output); // A built-in `Fn` impl only holds if the output is sized. diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 168921655a39..651f073efb82 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -360,17 +360,15 @@ where } let cx = ecx.cx(); - let tupled_inputs_and_output = - match structural_traits::extract_tupled_inputs_and_output_from_callable( + let Some(tupled_inputs_and_output) = + structural_traits::extract_tupled_inputs_and_output_from_callable( cx, goal.predicate.self_ty(), goal_kind, - )? { - Some(a) => a, - None => { - return ecx.forced_ambiguity(MaybeCause::Ambiguity); - } - }; + )? + else { + return ecx.forced_ambiguity(MaybeCause::Ambiguity); + }; let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output); // A built-in `Fn` impl only holds if the output is sized. @@ -1409,42 +1407,39 @@ where let where_bounds: Vec<_> = candidates .extract_if(.., |c| matches!(c.source, CandidateSource::ParamEnv(_))) .collect(); - if let Some((response, info)) = self.try_merge_candidates(&where_bounds) { - match info { - // If there's an always applicable candidate, the result of all - // other candidates does not matter. This means we can ignore - // them when checking whether we've reached a fixpoint. - // - // We always prefer the first always applicable candidate, even if a - // later candidate is also always applicable and would result in fewer - // reruns. We could slightly improve this by e.g. searching for another - // always applicable candidate which doesn't depend on any cycle heads. - // - // NOTE: This is optimization is observable in case there is an always - // applicable global candidate and another non-global candidate which only - // applies because of a provisional result. I can't even think of a test - // case where this would occur and even then, this would not be unsound. - // Supporting this makes the code more involved, so I am just going to - // ignore this for now. - MergeCandidateInfo::AlwaysApplicable(i) => { - for (j, c) in where_bounds.into_iter().enumerate() { - if i != j { - self.ignore_candidate_head_usages(c.head_usages) - } - } - // If a where-bound does not apply, we don't actually get a - // candidate for it. We manually track the head usages - // of all failed `ParamEnv` candidates instead. - self.ignore_candidate_head_usages( - failed_candidate_info.param_env_head_usages, - ); - } - MergeCandidateInfo::EqualResponse => {} - } - return Ok((response, Some(TraitGoalProvenVia::ParamEnv))); - } else { + let Some((response, info)) = self.try_merge_candidates(&where_bounds) else { return Ok((self.bail_with_ambiguity(&where_bounds), None)); }; + match info { + // If there's an always applicable candidate, the result of all + // other candidates does not matter. This means we can ignore + // them when checking whether we've reached a fixpoint. + // + // We always prefer the first always applicable candidate, even if a + // later candidate is also always applicable and would result in fewer + // reruns. We could slightly improve this by e.g. searching for another + // always applicable candidate which doesn't depend on any cycle heads. + // + // NOTE: This is optimization is observable in case there is an always + // applicable global candidate and another non-global candidate which only + // applies because of a provisional result. I can't even think of a test + // case where this would occur and even then, this would not be unsound. + // Supporting this makes the code more involved, so I am just going to + // ignore this for now. + MergeCandidateInfo::AlwaysApplicable(i) => { + for (j, c) in where_bounds.into_iter().enumerate() { + if i != j { + self.ignore_candidate_head_usages(c.head_usages) + } + } + // If a where-bound does not apply, we don't actually get a + // candidate for it. We manually track the head usages + // of all failed `ParamEnv` candidates instead. + self.ignore_candidate_head_usages(failed_candidate_info.param_env_head_usages); + } + MergeCandidateInfo::EqualResponse => {} + } + return Ok((response, Some(TraitGoalProvenVia::ParamEnv))); } // Next, prefer any alias bound (nested or otherwise). diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 069944b638c7..233a4c48862a 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1537,86 +1537,80 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { /// Given `where ::Baz: String`, suggest `where T: Bar`. fn restrict_assoc_type_in_where_clause(&self, span: Span, err: &mut Diag<'_>) -> bool { // Detect that we are actually in a `where` predicate. - let (bounded_ty, bounds, where_span) = if let Some(ast::WherePredicate { + let Some(ast::WherePredicate { kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { bounded_ty, bound_generic_params, bounds, }), - span, + span: where_span, .. }) = self.diag_metadata.current_where_predicate - { - if !bound_generic_params.is_empty() { - return false; - } - (bounded_ty, bounds, span) - } else { + else { return false; }; + if !bound_generic_params.is_empty() { + return false; + } // Confirm that the target is an associated type. - let (ty, _, path) = if let ast::TyKind::Path(Some(qself), path) = &bounded_ty.kind { - // use this to verify that ident is a type param. - let Some(partial_res) = self.r.partial_res_map.get(&bounded_ty.id) else { - return false; - }; - if !matches!( - partial_res.full_res(), - Some(hir::def::Res::Def(hir::def::DefKind::AssocTy, _)) - ) { - return false; - } - (&qself.ty, qself.position, path) - } else { + let ast::TyKind::Path(Some(qself), path) = &bounded_ty.kind else { return false }; + // use this to verify that ident is a type param. + let Some(partial_res) = self.r.partial_res_map.get(&bounded_ty.id) else { return false }; + if !matches!( + partial_res.full_res(), + Some(hir::def::Res::Def(hir::def::DefKind::AssocTy, _)) + ) { + return false; + } + + let peeled_ty = qself.ty.peel_refs(); + let ast::TyKind::Path(None, type_param_path) = &peeled_ty.kind else { return false }; + // Confirm that the `SelfTy` is a type parameter. + let Some(partial_res) = self.r.partial_res_map.get(&peeled_ty.id) else { return false; }; - - let peeled_ty = ty.peel_refs(); - if let ast::TyKind::Path(None, type_param_path) = &peeled_ty.kind { - // Confirm that the `SelfTy` is a type parameter. - let Some(partial_res) = self.r.partial_res_map.get(&peeled_ty.id) else { + if !matches!( + partial_res.full_res(), + Some(hir::def::Res::Def(hir::def::DefKind::TyParam, _)) + ) { + return false; + } + let ([ast::PathSegment { args: None, .. }], [ast::GenericBound::Trait(poly_trait_ref)]) = + (&type_param_path.segments[..], &bounds[..]) + else { + return false; + }; + let [ast::PathSegment { ident, args: None, id }] = + &poly_trait_ref.trait_ref.path.segments[..] + else { + return false; + }; + if poly_trait_ref.modifiers != ast::TraitBoundModifiers::NONE { + return false; + } + if ident.span == span { + let Some(partial_res) = self.r.partial_res_map.get(&id) else { return false; }; - if !matches!( - partial_res.full_res(), - Some(hir::def::Res::Def(hir::def::DefKind::TyParam, _)) - ) { + if !matches!(partial_res.full_res(), Some(hir::def::Res::Def(..))) { return false; } - if let ( - [ast::PathSegment { args: None, .. }], - [ast::GenericBound::Trait(poly_trait_ref)], - ) = (&type_param_path.segments[..], &bounds[..]) - && let [ast::PathSegment { ident, args: None, id }] = - &poly_trait_ref.trait_ref.path.segments[..] - && poly_trait_ref.modifiers == ast::TraitBoundModifiers::NONE - { - if ident.span == span { - let Some(partial_res) = self.r.partial_res_map.get(&id) else { - return false; - }; - if !matches!(partial_res.full_res(), Some(hir::def::Res::Def(..))) { - return false; - } - let Some(new_where_bound_predicate) = - mk_where_bound_predicate(path, poly_trait_ref, ty) - else { - return false; - }; - err.span_suggestion_verbose( - *where_span, - format!("constrain the associated type to `{ident}`"), - where_bound_predicate_to_string(&new_where_bound_predicate), - Applicability::MaybeIncorrect, - ); - } - return true; - } + let Some(new_where_bound_predicate) = + mk_where_bound_predicate(path, poly_trait_ref, &qself.ty) + else { + return false; + }; + err.span_suggestion_verbose( + *where_span, + format!("constrain the associated type to `{ident}`"), + where_bound_predicate_to_string(&new_where_bound_predicate), + Applicability::MaybeIncorrect, + ); } - false + true } /// Check if the source is call expression and the first argument is `self`. If true, From 824f41ea6f68d04bc3a01e02c1fb0150e3c5c6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Dec 2025 00:43:46 +0000 Subject: [PATCH 0691/3801] Use `let...else` instead of `match foo { ... _ => return };` and `if let ... else return` --- src/intrinsic/simd.rs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index c7ed887b30d0..39b4bb3ebefa 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -774,24 +774,23 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( return Err(()); }}; } - let (elem_ty_str, elem_ty, cast_type) = if let ty::Float(ref f) = *in_elem.kind() { - let elem_ty = bx.cx.type_float_from_ty(*f); - match f.bit_width() { - 16 => ("", elem_ty, Some(bx.cx.double_type)), - 32 => ("f", elem_ty, None), - 64 => ("", elem_ty, None), - _ => { - return_error!(InvalidMonomorphization::FloatingPointVector { - span, - name, - f_ty: *f, - in_ty - }); - } - } - } else { + let ty::Float(ref f) = *in_elem.kind() else { return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); }; + let elem_ty = bx.cx.type_float_from_ty(*f); + let (elem_ty_str, elem_ty, cast_type) = match f.bit_width() { + 16 => ("", elem_ty, Some(bx.cx.double_type)), + 32 => ("f", elem_ty, None), + 64 => ("", elem_ty, None), + _ => { + return_error!(InvalidMonomorphization::FloatingPointVector { + span, + name, + f_ty: *f, + in_ty + }); + } + }; let vec_ty = bx.cx.type_vector(elem_ty, in_len); From e3f9bcef746096612567eb200f0695eaee152fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Dec 2025 00:43:46 +0000 Subject: [PATCH 0692/3801] Use `let...else` instead of `match foo { ... _ => return };` and `if let ... else return` --- src/debuginfo/unwind.rs | 6 ++---- src/optimize/peephole.rs | 6 +----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index ecaf88a26259..33ffe4cc4e9c 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -130,11 +130,9 @@ impl UnwindContext { return; } - let unwind_info = if let Some(unwind_info) = + let Some(unwind_info) = context.compiled_code().unwrap().create_unwind_info(module.isa()).unwrap() - { - unwind_info - } else { + else { return; }; diff --git a/src/optimize/peephole.rs b/src/optimize/peephole.rs index c93fe9352103..f38c1f96e6ed 100644 --- a/src/optimize/peephole.rs +++ b/src/optimize/peephole.rs @@ -29,11 +29,7 @@ pub(crate) fn maybe_known_branch_taken( arg: Value, test_zero: bool, ) -> Option { - let arg_inst = if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) { - arg_inst - } else { - return None; - }; + let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) else { return None }; match bcx.func.dfg.insts[arg_inst] { InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => { From a49c17538009294569a4658d61283823ab6adea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Dec 2025 00:54:18 +0000 Subject: [PATCH 0693/3801] `#![deny(clippy::manual_let_else)]` in some rustc modules --- compiler/rustc_ast/src/lib.rs | 1 + compiler/rustc_borrowck/src/lib.rs | 1 + compiler/rustc_const_eval/src/lib.rs | 1 + compiler/rustc_hir/src/lib.rs | 1 + compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_hir_typeck/src/lib.rs | 1 + compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_next_trait_solver/src/lib.rs | 1 + compiler/rustc_resolve/src/lib.rs | 1 + 10 files changed, 10 insertions(+) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index cbdc89f9deed..10a8e181c840 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -6,6 +6,7 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(array_windows))] +#![deny(clippy::manual_let_else)] #![doc(test(attr(deny(warnings), allow(internal_features))))] #![feature(associated_type_defaults)] #![feature(box_patterns)] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8d61ffde116c..d82357fca2d4 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,6 +2,7 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 2fce4b8c0566..6c74ed2a5121 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,5 +1,6 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] +#![deny(clippy::manual_let_else)] #![feature(array_try_map)] #![feature(assert_matches)] #![feature(box_patterns)] diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 7a5776f0d5a9..c27954b6d14e 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -4,6 +4,7 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(debug_closure_helpers))] +#![deny(clippy::manual_let_else)] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] #![feature(const_default)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 538fb8c7df1e..79c5fbab1ffa 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -59,6 +59,7 @@ This API is completely unstable and subject to change. #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(bootstrap, feature(debug_closure_helpers))] +#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(gen_blocks)] #![feature(if_let_guard)] diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index d3ef1d63e8ba..9ca5ddd494ae 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -1,4 +1,5 @@ // tidy-alphabetical-start +#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 4e7a3e405176..49929a0a9bc7 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -22,6 +22,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![cfg_attr(bootstrap, feature(array_windows))] +#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 5f62d44df6b6..ee3e89e57bd4 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -30,6 +30,7 @@ #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(bootstrap, feature(array_windows))] +#![deny(clippy::manual_let_else)] #![feature(allocator_api)] #![feature(assert_matches)] #![feature(associated_type_defaults)] diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index 5fa29b7d9f81..117751810e29 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -8,6 +8,7 @@ #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::usage_of_type_ir_inherent)] #![allow(rustc::usage_of_type_ir_traits)] +#![deny(clippy::manual_let_else)] // tidy-alphabetical-end pub mod canonical; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 0b4ec6956bd1..38cf83dc23f7 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -10,6 +10,7 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![deny(clippy::manual_let_else)] #![feature(arbitrary_self_types)] #![feature(assert_matches)] #![feature(box_patterns)] From 97c774215165b7422c2e6e18e52fc5d63f8669ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 12 Dec 2025 17:55:26 +0000 Subject: [PATCH 0694/3801] revert one change from rustc_next_trait_solver --- compiler/rustc_next_trait_solver/src/lib.rs | 1 - .../src/solve/eval_ctxt/mod.rs | 14 ++++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index 117751810e29..5fa29b7d9f81 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -8,7 +8,6 @@ #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::usage_of_type_ir_inherent)] #![allow(rustc::usage_of_type_ir_traits)] -#![deny(clippy::manual_let_else)] // tidy-alphabetical-end pub mod canonical; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 1c79a2fd65de..8d0a3ac94d5a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -810,16 +810,18 @@ where pub(super) fn term_is_fully_unconstrained(&self, goal: Goal>) -> bool { let universe_of_term = match goal.predicate.term.kind() { ty::TermKind::Ty(ty) => { - let ty::Infer(ty::TyVar(vid)) = ty.kind() else { + if let ty::Infer(ty::TyVar(vid)) = ty.kind() { + self.delegate.universe_of_ty(vid).unwrap() + } else { return false; - }; - self.delegate.universe_of_ty(vid).unwrap() + } } ty::TermKind::Const(ct) => { - let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() else { + if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() { + self.delegate.universe_of_ct(vid).unwrap() + } else { return false; - }; - self.delegate.universe_of_ct(vid).unwrap() + } } }; From 395c6f56a3ed8d6e696dd86915f0272a62ec8e8e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 12 Dec 2025 19:14:52 +0100 Subject: [PATCH 0695/3801] README: add more papers to the paper list --- src/tools/miri/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 32494141589a..86f190134d45 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -651,6 +651,11 @@ Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows * [Stacked Borrows: An Aliasing Model for Rust](https://plv.mpi-sws.org/rustbelt/stacked-borrows/) * [Using Lightweight Formal Methods to Validate a Key-Value Storage Node in Amazon S3](https://www.amazon.science/publications/using-lightweight-formal-methods-to-validate-a-key-value-storage-node-in-amazon-s3) * [SyRust: Automatic Testing of Rust Libraries with Semantic-Aware Program Synthesis](https://dl.acm.org/doi/10.1145/3453483.3454084) +* [Crabtree: Rust API Test Synthesis Guided by Coverage and Type](https://dl.acm.org/doi/10.1145/3689733) +* [Rustlantis: Randomized Differential Testing of the Rust Compiler](https://dl.acm.org/doi/10.1145/3689780) +* [A Study of Undefined Behavior Across Foreign Function Boundaries in Rust Libraries](https://arxiv.org/abs/2404.11671) +* [Tree Borrows](https://plf.inf.ethz.ch/research/pldi25-tree-borrows.html) +* [Miri: Practical Undefined Behavior Detection for Rust](https://plf.inf.ethz.ch/research/popl26-miri.html) **(this paper describes Miri itself)** ## License From 860716faa38c09a4e119c06f030ab222252b6509 Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 19 Sep 2025 20:56:07 +0200 Subject: [PATCH 0696/3801] std: reorganize pipe implementations --- library/std/src/io/pipe.rs | 24 +-- library/std/src/os/unix/process.rs | 16 +- library/std/src/os/windows/process.rs | 6 +- library/std/src/process.rs | 51 +++-- library/std/src/sys/anonymous_pipe/motor.rs | 11 -- library/std/src/sys/anonymous_pipe/unix.rs | 11 -- .../std/src/sys/anonymous_pipe/unsupported.rs | 7 - library/std/src/sys/mod.rs | 2 +- library/std/src/sys/pal/hermit/mod.rs | 2 - library/std/src/sys/pal/motor/mod.rs | 1 - library/std/src/sys/pal/motor/pipe.rs | 121 ------------ library/std/src/sys/pal/sgx/mod.rs | 2 - library/std/src/sys/pal/solid/mod.rs | 2 - library/std/src/sys/pal/teeos/mod.rs | 2 - library/std/src/sys/pal/trusty/mod.rs | 2 - library/std/src/sys/pal/uefi/mod.rs | 2 - library/std/src/sys/pal/unix/mod.rs | 1 - library/std/src/sys/pal/unix/pipe.rs | 184 ------------------ library/std/src/sys/pal/unsupported/mod.rs | 1 - library/std/src/sys/pal/wasi/mod.rs | 2 - library/std/src/sys/pal/wasm/mod.rs | 2 - library/std/src/sys/pal/windows/mod.rs | 1 - library/std/src/sys/pal/xous/mod.rs | 2 - library/std/src/sys/pal/zkvm/mod.rs | 2 - .../src/sys/{anonymous_pipe => pipe}/mod.rs | 8 +- library/std/src/sys/pipe/motor.rs | 9 + library/std/src/sys/pipe/unix.rs | 44 +++++ .../pipe.rs => pipe/unsupported.rs} | 46 ++--- .../sys/{anonymous_pipe => pipe}/windows.rs | 4 +- library/std/src/sys/process/mod.rs | 7 +- library/std/src/sys/process/motor.rs | 36 +++- library/std/src/sys/process/uefi.rs | 16 +- library/std/src/sys/process/unix/common.rs | 70 +++++-- library/std/src/sys/process/unix/mod.rs | 2 +- library/std/src/sys/process/unix/unix.rs | 2 +- library/std/src/sys/process/unsupported.rs | 16 +- library/std/src/sys/process/windows.rs | 18 +- .../pipe.rs => process/windows/child_pipe.rs} | 72 +++---- library/std/src/sys/stdio/motor.rs | 6 +- 39 files changed, 296 insertions(+), 517 deletions(-) delete mode 100644 library/std/src/sys/anonymous_pipe/motor.rs delete mode 100644 library/std/src/sys/anonymous_pipe/unix.rs delete mode 100644 library/std/src/sys/anonymous_pipe/unsupported.rs delete mode 100644 library/std/src/sys/pal/motor/pipe.rs delete mode 100644 library/std/src/sys/pal/unix/pipe.rs rename library/std/src/sys/{anonymous_pipe => pipe}/mod.rs (57%) create mode 100644 library/std/src/sys/pipe/motor.rs create mode 100644 library/std/src/sys/pipe/unix.rs rename library/std/src/sys/{pal/unsupported/pipe.rs => pipe/unsupported.rs} (72%) rename library/std/src/sys/{anonymous_pipe => pipe}/windows.rs (85%) rename library/std/src/sys/{pal/windows/pipe.rs => process/windows/child_pipe.rs} (91%) diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs index 16727d445416..8457e7bceddc 100644 --- a/library/std/src/io/pipe.rs +++ b/library/std/src/io/pipe.rs @@ -1,5 +1,5 @@ use crate::io; -use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; +use crate::sys::pipe as imp; use crate::sys_common::{FromInner, IntoInner}; /// Creates an anonymous pipe. @@ -84,39 +84,39 @@ use crate::sys_common::{FromInner, IntoInner}; #[stable(feature = "anonymous_pipe", since = "1.87.0")] #[inline] pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> { - pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer))) + imp::pipe().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer))) } /// Read end of an anonymous pipe. #[stable(feature = "anonymous_pipe", since = "1.87.0")] #[derive(Debug)] -pub struct PipeReader(pub(crate) AnonPipe); +pub struct PipeReader(pub(crate) imp::Pipe); /// Write end of an anonymous pipe. #[stable(feature = "anonymous_pipe", since = "1.87.0")] #[derive(Debug)] -pub struct PipeWriter(pub(crate) AnonPipe); +pub struct PipeWriter(pub(crate) imp::Pipe); -impl FromInner for PipeReader { - fn from_inner(inner: AnonPipe) -> Self { +impl FromInner for PipeReader { + fn from_inner(inner: imp::Pipe) -> Self { Self(inner) } } -impl IntoInner for PipeReader { - fn into_inner(self) -> AnonPipe { +impl IntoInner for PipeReader { + fn into_inner(self) -> imp::Pipe { self.0 } } -impl FromInner for PipeWriter { - fn from_inner(inner: AnonPipe) -> Self { +impl FromInner for PipeWriter { + fn from_inner(inner: imp::Pipe) -> Self { Self(inner) } } -impl IntoInner for PipeWriter { - fn into_inner(self) -> AnonPipe { +impl IntoInner for PipeWriter { + fn into_inner(self) -> imp::Pipe { self.0 } } diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index ee0c460f7dfa..74b46d297571 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -8,6 +8,7 @@ use crate::ffi::OsStr; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::path::Path; use crate::sealed::Sealed; +use crate::sys::process::ChildPipe; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{io, process, sys}; @@ -511,7 +512,7 @@ impl From for OwnedFd { /// Takes ownership of a [`ChildStdin`](crate::process::ChildStdin)'s file descriptor. #[inline] fn from(child_stdin: crate::process::ChildStdin) -> OwnedFd { - child_stdin.into_inner().into_inner().into_inner() + child_stdin.into_inner().into_inner() } } @@ -523,8 +524,7 @@ impl From for OwnedFd { impl From for process::ChildStdin { #[inline] fn from(fd: OwnedFd) -> process::ChildStdin { - let fd = sys::fd::FileDesc::from_inner(fd); - let pipe = sys::pipe::AnonPipe::from_inner(fd); + let pipe = ChildPipe::from_inner(fd); process::ChildStdin::from_inner(pipe) } } @@ -542,7 +542,7 @@ impl From for OwnedFd { /// Takes ownership of a [`ChildStdout`](crate::process::ChildStdout)'s file descriptor. #[inline] fn from(child_stdout: crate::process::ChildStdout) -> OwnedFd { - child_stdout.into_inner().into_inner().into_inner() + child_stdout.into_inner().into_inner() } } @@ -554,8 +554,7 @@ impl From for OwnedFd { impl From for process::ChildStdout { #[inline] fn from(fd: OwnedFd) -> process::ChildStdout { - let fd = sys::fd::FileDesc::from_inner(fd); - let pipe = sys::pipe::AnonPipe::from_inner(fd); + let pipe = ChildPipe::from_inner(fd); process::ChildStdout::from_inner(pipe) } } @@ -573,7 +572,7 @@ impl From for OwnedFd { /// Takes ownership of a [`ChildStderr`](crate::process::ChildStderr)'s file descriptor. #[inline] fn from(child_stderr: crate::process::ChildStderr) -> OwnedFd { - child_stderr.into_inner().into_inner().into_inner() + child_stderr.into_inner().into_inner() } } @@ -585,8 +584,7 @@ impl From for OwnedFd { impl From for process::ChildStderr { #[inline] fn from(fd: OwnedFd) -> process::ChildStderr { - let fd = sys::fd::FileDesc::from_inner(fd); - let pipe = sys::pipe::AnonPipe::from_inner(fd); + let pipe = ChildPipe::from_inner(fd); process::ChildStderr::from_inner(pipe) } } diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index f21ed51606f6..b34b5d2802ca 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -117,7 +117,7 @@ impl IntoRawHandle for process::ChildStderr { impl From for process::ChildStdin { fn from(handle: OwnedHandle) -> process::ChildStdin { let handle = sys::handle::Handle::from_inner(handle); - let pipe = sys::pipe::AnonPipe::from_inner(handle); + let pipe = sys::process::ChildPipe::from_inner(handle); process::ChildStdin::from_inner(pipe) } } @@ -130,7 +130,7 @@ impl From for process::ChildStdin { impl From for process::ChildStdout { fn from(handle: OwnedHandle) -> process::ChildStdout { let handle = sys::handle::Handle::from_inner(handle); - let pipe = sys::pipe::AnonPipe::from_inner(handle); + let pipe = sys::process::ChildPipe::from_inner(handle); process::ChildStdout::from_inner(pipe) } } @@ -143,7 +143,7 @@ impl From for process::ChildStdout { impl From for process::ChildStderr { fn from(handle: OwnedHandle) -> process::ChildStderr { let handle = sys::handle::Handle::from_inner(handle); - let pipe = sys::pipe::AnonPipe::from_inner(handle); + let pipe = sys::process::ChildPipe::from_inner(handle); process::ChildStderr::from_inner(pipe) } } diff --git a/library/std/src/process.rs b/library/std/src/process.rs index dbcf2684c6fb..68bdf04d08b3 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -166,7 +166,6 @@ use crate::io::prelude::*; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::num::NonZero; use crate::path::Path; -use crate::sys::pipe::{AnonPipe, read2}; use crate::sys::process as imp; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{fmt, fs, str}; @@ -300,9 +299,9 @@ impl fmt::Debug for Child { /// /// Used to pass pipe handles between this module and [`imp`]. pub(crate) struct StdioPipes { - pub stdin: Option, - pub stdout: Option, - pub stderr: Option, + pub stdin: Option, + pub stdout: Option, + pub stderr: Option, } /// A handle to a child process's standard input (stdin). @@ -317,7 +316,7 @@ pub(crate) struct StdioPipes { /// [dropped]: Drop #[stable(feature = "process", since = "1.0.0")] pub struct ChildStdin { - inner: AnonPipe, + inner: imp::ChildPipe, } // In addition to the `impl`s here, `ChildStdin` also has `impl`s for @@ -366,21 +365,21 @@ impl Write for &ChildStdin { } } -impl AsInner for ChildStdin { +impl AsInner for ChildStdin { #[inline] - fn as_inner(&self) -> &AnonPipe { + fn as_inner(&self) -> &imp::ChildPipe { &self.inner } } -impl IntoInner for ChildStdin { - fn into_inner(self) -> AnonPipe { +impl IntoInner for ChildStdin { + fn into_inner(self) -> imp::ChildPipe { self.inner } } -impl FromInner for ChildStdin { - fn from_inner(pipe: AnonPipe) -> ChildStdin { +impl FromInner for ChildStdin { + fn from_inner(pipe: imp::ChildPipe) -> ChildStdin { ChildStdin { inner: pipe } } } @@ -403,7 +402,7 @@ impl fmt::Debug for ChildStdin { /// [dropped]: Drop #[stable(feature = "process", since = "1.0.0")] pub struct ChildStdout { - inner: AnonPipe, + inner: imp::ChildPipe, } // In addition to the `impl`s here, `ChildStdout` also has `impl`s for @@ -436,21 +435,21 @@ impl Read for ChildStdout { } } -impl AsInner for ChildStdout { +impl AsInner for ChildStdout { #[inline] - fn as_inner(&self) -> &AnonPipe { + fn as_inner(&self) -> &imp::ChildPipe { &self.inner } } -impl IntoInner for ChildStdout { - fn into_inner(self) -> AnonPipe { +impl IntoInner for ChildStdout { + fn into_inner(self) -> imp::ChildPipe { self.inner } } -impl FromInner for ChildStdout { - fn from_inner(pipe: AnonPipe) -> ChildStdout { +impl FromInner for ChildStdout { + fn from_inner(pipe: imp::ChildPipe) -> ChildStdout { ChildStdout { inner: pipe } } } @@ -473,7 +472,7 @@ impl fmt::Debug for ChildStdout { /// [dropped]: Drop #[stable(feature = "process", since = "1.0.0")] pub struct ChildStderr { - inner: AnonPipe, + inner: imp::ChildPipe, } // In addition to the `impl`s here, `ChildStderr` also has `impl`s for @@ -506,21 +505,21 @@ impl Read for ChildStderr { } } -impl AsInner for ChildStderr { +impl AsInner for ChildStderr { #[inline] - fn as_inner(&self) -> &AnonPipe { + fn as_inner(&self) -> &imp::ChildPipe { &self.inner } } -impl IntoInner for ChildStderr { - fn into_inner(self) -> AnonPipe { +impl IntoInner for ChildStderr { + fn into_inner(self) -> imp::ChildPipe { self.inner } } -impl FromInner for ChildStderr { - fn from_inner(pipe: AnonPipe) -> ChildStderr { +impl FromInner for ChildStderr { + fn from_inner(pipe: imp::ChildPipe) -> ChildStderr { ChildStderr { inner: pipe } } } @@ -2380,7 +2379,7 @@ impl Child { res.unwrap(); } (Some(out), Some(err)) => { - let res = read2(out.inner, &mut stdout, err.inner, &mut stderr); + let res = imp::read_output(out.inner, &mut stdout, err.inner, &mut stderr); res.unwrap(); } } diff --git a/library/std/src/sys/anonymous_pipe/motor.rs b/library/std/src/sys/anonymous_pipe/motor.rs deleted file mode 100644 index dfe10f7fafe4..000000000000 --- a/library/std/src/sys/anonymous_pipe/motor.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::io; -use crate::sys::fd::FileDesc; -use crate::sys::pipe::anon_pipe; -use crate::sys_common::IntoInner; - -pub type AnonPipe = FileDesc; - -#[inline] -pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> { - anon_pipe().map(|(rx, wx)| (rx.into_inner(), wx.into_inner())) -} diff --git a/library/std/src/sys/anonymous_pipe/unix.rs b/library/std/src/sys/anonymous_pipe/unix.rs deleted file mode 100644 index dfe10f7fafe4..000000000000 --- a/library/std/src/sys/anonymous_pipe/unix.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::io; -use crate::sys::fd::FileDesc; -use crate::sys::pipe::anon_pipe; -use crate::sys_common::IntoInner; - -pub type AnonPipe = FileDesc; - -#[inline] -pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> { - anon_pipe().map(|(rx, wx)| (rx.into_inner(), wx.into_inner())) -} diff --git a/library/std/src/sys/anonymous_pipe/unsupported.rs b/library/std/src/sys/anonymous_pipe/unsupported.rs deleted file mode 100644 index a0805ba9540e..000000000000 --- a/library/std/src/sys/anonymous_pipe/unsupported.rs +++ /dev/null @@ -1,7 +0,0 @@ -use crate::io; -pub use crate::sys::pipe::AnonPipe; - -#[inline] -pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> { - Err(io::Error::UNSUPPORTED_PLATFORM) -} diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 2dbdc8a4e026..3c44543bce32 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -13,7 +13,6 @@ mod pal; mod alloc; mod personality; -pub mod anonymous_pipe; pub mod args; pub mod backtrace; pub mod cmath; @@ -26,6 +25,7 @@ pub mod io; pub mod net; pub mod os_str; pub mod path; +pub mod pipe; pub mod platform_version; pub mod process; pub mod random; diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index 3ddf6e5acb02..52bcd8da2420 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -23,8 +23,6 @@ use crate::sys::env; pub mod futex; pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; pub mod time; pub fn unsupported() -> crate::io::Result { diff --git a/library/std/src/sys/pal/motor/mod.rs b/library/std/src/sys/pal/motor/mod.rs index 32f95df6ad08..9bca264d78ea 100644 --- a/library/std/src/sys/pal/motor/mod.rs +++ b/library/std/src/sys/pal/motor/mod.rs @@ -1,7 +1,6 @@ #![allow(unsafe_op_in_unsafe_fn)] pub mod os; -pub mod pipe; pub mod time; pub use moto_rt::futex; diff --git a/library/std/src/sys/pal/motor/pipe.rs b/library/std/src/sys/pal/motor/pipe.rs deleted file mode 100644 index d3be6ddf1573..000000000000 --- a/library/std/src/sys/pal/motor/pipe.rs +++ /dev/null @@ -1,121 +0,0 @@ -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::sys::fd::FileDesc; -use crate::sys::map_motor_error; -use crate::sys_common::{FromInner, IntoInner}; - -#[derive(Debug)] -pub struct AnonPipe(FileDesc); - -impl From for AnonPipe { - fn from(rt_fd: moto_rt::RtFd) -> AnonPipe { - unsafe { AnonPipe::from_raw_fd(rt_fd) } - } -} - -impl AnonPipe { - pub fn read(&self, buf: &mut [u8]) -> io::Result { - moto_rt::fs::read(self.as_raw_fd(), buf).map_err(map_motor_error) - } - - pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { - crate::io::default_read_buf(|buf| self.read(buf), cursor) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - crate::io::default_read_vectored(|b| self.read(b), bufs) - } - - pub fn is_read_vectored(&self) -> bool { - false - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - moto_rt::fs::write(self.as_raw_fd(), buf).map_err(map_motor_error) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - crate::io::default_write_vectored(|b| self.write(b), bufs) - } - - pub fn is_write_vectored(&self) -> bool { - false - } - - pub fn read_to_end(&self, buf: &mut Vec) -> io::Result { - let mut temp_vec = Vec::new(); - let mut size = 0_usize; - loop { - temp_vec.resize(256, 0_u8); - match self.read(&mut temp_vec[..]) { - Ok(sz) => { - if sz == 0 { - return Ok(size); - } - size += sz; - temp_vec.truncate(sz); - buf.append(&mut temp_vec); - } - Err(err) => { - if size != 0 { - return Ok(size); - } else { - return Err(err); - } - } - } - } - } -} - -impl AsRawFd for AnonPipe { - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl FromRawFd for AnonPipe { - unsafe fn from_raw_fd(fd: RawFd) -> Self { - let desc = FileDesc::from_raw_fd(fd); - Self(desc) - } -} - -impl IntoRawFd for AnonPipe { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} - -impl AsFd for AnonPipe { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl IntoInner for AnonPipe { - fn into_inner(self) -> OwnedFd { - self.0.into_inner() - } -} - -impl IntoInner for AnonPipe { - fn into_inner(self) -> FileDesc { - self.0 - } -} - -impl FromInner for AnonPipe { - fn from_inner(owned_fd: OwnedFd) -> Self { - Self(FileDesc::from_inner(owned_fd)) - } -} - -pub fn read2(_p1: AnonPipe, _v1: &mut Vec, _p2: AnonPipe, _v2: &mut Vec) -> io::Result<()> { - Err(io::Error::from_raw_os_error(moto_rt::E_NOT_IMPLEMENTED.into())) -} - -#[inline] -pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { - Err(io::Error::UNSUPPORTED_PLATFORM) -} diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 9a33873af581..5d57be59aadf 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -11,8 +11,6 @@ use crate::sync::atomic::{Atomic, AtomicBool, Ordering}; pub mod abi; mod libunwind_integration; pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; pub mod thread_parking; pub mod time; pub mod waitqueue; diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index 9ca6dc581183..33df9116f5c2 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -18,8 +18,6 @@ pub mod itron { // `crate::sys::error` pub(crate) mod error; pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; pub use self::itron::thread_parking; pub mod time; diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index dd0155265da6..fe2dd9c6c493 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -7,8 +7,6 @@ #![allow(dead_code)] pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; #[allow(non_upper_case_globals)] #[path = "../unix/time.rs"] pub mod time; diff --git a/library/std/src/sys/pal/trusty/mod.rs b/library/std/src/sys/pal/trusty/mod.rs index cf0c098f8a2f..76a3a75b10c1 100644 --- a/library/std/src/sys/pal/trusty/mod.rs +++ b/library/std/src/sys/pal/trusty/mod.rs @@ -5,8 +5,6 @@ mod common; #[path = "../unsupported/os.rs"] pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; #[path = "../unsupported/time.rs"] pub mod time; diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index ebd311db1e12..e8236437b9c9 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -15,8 +15,6 @@ pub mod helpers; pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; pub mod time; #[cfg(test)] diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 81533d593131..a6c5decf2d34 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -8,7 +8,6 @@ pub mod futex; #[cfg(target_os = "linux")] pub mod linux; pub mod os; -pub mod pipe; pub mod stack_overflow; pub mod sync; pub mod thread_parking; diff --git a/library/std/src/sys/pal/unix/pipe.rs b/library/std/src/sys/pal/unix/pipe.rs deleted file mode 100644 index 4798acf9dad6..000000000000 --- a/library/std/src/sys/pal/unix/pipe.rs +++ /dev/null @@ -1,184 +0,0 @@ -use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::mem; -use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; -use crate::sys::fd::FileDesc; -use crate::sys::{cvt, cvt_r}; -use crate::sys_common::{FromInner, IntoInner}; - -//////////////////////////////////////////////////////////////////////////////// -// Anonymous pipes -//////////////////////////////////////////////////////////////////////////////// - -#[derive(Debug)] -pub struct AnonPipe(FileDesc); - -pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { - let mut fds = [0; 2]; - - // The only known way right now to create atomically set the CLOEXEC flag is - // to use the `pipe2` syscall. This was added to Linux in 2.6.27, glibc 2.9 - // and musl 0.9.3, and some other targets also have it. - cfg_select! { - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "hurd", - target_os = "illumos", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "cygwin", - target_os = "redox" - ) => { - unsafe { - cvt(libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC))?; - Ok((AnonPipe(FileDesc::from_raw_fd(fds[0])), AnonPipe(FileDesc::from_raw_fd(fds[1])))) - } - } - _ => { - unsafe { - cvt(libc::pipe(fds.as_mut_ptr()))?; - - let fd0 = FileDesc::from_raw_fd(fds[0]); - let fd1 = FileDesc::from_raw_fd(fds[1]); - fd0.set_cloexec()?; - fd1.set_cloexec()?; - Ok((AnonPipe(fd0), AnonPipe(fd1))) - } - } - } -} - -impl AnonPipe { - #[allow(dead_code)] - // FIXME: This function seems legitimately unused. - pub fn try_clone(&self) -> io::Result { - self.0.duplicate().map(Self) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.0.read_buf(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - self.0.read_vectored(bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - self.0.is_read_vectored() - } - - pub fn read_to_end(&self, buf: &mut Vec) -> io::Result { - self.0.read_to_end(buf) - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - self.0.write_vectored(bufs) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - self.0.is_write_vectored() - } - - #[allow(dead_code)] - // FIXME: This function seems legitimately unused. - pub fn as_file_desc(&self) -> &FileDesc { - &self.0 - } -} - -impl IntoInner for AnonPipe { - fn into_inner(self) -> FileDesc { - self.0 - } -} - -pub fn read2(p1: AnonPipe, v1: &mut Vec, p2: AnonPipe, v2: &mut Vec) -> io::Result<()> { - // Set both pipes into nonblocking mode as we're gonna be reading from both - // in the `select` loop below, and we wouldn't want one to block the other! - let p1 = p1.into_inner(); - let p2 = p2.into_inner(); - p1.set_nonblocking(true)?; - p2.set_nonblocking(true)?; - - let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() }; - fds[0].fd = p1.as_raw_fd(); - fds[0].events = libc::POLLIN; - fds[1].fd = p2.as_raw_fd(); - fds[1].events = libc::POLLIN; - loop { - // wait for either pipe to become readable using `poll` - cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?; - - if fds[0].revents != 0 && read(&p1, v1)? { - p2.set_nonblocking(false)?; - return p2.read_to_end(v2).map(drop); - } - if fds[1].revents != 0 && read(&p2, v2)? { - p1.set_nonblocking(false)?; - return p1.read_to_end(v1).map(drop); - } - } - - // Read as much as we can from each pipe, ignoring EWOULDBLOCK or - // EAGAIN. If we hit EOF, then this will happen because the underlying - // reader will return Ok(0), in which case we'll see `Ok` ourselves. In - // this case we flip the other fd back into blocking mode and read - // whatever's leftover on that file descriptor. - fn read(fd: &FileDesc, dst: &mut Vec) -> Result { - match fd.read_to_end(dst) { - Ok(_) => Ok(true), - Err(e) => { - if e.raw_os_error() == Some(libc::EWOULDBLOCK) - || e.raw_os_error() == Some(libc::EAGAIN) - { - Ok(false) - } else { - Err(e) - } - } - } - } -} - -impl AsRawFd for AnonPipe { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl AsFd for AnonPipe { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl IntoRawFd for AnonPipe { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} - -impl FromRawFd for AnonPipe { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self(FromRawFd::from_raw_fd(raw_fd)) - } -} - -impl FromInner for AnonPipe { - fn from_inner(fd: FileDesc) -> Self { - Self(fd) - } -} diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs index e64bbc7c6169..c33d2e5fb02a 100644 --- a/library/std/src/sys/pal/unsupported/mod.rs +++ b/library/std/src/sys/pal/unsupported/mod.rs @@ -1,7 +1,6 @@ #![deny(unsafe_op_in_unsafe_fn)] pub mod os; -pub mod pipe; pub mod time; mod common; diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index 42629a91e1af..5d36687df097 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -9,8 +9,6 @@ pub mod futex; pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; pub mod stack_overflow; #[path = "../unix/time.rs"] pub mod time; diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs index a20cd0e9ac77..80429a9aae18 100644 --- a/library/std/src/sys/pal/wasm/mod.rs +++ b/library/std/src/sys/pal/wasm/mod.rs @@ -18,8 +18,6 @@ #[path = "../unsupported/os.rs"] pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; #[path = "../unsupported/time.rs"] pub mod time; diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index a5f060080130..32bd6ea3a4f6 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -19,7 +19,6 @@ pub mod c; pub mod futex; pub mod handle; pub mod os; -pub mod pipe; pub mod time; cfg_select! { // We don't care about printing nice error messages for panic=immediate-abort diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs index e673157e0eb5..077cff1ee0f2 100644 --- a/library/std/src/sys/pal/xous/mod.rs +++ b/library/std/src/sys/pal/xous/mod.rs @@ -3,8 +3,6 @@ use crate::os::xous::ffi::exit; pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; pub mod time; #[path = "../unsupported/common.rs"] diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 9069c8d12fa1..6dece1055a08 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -12,8 +12,6 @@ pub const WORD_SIZE: usize = size_of::(); pub mod abi; pub mod os; -#[path = "../unsupported/pipe.rs"] -pub mod pipe; #[path = "../unsupported/time.rs"] pub mod time; diff --git a/library/std/src/sys/anonymous_pipe/mod.rs b/library/std/src/sys/pipe/mod.rs similarity index 57% rename from library/std/src/sys/anonymous_pipe/mod.rs rename to library/std/src/sys/pipe/mod.rs index 64b2c014b54f..85228963b4ad 100644 --- a/library/std/src/sys/anonymous_pipe/mod.rs +++ b/library/std/src/sys/pipe/mod.rs @@ -3,18 +3,18 @@ cfg_select! { unix => { mod unix; - pub use unix::{AnonPipe, pipe}; + pub use unix::{Pipe, pipe}; } windows => { mod windows; - pub use windows::{AnonPipe, pipe}; + pub use windows::{Pipe, pipe}; } target_os = "motor" => { mod motor; - pub use motor::{AnonPipe, pipe}; + pub use motor::{Pipe, pipe}; } _ => { mod unsupported; - pub use unsupported::{AnonPipe, pipe}; + pub use unsupported::{Pipe, pipe}; } } diff --git a/library/std/src/sys/pipe/motor.rs b/library/std/src/sys/pipe/motor.rs new file mode 100644 index 000000000000..50787c580133 --- /dev/null +++ b/library/std/src/sys/pipe/motor.rs @@ -0,0 +1,9 @@ +use crate::io; +use crate::sys::fd::FileDesc; + +pub type Pipe = FileDesc; + +#[inline] +pub fn pipe() -> io::Result<(Pipe, Pipe)> { + Err(io::Error::UNSUPPORTED_PLATFORM) +} diff --git a/library/std/src/sys/pipe/unix.rs b/library/std/src/sys/pipe/unix.rs new file mode 100644 index 000000000000..bb97e806a040 --- /dev/null +++ b/library/std/src/sys/pipe/unix.rs @@ -0,0 +1,44 @@ +use crate::io; +use crate::os::fd::FromRawFd; +use crate::sys::fd::FileDesc; +use crate::sys::pal::cvt; + +pub type Pipe = FileDesc; + +pub fn pipe() -> io::Result<(Pipe, Pipe)> { + let mut fds = [0; 2]; + + // The only known way right now to create atomically set the CLOEXEC flag is + // to use the `pipe2` syscall. This was added to Linux in 2.6.27, glibc 2.9 + // and musl 0.9.3, and some other targets also have it. + cfg_select! { + any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "hurd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "cygwin", + target_os = "redox" + ) => { + unsafe { + cvt(libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC))?; + Ok((Pipe::from_raw_fd(fds[0]), Pipe::from_raw_fd(fds[1]))) + } + } + _ => { + unsafe { + cvt(libc::pipe(fds.as_mut_ptr()))?; + + let fd0 = Pipe::from_raw_fd(fds[0]); + let fd1 = Pipe::from_raw_fd(fds[1]); + fd0.set_cloexec()?; + fd1.set_cloexec()?; + Ok((fd0, fd1)) + } + } + } +} diff --git a/library/std/src/sys/pal/unsupported/pipe.rs b/library/std/src/sys/pipe/unsupported.rs similarity index 72% rename from library/std/src/sys/pal/unsupported/pipe.rs rename to library/std/src/sys/pipe/unsupported.rs index 988e551de522..115e913e0f33 100644 --- a/library/std/src/sys/pal/unsupported/pipe.rs +++ b/library/std/src/sys/pipe/unsupported.rs @@ -1,16 +1,14 @@ use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::sys_common::{FromInner, IntoInner}; -pub struct AnonPipe(!); +pub struct Pipe(!); -impl fmt::Debug for AnonPipe { - fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 - } +#[inline] +pub fn pipe() -> io::Result<(Pipe, Pipe)> { + Err(io::Error::UNSUPPORTED_PLATFORM) } -impl AnonPipe { +impl Pipe { pub fn try_clone(&self) -> io::Result { self.0 } @@ -52,56 +50,52 @@ impl AnonPipe { } } -pub fn read2(p1: AnonPipe, _v1: &mut Vec, _p2: AnonPipe, _v2: &mut Vec) -> io::Result<()> { - match p1.0 {} -} - -impl FromInner for AnonPipe { - fn from_inner(inner: !) -> Self { - inner - } -} - -impl IntoInner for AnonPipe { - fn into_inner(self) -> ! { +impl fmt::Debug for Pipe { + fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { self.0 } } #[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] mod unix_traits { - use super::AnonPipe; + use super::Pipe; use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; - use crate::sys_common::FromInner; + use crate::sys_common::{FromInner, IntoInner}; - impl AsRawFd for AnonPipe { + impl AsRawFd for Pipe { #[inline] fn as_raw_fd(&self) -> RawFd { self.0 } } - impl AsFd for AnonPipe { + impl AsFd for Pipe { fn as_fd(&self) -> BorrowedFd<'_> { self.0 } } - impl IntoRawFd for AnonPipe { + impl IntoRawFd for Pipe { fn into_raw_fd(self) -> RawFd { self.0 } } - impl FromRawFd for AnonPipe { + impl FromRawFd for Pipe { unsafe fn from_raw_fd(_: RawFd) -> Self { panic!("creating pipe on this platform is unsupported!") } } - impl FromInner for AnonPipe { + impl FromInner for Pipe { fn from_inner(_: OwnedFd) -> Self { panic!("creating pipe on this platform is unsupported!") } } + + impl IntoInner for Pipe { + fn into_inner(self) -> OwnedFd { + self.0 + } + } } diff --git a/library/std/src/sys/anonymous_pipe/windows.rs b/library/std/src/sys/pipe/windows.rs similarity index 85% rename from library/std/src/sys/anonymous_pipe/windows.rs rename to library/std/src/sys/pipe/windows.rs index bdda7ffc5d25..5bd90b43d742 100644 --- a/library/std/src/sys/anonymous_pipe/windows.rs +++ b/library/std/src/sys/pipe/windows.rs @@ -3,9 +3,9 @@ use crate::sys::c; use crate::sys::handle::Handle; use crate::{io, ptr}; -pub type AnonPipe = Handle; +pub type Pipe = Handle; -pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> { +pub fn pipe() -> io::Result<(Pipe, Pipe)> { let mut read_pipe = c::INVALID_HANDLE_VALUE; let mut write_pipe = c::INVALID_HANDLE_VALUE; diff --git a/library/std/src/sys/process/mod.rs b/library/std/src/sys/process/mod.rs index 92e459298fc4..121d3bc9d5c3 100644 --- a/library/std/src/sys/process/mod.rs +++ b/library/std/src/sys/process/mod.rs @@ -28,7 +28,8 @@ mod env; pub use env::CommandEnvs; pub use imp::{ - Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio, + ChildPipe, Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio, + read_output, }; #[cfg(any( @@ -45,8 +46,6 @@ pub use imp::{ target_os = "motor" ))] pub fn output(cmd: &mut Command) -> crate::io::Result<(ExitStatus, Vec, Vec)> { - use crate::sys::pipe::read2; - let (mut process, mut pipes) = cmd.spawn(Stdio::MakePipe, false)?; drop(pipes.stdin.take()); @@ -62,7 +61,7 @@ pub fn output(cmd: &mut Command) -> crate::io::Result<(ExitStatus, Vec, Vec< res.unwrap(); } (Some(out), Some(err)) => { - let res = read2(out, &mut stdout, err, &mut stderr); + let res = read_output(out, &mut stdout, err, &mut stderr); res.unwrap(); } } diff --git a/library/std/src/sys/process/motor.rs b/library/std/src/sys/process/motor.rs index 949a9d494290..7a23a5d902c0 100644 --- a/library/std/src/sys/process/motor.rs +++ b/library/std/src/sys/process/motor.rs @@ -9,7 +9,6 @@ use crate::path::Path; use crate::process::StdioPipes; use crate::sys::fs::File; use crate::sys::map_motor_error; -use crate::sys::pipe::AnonPipe; use crate::sys_common::{AsInner, FromInner}; use crate::{fmt, io}; @@ -150,20 +149,26 @@ impl Command { Ok(( Process { handle }, StdioPipes { - stdin: if stdin >= 0 { Some(stdin.into()) } else { None }, - stdout: if stdout >= 0 { Some(stdout.into()) } else { None }, - stderr: if stderr >= 0 { Some(stderr.into()) } else { None }, + stdin: if stdin >= 0 { + Some(unsafe { ChildPipe::from_raw_fd(stdin) }) + } else { + None + }, + stdout: if stdout >= 0 { + Some(unsafe { ChildPipe::from_raw_fd(stdout) }) + } else { + None + }, + stderr: if stderr >= 0 { + Some(unsafe { ChildPipe::from_raw_fd(stderr) }) + } else { + None + }, }, )) } } -impl From for Stdio { - fn from(pipe: AnonPipe) -> Stdio { - unsafe { Stdio::Fd(crate::sys::fd::FileDesc::from_raw_fd(pipe.into_raw_fd())) } - } -} - impl From for Stdio { fn from(fd: crate::sys::fd::FileDesc) -> Stdio { Stdio::Fd(fd) @@ -315,3 +320,14 @@ impl<'a> fmt::Debug for CommandArgs<'a> { f.debug_list().entries(self.iter.clone()).finish() } } + +pub type ChildPipe = crate::sys::pipe::Pipe; + +pub fn read_output( + _out: ChildPipe, + _stdout: &mut Vec, + _err: ChildPipe, + _stderr: &mut Vec, +) -> io::Result<()> { + Err(io::Error::from_raw_os_error(moto_rt::E_NOT_IMPLEMENTED.into())) +} diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index 8d44292611bc..0e10bc02a0b9 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -10,7 +10,6 @@ use crate::process::StdioPipes; use crate::sys::fs::File; use crate::sys::pal::helpers; use crate::sys::pal::os::error_string; -use crate::sys::pipe::AnonPipe; use crate::sys::unsupported; use crate::{fmt, io}; @@ -204,8 +203,8 @@ pub fn output(command: &mut Command) -> io::Result<(ExitStatus, Vec, Vec Ok((ExitStatus(stat), stdout, stderr)) } -impl From for Stdio { - fn from(pipe: AnonPipe) -> Stdio { +impl From for Stdio { + fn from(pipe: ChildPipe) -> Stdio { pipe.diverge() } } @@ -356,6 +355,17 @@ impl<'a> fmt::Debug for CommandArgs<'a> { } } +pub type ChildPipe = crate::sys::pipe::Pipe; + +pub fn read_output( + out: ChildPipe, + _stdout: &mut Vec, + _err: ChildPipe, + _stderr: &mut Vec, +) -> io::Result<()> { + match out.diverge() {} +} + #[allow(dead_code)] mod uefi_command_internal { use r_efi::protocols::{loaded_image, simple_text_input, simple_text_output}; diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index 44d54aaf5151..d4344d1191a4 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -10,14 +10,15 @@ use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::os::unix::prelude::*; use crate::path::Path; use crate::process::StdioPipes; +use crate::sys::cvt_r; use crate::sys::fd::FileDesc; use crate::sys::fs::File; #[cfg(not(target_os = "fuchsia"))] use crate::sys::fs::OpenOptions; -use crate::sys::pipe::{self, AnonPipe}; +use crate::sys::pipe::pipe; use crate::sys::process::env::{CommandEnv, CommandEnvs}; use crate::sys_common::{FromInner, IntoInner}; -use crate::{fmt, io}; +use crate::{fmt, io, mem}; mod cstring_array; @@ -393,7 +394,7 @@ fn construct_envp(env: BTreeMap, saw_nul: &mut bool) -> CStr } impl Stdio { - pub fn to_child_stdio(&self, readable: bool) -> io::Result<(ChildStdio, Option)> { + pub fn to_child_stdio(&self, readable: bool) -> io::Result<(ChildStdio, Option)> { match *self { Stdio::Inherit => Ok((ChildStdio::Inherit, None)), @@ -418,9 +419,9 @@ impl Stdio { } Stdio::MakePipe => { - let (reader, writer) = pipe::anon_pipe()?; + let (reader, writer) = pipe()?; let (ours, theirs) = if readable { (writer, reader) } else { (reader, writer) }; - Ok((ChildStdio::Owned(theirs.into_inner()), Some(ours))) + Ok((ChildStdio::Owned(theirs), Some(ours))) } #[cfg(not(target_os = "fuchsia"))] @@ -438,12 +439,6 @@ impl Stdio { } } -impl From for Stdio { - fn from(pipe: AnonPipe) -> Stdio { - Stdio::Fd(pipe.into_inner()) - } -} - impl From for Stdio { fn from(fd: FileDesc) -> Stdio { Stdio::Fd(fd) @@ -632,3 +627,56 @@ impl<'a> fmt::Debug for CommandArgs<'a> { f.debug_list().entries(self.iter.clone()).finish() } } + +pub type ChildPipe = crate::sys::pipe::Pipe; + +pub fn read_output( + out: ChildPipe, + stdout: &mut Vec, + err: ChildPipe, + stderr: &mut Vec, +) -> io::Result<()> { + // Set both pipes into nonblocking mode as we're gonna be reading from both + // in the `select` loop below, and we wouldn't want one to block the other! + out.set_nonblocking(true)?; + err.set_nonblocking(true)?; + + let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() }; + fds[0].fd = out.as_raw_fd(); + fds[0].events = libc::POLLIN; + fds[1].fd = err.as_raw_fd(); + fds[1].events = libc::POLLIN; + loop { + // wait for either pipe to become readable using `poll` + cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?; + + if fds[0].revents != 0 && read(&out, stdout)? { + err.set_nonblocking(false)?; + return err.read_to_end(stderr).map(drop); + } + if fds[1].revents != 0 && read(&err, stderr)? { + out.set_nonblocking(false)?; + return out.read_to_end(stdout).map(drop); + } + } + + // Read as much as we can from each pipe, ignoring EWOULDBLOCK or + // EAGAIN. If we hit EOF, then this will happen because the underlying + // reader will return Ok(0), in which case we'll see `Ok` ourselves. In + // this case we flip the other fd back into blocking mode and read + // whatever's leftover on that file descriptor. + fn read(fd: &FileDesc, dst: &mut Vec) -> Result { + match fd.read_to_end(dst) { + Ok(_) => Ok(true), + Err(e) => { + if e.raw_os_error() == Some(libc::EWOULDBLOCK) + || e.raw_os_error() == Some(libc::EAGAIN) + { + Ok(false) + } else { + Err(e) + } + } + } + } +} diff --git a/library/std/src/sys/process/unix/mod.rs b/library/std/src/sys/process/unix/mod.rs index cda1bf74f1ca..1938e8f4b737 100644 --- a/library/std/src/sys/process/unix/mod.rs +++ b/library/std/src/sys/process/unix/mod.rs @@ -23,5 +23,5 @@ cfg_select! { pub use imp::{ExitStatus, ExitStatusError, Process}; -pub use self::common::{Command, CommandArgs, ExitCode, Stdio}; +pub use self::common::{ChildPipe, Command, CommandArgs, ExitCode, Stdio, read_output}; pub use crate::ffi::OsString as EnvKey; diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 7d944f2f7eef..d14caf6dc88d 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -78,7 +78,7 @@ impl Command { let (input, output) = sys::net::Socket::new_pair(libc::AF_UNIX, libc::SOCK_SEQPACKET)?; #[cfg(not(target_os = "linux"))] - let (input, output) = sys::pipe::anon_pipe()?; + let (input, output) = sys::pipe::pipe()?; // Whatever happens after the fork is almost for sure going to touch or // look at the environment in one way or another (PATH in `execvp` or diff --git a/library/std/src/sys/process/unsupported.rs b/library/std/src/sys/process/unsupported.rs index 2dfc676ec005..455c38e55b7b 100644 --- a/library/std/src/sys/process/unsupported.rs +++ b/library/std/src/sys/process/unsupported.rs @@ -5,7 +5,6 @@ use crate::num::NonZero; use crate::path::Path; use crate::process::StdioPipes; use crate::sys::fs::File; -use crate::sys::pipe::AnonPipe; use crate::sys::unsupported; use crate::{fmt, io}; @@ -107,8 +106,8 @@ pub fn output(_cmd: &mut Command) -> io::Result<(ExitStatus, Vec, Vec)> unsupported() } -impl From for Stdio { - fn from(pipe: AnonPipe) -> Stdio { +impl From for Stdio { + fn from(pipe: ChildPipe) -> Stdio { pipe.diverge() } } @@ -317,3 +316,14 @@ impl<'a> fmt::Debug for CommandArgs<'a> { f.debug_list().entries(self.iter.clone()).finish() } } + +pub type ChildPipe = crate::sys::pipe::Pipe; + +pub fn read_output( + out: ChildPipe, + _stdout: &mut Vec, + _err: ChildPipe, + _stderr: &mut Vec, +) -> io::Result<()> { + match out.diverge() {} +} diff --git a/library/std/src/sys/process/windows.rs b/library/std/src/sys/process/windows.rs index 6e8be21a1fa6..85b9682320d2 100644 --- a/library/std/src/sys/process/windows.rs +++ b/library/std/src/sys/process/windows.rs @@ -23,11 +23,14 @@ use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; use crate::sys::pal::api::{self, WinError, utf16}; use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf}; -use crate::sys::pipe::{self, AnonPipe}; use crate::sys::{cvt, path, stdio}; use crate::sys_common::IntoInner; use crate::{cmp, env, fmt, ptr}; +mod child_pipe; + +pub use self::child_pipe::{ChildPipe, read_output}; + //////////////////////////////////////////////////////////////////////////////// // Command //////////////////////////////////////////////////////////////////////////////// @@ -167,7 +170,7 @@ pub enum Stdio { InheritSpecific { from_stdio_id: u32 }, Null, MakePipe, - Pipe(AnonPipe), + Pipe(ChildPipe), Handle(Handle), } @@ -596,7 +599,7 @@ fn program_exists(path: &Path) -> Option> { } impl Stdio { - fn to_handle(&self, stdio_id: u32, pipe: &mut Option) -> io::Result { + fn to_handle(&self, stdio_id: u32, pipe: &mut Option) -> io::Result { let use_stdio_id = |stdio_id| match stdio::get_handle(stdio_id) { Ok(io) => unsafe { let io = Handle::from_raw_handle(io); @@ -613,14 +616,15 @@ impl Stdio { Stdio::MakePipe => { let ours_readable = stdio_id != c::STD_INPUT_HANDLE; - let pipes = pipe::anon_pipe(ours_readable, true)?; + let pipes = child_pipe::child_pipe(ours_readable, true)?; *pipe = Some(pipes.ours); Ok(pipes.theirs.into_handle()) } Stdio::Pipe(ref source) => { let ours_readable = stdio_id != c::STD_INPUT_HANDLE; - pipe::spawn_pipe_relay(source, ours_readable, true).map(AnonPipe::into_handle) + child_pipe::spawn_pipe_relay(source, ours_readable, true) + .map(ChildPipe::into_handle) } Stdio::Handle(ref handle) => handle.duplicate(0, true, c::DUPLICATE_SAME_ACCESS), @@ -639,8 +643,8 @@ impl Stdio { } } -impl From for Stdio { - fn from(pipe: AnonPipe) -> Stdio { +impl From for Stdio { + fn from(pipe: ChildPipe) -> Stdio { Stdio::Pipe(pipe) } } diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/process/windows/child_pipe.rs similarity index 91% rename from library/std/src/sys/pal/windows/pipe.rs rename to library/std/src/sys/process/windows/child_pipe.rs index 32cf4695d4a1..6b00c54407ad 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/process/windows/child_pipe.rs @@ -6,39 +6,37 @@ use crate::sys::{api, c}; use crate::sys_common::{FromInner, IntoInner}; use crate::{mem, ptr}; -//////////////////////////////////////////////////////////////////////////////// -// Anonymous pipes -//////////////////////////////////////////////////////////////////////////////// - -pub struct AnonPipe { +pub struct ChildPipe { inner: Handle, } -impl IntoInner for AnonPipe { +impl IntoInner for ChildPipe { fn into_inner(self) -> Handle { self.inner } } -impl FromInner for AnonPipe { - fn from_inner(inner: Handle) -> AnonPipe { +impl FromInner for ChildPipe { + fn from_inner(inner: Handle) -> ChildPipe { Self { inner } } } -pub struct Pipes { - pub ours: AnonPipe, - pub theirs: AnonPipe, +pub(super) struct Pipes { + pub ours: ChildPipe, + pub theirs: ChildPipe, } -/// Although this looks similar to `anon_pipe` in the Unix module it's actually -/// subtly different. Here we'll return two pipes in the `Pipes` return value, -/// but one is intended for "us" where as the other is intended for "someone -/// else". +/// Creates an anonymous pipe suitable for communication with a child process. /// -/// Currently the only use case for this function is pipes for stdio on -/// processes in the standard library, so "ours" is the one that'll stay in our -/// process whereas "theirs" will be inherited to a child. +/// Windows unfortunately does not have a way of performing asynchronous operations +/// on a handle originally created for synchronous operation. As `read_output` can +/// only be correctly implemented with asynchronous reads but the pipe created by +/// `CreatePipe` is synchronous, we cannot use it (and thus [`io::pipe`]) to create +/// a pipe for communicating with a child. Instead, this function uses the NT API +/// to create a pipe where one pipe handle (`ours`) is asynchronous and one is +/// synchronous and can be inherited by a child for use as a console handle +/// (`theirs`). /// /// The ours/theirs pipes are *not* specifically readable or writable. Each /// one only supports a read or a write, but which is which depends on the @@ -50,7 +48,11 @@ pub struct Pipes { /// mode. This means that technically speaking it should only ever be used /// with `OVERLAPPED` instances, but also works out ok if it's only ever used /// once at a time (which we do indeed guarantee). -pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Result { +// FIXME(joboet): No, we don't guarantee that? E.g. `&Stdout` is both `Read` +// and `Sync`, so there could be multiple operations at the same +// time. All the functions below that forward to the inner handle +// methods could abort if used concurrently. +pub(super) fn child_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Result { // A 64kb pipe capacity is the same as a typical Linux default. const PIPE_BUFFER_CAPACITY: u32 = 64 * 1024; @@ -166,7 +168,7 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res } }; - Ok(Pipes { ours: AnonPipe { inner: ours }, theirs: AnonPipe { inner: theirs } }) + Ok(Pipes { ours: ChildPipe { inner: ours }, theirs: ChildPipe { inner: theirs } }) } } @@ -175,16 +177,16 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res /// /// This is achieved by creating a new set of pipes and spawning a thread that /// relays messages between the source and the synchronous pipe. -pub fn spawn_pipe_relay( - source: &AnonPipe, +pub(super) fn spawn_pipe_relay( + source: &ChildPipe, ours_readable: bool, their_handle_inheritable: bool, -) -> io::Result { +) -> io::Result { // We need this handle to live for the lifetime of the thread spawned below. let source = source.try_clone()?; // create a new pair of anon pipes. - let Pipes { theirs, ours } = anon_pipe(ours_readable, their_handle_inheritable)?; + let Pipes { theirs, ours } = child_pipe(ours_readable, their_handle_inheritable)?; // Spawn a thread that passes messages from one pipe to the other. // Any errors will simply cause the thread to exit. @@ -210,7 +212,7 @@ pub fn spawn_pipe_relay( Ok(theirs) } -impl AnonPipe { +impl ChildPipe { pub fn handle(&self) -> &Handle { &self.inner } @@ -219,7 +221,7 @@ impl AnonPipe { } pub fn try_clone(&self) -> io::Result { - self.inner.duplicate(0, false, c::DUPLICATE_SAME_ACCESS).map(|inner| AnonPipe { inner }) + self.inner.duplicate(0, false, c::DUPLICATE_SAME_ACCESS).map(|inner| ChildPipe { inner }) } pub fn read(&self, buf: &mut [u8]) -> io::Result { @@ -347,18 +349,17 @@ impl AnonPipe { // STEP 3: The callback. unsafe extern "system" fn callback( - dwErrorCode: u32, - dwNumberOfBytesTransferred: u32, - lpOverlapped: *mut c::OVERLAPPED, + error: u32, + transferred: u32, + overlapped: *mut c::OVERLAPPED, ) { // Set `async_result` using a pointer smuggled through `hEvent`. // SAFETY: // At this point, the OVERLAPPED struct will have been written to by the OS, // except for our `hEvent` field which we set to a valid AsyncResult pointer (see below) unsafe { - let result = - AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred }; - *(*lpOverlapped).hEvent.cast::>() = Some(result); + let result = AsyncResult { error, transferred }; + *(*overlapped).hEvent.cast::>() = Some(result); } } @@ -395,7 +396,12 @@ impl AnonPipe { } } -pub fn read2(p1: AnonPipe, v1: &mut Vec, p2: AnonPipe, v2: &mut Vec) -> io::Result<()> { +pub fn read_output( + p1: ChildPipe, + v1: &mut Vec, + p2: ChildPipe, + v2: &mut Vec, +) -> io::Result<()> { let p1 = p1.into_handle(); let p2 = p2.into_handle(); diff --git a/library/std/src/sys/stdio/motor.rs b/library/std/src/sys/stdio/motor.rs index 0a44feab723d..e268bd5413df 100644 --- a/library/std/src/sys/stdio/motor.rs +++ b/library/std/src/sys/stdio/motor.rs @@ -166,7 +166,7 @@ impl From for OwnedFd { impl From for process::ChildStdin { #[inline] fn from(fd: OwnedFd) -> process::ChildStdin { - let pipe = sys::pipe::AnonPipe::from_inner(fd); + let pipe = sys::process::ChildPipe::from_inner(fd); process::ChildStdin::from_inner(pipe) } } @@ -196,7 +196,7 @@ impl From for OwnedFd { impl From for process::ChildStdout { #[inline] fn from(fd: OwnedFd) -> process::ChildStdout { - let pipe = sys::pipe::AnonPipe::from_inner(fd); + let pipe = sys::process::ChildPipe::from_inner(fd); process::ChildStdout::from_inner(pipe) } } @@ -226,7 +226,7 @@ impl From for OwnedFd { impl From for process::ChildStderr { #[inline] fn from(fd: OwnedFd) -> process::ChildStderr { - let pipe = sys::pipe::AnonPipe::from_inner(fd); + let pipe = sys::process::ChildPipe::from_inner(fd); process::ChildStderr::from_inner(pipe) } } From 653520afb2fb75df7e7e88ab068202cd66725fa2 Mon Sep 17 00:00:00 2001 From: joboet Date: Sat, 20 Sep 2025 11:39:07 +0200 Subject: [PATCH 0697/3801] std: update pipe tests --- .../std/src/sys/io/kernel_copy/linux/tests.rs | 14 ++-------- library/std/src/sys/pal/windows/handle.rs | 3 --- .../std/src/sys/pal/windows/handle/tests.rs | 22 --------------- library/std/src/sys/process/windows/tests.rs | 27 ++++++++++++++++++- 4 files changed, 28 insertions(+), 38 deletions(-) delete mode 100644 library/std/src/sys/pal/windows/handle/tests.rs diff --git a/library/std/src/sys/io/kernel_copy/linux/tests.rs b/library/std/src/sys/io/kernel_copy/linux/tests.rs index 15dee768d928..9b2d9cbef990 100644 --- a/library/std/src/sys/io/kernel_copy/linux/tests.rs +++ b/library/std/src/sys/io/kernel_copy/linux/tests.rs @@ -88,13 +88,8 @@ fn dont_splice_pipes_from_files() -> Result<()> { use crate::io::SeekFrom; use crate::os::unix::fs::FileExt; - use crate::process::{ChildStdin, ChildStdout}; - use crate::sys_common::FromInner; - let (read_end, write_end) = crate::sys::pipe::anon_pipe()?; - - let mut read_end = ChildStdout::from_inner(read_end); - let mut write_end = ChildStdin::from_inner(write_end); + let (mut read_end, mut write_end) = crate::io::pipe()?; let tmp_path = tmpdir(); let file = tmp_path.join("to_be_modified"); @@ -220,13 +215,8 @@ fn bench_file_to_uds_copy(b: &mut test::Bencher) { fn bench_socket_pipe_socket_copy(b: &mut test::Bencher) { use super::CopyResult; use crate::io::ErrorKind; - use crate::process::{ChildStdin, ChildStdout}; - use crate::sys_common::FromInner; - let (read_end, write_end) = crate::sys::pipe::anon_pipe().unwrap(); - - let mut read_end = ChildStdout::from_inner(read_end); - let write_end = ChildStdin::from_inner(write_end); + let (mut read_end, write_end) = crate::io::pipe().unwrap(); let acceptor = crate::net::TcpListener::bind("localhost:0").unwrap(); let mut remote_end = crate::net::TcpStream::connect(acceptor.local_addr().unwrap()).unwrap(); diff --git a/library/std/src/sys/pal/windows/handle.rs b/library/std/src/sys/pal/windows/handle.rs index 712f41ba8030..fc17e0b5ebd3 100644 --- a/library/std/src/sys/pal/windows/handle.rs +++ b/library/std/src/sys/pal/windows/handle.rs @@ -1,8 +1,5 @@ #![unstable(issue = "none", feature = "windows_handle")] -#[cfg(test)] -mod tests; - use core::ffi::c_void; use core::{cmp, mem, ptr}; diff --git a/library/std/src/sys/pal/windows/handle/tests.rs b/library/std/src/sys/pal/windows/handle/tests.rs deleted file mode 100644 index 0c976ed84e6b..000000000000 --- a/library/std/src/sys/pal/windows/handle/tests.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::sys::pipe::{Pipes, anon_pipe}; -use crate::{thread, time}; - -/// Test the synchronous fallback for overlapped I/O. -#[test] -fn overlapped_handle_fallback() { - // Create some pipes. `ours` will be asynchronous. - let Pipes { ours, theirs } = anon_pipe(true, false).unwrap(); - - let async_readable = ours.into_handle(); - let sync_writeable = theirs.into_handle(); - - thread::scope(|_| { - thread::sleep(time::Duration::from_millis(100)); - sync_writeable.write(b"hello world!").unwrap(); - }); - - // The pipe buffer starts empty so reading won't complete synchronously unless - // our fallback path works. - let mut buffer = [0u8; 1024]; - async_readable.read(&mut buffer).unwrap(); -} diff --git a/library/std/src/sys/process/windows/tests.rs b/library/std/src/sys/process/windows/tests.rs index a21afe3363c5..bc5e0d5c7fc9 100644 --- a/library/std/src/sys/process/windows/tests.rs +++ b/library/std/src/sys/process/windows/tests.rs @@ -1,8 +1,10 @@ +use super::child_pipe::{Pipes, child_pipe}; use super::{Arg, make_command_line}; -use crate::env; use crate::ffi::{OsStr, OsString}; use crate::os::windows::io::AsHandle; use crate::process::{Command, Stdio}; +use crate::time::Duration; +use crate::{env, thread}; #[test] fn test_raw_args() { @@ -233,3 +235,26 @@ fn windows_exe_resolver() { ); } } + +/// Test the synchronous fallback for overlapped I/O. +/// +/// While technically testing `Handle` functionality, this is situated in this +/// module to allow easier access to `ChildPipe`. +#[test] +fn overlapped_handle_fallback() { + // Create some pipes. `ours` will be asynchronous. + let Pipes { ours, theirs } = child_pipe(true, false).unwrap(); + + let async_readable = ours.into_handle(); + let sync_writeable = theirs.into_handle(); + + thread::scope(|_| { + thread::sleep(Duration::from_millis(100)); + sync_writeable.write(b"hello world!").unwrap(); + }); + + // The pipe buffer starts empty so reading won't complete synchronously unless + // our fallback path works. + let mut buffer = [0u8; 1024]; + async_readable.read(&mut buffer).unwrap(); +} From 900c79ac89cf72b6d40e7de6beff2e01d8e97e9a Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 12 Dec 2025 21:24:59 +0000 Subject: [PATCH 0698/3801] update some outdated infos on error codes --- .../src/diagnostics/error-codes.md | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md index 1693432b90de..c7bb6669dce4 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md @@ -33,40 +33,22 @@ written, as always: ask your reviewer or ask around on the Rust Zulip. Error codes are stored in `compiler/rustc_error_codes`. -To create a new error, you first need to find the next available -code. You can find it with `tidy`: +To create a new error, you first need to find the next available code. +You can find it by opening `rustc_error_codes/src/lib.rs` and scrolling down +to the end of the `error_codes!` macro declaration. -``` -./x test tidy -``` - -This will invoke the tidy script, which generally checks that your code obeys -our coding conventions. Some of these jobs check error codes and ensure that -there aren't duplicates, etc (the tidy check is defined in -`src/tools/tidy/src/error_codes.rs`). Once it is finished with that, tidy will -print out the highest used error code: - -``` -... -tidy check -Found 505 error codes -Highest error code: `E0591` -... -``` - -Here we see the highest error code in use is `E0591`, so we _probably_ want -`E0592`. To be sure, run `rg E0592` and check, you should see no references. +Here we might see the highest error code in use is `E0805`, so we _probably_ want +`E0806`. To be sure, run `rg E0806` and check, you should see no references. You will have to write an extended description for your error, -which will go in `rustc_error_codes/src/error_codes/E0592.md`. -To register the error, open `rustc_error_codes/src/error_codes.rs` and add the -code (in its proper numerical order) into` register_diagnostics!` macro, like -this: +which will go in `rustc_error_codes/src/error_codes/E0806.md`. +To register the error, add the code (in its proper numerical order) to +the `error_codes!` macro, like this: ```rust -register_diagnostics! { - ... - E0592: include_str!("./error_codes/E0592.md"), +macro_rules! error_codes { +... +0806, } ``` @@ -75,7 +57,7 @@ To actually issue the error, you can use the `struct_span_code_err!` macro: ```rust struct_span_code_err!(self.dcx(), // some path to the `DiagCtxt` here span, // whatever span in the source you want - E0592, // your new error code + E0806, // your new error code fluent::example::an_error_message) .emit() // actually issue the error ``` From d0bd4df3aa09b3e01161beaea5ba1b44c3c8a0bd Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 29 Nov 2025 10:27:34 +0800 Subject: [PATCH 0699/3801] Fix span note for question mark expression --- .../traits/fulfillment_errors.rs | 32 ++++++++------- .../question-mark-result-err-mismatch.rs | 2 +- .../question-mark-result-err-mismatch.stderr | 2 +- tests/ui/traits/question-mark-span-144304.rs | 8 ++++ .../traits/question-mark-span-144304.stderr | 41 +++++++++++++++++++ 5 files changed, 68 insertions(+), 17 deletions(-) create mode 100644 tests/ui/traits/question-mark-span-144304.rs create mode 100644 tests/ui/traits/question-mark-span-144304.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 8c867f842b89..d96a1b0a8c0e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1229,7 +1229,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { chain.push((expr.span, prev_ty)); let mut prev = None; - for (span, err_ty) in chain.into_iter().rev() { + let mut iter = chain.into_iter().rev().peekable(); + while let Some((span, err_ty)) = iter.next() { + let is_last = iter.peek().is_none(); let err_ty = get_e_type(err_ty); let err_ty = match (err_ty, prev) { (Some(err_ty), Some(prev)) if !self.can_eq(obligation.param_env, err_ty, prev) => { @@ -1241,27 +1243,27 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { continue; } }; - if self + + let implements_from = self .infcx .type_implements_trait( self.tcx.get_diagnostic_item(sym::From).unwrap(), [self_ty, err_ty], obligation.param_env, ) - .must_apply_modulo_regions() - { - if !suggested { - let err_ty = self.tcx.short_string(err_ty, err.long_ty_path()); - err.span_label(span, format!("this has type `Result<_, {err_ty}>`")); - } + .must_apply_modulo_regions(); + + let err_ty_str = self.tcx.short_string(err_ty, err.long_ty_path()); + let label = if !implements_from && is_last { + format!( + "this can't be annotated with `?` because it has type `Result<_, {err_ty_str}>`" + ) } else { - let err_ty = self.tcx.short_string(err_ty, err.long_ty_path()); - err.span_label( - span, - format!( - "this can't be annotated with `?` because it has type `Result<_, {err_ty}>`", - ), - ); + format!("this has type `Result<_, {err_ty_str}>`") + }; + + if !suggested || !implements_from { + err.span_label(span, label); } prev = Some(err_ty); } diff --git a/tests/ui/traits/question-mark-result-err-mismatch.rs b/tests/ui/traits/question-mark-result-err-mismatch.rs index df1d5105a34a..dfea4b93f46d 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.rs +++ b/tests/ui/traits/question-mark-result-err-mismatch.rs @@ -9,7 +9,7 @@ fn foo() -> Result { //~ NOTE expected `String` because of this }); let one = x .map(|s| ()) - .map_err(|e| { //~ NOTE this can't be annotated with `?` because it has type `Result<_, ()>` + .map_err(|e| { //~ NOTE this has type `Result<_, ()>` e; //~ HELP remove this semicolon }) .map(|()| "")?; //~ ERROR `?` couldn't convert the error to `String` diff --git a/tests/ui/traits/question-mark-result-err-mismatch.stderr b/tests/ui/traits/question-mark-result-err-mismatch.stderr index 0f83c9e73a31..be3f17cfc527 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.stderr +++ b/tests/ui/traits/question-mark-result-err-mismatch.stderr @@ -9,7 +9,7 @@ LL | .map_err(|e| { LL | | e; | | - help: remove this semicolon LL | | }) - | |__________- this can't be annotated with `?` because it has type `Result<_, ()>` + | |__________- this has type `Result<_, ()>` LL | .map(|()| "")?; | ^ the trait `From<()>` is not implemented for `String` | diff --git a/tests/ui/traits/question-mark-span-144304.rs b/tests/ui/traits/question-mark-span-144304.rs new file mode 100644 index 000000000000..bb015cae8ac9 --- /dev/null +++ b/tests/ui/traits/question-mark-span-144304.rs @@ -0,0 +1,8 @@ +//@ ignore-arm - armhf-gnu have more types implement trait `From`, let's skip it +fn f() -> Result<(), i32> { + Err("str").map_err(|e| e)?; //~ ERROR `?` couldn't convert the error to `i32` + Err("str").map_err(|e| e.to_string())?; //~ ERROR `?` couldn't convert the error to `i32` + Ok(()) +} + +fn main() {} diff --git a/tests/ui/traits/question-mark-span-144304.stderr b/tests/ui/traits/question-mark-span-144304.stderr new file mode 100644 index 000000000000..a412da0d235d --- /dev/null +++ b/tests/ui/traits/question-mark-span-144304.stderr @@ -0,0 +1,41 @@ +error[E0277]: `?` couldn't convert the error to `i32` + --> $DIR/question-mark-span-144304.rs:3:30 + | +LL | fn f() -> Result<(), i32> { + | --------------- expected `i32` because of this +LL | Err("str").map_err(|e| e)?; + | ---------- ^ the trait `From<&str>` is not implemented for `i32` + | | + | this has type `Result<_, &str>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = help: the following other types implement trait `From`: + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + +error[E0277]: `?` couldn't convert the error to `i32` + --> $DIR/question-mark-span-144304.rs:4:42 + | +LL | fn f() -> Result<(), i32> { + | --------------- expected `i32` because of this +LL | Err("str").map_err(|e| e)?; +LL | Err("str").map_err(|e| e.to_string())?; + | ---------- --------------------------^ the trait `From` is not implemented for `i32` + | | | + | | this can't be annotated with `?` because it has type `Result<_, String>` + | this has type `Result<_, &str>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = help: the following other types implement trait `From`: + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From 3fd0fb600528c8c339a74d6b02ec90d6c0c51dcc Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 13 Dec 2025 04:54:48 +0000 Subject: [PATCH 0700/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to dc47a69ed94bc88b10b7d500cceacf29b87bcbbe. --- 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 2e81ccbba184..e79ad9362c08 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -f5209000832c9d3bc29c91f4daef4ca9f28dc797 +dc47a69ed94bc88b10b7d500cceacf29b87bcbbe From e39e127bd0d2baa51b57671f1fa00d0c4e7afbbb Mon Sep 17 00:00:00 2001 From: Oleksii Lozovskyi Date: Sat, 13 Dec 2025 16:19:33 +0900 Subject: [PATCH 0701/3801] libtest: Stricter XML validation Expect the entire input to be a single XML document, instead of reading it line by line. This detects trailing junk better. --- tests/run-make/libtest-junit/validate_junit.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/run-make/libtest-junit/validate_junit.py b/tests/run-make/libtest-junit/validate_junit.py index f92473751b03..a9cb0a059563 100755 --- a/tests/run-make/libtest-junit/validate_junit.py +++ b/tests/run-make/libtest-junit/validate_junit.py @@ -13,10 +13,10 @@ import sys import xml.etree.ElementTree as ET -# Try to decode line in order to ensure it is a valid XML document -for line in sys.stdin: - try: - ET.fromstring(line) - except ET.ParseError: - print("Invalid xml: %r" % line) - raise +# Read the entire output and try to decode it as XML. +junit = sys.stdin.read() +try: + ET.fromstring(junit) +except ET.ParseError: + print("Invalid xml: %r" % junit) + raise From 2cc434863c56a925d56e979cbfb1d824040d1cd7 Mon Sep 17 00:00:00 2001 From: Oleksii Lozovskyi Date: Sat, 13 Dec 2025 14:29:44 +0900 Subject: [PATCH 0702/3801] rustdoc: Test --format=junit Copied validate_junit.py from libtest-junit. JUnit format works well in edition 2021, but is currently broken in edition 2024 by the mergeable doctest report. --- .../run-make/doctests-junit/doctest-2021.xml | 1 + tests/run-make/doctests-junit/doctest.rs | 14 ++++ tests/run-make/doctests-junit/rmake.rs | 72 +++++++++++++++++++ .../run-make/doctests-junit/validate_junit.py | 22 ++++++ 4 files changed, 109 insertions(+) create mode 100644 tests/run-make/doctests-junit/doctest-2021.xml create mode 100644 tests/run-make/doctests-junit/doctest.rs create mode 100644 tests/run-make/doctests-junit/rmake.rs create mode 100755 tests/run-make/doctests-junit/validate_junit.py diff --git a/tests/run-make/doctests-junit/doctest-2021.xml b/tests/run-make/doctests-junit/doctest-2021.xml new file mode 100644 index 000000000000..5facfb80ce62 --- /dev/null +++ b/tests/run-make/doctests-junit/doctest-2021.xml @@ -0,0 +1 @@ + diff --git a/tests/run-make/doctests-junit/doctest.rs b/tests/run-make/doctests-junit/doctest.rs new file mode 100644 index 000000000000..1873d63a49c6 --- /dev/null +++ b/tests/run-make/doctests-junit/doctest.rs @@ -0,0 +1,14 @@ +/// ``` +/// assert_eq!(doctest::add(2, 2), 4); +/// ``` +/// +/// ```should_panic +/// assert_eq!(doctest::add(2, 2), 5); +/// ``` +/// +/// ```compile_fail +/// assert_eq!(doctest::add(2, 2), "banana"); +/// ``` +pub fn add(a: i32, b: i32) -> i32 { + a + b +} diff --git a/tests/run-make/doctests-junit/rmake.rs b/tests/run-make/doctests-junit/rmake.rs new file mode 100644 index 000000000000..40dc541b5d2c --- /dev/null +++ b/tests/run-make/doctests-junit/rmake.rs @@ -0,0 +1,72 @@ +// Check rustdoc's test JUnit (XML) output against snapshots. + +//@ ignore-cross-compile (running doctests) +//@ needs-unwind (test file contains `should_panic` test) + +use std::path::Path; + +use run_make_support::{cwd, diff, python_command, rustc, rustdoc}; + +fn main() { + let rlib = cwd().join("libdoctest.rlib"); + rustc().input("doctest.rs").crate_type("rlib").output(&rlib).run(); + + run_doctests(&rlib, "2021", "doctest-2021.xml"); + run_doctests_fail(&rlib, "2024"); +} + +#[track_caller] +fn run_doctests(rlib: &Path, edition: &str, expected_xml: &str) { + let rustdoc_out = rustdoc() + .input("doctest.rs") + .args(&[ + "--test", + "--test-args=-Zunstable-options", + "--test-args=--test-threads=1", + "--test-args=--format=junit", + ]) + .edition(edition) + .env("RUST_BACKTRACE", "0") + .extern_("doctest", rlib.display().to_string()) + .run(); + let rustdoc_stdout = &rustdoc_out.stdout_utf8(); + + python_command().arg("validate_junit.py").stdin_buf(rustdoc_stdout).run(); + + diff() + .expected_file(expected_xml) + .actual_text("output", rustdoc_stdout) + .normalize(r#"\btime="[0-9.]+""#, r#"time="$$TIME""#) + .run(); +} + +// FIXME: gone in the next patch +#[track_caller] +fn run_doctests_fail(rlib: &Path, edition: &str) { + let rustdoc_out = rustdoc() + .input("doctest.rs") + .args(&[ + "--test", + "--test-args=-Zunstable-options", + "--test-args=--test-threads=1", + "--test-args=--format=junit", + ]) + .edition(edition) + .env("RUST_BACKTRACE", "0") + .extern_("doctest", rlib.display().to_string()) + .run_fail(); + let rustdoc_stderr = &rustdoc_out.stderr_utf8(); + + diff() + .expected_text( + "expected", + r#" +thread 'main' ($TID) panicked at library/test/src/formatters/junit.rs:22:9: +assertion failed: !s.contains('\n') +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +"#, + ) + .actual_text("actual", rustdoc_stderr) + .normalize(r#"thread 'main' \([0-9]+\)"#, r#"thread 'main' ($$TID)"#) + .run(); +} diff --git a/tests/run-make/doctests-junit/validate_junit.py b/tests/run-make/doctests-junit/validate_junit.py new file mode 100755 index 000000000000..a9cb0a059563 --- /dev/null +++ b/tests/run-make/doctests-junit/validate_junit.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +# Trivial Python script that reads lines from stdin, and checks that each line +# is a well-formed XML document. +# +# This takes advantage of the fact that Python has a built-in XML parser, +# whereas doing the same check in Rust would require us to pull in an XML +# crate just for this relatively-minor test. +# +# If you're trying to remove Python scripts from the test suite, think twice +# before removing this one. You could do so, but it's probably not worth it. + +import sys +import xml.etree.ElementTree as ET + +# Read the entire output and try to decode it as XML. +junit = sys.stdin.read() +try: + ET.fromstring(junit) +except ET.ParseError: + print("Invalid xml: %r" % junit) + raise From 069cf9dfc906452d90d4e2898eac568fb558d25d Mon Sep 17 00:00:00 2001 From: Oleksii Lozovskyi Date: Sat, 29 Nov 2025 09:46:48 +0900 Subject: [PATCH 0703/3801] rustdoc: Write newline differently Fix the panic in write_message() which expects messages to contain no embedded newlines. We still want a trailing newline at the end of the file though, so write it in different manner. Doctest runner no longer panics, but the output is kinda broken when `compile_fail` doctests are present. This is because they are not mergeable. --- library/test/src/formatters/junit.rs | 6 ++- .../run-make/doctests-junit/doctest-2024.xml | 3 ++ tests/run-make/doctests-junit/rmake.rs | 40 +++---------------- 3 files changed, 13 insertions(+), 36 deletions(-) create mode 100644 tests/run-make/doctests-junit/doctest-2024.xml diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs index 1566f1cb1dac..74d99e0f1270 100644 --- a/library/test/src/formatters/junit.rs +++ b/library/test/src/formatters/junit.rs @@ -189,8 +189,10 @@ impl OutputFormatter for JunitFormatter { compilation_time: f64, ) -> io::Result<()> { self.write_message(&format!( - "\n", - )) + "", + ))?; + self.out.write_all(b"\n")?; + Ok(()) } } diff --git a/tests/run-make/doctests-junit/doctest-2024.xml b/tests/run-make/doctests-junit/doctest-2024.xml new file mode 100644 index 000000000000..4f94f01c3e32 --- /dev/null +++ b/tests/run-make/doctests-junit/doctest-2024.xml @@ -0,0 +1,3 @@ + + + diff --git a/tests/run-make/doctests-junit/rmake.rs b/tests/run-make/doctests-junit/rmake.rs index 40dc541b5d2c..4cc7ac7c31d7 100644 --- a/tests/run-make/doctests-junit/rmake.rs +++ b/tests/run-make/doctests-junit/rmake.rs @@ -12,7 +12,7 @@ fn main() { rustc().input("doctest.rs").crate_type("rlib").output(&rlib).run(); run_doctests(&rlib, "2021", "doctest-2021.xml"); - run_doctests_fail(&rlib, "2024"); + run_doctests(&rlib, "2024", "doctest-2024.xml"); } #[track_caller] @@ -31,42 +31,14 @@ fn run_doctests(rlib: &Path, edition: &str, expected_xml: &str) { .run(); let rustdoc_stdout = &rustdoc_out.stdout_utf8(); - python_command().arg("validate_junit.py").stdin_buf(rustdoc_stdout).run(); + // FIXME: merged output of compile_fail tests is broken + if edition != "2024" { + python_command().arg("validate_junit.py").stdin_buf(rustdoc_stdout).run(); + } diff() .expected_file(expected_xml) .actual_text("output", rustdoc_stdout) - .normalize(r#"\btime="[0-9.]+""#, r#"time="$$TIME""#) - .run(); -} - -// FIXME: gone in the next patch -#[track_caller] -fn run_doctests_fail(rlib: &Path, edition: &str) { - let rustdoc_out = rustdoc() - .input("doctest.rs") - .args(&[ - "--test", - "--test-args=-Zunstable-options", - "--test-args=--test-threads=1", - "--test-args=--format=junit", - ]) - .edition(edition) - .env("RUST_BACKTRACE", "0") - .extern_("doctest", rlib.display().to_string()) - .run_fail(); - let rustdoc_stderr = &rustdoc_out.stderr_utf8(); - - diff() - .expected_text( - "expected", - r#" -thread 'main' ($TID) panicked at library/test/src/formatters/junit.rs:22:9: -assertion failed: !s.contains('\n') -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -"#, - ) - .actual_text("actual", rustdoc_stderr) - .normalize(r#"thread 'main' \([0-9]+\)"#, r#"thread 'main' ($$TID)"#) + .normalize(r#"\b(time|total_time|compilation_time)="[0-9.]+""#, r#"$1="$$TIME""#) .run(); } From 1b9b4f4dc69302c80925ed910e7e94766d88db63 Mon Sep 17 00:00:00 2001 From: Clara Engler Date: Sat, 13 Dec 2025 10:12:17 +0100 Subject: [PATCH 0704/3801] time: Test and document time precision edge-case There is a slight edge case when adding and subtracting a `Duration` from a `SystemTime`, namely when the duration itself is finer/smaller than the time precision on the operating systems. On most (if not all non-Windows) operating systems, the precision of `Duration` aligns with the `SystemTime`, both being one nanosecond. However, on Windows, this time precision is 100ns, meaning that adding or subtracting a `Duration` whose value is `< Duration::new(0, 100)` will result in that method behaving like an addition/subtracting of `Duration::ZERO`, due to the `Duration` getting rounded-down to the zero value. --- library/std/src/time.rs | 32 ++++++++++++++++++++++++++------ library/std/tests/time.rs | 17 ++++++++++++----- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 0bda83af4dfb..67c144be14f6 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -514,7 +514,9 @@ impl SystemTime { /// Represents the maximum value representable by [`SystemTime`] on this platform. /// /// This value differs a lot between platforms, but it is always the case - /// that any positive addition to [`SystemTime::MAX`] will fail. + /// that any positive addition of a [`Duration`], whose value is greater + /// than or equal to the time precision of the operating system, to + /// [`SystemTime::MAX`] will fail. /// /// # Examples /// @@ -525,8 +527,13 @@ impl SystemTime { /// // Adding zero will change nothing. /// assert_eq!(SystemTime::MAX.checked_add(Duration::ZERO), Some(SystemTime::MAX)); /// - /// // But adding just 1ns will already fail. - /// assert_eq!(SystemTime::MAX.checked_add(Duration::new(0, 1)), None); + /// // But adding just one second will already fail ... + /// // + /// // Keep in mind that this in fact may succeed, if the Duration is + /// // smaller than the time precision of the operating system, which + /// // happens to be 1ns on most operating systems, with Windows being the + /// // notable exception by using 100ns, hence why this example uses 1s. + /// assert_eq!(SystemTime::MAX.checked_add(Duration::new(1, 0)), None); /// /// // Utilize this for saturating arithmetic to improve error handling. /// // In this case, we will use a certificate with a timestamp in the @@ -543,7 +550,9 @@ impl SystemTime { /// Represents the minimum value representable by [`SystemTime`] on this platform. /// /// This value differs a lot between platforms, but it is always the case - /// that any positive subtraction from [`SystemTime::MIN`] will fail. + /// that any positive subtraction of a [`Duration`] from, whose value is + /// greater than or equal to the time precision of the operating system, to + /// [`SystemTime::MIN`] will fail. /// /// Depending on the platform, this may be either less than or equal to /// [`SystemTime::UNIX_EPOCH`], depending on whether the operating system @@ -560,8 +569,13 @@ impl SystemTime { /// // Subtracting zero will change nothing. /// assert_eq!(SystemTime::MIN.checked_sub(Duration::ZERO), Some(SystemTime::MIN)); /// - /// // But subtracting just 1ns will already fail. - /// assert_eq!(SystemTime::MIN.checked_sub(Duration::new(0, 1)), None); + /// // But subtracting just one second will already fail. + /// // + /// // Keep in mind that this in fact may succeed, if the Duration is + /// // smaller than the time precision of the operating system, which + /// // happens to be 1ns on most operating systems, with Windows being the + /// // notable exception by using 100ns, hence why this example uses 1s. + /// assert_eq!(SystemTime::MIN.checked_sub(Duration::new(1, 0)), None); /// /// // Utilize this for saturating arithmetic to improve error handling. /// // In this case, we will use a cache expiry as a practical example. @@ -651,6 +665,9 @@ impl SystemTime { /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. + /// + /// In the case that the `duration` is smaller than the time precision of the operating + /// system, `Some(self)` will be returned. #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_add(&self, duration: Duration) -> Option { self.0.checked_add_duration(&duration).map(SystemTime) @@ -659,6 +676,9 @@ impl SystemTime { /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None` /// otherwise. + /// + /// In the case that the `duration` is smaller than the time precision of the operating + /// system, `Some(self)` will be returned. #[stable(feature = "time_checked_add", since = "1.34.0")] pub fn checked_sub(&self, duration: Duration) -> Option { self.0.checked_sub_duration(&duration).map(SystemTime) diff --git a/library/std/tests/time.rs b/library/std/tests/time.rs index 31cc7171fe52..0ef89bb09c63 100644 --- a/library/std/tests/time.rs +++ b/library/std/tests/time.rs @@ -250,15 +250,22 @@ fn system_time_duration_since_max_range_on_unix() { #[test] fn system_time_max_min() { + #[cfg(not(target_os = "windows"))] + /// Most (all?) non-Windows systems have nanosecond precision. + const MIN_INTERVAL: Duration = Duration::new(0, 1); + #[cfg(target_os = "windows")] + /// Windows' time precision is at 100ns. + const MIN_INTERVAL: Duration = Duration::new(0, 100); + // First, test everything with checked_* and Duration::ZERO. assert_eq!(SystemTime::MAX.checked_add(Duration::ZERO), Some(SystemTime::MAX)); assert_eq!(SystemTime::MAX.checked_sub(Duration::ZERO), Some(SystemTime::MAX)); assert_eq!(SystemTime::MIN.checked_add(Duration::ZERO), Some(SystemTime::MIN)); assert_eq!(SystemTime::MIN.checked_sub(Duration::ZERO), Some(SystemTime::MIN)); - // Now do the same again with checked_* but try by ± a single nanosecond. - assert!(SystemTime::MAX.checked_add(Duration::new(0, 1)).is_none()); - assert!(SystemTime::MAX.checked_sub(Duration::new(0, 1)).is_some()); - assert!(SystemTime::MIN.checked_add(Duration::new(0, 1)).is_some()); - assert!(SystemTime::MIN.checked_sub(Duration::new(0, 1)).is_none()); + // Now do the same again with checked_* but try by ± the lowest time precision. + assert!(SystemTime::MAX.checked_add(MIN_INTERVAL).is_none()); + assert!(SystemTime::MAX.checked_sub(MIN_INTERVAL).is_some()); + assert!(SystemTime::MIN.checked_add(MIN_INTERVAL).is_some()); + assert!(SystemTime::MIN.checked_sub(MIN_INTERVAL).is_none()); } From 0ecf91a701b0c4258dba75acde7dadf0586c7ed2 Mon Sep 17 00:00:00 2001 From: nxsaken Date: Sat, 13 Dec 2025 14:00:44 +0400 Subject: [PATCH 0705/3801] Use an explicit receiver in `DropGuard::dismiss` --- library/core/src/mem/drop_guard.rs | 10 +++++----- library/coretests/tests/mem.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/core/src/mem/drop_guard.rs b/library/core/src/mem/drop_guard.rs index 013134727b7f..74bf35390745 100644 --- a/library/core/src/mem/drop_guard.rs +++ b/library/core/src/mem/drop_guard.rs @@ -79,30 +79,30 @@ where /// /// let value = String::from("Nori likes chicken"); /// let guard = DropGuard::new(value, |s| println!("{s}")); - /// assert_eq!(guard.dismiss(), "Nori likes chicken"); + /// assert_eq!(DropGuard::dismiss(guard), "Nori likes chicken"); /// ``` #[unstable(feature = "drop_guard", issue = "144426")] #[rustc_const_unstable(feature = "const_drop_guard", issue = "none")] #[inline] - pub const fn dismiss(self) -> T + pub const fn dismiss(guard: Self) -> T where F: [const] Destruct, { // First we ensure that dropping the guard will not trigger // its destructor - let mut this = ManuallyDrop::new(self); + let mut guard = ManuallyDrop::new(guard); // Next we manually read the stored value from the guard. // // SAFETY: this is safe because we've taken ownership of the guard. - let value = unsafe { ManuallyDrop::take(&mut this.inner) }; + let value = unsafe { ManuallyDrop::take(&mut guard.inner) }; // Finally we drop the stored closure. We do this *after* having read // the value, so that even if the closure's `drop` function panics, // unwinding still tries to drop the value. // // SAFETY: this is safe because we've taken ownership of the guard. - unsafe { ManuallyDrop::drop(&mut this.f) }; + unsafe { ManuallyDrop::drop(&mut guard.f) }; value } } diff --git a/library/coretests/tests/mem.rs b/library/coretests/tests/mem.rs index 00582109aa2c..5247e01fba01 100644 --- a/library/coretests/tests/mem.rs +++ b/library/coretests/tests/mem.rs @@ -815,7 +815,7 @@ fn drop_guard_into_inner() { let dropped = Cell::new(false); let value = DropGuard::new(42, |_| dropped.set(true)); let guard = DropGuard::new(value, |_| dropped.set(true)); - let inner = guard.dismiss(); + let inner = DropGuard::dismiss(guard); assert_eq!(dropped.get(), false); assert_eq!(*inner, 42); } @@ -837,7 +837,7 @@ fn drop_guard_always_drops_value_if_closure_drop_unwinds() { // run the destructor of the value we passed, which we validate. let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { let guard = DropGuard::new(value_with_tracked_destruction, closure_that_panics_on_drop); - guard.dismiss(); + DropGuard::dismiss(guard); })); assert!(value_was_dropped); } From d602710e5a7813c94bb8cf7d0fb92ae558e1c46a Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 13 Dec 2025 20:13:24 +1100 Subject: [PATCH 0706/3801] Move match-candidate partitioning code into its own module --- .../src/builder/matches/buckets.rs | 349 ++++++++++++++++++ .../src/builder/matches/mod.rs | 81 +--- .../src/builder/matches/test.rs | 263 +------------ 3 files changed, 353 insertions(+), 340 deletions(-) create mode 100644 compiler/rustc_mir_build/src/builder/matches/buckets.rs diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs new file mode 100644 index 000000000000..0643704ed35a --- /dev/null +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -0,0 +1,349 @@ +use std::cmp::Ordering; + +use rustc_data_structures::fx::FxIndexMap; +use rustc_middle::mir::{BinOp, Place}; +use rustc_middle::span_bug; +use tracing::debug; + +use crate::builder::Builder; +use crate::builder::matches::test::is_switch_ty; +use crate::builder::matches::{Candidate, Test, TestBranch, TestCase, TestKind}; + +impl<'a, 'tcx> Builder<'a, 'tcx> { + /// Given a test, we partition the input candidates into several buckets. + /// If a candidate matches in exactly one of the branches of `test` + /// (and no other branches), we put it into the corresponding bucket. + /// If it could match in more than one of the branches of `test`, the test + /// doesn't usefully apply to it, and we stop partitioning candidates. + /// + /// Importantly, we also **mutate** the branched candidates to remove match pairs + /// that are entailed by the outcome of the test, and add any sub-pairs of the + /// removed pairs. + /// + /// This returns a pair of + /// - the candidates that weren't sorted; + /// - for each possible outcome of the test, the candidates that match in that outcome. + /// + /// For example: + /// ``` + /// # let (x, y, z) = (true, true, true); + /// match (x, y, z) { + /// (true , _ , true ) => true, // (0) + /// (false, false, _ ) => false, // (1) + /// (_ , true , _ ) => true, // (2) + /// (true , _ , false) => false, // (3) + /// } + /// # ; + /// ``` + /// + /// Assume we are testing on `x`. Conceptually, there are 2 overlapping candidate sets: + /// - If the outcome is that `x` is true, candidates {0, 2, 3} are possible + /// - If the outcome is that `x` is false, candidates {1, 2} are possible + /// + /// Following our algorithm: + /// - Candidate 0 is sorted into outcome `x == true` + /// - Candidate 1 is sorted into outcome `x == false` + /// - Candidate 2 remains unsorted, because testing `x` has no effect on it + /// - Candidate 3 remains unsorted, because a previous candidate (2) was unsorted + /// - This helps preserve the illusion that candidates are tested "in order" + /// + /// The sorted candidates are mutated to remove entailed match pairs: + /// - candidate 0 becomes `[z @ true]` since we know that `x` was `true`; + /// - candidate 1 becomes `[y @ false]` since we know that `x` was `false`. + pub(super) fn sort_candidates<'b, 'c>( + &mut self, + match_place: Place<'tcx>, + test: &Test<'tcx>, + mut candidates: &'b mut [&'c mut Candidate<'tcx>], + ) -> ( + &'b mut [&'c mut Candidate<'tcx>], + FxIndexMap, Vec<&'b mut Candidate<'tcx>>>, + ) { + // For each of the possible outcomes, collect vector of candidates that apply if the test + // has that particular outcome. + let mut target_candidates: FxIndexMap<_, Vec<&mut Candidate<'_>>> = Default::default(); + + let total_candidate_count = candidates.len(); + + // Sort the candidates into the appropriate vector in `target_candidates`. Note that at some + // point we may encounter a candidate where the test is not relevant; at that point, we stop + // sorting. + while let Some(candidate) = candidates.first_mut() { + let Some(branch) = + self.sort_candidate(match_place, test, candidate, &target_candidates) + else { + break; + }; + let (candidate, rest) = candidates.split_first_mut().unwrap(); + target_candidates.entry(branch).or_insert_with(Vec::new).push(candidate); + candidates = rest; + } + + // At least the first candidate ought to be tested + assert!( + total_candidate_count > candidates.len(), + "{total_candidate_count}, {candidates:#?}" + ); + debug!("tested_candidates: {}", total_candidate_count - candidates.len()); + debug!("untested_candidates: {}", candidates.len()); + + (candidates, target_candidates) + } + + /// Given that we are performing `test` against `test_place`, this job + /// sorts out what the status of `candidate` will be after the test. See + /// `test_candidates` for the usage of this function. The candidate may + /// be modified to update its `match_pairs`. + /// + /// So, for example, if this candidate is `x @ Some(P0)` and the `Test` is + /// a variant test, then we would modify the candidate to be `(x as + /// Option).0 @ P0` and return the index corresponding to the variant + /// `Some`. + /// + /// However, in some cases, the test may just not be relevant to candidate. + /// For example, suppose we are testing whether `foo.x == 22`, but in one + /// match arm we have `Foo { x: _, ... }`... in that case, the test for + /// the value of `x` has no particular relevance to this candidate. In + /// such cases, this function just returns None without doing anything. + /// This is used by the overall `match_candidates` algorithm to structure + /// the match as a whole. See `match_candidates` for more details. + /// + /// FIXME(#29623). In some cases, we have some tricky choices to make. for + /// example, if we are testing that `x == 22`, but the candidate is `x @ + /// 13..55`, what should we do? In the event that the test is true, we know + /// that the candidate applies, but in the event of false, we don't know + /// that it *doesn't* apply. For now, we return false, indicate that the + /// test does not apply to this candidate, but it might be we can get + /// tighter match code if we do something a bit different. + fn sort_candidate( + &mut self, + test_place: Place<'tcx>, + test: &Test<'tcx>, + candidate: &mut Candidate<'tcx>, + sorted_candidates: &FxIndexMap, Vec<&mut Candidate<'tcx>>>, + ) -> Option> { + // Find the match_pair for this place (if any). At present, + // afaik, there can be at most one. (In the future, if we + // adopted a more general `@` operator, there might be more + // than one, but it'd be very unusual to have two sides that + // both require tests; you'd expect one side to be simplified + // away.) + let (match_pair_index, match_pair) = candidate + .match_pairs + .iter() + .enumerate() + .find(|&(_, mp)| mp.place == Some(test_place))?; + + // If true, the match pair is completely entailed by its corresponding test + // branch, so it can be removed. If false, the match pair is _compatible_ + // with its test branch, but still needs a more specific test. + let fully_matched; + let ret = match (&test.kind, &match_pair.test_case) { + // If we are performing a variant switch, then this + // informs variant patterns, but nothing else. + ( + &TestKind::Switch { adt_def: tested_adt_def }, + &TestCase::Variant { adt_def, variant_index }, + ) => { + assert_eq!(adt_def, tested_adt_def); + fully_matched = true; + Some(TestBranch::Variant(variant_index)) + } + + // If we are performing a switch over integers, then this informs integer + // equality, but nothing else. + // + // FIXME(#29623) we could use PatKind::Range to rule + // things out here, in some cases. + (TestKind::SwitchInt, &TestCase::Constant { value }) + if is_switch_ty(match_pair.pattern_ty) => + { + // An important invariant of candidate sorting is that a candidate + // must not match in multiple branches. For `SwitchInt` tests, adding + // a new value might invalidate that property for range patterns that + // have already been sorted into the failure arm, so we must take care + // not to add such values here. + let is_covering_range = |test_case: &TestCase<'tcx>| { + test_case.as_range().is_some_and(|range| { + matches!(range.contains(value, self.tcx), None | Some(true)) + }) + }; + let is_conflicting_candidate = |candidate: &&mut Candidate<'tcx>| { + candidate + .match_pairs + .iter() + .any(|mp| mp.place == Some(test_place) && is_covering_range(&mp.test_case)) + }; + if sorted_candidates + .get(&TestBranch::Failure) + .is_some_and(|candidates| candidates.iter().any(is_conflicting_candidate)) + { + fully_matched = false; + None + } else { + fully_matched = true; + Some(TestBranch::Constant(value)) + } + } + (TestKind::SwitchInt, TestCase::Range(range)) => { + // When performing a `SwitchInt` test, a range pattern can be + // sorted into the failure arm if it doesn't contain _any_ of + // the values being tested. (This restricts what values can be + // added to the test by subsequent candidates.) + fully_matched = false; + let not_contained = sorted_candidates + .keys() + .filter_map(|br| br.as_constant()) + .all(|val| matches!(range.contains(val, self.tcx), Some(false))); + + not_contained.then(|| { + // No switch values are contained in the pattern range, + // so the pattern can be matched only if this test fails. + TestBranch::Failure + }) + } + + (TestKind::If, TestCase::Constant { value }) => { + fully_matched = true; + let value = value.try_to_bool().unwrap_or_else(|| { + span_bug!(test.span, "expected boolean value but got {value:?}") + }); + Some(if value { TestBranch::Success } else { TestBranch::Failure }) + } + + ( + &TestKind::Len { len: test_len, op: BinOp::Eq }, + &TestCase::Slice { len, variable_length }, + ) => { + match (test_len.cmp(&(len as u64)), variable_length) { + (Ordering::Equal, false) => { + // on true, min_len = len = $actual_length, + // on false, len != $actual_length + fully_matched = true; + Some(TestBranch::Success) + } + (Ordering::Less, _) => { + // test_len < pat_len. If $actual_len = test_len, + // then $actual_len < pat_len and we don't have + // enough elements. + fully_matched = false; + Some(TestBranch::Failure) + } + (Ordering::Equal | Ordering::Greater, true) => { + // This can match both if $actual_len = test_len >= pat_len, + // and if $actual_len > test_len. We can't advance. + fully_matched = false; + None + } + (Ordering::Greater, false) => { + // test_len != pat_len, so if $actual_len = test_len, then + // $actual_len != pat_len. + fully_matched = false; + Some(TestBranch::Failure) + } + } + } + ( + &TestKind::Len { len: test_len, op: BinOp::Ge }, + &TestCase::Slice { len, variable_length }, + ) => { + // the test is `$actual_len >= test_len` + match (test_len.cmp(&(len as u64)), variable_length) { + (Ordering::Equal, true) => { + // $actual_len >= test_len = pat_len, + // so we can match. + fully_matched = true; + Some(TestBranch::Success) + } + (Ordering::Less, _) | (Ordering::Equal, false) => { + // test_len <= pat_len. If $actual_len < test_len, + // then it is also < pat_len, so the test passing is + // necessary (but insufficient). + fully_matched = false; + Some(TestBranch::Success) + } + (Ordering::Greater, false) => { + // test_len > pat_len. If $actual_len >= test_len > pat_len, + // then we know we won't have a match. + fully_matched = false; + Some(TestBranch::Failure) + } + (Ordering::Greater, true) => { + // test_len < pat_len, and is therefore less + // strict. This can still go both ways. + fully_matched = false; + None + } + } + } + + (TestKind::Range(test), TestCase::Range(pat)) => { + if test == pat { + fully_matched = true; + Some(TestBranch::Success) + } else { + fully_matched = false; + // If the testing range does not overlap with pattern range, + // the pattern can be matched only if this test fails. + if !test.overlaps(pat, self.tcx)? { Some(TestBranch::Failure) } else { None } + } + } + (TestKind::Range(range), &TestCase::Constant { value }) => { + fully_matched = false; + if !range.contains(value, self.tcx)? { + // `value` is not contained in the testing range, + // so `value` can be matched only if this test fails. + Some(TestBranch::Failure) + } else { + None + } + } + + (TestKind::Eq { value: test_val, .. }, TestCase::Constant { value: case_val }) => { + if test_val == case_val { + fully_matched = true; + Some(TestBranch::Success) + } else { + fully_matched = false; + Some(TestBranch::Failure) + } + } + + (TestKind::Deref { temp: test_temp, .. }, TestCase::Deref { temp, .. }) + if test_temp == temp => + { + fully_matched = true; + Some(TestBranch::Success) + } + + (TestKind::Never, _) => { + fully_matched = true; + Some(TestBranch::Success) + } + + ( + TestKind::Switch { .. } + | TestKind::SwitchInt { .. } + | TestKind::If + | TestKind::Len { .. } + | TestKind::Range { .. } + | TestKind::Eq { .. } + | TestKind::Deref { .. }, + _, + ) => { + fully_matched = false; + None + } + }; + + if fully_matched { + // Replace the match pair by its sub-pairs. + let match_pair = candidate.match_pairs.remove(match_pair_index); + candidate.match_pairs.extend(match_pair.subpairs); + // Move or-patterns to the end. + candidate.sort_match_pairs(); + } + + ret + } +} diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 433c3e5aaaee..aa223435720c 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -34,6 +34,7 @@ use crate::builder::{ }; // helper functions, broken out by category: +mod buckets; mod match_pair; mod test; mod user_ty; @@ -2172,86 +2173,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { (match_place, test) } - /// Given a test, we partition the input candidates into several buckets. - /// If a candidate matches in exactly one of the branches of `test` - /// (and no other branches), we put it into the corresponding bucket. - /// If it could match in more than one of the branches of `test`, the test - /// doesn't usefully apply to it, and we stop partitioning candidates. - /// - /// Importantly, we also **mutate** the branched candidates to remove match pairs - /// that are entailed by the outcome of the test, and add any sub-pairs of the - /// removed pairs. - /// - /// This returns a pair of - /// - the candidates that weren't sorted; - /// - for each possible outcome of the test, the candidates that match in that outcome. - /// - /// For example: - /// ``` - /// # let (x, y, z) = (true, true, true); - /// match (x, y, z) { - /// (true , _ , true ) => true, // (0) - /// (false, false, _ ) => false, // (1) - /// (_ , true , _ ) => true, // (2) - /// (true , _ , false) => false, // (3) - /// } - /// # ; - /// ``` - /// - /// Assume we are testing on `x`. Conceptually, there are 2 overlapping candidate sets: - /// - If the outcome is that `x` is true, candidates {0, 2, 3} are possible - /// - If the outcome is that `x` is false, candidates {1, 2} are possible - /// - /// Following our algorithm: - /// - Candidate 0 is sorted into outcome `x == true` - /// - Candidate 1 is sorted into outcome `x == false` - /// - Candidate 2 remains unsorted, because testing `x` has no effect on it - /// - Candidate 3 remains unsorted, because a previous candidate (2) was unsorted - /// - This helps preserve the illusion that candidates are tested "in order" - /// - /// The sorted candidates are mutated to remove entailed match pairs: - /// - candidate 0 becomes `[z @ true]` since we know that `x` was `true`; - /// - candidate 1 becomes `[y @ false]` since we know that `x` was `false`. - fn sort_candidates<'b, 'c>( - &mut self, - match_place: Place<'tcx>, - test: &Test<'tcx>, - mut candidates: &'b mut [&'c mut Candidate<'tcx>], - ) -> ( - &'b mut [&'c mut Candidate<'tcx>], - FxIndexMap, Vec<&'b mut Candidate<'tcx>>>, - ) { - // For each of the possible outcomes, collect vector of candidates that apply if the test - // has that particular outcome. - let mut target_candidates: FxIndexMap<_, Vec<&mut Candidate<'_>>> = Default::default(); - - let total_candidate_count = candidates.len(); - - // Sort the candidates into the appropriate vector in `target_candidates`. Note that at some - // point we may encounter a candidate where the test is not relevant; at that point, we stop - // sorting. - while let Some(candidate) = candidates.first_mut() { - let Some(branch) = - self.sort_candidate(match_place, test, candidate, &target_candidates) - else { - break; - }; - let (candidate, rest) = candidates.split_first_mut().unwrap(); - target_candidates.entry(branch).or_insert_with(Vec::new).push(candidate); - candidates = rest; - } - - // At least the first candidate ought to be tested - assert!( - total_candidate_count > candidates.len(), - "{total_candidate_count}, {candidates:#?}" - ); - debug!("tested_candidates: {}", total_candidate_count - candidates.len()); - debug!("untested_candidates: {}", candidates.len()); - - (candidates, target_candidates) - } - /// This is the most subtle part of the match lowering algorithm. At this point, there are /// no fully-satisfied candidates, and no or-patterns to expand, so we actually need to /// perform some sort of test to make progress. diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 1b6d96e49f0c..46a76a7b9a30 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -5,7 +5,6 @@ // identify what tests are needed, perform the tests, and then filter // the candidates based on the result. -use std::cmp::Ordering; use std::sync::Arc; use rustc_data_structures::fx::FxIndexMap; @@ -20,7 +19,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use tracing::{debug, instrument}; use crate::builder::Builder; -use crate::builder::matches::{Candidate, MatchPairTree, Test, TestBranch, TestCase, TestKind}; +use crate::builder::matches::{MatchPairTree, Test, TestBranch, TestCase, TestKind}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Identifies what test is needed to decide if `match_pair` is applicable. @@ -486,266 +485,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TerminatorKind::if_(Operand::Move(eq_result), success_block, fail_block), ); } - - /// Given that we are performing `test` against `test_place`, this job - /// sorts out what the status of `candidate` will be after the test. See - /// `test_candidates` for the usage of this function. The candidate may - /// be modified to update its `match_pairs`. - /// - /// So, for example, if this candidate is `x @ Some(P0)` and the `Test` is - /// a variant test, then we would modify the candidate to be `(x as - /// Option).0 @ P0` and return the index corresponding to the variant - /// `Some`. - /// - /// However, in some cases, the test may just not be relevant to candidate. - /// For example, suppose we are testing whether `foo.x == 22`, but in one - /// match arm we have `Foo { x: _, ... }`... in that case, the test for - /// the value of `x` has no particular relevance to this candidate. In - /// such cases, this function just returns None without doing anything. - /// This is used by the overall `match_candidates` algorithm to structure - /// the match as a whole. See `match_candidates` for more details. - /// - /// FIXME(#29623). In some cases, we have some tricky choices to make. for - /// example, if we are testing that `x == 22`, but the candidate is `x @ - /// 13..55`, what should we do? In the event that the test is true, we know - /// that the candidate applies, but in the event of false, we don't know - /// that it *doesn't* apply. For now, we return false, indicate that the - /// test does not apply to this candidate, but it might be we can get - /// tighter match code if we do something a bit different. - pub(super) fn sort_candidate( - &mut self, - test_place: Place<'tcx>, - test: &Test<'tcx>, - candidate: &mut Candidate<'tcx>, - sorted_candidates: &FxIndexMap, Vec<&mut Candidate<'tcx>>>, - ) -> Option> { - // Find the match_pair for this place (if any). At present, - // afaik, there can be at most one. (In the future, if we - // adopted a more general `@` operator, there might be more - // than one, but it'd be very unusual to have two sides that - // both require tests; you'd expect one side to be simplified - // away.) - let (match_pair_index, match_pair) = candidate - .match_pairs - .iter() - .enumerate() - .find(|&(_, mp)| mp.place == Some(test_place))?; - - // If true, the match pair is completely entailed by its corresponding test - // branch, so it can be removed. If false, the match pair is _compatible_ - // with its test branch, but still needs a more specific test. - let fully_matched; - let ret = match (&test.kind, &match_pair.test_case) { - // If we are performing a variant switch, then this - // informs variant patterns, but nothing else. - ( - &TestKind::Switch { adt_def: tested_adt_def }, - &TestCase::Variant { adt_def, variant_index }, - ) => { - assert_eq!(adt_def, tested_adt_def); - fully_matched = true; - Some(TestBranch::Variant(variant_index)) - } - - // If we are performing a switch over integers, then this informs integer - // equality, but nothing else. - // - // FIXME(#29623) we could use PatKind::Range to rule - // things out here, in some cases. - (TestKind::SwitchInt, &TestCase::Constant { value }) - if is_switch_ty(match_pair.pattern_ty) => - { - // An important invariant of candidate sorting is that a candidate - // must not match in multiple branches. For `SwitchInt` tests, adding - // a new value might invalidate that property for range patterns that - // have already been sorted into the failure arm, so we must take care - // not to add such values here. - let is_covering_range = |test_case: &TestCase<'tcx>| { - test_case.as_range().is_some_and(|range| { - matches!(range.contains(value, self.tcx), None | Some(true)) - }) - }; - let is_conflicting_candidate = |candidate: &&mut Candidate<'tcx>| { - candidate - .match_pairs - .iter() - .any(|mp| mp.place == Some(test_place) && is_covering_range(&mp.test_case)) - }; - if sorted_candidates - .get(&TestBranch::Failure) - .is_some_and(|candidates| candidates.iter().any(is_conflicting_candidate)) - { - fully_matched = false; - None - } else { - fully_matched = true; - Some(TestBranch::Constant(value)) - } - } - (TestKind::SwitchInt, TestCase::Range(range)) => { - // When performing a `SwitchInt` test, a range pattern can be - // sorted into the failure arm if it doesn't contain _any_ of - // the values being tested. (This restricts what values can be - // added to the test by subsequent candidates.) - fully_matched = false; - let not_contained = sorted_candidates - .keys() - .filter_map(|br| br.as_constant()) - .all(|val| matches!(range.contains(val, self.tcx), Some(false))); - - not_contained.then(|| { - // No switch values are contained in the pattern range, - // so the pattern can be matched only if this test fails. - TestBranch::Failure - }) - } - - (TestKind::If, TestCase::Constant { value }) => { - fully_matched = true; - let value = value.try_to_bool().unwrap_or_else(|| { - span_bug!(test.span, "expected boolean value but got {value:?}") - }); - Some(if value { TestBranch::Success } else { TestBranch::Failure }) - } - - ( - &TestKind::Len { len: test_len, op: BinOp::Eq }, - &TestCase::Slice { len, variable_length }, - ) => { - match (test_len.cmp(&(len as u64)), variable_length) { - (Ordering::Equal, false) => { - // on true, min_len = len = $actual_length, - // on false, len != $actual_length - fully_matched = true; - Some(TestBranch::Success) - } - (Ordering::Less, _) => { - // test_len < pat_len. If $actual_len = test_len, - // then $actual_len < pat_len and we don't have - // enough elements. - fully_matched = false; - Some(TestBranch::Failure) - } - (Ordering::Equal | Ordering::Greater, true) => { - // This can match both if $actual_len = test_len >= pat_len, - // and if $actual_len > test_len. We can't advance. - fully_matched = false; - None - } - (Ordering::Greater, false) => { - // test_len != pat_len, so if $actual_len = test_len, then - // $actual_len != pat_len. - fully_matched = false; - Some(TestBranch::Failure) - } - } - } - ( - &TestKind::Len { len: test_len, op: BinOp::Ge }, - &TestCase::Slice { len, variable_length }, - ) => { - // the test is `$actual_len >= test_len` - match (test_len.cmp(&(len as u64)), variable_length) { - (Ordering::Equal, true) => { - // $actual_len >= test_len = pat_len, - // so we can match. - fully_matched = true; - Some(TestBranch::Success) - } - (Ordering::Less, _) | (Ordering::Equal, false) => { - // test_len <= pat_len. If $actual_len < test_len, - // then it is also < pat_len, so the test passing is - // necessary (but insufficient). - fully_matched = false; - Some(TestBranch::Success) - } - (Ordering::Greater, false) => { - // test_len > pat_len. If $actual_len >= test_len > pat_len, - // then we know we won't have a match. - fully_matched = false; - Some(TestBranch::Failure) - } - (Ordering::Greater, true) => { - // test_len < pat_len, and is therefore less - // strict. This can still go both ways. - fully_matched = false; - None - } - } - } - - (TestKind::Range(test), TestCase::Range(pat)) => { - if test == pat { - fully_matched = true; - Some(TestBranch::Success) - } else { - fully_matched = false; - // If the testing range does not overlap with pattern range, - // the pattern can be matched only if this test fails. - if !test.overlaps(pat, self.tcx)? { Some(TestBranch::Failure) } else { None } - } - } - (TestKind::Range(range), &TestCase::Constant { value }) => { - fully_matched = false; - if !range.contains(value, self.tcx)? { - // `value` is not contained in the testing range, - // so `value` can be matched only if this test fails. - Some(TestBranch::Failure) - } else { - None - } - } - - (TestKind::Eq { value: test_val, .. }, TestCase::Constant { value: case_val }) => { - if test_val == case_val { - fully_matched = true; - Some(TestBranch::Success) - } else { - fully_matched = false; - Some(TestBranch::Failure) - } - } - - (TestKind::Deref { temp: test_temp, .. }, TestCase::Deref { temp, .. }) - if test_temp == temp => - { - fully_matched = true; - Some(TestBranch::Success) - } - - (TestKind::Never, _) => { - fully_matched = true; - Some(TestBranch::Success) - } - - ( - TestKind::Switch { .. } - | TestKind::SwitchInt { .. } - | TestKind::If - | TestKind::Len { .. } - | TestKind::Range { .. } - | TestKind::Eq { .. } - | TestKind::Deref { .. }, - _, - ) => { - fully_matched = false; - None - } - }; - - if fully_matched { - // Replace the match pair by its sub-pairs. - let match_pair = candidate.match_pairs.remove(match_pair_index); - candidate.match_pairs.extend(match_pair.subpairs); - // Move or-patterns to the end. - candidate.sort_match_pairs(); - } - - ret - } } -fn is_switch_ty(ty: Ty<'_>) -> bool { +/// Returns true if this type be used with [`TestKind::SwitchInt`]. +pub(crate) fn is_switch_ty(ty: Ty<'_>) -> bool { ty.is_integral() || ty.is_char() } From bc11e7e142641c5784dcbf664a043adcc83c4a5e Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 13 Dec 2025 20:28:05 +1100 Subject: [PATCH 0707/3801] Rename match-candidate partitioning methods --- .../src/builder/matches/buckets.rs | 56 ++++++++++--------- .../src/builder/matches/mod.rs | 9 +-- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs index 0643704ed35a..f53e73d406c3 100644 --- a/compiler/rustc_mir_build/src/builder/matches/buckets.rs +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -9,6 +9,14 @@ use crate::builder::Builder; use crate::builder::matches::test::is_switch_ty; use crate::builder::matches::{Candidate, Test, TestBranch, TestCase, TestKind}; +/// Output of [`Builder::partition_candidates_into_buckets`]. +pub(crate) struct PartitionedCandidates<'tcx, 'b, 'c> { + /// For each possible outcome of the test, the candidates that are matched in that outcome. + pub(crate) target_candidates: FxIndexMap, Vec<&'b mut Candidate<'tcx>>>, + /// The remaining candidates that weren't associated with any test outcome. + pub(crate) remaining_candidates: &'b mut [&'c mut Candidate<'tcx>], +} + impl<'a, 'tcx> Builder<'a, 'tcx> { /// Given a test, we partition the input candidates into several buckets. /// If a candidate matches in exactly one of the branches of `test` @@ -20,10 +28,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// that are entailed by the outcome of the test, and add any sub-pairs of the /// removed pairs. /// - /// This returns a pair of - /// - the candidates that weren't sorted; - /// - for each possible outcome of the test, the candidates that match in that outcome. - /// /// For example: /// ``` /// # let (x, y, z) = (true, true, true); @@ -41,36 +45,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// - If the outcome is that `x` is false, candidates {1, 2} are possible /// /// Following our algorithm: - /// - Candidate 0 is sorted into outcome `x == true` - /// - Candidate 1 is sorted into outcome `x == false` - /// - Candidate 2 remains unsorted, because testing `x` has no effect on it - /// - Candidate 3 remains unsorted, because a previous candidate (2) was unsorted + /// - Candidate 0 is bucketed into outcome `x == true` + /// - Candidate 1 is bucketed into outcome `x == false` + /// - Candidate 2 remains unbucketed, because testing `x` has no effect on it + /// - Candidate 3 remains unbucketed, because a previous candidate (2) was unbucketed /// - This helps preserve the illusion that candidates are tested "in order" /// - /// The sorted candidates are mutated to remove entailed match pairs: + /// The bucketed candidates are mutated to remove entailed match pairs: /// - candidate 0 becomes `[z @ true]` since we know that `x` was `true`; /// - candidate 1 becomes `[y @ false]` since we know that `x` was `false`. - pub(super) fn sort_candidates<'b, 'c>( + pub(super) fn partition_candidates_into_buckets<'b, 'c>( &mut self, match_place: Place<'tcx>, test: &Test<'tcx>, mut candidates: &'b mut [&'c mut Candidate<'tcx>], - ) -> ( - &'b mut [&'c mut Candidate<'tcx>], - FxIndexMap, Vec<&'b mut Candidate<'tcx>>>, - ) { - // For each of the possible outcomes, collect vector of candidates that apply if the test + ) -> PartitionedCandidates<'tcx, 'b, 'c> { + // For each of the possible outcomes, collect a vector of candidates that apply if the test // has that particular outcome. let mut target_candidates: FxIndexMap<_, Vec<&mut Candidate<'_>>> = Default::default(); let total_candidate_count = candidates.len(); - // Sort the candidates into the appropriate vector in `target_candidates`. Note that at some - // point we may encounter a candidate where the test is not relevant; at that point, we stop - // sorting. + // Partition the candidates into the appropriate vector in `target_candidates`. + // Note that at some point we may encounter a candidate where the test is not relevant; + // at that point, we stop partitioning. while let Some(candidate) = candidates.first_mut() { let Some(branch) = - self.sort_candidate(match_place, test, candidate, &target_candidates) + self.choose_bucket_for_candidate(match_place, test, candidate, &target_candidates) else { break; }; @@ -87,7 +88,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("tested_candidates: {}", total_candidate_count - candidates.len()); debug!("untested_candidates: {}", candidates.len()); - (candidates, target_candidates) + PartitionedCandidates { target_candidates, remaining_candidates: candidates } } /// Given that we are performing `test` against `test_place`, this job @@ -115,12 +116,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// that it *doesn't* apply. For now, we return false, indicate that the /// test does not apply to this candidate, but it might be we can get /// tighter match code if we do something a bit different. - fn sort_candidate( + fn choose_bucket_for_candidate( &mut self, test_place: Place<'tcx>, test: &Test<'tcx>, candidate: &mut Candidate<'tcx>, - sorted_candidates: &FxIndexMap, Vec<&mut Candidate<'tcx>>>, + // Other candidates that have already been partitioned into a bucket for this test, if any + prior_candidates: &FxIndexMap, Vec<&mut Candidate<'tcx>>>, ) -> Option> { // Find the match_pair for this place (if any). At present, // afaik, there can be at most one. (In the future, if we @@ -155,13 +157,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // FIXME(#29623) we could use PatKind::Range to rule // things out here, in some cases. + // + // FIXME(Zalathar): Is the `is_switch_ty` test unnecessary? (TestKind::SwitchInt, &TestCase::Constant { value }) if is_switch_ty(match_pair.pattern_ty) => { - // An important invariant of candidate sorting is that a candidate + // An important invariant of candidate bucketing is that a candidate // must not match in multiple branches. For `SwitchInt` tests, adding // a new value might invalidate that property for range patterns that - // have already been sorted into the failure arm, so we must take care + // have already been partitioned into the failure arm, so we must take care // not to add such values here. let is_covering_range = |test_case: &TestCase<'tcx>| { test_case.as_range().is_some_and(|range| { @@ -174,7 +178,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .iter() .any(|mp| mp.place == Some(test_place) && is_covering_range(&mp.test_case)) }; - if sorted_candidates + if prior_candidates .get(&TestBranch::Failure) .is_some_and(|candidates| candidates.iter().any(is_conflicting_candidate)) { @@ -191,7 +195,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // the values being tested. (This restricts what values can be // added to the test by subsequent candidates.) fully_matched = false; - let not_contained = sorted_candidates + let not_contained = prior_candidates .keys() .filter_map(|br| br.as_constant()) .all(|val| matches!(range.contains(val, self.tcx), Some(false))); diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index aa223435720c..5074ce336798 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -27,6 +27,7 @@ use tracing::{debug, instrument}; use crate::builder::ForGuard::{self, OutsideGuard, RefWithinGuard}; use crate::builder::expr::as_place::PlaceBuilder; +use crate::builder::matches::buckets::PartitionedCandidates; use crate::builder::matches::user_ty::ProjectedUserTypesNode; use crate::builder::scope::DropKind; use crate::builder::{ @@ -1069,7 +1070,7 @@ struct Candidate<'tcx> { /// Key mutations include: /// /// - When a match pair is fully satisfied by a test, it is removed from the - /// list, and its subpairs are added instead (see [`Builder::sort_candidate`]). + /// list, and its subpairs are added instead (see [`Builder::choose_bucket_for_candidate`]). /// - During or-pattern expansion, any leading or-pattern is removed, and is /// converted into subcandidates (see [`Builder::expand_and_match_or_candidates`]). /// - After a candidate's subcandidates have been lowered, a copy of any remaining @@ -1254,7 +1255,7 @@ struct Ascription<'tcx> { /// /// Created by [`MatchPairTree::for_pattern`], and then inspected primarily by: /// - [`Builder::pick_test_for_match_pair`] (to choose a test) -/// - [`Builder::sort_candidate`] (to see how the test interacts with a match pair) +/// - [`Builder::choose_bucket_for_candidate`] (to see how the test interacts with a match pair) /// /// Note that or-patterns are not tested directly like the other variants. /// Instead they participate in or-pattern expansion, where they are transformed into @@ -2284,8 +2285,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // For each of the N possible test outcomes, build the vector of candidates that applies if // the test has that particular outcome. This also mutates the candidates to remove match // pairs that are fully satisfied by the relevant outcome. - let (remaining_candidates, target_candidates) = - self.sort_candidates(match_place, &test, candidates); + let PartitionedCandidates { target_candidates, remaining_candidates } = + self.partition_candidates_into_buckets(match_place, &test, candidates); // The block that we should branch to if none of the `target_candidates` match. let remainder_start = self.cfg.start_new_block(); From 0d2a418798a030ebf72115e6c4624609f690b249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 12 Dec 2025 16:35:41 +0100 Subject: [PATCH 0708/3801] Add `PlainSourceTarballGpl` component that includes also GPL code --- src/bootstrap/src/core/build_steps/dist.rs | 37 ++++++++++++++++++- .../builder/cli_paths/snapshots/x_dist.snap | 3 ++ src/bootstrap/src/core/builder/mod.rs | 1 + 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 24781083bfab..b9bf5ba61eed 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1211,7 +1211,8 @@ impl Step for Src { } /// Tarball for people who want to build rustc and other components from the source. -/// Does not contain GPL code for licensing reasons. +/// Does not contain GPL code, which is separated into `PlainSourceTarballGpl` +/// for licensing reasons. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct PlainSourceTarball; @@ -1261,7 +1262,39 @@ impl Step for PlainSourceTarball { } } -fn prepare_source_tarball(builder: &Builder<'_>, name: &str, exclude_dirs: &[&str]) -> Tarball { +/// Tarball with *all* source code for source builds, including GPL-licensed code. +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct PlainSourceTarballGpl; + +impl Step for PlainSourceTarballGpl { + /// Produces the location of the tarball generated + type Output = GeneratedTarball; + const IS_HOST: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("rustc-src-gpl") + } + + fn is_default_step(builder: &Builder<'_>) -> bool { + builder.config.rust_dist_src + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(PlainSourceTarballGpl); + } + + /// Creates the plain source tarball + fn run(self, builder: &Builder<'_>) -> GeneratedTarball { + let tarball = prepare_source_tarball(builder, "src-gpl", &[]); + tarball.bare() + } +} + +fn prepare_source_tarball<'a>( + builder: &'a Builder<'a>, + name: &str, + exclude_dirs: &[&str], +) -> Tarball<'a> { // NOTE: This is a strange component in a lot of ways. It uses `src` as the target, which // means neither rustup nor rustup-toolchain-install-master know how to download it. // It also contains symbolic links, unlike other any other dist tarball. diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_dist.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_dist.snap index 2fc8ca143dd0..7fae0b24df94 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_dist.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_dist.snap @@ -29,6 +29,9 @@ expression: dist [Dist] dist::PlainSourceTarball targets: [x86_64-unknown-linux-gnu] - Set({dist::rustc-src}) +[Dist] dist::PlainSourceTarballGpl + targets: [x86_64-unknown-linux-gnu] + - Set({dist::rustc-src-gpl}) [Dist] dist::ReproducibleArtifacts targets: [x86_64-unknown-linux-gnu] - Set({dist::reproducible-artifacts}) diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 961d0cd855ae..a5d339511267 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -986,6 +986,7 @@ impl<'a> Builder<'a> { // and force us to rebuild tools after vendoring dependencies. // To work around this, create the Tarball after building all the tools. dist::PlainSourceTarball, + dist::PlainSourceTarballGpl, dist::BuildManifest, dist::ReproducibleArtifacts, dist::Gcc From d80348b6c9c72c8d9bd32e764c531958160d6327 Mon Sep 17 00:00:00 2001 From: Clara Engler Date: Sat, 13 Dec 2025 10:09:20 +0100 Subject: [PATCH 0709/3801] time: Fix Windows' `SystemTime::checked_sub` The Windows implementation of `SystemTime::checked_sub` contains a bug, namely that it does not return `None` on values below 1601. This bug stems from the fact that internally, the time gets converted to an i64, with zero representing the anchor in 1601. Of course, performing checked subtraction on a signed integer generally works fine. However, the resulting value delivers undefined behavior on Windows systems. To mitigate this issue, we try to convert the resulting i64 to an u64 because a negative value should obviously fail there. --- library/std/src/sys/pal/windows/time.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs index 88f4d4cdbd61..6cccf090a3fc 100644 --- a/library/std/src/sys/pal/windows/time.rs +++ b/library/std/src/sys/pal/windows/time.rs @@ -111,8 +111,13 @@ impl SystemTime { } pub fn checked_sub_duration(&self, other: &Duration) -> Option { - let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?; - Some(SystemTime::from_intervals(intervals)) + // Windows does not support times before 1601, hence why we don't + // support negatives. In order to tackle this, we try to convert the + // resulting value into an u64, which should obviously fail in the case + // that the value is below zero. + let intervals: u64 = + self.intervals().checked_sub(checked_dur2intervals(other)?)?.try_into().ok()?; + Some(SystemTime::from_intervals(intervals as i64)) } } From 25a6fca2df6a417e4364225c7feea7fb236d1623 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 13 Dec 2025 13:10:35 +0100 Subject: [PATCH 0710/3801] Cleanup context --- compiler/rustc_attr_parsing/src/context.rs | 152 ++++++--------------- 1 file changed, 38 insertions(+), 114 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 074f3b4194ae..2cbc4a65b276 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -434,6 +434,22 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { self.emit_err(UnknownMetaItem { span, item: found, expected: options }) } + fn emit_parse_error( + &self, + span: Span, + reason: AttributeParseErrorReason<'_>, + ) -> ErrorGuaranteed { + self.emit_err(AttributeParseError { + span, + attr_span: self.attr_span, + template: self.template.clone(), + path: self.attr_path.clone(), + description: self.parsed_description, + reason, + suggestions: self.suggestions(), + }) + } + /// error that a string literal was expected. /// You can optionally give the literal you did find (which you found not to be a string literal) /// which can make better errors. For example, if the literal was a byte string it will suggest @@ -443,133 +459,56 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span: Span, actual_literal: Option<&MetaItemLit>, ) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { + self.emit_parse_error( span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedStringLiteral { + AttributeParseErrorReason::ExpectedStringLiteral { byte_string: actual_literal.and_then(|i| { i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span)) }), }, - suggestions: self.suggestions(), - }) + ) } pub(crate) fn expected_integer_literal(&self, span: Span) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { - span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedIntegerLiteral, - suggestions: self.suggestions(), - }) + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedIntegerLiteral) } pub(crate) fn expected_list(&self, span: Span) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { - span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedList, - suggestions: self.suggestions(), - }) + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedList) } - pub(crate) fn expected_no_args(&self, args_span: Span) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { - span: args_span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedNoArgs, - suggestions: self.suggestions(), - }) + pub(crate) fn expected_no_args(&self, span: Span) -> ErrorGuaranteed { + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNoArgs) } /// emit an error that a `name` was expected here pub(crate) fn expected_identifier(&self, span: Span) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { - span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedIdentifier, - suggestions: self.suggestions(), - }) + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedIdentifier) } /// emit an error that a `name = value` pair was expected at this span. The symbol can be given for /// a nicer error message talking about the specific name that was found lacking a value. pub(crate) fn expected_name_value(&self, span: Span, name: Option) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { - span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedNameValue(name), - suggestions: self.suggestions(), - }) + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNameValue(name)) } /// emit an error that a `name = value` pair was found where that name was already seen. pub(crate) fn duplicate_key(&self, span: Span, key: Symbol) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { - span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::DuplicateKey(key), - suggestions: self.suggestions(), - }) + self.emit_parse_error(span, AttributeParseErrorReason::DuplicateKey(key)) } /// an error that should be emitted when a [`MetaItemOrLitParser`](crate::parser::MetaItemOrLitParser) /// was expected *not* to be a literal, but instead a meta item. pub(crate) fn unexpected_literal(&self, span: Span) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { - span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::UnexpectedLiteral, - suggestions: self.suggestions(), - }) + self.emit_parse_error(span, AttributeParseErrorReason::UnexpectedLiteral) } pub(crate) fn expected_single_argument(&self, span: Span) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { - span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedSingleArgument, - suggestions: self.suggestions(), - }) + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedSingleArgument) } pub(crate) fn expected_at_least_one_argument(&self, span: Span) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { - span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument, - suggestions: self.suggestions(), - }) + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedAtLeastOneArgument) } /// produces an error along the lines of `expected one of [foo, meow]` @@ -578,19 +517,14 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span: Span, possibilities: &[Symbol], ) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { + self.emit_parse_error( span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedSpecificArgument { + AttributeParseErrorReason::ExpectedSpecificArgument { possibilities, strings: false, list: false, }, - suggestions: self.suggestions(), - }) + ) } /// produces an error along the lines of `expected one of [foo, meow] as an argument`. @@ -600,19 +534,14 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span: Span, possibilities: &[Symbol], ) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { + self.emit_parse_error( span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedSpecificArgument { + AttributeParseErrorReason::ExpectedSpecificArgument { possibilities, strings: false, list: true, }, - suggestions: self.suggestions(), - }) + ) } /// produces an error along the lines of `expected one of ["foo", "meow"]` @@ -621,19 +550,14 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span: Span, possibilities: &[Symbol], ) -> ErrorGuaranteed { - self.emit_err(AttributeParseError { + self.emit_parse_error( span, - attr_span: self.attr_span, - template: self.template.clone(), - path: self.attr_path.clone(), - description: self.parsed_description, - reason: AttributeParseErrorReason::ExpectedSpecificArgument { + AttributeParseErrorReason::ExpectedSpecificArgument { possibilities, strings: true, list: false, }, - suggestions: self.suggestions(), - }) + ) } pub(crate) fn warn_empty_attribute(&mut self, span: Span) { From ebbb4d5ea4a52b048d4d25c16a118fc6d8252717 Mon Sep 17 00:00:00 2001 From: increasing Date: Thu, 11 Dec 2025 19:16:55 +0100 Subject: [PATCH 0711/3801] replace addr_of_mut with &raw mut in maybeuninit docs --- library/core/src/mem/maybe_uninit.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index e00cf45fcab2..1f066697fa48 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -160,11 +160,10 @@ use crate::{fmt, intrinsics, ptr, slice}; /// /// ## Initializing a struct field-by-field /// -/// You can use `MaybeUninit`, and the [`std::ptr::addr_of_mut`] macro, to initialize structs field by field: +/// You can use `MaybeUninit` and the [`&raw mut`] syntax to initialize structs field by field: /// /// ```rust /// use std::mem::MaybeUninit; -/// use std::ptr::addr_of_mut; /// /// #[derive(Debug, PartialEq)] /// pub struct Foo { @@ -179,11 +178,11 @@ use crate::{fmt, intrinsics, ptr, slice}; /// // Initializing the `name` field /// // Using `write` instead of assignment via `=` to not call `drop` on the /// // old, uninitialized value. -/// unsafe { addr_of_mut!((*ptr).name).write("Bob".to_string()); } +/// unsafe { (&raw mut (*ptr).name).write("Bob".to_string()); } /// /// // Initializing the `list` field /// // If there is a panic here, then the `String` in the `name` field leaks. -/// unsafe { addr_of_mut!((*ptr).list).write(vec![0, 1, 2]); } +/// unsafe { (&raw mut (*ptr).list).write(vec![0, 1, 2]); } /// /// // All the fields are initialized, so we call `assume_init` to get an initialized Foo. /// unsafe { uninit.assume_init() } @@ -197,7 +196,7 @@ use crate::{fmt, intrinsics, ptr, slice}; /// } /// ); /// ``` -/// [`std::ptr::addr_of_mut`]: crate::ptr::addr_of_mut +/// [`&raw mut`]: https://doc.rust-lang.org/reference/types/pointer.html#r-type.pointer.raw.constructor /// [ub]: ../../reference/behavior-considered-undefined.html /// /// # Layout From e72613030e46817a54698ddaacd2d32f9d887209 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Sat, 13 Dec 2025 13:38:13 +0100 Subject: [PATCH 0712/3801] stop applying `dereferenceable(n)` to return types --- compiler/rustc_ty_utils/src/abi.rs | 17 +++++++++++------ tests/codegen-llvm/function-arguments.rs | 4 ++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index f98f161e8093..4bee120db8c3 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -315,13 +315,18 @@ fn arg_attrs_for_rust_scalar<'tcx>( attrs.pointee_align = Some(pointee.align.min(cx.tcx().sess.target.max_reliable_alignment())); - // `Box` are not necessarily dereferenceable for the entire duration of the function as - // they can be deallocated at any time. Same for non-frozen shared references (see - // ), and for mutable references to - // potentially self-referential types (see - // ). If LLVM had a way - // to say "dereferenceable on entry" we could use it here. attrs.pointee_size = match kind { + // LLVM dereferenceable attribute has unclear semantics on the return type, + // they seem to be "dereferenceable until the end of the program", which is + // generally, not valid for references. See + // + _ if is_return => Size::ZERO, + // `Box` are not necessarily dereferenceable for the entire duration of the function as + // they can be deallocated at any time. Same for non-frozen shared references (see + // ), and for mutable references to + // potentially self-referential types (see + // ). If LLVM had a way + // to say "dereferenceable on entry" we could use it here. PointerKind::Box { .. } | PointerKind::SharedRef { frozen: false } | PointerKind::MutableRef { unpin: false } => Size::ZERO, diff --git a/tests/codegen-llvm/function-arguments.rs b/tests/codegen-llvm/function-arguments.rs index 953b654555d5..4d557470504e 100644 --- a/tests/codegen-llvm/function-arguments.rs +++ b/tests/codegen-llvm/function-arguments.rs @@ -85,7 +85,7 @@ pub fn option_nonzero_int(x: Option>) -> Option> { #[no_mangle] pub fn readonly_borrow(_: &i32) {} -// CHECK: noundef align 4 dereferenceable(4) ptr @readonly_borrow_ret() +// CHECK: noundef nonnull align 4 ptr @readonly_borrow_ret() #[no_mangle] pub fn readonly_borrow_ret() -> &'static i32 { loop {} @@ -116,7 +116,7 @@ pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {} #[no_mangle] pub fn mutable_borrow(_: &mut i32) {} -// CHECK: noundef align 4 dereferenceable(4) ptr @mutable_borrow_ret() +// CHECK: noundef nonnull align 4 ptr @mutable_borrow_ret() #[no_mangle] pub fn mutable_borrow_ret() -> &'static mut i32 { loop {} From 1da1a39c9ae2ad51bc5bb438e45658f965ac530e Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 13 Dec 2025 13:18:59 +0100 Subject: [PATCH 0713/3801] Remove `UnknownMetaItem` error --- compiler/rustc_attr_parsing/messages.ftl | 4 ---- .../src/attributes/deprecation.rs | 7 +++--- .../src/attributes/prototype.rs | 5 ++--- .../src/attributes/stability.rs | 22 ++++++++++--------- compiler/rustc_attr_parsing/src/context.rs | 11 +--------- .../src/session_diagnostics.rs | 20 ----------------- .../src/error_codes/E0541.md | 4 +++- tests/ui/deprecation/deprecation-sanity.rs | 2 +- .../ui/deprecation/deprecation-sanity.stderr | 10 +++++---- .../stability-attribute-sanity-2.rs | 2 +- .../stability-attribute-sanity-2.stderr | 11 ++++++---- .../stability-attribute-sanity.rs | 2 +- .../stability-attribute-sanity.stderr | 11 ++++++---- 13 files changed, 44 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 61f816f0baf8..d28b2aec4b68 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -213,10 +213,6 @@ attr_parsing_stability_outside_std = stability attributes may not be used outsid attr_parsing_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes .help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) -attr_parsing_unknown_meta_item = - unknown meta item '{$item}' - .label = expected one of {$expected} - attr_parsing_unknown_version_literal = unknown version literal format, assuming it refers to a future version diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs index ad3e2ced60c7..2d79e3a103d6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs +++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs @@ -110,13 +110,12 @@ impl SingleAttributeParser for DeprecationParser { Some(get(cx, name, param.span(), param.args(), &suggestion)?); } _ => { - cx.unknown_key( + cx.expected_specific_argument( param.span(), - param.path().to_string(), if features.deprecated_suggestion() { - &["since", "note", "suggestion"] + &[sym::since, sym::note, sym::suggestion] } else { - &["since", "note"] + &[sym::since, sym::note] }, ); return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/prototype.rs b/compiler/rustc_attr_parsing/src/attributes/prototype.rs index cd7c84f45fe5..aef983df0204 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prototype.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prototype.rs @@ -46,9 +46,8 @@ impl SingleAttributeParser for CustomMirParser { extract_value(cx, sym::dialect, arg, meta_item.span(), &mut dialect, &mut failed); } else if let Some(arg) = meta_item.word_is(sym::phase) { extract_value(cx, sym::phase, arg, meta_item.span(), &mut phase, &mut failed); - } else if let Some(word) = meta_item.path().word() { - let word = word.to_string(); - cx.unknown_key(meta_item.span(), word, &["dialect", "phase"]); + } else if let Some(..) = meta_item.path().word() { + cx.expected_specific_argument(meta_item.span(), &[sym::dialect, sym::phase]); failed = true; } else { cx.expected_name_value(meta_item.span(), None); diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index 571cb884c1fc..383d72766686 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -315,11 +315,7 @@ pub(crate) fn parse_stability( insert_value_into_option_or_error(cx, ¶m, &mut since, word.unwrap())? } _ => { - cx.emit_err(session_diagnostics::UnknownMetaItem { - span: param_span, - item: param.path().to_string(), - expected: &["feature", "since"], - }); + cx.expected_specific_argument(param_span, &[sym::feature, sym::since]); return None; } } @@ -426,11 +422,17 @@ pub(crate) fn parse_unstability( insert_value_into_option_or_error(cx, ¶m, &mut old_name, word.unwrap())? } _ => { - cx.emit_err(session_diagnostics::UnknownMetaItem { - span: param.span(), - item: param.path().to_string(), - expected: &["feature", "reason", "issue", "soft", "implied_by", "old_name"], - }); + cx.expected_specific_argument( + param.span(), + &[ + sym::feature, + sym::reason, + sym::issue, + sym::soft, + sym::implied_by, + sym::old_name, + ], + ); return None; } } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 2cbc4a65b276..8712035957d0 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -77,7 +77,7 @@ use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; use crate::parser::{ArgParser, RefPathParser}; use crate::session_diagnostics::{ - AttributeParseError, AttributeParseErrorReason, ParsedDescription, UnknownMetaItem, + AttributeParseError, AttributeParseErrorReason, ParsedDescription, }; use crate::target_checking::AllowedTargets; @@ -425,15 +425,6 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { } impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { - pub(crate) fn unknown_key( - &self, - span: Span, - found: String, - options: &[&'static str], - ) -> ErrorGuaranteed { - self.emit_err(UnknownMetaItem { span, item: found, expected: options }) - } - fn emit_parse_error( &self, span: Span, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index b50a7f92fcdc..f103faec80af 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -64,26 +64,6 @@ pub(crate) struct DocAttributeNotAttribute { pub attribute: Symbol, } -/// Error code: E0541 -pub(crate) struct UnknownMetaItem<'a> { - pub span: Span, - pub item: String, - pub expected: &'a [&'a str], -} - -// Manual implementation to be able to format `expected` items correctly. -impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnknownMetaItem<'_> { - fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::>(); - Diag::new(dcx, level, fluent::attr_parsing_unknown_meta_item) - .with_span(self.span) - .with_code(E0541) - .with_arg("item", self.item) - .with_arg("expected", expected.join(", ")) - .with_span_label(self.span, fluent::attr_parsing_label) - } -} - #[derive(Diagnostic)] #[diag(attr_parsing_missing_since, code = E0542)] pub(crate) struct MissingSince { diff --git a/compiler/rustc_error_codes/src/error_codes/E0541.md b/compiler/rustc_error_codes/src/error_codes/E0541.md index 96334088feee..f1f97b39fa28 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0541.md +++ b/compiler/rustc_error_codes/src/error_codes/E0541.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + An unknown meta item was used. Erroneous code example: -```compile_fail,E0541 +```compile_fail (no longer emitted) #[deprecated( since="1.0.0", // error: unknown meta item diff --git a/tests/ui/deprecation/deprecation-sanity.rs b/tests/ui/deprecation/deprecation-sanity.rs index 45ee91741e5a..d1061dc1e170 100644 --- a/tests/ui/deprecation/deprecation-sanity.rs +++ b/tests/ui/deprecation/deprecation-sanity.rs @@ -3,7 +3,7 @@ // Various checks that deprecation attributes are used correctly mod bogus_attribute_types_1 { - #[deprecated(since = "a", note = "a", reason)] //~ ERROR unknown meta item 'reason' + #[deprecated(since = "a", note = "a", reason)] //~ ERROR malformed `deprecated` attribute input [E0539] fn f1() { } #[deprecated(since = "a", note)] //~ ERROR malformed `deprecated` attribute input [E0539] diff --git a/tests/ui/deprecation/deprecation-sanity.stderr b/tests/ui/deprecation/deprecation-sanity.stderr index a96d4a0bdea8..a4dc9f23d3d2 100644 --- a/tests/ui/deprecation/deprecation-sanity.stderr +++ b/tests/ui/deprecation/deprecation-sanity.stderr @@ -1,8 +1,10 @@ -error[E0541]: unknown meta item 'reason' - --> $DIR/deprecation-sanity.rs:6:43 +error[E0539]: malformed `deprecated` attribute input + --> $DIR/deprecation-sanity.rs:6:5 | LL | #[deprecated(since = "a", note = "a", reason)] - | ^^^^^^ expected one of `since`, `note` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^ + | | + | valid arguments are `since` or `note` error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:9:5 @@ -86,5 +88,5 @@ LL | #[deprecated = "hello"] error: aborting due to 10 previous errors -Some errors have detailed explanations: E0538, E0539, E0541, E0565. +Some errors have detailed explanations: E0538, E0539, E0565. For more information about an error, try `rustc --explain E0538`. diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-2.rs b/tests/ui/stability-attribute/stability-attribute-sanity-2.rs index 92e300d33d6e..dabff97ad52d 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity-2.rs +++ b/tests/ui/stability-attribute/stability-attribute-sanity-2.rs @@ -7,7 +7,7 @@ #[stable(feature = "a", feature = "b", since = "1.0.0")] //~ ERROR malformed `stable` attribute input [E0538] fn f1() { } -#[stable(feature = "a", sinse = "1.0.0")] //~ ERROR unknown meta item 'sinse' +#[stable(feature = "a", sinse = "1.0.0")] //~ ERROR malformed `stable` attribute input [E0539] fn f2() { } #[unstable(feature = "a", issue = "no")] diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-2.stderr b/tests/ui/stability-attribute/stability-attribute-sanity-2.stderr index 5b35a51cad72..7beb9fd979ce 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity-2.stderr +++ b/tests/ui/stability-attribute/stability-attribute-sanity-2.stderr @@ -7,11 +7,14 @@ LL | #[stable(feature = "a", feature = "b", since = "1.0.0")] | | found `feature` used as a key more than once | help: must be of the form: `#[stable(feature = "name", since = "version")]` -error[E0541]: unknown meta item 'sinse' - --> $DIR/stability-attribute-sanity-2.rs:10:25 +error[E0539]: malformed `stable` attribute input + --> $DIR/stability-attribute-sanity-2.rs:10:1 | LL | #[stable(feature = "a", sinse = "1.0.0")] - | ^^^^^^^^^^^^^^^ expected one of `feature`, `since` + | ^^^^^^^^^^^^^^^^^^^^^^^^---------------^^ + | | | + | | valid arguments are `feature` or `since` + | help: must be of the form: `#[stable(feature = "name", since = "version")]` error[E0545]: `issue` must be a non-zero numeric string or "none" --> $DIR/stability-attribute-sanity-2.rs:13:27 @@ -23,5 +26,5 @@ LL | #[unstable(feature = "a", issue = "no")] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0538, E0541, E0545. +Some errors have detailed explanations: E0538, E0539, E0545. For more information about an error, try `rustc --explain E0538`. diff --git a/tests/ui/stability-attribute/stability-attribute-sanity.rs b/tests/ui/stability-attribute/stability-attribute-sanity.rs index c4c86e12d267..cee8d5fae1d2 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity.rs +++ b/tests/ui/stability-attribute/stability-attribute-sanity.rs @@ -5,7 +5,7 @@ #![stable(feature = "rust1", since = "1.0.0")] mod bogus_attribute_types_1 { - #[stable(feature = "a", since = "4.4.4", reason)] //~ ERROR unknown meta item 'reason' [E0541] + #[stable(feature = "a", since = "4.4.4", reason)] //~ ERROR malformed `stable` attribute input [E0539] fn f1() { } #[stable(feature = "a", since)] //~ ERROR malformed `stable` attribute input [E0539] diff --git a/tests/ui/stability-attribute/stability-attribute-sanity.stderr b/tests/ui/stability-attribute/stability-attribute-sanity.stderr index ae948237d7ed..05c34484b9f8 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity.stderr +++ b/tests/ui/stability-attribute/stability-attribute-sanity.stderr @@ -1,8 +1,11 @@ -error[E0541]: unknown meta item 'reason' - --> $DIR/stability-attribute-sanity.rs:8:46 +error[E0539]: malformed `stable` attribute input + --> $DIR/stability-attribute-sanity.rs:8:5 | LL | #[stable(feature = "a", since = "4.4.4", reason)] - | ^^^^^^ expected one of `feature`, `since` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^ + | | | + | | valid arguments are `feature` or `since` + | help: must be of the form: `#[stable(feature = "name", since = "version")]` error[E0539]: malformed `stable` attribute input --> $DIR/stability-attribute-sanity.rs:11:5 @@ -138,5 +141,5 @@ LL | #[stable(feature = "a", since = "1.0.0")] error: aborting due to 20 previous errors -Some errors have detailed explanations: E0539, E0541, E0542, E0543, E0544, E0546, E0547, E0549, E0711. +Some errors have detailed explanations: E0539, E0542, E0543, E0544, E0546, E0547, E0549, E0711. For more information about an error, try `rustc --explain E0539`. From 42334f76a7fc2c00e518908f38e5ece4ff672ab8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 15:22:27 +0200 Subject: [PATCH 0714/3801] sembr README.md --- src/doc/rustc-dev-guide/README.md | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index 8f0fa462a8c5..9c439b83739c 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -1,8 +1,8 @@ [![CI](https://github.com/rust-lang/rustc-dev-guide/actions/workflows/ci.yml/badge.svg)](https://github.com/rust-lang/rustc-dev-guide/actions/workflows/ci.yml) -This is a collaborative effort to build a guide that explains how rustc -works. The aim of the guide is to help new contributors get oriented +This is a collaborative effort to build a guide that explains how rustc works. +The aim of the guide is to help new contributors get oriented to rustc, as well as to help more experienced folks in figuring out some new part of the compiler that they haven't worked on before. @@ -21,25 +21,24 @@ For documentation on developing the standard library, see The guide is useful today, but it has a lot of work still to go. -If you'd like to help improve the guide, we'd love to have you! You can find -plenty of issues on the [issue -tracker](https://github.com/rust-lang/rustc-dev-guide/issues). Just post a -comment on the issue you would like to work on to make sure that we don't -accidentally duplicate work. If you think something is missing, please open an -issue about it! +If you'd like to help improve the guide, we'd love to have you! +You can find plenty of issues on the [issue +tracker](https://github.com/rust-lang/rustc-dev-guide/issues). +Just post a comment on the issue you would like to work on to make sure that we don't +accidentally duplicate work. +If you think something is missing, please open an issue about it! **In general, if you don't know how the compiler works, that is not a problem!** In that case, what we will do is to schedule a bit of time for you to talk with someone who **does** know the code, or who wants -to pair with you and figure it out. Then you can work on writing up -what you learned. +to pair with you and figure it out. + Then you can work on writing up what you learned. In general, when writing about a particular part of the compiler's code, we -recommend that you link to the relevant parts of the [rustc -rustdocs][rustdocs]. +recommend that you link to the relevant parts of the [rustc rustdocs][rustdocs]. -The guide has a much lower bar for what it takes for a PR to be merged. Check out -the forge documentation for [our policy][forge_policy]. +The guide has a much lower bar for what it takes for a PR to be merged. +Check out the forge documentation for [our policy][forge_policy]. [forge_policy]: https://forge.rust-lang.org/rustc-dev-guide/index.html#review-policy @@ -61,9 +60,9 @@ The build files are found in the `book/html` directory. ### Link Validations -We use `mdbook-linkcheck2` to validate URLs included in our documentation. Link -checking is **not** run by default locally, though it is in CI. To enable it -locally, set the environment variable `ENABLE_LINKCHECK=1` like in the +We use `mdbook-linkcheck2` to validate URLs included in our documentation. +Link checking is **not** run by default locally, though it is in CI. +To enable it locally, set the environment variable `ENABLE_LINKCHECK=1` like in the following example. ``` @@ -72,6 +71,7 @@ ENABLE_LINKCHECK=1 mdbook serve ## Synchronizing josh subtree with rustc -This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. +This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. +You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. You can find a guide on how to perform the synchronization [here](./src/external-repos.md#synchronizing-a-josh-subtree). From 12c2c05a26a584d2dfb72922649c02378c67eaef Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Sat, 13 Dec 2025 13:27:26 +0000 Subject: [PATCH 0715/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to ce63e5d9ea20f15a70c6fdc4d4de7aee352fd965. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 7a84872f266d..4bcbec1a9f48 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -dfe1b8c97bcde283102f706d5dcdc3649e5e12e3 +ce63e5d9ea20f15a70c6fdc4d4de7aee352fd965 From ef04de5f20ff7033160b5a57e96b23e6b79c574a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 15:54:54 +0200 Subject: [PATCH 0716/3801] sembr nit (missed by tool) --- src/doc/rustc-dev-guide/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index 9c439b83739c..dba4f9ea759e 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -2,8 +2,8 @@ This is a collaborative effort to build a guide that explains how rustc works. -The aim of the guide is to help new contributors get oriented -to rustc, as well as to help more experienced folks in figuring out +The aim of the guide is to help new contributors get oriented to rustc, +as well as to help more experienced folks in figuring out some new part of the compiler that they haven't worked on before. [You can read the latest version of the guide here.](https://rustc-dev-guide.rust-lang.org/) From 48782ebaea174e1e706c2ccf4e95408d45811a71 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 15:56:22 +0200 Subject: [PATCH 0717/3801] small README improvements --- src/doc/rustc-dev-guide/README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index dba4f9ea759e..ed14e000f49a 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -1,19 +1,15 @@ [![CI](https://github.com/rust-lang/rustc-dev-guide/actions/workflows/ci.yml/badge.svg)](https://github.com/rust-lang/rustc-dev-guide/actions/workflows/ci.yml) - This is a collaborative effort to build a guide that explains how rustc works. The aim of the guide is to help new contributors get oriented to rustc, as well as to help more experienced folks in figuring out some new part of the compiler that they haven't worked on before. -[You can read the latest version of the guide here.](https://rustc-dev-guide.rust-lang.org/) +You may also find the [rustc API docs] useful. -You may also find the rustdocs [for the compiler itself][rustdocs] useful. Note that these are not intended as a guide; it's recommended that you search for the docs you're looking for instead of reading them top to bottom. -[rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc - For documentation on developing the standard library, see [`std-dev-guide`](https://std-dev-guide.rust-lang.org/). @@ -32,10 +28,10 @@ If you think something is missing, please open an issue about it! problem!** In that case, what we will do is to schedule a bit of time for you to talk with someone who **does** know the code, or who wants to pair with you and figure it out. - Then you can work on writing up what you learned. +Then you can work on writing up what you learned. In general, when writing about a particular part of the compiler's code, we -recommend that you link to the relevant parts of the [rustc rustdocs][rustdocs]. +recommend that you link to the relevant parts of the [rustc API docs]. The guide has a much lower bar for what it takes for a PR to be merged. Check out the forge documentation for [our policy][forge_policy]. @@ -75,3 +71,5 @@ This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.g You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. You can find a guide on how to perform the synchronization [here](./src/external-repos.md#synchronizing-a-josh-subtree). + +[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc From bf1f3ebf3713e5a7df7b745a3918afeb8f70a5a7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:08:32 +0200 Subject: [PATCH 0718/3801] point to the "main crate", instead of a list of crates --- src/doc/rustc-dev-guide/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index ed14e000f49a..59d6719c71cb 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -72,4 +72,4 @@ You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool t You can find a guide on how to perform the synchronization [here](./src/external-repos.md#synchronizing-a-josh-subtree). -[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc +[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle From f357e51e89113b9e8a59b580d635a1838aa1e8f1 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 13 Dec 2025 13:31:32 +0100 Subject: [PATCH 0719/3801] Stop using `IllFormedAttributeInputLint` for `macro_use` --- .../src/attributes/macro_attrs.rs | 11 +----- compiler/rustc_attr_parsing/src/context.rs | 4 ++ .../src/session_diagnostics.rs | 4 ++ tests/ui/attributes/invalid-macro-use.rs | 4 +- tests/ui/attributes/invalid-macro-use.stderr | 38 ++++++++++++------- tests/ui/attributes/malformed-attrs.rs | 2 +- tests/ui/attributes/malformed-attrs.stderr | 14 ++++++- .../issue-43106-gating-of-macro_use.rs | 2 +- .../issue-43106-gating-of-macro_use.stderr | 15 +++++++- 9 files changed, 64 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index e4209c3edd85..7db87feb38f1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -3,7 +3,7 @@ use rustc_hir::attrs::MacroUseArgs; use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS; use super::prelude::*; -use crate::session_diagnostics::IllFormedAttributeInputLint; +use crate::session_diagnostics::{AttributeParseErrorReason, IllFormedAttributeInputLint}; pub(crate) struct MacroEscapeParser; impl NoArgsAttributeParser for MacroEscapeParser { @@ -102,14 +102,7 @@ impl AttributeParser for MacroUseParser { } } ArgParser::NameValue(_) => { - let suggestions = cx.suggestions(); - cx.emit_err(IllFormedAttributeInputLint { - num_suggestions: suggestions.len(), - suggestions: DiagArgValue::StrListSepByAnd( - suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), - ), - span, - }); + cx.expected_list_or_no_args(span); } } }, diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8712035957d0..bd19eaf9ab39 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -468,6 +468,10 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedList) } + pub(crate) fn expected_list_or_no_args(&self, span: Span) -> ErrorGuaranteed { + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedListOrNoArgs) + } + pub(crate) fn expected_no_args(&self, span: Span) -> ErrorGuaranteed { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNoArgs) } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index f103faec80af..4f10b7cabd4c 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -519,6 +519,7 @@ pub(crate) enum AttributeParseErrorReason<'a> { ExpectedAtLeastOneArgument, ExpectedSingleArgument, ExpectedList, + ExpectedListOrNoArgs, UnexpectedLiteral, ExpectedNameValue(Option), DuplicateKey(Symbol), @@ -591,6 +592,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { AttributeParseErrorReason::ExpectedList => { diag.span_label(self.span, "expected this to be a list"); } + AttributeParseErrorReason::ExpectedListOrNoArgs => { + diag.span_label(self.span, "expected a list or no arguments here"); + } AttributeParseErrorReason::DuplicateKey(key) => { diag.span_label(self.span, format!("found `{key}` used as a key more than once")); diag.code(E0538); diff --git a/tests/ui/attributes/invalid-macro-use.rs b/tests/ui/attributes/invalid-macro-use.rs index 52e4608303f0..4d05e933647b 100644 --- a/tests/ui/attributes/invalid-macro-use.rs +++ b/tests/ui/attributes/invalid-macro-use.rs @@ -2,7 +2,9 @@ //~^ NOTE the lint level is defined here #[macro_use = 5] -//~^ ERROR valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` +//~^ ERROR malformed `macro_use` attribute input +//~| NOTE expected a list or no arguments here +//~| NOTE for more information, visit extern crate std as s1; #[macro_use(5)] diff --git a/tests/ui/attributes/invalid-macro-use.stderr b/tests/ui/attributes/invalid-macro-use.stderr index ff3ed6196d3d..ade9c9a21b8a 100644 --- a/tests/ui/attributes/invalid-macro-use.stderr +++ b/tests/ui/attributes/invalid-macro-use.stderr @@ -1,23 +1,33 @@ error[E0469]: imported macro not found - --> $DIR/invalid-macro-use.rs:51:13 + --> $DIR/invalid-macro-use.rs:53:13 | LL | #[macro_use(a)] | ^ error[E0469]: imported macro not found - --> $DIR/invalid-macro-use.rs:53:13 + --> $DIR/invalid-macro-use.rs:55:13 | LL | #[macro_use(b)] | ^ -error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` +error[E0539]: malformed `macro_use` attribute input --> $DIR/invalid-macro-use.rs:4:1 | LL | #[macro_use = 5] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ expected a list or no arguments here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_use = 5] +LL + #[macro_use(name1, name2, ...)] + | +LL - #[macro_use = 5] +LL + #[macro_use] + | error[E0539]: malformed `macro_use` attribute input - --> $DIR/invalid-macro-use.rs:8:1 + --> $DIR/invalid-macro-use.rs:10:1 | LL | #[macro_use(5)] | ^^^^^^^^^^^^-^^ @@ -35,7 +45,7 @@ LL + #[macro_use] | error[E0565]: malformed `macro_use` attribute input - --> $DIR/invalid-macro-use.rs:14:1 + --> $DIR/invalid-macro-use.rs:16:1 | LL | #[macro_use(a = "b")] | ^^^^^^^^^^^^^^-----^^ @@ -53,7 +63,7 @@ LL + #[macro_use] | error[E0565]: malformed `macro_use` attribute input - --> $DIR/invalid-macro-use.rs:20:1 + --> $DIR/invalid-macro-use.rs:22:1 | LL | #[macro_use(a(b))] | ^^^^^^^^^^^^^---^^ @@ -71,7 +81,7 @@ LL + #[macro_use] | error[E0539]: malformed `macro_use` attribute input - --> $DIR/invalid-macro-use.rs:26:1 + --> $DIR/invalid-macro-use.rs:28:1 | LL | #[macro_use(a::b)] | ^^^^^^^^^^^^----^^ @@ -89,13 +99,13 @@ LL + #[macro_use] | error: unused attribute - --> $DIR/invalid-macro-use.rs:32:1 + --> $DIR/invalid-macro-use.rs:34:1 | LL | #[macro_use(a)] | ^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/invalid-macro-use.rs:34:1 + --> $DIR/invalid-macro-use.rs:36:1 | LL | #[macro_use] | ^^^^^^^^^^^^ @@ -106,25 +116,25 @@ LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/invalid-macro-use.rs:40:1 + --> $DIR/invalid-macro-use.rs:42:1 | LL | #[macro_use(a)] | ^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/invalid-macro-use.rs:38:1 + --> $DIR/invalid-macro-use.rs:40:1 | LL | #[macro_use] | ^^^^^^^^^^^^ error: unused attribute - --> $DIR/invalid-macro-use.rs:46:1 + --> $DIR/invalid-macro-use.rs:48:1 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/invalid-macro-use.rs:44:1 + --> $DIR/invalid-macro-use.rs:46:1 | LL | #[macro_use] | ^^^^^^^^^^^^ diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 26ee89dd7b3b..3e67242a14b2 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -214,7 +214,7 @@ static mut TLS: u8 = 42; #[no_link()] //~^ ERROR malformed #[macro_use = 1] -//~^ ERROR valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` +//~^ ERROR malformed extern crate wloop; //~^ ERROR can't find crate for `wloop` [E0463] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index e1ebe4ac9eab..53446fb4da10 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -614,11 +614,21 @@ LL | #[non_exhaustive = 1] | | didn't expect any arguments here | help: must be of the form: `#[non_exhaustive]` -error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` +error[E0539]: malformed `macro_use` attribute input --> $DIR/malformed-attrs.rs:216:1 | LL | #[macro_use = 1] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ expected a list or no arguments here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_use = 1] +LL + #[macro_use(name1, name2, ...)] + | +LL - #[macro_use = 1] +LL + #[macro_use] + | error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/malformed-attrs.rs:221:1 diff --git a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.rs b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.rs index 67959a318297..274faa4495ef 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.rs @@ -13,7 +13,7 @@ mod macro_escape { //~^ ERROR arguments to `macro_use` are not allowed here #[macro_use = "2700"] struct S; - //~^ ERROR valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` + //~^ ERROR malformed //~| WARN cannot be used on //~| WARN previously accepted diff --git a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr index 5be17e96fb15..e8fcef8a1638 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr @@ -16,11 +16,21 @@ error: arguments to `macro_use` are not allowed here LL | #![macro_use(my_macro)] | ^^^^^^^^^^^^^^^^^^^^^^^ -error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` +error[E0539]: malformed `macro_use` attribute input --> $DIR/issue-43106-gating-of-macro_use.rs:15:5 | LL | #[macro_use = "2700"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ expected a list or no arguments here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_use = "2700"] struct S; +LL + #[macro_use(name1, name2, ...)] struct S; + | +LL - #[macro_use = "2700"] struct S; +LL + #[macro_use] struct S; + | warning: `#[macro_use]` attribute cannot be used on structs --> $DIR/issue-43106-gating-of-macro_use.rs:15:5 @@ -61,3 +71,4 @@ LL | #[macro_use] impl S { } error: aborting due to 4 previous errors; 4 warnings emitted +For more information about this error, try `rustc --explain E0539`. From 6a7ed1353d915f8ae9ce11d0caf0338c736424be Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 13 Dec 2025 13:33:45 +0100 Subject: [PATCH 0720/3801] Stop using `IllFormedAttributeInputLint` for `macro_use` --- .../src/attributes/macro_attrs.rs | 12 +----------- tests/ui/attributes/malformed-attrs.rs | 2 +- tests/ui/attributes/malformed-attrs.stderr | 13 +++++++++++-- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 7db87feb38f1..8a456778643b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -1,9 +1,7 @@ -use rustc_errors::DiagArgValue; use rustc_hir::attrs::MacroUseArgs; use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS; use super::prelude::*; -use crate::session_diagnostics::{AttributeParseErrorReason, IllFormedAttributeInputLint}; pub(crate) struct MacroEscapeParser; impl NoArgsAttributeParser for MacroEscapeParser { @@ -158,15 +156,7 @@ impl SingleAttributeParser for MacroExportParser { } } ArgParser::NameValue(_) => { - let span = cx.attr_span; - let suggestions = cx.suggestions(); - cx.emit_err(IllFormedAttributeInputLint { - num_suggestions: suggestions.len(), - suggestions: DiagArgValue::StrListSepByAnd( - suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), - ), - span, - }); + cx.expected_list_or_no_args(cx.attr_span); return None; } }; diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 3e67242a14b2..8ffad3a9a2e9 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -219,7 +219,7 @@ extern crate wloop; //~^ ERROR can't find crate for `wloop` [E0463] #[macro_export = 18] -//~^ ERROR valid forms for the attribute are +//~^ ERROR malformed #[allow_internal_unsafe = 1] //~^ ERROR malformed //~| ERROR allow_internal_unsafe side-steps the unsafe_code lint diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 53446fb4da10..4c1bd9277bc7 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -630,11 +630,20 @@ LL - #[macro_use = 1] LL + #[macro_use] | -error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` +error[E0539]: malformed `macro_export` attribute input --> $DIR/malformed-attrs.rs:221:1 | LL | #[macro_export = 18] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ expected a list or no arguments here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_export = 18] +LL + #[macro_export(local_inner_macros)] + | +LL - #[macro_export = 18] +LL + #[macro_export] + | error[E0565]: malformed `allow_internal_unsafe` attribute input --> $DIR/malformed-attrs.rs:223:1 From 69a59e8e87ae6b506f94ee4ef4a37ba1af764d84 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 13 Dec 2025 13:37:12 +0100 Subject: [PATCH 0721/3801] Stop using `IllFormedAttributeInputLint` for `must_use` --- compiler/rustc_attr_parsing/messages.ftl | 5 ----- .../rustc_attr_parsing/src/attributes/must_use.rs | 12 +----------- .../rustc_attr_parsing/src/session_diagnostics.rs | 9 --------- tests/ui/attributes/malformed-attrs.rs | 2 +- tests/ui/attributes/malformed-attrs.stderr | 12 +++++++++++- tests/ui/attributes/malformed-must_use.rs | 2 +- tests/ui/attributes/malformed-must_use.stderr | 13 ++++++++++++- 7 files changed, 26 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index d28b2aec4b68..fb9016ca4d86 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -50,11 +50,6 @@ attr_parsing_expects_feature_list = attr_parsing_expects_features = `{$name}` expects feature names -attr_parsing_ill_formed_attribute_input = {$num_suggestions -> - [1] attribute must be of the form {$suggestions} - *[other] valid forms for the attribute are {$suggestions} - } - attr_parsing_import_name_type_raw = import name type can only be used with link kind `raw-dylib` diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index a27e1ecb707e..2cbf6300ede4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs @@ -1,7 +1,4 @@ -use rustc_errors::DiagArgValue; - use super::prelude::*; -use crate::session_diagnostics::IllFormedAttributeInputLint; pub(crate) struct MustUseParser; @@ -45,14 +42,7 @@ impl SingleAttributeParser for MustUseParser { Some(value_str) } ArgParser::List(_) => { - let suggestions = cx.suggestions(); - cx.emit_err(IllFormedAttributeInputLint { - num_suggestions: suggestions.len(), - suggestions: DiagArgValue::StrListSepByAnd( - suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), - ), - span: cx.attr_span, - }); + cx.expected_name_value(cx.attr_span, None); return None; } }, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 4f10b7cabd4c..b93b2f737f6e 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -380,15 +380,6 @@ pub(crate) struct UnusedMultiple { pub name: Symbol, } -#[derive(Diagnostic)] -#[diag(attr_parsing_ill_formed_attribute_input)] -pub(crate) struct IllFormedAttributeInputLint { - #[primary_span] - pub span: Span, - pub num_suggestions: usize, - pub suggestions: DiagArgValue, -} - #[derive(Diagnostic)] #[diag(attr_parsing_null_on_export, code = E0648)] pub(crate) struct NullOnExport { diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 8ffad3a9a2e9..37ccf9faa1a3 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -59,7 +59,7 @@ #[cold = 1] //~^ ERROR malformed #[must_use()] -//~^ ERROR valid forms for the attribute are +//~^ ERROR malformed #[no_mangle = 1] //~^ ERROR malformed #[unsafe(naked())] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 4c1bd9277bc7..3e04a7e1a4e3 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -314,11 +314,21 @@ LL | #[cold = 1] | | didn't expect any arguments here | help: must be of the form: `#[cold]` -error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` +error[E0539]: malformed `must_use` attribute input --> $DIR/malformed-attrs.rs:61:1 | LL | #[must_use()] | ^^^^^^^^^^^^^ + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[must_use()] +LL + #[must_use = "reason"] + | +LL - #[must_use()] +LL + #[must_use] + | error[E0565]: malformed `no_mangle` attribute input --> $DIR/malformed-attrs.rs:63:1 diff --git a/tests/ui/attributes/malformed-must_use.rs b/tests/ui/attributes/malformed-must_use.rs index 4b98affa8abd..79a1c369f838 100644 --- a/tests/ui/attributes/malformed-must_use.rs +++ b/tests/ui/attributes/malformed-must_use.rs @@ -1,4 +1,4 @@ -#[must_use()] //~ ERROR valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` +#[must_use()] //~ ERROR malformed struct Test; fn main() {} diff --git a/tests/ui/attributes/malformed-must_use.stderr b/tests/ui/attributes/malformed-must_use.stderr index c948ba677444..38855f24a011 100644 --- a/tests/ui/attributes/malformed-must_use.stderr +++ b/tests/ui/attributes/malformed-must_use.stderr @@ -1,8 +1,19 @@ -error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` +error[E0539]: malformed `must_use` attribute input --> $DIR/malformed-must_use.rs:1:1 | LL | #[must_use()] | ^^^^^^^^^^^^^ + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[must_use()] +LL + #[must_use = "reason"] + | +LL - #[must_use()] +LL + #[must_use] + | error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. From dd91e003814086e0d92316b1569ac8629869d965 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:19:08 +0200 Subject: [PATCH 0722/3801] whitespace --- src/doc/rustc-dev-guide/.github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index fe92bc876cf7..3ec22145ccd2 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: pull_request: schedule: # Run multiple times a day as the successfull cached links are not checked every time. - - cron: '0 */8 * * *' + - cron: "0 */8 * * *" jobs: ci: From 745a0fb8d3354ecd2bcd57358d3067163c38ed06 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:24:32 +0200 Subject: [PATCH 0723/3801] does not work for some reason --- src/doc/rustc-dev-guide/.github/workflows/ci.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index 3ec22145ccd2..f2f2f7ed1485 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -83,16 +83,6 @@ jobs: git commit -m "Deploy ${GITHUB_SHA} to gh-pages" git push --quiet -f "https://x-token:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}" HEAD:gh-pages - - name: Cache sembr build - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - ci/sembr/target/ - key: sembr-${{ hashFiles('ci/sembr/Cargo.lock') }} - - name: Check if files comply with semantic line breaks continue-on-error: true run: | From de868f6b43bc15662028751fc74222cf616fc404 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Sat, 13 Dec 2025 14:31:45 +0000 Subject: [PATCH 0724/3801] bump stage0 --- src/stage0 | 915 +++++++++++++++++++++++------------------------------ 1 file changed, 391 insertions(+), 524 deletions(-) diff --git a/src/stage0 b/src/stage0 index 0e4e9eb1c4b9..ea0fe3bf84c4 100644 --- a/src/stage0 +++ b/src/stage0 @@ -13,528 +13,395 @@ nightly_branch=main # All changes below this comment will be overridden the next time the # tool is executed. -compiler_channel_manifest_hash=d8adf7e1722d2dc8ebdb327ee661e58a58145464bfcd9bb3cab66d652cc7bb90 -compiler_git_commit_hash=3b4dd9bf1410f8da6329baa36ce5e37673cbbd1f -compiler_date=2025-10-28 -compiler_version=beta -rustfmt_channel_manifest_hash=108599f303463cabaef3b53ab5e0c0e560a6a5a97f606d75a802efb595141baf -rustfmt_git_commit_hash=adaa838976ff99a4f0661136322f64cb466b58a0 -rustfmt_date=2025-10-28 -rustfmt_version=nightly +compiler_channel_manifest_hash=b2a49624353173ecdacf59c158c00929300606e1963f6e4609fb483a508402d0 +compiler_git_commit_hash=ded5c06cf21d2b93bffd5d884aa6e96934ee4234 +compiler_date=2025-12-11 +compiler_version=1.92.0 -dist/2025-10-28/rustc-beta-aarch64-apple-darwin.tar.gz=5d971d3a1c127d314f94f41440f0717b51692176630fef7f05a70d9bcd3bae44 -dist/2025-10-28/rustc-beta-aarch64-apple-darwin.tar.xz=2cedfc3a96acc9ebe82c5cf5bcf5355902a5726e1c28e7d50b15cfa2ee343174 -dist/2025-10-28/rustc-beta-aarch64-pc-windows-gnullvm.tar.gz=1875833b43088879444902023cc76682fa58f39520a1135e438afaacf3605f88 -dist/2025-10-28/rustc-beta-aarch64-pc-windows-gnullvm.tar.xz=a925fb02b296b8ce753ff7b1fae583a27fb2ef6de582a80f1428678a2f61a466 -dist/2025-10-28/rustc-beta-aarch64-pc-windows-msvc.tar.gz=28f423bb7db80232b887bd0d47243341a50611eca913c17c305dd55fa6bd3f12 -dist/2025-10-28/rustc-beta-aarch64-pc-windows-msvc.tar.xz=3be7d39a956afd591ba4b22785b4851fd6c0c7afd23d045c54d6b603cc14bc2d -dist/2025-10-28/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=8b98b7e04ef03c3b2bc95e0d6e3a92ad7849bad8d5a8969d6c9eefe169673066 -dist/2025-10-28/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=1b35688d58c10fdd1f1d02325022ae9eb36ee139f76ae753e16a0f4524d0f6d4 -dist/2025-10-28/rustc-beta-aarch64-unknown-linux-musl.tar.gz=c1de08dbaff419f08f82aef49972965d87e02054822e83e6e7f73714afbc4155 -dist/2025-10-28/rustc-beta-aarch64-unknown-linux-musl.tar.xz=2755a71cee31227e4638499dc882347ed9ecf0698cc64a177ff8a94c6ff3be8c -dist/2025-10-28/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=dac50bed8e2bb5d65b5f6ea52963d2b268829c9f79800304a225e058152be0bd -dist/2025-10-28/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=f818783e566cebc2ac392f923efd0ae8f51ae77ce6ade284514a57c21d288b7e -dist/2025-10-28/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=922d9d3aba6c5ac4da95ab9310d0f33ec7da4830a7d424b83d6f0181af96bccb -dist/2025-10-28/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=746a200dab88eec922dc08ea244ae818c27a0ca91360278e578ab9fc433bd3be -dist/2025-10-28/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=ac45fe7547dc1064286de6704a9343e95fa760163247ac02ff88ebf2bf4d7d8c -dist/2025-10-28/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=35ab727f335242d588742f79f29fb94590ac0c3bef29d012538f2e925cb9f96f -dist/2025-10-28/rustc-beta-i686-pc-windows-gnu.tar.gz=42eab38b498e0b8efd7fae51facd7caaf253e1bc341f915f978b484065e4c812 -dist/2025-10-28/rustc-beta-i686-pc-windows-gnu.tar.xz=d663982b6293285fa1ffcc5987ded64569216c0133476243b5525768cd6123bb -dist/2025-10-28/rustc-beta-i686-pc-windows-msvc.tar.gz=571eeccc9c1f25c4b9c2c6f45d15dbd9730bf6c0ac0f75a5b49652b6d4e98f68 -dist/2025-10-28/rustc-beta-i686-pc-windows-msvc.tar.xz=595a8b6b74910fa53a947ddde81f5519152f8c773a41a2f5b0d663540bc913fa -dist/2025-10-28/rustc-beta-i686-unknown-linux-gnu.tar.gz=3f2261279e5c16b0a4b572e799e2d3079aa33192e7713803214011e14c5c6707 -dist/2025-10-28/rustc-beta-i686-unknown-linux-gnu.tar.xz=c49c0e84b4b43aa6b72dc355173b4b5dc41563f3f76e882c405a8625c00befbc -dist/2025-10-28/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=92cea4e2708fbd86b35bc798b25a69ab10b62f28e972ff0624709e6e8268db60 -dist/2025-10-28/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=224f6e9896d19e00e369da70bc0e0dbd545d04033ff6ecff12b3f2d2bfe73fc8 -dist/2025-10-28/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=74901d397d5f6695df197520d16851986df2a5c5d432b8f24da1a5c3a5c0474b -dist/2025-10-28/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=02d8962da7234bfd365147b4177497a99c8f1f12f6841160abede61332edd35f -dist/2025-10-28/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=b8d810c76102a325cdecb98e7d7fab480a8d349328ce8a275366018a627fa4bf -dist/2025-10-28/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=f09c4e8d4a4ae4cf490e55bcd29ab00b6f7c1aed09c93b63f10fc3f812f415e7 -dist/2025-10-28/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=6c71850444d597cdc07a7169bd5d2564cbd99d1a34ec806ac8b818b39c9fd529 -dist/2025-10-28/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=01f3537787f41c2fd2ed1f955520ff0852bb27d899141cf44de3ae126abf8808 -dist/2025-10-28/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=833dcfab6dc87d375154d593c8e53cd5c74b3029f8b94c753928de718185283c -dist/2025-10-28/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=cf99a56b49b3db107d33f5c6e668310317aaeb2b2ca3c80a0ea2b30a09b453dd -dist/2025-10-28/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=55b1db794a4bb0f535e46a2c4a85eb7ea0016482b7086b6deae033746a42a69d -dist/2025-10-28/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=a741b18a92f5fa35cab2ed93d90782175b70e3ef5a127e21fde7acabb6228b59 -dist/2025-10-28/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=97335caa2ace3f33cd959dc35f01ec8a3d2de5699518b93fd191766eda3fe318 -dist/2025-10-28/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=2127853b7b4e2b3cf906ef292e9c7e370ec3f3760ce5576b447ed7902048794f -dist/2025-10-28/rustc-beta-s390x-unknown-linux-gnu.tar.gz=eb3df84c1a840cc69799ef0649972e5312afe59144700ba3652bd6083f48074a -dist/2025-10-28/rustc-beta-s390x-unknown-linux-gnu.tar.xz=16942680ea11ead1ab4d9d46d31389a14f237637a6877b278cd30a608446b787 -dist/2025-10-28/rustc-beta-sparcv9-sun-solaris.tar.gz=5c7848ab2b2cb181bd7f64cdbdc3b5b659b61850c14604a7977c35b9807daa48 -dist/2025-10-28/rustc-beta-sparcv9-sun-solaris.tar.xz=0f12cb118e253206ea74e7b1dabdda6e95bb0b10d47657aa4c560fa9ca28cf83 -dist/2025-10-28/rustc-beta-x86_64-apple-darwin.tar.gz=3c34e03deee0445864c7f5ebc89883db051a3c69b874a2daff658fb5dd364aba -dist/2025-10-28/rustc-beta-x86_64-apple-darwin.tar.xz=292d40e5ea57295ecd921a07fa11796771953d38793edcea9841a95e79d94ac2 -dist/2025-10-28/rustc-beta-x86_64-pc-solaris.tar.gz=6ac79775ff166ba76e663e8760ddf9625e06a28e5033d4d8cc570dcca73ca725 -dist/2025-10-28/rustc-beta-x86_64-pc-solaris.tar.xz=46c214af2c11ccb17529a991201624bad044d59c171c6f872468acb8523b6f96 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-gnu.tar.gz=29067fc4a5e0f123c34a045a1b0d55f88170bc9f658584d50e32219cd5945854 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-gnu.tar.xz=30c20794d0c244bd04dbd4de304ef3aea5ba11e26882f2a004680281f21e05b0 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-gnullvm.tar.gz=6c6c7614b538d9bad498b3642321adf0b2b6cdd3b24706903a8eb2125c0c122a -dist/2025-10-28/rustc-beta-x86_64-pc-windows-gnullvm.tar.xz=09822c7d5bbf218d5113e902968b37719949997fd788523bf80400274f428986 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-msvc.tar.gz=fcf05b8150cf7199e100f560854f6acb6874985a5cfbb00ead36914dc3fb66e9 -dist/2025-10-28/rustc-beta-x86_64-pc-windows-msvc.tar.xz=f5259f5b521ea10f093c522abd5bcec4e9dfb94ce3e384e3b53865a223e700d0 -dist/2025-10-28/rustc-beta-x86_64-unknown-freebsd.tar.gz=c3719366a9687d243483431231b86140e268bf2ce99e1ea1759a611524ea8ade -dist/2025-10-28/rustc-beta-x86_64-unknown-freebsd.tar.xz=015e02fb99098c31d502738e9e525d48ac6ca386e16f3ecb55235c7268d4abe7 -dist/2025-10-28/rustc-beta-x86_64-unknown-illumos.tar.gz=508acec5f2b092d09d55590e7fe921f7415aacc13c535532997776c4ebb86483 -dist/2025-10-28/rustc-beta-x86_64-unknown-illumos.tar.xz=f7437c9b0e747b0eccd7755a3ef551fa81194f23304ddb40ae44bca5782dda4b -dist/2025-10-28/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=cd985cf21af999dbb76e25cb6c9b5ac5723e8cda8625cf511e7df2c98e7e735a -dist/2025-10-28/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=d30acafe9f3ddfd25148abdd3078deaaafb6bb62f7979252e9e7880abc260b23 -dist/2025-10-28/rustc-beta-x86_64-unknown-linux-musl.tar.gz=1778c649d790e52b8462d5ea377339443e607b2434fa9b579236b465f63748c7 -dist/2025-10-28/rustc-beta-x86_64-unknown-linux-musl.tar.xz=909808e6e3a10cd3fc2c0927f47dbe4ac8de4653b4e771c9c44b8e58cbe5fe2d -dist/2025-10-28/rustc-beta-x86_64-unknown-netbsd.tar.gz=8584d5ad71c7cedcf6e64b0f83ed2cfa82346e88a1000acac677f464dbb0e6f6 -dist/2025-10-28/rustc-beta-x86_64-unknown-netbsd.tar.xz=7b85928ce5f6908ad82895097ba07fad70990b7810aa23c63725d7ecbbf54d54 -dist/2025-10-28/rust-std-beta-aarch64-apple-darwin.tar.gz=312c1121edf001f03ea169e8fff9668efd1925a45962b282b32d5f126bd6b010 -dist/2025-10-28/rust-std-beta-aarch64-apple-darwin.tar.xz=11e0fd642939358a892e66ebeea7f1737a009ad23692da486c7427cdce60c37d -dist/2025-10-28/rust-std-beta-aarch64-apple-ios.tar.gz=d7086698f3414ebf1410f79f8167ef2e4cf8e9143dc7e3704200d67e64252080 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios.tar.xz=a71fd039b0bfa2fa7a1abd13c622c89371f7af273fc44b3c210b1ead6a1f9156 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=52795cad4c58b32c3f36fb7b596c25a8e3277c85c165e161445d1fc81e0c4200 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=7db4e584f7890bd05d7cf8a991f539be249e0f04526e30743575129dada977c2 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios-sim.tar.gz=575b6d5185a71a4f4d29dc881f5dea5fe492d7b21a01c0bd9987cc212bb8ca25 -dist/2025-10-28/rust-std-beta-aarch64-apple-ios-sim.tar.xz=ea1c7896e21d0a89da399405611a25ec447ff71495a4b5d48501c9f8129b2a20 -dist/2025-10-28/rust-std-beta-aarch64-linux-android.tar.gz=f7a85a478dd9d55491a2395dda9539ab7898385782ef5be479362ba35e8be837 -dist/2025-10-28/rust-std-beta-aarch64-linux-android.tar.xz=4fc53a2be557540332410446f6f43f5e6339d10d8010c153d99d707df64a5ef1 -dist/2025-10-28/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=99b3f95696883f18e3734d02c75a5dc91edac003b6d9627c5a32baac41f3c69c -dist/2025-10-28/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=375db4717baaac6a784d8f53f84035f99d5f76f9a3f7df7dd385ee2d93027368 -dist/2025-10-28/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=b650ca7708ae5b05fc82c7aa483f9aaa42be83d6bcc6c524690da745f32f6f60 -dist/2025-10-28/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=1683d5a33387dd546ff641222b501e90049241df0f52c2f1a5dc568b35594135 -dist/2025-10-28/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=3e2d64dd8d2fdedb30b25f899f8ed8deff653c4d3f3f7e16e534ab7e1eec8a66 -dist/2025-10-28/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=e83d63666e0372f27d404a4ddf48de7abc5b646d9f087ebf8856bcbfe6f86362 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=8a99f5fbaf869f68bced6435acf18127ac8880193fb23e44cb5791546bc795d7 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=53be5ecbcb4d47e6a1fb811a6e8b4ecec7fd6ae2b6efac7d9934dee4cfb19dce -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=f61af59bc40a53dddf0a85b5205bec90d287a41ee3ac32345a97d21861ae6546 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=9ed2894300f6ac917ac33d0724133ba2fada2ab2e42a0b21a9bd994d70c942f4 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=70ad473c7d4934bab123afb8cff98773993fdbb73b4941f6022a25ef2942a223 -dist/2025-10-28/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=d0a06230a38c725ceed103c89e8031b541b7bc15a3646a1a3662d8147901b2fd -dist/2025-10-28/rust-std-beta-aarch64-unknown-none.tar.gz=90d4484a1e390e0d3edf25331d41f9b419730bd2e318e8927c4a891b2c035652 -dist/2025-10-28/rust-std-beta-aarch64-unknown-none.tar.xz=5b795b7378b6753fb2a8ea0ecef760009ffa05c9a4778815d2d2b4085baffe14 -dist/2025-10-28/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=52d0e13f1dc2083787d3294d5c3569b11227724ab4ced4ba9905ac0a5f25bde0 -dist/2025-10-28/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=981dca064b73d6617039bb35a32a17111445bc1ed9ba957525d227d3be9e8f6d -dist/2025-10-28/rust-std-beta-aarch64-unknown-uefi.tar.gz=fbb7066da0824513e4441bb59d4c6a6d4c8bc34f67ed79f67da3b8ec69ff3a4c -dist/2025-10-28/rust-std-beta-aarch64-unknown-uefi.tar.xz=c0bb51d8c513c0b5d597cbc00260bf2764595b12244906606c20ae6f98e0fc66 -dist/2025-10-28/rust-std-beta-arm-linux-androideabi.tar.gz=7cd5763f202c5679dc1bdc0e6551dc8093ee95a9b2d405ad8cbd31fcf232332c -dist/2025-10-28/rust-std-beta-arm-linux-androideabi.tar.xz=126b3a04432a3f6f5f1aef6f5e22deec98629da4a0809b0c7739911ae5e4b6cc -dist/2025-10-28/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=01bc31ad9812edeb11dc4b6c15d4bf80a325e286390829babd85176b91c38cfa -dist/2025-10-28/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=0b1c799856c8314afddfaa5109535535c36df31bb9188a319c1e45f4968a7079 -dist/2025-10-28/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=8792d0115ba1d9b0e3bfefbd7a9ddf7859f7bbf8431ef32530b05ec7cf9c68b8 -dist/2025-10-28/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=fc470db282fb0fab537e4b93a9498d4b4fc65cf014536905654cc2c14f82d245 -dist/2025-10-28/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=fe82493d2a7f4a9566916beefcd7fb26301bd13b8b838b5251398ecac0c867ef -dist/2025-10-28/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=b7cd0514db083e115d8aacceb3f7998da11f26e9f2be44137e8af2e2f9ac786e -dist/2025-10-28/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=0adc4e2e0f5bee4c28c81ba2cfd9796268e830d23b23b80c71121c30f08e3326 -dist/2025-10-28/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=8c98799e7b4c454cad130d0eb87e8ed59e0e7e64bb0513af8beb6d1d5f8e3ac7 -dist/2025-10-28/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=bb1da273578b508b9f397074438ecb2527a729e404d2820bd34d67dc8824106a -dist/2025-10-28/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=e004d91a9732284851d613a3c488909bc7d457b2053a1af45710aa4bbe3169e9 -dist/2025-10-28/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=7e6b5d4266306001366003cdc4fd4b60d700e86ec5dce01b58b0e73bd6a50c42 -dist/2025-10-28/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=170b32ea83d21436e744d11a56ea8e298278f8b9aa58fd82d6d788ff1e3258f3 -dist/2025-10-28/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=8ee71b71a8e90b21d580f9e64cc115f182db8582cd6238f946e24fc32de27e65 -dist/2025-10-28/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=9319475d974dce729182c3d99696bd5cf6a36257b1b80186f261d2885610ddb9 -dist/2025-10-28/rust-std-beta-armv7-linux-androideabi.tar.gz=71db2b02df33e229899f0dafc675572f2b4041400954f9145796edee7cd923d4 -dist/2025-10-28/rust-std-beta-armv7-linux-androideabi.tar.xz=0f331806b4523d61204f38f2d7ddd07e6f3dcda8a15806a9f01cb1747a587e8f -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=52f331579373b749fb1c7a6302a770a4be33008cdd9db4a5640208ba1ba7b540 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=1e8c5dcc4cb672c4e8ba2862549cd281ea6802fb73701c885eaf5423673ab233 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=2d0dded898f567cbfa5605dcc09b1e44970e345a030ef91c806eafcac4470258 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=3a63913c874f30c8a68d5cbb62dc654ec9c3bf2f4488e1098034f60c51824bb7 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=24c341427a9b5a4d883e7f322a9c7760446896e8c2eeb1f8654b80cef00db6ea -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=53c5607351479ad76c3450bcc81353633f2587aafda473487bb11e42f80d8523 -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=beda2ede28453b81588d639c18b36fa6e935e586723159e39ab9b714291c680a -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=f175a55fc81159e9a40407b1d97ea658239014cf0f5191a3533318e53ee1ff7f -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=db1f0cfd65d795d23a60d29e44f24e6174a0a516b998e65bd1964230c9c6c03c -dist/2025-10-28/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=264efedfd340c095dfe08fc95a35c36392eda0d1c2c179e56c75b27685b90d7e -dist/2025-10-28/rust-std-beta-armv7a-none-eabi.tar.gz=578fe97f24afa73c155290bf7386594e8b18a4652f54477d7a4e3f6f3ada0b5a -dist/2025-10-28/rust-std-beta-armv7a-none-eabi.tar.xz=a373109143f701d266ba53b3fff32206d88f5dfabdd888ac988606fade0b4928 -dist/2025-10-28/rust-std-beta-armv7a-none-eabihf.tar.gz=b3d6ec33c14a034c621aaf7de6ec81f0a916e18f5acc933713cc479fc21af755 -dist/2025-10-28/rust-std-beta-armv7a-none-eabihf.tar.xz=6550b2a97ce84884aa0da9133b81703e08b6e57b65c2e93f310fad2559ea4a08 -dist/2025-10-28/rust-std-beta-armv7r-none-eabi.tar.gz=b50984f65ee8a9e8c1b62158d8e91cb976f7c36f6ebc3c70ccfcab2a3da26533 -dist/2025-10-28/rust-std-beta-armv7r-none-eabi.tar.xz=0227fe58cacca86a04d85860a1de852a29ab9ac1bfea7bc50c2f560b73951d8b -dist/2025-10-28/rust-std-beta-armv7r-none-eabihf.tar.gz=da5e26a7cb5b91d3b8ec4f1a02c81b0f538dbb416e10e9453f3fd9d5cfc08129 -dist/2025-10-28/rust-std-beta-armv7r-none-eabihf.tar.xz=9132e8a69bf5dbd144def8bc647c659304fa785612a0f68f2e1a2df5dc195e33 -dist/2025-10-28/rust-std-beta-armv8r-none-eabihf.tar.gz=a312253ad16ccffacd0d840cba85d290fb5d2580865de99887990eff96f58b45 -dist/2025-10-28/rust-std-beta-armv8r-none-eabihf.tar.xz=474813a75bd586e562cf76705bdabf37a915cda6edb45afe029cbcbe54be3cb5 -dist/2025-10-28/rust-std-beta-i586-unknown-linux-gnu.tar.gz=4be0898bb9da3e8d75cb9b4851d5119efdd3136eb10cf31a42109f188781b6ea -dist/2025-10-28/rust-std-beta-i586-unknown-linux-gnu.tar.xz=5a51fb1f2da0dd645c1eb6ce19f37f16f356042ba176ab109f8bcd4ad3514ad3 -dist/2025-10-28/rust-std-beta-i586-unknown-linux-musl.tar.gz=96f621043d426d00f6baec72f66db5d91940215ba3e6985bb823c7b02acbd7ff -dist/2025-10-28/rust-std-beta-i586-unknown-linux-musl.tar.xz=2e62b9a670e3ca1d892ab18da1cd4b2bd946395e35c3b7829dd4b03726a73e4c -dist/2025-10-28/rust-std-beta-i686-linux-android.tar.gz=6c3b0e8796cb87e1a0369b55a91e49d5129af929deb4b63a623cf68219679543 -dist/2025-10-28/rust-std-beta-i686-linux-android.tar.xz=682747e9ab2706e90b5071ce13e8bff21160987d42ed0565f8e0012acded5f40 -dist/2025-10-28/rust-std-beta-i686-pc-windows-gnu.tar.gz=e7afe1e6ccb84fcf03114a6a3fd7232b40d7b2005f31a00a02d9c8e092af8b5d -dist/2025-10-28/rust-std-beta-i686-pc-windows-gnu.tar.xz=99d64d295d7bc0befe84a1da5d888de3ee0daa67a027c8628f78c36ab53eb7b4 -dist/2025-10-28/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=1b36e3979b73348b46a01961a2515bc6ae19a54924e63272cb1bca709a07bcf0 -dist/2025-10-28/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=f579f144f9f653df8be318e4f5ba363116a538b840030d3cd5305f87e03b9e23 -dist/2025-10-28/rust-std-beta-i686-pc-windows-msvc.tar.gz=79de79f2ed569a93dcd57aba35c7995582dde8b633bafbf0fc43ab6a8fb9d152 -dist/2025-10-28/rust-std-beta-i686-pc-windows-msvc.tar.xz=8c3fdbeb815085aaa9d484f1b22d0adbcc829a88511df5930bb518b139d20801 -dist/2025-10-28/rust-std-beta-i686-unknown-freebsd.tar.gz=d25fbb684148778444743e9d651a6d36dc4527d42367bfa67eebc43200e6cc0f -dist/2025-10-28/rust-std-beta-i686-unknown-freebsd.tar.xz=32c6d84e419a72cb862294a110fc79a88b123c4180a3a64bd53c38b200c60f9a -dist/2025-10-28/rust-std-beta-i686-unknown-linux-gnu.tar.gz=577cec0f5fb83cd22a9256dcf7c74529d95572976f102a8a63eb1cb9550f0a6c -dist/2025-10-28/rust-std-beta-i686-unknown-linux-gnu.tar.xz=dc537d7c09efaeb054d2954689842c813b5e9d646fcad912005f4b10e137181d -dist/2025-10-28/rust-std-beta-i686-unknown-linux-musl.tar.gz=5713f1784a424f509f47f70e0bce2bf8ae82e1a16efab8cd771677988b37516b -dist/2025-10-28/rust-std-beta-i686-unknown-linux-musl.tar.xz=1a3dc46f4cb4e4c8e4f96e9835b1188242addcb7a5a8ebbe3ef614c3aef862c4 -dist/2025-10-28/rust-std-beta-i686-unknown-uefi.tar.gz=4c32dcb28c1fbaeb910c9c7c60ea7dfe50e6556663eb3f002b66ec3ed42bd7ed -dist/2025-10-28/rust-std-beta-i686-unknown-uefi.tar.xz=1683c1c2838a2693b2f08a9daf0626675623d6bccbc4c996fcda8489eac853a1 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=401945e68f2246d1f502d4ac63666d5443ca7fa2f81ce38e76fbb0647fed4643 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=9b8d7d2f8a4ebf1369718d8bd3ae6973c977cdcb7030ccea0542f9e28970c281 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=ae351e8f921f0c3b8bcccafa0c84402e15ced7591debf82287e63bac0965801b -dist/2025-10-28/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=7d64ee15508ebb610abe61e1aa03607140302fdbe41200e82070be85312d4a07 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-none.tar.gz=9f951f51a32a4f037f3548935a07208e14f3e67d29100954ae6fbf61a8e56c06 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-none.tar.xz=80494d9d9e02d7a6f56a638d93253d087a4edb83d4662b4771bd1d5c2cba97b3 -dist/2025-10-28/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=f23fd6331ba600a3a4350565ad11f51129ad13a248f35c37b9d485fab725b4ac -dist/2025-10-28/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=03d765256191ab9fac9f37102fa4252f7efb05261c8d2464745826232351dcd7 -dist/2025-10-28/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=509bcbeb245d69fcb828bf9f3fa4413d1d4d59a0e85ed28c4f412929c734aacf -dist/2025-10-28/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=543aa41bd2ae544c0114cca0e5a50c15eb7ed78d3d132bf5b48f93f2f92b502d -dist/2025-10-28/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=d67670d0b9385f4433635a473548031d083fe14e1a407766fb1ae5c4762da93e -dist/2025-10-28/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=e2f403936d191b38347bbad4e9b9bd66270b23e9df238ba9b5d52f81aaebfdb8 -dist/2025-10-28/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=15ef51a8fc10b2298db444d68130ef350414722133097d670b8106e8de68609b -dist/2025-10-28/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=515151364a93fc458ab5f11831797d2d708b22d9a71c78f717cf89e4e593417a -dist/2025-10-28/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=8ea0204c3ac93828c5a72f671c12167d0b5120cde99bb797c8d839caeb3ba3d8 -dist/2025-10-28/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=138969d2a43b6c4d736a950f8ba5bc0ed5fc7868c7044623d389d8278727e759 -dist/2025-10-28/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=a3423e7917b59232faaf855ad9b9cd3b23e5d2188aeb8636e2cef324d405beb4 -dist/2025-10-28/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=36914d3ce6a2e5a56a2a394d2c5a461a7c8a40fc235b3552a658ab1ed7d786f6 -dist/2025-10-28/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=dbc0b69f7eba79726bc08a0a6b357f9d818623d3cbe153dff5f2fcb31aeea61b -dist/2025-10-28/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=39def1e42a80080159347b5e85bc666830a3a346c9b0e83eea8207e94659ed94 -dist/2025-10-28/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=7aebf847c08b0eee42c77da8defc6b30439f4b6d29e4122802f02d029518a31e -dist/2025-10-28/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=35c49b2df4b3e18e0ec8ac20ec8b9a4a81b69f026921d85a666e0a97a671045b -dist/2025-10-28/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=b10e9e0a0457db1441a9bfeb3c4b9a8b2af4d33518bc58a8ee1d3fa7546c0bb5 -dist/2025-10-28/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=8e210b59b95b3c8db109d978ea73a540478315fb49d4515ccf248aafa7517617 -dist/2025-10-28/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=e2bfdac9e858f144db5e9ae79b494f1e09b2a012b18f0eaac96ce684a6a43e25 -dist/2025-10-28/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=6d2f5e60af9f6824fe2078a58a6cb804e61116e4848e1502289e08b0b9a5196c -dist/2025-10-28/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=382f448ea95627ee9fbb3d42c32ab9ecffe21ea12c00810e4eb8e94553d463a9 -dist/2025-10-28/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=ad7f534565c1b97495bf29054c202d8fada0a0ddfa0cca110c14a8221c654cb9 -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=7c8cf6afaa4edb589259dcc61ec5e1e667a5deeace8e277f752a433f20bcbf8d -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=8a396e9db63f1352bfde7a0d51446dabe6873c9a0a46e3c74f59ee775092e2af -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=551d398055ee522ec4a67a9173daca7a1f0f537ab006383ed2ada6b00cc81cbc -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=cf08dcb74f961bff041ad52efcae0c8e239e6439ecdcb32f869eb57b1a3aea1d -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=fd4e49a23ea0d512ed32bbaaefc1e5ea32c837e9a371513b94643966afabc521 -dist/2025-10-28/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=10700fa42e00a3b58ddcd664c0179016b837b43a31476fe4c56e8124619e4a22 -dist/2025-10-28/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=ea2f2873255dcc73185490b2c396abb4bcd5f1623f7749f77885426f753ce29f -dist/2025-10-28/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=7c02315d003cf65ac1246e3ac21b6da39cb1d99e61078ba9941647ae48bf9aa5 -dist/2025-10-28/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=008321f0ccd9b96e77829b709c2683c0053acbb19ae86f2fccef49c2cb964531 -dist/2025-10-28/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=047db35903bec7fee6c1d9deee5b4dc21db546a06e11c30d8372ffaf09814c59 -dist/2025-10-28/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=19677dc6495a139eac6c5827cb765e54e3b099d64f83e92273190f09ead7dab7 -dist/2025-10-28/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=d5815d1eb4906a442da0a0b56fe61cf94767dda29479da447d94a23803f9cf0e -dist/2025-10-28/rust-std-beta-sparcv9-sun-solaris.tar.gz=184424d0d18c2c49ce1c819e49804d7667edf2bce34fafedd4eeb6d4f427ae5e -dist/2025-10-28/rust-std-beta-sparcv9-sun-solaris.tar.xz=30ad3f9e3eaf48af0eb700d528b330118ad39f221a7beaab1a42e52b1ffa8531 -dist/2025-10-28/rust-std-beta-thumbv6m-none-eabi.tar.gz=c9a72ea7a13651f1b9bc6e509d9d6d32e56a4659d541e20f571ef9f6dd858480 -dist/2025-10-28/rust-std-beta-thumbv6m-none-eabi.tar.xz=6dd3a25ee5060cdf4631d8b0b7f16aa569bf611ef392d93826e88846053779e5 -dist/2025-10-28/rust-std-beta-thumbv7em-none-eabi.tar.gz=ccf8d09ba0bed60fecc775689649f2de31bab68cff273d796378d213c9d1e44a -dist/2025-10-28/rust-std-beta-thumbv7em-none-eabi.tar.xz=b7a972a9b972a2e0665387cd825491bf0ee9581ff26a586806c986014f0ae742 -dist/2025-10-28/rust-std-beta-thumbv7em-none-eabihf.tar.gz=26baa00580268fb5b7aba63a069c187dcca43dcf29161a0c1b849ef3765bbbda -dist/2025-10-28/rust-std-beta-thumbv7em-none-eabihf.tar.xz=dcd67a3ad1f2c553fb90009c630a8edcd8f571e28e5fcef0ade63c624fa11037 -dist/2025-10-28/rust-std-beta-thumbv7m-none-eabi.tar.gz=cef72caa89fcd3d48c070b1aae2fe85f29547c9b615446af2d51767ef42b5045 -dist/2025-10-28/rust-std-beta-thumbv7m-none-eabi.tar.xz=70ad20d0016c6c81b4526ccf89bbd96f4bc0a97b904b2c06487fd0a0368d7a17 -dist/2025-10-28/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=f22aeb9cdd40a4a465525fca7e6520aaa74b5fbfb41f45777e1376742f711c59 -dist/2025-10-28/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=48410a5a2f05c80f3d76b9f0b3e0eb89521495b273a854b40386048f27b553c2 -dist/2025-10-28/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=a791f5442467819c154f943c3126de1dd8f5fdd6b62527aadd88260ecb8c380b -dist/2025-10-28/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=cf43ec766a353cad48150d47d108d8df4b1561101b2c95241b909d4a5ec47bce -dist/2025-10-28/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=3699e5b727abc016ab9fa78f40655ef7d88ff157e46759297cd80e5c169136f8 -dist/2025-10-28/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=a6942c04a569f68cf1c5126e520400c51dfccd9e18a1d3941e28d7a8e63ae648 -dist/2025-10-28/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=eb27f46d3ee51e4f71316a75087d4ca2493f55ed5e0b720f0dfa3564c8f19a67 -dist/2025-10-28/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=f50b7fa2830844fd27041ced4c96eaa68ae6595b370eef1c958e3542c718d5aa -dist/2025-10-28/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=398556eca8a50c1d905ef7e2bf3f25d75f8dcf1d9b679af87b565f5f58af5c2b -dist/2025-10-28/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=8dc4a5036cfda5725120a8d7e7d0cd05151230ed967ff77fa028c4b73dde6885 -dist/2025-10-28/rust-std-beta-wasm32-unknown-emscripten.tar.gz=212f761263b9a4c72a53aba0b76986f70b3d624557f34d36af2e7d935702359d -dist/2025-10-28/rust-std-beta-wasm32-unknown-emscripten.tar.xz=89c0dae14955afab89b8fa2892944325ff154987c863fd36f93089f29ef993b6 -dist/2025-10-28/rust-std-beta-wasm32-unknown-unknown.tar.gz=92159d52588bb1ca6346025f894dce5520b42d89cb54a78a3ff42ee119c1e90b -dist/2025-10-28/rust-std-beta-wasm32-unknown-unknown.tar.xz=a187e36833f587ad5f117b012a5d9ddacb3122b39b902bc2a9d9d03b5aba27a2 -dist/2025-10-28/rust-std-beta-wasm32-wasip1.tar.gz=fa8971fcd7c22f5d382f4239fa8742238ec967f70fa40180ac9d8a39bffc28b3 -dist/2025-10-28/rust-std-beta-wasm32-wasip1.tar.xz=0603acb7e6fa5540fb458cf363fe473889b0abba91ec0c124ce380ffb1869cbf -dist/2025-10-28/rust-std-beta-wasm32-wasip1-threads.tar.gz=7651d409d4a89dab576cabf51cdd2947f877b77f09f668c6f9b8826dccd5c322 -dist/2025-10-28/rust-std-beta-wasm32-wasip1-threads.tar.xz=a6c3bc7f7f2e6a4cee6db2aa16f74af80cdd17ca92dcfcb1ab1e0c06bbaddd79 -dist/2025-10-28/rust-std-beta-wasm32-wasip2.tar.gz=77537c7a4518e62cb592e5e9d41df02d1ec8a3038b87cdfe082c98ae578973d5 -dist/2025-10-28/rust-std-beta-wasm32-wasip2.tar.xz=794a3c2e08edd74b7a004489017172c30a3242f7f0c5538c3b033937787da332 -dist/2025-10-28/rust-std-beta-wasm32v1-none.tar.gz=746ac6eb726ea2d2996b68be881d5c5fbeeba2bec1fbe57e6c315d4953cccba1 -dist/2025-10-28/rust-std-beta-wasm32v1-none.tar.xz=8bdbcf0cc2b598cbb2098f113128e6f94085dfdaea3ed3d5e15cfd0a82262b56 -dist/2025-10-28/rust-std-beta-x86_64-apple-darwin.tar.gz=2082bcdfd0e837163aec012cba1ae674825f52f5891c8cf3d4d00c619d5bd27b -dist/2025-10-28/rust-std-beta-x86_64-apple-darwin.tar.xz=b2267e0df76f21bcfbb55ab323c58015501d3a3060c4127a005e29fa0e628a7b -dist/2025-10-28/rust-std-beta-x86_64-apple-ios.tar.gz=6a48b60d0aa883ffad612a657d9de232ad1df92f937a5166532a7ee4e655fcc7 -dist/2025-10-28/rust-std-beta-x86_64-apple-ios.tar.xz=81ee2cdad7fd25b56be24d919268d0dc61c1d44d50bccb4c1811e30e85b97869 -dist/2025-10-28/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=01d5952f0970508064fa24196e126cb09aca5085ad6258c53397c3b23b006217 -dist/2025-10-28/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=3c10717be0087060ffb0e5b83c86ce69bff8b0dee9dee95b1be6a44f4238b5c5 -dist/2025-10-28/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=ce87a282ea73eb83015a321b208abfa9d4afdf4a797c799d9efeb1a246e4a64d -dist/2025-10-28/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=5c8866ec1cb4ec7826a94510c00f5cbc7f31822dd7e01ec2fe6b781b25e2afa8 -dist/2025-10-28/rust-std-beta-x86_64-linux-android.tar.gz=19538e0dd74d638b3ac1ac9ed679b8ebc6c058f661d7f167f957eb0866f7cb65 -dist/2025-10-28/rust-std-beta-x86_64-linux-android.tar.xz=15554ba8cc8d1d1c4c46e0438503170aff5a5519eb8bedef07a32d187ca32915 -dist/2025-10-28/rust-std-beta-x86_64-pc-solaris.tar.gz=41a6db659dff188414e33595448dc9c2b99103dbbdedab53d74c6aeccbb76458 -dist/2025-10-28/rust-std-beta-x86_64-pc-solaris.tar.xz=2bbcb13b8271c39a48ac2774e7444fdce883a283622400085623c161f8be405d -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=e2390bf5da8a91f056df7133020d053d5d90c84c81763738efe8a862864318ae -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=5d6fb692f2a1d2bad7b550b79e1288223ec598a46975848d07f2a5105b36cb4d -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=30c66f64c7343388f3205e172e64e51dc2930214fae46eb3b21648285092c944 -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=25788901f6fc13a4963bba4e985d619e0739b1239a5679406229a2bd5eaafbaa -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=9fab4a6cc38c2f06113ae9f0620e40ff5e9134f83562c32576c1e82048ad3bc8 -dist/2025-10-28/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=1b7007f9bc3619cfba09bfa92c3b1e5460316501fee4ae7c8492703a79517f4a -dist/2025-10-28/rust-std-beta-x86_64-unknown-freebsd.tar.gz=461036ed77e332851e88fb6f0f5c64068aef0b177b27662f326d157c06c7115a -dist/2025-10-28/rust-std-beta-x86_64-unknown-freebsd.tar.xz=fd7c7b75a50833650f131a6a676df90dcd57c4784654aee12ce594846da1c219 -dist/2025-10-28/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=882fe895b376384d9b1b1d9c01d9b641ab56b1405d63d7a83266f228b4b759d7 -dist/2025-10-28/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=e9d1fdbd0ba327b6d4e618622c0336eb6895e0e188005423710d514e145baac7 -dist/2025-10-28/rust-std-beta-x86_64-unknown-illumos.tar.gz=aade9f95b362cf13ee48e1d7608eb8487229cf86cc72082afe21fef533e45f5d -dist/2025-10-28/rust-std-beta-x86_64-unknown-illumos.tar.xz=de92c9cf00a2413d5481e96e1db5157c5cb3814851951076e4881b9269651cb9 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=04f6feb37de8305d17e7aacc6174395bd55447340963303767c5a66a63200149 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=2838910a0ef0084245a69fefdc67845ea579f49629cd24fa051b4db0bdc76d98 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=d2f88d608fdccd0aecbcd83cc184d157d93159e29ad525583188013f327572d1 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=b5e7ae18377727f93fece51d9ee5704ffd5a9ccd00c540b38ebbf3b9155cf20a -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=40a52cf3527090a12095b0ed4ad8d35fa5e3cef39146a9a8bff9009cf5772dc1 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=28be865d06f9bd744aaad2e82ab8bdb87045e6e2d7ee6fceef2024fa620ba920 -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=e0afdd5422adac97fe8c6943470a8561847a614d3e367cb983f28250c0e2e34c -dist/2025-10-28/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=3007d13a0640d915eca622260c6b8b6a8936788a1228011b90df817b6888155c -dist/2025-10-28/rust-std-beta-x86_64-unknown-netbsd.tar.gz=1744c2485854792601518dcf7855d4223db63e9f3693e2d06c1ac285b92ba33b -dist/2025-10-28/rust-std-beta-x86_64-unknown-netbsd.tar.xz=757803d3cfb8db12dd7c9528852c1e28fb3a9ba97e4230d1e29dbf1834cf3f84 -dist/2025-10-28/rust-std-beta-x86_64-unknown-none.tar.gz=21d5de489cc22d849f246225909278f123483a446e1a3c68b14b8b992c104082 -dist/2025-10-28/rust-std-beta-x86_64-unknown-none.tar.xz=62755ecf24c0a2423b4d05c09ec8e8d38737e6762312d1ba993e1a9417083ba9 -dist/2025-10-28/rust-std-beta-x86_64-unknown-redox.tar.gz=0339d37d857f7f5ecb1607e8c53c499623f0c3563e3b68f2b939ee960d31b270 -dist/2025-10-28/rust-std-beta-x86_64-unknown-redox.tar.xz=613b5ca94e5c33c46d9f29cb557d1e512abd1104c5d81f1897915f6153175cc5 -dist/2025-10-28/rust-std-beta-x86_64-unknown-uefi.tar.gz=1da6167f0a2652b1622cae5ac815d55e307dbd639e4901005a3b225150dcafa7 -dist/2025-10-28/rust-std-beta-x86_64-unknown-uefi.tar.xz=6fca79a15c1ef9f8a3974f84af805106ab453099bdb6f652f584abcd7c8174be -dist/2025-10-28/cargo-beta-aarch64-apple-darwin.tar.gz=e66d076303fe8010c27fdbf8a9e31f47223508a280cd2ffcfea698aede848986 -dist/2025-10-28/cargo-beta-aarch64-apple-darwin.tar.xz=f4e87741a4070fe5bc4ad59ecfd324785cd9a477c539543d6a4fc1675afa8111 -dist/2025-10-28/cargo-beta-aarch64-pc-windows-gnullvm.tar.gz=5e9213968960bab07ad28408563b46d01c1d881c26ccd07651bdb527440461cb -dist/2025-10-28/cargo-beta-aarch64-pc-windows-gnullvm.tar.xz=ec01099da59fab595f8ed8a2f6fb308fbaaabf563cf50c103d47fad4595d72ec -dist/2025-10-28/cargo-beta-aarch64-pc-windows-msvc.tar.gz=ed3cd99db73648bb87c5a25556da30993346f1acc665f9dc906094639370282a -dist/2025-10-28/cargo-beta-aarch64-pc-windows-msvc.tar.xz=c5f89cae65188a7d1b5b5a93f8645774f878db6a14032abb8fd960fa9f4cdb06 -dist/2025-10-28/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=2c85f1c5b1a8bb9532194a16ceb8b04f1586d0ade14442f45e740f3e85022924 -dist/2025-10-28/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=a675601cf6552783625b79c33c1d42715c3918a08078e6eed01236910bafc4b4 -dist/2025-10-28/cargo-beta-aarch64-unknown-linux-musl.tar.gz=e5f2cc9f31b927e2e02117c38a5822c39993242459a057c48e7e11695dabe5a5 -dist/2025-10-28/cargo-beta-aarch64-unknown-linux-musl.tar.xz=1830b8b7e43fc03f0348503ae036b30d0e906cb024bc2257e717a58df95ac222 -dist/2025-10-28/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=eef6f553184a8177525a1ee932d6e293f42eaed6986c1c83f7d76d579f02b867 -dist/2025-10-28/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=13c81e5874532e490c987dbc46b19cf3a7eac14fefdffc30d0c5493a84f8a257 -dist/2025-10-28/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=56d7f1b41af4d72091c8a99b9a583f24d5aa3912f6dfcbfeeae4eb47bfbf158e -dist/2025-10-28/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=010292117dca5b10b71b7aabe38d1e8c2f0180ab54e9bf072a9ca8bab3f40ced -dist/2025-10-28/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=91671bdd6438df48e4c529e5897afe57b91e8575c12d40c3cb3280493599c0d9 -dist/2025-10-28/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=0da8474db35ef547b28f123e8c98ec84dcc4a4a5c4a487a222ac006e809ceb80 -dist/2025-10-28/cargo-beta-i686-pc-windows-gnu.tar.gz=5d9ce7ba82e8d694e53ac877214c0873b0dd78a60c8eabcfe9128433d199d12e -dist/2025-10-28/cargo-beta-i686-pc-windows-gnu.tar.xz=209100fad49e274457d8299360a4c2e83803411a69fec69898a03d9a2bdee955 -dist/2025-10-28/cargo-beta-i686-pc-windows-msvc.tar.gz=edca4ca03b055b40d0c4778e325b93e3759123f207a6d32d7ff42cfa0f323604 -dist/2025-10-28/cargo-beta-i686-pc-windows-msvc.tar.xz=5146440d030e04450de61bd6022cd7ad6364fd06f9cec28bbb7889bad171e579 -dist/2025-10-28/cargo-beta-i686-unknown-linux-gnu.tar.gz=d1045ab266d914060e24224b0e74ea865f4bf4cd527d9a09c5631441c40f48a3 -dist/2025-10-28/cargo-beta-i686-unknown-linux-gnu.tar.xz=caed7a0786cc9f476d1b9fb5367c67a02397ccb12ed18a357b5ed04fe77fb12f -dist/2025-10-28/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=017335d6ca97cbe4bf93e2ffb4def850b05a8efa0367b008de4cc8b55f1af3cf -dist/2025-10-28/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=f5671ec0dee9841d4a482183f56ccb986f358a80d043d1ec4b05bc8a356f8ad7 -dist/2025-10-28/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=0a280ebc1b5aab8452f1445fe858ad4808fd7035dd498510951d8b7caa13edc8 -dist/2025-10-28/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=8ab41df2264470d6ed0a6d82b665992f76f9065046a153bc8ee1eda9ca81eaae -dist/2025-10-28/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=7368d0d297fa06108271b03138a9dda0cfbdbe5463a614ebf6fb5b573dde08d7 -dist/2025-10-28/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=1ad0b7d4e3173150768db7105b1a691e8c85db3e9c6a391390e2f5df7844d420 -dist/2025-10-28/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=75740d0b1847f73777894f484e085f70f24d981b0ef69d00cb5b0c29d276c5b5 -dist/2025-10-28/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=1ca71e60a6fa9752dd27bfe4f354a1b732b67e55c9e645021e6041a2450b7994 -dist/2025-10-28/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=ab37e6d39ccb7fe33c55bf62836c2174f1a4197f02cbe9d88d118b81ec6d49e2 -dist/2025-10-28/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=77cc38c5b89fc65fb7453dcc3c3212e0a512923497420b7782ffbfd88f00b39f -dist/2025-10-28/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=29a2dd23fe30b2d1741e1d4032d4250b4f7f0e2af5ae718b309f2d271e13ef41 -dist/2025-10-28/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=bac42c5d4af02abbb4db1a9dd4664340d686e4c23f923f372d3b08e090bd105c -dist/2025-10-28/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=3b396bf0ddede9f4964bc9fb27b52e628db1d9ccc38dbc5d5e06c316ba8bef87 -dist/2025-10-28/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=e706521e4496c79bb677d7d06d79fc1ae2770cdba4a81d8c28ede81ab4ee7909 -dist/2025-10-28/cargo-beta-s390x-unknown-linux-gnu.tar.gz=2fa6ecf04d1cb20dde5f700a0e425ea186d628c5704885e84e197e4494af101f -dist/2025-10-28/cargo-beta-s390x-unknown-linux-gnu.tar.xz=e8810699e679fd0306d4e6c95608970ec5a1d1ccffcdd707fe4a4508518a0e6d -dist/2025-10-28/cargo-beta-sparcv9-sun-solaris.tar.gz=2fcae7eb2f538d84545944c744bbac39e28b3bd58e8d2bdc862d5f66df7068e7 -dist/2025-10-28/cargo-beta-sparcv9-sun-solaris.tar.xz=2fe42f27469fdc23a9e45ec025c60a09f00be07a239cd8c8df74ce52e94b4cab -dist/2025-10-28/cargo-beta-x86_64-apple-darwin.tar.gz=c92c1a580eb85d96f973df4dd9cf4440eb661f8fab9c632b5f0621cf0839badc -dist/2025-10-28/cargo-beta-x86_64-apple-darwin.tar.xz=6c2b13253e1066e49fc52f3cb1654776d5d38853a15e8022652b4a2cb6845daa -dist/2025-10-28/cargo-beta-x86_64-pc-solaris.tar.gz=ca98af5dcaae734ccc02fde2807dca8d95947918eb753d407c12dd05ae937568 -dist/2025-10-28/cargo-beta-x86_64-pc-solaris.tar.xz=864ed5842890359e9f767b4050b8a27ec9c27c88a8cef20993b8f775c213d394 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-gnu.tar.gz=ec8a9e8436f83388736f16f7ad9962a1d9b72673c3da56b8233a6b39dde54534 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-gnu.tar.xz=1f059aae8e6faedcc56663d833a07417e07eededdc2776b2762822987a010131 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-gnullvm.tar.gz=f364bf2f20f35c7ff0381cbd34c88a256849a1b9a27267436e14bc01b7bacfbd -dist/2025-10-28/cargo-beta-x86_64-pc-windows-gnullvm.tar.xz=451f18d049f1c47bfa0c010481e499afa1baaffb889de11534cf451578c62f76 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-msvc.tar.gz=96ca48b12b27b8e933cbb426e7123873a1120bd884a62d150aceb6a26bfc7694 -dist/2025-10-28/cargo-beta-x86_64-pc-windows-msvc.tar.xz=dfe14d019f5c1744a312da8d926059147974de0b5bcdcd869526b5257a1112b3 -dist/2025-10-28/cargo-beta-x86_64-unknown-freebsd.tar.gz=7ef3d3edb6b536382f5063a5de5aaf036d6ba09bf7bd1ff770b87d8942110c2a -dist/2025-10-28/cargo-beta-x86_64-unknown-freebsd.tar.xz=beb5587235e8ff471a8eb9fd84ae5cf4380e7ec9b00ab03dc0c549be0e661dd0 -dist/2025-10-28/cargo-beta-x86_64-unknown-illumos.tar.gz=b97f511486ad044dae0c8b50df8430e489887ac36b770155f163d8e4216cd9c9 -dist/2025-10-28/cargo-beta-x86_64-unknown-illumos.tar.xz=21fc84a42fa988632fb9b0d9dccdf6ab2fbbd06a6780076282fc9bea56567559 -dist/2025-10-28/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=d5b05dc398716909df77415b4a68233b68a5d578855e0e91dcf423f2985fc1cd -dist/2025-10-28/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=21e79bba772e93a6fd910e9d6ee833b55a53b80088f8280525717a4cd800c21b -dist/2025-10-28/cargo-beta-x86_64-unknown-linux-musl.tar.gz=4d126f2591652ddea26884973c1ae1f1e25246cc5f60baeb3a52d6ff45a1aa15 -dist/2025-10-28/cargo-beta-x86_64-unknown-linux-musl.tar.xz=62113a7383f7ff8a9bee099155ca55c3c69d16bf135fc06046f672b2102deafa -dist/2025-10-28/cargo-beta-x86_64-unknown-netbsd.tar.gz=e9a07f035f308d4b9cf5f1b0ab4ef969cad1c41528adea2fca81d8dfe45ebff0 -dist/2025-10-28/cargo-beta-x86_64-unknown-netbsd.tar.xz=3f3d87269072d8e219e7213ca878a7fd441aaf74e4d052ca44ccc7ad75e83eee -dist/2025-10-28/clippy-beta-aarch64-apple-darwin.tar.gz=a44daddb30309be19856b9572679569ffc2ab2c30318706ad59aa2dc14887587 -dist/2025-10-28/clippy-beta-aarch64-apple-darwin.tar.xz=00576ad0f30db5be96e6434e22a2fcdd167067d65ab85199df06a6d11d1ef6c0 -dist/2025-10-28/clippy-beta-aarch64-pc-windows-gnullvm.tar.gz=24fb3dc6680e845c84e535f9c14be5e3d4052ef3ccc800e0fd81815edccb4836 -dist/2025-10-28/clippy-beta-aarch64-pc-windows-gnullvm.tar.xz=20d2ebdb6e2a902eb74ad502a14a2a66e6a9316d5f94513ec9781d146c323d9d -dist/2025-10-28/clippy-beta-aarch64-pc-windows-msvc.tar.gz=652e5bdffbb89ba281cbd5efe3a2cf103adea6af7ba56a21cb6bb538a2ea6536 -dist/2025-10-28/clippy-beta-aarch64-pc-windows-msvc.tar.xz=59d0fb72db77c484571ebab8c992303659225735d3f820ed7048122d8f96d764 -dist/2025-10-28/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=6bf6fb7279ecf5df6edca6014db5f8ba0427fd8cd32f073630b6b02e2e69feaf -dist/2025-10-28/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=0a8d19bca62dc38e64cf527b239106901fa2e0642ca5c2ef1cde070faaa901b0 -dist/2025-10-28/clippy-beta-aarch64-unknown-linux-musl.tar.gz=663581dbd93b22b3b20d281486c8dc0580e43ceca42d9455d78f2d2c341cc758 -dist/2025-10-28/clippy-beta-aarch64-unknown-linux-musl.tar.xz=49548d8ee0561ab96629e354ad055ed5f0c6f3f60c1559ca2a27352b441ff848 -dist/2025-10-28/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=b3d44866b1f909576e0e586aa34b480f1170aa3eba28209ac5bcb929f544d07c -dist/2025-10-28/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=717397166acd760e391c251b1c308657f45deadd928035d2860c772c8b377b91 -dist/2025-10-28/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=8911fa3347ca26a2afed6140bc4cafa629830740b8e4ff5e648c517f6ea43c6b -dist/2025-10-28/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=e7360c728068520ec7bd712d57357ce30bbfbb629ec69cfdcf6596002751d93b -dist/2025-10-28/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=6d94df05e43804f1054d17542db72cfd3f2df27eedc275c810b35362f9d581c1 -dist/2025-10-28/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=25c33744d9722aad4f9fc80674233d16eb653adb17d0deadcd3be8f16a79ecb7 -dist/2025-10-28/clippy-beta-i686-pc-windows-gnu.tar.gz=dfb9ba0cc842b7c92f1dda8bb88bd1db9beeac746c3ca3d144dd4d66d91ff6ff -dist/2025-10-28/clippy-beta-i686-pc-windows-gnu.tar.xz=20f3cf3fe6b52b8f54391be7edd11331a376313c37b674f4987589f50eac68d0 -dist/2025-10-28/clippy-beta-i686-pc-windows-msvc.tar.gz=bcabe1f7679e1ae416c7ed56afd74ad224ff47cd9b5413dececb0e6f503ce393 -dist/2025-10-28/clippy-beta-i686-pc-windows-msvc.tar.xz=f8ebfef39e7119b45a4f714e91b47964aeb6653fbdaf9b01786ef629cbaf3d31 -dist/2025-10-28/clippy-beta-i686-unknown-linux-gnu.tar.gz=f0fc318e90de4f45f6ca7d0d6ca3ed5d044db75f97254d792cdea9a7b196042e -dist/2025-10-28/clippy-beta-i686-unknown-linux-gnu.tar.xz=27c9adb19a7f84edb19ff4c8ce34dd836fb8d10e8786999591e41ec9c60e4602 -dist/2025-10-28/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=04673347c7e13eee9e301ffc1640ce7a5ed733915c29d90750706829d6b02884 -dist/2025-10-28/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=2484f24346fbbd2d48f69d86ab7710ef65a5952bb5ea0141f3388f616c7d6d0c -dist/2025-10-28/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=656eb1b94dd2324958e6ba0b1c7a37281abe24dac7d87b0e406fc10931ea0d29 -dist/2025-10-28/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=3349952da5d2693554d2e1ae60bb7ff9cd64451719cadf4227095b73377228c1 -dist/2025-10-28/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=40eeba3b2807a1d807ed25c3bc0482d5b91135a769d2281a894ec8cb8bb52a35 -dist/2025-10-28/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=0a6e79cea6655d6b3e1ff1218651c627886d8f06a5d36e9c3bd3c9c45b375f57 -dist/2025-10-28/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=b11f919fce34d70816a6dfa0884e37939c38336bad6261fccf5d67d25935852c -dist/2025-10-28/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=ead91ce4260d07d4e4f950092e94ae224f067ae3c711efe2ccedc9250b2f3dd7 -dist/2025-10-28/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=481a2e3b45751e2d86c30d4fb3897f0a7a18e9eadde2c9a3ad1a8b0259fa2066 -dist/2025-10-28/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=d5d6529cfc89c29443d9e87041a5f93b746e5bc5791016242e2f271be5bcb557 -dist/2025-10-28/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=a70d30948f5e95cdd454fa2b3284b97f29134f59e98e130fc2877781f3b62e89 -dist/2025-10-28/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=8dddfc0b1b2ca8e8866a11a1c95b8601c50150f1e52adbd3803cca2fabb386e9 -dist/2025-10-28/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=bd1b28dd79a52de657515ba5c25063b0b6015eb30ee3b0ee05511567b429c992 -dist/2025-10-28/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=5262011db6be068ef70905a28939b1838a2fd2b719d38d59e80754695049269b -dist/2025-10-28/clippy-beta-s390x-unknown-linux-gnu.tar.gz=6d3d83d03c46e1de2cc6b6f204e701acc9dddb6d4baef80fada9d868b7eb86cc -dist/2025-10-28/clippy-beta-s390x-unknown-linux-gnu.tar.xz=e57ac819f962d9b431b699b40a047d3e2530f76f2670c5a04747b7de11c3d5e2 -dist/2025-10-28/clippy-beta-sparcv9-sun-solaris.tar.gz=7a492d27b49facb9554248935728cba483eb7ecf3de317751a7445c3932932e6 -dist/2025-10-28/clippy-beta-sparcv9-sun-solaris.tar.xz=cc02f4f971b9e5eb63ca65ff6947cf3490101bfb40ea9fb2b310283bb6d10b27 -dist/2025-10-28/clippy-beta-x86_64-apple-darwin.tar.gz=56f11b8ca012467ef6aa8dc3458a5bf45950f1de062a616a01f6c0aae412d0fd -dist/2025-10-28/clippy-beta-x86_64-apple-darwin.tar.xz=01fe53ec63d71a8427fa3220d037313fc31f8d0fa33a64305b01109344aac21a -dist/2025-10-28/clippy-beta-x86_64-pc-solaris.tar.gz=d222cfda8613bba09b0ac1d02fad99c0d081d10733f0f9253d809221ffdda506 -dist/2025-10-28/clippy-beta-x86_64-pc-solaris.tar.xz=918706ee8ed38bf398cbf0dad85333e3082dc461fff2fb2399b96e840dc24766 -dist/2025-10-28/clippy-beta-x86_64-pc-windows-gnu.tar.gz=7764df051100b08b4b4e5c434d5ced1aaa84d9665f6a4401c9ed6350db983b70 -dist/2025-10-28/clippy-beta-x86_64-pc-windows-gnu.tar.xz=4a43dee6ce0279de929566f844fa4987d10fa5ca856bb2a2cbea4327eef3308e -dist/2025-10-28/clippy-beta-x86_64-pc-windows-gnullvm.tar.gz=add2532fe4e8afb8b53aee8a729fde0c0b36f83a8f6a859c39ae25f3d01e8dd6 -dist/2025-10-28/clippy-beta-x86_64-pc-windows-gnullvm.tar.xz=7117f0afc57ac09c277ba99be4a7de80d62ffaebe4174706910d5ab6501ec9f7 -dist/2025-10-28/clippy-beta-x86_64-pc-windows-msvc.tar.gz=e71d45b8bdb5346d89f769b4698b404b293884878a7f697680318c72829c1d6f -dist/2025-10-28/clippy-beta-x86_64-pc-windows-msvc.tar.xz=67be8cf6580a4a6e36eff94bfe19fdad290eae5db598d2a016dfcc7516178e14 -dist/2025-10-28/clippy-beta-x86_64-unknown-freebsd.tar.gz=03b78bad90efe98cab6416ecc641b7da0c9a2be5950edbb4c520c0758cdb90a8 -dist/2025-10-28/clippy-beta-x86_64-unknown-freebsd.tar.xz=056aecae34c8ae10a41516834809d983bd6126bd0374a7bf0857710492f0d0a5 -dist/2025-10-28/clippy-beta-x86_64-unknown-illumos.tar.gz=a67147c647da8a9b68a507087b66610ed19e65b94538b08326b000e66c170260 -dist/2025-10-28/clippy-beta-x86_64-unknown-illumos.tar.xz=09bd43034d7bc1e9ad1873610237f98543751809ebe63d8255813eadf4a00e70 -dist/2025-10-28/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=9397e5c3b1f45ce949b8e3420233e8b86f95a887667c917b8e7615218989820f -dist/2025-10-28/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=5b67e9eb803c180d101e799f6d7c2a6ea7ec07a93a6395b4f688bf2592bc30d5 -dist/2025-10-28/clippy-beta-x86_64-unknown-linux-musl.tar.gz=b255c33a89b0b1bd666ffb584c20554daa3a7c48123de75eae5e1b4cbc53e1aa -dist/2025-10-28/clippy-beta-x86_64-unknown-linux-musl.tar.xz=bc7f3f7d59f9c52370849092541a9368632f390ed9bc88f2566f1e3700f4da80 -dist/2025-10-28/clippy-beta-x86_64-unknown-netbsd.tar.gz=a8f366918520cc5a82c9bcfbb419570e6792712455ec5c04655e6557a657e949 -dist/2025-10-28/clippy-beta-x86_64-unknown-netbsd.tar.xz=dad3555be56e7c8d042f65dfced7915856f9f23cec13a7a633a4aad38c634247 -dist/2025-10-28/rust-beta-aarch64-pc-windows-msvc.msi=943683af0d464ecd36678e1c87b1207a67105820cb3d1516eeebaae450a2928b -dist/2025-10-28/rust-beta-i686-pc-windows-gnu.msi=8532743b3406fbf2926e5c6643300194eaace9de492e7f2ad0caa6f7d040f8db -dist/2025-10-28/rust-beta-i686-pc-windows-msvc.msi=1b3b15aa90c3dca73e9d72d53d214eb3c02b97386c83d8755a03f571cc09de4e -dist/2025-10-28/rust-beta-x86_64-pc-windows-gnu.msi=6249ad7cfcfe78b541e4935ed18dc4cfb10130252885668383a4c8f5046ecc2d -dist/2025-10-28/rust-beta-x86_64-pc-windows-msvc.msi=700f63a1baf0de2f0d1972454486f890af15b3700481698ffb0daf403778390a -dist/2025-10-28/rust-beta-aarch64-apple-darwin.pkg=1f2862fd5dbf8a9c7a765e75391cfffc5a3cd6837066b29f95778b5a346f0f59 -dist/2025-10-28/rust-beta-x86_64-apple-darwin.pkg=ffa2c6275b401c73575a5158911bc53edfece2edc03f6b3f6a140823cf870ee4 -dist/2025-10-28/rustc-beta-src.tar.gz=dbbae9e1c0b5e914b588ba5b659b7fb6af3d5b422831aba028d64b00c7161417 -dist/2025-10-28/rustc-beta-src.tar.xz=aa771d2b1ea8c933444c962c03c384bf2511bdeddf90edcaac8f45bd49f5232c -dist/2025-10-28/rustfmt-nightly-aarch64-apple-darwin.tar.gz=5a5e525f45010fd3e30503f408f21eef78cafa54e42adf9709cff50f6cb29720 -dist/2025-10-28/rustfmt-nightly-aarch64-apple-darwin.tar.xz=b6f92173abde0be1f4f3378c682e42016390e6e5e20df7e84cbd7804a6161114 -dist/2025-10-28/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.gz=430775c6856f4aea6a2b83e245904d5527f6ace134a9375dc7172f77ecd328f6 -dist/2025-10-28/rustfmt-nightly-aarch64-pc-windows-gnullvm.tar.xz=3d14ccf194d04ad5767a5fc3df6f9c1427cd0e282671887d2264b8314586e168 -dist/2025-10-28/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=251f7fa0b78fdad3be1977ffd6a2f563d1524b6423d2bab73d1741aec97b4717 -dist/2025-10-28/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=534cacc40024fec78c02916e7e2d46cde8b8153d303efc1b805af8789f25fb1e -dist/2025-10-28/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=5663e413cd9ae9f403a4b5c5e9a9862c00d57bcd68bde9161c91e852115e45cd -dist/2025-10-28/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=3625b287a83796cb71741b9a4b002eb4517950d386f97a91470c0acd5aed835c -dist/2025-10-28/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=657b0774a95a925eb38d039ef11bc23d15c4733d0b322f172f0b8236bc7410f6 -dist/2025-10-28/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=4e058f11346ec86801bc9cdb830c6dec2620b81fe2cd4b439b275a5145859dfa -dist/2025-10-28/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=820ece81e455d11f65ddf09093b6bf97359cc803959d951bd199c70a79ae117e -dist/2025-10-28/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=8a72a3e715ab2427fc120f8af20d67f722881ee9e13bf482e45ef07f5fb2bf86 -dist/2025-10-28/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=fb583c846e1a11663a1fc525f02c0146dc70e7b4da12c264c8b00cf7927ad9c9 -dist/2025-10-28/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=8a15430000d48b702142cc4569a5eef3aba59c07f33f69cfb6966250fae18178 -dist/2025-10-28/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=c470dd9f35b1b701e8475716e61cfadee5475fa29a2994f407d532a794c0ef82 -dist/2025-10-28/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=774898dd43893b99e4e11d004c52244d78d2fb08aaa6fa242cf1d7070d9ff8ac -dist/2025-10-28/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=31ef71bea5f5ce3668b903fabb1582dc256fe6e2f97e5c23ca468e05f3deb7c9 -dist/2025-10-28/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=232351f0a578f9973b536eb587b2e90cb01ca5f76ad376c09d7dd225c09810b0 -dist/2025-10-28/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=eb469e8475af339d36e1381474f931e326ef1f095a6f56f44730019c5f6422fb -dist/2025-10-28/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=42c5f2e88f81cdcc375d26c4ab6d9ec03b387b8de632af8a3fa75bcbfcbf56da -dist/2025-10-28/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=79e06c14b8f18927b1c24cc4ea97e55a805355137a9bdbe3ba616e334878d85a -dist/2025-10-28/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=3883c297de03da522a20b893f24970305fadaf726dd9388f89196e1f284115e9 -dist/2025-10-28/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=b3ddf283d7964a4c261668df7685bc47b469c7294325f975436d465cb7d44163 -dist/2025-10-28/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=9e63e1bd8b4c52943092e91942737be9b3ee9c128dfbeafdc01d3dc732058165 -dist/2025-10-28/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=83845c5809a9b525655565b3e3b4889e2a07562587c6f046280a44dcbb809094 -dist/2025-10-28/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=533113ead2985a36cf685cfbd6645d43f1a7e2e66b6eaadbde2ff5a72d10c5dd -dist/2025-10-28/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=82c6aa57adb0f03b96982f51edc65aebfac3811cd2845d280b7bf5fb81cbe92a -dist/2025-10-28/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=8f4b3c91072d56ba80ba4702e611dbc6fe66163666e6ee35d74602ef36fe9839 -dist/2025-10-28/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=4fe0b85296e2249b36a0b021d6b82e7c31c40a5f717a5f447b6bf9b9524069a2 -dist/2025-10-28/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=9257bb295a58a7df3fbbda809bafc74a8601618afd0fd41467439a8972278cae -dist/2025-10-28/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=d3a5851060a66a0e027ba142dbdb6e827f4f5f5116b5fdb0b8e86ee56616d682 -dist/2025-10-28/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=fe1e9e4e3a234ba8cb656b08b7bbf5349f5068906cb60a4c5c53f7fe3e214487 -dist/2025-10-28/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=2187f1ccbd4e638efaf9f05566998b579b32729fd9ee4332964a3c54556c3a20 -dist/2025-10-28/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=88526ca6af21bdbc6c46130012cb5fdde25fd44e6372187e66d273067efbc052 -dist/2025-10-28/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=9299c8d4dfc320cf331dc4005c36a0108961a6d5ad750a5b0a6be8c7cda77953 -dist/2025-10-28/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=7da58822a9ba4d65258ca0cd514b9abcc85070baa195ce65d40ed9d9de049049 -dist/2025-10-28/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=e07cc8f1166bb39aada202559c1e2ee9190cf85fc11b4d4abb921cab352748f8 -dist/2025-10-28/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=ebcb49b4ee1e8dded5e6569c7edea1578a369e92aac9030a51d11e95bd8bb8b1 -dist/2025-10-28/rustfmt-nightly-sparcv9-sun-solaris.tar.gz=247ce6a1fb10911b8f38bc8f88617d9a7dd2147e1f1896710b0b610f8bb4b86e -dist/2025-10-28/rustfmt-nightly-sparcv9-sun-solaris.tar.xz=020d64391c730a61f4c61d802b432a463d4909d0e4d5fe4756db4683df6e000c -dist/2025-10-28/rustfmt-nightly-x86_64-apple-darwin.tar.gz=547d7711acee55435e271fca1cebead82045375b0fb136404be7df379b0d404b -dist/2025-10-28/rustfmt-nightly-x86_64-apple-darwin.tar.xz=e8ef4fa56be91b642fd3a8c29afb9dfb3fb7601c8fbd24393be4f3dea1802163 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-solaris.tar.gz=0e41caa314927c9a8656d16b6623c95463a64f07a23941d03597a17582c224d6 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-solaris.tar.xz=d73dcd42d9110befbdf64c46b9e4e8bad07839302cec49e2d8cd99ab436d4bbf -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=8e821c45dc91d5df1b9f8487554cadc4deb86a9ef3db25f4e21b38eab3cc8ed2 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=f98ccfcc37b7412788a546cbafe5f09b90c26f823e3cad17e71432df4ba910ef -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.gz=762e15406bac23f0f41dae2b1b3370458b92e8be771868b4f8f536f53cb26fc3 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-gnullvm.tar.xz=cd87b4a4c2af3edea8ba09ce9bb8704449d8f51c5dee8ba10161e0ce2ec2aa19 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=7de2ee69be5384656024a6d7c3481315fe90abc9ba9a26726f1eab09aae2c818 -dist/2025-10-28/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=16377ae5474e30b6c11ba886579ef13db4039d0b9f43240db00aacf7366b37d7 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=d98fd17080ed5a4fda444719011540a80320001a0b0dc36148f2e3f78e5f5c33 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=c825c2b46f43fe71f4452494fb422cd9565ec6454857835a6c77081553081523 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=8844743cc05351b1f6ba8fb50ac1d86161a285775eb4c0e474308aec71b631c7 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=172dc660ceb00e7003e855a09f46d9f83096773495ed6d7b8b1ed6b9e770912f -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=2710450c26834b07a5eb80bf990dc67a6db89f87e26d6b613ed96116c28958d4 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=bbb8eac454e0ba3b23c9803d8201fa341d0f0af509aa9e8b530c9b98a1d9886c -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=e6bb6a67878c9cbbbbc96f1a1858500403ecc3b8c951366e18ace0f2601f41cb -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=f6509af9551e73ac16c425c53e667382bf7b6b48be65f4779485ee7843e68030 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=3915f1907939fbfcd82012efa4293e7ddf22bd5bf1484efffacb31c805e6cf68 -dist/2025-10-28/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=cca6182ce9f2906a8b16971741a8435dbcf60d9ef6020cc7d6f7909525a73dc2 -dist/2025-10-28/rustc-nightly-aarch64-apple-darwin.tar.gz=876004fa16a6154ea8ea46cd1bb60a06fc14b24e72e26e20e42fde4e32882b46 -dist/2025-10-28/rustc-nightly-aarch64-apple-darwin.tar.xz=0a98f29bb6a2a1555f6ceaa161ecdd2e599ffe879b98bc98c6066e257fc12362 -dist/2025-10-28/rustc-nightly-aarch64-pc-windows-gnullvm.tar.gz=b07b2f7975b463970cbb4a8c92e51788ac63c3a46d3ae6c8cb54c7024161d899 -dist/2025-10-28/rustc-nightly-aarch64-pc-windows-gnullvm.tar.xz=5445b2e30804733fe2a7d07f66a77c2e3ec5e7c71bb55403541b8d365cf91870 -dist/2025-10-28/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=d2cff6b8cb52172f4bb394f8ca891897c774ece1b87f9d30729aa236dfa24900 -dist/2025-10-28/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=a6d0c00367b49654c91d4b71b33819854f628d51b7193c2475b9f737258a575a -dist/2025-10-28/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=c30649c2360aef41d97bdbf76d55bbfe674a1225161bc125a8215d3954656cda -dist/2025-10-28/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=3b204fb1461f47b4e2a79a67923abcf8610ab7ab006ee3f9a70cdc87458f81c5 -dist/2025-10-28/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=949f55697b50db7d70a6465b100ae4458d2f676b818ca7227014ddc9c5f707e5 -dist/2025-10-28/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=ff500cd8f318f0316936af462264254df2aa1bd5a2b368ad3c5758e9079eaf71 -dist/2025-10-28/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=231c4cfa37df03a0e0517843bd115a0f0b13ec259397d6e4dfb4014d3a0d4d9f -dist/2025-10-28/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=50f4d7060d02833949ffc970b88c5ad2183fabd3c498334bf63d87d0c9602720 -dist/2025-10-28/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=f89586ea5bac722a06c225a50d7d603b4895aea89297509f248a1cb51a5cf0ed -dist/2025-10-28/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=0de0552ae68cb9b61f2c5031cdbefae5ccde39c4003441e93c2e4e704d3751aa -dist/2025-10-28/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=019bbb267d1c0520a715287e0a1a680b58dd5e9ece2071f3ebd6f2b1d8eb2228 -dist/2025-10-28/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=069bcd46adfb5e14786fd8aced5ceb74af24cc05dfa2bd41ebd81ac146122598 -dist/2025-10-28/rustc-nightly-i686-pc-windows-gnu.tar.gz=911eb977b10aa4bb1f25124f08f3397fb3ac65f36666865be40bf44259b5d77a -dist/2025-10-28/rustc-nightly-i686-pc-windows-gnu.tar.xz=14ed0abc8708a90e8bbaf0c0de2aec1a4ed60c63b4db00fd4a732f3c808c125b -dist/2025-10-28/rustc-nightly-i686-pc-windows-msvc.tar.gz=8917e6dd4786f0f413908e9db4c92e060bce525f91b9cc0d43b453d26057435d -dist/2025-10-28/rustc-nightly-i686-pc-windows-msvc.tar.xz=86a8580a180de9224c176beb1ada2c69acc37fc73ae0e7c7780bbbded842365c -dist/2025-10-28/rustc-nightly-i686-unknown-linux-gnu.tar.gz=0d29e999ccbc46ff6b0c50a5648e0c5c8f767daa9a0d1fc86dff30c6e0078dd5 -dist/2025-10-28/rustc-nightly-i686-unknown-linux-gnu.tar.xz=bcafb54ca3f587d3cc9302c057da2fbdb4531e2279ef462fc8682e82e1046561 -dist/2025-10-28/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=0a5bfd49a7a2fb98fe06815a2a50d9dc859722da3cc107928e36596c7b8c7f8e -dist/2025-10-28/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=b8ec7898e087577b78ef1b716f8935c7023d740b389234f38075a09b2c7b494a -dist/2025-10-28/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=5cab6709c372feed484b5148ec642cf9767e7fe051146023459467012f2e0b64 -dist/2025-10-28/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=e42a3c007bdf7e8179c597daffc61d7a6bd8eac782b8d81d0b883267bc226f86 -dist/2025-10-28/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=a7cb220770ebd482ff9737d787d04e2e1274c46b7da0809041d06712e27f69ae -dist/2025-10-28/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=088b1d0898bc5b5d83d0fe20edfdadc2d1c0865c39108d11a5d078074aa37a1f -dist/2025-10-28/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=90a3b28ca667187fb18eee8b87f5aebdb2c2e457acbe5b7b088d9b9a39314a1a -dist/2025-10-28/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=4eb8f1d20b2eeb85a2b78d3e28a1d665e1171e1271540bdd8453833818d53c30 -dist/2025-10-28/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=e4fc106d7d4e098912b4dc0ac0211769ecc1f01731e118bf6c0bca33c7ceb9f5 -dist/2025-10-28/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=74bf23136731240e8dac7497d8b1a244fc35cd529d12f77fff308099354f3aef -dist/2025-10-28/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=85ada50366246530a0dcbd462aef31a6edac600d22074d97bfc07321569eafdf -dist/2025-10-28/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=f0cb51df2f6639fc65091608d569b9ac0730f5a8d88e27079d87bc8a8834b1e4 -dist/2025-10-28/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=c37432d8d8db7aaad9132e1301025dd5bf3671bad0ac1fea0f04e9aae238cae3 -dist/2025-10-28/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=57f72896f0309149a4b376a21d56ea28e65316db08065bfe32cdbd750bbc9657 -dist/2025-10-28/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=170776eefa09f01859af0b3694c013ebfab04e9fcf8fb44233593ef4a763bd38 -dist/2025-10-28/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=29335ffe7d88b758ec1a7a067056e35fe8f24430e8d899df3256b4e2d19ac16e -dist/2025-10-28/rustc-nightly-sparcv9-sun-solaris.tar.gz=14b5cfe710c92e8691aaad99de891695ef025638eca065587107c075a31215bf -dist/2025-10-28/rustc-nightly-sparcv9-sun-solaris.tar.xz=d21bb41b4abdaededefd199192bc257424295ec74d482693d032ca67f02dee15 -dist/2025-10-28/rustc-nightly-x86_64-apple-darwin.tar.gz=09c7d0777ea308ad552ea1e958f5c65fa3380c9cb93efa1e6edec3a29fc30b5c -dist/2025-10-28/rustc-nightly-x86_64-apple-darwin.tar.xz=923ef47f5bd9608d277b6636b8c798c5b2760460264fa6f0c0836f317746a89c -dist/2025-10-28/rustc-nightly-x86_64-pc-solaris.tar.gz=805643ab958df449ffd8dd5557e43c5e7060a10a3deab2238096b721ab451f08 -dist/2025-10-28/rustc-nightly-x86_64-pc-solaris.tar.xz=f2fb0c0643808bd9f483bf9bf66ead4444285f2e50bc1264b4861deddfaa9c62 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=05b7ee4041b2cdcee1739da7a22e4083acc24c043d11cb3f61d0c22237a9f42a -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=2f3b04d56dd929ab5997711bc52395fa700247ff38b9362cda375b685c740337 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-gnullvm.tar.gz=52575038868d91349b40434ec8faf9836a0aa0a4f77c2decc634a9ba02796c07 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-gnullvm.tar.xz=d2d1f2a0d26cc3dc86d88ae46a9dcaa5f0ce694ebac3f46b7466fb058a1a76e5 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=5469701cbe03939a82ce5ec50dc166342ab968d2f96cb372dee8f29dfd6e4362 -dist/2025-10-28/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=e6d18f7b7fa3a3613f1aa129f4a14820d4fa1977550689cd99b7dad12054edab -dist/2025-10-28/rustc-nightly-x86_64-unknown-freebsd.tar.gz=e2a5ff9df2b07f8c939fdb885da717faf19a5b3e63ab780962dc288f832cba6f -dist/2025-10-28/rustc-nightly-x86_64-unknown-freebsd.tar.xz=b577558a8f1b42d6bbbc80804e3b72835a85979c98659696db32832595283d04 -dist/2025-10-28/rustc-nightly-x86_64-unknown-illumos.tar.gz=5535a693d5b8edf3fae7e1da97c20596a1f60135fefe22835109ed3648765a16 -dist/2025-10-28/rustc-nightly-x86_64-unknown-illumos.tar.xz=bfc15f0678099ea110135d4e7bcb1b9a545f041e5810f6528d49e0b5451a29bb -dist/2025-10-28/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=877bf56730551f851e2ce5279c105f231906959bcf904aa2fc29acaba5160cc5 -dist/2025-10-28/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=911bf7891d7687675f9200d3bd51946e21df3762b5320b7d31bd49d58526a8a7 -dist/2025-10-28/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=c0c26704d16d6612d0d99ad078bbcb2ac0ed86419a0404a9e08739990acc5ad9 -dist/2025-10-28/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=677f5c6126262b64126b5fc7c3c527cbc9e8ba62aaf4376c924149b6d05e16db -dist/2025-10-28/rustc-nightly-x86_64-unknown-netbsd.tar.gz=84c82523969ff1b987a09d5f7401e9a773b3110f51f00d708a4791ef6615272b -dist/2025-10-28/rustc-nightly-x86_64-unknown-netbsd.tar.xz=680eb70467d5695e986b013b3d16dbd0c0b0b7bc85cf8df4a3392c100f97eff9 -dist/2025-10-28/rust-nightly-aarch64-pc-windows-msvc.msi=a8f7ef71113d5ca8094d9433f23d5bab8ae910803e0cc23110d4fd0e04816bf3 -dist/2025-10-28/rust-nightly-i686-pc-windows-gnu.msi=6c4c49c2c2303f94a39d5c598c4f75b9d2c894b1c30aa6b49c8ab7ca674c8ca9 -dist/2025-10-28/rust-nightly-i686-pc-windows-msvc.msi=f7c80d8c614f5b53a596bfd8a263fc0e680b554ec47630e36e23354afb7fd426 -dist/2025-10-28/rust-nightly-x86_64-pc-windows-gnu.msi=2f830bf3391a7da78de14ba4ffd82de8a49652262fcc7a3ae377a3703fe7ab93 -dist/2025-10-28/rust-nightly-x86_64-pc-windows-msvc.msi=c9b61b50bace832fc504853a5ea5dacd869909946c04d1d9c95b15385e98fd47 -dist/2025-10-28/rust-nightly-aarch64-apple-darwin.pkg=8d7cb75018220eac497ffa180c94b210e2e53e8e8c36ab8a39d6c4c6234fe72b -dist/2025-10-28/rust-nightly-x86_64-apple-darwin.pkg=82e9979fe0cdbac0e008f46cd2d7da70e9fa2caa0d4f1df56654cf57114c993a -dist/2025-10-28/rustc-nightly-src.tar.gz=f6da3a086dd47e5ace7eec9f03879d4c3082503912fe631e54e38168dac60f22 -dist/2025-10-28/rustc-nightly-src.tar.xz=523289ae9e6a87f076decc1beb412897184e728302826882bf53dfde4df4ce15 +dist/2025-12-11/rustc-1.92.0-aarch64-apple-darwin.tar.gz=9bba82c249776b282e25f4bc9c9386ea5ec81d3a2346281516c9da8910a5fd22 +dist/2025-12-11/rustc-1.92.0-aarch64-apple-darwin.tar.xz=15dee753c9217dff4cf45d734b29dc13ce6017d8a55fe34eed75022b39a63ff0 +dist/2025-12-11/rustc-1.92.0-aarch64-pc-windows-gnullvm.tar.gz=be37ee49589ab366548802d5f123ebd20eaeb7046c2f2149bbaef76582a154bb +dist/2025-12-11/rustc-1.92.0-aarch64-pc-windows-gnullvm.tar.xz=a7556b86bce94dd8c078a62f71a9a0a3f4b3e841bc5d4fae546d797b78186eb1 +dist/2025-12-11/rustc-1.92.0-aarch64-pc-windows-msvc.tar.gz=9296c18c3502c9c083bf39be6c5cab0d1afd39d3270810a1e630d6237f1cde0a +dist/2025-12-11/rustc-1.92.0-aarch64-pc-windows-msvc.tar.xz=07ba5606143de3bc916455714f67732fca05805591396a8190d5e88b8863eea3 +dist/2025-12-11/rustc-1.92.0-aarch64-unknown-linux-gnu.tar.gz=0d4e2145fe184fd6069c3a67deb44cc5bdadee7a631e742a025a47e3ea774577 +dist/2025-12-11/rustc-1.92.0-aarch64-unknown-linux-gnu.tar.xz=7c8706fad4c038b5eacab0092e15db54d2b365d5f3323ca046fe987f814e7826 +dist/2025-12-11/rustc-1.92.0-aarch64-unknown-linux-musl.tar.gz=da8c6d290ed86fb58ac9a7af78d3b0c27e1171e2ec62893fce667c085d172593 +dist/2025-12-11/rustc-1.92.0-aarch64-unknown-linux-musl.tar.xz=e7099dddd30f92093916e47a34cd6a866ea0acbf2836c17b74bdd795f0137a2a +dist/2025-12-11/rustc-1.92.0-arm-unknown-linux-gnueabi.tar.gz=601d613c027cccc3ed295c057d5948fe57cbe75992419970d15dc04e9b083b6f +dist/2025-12-11/rustc-1.92.0-arm-unknown-linux-gnueabi.tar.xz=18961e1d83fb747b60c766f68f8297a54452def6e79cc3e02c2d23712e0b3a17 +dist/2025-12-11/rustc-1.92.0-arm-unknown-linux-gnueabihf.tar.gz=5b79849c220f59a41f0949cd3b8fbf719200d3230b5922ae9b1c88e1f0860c42 +dist/2025-12-11/rustc-1.92.0-arm-unknown-linux-gnueabihf.tar.xz=53406761d1774302d50007ab005ff95befc9396856389fadbc94949629bed71d +dist/2025-12-11/rustc-1.92.0-armv7-unknown-linux-gnueabihf.tar.gz=f34a35f33fd922ffb5f9b40753c86159707449788dbb7fe43090dc030bc47cf1 +dist/2025-12-11/rustc-1.92.0-armv7-unknown-linux-gnueabihf.tar.xz=c49d5679f7f4f5ce3cf0d3b72c4299a0f95521087f3122d6c15be77658d4f9e9 +dist/2025-12-11/rustc-1.92.0-i686-pc-windows-gnu.tar.gz=9e8839f507a74653cfc06fc6de8a028d7874b933ea55e953f5a1d1eab29c9d0f +dist/2025-12-11/rustc-1.92.0-i686-pc-windows-gnu.tar.xz=a3dd59a53c7c919457b4c4eab814c3cd18cdc7a3f679fdaf8df6f9a21ef8c1ef +dist/2025-12-11/rustc-1.92.0-i686-pc-windows-msvc.tar.gz=4883ea7d39f7030a4290d7e9e5cc71483c867b4188bff293ff8f770bf4ee8f66 +dist/2025-12-11/rustc-1.92.0-i686-pc-windows-msvc.tar.xz=e892036f2ac1f24cdf853df74f631e9ad80fa6fcb2b9ca241527ed5b03eea96d +dist/2025-12-11/rustc-1.92.0-i686-unknown-linux-gnu.tar.gz=81b884e76b8e3b45509c20874f93d993477c4db2131745c8bf61282c8e673d78 +dist/2025-12-11/rustc-1.92.0-i686-unknown-linux-gnu.tar.xz=c1c920cd59e255e5dcf844af22b80483fe4b04ff04f143be6da69314bd6733f8 +dist/2025-12-11/rustc-1.92.0-loongarch64-unknown-linux-gnu.tar.gz=d85f10ad64fa7e8ddde205538503a97968f10d800e1432e8d22c94ff48a4345f +dist/2025-12-11/rustc-1.92.0-loongarch64-unknown-linux-gnu.tar.xz=6207ea209b332c01437fe742c2ef2bc914c88b6d4f9a23a43bc01ad924f6e4a8 +dist/2025-12-11/rustc-1.92.0-loongarch64-unknown-linux-musl.tar.gz=4203f9a11ffb57374dc498a6eb6f2df6f7bff4d13586a10af12476a69fb801b6 +dist/2025-12-11/rustc-1.92.0-loongarch64-unknown-linux-musl.tar.xz=66ac74c23df9f42cbda26587a37a70a67d5fd9821673656712a9f5a3b4cc8151 +dist/2025-12-11/rustc-1.92.0-powerpc-unknown-linux-gnu.tar.gz=84dc48d1b6b553439267dbb22bda57232e604764181cba7c19ed6a601b17ef27 +dist/2025-12-11/rustc-1.92.0-powerpc-unknown-linux-gnu.tar.xz=961cb6b8c2b5e969ad8eb0256fee43b88608b27310d946a7df3c9e9577139cae +dist/2025-12-11/rustc-1.92.0-powerpc64-unknown-linux-gnu.tar.gz=209a0e4371ae4f5670c58ca35cdd295d4b9f590b5270225b045a4655e3ca216e +dist/2025-12-11/rustc-1.92.0-powerpc64-unknown-linux-gnu.tar.xz=357dd4745f978080d35dbb6192ecfea331abbb93d88be7d70407856b30722a40 +dist/2025-12-11/rustc-1.92.0-powerpc64le-unknown-linux-gnu.tar.gz=89cdf91094ff3f68cc3bc679274134e491087eea3b0cf2fe61ebc2ce5f211827 +dist/2025-12-11/rustc-1.92.0-powerpc64le-unknown-linux-gnu.tar.xz=f48a214ff6fa36a77de8a0a2ee009be8aa48ba1533792450aca5edac29497606 +dist/2025-12-11/rustc-1.92.0-powerpc64le-unknown-linux-musl.tar.gz=9215fe368a7d22143b96d42d9ada17009420ea080e5650d30fb8a4e2e720117e +dist/2025-12-11/rustc-1.92.0-powerpc64le-unknown-linux-musl.tar.xz=f418ffded33abecec8d8aa72abf40448511ac78e8ae14ca43c066c7dd98310c3 +dist/2025-12-11/rustc-1.92.0-riscv64gc-unknown-linux-gnu.tar.gz=e36b96182e9a0c2e2f3a83cddfc5318a8ca2d049a0bddca9b42d05428ebed89d +dist/2025-12-11/rustc-1.92.0-riscv64gc-unknown-linux-gnu.tar.xz=729f4c074ccda30bff493fa94f255bcfcec1be594fecd8a4d0f57da845121c64 +dist/2025-12-11/rustc-1.92.0-s390x-unknown-linux-gnu.tar.gz=1fb255054864d857b32ca2c0dd06a2739cdd464d8872e18f2b103fb7a6d1f530 +dist/2025-12-11/rustc-1.92.0-s390x-unknown-linux-gnu.tar.xz=6a8cf614a74f7469c70d32b378f0163633e6bbe19624b248b758501c5bcdfe84 +dist/2025-12-11/rustc-1.92.0-sparcv9-sun-solaris.tar.gz=a5d20ba9277bb8b3b756f9f6dd2f7a1e9931ac8673fcca31d745eb81f1d573b6 +dist/2025-12-11/rustc-1.92.0-sparcv9-sun-solaris.tar.xz=74d6f885557f11b136d780c6fcc22d1db4b80644baaad22dbbbe29c890a0475a +dist/2025-12-11/rustc-1.92.0-x86_64-apple-darwin.tar.gz=d3dc5b7ddad48bb0afba0c6448aa00efec2d3fa9bc02ca55575c76d425c15ce4 +dist/2025-12-11/rustc-1.92.0-x86_64-apple-darwin.tar.xz=0facbd5d2742c8e97c53d59c9b5b81db6088cfc285d9ecb99523a50d6765fc5c +dist/2025-12-11/rustc-1.92.0-x86_64-pc-solaris.tar.gz=aeec5a91df699ab7a6b276e694a2711a59988dcc664ba9de43d5502e53d7b504 +dist/2025-12-11/rustc-1.92.0-x86_64-pc-solaris.tar.xz=03ed0965a4b4006f347513e7a2e7e0a9dac13053b432d65e97c59fd604973542 +dist/2025-12-11/rustc-1.92.0-x86_64-pc-windows-gnu.tar.gz=338ec86978c5d25799b79105c7bfb146002208d656f9e82b14692cd535c2ae65 +dist/2025-12-11/rustc-1.92.0-x86_64-pc-windows-gnu.tar.xz=fa0cbdf49f267f316433f054ca99951177827d0d406ddbaba9a0bbdcb093b56d +dist/2025-12-11/rustc-1.92.0-x86_64-pc-windows-gnullvm.tar.gz=b3575d7f29cd0423dbcf89457a9682acf8c0c1ad923136a12c7d3162c7b9a2d9 +dist/2025-12-11/rustc-1.92.0-x86_64-pc-windows-gnullvm.tar.xz=e67ec11b4c6e04e95effa7b4063ae8327c2861c6d08a7c692d69a0f1adcd8ecb +dist/2025-12-11/rustc-1.92.0-x86_64-pc-windows-msvc.tar.gz=4f321ca1903b8b08ceb07c0305f9f0320bc711ff6e285d726b8ef1dda774935d +dist/2025-12-11/rustc-1.92.0-x86_64-pc-windows-msvc.tar.xz=6aec5aba5384ce1041538e71ebebf671d82e29f4fe697bc7844626d94b0dbfe6 +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-freebsd.tar.gz=a0c0710281e86f7523d116c3826ed406491430d9f92769e4f4b4caf28e686edf +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-freebsd.tar.xz=f9b3a4fdb825c171e15f68db7c4faefecd60ea7475b9b11e98004fb7d711fd7c +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-illumos.tar.gz=b48d9c46b58f00a164b35611a58d0ed13bf5dd4ff7b138252b61f8100fcd7434 +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-illumos.tar.xz=e74f639cdfb368edfede795394932c8665cb192a2618e88c947ebd57ce2cc159 +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-linux-gnu.tar.gz=e133546ebb40974356cc82434e07f6a0ce15966d8b01898f97eab235c46883e8 +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-linux-gnu.tar.xz=78b2dd9c6b1fcd2621fa81c611cf5e2d6950690775038b585c64f364422886e0 +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-linux-musl.tar.gz=eaff6d6b051e59875eb585a981c799be87a2a68f1d52556dc64e26531a499531 +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-linux-musl.tar.xz=f1a037c367d29d329d041f0bf1d271e60440adc961b6eaa9ea902018a672d4a3 +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-netbsd.tar.gz=49f33344d9b22dea5a4f97f1d1c4fdb52afd1c34bd5fd78bb8d7e5e5ee92333c +dist/2025-12-11/rustc-1.92.0-x86_64-unknown-netbsd.tar.xz=a0cdbdd508e72de8f3e783b61827fac1f741acd6503464dc263a7292880a16e5 +dist/2025-12-11/rust-std-1.92.0-aarch64-apple-darwin.tar.gz=b1f55aac4bc982ea67b68b262b711263005e470d31cab5d09d534bc1866d455a +dist/2025-12-11/rust-std-1.92.0-aarch64-apple-darwin.tar.xz=ea619984fcb8e24b05dbd568d599b8e10d904435ab458dfba6469e03e0fd69aa +dist/2025-12-11/rust-std-1.92.0-aarch64-apple-ios.tar.gz=449a3f453215eaa86ee80bd4f70cb1a8dfca0447e27f7e820a73047913d7c724 +dist/2025-12-11/rust-std-1.92.0-aarch64-apple-ios.tar.xz=81fb496f94a3f52ec2818a76a7107905b13b37d490ca849d22c0a7a7d7b0125e +dist/2025-12-11/rust-std-1.92.0-aarch64-apple-ios-macabi.tar.gz=cc4ca331919012b71cb634082ab761003c752067a7b7cbcdb5a513a56f629bef +dist/2025-12-11/rust-std-1.92.0-aarch64-apple-ios-macabi.tar.xz=d0453906db0abe9efb595e1ed59feb131a94c0312c0bc72da6482936667ff8da +dist/2025-12-11/rust-std-1.92.0-aarch64-apple-ios-sim.tar.gz=1e08495db970e62931fd1f2349b10c04a765469aecd84b9ded10bcf09e98904d +dist/2025-12-11/rust-std-1.92.0-aarch64-apple-ios-sim.tar.xz=9362b66fbaf2503276ea34f34b41b171269db9ba4dce05dde3472ea9d1852601 +dist/2025-12-11/rust-std-1.92.0-aarch64-linux-android.tar.gz=f6689cf5b71056e887261ec84ae1f499eeb42c67e5ae73e7c0e06065b6648c44 +dist/2025-12-11/rust-std-1.92.0-aarch64-linux-android.tar.xz=ce6350bd43856c630773c93e40310989c6cb98a1178233c44e512a31761943d0 +dist/2025-12-11/rust-std-1.92.0-aarch64-pc-windows-gnullvm.tar.gz=4b4774c66e6952fb46d0049dffb2c664d95712052c4816e354bca3e97799dda4 +dist/2025-12-11/rust-std-1.92.0-aarch64-pc-windows-gnullvm.tar.xz=4e79f57b80040757a3425568b5978986f026daf771649a64021c74bcc138214b +dist/2025-12-11/rust-std-1.92.0-aarch64-pc-windows-msvc.tar.gz=7b27adfa0f10ee44a78430ad7ec000eb95cf4586b7338bc001dae5d5b865578c +dist/2025-12-11/rust-std-1.92.0-aarch64-pc-windows-msvc.tar.xz=b20c5c696af4ecfb683370ca0ee3c76ab8726fe6470ce9f1368d41a5b06ea065 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-fuchsia.tar.gz=ead00e822bf91191e4982e35d89744e977a9c51aa1b3ea1717e744c899067ee5 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-fuchsia.tar.xz=6021246b6c0d9d6104c0b350f7cd48a31d5707edaa8063f77f5636fe07bdb79d +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-linux-gnu.tar.gz=04a5c9883bce2c4e89d22dd68af1bdc29b741bb456c01f8839b759a163e8e9d4 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-linux-gnu.tar.xz=ce2ab42c09d633b0a8b4b65a297c700ae0fad47aae890f75894782f95be7e36d +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-linux-musl.tar.gz=715fbcfd8712c723947a020d0371c8a1a21f7531f2b696aeaed50ac23ba675c9 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-linux-musl.tar.xz=94b9f84f21d29825c55a27fbb6b4b9fb9296a4a841aa54d85b95c42445623363 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-linux-ohos.tar.gz=0971b3c864ab1baa06a7fb5ba2fb176d8ca762bdecfd9e374810dc827d69d134 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-linux-ohos.tar.xz=6fb30061fae54c4a27bb209d314456d04826c345a8015b10d1fe9b82eeb46f9c +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-none.tar.gz=93e18afe654009b56783f1295d25a8bafa31badc8f6fcb46c2e217856daf68a6 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-none.tar.xz=ab6a2edab924739fc2c86e9f8fd8068b379e881a6261a177d66608d3ea4cacb1 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-none-softfloat.tar.gz=911108d6f01ff1040ea3de993bcf3ea52fe19aee099516a607e9967ce4813bcb +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-none-softfloat.tar.xz=0dc46fafaaa36f53eec49e14a69e1d6d9ac6f0b9624a01081ad311d8139a2be0 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-uefi.tar.gz=a14f2491f87149b779460b898ff1208adc31fc463094d8eff86e778fce9f6ce6 +dist/2025-12-11/rust-std-1.92.0-aarch64-unknown-uefi.tar.xz=f98001222bf23743598382c232b08d3137035b53645a420a1425288d501808af +dist/2025-12-11/rust-std-1.92.0-arm-linux-androideabi.tar.gz=7d9d430c187580c1075649dfdef03dde9f5616ed74ed050ae01cc9d5eda79268 +dist/2025-12-11/rust-std-1.92.0-arm-linux-androideabi.tar.xz=d41ec7255556b605dda04201a23e4445b5b86bc6786c703f91eb985bddc9f4ca +dist/2025-12-11/rust-std-1.92.0-arm-unknown-linux-gnueabi.tar.gz=56d8b0df4b716a69aeefc06fbd859461938d54bcac37d7eea25b07764f6e3c5c +dist/2025-12-11/rust-std-1.92.0-arm-unknown-linux-gnueabi.tar.xz=35478e20f8cc13912b31f2905b313a2820ddae564b363a66ab7a5da39d12787f +dist/2025-12-11/rust-std-1.92.0-arm-unknown-linux-gnueabihf.tar.gz=d0a355524cf219351f15d8984c102f6425bc2c6c1e14af9282e2db60a997a5e0 +dist/2025-12-11/rust-std-1.92.0-arm-unknown-linux-gnueabihf.tar.xz=836ada282b65c57d71f9b7e6fb490832410c954aac905c5437fb0bf851b53c83 +dist/2025-12-11/rust-std-1.92.0-arm-unknown-linux-musleabi.tar.gz=a505ed45f3c55334e8294f304366e2210609305dd25a86b0396c89016219a9d7 +dist/2025-12-11/rust-std-1.92.0-arm-unknown-linux-musleabi.tar.xz=91d3c5fdbda9ba2e778bb638e3a5d060f3021bbc7a60edf22b0035be4e611b30 +dist/2025-12-11/rust-std-1.92.0-arm-unknown-linux-musleabihf.tar.gz=1a2bba0ac573420064fec467a713ab169b54d9281d5652817d5d628a98ff167a +dist/2025-12-11/rust-std-1.92.0-arm-unknown-linux-musleabihf.tar.xz=20411e3858308add0dadde9ce2059d82cdd6c5339881fa93ac995e733df0f832 +dist/2025-12-11/rust-std-1.92.0-arm64ec-pc-windows-msvc.tar.gz=8cca22404b172c1ac590e6a507ec73bece0e3698bfd74f549246d23392ee3a45 +dist/2025-12-11/rust-std-1.92.0-arm64ec-pc-windows-msvc.tar.xz=1618d3d429a3c9b06d43bcc12ec7c50c5eb6cb01cb2f077c525bc0f077c7a6f0 +dist/2025-12-11/rust-std-1.92.0-armv5te-unknown-linux-gnueabi.tar.gz=547a6282ed5896dbac1df388a116301cfedf41fc579fa25caa57b3ee7e333e19 +dist/2025-12-11/rust-std-1.92.0-armv5te-unknown-linux-gnueabi.tar.xz=702be50f225ad4681af1bf9c40fd020b4623ee46aab5363ea96e4874dffb694d +dist/2025-12-11/rust-std-1.92.0-armv5te-unknown-linux-musleabi.tar.gz=578a0eee2513520e4195e09c0657b074cc9f7bff215507ddd905cfe7b15bab77 +dist/2025-12-11/rust-std-1.92.0-armv5te-unknown-linux-musleabi.tar.xz=c1c645c1b33625b9735a7c6f062a122fb172957093fac33f8ee3b80663deeb41 +dist/2025-12-11/rust-std-1.92.0-armv7-linux-androideabi.tar.gz=18f6e6903c5f4361efe8c8a1ea546303e4473e8b9cd1b11fcf4e5b170468d464 +dist/2025-12-11/rust-std-1.92.0-armv7-linux-androideabi.tar.xz=06ac2f08dcf5c480e7767c0541c9bd7460754ec3a369a4b7097b328eca28fab9 +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-gnueabi.tar.gz=1e2238cb33c6adc29c13fdc980a4019587f69af5ae88f7bd473da2dbd9b70a2c +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-gnueabi.tar.xz=3d5e3fb14441ea8e6fc6307cbd89efd69be42143ff7f2b8dfb19818ddca993c0 +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-gnueabihf.tar.gz=2c44994e0982bdb60c132c40b481b3c6ca83a131f09d568831553e3e29384130 +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-gnueabihf.tar.xz=e3ac810db43067d8af9e17679d47534e871f1daad8cd0762e67da935681e9e19 +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-musleabi.tar.gz=3bf1b0015dc3b0f5f6f5622588431855c658d5c47093f24e4077f6893229ab30 +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-musleabi.tar.xz=89cbf7db934d543754b446a52398081ec40ee6b98ed5bca93ac1dbd5faf48c16 +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-musleabihf.tar.gz=fc5c4ca757599caab8e93000becb9d57587088d32dab5c4f3b253f00ec3a2fd6 +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-musleabihf.tar.xz=c7c08a389bd351226fd52266bfe2d2c444597e1bbb5d0307da44bdfa4df62c99 +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-ohos.tar.gz=4cc8337f39f1b2820880dd8cac203399b5fd0eee7716d0a9c785a71f6d9fbf50 +dist/2025-12-11/rust-std-1.92.0-armv7-unknown-linux-ohos.tar.xz=e75603f745d5becd2e79d0cd6c7976e53bcc56d7af8ba1ac4e3494effc502f15 +dist/2025-12-11/rust-std-1.92.0-armv7a-none-eabi.tar.gz=b7b68dc24eb7e80592938a928372391e57fc04066238b178855f06863a597341 +dist/2025-12-11/rust-std-1.92.0-armv7a-none-eabi.tar.xz=e97368a7876332ce5181d8efca43996ee9d16ecc0be195e7d9b4f295a36c39ac +dist/2025-12-11/rust-std-1.92.0-armv7a-none-eabihf.tar.gz=f79f1983b5c3867657ba1849472b0aa1a54ab1ab94bab66f046583f8858bebad +dist/2025-12-11/rust-std-1.92.0-armv7a-none-eabihf.tar.xz=407899b91b4a44d5096bebbae00b3044ecc71e4cce958f79a149f4149a662bf6 +dist/2025-12-11/rust-std-1.92.0-armv7r-none-eabi.tar.gz=310c5149e672a794364c389ee383f437e367eac912c8c9c63e9e024c8eb5a98e +dist/2025-12-11/rust-std-1.92.0-armv7r-none-eabi.tar.xz=d135b9aa652dbdbf8115c31a71eb5b5e022968dd3c98a6d0421ad13ed8b8385e +dist/2025-12-11/rust-std-1.92.0-armv7r-none-eabihf.tar.gz=49b7583f91e42ee05c057e8ca5b736d883725d40e71bc8f8ce369b46bb074343 +dist/2025-12-11/rust-std-1.92.0-armv7r-none-eabihf.tar.xz=d6b44323ffcb32ead9be54ef4786048f48cec1f18cd269e2fcab36d2c3d5e7e9 +dist/2025-12-11/rust-std-1.92.0-armv8r-none-eabihf.tar.gz=f0b184acd74d500d6a7f559a62d7946d00fed6ac427bdbd7c52640be6d98e767 +dist/2025-12-11/rust-std-1.92.0-armv8r-none-eabihf.tar.xz=355ffd45d0d450e1e5d2ce8aa1ff0977ebb4b3ca9c6689e8d72dcd2c56b6046d +dist/2025-12-11/rust-std-1.92.0-i586-unknown-linux-gnu.tar.gz=3fb6630b6341a07a9bbc37a8c541ad3e389a26dc0ef48c09aa3b14a6afbf672a +dist/2025-12-11/rust-std-1.92.0-i586-unknown-linux-gnu.tar.xz=8b984b31ffca1f27d32ee77ec2cc4c2ab59e72beab67bfce13bbd926dbea8715 +dist/2025-12-11/rust-std-1.92.0-i586-unknown-linux-musl.tar.gz=6c39e5506fd6a0532d15f3cd9510e6e9fb0da0712f426b8a55f04114125b6e13 +dist/2025-12-11/rust-std-1.92.0-i586-unknown-linux-musl.tar.xz=059d919f147e6bd40e132ad00ee23de59d5464f5e3409f3139b3ac14faf45893 +dist/2025-12-11/rust-std-1.92.0-i686-linux-android.tar.gz=d994d70493ad68ced22a5269e41b9fa6f83af9f3adabade154860058bc2e18c0 +dist/2025-12-11/rust-std-1.92.0-i686-linux-android.tar.xz=e45832b005556f65c6d26f05f34bd4ab5ceea8d9b9fefc4175d52b0780ca89db +dist/2025-12-11/rust-std-1.92.0-i686-pc-windows-gnu.tar.gz=5f30330e61a7d87426e3192e3ba99ec5db2b3d239825f15ce7482b88e695757e +dist/2025-12-11/rust-std-1.92.0-i686-pc-windows-gnu.tar.xz=b3eefe10d4aed3ccbeaff3ae9cd2e0e0a36894c0635d0e69af1c9a698679d75f +dist/2025-12-11/rust-std-1.92.0-i686-pc-windows-gnullvm.tar.gz=916badef8e6415e599b41b706aa522f514ee2932b5e65baea5b04db34e03c185 +dist/2025-12-11/rust-std-1.92.0-i686-pc-windows-gnullvm.tar.xz=e6d709f85dea51d81f2f1a030845b732b9f7761d95d93c57c7276b0a451c2993 +dist/2025-12-11/rust-std-1.92.0-i686-pc-windows-msvc.tar.gz=2d248d48ff8650e61097c57d653ae3c785413b8fa916c51623374b22c5f3be0c +dist/2025-12-11/rust-std-1.92.0-i686-pc-windows-msvc.tar.xz=e5671b276047647e994a7cab99c90ee70c46787572fbe4e266a13c6edb84d5ce +dist/2025-12-11/rust-std-1.92.0-i686-unknown-freebsd.tar.gz=235c77dac41505cfc170a448ff70695fbb78b986e6febbb72eb931f23c66d8cc +dist/2025-12-11/rust-std-1.92.0-i686-unknown-freebsd.tar.xz=e008a0506ec4d5eff30abdf376c7933e235670bd6c5e1131c52bcda097a21116 +dist/2025-12-11/rust-std-1.92.0-i686-unknown-linux-gnu.tar.gz=f568a3c307fad16528bf5accecfdce9e77b6ebda3302ae7a79588adc10d2bd29 +dist/2025-12-11/rust-std-1.92.0-i686-unknown-linux-gnu.tar.xz=abc840631a4462a4c8ec61341110ff653ab2ef86ef3b10f84489d00cc8a9310d +dist/2025-12-11/rust-std-1.92.0-i686-unknown-linux-musl.tar.gz=3d6ccb700a17533eea10c7541896c92817783045c5537af37228142da7668fb3 +dist/2025-12-11/rust-std-1.92.0-i686-unknown-linux-musl.tar.xz=c796874b1343721f575203fa179dc258e09ac45cd95dd6c35c4d5979a3870494 +dist/2025-12-11/rust-std-1.92.0-i686-unknown-uefi.tar.gz=78814c81a60fc1e3326f6d00eee4bc907053bb3a8971a825bf6728ba645f264c +dist/2025-12-11/rust-std-1.92.0-i686-unknown-uefi.tar.xz=90da7759e28e62fb82454d4eb4e02ac14320b8da3372e02f9ca4f47f7afbfe40 +dist/2025-12-11/rust-std-1.92.0-loongarch64-unknown-linux-gnu.tar.gz=cabff40eb871616ce5d40592262b25aba1e6ff8f309bb6e0dab08609470dcfce +dist/2025-12-11/rust-std-1.92.0-loongarch64-unknown-linux-gnu.tar.xz=62e2568ebf6f1addc750a8c32dd1fa4fef8d27679cbac33b837afeb54f204819 +dist/2025-12-11/rust-std-1.92.0-loongarch64-unknown-linux-musl.tar.gz=e46b3f6a18ba0faa5190deb3ee296fc971214c9d38f9d616fce2457e335a98a8 +dist/2025-12-11/rust-std-1.92.0-loongarch64-unknown-linux-musl.tar.xz=274838eebb615e6d2719157aa53230cd0c3233a1e6f1c975c0f5978198c55da3 +dist/2025-12-11/rust-std-1.92.0-loongarch64-unknown-none.tar.gz=dfe120d2bc8cb81ee70c2a2e1ad685d382a0ebd72b37231183d8cb7b6890effe +dist/2025-12-11/rust-std-1.92.0-loongarch64-unknown-none.tar.xz=7e03cbb3aeb5a2c882433f2de0d096455bcab2465729cb0399d1b31e2d400075 +dist/2025-12-11/rust-std-1.92.0-loongarch64-unknown-none-softfloat.tar.gz=7e07f54e69ee2b7e4ef2861d7b1fcadfe3fda3ccb5442e0d85afe1dfdfc52b8a +dist/2025-12-11/rust-std-1.92.0-loongarch64-unknown-none-softfloat.tar.xz=dd01f0348ca2c90d6115b79894360f9ae8468aa8755e0f345e53fe5186f2d891 +dist/2025-12-11/rust-std-1.92.0-nvptx64-nvidia-cuda.tar.gz=3f4ac1e0c35b4a709d926727a49c86d169fa61660d08e940f10f948da9777375 +dist/2025-12-11/rust-std-1.92.0-nvptx64-nvidia-cuda.tar.xz=e8d3d0d81d5bb92baae3f0cc0c43d456e312d6f2770c460ff62521dccba7a855 +dist/2025-12-11/rust-std-1.92.0-powerpc-unknown-linux-gnu.tar.gz=28320c60a2fb42756d7a825f44d35c12100492c44770b0658056e4c468974f86 +dist/2025-12-11/rust-std-1.92.0-powerpc-unknown-linux-gnu.tar.xz=c3e809a324b00eb53096c58df38645bb496c6560de334dfe04ed0b77c0605aaa +dist/2025-12-11/rust-std-1.92.0-powerpc64-unknown-linux-gnu.tar.gz=c47938c152f1b237c901090d69522ce1ccfa69a859ed10d634fe3083108c3017 +dist/2025-12-11/rust-std-1.92.0-powerpc64-unknown-linux-gnu.tar.xz=2ce706afa4a46b6773340854de877fc63618a40e351298a4e3da8eb482619863 +dist/2025-12-11/rust-std-1.92.0-powerpc64le-unknown-linux-gnu.tar.gz=f63de16a3c3f8e11aaf21de60ec38de59b1234aea4fe38d0577414a43adc4a8e +dist/2025-12-11/rust-std-1.92.0-powerpc64le-unknown-linux-gnu.tar.xz=eba59766c2d9805c0a1fc82fd723acbb36569e1bec1088c037bba84d965f70ba +dist/2025-12-11/rust-std-1.92.0-powerpc64le-unknown-linux-musl.tar.gz=696958d87842d877640140ddbbaa74d044374874dee9516e227a395b70bfb8d4 +dist/2025-12-11/rust-std-1.92.0-powerpc64le-unknown-linux-musl.tar.xz=8b515e18b6ac8f8d37ea3cabe644b7f571984333c3b4192b7f5877e79eae7893 +dist/2025-12-11/rust-std-1.92.0-riscv32i-unknown-none-elf.tar.gz=a56084ad27ec50df0a0da2473deb84d51cb831cbf913bf983a029850e9e9f0ac +dist/2025-12-11/rust-std-1.92.0-riscv32i-unknown-none-elf.tar.xz=e115633fa0dccec2f94477e26c5c93cbb17c54af2769e19b4636f50708a00f6b +dist/2025-12-11/rust-std-1.92.0-riscv32im-unknown-none-elf.tar.gz=b1ac7c191995b67f819446f2dc1bc4a3e66036aa5ae54ad05b7891bb4bbf0e50 +dist/2025-12-11/rust-std-1.92.0-riscv32im-unknown-none-elf.tar.xz=2d7547fbf012b06a2b570c94e3611b86fb10edcf23589c47ea4da99c87d50537 +dist/2025-12-11/rust-std-1.92.0-riscv32imac-unknown-none-elf.tar.gz=52d8c75e48a2575381e2a041a5bb359adf161a6c29f4ba990e54384fa6699861 +dist/2025-12-11/rust-std-1.92.0-riscv32imac-unknown-none-elf.tar.xz=5915223db6b8afa173f67eb4fe6f5aff2402351ed9abab1b370d0860be4af6c9 +dist/2025-12-11/rust-std-1.92.0-riscv32imafc-unknown-none-elf.tar.gz=2bd1d15d7d1e1a133afc7244375f3af405453153c4c3f924a0ee019fff807ca6 +dist/2025-12-11/rust-std-1.92.0-riscv32imafc-unknown-none-elf.tar.xz=a3de78da39a79a9facf729ac005f69b4d3c68044f0b8ec4daa9e271a719d9a46 +dist/2025-12-11/rust-std-1.92.0-riscv32imc-unknown-none-elf.tar.gz=939b46b6320a082d562ba79efd53a028b3c01276f70106ecbcc95148b013f990 +dist/2025-12-11/rust-std-1.92.0-riscv32imc-unknown-none-elf.tar.xz=e1c6968ce25ab78f2c5b5460691763a2d39cb71b01d6d54c208d4a8b735b0584 +dist/2025-12-11/rust-std-1.92.0-riscv64gc-unknown-linux-gnu.tar.gz=b15965fec2297deff49412cc0e22a005db5ff710ca77187058c4907f1e7dd467 +dist/2025-12-11/rust-std-1.92.0-riscv64gc-unknown-linux-gnu.tar.xz=8ee20dcf3b1063fa6069b3ce85e1fcf42794dfa783263314865cb53fff42d9e4 +dist/2025-12-11/rust-std-1.92.0-riscv64gc-unknown-linux-musl.tar.gz=34f5722ff2a0940bcd7ff6603a7748d2b963de72f6f713579c39c74ead06a7a0 +dist/2025-12-11/rust-std-1.92.0-riscv64gc-unknown-linux-musl.tar.xz=f20d822309900fd6c7230688694baf91e900154e44e6247feca49b7b7a203a57 +dist/2025-12-11/rust-std-1.92.0-riscv64gc-unknown-none-elf.tar.gz=aa6d992ef5ea58a732e9f7a5843b37b6d03059f0de90bd6f0e45a9067e4c52cf +dist/2025-12-11/rust-std-1.92.0-riscv64gc-unknown-none-elf.tar.xz=7eacf6a98786d58ef912643fd5aedc35111712e96a47b7e5d3ccddcdf9fb166d +dist/2025-12-11/rust-std-1.92.0-riscv64imac-unknown-none-elf.tar.gz=d81c6b2c7c71e38e6b0e1634af5b782e23f35adef36e1f35237d66c191d9f170 +dist/2025-12-11/rust-std-1.92.0-riscv64imac-unknown-none-elf.tar.xz=e3eda32b99bbff3fe77aa72c29de9373009e8650f7ab93c2b4c344ad13bc459e +dist/2025-12-11/rust-std-1.92.0-s390x-unknown-linux-gnu.tar.gz=c33203be69a7415c6d3465bc30189617684105bdcd68a3c78d6b7257c83b005b +dist/2025-12-11/rust-std-1.92.0-s390x-unknown-linux-gnu.tar.xz=ebf944dc95015498d322504a54e4f9cdb28590f7790aa3a9eb86d6cf4b6c93ff +dist/2025-12-11/rust-std-1.92.0-sparc64-unknown-linux-gnu.tar.gz=6915a7d1880facef71d4712623b254a78fdc7c9edc8f98e3200b6095d81b99ab +dist/2025-12-11/rust-std-1.92.0-sparc64-unknown-linux-gnu.tar.xz=d85afb14120c3c7367338a565a920db653dccd4bc5062398791d7b62b89fd1fd +dist/2025-12-11/rust-std-1.92.0-sparcv9-sun-solaris.tar.gz=637a8fcc402792ab97411031258fdbbfbe66328fbc4aad8aa536f598501ba10d +dist/2025-12-11/rust-std-1.92.0-sparcv9-sun-solaris.tar.xz=e9ae7dc479e6c97335b3ebee8c3d69069cf6a617942196871229794ca94f3458 +dist/2025-12-11/rust-std-1.92.0-thumbv6m-none-eabi.tar.gz=a8a57993bb98d61486fac274b285168e253988d7a7fca0b3f72dc23057d9a88e +dist/2025-12-11/rust-std-1.92.0-thumbv6m-none-eabi.tar.xz=f55de77126b60e1da38f8a5cdd127db872155ce9fbb53d4459502dd47b1dd476 +dist/2025-12-11/rust-std-1.92.0-thumbv7em-none-eabi.tar.gz=fdbc35de85989f4c2155b813d1ba4abb34f57c195d97ed863c06de8b8fb426d7 +dist/2025-12-11/rust-std-1.92.0-thumbv7em-none-eabi.tar.xz=fdee017dcebfa8675220c20ca65b945b6eaee744d5d19b92cb0ca5480dd19ba6 +dist/2025-12-11/rust-std-1.92.0-thumbv7em-none-eabihf.tar.gz=d94cd679358a4eb33970df571fdfcacb385980c4f4a3f92114ffa5d356f86456 +dist/2025-12-11/rust-std-1.92.0-thumbv7em-none-eabihf.tar.xz=6bfd083ce4917440fb4b04ca39ab4dadc9f40d9dc2775056899857bfa8911fd0 +dist/2025-12-11/rust-std-1.92.0-thumbv7m-none-eabi.tar.gz=7861c515c0fdb2fcf74e434813d43de8d0b084babdd87b9cd8bf67fc173cfc54 +dist/2025-12-11/rust-std-1.92.0-thumbv7m-none-eabi.tar.xz=7dc4c92e97db5ce1ddd9fbb7fbb1ad2d367f1c2e20d296a6d6427480c900c315 +dist/2025-12-11/rust-std-1.92.0-thumbv7neon-linux-androideabi.tar.gz=28f77e164fbdb373d5bf729a7672d775d57a08ccbbf2d8d6aefffa0f1b9d6112 +dist/2025-12-11/rust-std-1.92.0-thumbv7neon-linux-androideabi.tar.xz=ce99df993198da32a2f655d8f6666f2ef7995242cdc31686db49bfeac07e6f7c +dist/2025-12-11/rust-std-1.92.0-thumbv7neon-unknown-linux-gnueabihf.tar.gz=c9de934e22d796a4f542783d60b43b62a213a15014bbea02ca9f9520abfec872 +dist/2025-12-11/rust-std-1.92.0-thumbv7neon-unknown-linux-gnueabihf.tar.xz=08a51cb570fc25bf226c25c1031b98d3963a52e263bbacd873f111faa918484e +dist/2025-12-11/rust-std-1.92.0-thumbv8m.base-none-eabi.tar.gz=06453a93570c63a0d6a56000493d4e6ff20f1e20c4c3b9ec7124359ebc79a3eb +dist/2025-12-11/rust-std-1.92.0-thumbv8m.base-none-eabi.tar.xz=3c5d71fa1d6f242be184339d8bbb360acf9ca552f0093c10309c83e06a95bcaf +dist/2025-12-11/rust-std-1.92.0-thumbv8m.main-none-eabi.tar.gz=c3c0cde9afce994bfbd0f2fbde02efb6ad1238a3d33056ccac6e99aba579af3a +dist/2025-12-11/rust-std-1.92.0-thumbv8m.main-none-eabi.tar.xz=61a6a80d03ebdb80ab06a044d4ec60e3c2bd8dc4d6011e920cf41592df4f0646 +dist/2025-12-11/rust-std-1.92.0-thumbv8m.main-none-eabihf.tar.gz=21336cc1a032eb35b8c4a546805ce1e8e3afa24735ee23aae5599fd8787ce581 +dist/2025-12-11/rust-std-1.92.0-thumbv8m.main-none-eabihf.tar.xz=24c2f65371a2a5c6a40b51ae0e276ea9afff0479255f180f5e1549a0a4d58fb3 +dist/2025-12-11/rust-std-1.92.0-wasm32-unknown-emscripten.tar.gz=fec9cb6cced27592fa601c18afb357bb861d5ebeaad1dda9304f6acfd85b4000 +dist/2025-12-11/rust-std-1.92.0-wasm32-unknown-emscripten.tar.xz=59b7adf18c0cc416a005fad7f704203b965905eb1c0ed9c556daa3c14048b9f4 +dist/2025-12-11/rust-std-1.92.0-wasm32-unknown-unknown.tar.gz=4763b575ecceab7637557527a91af6c5c36816a68e3f2de1e18518dd15a63bcd +dist/2025-12-11/rust-std-1.92.0-wasm32-unknown-unknown.tar.xz=6c73f053ccd6adc886f802270ba960fd854e5e1111e4b5cfb875f1fdcfc0eb60 +dist/2025-12-11/rust-std-1.92.0-wasm32-wasip1.tar.gz=a8736000e35213951e53315e3d5841cbe8e6c70fad167a302bd8ae1a43331cec +dist/2025-12-11/rust-std-1.92.0-wasm32-wasip1.tar.xz=8107dc35f0b6b744d998e766351419b4e0d27cddd6456c461337753a25f29fcd +dist/2025-12-11/rust-std-1.92.0-wasm32-wasip1-threads.tar.gz=87476037322f6bb9467467ce0b11bc2fe81d9fab181a14f6adbb949136f044d6 +dist/2025-12-11/rust-std-1.92.0-wasm32-wasip1-threads.tar.xz=feea056dd657a26560dfddfe4b53daeef3ded83c140b453b6dbdebaabd2a664c +dist/2025-12-11/rust-std-1.92.0-wasm32-wasip2.tar.gz=20b2ee79e2a66f80764f2829b9cd313bd66532fff85c71a75cd7d4f6f75decbf +dist/2025-12-11/rust-std-1.92.0-wasm32-wasip2.tar.xz=e69ce601b6b24eea08b0d9e1fb0d9bf2a4188b3109353b272be4d995f687c943 +dist/2025-12-11/rust-std-1.92.0-wasm32v1-none.tar.gz=b5d12a32aef0ce2be6999e7a15f21496e50fc9366e2dceb273e3816381821f73 +dist/2025-12-11/rust-std-1.92.0-wasm32v1-none.tar.xz=0b89f2b5a720589168a81e294fc80ab6bc2c7bbe5509030dd17ad38e221ce903 +dist/2025-12-11/rust-std-1.92.0-x86_64-apple-darwin.tar.gz=1e5a8fee4e038ea2d35d82a680e2b9bf44ffccb3746aaf9dbdc56cb14152dcb8 +dist/2025-12-11/rust-std-1.92.0-x86_64-apple-darwin.tar.xz=6ce143bf9e83c71e200f4180e8774ab22c8c8c2351c88484b13ff13be82c8d57 +dist/2025-12-11/rust-std-1.92.0-x86_64-apple-ios.tar.gz=4ca50621893f34bde5ad81cd82006c8b271fef8cc0ba4a4e1418fe3dbf599e56 +dist/2025-12-11/rust-std-1.92.0-x86_64-apple-ios.tar.xz=b6e38e5f8c9e6fb294681a7951301856b8f9424af4589e14493c0c939338814c +dist/2025-12-11/rust-std-1.92.0-x86_64-apple-ios-macabi.tar.gz=14e6389c01ab709dbf62885639b8c3e6fc97e6d8fa91f9805db26e9309107ec2 +dist/2025-12-11/rust-std-1.92.0-x86_64-apple-ios-macabi.tar.xz=6a292d774653f2deaac743060ec68bfd5d7ff01d9b364e1a7d1e57a679650b47 +dist/2025-12-11/rust-std-1.92.0-x86_64-fortanix-unknown-sgx.tar.gz=88fc95491ec06d98bde84ccf4b6a4cc63aa0a6d3e66e0d796de158afb7d69c67 +dist/2025-12-11/rust-std-1.92.0-x86_64-fortanix-unknown-sgx.tar.xz=b0339c3bf7966e7b1c9892f855c85d123382632f49a1d1f589db68bf0908feb7 +dist/2025-12-11/rust-std-1.92.0-x86_64-linux-android.tar.gz=b9074f6961baff09334afaff745fb16dbf9f05cdf856b17309d8e6232a281c40 +dist/2025-12-11/rust-std-1.92.0-x86_64-linux-android.tar.xz=ffd39429435ff2f0763b940dd6afb4b9ccb1ed443eeef4fff9f1e9b3c5730026 +dist/2025-12-11/rust-std-1.92.0-x86_64-pc-solaris.tar.gz=28f7f5568399c56e64f614194dc70f7073c0e394c5ad60bcb85dc1b1018c6089 +dist/2025-12-11/rust-std-1.92.0-x86_64-pc-solaris.tar.xz=776ceb389296b22a74bd7631f4440b965504d1687448030d2d51c853fe4598a5 +dist/2025-12-11/rust-std-1.92.0-x86_64-pc-windows-gnu.tar.gz=6256f3497e3b14b6650511e84fdfb51fc632db1908ae5a173dffcdc96c80b7ce +dist/2025-12-11/rust-std-1.92.0-x86_64-pc-windows-gnu.tar.xz=d4043304ef0e4792fb79a1153cbeca41308aac37cb1af3aa6bc3f0bb6d2276e1 +dist/2025-12-11/rust-std-1.92.0-x86_64-pc-windows-gnullvm.tar.gz=67bd7e328b9579c01365c01f58e29fa616806444eafb9b8bfead0de2b57fcf32 +dist/2025-12-11/rust-std-1.92.0-x86_64-pc-windows-gnullvm.tar.xz=6169605b3073a7c2d6960bc1c74cb9cd6b65f45ee34e7ede02368e07ce4564cf +dist/2025-12-11/rust-std-1.92.0-x86_64-pc-windows-msvc.tar.gz=3af377fb29083c2117e85e6a107aedb008bd76929c22d56ce45c5be1be3a2540 +dist/2025-12-11/rust-std-1.92.0-x86_64-pc-windows-msvc.tar.xz=b4e53a9c9b96a1a0618364791b7728a1c8978101ec6d1ee78fe930e1ef061994 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-freebsd.tar.gz=3616afb808cd030e65e66c51f6f0fb6a6fc52d877d0d70bb681b0c35238adbe8 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-freebsd.tar.xz=151929a4255175d14b2cbcb69ef46d9217add23be268b9cd1446f8eab16616f2 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-fuchsia.tar.gz=8b895dc4bbd95481cd171a6de01a0b74248fbd3f55bafec8dc0360e110946836 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-fuchsia.tar.xz=51ec26391d166e2f190a329919e3c7bd793861f02284aba461a086268725d9f1 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-illumos.tar.gz=a197e02ac48cdacfdb7487f612818b23c461c52e7e6015737a6b0a1cc2a744c5 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-illumos.tar.xz=31c6f2296543e684554b9eb4ac34551270a0a9c7d0cbc96986cf15a301e27035 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-linux-gnu.tar.gz=ba4e0b4a60c082e0b1cc6284a38bb144844c92f1aab09732cd1183658e08a6e7 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-linux-gnu.tar.xz=5f106805ed86ebf8df287039e53a45cf974391ef4d088c2760776b05b8e48b5d +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-linux-gnux32.tar.gz=8b9c9330278a97b79f3783dbacaaf4c0d110bb608cd1c615bb931b340ca6b27f +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-linux-gnux32.tar.xz=f29c2380d21edbd0cd9f674a2915ccc95822c9ecdae3b2e823f066de32760bb9 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-linux-musl.tar.gz=8bfd9a42c8295949d556587201acdb35d2bfb8b7ce55223845f337aa5614f9a3 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-linux-musl.tar.xz=11f0b7efccdb5e7972e3c0fc23693a487abc28b624675c08161d055a016d527e +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-linux-ohos.tar.gz=61dfeaf174eabc9152fff91b9de705539e76f623f37606ac878564fef79fb4fc +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-linux-ohos.tar.xz=a5d6c40e3e712d9d7ffcc3d3895e53dad19bcba792ad6b6945a60304bdb82be1 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-netbsd.tar.gz=1048621ad4bcd2c629882e74f9439d8b0508e6eb4ce5fee5dab0ffd6a5988261 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-netbsd.tar.xz=db6a8d3a091551701b12e40cc58d4a541adfb63f250074aae90d250329beb8de +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-none.tar.gz=a912deaa2ceff2042cb67a12e82b9212c849c1bc0321aea639f2ec432d13f9d2 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-none.tar.xz=1d8420ab8eb241a35e38b76470277c722bd5a7aa4ac0c7a565ad6f30b37cb852 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-redox.tar.gz=c5a5c0dc2ca2eec79b78d9efa4af92815a3b0aefdb4009fb523b9d2a989d55de +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-redox.tar.xz=c5c1466da81956d483fe673c604e7c66f5d16e44752d39c79fab45906738b178 +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-uefi.tar.gz=89a5e952221daa4cdbd4d033bb33a18855e1f3428a022af31843391af6cda8dc +dist/2025-12-11/rust-std-1.92.0-x86_64-unknown-uefi.tar.xz=1b849250cf095269f3a2c7bc2087a919386da7da28e80dc289e6268bc705142d +dist/2025-12-11/cargo-1.92.0-aarch64-apple-darwin.tar.gz=5295d590590a606d98e3f97b730fe3b4e8d96a0c78e5268232b15b3c45180d28 +dist/2025-12-11/cargo-1.92.0-aarch64-apple-darwin.tar.xz=bce6e7def37240c5a63115828017a9fc0ebcb31e64115382f5943b62b71aa34a +dist/2025-12-11/cargo-1.92.0-aarch64-pc-windows-gnullvm.tar.gz=77567d78fd5d8ae368a21682172aa929cb6b293dd03d234b01fb0e014b14c29c +dist/2025-12-11/cargo-1.92.0-aarch64-pc-windows-gnullvm.tar.xz=56d38a6a89e2a38ec777938d74feb93a3498bc8788df96a94fcb4eac2e07338b +dist/2025-12-11/cargo-1.92.0-aarch64-pc-windows-msvc.tar.gz=c283f18461a840191b2e03d19a8ac0e6441646b668a94a03a3e76e11b75296fb +dist/2025-12-11/cargo-1.92.0-aarch64-pc-windows-msvc.tar.xz=3fc47cc29781190c5075f807836c4b98d411aaf27c59598fbfb2aa781ccf6190 +dist/2025-12-11/cargo-1.92.0-aarch64-unknown-linux-gnu.tar.gz=f0bc99a9990f722c3c795bd778cae6aa7927a9907100698a1eed272beb4bef20 +dist/2025-12-11/cargo-1.92.0-aarch64-unknown-linux-gnu.tar.xz=cb2ce6be6411b986e25c71ad8a813f9dfbe3461738136fd684e3644f8dd75df4 +dist/2025-12-11/cargo-1.92.0-aarch64-unknown-linux-musl.tar.gz=92287147c07b5b31b69b355eb8040f4d3cb22cede8418ee77f806a93e90cc005 +dist/2025-12-11/cargo-1.92.0-aarch64-unknown-linux-musl.tar.xz=492614aa4fab1d58cdf495ab040426174e740038f715145bbbce7a87716a4c8b +dist/2025-12-11/cargo-1.92.0-arm-unknown-linux-gnueabi.tar.gz=09dc930cf59637c3bd48ff5bc0b53200949e5194e39fbba374f139a7a03f69a8 +dist/2025-12-11/cargo-1.92.0-arm-unknown-linux-gnueabi.tar.xz=d09d3e8402f868b784aa17f2e8268de91d8f4634c34bfb5be65596abc6043d35 +dist/2025-12-11/cargo-1.92.0-arm-unknown-linux-gnueabihf.tar.gz=401b054bc35f33835e6234352b519858ca9fe009bd01b85766dbcacce986dc48 +dist/2025-12-11/cargo-1.92.0-arm-unknown-linux-gnueabihf.tar.xz=dbeb44e4924218afc7c57db5f7a48058fe0bd0653c292fab5cc4a8b9016b2096 +dist/2025-12-11/cargo-1.92.0-armv7-unknown-linux-gnueabihf.tar.gz=861561f65347eb9020cb93daa51eb43592f994dca7c392a3e8d9771ab797435a +dist/2025-12-11/cargo-1.92.0-armv7-unknown-linux-gnueabihf.tar.xz=713f7d2ca8776ce537c0a5e716f7bdf644d54949c78c0a98ca4113f80bd670e7 +dist/2025-12-11/cargo-1.92.0-i686-pc-windows-gnu.tar.gz=c7f394ac5eb52bb9790feedbc2a22bbf5770c614f94ac899004e895580fe8955 +dist/2025-12-11/cargo-1.92.0-i686-pc-windows-gnu.tar.xz=8b6368d75f20c3cdfbb0c03f2cd7c386b9224bbf3717fbd635fff6ace0260660 +dist/2025-12-11/cargo-1.92.0-i686-pc-windows-msvc.tar.gz=25035fc699d3d907e0ac3c77ee4b524455b29d762b98951dd4f8084c64d0c416 +dist/2025-12-11/cargo-1.92.0-i686-pc-windows-msvc.tar.xz=a734070e84d1d9124bd0f4157eadf66c5b2030e49162f209ad0a0ebf895333ff +dist/2025-12-11/cargo-1.92.0-i686-unknown-linux-gnu.tar.gz=f95a54f1aabc6b4611d80f2bd5dda8f27719266f7cd829c5b9c2edcbf190a42c +dist/2025-12-11/cargo-1.92.0-i686-unknown-linux-gnu.tar.xz=63001bbde1c036fae9ad624807bfb18117c7e7cb4a04de81adc4acc7e8580c07 +dist/2025-12-11/cargo-1.92.0-loongarch64-unknown-linux-gnu.tar.gz=572a85632fcf90dd9fa359dd6eaed16266b75eaccc7d47e2c6974a01b0139b27 +dist/2025-12-11/cargo-1.92.0-loongarch64-unknown-linux-gnu.tar.xz=32f4b393f1471d7d50c9a50512f02116187b3ea6a885c26ff2d74f87fa72baa8 +dist/2025-12-11/cargo-1.92.0-loongarch64-unknown-linux-musl.tar.gz=0a02be499899e8a59fdf97e08bd1c2eaeb2bcb1328e230d8966eb1c0c0fc736e +dist/2025-12-11/cargo-1.92.0-loongarch64-unknown-linux-musl.tar.xz=edf8ae60bbe7821dfd02434951cca3b8c3ea63dc075b8a425ca45ac84da5796e +dist/2025-12-11/cargo-1.92.0-powerpc-unknown-linux-gnu.tar.gz=f33e2312126f52f0da9e5073b4311e9cad114228607e0fb5c3ae51b3add2a624 +dist/2025-12-11/cargo-1.92.0-powerpc-unknown-linux-gnu.tar.xz=1249c64f95d8187b3a89cf8429329bdbc98f53a9fc538e898c95c487e3234d90 +dist/2025-12-11/cargo-1.92.0-powerpc64-unknown-linux-gnu.tar.gz=414cfee5d5c39b757fb4bead92af90018601f8e40a447c2d2ee172a235605ecb +dist/2025-12-11/cargo-1.92.0-powerpc64-unknown-linux-gnu.tar.xz=e94a8f97c3143158e285b4f8ade1fae844961caca30c0eeed44f6c14da484f05 +dist/2025-12-11/cargo-1.92.0-powerpc64le-unknown-linux-gnu.tar.gz=69f56f4df9722d1a50273a69d32ed4593e84ec81f61ec949e58684e2ab1fac5c +dist/2025-12-11/cargo-1.92.0-powerpc64le-unknown-linux-gnu.tar.xz=49dd01f5d10e3f368181223db0fbf7dc191161f7d80a295de4909bf87e53da58 +dist/2025-12-11/cargo-1.92.0-powerpc64le-unknown-linux-musl.tar.gz=37a3d27d185abf8e3af51912f5f28b6acbd768445d1ca78e97acab5de4741b8a +dist/2025-12-11/cargo-1.92.0-powerpc64le-unknown-linux-musl.tar.xz=0f64d4df6bfad74ac9a60dfccf0c574ef56cd092d3207931b100e9b9130f7640 +dist/2025-12-11/cargo-1.92.0-riscv64gc-unknown-linux-gnu.tar.gz=6e6e42f0fbe0d0f8aca38946b3884b8d0cde6513ffe59fe9c2bcccd89d40f0e4 +dist/2025-12-11/cargo-1.92.0-riscv64gc-unknown-linux-gnu.tar.xz=e8708d0a929ad15941ecde368e8a156911927a805b492afafc737124b6aa55d4 +dist/2025-12-11/cargo-1.92.0-s390x-unknown-linux-gnu.tar.gz=8efdf1355d3eb6107854dcd3ab5b4396bed7b09910099dc791633740859cf5f2 +dist/2025-12-11/cargo-1.92.0-s390x-unknown-linux-gnu.tar.xz=a290edf359a5632dfda3b2325a309d9edeb58c97de97e3cc67274335b58adf05 +dist/2025-12-11/cargo-1.92.0-sparcv9-sun-solaris.tar.gz=535bf08187504fc5b157be2443973310e94ce75ab029ccf54f39f59b0f2d4c88 +dist/2025-12-11/cargo-1.92.0-sparcv9-sun-solaris.tar.xz=a0749eb1c52b8b6488fa0515ce0ae945f5a8dee331762334e1462776dfa0ec96 +dist/2025-12-11/cargo-1.92.0-x86_64-apple-darwin.tar.gz=3423880db7c38ba0259dbe8106039ad9cfb650c65b7bf311a33addd05aec3cb5 +dist/2025-12-11/cargo-1.92.0-x86_64-apple-darwin.tar.xz=b033a7c33aba8af947c9d0ab2785f9696347cded228ffe731897f1c627466262 +dist/2025-12-11/cargo-1.92.0-x86_64-pc-solaris.tar.gz=6f6f2a5b13fdde3ebcdb4e3f9a0a62104616940400bad050d27dec9c9cb00b25 +dist/2025-12-11/cargo-1.92.0-x86_64-pc-solaris.tar.xz=cbfc3e9543990f65dff8c76f0cc87b22b15f5ed6777cfb71b7eb7ea634a4d27f +dist/2025-12-11/cargo-1.92.0-x86_64-pc-windows-gnu.tar.gz=e2c59ffc93e18049f0ee829e6a9b768aa97a7aee480a28576cf786fd4aeb95dd +dist/2025-12-11/cargo-1.92.0-x86_64-pc-windows-gnu.tar.xz=962e0350346b417719cc36db333424a03e368d602fb411676c901f15487ea29c +dist/2025-12-11/cargo-1.92.0-x86_64-pc-windows-gnullvm.tar.gz=8c5de85558085a3e0f3b3280865236d3ea6d06c6e39fc458318c6b4becb7ad7f +dist/2025-12-11/cargo-1.92.0-x86_64-pc-windows-gnullvm.tar.xz=c27d5936e1c11feb33f3221b85741c33f783c8723fca84552e7c2a5a73959352 +dist/2025-12-11/cargo-1.92.0-x86_64-pc-windows-msvc.tar.gz=9f6178ddcaed7c9190c454db5da801e2fe6c8fde8600258a9bdd0e107e81ac3b +dist/2025-12-11/cargo-1.92.0-x86_64-pc-windows-msvc.tar.xz=f4057534ec58708ed3554957582a6c8e8c6abfee011b5c8ad45c3ab27c0b3076 +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-freebsd.tar.gz=a43043c5bbc907260594d542ea0dd17630d432024dd0af0b90c99b7397227f9e +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-freebsd.tar.xz=7bf1853c6ac4b426d7b4b67ee4ecf60f4a3e83151147a13b4cf04f81ccff3c4b +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-illumos.tar.gz=4c679e0c8c18649ca280096b1d6b7856a26540a6ac37e4fca371576c1dc0811e +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-illumos.tar.xz=a620fd5c893261ac0f9b59dfe6062f4a8e1eaf517b8116b64d3c0925dc1a5d1d +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-linux-gnu.tar.gz=2aa2b1c1df189d346f3937b4887c901b737df2663a667de17beb8f1098442bb9 +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-linux-gnu.tar.xz=e5e12be2c7126a7036c8adf573078a28b92611f5767cc9bd0a6f7c83081df103 +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-linux-musl.tar.gz=df116b5f1400daffd0074125e6c7cb98e5763ae9aefe341e3605b623042b7b11 +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-linux-musl.tar.xz=b37ef0ce8c49103a904559f17c83c6e5a182f0f165f158e7be00e9036ca8c6d5 +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-netbsd.tar.gz=e6ddc2363ad9073d101368110eeedb2bd91fa7a318f3823295edab3bc191747a +dist/2025-12-11/cargo-1.92.0-x86_64-unknown-netbsd.tar.xz=19065f32ac1edae4f000695d3814b5b1ae2649e218304d223e8af1634f465b37 +dist/2025-12-11/clippy-1.92.0-aarch64-apple-darwin.tar.gz=02cb1fb33fead2b4378c37db711fda2945b7487ccc462ee1abeeb3a4ffcff312 +dist/2025-12-11/clippy-1.92.0-aarch64-apple-darwin.tar.xz=08c65b6cf8faae3861706f8c97acf2aa6b784ed9455354c3b13495a7cfe5cb84 +dist/2025-12-11/clippy-1.92.0-aarch64-pc-windows-gnullvm.tar.gz=8a7fcc3e006b5fe1160011f692adec30a8c772585572541c52fc5647b9ec74d4 +dist/2025-12-11/clippy-1.92.0-aarch64-pc-windows-gnullvm.tar.xz=ea3e63c684273f629f918e8f50d510225c48a35ec28eaf026fa68c27f273bbd6 +dist/2025-12-11/clippy-1.92.0-aarch64-pc-windows-msvc.tar.gz=4fa5ed26256ad52a5f5f2039c3b2fa008ee890a6c366153806368c912d74b0db +dist/2025-12-11/clippy-1.92.0-aarch64-pc-windows-msvc.tar.xz=2aa2f1288072ea1f870d6d860d09f5911c1305d506f344b65cf5e27b5070e262 +dist/2025-12-11/clippy-1.92.0-aarch64-unknown-linux-gnu.tar.gz=37c0bc5ea8a2421d2353bbb871620617ac5de0c3aaa7548a0952d0d64d551222 +dist/2025-12-11/clippy-1.92.0-aarch64-unknown-linux-gnu.tar.xz=333ab38c673b589468b8293b525e5704fb52515d9d516ee28d3d34dd5a63d3c3 +dist/2025-12-11/clippy-1.92.0-aarch64-unknown-linux-musl.tar.gz=8e7a88b0bee51760b9c416dce4a0b355a74cf8681de115ef55bee14a6bf9ba46 +dist/2025-12-11/clippy-1.92.0-aarch64-unknown-linux-musl.tar.xz=8aecf9e71c9a8b349587e5c0c69dc91e373264ffc55d946a00ab8f9aff072e64 +dist/2025-12-11/clippy-1.92.0-arm-unknown-linux-gnueabi.tar.gz=39ce64be0c9878f2fd20f9bdda70f6cdf7bfc5928986c65719d93580cd784a11 +dist/2025-12-11/clippy-1.92.0-arm-unknown-linux-gnueabi.tar.xz=957d0c8bb77f6589d579d6133e98aaf351dfbbcec3ef1603659a90d9d7c2ce41 +dist/2025-12-11/clippy-1.92.0-arm-unknown-linux-gnueabihf.tar.gz=27ac4e9184be7e3a245ce6dddf438a2728a6b4fd8959e665e9f02b63ef99f671 +dist/2025-12-11/clippy-1.92.0-arm-unknown-linux-gnueabihf.tar.xz=0c360081ff01d1319cf9667b1c46f9ee684276bfbabce268589342e304c32299 +dist/2025-12-11/clippy-1.92.0-armv7-unknown-linux-gnueabihf.tar.gz=b85d187bb8f896383e349ec91699501205644152fce229c2ffbc87723e44d4ff +dist/2025-12-11/clippy-1.92.0-armv7-unknown-linux-gnueabihf.tar.xz=c47e0bb86ac299c36492a125f0231bc715787fc65ab28de5a2dd576ac613cbd3 +dist/2025-12-11/clippy-1.92.0-i686-pc-windows-gnu.tar.gz=4f8cecf22d6ba620ed2739ef84463f546da12b1b4320ac97144f4a1adda12e23 +dist/2025-12-11/clippy-1.92.0-i686-pc-windows-gnu.tar.xz=37bf65d4d059534ff633996963e497cc470fbd8f3d52a87af45298c1d3785473 +dist/2025-12-11/clippy-1.92.0-i686-pc-windows-msvc.tar.gz=5291a3c1f8c1ba513575b1240613eabf1fc423570d1fec8ed2927b8d7110b70f +dist/2025-12-11/clippy-1.92.0-i686-pc-windows-msvc.tar.xz=974ed40fe323ea3a6c2de1226aed5634d168b29113ac25d87370d4934c956ea5 +dist/2025-12-11/clippy-1.92.0-i686-unknown-linux-gnu.tar.gz=987e71ce7fd0b633db9fc0ab37eb149cb6d67add4e767d0fe30870cd6a6d2e62 +dist/2025-12-11/clippy-1.92.0-i686-unknown-linux-gnu.tar.xz=f21090ddb01503ab7e326ff8b1ab44121611121e83572aa2dba2c5ceffe12d22 +dist/2025-12-11/clippy-1.92.0-loongarch64-unknown-linux-gnu.tar.gz=bfd0bd79f87e61f99645cdc439be58b7fd64a4a9ef0ef32aeab2ec59ec250d1a +dist/2025-12-11/clippy-1.92.0-loongarch64-unknown-linux-gnu.tar.xz=70783e0b31682938db53b78f87c948acfe589e3ece5dee6ae6aa5b667a384f3c +dist/2025-12-11/clippy-1.92.0-loongarch64-unknown-linux-musl.tar.gz=cf38e7b7abb35fff475847285c8e6d71651bc230fc69df91d8b5d9fa7c09c277 +dist/2025-12-11/clippy-1.92.0-loongarch64-unknown-linux-musl.tar.xz=790b5b921c6423a007951f3839a083c4c73a9b64fb6c5019e1e117f98975d9f9 +dist/2025-12-11/clippy-1.92.0-powerpc-unknown-linux-gnu.tar.gz=162f860ee371105f141aa2ac9024d6c597615f4511b7bc628f33d6346625f4f3 +dist/2025-12-11/clippy-1.92.0-powerpc-unknown-linux-gnu.tar.xz=93ed9fdd6fc2655c7789ed096d57a47178532b6bda1ec4480adca7920563e934 +dist/2025-12-11/clippy-1.92.0-powerpc64-unknown-linux-gnu.tar.gz=d430546bbad6c5710d68bb88e6c6f405bd79b191af2da1ca2760b7d1adfd1b93 +dist/2025-12-11/clippy-1.92.0-powerpc64-unknown-linux-gnu.tar.xz=7912584254f455b90ed6ce6089c4efded33bb753d1bf948286ef2f4f782d2f30 +dist/2025-12-11/clippy-1.92.0-powerpc64le-unknown-linux-gnu.tar.gz=46c0b94dbf705439bebd9cb47de7fb6925e462b62db8885375205e4b48db518f +dist/2025-12-11/clippy-1.92.0-powerpc64le-unknown-linux-gnu.tar.xz=873047278043e6506f5c98b8f633a9b96dc49ff83869a86a151fe5b1b9455044 +dist/2025-12-11/clippy-1.92.0-powerpc64le-unknown-linux-musl.tar.gz=d630a37d6b9ff16c17a0b363adf6ace44bfbf71cd61db1c11f9e4d5ac135774f +dist/2025-12-11/clippy-1.92.0-powerpc64le-unknown-linux-musl.tar.xz=b0b1ebe31d7b2ec101cb0464c64bdcd28e1ca4172f765fcc8478ebd8b2f90b39 +dist/2025-12-11/clippy-1.92.0-riscv64gc-unknown-linux-gnu.tar.gz=7a5d3773d578649f3b683463c3d7559b8788370d8c79b4fb6036e3d72ced8e6d +dist/2025-12-11/clippy-1.92.0-riscv64gc-unknown-linux-gnu.tar.xz=bdedabeedd48080e6ef70376c52338fbb45ff80d1fbb12a81aa2d8cabbb706c8 +dist/2025-12-11/clippy-1.92.0-s390x-unknown-linux-gnu.tar.gz=80bd8a76913069a8f467f5121a0d2fa969a9dc525813d033f2234c3304531a06 +dist/2025-12-11/clippy-1.92.0-s390x-unknown-linux-gnu.tar.xz=41aa44f1cf37cac87b83e450eb19148c539ff266bb40dc146207ad5b9e1e1acc +dist/2025-12-11/clippy-1.92.0-sparcv9-sun-solaris.tar.gz=b73f28698ae974ebdb03f89cac3933fd34bd048ec2b4392d13fd082302b44720 +dist/2025-12-11/clippy-1.92.0-sparcv9-sun-solaris.tar.xz=c8e6cfbfe8442f9e34c0e6d2d2a6ae8f7fec5278b800c8adc4446c7ca89fc6d7 +dist/2025-12-11/clippy-1.92.0-x86_64-apple-darwin.tar.gz=4bdbc9b3a0dcbf04f1bf807dc74311fe4a4fbadc1887e57e01f3bae1d16bd801 +dist/2025-12-11/clippy-1.92.0-x86_64-apple-darwin.tar.xz=39cce87aab3d8b71350edcb3f943fba7bc59581ce1e65e158ee01e64cf0f1cf5 +dist/2025-12-11/clippy-1.92.0-x86_64-pc-solaris.tar.gz=8d9b266efa76ef5e4514705c61b7f92a0829a15bcc9e492895b551e7d9811ae1 +dist/2025-12-11/clippy-1.92.0-x86_64-pc-solaris.tar.xz=4cd9a59b61ba75146a20d24c016a14b971ffefbc9256fdd2145f31987520b8d7 +dist/2025-12-11/clippy-1.92.0-x86_64-pc-windows-gnu.tar.gz=c4a858e83cea2aab2eb101285b61df663eb08042226c4c13f4cdc18b3e94698e +dist/2025-12-11/clippy-1.92.0-x86_64-pc-windows-gnu.tar.xz=e9084ced75940856b57e61e3dda7ccce08d57890dff9c2caa8c814c356fa34d2 +dist/2025-12-11/clippy-1.92.0-x86_64-pc-windows-gnullvm.tar.gz=4495c4d97736105fe93fbe9bce954ba21508ebb8d31b473ebc0f6cf57ac981c3 +dist/2025-12-11/clippy-1.92.0-x86_64-pc-windows-gnullvm.tar.xz=b22f615210f328aabafa8d0eab3fed62784fa771956c51a92ae24a4dfd2073ed +dist/2025-12-11/clippy-1.92.0-x86_64-pc-windows-msvc.tar.gz=c4f5bf37194bf71a872ab0c7248338d7d6ddf28d0cf35cfde9bad94745bd9f9e +dist/2025-12-11/clippy-1.92.0-x86_64-pc-windows-msvc.tar.xz=51a9a67931a3e50eb0c26b4c6a7ec2ef6ddd633319343a2d4767710c1e33b21f +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-freebsd.tar.gz=617ef6d0be4bc2accc80909037e80d450fb1c0cbf797f0d6152fb50a26356437 +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-freebsd.tar.xz=73d799e51800ebe4af40395c63c46ec60fc51b7b5f56467b550d5a29f213075a +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-illumos.tar.gz=031f313032ef7c704f6212a5a84a798a828e9775a61e40ed7b246dcce43c12a7 +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-illumos.tar.xz=8b7383dfc99c026917b037c0fbad8f42da494a898d71fb7ff6c98ebfea4e9448 +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-linux-gnu.tar.gz=cd63fc19e6047742b735e959ed615f2013df5a0653913ec37a7e17fe9b0f99d7 +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-linux-gnu.tar.xz=2c1bf6e7da8ec50feba03fe188fc9a744ba59e2c6ece7970c13e201d08defa9a +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-linux-musl.tar.gz=81596511aa023876b881869224188d98d803bf393b6d5a5abe32b486f7fc1dc7 +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-linux-musl.tar.xz=8051ed46eb7c3650361dc26dc348dcdcbffb765ef099f9f44bbf8141e223050a +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-netbsd.tar.gz=55678429c5dd5370cb455bb6600dbb2c9383662789bf75577282a7c8b1a2ff10 +dist/2025-12-11/clippy-1.92.0-x86_64-unknown-netbsd.tar.xz=66ab46b59f74700d99b5554a191877011aa465e805b52118b65f4964c4ce3563 +dist/2025-12-11/rust-1.92.0-aarch64-pc-windows-msvc.msi=dbb09f213d5a9ebb3b2f4c7d65ba7c3c6cad7d9a76927d079604020c3ea0ad5a +dist/2025-12-11/rust-1.92.0-i686-pc-windows-gnu.msi=95a4922605093c67f6527c44c0e982026727b38a1e25979fcd8b2b0ff9cc7968 +dist/2025-12-11/rust-1.92.0-i686-pc-windows-msvc.msi=b73f851252fe3ae340b9be8e1f9cc05e34210498c0c3321a46243be633454909 +dist/2025-12-11/rust-1.92.0-x86_64-pc-windows-gnu.msi=899c79a6a68c59470d5f721ae90718f83cabd613e0a7fb595fe87ab6429a0fc6 +dist/2025-12-11/rust-1.92.0-x86_64-pc-windows-msvc.msi=bd3fd270e92d12094151aae3a67435b7fef2164b10d96e99a94230929cda09fd +dist/2025-12-11/rust-1.92.0-aarch64-apple-darwin.pkg=ce8eca0010032eb9ccb1baa8d3527d3ed7099c06db5a048205d0940c3866b0c9 +dist/2025-12-11/rust-1.92.0-x86_64-apple-darwin.pkg=d8b439cbabd4db21a3958d6cf9126bd216257f29c1457bba524363d06f4b1eec +dist/2025-12-11/rustc-1.92.0-src.tar.gz=9e0d2ca75c7e275fdc758255bf4b03afb3d65d1543602746907c933b6901c3b8 +dist/2025-12-11/rustc-1.92.0-src.tar.xz=ebee170bfe4c4dfc59521a101de651e5534f4dae889756a5c97ca9ea40d0c307 From 51580d38354328a58ff74c1124a67438722fda25 Mon Sep 17 00:00:00 2001 From: Cuong Le Date: Sat, 13 Dec 2025 21:34:20 +0700 Subject: [PATCH 0725/3801] Refine never_loop iterator reduction check --- clippy_lints/src/loops/mod.rs | 31 +++++++++++++++------------- clippy_lints/src/loops/never_loop.rs | 6 +++--- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 1070f568eddd..e273567c98eb 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -26,7 +26,8 @@ mod while_let_on_iterator; use clippy_config::Conf; use clippy_utils::msrvs::Msrv; -use clippy_utils::{higher, sym, ty}; +use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; +use clippy_utils::{higher, sym}; use rustc_ast::Label; use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; use rustc_lint::{LateContext, LateLintPass}; @@ -881,23 +882,25 @@ impl<'tcx> LateLintPass<'tcx> for Loops { manual_while_let_some::check(cx, condition, body, span); } - if let ExprKind::MethodCall(path, recv, [arg], _) = expr.kind - && matches!( + if let ExprKind::MethodCall(path, recv, args, _) = expr.kind { + if matches!( path.ident.name, sym::all | sym::any | sym::filter_map | sym::find_map | sym::flat_map | sym::for_each | sym::map - ) - { - unused_enumerate_index::check_method(cx, expr, recv, arg); - } + ) && let [arg] = args + { + unused_enumerate_index::check_method(cx, expr, recv, arg); + } - if let ExprKind::MethodCall(path, recv, args, _) = expr.kind - && matches!( + if matches!( path.ident.name, - sym::for_each | sym::try_for_each | sym::fold | sym::try_fold | sym::reduce | sym::all | sym::any - ) - && ty::get_iterator_item_ty(cx, cx.typeck_results().expr_ty(recv)).is_some() - { - never_loop::check_iterator_reduction(cx, expr, recv, args); + sym::all | sym::any | sym::for_each | sym::try_for_each | sym::fold | sym::try_fold | sym::reduce + ) && cx + .ty_based_def(expr) + .assoc_fn_parent(cx) + .is_diag_item(cx, sym::Iterator) + { + never_loop::check_iterator_reduction(cx, expr, recv, args); + } } } } diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index b57d800ff37c..dca104795ce3 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -3,7 +3,7 @@ use super::utils::make_iterator_snippet; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::ForLoop; use clippy_utils::macros::root_macro_call_first_node; -use clippy_utils::source::snippet; +use clippy_utils::source::{snippet, snippet_with_context}; use clippy_utils::sym; use clippy_utils::visitors::{Descend, for_each_expr_without_closures}; use rustc_errors::Applicability; @@ -111,8 +111,8 @@ pub(super) fn check_iterator_reduction<'tcx>( expr.span, "this iterator reduction never loops (closure always diverges)", |diag| { - let mut app = Applicability::Unspecified; - let recv_snip = make_iterator_snippet(cx, recv, &mut app); + let mut app = Applicability::HasPlaceholders; + let recv_snip = snippet_with_context(cx, recv.span, expr.span.ctxt(), "", &mut app).0; diag.note("if you only need one element, `if let Some(x) = iter.next()` is clearer"); let sugg = format!("if let Some(x) = {recv_snip}.next() {{ ... }}"); diag.span_suggestion_verbose(expr.span, "consider this pattern", sugg, app); From ce0f8c9b4dfc4355008615ccc4ed82b7a7f1122f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:43:00 +0200 Subject: [PATCH 0726/3801] test is hard to follow --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 34 -------------------- 1 file changed, 34 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 7ace34aed984..04bf7e2bd79b 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -294,40 +294,6 @@ fn test_prettify_ignore_link_targets() { assert_eq!(original, lengthen_lines(original, 100)); } -#[test] -fn test_sembr_then_prettify() { - let original = " -hi there. do -not split -short sentences. -hi again. -"; - let expected = " -hi there. -do -not split -short sentences. -hi again. -"; - let processed = comply(original); - assert_eq!(expected, processed); - let expected = " -hi there. -do not split -short sentences. -hi again. -"; - let processed = lengthen_lines(&processed, 50); - assert_eq!(expected, processed); - let expected = " -hi there. -do not split short sentences. -hi again. -"; - let processed = lengthen_lines(&processed, 50); - assert_eq!(expected, processed); -} - #[test] fn test_sembr_question_mark() { let original = " From cfb6a1f5c7883164b7fd9efb25431c23bda1daf5 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Sat, 13 Dec 2025 15:18:07 +0100 Subject: [PATCH 0727/3801] simplify how inline asm handles `MaybeUninit` --- compiler/rustc_codegen_cranelift/src/inline_asm.rs | 14 ++------------ compiler/rustc_hir_typeck/src/inline_asm.rs | 14 +------------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index 08cabe9d695c..ac0da06cbb8e 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -857,19 +857,9 @@ fn call_inline_asm<'tcx>( fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option { match ty.kind() { - // Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151 + // Adapted from https://github.com/rust-lang/rust/blob/df44a57fd29fca899ce473f85ed64efd0708dd7c/compiler/rustc_hir_typeck/src/inline_asm.rs#L180-L183 ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => { - let fields = &adt.non_enum_variant().fields; - let ty = fields[FieldIdx::ONE].ty(fx.tcx, args); - let ty::Adt(ty, args) = ty.kind() else { - unreachable!("expected first field of `MaybeUninit` to be an ADT") - }; - assert!( - ty.is_manually_drop(), - "expected first field of `MaybeUninit` to be `ManuallyDrop`" - ); - let fields = &ty.non_enum_variant().fields; - let ty = fields[FieldIdx::ZERO].ty(fx.tcx, args); + let ty = args.type_at(0); fx.clif_type(ty) } _ => fx.clif_type(ty), diff --git a/compiler/rustc_hir_typeck/src/inline_asm.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs index 6626c3edb546..7c1655f8201d 100644 --- a/compiler/rustc_hir_typeck/src/inline_asm.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -178,19 +178,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Never if is_input => return None, _ if ty.references_error() => return None, ty::Adt(adt, args) if self.tcx().is_lang_item(adt.did(), LangItem::MaybeUninit) => { - let fields = &adt.non_enum_variant().fields; - let ty = fields[FieldIdx::ONE].ty(self.tcx(), args); - // FIXME: Are we just trying to map to the `T` in `MaybeUninit`? - // If so, just get it from the args. - let ty::Adt(ty, args) = ty.kind() else { - unreachable!("expected first field of `MaybeUninit` to be an ADT") - }; - assert!( - ty.is_manually_drop(), - "expected first field of `MaybeUninit` to be `ManuallyDrop`" - ); - let fields = &ty.non_enum_variant().fields; - let ty = fields[FieldIdx::ZERO].ty(self.tcx(), args); + let ty = args.type_at(0); self.get_asm_ty(expr.span, ty) } _ => self.get_asm_ty(expr.span, ty), From 6a821c5518a81145048faccf619b211eb7c23c2f Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Sat, 13 Dec 2025 15:18:07 +0100 Subject: [PATCH 0728/3801] simplify how inline asm handles `MaybeUninit` --- src/inline_asm.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 08cabe9d695c..ac0da06cbb8e 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -857,19 +857,9 @@ fn call_inline_asm<'tcx>( fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option { match ty.kind() { - // Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151 + // Adapted from https://github.com/rust-lang/rust/blob/df44a57fd29fca899ce473f85ed64efd0708dd7c/compiler/rustc_hir_typeck/src/inline_asm.rs#L180-L183 ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => { - let fields = &adt.non_enum_variant().fields; - let ty = fields[FieldIdx::ONE].ty(fx.tcx, args); - let ty::Adt(ty, args) = ty.kind() else { - unreachable!("expected first field of `MaybeUninit` to be an ADT") - }; - assert!( - ty.is_manually_drop(), - "expected first field of `MaybeUninit` to be `ManuallyDrop`" - ); - let fields = &ty.non_enum_variant().fields; - let ty = fields[FieldIdx::ZERO].ty(fx.tcx, args); + let ty = args.type_at(0); fx.clif_type(ty) } _ => fx.clif_type(ty), From 9d62f73e874bd37f23b24e79faa9d5679c9953b4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:23:06 +0200 Subject: [PATCH 0729/3801] fix corner case --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 04bf7e2bd79b..2539a9eadda3 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -177,6 +177,9 @@ fn lengthen_lines(content: &str, limit: usize) -> String { let Some(next_line) = content.get(n + 1) else { continue; }; + if next_line.trim_start().starts_with("```") { + continue; + } if ignore(next_line, in_code_block) || REGEX_LIST_ENTRY.is_match(next_line) || REGEX_IGNORE_END.is_match(line) @@ -255,6 +258,12 @@ preserve next line preserve next line * three + +do not mess with code block chars +``` +leave the +text alone +``` "; let expected = "\ do not split short sentences @@ -269,6 +278,12 @@ preserve next line preserve next line * three + +do not mess with code block chars +``` +leave the +text alone +``` "; assert_eq!(expected, lengthen_lines(original, 50)); } From 3d73b326340b71048bb92b02acc805f5b10a0d47 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:31:53 +0200 Subject: [PATCH 0730/3801] sembr fuzzing.md --- src/doc/rustc-dev-guide/src/fuzzing.md | 68 +++++++++++++------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index cc98b49a97c6..295f2ef87265 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -3,12 +3,13 @@ For the purposes of this guide, *fuzzing* is any testing methodology that -involves compiling a wide variety of programs in an attempt to uncover bugs in -rustc. Fuzzing is often used to find internal compiler errors (ICEs). Fuzzing -can be beneficial, because it can find bugs before users run into them and +involves compiling a wide variety of programs in an attempt to uncover bugs in rustc. +Fuzzing is often used to find internal compiler errors (ICEs). +Fuzzing can be beneficial, because it can find bugs before users run into them and provide small, self-contained programs that make the bug easier to track down. However, some common mistakes can reduce the helpfulness of fuzzing and end up -making contributors' lives harder. To maximize your positive impact on the Rust +making contributors' lives harder. +To maximize your positive impact on the Rust project, please read this guide before reporting fuzzer-generated bugs! ## Guidelines @@ -28,16 +29,14 @@ project, please read this guide before reporting fuzzer-generated bugs! - Don't report lots of bugs that use internal features, including but not limited to `custom_mir`, `lang_items`, `no_core`, and `rustc_attrs`. -- Don't seed your fuzzer with inputs that are known to crash rustc (details - below). +- Don't seed your fuzzer with inputs that are known to crash rustc (details below). ### Discussion If you're not sure whether or not an ICE is a duplicate of one that's already -been reported, please go ahead and report it and link to issues you think might -be related. In general, ICEs on the same line but with different *query stacks* -are usually distinct bugs. For example, [#109020][#109020] and [#109129][#109129] -had similar error messages: +been reported, please go ahead and report it and link to issues you think might be related. +In general, ICEs on the same line but with different *query stacks* are usually distinct bugs. +For example, [#109020][#109020] and [#109129][#109129] had similar error messages: ``` error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead @@ -63,10 +62,10 @@ end of query stack ## Building a corpus -When building a corpus, be sure to avoid collecting tests that are already -known to crash rustc. A fuzzer that is seeded with such tests is more likely to -generate bugs with the same root cause, wasting everyone's time. The simplest -way to avoid this is to loop over each file in the corpus, see if it causes an +When building a corpus, be sure to avoid collecting tests that are already known to crash rustc. +A fuzzer that is seeded with such tests is more likely to +generate bugs with the same root cause, wasting everyone's time. +The simplest way to avoid this is to loop over each file in the corpus, see if it causes an ICE, and remove it if so. To build a corpus, you may want to use: @@ -84,16 +83,16 @@ To build a corpus, you may want to use: Here are a few things you can do to help the Rust project after filing an ICE. - [Bisect][bisect] the bug to figure out when it was introduced. - If you find the regressing PR / commit, you can mark the issue with the label - `S-has-bisection`. If not, consider applying `E-needs-bisection` instead. + If you find the regressing PR / commit, you can mark the issue with the label `S-has-bisection`. + If not, consider applying `E-needs-bisection` instead. - Fix "distractions": problems with the test case that don't contribute to triggering the ICE, such as syntax errors or borrow-checking errors -- Minimize the test case (see below). If successful, you can label the - issue with `S-has-mcve`. Otherwise, you can apply `E-needs-mcve`. +- Minimize the test case (see below). + If successful, you can label the issue with `S-has-mcve`. + Otherwise, you can apply `E-needs-mcve`. - Add the minimal test case to the rust-lang/rust repo as a [crash test]. While you're at it, consider including other "untracked" crashes in your PR. - Please don't forget to mark all relevant issues with `S-bug-has-test` once - your PR is merged. + Please don't forget to mark all relevant issues with `S-bug-has-test` once your PR is merged. See also [applying and removing labels][labeling]. @@ -103,13 +102,14 @@ See also [applying and removing labels][labeling]. ## Minimization -It is helpful to carefully *minimize* the fuzzer-generated input. When -minimizing, be careful to preserve the original error, and avoid introducing +It is helpful to carefully *minimize* the fuzzer-generated input. +When minimizing, be careful to preserve the original error, and avoid introducing distracting problems such as syntax, type-checking, or borrow-checking errors. -There are some tools that can help with minimization. If you're not sure how -to avoid introducing syntax, type-, and borrow-checking errors while using -these tools, post both the complete and minimized test cases. Generally, +There are some tools that can help with minimization. +If you're not sure how to avoid introducing syntax, type-, and borrow-checking errors while using +these tools, post both the complete and minimized test cases. +Generally, *syntax-aware* tools give the best results in the least amount of time. [`treereduce-rust`][treereduce] and [picireny][picireny] are syntax-aware. [`halfempty`][halfempty] is not, but is generally a high-quality tool. @@ -121,21 +121,23 @@ these tools, post both the complete and minimized test cases. Generally, ## Effective fuzzing When fuzzing rustc, you may want to avoid generating machine code, since this -is mostly done by LLVM. Try `--emit=mir` instead. +is mostly done by LLVM. +Try `--emit=mir` instead. -A variety of compiler flags can uncover different issues. `-Zmir-opt-level=4` -will turn on MIR optimization passes that are not run by default, potentially -uncovering interesting bugs. `-Zvalidate-mir` can help uncover such bugs. +A variety of compiler flags can uncover different issues. +`-Zmir-opt-level=4` will turn on MIR optimization passes that are not run by default, potentially +uncovering interesting bugs. +`-Zvalidate-mir` can help uncover such bugs. If you're fuzzing a compiler you built, you may want to build it with `-C -target-cpu=native` or even PGO/BOLT to squeeze out a few more executions per -second. Of course, it's best to try multiple build configurations and see +target-cpu=native` or even PGO/BOLT to squeeze out a few more executions per second. +Of course, it's best to try multiple build configurations and see what actually results in superior throughput. You may want to build rustc from source with debug assertions to find additional bugs, though this is a trade-off: it can slow down fuzzing by -requiring extra work for every execution. To enable debug assertions, add this -to `bootstrap.toml` when compiling rustc: +requiring extra work for every execution. +To enable debug assertions, add this to `bootstrap.toml` when compiling rustc: ```toml [rust] From cfe2be49b53a192bbe20946743503032ebaf071b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:36:27 +0200 Subject: [PATCH 0731/3801] make more readable --- src/doc/rustc-dev-guide/src/fuzzing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 295f2ef87265..009ca0770668 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -5,8 +5,8 @@ For the purposes of this guide, *fuzzing* is any testing methodology that involves compiling a wide variety of programs in an attempt to uncover bugs in rustc. Fuzzing is often used to find internal compiler errors (ICEs). -Fuzzing can be beneficial, because it can find bugs before users run into them and -provide small, self-contained programs that make the bug easier to track down. +Fuzzing can be beneficial, because it can find bugs before users run into them. +It also provides small, self-contained programs that make the bug easier to track down. However, some common mistakes can reduce the helpfulness of fuzzing and end up making contributors' lives harder. To maximize your positive impact on the Rust @@ -144,7 +144,7 @@ To enable debug assertions, add this to `bootstrap.toml` when compiling rustc: debug-assertions = true ``` -ICEs that require debug assertions to reproduce should be tagged +ICEs that require debug assertions to reproduce should be tagged [`requires-debug-assertions`][requires-debug-assertions]. [requires-debug-assertions]: https://github.com/rust-lang/rust/labels/requires-debug-assertions From a1b57f4383e1c6c8df6ce5d4e684c39ce11420e2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:39:16 +0200 Subject: [PATCH 0732/3801] remove unclear text --- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 009ca0770668..b4792f8ef9f1 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -22,7 +22,7 @@ project, please read this guide before reporting fuzzer-generated bugs! - Include a reasonably minimal, standalone example along with any bug report - Include all of the information requested in the bug report template - Search for existing reports with the same message and query stack -- Format the test case with `rustfmt`, if it maintains the bug +- Format the test case with `rustfmt` - Indicate that the bug was found by fuzzing *Please don't:* From ae39d3d9ab3ef431d2e7aeedbd0b084089b0de84 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 13 Dec 2025 15:43:01 +0100 Subject: [PATCH 0733/3801] Improve spans of malformed attribute errors --- .../rustc_attr_parsing/src/attributes/cfg.rs | 2 +- .../src/attributes/codegen_attrs.rs | 6 +++--- .../src/attributes/confusables.rs | 2 +- .../src/attributes/debugger.rs | 2 +- .../rustc_attr_parsing/src/attributes/doc.rs | 2 +- .../src/attributes/link_attrs.rs | 4 ++-- .../src/attributes/macro_attrs.rs | 8 ++++---- .../src/attributes/must_use.rs | 4 ++-- .../src/attributes/proc_macro_attrs.rs | 6 +++--- .../src/attributes/prototype.rs | 2 +- .../rustc_attr_parsing/src/attributes/repr.rs | 4 ++-- .../src/attributes/stability.rs | 4 ++-- .../rustc_attr_parsing/src/attributes/traits.rs | 2 +- .../rustc_attr_parsing/src/attributes/util.rs | 2 +- compiler/rustc_attr_parsing/src/context.rs | 11 ++++++++++- compiler/rustc_attr_parsing/src/parser.rs | 6 +++++- .../src/session_diagnostics.rs | 4 ++++ tests/rustdoc-ui/invalid-cfg.stderr | 16 ++++++++++++---- tests/ui/attributes/invalid-macro-use.stderr | 4 +++- tests/ui/attributes/malformed-attrs.stderr | 12 +++++++++--- tests/ui/attributes/malformed-fn-align.stderr | 6 +++--- tests/ui/attributes/malformed-must_use.stderr | 4 +++- .../ui/attributes/malformed-static-align.stderr | 6 +++--- .../rustc_skip_during_method_dispatch.stderr | 6 +++--- .../cfg-attr-syntax-validation.stderr | 6 +++--- .../issue-43106-gating-of-macro_use.stderr | 4 +++- .../link-attr-validation-early.stderr | 4 +++- .../link-attr-validation-late.stderr | 6 +++--- tests/ui/malformed/malformed-regressions.stderr | 4 +++- tests/ui/proc-macro/attribute.stderr | 4 +++- tests/ui/repr/repr.stderr | 8 ++++++-- tests/ui/sanitize-attr/invalid-sanitize.stderr | 4 +++- .../stability-attribute-sanity-4.stderr | 12 ++++++------ tests/ui/target-feature/invalid-attribute.stderr | 6 +++--- 34 files changed, 116 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 5b4786a64ef2..798cc1076541 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -42,7 +42,7 @@ pub fn parse_cfg( args: &ArgParser, ) -> Option { let ArgParser::List(list) = args else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; }; let Some(single) = list.single() else { diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 7d3a7418f06c..17c748fa3e68 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -25,7 +25,7 @@ impl SingleAttributeParser for OptimizeParser { fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(list) = args.list() else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; }; @@ -478,7 +478,7 @@ fn parse_tf_attribute( ) -> impl IntoIterator { let mut features = Vec::new(); let ArgParser::List(list) = args else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return features; }; if list.is_empty() { @@ -601,7 +601,7 @@ impl SingleAttributeParser for SanitizeParser { fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(list) = args.list() else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; }; diff --git a/compiler/rustc_attr_parsing/src/attributes/confusables.rs b/compiler/rustc_attr_parsing/src/attributes/confusables.rs index 97e78dfb136b..0b7ac989346a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/confusables.rs +++ b/compiler/rustc_attr_parsing/src/attributes/confusables.rs @@ -13,7 +13,7 @@ impl AttributeParser for ConfusablesParser { template!(List: &[r#""name1", "name2", ..."#]), |this, cx, args| { let Some(list) = args.list() else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return; }; diff --git a/compiler/rustc_attr_parsing/src/attributes/debugger.rs b/compiler/rustc_attr_parsing/src/attributes/debugger.rs index c88b795aab03..52a66942cf93 100644 --- a/compiler/rustc_attr_parsing/src/attributes/debugger.rs +++ b/compiler/rustc_attr_parsing/src/attributes/debugger.rs @@ -21,7 +21,7 @@ impl CombineAttributeParser for DebuggerViualizerParser { args: &ArgParser, ) -> impl IntoIterator { let Some(l) = args.list() else { - cx.expected_list(args.span().unwrap_or(cx.attr_span)); + cx.expected_list(cx.attr_span, args); return None; }; let Some(single) = l.single() else { diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index b6fea37c92aa..16dbb04b48eb 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -106,7 +106,7 @@ impl DocParser { } Some(sym::attr) => { let Some(list) = args.list() else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return; }; diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index fe8f3578fe14..388553c8fd9b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -76,7 +76,7 @@ impl CombineAttributeParser for LinkParser { return None; } _ => { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; } }; @@ -379,7 +379,7 @@ impl LinkParser { return true; } let Some(link_cfg) = item.args().list() else { - cx.expected_list(item.span()); + cx.expected_list(item.span(), item.args()); return true; }; let Some(link_cfg) = link_cfg.single() else { diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 8a456778643b..0f1ab02fca25 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -99,8 +99,8 @@ impl AttributeParser for MacroUseParser { } } } - ArgParser::NameValue(_) => { - cx.expected_list_or_no_args(span); + ArgParser::NameValue(nv) => { + cx.expected_list_or_no_args(nv.args_span()); } } }, @@ -155,8 +155,8 @@ impl SingleAttributeParser for MacroExportParser { } } } - ArgParser::NameValue(_) => { - cx.expected_list_or_no_args(cx.attr_span); + ArgParser::NameValue(nv) => { + cx.expected_list_or_no_args(nv.args_span()); return None; } }; diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index 2cbf6300ede4..673e2c902da0 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs @@ -41,8 +41,8 @@ impl SingleAttributeParser for MustUseParser { }; Some(value_str) } - ArgParser::List(_) => { - cx.expected_name_value(cx.attr_span, None); + ArgParser::List(list) => { + cx.expected_nv_or_no_args(list.span); return None; } }, diff --git a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs index e1762005d4c4..3674aa7124ab 100644 --- a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs @@ -65,7 +65,7 @@ fn parse_derive_like( if args.no_args().is_ok() && !trait_name_mandatory { return Some((None, ThinVec::new())); } - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; }; let mut items = list.mixed(); @@ -96,7 +96,7 @@ fn parse_derive_like( let mut attributes = ThinVec::new(); if let Some(attrs) = items.next() { let Some(attr_list) = attrs.meta_item() else { - cx.expected_list(attrs.span()); + cx.unexpected_literal(attrs.span()); return None; }; if !attr_list.path().word_is(sym::attributes) { @@ -104,7 +104,7 @@ fn parse_derive_like( return None; } let Some(attr_list) = attr_list.args().list() else { - cx.expected_list(attrs.span()); + cx.expected_list(attrs.span(), attr_list.args()); return None; }; diff --git a/compiler/rustc_attr_parsing/src/attributes/prototype.rs b/compiler/rustc_attr_parsing/src/attributes/prototype.rs index aef983df0204..ac50fe33839d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prototype.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prototype.rs @@ -27,7 +27,7 @@ impl SingleAttributeParser for CustomMirParser { fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(list) = args.list() else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; }; diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 4520e4f5dbac..9ad103f3bb8e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -33,7 +33,7 @@ impl CombineAttributeParser for ReprParser { let mut reprs = Vec::new(); let Some(list) = args.list() else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return reprs; }; @@ -278,7 +278,7 @@ impl AlignParser { fn parse(&mut self, cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) { match args { ArgParser::NoArgs | ArgParser::NameValue(_) => { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); } ArgParser::List(list) => { let Some(align) = list.single() else { diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index 383d72766686..6d4f77ef1751 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -295,7 +295,7 @@ pub(crate) fn parse_stability( let mut since = None; let ArgParser::List(list) = args else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; }; @@ -367,7 +367,7 @@ pub(crate) fn parse_unstability( let mut old_name = None; let ArgParser::List(list) = args else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; }; diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index a9b76021a989..ee5895a6efd0 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -22,7 +22,7 @@ impl SingleAttributeParser for SkipDuringMethodDispatchParser { let mut array = false; let mut boxed_slice = false; let Some(args) = args.list() else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; }; if args.is_empty() { diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs index 4e3478abbf4f..431ba539b2ba 100644 --- a/compiler/rustc_attr_parsing/src/attributes/util.rs +++ b/compiler/rustc_attr_parsing/src/attributes/util.rs @@ -43,7 +43,7 @@ pub(crate) fn parse_single_integer( args: &ArgParser, ) -> Option { let Some(list) = args.list() else { - cx.expected_list(cx.attr_span); + cx.expected_list(cx.attr_span, args); return None; }; let Some(single) = list.single() else { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index bd19eaf9ab39..ec9f62bf1eb6 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -464,7 +464,12 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedIntegerLiteral) } - pub(crate) fn expected_list(&self, span: Span) -> ErrorGuaranteed { + pub(crate) fn expected_list(&self, span: Span, args: &ArgParser) -> ErrorGuaranteed { + let span = match args { + ArgParser::NoArgs => span, + ArgParser::List(list) => list.span, + ArgParser::NameValue(nv) => nv.args_span(), + }; self.emit_parse_error(span, AttributeParseErrorReason::ExpectedList) } @@ -472,6 +477,10 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedListOrNoArgs) } + pub(crate) fn expected_nv_or_no_args(&self, span: Span) -> ErrorGuaranteed { + self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNameValueOrNoArgs) + } + pub(crate) fn expected_no_args(&self, span: Span) -> ErrorGuaranteed { self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNoArgs) } diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 09ecfaedb5ed..9551744d5ec5 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -177,7 +177,7 @@ impl ArgParser { match self { Self::NoArgs => Ok(()), Self::List(args) => Err(args.span), - Self::NameValue(args) => Err(args.eq_span.to(args.value_span)), + Self::NameValue(args) => Err(args.args_span()), } } } @@ -314,6 +314,10 @@ impl NameValueParser { pub fn value_as_str(&self) -> Option { self.value_as_lit().kind.str() } + + pub fn args_span(&self) -> Span { + self.eq_span.to(self.value_span) + } } fn expr_to_lit( diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index b93b2f737f6e..4aea4064b1c4 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -511,6 +511,7 @@ pub(crate) enum AttributeParseErrorReason<'a> { ExpectedSingleArgument, ExpectedList, ExpectedListOrNoArgs, + ExpectedNameValueOrNoArgs, UnexpectedLiteral, ExpectedNameValue(Option), DuplicateKey(Symbol), @@ -586,6 +587,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { AttributeParseErrorReason::ExpectedListOrNoArgs => { diag.span_label(self.span, "expected a list or no arguments here"); } + AttributeParseErrorReason::ExpectedNameValueOrNoArgs => { + diag.span_label(self.span, "didn't expect a list here"); + } AttributeParseErrorReason::DuplicateKey(key) => { diag.span_label(self.span, format!("found `{key}` used as a key more than once")); diag.code(E0538); diff --git a/tests/rustdoc-ui/invalid-cfg.stderr b/tests/rustdoc-ui/invalid-cfg.stderr index 84f8cea54314..539611070969 100644 --- a/tests/rustdoc-ui/invalid-cfg.stderr +++ b/tests/rustdoc-ui/invalid-cfg.stderr @@ -2,7 +2,9 @@ error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:2:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^^^^-----^^ + | | + | expected this to be a list error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:3:1 @@ -16,7 +18,9 @@ error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:7:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^^^^-----^^ + | | + | expected this to be a list error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:8:1 @@ -30,7 +34,9 @@ error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:12:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^^^^-----^^ + | | + | expected this to be a list error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:13:1 @@ -44,7 +50,9 @@ error[E0539]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:18:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^^^^-----^^ + | | + | expected this to be a list error[E0805]: malformed `doc` attribute input --> $DIR/invalid-cfg.rs:19:1 diff --git a/tests/ui/attributes/invalid-macro-use.stderr b/tests/ui/attributes/invalid-macro-use.stderr index ade9c9a21b8a..fe235ab209f3 100644 --- a/tests/ui/attributes/invalid-macro-use.stderr +++ b/tests/ui/attributes/invalid-macro-use.stderr @@ -14,7 +14,9 @@ error[E0539]: malformed `macro_use` attribute input --> $DIR/invalid-macro-use.rs:4:1 | LL | #[macro_use = 5] - | ^^^^^^^^^^^^^^^^ expected a list or no arguments here + | ^^^^^^^^^^^^---^ + | | + | expected a list or no arguments here | = note: for more information, visit help: try changing it to one of the following valid forms of the attribute diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 3e04a7e1a4e3..0cd88e254194 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -318,7 +318,9 @@ error[E0539]: malformed `must_use` attribute input --> $DIR/malformed-attrs.rs:61:1 | LL | #[must_use()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^--^ + | | + | didn't expect a list here | = note: for more information, visit help: try changing it to one of the following valid forms of the attribute @@ -628,7 +630,9 @@ error[E0539]: malformed `macro_use` attribute input --> $DIR/malformed-attrs.rs:216:1 | LL | #[macro_use = 1] - | ^^^^^^^^^^^^^^^^ expected a list or no arguments here + | ^^^^^^^^^^^^---^ + | | + | expected a list or no arguments here | = note: for more information, visit help: try changing it to one of the following valid forms of the attribute @@ -644,7 +648,9 @@ error[E0539]: malformed `macro_export` attribute input --> $DIR/malformed-attrs.rs:221:1 | LL | #[macro_export = 18] - | ^^^^^^^^^^^^^^^^^^^^ expected a list or no arguments here + | ^^^^^^^^^^^^^^^----^ + | | + | expected a list or no arguments here | help: try changing it to one of the following valid forms of the attribute | diff --git a/tests/ui/attributes/malformed-fn-align.stderr b/tests/ui/attributes/malformed-fn-align.stderr index b419df8ea2d1..ad01457d063b 100644 --- a/tests/ui/attributes/malformed-fn-align.stderr +++ b/tests/ui/attributes/malformed-fn-align.stderr @@ -20,9 +20,9 @@ error[E0539]: malformed `rustc_align` attribute input --> $DIR/malformed-fn-align.rs:17:1 | LL | #[rustc_align = 16] - | ^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^----^ + | | | + | | expected this to be a list | help: must be of the form: `#[rustc_align()]` error[E0589]: invalid alignment value: not an unsuffixed integer diff --git a/tests/ui/attributes/malformed-must_use.stderr b/tests/ui/attributes/malformed-must_use.stderr index 38855f24a011..d4797baa1b0b 100644 --- a/tests/ui/attributes/malformed-must_use.stderr +++ b/tests/ui/attributes/malformed-must_use.stderr @@ -2,7 +2,9 @@ error[E0539]: malformed `must_use` attribute input --> $DIR/malformed-must_use.rs:1:1 | LL | #[must_use()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^--^ + | | + | didn't expect a list here | = note: for more information, visit help: try changing it to one of the following valid forms of the attribute diff --git a/tests/ui/attributes/malformed-static-align.stderr b/tests/ui/attributes/malformed-static-align.stderr index e618ca8acd75..6f5225f7278d 100644 --- a/tests/ui/attributes/malformed-static-align.stderr +++ b/tests/ui/attributes/malformed-static-align.stderr @@ -2,9 +2,9 @@ error[E0539]: malformed `rustc_align_static` attribute input --> $DIR/malformed-static-align.rs:4:1 | LL | #[rustc_align_static = 16] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^^^^^^^^----^ + | | | + | | expected this to be a list | help: must be of the form: `#[rustc_align_static()]` error[E0589]: invalid alignment value: not an unsuffixed integer diff --git a/tests/ui/attributes/rustc_skip_during_method_dispatch.stderr b/tests/ui/attributes/rustc_skip_during_method_dispatch.stderr index 094987e944fd..04907f5d638e 100644 --- a/tests/ui/attributes/rustc_skip_during_method_dispatch.stderr +++ b/tests/ui/attributes/rustc_skip_during_method_dispatch.stderr @@ -11,9 +11,9 @@ error[E0539]: malformed `rustc_skip_during_method_dispatch` attribute input --> $DIR/rustc_skip_during_method_dispatch.rs:7:1 | LL | #[rustc_skip_during_method_dispatch = "array"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^ + | | | + | | expected this to be a list | help: must be of the form: `#[rustc_skip_during_method_dispatch(array, boxed_slice)]` error[E0539]: malformed `rustc_skip_during_method_dispatch` attribute input diff --git a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr index e73b20f2d5d3..1be52de708e5 100644 --- a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr @@ -13,9 +13,9 @@ error[E0539]: malformed `cfg` attribute input --> $DIR/cfg-attr-syntax-validation.rs:7:1 | LL | #[cfg = 10] - | ^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^----^ + | | | + | | expected this to be a list | help: must be of the form: `#[cfg(predicate)]` | = note: for more information, visit diff --git a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr index e8fcef8a1638..1aa0e8fc2830 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr @@ -20,7 +20,9 @@ error[E0539]: malformed `macro_use` attribute input --> $DIR/issue-43106-gating-of-macro_use.rs:15:5 | LL | #[macro_use = "2700"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^ expected a list or no arguments here + | ^^^^^^^^^^^^--------^ + | | + | expected a list or no arguments here | = note: for more information, visit help: try changing it to one of the following valid forms of the attribute diff --git a/tests/ui/link-native-libs/link-attr-validation-early.stderr b/tests/ui/link-native-libs/link-attr-validation-early.stderr index 101df0371b54..4bf88e150f45 100644 --- a/tests/ui/link-native-libs/link-attr-validation-early.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-early.stderr @@ -10,7 +10,9 @@ error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-early.rs:3:1 | LL | #[link = "foo"] - | ^^^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^-------^ + | | + | expected this to be a list | = note: for more information, visit diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr index a5f654ca0aeb..b09431f923aa 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr @@ -142,9 +142,9 @@ error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:24:1 | LL | #[link(name = "...", cfg = "literal")] - | ^^^^^^^^^^^^^^^^^^^^^---------------^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^ + | | + | expected this to be a list | = note: for more information, visit diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index f46afda1e477..2bf6ff3a9e7a 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr @@ -10,7 +10,9 @@ error[E0539]: malformed `link` attribute input --> $DIR/malformed-regressions.rs:10:1 | LL | #[link = ""] - | ^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^----^ + | | + | expected this to be a list | = note: for more information, visit diff --git a/tests/ui/proc-macro/attribute.stderr b/tests/ui/proc-macro/attribute.stderr index e7127c8ef1d2..24962cf270a4 100644 --- a/tests/ui/proc-macro/attribute.stderr +++ b/tests/ui/proc-macro/attribute.stderr @@ -16,7 +16,9 @@ error[E0539]: malformed `proc_macro_derive` attribute input --> $DIR/attribute.rs:15:1 | LL | #[proc_macro_derive = ""] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^^^^^^^^^^^^^^----^ + | | + | expected this to be a list | = note: for more information, visit help: try changing it to one of the following valid forms of the attribute diff --git a/tests/ui/repr/repr.stderr b/tests/ui/repr/repr.stderr index e8168f8f9a58..a842590c9639 100644 --- a/tests/ui/repr/repr.stderr +++ b/tests/ui/repr/repr.stderr @@ -10,7 +10,9 @@ error[E0539]: malformed `repr` attribute input --> $DIR/repr.rs:4:1 | LL | #[repr = "B"] - | ^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^-----^ + | | + | expected this to be a list | = note: for more information, visit @@ -18,7 +20,9 @@ error[E0539]: malformed `repr` attribute input --> $DIR/repr.rs:7:1 | LL | #[repr = "C"] - | ^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^-----^ + | | + | expected this to be a list | = note: for more information, visit diff --git a/tests/ui/sanitize-attr/invalid-sanitize.stderr b/tests/ui/sanitize-attr/invalid-sanitize.stderr index 2a3497678bdc..26ef31603d88 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.stderr +++ b/tests/ui/sanitize-attr/invalid-sanitize.stderr @@ -42,7 +42,9 @@ error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:18:1 | LL | #[sanitize = "off"] - | ^^^^^^^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^^^^^-------^ + | | + | expected this to be a list error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:21:1 diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr b/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr index f656aeaa16c7..9b3f540198ce 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr +++ b/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr @@ -11,9 +11,9 @@ error[E0539]: malformed `unstable` attribute input --> $DIR/stability-attribute-sanity-4.rs:11:5 | LL | #[unstable = "b"] - | ^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^-----^ + | | | + | | expected this to be a list | help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]` error[E0539]: malformed `stable` attribute input @@ -29,9 +29,9 @@ error[E0539]: malformed `stable` attribute input --> $DIR/stability-attribute-sanity-4.rs:17:5 | LL | #[stable = "a"] - | ^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^-----^ + | | | + | | expected this to be a list | help: must be of the form: `#[stable(feature = "name", since = "version")]` error[E0542]: missing 'since' diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr index eaa26aa3ecaf..05a836b01af5 100644 --- a/tests/ui/target-feature/invalid-attribute.stderr +++ b/tests/ui/target-feature/invalid-attribute.stderr @@ -26,9 +26,9 @@ error[E0539]: malformed `target_feature` attribute input --> $DIR/invalid-attribute.rs:17:1 | LL | #[target_feature = "+sse2"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^^^^---------^ + | | | + | | expected this to be a list | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]` error[E0539]: malformed `target_feature` attribute input From d79d0aef3c702e1bfe735bff2615f4160852765b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:46:47 +0200 Subject: [PATCH 0734/3801] horizontal scroll is excessive for these examples --- src/doc/rustc-dev-guide/src/fuzzing.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index b4792f8ef9f1..070092879e4d 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -38,13 +38,11 @@ been reported, please go ahead and report it and link to issues you think might In general, ICEs on the same line but with different *query stacks* are usually distinct bugs. For example, [#109020][#109020] and [#109129][#109129] had similar error messages: -``` -error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead -``` -``` -error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead -``` -but different query stacks: +> error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead + +> error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead + +However, they have different query stacks: ``` query stack during panic: #0 [fn_abi_of_instance] computing call ABI of `<[closure@src/main.rs:36:25: 36:28] as core::ops::function::FnOnce<(Emplacable<()>,)>>::call_once - shim(vtable)` From 6f5454a580913795e58ad480f8e3c243139026f2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:47:48 +0200 Subject: [PATCH 0735/3801] guidance is clear enough --- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 070092879e4d..dc601e8b0092 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -62,7 +62,7 @@ end of query stack When building a corpus, be sure to avoid collecting tests that are already known to crash rustc. A fuzzer that is seeded with such tests is more likely to -generate bugs with the same root cause, wasting everyone's time. +generate bugs with the same root cause. The simplest way to avoid this is to loop over each file in the corpus, see if it causes an ICE, and remove it if so. From d8d8dbd9732c264090c7dcc97a5ff992352a980a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:02:02 +0200 Subject: [PATCH 0736/3801] feels appropriate --- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index dc601e8b0092..6cbe3cdb4359 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -78,7 +78,7 @@ To build a corpus, you may want to use: ## Extra credit -Here are a few things you can do to help the Rust project after filing an ICE. +Here are a few things you can do to help the Rust project after filing an ICE: - [Bisect][bisect] the bug to figure out when it was introduced. If you find the regressing PR / commit, you can mark the issue with the label `S-has-bisection`. From cc28befef11c3142e6e0f82a1a9d3c3dc57a07d2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:14:14 +0200 Subject: [PATCH 0737/3801] fluff --- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 6cbe3cdb4359..9f5360e1ecf3 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -133,7 +133,7 @@ Of course, it's best to try multiple build configurations and see what actually results in superior throughput. You may want to build rustc from source with debug assertions to find -additional bugs, though this is a trade-off: it can slow down fuzzing by +additional bugs, though this can slow down fuzzing by requiring extra work for every execution. To enable debug assertions, add this to `bootstrap.toml` when compiling rustc: From 86f18b3f8487d13fff27d70da46376f3fb98cbf8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:15:07 +0200 Subject: [PATCH 0738/3801] use compact format, as this is what is in bootstrap.example.toml --- src/doc/rustc-dev-guide/src/fuzzing.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 9f5360e1ecf3..648fa351c8f5 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -138,8 +138,7 @@ requiring extra work for every execution. To enable debug assertions, add this to `bootstrap.toml` when compiling rustc: ```toml -[rust] -debug-assertions = true +rust.debug-assertions = true ``` ICEs that require debug assertions to reproduce should be tagged From da01b354cfa14ef69c43dd449341a3bcc8aa6521 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:18:39 +0200 Subject: [PATCH 0739/3801] redundant --- src/doc/rustc-dev-guide/src/fuzzing.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 648fa351c8f5..6ef8c3179639 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -36,7 +36,7 @@ project, please read this guide before reporting fuzzer-generated bugs! If you're not sure whether or not an ICE is a duplicate of one that's already been reported, please go ahead and report it and link to issues you think might be related. In general, ICEs on the same line but with different *query stacks* are usually distinct bugs. -For example, [#109020][#109020] and [#109129][#109129] had similar error messages: +For example, [#109020] and [#109129] had similar error messages: > error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead @@ -71,7 +71,7 @@ To build a corpus, you may want to use: - The rustc/rust-analyzer/clippy test suites (or even source code) --- though avoid tests that are already known to cause failures, which often begin with comments like `//@ failure-status: 101` or `//@ known-bug: #NNN`. -- The already-fixed ICEs in the archived [Glacier][glacier] repository --- though +- The already-fixed ICEs in the archived [Glacier] repository --- though avoid the unfixed ones in `ices/`! [glacier]: https://github.com/rust-lang/glacier @@ -142,9 +142,9 @@ rust.debug-assertions = true ``` ICEs that require debug assertions to reproduce should be tagged -[`requires-debug-assertions`][requires-debug-assertions]. +[`requires-debug-assertions`]. -[requires-debug-assertions]: https://github.com/rust-lang/rust/labels/requires-debug-assertions +[`requires-debug-assertions`]: https://github.com/rust-lang/rust/labels/requires-debug-assertions ## Existing projects From cc8cfcc187ef8a3e4bd26566b873c8866574085a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:26:45 +0200 Subject: [PATCH 0740/3801] fails link checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit error: Potential incomplete link ┌─ fuzzing.md:41:122 │ 41 │ > error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Did you forget to define a URL for `closure@src/main.rs:36:25: 36:28`? --- src/doc/rustc-dev-guide/src/fuzzing.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 6ef8c3179639..635c01d21aee 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -38,9 +38,13 @@ been reported, please go ahead and report it and link to issues you think might In general, ICEs on the same line but with different *query stacks* are usually distinct bugs. For example, [#109020] and [#109129] had similar error messages: -> error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead +``` +error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead +``` -> error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead +``` +error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead +``` However, they have different query stacks: ``` From d484f9361eef9078b729990fd1ba8a40af8bdb6f Mon Sep 17 00:00:00 2001 From: Eli Ozcan <62805599+elijah629@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:12:28 +0000 Subject: [PATCH 0741/3801] Fix typo in armv7a-vex-v5 documentation --- src/doc/rustc/src/platform-support/armv7a-vex-v5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md index 3677f8931dd6..68fbec2ff4b4 100644 --- a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md +++ b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md @@ -21,7 +21,7 @@ This target is cross-compiled. Dynamic linking is unsupported. `#![no_std]` crates can be built using `build-std` to build `core` and `panic_abort` and optionally `alloc`. Unwinding panics are not yet supported on this target. -`std` has only partial support due platform limitations. Notably: +`std` has only partial support due to platform limitations. Notably: - `std::process` and `std::net` are unimplemented. `std::thread` only supports sleeping and yielding, as this is a single-threaded environment. - `std::time` has full support for `Instant`, but no support for `SystemTime`. - `std::io` has full support for `stdin`/`stdout`/`stderr`. `stdout` and `stderr` both write to to USB channel 1 on this platform and are not differentiated. From aefb01b8521bd54128eec360ee78de83643b1d75 Mon Sep 17 00:00:00 2001 From: abd002 Date: Wed, 10 Dec 2025 19:14:47 +0200 Subject: [PATCH 0742/3801] Fix clippy::ref_as_ptr for non-temporary references in let/const --- clippy_lints/src/casts/ref_as_ptr.rs | 16 ++++++-- tests/ui/ref_as_ptr.fixed | 10 +++++ tests/ui/ref_as_ptr.rs | 10 +++++ tests/ui/ref_as_ptr.stderr | 60 ++++++++++++++++++---------- 4 files changed, 71 insertions(+), 25 deletions(-) diff --git a/clippy_lints/src/casts/ref_as_ptr.rs b/clippy_lints/src/casts/ref_as_ptr.rs index 592c820a25e1..b3805c678174 100644 --- a/clippy_lints/src/casts/ref_as_ptr.rs +++ b/clippy_lints/src/casts/ref_as_ptr.rs @@ -1,9 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; -use clippy_utils::{ExprUseNode, expr_use_ctxt, std_or_core}; +use clippy_utils::{ExprUseNode, expr_use_ctxt, is_expr_temporary_value, std_or_core}; use rustc_errors::Applicability; -use rustc_hir::{Expr, Mutability, Ty, TyKind}; +use rustc_hir::{Expr, ExprKind, Mutability, Ty, TyKind}; use rustc_lint::LateContext; use rustc_middle::ty; @@ -23,10 +23,18 @@ pub(super) fn check<'tcx>( if matches!(cast_from.kind(), ty::Ref(..)) && let ty::RawPtr(_, to_mutbl) = cast_to.kind() && let use_cx = expr_use_ctxt(cx, expr) - // TODO: only block the lint if `cast_expr` is a temporary - && !matches!(use_cx.use_node(cx), ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_)) && let Some(std_or_core) = std_or_core(cx) { + if let ExprKind::AddrOf(_, _, addr_inner) = cast_expr.kind + && is_expr_temporary_value(cx, addr_inner) + && matches!( + use_cx.use_node(cx), + ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_) + ) + { + return; + } + let fn_name = match to_mutbl { Mutability::Not => "from_ref", Mutability::Mut => "from_mut", diff --git a/tests/ui/ref_as_ptr.fixed b/tests/ui/ref_as_ptr.fixed index ce144508581e..eadbb7c36415 100644 --- a/tests/ui/ref_as_ptr.fixed +++ b/tests/ui/ref_as_ptr.fixed @@ -86,6 +86,16 @@ fn main() { f(std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i))); //~^ ref_as_ptr + let x = (10, 20); + let _ = std::ptr::from_ref(&x); + //~^ ref_as_ptr + let _ = std::ptr::from_ref(&x.0); + //~^ ref_as_ptr + + let x = Box::new(10); + let _ = std::ptr::from_ref(&*x); + //~^ ref_as_ptr + let _ = &String::new() as *const _; let _ = &mut String::new() as *mut _; const FOO: *const String = &String::new() as *const _; diff --git a/tests/ui/ref_as_ptr.rs b/tests/ui/ref_as_ptr.rs index acdff2c2ba29..ef96a3ff5693 100644 --- a/tests/ui/ref_as_ptr.rs +++ b/tests/ui/ref_as_ptr.rs @@ -86,6 +86,16 @@ fn main() { f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]); //~^ ref_as_ptr + let x = (10, 20); + let _ = &x as *const _; + //~^ ref_as_ptr + let _ = &x.0 as *const _; + //~^ ref_as_ptr + + let x = Box::new(10); + let _ = &*x as *const _; + //~^ ref_as_ptr + let _ = &String::new() as *const _; let _ = &mut String::new() as *mut _; const FOO: *const String = &String::new() as *const _; diff --git a/tests/ui/ref_as_ptr.stderr b/tests/ui/ref_as_ptr.stderr index 79db29e596bd..587e4fb809cd 100644 --- a/tests/ui/ref_as_ptr.stderr +++ b/tests/ui/ref_as_ptr.stderr @@ -200,61 +200,67 @@ LL | f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i))` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:109:7 + --> tests/ui/ref_as_ptr.rs:90:13 + | +LL | let _ = &x as *const _; + | ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&x)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:92:13 + | +LL | let _ = &x.0 as *const _; + | ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&x.0)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:96:13 + | +LL | let _ = &*x as *const _; + | ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&*x)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:119:7 | LL | f(val as *const i32); | ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:111:7 + --> tests/ui/ref_as_ptr.rs:121:7 | LL | f(mut_val as *mut i32); | ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(mut_val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:116:7 + --> tests/ui/ref_as_ptr.rs:126:7 | LL | f(val as *const _); | ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:118:7 + --> tests/ui/ref_as_ptr.rs:128:7 | LL | f(val as *const [u8]); | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[u8]>(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:123:7 + --> tests/ui/ref_as_ptr.rs:133:7 | LL | f(val as *mut _); | ^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:125:7 + --> tests/ui/ref_as_ptr.rs:135:7 | LL | f(val as *mut str); | ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::(val)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:133:9 + --> tests/ui/ref_as_ptr.rs:143:9 | LL | self.0 as *const _ as *const _ | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:138:9 - | -LL | self.0 as *const _ as *const _ - | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` - -error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:147:9 - | -LL | self.0 as *const _ as *const _ - | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` - -error: reference as raw pointer - --> tests/ui/ref_as_ptr.rs:152:9 + --> tests/ui/ref_as_ptr.rs:148:9 | LL | self.0 as *const _ as *const _ | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` @@ -262,8 +268,20 @@ LL | self.0 as *const _ as *const _ error: reference as raw pointer --> tests/ui/ref_as_ptr.rs:157:9 | +LL | self.0 as *const _ as *const _ + | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:162:9 + | +LL | self.0 as *const _ as *const _ + | ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)` + +error: reference as raw pointer + --> tests/ui/ref_as_ptr.rs:167:9 + | LL | self.0 as *mut _ as *mut _ | ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(self.0)` -error: aborting due to 44 previous errors +error: aborting due to 47 previous errors From 48b0f834ea3cbf04be98f6329f231bd8eaf4488f Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 12 Dec 2025 17:51:30 -0500 Subject: [PATCH 0743/3801] Update cargo submodule --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 2c283a9a5c59..e91b2baa632c 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 2c283a9a5c5968eeb9a8f12313f04feb1ff8dfac +Subproject commit e91b2baa632c0c7e84216c91ecfe107c37d887c1 From 67c0f741ef1176c60340d3cd1736b170264edcc7 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sat, 13 Dec 2025 20:12:08 +0200 Subject: [PATCH 0744/3801] Use a generated name in old format_args lowering, instead of `args` To prevent it from clashing with other names. --- .../hir-def/src/expr_store/lower/format_args.rs | 4 ++-- .../crates/hir-def/src/expr_store/tests/body.rs | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs index 7efc9a956c1c..4bbfc5b144f1 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/format_args.rs @@ -655,7 +655,7 @@ impl<'db> ExprCollector<'db> { .collect(); let args = self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: args })); - let args_name = Name::new_symbol_root(sym::args); + let args_name = self.generate_new_name(); let args_binding = self.alloc_binding( args_name.clone(), BindingAnnotation::Unannotated, @@ -674,7 +674,7 @@ impl<'db> ExprCollector<'db> { } else { // Generate: // super let args = (&arg0, &arg1, &...); - let args_name = Name::new_symbol_root(sym::args); + let args_name = self.generate_new_name(); let args_binding = self.alloc_binding( args_name.clone(), BindingAnnotation::Unannotated, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs index 7e48ca8f4558..504c310684d6 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body.rs @@ -278,16 +278,16 @@ fn main() { let are = "are"; let count = 10; { - let args = (&"fancy", &(), &"!", &count, &are, ); - let args = [ + let 0 = (&"fancy", &(), &"!", &count, &are, ); + let 0 = [ builtin#lang(Argument::new_display)( - args.3, + 0.3, ), builtin#lang(Argument::new_display)( - args.0, + 0.0, ), builtin#lang(Argument::new_debug)( - args.4, + 0.4, ), builtin#lang(Argument::new_display)( - args.2, + 0.2, ), ]; unsafe { @@ -295,7 +295,7 @@ fn main() { &[ "\u{1b}hello ", " ", " friends, we ", " ", "", ], - &args, + &0, &[ builtin#lang(Placeholder::new)( 0usize, From ddcd55fa66354b7a3a7b524ba773a06bcbe4ae27 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 9 Nov 2025 17:54:22 +0100 Subject: [PATCH 0745/3801] Don't allow codegen attributes on trait methods Signed-off-by: Jonathan Brouwer --- compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs | 1 - compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs | 3 +-- compiler/rustc_attr_parsing/src/attributes/link_attrs.rs | 3 +-- compiler/rustc_attr_parsing/src/attributes/repr.rs | 2 +- tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs | 4 ++++ 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index 79f7171cc0c8..7323db06a8f1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -61,7 +61,6 @@ impl CombineAttributeParser for AllowConstFnUnstableParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), - Allow(Target::Method(MethodKind::Trait { body: false })), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), ]); diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 7d3a7418f06c..477b8adc6729 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -57,7 +57,6 @@ impl NoArgsAttributeParser for ColdParser { Allow(Target::Fn), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), - Allow(Target::Method(MethodKind::Trait { body: false })), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::ForeignFn), Allow(Target::Closure), @@ -343,7 +342,7 @@ impl NoArgsAttributeParser for TrackCallerParser { Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), - Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: false })), // `#[track_caller]` is inherited from trait methods Allow(Target::ForeignFn), Allow(Target::Closure), Warn(Target::MacroDef), diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index fe8f3578fe14..79143823bc68 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -469,7 +469,6 @@ impl SingleAttributeParser for LinkSectionParser { Allow(Target::Static), Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), - Allow(Target::Method(MethodKind::Trait { body: false })), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), ]); @@ -587,12 +586,12 @@ impl SingleAttributeParser for LinkageParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), - Allow(Target::Method(MethodKind::Trait { body: false })), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), Allow(Target::Static), Allow(Target::ForeignStatic), Allow(Target::ForeignFn), + Warn(Target::Method(MethodKind::Trait { body: false })), // Not inherited ]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: [ diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 4520e4f5dbac..8df2f1d2c468 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -315,7 +315,7 @@ impl AttributeParser for AlignParser { Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), - Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: false })), // `#[align]` is inherited from trait methods Allow(Target::ForeignFn), ]); diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 4b5420a2ff8b..6716e78a7197 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -680,6 +680,10 @@ mod link_section { //~| HELP remove the attribute trait Tr { #[link_section = "1800"] + //~^ WARN attribute cannot be used on + //~| WARN previously accepted + //~| HELP can be applied to + //~| HELP remove the attribute fn inside_tr_no_default(&self); #[link_section = "1800"] From 8fa10c0ed768cc31bfc7a55cf02b9bae4f1fbc86 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 9 Nov 2025 18:34:24 +0100 Subject: [PATCH 0746/3801] Add regression test for codegen attributes on required trait methods Signed-off-by: Jonathan Brouwer --- .../codegen_attr_on_required_trait_method.rs | 24 +++ ...degen_attr_on_required_trait_method.stderr | 34 ++++ ...issue-43106-gating-of-builtin-attrs.stderr | 169 +++++++++--------- 3 files changed, 147 insertions(+), 80 deletions(-) create mode 100644 tests/ui/attributes/codegen_attr_on_required_trait_method.rs create mode 100644 tests/ui/attributes/codegen_attr_on_required_trait_method.stderr diff --git a/tests/ui/attributes/codegen_attr_on_required_trait_method.rs b/tests/ui/attributes/codegen_attr_on_required_trait_method.rs new file mode 100644 index 000000000000..6301a5a8ebf7 --- /dev/null +++ b/tests/ui/attributes/codegen_attr_on_required_trait_method.rs @@ -0,0 +1,24 @@ +#![deny(unused_attributes)] +#![feature(linkage)] +#![feature(fn_align)] + +trait Test { + #[cold] + //~^ ERROR cannot be used on required trait methods [unused_attributes] + //~| WARN previously accepted + fn method1(&self); + #[link_section = ".text"] + //~^ ERROR cannot be used on required trait methods [unused_attributes] + //~| WARN previously accepted + fn method2(&self); + #[linkage = "common"] + //~^ ERROR cannot be used on required trait methods [unused_attributes] + //~| WARN previously accepted + fn method3(&self); + #[track_caller] + fn method4(&self); + #[rustc_align(1)] + fn method5(&self); +} + +fn main() {} diff --git a/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr b/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr new file mode 100644 index 000000000000..0770ccae4146 --- /dev/null +++ b/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr @@ -0,0 +1,34 @@ +error: `#[cold]` attribute cannot be used on required trait methods + --> $DIR/codegen_attr_on_required_trait_method.rs:6:5 + | +LL | #[cold] + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[cold]` can be applied to closures, foreign functions, functions, inherent methods, provided trait methods, and trait methods in impl blocks +note: the lint level is defined here + --> $DIR/codegen_attr_on_required_trait_method.rs:1:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: `#[link_section]` attribute cannot be used on required trait methods + --> $DIR/codegen_attr_on_required_trait_method.rs:10:5 + | +LL | #[link_section = ".text"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks + +error: `#[linkage]` attribute cannot be used on required trait methods + --> $DIR/codegen_attr_on_required_trait_method.rs:14:5 + | +LL | #[linkage = "common"] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[linkage]` can be applied to foreign functions, foreign statics, functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks + +error: aborting due to 3 previous errors + diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 676372ad85e0..8ed39a0079ba 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -203,7 +203,7 @@ LL | #![reexport_test_harness_main = "2900"] | + warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:1 | LL | #[link(name = "x")] | ^^^^^^^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:832:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:836:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -230,7 +230,7 @@ LL | #![crate_type = "0800"] | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:856:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:860:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ @@ -241,7 +241,7 @@ LL | #![feature(x0600)] | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:881:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:1 | LL | #[no_main] | ^^^^^^^^^^ @@ -252,7 +252,7 @@ LL | #![no_main] | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:905:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:909:1 | LL | #[no_builtins] | ^^^^^^^^^^^^^^ @@ -329,7 +329,7 @@ LL | #![reexport_test_harness_main = "2900"] impl S { } | + warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:17 | LL | mod inner { #![link(name = "x")] } | ------------^^^^^^^^^^^^^^^^^^^^-- not an `extern` block @@ -337,7 +337,7 @@ LL | mod inner { #![link(name = "x")] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5 | LL | #[link(name = "x")] fn f() { } | ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block @@ -345,7 +345,7 @@ LL | #[link(name = "x")] fn f() { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:722:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:5 | LL | #[link(name = "x")] struct S; | ^^^^^^^^^^^^^^^^^^^ --------- not an `extern` block @@ -353,7 +353,7 @@ LL | #[link(name = "x")] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:5 | LL | #[link(name = "x")] type T = S; | ^^^^^^^^^^^^^^^^^^^ ----------- not an `extern` block @@ -361,7 +361,7 @@ LL | #[link(name = "x")] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5 | LL | #[link(name = "x")] impl S { } | ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block @@ -369,7 +369,7 @@ LL | #[link(name = "x")] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:741:5 | LL | #[link(name = "x")] extern "Rust" {} | ^^^^^^^^^^^^^^^^^^^ @@ -377,13 +377,13 @@ LL | #[link(name = "x")] extern "Rust" {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:836:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:840:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -394,7 +394,7 @@ LL | #![crate_type = "0800"] fn f() { } | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -405,7 +405,7 @@ LL | #![crate_type = "0800"] struct S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -416,7 +416,7 @@ LL | #![crate_type = "0800"] type T = S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:855:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -427,13 +427,13 @@ LL | #![crate_type = "0800"] impl S { } | + warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:860:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:864:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:863:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:867:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ @@ -444,7 +444,7 @@ LL | #![feature(x0600)] fn f() { } | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:867:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:871:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ @@ -455,7 +455,7 @@ LL | #![feature(x0600)] struct S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:871:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:875:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ @@ -466,7 +466,7 @@ LL | #![feature(x0600)] type T = S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:875:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:879:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ @@ -477,13 +477,13 @@ LL | #![feature(x0600)] impl S { } | + warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:889:17 | LL | mod inner { #![no_main] } | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:888:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5 | LL | #[no_main] fn f() { } | ^^^^^^^^^^ @@ -494,7 +494,7 @@ LL | #![no_main] fn f() { } | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5 | LL | #[no_main] struct S; | ^^^^^^^^^^ @@ -505,7 +505,7 @@ LL | #![no_main] struct S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5 | LL | #[no_main] type T = S; | ^^^^^^^^^^ @@ -516,7 +516,7 @@ LL | #![no_main] type T = S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:5 | LL | #[no_main] impl S { } | ^^^^^^^^^^ @@ -527,13 +527,13 @@ LL | #![no_main] impl S { } | + warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:909:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:913:17 | LL | mod inner { #![no_builtins] } | ^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:912:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:916:5 | LL | #[no_builtins] fn f() { } | ^^^^^^^^^^^^^^ @@ -544,7 +544,7 @@ LL | #![no_builtins] fn f() { } | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:916:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:920:5 | LL | #[no_builtins] struct S; | ^^^^^^^^^^^^^^ @@ -555,7 +555,7 @@ LL | #![no_builtins] struct S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:920:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:924:5 | LL | #[no_builtins] type T = S; | ^^^^^^^^^^^^^^ @@ -566,7 +566,7 @@ LL | #![no_builtins] type T = S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:924:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:928:5 | LL | #[no_builtins] impl S { } | ^^^^^^^^^^^^^^ @@ -1222,8 +1222,17 @@ LL | #[link_section = "1800"] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[link_section]` can be applied to functions and statics +warning: `#[link_section]` attribute cannot be used on required trait methods + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:9 + | +LL | #[link_section = "1800"] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks + warning: `#[must_use]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:1 | LL | #[must_use] | ^^^^^^^^^^^ @@ -1232,7 +1241,7 @@ LL | #[must_use] = help: `#[must_use]` can be applied to data types, functions, traits, and unions warning: `#[must_use]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:17 | LL | mod inner { #![must_use] } | ^^^^^^^^^^^^ @@ -1241,7 +1250,7 @@ LL | mod inner { #![must_use] } = help: `#[must_use]` can be applied to data types, functions, traits, and unions warning: `#[must_use]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:771:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:775:5 | LL | #[must_use] type T = S; | ^^^^^^^^^^^ @@ -1250,7 +1259,7 @@ LL | #[must_use] type T = S; = help: `#[must_use]` can be applied to data types, functions, traits, and unions warning: `#[must_use]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5 | LL | #[must_use] impl S { } | ^^^^^^^^^^^ @@ -1259,13 +1268,13 @@ LL | #[must_use] impl S { } = help: `#[must_use]` can be applied to data types, functions, traits, and unions warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:782:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:1 | LL | #[windows_subsystem = "windows"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:1 | LL | / mod windows_subsystem { LL | | @@ -1275,67 +1284,67 @@ LL | | } | |_^ warning: the `#![windows_subsystem]` attribute can only be used at the crate root - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:17 | LL | mod inner { #![windows_subsystem="windows"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5 | LL | #[windows_subsystem = "windows"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:38 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:38 | LL | #[windows_subsystem = "windows"] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5 | LL | #[windows_subsystem = "windows"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this struct - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:38 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:38 | LL | #[windows_subsystem = "windows"] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5 | LL | #[windows_subsystem = "windows"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this type alias - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:38 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:38 | LL | #[windows_subsystem = "windows"] type T = S; | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:5 | LL | #[windows_subsystem = "windows"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this implementation block - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:38 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:38 | LL | #[windows_subsystem = "windows"] impl S { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:808:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:812:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:1 | LL | / mod crate_name { LL | | @@ -1345,67 +1354,67 @@ LL | | } | |_^ warning: the `#![crate_name]` attribute can only be used at the crate root - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:812:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:816:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:28 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:28 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this struct - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:28 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:28 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this type alias - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:28 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:28 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this implementation block - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:28 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:28 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:929:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:931:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:935:1 | LL | / mod recursion_limit { LL | | @@ -1415,67 +1424,67 @@ LL | | } | |_^ warning: the `#![recursion_limit]` attribute can only be used at the crate root - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:937:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:936:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:936:31 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:31 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this struct - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:31 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:31 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this type alias - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:31 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:31 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:952:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this implementation block - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:31 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:952:31 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:953:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:957:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:955:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:959:1 | LL | / mod type_length_limit { LL | | @@ -1485,55 +1494,55 @@ LL | | } | |_^ warning: the `#![type_length_limit]` attribute can only be used at the crate root - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:957:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:961:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:960:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:960:33 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:33 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this struct - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:33 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:33 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this type alias - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:33 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:33 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:976:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this implementation block - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:33 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:976:33 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^ @@ -1601,5 +1610,5 @@ LL | #![must_use] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[must_use]` can be applied to data types, functions, traits, and unions -warning: 174 warnings emitted +warning: 175 warnings emitted From d0d8258886dfb8c09d337b094ca1e6f26f85cd8b Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 12 Oct 2025 17:19:17 +0200 Subject: [PATCH 0747/3801] Stabilize `-Zremap-path-scope` as `--remap-path-scope` In the process also document that new `--remap-path-scope` scopes may be added in the future, and that the `all` scope always represent all the scopes. Co-authored-by: David Wood --- compiler/rustc_session/src/config.rs | 48 ++++++++++++++++--- compiler/rustc_session/src/options.rs | 28 +---------- src/doc/rustc/src/command-line-arguments.md | 8 ++++ src/doc/rustc/src/remap-source-paths.md | 27 ++++++++++- .../src/compiler-flags/remap-path-scope.md | 23 --------- tests/coverage/remap-path-prefix.rs | 6 +-- ...emap-path-prefix.with_macro_scope.coverage | 6 +-- .../remap-path-prefix-consts/rmake.rs | 4 +- .../run-make/remap-path-prefix-dwarf/rmake.rs | 8 ++-- tests/run-make/remap-path-prefix/rmake.rs | 6 +-- tests/run-make/rustc-help/help-v.diff | 5 +- tests/run-make/rustc-help/help-v.stdout | 3 ++ tests/run-make/split-debuginfo/rmake.rs | 13 +++-- tests/ui/errors/auxiliary/file-debuginfo.rs | 2 +- tests/ui/errors/auxiliary/file-diag.rs | 2 +- tests/ui/errors/auxiliary/file-macro.rs | 2 +- tests/ui/errors/auxiliary/trait-debuginfo.rs | 2 +- tests/ui/errors/auxiliary/trait-diag.rs | 2 +- tests/ui/errors/auxiliary/trait-macro.rs | 2 +- .../errors/remap-path-prefix-diagnostics.rs | 10 ++-- tests/ui/errors/remap-path-prefix-macro.rs | 10 ++-- tests/ui/errors/remap-path-prefix.rs | 4 +- 22 files changed, 124 insertions(+), 97 deletions(-) delete mode 100644 src/doc/unstable-book/src/compiler-flags/remap-path-scope.md diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index be4b36e3b926..4d2ca8987df4 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -24,7 +24,9 @@ use rustc_hashes::Hash64; use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; -use rustc_span::{FileName, RealFileName, SourceFileHashAlgorithm, Symbol, sym}; +use rustc_span::{ + FileName, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm, Symbol, sym, +}; use rustc_target::spec::{ FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo, Target, TargetTuple, @@ -1315,6 +1317,29 @@ impl OutputFilenames { } } +pub(crate) fn parse_remap_path_scope( + early_dcx: &EarlyDiagCtxt, + matches: &getopts::Matches, +) -> RemapPathScopeComponents { + if let Some(v) = matches.opt_str("remap-path-scope") { + let mut slot = RemapPathScopeComponents::empty(); + for s in v.split(',') { + slot |= match s { + "macro" => RemapPathScopeComponents::MACRO, + "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS, + "debuginfo" => RemapPathScopeComponents::DEBUGINFO, + "coverage" => RemapPathScopeComponents::COVERAGE, + "object" => RemapPathScopeComponents::OBJECT, + "all" => RemapPathScopeComponents::all(), + _ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `coverage`, `object`, `all`"), + } + } + slot + } else { + RemapPathScopeComponents::all() + } +} + #[derive(Clone, Debug)] pub struct Sysroot { pub explicit: Option, @@ -1351,9 +1376,9 @@ pub fn host_tuple() -> &'static str { fn file_path_mapping( remap_path_prefix: Vec<(PathBuf, PathBuf)>, - unstable_opts: &UnstableOptions, + remap_path_scope: RemapPathScopeComponents, ) -> FilePathMapping { - FilePathMapping::new(remap_path_prefix.clone(), unstable_opts.remap_path_scope) + FilePathMapping::new(remap_path_prefix.clone(), remap_path_scope) } impl Default for Options { @@ -1365,7 +1390,7 @@ impl Default for Options { // to create a default working directory. let working_dir = { let working_dir = std::env::current_dir().unwrap(); - let file_mapping = file_path_mapping(Vec::new(), &unstable_opts); + let file_mapping = file_path_mapping(Vec::new(), RemapPathScopeComponents::empty()); file_mapping.to_real_filename(&RealFileName::empty(), &working_dir) }; @@ -1401,6 +1426,7 @@ impl Default for Options { cli_forced_codegen_units: None, cli_forced_local_thinlto_off: false, remap_path_prefix: Vec::new(), + remap_path_scope: RemapPathScopeComponents::all(), real_rust_source_base_dir: None, real_rustc_dev_source_base_dir: None, edition: DEFAULT_EDITION, @@ -1427,7 +1453,7 @@ impl Options { } pub fn file_path_mapping(&self) -> FilePathMapping { - file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts) + file_path_mapping(self.remap_path_prefix.clone(), self.remap_path_scope) } /// Returns `true` if there will be an output file generated. @@ -1864,6 +1890,14 @@ pub fn rustc_optgroups() -> Vec { "Remap source names in all output (compiler messages and output files)", "=", ), + opt( + Stable, + Opt, + "", + "remap-path-scope", + "Defines which scopes of paths should be remapped by `--remap-path-prefix`", + "", + ), opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "="), ]; options.extend(verbose_only.into_iter().map(|mut opt| { @@ -2704,6 +2738,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let externs = parse_externs(early_dcx, matches, &unstable_opts); let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches, &unstable_opts); + let remap_path_scope = parse_remap_path_scope(early_dcx, matches); let pretty = parse_pretty(early_dcx, &unstable_opts); @@ -2770,7 +2805,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M early_dcx.early_fatal(format!("Current directory is invalid: {e}")); }); - let file_mapping = file_path_mapping(remap_path_prefix.clone(), &unstable_opts); + let file_mapping = file_path_mapping(remap_path_prefix.clone(), remap_path_scope); file_mapping.to_real_filename(&RealFileName::empty(), &working_dir) }; @@ -2808,6 +2843,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M cli_forced_codegen_units: codegen_units, cli_forced_local_thinlto_off: disable_local_thinlto, remap_path_prefix, + remap_path_scope, real_rust_source_base_dir, real_rustc_dev_source_base_dir, edition, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index aea0b73ee927..42d62a7f8437 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -454,6 +454,8 @@ top_level_options!( /// Remap source path prefixes in all output (messages, object files, debug, etc.). remap_path_prefix: Vec<(PathBuf, PathBuf)> [TRACKED_NO_CRATE_HASH], + /// Defines which scopes of paths should be remapped by `--remap-path-prefix`. + remap_path_scope: RemapPathScopeComponents [TRACKED_NO_CRATE_HASH], /// Base directory containing the `library/` directory for the Rust standard library. /// Right now it's always `$sysroot/lib/rustlib/src/rust` @@ -872,7 +874,6 @@ mod desc { pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)"; pub(crate) const parse_proc_macro_execution_strategy: &str = "one of supported execution strategies (`same-thread`, or `cross-thread`)"; - pub(crate) const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `debuginfo`, `coverage`, `object`, `all`"; pub(crate) const parse_inlining_threshold: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number"; pub(crate) const parse_llvm_module_flag: &str = ":::. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)"; @@ -1711,29 +1712,6 @@ pub mod parse { true } - pub(crate) fn parse_remap_path_scope( - slot: &mut RemapPathScopeComponents, - v: Option<&str>, - ) -> bool { - if let Some(v) = v { - *slot = RemapPathScopeComponents::empty(); - for s in v.split(',') { - *slot |= match s { - "macro" => RemapPathScopeComponents::MACRO, - "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS, - "debuginfo" => RemapPathScopeComponents::DEBUGINFO, - "coverage" => RemapPathScopeComponents::COVERAGE, - "object" => RemapPathScopeComponents::OBJECT, - "all" => RemapPathScopeComponents::all(), - _ => return false, - } - } - true - } else { - false - } - } - pub(crate) fn parse_relocation_model(slot: &mut Option, v: Option<&str>) -> bool { match v.and_then(|s| RelocModel::from_str(s).ok()) { Some(relocation_model) => *slot = Some(relocation_model), @@ -2584,8 +2562,6 @@ options! { "whether ELF relocations can be relaxed"), remap_cwd_prefix: Option = (None, parse_opt_pathbuf, [TRACKED], "remap paths under the current working directory to this path prefix"), - remap_path_scope: RemapPathScopeComponents = (RemapPathScopeComponents::all(), parse_remap_path_scope, [TRACKED], - "remap path scope (default: all)"), remark_dir: Option = (None, parse_opt_pathbuf, [UNTRACKED], "directory into which to write optimization remarks (if not specified, they will be \ written to standard error output)"), diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 0b15fbc24dfc..1309ecd73679 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -428,6 +428,14 @@ specified multiple times. Refer to the [Remap source paths](remap-source-paths.md) section of this book for further details and explanation. + +## `--remap-path-scope`: remap source paths in output + +Defines which scopes of paths should be remapped by `--remap-path-prefix`. + +Refer to the [Remap source paths](remap-source-paths.md) section of this book for +further details and explanation. + ## `--json`: configure json messages printed by the compiler diff --git a/src/doc/rustc/src/remap-source-paths.md b/src/doc/rustc/src/remap-source-paths.md index 03f5d98091cc..d27359fb550f 100644 --- a/src/doc/rustc/src/remap-source-paths.md +++ b/src/doc/rustc/src/remap-source-paths.md @@ -6,7 +6,7 @@ output, including compiler diagnostics, debugging information, macro expansions, This is useful for normalizing build products, for example by removing the current directory out of the paths emitted into object files. -The remapping is done via the `--remap-path-prefix` option. +The remapping is done via the `--remap-path-prefix` flag and can be customized via the `--remap-path-scope` flag. ## `--remap-path-prefix` @@ -25,6 +25,31 @@ rustc --remap-path-prefix "/home/user/project=/redacted" This example replaces all occurrences of `/home/user/project` in emitted paths with `/redacted`. +## `--remap-path-scope` + +Defines which scopes of paths should be remapped by `--remap-path-prefix`. + +This flag accepts a comma-separated list of values and may be specified multiple times, in which case the scopes are aggregated together. + +The valid scopes are: + +- `macro` - apply remappings to the expansion of `std::file!()` macro. This is where paths in embedded panic messages come from +- `diagnostics` - apply remappings to printed compiler diagnostics +- `debuginfo` - apply remappings to debug information +- `coverage` - apply remappings to coverage information +- `object` - apply remappings to all paths in compiled executables or libraries, but not elsewhere. Currently an alias for `macro,coverage,debuginfo`. +- `all` (default) - an alias for all of the above, also equivalent to supplying only `--remap-path-prefix` without `--remap-path-scope`. + +The scopes accepted by `--remap-path-scope` are not exhaustive - new scopes may be added in future releases for eventual stabilisation. +This implies that the `all` scope can correspond to different scopes between releases. + +### Example + +```sh +# With `object` scope only the build outputs will be remapped, the diagnostics won't be remapped. +rustc --remap-path-prefix=$(PWD)=/remapped --remap-path-scope=object main.rs +``` + ## Caveats and Limitations ### Linkers generated paths diff --git a/src/doc/unstable-book/src/compiler-flags/remap-path-scope.md b/src/doc/unstable-book/src/compiler-flags/remap-path-scope.md deleted file mode 100644 index fb1c7d7a6878..000000000000 --- a/src/doc/unstable-book/src/compiler-flags/remap-path-scope.md +++ /dev/null @@ -1,23 +0,0 @@ -# `remap-path-scope` - -The tracking issue for this feature is: [#111540](https://github.com/rust-lang/rust/issues/111540). - ------------------------- - -When the `--remap-path-prefix` option is passed to rustc, source path prefixes in all output will be affected by default. -The `--remap-path-scope` argument can be used in conjunction with `--remap-path-prefix` to determine paths in which output context should be affected. -This flag accepts a comma-separated list of values and may be specified multiple times, in which case the scopes are aggregated together. The valid scopes are: - -- `macro` - apply remappings to the expansion of `std::file!()` macro. This is where paths in embedded panic messages come from -- `diagnostics` - apply remappings to printed compiler diagnostics -- `debuginfo` - apply remappings to debug information -- `coverage` - apply remappings to coverage information -- `object` - apply remappings to all paths in compiled executables or libraries, but not elsewhere. Currently an alias for `macro,debuginfo`. -- `all` - an alias for all of the above, also equivalent to supplying only `--remap-path-prefix` without `--remap-path-scope`. - -## Example -```sh -# This would produce an absolute path to main.rs in build outputs of -# "./main.rs". -rustc --remap-path-prefix=$(PWD)=/remapped -Zremap-path-scope=object main.rs -``` diff --git a/tests/coverage/remap-path-prefix.rs b/tests/coverage/remap-path-prefix.rs index 29c5826989c4..031b87b8f771 100644 --- a/tests/coverage/remap-path-prefix.rs +++ b/tests/coverage/remap-path-prefix.rs @@ -10,8 +10,8 @@ //@ revisions: with_remap with_coverage_scope with_object_scope with_macro_scope //@ compile-flags: --remap-path-prefix={{src-base}}=remapped // -//@[with_coverage_scope] compile-flags: -Zremap-path-scope=coverage -//@[with_object_scope] compile-flags: -Zremap-path-scope=object -//@[with_macro_scope] compile-flags: -Zremap-path-scope=macro +//@[with_coverage_scope] compile-flags: --remap-path-scope=coverage +//@[with_object_scope] compile-flags: --remap-path-scope=object +//@[with_macro_scope] compile-flags: --remap-path-scope=macro fn main() {} diff --git a/tests/coverage/remap-path-prefix.with_macro_scope.coverage b/tests/coverage/remap-path-prefix.with_macro_scope.coverage index 63979d8fe15a..9e8317672f90 100644 --- a/tests/coverage/remap-path-prefix.with_macro_scope.coverage +++ b/tests/coverage/remap-path-prefix.with_macro_scope.coverage @@ -10,9 +10,9 @@ LL| |//@ revisions: with_remap with_coverage_scope with_object_scope with_macro_scope LL| |//@ compile-flags: --remap-path-prefix={{src-base}}=remapped LL| |// - LL| |//@[with_coverage_scope] compile-flags: -Zremap-path-scope=coverage - LL| |//@[with_object_scope] compile-flags: -Zremap-path-scope=object - LL| |//@[with_macro_scope] compile-flags: -Zremap-path-scope=macro + LL| |//@[with_coverage_scope] compile-flags: --remap-path-scope=coverage + LL| |//@[with_object_scope] compile-flags: --remap-path-scope=object + LL| |//@[with_macro_scope] compile-flags: --remap-path-scope=macro LL| | LL| 1|fn main() {} diff --git a/tests/run-make/remap-path-prefix-consts/rmake.rs b/tests/run-make/remap-path-prefix-consts/rmake.rs index d07a5e00768a..07b5e2f97414 100644 --- a/tests/run-make/remap-path-prefix-consts/rmake.rs +++ b/tests/run-make/remap-path-prefix-consts/rmake.rs @@ -97,7 +97,7 @@ fn main() { location_caller .crate_type("lib") .remap_path_prefix(cwd(), "/remapped") - .arg("-Zremap-path-scope=object") + .arg("--remap-path-scope=object") .input(cwd().join("location-caller.rs")); location_caller.run(); @@ -105,7 +105,7 @@ fn main() { runner .crate_type("bin") .remap_path_prefix(cwd(), "/remapped") - .arg("-Zremap-path-scope=diagnostics") + .arg("--remap-path-scope=diagnostics") .input(cwd().join("runner.rs")) .output(&runner_bin); runner.run(); diff --git a/tests/run-make/remap-path-prefix-dwarf/rmake.rs b/tests/run-make/remap-path-prefix-dwarf/rmake.rs index 3b88fca0bb7f..ab6c1fb70d68 100644 --- a/tests/run-make/remap-path-prefix-dwarf/rmake.rs +++ b/tests/run-make/remap-path-prefix-dwarf/rmake.rs @@ -105,7 +105,7 @@ fn check_dwarf_deps(scope: &str, dwarf_test: DwarfDump) { let mut rustc_sm = rustc(); rustc_sm.input(cwd().join("src/some_value.rs")); rustc_sm.arg("-Cdebuginfo=2"); - rustc_sm.arg(format!("-Zremap-path-scope={}", scope)); + rustc_sm.arg(format!("--remap-path-scope={}", scope)); rustc_sm.arg("--remap-path-prefix"); rustc_sm.arg(format!("{}=/REMAPPED", cwd().display())); rustc_sm.arg("-Csplit-debuginfo=off"); @@ -117,7 +117,7 @@ fn check_dwarf_deps(scope: &str, dwarf_test: DwarfDump) { rustc_pv.input(cwd().join("src/print_value.rs")); rustc_pv.output(&print_value_rlib); rustc_pv.arg("-Cdebuginfo=2"); - rustc_pv.arg(format!("-Zremap-path-scope={}", scope)); + rustc_pv.arg(format!("--remap-path-scope={}", scope)); rustc_pv.arg("--remap-path-prefix"); rustc_pv.arg(format!("{}=/REMAPPED", cwd().display())); rustc_pv.arg("-Csplit-debuginfo=off"); @@ -158,8 +158,8 @@ fn check_dwarf(test: DwarfTest) { rustc.arg("-Cdebuginfo=2"); if let Some(scope) = test.scope { match scope { - ScopeType::Object => rustc.arg("-Zremap-path-scope=object"), - ScopeType::Diagnostics => rustc.arg("-Zremap-path-scope=diagnostics"), + ScopeType::Object => rustc.arg("--remap-path-scope=object"), + ScopeType::Diagnostics => rustc.arg("--remap-path-scope=diagnostics"), }; if is_darwin() { rustc.arg("-Csplit-debuginfo=off"); diff --git a/tests/run-make/remap-path-prefix/rmake.rs b/tests/run-make/remap-path-prefix/rmake.rs index b75ca9e796ac..22ffd4f1f0d1 100644 --- a/tests/run-make/remap-path-prefix/rmake.rs +++ b/tests/run-make/remap-path-prefix/rmake.rs @@ -38,9 +38,9 @@ fn main() { rmeta_contains("/the/aux/lib.rs"); rmeta_not_contains("auxiliary"); - out_object.arg("-Zremap-path-scope=object"); - out_macro.arg("-Zremap-path-scope=macro"); - out_diagobj.arg("-Zremap-path-scope=diagnostics,object"); + out_object.arg("--remap-path-scope=object"); + out_macro.arg("--remap-path-scope=macro"); + out_diagobj.arg("--remap-path-scope=diagnostics,object"); if is_darwin() { out_object.arg("-Csplit-debuginfo=off"); out_macro.arg("-Csplit-debuginfo=off"); diff --git a/tests/run-make/rustc-help/help-v.diff b/tests/run-make/rustc-help/help-v.diff index 60a9dfbe201d..94ed6a0ed027 100644 --- a/tests/run-make/rustc-help/help-v.diff +++ b/tests/run-make/rustc-help/help-v.diff @@ -1,4 +1,4 @@ -@@ -65,10 +65,28 @@ +@@ -65,10 +65,31 @@ Set a codegen option -V, --version Print version info and exit -v, --verbose Use verbose output @@ -20,6 +20,9 @@ + --remap-path-prefix = + Remap source names in all output (compiler messages + and output files) ++ --remap-path-scope ++ Defines which scopes of paths should be remapped by ++ `--remap-path-prefix` + @path Read newline separated options from `path` Additional help: diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout index c41cb5e3bde8..fb08d114ad1a 100644 --- a/tests/run-make/rustc-help/help-v.stdout +++ b/tests/run-make/rustc-help/help-v.stdout @@ -83,6 +83,9 @@ Options: --remap-path-prefix = Remap source names in all output (compiler messages and output files) + --remap-path-scope + Defines which scopes of paths should be remapped by + `--remap-path-prefix` @path Read newline separated options from `path` Additional help: diff --git a/tests/run-make/split-debuginfo/rmake.rs b/tests/run-make/split-debuginfo/rmake.rs index e53b71010781..0d311607a11a 100644 --- a/tests/run-make/split-debuginfo/rmake.rs +++ b/tests/run-make/split-debuginfo/rmake.rs @@ -171,8 +171,7 @@ enum RemapPathPrefix { Unspecified, } -/// `-Zremap-path-scope`. See -/// . +/// `--remap-path-scope` #[derive(Debug, Clone)] enum RemapPathScope { /// Comma-separated list of remap scopes: `macro`, `diagnostics`, `debuginfo`, `object`, `all`. @@ -921,7 +920,7 @@ mod shared_linux_other_tests { .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) - .arg(format!("-Zremap-path-scope={scope}")) + .arg(format!("--remap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } @@ -950,7 +949,7 @@ mod shared_linux_other_tests { .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) - .arg(format!("-Zremap-path-scope={scope}")) + .arg(format!("--remap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } @@ -1202,7 +1201,7 @@ mod shared_linux_other_tests { .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) - .arg(format!("-Zremap-path-scope={scope}")) + .arg(format!("--remap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); @@ -1242,7 +1241,7 @@ mod shared_linux_other_tests { .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) - .arg(format!("-Zremap-path-scope={scope}")) + .arg(format!("--remap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); @@ -1356,7 +1355,7 @@ fn main() { // NOTE: these combinations are not exhaustive, because while porting to rmake.rs initially I // tried to preserve the existing test behavior closely. Notably, no attempt was made to // exhaustively cover all cases in the 6-fold Cartesian product of `{,-Csplit=debuginfo=...}` x - // `{,-Cdebuginfo=...}` x `{,--remap-path-prefix}` x `{,-Zremap-path-scope=...}` x + // `{,-Cdebuginfo=...}` x `{,--remap-path-prefix}` x `{,--remap-path-scope=...}` x // `{,-Zsplit-dwarf-kind=...}` x `{,-Clinker-plugin-lto}`. If you really want to, you can // identify which combination isn't exercised with a 6-layers nested for loop iterating through // each of the cli flag enum variants. diff --git a/tests/ui/errors/auxiliary/file-debuginfo.rs b/tests/ui/errors/auxiliary/file-debuginfo.rs index 08113ec26bfd..3c95512d8cc2 100644 --- a/tests/ui/errors/auxiliary/file-debuginfo.rs +++ b/tests/ui/errors/auxiliary/file-debuginfo.rs @@ -1,5 +1,5 @@ //@ compile-flags: --remap-path-prefix={{src-base}}=remapped -//@ compile-flags: -Zremap-path-scope=debuginfo +//@ compile-flags: --remap-path-scope=debuginfo #[macro_export] macro_rules! my_file { diff --git a/tests/ui/errors/auxiliary/file-diag.rs b/tests/ui/errors/auxiliary/file-diag.rs index f29c349f703b..61fc9d2b4829 100644 --- a/tests/ui/errors/auxiliary/file-diag.rs +++ b/tests/ui/errors/auxiliary/file-diag.rs @@ -1,5 +1,5 @@ //@ compile-flags: --remap-path-prefix={{src-base}}=remapped -//@ compile-flags: -Zremap-path-scope=diagnostics +//@ compile-flags: --remap-path-scope=diagnostics #[macro_export] macro_rules! my_file { diff --git a/tests/ui/errors/auxiliary/file-macro.rs b/tests/ui/errors/auxiliary/file-macro.rs index 11abc0549a7b..11e5de1e3274 100644 --- a/tests/ui/errors/auxiliary/file-macro.rs +++ b/tests/ui/errors/auxiliary/file-macro.rs @@ -1,5 +1,5 @@ //@ compile-flags: --remap-path-prefix={{src-base}}=remapped -//@ compile-flags: -Zremap-path-scope=macro +//@ compile-flags: --remap-path-scope=macro #[macro_export] macro_rules! my_file { diff --git a/tests/ui/errors/auxiliary/trait-debuginfo.rs b/tests/ui/errors/auxiliary/trait-debuginfo.rs index d5a0825fe6d1..dbe3d09d317d 100644 --- a/tests/ui/errors/auxiliary/trait-debuginfo.rs +++ b/tests/ui/errors/auxiliary/trait-debuginfo.rs @@ -1,4 +1,4 @@ //@ compile-flags: --remap-path-prefix={{src-base}}=remapped -//@ compile-flags: -Zremap-path-scope=debuginfo +//@ compile-flags: --remap-path-scope=debuginfo pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/auxiliary/trait-diag.rs b/tests/ui/errors/auxiliary/trait-diag.rs index e07961a276a9..3a30366683c4 100644 --- a/tests/ui/errors/auxiliary/trait-diag.rs +++ b/tests/ui/errors/auxiliary/trait-diag.rs @@ -1,4 +1,4 @@ //@ compile-flags: --remap-path-prefix={{src-base}}=remapped -//@ compile-flags: -Zremap-path-scope=diagnostics +//@ compile-flags: --remap-path-scope=diagnostics pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/auxiliary/trait-macro.rs b/tests/ui/errors/auxiliary/trait-macro.rs index 48673d04ee16..334b1c9bba2f 100644 --- a/tests/ui/errors/auxiliary/trait-macro.rs +++ b/tests/ui/errors/auxiliary/trait-macro.rs @@ -1,4 +1,4 @@ //@ compile-flags: --remap-path-prefix={{src-base}}=remapped -//@ compile-flags: -Zremap-path-scope=macro +//@ compile-flags: --remap-path-scope=macro pub trait Trait: std::fmt::Display {} diff --git a/tests/ui/errors/remap-path-prefix-diagnostics.rs b/tests/ui/errors/remap-path-prefix-diagnostics.rs index fac7e937cb0b..54dbcfd64711 100644 --- a/tests/ui/errors/remap-path-prefix-diagnostics.rs +++ b/tests/ui/errors/remap-path-prefix-diagnostics.rs @@ -1,4 +1,4 @@ -// This test exercises `-Zremap-path-scope`, diagnostics printing paths and dependency. +// This test exercises `--remap-path-scope`, diagnostics printing paths and dependency. // // We test different combinations with/without remap in deps, with/without remap in this // crate but always in deps and always here but never in deps. @@ -12,10 +12,10 @@ //@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[not-diag-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped -//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics -//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro -//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo -//@[not-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics +//@[with-diag-in-deps] compile-flags: --remap-path-scope=diagnostics +//@[with-macro-in-deps] compile-flags: --remap-path-scope=macro +//@[with-debuginfo-in-deps] compile-flags: --remap-path-scope=debuginfo +//@[not-diag-in-deps] compile-flags: --remap-path-scope=diagnostics //@[with-diag-in-deps] aux-build:trait-diag.rs //@[with-macro-in-deps] aux-build:trait-macro.rs diff --git a/tests/ui/errors/remap-path-prefix-macro.rs b/tests/ui/errors/remap-path-prefix-macro.rs index 3e93843f9164..1f895aeeb6b4 100644 --- a/tests/ui/errors/remap-path-prefix-macro.rs +++ b/tests/ui/errors/remap-path-prefix-macro.rs @@ -1,4 +1,4 @@ -// This test exercises `-Zremap-path-scope`, macros (like file!()) and dependency. +// This test exercises `--remap-path-scope`, macros (like file!()) and dependency. // // We test different combinations with/without remap in deps, with/without remap in // this crate but always in deps and always here but never in deps. @@ -15,10 +15,10 @@ //@[with-debuginfo-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped //@[not-macro-in-deps] compile-flags: --remap-path-prefix={{src-base}}=remapped -//@[with-diag-in-deps] compile-flags: -Zremap-path-scope=diagnostics -//@[with-macro-in-deps] compile-flags: -Zremap-path-scope=macro -//@[with-debuginfo-in-deps] compile-flags: -Zremap-path-scope=debuginfo -//@[not-macro-in-deps] compile-flags: -Zremap-path-scope=macro +//@[with-diag-in-deps] compile-flags: --remap-path-scope=diagnostics +//@[with-macro-in-deps] compile-flags: --remap-path-scope=macro +//@[with-debuginfo-in-deps] compile-flags: --remap-path-scope=debuginfo +//@[not-macro-in-deps] compile-flags: --remap-path-scope=macro //@[with-diag-in-deps] aux-build:file-diag.rs //@[with-macro-in-deps] aux-build:file-macro.rs diff --git a/tests/ui/errors/remap-path-prefix.rs b/tests/ui/errors/remap-path-prefix.rs index de18aa8cc204..b49514711355 100644 --- a/tests/ui/errors/remap-path-prefix.rs +++ b/tests/ui/errors/remap-path-prefix.rs @@ -1,7 +1,7 @@ //@ revisions: normal with-diagnostic-scope without-diagnostic-scope //@ compile-flags: --remap-path-prefix={{src-base}}=remapped -//@ [with-diagnostic-scope]compile-flags: -Zremap-path-scope=diagnostics -//@ [without-diagnostic-scope]compile-flags: -Zremap-path-scope=object +//@ [with-diagnostic-scope]compile-flags: --remap-path-scope=diagnostics +//@ [without-diagnostic-scope]compile-flags: --remap-path-scope=object // Manually remap, so the remapped path remains in .stderr file. // The remapped paths are not normalized by compiletest. From 075548e9e98013c1ac5e04ae36052b64eab6a5b5 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 13 Dec 2025 18:51:30 +0000 Subject: [PATCH 0748/3801] fix: `unchecked_time_subtraction` FN on `Ops::sub` method call --- clippy_lints/src/time_subtraction.rs | 55 ++++++++++------------ tests/ui/unchecked_time_subtraction.fixed | 10 ++++ tests/ui/unchecked_time_subtraction.rs | 10 ++++ tests/ui/unchecked_time_subtraction.stderr | 14 +++++- 4 files changed, 59 insertions(+), 30 deletions(-) diff --git a/clippy_lints/src/time_subtraction.rs b/clippy_lints/src/time_subtraction.rs index e0fdca97dbee..b4a07db9aeda 100644 --- a/clippy_lints/src/time_subtraction.rs +++ b/clippy_lints/src/time_subtraction.rs @@ -8,7 +8,6 @@ use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::impl_lint_pass; -use rustc_span::source_map::Spanned; use rustc_span::sym; declare_clippy_lint! { @@ -84,43 +83,41 @@ impl_lint_pass!(UncheckedTimeSubtraction => [MANUAL_INSTANT_ELAPSED, UNCHECKED_T impl LateLintPass<'_> for UncheckedTimeSubtraction { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) { - if let ExprKind::Binary( - Spanned { - node: BinOpKind::Sub, .. + let (lhs, rhs) = match expr.kind { + ExprKind::Binary(op, lhs, rhs) if matches!(op.node, BinOpKind::Sub,) => (lhs, rhs), + ExprKind::MethodCall(fn_name, lhs, [rhs], _) if cx.ty_based_def(expr).is_diag_item(cx, sym::sub) => { + (lhs, rhs) }, - lhs, - rhs, - ) = expr.kind - { - let typeck = cx.typeck_results(); - let lhs_ty = typeck.expr_ty(lhs); - let rhs_ty = typeck.expr_ty(rhs); + _ => return, + }; + let typeck = cx.typeck_results(); + let lhs_ty = typeck.expr_ty(lhs); + let rhs_ty = typeck.expr_ty(rhs); - if lhs_ty.is_diag_item(cx, sym::Instant) { - // Instant::now() - instant - if is_instant_now_call(cx, lhs) - && rhs_ty.is_diag_item(cx, sym::Instant) - && let Some(sugg) = Sugg::hir_opt(cx, rhs) - { - print_manual_instant_elapsed_sugg(cx, expr, sugg); - } - // instant - duration - else if rhs_ty.is_diag_item(cx, sym::Duration) - && !expr.span.from_expansion() - && self.msrv.meets(cx, msrvs::TRY_FROM) - { - print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); - } + if lhs_ty.is_diag_item(cx, sym::Instant) { + // Instant::now() - instant + if is_instant_now_call(cx, lhs) + && rhs_ty.is_diag_item(cx, sym::Instant) + && let Some(sugg) = Sugg::hir_opt(cx, rhs) + { + print_manual_instant_elapsed_sugg(cx, expr, sugg); } - // duration - duration - else if lhs_ty.is_diag_item(cx, sym::Duration) - && rhs_ty.is_diag_item(cx, sym::Duration) + // instant - duration + else if rhs_ty.is_diag_item(cx, sym::Duration) && !expr.span.from_expansion() && self.msrv.meets(cx, msrvs::TRY_FROM) { print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); } } + // duration - duration + else if lhs_ty.is_diag_item(cx, sym::Duration) + && rhs_ty.is_diag_item(cx, sym::Duration) + && !expr.span.from_expansion() + && self.msrv.meets(cx, msrvs::TRY_FROM) + { + print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr); + } } } diff --git a/tests/ui/unchecked_time_subtraction.fixed b/tests/ui/unchecked_time_subtraction.fixed index 2f923fef4c25..a75de6c9717c 100644 --- a/tests/ui/unchecked_time_subtraction.fixed +++ b/tests/ui/unchecked_time_subtraction.fixed @@ -35,3 +35,13 @@ fn main() { let _ = (2 * dur1).checked_sub(dur2).unwrap(); //~^ unchecked_time_subtraction } + +fn issue16230() { + use std::ops::Sub as _; + + Duration::ZERO.checked_sub(Duration::MAX).unwrap(); + //~^ unchecked_time_subtraction + + let _ = Duration::ZERO.checked_sub(Duration::MAX).unwrap(); + //~^ unchecked_time_subtraction +} diff --git a/tests/ui/unchecked_time_subtraction.rs b/tests/ui/unchecked_time_subtraction.rs index cf727f62aafa..dd40d8aa14c4 100644 --- a/tests/ui/unchecked_time_subtraction.rs +++ b/tests/ui/unchecked_time_subtraction.rs @@ -35,3 +35,13 @@ fn main() { let _ = 2 * dur1 - dur2; //~^ unchecked_time_subtraction } + +fn issue16230() { + use std::ops::Sub as _; + + Duration::ZERO.sub(Duration::MAX); + //~^ unchecked_time_subtraction + + let _ = Duration::ZERO - Duration::MAX; + //~^ unchecked_time_subtraction +} diff --git a/tests/ui/unchecked_time_subtraction.stderr b/tests/ui/unchecked_time_subtraction.stderr index c129497447fc..046024d11f75 100644 --- a/tests/ui/unchecked_time_subtraction.stderr +++ b/tests/ui/unchecked_time_subtraction.stderr @@ -49,5 +49,17 @@ error: unchecked subtraction of a `Duration` LL | let _ = 2 * dur1 - dur2; | ^^^^^^^^^^^^^^^ help: try: `(2 * dur1).checked_sub(dur2).unwrap()` -error: aborting due to 8 previous errors +error: unchecked subtraction of a `Duration` + --> tests/ui/unchecked_time_subtraction.rs:42:5 + | +LL | Duration::ZERO.sub(Duration::MAX); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::ZERO.checked_sub(Duration::MAX).unwrap()` + +error: unchecked subtraction of a `Duration` + --> tests/ui/unchecked_time_subtraction.rs:45:13 + | +LL | let _ = Duration::ZERO - Duration::MAX; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::ZERO.checked_sub(Duration::MAX).unwrap()` + +error: aborting due to 10 previous errors From e95ceddbc6aea8bda568bad7793939749558a992 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 13 Dec 2025 19:06:44 +0000 Subject: [PATCH 0749/3801] fix: `unchecked_time_subtraction` wrongly unmangled macros --- clippy_lints/src/time_subtraction.rs | 5 +++-- tests/ui/unchecked_time_subtraction.fixed | 15 +++++++++++++++ tests/ui/unchecked_time_subtraction.rs | 15 +++++++++++++++ tests/ui/unchecked_time_subtraction.stderr | 14 +++++++++++++- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/time_subtraction.rs b/clippy_lints/src/time_subtraction.rs index b4a07db9aeda..b3ad13d8488d 100644 --- a/clippy_lints/src/time_subtraction.rs +++ b/clippy_lints/src/time_subtraction.rs @@ -178,8 +178,9 @@ fn print_unchecked_duration_subtraction_sugg( // avoid suggestions if !is_chained_time_subtraction(cx, left_expr) { let mut applicability = Applicability::MachineApplicable; - let left_sugg = Sugg::hir_with_applicability(cx, left_expr, "", &mut applicability); - let right_sugg = Sugg::hir_with_applicability(cx, right_expr, "", &mut applicability); + let left_sugg = Sugg::hir_with_context(cx, left_expr, expr.span.ctxt(), "", &mut applicability); + let right_sugg = + Sugg::hir_with_context(cx, right_expr, expr.span.ctxt(), "", &mut applicability); diag.span_suggestion( expr.span, diff --git a/tests/ui/unchecked_time_subtraction.fixed b/tests/ui/unchecked_time_subtraction.fixed index a75de6c9717c..830b737f18e7 100644 --- a/tests/ui/unchecked_time_subtraction.fixed +++ b/tests/ui/unchecked_time_subtraction.fixed @@ -45,3 +45,18 @@ fn issue16230() { let _ = Duration::ZERO.checked_sub(Duration::MAX).unwrap(); //~^ unchecked_time_subtraction } + +fn issue16234() { + use std::ops::Sub as _; + + macro_rules! duration { + ($secs:expr) => { + Duration::from_secs($secs) + }; + } + + duration!(0).checked_sub(duration!(1)).unwrap(); + //~^ unchecked_time_subtraction + let _ = duration!(0).checked_sub(duration!(1)).unwrap(); + //~^ unchecked_time_subtraction +} diff --git a/tests/ui/unchecked_time_subtraction.rs b/tests/ui/unchecked_time_subtraction.rs index dd40d8aa14c4..e41860157c41 100644 --- a/tests/ui/unchecked_time_subtraction.rs +++ b/tests/ui/unchecked_time_subtraction.rs @@ -45,3 +45,18 @@ fn issue16230() { let _ = Duration::ZERO - Duration::MAX; //~^ unchecked_time_subtraction } + +fn issue16234() { + use std::ops::Sub as _; + + macro_rules! duration { + ($secs:expr) => { + Duration::from_secs($secs) + }; + } + + duration!(0).sub(duration!(1)); + //~^ unchecked_time_subtraction + let _ = duration!(0) - duration!(1); + //~^ unchecked_time_subtraction +} diff --git a/tests/ui/unchecked_time_subtraction.stderr b/tests/ui/unchecked_time_subtraction.stderr index 046024d11f75..fa4bd1db81ae 100644 --- a/tests/ui/unchecked_time_subtraction.stderr +++ b/tests/ui/unchecked_time_subtraction.stderr @@ -61,5 +61,17 @@ error: unchecked subtraction of a `Duration` LL | let _ = Duration::ZERO - Duration::MAX; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::ZERO.checked_sub(Duration::MAX).unwrap()` -error: aborting due to 10 previous errors +error: unchecked subtraction of a `Duration` + --> tests/ui/unchecked_time_subtraction.rs:58:5 + | +LL | duration!(0).sub(duration!(1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `duration!(0).checked_sub(duration!(1)).unwrap()` + +error: unchecked subtraction of a `Duration` + --> tests/ui/unchecked_time_subtraction.rs:60:13 + | +LL | let _ = duration!(0) - duration!(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `duration!(0).checked_sub(duration!(1)).unwrap()` + +error: aborting due to 12 previous errors From 624135bd79ccfc6602b013225de4a33d5701035f Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Sat, 13 Dec 2025 20:16:12 +0100 Subject: [PATCH 0750/3801] Promote powerpc64-unknown-linux-musl to tier 2 with host tools Signed-off-by: Jens Reidel --- .../targets/powerpc64_unknown_linux_musl.rs | 4 +- src/bootstrap/src/core/build_steps/llvm.rs | 1 + src/bootstrap/src/core/download.rs | 1 + .../Dockerfile | 2 +- .../powerpc64-linux-gnu.defconfig | 0 .../dist-powerpc64-linux-musl/Dockerfile | 39 +++++++++++++++++++ .../powerpc64-unknown-linux-musl.defconfig | 15 +++++++ src/ci/github-actions/jobs.yml | 5 ++- src/doc/rustc/src/platform-support.md | 2 +- .../powerpc64-unknown-linux-musl.md | 10 +++-- 10 files changed, 70 insertions(+), 9 deletions(-) rename src/ci/docker/host-x86_64/{dist-powerpc64-linux => dist-powerpc64-linux-gnu}/Dockerfile (89%) rename src/ci/docker/host-x86_64/{dist-powerpc64-linux => dist-powerpc64-linux-gnu}/powerpc64-linux-gnu.defconfig (100%) create mode 100644 src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/Dockerfile create mode 100644 src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/powerpc64-unknown-linux-musl.defconfig diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs index b663ddf962ea..130bcacfc8cc 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs @@ -17,8 +17,8 @@ pub(crate) fn target() -> Target { llvm_target: "powerpc64-unknown-linux-musl".into(), metadata: TargetMetadata { description: Some("64-bit PowerPC Linux with musl 1.2.5".into()), - tier: Some(3), - host_tools: Some(false), + tier: Some(2), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index db2a76c4a2df..8acc92451519 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -223,6 +223,7 @@ pub(crate) fn is_ci_llvm_available_for_target( ("loongarch64-unknown-linux-musl", false), ("powerpc-unknown-linux-gnu", false), ("powerpc64-unknown-linux-gnu", false), + ("powerpc64-unknown-linux-musl", false), ("powerpc64le-unknown-linux-gnu", false), ("powerpc64le-unknown-linux-musl", false), ("riscv64gc-unknown-linux-gnu", false), diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index d950dc1a1c58..274bd56aff7e 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -460,6 +460,7 @@ pub(crate) fn is_download_ci_available(target_triple: &str, llvm_assertions: boo "loongarch64-unknown-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", + "powerpc64-unknown-linux-musl", "powerpc64le-unknown-linux-gnu", "powerpc64le-unknown-linux-musl", "riscv64gc-unknown-linux-gnu", diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64-linux-gnu/Dockerfile similarity index 89% rename from src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile rename to src/ci/docker/host-x86_64/dist-powerpc64-linux-gnu/Dockerfile index 298282a76463..046406224c34 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-powerpc64-linux-gnu/Dockerfile @@ -11,7 +11,7 @@ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp COPY scripts/crosstool-ng-build.sh /scripts/ -COPY host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.defconfig /tmp/crosstool.defconfig +COPY host-x86_64/dist-powerpc64-linux-gnu/powerpc64-linux-gnu.defconfig /tmp/crosstool.defconfig RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-powerpc64-linux-gnu/powerpc64-linux-gnu.defconfig similarity index 100% rename from src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.defconfig rename to src/ci/docker/host-x86_64/dist-powerpc64-linux-gnu/powerpc64-linux-gnu.defconfig diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/Dockerfile new file mode 100644 index 000000000000..7c8a1e657ac2 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/Dockerfile @@ -0,0 +1,39 @@ +FROM ubuntu:22.04 + +COPY scripts/cross-apt-packages.sh /scripts/ +RUN sh /scripts/cross-apt-packages.sh + +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh + +COPY scripts/rustbuild-setup.sh /scripts/ +RUN sh /scripts/rustbuild-setup.sh + +WORKDIR /tmp + +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-powerpc64-linux-musl/powerpc64-unknown-linux-musl.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-musl/bin + +ENV \ + AR_powerpc64_unknown_linux_musl=powerpc64-unknown-linux-musl-ar \ + CC_powerpc64_unknown_linux_musl=powerpc64-unknown-linux-musl-gcc \ + CXX_powerpc64_unknown_linux_musl=powerpc64-unknown-linux-musl-g++ + +ENV HOSTS=powerpc64-unknown-linux-musl + +ENV RUST_CONFIGURE_ARGS \ + --enable-extended \ + --enable-full-tools \ + --enable-profiler \ + --enable-sanitizers \ + --disable-docs \ + --set target.powerpc64-unknown-linux-musl.crt-static=false \ + --musl-root-powerpc64=/x-tools/powerpc64-unknown-linux-musl/powerpc64-unknown-linux-musl/sysroot/usr + +ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/powerpc64-unknown-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/powerpc64-unknown-linux-musl.defconfig new file mode 100644 index 000000000000..08132d3ab8ba --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-powerpc64-linux-musl/powerpc64-unknown-linux-musl.defconfig @@ -0,0 +1,15 @@ +CT_CONFIG_VERSION="4" +CT_EXPERIMENTAL=y +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_POWERPC=y +CT_ARCH_64=y +CT_ARCH_ABI="elfv2" +# CT_DEMULTILIB is not set +CT_KERNEL_LINUX=y +CT_LINUX_V_4_19=y +CT_LIBC_MUSL=y +CT_MUSL_V_1_2_5=y +CT_CC_LANG_CXX=y +CT_GETTEXT_NEEDED=y diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 9acad5c06b21..38c30f8b8e29 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -232,7 +232,10 @@ auto: - name: dist-powerpc-linux <<: *job-linux-4c - - name: dist-powerpc64-linux + - name: dist-powerpc64-linux-gnu + <<: *job-linux-4c + + - name: dist-powerpc64-linux-musl <<: *job-linux-4c - name: dist-powerpc64le-linux-gnu diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d772702df76e..c2b26e56ef49 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -100,6 +100,7 @@ target | notes [`i686-pc-windows-gnu`](platform-support/windows-gnu.md) | 32-bit MinGW (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI] [^win32-msvc-alignment] `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2+, glibc 2.17) `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2+, glibc 2.17) +[`powerpc64-unknown-linux-musl`](platform-support/powerpc64-unknown-linux-musl.md) | PPC64 Linux (kernel 4.19+, musl 1.2.5) [`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10+, glibc 2.17) [`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19+, musl 1.2.5) [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20+, glibc 2.29) @@ -369,7 +370,6 @@ target | std | host | notes [`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | | [`powerpc64-ibm-aix`](platform-support/aix.md) | ? | | 64-bit AIX (7.2 and newer) [`powerpc64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64 FreeBSD (ELFv2) -[`powerpc64-unknown-linux-musl`](platform-support/powerpc64-unknown-linux-musl.md) | ✓ | ✓ | PPC64 Linux (kernel 4.19, musl 1.2.5) [`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 [`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`powerpc64le-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64LE FreeBSD diff --git a/src/doc/rustc/src/platform-support/powerpc64-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/powerpc64-unknown-linux-musl.md index 7213e54d5a1a..23cb31af6a26 100644 --- a/src/doc/rustc/src/platform-support/powerpc64-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/powerpc64-unknown-linux-musl.md @@ -1,10 +1,13 @@ # powerpc64-unknown-linux-musl -**Tier: 3** +**Tier: 2** Target for 64-bit big endian PowerPC Linux programs using musl libc. This target uses the ELF v2 ABI. +The baseline CPU required is a PowerPC 970, which means AltiVec is required and +the oldest IBM server CPU supported is therefore POWER6. + ## Target maintainers [@Gelbpunkt](https://github.com/Gelbpunkt) @@ -38,9 +41,8 @@ linker = "powerpc64-linux-musl-gcc" ## Building Rust programs -Rust does not yet ship pre-compiled artifacts for this target. To compile for -this target, you will first need to build Rust with the target enabled (see -"Building the target" above). +This target is distributed through `rustup`, and otherwise requires no +special configuration. ## Cross-compilation From e0a74c33352706d6c43fe8a14694241f5833b1eb Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Sat, 13 Dec 2025 20:57:44 +0000 Subject: [PATCH 0751/3801] fix: `manual_instant_elapsed` wrongly unmangled macros --- clippy_lints/src/time_subtraction.rs | 13 ++++++------- tests/ui/manual_instant_elapsed.fixed | 16 ++++++++++++++++ tests/ui/manual_instant_elapsed.rs | 16 ++++++++++++++++ tests/ui/manual_instant_elapsed.stderr | 14 +++++++++++++- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/time_subtraction.rs b/clippy_lints/src/time_subtraction.rs index b3ad13d8488d..92bce998c32f 100644 --- a/clippy_lints/src/time_subtraction.rs +++ b/clippy_lints/src/time_subtraction.rs @@ -96,11 +96,8 @@ impl LateLintPass<'_> for UncheckedTimeSubtraction { if lhs_ty.is_diag_item(cx, sym::Instant) { // Instant::now() - instant - if is_instant_now_call(cx, lhs) - && rhs_ty.is_diag_item(cx, sym::Instant) - && let Some(sugg) = Sugg::hir_opt(cx, rhs) - { - print_manual_instant_elapsed_sugg(cx, expr, sugg); + if is_instant_now_call(cx, lhs) && rhs_ty.is_diag_item(cx, sym::Instant) { + print_manual_instant_elapsed_sugg(cx, expr, rhs); } // instant - duration else if rhs_ty.is_diag_item(cx, sym::Duration) @@ -150,7 +147,9 @@ fn is_time_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { ty.is_diag_item(cx, sym::Duration) || ty.is_diag_item(cx, sym::Instant) } -fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, sugg: Sugg<'_>) { +fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, rhs: &Expr<'_>) { + let mut applicability = Applicability::MachineApplicable; + let sugg = Sugg::hir_with_context(cx, rhs, expr.span.ctxt(), "", &mut applicability); span_lint_and_sugg( cx, MANUAL_INSTANT_ELAPSED, @@ -158,7 +157,7 @@ fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, sugg "manual implementation of `Instant::elapsed`", "try", format!("{}.elapsed()", sugg.maybe_paren()), - Applicability::MachineApplicable, + applicability, ); } diff --git a/tests/ui/manual_instant_elapsed.fixed b/tests/ui/manual_instant_elapsed.fixed index a04c601e08c1..2fa5702f8a04 100644 --- a/tests/ui/manual_instant_elapsed.fixed +++ b/tests/ui/manual_instant_elapsed.fixed @@ -28,3 +28,19 @@ fn main() { // //~^^ manual_instant_elapsed } + +fn issue16236() { + use std::ops::Sub as _; + macro_rules! deref { + ($e:expr) => { + *$e + }; + } + + let start = &Instant::now(); + let _ = deref!(start).elapsed(); + //~^ manual_instant_elapsed + + deref!(start).elapsed(); + //~^ manual_instant_elapsed +} diff --git a/tests/ui/manual_instant_elapsed.rs b/tests/ui/manual_instant_elapsed.rs index 7c67f6acf85d..e7a0e6499e74 100644 --- a/tests/ui/manual_instant_elapsed.rs +++ b/tests/ui/manual_instant_elapsed.rs @@ -28,3 +28,19 @@ fn main() { // //~^^ manual_instant_elapsed } + +fn issue16236() { + use std::ops::Sub as _; + macro_rules! deref { + ($e:expr) => { + *$e + }; + } + + let start = &Instant::now(); + let _ = Instant::now().sub(deref!(start)); + //~^ manual_instant_elapsed + + Instant::now() - deref!(start); + //~^ manual_instant_elapsed +} diff --git a/tests/ui/manual_instant_elapsed.stderr b/tests/ui/manual_instant_elapsed.stderr index e84f3126f707..e42ac5739a29 100644 --- a/tests/ui/manual_instant_elapsed.stderr +++ b/tests/ui/manual_instant_elapsed.stderr @@ -13,5 +13,17 @@ error: manual implementation of `Instant::elapsed` LL | Instant::now() - *ref_to_instant; // to ensure parens are added correctly | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*ref_to_instant).elapsed()` -error: aborting due to 2 previous errors +error: manual implementation of `Instant::elapsed` + --> tests/ui/manual_instant_elapsed.rs:41:13 + | +LL | let _ = Instant::now().sub(deref!(start)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `deref!(start).elapsed()` + +error: manual implementation of `Instant::elapsed` + --> tests/ui/manual_instant_elapsed.rs:44:5 + | +LL | Instant::now() - deref!(start); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `deref!(start).elapsed()` + +error: aborting due to 4 previous errors From 0def1822a0a3f32d457644a4a8e2282d19eab071 Mon Sep 17 00:00:00 2001 From: Redddy Date: Sun, 14 Dec 2025 06:26:45 +0900 Subject: [PATCH 0752/3801] Updated titles and links for two references in the bibliography --- src/doc/rustc-dev-guide/src/appendix/bibliography.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index e862ac368475..13a9c3a0b40b 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/src/appendix/bibliography.md @@ -25,12 +25,12 @@ Rust, as well as publications about Rust. * [Contention aware scheduling](https://www.blagodurov.net/files/a8-blagodurov.pdf) * [Dynamic circular work stealing deque](https://patents.google.com/patent/US7346753B2/en) - The Chase/Lev deque * [Epoch-based reclamation](https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-579.pdf). -* [Language support for fast and reliable message passing in singularity OS](https://research.microsoft.com/pubs/67482/singsharp.pdf) +* [Language support for fast and reliable message-based communication in singularity OS](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/04/singsharp.pdf) * [Non-blocking steal-half work queues](https://www.cs.bgu.ac.il/%7Ehendlerd/papers/p280-hendler.pdf) * [Reagents: expressing and composing fine-grained concurrency](https://aturon.github.io/academic/reagents.pdf) * [Scheduling multithreaded computations by work stealing](https://www.lri.fr/~cecile/ENSEIGNEMENT/IPAR/Exposes/cilk1.pdf) * [Scheduling techniques for concurrent systems](https://www.stanford.edu/~ouster/cgi-bin/papers/coscheduling.pdf) -* [Singularity: rethinking the software stack](https://research.microsoft.com/pubs/69431/osr2007_rethinkingsoftwarestack.pdf) +* [Singularity: rethinking the software stack](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/osr2007_rethinkingsoftwarestack.pdf) * [The data locality of work stealing](http://www.aladdin.cs.cmu.edu/papers/pdfs/y2000/locality_spaa00.pdf) * [Thread scheduling for multiprogramming multiprocessors](https://dl.acm.org/doi/10.1145/277651.277678) * [Three layer cake for shared-memory programming](https://dl.acm.org/doi/10.1145/1953611.1953616) From 065e4c1c8a4701d605518f80b26bf031a22f3756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Sat, 13 Dec 2025 17:33:34 +0100 Subject: [PATCH 0753/3801] ignore windows --- tests/ui/eii/codegen_cross_crate.rs | 2 ++ tests/ui/eii/codegen_single_crate.rs | 2 ++ tests/ui/eii/default/call_default.rs | 2 ++ tests/ui/eii/default/call_impl.rs | 2 ++ tests/ui/eii/default/local_crate.rs | 2 ++ tests/ui/eii/default/local_crate_explicit.rs | 2 ++ tests/ui/eii/default/local_crate_explicit.stderr | 2 +- tests/ui/eii/duplicate/duplicate1.rs | 2 ++ tests/ui/eii/duplicate/duplicate2.rs | 2 ++ tests/ui/eii/duplicate/duplicate3.rs | 2 ++ tests/ui/eii/multiple_impls.rs | 2 ++ tests/ui/eii/privacy1.rs | 2 ++ tests/ui/eii/same-symbol.rs | 2 ++ 13 files changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/ui/eii/codegen_cross_crate.rs b/tests/ui/eii/codegen_cross_crate.rs index 760c960297e0..a1fa617491bd 100644 --- a/tests/ui/eii/codegen_cross_crate.rs +++ b/tests/ui/eii/codegen_cross_crate.rs @@ -3,6 +3,8 @@ //@ aux-build: codegen2.rs //@ compile-flags: -O //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Tests whether calling EIIs works with the declaration in another crate. #![feature(extern_item_impls)] diff --git a/tests/ui/eii/codegen_single_crate.rs b/tests/ui/eii/codegen_single_crate.rs index 00e0abca65f3..8e85c354bba1 100644 --- a/tests/ui/eii/codegen_single_crate.rs +++ b/tests/ui/eii/codegen_single_crate.rs @@ -1,6 +1,8 @@ //@ run-pass //@ check-run-results //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Tests whether calling EIIs works with the declaration in the same crate. #![feature(extern_item_impls)] diff --git a/tests/ui/eii/default/call_default.rs b/tests/ui/eii/default/call_default.rs index 7b39f6d225af..b479baa80444 100644 --- a/tests/ui/eii/default/call_default.rs +++ b/tests/ui/eii/default/call_default.rs @@ -3,6 +3,8 @@ //@ run-pass //@ check-run-results //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Functions can have target-cpu applied. On apple-darwin this is super important, // since you can have binaries which mix x86 and aarch64 code that are compatible // with both architectures. So we can't just reject target_cpu on EIIs since apple diff --git a/tests/ui/eii/default/call_impl.rs b/tests/ui/eii/default/call_impl.rs index 2e1cd5e7a966..94b2aa552a1e 100644 --- a/tests/ui/eii/default/call_impl.rs +++ b/tests/ui/eii/default/call_impl.rs @@ -4,6 +4,8 @@ //@ run-pass //@ check-run-results //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Tests EIIs with default implementations. // When an explicit implementation is given in one dependency, and the declaration is in another, // the explicit implementation is preferred. diff --git a/tests/ui/eii/default/local_crate.rs b/tests/ui/eii/default/local_crate.rs index f229f3cabf0c..d98c2fac4234 100644 --- a/tests/ui/eii/default/local_crate.rs +++ b/tests/ui/eii/default/local_crate.rs @@ -1,6 +1,8 @@ //@ run-pass //@ check-run-results //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Tests EIIs with default implementations. // In the same crate, when there's no explicit declaration, the default should be called. #![feature(extern_item_impls)] diff --git a/tests/ui/eii/default/local_crate_explicit.rs b/tests/ui/eii/default/local_crate_explicit.rs index e9d879b61c92..a4cc54fcd31f 100644 --- a/tests/ui/eii/default/local_crate_explicit.rs +++ b/tests/ui/eii/default/local_crate_explicit.rs @@ -1,6 +1,8 @@ //@ run-pass //@ check-run-results //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Tests EIIs with default implementations. // In the same crate, the explicit implementation should get priority. #![feature(extern_item_impls)] diff --git a/tests/ui/eii/default/local_crate_explicit.stderr b/tests/ui/eii/default/local_crate_explicit.stderr index 4102b35bcb5e..d80acf14c516 100644 --- a/tests/ui/eii/default/local_crate_explicit.stderr +++ b/tests/ui/eii/default/local_crate_explicit.stderr @@ -1,5 +1,5 @@ warning: function `decl1` is never used - --> $DIR/local_crate_explicit.rs:9:8 + --> $DIR/local_crate_explicit.rs:11:8 | LL | pub fn decl1(x: u64) { | ^^^^^ diff --git a/tests/ui/eii/duplicate/duplicate1.rs b/tests/ui/eii/duplicate/duplicate1.rs index 2e12d700b0a6..3269778aca0c 100644 --- a/tests/ui/eii/duplicate/duplicate1.rs +++ b/tests/ui/eii/duplicate/duplicate1.rs @@ -2,6 +2,8 @@ //@ aux-build: impl1.rs //@ aux-build: impl2.rs //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // tests that EIIs error properly, even if the conflicting implementations live in another crate. #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/duplicate2.rs b/tests/ui/eii/duplicate/duplicate2.rs index 157871d2a3db..4c883d28d74a 100644 --- a/tests/ui/eii/duplicate/duplicate2.rs +++ b/tests/ui/eii/duplicate/duplicate2.rs @@ -3,6 +3,8 @@ //@ aux-build: impl2.rs //@ aux-build: impl3.rs //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Tests the error message when there are multiple implementations of an EII in many crates. #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/duplicate3.rs b/tests/ui/eii/duplicate/duplicate3.rs index 5ac5ae7ff3d4..b04676074509 100644 --- a/tests/ui/eii/duplicate/duplicate3.rs +++ b/tests/ui/eii/duplicate/duplicate3.rs @@ -4,6 +4,8 @@ //@ aux-build: impl3.rs //@ aux-build: impl4.rs //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Tests the error message when there are multiple implementations of an EII in many crates. #![feature(extern_item_impls)] diff --git a/tests/ui/eii/multiple_impls.rs b/tests/ui/eii/multiple_impls.rs index ec3244137390..c02c783223ac 100644 --- a/tests/ui/eii/multiple_impls.rs +++ b/tests/ui/eii/multiple_impls.rs @@ -1,6 +1,8 @@ //@ run-pass //@ check-run-results //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Tests whether one function could implement two EIIs. #![feature(extern_item_impls)] diff --git a/tests/ui/eii/privacy1.rs b/tests/ui/eii/privacy1.rs index fc13a27c061e..b5bbf68bfdaf 100644 --- a/tests/ui/eii/privacy1.rs +++ b/tests/ui/eii/privacy1.rs @@ -2,6 +2,8 @@ //@ check-run-results //@ aux-build: codegen1.rs //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows // Tests whether re-exports work. #![feature(extern_item_impls)] diff --git a/tests/ui/eii/same-symbol.rs b/tests/ui/eii/same-symbol.rs index d24e5c4266bb..baf36ff4f5a0 100644 --- a/tests/ui/eii/same-symbol.rs +++ b/tests/ui/eii/same-symbol.rs @@ -1,6 +1,8 @@ //@ run-pass //@ check-run-results //@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows #![feature(extern_item_impls)] pub mod a { From 189a794a50ae964b59b157c90af4862ce6285fd8 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 14 Dec 2025 07:40:41 +0800 Subject: [PATCH 0754/3801] Fix bind_unused_param applicable on closure Example --- ```rust fn foo() { let _ = |$0x| 2; } ``` **Before this PR** ```rust fn foo() { let _ = x; let _ = |x| 2; } ``` **After this PR** Assist not applicable --- .../ide-assists/src/handlers/bind_unused_param.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs index 1b24f7fe7ffb..771e80bb9231 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs @@ -33,7 +33,7 @@ pub(crate) fn bind_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) -> O return None; } - let func = param.syntax().ancestors().find_map(ast::Fn::cast)?; + let func = param.syntax().ancestors().nth(2).and_then(ast::Fn::cast)?; let stmt_list = func.body()?.stmt_list()?; let l_curly_range = stmt_list.l_curly_token()?.text_range(); let r_curly_range = stmt_list.r_curly_token()?.text_range(); @@ -176,6 +176,18 @@ fn foo(x: i32, $0y: i32) { y; } bind_unused_param, r#" fn foo($0_x: i32, y: i32) {} +"#, + ); + } + + #[test] + fn not_applicable_closure() { + check_assist_not_applicable( + bind_unused_param, + r#" +fn foo() { + let _ = |$0x| 2; +} "#, ); } From 4081c149b890c7536d0fa03c4c379a7c58074c2a Mon Sep 17 00:00:00 2001 From: Mahdi Ali-Raihan Date: Sat, 13 Dec 2025 19:18:17 -0500 Subject: [PATCH 0755/3801] create_dir_all() operates iteratively instead of recursively --- library/std/src/fs.rs | 50 ++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index b548eb4939d4..90e619ffbc15 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -3333,26 +3333,42 @@ impl DirBuilder { return Ok(()); } - match self.inner.mkdir(path) { - Ok(()) => return Ok(()), - Err(ref e) if e.kind() == io::ErrorKind::NotFound => {} - Err(_) if path.is_dir() => return Ok(()), - Err(e) => return Err(e), - } - match path.parent() { - Some(p) => self.create_dir_all(p)?, - None => { - return Err(io::const_error!( - io::ErrorKind::Uncategorized, - "failed to create whole tree", - )); + let ancestors = path.ancestors(); + let mut uncreated_dirs = 0; + + for ancestor in ancestors { + // 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 == Path::new("") { + break; + } + + match self.inner.mkdir(ancestor) { + Ok(()) => break, + Err(e) if e.kind() == io::ErrorKind::NotFound => uncreated_dirs += 1, + // we check if the err is AlreadyExists for two reasons + // - in case the path exists as a *file* + // - and to avoid calls to .is_dir() in case of other errs + // (i.e. PermissionDenied) + Err(e) if e.kind() == io::ErrorKind::AlreadyExists && ancestor.is_dir() => break, + Err(e) => return Err(e), } } - match self.inner.mkdir(path) { - Ok(()) => Ok(()), - Err(_) if path.is_dir() => Ok(()), - Err(e) => Err(e), + + // collect only the uncreated directories w/o letting the vec resize + let mut uncreated_dirs_vec = Vec::with_capacity(uncreated_dirs); + uncreated_dirs_vec.extend(ancestors.take(uncreated_dirs)); + + for uncreated_dir in uncreated_dirs_vec.iter().rev() { + if let Err(e) = self.inner.mkdir(uncreated_dir) { + if e.kind() != io::ErrorKind::AlreadyExists || !uncreated_dir.is_dir() { + return Err(e); + } + } } + + Ok(()) } } From 98e10289ceccdfc93ce5d9fe82b04f125aeb8ede Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Sun, 14 Dec 2025 10:54:27 +0800 Subject: [PATCH 0756/3801] Enable to ping LoongArch group via triagebot --- triagebot.toml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 3182122bdeb0..1a1f71bd2edd 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -96,6 +96,17 @@ Thanks! <3 """ label = "O-ARM" +[ping.loongarch] +message = """\ +Hey LoongArch Group! This bug has been identified as a good "LoongArch candidate". +In case it's useful, here are some [instructions] for tackling these sorts of +bugs. Maybe take a look? +Thanks! <3 + +[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/loongarch.html +""" +label = "O-loongarch" + [ping.risc-v] message = """\ Hey RISC-V Group! This bug has been identified as a good "RISC-V candidate". From 9dca2a8ad32aeb93d75429427baf3c38d9d58de2 Mon Sep 17 00:00:00 2001 From: Cuong Le Date: Sun, 14 Dec 2025 09:56:35 +0700 Subject: [PATCH 0757/3801] Refactor loops MethodCall handling into single match --- clippy_lints/src/loops/mod.rs | 36 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index e273567c98eb..051765a22c31 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -883,23 +883,29 @@ impl<'tcx> LateLintPass<'tcx> for Loops { } if let ExprKind::MethodCall(path, recv, args, _) = expr.kind { - if matches!( - path.ident.name, - sym::all | sym::any | sym::filter_map | sym::find_map | sym::flat_map | sym::for_each | sym::map - ) && let [arg] = args - { - unused_enumerate_index::check_method(cx, expr, recv, arg); - } - - if matches!( - path.ident.name, - sym::all | sym::any | sym::for_each | sym::try_for_each | sym::fold | sym::try_fold | sym::reduce - ) && cx + let name = path.ident.name; + let is_iterator_method = cx .ty_based_def(expr) .assoc_fn_parent(cx) - .is_diag_item(cx, sym::Iterator) - { - never_loop::check_iterator_reduction(cx, expr, recv, args); + .is_diag_item(cx, sym::Iterator); + + match (name, args) { + (sym::for_each | sym::all | sym::any, [arg]) => { + unused_enumerate_index::check_method(cx, expr, recv, arg); + if is_iterator_method { + never_loop::check_iterator_reduction(cx, expr, recv, args); + } + }, + + (sym::filter_map | sym::find_map | sym::flat_map | sym::map, [arg]) => { + unused_enumerate_index::check_method(cx, expr, recv, arg); + }, + + (sym::try_for_each | sym::reduce | sym::fold | sym::try_fold, args) if is_iterator_method => { + never_loop::check_iterator_reduction(cx, expr, recv, args); + }, + + _ => {}, } } } From 594623cada4441419550389c99822a541c99eced Mon Sep 17 00:00:00 2001 From: dfireBird Date: Sun, 7 Dec 2025 18:09:55 +0530 Subject: [PATCH 0758/3801] feat: semantics implementation of locals used for extract function fix: consider let-else expr for return control type --- .../crates/hir-expand/src/name.rs | 4 + .../rust-analyzer/crates/hir/src/semantics.rs | 84 ++++++- .../crates/hir/src/source_analyzer.rs | 2 +- .../src/handlers/extract_function.rs | 205 ++++++++++-------- 4 files changed, 200 insertions(+), 95 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs index 217d991d110d..1e5efb6e146f 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs @@ -197,6 +197,10 @@ impl Name { pub fn symbol(&self) -> &Symbol { &self.symbol } + + pub fn is_generated(&self) -> bool { + self.as_str().starts_with("") + } } struct Display<'a> { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index ffb518b1e66f..a9af26aa3f66 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -16,7 +16,7 @@ use hir_def::{ expr_store::{Body, ExprOrPatSource, HygieneId, path::Path}, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, nameres::{ModuleOrigin, crate_def_map}, - resolver::{self, HasResolver, Resolver, TypeNs}, + resolver::{self, HasResolver, Resolver, TypeNs, ValueNs}, type_ref::Mutability, }; use hir_expand::{ @@ -2192,6 +2192,88 @@ impl<'db> SemanticsImpl<'db> { self.cache(adt_source.value.syntax().ancestors().last().unwrap(), adt_source.file_id); ToDef::to_def(self, adt_source.as_ref()) } + + pub fn locals_used( + &self, + element: Either<&ast::Expr, &ast::StmtList>, + text_range: TextRange, + ) -> Option> { + let sa = self.analyze(element.either(|e| e.syntax(), |s| s.syntax()))?; + let store = sa.store()?; + let mut resolver = sa.resolver.clone(); + let def = resolver.body_owner()?; + + let is_not_generated = |path: &Path| { + !path.mod_path().and_then(|path| path.as_ident()).is_some_and(Name::is_generated) + }; + + let exprs = element.either( + |e| vec![e.clone()], + |stmts| { + let mut exprs: Vec<_> = stmts + .statements() + .filter(|stmt| text_range.contains_range(stmt.syntax().text_range())) + .filter_map(|stmt| match stmt { + ast::Stmt::ExprStmt(expr_stmt) => expr_stmt.expr().map(|e| vec![e]), + ast::Stmt::Item(_) => None, + ast::Stmt::LetStmt(let_stmt) => { + let init = let_stmt.initializer(); + let let_else = let_stmt + .let_else() + .and_then(|le| le.block_expr()) + .map(ast::Expr::BlockExpr); + + match (init, let_else) { + (Some(i), Some(le)) => Some(vec![i, le]), + (Some(i), _) => Some(vec![i]), + (_, Some(le)) => Some(vec![le]), + _ => None, + } + } + }) + .flatten() + .collect(); + + if let Some(tail_expr) = stmts.tail_expr() + && text_range.contains_range(tail_expr.syntax().text_range()) + { + exprs.push(tail_expr); + } + exprs + }, + ); + let mut exprs: Vec<_> = + exprs.into_iter().filter_map(|e| sa.expr_id(e).and_then(|e| e.as_expr())).collect(); + + let mut locals: Vec = Vec::new(); + let mut add_to_locals_used = |expr_id| { + if let Expr::Path(path) = &store[expr_id] + && is_not_generated(path) + { + let _ = resolver.update_to_inner_scope(self.db, def, expr_id); + resolver + .resolve_path_in_value_ns_fully(self.db, path, store.expr_path_hygiene(expr_id)) + .inspect(|value| { + if let ValueNs::LocalBinding(id) = value { + locals.push((def, *id).into()); + } + }); + } + }; + + while let Some(expr_id) = exprs.pop() { + let mut has_child = false; + store.walk_child_exprs(expr_id, |id| { + has_child = true; + exprs.push(id); + }); + if !has_child { + add_to_locals_used(expr_id) + } + } + + Some(locals) + } } // FIXME This can't be the best way to do this diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 901c9e1575b2..b90eb97d8791 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -240,7 +240,7 @@ impl<'db> SourceAnalyzer<'db> { ) } - fn expr_id(&self, expr: ast::Expr) -> Option { + pub(crate) fn expr_id(&self, expr: ast::Expr) -> Option { let src = InFile { file_id: self.file_id, value: expr }; self.store_sm()?.node_expr(src.as_ref()) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 4b7314be4609..19ded49b1850 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -9,14 +9,14 @@ use hir::{ use ide_db::{ FxIndexSet, RootDatabase, assists::GroupLabel, - defs::{Definition, NameRefClass}, + defs::Definition, famous_defs::FamousDefs, helpers::mod_path_to_ast, imports::insert_use::{ImportScope, insert_use}, search::{FileReference, ReferenceCategory, SearchScope}, source_change::SourceChangeBuilder, syntax_helpers::node_ext::{ - for_each_tail_expr, preorder_expr, walk_expr, walk_pat, walk_patterns_in_expr, + for_each_tail_expr, preorder_expr, walk_pat, walk_patterns_in_expr, }, }; use itertools::Itertools; @@ -687,29 +687,6 @@ impl FunctionBody { } } - fn walk_expr(&self, cb: &mut dyn FnMut(ast::Expr)) { - match self { - FunctionBody::Expr(expr) => walk_expr(expr, cb), - FunctionBody::Span { parent, text_range, .. } => { - parent - .statements() - .filter(|stmt| text_range.contains_range(stmt.syntax().text_range())) - .filter_map(|stmt| match stmt { - ast::Stmt::ExprStmt(expr_stmt) => expr_stmt.expr(), - ast::Stmt::Item(_) => None, - ast::Stmt::LetStmt(stmt) => stmt.initializer(), - }) - .for_each(|expr| walk_expr(&expr, cb)); - if let Some(expr) = parent - .tail_expr() - .filter(|it| text_range.contains_range(it.syntax().text_range())) - { - walk_expr(&expr, cb); - } - } - } - } - fn preorder_expr(&self, cb: &mut dyn FnMut(WalkEvent) -> bool) { match self { FunctionBody::Expr(expr) => preorder_expr(expr, cb), @@ -718,10 +695,24 @@ impl FunctionBody { .statements() .filter(|stmt| text_range.contains_range(stmt.syntax().text_range())) .filter_map(|stmt| match stmt { - ast::Stmt::ExprStmt(expr_stmt) => expr_stmt.expr(), + ast::Stmt::ExprStmt(expr_stmt) => expr_stmt.expr().map(|e| vec![e]), ast::Stmt::Item(_) => None, - ast::Stmt::LetStmt(stmt) => stmt.initializer(), + ast::Stmt::LetStmt(stmt) => { + let init = stmt.initializer(); + let let_else = stmt + .let_else() + .and_then(|le| le.block_expr()) + .map(ast::Expr::BlockExpr); + + match (init, let_else) { + (Some(i), Some(le)) => Some(vec![i, le]), + (Some(i), _) => Some(vec![i]), + (_, Some(le)) => Some(vec![le]), + _ => None, + } + } }) + .flatten() .for_each(|expr| preorder_expr(&expr, cb)); if let Some(expr) = parent .tail_expr() @@ -799,22 +790,14 @@ impl FunctionBody { let mut self_param = None; let mut res = FxIndexSet::default(); - fn local_from_name_ref( - sema: &Semantics<'_, RootDatabase>, - name_ref: ast::NameRef, - ) -> Option { - match NameRefClass::classify(sema, &name_ref) { - Some( - NameRefClass::Definition(Definition::Local(local_ref), _) - | NameRefClass::FieldShorthand { local_ref, field_ref: _, adt_subst: _ }, - ) => Some(local_ref), - _ => None, - } - } + let (text_range, element) = match self { + FunctionBody::Expr(expr) => (expr.syntax().text_range(), Either::Left(expr)), + FunctionBody::Span { parent, text_range, .. } => (*text_range, Either::Right(parent)), + }; let mut add_name_if_local = |local_ref: Local| { - let InFile { file_id, value } = local_ref.primary_source(sema.db).source; // locals defined inside macros are not relevant to us + let InFile { file_id, value } = local_ref.primary_source(sema.db).source; if !file_id.is_macro() { match value { Either::Right(it) => { @@ -826,59 +809,11 @@ impl FunctionBody { } } }; - self.walk_expr(&mut |expr| match expr { - ast::Expr::PathExpr(path_expr) => { - if let Some(local) = path_expr - .path() - .and_then(|it| it.as_single_name_ref()) - .and_then(|name_ref| local_from_name_ref(sema, name_ref)) - { - add_name_if_local(local); - } - } - ast::Expr::ClosureExpr(closure_expr) => { - if let Some(body) = closure_expr.body() { - body.syntax() - .descendants() - .filter_map(ast::NameRef::cast) - .filter_map(|name_ref| local_from_name_ref(sema, name_ref)) - .for_each(&mut add_name_if_local); - } - } - ast::Expr::MacroExpr(expr) => { - if let Some(tt) = expr.macro_call().and_then(|call| call.token_tree()) { - tt.syntax() - .descendants_with_tokens() - .filter_map(SyntaxElement::into_token) - .filter(|it| { - matches!(it.kind(), SyntaxKind::STRING | SyntaxKind::IDENT | T![self]) - }) - .for_each(|t| { - if ast::String::can_cast(t.kind()) { - if let Some(parts) = - ast::String::cast(t).and_then(|s| sema.as_format_args_parts(&s)) - { - parts - .into_iter() - .filter_map(|(_, value)| value.and_then(|it| it.left())) - .filter_map(|path| match path { - PathResolution::Local(local) => Some(local), - _ => None, - }) - .for_each(&mut add_name_if_local); - } - } else { - sema.descend_into_macros_exact(t) - .into_iter() - .filter_map(|t| t.parent().and_then(ast::NameRef::cast)) - .filter_map(|name_ref| local_from_name_ref(sema, name_ref)) - .for_each(&mut add_name_if_local); - } - }); - } - } - _ => (), - }); + + if let Some(locals) = sema.locals_used(element, text_range) { + locals.into_iter().for_each(&mut add_name_if_local); + } + (res, self_param) } @@ -6291,6 +6226,90 @@ fn foo() { fn $0fun_name(v: i32) { print!("{v:?}{}", v == 123); +}"#, + ); + } + + #[test] + fn no_parameter_for_variable_used_only_let_else() { + check_assist( + extract_function, + r#" +fn foo() -> u32 { + let x = 5; + + $0let Some(y) = Some(1) else { + return x * 2; + };$0 + + y +}"#, + r#" +fn foo() -> u32 { + let x = 5; + + let y = match fun_name(x) { + Ok(value) => value, + Err(value) => return value, + }; + + y +} + +fn $0fun_name(x: u32) -> Result<_, u32> { + let Some(y) = Some(1) else { + return Err(x * 2); + }; + Ok(y) +}"#, + ); + } + + #[test] + fn deeply_nested_macros() { + check_assist( + extract_function, + r#" +macro_rules! m { + ($val:ident) => { $val }; +} + +macro_rules! n { + ($v1:ident, $v2:ident) => { m!($v1) + $v2 }; +} + +macro_rules! o { + ($v1:ident, $v2:ident, $v3:ident) => { n!($v1, $v2) + $v3 }; +} + +fn foo() -> u32 { + let v1 = 1; + let v2 = 2; + $0let v3 = 3; + o!(v1, v2, v3)$0 +}"#, + r#" +macro_rules! m { + ($val:ident) => { $val }; +} + +macro_rules! n { + ($v1:ident, $v2:ident) => { m!($v1) + $v2 }; +} + +macro_rules! o { + ($v1:ident, $v2:ident, $v3:ident) => { n!($v1, $v2) + $v3 }; +} + +fn foo() -> u32 { + let v1 = 1; + let v2 = 2; + fun_name(v1, v2) +} + +fn $0fun_name(v1: u32, v2: u32) -> u32 { + let v3 = 3; + o!(v1, v2, v3) }"#, ); } From ba6b40e6dc37cf3138aedc38a2cdf3a57c8aeb8f Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sun, 14 Dec 2025 04:58:26 +0000 Subject: [PATCH 0759/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 2cd4ee6bcf517345dd76d7b102d56b2e873cddbc. --- 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 e79ad9362c08..a1b44d65c597 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -dc47a69ed94bc88b10b7d500cceacf29b87bcbbe +2cd4ee6bcf517345dd76d7b102d56b2e873cddbc From 8bd369063e35abe3519f34227ed0653dfa424b19 Mon Sep 17 00:00:00 2001 From: Jesung Yang Date: Sun, 14 Dec 2025 03:25:08 +0000 Subject: [PATCH 0760/3801] fix: respect rustc's lint attribute application order Reverse the order of returned lint attributes for a `SyntaxNode` to match rustc's behavior. When multiple lint attributes are present, rustc overrides earlier ones with the last defined attribute. The previous iteration order was incorrect, causing earlier attributes to override the later ones. --- .../rust-analyzer/crates/hir/src/semantics.rs | 2 +- .../src/handlers/incorrect_case.rs | 3 +- .../src/handlers/unused_variables.rs | 55 +++++++++++++++++++ .../crates/ide-diagnostics/src/lib.rs | 10 +--- 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index ffb518b1e66f..b15e642daae7 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -267,7 +267,7 @@ impl Semantics<'_, DB> { &self, krate: Crate, item: ast::AnyHasAttrs, - ) -> impl Iterator { + ) -> impl DoubleEndedIterator { let mut cfg_options = None; let cfg_options = || *cfg_options.get_or_insert_with(|| krate.id.cfg_options(self.db)); let mut result = Vec::new(); diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs index fdc426c32c7b..4a12c5a26d45 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs @@ -1000,7 +1000,8 @@ mod OtherBadCase; // ^^^^^^^^^^^^ 💡 error: Module `OtherBadCase` should have snake_case name, e.g. `other_bad_case` //- /BAD_CASE/OtherBadCase.rs -#![deny(non_snake_case)] +#![allow(non_snake_case)] +#![deny(non_snake_case)] // The lint level has been overridden. fn FOO() {} // ^^^ 💡 error: Function `FOO` should have snake_case name, e.g. `foo` diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs index 84e63acbc04f..b7ec8fa53fa7 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unused_variables.rs @@ -182,6 +182,61 @@ fn main2() { ); } + #[test] + fn apply_last_lint_attribute_when_multiple_are_present() { + check_diagnostics( + r#" +#![allow(unused_variables)] +#![warn(unused_variables)] +#![deny(unused_variables)] + +fn main() { + let x = 2; + //^ 💡 error: unused variable + + #[deny(unused_variables)] + #[warn(unused_variables)] + #[allow(unused_variables)] + let y = 0; +} +"#, + ); + } + + #[test] + fn prefer_closest_ancestor_lint_attribute() { + check_diagnostics( + r#" +#![allow(unused_variables)] + +fn main() { + #![warn(unused_variables)] + + #[deny(unused_variables)] + let x = 2; + //^ 💡 error: unused variable +} + +#[warn(unused_variables)] +fn main2() { + #[deny(unused_variables)] + let x = 2; + //^ 💡 error: unused variable +} + +#[warn(unused_variables)] +fn main3() { + let x = 2; + //^ 💡 warn: unused variable +} + +fn main4() { + let x = 2; +} +"#, + ); + } + #[test] fn fix_unused_variable() { check_fix( diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index fe04bd175c96..343c28e8f9a4 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -643,19 +643,13 @@ fn find_outline_mod_lint_severity( let mod_def = sema.to_module_def(&mod_node)?; let module_source_file = sema.module_definition_node(mod_def); - let mut result = None; let lint_groups = lint_groups(&diag.code, edition); lint_attrs( sema, krate, ast::AnyHasAttrs::cast(module_source_file.value).expect("SourceFile always has attrs"), ) - .for_each(|(lint, severity)| { - if lint_groups.contains(&lint) { - result = Some(severity); - } - }); - result + .find_map(|(lint, severity)| lint_groups.contains(&lint).then_some(severity)) } fn lint_severity_at( @@ -682,7 +676,7 @@ fn lint_attrs( krate: hir::Crate, ancestor: ast::AnyHasAttrs, ) -> impl Iterator { - sema.lint_attrs(krate, ancestor).map(|(lint_attr, lint)| { + sema.lint_attrs(krate, ancestor).rev().map(|(lint_attr, lint)| { let severity = match lint_attr { hir::LintAttr::Allow | hir::LintAttr::Expect => Severity::Allow, hir::LintAttr::Warn => Severity::Warning, From cd39f5a5fe0dededd4d53823fe395f98f0747cc2 Mon Sep 17 00:00:00 2001 From: tison Date: Sun, 14 Dec 2025 14:35:07 +0800 Subject: [PATCH 0761/3801] Add waker_fn and local_waker_fn to std::task Signed-off-by: tison --- library/alloc/src/task.rs | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index b4116f4988b6..73b732241974 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -127,6 +127,44 @@ impl From> for RawWaker { } } +/// Converts a closure into a [`Waker`]. +/// +/// The closure gets called every time the waker is woken. +/// +/// # Examples +/// +/// ``` +/// #![feature(waker_fn)] +/// use std::task::waker_fn; +/// +/// let waker = waker_fn(|| println!("woken")); +/// +/// waker.wake_by_ref(); // Prints "woken". +/// waker.wake(); // Prints "woken". +/// ``` +#[cfg(target_has_atomic = "ptr")] +#[unstable(feature = "waker_fn", issue = "149580")] +pub fn waker_fn(f: F) -> Waker { + struct WakeFn { + f: F, + } + + impl Wake for WakeFn + where + F: Fn(), + { + fn wake(self: Arc) { + (self.f)() + } + + fn wake_by_ref(self: &Arc) { + (self.f)() + } + } + + Waker::from(Arc::new(WakeFn { f })) +} + // NB: This private function for constructing a RawWaker is used, rather than // inlining this into the `From> for RawWaker` impl, to ensure that // the safety of `From> for Waker` does not depend on the correct @@ -306,6 +344,44 @@ impl From> for RawWaker { } } +/// Converts a closure into a [`LocalWaker`]. +/// +/// The closure gets called every time the local waker is woken. +/// +/// # Examples +/// +/// ``` +/// #![feature(local_waker)] +/// #![feature(waker_fn)] +/// use std::task::local_waker_fn; +/// +/// let waker = local_waker_fn(|| println!("woken")); +/// +/// waker.wake_by_ref(); // Prints "woken". +/// waker.wake(); // Prints "woken". +/// ``` +#[unstable(feature = "waker_fn", issue = "149580")] +pub fn local_waker_fn(f: F) -> LocalWaker { + struct LocalWakeFn { + f: F, + } + + impl LocalWake for LocalWakeFn + where + F: Fn(), + { + fn wake(self: Rc) { + (self.f)() + } + + fn wake_by_ref(self: &Rc) { + (self.f)() + } + } + + LocalWaker::from(Rc::new(LocalWakeFn { f })) +} + // NB: This private function for constructing a RawWaker is used, rather than // inlining this into the `From> for RawWaker` impl, to ensure that // the safety of `From> for Waker` does not depend on the correct From a945d42399e53889a35281f3afc50935cae7fbcc Mon Sep 17 00:00:00 2001 From: usamoi Date: Sun, 14 Dec 2025 16:01:13 +0800 Subject: [PATCH 0762/3801] use simd_reduce_add_ordered on aarch64 --- .../core_arch/src/aarch64/neon/generated.rs | 32 +++++++++---------- .../spec/neon/aarch64.spec.yml | 16 +++++----- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index ce864cc7d907..b1d36343a00c 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -613,7 +613,7 @@ pub fn vaddvq_f64(a: float64x2_t) -> f64 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addp))] pub fn vaddv_s32(a: int32x2_t) -> i32 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_s8)"] @@ -622,7 +622,7 @@ pub fn vaddv_s32(a: int32x2_t) -> i32 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddv_s8(a: int8x8_t) -> i8 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_s8)"] @@ -631,7 +631,7 @@ pub fn vaddv_s8(a: int8x8_t) -> i8 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddvq_s8(a: int8x16_t) -> i8 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_s16)"] @@ -640,7 +640,7 @@ pub fn vaddvq_s8(a: int8x16_t) -> i8 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddv_s16(a: int16x4_t) -> i16 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_s16)"] @@ -649,7 +649,7 @@ pub fn vaddv_s16(a: int16x4_t) -> i16 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddvq_s16(a: int16x8_t) -> i16 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_s32)"] @@ -658,7 +658,7 @@ pub fn vaddvq_s16(a: int16x8_t) -> i16 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddvq_s32(a: int32x4_t) -> i32 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_u32)"] @@ -667,7 +667,7 @@ pub fn vaddvq_s32(a: int32x4_t) -> i32 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addp))] pub fn vaddv_u32(a: uint32x2_t) -> u32 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_u8)"] @@ -676,7 +676,7 @@ pub fn vaddv_u32(a: uint32x2_t) -> u32 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddv_u8(a: uint8x8_t) -> u8 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_u8)"] @@ -685,7 +685,7 @@ pub fn vaddv_u8(a: uint8x8_t) -> u8 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddvq_u8(a: uint8x16_t) -> u8 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddv_u16)"] @@ -694,7 +694,7 @@ pub fn vaddvq_u8(a: uint8x16_t) -> u8 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddv_u16(a: uint16x4_t) -> u16 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_u16)"] @@ -703,7 +703,7 @@ pub fn vaddv_u16(a: uint16x4_t) -> u16 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddvq_u16(a: uint16x8_t) -> u16 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_u32)"] @@ -712,7 +712,7 @@ pub fn vaddvq_u16(a: uint16x8_t) -> u16 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addv))] pub fn vaddvq_u32(a: uint32x4_t) -> u32 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_s64)"] @@ -721,7 +721,7 @@ pub fn vaddvq_u32(a: uint32x4_t) -> u32 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addp))] pub fn vaddvq_s64(a: int64x2_t) -> i64 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add across vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddvq_u64)"] @@ -730,7 +730,7 @@ pub fn vaddvq_s64(a: int64x2_t) -> i64 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addp))] pub fn vaddvq_u64(a: uint64x2_t) -> u64 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Multi-vector floating-point absolute maximum"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vamax_f32)"] @@ -15774,7 +15774,7 @@ pub fn vpadds_f32(a: float32x2_t) -> f32 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addp))] pub fn vpaddd_s64(a: int64x2_t) -> i64 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Add pairwise"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddd_u64)"] @@ -15783,7 +15783,7 @@ pub fn vpaddd_s64(a: int64x2_t) -> i64 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(addp))] pub fn vpaddd_u64(a: uint64x2_t) -> u64 { - unsafe { simd_reduce_add_unordered(a) } + unsafe { simd_reduce_add_ordered(a, 0) } } #[doc = "Floating-point add pairwise"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vpaddq_f16)"] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index 48c12779a8c1..41ba11fb0665 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -13261,7 +13261,7 @@ intrinsics: types: - [int64x2_t, i64] compose: - - FnCall: [simd_reduce_add_unordered, [a]] + - FnCall: [simd_reduce_add_ordered, [a, 0]] - name: "vpaddd_u64" doc: "Add pairwise" @@ -13274,7 +13274,7 @@ intrinsics: types: - [uint64x2_t, u64] compose: - - FnCall: [simd_reduce_add_unordered, [a]] + - FnCall: [simd_reduce_add_ordered, [a, 0]] - name: "vaddv{neon_type[0].no}" doc: "Add across vector" @@ -13291,7 +13291,7 @@ intrinsics: - [int16x8_t, i16] - [int32x4_t, i32] compose: - - FnCall: [simd_reduce_add_unordered, [a]] + - FnCall: [simd_reduce_add_ordered, [a, 0]] - name: "vaddv{neon_type[0].no}" doc: "Add across vector" @@ -13304,7 +13304,7 @@ intrinsics: types: - [int32x2_t, i32] compose: - - FnCall: [simd_reduce_add_unordered, [a]] + - FnCall: [simd_reduce_add_ordered, [a, 0]] - name: "vaddv{neon_type[0].no}" doc: "Add across vector" @@ -13317,7 +13317,7 @@ intrinsics: types: - [int64x2_t, i64] compose: - - FnCall: [simd_reduce_add_unordered, [a]] + - FnCall: [simd_reduce_add_ordered, [a, 0]] - name: "vaddv{neon_type[0].no}" doc: "Add across vector" @@ -13334,7 +13334,7 @@ intrinsics: - [uint16x8_t, u16] - [uint32x4_t, u32] compose: - - FnCall: [simd_reduce_add_unordered, [a]] + - FnCall: [simd_reduce_add_ordered, [a, 0]] - name: "vaddv{neon_type[0].no}" doc: "Add across vector" @@ -13347,7 +13347,7 @@ intrinsics: types: - [uint32x2_t, u32, i32] compose: - - FnCall: [simd_reduce_add_unordered, [a]] + - FnCall: [simd_reduce_add_ordered, [a, 0]] - name: "vaddv{neon_type[0].no}" doc: "Add across vector" @@ -13360,7 +13360,7 @@ intrinsics: types: - [uint64x2_t, u64, i64] compose: - - FnCall: [simd_reduce_add_unordered, [a]] + - FnCall: [simd_reduce_add_ordered, [a, 0]] - name: "vaddlv{neon_type[0].no}" doc: "Signed Add Long across Vector" From 701bb2fee1ca3708401a5426d31817cf3fa6bda8 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 12 Dec 2025 12:32:52 +0100 Subject: [PATCH 0763/3801] minor: Emit `WorkspaceDiagnosticRefresh` when flycheck finished --- .../crates/rust-analyzer/src/main_loop.rs | 16 ++++++++++++---- .../rust-analyzer/tests/slow-tests/support.rs | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index 77dedf12720c..1a1c0182f87a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -437,11 +437,17 @@ impl GlobalState { } } Event::Flycheck(message) => { - let _p = tracing::info_span!("GlobalState::handle_event/flycheck").entered(); - self.handle_flycheck_msg(message); + let mut cargo_finished = false; + self.handle_flycheck_msg(message, &mut cargo_finished); // Coalesce many flycheck updates into a single loop turn while let Ok(message) = self.flycheck_receiver.try_recv() { - self.handle_flycheck_msg(message); + self.handle_flycheck_msg(message, &mut cargo_finished); + } + if cargo_finished { + self.send_request::( + (), + |_, _| (), + ); } } Event::TestResult(message) => { @@ -1109,7 +1115,7 @@ impl GlobalState { } } - fn handle_flycheck_msg(&mut self, message: FlycheckMessage) { + fn handle_flycheck_msg(&mut self, message: FlycheckMessage, cargo_finished: &mut bool) { match message { FlycheckMessage::AddDiagnostic { id, @@ -1167,6 +1173,7 @@ impl GlobalState { flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)), flycheck::Progress::DidCancel => { self.last_flycheck_error = None; + *cargo_finished = true; (Progress::End, None) } flycheck::Progress::DidFailToRestart(err) => { @@ -1177,6 +1184,7 @@ impl GlobalState { flycheck::Progress::DidFinish(result) => { self.last_flycheck_error = result.err().map(|err| format!("cargo check failed to start: {err}")); + *cargo_finished = true; (Progress::End, None) } }; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs index b1b428e7068d..195ad226ae0c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs @@ -48,6 +48,7 @@ impl Project<'_> { "enable": false, }, }, + "checkOnSave": false, "procMacro": { "enable": false, } From aecd399ac8466744ca53005499ddaf374db2ed8c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 7 Dec 2025 14:50:24 +0100 Subject: [PATCH 0764/3801] internal: Give `FileSymbol` it's `'db` lifetime --- .../rust-analyzer/crates/base-db/src/lib.rs | 22 ++++++ src/tools/rust-analyzer/crates/hir/src/db.rs | 37 --------- .../rust-analyzer/crates/hir/src/symbols.rs | 23 ++++-- .../crates/ide-db/src/symbol_index.rs | 77 +++++++++++-------- .../ide-db/src/test_data/test_doc_alias.txt | 7 ++ .../test_symbol_index_collection.txt | 33 ++++++++ .../test_symbols_exclude_imports.txt | 1 + .../test_data/test_symbols_with_imports.txt | 2 + .../crates/ide/src/navigation_target.rs | 2 +- 9 files changed, 129 insertions(+), 75 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index 97938924100b..0e2255ba3fb9 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -59,6 +59,28 @@ macro_rules! impl_intern_key { }; } +/// # SAFETY +/// +/// `old_pointer` must be valid for unique writes +pub unsafe fn unsafe_update_eq(old_pointer: *mut T, new_value: T) -> bool +where + T: PartialEq, +{ + // SAFETY: Caller obligation + let old_ref: &mut T = unsafe { &mut *old_pointer }; + + if *old_ref != new_value { + *old_ref = new_value; + true + } else { + // Subtle but important: Eq impls can be buggy or define equality + // in surprising ways. If it says that the value has not changed, + // we do not modify the existing value, and thus do not have to + // update the revision, as downstream code will not see the new value. + false + } +} + pub const DEFAULT_FILE_TEXT_LRU_CAP: u16 = 16; pub const DEFAULT_PARSE_LRU_CAP: u16 = 128; pub const DEFAULT_BORROWCK_LRU_CAP: u16 = 2024; diff --git a/src/tools/rust-analyzer/crates/hir/src/db.rs b/src/tools/rust-analyzer/crates/hir/src/db.rs index 64d97b3f2a23..3021ccf4029c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir/src/db.rs @@ -4,42 +4,5 @@ //! //! But we need this for at least LRU caching at the query level. pub use hir_def::db::DefDatabase; -// AttrsQuery, BlockDefMapQuery, BlockItemTreeQuery, BlockItemTreeWithSourceMapQuery, BodyQuery, -// BodyWithSourceMapQuery, ConstDataQuery, ConstVisibilityQuery, CrateDefMapQuery, -// CrateLangItemsQuery, CrateNotableTraitsQuery, CrateSupportsNoStdQuery, DefDatabase, -// DefDatabaseStorage, EnumDataQuery, EnumVariantDataWithDiagnosticsQuery, -// ExpandProcAttrMacrosQuery, ExprScopesQuery, ExternCrateDeclDataQuery, FieldVisibilitiesQuery, -// FieldsAttrsQuery, FieldsAttrsSourceMapQuery, FileItemTreeQuery, FileItemTreeWithSourceMapQuery, -// FunctionDataQuery, FunctionVisibilityQuery, GenericParamsQuery, -// GenericParamsWithSourceMapQuery, ImplItemsWithDiagnosticsQuery, ImportMapQuery, -// IncludeMacroInvocQuery, InternAnonymousConstQuery, InternBlockQuery, InternConstQuery, -// InternDatabase, InternDatabaseStorage, InternEnumQuery, InternExternBlockQuery, -// InternExternCrateQuery, InternFunctionQuery, InternImplQuery, InternInTypeConstQuery, -// InternMacro2Query, InternMacroRulesQuery, InternProcMacroQuery, InternStaticQuery, -// InternStructQuery, InternTraitAliasQuery, InternTraitQuery, InternTypeAliasQuery, -// InternUnionQuery, InternUseQuery, LangItemQuery, Macro2DataQuery, MacroDefQuery, -// MacroRulesDataQuery, NotableTraitsInDepsQuery, ProcMacroDataQuery, StaticDataQuery, -// StructDataWithDiagnosticsQuery, TraitAliasDataQuery, TraitItemsWithDiagnosticsQuery, -// TypeAliasDataQuery, UnionDataWithDiagnosticsQuery, -// }; pub use hir_expand::db::ExpandDatabase; -// AstIdMapQuery, DeclMacroExpanderQuery, ExpandDatabase, ExpandDatabaseStorage, -// ExpandProcMacroQuery, InternMacroCallQuery, InternSyntaxContextQuery, MacroArgQuery, -// ParseMacroExpansionErrorQuery, ParseMacroExpansionQuery, ProcMacroSpanQuery, ProcMacrosQuery, -// RealSpanMapQuery, pub use hir_ty::db::HirDatabase; -// AdtDatumQuery, AdtVarianceQuery, AssociatedTyDataQuery, AssociatedTyValueQuery, BorrowckQuery, -// CallableItemSignatureQuery, ConstEvalDiscriminantQuery, ConstEvalQuery, ConstEvalStaticQuery, -// ConstParamTyQuery, DynCompatibilityOfTraitQuery, FieldTypesQuery, FnDefDatumQuery, -// FnDefVarianceQuery, GenericDefaultsQuery, GenericPredicatesForParamQuery, -// GenericPredicatesQuery, GenericPredicatesWithoutParentQuery, HirDatabase, HirDatabaseStorage, -// ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, IncoherentInherentImplCratesQuery, InferQuery, -// InherentImplsInBlockQuery, InherentImplsInCrateQuery, InternCallableDefQuery, -// InternClosureQuery, InternCoroutineQuery, InternImplTraitIdQuery, InternLifetimeParamIdQuery, -// InternTypeOrConstParamIdQuery, LayoutOfAdtQuery, LayoutOfTyQuery, LookupImplMethodQuery, -// MirBodyForClosureQuery, MirBodyQuery, MonomorphizedMirBodyForClosureQuery, -// MonomorphizedMirBodyQuery, ProgramClausesForChalkEnvQuery, ReturnTypeImplTraitsQuery, -// TargetDataLayoutQuery, TraitDatumQuery, TraitEnvironmentQuery, TraitImplsInBlockQuery, -// TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery, -// TypeAliasImplTraitsQuery, ValueTyQuery, -// }; diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs index a9320fdda7e1..073142670d2a 100644 --- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs +++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs @@ -1,5 +1,7 @@ //! File symbol extraction. +use std::marker::PhantomData; + use base_db::FxIndexSet; use either::Either; use hir_def::{ @@ -25,7 +27,7 @@ use crate::{HasCrate, Module, ModuleDef, Semantics}; /// The actual data that is stored in the index. It should be as compact as /// possible. #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FileSymbol { +pub struct FileSymbol<'db> { pub name: Symbol, pub def: ModuleDef, pub loc: DeclarationLocation, @@ -35,6 +37,7 @@ pub struct FileSymbol { pub is_assoc: bool, pub is_import: bool, pub do_not_complete: Complete, + _marker: PhantomData<&'db ()>, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -61,9 +64,9 @@ struct SymbolCollectorWork { parent: Option, } -pub struct SymbolCollector<'a> { - db: &'a dyn HirDatabase, - symbols: FxIndexSet, +pub struct SymbolCollector<'db> { + db: &'db dyn HirDatabase, + symbols: FxIndexSet>, work: Vec, current_container_name: Option, collect_pub_only: bool, @@ -83,10 +86,10 @@ impl<'a> SymbolCollector<'a> { } pub fn new_module( - db: &dyn HirDatabase, + db: &'a dyn HirDatabase, module: Module, collect_pub_only: bool, - ) -> Box<[FileSymbol]> { + ) -> Box<[FileSymbol<'a>]> { let mut symbol_collector = SymbolCollector::new(db, collect_pub_only); symbol_collector.collect(module); symbol_collector.finish() @@ -105,7 +108,7 @@ impl<'a> SymbolCollector<'a> { } } - pub fn finish(self) -> Box<[FileSymbol]> { + pub fn finish(self) -> Box<[FileSymbol<'a>]> { self.symbols.into_iter().collect() } @@ -217,6 +220,7 @@ impl<'a> SymbolCollector<'a> { is_assoc: false, is_import: true, do_not_complete: Complete::Yes, + _marker: PhantomData, }); }; @@ -251,6 +255,7 @@ impl<'a> SymbolCollector<'a> { is_assoc: false, is_import: false, do_not_complete: Complete::Yes, + _marker: PhantomData, }); }; @@ -428,6 +433,7 @@ impl<'a> SymbolCollector<'a> { is_assoc, is_import: false, do_not_complete, + _marker: PhantomData, }); } } @@ -441,6 +447,7 @@ impl<'a> SymbolCollector<'a> { is_assoc, is_import: false, do_not_complete, + _marker: PhantomData, }); do_not_complete @@ -474,6 +481,7 @@ impl<'a> SymbolCollector<'a> { is_assoc: false, is_import: false, do_not_complete, + _marker: PhantomData, }); } } @@ -487,6 +495,7 @@ impl<'a> SymbolCollector<'a> { is_assoc: false, is_import: false, do_not_complete, + _marker: PhantomData, }); } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs index c5ead45a20ae..e15d0b33bbaa 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs @@ -37,6 +37,7 @@ use hir::{ }; use rayon::prelude::*; use rustc_hash::FxHashSet; +use salsa::Update; use crate::RootDatabase; @@ -118,7 +119,7 @@ pub struct LocalRoots { } /// The symbol indices of modules that make up a given crate. -pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex]> { +pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex<'_>]> { let _p = tracing::info_span!("crate_symbols").entered(); krate.modules(db).into_iter().map(|module| SymbolIndex::module_symbols(db, module)).collect() } @@ -148,7 +149,7 @@ pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex]> // | Editor | Shortcut | // |---------|-----------| // | VS Code | Ctrl+T -pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { +pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec> { let _p = tracing::info_span!("world_symbols", query = ?query.query).entered(); let indices: Vec<_> = if query.libs { @@ -170,9 +171,7 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { crates .par_iter() .for_each_with(db.clone(), |snap, &krate| _ = crate_symbols(snap, krate.into())); - let indices: Vec<_> = - crates.into_iter().map(|krate| crate_symbols(db, krate.into())).collect(); - indices.iter().flat_map(|indices| indices.iter().cloned()).collect() + crates.into_iter().flat_map(|krate| Vec::from(crate_symbols(db, krate.into()))).collect() }; let mut res = vec![]; @@ -184,24 +183,27 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { } #[derive(Default)] -pub struct SymbolIndex { - symbols: Box<[FileSymbol]>, +pub struct SymbolIndex<'db> { + symbols: Box<[FileSymbol<'db>]>, map: fst::Map>, } -impl SymbolIndex { +impl<'db> SymbolIndex<'db> { /// The symbol index for a given source root within library_roots. - pub fn library_symbols(db: &dyn HirDatabase, source_root_id: SourceRootId) -> &SymbolIndex { + pub fn library_symbols( + db: &'db dyn HirDatabase, + source_root_id: SourceRootId, + ) -> &'db SymbolIndex<'db> { // FIXME: #[salsa::interned] struct InternedSourceRootId { id: SourceRootId, } #[salsa::tracked(returns(ref))] - fn library_symbols( - db: &dyn HirDatabase, - source_root_id: InternedSourceRootId<'_>, - ) -> SymbolIndex { + fn library_symbols<'db>( + db: &'db dyn HirDatabase, + source_root_id: InternedSourceRootId<'db>, + ) -> SymbolIndex<'db> { let _p = tracing::info_span!("library_symbols").entered(); // We call this without attaching because this runs in parallel, so we need to attach here. @@ -224,7 +226,7 @@ impl SymbolIndex { /// The symbol index for a given module. These modules should only be in source roots that /// are inside local_roots. - pub fn module_symbols(db: &dyn HirDatabase, module: Module) -> &SymbolIndex { + pub fn module_symbols(db: &dyn HirDatabase, module: Module) -> &SymbolIndex<'_> { // FIXME: #[salsa::interned] struct InternedModuleId { @@ -232,7 +234,10 @@ impl SymbolIndex { } #[salsa::tracked(returns(ref))] - fn module_symbols(db: &dyn HirDatabase, module: InternedModuleId<'_>) -> SymbolIndex { + fn module_symbols<'db>( + db: &'db dyn HirDatabase, + module: InternedModuleId<'db>, + ) -> SymbolIndex<'db> { let _p = tracing::info_span!("module_symbols").entered(); // We call this without attaching because this runs in parallel, so we need to attach here. @@ -250,29 +255,41 @@ impl SymbolIndex { } } -impl fmt::Debug for SymbolIndex { +impl fmt::Debug for SymbolIndex<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SymbolIndex").field("n_symbols", &self.symbols.len()).finish() } } -impl PartialEq for SymbolIndex { - fn eq(&self, other: &SymbolIndex) -> bool { +impl PartialEq for SymbolIndex<'_> { + fn eq(&self, other: &SymbolIndex<'_>) -> bool { self.symbols == other.symbols } } -impl Eq for SymbolIndex {} +impl Eq for SymbolIndex<'_> {} -impl Hash for SymbolIndex { +impl Hash for SymbolIndex<'_> { fn hash(&self, hasher: &mut H) { self.symbols.hash(hasher) } } -impl SymbolIndex { - fn new(mut symbols: Box<[FileSymbol]>) -> SymbolIndex { - fn cmp(lhs: &FileSymbol, rhs: &FileSymbol) -> Ordering { +unsafe impl Update for SymbolIndex<'_> { + unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool { + let this = unsafe { &mut *old_pointer }; + if *this == new_value { + false + } else { + *this = new_value; + true + } + } +} + +impl<'db> SymbolIndex<'db> { + fn new(mut symbols: Box<[FileSymbol<'db>]>) -> SymbolIndex<'db> { + fn cmp(lhs: &FileSymbol<'_>, rhs: &FileSymbol<'_>) -> Ordering { let lhs_chars = lhs.name.as_str().chars().map(|c| c.to_ascii_lowercase()); let rhs_chars = rhs.name.as_str().chars().map(|c| c.to_ascii_lowercase()); lhs_chars.cmp(rhs_chars) @@ -318,7 +335,7 @@ impl SymbolIndex { } pub fn memory_size(&self) -> usize { - self.map.as_fst().size() + self.symbols.len() * size_of::() + self.map.as_fst().size() + self.symbols.len() * size_of::>() } fn range_to_map_value(start: usize, end: usize) -> u64 { @@ -336,10 +353,10 @@ impl SymbolIndex { } impl Query { - pub(crate) fn search<'sym, T>( + pub(crate) fn search<'db, T>( self, - indices: &'sym [&SymbolIndex], - cb: impl FnMut(&'sym FileSymbol) -> ControlFlow, + indices: &[&'db SymbolIndex<'db>], + cb: impl FnMut(&'db FileSymbol<'db>) -> ControlFlow, ) -> Option { let _p = tracing::info_span!("symbol_index::Query::search").entered(); let mut op = fst::map::OpBuilder::new(); @@ -371,11 +388,11 @@ impl Query { } } - fn search_maps<'sym, T>( + fn search_maps<'db, T>( &self, - indices: &'sym [&SymbolIndex], + indices: &[&'db SymbolIndex<'db>], mut stream: fst::map::Union<'_>, - mut cb: impl FnMut(&'sym FileSymbol) -> ControlFlow, + mut cb: impl FnMut(&'db FileSymbol<'db>) -> ControlFlow, ) -> Option { let ignore_underscore_prefixed = !self.query.starts_with("__"); while let Some((_, indexed_values)) = stream.next() { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt index c8a9231fa99e..5783d97564d0 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_doc_alias.txt @@ -39,6 +39,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "Struct", @@ -73,6 +74,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "mul1", @@ -107,6 +109,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "mul2", @@ -141,6 +144,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "s1", @@ -175,6 +179,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "s1", @@ -209,6 +214,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "s2", @@ -243,6 +249,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, ], ), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt index cc879cf84fc6..953bc73da9d8 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -39,6 +39,7 @@ is_assoc: true, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "Alias", @@ -71,6 +72,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "B", @@ -105,6 +107,7 @@ is_assoc: true, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "CONST", @@ -137,6 +140,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "CONST_WITH_INNER", @@ -169,6 +173,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "Enum", @@ -203,6 +208,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "ItemLikeMacro", @@ -237,6 +243,7 @@ is_assoc: false, is_import: true, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "Macro", @@ -271,6 +278,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "STATIC", @@ -303,6 +311,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "Struct", @@ -337,6 +346,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "StructFromMacro", @@ -371,6 +381,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "StructInFn", @@ -407,6 +418,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "StructInNamedConst", @@ -443,6 +455,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "StructInUnnamedConst", @@ -477,6 +490,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "StructT", @@ -511,6 +525,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "Trait", @@ -543,6 +558,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "Trait", @@ -577,6 +593,7 @@ is_assoc: false, is_import: true, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "Union", @@ -611,6 +628,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "a_mod", @@ -643,6 +661,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "b_mod", @@ -675,6 +694,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "define_struct", @@ -709,6 +729,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "generic_impl_fn", @@ -743,6 +764,7 @@ is_assoc: true, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "impl_fn", @@ -777,6 +799,7 @@ is_assoc: true, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "macro_rules_macro", @@ -811,6 +834,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "main", @@ -843,6 +867,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "really_define_struct", @@ -877,6 +902,7 @@ is_assoc: false, is_import: true, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "trait_fn", @@ -911,6 +937,7 @@ is_assoc: true, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, ], ), @@ -954,6 +981,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, ], ), @@ -995,6 +1023,7 @@ is_assoc: false, is_import: true, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "IsThisJustATrait", @@ -1029,6 +1058,7 @@ is_assoc: false, is_import: true, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "StructInModB", @@ -1063,6 +1093,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "SuperItemLikeMacro", @@ -1097,6 +1128,7 @@ is_assoc: false, is_import: true, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "ThisStruct", @@ -1131,6 +1163,7 @@ is_assoc: false, is_import: true, do_not_complete: Yes, + _marker: PhantomData<&()>, }, ], ), diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt index dc512fe1b87a..6f5f8f889c7d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt @@ -32,5 +32,6 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, ] diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt index 0b2522775d4d..5d3fe4d2658d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt +++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbols_with_imports.txt @@ -32,6 +32,7 @@ is_assoc: false, is_import: false, do_not_complete: Yes, + _marker: PhantomData<&()>, }, FileSymbol { name: "Foo", @@ -66,5 +67,6 @@ is_assoc: false, is_import: true, do_not_complete: Yes, + _marker: PhantomData<&()>, }, ] diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs index 67472507f66e..29530ed02bb6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs +++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs @@ -225,7 +225,7 @@ impl NavigationTarget { } } -impl TryToNav for FileSymbol { +impl<'db> TryToNav for FileSymbol<'db> { fn try_to_nav( &self, sema: &Semantics<'_, RootDatabase>, From 25376c8498494da1ac1e6c707aed3a71fa799347 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sun, 14 Dec 2025 18:51:52 +0800 Subject: [PATCH 0765/3801] Fix invalid logic op for replace_let_with_if_let Example --- ```rust fn main() { $0let x = true && false; } ``` **Before this PR** ```rust fn main() { if let x = true { } } ``` **After this PR** ```rust fn main() { if let x = (true && false) { } } ``` --- .../src/handlers/replace_let_with_if_let.rs | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs index 90f4ff7ad251..b95e9b52b053 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs @@ -60,11 +60,13 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_> } } }; + let init_expr = + if let_expr_needs_paren(&init) { make.expr_paren(init).into() } else { init }; let block = make.block_expr([], None); block.indent(IndentLevel::from_node(let_stmt.syntax())); let if_expr = make.expr_if( - make.expr_let(pat, init).into(), + make.expr_let(pat, init_expr).into(), block, let_stmt .let_else() @@ -79,6 +81,16 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_> ) } +fn let_expr_needs_paren(expr: &ast::Expr) -> bool { + let fake_expr_let = + ast::make::expr_let(ast::make::tuple_pat(None).into(), ast::make::ext::expr_unit()); + let Some(fake_expr) = fake_expr_let.expr() else { + stdx::never!(); + return false; + }; + expr.needs_parens_in_place_of(fake_expr_let.syntax(), fake_expr.syntax()) +} + #[cfg(test)] mod tests { use crate::tests::check_assist; @@ -107,6 +119,42 @@ fn main() { ) } + #[test] + fn replace_let_logic_and() { + check_assist( + replace_let_with_if_let, + r" +fn main() { + $0let x = true && false; +} + ", + r" +fn main() { + if let x = (true && false) { + } +} + ", + ) + } + + #[test] + fn replace_let_logic_or() { + check_assist( + replace_let_with_if_let, + r" +fn main() { + $0let x = true || false; +} + ", + r" +fn main() { + if let x = (true || false) { + } +} + ", + ) + } + #[test] fn replace_let_else() { check_assist( From 4748c5372077eb7ce4fc080769f974a5ea222de9 Mon Sep 17 00:00:00 2001 From: Opstic <46141527+opstic@users.noreply.github.com> Date: Sun, 14 Dec 2025 05:53:13 -0500 Subject: [PATCH 0766/3801] Add `llvm.x86.vcvtps2ph.128` (#1613) * Add `llvm.x86.vcvtps2ph.128` * `cargo fmt` * Test `_mm_cvtps_ph` --- example/std_example.rs | 18 ++++++++++++++++++ src/intrinsics/llvm_x86.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/example/std_example.rs b/example/std_example.rs index c569ef0ef829..33db75f0943a 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -259,6 +259,9 @@ unsafe fn test_simd() { test_mm_cvttps_epi32(); test_mm_cvtsi128_si64(); + #[cfg(not(jit))] + test_mm_cvtps_ph(); + test_mm_extract_epi8(); test_mm_insert_epi16(); test_mm_shuffle_epi8(); @@ -558,6 +561,21 @@ unsafe fn test_mm_cvttps_epi32() { } } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "f16c")] +#[cfg(not(jit))] +unsafe fn test_mm_cvtps_ph() { + const F16_ONE: i16 = 0x3c00; + const F16_TWO: i16 = 0x4000; + const F16_THREE: i16 = 0x4200; + const F16_FOUR: i16 = 0x4400; + + let a = _mm_set_ps(1.0, 2.0, 3.0, 4.0); + let r = _mm_cvtps_ph::<_MM_FROUND_CUR_DIRECTION>(a); + let e = _mm_set_epi16(0, 0, 0, 0, F16_ONE, F16_TWO, F16_THREE, F16_FOUR); + assert_eq_m128i(r, e); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 37fbe4be1b0f..61f48fa97743 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -1313,6 +1313,35 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>( ret.write_cvalue_transmute(fx, res); } + "llvm.x86.vcvtps2ph.128" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtps_ph + intrinsic_args!(fx, args => (a, _imm8); intrinsic); + let a = a.load_scalar(fx); + + let imm8 = + if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[1].node) { + imm8 + } else { + fx.tcx + .dcx() + .span_fatal(span, "Index argument for `_mm_cvtps_ph` is not a constant"); + }; + + let imm8 = imm8.to_u32(); + + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String(format!("vcvtps2ph xmm0, xmm0, {imm8}").into())], + &[CInlineAsmOperand::InOut { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)), + _late: true, + in_value: a, + out_place: Some(ret), + }], + InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, + ); + } + _ => { fx.tcx .dcx() From cab911449aa0921005f48c859dcf4e78888643f9 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Tue, 4 Nov 2025 17:54:46 +0000 Subject: [PATCH 0767/3801] dangling pointer from temp cleanup --- compiler/rustc_lint/messages.ftl | 18 +- compiler/rustc_lint/src/lints.rs | 9 +- .../lint/dangling-pointers-from-locals.stderr | 19 ++ .../allow.rs | 4 +- .../allow.stderr | 28 +-- .../calls.rs | 10 +- .../calls.stderr | 70 +++--- .../cstring-as-ptr.rs | 4 +- .../cstring-as-ptr.stderr | 28 +-- .../example-from-issue123613.rs | 4 +- .../example-from-issue123613.stderr | 28 +-- .../dangling-pointers-from-temporaries/ext.rs | 4 +- .../ext.stderr | 28 +-- .../methods.rs | 4 +- .../methods.stderr | 28 +-- .../temporaries.rs | 16 +- .../temporaries.stderr | 112 ++++----- .../types.rs | 34 +-- .../types.stderr | 238 +++++++++--------- 19 files changed, 354 insertions(+), 332 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 8aa90c070acd..ad9e5b0fbd94 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -197,15 +197,17 @@ lint_dangling_pointers_from_locals = {$fn_kind} returns a dangling pointer to dr .ret_ty = return type is `{$ret_ty}` .local_var = local variable `{$local_var_name}` is dropped at the end of the {$fn_kind} .created_at = dangling pointer created here - .note = a dangling pointer is safe, but dereferencing one is undefined behavior + .note_safe = a dangling pointer is safe, but dereferencing one is undefined behavior + .note_more_info = for more information, see + +lint_dangling_pointers_from_temporaries = this creates a dangling pointer because temporary `{$ty}` is dropped at end of statement + .label_ptr = pointer created here + .label_temporary = this `{$ty}` is dropped at end of statement + .help_bind = bind the `{$ty}` to a variable such that it outlives the pointer returned by `{$callee}` + .note_safe = a dangling pointer is safe, but dereferencing one is undefined behavior + .note_return = returning a pointer to a local variable will always result in a dangling pointer + .note_more_info = for more information, see -lint_dangling_pointers_from_temporaries = a dangling pointer will be produced because the temporary `{$ty}` will be dropped - .label_ptr = this pointer will immediately be invalid - .label_temporary = this `{$ty}` is deallocated at the end of the statement, bind it to a variable to extend its lifetime - .note = pointers do not have a lifetime; when calling `{$callee}` the `{$ty}` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - .help_bind = you must make sure that the variable you bind the `{$ty}` to lives at least as long as the pointer returned by the call to `{$callee}` - .help_returned = in particular, if this pointer is returned from the current function, binding the `{$ty}` inside the function will not suffice - .help_visit = for more information, see lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance .note = a `use rustc_data_structures::fx::{$preferred}` may be necessary diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c55f2b9dd6f2..54eea5b41a16 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1106,10 +1106,10 @@ pub(crate) struct IgnoredUnlessCrateSpecified<'a> { // dangling.rs #[derive(LintDiagnostic)] #[diag(lint_dangling_pointers_from_temporaries)] -#[note] #[help(lint_help_bind)] -#[help(lint_help_returned)] -#[help(lint_help_visit)] +#[note(lint_note_safe)] +#[note(lint_note_return)] +#[note(lint_note_more_info)] // FIXME: put #[primary_span] on `ptr_span` once it does not cause conflicts pub(crate) struct DanglingPointersFromTemporaries<'tcx> { pub callee: Ident, @@ -1122,7 +1122,8 @@ pub(crate) struct DanglingPointersFromTemporaries<'tcx> { #[derive(LintDiagnostic)] #[diag(lint_dangling_pointers_from_locals)] -#[note] +#[note(lint_note_safe)] +#[note(lint_note_more_info)] pub(crate) struct DanglingPointersFromLocals<'tcx> { pub ret_ty: Ty<'tcx>, #[label(lint_ret_ty)] diff --git a/tests/ui/lint/dangling-pointers-from-locals.stderr b/tests/ui/lint/dangling-pointers-from-locals.stderr index 45acc74ac34e..05ced1cdc004 100644 --- a/tests/ui/lint/dangling-pointers-from-locals.stderr +++ b/tests/ui/lint/dangling-pointers-from-locals.stderr @@ -9,6 +9,7 @@ LL | &x | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see = note: `#[warn(dangling_pointers_from_locals)]` on by default warning: function returns a dangling pointer to dropped local variable `x` @@ -24,6 +25,7 @@ LL | x | ^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:24:12 @@ -38,6 +40,7 @@ LL | return y; | ^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:30:5 @@ -52,6 +55,7 @@ LL | &x as *const u8 | dangling pointer created here | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:37:5 @@ -66,6 +70,7 @@ LL | x as *const u8 | ^^^^^^^^^^^^^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:43:12 @@ -80,6 +85,7 @@ LL | return &mut x as *mut u8 as *const u8 as *mut u8; | dangling pointer created here | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:49:5 @@ -92,6 +98,7 @@ LL | &{ x } | ^^^^^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:57:13 @@ -108,6 +115,7 @@ LL | | } | |_____________^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:67:12 @@ -120,6 +128,7 @@ LL | return &x; | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:73:12 @@ -132,6 +141,7 @@ LL | return &mut x; | ^^^^^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:80:16 @@ -145,6 +155,7 @@ LL | return &x; | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:88:5 @@ -157,6 +168,7 @@ LL | &x | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:94:12 @@ -169,6 +181,7 @@ LL | return &x; | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: closure returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:101:16 @@ -181,6 +194,7 @@ LL | return &x; | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:113:5 @@ -194,6 +208,7 @@ LL | &x | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:118:5 @@ -206,6 +221,7 @@ LL | &a | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:123:5 @@ -218,6 +234,7 @@ LL | &a | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:128:5 @@ -230,6 +247,7 @@ LL | &a | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:133:5 @@ -242,6 +260,7 @@ LL | &a | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: 19 warnings emitted diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs b/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs index d892ebdf6069..7ecee90479d2 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs @@ -7,7 +7,7 @@ fn main() { #[deny(dangling_pointers_from_temporaries)] { dbg!(String::new().as_ptr()); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer } S.foo() } @@ -18,6 +18,6 @@ impl S { #[warn(dangling_pointers_from_temporaries)] fn foo(self) { dbg!(String::new().as_ptr()); - //~^ WARNING a dangling pointer will be produced because the temporary `String` will be dropped + //~^ WARNING dangling pointer } } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/allow.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/allow.stderr index e1c12cfd1a50..a235af144e48 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/allow.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/allow.stderr @@ -1,33 +1,33 @@ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/allow.rs:9:28 | LL | dbg!(String::new().as_ptr()); - | ------------- ^^^^^^ this pointer will immediately be invalid + | ------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/allow.rs:7:12 | LL | #[deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: a dangling pointer will be produced because the temporary `String` will be dropped +warning: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/allow.rs:20:28 | LL | dbg!(String::new().as_ptr()); - | ------------- ^^^^^^ this pointer will immediately be invalid + | ------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/allow.rs:18:12 | diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/calls.rs b/tests/ui/lint/dangling-pointers-from-temporaries/calls.rs index b376582a8867..80787390176f 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/calls.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/calls.rs @@ -25,12 +25,12 @@ fn ok() { fn not_ok() { { let ptr = cstring().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer consume(ptr); } consume({ let ptr = cstring().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer ptr }); consume({ @@ -39,11 +39,11 @@ fn not_ok() { //^ FIXME: should error }); let _ptr: *const u8 = cstring().as_ptr().cast(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer let _ptr: *const u8 = { cstring() }.as_ptr().cast(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer let _ptr: *const u8 = { cstring().as_ptr() }.cast(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer } fn main() { diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/calls.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/calls.stderr index 41c6cdd0e3ef..4e302dcc9942 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/calls.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/calls.stderr @@ -1,72 +1,72 @@ -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:27:29 | LL | let ptr = cstring().as_ptr(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/calls.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:32:29 | LL | let ptr = cstring().as_ptr(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:41:37 | LL | let _ptr: *const u8 = cstring().as_ptr().cast(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:43:41 | LL | let _ptr: *const u8 = { cstring() }.as_ptr().cast(); - | ------------- ^^^^^^ this pointer will immediately be invalid + | ------------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:45:39 | LL | let _ptr: *const u8 = { cstring().as_ptr() }.cast(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 5 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs index a98378794abc..7036019362cd 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs @@ -7,12 +7,12 @@ use std::ffi::CString; macro_rules! mymacro { () => { let s = CString::new("some text").unwrap().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer } } fn main() { let s = CString::new("some text").unwrap().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer mymacro!(); } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr index d4126ba231f7..be9f8b19545b 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr @@ -6,39 +6,39 @@ LL | #![deny(temporary_cstring_as_ptr)] | = note: `#[warn(renamed_and_removed_lints)]` on by default -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/cstring-as-ptr.rs:15:48 | LL | let s = CString::new("some text").unwrap().as_ptr(); - | ---------------------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------------------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/cstring-as-ptr.rs:2:9 | LL | #![deny(temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/cstring-as-ptr.rs:9:52 | LL | let s = CString::new("some text").unwrap().as_ptr(); - | ---------------------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------------------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement ... LL | mymacro!(); | ---------- in this macro invocation | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see = note: this error originates in the macro `mymacro` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs index 0fb07a3f3bc9..771ddb349344 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs @@ -3,9 +3,9 @@ const MAX_PATH: usize = 260; fn main() { let str1 = String::with_capacity(MAX_PATH).as_mut_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer let str2 = String::from("TotototototototototototototototototoT").as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer unsafe { std::ptr::copy_nonoverlapping(str2, str1, 30); println!("{:?}", String::from_raw_parts(str1, 30, 30)); diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr index aace55e92cf1..b8baa2bf5601 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr @@ -1,33 +1,33 @@ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/example-from-issue123613.rs:5:48 | LL | let str1 = String::with_capacity(MAX_PATH).as_mut_ptr(); - | ------------------------------- ^^^^^^^^^^ this pointer will immediately be invalid + | ------------------------------- ^^^^^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_mut_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_mut_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_mut_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/example-from-issue123613.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/example-from-issue123613.rs:7:70 | LL | let str2 = String::from("TotototototototototototototototototoT").as_ptr(); - | ----------------------------------------------------- ^^^^^^ this pointer will immediately be invalid + | ----------------------------------------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 2 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/ext.rs b/tests/ui/lint/dangling-pointers-from-temporaries/ext.rs index a5e84d36090f..e56bc0f433e4 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/ext.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/ext.rs @@ -26,7 +26,7 @@ impl Ext2 for *const u32 { fn main() { let _ptr1 = Vec::::new().as_ptr().dbg(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer let _ptr2 = vec![0].as_ptr().foo(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/ext.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/ext.stderr index 976334ddef9c..f780f88134f2 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/ext.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/ext.stderr @@ -1,33 +1,33 @@ -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/ext.rs:28:35 | LL | let _ptr1 = Vec::::new().as_ptr().dbg(); - | ----------------- ^^^^^^ this pointer will immediately be invalid + | ----------------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/ext.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/ext.rs:30:25 | LL | let _ptr2 = vec![0].as_ptr().foo(); - | ------- ^^^^^^ this pointer will immediately be invalid + | ------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 2 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs b/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs index 26019b376d3a..10666e0a8282 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs @@ -2,7 +2,7 @@ fn main() { vec![0u8].as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer vec![0u8].as_mut_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr index a86a69bc39a2..367dfae9e65d 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr @@ -1,33 +1,33 @@ -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/methods.rs:4:15 | LL | vec![0u8].as_ptr(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/methods.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/methods.rs:6:15 | LL | vec![0u8].as_mut_ptr(); - | --------- ^^^^^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_mut_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_mut_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_mut_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 2 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs index 1f216586ae81..1f816996d514 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs @@ -19,18 +19,18 @@ fn main() { // Call string().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer // MethodCall "hello".to_string().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer // Tup // impossible // Binary (string() + "hello").as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer // Path { @@ -66,7 +66,7 @@ fn main() { // If { (if true { String::new() } else { "hello".into() }).as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer } // Loop @@ -75,7 +75,7 @@ fn main() { break String::new(); }) .as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer } // Match @@ -84,7 +84,7 @@ fn main() { s => s, } .as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer } // Closure @@ -92,7 +92,7 @@ fn main() { // Block { string() }.as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer // Assign, AssignOp // impossible @@ -132,5 +132,5 @@ fn main() { // Macro vec![0u8].as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr index e8994703cabf..be001acad747 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr @@ -1,115 +1,115 @@ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:21:14 | LL | string().as_ptr(); - | -------- ^^^^^^ this pointer will immediately be invalid + | -------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/temporaries.rs:2:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:25:25 | LL | "hello".to_string().as_ptr(); - | ------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:32:26 | LL | (string() + "hello").as_ptr(); - | -------------------- ^^^^^^ this pointer will immediately be invalid + | -------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:68:61 | LL | (if true { String::new() } else { "hello".into() }).as_ptr(); - | --------------------------------------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------------------------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:77:10 | LL | / (loop { LL | | break String::new(); LL | | }) - | |__________- this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | |__________- this `String` is dropped at end of statement LL | .as_ptr(); - | ^^^^^^ this pointer will immediately be invalid + | ^^^^^^ pointer created here | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:86:10 | LL | / match string() { LL | | s => s, LL | | } - | |_________- this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | |_________- this `String` is dropped at end of statement LL | .as_ptr(); - | ^^^^^^ this pointer will immediately be invalid + | ^^^^^^ pointer created here | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:94:18 | LL | { string() }.as_ptr(); - | ------------ ^^^^^^ this pointer will immediately be invalid + | ------------ ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/temporaries.rs:134:15 | LL | vec![0u8].as_ptr(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 8 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/types.rs b/tests/ui/lint/dangling-pointers-from-temporaries/types.rs index 17c3eca89e27..072ec25f4d83 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/types.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/types.rs @@ -19,39 +19,39 @@ fn declval() -> T { fn main() { declval::().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer because temporary `CString` declval::().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer because temporary `String` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer because temporary `Vec` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box` will be dropped + //~^ ERROR dangling pointer because temporary `Box` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box<[u8]>` will be dropped + //~^ ERROR dangling pointer because temporary `Box<[u8]>` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box` will be dropped + //~^ ERROR dangling pointer because temporary `Box` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box` will be dropped + //~^ ERROR dangling pointer because temporary `Box` declval::<[u8; 10]>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `[u8; 10]` will be dropped + //~^ ERROR dangling pointer because temporary `[u8; 10]` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box<[u8; 10]>` will be dropped + //~^ ERROR dangling pointer because temporary `Box<[u8; 10]>` declval::>>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box>` will be dropped + //~^ ERROR dangling pointer because temporary `Box>` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box` will be dropped + //~^ ERROR dangling pointer because temporary `Box` declval::>>>>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box>>>` will be dropped + //~^ ERROR dangling pointer because temporary `Box>>>` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Cell` will be dropped + //~^ ERROR dangling pointer because temporary `Cell` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `MaybeUninit` will be dropped + //~^ ERROR dangling pointer because temporary `MaybeUninit` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer because temporary `Vec` declval::>().get(); - //~^ ERROR a dangling pointer will be produced because the temporary `UnsafeCell` will be dropped + //~^ ERROR dangling pointer because temporary `UnsafeCell` declval::>().get(); - //~^ ERROR a dangling pointer will be produced because the temporary `SyncUnsafeCell` will be dropped + //~^ ERROR dangling pointer because temporary `SyncUnsafeCell` declval::>().as_ptr(); declval::().as_ptr(); } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr index fab2459b53f6..bb37c8ad211b 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr @@ -1,228 +1,228 @@ -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/types.rs:21:26 | LL | declval::().as_ptr(); - | -------------------- ^^^^^^ this pointer will immediately be invalid + | -------------------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/types.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/types.rs:23:25 | LL | declval::().as_ptr(); - | ------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/types.rs:25:26 | LL | declval::>().as_ptr(); - | -------------------- ^^^^^^ this pointer will immediately be invalid + | -------------------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box` will be dropped +error: this creates a dangling pointer because temporary `Box` is dropped at end of statement --> $DIR/types.rs:27:31 | LL | declval::>().as_ptr(); - | ------------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------------- ^^^^^^ pointer created here | | - | this `Box` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box` inside the function will not suffice - = help: for more information, see + = help: bind the `Box` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box<[u8]>` will be dropped +error: this creates a dangling pointer because temporary `Box<[u8]>` is dropped at end of statement --> $DIR/types.rs:29:28 | LL | declval::>().as_ptr(); - | ---------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------- ^^^^^^ pointer created here | | - | this `Box<[u8]>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box<[u8]>` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<[u8]>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box<[u8]>` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box<[u8]>` inside the function will not suffice - = help: for more information, see + = help: bind the `Box<[u8]>` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box` will be dropped +error: this creates a dangling pointer because temporary `Box` is dropped at end of statement --> $DIR/types.rs:31:27 | LL | declval::>().as_ptr(); - | --------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------- ^^^^^^ pointer created here | | - | this `Box` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box` inside the function will not suffice - = help: for more information, see + = help: bind the `Box` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box` will be dropped +error: this creates a dangling pointer because temporary `Box` is dropped at end of statement --> $DIR/types.rs:33:28 | LL | declval::>().as_ptr(); - | ---------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------- ^^^^^^ pointer created here | | - | this `Box` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box` inside the function will not suffice - = help: for more information, see + = help: bind the `Box` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `[u8; 10]` will be dropped +error: this creates a dangling pointer because temporary `[u8; 10]` is dropped at end of statement --> $DIR/types.rs:35:27 | LL | declval::<[u8; 10]>().as_ptr(); - | --------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------- ^^^^^^ pointer created here | | - | this `[u8; 10]` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `[u8; 10]` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `[u8; 10]` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `[u8; 10]` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `[u8; 10]` inside the function will not suffice - = help: for more information, see + = help: bind the `[u8; 10]` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box<[u8; 10]>` will be dropped +error: this creates a dangling pointer because temporary `Box<[u8; 10]>` is dropped at end of statement --> $DIR/types.rs:37:32 | LL | declval::>().as_ptr(); - | -------------------------- ^^^^^^ this pointer will immediately be invalid + | -------------------------- ^^^^^^ pointer created here | | - | this `Box<[u8; 10]>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box<[u8; 10]>` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<[u8; 10]>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box<[u8; 10]>` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box<[u8; 10]>` inside the function will not suffice - = help: for more information, see + = help: bind the `Box<[u8; 10]>` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box>` will be dropped +error: this creates a dangling pointer because temporary `Box>` is dropped at end of statement --> $DIR/types.rs:39:31 | LL | declval::>>().as_ptr(); - | ------------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------------- ^^^^^^ pointer created here | | - | this `Box>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box>` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box>` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box>` inside the function will not suffice - = help: for more information, see + = help: bind the `Box>` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box` will be dropped +error: this creates a dangling pointer because temporary `Box` is dropped at end of statement --> $DIR/types.rs:41:30 | LL | declval::>().as_ptr(); - | ------------------------ ^^^^^^ this pointer will immediately be invalid + | ------------------------ ^^^^^^ pointer created here | | - | this `Box` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box` inside the function will not suffice - = help: for more information, see + = help: bind the `Box` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box>>>` will be dropped +error: this creates a dangling pointer because temporary `Box>>>` is dropped at end of statement --> $DIR/types.rs:43:43 | LL | declval::>>>>().as_ptr(); - | ------------------------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------------------------- ^^^^^^ pointer created here | | - | this `Box>>>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box>>>` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box>>>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box>>>` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box>>>` inside the function will not suffice - = help: for more information, see + = help: bind the `Box>>>` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Cell` will be dropped +error: this creates a dangling pointer because temporary `Cell` is dropped at end of statement --> $DIR/types.rs:45:27 | LL | declval::>().as_ptr(); - | --------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------- ^^^^^^ pointer created here | | - | this `Cell` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Cell` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Cell` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Cell` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Cell` inside the function will not suffice - = help: for more information, see + = help: bind the `Cell` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `MaybeUninit` will be dropped +error: this creates a dangling pointer because temporary `MaybeUninit` is dropped at end of statement --> $DIR/types.rs:47:34 | LL | declval::>().as_ptr(); - | ---------------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------------- ^^^^^^ pointer created here | | - | this `MaybeUninit` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `MaybeUninit` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `MaybeUninit` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `MaybeUninit` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `MaybeUninit` inside the function will not suffice - = help: for more information, see + = help: bind the `MaybeUninit` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/types.rs:49:33 | LL | declval::>().as_ptr(); - | --------------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `UnsafeCell` will be dropped +error: this creates a dangling pointer because temporary `UnsafeCell` is dropped at end of statement --> $DIR/types.rs:51:33 | LL | declval::>().get(); - | --------------------------- ^^^ this pointer will immediately be invalid + | --------------------------- ^^^ pointer created here | | - | this `UnsafeCell` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `UnsafeCell` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `get` the `UnsafeCell` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `UnsafeCell` to lives at least as long as the pointer returned by the call to `get` - = help: in particular, if this pointer is returned from the current function, binding the `UnsafeCell` inside the function will not suffice - = help: for more information, see + = help: bind the `UnsafeCell` to a variable such that it outlives the pointer returned by `get` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `SyncUnsafeCell` will be dropped +error: this creates a dangling pointer because temporary `SyncUnsafeCell` is dropped at end of statement --> $DIR/types.rs:53:37 | LL | declval::>().get(); - | ------------------------------- ^^^ this pointer will immediately be invalid + | ------------------------------- ^^^ pointer created here | | - | this `SyncUnsafeCell` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `SyncUnsafeCell` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `get` the `SyncUnsafeCell` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `SyncUnsafeCell` to lives at least as long as the pointer returned by the call to `get` - = help: in particular, if this pointer is returned from the current function, binding the `SyncUnsafeCell` inside the function will not suffice - = help: for more information, see + = help: bind the `SyncUnsafeCell` to a variable such that it outlives the pointer returned by `get` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 17 previous errors From 5e42f8b22f452fd23f60aab137bcd1af5f4f9a57 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 14 Dec 2025 23:16:05 +1100 Subject: [PATCH 0768/3801] Move ambient cdb discovery from compiletest to bootstrap --- src/bootstrap/src/core/build_steps/test.rs | 4 ++ src/bootstrap/src/core/debuggers/cdb.rs | 41 +++++++++++++++++++ src/bootstrap/src/core/debuggers/mod.rs | 2 + src/tools/compiletest/src/debuggers.rs | 47 +--------------------- src/tools/compiletest/src/lib.rs | 2 +- 5 files changed, 49 insertions(+), 47 deletions(-) create mode 100644 src/bootstrap/src/core/debuggers/cdb.rs diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 9f8bb4dea54f..67214d832444 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2181,6 +2181,10 @@ Please disable assertions with `rust.debug-assertions = false`. } if mode == CompiletestMode::Debuginfo { + if let Some(debuggers::Cdb { cdb }) = debuggers::discover_cdb(target) { + cmd.arg("--cdb").arg(cdb); + } + if let Some(debuggers::Gdb { gdb }) = debuggers::discover_gdb(builder, android.as_ref()) { cmd.arg("--gdb").arg(gdb.as_ref()); diff --git a/src/bootstrap/src/core/debuggers/cdb.rs b/src/bootstrap/src/core/debuggers/cdb.rs new file mode 100644 index 000000000000..a19b70477ecf --- /dev/null +++ b/src/bootstrap/src/core/debuggers/cdb.rs @@ -0,0 +1,41 @@ +use std::env; +use std::path::PathBuf; + +use crate::core::config::TargetSelection; + +pub(crate) struct Cdb { + pub(crate) cdb: PathBuf, +} + +/// FIXME: This CDB discovery code was very questionable when it was in +/// compiletest, and it's just as questionable now that it's in bootstrap. +pub(crate) fn discover_cdb(target: TargetSelection) -> Option { + if !cfg!(windows) || !target.ends_with("-pc-windows-msvc") { + return None; + } + + let pf86 = + PathBuf::from(env::var_os("ProgramFiles(x86)").or_else(|| env::var_os("ProgramFiles"))?); + let cdb_arch = if cfg!(target_arch = "x86") { + "x86" + } else if cfg!(target_arch = "x86_64") { + "x64" + } else if cfg!(target_arch = "aarch64") { + "arm64" + } else if cfg!(target_arch = "arm") { + "arm" + } else { + return None; // No compatible CDB.exe in the Windows 10 SDK + }; + + let mut path = pf86; + path.push(r"Windows Kits\10\Debuggers"); // We could check 8.1 etc. too? + path.push(cdb_arch); + path.push(r"cdb.exe"); + + if !path.exists() { + return None; + } + + Some(Cdb { cdb: path }) +} diff --git a/src/bootstrap/src/core/debuggers/mod.rs b/src/bootstrap/src/core/debuggers/mod.rs index a11eda8e686e..65d76e114189 100644 --- a/src/bootstrap/src/core/debuggers/mod.rs +++ b/src/bootstrap/src/core/debuggers/mod.rs @@ -1,8 +1,10 @@ //! Code for discovering debuggers and debugger-related configuration, so that //! it can be passed to compiletest when running debuginfo tests. +pub(crate) use self::cdb::{Cdb, discover_cdb}; pub(crate) use self::gdb::{Gdb, discover_gdb}; pub(crate) use self::lldb::{Lldb, discover_lldb}; +mod cdb; mod gdb; mod lldb; diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs index b0d0372454e2..4a1a74ddfe1b 100644 --- a/src/tools/compiletest/src/debuggers.rs +++ b/src/tools/compiletest/src/debuggers.rs @@ -2,7 +2,7 @@ use std::env; use std::process::Command; use std::sync::Arc; -use camino::{Utf8Path, Utf8PathBuf}; +use camino::Utf8Path; use crate::common::{Config, Debugger}; @@ -54,51 +54,6 @@ pub(crate) fn configure_lldb(config: &Config) -> Option> { Some(Arc::new(Config { debugger: Some(Debugger::Lldb), ..config.clone() })) } -/// Returns `true` if the given target is a MSVC target for the purposes of CDB testing. -fn is_pc_windows_msvc_target(target: &str) -> bool { - target.ends_with("-pc-windows-msvc") -} - -/// FIXME: this is very questionable... -fn find_cdb(target: &str) -> Option { - if !(cfg!(windows) && is_pc_windows_msvc_target(target)) { - return None; - } - - let pf86 = Utf8PathBuf::from_path_buf( - env::var_os("ProgramFiles(x86)").or_else(|| env::var_os("ProgramFiles"))?.into(), - ) - .unwrap(); - let cdb_arch = if cfg!(target_arch = "x86") { - "x86" - } else if cfg!(target_arch = "x86_64") { - "x64" - } else if cfg!(target_arch = "aarch64") { - "arm64" - } else if cfg!(target_arch = "arm") { - "arm" - } else { - return None; // No compatible CDB.exe in the Windows 10 SDK - }; - - let mut path = pf86; - path.push(r"Windows Kits\10\Debuggers"); // We could check 8.1 etc. too? - path.push(cdb_arch); - path.push(r"cdb.exe"); - - if !path.exists() { - return None; - } - - Some(path) -} - -/// Returns Path to CDB -pub(crate) fn discover_cdb(cdb: Option, target: &str) -> Option { - let cdb = cdb.map(Utf8PathBuf::from).or_else(|| find_cdb(target)); - cdb -} - pub(crate) fn query_cdb_version(cdb: &Utf8Path) -> Option<[u16; 4]> { let mut version = None; if let Ok(output) = Command::new(cdb).arg("/version").output() { diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 71dad3633793..90b1c10308a2 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -263,7 +263,7 @@ fn parse_config(args: Vec) -> Config { let adb_device_status = target.contains("android") && adb_test_dir.is_some(); // FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config! - let cdb = debuggers::discover_cdb(matches.opt_str("cdb"), &target); + let cdb = matches.opt_str("cdb").map(Utf8PathBuf::from); let cdb_version = cdb.as_deref().and_then(debuggers::query_cdb_version); // FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config! let gdb = matches.opt_str("gdb").map(Utf8PathBuf::from); From 69ba7c5bd3208a1d1b026d8773bbfee8256a8e51 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sun, 14 Dec 2025 14:32:27 +0200 Subject: [PATCH 0769/3801] about-this-guide.md: make more clear My first thought seeing the sentence part of the list was that there was a missing hyperlink --- src/doc/rustc-dev-guide/src/about-this-guide.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md index 4f5733ae0821..bf5cfe67fbc0 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -64,10 +64,12 @@ please see the corresponding [subsection on writing documentation in this guide] ## Other places to find information +This guide, the one you are currently reading, +contains information about how various parts of the compiler work, +and how to contribute to the compiler. + You might also find the following sites useful: -- This guide contains information about how various parts of the - compiler work and how to contribute to the compiler. - [rustc API docs] -- rustdoc documentation for the compiler, devtools, and internal tools - [Forge] -- contains documentation about Rust infrastructure, team procedures, and more - [compiler-team] -- the home-base for the Rust compiler team, with description From efaa0c067f681e42c39f4594042bafd8d02e3e7a Mon Sep 17 00:00:00 2001 From: Flakebi Date: Sat, 13 Dec 2025 19:16:32 +0100 Subject: [PATCH 0770/3801] Improve amdgpu docs: Mention device-libs and xnack Mention amdgpu-device-libs for allocator and println support and mention the necessary target flag for GPUs from some some series without xnack support. For the last half year, there were no major changes in the amdgpu-device-libs crate (in fact, there was no need to update the crate), so I believe it is stable enough to mention it here. The xnack-support flag is something I stumbled upon recently, when more complex printlns failed on a certain GPU. --- .../rustc/src/platform-support/amdgcn-amd-amdhsa.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md index 16152dd2dad5..dbdb96283a5f 100644 --- a/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md +++ b/src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md @@ -20,8 +20,8 @@ The format of binaries is a linked ELF. Binaries must be built with no-std. They can use `core` and `alloc` (`alloc` only if an allocator is supplied). -At least one function needs to use the `"gpu-kernel"` calling convention and should be marked with `no_mangle` for simplicity. -Functions using the `"gpu-kernel"` calling convention are kernel entrypoints and can be used from the host runtime. +At least one function should use the `"gpu-kernel"` calling convention and should be marked with `no_mangle` or `export_name`. +Functions using the `"gpu-kernel"` calling convention are kernel entrypoints and can be launched from the host runtime. ## Building the target @@ -34,6 +34,9 @@ The generations are exposed as different target-cpus in the backend. As there are many, Rust does not ship pre-compiled libraries for this target. Therefore, you have to build your own copy of `core` by using `cargo -Zbuild-std=core` or similar. +An allocator and `println!()` support is provided by the [`amdgpu-device-libs`] crate. +Both features rely on the [HIP] runtime. + To build a binary, create a no-std library: ```rust,ignore (platform-specific) // src/lib.rs @@ -65,6 +68,8 @@ lto = true The target-cpu must be from the list [supported by LLVM] (or printed with `rustc --target amdgcn-amd-amdhsa --print target-cpus`). The GPU version on the current system can be found e.g. with [`rocminfo`]. +For a GPU series that has xnack support but the target GPU has not, the `-xnack-support` target-feature needs to be enabled. +I.e. if the ISA info as printed with [`rocminfo`] says something about `xnack-`, e.g. `gfx1010:xnack-`, add `-Ctarget-feature=-xnack-support` to the rustflags. Example `.cargo/config.toml` file to set the target and GPU generation: ```toml @@ -72,6 +77,7 @@ Example `.cargo/config.toml` file to set the target and GPU generation: [build] target = "amdgcn-amd-amdhsa" rustflags = ["-Ctarget-cpu=gfx1100"] +# Add "-Ctarget-feature=-xnack-support" for xnack- GPUs (see above) [unstable] build-std = ["core"] # Optional: "alloc" @@ -85,8 +91,6 @@ Example code on how to load a compiled binary and run it is available in [ROCm e On Linux, binaries can also run through the HSA runtime as implemented in [ROCR-Runtime]. - - $DIR/const-item-interior-mutations-const-cell.rs:16:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:15:13 | LL | let _ = LazyCell::force(&A); | ^^^^^^^^^^^^^^^^^-^ @@ -17,7 +17,7 @@ LL + static A: LazyCell = LazyCell::new(|| 0); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const-cell.rs:23:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:22:13 | LL | let _ = A.set(10); | -^^^^^^^^ @@ -34,7 +34,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `try_insert` - --> $DIR/const-item-interior-mutations-const-cell.rs:26:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:25:13 | LL | let _ = A.try_insert(20); | -^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_init` - --> $DIR/const-item-interior-mutations-const-cell.rs:29:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:28:13 | LL | let _ = A.get_or_init(|| 30); | -^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_try_init` - --> $DIR/const-item-interior-mutations-const-cell.rs:32:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:31:13 | LL | let _ = A.get_or_try_init(|| Ok::<_, ()>(40)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const-cell.rs:39:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:38:13 | LL | let _ = A.set(1); | -^^^^^^^ @@ -102,7 +102,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `swap` - --> $DIR/const-item-interior-mutations-const-cell.rs:42:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:41:13 | LL | let _ = A.swap(&A); | -^^^^^^^^^ @@ -119,7 +119,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const-cell.rs:45:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:44:13 | LL | let _ = A.replace(2); | -^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-cell.rs:48:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:47:13 | LL | let _ = A.get(); | -^^^^^^ @@ -153,7 +153,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `update` - --> $DIR/const-item-interior-mutations-const-cell.rs:51:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:50:13 | LL | let _ = A.update(|x| x + 1); | -^^^^^^^^^^^^^^^^^^ @@ -170,7 +170,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const-cell.rs:58:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:57:13 | LL | let _ = A.replace(1); | -^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace_with` - --> $DIR/const-item-interior-mutations-const-cell.rs:61:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:60:13 | LL | let _ = A.replace_with(|x| *x + 2); | -^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `swap` - --> $DIR/const-item-interior-mutations-const-cell.rs:64:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:63:13 | LL | let _ = A.swap(&A); | -^^^^^^^^^ @@ -221,7 +221,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `borrow` - --> $DIR/const-item-interior-mutations-const-cell.rs:67:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:66:13 | LL | let _ = A.borrow(); | -^^^^^^^^^ @@ -238,7 +238,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `try_borrow` - --> $DIR/const-item-interior-mutations-const-cell.rs:70:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:69:13 | LL | let _ = A.try_borrow(); | -^^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `borrow_mut` - --> $DIR/const-item-interior-mutations-const-cell.rs:73:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:72:13 | LL | let _ = A.borrow_mut(); | -^^^^^^^^^^^^^ @@ -272,7 +272,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `try_borrow_mut` - --> $DIR/const-item-interior-mutations-const-cell.rs:76:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:75:13 | LL | let _ = A.try_borrow_mut(); | -^^^^^^^^^^^^^^^^^ @@ -289,7 +289,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const-cell.rs:83:22 + --> $DIR/const-item-interior-mutations-const-cell.rs:82:22 | LL | let _ = unsafe { A.replace(1) }; | -^^^^^^^^^^^ @@ -306,7 +306,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-cell.rs:86:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:85:13 | LL | let _ = A.get(); | -^^^^^^ @@ -323,7 +323,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `as_ref_unchecked` - --> $DIR/const-item-interior-mutations-const-cell.rs:90:17 + --> $DIR/const-item-interior-mutations-const-cell.rs:89:17 | LL | let _ = A.as_ref_unchecked(); | -^^^^^^^^^^^^^^^^^^^ @@ -340,7 +340,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `as_mut_unchecked` - --> $DIR/const-item-interior-mutations-const-cell.rs:93:17 + --> $DIR/const-item-interior-mutations-const-cell.rs:92:17 | LL | let _ = A.as_mut_unchecked(); | -^^^^^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-cell.rs:101:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:100:13 | LL | let _ = A.get(); | -^^^^^^ diff --git a/tests/ui/lint/const-item-interior-mutations-const.fixed b/tests/ui/lint/const-item-interior-mutations-const.fixed index 82f3fdac43a3..97091ab10af8 100644 --- a/tests/ui/lint/const-item-interior-mutations-const.fixed +++ b/tests/ui/lint/const-item-interior-mutations-const.fixed @@ -6,7 +6,6 @@ #![feature(lock_value_accessors)] #![feature(once_cell_try_insert)] #![feature(once_cell_try)] -#![feature(lazy_get)] use std::sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock}; use std::time::Duration; diff --git a/tests/ui/lint/const-item-interior-mutations-const.rs b/tests/ui/lint/const-item-interior-mutations-const.rs index 5dbbfd8ca32f..40565118ca79 100644 --- a/tests/ui/lint/const-item-interior-mutations-const.rs +++ b/tests/ui/lint/const-item-interior-mutations-const.rs @@ -6,7 +6,6 @@ #![feature(lock_value_accessors)] #![feature(once_cell_try_insert)] #![feature(once_cell_try)] -#![feature(lazy_get)] use std::sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock}; use std::time::Duration; diff --git a/tests/ui/lint/const-item-interior-mutations-const.stderr b/tests/ui/lint/const-item-interior-mutations-const.stderr index 7d3e7bee7fbb..2fe8f190dbed 100644 --- a/tests/ui/lint/const-item-interior-mutations-const.stderr +++ b/tests/ui/lint/const-item-interior-mutations-const.stderr @@ -1,5 +1,5 @@ warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const.rs:17:14 + --> $DIR/const-item-interior-mutations-const.rs:16:14 | LL | let _a = A.set(1); | -^^^^^^^ @@ -17,7 +17,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const.rs:20:14 + --> $DIR/const-item-interior-mutations-const.rs:19:14 | LL | let _a = A.replace(2); | -^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `lock` - --> $DIR/const-item-interior-mutations-const.rs:23:10 + --> $DIR/const-item-interior-mutations-const.rs:22:10 | LL | drop(A.lock()); | -^^^^^^^ @@ -51,7 +51,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `try_lock` - --> $DIR/const-item-interior-mutations-const.rs:26:10 + --> $DIR/const-item-interior-mutations-const.rs:25:10 | LL | drop(A.try_lock()); | -^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `clear_poison` - --> $DIR/const-item-interior-mutations-const.rs:29:14 + --> $DIR/const-item-interior-mutations-const.rs:28:14 | LL | let _a = A.clear_poison(); | -^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `call_once` - --> $DIR/const-item-interior-mutations-const.rs:36:14 + --> $DIR/const-item-interior-mutations-const.rs:35:14 | LL | let _a = A.call_once(|| {}); | -^^^^^^^^^^^^^^^^^ @@ -102,7 +102,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `call_once_force` - --> $DIR/const-item-interior-mutations-const.rs:39:14 + --> $DIR/const-item-interior-mutations-const.rs:38:14 | LL | let _a = A.call_once_force(|_| {}); | -^^^^^^^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `wait` - --> $DIR/const-item-interior-mutations-const.rs:42:14 + --> $DIR/const-item-interior-mutations-const.rs:41:14 | LL | let _a = A.wait(); | -^^^^^^^ @@ -136,7 +136,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `wait_force` - --> $DIR/const-item-interior-mutations-const.rs:45:14 + --> $DIR/const-item-interior-mutations-const.rs:44:14 | LL | let _a = A.wait_force(); | -^^^^^^^^^^^^^ @@ -153,7 +153,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const.rs:52:14 + --> $DIR/const-item-interior-mutations-const.rs:51:14 | LL | let _a = A.set(1); | -^^^^^^^ @@ -170,7 +170,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const.rs:55:14 + --> $DIR/const-item-interior-mutations-const.rs:54:14 | LL | let _a = A.replace(2); | -^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `read` - --> $DIR/const-item-interior-mutations-const.rs:58:10 + --> $DIR/const-item-interior-mutations-const.rs:57:10 | LL | drop(A.read()); | -^^^^^^^ @@ -204,7 +204,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `try_read` - --> $DIR/const-item-interior-mutations-const.rs:61:10 + --> $DIR/const-item-interior-mutations-const.rs:60:10 | LL | drop(A.try_read()); | -^^^^^^^^^^^ @@ -221,7 +221,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `write` - --> $DIR/const-item-interior-mutations-const.rs:64:10 + --> $DIR/const-item-interior-mutations-const.rs:63:10 | LL | drop(A.write()); | -^^^^^^^^ @@ -238,7 +238,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `try_write` - --> $DIR/const-item-interior-mutations-const.rs:67:10 + --> $DIR/const-item-interior-mutations-const.rs:66:10 | LL | drop(A.try_write()); | -^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `force` - --> $DIR/const-item-interior-mutations-const.rs:74:14 + --> $DIR/const-item-interior-mutations-const.rs:73:14 | LL | let _a = LazyLock::force(&A); | ^^^^^^^^^^^^^^^^^-^ @@ -272,7 +272,7 @@ LL + static A: LazyLock = LazyLock::new(|| 0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const.rs:77:14 + --> $DIR/const-item-interior-mutations-const.rs:76:14 | LL | let _a = LazyLock::get(&A); | ^^^^^^^^^^^^^^^-^ @@ -289,7 +289,7 @@ LL + static A: LazyLock = LazyLock::new(|| 0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const.rs:84:14 + --> $DIR/const-item-interior-mutations-const.rs:83:14 | LL | let _a = A.get(); | -^^^^^^ @@ -306,7 +306,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `wait` - --> $DIR/const-item-interior-mutations-const.rs:87:14 + --> $DIR/const-item-interior-mutations-const.rs:86:14 | LL | let _a = A.wait(); | -^^^^^^^ @@ -323,7 +323,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const.rs:90:14 + --> $DIR/const-item-interior-mutations-const.rs:89:14 | LL | let _a = A.set(10); | -^^^^^^^^ @@ -340,7 +340,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `try_insert` - --> $DIR/const-item-interior-mutations-const.rs:93:14 + --> $DIR/const-item-interior-mutations-const.rs:92:14 | LL | let _a = A.try_insert(20); | -^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_init` - --> $DIR/const-item-interior-mutations-const.rs:96:14 + --> $DIR/const-item-interior-mutations-const.rs:95:14 | LL | let _a = A.get_or_init(|| 30); | -^^^^^^^^^^^^^^^^^^^ @@ -374,7 +374,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_try_init` - --> $DIR/const-item-interior-mutations-const.rs:99:14 + --> $DIR/const-item-interior-mutations-const.rs:98:14 | LL | let _a = A.get_or_try_init(|| Ok::<_, ()>(40)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -391,7 +391,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `wait` - --> $DIR/const-item-interior-mutations-const.rs:109:14 + --> $DIR/const-item-interior-mutations-const.rs:108:14 | LL | let _a = A.wait(guard); | -^^^^^^^^^^^^ @@ -408,7 +408,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_while` - --> $DIR/const-item-interior-mutations-const.rs:114:14 + --> $DIR/const-item-interior-mutations-const.rs:113:14 | LL | let _a = A.wait_while(guard, |x| *x == 0); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -425,7 +425,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_timeout_ms` - --> $DIR/const-item-interior-mutations-const.rs:119:14 + --> $DIR/const-item-interior-mutations-const.rs:118:14 | LL | let _a = A.wait_timeout_ms(guard, 10); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -442,7 +442,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_timeout` - --> $DIR/const-item-interior-mutations-const.rs:124:14 + --> $DIR/const-item-interior-mutations-const.rs:123:14 | LL | let _a = A.wait_timeout(guard, Duration::from_millis(10)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -459,7 +459,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_timeout_while` - --> $DIR/const-item-interior-mutations-const.rs:129:14 + --> $DIR/const-item-interior-mutations-const.rs:128:14 | LL | let _a = A.wait_timeout_while(guard, Duration::from_millis(10), |x| *x == 0); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -476,7 +476,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `notify_one` - --> $DIR/const-item-interior-mutations-const.rs:132:14 + --> $DIR/const-item-interior-mutations-const.rs:131:14 | LL | let _a = A.notify_one(); | -^^^^^^^^^^^^^ @@ -493,7 +493,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `notify_all` - --> $DIR/const-item-interior-mutations-const.rs:135:14 + --> $DIR/const-item-interior-mutations-const.rs:134:14 | LL | let _a = A.notify_all(); | -^^^^^^^^^^^^^ From a44de58d4b3135b80ed5925a85a004da66fe8bb0 Mon Sep 17 00:00:00 2001 From: dfireBird Date: Mon, 15 Dec 2025 17:28:05 +0530 Subject: [PATCH 0815/3801] fix: consider path used in pattern destructing assignments fix: assign mutable for variables in pattern destructing assignments --- .../rust-analyzer/crates/hir/src/semantics.rs | 53 +++++++++++----- .../src/handlers/extract_function.rs | 62 +++++++++++++++++++ .../rust-analyzer/crates/ide-db/src/search.rs | 2 +- 3 files changed, 99 insertions(+), 18 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index a9af26aa3f66..ccbfd45e3011 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -10,6 +10,7 @@ use std::{ ops::{self, ControlFlow, Not}, }; +use base_db::FxIndexSet; use either::Either; use hir_def::{ DefWithBodyId, FunctionId, MacroId, StructId, TraitId, VariantId, @@ -2197,7 +2198,7 @@ impl<'db> SemanticsImpl<'db> { &self, element: Either<&ast::Expr, &ast::StmtList>, text_range: TextRange, - ) -> Option> { + ) -> Option> { let sa = self.analyze(element.either(|e| e.syntax(), |s| s.syntax()))?; let store = sa.store()?; let mut resolver = sa.resolver.clone(); @@ -2245,31 +2246,49 @@ impl<'db> SemanticsImpl<'db> { let mut exprs: Vec<_> = exprs.into_iter().filter_map(|e| sa.expr_id(e).and_then(|e| e.as_expr())).collect(); - let mut locals: Vec = Vec::new(); - let mut add_to_locals_used = |expr_id| { - if let Expr::Path(path) = &store[expr_id] + let mut locals: FxIndexSet = FxIndexSet::default(); + let mut add_to_locals_used = |id, parent_expr| { + let path = match id { + ExprOrPatId::ExprId(expr_id) => { + if let Expr::Path(path) = &store[expr_id] { + Some(path) + } else { + None + } + } + ExprOrPatId::PatId(pat_id) => { + if let Pat::Path(path) = &store[pat_id] { + Some(path) + } else { + None + } + } + }; + + if let Some(path) = path && is_not_generated(path) { - let _ = resolver.update_to_inner_scope(self.db, def, expr_id); - resolver - .resolve_path_in_value_ns_fully(self.db, path, store.expr_path_hygiene(expr_id)) - .inspect(|value| { - if let ValueNs::LocalBinding(id) = value { - locals.push((def, *id).into()); - } - }); + let _ = resolver.update_to_inner_scope(self.db, def, parent_expr); + let hygiene = store.expr_or_pat_path_hygiene(id); + resolver.resolve_path_in_value_ns_fully(self.db, path, hygiene).inspect(|value| { + if let ValueNs::LocalBinding(id) = value { + locals.insert((def, *id).into()); + } + }); } }; while let Some(expr_id) = exprs.pop() { - let mut has_child = false; + if let Expr::Assignment { target, .. } = store[expr_id] { + store.walk_pats(target, &mut |id| { + add_to_locals_used(ExprOrPatId::PatId(id), expr_id) + }); + }; store.walk_child_exprs(expr_id, |id| { - has_child = true; exprs.push(id); }); - if !has_child { - add_to_locals_used(expr_id) - } + + add_to_locals_used(ExprOrPatId::ExprId(expr_id), expr_id) } Some(locals) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 19ded49b1850..231df9b5b3e1 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -6313,4 +6313,66 @@ fn $0fun_name(v1: u32, v2: u32) -> u32 { }"#, ); } + + #[test] + fn pattern_assignment() { + check_assist( + extract_function, + r#" +struct Point {x: u32, y: u32}; + +fn point() -> Point { + Point { x: 45, y: 50 }; +} + +fn foo() { + let mut a = 1; + let mut b = 3; + $0Point { x: a, y: b } = point();$0 +} +"#, + r#" +struct Point {x: u32, y: u32}; + +fn point() -> Point { + Point { x: 45, y: 50 }; +} + +fn foo() { + let mut a = 1; + let mut b = 3; + fun_name(a, b); +} + +fn $0fun_name(mut a: u32, mut b: u32) { + Point { x: a, y: b } = point(); +} +"#, + ); + } + + #[test] + fn tuple_assignment() { + check_assist( + extract_function, + r#" +fn foo() { + let mut a = 3; + let mut b = 4; + $0(a, b) = (b, a);$0 +} +"#, + r#" +fn foo() { + let mut a = 3; + let mut b = 4; + fun_name(a, b); +} + +fn $0fun_name(mut a: i32, mut b: i32) { + (a, b) = (b, a); +} +"#, + ); + } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index a48438cfa86f..1d865892a22b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -1345,7 +1345,7 @@ impl ReferenceCategory { // If the variable or field ends on the LHS's end then it's a Write // (covers fields and locals). FIXME: This is not terribly accurate. if let Some(lhs) = expr.lhs() - && lhs.syntax().text_range().end() == r.syntax().text_range().end() { + && lhs.syntax().text_range().contains_range(r.syntax().text_range()) { return Some(ReferenceCategory::WRITE) } } From 1fe0a85df732aeffb58e183561ebd22563c0d3cb Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Mon, 10 Nov 2025 14:52:54 +0000 Subject: [PATCH 0816/3801] Add rv64IM --- compiler/rustc_target/src/spec/mod.rs | 1 + .../targets/riscv64im_unknown_none_elf.rs | 35 ++++++++++++ src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 1 + .../riscv64im-unknown-none-elf.md | 54 +++++++++++++++++++ tests/assembly-llvm/targets/targets-elf.rs | 3 ++ 6 files changed, 95 insertions(+) create mode 100644 compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs create mode 100644 src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index c76e345bb7b6..3d500694c978 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1686,6 +1686,7 @@ supported_targets! { ("riscv32imac-unknown-xous-elf", riscv32imac_unknown_xous_elf), ("riscv32gc-unknown-linux-gnu", riscv32gc_unknown_linux_gnu), ("riscv32gc-unknown-linux-musl", riscv32gc_unknown_linux_musl), + ("riscv64im-unknown-none-elf", riscv64im_unknown_none_elf), ("riscv64imac-unknown-none-elf", riscv64imac_unknown_none_elf), ("riscv64gc-unknown-none-elf", riscv64gc_unknown_none_elf), ("riscv64gc-unknown-linux-gnu", riscv64gc_unknown_linux_gnu), diff --git a/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs new file mode 100644 index 000000000000..6aae40a3f90d --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/riscv64im_unknown_none_elf.rs @@ -0,0 +1,35 @@ +use crate::spec::{ + Arch, Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, + TargetOptions, +}; + +pub(crate) fn target() -> Target { + Target { + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), + llvm_target: "riscv64".into(), + metadata: TargetMetadata { + description: Some("Bare RISC-V (RV64IM ISA)".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 64, + arch: Arch::RiscV64, + + options: TargetOptions { + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + linker: Some("rust-lld".into()), + cpu: "generic-rv64".into(), + max_atomic_width: Some(64), + atomic_cas: false, + features: "+m,+forced-atomics".into(), + llvm_abiname: "lp64".into(), + panic_strategy: PanicStrategy::Abort, + relocation_model: RelocModel::Static, + code_model: Some(CodeModel::Medium), + emit_debug_gdb_scripts: false, + eh_frame_header: false, + ..Default::default() + }, + } +} diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 832b5a69d47c..3b8852f8ff9f 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -112,6 +112,7 @@ - [riscv32i\*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md) - [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md) - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) + - [riscv64im-unknown-none-elf](platform-support/riscv64im-unknown-none-elf.md) - [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md) - [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md) - [riscv64a23-unknown-linux-gnu](platform-support/riscv64a23-unknown-linux-gnu.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d772702df76e..5164ab69d353 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -184,6 +184,7 @@ target | std | notes [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | ✓ |RISC-V Linux (kernel 4.20+, musl 1.2.5) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) +[`riscv64im-unknown-none-elf`](platform-support/riscv64im-unknown-none-elf.md) | * | Bare RISC-V (RV64IM ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4+, glibc 2.23) [`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M diff --git a/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md new file mode 100644 index 000000000000..033904959db3 --- /dev/null +++ b/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md @@ -0,0 +1,54 @@ +# `riscv64im-unknown-none-elf` + +**Tier: 3** + +Bare-metal target for RISC-V CPUs with the RV64IM ISA. + +## Target maintainers + +* Rust Embedded Working Group, [RISC-V team](https://github.com/rust-embedded/wg#the-risc-v-team) + +## Requirements + +This target is cross-compiled and uses static linking. The target supports `core` and `alloc`, but not `std`. + +The target does not support atomic compare-and-swap operations, as the RV64IM ISA lacks the "A" (Atomics) extension. Atomic operations are emulated using the `+forced-atomics` feature. + +No external toolchain is required and the default `rust-lld` linker works, but you must specify a linker script. The [`riscv-rt`] crate provides suitable linker scripts. The [`riscv-rust-quickstart`] repository gives examples of RISC-V bare-metal projects. + +[`riscv-rt`]: https://crates.io/crates/riscv-rt +[`riscv-rust-quickstart`]: https://github.com/riscv-rust/riscv-rust-quickstart + +## Building the target + +This target is included in Rust and can be installed via `rustup`: + +```bash +rustup target add riscv64im-unknown-none-elf +``` + +## Building Rust programs + +Build using the standard Cargo workflow: + +```bash +cargo build --target riscv64im-unknown-none-elf +``` + +You will need to provide a linker script. The [`riscv-rt`] crate handles this automatically when used as a dependency. + +## Testing + +This is a cross-compiled `no-std` target, which must be run either in a simulator or by programming onto suitable hardware. It is not possible to run the Rust test-suite on this target. + +You can test the target in QEMU with: + +```bash +qemu-system-riscv64 -machine virt -cpu rv64,a=false,c=false -nographic -semihosting -kernel your-binary +``` + +Note: You must explicitly disable the 'a' (atomics) and 'c' (compressed) extensions when using QEMU to accurately emulate an RV64IM-only CPU. + +## Cross-compilation toolchains and C code + +This target supports C code. If interlinking with C or C++, you may need to use `riscv64-unknown-elf-gcc` with the appropriate `-march=rv64im -mabi=lp64` flags as a linker instead of `rust-lld`. diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index 324c7fc9da4e..c8b81cc858d6 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -520,6 +520,9 @@ //@ revisions: riscv64gc_unknown_redox //@ [riscv64gc_unknown_redox] compile-flags: --target riscv64gc-unknown-redox //@ [riscv64gc_unknown_redox] needs-llvm-components: riscv +//@ revisions: riscv64im_unknown_none_elf +//@ [riscv64im_unknown_none_elf] compile-flags: --target riscv64im-unknown-none-elf +//@ [riscv64im_unknown_none_elf] needs-llvm-components: riscv //@ revisions: riscv64imac_unknown_none_elf //@ [riscv64imac_unknown_none_elf] compile-flags: --target riscv64imac-unknown-none-elf //@ [riscv64imac_unknown_none_elf] needs-llvm-components: riscv From 2846968f78b35e31f8087787d930db0708c93908 Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Mon, 10 Nov 2025 14:56:07 +0000 Subject: [PATCH 0817/3801] add riscv64im to ignore list for stage0 --- src/bootstrap/src/core/sanity.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 50d8154014bb..d1f706fd9c3e 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -41,6 +41,7 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[ "sparc64-unknown-helenos", // just a dummy comment so the list doesn't get onelined "riscv64gc-unknown-redox", + "riscv64im-unknown-none-elf", "hexagon-unknown-qurt", ]; From 9ba7852ddf317a997f656ac123bdccc8d22db394 Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Mon, 10 Nov 2025 21:25:13 +0000 Subject: [PATCH 0818/3801] refactor readme --- .../riscv64im-unknown-none-elf.md | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md index 033904959db3..505810caa425 100644 --- a/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md @@ -12,7 +12,7 @@ Bare-metal target for RISC-V CPUs with the RV64IM ISA. This target is cross-compiled and uses static linking. The target supports `core` and `alloc`, but not `std`. -The target does not support atomic compare-and-swap operations, as the RV64IM ISA lacks the "A" (Atomics) extension. Atomic operations are emulated using the `+forced-atomics` feature. +As the RV64IM ISA lacks the "A" (Atomics) extension, atomic operations are emulated using the `+forced-atomics` feature. No external toolchain is required and the default `rust-lld` linker works, but you must specify a linker script. The [`riscv-rt`] crate provides suitable linker scripts. The [`riscv-rust-quickstart`] repository gives examples of RISC-V bare-metal projects. @@ -21,34 +21,27 @@ No external toolchain is required and the default `rust-lld` linker works, but y ## Building the target -This target is included in Rust and can be installed via `rustup`: +You can build Rust with support for the target by adding it to the `target` list in `bootstrap.toml`: + +```toml +[build] +target = ["riscv64im-unknown-none-elf"] +``` + +Alternatively, you can use the `-Z build-std` flag to build the standard library on-demand: ```bash -rustup target add riscv64im-unknown-none-elf +cargo build -Z build-std=core,alloc --target riscv64im-unknown-none-elf ``` ## Building Rust programs -Build using the standard Cargo workflow: - -```bash -cargo build --target riscv64im-unknown-none-elf -``` - -You will need to provide a linker script. The [`riscv-rt`] crate handles this automatically when used as a dependency. +Rust does not yet ship pre-compiled artifacts for this target. To compile for this target (see "Building the target" above) ## Testing This is a cross-compiled `no-std` target, which must be run either in a simulator or by programming onto suitable hardware. It is not possible to run the Rust test-suite on this target. -You can test the target in QEMU with: - -```bash -qemu-system-riscv64 -machine virt -cpu rv64,a=false,c=false -nographic -semihosting -kernel your-binary -``` - -Note: You must explicitly disable the 'a' (atomics) and 'c' (compressed) extensions when using QEMU to accurately emulate an RV64IM-only CPU. - ## Cross-compilation toolchains and C code This target supports C code. If interlinking with C or C++, you may need to use `riscv64-unknown-elf-gcc` with the appropriate `-march=rv64im -mabi=lp64` flags as a linker instead of `rust-lld`. From aa73de400ddc4ac9dde1fdba69818bb3f20deb74 Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 20:28:42 +0100 Subject: [PATCH 0819/3801] std: move `RawOsError` to `sys::io` --- library/std/src/io/error.rs | 2 +- library/std/src/sys/io/mod.rs | 5 +++++ library/std/src/sys/pal/mod.rs | 3 --- library/std/src/sys/pal/uefi/mod.rs | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 0167be4d514c..98b266663ad2 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -139,7 +139,7 @@ enum ErrorData { /// /// [`into`]: Into::into #[unstable(feature = "raw_os_error_ty", issue = "107792")] -pub type RawOsError = sys::RawOsError; +pub type RawOsError = sys::io::RawOsError; // `#[repr(align(4))]` is probably redundant, it should have that value or // higher already. We include it just because repr_bitpacked.rs's encoding diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs index b4e4e6ec7312..4a5d6f8e27f2 100644 --- a/library/std/src/sys/io/mod.rs +++ b/library/std/src/sys/io/mod.rs @@ -55,3 +55,8 @@ pub use kernel_copy::{CopyState, kernel_copy}; // Bare metal platforms usually have very small amounts of RAM // (in the order of hundreds of KB) pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 }; + +pub type RawOsError = cfg_select! { + target_os = "uefi" => usize, + _ => i32, +}; diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index 2bd3ec8188a7..0ecbcf5a2702 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -92,6 +92,3 @@ pub const FULL_BACKTRACE_DEFAULT: bool = cfg_select! { target_os = "fuchsia" => true, _ => false, }; - -#[cfg(not(target_os = "uefi"))] -pub type RawOsError = i32; diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index e8236437b9c9..61725b2ed048 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -13,6 +13,8 @@ //! [`OsString`]: crate::ffi::OsString #![forbid(unsafe_op_in_unsafe_fn)] +use crate::io::RawOsError; + pub mod helpers; pub mod os; pub mod time; @@ -20,8 +22,6 @@ pub mod time; #[cfg(test)] mod tests; -pub type RawOsError = usize; - use crate::io as std_io; use crate::os::uefi; use crate::ptr::NonNull; From 854df94584faadeeb304d1e9229890a527cbd5cc Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 20:29:44 +0100 Subject: [PATCH 0820/3801] std: move `FULL_BACKTRACE_DEFAULT` to `sys::backtrace` --- library/std/src/panic.rs | 2 +- library/std/src/sys/backtrace.rs | 6 ++++++ library/std/src/sys/pal/mod.rs | 6 ------ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 1997785885d3..beddc328582c 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -523,7 +523,7 @@ pub fn get_backtrace_style() -> Option { Some(x) if &x == "0" => BacktraceStyle::Off, Some(x) if &x == "full" => BacktraceStyle::Full, Some(_) => BacktraceStyle::Short, - None if crate::sys::FULL_BACKTRACE_DEFAULT => BacktraceStyle::Full, + None if crate::sys::backtrace::FULL_BACKTRACE_DEFAULT => BacktraceStyle::Full, None => BacktraceStyle::Off, }; diff --git a/library/std/src/sys/backtrace.rs b/library/std/src/sys/backtrace.rs index 8e4e6aab0e49..858a95882b39 100644 --- a/library/std/src/sys/backtrace.rs +++ b/library/std/src/sys/backtrace.rs @@ -11,6 +11,12 @@ use crate::{env, fmt, io}; /// Max number of frames to print. const MAX_NB_FRAMES: usize = 100; +pub(crate) const FULL_BACKTRACE_DEFAULT: bool = cfg_select! { + // Fuchsia components default to full backtrace. + target_os = "fuchsia" => true, + _ => false, +}; + pub(crate) struct BacktraceLock<'a>(#[allow(dead_code)] MutexGuard<'a, ()>); pub(crate) fn lock<'a>() -> BacktraceLock<'a> { diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs index 0ecbcf5a2702..93ad4536e18f 100644 --- a/library/std/src/sys/pal/mod.rs +++ b/library/std/src/sys/pal/mod.rs @@ -86,9 +86,3 @@ cfg_select! { pub use self::unsupported::*; } } - -pub const FULL_BACKTRACE_DEFAULT: bool = cfg_select! { - // Fuchsia components default to full backtrace. - target_os = "fuchsia" => true, - _ => false, -}; From 19acd4f491881423c793bdf8781b764d0101b087 Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 20:33:14 +0100 Subject: [PATCH 0821/3801] std: move `FromInner` etc. to `sys` ... and remove the `#[doc(hidden)]` in favour of making them `pub(crate)`. --- library/std/src/sys/mod.rs | 22 ++++++++++++++++++++++ library/std/src/sys_common/mod.rs | 26 -------------------------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 3c44543bce32..0c72f6a57fe8 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -37,3 +37,25 @@ pub mod thread_local; // FIXME(117276): remove this, move feature implementations into individual // submodules. pub use pal::*; + +/// A trait for viewing representations from std types. +#[cfg_attr(not(target_os = "linux"), allow(unused))] +pub(crate) trait AsInner { + fn as_inner(&self) -> &Inner; +} + +/// A trait for viewing representations from std types. +#[cfg_attr(not(target_os = "linux"), allow(unused))] +pub(crate) trait AsInnerMut { + fn as_inner_mut(&mut self) -> &mut Inner; +} + +/// A trait for extracting representations from std types. +pub(crate) trait IntoInner { + fn into_inner(self) -> Inner; +} + +/// A trait for creating std types from internal representations. +pub(crate) trait FromInner { + fn from_inner(inner: Inner) -> Self; +} diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index c6cb1b006e8c..015042440b5a 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -23,32 +23,6 @@ pub mod wstr; // common error constructors -/// A trait for viewing representations from std types -#[doc(hidden)] -#[allow(dead_code)] // not used on all platforms -pub trait AsInner { - fn as_inner(&self) -> &Inner; -} - -/// A trait for viewing representations from std types -#[doc(hidden)] -#[allow(dead_code)] // not used on all platforms -pub trait AsInnerMut { - fn as_inner_mut(&mut self) -> &mut Inner; -} - -/// A trait for extracting representations from std types -#[doc(hidden)] -pub trait IntoInner { - fn into_inner(self) -> Inner; -} - -/// A trait for creating std types from internal representations -#[doc(hidden)] -pub trait FromInner { - fn from_inner(inner: Inner) -> Self; -} - // Computes (value*numerator)/denom without overflow, as long as both (numerator*denom) and the // overall result fit into i64 (which is the case for our time conversions). #[allow(dead_code)] // not used on all platforms From 33409da171eb691db711205be9087f3268111943 Mon Sep 17 00:00:00 2001 From: joboet Date: Fri, 12 Dec 2025 20:49:51 +0100 Subject: [PATCH 0822/3801] std: update references to `FromInner` etc. --- library/std/src/ffi/os_str.rs | 2 +- library/std/src/fs.rs | 3 +-- library/std/src/io/pipe.rs | 3 +-- library/std/src/net/tcp.rs | 3 +-- library/std/src/net/udp.rs | 3 +-- library/std/src/os/aix/fs.rs | 2 +- library/std/src/os/android/fs.rs | 2 +- library/std/src/os/cygwin/fs.rs | 2 +- library/std/src/os/darwin/fs.rs | 2 +- library/std/src/os/dragonfly/fs.rs | 2 +- library/std/src/os/emscripten/fs.rs | 2 +- library/std/src/os/espidf/fs.rs | 2 +- library/std/src/os/fd/net.rs | 2 +- library/std/src/os/fd/owned.rs | 2 +- library/std/src/os/fd/raw.rs | 2 +- library/std/src/os/freebsd/fs.rs | 2 +- library/std/src/os/freebsd/net.rs | 2 +- library/std/src/os/fuchsia/fs.rs | 2 +- library/std/src/os/haiku/fs.rs | 2 +- library/std/src/os/hermit/io/net.rs | 4 ++-- library/std/src/os/horizon/fs.rs | 2 +- library/std/src/os/hurd/fs.rs | 2 +- library/std/src/os/illumos/fs.rs | 2 +- library/std/src/os/illumos/net.rs | 2 +- library/std/src/os/l4re/fs.rs | 2 +- library/std/src/os/linux/fs.rs | 2 +- library/std/src/os/linux/process.rs | 2 +- library/std/src/os/motor/ffi.rs | 2 +- library/std/src/os/motor/process.rs | 2 +- library/std/src/os/net/linux_ext/socket.rs | 2 +- library/std/src/os/net/linux_ext/tcp.rs | 2 +- library/std/src/os/netbsd/fs.rs | 2 +- library/std/src/os/netbsd/net.rs | 2 +- library/std/src/os/nto/fs.rs | 2 +- library/std/src/os/nuttx/fs.rs | 2 +- library/std/src/os/openbsd/fs.rs | 2 +- library/std/src/os/redox/fs.rs | 2 +- library/std/src/os/rtems/fs.rs | 2 +- library/std/src/os/solaris/fs.rs | 2 +- library/std/src/os/solaris/net.rs | 2 +- library/std/src/os/solid/io.rs | 2 +- library/std/src/os/unix/ffi/os_str.rs | 2 +- library/std/src/os/unix/fs.rs | 2 +- library/std/src/os/unix/net/datagram.rs | 3 +-- library/std/src/os/unix/net/listener.rs | 3 +-- library/std/src/os/unix/net/stream.rs | 3 +-- library/std/src/os/unix/process.rs | 2 +- library/std/src/os/unix/thread.rs | 2 +- library/std/src/os/vita/fs.rs | 2 +- library/std/src/os/vxworks/fs.rs | 2 +- library/std/src/os/wasi/fs.rs | 2 +- library/std/src/os/windows/ffi.rs | 2 +- library/std/src/os/windows/fs.rs | 2 +- library/std/src/os/windows/io/handle.rs | 3 +-- library/std/src/os/windows/io/raw.rs | 2 +- library/std/src/os/windows/process.rs | 2 +- library/std/src/os/windows/thread.rs | 2 +- library/std/src/process.rs | 3 +-- library/std/src/sys/args/sgx.rs | 2 +- library/std/src/sys/args/windows.rs | 3 +-- library/std/src/sys/env/zkvm.rs | 3 +-- library/std/src/sys/fd/hermit.rs | 3 +-- library/std/src/sys/fd/motor.rs | 3 +-- library/std/src/sys/fd/unix.rs | 3 +-- library/std/src/sys/fs/hermit.rs | 3 +-- library/std/src/sys/fs/motor.rs | 3 +-- library/std/src/sys/fs/unix.rs | 3 +-- library/std/src/sys/fs/windows.rs | 3 +-- library/std/src/sys/net/connection/motor.rs | 3 +-- library/std/src/sys/net/connection/socket/hermit.rs | 2 +- library/std/src/sys/net/connection/socket/mod.rs | 2 +- library/std/src/sys/net/connection/socket/solid.rs | 3 +-- library/std/src/sys/net/connection/socket/unix.rs | 2 +- library/std/src/sys/net/connection/socket/windows.rs | 3 +-- library/std/src/sys/net/connection/wasip1.rs | 3 +-- library/std/src/sys/os_str/bytes.rs | 2 +- library/std/src/sys/os_str/utf8.rs | 2 +- library/std/src/sys/os_str/wtf8.rs | 2 +- library/std/src/sys/pal/sgx/mod.rs | 2 -- library/std/src/sys/pal/unix/linux/pidfd.rs | 3 +-- library/std/src/sys/pal/unix/time.rs | 2 +- library/std/src/sys/pal/windows/handle.rs | 3 +-- library/std/src/sys/pal/windows/time.rs | 3 +-- library/std/src/sys/pipe/unsupported.rs | 2 +- library/std/src/sys/process/motor.rs | 3 +-- library/std/src/sys/process/unix/common.rs | 3 +-- library/std/src/sys/process/unix/unix.rs | 4 ++-- library/std/src/sys/process/windows.rs | 3 +-- library/std/src/sys/process/windows/child_pipe.rs | 3 +-- library/std/src/sys/stdio/motor.rs | 3 +-- library/std/src/sys/thread/windows.rs | 3 +-- library/std/src/thread/join_handle.rs | 3 +-- library/std/src/thread/lifecycle.rs | 3 +-- library/std/src/time.rs | 3 +-- 94 files changed, 95 insertions(+), 131 deletions(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index a1dd8e5f86f4..d390c82021c7 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -13,7 +13,7 @@ use crate::rc::Rc; use crate::str::FromStr; use crate::sync::Arc; use crate::sys::os_str::{Buf, Slice}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; use crate::{cmp, fmt, slice}; /// A type that can represent owned, mutable platform-native strings, but is diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index d14d0ad2f0ea..f078dec21d0a 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -46,8 +46,7 @@ use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, use crate::path::{Path, PathBuf}; use crate::sealed::Sealed; use crate::sync::Arc; -use crate::sys::fs as fs_imp; -use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, fs as fs_imp}; use crate::time::SystemTime; use crate::{error, fmt}; diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs index 8457e7bceddc..61b81cf074a6 100644 --- a/library/std/src/io/pipe.rs +++ b/library/std/src/io/pipe.rs @@ -1,6 +1,5 @@ use crate::io; -use crate::sys::pipe as imp; -use crate::sys_common::{FromInner, IntoInner}; +use crate::sys::{FromInner, IntoInner, pipe as imp}; /// Creates an anonymous pipe. /// diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index ae50f531a716..dac568e419f3 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -16,8 +16,7 @@ use crate::io::prelude::*; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::iter::FusedIterator; use crate::net::{Shutdown, SocketAddr, ToSocketAddrs}; -use crate::sys::net as net_imp; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, net as net_imp}; use crate::time::Duration; /// A TCP stream between a local and a remote socket. diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs index 72e292e3d157..136803ab16f1 100644 --- a/library/std/src/net/udp.rs +++ b/library/std/src/net/udp.rs @@ -13,8 +13,7 @@ mod tests; use crate::fmt; use crate::io::{self, ErrorKind}; use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs}; -use crate::sys::net as net_imp; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, net as net_imp}; use crate::time::Duration; /// A UDP socket. diff --git a/library/std/src/os/aix/fs.rs b/library/std/src/os/aix/fs.rs index ac9dd45f0542..2a940c6b9c97 100644 --- a/library/std/src/os/aix/fs.rs +++ b/library/std/src/os/aix/fs.rs @@ -5,7 +5,7 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/android/fs.rs b/library/std/src/os/android/fs.rs index 6b931e381695..d67c5582fd91 100644 --- a/library/std/src/os/android/fs.rs +++ b/library/std/src/os/android/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::android::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/cygwin/fs.rs b/library/std/src/os/cygwin/fs.rs index 5533264fd515..42623e6d47ad 100644 --- a/library/std/src/os/cygwin/fs.rs +++ b/library/std/src/os/cygwin/fs.rs @@ -1,6 +1,6 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// /// [`fs::Metadata`]: crate::fs::Metadata diff --git a/library/std/src/os/darwin/fs.rs b/library/std/src/os/darwin/fs.rs index 5740c86e6218..af98e069b41a 100644 --- a/library/std/src/os/darwin/fs.rs +++ b/library/std/src/os/darwin/fs.rs @@ -5,7 +5,7 @@ use crate::fs::{self, Metadata}; use crate::sealed::Sealed; -use crate::sys_common::{AsInner, AsInnerMut, IntoInner}; +use crate::sys::{AsInner, AsInnerMut, IntoInner}; use crate::time::SystemTime; /// OS-specific extensions to [`fs::Metadata`]. diff --git a/library/std/src/os/dragonfly/fs.rs b/library/std/src/os/dragonfly/fs.rs index 0cd543b2ab97..b47b5108c70e 100644 --- a/library/std/src/os/dragonfly/fs.rs +++ b/library/std/src/os/dragonfly/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::dragonfly::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/emscripten/fs.rs b/library/std/src/os/emscripten/fs.rs index 81f9ef331a5f..a5778812ad94 100644 --- a/library/std/src/os/emscripten/fs.rs +++ b/library/std/src/os/emscripten/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::emscripten::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/espidf/fs.rs b/library/std/src/os/espidf/fs.rs index ffff584cda02..cd09efca2db5 100644 --- a/library/std/src/os/espidf/fs.rs +++ b/library/std/src/os/espidf/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::espidf::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/fd/net.rs b/library/std/src/os/fd/net.rs index 34479ca0e190..98faf0709153 100644 --- a/library/std/src/os/fd/net.rs +++ b/library/std/src/os/fd/net.rs @@ -1,6 +1,6 @@ use crate::os::fd::owned::OwnedFd; use crate::os::fd::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; use crate::{net, sys}; macro_rules! impl_as_raw_fd { diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 6a0e7a640028..846ad37aad22 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -20,7 +20,7 @@ use crate::mem::ManuallyDrop; )))] use crate::sys::cvt; #[cfg(not(target_os = "trusty"))] -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; use crate::{fmt, io}; type ValidRawFd = core::num::niche_types::NotAllOnes; diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index c01e6b83cd36..39e374174646 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -23,7 +23,7 @@ use crate::os::unix::io::OwnedFd; #[cfg(target_os = "wasi")] use crate::os::wasi::io::OwnedFd; #[cfg(not(target_os = "trusty"))] -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; /// Raw file descriptors. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/os/freebsd/fs.rs b/library/std/src/os/freebsd/fs.rs index 34384a4bcb50..682a32a94c19 100644 --- a/library/std/src/os/freebsd/fs.rs +++ b/library/std/src/os/freebsd/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::freebsd::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/freebsd/net.rs b/library/std/src/os/freebsd/net.rs index fcfc5c1c8393..f759b91921b5 100644 --- a/library/std/src/os/freebsd/net.rs +++ b/library/std/src/os/freebsd/net.rs @@ -6,7 +6,7 @@ use crate::ffi::CStr; use crate::io; use crate::os::unix::net; use crate::sealed::Sealed; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// FreeBSD-specific functionality for `AF_UNIX` sockets [`UnixDatagram`] /// and [`UnixStream`]. diff --git a/library/std/src/os/fuchsia/fs.rs b/library/std/src/os/fuchsia/fs.rs index b48a46f9124a..8cded1db37d7 100644 --- a/library/std/src/os/fuchsia/fs.rs +++ b/library/std/src/os/fuchsia/fs.rs @@ -1,7 +1,7 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/haiku/fs.rs b/library/std/src/os/haiku/fs.rs index 23f6493180b7..86624edcaef9 100644 --- a/library/std/src/os/haiku/fs.rs +++ b/library/std/src/os/haiku/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::haiku::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/hermit/io/net.rs b/library/std/src/os/hermit/io/net.rs index 233bc885fc73..d5baeafec649 100644 --- a/library/std/src/os/hermit/io/net.rs +++ b/library/std/src/os/hermit/io/net.rs @@ -1,6 +1,6 @@ +use crate::net; use crate::os::hermit::io::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::sys_common::{self, AsInner, FromInner, IntoInner}; -use crate::{net, sys}; +use crate::sys::{self, AsInner, FromInner, IntoInner}; macro_rules! impl_as_raw_fd { ($($t:ident)*) => {$( diff --git a/library/std/src/os/horizon/fs.rs b/library/std/src/os/horizon/fs.rs index 1325522105dc..a5f3f791e6a1 100644 --- a/library/std/src/os/horizon/fs.rs +++ b/library/std/src/os/horizon/fs.rs @@ -1,7 +1,7 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/hurd/fs.rs b/library/std/src/os/hurd/fs.rs index e3087fa8af1c..e0fc544fed1d 100644 --- a/library/std/src/os/hurd/fs.rs +++ b/library/std/src/os/hurd/fs.rs @@ -5,7 +5,7 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/illumos/fs.rs b/library/std/src/os/illumos/fs.rs index 75dbe167785d..76a5871638a1 100644 --- a/library/std/src/os/illumos/fs.rs +++ b/library/std/src/os/illumos/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::illumos::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/illumos/net.rs b/library/std/src/os/illumos/net.rs index 5ef4e1ec89e3..c21c887edbdf 100644 --- a/library/std/src/os/illumos/net.rs +++ b/library/std/src/os/illumos/net.rs @@ -5,7 +5,7 @@ use crate::io; use crate::os::unix::net; use crate::sealed::Sealed; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// illumos-specific functionality for `AF_UNIX` sockets [`UnixDatagram`] /// and [`UnixStream`]. diff --git a/library/std/src/os/l4re/fs.rs b/library/std/src/os/l4re/fs.rs index 0511ddcf19af..1f0bacae1ca6 100644 --- a/library/std/src/os/l4re/fs.rs +++ b/library/std/src/os/l4re/fs.rs @@ -7,7 +7,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::l4re::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/linux/fs.rs b/library/std/src/os/linux/fs.rs index 20a7a161a262..e52a63bc798e 100644 --- a/library/std/src/os/linux/fs.rs +++ b/library/std/src/os/linux/fs.rs @@ -7,7 +7,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::linux::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/linux/process.rs b/library/std/src/os/linux/process.rs index 919590947972..fef321436f6a 100644 --- a/library/std/src/os/linux/process.rs +++ b/library/std/src/os/linux/process.rs @@ -8,9 +8,9 @@ use crate::io::Result; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::process::{self, ExitStatus}; use crate::sealed::Sealed; +use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner}; #[cfg(not(doc))] use crate::sys::{fd::FileDesc, linux::pidfd::PidFd as InnerPidFd}; -use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; #[cfg(doc)] struct InnerPidFd; diff --git a/library/std/src/os/motor/ffi.rs b/library/std/src/os/motor/ffi.rs index 10e8da392dcc..e65a7736d3fa 100644 --- a/library/std/src/os/motor/ffi.rs +++ b/library/std/src/os/motor/ffi.rs @@ -3,7 +3,7 @@ use crate::ffi::{OsStr, OsString}; use crate::sealed::Sealed; -use crate::sys_common::{AsInner, IntoInner}; +use crate::sys::{AsInner, IntoInner}; /// Motor OS–specific extensions to [`OsString`]. /// diff --git a/library/std/src/os/motor/process.rs b/library/std/src/os/motor/process.rs index 015fbcb97f97..09f38a4721bb 100644 --- a/library/std/src/os/motor/process.rs +++ b/library/std/src/os/motor/process.rs @@ -1,7 +1,7 @@ #![unstable(feature = "motor_ext", issue = "147456")] use crate::sealed::Sealed; -use crate::sys_common::AsInner; +use crate::sys::AsInner; pub trait ChildExt: Sealed { /// Extracts the main thread raw handle, without taking ownership diff --git a/library/std/src/os/net/linux_ext/socket.rs b/library/std/src/os/net/linux_ext/socket.rs index a15feb6bd9f2..ecc2758961e1 100644 --- a/library/std/src/os/net/linux_ext/socket.rs +++ b/library/std/src/os/net/linux_ext/socket.rs @@ -3,7 +3,7 @@ use crate::io; use crate::os::unix::net; use crate::sealed::Sealed; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// Linux-specific functionality for `AF_UNIX` sockets [`UnixDatagram`] /// and [`UnixStream`]. diff --git a/library/std/src/os/net/linux_ext/tcp.rs b/library/std/src/os/net/linux_ext/tcp.rs index 3f9b2bd3f4b4..c97063dd1650 100644 --- a/library/std/src/os/net/linux_ext/tcp.rs +++ b/library/std/src/os/net/linux_ext/tcp.rs @@ -3,7 +3,7 @@ //! [`std::net`]: crate::net use crate::sealed::Sealed; -use crate::sys_common::AsInner; +use crate::sys::AsInner; #[cfg(target_os = "linux")] use crate::time::Duration; use crate::{io, net}; diff --git a/library/std/src/os/netbsd/fs.rs b/library/std/src/os/netbsd/fs.rs index 74fbbabb17a5..e61afd895deb 100644 --- a/library/std/src/os/netbsd/fs.rs +++ b/library/std/src/os/netbsd/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::netbsd::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/netbsd/net.rs b/library/std/src/os/netbsd/net.rs index e1950d349bf7..9174fee2f996 100644 --- a/library/std/src/os/netbsd/net.rs +++ b/library/std/src/os/netbsd/net.rs @@ -6,7 +6,7 @@ use crate::ffi::CStr; use crate::io; use crate::os::unix::net; use crate::sealed::Sealed; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// NetBSD-specific functionality for `AF_UNIX` sockets [`UnixDatagram`] /// and [`UnixStream`]. diff --git a/library/std/src/os/nto/fs.rs b/library/std/src/os/nto/fs.rs index 8f915b08c9e2..d371936c4336 100644 --- a/library/std/src/os/nto/fs.rs +++ b/library/std/src/os/nto/fs.rs @@ -1,7 +1,7 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { diff --git a/library/std/src/os/nuttx/fs.rs b/library/std/src/os/nuttx/fs.rs index 7d6d8d16eca7..f6c74bab9b45 100644 --- a/library/std/src/os/nuttx/fs.rs +++ b/library/std/src/os/nuttx/fs.rs @@ -1,7 +1,7 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { diff --git a/library/std/src/os/openbsd/fs.rs b/library/std/src/os/openbsd/fs.rs index e584098476a7..d3ca2426507a 100644 --- a/library/std/src/os/openbsd/fs.rs +++ b/library/std/src/os/openbsd/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::openbsd::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/redox/fs.rs b/library/std/src/os/redox/fs.rs index c6b813f0cc6c..0451e91071bc 100644 --- a/library/std/src/os/redox/fs.rs +++ b/library/std/src/os/redox/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::redox::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/rtems/fs.rs b/library/std/src/os/rtems/fs.rs index bec0d41e42d8..97a0c9004c00 100644 --- a/library/std/src/os/rtems/fs.rs +++ b/library/std/src/os/rtems/fs.rs @@ -1,7 +1,7 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/solaris/fs.rs b/library/std/src/os/solaris/fs.rs index 9b0527d71389..d32f57522860 100644 --- a/library/std/src/os/solaris/fs.rs +++ b/library/std/src/os/solaris/fs.rs @@ -3,7 +3,7 @@ use crate::fs::Metadata; #[allow(deprecated)] use crate::os::solaris::raw; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/solaris/net.rs b/library/std/src/os/solaris/net.rs index ca841f15b0e7..cea65f6ee701 100644 --- a/library/std/src/os/solaris/net.rs +++ b/library/std/src/os/solaris/net.rs @@ -5,7 +5,7 @@ use crate::io; use crate::os::unix::net; use crate::sealed::Sealed; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// solaris-specific functionality for `AF_UNIX` sockets [`UnixDatagram`] /// and [`UnixStream`]. diff --git a/library/std/src/os/solid/io.rs b/library/std/src/os/solid/io.rs index c23d842b238b..a1c8a86c9861 100644 --- a/library/std/src/os/solid/io.rs +++ b/library/std/src/os/solid/io.rs @@ -48,7 +48,7 @@ use crate::marker::PhantomData; use crate::mem::ManuallyDrop; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; use crate::{fmt, net, sys}; /// Raw file descriptors. diff --git a/library/std/src/os/unix/ffi/os_str.rs b/library/std/src/os/unix/ffi/os_str.rs index 650f712bc6ee..da47112f7cb4 100644 --- a/library/std/src/os/unix/ffi/os_str.rs +++ b/library/std/src/os/unix/ffi/os_str.rs @@ -2,7 +2,7 @@ use crate::ffi::{OsStr, OsString}; use crate::mem; use crate::sealed::Sealed; use crate::sys::os_str::Buf; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; // Note: this file is currently reused in other `std::os::{platform}::ffi` modules to reduce duplication. // Keep this in mind when applying changes to this file that only apply to `unix`. diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index 1d1a138b3025..219b340b9246 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -15,7 +15,7 @@ use crate::io::BorrowedCursor; use crate::os::unix::io::{AsFd, AsRawFd}; use crate::path::Path; use crate::sealed::Sealed; -use crate::sys_common::{AsInner, AsInnerMut, FromInner}; +use crate::sys::{AsInner, AsInnerMut, FromInner}; use crate::{io, sys}; // Tests for this module diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 163267be1e5c..beda370006f7 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -22,9 +22,8 @@ use crate::net::Shutdown; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::path::Path; use crate::sealed::Sealed; -use crate::sys::cvt; use crate::sys::net::Socket; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, cvt}; use crate::time::Duration; use crate::{fmt, io}; #[cfg(not(any( diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs index 5b4659e26188..99eef7f4013d 100644 --- a/library/std/src/os/unix/net/listener.rs +++ b/library/std/src/os/unix/net/listener.rs @@ -1,9 +1,8 @@ use super::{SocketAddr, UnixStream, sockaddr_un}; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::path::Path; -use crate::sys::cvt; use crate::sys::net::Socket; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, cvt}; use crate::{fmt, io, mem}; /// A structure representing a Unix domain socket server. diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 851ff7f08795..1fed1229d5ae 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -36,9 +36,8 @@ use crate::net::Shutdown; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::path::Path; use crate::sealed::Sealed; -use crate::sys::cvt; use crate::sys::net::Socket; -use crate::sys_common::{AsInner, FromInner}; +use crate::sys::{AsInner, FromInner, cvt}; use crate::time::Duration; /// A Unix stream socket. diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 74b46d297571..fab1b20b8c0e 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -9,7 +9,7 @@ use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, Owned use crate::path::Path; use crate::sealed::Sealed; use crate::sys::process::ChildPipe; -use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{io, process, sys}; cfg_select! { diff --git a/library/std/src/os/unix/thread.rs b/library/std/src/os/unix/thread.rs index 03dcc3a4f9ba..32085e525942 100644 --- a/library/std/src/os/unix/thread.rs +++ b/library/std/src/os/unix/thread.rs @@ -6,7 +6,7 @@ #[allow(deprecated)] use crate::os::unix::raw::pthread_t; -use crate::sys_common::{AsInner, IntoInner}; +use crate::sys::{AsInner, IntoInner}; use crate::thread::JoinHandle; #[stable(feature = "thread_extensions", since = "1.9.0")] diff --git a/library/std/src/os/vita/fs.rs b/library/std/src/os/vita/fs.rs index a5a06764a4dd..d796f02ba6a3 100644 --- a/library/std/src/os/vita/fs.rs +++ b/library/std/src/os/vita/fs.rs @@ -1,7 +1,7 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// diff --git a/library/std/src/os/vxworks/fs.rs b/library/std/src/os/vxworks/fs.rs index 77e6238ca1f5..b88ed19b067a 100644 --- a/library/std/src/os/vxworks/fs.rs +++ b/library/std/src/os/vxworks/fs.rs @@ -1,7 +1,7 @@ #![stable(feature = "metadata_ext", since = "1.1.0")] use crate::fs::Metadata; -use crate::sys_common::AsInner; +use crate::sys::AsInner; /// /// [`fs::Metadata`]: crate::fs::Metadata diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs index 9145283dae6e..248112cb369d 100644 --- a/library/std/src/os/wasi/fs.rs +++ b/library/std/src/os/wasi/fs.rs @@ -17,7 +17,7 @@ use crate::os::fd::AsRawFd; use crate::path::Path; #[cfg(target_env = "p1")] use crate::sys::err2io; -use crate::sys_common::{AsInner, AsInnerMut}; +use crate::sys::{AsInner, AsInnerMut}; /// WASI-specific extensions to [`File`]. pub trait FileExt { diff --git a/library/std/src/os/windows/ffi.rs b/library/std/src/os/windows/ffi.rs index 20e5383dc09e..fa115385c5d4 100644 --- a/library/std/src/os/windows/ffi.rs +++ b/library/std/src/os/windows/ffi.rs @@ -60,7 +60,7 @@ use crate::fmt; use crate::iter::FusedIterator; use crate::sealed::Sealed; use crate::sys::os_str::Buf; -use crate::sys_common::{AsInner, FromInner}; +use crate::sys::{AsInner, FromInner}; /// Windows-specific extensions to [`OsString`]. /// diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs index b445f368aeb1..c544bf485a25 100644 --- a/library/std/src/os/windows/fs.rs +++ b/library/std/src/os/windows/fs.rs @@ -8,7 +8,7 @@ use crate::fs::{self, Metadata, OpenOptions}; use crate::io::BorrowedCursor; use crate::path::Path; use crate::sealed::Sealed; -use crate::sys_common::{AsInner, AsInnerMut, IntoInner}; +use crate::sys::{AsInner, AsInnerMut, IntoInner}; use crate::time::SystemTime; use crate::{io, sys}; diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index 4fc04b79315f..afc58ca59cfa 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -5,8 +5,7 @@ use super::raw::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle}; use crate::marker::PhantomData; use crate::mem::ManuallyDrop; -use crate::sys::cvt; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, cvt}; use crate::{fmt, fs, io, ptr, sys}; /// A borrowed handle. diff --git a/library/std/src/os/windows/io/raw.rs b/library/std/src/os/windows/io/raw.rs index a3ec7440338d..0d3f24005f36 100644 --- a/library/std/src/os/windows/io/raw.rs +++ b/library/std/src/os/windows/io/raw.rs @@ -6,7 +6,7 @@ use crate::os::windows::io::{AsHandle, AsSocket}; use crate::os::windows::io::{OwnedHandle, OwnedSocket}; use crate::os::windows::raw; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; use crate::{fs, io, net, ptr, sys}; /// Raw HANDLEs. diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index b34b5d2802ca..b32c6cd442ff 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -10,7 +10,7 @@ use crate::os::windows::io::{ AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle, }; use crate::sealed::Sealed; -use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner}; use crate::{io, marker, process, ptr, sys}; #[stable(feature = "process_extensions", since = "1.2.0")] diff --git a/library/std/src/os/windows/thread.rs b/library/std/src/os/windows/thread.rs index d81d6d0ac28a..1cdee44de4b7 100644 --- a/library/std/src/os/windows/thread.rs +++ b/library/std/src/os/windows/thread.rs @@ -5,7 +5,7 @@ #![stable(feature = "thread_extensions", since = "1.9.0")] use crate::os::windows::io::{AsRawHandle, IntoRawHandle, RawHandle}; -use crate::sys_common::{AsInner, IntoInner}; +use crate::sys::{AsInner, IntoInner}; use crate::thread; #[stable(feature = "thread_extensions", since = "1.9.0")] diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 68bdf04d08b3..720ba0ad73e2 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -166,8 +166,7 @@ use crate::io::prelude::*; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::num::NonZero; use crate::path::Path; -use crate::sys::process as imp; -use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, process as imp}; use crate::{fmt, fs, str}; /// Representation of a running or exited child process. diff --git a/library/std/src/sys/args/sgx.rs b/library/std/src/sys/args/sgx.rs index f800500c22a8..6ff94f5681b6 100644 --- a/library/std/src/sys/args/sgx.rs +++ b/library/std/src/sys/args/sgx.rs @@ -4,10 +4,10 @@ use crate::ffi::OsString; use crate::num::NonZero; use crate::ops::Try; use crate::sync::atomic::{Atomic, AtomicUsize, Ordering}; +use crate::sys::FromInner; use crate::sys::os_str::Buf; use crate::sys::pal::abi::usercalls::alloc; use crate::sys::pal::abi::usercalls::raw::ByteBuffer; -use crate::sys_common::FromInner; use crate::{fmt, slice}; // Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests diff --git a/library/std/src/sys/args/windows.rs b/library/std/src/sys/args/windows.rs index 81c44fabdcc6..b4de759e1a4c 100644 --- a/library/std/src/sys/args/windows.rs +++ b/library/std/src/sys/args/windows.rs @@ -14,8 +14,7 @@ use crate::path::{Path, PathBuf}; use crate::sys::pal::os::current_exe; use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf}; use crate::sys::path::get_long_path; -use crate::sys::{c, to_u16s}; -use crate::sys_common::AsInner; +use crate::sys::{AsInner, c, to_u16s}; use crate::sys_common::wstr::WStrUnits; use crate::{io, iter, ptr}; diff --git a/library/std/src/sys/env/zkvm.rs b/library/std/src/sys/env/zkvm.rs index 2eb7005ba128..b672a03bf0ba 100644 --- a/library/std/src/sys/env/zkvm.rs +++ b/library/std/src/sys/env/zkvm.rs @@ -4,9 +4,8 @@ mod unsupported_env; pub use unsupported_env::{Env, env, setenv, unsetenv}; use crate::ffi::{OsStr, OsString}; -use crate::sys::os_str; use crate::sys::pal::{WORD_SIZE, abi}; -use crate::sys_common::FromInner; +use crate::sys::{FromInner, os_str}; pub fn getenv(varname: &OsStr) -> Option { let varname = varname.as_encoded_bytes(); diff --git a/library/std/src/sys/fd/hermit.rs b/library/std/src/sys/fd/hermit.rs index afcd8c635541..28fafdaf57d8 100644 --- a/library/std/src/sys/fd/hermit.rs +++ b/library/std/src/sys/fd/hermit.rs @@ -4,8 +4,7 @@ use crate::cmp; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, SeekFrom}; use crate::os::hermit::hermit_abi; use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::sys::{cvt, unsupported}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, cvt, unsupported}; const fn max_iov() -> usize { hermit_abi::IOV_MAX diff --git a/library/std/src/sys/fd/motor.rs b/library/std/src/sys/fd/motor.rs index 4211fef8007a..edeb99ccf8ef 100644 --- a/library/std/src/sys/fd/motor.rs +++ b/library/std/src/sys/fd/motor.rs @@ -2,8 +2,7 @@ use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read}; use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::sys::map_motor_error; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, map_motor_error}; #[derive(Debug)] pub struct FileDesc(OwnedFd); diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index 33fff36b35b0..c5e8646dada1 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -36,12 +36,11 @@ cfg_select! { use crate::cmp; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read}; use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::sys::cvt; #[cfg(all(target_os = "android", target_pointer_width = "64"))] use crate::sys::pal::weak::syscall; #[cfg(any(all(target_os = "android", target_pointer_width = "32"), target_vendor = "apple"))] use crate::sys::pal::weak::weak; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, cvt}; #[derive(Debug)] pub struct FileDesc(OwnedFd); diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index 21235bcfbd8c..0914e4b6c907 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -13,8 +13,7 @@ use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::fd::FileDesc; pub use crate::sys::fs::common::{copy, exists}; use crate::sys::time::SystemTime; -use crate::sys::{cvt, unsupported, unsupported_err}; -use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, cvt, unsupported, unsupported_err}; use crate::{fmt, mem}; #[derive(Debug)] diff --git a/library/std/src/sys/fs/motor.rs b/library/std/src/sys/fs/motor.rs index f723a23bd5df..8f3336e2fa96 100644 --- a/library/std/src/sys/fs/motor.rs +++ b/library/std/src/sys/fs/motor.rs @@ -6,8 +6,7 @@ use crate::path::{Path, PathBuf}; use crate::sys::fd::FileDesc; pub use crate::sys::fs::common::exists; use crate::sys::time::SystemTime; -use crate::sys::{map_motor_error, unsupported}; -use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, map_motor_error, unsupported}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct FileType { diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 74206405bfe7..ee3cb54a5ee6 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -97,8 +97,7 @@ use crate::sys::time::SystemTime; use crate::sys::weak::syscall; #[cfg(target_os = "android")] use crate::sys::weak::weak; -use crate::sys::{cvt, cvt_r}; -use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, cvt, cvt_r}; use crate::{mem, ptr}; pub struct File(FileDesc); diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index f2d325da35c7..b588b91c753b 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -15,8 +15,7 @@ use crate::sys::pal::api::{self, WinError, set_file_information_by_handle}; use crate::sys::pal::{IoResult, fill_utf16_buf, to_u16s, truncate_utf16_at_nul}; use crate::sys::path::{WCStr, maybe_verbatim}; use crate::sys::time::SystemTime; -use crate::sys::{Align8, c, cvt}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{Align8, AsInner, FromInner, IntoInner, c, cvt}; use crate::{fmt, ptr, slice}; mod remove_dir_all; diff --git a/library/std/src/sys/net/connection/motor.rs b/library/std/src/sys/net/connection/motor.rs index e9bf29e34f90..9beed0779752 100644 --- a/library/std/src/sys/net/connection/motor.rs +++ b/library/std/src/sys/net/connection/motor.rs @@ -5,8 +5,7 @@ use crate::net::SocketAddr::{V4, V6}; use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs}; use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::sys::fd::FileDesc; -use crate::sys::map_motor_error; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, map_motor_error}; use crate::time::Duration; // We want to re-use as much of Rust's stdlib code as possible, diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs index f044bf8dfae0..8350d2b5fe4a 100644 --- a/library/std/src/sys/net/connection/socket/hermit.rs +++ b/library/std/src/sys/net/connection/socket/hermit.rs @@ -10,8 +10,8 @@ use crate::net::{Shutdown, SocketAddr}; use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd}; use crate::sys::fd::FileDesc; use crate::sys::time::Instant; +use crate::sys::{AsInner, FromInner, IntoInner}; pub use crate::sys::{cvt, cvt_r}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::Duration; use crate::{cmp, mem}; diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs index 63d5c1d23124..c6df9c6b8ae1 100644 --- a/library/std/src/sys/net/connection/socket/mod.rs +++ b/library/std/src/sys/net/connection/socket/mod.rs @@ -9,7 +9,7 @@ use crate::net::{ }; use crate::sys::common::small_c_string::run_with_cstr; use crate::sys::net::connection::each_addr; -use crate::sys_common::{AsInner, FromInner}; +use crate::sys::{AsInner, FromInner}; use crate::time::Duration; use crate::{cmp, fmt, mem, ptr}; diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs index 731157ec319c..ac06cdc00c8f 100644 --- a/library/std/src/sys/net/connection/socket/solid.rs +++ b/library/std/src/sys/net/connection/socket/solid.rs @@ -6,8 +6,7 @@ use crate::ffi::CStr; use crate::io::{self, BorrowedBuf, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut}; use crate::net::{Shutdown, SocketAddr}; use crate::os::solid::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd}; -use crate::sys::abi; -use crate::sys_common::{FromInner, IntoInner}; +use crate::sys::{FromInner, IntoInner, abi}; use crate::time::Duration; use crate::{cmp, mem, ptr, str}; diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index d30f6054077d..323d6214347e 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -8,7 +8,7 @@ use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::sys::fd::FileDesc; use crate::sys::net::{getsockopt, setsockopt}; use crate::sys::pal::IsMinusOne; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; use crate::time::{Duration, Instant}; use crate::{cmp, mem}; diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index 08196d61aa30..4da51d78ea69 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs @@ -8,9 +8,8 @@ use crate::net::{Shutdown, SocketAddr}; use crate::os::windows::io::{ AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket, }; -use crate::sys::c; use crate::sys::pal::winsock::last_error; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, c}; use crate::time::Duration; use crate::{cmp, mem, ptr, sys}; diff --git a/library/std/src/sys/net/connection/wasip1.rs b/library/std/src/sys/net/connection/wasip1.rs index 3a0ac5552a64..95a4ab2fbf0f 100644 --- a/library/std/src/sys/net/connection/wasip1.rs +++ b/library/std/src/sys/net/connection/wasip1.rs @@ -5,8 +5,7 @@ use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs}; use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::sys::fd::FileDesc; -use crate::sys::{err2io, unsupported}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, err2io, unsupported}; use crate::time::Duration; pub struct Socket(FileDesc); diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 258279bd4a60..7ba6c46eaef4 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -8,7 +8,7 @@ use crate::collections::TryReserveError; use crate::fmt::Write; use crate::rc::Rc; use crate::sync::Arc; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; use crate::{fmt, mem, str}; #[cfg(test)] diff --git a/library/std/src/sys/os_str/utf8.rs b/library/std/src/sys/os_str/utf8.rs index 5dd24f67d303..a324a478325e 100644 --- a/library/std/src/sys/os_str/utf8.rs +++ b/library/std/src/sys/os_str/utf8.rs @@ -6,7 +6,7 @@ use crate::borrow::Cow; use crate::collections::TryReserveError; use crate::rc::Rc; use crate::sync::Arc; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; use crate::{fmt, mem}; #[derive(Hash)] diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index 5050fd279433..1f130d91cf39 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -8,7 +8,7 @@ use crate::borrow::Cow; use crate::collections::TryReserveError; use crate::rc::Rc; use crate::sync::Arc; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner}; use crate::{fmt, mem}; #[derive(Hash)] diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 5d57be59aadf..7a207ceb329e 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -120,8 +120,6 @@ pub extern "C" fn __rust_abort() { abort_internal(); } -pub use crate::sys_common::{AsInner, FromInner, IntoInner}; - pub trait TryIntoInner: Sized { fn try_into_inner(self) -> Result; } diff --git a/library/std/src/sys/pal/unix/linux/pidfd.rs b/library/std/src/sys/pal/unix/linux/pidfd.rs index 47e9a616bfda..7859854e96b4 100644 --- a/library/std/src/sys/pal/unix/linux/pidfd.rs +++ b/library/std/src/sys/pal/unix/linux/pidfd.rs @@ -1,9 +1,8 @@ use crate::io; use crate::os::fd::{AsRawFd, FromRawFd, RawFd}; -use crate::sys::cvt; use crate::sys::fd::FileDesc; use crate::sys::process::ExitStatus; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, cvt}; #[cfg(test)] mod tests; diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 1b3fbeee4d90..598bf994b3e5 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -1,6 +1,6 @@ use core::num::niche_types::Nanoseconds; -use crate::sys_common::AsInner; +use crate::sys::AsInner; use crate::time::Duration; use crate::{fmt, io}; diff --git a/library/std/src/sys/pal/windows/handle.rs b/library/std/src/sys/pal/windows/handle.rs index fc17e0b5ebd3..ffa8507831ac 100644 --- a/library/std/src/sys/pal/windows/handle.rs +++ b/library/std/src/sys/pal/windows/handle.rs @@ -7,8 +7,7 @@ use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, Read}; use crate::os::windows::io::{ AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle, }; -use crate::sys::{c, cvt}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, c, cvt}; /// An owned container for `HANDLE` object, closing them on Drop. /// diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs index 6cccf090a3fc..ecd46c950b5e 100644 --- a/library/std/src/sys/pal/windows/time.rs +++ b/library/std/src/sys/pal/windows/time.rs @@ -3,8 +3,7 @@ use core::ops::Neg; use crate::cmp::Ordering; use crate::ptr::null; -use crate::sys::c; -use crate::sys_common::IntoInner; +use crate::sys::{IntoInner, c}; use crate::time::Duration; use crate::{fmt, mem}; diff --git a/library/std/src/sys/pipe/unsupported.rs b/library/std/src/sys/pipe/unsupported.rs index 115e913e0f33..1c5df47c9581 100644 --- a/library/std/src/sys/pipe/unsupported.rs +++ b/library/std/src/sys/pipe/unsupported.rs @@ -60,7 +60,7 @@ impl fmt::Debug for Pipe { mod unix_traits { use super::Pipe; use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; - use crate::sys_common::{FromInner, IntoInner}; + use crate::sys::{FromInner, IntoInner}; impl AsRawFd for Pipe { #[inline] diff --git a/library/std/src/sys/process/motor.rs b/library/std/src/sys/process/motor.rs index 7a23a5d902c0..97b5a0fce2e4 100644 --- a/library/std/src/sys/process/motor.rs +++ b/library/std/src/sys/process/motor.rs @@ -8,8 +8,7 @@ use crate::os::motor::ffi::OsStrExt; use crate::path::Path; use crate::process::StdioPipes; use crate::sys::fs::File; -use crate::sys::map_motor_error; -use crate::sys_common::{AsInner, FromInner}; +use crate::sys::{AsInner, FromInner, map_motor_error}; use crate::{fmt, io}; pub enum Stdio { diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index d4344d1191a4..2e1cd7068d7f 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -10,14 +10,13 @@ use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::os::unix::prelude::*; use crate::path::Path; use crate::process::StdioPipes; -use crate::sys::cvt_r; use crate::sys::fd::FileDesc; use crate::sys::fs::File; #[cfg(not(target_os = "fuchsia"))] use crate::sys::fs::OpenOptions; use crate::sys::pipe::pipe; use crate::sys::process::env::{CommandEnv, CommandEnvs}; -use crate::sys_common::{FromInner, IntoInner}; +use crate::sys::{FromInner, IntoInner, cvt_r}; use crate::{fmt, io, mem}; mod cstring_array; diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index d14caf6dc88d..5ba57e11679c 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -966,7 +966,7 @@ impl Process { /// [I/O Safety]: crate::io#io-safety unsafe fn new(pid: pid_t, pidfd: pid_t) -> Self { use crate::os::unix::io::FromRawFd; - use crate::sys_common::FromInner; + use crate::sys::FromInner; // Safety: If `pidfd` is nonnegative, we assume it's valid and otherwise unowned. let pidfd = (pidfd >= 0).then(|| PidFd::from_inner(sys::fd::FileDesc::from_raw_fd(pidfd))); Process { pid, status: None, pidfd } @@ -1264,8 +1264,8 @@ impl ExitStatusError { mod linux_child_ext { use crate::io::ErrorKind; use crate::os::linux::process as os; + use crate::sys::FromInner; use crate::sys::pal::linux::pidfd as imp; - use crate::sys_common::FromInner; use crate::{io, mem}; #[unstable(feature = "linux_pidfd", issue = "82971")] diff --git a/library/std/src/sys/process/windows.rs b/library/std/src/sys/process/windows.rs index 85b9682320d2..dba647c502d1 100644 --- a/library/std/src/sys/process/windows.rs +++ b/library/std/src/sys/process/windows.rs @@ -23,8 +23,7 @@ use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; use crate::sys::pal::api::{self, WinError, utf16}; use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf}; -use crate::sys::{cvt, path, stdio}; -use crate::sys_common::IntoInner; +use crate::sys::{IntoInner, cvt, path, stdio}; use crate::{cmp, env, fmt, ptr}; mod child_pipe; diff --git a/library/std/src/sys/process/windows/child_pipe.rs b/library/std/src/sys/process/windows/child_pipe.rs index 6b00c54407ad..b848435ac275 100644 --- a/library/std/src/sys/process/windows/child_pipe.rs +++ b/library/std/src/sys/process/windows/child_pipe.rs @@ -2,8 +2,7 @@ use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::ops::Neg; use crate::os::windows::prelude::*; use crate::sys::handle::Handle; -use crate::sys::{api, c}; -use crate::sys_common::{FromInner, IntoInner}; +use crate::sys::{FromInner, IntoInner, api, c}; use crate::{mem, ptr}; pub struct ChildPipe { diff --git a/library/std/src/sys/stdio/motor.rs b/library/std/src/sys/stdio/motor.rs index e268bd5413df..2b1bc15285f9 100644 --- a/library/std/src/sys/stdio/motor.rs +++ b/library/std/src/sys/stdio/motor.rs @@ -1,6 +1,5 @@ use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::sys::map_motor_error; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys::{AsInner, FromInner, IntoInner, map_motor_error}; use crate::{io, process, sys}; pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE; diff --git a/library/std/src/sys/thread/windows.rs b/library/std/src/sys/thread/windows.rs index 1ef496a20cfe..6a21b11e0312 100644 --- a/library/std/src/sys/thread/windows.rs +++ b/library/std/src/sys/thread/windows.rs @@ -6,8 +6,7 @@ use crate::os::windows::io::{AsRawHandle, HandleOrNull}; use crate::sys::handle::Handle; use crate::sys::pal::time::WaitableTimer; use crate::sys::pal::{dur2timeout, to_u16s}; -use crate::sys::{c, stack_overflow}; -use crate::sys_common::FromInner; +use crate::sys::{FromInner, c, stack_overflow}; use crate::thread::ThreadInit; use crate::time::Duration; use crate::{io, ptr}; diff --git a/library/std/src/thread/join_handle.rs b/library/std/src/thread/join_handle.rs index 8714ceeb4f46..7112fe44f907 100644 --- a/library/std/src/thread/join_handle.rs +++ b/library/std/src/thread/join_handle.rs @@ -2,8 +2,7 @@ use super::Result; use super::lifecycle::JoinInner; use super::thread::Thread; use crate::fmt; -use crate::sys::thread as imp; -use crate::sys_common::{AsInner, IntoInner}; +use crate::sys::{AsInner, IntoInner, thread as imp}; /// An owned permission to join on a thread (block on its termination). /// diff --git a/library/std/src/thread/lifecycle.rs b/library/std/src/thread/lifecycle.rs index a48594c606a3..0bb1f347ffaa 100644 --- a/library/std/src/thread/lifecycle.rs +++ b/library/std/src/thread/lifecycle.rs @@ -10,8 +10,7 @@ use crate::marker::PhantomData; use crate::mem::{ManuallyDrop, MaybeUninit}; use crate::sync::Arc; use crate::sync::atomic::{Atomic, AtomicUsize, Ordering}; -use crate::sys::thread as imp; -use crate::sys_common::{AsInner, IntoInner}; +use crate::sys::{AsInner, IntoInner, thread as imp}; use crate::{env, io, panic}; #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 67c144be14f6..0fc23fdf96a2 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -39,8 +39,7 @@ pub use core::time::TryFromFloatSecsError; use crate::error::Error; use crate::fmt; use crate::ops::{Add, AddAssign, Sub, SubAssign}; -use crate::sys::time; -use crate::sys_common::{FromInner, IntoInner}; +use crate::sys::{FromInner, IntoInner, time}; /// A measurement of a monotonically nondecreasing clock. /// Opaque and useful only with [`Duration`]. From 7cf35566e366a3e251cb3e9e2da9c075ee71d62c Mon Sep 17 00:00:00 2001 From: David <75451291+david-d-h@users.noreply.github.com> Date: Mon, 15 Dec 2025 14:09:13 +0100 Subject: [PATCH 0823/3801] document that mpmc channels deliver an item to (at most) one receiver --- library/std/src/sync/mpmc/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs index 673033034eff..ee9795a52812 100644 --- a/library/std/src/sync/mpmc/mod.rs +++ b/library/std/src/sync/mpmc/mod.rs @@ -6,9 +6,10 @@ //! * [`Sender`] //! * [`Receiver`] //! -//! [`Sender`]s are used to send data to a set of [`Receiver`]s. Both -//! sender and receiver are cloneable (multi-producer) such that many threads can send -//! simultaneously to receivers (multi-consumer). +//! [`Sender`]s are used to send data to a set of [`Receiver`]s where each item +//! sent is delivered to (at most) one receiver. Both sender and receiver are +//! cloneable (multi-producer) such that many threads can send simultaneously +//! to receivers (multi-consumer). //! //! These channels come in two flavors: //! From 9c14e3f6317124684da58dd4923427dff40468d5 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sat, 29 Nov 2025 23:22:40 +0530 Subject: [PATCH 0824/3801] std: sys: fs: uefi: Implement set_times and set_perm - Tested on QEMU OVMF. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 52 ++++++++++++++++++++----- library/std/src/sys/pal/uefi/helpers.rs | 4 ++ 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 44f8b6e80f90..21ef70b43dcd 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -9,7 +9,6 @@ use crate::path::{Path, PathBuf}; use crate::sys::time::SystemTime; use crate::sys::{helpers, unsupported}; -#[expect(dead_code)] const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY; pub struct File(!); @@ -109,7 +108,6 @@ impl FilePermissions { Self(attr & r_efi::protocols::file::READ_ONLY != 0) } - #[expect(dead_code)] const fn to_attr(&self) -> u64 { if self.0 { r_efi::protocols::file::READ_ONLY } else { 0 } } @@ -366,16 +364,40 @@ pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> { unsupported() } -pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { - unsupported() +pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { + let f = uefi_fs::File::from_path(p, file::MODE_READ | file::MODE_WRITE, 0)?; + let mut file_info = f.file_info()?; + + unsafe { + (*file_info.as_mut_ptr()).attribute = + ((*file_info.as_ptr()).attribute & !FILE_PERMISSIONS_MASK) | perm.to_attr() + }; + + f.set_file_info(file_info) } -pub fn set_times(_p: &Path, _times: FileTimes) -> io::Result<()> { - unsupported() +pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> { + // UEFI does not support symlinks + set_times_nofollow(p, times) } -pub fn set_times_nofollow(_p: &Path, _times: FileTimes) -> io::Result<()> { - unsupported() +pub fn set_times_nofollow(p: &Path, times: FileTimes) -> io::Result<()> { + let f = uefi_fs::File::from_path(p, file::MODE_READ | file::MODE_WRITE, 0)?; + let mut file_info = f.file_info()?; + + if let Some(x) = times.accessed { + unsafe { + (*file_info.as_mut_ptr()).last_access_time = uefi_fs::systemtime_to_uefi(x); + } + } + + if let Some(x) = times.modified { + unsafe { + (*file_info.as_mut_ptr()).modification_time = uefi_fs::systemtime_to_uefi(x); + } + } + + f.set_file_info(file_info) } pub fn rmdir(p: &Path) -> io::Result<()> { @@ -560,6 +582,17 @@ mod uefi_fs { if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(info) } } + pub(crate) fn set_file_info(&self, mut info: UefiBox) -> io::Result<()> { + let file_ptr = self.0.as_ptr(); + let mut info_id = file::INFO_ID; + + let r = unsafe { + ((*file_ptr).set_info)(file_ptr, &mut info_id, info.len(), info.as_mut_ptr().cast()) + }; + + if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } + } + pub(crate) fn delete(self) -> io::Result<()> { let file_ptr = self.0.as_ptr(); let r = unsafe { ((*file_ptr).delete)(file_ptr) }; @@ -643,8 +676,7 @@ mod uefi_fs { } /// Convert to UEFI Time with the current timezone. - #[expect(dead_code)] - fn systemtime_to_uefi(time: SystemTime) -> r_efi::efi::Time { + pub(crate) fn systemtime_to_uefi(time: SystemTime) -> r_efi::efi::Time { let now = time::system_time_internal::now(); time.to_uefi_loose(now.timezone, now.daylight) } diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index bfad6491e321..d059be010e98 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -802,6 +802,10 @@ impl UefiBox { pub(crate) fn as_ptr(&self) -> *const T { self.inner.as_ptr().cast() } + + pub(crate) const fn len(&self) -> usize { + self.size + } } impl Drop for UefiBox { From 95c38b2bbaa666c52268902c3dff108615cfa63d Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 8 Nov 2025 11:36:01 -0500 Subject: [PATCH 0825/3801] Add libgccjit-libs-dir config --- bootstrap.example.toml | 25 +++ src/bootstrap/src/core/build_steps/compile.rs | 187 ++++++++++++++++-- src/bootstrap/src/core/build_steps/dist.rs | 6 +- src/bootstrap/src/core/build_steps/gcc.rs | 155 ++++++++++----- src/bootstrap/src/core/build_steps/test.rs | 7 +- src/bootstrap/src/core/config/config.rs | 7 +- src/bootstrap/src/core/config/toml/gcc.rs | 1 + src/bootstrap/src/lib.rs | 4 - 8 files changed, 313 insertions(+), 79 deletions(-) diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 4e850810a30a..63bf50722ca0 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -191,6 +191,31 @@ # Currently, this is only supported for the `x86_64-unknown-linux-gnu` target. #gcc.download-ci-gcc = false +# Provide a directory of prebuilt libgccjit.so dylibs for given (host, target) compilation pairs. +# This is useful when you want to cross-compile `rustc` to another target since GCC is not a +# multi-target compiler. +# You have to use a directory structure that looks like this: +# `///libgccjit.so`. +# For example: +# +# ``` +# +# ├── m68k-unknown-linux-gnu +# │ └── m68k-unknown-linux-gnu +# │ └── libgccjit.so +# └── x86_64-unknown-linux-gnu +# ├── m68k-unknown-linux-gnu +# │ └── libgccjit.so +# └── x86_64-unknown-linux-gnu +# └── libgccjit.so +# ``` +# The directory above would allow you to cross-compile rustc from x64 to m68k +# +# Note that this option has priority over `gcc.download-ci-gcc`. +# If you set both, bootstrap will first try to load libgccjit.so from this directory. +# Only if it isn't found, it will try to download it from CI or build it locally. +#gcc.libgccjit-libs-dir = "/path/to/libgccjit-libs-dir" + # ============================================================================= # General build configuration options # ============================================================================= diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 82cc25f123bc..9adf889def00 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -7,7 +7,7 @@ //! goes along from the output of the previous stage. use std::borrow::Cow; -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap, HashSet}; use std::ffi::OsStr; use std::io::BufReader; use std::io::prelude::*; @@ -19,7 +19,7 @@ use serde_derive::Deserialize; #[cfg(feature = "tracing")] use tracing::span; -use crate::core::build_steps::gcc::{Gcc, GccOutput, add_cg_gcc_cargo_flags}; +use crate::core::build_steps::gcc::{Gcc, GccOutput, GccTargetPair, add_cg_gcc_cargo_flags}; use crate::core::build_steps::tool::{RustcPrivateCompilers, SourceType, copy_lld_artifacts}; use crate::core::build_steps::{dist, llvm}; use crate::core::builder; @@ -1576,17 +1576,98 @@ impl Step for RustcLink { } } +/// Set of `libgccjit` dylibs that can be used by `cg_gcc` to compile code for a set of targets. +#[derive(Clone)] +pub struct GccDylibSet { + dylibs: BTreeMap, + host_pair: GccTargetPair, +} + +impl GccDylibSet { + /// Returns the libgccjit.so dylib that corresponds to a host target on which `cg_gcc` will be + /// executed, and which will target the host. So e.g. if `cg_gcc` will be executed on + /// x86_64-unknown-linux-gnu, the host dylib will be for compilation pair + /// `(x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu)`. + fn host_dylib(&self) -> &GccOutput { + self.dylibs.get(&self.host_pair).unwrap_or_else(|| { + panic!("libgccjit.so was not built for host target {}", self.host_pair) + }) + } + + /// Install the libgccjit dylibs to the corresponding target directories of the given compiler. + /// cg_gcc know how to search for the libgccjit dylibs in these directories, according to the + /// (host, target) pair that is being compiled by rustc and cg_gcc. + pub fn install_to(&self, builder: &Builder<'_>, compiler: Compiler) { + if builder.config.dry_run() { + return; + } + + // /lib//codegen-backends + let cg_sysroot = builder.sysroot_codegen_backends(compiler); + + for (target_pair, libgccjit) in &self.dylibs { + assert_eq!( + target_pair.host(), + compiler.host, + "Trying to install libgccjit ({target_pair}) to a compiler with a different host ({})", + compiler.host + ); + let libgccjit = libgccjit.libgccjit(); + let target_filename = libgccjit.file_name().unwrap().to_str().unwrap(); + + // If we build libgccjit ourselves, then `libgccjit` can actually be a symlink. + // In that case, we have to resolve it first, otherwise we'd create a symlink to a + // symlink, which wouldn't work. + let actual_libgccjit_path = t!( + libgccjit.canonicalize(), + format!("Cannot find libgccjit at {}", libgccjit.display()) + ); + + // /lib//libgccjit.so + let dest_dir = cg_sysroot.join("lib").join(target_pair.target()); + t!(fs::create_dir_all(&dest_dir)); + let dst = dest_dir.join(target_filename); + builder.copy_link(&actual_libgccjit_path, &dst, FileType::NativeLibrary); + } + } +} + /// Output of the `compile::GccCodegenBackend` step. -/// It includes the path to the libgccjit library on which this backend depends. +/// +/// It contains paths to all built libgccjit libraries on which this backend depends here. #[derive(Clone)] pub struct GccCodegenBackendOutput { stamp: BuildStamp, - gcc: GccOutput, + dylib_set: GccDylibSet, } +/// Builds the GCC codegen backend (`cg_gcc`). +/// The `cg_gcc` backend uses `libgccjit`, which requires a separate build for each +/// `host -> target` pair. So if you are on linux-x64 and build for linux-aarch64, +/// you will need at least: +/// - linux-x64 -> linux-x64 libgccjit (for building host code like proc macros) +/// - linux-x64 -> linux-aarch64 libgccjit (for the aarch64 target code) +/// +/// We model this by having a single cg_gcc for a given host target, which contains one +/// libgccjit per (host, target) pair. +/// Note that the host target is taken from `self.compilers.target_compiler.host`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct GccCodegenBackend { compilers: RustcPrivateCompilers, + targets: Vec, +} + +impl GccCodegenBackend { + /// Build `cg_gcc` that will run on host `H` (`compilers.target_compiler.host`) and will be + /// able to produce code target pairs (`H`, `T`) for all `T` from `targets`. + pub fn for_targets( + compilers: RustcPrivateCompilers, + mut targets: Vec, + ) -> Self { + // Sort targets to improve step cache hits + targets.sort(); + Self { compilers, targets } + } } impl Step for GccCodegenBackend { @@ -1599,23 +1680,34 @@ impl Step for GccCodegenBackend { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(GccCodegenBackend { - compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), - }); + // By default, build cg_gcc that will only be able to compile native code for the given + // host target. + let compilers = RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target); + run.builder.ensure(GccCodegenBackend { compilers, targets: vec![run.target] }); } fn run(self, builder: &Builder<'_>) -> Self::Output { - let target = self.compilers.target(); + let host = self.compilers.target(); let build_compiler = self.compilers.build_compiler(); let stamp = build_stamp::codegen_backend_stamp( builder, build_compiler, - target, + host, &CodegenBackendKind::Gcc, ); - let gcc = builder.ensure(Gcc { target }); + let dylib_set = GccDylibSet { + dylibs: self + .targets + .iter() + .map(|&target| { + let target_pair = GccTargetPair::for_target_pair(host, target); + (target_pair, builder.ensure(Gcc { target_pair })) + }) + .collect(), + host_pair: GccTargetPair::for_native_build(host), + }; if builder.config.keep_stage.contains(&build_compiler.stage) { trace!("`keep-stage` requested"); @@ -1625,7 +1717,7 @@ impl Step for GccCodegenBackend { ); // Codegen backends are linked separately from this step today, so we don't do // anything here. - return GccCodegenBackendOutput { stamp, gcc }; + return GccCodegenBackendOutput { stamp, dylib_set }; } let mut cargo = builder::Cargo::new( @@ -1633,21 +1725,21 @@ impl Step for GccCodegenBackend { build_compiler, Mode::Codegen, SourceType::InTree, - target, + host, Kind::Build, ); cargo.arg("--manifest-path").arg(builder.src.join("compiler/rustc_codegen_gcc/Cargo.toml")); - rustc_cargo_env(builder, &mut cargo, target); + rustc_cargo_env(builder, &mut cargo, host); - add_cg_gcc_cargo_flags(&mut cargo, &gcc); + add_cg_gcc_cargo_flags(&mut cargo, dylib_set.host_dylib()); let _guard = - builder.msg(Kind::Build, "codegen backend gcc", Mode::Codegen, build_compiler, target); + builder.msg(Kind::Build, "codegen backend gcc", Mode::Codegen, build_compiler, host); let files = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false); GccCodegenBackendOutput { stamp: write_codegen_backend_stamp(stamp, files, builder.config.dry_run()), - gcc, + dylib_set, } } @@ -2324,12 +2416,65 @@ impl Step for Assemble { copy_codegen_backends_to_sysroot(builder, stamp, target_compiler); } CodegenBackendKind::Gcc => { - let output = - builder.ensure(GccCodegenBackend { compilers: prepare_compilers() }); + // We need to build cg_gcc for the host target of the compiler which we + // build here, which is `target_compiler`. + // But we also need to build libgccjit for some additional targets, in + // the most general case. + // 1. We need to build (target_compiler.host, stdlib target) libgccjit + // for all stdlibs that we build, so that cg_gcc can be used to build code + // for all those targets. + // 2. We need to build (target_compiler.host, target_compiler.host) + // libgccjit, so that the target compiler can compile host code (e.g. proc + // macros). + // 3. We need to build (target_compiler.host, host target) libgccjit + // for all *host targets* that we build, so that cg_gcc can be used to + // build a (possibly cross-compiled) stage 2+ rustc. + // + // Assume that we are on host T1 and we do a stage2 build of rustc for T2. + // We want the T2 rustc compiler to be able to use cg_gcc and build code + // for T2 (host) and T3 (target). We also want to build the stage2 compiler + // itself using cg_gcc. + // This could correspond to the following bootstrap invocation: + // `x build rustc --build T1 --host T2 --target T3 --set codegen-backends=['gcc', 'llvm']` + // + // For that, we will need the following GCC target pairs: + // 1. T1 -> T2 (to cross-compile a T2 rustc using cg_gcc running on T1) + // 2. T2 -> T2 (to build host code with the stage 2 rustc running on T2) + // 3. T2 -> T3 (to cross-compile code with the stage 2 rustc running on T2) + // + // FIXME: this set of targets is *maximal*, in reality we might need + // less libgccjits at this current build stage. Try to reduce the set of + // GCC dylibs built below by taking a look at the current stage and whether + // cg_gcc is used as the default codegen backend. + + let compilers = prepare_compilers(); + + // The left side of the target pairs below is implied. It has to match the + // host target on which cg_gcc will run, which is the host target of + // `target_compiler`. We only pass the right side of the target pairs to + // the `GccCodegenBackend` constructor. + let mut targets = HashSet::new(); + // Add all host targets, so that we are able to build host code in this + // bootstrap invocation using cg_gcc. + for target in &builder.hosts { + targets.insert(*target); + } + // Add all stdlib targets, so that the built rustc can produce code for them + for target in &builder.targets { + targets.insert(*target); + } + // Add the host target of the built rustc itself, so that it can build + // host code (e.g. proc macros) using cg_gcc. + targets.insert(compilers.target_compiler().host); + + let output = builder.ensure(GccCodegenBackend::for_targets( + compilers, + targets.into_iter().collect(), + )); copy_codegen_backends_to_sysroot(builder, output.stamp, target_compiler); - // Also copy libgccjit to the library sysroot, so that it is available for - // the codegen backend. - output.gcc.install_to(builder, &rustc_libdir); + // Also copy all requires libgccjit dylibs to the corresponding + // library sysroots, so that they are available for the codegen backend. + output.dylib_set.install_to(builder, target_compiler); } CodegenBackendKind::Llvm | CodegenBackendKind::Custom(_) => continue, } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index caf0af35e401..cbbdc7e02419 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -21,6 +21,7 @@ use tracing::instrument; use crate::core::build_steps::compile::{get_codegen_backend_file, normalize_codegen_backend_name}; use crate::core::build_steps::doc::DocumentationFormat; +use crate::core::build_steps::gcc::GccTargetPair; use crate::core::build_steps::tool::{ self, RustcPrivateCompilers, ToolTargetBuildMode, get_tool_target_compiler, }; @@ -2856,8 +2857,9 @@ impl Step for Gcc { fn run(self, builder: &Builder<'_>) -> Self::Output { let tarball = Tarball::new(builder, "gcc", &self.target.triple); - let output = builder.ensure(super::gcc::Gcc { target: self.target }); - tarball.add_file(&output.libgccjit, "lib", FileType::NativeLibrary); + let output = builder + .ensure(super::gcc::Gcc { target_pair: GccTargetPair::for_native_build(self.target) }); + tarball.add_file(output.libgccjit(), "lib", FileType::NativeLibrary); tarball.generate() } diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index fc87c48f17b6..9cc5d0ed71b1 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -8,49 +8,69 @@ //! GCC and compiler-rt are essentially just wired up to everything else to //! ensure that they're always in place if needed. +use std::fmt::{Display, Formatter}; use std::fs; use std::path::{Path, PathBuf}; use std::sync::OnceLock; -use crate::FileType; use crate::core::builder::{Builder, Cargo, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash}; use crate::utils::exec::command; use crate::utils::helpers::{self, t}; +/// GCC cannot cross-compile from a single binary to multiple targets. +/// So we need to have a separate GCC dylib for each (host, target) pair. +/// We represent this explicitly using this struct. +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct GccTargetPair { + /// Target on which the libgccjit.so dylib will be executed. + host: TargetSelection, + /// Target for which the libgccjit.so dylib will generate assembly. + target: TargetSelection, +} + +impl GccTargetPair { + /// Create a target pair for a GCC that will run on `target` and generate assembly for `target`. + pub fn for_native_build(target: TargetSelection) -> Self { + Self { host: target, target } + } + + /// Create a target pair for a GCC that will run on `host` and generate assembly for `target`. + /// This may be cross-compilation if `host != target`. + pub fn for_target_pair(host: TargetSelection, target: TargetSelection) -> Self { + Self { host, target } + } + + pub fn host(&self) -> TargetSelection { + self.host + } + + pub fn target(&self) -> TargetSelection { + self.target + } +} + +impl Display for GccTargetPair { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{} -> {}", self.host, self.target) + } +} + #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Gcc { - pub target: TargetSelection, + pub target_pair: GccTargetPair, } #[derive(Clone)] pub struct GccOutput { - pub libgccjit: PathBuf, - target: TargetSelection, + /// Path to a built or downloaded libgccjit. + libgccjit: PathBuf, } impl GccOutput { - /// Install the required libgccjit library file(s) to the specified `path`. - pub fn install_to(&self, builder: &Builder<'_>, directory: &Path) { - if builder.config.dry_run() { - return; - } - - let target_filename = self.libgccjit.file_name().unwrap().to_str().unwrap().to_string(); - - // If we build libgccjit ourselves, then `self.libgccjit` can actually be a symlink. - // In that case, we have to resolve it first, otherwise we'd create a symlink to a symlink, - // which wouldn't work. - let actual_libgccjit_path = t!( - self.libgccjit.canonicalize(), - format!("Cannot find libgccjit at {}", self.libgccjit.display()) - ); - - let dest_dir = directory.join("rustlib").join(self.target).join("lib"); - t!(fs::create_dir_all(&dest_dir)); - let dst = dest_dir.join(target_filename); - builder.copy_link(&actual_libgccjit_path, &dst, FileType::NativeLibrary); + pub fn libgccjit(&self) -> &Path { + &self.libgccjit } } @@ -64,33 +84,38 @@ impl Step for Gcc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Gcc { target: run.target }); + // By default, we build libgccjit that can do native compilation (no cross-compilation) + // on a given target. + run.builder + .ensure(Gcc { target_pair: GccTargetPair { host: run.target, target: run.target } }); } /// Compile GCC (specifically `libgccjit`) for `target`. fn run(self, builder: &Builder<'_>) -> Self::Output { - let target = self.target; + let target_pair = self.target_pair; // If GCC has already been built, we avoid building it again. - let metadata = match get_gcc_build_status(builder, target) { - GccBuildStatus::AlreadyBuilt(path) => return GccOutput { libgccjit: path, target }, + let metadata = match get_gcc_build_status(builder, target_pair) { + GccBuildStatus::AlreadyBuilt(path) => return GccOutput { libgccjit: path }, GccBuildStatus::ShouldBuild(m) => m, }; - let _guard = builder.msg_unstaged(Kind::Build, "GCC", target); + let action = Kind::Build.description(); + let msg = format!("{action} GCC for {target_pair}"); + let _guard = builder.group(&msg); t!(metadata.stamp.remove()); let _time = helpers::timeit(builder); let libgccjit_path = libgccjit_built_path(&metadata.install_dir); if builder.config.dry_run() { - return GccOutput { libgccjit: libgccjit_path, target }; + return GccOutput { libgccjit: libgccjit_path }; } - build_gcc(&metadata, builder, target); + build_gcc(&metadata, builder, target_pair); t!(metadata.stamp.write()); - GccOutput { libgccjit: libgccjit_path, target } + GccOutput { libgccjit: libgccjit_path } } } @@ -111,15 +136,27 @@ pub enum GccBuildStatus { /// are available for the given target. /// Returns a path to the libgccjit.so file. #[cfg(not(test))] -fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option { +fn try_download_gcc(builder: &Builder<'_>, target_pair: GccTargetPair) -> Option { use build_helper::git::PathFreshness; // Try to download GCC from CI if configured and available if !matches!(builder.config.gcc_ci_mode, crate::core::config::GccCiMode::DownloadFromCi) { return None; } - if target != "x86_64-unknown-linux-gnu" { - eprintln!("GCC CI download is only available for the `x86_64-unknown-linux-gnu` target"); + + // We currently do not support downloading CI GCC if the host/target pair doesn't match. + if target_pair.host != target_pair.target { + eprintln!( + "GCC CI download is not available when the host ({}) does not equal the compilation target ({}).", + target_pair.host, target_pair.target + ); + return None; + } + + if target_pair.host != "x86_64-unknown-linux-gnu" { + eprintln!( + "GCC CI download is only available for the `x86_64-unknown-linux-gnu` host/target" + ); return None; } let source = detect_gcc_freshness( @@ -132,7 +169,7 @@ fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option { // Download from upstream CI - let root = ci_gcc_root(&builder.config, target); + let root = ci_gcc_root(&builder.config, target_pair.target); let gcc_stamp = BuildStamp::new(&root).with_prefix("gcc").add_stamp(&upstream); if !gcc_stamp.is_up_to_date() && !builder.config.dry_run() { builder.config.download_ci_gcc(&upstream, &root); @@ -158,7 +195,7 @@ fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option, _target: TargetSelection) -> Option { +fn try_download_gcc(_builder: &Builder<'_>, _target_pair: GccTargetPair) -> Option { None } @@ -167,11 +204,28 @@ fn try_download_gcc(_builder: &Builder<'_>, _target: TargetSelection) -> Option< /// /// It's used to avoid busting caches during x.py check -- if we've already built /// GCC, it's fine for us to not try to avoid doing so. -pub fn get_gcc_build_status(builder: &Builder<'_>, target: TargetSelection) -> GccBuildStatus { - if let Some(path) = try_download_gcc(builder, target) { +pub fn get_gcc_build_status(builder: &Builder<'_>, target_pair: GccTargetPair) -> GccBuildStatus { + // Prefer taking externally provided prebuilt libgccjit dylib + if let Some(dir) = &builder.config.libgccjit_libs_dir { + // The dir structure should be ///libgccjit.so + let host_dir = dir.join(target_pair.host); + let path = host_dir.join(target_pair.target).join("libgccjit.so"); + if path.exists() { + return GccBuildStatus::AlreadyBuilt(path); + } else { + builder.info(&format!( + "libgccjit.so for `{target_pair}` was not found at `{}`", + path.display() + )); + } + } + + // If not available, try to download from CI + if let Some(path) = try_download_gcc(builder, target_pair) { return GccBuildStatus::AlreadyBuilt(path); } + // If not available, try to build (or use already built libgccjit from disk) static STAMP_HASH_MEMO: OnceLock = OnceLock::new(); let smart_stamp_hash = STAMP_HASH_MEMO.get_or_init(|| { generate_smart_stamp_hash( @@ -185,8 +239,8 @@ pub fn get_gcc_build_status(builder: &Builder<'_>, target: TargetSelection) -> G builder.config.update_submodule("src/gcc"); let root = builder.src.join("src/gcc"); - let out_dir = builder.gcc_out(target).join("build"); - let install_dir = builder.gcc_out(target).join("install"); + let out_dir = gcc_out(builder, target_pair).join("build"); + let install_dir = gcc_out(builder, target_pair).join("install"); let stamp = BuildStamp::new(&out_dir).with_prefix("gcc").add_stamp(smart_stamp_hash); @@ -215,15 +269,20 @@ pub fn get_gcc_build_status(builder: &Builder<'_>, target: TargetSelection) -> G GccBuildStatus::ShouldBuild(Meta { stamp, out_dir, install_dir, root }) } +fn gcc_out(builder: &Builder<'_>, pair: GccTargetPair) -> PathBuf { + builder.out.join(pair.host).join("gcc").join(pair.target) +} + /// Returns the path to a libgccjit.so file in the install directory of GCC. fn libgccjit_built_path(install_dir: &Path) -> PathBuf { install_dir.join("lib/libgccjit.so") } -fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) { - if builder.build.cc_tool(target).is_like_clang() - || builder.build.cxx_tool(target).is_like_clang() - { +fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target_pair: GccTargetPair) { + // Target on which libgccjit.so will be executed. Here we will generate a dylib with + // instructions for that target. + let host = target_pair.host; + if builder.build.cc_tool(host).is_like_clang() || builder.build.cxx_tool(host).is_like_clang() { panic!( "Attempting to build GCC using Clang, which is known to misbehave. Please use GCC as the host C/C++ compiler. " ); @@ -241,7 +300,7 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) { // builds. // Therefore, we first copy the whole source directory to the build directory, and perform the // build from there. - let src_dir = builder.gcc_out(target).join("src"); + let src_dir = gcc_out(builder, target_pair).join("src"); if src_dir.exists() { builder.remove_dir(&src_dir); } @@ -259,7 +318,7 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) { .arg("--disable-multilib") .arg(format!("--prefix={}", install_dir.display())); - let cc = builder.build.cc(target).display().to_string(); + let cc = builder.build.cc(host).display().to_string(); let cc = builder .build .config @@ -268,7 +327,7 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) { .map_or_else(|| cc.clone(), |ccache| format!("{ccache} {cc}")); configure_cmd.env("CC", cc); - if let Ok(ref cxx) = builder.build.cxx(target) { + if let Ok(ref cxx) = builder.build.cxx(host) { let cxx = cxx.display().to_string(); let cxx = builder .build diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 9f8bb4dea54f..05aa2521b2e0 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -16,7 +16,7 @@ use build_helper::exit; use crate::core::build_steps::compile::{Std, run_cargo}; use crate::core::build_steps::doc::{DocumentationFormat, prepare_doc_compiler}; -use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags}; +use crate::core::build_steps::gcc::{Gcc, GccTargetPair, add_cg_gcc_cargo_flags}; use crate::core::build_steps::llvm::get_llvm_version; use crate::core::build_steps::run::{get_completion_paths, get_help_path}; use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget; @@ -3956,7 +3956,7 @@ impl Step for CodegenGCC { let compilers = self.compilers; let target = self.target; - let gcc = builder.ensure(Gcc { target }); + let gcc = builder.ensure(Gcc { target_pair: GccTargetPair::for_native_build(target) }); builder.ensure( compile::Std::new(compilers.build_compiler(), target) @@ -3997,12 +3997,13 @@ impl Step for CodegenGCC { .arg("--use-backend") .arg("gcc") .arg("--gcc-path") - .arg(gcc.libgccjit.parent().unwrap()) + .arg(gcc.libgccjit().parent().unwrap()) .arg("--out-dir") .arg(builder.stage_out(compilers.build_compiler(), Mode::Codegen).join("cg_gcc")) .arg("--release") .arg("--mini-tests") .arg("--std-tests"); + cargo.args(builder.config.test_args()); cargo.into_cmd().run(builder); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 2f493658ec0e..a81b8ccb9140 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -188,6 +188,7 @@ pub struct Config { // gcc codegen options pub gcc_ci_mode: GccCiMode, + pub libgccjit_libs_dir: Option, // rust codegen options pub rust_optimize: RustOptimize, @@ -620,7 +621,10 @@ impl Config { vendor: dist_vendor, } = toml.dist.unwrap_or_default(); - let Gcc { download_ci_gcc: gcc_download_ci_gcc } = toml.gcc.unwrap_or_default(); + let Gcc { + download_ci_gcc: gcc_download_ci_gcc, + libgccjit_libs_dir: gcc_libgccjit_libs_dir, + } = toml.gcc.unwrap_or_default(); if rust_bootstrap_override_lld.is_some() && rust_bootstrap_override_lld_legacy.is_some() { panic!( @@ -1346,6 +1350,7 @@ impl Config { keep_stage: flags_keep_stage, keep_stage_std: flags_keep_stage_std, libdir: install_libdir.map(PathBuf::from), + libgccjit_libs_dir: gcc_libgccjit_libs_dir, library_docs_private_items: build_library_docs_private_items.unwrap_or(false), lld_enabled, lldb: build_lldb.map(PathBuf::from), diff --git a/src/bootstrap/src/core/config/toml/gcc.rs b/src/bootstrap/src/core/config/toml/gcc.rs index 9ea697edf159..94d15a9baaff 100644 --- a/src/bootstrap/src/core/config/toml/gcc.rs +++ b/src/bootstrap/src/core/config/toml/gcc.rs @@ -15,5 +15,6 @@ define_config! { #[derive(Default)] struct Gcc { download_ci_gcc: Option = "download-ci-gcc", + libgccjit_libs_dir: Option = "libgccjit-libs-dir", } } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index a31eb0c1c801..adae9a1b8b08 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -975,10 +975,6 @@ impl Build { self.out.join(&*target.triple).join("enzyme") } - fn gcc_out(&self, target: TargetSelection) -> PathBuf { - self.out.join(&*target.triple).join("gcc") - } - fn lld_out(&self, target: TargetSelection) -> PathBuf { self.out.join(target).join("lld") } From a9511b9b49f2118e8176609389bf84a404ca15ac Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 11 Dec 2025 11:15:15 -0500 Subject: [PATCH 0826/3801] When we cannot load libgccjit.so, show the paths that were tried --- compiler/rustc_codegen_gcc/src/lib.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index a77239e23b4e..96d3a0024f41 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -98,7 +98,6 @@ use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames}; -use rustc_session::filesearch::make_target_lib_path; use rustc_span::Symbol; use rustc_target::spec::{Arch, RelocModel}; use tempfile::TempDir; @@ -207,18 +206,38 @@ impl CodegenBackend for GccCodegenBackend { } fn init(&self, sess: &Session) { + fn file_path(sysroot_path: &Path, sess: &Session) -> PathBuf { + let rustlib_path = + rustc_target::relative_target_rustlib_path(sysroot_path, &sess.host.llvm_target); + sysroot_path + .join(rustlib_path) + .join("codegen-backends") + .join("lib") + .join(sess.target.llvm_target.as_ref()) + .join("libgccjit.so") + } + // We use all_paths() instead of only path() in case the path specified by --sysroot is // invalid. // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. for path in sess.opts.sysroot.all_paths() { - let libgccjit_target_lib_file = - make_target_lib_path(path, &sess.target.llvm_target).join("libgccjit.so"); + let libgccjit_target_lib_file = file_path(path, sess); if let Ok(true) = fs::exists(&libgccjit_target_lib_file) { load_libgccjit_if_needed(&libgccjit_target_lib_file); break; } } + if !gccjit::is_loaded() { + let mut paths = vec![]; + for path in sess.opts.sysroot.all_paths() { + let libgccjit_target_lib_file = file_path(path, sess); + paths.push(libgccjit_target_lib_file); + } + + panic!("Could not load libgccjit.so. Attempted paths: {:#?}", paths); + } + #[cfg(feature = "master")] { let target_cpu = target_cpu(sess); From 15e3955f3a6e38cf8cd4f678b588609c0617b2a1 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 11 Dec 2025 14:26:57 -0500 Subject: [PATCH 0827/3801] Document new gcc.download-ci-gcc option --- .../src/tests/codegen-backend-tests/cg_gcc.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md index 4325cc58797f..7a1c5b9a98c0 100644 --- a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md +++ b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md @@ -77,6 +77,26 @@ will be downloaded from CI or built locally. The default value is `true`, which will download GCC from CI if there are no local changes to the GCC sources and the given host target is available on CI. +## Providing your own GCC + +There are cases where you will want to provide yourself the `libgccjit.so` file. +One such case is when you want to cross-compile `rustc` to another target since GCC is not a multi-target compiler. +To support this use case, there is the bootstrap option `gcc.libgccjit-libs-dir`. +This option override `gcc.download-ci-gcc`, meaning `libgccjit.so` won't be downloaded or built locally by bootstrap. +The directory structure of this directory is `//libgccjit.so`, for instance: + +``` +. +├── m68k-unknown-linux-gnu +│ └── m68k-unknown-linux-gnu +│ └── libgccjit.so +└── x86_64-unknown-linux-gnu + ├── m68k-unknown-linux-gnu + │ └── libgccjit.so + └── x86_64-unknown-linux-gnu + └── libgccjit.so +``` + ## Running tests of the backend itself In addition to running the compiler's test suites using the GCC codegen backend, you can also run the test suite of the backend itself. From 8f035402e074a285af3407b2989234bb7081d7ce Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 11 Dec 2025 14:27:29 -0500 Subject: [PATCH 0828/3801] Add new ChangeInfo for the new option gcc.libgccjit-libs-dir --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 37ad5f09897f..d7990c2316d1 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -601,4 +601,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "New options `rust.rustflags` for all targets and per-target `rustflags` that will pass specified flags to rustc for all stages. Target-specific flags override global `rust.rustflags` ones.", }, + ChangeInfo { + change_id: 149354, + severity: ChangeSeverity::Info, + summary: "New option `gcc.libgccjit-libs-dir` to specify which libgccjit.so to use per target.", + }, ]; From b98a91e6ca1a5ab38eef810922b54405f0a2a5b8 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sun, 14 Dec 2025 08:09:34 -0500 Subject: [PATCH 0829/3801] Error out if a GCC cross-compiler cannot be found --- src/bootstrap/src/core/build_steps/gcc.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs index 9cc5d0ed71b1..648a2bea4181 100644 --- a/src/bootstrap/src/core/build_steps/gcc.rs +++ b/src/bootstrap/src/core/build_steps/gcc.rs @@ -217,6 +217,15 @@ pub fn get_gcc_build_status(builder: &Builder<'_>, target_pair: GccTargetPair) - "libgccjit.so for `{target_pair}` was not found at `{}`", path.display() )); + + if target_pair.host != target_pair.target || target_pair.host != builder.host_target { + eprintln!( + "info: libgccjit.so for `{target_pair}` was not found at `{}`", + path.display() + ); + eprintln!("error: we do not support downloading or building a GCC cross-compiler"); + std::process::exit(1); + } } } From f0418b3461ec949f04e803e2292c568f8816f655 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 11 Dec 2025 11:15:15 -0500 Subject: [PATCH 0830/3801] When we cannot load libgccjit.so, show the paths that were tried --- src/lib.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a77239e23b4e..96d3a0024f41 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -98,7 +98,6 @@ use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames}; -use rustc_session::filesearch::make_target_lib_path; use rustc_span::Symbol; use rustc_target::spec::{Arch, RelocModel}; use tempfile::TempDir; @@ -207,18 +206,38 @@ impl CodegenBackend for GccCodegenBackend { } fn init(&self, sess: &Session) { + fn file_path(sysroot_path: &Path, sess: &Session) -> PathBuf { + let rustlib_path = + rustc_target::relative_target_rustlib_path(sysroot_path, &sess.host.llvm_target); + sysroot_path + .join(rustlib_path) + .join("codegen-backends") + .join("lib") + .join(sess.target.llvm_target.as_ref()) + .join("libgccjit.so") + } + // We use all_paths() instead of only path() in case the path specified by --sysroot is // invalid. // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. for path in sess.opts.sysroot.all_paths() { - let libgccjit_target_lib_file = - make_target_lib_path(path, &sess.target.llvm_target).join("libgccjit.so"); + let libgccjit_target_lib_file = file_path(path, sess); if let Ok(true) = fs::exists(&libgccjit_target_lib_file) { load_libgccjit_if_needed(&libgccjit_target_lib_file); break; } } + if !gccjit::is_loaded() { + let mut paths = vec![]; + for path in sess.opts.sysroot.all_paths() { + let libgccjit_target_lib_file = file_path(path, sess); + paths.push(libgccjit_target_lib_file); + } + + panic!("Could not load libgccjit.so. Attempted paths: {:#?}", paths); + } + #[cfg(feature = "master")] { let target_cpu = target_cpu(sess); From 854f619d6a023b15a8b5461a7923134f347b3bb6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 15 Dec 2025 14:36:18 +0100 Subject: [PATCH 0831/3801] Correctly encode doc attribute metadata --- .../rustc_hir/src/attrs/data_structures.rs | 58 ++++++++++++++++++- compiler/rustc_metadata/src/rmeta/encoder.rs | 10 +--- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 34d78afca9b2..5ebe121dd67c 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -530,7 +530,7 @@ pub struct CfgHideShow { pub values: ThinVec, } -#[derive(Clone, Debug, Default, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +#[derive(Clone, Debug, Default, HashStable_Generic, Decodable, PrintAttribute)] pub struct DocAttribute { pub aliases: FxIndexMap, pub hidden: Option, @@ -566,6 +566,62 @@ pub struct DocAttribute { pub no_crate_inject: Option, } +impl rustc_serialize::Encodable for DocAttribute { + fn encode(&self, encoder: &mut E) { + let DocAttribute { + aliases, + hidden, + inline, + cfg, + auto_cfg, + auto_cfg_change, + fake_variadic, + keyword, + attribute, + masked, + notable_trait, + search_unbox, + html_favicon_url, + html_logo_url, + html_playground_url, + html_root_url, + html_no_source, + issue_tracker_base_url, + rust_logo, + test_attrs, + no_crate_inject, + } = self; + rustc_serialize::Encodable::::encode(aliases, encoder); + rustc_serialize::Encodable::::encode(hidden, encoder); + + // FIXME: The `doc(inline)` attribute is never encoded, but is it actually the right thing + // to do? I suspect the condition was broken, should maybe instead not encode anything if we + // have `doc(no_inline)`. + let inline: ThinVec<_> = + inline.iter().filter(|(i, _)| *i != DocInline::Inline).cloned().collect(); + rustc_serialize::Encodable::::encode(&inline, encoder); + + rustc_serialize::Encodable::::encode(cfg, encoder); + rustc_serialize::Encodable::::encode(auto_cfg, encoder); + rustc_serialize::Encodable::::encode(auto_cfg_change, encoder); + rustc_serialize::Encodable::::encode(fake_variadic, encoder); + rustc_serialize::Encodable::::encode(keyword, encoder); + rustc_serialize::Encodable::::encode(attribute, encoder); + rustc_serialize::Encodable::::encode(masked, encoder); + rustc_serialize::Encodable::::encode(notable_trait, encoder); + rustc_serialize::Encodable::::encode(search_unbox, encoder); + rustc_serialize::Encodable::::encode(html_favicon_url, encoder); + rustc_serialize::Encodable::::encode(html_logo_url, encoder); + rustc_serialize::Encodable::::encode(html_playground_url, encoder); + rustc_serialize::Encodable::::encode(html_root_url, encoder); + rustc_serialize::Encodable::::encode(html_no_source, encoder); + rustc_serialize::Encodable::::encode(issue_tracker_base_url, encoder); + rustc_serialize::Encodable::::encode(rust_logo, encoder); + rustc_serialize::Encodable::::encode(test_attrs, encoder); + rustc_serialize::Encodable::::encode(no_crate_inject, encoder); + } +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b15ed34fc356..6abde26e7e6d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -879,13 +879,9 @@ fn analyze_attr(attr: &hir::Attribute, state: &mut AnalyzeAttrState<'_>) -> bool should_encode = true; } } else if let hir::Attribute::Parsed(AttributeKind::Doc(d)) = attr { - // If this is a `doc` attribute that doesn't have anything except maybe `inline` (as in - // `#[doc(inline)]`), then we can remove it. It won't be inlinable in downstream crates. - if d.inline.is_empty() { - should_encode = true; - if d.hidden.is_some() { - state.is_doc_hidden = true; - } + should_encode = true; + if d.hidden.is_some() { + state.is_doc_hidden = true; } } else if let &[sym::diagnostic, seg] = &*attr.path() { should_encode = rustc_feature::is_stable_diagnostic_attribute(seg, state.features); From ef4a74134fd0907d5285621c56bf6637f7591922 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 27 Nov 2025 18:56:47 +0530 Subject: [PATCH 0832/3801] Add bidirectional messaging proc-macro-srv --- src/tools/rust-analyzer/Cargo.lock | 3 + .../hir-def/src/macro_expansion_tests/mod.rs | 3 +- .../crates/hir-expand/src/proc_macro.rs | 4 +- .../crates/load-cargo/src/lib.rs | 6 +- .../crates/proc-macro-api/Cargo.toml | 1 + .../src/bidirectional_protocol.rs | 296 +++++++++++++++++ .../src/bidirectional_protocol/msg.rs | 114 +++++++ .../proc-macro-api/src/legacy_protocol.rs | 23 +- .../proc-macro-api/src/legacy_protocol/msg.rs | 2 +- .../crates/proc-macro-api/src/lib.rs | 11 +- .../crates/proc-macro-api/src/process.rs | 173 +++++++--- .../crates/proc-macro-api/src/transport.rs | 3 + .../src/{ => transport}/codec.rs | 5 +- .../codec}/json.rs | 6 +- .../codec}/postcard.rs | 6 +- .../src/{ => transport}/framing.rs | 4 +- .../crates/proc-macro-srv-cli/Cargo.toml | 1 + .../crates/proc-macro-srv-cli/src/main.rs | 6 + .../proc-macro-srv-cli/src/main_loop.rs | 309 +++++++++++++++++- .../crates/proc-macro-srv/Cargo.toml | 1 + .../crates/proc-macro-srv/src/dylib.rs | 26 ++ .../proc-macro-srv/src/dylib/proc_macros.rs | 77 ++++- .../crates/proc-macro-srv/src/lib.rs | 86 ++++- .../src/server_impl/rust_analyzer_span.rs | 24 +- .../src/server_impl/token_id.rs | 4 + .../crates/test-fixture/src/lib.rs | 10 + 26 files changed, 1112 insertions(+), 92 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs create mode 100644 src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs create mode 100644 src/tools/rust-analyzer/crates/proc-macro-api/src/transport.rs rename src/tools/rust-analyzer/crates/proc-macro-api/src/{ => transport}/codec.rs (76%) rename src/tools/rust-analyzer/crates/proc-macro-api/src/{legacy_protocol => transport/codec}/json.rs (89%) rename src/tools/rust-analyzer/crates/proc-macro-api/src/{legacy_protocol => transport/codec}/postcard.rs (84%) rename src/tools/rust-analyzer/crates/proc-macro-api/src/{ => transport}/framing.rs (63%) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index efe56cb7f61c..060a62b112b7 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1836,6 +1836,7 @@ dependencies = [ name = "proc-macro-api" version = "0.0.0" dependencies = [ + "base-db", "indexmap", "intern", "paths", @@ -1856,6 +1857,7 @@ dependencies = [ name = "proc-macro-srv" version = "0.0.0" dependencies = [ + "crossbeam-channel", "expect-test", "intern", "libc", @@ -1874,6 +1876,7 @@ name = "proc-macro-srv-cli" version = "0.0.0" dependencies = [ "clap", + "crossbeam-channel", "postcard", "proc-macro-api", "proc-macro-srv", diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index 78af976e1b13..07cad9695b61 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -16,7 +16,7 @@ mod proc_macros; use std::{any::TypeId, iter, ops::Range, sync}; -use base_db::RootQueryDb; +use base_db::{RootQueryDb, SourceDatabase}; use expect_test::Expect; use hir_expand::{ AstId, InFile, MacroCallId, MacroCallKind, MacroKind, @@ -374,6 +374,7 @@ struct IdentityWhenValidProcMacroExpander; impl ProcMacroExpander for IdentityWhenValidProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &base_db::Env, diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs index f97d721dfa88..d2614aa5f149 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/proc_macro.rs @@ -4,7 +4,7 @@ use core::fmt; use std::any::Any; use std::{panic::RefUnwindSafe, sync}; -use base_db::{Crate, CrateBuilderId, CratesIdMap, Env, ProcMacroLoadingError}; +use base_db::{Crate, CrateBuilderId, CratesIdMap, Env, ProcMacroLoadingError, SourceDatabase}; use intern::Symbol; use rustc_hash::FxHashMap; use span::Span; @@ -25,6 +25,7 @@ pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe + Any { /// [`ProcMacroKind::Attr`]), environment variables, and span information. fn expand( &self, + db: &dyn SourceDatabase, subtree: &tt::TopSubtree, attrs: Option<&tt::TopSubtree>, env: &Env, @@ -309,6 +310,7 @@ impl CustomProcMacroExpander { let current_dir = calling_crate.data(db).proc_macro_cwd.to_string(); match proc_macro.expander.expand( + db, tt, attr_arg, env, diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 28fbfecfde80..e043e4ac7634 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -17,7 +17,9 @@ use hir_expand::proc_macro::{ }; use ide_db::{ ChangeWithProcMacros, FxHashMap, RootDatabase, - base_db::{CrateGraphBuilder, Env, ProcMacroLoadingError, SourceRoot, SourceRootId}, + base_db::{ + CrateGraphBuilder, Env, ProcMacroLoadingError, SourceDatabase, SourceRoot, SourceRootId, + }, prime_caches, }; use itertools::Itertools; @@ -522,6 +524,7 @@ struct Expander(proc_macro_api::ProcMacro); impl ProcMacroExpander for Expander { fn expand( &self, + db: &dyn SourceDatabase, subtree: &tt::TopSubtree, attrs: Option<&tt::TopSubtree>, env: &Env, @@ -531,6 +534,7 @@ impl ProcMacroExpander for Expander { current_dir: String, ) -> Result, ProcMacroExpansionError> { match self.0.expand( + db, subtree.view(), attrs.map(|attrs| attrs.view()), env.clone().into(), diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml index 4de1a3e5dd7d..7e56d68964ce 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml @@ -19,6 +19,7 @@ serde_json = { workspace = true, features = ["unbounded_depth"] } tracing.workspace = true rustc-hash.workspace = true indexmap.workspace = true +base-db.workspace = true # local deps paths = { workspace = true, features = ["serde1"] } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs new file mode 100644 index 000000000000..246f70a10196 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -0,0 +1,296 @@ +//! Bidirectional protocol methods + +use std::{ + io::{self, BufRead, Write}, + sync::Arc, +}; + +use base_db::SourceDatabase; +use paths::AbsPath; +use span::{FileId, Span}; + +use crate::{ + Codec, ProcMacro, ProcMacroKind, ServerError, + bidirectional_protocol::msg::{ + Envelope, ExpandMacro, ExpandMacroData, ExpnGlobals, Kind, Payload, Request, RequestId, + Response, SubRequest, SubResponse, + }, + legacy_protocol::{ + SpanMode, + msg::{ + FlatTree, ServerConfig, SpanDataIndexMap, deserialize_span_data_index_map, + serialize_span_data_index_map, + }, + }, + process::ProcMacroServerProcess, + transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, + version, +}; + +pub mod msg; + +pub trait ClientCallbacks { + fn handle_sub_request(&mut self, id: u64, req: SubRequest) -> Result; +} + +pub fn run_conversation( + writer: &mut dyn Write, + reader: &mut dyn BufRead, + buf: &mut C::Buf, + id: RequestId, + initial: Payload, + callbacks: &mut dyn ClientCallbacks, +) -> Result { + let msg = Envelope { id, kind: Kind::Request, payload: initial }; + let encoded = C::encode(&msg).map_err(wrap_encode)?; + C::write(writer, &encoded).map_err(wrap_io("failed to write initial request"))?; + + loop { + let maybe_buf = C::read(reader, buf).map_err(wrap_io("failed to read message"))?; + let Some(b) = maybe_buf else { + return Err(ServerError { + message: "proc-macro server closed the stream".into(), + io: Some(Arc::new(io::Error::new(io::ErrorKind::UnexpectedEof, "closed"))), + }); + }; + + let msg: Envelope = C::decode(b).map_err(wrap_decode)?; + + if msg.id != id { + return Err(ServerError { + message: format!("unexpected message id {}, expected {}", msg.id, id), + io: None, + }); + } + + match (msg.kind, msg.payload) { + (Kind::SubRequest, Payload::SubRequest(sr)) => { + let resp = callbacks.handle_sub_request(id, sr)?; + let reply = + Envelope { id, kind: Kind::SubResponse, payload: Payload::SubResponse(resp) }; + let encoded = C::encode(&reply).map_err(wrap_encode)?; + C::write(writer, &encoded).map_err(wrap_io("failed to write sub-response"))?; + } + (Kind::Response, payload) => { + return Ok(payload); + } + (kind, payload) => { + return Err(ServerError { + message: format!( + "unexpected message kind {:?} with payload {:?}", + kind, payload + ), + io: None, + }); + } + } + } +} + +fn wrap_io(msg: &'static str) -> impl Fn(io::Error) -> ServerError { + move |err| ServerError { message: msg.into(), io: Some(Arc::new(err)) } +} + +fn wrap_encode(err: io::Error) -> ServerError { + ServerError { message: "failed to encode message".into(), io: Some(Arc::new(err)) } +} + +fn wrap_decode(err: io::Error) -> ServerError { + ServerError { message: "failed to decode message".into(), io: Some(Arc::new(err)) } +} + +pub(crate) fn version_check(srv: &ProcMacroServerProcess) -> Result { + let request = Payload::Request(Request::ApiVersionCheck {}); + + struct NoCallbacks; + impl ClientCallbacks for NoCallbacks { + fn handle_sub_request( + &mut self, + _id: u64, + _req: SubRequest, + ) -> Result { + Err(ServerError { message: "sub-request not supported here".into(), io: None }) + } + } + + let mut callbacks = NoCallbacks; + + let response_payload = + run_bidirectional(srv, (0, Kind::Request, request).into(), &mut callbacks)?; + + match response_payload { + Payload::Response(Response::ApiVersionCheck(version)) => Ok(version), + other => { + Err(ServerError { message: format!("unexpected response: {:?}", other), io: None }) + } + } +} + +/// Enable support for rust-analyzer span mode if the server supports it. +pub(crate) fn enable_rust_analyzer_spans( + srv: &ProcMacroServerProcess, +) -> Result { + let request = + Payload::Request(Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer })); + + struct NoCallbacks; + impl ClientCallbacks for NoCallbacks { + fn handle_sub_request( + &mut self, + _id: u64, + _req: SubRequest, + ) -> Result { + Err(ServerError { message: "sub-request not supported here".into(), io: None }) + } + } + + let mut callbacks = NoCallbacks; + + let response_payload = + run_bidirectional(srv, (0, Kind::Request, request).into(), &mut callbacks)?; + + match response_payload { + Payload::Response(Response::SetConfig(ServerConfig { span_mode })) => Ok(span_mode), + _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }), + } +} + +/// Finds proc-macros in a given dynamic library. +pub(crate) fn find_proc_macros( + srv: &ProcMacroServerProcess, + dylib_path: &AbsPath, +) -> Result, String>, ServerError> { + let request = + Payload::Request(Request::ListMacros { dylib_path: dylib_path.to_path_buf().into() }); + + struct NoCallbacks; + impl ClientCallbacks for NoCallbacks { + fn handle_sub_request( + &mut self, + _id: u64, + _req: SubRequest, + ) -> Result { + Err(ServerError { message: "sub-request not supported here".into(), io: None }) + } + } + + let mut callbacks = NoCallbacks; + + let response_payload = + run_bidirectional(srv, (0, Kind::Request, request).into(), &mut callbacks)?; + + match response_payload { + Payload::Response(Response::ListMacros(it)) => Ok(it), + _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }), + } +} + +pub(crate) fn expand( + proc_macro: &ProcMacro, + db: &dyn SourceDatabase, + subtree: tt::SubtreeView<'_, Span>, + attr: Option>, + env: Vec<(String, String)>, + def_site: Span, + call_site: Span, + mixed_site: Span, + current_dir: String, +) -> Result>, String>, crate::ServerError> +{ + let version = proc_macro.process.version(); + let mut span_data_table = SpanDataIndexMap::default(); + let def_site = span_data_table.insert_full(def_site).0; + let call_site = span_data_table.insert_full(call_site).0; + let mixed_site = span_data_table.insert_full(mixed_site).0; + let task = Payload::Request(Request::ExpandMacro(Box::new(ExpandMacro { + data: ExpandMacroData { + macro_body: FlatTree::from_subtree(subtree, version, &mut span_data_table), + macro_name: proc_macro.name.to_string(), + attributes: attr + .map(|subtree| FlatTree::from_subtree(subtree, version, &mut span_data_table)), + has_global_spans: ExpnGlobals { + serialize: version >= version::HAS_GLOBAL_SPANS, + def_site, + call_site, + mixed_site, + }, + span_data_table: if proc_macro.process.rust_analyzer_spans() { + serialize_span_data_index_map(&span_data_table) + } else { + Vec::new() + }, + }, + lib: proc_macro.dylib_path.to_path_buf().into(), + env, + current_dir: Some(current_dir), + }))); + + struct Callbacks<'de> { + db: &'de dyn SourceDatabase, + } + impl<'db> ClientCallbacks for Callbacks<'db> { + fn handle_sub_request( + &mut self, + _id: u64, + req: SubRequest, + ) -> Result { + match req { + SubRequest::SourceText { file_id, start, end } => { + let file = FileId::from_raw(file_id); + let text = self.db.file_text(file).text(self.db); + + let slice = text.get(start as usize..end as usize).map(|s| s.to_owned()); + + Ok(SubResponse::SourceTextResult { text: slice }) + } + } + } + } + + let mut callbacks = Callbacks { db }; + + let response_payload = + run_bidirectional(&proc_macro.process, (0, Kind::Request, task).into(), &mut callbacks)?; + + match response_payload { + Payload::Response(Response::ExpandMacro(it)) => Ok(it + .map(|tree| { + let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table); + if proc_macro.needs_fixup_change() { + proc_macro.change_fixup_to_match_old_server(&mut expanded); + } + expanded + }) + .map_err(|msg| msg.0)), + Payload::Response(Response::ExpandMacroExtended(it)) => Ok(it + .map(|resp| { + let mut expanded = FlatTree::to_subtree_resolved( + resp.tree, + version, + &deserialize_span_data_index_map(&resp.span_data_table), + ); + if proc_macro.needs_fixup_change() { + proc_macro.change_fixup_to_match_old_server(&mut expanded); + } + expanded + }) + .map_err(|msg| msg.0)), + _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }), + } +} + +fn run_bidirectional( + srv: &ProcMacroServerProcess, + msg: Envelope, + callbacks: &mut dyn ClientCallbacks, +) -> Result { + if let Some(server_error) = srv.exited() { + return Err(server_error.clone()); + } + + if srv.use_postcard() { + srv.run_bidirectional::(msg.id, msg.payload, callbacks) + } else { + srv.run_bidirectional::(msg.id, msg.payload, callbacks) + } +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs new file mode 100644 index 000000000000..7aed3ae1e607 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -0,0 +1,114 @@ +//! Bidirectional protocol messages + +use paths::Utf8PathBuf; +use serde::{Deserialize, Serialize}; + +use crate::{ + ProcMacroKind, + legacy_protocol::msg::{FlatTree, Message, PanicMessage, ServerConfig}, +}; + +pub type RequestId = u64; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Envelope { + pub id: RequestId, + pub kind: Kind, + pub payload: Payload, +} + +impl From<(RequestId, Kind, Payload)> for Envelope { + fn from(value: (RequestId, Kind, Payload)) -> Self { + Envelope { id: value.0, kind: value.1, payload: value.2 } + } +} + +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] +pub enum Kind { + Request, + Response, + SubRequest, + SubResponse, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum SubRequest { + SourceText { file_id: u32, start: u32, end: u32 }, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum SubResponse { + SourceTextResult { text: Option }, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum Payload { + Request(Request), + Response(Response), + SubRequest(SubRequest), + SubResponse(SubResponse), +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum Request { + ListMacros { dylib_path: Utf8PathBuf }, + ExpandMacro(Box), + ApiVersionCheck {}, + SetConfig(ServerConfig), +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum Response { + ListMacros(Result, String>), + ExpandMacro(Result), + ApiVersionCheck(u32), + SetConfig(ServerConfig), + ExpandMacroExtended(Result), +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ExpandMacro { + pub lib: Utf8PathBuf, + pub env: Vec<(String, String)>, + pub current_dir: Option, + #[serde(flatten)] + pub data: ExpandMacroData, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ExpandMacroExtended { + pub tree: FlatTree, + pub span_data_table: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ExpandMacroData { + pub macro_body: FlatTree, + pub macro_name: String, + pub attributes: Option, + #[serde(skip_serializing_if = "ExpnGlobals::skip_serializing_if")] + #[serde(default)] + pub has_global_spans: ExpnGlobals, + + #[serde(skip_serializing_if = "Vec::is_empty")] + #[serde(default)] + pub span_data_table: Vec, +} + +#[derive(Clone, Copy, Default, Debug, Serialize, Deserialize)] +pub struct ExpnGlobals { + #[serde(skip_serializing)] + #[serde(default)] + pub serialize: bool, + pub def_site: usize, + pub call_site: usize, + pub mixed_site: usize, +} + +impl ExpnGlobals { + fn skip_serializing_if(&self) -> bool { + !self.serialize + } +} + +impl Message for Envelope {} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs index c2b132ddcc1d..81a9f391812c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs @@ -1,30 +1,26 @@ //! The initial proc-macro-srv protocol, soon to be deprecated. -pub mod json; pub mod msg; -pub mod postcard; use std::{ io::{BufRead, Write}, sync::Arc, }; +use base_db::SourceDatabase; use paths::AbsPath; use span::Span; use crate::{ ProcMacro, ProcMacroKind, ServerError, - codec::Codec, - legacy_protocol::{ - json::JsonProtocol, - msg::{ - ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, Message, Request, Response, - ServerConfig, SpanDataIndexMap, deserialize_span_data_index_map, - flat::serialize_span_data_index_map, - }, - postcard::PostcardProtocol, + legacy_protocol::msg::{ + ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, Message, Request, Response, + ServerConfig, SpanDataIndexMap, deserialize_span_data_index_map, + flat::serialize_span_data_index_map, }, process::ProcMacroServerProcess, + transport::codec::Codec, + transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version, }; @@ -82,6 +78,7 @@ pub(crate) fn find_proc_macros( pub(crate) fn expand( proc_macro: &ProcMacro, + _db: &dyn SourceDatabase, subtree: tt::SubtreeView<'_, Span>, attr: Option>, env: Vec<(String, String)>, @@ -155,9 +152,9 @@ fn send_task(srv: &ProcMacroServerProcess, req: Request) -> Result, req) + srv.send_task::<_, _, PostcardProtocol>(send_request::, req) } else { - srv.send_task(send_request::, req) + srv.send_task::<_, _, JsonProtocol>(send_request::, req) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs index a6e228d977db..0ebb0e9f93d5 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs @@ -8,7 +8,7 @@ use paths::Utf8PathBuf; use serde::de::DeserializeOwned; use serde_derive::{Deserialize, Serialize}; -use crate::{ProcMacroKind, codec::Codec}; +use crate::{Codec, ProcMacroKind}; /// Represents requests sent from the client to the proc-macro-srv. #[derive(Debug, Serialize, Deserialize)] diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 85b250eddfd4..7b9b5b39ab1c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -16,18 +16,19 @@ #[cfg(feature = "in-rust-tree")] extern crate rustc_driver as _; -mod codec; -mod framing; +pub mod bidirectional_protocol; pub mod legacy_protocol; mod process; +pub mod transport; +use base_db::SourceDatabase; use paths::{AbsPath, AbsPathBuf}; use semver::Version; use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span}; use std::{fmt, io, sync::Arc, time::SystemTime}; -pub use crate::codec::Codec; use crate::process::ProcMacroServerProcess; +pub use crate::transport::codec::Codec; /// The versions of the server protocol pub mod version { @@ -218,6 +219,7 @@ impl ProcMacro { /// This includes span information and environmental context. pub fn expand( &self, + db: &dyn SourceDatabase, subtree: tt::SubtreeView<'_, Span>, attr: Option>, env: Vec<(String, String)>, @@ -240,7 +242,8 @@ impl ProcMacro { } } - legacy_protocol::expand( + self.process.expand( + db, self, subtree, attr, diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index d6a8d27bfc42..39d954855187 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -7,12 +7,18 @@ use std::{ sync::{Arc, Mutex, OnceLock}, }; +use base_db::SourceDatabase; use paths::AbsPath; use semver::Version; +use span::Span; use stdx::JodChild; use crate::{ - ProcMacroKind, ServerError, + Codec, ProcMacro, ProcMacroKind, ServerError, + bidirectional_protocol::{ + self, ClientCallbacks, + msg::{Payload, RequestId}, + }, legacy_protocol::{self, SpanMode}, version, }; @@ -33,6 +39,8 @@ pub(crate) struct ProcMacroServerProcess { pub(crate) enum Protocol { LegacyJson { mode: SpanMode }, LegacyPostcard { mode: SpanMode }, + NewPostcard { mode: SpanMode }, + NewJson { mode: SpanMode }, } /// Maintains the state of the proc-macro server process. @@ -62,6 +70,8 @@ impl ProcMacroServerProcess { && has_working_format_flag { &[ + (Some("postcard-new"), Protocol::NewPostcard { mode: SpanMode::Id }), + (Some("json-new"), Protocol::NewJson { mode: SpanMode::Id }), (Some("postcard-legacy"), Protocol::LegacyPostcard { mode: SpanMode::Id }), (Some("json-legacy"), Protocol::LegacyJson { mode: SpanMode::Id }), ] @@ -105,9 +115,10 @@ impl ProcMacroServerProcess { && let Ok(new_mode) = srv.enable_rust_analyzer_spans() { match &mut srv.protocol { - Protocol::LegacyJson { mode } | Protocol::LegacyPostcard { mode } => { - *mode = new_mode - } + Protocol::LegacyJson { mode } + | Protocol::LegacyPostcard { mode } + | Protocol::NewJson { mode } + | Protocol::NewPostcard { mode } => *mode = new_mode, } } tracing::info!("Proc-macro server protocol: {:?}", srv.protocol); @@ -143,22 +154,32 @@ impl ProcMacroServerProcess { match self.protocol { Protocol::LegacyJson { mode } => mode == SpanMode::RustAnalyzer, Protocol::LegacyPostcard { mode } => mode == SpanMode::RustAnalyzer, + Protocol::NewJson { mode } => mode == SpanMode::RustAnalyzer, + Protocol::NewPostcard { mode } => mode == SpanMode::RustAnalyzer, } } /// Checks the API version of the running proc-macro server. fn version_check(&self) -> Result { match self.protocol { - Protocol::LegacyJson { .. } => legacy_protocol::version_check(self), - Protocol::LegacyPostcard { .. } => legacy_protocol::version_check(self), + Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { + legacy_protocol::version_check(self) + } + Protocol::NewJson { .. } | Protocol::NewPostcard { .. } => { + bidirectional_protocol::version_check(self) + } } } /// Enable support for rust-analyzer span mode if the server supports it. fn enable_rust_analyzer_spans(&self) -> Result { match self.protocol { - Protocol::LegacyJson { .. } => legacy_protocol::enable_rust_analyzer_spans(self), - Protocol::LegacyPostcard { .. } => legacy_protocol::enable_rust_analyzer_spans(self), + Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { + legacy_protocol::enable_rust_analyzer_spans(self) + } + Protocol::NewJson { .. } | Protocol::NewPostcard { .. } => { + bidirectional_protocol::enable_rust_analyzer_spans(self) + } } } @@ -168,28 +189,69 @@ impl ProcMacroServerProcess { dylib_path: &AbsPath, ) -> Result, String>, ServerError> { match self.protocol { - Protocol::LegacyJson { .. } => legacy_protocol::find_proc_macros(self, dylib_path), - Protocol::LegacyPostcard { .. } => legacy_protocol::find_proc_macros(self, dylib_path), + Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { + legacy_protocol::find_proc_macros(self, dylib_path) + } + Protocol::NewJson { .. } | Protocol::NewPostcard { .. } => { + bidirectional_protocol::find_proc_macros(self, dylib_path) + } } } - pub(crate) fn send_task( + pub(crate) fn expand( &self, - serialize_req: impl FnOnce( + db: &dyn SourceDatabase, + proc_macro: &ProcMacro, + subtree: tt::SubtreeView<'_, Span>, + attr: Option>, + env: Vec<(String, String)>, + def_site: Span, + call_site: Span, + mixed_site: Span, + current_dir: String, + ) -> Result, String>, ServerError> { + match self.protocol { + Protocol::LegacyJson { .. } | Protocol::LegacyPostcard { .. } => { + legacy_protocol::expand( + proc_macro, + db, + subtree, + attr, + env, + def_site, + call_site, + mixed_site, + current_dir, + ) + } + Protocol::NewJson { .. } | Protocol::NewPostcard { .. } => { + bidirectional_protocol::expand( + proc_macro, + db, + subtree, + attr, + env, + def_site, + call_site, + mixed_site, + current_dir, + ) + } + } + } + + pub(crate) fn send_task( + &self, + send: impl FnOnce( &mut dyn Write, &mut dyn BufRead, Request, - &mut Buf, + &mut C::Buf, ) -> Result, ServerError>, req: Request, - ) -> Result - where - Buf: Default, - { - let state = &mut *self.state.lock().unwrap(); - let mut buf = Buf::default(); - serialize_req(&mut state.stdin, &mut state.stdout, req, &mut buf) - .and_then(|res| { + ) -> Result { + self.with_locked_io::(|writer, reader, buf| { + send(writer, reader, req, buf).and_then(|res| { res.ok_or_else(|| { let message = "proc-macro server did not respond with data".to_owned(); ServerError { @@ -201,33 +263,54 @@ impl ProcMacroServerProcess { } }) }) - .map_err(|e| { - if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) { - match state.process.child.try_wait() { - Ok(None) | Err(_) => e, - Ok(Some(status)) => { - let mut msg = String::new(); - if !status.success() - && let Some(stderr) = state.process.child.stderr.as_mut() - { - _ = stderr.read_to_string(&mut msg); - } - let server_error = ServerError { - message: format!( - "proc-macro server exited with {status}{}{msg}", - if msg.is_empty() { "" } else { ": " } - ), - io: None, - }; - // `AssertUnwindSafe` is fine here, we already correct initialized - // server_error at this point. - self.exited.get_or_init(|| AssertUnwindSafe(server_error)).0.clone() + }) + } + + pub(crate) fn with_locked_io( + &self, + f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut C::Buf) -> Result, + ) -> Result { + let state = &mut *self.state.lock().unwrap(); + let mut buf = C::Buf::default(); + + f(&mut state.stdin, &mut state.stdout, &mut buf).map_err(|e| { + if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) { + match state.process.child.try_wait() { + Ok(None) | Err(_) => e, + Ok(Some(status)) => { + let mut msg = String::new(); + if !status.success() + && let Some(stderr) = state.process.child.stderr.as_mut() + { + _ = stderr.read_to_string(&mut msg); } + let server_error = ServerError { + message: format!( + "proc-macro server exited with {status}{}{msg}", + if msg.is_empty() { "" } else { ": " } + ), + io: None, + }; + self.exited.get_or_init(|| AssertUnwindSafe(server_error)).0.clone() } - } else { - e } - }) + } else { + e + } + }) + } + + pub(crate) fn run_bidirectional( + &self, + id: RequestId, + initial: Payload, + callbacks: &mut dyn ClientCallbacks, + ) -> Result { + self.with_locked_io::(|writer, reader, buf| { + bidirectional_protocol::run_conversation::( + writer, reader, buf, id, initial, callbacks, + ) + }) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/transport.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport.rs new file mode 100644 index 000000000000..b7a1d8f7322c --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport.rs @@ -0,0 +1,3 @@ +//! Contains construct for transport of messages. +pub mod codec; +pub mod framing; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/codec.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/codec.rs similarity index 76% rename from src/tools/rust-analyzer/crates/proc-macro-api/src/codec.rs rename to src/tools/rust-analyzer/crates/proc-macro-api/src/transport/codec.rs index baccaa6be4c2..c9afad260a56 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/codec.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/codec.rs @@ -4,7 +4,10 @@ use std::io; use serde::de::DeserializeOwned; -use crate::framing::Framing; +use crate::transport::framing::Framing; + +pub mod json; +pub mod postcard; pub trait Codec: Framing { fn encode(msg: &T) -> io::Result; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/codec/json.rs similarity index 89% rename from src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs rename to src/tools/rust-analyzer/crates/proc-macro-api/src/transport/codec/json.rs index 1359c0568402..96db802e0bfd 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/codec/json.rs @@ -3,14 +3,14 @@ use std::io::{self, BufRead, Write}; use serde::{Serialize, de::DeserializeOwned}; -use crate::{codec::Codec, framing::Framing}; +use crate::{Codec, transport::framing::Framing}; pub struct JsonProtocol; impl Framing for JsonProtocol { type Buf = String; - fn read<'a, R: BufRead>( + fn read<'a, R: BufRead + ?Sized>( inp: &mut R, buf: &'a mut String, ) -> io::Result> { @@ -35,7 +35,7 @@ impl Framing for JsonProtocol { } } - fn write(out: &mut W, buf: &String) -> io::Result<()> { + fn write(out: &mut W, buf: &String) -> io::Result<()> { tracing::debug!("> {}", buf); out.write_all(buf.as_bytes())?; out.write_all(b"\n")?; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/postcard.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/codec/postcard.rs similarity index 84% rename from src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/postcard.rs rename to src/tools/rust-analyzer/crates/proc-macro-api/src/transport/codec/postcard.rs index c28a9bfe3a1a..6f5319e75b37 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/postcard.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/codec/postcard.rs @@ -4,14 +4,14 @@ use std::io::{self, BufRead, Write}; use serde::{Serialize, de::DeserializeOwned}; -use crate::{codec::Codec, framing::Framing}; +use crate::{Codec, transport::framing::Framing}; pub struct PostcardProtocol; impl Framing for PostcardProtocol { type Buf = Vec; - fn read<'a, R: BufRead>( + fn read<'a, R: BufRead + ?Sized>( inp: &mut R, buf: &'a mut Vec, ) -> io::Result>> { @@ -23,7 +23,7 @@ impl Framing for PostcardProtocol { Ok(Some(buf)) } - fn write(out: &mut W, buf: &Vec) -> io::Result<()> { + fn write(out: &mut W, buf: &Vec) -> io::Result<()> { out.write_all(buf)?; out.flush() } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/framing.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/framing.rs similarity index 63% rename from src/tools/rust-analyzer/crates/proc-macro-api/src/framing.rs rename to src/tools/rust-analyzer/crates/proc-macro-api/src/transport/framing.rs index a1e6fc05ca11..2a11eb19c365 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/framing.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/framing.rs @@ -5,10 +5,10 @@ use std::io::{self, BufRead, Write}; pub trait Framing { type Buf: Default; - fn read<'a, R: BufRead>( + fn read<'a, R: BufRead + ?Sized>( inp: &mut R, buf: &'a mut Self::Buf, ) -> io::Result>; - fn write(out: &mut W, buf: &Self::Buf) -> io::Result<()>; + fn write(out: &mut W, buf: &Self::Buf) -> io::Result<()>; } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml index aa153897fa96..298592ee4763 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml @@ -15,6 +15,7 @@ proc-macro-srv.workspace = true proc-macro-api.workspace = true tt.workspace = true postcard.workspace = true +crossbeam-channel.workspace = true clap = {version = "4.5.42", default-features = false, features = ["std"]} [features] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index 813ac339a91d..d3dae0494fe4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -52,6 +52,8 @@ fn main() -> std::io::Result<()> { enum ProtocolFormat { JsonLegacy, PostcardLegacy, + JsonNew, + PostcardNew, } impl ValueEnum for ProtocolFormat { @@ -65,12 +67,16 @@ impl ValueEnum for ProtocolFormat { ProtocolFormat::PostcardLegacy => { Some(clap::builder::PossibleValue::new("postcard-legacy")) } + ProtocolFormat::JsonNew => Some(clap::builder::PossibleValue::new("json-new")), + ProtocolFormat::PostcardNew => Some(clap::builder::PossibleValue::new("postcard-new")), } } fn from_str(input: &str, _ignore_case: bool) -> Result { match input { "json-legacy" => Ok(ProtocolFormat::JsonLegacy), "postcard-legacy" => Ok(ProtocolFormat::PostcardLegacy), + "postcard-new" => Ok(ProtocolFormat::PostcardNew), + "json-new" => Ok(ProtocolFormat::JsonNew), _ => Err(format!("unknown protocol format: {input}")), } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index df54f38cbccb..e543260964fb 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -1,16 +1,16 @@ //! The main loop of the proc-macro server. use std::io; +use crossbeam_channel::unbounded; +use proc_macro_api::bidirectional_protocol::msg::Request; use proc_macro_api::{ Codec, - legacy_protocol::{ - json::JsonProtocol, - msg::{ - self, ExpandMacroData, ExpnGlobals, Message, SpanMode, SpanTransformer, - deserialize_span_data_index_map, serialize_span_data_index_map, - }, - postcard::PostcardProtocol, + bidirectional_protocol::msg::{Envelope, Kind, Payload}, + legacy_protocol::msg::{ + self, ExpandMacroData, ExpnGlobals, Message, SpanMode, SpanTransformer, + deserialize_span_data_index_map, serialize_span_data_index_map, }, + transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; use proc_macro_srv::{EnvSnapshot, SpanId}; @@ -39,9 +39,280 @@ pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> { match format { ProtocolFormat::JsonLegacy => run_::(), ProtocolFormat::PostcardLegacy => run_::(), + ProtocolFormat::JsonNew => run_new::(), + ProtocolFormat::PostcardNew => run_new::(), } } +fn run_new() -> io::Result<()> { + fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind { + match kind { + proc_macro_srv::ProcMacroKind::CustomDerive => { + proc_macro_api::ProcMacroKind::CustomDerive + } + proc_macro_srv::ProcMacroKind::Bang => proc_macro_api::ProcMacroKind::Bang, + proc_macro_srv::ProcMacroKind::Attr => proc_macro_api::ProcMacroKind::Attr, + } + } + + let mut buf = C::Buf::default(); + let mut stdin = io::stdin().lock(); + let mut stdout = io::stdout().lock(); + + let env_snapshot = EnvSnapshot::default(); + let srv = proc_macro_srv::ProcMacroSrv::new(&env_snapshot); + + let mut span_mode = SpanMode::Id; + + 'outer: loop { + let req_opt = Envelope::read::<_, C>(&mut stdin, &mut buf)?; + let Some(req) = req_opt else { + break 'outer; + }; + + match (req.kind, req.payload) { + (Kind::Request, Payload::Request(request)) => match request { + Request::ListMacros { dylib_path } => { + let res = srv.list_macros(&dylib_path).map(|macros| { + macros + .into_iter() + .map(|(name, kind)| (name, macro_kind_to_api(kind))) + .collect() + }); + + let resp_env = Envelope { + id: req.id, + kind: Kind::Response, + payload: Payload::Response( + proc_macro_api::bidirectional_protocol::msg::Response::ListMacros(res), + ), + }; + + resp_env.write::<_, C>(&mut stdout)?; + } + + Request::ApiVersionCheck {} => { + let resp_env = Envelope { + id: req.id, + kind: Kind::Response, + payload: Payload::Response( + proc_macro_api::bidirectional_protocol::msg::Response::ApiVersionCheck( + CURRENT_API_VERSION, + ), + ), + }; + resp_env.write::<_, C>(&mut stdout)?; + } + + Request::SetConfig(config) => { + span_mode = config.span_mode; + let resp_env = Envelope { + id: req.id, + kind: Kind::Response, + payload: Payload::Response( + proc_macro_api::bidirectional_protocol::msg::Response::SetConfig( + config, + ), + ), + }; + resp_env.write::<_, C>(&mut stdout)?; + } + + Request::ExpandMacro(task) => { + let proc_macro_api::bidirectional_protocol::msg::ExpandMacro { + lib, + env, + current_dir, + data: + proc_macro_api::bidirectional_protocol::msg::ExpandMacroData { + macro_body, + macro_name, + attributes, + has_global_spans: + proc_macro_api::bidirectional_protocol::msg::ExpnGlobals { + serialize: _, + def_site, + call_site, + mixed_site, + }, + span_data_table, + }, + } = *task; + + match span_mode { + SpanMode::Id => { + let def_site = SpanId(def_site as u32); + let call_site = SpanId(call_site as u32); + let mixed_site = SpanId(mixed_site as u32); + + let macro_body = macro_body.to_tokenstream_unresolved::( + CURRENT_API_VERSION, + |_, b| b, + ); + let attributes = attributes.map(|it| { + it.to_tokenstream_unresolved::( + CURRENT_API_VERSION, + |_, b| b, + ) + }); + + let res = srv + .expand( + lib, + &env, + current_dir, + ¯o_name, + macro_body, + attributes, + def_site, + call_site, + mixed_site, + ) + .map(|it| { + msg::FlatTree::from_tokenstream_raw::( + it, + call_site, + CURRENT_API_VERSION, + ) + }) + .map_err(|e| e.into_string().unwrap_or_default()) + .map_err(msg::PanicMessage); + + let resp_env = Envelope { + id: req.id, + kind: Kind::Response, + payload: Payload::Response(proc_macro_api::bidirectional_protocol::msg::Response::ExpandMacro(res)), + }; + + resp_env.write::<_, C>(&mut stdout)?; + } + + SpanMode::RustAnalyzer => { + let mut span_data_table = + deserialize_span_data_index_map(&span_data_table); + + let def_site_span = span_data_table[def_site]; + let call_site_span = span_data_table[call_site]; + let mixed_site_span = span_data_table[mixed_site]; + + let macro_body_ts = macro_body.to_tokenstream_resolved( + CURRENT_API_VERSION, + &span_data_table, + |a, b| srv.join_spans(a, b).unwrap_or(b), + ); + let attributes_ts = attributes.map(|it| { + it.to_tokenstream_resolved( + CURRENT_API_VERSION, + &span_data_table, + |a, b| srv.join_spans(a, b).unwrap_or(b), + ) + }); + + let (subreq_tx, subreq_rx) = unbounded::(); + let (subresp_tx, subresp_rx) = + unbounded::(); + let (result_tx, result_rx) = crossbeam_channel::bounded(1); + + std::thread::scope(|scope| { + let srv_ref = &srv; + + scope.spawn({ + let lib = lib.clone(); + let env = env.clone(); + let current_dir = current_dir.clone(); + let macro_name = macro_name.clone(); + move || { + let res = srv_ref + .expand_with_channels( + lib, + &env, + current_dir, + ¯o_name, + macro_body_ts, + attributes_ts, + def_site_span, + call_site_span, + mixed_site_span, + subresp_rx, + subreq_tx, + ) + .map(|it| { + ( + msg::FlatTree::from_tokenstream( + it, + CURRENT_API_VERSION, + call_site_span, + &mut span_data_table, + ), + serialize_span_data_index_map(&span_data_table), + ) + }) + .map(|(tree, span_data_table)| { + proc_macro_api::bidirectional_protocol::msg::ExpandMacroExtended { tree, span_data_table } + }) + .map_err(|e| e.into_string().unwrap_or_default()) + .map_err(msg::PanicMessage); + let _ = result_tx.send(res); + } + }); + + loop { + if let Ok(res) = result_rx.try_recv() { + let resp_env = Envelope { + id: req.id, + kind: Kind::Response, + payload: Payload::Response( + proc_macro_api::bidirectional_protocol::msg::Response::ExpandMacroExtended(res), + ), + }; + resp_env.write::<_, C>(&mut stdout).unwrap(); + break; + } + + let subreq = match subreq_rx.recv() { + Ok(r) => r, + Err(_) => { + break; + } + }; + + let sub_env = Envelope { + id: req.id, + kind: Kind::SubRequest, + payload: Payload::SubRequest(from_srv_req(subreq)), + }; + sub_env.write::<_, C>(&mut stdout).unwrap(); + + let resp_opt = + Envelope::read::<_, C>(&mut stdin, &mut buf).unwrap(); + let resp = match resp_opt { + Some(env) => env, + None => { + break; + } + }; + + match (resp.kind, resp.payload) { + (Kind::SubResponse, Payload::SubResponse(subresp)) => { + let _ = subresp_tx.send(from_client_res(subresp)); + } + _ => { + break; + } + } + } + }); + } + } + } + }, + _ => {} + } + } + + Ok(()) +} + fn run_() -> io::Result<()> { fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind { match kind { @@ -178,3 +449,27 @@ fn run_() -> io::Result<()> { Ok(()) } + +fn from_srv_req( + value: proc_macro_srv::SubRequest, +) -> proc_macro_api::bidirectional_protocol::msg::SubRequest { + match value { + proc_macro_srv::SubRequest::SourceText { file_id, start, end } => { + proc_macro_api::bidirectional_protocol::msg::SubRequest::SourceText { + file_id: file_id.file_id().index(), + start, + end, + } + } + } +} + +fn from_client_res( + value: proc_macro_api::bidirectional_protocol::msg::SubResponse, +) -> proc_macro_srv::SubResponse { + match value { + proc_macro_api::bidirectional_protocol::msg::SubResponse::SourceTextResult { text } => { + proc_macro_srv::SubResponse::SourceTextResult { text } + } + } +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml index 361017178409..b2abda0bfd7f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml @@ -22,6 +22,7 @@ paths.workspace = true # span = {workspace = true, default-features = false} does not work span = { path = "../span", version = "0.0.0", default-features = false} intern.workspace = true +crossbeam-channel.workspace = true ra-ap-rustc_lexer.workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index 03433197b779..ba089c9549d3 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -54,6 +54,32 @@ impl Expander { .expand(macro_name, macro_body, attribute, def_site, call_site, mixed_site) } + pub(crate) fn expand_with_channels( + &self, + macro_name: &str, + macro_body: crate::token_stream::TokenStream, + attribute: Option>, + def_site: S, + call_site: S, + mixed_site: S, + cli_to_server: crossbeam_channel::Receiver, + server_to_cli: crossbeam_channel::Sender, + ) -> Result, crate::PanicMessage> + where + ::TokenStream: Default, + { + self.inner.proc_macros.expand_with_channels( + macro_name, + macro_body, + attribute, + def_site, + call_site, + mixed_site, + cli_to_server, + server_to_cli, + ) + } + pub(crate) fn list_macros(&self) -> impl Iterator { self.inner.proc_macros.list_macros() } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs index c879c7609d91..5b6f1cf2f332 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs @@ -1,5 +1,4 @@ //! Proc macro ABI - use proc_macro::bridge; use crate::{ProcMacroKind, ProcMacroSrvSpan, token_stream::TokenStream}; @@ -32,7 +31,7 @@ impl ProcMacros { { let res = client.run( &bridge::server::SameThread, - S::make_server(call_site, def_site, mixed_site), + S::make_server(call_site, def_site, mixed_site, None, None), macro_body, cfg!(debug_assertions), ); @@ -41,7 +40,7 @@ impl ProcMacros { bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { let res = client.run( &bridge::server::SameThread, - S::make_server(call_site, def_site, mixed_site), + S::make_server(call_site, def_site, mixed_site, None, None), macro_body, cfg!(debug_assertions), ); @@ -50,7 +49,77 @@ impl ProcMacros { bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { let res = client.run( &bridge::server::SameThread, - S::make_server(call_site, def_site, mixed_site), + S::make_server(call_site, def_site, mixed_site, None, None), + parsed_attributes, + macro_body, + cfg!(debug_assertions), + ); + return res.map_err(crate::PanicMessage::from); + } + _ => continue, + } + } + + Err(bridge::PanicMessage::String(format!("proc-macro `{macro_name}` is missing")).into()) + } + + pub(crate) fn expand_with_channels( + &self, + macro_name: &str, + macro_body: TokenStream, + attribute: Option>, + def_site: S, + call_site: S, + mixed_site: S, + cli_to_server: crossbeam_channel::Receiver, + server_to_cli: crossbeam_channel::Sender, + ) -> Result, crate::PanicMessage> { + let parsed_attributes = attribute.unwrap_or_default(); + + for proc_macro in &self.0 { + match proc_macro { + bridge::client::ProcMacro::CustomDerive { trait_name, client, .. } + if *trait_name == macro_name => + { + let res = client.run( + &bridge::server::SameThread, + S::make_server( + call_site, + def_site, + mixed_site, + Some(cli_to_server), + Some(server_to_cli), + ), + macro_body, + cfg!(debug_assertions), + ); + return res.map_err(crate::PanicMessage::from); + } + bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { + let res = client.run( + &bridge::server::SameThread, + S::make_server( + call_site, + def_site, + mixed_site, + Some(cli_to_server), + Some(server_to_cli), + ), + macro_body, + cfg!(debug_assertions), + ); + return res.map_err(crate::PanicMessage::from); + } + bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { + let res = client.run( + &bridge::server::SameThread, + S::make_server( + call_site, + def_site, + mixed_site, + Some(cli_to_server), + Some(server_to_cli), + ), parsed_attributes, macro_body, cfg!(debug_assertions), diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 93319df824c0..f369ab93a2a3 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -47,7 +47,7 @@ use std::{ }; use paths::{Utf8Path, Utf8PathBuf}; -use span::Span; +use span::{EditionedFileId, Span}; use temp_dir::TempDir; pub use crate::server_impl::token_id::SpanId; @@ -91,6 +91,14 @@ impl<'env> ProcMacroSrv<'env> { } } +pub enum SubRequest { + SourceText { file_id: EditionedFileId, start: u32, end: u32 }, +} + +pub enum SubResponse { + SourceTextResult { text: Option }, +} + const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; impl ProcMacroSrv<'_> { @@ -133,6 +141,53 @@ impl ProcMacroSrv<'_> { result } + pub fn expand_with_channels( + &self, + lib: impl AsRef, + env: &[(String, String)], + current_dir: Option>, + macro_name: &str, + macro_body: token_stream::TokenStream, + attribute: Option>, + def_site: S, + call_site: S, + mixed_site: S, + cli_to_server: crossbeam_channel::Receiver, + server_to_cli: crossbeam_channel::Sender, + ) -> Result, PanicMessage> { + let snapped_env = self.env; + let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage { + message: Some(format!("failed to load macro: {err}")), + })?; + + let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref)); + + let result = thread::scope(|s| { + let thread = thread::Builder::new() + .stack_size(EXPANDER_STACK_SIZE) + .name(macro_name.to_owned()) + .spawn_scoped(s, move || { + expander.expand_with_channels( + macro_name, + macro_body, + attribute, + def_site, + call_site, + mixed_site, + cli_to_server, + server_to_cli, + ) + }); + match thread.unwrap().join() { + Ok(res) => res, + Err(e) => std::panic::resume_unwind(e), + } + }); + prev_env.rollback(); + + result + } + pub fn list_macros( &self, dylib_path: &Utf8Path, @@ -170,31 +225,54 @@ impl ProcMacroSrv<'_> { pub trait ProcMacroSrvSpan: Copy + Send + Sync { type Server: proc_macro::bridge::server::Server>; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server; + fn make_server( + call_site: Self, + def_site: Self, + mixed_site: Self, + cli_to_server: Option>, + server_to_cli: Option>, + ) -> Self::Server; } impl ProcMacroSrvSpan for SpanId { type Server = server_impl::token_id::SpanIdServer; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server { + fn make_server( + call_site: Self, + def_site: Self, + mixed_site: Self, + cli_to_server: Option>, + server_to_cli: Option>, + ) -> Self::Server { Self::Server { call_site, def_site, mixed_site, + cli_to_server, + server_to_cli, tracked_env_vars: Default::default(), tracked_paths: Default::default(), } } } + impl ProcMacroSrvSpan for Span { type Server = server_impl::rust_analyzer_span::RaSpanServer; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server { + fn make_server( + call_site: Self, + def_site: Self, + mixed_site: Self, + cli_to_server: Option>, + server_to_cli: Option>, + ) -> Self::Server { Self::Server { call_site, def_site, mixed_site, tracked_env_vars: Default::default(), tracked_paths: Default::default(), + cli_to_server, + server_to_cli, } } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 7c685c2da734..1a8f6d6730f7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -14,6 +14,7 @@ use proc_macro::bridge::server; use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TextRange, TextSize}; use crate::{ + SubRequest, SubResponse, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; @@ -28,6 +29,8 @@ pub struct RaSpanServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, + pub cli_to_server: Option>, + pub server_to_cli: Option>, } impl server::Types for RaSpanServer { @@ -149,9 +152,26 @@ impl server::Span for RaSpanServer { /// /// See PR: /// https://github.com/rust-lang/rust/pull/55780 - fn source_text(&mut self, _span: Self::Span) -> Option { + fn source_text(&mut self, span: Self::Span) -> Option { // FIXME requires db, needs special handling wrt fixup spans - None + if self.server_to_cli.is_some() && self.cli_to_server.is_some() { + let file_id = span.anchor.file_id; + let start: u32 = span.range.start().into(); + let end: u32 = span.range.end().into(); + let _ = self.server_to_cli.clone().unwrap().send(SubRequest::SourceText { + file_id, + start, + end, + }); + self.cli_to_server + .clone() + .unwrap() + .recv() + .and_then(|SubResponse::SourceTextResult { text }| Ok(text)) + .expect("REASON") + } else { + None + } } fn parent(&mut self, _span: Self::Span) -> Option { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index 5ac263b9d5f6..268042b3bc07 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -9,6 +9,7 @@ use intern::Symbol; use proc_macro::bridge::server; use crate::{ + SubRequest, SubResponse, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; @@ -34,6 +35,8 @@ pub struct SpanIdServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, + pub cli_to_server: Option>, + pub server_to_cli: Option>, } impl server::Types for SpanIdServer { @@ -139,6 +142,7 @@ impl server::Span for SpanIdServer { /// See PR: /// https://github.com/rust-lang/rust/pull/55780 fn source_text(&mut self, _span: Self::Span) -> Option { + // FIXME requires db, needs special handling wrt fixup spans None } diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 5e8b250c24a0..e08a65c39204 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -732,6 +732,7 @@ struct IdentityProcMacroExpander; impl ProcMacroExpander for IdentityProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -754,6 +755,7 @@ struct Issue18089ProcMacroExpander; impl ProcMacroExpander for Issue18089ProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -789,6 +791,7 @@ struct AttributeInputReplaceProcMacroExpander; impl ProcMacroExpander for AttributeInputReplaceProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, _: &TopSubtree, attrs: Option<&TopSubtree>, _: &Env, @@ -812,6 +815,7 @@ struct Issue18840ProcMacroExpander; impl ProcMacroExpander for Issue18840ProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, fn_: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -847,6 +851,7 @@ struct MirrorProcMacroExpander; impl ProcMacroExpander for MirrorProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, input: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -885,6 +890,7 @@ struct ShortenProcMacroExpander; impl ProcMacroExpander for ShortenProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, input: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -927,6 +933,7 @@ struct Issue17479ProcMacroExpander; impl ProcMacroExpander for Issue17479ProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -956,6 +963,7 @@ struct Issue18898ProcMacroExpander; impl ProcMacroExpander for Issue18898ProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -1011,6 +1019,7 @@ struct DisallowCfgProcMacroExpander; impl ProcMacroExpander for DisallowCfgProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -1042,6 +1051,7 @@ struct GenerateSuffixedTypeProcMacroExpander; impl ProcMacroExpander for GenerateSuffixedTypeProcMacroExpander { fn expand( &self, + _: &dyn SourceDatabase, subtree: &TopSubtree, _attrs: Option<&TopSubtree>, _env: &Env, From e260484e3eddc5eb16203512257068af78e673d8 Mon Sep 17 00:00:00 2001 From: Catherine Gasnier Date: Mon, 15 Dec 2025 06:21:38 -0800 Subject: [PATCH 0833/3801] Fix "Invariant violation: file emitted multiple times" when doing `scip .` Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: --- src/tools/rust-analyzer/crates/ide/src/static_index.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs index 7749f8e2f2ea..9d3fd9e005d8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs +++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs @@ -325,12 +325,12 @@ impl StaticIndex<'_> { }; let mut visited_files = FxHashSet::default(); for module in work { - let file_id = module.definition_source_file_id(db).original_file(db); + let file_id = + module.definition_source_file_id(db).original_file(db).file_id(&analysis.db); if visited_files.contains(&file_id) { continue; } - this.add_file(file_id.file_id(&analysis.db)); - // mark the file + this.add_file(file_id); visited_files.insert(file_id); } this From f71e6d10384de7f4458c4dfeb5eff5bec4dd4a9c Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Mon, 15 Dec 2025 23:16:08 +0900 Subject: [PATCH 0834/3801] fix: Prefix json target file with workspace root for sysroot metadata --- .../crates/project-model/src/workspace.rs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 10abb21ace83..747aa68f082d 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -391,6 +391,7 @@ impl ProjectWorkspace { sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( config, + workspace_dir, &targets, toolchain.clone(), )), @@ -500,6 +501,7 @@ impl ProjectWorkspace { sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( config, + project_json.project_root(), &targets, toolchain.clone(), )), @@ -555,6 +557,7 @@ impl ProjectWorkspace { let loaded_sysroot = sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( config, + dir, &targets, toolchain.clone(), )), @@ -1907,12 +1910,28 @@ fn add_dep_inner(graph: &mut CrateGraphBuilder, from: CrateBuilderId, dep: Depen fn sysroot_metadata_config( config: &CargoConfig, + workspace_root: &AbsPath, targets: &[String], toolchain_version: Option, ) -> CargoMetadataConfig { + // If the target is a JSON path, prefix it with workspace root directory. + // Since `cargo metadata` command for sysroot is run inside sysroots dir, it may fail to + // locate the target file if it is given as a relative path. + let targets = targets + .iter() + .map(|target| { + if target.ends_with(".json") { + // If `target` is an absolute path, this will replace the whole path. + workspace_root.join(target).to_string() + } else { + target.to_owned() + } + }) + .collect(); + CargoMetadataConfig { features: Default::default(), - targets: targets.to_vec(), + targets, extra_args: Default::default(), extra_env: config.extra_env.clone(), toolchain_version, From 8bcb4db1e52397a7d4c44479759089f706550e17 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 15 Dec 2025 20:02:26 +0530 Subject: [PATCH 0835/3801] remove salsa dependency check on proc_macro_srv_cli --- src/tools/rust-analyzer/.github/workflows/ci.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index 5975272d871a..623200aea032 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -71,9 +71,6 @@ jobs: - name: Test run: cargo test --features sysroot-abi -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api -- --quiet - - name: Check salsa dependency - run: "! (cargo tree -p proc-macro-srv-cli | grep -q salsa)" - rust: if: github.repository == 'rust-lang/rust-analyzer' name: Rust From a1f3d726e57e0f8ef12d04f679c0fec198d7fd94 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 15 Dec 2025 20:16:51 +0530 Subject: [PATCH 0836/3801] make json-new as default protocol choice for proc-macro-srv-cli --- .../rust-analyzer/crates/proc-macro-srv-cli/src/main.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index d3dae0494fe4..c9134b402dfa 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -31,7 +31,7 @@ fn main() -> std::io::Result<()> { clap::Arg::new("format") .long("format") .action(clap::ArgAction::Set) - .default_value("json-legacy") + .default_value("json-new") .value_parser(clap::builder::EnumValueParser::::new()), clap::Arg::new("version") .long("version") @@ -58,7 +58,12 @@ enum ProtocolFormat { impl ValueEnum for ProtocolFormat { fn value_variants<'a>() -> &'a [Self] { - &[ProtocolFormat::JsonLegacy, ProtocolFormat::PostcardLegacy] + &[ + ProtocolFormat::JsonLegacy, + ProtocolFormat::PostcardLegacy, + ProtocolFormat::JsonNew, + ProtocolFormat::PostcardNew, + ] } fn to_possible_value(&self) -> Option { From ddd5aad8a309ae49b3526334d2083db6b13d816a Mon Sep 17 00:00:00 2001 From: sgasho Date: Mon, 24 Nov 2025 20:50:08 +0900 Subject: [PATCH 0837/3801] feat: dlopen Enzyme --- Cargo.lock | 1 + compiler/rustc_codegen_llvm/Cargo.toml | 4 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 32 +- compiler/rustc_codegen_llvm/src/back/write.rs | 9 +- compiler/rustc_codegen_llvm/src/lib.rs | 12 + .../rustc_codegen_llvm/src/llvm/enzyme_ffi.rs | 648 +++++++++++++----- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 +- compiler/rustc_codegen_llvm/src/typetree.rs | 11 +- compiler/rustc_codegen_ssa/src/back/write.rs | 3 + .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 33 +- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 12 - src/bootstrap/src/core/build_steps/compile.rs | 13 - typos.toml | 2 + 13 files changed, 536 insertions(+), 246 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07de5d221685..1cd998a0bd2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3613,6 +3613,7 @@ dependencies = [ "gimli 0.31.1", "itertools", "libc", + "libloading 0.9.0", "measureme", "object 0.37.3", "rustc-demangle", diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 0544a94fd59f..21f6484bd0c9 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -14,6 +14,7 @@ bitflags = "2.4.1" gimli = "0.31" itertools = "0.12" libc = "0.2" +libloading = { version = "0.9.0", optional = true } measureme = "12.0.1" object = { version = "0.37.0", default-features = false, features = ["std", "read"] } rustc-demangle = "0.1.21" @@ -46,7 +47,6 @@ tracing = "0.1" [features] # tidy-alphabetical-start check_only = ["rustc_llvm/check_only"] -llvm_enzyme = [] +llvm_enzyme = ["dep:libloading"] llvm_offload = [] # tidy-alphabetical-end - diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 482e95413855..c9a5e167d9f6 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -528,31 +528,37 @@ fn thin_lto( } } -fn enable_autodiff_settings(ad: &[config::AutoDiff]) { +#[cfg(feature = "llvm_enzyme")] +pub(crate) fn enable_autodiff_settings( + sysroot: &rustc_session::config::Sysroot, + ad: &[config::AutoDiff], +) { + let mut enzyme = llvm::EnzymeWrapper::get_or_init(sysroot); + for val in ad { // We intentionally don't use a wildcard, to not forget handling anything new. match val { config::AutoDiff::PrintPerf => { - llvm::set_print_perf(true); + enzyme.set_print_perf(true); } config::AutoDiff::PrintAA => { - llvm::set_print_activity(true); + enzyme.set_print_activity(true); } config::AutoDiff::PrintTA => { - llvm::set_print_type(true); + enzyme.set_print_type(true); } config::AutoDiff::PrintTAFn(fun) => { - llvm::set_print_type(true); // Enable general type printing - llvm::set_print_type_fun(&fun); // Set specific function to analyze + enzyme.set_print_type(true); // Enable general type printing + enzyme.set_print_type_fun(&fun); // Set specific function to analyze } config::AutoDiff::Inline => { - llvm::set_inline(true); + enzyme.set_inline(true); } config::AutoDiff::LooseTypes => { - llvm::set_loose_types(true); + enzyme.set_loose_types(true); } config::AutoDiff::PrintSteps => { - llvm::set_print(true); + enzyme.set_print(true); } // We handle this in the PassWrapper.cpp config::AutoDiff::PrintPasses => {} @@ -571,9 +577,9 @@ fn enable_autodiff_settings(ad: &[config::AutoDiff]) { } } // This helps with handling enums for now. - llvm::set_strict_aliasing(false); + enzyme.set_strict_aliasing(false); // FIXME(ZuseZ4): Test this, since it was added a long time ago. - llvm::set_rust_rules(true); + enzyme.set_rust_rules(true); } pub(crate) fn run_pass_manager( @@ -607,10 +613,6 @@ pub(crate) fn run_pass_manager( if enable_ad { write::AutodiffStage::DuringAD } else { write::AutodiffStage::PostAD } }; - if enable_ad { - enable_autodiff_settings(&config.autodiff); - } - unsafe { write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage); } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 2c4943e835a6..ecac6e6503cb 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -730,6 +730,13 @@ pub(crate) unsafe fn llvm_optimize( let llvm_plugins = config.llvm_plugins.join(","); + let enzyme_fn = if consider_ad { + let wrapper = llvm::EnzymeWrapper::get_or_init(&cgcx.sysroot); + wrapper.registerEnzymeAndPassPipeline + } else { + std::ptr::null() + }; + let result = unsafe { llvm::LLVMRustOptimize( module.module_llvm.llmod(), @@ -749,7 +756,7 @@ pub(crate) unsafe fn llvm_optimize( vectorize_loop, config.no_builtins, config.emit_lifetime_markers, - run_enzyme, + enzyme_fn, print_before_enzyme, print_after_enzyme, print_passes, diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 0da5810518c5..b0901d5f3e1e 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -240,6 +240,18 @@ impl CodegenBackend for LlvmCodegenBackend { fn init(&self, sess: &Session) { llvm_util::init(sess); // Make sure llvm is inited + + #[cfg(feature = "llvm_enzyme")] + { + use rustc_session::config::AutoDiff; + if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) { + { + use crate::back::lto::enable_autodiff_settings; + + enable_autodiff_settings(&sess.opts.sysroot, &sess.opts.unstable_opts.autodiff); + } + } + } } fn provide(&self, providers: &mut Providers) { diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index e63043b21227..28923bf2743e 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -91,102 +91,363 @@ pub(crate) use self::Enzyme_AD::*; #[cfg(feature = "llvm_enzyme")] pub(crate) mod Enzyme_AD { - use std::ffi::{CString, c_char}; + use std::ffi::{c_char, c_void}; + use std::sync::{Mutex, MutexGuard, OnceLock}; - use libc::c_void; + use rustc_middle::bug; + use rustc_session::config::{Sysroot, host_tuple}; + use rustc_session::filesearch; use super::{CConcreteType, CTypeTreeRef, Context}; + use crate::llvm::{EnzymeTypeTree, LLVMRustVersionMajor}; - unsafe extern "C" { - pub(crate) fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8); - pub(crate) fn EnzymeSetCLString(arg1: *mut ::std::os::raw::c_void, arg2: *const c_char); + type EnzymeSetCLBoolFn = unsafe extern "C" fn(*mut c_void, u8); + type EnzymeSetCLStringFn = unsafe extern "C" fn(*mut c_void, *const c_char); + + type EnzymeNewTypeTreeFn = unsafe extern "C" fn() -> CTypeTreeRef; + type EnzymeNewTypeTreeCTFn = unsafe extern "C" fn(CConcreteType, &Context) -> CTypeTreeRef; + type EnzymeNewTypeTreeTRFn = unsafe extern "C" fn(CTypeTreeRef) -> CTypeTreeRef; + type EnzymeFreeTypeTreeFn = unsafe extern "C" fn(CTypeTreeRef); + type EnzymeMergeTypeTreeFn = unsafe extern "C" fn(CTypeTreeRef, CTypeTreeRef) -> bool; + type EnzymeTypeTreeOnlyEqFn = unsafe extern "C" fn(CTypeTreeRef, i64); + type EnzymeTypeTreeData0EqFn = unsafe extern "C" fn(CTypeTreeRef); + type EnzymeTypeTreeShiftIndiciesEqFn = + unsafe extern "C" fn(CTypeTreeRef, *const c_char, i64, i64, u64); + type EnzymeTypeTreeInsertEqFn = + unsafe extern "C" fn(CTypeTreeRef, *const i64, usize, CConcreteType, &Context); + type EnzymeTypeTreeToStringFn = unsafe extern "C" fn(CTypeTreeRef) -> *const c_char; + type EnzymeTypeTreeToStringFreeFn = unsafe extern "C" fn(*const c_char); + + #[allow(non_snake_case)] + pub(crate) struct EnzymeWrapper { + EnzymeNewTypeTree: EnzymeNewTypeTreeFn, + EnzymeNewTypeTreeCT: EnzymeNewTypeTreeCTFn, + EnzymeNewTypeTreeTR: EnzymeNewTypeTreeTRFn, + EnzymeFreeTypeTree: EnzymeFreeTypeTreeFn, + EnzymeMergeTypeTree: EnzymeMergeTypeTreeFn, + EnzymeTypeTreeOnlyEq: EnzymeTypeTreeOnlyEqFn, + EnzymeTypeTreeData0Eq: EnzymeTypeTreeData0EqFn, + EnzymeTypeTreeShiftIndiciesEq: EnzymeTypeTreeShiftIndiciesEqFn, + EnzymeTypeTreeInsertEq: EnzymeTypeTreeInsertEqFn, + EnzymeTypeTreeToString: EnzymeTypeTreeToStringFn, + EnzymeTypeTreeToStringFree: EnzymeTypeTreeToStringFreeFn, + + EnzymePrintPerf: *mut c_void, + EnzymePrintActivity: *mut c_void, + EnzymePrintType: *mut c_void, + EnzymeFunctionToAnalyze: *mut c_void, + EnzymePrint: *mut c_void, + EnzymeStrictAliasing: *mut c_void, + EnzymeInline: *mut c_void, + EnzymeMaxTypeDepth: *mut c_void, + RustTypeRules: *mut c_void, + looseTypeAnalysis: *mut c_void, + + EnzymeSetCLBool: EnzymeSetCLBoolFn, + EnzymeSetCLString: EnzymeSetCLStringFn, + pub registerEnzymeAndPassPipeline: *const c_void, + lib: libloading::Library, } - // TypeTree functions - unsafe extern "C" { - pub(crate) fn EnzymeNewTypeTree() -> CTypeTreeRef; - pub(crate) fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef; - pub(crate) fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef; - pub(crate) fn EnzymeFreeTypeTree(CTT: CTypeTreeRef); - pub(crate) fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool; - pub(crate) fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64); - pub(crate) fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef); - pub(crate) fn EnzymeTypeTreeShiftIndiciesEq( - arg1: CTypeTreeRef, + unsafe impl Sync for EnzymeWrapper {} + unsafe impl Send for EnzymeWrapper {} + + fn load_ptr_by_symbol_mut_void( + lib: &libloading::Library, + bytes: &[u8], + ) -> Result<*mut c_void, Box> { + unsafe { + let s: libloading::Symbol<'_, *mut c_void> = lib.get(bytes)?; + // libloading = 0.9.0: try_as_raw_ptr always succeeds and returns Some + let s = s.try_as_raw_ptr().unwrap(); + Ok(s) + } + } + + // e.g. + // load_ptrs_by_symbols_mut_void(ABC, XYZ); + // => + // let ABC = load_ptr_mut_void(&lib, b"ABC")?; + // let XYZ = load_ptr_mut_void(&lib, b"XYZ")?; + macro_rules! load_ptrs_by_symbols_mut_void { + ($lib:expr, $($name:ident),* $(,)?) => { + $( + #[allow(non_snake_case)] + let $name = load_ptr_by_symbol_mut_void(&$lib, stringify!($name).as_bytes())?; + )* + }; + } + + // e.g. + // load_ptrs_by_symbols_fn(ABC: ABCFn, XYZ: XYZFn); + // => + // let ABC: libloading::Symbol<'_, ABCFn> = unsafe { lib.get(b"ABC")? }; + // let XYZ: libloading::Symbol<'_, XYZFn> = unsafe { lib.get(b"XYZ")? }; + macro_rules! load_ptrs_by_symbols_fn { + ($lib:expr, $($name:ident : $ty:ty),* $(,)?) => { + $( + #[allow(non_snake_case)] + let $name: $ty = *unsafe { $lib.get::<$ty>(stringify!($name).as_bytes())? }; + )* + }; + } + + static ENZYME_INSTANCE: OnceLock> = OnceLock::new(); + + impl EnzymeWrapper { + /// Initialize EnzymeWrapper with the given sysroot if not already initialized. + /// Safe to call multiple times - subsequent calls are no-ops due to OnceLock. + pub(crate) fn get_or_init( + sysroot: &rustc_session::config::Sysroot, + ) -> MutexGuard<'static, Self> { + ENZYME_INSTANCE + .get_or_init(|| { + Self::call_dynamic(sysroot) + .unwrap_or_else(|e| bug!("failed to load Enzyme: {e}")) + .into() + }) + .lock() + .unwrap() + } + + /// Get the EnzymeWrapper instance. Panics if not initialized. + pub(crate) fn get_instance() -> MutexGuard<'static, Self> { + ENZYME_INSTANCE + .get() + .expect("EnzymeWrapper not initialized. Call get_or_init with sysroot first.") + .lock() + .unwrap() + } + + pub(crate) fn new_type_tree(&self) -> CTypeTreeRef { + unsafe { (self.EnzymeNewTypeTree)() } + } + + pub(crate) fn new_type_tree_ct( + &self, + t: CConcreteType, + ctx: &Context, + ) -> *mut EnzymeTypeTree { + unsafe { (self.EnzymeNewTypeTreeCT)(t, ctx) } + } + + pub(crate) fn new_type_tree_tr(&self, tree: CTypeTreeRef) -> CTypeTreeRef { + unsafe { (self.EnzymeNewTypeTreeTR)(tree) } + } + + pub(crate) fn free_type_tree(&self, tree: CTypeTreeRef) { + unsafe { (self.EnzymeFreeTypeTree)(tree) } + } + + pub(crate) fn merge_type_tree(&self, tree1: CTypeTreeRef, tree2: CTypeTreeRef) -> bool { + unsafe { (self.EnzymeMergeTypeTree)(tree1, tree2) } + } + + pub(crate) fn tree_only_eq(&self, tree: CTypeTreeRef, num: i64) { + unsafe { (self.EnzymeTypeTreeOnlyEq)(tree, num) } + } + + pub(crate) fn tree_data0_eq(&self, tree: CTypeTreeRef) { + unsafe { (self.EnzymeTypeTreeData0Eq)(tree) } + } + + pub(crate) fn shift_indicies_eq( + &self, + tree: CTypeTreeRef, data_layout: *const c_char, offset: i64, max_size: i64, add_offset: u64, - ); - pub(crate) fn EnzymeTypeTreeInsertEq( - CTT: CTypeTreeRef, + ) { + unsafe { + (self.EnzymeTypeTreeShiftIndiciesEq)( + tree, + data_layout, + offset, + max_size, + add_offset, + ) + } + } + + pub(crate) fn tree_insert_eq( + &self, + tree: CTypeTreeRef, indices: *const i64, len: usize, ct: CConcreteType, ctx: &Context, - ); - pub(crate) fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char; - pub(crate) fn EnzymeTypeTreeToStringFree(arg1: *const c_char); - } + ) { + unsafe { (self.EnzymeTypeTreeInsertEq)(tree, indices, len, ct, ctx) } + } - unsafe extern "C" { - static mut EnzymePrintPerf: c_void; - static mut EnzymePrintActivity: c_void; - static mut EnzymePrintType: c_void; - static mut EnzymeFunctionToAnalyze: c_void; - static mut EnzymePrint: c_void; - static mut EnzymeStrictAliasing: c_void; - static mut looseTypeAnalysis: c_void; - static mut EnzymeInline: c_void; - static mut RustTypeRules: c_void; - } - pub(crate) fn set_print_perf(print: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintPerf), print as u8); + pub(crate) fn tree_to_string(&self, tree: *mut EnzymeTypeTree) -> *const c_char { + unsafe { (self.EnzymeTypeTreeToString)(tree) } } - } - pub(crate) fn set_print_activity(print: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintActivity), print as u8); + + pub(crate) fn tree_to_string_free(&self, ch: *const c_char) { + unsafe { (self.EnzymeTypeTreeToStringFree)(ch) } } - } - pub(crate) fn set_print_type(print: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintType), print as u8); + + pub(crate) fn get_max_type_depth(&self) -> usize { + unsafe { std::ptr::read::(self.EnzymeMaxTypeDepth as *const u32) as usize } } - } - pub(crate) fn set_print_type_fun(fun_name: &str) { - let c_fun_name = CString::new(fun_name).unwrap(); - unsafe { - EnzymeSetCLString( - std::ptr::addr_of_mut!(EnzymeFunctionToAnalyze), - c_fun_name.as_ptr() as *const c_char, + + pub(crate) fn set_print_perf(&mut self, print: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymePrintPerf, print as u8); + } + } + + pub(crate) fn set_print_activity(&mut self, print: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymePrintActivity, print as u8); + } + } + + pub(crate) fn set_print_type(&mut self, print: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymePrintType, print as u8); + } + } + + pub(crate) fn set_print_type_fun(&mut self, fun_name: &str) { + let c_fun_name = std::ffi::CString::new(fun_name) + .unwrap_or_else(|err| bug!("failed to set_print_type_fun: {err}")); + unsafe { + (self.EnzymeSetCLString)( + self.EnzymeFunctionToAnalyze, + c_fun_name.as_ptr() as *const c_char, + ); + } + } + + pub(crate) fn set_print(&mut self, print: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymePrint, print as u8); + } + } + + pub(crate) fn set_strict_aliasing(&mut self, strict: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymeStrictAliasing, strict as u8); + } + } + + pub(crate) fn set_loose_types(&mut self, loose: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.looseTypeAnalysis, loose as u8); + } + } + + pub(crate) fn set_inline(&mut self, val: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymeInline, val as u8); + } + } + + pub(crate) fn set_rust_rules(&mut self, val: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.RustTypeRules, val as u8); + } + } + + #[allow(non_snake_case)] + fn call_dynamic( + sysroot: &rustc_session::config::Sysroot, + ) -> Result> { + let enzyme_path = Self::get_enzyme_path(sysroot)?; + let lib = unsafe { libloading::Library::new(enzyme_path)? }; + + load_ptrs_by_symbols_fn!( + lib, + EnzymeNewTypeTree: EnzymeNewTypeTreeFn, + EnzymeNewTypeTreeCT: EnzymeNewTypeTreeCTFn, + EnzymeNewTypeTreeTR: EnzymeNewTypeTreeTRFn, + EnzymeFreeTypeTree: EnzymeFreeTypeTreeFn, + EnzymeMergeTypeTree: EnzymeMergeTypeTreeFn, + EnzymeTypeTreeOnlyEq: EnzymeTypeTreeOnlyEqFn, + EnzymeTypeTreeData0Eq: EnzymeTypeTreeData0EqFn, + EnzymeTypeTreeShiftIndiciesEq: EnzymeTypeTreeShiftIndiciesEqFn, + EnzymeTypeTreeInsertEq: EnzymeTypeTreeInsertEqFn, + EnzymeTypeTreeToString: EnzymeTypeTreeToStringFn, + EnzymeTypeTreeToStringFree: EnzymeTypeTreeToStringFreeFn, + EnzymeSetCLBool: EnzymeSetCLBoolFn, + EnzymeSetCLString: EnzymeSetCLStringFn, ); + + load_ptrs_by_symbols_mut_void!( + lib, + registerEnzymeAndPassPipeline, + EnzymePrintPerf, + EnzymePrintActivity, + EnzymePrintType, + EnzymeFunctionToAnalyze, + EnzymePrint, + EnzymeStrictAliasing, + EnzymeInline, + EnzymeMaxTypeDepth, + RustTypeRules, + looseTypeAnalysis, + ); + + Ok(Self { + EnzymeNewTypeTree, + EnzymeNewTypeTreeCT, + EnzymeNewTypeTreeTR, + EnzymeFreeTypeTree, + EnzymeMergeTypeTree, + EnzymeTypeTreeOnlyEq, + EnzymeTypeTreeData0Eq, + EnzymeTypeTreeShiftIndiciesEq, + EnzymeTypeTreeInsertEq, + EnzymeTypeTreeToString, + EnzymeTypeTreeToStringFree, + EnzymePrintPerf, + EnzymePrintActivity, + EnzymePrintType, + EnzymeFunctionToAnalyze, + EnzymePrint, + EnzymeStrictAliasing, + EnzymeInline, + EnzymeMaxTypeDepth, + RustTypeRules, + looseTypeAnalysis, + EnzymeSetCLBool, + EnzymeSetCLString, + registerEnzymeAndPassPipeline, + lib, + }) } - } - pub(crate) fn set_print(print: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrint), print as u8); - } - } - pub(crate) fn set_strict_aliasing(strict: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeStrictAliasing), strict as u8); - } - } - pub(crate) fn set_loose_types(loose: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(looseTypeAnalysis), loose as u8); - } - } - pub(crate) fn set_inline(val: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeInline), val as u8); - } - } - pub(crate) fn set_rust_rules(val: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(RustTypeRules), val as u8); + + fn get_enzyme_path(sysroot: &Sysroot) -> Result { + let llvm_version_major = unsafe { LLVMRustVersionMajor() }; + + let path_buf = sysroot + .all_paths() + .map(|sysroot_path| { + filesearch::make_target_lib_path(sysroot_path, host_tuple()) + .join("lib") + .with_file_name(format!("libEnzyme-{llvm_version_major}")) + .with_extension(std::env::consts::DLL_EXTENSION) + }) + .find(|f| f.exists()) + .ok_or_else(|| { + let candidates = sysroot + .all_paths() + .map(|p| p.join("lib").display().to_string()) + .collect::>() + .join("\n* "); + format!( + "failed to find a `libEnzyme-{llvm_version_major}` folder \ + in the sysroot candidates:\n* {candidates}" + ) + })?; + + Ok(path_buf + .to_str() + .ok_or_else(|| format!("invalid UTF-8 in path: {}", path_buf.display()))? + .to_string()) } } } @@ -198,111 +459,156 @@ pub(crate) use self::Fallback_AD::*; pub(crate) mod Fallback_AD { #![allow(unused_variables)] + use std::ffi::c_void; + use std::sync::{Mutex, MutexGuard}; + use libc::c_char; + use rustc_codegen_ssa::back::write::CodegenContext; + use rustc_codegen_ssa::traits::WriteBackendMethods; - use super::{CConcreteType, CTypeTreeRef, Context}; + use super::{CConcreteType, CTypeTreeRef, Context, EnzymeTypeTree}; - // TypeTree function fallbacks - pub(crate) unsafe fn EnzymeNewTypeTree() -> CTypeTreeRef { - unimplemented!() + pub(crate) struct EnzymeWrapper { + pub registerEnzymeAndPassPipeline: *const c_void, } - pub(crate) unsafe fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef { - unimplemented!() - } + impl EnzymeWrapper { + pub(crate) fn get_or_init( + _sysroot: &rustc_session::config::Sysroot, + ) -> MutexGuard<'static, Self> { + unimplemented!("Enzyme not available: build with llvm_enzyme feature") + } - pub(crate) unsafe fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef { - unimplemented!() - } + pub(crate) fn init<'a, B: WriteBackendMethods>( + _cgcx: &'a CodegenContext, + ) -> &'static Mutex { + unimplemented!("Enzyme not available: build with llvm_enzyme feature") + } - pub(crate) unsafe fn EnzymeFreeTypeTree(CTT: CTypeTreeRef) { - unimplemented!() - } + pub(crate) fn get_instance() -> MutexGuard<'static, Self> { + unimplemented!("Enzyme not available: build with llvm_enzyme feature") + } - pub(crate) unsafe fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool { - unimplemented!() - } + pub(crate) fn new_type_tree(&self) -> CTypeTreeRef { + unimplemented!() + } - pub(crate) unsafe fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64) { - unimplemented!() - } + pub(crate) fn new_type_tree_ct( + &self, + t: CConcreteType, + ctx: &Context, + ) -> *mut EnzymeTypeTree { + unimplemented!() + } - pub(crate) unsafe fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef) { - unimplemented!() - } + pub(crate) fn new_type_tree_tr(&self, tree: CTypeTreeRef) -> CTypeTreeRef { + unimplemented!() + } - pub(crate) unsafe fn EnzymeTypeTreeShiftIndiciesEq( - arg1: CTypeTreeRef, - data_layout: *const c_char, - offset: i64, - max_size: i64, - add_offset: u64, - ) { - unimplemented!() - } + pub(crate) fn free_type_tree(&self, tree: CTypeTreeRef) { + unimplemented!() + } - pub(crate) unsafe fn EnzymeTypeTreeInsertEq( - CTT: CTypeTreeRef, - indices: *const i64, - len: usize, - ct: CConcreteType, - ctx: &Context, - ) { - unimplemented!() - } + pub(crate) fn merge_type_tree(&self, tree1: CTypeTreeRef, tree2: CTypeTreeRef) -> bool { + unimplemented!() + } - pub(crate) unsafe fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char { - unimplemented!() - } + pub(crate) fn tree_only_eq(&self, tree: CTypeTreeRef, num: i64) { + unimplemented!() + } - pub(crate) unsafe fn EnzymeTypeTreeToStringFree(arg1: *const c_char) { - unimplemented!() - } + pub(crate) fn tree_data0_eq(&self, tree: CTypeTreeRef) { + unimplemented!() + } - pub(crate) fn set_inline(val: bool) { - unimplemented!() - } - pub(crate) fn set_print_perf(print: bool) { - unimplemented!() - } - pub(crate) fn set_print_activity(print: bool) { - unimplemented!() - } - pub(crate) fn set_print_type(print: bool) { - unimplemented!() - } - pub(crate) fn set_print_type_fun(fun_name: &str) { - unimplemented!() - } - pub(crate) fn set_print(print: bool) { - unimplemented!() - } - pub(crate) fn set_strict_aliasing(strict: bool) { - unimplemented!() - } - pub(crate) fn set_loose_types(loose: bool) { - unimplemented!() - } - pub(crate) fn set_rust_rules(val: bool) { - unimplemented!() + pub(crate) fn shift_indicies_eq( + &self, + tree: CTypeTreeRef, + data_layout: *const c_char, + offset: i64, + max_size: i64, + add_offset: u64, + ) { + unimplemented!() + } + + pub(crate) fn tree_insert_eq( + &self, + tree: CTypeTreeRef, + indices: *const i64, + len: usize, + ct: CConcreteType, + ctx: &Context, + ) { + unimplemented!() + } + + pub(crate) fn tree_to_string(&self, tree: *mut EnzymeTypeTree) -> *const c_char { + unimplemented!() + } + + pub(crate) fn tree_to_string_free(&self, ch: *const c_char) { + unimplemented!() + } + + pub(crate) fn get_max_type_depth(&self) -> usize { + unimplemented!() + } + + pub(crate) fn set_inline(&mut self, val: bool) { + unimplemented!() + } + + pub(crate) fn set_print_perf(&mut self, print: bool) { + unimplemented!() + } + + pub(crate) fn set_print_activity(&mut self, print: bool) { + unimplemented!() + } + + pub(crate) fn set_print_type(&mut self, print: bool) { + unimplemented!() + } + + pub(crate) fn set_print_type_fun(&mut self, fun_name: &str) { + unimplemented!() + } + + pub(crate) fn set_print(&mut self, print: bool) { + unimplemented!() + } + + pub(crate) fn set_strict_aliasing(&mut self, strict: bool) { + unimplemented!() + } + + pub(crate) fn set_loose_types(&mut self, loose: bool) { + unimplemented!() + } + + pub(crate) fn set_rust_rules(&mut self, val: bool) { + unimplemented!() + } } } impl TypeTree { pub(crate) fn new() -> TypeTree { - let inner = unsafe { EnzymeNewTypeTree() }; + let wrapper = EnzymeWrapper::get_instance(); + let inner = wrapper.new_type_tree(); TypeTree { inner } } pub(crate) fn from_type(t: CConcreteType, ctx: &Context) -> TypeTree { - let inner = unsafe { EnzymeNewTypeTreeCT(t, ctx) }; + let wrapper = EnzymeWrapper::get_instance(); + let inner = wrapper.new_type_tree_ct(t, ctx); TypeTree { inner } } pub(crate) fn merge(self, other: Self) -> Self { - unsafe { - EnzymeMergeTypeTree(self.inner, other.inner); - } + let wrapper = EnzymeWrapper::get_instance(); + wrapper.merge_type_tree(self.inner, other.inner); drop(other); self } @@ -316,37 +622,36 @@ impl TypeTree { add_offset: usize, ) -> Self { let layout = std::ffi::CString::new(layout).unwrap(); - - unsafe { - EnzymeTypeTreeShiftIndiciesEq( - self.inner, - layout.as_ptr(), - offset as i64, - max_size as i64, - add_offset as u64, - ); - } + let wrapper = EnzymeWrapper::get_instance(); + wrapper.shift_indicies_eq( + self.inner, + layout.as_ptr(), + offset as i64, + max_size as i64, + add_offset as u64, + ); self } pub(crate) fn insert(&mut self, indices: &[i64], ct: CConcreteType, ctx: &Context) { - unsafe { - EnzymeTypeTreeInsertEq(self.inner, indices.as_ptr(), indices.len(), ct, ctx); - } + let wrapper = EnzymeWrapper::get_instance(); + wrapper.tree_insert_eq(self.inner, indices.as_ptr(), indices.len(), ct, ctx); } } impl Clone for TypeTree { fn clone(&self) -> Self { - let inner = unsafe { EnzymeNewTypeTreeTR(self.inner) }; + let wrapper = EnzymeWrapper::get_instance(); + let inner = wrapper.new_type_tree_tr(self.inner); TypeTree { inner } } } impl std::fmt::Display for TypeTree { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let ptr = unsafe { EnzymeTypeTreeToString(self.inner) }; + let wrapper = EnzymeWrapper::get_instance(); + let ptr = wrapper.tree_to_string(self.inner); let cstr = unsafe { std::ffi::CStr::from_ptr(ptr) }; match cstr.to_str() { Ok(x) => write!(f, "{}", x)?, @@ -354,9 +659,7 @@ impl std::fmt::Display for TypeTree { } // delete C string pointer - unsafe { - EnzymeTypeTreeToStringFree(ptr); - } + wrapper.tree_to_string_free(ptr); Ok(()) } @@ -370,6 +673,7 @@ impl std::fmt::Debug for TypeTree { impl Drop for TypeTree { fn drop(&mut self) { - unsafe { EnzymeFreeTypeTree(self.inner) } + let wrapper = EnzymeWrapper::get_instance(); + wrapper.free_type_tree(self.inner) } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8abf8b24d9d6..7835319f5c1d 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2411,7 +2411,7 @@ unsafe extern "C" { LoopVectorize: bool, DisableSimplifyLibCalls: bool, EmitLifetimeMarkers: bool, - RunEnzyme: bool, + RunEnzyme: *const c_void, PrintBeforeEnzyme: bool, PrintAfterEnzyme: bool, PrintPasses: bool, diff --git a/compiler/rustc_codegen_llvm/src/typetree.rs b/compiler/rustc_codegen_llvm/src/typetree.rs index 7e2635037008..513a832e7fe8 100644 --- a/compiler/rustc_codegen_llvm/src/typetree.rs +++ b/compiler/rustc_codegen_llvm/src/typetree.rs @@ -2,6 +2,7 @@ use rustc_ast::expand::typetree::FncTree; #[cfg(feature = "llvm_enzyme")] use { crate::attributes, + crate::llvm::EnzymeWrapper, rustc_ast::expand::typetree::TypeTree as RustTypeTree, std::ffi::{CString, c_char, c_uint}, }; @@ -77,7 +78,8 @@ pub(crate) fn add_tt<'ll>( for (i, input) in inputs.iter().enumerate() { unsafe { let enzyme_tt = to_enzyme_typetree(input.clone(), llvm_data_layout, llcx); - let c_str = llvm::EnzymeTypeTreeToString(enzyme_tt.inner); + let enzyme_wrapper = EnzymeWrapper::get_instance(); + let c_str = enzyme_wrapper.tree_to_string(enzyme_tt.inner); let c_str = std::ffi::CStr::from_ptr(c_str); let attr = llvm::LLVMCreateStringAttribute( @@ -89,13 +91,14 @@ pub(crate) fn add_tt<'ll>( ); attributes::apply_to_llfn(fn_def, llvm::AttributePlace::Argument(i as u32), &[attr]); - llvm::EnzymeTypeTreeToStringFree(c_str.as_ptr()); + enzyme_wrapper.tree_to_string_free(c_str.as_ptr()); } } unsafe { let enzyme_tt = to_enzyme_typetree(ret_tt, llvm_data_layout, llcx); - let c_str = llvm::EnzymeTypeTreeToString(enzyme_tt.inner); + let enzyme_wrapper = EnzymeWrapper::get_instance(); + let c_str = enzyme_wrapper.tree_to_string(enzyme_tt.inner); let c_str = std::ffi::CStr::from_ptr(c_str); let ret_attr = llvm::LLVMCreateStringAttribute( @@ -107,7 +110,7 @@ pub(crate) fn add_tt<'ll>( ); attributes::apply_to_llfn(fn_def, llvm::AttributePlace::ReturnValue, &[ret_attr]); - llvm::EnzymeTypeTreeToStringFree(c_str.as_ptr()); + enzyme_wrapper.tree_to_string_free(c_str.as_ptr()); } } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 3e36bd8552b1..3196b51e0c2b 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -29,6 +29,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{ self, CrateType, Lto, OutFileName, OutputFilenames, OutputType, Passes, SwitchWithOptPath, + Sysroot, }; use rustc_span::source_map::SourceMap; use rustc_span::{FileName, InnerSpan, Span, SpanData, sym}; @@ -346,6 +347,7 @@ pub struct CodegenContext { pub split_debuginfo: rustc_target::spec::SplitDebuginfo, pub split_dwarf_kind: rustc_session::config::SplitDwarfKind, pub pointer_size: Size, + pub sysroot: Sysroot, /// Emitter to use for diagnostics produced during codegen. pub diag_emitter: SharedEmitter, @@ -1317,6 +1319,7 @@ fn start_executing_work( parallel: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend, pointer_size: tcx.data_layout.pointer_size(), invocation_temp: sess.invocation_temp.clone(), + sysroot: sess.opts.sysroot.clone(), }; // This is the "main loop" of parallel work happening for parallel codegen. diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 714ba0f177a8..95cbec1b37b4 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -550,17 +550,8 @@ struct LLVMRustSanitizerOptions { bool SanitizeKernelAddressRecover; }; -// This symbol won't be available or used when Enzyme is not enabled. -// Always set AugmentPassBuilder to true, since it registers optimizations which -// will improve the performance for Enzyme. -#ifdef ENZYME -extern "C" void registerEnzymeAndPassPipeline(llvm::PassBuilder &PB, - /* augmentPassBuilder */ bool); - -extern "C" { -extern llvm::cl::opt EnzymeFunctionToAnalyze; -} -#endif +extern "C" typedef void (*registerEnzymeAndPassPipelineFn)( + llvm::PassBuilder &PB, bool augment); extern "C" LLVMRustResult LLVMRustOptimize( LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef, @@ -569,8 +560,8 @@ extern "C" LLVMRustResult LLVMRustOptimize( bool LintIR, LLVMRustThinLTOBuffer **ThinLTOBufferRef, bool EmitThinLTO, bool EmitThinLTOSummary, bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, - bool EmitLifetimeMarkers, bool RunEnzyme, bool PrintBeforeEnzyme, - bool PrintAfterEnzyme, bool PrintPasses, + bool EmitLifetimeMarkers, registerEnzymeAndPassPipelineFn EnzymePtr, + bool PrintBeforeEnzyme, bool PrintAfterEnzyme, bool PrintPasses, LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage, const char *InstrProfileOutput, const char *PGOSampleUsePath, @@ -907,8 +898,8 @@ extern "C" LLVMRustResult LLVMRustOptimize( } // now load "-enzyme" pass: -#ifdef ENZYME - if (RunEnzyme) { + // With dlopen, ENZYME macro may not be defined, so check EnzymePtr directly + if (EnzymePtr) { if (PrintBeforeEnzyme) { // Handle the Rust flag `-Zautodiff=PrintModBefore`. @@ -916,29 +907,19 @@ extern "C" LLVMRustResult LLVMRustOptimize( MPM.addPass(PrintModulePass(outs(), Banner, true, false)); } - registerEnzymeAndPassPipeline(PB, false); + EnzymePtr(PB, false); if (auto Err = PB.parsePassPipeline(MPM, "enzyme")) { std::string ErrMsg = toString(std::move(Err)); LLVMRustSetLastError(ErrMsg.c_str()); return LLVMRustResult::Failure; } - // Check if PrintTAFn was used and add type analysis pass if needed - if (!EnzymeFunctionToAnalyze.empty()) { - if (auto Err = PB.parsePassPipeline(MPM, "print-type-analysis")) { - std::string ErrMsg = toString(std::move(Err)); - LLVMRustSetLastError(ErrMsg.c_str()); - return LLVMRustResult::Failure; - } - } - if (PrintAfterEnzyme) { // Handle the Rust flag `-Zautodiff=PrintModAfter`. std::string Banner = "Module after EnzymeNewPM"; MPM.addPass(PrintModulePass(outs(), Banner, true, false)); } } -#endif if (PrintPasses) { // Print all passes from the PM: std::string Pipeline; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index dda06e9b2bf6..0720af0eb7e0 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1791,18 +1791,6 @@ extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) { GV.setSanitizerMetadata(MD); } -#ifdef ENZYME -extern "C" { -extern llvm::cl::opt EnzymeMaxTypeDepth; -} - -extern "C" size_t LLVMRustEnzymeGetMaxTypeDepth() { return EnzymeMaxTypeDepth; } -#else -extern "C" size_t LLVMRustEnzymeGetMaxTypeDepth() { - return 6; // Default fallback depth -} -#endif - // Statically assert that the fixed metadata kind IDs declared in // `metadata_kind.rs` match the ones actually used by LLVM. #define FIXED_MD_KIND(VARIANT, VALUE) \ diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 82cc25f123bc..2f6a0ef6575d 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1232,19 +1232,6 @@ pub fn rustc_cargo( // . cargo.rustflag("-Zon-broken-pipe=kill"); - // We want to link against registerEnzyme and in the future we want to use additional - // functionality from Enzyme core. For that we need to link against Enzyme. - if builder.config.llvm_enzyme { - let arch = builder.build.host_target; - let enzyme_dir = builder.build.out.join(arch).join("enzyme").join("lib"); - cargo.rustflag("-L").rustflag(enzyme_dir.to_str().expect("Invalid path")); - - if let Some(llvm_config) = builder.llvm_config(builder.config.host_target) { - let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config); - cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}")); - } - } - // Building with protected visibility reduces the number of dynamic relocations needed, giving // us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object // with direct references to protected symbols, so for now we only use protected symbols if diff --git a/typos.toml b/typos.toml index 758239ffe751..b9d9c6c3522c 100644 --- a/typos.toml +++ b/typos.toml @@ -50,6 +50,8 @@ unstalled = "unstalled" debug_aranges = "debug_aranges" DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME = "DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME" EnzymeTypeTreeShiftIndiciesEq = "EnzymeTypeTreeShiftIndiciesEq" +EnzymeTypeTreeShiftIndiciesEqFn = "EnzymeTypeTreeShiftIndiciesEqFn" +shift_indicies_eq = "shift_indicies_eq" ERRNO_ACCES = "ERRNO_ACCES" ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS = "ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS" ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC = "ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC" From 4d12cb0fb8df408aa3df572f81411f799d82289c Mon Sep 17 00:00:00 2001 From: sgasho Date: Mon, 15 Dec 2025 21:29:52 +0900 Subject: [PATCH 0838/3801] refactor: initialize EnzymeWrapper in LlvmCodegenBackend::init --- compiler/rustc_codegen_llvm/src/back/lto.rs | 7 ++----- compiler/rustc_codegen_llvm/src/back/write.rs | 2 +- compiler/rustc_codegen_llvm/src/lib.rs | 9 ++++----- compiler/rustc_codegen_ssa/src/back/write.rs | 3 --- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index c9a5e167d9f6..314e64272ffe 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -529,11 +529,8 @@ fn thin_lto( } #[cfg(feature = "llvm_enzyme")] -pub(crate) fn enable_autodiff_settings( - sysroot: &rustc_session::config::Sysroot, - ad: &[config::AutoDiff], -) { - let mut enzyme = llvm::EnzymeWrapper::get_or_init(sysroot); +pub(crate) fn enable_autodiff_settings(ad: &[config::AutoDiff]) { + let mut enzyme = llvm::EnzymeWrapper::get_instance(); for val in ad { // We intentionally don't use a wildcard, to not forget handling anything new. diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index ecac6e6503cb..18da945f5a31 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -731,7 +731,7 @@ pub(crate) unsafe fn llvm_optimize( let llvm_plugins = config.llvm_plugins.join(","); let enzyme_fn = if consider_ad { - let wrapper = llvm::EnzymeWrapper::get_or_init(&cgcx.sysroot); + let wrapper = llvm::EnzymeWrapper::get_instance(); wrapper.registerEnzymeAndPassPipeline } else { std::ptr::null() diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index b0901d5f3e1e..c51b334d95e1 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -244,12 +244,11 @@ impl CodegenBackend for LlvmCodegenBackend { #[cfg(feature = "llvm_enzyme")] { use rustc_session::config::AutoDiff; - if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) { - { - use crate::back::lto::enable_autodiff_settings; - enable_autodiff_settings(&sess.opts.sysroot, &sess.opts.unstable_opts.autodiff); - } + use crate::back::lto::enable_autodiff_settings; + if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) { + drop(llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot)); + enable_autodiff_settings(&sess.opts.unstable_opts.autodiff); } } } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 3196b51e0c2b..3e36bd8552b1 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -29,7 +29,6 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{ self, CrateType, Lto, OutFileName, OutputFilenames, OutputType, Passes, SwitchWithOptPath, - Sysroot, }; use rustc_span::source_map::SourceMap; use rustc_span::{FileName, InnerSpan, Span, SpanData, sym}; @@ -347,7 +346,6 @@ pub struct CodegenContext { pub split_debuginfo: rustc_target::spec::SplitDebuginfo, pub split_dwarf_kind: rustc_session::config::SplitDwarfKind, pub pointer_size: Size, - pub sysroot: Sysroot, /// Emitter to use for diagnostics produced during codegen. pub diag_emitter: SharedEmitter, @@ -1319,7 +1317,6 @@ fn start_executing_work( parallel: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend, pointer_size: tcx.data_layout.pointer_size(), invocation_temp: sess.invocation_temp.clone(), - sysroot: sess.opts.sysroot.clone(), }; // This is the "main loop" of parallel work happening for parallel codegen. From 58aeab58ab8028a8b26ba02ffb8deb1d0c4a3e29 Mon Sep 17 00:00:00 2001 From: sgasho Date: Mon, 15 Dec 2025 21:41:40 +0900 Subject: [PATCH 0839/3801] add trailing line at compiler/rustc_codegen_llvm/Cargo.toml --- compiler/rustc_codegen_llvm/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 21f6484bd0c9..076ec5e59eb6 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -50,3 +50,4 @@ check_only = ["rustc_llvm/check_only"] llvm_enzyme = ["dep:libloading"] llvm_offload = [] # tidy-alphabetical-end + From c9448e49497d3f524f0e22ff9881542823f3b453 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 15 Dec 2025 17:51:53 +0200 Subject: [PATCH 0840/3801] Fix method resolution for incoherent impls when there are two sysroots in the crate graph Which can happen when two workspaces are opened, by only considering impls from dependencies of this crate. I have no idea how to construct a test for this, but I tested it manually and it works. --- .../rust-analyzer/crates/base-db/src/input.rs | 4 +- .../crates/hir-ty/src/method_resolution.rs | 40 ++++++++----------- .../hir-ty/src/method_resolution/probe.rs | 10 +++-- src/tools/rust-analyzer/crates/hir/src/lib.rs | 19 ++++++--- 4 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index 1b41386adf77..14649dde648f 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -465,7 +465,7 @@ impl Crate { /// including the crate itself. /// /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications. - pub fn transitive_deps(self, db: &dyn salsa::Database) -> Box<[Crate]> { + pub fn transitive_deps(self, db: &dyn salsa::Database) -> Vec { // There is a bit of duplication here and in `CrateGraphBuilder` in the same method, but it's not terrible // and removing that is a bit difficult. let mut worklist = vec![self]; @@ -480,7 +480,7 @@ impl Crate { worklist.extend(krate.data(db).dependencies.iter().map(|dep| dep.crate_id)); } - deps.into_boxed_slice() + deps } /// Returns all transitive reverse dependencies of the given crate, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index 868ae00329b3..d66a386bcdeb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -505,13 +505,19 @@ pub(crate) fn find_matching_impl<'db>( } #[salsa::tracked(returns(ref))] -fn crates_containing_incoherent_inherent_impls(db: &dyn HirDatabase) -> Box<[Crate]> { +fn crates_containing_incoherent_inherent_impls(db: &dyn HirDatabase, krate: Crate) -> Box<[Crate]> { + let _p = tracing::info_span!("crates_containing_incoherent_inherent_impls").entered(); // We assume that only sysroot crates contain `#[rustc_has_incoherent_inherent_impls]` // impls, since this is an internal feature and only std uses it. - db.all_crates().iter().copied().filter(|krate| krate.data(db).origin.is_lang()).collect() + krate.transitive_deps(db).into_iter().filter(|krate| krate.data(db).origin.is_lang()).collect() } -pub fn incoherent_inherent_impls(db: &dyn HirDatabase, self_ty: SimplifiedType) -> &[ImplId] { +pub fn with_incoherent_inherent_impls( + db: &dyn HirDatabase, + krate: Crate, + self_ty: &SimplifiedType, + mut callback: impl FnMut(&[ImplId]), +) { let has_incoherent_impls = match self_ty.def() { Some(def_id) => match def_id.try_into() { Ok(def_id) => AttrFlags::query(db, def_id) @@ -520,26 +526,14 @@ pub fn incoherent_inherent_impls(db: &dyn HirDatabase, self_ty: SimplifiedType) }, _ => true, }; - return if !has_incoherent_impls { - &[] - } else { - incoherent_inherent_impls_query(db, (), self_ty) - }; - - #[salsa::tracked(returns(ref))] - fn incoherent_inherent_impls_query( - db: &dyn HirDatabase, - _force_query_input_to_be_interned: (), - self_ty: SimplifiedType, - ) -> Box<[ImplId]> { - let _p = tracing::info_span!("incoherent_inherent_impl_crates").entered(); - - let mut result = Vec::new(); - for &krate in crates_containing_incoherent_inherent_impls(db) { - let impls = InherentImpls::for_crate(db, krate); - result.extend_from_slice(impls.for_self_ty(&self_ty)); - } - result.into_boxed_slice() + if !has_incoherent_impls { + return; + } + let _p = tracing::info_span!("incoherent_inherent_impls").entered(); + let crates = crates_containing_incoherent_inherent_impls(db, krate); + for &krate in crates { + let impls = InherentImpls::for_crate(db, krate); + callback(impls.for_self_ty(self_ty)); } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs index 6af47ab68bfc..9ea0d500a5f4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution/probe.rs @@ -27,7 +27,7 @@ use crate::{ lower::GenericPredicates, method_resolution::{ CandidateId, CandidateSource, InherentImpls, MethodError, MethodResolutionContext, - incoherent_inherent_impls, simplified_type_module, + simplified_type_module, with_incoherent_inherent_impls, }, next_solver::{ Binder, Canonical, ClauseKind, DbInterner, FnSig, GenericArg, GenericArgs, Goal, ParamEnv, @@ -965,9 +965,11 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { else { panic!("unexpected incoherent type: {:?}", self_ty) }; - for &impl_def_id in incoherent_inherent_impls(self.db(), simp) { - self.assemble_inherent_impl_probe(impl_def_id, receiver_steps); - } + with_incoherent_inherent_impls(self.db(), self.ctx.resolver.krate(), &simp, |impls| { + for &impl_def_id in impls { + self.assemble_inherent_impl_probe(impl_def_id, receiver_steps); + } + }); } fn assemble_inherent_impl_candidates_for_type( diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index a50a736ccd0e..ae7e4aa6c8ac 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -4331,10 +4331,7 @@ impl Impl { /// blanket impls, and only does a shallow type constructor check. In fact, this should've probably been on `Adt` /// etc., and not on `Type`. If you would want to create a precise list of all impls applying to a type, /// you would need to include blanket impls, and try to prove to predicates for each candidate. - pub fn all_for_type<'db>( - db: &'db dyn HirDatabase, - Type { ty, env: _ }: Type<'db>, - ) -> Vec { + pub fn all_for_type<'db>(db: &'db dyn HirDatabase, Type { ty, env }: Type<'db>) -> Vec { let mut result = Vec::new(); let interner = DbInterner::new_no_crate(db); let Some(simplified_ty) = @@ -4344,7 +4341,12 @@ impl Impl { }; let mut extend_with_impls = |impls: &[ImplId]| result.extend(impls.iter().copied().map(Impl::from)); - extend_with_impls(method_resolution::incoherent_inherent_impls(db, simplified_ty)); + method_resolution::with_incoherent_inherent_impls( + db, + env.krate, + &simplified_ty, + &mut extend_with_impls, + ); if let Some(module) = method_resolution::simplified_type_module(db, &simplified_ty) { InherentImpls::for_each_crate_and_block( db, @@ -5322,7 +5324,12 @@ impl<'db> Type<'db> { return; }; - handle_impls(method_resolution::incoherent_inherent_impls(db, simplified_type)); + method_resolution::with_incoherent_inherent_impls( + db, + self.env.krate, + &simplified_type, + &mut handle_impls, + ); if let Some(module) = method_resolution::simplified_type_module(db, &simplified_type) { InherentImpls::for_each_crate_and_block( From a4214a410b10ad7133998f75b8ff66a80ba0b844 Mon Sep 17 00:00:00 2001 From: dfireBird Date: Mon, 15 Dec 2025 22:33:06 +0530 Subject: [PATCH 0841/3801] fix: use `cmark_with_options` to write shortcuts links to the output --- src/tools/rust-analyzer/crates/ide/src/doc_links.rs | 8 +++----- src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs | 5 ++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index 0ed91cf7f588..d854c1c45044 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -8,7 +8,7 @@ mod intra_doc_links; use std::ops::Range; use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; -use pulldown_cmark_to_cmark::{Options as CMarkOptions, cmark_resume_with_options}; +use pulldown_cmark_to_cmark::{Options as CMarkOptions, cmark_with_options}; use stdx::format_to; use url::Url; @@ -89,10 +89,9 @@ pub(crate) fn rewrite_links( } }); let mut out = String::new(); - cmark_resume_with_options( + cmark_with_options( doc, &mut out, - None, CMarkOptions { code_block_token_count: 3, ..Default::default() }, ) .ok(); @@ -125,10 +124,9 @@ pub(crate) fn remove_links(markdown: &str) -> String { }); let mut out = String::new(); - cmark_resume_with_options( + cmark_with_options( doc, &mut out, - None, CMarkOptions { code_block_token_count: 3, ..Default::default() }, ) .ok(); diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs index 34ffc11c4b5f..8594a0a22475 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs @@ -724,7 +724,10 @@ pub struct $0Foo; /// [`foo`]: Foo pub struct $0Foo; "#, - expect![["[`foo`]"]], + expect![[r#" + [`foo`] + + [`foo`]: https://docs.rs/foo/*/foo/struct.Foo.html"#]], ); } From 1bd997a4520e5712ab17a4cbc12624a0620b3836 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Wed, 10 Dec 2025 10:52:37 +0900 Subject: [PATCH 0842/3801] Cleaned up some tests Split invalid-compile-flags into run-pass & invalid Update tests/ui/README.md --- tests/ui/README.md | 22 ++++++++++++------- tests/ui/borrowck/return-ref-to-temporary.rs | 3 ++- .../borrowck/return-ref-to-temporary.stderr | 2 +- .../closures/closure-upvar-trait-caching.rs | 5 +++-- tests/ui/closures/nested-closure-call.rs | 3 ++- ...protection-missing-pac-ret.BADFLAGS.stderr | 0 ...otection-missing-pac-ret.BADFLAGSPC.stderr | 0 ...rotection-missing-pac-ret.BADTARGET.stderr | 0 .../branch-protection-missing-pac-ret.rs | 0 .../invalid}/codegen-option-without-group.rs | 0 .../codegen-option-without-group.stderr | 0 .../crate-type-flag.empty_crate_type.stderr | 0 ...ate-type-flag.proc_underscore_macro.stderr | 0 .../invalid}/crate-type-flag.rs | 0 .../invalid}/crate-type-flag.unknown.stderr | 0 .../invalid}/debug-option-without-group.rs | 0 .../debug-option-without-group.stderr | 0 .../emit-output-types-without-args.rs | 0 .../emit-output-types-without-args.stderr | 0 .../requires-x86-or-x86_64.aarch64.stderr | 0 .../function-return/requires-x86-or-x86_64.rs | 0 ...requires-non-large-code-model.large.stderr | 0 ...nk-extern-requires-non-large-code-model.rs | 0 .../requires-x86-or-x86_64.aarch64.stderr | 0 .../requires-x86-or-x86_64.rs | 0 .../invalid}/invalid-llvm-passes.rs | 0 .../invalid}/invalid-llvm-passes.stderr | 0 .../invalid}/need-crate-arg-ignore-tidy$x.rs | 0 .../need-crate-arg-ignore-tidy$x.stderr | 0 ...crate-name-request-malformed-crate-name.rs | 0 ...e-name-request-malformed-crate-name.stderr | 0 ...le-names-request-malformed-crate-name-1.rs | 0 ...ames-request-malformed-crate-name-1.stderr | 0 ...le-names-request-malformed-crate-name-2.rs | 0 ...ames-request-malformed-crate-name-2.stderr | 0 ...file-names-request-malformed-crate-name.rs | 0 ...-names-request-malformed-crate-name.stderr | 0 .../invalid}/print-without-arg.rs | 0 .../invalid}/print-without-arg.stderr | 0 .../invalid}/print.rs | 0 .../invalid}/print.stderr | 0 .../requires-x86.aarch64.stderr | 0 .../reg-struct-return/requires-x86.rs | 0 .../requires-x86.x86_64.stderr | 0 .../regparm-valid-values.regparm4.stderr | 0 .../invalid}/regparm/regparm-valid-values.rs | 0 .../regparm/requires-x86.aarch64.stderr | 0 .../invalid}/regparm/requires-x86.rs | 0 .../regparm/requires-x86.x86_64.stderr | 0 .../run-pass}/repeated-debug-opt-flags.rs | 1 + tests/ui/enum/enum-variant-no-field.rs | 5 ++++- tests/ui/enum/enum-variant-no-field.stderr | 2 +- .../ui/enum/enum-with-uninhabited-variant.rs | 3 ++- tests/ui/expr/return-in-block-tuple.rs | 3 ++- tests/ui/extern/extern-rust-trait-method.rs | 1 + tests/ui/fmt/println-float.rs | 1 + tests/ui/indexing/ref-array-indexing.rs | 5 +++-- tests/ui/issues/issue-21449.rs | 6 ----- tests/ui/issues/issue-21449.stderr | 9 -------- tests/ui/issues/issue-23189.rs | 5 ----- tests/ui/issues/issue-23189.stderr | 9 -------- .../trait-method-lifetime-suggestion.rs | 5 +++-- .../trait-method-lifetime-suggestion.stderr | 2 +- tests/ui/lint/lint-missing-doc-crate-attr.rs | 4 ++++ ...err => lint-missing-doc-crate-attr.stderr} | 9 ++++---- .../lint/lint-missing-doc-crate-flags.stderr | 2 +- tests/ui/lint/lint-missing-docs-crate-attr.rs | 3 --- tests/ui/macros/undefined-macro-in-impl.rs | 1 + .../ui/macros/undefined-macro-in-impl.stderr | 2 +- .../match/match-const-tuple-type-mismatch.rs | 17 +++++++------- .../match-const-tuple-type-mismatch.stderr | 21 +++++++++--------- tests/ui/match/match-range-char-const.rs | 3 ++- tests/ui/match/match-static-pattern.rs | 5 +++-- tests/ui/match/match-static-pattern.stderr | 4 ++-- tests/ui/moves/array-copy-move.rs | 1 + tests/ui/never_type/never-deref.rs | 1 + tests/ui/never_type/never-deref.stderr | 2 +- .../parser/cast-angle-bracket-precedence.rs | 2 ++ .../cast-angle-bracket-precedence.stderr | 12 +++++----- .../pattern/match-at-pattern-shadows-name.rs | 4 +++- .../match-at-pattern-shadows-name.stderr | 4 ++-- .../module-used-as-struct-constructor.rs | 1 + .../module-used-as-struct-constructor.stderr | 2 +- .../shadowed/match-binding-shadows-const.rs | 1 + .../match-binding-shadows-const.stderr | 2 +- tests/ui/statics/static-mut-unsafe-init.rs | 7 +++--- .../ui/threads-sendsync/thread-join-unwrap.rs | 3 +-- .../ui/trait-bounds/sort-missing-ord-bound.rs | 5 ++++- .../sort-missing-ord-bound.stderr | 4 ++-- .../solver-cycles/assoc-equality-cycle.rs | 5 +++-- .../solver-cycles/assoc-equality-cycle.stderr | 8 +++---- .../traits/solver-cycles/self-item-cycle.rs | 7 +++--- .../solver-cycles/self-item-cycle.stderr | 12 +++++----- tests/ui/typeck/missing-type-annotation.rs | 1 + .../ui/typeck/missing-type-annotation.stderr | 2 +- tests/ui/typeck/osstring-str-equality.rs | 1 + .../return-expression-invalid-callee.rs | 9 ++++---- .../return-expression-invalid-callee.stderr | 6 ++--- 98 files changed, 139 insertions(+), 126 deletions(-) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/branch-protection-missing-pac-ret.BADFLAGS.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/branch-protection-missing-pac-ret.BADFLAGSPC.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/branch-protection-missing-pac-ret.BADTARGET.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/branch-protection-missing-pac-ret.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/codegen-option-without-group.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/codegen-option-without-group.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/crate-type-flag.empty_crate_type.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/crate-type-flag.proc_underscore_macro.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/crate-type-flag.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/crate-type-flag.unknown.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/debug-option-without-group.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/debug-option-without-group.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/emit-output-types-without-args.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/emit-output-types-without-args.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/function-return/requires-x86-or-x86_64.aarch64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/function-return/requires-x86-or-x86_64.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/function-return/thunk-extern-requires-non-large-code-model.large.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/function-return/thunk-extern-requires-non-large-code-model.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/invalid-llvm-passes.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/invalid-llvm-passes.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/need-crate-arg-ignore-tidy$x.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/need-crate-arg-ignore-tidy$x.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-crate-name-request-malformed-crate-name.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-crate-name-request-malformed-crate-name.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name-1.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name-1.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name-2.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name-2.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-without-arg.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-without-arg.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/reg-struct-return/requires-x86.aarch64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/reg-struct-return/requires-x86.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/reg-struct-return/requires-x86.x86_64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/regparm-valid-values.regparm4.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/regparm-valid-values.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/requires-x86.aarch64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/requires-x86.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/requires-x86.x86_64.stderr (100%) rename tests/ui/{codegen => compile-flags/run-pass}/repeated-debug-opt-flags.rs (72%) delete mode 100644 tests/ui/issues/issue-21449.rs delete mode 100644 tests/ui/issues/issue-21449.stderr delete mode 100644 tests/ui/issues/issue-23189.rs delete mode 100644 tests/ui/issues/issue-23189.stderr create mode 100644 tests/ui/lint/lint-missing-doc-crate-attr.rs rename tests/ui/lint/{lint-missing-docs-crate-attr.stderr => lint-missing-doc-crate-attr.stderr} (58%) delete mode 100644 tests/ui/lint/lint-missing-docs-crate-attr.rs diff --git a/tests/ui/README.md b/tests/ui/README.md index 25e870fd8f18..ca9f89f002ee 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -256,6 +256,10 @@ Some traits' implementation must be compared with their definition, checking for This subdirectory is *not* intended comparison traits (`PartialEq`, `Eq`, `PartialOrd`, `Ord`). +## `tests/ui/compile-flags/` + +Tests for compile flags. + ## `tests/ui/compiletest-self-test/`: compiletest "meta" tests Meta test suite of the test harness `compiletest` itself. @@ -548,6 +552,8 @@ A broad directory for tests on expressions. Tests on the `extern` keyword and `extern` blocks and functions. +**FIXME**: Merge with `tests/ui/abi/extern`. + ## `tests/ui/extern-flag/`: `--extern` command line flag Tests for the `--extern` CLI flag. @@ -556,6 +562,12 @@ Tests for the `--extern` CLI flag. Tests on feature-gating, and the `#![feature(..)]` mechanism itself. +## `tests/ui/ffi/`: Foreign Function Interface + +Tests for the `std::ffi` module. + +See [`std::ffi`](https://doc.rust-lang.org/std/ffi/index.html) + ## `tests/ui/ffi-attrs/`: `#![feature(ffi_const, ffi_pure)]` The `#[ffi_const]` and `#[ffi_pure]` attributes applies clang's `const` and `pure` attributes to foreign functions declarations, respectively. These attributes are the core element of the tests in this category. @@ -733,15 +745,9 @@ Various tests related to rejecting invalid inputs. **FIXME**: This is rather uninformative, possibly rehome into more meaningful directories. -## `tests/ui/invalid-compile-flags/` +## `tests/ui/io-checks/`: Input Output -Tests for checking that invalid usage of compiler flags are rejected. - -## `tests/ui/io-checks/` - -Contains a single test. The test tries to output a file into an invalid directory with `-o`, then checks that the result is an error, not an internal compiler error. - -**FIXME**: Rehome to invalid compiler flags maybe. +Tests for I/O related behaviour, covering stdout/stderr handling and error propagation. ## `tests/ui/issues/`: Tests directly related to GitHub issues diff --git a/tests/ui/borrowck/return-ref-to-temporary.rs b/tests/ui/borrowck/return-ref-to-temporary.rs index b9e20e8dbcb5..90609b8d6da6 100644 --- a/tests/ui/borrowck/return-ref-to-temporary.rs +++ b/tests/ui/borrowck/return-ref-to-temporary.rs @@ -1,6 +1,7 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/46472 fn bar<'a>() -> &'a mut u32 { &mut 4 //~^ ERROR cannot return reference to temporary value [E0515] } -fn main() { } +fn main() {} diff --git a/tests/ui/borrowck/return-ref-to-temporary.stderr b/tests/ui/borrowck/return-ref-to-temporary.stderr index 6115da28cc91..85faf0a9e375 100644 --- a/tests/ui/borrowck/return-ref-to-temporary.stderr +++ b/tests/ui/borrowck/return-ref-to-temporary.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return reference to temporary value - --> $DIR/issue-46472.rs:2:5 + --> $DIR/return-ref-to-temporary.rs:3:5 | LL | &mut 4 | ^^^^^- diff --git a/tests/ui/closures/closure-upvar-trait-caching.rs b/tests/ui/closures/closure-upvar-trait-caching.rs index d2a6862e05c4..82588631c99c 100644 --- a/tests/ui/closures/closure-upvar-trait-caching.rs +++ b/tests/ui/closures/closure-upvar-trait-caching.rs @@ -7,8 +7,9 @@ // reasonable examples) let to ambiguity errors about not being able // to infer sufficient type information. - fn main() { let n = 0; - let it = Some(1_usize).into_iter().inspect(|_| {n;}); + let it = Some(1_usize).into_iter().inspect(|_| { + n; + }); } diff --git a/tests/ui/closures/nested-closure-call.rs b/tests/ui/closures/nested-closure-call.rs index f371828606c4..9d0860167a1a 100644 --- a/tests/ui/closures/nested-closure-call.rs +++ b/tests/ui/closures/nested-closure-call.rs @@ -1,4 +1,5 @@ +//! regression test for https://github.com/rust-lang/rust/issues/24779 //@ run-pass fn main() { - assert_eq!((||||42)()(), 42); + assert_eq!((|| || 42)()(), 42); } diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGS.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGS.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGSPC.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGSPC.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADTARGET.stderr b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADTARGET.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADTARGET.stderr rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADTARGET.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.rs similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.rs diff --git a/tests/ui/invalid-compile-flags/codegen-option-without-group.rs b/tests/ui/compile-flags/invalid/codegen-option-without-group.rs similarity index 100% rename from tests/ui/invalid-compile-flags/codegen-option-without-group.rs rename to tests/ui/compile-flags/invalid/codegen-option-without-group.rs diff --git a/tests/ui/invalid-compile-flags/codegen-option-without-group.stderr b/tests/ui/compile-flags/invalid/codegen-option-without-group.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/codegen-option-without-group.stderr rename to tests/ui/compile-flags/invalid/codegen-option-without-group.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr b/tests/ui/compile-flags/invalid/crate-type-flag.empty_crate_type.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr rename to tests/ui/compile-flags/invalid/crate-type-flag.empty_crate_type.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr b/tests/ui/compile-flags/invalid/crate-type-flag.proc_underscore_macro.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr rename to tests/ui/compile-flags/invalid/crate-type-flag.proc_underscore_macro.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.rs b/tests/ui/compile-flags/invalid/crate-type-flag.rs similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.rs rename to tests/ui/compile-flags/invalid/crate-type-flag.rs diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr b/tests/ui/compile-flags/invalid/crate-type-flag.unknown.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr rename to tests/ui/compile-flags/invalid/crate-type-flag.unknown.stderr diff --git a/tests/ui/invalid-compile-flags/debug-option-without-group.rs b/tests/ui/compile-flags/invalid/debug-option-without-group.rs similarity index 100% rename from tests/ui/invalid-compile-flags/debug-option-without-group.rs rename to tests/ui/compile-flags/invalid/debug-option-without-group.rs diff --git a/tests/ui/invalid-compile-flags/debug-option-without-group.stderr b/tests/ui/compile-flags/invalid/debug-option-without-group.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/debug-option-without-group.stderr rename to tests/ui/compile-flags/invalid/debug-option-without-group.stderr diff --git a/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs b/tests/ui/compile-flags/invalid/emit-output-types-without-args.rs similarity index 100% rename from tests/ui/invalid-compile-flags/emit-output-types-without-args.rs rename to tests/ui/compile-flags/invalid/emit-output-types-without-args.rs diff --git a/tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr b/tests/ui/compile-flags/invalid/emit-output-types-without-args.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr rename to tests/ui/compile-flags/invalid/emit-output-types-without-args.stderr diff --git a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.aarch64.stderr b/tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.aarch64.stderr rename to tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs b/tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.rs similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs rename to tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.rs diff --git a/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.large.stderr b/tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.large.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.large.stderr rename to tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.large.stderr diff --git a/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs b/tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.rs similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs rename to tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.rs diff --git a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr b/tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr rename to tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs b/tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs similarity index 100% rename from tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs rename to tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs diff --git a/tests/ui/invalid-compile-flags/invalid-llvm-passes.rs b/tests/ui/compile-flags/invalid/invalid-llvm-passes.rs similarity index 100% rename from tests/ui/invalid-compile-flags/invalid-llvm-passes.rs rename to tests/ui/compile-flags/invalid/invalid-llvm-passes.rs diff --git a/tests/ui/invalid-compile-flags/invalid-llvm-passes.stderr b/tests/ui/compile-flags/invalid/invalid-llvm-passes.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/invalid-llvm-passes.stderr rename to tests/ui/compile-flags/invalid/invalid-llvm-passes.stderr diff --git a/tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.rs b/tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.rs similarity index 100% rename from tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.rs rename to tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.rs diff --git a/tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.stderr b/tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.stderr rename to tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.stderr diff --git a/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.rs b/tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.rs rename to tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.rs diff --git a/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr b/tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr rename to tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.stderr diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.rs b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.rs rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.rs diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.stderr diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.rs b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.rs rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.rs diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.stderr diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.rs b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.rs rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.rs diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.stderr diff --git a/tests/ui/invalid-compile-flags/print-without-arg.rs b/tests/ui/compile-flags/invalid/print-without-arg.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-without-arg.rs rename to tests/ui/compile-flags/invalid/print-without-arg.rs diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/compile-flags/invalid/print-without-arg.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-without-arg.stderr rename to tests/ui/compile-flags/invalid/print-without-arg.stderr diff --git a/tests/ui/invalid-compile-flags/print.rs b/tests/ui/compile-flags/invalid/print.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print.rs rename to tests/ui/compile-flags/invalid/print.rs diff --git a/tests/ui/invalid-compile-flags/print.stderr b/tests/ui/compile-flags/invalid/print.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print.stderr rename to tests/ui/compile-flags/invalid/print.stderr diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.aarch64.stderr b/tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.aarch64.stderr rename to tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs b/tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.rs similarity index 100% rename from tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs rename to tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.rs diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.x86_64.stderr b/tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.x86_64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.x86_64.stderr rename to tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.x86_64.stderr diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr b/tests/ui/compile-flags/invalid/regparm/regparm-valid-values.regparm4.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr rename to tests/ui/compile-flags/invalid/regparm/regparm-valid-values.regparm4.stderr diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs b/tests/ui/compile-flags/invalid/regparm/regparm-valid-values.rs similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs rename to tests/ui/compile-flags/invalid/regparm/regparm-valid-values.rs diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr b/tests/ui/compile-flags/invalid/regparm/requires-x86.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr rename to tests/ui/compile-flags/invalid/regparm/requires-x86.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.rs b/tests/ui/compile-flags/invalid/regparm/requires-x86.rs similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/requires-x86.rs rename to tests/ui/compile-flags/invalid/regparm/requires-x86.rs diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr b/tests/ui/compile-flags/invalid/regparm/requires-x86.x86_64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr rename to tests/ui/compile-flags/invalid/regparm/requires-x86.x86_64.stderr diff --git a/tests/ui/codegen/repeated-debug-opt-flags.rs b/tests/ui/compile-flags/run-pass/repeated-debug-opt-flags.rs similarity index 72% rename from tests/ui/codegen/repeated-debug-opt-flags.rs rename to tests/ui/compile-flags/run-pass/repeated-debug-opt-flags.rs index 5d8044b0a1a0..d584ec9fd280 100644 --- a/tests/ui/codegen/repeated-debug-opt-flags.rs +++ b/tests/ui/compile-flags/run-pass/repeated-debug-opt-flags.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/24945 //@ run-pass // This test is just checking that we continue to accept `-g -g -O -O` // as options to the compiler. diff --git a/tests/ui/enum/enum-variant-no-field.rs b/tests/ui/enum/enum-variant-no-field.rs index b285cb81ee23..a69766b7c48d 100644 --- a/tests/ui/enum/enum-variant-no-field.rs +++ b/tests/ui/enum/enum-variant-no-field.rs @@ -1,4 +1,7 @@ -enum Foo { Bar } +//! regression test for https://github.com/rust-lang/rust/issues/23253 +enum Foo { + Bar, +} fn main() { Foo::Bar.a; diff --git a/tests/ui/enum/enum-variant-no-field.stderr b/tests/ui/enum/enum-variant-no-field.stderr index ec7696909e72..4d02bf876189 100644 --- a/tests/ui/enum/enum-variant-no-field.stderr +++ b/tests/ui/enum/enum-variant-no-field.stderr @@ -1,5 +1,5 @@ error[E0609]: no field `a` on type `Foo` - --> $DIR/issue-23253.rs:4:14 + --> $DIR/enum-variant-no-field.rs:7:14 | LL | Foo::Bar.a; | ^ unknown field diff --git a/tests/ui/enum/enum-with-uninhabited-variant.rs b/tests/ui/enum/enum-with-uninhabited-variant.rs index 70c764f33ddf..8dfa492e6ea5 100644 --- a/tests/ui/enum/enum-with-uninhabited-variant.rs +++ b/tests/ui/enum/enum-with-uninhabited-variant.rs @@ -1,3 +1,4 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/50442 //@ run-pass #![allow(dead_code)] enum Void {} @@ -5,7 +6,7 @@ enum Void {} enum Foo { A(i32), B(Void), - C(i32) + C(i32), } fn main() { diff --git a/tests/ui/expr/return-in-block-tuple.rs b/tests/ui/expr/return-in-block-tuple.rs index 6d563a5bae1c..2b3a59f21412 100644 --- a/tests/ui/expr/return-in-block-tuple.rs +++ b/tests/ui/expr/return-in-block-tuple.rs @@ -1,6 +1,7 @@ +//! regression test for https://github.com/rust-lang/rust/issues/18110 //@ run-pass #![allow(unreachable_code)] fn main() { - ({return},); + ({ return },); } diff --git a/tests/ui/extern/extern-rust-trait-method.rs b/tests/ui/extern/extern-rust-trait-method.rs index 473e43650c2c..d71e5a8b6d53 100644 --- a/tests/ui/extern/extern-rust-trait-method.rs +++ b/tests/ui/extern/extern-rust-trait-method.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/19398 //@ check-pass trait T { diff --git a/tests/ui/fmt/println-float.rs b/tests/ui/fmt/println-float.rs index 18c8c756f32e..3adb0b434349 100644 --- a/tests/ui/fmt/println-float.rs +++ b/tests/ui/fmt/println-float.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/11382 //@ run-pass fn main() { println!("{}", 1.2); diff --git a/tests/ui/indexing/ref-array-indexing.rs b/tests/ui/indexing/ref-array-indexing.rs index 9f54d4258bf1..302255798df2 100644 --- a/tests/ui/indexing/ref-array-indexing.rs +++ b/tests/ui/indexing/ref-array-indexing.rs @@ -1,5 +1,6 @@ +//! regression test for https://github.com/rust-lang/rust/issues/43205 //@ run-pass fn main() { - let _ = &&[()][0]; - println!("{:?}", &[(),()][1]); + let _ = &&[()][0]; + println!("{:?}", &[(), ()][1]); } diff --git a/tests/ui/issues/issue-21449.rs b/tests/ui/issues/issue-21449.rs deleted file mode 100644 index 00ce2b7fffa8..000000000000 --- a/tests/ui/issues/issue-21449.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod MyMod {} - -fn main() { - let myVar = MyMod { T: 0 }; - //~^ ERROR expected struct, variant or union type, found module `MyMod` -} diff --git a/tests/ui/issues/issue-21449.stderr b/tests/ui/issues/issue-21449.stderr deleted file mode 100644 index cd1059d48993..000000000000 --- a/tests/ui/issues/issue-21449.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0574]: expected struct, variant or union type, found module `MyMod` - --> $DIR/issue-21449.rs:4:17 - | -LL | let myVar = MyMod { T: 0 }; - | ^^^^^ not a struct, variant or union type - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/issues/issue-23189.rs b/tests/ui/issues/issue-23189.rs deleted file mode 100644 index e5526357cb0e..000000000000 --- a/tests/ui/issues/issue-23189.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod module {} - -fn main() { - let _ = module { x: 0 }; //~ERROR expected struct -} diff --git a/tests/ui/issues/issue-23189.stderr b/tests/ui/issues/issue-23189.stderr deleted file mode 100644 index 37d778dc992e..000000000000 --- a/tests/ui/issues/issue-23189.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0574]: expected struct, variant or union type, found module `module` - --> $DIR/issue-23189.rs:4:13 - | -LL | let _ = module { x: 0 }; - | ^^^^^^ not a struct, variant or union type - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs b/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs index e2ee84694e39..39cf4ae64185 100644 --- a/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs +++ b/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs @@ -1,5 +1,6 @@ -// Test that regionck suggestions in a provided method of a trait -// don't ICE +//! regression test for https://github.com/rust-lang/rust/issues/17758 +//! Test that regionck suggestions in a provided method of a trait +//! don't ICE trait Foo<'a> { fn foo(&'a self); diff --git a/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr b/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr index 7a7d2374ef87..64347577d070 100644 --- a/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr +++ b/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-17758.rs:7:9 + --> $DIR/trait-method-lifetime-suggestion.rs:8:9 | LL | trait Foo<'a> { | -- lifetime `'a` defined here diff --git a/tests/ui/lint/lint-missing-doc-crate-attr.rs b/tests/ui/lint/lint-missing-doc-crate-attr.rs new file mode 100644 index 000000000000..51959785c53b --- /dev/null +++ b/tests/ui/lint/lint-missing-doc-crate-attr.rs @@ -0,0 +1,4 @@ +// regression test for https://github.com/rust-lang/rust/issues/10656 +#![deny(missing_docs)] +//~^ ERROR missing documentation for the crate +#![crate_type = "lib"] diff --git a/tests/ui/lint/lint-missing-docs-crate-attr.stderr b/tests/ui/lint/lint-missing-doc-crate-attr.stderr similarity index 58% rename from tests/ui/lint/lint-missing-docs-crate-attr.stderr rename to tests/ui/lint/lint-missing-doc-crate-attr.stderr index 61828f9c02a6..caff87df664b 100644 --- a/tests/ui/lint/lint-missing-docs-crate-attr.stderr +++ b/tests/ui/lint/lint-missing-doc-crate-attr.stderr @@ -1,12 +1,13 @@ error: missing documentation for the crate - --> $DIR/issue-10656.rs:1:1 + --> $DIR/lint-missing-doc-crate-attr.rs:2:1 | LL | / #![deny(missing_docs)] -LL | | #![crate_type="lib"] - | |____________________^ +LL | | +LL | | #![crate_type = "lib"] + | |______________________^ | note: the lint level is defined here - --> $DIR/issue-10656.rs:1:9 + --> $DIR/lint-missing-doc-crate-attr.rs:2:9 | LL | #![deny(missing_docs)] | ^^^^^^^^^^^^ diff --git a/tests/ui/lint/lint-missing-doc-crate-flags.stderr b/tests/ui/lint/lint-missing-doc-crate-flags.stderr index 8efd3a17263f..040d60a56ebf 100644 --- a/tests/ui/lint/lint-missing-doc-crate-flags.stderr +++ b/tests/ui/lint/lint-missing-doc-crate-flags.stderr @@ -1,5 +1,5 @@ error: missing documentation for the crate - --> $DIR/lint-missing-doc-crate.rs:4:47 + --> $DIR/lint-missing-doc-crate-flags.rs:4:47 | LL | | ^ diff --git a/tests/ui/lint/lint-missing-docs-crate-attr.rs b/tests/ui/lint/lint-missing-docs-crate-attr.rs deleted file mode 100644 index 250c4bc442f9..000000000000 --- a/tests/ui/lint/lint-missing-docs-crate-attr.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![deny(missing_docs)] -#![crate_type="lib"] -//~^^ ERROR missing documentation for the crate diff --git a/tests/ui/macros/undefined-macro-in-impl.rs b/tests/ui/macros/undefined-macro-in-impl.rs index fe4a327aef49..64b394f984be 100644 --- a/tests/ui/macros/undefined-macro-in-impl.rs +++ b/tests/ui/macros/undefined-macro-in-impl.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/19734 fn main() {} struct Type; diff --git a/tests/ui/macros/undefined-macro-in-impl.stderr b/tests/ui/macros/undefined-macro-in-impl.stderr index ed48714fe507..8d1bd958d7f6 100644 --- a/tests/ui/macros/undefined-macro-in-impl.stderr +++ b/tests/ui/macros/undefined-macro-in-impl.stderr @@ -1,5 +1,5 @@ error: cannot find macro `undef` in this scope - --> $DIR/issue-19734.rs:6:5 + --> $DIR/undefined-macro-in-impl.rs:7:5 | LL | undef!(); | ^^^^^ diff --git a/tests/ui/match/match-const-tuple-type-mismatch.rs b/tests/ui/match/match-const-tuple-type-mismatch.rs index 08539d6debd8..c9358e3d5faa 100644 --- a/tests/ui/match/match-const-tuple-type-mismatch.rs +++ b/tests/ui/match/match-const-tuple-type-mismatch.rs @@ -1,12 +1,13 @@ -// Regression test for issue #4968 - +//! Regression test for issue https://github.com/rust-lang/rust/issues/4968 //@ dont-require-annotations: NOTE -const A: (isize,isize) = (4,2); +const A: (isize, isize) = (4, 2); fn main() { - match 42 { A => () } - //~^ ERROR mismatched types - //~| NOTE expected type `{integer}` - //~| NOTE found tuple `(isize, isize)` - //~| NOTE expected integer, found `(isize, isize)` + match 42 { + A => (), + //~^ ERROR mismatched types + //~| NOTE expected type `{integer}` + //~| NOTE found tuple `(isize, isize)` + //~| NOTE expected integer, found `(isize, isize)` + } } diff --git a/tests/ui/match/match-const-tuple-type-mismatch.stderr b/tests/ui/match/match-const-tuple-type-mismatch.stderr index 2c1e1d7bfe5a..e7dd97c4e9a6 100644 --- a/tests/ui/match/match-const-tuple-type-mismatch.stderr +++ b/tests/ui/match/match-const-tuple-type-mismatch.stderr @@ -1,16 +1,17 @@ error[E0308]: mismatched types - --> $DIR/issue-4968.rs:7:16 + --> $DIR/match-const-tuple-type-mismatch.rs:7:9 | -LL | const A: (isize,isize) = (4,2); - | ---------------------- constant defined here +LL | const A: (isize, isize) = (4, 2); + | ----------------------- constant defined here LL | fn main() { -LL | match 42 { A => () } - | -- ^ - | | | - | | expected integer, found `(isize, isize)` - | | `A` is interpreted as a constant, not a new binding - | | help: introduce a new binding instead: `other_a` - | this expression has type `{integer}` +LL | match 42 { + | -- this expression has type `{integer}` +LL | A => (), + | ^ + | | + | expected integer, found `(isize, isize)` + | `A` is interpreted as a constant, not a new binding + | help: introduce a new binding instead: `other_a` | = note: expected type `{integer}` found tuple `(isize, isize)` diff --git a/tests/ui/match/match-range-char-const.rs b/tests/ui/match/match-range-char-const.rs index 995064719839..84881fd56cc0 100644 --- a/tests/ui/match/match-range-char-const.rs +++ b/tests/ui/match/match-range-char-const.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18464 //@ run-pass #![deny(dead_code)] @@ -7,6 +8,6 @@ const HIGH_RANGE: char = '9'; fn main() { match '5' { LOW_RANGE..=HIGH_RANGE => (), - _ => () + _ => (), }; } diff --git a/tests/ui/match/match-static-pattern.rs b/tests/ui/match/match-static-pattern.rs index 6da4e6e15284..5d367f9ec17c 100644 --- a/tests/ui/match/match-static-pattern.rs +++ b/tests/ui/match/match-static-pattern.rs @@ -1,9 +1,10 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/17933 pub static X: usize = 1; fn main() { match 1 { - self::X => { }, + self::X => {} //~^ ERROR expected unit struct, unit variant or constant, found static `self::X` - _ => { }, + _ => {} } } diff --git a/tests/ui/match/match-static-pattern.stderr b/tests/ui/match/match-static-pattern.stderr index 42a7e0442073..1b111fbcc2de 100644 --- a/tests/ui/match/match-static-pattern.stderr +++ b/tests/ui/match/match-static-pattern.stderr @@ -1,7 +1,7 @@ error[E0532]: expected unit struct, unit variant or constant, found static `self::X` - --> $DIR/issue-17933.rs:5:9 + --> $DIR/match-static-pattern.rs:6:9 | -LL | self::X => { }, +LL | self::X => {} | ^^^^^^^ not a unit struct, unit variant or constant error: aborting due to 1 previous error diff --git a/tests/ui/moves/array-copy-move.rs b/tests/ui/moves/array-copy-move.rs index 2ecc42b579d5..ea95bc06a369 100644 --- a/tests/ui/moves/array-copy-move.rs +++ b/tests/ui/moves/array-copy-move.rs @@ -1,3 +1,4 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/16783 //@ run-pass #![allow(unused_variables)] diff --git a/tests/ui/never_type/never-deref.rs b/tests/ui/never_type/never-deref.rs index dc3be48a7ead..6e4b89db04a5 100644 --- a/tests/ui/never_type/never-deref.rs +++ b/tests/ui/never_type/never-deref.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17373 fn main() { *return //~ ERROR type `!` cannot be dereferenced ; diff --git a/tests/ui/never_type/never-deref.stderr b/tests/ui/never_type/never-deref.stderr index 0e16d08c87d3..76f31f377987 100644 --- a/tests/ui/never_type/never-deref.stderr +++ b/tests/ui/never_type/never-deref.stderr @@ -1,5 +1,5 @@ error[E0614]: type `!` cannot be dereferenced - --> $DIR/issue-17373.rs:2:5 + --> $DIR/never-deref.rs:3:5 | LL | *return | ^^^^^^^ can't be dereferenced diff --git a/tests/ui/parser/cast-angle-bracket-precedence.rs b/tests/ui/parser/cast-angle-bracket-precedence.rs index e3ada65049d5..65b598d03bde 100644 --- a/tests/ui/parser/cast-angle-bracket-precedence.rs +++ b/tests/ui/parser/cast-angle-bracket-precedence.rs @@ -1,3 +1,5 @@ +//! regression test for https://github.com/rust-lang/rust/issues/22644 + fn main() { let a: usize = 0; let long_name: usize = 0; diff --git a/tests/ui/parser/cast-angle-bracket-precedence.stderr b/tests/ui/parser/cast-angle-bracket-precedence.stderr index c6d41cc856dd..975bfea9425a 100644 --- a/tests/ui/parser/cast-angle-bracket-precedence.stderr +++ b/tests/ui/parser/cast-angle-bracket-precedence.stderr @@ -1,5 +1,5 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:6:31 + --> $DIR/cast-angle-bracket-precedence.rs:8:31 | LL | println!("{}", a as usize < long_name); | ^ --------- interpreted as generic arguments @@ -12,7 +12,7 @@ LL | println!("{}", (a as usize) < long_name); | + + error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:7:33 + --> $DIR/cast-angle-bracket-precedence.rs:9:33 | LL | println!("{}{}", a as usize < long_name, long_name); | ^ -------------------- interpreted as generic arguments @@ -25,7 +25,7 @@ LL | println!("{}{}", (a as usize) < long_name, long_name); | + + error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:9:31 + --> $DIR/cast-angle-bracket-precedence.rs:11:31 | LL | println!("{}", a as usize < 4); | ^ - interpreted as generic arguments @@ -38,7 +38,7 @@ LL | println!("{}", (a as usize) < 4); | + + error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:14:20 + --> $DIR/cast-angle-bracket-precedence.rs:16:20 | LL | < | ^ not interpreted as comparison @@ -53,7 +53,7 @@ LL ~ usize) | error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:23:20 + --> $DIR/cast-angle-bracket-precedence.rs:25:20 | LL | < | ^ not interpreted as comparison @@ -70,7 +70,7 @@ LL ~ usize) | error: `<<` is interpreted as a start of generic arguments for `usize`, not a shift - --> $DIR/issue-22644.rs:26:31 + --> $DIR/cast-angle-bracket-precedence.rs:28:31 | LL | println!("{}", a as usize << long_name); | ^^ --------- interpreted as generic arguments diff --git a/tests/ui/pattern/match-at-pattern-shadows-name.rs b/tests/ui/pattern/match-at-pattern-shadows-name.rs index a23819a20f9a..3cd2040c9faf 100644 --- a/tests/ui/pattern/match-at-pattern-shadows-name.rs +++ b/tests/ui/pattern/match-at-pattern-shadows-name.rs @@ -1,10 +1,12 @@ +//! regression test for https://github.com/rust-lang/rust/issues/27033 fn main() { match Some(1) { None @ _ => {} //~ ERROR match bindings cannot shadow unit variants }; const C: u8 = 1; match 1 { - C @ 2 => { //~ ERROR match bindings cannot shadow constant + C @ 2 => { + //~^ ERROR match bindings cannot shadow constant println!("{}", C); } _ => {} diff --git a/tests/ui/pattern/match-at-pattern-shadows-name.stderr b/tests/ui/pattern/match-at-pattern-shadows-name.stderr index 129870f8c409..6e2fbf546e82 100644 --- a/tests/ui/pattern/match-at-pattern-shadows-name.stderr +++ b/tests/ui/pattern/match-at-pattern-shadows-name.stderr @@ -1,5 +1,5 @@ error[E0530]: match bindings cannot shadow unit variants - --> $DIR/issue-27033.rs:3:9 + --> $DIR/match-at-pattern-shadows-name.rs:4:9 | LL | None @ _ => {} | ^^^^ cannot be named the same as a unit variant @@ -9,7 +9,7 @@ LL | None @ _ => {} = note: the unit variant `None` is defined here error[E0530]: match bindings cannot shadow constants - --> $DIR/issue-27033.rs:7:9 + --> $DIR/match-at-pattern-shadows-name.rs:8:9 | LL | const C: u8 = 1; | ---------------- the constant `C` is defined here diff --git a/tests/ui/resolve/module-used-as-struct-constructor.rs b/tests/ui/resolve/module-used-as-struct-constructor.rs index 68cb2865fdc8..bdc7b2bf5841 100644 --- a/tests/ui/resolve/module-used-as-struct-constructor.rs +++ b/tests/ui/resolve/module-used-as-struct-constructor.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17001, https://github.com/rust-lang/rust/issues/21449, https://github.com/rust-lang/rust/issues/23189 mod foo {} fn main() { diff --git a/tests/ui/resolve/module-used-as-struct-constructor.stderr b/tests/ui/resolve/module-used-as-struct-constructor.stderr index 6ea32e0a45c3..b94a28762a7f 100644 --- a/tests/ui/resolve/module-used-as-struct-constructor.stderr +++ b/tests/ui/resolve/module-used-as-struct-constructor.stderr @@ -1,5 +1,5 @@ error[E0574]: expected struct, variant or union type, found module `foo` - --> $DIR/issue-17001.rs:4:13 + --> $DIR/module-used-as-struct-constructor.rs:5:13 | LL | let p = foo { x: () }; | ^^^ not a struct, variant or union type diff --git a/tests/ui/shadowed/match-binding-shadows-const.rs b/tests/ui/shadowed/match-binding-shadows-const.rs index 55196177f693..95f2e087b5e7 100644 --- a/tests/ui/shadowed/match-binding-shadows-const.rs +++ b/tests/ui/shadowed/match-binding-shadows-const.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/34047 const C: u8 = 0; fn main() { diff --git a/tests/ui/shadowed/match-binding-shadows-const.stderr b/tests/ui/shadowed/match-binding-shadows-const.stderr index 97b1230ce350..345c67700e62 100644 --- a/tests/ui/shadowed/match-binding-shadows-const.stderr +++ b/tests/ui/shadowed/match-binding-shadows-const.stderr @@ -1,5 +1,5 @@ error[E0530]: match bindings cannot shadow constants - --> $DIR/issue-34047.rs:5:13 + --> $DIR/match-binding-shadows-const.rs:6:13 | LL | const C: u8 = 0; | ---------------- the constant `C` is defined here diff --git a/tests/ui/statics/static-mut-unsafe-init.rs b/tests/ui/statics/static-mut-unsafe-init.rs index d8b20169ee0c..ee8472100a08 100644 --- a/tests/ui/statics/static-mut-unsafe-init.rs +++ b/tests/ui/statics/static-mut-unsafe-init.rs @@ -1,7 +1,8 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17450 //@ build-pass -#![allow(dead_code, warnings)] +#![allow(dead_code)] -static mut x: isize = 3; -static mut y: isize = unsafe { x }; +static mut X: isize = 3; +static mut Y: isize = unsafe { X }; fn main() {} diff --git a/tests/ui/threads-sendsync/thread-join-unwrap.rs b/tests/ui/threads-sendsync/thread-join-unwrap.rs index 06f50ac6996d..6288e15b1874 100644 --- a/tests/ui/threads-sendsync/thread-join-unwrap.rs +++ b/tests/ui/threads-sendsync/thread-join-unwrap.rs @@ -1,8 +1,7 @@ +//! Regression test for unwrapping the result of `join`, issue https://github.com/rust-lang/rust/issues/21291 //@ run-pass //@ needs-threads -// Regression test for unwrapping the result of `join`, issue #21291 - use std::thread; fn main() { diff --git a/tests/ui/trait-bounds/sort-missing-ord-bound.rs b/tests/ui/trait-bounds/sort-missing-ord-bound.rs index b491bc37f515..8d4ea8815017 100644 --- a/tests/ui/trait-bounds/sort-missing-ord-bound.rs +++ b/tests/ui/trait-bounds/sort-missing-ord-bound.rs @@ -1,4 +1,7 @@ -struct X { x: i32 } +//! regression test for issue https://github.com/rust-lang/rust/issues/20162 +struct X { + x: i32, +} fn main() { let mut b: Vec = vec![]; diff --git a/tests/ui/trait-bounds/sort-missing-ord-bound.stderr b/tests/ui/trait-bounds/sort-missing-ord-bound.stderr index 8f45f0d36c71..c11781e5fff3 100644 --- a/tests/ui/trait-bounds/sort-missing-ord-bound.stderr +++ b/tests/ui/trait-bounds/sort-missing-ord-bound.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `X: Ord` is not satisfied - --> $DIR/issue-20162.rs:5:7 + --> $DIR/sort-missing-ord-bound.rs:8:7 | LL | b.sort(); | ^^^^ the trait `Ord` is not implemented for `X` @@ -9,7 +9,7 @@ note: required by a bound in `slice::::sort` help: consider annotating `X` with `#[derive(Ord)]` | LL + #[derive(Ord)] -LL | struct X { x: i32 } +LL | struct X { | error: aborting due to 1 previous error diff --git a/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs b/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs index 258e362d1317..f82bffc598b8 100644 --- a/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs +++ b/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs @@ -1,9 +1,10 @@ +//! regression test for https://github.com/rust-lang/rust/issues/21177 trait Trait { type A; type B; } -fn foo>() { } +fn foo>() {} //~^ ERROR cycle detected -fn main() { } +fn main() {} diff --git a/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr b/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr index 9f66f43a195a..a8c0228601a2 100644 --- a/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr +++ b/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr @@ -1,14 +1,14 @@ error[E0391]: cycle detected when computing the bounds for type parameter `T` - --> $DIR/issue-21177.rs:6:21 + --> $DIR/assoc-equality-cycle.rs:7:21 | -LL | fn foo>() { } +LL | fn foo>() {} | ^^^^ | = note: ...which immediately requires computing the bounds for type parameter `T` again note: cycle used when computing explicit predicates of `foo` - --> $DIR/issue-21177.rs:6:21 + --> $DIR/assoc-equality-cycle.rs:7:21 | -LL | fn foo>() { } +LL | fn foo>() {} | ^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information diff --git a/tests/ui/traits/solver-cycles/self-item-cycle.rs b/tests/ui/traits/solver-cycles/self-item-cycle.rs index 1500bc831528..b0b5ab4235be 100644 --- a/tests/ui/traits/solver-cycles/self-item-cycle.rs +++ b/tests/ui/traits/solver-cycles/self-item-cycle.rs @@ -1,5 +1,6 @@ -trait T : Iterator -//~^ ERROR cycle detected -{} +//! regression test for https://github.com/rust-lang/rust/issues/20772 +trait T: Iterator //~ ERROR cycle detected +{ +} fn main() {} diff --git a/tests/ui/traits/solver-cycles/self-item-cycle.stderr b/tests/ui/traits/solver-cycles/self-item-cycle.stderr index 81f80aef5944..9ffb9955af8a 100644 --- a/tests/ui/traits/solver-cycles/self-item-cycle.stderr +++ b/tests/ui/traits/solver-cycles/self-item-cycle.stderr @@ -1,15 +1,15 @@ error[E0391]: cycle detected when computing the super traits of `T` with associated type name `Item` - --> $DIR/issue-20772.rs:1:1 + --> $DIR/self-item-cycle.rs:2:1 | -LL | trait T : Iterator - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | trait T: Iterator + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: ...which immediately requires computing the super traits of `T` with associated type name `Item` again note: cycle used when computing the super predicates of `T` - --> $DIR/issue-20772.rs:1:1 + --> $DIR/self-item-cycle.rs:2:1 | -LL | trait T : Iterator - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | trait T: Iterator + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 1 previous error diff --git a/tests/ui/typeck/missing-type-annotation.rs b/tests/ui/typeck/missing-type-annotation.rs index bd347d632984..d13a7a8559e3 100644 --- a/tests/ui/typeck/missing-type-annotation.rs +++ b/tests/ui/typeck/missing-type-annotation.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18159 fn main() { let x; //~ ERROR type annotations needed } diff --git a/tests/ui/typeck/missing-type-annotation.stderr b/tests/ui/typeck/missing-type-annotation.stderr index 5de13a5c314c..88716e757a93 100644 --- a/tests/ui/typeck/missing-type-annotation.stderr +++ b/tests/ui/typeck/missing-type-annotation.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/issue-18159.rs:2:9 + --> $DIR/missing-type-annotation.rs:3:9 | LL | let x; | ^ diff --git a/tests/ui/typeck/osstring-str-equality.rs b/tests/ui/typeck/osstring-str-equality.rs index b5a3f07dd4b8..47d3dd632bdc 100644 --- a/tests/ui/typeck/osstring-str-equality.rs +++ b/tests/ui/typeck/osstring-str-equality.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/49854 //@ run-pass use std::ffi::OsString; diff --git a/tests/ui/typeck/return-expression-invalid-callee.rs b/tests/ui/typeck/return-expression-invalid-callee.rs index 31fd87961dc9..1416f3e9ddfe 100644 --- a/tests/ui/typeck/return-expression-invalid-callee.rs +++ b/tests/ui/typeck/return-expression-invalid-callee.rs @@ -1,7 +1,8 @@ -// Test that overloaded call parameter checking does not ICE -// when a type error or unconstrained type variable propagates -// into it. +//! regression test for issue https://github.com/rust-lang/rust/issues/18532 +//! Test that overloaded call parameter checking does not ICE +//! when a type error or unconstrained type variable propagates +//! into it. fn main() { - (return)((),()); //~ ERROR expected function, found `!` + (return)((), ()); //~ ERROR expected function, found `!` } diff --git a/tests/ui/typeck/return-expression-invalid-callee.stderr b/tests/ui/typeck/return-expression-invalid-callee.stderr index 059c7f137819..5a36602af8bb 100644 --- a/tests/ui/typeck/return-expression-invalid-callee.stderr +++ b/tests/ui/typeck/return-expression-invalid-callee.stderr @@ -1,8 +1,8 @@ error[E0618]: expected function, found `!` - --> $DIR/issue-18532.rs:6:5 + --> $DIR/return-expression-invalid-callee.rs:7:5 | -LL | (return)((),()); - | ^^^^^^^^------- +LL | (return)((), ()); + | ^^^^^^^^-------- | | | call expression requires function From 6d139caded024c75752f591a653410f488bc81bf Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 15 Dec 2025 19:01:33 +0100 Subject: [PATCH 0843/3801] Update books --- src/doc/nomicon | 2 +- src/doc/reference | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/nomicon b/src/doc/nomicon index 9fe8fa599ad2..5b3a9d084cbc 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 9fe8fa599ad228dda74f240cc32b54bc5c1aa3e6 +Subproject commit 5b3a9d084cbc64e54da87e3eec7c7faae0e48ba9 diff --git a/src/doc/reference b/src/doc/reference index 50c5de90487b..ec78de0ffe2f 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 50c5de90487b68d429a30cc9466dc8f5b410128f +Subproject commit ec78de0ffe2f8344bd0e222b17ac7a7d32dc7a26 From ebfe9698f0cab44ca719a6e5850c9404d1ebcc4b Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Mon, 15 Dec 2025 18:42:56 +0100 Subject: [PATCH 0844/3801] Parent of struct constructor is the struct itself Also, the `Fn`/`AssocFn` cases were not tested anywhere, and according to the comments inside `TyCtxt::res_generic_def_id()` could have made the `TyCtxt::generics_of()` call also trigger an ICE. --- clippy_lints/src/casts/needless_type_cast.rs | 7 +------ tests/ui/needless_type_cast_unfixable.rs | 20 ++++++++++++++++++++ tests/ui/needless_type_cast_unfixable.stderr | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 tests/ui/needless_type_cast_unfixable.rs create mode 100644 tests/ui/needless_type_cast_unfixable.stderr diff --git a/clippy_lints/src/casts/needless_type_cast.rs b/clippy_lints/src/casts/needless_type_cast.rs index ca6aa0f87bbf..8ef9db1b510c 100644 --- a/clippy_lints/src/casts/needless_type_cast.rs +++ b/clippy_lints/src/casts/needless_type_cast.rs @@ -182,12 +182,7 @@ fn is_generic_res(cx: &LateContext<'_>, res: Res) -> bool { .iter() .any(|p| p.kind.is_ty_or_const()) }; - match res { - Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => has_type_params(def_id), - // Ctor → Variant → ADT: constructor's parent is variant, variant's parent is the ADT - Res::Def(DefKind::Ctor(..), def_id) => has_type_params(cx.tcx.parent(cx.tcx.parent(def_id))), - _ => false, - } + cx.tcx.res_generics_def_id(res).is_some_and(has_type_params) } fn is_cast_in_generic_context<'a>(cx: &LateContext<'a>, cast_expr: &Expr<'a>) -> bool { diff --git a/tests/ui/needless_type_cast_unfixable.rs b/tests/ui/needless_type_cast_unfixable.rs new file mode 100644 index 000000000000..bbea9bd24296 --- /dev/null +++ b/tests/ui/needless_type_cast_unfixable.rs @@ -0,0 +1,20 @@ +//@no-rustfix +#![warn(clippy::needless_type_cast)] + +struct Foo(*mut core::ffi::c_void); + +enum Bar { + Variant(*mut core::ffi::c_void), +} + +// Suggestions will not compile directly, as `123` is a literal which +// is not compatible with the suggested `*mut core::ffi::c_void` type +fn issue_16243() { + let underlying: isize = 123; + //~^ needless_type_cast + let handle: Foo = Foo(underlying as _); + + let underlying: isize = 123; + //~^ needless_type_cast + let handle: Bar = Bar::Variant(underlying as _); +} diff --git a/tests/ui/needless_type_cast_unfixable.stderr b/tests/ui/needless_type_cast_unfixable.stderr new file mode 100644 index 000000000000..b71f8a09c40f --- /dev/null +++ b/tests/ui/needless_type_cast_unfixable.stderr @@ -0,0 +1,17 @@ +error: this binding is defined as `isize` but is always cast to `*mut std::ffi::c_void` + --> tests/ui/needless_type_cast_unfixable.rs:13:21 + | +LL | let underlying: isize = 123; + | ^^^^^ help: consider defining it as: `*mut std::ffi::c_void` + | + = note: `-D clippy::needless-type-cast` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_type_cast)]` + +error: this binding is defined as `isize` but is always cast to `*mut std::ffi::c_void` + --> tests/ui/needless_type_cast_unfixable.rs:17:21 + | +LL | let underlying: isize = 123; + | ^^^^^ help: consider defining it as: `*mut std::ffi::c_void` + +error: aborting due to 2 previous errors + From 023f38fe73f5e392ea94cc15e53611bd2074302e Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 13 Dec 2025 22:59:34 +0100 Subject: [PATCH 0845/3801] custom `VaList` layout for Hexagon --- library/core/src/ffi/va_list.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index 4c59ea0cc532..d5166baf0c7c 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -31,6 +31,9 @@ use crate::marker::PhantomCovariantLifetime; // the pointer decay behavior in Rust, while otherwise matching Rust semantics. // This attribute ensures that the compiler uses the correct ABI for functions // like `extern "C" fn takes_va_list(va: VaList<'_>)` by passing `va` indirectly. +// +// The Clang `BuiltinVaListKind` enumerates the `va_list` variations that Clang supports, +// and we mirror these here. crate::cfg_select! { all( target_arch = "aarch64", @@ -124,6 +127,23 @@ crate::cfg_select! { } } + all(target_arch = "hexagon", target_env = "musl") => { + /// Hexagon Musl implementation of a `va_list`. + /// + /// See the [LLVM source] for more details. On bare metal Hexagon uses an opaque pointer. + /// + /// [LLVM source]: + /// https://github.com/llvm/llvm-project/blob/0cdc1b6dd4a870fc41d4b15ad97e0001882aba58/clang/lib/CodeGen/Targets/Hexagon.cpp#L407-L417 + #[repr(C)] + #[derive(Debug)] + #[rustc_pass_indirectly_in_non_rustic_abis] + struct VaListInner { + __current_saved_reg_area_pointer: *const c_void, + __saved_reg_area_end_pointer: *const c_void, + __overflow_area_pointer: *const c_void, + } + } + // The fallback implementation, used for: // // - apple aarch64 (see https://github.com/rust-lang/rust/pull/56599) From 72c84a6c808471ef03550a523dc968f96c312ef5 Mon Sep 17 00:00:00 2001 From: Jane Losare-Lusby Date: Thu, 4 Dec 2025 11:35:21 -0800 Subject: [PATCH 0846/3801] assert impossible branch is impossible --- compiler/rustc_resolve/src/ident.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 16f2212bd734..f4a594a4731d 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -743,10 +743,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let ambiguity_error_kind = if is_builtin(innermost_res) || is_builtin(res) { Some(AmbiguityKind::BuiltinAttr) - } else if innermost_res == derive_helper_compat - || res == derive_helper_compat && innermost_res != derive_helper - { + } else if innermost_res == derive_helper_compat { Some(AmbiguityKind::DeriveHelper) + } else if res == derive_helper_compat && innermost_res != derive_helper { + span_bug!(orig_ident.span, "impossible inner resolution kind") } else if innermost_flags.contains(Flags::MACRO_RULES) && flags.contains(Flags::MODULE) && !self.disambiguate_macro_rules_vs_modularized(innermost_binding, binding) From 344ddcf9f2bfba51c49b047280eee45293ec2b4f Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Mon, 15 Dec 2025 20:12:17 +0100 Subject: [PATCH 0847/3801] Move `needless_type_cast` lint to nursery The lint is new and already has several bugs filed against it, including an ICE. --- clippy_lints/src/casts/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 494d6180d3cb..7220a8a80066 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -836,7 +836,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.93.0"] pub NEEDLESS_TYPE_CAST, - pedantic, + nursery, "binding defined with one type but always cast to another" } From b3c1dff330f82827e823e8e7b8572562e8d5dc56 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 15 Dec 2025 14:46:15 -0500 Subject: [PATCH 0848/3801] Open bootstrap.example.toml with the utf-8 encoding --- src/bootstrap/configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 1915986be28c..e3895d4e0a18 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -593,7 +593,7 @@ def parse_example_config(known_args, config): top_level_keys = [] comment_lines = [] - with open(rust_dir + "/bootstrap.example.toml") as example_config: + with open(rust_dir + "/bootstrap.example.toml", encoding="utf-8") as example_config: example_lines = example_config.read().split("\n") for line in example_lines: if line.count("=") >= 1 and not line.startswith("# "): From c194e9ef56f971980bc39538cf06917d2a894953 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 15 Dec 2025 20:55:33 +0000 Subject: [PATCH 0849/3801] do not add `I-prioritize` when `F-*` labels are present --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 3182122bdeb0..ce1abd6df3e7 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -218,6 +218,7 @@ exclude_labels = [ "T-infra", "T-release", "requires-nightly", + "F-*", ] [autolabel."T-rustdoc"] From 3493f8c0b6393430b3437121a463a6c6d69f3f3d Mon Sep 17 00:00:00 2001 From: Almog Gavra Date: Mon, 15 Dec 2025 13:02:47 -0800 Subject: [PATCH 0850/3801] fix docustring on fetch_or --- library/core/src/sync/atomic.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 0601019abbd5..1eae06ebd33e 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1151,8 +1151,8 @@ impl AtomicBool { /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true); /// assert_eq!(foo.load(Ordering::SeqCst), true); /// - /// let foo = AtomicBool::new(true); - /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), true); + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), false); /// assert_eq!(foo.load(Ordering::SeqCst), true); /// /// let foo = AtomicBool::new(false); From f05ed901fcfb6a4a18ac16b6b3328a5898337005 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 15 Dec 2025 22:09:07 +0100 Subject: [PATCH 0851/3801] Use the embeddable filename for coverage artifacts --- .../src/coverageinfo/mapgen.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index bc54657a380a..a728f3ea1e66 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -7,7 +7,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods}; use rustc_data_structures::fx::FxIndexMap; use rustc_index::IndexVec; use rustc_middle::ty::TyCtxt; -use rustc_span::{RemapPathScopeComponents, SourceFile, StableSourceFileId}; +use rustc_span::{FileName, RemapPathScopeComponents, SourceFile, StableSourceFileId}; use tracing::debug; use crate::common::CodegenCx; @@ -125,7 +125,19 @@ impl GlobalFileTable { for file in all_files { raw_file_table.entry(file.stable_id).or_insert_with(|| { - file.name.display(RemapPathScopeComponents::COVERAGE).to_string_lossy().into_owned() + // Prefer using the embeddable filename as this filename is going to + // end-up in the coverage artifacts (see rust-lang/rust#150020). + if let FileName::Real(real) = &file.name { + let (_work_dir, abs_name) = + real.embeddable_name(RemapPathScopeComponents::COVERAGE); + + abs_name.to_string_lossy().into_owned() + } else { + file.name + .display(RemapPathScopeComponents::COVERAGE) + .to_string_lossy() + .into_owned() + } }); } From d8a0f800f7cc6b977e2bde9b28ad97964ed4381b Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 15 Dec 2025 16:22:55 -0600 Subject: [PATCH 0852/3801] fixup! Implement va_arg for Hexagon Linux musl targets --- compiler/rustc_codegen_llvm/src/va_arg.rs | 55 ++++++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index aa5776b298d2..82cc45d161c4 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -780,7 +780,7 @@ fn x86_64_sysv64_va_arg_from_memory<'ll, 'tcx>( mem_addr } -fn emit_hexagon_va_arg<'ll, 'tcx>( +fn emit_hexagon_va_arg_musl<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, list: OperandRef<'tcx, &'ll Value>, target_ty: Ty<'tcx>, @@ -865,6 +865,57 @@ fn emit_hexagon_va_arg<'ll, 'tcx>( bx.load(layout.llvm_type(bx), value_addr, layout.align.abi) } +fn emit_hexagon_va_arg_bare_metal<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, + list: OperandRef<'tcx, &'ll Value>, + target_ty: Ty<'tcx>, +) -> &'ll Value { + // Implementation of va_arg for Hexagon bare-metal (non-musl) targets. + // Based on LLVM's EmitVAArgForHexagon implementation. + // + // va_list is a simple pointer (char *) + let va_list_addr = list.immediate(); + let layout = bx.cx.layout_of(target_ty); + let ptr_align_abi = bx.tcx().data_layout.pointer_align().abi; + + // Load current pointer from va_list + let current_ptr = bx.load(bx.type_ptr(), va_list_addr, ptr_align_abi); + + // Handle address alignment for types with alignment > 4 bytes + let ty_align = layout.align.abi; + let aligned_ptr = if ty_align.bytes() > 4 { + // Ensure alignment is a power of 2 + debug_assert!(ty_align.bytes().is_power_of_two(), "Alignment is not power of 2!"); + round_pointer_up_to_alignment(bx, current_ptr, ty_align, bx.type_ptr()) + } else { + current_ptr + }; + + // Calculate offset: round up type size to 4-byte boundary (minimum stack slot size) + let type_size = layout.size.bytes(); + let offset = ((type_size + 3) / 4) * 4; // align to 4 bytes + + // Update va_list to point to next argument + let next_ptr = bx.inbounds_ptradd(aligned_ptr, bx.const_usize(offset)); + bx.store(next_ptr, va_list_addr, ptr_align_abi); + + // Load and return the argument value + bx.load(layout.llvm_type(bx), aligned_ptr, layout.align.abi) +} + +fn emit_hexagon_va_arg<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, + list: OperandRef<'tcx, &'ll Value>, + target_ty: Ty<'tcx>, + is_musl: bool, +) -> &'ll Value { + if is_musl { + emit_hexagon_va_arg_musl(bx, list, target_ty) + } else { + emit_hexagon_va_arg_bare_metal(bx, list, target_ty) + } +} + fn emit_xtensa_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, list: OperandRef<'tcx, &'ll Value>, @@ -1049,7 +1100,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( // This includes `target.is_like_darwin`, which on x86_64 targets is like sysv64. Arch::X86_64 => emit_x86_64_sysv64_va_arg(bx, addr, target_ty), Arch::Xtensa => emit_xtensa_va_arg(bx, addr, target_ty), - Arch::Hexagon if target.env == Env::Musl => emit_hexagon_va_arg(bx, addr, target_ty), + Arch::Hexagon => emit_hexagon_va_arg(bx, addr, target_ty, target.env == Env::Musl), // For all other architecture/OS combinations fall back to using // the LLVM va_arg instruction. // https://llvm.org/docs/LangRef.html#va-arg-instruction From dbfc8c218e1f48290b261146f8463878362ba100 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Mon, 15 Dec 2025 15:21:18 +0000 Subject: [PATCH 0853/3801] dont create unnecessary `DefId`s under mgca --- compiler/rustc_metadata/src/rmeta/encoder.rs | 5 +++- compiler/rustc_resolve/src/def_collector.rs | 10 ++++++++ .../mgca/explicit_anon_consts.rs | 5 ++-- .../mgca/explicit_anon_consts.stderr | 24 +++++++++---------- .../mgca/unused_speculative_def_id.rs | 24 +++++++++++++++++++ .../mgca/unused_speculative_def_id.stderr | 18 ++++++++++++++ 6 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 tests/ui/const-generics/mgca/unused_speculative_def_id.rs create mode 100644 tests/ui/const-generics/mgca/unused_speculative_def_id.stderr diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b15ed34fc356..7da82835befb 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1451,7 +1451,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { _ => false, } { - continue; + // MGCA doesn't have unnecessary DefIds + if !tcx.features().min_generic_const_args() { + continue; + } } if def_kind == DefKind::Field diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index ea64a1e6c64d..71bbd64ddc6c 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -357,6 +357,16 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } fn visit_anon_const(&mut self, constant: &'a AnonConst) { + // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so + // to avoid affecting stable we have to feature gate the not creating + // anon consts + if let MgcaDisambiguation::Direct = constant.mgca_disambiguation + && self.resolver.tcx.features().min_generic_const_args() + { + visit::walk_anon_const(self, constant); + return; + } + let parent = self.create_def(constant.id, None, DefKind::AnonConst, constant.value.span); self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); } diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs index 459282776266..31391b023bfe 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -1,5 +1,8 @@ #![feature(associated_const_equality, generic_const_items, min_generic_const_args)] #![expect(incomplete_features)] +// library crates exercise weirder code paths around +// DefIds which were created for const args. +#![crate_type = "lib"] struct Foo; @@ -66,5 +69,3 @@ struct Default3; struct Default4; //~^ ERROR: complex const arguments must be placed inside of a `const` block struct Default5; - -fn main() {} diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index e4bf49c71efe..b3d960e315ea 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:8:41 + --> $DIR/explicit_anon_consts.rs:11:41 | LL | type Adt3 = Foo; | ^ cannot perform const operation using `N` @@ -8,7 +8,7 @@ LL | type Adt3 = Foo; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:16:42 + --> $DIR/explicit_anon_consts.rs:19:42 | LL | type Arr3 = [(); const { N }]; | ^ cannot perform const operation using `N` @@ -17,7 +17,7 @@ LL | type Arr3 = [(); const { N }]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:25:27 + --> $DIR/explicit_anon_consts.rs:28:27 | LL | let _3 = [(); const { N }]; | ^ cannot perform const operation using `N` @@ -26,7 +26,7 @@ LL | let _3 = [(); const { N }]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:37:46 + --> $DIR/explicit_anon_consts.rs:40:46 | LL | const ITEM3: usize = const { N }; | ^ cannot perform const operation using `N` @@ -35,7 +35,7 @@ LL | const ITEM3: usize = const { N }; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:55:31 + --> $DIR/explicit_anon_consts.rs:58:31 | LL | T3: Trait, | ^ cannot perform const operation using `N` @@ -44,7 +44,7 @@ LL | T3: Trait, = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:64:58 + --> $DIR/explicit_anon_consts.rs:67:58 | LL | struct Default3; | ^ cannot perform const operation using `N` @@ -53,37 +53,37 @@ LL | struct Default3; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:10:33 + --> $DIR/explicit_anon_consts.rs:13:33 | LL | type Adt4 = Foo<{ 1 + 1 }>; | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:18:34 + --> $DIR/explicit_anon_consts.rs:21:34 | LL | type Arr4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:27:19 + --> $DIR/explicit_anon_consts.rs:30:19 | LL | let _4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:40:38 + --> $DIR/explicit_anon_consts.rs:43:38 | LL | const ITEM4: usize = { 1 + 1 }; | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:57:23 + --> $DIR/explicit_anon_consts.rs:60:23 | LL | T4: Trait, | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:66:50 + --> $DIR/explicit_anon_consts.rs:69:50 | LL | struct Default4; | ^^^^^^^^^ diff --git a/tests/ui/const-generics/mgca/unused_speculative_def_id.rs b/tests/ui/const-generics/mgca/unused_speculative_def_id.rs new file mode 100644 index 000000000000..e617daba24b6 --- /dev/null +++ b/tests/ui/const-generics/mgca/unused_speculative_def_id.rs @@ -0,0 +1,24 @@ +#![feature(min_generic_const_args, generic_const_exprs, generic_const_items)] +#![expect(incomplete_features)] + +// Previously we would create a `DefId` to represent the const argument to `A` +// except it would go unused as it's a MGCA path const arg. We would also make +// a `DefId` for the `const { 1 }` anon const arg to `ERR` which would wind up +// with a `DefId` parent of the speculatively created `DefId` for the argument to +// `A`. +// +// This then caused Problems:tm: in the rest of the compiler that did not expect +// to encounter such nonsensical `DefId`s. +// +// The `ERR` path must fail to resolve as if it can be resolved then broken GCE +// logic will attempt to evaluate the constant directly which is wrong for +// `type_const`s which do not have bodies. + +struct A; + +struct Foo { + field: A<{ ERR:: }>, + //~^ ERROR: cannot find value `ERR` in this scope +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr b/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr new file mode 100644 index 000000000000..e087e046ec35 --- /dev/null +++ b/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr @@ -0,0 +1,18 @@ +error[E0425]: cannot find value `ERR` in this scope + --> $DIR/unused_speculative_def_id.rs:20:16 + | +LL | field: A<{ ERR:: }>, + | ^^^ + | + --> $SRC_DIR/core/src/result.rs:LL:COL + | + = note: similarly named tuple variant `Err` defined here +help: a tuple variant with a similar name exists + | +LL - field: A<{ ERR:: }>, +LL + field: A<{ Err:: }>, + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. From cf267e5b47648d3a1240d1fdc42fdaede9636c89 Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Mon, 1 Dec 2025 22:49:41 +0000 Subject: [PATCH 0854/3801] fix: `use_self` FP on type in const generics --- clippy_lints/src/use_self.rs | 36 +++++++++++++++- tests/ui/use_self.fixed | 25 +++++++++++ tests/ui/use_self.rs | 25 +++++++++++ tests/ui/use_self.stderr | 84 ++++++++++++++++++------------------ 4 files changed, 127 insertions(+), 43 deletions(-) diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index eba60501ae21..38ce9dc3f916 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -10,13 +10,14 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty}; use rustc_hir::{ self as hir, AmbigArg, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParamKind, HirId, Impl, - ImplItemImplKind, ImplItemKind, Item, ItemKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind, + ImplItemImplKind, ImplItemKind, Item, ItemKind, Node, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty as MiddleTy; use rustc_session::impl_lint_pass; use rustc_span::Span; use std::iter; +use std::ops::ControlFlow; declare_clippy_lint! { /// ### What it does @@ -213,6 +214,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { path.res, Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Def(DefKind::TyParam, _) ) + && !ty_is_in_generic_args(cx, hir_ty) && !types_to_skip.contains(&hir_ty.hir_id) && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty()) && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity() @@ -312,6 +314,38 @@ fn lint_path_to_variant(cx: &LateContext<'_>, path: &Path<'_>) { } } +fn ty_is_in_generic_args<'tcx>(cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) -> bool { + cx.tcx.hir_parent_iter(hir_ty.hir_id).any(|(_, parent)| { + matches!(parent, Node::ImplItem(impl_item) if impl_item.generics.params.iter().any(|param| { + let GenericParamKind::Const { ty: const_ty, .. } = ¶m.kind else { + return false; + }; + ty_contains_ty(const_ty, hir_ty) + })) + }) +} + +fn ty_contains_ty<'tcx>(outer: &Ty<'tcx>, inner: &Ty<'tcx, AmbigArg>) -> bool { + struct ContainsVisitor<'tcx> { + inner: &'tcx Ty<'tcx, AmbigArg>, + } + + impl<'tcx> Visitor<'tcx> for ContainsVisitor<'tcx> { + type Result = ControlFlow<()>; + + fn visit_ty(&mut self, t: &'tcx Ty<'tcx, AmbigArg>) -> Self::Result { + if t.hir_id == self.inner.hir_id { + return ControlFlow::Break(()); + } + + walk_ty(self, t) + } + } + + let mut visitor = ContainsVisitor { inner }; + visitor.visit_ty_unambig(outer).is_break() +} + /// Checks whether types `a` and `b` have the same lifetime parameters. /// /// This function does not check that types `a` and `b` are the same types. diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index 075e31d202b0..37559f9a2367 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -10,6 +10,9 @@ clippy::needless_lifetimes, clippy::missing_transmute_annotations )] +#![allow(incomplete_features)] +#![feature(adt_const_params)] +#![feature(unsized_const_params)] #[macro_use] extern crate proc_macro_derive; @@ -769,3 +772,25 @@ mod issue_13277 { type Item<'foo> = Option>; } } + +mod issue16164 { + trait Bits { + fn bit(self) -> bool; + } + + impl Bits for u8 { + fn bit(self) -> bool { + todo!() + } + } + + trait T { + fn f(self) -> bool; + } + + impl T for u8 { + fn f(self) -> bool { + todo!() + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 6fbba0bbc550..74abd2f61bf9 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -10,6 +10,9 @@ clippy::needless_lifetimes, clippy::missing_transmute_annotations )] +#![allow(incomplete_features)] +#![feature(adt_const_params)] +#![feature(unsized_const_params)] #[macro_use] extern crate proc_macro_derive; @@ -769,3 +772,25 @@ mod issue_13277 { type Item<'foo> = Option>; } } + +mod issue16164 { + trait Bits { + fn bit(self) -> bool; + } + + impl Bits for u8 { + fn bit(self) -> bool { + todo!() + } + } + + trait T { + fn f(self) -> bool; + } + + impl T for u8 { + fn f(self) -> bool { + todo!() + } + } +} diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index 5f65c53ea25c..8ce341d22d4f 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -1,5 +1,5 @@ error: unnecessary structure name repetition - --> tests/ui/use_self.rs:23:21 + --> tests/ui/use_self.rs:26:21 | LL | fn new() -> Foo { | ^^^ help: use the applicable keyword: `Self` @@ -8,247 +8,247 @@ LL | fn new() -> Foo { = help: to override `-D warnings` add `#[allow(clippy::use_self)]` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:25:13 + --> tests/ui/use_self.rs:28:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:28:22 + --> tests/ui/use_self.rs:31:22 | LL | fn test() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:30:13 + --> tests/ui/use_self.rs:33:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:36:25 + --> tests/ui/use_self.rs:39:25 | LL | fn default() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:38:13 + --> tests/ui/use_self.rs:41:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:80:28 + --> tests/ui/use_self.rs:83:28 | LL | fn clone(&self) -> Foo<'a> { | ^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:114:24 + --> tests/ui/use_self.rs:117:24 | LL | fn bad(foos: &[Foo]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:114:55 + --> tests/ui/use_self.rs:117:55 | LL | fn bad(foos: &[Foo]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:131:13 + --> tests/ui/use_self.rs:134:13 | LL | TS(0) | ^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:167:29 + --> tests/ui/use_self.rs:170:29 | LL | fn bar() -> Bar { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:169:21 + --> tests/ui/use_self.rs:172:21 | LL | Bar { foo: Foo {} } | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:181:21 + --> tests/ui/use_self.rs:184:21 | LL | fn baz() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:183:13 + --> tests/ui/use_self.rs:186:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:201:21 + --> tests/ui/use_self.rs:204:21 | LL | let _ = Enum::B(42); | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:203:21 + --> tests/ui/use_self.rs:206:21 | LL | let _ = Enum::C { field: true }; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:205:21 + --> tests/ui/use_self.rs:208:21 | LL | let _ = Enum::A; | ^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:248:13 + --> tests/ui/use_self.rs:251:13 | LL | nested::A::fun_1(); | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:250:13 + --> tests/ui/use_self.rs:253:13 | LL | nested::A::A; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:253:13 + --> tests/ui/use_self.rs:256:13 | LL | nested::A {}; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:273:13 + --> tests/ui/use_self.rs:276:13 | LL | TestStruct::from_something() | ^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:288:25 + --> tests/ui/use_self.rs:291:25 | LL | async fn g() -> S { | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:290:13 + --> tests/ui/use_self.rs:293:13 | LL | S {} | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:295:16 + --> tests/ui/use_self.rs:298:16 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:295:22 + --> tests/ui/use_self.rs:298:22 | LL | &p[S::A..S::B] | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:320:29 + --> tests/ui/use_self.rs:323:29 | LL | fn foo(value: T) -> Foo { | ^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:322:13 + --> tests/ui/use_self.rs:325:13 | LL | Foo:: { value } | ^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:495:13 + --> tests/ui/use_self.rs:498:13 | LL | A::new::(submod::B {}) | ^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:571:17 + --> tests/ui/use_self.rs:574:17 | LL | Foo::Bar => unimplemented!(), | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:573:17 + --> tests/ui/use_self.rs:576:17 | LL | Foo::Baz => unimplemented!(), | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:580:20 + --> tests/ui/use_self.rs:583:20 | LL | if let Foo::Bar = self { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:605:17 + --> tests/ui/use_self.rs:608:17 | LL | Something::Num(n) => *n, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:607:17 + --> tests/ui/use_self.rs:610:17 | LL | Something::TupleNums(n, _m) => *n, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:609:17 + --> tests/ui/use_self.rs:612:17 | LL | Something::StructNums { one, two: _ } => *one, | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:616:17 + --> tests/ui/use_self.rs:619:17 | LL | crate::issue8845::Something::Num(n) => *n, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:618:17 + --> tests/ui/use_self.rs:621:17 | LL | crate::issue8845::Something::TupleNums(n, _m) => *n, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:620:17 + --> tests/ui/use_self.rs:623:17 | LL | crate::issue8845::Something::StructNums { one, two: _ } => *one, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:637:17 + --> tests/ui/use_self.rs:640:17 | LL | let Foo(x) = self; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:643:17 + --> tests/ui/use_self.rs:646:17 | LL | let crate::issue8845::Foo(x) = self; | ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:651:17 + --> tests/ui/use_self.rs:654:17 | LL | let Bar { x, .. } = self; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:657:17 + --> tests/ui/use_self.rs:660:17 | LL | let crate::issue8845::Bar { x, .. } = self; | ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> tests/ui/use_self.rs:697:17 + --> tests/ui/use_self.rs:700:17 | LL | E::A => {}, | ^ help: use the applicable keyword: `Self` From bb6d9363a73fb037a5800f595be1bdb55e9a3a00 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Wed, 10 Dec 2025 19:09:24 +0200 Subject: [PATCH 0855/3801] Provide an extended framework for type visit, for use in rust-analyzer rust-analyzer needs to be able to visit types when treating not only `Ty`, `Const`, `Region` and `Predicate` specifically, but *all* rust-analyzer-made types specifically (excluding e.g. `TraitRef`, that is declared in rustc_type_ir). This is needed to implement garbage collection. To support this, we introduce a second, rust-analyzer-only visit trait, named `GenericTypeVisitable`. It's simpler than `TypeVisitable` (for example, it does not have a trait for the visitor, and does not support early-returning) because this is what rust-analyzer needs, but its most distinguished feature is that the visitor is a generic of the *trait* instead of the *method*. This way, specific types can treat specific visitor types specifically and call their methods. In rustc_type_ir we implement it for a bunch of basic types, and using a derive macro for the rest. The macro and trait are completely disabled when compiling for rustc (`feature = "nightly"`), so not even a compile time penalty will be paid. --- compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/binder.rs | 6 +- compiler/rustc_type_ir/src/canonical.rs | 7 +- compiler/rustc_type_ir/src/const_kind.rs | 7 +- compiler/rustc_type_ir/src/error.rs | 6 +- compiler/rustc_type_ir/src/generic_arg.rs | 3 + compiler/rustc_type_ir/src/generic_visit.rs | 251 ++++++++++++++++++ compiler/rustc_type_ir/src/lib.rs | 7 +- compiler/rustc_type_ir/src/opaque_ty.rs | 4 +- compiler/rustc_type_ir/src/pattern.rs | 6 +- compiler/rustc_type_ir/src/predicate.rs | 28 +- compiler/rustc_type_ir/src/predicate_kind.rs | 6 +- compiler/rustc_type_ir/src/region_kind.rs | 2 + compiler/rustc_type_ir/src/solve/inspect.rs | 6 +- compiler/rustc_type_ir/src/solve/mod.rs | 16 +- compiler/rustc_type_ir/src/ty_info.rs | 3 +- compiler/rustc_type_ir/src/ty_kind.rs | 20 +- compiler/rustc_type_ir/src/ty_kind/closure.rs | 14 +- compiler/rustc_type_ir_macros/Cargo.toml | 3 + compiler/rustc_type_ir_macros/src/lib.rs | 40 +++ 20 files changed, 381 insertions(+), 55 deletions(-) create mode 100644 compiler/rustc_type_ir/src/generic_visit.rs diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 6ccddb17ff22..315ab8b97e9b 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -35,6 +35,7 @@ nightly = [ "dep:rustc_span", "rustc_ast_ir/nightly", "rustc_index/nightly", + "rustc_type_ir_macros/nightly", "smallvec/may_dangle", "smallvec/union", ] diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 94b950357e1e..036d3fbcd528 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -4,7 +4,7 @@ use std::ops::{ControlFlow, Deref}; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::instrument; use crate::data_structures::SsoHashSet; @@ -24,6 +24,7 @@ use crate::{self as ty, DebruijnIndex, Interner}; /// `Decodable` and `Encodable` are implemented for `Binder` using the `impl_binder_encode_decode!` macro. #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, T)] #[derive_where(Copy; I: Interner, T: Copy)] +#[derive(GenericTypeVisitable)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct Binder { value: T, @@ -360,6 +361,7 @@ impl TypeVisitor for ValidateBoundVars { #[derive_where(Clone, PartialEq, Ord, Hash, Debug; I: Interner, T)] #[derive_where(PartialOrd; I: Interner, T: Ord)] #[derive_where(Copy; I: Interner, T: Copy)] +#[derive(GenericTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -943,7 +945,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> { feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub enum BoundVarIndexKind { Bound(DebruijnIndex), Canonical, diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 7b4b953b2cf6..47e753d78731 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -5,7 +5,9 @@ use arrayvec::ArrayVec; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::data_structures::HashMap; use crate::inherent::*; @@ -86,6 +88,7 @@ impl fmt::Display for Canonical { /// a copy of the canonical value in some other inference context, /// with fresh inference variables replacing the canonical values. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] +#[derive(GenericTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -219,7 +222,7 @@ impl CanonicalVarKind { feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct CanonicalVarValues { pub var_values: I::GenericArgs, } diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 8393bbe5caf8..f315e8b3e11c 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -5,12 +5,15 @@ use derive_where::derive_where; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::{self as ty, BoundVarIndexKind, Interner}; /// Represents a constant in Rust. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] +#[derive(GenericTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -66,7 +69,7 @@ impl fmt::Debug for ConstKind { /// An unevaluated (potentially generic) constant used in the type-system. #[derive_where(Clone, Copy, Debug, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index eb5b6b4a1b45..502622aa50ca 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -1,11 +1,11 @@ use derive_where::derive_where; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::solve::NoSolution; use crate::{self as ty, Interner}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[derive(TypeFoldable_Generic, TypeVisitable_Generic)] +#[derive(TypeFoldable_Generic, TypeVisitable_Generic, GenericTypeVisitable)] pub struct ExpectedFound { pub expected: T, pub found: T, @@ -19,7 +19,7 @@ impl ExpectedFound { // Data structures used in type unification #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable)] #[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum TypeError { Mismatch, diff --git a/compiler/rustc_type_ir/src/generic_arg.rs b/compiler/rustc_type_ir/src/generic_arg.rs index d6e33f724d0b..5d612740fdd8 100644 --- a/compiler/rustc_type_ir/src/generic_arg.rs +++ b/compiler/rustc_type_ir/src/generic_arg.rs @@ -1,10 +1,12 @@ use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; +use rustc_type_ir_macros::GenericTypeVisitable; use crate::Interner; #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] +#[derive(GenericTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -18,6 +20,7 @@ pub enum GenericArgKind { impl Eq for GenericArgKind {} #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] +#[derive(GenericTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/generic_visit.rs b/compiler/rustc_type_ir/src/generic_visit.rs new file mode 100644 index 000000000000..ee55c63ab477 --- /dev/null +++ b/compiler/rustc_type_ir/src/generic_visit.rs @@ -0,0 +1,251 @@ +//! A visiting traversal mechanism for complex data structures that contain type +//! information. +//! +//! This is a read-only traversal of the data structure. +//! +//! This traversal has limited flexibility. Only a small number of "types of +//! interest" within the complex data structures can receive custom +//! visitation. These are the ones containing the most important type-related +//! information, such as `Ty`, `Predicate`, `Region`, and `Const`. +//! +//! There are three traits involved in each traversal. +//! - `GenericTypeVisitable`. This is implemented once for many types, including: +//! - Types of interest, for which the methods delegate to the visitor. +//! - All other types, including generic containers like `Vec` and `Option`. +//! It defines a "skeleton" of how they should be visited. +//! - `TypeSuperVisitable`. This is implemented only for recursive types of +//! interest, and defines the visiting "skeleton" for these types. (This +//! excludes `Region` because it is non-recursive, i.e. it never contains +//! other types of interest.) +//! - `CustomizableTypeVisitor`. This is implemented for each visitor. This defines how +//! types of interest are visited. +//! +//! This means each visit is a mixture of (a) generic visiting operations, and (b) +//! custom visit operations that are specific to the visitor. +//! - The `GenericTypeVisitable` impls handle most of the traversal, and call into +//! `CustomizableTypeVisitor` when they encounter a type of interest. +//! - A `CustomizableTypeVisitor` may call into another `GenericTypeVisitable` impl, because some of +//! the types of interest are recursive and can contain other types of interest. +//! - A `CustomizableTypeVisitor` may also call into a `TypeSuperVisitable` impl, because each +//! visitor might provide custom handling only for some types of interest, or +//! only for some variants of each type of interest, and then use default +//! traversal for the remaining cases. +//! +//! For example, if you have `struct S(Ty, U)` where `S: GenericTypeVisitable` and `U: +//! GenericTypeVisitable`, and an instance `s = S(ty, u)`, it would be visited like so: +//! ```text +//! s.generic_visit_with(visitor) calls +//! - ty.generic_visit_with(visitor) calls +//! - visitor.visit_ty(ty) may call +//! - ty.super_generic_visit_with(visitor) +//! - u.generic_visit_with(visitor) +//! ``` + +use std::sync::Arc; + +use rustc_index::{Idx, IndexVec}; +use smallvec::SmallVec; +use thin_vec::ThinVec; + +/// This trait is implemented for every type that can be visited, +/// providing the skeleton of the traversal. +/// +/// To implement this conveniently, use the derive macro located in +/// `rustc_macros`. +pub trait GenericTypeVisitable { + /// The entry point for visiting. To visit a value `t` with a visitor `v` + /// call: `t.generic_visit_with(v)`. + /// + /// For most types, this just traverses the value, calling `generic_visit_with` on + /// each field/element. + /// + /// For types of interest (such as `Ty`), the implementation of this method + /// that calls a visitor method specifically for that type (such as + /// `V::visit_ty`). This is where control transfers from `GenericTypeVisitable` to + /// `CustomizableTypeVisitor`. + fn generic_visit_with(&self, visitor: &mut V); +} + +/////////////////////////////////////////////////////////////////////////// +// Traversal implementations. + +impl> GenericTypeVisitable for &T { + fn generic_visit_with(&self, visitor: &mut V) { + T::generic_visit_with(*self, visitor) + } +} + +impl, U: GenericTypeVisitable> GenericTypeVisitable for (T, U) { + fn generic_visit_with(&self, visitor: &mut V) { + self.0.generic_visit_with(visitor); + self.1.generic_visit_with(visitor); + } +} + +impl, B: GenericTypeVisitable, C: GenericTypeVisitable> + GenericTypeVisitable for (A, B, C) +{ + fn generic_visit_with(&self, visitor: &mut V) { + self.0.generic_visit_with(visitor); + self.1.generic_visit_with(visitor); + self.2.generic_visit_with(visitor); + } +} + +impl> GenericTypeVisitable for Option { + fn generic_visit_with(&self, visitor: &mut V) { + match self { + Some(v) => v.generic_visit_with(visitor), + None => {} + } + } +} + +impl, E: GenericTypeVisitable> GenericTypeVisitable + for Result +{ + fn generic_visit_with(&self, visitor: &mut V) { + match self { + Ok(v) => v.generic_visit_with(visitor), + Err(e) => e.generic_visit_with(visitor), + } + } +} + +impl> GenericTypeVisitable for Arc { + fn generic_visit_with(&self, visitor: &mut V) { + (**self).generic_visit_with(visitor) + } +} + +impl> GenericTypeVisitable for Box { + fn generic_visit_with(&self, visitor: &mut V) { + (**self).generic_visit_with(visitor) + } +} + +impl> GenericTypeVisitable for Vec { + fn generic_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.generic_visit_with(visitor)); + } +} + +impl> GenericTypeVisitable for ThinVec { + fn generic_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.generic_visit_with(visitor)); + } +} + +impl, const N: usize> GenericTypeVisitable for SmallVec<[T; N]> { + fn generic_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.generic_visit_with(visitor)); + } +} + +impl> GenericTypeVisitable for [T] { + fn generic_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.generic_visit_with(visitor)); + } +} + +impl, Ix: Idx> GenericTypeVisitable for IndexVec { + fn generic_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.generic_visit_with(visitor)); + } +} + +impl GenericTypeVisitable for std::hash::BuildHasherDefault { + fn generic_visit_with(&self, _visitor: &mut V) {} +} + +#[expect(rustc::default_hash_types, rustc::potential_query_instability)] +impl< + Visitor, + Key: GenericTypeVisitable, + Value: GenericTypeVisitable, + S: GenericTypeVisitable, +> GenericTypeVisitable for std::collections::HashMap +{ + fn generic_visit_with(&self, visitor: &mut Visitor) { + self.iter().for_each(|it| it.generic_visit_with(visitor)); + self.hasher().generic_visit_with(visitor); + } +} + +#[expect(rustc::default_hash_types, rustc::potential_query_instability)] +impl, S: GenericTypeVisitable> GenericTypeVisitable + for std::collections::HashSet +{ + fn generic_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.generic_visit_with(visitor)); + self.hasher().generic_visit_with(visitor); + } +} + +impl< + Visitor, + Key: GenericTypeVisitable, + Value: GenericTypeVisitable, + S: GenericTypeVisitable, +> GenericTypeVisitable for indexmap::IndexMap +{ + fn generic_visit_with(&self, visitor: &mut Visitor) { + self.iter().for_each(|it| it.generic_visit_with(visitor)); + self.hasher().generic_visit_with(visitor); + } +} + +impl, S: GenericTypeVisitable> GenericTypeVisitable + for indexmap::IndexSet +{ + fn generic_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.generic_visit_with(visitor)); + self.hasher().generic_visit_with(visitor); + } +} + +macro_rules! trivial_impls { + ( $($ty:ty),* $(,)? ) => { + $( + impl + GenericTypeVisitable for $ty + { + fn generic_visit_with(&self, _visitor: &mut V) {} + } + )* + }; +} + +trivial_impls!( + (), + rustc_ast_ir::Mutability, + bool, + i8, + i16, + i32, + i64, + i128, + isize, + u8, + u16, + u32, + u64, + u128, + usize, + crate::PredicatePolarity, + crate::BoundConstness, + crate::AliasRelationDirection, + crate::DebruijnIndex, + crate::solve::Certainty, + crate::UniverseIndex, + crate::BoundVar, + crate::InferTy, + crate::IntTy, + crate::UintTy, + crate::FloatTy, + crate::InferConst, + crate::RegionVid, + rustc_hash::FxBuildHasher, + crate::TypeFlags, + crate::solve::GoalSource, +); diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 8065db1e05dd..1b8a0c5ba3fd 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -44,6 +44,8 @@ mod const_kind; mod flags; mod fold; mod generic_arg; +#[cfg(not(feature = "nightly"))] +mod generic_visit; mod infer_ctxt; mod interner; mod opaque_ty; @@ -67,6 +69,8 @@ pub use const_kind::*; pub use flags::*; pub use fold::*; pub use generic_arg::*; +#[cfg(not(feature = "nightly"))] +pub use generic_visit::*; pub use infer_ctxt::*; pub use interner::*; pub use opaque_ty::*; @@ -75,6 +79,7 @@ pub use predicate::*; pub use predicate_kind::*; pub use region_kind::*; pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy}; +use rustc_type_ir_macros::GenericTypeVisitable; pub use ty_info::*; pub use ty_kind::*; pub use upcast::*; @@ -213,7 +218,7 @@ pub fn debug_bound_var( } } -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, GenericTypeVisitable)] #[cfg_attr(feature = "nightly", derive(Decodable, Encodable, HashStable_NoContext))] #[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum Variance { diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs index b6fb9f28930f..870e15af519d 100644 --- a/compiler/rustc_type_ir/src/opaque_ty.rs +++ b/compiler/rustc_type_ir/src/opaque_ty.rs @@ -1,13 +1,13 @@ use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::inherent::*; use crate::{self as ty, Interner}; #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/pattern.rs b/compiler/rustc_type_ir/src/pattern.rs index 1f8b7158cb11..d0febc739db4 100644 --- a/compiler/rustc_type_ir/src/pattern.rs +++ b/compiler/rustc_type_ir/src/pattern.rs @@ -1,12 +1,14 @@ use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::Interner; #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 3e32a7788546..c6b76f6a9ae6 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -6,7 +6,9 @@ use derive_where::derive_where; use rustc_macros::{ Decodable, Decodable_NoContext, Encodable, Encodable_NoContext, HashStable_NoContext, }; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::inherent::*; use crate::lift::Lift; @@ -17,7 +19,7 @@ use crate::{self as ty, Interner}; /// `A: 'region` #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)] #[derive_where(Copy; I: Interner, A: Copy)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -52,7 +54,7 @@ where /// Trait references also appear in object types like `Foo`, but in /// that case the `Self` parameter is absent from the generic parameters. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -129,7 +131,7 @@ impl ty::Binder> { } #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -274,7 +276,7 @@ impl fmt::Display for PredicatePolarity { } #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -325,7 +327,7 @@ impl ty::Binder> { /// The generic parameters don't include the erased `Self`, only trait /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -394,7 +396,7 @@ impl ty::Binder> { /// A `ProjectionPredicate` for an `ExistentialTraitRef`. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -552,7 +554,7 @@ impl From for AliasTermKind { /// * For an inherent projection, this would be `Ty::N<...>`. /// * For an opaque type, there is no explicit syntax. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -764,7 +766,7 @@ impl From> for AliasTerm { /// Form #2 eventually yields one of these `ProjectionPredicate` /// instances to normalize the LHS. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -827,7 +829,7 @@ impl fmt::Debug for ProjectionPredicate { /// Used by the new solver to normalize an alias. This always expects the `term` to /// be an unconstrained inference variable which is used as the output. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -864,7 +866,7 @@ impl fmt::Debug for NormalizesTo { } #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -910,7 +912,7 @@ impl ty::Binder> { /// whether the `a` type is the type that we should label as "expected" when /// presenting user diagnostics. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -925,7 +927,7 @@ impl Eq for SubtypePredicate {} /// Encodes that we have to coerce *from* the `a` type to the `b` type. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 785d41929cfc..445e85a888fc 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -3,14 +3,14 @@ use std::fmt; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::{self as ty, Interner}; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -58,7 +58,7 @@ pub enum ClauseKind { impl Eq for ClauseKind {} #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index 1e8585cf52ce..9acf9ff8557e 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -5,6 +5,7 @@ use derive_where::derive_where; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; +use rustc_type_ir_macros::GenericTypeVisitable; use self::RegionKind::*; use crate::{BoundVarIndexKind, Interner}; @@ -126,6 +127,7 @@ rustc_index::newtype_index! { /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] +#[derive(GenericTypeVisitable)] #[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))] pub enum RegionKind { /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`. diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs index 3af2f8dbaf27..20432687e5f6 100644 --- a/compiler/rustc_type_ir/src/solve/inspect.rs +++ b/compiler/rustc_type_ir/src/solve/inspect.rs @@ -18,7 +18,7 @@ //! [canonicalized]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html use derive_where::derive_where; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::solve::{CandidateSource, Certainty, Goal, GoalSource, QueryResult}; use crate::{Canonical, CanonicalVarValues, Interner}; @@ -31,7 +31,7 @@ use crate::{Canonical, CanonicalVarValues, Interner}; /// inference variables from a nested `InferCtxt`. #[derive_where(Clone, PartialEq, Hash, Debug; I: Interner, T)] #[derive_where(Copy; I: Interner, T: Copy)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct State { pub var_values: CanonicalVarValues, pub data: T, @@ -87,7 +87,7 @@ pub enum ProbeStep { /// the final result of the current goal - via [ProbeKind::Root] - we also /// store the [QueryResult]. #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub enum ProbeKind { /// The root inference context while proving a goal. Root { result: QueryResult }, diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index ede23d599832..72b7df22b30d 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -5,7 +5,9 @@ use std::hash::Hash; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::lang_items::SolverTraitLangItem; use crate::search_graph::PathKind; @@ -33,7 +35,7 @@ pub struct NoSolution; /// we're currently typechecking while the `predicate` is some trait bound. #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, P)] #[derive_where(Copy; I: Interner, P: Copy)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -95,7 +97,7 @@ pub enum GoalSource { #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, Goal)] #[derive_where(Copy; I: Interner, Goal: Copy)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -206,7 +208,7 @@ pub enum ParamEnvSource { } #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub enum AliasBoundKind { /// Alias bound from the self type of a projection SelfBounds, @@ -235,7 +237,7 @@ pub enum BuiltinImplSource { } #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct Response { pub certainty: Certainty, @@ -248,7 +250,7 @@ impl Eq for Response {} /// Additional constraints returned on success. #[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct ExternalConstraintsData { pub region_constraints: Vec>, @@ -267,7 +269,7 @@ impl ExternalConstraintsData { } #[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct NestedNormalizationGoals(pub Vec<(GoalSource, Goal)>); diff --git a/compiler/rustc_type_ir/src/ty_info.rs b/compiler/rustc_type_ir/src/ty_info.rs index a99956674507..53994b5dbf63 100644 --- a/compiler/rustc_type_ir/src/ty_info.rs +++ b/compiler/rustc_type_ir/src/ty_info.rs @@ -6,6 +6,7 @@ use std::ops::Deref; use rustc_data_structures::fingerprint::Fingerprint; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_type_ir_macros::GenericTypeVisitable; use crate::{DebruijnIndex, TypeFlags}; @@ -16,7 +17,7 @@ use crate::{DebruijnIndex, TypeFlags}; /// StableHash::ZERO for the hash, in which case the hash gets computed each time. /// This is useful if you have values that you intern but never (can?) use for stable /// hashing. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, GenericTypeVisitable)] pub struct WithCachedTypeInfo { pub internee: T, diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index bb80e2cf46d4..34bb3cd8a6c3 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -8,7 +8,9 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir::data_structures::{NoError, UnifyKey, UnifyValue}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use self::TyKind::*; pub use self::closure::*; @@ -20,6 +22,7 @@ use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy}; mod closure; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(GenericTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -56,6 +59,7 @@ impl AliasTyKind { /// converted to this representation using `::lower_ty`. #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")] #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] +#[derive(GenericTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -391,7 +395,7 @@ impl fmt::Debug for TyKind { /// * For an inherent projection, this would be `Ty::N<...>`. /// * For an opaque type, there is no explicit syntax. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -713,7 +717,7 @@ impl fmt::Debug for InferTy { feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct TypeAndMut { pub ty: I::Ty, pub mutbl: Mutability, @@ -726,7 +730,7 @@ impl Eq for TypeAndMut {} feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct FnSig { pub inputs_and_output: I::Tys, pub c_variadic: bool, @@ -839,7 +843,7 @@ impl fmt::Debug for FnSig { // impls in this crate for `Binder`. #[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct UnsafeBinderInner(ty::Binder); impl Eq for UnsafeBinderInner {} @@ -905,7 +909,7 @@ where feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct FnSigTys { pub inputs_and_output: I::Tys, } @@ -959,7 +963,7 @@ impl ty::Binder> { feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct FnHeader { pub c_variadic: bool, pub safety: I::Safety, @@ -973,7 +977,7 @@ impl Eq for FnHeader {} feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct CoroutineWitnessTypes { pub types: I::Tys, pub assumptions: I::RegionAssumptions, diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index 4d9fd6040d8b..e8f94c8e7cc9 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -1,7 +1,9 @@ use std::ops::ControlFlow; use derive_where::derive_where; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::data_structures::DelayedMap; use crate::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region}; @@ -102,7 +104,7 @@ use crate::{self as ty, Interner}; /// * `GR`: The "return type", which is the type of value returned upon /// completion of the coroutine. #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct ClosureArgs { /// Lifetime and type parameters from the enclosing function, /// concatenated with a tuple containing the types of the upvars. @@ -206,7 +208,7 @@ impl ClosureArgs { } #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct CoroutineClosureArgs { pub args: I::GenericArgs, } @@ -354,7 +356,7 @@ impl TypeVisitor for HasRegionsBoundAt { } #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct CoroutineClosureSignature { pub tupled_inputs_ty: I::Ty, pub resume_ty: I::Ty, @@ -549,7 +551,7 @@ impl TypeFolder for FoldEscapingRegions { } #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic)] pub struct GenSig { pub resume_ty: I::Ty, pub yield_ty: I::Ty, @@ -559,7 +561,7 @@ pub struct GenSig { impl Eq for GenSig {} /// Similar to `ClosureArgs`; see the above documentation for more. #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct CoroutineArgs { pub args: I::GenericArgs, } diff --git a/compiler/rustc_type_ir_macros/Cargo.toml b/compiler/rustc_type_ir_macros/Cargo.toml index 14bffa403a86..910eef5e21f4 100644 --- a/compiler/rustc_type_ir_macros/Cargo.toml +++ b/compiler/rustc_type_ir_macros/Cargo.toml @@ -6,6 +6,9 @@ edition = "2024" [lib] proc-macro = true +[features] +nightly = [] + [dependencies] # tidy-alphabetical-start proc-macro2 = "1" diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index 37617b789dba..8df10b6a9ecc 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -12,6 +12,10 @@ decl_derive!( decl_derive!( [Lift_Generic] => lift_derive ); +#[cfg(not(feature = "nightly"))] +decl_derive!( + [GenericTypeVisitable] => customizable_type_visitable_derive +); fn has_ignore_attr(attrs: &[Attribute], name: &'static str, meta: &'static str) -> bool { let mut ignored = false; @@ -211,3 +215,39 @@ fn lift(mut ty: syn::Type) -> syn::Type { ty } + +#[cfg(not(feature = "nightly"))] +fn customizable_type_visitable_derive( + mut s: synstructure::Structure<'_>, +) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + s.add_impl_generic(parse_quote!(__V)); + s.add_bounds(synstructure::AddBounds::Fields); + let body_visit = s.each(|bind| { + quote! { + ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(#bind, __visitor); + } + }); + s.bind_with(|_| synstructure::BindStyle::Move); + + s.bound_impl( + quote!(::rustc_type_ir::GenericTypeVisitable<__V>), + quote! { + fn generic_visit_with( + &self, + __visitor: &mut __V + ) { + match *self { #body_visit } + } + }, + ) +} + +#[cfg(feature = "nightly")] +#[proc_macro_derive(GenericTypeVisitable)] +pub fn customizable_type_visitable_derive(_: proc_macro::TokenStream) -> proc_macro::TokenStream { + proc_macro::TokenStream::new() +} From 07f77185269c135b06baf47c17576ebe3b5be864 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 16 Dec 2025 10:17:43 +0800 Subject: [PATCH 0856/3801] Fix expected type no strip deref Example --- ```rust fn main() { let r = &2; let _: fn() -> i32 = || *$0; } ``` **Before this PR** `ty: &'_ u32, name: x` ```rust fn main() { let r = &2; let _: fn() -> i32 = || **r; } ``` **After this PR** `ty: &'_ &'_ u32, name: x` ```rust fn main() { let r = &2; let _: fn() -> i32 = || *r; } ``` --- .../ide-completion/src/context/analysis.rs | 18 +++++++++++++++++- .../crates/ide-completion/src/context/tests.rs | 12 ++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index add637a16fdf..b65c68a2401e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -600,10 +600,26 @@ fn expected_type_and_name<'db>( Some(it) => it, None => return ty, }; - for _ in top_syn.ancestors().skip(1).map_while(ast::RefExpr::cast) { + let refs_level = top_syn + .ancestors() + .skip(1) + .map_while(Either::::cast) + .take_while(|it| match it { + Either::Left(_) => true, + Either::Right(prefix) => prefix.op_kind() == Some(ast::UnaryOp::Deref), + }) + .fold(0i32, |level, expr| match expr { + Either::Left(_) => level + 1, + Either::Right(_) => level - 1, + }); + for _ in 0..refs_level { cov_mark::hit!(expected_type_fn_param_ref); ty = ty.strip_reference(); } + for _ in refs_level..0 { + cov_mark::hit!(expected_type_fn_param_deref); + ty = ty.add_reference(hir::Mutability::Shared); + } ty } _ => ty, diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs index 41f0db3c5282..b929d36ce687 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs @@ -146,6 +146,18 @@ fn bar(x: &u32) {} ); } +#[test] +fn expected_type_fn_param_deref() { + cov_mark::check!(expected_type_fn_param_deref); + check_expected_type_and_name( + r#" +fn foo() { bar(*$0); } +fn bar(x: &u32) {} +"#, + expect!["ty: &'_ &'_ u32, name: x"], + ); +} + #[test] fn expected_type_struct_field_without_leading_char() { cov_mark::check!(expected_type_struct_field_without_leading_char); From 2a8e61f538ed530c8c491ff6b5c125ebf0e9e451 Mon Sep 17 00:00:00 2001 From: Ross Sullivan Date: Fri, 12 Dec 2025 15:16:59 +0900 Subject: [PATCH 0857/3801] Backport Cargo bug fixes for Rust 1.93 --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 2c283a9a5c59..083ac5135f96 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 2c283a9a5c5968eeb9a8f12313f04feb1ff8dfac +Subproject commit 083ac5135f967fd9dc906ab057a2315861c7a80d From ce4929b173957fc2d9dc9b67179d6ff5586c5cf7 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Tue, 16 Dec 2025 10:46:45 +0800 Subject: [PATCH 0858/3801] Fix add reference for `&mut ty` -> `&ty` Example --- ```rust fn foo(r: &mut i32) -> &i32 { $0 } ``` **Before this PR** `lc &r [type+local]` This is a compilation error ```rust fn foo(r: &mut i32) -> &i32 { &r } ``` **After this PR** `lc r &mut i32 [type+local]` ```rust fn foo(r: &mut i32) -> &i32 { r } ``` --- .../crates/ide-completion/src/render.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index bc5589a64550..f2312c64945e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -604,6 +604,14 @@ fn compute_type_match( return None; } + // &mut ty -> &ty + if completion_ty.is_mutable_reference() + && let Some(expected_type) = expected_type.remove_ref() + && let Some(completion_ty) = completion_ty.remove_ref() + { + return match_types(ctx, &expected_type, &completion_ty); + } + match_types(ctx, expected_type, completion_ty) } @@ -622,6 +630,7 @@ fn compute_ref_match( return None; } if let Some(expected_without_ref) = &expected_without_ref + && completion_without_ref.is_none() && completion_ty.autoderef(ctx.db).any(|ty| ty == *expected_without_ref) { cov_mark::hit!(suggest_ref); @@ -2049,6 +2058,17 @@ fn go(world: &WorldSnapshot) { go(w$0) } ); } + #[test] + fn prioritize_mutable_ref_as_immutable_ref_match() { + check_relevance( + r#"fn foo(r: &mut i32) -> &i32 { $0 }"#, + expect![[r#" + lc r &mut i32 [type+local] + fn foo(…) fn(&mut i32) -> &i32 [type] + "#]], + ); + } + #[test] fn too_many_arguments() { cov_mark::check!(too_many_arguments); From 63cdf9310e41d3ee38f546a75b2c8cd7d5f2b565 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Tue, 16 Dec 2025 03:59:09 +0000 Subject: [PATCH 0859/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to cec70080fd441d16e9fb08a0d1d1a04c72d1ed25. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 4bcbec1a9f48..71a84e2bda12 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -ce63e5d9ea20f15a70c6fdc4d4de7aee352fd965 +cec70080fd441d16e9fb08a0d1d1a04c72d1ed25 From 38ef5c1cdbd7861dbe26c256f232a1722967a065 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 16 Dec 2025 06:04:11 +0200 Subject: [PATCH 0860/3801] improve cg_gcc.md a little --- .../rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md index 7a1c5b9a98c0..9ed91550b262 100644 --- a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md +++ b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md @@ -79,10 +79,10 @@ if there are no local changes to the GCC sources and the given host target is av ## Providing your own GCC -There are cases where you will want to provide yourself the `libgccjit.so` file. +There are cases where you will want to provide your own `libgccjit.so` file. One such case is when you want to cross-compile `rustc` to another target since GCC is not a multi-target compiler. To support this use case, there is the bootstrap option `gcc.libgccjit-libs-dir`. -This option override `gcc.download-ci-gcc`, meaning `libgccjit.so` won't be downloaded or built locally by bootstrap. +This option overrides `gcc.download-ci-gcc`, meaning `libgccjit.so` won't be downloaded or built locally by bootstrap. The directory structure of this directory is `//libgccjit.so`, for instance: ``` From 4a00c4ff3aec7bdfe96caa85c9c3eeceee0378b5 Mon Sep 17 00:00:00 2001 From: Jesung Yang Date: Tue, 16 Dec 2025 04:50:26 +0000 Subject: [PATCH 0861/3801] internal: add special `ErasedFileAstId` used for bypassing downmapping Introduce `NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER`, which prevents `Span`s from being mapped down into macro expansions. This is a preparatory step for adding a new field to the `rust-project.json` format that can inject crate-level attributes. `Span`s for those attributes will be marked with `NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER`, indicating that they should not be mapped down into macro expansions. --- .../hir-def/src/macro_expansion_tests/mod.rs | 116 +++++++++++++----- .../crates/hir-expand/src/lib.rs | 12 +- .../rust-analyzer/crates/span/src/ast_id.rs | 9 ++ .../rust-analyzer/crates/span/src/lib.rs | 2 +- 4 files changed, 103 insertions(+), 36 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs index 78af976e1b13..59bd9474a959 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -19,7 +19,7 @@ use std::{any::TypeId, iter, ops::Range, sync}; use base_db::RootQueryDb; use expect_test::Expect; use hir_expand::{ - AstId, InFile, MacroCallId, MacroCallKind, MacroKind, + AstId, ExpansionInfo, InFile, MacroCallId, MacroCallKind, MacroKind, builtin::quote::quote, db::ExpandDatabase, proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind}, @@ -27,7 +27,10 @@ use hir_expand::{ }; use intern::{Symbol, sym}; use itertools::Itertools; -use span::{Edition, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext}; +use span::{ + Edition, NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, + SyntaxContext, +}; use stdx::{format_to, format_to_acc}; use syntax::{ AstNode, AstPtr, @@ -97,37 +100,6 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream }, )]; - fn resolve( - db: &dyn DefDatabase, - def_map: &DefMap, - ast_id: AstId, - ast_ptr: InFile>, - ) -> Option { - def_map.modules().find_map(|module| { - for decl in - module.1.scope.declarations().chain(module.1.scope.unnamed_consts().map(Into::into)) - { - let body = match decl { - ModuleDefId::FunctionId(it) => it.into(), - ModuleDefId::ConstId(it) => it.into(), - ModuleDefId::StaticId(it) => it.into(), - _ => continue, - }; - - let (body, sm) = db.body_with_source_map(body); - if let Some(it) = - body.blocks(db).find_map(|block| resolve(db, block.1, ast_id, ast_ptr)) - { - return Some(it); - } - if let Some((_, res)) = sm.macro_calls().find(|it| it.0 == ast_ptr) { - return Some(res); - } - } - module.1.scope.macro_invoc(ast_id) - }) - } - let db = TestDB::with_files_extra_proc_macros(ra_fixture, extra_proc_macros); let krate = db.fetch_test_crate(); let def_map = crate_def_map(&db, krate); @@ -144,7 +116,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream let ast_id = db.ast_id_map(source.file_id).ast_id(¯o_call_node); let ast_id = InFile::new(source.file_id, ast_id); let ptr = InFile::new(source.file_id, AstPtr::new(¯o_call_node)); - let macro_call_id = resolve(&db, def_map, ast_id, ptr) + let macro_call_id = resolve_macro_call_id(&db, def_map, ast_id, ptr) .unwrap_or_else(|| panic!("unable to find semantic macro call {macro_call_node}")); let expansion_result = db.parse_macro_expansion(macro_call_id); expansions.push((macro_call_node.clone(), expansion_result)); @@ -278,6 +250,38 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream expect.assert_eq(&expanded_text); } +fn resolve_macro_call_id( + db: &dyn DefDatabase, + def_map: &DefMap, + ast_id: AstId, + ast_ptr: InFile>, +) -> Option { + def_map.modules().find_map(|module| { + for decl in + module.1.scope.declarations().chain(module.1.scope.unnamed_consts().map(Into::into)) + { + let body = match decl { + ModuleDefId::FunctionId(it) => it.into(), + ModuleDefId::ConstId(it) => it.into(), + ModuleDefId::StaticId(it) => it.into(), + _ => continue, + }; + + let (body, sm) = db.body_with_source_map(body); + if let Some(it) = body + .blocks(db) + .find_map(|block| resolve_macro_call_id(db, block.1, ast_id, ast_ptr)) + { + return Some(it); + } + if let Some((_, res)) = sm.macro_calls().find(|it| it.0 == ast_ptr) { + return Some(res); + } + } + module.1.scope.macro_invoc(ast_id) + }) +} + fn reindent(indent: IndentLevel, pp: String) -> String { if !pp.contains('\n') { return pp; @@ -430,3 +434,47 @@ fn regression_20171() { Edition::CURRENT }); } + +#[test] +fn no_downmap() { + let fixture = r#" +macro_rules! m { + ($func_name:ident) => { + fn $func_name() { todo!() } + }; +} +m!(f); +m!(g); + "#; + + let (db, file_id) = TestDB::with_single_file(fixture); + let krate = file_id.krate(&db); + let def_map = crate_def_map(&db, krate); + let source = def_map[def_map.root].definition_source(&db); + let source_file = match source.value { + ModuleSource::SourceFile(it) => it, + ModuleSource::Module(_) | ModuleSource::BlockExpr(_) => panic!(), + }; + let no_downmap_spans: Vec<_> = source_file + .syntax() + .descendants() + .map(|node| { + let mut span = db.real_span_map(file_id).span_for_range(node.text_range()); + span.anchor.ast_id = NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER; + span + }) + .collect(); + + for macro_call_node in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) { + let ast_id = db.ast_id_map(source.file_id).ast_id(¯o_call_node); + let ast_id = InFile::new(source.file_id, ast_id); + let ptr = InFile::new(source.file_id, AstPtr::new(¯o_call_node)); + let macro_call_id = resolve_macro_call_id(&db, def_map, ast_id, ptr) + .unwrap_or_else(|| panic!("unable to find semantic macro call {macro_call_node}")); + let expansion_info = ExpansionInfo::new(&db, macro_call_id); + for &span in no_downmap_spans.iter() { + assert!(expansion_info.map_range_down(span).is_none()); + assert!(expansion_info.map_range_down_exact(span).is_none()); + } + } +} diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index c92e41f5070c..047996c97853 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -37,7 +37,9 @@ use std::{hash::Hash, ops}; use base_db::Crate; use either::Either; -use span::{Edition, ErasedFileAstId, FileAstId, Span, SyntaxContext}; +use span::{ + Edition, ErasedFileAstId, FileAstId, NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER, Span, SyntaxContext, +}; use syntax::{ SyntaxNode, SyntaxToken, TextRange, TextSize, ast::{self, AstNode}, @@ -854,6 +856,10 @@ impl ExpansionInfo { &self, span: Span, ) -> Option + '_>> { + if span.anchor.ast_id == NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER { + return None; + } + let tokens = self.exp_map.ranges_with_span_exact(span).flat_map(move |(range, ctx)| { self.expanded.value.covering_element(range).into_token().zip(Some(ctx)) }); @@ -869,6 +875,10 @@ impl ExpansionInfo { &self, span: Span, ) -> Option + '_>> { + if span.anchor.ast_id == NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER { + return None; + } + let tokens = self.exp_map.ranges_with_span(span).flat_map(move |(range, ctx)| { self.expanded.value.covering_element(range).into_token().zip(Some(ctx)) }); diff --git a/src/tools/rust-analyzer/crates/span/src/ast_id.rs b/src/tools/rust-analyzer/crates/span/src/ast_id.rs index bd49e08b10fa..a25189261311 100644 --- a/src/tools/rust-analyzer/crates/span/src/ast_id.rs +++ b/src/tools/rust-analyzer/crates/span/src/ast_id.rs @@ -48,6 +48,11 @@ pub const ROOT_ERASED_FILE_AST_ID: ErasedFileAstId = pub const FIXUP_ERASED_FILE_AST_ID_MARKER: ErasedFileAstId = ErasedFileAstId(pack_hash_index_and_kind(0, 0, ErasedFileAstIdKind::Fixup as u32)); +/// [`ErasedFileAstId`] used as the span for syntax nodes that should not be mapped down to +/// macro expansion. Any `Span` containing this file id is to be considered fake. +pub const NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER: ErasedFileAstId = + ErasedFileAstId(pack_hash_index_and_kind(0, 0, ErasedFileAstIdKind::NoDownmap as u32)); + /// This is a type erased FileAstId. #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct ErasedFileAstId(u32); @@ -95,6 +100,7 @@ impl fmt::Debug for ErasedFileAstId { BlockExpr, AsmExpr, Fixup, + NoDownmap, ); if f.alternate() { write!(f, "{kind}[{:04X}, {}]", self.hash_value(), self.index()) @@ -150,6 +156,9 @@ enum ErasedFileAstIdKind { // because incrementality is not a problem, they will always be the only item in the macro file, // and memory usage also not because they're rare. AsmExpr, + /// Represents a fake [`ErasedFileAstId`] that should not be mapped down to macro expansion + /// result. + NoDownmap, /// Keep this last. Root, } diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs index c44b0198b72c..1a8aaeb71517 100644 --- a/src/tools/rust-analyzer/crates/span/src/lib.rs +++ b/src/tools/rust-analyzer/crates/span/src/lib.rs @@ -14,7 +14,7 @@ mod map; pub use self::{ ast_id::{ AstIdMap, AstIdNode, ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, FileAstId, - ROOT_ERASED_FILE_AST_ID, + NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER, ROOT_ERASED_FILE_AST_ID, }, hygiene::{SyntaxContext, Transparency}, map::{RealSpanMap, SpanMap}, From 8f105cb330791dfdd9982989a8bc7a1fca437a77 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 16 Dec 2025 07:50:42 +0200 Subject: [PATCH 0862/3801] Fix an assert that didn't check what it should --- src/tools/rust-analyzer/crates/span/src/ast_id.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/span/src/ast_id.rs b/src/tools/rust-analyzer/crates/span/src/ast_id.rs index bd49e08b10fa..2e93925bd566 100644 --- a/src/tools/rust-analyzer/crates/span/src/ast_id.rs +++ b/src/tools/rust-analyzer/crates/span/src/ast_id.rs @@ -158,7 +158,7 @@ enum ErasedFileAstIdKind { const HASH_BITS: u32 = 16; const INDEX_BITS: u32 = 11; const KIND_BITS: u32 = 5; -const _: () = assert!(ErasedFileAstIdKind::Fixup as u32 <= ((1 << KIND_BITS) - 1)); +const _: () = assert!(ErasedFileAstIdKind::Root as u32 <= ((1 << KIND_BITS) - 1)); const _: () = assert!(HASH_BITS + INDEX_BITS + KIND_BITS == u32::BITS); #[inline] From 8d37589f37cf435d66d4fa2b6aed3ac006063a9e Mon Sep 17 00:00:00 2001 From: Laine Taffin Altman Date: Mon, 15 Dec 2025 22:08:00 -0800 Subject: [PATCH 0863/3801] std_detect: AArch64 Darwin: expose SME F16F16 and B16B16 features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This synchronizes the list with the current state of `sysctl` on macOS “Tahoe” 26.2. r? @Amanieu --- library/std_detect/src/detect/os/darwin/aarch64.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std_detect/src/detect/os/darwin/aarch64.rs b/library/std_detect/src/detect/os/darwin/aarch64.rs index 8c9fd9647b8a..a23d65a23d81 100644 --- a/library/std_detect/src/detect/os/darwin/aarch64.rs +++ b/library/std_detect/src/detect/os/darwin/aarch64.rs @@ -76,6 +76,8 @@ pub(crate) fn detect_features() -> cache::Initializer { let sme = _sysctlbyname(c"hw.optional.arm.FEAT_SME"); let sme2 = _sysctlbyname(c"hw.optional.arm.FEAT_SME2"); let sme2p1 = _sysctlbyname(c"hw.optional.arm.FEAT_SME2p1"); + let sme_b16b16 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_B16B16"); + let sme_f16f16 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_F16F16"); let sme_f64f64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_F64F64"); let sme_i16i64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_I16I64"); let ssbs = _sysctlbyname(c"hw.optional.arm.FEAT_SSBS"); @@ -153,6 +155,8 @@ pub(crate) fn detect_features() -> cache::Initializer { enable_feature(Feature::sme, sme); enable_feature(Feature::sme2, sme2); enable_feature(Feature::sme2p1, sme2p1); + enable_feature(Feature::sme_b16b16, sme_b16b16); + enable_feature(Feature::sme_f16f16, sme_f16f16); enable_feature(Feature::sme_f64f64, sme_f64f64); enable_feature(Feature::sme_i16i64, sme_i16i64); enable_feature(Feature::ssbs, ssbs); From fc16679419b9f17cbfde666aa26fa728781fb435 Mon Sep 17 00:00:00 2001 From: usamoi Date: Sun, 14 Dec 2025 17:59:55 +0800 Subject: [PATCH 0864/3801] add avx512 pshufb --- src/tools/miri/src/shims/x86/avx2.rs | 25 +---------- src/tools/miri/src/shims/x86/avx512.rs | 9 +++- src/tools/miri/src/shims/x86/mod.rs | 45 +++++++++++++++++++ src/tools/miri/src/shims/x86/ssse3.rs | 24 +--------- .../pass/shims/x86/intrinsics-x86-avx512.rs | 24 ++++++++++ 5 files changed, 81 insertions(+), 46 deletions(-) diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 8fe225c494d5..b089a0249bd7 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -6,7 +6,7 @@ use rustc_target::callconv::FnAbi; use super::{ ShiftOp, horizontal_bin_op, mpsadbw, packssdw, packsswb, packusdw, packuswb, permute, pmaddbw, - pmulhrsw, psadbw, psign, shift_simd_by_scalar, + pmulhrsw, psadbw, pshufb, psign, shift_simd_by_scalar, }; use crate::*; @@ -189,28 +189,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [left, right] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - for i in 0..dest_len { - let right = this.read_scalar(&this.project_index(&right, i)?)?.to_u8()?; - let dest = this.project_index(&dest, i)?; - - let res = if right & 0x80 == 0 { - // Shuffle each 128-bit (16-byte) block independently. - let j = u64::from(right % 16).strict_add(i & !15); - this.read_scalar(&this.project_index(&left, j)?)? - } else { - // If the highest bit in `right` is 1, write zero. - Scalar::from_u8(0) - }; - - this.write_scalar(res, &dest)?; - } + pshufb(this, left, right, dest)?; } // Used to implement the _mm256_sign_epi{8,16,32} functions. // Negates elements from `left` when the corresponding element in diff --git a/src/tools/miri/src/shims/x86/avx512.rs b/src/tools/miri/src/shims/x86/avx512.rs index 9b43aad96e5c..a886f5622ced 100644 --- a/src/tools/miri/src/shims/x86/avx512.rs +++ b/src/tools/miri/src/shims/x86/avx512.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use super::{permute, pmaddbw, psadbw}; +use super::{permute, pmaddbw, psadbw, pshufb}; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -102,6 +102,13 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { permute(this, left, right, dest)?; } + // Used to implement the _mm512_shuffle_epi8 intrinsic. + "pshuf.b.512" => { + let [left, right] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + + pshufb(this, left, right, dest)?; + } _ => return interp_ok(EmulateItemResult::NotSupported), } interp_ok(EmulateItemResult::NeedsReturn) diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 40dcd7ac1c2d..a5164cc87ab4 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -1155,6 +1155,51 @@ fn pclmulqdq<'tcx>( interp_ok(()) } +/// Shuffles bytes from `left` using `right` as pattern. Each 16-byte block is shuffled independently. +/// +/// `left` and `right` are both vectors of type `len` x i8. +/// +/// If the highest bit of a byte in `right` is not set, the corresponding byte in `dest` is taken +/// from the current 16-byte block of `left` at the position indicated by the lowest 4 bits of this +/// byte in `right`. If the highest bit of a byte in `right` is set, the corresponding byte in +/// `dest` is set to `0`. +/// +/// +/// +/// +fn pshufb<'tcx>( + ecx: &mut crate::MiriInterpCx<'tcx>, + left: &OpTy<'tcx>, + right: &OpTy<'tcx>, + dest: &MPlaceTy<'tcx>, +) -> InterpResult<'tcx, ()> { + let (left, left_len) = ecx.project_to_simd(left)?; + let (right, right_len) = ecx.project_to_simd(right)?; + let (dest, dest_len) = ecx.project_to_simd(dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + + for i in 0..dest_len { + let right = ecx.read_scalar(&ecx.project_index(&right, i)?)?.to_u8()?; + let dest = ecx.project_index(&dest, i)?; + + let res = if right & 0x80 == 0 { + // Shuffle each 128-bit (16-byte) block independently. + let block_offset = i & !15; // round down to previous multiple of 16 + let j = block_offset.strict_add((right % 16).into()); + ecx.read_scalar(&ecx.project_index(&left, j)?)? + } else { + // If the highest bit in `right` is 1, write zero. + Scalar::from_u8(0) + }; + + ecx.write_scalar(res, &dest)?; + } + + interp_ok(()) +} + /// Packs two N-bit integer vectors to a single N/2-bit integers. /// /// The conversion from N-bit to N/2-bit should be provided by `f`. diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index 56fc63ce1473..b01a8795b4d1 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -4,7 +4,7 @@ use rustc_middle::ty::Ty; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; -use super::{horizontal_bin_op, pmaddbw, pmulhrsw, psign}; +use super::{horizontal_bin_op, pmaddbw, pmulhrsw, pshufb, psign}; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -29,27 +29,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let [left, right] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; - let (left, left_len) = this.project_to_simd(left)?; - let (right, right_len) = this.project_to_simd(right)?; - let (dest, dest_len) = this.project_to_simd(dest)?; - - assert_eq!(dest_len, left_len); - assert_eq!(dest_len, right_len); - - for i in 0..dest_len { - let right = this.read_scalar(&this.project_index(&right, i)?)?.to_u8()?; - let dest = this.project_index(&dest, i)?; - - let res = if right & 0x80 == 0 { - let j = right % 16; // index wraps around - this.read_scalar(&this.project_index(&left, j.into())?)? - } else { - // If the highest bit in `right` is 1, write zero. - Scalar::from_u8(0) - }; - - this.write_scalar(res, &dest)?; - } + pshufb(this, left, right, dest)?; } // Used to implement the _mm_h{adds,subs}_epi16 functions. // Horizontally add / subtract with saturation adjacent 16-bit diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs index e778567b483f..f95429d59ebe 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs @@ -143,6 +143,30 @@ unsafe fn test_avx512() { assert_eq_m512i(r, e); } test_mm512_permutexvar_epi32(); + + #[target_feature(enable = "avx512bw")] + unsafe fn test_mm512_shuffle_epi8() { + #[rustfmt::skip] + let a = _mm512_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63); + #[rustfmt::skip] + let b = _mm512_set_epi8(-1, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -1, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -1, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -1, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + let r = _mm512_shuffle_epi8(a, b); + // `_mm512_set_epi8` sets the bytes in inverse order (?!?), so the indices in `b` seem to + // index from the *back* of the corresponding 16-byte block in `a`. + #[rustfmt::skip] + let e = _mm512_set_epi8(0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 0, 16, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 0, 32, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 0, 48, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62); + assert_eq_m512i(r, e); + } + test_mm512_shuffle_epi8(); } // Some of the constants in the tests below are just bit patterns. They should not From fca8611a3e79a22a7339a75eba0cb66d627afc6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 16 Dec 2025 09:42:42 +0100 Subject: [PATCH 0865/3801] Mirror GCC --- src/ci/docker/scripts/build-gcc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/scripts/build-gcc.sh b/src/ci/docker/scripts/build-gcc.sh index 11db5aa811ce..ab4cae21e025 100755 --- a/src/ci/docker/scripts/build-gcc.sh +++ b/src/ci/docker/scripts/build-gcc.sh @@ -7,7 +7,7 @@ source shared.sh # This version is specified in the Dockerfile GCC=$GCC_VERSION -curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.xz | xzcat | tar xf - +curl https://ci-mirrors.rust-lang.org/rustc/gcc/gcc-$GCC.tar.xz | xzcat | tar xf - cd gcc-$GCC # FIXME(#49246): Remove the `sed` below. From d5bf1a4c9a9205d820faedff789f4e55ebf18857 Mon Sep 17 00:00:00 2001 From: Ivar Flakstad <69173633+ivarflakstad@users.noreply.github.com> Date: Sun, 13 Jul 2025 15:32:28 +0200 Subject: [PATCH 0866/3801] Introduce `vtable_for` intrinsic and use it to implement `try_as_dyn` and `try_as_dyn_mut` for fallible coercion from `&T` / `&mut T` to `&dyn Trait`. --- .../src/interpret/intrinsics.rs | 50 +++++++- .../rustc_hir_analysis/src/check/intrinsic.rs | 15 +++ compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_type_ir/src/predicate.rs | 7 ++ library/core/src/any.rs | 108 +++++++++++++++++- library/core/src/intrinsics/mod.rs | 16 +++ library/coretests/tests/intrinsics.rs | 19 ++- tests/ui/any/try_as_dyn.rs | 29 +++++ tests/ui/any/try_as_dyn_mut.rs | 20 ++++ tests/ui/any/try_as_dyn_soundness_test1.rs | 22 ++++ tests/ui/any/try_as_dyn_soundness_test2.rs | 16 +++ 11 files changed, 299 insertions(+), 4 deletions(-) create mode 100644 tests/ui/any/try_as_dyn.rs create mode 100644 tests/ui/any/try_as_dyn_mut.rs create mode 100644 tests/ui/any/try_as_dyn_soundness_test1.rs create mode 100644 tests/ui/any/try_as_dyn_soundness_test2.rs diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index a7a3bbebed5f..44c817b33184 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -6,14 +6,17 @@ mod simd; use std::assert_matches::assert_matches; -use rustc_abi::{FieldIdx, HasDataLayout, Size, VariantIdx}; +use rustc_abi::{FIRST_VARIANT, FieldIdx, HasDataLayout, Size, VariantIdx}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; +use rustc_hir::def_id::CRATE_DEF_ID; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint}; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{FloatTy, Ty, TyCtxt}; +use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_middle::{bug, span_bug, ty}; use rustc_span::{Symbol, sym}; +use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; use tracing::trace; use super::memory::MemoryKind; @@ -219,6 +222,49 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(Scalar::from_target_usize(offset, self), dest)?; } + sym::vtable_for => { + let tp_ty = instance.args.type_at(0); + let result_ty = instance.args.type_at(1); + + ensure_monomorphic_enough(tcx, tp_ty)?; + ensure_monomorphic_enough(tcx, result_ty)?; + let ty::Dynamic(preds, _) = result_ty.kind() else { + span_bug!( + self.find_closest_untracked_caller_location(), + "Invalid type provided to vtable_for::. U must be dyn Trait, got {result_ty}." + ); + }; + + let (infcx, param_env) = + self.tcx.infer_ctxt().build_with_typing_env(self.typing_env); + + let ocx = ObligationCtxt::new(&infcx); + ocx.register_obligations(preds.iter().map(|pred: PolyExistentialPredicate<'_>| { + let pred = pred.with_self_ty(tcx, tp_ty); + // Lifetimes can only be 'static because of the bound on T + let pred = pred.fold_with(&mut ty::BottomUpFolder { + tcx, + ty_op: |ty| ty, + lt_op: |lt| { + if lt == tcx.lifetimes.re_erased { tcx.lifetimes.re_static } else { lt } + }, + ct_op: |ct| ct, + }); + Obligation::new(tcx, ObligationCause::dummy(), param_env, pred) + })); + let type_impls_trait = ocx.evaluate_obligations_error_on_ambiguity().is_empty(); + // Since `assumed_wf_tys=[]` the choice of LocalDefId is irrelevant, so using the "default" + let regions_are_valid = ocx.resolve_regions(CRATE_DEF_ID, param_env, []).is_empty(); + + if regions_are_valid && type_impls_trait { + let vtable_ptr = self.get_vtable_ptr(tp_ty, preds)?; + // Writing a non-null pointer into an `Option` will automatically make it `Some`. + self.write_pointer(vtable_ptr, dest)?; + } else { + // Write `None` + self.write_discriminant(FIRST_VARIANT, dest)?; + } + } sym::variant_count => { let tp_ty = instance.args.type_at(0); let ty = match tp_ty.kind() { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 676c9a980aff..4e8333f678b6 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -215,6 +215,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::type_name | sym::ub_checks | sym::variant_count + | sym::vtable_for | sym::wrapping_add | sym::wrapping_mul | sym::wrapping_sub @@ -643,6 +644,20 @@ pub(crate) fn check_intrinsic_type( (0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize) } + sym::vtable_for => { + let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, span); + let dyn_metadata_adt_ref = tcx.adt_def(dyn_metadata); + let dyn_metadata_args = tcx.mk_args(&[param(1).into()]); + let dyn_ty = Ty::new_adt(tcx, dyn_metadata_adt_ref, dyn_metadata_args); + + let option_did = tcx.require_lang_item(LangItem::Option, span); + let option_adt_ref = tcx.adt_def(option_did); + let option_args = tcx.mk_args(&[dyn_ty.into()]); + let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args); + + (2, 0, vec![], ret_ty) + } + // This type check is not particularly useful, but the `where` bounds // on the definition in `core` do the heavy lifting for checking it. sym::aggregate_raw_ptr => (3, 0, vec![param(1), param(2)], param(0)), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8e464b55d6c2..4700d945795a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2473,6 +2473,7 @@ symbols! { vsreg, vsx, vtable_align, + vtable_for, vtable_size, warn, wasip2, diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 3e32a7788546..bfe906515779 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -291,6 +291,13 @@ pub enum ExistentialPredicate { impl Eq for ExistentialPredicate {} impl ty::Binder> { + pub fn def_id(&self) -> I::DefId { + match self.skip_binder() { + ExistentialPredicate::Trait(tr) => tr.def_id.into(), + ExistentialPredicate::Projection(p) => p.def_id.into(), + ExistentialPredicate::AutoTrait(did) => did.into(), + } + } /// Given an existential predicate like `?Self: PartialEq` (e.g., derived from `dyn PartialEq`), /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq`, in our example). diff --git a/library/core/src/any.rs b/library/core/src/any.rs index ff55793340bd..42f332f7d8ba 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -86,7 +86,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::{fmt, hash, intrinsics}; +use crate::{fmt, hash, intrinsics, ptr}; /////////////////////////////////////////////////////////////////////////////// // Any trait @@ -906,3 +906,109 @@ pub const fn type_name() -> &'static str { pub const fn type_name_of_val(_val: &T) -> &'static str { type_name::() } + +/// Returns `Some(&U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`. +/// +/// # Compile-time failures +/// Determining whether `T` can be coerced to the trait object type `U` requires compiler trait resolution. +/// In some cases, that resolution can exceed the recursion limit, +/// and compilation will fail instead of this function returning `None`. +/// # Examples +/// +/// ```rust +/// #![feature(try_as_dyn)] +/// +/// use core::any::try_as_dyn; +/// +/// trait Animal { +/// fn speak(&self) -> &'static str; +/// } +/// +/// struct Dog; +/// impl Animal for Dog { +/// fn speak(&self) -> &'static str { "woof" } +/// } +/// +/// struct Rock; // does not implement Animal +/// +/// let dog = Dog; +/// let rock = Rock; +/// +/// let as_animal: Option<&dyn Animal> = try_as_dyn::(&dog); +/// assert_eq!(as_animal.unwrap().speak(), "woof"); +/// +/// let not_an_animal: Option<&dyn Animal> = try_as_dyn::(&rock); +/// assert!(not_an_animal.is_none()); +/// ``` +#[must_use] +#[unstable(feature = "try_as_dyn", issue = "144361")] +pub const fn try_as_dyn< + T: Any + 'static, + U: ptr::Pointee> + ?Sized + 'static, +>( + t: &T, +) -> Option<&U> { + let vtable: Option> = const { intrinsics::vtable_for::() }; + match vtable { + Some(dyn_metadata) => { + let pointer = ptr::from_raw_parts(t, dyn_metadata); + // SAFETY: `t` is a reference to a type, so we know it is valid. + // `dyn_metadata` is a vtable for T, implementing the trait of `U`. + Some(unsafe { &*pointer }) + } + None => None, + } +} + +/// Returns `Some(&mut U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`. +/// +/// # Compile-time failures +/// Determining whether `T` can be coerced to the trait object type `U` requires compiler trait resolution. +/// In some cases, that resolution can exceed the recursion limit, +/// and compilation will fail instead of this function returning `None`. +/// # Examples +/// +/// ```rust +/// #![feature(try_as_dyn)] +/// +/// use core::any::try_as_dyn_mut; +/// +/// trait Animal { +/// fn speak(&self) -> &'static str; +/// } +/// +/// struct Dog; +/// impl Animal for Dog { +/// fn speak(&self) -> &'static str { "woof" } +/// } +/// +/// struct Rock; // does not implement Animal +/// +/// let mut dog = Dog; +/// let mut rock = Rock; +/// +/// let as_animal: Option<&mut dyn Animal> = try_as_dyn_mut::(&mut dog); +/// assert_eq!(as_animal.unwrap().speak(), "woof"); +/// +/// let not_an_animal: Option<&mut dyn Animal> = try_as_dyn_mut::(&mut rock); +/// assert!(not_an_animal.is_none()); +/// ``` +#[must_use] +#[unstable(feature = "try_as_dyn", issue = "144361")] +pub const fn try_as_dyn_mut< + T: Any + 'static, + U: ptr::Pointee> + ?Sized + 'static, +>( + t: &mut T, +) -> Option<&mut U> { + let vtable: Option> = const { intrinsics::vtable_for::() }; + match vtable { + Some(dyn_metadata) => { + let pointer = ptr::from_raw_parts_mut(t, dyn_metadata); + // SAFETY: `t` is a reference to a type, so we know it is valid. + // `dyn_metadata` is a vtable for T, implementing the trait of `U`. + Some(unsafe { &mut *pointer }) + } + None => None, + } +} diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 722e16ab0fa4..2179b451c375 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2754,6 +2754,22 @@ pub unsafe fn vtable_size(ptr: *const ()) -> usize; #[rustc_intrinsic] pub unsafe fn vtable_align(ptr: *const ()) -> usize; +/// The intrinsic returns the `U` vtable for `T` if `T` can be coerced to the trait object type `U`. +/// +/// # Compile-time failures +/// Determining whether `T` can be coerced to the trait object type `U` requires trait resolution by the compiler. +/// In some cases, that resolution can exceed the recursion limit, +/// and compilation will fail instead of this function returning `None`. +/// +/// # Safety +/// +/// `ptr` must point to a vtable. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_intrinsic] +pub const fn vtable_for> + ?Sized>() +-> Option>; + /// The size of a type in bytes. /// /// Note that, unlike most intrinsics, this is safe to call; diff --git a/library/coretests/tests/intrinsics.rs b/library/coretests/tests/intrinsics.rs index 744a6a0d2dd8..c6d841b8383a 100644 --- a/library/coretests/tests/intrinsics.rs +++ b/library/coretests/tests/intrinsics.rs @@ -1,5 +1,8 @@ use core::any::TypeId; -use core::intrinsics::assume; +use core::intrinsics::{assume, vtable_for}; +use std::fmt::Debug; +use std::option::Option; +use std::ptr::DynMetadata; #[test] fn test_typeid_sized_types() { @@ -193,3 +196,17 @@ fn carrying_mul_add_fallback_i128() { (u128::MAX - 1, -(i128::MIN / 2)), ); } + +#[test] +fn test_vtable_for() { + #[derive(Debug)] + struct A {} + + struct B {} + + const A_VTABLE: Option> = vtable_for::(); + assert!(A_VTABLE.is_some()); + + const B_VTABLE: Option> = vtable_for::(); + assert!(B_VTABLE.is_none()); +} diff --git a/tests/ui/any/try_as_dyn.rs b/tests/ui/any/try_as_dyn.rs new file mode 100644 index 000000000000..ee220f797ced --- /dev/null +++ b/tests/ui/any/try_as_dyn.rs @@ -0,0 +1,29 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::fmt::Debug; + +// Look ma, no `T: Debug` +fn debug_format_with_try_as_dyn(t: &T) -> String { + match std::any::try_as_dyn::<_, dyn Debug>(t) { + Some(d) => format!("{d:?}"), + None => "default".to_string() + } +} + +// Test that downcasting to a dyn trait works as expected +fn main() { + #[allow(dead_code)] + #[derive(Debug)] + struct A { + index: usize + } + let a = A { index: 42 }; + let result = debug_format_with_try_as_dyn(&a); + assert_eq!("A { index: 42 }", result); + + struct B {} + let b = B {}; + let result = debug_format_with_try_as_dyn(&b); + assert_eq!("default", result); +} diff --git a/tests/ui/any/try_as_dyn_mut.rs b/tests/ui/any/try_as_dyn_mut.rs new file mode 100644 index 000000000000..ff7baa32ea87 --- /dev/null +++ b/tests/ui/any/try_as_dyn_mut.rs @@ -0,0 +1,20 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::fmt::{Error, Write}; + +// Look ma, no `T: Write` +fn try_as_dyn_mut_write(t: &mut T, s: &str) -> Result<(), Error> { + match std::any::try_as_dyn_mut::<_, dyn Write>(t) { + Some(w) => w.write_str(s), + None => Ok(()) + } +} + +// Test that downcasting to a mut dyn trait works as expected +fn main() { + let mut buf = "Hello".to_string(); + + try_as_dyn_mut_write(&mut buf, " world!").unwrap(); + assert_eq!(buf, "Hello world!"); +} diff --git a/tests/ui/any/try_as_dyn_soundness_test1.rs b/tests/ui/any/try_as_dyn_soundness_test1.rs new file mode 100644 index 000000000000..0772e9a2d77e --- /dev/null +++ b/tests/ui/any/try_as_dyn_soundness_test1.rs @@ -0,0 +1,22 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::any::try_as_dyn; + +trait Trait { + +} + +impl Trait for for<'a> fn(&'a Box) { + +} + +fn store(_: &'static Box) { + +} + +fn main() { + let fn_ptr: fn(&'static Box) = store; + let dt = try_as_dyn::<_, dyn Trait>(&fn_ptr); + assert!(dt.is_none()); +} diff --git a/tests/ui/any/try_as_dyn_soundness_test2.rs b/tests/ui/any/try_as_dyn_soundness_test2.rs new file mode 100644 index 000000000000..c16b50d0261e --- /dev/null +++ b/tests/ui/any/try_as_dyn_soundness_test2.rs @@ -0,0 +1,16 @@ +//@ run-pass +#![feature(try_as_dyn)] +use std::any::try_as_dyn; + +trait Trait { + +} + +impl Trait fn(&'a Box)> for () { + +} + +fn main() { + let dt = try_as_dyn::<_, dyn Trait)>>(&()); + assert!(dt.is_none()); +} From 78b06057ef61a8685e570997cb165f7d95a22c4c Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 8 Jul 2025 08:29:46 +0000 Subject: [PATCH 0867/3801] attr: parse `rustc_scalable_vector(N)` Extend parsing of `ReprOptions` with `rustc_scalable_vector(N)` which optionally accepts a single literal integral value - the base multiple of lanes that are in a scalable vector. Can only be applied to structs. Co-authored-by: Jamie Cunliffe --- compiler/rustc_abi/src/lib.rs | 26 +- compiler/rustc_attr_parsing/messages.ftl | 3 + .../src/attributes/rustc_internal.rs | 27 ++ compiler/rustc_attr_parsing/src/context.rs | 4 +- .../src/session_diagnostics.rs | 9 + compiler/rustc_feature/src/builtin_attrs.rs | 4 + .../rustc_hir/src/attrs/data_structures.rs | 8 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_hir/src/attrs/pretty_printing.rs | 10 + compiler/rustc_middle/src/ty/mod.rs | 24 +- compiler/rustc_middle/src/ty/sty.rs | 8 + compiler/rustc_passes/src/check_attr.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + tests/ui/scalable-vectors/invalid.rs | 162 +++++++++ tests/ui/scalable-vectors/invalid.stderr | 333 ++++++++++++++++++ tests/ui/thir-print/thir-tree-match.stdout | 8 +- 16 files changed, 620 insertions(+), 9 deletions(-) create mode 100644 tests/ui/scalable-vectors/invalid.rs create mode 100644 tests/ui/scalable-vectors/invalid.stderr diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index cd85efb2753a..bdd7d372c3c8 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -96,9 +96,11 @@ bitflags! { /// If true, the type is always passed indirectly by non-Rustic ABIs. /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. const PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS = 1 << 5; - /// Any of these flags being set prevent field reordering optimisation. - const FIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits() + const IS_SCALABLE = 1 << 6; + // Any of these flags being set prevent field reordering optimisation. + const FIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits() + | ReprFlags::IS_SCALABLE.bits() | ReprFlags::IS_LINEAR.bits(); const ABI_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits(); } @@ -135,6 +137,19 @@ impl IntegerType { } } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[cfg_attr( + feature = "nightly", + derive(Encodable_NoContext, Decodable_NoContext, HashStable_Generic) +)] +pub enum ScalableElt { + /// `N` in `rustc_scalable_vector(N)` - the element count of the scalable vector + ElementCount(u16), + /// `rustc_scalable_vector` w/out `N`, used for tuple types of scalable vectors that only + /// contain other scalable vectors + Container, +} + /// Represents the repr options provided by the user. #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)] #[cfg_attr( @@ -146,6 +161,8 @@ pub struct ReprOptions { pub align: Option, pub pack: Option, pub flags: ReprFlags, + /// `#[rustc_scalable_vector]` + pub scalable: Option, /// The seed to be used for randomizing a type's layout /// /// Note: This could technically be a `u128` which would @@ -162,6 +179,11 @@ impl ReprOptions { self.flags.contains(ReprFlags::IS_SIMD) } + #[inline] + pub fn scalable(&self) -> bool { + self.flags.contains(ReprFlags::IS_SCALABLE) + } + #[inline] pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index fb9016ca4d86..5caa98b05357 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -200,6 +200,9 @@ attr_parsing_rustc_allowed_unstable_pairing = attr_parsing_rustc_promotable_pairing = `rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute +attr_parsing_rustc_scalable_vector_count_out_of_range = element count in `rustc_scalable_vector` is too large: `{$n}` + .note = the value may not exceed `u16::MAX` + attr_parsing_soft_no_args = `soft` should not have any arguments diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index d51fa2510b93..4be141651ae6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1,5 +1,6 @@ use super::prelude::*; use super::util::parse_single_integer; +use crate::session_diagnostics::RustcScalableVectorCountOutOfRange; pub(crate) struct RustcMainParser; @@ -76,3 +77,29 @@ impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser Some(AttributeKind::RustcSimdMonomorphizeLaneLimit(cx.parse_limit_int(nv)?)) } } + +pub(crate) struct RustcScalableVectorParser; + +impl SingleAttributeParser for RustcScalableVectorParser { + const PATH: &[rustc_span::Symbol] = &[sym::rustc_scalable_vector]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + if args.no_args().is_ok() { + return Some(AttributeKind::RustcScalableVector { + element_count: None, + span: cx.attr_span, + }); + } + + let n = parse_single_integer(cx, args)?; + let Ok(n) = n.try_into() else { + cx.emit_err(RustcScalableVectorCountOutOfRange { span: cx.attr_span, n }); + return None; + }; + Some(AttributeKind::RustcScalableVector { element_count: Some(n), span: cx.attr_span }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8f5f5c55dcd5..9c7006f84024 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -60,7 +60,8 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcMainParser, - RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser, + RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, + RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -209,6 +210,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 4aea4064b1c4..73b65193fd34 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -501,6 +501,15 @@ pub(crate) struct LinkOrdinalOutOfRange { pub ordinal: u128, } +#[derive(Diagnostic)] +#[diag(attr_parsing_rustc_scalable_vector_count_out_of_range)] +#[note] +pub(crate) struct RustcScalableVectorCountOutOfRange { + #[primary_span] + pub span: Span, + pub n: u128, +} + pub(crate) enum AttributeParseErrorReason<'a> { ExpectedNoArgs, ExpectedStringLiteral { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index c70dbc15e552..0b930dc342f2 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1422,6 +1422,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes, "`#[rustc_force_inline]` forces a free function to be inlined" ), + rustc_attr!( + rustc_scalable_vector, Normal, template!(List: &["count"]), WarnFollowing, EncodeCrossCrate::Yes, + "`#[rustc_scalable_vector]` defines a scalable vector type" + ), // ========================================================================== // Internal attributes, Testing: diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 34d78afca9b2..5f38eaf4d5f4 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -878,6 +878,14 @@ pub enum AttributeKind { /// Represents `#[rustc_pass_indirectly_in_non_rustic_abis]` RustcPassIndirectlyInNonRusticAbis(Span), + /// Represents `#[rustc_scalable_vector(N)]` + RustcScalableVector { + /// The base multiple of lanes that are in a scalable vector, if provided. `element_count` + /// is not provided for representing tuple types. + element_count: Option, + span: Span, + }, + /// Represents `#[rustc_should_not_be_called_on_const_items]` RustcShouldNotBeCalledOnConstItems(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 4cb786f59bfe..90fb0497a5b2 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -95,6 +95,7 @@ impl AttributeKind { RustcMain => No, RustcObjectLifetimeDefault => No, RustcPassIndirectlyInNonRusticAbis(..) => No, + RustcScalableVector { .. } => Yes, RustcShouldNotBeCalledOnConstItems(..) => Yes, RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate Sanitize { .. } => No, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index 0ad486cef43d..8bd267a1c256 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -1,4 +1,5 @@ use std::num::NonZero; +use std::ops::Deref; use rustc_abi::Align; use rustc_ast::token::{CommentKind, DocFragmentKind}; @@ -37,6 +38,15 @@ impl PrintAttribute for &T { T::print_attribute(self, p) } } +impl PrintAttribute for Box { + fn should_render(&self) -> bool { + self.deref().should_render() + } + + fn print_attribute(&self, p: &mut Printer) { + T::print_attribute(self.deref(), p) + } +} impl PrintAttribute for Option { fn should_render(&self) -> bool { self.as_ref().is_some_and(|x| x.should_render()) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b91176e3d486..91e6e6326c09 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -24,7 +24,9 @@ pub use assoc::*; pub use generic_args::{GenericArgKind, TermKind, *}; pub use generics::*; pub use intrinsic::IntrinsicDef; -use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx}; +use rustc_abi::{ + Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, ScalableElt, VariantIdx, +}; use rustc_ast::AttrVec; use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree}; use rustc_ast::node_id::NodeMap; @@ -1515,6 +1517,17 @@ impl<'tcx> TyCtxt<'tcx> { } let attributes = self.get_all_attrs(did); + let elt = find_attr!( + attributes, + AttributeKind::RustcScalableVector { element_count, .. } => element_count + ) + .map(|elt| match elt { + Some(n) => ScalableElt::ElementCount(*n), + None => ScalableElt::Container, + }); + if elt.is_some() { + flags.insert(ReprFlags::IS_SCALABLE); + } if let Some(reprs) = find_attr!(attributes, AttributeKind::Repr { reprs, .. } => reprs) { for (r, _) in reprs { flags.insert(match *r { @@ -1579,7 +1592,14 @@ impl<'tcx> TyCtxt<'tcx> { flags.insert(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS); } - ReprOptions { int: size, align: max_align, pack: min_pack, flags, field_shuffle_seed } + ReprOptions { + int: size, + align: max_align, + pack: min_pack, + flags, + field_shuffle_seed, + scalable: elt, + } } /// Look up the name of a definition across crates. This does not look at HIR. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 852a0017687f..4d42b0237c13 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1253,6 +1253,14 @@ impl<'tcx> Ty<'tcx> { } } + #[inline] + pub fn is_scalable_vector(self) -> bool { + match self.kind() { + Adt(def, _) => def.repr().scalable(), + _ => false, + } + } + pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match self.kind() { Array(ty, _) | Slice(ty) => *ty, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 34f73212e90b..e836277e9761 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -252,6 +252,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::MacroEscape( .. ) | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) + | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) | AttributeKind::RustcShouldNotBeCalledOnConstItems(..) | AttributeKind::ExportStable diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8e464b55d6c2..c484476037e2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1998,6 +1998,7 @@ symbols! { rustc_reallocator, rustc_regions, rustc_reservation_impl, + rustc_scalable_vector, rustc_serialize, rustc_should_not_be_called_on_const_items, rustc_simd_monomorphize_lane_limit, diff --git a/tests/ui/scalable-vectors/invalid.rs b/tests/ui/scalable-vectors/invalid.rs new file mode 100644 index 000000000000..fde4911b2c8b --- /dev/null +++ b/tests/ui/scalable-vectors/invalid.rs @@ -0,0 +1,162 @@ +//@ edition: 2024 +#![allow(internal_features, unused_imports, unused_macros)] +#![feature(extern_types)] +#![feature(gen_blocks)] +#![feature(rustc_attrs)] +#![feature(stmt_expr_attributes)] +#![feature(trait_alias)] + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on extern crates +extern crate std as other_std; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on use statements +use std::vec::Vec; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on statics +static _X: u32 = 0; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on constants +const _Y: u32 = 0; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on modules +mod bar { +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on foreign modules +unsafe extern "C" { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on foreign statics + static X: &'static u32; + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on foreign types + type Y; + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on foreign functions + fn foo(); +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on type aliases +type Foo = u32; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on enums +enum Bar<#[rustc_scalable_vector(4)] T> { +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on function params + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on enum variants + Baz(std::marker::PhantomData), +} + +struct Qux { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on struct fields + field: u32, +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on unions +union FooBar { + x: u32, + y: u32, +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on traits +trait FooBaz { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on associated types + type Foo; + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on associated consts + const Bar: i32; + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on provided trait methods + fn foo() {} +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on trait aliases +trait FooQux = FooBaz; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on inherent impl blocks +impl Bar { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on inherent methods + fn foo() {} +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on trait impl blocks +impl FooBaz for Bar { + type Foo = u32; + const Bar: i32 = 3; +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on macro defs +macro_rules! barqux { ($foo:tt) => { $foo }; } + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on functions +fn barqux(#[rustc_scalable_vector(4)] _x: u32) {} +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on function params +//~^^ ERROR: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on functions +async fn async_foo() {} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on functions +gen fn gen_foo() {} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on functions +async gen fn async_gen_foo() {} + +fn main() { + let _x = #[rustc_scalable_vector(4)] || { }; +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on closures + let _y = #[rustc_scalable_vector(4)] 3 + 4; +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on expressions + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on statements + let _z = 3; + + match _z { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on match arms + 1 => (), + _ => (), + } +} + +#[rustc_scalable_vector("4")] +//~^ ERROR: malformed `rustc_scalable_vector` attribute input +struct ArgNotLit(f32); + +#[rustc_scalable_vector(4, 2)] +//~^ ERROR: malformed `rustc_scalable_vector` attribute input +struct ArgMultipleLits(f32); + +#[rustc_scalable_vector(count = "4")] +//~^ ERROR: malformed `rustc_scalable_vector` attribute input +struct ArgKind(f32); + +#[rustc_scalable_vector(65536)] +//~^ ERROR: element count in `rustc_scalable_vector` is too large: `65536` +struct CountTooLarge(f32); + +#[rustc_scalable_vector(4)] +struct Okay(f32); + +#[rustc_scalable_vector] +struct OkayNoArg(f32); diff --git a/tests/ui/scalable-vectors/invalid.stderr b/tests/ui/scalable-vectors/invalid.stderr new file mode 100644 index 000000000000..832bbe838dc4 --- /dev/null +++ b/tests/ui/scalable-vectors/invalid.stderr @@ -0,0 +1,333 @@ +error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + --> $DIR/invalid.rs:109:11 + | +LL | fn barqux(#[rustc_scalable_vector(4)] _x: u32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[rustc_scalable_vector]` attribute cannot be used on extern crates + --> $DIR/invalid.rs:9:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on use statements + --> $DIR/invalid.rs:13:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on statics + --> $DIR/invalid.rs:17:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on constants + --> $DIR/invalid.rs:21:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on modules + --> $DIR/invalid.rs:25:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on foreign modules + --> $DIR/invalid.rs:30:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on foreign statics + --> $DIR/invalid.rs:33:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on foreign types + --> $DIR/invalid.rs:36:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on foreign functions + --> $DIR/invalid.rs:39:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on type aliases + --> $DIR/invalid.rs:44:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on enums + --> $DIR/invalid.rs:48:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on function params + --> $DIR/invalid.rs:50:10 + | +LL | enum Bar<#[rustc_scalable_vector(4)] T> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on enum variants + --> $DIR/invalid.rs:52:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on struct fields + --> $DIR/invalid.rs:58:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on unions + --> $DIR/invalid.rs:63:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on traits + --> $DIR/invalid.rs:70:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on associated types + --> $DIR/invalid.rs:73:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on associated consts + --> $DIR/invalid.rs:76:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on provided trait methods + --> $DIR/invalid.rs:79:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on trait aliases + --> $DIR/invalid.rs:84:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on inherent impl blocks + --> $DIR/invalid.rs:88:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on inherent methods + --> $DIR/invalid.rs:91:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on trait impl blocks + --> $DIR/invalid.rs:96:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on macro defs + --> $DIR/invalid.rs:103:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on functions + --> $DIR/invalid.rs:107:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on function params + --> $DIR/invalid.rs:109:11 + | +LL | fn barqux(#[rustc_scalable_vector(4)] _x: u32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on functions + --> $DIR/invalid.rs:113:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on functions + --> $DIR/invalid.rs:117:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on functions + --> $DIR/invalid.rs:121:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on closures + --> $DIR/invalid.rs:126:14 + | +LL | let _x = #[rustc_scalable_vector(4)] || { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on expressions + --> $DIR/invalid.rs:128:14 + | +LL | let _y = #[rustc_scalable_vector(4)] 3 + 4; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on statements + --> $DIR/invalid.rs:130:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on match arms + --> $DIR/invalid.rs:135:9 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error[E0539]: malformed `rustc_scalable_vector` attribute input + --> $DIR/invalid.rs:142:1 + | +LL | #[rustc_scalable_vector("4")] + | ^^^^^^^^^^^^^^^^^^^^^^^^---^^ + | | + | expected an integer literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_scalable_vector("4")] +LL + #[rustc_scalable_vector(count)] + | +LL - #[rustc_scalable_vector("4")] +LL + #[rustc_scalable_vector] + | + +error[E0805]: malformed `rustc_scalable_vector` attribute input + --> $DIR/invalid.rs:146:1 + | +LL | #[rustc_scalable_vector(4, 2)] + | ^^^^^^^^^^^^^^^^^^^^^^^------^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_scalable_vector(4, 2)] +LL + #[rustc_scalable_vector(count)] + | +LL - #[rustc_scalable_vector(4, 2)] +LL + #[rustc_scalable_vector] + | + +error[E0539]: malformed `rustc_scalable_vector` attribute input + --> $DIR/invalid.rs:150:1 + | +LL | #[rustc_scalable_vector(count = "4")] + | ^^^^^^^^^^^^^^^^^^^^^^^^-----------^^ + | | + | expected an integer literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_scalable_vector(count = "4")] +LL + #[rustc_scalable_vector(count)] + | +LL - #[rustc_scalable_vector(count = "4")] +LL + #[rustc_scalable_vector] + | + +error: element count in `rustc_scalable_vector` is too large: `65536` + --> $DIR/invalid.rs:154:1 + | +LL | #[rustc_scalable_vector(65536)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the value may not exceed `u16::MAX` + +error: aborting due to 38 previous errors + +Some errors have detailed explanations: E0539, E0805. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index 8a2bad56c126..ecc5fb21435f 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -95,7 +95,7 @@ body: did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 13397682652773712997 } args: [] variant_index: 0 subpatterns: [ @@ -109,7 +109,7 @@ body: did: DefId(0:3 ~ thir_tree_match[fcf8]::Bar) variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 7908585036048874241 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7908585036048874241 } args: [] variant_index: 0 subpatterns: [] @@ -157,7 +157,7 @@ body: did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 13397682652773712997 } args: [] variant_index: 0 subpatterns: [ @@ -209,7 +209,7 @@ body: did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 13397682652773712997 } args: [] variant_index: 1 subpatterns: [] From ba9262936ec0f85a53a5407fa903931e2b8031e4 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 9 Jul 2025 16:25:29 +0000 Subject: [PATCH 0868/3801] hir/trait_sel: prohibit scalable vectors in types Extend well-formedness checking and HIR analysis to prohibit the use of scalable vectors in structs, enums, unions, tuples and arrays. LLVM does not support scalable vectors being members of other types, so these restrictions are necessary. Co-authored-by: Jamie Cunliffe --- compiler/rustc_ast_passes/messages.ftl | 2 + .../rustc_ast_passes/src/ast_validation.rs | 8 ++ compiler/rustc_ast_passes/src/errors.rs | 7 + .../rustc_hir_analysis/src/check/check.rs | 100 +++++++++++++- .../rustc_hir_analysis/src/check/wfcheck.rs | 18 ++- .../rustc_trait_selection/src/traits/wf.rs | 18 ++- .../illformed-element-type.rs | 93 +++++++++++++ .../illformed-element-type.stderr | 122 +++++++++++++++++ .../illformed-tuples-of-scalable-vectors.rs | 36 +++++ ...llformed-tuples-of-scalable-vectors.stderr | 38 ++++++ .../illformed-within-types.rs | 23 ++++ .../illformed-within-types.stderr | 32 +++++ tests/ui/scalable-vectors/illformed.rs | 59 +++++++++ tests/ui/scalable-vectors/illformed.stderr | 125 ++++++++++++++++++ tests/ui/scalable-vectors/invalid.rs | 1 + tests/ui/scalable-vectors/invalid.stderr | 8 +- .../ui/scalable-vectors/wellformed-arrays.rs | 10 ++ tests/ui/scalable-vectors/wellformed.rs | 48 +++++++ 18 files changed, 742 insertions(+), 6 deletions(-) create mode 100644 tests/ui/scalable-vectors/illformed-element-type.rs create mode 100644 tests/ui/scalable-vectors/illformed-element-type.stderr create mode 100644 tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.rs create mode 100644 tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.stderr create mode 100644 tests/ui/scalable-vectors/illformed-within-types.rs create mode 100644 tests/ui/scalable-vectors/illformed-within-types.stderr create mode 100644 tests/ui/scalable-vectors/illformed.rs create mode 100644 tests/ui/scalable-vectors/illformed.stderr create mode 100644 tests/ui/scalable-vectors/wellformed-arrays.rs create mode 100644 tests/ui/scalable-vectors/wellformed.rs diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index f1f734b855c1..b9117c83ae2f 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -270,6 +270,8 @@ ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc} +ast_passes_scalable_vector_not_tuple_struct = scalable vectors must be tuple structs + ast_passes_static_without_body = free static item without body .suggestion = provide a definition for the static diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0d34ba6c2ca8..a083ca7d133e 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1319,6 +1319,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ItemKind::Struct(ident, generics, vdata) => { self.with_tilde_const(Some(TildeConstReason::Struct { span: item.span }), |this| { + // Scalable vectors can only be tuple structs + let is_scalable_vector = + item.attrs.iter().any(|attr| attr.has_name(sym::rustc_scalable_vector)); + if is_scalable_vector && !matches!(vdata, VariantData::Tuple(..)) { + this.dcx() + .emit_err(errors::ScalableVectorNotTupleStruct { span: item.span }); + } + match vdata { VariantData::Struct { fields, .. } => { this.visit_attrs_vis_ident(&item.attrs, &item.vis, ident); diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index bf9309614fe2..22adaae8c6f2 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -990,3 +990,10 @@ pub(crate) struct AbiX86Interrupt { pub spans: Vec, pub param_count: usize, } + +#[derive(Diagnostic)] +#[diag(ast_passes_scalable_vector_not_tuple_struct)] +pub(crate) struct ScalableVectorNotTupleStruct { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index beba0165549e..a81df02f023f 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1,7 +1,7 @@ use std::cell::LazyCell; use std::ops::ControlFlow; -use rustc_abi::{ExternAbi, FieldIdx}; +use rustc_abi::{ExternAbi, FieldIdx, ScalableElt}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::codes::*; use rustc_errors::{EmissionGuarantee, MultiSpan}; @@ -92,7 +92,9 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) { let span = tcx.def_span(def_id); def.destructor(tcx); // force the destructor to be evaluated - if def.repr().simd() { + if let Some(scalable) = def.repr().scalable { + check_scalable_vector(tcx, span, def_id, scalable); + } else if def.repr().simd() { check_simd(tcx, span, def_id); } @@ -1426,6 +1428,100 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { } } +#[tracing::instrument(skip(tcx), level = "debug")] +fn check_scalable_vector(tcx: TyCtxt<'_>, span: Span, def_id: LocalDefId, scalable: ScalableElt) { + let ty = tcx.type_of(def_id).instantiate_identity(); + let ty::Adt(def, args) = ty.kind() else { return }; + if !def.is_struct() { + tcx.dcx().delayed_bug("`rustc_scalable_vector` applied to non-struct"); + return; + } + + let fields = &def.non_enum_variant().fields; + match scalable { + ScalableElt::ElementCount(..) if fields.is_empty() => { + let mut err = + tcx.dcx().struct_span_err(span, "scalable vectors must have a single field"); + err.help("scalable vector types' only field must be a primitive scalar type"); + err.emit(); + return; + } + ScalableElt::ElementCount(..) if fields.len() >= 2 => { + tcx.dcx().struct_span_err(span, "scalable vectors cannot have multiple fields").emit(); + return; + } + ScalableElt::Container if fields.is_empty() => { + let mut err = + tcx.dcx().struct_span_err(span, "scalable vectors must have a single field"); + err.help("tuples of scalable vectors can only contain multiple of the same scalable vector type"); + err.emit(); + return; + } + _ => {} + } + + match scalable { + ScalableElt::ElementCount(..) => { + let element_ty = &fields[FieldIdx::ZERO].ty(tcx, args); + + // Check that `element_ty` only uses types valid in the lanes of a scalable vector + // register: scalar types which directly match a "machine" type - integers, floats and + // bools + match element_ty.kind() { + ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Bool => (), + _ => { + let mut err = tcx.dcx().struct_span_err( + span, + "element type of a scalable vector must be a primitive scalar", + ); + err.help("only `u*`, `i*`, `f*` and `bool` types are accepted"); + err.emit(); + } + } + } + ScalableElt::Container => { + let mut prev_field_ty = None; + for field in fields.iter() { + let element_ty = field.ty(tcx, args); + if let ty::Adt(def, _) = element_ty.kind() + && def.repr().scalable() + { + match def + .repr() + .scalable + .expect("`repr().scalable.is_some()` != `repr().scalable()`") + { + ScalableElt::ElementCount(_) => { /* expected field */ } + ScalableElt::Container => { + tcx.dcx().span_err( + tcx.def_span(field.did), + "scalable vector structs cannot contain other scalable vector structs", + ); + break; + } + } + } else { + tcx.dcx().span_err( + tcx.def_span(field.did), + "scalable vector structs can only have scalable vector fields", + ); + break; + } + + if let Some(prev_ty) = prev_field_ty.replace(element_ty) + && prev_ty != element_ty + { + tcx.dcx().span_err( + tcx.def_span(field.did), + "all fields in a scalable vector struct must be the same type", + ); + break; + } + } + } + } +} + pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { let repr = def.repr(); if repr.packed() { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5ed0e0018f8d..16f5222f621c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2,7 +2,7 @@ use std::cell::LazyCell; use std::ops::{ControlFlow, Deref}; use hir::intravisit::{self, Visitor}; -use rustc_abi::ExternAbi; +use rustc_abi::{ExternAbi, ScalableElt}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; @@ -1038,7 +1038,21 @@ fn check_type_defn<'tcx>( hir_ty.span, Some(WellFormedLoc::Ty(field_id)), ty.into(), - ) + ); + + if matches!(ty.kind(), ty::Adt(def, _) if def.repr().scalable()) + && !matches!(adt_def.repr().scalable, Some(ScalableElt::Container)) + { + // Scalable vectors can only be fields of structs if the type has a + // `rustc_scalable_vector` attribute w/out specifying an element count + tcx.dcx().span_err( + hir_ty.span, + format!( + "scalable vectors cannot be fields of a {}", + adt_def.variant_descr() + ), + ); + } } // For DST, or when drop needs to copy things around, all diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index db7bd635f32e..394095508393 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -771,9 +771,25 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { } ty::Tuple(tys) => { - if let Some((_last, rest)) = tys.split_last() { + if let Some((last, rest)) = tys.split_last() { for &elem in rest { self.require_sized(elem, ObligationCauseCode::TupleElem); + if elem.is_scalable_vector() && !self.span.is_dummy() { + self.tcx() + .dcx() + .struct_span_err( + self.span, + "scalable vectors cannot be tuple fields", + ) + .emit(); + } + } + + if last.is_scalable_vector() && !self.span.is_dummy() { + self.tcx() + .dcx() + .struct_span_err(self.span, "scalable vectors cannot be tuple fields") + .emit(); } } } diff --git a/tests/ui/scalable-vectors/illformed-element-type.rs b/tests/ui/scalable-vectors/illformed-element-type.rs new file mode 100644 index 000000000000..469ca006f5e9 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-element-type.rs @@ -0,0 +1,93 @@ +//@ compile-flags: --crate-type=lib +#![allow(internal_features)] +#![feature(extern_types)] +#![feature(never_type)] +#![feature(rustc_attrs)] + +struct Foo; +enum Bar {} +union Baz { x: u16 } +extern "C" { + type Qux; +} + +#[rustc_scalable_vector(4)] +struct TyChar(char); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(2)] +struct TyConstPtr(*const u8); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(2)] +struct TyMutPtr(*mut u8); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyStruct(Foo); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyEnum(Bar); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyUnion(Baz); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyForeign(Qux); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyArray([u32; 4]); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TySlice([u32]); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyRef<'a>(&'a u32); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyFnPtr(fn(u32) -> u32); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyDyn(dyn std::io::Write); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyNever(!); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyTuple((u32, u32)); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +type ValidAlias = u32; +type InvalidAlias = String; + +#[rustc_scalable_vector(4)] +struct TyValidAlias(ValidAlias); + +#[rustc_scalable_vector(4)] +struct TyInvalidAlias(InvalidAlias); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +trait Tr { + type Valid; + type Invalid; +} + +impl Tr for () { + type Valid = u32; + type Invalid = String; +} + +struct TyValidProjection(<() as Tr>::Valid); + +struct TyInvalidProjection(<() as Tr>::Invalid); +// FIXME: element type of a scalable vector must be a primitive scalar diff --git a/tests/ui/scalable-vectors/illformed-element-type.stderr b/tests/ui/scalable-vectors/illformed-element-type.stderr new file mode 100644 index 000000000000..f8ca8b76215f --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-element-type.stderr @@ -0,0 +1,122 @@ +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:15:1 + | +LL | struct TyChar(char); + | ^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:19:1 + | +LL | struct TyConstPtr(*const u8); + | ^^^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:23:1 + | +LL | struct TyMutPtr(*mut u8); + | ^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:27:1 + | +LL | struct TyStruct(Foo); + | ^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:31:1 + | +LL | struct TyEnum(Bar); + | ^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:35:1 + | +LL | struct TyUnion(Baz); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:39:1 + | +LL | struct TyForeign(Qux); + | ^^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:43:1 + | +LL | struct TyArray([u32; 4]); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:47:1 + | +LL | struct TySlice([u32]); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:51:1 + | +LL | struct TyRef<'a>(&'a u32); + | ^^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:55:1 + | +LL | struct TyFnPtr(fn(u32) -> u32); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:59:1 + | +LL | struct TyDyn(dyn std::io::Write); + | ^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:63:1 + | +LL | struct TyNever(!); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:67:1 + | +LL | struct TyTuple((u32, u32)); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:77:1 + | +LL | struct TyInvalidAlias(InvalidAlias); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: aborting due to 15 previous errors + diff --git a/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.rs b/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.rs new file mode 100644 index 000000000000..4f89a8f9055e --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.rs @@ -0,0 +1,36 @@ +//@ compile-flags: --crate-type=lib +#![allow(internal_features)] +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(2)] +struct ValidI64(i64); + +#[rustc_scalable_vector(4)] +struct ValidI32(i32); + +#[rustc_scalable_vector] +struct ValidTuple(ValidI32, ValidI32, ValidI32); + +#[rustc_scalable_vector] +struct Struct { x: ValidI64, y: ValidI64 } +//~^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector] +struct DifferentVectorTypes(ValidI64, ValidI32); +//~^ ERROR: all fields in a scalable vector struct must be the same type + +#[rustc_scalable_vector] +struct NonVectorTypes(u32, u64); +//~^ ERROR: scalable vector structs can only have scalable vector fields + +#[rustc_scalable_vector] +struct DifferentNonVectorTypes(u32, u64); +//~^ ERROR: scalable vector structs can only have scalable vector fields + +#[rustc_scalable_vector] +struct SomeVectorTypes(ValidI64, u64); +//~^ ERROR: scalable vector structs can only have scalable vector fields + +#[rustc_scalable_vector] +struct NestedTuple(ValidTuple, ValidTuple); +//~^ ERROR: scalable vector structs cannot contain other scalable vector structs diff --git a/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.stderr b/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.stderr new file mode 100644 index 000000000000..f5fd963204a2 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.stderr @@ -0,0 +1,38 @@ +error: scalable vectors must be tuple structs + --> $DIR/illformed-tuples-of-scalable-vectors.rs:15:1 + | +LL | struct Struct { x: ValidI64, y: ValidI64 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: all fields in a scalable vector struct must be the same type + --> $DIR/illformed-tuples-of-scalable-vectors.rs:19:39 + | +LL | struct DifferentVectorTypes(ValidI64, ValidI32); + | ^^^^^^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed-tuples-of-scalable-vectors.rs:23:23 + | +LL | struct NonVectorTypes(u32, u64); + | ^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed-tuples-of-scalable-vectors.rs:27:32 + | +LL | struct DifferentNonVectorTypes(u32, u64); + | ^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed-tuples-of-scalable-vectors.rs:31:34 + | +LL | struct SomeVectorTypes(ValidI64, u64); + | ^^^ + +error: scalable vector structs cannot contain other scalable vector structs + --> $DIR/illformed-tuples-of-scalable-vectors.rs:35:20 + | +LL | struct NestedTuple(ValidTuple, ValidTuple); + | ^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/scalable-vectors/illformed-within-types.rs b/tests/ui/scalable-vectors/illformed-within-types.rs new file mode 100644 index 000000000000..81d960e4d4e1 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-within-types.rs @@ -0,0 +1,23 @@ +//@ compile-flags: --crate-type=lib +#![allow(internal_features)] +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(2)] +struct ValidI64(i64); + +struct Struct { + x: ValidI64, +//~^ ERROR: scalable vectors cannot be fields of a struct + in_tuple: (ValidI64,), +//~^ ERROR: scalable vectors cannot be tuple fields +} + +struct TupleStruct(ValidI64); +//~^ ERROR: scalable vectors cannot be fields of a struct + +enum Enum { + StructVariant { _ty: ValidI64 }, +//~^ ERROR: scalable vectors cannot be fields of a variant + TupleVariant(ValidI64), +//~^ ERROR: scalable vectors cannot be fields of a variant +} diff --git a/tests/ui/scalable-vectors/illformed-within-types.stderr b/tests/ui/scalable-vectors/illformed-within-types.stderr new file mode 100644 index 000000000000..e76ef26f2aa4 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-within-types.stderr @@ -0,0 +1,32 @@ +error: scalable vectors cannot be fields of a struct + --> $DIR/illformed-within-types.rs:9:8 + | +LL | x: ValidI64, + | ^^^^^^^^ + +error: scalable vectors cannot be tuple fields + --> $DIR/illformed-within-types.rs:11:15 + | +LL | in_tuple: (ValidI64,), + | ^^^^^^^^^^^ + +error: scalable vectors cannot be fields of a struct + --> $DIR/illformed-within-types.rs:15:20 + | +LL | struct TupleStruct(ValidI64); + | ^^^^^^^^ + +error: scalable vectors cannot be fields of a variant + --> $DIR/illformed-within-types.rs:19:26 + | +LL | StructVariant { _ty: ValidI64 }, + | ^^^^^^^^ + +error: scalable vectors cannot be fields of a variant + --> $DIR/illformed-within-types.rs:21:18 + | +LL | TupleVariant(ValidI64), + | ^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/scalable-vectors/illformed.rs b/tests/ui/scalable-vectors/illformed.rs new file mode 100644 index 000000000000..de135413a9f2 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed.rs @@ -0,0 +1,59 @@ +//@ compile-flags: --crate-type=lib +#![allow(internal_features)] +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(4)] +struct NoFieldsStructWithElementCount {} +//~^ ERROR: scalable vectors must have a single field +//~^^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector(4)] +struct NoFieldsTupleWithElementCount(); +//~^ ERROR: scalable vectors must have a single field + +#[rustc_scalable_vector(4)] +struct NoFieldsUnitWithElementCount; +//~^ ERROR: scalable vectors must have a single field +//~^^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector] +struct NoFieldsStructWithoutElementCount {} +//~^ ERROR: scalable vectors must have a single field +//~^^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector] +struct NoFieldsTupleWithoutElementCount(); +//~^ ERROR: scalable vectors must have a single field + +#[rustc_scalable_vector] +struct NoFieldsUnitWithoutElementCount; +//~^ ERROR: scalable vectors must have a single field +//~^^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector(4)] +struct MultipleFieldsStructWithElementCount { +//~^ ERROR: scalable vectors cannot have multiple fields +//~^^ ERROR: scalable vectors must be tuple structs + _ty: f32, + other: u32, +} + +#[rustc_scalable_vector(4)] +struct MultipleFieldsTupleWithElementCount(f32, u32); +//~^ ERROR: scalable vectors cannot have multiple fields + +#[rustc_scalable_vector] +struct MultipleFieldsStructWithoutElementCount { +//~^ ERROR: scalable vectors must be tuple structs + _ty: f32, +//~^ ERROR: scalable vector structs can only have scalable vector fields + other: u32, +} + +#[rustc_scalable_vector] +struct MultipleFieldsTupleWithoutElementCount(f32, u32); +//~^ ERROR: scalable vector structs can only have scalable vector fields + +#[rustc_scalable_vector(2)] +struct SingleFieldStruct { _ty: f64 } +//~^ ERROR: scalable vectors must be tuple structs diff --git a/tests/ui/scalable-vectors/illformed.stderr b/tests/ui/scalable-vectors/illformed.stderr new file mode 100644 index 000000000000..bdf519c91058 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed.stderr @@ -0,0 +1,125 @@ +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:6:1 + | +LL | struct NoFieldsStructWithElementCount {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:15:1 + | +LL | struct NoFieldsUnitWithElementCount; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:20:1 + | +LL | struct NoFieldsStructWithoutElementCount {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:29:1 + | +LL | struct NoFieldsUnitWithoutElementCount; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:34:1 + | +LL | / struct MultipleFieldsStructWithElementCount { +LL | | +LL | | +LL | | _ty: f32, +LL | | other: u32, +LL | | } + | |_^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:46:1 + | +LL | / struct MultipleFieldsStructWithoutElementCount { +LL | | +LL | | _ty: f32, +... | +LL | | } + | |_^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:58:1 + | +LL | struct SingleFieldStruct { _ty: f64 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:6:1 + | +LL | struct NoFieldsStructWithElementCount {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: scalable vector types' only field must be a primitive scalar type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:11:1 + | +LL | struct NoFieldsTupleWithElementCount(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: scalable vector types' only field must be a primitive scalar type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:15:1 + | +LL | struct NoFieldsUnitWithElementCount; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: scalable vector types' only field must be a primitive scalar type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:20:1 + | +LL | struct NoFieldsStructWithoutElementCount {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: tuples of scalable vectors can only contain multiple of the same scalable vector type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:25:1 + | +LL | struct NoFieldsTupleWithoutElementCount(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: tuples of scalable vectors can only contain multiple of the same scalable vector type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:29:1 + | +LL | struct NoFieldsUnitWithoutElementCount; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: tuples of scalable vectors can only contain multiple of the same scalable vector type + +error: scalable vectors cannot have multiple fields + --> $DIR/illformed.rs:34:1 + | +LL | struct MultipleFieldsStructWithElementCount { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors cannot have multiple fields + --> $DIR/illformed.rs:42:1 + | +LL | struct MultipleFieldsTupleWithElementCount(f32, u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed.rs:48:5 + | +LL | _ty: f32, + | ^^^^^^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed.rs:54:47 + | +LL | struct MultipleFieldsTupleWithoutElementCount(f32, u32); + | ^^^ + +error: aborting due to 17 previous errors + diff --git a/tests/ui/scalable-vectors/invalid.rs b/tests/ui/scalable-vectors/invalid.rs index fde4911b2c8b..beb3ad66b78b 100644 --- a/tests/ui/scalable-vectors/invalid.rs +++ b/tests/ui/scalable-vectors/invalid.rs @@ -160,3 +160,4 @@ struct Okay(f32); #[rustc_scalable_vector] struct OkayNoArg(f32); +//~^ ERROR: scalable vector structs can only have scalable vector fields diff --git a/tests/ui/scalable-vectors/invalid.stderr b/tests/ui/scalable-vectors/invalid.stderr index 832bbe838dc4..43be84a8b005 100644 --- a/tests/ui/scalable-vectors/invalid.stderr +++ b/tests/ui/scalable-vectors/invalid.stderr @@ -327,7 +327,13 @@ LL | #[rustc_scalable_vector(65536)] | = note: the value may not exceed `u16::MAX` -error: aborting due to 38 previous errors +error: scalable vector structs can only have scalable vector fields + --> $DIR/invalid.rs:162:18 + | +LL | struct OkayNoArg(f32); + | ^^^ + +error: aborting due to 39 previous errors Some errors have detailed explanations: E0539, E0805. For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/scalable-vectors/wellformed-arrays.rs b/tests/ui/scalable-vectors/wellformed-arrays.rs new file mode 100644 index 000000000000..b8f0bf291eea --- /dev/null +++ b/tests/ui/scalable-vectors/wellformed-arrays.rs @@ -0,0 +1,10 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(16)] +struct ScalableU8(u8); + +fn main() { + let x: [ScalableU8; 4] = todo!(); +} diff --git a/tests/ui/scalable-vectors/wellformed.rs b/tests/ui/scalable-vectors/wellformed.rs new file mode 100644 index 000000000000..cb6a22d6c433 --- /dev/null +++ b/tests/ui/scalable-vectors/wellformed.rs @@ -0,0 +1,48 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(16)] +struct ScalableU8(u8); + +#[rustc_scalable_vector(8)] +struct ScalableU16(u16); + +#[rustc_scalable_vector(4)] +struct ScalableU32(u32); + +#[rustc_scalable_vector(2)] +struct ScalableU64(u64); + +#[rustc_scalable_vector(1)] +struct ScalableU128(u128); + +#[rustc_scalable_vector(16)] +struct ScalableI8(i8); + +#[rustc_scalable_vector(8)] +struct ScalableI16(i16); + +#[rustc_scalable_vector(4)] +struct ScalableI32(i32); + +#[rustc_scalable_vector(2)] +struct ScalableI64(i64); + +#[rustc_scalable_vector(1)] +struct ScalableI128(i128); + +#[rustc_scalable_vector(8)] +struct ScalableF16(f32); + +#[rustc_scalable_vector(4)] +struct ScalableF32(f32); + +#[rustc_scalable_vector(2)] +struct ScalableF64(f64); + +#[rustc_scalable_vector(16)] +struct ScalableBool(bool); + +#[rustc_scalable_vector] +struct ScalableTuple(ScalableU8, ScalableU8, ScalableU8); From a56b1b928341e2b050b617bfcf0c35ef5a0c867e Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 10 Jul 2025 10:17:44 +0000 Subject: [PATCH 0869/3801] codegen: implement `repr(scalable)` Introduces `BackendRepr::ScalableVector` corresponding to scalable vector types annotated with `repr(scalable)` which lowers to a scalable vector type in LLVM. Co-authored-by: Jamie Cunliffe --- compiler/rustc_abi/src/callconv.rs | 4 + compiler/rustc_abi/src/layout.rs | 134 ++++++++++++------ compiler/rustc_abi/src/layout/ty.rs | 8 ++ compiler/rustc_abi/src/lib.rs | 39 ++++- compiler/rustc_codegen_gcc/src/builder.rs | 4 + .../rustc_codegen_gcc/src/intrinsic/mod.rs | 2 +- compiler/rustc_codegen_gcc/src/type_of.rs | 4 + compiler/rustc_codegen_llvm/src/builder.rs | 19 +++ compiler/rustc_codegen_llvm/src/intrinsic.rs | 34 ++++- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_llvm/src/type_.rs | 4 + compiler/rustc_codegen_llvm/src/type_of.rs | 14 +- compiler/rustc_codegen_llvm/src/va_arg.rs | 6 +- compiler/rustc_codegen_ssa/messages.ftl | 1 + compiler/rustc_codegen_ssa/src/errors.rs | 8 ++ compiler/rustc_codegen_ssa/src/mir/operand.rs | 8 +- compiler/rustc_codegen_ssa/src/mir/place.rs | 18 ++- .../rustc_codegen_ssa/src/traits/builder.rs | 1 + .../src/interpret/validity.rs | 2 +- .../src/util/check_validity_requirement.rs | 2 + compiler/rustc_middle/src/ty/layout.rs | 4 + compiler/rustc_middle/src/ty/sty.rs | 15 +- compiler/rustc_mir_transform/src/gvn.rs | 4 +- compiler/rustc_public/src/abi.rs | 14 +- .../src/unstable/convert/stable/abi.rs | 3 + compiler/rustc_target/src/callconv/aarch64.rs | 4 +- .../rustc_target/src/callconv/loongarch.rs | 5 +- compiler/rustc_target/src/callconv/mod.rs | 1 + compiler/rustc_target/src/callconv/riscv.rs | 4 +- compiler/rustc_target/src/callconv/x86.rs | 3 + compiler/rustc_target/src/callconv/x86_64.rs | 2 + .../rustc_target/src/callconv/x86_win64.rs | 1 + compiler/rustc_ty_utils/src/abi.rs | 4 +- compiler/rustc_ty_utils/src/layout.rs | 35 ++++- .../rustc_ty_utils/src/layout/invariant.rs | 2 +- tests/codegen-llvm/scalable-vectors/simple.rs | 49 +++++++ tests/ui/scalable-vectors/closure-capture.rs | 51 +++++++ .../scalable-vectors/closure-capture.stderr | 8 ++ tests/ui/scalable-vectors/copy-clone.rs | 31 ++++ tests/ui/scalable-vectors/copy-clone.stderr | 17 +++ tests/ui/scalable-vectors/fn-trait.rs | 13 ++ tests/ui/scalable-vectors/fn-trait.stderr | 8 ++ tests/ui/scalable-vectors/value-type.rs | 37 +++++ tests/ui/scalable-vectors/value-type.stderr | 17 +++ 44 files changed, 571 insertions(+), 74 deletions(-) create mode 100644 tests/codegen-llvm/scalable-vectors/simple.rs create mode 100644 tests/ui/scalable-vectors/closure-capture.rs create mode 100644 tests/ui/scalable-vectors/closure-capture.stderr create mode 100644 tests/ui/scalable-vectors/copy-clone.rs create mode 100644 tests/ui/scalable-vectors/copy-clone.stderr create mode 100644 tests/ui/scalable-vectors/fn-trait.rs create mode 100644 tests/ui/scalable-vectors/fn-trait.stderr create mode 100644 tests/ui/scalable-vectors/value-type.rs create mode 100644 tests/ui/scalable-vectors/value-type.stderr diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs index a21e1aee9b08..1664b3003095 100644 --- a/compiler/rustc_abi/src/callconv.rs +++ b/compiler/rustc_abi/src/callconv.rs @@ -82,6 +82,10 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { })) } + BackendRepr::ScalableVector { .. } => { + unreachable!("`homogeneous_aggregate` should not be called for scalable vectors") + } + BackendRepr::ScalarPair(..) | BackendRepr::Memory { sized: true } => { // Helper for computing `homogeneous_aggregate`, allowing a custom // starting offset (used below for handling variants). diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index b078fc92482f..b852d71b8008 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -11,7 +11,7 @@ use tracing::{debug, trace}; use crate::{ AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, LayoutData, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, - Variants, WrappingRange, + TargetDataLayout, Variants, WrappingRange, }; mod coroutine; @@ -143,58 +143,32 @@ impl LayoutCalculator { }) } - pub fn simd_type< + pub fn scalable_vector_type( + &self, + element: F, + count: u64, + ) -> LayoutCalculatorResult + where FieldIdx: Idx, VariantIdx: Idx, F: AsRef> + fmt::Debug, - >( + { + vector_type_layout(VectorKind::Scalable, self.cx.data_layout(), element, count) + } + + pub fn simd_type( &self, element: F, count: u64, repr_packed: bool, - ) -> LayoutCalculatorResult { - let elt = element.as_ref(); - if count == 0 { - return Err(LayoutCalculatorError::ZeroLengthSimdType); - } else if count > crate::MAX_SIMD_LANES { - return Err(LayoutCalculatorError::OversizedSimdType { - max_lanes: crate::MAX_SIMD_LANES, - }); - } - - let BackendRepr::Scalar(e_repr) = elt.backend_repr else { - return Err(LayoutCalculatorError::NonPrimitiveSimdType(element)); - }; - - // Compute the size and alignment of the vector - let dl = self.cx.data_layout(); - let size = - elt.size.checked_mul(count, dl).ok_or_else(|| LayoutCalculatorError::SizeOverflow)?; - let (repr, align) = if repr_packed && !count.is_power_of_two() { - // Non-power-of-two vectors have padding up to the next power-of-two. - // If we're a packed repr, remove the padding while keeping the alignment as close - // to a vector as possible. - (BackendRepr::Memory { sized: true }, Align::max_aligned_factor(size)) - } else { - (BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size)) - }; - let size = size.align_to(align); - - Ok(LayoutData { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Arbitrary { - offsets: [Size::ZERO].into(), - memory_index: [0].into(), - }, - backend_repr: repr, - largest_niche: elt.largest_niche, - uninhabited: false, - size, - align: AbiAlign::new(align), - max_repr_align: None, - unadjusted_abi_align: elt.align.abi, - randomization_seed: elt.randomization_seed.wrapping_add(Hash64::new(count)), - }) + ) -> LayoutCalculatorResult + where + FieldIdx: Idx, + VariantIdx: Idx, + F: AsRef> + fmt::Debug, + { + let kind = if repr_packed { VectorKind::PackedFixed } else { VectorKind::Fixed }; + vector_type_layout(kind, self.cx.data_layout(), element, count) } /// Compute the layout for a coroutine. @@ -453,6 +427,7 @@ impl LayoutCalculator { BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..) | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } | BackendRepr::Memory { .. } => repr, }, }; @@ -524,7 +499,8 @@ impl LayoutCalculator { hide_niches(a); hide_niches(b); } - BackendRepr::SimdVector { element, count: _ } => hide_niches(element), + BackendRepr::SimdVector { element, .. } + | BackendRepr::ScalableVector { element, .. } => hide_niches(element), BackendRepr::Memory { sized: _ } => {} } st.largest_niche = None; @@ -1501,3 +1477,67 @@ impl LayoutCalculator { s } } + +enum VectorKind { + /// `#[rustc_scalable_vector]` + Scalable, + /// `#[repr(simd, packed)]` + PackedFixed, + /// `#[repr(simd)]` + Fixed, +} + +fn vector_type_layout( + kind: VectorKind, + dl: &TargetDataLayout, + element: F, + count: u64, +) -> LayoutCalculatorResult +where + FieldIdx: Idx, + VariantIdx: Idx, + F: AsRef> + fmt::Debug, +{ + let elt = element.as_ref(); + if count == 0 { + return Err(LayoutCalculatorError::ZeroLengthSimdType); + } else if count > crate::MAX_SIMD_LANES { + return Err(LayoutCalculatorError::OversizedSimdType { max_lanes: crate::MAX_SIMD_LANES }); + } + + let BackendRepr::Scalar(element) = elt.backend_repr else { + return Err(LayoutCalculatorError::NonPrimitiveSimdType(element)); + }; + + // Compute the size and alignment of the vector + let size = + elt.size.checked_mul(count, dl).ok_or_else(|| LayoutCalculatorError::SizeOverflow)?; + let (repr, align) = match kind { + VectorKind::Scalable => { + (BackendRepr::ScalableVector { element, count }, dl.llvmlike_vector_align(size)) + } + // Non-power-of-two vectors have padding up to the next power-of-two. + // If we're a packed repr, remove the padding while keeping the alignment as close + // to a vector as possible. + VectorKind::PackedFixed if !count.is_power_of_two() => { + (BackendRepr::Memory { sized: true }, Align::max_aligned_factor(size)) + } + VectorKind::PackedFixed | VectorKind::Fixed => { + (BackendRepr::SimdVector { element, count }, dl.llvmlike_vector_align(size)) + } + }; + let size = size.align_to(align); + + Ok(LayoutData { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }, + backend_repr: repr, + largest_niche: elt.largest_niche, + uninhabited: false, + size, + align: AbiAlign::new(align), + max_repr_align: None, + unadjusted_abi_align: elt.align.abi, + randomization_seed: elt.randomization_seed.wrapping_add(Hash64::new(count)), + }) +} diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index ca2753ea2fd9..a384eddc0b52 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -172,6 +172,7 @@ pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug { fn is_tuple(this: TyAndLayout<'a, Self>) -> bool; fn is_unit(this: TyAndLayout<'a, Self>) -> bool; fn is_transparent(this: TyAndLayout<'a, Self>) -> bool; + fn is_scalable_vector(this: TyAndLayout<'a, Self>) -> bool; /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. fn is_pass_indirectly_in_non_rustic_abis_flag_set(this: TyAndLayout<'a, Self>) -> bool; } @@ -271,6 +272,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty::is_transparent(self) } + pub fn is_scalable_vector(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_scalable_vector(self) + } + /// If this method returns `true`, then this type should always have a `PassMode` of /// `Indirect { on_stack: false, .. }` when being used as the argument type of a function with a /// non-Rustic ABI (this is true for structs annotated with the diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index bdd7d372c3c8..53b2c3f36dfc 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1758,6 +1758,10 @@ impl AddressSpace { pub enum BackendRepr { Scalar(Scalar), ScalarPair(Scalar, Scalar), + ScalableVector { + element: Scalar, + count: u64, + }, SimdVector { element: Scalar, count: u64, @@ -1776,6 +1780,12 @@ impl BackendRepr { match *self { BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) + // FIXME(rustc_scalable_vector): Scalable vectors are `Sized` while the + // `sized_hierarchy` feature is not yet fully implemented. After `sized_hierarchy` is + // fully implemented, scalable vectors will remain `Sized`, they just won't be + // `const Sized` - whether `is_unsized` continues to return `false` at that point will + // need to be revisited and will depend on what `is_unsized` is used for. + | BackendRepr::ScalableVector { .. } | BackendRepr::SimdVector { .. } => false, BackendRepr::Memory { sized } => !sized, } @@ -1816,7 +1826,9 @@ impl BackendRepr { BackendRepr::Scalar(s) => Some(s.align(cx).abi), BackendRepr::ScalarPair(s1, s2) => Some(s1.align(cx).max(s2.align(cx)).abi), // The align of a Vector can vary in surprising ways - BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => None, + BackendRepr::SimdVector { .. } + | BackendRepr::Memory { .. } + | BackendRepr::ScalableVector { .. } => None, } } @@ -1838,7 +1850,9 @@ impl BackendRepr { Some(size) } // The size of a Vector can vary in surprising ways - BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => None, + BackendRepr::SimdVector { .. } + | BackendRepr::Memory { .. } + | BackendRepr::ScalableVector { .. } => None, } } @@ -1853,6 +1867,9 @@ impl BackendRepr { BackendRepr::SimdVector { element: element.to_union(), count } } BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true }, + BackendRepr::ScalableVector { element, count } => { + BackendRepr::ScalableVector { element: element.to_union(), count } + } } } @@ -2093,7 +2110,9 @@ impl LayoutData { /// Returns `true` if this is an aggregate type (including a ScalarPair!) pub fn is_aggregate(&self) -> bool { match self.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => false, + BackendRepr::Scalar(_) + | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } => false, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true, } } @@ -2187,6 +2206,19 @@ impl LayoutData { self.is_sized() && self.size.bytes() == 0 && self.align.bytes() == 1 } + /// Returns `true` if the size of the type is only known at runtime. + pub fn is_runtime_sized(&self) -> bool { + matches!(self.backend_repr, BackendRepr::ScalableVector { .. }) + } + + /// Returns the elements count of a scalable vector. + pub fn scalable_vector_element_count(&self) -> Option { + match self.backend_repr { + BackendRepr::ScalableVector { count, .. } => Some(count), + _ => None, + } + } + /// Returns `true` if the type is a ZST and not unsized. /// /// Note that this does *not* imply that the type is irrelevant for layout! It can still have @@ -2195,6 +2227,7 @@ impl LayoutData { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) + | BackendRepr::ScalableVector { .. } | BackendRepr::SimdVector { .. } => false, BackendRepr::Memory { sized } => sized && self.size.bytes() == 0, } diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index df1e64c75b96..79228c20d292 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -943,6 +943,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { .get_address(self.location) } + fn scalable_alloca(&mut self, _elt: u64, _align: Align, _element_ty: Ty<'_>) -> RValue<'gcc> { + todo!() + } + fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { let block = self.llbb(); let function = block.get_function(); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index a38dcf8e4c93..d2714ba7914f 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -504,7 +504,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - SimdVector { .. } => false, + SimdVector { .. } | ScalableVector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 93202483eed8..68fca5a17ad3 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -85,6 +85,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( ); } BackendRepr::Memory { .. } => {} + BackendRepr::ScalableVector { .. } => todo!(), } let name = match *layout.ty.kind() { @@ -179,6 +180,8 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, + // FIXME(rustc_scalable_vector): Not yet implemented in rustc_codegen_gcc. + BackendRepr::ScalableVector { .. } => todo!(), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -188,6 +191,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { BackendRepr::ScalarPair(..) => true, BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 3442abece2f7..9a9e4dcdbb3c 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -613,6 +613,25 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } + fn scalable_alloca(&mut self, elt: u64, align: Align, element_ty: Ty<'_>) -> Self::Value { + let mut bx = Builder::with_cx(self.cx); + bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) }); + let llvm_ty = match element_ty.kind() { + ty::Bool => bx.type_i1(), + ty::Int(int_ty) => self.cx.type_int_from_ty(*int_ty), + ty::Uint(uint_ty) => self.cx.type_uint_from_ty(*uint_ty), + ty::Float(float_ty) => self.cx.type_float_from_ty(*float_ty), + _ => unreachable!("scalable vectors can only contain a bool, int, uint or float"), + }; + + unsafe { + let ty = llvm::LLVMScalableVectorType(llvm_ty, elt.try_into().unwrap()); + let alloca = llvm::LLVMBuildAlloca(&bx.llbuilder, ty, UNNAMED); + llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); + alloca + } + } + fn load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &'ll Value { unsafe { let load = llvm::LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index e43bd8c2feef..82615d4a160e 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -480,6 +480,14 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, SimdVector { .. } => false, + ScalableVector { .. } => { + tcx.dcx().emit_err(InvalidMonomorphization::NonScalableType { + span, + name: sym::raw_eq, + ty: tp_ty, + }); + return Ok(()); + } Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), @@ -1679,11 +1687,27 @@ fn generic_simd_intrinsic<'ll, 'tcx>( m_len == v_len, InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len } ); - let in_elem_bitwidth = require_int_or_uint_ty!( - m_elem_ty.kind(), - InvalidMonomorphization::MaskWrongElementType { span, name, ty: m_elem_ty } - ); - let m_i1s = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, m_len); + + let m_i1s = if args[1].layout.ty.is_scalable_vector() { + match m_elem_ty.kind() { + ty::Bool => {} + _ => return_error!(InvalidMonomorphization::MaskWrongElementType { + span, + name, + ty: m_elem_ty + }), + }; + let i1 = bx.type_i1(); + let i1xn = bx.type_scalable_vector(i1, m_len as u64); + bx.trunc(args[0].immediate(), i1xn) + } else { + let in_elem_bitwidth = require_int_or_uint_ty!( + m_elem_ty.kind(), + InvalidMonomorphization::MaskWrongElementType { span, name, ty: m_elem_ty } + ); + vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, m_len) + }; + return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 7835319f5c1d..2f53a1995248 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -998,6 +998,7 @@ unsafe extern "C" { // Operations on array, pointer, and vector types (sequence types) pub(crate) safe fn LLVMPointerTypeInContext(C: &Context, AddressSpace: c_uint) -> &Type; pub(crate) fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type; + pub(crate) fn LLVMScalableVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type; pub(crate) fn LLVMGetElementType(Ty: &Type) -> &Type; pub(crate) fn LLVMGetVectorSize(VectorTy: &Type) -> c_uint; diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 55f053f4fad3..83d7fa0c9153 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -68,6 +68,10 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { unsafe { llvm::LLVMVectorType(ty, len as c_uint) } } + pub(crate) fn type_scalable_vector(&self, ty: &'ll Type, count: u64) -> &'ll Type { + unsafe { llvm::LLVMScalableVectorType(ty, count as c_uint) } + } + pub(crate) fn add_func(&self, name: &str, ty: &'ll Type) -> &'ll Value { let name = SmallCStr::new(name); unsafe { llvm::LLVMAddFunction(self.llmod(), name.as_ptr(), ty) } diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 2b2ac1c6eb29..1ed06fbd2821 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -24,6 +24,15 @@ fn uncached_llvm_type<'a, 'tcx>( let element = layout.scalar_llvm_type_at(cx, element); return cx.type_vector(element, count); } + BackendRepr::ScalableVector { ref element, count } => { + let element = if element.is_bool() { + cx.type_i1() + } else { + layout.scalar_llvm_type_at(cx, *element) + }; + + return cx.type_scalable_vector(element, count); + } BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {} } @@ -176,7 +185,9 @@ pub(crate) trait LayoutLlvmExt<'tcx> { impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { fn is_llvm_immediate(&self) -> bool { match self.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, + BackendRepr::Scalar(_) + | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } => true, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -186,6 +197,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { BackendRepr::ScalarPair(..) => true, BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index add25da025b2..8d77c25bbf90 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -549,7 +549,7 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( registers_for_primitive(scalar1.primitive()); registers_for_primitive(scalar2.primitive()); } - BackendRepr::SimdVector { .. } => { + BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { // Because no instance of VaArgSafe uses a non-scalar `BackendRepr`. unreachable!( "No x86-64 SysV va_arg implementation for {:?}", @@ -689,7 +689,9 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( } } // The Previous match on `BackendRepr` means control flow already escaped. - BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => unreachable!(), + BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } + | BackendRepr::Memory { .. } => unreachable!(), }; // AMD64-ABI 3.5.7p5: Step 5. Set: diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index fc6e4fb12574..ff78bea5b67c 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -129,6 +129,7 @@ codegen_ssa_invalid_monomorphization_mask_wrong_element_type = invalid monomorph codegen_ssa_invalid_monomorphization_mismatched_lengths = invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}` +codegen_ssa_invalid_monomorphization_non_scalable_type = invalid monomorphization of `{$name}` intrinsic: expected non-scalable type, found scalable type `{$ty}` codegen_ssa_invalid_monomorphization_return_element = invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}` codegen_ssa_invalid_monomorphization_return_integer_type = invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}` diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 84be2af3c9a7..c3d63e332989 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1094,6 +1094,14 @@ pub enum InvalidMonomorphization<'tcx> { expected_element: Ty<'tcx>, vector_type: Ty<'tcx>, }, + + #[diag(codegen_ssa_invalid_monomorphization_non_scalable_type, code = E0511)] + NonScalableType { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, } pub enum ExpectedPointerMutability { diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 5a139702f81d..6fd118a60d4d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -405,7 +405,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { imm } } - BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { .. } => bug!(), + BackendRepr::ScalarPair(_, _) + | BackendRepr::Memory { .. } + | BackendRepr::ScalableVector { .. } => bug!(), }) }; @@ -692,7 +694,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandRefBuilder<'tcx, V> { BackendRepr::ScalarPair(a, b) => { OperandValueBuilder::Pair(Either::Right(a), Either::Right(b)) } - BackendRepr::SimdVector { .. } => OperandValueBuilder::Vector(Either::Right(())), + BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { + OperandValueBuilder::Vector(Either::Right(())) + } BackendRepr::Memory { .. } => { bug!("Cannot use non-ZST Memory-ABI type in operand builder: {layout:?}"); } diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 50f56f913a51..d62e622b6fed 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -109,7 +109,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bx: &mut Bx, layout: TyAndLayout<'tcx>, ) -> Self { - Self::alloca_size(bx, layout.size, layout) + if layout.is_runtime_sized() { + Self::alloca_runtime_sized(bx, layout) + } else { + Self::alloca_size(bx, layout.size, layout) + } } pub fn alloca_size>( @@ -146,6 +150,18 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bug!("unexpected layout `{:#?}` in PlaceRef::len", self.layout) } } + + fn alloca_runtime_sized>( + bx: &mut Bx, + layout: TyAndLayout<'tcx>, + ) -> Self { + let (element_count, ty) = layout.ty.scalable_vector_element_count_and_type(bx.tcx()); + PlaceValue::new_sized( + bx.scalable_alloca(element_count as u64, layout.align.abi, ty), + layout.align.abi, + ) + .with_type(layout) + } } impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index f57f9108f744..4f45c614e003 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -235,6 +235,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value; fn alloca(&mut self, size: Size, align: Align) -> Self::Value; + fn scalable_alloca(&mut self, elt: u64, align: Align, element_ty: Ty<'_>) -> Self::Value; fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value; fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value; diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 34296b6d8de3..5d8ae42f5ecc 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1315,7 +1315,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, self.visit_scalar(b, b_layout)?; } } - BackendRepr::SimdVector { .. } => { + BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { // No checks here, we assume layout computation gets this right. // (This is harder to check since Miri does not represent these as `Immediate`. We // also cannot use field projections since this might be a newtype around a vector.) diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 34bd8423e8e1..939f9151680b 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -119,7 +119,9 @@ fn check_validity_requirement_lax<'tcx>( } BackendRepr::SimdVector { element: s, count } => count == 0 || scalar_allows_raw_init(s), BackendRepr::Memory { .. } => true, // Fields are checked below. + BackendRepr::ScalableVector { element, .. } => scalar_allows_raw_init(element), }; + if !valid { // This is definitely not okay. return Ok(false); diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index d0fd2f02a336..81b8142d03f3 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1178,6 +1178,10 @@ where matches!(this.ty.kind(), ty::Adt(def, _) if def.repr().transparent()) } + fn is_scalable_vector(this: TyAndLayout<'tcx>) -> bool { + this.ty.is_scalable_vector() + } + /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. fn is_pass_indirectly_in_non_rustic_abis_flag_set(this: TyAndLayout<'tcx>) -> bool { matches!(this.ty.kind(), ty::Adt(def, _) if def.repr().flags.contains(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS)) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 4d42b0237c13..c3834607e923 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -7,7 +7,7 @@ use std::borrow::Cow; use std::ops::{ControlFlow, Range}; use hir::def::{CtorKind, DefKind}; -use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; +use rustc_abi::{FIRST_VARIANT, FieldIdx, ScalableElt, VariantIdx}; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::LangItem; @@ -1269,6 +1269,19 @@ impl<'tcx> Ty<'tcx> { } } + pub fn scalable_vector_element_count_and_type(self, tcx: TyCtxt<'tcx>) -> (u16, Ty<'tcx>) { + let Adt(def, args) = self.kind() else { + bug!("`scalable_vector_size_and_type` called on invalid type") + }; + let Some(ScalableElt::ElementCount(element_count)) = def.repr().scalable else { + bug!("`scalable_vector_size_and_type` called on non-scalable vector type"); + }; + let variant = def.non_enum_variant(); + assert_eq!(variant.fields.len(), 1); + let field_ty = variant.fields[FieldIdx::ZERO].ty(tcx, args); + (element_count, field_ty) + } + pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) { let Adt(def, args) = self.kind() else { bug!("`simd_size_and_type` called on invalid type") diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 92c74e7fc276..526d0e96a36d 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1661,7 +1661,9 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { BackendRepr::ScalarPair(a, b) => { !a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx) } - BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => false, + BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } + | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index 820c41acf5b2..aced39059f6b 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -225,6 +225,10 @@ pub enum ValueAbi { element: Scalar, count: u64, }, + ScalableVector { + element: Scalar, + count: u64, + }, Aggregate { /// If true, the size is exact, otherwise it's only a lower bound. sized: bool, @@ -235,7 +239,15 @@ impl ValueAbi { /// Returns `true` if the layout corresponds to an unsized type. pub fn is_unsized(&self) -> bool { match *self { - ValueAbi::Scalar(_) | ValueAbi::ScalarPair(..) | ValueAbi::Vector { .. } => false, + ValueAbi::Scalar(_) + | ValueAbi::ScalarPair(..) + | ValueAbi::Vector { .. } + // FIXME(rustc_scalable_vector): Scalable vectors are `Sized` while the + // `sized_hierarchy` feature is not yet fully implemented. After `sized_hierarchy` is + // fully implemented, scalable vectors will remain `Sized`, they just won't be + // `const Sized` - whether `is_unsized` continues to return `false` at that point will + // need to be revisited and will depend on what `is_unsized` is used for. + | ValueAbi::ScalableVector { .. } => false, ValueAbi::Aggregate { sized } => !sized, } } diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index 782e75a930e0..03328d084ee9 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -256,6 +256,9 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { rustc_abi::BackendRepr::SimdVector { element, count } => { ValueAbi::Vector { element: element.stable(tables, cx), count } } + rustc_abi::BackendRepr::ScalableVector { element, count } => { + ValueAbi::ScalableVector { element: element.stable(tables, cx), count } + } rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized }, } } diff --git a/compiler/rustc_target/src/callconv/aarch64.rs b/compiler/rustc_target/src/callconv/aarch64.rs index cb2b7f4455c6..b38d45551553 100644 --- a/compiler/rustc_target/src/callconv/aarch64.rs +++ b/compiler/rustc_target/src/callconv/aarch64.rs @@ -78,7 +78,7 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec, { - if !ret.layout.is_sized() { + if !ret.layout.is_sized() || ret.layout.is_scalable_vector() { // Not touching this... return; } @@ -110,7 +110,7 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec, { - if !arg.layout.is_sized() { + if !arg.layout.is_sized() || arg.layout.is_scalable_vector() { // Not touching this... return; } diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs index bbea841b4106..d74d15446eaf 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs @@ -85,7 +85,10 @@ where } } }, - BackendRepr::SimdVector { .. } => return Err(CannotUseFpConv), + BackendRepr::SimdVector { .. } => { + return Err(CannotUseFpConv); + } + BackendRepr::ScalableVector { .. } => panic!("scalable vectors are unsupported"), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 878340143582..092d99e91118 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -393,6 +393,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { ), BackendRepr::SimdVector { .. } => PassMode::Direct(ArgAttributes::new()), BackendRepr::Memory { .. } => Self::indirect_pass_mode(&layout), + BackendRepr::ScalableVector { .. } => PassMode::Direct(ArgAttributes::new()), }; ArgAbi { layout, mode } } diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs index c4310bf6ccfb..f166b8330516 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs @@ -91,7 +91,9 @@ where } } }, - BackendRepr::SimdVector { .. } => return Err(CannotUseFpConv), + BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { + return Err(CannotUseFpConv); + } BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 93dc60dc1593..5e8cab0ee987 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -103,6 +103,9 @@ where } false } + BackendRepr::ScalableVector { .. } => { + panic!("scalable vectors are unsupported") + } } } diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index 04eecbfbc8dd..8fab4e444228 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -59,6 +59,8 @@ where BackendRepr::SimdVector { .. } => Class::Sse, + BackendRepr::ScalableVector { .. } => panic!("scalable vectors are unsupported"), + BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => { for i in 0..layout.fields.count() { let field_off = off + layout.fields.offset(i); diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs index 85ee59eabc7c..48f7700a86d5 100644 --- a/compiler/rustc_target/src/callconv/x86_win64.rs +++ b/compiler/rustc_target/src/callconv/x86_win64.rs @@ -25,6 +25,7 @@ where // FIXME(eddyb) there should be a size cap here // (probably what clang calls "illegal vectors"). } + BackendRepr::ScalableVector { .. } => panic!("scalable vectors are unsupported"), BackendRepr::Scalar(scalar) => { if is_ret && matches!(scalar.primitive(), Primitive::Int(Integer::I128, _)) { if cx.target_spec().rustc_abi == Some(RustcAbi::X86Softfloat) { diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index f98f161e8093..78deee92bba5 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -407,7 +407,9 @@ fn fn_abi_sanity_check<'tcx>( // `layout.backend_repr` and ignore everything else. We should just reject //`Aggregate` entirely here, but some targets need to be fixed first. match arg.layout.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => {} + BackendRepr::Scalar(_) + | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } => {} BackendRepr::ScalarPair(..) => { panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty) } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 3a935b917ea2..6962eeddf137 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -3,8 +3,8 @@ use rustc_abi::Integer::{I8, I32}; use rustc_abi::Primitive::{self, Float, Int, Pointer}; use rustc_abi::{ AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Layout, - LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding, - VariantIdx, Variants, WrappingRange, + LayoutCalculatorError, LayoutData, Niche, ReprOptions, ScalableElt, Scalar, Size, StructKind, + TagEncoding, VariantIdx, Variants, WrappingRange, }; use rustc_hashes::Hash64; use rustc_hir::attrs::AttributeKind; @@ -567,6 +567,37 @@ fn layout_of_uncached<'tcx>( univariant(tys, kind)? } + // Scalable vector types + // + // ```rust (ignore, example) + // #[rustc_scalable_vector(3)] + // struct svuint32_t(u32); + // ``` + ty::Adt(def, args) + if matches!(def.repr().scalable, Some(ScalableElt::ElementCount(..))) => + { + let Some(element_ty) = def + .is_struct() + .then(|| &def.variant(FIRST_VARIANT).fields) + .filter(|fields| fields.len() == 1) + .map(|fields| fields[FieldIdx::ZERO].ty(tcx, args)) + else { + let guar = tcx + .dcx() + .delayed_bug("#[rustc_scalable_vector] was applied to an invalid type"); + return Err(error(cx, LayoutError::ReferencesError(guar))); + }; + let Some(ScalableElt::ElementCount(element_count)) = def.repr().scalable else { + let guar = tcx + .dcx() + .delayed_bug("#[rustc_scalable_vector] was applied to an invalid type"); + return Err(error(cx, LayoutError::ReferencesError(guar))); + }; + + let element_layout = cx.layout_of(element_ty)?; + map_layout(cx.calc.scalable_vector_type(element_layout, element_count as u64))? + } + // SIMD vector types. ty::Adt(def, args) if def.repr().simd() => { // Supported SIMD vectors are ADTs with a single array field: diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index 01435f7e67a4..b013902f3fe3 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -250,7 +250,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou // And the size has to be element * count plus alignment padding, of course assert!(size == (element_size * count).align_to(align)); } - BackendRepr::Memory { .. } => {} // Nothing to check. + BackendRepr::Memory { .. } | BackendRepr::ScalableVector { .. } => {} // Nothing to check. } } diff --git a/tests/codegen-llvm/scalable-vectors/simple.rs b/tests/codegen-llvm/scalable-vectors/simple.rs new file mode 100644 index 000000000000..b3530e19ff33 --- /dev/null +++ b/tests/codegen-llvm/scalable-vectors/simple.rs @@ -0,0 +1,49 @@ +//@ edition: 2021 +//@ only-aarch64 +#![crate_type = "lib"] +#![allow(incomplete_features, internal_features)] +#![feature(simd_ffi, rustc_attrs, link_llvm_intrinsics)] + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[inline(never)] +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; + } + unsafe { _svdup_n_s32(op) } +} + +#[inline] +#[target_feature(enable = "sve,sve2")] +pub unsafe fn svxar_n_s32(op1: svint32_t, op2: svint32_t) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.xar.nxv4i32")] + fn _svxar_n_s32(op1: svint32_t, op2: svint32_t, imm3: i32) -> svint32_t; + } + unsafe { _svxar_n_s32(op1, op2, IMM3) } +} + +#[inline(never)] +#[no_mangle] +#[target_feature(enable = "sve,sve2")] +// CHECK: define @pass_as_ref(ptr {{.*}}align 16{{.*}} %a, %b) +pub unsafe fn pass_as_ref(a: &svint32_t, b: svint32_t) -> svint32_t { + // CHECK: load , ptr %a, align 16 + svxar_n_s32::<1>(*a, b) +} + +#[no_mangle] +#[target_feature(enable = "sve,sve2")] +// CHECK: define @test() +pub unsafe fn test() -> svint32_t { + let a = svdup_n_s32(1); + let b = svdup_n_s32(2); + // CHECK: %_0 = call @pass_as_ref(ptr {{.*}}align 16{{.*}} %a, %b) + pass_as_ref(&a, b) +} diff --git a/tests/ui/scalable-vectors/closure-capture.rs b/tests/ui/scalable-vectors/closure-capture.rs new file mode 100644 index 000000000000..d6a45f76e214 --- /dev/null +++ b/tests/ui/scalable-vectors/closure-capture.rs @@ -0,0 +1,51 @@ +//@ compile-flags: --crate-type=lib +//@ only-aarch64 + +#![allow(incomplete_features, internal_features)] +#![feature( + link_llvm_intrinsics, + rustc_attrs, + simd_ffi +)] + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[inline(never)] +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; + } + unsafe { _svdup_n_s32(op) } +} + +#[inline] +#[target_feature(enable = "sve,sve2")] +pub unsafe fn svxar_n_s32(op1: svint32_t, op2: svint32_t) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.xar.nxv4i32")] + fn _svxar_n_s32(op1: svint32_t, op2: svint32_t, imm3: i32) -> svint32_t; + } + unsafe { _svxar_n_s32(op1, op2, IMM3) } +} + +#[inline(never)] +#[target_feature(enable = "sve,sve2")] +fn run(f: impl Fn() -> ()) { + f(); +} + +#[target_feature(enable = "sve,sve2")] +fn foo() { + unsafe { + let a = svdup_n_s32(42); + run(move || { +//~^ ERROR: scalable vectors cannot be tuple fields + svxar_n_s32::<2>(a, a); + }); + } +} diff --git a/tests/ui/scalable-vectors/closure-capture.stderr b/tests/ui/scalable-vectors/closure-capture.stderr new file mode 100644 index 000000000000..ea53066988e5 --- /dev/null +++ b/tests/ui/scalable-vectors/closure-capture.stderr @@ -0,0 +1,8 @@ +error: scalable vectors cannot be tuple fields + --> $DIR/closure-capture.rs:46:9 + | +LL | run(move || { + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/scalable-vectors/copy-clone.rs b/tests/ui/scalable-vectors/copy-clone.rs new file mode 100644 index 000000000000..7576b6ec18dc --- /dev/null +++ b/tests/ui/scalable-vectors/copy-clone.rs @@ -0,0 +1,31 @@ +//@ build-pass +//@ only-aarch64 +#![feature(simd_ffi, rustc_attrs, link_llvm_intrinsics)] + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; +//~^ WARN: `extern` block uses type `svint32_t`, which is not FFI-safe + } + unsafe { _svdup_n_s32(op) } +} + +#[target_feature(enable = "sve")] +fn require_copy(t: T) {} + +#[target_feature(enable = "sve")] +fn test() { + unsafe { + let a = svdup_n_s32(1); + require_copy(a); + } +} + +fn main() {} diff --git a/tests/ui/scalable-vectors/copy-clone.stderr b/tests/ui/scalable-vectors/copy-clone.stderr new file mode 100644 index 000000000000..8b07aba8e1c0 --- /dev/null +++ b/tests/ui/scalable-vectors/copy-clone.stderr @@ -0,0 +1,17 @@ +warning: `extern` block uses type `svint32_t`, which is not FFI-safe + --> $DIR/copy-clone.rs:14:37 + | +LL | fn _svdup_n_s32(op: i32) -> svint32_t; + | ^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/copy-clone.rs:8:1 + | +LL | pub struct svint32_t(i32); + | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(improper_ctypes)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/scalable-vectors/fn-trait.rs b/tests/ui/scalable-vectors/fn-trait.rs new file mode 100644 index 000000000000..5203b5fa0efd --- /dev/null +++ b/tests/ui/scalable-vectors/fn-trait.rs @@ -0,0 +1,13 @@ +#![allow(internal_features)] +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(4)] +pub struct ScalableSimdFloat(f32); + +unsafe fn test(f: T) +where + T: Fn(ScalableSimdFloat), //~ ERROR: scalable vectors cannot be tuple fields +{ +} + +fn main() {} diff --git a/tests/ui/scalable-vectors/fn-trait.stderr b/tests/ui/scalable-vectors/fn-trait.stderr new file mode 100644 index 000000000000..4d00272dd1b5 --- /dev/null +++ b/tests/ui/scalable-vectors/fn-trait.stderr @@ -0,0 +1,8 @@ +error: scalable vectors cannot be tuple fields + --> $DIR/fn-trait.rs:9:8 + | +LL | T: Fn(ScalableSimdFloat), + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/scalable-vectors/value-type.rs b/tests/ui/scalable-vectors/value-type.rs new file mode 100644 index 000000000000..31a9ee8344eb --- /dev/null +++ b/tests/ui/scalable-vectors/value-type.rs @@ -0,0 +1,37 @@ +//@ build-pass +//@ compile-flags: --crate-type=lib +//@ only-aarch64 +#![allow(internal_features)] +#![feature( + link_llvm_intrinsics, + rustc_attrs, + simd_ffi, +)] + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; +//~^ WARN: `extern` block uses type `svint32_t`, which is not FFI-safe + } + unsafe { _svdup_n_s32(op) } +} + +// Tests that scalable vectors can be locals, arguments and return types. + +#[target_feature(enable = "sve")] +fn id(v: svint32_t) -> svint32_t { v } + +#[target_feature(enable = "sve")] +fn foo() { + unsafe { + let v = svdup_n_s32(1); + let v = id(v); + } +} diff --git a/tests/ui/scalable-vectors/value-type.stderr b/tests/ui/scalable-vectors/value-type.stderr new file mode 100644 index 000000000000..3fc90ebd874e --- /dev/null +++ b/tests/ui/scalable-vectors/value-type.stderr @@ -0,0 +1,17 @@ +warning: `extern` block uses type `svint32_t`, which is not FFI-safe + --> $DIR/value-type.rs:20:37 + | +LL | fn _svdup_n_s32(op: i32) -> svint32_t; + | ^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/value-type.rs:14:1 + | +LL | pub struct svint32_t(i32); + | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(improper_ctypes)]` on by default + +warning: 1 warning emitted + From 89eea57594e3e1d8e618dd530ea1c8e7c9b4c7a4 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 10 Jul 2025 10:17:53 +0000 Subject: [PATCH 0870/3801] debuginfo: no spill `` for `N!=16` LLVM doesn't handle stores on `` for `N != 16`, a type used internally in SVE intrinsics. Spilling to the stack to create debuginfo will cause errors during instruction selection. These types that are an internal implementation detail to the intrinsic, so users should never see them types and won't need any debuginfo. Co-authored-by: Jamie Cunliffe --- .../rustc_codegen_ssa/src/mir/debuginfo.rs | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 0c9acf087f9f..f068a51f7d4a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -2,7 +2,7 @@ use std::collections::hash_map::Entry; use std::marker::PhantomData; use std::ops::Range; -use rustc_abi::{BackendRepr, FieldIdx, FieldsShape, Size, VariantIdx}; +use rustc_abi::{BackendRepr, FieldIdx, FieldsShape, ScalableElt, Size, VariantIdx}; use rustc_data_structures::fx::FxHashMap; use rustc_index::IndexVec; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; @@ -408,6 +408,49 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } + // Don't spill `` for `N != 16`: + // + // SVE predicates are only one bit for each byte in an SVE vector (which makes + // sense, the predicate only needs to keep track of whether a lane is + // enabled/disabled). i.e. a `` vector has a `` + // predicate type. `` corresponds to two bytes of storage, + // multiplied by the `vscale`, with one bit for each of the sixteen lanes. + // + // For a vector with fewer elements, such as `svint32_t`/``, + // while only a `` predicate type would be strictly necessary, + // relevant intrinsics still take a `svbool_t`/`` - this is + // because a `` is only half of a byte (for `vscale=1`), and with + // memory being byte-addressable, it's unclear how to store that. + // + // Due to this, LLVM ultimately decided not to support stores of `` + // for `N != 16`. As for `vscale=1` and `N` fewer than sixteen, partial bytes would + // need to be stored (except for `N=8`, but that also isn't supported). `N` can + // never be greater than sixteen as that ends up larger than the 128-bit increment + // size. + // + // Internally, with an intrinsic operating on a `svint32_t`/`` + // (for example), the intrinsic takes the `svbool_t`/`` predicate + // and casts it to a `svbool4_t`/``. Therefore, it's important that + // the `` never spills because that'll cause errors during + // instruction selection. Spilling to the stack to create debuginfo for these + // intermediate values must be avoided and won't degrade the debugging experience + // anyway. + if operand.layout.ty.is_scalable_vector() + && bx.sess().target.arch == rustc_target::spec::Arch::AArch64 + && let ty::Adt(adt, args) = &operand.layout.ty.kind() + && let Some(marker_type_field) = + adt.non_enum_variant().fields.get(FieldIdx::from_u32(0)) + { + let marker_type = marker_type_field.ty(bx.tcx(), args); + // i.e. `` when `N != 16` + if let ty::Slice(element_ty) = marker_type.kind() + && element_ty.is_bool() + && adt.repr().scalable != Some(ScalableElt::ElementCount(16)) + { + return; + } + } + Self::spill_operand_to_stack(*operand, name, bx) } From 4185e9f2ecea8b11fb17f543a98b65c1047da1b2 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 10 Jul 2025 06:18:13 +0000 Subject: [PATCH 0871/3801] mir_transform: prohibit scalable vectors in async Scalable vectors cannot be members of ADTs and thus cannot be kept over await points in async functions. --- compiler/rustc_mir_transform/src/coroutine.rs | 10 +++++ tests/ui/scalable-vectors/async.rs | 44 +++++++++++++++++++ tests/ui/scalable-vectors/async.stderr | 8 ++++ 3 files changed, 62 insertions(+) create mode 100644 tests/ui/scalable-vectors/async.rs create mode 100644 tests/ui/scalable-vectors/async.stderr diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 072733c97efb..7fad380ba5a1 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1891,6 +1891,16 @@ fn check_must_not_suspend_ty<'tcx>( SuspendCheckData { descr_pre: &format!("{}allocator ", data.descr_pre), ..data }, ) } + // FIXME(sized_hierarchy): This should be replaced with a requirement that types in + // coroutines implement `const Sized`. Scalable vectors are temporarily `Sized` while + // `feature(sized_hierarchy)` is not fully implemented, but in practice are + // non-`const Sized` and so do not have a known size at compilation time. Layout computation + // for a coroutine containing scalable vectors would be incorrect. + ty::Adt(def, _) if def.repr().scalable() => { + tcx.dcx() + .span_err(data.source_span, "scalable vectors cannot be held over await points"); + true + } ty::Adt(def, _) => check_must_not_suspend_def(tcx, def.did(), hir_id, data), // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { diff --git a/tests/ui/scalable-vectors/async.rs b/tests/ui/scalable-vectors/async.rs new file mode 100644 index 000000000000..916c64ee7435 --- /dev/null +++ b/tests/ui/scalable-vectors/async.rs @@ -0,0 +1,44 @@ +//@ only-aarch64 +//@ edition:2021 + +#![allow(incomplete_features, internal_features)] +#![feature( + core_intrinsics, + simd_ffi, + rustc_attrs, + link_llvm_intrinsics +)] + +use core::intrinsics::transmute_unchecked; + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; + } + unsafe { _svdup_n_s32(op) } +} + +#[target_feature(enable = "sve")] +async fn another() -> i32 { + 42 +} + +#[no_mangle] +#[target_feature(enable = "sve")] +pub async fn test_function() { + unsafe { + let x = svdup_n_s32(1); //~ ERROR: scalable vectors cannot be held over await points + let temp = another().await; + let y: svint32_t = transmute_unchecked(x); + } +} + +fn main() { + let _ = unsafe { test_function() }; +} diff --git a/tests/ui/scalable-vectors/async.stderr b/tests/ui/scalable-vectors/async.stderr new file mode 100644 index 000000000000..fa81c7b8ed4d --- /dev/null +++ b/tests/ui/scalable-vectors/async.stderr @@ -0,0 +1,8 @@ +error: scalable vectors cannot be held over await points + --> $DIR/async.rs:36:13 + | +LL | let x = svdup_n_s32(1); + | ^ + +error: aborting due to 1 previous error + From 11bc2e0907f3bec4a1a955c76bceaa799d8489f4 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 10 Jul 2025 10:17:44 +0000 Subject: [PATCH 0872/3801] codegen: implement `repr(scalable)` Introduces `BackendRepr::ScalableVector` corresponding to scalable vector types annotated with `repr(scalable)` which lowers to a scalable vector type in LLVM. Co-authored-by: Jamie Cunliffe --- src/builder.rs | 4 ++++ src/intrinsic/mod.rs | 2 +- src/type_of.rs | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index df1e64c75b96..79228c20d292 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -943,6 +943,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { .get_address(self.location) } + fn scalable_alloca(&mut self, _elt: u64, _align: Align, _element_ty: Ty<'_>) -> RValue<'gcc> { + todo!() + } + fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { let block = self.llbb(); let function = block.get_function(); diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index a38dcf8e4c93..d2714ba7914f 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -504,7 +504,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - SimdVector { .. } => false, + SimdVector { .. } | ScalableVector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/src/type_of.rs b/src/type_of.rs index 93202483eed8..68fca5a17ad3 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -85,6 +85,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( ); } BackendRepr::Memory { .. } => {} + BackendRepr::ScalableVector { .. } => todo!(), } let name = match *layout.ty.kind() { @@ -179,6 +180,8 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, + // FIXME(rustc_scalable_vector): Not yet implemented in rustc_codegen_gcc. + BackendRepr::ScalableVector { .. } => todo!(), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -188,6 +191,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { BackendRepr::ScalarPair(..) => true, BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } | BackendRepr::Memory { .. } => false, } } From 5f27abdbc85c3fcaec27ed6e2046841edf2f98d1 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 10 Jul 2025 08:46:19 +0000 Subject: [PATCH 0873/3801] mono: require target feature for scalable vectors Scalable vector types only work with the relevant target features enabled, so require this for any function with the types in its signature. --- compiler/rustc_monomorphize/messages.ftl | 5 +- compiler/rustc_monomorphize/src/errors.rs | 2 + .../src/mono_checks/abi_check.rs | 98 ++++++++++++++----- compiler/rustc_target/src/target_features.rs | 75 ++++++++------ .../require-target-feature.rs | 40 ++++++++ .../require-target-feature.stderr | 25 +++++ 6 files changed, 190 insertions(+), 55 deletions(-) create mode 100644 tests/ui/scalable-vectors/require-target-feature.rs create mode 100644 tests/ui/scalable-vectors/require-target-feature.stderr diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index bfb2edf286a2..edb91d8f2eda 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -2,7 +2,10 @@ monomorphize_abi_error_disabled_vector_type = this function {$is_call -> [true] call *[false] definition - } uses SIMD vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled{$is_call -> + } uses {$is_scalable -> + [true] scalable + *[false] SIMD + } vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled{$is_call -> [true] {" "}in the caller *[false] {""} } diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index a5040ef22dd0..4949d9ae3922 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -78,6 +78,8 @@ pub(crate) struct AbiErrorDisabledVectorType<'a> { pub ty: Ty<'a>, /// Whether this is a problem at a call site or at a declaration. pub is_call: bool, + /// Whether this is a problem with a fixed length vector or a scalable vector + pub is_scalable: bool, } #[derive(Diagnostic)] diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index 60859f94f9bd..a5f2ba2f1ced 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -10,14 +10,37 @@ use rustc_target::callconv::{FnAbi, PassMode}; use crate::errors; -fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool { +/// Are vector registers used? +enum UsesVectorRegisters { + /// e.g. `neon` + FixedVector, + /// e.g. `sve` + ScalableVector, + No, +} + +/// Determines whether the combination of `mode` and `repr` will use fixed vector registers, +/// scalable vector registers or no vector registers. +fn passes_vectors_by_value(mode: &PassMode, repr: &BackendRepr) -> UsesVectorRegisters { match mode { - PassMode::Ignore | PassMode::Indirect { .. } => false, - PassMode::Cast { pad_i32: _, cast } => { - cast.prefix.iter().any(|r| r.is_some_and(|x| x.kind == RegKind::Vector)) - || cast.rest.unit.kind == RegKind::Vector + PassMode::Ignore | PassMode::Indirect { .. } => UsesVectorRegisters::No, + PassMode::Cast { pad_i32: _, cast } + if cast.prefix.iter().any(|r| r.is_some_and(|x| x.kind == RegKind::Vector)) + || cast.rest.unit.kind == RegKind::Vector => + { + UsesVectorRegisters::FixedVector } - PassMode::Direct(..) | PassMode::Pair(..) => matches!(repr, BackendRepr::SimdVector { .. }), + PassMode::Direct(..) | PassMode::Pair(..) + if matches!(repr, BackendRepr::SimdVector { .. }) => + { + UsesVectorRegisters::FixedVector + } + PassMode::Direct(..) | PassMode::Pair(..) + if matches!(repr, BackendRepr::ScalableVector { .. }) => + { + UsesVectorRegisters::ScalableVector + } + _ => UsesVectorRegisters::No, } } @@ -32,37 +55,60 @@ fn do_check_simd_vector_abi<'tcx>( is_call: bool, loc: impl Fn() -> (Span, HirId), ) { - let feature_def = tcx.sess.target.features_for_correct_vector_abi(); let codegen_attrs = tcx.codegen_fn_attrs(def_id); let have_feature = |feat: Symbol| { - tcx.sess.unstable_target_features.contains(&feat) - || codegen_attrs.target_features.iter().any(|x| x.name == feat) + let target_feats = tcx.sess.unstable_target_features.contains(&feat); + let fn_feats = codegen_attrs.target_features.iter().any(|x| x.name == feat); + target_feats || fn_feats }; for arg_abi in abi.args.iter().chain(std::iter::once(&abi.ret)) { let size = arg_abi.layout.size; - if uses_vector_registers(&arg_abi.mode, &arg_abi.layout.backend_repr) { - // Find the first feature that provides at least this vector size. - let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) { - Some((_, feature)) => feature, - None => { + match passes_vectors_by_value(&arg_abi.mode, &arg_abi.layout.backend_repr) { + UsesVectorRegisters::FixedVector => { + let feature_def = tcx.sess.target.features_for_correct_fixed_length_vector_abi(); + // Find the first feature that provides at least this vector size. + let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) { + Some((_, feature)) => feature, + None => { + let (span, _hir_id) = loc(); + tcx.dcx().emit_err(errors::AbiErrorUnsupportedVectorType { + span, + ty: arg_abi.layout.ty, + is_call, + }); + continue; + } + }; + if !feature.is_empty() && !have_feature(Symbol::intern(feature)) { let (span, _hir_id) = loc(); - tcx.dcx().emit_err(errors::AbiErrorUnsupportedVectorType { + tcx.dcx().emit_err(errors::AbiErrorDisabledVectorType { span, + required_feature: feature, ty: arg_abi.layout.ty, is_call, + is_scalable: false, }); - continue; } - }; - if !feature.is_empty() && !have_feature(Symbol::intern(feature)) { - // Emit error. - let (span, _hir_id) = loc(); - tcx.dcx().emit_err(errors::AbiErrorDisabledVectorType { - span, - required_feature: feature, - ty: arg_abi.layout.ty, - is_call, - }); + } + UsesVectorRegisters::ScalableVector => { + let Some(required_feature) = + tcx.sess.target.features_for_correct_scalable_vector_abi() + else { + continue; + }; + if !required_feature.is_empty() && !have_feature(Symbol::intern(required_feature)) { + let (span, _) = loc(); + tcx.dcx().emit_err(errors::AbiErrorDisabledVectorType { + span, + required_feature, + ty: arg_abi.layout.ty, + is_call, + is_scalable: true, + }); + } + } + UsesVectorRegisters::No => { + continue; } } } diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index d9d03cc2b5e8..e516a31d1e66 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -911,18 +911,24 @@ pub fn all_rust_features() -> impl Iterator { // These arrays represent the least-constraining feature that is required for vector types up to a // certain size to have their "proper" ABI on each architecture. // Note that they must be kept sorted by vector size. -const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = +const X86_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "sse"), (256, "avx"), (512, "avx512f")]; // FIXME: might need changes for AVX10. -const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")]; +const AARCH64_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = + &[(128, "neon")]; // We might want to add "helium" too. -const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")]; +const ARM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = + &[(128, "neon")]; -const AMDGPU_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(1024, "")]; -const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")]; -const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")]; -const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")]; -const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[ +const AMDGPU_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = + &[(1024, "")]; +const POWERPC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = + &[(128, "altivec")]; +const WASM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = + &[(128, "simd128")]; +const S390X_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = + &[(128, "vector")]; +const RISCV_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = &[ (32, "zvl32b"), (64, "zvl64b"), (128, "zvl128b"), @@ -937,13 +943,16 @@ const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[ (65536, "zvl65536b"), ]; // Always error on SPARC, as the necessary target features cannot be enabled in Rust at the moment. -const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(64, "vis")*/]; +const SPARC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = + &[/*(64, "vis")*/]; -const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = +const HEXAGON_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(512, "hvx-length64b"),*/ (1024, "hvx-length128b")]; -const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")]; -const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")]; -const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = +const MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = + &[(128, "msa")]; +const CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = + &[(128, "vdspv1")]; +const LOONGARCH_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "lsx"), (256, "lasx")]; #[derive(Copy, Clone, Debug)] @@ -982,24 +991,26 @@ impl Target { } } - pub fn features_for_correct_vector_abi(&self) -> &'static [(u64, &'static str)] { + pub fn features_for_correct_fixed_length_vector_abi(&self) -> &'static [(u64, &'static str)] { match &self.arch { - Arch::X86 | Arch::X86_64 => X86_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::Arm => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::LoongArch32 | Arch::LoongArch64 => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::S390x => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::Hexagon => HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI, - Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => { - MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI + Arch::X86 | Arch::X86_64 => X86_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, + Arch::AArch64 | Arch::Arm64EC => AARCH64_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, + Arch::Arm => ARM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, + Arch::PowerPC | Arch::PowerPC64 => POWERPC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, + Arch::LoongArch32 | Arch::LoongArch64 => { + LOONGARCH_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI } - Arch::AmdGpu => AMDGPU_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::RiscV32 | Arch::RiscV64 => RISCV_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, + Arch::Wasm32 | Arch::Wasm64 => WASM_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, + Arch::S390x => S390X_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, + Arch::Sparc | Arch::Sparc64 => SPARC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, + Arch::Hexagon => HEXAGON_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, + Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => { + MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI + } + Arch::AmdGpu => AMDGPU_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, Arch::Nvptx64 | Arch::Bpf | Arch::M68k => &[], // no vector ABI - Arch::CSky => CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI, + Arch::CSky => CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI, // FIXME: for some tier3 targets, we are overly cautious and always give warnings // when passing args in vector registers. Arch::Avr @@ -1011,6 +1022,14 @@ impl Target { } } + pub fn features_for_correct_scalable_vector_abi(&self) -> Option<&'static str> { + match &self.arch { + Arch::AArch64 | Arch::Arm64EC => Some("sve"), + // Other targets have no scalable vectors or they are unimplemented. + _ => None, + } + } + pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] { match &self.arch { Arch::AArch64 | Arch::Arm64EC => AARCH64_TIED_FEATURES, diff --git a/tests/ui/scalable-vectors/require-target-feature.rs b/tests/ui/scalable-vectors/require-target-feature.rs new file mode 100644 index 000000000000..b3c1d3e51007 --- /dev/null +++ b/tests/ui/scalable-vectors/require-target-feature.rs @@ -0,0 +1,40 @@ +//@ build-fail +//@ compile-flags: --crate-type=lib +//@ only-aarch64 +#![allow(incomplete_features, internal_features)] +#![feature( + simd_ffi, + rustc_attrs, + link_llvm_intrinsics +)] + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[inline(never)] +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; +//~^ WARN: `extern` block uses type `svint32_t`, which is not FFI-safe + } + unsafe { _svdup_n_s32(op) } +} + +pub fn non_annotated_callee(x: svint32_t) {} +//~^ ERROR: this function definition uses scalable vector type `svint32_t` + +#[target_feature(enable = "sve")] +pub fn annotated_callee(x: svint32_t) {} // okay! + +#[target_feature(enable = "sve")] +pub fn caller() { + unsafe { + let a = svdup_n_s32(42); + non_annotated_callee(a); + annotated_callee(a); + } +} diff --git a/tests/ui/scalable-vectors/require-target-feature.stderr b/tests/ui/scalable-vectors/require-target-feature.stderr new file mode 100644 index 000000000000..85b9e5b6579c --- /dev/null +++ b/tests/ui/scalable-vectors/require-target-feature.stderr @@ -0,0 +1,25 @@ +warning: `extern` block uses type `svint32_t`, which is not FFI-safe + --> $DIR/require-target-feature.rs:21:37 + | +LL | fn _svdup_n_s32(op: i32) -> svint32_t; + | ^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/require-target-feature.rs:14:1 + | +LL | pub struct svint32_t(i32); + | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(improper_ctypes)]` on by default + +error: this function definition uses scalable vector type `svint32_t` which (with the chosen ABI) requires the `sve` target feature, which is not enabled + --> $DIR/require-target-feature.rs:27:1 + | +LL | pub fn non_annotated_callee(x: svint32_t) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = help: consider enabling it globally (`-C target-feature=+sve`) or locally (`#[target_feature(enable="sve")]`) + +error: aborting due to 1 previous error; 1 warning emitted + From f0dfeab43dae26a8406d78d883a7be0ad3824f24 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 11 Dec 2025 12:22:53 +0000 Subject: [PATCH 0874/3801] abi: `Display` bound on `TyAbiInterface` The `fmt::Debug` impl for `TyAndLayout<'a, Ty>'` requires `fmt::Display` on the `Ty` parameter. In `ArgAbi`, `TyAndLayout`'s Ty` is instantiated with a parameter that implements `TyAbiInterface`. `TyAbiInterface` only required `fmt::Debug` be implemented on `Self`, not `fmt::Display`, which meant that it wasn't actually possible to debug print `ArgAbi`. --- compiler/rustc_abi/src/callconv.rs | 1 + compiler/rustc_abi/src/layout/ty.rs | 2 +- compiler/rustc_target/src/callconv/aarch64.rs | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs index 1664b3003095..5b43a6c5881d 100644 --- a/compiler/rustc_abi/src/callconv.rs +++ b/compiler/rustc_abi/src/callconv.rs @@ -60,6 +60,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// This is public so that it can be used in unit tests, but /// should generally only be relevant to the ABI details of /// specific targets. + #[tracing::instrument(skip(cx), level = "debug")] pub fn homogeneous_aggregate(&self, cx: &C) -> Result where Ty: TyAbiInterface<'a, C> + Copy, diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index a384eddc0b52..41ad14f550ab 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -155,7 +155,7 @@ impl<'a, Ty> AsRef> for TyAndLayout<'a, Ty> { /// Trait that needs to be implemented by the higher-level type representation /// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality. -pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug { +pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug + std::fmt::Display { fn ty_and_layout_for_variant( this: TyAndLayout<'a, Self>, cx: &C, diff --git a/compiler/rustc_target/src/callconv/aarch64.rs b/compiler/rustc_target/src/callconv/aarch64.rs index b38d45551553..13be3888611f 100644 --- a/compiler/rustc_target/src/callconv/aarch64.rs +++ b/compiler/rustc_target/src/callconv/aarch64.rs @@ -9,13 +9,14 @@ use crate::spec::{Abi, HasTargetSpec, Target}; /// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI. /// /// Corresponds to Clang's `AArch64ABIInfo::ABIKind`. -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq)] pub(crate) enum AbiKind { AAPCS, DarwinPCS, Win64, } +#[tracing::instrument(skip(cx), level = "debug")] fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option where Ty: TyAbiInterface<'a, C> + Copy, @@ -73,6 +74,7 @@ fn softfloat_float_abi(target: &Target, arg: &mut ArgAbi<'_, Ty>) { } } +#[tracing::instrument(skip(cx), level = "debug")] fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, kind: AbiKind) where Ty: TyAbiInterface<'a, C> + Copy, @@ -105,6 +107,7 @@ where ret.make_indirect(); } +#[tracing::instrument(skip(cx), level = "debug")] fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, kind: AbiKind) where Ty: TyAbiInterface<'a, C> + Copy, From 6d6068f6c5b371b91e51289e5e875f8df75e5def Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 16 Dec 2025 10:42:14 +0000 Subject: [PATCH 0875/3801] stabilize annotate-snippet as default formatter --- compiler/rustc_errors/src/emitter.rs | 13 +++--- compiler/rustc_errors/src/json.rs | 47 ++++++--------------- compiler/rustc_errors/src/json/tests.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/config.rs | 55 ++++++------------------- compiler/rustc_session/src/session.rs | 27 ++---------- src/librustdoc/config.rs | 12 ++---- src/librustdoc/core.rs | 15 +------ src/librustdoc/doctest.rs | 2 +- 9 files changed, 42 insertions(+), 133 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 78feb60261bd..2e41f74ee25d 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -46,17 +46,14 @@ const DEFAULT_COLUMN_WIDTH: usize = 140; /// Describes the way the content of the `rendered` field of the json output is generated #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum HumanReadableErrorType { - Default { short: bool }, - AnnotateSnippet { short: bool, unicode: bool }, +pub struct HumanReadableErrorType { + pub short: bool, + pub unicode: bool, } impl HumanReadableErrorType { pub fn short(&self) -> bool { - match self { - HumanReadableErrorType::Default { short } - | HumanReadableErrorType::AnnotateSnippet { short, .. } => *short, - } + self.short } } @@ -607,7 +604,7 @@ pub enum OutputTheme { Unicode, } -/// Handles the writing of `HumanReadableErrorType::Default` and `HumanReadableErrorType::Short` +/// Handles the writing of `HumanReadableErrorType` #[derive(Setters)] pub struct HumanEmitter { #[setters(skip)] diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 3b8c8baa5eff..85801245bea9 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -28,8 +28,8 @@ use serde::Serialize; use crate::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use crate::diagnostic::IsLint; use crate::emitter::{ - ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType, OutputTheme, - TimingEvent, should_show_source_code, + ColorConfig, Destination, Emitter, HumanReadableErrorType, OutputTheme, TimingEvent, + should_show_source_code, }; use crate::registry::Registry; use crate::timings::{TimingRecord, TimingSection}; @@ -378,38 +378,17 @@ impl Diagnostic { choice => choice, }, ); - match je.json_rendered { - HumanReadableErrorType::AnnotateSnippet { short, unicode } => { - AnnotateSnippetEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks( - je.ignored_directories_in_source_blocks.clone(), - ) - .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) - .emit_diagnostic(diag, registry) - } - HumanReadableErrorType::Default { short } => { - HumanEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks( - je.ignored_directories_in_source_blocks.clone(), - ) - .theme(OutputTheme::Ascii) - .emit_diagnostic(diag, registry) - } - } + AnnotateSnippetEmitter::new(dst, je.translator.clone()) + .short_message(je.json_rendered.short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone()) + .theme(if je.json_rendered.unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .emit_diagnostic(diag, registry); let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); let buf = String::from_utf8(buf).unwrap(); diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 30be06ae0bd3..c1c9ecf7198f 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -54,7 +54,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { Some(sm), translator, true, // pretty - HumanReadableErrorType::Default { short: true }, + HumanReadableErrorType { short: true, unicode: false }, ColorConfig::Never, ); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 89b8a5fddb89..8dab3a7f37f5 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -321,7 +321,7 @@ fn test_search_paths_tracking_hash_different_order() { let early_dcx = EarlyDiagCtxt::new(JSON); const JSON: ErrorOutputType = ErrorOutputType::Json { pretty: false, - json_rendered: HumanReadableErrorType::Default { short: false }, + json_rendered: HumanReadableErrorType { short: false, unicode: false }, color_config: ColorConfig::Never, }; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index be4b36e3b926..5b2ae59aba40 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -806,7 +806,7 @@ pub enum ErrorOutputType { /// Output meant for the consumption of humans. #[default] HumanReadable { - kind: HumanReadableErrorType = HumanReadableErrorType::Default { short: false }, + kind: HumanReadableErrorType = HumanReadableErrorType { short: false, unicode: false }, color_config: ColorConfig = ColorConfig::Auto, }, /// Output that's consumed by other tools such as `rustfix` or the `RLS`. @@ -1965,16 +1965,8 @@ impl JsonUnusedExterns { /// /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. -pub fn parse_json( - early_dcx: &EarlyDiagCtxt, - matches: &getopts::Matches, - is_nightly_build: bool, -) -> JsonConfig { - let mut json_rendered = if is_nightly_build { - HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } - } else { - HumanReadableErrorType::Default { short: false } - }; +pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig { + let mut json_rendered = HumanReadableErrorType { short: false, unicode: false }; let mut json_color = ColorConfig::Never; let mut json_artifact_notifications = false; let mut json_unused_externs = JsonUnusedExterns::No; @@ -1991,15 +1983,10 @@ pub fn parse_json( for sub_option in option.split(',') { match sub_option { "diagnostic-short" => { - json_rendered = if is_nightly_build { - HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } - } else { - HumanReadableErrorType::Default { short: true } - }; + json_rendered = HumanReadableErrorType { short: true, unicode: false }; } "diagnostic-unicode" => { - json_rendered = - HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }; + json_rendered = HumanReadableErrorType { short: false, unicode: true }; } "diagnostic-rendered-ansi" => json_color = ColorConfig::Always, "artifacts" => json_artifact_notifications = true, @@ -2029,13 +2016,8 @@ pub fn parse_error_format( color_config: ColorConfig, json_color: ColorConfig, json_rendered: HumanReadableErrorType, - is_nightly_build: bool, ) -> ErrorOutputType { - let default_kind = if is_nightly_build { - HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } - } else { - HumanReadableErrorType::Default { short: false } - }; + let default_kind = HumanReadableErrorType { short: false, unicode: false }; // We need the `opts_present` check because the driver will send us Matches // with only stable options if no unstable options are used. Since error-format // is unstable, it will not be present. We have to use `opts_present` not @@ -2046,7 +2028,7 @@ pub fn parse_error_format( ErrorOutputType::HumanReadable { color_config, kind: default_kind } } Some("human-annotate-rs") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false }, + kind: HumanReadableErrorType { short: false, unicode: false }, color_config, }, Some("json") => { @@ -2056,15 +2038,11 @@ pub fn parse_error_format( ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color } } Some("short") => ErrorOutputType::HumanReadable { - kind: if is_nightly_build { - HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } - } else { - HumanReadableErrorType::Default { short: true } - }, + kind: HumanReadableErrorType { short: true, unicode: false }, color_config, }, Some("human-unicode") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }, + kind: HumanReadableErrorType { short: false, unicode: true }, color_config, }, Some(arg) => { @@ -2136,8 +2114,8 @@ fn check_error_format_stability( let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", ErrorOutputType::HumanReadable { kind, .. } => match kind { - HumanReadableErrorType::AnnotateSnippet { unicode: false, .. } => "human-annotate-rs", - HumanReadableErrorType::AnnotateSnippet { unicode: true, .. } => "human-unicode", + HumanReadableErrorType { unicode: false, .. } => "human-annotate-rs", + HumanReadableErrorType { unicode: true, .. } => "human-unicode", _ => return, }, _ => return, @@ -2465,16 +2443,9 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M json_timings, json_unused_externs, json_future_incompat, - } = parse_json(early_dcx, matches, unstable_features.is_nightly_build()); + } = parse_json(early_dcx, matches); - let error_format = parse_error_format( - early_dcx, - matches, - color, - json_color, - json_rendered, - unstable_features.is_nightly_build(), - ); + let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered); early_dcx.set_error_format(error_format); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 14b80099bafe..1a0ec600af47 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -13,9 +13,7 @@ use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_data_structures::sync::{DynSend, DynSync, Lock, MappedReadGuard, ReadGuard, RwLock}; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; -use rustc_errors::emitter::{ - DynEmitter, HumanEmitter, HumanReadableErrorType, OutputTheme, stderr_destination, -}; +use rustc_errors::emitter::{DynEmitter, HumanReadableErrorType, OutputTheme, stderr_destination}; use rustc_errors::json::JsonEmitter; use rustc_errors::timings::TimingSectionHandler; use rustc_errors::translation::Translator; @@ -920,7 +918,7 @@ fn default_emitter( match sopts.error_format { config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { - HumanReadableErrorType::AnnotateSnippet { short, unicode } => { + HumanReadableErrorType { short, unicode } => { let emitter = AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map) @@ -938,20 +936,6 @@ fn default_emitter( ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } - HumanReadableErrorType::Default { short } => { - let emitter = HumanEmitter::new(stderr_destination(color_config), translator) - .sm(source_map) - .short_message(short) - .diagnostic_width(sopts.diagnostic_width) - .macro_backtrace(macro_backtrace) - .track_diagnostics(track_diagnostics) - .terminal_url(terminal_url) - .theme(OutputTheme::Ascii) - .ignored_directories_in_source_blocks( - sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(), - ); - Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) - } }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => Box::new( JsonEmitter::new( @@ -1460,16 +1444,11 @@ fn mk_emitter(output: ErrorOutputType) -> Box { Translator::with_fallback_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box = match output { config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { - HumanReadableErrorType::AnnotateSnippet { short, unicode } => Box::new( + HumanReadableErrorType { short, unicode } => Box::new( AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .short_message(short), ), - HumanReadableErrorType::Default { short } => Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .theme(OutputTheme::Ascii) - .short_message(short), - ), }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => { Box::new(JsonEmitter::new( diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e5a4593260a4..3d4b4e969157 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -404,15 +404,9 @@ impl Options { let unstable_features = rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); let config::JsonConfig { json_rendered, json_unused_externs, json_color, .. } = - config::parse_json(early_dcx, matches, unstable_features.is_nightly_build()); - let error_format = config::parse_error_format( - early_dcx, - matches, - color, - json_color, - json_rendered, - unstable_features.is_nightly_build(), - ); + config::parse_json(early_dcx, matches); + let error_format = + config::parse_error_format(early_dcx, matches, color, json_color, json_rendered); let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default(); let mut target_modifiers = BTreeMap::::new(); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 6e70f5b41c42..fb2088963284 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -7,9 +7,7 @@ use rustc_driver::USING_INTERNAL_FEATURES; use rustc_errors::TerminalUrl; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; -use rustc_errors::emitter::{ - DynEmitter, HumanEmitter, HumanReadableErrorType, OutputTheme, stderr_destination, -}; +use rustc_errors::emitter::{DynEmitter, HumanReadableErrorType, OutputTheme, stderr_destination}; use rustc_errors::json::JsonEmitter; use rustc_feature::UnstableFeatures; use rustc_hir::def::Res; @@ -162,7 +160,7 @@ pub(crate) fn new_dcx( let translator = rustc_driver::default_translator(); let emitter: Box = match error_format { ErrorOutputType::HumanReadable { kind, color_config } => match kind { - HumanReadableErrorType::AnnotateSnippet { short, unicode } => Box::new( + HumanReadableErrorType { short, unicode } => Box::new( AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map.map(|sm| sm as _)) .short_message(short) @@ -171,15 +169,6 @@ pub(crate) fn new_dcx( .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .ui_testing(unstable_opts.ui_testing), ), - HumanReadableErrorType::Default { short } => Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .sm(source_map.map(|sm| sm as _)) - .short_message(short) - .diagnostic_width(diagnostic_width) - .track_diagnostics(unstable_opts.track_diagnostics) - .theme(OutputTheme::Ascii) - .ui_testing(unstable_opts.ui_testing), - ), }, ErrorOutputType::Json { pretty, json_rendered, color_config } => { let source_map = source_map.unwrap_or_else(|| { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 85fecb87533d..25868e24ce16 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -625,7 +625,7 @@ fn run_test( ]); if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { let short = kind.short(); - let unicode = kind == HumanReadableErrorType::AnnotateSnippet { unicode: true, short }; + let unicode = kind == HumanReadableErrorType { unicode: true, short }; if short { compiler_args.extend_from_slice(&["--error-format".to_owned(), "short".to_owned()]); From f33abb17db4045a629e0ef4e9755dc145e3fdaec Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 16 Dec 2025 12:32:00 +0100 Subject: [PATCH 0876/3801] Update to LLVM 21.1.8 --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 89bab96463d4..85a90d119deb 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 89bab96463d42e979145166e0f8e6b8157fedc12 +Subproject commit 85a90d119deb25b518867cd37d62c7b93b575a6f From 7f6f52276159ed9d175f98c950adfa2306d46b44 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 15 Dec 2025 18:26:44 +1100 Subject: [PATCH 0877/3801] Rename `TestCase` to `TestableCase` --- .../src/builder/matches/buckets.rs | 35 +++++++++---------- .../src/builder/matches/match_pair.rs | 26 ++++++++------ .../src/builder/matches/mod.rs | 25 +++++++------ .../src/builder/matches/test.rs | 26 ++++++++------ .../src/builder/matches/util.rs | 6 ++-- 5 files changed, 64 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/matches/buckets.rs b/compiler/rustc_mir_build/src/builder/matches/buckets.rs index f53e73d406c3..6c5f0ed28a82 100644 --- a/compiler/rustc_mir_build/src/builder/matches/buckets.rs +++ b/compiler/rustc_mir_build/src/builder/matches/buckets.rs @@ -7,7 +7,7 @@ use tracing::debug; use crate::builder::Builder; use crate::builder::matches::test::is_switch_ty; -use crate::builder::matches::{Candidate, Test, TestBranch, TestCase, TestKind}; +use crate::builder::matches::{Candidate, Test, TestBranch, TestKind, TestableCase}; /// Output of [`Builder::partition_candidates_into_buckets`]. pub(crate) struct PartitionedCandidates<'tcx, 'b, 'c> { @@ -140,12 +140,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // branch, so it can be removed. If false, the match pair is _compatible_ // with its test branch, but still needs a more specific test. let fully_matched; - let ret = match (&test.kind, &match_pair.test_case) { + let ret = match (&test.kind, &match_pair.testable_case) { // If we are performing a variant switch, then this // informs variant patterns, but nothing else. ( &TestKind::Switch { adt_def: tested_adt_def }, - &TestCase::Variant { adt_def, variant_index }, + &TestableCase::Variant { adt_def, variant_index }, ) => { assert_eq!(adt_def, tested_adt_def); fully_matched = true; @@ -159,7 +159,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // things out here, in some cases. // // FIXME(Zalathar): Is the `is_switch_ty` test unnecessary? - (TestKind::SwitchInt, &TestCase::Constant { value }) + (TestKind::SwitchInt, &TestableCase::Constant { value }) if is_switch_ty(match_pair.pattern_ty) => { // An important invariant of candidate bucketing is that a candidate @@ -167,16 +167,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // a new value might invalidate that property for range patterns that // have already been partitioned into the failure arm, so we must take care // not to add such values here. - let is_covering_range = |test_case: &TestCase<'tcx>| { - test_case.as_range().is_some_and(|range| { + let is_covering_range = |testable_case: &TestableCase<'tcx>| { + testable_case.as_range().is_some_and(|range| { matches!(range.contains(value, self.tcx), None | Some(true)) }) }; let is_conflicting_candidate = |candidate: &&mut Candidate<'tcx>| { - candidate - .match_pairs - .iter() - .any(|mp| mp.place == Some(test_place) && is_covering_range(&mp.test_case)) + candidate.match_pairs.iter().any(|mp| { + mp.place == Some(test_place) && is_covering_range(&mp.testable_case) + }) }; if prior_candidates .get(&TestBranch::Failure) @@ -189,7 +188,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some(TestBranch::Constant(value)) } } - (TestKind::SwitchInt, TestCase::Range(range)) => { + (TestKind::SwitchInt, TestableCase::Range(range)) => { // When performing a `SwitchInt` test, a range pattern can be // sorted into the failure arm if it doesn't contain _any_ of // the values being tested. (This restricts what values can be @@ -207,7 +206,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) } - (TestKind::If, TestCase::Constant { value }) => { + (TestKind::If, TestableCase::Constant { value }) => { fully_matched = true; let value = value.try_to_bool().unwrap_or_else(|| { span_bug!(test.span, "expected boolean value but got {value:?}") @@ -217,7 +216,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ( &TestKind::Len { len: test_len, op: BinOp::Eq }, - &TestCase::Slice { len, variable_length }, + &TestableCase::Slice { len, variable_length }, ) => { match (test_len.cmp(&(len as u64)), variable_length) { (Ordering::Equal, false) => { @@ -249,7 +248,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ( &TestKind::Len { len: test_len, op: BinOp::Ge }, - &TestCase::Slice { len, variable_length }, + &TestableCase::Slice { len, variable_length }, ) => { // the test is `$actual_len >= test_len` match (test_len.cmp(&(len as u64)), variable_length) { @@ -281,7 +280,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - (TestKind::Range(test), TestCase::Range(pat)) => { + (TestKind::Range(test), TestableCase::Range(pat)) => { if test == pat { fully_matched = true; Some(TestBranch::Success) @@ -292,7 +291,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if !test.overlaps(pat, self.tcx)? { Some(TestBranch::Failure) } else { None } } } - (TestKind::Range(range), &TestCase::Constant { value }) => { + (TestKind::Range(range), &TestableCase::Constant { value }) => { fully_matched = false; if !range.contains(value, self.tcx)? { // `value` is not contained in the testing range, @@ -303,7 +302,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - (TestKind::Eq { value: test_val, .. }, TestCase::Constant { value: case_val }) => { + (TestKind::Eq { value: test_val, .. }, TestableCase::Constant { value: case_val }) => { if test_val == case_val { fully_matched = true; Some(TestBranch::Success) @@ -313,7 +312,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - (TestKind::Deref { temp: test_temp, .. }, TestCase::Deref { temp, .. }) + (TestKind::Deref { temp: test_temp, .. }, TestableCase::Deref { temp, .. }) if test_temp == temp => { fully_matched = true; diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index a0d54354a9c6..dc1545c9278a 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt}; use crate::builder::Builder; use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder}; -use crate::builder::matches::{FlatPat, MatchPairTree, PatternExtraData, TestCase}; +use crate::builder::matches::{FlatPat, MatchPairTree, PatternExtraData, TestableCase}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in @@ -132,7 +132,7 @@ impl<'tcx> MatchPairTree<'tcx> { let place = place_builder.try_to_place(cx); let mut subpairs = Vec::new(); - let test_case = match pattern.kind { + let testable_case = match pattern.kind { PatKind::Missing | PatKind::Wild | PatKind::Error(_) => None, PatKind::Or { ref pats } => { @@ -146,18 +146,18 @@ impl<'tcx> MatchPairTree<'tcx> { // FIXME(@dianne): this needs updating/removing if we always merge or-patterns extra_data.bindings.push(super::SubpatternBindings::FromOrPattern); } - Some(TestCase::Or { pats }) + Some(TestableCase::Or { pats }) } PatKind::Range(ref range) => { if range.is_full_range(cx.tcx) == Some(true) { None } else { - Some(TestCase::Range(Arc::clone(range))) + Some(TestableCase::Range(Arc::clone(range))) } } - PatKind::Constant { value } => Some(TestCase::Constant { value }), + PatKind::Constant { value } => Some(TestableCase::Constant { value }), PatKind::AscribeUserType { ascription: Ascription { ref annotation, variance }, @@ -256,7 +256,7 @@ impl<'tcx> MatchPairTree<'tcx> { if prefix.is_empty() && slice.is_some() && suffix.is_empty() { None } else { - Some(TestCase::Slice { + Some(TestableCase::Slice { len: prefix.len() + suffix.len(), variable_length: slice.is_some(), }) @@ -275,7 +275,11 @@ impl<'tcx> MatchPairTree<'tcx> { cx.def_id.into(), ) }) && !adt_def.variant_list_has_applicable_non_exhaustive(); - if irrefutable { None } else { Some(TestCase::Variant { adt_def, variant_index }) } + if irrefutable { + None + } else { + Some(TestableCase::Variant { adt_def, variant_index }) + } } PatKind::Leaf { ref subpatterns } => { @@ -331,17 +335,17 @@ impl<'tcx> MatchPairTree<'tcx> { &mut subpairs, extra_data, ); - Some(TestCase::Deref { temp, mutability }) + Some(TestableCase::Deref { temp, mutability }) } - PatKind::Never => Some(TestCase::Never), + PatKind::Never => Some(TestableCase::Never), }; - if let Some(test_case) = test_case { + if let Some(testable_case) = testable_case { // This pattern is refutable, so push a new match-pair node. match_pairs.push(MatchPairTree { place, - test_case, + testable_case, subpairs, pattern_ty: pattern.ty, pattern_span: pattern.span, diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 5074ce336798..ecdc3842a9b8 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1078,7 +1078,7 @@ struct Candidate<'tcx> { /// (see [`Builder::test_remaining_match_pairs_after_or`]). /// /// Invariants: - /// - All or-patterns ([`TestCase::Or`]) have been sorted to the end. + /// - All or-patterns ([`TestableCase::Or`]) have been sorted to the end. match_pairs: Vec>, /// ...and if this is non-empty, one of these subcandidates also has to match... @@ -1164,12 +1164,15 @@ impl<'tcx> Candidate<'tcx> { /// Restores the invariant that or-patterns must be sorted to the end. fn sort_match_pairs(&mut self) { - self.match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. })); + self.match_pairs.sort_by_key(|pair| matches!(pair.testable_case, TestableCase::Or { .. })); } /// Returns whether the first match pair of this candidate is an or-pattern. fn starts_with_or_pattern(&self) -> bool { - matches!(&*self.match_pairs, [MatchPairTree { test_case: TestCase::Or { .. }, .. }, ..]) + matches!( + &*self.match_pairs, + [MatchPairTree { testable_case: TestableCase::Or { .. }, .. }, ..] + ) } /// Visit the leaf candidates (those with no subcandidates) contained in @@ -1261,7 +1264,7 @@ struct Ascription<'tcx> { /// Instead they participate in or-pattern expansion, where they are transformed into /// subcandidates. See [`Builder::expand_and_match_or_candidates`]. #[derive(Debug, Clone)] -enum TestCase<'tcx> { +enum TestableCase<'tcx> { Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx }, Constant { value: ty::Value<'tcx> }, Range(Arc>), @@ -1271,7 +1274,7 @@ enum TestCase<'tcx> { Or { pats: Box<[FlatPat<'tcx>]> }, } -impl<'tcx> TestCase<'tcx> { +impl<'tcx> TestableCase<'tcx> { fn as_range(&self) -> Option<&PatRange<'tcx>> { if let Self::Range(v) = self { Some(v.as_ref()) } else { None } } @@ -1289,12 +1292,12 @@ pub(crate) struct MatchPairTree<'tcx> { /// --- /// This can be `None` if it referred to a non-captured place in a closure. /// - /// Invariant: Can only be `None` when `test_case` is `Or`. + /// Invariant: Can only be `None` when `testable_case` is `Or`. /// Therefore this must be `Some(_)` after or-pattern expansion. place: Option>, /// ... must pass this test... - test_case: TestCase<'tcx>, + testable_case: TestableCase<'tcx>, /// ... and these subpairs must match. /// @@ -1317,7 +1320,7 @@ enum TestKind<'tcx> { /// Test what enum variant a value is. /// /// The subset of expected variants is not stored here; instead they are - /// extracted from the [`TestCase`]s of the candidates participating in the + /// extracted from the [`TestableCase`]s of the candidates participating in the /// test. Switch { /// The enum type being tested. @@ -1327,7 +1330,7 @@ enum TestKind<'tcx> { /// Test what value an integer or `char` has. /// /// The test's target values are not stored here; instead they are extracted - /// from the [`TestCase`]s of the candidates participating in the test. + /// from the [`TestableCase`]s of the candidates participating in the test. SwitchInt, /// Test whether a `bool` is `true` or `false`. @@ -1948,7 +1951,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate: &mut Candidate<'tcx>, match_pair: MatchPairTree<'tcx>, ) { - let TestCase::Or { pats } = match_pair.test_case else { bug!() }; + let TestableCase::Or { pats } = match_pair.testable_case else { bug!() }; debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats); candidate.or_span = Some(match_pair.pattern_span); candidate.subcandidates = pats @@ -2116,7 +2119,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug_assert!( remaining_match_pairs .iter() - .all(|match_pair| matches!(match_pair.test_case, TestCase::Or { .. })) + .all(|match_pair| matches!(match_pair.testable_case, TestableCase::Or { .. })) ); // Visit each leaf candidate within this subtree, add a copy of the remaining diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index 46a76a7b9a30..55e21ff18aae 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -19,7 +19,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use tracing::{debug, instrument}; use crate::builder::Builder; -use crate::builder::matches::{MatchPairTree, Test, TestBranch, TestCase, TestKind}; +use crate::builder::matches::{MatchPairTree, Test, TestBranch, TestKind, TestableCase}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Identifies what test is needed to decide if `match_pair` is applicable. @@ -29,30 +29,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, match_pair: &MatchPairTree<'tcx>, ) -> Test<'tcx> { - let kind = match match_pair.test_case { - TestCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def }, + let kind = match match_pair.testable_case { + TestableCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def }, - TestCase::Constant { .. } if match_pair.pattern_ty.is_bool() => TestKind::If, - TestCase::Constant { .. } if is_switch_ty(match_pair.pattern_ty) => TestKind::SwitchInt, - TestCase::Constant { value } => TestKind::Eq { value, cast_ty: match_pair.pattern_ty }, + TestableCase::Constant { .. } if match_pair.pattern_ty.is_bool() => TestKind::If, + TestableCase::Constant { .. } if is_switch_ty(match_pair.pattern_ty) => { + TestKind::SwitchInt + } + TestableCase::Constant { value } => { + TestKind::Eq { value, cast_ty: match_pair.pattern_ty } + } - TestCase::Range(ref range) => { + TestableCase::Range(ref range) => { assert_eq!(range.ty, match_pair.pattern_ty); TestKind::Range(Arc::clone(range)) } - TestCase::Slice { len, variable_length } => { + TestableCase::Slice { len, variable_length } => { let op = if variable_length { BinOp::Ge } else { BinOp::Eq }; TestKind::Len { len: len as u64, op } } - TestCase::Deref { temp, mutability } => TestKind::Deref { temp, mutability }, + TestableCase::Deref { temp, mutability } => TestKind::Deref { temp, mutability }, - TestCase::Never => TestKind::Never, + TestableCase::Never => TestKind::Never, // Or-patterns are not tested directly; instead they are expanded into subcandidates, // which are then distinguished by testing whatever non-or patterns they contain. - TestCase::Or { .. } => bug!("or-patterns should have already been handled"), + TestableCase::Or { .. } => bug!("or-patterns should have already been handled"), }; Test { span: match_pair.pattern_span, kind } diff --git a/compiler/rustc_mir_build/src/builder/matches/util.rs b/compiler/rustc_mir_build/src/builder/matches/util.rs index 2c8ad95b6afd..f1df90f93fd6 100644 --- a/compiler/rustc_mir_build/src/builder/matches/util.rs +++ b/compiler/rustc_mir_build/src/builder/matches/util.rs @@ -6,7 +6,7 @@ use tracing::debug; use crate::builder::Builder; use crate::builder::expr::as_place::PlaceBase; -use crate::builder::matches::{Binding, Candidate, FlatPat, MatchPairTree, TestCase}; +use crate::builder::matches::{Binding, Candidate, FlatPat, MatchPairTree, TestableCase}; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Creates a false edge to `imaginary_target` and a real edge to @@ -159,11 +159,11 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { } fn visit_match_pair(&mut self, match_pair: &MatchPairTree<'tcx>) { - if let TestCase::Or { pats, .. } = &match_pair.test_case { + if let TestableCase::Or { pats, .. } = &match_pair.testable_case { for flat_pat in pats.iter() { self.visit_flat_pat(flat_pat) } - } else if matches!(match_pair.test_case, TestCase::Deref { .. }) { + } else if matches!(match_pair.testable_case, TestableCase::Deref { .. }) { // The subpairs of a deref pattern are all places relative to the deref temporary, so we // don't fake borrow them. Problem is, if we only shallowly fake-borrowed // `match_pair.place`, this would allow: From a8f4a6744c5927053e3415704d54daf463e5eec1 Mon Sep 17 00:00:00 2001 From: Oleksii Lozovskyi Date: Tue, 16 Dec 2025 21:10:29 +0900 Subject: [PATCH 0878/3801] rustdoc: Test only in stage2 stage1's rustdoc is using stage0's libtest which does not have a fix from 069cf9dfc90, making the test run fail. Ensure that this test is executed with everything recompiled in stage2. --- tests/run-make/doctests-junit/rmake.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/run-make/doctests-junit/rmake.rs b/tests/run-make/doctests-junit/rmake.rs index 4cc7ac7c31d7..e3198502bb17 100644 --- a/tests/run-make/doctests-junit/rmake.rs +++ b/tests/run-make/doctests-junit/rmake.rs @@ -1,6 +1,7 @@ // Check rustdoc's test JUnit (XML) output against snapshots. //@ ignore-cross-compile (running doctests) +//@ ignore-stage1 (rustdoc depends on a fix in libtest) //@ needs-unwind (test file contains `should_panic` test) use std::path::Path; From a47c8b292ed7b2a3bff627da1cd6e2826aab6db0 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 16 Dec 2025 10:47:37 +0000 Subject: [PATCH 0879/3801] remove human-annotate-rs --- compiler/rustc_session/src/config.rs | 9 ++------- tests/ui/annotate-snippet/missing-type.rs | 2 +- tests/ui/annotate-snippet/multiple-files.rs | 2 +- tests/ui/annotate-snippet/multispan.rs | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5b2ae59aba40..a3a97dfec61d 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2027,10 +2027,6 @@ pub fn parse_error_format( None | Some("human") => { ErrorOutputType::HumanReadable { color_config, kind: default_kind } } - Some("human-annotate-rs") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType { short: false, unicode: false }, - color_config, - }, Some("json") => { ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color } } @@ -2051,8 +2047,8 @@ pub fn parse_error_format( kind: default_kind, }); early_dcx.early_fatal(format!( - "argument for `--error-format` must be `human`, `human-annotate-rs`, \ - `human-unicode`, `json`, `pretty-json` or `short` (instead was `{arg}`)" + "argument for `--error-format` must be `human`, `human-unicode`, \ + `json`, `pretty-json` or `short` (instead was `{arg}`)" )) } } @@ -2114,7 +2110,6 @@ fn check_error_format_stability( let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", ErrorOutputType::HumanReadable { kind, .. } => match kind { - HumanReadableErrorType { unicode: false, .. } => "human-annotate-rs", HumanReadableErrorType { unicode: true, .. } => "human-unicode", _ => return, }, diff --git a/tests/ui/annotate-snippet/missing-type.rs b/tests/ui/annotate-snippet/missing-type.rs index 54088def3eea..2d06c13b96ab 100644 --- a/tests/ui/annotate-snippet/missing-type.rs +++ b/tests/ui/annotate-snippet/missing-type.rs @@ -1,5 +1,5 @@ //@ edition: 2015 -//@ compile-flags: --error-format human-annotate-rs -Z unstable-options +//@ compile-flags: --error-format human pub fn main() { let x: Iter; diff --git a/tests/ui/annotate-snippet/multiple-files.rs b/tests/ui/annotate-snippet/multiple-files.rs index c67a31d8f071..060e817bea08 100644 --- a/tests/ui/annotate-snippet/multiple-files.rs +++ b/tests/ui/annotate-snippet/multiple-files.rs @@ -1,5 +1,5 @@ //@ aux-build:other_file.rs -//@ compile-flags: --error-format human-annotate-rs -Z unstable-options +//@ compile-flags: --error-format human extern crate other_file; diff --git a/tests/ui/annotate-snippet/multispan.rs b/tests/ui/annotate-snippet/multispan.rs index c2054f62d24c..adbbef6d42f7 100644 --- a/tests/ui/annotate-snippet/multispan.rs +++ b/tests/ui/annotate-snippet/multispan.rs @@ -1,5 +1,5 @@ //@ proc-macro: multispan.rs -//@ compile-flags: --error-format human-annotate-rs -Z unstable-options +//@ compile-flags: --error-format human #![feature(proc_macro_hygiene)] From 84f2854bc3bfea59aeb6fd23245a788196c9d4ff Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 16 Dec 2025 10:48:15 +0000 Subject: [PATCH 0880/3801] remove fixme & update stderr files --- .../src/annotate_snippet_emitter_writer.rs | 17 ----------------- src/tools/clippy/tests/ui/unit_arg.stderr | 3 --- tests/ui/attributes/crate-type-delimited.stderr | 1 - tests/ui/attributes/crate-type-empty.stderr | 1 - .../ui/attributes/crate-type-macro-call.stderr | 1 - .../generic_const_exprs/issue-105608.stderr | 1 - .../ice-line-bounds-issue-148732.stderr | 1 - tests/ui/macros/cfg_select.stderr | 2 -- .../issue-42234-unknown-receiver-type.stderr | 1 - .../structs/ice-line-bounds-issue-148684.stderr | 1 - 10 files changed, 29 deletions(-) diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 7f64dc3df23e..9bb318973958 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -303,17 +303,6 @@ impl AnnotateSnippetEmitter { } } - let suggestions_expected = suggestions - .iter() - .filter(|s| { - matches!( - s.style, - SuggestionStyle::HideCodeInline - | SuggestionStyle::ShowCode - | SuggestionStyle::ShowAlways - ) - }) - .count(); for suggestion in suggestions { match suggestion.style { SuggestionStyle::CompletelyHidden => { @@ -526,12 +515,6 @@ impl AnnotateSnippetEmitter { } } - // FIXME: This hack should be removed once annotate_snippets is the - // default emitter. - if suggestions_expected > 0 && report.is_empty() { - group = group.element(Padding); - } - if !group.is_empty() { report.push(group); } diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr index 0dcfb02b9fa0..eb7c56c45b59 100644 --- a/src/tools/clippy/tests/ui/unit_arg.stderr +++ b/src/tools/clippy/tests/ui/unit_arg.stderr @@ -204,21 +204,18 @@ error: passing a unit value to a function | LL | fn_take_unit(mac!(def)); | ^^^^^^^^^^^^^^^^^^^^^^^ - | error: passing a unit value to a function --> tests/ui/unit_arg.rs:173:5 | LL | fn_take_unit(mac!(func Default::default)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | error: passing a unit value to a function --> tests/ui/unit_arg.rs:175:5 | LL | fn_take_unit(mac!(nonempty_block Default::default())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | error: aborting due to 13 previous errors diff --git a/tests/ui/attributes/crate-type-delimited.stderr b/tests/ui/attributes/crate-type-delimited.stderr index 23234efe169f..e9616f27174c 100644 --- a/tests/ui/attributes/crate-type-delimited.stderr +++ b/tests/ui/attributes/crate-type-delimited.stderr @@ -5,7 +5,6 @@ LL | #![crate_type(lib)] | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit - | error: aborting due to 1 previous error diff --git a/tests/ui/attributes/crate-type-empty.stderr b/tests/ui/attributes/crate-type-empty.stderr index c1d474d9f17f..b8eca61748ea 100644 --- a/tests/ui/attributes/crate-type-empty.stderr +++ b/tests/ui/attributes/crate-type-empty.stderr @@ -5,7 +5,6 @@ LL | #![crate_type] | ^^^^^^^^^^^^^^ | = note: for more information, visit - | error: aborting due to 1 previous error diff --git a/tests/ui/attributes/crate-type-macro-call.stderr b/tests/ui/attributes/crate-type-macro-call.stderr index cd17b324041b..b3927fef4718 100644 --- a/tests/ui/attributes/crate-type-macro-call.stderr +++ b/tests/ui/attributes/crate-type-macro-call.stderr @@ -5,7 +5,6 @@ LL | #![crate_type = foo!()] | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit - | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr index 1c97eaddfe1b..cc35035edf95 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr @@ -3,7 +3,6 @@ error[E0282]: type annotations needed | LL | Combination::<0>.and::<_>().and::<_>(); | ^^^ cannot infer type of the type parameter `M` declared on the method `and` - | error: aborting due to 1 previous error diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr index 1f43ec335448..f332bc6a7a21 100644 --- a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr @@ -5,7 +5,6 @@ LL | dbg!(b); | ^^^^^^^ expected named lifetime parameter | = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) - | error[E0425]: cannot find function `a` in this scope --> $DIR/ice-line-bounds-issue-148732.rs:1:7 diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 5e2d705760cf..510fc33d6d11 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -38,14 +38,12 @@ error[E0539]: malformed `cfg_select` macro input | LL | "str" => {} | ^^^^^ expected a valid identifier here - | error[E0539]: malformed `cfg_select` macro input --> $DIR/cfg_select.rs:80:5 | LL | a::b => {} | ^^^^ expected a valid identifier here - | error[E0537]: invalid predicate `a` --> $DIR/cfg_select.rs:85:5 diff --git a/tests/ui/span/issue-42234-unknown-receiver-type.stderr b/tests/ui/span/issue-42234-unknown-receiver-type.stderr index 10308ec07da5..f16006a8e085 100644 --- a/tests/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/tests/ui/span/issue-42234-unknown-receiver-type.stderr @@ -16,7 +16,6 @@ error[E0282]: type annotations needed | LL | .sum::<_>() | ^^^ cannot infer type of the type parameter `S` declared on the method `sum` - | error: aborting due to 2 previous errors diff --git a/tests/ui/structs/ice-line-bounds-issue-148684.stderr b/tests/ui/structs/ice-line-bounds-issue-148684.stderr index f26d96cd1172..71ed393bf056 100644 --- a/tests/ui/structs/ice-line-bounds-issue-148684.stderr +++ b/tests/ui/structs/ice-line-bounds-issue-148684.stderr @@ -9,7 +9,6 @@ LL | | } ... LL | A(2, vec![]) | ^^^^^^^^^^^^ - | error: aborting due to 1 previous error From 9dec5bb31a6041960083bb78678e85b0cc387c96 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 16 Dec 2025 10:48:15 +0000 Subject: [PATCH 0881/3801] remove fixme & update stderr files --- tests/ui/unit_arg.stderr | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/ui/unit_arg.stderr b/tests/ui/unit_arg.stderr index 0dcfb02b9fa0..eb7c56c45b59 100644 --- a/tests/ui/unit_arg.stderr +++ b/tests/ui/unit_arg.stderr @@ -204,21 +204,18 @@ error: passing a unit value to a function | LL | fn_take_unit(mac!(def)); | ^^^^^^^^^^^^^^^^^^^^^^^ - | error: passing a unit value to a function --> tests/ui/unit_arg.rs:173:5 | LL | fn_take_unit(mac!(func Default::default)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | error: passing a unit value to a function --> tests/ui/unit_arg.rs:175:5 | LL | fn_take_unit(mac!(nonempty_block Default::default())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | error: aborting due to 13 previous errors From 6cd1740e17f93d04d53a42b7dc06f49757bfba8f Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 16 Dec 2025 17:00:12 +0200 Subject: [PATCH 0882/3801] Upgrade rustc crates Changes: - `const_of_item()` was added to `Interner`, analogous to `type_of()`. No strongly-typed ID (yet). - New solver trait lang item: `TrivialClone`. - `TypeRelation` changed a bit, the code was copied from rustc. --- src/tools/rust-analyzer/Cargo.lock | 45 +++++++++---------- src/tools/rust-analyzer/Cargo.toml | 16 +++---- .../crates/hir-def/src/lang_item.rs | 1 + .../next_solver/infer/relate/generalize.rs | 39 ++++++++-------- .../src/next_solver/infer/relate/lattice.rs | 23 ++++++++-- .../crates/hir-ty/src/next_solver/interner.rs | 19 +++++++- .../crates/intern/src/symbol/symbols.rs | 1 + 7 files changed, 86 insertions(+), 58 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index efe56cb7f61c..9b7b7650199e 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2040,9 +2040,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "ra-ap-rustc_abi" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce480c45c05462cf6b700468118201b00132613a968a1849da5f7a555c0f1db9" +checksum = "1d49dbe5d570793b3c3227972a6ac85fc3e830f09b32c3cb3b68cfceebad3b0a" dependencies = [ "bitflags 2.9.4", "ra-ap-rustc_hashes", @@ -2052,34 +2052,33 @@ dependencies = [ [[package]] name = "ra-ap-rustc_ast_ir" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453da2376de406d740ca28412a31ae3d5a6039cd45698c1c2fb01b577dff64ae" +checksum = "cd0956db62c264a899d15667993cbbd2e8f0b02108712217e2579c61ac30b94b" [[package]] name = "ra-ap-rustc_hashes" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf411a55deaa3ea348594c8273fb2d1200265bf87b881b40c62b32f75caf8323" +checksum = "7df512084c24f4c96c8cc9a59cbd264301efbc8913d3759b065398024af316c9" dependencies = [ "rustc-stable-hash", ] [[package]] name = "ra-ap-rustc_index" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0dd4cf1417ea8a809e9e7bf296c6ce6e05b75b043483872d1bd2951a08142c" +checksum = "bca3a49a928d38ba7927605e5909b6abe77d09ff359e4695c070c3f91d69cc8a" dependencies = [ "ra-ap-rustc_index_macros", - "smallvec", ] [[package]] name = "ra-ap-rustc_index_macros" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b0d218fb91f8969716a962142c722d88b3cd3fd1f7ef03093261bf37e85dfd" +checksum = "4463e908a62c64c2a65c1966c2f4995d0e1f8b7dfc85a8b8de2562edf3d89070" dependencies = [ "proc-macro2", "quote", @@ -2088,9 +2087,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_lexer" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec7c26e92c44d5433b29cf661faf0027e263b70a411d0f28996bd67e3bdb57e" +checksum = "228e01e1b237adb4bd8793487e1c37019c1e526a8f93716d99602301be267056" dependencies = [ "memchr", "unicode-properties", @@ -2099,9 +2098,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_next_trait_solver" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "029686fdbc8a058cf3d81ad157e1cdc81a37b9de0400289ccb86a62465484313" +checksum = "10d6f91143011d474bb844d268b0784c6a4c6db57743558b83f5ad34511627f1" dependencies = [ "derive-where", "ra-ap-rustc_index", @@ -2112,9 +2111,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_parse_format" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509d279f1e87acc33476da3fbd05a6054e9ffeb4427cb38ba01b9d2656aec268" +checksum = "37fa8effbc436c0ddd9d7b1421aa3cccf8b94566c841c4e4aa3e09063b8f423f" dependencies = [ "ra-ap-rustc_lexer", "rustc-literal-escaper 0.0.5", @@ -2122,9 +2121,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb2c9930854314b03bd7aab060a14bca6f194b76381a4c309e3905ec3a02bbc" +checksum = "883c843fc27847ad03b8e772dd4a2d2728af4333a6d6821a22dfcfe7136dff3e" dependencies = [ "ra-ap-rustc_index", "rustc-hash 2.1.1", @@ -2135,9 +2134,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_type_ir" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4a92a3e4dbdebb0d4c9caceb52eff45c4df784d21fb2da90dac50e218f95c0" +checksum = "a86e33c46b2b261a173b23f207461a514812a8b2d2d7935bbc685f733eacce10" dependencies = [ "arrayvec", "bitflags 2.9.4", @@ -2155,9 +2154,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_type_ir_macros" -version = "0.139.0" +version = "0.143.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca368eca2472367f2e6fdfb431c8342e99d848e4ce89cb20dd3b3bdcc43cbc28" +checksum = "15034c2fcaa5cf302aea6db20eda0f71fffeb0b372d6073cc50f940e974a2a47" dependencies = [ "proc-macro2", "quote", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 6991eeec738e..17051e57de34 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -86,14 +86,14 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } edition = { path = "./crates/edition", version = "0.0.0" } -ra-ap-rustc_lexer = { version = "0.139", default-features = false } -ra-ap-rustc_parse_format = { version = "0.139", default-features = false } -ra-ap-rustc_index = { version = "0.139", default-features = false } -ra-ap-rustc_abi = { version = "0.139", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.139", default-features = false } -ra-ap-rustc_ast_ir = { version = "0.139", default-features = false } -ra-ap-rustc_type_ir = { version = "0.139", default-features = false } -ra-ap-rustc_next_trait_solver = { version = "0.139", default-features = false } +ra-ap-rustc_lexer = { version = "0.143", default-features = false } +ra-ap-rustc_parse_format = { version = "0.143", default-features = false } +ra-ap-rustc_index = { version = "0.143", default-features = false } +ra-ap-rustc_abi = { version = "0.143", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.143", default-features = false } +ra-ap-rustc_ast_ir = { version = "0.143", default-features = false } +ra-ap-rustc_type_ir = { version = "0.143", default-features = false } +ra-ap-rustc_next_trait_solver = { version = "0.143", default-features = false } # local crates that aren't published to crates.io. These should not have versions. diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 9fdfb5f5b32e..6c8fb55d8f51 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -237,6 +237,7 @@ language_item_table! { LangItems => StructuralTeq, sym::structural_teq, structural_teq_trait, TraitId, GenericRequirement::None; Copy, sym::copy, copy_trait, TraitId, GenericRequirement::Exact(0); Clone, sym::clone, clone_trait, TraitId, GenericRequirement::None; + TrivialClone, sym::trivial_clone, clone_trait, TraitId, GenericRequirement::None; Sync, sym::sync, sync_trait, TraitId, GenericRequirement::Exact(0); DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, TraitId, GenericRequirement::None; /// The associated item of the `DiscriminantKind` trait. diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/relate/generalize.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/relate/generalize.rs index d06984cac11c..0f7ae99fa41d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/relate/generalize.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/relate/generalize.rs @@ -16,14 +16,14 @@ use tracing::{debug, instrument, warn}; use super::{ PredicateEmittingRelation, Relate, RelateResult, StructurallyRelateAliases, TypeRelation, }; -use crate::next_solver::infer::type_variable::TypeVariableValue; use crate::next_solver::infer::unify_key::ConstVariableValue; use crate::next_solver::infer::{InferCtxt, relate}; use crate::next_solver::util::MaxUniverse; use crate::next_solver::{ - AliasTy, Binder, ClauseKind, Const, ConstKind, DbInterner, GenericArgs, PredicateKind, Region, - SolverDefId, Term, TermVid, Ty, TyKind, TypingMode, UnevaluatedConst, + AliasTy, Binder, ClauseKind, Const, ConstKind, DbInterner, PredicateKind, Region, SolverDefId, + Term, TermVid, Ty, TyKind, TypingMode, UnevaluatedConst, }; +use crate::next_solver::{GenericArgs, infer::type_variable::TypeVariableValue}; impl<'db> InferCtxt<'db> { /// The idea is that we should ensure that the type variable `target_vid` @@ -384,29 +384,26 @@ impl<'db> TypeRelation> for Generalizer<'_, 'db> { self.infcx.interner } - fn relate_item_args( + fn relate_ty_args( &mut self, - item_def_id: SolverDefId, - a_arg: GenericArgs<'db>, - b_arg: GenericArgs<'db>, - ) -> RelateResult<'db, GenericArgs<'db>> { - if self.ambient_variance == Variance::Invariant { + a_ty: Ty<'db>, + _: Ty<'db>, + def_id: SolverDefId, + a_args: GenericArgs<'db>, + b_args: GenericArgs<'db>, + mk: impl FnOnce(GenericArgs<'db>) -> Ty<'db>, + ) -> RelateResult<'db, Ty<'db>> { + let args = if self.ambient_variance == Variance::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). - relate::relate_args_invariantly(self, a_arg, b_arg) + relate::relate_args_invariantly(self, a_args, b_args) } else { - let tcx = self.cx(); - let opt_variances = tcx.variances_of(item_def_id); - relate::relate_args_with_variances( - self, - item_def_id, - opt_variances, - a_arg, - b_arg, - false, - ) - } + let interner = self.cx(); + let variances = interner.variances_of(def_id); + relate::relate_args_with_variances(self, variances, a_args, b_args) + }?; + if args == a_args { Ok(a_ty) } else { Ok(mk(args)) } } #[instrument(level = "debug", skip(self, variance, b), ret)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/relate/lattice.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/relate/lattice.rs index 374895c337c7..1abe6a93f4dd 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/relate/lattice.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/infer/relate/lattice.rs @@ -18,17 +18,19 @@ //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order) use rustc_type_ir::{ - AliasRelationDirection, TypeVisitableExt, Upcast, Variance, + AliasRelationDirection, Interner, TypeVisitableExt, Upcast, Variance, inherent::{IntoKind, Span as _}, relate::{ Relate, StructurallyRelateAliases, TypeRelation, VarianceDiagInfo, - combine::{PredicateEmittingRelation, super_combine_consts, super_combine_tys}, + combine::{ + PredicateEmittingRelation, combine_ty_args, super_combine_consts, super_combine_tys, + }, }, }; use crate::next_solver::{ - AliasTy, Binder, Const, DbInterner, Goal, ParamEnv, Predicate, PredicateKind, Region, Span, Ty, - TyKind, + AliasTy, Binder, Const, DbInterner, GenericArgs, Goal, ParamEnv, Predicate, PredicateKind, + Region, SolverDefId, Span, Ty, TyKind, infer::{ InferCtxt, TypeTrace, relate::RelateResult, @@ -82,6 +84,19 @@ impl<'db> TypeRelation> for LatticeOp<'_, 'db> { self.infcx.interner } + fn relate_ty_args( + &mut self, + a_ty: Ty<'db>, + b_ty: Ty<'db>, + def_id: SolverDefId, + a_args: GenericArgs<'db>, + b_args: GenericArgs<'db>, + mk: impl FnOnce(GenericArgs<'db>) -> Ty<'db>, + ) -> RelateResult<'db, Ty<'db>> { + let variances = self.cx().variances_of(def_id); + combine_ty_args(self.infcx, self, a_ty, b_ty, variances, a_args, b_args, mk) + } + fn relate_with_variance>>( &mut self, variance: Variance, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 8b24a20a5bed..2a9f6c4053a4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -25,7 +25,7 @@ use rustc_type_ir::{ elaborate::elaborate, error::TypeError, fast_reject, - inherent::{self, GenericsOf, IntoKind, SliceLike as _, Span as _, Ty as _}, + inherent::{self, Const as _, GenericsOf, IntoKind, SliceLike as _, Span as _, Ty as _}, lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}, solve::SizedTraitKind, }; @@ -39,7 +39,7 @@ use crate::{ AdtIdWrapper, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper, CoroutineIdWrapper, Ctor, FnSig, FxIndexMap, GeneralConstIdWrapper, ImplIdWrapper, OpaqueTypeKey, RegionAssumptions, SimplifiedType, SolverContext, SolverDefIds, - TraitIdWrapper, TypeAliasIdWrapper, util::explicit_item_bounds, + TraitIdWrapper, TypeAliasIdWrapper, UnevaluatedConst, util::explicit_item_bounds, }, }; @@ -1512,6 +1512,7 @@ impl<'db> Interner for DbInterner<'db> { SolverTraitLangItem::BikeshedGuaranteedNoDrop => { unimplemented!() } + SolverTraitLangItem::TrivialClone => lang_items.TrivialClone, }; lang_item.expect("Lang item required but not found.").into() } @@ -1565,6 +1566,7 @@ impl<'db> Interner for DbInterner<'db> { AsyncFn, AsyncFnMut, AsyncFnOnce, + TrivialClone, ) } @@ -1651,6 +1653,7 @@ impl<'db> Interner for DbInterner<'db> { AsyncFn, AsyncFnMut, AsyncFnOnce, + TrivialClone, ) } @@ -2167,6 +2170,18 @@ impl<'db> Interner for DbInterner<'db> { Some(SolverTraitLangItem::Sized | SolverTraitLangItem::MetaSized) ) } + + fn const_of_item(self, def_id: Self::DefId) -> rustc_type_ir::EarlyBinder { + let id = match def_id { + SolverDefId::StaticId(id) => id.into(), + SolverDefId::ConstId(id) => id.into(), + _ => unreachable!(), + }; + EarlyBinder::bind(Const::new_unevaluated( + self, + UnevaluatedConst { def: GeneralConstIdWrapper(id), args: GenericArgs::empty(self) }, + )) + } } impl<'db> DbInterner<'db> { diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 462f1c69fa69..6e9c6d26b5b1 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -161,6 +161,7 @@ define_symbols! { cfg_select, char, clone, + trivial_clone, Clone, coerce_unsized, column, From b9839eb105204f665e8675689c49b26a3d8fdcdd Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 16 Dec 2025 16:13:22 +0000 Subject: [PATCH 0883/3801] Rustup to rustc 1.94.0-nightly (21ff67df1 2025-12-15) --- rust-toolchain | 2 +- src/driver/jit.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust-toolchain b/rust-toolchain index 461dbcdb0fb5..61ef39d75ffc 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-12-08" +channel = "nightly-2025-12-16" components = ["rust-src", "rustc-dev", "llvm-tools"] profile = "minimal" diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 9dba46363936..3a8ca25a5fc0 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -190,7 +190,7 @@ fn dep_symbol_lookup_fn( diag.emit(); } Linkage::Dynamic => { - dylib_paths.push(src.dylib.as_ref().unwrap().0.clone()); + dylib_paths.push(src.dylib.as_ref().unwrap().clone()); } } } From b73270f189cfe1f2c4bfbf9dda70f300ee8ed0bb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 16 Dec 2025 16:40:44 +0000 Subject: [PATCH 0884/3801] Fix rustc test suite --- scripts/test_rustc_tests.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index b5af585a732e..570ac434b97e 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -70,6 +70,7 @@ rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported rm -r tests/ui/explicit-tail-calls # tail calls rm -r tests/run-make/pointer-auth-link-with-c # pointer auth +rm -r tests/ui/eii # EII not yet implemented # requires LTO rm -r tests/run-make/cdylib @@ -143,6 +144,14 @@ rm tests/ui/errors/remap-path-prefix-sysroot.rs # different sysroot source path rm -r tests/run-make/export/extern-opt # something about rustc version mismatches rm -r tests/run-make/export # same rm -r tests/ui/compiletest-self-test/compile-flags-incremental.rs # needs compiletest compiled with panic=unwind +rm tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs # something going wrong with stdlib source remapping +rm tests/ui/consts/miri_unleashed/drop.rs # same +rm tests/ui/error-emitter/multiline-removal-suggestion.rs # same +rm tests/ui/lint/lint-const-item-mutation.rs # same +rm tests/ui/lint/use-redundant/use-redundant-issue-71450.rs # same +rm tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs # same +rm tests/ui/specialization/const_trait_impl.rs # same +rm tests/ui/thir-print/offset_of.rs # same # genuine bugs # ============ From 0004d8d421f0e8bfb432cc2a4234ec0b33a4fbec Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 16 Dec 2025 08:36:33 -0800 Subject: [PATCH 0885/3801] Remove deny of manual-let-else --- compiler/rustc_ast/src/lib.rs | 1 - compiler/rustc_borrowck/src/lib.rs | 1 - compiler/rustc_const_eval/src/lib.rs | 1 - compiler/rustc_hir/src/lib.rs | 1 - compiler/rustc_hir_analysis/src/lib.rs | 1 - compiler/rustc_hir_typeck/src/lib.rs | 1 - compiler/rustc_lint/src/lib.rs | 1 - compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_resolve/src/lib.rs | 1 - 9 files changed, 9 deletions(-) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 10a8e181c840..cbdc89f9deed 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -6,7 +6,6 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(array_windows))] -#![deny(clippy::manual_let_else)] #![doc(test(attr(deny(warnings), allow(internal_features))))] #![feature(associated_type_defaults)] #![feature(box_patterns)] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index d82357fca2d4..8d61ffde116c 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,7 +2,6 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 6c74ed2a5121..2fce4b8c0566 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] -#![deny(clippy::manual_let_else)] #![feature(array_try_map)] #![feature(assert_matches)] #![feature(box_patterns)] diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index c27954b6d14e..7a5776f0d5a9 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -4,7 +4,6 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(debug_closure_helpers))] -#![deny(clippy::manual_let_else)] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] #![feature(const_default)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 79c5fbab1ffa..538fb8c7df1e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -59,7 +59,6 @@ This API is completely unstable and subject to change. #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(bootstrap, feature(debug_closure_helpers))] -#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(gen_blocks)] #![feature(if_let_guard)] diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 9ca5ddd494ae..d3ef1d63e8ba 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 49929a0a9bc7..4e7a3e405176 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -22,7 +22,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![cfg_attr(bootstrap, feature(array_windows))] -#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index ee3e89e57bd4..5f62d44df6b6 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -30,7 +30,6 @@ #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(bootstrap, feature(array_windows))] -#![deny(clippy::manual_let_else)] #![feature(allocator_api)] #![feature(assert_matches)] #![feature(associated_type_defaults)] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b3141406e467..775335e5008c 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -10,7 +10,6 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![deny(clippy::manual_let_else)] #![feature(arbitrary_self_types)] #![feature(assert_matches)] #![feature(box_patterns)] From 49f1fa5110846d1ffec4e5557961a4a9a1b4334e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 16 Dec 2025 16:42:17 +0000 Subject: [PATCH 0886/3801] Unconditionally install rustfmt Rustfmt used to be optional for nightlies long ago, but it is now always present. Also rename rust-toolchain to rust-toolchain.toml. --- .github/workflows/main.yml | 8 ++++---- .github/workflows/rustc.yml | 4 ++-- rust-toolchain | 4 ---- rust-toolchain.toml | 4 ++++ scripts/rustup.sh | 5 ++--- 5 files changed, 12 insertions(+), 13 deletions(-) delete mode 100644 rust-toolchain create mode 100644 rust-toolchain.toml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0930b924d177..07d9af4a9b54 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: - name: Avoid installing rustc-dev run: | - sed -i 's/components.*/components = ["rustfmt"]/' rust-toolchain + sed -i 's/components.*/components = ["rustfmt"]/' rust-toolchain.toml rustfmt -v - name: Rustfmt @@ -88,7 +88,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} - name: Set MinGW as the default toolchain if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' @@ -158,7 +158,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} - name: Install hyperfine run: | @@ -207,7 +207,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-dist-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-dist-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} - name: Set MinGW as the default toolchain if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' diff --git a/.github/workflows/rustc.yml b/.github/workflows/rustc.yml index 9253ab96353c..b22725fdc9d4 100644 --- a/.github/workflows/rustc.yml +++ b/.github/workflows/rustc.yml @@ -20,7 +20,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }} - name: Test run: ./scripts/test_bootstrap.sh @@ -40,7 +40,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }} - name: Install ripgrep run: | diff --git a/rust-toolchain b/rust-toolchain deleted file mode 100644 index 61ef39d75ffc..000000000000 --- a/rust-toolchain +++ /dev/null @@ -1,4 +0,0 @@ -[toolchain] -channel = "nightly-2025-12-16" -components = ["rust-src", "rustc-dev", "llvm-tools"] -profile = "minimal" diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000000..4d3fe30e7d47 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "nightly-2025-12-16" +components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] +profile = "minimal" diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 1a82193303e2..e26be307328f 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -22,8 +22,7 @@ case $1 in "prepare") echo "=> Installing new nightly" rustup toolchain install --profile minimal "nightly-${TOOLCHAIN}" # Sanity check to see if the nightly exists - sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain - rustup component add rustfmt || true + sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain.toml echo "=> Uninstalling all old nightlies" for nightly in $(rustup toolchain list | grep nightly | grep -v "$TOOLCHAIN" | grep -v nightly-x86_64); do @@ -35,7 +34,7 @@ case $1 in ./y.sh prepare ;; "commit") - git add rust-toolchain + git add rust-toolchain.toml git commit -m "Rustup to $(rustc -V)" ;; "push") From bb9dac5fe5889f6c4cfb373388ca0e54413429f9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 16 Dec 2025 16:49:44 +0000 Subject: [PATCH 0887/3801] Disable linker plugin lto rustc test --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 570ac434b97e..09de603efa11 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -79,6 +79,7 @@ rm -r tests/run-make/lto-* rm -r tests/run-make/reproducible-build-2 rm -r tests/run-make/no-builtins-lto rm -r tests/run-make/reachable-extern-fn-available-lto +rm -r tests/run-make/no-builtins-linker-plugin-lto # coverage instrumentation rm tests/ui/consts/precise-drop-with-coverage.rs From 4efe2681f75bc8fb3910f1bf183f4bfc70d7aca8 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 16 Dec 2025 22:27:42 +0530 Subject: [PATCH 0888/3801] std: io: error: Add comment for UEFI unpacked repr use The following commit adds the comment explaining the rational why UEFI uses unpacked representation on 64-bit platforms as opposed to bit-packed representation used in all other 64-bit platforms. Signed-off-by: Ayush Singh --- library/std/src/io/error.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 98b266663ad2..528eb185df08 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -1,6 +1,13 @@ #[cfg(test)] mod tests; +// On 64-bit platforms, `io::Error` may use a bit-packed representation to +// reduce size. However, this representation assumes that error codes are +// always 32-bit wide. +// +// This assumption is invalid on 64-bit UEFI, where error codes are 64-bit. +// Therefore, the packed representation is explicitly disabled for UEFI +// targets, and the unpacked representation must be used instead. #[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))] mod repr_bitpacked; #[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))] From 3822cf126bf004c9c9a5db6609f32e7758ea3427 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 16 Dec 2025 17:00:09 +0000 Subject: [PATCH 0889/3801] Disable a bunch of rustc tests that fail with --panic-unwind-support --- scripts/test_rustc_tests.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 09de603efa11..69c6099c3ab8 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -53,17 +53,21 @@ rm tests/ui/sanitizer/kcfi-c-variadic.rs # same rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported rm tests/ui/delegation/fn-header.rs +# inline assembly features +rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly +rm tests/ui/asm/global-asm-mono-sym-fn.rs # same +rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same +rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported +rm tests/ui/asm/label-operand.rs # same +rm tests/ui/asm/may_unwind.rs # asm unwinding not supported +rm tests/ui/asm/aarch64/may_unwind.rs # same + # misc unimplemented things rm tests/ui/target-feature/missing-plusminus.rs # error not implemented rm -r tests/run-make/repr128-dwarf # debuginfo test rm -r tests/run-make/split-debuginfo # same rm -r tests/run-make/target-specs # i686 not supported by Cranelift rm -r tests/run-make/mismatching-target-triples # same -rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly -rm tests/ui/asm/global-asm-mono-sym-fn.rs # same -rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same -rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported -rm tests/ui/asm/label-operand.rs # same rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same @@ -71,6 +75,7 @@ rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported rm -r tests/ui/explicit-tail-calls # tail calls rm -r tests/run-make/pointer-auth-link-with-c # pointer auth rm -r tests/ui/eii # EII not yet implemented +rm -r tests/run-make/forced-unwind-terminate-pof # forced unwinding doesn't take precedence # requires LTO rm -r tests/run-make/cdylib @@ -89,6 +94,7 @@ rm -r tests/ui/instrument-coverage/ # ================== rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations rm tests/ui/codegen/init-large-type.rs # same +rm tests/ui/codegen/StackColoring-not-blowup-stack-issue-40883.rs # same rm tests/ui/statics/const_generics.rs # tests an optimization rm tests/ui/linking/executable-no-mangle-strip.rs # requires --gc-sections to work for statics @@ -167,6 +173,7 @@ rm tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs # same rm tests/ui/async-await/async-drop/async-drop-initial.rs # same (rust-lang/rust#140493) rm -r tests/ui/codegen/equal-pointers-unequal # make incorrect assumptions about the location of stack variables rm -r tests/run-make-cargo/rustdoc-scrape-examples-paths # FIXME(rust-lang/rust#145580) incr comp bug +rm -r tests/incremental/extern_static/issue-49153.rs # assumes reference to undefined static gets optimized away rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # really slow with unoptimized libstd rm tests/ui/process/process-panic-after-fork.rs # same From 60bba9bd9c2eb43c9ad0363633e3c480f09f0dec Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 2 Dec 2025 14:23:10 +0530 Subject: [PATCH 0890/3801] std: sys: fs: uefi: Implement readdir - Add path field to uefi file since this will also be required in implementing Debug for rust File. - Tested on OVMF. Signed-off-by: Ayush Singh --- library/std/src/sys/fs/uefi.rs | 131 ++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 26 deletions(-) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 21ef70b43dcd..1c65e3e2b155 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -21,9 +21,13 @@ pub struct FileAttr { created: Option, } -pub struct ReadDir(!); +pub struct ReadDir(uefi_fs::File); -pub struct DirEntry(!); +pub struct DirEntry { + attr: FileAttr, + file_name: OsString, + path: PathBuf, +} #[derive(Clone, Debug)] pub struct OpenOptions { @@ -143,8 +147,10 @@ impl FileType { } impl fmt::Debug for ReadDir { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut b = f.debug_struct("ReadDir"); + b.field("path", &self.0.path()); + b.finish() } } @@ -152,25 +158,35 @@ impl Iterator for ReadDir { type Item = io::Result; fn next(&mut self) -> Option> { - self.0 + match self.0.read_dir_entry() { + Ok(None) => None, + Ok(Some(x)) => Some(Ok(DirEntry::from_uefi(x, self.0.path()))), + Err(e) => Some(Err(e)), + } } } impl DirEntry { pub fn path(&self) -> PathBuf { - self.0 + self.path.clone() } pub fn file_name(&self) -> OsString { - self.0 + self.file_name.clone() } pub fn metadata(&self) -> io::Result { - self.0 + Ok(self.attr.clone()) } pub fn file_type(&self) -> io::Result { - self.0 + Ok(self.attr.file_type()) + } + + fn from_uefi(info: helpers::UefiBox, parent: &Path) -> Self { + let file_name = uefi_fs::file_name_from_uefi(&info); + let path = parent.join(&file_name); + Self { file_name, path, attr: FileAttr::from_uefi(info) } } } @@ -344,8 +360,17 @@ impl fmt::Debug for File { } } -pub fn readdir(_p: &Path) -> io::Result { - unsupported() +pub fn readdir(p: &Path) -> io::Result { + let path = crate::path::absolute(p)?; + let f = uefi_fs::File::from_path(&path, file::MODE_READ, 0)?; + let file_info = f.file_info()?; + let file_attr = FileAttr::from_uefi(file_info); + + if file_attr.file_type().is_dir() { + Ok(ReadDir(f)) + } else { + Err(io::const_error!(io::ErrorKind::NotADirectory, "expected a directory but got a file")) + } } pub fn unlink(p: &Path) -> io::Result<()> { @@ -459,13 +484,18 @@ mod uefi_fs { use r_efi::protocols::{device_path, file, simple_file_system}; use crate::boxed::Box; + use crate::ffi::OsString; use crate::io; + use crate::os::uefi::ffi::OsStringExt; use crate::path::Path; use crate::ptr::NonNull; use crate::sys::helpers::{self, UefiBox}; use crate::sys::time::{self, SystemTime}; - pub(crate) struct File(NonNull); + pub(crate) struct File { + protocol: NonNull, + path: crate::path::PathBuf, + } impl File { pub(crate) fn from_path(path: &Path, open_mode: u64, attr: u64) -> io::Result { @@ -474,7 +504,8 @@ mod uefi_fs { let p = helpers::OwnedDevicePath::from_text(absolute.as_os_str())?; let (vol, mut path_remaining) = Self::open_volume_from_device_path(p.borrow())?; - vol.open(&mut path_remaining, open_mode, attr) + let protocol = Self::open(vol, &mut path_remaining, open_mode, attr)?; + Ok(Self { protocol, path: absolute }) } /// Open Filesystem volume given a devicepath to the volume, or a file/directory in the @@ -490,7 +521,7 @@ mod uefi_fs { /// and return the remaining file path "\abc\run.efi". fn open_volume_from_device_path( path: helpers::BorrowedDevicePath<'_>, - ) -> io::Result<(Self, Box<[u16]>)> { + ) -> io::Result<(NonNull, Box<[u16]>)> { let handles = match helpers::locate_handles(simple_file_system::PROTOCOL_GUID) { Ok(x) => x, Err(e) => return Err(e), @@ -512,7 +543,9 @@ mod uefi_fs { } // Open volume on device_handle using SIMPLE_FILE_SYSTEM_PROTOCOL - fn open_volume(device_handle: NonNull) -> io::Result { + fn open_volume( + device_handle: NonNull, + ) -> io::Result> { let simple_file_system_protocol = helpers::open_protocol::( device_handle, simple_file_system::PROTOCOL_GUID, @@ -531,11 +564,16 @@ mod uefi_fs { // Since no error was returned, file protocol should be non-NULL. let p = NonNull::new(file_protocol).unwrap(); - Ok(Self(p)) + Ok(p) } - fn open(&self, path: &mut [u16], open_mode: u64, attr: u64) -> io::Result { - let file_ptr = self.0.as_ptr(); + fn open( + protocol: NonNull, + path: &mut [u16], + open_mode: u64, + attr: u64, + ) -> io::Result> { + let file_ptr = protocol.as_ptr(); let mut file_opened = crate::ptr::null_mut(); let r = unsafe { @@ -548,11 +586,37 @@ mod uefi_fs { // Since no error was returned, file protocol should be non-NULL. let p = NonNull::new(file_opened).unwrap(); - Ok(File(p)) + Ok(p) + } + + pub(crate) fn read_dir_entry(&self) -> io::Result>> { + let file_ptr = self.protocol.as_ptr(); + let mut buf_size = 0; + + let r = unsafe { ((*file_ptr).read)(file_ptr, &mut buf_size, crate::ptr::null_mut()) }; + + if buf_size == 0 { + return Ok(None); + } + + assert!(r.is_error()); + if r != r_efi::efi::Status::BUFFER_TOO_SMALL { + return Err(io::Error::from_raw_os_error(r.as_usize())); + } + + let mut info: UefiBox = UefiBox::new(buf_size)?; + let r = + unsafe { ((*file_ptr).read)(file_ptr, &mut buf_size, info.as_mut_ptr().cast()) }; + + if r.is_error() { + Err(io::Error::from_raw_os_error(r.as_usize())) + } else { + Ok(Some(info)) + } } pub(crate) fn file_info(&self) -> io::Result> { - let file_ptr = self.0.as_ptr(); + let file_ptr = self.protocol.as_ptr(); let mut info_id = file::INFO_ID; let mut buf_size = 0; @@ -583,7 +647,7 @@ mod uefi_fs { } pub(crate) fn set_file_info(&self, mut info: UefiBox) -> io::Result<()> { - let file_ptr = self.0.as_ptr(); + let file_ptr = self.protocol.as_ptr(); let mut info_id = file::INFO_ID; let r = unsafe { @@ -594,7 +658,7 @@ mod uefi_fs { } pub(crate) fn delete(self) -> io::Result<()> { - let file_ptr = self.0.as_ptr(); + let file_ptr = self.protocol.as_ptr(); let r = unsafe { ((*file_ptr).delete)(file_ptr) }; // Spec states that even in case of failure, the file handle will be closed. @@ -602,12 +666,16 @@ mod uefi_fs { if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } + + pub(crate) fn path(&self) -> &Path { + &self.path + } } impl Drop for File { fn drop(&mut self) { - let file_ptr = self.0.as_ptr(); - let _ = unsafe { ((*self.0.as_ptr()).close)(file_ptr) }; + let file_ptr = self.protocol.as_ptr(); + let _ = unsafe { ((*file_ptr).close)(file_ptr) }; } } @@ -647,7 +715,7 @@ mod uefi_fs { let (vol, mut path_remaining) = File::open_volume_from_device_path(p.borrow())?; // Check if file exists - match vol.open(&mut path_remaining, file::MODE_READ, 0) { + match File::open(vol, &mut path_remaining, file::MODE_READ, 0) { Ok(_) => { return Err(io::Error::new(io::ErrorKind::AlreadyExists, "Path already exists")); } @@ -655,7 +723,8 @@ mod uefi_fs { Err(e) => return Err(e), } - let _ = vol.open( + let _ = File::open( + vol, &mut path_remaining, file::MODE_READ | file::MODE_WRITE | file::MODE_CREATE, file::DIRECTORY, @@ -680,4 +749,14 @@ mod uefi_fs { let now = time::system_time_internal::now(); time.to_uefi_loose(now.timezone, now.daylight) } + + pub(crate) fn file_name_from_uefi(info: &UefiBox) -> OsString { + let file_name = { + let size = unsafe { (*info.as_ptr()).size }; + let strlen = (size as usize - crate::mem::size_of::>() - 1) / 2; + unsafe { crate::slice::from_raw_parts((*info.as_ptr()).file_name.as_ptr(), strlen) } + }; + + OsString::from_wide(file_name) + } } From 4bd0e65bde6fdfc9b1e456336c1b30cb35e4c51e Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Mon, 15 Dec 2025 10:47:58 +0100 Subject: [PATCH 0891/3801] Port `#[rustc_legacy_const_generics]` to use attribute parser --- compiler/rustc_ast_lowering/src/lib.rs | 36 ++--- .../src/attributes/rustc_internal.rs | 46 +++++++ compiler/rustc_attr_parsing/src/context.rs | 7 +- .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_hir/src/attrs/pretty_printing.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 1 - compiler/rustc_passes/messages.ftl | 3 - compiler/rustc_passes/src/check_attr.rs | 64 +++------ compiler/rustc_passes/src/errors.rs | 7 - compiler/rustc_resolve/src/lib.rs | 67 +++++----- src/librustdoc/clean/mod.rs | 38 +++--- ...d-rustc_legacy_const_generics-arguments.rs | 20 +-- ...stc_legacy_const_generics-arguments.stderr | 125 +++++++++++------- 14 files changed, 229 insertions(+), 191 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 10093da97fe3..d0871b0b98f4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -237,25 +237,27 @@ impl SpanLowerer { #[extension(trait ResolverAstLoweringExt)] impl ResolverAstLowering { fn legacy_const_generic_args(&self, expr: &Expr) -> Option> { - if let ExprKind::Path(None, path) = &expr.kind { - // Don't perform legacy const generics rewriting if the path already - // has generic arguments. - if path.segments.last().unwrap().args.is_some() { - return None; - } + let ExprKind::Path(None, path) = &expr.kind else { + return None; + }; - if let Res::Def(DefKind::Fn, def_id) = self.partial_res_map.get(&expr.id)?.full_res()? { - // We only support cross-crate argument rewriting. Uses - // within the same crate should be updated to use the new - // const generics style. - if def_id.is_local() { - return None; - } + // Don't perform legacy const generics rewriting if the path already + // has generic arguments. + if path.segments.last().unwrap().args.is_some() { + return None; + } - if let Some(v) = self.legacy_const_generic_args.get(&def_id) { - return v.clone(); - } - } + let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?; + + // We only support cross-crate argument rewriting. Uses + // within the same crate should be updated to use the new + // const generics style. + if def_id.is_local() { + return None; + } + + if let Some(v) = self.legacy_const_generic_args.get(&def_id) { + return v.clone(); } None diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 4be141651ae6..f04d4ceea35a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1,3 +1,5 @@ +use rustc_ast::{LitIntType, LitKind, MetaItemLit}; + use super::prelude::*; use super::util::parse_single_integer; use crate::session_diagnostics::RustcScalableVectorCountOutOfRange; @@ -41,6 +43,50 @@ impl SingleAttributeParser for RustcLayoutScalarValidRangeEndParser } } +pub(crate) struct RustcLegacyConstGenericsParser; + +impl SingleAttributeParser for RustcLegacyConstGenericsParser { + const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const TEMPLATE: AttributeTemplate = template!(List: &["N"]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let ArgParser::List(meta_items) = args else { + cx.expected_list(cx.attr_span, args); + return None; + }; + + let mut parsed_indexes = ThinVec::new(); + let mut errored = false; + + for possible_index in meta_items.mixed() { + if let MetaItemOrLitParser::Lit(MetaItemLit { + kind: LitKind::Int(index, LitIntType::Unsuffixed), + .. + }) = possible_index + { + parsed_indexes.push((index.0 as usize, possible_index.span())); + } else { + cx.expected_integer_literal(possible_index.span()); + errored = true; + } + } + if errored { + return None; + } else if parsed_indexes.is_empty() { + cx.expected_at_least_one_argument(args.span()?); + return None; + } + + Some(AttributeKind::RustcLegacyConstGenerics { + fn_indexes: parsed_indexes, + attr_span: cx.attr_span, + }) + } +} + pub(crate) struct RustcObjectLifetimeDefaultParser; impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9c7006f84024..242e0c013bc0 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -59,9 +59,9 @@ use crate::attributes::proc_macro_attrs::{ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ - RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcMainParser, - RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, - RustcSimdMonomorphizeLaneLimitParser, + RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, + RustcLegacyConstGenericsParser, RustcMainParser, RustcObjectLifetimeDefaultParser, + RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -209,6 +209,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 5f38eaf4d5f4..177a4247e6f0 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -869,6 +869,9 @@ pub enum AttributeKind { /// Represents `#[rustc_layout_scalar_valid_range_start]`. RustcLayoutScalarValidRangeStart(Box, Span), + /// Represents `#[rustc_legacy_const_generics]` + RustcLegacyConstGenerics { fn_indexes: ThinVec<(usize, Span)>, attr_span: Span }, + /// Represents `#[rustc_main]`. RustcMain, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 90fb0497a5b2..10b7af14aeae 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -92,6 +92,7 @@ impl AttributeKind { RustcCoherenceIsCore(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, + RustcLegacyConstGenerics { .. } => Yes, RustcMain => No, RustcObjectLifetimeDefault => No, RustcPassIndirectlyInNonRusticAbis(..) => No, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index 8bd267a1c256..f8ac2a547ca8 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -169,7 +169,7 @@ macro_rules! print_tup { print_tup!(A B C D E F G H); print_skip!(Span, (), ErrorGuaranteed); -print_disp!(u16, u128, bool, NonZero, Limit); +print_disp!(u16, u128, usize, bool, NonZero, Limit); print_debug!( Symbol, Ident, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 91e6e6326c09..2021f175cd84 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -197,7 +197,6 @@ pub struct ResolverGlobalCtxt { #[derive(Debug)] pub struct ResolverAstLowering { pub legacy_const_generic_args: FxHashMap>>, - /// Resolutions for nodes that have a single resolution. pub partial_res_map: NodeMap, /// Resolutions for import nodes, which have multiple resolutions in different namespaces. diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 21191085253b..0f206edcc775 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -478,9 +478,6 @@ passes_rustc_legacy_const_generics_index_exceed = *[other] arguments } -passes_rustc_legacy_const_generics_index_negative = - arguments should be non-negative integers - passes_rustc_legacy_const_generics_only = #[rustc_legacy_const_generics] functions must only have const generics .label = non-const generic parameter diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e836277e9761..f4896a8ca878 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -10,9 +10,10 @@ use std::collections::hash_map::Entry; use std::slice; use rustc_abi::{Align, ExternAbi, Size}; -use rustc_ast::{AttrStyle, LitKind, MetaItemKind, ast}; +use rustc_ast::{AttrStyle, MetaItemKind, ast}; use rustc_attr_parsing::{AttributeParser, Late}; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; use rustc_feature::{ ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, @@ -211,6 +212,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::MacroExport { span, .. }) => { self.check_macro_export(hir_id, *span, target) }, + Attribute::Parsed(AttributeKind::RustcLegacyConstGenerics{attr_span, fn_indexes}) => { + self.check_rustc_legacy_const_generics(item, *attr_span, fn_indexes) + }, Attribute::Parsed(AttributeKind::Doc(attr)) => self.check_doc_attrs(attr, hir_id, target), Attribute::Parsed(AttributeKind::EiiImpls(impls)) => { self.check_eii_impl(impls, target) @@ -306,9 +310,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_never_returns_null_ptr, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } - [sym::rustc_legacy_const_generics, ..] => { - self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item) - } [sym::rustc_lint_query_instability, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } @@ -1218,33 +1219,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument. fn check_rustc_legacy_const_generics( &self, - hir_id: HirId, - attr: &Attribute, - span: Span, - target: Target, item: Option>, + attr_span: Span, + index_list: &ThinVec<(usize, Span)>, ) { - let is_function = matches!(target, Target::Fn); - if !is_function { - self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { - attr_span: attr.span(), - defn_span: span, - on_crate: hir_id == CRATE_HIR_ID, - }); - return; - } - - let Some(list) = attr.meta_item_list() else { - // The attribute form is validated on AST. - return; - }; - let Some(ItemLike::Item(Item { kind: ItemKind::Fn { sig: FnSig { decl, .. }, generics, .. }, .. })) = item else { - bug!("should be a function item"); + // No error here, since it's already given by the parser + return; }; for param in generics.params { @@ -1252,7 +1237,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { hir::GenericParamKind::Const { .. } => {} _ => { self.dcx().emit_err(errors::RustcLegacyConstGenericsOnly { - attr_span: attr.span(), + attr_span, param_span: param.span, }); return; @@ -1260,34 +1245,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - if list.len() != generics.params.len() { + if index_list.len() != generics.params.len() { self.dcx().emit_err(errors::RustcLegacyConstGenericsIndex { - attr_span: attr.span(), + attr_span, generics_span: generics.span, }); return; } - let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128; - let mut invalid_args = vec![]; - for meta in list { - if let Some(LitKind::Int(val, _)) = meta.lit().map(|lit| &lit.kind) { - if *val >= arg_count { - let span = meta.span(); - self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexExceed { - span, - arg_count: arg_count as usize, - }); - return; - } - } else { - invalid_args.push(meta.span()); + let arg_count = decl.inputs.len() + generics.params.len(); + for (index, span) in index_list { + if *index >= arg_count { + self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexExceed { + span: *span, + arg_count, + }); } } - - if !invalid_args.is_empty() { - self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexNegative { invalid_args }); - } } /// Helper function for checking that the provided attribute is only applied to a function or diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 7abd2c703aeb..8ead69da9916 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -290,13 +290,6 @@ pub(crate) struct RustcLegacyConstGenericsIndexExceed { pub arg_count: usize, } -#[derive(Diagnostic)] -#[diag(passes_rustc_legacy_const_generics_index_negative)] -pub(crate) struct RustcLegacyConstGenericsIndexNegative { - #[primary_span] - pub invalid_args: Vec, -} - #[derive(Diagnostic)] #[diag(passes_rustc_dirty_clean)] pub(crate) struct RustcDirtyClean { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b3141406e467..d373d6136b52 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -44,7 +44,7 @@ use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::node_id::NodeMap; use rustc_ast::{ self as ast, AngleBracketedArg, CRATE_NODE_ID, Crate, Expr, ExprKind, GenericArg, GenericArgs, - LitKind, NodeId, Path, attr, + NodeId, Path, attr, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; @@ -54,7 +54,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed, LintBuffer}; use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; use rustc_feature::BUILTIN_ATTRIBUTES; -use rustc_hir::attrs::StrippedCfgItem; +use rustc_hir::attrs::{AttributeKind, StrippedCfgItem}; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{ self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, MacroKinds, NonMacroAttrKind, PartialRes, @@ -62,7 +62,7 @@ use rustc_hir::def::{ }; use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::DisambiguatorState; -use rustc_hir::{PrimTy, TraitCandidate}; +use rustc_hir::{PrimTy, TraitCandidate, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::CStore; use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; @@ -1676,8 +1676,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { node_id_to_def_id, disambiguator: DisambiguatorState::new(), placeholder_field_indices: Default::default(), - invocation_parents, legacy_const_generic_args: Default::default(), + invocation_parents, item_generics_num_lifetimes: Default::default(), trait_impls: Default::default(), confused_type_with_std_module: Default::default(), @@ -2396,40 +2396,33 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// `#[rustc_legacy_const_generics]` and returns the argument index list /// from the attribute. fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option> { - if let ExprKind::Path(None, path) = &expr.kind { - // Don't perform legacy const generics rewriting if the path already - // has generic arguments. - if path.segments.last().unwrap().args.is_some() { - return None; - } - - let res = self.partial_res_map.get(&expr.id)?.full_res()?; - if let Res::Def(def::DefKind::Fn, def_id) = res { - // We only support cross-crate argument rewriting. Uses - // within the same crate should be updated to use the new - // const generics style. - if def_id.is_local() { - return None; - } - - if let Some(v) = self.legacy_const_generic_args.get(&def_id) { - return v.clone(); - } - - let attr = self.tcx.get_attr(def_id, sym::rustc_legacy_const_generics)?; - let mut ret = Vec::new(); - for meta in attr.meta_item_list()? { - match meta.lit()?.kind { - LitKind::Int(a, _) => ret.push(a.get() as usize), - _ => panic!("invalid arg index"), - } - } - // Cache the lookup to avoid parsing attributes for an item multiple times. - self.legacy_const_generic_args.insert(def_id, Some(ret.clone())); - return Some(ret); - } + let ExprKind::Path(None, path) = &expr.kind else { + return None; + }; + // Don't perform legacy const generics rewriting if the path already + // has generic arguments. + if path.segments.last().unwrap().args.is_some() { + return None; } - None + + let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?; + + // We only support cross-crate argument rewriting. Uses + // within the same crate should be updated to use the new + // const generics style. + if def_id.is_local() { + return None; + } + + let indexes = find_attr!( + // we can use parsed attrs here since for other crates they're already available + self.tcx.get_all_attrs(def_id), + AttributeKind::RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes + ) + .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect()); + + self.legacy_const_generic_args.insert(def_id, indexes.clone()); + indexes } fn resolve_main(&mut self) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dd5c50d2ba37..764b3a0acdb6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1,7 +1,7 @@ //! This module defines the primary IR[^1] used in rustdoc together with the procedures that //! transform rustc data types into it. //! -//! This IR — commonly referred to as the *cleaned AST* — is modeled after the [AST][ast]. +//! This IR — commonly referred to as the *cleaned AST* — is modeled after the [AST][rustc_ast]. //! //! There are two kinds of transformation — *cleaning* — procedures: //! @@ -38,6 +38,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, In use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::codes::*; use rustc_errors::{FatalError, struct_span_code_err}; +use rustc_hir as hir; use rustc_hir::attrs::{AttributeKind, DocAttribute, DocInline}; use rustc_hir::def::{CtorKind, DefKind, MacroKinds, Res}; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId}; @@ -54,7 +55,6 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_trait_selection::traits::wf::object_region_bounds; use tracing::{debug, instrument}; use utils::*; -use {rustc_ast as ast, rustc_hir as hir}; pub(crate) use self::cfg::{CfgInfo, extract_cfg_from_attrs}; pub(crate) use self::types::*; @@ -1026,26 +1026,20 @@ fn clean_fn_or_proc_macro<'tcx>( /// `rustc_legacy_const_generics`. More information in /// . fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attribute]) { - for meta_item_list in attrs - .iter() - .filter(|a| a.has_name(sym::rustc_legacy_const_generics)) - .filter_map(|a| a.meta_item_list()) - { - for (pos, literal) in meta_item_list.iter().filter_map(|meta| meta.lit()).enumerate() { - match literal.kind { - ast::LitKind::Int(a, _) => { - let GenericParamDef { name, kind, .. } = func.generics.params.remove(0); - if let GenericParamDefKind::Const { ty, .. } = kind { - func.decl.inputs.insert( - a.get() as _, - Parameter { name: Some(name), type_: *ty, is_const: true }, - ); - } else { - panic!("unexpected non const in position {pos}"); - } - } - _ => panic!("invalid arg index"), - } + let Some(indexes) = + find_attr!(attrs, AttributeKind::RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes) + else { + return; + }; + + for (pos, (index, _)) in indexes.iter().enumerate() { + let GenericParamDef { name, kind, .. } = func.generics.params.remove(0); + if let GenericParamDefKind::Const { ty, .. } = kind { + func.decl + .inputs + .insert(*index, Parameter { name: Some(name), type_: *ty, is_const: true }); + } else { + panic!("unexpected non const in position {pos}"); } } } diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs index 73a0363904ae..03a28fac95de 100644 --- a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs +++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs @@ -9,20 +9,24 @@ fn foo2() {} #[rustc_legacy_const_generics(2)] //~ ERROR index exceeds number of arguments fn foo3(_: u8) {} -#[rustc_legacy_const_generics(a)] //~ ERROR arguments should be non-negative integers +#[rustc_legacy_const_generics(a)] //~ ERROR malformed `rustc_legacy_const_generics` attribute input fn foo4() {} -#[rustc_legacy_const_generics(1, a, 2, b)] //~ ERROR arguments should be non-negative integers +#[rustc_legacy_const_generics(1, a, 2, b)] +//~^ ERROR malformed `rustc_legacy_const_generics` attribute input +//~^^ ERROR malformed `rustc_legacy_const_generics` attribute input fn foo5() {} -#[rustc_legacy_const_generics(0)] //~ ERROR attribute should be applied to a function +#[rustc_legacy_const_generics(0)] //~ ERROR `#[rustc_legacy_const_generics]` attribute cannot be used on structs struct S; -#[rustc_legacy_const_generics(0usize)] //~ ERROR suffixed literals are not allowed in attributes +#[rustc_legacy_const_generics(0usize)] +//~^ ERROR suffixed literals are not allowed in attributes +//~^^ ERROR malformed `rustc_legacy_const_generics` attribute input fn foo6() {} extern "C" { - #[rustc_legacy_const_generics(1)] //~ ERROR attribute should be applied to a function + #[rustc_legacy_const_generics(1)] //~ ERROR `#[rustc_legacy_const_generics]` attribute cannot be used on foreign functions fn foo7(); //~ ERROR foreign items may not have const parameters } @@ -30,14 +34,14 @@ extern "C" { fn foo8() {} impl S { - #[rustc_legacy_const_generics(0)] //~ ERROR attribute should be applied to a function + #[rustc_legacy_const_generics(0)] //~ ERROR `#[rustc_legacy_const_generics]` attribute cannot be used on inherent methods fn foo9() {} } -#[rustc_legacy_const_generics] //~ ERROR malformed `rustc_legacy_const_generics` attribute +#[rustc_legacy_const_generics] //~ ERROR malformed `rustc_legacy_const_generics` attribute input fn bar1() {} -#[rustc_legacy_const_generics = 1] //~ ERROR malformed `rustc_legacy_const_generics` attribute +#[rustc_legacy_const_generics = 1] //~ ERROR malformed `rustc_legacy_const_generics` attribute input fn bar2() {} fn main() {} diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr index 1ced1433fe95..e4da6c86c83e 100644 --- a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr +++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr @@ -1,22 +1,88 @@ +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:12:1 + | +LL | #[rustc_legacy_const_generics(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:15:1 + | +LL | #[rustc_legacy_const_generics(1, a, 2, b)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:15:1 + | +LL | #[rustc_legacy_const_generics(1, a, 2, b)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error: `#[rustc_legacy_const_generics]` attribute cannot be used on structs + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:20:1 + | +LL | #[rustc_legacy_const_generics(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_legacy_const_generics]` can only be applied to functions + error: suffixed literals are not allowed in attributes - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:21:31 + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:23:31 | LL | #[rustc_legacy_const_generics(0usize)] | ^^^^^^ | = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) -error: malformed `rustc_legacy_const_generics` attribute input - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:37:1 +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:23:1 + | +LL | #[rustc_legacy_const_generics(0usize)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error: `#[rustc_legacy_const_generics]` attribute cannot be used on foreign functions + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:5 + | +LL | #[rustc_legacy_const_generics(1)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_legacy_const_generics]` can only be applied to functions + +error: `#[rustc_legacy_const_generics]` attribute cannot be used on inherent methods + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:37:5 + | +LL | #[rustc_legacy_const_generics(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_legacy_const_generics]` can only be applied to functions + +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:41:1 | LL | #[rustc_legacy_const_generics] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_legacy_const_generics(N)]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` -error: malformed `rustc_legacy_const_generics` attribute input - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:40:1 +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:44:1 | LL | #[rustc_legacy_const_generics = 1] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_legacy_const_generics(N)]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | expected this to be a list + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` error: #[rustc_legacy_const_generics] must have one index for each generic parameter --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:3:1 @@ -38,58 +104,23 @@ error: index exceeds number of arguments LL | #[rustc_legacy_const_generics(2)] | ^ there are only 2 arguments -error: arguments should be non-negative integers - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:12:31 - | -LL | #[rustc_legacy_const_generics(a)] - | ^ - -error: arguments should be non-negative integers - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:15:34 - | -LL | #[rustc_legacy_const_generics(1, a, 2, b)] - | ^ ^ - -error: attribute should be applied to a function definition - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:18:1 - | -LL | #[rustc_legacy_const_generics(0)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | struct S; - | --------- not a function definition - error: #[rustc_legacy_const_generics] functions must only have const generics - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:1 + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:33:1 | LL | #[rustc_legacy_const_generics(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | fn foo8() {} | - non-const generic parameter -error: attribute should be applied to a function definition - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:33:5 - | -LL | #[rustc_legacy_const_generics(0)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | fn foo9() {} - | ---------------------------- not a function definition - -error: attribute should be applied to a function definition - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:25:5 - | -LL | #[rustc_legacy_const_generics(1)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | fn foo7(); - | -------------------------- not a function definition - error[E0044]: foreign items may not have const parameters - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:26:5 + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:30:5 | LL | fn foo7(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters | = help: replace the const parameters with concrete consts -error: aborting due to 13 previous errors +error: aborting due to 15 previous errors -For more information about this error, try `rustc --explain E0044`. +Some errors have detailed explanations: E0044, E0539. +For more information about an error, try `rustc --explain E0044`. From 1308c0afc76e8407fe76d10b519dc8a1aef5a96b Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 16 Dec 2025 17:40:02 +0200 Subject: [PATCH 0892/3801] Remove Rust ungram file from the Ungrammar repo It can be confused with the real Rust ungram, now that they're in the same repo. --- .../rust-analyzer/lib/ungrammar/rust.ungram | 666 ------------------ .../rust-analyzer/lib/ungrammar/src/lib.rs | 11 - 2 files changed, 677 deletions(-) delete mode 100644 src/tools/rust-analyzer/lib/ungrammar/rust.ungram diff --git a/src/tools/rust-analyzer/lib/ungrammar/rust.ungram b/src/tools/rust-analyzer/lib/ungrammar/rust.ungram deleted file mode 100644 index 7781e719e2af..000000000000 --- a/src/tools/rust-analyzer/lib/ungrammar/rust.ungram +++ /dev/null @@ -1,666 +0,0 @@ -// Note this grammar file does not reflect the current language as this file is no longer maintained. - -// Rust Un-Grammar. -// -// This grammar specifies the structure of Rust's concrete syntax tree. -// It does not specify parsing rules (ambiguities, precedence, etc are out of scope). -// Tokens are processed -- contextual keywords are recognised, compound operators glued. -// -// Legend: -// -// // -- comment -// Name = -- non-terminal definition -// 'ident' -- token (terminal) -// A B -- sequence -// A | B -- alternation -// A* -- zero or more repetition -// A? -- zero or one repetition -// (A) -- same as A -// label:A -- suggested name for field of AST node - -//*************************// -// Names, Paths and Macros // -//*************************// - -Name = - 'ident' | 'self' - -NameRef = - 'ident' | 'int_number' | 'self' | 'super' | 'crate' | 'Self' - -Lifetime = - 'lifetime_ident' - -Path = - (qualifier:Path '::')? segment:PathSegment - -PathSegment = - '::'? NameRef -| NameRef GenericArgList? -| NameRef ParamList RetType? -| '<' PathType ('as' PathType)? '>' - -GenericArgList = - '::'? '<' (GenericArg (',' GenericArg)* ','?)? '>' - -GenericArg = - TypeArg -| AssocTypeArg -| LifetimeArg -| ConstArg - -TypeArg = - Type - -AssocTypeArg = - NameRef GenericParamList? (':' TypeBoundList | '=' Type) - -LifetimeArg = - Lifetime - -ConstArg = - Expr - -MacroCall = - Attr* Path '!' TokenTree ';'? - -TokenTree = - '(' ')' -| '{' '}' -| '[' ']' - -MacroItems = - Item* - -MacroStmts = - statements:Stmt* - Expr? - -//*************************// -// Items // -//*************************// - -SourceFile = - 'shebang'? - Attr* - Item* - -Item = - Const -| Enum -| ExternBlock -| ExternCrate -| Fn -| Impl -| MacroCall -| MacroRules -| MacroDef -| Module -| Static -| Struct -| Trait -| TypeAlias -| Union -| Use - -MacroRules = - Attr* Visibility? - 'macro_rules' '!' Name - TokenTree - -MacroDef = - Attr* Visibility? - 'macro' Name args:TokenTree? - body:TokenTree - -Module = - Attr* Visibility? - 'mod' Name - (ItemList | ';') - -ItemList = - '{' Attr* Item* '}' - -ExternCrate = - Attr* Visibility? - 'extern' 'crate' NameRef Rename? ';' - -Rename = - 'as' (Name | '_') - -Use = - Attr* Visibility? - 'use' UseTree ';' - -UseTree = - (Path? '::')? ('*' | UseTreeList) -| Path Rename? - -UseTreeList = - '{' (UseTree (',' UseTree)* ','?)? '}' - -Fn = - Attr* Visibility? - 'default'? 'const'? 'async'? 'unsafe'? Abi? - 'fn' Name GenericParamList? ParamList RetType? WhereClause? - (body:BlockExpr | ';') - -Abi = - 'extern' 'string'? - -ParamList = - '('( - SelfParam - | (SelfParam ',')? (Param (',' Param)* ','?)? - )')' -| '|' (Param (',' Param)* ','?)? '|' - -SelfParam = - Attr* ( - ('&' Lifetime?)? 'mut'? Name - | 'mut'? Name ':' Type - ) - -Param = - Attr* ( - Pat (':' Type)? - | Type - | '...' - ) - -RetType = - '->' Type - -TypeAlias = - Attr* Visibility? - 'default'? - 'type' Name GenericParamList? (':' TypeBoundList?)? WhereClause? - ('=' Type)? ';' - -Struct = - Attr* Visibility? - 'struct' Name GenericParamList? ( - WhereClause? (RecordFieldList | ';') - | TupleFieldList WhereClause? ';' - ) - -RecordFieldList = - '{' fields:(RecordField (',' RecordField)* ','?)? '}' - -RecordField = - Attr* Visibility? - Name ':' Type - -TupleFieldList = - '(' fields:(TupleField (',' TupleField)* ','?)? ')' - -TupleField = - Attr* Visibility? - Type - -FieldList = - RecordFieldList -| TupleFieldList - -Enum = - Attr* Visibility? - 'enum' Name GenericParamList? WhereClause? - VariantList - -VariantList = - '{' (Variant (',' Variant)* ','?)? '}' - -Variant = - Attr* Visibility? - Name FieldList? ('=' Expr)? - -Union = - Attr* Visibility? - 'union' Name GenericParamList? WhereClause? - RecordFieldList - -// A Data Type. -// -// Not used directly in the grammar, but handy to have anyway. -Adt = - Enum -| Struct -| Union - -Const = - Attr* Visibility? - 'default'? - 'const' (Name | '_') ':' Type - ('=' body:Expr)? ';' - -Static = - Attr* Visibility? - 'static' 'mut'? Name ':' Type - ('=' body:Expr)? ';' - -Trait = - Attr* Visibility? - 'unsafe'? 'auto'? - 'trait' Name GenericParamList? (':' TypeBoundList?)? WhereClause? - AssocItemList - -AssocItemList = - '{' Attr* AssocItem* '}' - -AssocItem = - Const -| Fn -| MacroCall -| TypeAlias - -Impl = - Attr* Visibility? - 'default'? 'unsafe'? - 'impl' GenericParamList? ('const'? '!'? trait:Type 'for')? self_ty:Type WhereClause? - AssocItemList - -ExternBlock = - Attr* 'unsafe'? Abi ExternItemList - -ExternItemList = - '{' Attr* ExternItem* '}' - -ExternItem = - Fn -| MacroCall -| Static -| TypeAlias - -GenericParamList = - '<' (GenericParam (',' GenericParam)* ','?)? '>' - -GenericParam = - ConstParam -| LifetimeParam -| TypeParam - -TypeParam = - Attr* Name (':' TypeBoundList?)? - ('=' default_type:Type)? - -ConstParam = - Attr* 'const' Name ':' Type - ('=' default_val:Expr)? - -LifetimeParam = - Attr* Lifetime (':' TypeBoundList?)? - -WhereClause = - 'where' predicates:(WherePred (',' WherePred)* ','?) - -WherePred = - ('for' GenericParamList)? (Lifetime | Type) ':' TypeBoundList? - -Visibility = - 'pub' ('(' 'in'? Path ')')? - -Attr = - '#' '!'? '[' Meta ']' - -Meta = - Path ('=' Expr | TokenTree)? - -//****************************// -// Statements and Expressions // -//****************************// - -Stmt = - ';' -| ExprStmt -| Item -| LetStmt - -LetStmt = - Attr* 'let' Pat (':' Type)? - '=' initializer:Expr - LetElse? - ';' - -LetElse = - 'else' BlockExpr - -ExprStmt = - Expr ';'? - -Expr = - ArrayExpr -| AwaitExpr -| BinExpr -| BlockExpr -| BoxExpr -| BreakExpr -| CallExpr -| CastExpr -| ClosureExpr -| ContinueExpr -| FieldExpr -| ForExpr -| IfExpr -| IndexExpr -| Literal -| LoopExpr -| MacroCall -| MacroStmts -| MatchExpr -| MethodCallExpr -| ParenExpr -| PathExpr -| PrefixExpr -| RangeExpr -| RecordExpr -| RefExpr -| ReturnExpr -| TryExpr -| TupleExpr -| WhileExpr -| YieldExpr -| LetExpr -| UnderscoreExpr - -Literal = - Attr* value:( - 'int_number' | 'float_number' - | 'string' | 'raw_string' - | 'byte_string' | 'raw_byte_string' - | 'true' | 'false' - | 'char' | 'byte' - ) - -PathExpr = - Attr* Path - -StmtList = - '{' - Attr* - statements:Stmt* - tail_expr:Expr? - '}' - -RefExpr = - Attr* '&' ('raw' | 'mut' | 'const') Expr - -TryExpr = - Attr* Expr '?' - -BlockExpr = - Attr* Label? ('try' | 'unsafe' | 'async' | 'const') StmtList - -PrefixExpr = - Attr* op:('-' | '!' | '*') Expr - -BinExpr = - Attr* - lhs:Expr - op:( - '||' | '&&' - | '==' | '!=' | '<=' | '>=' | '<' | '>' - | '+' | '*' | '-' | '/' | '%' | '<<' | '>>' | '^' | '|' | '&' - | '=' | '+=' | '/=' | '*=' | '%=' | '>>=' | '<<=' | '-=' | '|=' | '&=' | '^=' - ) - rhs:Expr - -CastExpr = - Attr* Expr 'as' Type - -ParenExpr = - Attr* '(' Attr* Expr ')' - -ArrayExpr = - Attr* '[' Attr* ( - (Expr (',' Expr)* ','?)? - | Expr ';' Expr - ) ']' - -IndexExpr = - Attr* base:Expr '[' index:Expr ']' - -TupleExpr = - Attr* '(' Attr* fields:(Expr (',' Expr)* ','?)? ')' - -RecordExpr = - Path RecordExprFieldList - -RecordExprFieldList = - '{' - Attr* - fields:(RecordExprField (',' RecordExprField)* ','?)? - ('..' spread:Expr?)? - '}' - -RecordExprField = - Attr* (NameRef ':')? Expr - -CallExpr = - Attr* Expr ArgList - -ArgList = - '(' args:(Expr (',' Expr)* ','?)? ')' - -MethodCallExpr = - Attr* receiver:Expr '.' NameRef GenericArgList? ArgList - -FieldExpr = - Attr* Expr '.' NameRef - -ClosureExpr = - Attr* 'static'? 'async'? 'move'? ParamList RetType? - body:Expr - -IfExpr = - Attr* 'if' condition:Expr then_branch:BlockExpr - ('else' else_branch:(IfExpr | BlockExpr))? - -LoopExpr = - Attr* Label? 'loop' - loop_body:BlockExpr - -ForExpr = - Attr* Label? 'for' Pat 'in' iterable:Expr - loop_body:BlockExpr - -WhileExpr = - Attr* Label? 'while' condition:Expr - loop_body:BlockExpr - -Label = - Lifetime ':' - -BreakExpr = - Attr* 'break' Lifetime? Expr? - -ContinueExpr = - Attr* 'continue' Lifetime? - -RangeExpr = - Attr* start:Expr? op:('..' | '..=') end:Expr? - -MatchExpr = - Attr* 'match' Expr MatchArmList - -MatchArmList = - '{' - Attr* - arms:MatchArm* - '}' - -MatchArm = - Attr* Pat guard:MatchGuard? '=>' Expr ','? - -MatchGuard = - 'if' condition:Expr - -ReturnExpr = - Attr* 'return' Expr? - -YieldExpr = - Attr* 'yield' Expr? - -LetExpr = - Attr* 'let' Pat '=' Expr - -UnderscoreExpr = - Attr* '_' - -AwaitExpr = - Attr* Expr '.' 'await' - -BoxExpr = - Attr* 'box' Expr - -//*************************// -// Types // -//*************************// - -Type = - ArrayType -| DynTraitType -| FnPtrType -| ForType -| ImplTraitType -| InferType -| MacroType -| NeverType -| ParenType -| PathType -| PtrType -| RefType -| SliceType -| TupleType - -ParenType = - '(' Type ')' - -NeverType = - '!' - -MacroType = - MacroCall - -PathType = - Path - -TupleType = - '(' fields:(Type (',' Type)* ','?)? ')' - -PtrType = - '*' ('const' | 'mut') Type - -RefType = - '&' Lifetime? 'mut'? Type - -ArrayType = - '[' Type ';' Expr ']' - -SliceType = - '[' Type ']' - -InferType = - '_' - -FnPtrType = - 'const'? 'async'? 'unsafe'? Abi? 'fn' ParamList RetType? - -ForType = - 'for' GenericParamList Type - -ImplTraitType = - 'impl' TypeBoundList - -DynTraitType = - 'dyn' TypeBoundList - -TypeBoundList = - bounds:(TypeBound ('+' TypeBound)* '+'?) - -TypeBound = - Lifetime -| ('?' | '~' 'const')? Type - -//************************// -// Patterns // -//************************// - -Pat = - IdentPat -| BoxPat -| RestPat -| LiteralPat -| MacroPat -| OrPat -| ParenPat -| PathPat -| WildcardPat -| RangePat -| RecordPat -| RefPat -| SlicePat -| TuplePat -| TupleStructPat -| ConstBlockPat - -LiteralPat = - Literal - -IdentPat = - Attr* 'ref'? 'mut'? Name ('@' Pat)? - -WildcardPat = - '_' - -RangePat = - // 1.. - start:Pat op:('..' | '..=') - // 1..2 - | start:Pat op:('..' | '..=') end:Pat - // ..2 - | op:('..' | '..=') end:Pat - -RefPat = - '&' 'mut'? Pat - -RecordPat = - Path RecordPatFieldList - -RecordPatFieldList = - '{' - fields:(RecordPatField (',' RecordPatField)* ','?)? - RestPat? - '}' - -RecordPatField = - Attr* (NameRef ':')? Pat - -TupleStructPat = - Path '(' fields:(Pat (',' Pat)* ','?)? ')' - -TuplePat = - '(' fields:(Pat (',' Pat)* ','?)? ')' - -ParenPat = - '(' Pat ')' - -SlicePat = - '[' (Pat (',' Pat)* ','?)? ']' - -PathPat = - Path - -OrPat = - (Pat ('|' Pat)* '|'?) - -BoxPat = - 'box' Pat - -RestPat = - Attr* '..' - -MacroPat = - MacroCall - -ConstBlockPat = - 'const' BlockExpr diff --git a/src/tools/rust-analyzer/lib/ungrammar/src/lib.rs b/src/tools/rust-analyzer/lib/ungrammar/src/lib.rs index 6adf8ef8ea6a..e31b0c2f470a 100644 --- a/src/tools/rust-analyzer/lib/ungrammar/src/lib.rs +++ b/src/tools/rust-analyzer/lib/ungrammar/src/lib.rs @@ -19,12 +19,6 @@ use std::{ops, str::FromStr}; pub use error::{Error, Result}; -/// Returns a Rust grammar. -pub fn rust_grammar() -> Grammar { - let src = include_str!("../rust.ungram"); - src.parse().unwrap() -} - /// A node, like `A = 'b' | 'c'`. /// /// Indexing into a [`Grammar`] with a [`Node`] returns a reference to a @@ -130,8 +124,3 @@ fn smoke() { let grammar = grammar.parse::().unwrap(); drop(grammar) } - -#[test] -fn test_rust_grammar() { - let _ = rust_grammar(); -} From ca398e04feecfa2e84dc276c2d602035e65724b8 Mon Sep 17 00:00:00 2001 From: sayantn Date: Wed, 17 Dec 2025 01:41:29 +0530 Subject: [PATCH 0893/3801] panic if cpuid is called with SGX --- library/stdarch/crates/core_arch/src/x86/cpuid.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/stdarch/crates/core_arch/src/x86/cpuid.rs b/library/stdarch/crates/core_arch/src/x86/cpuid.rs index 84dcf75492b3..b35699bd7ab2 100644 --- a/library/stdarch/crates/core_arch/src/x86/cpuid.rs +++ b/library/stdarch/crates/core_arch/src/x86/cpuid.rs @@ -59,6 +59,10 @@ pub struct CpuidResult { #[cfg_attr(test, assert_instr(cpuid))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult { + if cfg!(target_env = "sgx") { + panic!("`__cpuid` cannot be used in SGX"); + } + let eax; let ebx; let ecx; From 96423581b2c5d792f25d5c6aab72c9d40d50980e Mon Sep 17 00:00:00 2001 From: Linshu Yang Date: Mon, 1 Dec 2025 22:08:08 +0000 Subject: [PATCH 0894/3801] Make `empty_enum_variants_with_brackets` to support empty variant with braces --- clippy_lints/src/empty_with_brackets.rs | 174 +++++++++--------- .../empty_enum_variants_with_brackets.fixed | 46 +++++ tests/ui/empty_enum_variants_with_brackets.rs | 46 +++++ .../empty_enum_variants_with_brackets.stderr | 33 +++- 4 files changed, 214 insertions(+), 85 deletions(-) diff --git a/clippy_lints/src/empty_with_brackets.rs b/clippy_lints/src/empty_with_brackets.rs index 5dc1bb96266a..7e335d5c9809 100644 --- a/clippy_lints/src/empty_with_brackets.rs +++ b/clippy_lints/src/empty_with_brackets.rs @@ -1,6 +1,8 @@ use clippy_utils::attrs::span_contains_cfg; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; -use rustc_data_structures::fx::FxIndexMap; +use clippy_utils::source::SpanRangeExt; +use clippy_utils::span_contains_non_whitespace; +use rustc_data_structures::fx::{FxIndexMap, IndexEntry}; use rustc_errors::Applicability; use rustc_hir::def::DefKind::Ctor; use rustc_hir::def::Res::Def; @@ -10,7 +12,7 @@ use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node, Pat, PatKind, Path, QPath, use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::impl_lint_pass; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does @@ -118,7 +120,6 @@ impl LateLintPass<'_> for EmptyWithBrackets { } fn check_variant(&mut self, cx: &LateContext<'_>, variant: &Variant<'_>) { - // FIXME: handle `$name {}` if !variant.span.from_expansion() && !variant.ident.span.from_expansion() && let span_after_ident = variant.span.with_lo(variant.ident.span.hi()) @@ -126,44 +127,14 @@ impl LateLintPass<'_> for EmptyWithBrackets { { match variant.data { VariantData::Struct { .. } => { - // Empty struct variants can be linted immediately - span_lint_and_then( - cx, - EMPTY_ENUM_VARIANTS_WITH_BRACKETS, - span_after_ident, - "enum variant has empty brackets", - |diagnostic| { - diagnostic.span_suggestion_hidden( - span_after_ident, - "remove the brackets", - "", - Applicability::MaybeIncorrect, - ); - }, - ); + self.add_enum_variant(variant.def_id); }, VariantData::Tuple(.., local_def_id) => { // Don't lint reachable tuple enums if cx.effective_visibilities.is_reachable(variant.def_id) { return; } - if let Some(entry) = self.empty_tuple_enum_variants.get_mut(&local_def_id) { - // empty_tuple_enum_variants contains Usage::NoDefinition if the variant was called before the - // definition was encountered. Now that there's a definition, convert it - // to Usage::Unused. - if let Usage::NoDefinition { redundant_use_sites } = entry { - *entry = Usage::Unused { - redundant_use_sites: redundant_use_sites.clone(), - }; - } - } else { - self.empty_tuple_enum_variants.insert( - local_def_id, - Usage::Unused { - redundant_use_sites: vec![], - }, - ); - } + self.add_enum_variant(local_def_id); }, VariantData::Unit(..) => {}, } @@ -171,45 +142,58 @@ impl LateLintPass<'_> for EmptyWithBrackets { } fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if let Some(def_id) = check_expr_for_enum_as_function(expr) { - if let Some(parentheses_span) = call_parentheses_span(cx.tcx, expr) { + if let Some((def_id, mut span)) = check_expr_for_enum_as_function(cx, expr) { + if span.is_empty() + && let Some(parentheses_span) = call_parentheses_span(cx.tcx, expr) + { + span = parentheses_span; + } + + if span.is_empty() { + // The parentheses are not redundant. + self.empty_tuple_enum_variants.insert(def_id, Usage::Used); + } else { // Do not count expressions from macro expansion as a redundant use site. if expr.span.from_expansion() { return; } - self.update_enum_variant_usage(def_id, parentheses_span); - } else { - // The parentheses are not redundant. - self.empty_tuple_enum_variants.insert(def_id, Usage::Used); + self.update_enum_variant_usage(def_id, span); } } } fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) { - if let Some((def_id, parentheses_span)) = check_pat_for_enum_as_function(cx, pat) { - if pat.span.from_expansion() { - return; - } - - self.update_enum_variant_usage(def_id, parentheses_span); + if !pat.span.from_expansion() + && let Some((def_id, span)) = check_pat_for_enum_as_function(cx, pat) + { + self.update_enum_variant_usage(def_id, span); } } fn check_crate_post(&mut self, cx: &LateContext<'_>) { - for (local_def_id, usage) in &self.empty_tuple_enum_variants { + for (&local_def_id, usage) in &self.empty_tuple_enum_variants { // Ignore all variants with Usage::Used or Usage::NoDefinition let Usage::Unused { redundant_use_sites } = usage else { continue; }; + // Attempt to fetch the Variant from LocalDefId. - let Node::Variant(variant) = cx.tcx.hir_node( - cx.tcx - .local_def_id_to_hir_id(cx.tcx.parent(local_def_id.to_def_id()).expect_local()), - ) else { + let variant = if let Node::Variant(variant) = cx.tcx.hir_node_by_def_id(local_def_id) { + variant + } else if let Node::Variant(variant) = cx.tcx.hir_node_by_def_id(cx.tcx.local_parent(local_def_id)) { + variant + } else { continue; }; + // Span of the parentheses in variant definition let span = variant.span.with_lo(variant.ident.span.hi()); + let span_inner = span + .with_lo(SpanRangeExt::trim_start(span, cx).start + BytePos(1)) + .with_hi(span.hi() - BytePos(1)); + if span_contains_non_whitespace(cx, span_inner, false) { + continue; + } span_lint_hir_and_then( cx, EMPTY_ENUM_VARIANTS_WITH_BRACKETS, @@ -242,28 +226,38 @@ impl LateLintPass<'_> for EmptyWithBrackets { } impl EmptyWithBrackets { - fn update_enum_variant_usage(&mut self, def_id: LocalDefId, parentheses_span: Span) { - match self.empty_tuple_enum_variants.get_mut(&def_id) { - Some( - &mut (Usage::Unused { - ref mut redundant_use_sites, + fn add_enum_variant(&mut self, local_def_id: LocalDefId) { + self.empty_tuple_enum_variants + .entry(local_def_id) + .and_modify(|entry| { + // empty_tuple_enum_variants contains Usage::NoDefinition if the variant was called before + // the definition was encountered. Now that there's a + // definition, convert it to Usage::Unused. + if let Usage::NoDefinition { redundant_use_sites } = entry { + *entry = Usage::Unused { + redundant_use_sites: redundant_use_sites.clone(), + }; + } + }) + .or_insert_with(|| Usage::Unused { + redundant_use_sites: vec![], + }); + } + + fn update_enum_variant_usage(&mut self, def_id: LocalDefId, parentheses_span: Span) { + match self.empty_tuple_enum_variants.entry(def_id) { + IndexEntry::Occupied(mut e) => { + if let Usage::Unused { redundant_use_sites } | Usage::NoDefinition { redundant_use_sites } = e.get_mut() + { + redundant_use_sites.push(parentheses_span); } - | Usage::NoDefinition { - ref mut redundant_use_sites, - }), - ) => { - redundant_use_sites.push(parentheses_span); }, - None => { + IndexEntry::Vacant(e) => { // The variant isn't in the IndexMap which means its definition wasn't encountered yet. - self.empty_tuple_enum_variants.insert( - def_id, - Usage::NoDefinition { - redundant_use_sites: vec![parentheses_span], - }, - ); + e.insert(Usage::NoDefinition { + redundant_use_sites: vec![parentheses_span], + }); }, - _ => {}, } } } @@ -293,18 +287,27 @@ fn call_parentheses_span(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> Option { } // Returns the LocalDefId of the variant being called as a function if it exists. -fn check_expr_for_enum_as_function(expr: &Expr<'_>) -> Option { - if let ExprKind::Path(QPath::Resolved( - _, - Path { - res: Def(Ctor(CtorOf::Variant, _), def_id), - .. +fn check_expr_for_enum_as_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(LocalDefId, Span)> { + match expr.kind { + ExprKind::Path(QPath::Resolved( + _, + Path { + res: Def(Ctor(CtorOf::Variant, _), def_id), + span, + .. + }, + )) => def_id.as_local().map(|id| (id, span.with_lo(expr.span.hi()))), + ExprKind::Struct(qpath, ..) + if let Def(DefKind::Variant, mut def_id) = cx.typeck_results().qpath_res(qpath, expr.hir_id) => + { + let ty = cx.tcx.type_of(def_id).instantiate_identity(); + if let ty::FnDef(ctor_def_id, _) = ty.kind() { + def_id = *ctor_def_id; + } + + def_id.as_local().map(|id| (id, qpath.span().with_lo(expr.span.hi()))) }, - )) = expr.kind - { - def_id.as_local() - } else { - None + _ => None, } } @@ -316,10 +319,13 @@ fn check_pat_for_enum_as_function(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi()))) }, PatKind::Struct(qpath, ..) - if let Def(DefKind::Variant, def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) - && let ty = cx.tcx.type_of(def_id).instantiate_identity() - && let ty::FnDef(def_id, _) = ty.kind() => + if let Def(DefKind::Variant, mut def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) => { + let ty = cx.tcx.type_of(def_id).instantiate_identity(); + if let ty::FnDef(ctor_def_id, _) = ty.kind() { + def_id = *ctor_def_id; + } + def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi()))) }, _ => None, diff --git a/tests/ui/empty_enum_variants_with_brackets.fixed b/tests/ui/empty_enum_variants_with_brackets.fixed index 515d5a975944..caf34eaefab9 100644 --- a/tests/ui/empty_enum_variants_with_brackets.fixed +++ b/tests/ui/empty_enum_variants_with_brackets.fixed @@ -115,4 +115,50 @@ fn issue16157() { ::V = E::V; } +fn variant_with_braces() { + enum E { + V, + //~^ empty_enum_variants_with_brackets + } + E::V = E::V; + E::V = E::V; + ::V = ::V; + + enum F { + U, + //~^ empty_enum_variants_with_brackets + } + F::U = F::U; + ::U = F::U; +} + +fn variant_with_comments_and_cfg() { + enum E { + V( + // This is a comment + ), + } + E::V() = E::V(); + + enum F { + U { + // This is a comment + }, + } + F::U {} = F::U {}; + + enum G { + V(#[cfg(target_os = "cuda")] String), + } + G::V() = G::V(); + + enum H { + U { + #[cfg(target_os = "cuda")] + value: String, + }, + } + H::U {} = H::U {}; +} + fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.rs b/tests/ui/empty_enum_variants_with_brackets.rs index 2c29fc505d3b..f7ab062edd1e 100644 --- a/tests/ui/empty_enum_variants_with_brackets.rs +++ b/tests/ui/empty_enum_variants_with_brackets.rs @@ -115,4 +115,50 @@ fn issue16157() { ::V {} = E::V(); } +fn variant_with_braces() { + enum E { + V(), + //~^ empty_enum_variants_with_brackets + } + E::V() = E::V(); + E::V() = E::V {}; + ::V {} = ::V {}; + + enum F { + U {}, + //~^ empty_enum_variants_with_brackets + } + F::U {} = F::U {}; + ::U {} = F::U {}; +} + +fn variant_with_comments_and_cfg() { + enum E { + V( + // This is a comment + ), + } + E::V() = E::V(); + + enum F { + U { + // This is a comment + }, + } + F::U {} = F::U {}; + + enum G { + V(#[cfg(target_os = "cuda")] String), + } + G::V() = G::V(); + + enum H { + U { + #[cfg(target_os = "cuda")] + value: String, + }, + } + H::U {} = H::U {}; +} + fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.stderr b/tests/ui/empty_enum_variants_with_brackets.stderr index c487cebd21ac..d50b07036a94 100644 --- a/tests/ui/empty_enum_variants_with_brackets.stderr +++ b/tests/ui/empty_enum_variants_with_brackets.stderr @@ -96,5 +96,36 @@ LL ~ ::V = E::V; LL ~ ::V = E::V; | -error: aborting due to 9 previous errors +error: enum variant has empty brackets + --> tests/ui/empty_enum_variants_with_brackets.rs:120:10 + | +LL | V(), + | ^^ + | +help: remove the brackets + | +LL ~ V, +LL | +LL | } +LL ~ E::V = E::V; +LL ~ E::V = E::V; +LL ~ ::V = ::V; + | + +error: enum variant has empty brackets + --> tests/ui/empty_enum_variants_with_brackets.rs:128:10 + | +LL | U {}, + | ^^^ + | +help: remove the brackets + | +LL ~ U, +LL | +LL | } +LL ~ F::U = F::U; +LL ~ ::U = F::U; + | + +error: aborting due to 11 previous errors From 793d990d11fa7bf38677d27c88eccea6e360a783 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 16 Dec 2025 21:33:28 +0100 Subject: [PATCH 0895/3801] Emit a proper error if we fail to find libEnzyme --- compiler/rustc_codegen_llvm/messages.ftl | 3 ++- compiler/rustc_codegen_llvm/src/errors.rs | 5 +++++ compiler/rustc_codegen_llvm/src/lib.rs | 5 ++++- .../rustc_codegen_llvm/src/llvm/enzyme_ffi.rs | 18 ++++++++---------- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index 0e7b00d0bcb7..b3ef9840f5dc 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -1,9 +1,10 @@ +codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend. Did you install it via rustup? + codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err} - codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture codegen_llvm_from_llvm_diag = {$message} diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index dd9fde0b08c6..f2e147b1ee0a 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -32,6 +32,11 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { } } +#[cfg(feature = "llvm_enzyme")] +#[derive(Diagnostic)] +#[diag(codegen_llvm_autodiff_component_unavailable)] +pub(crate) struct AutoDiffComponentUnavailable; + #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_without_lto)] pub(crate) struct AutoDiffWithoutLto; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index c51b334d95e1..4d0f8dbb9302 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -13,6 +13,7 @@ #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] #![feature(macro_derive)] +#![feature(once_cell_try)] #![feature(trim_prefix_suffix)] #![feature(try_blocks)] // tidy-alphabetical-end @@ -247,7 +248,9 @@ impl CodegenBackend for LlvmCodegenBackend { use crate::back::lto::enable_autodiff_settings; if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) { - drop(llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot)); + if let Err(_) = llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) { + sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable); + } enable_autodiff_settings(&sess.opts.unstable_opts.autodiff); } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 28923bf2743e..956a4e43a7de 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -199,15 +199,13 @@ pub(crate) mod Enzyme_AD { /// Safe to call multiple times - subsequent calls are no-ops due to OnceLock. pub(crate) fn get_or_init( sysroot: &rustc_session::config::Sysroot, - ) -> MutexGuard<'static, Self> { - ENZYME_INSTANCE - .get_or_init(|| { - Self::call_dynamic(sysroot) - .unwrap_or_else(|e| bug!("failed to load Enzyme: {e}")) - .into() - }) - .lock() - .unwrap() + ) -> Result, Box> { + let mtx: &'static Mutex = ENZYME_INSTANCE.get_or_try_init(|| { + let w = Self::call_dynamic(sysroot)?; + Ok::<_, Box>(Mutex::new(w)) + })?; + + Ok(mtx.lock().unwrap()) } /// Get the EnzymeWrapper instance. Panics if not initialized. @@ -475,7 +473,7 @@ pub(crate) mod Fallback_AD { impl EnzymeWrapper { pub(crate) fn get_or_init( _sysroot: &rustc_session::config::Sysroot, - ) -> MutexGuard<'static, Self> { + ) -> Result, Box> { unimplemented!("Enzyme not available: build with llvm_enzyme feature") } From 6847bd0facd27b6a3a2d81eb457d1afb33352539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 16 Dec 2025 20:38:23 +0100 Subject: [PATCH 0896/3801] Revert 147888 --- src/bootstrap/src/core/config/toml/llvm.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/toml/llvm.rs b/src/bootstrap/src/core/config/toml/llvm.rs index 9523f8021484..9751837a8879 100644 --- a/src/bootstrap/src/core/config/toml/llvm.rs +++ b/src/bootstrap/src/core/config/toml/llvm.rs @@ -117,7 +117,7 @@ pub fn check_incompatible_options_for_ci_llvm( enable_warnings, download_ci_llvm: _, build_config, - enzyme: _, + enzyme, } = ci_llvm_config; err!(current_llvm_config.optimize, optimize); @@ -139,6 +139,7 @@ pub fn check_incompatible_options_for_ci_llvm( err!(current_llvm_config.clang, clang); err!(current_llvm_config.build_config, build_config); err!(current_llvm_config.plugins, plugins); + err!(current_llvm_config.enzyme, enzyme); warn!(current_llvm_config.enable_warnings, enable_warnings); From 7463b150441f8a43f59b284a42af4ce6cffe6a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 16 Dec 2025 20:40:29 +0100 Subject: [PATCH 0897/3801] Print warning if LLVM CMake directory does not exist --- src/bootstrap/src/core/build_steps/llvm.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index db2a76c4a2df..51a791daef28 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -925,7 +925,7 @@ impl Step for Enzyme { } let target = self.target; - let LlvmResult { host_llvm_config, .. } = builder.ensure(Llvm { target: self.target }); + let LlvmResult { host_llvm_config, llvm_cmake_dir } = builder.ensure(Llvm { target }); static STAMP_HASH_MEMO: OnceLock = OnceLock::new(); let smart_stamp_hash = STAMP_HASH_MEMO.get_or_init(|| { @@ -955,15 +955,20 @@ impl Step for Enzyme { return out_dir; } + if !builder.config.dry_run() && !llvm_cmake_dir.is_dir() { + builder.info(&format!( + "WARNING: {} does not exist, Enzyme build will likely fail", + llvm_cmake_dir.display() + )); + } + trace!(?target, "(re)building enzyme artifacts"); builder.info(&format!("Building Enzyme for {target}")); t!(stamp.remove()); let _time = helpers::timeit(builder); t!(fs::create_dir_all(&out_dir)); - builder - .config - .update_submodule(Path::new("src").join("tools").join("enzyme").to_str().unwrap()); + builder.config.update_submodule("src/tools/enzyme"); let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/")); configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]); @@ -983,7 +988,7 @@ impl Step for Enzyme { .define("LLVM_ENABLE_ASSERTIONS", "ON") .define("ENZYME_EXTERNAL_SHARED_LIB", "ON") .define("ENZYME_BC_LOADER", "OFF") - .define("LLVM_DIR", builder.llvm_out(target)); + .define("LLVM_DIR", llvm_cmake_dir); cfg.build(); From fc0d01b3a950d6a946f8f6a91732bf86fcb28623 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 16 Dec 2025 11:40:33 +0000 Subject: [PATCH 0898/3801] make the check calls fewer times --- compiler/rustc_mir_build/src/builder/mod.rs | 38 +++++++++------------ 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 14a24265a8f4..40f1fe0d5d11 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -838,26 +838,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.parent_module, self.infcx.typing_env(self.param_env), ); - - // check if the function's return type is inhabited - // this was added here because of this regression - // https://github.com/rust-lang/rust/issues/149571 - let output_is_inhabited = - if matches!(self.tcx.def_kind(self.def_id), DefKind::Fn | DefKind::AssocFn) { - self.tcx - .fn_sig(self.def_id) - .instantiate_identity() - .skip_binder() - .output() - .is_inhabited_from( - self.tcx, - self.parent_module, - self.infcx.typing_env(self.param_env), - ) - } else { - true - }; - if !ty_is_inhabited { // Unreachable code warnings are already emitted during type checking. // However, during type checking, full type information is being @@ -868,7 +848,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // uninhabited types (e.g. empty enums). The check above is used so // that we do not emit the same warning twice if the uninhabited type // is indeed `!`. - if !ty.is_never() && output_is_inhabited { + if !ty.is_never() + && matches!(self.tcx.def_kind(self.def_id), DefKind::Fn | DefKind::AssocFn) + // check if the function's return type is inhabited + // this was added here because of this regression + // https://github.com/rust-lang/rust/issues/149571 + && self + .tcx + .fn_sig(self.def_id) + .instantiate_identity() + .skip_binder() + .output() + .is_inhabited_from( + self.tcx, + self.parent_module, + self.infcx.typing_env(self.param_env), + ) + { lints.push((target_bb, ty, term.source_info.span)); } From 96c165b1110db7519e60f076a111b8a796180305 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 16 Dec 2025 22:38:34 +0100 Subject: [PATCH 0899/3801] Make `asm_experimental_arch` work in `allow_internal_unstable` macros --- compiler/rustc_ast_lowering/src/asm.rs | 10 +++++++++- .../ui/internal/auxiliary/internal_unstable.rs | 7 +++++++ .../internal-unstable-asm-experimental-arch.rs | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tests/ui/internal/internal-unstable-asm-experimental-arch.rs diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index d44faad017ee..04e5f0523101 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -52,7 +52,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | asm::InlineAsmArch::LoongArch64 | asm::InlineAsmArch::S390x ); - if !is_stable && !self.tcx.features().asm_experimental_arch() { + if !is_stable + && !self.tcx.features().asm_experimental_arch() + && sp + .ctxt() + .outer_expn_data() + .allow_internal_unstable + .filter(|features| features.contains(&sym::asm_experimental_arch)) + .is_none() + { feature_err( &self.tcx.sess, sym::asm_experimental_arch, diff --git a/tests/ui/internal/auxiliary/internal_unstable.rs b/tests/ui/internal/auxiliary/internal_unstable.rs index eb4d6cb380ef..bea153227a77 100644 --- a/tests/ui/internal/auxiliary/internal_unstable.rs +++ b/tests/ui/internal/auxiliary/internal_unstable.rs @@ -99,3 +99,10 @@ macro_rules! access_field_noallow { macro_rules! pass_through_noallow { ($e: expr) => { $e } } + +#[stable(feature = "stable", since = "1.0.0")] +#[allow_internal_unstable(asm_experimental_arch)] +#[macro_export] +macro_rules! asm_redirect { + ($($t:tt)*) => { core::arch::global_asm!($($t)*); } +} diff --git a/tests/ui/internal/internal-unstable-asm-experimental-arch.rs b/tests/ui/internal/internal-unstable-asm-experimental-arch.rs new file mode 100644 index 000000000000..6d97779ff911 --- /dev/null +++ b/tests/ui/internal/internal-unstable-asm-experimental-arch.rs @@ -0,0 +1,18 @@ +//@ only-wasm32-wasip1 +//@ compile-flags: --crate-type=lib +//@ build-pass +//@ aux-build:internal_unstable.rs + +#[macro_use] +extern crate internal_unstable; + +asm_redirect!( + "test:", + ".globl test", + ".functype test (i32) -> (i32)", + "local.get 0", + "i32.const 1", + "i32.add", + "end_function", + ".export_name test, test", +); From 52bcaabdb865063439395db3bdc08cf29693a071 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Tue, 16 Dec 2025 22:06:29 +0100 Subject: [PATCH 0900/3801] Port `#[no_link]` to use attribute parser --- .../rustc_attr_parsing/src/attributes/mod.rs | 1 + .../src/attributes/no_link.rs | 14 ++ compiler/rustc_attr_parsing/src/context.rs | 2 + .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/messages.ftl | 9 - compiler/rustc_passes/src/check_attr.rs | 28 +-- compiler/rustc_passes/src/errors.rs | 15 -- tests/ui/attributes/malformed-attrs.stderr | 17 +- ...sue-43106-gating-of-builtin-attrs-error.rs | 22 +-- ...43106-gating-of-builtin-attrs-error.stderr | 176 +++++++++--------- .../lint/unused/unused-attr-duplicate.stderr | 24 +-- 12 files changed, 141 insertions(+), 171 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/no_link.rs diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 64f29a4729c3..f7290bd7e6f2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -47,6 +47,7 @@ pub(crate) mod loop_match; pub(crate) mod macro_attrs; pub(crate) mod must_use; pub(crate) mod no_implicit_prelude; +pub(crate) mod no_link; pub(crate) mod non_exhaustive; pub(crate) mod path; pub(crate) mod pin_v2; diff --git a/compiler/rustc_attr_parsing/src/attributes/no_link.rs b/compiler/rustc_attr_parsing/src/attributes/no_link.rs new file mode 100644 index 000000000000..43cd1c5406e9 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/no_link.rs @@ -0,0 +1,14 @@ +use super::prelude::*; + +pub(crate) struct NoLinkParser; +impl NoArgsAttributeParser for NoLinkParser { + const PATH: &[Symbol] = &[sym::no_link]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::ExternCrate), + Warn(Target::Field), + Warn(Target::Arm), + Warn(Target::MacroDef), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoLink; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9c7006f84024..7b60ff731bd3 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -50,6 +50,7 @@ use crate::attributes::macro_attrs::{ }; use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; +use crate::attributes::no_link::NoLinkParser; use crate::attributes::non_exhaustive::NonExhaustiveParser; use crate::attributes::path::PathParser as PathAttributeParser; use crate::attributes::pin_v2::PinV2Parser; @@ -240,6 +241,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 5f38eaf4d5f4..64192f6f457e 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -803,6 +803,9 @@ pub enum AttributeKind { /// Represents `#[no_implicit_prelude]` NoImplicitPrelude(Span), + /// Represents `#[no_link]` + NoLink, + /// Represents `#[no_mangle]` NoMangle(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 90fb0497a5b2..d51aea80101a 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -70,6 +70,7 @@ impl AttributeKind { Naked(..) => No, NoCore(..) => No, NoImplicitPrelude(..) => No, + NoLink => No, NoMangle(..) => Yes, // Needed for rustdoc NoStd(..) => No, NonExhaustive(..) => Yes, // Needed for rustdoc diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 21191085253b..5f792883826c 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -240,11 +240,6 @@ passes_has_incoherent_inherent_impl = `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits .label = only adts, extern types and traits are supported -passes_ignored_attr_with_macro = - `#[{$sym}]` is ignored on struct fields, match arms and macro defs - .warn = {-passes_previously_accepted} - .note = {-passes_see_issue(issue: "80564")} - passes_ignored_derived_impls = `{$name}` has {$trait_list_len -> [one] a derived impl @@ -379,10 +374,6 @@ passes_must_not_suspend = `must_not_suspend` attribute should be applied to a struct, enum, union, or trait .label = is not a struct, enum, union, or trait -passes_no_link = - attribute should be applied to an `extern crate` item - .label = not an `extern crate` item - passes_no_main_function = `main` function not found in crate `{$crate_name}` .here_is_main = here is a function named `main` diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e836277e9761..735cf0ee5c33 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -250,6 +250,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::LinkSection { .. } | AttributeKind::MacroUse { .. } | AttributeKind::MacroEscape( .. ) + | AttributeKind::NoLink | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcScalableVector { .. } @@ -299,7 +300,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::no_link, ..] => self.check_no_link(hir_id, attr, span, target), [sym::rustc_no_implicit_autorefs, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } @@ -456,15 +456,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_mix_no_mangle_export(hir_id, attrs); } - fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr_span: Span, sym: &str) { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr_span, - errors::IgnoredAttrWithMacro { sym }, - ); - } - fn check_eii_impl(&self, impls: &[EiiImpl], target: Target) { for EiiImpl { span, inner_span, eii_macro, impl_marked_unsafe, is_default: _ } in impls { match target { @@ -1198,23 +1189,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ); } - /// Checks if `#[no_link]` is applied to an `extern crate`. - fn check_no_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { - match target { - Target::ExternCrate => {} - // FIXME(#80564): We permit struct fields, match arms and macro defs to have an - // `#[no_link]` attribute with just a lint, because we previously - // erroneously allowed it and some crates used it accidentally, to be compatible - // with crates depending on them, we can't throw an error here. - Target::Field | Target::Arm | Target::MacroDef => { - self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_link"); - } - _ => { - self.dcx().emit_err(errors::NoLink { attr_span: attr.span(), span }); - } - } - } - /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument. fn check_rustc_legacy_const_generics( &self, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 7abd2c703aeb..ea3cef258c58 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -80,12 +80,6 @@ pub(crate) struct OuterCrateLevelAttrSuggestion { #[diag(passes_inner_crate_level_attr)] pub(crate) struct InnerCrateLevelAttr; -#[derive(LintDiagnostic)] -#[diag(passes_ignored_attr_with_macro)] -pub(crate) struct IgnoredAttrWithMacro<'a> { - pub sym: &'a str, -} - #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_fn)] pub(crate) struct AttrShouldBeAppliedToFn { @@ -254,15 +248,6 @@ pub(crate) struct Link { pub span: Option, } -#[derive(Diagnostic)] -#[diag(passes_no_link)] -pub(crate) struct NoLink { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(passes_rustc_legacy_const_generics_only)] pub(crate) struct RustcLegacyConstGenericsOnly { diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 0cd88e254194..228ea12cba8b 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -147,14 +147,6 @@ error: malformed `thread_local` attribute input LL | #[thread_local()] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` -error: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:214:1 - | -LL | #[no_link()] - | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` - | - = note: for more information, visit - error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type --> $DIR/malformed-attrs.rs:105:1 | @@ -626,6 +618,15 @@ LL | #[non_exhaustive = 1] | | didn't expect any arguments here | help: must be of the form: `#[non_exhaustive]` +error[E0565]: malformed `no_link` attribute input + --> $DIR/malformed-attrs.rs:214:1 + | +LL | #[no_link()] + | ^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[no_link]` + error[E0539]: malformed `macro_use` attribute input --> $DIR/malformed-attrs.rs:216:1 | diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs index 0b0dd80f0115..c819e8763ef4 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs @@ -1,4 +1,3 @@ -//~ NOTE: not an `extern crate` item // This is testing whether various builtin attributes signals an // error or warning when put in "weird" places. // @@ -29,7 +28,7 @@ //~| WARN cannot be used on crates //~| WARN previously accepted #![no_link] -//~^ ERROR: attribute should be applied to an `extern crate` item +//~^ ERROR: `#[no_link]` attribute cannot be used on crates #![export_name = "2200"] //~^ ERROR: attribute cannot be used on //~| NOTE takes precedence @@ -60,29 +59,22 @@ mod inline { } #[no_link] -//~^ ERROR attribute should be applied to an `extern crate` item +//~^ ERROR `#[no_link]` attribute cannot be used on modules mod no_link { - //~^ NOTE not an `extern crate` item - mod inner { #![no_link] } - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on modules #[no_link] fn f() { } - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on functions #[no_link] struct S; - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on structs #[no_link]type T = S; - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on type aliases #[no_link] impl S { } - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on inherent impl blocks } #[export_name = "2200"] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 013e52923811..b4086e3ed916 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -1,5 +1,5 @@ error[E0658]: use of an internal attribute - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:11:1 | LL | #![rustc_main] | ^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | #![rustc_main] = note: the `#[rustc_main]` attribute is used internally to specify test entry point function error: `#[macro_export]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:10:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:9:1 | LL | #![macro_export] | ^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #![macro_export] = help: `#[macro_export]` can only be applied to macro defs error: `#[rustc_main]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:11:1 | LL | #![rustc_main] | ^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | #![rustc_main] = help: `#[rustc_main]` can only be applied to functions error: `#[path]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:21:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:20:1 | LL | #![path = "3800"] | ^^^^^^^^^^^^^^^^^ @@ -33,15 +33,23 @@ LL | #![path = "3800"] = help: `#[path]` can only be applied to modules error: `#[automatically_derived]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:23:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:22:1 | LL | #![automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: `#[automatically_derived]` can only be applied to trait impl blocks +error: `#[no_link]` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:30:1 + | +LL | #![no_link] + | ^^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + error: `#[export_name]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:33:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:1 | LL | #![export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +57,7 @@ LL | #![export_name = "2200"] = help: `#[export_name]` can be applied to functions and statics error: `#[inline]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:36:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:35:1 | LL | #![inline] | ^^^^^^^^^^ @@ -57,7 +65,7 @@ LL | #![inline] = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:38:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:37:1 | LL | #[inline] | ^^^^^^^^^ @@ -65,7 +73,7 @@ LL | #[inline] = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:43:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:42:17 | LL | mod inner { #![inline] } | ^^^^^^^^^^ @@ -73,7 +81,7 @@ LL | mod inner { #![inline] } = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:52:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:51:5 | LL | #[inline] struct S; | ^^^^^^^^^ @@ -81,7 +89,7 @@ LL | #[inline] struct S; = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:55:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:54:5 | LL | #[inline] type T = S; | ^^^^^^^^^ @@ -89,15 +97,63 @@ LL | #[inline] type T = S; = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:58:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:57:5 | LL | #[inline] impl S { } | ^^^^^^^^^ | = help: `#[inline]` can only be applied to functions +error: `#[no_link]` attribute cannot be used on modules + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:61:1 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on modules + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:64:17 + | +LL | mod inner { #![no_link] } + | ^^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on functions + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:5 + | +LL | #[no_link] fn f() { } + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on structs + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:70:5 + | +LL | #[no_link] struct S; + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on type aliases + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:73:5 + | +LL | #[no_link]type T = S; + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on inherent impl blocks + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:76:5 + | +LL | #[no_link] impl S { } + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:88:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:1 | LL | #[export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +161,7 @@ LL | #[export_name = "2200"] = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:83:17 | LL | mod inner { #![export_name="2200"] } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +169,7 @@ LL | mod inner { #![export_name="2200"] } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:88:5 | LL | #[export_name = "2200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +177,7 @@ LL | #[export_name = "2200"] struct S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:99:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:5 | LL | #[export_name = "2200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,7 +185,7 @@ LL | #[export_name = "2200"] type T = S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:102:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:94:5 | LL | #[export_name = "2200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,29 +193,15 @@ LL | #[export_name = "2200"] impl S { } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on required trait methods - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:106:9 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:98:9 | LL | #[export_name = "2200"] fn foo(); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: `#[export_name]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:62:1 - | -LL | #[no_link] - | ^^^^^^^^^^ -LL | -LL | / mod no_link { -LL | | -LL | | -LL | | mod inner { #![no_link] } -... | -LL | | } - | |_- not an `extern crate` item - error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:105:8 | LL | #[repr(C)] | ^ @@ -172,7 +214,7 @@ LL | | } | |_- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:129:8 | LL | #[repr(Rust)] | ^^^^ @@ -184,20 +226,14 @@ LL | | mod inner { #![repr(Rust)] } LL | | } | |_- not a struct, enum, or union -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:31:1 - | -LL | #![no_link] - | ^^^^^^^^^^^ not an `extern crate` item - warning: `#[no_mangle]` attribute may not be used in combination with `#[export_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:24:1 | LL | #![no_mangle] | ^^^^^^^^^^^^^ `#[no_mangle]` is ignored | note: `#[export_name]` takes precedence - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:33:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:1 | LL | #![export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -208,7 +244,7 @@ LL - #![no_mangle] | error: `repr` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | LL | #![repr()] | ^^^^^^^^^^ @@ -222,86 +258,56 @@ LL - #![repr()] LL + #[repr()] | -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:17 - | -LL | mod inner { #![no_link] } - | ------------^^^^^^^^^^^-- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:71:5 - | -LL | #[no_link] fn f() { } - | ^^^^^^^^^^ ---------- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:75:5 - | -LL | #[no_link] struct S; - | ^^^^^^^^^^ --------- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:79:5 - | -LL | #[no_link]type T = S; - | ^^^^^^^^^^----------- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:83:5 - | -LL | #[no_link] impl S { } - | ^^^^^^^^^^ ---------- not an `extern crate` item - error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:117:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:25 | LL | mod inner { #![repr(C)] } | --------------------^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:121:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:12 | LL | #[repr(C)] fn f() { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:12 | LL | #[repr(C)] type T = S; | ^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:12 | LL | #[repr(C)] impl S { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:141:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:133:25 | LL | mod inner { #![repr(Rust)] } | --------------------^^^^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:145:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:12 | LL | #[repr(Rust)] fn f() { } | ^^^^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:151:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:143:12 | LL | #[repr(Rust)] type T = S; | ^^^^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:155:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:147:12 | LL | #[repr(Rust)] impl S { } | ^^^^ ---------- not a struct, enum, or union error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:45:5 | LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ @@ -311,7 +317,7 @@ LL | #[inline = "2100"] fn f() { } = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | LL | #![repr()] | ^^^^^^^^^^ help: remove this attribute @@ -319,7 +325,7 @@ LL | #![repr()] = note: using `repr` with an empty list has no effect warning: `#[no_mangle]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:24:1 | LL | #![no_mangle] | ^^^^^^^^^^^^^ @@ -333,7 +339,7 @@ Some errors have detailed explanations: E0517, E0658. For more information about an error, try `rustc --explain E0517`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:45:5 | LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 86506dba5f08..54ed351d4348 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -16,18 +16,6 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:37:1 - | -LL | #[no_link] - | ^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:36:1 - | -LL | #[no_link] - | ^^^^^^^^^^ - error: unused attribute --> $DIR/unused-attr-duplicate.rs:34:1 | @@ -40,6 +28,18 @@ note: attribute also specified here LL | #![no_builtins] | ^^^^^^^^^^^^^^^ +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:37:1 + | +LL | #[no_link] + | ^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:36:1 + | +LL | #[no_link] + | ^^^^^^^^^^ + error: unused attribute --> $DIR/unused-attr-duplicate.rs:41:1 | From b09a9d006243e40b34e2597b1a4734f5b4188e8e Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Tue, 16 Dec 2025 22:45:56 +0100 Subject: [PATCH 0901/3801] add tests making sure to FCW warn on `field`, `arm`, and `macro def` --- ...sue-43106-gating-of-builtin-attrs-error.rs | 24 ++++++- ...43106-gating-of-builtin-attrs-error.stderr | 71 +++++++++++++------ 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs index c819e8763ef4..1560f2b5f4a7 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs @@ -64,17 +64,35 @@ mod no_link { mod inner { #![no_link] } //~^ ERROR `#[no_link]` attribute cannot be used on modules - #[no_link] fn f() { } - //~^ ERROR `#[no_link]` attribute cannot be used on functions + #[no_link] fn f() { + //~^ ERROR `#[no_link]` attribute cannot be used on functions + match () { + #[no_link] + //~^ WARN `#[no_link]` attribute cannot be used on match arms [unused_attributes] + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + _ => () + } + } - #[no_link] struct S; + #[no_link] //~^ ERROR `#[no_link]` attribute cannot be used on structs + struct S { + #[no_link] + //~^ WARN `#[no_link]` attribute cannot be used on struct fields [unused_attributes] + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + field: () + } #[no_link]type T = S; //~^ ERROR `#[no_link]` attribute cannot be used on type aliases #[no_link] impl S { } //~^ ERROR `#[no_link]` attribute cannot be used on inherent impl blocks + + #[no_link] + //~^ WARN `#[no_link]` attribute cannot be used on macro defs + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + macro_rules! m{() => {}} } #[export_name = "2200"] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index b4086e3ed916..662776e58026 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -123,21 +123,21 @@ LL | mod inner { #![no_link] } error: `#[no_link]` attribute cannot be used on functions --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:5 | -LL | #[no_link] fn f() { } +LL | #[no_link] fn f() { | ^^^^^^^^^^ | = help: `#[no_link]` can only be applied to extern crates error: `#[no_link]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:70:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:77:5 | -LL | #[no_link] struct S; +LL | #[no_link] | ^^^^^^^^^^ | = help: `#[no_link]` can only be applied to extern crates error: `#[no_link]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:73:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:86:5 | LL | #[no_link]type T = S; | ^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | #[no_link]type T = S; = help: `#[no_link]` can only be applied to extern crates error: `#[no_link]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:76:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:89:5 | LL | #[no_link] impl S { } | ^^^^^^^^^^ @@ -153,7 +153,7 @@ LL | #[no_link] impl S { } = help: `#[no_link]` can only be applied to extern crates error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:98:1 | LL | #[export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -161,7 +161,7 @@ LL | #[export_name = "2200"] = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:83:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:101:17 | LL | mod inner { #![export_name="2200"] } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | mod inner { #![export_name="2200"] } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:88:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:106:5 | LL | #[export_name = "2200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | #[export_name = "2200"] struct S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:5 | LL | #[export_name = "2200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ LL | #[export_name = "2200"] type T = S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:94:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:112:5 | LL | #[export_name = "2200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL | #[export_name = "2200"] impl S { } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on required trait methods - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:98:9 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:116:9 | LL | #[export_name = "2200"] fn foo(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -201,7 +201,7 @@ LL | #[export_name = "2200"] fn foo(); = help: `#[export_name]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:105:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:8 | LL | #[repr(C)] | ^ @@ -214,7 +214,7 @@ LL | | } | |_- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:129:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:147:8 | LL | #[repr(Rust)] | ^^^^ @@ -259,49 +259,49 @@ LL + #[repr()] | error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:25 | LL | mod inner { #![repr(C)] } | --------------------^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:12 | LL | #[repr(C)] fn f() { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:12 | LL | #[repr(C)] type T = S; | ^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:141:12 | LL | #[repr(C)] impl S { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:133:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:151:25 | LL | mod inner { #![repr(Rust)] } | --------------------^^^^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:155:12 | LL | #[repr(Rust)] fn f() { } | ^^^^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:143:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:161:12 | LL | #[repr(Rust)] type T = S; | ^^^^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:147:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:165:12 | LL | #[repr(Rust)] impl S { } | ^^^^ ---------- not a struct, enum, or union @@ -316,6 +316,33 @@ LL | #[inline = "2100"] fn f() { } = note: for more information, see issue #57571 = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default +warning: `#[no_link]` attribute cannot be used on match arms + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:70:13 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_link]` can only be applied to extern crates + +warning: `#[no_link]` attribute cannot be used on struct fields + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:9 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_link]` can only be applied to extern crates + +warning: `#[no_link]` attribute cannot be used on macro defs + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:92:5 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_link]` can only be applied to extern crates + warning: unused attribute --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | @@ -333,7 +360,7 @@ LL | #![no_mangle] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[no_mangle]` can be applied to functions and statics -error: aborting due to 37 previous errors; 3 warnings emitted +error: aborting due to 37 previous errors; 6 warnings emitted Some errors have detailed explanations: E0517, E0658. For more information about an error, try `rustc --explain E0517`. From 383053e01602a1a754a170d7c201cc43fff87739 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 5 Sep 2025 15:27:17 -0400 Subject: [PATCH 0902/3801] Enable `outline-atomics` by default on AArch64 FreeBSD Many aarch64 targets without LSE in the baseline enable the `outline-atomics` feature, which uses runtime detection of LSE for its faster atomic ops. This provides nontrivial performance improvements on most hardware from the past decade, at a small cost to anything pre-LSE. This matches what Clang does [1]. [1]: https://github.com/llvm/llvm-project/commit/e24f90190c772b6fdd915cd0a2e55cbd468c3024 --- .../rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs index 69a65e6b0f02..47775f968400 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: Arch::AArch64, options: TargetOptions { - features: "+v8a".into(), + features: "+v8a,+outline-atomics".into(), max_atomic_width: Some(128), stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::ADDRESS From 4ff4b255d078225d9c0244f9c4f0ade2ae5bb0d5 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Tue, 16 Dec 2025 21:05:13 -0600 Subject: [PATCH 0903/3801] fixup! Implement va_arg for Hexagon Linux musl targets --- compiler/rustc_codegen_llvm/src/va_arg.rs | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 82cc45d161c4..163b83ee08cd 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -893,7 +893,7 @@ fn emit_hexagon_va_arg_bare_metal<'ll, 'tcx>( // Calculate offset: round up type size to 4-byte boundary (minimum stack slot size) let type_size = layout.size.bytes(); - let offset = ((type_size + 3) / 4) * 4; // align to 4 bytes + let offset = type_size.next_multiple_of(4); // align to 4 bytes // Update va_list to point to next argument let next_ptr = bx.inbounds_ptradd(aligned_ptr, bx.const_usize(offset)); @@ -903,19 +903,6 @@ fn emit_hexagon_va_arg_bare_metal<'ll, 'tcx>( bx.load(layout.llvm_type(bx), aligned_ptr, layout.align.abi) } -fn emit_hexagon_va_arg<'ll, 'tcx>( - bx: &mut Builder<'_, 'll, 'tcx>, - list: OperandRef<'tcx, &'ll Value>, - target_ty: Ty<'tcx>, - is_musl: bool, -) -> &'ll Value { - if is_musl { - emit_hexagon_va_arg_musl(bx, list, target_ty) - } else { - emit_hexagon_va_arg_bare_metal(bx, list, target_ty) - } -} - fn emit_xtensa_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, list: OperandRef<'tcx, &'ll Value>, @@ -1100,7 +1087,13 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( // This includes `target.is_like_darwin`, which on x86_64 targets is like sysv64. Arch::X86_64 => emit_x86_64_sysv64_va_arg(bx, addr, target_ty), Arch::Xtensa => emit_xtensa_va_arg(bx, addr, target_ty), - Arch::Hexagon => emit_hexagon_va_arg(bx, addr, target_ty, target.env == Env::Musl), + Arch::Hexagon => { + if target.env == Env::Musl { + emit_hexagon_va_arg_musl(bx, addr, target_ty) + } else { + emit_hexagon_va_arg_bare_metal(bx, addr, target_ty) + } + } // For all other architecture/OS combinations fall back to using // the LLVM va_arg instruction. // https://llvm.org/docs/LangRef.html#va-arg-instruction From 25cc98f1168f7e7c40718bb00deefb9112b71282 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 15 Dec 2025 20:35:01 -0800 Subject: [PATCH 0904/3801] Avoid unhelpful suggestion when crate name is invalid Pointing out they can set the crate's name is non-actionable: their problem is they found out how and set it incorrectly. Remove extraneous information that can only confuse the matter. --- compiler/rustc_session/messages.ftl | 1 - compiler/rustc_session/src/errors.rs | 2 -- compiler/rustc_session/src/output.rs | 1 - .../compile-flags/invalid/need-crate-arg-ignore-tidy$x.stderr | 2 -- 4 files changed, 6 deletions(-) diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index a4166951e350..2fdce628f0c9 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -57,7 +57,6 @@ session_int_literal_too_large = integer literal is too large .note = value exceeds limit of `{$limit}` session_invalid_character_in_crate_name = invalid character {$character} in crate name: `{$crate_name}` - .help = you can either pass `--crate-name` on the command line or add `#![crate_name = "…"]` to set the crate name session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal .label = invalid suffix `{$suffix}` diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 07b41a3de714..1f2d386a23cb 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -238,8 +238,6 @@ pub(crate) struct InvalidCharacterInCrateName { pub(crate) span: Option, pub(crate) character: char, pub(crate) crate_name: Symbol, - #[help] - pub(crate) help: Option<()>, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index 99c736c3b1a5..de8f1d6009ab 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -69,7 +69,6 @@ pub fn validate_crate_name(sess: &Session, crate_name: Symbol, span: Option Date: Wed, 17 Dec 2025 04:56:18 +0000 Subject: [PATCH 0905/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 2dc30247c5d8293aaa31e1d7dae2ed2fde908ada. --- library/compiler-builtins/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/rust-version b/library/compiler-builtins/rust-version index 71fbbbaa984f..7345c25066a8 100644 --- a/library/compiler-builtins/rust-version +++ b/library/compiler-builtins/rust-version @@ -1 +1 @@ -47cd7120d9b4e1b64eb27c87522a07888197fae8 +2dc30247c5d8293aaa31e1d7dae2ed2fde908ada From bd06672d1a4239b8753b8bee5b45dcbaafb3f2b3 Mon Sep 17 00:00:00 2001 From: quaternic <57393910+quaternic@users.noreply.github.com> Date: Tue, 16 Dec 2025 18:06:46 +0200 Subject: [PATCH 0906/3801] apply the rename to aarch64_outline_atomics in builtins-test --- .../builtins-test/tests/lse.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/library/compiler-builtins/builtins-test/tests/lse.rs b/library/compiler-builtins/builtins-test/tests/lse.rs index 5d59fbb7f44d..56891be8a8ac 100644 --- a/library/compiler-builtins/builtins-test/tests/lse.rs +++ b/library/compiler-builtins/builtins-test/tests/lse.rs @@ -19,7 +19,11 @@ mod cas { let mut target = expected.wrapping_add(10); assert_eq!( unsafe { - compiler_builtins::aarch64_linux::$name::$name(expected, new, &mut target) + compiler_builtins::aarch64_outline_atomics::$name::$name( + expected, + new, + &mut target, + ) }, expected.wrapping_add(10), "return value should always be the previous value", @@ -33,7 +37,11 @@ mod cas { target = expected; assert_eq!( unsafe { - compiler_builtins::aarch64_linux::$name::$name(expected, new, &mut target) + compiler_builtins::aarch64_outline_atomics::$name::$name( + expected, + new, + &mut target, + ) }, expected ); @@ -54,7 +62,9 @@ mod swap { builtins_test::fuzz_2(10000, |left: super::int_ty!($bytes), mut right| { let orig_right = right; assert_eq!( - unsafe { compiler_builtins::aarch64_linux::$name::$name(left, &mut right) }, + unsafe { + compiler_builtins::aarch64_outline_atomics::$name::$name(left, &mut right) + }, orig_right ); assert_eq!(left, right); @@ -74,7 +84,7 @@ macro_rules! test_op { let mut target = old; let op: fn(super::int_ty!($bytes), super::int_ty!($bytes)) -> _ = $($op)*; let expected = op(old, val); - assert_eq!(old, unsafe { compiler_builtins::aarch64_linux::$name::$name(val, &mut target) }, "{} should return original value", stringify!($name)); + assert_eq!(old, unsafe { compiler_builtins::aarch64_outline_atomics::$name::$name(val, &mut target) }, "{} should return original value", stringify!($name)); assert_eq!(expected, target, "{} should store to target", stringify!($name)); }); } From 5faeb43a5cf2d4acf83c664051f8945296ea5bd2 Mon Sep 17 00:00:00 2001 From: Juho Kahala <57393910+quaternic@users.noreply.github.com> Date: Wed, 17 Dec 2025 07:56:27 +0200 Subject: [PATCH 0907/3801] remove uses of Ord::clamp in scalbn (#1047) Avoid using `Ord::clamp` in the `f16`-specific part of the generic `scalbn`. It turned out to be redundant anyway, as both callsites follow a pattern like ``` if n < negative_val { let foo = (n + positive_val).clamp(negative_val, positive_val); } ``` and `n < negative_val < 0` implies `n + positive_val < positive_val`. Fixes: rust-lang/compiler-builtins#1046 --- library/compiler-builtins/libm/src/math/generic/scalbn.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/compiler-builtins/libm/src/math/generic/scalbn.rs b/library/compiler-builtins/libm/src/math/generic/scalbn.rs index 6dd9b1a9b84a..68de41757913 100644 --- a/library/compiler-builtins/libm/src/math/generic/scalbn.rs +++ b/library/compiler-builtins/libm/src/math/generic/scalbn.rs @@ -96,14 +96,14 @@ where // Work aroudn this by using a different algorithm that calculates the prescale // dynamically based on the maximum possible value. This adds more operations per round // since it needs to construct the scale, but works better in the general case. - let add = -(n + sig_total_bits as i32).clamp(exp_min, sig_total_bits as i32); + let add = -(n + sig_total_bits as i32).max(exp_min); let mul = F::from_parts(false, (F::EXP_BIAS as i32 - add) as u32, zero); x *= mul; n += add; if n < exp_min { - let add = -(n + sig_total_bits as i32).clamp(exp_min, sig_total_bits as i32); + let add = -(n + sig_total_bits as i32).max(exp_min); let mul = F::from_parts(false, (F::EXP_BIAS as i32 - add) as u32, zero); x *= mul; From a9fa80ce919b7d3f71f5a18340c2e4edb943033c Mon Sep 17 00:00:00 2001 From: Juho Kahala <57393910+quaternic@users.noreply.github.com> Date: Wed, 17 Dec 2025 07:56:45 +0200 Subject: [PATCH 0908/3801] Fix `expm1f` overflow threshold Due to an erroneous overflow threshold, `expm1f` was incorrectly returning `inf` for inputs in the range `[88.72169, 88.72283]`. This additionally caused `sinhf` to return `NaN` for inputs in that range. The bug was ported from the original in musl, which has since been fixed in [1]. [1]: https://git.musl-libc.org/cgit/musl/commit/?id=964104f9f0e056cf58d9defa0b716d7756f040f6 --- .../libm-test/src/precision.rs | 21 ------------------- .../compiler-builtins/libm/src/math/expm1f.rs | 4 ++-- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/library/compiler-builtins/libm-test/src/precision.rs b/library/compiler-builtins/libm-test/src/precision.rs index 968ac7170c08..7887c032394b 100644 --- a/library/compiler-builtins/libm-test/src/precision.rs +++ b/library/compiler-builtins/libm-test/src/precision.rs @@ -218,27 +218,6 @@ impl MaybeOverride<(f16,)> for SpecialCase {} impl MaybeOverride<(f32,)> for SpecialCase { fn check_float(input: (f32,), actual: F, expected: F, ctx: &CheckCtx) -> CheckAction { - if ctx.base_name == BaseName::Expm1 - && !input.0.is_infinite() - && input.0 > 80.0 - && actual.is_infinite() - && !expected.is_infinite() - { - // we return infinity but the number is representable - if ctx.basis == CheckBasis::Musl { - return XFAIL_NOCHECK; - } - return XFAIL("expm1 representable numbers"); - } - - if ctx.base_name == BaseName::Sinh && input.0.abs() > 80.0 && actual.is_nan() { - // we return some NaN that should be real values or infinite - if ctx.basis == CheckBasis::Musl { - return XFAIL_NOCHECK; - } - return XFAIL("sinh unexpected NaN"); - } - if (ctx.base_name == BaseName::Lgamma || ctx.base_name == BaseName::LgammaR) && input.0 > 4e36 && expected.is_infinite() diff --git a/library/compiler-builtins/libm/src/math/expm1f.rs b/library/compiler-builtins/libm/src/math/expm1f.rs index f77515a4b99b..388da3f30173 100644 --- a/library/compiler-builtins/libm/src/math/expm1f.rs +++ b/library/compiler-builtins/libm/src/math/expm1f.rs @@ -13,7 +13,6 @@ * ==================================================== */ -const O_THRESHOLD: f32 = 8.8721679688e+01; /* 0x42b17180 */ const LN2_HI: f32 = 6.9313812256e-01; /* 0x3f317180 */ const LN2_LO: f32 = 9.0580006145e-06; /* 0x3717f7d1 */ const INV_LN2: f32 = 1.4426950216e+00; /* 0x3fb8aa3b */ @@ -50,7 +49,8 @@ pub fn expm1f(mut x: f32) -> f32 { if sign { return -1.; } - if x > O_THRESHOLD { + if hx > 0x42b17217 { + /* x > log(FLT_MAX) */ x *= x1p127; return x; } From a412446bb39f33c2ff614960cae02cf1e8b1821a Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Wed, 17 Dec 2025 07:22:03 +0000 Subject: [PATCH 0909/3801] Prepare for merging from rust-lang/rust This updates the rust-version file to 2dc30247c5d8293aaa31e1d7dae2ed2fde908ada. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 71a84e2bda12..7345c25066a8 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -cec70080fd441d16e9fb08a0d1d1a04c72d1ed25 +2dc30247c5d8293aaa31e1d7dae2ed2fde908ada From 8944338010db65e35273a7f2cf137558ad0f4480 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 17 Dec 2025 17:34:43 +0800 Subject: [PATCH 0910/3801] Fix match arm nested body invalid expected type Example --- ```rust struct Foo; enum E { X } fn foo() -> Foo { match E::X { Foo::X => { $0 } } } ``` **Before this PR** ```text ty: E, name: ? ``` **After this PR** ```text ty: Foo, name: ? ``` --- .../ide-completion/src/context/analysis.rs | 17 +++++++++++++++++ .../crates/ide-completion/src/context/tests.rs | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index b65c68a2401e..e48c433fa4e9 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs @@ -734,6 +734,23 @@ fn expected_type_and_name<'db>( }.map(TypeInfo::original); (ty, None) }, + ast::MatchArm(it) => { + let on_arrow = previous_non_trivia_token(token.clone()).is_some_and(|it| T![=>] == it.kind()); + let in_body = it.expr().is_some_and(|it| it.syntax().text_range().contains_range(token.text_range())); + let match_expr = it.syntax().ancestors().nth(2).and_then(ast::MatchExpr::cast); + + let ty = if on_arrow || in_body { + // match foo { ..., pat => $0 } + cov_mark::hit!(expected_type_match_arm_body_without_leading_char); + cov_mark::hit!(expected_type_match_arm_body_with_leading_char); + match_expr.and_then(|it| sema.type_of_expr(&it.into())) + } else { + // match foo { $0 } + cov_mark::hit!(expected_type_match_arm_without_leading_char); + match_expr.and_then(|it| it.expr()).and_then(|e| sema.type_of_expr(&e)) + }.map(TypeInfo::original); + (ty, None) + }, ast::IfExpr(it) => { let ty = if let Some(body) = it.then_branch() && token.text_range().end() > body.syntax().text_range().start() diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs index b929d36ce687..09a9b6f112f0 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/tests.rs @@ -256,6 +256,22 @@ fn foo() -> Foo { ); } +#[test] +fn expected_type_match_arm_block_body_without_leading_char() { + cov_mark::check!(expected_type_match_arm_body_without_leading_char); + cov_mark::check!(expected_type_match_arm_body_with_leading_char); + check_expected_type_and_name( + r#" +struct Foo; +enum E { X } +fn foo() -> Foo { + match E::X { Foo::X => { $0 } } +} +"#, + expect![[r#"ty: Foo, name: ?"#]], + ); +} + #[test] fn expected_type_match_body_arm_with_leading_char() { cov_mark::check!(expected_type_match_arm_body_with_leading_char); From 677b4be526a214400879b2c50d7da6e838a71fc3 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 17 Dec 2025 17:53:52 +0800 Subject: [PATCH 0911/3801] Fix applicable on non naked if for move_guard assist Example --- ```rust fn main() { match 92 { _ => { let cond = true; $0if cond { foo() } }, _ => true } } ``` **Before this PR** ```rust fn main() { match 92 { _ if cond => foo(), _ => true } } ``` **After this PR** Assist not applicable --- .../ide-assists/src/handlers/move_guard.rs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs index 6b50718424c7..8daf86923d92 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs @@ -108,6 +108,10 @@ pub(crate) fn move_arm_cond_to_match_guard( let mut replace_node = None; let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone()).or_else(|| { let block_expr = BlockExpr::cast(arm_body.syntax().clone())?; + if block_expr.statements().next().is_some() { + cov_mark::hit!(move_guard_non_naked_if); + return None; + } if let Expr::IfExpr(e) = block_expr.tail_expr()? { replace_node = Some(block_expr.syntax().clone()); Some(e) @@ -238,6 +242,46 @@ fn main() { "#, ); } + + #[test] + fn move_non_naked_arm_cond_to_guard() { + cov_mark::check!(move_guard_non_naked_if); + check_assist_not_applicable( + move_arm_cond_to_match_guard, + r#" +fn main() { + match 92 { + _ => { + let cond = true; + $0if cond { + foo() + } + }, + _ => true + } +} +"#, + ); + check_assist_not_applicable( + move_arm_cond_to_match_guard, + r#" +fn main() { + match 92 { + _ => { + let cond = true; + $0if cond { + foo() + } else { + bar() + } + }, + _ => true + } +} +"#, + ); + } + #[test] fn move_guard_to_arm_body_target() { check_assist_target( From 60b616d3382b15b07c16db48edf5993254b7fc4d Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 17 Dec 2025 11:20:44 +0100 Subject: [PATCH 0912/3801] tests/run-make-cargo/same-crate-name-and-macro-name: New regression test --- .../consumer/Cargo.toml | 10 ++++++++++ .../consumer/src/main.rs | 7 +++++++ .../mylib_v1/Cargo.toml | 6 ++++++ .../mylib_v1/src/lib.rs | 6 ++++++ .../mylib_v2/Cargo.toml | 6 ++++++ .../mylib_v2/src/lib.rs | 6 ++++++ .../same-crate-name-and-macro-name/rmake.rs | 13 +++++++++++++ 7 files changed, 54 insertions(+) create mode 100644 tests/run-make-cargo/same-crate-name-and-macro-name/consumer/Cargo.toml create mode 100644 tests/run-make-cargo/same-crate-name-and-macro-name/consumer/src/main.rs create mode 100644 tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v1/Cargo.toml create mode 100644 tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v1/src/lib.rs create mode 100644 tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v2/Cargo.toml create mode 100644 tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v2/src/lib.rs create mode 100644 tests/run-make-cargo/same-crate-name-and-macro-name/rmake.rs diff --git a/tests/run-make-cargo/same-crate-name-and-macro-name/consumer/Cargo.toml b/tests/run-make-cargo/same-crate-name-and-macro-name/consumer/Cargo.toml new file mode 100644 index 000000000000..870d333da3a4 --- /dev/null +++ b/tests/run-make-cargo/same-crate-name-and-macro-name/consumer/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "consumer" +version = "0.1.0" + +[dependencies] +mylib_v1 = { path = "../mylib_v1", package = "mylib" } +mylib_v2 = { path = "../mylib_v2", package = "mylib" } + +# Avoid interference with root workspace when casually testing +[workspace] diff --git a/tests/run-make-cargo/same-crate-name-and-macro-name/consumer/src/main.rs b/tests/run-make-cargo/same-crate-name-and-macro-name/consumer/src/main.rs new file mode 100644 index 000000000000..80e76ae28117 --- /dev/null +++ b/tests/run-make-cargo/same-crate-name-and-macro-name/consumer/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let v1 = mylib_v1::my_macro!(); + assert_eq!(v1, "version 1"); + + let v2 = mylib_v2::my_macro!(); + assert_eq!(v2, "version 2"); +} diff --git a/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v1/Cargo.toml b/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v1/Cargo.toml new file mode 100644 index 000000000000..69f80bfc89ed --- /dev/null +++ b/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v1/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "mylib" +version = "1.0.0" + +# Avoid interference with root workspace when casually testing +[workspace] diff --git a/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v1/src/lib.rs b/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v1/src/lib.rs new file mode 100644 index 000000000000..0603b754ea82 --- /dev/null +++ b/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v1/src/lib.rs @@ -0,0 +1,6 @@ +#[macro_export] +macro_rules! my_macro { + () => { + "version 1" + }; +} diff --git a/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v2/Cargo.toml b/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v2/Cargo.toml new file mode 100644 index 000000000000..f164616393ba --- /dev/null +++ b/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v2/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "mylib" +version = "2.0.0" + +# Avoid interference with root workspace when casually testing +[workspace] diff --git a/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v2/src/lib.rs b/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v2/src/lib.rs new file mode 100644 index 000000000000..352c7c514f83 --- /dev/null +++ b/tests/run-make-cargo/same-crate-name-and-macro-name/mylib_v2/src/lib.rs @@ -0,0 +1,6 @@ +#[macro_export] +macro_rules! my_macro { + () => { + "version 2" + }; +} diff --git a/tests/run-make-cargo/same-crate-name-and-macro-name/rmake.rs b/tests/run-make-cargo/same-crate-name-and-macro-name/rmake.rs new file mode 100644 index 000000000000..cce98cebb804 --- /dev/null +++ b/tests/run-make-cargo/same-crate-name-and-macro-name/rmake.rs @@ -0,0 +1,13 @@ +//! Regression test for +//! +//! (that particular comment describes the issue well). +//! +//! We test that two library crates with the same name can export macros with +//! the same name without causing interference when both are used in another +//! crate. + +use run_make_support::cargo; + +fn main() { + cargo().current_dir("consumer").arg("run").run(); +} From 3ca0ac033af115c53390ea9eaa98cb04b0dc54a7 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Tue, 16 Dec 2025 16:15:31 +0200 Subject: [PATCH 0913/3801] Upgrade Salsa The new version gives an additional `salsa::Id` to cycle handlers, and renames `non_update_return_type` to `non_update_types`. --- src/tools/rust-analyzer/Cargo.lock | 12 ++++++------ src/tools/rust-analyzer/Cargo.toml | 4 ++-- .../rust-analyzer/crates/hir-ty/src/consteval.rs | 3 +++ src/tools/rust-analyzer/crates/hir-ty/src/db.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/infer.rs | 4 ++-- .../rust-analyzer/crates/hir-ty/src/layout.rs | 1 + .../rust-analyzer/crates/hir-ty/src/layout/adt.rs | 1 + .../rust-analyzer/crates/hir-ty/src/lower.rs | 15 ++++++++++----- .../rust-analyzer/crates/hir-ty/src/mir/lower.rs | 1 + .../crates/hir-ty/src/mir/monomorphization.rs | 1 + .../crates/hir-ty/src/next_solver/consts.rs | 4 ++-- .../crates/hir-ty/src/next_solver/interner.rs | 4 ++-- .../crates/hir-ty/src/next_solver/opaques.rs | 2 +- .../crates/hir-ty/src/next_solver/predicate.rs | 4 ++-- .../crates/hir-ty/src/next_solver/region.rs | 2 +- .../crates/hir-ty/src/next_solver/ty.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/opaques.rs | 4 ++-- .../crates/hir-ty/src/specialization.rs | 1 + .../rust-analyzer/crates/hir-ty/src/variance.rs | 1 + .../crates/query-group-macro/src/queries.rs | 2 +- 20 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index efe56cb7f61c..ed13ffd4c3b3 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -2445,9 +2445,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa" -version = "0.24.0" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27956164373aeec733ac24ff1736de8541234e3a8e7e6f916b28175b5752af3b" +checksum = "e2e2aa2fca57727371eeafc975acc8e6f4c52f8166a78035543f6ee1c74c2dcc" dependencies = [ "boxcar", "crossbeam-queue", @@ -2470,15 +2470,15 @@ dependencies = [ [[package]] name = "salsa-macro-rules" -version = "0.24.0" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ca3b9d6e47c08b5de4b218e0c5f7ec910b51bce6314e651c8e7b9d154d174da" +checksum = "1bfc2a1e7bf06964105515451d728f2422dedc3a112383324a00b191a5c397a3" [[package]] name = "salsa-macros" -version = "0.24.0" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6337b62f2968be6b8afa30017d7564ecbde6832ada47ed2261fb14d0fd402ff4" +checksum = "3d844c1aa34946da46af683b5c27ec1088a3d9d84a2b837a108223fd830220e1" dependencies = [ "proc-macro2", "quote", diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 6991eeec738e..3abe586db3c5 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -135,13 +135,13 @@ rayon = "1.10.0" rowan = "=0.15.17" # Ideally we'd not enable the macros feature but unfortunately the `tracked` attribute does not work # on impls without it -salsa = { version = "0.24.0", default-features = false, features = [ +salsa = { version = "0.25.2", default-features = false, features = [ "rayon", "salsa_unstable", "macros", "inventory", ] } -salsa-macros = "0.24.0" +salsa-macros = "0.25.2" semver = "1.0.26" serde = { version = "1.0.219" } serde_derive = { version = "1.0.219" } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index 012632aa55b5..32c207b189f0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -257,6 +257,7 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd pub(crate) fn const_eval_cycle_result<'db>( _: &'db dyn HirDatabase, + _: salsa::Id, _: ConstId, _: GenericArgs<'db>, _: Option>, @@ -266,6 +267,7 @@ pub(crate) fn const_eval_cycle_result<'db>( pub(crate) fn const_eval_static_cycle_result<'db>( _: &'db dyn HirDatabase, + _: salsa::Id, _: StaticId, ) -> Result, ConstEvalError<'db>> { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) @@ -273,6 +275,7 @@ pub(crate) fn const_eval_static_cycle_result<'db>( pub(crate) fn const_eval_discriminant_cycle_result<'db>( _: &'db dyn HirDatabase, + _: salsa::Id, _: EnumVariantId, ) -> Result> { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index f9523e7168de..47bb6675ea48 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -245,7 +245,7 @@ pub struct InternedConstParamId { pub loc: ConstParamId, } -#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)] +#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX, unsafe(non_update_types))] #[derive(PartialOrd, Ord)] pub struct InternedOpaqueTyId { pub loc: ImplTraitId<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 70868e4b95aa..d6682c0cf2fe 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -162,7 +162,7 @@ fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> ctx.resolve_all() } -fn infer_cycle_result(db: &dyn HirDatabase, _: DefWithBodyId) -> InferenceResult<'_> { +fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> InferenceResult<'_> { InferenceResult { has_errors: true, ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)) @@ -547,7 +547,7 @@ pub struct InferenceResult<'db> { #[salsa::tracked] impl<'db> InferenceResult<'db> { - #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)] + #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result, unsafe(non_update_types))] pub fn for_body(db: &'db dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'db> { infer_query(db, def) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 4b20d6eb3220..1ed604865b00 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -359,6 +359,7 @@ pub fn layout_of_ty_query<'db>( pub(crate) fn layout_of_ty_cycle_result<'db>( _: &dyn HirDatabase, + _: salsa::Id, _: Ty<'db>, _: ParamEnvAndCrate<'db>, ) -> Result, LayoutError> { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs index cf2d0989fd9f..1e2c3aa31b8d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs @@ -97,6 +97,7 @@ pub fn layout_of_adt_query<'db>( pub(crate) fn layout_of_adt_cycle_result<'db>( _: &'db dyn HirDatabase, + _: salsa::Id, _def: AdtId, _args: GenericArgs<'db>, _trait_env: ParamEnvAndCrate<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index dd34bbe2fd02..3f901ad69285 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -1137,7 +1137,7 @@ impl InternedOpaqueTyId { #[salsa::tracked] impl<'db> ImplTraits<'db> { - #[salsa::tracked(returns(ref), unsafe(non_update_return_type))] + #[salsa::tracked(returns(ref), unsafe(non_update_types))] pub(crate) fn return_type_impl_traits( db: &'db dyn HirDatabase, def: hir_def::FunctionId, @@ -1166,7 +1166,7 @@ impl<'db> ImplTraits<'db> { } } - #[salsa::tracked(returns(ref), unsafe(non_update_return_type))] + #[salsa::tracked(returns(ref), unsafe(non_update_types))] pub(crate) fn type_alias_impl_traits( db: &'db dyn HirDatabase, def: hir_def::TypeAliasId, @@ -1373,6 +1373,7 @@ pub(crate) fn type_for_type_alias_with_diagnostics_query<'db>( pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result<'db>( db: &'db dyn HirDatabase, + _: salsa::Id, _adt: TypeAliasId, ) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) { (EarlyBinder::bind(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)), None) @@ -1406,6 +1407,7 @@ pub(crate) fn impl_self_ty_with_diagnostics_query<'db>( pub(crate) fn impl_self_ty_with_diagnostics_cycle_result( db: &dyn HirDatabase, + _: salsa::Id, _impl_id: ImplId, ) -> (EarlyBinder<'_, Ty<'_>>, Diagnostics) { (EarlyBinder::bind(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)), None) @@ -1443,6 +1445,7 @@ pub(crate) fn const_param_ty_with_diagnostics_query<'db>( pub(crate) fn const_param_ty_with_diagnostics_cycle_result<'db>( db: &'db dyn HirDatabase, + _: salsa::Id, _: crate::db::HirDatabaseData, _def: ConstParamId, ) -> (Ty<'db>, Diagnostics) { @@ -1496,7 +1499,7 @@ pub(crate) fn field_types_with_diagnostics_query<'db>( /// following bounds are disallowed: `T: Foo, U: Foo`, but /// these are fine: `T: Foo, U: Foo<()>`. #[tracing::instrument(skip(db), ret)] -#[salsa::tracked(returns(ref), unsafe(non_update_return_type), cycle_result = generic_predicates_for_param_cycle_result)] +#[salsa::tracked(returns(ref), unsafe(non_update_types), cycle_result = generic_predicates_for_param_cycle_result)] pub(crate) fn generic_predicates_for_param<'db>( db: &'db dyn HirDatabase, def: GenericDefId, @@ -1609,6 +1612,7 @@ pub(crate) fn generic_predicates_for_param<'db>( pub(crate) fn generic_predicates_for_param_cycle_result<'db>( _db: &'db dyn HirDatabase, + _: salsa::Id, _def: GenericDefId, _param_id: TypeOrConstParamId, _assoc_name: Option, @@ -1624,7 +1628,7 @@ pub(crate) fn type_alias_bounds<'db>( type_alias_bounds_with_diagnostics(db, type_alias).0.as_ref().map_bound(|it| &**it) } -#[salsa::tracked(returns(ref), unsafe(non_update_return_type))] +#[salsa::tracked(returns(ref), unsafe(non_update_types))] pub fn type_alias_bounds_with_diagnostics<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, @@ -1682,7 +1686,7 @@ impl<'db> GenericPredicates<'db> { /// Resolve the where clause(s) of an item with generics. /// /// Diagnostics are computed only for this item's predicates, not for parents. - #[salsa::tracked(returns(ref), unsafe(non_update_return_type))] + #[salsa::tracked(returns(ref), unsafe(non_update_types))] pub fn query_with_diagnostics( db: &'db dyn HirDatabase, def: GenericDefId, @@ -2090,6 +2094,7 @@ pub(crate) fn generic_defaults_with_diagnostics_query( pub(crate) fn generic_defaults_with_diagnostics_cycle_result( _db: &dyn HirDatabase, + _: salsa::Id, _def: GenericDefId, ) -> (GenericDefaults<'_>, Diagnostics) { (GenericDefaults(None), None) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index 5bce4222a4fa..d7a8c18614a4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -2261,6 +2261,7 @@ pub fn mir_body_query<'db>( pub(crate) fn mir_body_cycle_result<'db>( _db: &'db dyn HirDatabase, + _: salsa::Id, _def: DefWithBodyId, ) -> Result<'db, Arc>> { Err(MirLowerError::Loop) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs index b67365c344a6..beb0003c31ca 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs @@ -223,6 +223,7 @@ pub fn monomorphized_mir_body_query<'db>( pub(crate) fn monomorphized_mir_body_cycle_result<'db>( _db: &'db dyn HirDatabase, + _: salsa::Id, _: DefWithBodyId, _: GenericArgs<'db>, _: ParamEnvAndCrate<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs index 926dbdc03d03..3a32cf8b1fef 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/consts.rs @@ -23,7 +23,7 @@ use super::{BoundVarKind, DbInterner, ErrorGuaranteed, GenericArgs, Placeholder, pub type ConstKind<'db> = rustc_type_ir::ConstKind>; pub type UnevaluatedConst<'db> = rustc_type_ir::UnevaluatedConst>; -#[salsa::interned(constructor = new_)] +#[salsa::interned(constructor = new_, unsafe(non_update_types))] pub struct Const<'db> { #[returns(ref)] kind_: InternedWrapperNoDebug>>, @@ -202,7 +202,7 @@ impl Hash for ConstBytes<'_> { } } -#[salsa::interned(constructor = new_, debug)] +#[salsa::interned(constructor = new_, debug, unsafe(non_update_types))] pub struct Valtree<'db> { #[returns(ref)] bytes_: ConstBytes<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 8b24a20a5bed..4c34183da99c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -202,7 +202,7 @@ macro_rules! _interned_vec_db { } }; ($name:ident, $ty:ident, nofold) => { - #[salsa::interned(constructor = new_)] + #[salsa::interned(constructor = new_, unsafe(non_update_types))] pub struct $name<'db> { #[returns(ref)] inner_: smallvec::SmallVec<[$ty<'db>; 2]>, @@ -762,7 +762,7 @@ impl std::ops::Deref for UnsizingParams { pub type PatternKind<'db> = rustc_type_ir::PatternKind>; -#[salsa::interned(constructor = new_, debug)] +#[salsa::interned(constructor = new_, debug, unsafe(non_update_types))] pub struct Pattern<'db> { #[returns(ref)] kind_: InternedWrapperNoDebug>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs index e8f5be2eb598..4fbeb76adaad 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/opaques.rs @@ -15,7 +15,7 @@ pub type ExternalConstraintsData<'db> = interned_vec_nolifetime_salsa!(SolverDefIds, SolverDefId); -#[salsa::interned(constructor = new_, debug)] +#[salsa::interned(constructor = new_, debug, unsafe(non_update_types))] pub struct ExternalConstraints<'db> { #[returns(ref)] kind_: rustc_type_ir::solve::ExternalConstraintsData>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs index 783966ee1ee1..71d9b0b55a30 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/predicate.rs @@ -172,7 +172,7 @@ impl<'db> rustc_type_ir::relate::Relate> for BoundExistentialPre } } -#[salsa::interned(constructor = new_)] +#[salsa::interned(constructor = new_, unsafe(non_update_types))] pub struct Predicate<'db> { #[returns(ref)] kind_: InternedWrapperNoDebug>>>, @@ -278,7 +278,7 @@ impl<'db> std::hash::Hash for InternedClausesWrapper<'db> { } } -#[salsa::interned(constructor = new_)] +#[salsa::interned(constructor = new_, unsafe(non_update_types))] pub struct Clauses<'db> { #[returns(ref)] inner_: InternedClausesWrapper<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs index 19f3c38b673d..3be715ab07d3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/region.rs @@ -18,7 +18,7 @@ use super::{ pub type RegionKind<'db> = rustc_type_ir::RegionKind>; -#[salsa::interned(constructor = new_)] +#[salsa::interned(constructor = new_, unsafe(non_update_types))] pub struct Region<'db> { #[returns(ref)] kind_: RegionKind<'db>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs index ff89f8e059a5..7dcb8567c2e4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/ty.rs @@ -44,7 +44,7 @@ pub type SimplifiedType = rustc_type_ir::fast_reject::SimplifiedType = rustc_type_ir::TyKind>; pub type FnHeader<'db> = rustc_type_ir::FnHeader>; -#[salsa::interned(constructor = new_)] +#[salsa::interned(constructor = new_, unsafe(non_update_types))] pub struct Ty<'db> { #[returns(ref)] kind_: InternedWrapperNoDebug>>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs index 4c6b585016fa..76a6207e2338 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/opaques.rs @@ -89,7 +89,7 @@ pub(crate) fn opaque_types_defined_by( // These are firewall queries to prevent drawing dependencies between infers: -#[salsa::tracked(returns(ref), unsafe(non_update_return_type))] +#[salsa::tracked(returns(ref), unsafe(non_update_types))] pub(crate) fn rpit_hidden_types<'db>( db: &'db dyn HirDatabase, function: FunctionId, @@ -103,7 +103,7 @@ pub(crate) fn rpit_hidden_types<'db>( result } -#[salsa::tracked(returns(ref), unsafe(non_update_return_type))] +#[salsa::tracked(returns(ref), unsafe(non_update_types))] pub(crate) fn tait_hidden_types<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs index 9ae9a8e2a993..4164e39e6592 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/specialization.rs @@ -22,6 +22,7 @@ use crate::{ // cannot create a cycle, but a cycle handler is required nevertheless. fn specializes_query_cycle( _db: &dyn HirDatabase, + _: salsa::Id, _specializing_impl_def_id: ImplId, _parent_impl_def_id: ImplId, ) -> bool { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs index 5c0af6dafb52..b32180d41247 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs @@ -105,6 +105,7 @@ fn glb(v1: Variance, v2: Variance) -> Variance { pub(crate) fn variances_of_cycle_initial( db: &dyn HirDatabase, + _: salsa::Id, def: GenericDefId, ) -> VariancesOf<'_> { let interner = DbInterner::new_no_crate(db); diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs index 7698ce5fff13..fe932ac133a0 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs @@ -49,7 +49,7 @@ impl ToTokens for TrackedQuery { }) .into_iter() .chain(self.lru.map(|lru| quote!(lru = #lru))) - .chain(Some(quote!(unsafe(non_update_return_type)))); + .chain(Some(quote!(unsafe(non_update_types)))); let annotation = quote!(#[salsa_macros::tracked( #(#options),* )]); let pat_and_tys = &self.pat_and_tys; From 6166f9072afb9696a52e7e05370f6cea21caa1ea Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Wed, 17 Dec 2025 13:11:23 +0200 Subject: [PATCH 0914/3801] Remove redundant things from the lang items macro --- .../crates/hir-def/src/lang_item.rs | 304 +++++++++--------- 1 file changed, 149 insertions(+), 155 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index 6c8fb55d8f51..fd693477a4b4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs @@ -154,16 +154,10 @@ pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option if traits.is_empty() { None } else { Some(traits.into_iter().collect()) } } -pub enum GenericRequirement { - None, - Minimum(usize), - Exact(usize), -} - macro_rules! language_item_table { ( $LangItems:ident => - $( $(#[$attr:meta])* $lang_item:ident, $module:ident :: $name:ident, $method:ident, $target:ident, $generics:expr; )* + $( $(#[$attr:meta])* $lang_item:ident, $module:ident :: $name:ident, $target:ident; )* ) => { #[allow(non_snake_case)] // FIXME: Should we remove this? #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] @@ -226,101 +220,101 @@ macro_rules! language_item_table { } language_item_table! { LangItems => -// Variant name, Name, Getter method name, Target Generic requirements; - Sized, sym::sized, sized_trait, TraitId, GenericRequirement::Exact(0); - MetaSized, sym::meta_sized, sized_trait, TraitId, GenericRequirement::Exact(0); - PointeeSized, sym::pointee_sized, sized_trait, TraitId, GenericRequirement::Exact(0); - Unsize, sym::unsize, unsize_trait, TraitId, GenericRequirement::Minimum(1); +// Variant name, Name, Target; + Sized, sym::sized, TraitId; + MetaSized, sym::meta_sized, TraitId; + PointeeSized, sym::pointee_sized, TraitId; + Unsize, sym::unsize, TraitId; /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ"). - StructuralPeq, sym::structural_peq, structural_peq_trait, TraitId, GenericRequirement::None; + StructuralPeq, sym::structural_peq, TraitId; /// Trait injected by `#[derive(Eq)]`, (i.e. "Total EQ"; no, I will not apologize). - StructuralTeq, sym::structural_teq, structural_teq_trait, TraitId, GenericRequirement::None; - Copy, sym::copy, copy_trait, TraitId, GenericRequirement::Exact(0); - Clone, sym::clone, clone_trait, TraitId, GenericRequirement::None; - TrivialClone, sym::trivial_clone, clone_trait, TraitId, GenericRequirement::None; - Sync, sym::sync, sync_trait, TraitId, GenericRequirement::Exact(0); - DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, TraitId, GenericRequirement::None; + StructuralTeq, sym::structural_teq, TraitId; + Copy, sym::copy, TraitId; + Clone, sym::clone, TraitId; + TrivialClone, sym::trivial_clone, TraitId; + Sync, sym::sync, TraitId; + DiscriminantKind, sym::discriminant_kind, TraitId; /// The associated item of the `DiscriminantKind` trait. - Discriminant, sym::discriminant_type, discriminant_type, TypeAliasId, GenericRequirement::None; + Discriminant, sym::discriminant_type, TypeAliasId; - PointeeTrait, sym::pointee_trait, pointee_trait, TraitId, GenericRequirement::None; - Metadata, sym::metadata_type, metadata_type, TypeAliasId, GenericRequirement::None; - DynMetadata, sym::dyn_metadata, dyn_metadata, StructId, GenericRequirement::None; + PointeeTrait, sym::pointee_trait, TraitId; + Metadata, sym::metadata_type, TypeAliasId; + DynMetadata, sym::dyn_metadata, StructId; - Freeze, sym::freeze, freeze_trait, TraitId, GenericRequirement::Exact(0); + Freeze, sym::freeze, TraitId; - FnPtrTrait, sym::fn_ptr_trait, fn_ptr_trait, TraitId, GenericRequirement::Exact(0); - FnPtrAddr, sym::fn_ptr_addr, fn_ptr_addr, FunctionId, GenericRequirement::None; + FnPtrTrait, sym::fn_ptr_trait, TraitId; + FnPtrAddr, sym::fn_ptr_addr, FunctionId; - Drop, sym::drop, drop_trait, TraitId, GenericRequirement::None; - Destruct, sym::destruct, destruct_trait, TraitId, GenericRequirement::None; + Drop, sym::drop, TraitId; + Destruct, sym::destruct, TraitId; - CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, TraitId, GenericRequirement::Minimum(1); - DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, TraitId, GenericRequirement::Minimum(1); + CoerceUnsized, sym::coerce_unsized, TraitId; + DispatchFromDyn, sym::dispatch_from_dyn, TraitId; // language items relating to transmutability - TransmuteOpts, sym::transmute_opts, transmute_opts, StructId, GenericRequirement::Exact(0); - TransmuteTrait, sym::transmute_trait, transmute_trait, TraitId, GenericRequirement::Exact(3); + TransmuteOpts, sym::transmute_opts, StructId; + TransmuteTrait, sym::transmute_trait, TraitId; - Add, sym::add, add_trait, TraitId, GenericRequirement::Exact(1); - Sub, sym::sub, sub_trait, TraitId, GenericRequirement::Exact(1); - Mul, sym::mul, mul_trait, TraitId, GenericRequirement::Exact(1); - Div, sym::div, div_trait, TraitId, GenericRequirement::Exact(1); - Rem, sym::rem, rem_trait, TraitId, GenericRequirement::Exact(1); - Neg, sym::neg, neg_trait, TraitId, GenericRequirement::Exact(0); - Not, sym::not, not_trait, TraitId, GenericRequirement::Exact(0); - BitXor, sym::bitxor, bitxor_trait, TraitId, GenericRequirement::Exact(1); - BitAnd, sym::bitand, bitand_trait, TraitId, GenericRequirement::Exact(1); - BitOr, sym::bitor, bitor_trait, TraitId, GenericRequirement::Exact(1); - Shl, sym::shl, shl_trait, TraitId, GenericRequirement::Exact(1); - Shr, sym::shr, shr_trait, TraitId, GenericRequirement::Exact(1); - AddAssign, sym::add_assign, add_assign_trait, TraitId, GenericRequirement::Exact(1); - SubAssign, sym::sub_assign, sub_assign_trait, TraitId, GenericRequirement::Exact(1); - MulAssign, sym::mul_assign, mul_assign_trait, TraitId, GenericRequirement::Exact(1); - DivAssign, sym::div_assign, div_assign_trait, TraitId, GenericRequirement::Exact(1); - RemAssign, sym::rem_assign, rem_assign_trait, TraitId, GenericRequirement::Exact(1); - BitXorAssign, sym::bitxor_assign, bitxor_assign_trait, TraitId, GenericRequirement::Exact(1); - BitAndAssign, sym::bitand_assign, bitand_assign_trait, TraitId, GenericRequirement::Exact(1); - BitOrAssign, sym::bitor_assign, bitor_assign_trait, TraitId, GenericRequirement::Exact(1); - ShlAssign, sym::shl_assign, shl_assign_trait, TraitId, GenericRequirement::Exact(1); - ShrAssign, sym::shr_assign, shr_assign_trait, TraitId, GenericRequirement::Exact(1); - Index, sym::index, index_trait, TraitId, GenericRequirement::Exact(1); - IndexMut, sym::index_mut, index_mut_trait, TraitId, GenericRequirement::Exact(1); + Add, sym::add, TraitId; + Sub, sym::sub, TraitId; + Mul, sym::mul, TraitId; + Div, sym::div, TraitId; + Rem, sym::rem, TraitId; + Neg, sym::neg, TraitId; + Not, sym::not, TraitId; + BitXor, sym::bitxor, TraitId; + BitAnd, sym::bitand, TraitId; + BitOr, sym::bitor, TraitId; + Shl, sym::shl, TraitId; + Shr, sym::shr, TraitId; + AddAssign, sym::add_assign, TraitId; + SubAssign, sym::sub_assign, TraitId; + MulAssign, sym::mul_assign, TraitId; + DivAssign, sym::div_assign, TraitId; + RemAssign, sym::rem_assign, TraitId; + BitXorAssign, sym::bitxor_assign, TraitId; + BitAndAssign, sym::bitand_assign, TraitId; + BitOrAssign, sym::bitor_assign, TraitId; + ShlAssign, sym::shl_assign, TraitId; + ShrAssign, sym::shr_assign, TraitId; + Index, sym::index, TraitId; + IndexMut, sym::index_mut, TraitId; - UnsafeCell, sym::unsafe_cell, unsafe_cell_type, StructId, GenericRequirement::None; - UnsafePinned, sym::unsafe_pinned, unsafe_pinned_type, StructId, GenericRequirement::None; - VaList, sym::va_list, va_list, StructId, GenericRequirement::None; + UnsafeCell, sym::unsafe_cell, StructId; + UnsafePinned, sym::unsafe_pinned, StructId; + VaList, sym::va_list, StructId; - Deref, sym::deref, deref_trait, TraitId, GenericRequirement::Exact(0); - DerefMut, sym::deref_mut, deref_mut_trait, TraitId, GenericRequirement::Exact(0); - DerefTarget, sym::deref_target, deref_target, TypeAliasId, GenericRequirement::None; - Receiver, sym::receiver, receiver_trait, TraitId, GenericRequirement::None; - ReceiverTarget, sym::receiver_target, receiver_target, TypeAliasId, GenericRequirement::None; + Deref, sym::deref, TraitId; + DerefMut, sym::deref_mut, TraitId; + DerefTarget, sym::deref_target, TypeAliasId; + Receiver, sym::receiver, TraitId; + ReceiverTarget, sym::receiver_target, TypeAliasId; - Fn, sym::fn_, fn_trait, TraitId, GenericRequirement::Exact(1); - FnMut, sym::fn_mut, fn_mut_trait, TraitId, GenericRequirement::Exact(1); - FnOnce, sym::fn_once, fn_once_trait, TraitId, GenericRequirement::Exact(1); - AsyncFn, sym::async_fn, async_fn_trait, TraitId, GenericRequirement::Exact(1); - AsyncFnMut, sym::async_fn_mut, async_fn_mut_trait, TraitId, GenericRequirement::Exact(1); - AsyncFnOnce, sym::async_fn_once, async_fn_once_trait, TraitId, GenericRequirement::Exact(1); + Fn, sym::fn_, TraitId; + FnMut, sym::fn_mut, TraitId; + FnOnce, sym::fn_once, TraitId; + AsyncFn, sym::async_fn, TraitId; + AsyncFnMut, sym::async_fn_mut, TraitId; + AsyncFnOnce, sym::async_fn_once, TraitId; - CallRefFuture, sym::call_ref_future, call_ref_future_ty, TypeAliasId, GenericRequirement::None; - CallOnceFuture, sym::call_once_future, call_once_future_ty, TypeAliasId, GenericRequirement::None; - AsyncFnOnceOutput, sym::async_fn_once_output, async_fn_once_output_ty, TypeAliasId, GenericRequirement::None; + CallRefFuture, sym::call_ref_future, TypeAliasId; + CallOnceFuture, sym::call_once_future, TypeAliasId; + AsyncFnOnceOutput, sym::async_fn_once_output, TypeAliasId; - FnOnceOutput, sym::fn_once_output, fn_once_output, TypeAliasId, GenericRequirement::None; + FnOnceOutput, sym::fn_once_output, TypeAliasId; - Future, sym::future_trait, future_trait, TraitId, GenericRequirement::Exact(0); - CoroutineState, sym::coroutine_state, coroutine_state, EnumId, GenericRequirement::None; - Coroutine, sym::coroutine, coroutine_trait, TraitId, GenericRequirement::Minimum(1); - CoroutineReturn, sym::coroutine_return, coroutine_return_ty, TypeAliasId, GenericRequirement::None; - CoroutineYield, sym::coroutine_yield, coroutine_yield_ty, TypeAliasId, GenericRequirement::None; - Unpin, sym::unpin, unpin_trait, TraitId, GenericRequirement::None; - Pin, sym::pin, pin_type, StructId, GenericRequirement::None; + Future, sym::future_trait, TraitId; + CoroutineState, sym::coroutine_state, EnumId; + Coroutine, sym::coroutine, TraitId; + CoroutineReturn, sym::coroutine_return, TypeAliasId; + CoroutineYield, sym::coroutine_yield, TypeAliasId; + Unpin, sym::unpin, TraitId; + Pin, sym::pin, StructId; - PartialEq, sym::eq, eq_trait, TraitId, GenericRequirement::Exact(1); - PartialOrd, sym::partial_ord, partial_ord_trait, TraitId, GenericRequirement::Exact(1); - CVoid, sym::c_void, c_void, EnumId, GenericRequirement::None; + PartialEq, sym::eq, TraitId; + PartialOrd, sym::partial_ord, TraitId; + CVoid, sym::c_void, EnumId; // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays. @@ -329,107 +323,107 @@ language_item_table! { LangItems => // in the sense that a crate is not required to have it defined to use it, but a final product // is required to define it somewhere. Additionally, there are restrictions on crates that use // a weak lang item, but do not have it defined. - Panic, sym::panic, panic_fn, FunctionId, GenericRequirement::Exact(0); - PanicNounwind, sym::panic_nounwind, panic_nounwind, FunctionId, GenericRequirement::Exact(0); - PanicFmt, sym::panic_fmt, panic_fmt, FunctionId, GenericRequirement::None; - PanicDisplay, sym::panic_display, panic_display, FunctionId, GenericRequirement::None; - ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, FunctionId, GenericRequirement::None; - PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, FunctionId, GenericRequirement::Exact(0); - PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, FunctionId, GenericRequirement::Exact(0); - PanicInfo, sym::panic_info, panic_info, StructId, GenericRequirement::None; - PanicLocation, sym::panic_location, panic_location, StructId, GenericRequirement::None; - PanicImpl, sym::panic_impl, panic_impl, FunctionId, GenericRequirement::None; - PanicCannotUnwind, sym::panic_cannot_unwind, panic_cannot_unwind, FunctionId, GenericRequirement::Exact(0); - PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, FunctionId, GenericRequirement::None; + Panic, sym::panic, FunctionId; + PanicNounwind, sym::panic_nounwind, FunctionId; + PanicFmt, sym::panic_fmt, FunctionId; + PanicDisplay, sym::panic_display, FunctionId; + ConstPanicFmt, sym::const_panic_fmt, FunctionId; + PanicBoundsCheck, sym::panic_bounds_check, FunctionId; + PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, FunctionId; + PanicInfo, sym::panic_info, StructId; + PanicLocation, sym::panic_location, StructId; + PanicImpl, sym::panic_impl, FunctionId; + PanicCannotUnwind, sym::panic_cannot_unwind, FunctionId; + PanicNullPointerDereference, sym::panic_null_pointer_dereference, FunctionId; /// libstd panic entry point. Necessary for const eval to be able to catch it - BeginPanic, sym::begin_panic, begin_panic_fn, FunctionId, GenericRequirement::None; + BeginPanic, sym::begin_panic, FunctionId; // Lang items needed for `format_args!()`. - FormatAlignment, sym::format_alignment, format_alignment, EnumId, GenericRequirement::None; - FormatArgument, sym::format_argument, format_argument, StructId, GenericRequirement::None; - FormatArguments, sym::format_arguments, format_arguments, StructId, GenericRequirement::None; - FormatCount, sym::format_count, format_count, EnumId, GenericRequirement::None; - FormatPlaceholder, sym::format_placeholder, format_placeholder, StructId, GenericRequirement::None; - FormatUnsafeArg, sym::format_unsafe_arg, format_unsafe_arg, StructId, GenericRequirement::None; + FormatAlignment, sym::format_alignment, EnumId; + FormatArgument, sym::format_argument, StructId; + FormatArguments, sym::format_arguments, StructId; + FormatCount, sym::format_count, EnumId; + FormatPlaceholder, sym::format_placeholder, StructId; + FormatUnsafeArg, sym::format_unsafe_arg, StructId; - ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, FunctionId, GenericRequirement::None; - BoxFree, sym::box_free, box_free_fn, FunctionId, GenericRequirement::Minimum(1); - DropInPlace, sym::drop_in_place, drop_in_place_fn, FunctionId, GenericRequirement::Minimum(1); - AllocLayout, sym::alloc_layout, alloc_layout, StructId, GenericRequirement::None; + ExchangeMalloc, sym::exchange_malloc, FunctionId; + BoxFree, sym::box_free, FunctionId; + DropInPlace, sym::drop_in_place, FunctionId; + AllocLayout, sym::alloc_layout, StructId; - Start, sym::start, start_fn, FunctionId, GenericRequirement::Exact(1); + Start, sym::start, FunctionId; - EhPersonality, sym::eh_personality, eh_personality, FunctionId, GenericRequirement::None; - EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, StaticId, GenericRequirement::None; + EhPersonality, sym::eh_personality, FunctionId; + EhCatchTypeinfo, sym::eh_catch_typeinfo, StaticId; - OwnedBox, sym::owned_box, owned_box, StructId, GenericRequirement::Minimum(1); + OwnedBox, sym::owned_box, StructId; - PhantomData, sym::phantom_data, phantom_data, StructId, GenericRequirement::Exact(1); + PhantomData, sym::phantom_data, StructId; - ManuallyDrop, sym::manually_drop, manually_drop, StructId, GenericRequirement::None; + ManuallyDrop, sym::manually_drop, StructId; - MaybeUninit, sym::maybe_uninit, maybe_uninit, UnionId, GenericRequirement::None; + MaybeUninit, sym::maybe_uninit, UnionId; /// Align offset for stride != 1; must not panic. - AlignOffset, sym::align_offset, align_offset_fn, FunctionId, GenericRequirement::None; + AlignOffset, sym::align_offset, FunctionId; - Termination, sym::termination, termination, TraitId, GenericRequirement::None; + Termination, sym::termination, TraitId; - Try, sym::Try, try_trait, TraitId, GenericRequirement::None; + Try, sym::Try, TraitId; - Tuple, sym::tuple_trait, tuple_trait, TraitId, GenericRequirement::Exact(0); + Tuple, sym::tuple_trait, TraitId; - SliceLen, sym::slice_len_fn, slice_len_fn, FunctionId, GenericRequirement::None; + SliceLen, sym::slice_len_fn, FunctionId; // Language items from AST lowering - TryTraitFromResidual, sym::from_residual, from_residual_fn, FunctionId, GenericRequirement::None; - TryTraitFromOutput, sym::from_output, from_output_fn, FunctionId, GenericRequirement::None; - TryTraitBranch, sym::branch, branch_fn, FunctionId, GenericRequirement::None; - TryTraitFromYeet, sym::from_yeet, from_yeet_fn, FunctionId, GenericRequirement::None; + TryTraitFromResidual, sym::from_residual, FunctionId; + TryTraitFromOutput, sym::from_output, FunctionId; + TryTraitBranch, sym::branch, FunctionId; + TryTraitFromYeet, sym::from_yeet, FunctionId; - PointerLike, sym::pointer_like, pointer_like, TraitId, GenericRequirement::Exact(0); + PointerLike, sym::pointer_like, TraitId; - ConstParamTy, sym::const_param_ty, const_param_ty_trait, TraitId, GenericRequirement::Exact(0); + ConstParamTy, sym::const_param_ty, TraitId; - Poll, sym::Poll, poll, EnumId, GenericRequirement::None; - PollReady, sym::Ready, poll_ready_variant, EnumVariantId, GenericRequirement::None; - PollPending, sym::Pending, poll_pending_variant, EnumVariantId, GenericRequirement::None; + Poll, sym::Poll, EnumId; + PollReady, sym::Ready, EnumVariantId; + PollPending, sym::Pending, EnumVariantId; // FIXME(swatinem): the following lang items are used for async lowering and // should become obsolete eventually. - ResumeTy, sym::ResumeTy, resume_ty, StructId, GenericRequirement::None; - GetContext, sym::get_context, get_context_fn, FunctionId, GenericRequirement::None; + ResumeTy, sym::ResumeTy, StructId; + GetContext, sym::get_context, FunctionId; - Context, sym::Context, context, StructId, GenericRequirement::None; - FuturePoll, sym::poll, future_poll_fn, FunctionId, GenericRequirement::None; - FutureOutput, sym::future_output, future_output, TypeAliasId, GenericRequirement::None; + Context, sym::Context, StructId; + FuturePoll, sym::poll, FunctionId; + FutureOutput, sym::future_output, TypeAliasId; - Option, sym::Option, option_type, EnumId, GenericRequirement::None; - OptionSome, sym::Some, option_some_variant, EnumVariantId, GenericRequirement::None; - OptionNone, sym::None, option_none_variant, EnumVariantId, GenericRequirement::None; + Option, sym::Option, EnumId; + OptionSome, sym::Some, EnumVariantId; + OptionNone, sym::None, EnumVariantId; - ResultOk, sym::Ok, result_ok_variant, EnumVariantId, GenericRequirement::None; - ResultErr, sym::Err, result_err_variant, EnumVariantId, GenericRequirement::None; + ResultOk, sym::Ok, EnumVariantId; + ResultErr, sym::Err, EnumVariantId; - ControlFlowContinue, sym::Continue, cf_continue_variant, EnumVariantId, GenericRequirement::None; - ControlFlowBreak, sym::Break, cf_break_variant, EnumVariantId, GenericRequirement::None; + ControlFlowContinue, sym::Continue, EnumVariantId; + ControlFlowBreak, sym::Break, EnumVariantId; - IntoFutureIntoFuture, sym::into_future, into_future_fn, FunctionId, GenericRequirement::None; - IntoIterIntoIter, sym::into_iter, into_iter_fn, FunctionId, GenericRequirement::None; - IteratorNext, sym::next, next_fn, FunctionId, GenericRequirement::None; - Iterator, sym::iterator, iterator, TraitId, GenericRequirement::None; + IntoFutureIntoFuture, sym::into_future, FunctionId; + IntoIterIntoIter, sym::into_iter, FunctionId; + IteratorNext, sym::next, FunctionId; + Iterator, sym::iterator, TraitId; - PinNewUnchecked, sym::new_unchecked, new_unchecked_fn, FunctionId, GenericRequirement::None; + PinNewUnchecked, sym::new_unchecked, FunctionId; - RangeFrom, sym::RangeFrom, range_from_struct, StructId, GenericRequirement::None; - RangeFull, sym::RangeFull, range_full_struct, StructId, GenericRequirement::None; - RangeInclusiveStruct, sym::RangeInclusive, range_inclusive_struct, StructId, GenericRequirement::None; - RangeInclusiveNew, sym::range_inclusive_new, range_inclusive_new_method, FunctionId, GenericRequirement::None; - Range, sym::Range, range_struct, StructId, GenericRequirement::None; - RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, StructId, GenericRequirement::None; - RangeTo, sym::RangeTo, range_to_struct, StructId, GenericRequirement::None; + RangeFrom, sym::RangeFrom, StructId; + RangeFull, sym::RangeFull, StructId; + RangeInclusiveStruct, sym::RangeInclusive, StructId; + RangeInclusiveNew, sym::range_inclusive_new, FunctionId; + Range, sym::Range, StructId; + RangeToInclusive, sym::RangeToInclusive, StructId; + RangeTo, sym::RangeTo, StructId; - String, sym::String, string, StructId, GenericRequirement::None; - CStr, sym::CStr, c_str, StructId, GenericRequirement::None; - Ordering, sym::Ordering, ordering, EnumId, GenericRequirement::None; + String, sym::String, StructId; + CStr, sym::CStr, StructId; + Ordering, sym::Ordering, EnumId; } From 3e55ab1adfd50292a3710ad860fd01f511bc7b66 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Mon, 20 Oct 2025 17:41:40 +0200 Subject: [PATCH 0915/3801] dogfood the lint This commit is put before the one that actually introduces the lint, since, were they put in the opposite order, the first commit wouldn't pass dogfood --- clippy_lints/src/booleans.rs | 2 +- clippy_lints/src/fallible_impl_from.rs | 2 +- clippy_lints/src/implicit_hasher.rs | 23 +++++------ clippy_lints/src/loops/for_kv_map.rs | 2 +- clippy_lints/src/manual_let_else.rs | 2 +- clippy_lints/src/matches/match_wild_enum.rs | 2 +- clippy_lints/src/methods/expect_fun_call.rs | 10 ++--- clippy_lints/src/methods/iter_count.rs | 31 ++++++--------- clippy_lints/src/methods/iter_kv_map.rs | 2 +- .../src/methods/join_absolute_paths.rs | 2 +- clippy_lints/src/methods/map_clone.rs | 2 +- clippy_lints/src/methods/or_then_unwrap.rs | 38 ++++++++++--------- .../src/methods/unnecessary_get_then_check.rs | 4 +- .../src/methods/unwrap_expect_used.rs | 24 ++++++------ clippy_lints/src/missing_fields_in_debug.rs | 12 ++++-- clippy_lints/src/time_subtraction.rs | 16 ++++---- clippy_lints/src/zero_sized_map_values.rs | 2 +- clippy_utils/src/consts.rs | 10 +++-- clippy_utils/src/sym.rs | 4 ++ 19 files changed, 94 insertions(+), 96 deletions(-) diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index 902ba70577b9..a04a56d72bc0 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -433,7 +433,7 @@ fn simplify_not(cx: &LateContext<'_>, curr_msrv: Msrv, expr: &Expr<'_>) -> Optio }, ExprKind::MethodCall(path, receiver, args, _) => { let type_of_receiver = cx.typeck_results().expr_ty(receiver); - if !type_of_receiver.is_diag_item(cx, sym::Option) && !type_of_receiver.is_diag_item(cx, sym::Result) { + if !matches!(type_of_receiver.opt_diag_name(cx), Some(sym::Option | sym::Result)) { return None; } METHODS_WITH_NEGATION diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index c42998ffc3f5..bd2bd6628464 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -82,7 +82,7 @@ fn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Sp // check for `unwrap` if let Some(arglists) = method_chain_args(expr, &[sym::unwrap]) { let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs(); - if receiver_ty.is_diag_item(self.lcx, sym::Option) || receiver_ty.is_diag_item(self.lcx, sym::Result) { + if matches!(receiver_ty.opt_diag_name(self.lcx), Some(sym::Option | sym::Result)) { self.result.push(expr.span); } } diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 638a08b096db..9dc74a157cbf 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -223,25 +223,20 @@ impl<'tcx> ImplicitHasherType<'tcx> { _ => None, }) .collect(); - let params_len = params.len(); let ty = lower_ty(cx.tcx, hir_ty); - if ty.is_diag_item(cx, sym::HashMap) && params_len == 2 { - Some(ImplicitHasherType::HashMap( + match (ty.opt_diag_name(cx), ¶ms[..]) { + (Some(sym::HashMap), [k, v]) => Some(ImplicitHasherType::HashMap( hir_ty.span, ty, - snippet(cx, params[0].span, "K"), - snippet(cx, params[1].span, "V"), - )) - } else if ty.is_diag_item(cx, sym::HashSet) && params_len == 1 { - Some(ImplicitHasherType::HashSet( - hir_ty.span, - ty, - snippet(cx, params[0].span, "T"), - )) - } else { - None + snippet(cx, k.span, "K"), + snippet(cx, v.span, "V"), + )), + (Some(sym::HashSet), [t]) => { + Some(ImplicitHasherType::HashSet(hir_ty.span, ty, snippet(cx, t.span, "T"))) + }, + _ => None, } } else { None diff --git a/clippy_lints/src/loops/for_kv_map.rs b/clippy_lints/src/loops/for_kv_map.rs index c6b650a1a88b..39b2391c98ec 100644 --- a/clippy_lints/src/loops/for_kv_map.rs +++ b/clippy_lints/src/loops/for_kv_map.rs @@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx _ => arg, }; - if ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap) { + if matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) { span_lint_and_then( cx, FOR_KV_MAP, diff --git a/clippy_lints/src/manual_let_else.rs b/clippy_lints/src/manual_let_else.rs index 0f3d8b336675..38ee4ce104a5 100644 --- a/clippy_lints/src/manual_let_else.rs +++ b/clippy_lints/src/manual_let_else.rs @@ -374,7 +374,7 @@ fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: boo } let ty = typeck_results.pat_ty(pat); // Option and Result are allowed, everything else isn't. - if !(ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result)) { + if !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) { has_disallowed = true; } }); diff --git a/clippy_lints/src/matches/match_wild_enum.rs b/clippy_lints/src/matches/match_wild_enum.rs index fa44a56af182..00bd1c2ca698 100644 --- a/clippy_lints/src/matches/match_wild_enum.rs +++ b/clippy_lints/src/matches/match_wild_enum.rs @@ -16,7 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { let ty = cx.typeck_results().expr_ty(ex).peel_refs(); let adt_def = match ty.kind() { ty::Adt(adt_def, _) - if adt_def.is_enum() && !(ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result)) => + if adt_def.is_enum() && !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) => { adt_def }, diff --git a/clippy_lints/src/methods/expect_fun_call.rs b/clippy_lints/src/methods/expect_fun_call.rs index 288f966991ac..e891b2ac6d64 100644 --- a/clippy_lints/src/methods/expect_fun_call.rs +++ b/clippy_lints/src/methods/expect_fun_call.rs @@ -26,12 +26,10 @@ pub(super) fn check<'tcx>( let arg_root = get_arg_root(cx, arg); if contains_call(cx, arg_root) && !contains_return(arg_root) { let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver); - let closure_args = if receiver_type.is_diag_item(cx, sym::Option) { - "||" - } else if receiver_type.is_diag_item(cx, sym::Result) { - "|_|" - } else { - return; + let closure_args = match receiver_type.opt_diag_name(cx) { + Some(sym::Option) => "||", + Some(sym::Result) => "|_|", + _ => return, }; let span_replace_word = method_span.with_hi(expr.span.hi()); diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs index ea2508cd7f38..8b303c0ca5b2 100644 --- a/clippy_lints/src/methods/iter_count.rs +++ b/clippy_lints/src/methods/iter_count.rs @@ -11,26 +11,17 @@ use super::ITER_COUNT; pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, iter_method: Symbol) { let ty = cx.typeck_results().expr_ty(recv); - let caller_type = if derefs_to_slice(cx, recv, ty).is_some() { - "slice" - } else if ty.is_diag_item(cx, sym::Vec) { - "Vec" - } else if ty.is_diag_item(cx, sym::VecDeque) { - "VecDeque" - } else if ty.is_diag_item(cx, sym::HashSet) { - "HashSet" - } else if ty.is_diag_item(cx, sym::HashMap) { - "HashMap" - } else if ty.is_diag_item(cx, sym::BTreeMap) { - "BTreeMap" - } else if ty.is_diag_item(cx, sym::BTreeSet) { - "BTreeSet" - } else if ty.is_diag_item(cx, sym::LinkedList) { - "LinkedList" - } else if ty.is_diag_item(cx, sym::BinaryHeap) { - "BinaryHeap" - } else { - return; + let caller_type = match ty.opt_diag_name(cx) { + _ if derefs_to_slice(cx, recv, ty).is_some() => "slice", + Some(sym::Vec) => "Vec", + Some(sym::VecDeque) => "VecDeque", + Some(sym::HashSet) => "HashSet", + Some(sym::HashMap) => "HashMap", + Some(sym::BTreeMap) => "BTreeMap", + Some(sym::BTreeSet) => "BTreeSet", + Some(sym::LinkedList) => "LinkedList", + Some(sym::BinaryHeap) => "BinaryHeap", + _ => return, }; let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index 2d6bc36dc535..16db8663941e 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -38,7 +38,7 @@ pub(super) fn check<'tcx>( _ => return, } && let ty = cx.typeck_results().expr_ty_adjusted(recv).peel_refs() - && (ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap)) + && matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) { let mut applicability = rustc_errors::Applicability::MachineApplicable; let recv_snippet = snippet_with_applicability(cx, recv.span, "map", &mut applicability); diff --git a/clippy_lints/src/methods/join_absolute_paths.rs b/clippy_lints/src/methods/join_absolute_paths.rs index e84b7452c758..905a58afa795 100644 --- a/clippy_lints/src/methods/join_absolute_paths.rs +++ b/clippy_lints/src/methods/join_absolute_paths.rs @@ -13,7 +13,7 @@ use super::JOIN_ABSOLUTE_PATHS; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx Expr<'tcx>, join_arg: &'tcx Expr<'tcx>, expr_span: Span) { let ty = cx.typeck_results().expr_ty(recv).peel_refs(); - if (ty.is_diag_item(cx, sym::Path) || ty.is_diag_item(cx, sym::PathBuf)) + if matches!(ty.opt_diag_name(cx), Some(sym::Path | sym::PathBuf)) && let ExprKind::Lit(spanned) = expr_or_init(cx, join_arg).kind && let LitKind::Str(symbol, _) = spanned.node && let sym_str = symbol.as_str() diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs index a1aac96ccf86..8a1cc664ac60 100644 --- a/clippy_lints/src/methods/map_clone.rs +++ b/clippy_lints/src/methods/map_clone.rs @@ -25,7 +25,7 @@ fn should_run_lint(cx: &LateContext<'_>, e: &hir::Expr<'_>, method_parent_id: De } // We check if it's an `Option` or a `Result`. if let Some(ty) = method_parent_id.opt_impl_ty(cx) { - if !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result) { + if !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) { return false; } } else { diff --git a/clippy_lints/src/methods/or_then_unwrap.rs b/clippy_lints/src/methods/or_then_unwrap.rs index 07199b84f39e..448ab621a7ce 100644 --- a/clippy_lints/src/methods/or_then_unwrap.rs +++ b/clippy_lints/src/methods/or_then_unwrap.rs @@ -20,24 +20,28 @@ pub(super) fn check<'tcx>( let title; let or_arg_content: Span; - if ty.is_diag_item(cx, sym::Option) { - title = "found `.or(Some(…)).unwrap()`"; - if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::OptionSome) { - or_arg_content = content; - } else { + match ty.opt_diag_name(cx) { + Some(sym::Option) => { + title = "found `.or(Some(…)).unwrap()`"; + if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::OptionSome) { + or_arg_content = content; + } else { + return; + } + }, + Some(sym::Result) => { + title = "found `.or(Ok(…)).unwrap()`"; + if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::ResultOk) { + or_arg_content = content; + } else { + return; + } + }, + _ => { + // Someone has implemented a struct with .or(...).unwrap() chaining, + // but it's not an Option or a Result, so bail return; - } - } else if ty.is_diag_item(cx, sym::Result) { - title = "found `.or(Ok(…)).unwrap()`"; - if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::ResultOk) { - or_arg_content = content; - } else { - return; - } - } else { - // Someone has implemented a struct with .or(...).unwrap() chaining, - // but it's not an Option or a Result, so bail - return; + }, } let mut applicability = Applicability::MachineApplicable; diff --git a/clippy_lints/src/methods/unnecessary_get_then_check.rs b/clippy_lints/src/methods/unnecessary_get_then_check.rs index 10ea0c0c3e23..3207c4207fc0 100644 --- a/clippy_lints/src/methods/unnecessary_get_then_check.rs +++ b/clippy_lints/src/methods/unnecessary_get_then_check.rs @@ -11,11 +11,11 @@ use rustc_span::{Span, sym}; use super::UNNECESSARY_GET_THEN_CHECK; fn is_a_std_set_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - ty.is_diag_item(cx, sym::HashSet) || ty.is_diag_item(cx, sym::BTreeSet) + matches!(ty.opt_diag_name(cx), Some(sym::HashSet | sym::BTreeSet)) } fn is_a_std_map_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap) + matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) } pub(super) fn check( diff --git a/clippy_lints/src/methods/unwrap_expect_used.rs b/clippy_lints/src/methods/unwrap_expect_used.rs index 73a407be4f21..30db2a75df57 100644 --- a/clippy_lints/src/methods/unwrap_expect_used.rs +++ b/clippy_lints/src/methods/unwrap_expect_used.rs @@ -46,19 +46,19 @@ pub(super) fn check( ) { let ty = cx.typeck_results().expr_ty(recv).peel_refs(); - let (kind, none_value, none_prefix) = if ty.is_diag_item(cx, sym::Option) && !is_err { - ("an `Option`", "None", "") - } else if ty.is_diag_item(cx, sym::Result) - && let ty::Adt(_, substs) = ty.kind() - && let Some(t_or_e_ty) = substs[usize::from(!is_err)].as_type() - { - if is_never_like(t_or_e_ty) { - return; - } + let (kind, none_value, none_prefix) = match ty.opt_diag_name(cx) { + Some(sym::Option) if !is_err => ("an `Option`", "None", ""), + Some(sym::Result) + if let ty::Adt(_, substs) = ty.kind() + && let Some(t_or_e_ty) = substs[usize::from(!is_err)].as_type() => + { + if is_never_like(t_or_e_ty) { + return; + } - ("a `Result`", if is_err { "Ok" } else { "Err" }, "an ") - } else { - return; + ("a `Result`", if is_err { "Ok" } else { "Err" }, "an ") + }, + _ => return, }; let method_suffix = if is_err { "_err" } else { "" }; diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs index 15b773c2c64f..a26f24d15247 100644 --- a/clippy_lints/src/missing_fields_in_debug.rs +++ b/clippy_lints/src/missing_fields_in_debug.rs @@ -112,10 +112,14 @@ fn should_lint<'tcx>( if let ExprKind::MethodCall(path, recv, ..) = &expr.kind { let recv_ty = typeck_results.expr_ty(recv).peel_refs(); - if path.ident.name == sym::debug_struct && recv_ty.is_diag_item(cx, sym::Formatter) { - has_debug_struct = true; - } else if path.ident.name == sym::finish_non_exhaustive && recv_ty.is_diag_item(cx, sym::DebugStruct) { - has_finish_non_exhaustive = true; + match (path.ident.name, recv_ty.opt_diag_name(cx)) { + (sym::debug_struct, Some(sym::Formatter)) => { + has_debug_struct = true; + }, + (sym::finish_non_exhaustive, Some(sym::DebugStruct)) => { + has_finish_non_exhaustive = true; + }, + _ => {}, } } ControlFlow::::Continue(()) diff --git a/clippy_lints/src/time_subtraction.rs b/clippy_lints/src/time_subtraction.rs index 92bce998c32f..3ba59aefea06 100644 --- a/clippy_lints/src/time_subtraction.rs +++ b/clippy_lints/src/time_subtraction.rs @@ -91,16 +91,16 @@ impl LateLintPass<'_> for UncheckedTimeSubtraction { _ => return, }; let typeck = cx.typeck_results(); - let lhs_ty = typeck.expr_ty(lhs); - let rhs_ty = typeck.expr_ty(rhs); + let lhs_name = typeck.expr_ty(lhs).opt_diag_name(cx); + let rhs_name = typeck.expr_ty(rhs).opt_diag_name(cx); - if lhs_ty.is_diag_item(cx, sym::Instant) { + if lhs_name == Some(sym::Instant) { // Instant::now() - instant - if is_instant_now_call(cx, lhs) && rhs_ty.is_diag_item(cx, sym::Instant) { + if is_instant_now_call(cx, lhs) && rhs_name == Some(sym::Instant) { print_manual_instant_elapsed_sugg(cx, expr, rhs); } // instant - duration - else if rhs_ty.is_diag_item(cx, sym::Duration) + else if rhs_name == Some(sym::Duration) && !expr.span.from_expansion() && self.msrv.meets(cx, msrvs::TRY_FROM) { @@ -108,8 +108,8 @@ impl LateLintPass<'_> for UncheckedTimeSubtraction { } } // duration - duration - else if lhs_ty.is_diag_item(cx, sym::Duration) - && rhs_ty.is_diag_item(cx, sym::Duration) + else if lhs_name == Some(sym::Duration) + && rhs_name == Some(sym::Duration) && !expr.span.from_expansion() && self.msrv.meets(cx, msrvs::TRY_FROM) { @@ -144,7 +144,7 @@ fn is_chained_time_subtraction(cx: &LateContext<'_>, lhs: &Expr<'_>) -> bool { /// Returns true if the type is Duration or Instant fn is_time_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - ty.is_diag_item(cx, sym::Duration) || ty.is_diag_item(cx, sym::Instant) + matches!(ty.opt_diag_name(cx), Some(sym::Duration | sym::Instant)) } fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, rhs: &Expr<'_>) { diff --git a/clippy_lints/src/zero_sized_map_values.rs b/clippy_lints/src/zero_sized_map_values.rs index bf133d26ed9d..94c2fb20d5f5 100644 --- a/clippy_lints/src/zero_sized_map_values.rs +++ b/clippy_lints/src/zero_sized_map_values.rs @@ -49,7 +49,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues { && !in_trait_impl(cx, hir_ty.hir_id) // We don't care about infer vars && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty()) - && (ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap)) + && matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) && let ty::Adt(_, args) = ty.kind() && let ty = args.type_at(1) // Ensure that no type information is missing, to avoid a delayed bug in the compiler if this is not the case. diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 7e3fa4f9909b..83b0aebb9e8e 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -809,10 +809,12 @@ impl<'tcx> ConstEvalCtxt<'tcx> { | sym::i128_legacy_const_max ) ) || self.tcx.opt_parent(did).is_some_and(|parent| { - parent.is_diag_item(&self.tcx, sym::f16_consts_mod) - || parent.is_diag_item(&self.tcx, sym::f32_consts_mod) - || parent.is_diag_item(&self.tcx, sym::f64_consts_mod) - || parent.is_diag_item(&self.tcx, sym::f128_consts_mod) + matches!( + parent.opt_diag_name(&self.tcx), + Some( + sym::f16_consts_mod | sym::f32_consts_mod | sym::f64_consts_mod | sym::f128_consts_mod + ) + ) })) => { did diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index 9e7f6e4ee308..db7e263b6269 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -58,6 +58,7 @@ generate! { LowerHex, MAX, MIN, + MaybeDef, MsrvStack, Octal, OpenOptions, @@ -192,6 +193,8 @@ generate! { io, is_ascii, is_char_boundary, + is_diag_item, + is_diagnostic_item, is_digit, is_empty, is_err, @@ -283,6 +286,7 @@ generate! { repeat, replace, replacen, + res, reserve, resize, restriction, From 29659288ffc98b7406c5c16110e8b9a10f541557 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova Date: Wed, 17 Dec 2025 12:16:10 +0100 Subject: [PATCH 0916/3801] feat(repeated_is_diagnostic_item): new internal lint --- clippy_lints_internal/src/internal_paths.rs | 1 + clippy_lints_internal/src/lib.rs | 2 + .../src/repeated_is_diagnostic_item.rs | 561 ++++++++++++++++++ .../repeated_is_diagnostic_item.fixed | 77 +++ .../repeated_is_diagnostic_item.rs | 77 +++ .../repeated_is_diagnostic_item.stderr | 82 +++ .../repeated_is_diagnostic_item_unfixable.rs | 213 +++++++ ...peated_is_diagnostic_item_unfixable.stderr | 374 ++++++++++++ 8 files changed, 1387 insertions(+) create mode 100644 clippy_lints_internal/src/repeated_is_diagnostic_item.rs create mode 100644 tests/ui-internal/repeated_is_diagnostic_item.fixed create mode 100644 tests/ui-internal/repeated_is_diagnostic_item.rs create mode 100644 tests/ui-internal/repeated_is_diagnostic_item.stderr create mode 100644 tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs create mode 100644 tests/ui-internal/repeated_is_diagnostic_item_unfixable.stderr diff --git a/clippy_lints_internal/src/internal_paths.rs b/clippy_lints_internal/src/internal_paths.rs index 95bdf27b019c..14d4139a0065 100644 --- a/clippy_lints_internal/src/internal_paths.rs +++ b/clippy_lints_internal/src/internal_paths.rs @@ -17,6 +17,7 @@ pub static TY_CTXT: PathLookup = type_path!(rustc_middle::ty::TyCtxt); // Paths in clippy itself pub static CLIPPY_SYM_MODULE: PathLookup = type_path!(clippy_utils::sym); +pub static MAYBE_DEF: PathLookup = type_path!(clippy_utils::res::MaybeDef); pub static MSRV_STACK: PathLookup = type_path!(clippy_utils::msrvs::MsrvStack); pub static PATH_LOOKUP_NEW: PathLookup = value_path!(clippy_utils::paths::PathLookup::new); pub static SPAN_LINT_AND_THEN: PathLookup = value_path!(clippy_utils::diagnostics::span_lint_and_then); diff --git a/clippy_lints_internal/src/lib.rs b/clippy_lints_internal/src/lib.rs index d686ba73387c..cca5608fa6be 100644 --- a/clippy_lints_internal/src/lib.rs +++ b/clippy_lints_internal/src/lib.rs @@ -38,6 +38,7 @@ mod lint_without_lint_pass; mod msrv_attr_impl; mod outer_expn_data_pass; mod produce_ice; +mod repeated_is_diagnostic_item; mod symbols; mod unnecessary_def_path; mod unsorted_clippy_utils_paths; @@ -77,4 +78,5 @@ pub fn register_lints(store: &mut LintStore) { store.register_late_pass(|_| Box::new(msrv_attr_impl::MsrvAttrImpl)); store.register_late_pass(|_| Box::new(almost_standard_lint_formulation::AlmostStandardFormulation::new())); store.register_late_pass(|_| Box::new(unusual_names::UnusualNames)); + store.register_late_pass(|_| Box::new(repeated_is_diagnostic_item::RepeatedIsDiagnosticItem)); } diff --git a/clippy_lints_internal/src/repeated_is_diagnostic_item.rs b/clippy_lints_internal/src/repeated_is_diagnostic_item.rs new file mode 100644 index 000000000000..55fb78b1e296 --- /dev/null +++ b/clippy_lints_internal/src/repeated_is_diagnostic_item.rs @@ -0,0 +1,561 @@ +use std::iter; +use std::ops::ControlFlow; + +use crate::internal_paths::MAYBE_DEF; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; +use clippy_utils::source::{snippet_indent, snippet_with_applicability}; +use clippy_utils::visitors::for_each_expr; +use clippy_utils::{eq_expr_value, if_sequence, sym}; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Node, StmtKind, UnOp}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::print::with_forced_trimmed_paths; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::Span; + +declare_tool_lint! { + /// ### What it does + /// Checks for repeated use of `MaybeDef::is_diag_item`/`TyCtxt::is_diagnostic_item`; + /// suggests to first call `MaybDef::opt_diag_name`/`TyCtxt::get_diagnostic_name` and then + /// compare the output with all the `Symbol`s. + /// + /// ### Why is this bad? + /// Each of such calls ultimately invokes the `diagnostic_items` query. + /// While the query is cached, it's still better to avoid calling it multiple times if possible. + /// + /// ### Example + /// ```no_run + /// ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result) + /// cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did) + /// + /// if ty.is_diag_item(cx, sym::Option) { + /// .. + /// } else if ty.is_diag_item(cx, sym::Result) { + /// .. + /// } else { + /// .. + /// } + /// + /// if cx.tcx.is_diagnostic_item(sym::Option, did) { + /// .. + /// } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + /// .. + /// } else { + /// .. + /// } + /// + /// { + /// if ty.is_diag_item(cx, sym::Option) { + /// .. + /// } + /// if ty.is_diag_item(cx, sym::Result) { + /// .. + /// } + /// } + /// + /// { + /// if cx.tcx.is_diagnostic_item(sym::Option, did) { + /// .. + /// } + /// if cx.tcx.is_diagnostic_item(sym::Result, did) { + /// .. + /// } + /// } + /// ``` + /// Use instead: + /// ```no_run + /// matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) + /// matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)) + /// + /// match ty.opt_diag_name(cx) { + /// Some(sym::Option) => { + /// .. + /// } + /// Some(sym::Result) => { + /// .. + /// } + /// _ => { + /// .. + /// } + /// } + /// + /// match cx.tcx.get_diagnostic_name(did) { + /// Some(sym::Option) => { + /// .. + /// } + /// Some(sym::Result) => { + /// .. + /// } + /// _ => { + /// .. + /// } + /// } + /// + /// { + /// let name = ty.opt_diag_name(cx); + /// if name == Some(sym::Option) { + /// .. + /// } + /// if name == Some(sym::Result) { + /// .. + /// } + /// } + /// + /// { + /// let name = cx.tcx.get_diagnostic_name(did); + /// if name == Some(sym::Option) { + /// .. + /// } + /// if name == Some(sym::Result) { + /// .. + /// } + /// } + /// ``` + pub clippy::REPEATED_IS_DIAGNOSTIC_ITEM, + Warn, + "repeated use of `MaybeDef::is_diag_item`/`TyCtxt::is_diagnostic_item`" +} +declare_lint_pass!(RepeatedIsDiagnosticItem => [REPEATED_IS_DIAGNOSTIC_ITEM]); + +const NOTE: &str = "each call performs the same compiler query -- it's faster to query once, and reuse the results"; + +impl<'tcx> LateLintPass<'tcx> for RepeatedIsDiagnosticItem { + #[expect(clippy::too_many_lines)] + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) { + for [(cond1, stmt1_span), (cond2, stmt2_span)] in block + .stmts + .windows(2) + .filter_map(|pair| { + if let [if1, if2] = pair + && let StmtKind::Expr(e1) | StmtKind::Semi(e1) = if1.kind + && let ExprKind::If(cond1, ..) = e1.kind + && let StmtKind::Expr(e2) | StmtKind::Semi(e2) = if2.kind + && let ExprKind::If(cond2, ..) = e2.kind + { + Some([(cond1, if1.span), (cond2, if2.span)]) + } else { + None + } + }) + .chain( + if let Some(if1) = block.stmts.last() + && let StmtKind::Expr(e1) | StmtKind::Semi(e1) = if1.kind + && let ExprKind::If(cond1, ..) = e1.kind + && let Some(e2) = block.expr + && let ExprKind::If(cond2, ..) = e2.kind + { + Some([(cond1, if1.span), (cond2, e2.span)]) + } else { + None + }, + ) + { + let lint_span = stmt1_span.to(stmt2_span); + + // if recv1.is_diag_item(cx, sym1) && .. { + // .. + // } + // if recv2.is_diag_item(cx, sym2) && .. { + // .. + // } + if let Some(first @ (span1, (cx1, recv1, _))) = extract_nested_is_diag_item(cx, cond1) + && let Some(second @ (span2, (cx2, recv2, _))) = extract_nested_is_diag_item(cx, cond2) + && eq_expr_value(cx, cx1, cx2) + && eq_expr_value(cx, recv1, recv2) + { + let recv_ty = + with_forced_trimmed_paths!(format!("{}", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs())); + let recv_ty = recv_ty.trim_end_matches("<'_>"); + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + lint_span, + format!("repeated calls to `{recv_ty}::is_diag_item`"), + |diag| { + diag.span_labels([span1, span2], "called here"); + diag.note(NOTE); + + let mut app = Applicability::HasPlaceholders; + let cx_str = snippet_with_applicability(cx, cx1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, recv1.span, "_", &mut app); + let indent = snippet_indent(cx, stmt1_span).unwrap_or_default(); + let sugg: Vec<_> = iter::once(( + stmt1_span.shrink_to_lo(), + format!("let /* name */ = {recv}.opt_diag_name({cx_str});\n{indent}"), + )) // call `opt_diag_name` once + .chain([first, second].into_iter().map(|(expr_span, (_, _, sym))| { + let sym = snippet_with_applicability(cx, sym.span, "_", &mut app); + (expr_span, format!("/* name */ == Some({sym})")) + })) + .collect(); + + diag.multipart_suggestion_verbose( + format!("call `{recv_ty}::opt_diag_name`, and reuse the results"), + sugg, + app, + ); + }, + ); + return; + } + + // if cx.tcx.is_diagnostic_item(sym1, did) && .. { + // .. + // } + // if cx.tcx.is_diagnostic_item(sym2, did) && .. { + // .. + // } + if let Some(first @ (span1, (tcx1, did1, _))) = extract_nested_is_diagnostic_item(cx, cond1) + && let Some(second @ (span2, (tcx2, did2, _))) = extract_nested_is_diagnostic_item(cx, cond2) + && eq_expr_value(cx, tcx1, tcx2) + && eq_expr_value(cx, did1, did2) + { + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + lint_span, + "repeated calls to `TyCtxt::is_diagnostic_item`", + |diag| { + diag.span_labels([span1, span2], "called here"); + diag.note(NOTE); + + let mut app = Applicability::HasPlaceholders; + let tcx = snippet_with_applicability(cx, tcx1.span, "_", &mut app); + let did = snippet_with_applicability(cx, did1.span, "_", &mut app); + let indent = snippet_indent(cx, stmt1_span).unwrap_or_default(); + let sugg: Vec<_> = iter::once(( + stmt1_span.shrink_to_lo(), + format!("let /* name */ = {tcx}.get_diagnostic_name({did});\n{indent}"), + )) // call `get_diagnostic_name` once + .chain([first, second].into_iter().map(|(expr_span, (_, _, sym))| { + let sym = snippet_with_applicability(cx, sym.span, "_", &mut app); + (expr_span, format!("/* name */ == Some({sym})")) + })) + .collect(); + + diag.multipart_suggestion_verbose( + "call `TyCtxt::get_diagnostic_name`, and reuse the results", + sugg, + app, + ); + }, + ); + } + } + } + + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if let ExprKind::Binary(op, left, right) = expr.kind { + if op.node == BinOpKind::Or { + check_ors(cx, expr.span, left, right); + } else if op.node == BinOpKind::And + && let ExprKind::Unary(UnOp::Not, left) = left.kind + && let ExprKind::Unary(UnOp::Not, right) = right.kind + { + check_ands(cx, expr.span, left, right); + } + } else if let (conds, _) = if_sequence(expr) + && !conds.is_empty() + { + check_if_chains(cx, expr, conds); + } + } +} + +fn check_ors(cx: &LateContext<'_>, span: Span, left: &Expr<'_>, right: &Expr<'_>) { + // recv1.is_diag_item(cx, sym1) || recv2.is_diag_item(cx, sym2) + if let Some((cx1, recv1, sym1)) = extract_is_diag_item(cx, left) + && let Some((cx2, recv2, sym2)) = extract_is_diag_item(cx, right) + && eq_expr_value(cx, cx1, cx2) + && eq_expr_value(cx, recv1, recv2) + { + let recv_ty = + with_forced_trimmed_paths!(format!("{}", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs())); + let recv_ty = recv_ty.trim_end_matches("<'_>"); + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + span, + format!("repeated calls to `{recv_ty}::is_diag_item`"), + |diag| { + diag.note(NOTE); + + let mut app = Applicability::MachineApplicable; + let cx_str = snippet_with_applicability(cx, cx1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, recv1.span, "_", &mut app); + let sym1 = snippet_with_applicability(cx, sym1.span, "_", &mut app); + let sym2 = snippet_with_applicability(cx, sym2.span, "_", &mut app); + diag.span_suggestion_verbose( + span, + format!("call `{recv_ty}::opt_diag_name`, and reuse the results"), + format!("matches!({recv}.opt_diag_name({cx_str}), Some({sym1} | {sym2}))"), + app, + ); + }, + ); + return; + } + + // cx.tcx.is_diagnostic_item(sym1, did) || cx.tcx.is_diagnostic_item(sym2, did) + if let Some((tcx1, did1, sym1)) = extract_is_diagnostic_item(cx, left) + && let Some((tcx2, did2, sym2)) = extract_is_diagnostic_item(cx, right) + && eq_expr_value(cx, tcx1, tcx2) + && eq_expr_value(cx, did1, did2) + { + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + span, + "repeated calls to `TyCtxt::is_diagnostic_item`", + |diag| { + diag.note(NOTE); + + let mut app = Applicability::MachineApplicable; + let tcx = snippet_with_applicability(cx, tcx1.span, "_", &mut app); + let did = snippet_with_applicability(cx, did1.span, "_", &mut app); + let sym1 = snippet_with_applicability(cx, sym1.span, "_", &mut app); + let sym2 = snippet_with_applicability(cx, sym2.span, "_", &mut app); + diag.span_suggestion_verbose( + span, + "call `TyCtxt::get_diagnostic_name`, and reuse the results", + format!("matches!({tcx}.get_diagnostic_name({did}), Some({sym1} | {sym2}))"), + app, + ); + }, + ); + } +} + +fn check_ands(cx: &LateContext<'_>, span: Span, left: &Expr<'_>, right: &Expr<'_>) { + // !recv1.is_diag_item(cx, sym1) && !recv2.is_diag_item(cx, sym2) + if let Some((cx1, recv1, sym1)) = extract_is_diag_item(cx, left) + && let Some((cx2, recv2, sym2)) = extract_is_diag_item(cx, right) + && eq_expr_value(cx, cx1, cx2) + && eq_expr_value(cx, recv1, recv2) + { + let recv_ty = + with_forced_trimmed_paths!(format!("{}", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs())); + let recv_ty = recv_ty.trim_end_matches("<'_>"); + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + span, + format!("repeated calls to `{recv_ty}::is_diag_item`"), + |diag| { + diag.note(NOTE); + + let mut app = Applicability::MachineApplicable; + let cx_str = snippet_with_applicability(cx, cx1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, recv1.span, "_", &mut app); + let sym1 = snippet_with_applicability(cx, sym1.span, "_", &mut app); + let sym2 = snippet_with_applicability(cx, sym2.span, "_", &mut app); + diag.span_suggestion_verbose( + span, + format!("call `{recv_ty}::opt_diag_name`, and reuse the results"), + format!("!matches!({recv}.opt_diag_name({cx_str}), Some({sym1} | {sym2}))"), + app, + ); + }, + ); + return; + } + + // !cx.tcx.is_diagnostic_item(sym1, did) && !cx.tcx.is_diagnostic_item(sym2, did) + if let Some((tcx1, did1, sym1)) = extract_is_diagnostic_item(cx, left) + && let Some((tcx2, did2, sym2)) = extract_is_diagnostic_item(cx, right) + && eq_expr_value(cx, tcx1, tcx2) + && eq_expr_value(cx, did1, did2) + { + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + span, + "repeated calls to `TyCtxt::is_diagnostic_item`", + |diag| { + diag.note(NOTE); + + let mut app = Applicability::MachineApplicable; + let tcx = snippet_with_applicability(cx, tcx1.span, "_", &mut app); + let did = snippet_with_applicability(cx, did1.span, "_", &mut app); + let sym1 = snippet_with_applicability(cx, sym1.span, "_", &mut app); + let sym2 = snippet_with_applicability(cx, sym2.span, "_", &mut app); + diag.span_suggestion_verbose( + span, + "call `TyCtxt::get_diagnostic_name`, and reuse the results", + format!("!matches!({tcx}.get_diagnostic_name({did}), Some({sym1} | {sym2}))"), + app, + ); + }, + ); + } +} + +fn check_if_chains<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, conds: Vec<&'tcx Expr<'_>>) { + // if ty.is_diag_item(cx, sym1) { + // .. + // } else if ty.is_diag_item(cx, sym2) { + // .. + // } else { + // .. + // } + let mut found = conds.iter().filter_map(|cond| extract_nested_is_diag_item(cx, cond)); + if let Some(first @ (_, (cx_1, recv1, _))) = found.next() + && let other = + found.filter(|(_, (cx_, recv, _))| eq_expr_value(cx, cx_, cx_1) && eq_expr_value(cx, recv, recv1)) + && let results = iter::once(first).chain(other).collect::>() + && results.len() > 1 + { + let recv_ty = + with_forced_trimmed_paths!(format!("{}", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs())); + let recv_ty = recv_ty.trim_end_matches("<'_>"); + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + expr.span, + format!("repeated calls to `{recv_ty}::is_diag_item`"), + |diag| { + diag.span_labels(results.iter().map(|(span, _)| *span), "called here"); + diag.note(NOTE); + + let mut app = Applicability::HasPlaceholders; + let cx_str = snippet_with_applicability(cx, cx_1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, recv1.span, "_", &mut app); + let span_before = if let Node::LetStmt(let_stmt) = cx.tcx.parent_hir_node(expr.hir_id) { + let_stmt.span + } else { + expr.span + }; + let indent = snippet_indent(cx, span_before).unwrap_or_default(); + let sugg: Vec<_> = iter::once(( + span_before.shrink_to_lo(), + format!("let /* name */ = {recv}.opt_diag_name({cx_str});\n{indent}"), + )) // call `opt_diag_name` once + .chain(results.into_iter().map(|(expr_span, (_, _, sym))| { + let sym = snippet_with_applicability(cx, sym.span, "_", &mut app); + (expr_span, format!("/* name */ == Some({sym})")) + })) + .collect(); + + diag.multipart_suggestion_verbose( + format!("call `{recv_ty}::opt_diag_name`, and reuse the results"), + sugg, + app, + ); + }, + ); + } + + // if cx.tcx.is_diagnostic_item(sym1, did) { + // .. + // } else if cx.tcx.is_diagnostic_item(sym2, did) { + // .. + // } else { + // .. + // } + let mut found = conds + .into_iter() + .filter_map(|cond| extract_nested_is_diagnostic_item(cx, cond)); + if let Some(first @ (_, (tcx1, did1, _))) = found.next() + && let other = found.filter(|(_, (tcx, did, _))| eq_expr_value(cx, tcx, tcx1) && eq_expr_value(cx, did, did1)) + && let results = iter::once(first).chain(other).collect::>() + && results.len() > 1 + { + span_lint_and_then( + cx, + REPEATED_IS_DIAGNOSTIC_ITEM, + expr.span, + "repeated calls to `TyCtxt::is_diagnostic_item`", + |diag| { + diag.span_labels(results.iter().map(|(span, _)| *span), "called here"); + diag.note(NOTE); + + let mut app = Applicability::HasPlaceholders; + let tcx = snippet_with_applicability(cx, tcx1.span, "_", &mut app); + let recv = snippet_with_applicability(cx, did1.span, "_", &mut app); + let span_before = if let Node::LetStmt(let_stmt) = cx.tcx.parent_hir_node(expr.hir_id) { + let_stmt.span + } else { + expr.span + }; + let indent = snippet_indent(cx, span_before).unwrap_or_default(); + let sugg: Vec<_> = iter::once(( + span_before.shrink_to_lo(), + format!("let /* name */ = {tcx}.get_diagnostic_name({recv});\n{indent}"), + )) // call `get_diagnostic_name` once + .chain(results.into_iter().map(|(expr_span, (_, _, sym))| { + let sym = snippet_with_applicability(cx, sym.span, "_", &mut app); + (expr_span, format!("/* name */ == Some({sym})")) + })) + .collect(); + + diag.multipart_suggestion_verbose( + "call `TyCtxt::get_diagnostic_name`, and reuse the results", + sugg, + app, + ); + }, + ); + } +} + +fn extract_is_diag_item<'tcx>( + cx: &LateContext<'_>, + expr: &'tcx Expr<'tcx>, +) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> { + if let ExprKind::MethodCall(is_diag_item, recv, [cx_, sym], _) = expr.kind + && is_diag_item.ident.name == sym::is_diag_item + // Whether this a method from the `MaybeDef` trait + && let Some(did) = cx.ty_based_def(expr).opt_parent(cx).opt_def_id() + && MAYBE_DEF.matches(cx, did) + { + Some((cx_, recv, sym)) + } else { + None + } +} + +fn extract_is_diagnostic_item<'tcx>( + cx: &LateContext<'_>, + expr: &'tcx Expr<'tcx>, +) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> { + if let ExprKind::MethodCall(is_diag_item, tcx, [sym, did], _) = expr.kind + && is_diag_item.ident.name == sym::is_diagnostic_item + // Whether this is an inherent method on `TyCtxt` + && cx + .ty_based_def(expr) + .opt_parent(cx) + .opt_impl_ty(cx) + .is_diag_item(cx, sym::TyCtxt) + { + Some((tcx, did, sym)) + } else { + None + } +} + +fn extract_nested_is_diag_item<'tcx>( + cx: &LateContext<'tcx>, + cond: &'tcx Expr<'_>, +) -> Option<(Span, (&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>))> { + for_each_expr(cx, cond, |cond_part| { + if let Some(res) = extract_is_diag_item(cx, cond_part) { + ControlFlow::Break((cond_part.span, res)) + } else { + ControlFlow::Continue(()) + } + }) +} + +fn extract_nested_is_diagnostic_item<'tcx>( + cx: &LateContext<'tcx>, + cond: &'tcx Expr<'_>, +) -> Option<(Span, (&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>))> { + for_each_expr(cx, cond, |cond_part| { + if let Some(res) = extract_is_diagnostic_item(cx, cond_part) { + ControlFlow::Break((cond_part.span, res)) + } else { + ControlFlow::Continue(()) + } + }) +} diff --git a/tests/ui-internal/repeated_is_diagnostic_item.fixed b/tests/ui-internal/repeated_is_diagnostic_item.fixed new file mode 100644 index 000000000000..fcacf504804c --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item.fixed @@ -0,0 +1,77 @@ +#![feature(rustc_private)] + +extern crate rustc_hir; +extern crate rustc_lint; +extern crate rustc_middle; +extern crate rustc_span; + +use clippy_utils::res::MaybeDef; +use clippy_utils::sym; +use rustc_hir::def_id::DefId; +use rustc_lint::LateContext; +use rustc_middle::ty::{AdtDef, Ty, TyCtxt}; +use rustc_span::Symbol; + +fn binops(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) { + let did = ty.opt_def_id().unwrap(); + + let _ = matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = !matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + let _ = !matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)); + //~^ repeated_is_diagnostic_item + + // Don't lint: `is_diagnostic_item` is called not on `TyCtxt` + struct FakeTyCtxt; + impl FakeTyCtxt { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool { + unimplemented!() + } + } + let f = FakeTyCtxt; + let _ = f.is_diagnostic_item(sym::Option, did) || f.is_diagnostic_item(sym::Result, did); + + // Don't lint: `is_diagnostic_item` on `TyCtxt` comes from a(n unrelated) trait + trait IsDiagnosticItem { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool; + } + impl IsDiagnosticItem for TyCtxt<'_> { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool { + unimplemented!() + } + } + let _ = IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Option, did) + || IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Result, did); + + // Don't lint: `is_diag_item` is an inherent method + struct DoesntImplMaybeDef; + impl DoesntImplMaybeDef { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool { + unimplemented!() + } + } + let d = DoesntImplMaybeDef; + let _ = d.is_diag_item(cx, sym::Option) || d.is_diag_item(cx, sym::Result); + + // Don't lint: `is_diag_item` comes from a trait other than `MaybeDef` + trait FakeMaybeDef { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool; + } + struct Bar; + impl FakeMaybeDef for Bar { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool { + unimplemented!() + } + } + let b = Bar; + let _ = b.is_diag_item(cx, sym::Option) || b.is_diag_item(cx, sym::Result); +} + +fn main() {} diff --git a/tests/ui-internal/repeated_is_diagnostic_item.rs b/tests/ui-internal/repeated_is_diagnostic_item.rs new file mode 100644 index 000000000000..7ccbbfd94029 --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item.rs @@ -0,0 +1,77 @@ +#![feature(rustc_private)] + +extern crate rustc_hir; +extern crate rustc_lint; +extern crate rustc_middle; +extern crate rustc_span; + +use clippy_utils::res::MaybeDef; +use clippy_utils::sym; +use rustc_hir::def_id::DefId; +use rustc_lint::LateContext; +use rustc_middle::ty::{AdtDef, Ty, TyCtxt}; +use rustc_span::Symbol; + +fn binops(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) { + let did = ty.opt_def_id().unwrap(); + + let _ = ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result); + //~^ repeated_is_diagnostic_item + let _ = !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result); + //~^ repeated_is_diagnostic_item + let _ = adt_def.is_diag_item(cx, sym::Option) || adt_def.is_diag_item(cx, sym::Result); + //~^ repeated_is_diagnostic_item + let _ = !adt_def.is_diag_item(cx, sym::Option) && !adt_def.is_diag_item(cx, sym::Result); + //~^ repeated_is_diagnostic_item + let _ = cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did); + //~^ repeated_is_diagnostic_item + let _ = !cx.tcx.is_diagnostic_item(sym::Option, did) && !cx.tcx.is_diagnostic_item(sym::Result, did); + //~^ repeated_is_diagnostic_item + + // Don't lint: `is_diagnostic_item` is called not on `TyCtxt` + struct FakeTyCtxt; + impl FakeTyCtxt { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool { + unimplemented!() + } + } + let f = FakeTyCtxt; + let _ = f.is_diagnostic_item(sym::Option, did) || f.is_diagnostic_item(sym::Result, did); + + // Don't lint: `is_diagnostic_item` on `TyCtxt` comes from a(n unrelated) trait + trait IsDiagnosticItem { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool; + } + impl IsDiagnosticItem for TyCtxt<'_> { + fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool { + unimplemented!() + } + } + let _ = IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Option, did) + || IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Result, did); + + // Don't lint: `is_diag_item` is an inherent method + struct DoesntImplMaybeDef; + impl DoesntImplMaybeDef { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool { + unimplemented!() + } + } + let d = DoesntImplMaybeDef; + let _ = d.is_diag_item(cx, sym::Option) || d.is_diag_item(cx, sym::Result); + + // Don't lint: `is_diag_item` comes from a trait other than `MaybeDef` + trait FakeMaybeDef { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool; + } + struct Bar; + impl FakeMaybeDef for Bar { + fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool { + unimplemented!() + } + } + let b = Bar; + let _ = b.is_diag_item(cx, sym::Option) || b.is_diag_item(cx, sym::Result); +} + +fn main() {} diff --git a/tests/ui-internal/repeated_is_diagnostic_item.stderr b/tests/ui-internal/repeated_is_diagnostic_item.stderr new file mode 100644 index 000000000000..8c52ba561d79 --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item.stderr @@ -0,0 +1,82 @@ +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:18:13 + | +LL | let _ = ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results + = note: `-D clippy::repeated-is-diagnostic-item` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::repeated_is_diagnostic_item)]` +help: call `Ty::opt_diag_name`, and reuse the results + | +LL - let _ = ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result); +LL + let _ = matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:20:13 + | +LL | let _ = !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL - let _ = !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result); +LL + let _ = !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `AdtDef::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:22:13 + | +LL | let _ = adt_def.is_diag_item(cx, sym::Option) || adt_def.is_diag_item(cx, sym::Result); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `AdtDef::opt_diag_name`, and reuse the results + | +LL - let _ = adt_def.is_diag_item(cx, sym::Option) || adt_def.is_diag_item(cx, sym::Result); +LL + let _ = matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `AdtDef::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:24:13 + | +LL | let _ = !adt_def.is_diag_item(cx, sym::Option) && !adt_def.is_diag_item(cx, sym::Result); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `AdtDef::opt_diag_name`, and reuse the results + | +LL - let _ = !adt_def.is_diag_item(cx, sym::Option) && !adt_def.is_diag_item(cx, sym::Result); +LL + let _ = !matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:26:13 + | +LL | let _ = cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL - let _ = cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did); +LL + let _ = matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)); + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item.rs:28:13 + | +LL | let _ = !cx.tcx.is_diagnostic_item(sym::Option, did) && !cx.tcx.is_diagnostic_item(sym::Result, did); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL - let _ = !cx.tcx.is_diagnostic_item(sym::Option, did) && !cx.tcx.is_diagnostic_item(sym::Result, did); +LL + let _ = !matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result)); + | + +error: aborting due to 6 previous errors + diff --git a/tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs b/tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs new file mode 100644 index 000000000000..807da07ce8aa --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs @@ -0,0 +1,213 @@ +//@no-rustfix +#![feature(rustc_private)] + +extern crate rustc_hir; +extern crate rustc_lint; +extern crate rustc_middle; +extern crate rustc_span; + +use clippy_utils::res::MaybeDef; +use clippy_utils::sym; +use rustc_hir::def_id::DefId; +use rustc_lint::LateContext; +use rustc_middle::ty::{AdtDef, Ty, TyCtxt}; +use rustc_span::Symbol; + +fn main() {} + +// if-chains with repeated calls on the same `ty` +fn if_chains(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) { + let did = ty.opt_def_id().unwrap(); + + let _ = if ty.is_diag_item(cx, sym::Option) { + //~^ repeated_is_diagnostic_item + "Option" + } else if ty.is_diag_item(cx, sym::Result) { + "Result" + } else { + return; + }; + // should ideally suggest the following: + // let _ = match ty.opt_diag_name() { + // Some(sym::Option) => { + // "Option" + // } + // Some(sym::Result) => { + // "Result" + // } + // _ => { + // return; + // } + // }; + + // same but in a stmt + if ty.is_diag_item(cx, sym::Option) { + //~^ repeated_is_diagnostic_item + eprintln!("Option"); + } else if ty.is_diag_item(cx, sym::Result) { + eprintln!("Result"); + } + // should ideally suggest the following: + // match ty.opt_diag_name() { + // Some(sym::Option) => { + // "Option" + // } + // Some(sym::Result) => { + // "Result" + // } + // _ => {} + // }; + + // nested conditions + let _ = if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + //~^ repeated_is_diagnostic_item + "Option" + } else if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + "Result" + } else { + return; + }; + + let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) { + //~^ repeated_is_diagnostic_item + "Option" + } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + "Result" + } else { + return; + }; + // should ideally suggest the following: + // let _ = match cx.get_diagnostic_name(did) { + // Some(sym::Option) => { + // "Option" + // } + // Some(sym::Result) => { + // "Result" + // } + // _ => { + // return; + // } + // }; + + // same but in a stmt + if cx.tcx.is_diagnostic_item(sym::Option, did) { + //~^ repeated_is_diagnostic_item + eprintln!("Option"); + } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + eprintln!("Result"); + } + // should ideally suggest the following: + // match cx.tcx.get_diagnostic_name(did) { + // Some(sym::Option) => { + // "Option" + // } + // Some(sym::Result) => { + // "Result" + // } + // _ => {} + // }; + + // nested conditions + let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + //~^ repeated_is_diagnostic_item + "Option" + } else if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + "Result" + } else { + return; + }; +} + +// if-chains with repeated calls on the same `ty` +fn consecutive_ifs(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) { + let did = ty.opt_def_id().unwrap(); + + { + if ty.is_diag_item(cx, sym::Option) { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if ty.is_diag_item(cx, sym::Result) { + println!("Result"); + } + println!("done!") + } + + // nested conditions + { + if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + println!("Result"); + } + println!("done!") + } + + { + if cx.tcx.is_diagnostic_item(sym::Option, did) { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if cx.tcx.is_diagnostic_item(sym::Result, did) { + println!("Result"); + } + println!("done!") + } + + // nested conditions + { + if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + println!("Result"); + } + println!("done!") + } + + // All the same, but the second if is the final expression + { + if ty.is_diag_item(cx, sym::Option) { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if ty.is_diag_item(cx, sym::Result) { + println!("Result"); + } + } + + // nested conditions + { + if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + println!("Result"); + } + } + + { + if cx.tcx.is_diagnostic_item(sym::Option, did) { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if cx.tcx.is_diagnostic_item(sym::Result, did) { + println!("Result"); + } + } + + // nested conditions + { + if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + //~^ repeated_is_diagnostic_item + println!("Option"); + } + if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + println!("Result"); + } + } +} diff --git a/tests/ui-internal/repeated_is_diagnostic_item_unfixable.stderr b/tests/ui-internal/repeated_is_diagnostic_item_unfixable.stderr new file mode 100644 index 000000000000..890817da5235 --- /dev/null +++ b/tests/ui-internal/repeated_is_diagnostic_item_unfixable.stderr @@ -0,0 +1,374 @@ +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:22:13 + | +LL | let _ = if ty.is_diag_item(cx, sym::Option) { + | ^ -------------------------------- called here + | _____________| + | | +LL | | +LL | | "Option" +LL | | } else if ty.is_diag_item(cx, sym::Result) { + | | -------------------------------- called here +... | +LL | | return; +LL | | }; + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results + = note: `-D clippy::repeated-is-diagnostic-item` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::repeated_is_diagnostic_item)]` +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ let _ = if /* name */ == Some(sym::Option) { +LL | +LL | "Option" +LL ~ } else if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:44:5 + | +LL | if ty.is_diag_item(cx, sym::Option) { + | ^ -------------------------------- called here + | _____| + | | +LL | | +LL | | eprintln!("Option"); +LL | | } else if ty.is_diag_item(cx, sym::Result) { + | | -------------------------------- called here +LL | | eprintln!("Result"); +LL | | } + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | eprintln!("Option"); +LL ~ } else if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:62:13 + | +LL | let _ = if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + | ^ -------------------------------- called here + | _____________| + | | +LL | | +LL | | "Option" +LL | | } else if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + | | -------------------------------- called here +... | +LL | | return; +LL | | }; + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ let _ = if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | "Option" +LL ~ } else if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:71:13 + | +LL | let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) { + | ^ ------------------------------------------- called here + | _____________| + | | +LL | | +LL | | "Option" +LL | | } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + | | ------------------------------------------- called here +... | +LL | | return; +LL | | }; + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ let _ = if /* name */ == Some(sym::Option) { +LL | +LL | "Option" +LL ~ } else if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:93:5 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) { + | ^ ------------------------------------------- called here + | _____| + | | +LL | | +LL | | eprintln!("Option"); +LL | | } else if cx.tcx.is_diagnostic_item(sym::Result, did) { + | | ------------------------------------------- called here +LL | | eprintln!("Result"); +LL | | } + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | eprintln!("Option"); +LL ~ } else if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:111:13 + | +LL | let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + | ^ ------------------------------------------- called here + | _____________| + | | +LL | | +LL | | "Option" +LL | | } else if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + | | ------------------------------------------- called here +... | +LL | | return; +LL | | }; + | |_____^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ let _ = if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | "Option" +LL ~ } else if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:126:9 + | +LL | if ty.is_diag_item(cx, sym::Option) { + | ^ -------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if ty.is_diag_item(cx, sym::Result) { + | | -------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:138:9 + | +LL | if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + | ^ -------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + | | -------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:149:9 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) { + | ^ ------------------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if cx.tcx.is_diagnostic_item(sym::Result, did) { + | | ------------------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:161:9 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + | ^ ------------------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + | | ------------------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:173:9 + | +LL | if ty.is_diag_item(cx, sym::Option) { + | ^ -------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if ty.is_diag_item(cx, sym::Result) { + | | -------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `Ty::is_diag_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:184:9 + | +LL | if ty.is_diag_item(cx, sym::Option) && 4 == 5 { + | ^ -------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if ty.is_diag_item(cx, sym::Result) && 4 == 5 { + | | -------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `Ty::opt_diag_name`, and reuse the results + | +LL ~ let /* name */ = ty.opt_diag_name(cx); +LL ~ if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:194:9 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) { + | ^ ------------------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if cx.tcx.is_diagnostic_item(sym::Result, did) { + | | ------------------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) { + | + +error: repeated calls to `TyCtxt::is_diagnostic_item` + --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:205:9 + | +LL | if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 { + | ^ ------------------------------------------- called here + | _________| + | | +LL | | +LL | | println!("Option"); +LL | | } +LL | | if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 { + | | ------------------------------------------- called here +LL | | println!("Result"); +LL | | } + | |_________^ + | + = note: each call performs the same compiler query -- it's faster to query once, and reuse the results +help: call `TyCtxt::get_diagnostic_name`, and reuse the results + | +LL ~ let /* name */ = cx.tcx.get_diagnostic_name(did); +LL ~ if /* name */ == Some(sym::Option) && 4 == 5 { +LL | +LL | println!("Option"); +LL | } +LL ~ if /* name */ == Some(sym::Result) && 4 == 5 { + | + +error: aborting due to 14 previous errors + From 569206452179abcfdb15fa2f7432cdd7c86af1ad Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 17 Dec 2025 11:54:35 +0100 Subject: [PATCH 0917/3801] Port `#[rustc_never_returns_null_ptr]` to attribute parser --- .../src/attributes/rustc_internal.rs | 15 +++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 6 ++++-- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/ptr_nulls.rs | 7 ++++--- compiler/rustc_passes/src/check_attr.rs | 4 +--- 6 files changed, 28 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index f04d4ceea35a..620878fb87a7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -13,6 +13,21 @@ impl NoArgsAttributeParser for RustcMainParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain; } +pub(crate) struct RustcNeverReturnsNullPointerParser; + +impl NoArgsAttributeParser for RustcNeverReturnsNullPointerParser { + const PATH: &[Symbol] = &[sym::rustc_never_returns_null_ptr]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNeverReturnsNullPointer; +} + pub(crate) struct RustcLayoutScalarValidRangeStartParser; impl SingleAttributeParser for RustcLayoutScalarValidRangeStartParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9e83ea411493..54c9785a42f6 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,8 +61,9 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcMainParser, RustcObjectLifetimeDefaultParser, - RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, + RustcLegacyConstGenericsParser, RustcMainParser, RustcNeverReturnsNullPointerParser, + RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, + RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -255,6 +256,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index fb3d9a6368ab..4a81c4ebe1e7 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -878,6 +878,9 @@ pub enum AttributeKind { /// Represents `#[rustc_main]`. RustcMain, + /// Represents `#[rustc_never_returns_null_ptr]` + RustcNeverReturnsNullPointer, + /// Represents `#[rustc_object_lifetime_default]`. RustcObjectLifetimeDefault, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 56446e8959c1..e631d6a2ab87 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -95,6 +95,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, RustcMain => No, + RustcNeverReturnsNullPointer => Yes, RustcObjectLifetimeDefault => No, RustcPassIndirectlyInNonRusticAbis(..) => No, RustcScalableVector { .. } => Yes, diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs index b2fa0fba76d9..b89e00dcbaae 100644 --- a/compiler/rustc_lint/src/ptr_nulls.rs +++ b/compiler/rustc_lint/src/ptr_nulls.rs @@ -1,5 +1,6 @@ use rustc_ast::LitKind; -use rustc_hir::{BinOpKind, Expr, ExprKind, TyKind}; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{BinOpKind, Expr, ExprKind, TyKind, find_attr}; use rustc_middle::ty::RawPtr; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{Span, sym}; @@ -72,14 +73,14 @@ fn useless_check<'a, 'tcx: 'a>( e = e.peel_blocks(); if let ExprKind::MethodCall(_, _expr, [], _) = e.kind && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) - && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr) + && find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::RustcNeverReturnsNullPointer) && let Some(fn_name) = cx.tcx.opt_item_ident(def_id) { return Some(UselessPtrNullChecksDiag::FnRet { fn_name }); } else if let ExprKind::Call(path, _args) = e.kind && let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() - && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr) + && find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::RustcNeverReturnsNullPointer) && let Some(fn_name) = cx.tcx.opt_item_ident(def_id) { return Some(UselessPtrNullChecksDiag::FnRet { fn_name }); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d8ecbbc49138..d1f96721fc65 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -257,6 +257,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::NoLink | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) + | AttributeKind::RustcNeverReturnsNullPointer | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) | AttributeKind::RustcShouldNotBeCalledOnConstItems(..) @@ -307,9 +308,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_no_implicit_autorefs, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } - [sym::rustc_never_returns_null_ptr, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) - } [sym::rustc_lint_query_instability, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } From dc3786eb3c0b373665939763ddeac1d630f07ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 14 Nov 2025 10:10:06 +0100 Subject: [PATCH 0918/3801] stabilize map_next_if --- library/core/src/iter/adapters/peekable.rs | 7 ++----- library/coretests/tests/lib.rs | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs index ee40d2b74c64..b9bdb827209b 100644 --- a/library/core/src/iter/adapters/peekable.rs +++ b/library/core/src/iter/adapters/peekable.rs @@ -337,7 +337,6 @@ impl Peekable { /// /// Parse the leading decimal number from an iterator of characters. /// ``` - /// #![feature(peekable_next_if_map)] /// let mut iter = "125 GOTO 10".chars().peekable(); /// let mut line_num = 0_u32; /// while let Some(digit) = iter.next_if_map(|c| c.to_digit(10).ok_or(c)) { @@ -349,7 +348,6 @@ impl Peekable { /// /// Matching custom types. /// ``` - /// #![feature(peekable_next_if_map)] /// /// #[derive(Debug, PartialEq, Eq)] /// enum Node { @@ -408,7 +406,7 @@ impl Peekable { ///# ], ///# ) /// ``` - #[unstable(feature = "peekable_next_if_map", issue = "143702")] + #[stable(feature = "peekable_next_if_map", since = "CURRENT_RUSTC_VERSION")] pub fn next_if_map(&mut self, f: impl FnOnce(I::Item) -> Result) -> Option { let unpeek = if let Some(item) = self.next() { match f(item) { @@ -437,7 +435,6 @@ impl Peekable { /// /// Parse the leading decimal number from an iterator of characters. /// ``` - /// #![feature(peekable_next_if_map)] /// let mut iter = "125 GOTO 10".chars().peekable(); /// let mut line_num = 0_u32; /// while let Some(digit) = iter.next_if_map_mut(|c| c.to_digit(10)) { @@ -446,7 +443,7 @@ impl Peekable { /// assert_eq!(line_num, 125); /// assert_eq!(iter.collect::(), " GOTO 10"); /// ``` - #[unstable(feature = "peekable_next_if_map", issue = "143702")] + #[stable(feature = "peekable_next_if_map", since = "CURRENT_RUSTC_VERSION")] pub fn next_if_map_mut(&mut self, f: impl FnOnce(&mut I::Item) -> Option) -> Option { let unpeek = if let Some(mut item) = self.next() { match f(&mut item) { diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 0387b442562d..222e5dd32c86 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -91,7 +91,6 @@ #![feature(one_sided_range)] #![feature(option_reduce)] #![feature(pattern)] -#![feature(peekable_next_if_map)] #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] #![feature(ptr_metadata)] From 4f57d5be5a021da14dc4efb65ed62fd8870428f8 Mon Sep 17 00:00:00 2001 From: Michael Gruenewald Date: Wed, 17 Dec 2025 14:20:43 +0100 Subject: [PATCH 0919/3801] Fix LSP configuration request handling --- .../rust-analyzer/editors/code/src/client.ts | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts index cb71a01138b3..5b358e3211fb 100644 --- a/src/tools/rust-analyzer/editors/code/src/client.ts +++ b/src/tools/rust-analyzer/editors/code/src/client.ts @@ -30,17 +30,24 @@ export async function createClient( }, async configuration( params: lc.ConfigurationParams, - token: vscode.CancellationToken, - next: lc.ConfigurationRequest.HandlerSignature, + _token: vscode.CancellationToken, + _next: lc.ConfigurationRequest.HandlerSignature, ) { - const resp = await next(params, token); - if (resp && Array.isArray(resp)) { - return resp.map((val) => { - return prepareVSCodeConfig(val); - }); - } else { - return resp; + // The rust-analyzer LSP only ever asks for the "rust-analyzer" + // section, so we only need to support that. Instead of letting + // the vscode-languageclient handle it, use the `cfg` property + // in the config. + if ( + params.items.length !== 1 || + params.items[0]?.section !== "rust-analyzer" || + params.items[0]?.scopeUri !== undefined + ) { + return new lc.ResponseError( + lc.ErrorCodes.InvalidParams, + 'Only the "rust-analyzer" config section is supported.', + ); } + return [prepareVSCodeConfig(config.cfg)]; }, }, async handleDiagnostics( From cb301751b3ade3cf65f1d3eeb0c94ffce1a45561 Mon Sep 17 00:00:00 2001 From: delta17920 Date: Sat, 13 Dec 2025 15:18:34 +0000 Subject: [PATCH 0920/3801] Suggest struct pattern when destructuring Range with .. syntax --- .../rustc_resolve/src/late/diagnostics.rs | 36 ++++++++++ .../suggest-range-struct-destructuring.rs | 15 +++++ .../suggest-range-struct-destructuring.stderr | 66 +++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 tests/ui/resolve/suggest-range-struct-destructuring.rs create mode 100644 tests/ui/resolve/suggest-range-struct-destructuring.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 233a4c48862a..0348764009b2 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -440,6 +440,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg); self.suggest_at_operator_in_slice_pat_with_range(&mut err, path); + self.suggest_range_struct_destructuring(&mut err, path, source); self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); if let Some((span, label)) = base_error.span_label { @@ -1383,6 +1384,41 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } + fn suggest_range_struct_destructuring( + &self, + err: &mut Diag<'_>, + path: &[Segment], + source: PathSource<'_, '_, '_>, + ) { + // We accept Expr here because range bounds (start..end) are parsed as expressions + if !matches!(source, PathSource::Pat | PathSource::TupleStruct(..) | PathSource::Expr(..)) { + return; + } + + if let Some(pat) = self.diag_metadata.current_pat + && let ast::PatKind::Range(Some(start_expr), Some(end_expr), _) = &pat.kind + && let (ast::ExprKind::Path(None, start_path), ast::ExprKind::Path(None, end_path)) = + (&start_expr.kind, &end_expr.kind) + && path.len() == 1 + { + let ident = path[0].ident; + + if (start_path.segments.len() == 1 && start_path.segments[0].ident == ident) + || (end_path.segments.len() == 1 && end_path.segments[0].ident == ident) + { + let start_name = start_path.segments[0].ident; + let end_name = end_path.segments[0].ident; + + err.span_suggestion_verbose( + pat.span, + "if you meant to destructure a `Range`, use the struct pattern", + format!("std::ops::Range {{ start: {}, end: {} }}", start_name, end_name), + Applicability::MaybeIncorrect, + ); + } + } + } + fn suggest_swapping_misplaced_self_ty_and_trait( &mut self, err: &mut Diag<'_>, diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.rs b/tests/ui/resolve/suggest-range-struct-destructuring.rs new file mode 100644 index 000000000000..f690a7cad23f --- /dev/null +++ b/tests/ui/resolve/suggest-range-struct-destructuring.rs @@ -0,0 +1,15 @@ +use std::ops::Range; + +fn test_basic_range(r: Range) { + let start..end = r; + //~^ ERROR cannot find value `start` in this scope + //~| ERROR cannot find value `end` in this scope +} + +fn test_different_names(r: Range) { + let min..max = r; + //~^ ERROR cannot find value `min` in this scope + //~| ERROR cannot find value `max` in this scope +} + +fn main() {} diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.stderr b/tests/ui/resolve/suggest-range-struct-destructuring.stderr new file mode 100644 index 000000000000..291abf0d01d3 --- /dev/null +++ b/tests/ui/resolve/suggest-range-struct-destructuring.stderr @@ -0,0 +1,66 @@ +error[E0425]: cannot find value `start` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:4:9 + | +LL | let start..end = r; + | ^^^^^ not found in this scope + | +help: if you meant to destructure a `Range`, use the struct pattern + | +LL - let start..end = r; +LL + let std::ops::Range { start: start, end: end } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:4:16 + | +LL | let start..end = r; + | ^^^ not found in this scope + | +help: if you meant to destructure a `Range`, use the struct pattern + | +LL - let start..end = r; +LL + let std::ops::Range { start: start, end: end } = r; + | + +error[E0425]: cannot find value `min` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:10:9 + | +LL | let min..max = r; + | ^^^ +... +LL | fn main() {} + | --------- similarly named function `main` defined here + | +help: if you meant to destructure a `Range`, use the struct pattern + | +LL - let min..max = r; +LL + let std::ops::Range { start: min, end: max } = r; + | +help: a function with a similar name exists + | +LL | let main..max = r; + | + +help: consider importing this function + | +LL + use std::cmp::min; + | + +error[E0425]: cannot find value `max` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:10:14 + | +LL | let min..max = r; + | ^^^ not found in this scope + | +help: if you meant to destructure a `Range`, use the struct pattern + | +LL - let min..max = r; +LL + let std::ops::Range { start: min, end: max } = r; + | +help: consider importing this function + | +LL + use std::cmp::max; + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0425`. From 3e78653ec32342708b70268e179dfcaad02f4d4e Mon Sep 17 00:00:00 2001 From: delta17920 Date: Sun, 14 Dec 2025 04:04:53 +0000 Subject: [PATCH 0921/3801] Fix grammar in suggestion message --- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- .../ui/resolve/suggest-range-struct-destructuring.stderr | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0348764009b2..85e8917ae32e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1411,7 +1411,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.span_suggestion_verbose( pat.span, - "if you meant to destructure a `Range`, use the struct pattern", + "if you meant to destructure a `Range`, use a struct pattern", format!("std::ops::Range {{ start: {}, end: {} }}", start_name, end_name), Applicability::MaybeIncorrect, ); diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.stderr b/tests/ui/resolve/suggest-range-struct-destructuring.stderr index 291abf0d01d3..1a11e6ac8421 100644 --- a/tests/ui/resolve/suggest-range-struct-destructuring.stderr +++ b/tests/ui/resolve/suggest-range-struct-destructuring.stderr @@ -4,7 +4,7 @@ error[E0425]: cannot find value `start` in this scope LL | let start..end = r; | ^^^^^ not found in this scope | -help: if you meant to destructure a `Range`, use the struct pattern +help: if you meant to destructure a `Range`, use a struct pattern | LL - let start..end = r; LL + let std::ops::Range { start: start, end: end } = r; @@ -16,7 +16,7 @@ error[E0425]: cannot find value `end` in this scope LL | let start..end = r; | ^^^ not found in this scope | -help: if you meant to destructure a `Range`, use the struct pattern +help: if you meant to destructure a `Range`, use a struct pattern | LL - let start..end = r; LL + let std::ops::Range { start: start, end: end } = r; @@ -31,7 +31,7 @@ LL | let min..max = r; LL | fn main() {} | --------- similarly named function `main` defined here | -help: if you meant to destructure a `Range`, use the struct pattern +help: if you meant to destructure a `Range`, use a struct pattern | LL - let min..max = r; LL + let std::ops::Range { start: min, end: max } = r; @@ -51,7 +51,7 @@ error[E0425]: cannot find value `max` in this scope LL | let min..max = r; | ^^^ not found in this scope | -help: if you meant to destructure a `Range`, use the struct pattern +help: if you meant to destructure a `Range`, use a struct pattern | LL - let min..max = r; LL + let std::ops::Range { start: min, end: max } = r; From 4b07875505bdd5c4b635fbf821401fcd4573dffd Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 17 Dec 2025 14:33:52 +0000 Subject: [PATCH 0922/3801] Revert #148937 (Remove initialized-bytes tracking from `BorrowedBuf` and `BorrowedCursor`) This caused several performance regressions because of existing code which uses `Read::read` and therefore requires full buffer initialization. This is particularly a problem when the same buffer is re-used for multiple read calls since this means it needs to be fully re-initialized each time. There is still some benefit to landing the API changes, but we will have to add private APIs so that the existing infrastructure can track and avoid redundant initialization. --- library/core/src/io/borrowed_buf.rs | 162 +++++++++++++++--- library/coretests/tests/io/borrowed_buf.rs | 90 ++++++++-- library/std/src/fs/tests.rs | 2 + library/std/src/io/buffered/bufreader.rs | 9 + .../std/src/io/buffered/bufreader/buffer.rs | 27 ++- library/std/src/io/buffered/tests.rs | 24 +++ library/std/src/io/copy.rs | 13 ++ library/std/src/io/mod.rs | 53 +++++- library/std/src/io/tests.rs | 9 + library/std/src/io/util.rs | 2 +- library/std/src/io/util/tests.rs | 8 + library/std/src/net/tcp/tests.rs | 2 + library/std/src/process/tests.rs | 2 + library/std/src/sys/fd/hermit.rs | 2 +- library/std/src/sys/fd/unix.rs | 4 +- library/std/src/sys/fs/solid.rs | 2 +- .../src/sys/net/connection/socket/hermit.rs | 2 +- .../src/sys/net/connection/socket/solid.rs | 2 +- .../std/src/sys/net/connection/socket/unix.rs | 2 +- .../src/sys/net/connection/socket/windows.rs | 2 +- .../std/src/sys/pal/sgx/abi/usercalls/mod.rs | 2 +- library/std/src/sys/pal/windows/handle.rs | 4 +- .../std/src/sys/process/windows/child_pipe.rs | 2 +- library/std/src/sys/stdio/zkvm.rs | 2 +- 24 files changed, 366 insertions(+), 63 deletions(-) diff --git a/library/core/src/io/borrowed_buf.rs b/library/core/src/io/borrowed_buf.rs index b765b96fd00a..088dea781294 100644 --- a/library/core/src/io/borrowed_buf.rs +++ b/library/core/src/io/borrowed_buf.rs @@ -2,26 +2,27 @@ use crate::fmt::{self, Debug, Formatter}; use crate::mem::{self, MaybeUninit}; +use crate::{cmp, ptr}; -/// A borrowed buffer of initially uninitialized bytes, which is incrementally filled. +/// A borrowed byte buffer which is incrementally filled and initialized. /// -/// This type makes it safer to work with `MaybeUninit` buffers, such as to read into a buffer -/// without having to initialize it first. It tracks the region of bytes that have been filled and -/// the region that remains uninitialized. +/// This type is a sort of "double cursor". It tracks three regions in the buffer: a region at the beginning of the +/// buffer that has been logically filled with data, a region that has been initialized at some point but not yet +/// logically filled, and a region at the end that is fully uninitialized. The filled region is guaranteed to be a +/// subset of the initialized region. /// -/// The contents of the buffer can be visualized as: +/// In summary, the contents of the buffer can be visualized as: /// ```not_rust -/// [ capacity ] -/// [ len: filled and initialized | capacity - len: uninitialized ] +/// [ capacity ] +/// [ filled | unfilled ] +/// [ initialized | uninitialized ] /// ``` /// -/// Note that `BorrowedBuf` does not distinguish between uninitialized data and data that was -/// previously initialized but no longer contains valid data. -/// -/// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique -/// reference (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_len`), but -/// cannot be directly written. To write into the buffer, use `unfilled` to create a -/// `BorrowedCursor`. The cursor has write-only access to the unfilled portion of the buffer. +/// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique reference +/// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but cannot be +/// directly written. To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor +/// has write-only access to the unfilled portion of the buffer (you can think of it as a +/// write-only iterator). /// /// The lifetime `'data` is a bound on the lifetime of the underlying data. pub struct BorrowedBuf<'data> { @@ -29,11 +30,14 @@ pub struct BorrowedBuf<'data> { buf: &'data mut [MaybeUninit], /// The length of `self.buf` which is known to be filled. filled: usize, + /// The length of `self.buf` which is known to be initialized. + init: usize, } impl Debug for BorrowedBuf<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("BorrowedBuf") + .field("init", &self.init) .field("filled", &self.filled) .field("capacity", &self.capacity()) .finish() @@ -44,22 +48,24 @@ impl Debug for BorrowedBuf<'_> { impl<'data> From<&'data mut [u8]> for BorrowedBuf<'data> { #[inline] fn from(slice: &'data mut [u8]) -> BorrowedBuf<'data> { + let len = slice.len(); + BorrowedBuf { - // SAFETY: Always in bounds. We treat the buffer as uninitialized, even though it's - // already initialized. + // SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf buf: unsafe { (slice as *mut [u8]).as_uninit_slice_mut().unwrap() }, filled: 0, + init: len, } } } /// Creates a new `BorrowedBuf` from an uninitialized buffer. /// -/// Use `set_filled` if part of the buffer is known to be already filled. +/// Use `set_init` if part of the buffer is known to be already initialized. impl<'data> From<&'data mut [MaybeUninit]> for BorrowedBuf<'data> { #[inline] fn from(buf: &'data mut [MaybeUninit]) -> BorrowedBuf<'data> { - BorrowedBuf { buf, filled: 0 } + BorrowedBuf { buf, filled: 0, init: 0 } } } @@ -68,11 +74,14 @@ impl<'data> From<&'data mut [MaybeUninit]> for BorrowedBuf<'data> { /// Use `BorrowedCursor::with_unfilled_buf` instead for a safer alternative. impl<'data> From> for BorrowedBuf<'data> { #[inline] - fn from(buf: BorrowedCursor<'data>) -> BorrowedBuf<'data> { + fn from(mut buf: BorrowedCursor<'data>) -> BorrowedBuf<'data> { + let init = buf.init_mut().len(); BorrowedBuf { - // SAFETY: Always in bounds. We treat the buffer as uninitialized. + // SAFETY: no initialized byte is ever uninitialized as per + // `BorrowedBuf`'s invariant buf: unsafe { buf.buf.buf.get_unchecked_mut(buf.buf.filled..) }, filled: 0, + init, } } } @@ -90,6 +99,12 @@ impl<'data> BorrowedBuf<'data> { self.filled } + /// Returns the length of the initialized part of the buffer. + #[inline] + pub fn init_len(&self) -> usize { + self.init + } + /// Returns a shared reference to the filled portion of the buffer. #[inline] pub fn filled(&self) -> &[u8] { @@ -144,16 +159,33 @@ impl<'data> BorrowedBuf<'data> { /// Clears the buffer, resetting the filled region to empty. /// - /// The contents of the buffer are not modified. + /// The number of initialized bytes is not changed, and the contents of the buffer are not modified. #[inline] pub fn clear(&mut self) -> &mut Self { self.filled = 0; self } + + /// Asserts that the first `n` bytes of the buffer are initialized. + /// + /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer + /// bytes than are already known to be initialized. + /// + /// # Safety + /// + /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized. + #[inline] + pub unsafe fn set_init(&mut self, n: usize) -> &mut Self { + self.init = cmp::max(self.init, n); + self + } } /// A writeable view of the unfilled portion of a [`BorrowedBuf`]. /// +/// The unfilled portion consists of an initialized and an uninitialized part; see [`BorrowedBuf`] +/// for details. +/// /// Data can be written directly to the cursor by using [`append`](BorrowedCursor::append) or /// indirectly by getting a slice of part or all of the cursor and writing into the slice. In the /// indirect case, the caller must call [`advance`](BorrowedCursor::advance) after writing to inform @@ -206,17 +238,48 @@ impl<'a> BorrowedCursor<'a> { self.buf.filled } + /// Returns a mutable reference to the initialized portion of the cursor. + #[inline] + pub fn init_mut(&mut self) -> &mut [u8] { + // SAFETY: We only slice the initialized part of the buffer, which is always valid + unsafe { + let buf = self.buf.buf.get_unchecked_mut(self.buf.filled..self.buf.init); + buf.assume_init_mut() + } + } + /// Returns a mutable reference to the whole cursor. /// /// # Safety /// - /// The caller must not uninitialize any previously initialized bytes. + /// The caller must not uninitialize any bytes in the initialized portion of the cursor. #[inline] pub unsafe fn as_mut(&mut self) -> &mut [MaybeUninit] { // SAFETY: always in bounds unsafe { self.buf.buf.get_unchecked_mut(self.buf.filled..) } } + /// Advances the cursor by asserting that `n` bytes have been filled. + /// + /// After advancing, the `n` bytes are no longer accessible via the cursor and can only be + /// accessed via the underlying buffer. I.e., the buffer's filled portion grows by `n` elements + /// and its unfilled portion (and the capacity of this cursor) shrinks by `n` elements. + /// + /// If less than `n` bytes initialized (by the cursor's point of view), `set_init` should be + /// called first. + /// + /// # Panics + /// + /// Panics if there are less than `n` bytes initialized. + #[inline] + pub fn advance(&mut self, n: usize) -> &mut Self { + // The subtraction cannot underflow by invariant of this type. + assert!(n <= self.buf.init - self.buf.filled); + + self.buf.filled += n; + self + } + /// Advances the cursor by asserting that `n` bytes have been filled. /// /// After advancing, the `n` bytes are no longer accessible via the cursor and can only be @@ -225,11 +288,42 @@ impl<'a> BorrowedCursor<'a> { /// /// # Safety /// - /// The caller must ensure that the first `n` bytes of the cursor have been initialized. `n` - /// must not exceed the remaining capacity of this cursor. + /// The caller must ensure that the first `n` bytes of the cursor have been properly + /// initialised. #[inline] - pub unsafe fn advance(&mut self, n: usize) -> &mut Self { + pub unsafe fn advance_unchecked(&mut self, n: usize) -> &mut Self { self.buf.filled += n; + self.buf.init = cmp::max(self.buf.init, self.buf.filled); + self + } + + /// Initializes all bytes in the cursor. + #[inline] + pub fn ensure_init(&mut self) -> &mut Self { + // SAFETY: always in bounds and we never uninitialize these bytes. + let uninit = unsafe { self.buf.buf.get_unchecked_mut(self.buf.init..) }; + + // SAFETY: 0 is a valid value for MaybeUninit and the length matches the allocation + // since it is comes from a slice reference. + unsafe { + ptr::write_bytes(uninit.as_mut_ptr(), 0, uninit.len()); + } + self.buf.init = self.buf.capacity(); + + self + } + + /// Asserts that the first `n` unfilled bytes of the cursor are initialized. + /// + /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when + /// called with fewer bytes than are already known to be initialized. + /// + /// # Safety + /// + /// The caller must ensure that the first `n` bytes of the buffer have already been initialized. + #[inline] + pub unsafe fn set_init(&mut self, n: usize) -> &mut Self { + self.buf.init = cmp::max(self.buf.init, self.buf.filled + n); self } @@ -247,6 +341,10 @@ impl<'a> BorrowedCursor<'a> { self.as_mut()[..buf.len()].write_copy_of_slice(buf); } + // SAFETY: We just added the entire contents of buf to the filled section. + unsafe { + self.set_init(buf.len()); + } self.buf.filled += buf.len(); } @@ -269,9 +367,17 @@ impl<'a> BorrowedCursor<'a> { // there, one could mark some bytes as initialized even though there aren't. assert!(core::ptr::addr_eq(prev_ptr, buf.buf)); - // SAFETY: These bytes were filled in the `BorrowedBuf`, so they're filled in the cursor - // too, because the buffer wasn't replaced. - self.buf.filled += buf.filled; + let filled = buf.filled; + let init = buf.init; + + // Update `init` and `filled` fields with what was written to the buffer. + // `self.buf.filled` was the starting length of the `BorrowedBuf`. + // + // SAFETY: These amounts of bytes were initialized/filled in the `BorrowedBuf`, + // and therefore they are initialized/filled in the cursor too, because the + // buffer wasn't replaced. + self.buf.init = self.buf.filled + init; + self.buf.filled += filled; res } diff --git a/library/coretests/tests/io/borrowed_buf.rs b/library/coretests/tests/io/borrowed_buf.rs index 730ba04465a1..aaa98d26ff8b 100644 --- a/library/coretests/tests/io/borrowed_buf.rs +++ b/library/coretests/tests/io/borrowed_buf.rs @@ -8,6 +8,7 @@ fn new() { let mut rbuf: BorrowedBuf<'_> = buf.into(); assert_eq!(rbuf.filled().len(), 0); + assert_eq!(rbuf.init_len(), 16); assert_eq!(rbuf.capacity(), 16); assert_eq!(rbuf.unfilled().capacity(), 16); } @@ -19,16 +20,27 @@ fn uninit() { let mut rbuf: BorrowedBuf<'_> = buf.into(); assert_eq!(rbuf.filled().len(), 0); + assert_eq!(rbuf.init_len(), 0); assert_eq!(rbuf.capacity(), 16); assert_eq!(rbuf.unfilled().capacity(), 16); } +#[test] +fn initialize_unfilled() { + let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16]; + let mut rbuf: BorrowedBuf<'_> = buf.into(); + + rbuf.unfilled().ensure_init(); + + assert_eq!(rbuf.init_len(), 16); +} + #[test] fn advance_filled() { let buf: &mut [_] = &mut [0; 16]; let mut rbuf: BorrowedBuf<'_> = buf.into(); - unsafe { rbuf.unfilled().advance(1) }; + rbuf.unfilled().advance(1); assert_eq!(rbuf.filled().len(), 1); assert_eq!(rbuf.unfilled().capacity(), 15); @@ -39,7 +51,7 @@ fn clear() { let buf: &mut [_] = &mut [255; 16]; let mut rbuf: BorrowedBuf<'_> = buf.into(); - unsafe { rbuf.unfilled().advance(16) }; + rbuf.unfilled().advance(16); assert_eq!(rbuf.filled().len(), 16); assert_eq!(rbuf.unfilled().capacity(), 0); @@ -49,9 +61,33 @@ fn clear() { assert_eq!(rbuf.filled().len(), 0); assert_eq!(rbuf.unfilled().capacity(), 16); - unsafe { rbuf.unfilled().advance(16) }; + assert_eq!(rbuf.unfilled().init_mut(), [255; 16]); +} - assert_eq!(rbuf.filled(), [255; 16]); +#[test] +fn set_init() { + let buf: &mut [_] = &mut [MaybeUninit::zeroed(); 16]; + let mut rbuf: BorrowedBuf<'_> = buf.into(); + + unsafe { + rbuf.set_init(8); + } + + assert_eq!(rbuf.init_len(), 8); + + rbuf.unfilled().advance(4); + + unsafe { + rbuf.set_init(2); + } + + assert_eq!(rbuf.init_len(), 8); + + unsafe { + rbuf.set_init(8); + } + + assert_eq!(rbuf.init_len(), 8); } #[test] @@ -61,6 +97,7 @@ fn append() { rbuf.unfilled().append(&[0; 8]); + assert_eq!(rbuf.init_len(), 8); assert_eq!(rbuf.filled().len(), 8); assert_eq!(rbuf.filled(), [0; 8]); @@ -68,6 +105,7 @@ fn append() { rbuf.unfilled().append(&[1; 16]); + assert_eq!(rbuf.init_len(), 16); assert_eq!(rbuf.filled().len(), 16); assert_eq!(rbuf.filled(), [1; 16]); } @@ -87,12 +125,43 @@ fn reborrow_written() { assert_eq!(cursor.written(), 32); assert_eq!(buf.unfilled().written(), 32); + assert_eq!(buf.init_len(), 32); assert_eq!(buf.filled().len(), 32); let filled = buf.filled(); assert_eq!(&filled[..16], [1; 16]); assert_eq!(&filled[16..], [2; 16]); } +#[test] +fn cursor_set_init() { + let buf: &mut [_] = &mut [MaybeUninit::zeroed(); 16]; + let mut rbuf: BorrowedBuf<'_> = buf.into(); + + unsafe { + rbuf.unfilled().set_init(8); + } + + assert_eq!(rbuf.init_len(), 8); + assert_eq!(rbuf.unfilled().init_mut().len(), 8); + assert_eq!(unsafe { rbuf.unfilled().as_mut().len() }, 16); + + rbuf.unfilled().advance(4); + + unsafe { + rbuf.unfilled().set_init(2); + } + + assert_eq!(rbuf.init_len(), 8); + + unsafe { + rbuf.unfilled().set_init(8); + } + + assert_eq!(rbuf.init_len(), 12); + assert_eq!(rbuf.unfilled().init_mut().len(), 8); + assert_eq!(unsafe { rbuf.unfilled().as_mut().len() }, 12); +} + #[test] fn cursor_with_unfilled_buf() { let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16]; @@ -100,30 +169,31 @@ fn cursor_with_unfilled_buf() { let mut cursor = rbuf.unfilled(); cursor.with_unfilled_buf(|buf| { - assert_eq!(buf.capacity(), 16); buf.unfilled().append(&[1, 2, 3]); assert_eq!(buf.filled(), &[1, 2, 3]); }); + assert_eq!(cursor.init_mut().len(), 0); assert_eq!(cursor.written(), 3); cursor.with_unfilled_buf(|buf| { assert_eq!(buf.capacity(), 13); + assert_eq!(buf.init_len(), 0); - unsafe { - buf.unfilled().as_mut().write_filled(0); - buf.unfilled().advance(4) - }; + buf.unfilled().ensure_init(); + buf.unfilled().advance(4); }); + assert_eq!(cursor.init_mut().len(), 9); assert_eq!(cursor.written(), 7); cursor.with_unfilled_buf(|buf| { assert_eq!(buf.capacity(), 9); + assert_eq!(buf.init_len(), 9); }); + assert_eq!(cursor.init_mut().len(), 9); assert_eq!(cursor.written(), 7); - assert_eq!(rbuf.len(), 7); assert_eq!(rbuf.filled(), &[1, 2, 3, 0, 0, 0, 0]); } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index bcaafcfee787..0a5d1153d860 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -709,6 +709,8 @@ fn file_test_read_buf() { let mut file = check!(File::open(filename)); check!(file.read_buf(buf.unfilled())); assert_eq!(buf.filled(), &[1, 2, 3, 4]); + // File::read_buf should omit buffer initialization. + assert_eq!(buf.init_len(), 4); check!(fs::remove_file(filename)); } diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 69c260b5410a..40441dc057d0 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -284,6 +284,15 @@ impl BufReader { } } +// This is only used by a test which asserts that the initialization-tracking is correct. +#[cfg(test)] +impl BufReader { + #[allow(missing_docs)] + pub fn initialized(&self) -> usize { + self.buf.initialized() + } +} + impl BufReader { /// Seeks relative to the current position. If the new position lies within the buffer, /// the buffer will not be flushed, allowing for more efficient seeks. diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 2694726b3f44..9b600cd55758 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -21,19 +21,25 @@ pub struct Buffer { // Each call to `fill_buf` sets `filled` to indicate how many bytes at the start of `buf` are // initialized with bytes from a read. filled: usize, + // This is the max number of bytes returned across all `fill_buf` calls. We track this so that we + // can accurately tell `read_buf` how many bytes of buf are initialized, to bypass as much of its + // defensive initialization as possible. Note that while this often the same as `filled`, it + // doesn't need to be. Calls to `fill_buf` are not required to actually fill the buffer, and + // omitting this is a huge perf regression for `Read` impls that do not. + initialized: usize, } impl Buffer { #[inline] pub fn with_capacity(capacity: usize) -> Self { let buf = Box::new_uninit_slice(capacity); - Self { buf, pos: 0, filled: 0 } + Self { buf, pos: 0, filled: 0, initialized: 0 } } #[inline] pub fn try_with_capacity(capacity: usize) -> io::Result { match Box::try_new_uninit_slice(capacity) { - Ok(buf) => Ok(Self { buf, pos: 0, filled: 0 }), + Ok(buf) => Ok(Self { buf, pos: 0, filled: 0, initialized: 0 }), Err(_) => { Err(io::const_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer")) } @@ -62,6 +68,12 @@ impl Buffer { self.pos } + // This is only used by a test which asserts that the initialization-tracking is correct. + #[cfg(test)] + pub fn initialized(&self) -> usize { + self.initialized + } + #[inline] pub fn discard_buffer(&mut self) { self.pos = 0; @@ -98,8 +110,13 @@ impl Buffer { /// Read more bytes into the buffer without discarding any of its contents pub fn read_more(&mut self, mut reader: impl Read) -> io::Result { let mut buf = BorrowedBuf::from(&mut self.buf[self.filled..]); + let old_init = self.initialized - self.filled; + unsafe { + buf.set_init(old_init); + } reader.read_buf(buf.unfilled())?; self.filled += buf.len(); + self.initialized += buf.init_len() - old_init; Ok(buf.len()) } @@ -120,10 +137,16 @@ impl Buffer { debug_assert!(self.pos == self.filled); let mut buf = BorrowedBuf::from(&mut *self.buf); + // SAFETY: `self.filled` bytes will always have been initialized. + unsafe { + buf.set_init(self.initialized); + } + let result = reader.read_buf(buf.unfilled()); self.pos = 0; self.filled = buf.len(); + self.initialized = buf.init_len(); result?; } diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs index fc77b02a8e82..6ad4158b9290 100644 --- a/library/std/src/io/buffered/tests.rs +++ b/library/std/src/io/buffered/tests.rs @@ -1052,6 +1052,30 @@ fn single_formatted_write() { assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]); } +#[test] +fn bufreader_full_initialize() { + struct OneByteReader; + impl Read for OneByteReader { + fn read(&mut self, buf: &mut [u8]) -> crate::io::Result { + if buf.len() > 0 { + buf[0] = 0; + Ok(1) + } else { + Ok(0) + } + } + } + let mut reader = BufReader::new(OneByteReader); + // Nothing is initialized yet. + assert_eq!(reader.initialized(), 0); + + let buf = reader.fill_buf().unwrap(); + // We read one byte... + assert_eq!(buf.len(), 1); + // But we initialized the whole buffer! + assert_eq!(reader.initialized(), reader.capacity()); +} + /// This is a regression test for https://github.com/rust-lang/rust/issues/127584. #[test] fn bufwriter_aliasing() { diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs index 8b5e7c4df4e0..2b558efb8885 100644 --- a/library/std/src/io/copy.rs +++ b/library/std/src/io/copy.rs @@ -214,19 +214,28 @@ impl BufferedWriterSpec for BufWriter { } let mut len = 0; + let mut init = 0; loop { let buf = self.buffer_mut(); let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into(); + unsafe { + // SAFETY: init is either 0 or the init_len from the previous iteration. + read_buf.set_init(init); + } + if read_buf.capacity() >= DEFAULT_BUF_SIZE { let mut cursor = read_buf.unfilled(); match reader.read_buf(cursor.reborrow()) { Ok(()) => { let bytes_read = cursor.written(); + if bytes_read == 0 { return Ok(len); } + + init = read_buf.init_len() - bytes_read; len += bytes_read as u64; // SAFETY: BorrowedBuf guarantees all of its filled bytes are init @@ -239,6 +248,10 @@ impl BufferedWriterSpec for BufWriter { Err(e) => return Err(e), } } else { + // All the bytes that were already in the buffer are initialized, + // treat them as such when the buffer is flushed. + init += buf.len(); + self.flush_buf()?; } } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 4c064c435e5b..b7756befa11e 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -419,6 +419,8 @@ pub(crate) fn default_read_to_end( .and_then(|s| s.checked_add(1024)?.checked_next_multiple_of(DEFAULT_BUF_SIZE)) .unwrap_or(DEFAULT_BUF_SIZE); + let mut initialized = 0; // Extra initialized bytes from previous loop iteration + const PROBE_SIZE: usize = 32; fn small_probe_read(r: &mut R, buf: &mut Vec) -> Result { @@ -447,6 +449,8 @@ pub(crate) fn default_read_to_end( } } + let mut consecutive_short_reads = 0; + loop { if buf.len() == buf.capacity() && buf.capacity() == start_cap { // The buffer might be an exact fit. Let's read into a probe buffer @@ -470,6 +474,11 @@ pub(crate) fn default_read_to_end( spare = &mut spare[..buf_len]; let mut read_buf: BorrowedBuf<'_> = spare.into(); + // SAFETY: These bytes were initialized but not filled in the previous loop + unsafe { + read_buf.set_init(initialized); + } + let mut cursor = read_buf.unfilled(); let result = loop { match r.read_buf(cursor.reborrow()) { @@ -480,7 +489,9 @@ pub(crate) fn default_read_to_end( } }; + let unfilled_but_initialized = cursor.init_mut().len(); let bytes_read = cursor.written(); + let was_fully_initialized = read_buf.init_len() == buf_len; // SAFETY: BorrowedBuf's invariants mean this much memory is initialized. unsafe { @@ -495,8 +506,27 @@ pub(crate) fn default_read_to_end( return Ok(buf.len() - start_len); } + if bytes_read < buf_len { + consecutive_short_reads += 1; + } else { + consecutive_short_reads = 0; + } + + // store how much was initialized but not filled + initialized = unfilled_but_initialized; + // Use heuristics to determine the max read size if no initial size hint was provided if size_hint.is_none() { + // The reader is returning short reads but it doesn't call ensure_init(). + // In that case we no longer need to restrict read sizes to avoid + // initialization costs. + // When reading from disk we usually don't get any short reads except at EOF. + // So we wait for at least 2 short reads before uncapping the read buffer; + // this helps with the Windows issue. + if !was_fully_initialized && consecutive_short_reads > 1 { + max_read_size = usize::MAX; + } + // we have passed a larger buffer than previously and the // reader still hasn't returned a short read if buf_len >= max_read_size && bytes_read == buf_len { @@ -557,13 +587,8 @@ pub(crate) fn default_read_buf(read: F, mut cursor: BorrowedCursor<'_>) -> Re where F: FnOnce(&mut [u8]) -> Result, { - // SAFETY: We do not uninitialize any part of the buffer. - let n = read(unsafe { cursor.as_mut().write_filled(0) })?; - assert!(n <= cursor.capacity()); - // SAFETY: We've initialized the entire buffer, and `read` can't make it uninitialized. - unsafe { - cursor.advance(n); - } + let n = read(cursor.ensure_init().init_mut())?; + cursor.advance(n); Ok(()) } @@ -3073,21 +3098,31 @@ impl Read for Take { // The condition above guarantees that `self.limit` fits in `usize`. let limit = self.limit as usize; + let extra_init = cmp::min(limit, buf.init_mut().len()); + // SAFETY: no uninit data is written to ibuf let ibuf = unsafe { &mut buf.as_mut()[..limit] }; let mut sliced_buf: BorrowedBuf<'_> = ibuf.into(); + // SAFETY: extra_init bytes of ibuf are known to be initialized + unsafe { + sliced_buf.set_init(extra_init); + } + let mut cursor = sliced_buf.unfilled(); let result = self.inner.read_buf(cursor.reborrow()); + let new_init = cursor.init_mut().len(); let filled = sliced_buf.len(); // cursor / sliced_buf / ibuf must drop here - // SAFETY: filled bytes have been filled and therefore initialized unsafe { - buf.advance(filled); + // SAFETY: filled bytes have been filled and therefore initialized + buf.advance_unchecked(filled); + // SAFETY: new_init bytes of buf's unfilled buffer have been initialized + buf.set_init(new_init); } self.limit -= filled as u64; diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index e14e6432eafa..b22988d4a8a9 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -209,6 +209,15 @@ fn read_buf_exact() { assert_eq!(c.read_buf_exact(buf.unfilled()).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); } +#[test] +#[should_panic] +fn borrowed_cursor_advance_overflow() { + let mut buf = [0; 512]; + let mut buf = BorrowedBuf::from(&mut buf[..]); + buf.unfilled().advance(1); + buf.unfilled().advance(usize::MAX); +} + #[test] fn take_eof() { struct R; diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index a09c8bc06930..0410df3ef1a3 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -283,7 +283,7 @@ impl Read for Repeat { // SAFETY: No uninit bytes are being written. unsafe { buf.as_mut() }.write_filled(self.byte); // SAFETY: the entire unfilled portion of buf has been initialized. - unsafe { buf.advance(buf.capacity()) }; + unsafe { buf.advance_unchecked(buf.capacity()) }; Ok(()) } diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs index 92dbc3919bea..d0f106d7af41 100644 --- a/library/std/src/io/util/tests.rs +++ b/library/std/src/io/util/tests.rs @@ -75,36 +75,43 @@ fn empty_reads() { let mut buf: BorrowedBuf<'_> = buf.into(); e.read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit()]; let mut buf: BorrowedBuf<'_> = buf.into(); e.read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; let mut buf: BorrowedBuf<'_> = buf.into(); e.read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; let mut buf: BorrowedBuf<'_> = buf.into(); Read::by_ref(&mut e).read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [MaybeUninit<_>] = &mut []; let mut buf: BorrowedBuf<'_> = buf.into(); e.read_buf_exact(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit()]; let mut buf: BorrowedBuf<'_> = buf.into(); assert_eq!(e.read_buf_exact(buf.unfilled()).unwrap_err().kind(), ErrorKind::UnexpectedEof); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; let mut buf: BorrowedBuf<'_> = buf.into(); assert_eq!(e.read_buf_exact(buf.unfilled()).unwrap_err().kind(), ErrorKind::UnexpectedEof); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; let mut buf: BorrowedBuf<'_> = buf.into(); @@ -113,6 +120,7 @@ fn empty_reads() { ErrorKind::UnexpectedEof, ); assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); let mut buf = Vec::new(); assert_eq!(e.read_to_end(&mut buf).unwrap(), 0); diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs index 4787f8a1040b..7c7ef7b2f701 100644 --- a/library/std/src/net/tcp/tests.rs +++ b/library/std/src/net/tcp/tests.rs @@ -315,6 +315,8 @@ fn read_buf() { let mut buf = BorrowedBuf::from(buf.as_mut_slice()); t!(s.read_buf(buf.unfilled())); assert_eq!(buf.filled(), &[1, 2, 3, 4]); + // TcpStream::read_buf should omit buffer initialization. + assert_eq!(buf.init_len(), 4); t.join().ok().expect("thread panicked"); }) diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs index c8a83edffe42..12c5130defe5 100644 --- a/library/std/src/process/tests.rs +++ b/library/std/src/process/tests.rs @@ -188,8 +188,10 @@ fn child_stdout_read_buf() { // ChildStdout::read_buf should omit buffer initialization. if cfg!(target_os = "windows") { assert_eq!(buf.filled(), b"abc\r\n"); + assert_eq!(buf.init_len(), 5); } else { assert_eq!(buf.filled(), b"abc\n"); + assert_eq!(buf.init_len(), 4); }; } diff --git a/library/std/src/sys/fd/hermit.rs b/library/std/src/sys/fd/hermit.rs index 28fafdaf57d8..2666da16420c 100644 --- a/library/std/src/sys/fd/hermit.rs +++ b/library/std/src/sys/fd/hermit.rs @@ -33,7 +33,7 @@ impl FileDesc { ) })?; // SAFETY: Exactly `result` bytes have been filled. - unsafe { buf.advance(result as usize) }; + unsafe { buf.advance_unchecked(result as usize) }; Ok(()) } diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index c5e8646dada1..bb6c0ac9e18e 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -185,7 +185,7 @@ impl FileDesc { // SAFETY: `ret` bytes were written to the initialized portion of the buffer unsafe { - cursor.advance(ret as usize); + cursor.advance_unchecked(ret as usize); } Ok(()) } @@ -203,7 +203,7 @@ impl FileDesc { // SAFETY: `ret` bytes were written to the initialized portion of the buffer unsafe { - cursor.advance(ret as usize); + cursor.advance_unchecked(ret as usize); } Ok(()) } diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index ec1db262855a..f6d5d3b784d3 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -401,7 +401,7 @@ impl File { // Safety: `num_bytes_read` bytes were written to the unfilled // portion of the buffer - cursor.advance(num_bytes_read); + cursor.advance_unchecked(num_bytes_read); Ok(()) } diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs index 8350d2b5fe4a..c32f8dcc8de8 100644 --- a/library/std/src/sys/net/connection/socket/hermit.rs +++ b/library/std/src/sys/net/connection/socket/hermit.rs @@ -143,7 +143,7 @@ impl Socket { ) })?; unsafe { - buf.advance(ret as usize); + buf.advance_unchecked(ret as usize); } Ok(()) } diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs index ac06cdc00c8f..673d75046d3f 100644 --- a/library/std/src/sys/net/connection/socket/solid.rs +++ b/library/std/src/sys/net/connection/socket/solid.rs @@ -190,7 +190,7 @@ impl Socket { netc::recv(self.as_raw_fd(), buf.as_mut().as_mut_ptr().cast(), buf.capacity(), flags) })?; unsafe { - buf.advance(ret as usize); + buf.advance_unchecked(ret as usize); } Ok(()) } diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index 323d6214347e..6d06a8d86bf1 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -294,7 +294,7 @@ impl Socket { ) })?; unsafe { - buf.advance(ret as usize); + buf.advance_unchecked(ret as usize); } Ok(()) } diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index 4da51d78ea69..7355f0ce6bf5 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs @@ -243,7 +243,7 @@ impl Socket { } } _ => { - unsafe { buf.advance(result as usize) }; + unsafe { buf.advance_unchecked(result as usize) }; Ok(()) } } diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs index f1e4a5a42577..5041770faf66 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs @@ -46,7 +46,7 @@ pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_>) -> IoResult<()> { let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.capacity()); let len = raw::read(fd, userbuf.as_mut_ptr().cast(), userbuf.len()).from_sgx_result()?; userbuf[..len].copy_to_enclave(&mut buf.as_mut()[..len]); - buf.advance(len); + buf.advance_unchecked(len); Ok(()) } } diff --git a/library/std/src/sys/pal/windows/handle.rs b/library/std/src/sys/pal/windows/handle.rs index ffa8507831ac..90e243e1aa03 100644 --- a/library/std/src/sys/pal/windows/handle.rs +++ b/library/std/src/sys/pal/windows/handle.rs @@ -117,7 +117,7 @@ impl Handle { Ok(read) => { // Safety: `read` bytes were written to the initialized portion of the buffer unsafe { - cursor.advance(read); + cursor.advance_unchecked(read); } Ok(()) } @@ -140,7 +140,7 @@ impl Handle { // SAFETY: `read` bytes were written to the initialized portion of the buffer unsafe { - cursor.advance(read); + cursor.advance_unchecked(read); } Ok(()) } diff --git a/library/std/src/sys/process/windows/child_pipe.rs b/library/std/src/sys/process/windows/child_pipe.rs index b848435ac275..da7a86ca072e 100644 --- a/library/std/src/sys/process/windows/child_pipe.rs +++ b/library/std/src/sys/process/windows/child_pipe.rs @@ -260,7 +260,7 @@ impl ChildPipe { Err(e) => Err(e), Ok(n) => { unsafe { - buf.advance(n); + buf.advance_unchecked(n); } Ok(()) } diff --git a/library/std/src/sys/stdio/zkvm.rs b/library/std/src/sys/stdio/zkvm.rs index 84496ac93736..f31c6c26e87c 100644 --- a/library/std/src/sys/stdio/zkvm.rs +++ b/library/std/src/sys/stdio/zkvm.rs @@ -19,7 +19,7 @@ impl io::Read for Stdin { fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> io::Result<()> { unsafe { let n = abi::sys_read(fileno::STDIN, buf.as_mut().as_mut_ptr().cast(), buf.capacity()); - buf.advance(n); + buf.advance_unchecked(n); } Ok(()) } From 6fac0fac9962962f77f46fe148bbca2ed6b60f59 Mon Sep 17 00:00:00 2001 From: delta17920 Date: Sun, 14 Dec 2025 15:08:01 +0000 Subject: [PATCH 0923/3801] Apply review suggestions --- .../rustc_resolve/src/late/diagnostics.rs | 85 +++++++++--- tests/ui/match/issue-92100.stderr | 6 + ...tern-meant-to-be-slice-rest-pattern.stderr | 18 +++ .../suggest-range-struct-destructuring.rs | 41 ++++-- .../suggest-range-struct-destructuring.stderr | 127 +++++++++++++----- tests/ui/typeck/issue-105946.stderr | 6 + 6 files changed, 221 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 85e8917ae32e..f75ac400dc0b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1385,38 +1385,81 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } fn suggest_range_struct_destructuring( - &self, + &mut self, err: &mut Diag<'_>, path: &[Segment], source: PathSource<'_, '_, '_>, ) { - // We accept Expr here because range bounds (start..end) are parsed as expressions if !matches!(source, PathSource::Pat | PathSource::TupleStruct(..) | PathSource::Expr(..)) { return; } - if let Some(pat) = self.diag_metadata.current_pat - && let ast::PatKind::Range(Some(start_expr), Some(end_expr), _) = &pat.kind - && let (ast::ExprKind::Path(None, start_path), ast::ExprKind::Path(None, end_path)) = - (&start_expr.kind, &end_expr.kind) - && path.len() == 1 - { - let ident = path[0].ident; + let Some(pat) = self.diag_metadata.current_pat else { return }; + let ast::PatKind::Range(start, end, end_kind) = &pat.kind else { return }; - if (start_path.segments.len() == 1 && start_path.segments[0].ident == ident) - || (end_path.segments.len() == 1 && end_path.segments[0].ident == ident) - { - let start_name = start_path.segments[0].ident; - let end_name = end_path.segments[0].ident; + let [segment] = path else { return }; + let failing_span = segment.ident.span; - err.span_suggestion_verbose( - pat.span, - "if you meant to destructure a `Range`, use a struct pattern", - format!("std::ops::Range {{ start: {}, end: {} }}", start_name, end_name), - Applicability::MaybeIncorrect, - ); - } + let in_start = start.as_ref().is_some_and(|e| e.span.contains(failing_span)); + let in_end = end.as_ref().is_some_and(|e| e.span.contains(failing_span)); + + if !in_start && !in_end { + return; } + + let start_snippet = + start.as_ref().and_then(|e| self.r.tcx.sess.source_map().span_to_snippet(e.span).ok()); + let end_snippet = + end.as_ref().and_then(|e| self.r.tcx.sess.source_map().span_to_snippet(e.span).ok()); + + let field = |name: &str, val: String| { + if val == name { val } else { format!("{name}: {val}") } + }; + + let mut resolve_short_name = |short: Symbol, full: &str| -> String { + let ident = Ident::with_dummy_span(short); + let path = Segment::from_path(&Path::from_ident(ident)); + + match self.resolve_path(&path, Some(TypeNS), None, PathSource::Type) { + PathResult::NonModule(..) => short.to_string(), + _ => full.to_string(), + } + }; + // FIXME(new_range): Also account for new range types + let (struct_path, fields) = match (start_snippet, end_snippet, &end_kind.node) { + (Some(start), Some(end), ast::RangeEnd::Excluded) => ( + resolve_short_name(sym::Range, "std::ops::Range"), + vec![field("start", start), field("end", end)], + ), + (Some(start), Some(end), ast::RangeEnd::Included(_)) => ( + resolve_short_name(sym::RangeInclusive, "std::ops::RangeInclusive"), + vec![field("start", start), field("end", end)], + ), + (Some(start), None, _) => ( + resolve_short_name(sym::RangeFrom, "std::ops::RangeFrom"), + vec![field("start", start)], + ), + (None, Some(end), ast::RangeEnd::Excluded) => { + (resolve_short_name(sym::RangeTo, "std::ops::RangeTo"), vec![field("end", end)]) + } + (None, Some(end), ast::RangeEnd::Included(_)) => ( + resolve_short_name(sym::RangeToInclusive, "std::ops::RangeToInclusive"), + vec![field("end", end)], + ), + _ => return, + }; + + err.span_suggestion_verbose( + pat.span, + format!("if you meant to destructure a range use a struct pattern"), + format!("{} {{ {} }}", struct_path, fields.join(", ")), + Applicability::MaybeIncorrect, + ); + + err.note( + "range patterns match against the start and end of a range; \ + to bind the components, use a struct pattern", + ); } fn suggest_swapping_misplaced_self_ty_and_trait( diff --git a/tests/ui/match/issue-92100.stderr b/tests/ui/match/issue-92100.stderr index eb9f4ba1ad69..13aacc4782af 100644 --- a/tests/ui/match/issue-92100.stderr +++ b/tests/ui/match/issue-92100.stderr @@ -4,10 +4,16 @@ error[E0425]: cannot find value `a` in this scope LL | [a.., a] => {} | ^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `a`, use the at operator | LL | [a @ .., a] => {} | + +help: if you meant to destructure a range use a struct pattern + | +LL - [a.., a] => {} +LL + [std::ops::RangeFrom { start: a }, a] => {} + | error: aborting due to 1 previous error diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr index 37b2d96bb019..378ff04d3a1a 100644 --- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr +++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr @@ -16,10 +16,16 @@ error[E0425]: cannot find value `rest` in this scope LL | [1, rest..] => println!("{rest}"), | ^^^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `rest`, use the at operator | LL | [1, rest @ ..] => println!("{rest}"), | + +help: if you meant to destructure a range use a struct pattern + | +LL - [1, rest..] => println!("{rest}"), +LL + [1, std::ops::RangeFrom { start: rest }] => println!("{rest}"), + | error[E0425]: cannot find value `rest` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:35 @@ -33,11 +39,17 @@ error[E0425]: cannot find value `tail` in this scope LL | [_, ..tail] => println!("{tail}"), | ^^^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `tail`, use the at operator | LL - [_, ..tail] => println!("{tail}"), LL + [_, tail @ ..] => println!("{tail}"), | +help: if you meant to destructure a range use a struct pattern + | +LL - [_, ..tail] => println!("{tail}"), +LL + [_, std::ops::RangeTo { end: tail }] => println!("{tail}"), + | error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:35 @@ -51,11 +63,17 @@ error[E0425]: cannot find value `tail` in this scope LL | [_, ...tail] => println!("{tail}"), | ^^^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `tail`, use the at operator | LL - [_, ...tail] => println!("{tail}"), LL + [_, tail @ ..] => println!("{tail}"), | +help: if you meant to destructure a range use a struct pattern + | +LL - [_, ...tail] => println!("{tail}"), +LL + [_, std::ops::RangeToInclusive { end: tail }] => println!("{tail}"), + | error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:36 diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.rs b/tests/ui/resolve/suggest-range-struct-destructuring.rs index f690a7cad23f..ee8a99ceaa1a 100644 --- a/tests/ui/resolve/suggest-range-struct-destructuring.rs +++ b/tests/ui/resolve/suggest-range-struct-destructuring.rs @@ -1,15 +1,40 @@ -use std::ops::Range; +use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive}; -fn test_basic_range(r: Range) { +fn test_range(r: Range) { let start..end = r; - //~^ ERROR cannot find value `start` in this scope - //~| ERROR cannot find value `end` in this scope + //~^ ERROR cannot find value `start` + //~| ERROR cannot find value `end` } -fn test_different_names(r: Range) { - let min..max = r; - //~^ ERROR cannot find value `min` in this scope - //~| ERROR cannot find value `max` in this scope +fn test_inclusive(r: RangeInclusive) { + let start..=end = r; + //~^ ERROR cannot find value `start` + //~| ERROR cannot find value `end` +} + +fn test_from(r: RangeFrom) { + let start.. = r; + //~^ ERROR cannot find value `start` +} + +fn test_to(r: RangeTo) { + let ..end = r; + //~^ ERROR cannot find value `end` +} + +fn test_to_inclusive(r: RangeToInclusive) { + let ..=end = r; + //~^ ERROR cannot find value `end` +} + +// Case 6: Complex Path (Keep this! It works!) +mod my { + // We don't define MISSING here to trigger the error +} +fn test_path(r: Range) { + let my::MISSING..end = r; + //~^ ERROR cannot find value `MISSING` + //~| ERROR cannot find value `end` } fn main() {} diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.stderr b/tests/ui/resolve/suggest-range-struct-destructuring.stderr index 1a11e6ac8421..78a248ed777d 100644 --- a/tests/ui/resolve/suggest-range-struct-destructuring.stderr +++ b/tests/ui/resolve/suggest-range-struct-destructuring.stderr @@ -4,10 +4,11 @@ error[E0425]: cannot find value `start` in this scope LL | let start..end = r; | ^^^^^ not found in this scope | -help: if you meant to destructure a `Range`, use a struct pattern + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern | LL - let start..end = r; -LL + let std::ops::Range { start: start, end: end } = r; +LL + let Range { start, end } = r; | error[E0425]: cannot find value `end` in this scope @@ -16,51 +17,111 @@ error[E0425]: cannot find value `end` in this scope LL | let start..end = r; | ^^^ not found in this scope | -help: if you meant to destructure a `Range`, use a struct pattern + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern | LL - let start..end = r; -LL + let std::ops::Range { start: start, end: end } = r; +LL + let Range { start, end } = r; | -error[E0425]: cannot find value `min` in this scope +error[E0425]: cannot find value `start` in this scope --> $DIR/suggest-range-struct-destructuring.rs:10:9 | -LL | let min..max = r; - | ^^^ -... -LL | fn main() {} - | --------- similarly named function `main` defined here +LL | let start..=end = r; + | ^^^^^ not found in this scope | -help: if you meant to destructure a `Range`, use a struct pattern + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern | -LL - let min..max = r; -LL + let std::ops::Range { start: min, end: max } = r; - | -help: a function with a similar name exists - | -LL | let main..max = r; - | + -help: consider importing this function - | -LL + use std::cmp::min; +LL - let start..=end = r; +LL + let RangeInclusive { start, end } = r; | -error[E0425]: cannot find value `max` in this scope - --> $DIR/suggest-range-struct-destructuring.rs:10:14 +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:10:17 | -LL | let min..max = r; - | ^^^ not found in this scope +LL | let start..=end = r; + | ^^^ not found in this scope | -help: if you meant to destructure a `Range`, use a struct pattern + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern | -LL - let min..max = r; -LL + let std::ops::Range { start: min, end: max } = r; - | -help: consider importing this function - | -LL + use std::cmp::max; +LL - let start..=end = r; +LL + let RangeInclusive { start, end } = r; | -error: aborting due to 4 previous errors +error[E0425]: cannot find value `start` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:16:9 + | +LL | let start.. = r; + | ^^^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to collect the rest of the slice in `start`, use the at operator + | +LL | let start @ .. = r; + | + +help: if you meant to destructure a range use a struct pattern + | +LL - let start.. = r; +LL + let RangeFrom { start } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:21:11 + | +LL | let ..end = r; + | ^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to collect the rest of the slice in `end`, use the at operator + | +LL - let ..end = r; +LL + let end @ .. = r; + | +help: if you meant to destructure a range use a struct pattern + | +LL - let ..end = r; +LL + let RangeTo { end } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:26:12 + | +LL | let ..=end = r; + | ^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to collect the rest of the slice in `end`, use the at operator + | +LL - let ..=end = r; +LL + let end @ .. = r; + | +help: if you meant to destructure a range use a struct pattern + | +LL - let ..=end = r; +LL + let RangeToInclusive { end } = r; + | + +error[E0425]: cannot find value `MISSING` in module `my` + --> $DIR/suggest-range-struct-destructuring.rs:35:13 + | +LL | let my::MISSING..end = r; + | ^^^^^^^ not found in `my` + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:35:22 + | +LL | let my::MISSING..end = r; + | ^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern + | +LL - let my::MISSING..end = r; +LL + let Range { start: my::MISSING, end } = r; + | + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/typeck/issue-105946.stderr b/tests/ui/typeck/issue-105946.stderr index 30fe2000a461..3f8733bda763 100644 --- a/tests/ui/typeck/issue-105946.stderr +++ b/tests/ui/typeck/issue-105946.stderr @@ -4,10 +4,16 @@ error[E0425]: cannot find value `_y` in this scope LL | let [_y..] = [Box::new(1), Box::new(2)]; | ^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `_y`, use the at operator | LL | let [_y @ ..] = [Box::new(1), Box::new(2)]; | + +help: if you meant to destructure a range use a struct pattern + | +LL - let [_y..] = [Box::new(1), Box::new(2)]; +LL + let [std::ops::RangeFrom { start: _y }] = [Box::new(1), Box::new(2)]; + | error[E0658]: `X..` patterns in slices are experimental --> $DIR/issue-105946.rs:7:10 From c7dd19b8d6fc3a06dfec78ad76452babcadef3b5 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 17 Dec 2025 12:25:45 +0100 Subject: [PATCH 0924/3801] add `miri_spin_loop` to make `hint::spin_loop` work consistently --- library/core/src/hint.rs | 9 +++++++++ src/tools/miri/src/shims/foreign_items.rs | 7 +++++++ src/tools/miri/tests/utils/miri_extern.rs | 3 +++ 3 files changed, 19 insertions(+) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index e2ac746d3149..4c050b49bf7e 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -269,6 +269,15 @@ pub const unsafe fn assert_unchecked(cond: bool) { #[stable(feature = "renamed_spin_loop", since = "1.49.0")] pub fn spin_loop() { crate::cfg_select! { + miri => { + unsafe extern "Rust" { + safe fn miri_spin_loop(); + } + + // Miri does support some of the intrinsics that are called below, but to guarantee + // consistent behavior across targets, this custom function is used. + miri_spin_loop(); + } target_arch = "x86" => { // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets. crate::arch::x86::_mm_pause() diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 8a959d06bf9c..48f4ca53cdca 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -435,6 +435,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Return value: 0 on success, otherwise the size it would have needed. this.write_int(if success { 0 } else { needed_size }, dest)?; } + // Hint that a loop is spinning indefinitely. + "miri_spin_loop" => { + let [] = this.check_shim_sig_lenient(abi, CanonAbi::Rust, link_name, args)?; + + // Try to run another thread to maximize the chance of finding actual bugs. + this.yield_active_thread(); + } // Obtains the size of a Miri backtrace. See the README for details. "miri_backtrace_size" => { this.handle_miri_backtrace_size(abi, link_name, args, dest)?; diff --git a/src/tools/miri/tests/utils/miri_extern.rs b/src/tools/miri/tests/utils/miri_extern.rs index 09f9ca032d43..bd01866dc34c 100644 --- a/src/tools/miri/tests/utils/miri_extern.rs +++ b/src/tools/miri/tests/utils/miri_extern.rs @@ -155,4 +155,7 @@ extern "Rust" { /// Blocks the current execution if the argument is false pub fn miri_genmc_assume(condition: bool); + + /// Indicate to Miri that this thread is busy-waiting in a spin loop. + pub fn miri_spin_loop(); } From 0f17de76b81f64f032d31a309d63f8a6c250a7c6 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 17 Dec 2025 16:23:28 +0100 Subject: [PATCH 0925/3801] skip `needless_type_cast` for single-use non-coercible casts --- clippy_lints/src/casts/needless_type_cast.rs | 59 +++++++++- tests/ui/needless_type_cast.fixed | 87 ++++++++++++++ tests/ui/needless_type_cast.rs | 87 ++++++++++++++ tests/ui/needless_type_cast.stderr | 114 +++++++++++++++++-- 4 files changed, 330 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/casts/needless_type_cast.rs b/clippy_lints/src/casts/needless_type_cast.rs index 8ef9db1b510c..1d899a21c229 100644 --- a/clippy_lints/src/casts/needless_type_cast.rs +++ b/clippy_lints/src/casts/needless_type_cast.rs @@ -1,6 +1,8 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::sugg::Sugg; use clippy_utils::visitors::{Descend, for_each_expr, for_each_expr_without_closures}; use core::ops::ControlFlow; +use rustc_ast::ast::{LitFloatType, LitIntType, LitKind}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; @@ -14,6 +16,7 @@ use super::NEEDLESS_TYPE_CAST; struct BindingInfo<'a> { source_ty: Ty<'a>, ty_span: Span, + init: Option<&'a Expr<'a>>, } struct UsageInfo<'a> { @@ -73,6 +76,7 @@ fn collect_binding_from_let<'a>( BindingInfo { source_ty: ty, ty_span: ty_hir.span, + init: Some(let_expr.init), }, ); } @@ -103,6 +107,7 @@ fn collect_binding_from_local<'a>( BindingInfo { source_ty: ty, ty_span: ty_hir.span, + init: let_stmt.init, }, ); } @@ -229,6 +234,18 @@ fn is_cast_in_generic_context<'a>(cx: &LateContext<'a>, cast_expr: &Expr<'a>) -> } } +fn can_coerce_to_target_type(expr: &Expr<'_>) -> bool { + match expr.kind { + ExprKind::Lit(lit) => matches!( + lit.node, + LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed) + ), + ExprKind::Unary(rustc_hir::UnOp::Neg, inner) => can_coerce_to_target_type(inner), + ExprKind::Binary(_, lhs, rhs) => can_coerce_to_target_type(lhs) && can_coerce_to_target_type(rhs), + _ => false, + } +} + fn check_binding_usages<'a>(cx: &LateContext<'a>, body: &Body<'a>, hir_id: HirId, binding_info: &BindingInfo<'a>) { let mut usages = Vec::new(); @@ -269,7 +286,19 @@ fn check_binding_usages<'a>(cx: &LateContext<'a>, body: &Body<'a>, hir_id: HirId return; }; - span_lint_and_sugg( + // Don't lint if there's exactly one use and the initializer cannot be coerced to the + // target type (i.e., would require an explicit cast). In such cases, the fix would add + // a cast to the initializer rather than eliminating one - the cast isn't truly "needless." + // See: https://github.com/rust-lang/rust-clippy/issues/16240 + if usages.len() == 1 + && binding_info + .init + .is_some_and(|init| !can_coerce_to_target_type(init) && !init.span.from_expansion()) + { + return; + } + + span_lint_and_then( cx, NEEDLESS_TYPE_CAST, binding_info.ty_span, @@ -277,8 +306,28 @@ fn check_binding_usages<'a>(cx: &LateContext<'a>, body: &Body<'a>, hir_id: HirId "this binding is defined as `{}` but is always cast to `{}`", binding_info.source_ty, first_target ), - "consider defining it as", - first_target.to_string(), - Applicability::MaybeIncorrect, + |diag| { + if let Some(init) = binding_info + .init + .filter(|i| !can_coerce_to_target_type(i) && !i.span.from_expansion()) + { + let sugg = Sugg::hir(cx, init, "..").as_ty(first_target); + diag.multipart_suggestion( + format!("consider defining it as `{first_target}` and casting the initializer"), + vec![ + (binding_info.ty_span, first_target.to_string()), + (init.span, sugg.to_string()), + ], + Applicability::MachineApplicable, + ); + } else { + diag.span_suggestion( + binding_info.ty_span, + "consider defining it as", + first_target.to_string(), + Applicability::MachineApplicable, + ); + } + }, ); } diff --git a/tests/ui/needless_type_cast.fixed b/tests/ui/needless_type_cast.fixed index 32c348d3ca3a..72eed32c4d73 100644 --- a/tests/ui/needless_type_cast.fixed +++ b/tests/ui/needless_type_cast.fixed @@ -9,6 +9,10 @@ fn generic(x: T) -> T { x } +fn returns_u8() -> u8 { + 10 +} + fn main() { let a: i32 = 10; //~^ needless_type_cast @@ -180,3 +184,86 @@ fn test_loop_with_generic() { }; let _ = x as i32; } + +fn test_size_of_cast() { + use std::mem::size_of; + // Should lint: suggest casting the initializer + let size: u64 = size_of::() as u64; + //~^ needless_type_cast + let _ = size as u64; + let _ = size as u64; +} + +fn test_suffixed_literal_cast() { + // Should lint: suggest casting the initializer + let a: i32 = 10u8 as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_negative_literal() { + // Negative literal - should just change type, not add cast + let a: i32 = -10; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_suffixed_negative_literal() { + // Suffixed negative - needs cast + let a: i32 = -10i8 as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_binary_op() { + // Binary op needs parens in cast + let a: i32 = 10 + 5; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_fn_return_as_init() { + let a: i32 = returns_u8() as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_method_as_init() { + let a: i32 = 2u8.saturating_add(3) as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_const_as_init() { + const X: u8 = 10; + let a: i32 = X as i32; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_single_use_fn_call() { + // Should not lint: only one use, and fixing would just move the cast + // to the initializer rather than eliminating it + let a: u8 = returns_u8(); + let _ = a as i32; +} + +fn test_single_use_suffixed_literal() { + // Should not lint: only one use with a suffixed literal + let a: u8 = 10u8; + let _ = a as i32; +} + +fn test_single_use_binary_op() { + // Should lint: binary op of unsuffixed literals can be coerced + let a: i32 = 10 + 5; + //~^ needless_type_cast + let _ = a as i32; +} diff --git a/tests/ui/needless_type_cast.rs b/tests/ui/needless_type_cast.rs index e28f620e035f..31337575fcc3 100644 --- a/tests/ui/needless_type_cast.rs +++ b/tests/ui/needless_type_cast.rs @@ -9,6 +9,10 @@ fn generic(x: T) -> T { x } +fn returns_u8() -> u8 { + 10 +} + fn main() { let a: u8 = 10; //~^ needless_type_cast @@ -180,3 +184,86 @@ fn test_loop_with_generic() { }; let _ = x as i32; } + +fn test_size_of_cast() { + use std::mem::size_of; + // Should lint: suggest casting the initializer + let size: usize = size_of::(); + //~^ needless_type_cast + let _ = size as u64; + let _ = size as u64; +} + +fn test_suffixed_literal_cast() { + // Should lint: suggest casting the initializer + let a: u8 = 10u8; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_negative_literal() { + // Negative literal - should just change type, not add cast + let a: i8 = -10; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_suffixed_negative_literal() { + // Suffixed negative - needs cast + let a: i8 = -10i8; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_binary_op() { + // Binary op needs parens in cast + let a: u8 = 10 + 5; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_fn_return_as_init() { + let a: u8 = returns_u8(); + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_method_as_init() { + let a: u8 = 2u8.saturating_add(3); + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_const_as_init() { + const X: u8 = 10; + let a: u8 = X; + //~^ needless_type_cast + let _ = a as i32; + let _ = a as i32; +} + +fn test_single_use_fn_call() { + // Should not lint: only one use, and fixing would just move the cast + // to the initializer rather than eliminating it + let a: u8 = returns_u8(); + let _ = a as i32; +} + +fn test_single_use_suffixed_literal() { + // Should not lint: only one use with a suffixed literal + let a: u8 = 10u8; + let _ = a as i32; +} + +fn test_single_use_binary_op() { + // Should lint: binary op of unsuffixed literals can be coerced + let a: u8 = 10 + 5; + //~^ needless_type_cast + let _ = a as i32; +} diff --git a/tests/ui/needless_type_cast.stderr b/tests/ui/needless_type_cast.stderr index 3ee9df1043e7..56d9e978d05c 100644 --- a/tests/ui/needless_type_cast.stderr +++ b/tests/ui/needless_type_cast.stderr @@ -1,5 +1,5 @@ error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:13:12 + --> tests/ui/needless_type_cast.rs:17:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` @@ -8,64 +8,154 @@ LL | let a: u8 = 10; = help: to override `-D warnings` add `#[allow(clippy::needless_type_cast)]` error: this binding is defined as `u8` but is always cast to `usize` - --> tests/ui/needless_type_cast.rs:33:12 + --> tests/ui/needless_type_cast.rs:37:12 | LL | let f: u8 = 1; | ^^ help: consider defining it as: `usize` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:39:12 + --> tests/ui/needless_type_cast.rs:43:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:52:12 + --> tests/ui/needless_type_cast.rs:56:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:59:12 + --> tests/ui/needless_type_cast.rs:63:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:66:12 + --> tests/ui/needless_type_cast.rs:70:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:77:12 + --> tests/ui/needless_type_cast.rs:81:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:99:16 + --> tests/ui/needless_type_cast.rs:103:16 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:107:12 + --> tests/ui/needless_type_cast.rs:111:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:116:12 + --> tests/ui/needless_type_cast.rs:120:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` error: this binding is defined as `u8` but is always cast to `i32` - --> tests/ui/needless_type_cast.rs:122:12 + --> tests/ui/needless_type_cast.rs:126:12 | LL | let a: u8 = 10; | ^^ help: consider defining it as: `i32` -error: aborting due to 11 previous errors +error: this binding is defined as `usize` but is always cast to `u64` + --> tests/ui/needless_type_cast.rs:191:15 + | +LL | let size: usize = size_of::(); + | ^^^^^ + | +help: consider defining it as `u64` and casting the initializer + | +LL - let size: usize = size_of::(); +LL + let size: u64 = size_of::() as u64; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:199:12 + | +LL | let a: u8 = 10u8; + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: u8 = 10u8; +LL + let a: i32 = 10u8 as i32; + | + +error: this binding is defined as `i8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:207:12 + | +LL | let a: i8 = -10; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `i8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:215:12 + | +LL | let a: i8 = -10i8; + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: i8 = -10i8; +LL + let a: i32 = -10i8 as i32; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:223:12 + | +LL | let a: u8 = 10 + 5; + | ^^ help: consider defining it as: `i32` + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:230:12 + | +LL | let a: u8 = returns_u8(); + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: u8 = returns_u8(); +LL + let a: i32 = returns_u8() as i32; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:237:12 + | +LL | let a: u8 = 2u8.saturating_add(3); + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: u8 = 2u8.saturating_add(3); +LL + let a: i32 = 2u8.saturating_add(3) as i32; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:245:12 + | +LL | let a: u8 = X; + | ^^ + | +help: consider defining it as `i32` and casting the initializer + | +LL - let a: u8 = X; +LL + let a: i32 = X as i32; + | + +error: this binding is defined as `u8` but is always cast to `i32` + --> tests/ui/needless_type_cast.rs:266:12 + | +LL | let a: u8 = 10 + 5; + | ^^ help: consider defining it as: `i32` + +error: aborting due to 20 previous errors From 8fcddc639303a83fcfbae47b1d7c88adc94e917c Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 17 Dec 2025 16:41:00 +0100 Subject: [PATCH 0926/3801] remove `legacy_const_generic_args` cache --- compiler/rustc_ast_lowering/src/expr.rs | 3 ++- compiler/rustc_ast_lowering/src/lib.rs | 16 +++++++++------- compiler/rustc_middle/src/ty/mod.rs | 3 +-- compiler/rustc_resolve/src/lib.rs | 10 ++-------- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index c8a311443a58..0502fd2873e9 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -114,7 +114,8 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), ExprKind::Call(f, args) => { - if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) { + if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f, self.tcx) + { self.lower_legacy_const_generics((**f).clone(), args.clone(), &legacy_args) } else { let f = self.lower_expr(f); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d0871b0b98f4..1bc8d7c25bb5 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -47,13 +47,14 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::spawn; use rustc_data_structures::tagged_ptr::TaggedRef; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId}; use rustc_hir::definitions::{DefPathData, DisambiguatorState}; use rustc_hir::lints::DelayedLint; use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, - LifetimeSyntax, ParamName, Target, TraitCandidate, + LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr, }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; @@ -236,7 +237,7 @@ impl SpanLowerer { #[extension(trait ResolverAstLoweringExt)] impl ResolverAstLowering { - fn legacy_const_generic_args(&self, expr: &Expr) -> Option> { + fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'_>) -> Option> { let ExprKind::Path(None, path) = &expr.kind else { return None; }; @@ -256,11 +257,12 @@ impl ResolverAstLowering { return None; } - if let Some(v) = self.legacy_const_generic_args.get(&def_id) { - return v.clone(); - } - - None + find_attr!( + // we can use parsed attrs here since for other crates they're already available + tcx.get_all_attrs(def_id), + AttributeKind::RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes + ) + .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect()) } fn get_partial_res(&self, id: NodeId) -> Option { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2021f175cd84..5239fc242c86 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -31,7 +31,7 @@ use rustc_ast::AttrVec; use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree}; use rustc_ast::node_id::NodeMap; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; @@ -196,7 +196,6 @@ pub struct ResolverGlobalCtxt { /// This struct is meant to be consumed by lowering. #[derive(Debug)] pub struct ResolverAstLowering { - pub legacy_const_generic_args: FxHashMap>>, /// Resolutions for nodes that have a single resolution. pub partial_res_map: NodeMap, /// Resolutions for import nodes, which have multiple resolutions in different namespaces. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 5d4134fd91c3..01687e6f4889 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1271,7 +1271,6 @@ pub struct Resolver<'ra, 'tcx> { /// and how the `impl Trait` fragments were introduced. invocation_parents: FxHashMap, - legacy_const_generic_args: FxHashMap>>, /// Amount of lifetime parameters for each item in the crate. item_generics_num_lifetimes: FxHashMap, delegation_fn_sigs: LocalDefIdMap, @@ -1675,7 +1674,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { node_id_to_def_id, disambiguator: DisambiguatorState::new(), placeholder_field_indices: Default::default(), - legacy_const_generic_args: Default::default(), invocation_parents, item_generics_num_lifetimes: Default::default(), trait_impls: Default::default(), @@ -1805,7 +1803,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { stripped_cfg_items, }; let ast_lowering = ty::ResolverAstLowering { - legacy_const_generic_args: self.legacy_const_generic_args, partial_res_map: self.partial_res_map, import_res_map: self.import_res_map, label_res_map: self.label_res_map, @@ -2413,15 +2410,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return None; } - let indexes = find_attr!( + find_attr!( // we can use parsed attrs here since for other crates they're already available self.tcx.get_all_attrs(def_id), AttributeKind::RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes ) - .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect()); - - self.legacy_const_generic_args.insert(def_id, indexes.clone()); - indexes + .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect()) } fn resolve_main(&mut self) { From 851f1698ab9defd3728137f1e04a60dc10070f22 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 17 Dec 2025 16:57:22 +0100 Subject: [PATCH 0927/3801] Fix invalid handling of field followed by negated macro call --- src/librustdoc/html/highlight.rs | 76 +++++++++++-------- .../field-followed-by-exclamation.rs | 26 +++++++ 2 files changed, 71 insertions(+), 31 deletions(-) create mode 100644 tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 6f6345cd8666..bc268d9495f8 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -832,6 +832,20 @@ impl<'a> PeekIter<'a> { .copied() } + fn peek_next_if bool>( + &mut self, + f: F, + ) -> Option<(TokenKind, &'a str)> { + let next = self.peek_next()?; + if f(next) { + Some(next) + } else { + // We go one step back. + self.peek_pos -= 1; + None + } + } + fn stop_peeking(&mut self) { self.peek_pos = 0; } @@ -903,18 +917,19 @@ fn classify<'src>( } } - if let Some((TokenKind::Colon | TokenKind::Ident, _)) = classifier.tokens.peek() { - let tokens = classifier.get_full_ident_path(); - for &(token, start, end) in &tokens { - let text = &classifier.src[start..end]; - classifier.advance(token, text, sink, start as u32); - classifier.byte_pos += text.len() as u32; + if let Some((TokenKind::Colon | TokenKind::Ident, _)) = classifier.tokens.peek() + && let Some(nb_items) = classifier.get_full_ident_path() + { + let start = classifier.byte_pos as usize; + let mut len = 0; + for _ in 0..nb_items { + if let Some((_, text, _)) = classifier.next() { + len += text.len(); + } } - if !tokens.is_empty() { - continue; - } - } - if let Some((token, text, before)) = classifier.next() { + let text = &classifier.src[start..start + len]; + classifier.advance(TokenKind::Ident, text, sink, start as u32); + } else if let Some((token, text, before)) = classifier.next() { classifier.advance(token, text, sink, before); } else { break; @@ -957,47 +972,47 @@ impl<'src> Classifier<'src> { } /// Concatenate colons and idents as one when possible. - fn get_full_ident_path(&mut self) -> Vec<(TokenKind, usize, usize)> { - let start = self.byte_pos as usize; - let mut pos = start; + fn get_full_ident_path(&mut self) -> Option { let mut has_ident = false; + let mut nb_items = 0; - loop { + let ret = loop { let mut nb = 0; - while let Some((TokenKind::Colon, _)) = self.tokens.peek() { - self.tokens.next(); + while self.tokens.peek_next_if(|(token, _)| token == TokenKind::Colon).is_some() { nb += 1; + nb_items += 1; } // Ident path can start with "::" but if we already have content in the ident path, // the "::" is mandatory. if has_ident && nb == 0 { - return vec![(TokenKind::Ident, start, pos)]; + break Some(nb_items); } else if nb != 0 && nb != 2 { if has_ident { - return vec![(TokenKind::Ident, start, pos), (TokenKind::Colon, pos, pos + nb)]; + // Following `;` will be handled on its own. + break Some(nb_items - 1); } else { - return vec![(TokenKind::Colon, start, pos + nb)]; + break None; } } - if let Some((TokenKind::Ident, text)) = self.tokens.peek() + if let Some((TokenKind::Ident, text)) = + self.tokens.peek_next_if(|(token, _)| token == TokenKind::Ident) && let symbol = Symbol::intern(text) && (symbol.is_path_segment_keyword() || !is_keyword(symbol)) { - // We only "add" the colon if there is an ident behind. - pos += text.len() + nb; has_ident = true; - self.tokens.next(); + nb_items += 1; } else if nb > 0 && has_ident { - return vec![(TokenKind::Ident, start, pos), (TokenKind::Colon, pos, pos + nb)]; - } else if nb > 0 { - return vec![(TokenKind::Colon, start, start + nb)]; + // Following `;` will be handled on its own. + break Some(nb_items - 1); } else if has_ident { - return vec![(TokenKind::Ident, start, pos)]; + break Some(nb_items); } else { - return Vec::new(); + break None; } - } + }; + self.tokens.stop_peeking(); + ret } /// Wraps the tokens iteration to ensure that the `byte_pos` is always correct. @@ -1243,7 +1258,6 @@ impl<'src> Classifier<'src> { Class::MacroNonTerminal } TokenKind::Ident => { - let file_span = self.file_span; let span = || new_span(before, text, file_span); match text { diff --git a/tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs b/tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs new file mode 100644 index 000000000000..e80b4c4ec873 --- /dev/null +++ b/tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs @@ -0,0 +1,26 @@ +// This test ensures that the macro expansion is correctly handled in cases like: +// `field: !f!`, because the `:` was simply not considered because of how paths +// are handled. + +//@ compile-flags: -Zunstable-options --generate-macro-expansion + +#![crate_name = "foo"] + +//@ has 'src/foo/field-followed-by-exclamation.rs.html' + +struct Bar { + bla: bool, +} + +macro_rules! f { + () => {{ false }} +} + +const X: Bar = Bar { + //@ has - '//*[@class="expansion"]/*[@class="original"]/*[@class="macro"]' 'f!' + //@ has - '//*[@class="expansion"]/*[@class="original"]' 'f!()' + //@ has - '//*[@class="expansion"]/*[@class="expanded"]' '{ false }' + // It includes both original and expanded code. + //@ has - '//*[@class="expansion"]' ' bla: !{ false }f!()' + bla: !f!(), +}; From bd137df64a4a9af48f7e107f4a488787fce3f51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 17 Dec 2025 14:23:13 +0100 Subject: [PATCH 0928/3801] test for duplicate default eii ICE 149985 Co-authored-by: SATVIKsynopsis --- tests/ui/eii/default/multiple-default-impls.rs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/ui/eii/default/multiple-default-impls.rs diff --git a/tests/ui/eii/default/multiple-default-impls.rs b/tests/ui/eii/default/multiple-default-impls.rs new file mode 100644 index 000000000000..8a91feec382d --- /dev/null +++ b/tests/ui/eii/default/multiple-default-impls.rs @@ -0,0 +1,8 @@ +#![crate_type = "lib"] +#![feature(extern_item_impls)] + +#[eii(eii1)] +fn a() {} + +#[eii(eii1)] +fn b() {} From 1cd7cb1e8d5cfcf64942222091dae67725bb1951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 17 Dec 2025 17:53:07 +0100 Subject: [PATCH 0929/3801] turn panic into span_delayed_bug --- compiler/rustc_passes/src/eii.rs | 3 ++- tests/ui/eii/default/multiple-default-impls.rs | 10 ++++++++++ tests/ui/eii/default/multiple-default-impls.stderr | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/ui/eii/default/multiple-default-impls.stderr diff --git a/compiler/rustc_passes/src/eii.rs b/compiler/rustc_passes/src/eii.rs index 691576e6a05f..ab3f9f0d2182 100644 --- a/compiler/rustc_passes/src/eii.rs +++ b/compiler/rustc_passes/src/eii.rs @@ -116,7 +116,8 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, (): } if default_impls.len() > 1 { - panic!("multiple not supported right now"); + let decl_span = tcx.def_ident_span(decl_did).unwrap(); + tcx.dcx().span_delayed_bug(decl_span, "multiple not supported right now"); } let (local_impl, is_default) = diff --git a/tests/ui/eii/default/multiple-default-impls.rs b/tests/ui/eii/default/multiple-default-impls.rs index 8a91feec382d..8d2ad0c1e137 100644 --- a/tests/ui/eii/default/multiple-default-impls.rs +++ b/tests/ui/eii/default/multiple-default-impls.rs @@ -1,8 +1,18 @@ #![crate_type = "lib"] #![feature(extern_item_impls)] +// `eii` expands to, among other things, `macro eii() {}`. +// If we have two eiis named the same thing, we have a duplicate definition +// for that macro. The compiler happily continues compiling on duplicate +// definitions though, to emit as many diagnostics as possible. +// However, in the case of eiis, this can break the assumption that every +// eii has only one default implementation, since the default for both eiis will +// name resolve to the same eii definiton (since the other definition was duplicate) +// This test tests for the previously-ICE that occurred when this assumption +// (of 1 default) was broken which was reported in #149982. #[eii(eii1)] fn a() {} #[eii(eii1)] +//~^ ERROR the name `eii1` is defined multiple times fn b() {} diff --git a/tests/ui/eii/default/multiple-default-impls.stderr b/tests/ui/eii/default/multiple-default-impls.stderr new file mode 100644 index 000000000000..b270b2346cd5 --- /dev/null +++ b/tests/ui/eii/default/multiple-default-impls.stderr @@ -0,0 +1,14 @@ +error[E0428]: the name `eii1` is defined multiple times + --> $DIR/multiple-default-impls.rs:16:1 + | +LL | #[eii(eii1)] + | ------------ previous definition of the macro `eii1` here +... +LL | #[eii(eii1)] + | ^^^^^^^^^^^^ `eii1` redefined here + | + = note: `eii1` must be defined only once in the macro namespace of this module + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0428`. From 08b7d34e06832250d3b1c8a4bf5ec78fbbae12a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 17 Dec 2025 17:57:04 +0100 Subject: [PATCH 0930/3801] another related case that deserved a test --- .../multiple-default-impls-same-name.rs | 19 ++++++++++++++ .../multiple-default-impls-same-name.stderr | 25 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/ui/eii/default/multiple-default-impls-same-name.rs create mode 100644 tests/ui/eii/default/multiple-default-impls-same-name.stderr diff --git a/tests/ui/eii/default/multiple-default-impls-same-name.rs b/tests/ui/eii/default/multiple-default-impls-same-name.rs new file mode 100644 index 000000000000..080e0a46b755 --- /dev/null +++ b/tests/ui/eii/default/multiple-default-impls-same-name.rs @@ -0,0 +1,19 @@ +#![crate_type = "lib"] +#![feature(extern_item_impls)] +// `eii` expands to, among other things, `macro eii() {}`. +// If we have two eiis named the same thing, we have a duplicate definition +// for that macro. The compiler happily continues compiling on duplicate +// definitions though, to emit as many diagnostics as possible. +// However, in the case of eiis, this can break the assumption that every +// eii has only one default implementation, since the default for both eiis will +// name resolve to the same eii definiton (since the other definition was duplicate) +// This test tests for the previously-ICE that occurred when this assumption +// (of 1 default) was broken which was reported in #149982. + +#[eii(eii1)] +fn a() {} + +#[eii(eii1)] +//~^ ERROR the name `eii1` is defined multiple times +fn a() {} +//~^ ERROR the name `a` is defined multiple times diff --git a/tests/ui/eii/default/multiple-default-impls-same-name.stderr b/tests/ui/eii/default/multiple-default-impls-same-name.stderr new file mode 100644 index 000000000000..20544fcfeeba --- /dev/null +++ b/tests/ui/eii/default/multiple-default-impls-same-name.stderr @@ -0,0 +1,25 @@ +error[E0428]: the name `a` is defined multiple times + --> $DIR/multiple-default-impls-same-name.rs:18:1 + | +LL | fn a() {} + | ------ previous definition of the value `a` here +... +LL | fn a() {} + | ^^^^^^ `a` redefined here + | + = note: `a` must be defined only once in the value namespace of this module + +error[E0428]: the name `eii1` is defined multiple times + --> $DIR/multiple-default-impls-same-name.rs:16:1 + | +LL | #[eii(eii1)] + | ------------ previous definition of the macro `eii1` here +... +LL | #[eii(eii1)] + | ^^^^^^^^^^^^ `eii1` redefined here + | + = note: `eii1` must be defined only once in the macro namespace of this module + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0428`. From bbda675aacff15a8bf93c9b98a66d2faeb0c0d1b Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 17 Dec 2025 12:31:58 +0100 Subject: [PATCH 0931/3801] Port `#[rustc_no_implicit_autorefs]` to attribute parser --- .../src/attributes/rustc_internal.rs | 15 +++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/autorefs.rs | 6 +++--- compiler/rustc_passes/src/check_attr.rs | 4 +--- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 620878fb87a7..dc743117d69c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -27,6 +27,21 @@ impl NoArgsAttributeParser for RustcNeverReturnsNullPointerParser { ]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNeverReturnsNullPointer; } +pub(crate) struct RustcNoImplicitAutorefsParser; + +impl NoArgsAttributeParser for RustcNoImplicitAutorefsParser { + const PATH: &[Symbol] = &[sym::rustc_no_implicit_autorefs]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitAutorefs; +} pub(crate) struct RustcLayoutScalarValidRangeStartParser; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 54c9785a42f6..8f286d4a0882 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,7 +61,7 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcMainParser, RustcNeverReturnsNullPointerParser, + RustcLegacyConstGenericsParser, RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; @@ -257,6 +257,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 4a81c4ebe1e7..bc5473f91cf7 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -881,6 +881,9 @@ pub enum AttributeKind { /// Represents `#[rustc_never_returns_null_ptr]` RustcNeverReturnsNullPointer, + /// Represents `#[rustc_no_implicit_autorefs]` + RustcNoImplicitAutorefs, + /// Represents `#[rustc_object_lifetime_default]`. RustcObjectLifetimeDefault, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index e631d6a2ab87..7b930ca22b1f 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -96,6 +96,7 @@ impl AttributeKind { RustcLegacyConstGenerics { .. } => Yes, RustcMain => No, RustcNeverReturnsNullPointer => Yes, + RustcNoImplicitAutorefs => Yes, RustcObjectLifetimeDefault => No, RustcPassIndirectlyInNonRusticAbis(..) => No, RustcScalableVector { .. } => Yes, diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs index 5490a3aac9b7..ed7ac0e33244 100644 --- a/compiler/rustc_lint/src/autorefs.rs +++ b/compiler/rustc_lint/src/autorefs.rs @@ -1,8 +1,8 @@ use rustc_ast::{BorrowKind, UnOp}; -use rustc_hir::{Expr, ExprKind, Mutability}; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{Expr, ExprKind, Mutability, find_attr}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDeref}; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::sym; use crate::lints::{ ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsMethodNote, ImplicitUnsafeAutorefsOrigin, @@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs { ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id), _ => None, } - && method_did.map(|did| cx.tcx.has_attr(did, sym::rustc_no_implicit_autorefs)).unwrap_or(true) + && method_did.map(|did| find_attr!(cx.tcx.get_all_attrs(did), AttributeKind::RustcNoImplicitAutorefs)).unwrap_or(true) { cx.emit_span_lint( DANGEROUS_IMPLICIT_AUTOREFS, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d1f96721fc65..25628605a03c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -255,6 +255,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::MacroUse { .. } | AttributeKind::MacroEscape( .. ) | AttributeKind::NoLink + | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcNeverReturnsNullPointer @@ -305,9 +306,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::rustc_no_implicit_autorefs, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) - } [sym::rustc_lint_query_instability, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } From 81d20363b3f7e1c5d56b35c0de516061b04709a8 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 17 Dec 2025 13:38:19 +0100 Subject: [PATCH 0932/3801] Port `#[rustc_lint_opt_ty]` to parsed attribute --- .../src/attributes/rustc_internal.rs | 9 +++++++++ compiler/rustc_attr_parsing/src/context.rs | 4 +++- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/internal.rs | 5 +++-- compiler/rustc_passes/messages.ftl | 4 ---- compiler/rustc_passes/src/check_attr.rs | 12 +----------- compiler/rustc_passes/src/errors.rs | 9 --------- 8 files changed, 20 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index dc743117d69c..dc03e1c9312a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -117,6 +117,15 @@ impl SingleAttributeParser for RustcLegacyConstGenericsParser { } } +pub(crate) struct RustcLintOptTyParser; + +impl NoArgsAttributeParser for RustcLintOptTyParser { + const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy; +} + pub(crate) struct RustcObjectLifetimeDefaultParser; impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8f286d4a0882..8cd30ac9ca46 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,7 +61,8 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, + RustcLegacyConstGenericsParser, RustcLintOptTyParser, RustcMainParser, + RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; @@ -255,6 +256,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index bc5473f91cf7..761078bf79fa 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -875,6 +875,9 @@ pub enum AttributeKind { /// Represents `#[rustc_legacy_const_generics]` RustcLegacyConstGenerics { fn_indexes: ThinVec<(usize, Span)>, attr_span: Span }, + /// Represents `#[rustc_lint_opt_ty]` + RustcLintOptTy, + /// Represents `#[rustc_main]`. RustcMain, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 7b930ca22b1f..e84fca61ac48 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -94,6 +94,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, + RustcLintOptTy => Yes, RustcMain => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index c00ba4959c94..25f5710cca3a 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -1,9 +1,10 @@ //! Some lints that are only useful in the compiler or crates that use compiler internals, such as //! Clippy. +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; -use rustc_hir::{Expr, ExprKind, HirId}; +use rustc_hir::{Expr, ExprKind, HirId, find_attr}; use rustc_middle::ty::{self, GenericArgsRef, PredicatePolarity, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::hygiene::{ExpnKind, MacroKind}; @@ -658,7 +659,7 @@ impl LateLintPass<'_> for BadOptAccess { let Some(adt_def) = cx.typeck_results().expr_ty(base).ty_adt_def() else { return }; // Skip types without `#[rustc_lint_opt_ty]` - only so that the rest of the lint can be // avoided. - if !cx.tcx.has_attr(adt_def.did(), sym::rustc_lint_opt_ty) { + if !find_attr!(cx.tcx.get_all_attrs(adt_def.did()), AttributeKind::RustcLintOptTy) { return; } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index dfa7826ece7d..5a9b75957517 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -477,10 +477,6 @@ passes_rustc_lint_opt_deny_field_access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field .label = not a field -passes_rustc_lint_opt_ty = - `#[rustc_lint_opt_ty]` should be applied to a struct - .label = not a struct - passes_rustc_pub_transparent = attribute should be applied to `#[repr(transparent)]` types .label = not a `#[repr(transparent)]` type diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 25628605a03c..00169cf6ae0c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -258,6 +258,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) + | AttributeKind::RustcLintOptTy | AttributeKind::RustcNeverReturnsNullPointer | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) @@ -315,7 +316,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_lint_diagnostics, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } - [sym::rustc_lint_opt_ty, ..] => self.check_rustc_lint_opt_ty(attr, span, target), [sym::rustc_lint_opt_deny_field_access, ..] => { self.check_rustc_lint_opt_deny_field_access(attr, span, target) } @@ -1253,16 +1253,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct. - fn check_rustc_lint_opt_ty(&self, attr: &Attribute, span: Span, target: Target) { - match target { - Target::Struct => {} - _ => { - self.dcx().emit_err(errors::RustcLintOptTy { attr_span: attr.span(), span }); - } - } - } - /// Checks that the `#[rustc_lint_opt_deny_field_access]` attribute is only applied to a field. fn check_rustc_lint_opt_deny_field_access(&self, attr: &Attribute, span: Span, target: Target) { match target { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 6b3c2bd1a7b2..f2b7d3740cb6 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -412,15 +412,6 @@ pub(crate) struct UnusedMultiple { pub name: Symbol, } -#[derive(Diagnostic)] -#[diag(passes_rustc_lint_opt_ty)] -pub(crate) struct RustcLintOptTy { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(passes_rustc_lint_opt_deny_field_access)] pub(crate) struct RustcLintOptDenyFieldAccess { From 96e453d713738204f68f75558d13f923097e33ae Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 17 Dec 2025 14:38:56 +0100 Subject: [PATCH 0933/3801] Port `#[rustc_lint_query_instability]` to parsed attribute --- .../src/attributes/rustc_internal.rs | 15 ++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 5 ++-- .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/internal.rs | 7 ++++-- compiler/rustc_passes/src/check_attr.rs | 4 +--- .../query_stability_incorrect.rs | 2 +- .../query_stability_incorrect.stderr | 23 +++++++++++-------- 8 files changed, 42 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index dc03e1c9312a..7910443787b4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -126,6 +126,21 @@ impl NoArgsAttributeParser for RustcLintOptTyParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy; } +pub(crate) struct RustcLintQueryInstabilityParser; + +impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { + const PATH: &[Symbol] = &[sym::rustc_lint_query_instability]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintQueryInstability; +} + pub(crate) struct RustcObjectLifetimeDefaultParser; impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8cd30ac9ca46..b4854c430cae 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,8 +61,8 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcLintOptTyParser, RustcMainParser, - RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, + RustcLegacyConstGenericsParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser, + RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; @@ -257,6 +257,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 761078bf79fa..3c7edb3201b7 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -878,6 +878,9 @@ pub enum AttributeKind { /// Represents `#[rustc_lint_opt_ty]` RustcLintOptTy, + /// Represents `#[rustc_lint_query_instability]` + RustcLintQueryInstability, + /// Represents `#[rustc_main]`. RustcMain, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index e84fca61ac48..f99069e416bd 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -95,6 +95,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, RustcLintOptTy => Yes, + RustcLintQueryInstability => Yes, RustcMain => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 25f5710cca3a..c32fed3674fc 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -91,7 +91,7 @@ impl<'tcx> LateLintPass<'tcx> for QueryStability { ty::Instance::try_resolve(cx.tcx, cx.typing_env(), callee_def_id, generic_args) { let def_id = instance.def_id(); - if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { + if find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::RustcLintQueryInstability) { cx.emit_span_lint( POTENTIAL_QUERY_INSTABILITY, span, @@ -151,7 +151,10 @@ fn has_unstable_into_iter_predicate<'tcx>( }; // Does the input type's `IntoIterator` implementation have the // `rustc_lint_query_instability` attribute on its `into_iter` method? - if cx.tcx.has_attr(instance.def_id(), sym::rustc_lint_query_instability) { + if find_attr!( + cx.tcx.get_all_attrs(instance.def_id()), + AttributeKind::RustcLintQueryInstability + ) { return true; } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 00169cf6ae0c..d03da2e06cf1 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -259,6 +259,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcLintOptTy + | AttributeKind::RustcLintQueryInstability | AttributeKind::RustcNeverReturnsNullPointer | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) @@ -307,9 +308,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::rustc_lint_query_instability, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) - } [sym::rustc_lint_untracked_query_information, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } diff --git a/tests/ui/internal-lints/query_stability_incorrect.rs b/tests/ui/internal-lints/query_stability_incorrect.rs index a428611caaa4..cefd89867711 100644 --- a/tests/ui/internal-lints/query_stability_incorrect.rs +++ b/tests/ui/internal-lints/query_stability_incorrect.rs @@ -3,7 +3,7 @@ #![feature(rustc_attrs)] #[rustc_lint_query_instability] -//~^ ERROR attribute should be applied to a function +//~^ ERROR `#[rustc_lint_query_instability]` attribute cannot be used on structs struct Foo; impl Foo { diff --git a/tests/ui/internal-lints/query_stability_incorrect.stderr b/tests/ui/internal-lints/query_stability_incorrect.stderr index 3f78b39edd96..8149ac3b9518 100644 --- a/tests/ui/internal-lints/query_stability_incorrect.stderr +++ b/tests/ui/internal-lints/query_stability_incorrect.stderr @@ -1,17 +1,20 @@ -error: malformed `rustc_lint_query_instability` attribute input - --> $DIR/query_stability_incorrect.rs:10:5 - | -LL | #[rustc_lint_query_instability(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_query_instability]` - -error: attribute should be applied to a function definition +error: `#[rustc_lint_query_instability]` attribute cannot be used on structs --> $DIR/query_stability_incorrect.rs:5:1 | LL | #[rustc_lint_query_instability] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | struct Foo; - | ----------- not a function definition + | + = help: `#[rustc_lint_query_instability]` can only be applied to functions + +error[E0565]: malformed `rustc_lint_query_instability` attribute input + --> $DIR/query_stability_incorrect.rs:10:5 + | +LL | #[rustc_lint_query_instability(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[rustc_lint_query_instability]` error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0565`. From af3604e84e9a584adc5aefdfbea60f4a8802cec4 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Mon, 15 Dec 2025 17:06:56 +0000 Subject: [PATCH 0934/3801] Remove fp16 target feature from some aarch64 intrinsics This seems to affect codegen on a lot of Arm intrinsics so I've avoided making the change there. --- .../core_arch/src/aarch64/neon/generated.rs | 20 +- .../src/arm_shared/neon/generated.rs | 233 ++++++++++++------ .../spec/neon/aarch64.spec.yml | 3 - .../spec/neon/arm_shared.spec.yml | 82 +++--- 4 files changed, 207 insertions(+), 131 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index ce864cc7d907..f1291c8fbddf 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -7217,8 +7217,8 @@ pub fn vcvtq_f64_u64(a: uint64x2_t) -> float64x2_t { #[doc = "Floating-point convert to lower precision"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_high_f16_f32)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(test, assert_instr(fcvtn2))] -#[target_feature(enable = "neon,fp16")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vcvt_high_f16_f32(a: float16x4_t, b: float32x4_t) -> float16x8_t { @@ -7227,8 +7227,8 @@ pub fn vcvt_high_f16_f32(a: float16x4_t, b: float32x4_t) -> float16x8_t { #[doc = "Floating-point convert to higher precision"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_high_f32_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(test, assert_instr(fcvtl2))] -#[target_feature(enable = "neon,fp16")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vcvt_high_f32_f16(a: float16x8_t) -> float32x4_t { @@ -21492,7 +21492,7 @@ pub fn vrecpxh_f16(a: f16) -> f16 { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_f16)"] #[inline] #[cfg(target_endian = "little")] -#[target_feature(enable = "neon,fp16")] +#[target_feature(enable = "neon")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -21503,7 +21503,7 @@ pub fn vreinterpret_f64_f16(a: float16x4_t) -> float64x1_t { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f64_f16)"] #[inline] #[cfg(target_endian = "big")] -#[target_feature(enable = "neon,fp16")] +#[target_feature(enable = "neon")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -21515,7 +21515,7 @@ pub fn vreinterpret_f64_f16(a: float16x4_t) -> float64x1_t { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_f16)"] #[inline] #[cfg(target_endian = "little")] -#[target_feature(enable = "neon,fp16")] +#[target_feature(enable = "neon")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -21526,7 +21526,7 @@ pub fn vreinterpretq_f64_f16(a: float16x8_t) -> float64x2_t { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f64_f16)"] #[inline] #[cfg(target_endian = "big")] -#[target_feature(enable = "neon,fp16")] +#[target_feature(enable = "neon")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -21541,7 +21541,7 @@ pub fn vreinterpretq_f64_f16(a: float16x8_t) -> float64x2_t { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_f64)"] #[inline] #[cfg(target_endian = "little")] -#[target_feature(enable = "neon,fp16")] +#[target_feature(enable = "neon")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -21552,7 +21552,7 @@ pub fn vreinterpret_f16_f64(a: float64x1_t) -> float16x4_t { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpret_f16_f64)"] #[inline] #[cfg(target_endian = "big")] -#[target_feature(enable = "neon,fp16")] +#[target_feature(enable = "neon")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -21566,7 +21566,7 @@ pub fn vreinterpret_f16_f64(a: float64x1_t) -> float16x4_t { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_f64)"] #[inline] #[cfg(target_endian = "little")] -#[target_feature(enable = "neon,fp16")] +#[target_feature(enable = "neon")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -21577,7 +21577,7 @@ pub fn vreinterpretq_f16_f64(a: float64x2_t) -> float16x8_t { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vreinterpretq_f16_f64)"] #[inline] #[cfg(target_endian = "big")] -#[target_feature(enable = "neon,fp16")] +#[target_feature(enable = "neon")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index d45454c696c7..cfd9c201864c 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -7569,8 +7569,9 @@ pub fn vcntq_p8(a: poly8x16_t) -> poly8x16_t { #[doc = "Join two smaller vectors into a single larger vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcombine_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -7785,13 +7786,14 @@ pub fn vcombine_p64(a: poly64x1_t, b: poly64x1_t) -> poly64x2_t { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_f16)"] #[inline] #[cfg(target_endian = "little")] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(nop) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vcreate_f16(a: u64) -> float16x4_t { @@ -7801,13 +7803,14 @@ pub fn vcreate_f16(a: u64) -> float16x4_t { #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcreate_f16)"] #[inline] #[cfg(target_endian = "big")] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(nop) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vcreate_f16(a: u64) -> float16x4_t { @@ -8305,13 +8308,14 @@ pub fn vcreate_p64(a: u64) -> poly64x1_t { #[doc = "Floating-point convert to lower precision narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f16_f32)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] # [cfg_attr (all (test , target_arch = "arm") , assert_instr (vcvt . f16 . f32))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(fcvtn) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vcvt_f16_f32(a: float32x4_t) -> float16x4_t { @@ -8380,13 +8384,14 @@ pub fn vcvtq_f16_u16(a: uint16x8_t) -> float16x8_t { #[doc = "Floating-point convert to higher precision long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvt_f32_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(fcvtl) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vcvt_f32_f16(a: float16x4_t) -> float32x4_t { @@ -9545,6 +9550,7 @@ pub fn vdotq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x16_t) -> uint32x4_t { #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))] #[cfg_attr( @@ -9552,7 +9558,7 @@ pub fn vdotq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x16_t) -> uint32x4_t { assert_instr(dup, N = 2) )] #[rustc_legacy_const_generics(1)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vdup_lane_f16(a: float16x4_t) -> float16x4_t { @@ -9562,6 +9568,7 @@ pub fn vdup_lane_f16(a: float16x4_t) -> float16x4_t { #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 2))] #[cfg_attr( @@ -9569,7 +9576,7 @@ pub fn vdup_lane_f16(a: float16x4_t) -> float16x4_t { assert_instr(dup, N = 2) )] #[rustc_legacy_const_generics(1)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vdupq_lane_f16(a: float16x4_t) -> float16x8_t { @@ -10108,6 +10115,7 @@ pub fn vdup_lane_u64(a: uint64x1_t) -> uint64x1_t { #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))] #[cfg_attr( @@ -10115,7 +10123,7 @@ pub fn vdup_lane_u64(a: uint64x1_t) -> uint64x1_t { assert_instr(dup, N = 4) )] #[rustc_legacy_const_generics(1)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vdup_laneq_f16(a: float16x8_t) -> float16x4_t { @@ -10125,6 +10133,7 @@ pub fn vdup_laneq_f16(a: float16x8_t) -> float16x4_t { #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16", N = 4))] #[cfg_attr( @@ -10132,7 +10141,7 @@ pub fn vdup_laneq_f16(a: float16x8_t) -> float16x4_t { assert_instr(dup, N = 4) )] #[rustc_legacy_const_generics(1)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vdupq_laneq_f16(a: float16x8_t) -> float16x8_t { @@ -10671,13 +10680,14 @@ pub fn vdup_laneq_u64(a: uint64x2_t) -> uint64x1_t { #[doc = "Create a new vector with all lanes set to a value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(dup) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vdup_n_f16(a: f16) -> float16x4_t { @@ -10686,13 +10696,14 @@ pub fn vdup_n_f16(a: f16) -> float16x4_t { #[doc = "Create a new vector with all lanes set to a value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_n_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(dup) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vdupq_n_f16(a: f16) -> float16x8_t { @@ -12829,8 +12840,9 @@ pub fn vfmsq_n_f32(a: float32x4_t, b: float32x4_t, c: f32) -> float32x4_t { #[doc = "Duplicate vector element to vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_high_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -12840,8 +12852,9 @@ pub fn vget_high_f16(a: float16x8_t) -> float16x4_t { #[doc = "Duplicate vector element to vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_low_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(nop))] @@ -13082,14 +13095,15 @@ pub fn vget_high_u64(a: uint64x2_t) -> uint64x1_t { #[doc = "Duplicate vector element to scalar"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(nop, LANE = 0) )] #[rustc_legacy_const_generics(1)] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vget_lane_f16(a: float16x4_t) -> f16 { @@ -13099,14 +13113,15 @@ pub fn vget_lane_f16(a: float16x4_t) -> f16 { #[doc = "Duplicate vector element to scalar"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vgetq_lane_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(nop, LANE = 0) )] #[rustc_legacy_const_generics(1)] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vgetq_lane_f16(a: float16x8_t) -> f16 { @@ -14457,13 +14472,14 @@ pub fn vhsubq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld1r) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1_dup_f16(ptr: *const f16) -> float16x4_t { @@ -14475,13 +14491,14 @@ pub unsafe fn vld1_dup_f16(ptr: *const f16) -> float16x4_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld1r) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1q_dup_f16(ptr: *const f16) -> float16x8_t { @@ -15123,13 +15140,14 @@ pub unsafe fn vld1q_f16(ptr: *const f16) -> float16x8_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld1) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1_f16_x2(a: *const f16) -> float16x4x2_t { @@ -15148,13 +15166,14 @@ pub unsafe fn vld1_f16_x2(a: *const f16) -> float16x4x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld1) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1_f16_x3(a: *const f16) -> float16x4x3_t { @@ -15173,13 +15192,14 @@ pub unsafe fn vld1_f16_x3(a: *const f16) -> float16x4x3_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld1) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1_f16_x4(a: *const f16) -> float16x4x4_t { @@ -15198,13 +15218,14 @@ pub unsafe fn vld1_f16_x4(a: *const f16) -> float16x4x4_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld1) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1q_f16_x2(a: *const f16) -> float16x8x2_t { @@ -15223,13 +15244,14 @@ pub unsafe fn vld1q_f16_x2(a: *const f16) -> float16x8x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld1) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1q_f16_x3(a: *const f16) -> float16x8x3_t { @@ -15248,13 +15270,14 @@ pub unsafe fn vld1q_f16_x3(a: *const f16) -> float16x8x3_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld1) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1q_f16_x4(a: *const f16) -> float16x8x4_t { @@ -15654,6 +15677,7 @@ pub unsafe fn vld1q_f32_x4(a: *const f32) -> float32x4x4_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1, LANE = 0))] #[cfg_attr( @@ -15661,7 +15685,7 @@ pub unsafe fn vld1q_f32_x4(a: *const f32) -> float32x4x4_t { assert_instr(ld1, LANE = 0) )] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1_lane_f16(ptr: *const f16, src: float16x4_t) -> float16x4_t { @@ -15673,6 +15697,7 @@ pub unsafe fn vld1_lane_f16(ptr: *const f16, src: float16x4_t) #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld1, LANE = 0))] #[cfg_attr( @@ -15680,7 +15705,7 @@ pub unsafe fn vld1_lane_f16(ptr: *const f16, src: float16x4_t) assert_instr(ld1, LANE = 0) )] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld1q_lane_f16(ptr: *const f16, src: float16x8_t) -> float16x8_t { @@ -19458,9 +19483,10 @@ pub unsafe fn vld1q_dup_p64(ptr: *const p64) -> poly64x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] @@ -19476,9 +19502,10 @@ pub unsafe fn vld2_dup_f16(a: *const f16) -> float16x4x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg(target_arch = "arm")] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] @@ -19494,12 +19521,13 @@ pub unsafe fn vld2q_dup_f16(a: *const f16) -> float16x8x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld2r) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2_dup_f16(a: *const f16) -> float16x4x2_t { @@ -19517,12 +19545,13 @@ pub unsafe fn vld2_dup_f16(a: *const f16) -> float16x4x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld2r) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2q_dup_f16(a: *const f16) -> float16x8x2_t { @@ -20435,10 +20464,11 @@ pub unsafe fn vld2q_dup_p16(a: *const p16) -> poly16x8x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2_f16(a: *const f16) -> float16x4x2_t { @@ -20453,10 +20483,11 @@ pub unsafe fn vld2_f16(a: *const f16) -> float16x4x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2q_f16(a: *const f16) -> float16x8x2_t { @@ -20471,12 +20502,13 @@ pub unsafe fn vld2q_f16(a: *const f16) -> float16x8x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld2) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2_f16(a: *const f16) -> float16x4x2_t { @@ -20494,12 +20526,13 @@ pub unsafe fn vld2_f16(a: *const f16) -> float16x4x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld2) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2q_f16(a: *const f16) -> float16x8x2_t { @@ -20801,7 +20834,7 @@ pub unsafe fn vld2q_s32(a: *const i32) -> int32x4x2_t { #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2_lane_f16(a: *const f16, b: float16x4x2_t) -> float16x4x2_t { @@ -20827,7 +20860,7 @@ pub unsafe fn vld2_lane_f16(a: *const f16, b: float16x4x2_t) -> #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld2, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2q_lane_f16(a: *const f16, b: float16x8x2_t) -> float16x8x2_t { @@ -20849,13 +20882,14 @@ pub unsafe fn vld2q_lane_f16(a: *const f16, b: float16x8x2_t) - #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld2, LANE = 0) )] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2_lane_f16(a: *const f16, b: float16x4x2_t) -> float16x4x2_t { @@ -20875,13 +20909,14 @@ pub unsafe fn vld2_lane_f16(a: *const f16, b: float16x4x2_t) -> #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld2, LANE = 0) )] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld2q_lane_f16(a: *const f16, b: float16x8x2_t) -> float16x8x2_t { @@ -22031,10 +22066,11 @@ pub unsafe fn vld2q_p16(a: *const p16) -> poly16x8x2_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3_dup_f16(a: *const f16) -> float16x4x3_t { @@ -22049,10 +22085,11 @@ pub unsafe fn vld3_dup_f16(a: *const f16) -> float16x4x3_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3q_dup_f16(a: *const f16) -> float16x8x3_t { @@ -22067,12 +22104,13 @@ pub unsafe fn vld3q_dup_f16(a: *const f16) -> float16x8x3_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld3r) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3_dup_f16(a: *const f16) -> float16x4x3_t { @@ -22090,12 +22128,13 @@ pub unsafe fn vld3_dup_f16(a: *const f16) -> float16x4x3_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld3r) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3q_dup_f16(a: *const f16) -> float16x8x3_t { @@ -23030,10 +23069,11 @@ pub unsafe fn vld3q_dup_p16(a: *const p16) -> poly16x8x3_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3_f16(a: *const f16) -> float16x4x3_t { @@ -23048,10 +23088,11 @@ pub unsafe fn vld3_f16(a: *const f16) -> float16x4x3_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3q_f16(a: *const f16) -> float16x8x3_t { @@ -23066,12 +23107,13 @@ pub unsafe fn vld3q_f16(a: *const f16) -> float16x8x3_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld3) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3_f16(a: *const f16) -> float16x4x3_t { @@ -23089,12 +23131,13 @@ pub unsafe fn vld3_f16(a: *const f16) -> float16x4x3_t { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld3) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3q_f16(a: *const f16) -> float16x8x3_t { @@ -23396,7 +23439,7 @@ pub unsafe fn vld3q_s32(a: *const i32) -> int32x4x3_t { #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3_lane_f16(a: *const f16, b: float16x4x3_t) -> float16x4x3_t { @@ -23423,7 +23466,7 @@ pub unsafe fn vld3_lane_f16(a: *const f16, b: float16x4x3_t) -> #[cfg(target_arch = "arm")] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(vld3, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3q_lane_f16(a: *const f16, b: float16x8x3_t) -> float16x8x3_t { @@ -23446,13 +23489,14 @@ pub unsafe fn vld3q_lane_f16(a: *const f16, b: float16x8x3_t) - #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld3, LANE = 0) )] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3_lane_f16(a: *const f16, b: float16x4x3_t) -> float16x4x3_t { @@ -23477,13 +23521,14 @@ pub unsafe fn vld3_lane_f16(a: *const f16, b: float16x4x3_t) -> #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(ld3, LANE = 0) )] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vld3q_lane_f16(a: *const f16, b: float16x8x3_t) -> float16x8x3_t { @@ -31524,13 +31569,14 @@ pub fn vmmlaq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x16_t) -> uint32x4_t { #[doc = "Duplicate element to vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmov_n_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(dup) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vmov_n_f16(a: f16) -> float16x4_t { @@ -31539,13 +31585,14 @@ pub fn vmov_n_f16(a: f16) -> float16x4_t { #[doc = "Duplicate element to vector"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmovq_n_f16)"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr("vdup.16"))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(dup) )] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub fn vmovq_n_f16(a: f16) -> float16x8_t { @@ -63675,9 +63722,10 @@ pub unsafe fn vst1q_f16_x3(a: *mut f16, b: float16x8x3_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(vst1))] @@ -63699,9 +63747,10 @@ pub unsafe fn vst1_f16_x4(a: *mut f16, b: float16x4x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(vst1))] @@ -64313,6 +64362,7 @@ pub unsafe fn vst1q_f32_x4(a: *mut f32, b: float32x4x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))] #[cfg_attr( @@ -64320,7 +64370,7 @@ pub unsafe fn vst1q_f32_x4(a: *mut f32, b: float32x4x4_t) { assert_instr(nop, LANE = 0) )] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst1_lane_f16(a: *mut f16, b: float16x4_t) { @@ -64332,6 +64382,7 @@ pub unsafe fn vst1_lane_f16(a: *mut f16, b: float16x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop, LANE = 0))] #[cfg_attr( @@ -64339,7 +64390,7 @@ pub unsafe fn vst1_lane_f16(a: *mut f16, b: float16x4_t) { assert_instr(nop, LANE = 0) )] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst1q_lane_f16(a: *mut f16, b: float16x8_t) { @@ -66933,8 +66984,9 @@ pub unsafe fn vst1q_lane_p64(a: *mut p64, b: poly64x2_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(st2))] @@ -66953,8 +67005,9 @@ pub unsafe fn vst2_f16(a: *mut f16, b: float16x4x2_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(st2))] @@ -66973,9 +67026,10 @@ pub unsafe fn vst2q_f16(a: *mut f16, b: float16x8x2_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(vst2))] @@ -66991,9 +67045,10 @@ pub unsafe fn vst2_f16(a: *mut f16, b: float16x4x2_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(vst2))] @@ -67289,10 +67344,11 @@ pub unsafe fn vst2q_s32(a: *mut i32, b: int32x4x2_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(st2, LANE = 0))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst2_lane_f16(a: *mut f16, b: float16x4x2_t) { @@ -67311,10 +67367,11 @@ pub unsafe fn vst2_lane_f16(a: *mut f16, b: float16x4x2_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(st2, LANE = 0))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst2q_lane_f16(a: *mut f16, b: float16x8x2_t) { @@ -67333,11 +67390,12 @@ pub unsafe fn vst2q_lane_f16(a: *mut f16, b: float16x8x2_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(test, assert_instr(vst2, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst2_lane_f16(a: *mut f16, b: float16x4x2_t) { @@ -67353,11 +67411,12 @@ pub unsafe fn vst2_lane_f16(a: *mut f16, b: float16x4x2_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(test, assert_instr(vst2, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst2q_lane_f16(a: *mut f16, b: float16x8x2_t) { @@ -68157,9 +68216,10 @@ pub unsafe fn vst2q_p16(a: *mut p16, b: poly16x8x2_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(vst3))] @@ -68175,9 +68235,10 @@ pub unsafe fn vst3_f16(a: *mut f16, b: float16x4x3_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(vst3))] @@ -68193,8 +68254,9 @@ pub unsafe fn vst3q_f16(a: *mut f16, b: float16x8x3_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(st3))] @@ -68213,8 +68275,9 @@ pub unsafe fn vst3_f16(a: *mut f16, b: float16x4x3_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(st3))] @@ -68513,11 +68576,12 @@ pub unsafe fn vst3q_s32(a: *mut i32, b: int32x4x3_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(test, assert_instr(vst3, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst3_lane_f16(a: *mut f16, b: float16x4x3_t) { @@ -68540,11 +68604,12 @@ pub unsafe fn vst3_lane_f16(a: *mut f16, b: float16x4x3_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(test, assert_instr(vst3, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst3q_lane_f16(a: *mut f16, b: float16x8x3_t) { @@ -68567,10 +68632,11 @@ pub unsafe fn vst3q_lane_f16(a: *mut f16, b: float16x8x3_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(st3, LANE = 0))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst3_lane_f16(a: *mut f16, b: float16x4x3_t) { @@ -68589,10 +68655,11 @@ pub unsafe fn vst3_lane_f16(a: *mut f16, b: float16x4x3_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(st3, LANE = 0))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst3q_lane_f16(a: *mut f16, b: float16x8x3_t) { @@ -69437,9 +69504,10 @@ pub unsafe fn vst3q_p16(a: *mut p16, b: poly16x8x3_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(vst4))] @@ -69462,9 +69530,10 @@ pub unsafe fn vst4_f16(a: *mut f16, b: float16x4x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(vst4))] @@ -69487,8 +69556,9 @@ pub unsafe fn vst4q_f16(a: *mut f16, b: float16x8x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(st4))] @@ -69507,8 +69577,9 @@ pub unsafe fn vst4_f16(a: *mut f16, b: float16x4x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(st4))] @@ -69856,11 +69927,12 @@ pub unsafe fn vst4q_s32(a: *mut i32, b: int32x4x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(test, assert_instr(vst4, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst4_lane_f16(a: *mut f16, b: float16x4x4_t) { @@ -69884,11 +69956,12 @@ pub unsafe fn vst4_lane_f16(a: *mut f16, b: float16x4x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(target_arch = "arm")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] #[cfg_attr(test, assert_instr(vst4, LANE = 0))] #[rustc_legacy_const_generics(2)] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst4q_lane_f16(a: *mut f16, b: float16x8x4_t) { @@ -69912,10 +69985,11 @@ pub unsafe fn vst4q_lane_f16(a: *mut f16, b: float16x8x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(st4, LANE = 0))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst4_lane_f16(a: *mut f16, b: float16x4x4_t) { @@ -69941,10 +70015,11 @@ pub unsafe fn vst4_lane_f16(a: *mut f16, b: float16x4x4_t) { #[doc = "## Safety"] #[doc = " * Neon instrinsic unsafe"] #[inline] +#[target_feature(enable = "neon")] #[cfg(not(target_arch = "arm"))] #[rustc_legacy_const_generics(2)] #[cfg_attr(test, assert_instr(st4, LANE = 0))] -#[target_feature(enable = "neon,fp16")] +#[cfg_attr(target_arch = "arm", target_feature(enable = "fp16"))] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] pub unsafe fn vst4q_lane_f16(a: *mut f16, b: float16x8x4_t) { diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index 48c12779a8c1..f3faf1483827 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -1506,7 +1506,6 @@ intrinsics: return_type: "{neon_type[0]}" attr: - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fcvtn2]]}]] - - *neon-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: safe @@ -1524,7 +1523,6 @@ intrinsics: return_type: "{neon_type[0]}" attr: - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fcvtl2]]}]] - - *neon-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: safe @@ -8793,7 +8791,6 @@ intrinsics: arguments: ["a: {type[0]}"] return_type: "{type[1]}" attr: - - *neon-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [nop] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 9ebdc4334c25..9727f0a4bbe4 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -71,6 +71,10 @@ neon-i8mm: &neon-i8mm neon-fp16: &neon-fp16 FnCall: [target_feature, ['enable = "neon,fp16"']] +# #[cfg_attr[target_arch = "arm", target_feature(enable = "neon,fp16")] +arm-fp16: &arm-fp16 + FnCall: [cfg_attr, ['target_arch = "arm"', {FnCall: [target_feature, ['enable = "fp16"']]}]] + enable-fcma: &enable-fcma FnCall: [cfg_attr, [{ FnCall: [not, ['target_arch = "arm"']]}, { FnCall: [target_feature, ['enable = "fcma"']] }]] @@ -1502,7 +1506,7 @@ intrinsics: - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"', 'N = 4']]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 4']]}]] - FnCall: [rustc_legacy_const_generics, ['1']] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const N: i32'] @@ -1522,7 +1526,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"']]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: safe @@ -1541,7 +1545,7 @@ intrinsics: - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"', 'N = 2']]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 2']]}]] - FnCall: [rustc_legacy_const_generics, ['1']] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const N: i32'] @@ -2754,7 +2758,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld1]]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld1]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: @@ -2785,7 +2789,7 @@ intrinsics: - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld1, 'LANE = 0']]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld1, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ["2"]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const LANE: i32'] @@ -2806,7 +2810,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ["vld1"]]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld1r]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: @@ -3399,7 +3403,7 @@ intrinsics: - *neon-v7 - *target-is-arm - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld2]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: @@ -3428,7 +3432,7 @@ intrinsics: attr: - *target-not-arm - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: @@ -3455,7 +3459,7 @@ intrinsics: attr: - *neon-v7 - *target-is-arm - - *neon-fp16 + - *arm-fp16 - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld2]]}]] - *neon-unstable-f16 - *target-not-arm64ec @@ -3486,7 +3490,7 @@ intrinsics: attr: - *target-not-arm - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2r]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: @@ -3516,7 +3520,7 @@ intrinsics: - *target-is-arm - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['vld2', 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ["2"]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: @@ -3559,7 +3563,7 @@ intrinsics: - *target-not-arm - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ["2"]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: @@ -3600,7 +3604,7 @@ intrinsics: - *neon-v7 - *target-is-arm - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld3]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: @@ -3629,7 +3633,7 @@ intrinsics: attr: - *target-not-arm - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: @@ -3657,7 +3661,7 @@ intrinsics: - *neon-v7 - *target-is-arm - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld3]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: @@ -3687,7 +3691,7 @@ intrinsics: attr: - *target-not-arm - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3r]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: @@ -3717,7 +3721,7 @@ intrinsics: - *target-is-arm - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['vld3', 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ["2"]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: @@ -3762,7 +3766,7 @@ intrinsics: - *target-not-arm - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ["2"]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: @@ -4744,7 +4748,7 @@ intrinsics: - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ["2"]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec types: @@ -4982,7 +4986,7 @@ intrinsics: attr: - *target-is-arm - *neon-v7 - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [vst1] @@ -5126,7 +5130,7 @@ intrinsics: arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"] attr: - *target-not-arm - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [st2] @@ -5217,7 +5221,7 @@ intrinsics: - *target-not-arm - FnCall: [rustc_legacy_const_generics, ['2']] - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st2, 'LANE = 0']]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const LANE: i32'] @@ -5309,7 +5313,7 @@ intrinsics: attr: - *target-is-arm - *neon-v7 - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [vst2] @@ -5376,7 +5380,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst2, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['2']] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const LANE: i32'] @@ -5587,7 +5591,7 @@ intrinsics: attr: - *target-is-arm - *neon-v7 - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [vst3] @@ -5656,7 +5660,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst3, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['2']] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const LANE: i32'] @@ -5717,7 +5721,7 @@ intrinsics: arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"] attr: - *target-not-arm - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [st3] @@ -5782,7 +5786,7 @@ intrinsics: - *target-not-arm - FnCall: [rustc_legacy_const_generics, ['2']] - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st3, 'LANE = 0']]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const LANE: i32'] @@ -5996,7 +6000,7 @@ intrinsics: attr: - *target-is-arm - *neon-v7 - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [vst4] @@ -6066,7 +6070,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst4, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['2']] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const LANE: i32'] @@ -6129,7 +6133,7 @@ intrinsics: arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"] attr: - *target-not-arm - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [st4] @@ -6196,7 +6200,7 @@ intrinsics: - *target-not-arm - FnCall: [rustc_legacy_const_generics, ['2']] - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st4, 'LANE = 0']]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const LANE: i32'] @@ -9139,7 +9143,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: safe @@ -10730,7 +10734,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt.f16.f32]]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtn]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: safe @@ -10747,7 +10751,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtl]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: safe @@ -14055,7 +14059,7 @@ intrinsics: return_type: "{neon_type[1]}" attr: - *neon-v7 - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [nop] @@ -14071,7 +14075,7 @@ intrinsics: return_type: "{neon_type[0]}" attr: - *neon-v7 - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec assert_instr: [nop] @@ -14088,10 +14092,10 @@ intrinsics: return_type: "{type[1]}" attr: - *neon-v7 - - *neon-fp16 - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ["1"]] + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec static_defs: ['const LANE: i32'] @@ -14111,7 +14115,7 @@ intrinsics: - *neon-v7 - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"']]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup]]}]] - - *neon-fp16 + - *arm-fp16 - *neon-unstable-f16 - *target-not-arm64ec safety: safe From 2c15ae530f03c0577435f87dffa249f2010e00af Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Tue, 16 Dec 2025 11:24:11 +0000 Subject: [PATCH 0935/3801] Fix some Arm instruction assertion tests --- .../crates/core_arch/src/aarch64/neon/generated.rs | 10 +++++----- .../crates/core_arch/src/arm_shared/neon/generated.rs | 2 +- .../crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml | 8 ++++---- .../stdarch-gen-arm/spec/neon/arm_shared.spec.yml | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index f1291c8fbddf..0c703916c136 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -9487,7 +9487,7 @@ pub fn vdivq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t { #[target_feature(enable = "neon,fp16")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] -#[cfg_attr(test, assert_instr(nop))] +#[cfg_attr(test, assert_instr(fdiv))] pub fn vdivh_f16(a: f16, b: f16) -> f16 { a / b } @@ -14829,7 +14829,7 @@ pub fn vmuld_lane_f64(a: f64, b: float64x1_t) -> f64 { #[target_feature(enable = "neon,fp16")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] -#[cfg_attr(test, assert_instr(nop))] +#[cfg_attr(test, assert_instr(fmul))] pub fn vmulh_f16(a: f16, b: f16) -> f16 { a * b } @@ -26719,7 +26719,7 @@ pub fn vsubq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t { #[inline] #[target_feature(enable = "neon")] #[stable(feature = "neon_intrinsics", since = "1.59.0")] -#[cfg_attr(test, assert_instr(nop))] +#[cfg_attr(test, assert_instr(sub))] pub fn vsubd_s64(a: i64, b: i64) -> i64 { a.wrapping_sub(b) } @@ -26728,7 +26728,7 @@ pub fn vsubd_s64(a: i64, b: i64) -> i64 { #[inline] #[target_feature(enable = "neon")] #[stable(feature = "neon_intrinsics", since = "1.59.0")] -#[cfg_attr(test, assert_instr(nop))] +#[cfg_attr(test, assert_instr(sub))] pub fn vsubd_u64(a: u64, b: u64) -> u64 { a.wrapping_sub(b) } @@ -26738,7 +26738,7 @@ pub fn vsubd_u64(a: u64, b: u64) -> u64 { #[target_feature(enable = "neon,fp16")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg(not(target_arch = "arm64ec"))] -#[cfg_attr(test, assert_instr(nop))] +#[cfg_attr(test, assert_instr(fsub))] pub fn vsubh_f16(a: f16, b: f16) -> f16 { a - b } diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index cfd9c201864c..314965cc208f 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -8310,7 +8310,7 @@ pub fn vcreate_p64(a: u64) -> poly64x1_t { #[inline] #[target_feature(enable = "neon")] #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))] -# [cfg_attr (all (test , target_arch = "arm") , assert_instr (vcvt . f16 . f32))] +#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))] #[cfg_attr( all(test, any(target_arch = "aarch64", target_arch = "arm64ec")), assert_instr(fcvtn) diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index f3faf1483827..42f716874b37 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -5669,7 +5669,7 @@ intrinsics: - *neon-fp16 - *neon-unstable-f16 - *target-not-arm64ec - assert_instr: [nop] + assert_instr: [fdiv] safety: safe types: - [f16, 'h'] @@ -5694,7 +5694,7 @@ intrinsics: arguments: ["a: {type[1]}", "b: {type[1]}"] return_type: "{type[1]}" attr: [*neon-stable] - assert_instr: [nop] + assert_instr: [sub] safety: safe types: - ['d_s64', 'i64'] @@ -5710,7 +5710,7 @@ intrinsics: - *neon-fp16 - *neon-unstable-f16 - *target-not-arm64ec - assert_instr: [nop] + assert_instr: [fsub] safety: safe types: - ['h_f16', 'f16'] @@ -11271,7 +11271,7 @@ intrinsics: - *neon-fp16 - *neon-unstable-f16 - *target-not-arm64ec - assert_instr: [nop] + assert_instr: [fmul] safety: safe types: - [f16, 'h'] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 9727f0a4bbe4..e8b31d73f939 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -10732,7 +10732,7 @@ intrinsics: return_type: "{neon_type[1]}" attr: - *neon-v7 - - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt.f16.f32]]}]] + - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]] - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtn]]}]] - *arm-fp16 - *neon-unstable-f16 From 15069c2a378e2e5c954cafdaca61cef3c7ce6e57 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 2 Jun 2025 11:51:40 -0700 Subject: [PATCH 0936/3801] Implement SetFileInformationByHandle, as well as direct shim test for it --- .../miri/src/shims/windows/foreign_items.rs | 6 ++ src/tools/miri/src/shims/windows/fs.rs | 85 +++++++++++++++++++ .../miri/tests/pass-dep/shims/windows-fs.rs | 35 +++++++- src/tools/miri/tests/pass/shims/fs.rs | 13 ++- 4 files changed, 133 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index c824147ad4be..7d30582c582c 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -307,6 +307,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = this.GetFileInformationByHandle(handle, info)?; this.write_scalar(res, dest)?; } + "SetFileInformationByHandle" => { + let [handle, class, info, size] = + this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; + let res = this.SetFileInformationByHandle(handle, class, info, size)?; + this.write_scalar(res, dest)?; + } "DeleteFileW" => { let [file_name] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; let res = this.DeleteFileW(file_name)?; diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs index ad22df2425af..967164cb250d 100644 --- a/src/tools/miri/src/shims/windows/fs.rs +++ b/src/tools/miri/src/shims/windows/fs.rs @@ -5,6 +5,7 @@ use std::path::PathBuf; use std::time::SystemTime; use bitflags::bitflags; +use rustc_abi::Size; use rustc_target::spec::Os; use crate::shims::files::{FdId, FileDescription, FileHandle}; @@ -372,6 +373,90 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(this.eval_windows("c", "TRUE")) } + fn SetFileInformationByHandle( + &mut self, + file: &OpTy<'tcx>, // HANDLE + class: &OpTy<'tcx>, // FILE_INFO_BY_HANDLE_CLASS + file_information: &OpTy<'tcx>, // LPVOID + buffer_size: &OpTy<'tcx>, // DWORD + ) -> InterpResult<'tcx, Scalar> { + // ^ Returns BOOL (i32 on Windows) + let this = self.eval_context_mut(); + this.assert_target_os(Os::Windows, "SetFileInformationByHandle"); + this.check_no_isolation("`SetFileInformationByHandle`")?; + + let class = this.read_scalar(class)?.to_u32()?; + let buffer_size = this.read_scalar(buffer_size)?.to_u32()?; + let file_information = this.read_pointer(file_information)?; + this.check_ptr_access( + file_information, + Size::from_bytes(buffer_size), + CheckInAllocMsg::MemoryAccess, + )?; + + let file = this.read_handle(file, "SetFileInformationByHandle")?; + let Handle::File(fd_num) = file else { this.invalid_handle("SetFileInformationByHandle")? }; + let Some(desc) = this.machine.fds.get(fd_num) else { + this.invalid_handle("SetFileInformationByHandle")? + }; + let file = desc.downcast::().ok_or_else(|| { + err_unsup_format!( + "`SetFileInformationByHandle` is only supported on file-backed file descriptors" + ) + })?; + + if class == this.eval_windows_u32("c", "FileEndOfFileInfo") { + let place = this + .ptr_to_mplace(file_information, this.windows_ty_layout("FILE_END_OF_FILE_INFO")); + let new_len = + this.read_scalar(&this.project_field_named(&place, "EndOfFile")?)?.to_i64()?; + match file.file.set_len(new_len.try_into().unwrap()) { + Ok(_) => interp_ok(this.eval_windows("c", "TRUE")), + Err(e) => { + this.set_last_error(e)?; + interp_ok(this.eval_windows("c", "FALSE")) + } + } + } else if class == this.eval_windows_u32("c", "FileAllocationInfo") { + // On Windows, files are somewhat similar to a `Vec` in that they have a separate + // "length" (called "EOF position") and "capacity" (called "allocation size"). + // Growing the allocation size is largely a performance hint which we can + // ignore -- it can also be directly queried, but we currently do not support that. + // So we only need to do something if this operation shrinks the allocation size + // so far that it affects the EOF position. + let place = this + .ptr_to_mplace(file_information, this.windows_ty_layout("FILE_ALLOCATION_INFO")); + let new_alloc_size: u64 = this + .read_scalar(&this.project_field_named(&place, "AllocationSize")?)? + .to_i64()? + .try_into() + .unwrap(); + let old_len = match file.file.metadata() { + Ok(m) => m.len(), + Err(e) => { + this.set_last_error(e)?; + return interp_ok(this.eval_windows("c", "FALSE")); + } + }; + if new_alloc_size < old_len { + match file.file.set_len(new_alloc_size) { + Ok(_) => interp_ok(this.eval_windows("c", "TRUE")), + Err(e) => { + this.set_last_error(e)?; + interp_ok(this.eval_windows("c", "FALSE")) + } + } + } else { + interp_ok(this.eval_windows("c", "TRUE")) + } + } else { + throw_unsup_format!( + "SetFileInformationByHandle: Unsupported `FileInformationClass` value {}", + class + ) + } + } + fn DeleteFileW( &mut self, file_name: &OpTy<'tcx>, // LPCWSTR diff --git a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs index 7b756603d929..0037f34d3c9a 100644 --- a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs +++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs @@ -19,9 +19,11 @@ use windows_sys::Win32::Foundation::{ }; use windows_sys::Win32::Storage::FileSystem::{ BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, DeleteFileW, - FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, FILE_BEGIN, FILE_CURRENT, - FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, FILE_SHARE_DELETE, FILE_SHARE_READ, - FILE_SHARE_WRITE, GetFileInformationByHandle, OPEN_ALWAYS, OPEN_EXISTING, SetFilePointerEx, + FILE_ALLOCATION_INFO, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, FILE_BEGIN, + FILE_CURRENT, FILE_END_OF_FILE_INFO, FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, + FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, FileAllocationInfo, FileEndOfFileInfo, + GetFileInformationByHandle, OPEN_ALWAYS, OPEN_EXISTING, SetFileInformationByHandle, + SetFilePointerEx, }; use windows_sys::Win32::System::IO::IO_STATUS_BLOCK; use windows_sys::Win32::System::Threading::GetCurrentProcess; @@ -37,6 +39,7 @@ fn main() { test_ntstatus_to_dos(); test_file_read_write(); test_file_seek(); + test_set_file_info(); test_dup_handle(); } } @@ -275,6 +278,32 @@ unsafe fn test_file_read_write() { assert_eq!(GetLastError(), 1234); } +unsafe fn test_set_file_info() { + let temp = utils::tmp().join("test_set_file.txt"); + let mut file = fs::File::create(&temp).unwrap(); + let handle = file.as_raw_handle(); + + let info = FILE_END_OF_FILE_INFO { EndOfFile: 20 }; + let res = SetFileInformationByHandle( + handle, + FileEndOfFileInfo, + ptr::from_ref(&info).cast(), + size_of::().try_into().unwrap(), + ); + assert!(res != 0); + assert_eq!(file.seek(SeekFrom::End(0)).unwrap(), 20); + + let info = FILE_ALLOCATION_INFO { AllocationSize: 0 }; + let res = SetFileInformationByHandle( + handle, + FileAllocationInfo, + ptr::from_ref(&info).cast(), + size_of::().try_into().unwrap(), + ); + assert!(res != 0); + assert_eq!(file.metadata().unwrap().len(), 0); +} + unsafe fn test_dup_handle() { let temp = utils::tmp().join("test_dup.txt"); diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 43fbf6b085f7..70bca703cc2f 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -28,9 +28,9 @@ fn main() { test_errors(); test_from_raw_os_error(); test_file_clone(); + test_file_set_len(); // Windows file handling is very incomplete. if cfg!(not(windows)) { - test_file_set_len(); test_file_sync(); test_rename(); test_directory(); @@ -77,6 +77,9 @@ fn test_file() { // However, writing 0 bytes can succeed or fail. let _ignore = file.write(&[]); + // Test calling File::create on an existing file, since that uses a different code path + File::create(&path).unwrap(); + // Removing file should succeed. remove_file(&path).unwrap(); } @@ -87,7 +90,6 @@ fn test_file_partial_reads_writes() { // Ensure we sometimes do incomplete writes. check_nondet(|| { - let _ = remove_file(&path1); // FIXME(win, issue #4483): errors if the file already exists let mut file = File::create(&path1).unwrap(); file.write(&[0; 4]).unwrap() == 4 }); @@ -210,7 +212,12 @@ fn test_file_set_len() { // Can't use set_len on a file not opened for writing let file = OpenOptions::new().read(true).open(&path).unwrap(); - assert_eq!(ErrorKind::InvalidInput, file.set_len(14).unwrap_err().kind()); + // Due to https://github.com/rust-lang/miri/issues/4457, we have to assume the failure could + // be either of the Windows or Unix kind, no matter which platform we're on. + assert!( + [ErrorKind::PermissionDenied, ErrorKind::InvalidInput] + .contains(&file.set_len(14).unwrap_err().kind()) + ); remove_file(&path).unwrap(); } From 977bf0a134609bd601343023bbb561137392f18f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 17 Dec 2025 20:29:58 +0200 Subject: [PATCH 0937/3801] crash test readme: point to rustc-dev-guide There is information that is duplicated here and in rustc-dev-guide, and the latter is more comprehensive, so point there. --- tests/crashes/README.md | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/tests/crashes/README.md b/tests/crashes/README.md index 2dc81a115df3..8026b7c2463c 100644 --- a/tests/crashes/README.md +++ b/tests/crashes/README.md @@ -1,25 +1 @@ -This is serves as a collection of crashes so that accidental ICE fixes are tracked. -This was formally done at https://github.com/rust-lang/glacier but doing it inside -the rustc testsuite is more convenient. - -It is imperative that a test in the suite causes an internal compiler error/panic -or makes rustc crash in some other way. -A test will "pass" if rustc exits with something other than 1 or 0. - -When adding crashes from https://github.com/rust-lang/rust/issues, the -issue number should be noted in the file name (12345.rs should suffice) -and also inside the file via `//@ known-bug #4321` if possible. - -If you happen to fix one of the crashes, please move it to a fitting -subdirectory in `tests/ui` and give it a meaningful name. -Also please add a doc comment at the top of the file explaining why -this test exists. :) -Adding -Fixes #NNNNN -Fixes #MMMMM -to the description of your pull request will ensure the -corresponding tickets will be closed automatically upon merge. -The ticket ids can be found in the file name or the `known-bug` annotation -inside the testfile. - -Please do not re-report any crashes that you find here! +Documentation on crash tests is at https://rustc-dev-guide.rust-lang.org/tests/compiletest#crash-tests From d5061a86172e73a33b43f50edc5b144ffa7cc556 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 17 Dec 2025 21:03:53 +0200 Subject: [PATCH 0938/3801] make date-check entries clickable --- src/doc/rustc-dev-guide/ci/date-check/src/main.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/date-check/src/main.rs b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs index 0a32f4e9b7b6..bdf727b09ebe 100644 --- a/src/doc/rustc-dev-guide/ci/date-check/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs @@ -153,9 +153,13 @@ fn main() { println!(); for (path, dates) in dates_by_file { - println!("- {}", path.strip_prefix(&root_dir_path).unwrap_or(&path).display(),); + let path = path.strip_prefix(&root_dir_path).unwrap_or(&path).display(); + println!("- {path}"); for (line, date) in dates { - println!(" - [ ] line {}: {}", line, date); + let url = format!( + "https://github.com/rust-lang/rustc-dev-guide/blob/main/{path}?plain=1#L{line}" + ); + println!(" - [ ] [{date}]({url})"); } } println!(); From 67bd5f5cfdd3d29cd302d1cc535f8d0ea2c6e351 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 17 Dec 2025 20:19:28 +0100 Subject: [PATCH 0939/3801] Prefer remapping the relative `library/` and `compiler/` directories This is done to avoid leaking the relative paths to the standard library after the overall of filenames. Noted that the paths were already leaking before, but to a lesser extent since the paths embedded in the distributed `rlib` were absolute. In general Cargo compiles workspace members with relative paths, so it's better anyway to remap the relative path. cf https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/remapping.20of.20the.20standard.20library/near/564093571 --- src/bootstrap/src/core/builder/cargo.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 5a6bade59a6a..4697de7ffe0d 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -1032,10 +1032,7 @@ impl Builder<'_> { self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::Compiler) { // When building compiler sources, we want to apply the compiler remap scheme. - cargo.env( - "RUSTC_DEBUGINFO_MAP", - format!("{}={}", self.build.src.display(), map_to), - ); + cargo.env("RUSTC_DEBUGINFO_MAP", format!("compiler/={map_to}/compiler")); cargo.env("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR", map_to); } } @@ -1047,10 +1044,7 @@ impl Builder<'_> { if let Some(ref map_to) = self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler) { - cargo.env( - "RUSTC_DEBUGINFO_MAP", - format!("{}={}", self.build.src.display(), map_to), - ); + cargo.env("RUSTC_DEBUGINFO_MAP", format!("library/={map_to}/library")); } } } From e17c2f3eccc7436d7f94c6ed4bc8a367f4c6a7fb Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 17 Dec 2025 21:25:19 +0200 Subject: [PATCH 0940/3801] show how to view docs locally --- tests/crashes/README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/crashes/README.md b/tests/crashes/README.md index 8026b7c2463c..a809ae798c20 100644 --- a/tests/crashes/README.md +++ b/tests/crashes/README.md @@ -1 +1,9 @@ -Documentation on crash tests is at https://rustc-dev-guide.rust-lang.org/tests/compiletest#crash-tests +Documentation on crash tests is at https://rustc-dev-guide.rust-lang.org/tests/compiletest#crash-tests. + +Alternatively, you can build the documentation from this repository: + +```console +mdbook serve --open src/doc/rustc-dev-guide +``` + +The documentation will then be available at http://localhost:3000/tests/compiletest.html#crash-tests. From 74eecf977696ba5e9eda6b25985269dd118fb1c1 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 17 Dec 2025 20:31:38 +0100 Subject: [PATCH 0941/3801] Use the non-embeddable (absolute) path to test relative remap of std --- compiler/rustc_metadata/src/rmeta/decoder.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 0a6e5f153dde..9bf2439910ed 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1669,15 +1669,14 @@ impl<'a> CrateMetadataRef<'a> { for virtual_dir in virtual_source_base_dir.iter().flatten() { if let Some(real_dir) = &real_source_base_dir && let rustc_span::FileName::Real(old_name) = name - && let (_working_dir, embeddable_name) = - old_name.embeddable_name(RemapPathScopeComponents::MACRO) - && let Ok(rest) = embeddable_name.strip_prefix(virtual_dir) + && let virtual_path = old_name.path(RemapPathScopeComponents::MACRO) + && let Ok(rest) = virtual_path.strip_prefix(virtual_dir) { let new_path = real_dir.join(rest); debug!( "try_to_translate_virtual_to_real: `{}` -> `{}`", - embeddable_name.display(), + virtual_path.display(), new_path.display(), ); From fd513105d8c6292e75db21e613375c13585a27cd Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 17 Dec 2025 21:38:54 +0200 Subject: [PATCH 0942/3801] output of "git diff" is better, and is what I use mostly --- src/doc/rustc-dev-guide/ci/sembr/Cargo.lock | 26 -------------------- src/doc/rustc-dev-guide/ci/sembr/Cargo.toml | 1 - src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 17 ------------- 3 files changed, 44 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/Cargo.lock b/src/doc/rustc-dev-guide/ci/sembr/Cargo.lock index 077fa42d2e5b..4defe49579f3 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/Cargo.lock +++ b/src/doc/rustc-dev-guide/ci/sembr/Cargo.lock @@ -148,12 +148,6 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "globset" version = "0.4.18" @@ -167,15 +161,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - [[package]] name = "heck" version = "0.5.0" @@ -198,16 +183,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "imara-diff" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f01d462f766df78ab820dd06f5eb700233c51f0f4c2e846520eaf4ba6aa5c5c" -dependencies = [ - "hashbrown", - "memchr", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -295,7 +270,6 @@ dependencies = [ "anyhow", "clap", "ignore", - "imara-diff", "regex", ] diff --git a/src/doc/rustc-dev-guide/ci/sembr/Cargo.toml b/src/doc/rustc-dev-guide/ci/sembr/Cargo.toml index 00818e2b3c2d..46228ea47922 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/Cargo.toml +++ b/src/doc/rustc-dev-guide/ci/sembr/Cargo.toml @@ -5,7 +5,6 @@ edition = "2024" [dependencies] anyhow = "1" ignore = "0.4" -imara-diff = "0.2" [dependencies.regex] version = "1" diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 2539a9eadda3..c19f19541846 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -5,7 +5,6 @@ use std::{fs, process}; use anyhow::Result; use clap::Parser; use ignore::Walk; -use imara_diff::{Algorithm, BasicLineDiffPrinter, Diff, InternedInput, UnifiedDiffConfig}; use regex::Regex; #[derive(Parser)] @@ -18,8 +17,6 @@ struct Cli { /// Applies to lines that are to be split #[arg(long, default_value_t = 100)] line_length_limit: usize, - #[arg(long)] - show_diff: bool, } static REGEX_IGNORE_END: LazyLock = @@ -54,10 +51,6 @@ fn main() -> Result<()> { } else if cli.overwrite { fs::write(&path, new)?; made_compliant.push(path.clone()); - } else if cli.show_diff { - println!("{}:", path.display()); - show_diff(&old, &new); - println!("---"); } else { not_compliant.push(path.clone()); } @@ -76,16 +69,6 @@ fn main() -> Result<()> { Ok(()) } -fn show_diff(old: &str, new: &str) { - let input = InternedInput::new(old, new); - let mut diff = Diff::compute(Algorithm::Histogram, &input); - diff.postprocess_lines(&input); - let diff = diff - .unified_diff(&BasicLineDiffPrinter(&input.interner), UnifiedDiffConfig::default(), &input) - .to_string(); - print!("{diff}"); -} - fn display(header: &str, paths: &[PathBuf]) { println!("{header}:"); for element in paths { From 9cb47c6e8ece9cf36b698bf2e061290c1e0c634b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Wed, 26 Mar 2025 03:26:09 +0100 Subject: [PATCH 0943/3801] ExprUseVisitor: properly report discriminant reads This solves the "can't find the upvar" ICEs that resulted from `maybe_read_scrutinee` being unfit for purpose. --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 102 +++++++++-- tests/crashes/137467-1.rs | 17 -- tests/crashes/137467-2.rs | 18 -- tests/crashes/137467-3.rs | 8 - .../2229_closure_analysis/capture-enums.rs | 2 + .../capture-enums.stderr | 26 ++- .../match/patterns-capture-analysis.rs | 5 + .../match/patterns-capture-analysis.stderr | 79 +++++--- .../only-inhabited-variant-stable.rs | 23 +++ .../only-inhabited-variant-stable.stderr | 20 +++ ...habited-variant.exhaustive_patterns.stderr | 20 +++ .../only-inhabited-variant.normal.stderr | 20 +++ ...tivariant.rs => only-inhabited-variant.rs} | 8 +- tests/ui/closures/or-patterns-issue-137467.rs | 170 ++++++++++++++++++ 14 files changed, 426 insertions(+), 92 deletions(-) delete mode 100644 tests/crashes/137467-1.rs delete mode 100644 tests/crashes/137467-2.rs delete mode 100644 tests/crashes/137467-3.rs create mode 100644 tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs create mode 100644 tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr create mode 100644 tests/ui/closures/2229_closure_analysis/only-inhabited-variant.exhaustive_patterns.stderr create mode 100644 tests/ui/closures/2229_closure_analysis/only-inhabited-variant.normal.stderr rename tests/ui/closures/2229_closure_analysis/{run_pass/multivariant.rs => only-inhabited-variant.rs} (55%) create mode 100644 tests/ui/closures/or-patterns-issue-137467.rs diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 27b66d07f98e..2e993cf7db95 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -943,6 +943,19 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } /// The core driver for walking a pattern + /// + /// This should mirror how pattern-matching gets lowered to MIR, as + /// otherwise lowering will ICE when trying to resolve the upvars. + /// + /// However, it is okay to approximate it here by doing *more* accesses than + /// the actual MIR builder will, which is useful when some checks are too + /// cumbersome to perform here. For example, if after typeck it becomes + /// clear that only one variant of an enum is inhabited, and therefore a + /// read of the discriminant is not necessary, `walk_pat` will have + /// over-approximated the necessary upvar capture granularity. + /// + /// Do note that discrepancies like these do still create obscure corners + /// in the semantics of the language, and should be avoided if possible. #[instrument(skip(self), level = "debug")] fn walk_pat( &self, @@ -952,6 +965,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ) -> Result<(), Cx::Error> { let tcx = self.cx.tcx(); self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| { + debug!("walk_pat: pat.kind={:?}", pat.kind); + let read_discriminant = || { + self.delegate.borrow_mut().borrow(place, discr_place.hir_id, BorrowKind::Immutable); + }; + match pat.kind { PatKind::Binding(_, canonical_id, ..) => { debug!("walk_pat: binding place={:?} pat={:?}", place, pat); @@ -974,11 +992,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // binding when lowering pattern guards to ensure that the guard does not // modify the scrutinee. if has_guard { - self.delegate.borrow_mut().borrow( - place, - discr_place.hir_id, - BorrowKind::Immutable, - ); + read_discriminant(); } // It is also a borrow or copy/move of the value being matched. @@ -1014,13 +1028,71 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx PatKind::Never => { // A `!` pattern always counts as an immutable read of the discriminant, // even in an irrefutable pattern. - self.delegate.borrow_mut().borrow( - place, - discr_place.hir_id, - BorrowKind::Immutable, - ); + read_discriminant(); + } + PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => { + // A `Path` pattern is just a name like `Foo`. This is either a + // named constant or else it refers to an ADT variant + + let res = self.cx.typeck_results().qpath_res(qpath, *hir_id); + match res { + Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => { + // Named constants have to be equated with the value + // being matched, so that's a read of the value being matched. + // + // FIXME: Does the MIR code skip this read when matching on a ZST? + // If so, we can also skip it here. + read_discriminant(); + } + _ => { + // Otherwise, this is a struct/enum variant, and so it's + // only a read if we need to read the discriminant. + if self.is_multivariant_adt(place.place.ty(), *span) { + read_discriminant(); + } + } + } + } + PatKind::Expr(_) | PatKind::Range(..) => { + // When matching against a literal or range, we need to + // borrow the place to compare it against the pattern. + // + // FIXME: What if the type being matched only has one + // possible value? + // FIXME: What if the range is the full range of the type + // and doesn't actually require a discriminant read? + read_discriminant(); + } + PatKind::Struct(..) | PatKind::TupleStruct(..) => { + if self.is_multivariant_adt(place.place.ty(), pat.span) { + read_discriminant(); + } + } + PatKind::Slice(lhs, wild, rhs) => { + // We don't need to test the length if the pattern is `[..]` + if matches!((lhs, wild, rhs), (&[], Some(_), &[])) + // Arrays have a statically known size, so + // there is no need to read their length + || place.place.ty().peel_refs().is_array() + { + // No read necessary + } else { + read_discriminant(); + } + } + PatKind::Or(_) + | PatKind::Box(_) + | PatKind::Ref(..) + | PatKind::Guard(..) + | PatKind::Tuple(..) + | PatKind::Wild + | PatKind::Missing + | PatKind::Err(_) => { + // If the PatKind is Or, Box, Ref, Guard, or Tuple, the relevant accesses + // are made later as these patterns contains subpatterns. + // If the PatKind is Missing, Wild or Err, any relevant accesses are made when processing + // the other patterns that are part of the match } - _ => {} } Ok(()) @@ -1904,6 +1976,14 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } + /// Checks whether a type has multiple variants, and therefore, whether a + /// read of the discriminant might be necessary. Note that the actual MIR + /// builder code does a more specific check, filtering out variants that + /// happen to be uninhabited. + /// + /// Here, we cannot perform such an accurate checks, because querying + /// whether a type is inhabited requires that it has been fully inferred, + /// which cannot be guaranteed at this point. fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool { if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() { // Note that if a non-exhaustive SingleVariant is defined in another crate, we need diff --git a/tests/crashes/137467-1.rs b/tests/crashes/137467-1.rs deleted file mode 100644 index b6bff2bdc4e8..000000000000 --- a/tests/crashes/137467-1.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #137467 -//@ edition: 2021 -enum Camera { - Normal { base_transform: i32 }, - Volume { transform: i32 }, -} - -fn draw_ui(camera: &mut Camera) { - || { - let (Camera::Normal { - base_transform: _transform, - } - | Camera::Volume { - transform: _transform, - }) = camera; - }; -} diff --git a/tests/crashes/137467-2.rs b/tests/crashes/137467-2.rs deleted file mode 100644 index a70ea92b22dc..000000000000 --- a/tests/crashes/137467-2.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ known-bug: #137467 -//@ edition: 2021 - -enum Camera { - Normal { base_transform: i32 }, - Volume { transform: i32 }, -} - -fn draw_ui(camera: &mut Camera) { - || { - let (Camera::Normal { - base_transform: _, - } - | Camera::Volume { - transform: _, - }) = camera; - }; -} diff --git a/tests/crashes/137467-3.rs b/tests/crashes/137467-3.rs deleted file mode 100644 index cb81a9a912e7..000000000000 --- a/tests/crashes/137467-3.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: #137467 -//@ edition: 2021 - -fn meow(x: (u32, u32, u32)) { - let f = || { - let ((0, a, _) | (_, _, a)) = x; - }; -} diff --git a/tests/ui/closures/2229_closure_analysis/capture-enums.rs b/tests/ui/closures/2229_closure_analysis/capture-enums.rs index d9c06a68c95b..4c600ccdaa43 100644 --- a/tests/ui/closures/2229_closure_analysis/capture-enums.rs +++ b/tests/ui/closures/2229_closure_analysis/capture-enums.rs @@ -22,6 +22,7 @@ fn multi_variant_enum() { //~| ERROR Min Capture analysis includes: if let Info::Point(_, _, str) = point { //~^ NOTE: Capturing point[] -> Immutable + //~| NOTE: Capturing point[] -> Immutable //~| NOTE: Capturing point[(2, 0)] -> ByValue //~| NOTE: Min Capture point[] -> ByValue println!("{}", str); @@ -29,6 +30,7 @@ fn multi_variant_enum() { if let Info::Meta(_, v) = meta { //~^ NOTE: Capturing meta[] -> Immutable + //~| NOTE: Capturing meta[] -> Immutable //~| NOTE: Capturing meta[(1, 1)] -> ByValue //~| NOTE: Min Capture meta[] -> ByValue println!("{:?}", v); diff --git a/tests/ui/closures/2229_closure_analysis/capture-enums.stderr b/tests/ui/closures/2229_closure_analysis/capture-enums.stderr index 89a879cec468..b62384ffe12e 100644 --- a/tests/ui/closures/2229_closure_analysis/capture-enums.stderr +++ b/tests/ui/closures/2229_closure_analysis/capture-enums.stderr @@ -9,7 +9,7 @@ LL | let c = #[rustc_capture_analysis] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: attributes on expressions are experimental - --> $DIR/capture-enums.rs:48:13 + --> $DIR/capture-enums.rs:50:13 | LL | let c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,18 +34,28 @@ note: Capturing point[] -> Immutable | LL | if let Info::Point(_, _, str) = point { | ^^^^^ +note: Capturing point[] -> Immutable + --> $DIR/capture-enums.rs:23:41 + | +LL | if let Info::Point(_, _, str) = point { + | ^^^^^ note: Capturing point[(2, 0)] -> ByValue --> $DIR/capture-enums.rs:23:41 | LL | if let Info::Point(_, _, str) = point { | ^^^^^ note: Capturing meta[] -> Immutable - --> $DIR/capture-enums.rs:30:35 + --> $DIR/capture-enums.rs:31:35 + | +LL | if let Info::Meta(_, v) = meta { + | ^^^^ +note: Capturing meta[] -> Immutable + --> $DIR/capture-enums.rs:31:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ note: Capturing meta[(1, 1)] -> ByValue - --> $DIR/capture-enums.rs:30:35 + --> $DIR/capture-enums.rs:31:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ @@ -67,13 +77,13 @@ note: Min Capture point[] -> ByValue LL | if let Info::Point(_, _, str) = point { | ^^^^^ note: Min Capture meta[] -> ByValue - --> $DIR/capture-enums.rs:30:35 + --> $DIR/capture-enums.rs:31:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ error: First Pass analysis includes: - --> $DIR/capture-enums.rs:52:5 + --> $DIR/capture-enums.rs:54:5 | LL | / || { LL | | @@ -85,13 +95,13 @@ LL | | }; | |_____^ | note: Capturing point[(2, 0)] -> ByValue - --> $DIR/capture-enums.rs:55:47 + --> $DIR/capture-enums.rs:57:47 | LL | let SingleVariant::Point(_, _, str) = point; | ^^^^^ error: Min Capture analysis includes: - --> $DIR/capture-enums.rs:52:5 + --> $DIR/capture-enums.rs:54:5 | LL | / || { LL | | @@ -103,7 +113,7 @@ LL | | }; | |_____^ | note: Min Capture point[(2, 0)] -> ByValue - --> $DIR/capture-enums.rs:55:47 + --> $DIR/capture-enums.rs:57:47 | LL | let SingleVariant::Point(_, _, str) = point; | ^^^^^ diff --git a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs index 40330af4088c..a9d2777d93f1 100644 --- a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs +++ b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs @@ -14,6 +14,7 @@ fn test_1_should_capture() { //~| ERROR Min Capture analysis includes: match variant { //~^ NOTE: Capturing variant[] -> Immutable + //~| NOTE: Capturing variant[] -> Immutable //~| NOTE: Min Capture variant[] -> Immutable Some(_) => {} _ => {} @@ -132,6 +133,7 @@ fn test_5_should_capture_multi_variant() { //~| ERROR Min Capture analysis includes: match variant { //~^ NOTE: Capturing variant[] -> Immutable + //~| NOTE: Capturing variant[] -> Immutable //~| NOTE: Min Capture variant[] -> Immutable MVariant::A => {} _ => {} @@ -150,6 +152,7 @@ fn test_7_should_capture_slice_len() { //~| ERROR Min Capture analysis includes: match slice { //~^ NOTE: Capturing slice[] -> Immutable + //~| NOTE: Capturing slice[Deref] -> Immutable //~| NOTE: Min Capture slice[] -> Immutable [_,_,_] => {}, _ => {} @@ -162,6 +165,7 @@ fn test_7_should_capture_slice_len() { //~| ERROR Min Capture analysis includes: match slice { //~^ NOTE: Capturing slice[] -> Immutable + //~| NOTE: Capturing slice[Deref] -> Immutable //~| NOTE: Min Capture slice[] -> Immutable [] => {}, _ => {} @@ -174,6 +178,7 @@ fn test_7_should_capture_slice_len() { //~| ERROR Min Capture analysis includes: match slice { //~^ NOTE: Capturing slice[] -> Immutable + //~| NOTE: Capturing slice[Deref] -> Immutable //~| NOTE: Min Capture slice[] -> Immutable [_, .. ,_] => {}, _ => {} diff --git a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr index e7e5e7f7fa1b..4b9d6fad0e50 100644 --- a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr @@ -14,6 +14,11 @@ note: Capturing variant[] -> Immutable | LL | match variant { | ^^^^^^^ +note: Capturing variant[] -> Immutable + --> $DIR/patterns-capture-analysis.rs:15:15 + | +LL | match variant { + | ^^^^^^^ error: Min Capture analysis includes: --> $DIR/patterns-capture-analysis.rs:12:5 @@ -33,7 +38,7 @@ LL | match variant { | ^^^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:30:5 + --> $DIR/patterns-capture-analysis.rs:31:5 | LL | / || { LL | | @@ -44,7 +49,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:49:5 + --> $DIR/patterns-capture-analysis.rs:50:5 | LL | / || { LL | | @@ -55,7 +60,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:63:5 + --> $DIR/patterns-capture-analysis.rs:64:5 | LL | / || { LL | | @@ -66,18 +71,18 @@ LL | | }; | |_____^ | note: Capturing variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:66:15 + --> $DIR/patterns-capture-analysis.rs:67:15 | LL | match variant { | ^^^^^^^ note: Capturing variant[(0, 0)] -> Immutable - --> $DIR/patterns-capture-analysis.rs:66:15 + --> $DIR/patterns-capture-analysis.rs:67:15 | LL | match variant { | ^^^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:63:5 + --> $DIR/patterns-capture-analysis.rs:64:5 | LL | / || { LL | | @@ -88,13 +93,13 @@ LL | | }; | |_____^ | note: Min Capture variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:66:15 + --> $DIR/patterns-capture-analysis.rs:67:15 | LL | match variant { | ^^^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:83:5 + --> $DIR/patterns-capture-analysis.rs:84:5 | LL | / || { LL | | @@ -105,7 +110,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:95:5 + --> $DIR/patterns-capture-analysis.rs:96:5 | LL | / || { LL | | @@ -116,7 +121,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:108:5 + --> $DIR/patterns-capture-analysis.rs:109:5 | LL | / || { LL | | @@ -127,7 +132,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:130:5 + --> $DIR/patterns-capture-analysis.rs:131:5 | LL | / || { LL | | @@ -138,13 +143,18 @@ LL | | }; | |_____^ | note: Capturing variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:133:15 + --> $DIR/patterns-capture-analysis.rs:134:15 + | +LL | match variant { + | ^^^^^^^ +note: Capturing variant[] -> Immutable + --> $DIR/patterns-capture-analysis.rs:134:15 | LL | match variant { | ^^^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:130:5 + --> $DIR/patterns-capture-analysis.rs:131:5 | LL | / || { LL | | @@ -155,13 +165,13 @@ LL | | }; | |_____^ | note: Min Capture variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:133:15 + --> $DIR/patterns-capture-analysis.rs:134:15 | LL | match variant { | ^^^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:148:5 + --> $DIR/patterns-capture-analysis.rs:150:5 | LL | / || { LL | | @@ -172,13 +182,18 @@ LL | | }; | |_____^ | note: Capturing slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:151:15 + --> $DIR/patterns-capture-analysis.rs:153:15 + | +LL | match slice { + | ^^^^^ +note: Capturing slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:153:15 | LL | match slice { | ^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:148:5 + --> $DIR/patterns-capture-analysis.rs:150:5 | LL | / || { LL | | @@ -189,13 +204,13 @@ LL | | }; | |_____^ | note: Min Capture slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:151:15 + --> $DIR/patterns-capture-analysis.rs:153:15 | LL | match slice { | ^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:160:5 + --> $DIR/patterns-capture-analysis.rs:163:5 | LL | / || { LL | | @@ -206,13 +221,18 @@ LL | | }; | |_____^ | note: Capturing slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:163:15 + --> $DIR/patterns-capture-analysis.rs:166:15 + | +LL | match slice { + | ^^^^^ +note: Capturing slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:166:15 | LL | match slice { | ^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:160:5 + --> $DIR/patterns-capture-analysis.rs:163:5 | LL | / || { LL | | @@ -223,13 +243,13 @@ LL | | }; | |_____^ | note: Min Capture slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:163:15 + --> $DIR/patterns-capture-analysis.rs:166:15 | LL | match slice { | ^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:172:5 + --> $DIR/patterns-capture-analysis.rs:176:5 | LL | / || { LL | | @@ -240,13 +260,18 @@ LL | | }; | |_____^ | note: Capturing slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:175:15 + --> $DIR/patterns-capture-analysis.rs:179:15 + | +LL | match slice { + | ^^^^^ +note: Capturing slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:179:15 | LL | match slice { | ^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:172:5 + --> $DIR/patterns-capture-analysis.rs:176:5 | LL | / || { LL | | @@ -257,13 +282,13 @@ LL | | }; | |_____^ | note: Min Capture slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:175:15 + --> $DIR/patterns-capture-analysis.rs:179:15 | LL | match slice { | ^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:189:5 + --> $DIR/patterns-capture-analysis.rs:194:5 | LL | / || { LL | | diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs new file mode 100644 index 000000000000..a8e4b9cd1823 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs @@ -0,0 +1,23 @@ +// This example used to compile, but the fact that it should was never properly +// discussed. With further experience, we concluded that capture precision +// depending on whether some types are inhabited goes too far, introducing a +// bunch of headaches without much benefit. +//@ edition:2021 +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +enum Void {} + +pub fn main() { + let mut r = Result::::Err((0, 0)); + let mut f = || { + let Err((ref mut a, _)) = r; + *a = 1; + }; + let mut g = || { + //~^ ERROR: cannot borrow `r` as mutable more than once at a time + let Err((_, ref mut b)) = r; + *b = 2; + }; + f(); + g(); + assert_eq!(r, Err((1, 2))); +} diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr new file mode 100644 index 000000000000..dea85ff947ce --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr @@ -0,0 +1,20 @@ +error[E0499]: cannot borrow `r` as mutable more than once at a time + --> $DIR/only-inhabited-variant-stable.rs:15:17 + | +LL | let mut f = || { + | -- first mutable borrow occurs here +LL | let Err((ref mut a, _)) = r; + | - first borrow occurs due to use of `r` in closure +... +LL | let mut g = || { + | ^^ second mutable borrow occurs here +LL | +LL | let Err((_, ref mut b)) = r; + | - second borrow occurs due to use of `r` in closure +... +LL | f(); + | - first borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.exhaustive_patterns.stderr b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.exhaustive_patterns.stderr new file mode 100644 index 000000000000..58a5348aa391 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.exhaustive_patterns.stderr @@ -0,0 +1,20 @@ +error[E0499]: cannot borrow `r` as mutable more than once at a time + --> $DIR/only-inhabited-variant.rs:16:17 + | +LL | let mut f = || { + | -- first mutable borrow occurs here +LL | let Err((ref mut a, _)) = r; + | - first borrow occurs due to use of `r` in closure +... +LL | let mut g = || { + | ^^ second mutable borrow occurs here +LL | +LL | let Err((_, ref mut b)) = r; + | - second borrow occurs due to use of `r` in closure +... +LL | f(); + | - first borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.normal.stderr b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.normal.stderr new file mode 100644 index 000000000000..58a5348aa391 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.normal.stderr @@ -0,0 +1,20 @@ +error[E0499]: cannot borrow `r` as mutable more than once at a time + --> $DIR/only-inhabited-variant.rs:16:17 + | +LL | let mut f = || { + | -- first mutable borrow occurs here +LL | let Err((ref mut a, _)) = r; + | - first borrow occurs due to use of `r` in closure +... +LL | let mut g = || { + | ^^ second mutable borrow occurs here +LL | +LL | let Err((_, ref mut b)) = r; + | - second borrow occurs due to use of `r` in closure +... +LL | f(); + | - first borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.rs similarity index 55% rename from tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs rename to tests/ui/closures/2229_closure_analysis/only-inhabited-variant.rs index 74f37b514e4a..463838734726 100644 --- a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.rs @@ -1,8 +1,9 @@ -// Test precise capture of a multi-variant enum (when remaining variants are -// visibly uninhabited). +// This example used to compile, but the fact that it should was never properly +// discussed. With further experience, we concluded that capture precision +// depending on whether some types are inhabited goes too far, introducing a +// bunch of headaches without much benefit. //@ revisions: normal exhaustive_patterns //@ edition:2021 -//@ run-pass #![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))] #![feature(never_type)] @@ -13,6 +14,7 @@ pub fn main() { *a = 1; }; let mut g = || { + //~^ ERROR: cannot borrow `r` as mutable more than once at a time let Err((_, ref mut b)) = r; *b = 2; }; diff --git a/tests/ui/closures/or-patterns-issue-137467.rs b/tests/ui/closures/or-patterns-issue-137467.rs new file mode 100644 index 000000000000..38144aa1e816 --- /dev/null +++ b/tests/ui/closures/or-patterns-issue-137467.rs @@ -0,0 +1,170 @@ +//@ edition:2024 +//@ check-pass + +const X: u32 = 0; + +fn match_literal(x: (u32, u32, u32)) { + let _ = || { + let ((0, a, _) | (_, _, a)) = x; + a + }; +} + +fn match_range(x: (u32, u32, u32)) { + let _ = || { + let ((0..5, a, _) | (_, _, a)) = x; + a + }; +} + +fn match_const(x: (u32, u32, u32)) { + let _ = || { + let ((X, a, _) | (_, _, a)) = x; + a + }; +} + +enum Choice { A, B } + +fn match_unit_variant(x: (Choice, u32, u32)) { + let _ = || { + let ((Choice::A, a, _) | (Choice::B, _, a)) = x; + a + }; +} + +struct Unit; + +fn match_unit_struct(mut x: (Unit, u32)) { + let r = &mut x.0; + let _ = || { + let (Unit, a) = x; + a + }; + + let _ = *r; +} + +enum Also { Unit } + +fn match_unit_enum(mut x: (Also, u32)) { + let r = &mut x.0; + let _ = || { + let (Also::Unit, a) = x; + a + }; + + let _ = *r; +} + +enum TEnum { + A(u32), + B(u32), +} + +enum SEnum { + A { a: u32 }, + B { a: u32 }, +} + +fn match_tuple_enum(x: TEnum) { + let _ = || { + let (TEnum::A(a) | TEnum::B(a)) = x; + a + }; +} + +fn match_struct_enum(x: SEnum) { + let _ = || { + let (SEnum::A { a } | SEnum::B { a }) = x; + a + }; +} + +enum TSingle { + A(u32, u32), +} + +enum SSingle { + A { a: u32, b: u32 }, +} + +struct TStruct(u32, u32); +struct SStruct { a: u32, b: u32 } + +fn match_struct(mut x: SStruct) { + let r = &mut x.a; + let _ = || { + let SStruct { b, .. } = x; + b + }; + + let _ = *r; +} + +fn match_tuple_struct(mut x: TStruct) { + let r = &mut x.0; + let _ = || { + let TStruct(_, a) = x; + a + }; + + let _ = *r; +} + +fn match_singleton(mut x: SSingle) { + let SSingle::A { a: ref mut r, .. } = x; + let _ = || { + let SSingle::A { b, .. } = x; + b + }; + + let _ = *r; +} + +fn match_tuple_singleton(mut x: TSingle) { + let TSingle::A(ref mut r, _) = x; + let _ = || { + let TSingle::A(_, a) = x; + a + }; + + let _ = *r; +} + +fn match_slice(x: (&[u32], u32, u32)) { + let _ = || { + let (([], a, _) | ([_, ..], _, a)) = x; + a + }; +} + +// Original testcase, for completeness +enum Camera { + Normal { base_transform: i32 }, + Volume { transform: i32 }, +} + +fn draw_ui(camera: &mut Camera) { + || { + let (Camera::Normal { + base_transform: _transform, + } + | Camera::Volume { + transform: _transform, + }) = camera; + }; +} + +fn draw_ui2(camera: &mut Camera) { + || { + let (Camera::Normal { + base_transform: _, + } + | Camera::Volume { + transform: _, + }) = camera; + }; +} + +fn main() {} From e25803acea4ba86691cb0f9be74f3d10b4be8b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Wed, 26 Mar 2025 20:59:50 +0100 Subject: [PATCH 0944/3801] ExprUseVisitor: remove maybe_read_scrutinee The split between walk_pat and maybe_read_scrutinee has now become redundant. Due to this change, one testcase within the testsuite has become similar enough to a known ICE to also break. I am leaving this as future work, as it requires feature(type_alias_impl_trait) --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 167 +++--------------- tests/crashes/{119786.rs => 119786-1.rs} | 0 tests/crashes/119786-2.rs | 15 ++ tests/crashes/119786-3.rs | 15 ++ ...oo-{closure#0}-{closure#0}.built.after.mir | 29 ++- ...-{closure#0}-{synthetic#0}.built.after.mir | 24 ++- .../match/match-edge-cases_2.stderr | 2 +- .../match/patterns-capture-analysis.rs | 22 +-- .../match/patterns-capture-analysis.stderr | 90 ++++------ .../at-pattern-weirdness-issue-137553.rs | 41 +++++ .../issue-96572-unconstrained.rs | 9 - 11 files changed, 152 insertions(+), 262 deletions(-) rename tests/crashes/{119786.rs => 119786-1.rs} (100%) create mode 100644 tests/crashes/119786-2.rs create mode 100644 tests/crashes/119786-3.rs create mode 100644 tests/ui/closures/at-pattern-weirdness-issue-137553.rs diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 2e993cf7db95..b35f62df82b7 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -7,9 +7,7 @@ use std::cell::{Ref, RefCell}; use std::ops::Deref; -use std::slice::from_ref; -use hir::Expr; use hir::def::DefKind; use hir::pat_util::EnumerateAndAdjustIterator as _; use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; @@ -313,7 +311,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let param_place = self.cat_rvalue(param.hir_id, param_ty); - self.walk_irrefutable_pat(¶m_place, param.pat)?; + self.fake_read_scrutinee(¶m_place, false)?; + self.walk_pat(¶m_place, param.pat, false)?; } self.consume_expr(body.value)?; @@ -455,13 +454,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx hir::ExprKind::Match(discr, arms, _) => { let discr_place = self.cat_expr(discr)?; - self.maybe_read_scrutinee( - discr, - discr_place.clone(), - arms.iter().map(|arm| arm.pat), - )?; + self.fake_read_scrutinee(&discr_place, true)?; + self.walk_expr(discr)?; - // treatment of the discriminant is handled while walking the arms. for arm in arms { self.walk_arm(&discr_place, arm)?; } @@ -598,116 +593,25 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx Ok(()) } - fn maybe_read_scrutinee<'t>( + #[instrument(skip(self), level = "debug")] + fn fake_read_scrutinee( &self, - discr: &Expr<'_>, - discr_place: PlaceWithHirId<'tcx>, - pats: impl Iterator>, + discr_place: &PlaceWithHirId<'tcx>, + refutable: bool, ) -> Result<(), Cx::Error> { - // Matching should not always be considered a use of the place, hence - // discr does not necessarily need to be borrowed. - // We only want to borrow discr if the pattern contain something other - // than wildcards. - let mut needs_to_be_read = false; - for pat in pats { - self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| { - match &pat.kind { - PatKind::Missing => unreachable!(), - PatKind::Binding(.., opt_sub_pat) => { - // If the opt_sub_pat is None, then the binding does not count as - // a wildcard for the purpose of borrowing discr. - if opt_sub_pat.is_none() { - needs_to_be_read = true; - } - } - PatKind::Never => { - // A never pattern reads the value. - // FIXME(never_patterns): does this do what I expect? - needs_to_be_read = true; - } - PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => { - // A `Path` pattern is just a name like `Foo`. This is either a - // named constant or else it refers to an ADT variant + let closure_def_id = match discr_place.place.base { + PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), + _ => None, + }; - let res = self.cx.typeck_results().qpath_res(qpath, *hir_id); - match res { - Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => { - // Named constants have to be equated with the value - // being matched, so that's a read of the value being matched. - // - // FIXME: We don't actually reads for ZSTs. - needs_to_be_read = true; - } - _ => { - // Otherwise, this is a struct/enum variant, and so it's - // only a read if we need to read the discriminant. - needs_to_be_read |= - self.is_multivariant_adt(place.place.ty(), *span); - } - } - } - PatKind::TupleStruct(..) | PatKind::Struct(..) | PatKind::Tuple(..) => { - // For `Foo(..)`, `Foo { ... }` and `(...)` patterns, check if we are matching - // against a multivariant enum or struct. In that case, we have to read - // the discriminant. Otherwise this kind of pattern doesn't actually - // read anything (we'll get invoked for the `...`, which may indeed - // perform some reads). - - let place_ty = place.place.ty(); - needs_to_be_read |= self.is_multivariant_adt(place_ty, pat.span); - } - PatKind::Expr(_) | PatKind::Range(..) => { - // If the PatKind is a Lit or a Range then we want - // to borrow discr. - needs_to_be_read = true; - } - PatKind::Slice(lhs, wild, rhs) => { - // We don't need to test the length if the pattern is `[..]` - if matches!((lhs, wild, rhs), (&[], Some(_), &[])) - // Arrays have a statically known size, so - // there is no need to read their length - || place.place.ty().peel_refs().is_array() - { - } else { - needs_to_be_read = true; - } - } - PatKind::Or(_) - | PatKind::Box(_) - | PatKind::Deref(_) - | PatKind::Ref(..) - | PatKind::Guard(..) - | PatKind::Wild - | PatKind::Err(_) => { - // If the PatKind is Or, Box, or Ref, the decision is made later - // as these patterns contains subpatterns - // If the PatKind is Wild or Err, the decision is made based on the other patterns - // being examined - } - } - - Ok(()) - })? - } - - if needs_to_be_read { - self.borrow_expr(discr, BorrowKind::Immutable)?; + let cause = if refutable { + FakeReadCause::ForMatchedPlace(closure_def_id) } else { - let closure_def_id = match discr_place.place.base { - PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), - _ => None, - }; + FakeReadCause::ForLet(closure_def_id) + }; - self.delegate.borrow_mut().fake_read( - &discr_place, - FakeReadCause::ForMatchedPlace(closure_def_id), - discr_place.hir_id, - ); + self.delegate.borrow_mut().fake_read(discr_place, cause, discr_place.hir_id); - // We always want to walk the discriminant. We want to make sure, for instance, - // that the discriminant has been initialized. - self.walk_expr(discr)?; - } Ok(()) } @@ -724,12 +628,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.walk_expr(expr)?; let expr_place = self.cat_expr(expr)?; f()?; + self.fake_read_scrutinee(&expr_place, els.is_some())?; + self.walk_pat(&expr_place, pat, false)?; if let Some(els) = els { - // borrowing because we need to test the discriminant - self.maybe_read_scrutinee(expr, expr_place.clone(), from_ref(pat).iter())?; self.walk_block(els)?; } - self.walk_irrefutable_pat(&expr_place, pat)?; Ok(()) } @@ -901,16 +804,6 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx discr_place: &PlaceWithHirId<'tcx>, arm: &hir::Arm<'_>, ) -> Result<(), Cx::Error> { - let closure_def_id = match discr_place.place.base { - PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), - _ => None, - }; - - self.delegate.borrow_mut().fake_read( - discr_place, - FakeReadCause::ForMatchedPlace(closure_def_id), - discr_place.hir_id, - ); self.walk_pat(discr_place, arm.pat, arm.guard.is_some())?; if let Some(ref e) = arm.guard { @@ -921,27 +814,6 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx Ok(()) } - /// Walks a pat that occurs in isolation (i.e., top-level of fn argument or - /// let binding, and *not* a match arm or nested pat.) - fn walk_irrefutable_pat( - &self, - discr_place: &PlaceWithHirId<'tcx>, - pat: &hir::Pat<'_>, - ) -> Result<(), Cx::Error> { - let closure_def_id = match discr_place.place.base { - PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), - _ => None, - }; - - self.delegate.borrow_mut().fake_read( - discr_place, - FakeReadCause::ForLet(closure_def_id), - discr_place.hir_id, - ); - self.walk_pat(discr_place, pat, false)?; - Ok(()) - } - /// The core driver for walking a pattern /// /// This should mirror how pattern-matching gets lowered to MIR, as @@ -1984,6 +1856,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// Here, we cannot perform such an accurate checks, because querying /// whether a type is inhabited requires that it has been fully inferred, /// which cannot be guaranteed at this point. + #[instrument(skip(self, span), level = "debug")] fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool { if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() { // Note that if a non-exhaustive SingleVariant is defined in another crate, we need diff --git a/tests/crashes/119786.rs b/tests/crashes/119786-1.rs similarity index 100% rename from tests/crashes/119786.rs rename to tests/crashes/119786-1.rs diff --git a/tests/crashes/119786-2.rs b/tests/crashes/119786-2.rs new file mode 100644 index 000000000000..76c5deb4605a --- /dev/null +++ b/tests/crashes/119786-2.rs @@ -0,0 +1,15 @@ +//@ known-bug: #119786 +//@ edition:2021 + +fn enum_upvar() { + type T = impl Copy; + let foo: T = Some((1u32, 2u32)); + let x = move || { + match foo { + None => (), + Some(_) => (), + } + }; +} + +pub fn main() {} diff --git a/tests/crashes/119786-3.rs b/tests/crashes/119786-3.rs new file mode 100644 index 000000000000..34bb90fd0fae --- /dev/null +++ b/tests/crashes/119786-3.rs @@ -0,0 +1,15 @@ +//@ known-bug: #119786 +//@ edition:2021 + +fn enum_upvar() { + type T = impl Copy; + let foo: T = Some((1u32, 2u32)); + let x = move || { + match foo { + None => (), + Some((a, b)) => (), + } + }; +} + +pub fn main() {} diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir index b43af549b232..9ff1a90ab820 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir @@ -4,18 +4,16 @@ fn foo::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_fake yields () { debug _task_context => _2; - debug f => (*(_1.0: &&Foo)); + debug f => (*(_1.0: &Foo)); let mut _0: (); let mut _3: &Foo; let mut _4: &&Foo; - let mut _5: &&&Foo; - let mut _6: isize; - let mut _7: bool; + let mut _5: isize; + let mut _6: bool; bb0: { - PlaceMention((*(_1.0: &&Foo))); - _6 = discriminant((*(*(_1.0: &&Foo)))); - switchInt(move _6) -> [0: bb2, otherwise: bb1]; + _5 = discriminant((*(_1.0: &Foo))); + switchInt(move _5) -> [0: bb2, otherwise: bb1]; } bb1: { @@ -32,17 +30,15 @@ yields () } bb4: { - FakeRead(ForMatchedPlace(None), (*(_1.0: &&Foo))); unreachable; } bb5: { - _3 = &fake shallow (*(*(_1.0: &&Foo))); - _4 = &fake shallow (*(_1.0: &&Foo)); - _5 = &fake shallow (_1.0: &&Foo); - StorageLive(_7); - _7 = const true; - switchInt(move _7) -> [0: bb8, otherwise: bb7]; + _3 = &fake shallow (*(_1.0: &Foo)); + _4 = &fake shallow (_1.0: &Foo); + StorageLive(_6); + _6 = const true; + switchInt(move _6) -> [0: bb8, otherwise: bb7]; } bb6: { @@ -50,10 +46,9 @@ yields () } bb7: { - StorageDead(_7); + StorageDead(_6); FakeRead(ForMatchGuard, _3); FakeRead(ForMatchGuard, _4); - FakeRead(ForMatchGuard, _5); _0 = const (); goto -> bb10; } @@ -63,7 +58,7 @@ yields () } bb9: { - StorageDead(_7); + StorageDead(_6); goto -> bb6; } diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir index 5623b6d64e97..4b745caf48c5 100644 --- a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir +++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{synthetic#0}.built.after.mir @@ -4,18 +4,16 @@ fn foo::{closure#0}::{synthetic#0}(_1: {async closure body@$DIR/async_closure_fa yields () { debug _task_context => _2; - debug f => (_1.0: &Foo); + debug f => (*(_1.0: &Foo)); let mut _0: (); let mut _3: &Foo; let mut _4: &&Foo; - let mut _5: &&&Foo; - let mut _6: isize; - let mut _7: bool; + let mut _5: isize; + let mut _6: bool; bb0: { - PlaceMention((_1.0: &Foo)); - _6 = discriminant((*(_1.0: &Foo))); - switchInt(move _6) -> [0: bb2, otherwise: bb1]; + _5 = discriminant((*(_1.0: &Foo))); + switchInt(move _5) -> [0: bb2, otherwise: bb1]; } bb1: { @@ -29,24 +27,22 @@ yields () bb3: { _3 = &fake shallow (*(_1.0: &Foo)); - _4 = &fake shallow (_1.0: &Foo); nop; - StorageLive(_7); - _7 = const true; - switchInt(move _7) -> [0: bb5, otherwise: bb4]; + StorageLive(_6); + _6 = const true; + switchInt(move _6) -> [0: bb5, otherwise: bb4]; } bb4: { - StorageDead(_7); + StorageDead(_6); FakeRead(ForMatchGuard, _3); FakeRead(ForMatchGuard, _4); - FakeRead(ForMatchGuard, _5); _0 = const (); goto -> bb6; } bb5: { - StorageDead(_7); + StorageDead(_6); falseEdge -> [real: bb1, imaginary: bb1]; } diff --git a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr index d82db0481a06..3f5fe9eda423 100644 --- a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr @@ -4,7 +4,7 @@ error[E0505]: cannot move out of `ts` because it is borrowed LL | let _b = || { match ts { | -- -- borrow occurs due to use in closure | | - | borrow of `ts` occurs here + | borrow of `ts.x` occurs here ... LL | let mut mut_ts = ts; | ^^ move out of `ts` occurs here diff --git a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs index a9d2777d93f1..16cb9d7355da 100644 --- a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs +++ b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs @@ -14,7 +14,6 @@ fn test_1_should_capture() { //~| ERROR Min Capture analysis includes: match variant { //~^ NOTE: Capturing variant[] -> Immutable - //~| NOTE: Capturing variant[] -> Immutable //~| NOTE: Min Capture variant[] -> Immutable Some(_) => {} _ => {} @@ -65,9 +64,8 @@ fn test_6_should_capture_single_variant() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: match variant { - //~^ NOTE: Capturing variant[] -> Immutable - //~| NOTE: Capturing variant[(0, 0)] -> Immutable - //~| NOTE: Min Capture variant[] -> Immutable + //~^ NOTE: Capturing variant[(0, 0)] -> Immutable + //~| NOTE: Min Capture variant[(0, 0)] -> Immutable SingleVariant::Points(a) => { println!("{:?}", a); } @@ -133,7 +131,6 @@ fn test_5_should_capture_multi_variant() { //~| ERROR Min Capture analysis includes: match variant { //~^ NOTE: Capturing variant[] -> Immutable - //~| NOTE: Capturing variant[] -> Immutable //~| NOTE: Min Capture variant[] -> Immutable MVariant::A => {} _ => {} @@ -151,9 +148,8 @@ fn test_7_should_capture_slice_len() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: match slice { - //~^ NOTE: Capturing slice[] -> Immutable - //~| NOTE: Capturing slice[Deref] -> Immutable - //~| NOTE: Min Capture slice[] -> Immutable + //~^ NOTE: Capturing slice[Deref] -> Immutable + //~| NOTE: Min Capture slice[Deref] -> Immutable [_,_,_] => {}, _ => {} } @@ -164,9 +160,8 @@ fn test_7_should_capture_slice_len() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: match slice { - //~^ NOTE: Capturing slice[] -> Immutable - //~| NOTE: Capturing slice[Deref] -> Immutable - //~| NOTE: Min Capture slice[] -> Immutable + //~^ NOTE: Capturing slice[Deref] -> Immutable + //~| NOTE: Min Capture slice[Deref] -> Immutable [] => {}, _ => {} } @@ -177,9 +172,8 @@ fn test_7_should_capture_slice_len() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: match slice { - //~^ NOTE: Capturing slice[] -> Immutable - //~| NOTE: Capturing slice[Deref] -> Immutable - //~| NOTE: Min Capture slice[] -> Immutable + //~^ NOTE: Capturing slice[Deref] -> Immutable + //~| NOTE: Min Capture slice[Deref] -> Immutable [_, .. ,_] => {}, _ => {} } diff --git a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr index 4b9d6fad0e50..73c685e15276 100644 --- a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr @@ -14,11 +14,6 @@ note: Capturing variant[] -> Immutable | LL | match variant { | ^^^^^^^ -note: Capturing variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:15:15 - | -LL | match variant { - | ^^^^^^^ error: Min Capture analysis includes: --> $DIR/patterns-capture-analysis.rs:12:5 @@ -38,7 +33,7 @@ LL | match variant { | ^^^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:31:5 + --> $DIR/patterns-capture-analysis.rs:30:5 | LL | / || { LL | | @@ -49,7 +44,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:50:5 + --> $DIR/patterns-capture-analysis.rs:49:5 | LL | / || { LL | | @@ -60,7 +55,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:64:5 + --> $DIR/patterns-capture-analysis.rs:63:5 | LL | / || { LL | | @@ -70,19 +65,14 @@ LL | | match variant { LL | | }; | |_____^ | -note: Capturing variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:67:15 - | -LL | match variant { - | ^^^^^^^ note: Capturing variant[(0, 0)] -> Immutable - --> $DIR/patterns-capture-analysis.rs:67:15 + --> $DIR/patterns-capture-analysis.rs:66:15 | LL | match variant { | ^^^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:64:5 + --> $DIR/patterns-capture-analysis.rs:63:5 | LL | / || { LL | | @@ -92,14 +82,14 @@ LL | | match variant { LL | | }; | |_____^ | -note: Min Capture variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:67:15 +note: Min Capture variant[(0, 0)] -> Immutable + --> $DIR/patterns-capture-analysis.rs:66:15 | LL | match variant { | ^^^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:84:5 + --> $DIR/patterns-capture-analysis.rs:82:5 | LL | / || { LL | | @@ -110,7 +100,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:96:5 + --> $DIR/patterns-capture-analysis.rs:94:5 | LL | / || { LL | | @@ -121,7 +111,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:109:5 + --> $DIR/patterns-capture-analysis.rs:107:5 | LL | / || { LL | | @@ -132,7 +122,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:131:5 + --> $DIR/patterns-capture-analysis.rs:129:5 | LL | / || { LL | | @@ -143,18 +133,13 @@ LL | | }; | |_____^ | note: Capturing variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:134:15 - | -LL | match variant { - | ^^^^^^^ -note: Capturing variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:134:15 + --> $DIR/patterns-capture-analysis.rs:132:15 | LL | match variant { | ^^^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:131:5 + --> $DIR/patterns-capture-analysis.rs:129:5 | LL | / || { LL | | @@ -165,13 +150,13 @@ LL | | }; | |_____^ | note: Min Capture variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:134:15 + --> $DIR/patterns-capture-analysis.rs:132:15 | LL | match variant { | ^^^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:150:5 + --> $DIR/patterns-capture-analysis.rs:147:5 | LL | / || { LL | | @@ -181,19 +166,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Capturing slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:153:15 - | -LL | match slice { - | ^^^^^ note: Capturing slice[Deref] -> Immutable - --> $DIR/patterns-capture-analysis.rs:153:15 + --> $DIR/patterns-capture-analysis.rs:150:15 | LL | match slice { | ^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:150:5 + --> $DIR/patterns-capture-analysis.rs:147:5 | LL | / || { LL | | @@ -203,14 +183,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Min Capture slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:153:15 +note: Min Capture slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:150:15 | LL | match slice { | ^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:163:5 + --> $DIR/patterns-capture-analysis.rs:159:5 | LL | / || { LL | | @@ -220,19 +200,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Capturing slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:166:15 - | -LL | match slice { - | ^^^^^ note: Capturing slice[Deref] -> Immutable - --> $DIR/patterns-capture-analysis.rs:166:15 + --> $DIR/patterns-capture-analysis.rs:162:15 | LL | match slice { | ^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:163:5 + --> $DIR/patterns-capture-analysis.rs:159:5 | LL | / || { LL | | @@ -242,14 +217,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Min Capture slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:166:15 +note: Min Capture slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:162:15 | LL | match slice { | ^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:176:5 + --> $DIR/patterns-capture-analysis.rs:171:5 | LL | / || { LL | | @@ -259,19 +234,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Capturing slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:179:15 - | -LL | match slice { - | ^^^^^ note: Capturing slice[Deref] -> Immutable - --> $DIR/patterns-capture-analysis.rs:179:15 + --> $DIR/patterns-capture-analysis.rs:174:15 | LL | match slice { | ^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:176:5 + --> $DIR/patterns-capture-analysis.rs:171:5 | LL | / || { LL | | @@ -281,14 +251,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Min Capture slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:179:15 +note: Min Capture slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:174:15 | LL | match slice { | ^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:194:5 + --> $DIR/patterns-capture-analysis.rs:188:5 | LL | / || { LL | | diff --git a/tests/ui/closures/at-pattern-weirdness-issue-137553.rs b/tests/ui/closures/at-pattern-weirdness-issue-137553.rs new file mode 100644 index 000000000000..7c934d4a1433 --- /dev/null +++ b/tests/ui/closures/at-pattern-weirdness-issue-137553.rs @@ -0,0 +1,41 @@ +//@ edition:2024 +//@ check-pass + +// Background: +fn f1() { + let mut a = (21, 37); + // only captures a.0, example compiles fine + let mut f = || { + let (ref mut x, _) = a; + *x = 42; + }; + a.1 = 69; + f(); +} + +// This used to error out: +fn f2() { + let mut a = (21, 37); + // used to capture all of a, now captures only a.0 + let mut f = || { + match a { + (ref mut x, _) => *x = 42, + } + }; + a.1 = 69; + f(); +} + +// This was inconsistent with the following: +fn main() { + let mut a = (21, 37); + // the useless @-pattern would cause it to capture only a.0. now the + // behavior is consistent with the case that doesn't use the @-pattern + let mut f = || { + match a { + (ref mut x @ _, _) => *x = 42, + } + }; + a.1 = 69; + f(); +} diff --git a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs index 7f0f6a214aae..383d9108eb90 100644 --- a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs +++ b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs @@ -23,15 +23,6 @@ fn upvar() { }; } -fn enum_upvar() { - type T = impl Copy; - let foo: T = Some((1u32, 2u32)); - let x = move || match foo { - None => (), - Some((a, b)) => (), - }; -} - fn r#struct() { #[derive(Copy, Clone)] struct Foo((u32, u32)); From 1cc7e7fe8b675dd3f55b5d75325b2e52466700bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Thu, 27 Mar 2025 16:50:11 +0100 Subject: [PATCH 0945/3801] Add test case for issue 138973 --- tests/ui/closures/or-patterns-issue-137467.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/ui/closures/or-patterns-issue-137467.rs b/tests/ui/closures/or-patterns-issue-137467.rs index 38144aa1e816..5a1e84e1c9a0 100644 --- a/tests/ui/closures/or-patterns-issue-137467.rs +++ b/tests/ui/closures/or-patterns-issue-137467.rs @@ -24,6 +24,13 @@ fn match_const(x: (u32, u32, u32)) { }; } +// related testcase reported in #138973 +fn without_bindings(x: u32) { + let _ = || { + let (0 | _) = x; + }; +} + enum Choice { A, B } fn match_unit_variant(x: (Choice, u32, u32)) { From 8800f956f4ac5a8a99f32a0820468bb96391654c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Tue, 1 Apr 2025 20:32:13 +0200 Subject: [PATCH 0946/3801] Avoid using #[derive] in test As per code review, it is preferred to not use derives in tests that aren't about them. --- .../2229_closure_analysis/only-inhabited-variant-stable.rs | 3 +-- .../2229_closure_analysis/only-inhabited-variant-stable.stderr | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs index a8e4b9cd1823..c7f367cc48ab 100644 --- a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs @@ -3,7 +3,6 @@ // depending on whether some types are inhabited goes too far, introducing a // bunch of headaches without much benefit. //@ edition:2021 -#[derive(Clone, Copy, PartialEq, Eq, Debug)] enum Void {} pub fn main() { @@ -19,5 +18,5 @@ pub fn main() { }; f(); g(); - assert_eq!(r, Err((1, 2))); + assert!(matches!(r, Err((1, 2)))); } diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr index dea85ff947ce..7f4c8942b0d9 100644 --- a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `r` as mutable more than once at a time - --> $DIR/only-inhabited-variant-stable.rs:15:17 + --> $DIR/only-inhabited-variant-stable.rs:14:17 | LL | let mut f = || { | -- first mutable borrow occurs here From 462b51a525b80200151c344c59f81f8af0788610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Tue, 22 Apr 2025 01:02:48 +0200 Subject: [PATCH 0947/3801] Add debug logging in hir_typeck::upvar This aims to make each major part responsible for modifying the precision be visible in the logs. --- compiler/rustc_hir_typeck/src/upvar.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 445386412058..1a2b76485f35 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -761,6 +761,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// ], /// } /// ``` + #[instrument(level = "debug", skip(self))] fn compute_min_captures( &self, closure_def_id: LocalDefId, @@ -2029,6 +2030,7 @@ struct InferBorrowKind<'tcx> { } impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { + #[instrument(skip(self), level = "debug")] fn fake_read( &mut self, place_with_id: &PlaceWithHirId<'tcx>, @@ -2119,6 +2121,7 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { } /// Rust doesn't permit moving fields out of a type that implements drop +#[instrument(skip(fcx), ret, level = "debug")] fn restrict_precision_for_drop_types<'a, 'tcx>( fcx: &'a FnCtxt<'a, 'tcx>, mut place: Place<'tcx>, @@ -2179,6 +2182,7 @@ fn restrict_precision_for_unsafe( /// - No unsafe block is required to capture `place`. /// /// Returns the truncated place and updated capture mode. +#[instrument(ret, level = "debug")] fn restrict_capture_precision( place: Place<'_>, curr_mode: ty::UpvarCapture, @@ -2208,6 +2212,7 @@ fn restrict_capture_precision( } /// Truncate deref of any reference. +#[instrument(ret, level = "debug")] fn adjust_for_move_closure( mut place: Place<'_>, mut kind: ty::UpvarCapture, @@ -2222,6 +2227,7 @@ fn adjust_for_move_closure( } /// Truncate deref of any reference. +#[instrument(ret, level = "debug")] fn adjust_for_use_closure( mut place: Place<'_>, mut kind: ty::UpvarCapture, @@ -2237,6 +2243,7 @@ fn adjust_for_use_closure( /// Adjust closure capture just that if taking ownership of data, only move data /// from enclosing stack frame. +#[instrument(ret, level = "debug")] fn adjust_for_non_move_closure( mut place: Place<'_>, mut kind: ty::UpvarCapture, @@ -2559,6 +2566,7 @@ fn determine_place_ancestry_relation<'tcx>( /// // it is constrained to `'a` /// } /// ``` +#[instrument(ret, level = "debug")] fn truncate_capture_for_optimization( mut place: Place<'_>, mut curr_mode: ty::UpvarCapture, From 19f6bc4ab7c8e8a740ab9dbe0c012e5e59431cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Tue, 22 Apr 2025 02:51:46 +0200 Subject: [PATCH 0948/3801] Add miri tests for new closure capture behavior --- .../tests/fail/closures/deref-in-pattern.rs | 20 ++++++++++++ .../fail/closures/deref-in-pattern.stderr | 20 ++++++++++++ .../tests/fail/closures/partial-pattern.rs | 28 +++++++++++++++++ .../fail/closures/partial-pattern.stderr | 20 ++++++++++++ .../fail/closures/uninhabited-variant.rs | 31 +++++++++++++++++++ .../fail/closures/uninhabited-variant.stderr | 20 ++++++++++++ 6 files changed, 139 insertions(+) create mode 100644 src/tools/miri/tests/fail/closures/deref-in-pattern.rs create mode 100644 src/tools/miri/tests/fail/closures/deref-in-pattern.stderr create mode 100644 src/tools/miri/tests/fail/closures/partial-pattern.rs create mode 100644 src/tools/miri/tests/fail/closures/partial-pattern.stderr create mode 100644 src/tools/miri/tests/fail/closures/uninhabited-variant.rs create mode 100644 src/tools/miri/tests/fail/closures/uninhabited-variant.stderr diff --git a/src/tools/miri/tests/fail/closures/deref-in-pattern.rs b/src/tools/miri/tests/fail/closures/deref-in-pattern.rs new file mode 100644 index 000000000000..c729469c78b0 --- /dev/null +++ b/src/tools/miri/tests/fail/closures/deref-in-pattern.rs @@ -0,0 +1,20 @@ +// This test serves to document the change in semantics introduced by +// rust-lang/rust#138961. +// +// A corollary of partial-pattern.rs: while the tuple access testcase makes +// it clear why these semantics are useful, it is actually the dereference +// being performed by the pattern that matters. + +fn main() { + // the inner reference is dangling + let x: &&u32 = unsafe { + let x: u32 = 42; + &&* &raw const x + }; + + let _ = || { //~ ERROR: encountered a dangling reference + match x { + &&_y => {}, + } + }; +} diff --git a/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr b/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr new file mode 100644 index 000000000000..aa97fd4b7ac2 --- /dev/null +++ b/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: constructing invalid value: encountered a dangling reference (use-after-free) + --> tests/fail/closures/deref-in-pattern.rs:LL:CC + | +LL | let _ = || { + | _____________^ +LL | | match x { +LL | | &&_y => {}, +LL | | } +LL | | }; + | |_____^ constructing invalid value: encountered a dangling reference (use-after-free) + | + = 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 + = note: BACKTRACE: + = note: inside `main` at tests/fail/closures/deref-in-pattern.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/closures/partial-pattern.rs b/src/tools/miri/tests/fail/closures/partial-pattern.rs new file mode 100644 index 000000000000..cb6446208180 --- /dev/null +++ b/src/tools/miri/tests/fail/closures/partial-pattern.rs @@ -0,0 +1,28 @@ +// This test serves to document the change in semantics introduced by +// rust-lang/rust#138961. +// +// Previously, the closure would capture the entirety of x, and access *(*x).0 +// when called. Now, the closure only captures *(*x).0, which means that +// a &*(*x).0 reborrow happens when the closure is constructed. +// +// Hence, if one of the references is dangling, this constitutes newly introduced UB +// in the case where the closure doesn't get called. This isn't a big deal, +// because while opsem only now considers this to be UB, the unsafe code +// guidelines have long recommended against any handling of dangling references. + +fn main() { + // the inner references are dangling + let x: &(&u32, &u32) = unsafe { + let a = 21; + let b = 37; + let ra = &* &raw const a; + let rb = &* &raw const b; + &(ra, rb) + }; + + let _ = || { //~ ERROR: encountered a dangling reference + match x { + (&_y, _) => {}, + } + }; +} diff --git a/src/tools/miri/tests/fail/closures/partial-pattern.stderr b/src/tools/miri/tests/fail/closures/partial-pattern.stderr new file mode 100644 index 000000000000..67b26709eb0d --- /dev/null +++ b/src/tools/miri/tests/fail/closures/partial-pattern.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: constructing invalid value: encountered a dangling reference (use-after-free) + --> tests/fail/closures/partial-pattern.rs:LL:CC + | +LL | let _ = || { + | _____________^ +LL | | match x { +LL | | (&_y, _) => {}, +LL | | } +LL | | }; + | |_____^ constructing invalid value: encountered a dangling reference (use-after-free) + | + = 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 + = note: BACKTRACE: + = note: inside `main` at tests/fail/closures/partial-pattern.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/closures/uninhabited-variant.rs b/src/tools/miri/tests/fail/closures/uninhabited-variant.rs new file mode 100644 index 000000000000..9c50fdc13a35 --- /dev/null +++ b/src/tools/miri/tests/fail/closures/uninhabited-variant.rs @@ -0,0 +1,31 @@ +// Motivated by rust-lang/rust#138961, this shows how invalid discriminants interact with +// closure captures. +#![feature(never_type)] + +#[repr(C)] +#[allow(dead_code)] +enum E { + V0, // discriminant: 0 + V1, // 1 + V2(!), // 2 +} + +fn main() { + assert_eq!(std::mem::size_of::(), 4); + + let val = 2u32; + let ptr = (&raw const val).cast::(); + let r = unsafe { &*ptr }; + let f = || { + // After rust-lang/rust#138961, constructing the closure performs a reborrow of r. + // Nevertheless, the discriminant is only actually inspected when the closure + // is called. + match r { //~ ERROR: read discriminant of an uninhabited enum variant + E::V0 => {} + E::V1 => {} + E::V2(_) => {} + } + }; + + f(); +} diff --git a/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr b/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr new file mode 100644 index 000000000000..0c374804b970 --- /dev/null +++ b/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: read discriminant of an uninhabited enum variant + --> tests/fail/closures/uninhabited-variant.rs:LL:CC + | +LL | match r { + | ^ read discriminant of an uninhabited enum variant + | + = 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 + = note: BACKTRACE: + = note: inside closure at tests/fail/closures/uninhabited-variant.rs:LL:CC +note: inside `main` + --> tests/fail/closures/uninhabited-variant.rs:LL:CC + | +LL | f(); + | ^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From e6c59990bd91b3b2b4c97192baf1d7e92baadd45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Tue, 22 Apr 2025 03:32:20 +0200 Subject: [PATCH 0949/3801] add a comment: MatchPair and ExprUseVisitor must stay in sync --- compiler/rustc_mir_build/src/builder/matches/match_pair.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index a0d54354a9c6..67c12bfa7790 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -339,6 +339,12 @@ impl<'tcx> MatchPairTree<'tcx> { if let Some(test_case) = test_case { // This pattern is refutable, so push a new match-pair node. + // + // Note: unless test_case is TestCase::Or, place must not be None. + // This means that the closure capture analysis in + // rustc_hir_typeck::upvar, and in particular the pattern handling + // code of ExprUseVisitor, must capture all of the places we'll use. + // Make sure to keep these two parts in sync! match_pairs.push(MatchPairTree { place, test_case, From 3d5d1d72e0db38ff9832df8021fd62af873f1d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sat, 31 May 2025 00:07:16 +0200 Subject: [PATCH 0950/3801] Mark crash 140011 as fixed --- tests/crashes/140011.rs | 11 ------ .../malformed-pattern-issue-140011.rs | 13 +++++++ .../malformed-pattern-issue-140011.stderr | 36 +++++++++++++++++++ 3 files changed, 49 insertions(+), 11 deletions(-) delete mode 100644 tests/crashes/140011.rs create mode 100644 tests/ui/closures/malformed-pattern-issue-140011.rs create mode 100644 tests/ui/closures/malformed-pattern-issue-140011.stderr diff --git a/tests/crashes/140011.rs b/tests/crashes/140011.rs deleted file mode 100644 index b9d57a2822d2..000000000000 --- a/tests/crashes/140011.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #140011 -//@compile-flags: -Wrust-2021-incompatible-closure-captures -enum b { - c(d), - e(f), -} -struct f; -fn g() { - let h; - || b::e(a) = h; -} diff --git a/tests/ui/closures/malformed-pattern-issue-140011.rs b/tests/ui/closures/malformed-pattern-issue-140011.rs new file mode 100644 index 000000000000..18061613e988 --- /dev/null +++ b/tests/ui/closures/malformed-pattern-issue-140011.rs @@ -0,0 +1,13 @@ +//@compile-flags: -Wrust-2021-incompatible-closure-captures +enum B { + C(D), //~ ERROR: cannot find type `D` in this scope + E(F), +} +struct F; +fn f(h: B) { + || { + let B::E(a) = h; //~ ERROR: refutable pattern in local binding + }; +} + +fn main() {} diff --git a/tests/ui/closures/malformed-pattern-issue-140011.stderr b/tests/ui/closures/malformed-pattern-issue-140011.stderr new file mode 100644 index 000000000000..08122b8a7d2e --- /dev/null +++ b/tests/ui/closures/malformed-pattern-issue-140011.stderr @@ -0,0 +1,36 @@ +error[E0412]: cannot find type `D` in this scope + --> $DIR/malformed-pattern-issue-140011.rs:3:7 + | +LL | C(D), + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | enum B { + | +++ + +error[E0005]: refutable pattern in local binding + --> $DIR/malformed-pattern-issue-140011.rs:9:13 + | +LL | let B::E(a) = h; + | ^^^^^^^ pattern `B::C(_)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html +note: `B` defined here + --> $DIR/malformed-pattern-issue-140011.rs:2:6 + | +LL | enum B { + | ^ +LL | C(D), + | - not covered + = note: the matched value is of type `B` +help: you might want to use `let else` to handle the variant that isn't matched + | +LL | let B::E(a) = h else { todo!() }; + | ++++++++++++++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0005, E0412. +For more information about an error, try `rustc --explain E0005`. From a2e249cd2672843493b641518141b62c0bccf745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sat, 31 May 2025 00:13:46 +0200 Subject: [PATCH 0951/3801] =?UTF-8?q?ExprUseVisitor:=20resolve=20a=20FIXME?= =?UTF-8?q?=20=E2=80=93=20it's=20fine=20as=20is?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index b35f62df82b7..93304d794bc2 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -929,10 +929,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // When matching against a literal or range, we need to // borrow the place to compare it against the pattern. // + // Note that we do this read even if the range matches all + // possible values, such as 0..=u8::MAX. This is because + // we don't want to depend on consteval here. + // // FIXME: What if the type being matched only has one // possible value? - // FIXME: What if the range is the full range of the type - // and doesn't actually require a discriminant read? read_discriminant(); } PatKind::Struct(..) | PatKind::TupleStruct(..) => { From 4f7915ba58a77cedc06d755bdeb714a9057ddc35 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 15 Oct 2025 07:27:39 +0000 Subject: [PATCH 0952/3801] Bless miri tests --- src/tools/miri/tests/fail/closures/deref-in-pattern.stderr | 2 +- src/tools/miri/tests/fail/closures/partial-pattern.stderr | 2 +- src/tools/miri/tests/fail/closures/uninhabited-variant.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr b/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr index aa97fd4b7ac2..ccdfad577315 100644 --- a/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr +++ b/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr @@ -7,7 +7,7 @@ LL | | match x { LL | | &&_y => {}, LL | | } LL | | }; - | |_____^ constructing invalid value: encountered a dangling reference (use-after-free) + | |_____^ 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/closures/partial-pattern.stderr b/src/tools/miri/tests/fail/closures/partial-pattern.stderr index 67b26709eb0d..f26d6ffed54b 100644 --- a/src/tools/miri/tests/fail/closures/partial-pattern.stderr +++ b/src/tools/miri/tests/fail/closures/partial-pattern.stderr @@ -7,7 +7,7 @@ LL | | match x { LL | | (&_y, _) => {}, LL | | } LL | | }; - | |_____^ constructing invalid value: encountered a dangling reference (use-after-free) + | |_____^ 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/closures/uninhabited-variant.stderr b/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr index 0c374804b970..995a5e3eac14 100644 --- a/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr +++ b/src/tools/miri/tests/fail/closures/uninhabited-variant.stderr @@ -2,7 +2,7 @@ error: Undefined Behavior: read discriminant of an uninhabited enum variant --> tests/fail/closures/uninhabited-variant.rs:LL:CC | LL | match r { - | ^ read discriminant of an uninhabited enum variant + | ^ 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 From d05b1d76f3ae7f1cebd17613f17058669b5971a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sun, 19 Oct 2025 00:38:31 +0200 Subject: [PATCH 0953/3801] Add a test for deref projections in new pattern capture behavior --- .../deref-mut-in-pattern.rs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs diff --git a/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs b/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs new file mode 100644 index 000000000000..4839fc7d9192 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs @@ -0,0 +1,35 @@ +// Newly accepted examples as a result of the changes introduced in #138961. +// +//@ edition:2024 +//@ check-pass +#![allow(unused_assignments)] + +fn f() { + let mut x: &mut [u8] = &mut [1, 2, 3]; + let c = || { + match x { + [] => (), + _ => (), + } + }; + x = &mut []; + c(); +} + +fn g() { + let mut x: &mut bool = &mut false; + let mut t = true; + let c = || { + match x { + true => (), + false => (), + } + }; + x = &mut t; + c(); +} + +fn main() { + f(); + g(); +} From 2443fba3a2af1f4474ba76f5a10627157fe59f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sun, 19 Oct 2025 00:49:56 +0200 Subject: [PATCH 0954/3801] Rewrite the comment on is_multivariant_adt As Nadrieril remarked, the previous comment was misleadingly framed. --- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 93304d794bc2..12c4dd203203 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1855,9 +1855,14 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx /// builder code does a more specific check, filtering out variants that /// happen to be uninhabited. /// - /// Here, we cannot perform such an accurate checks, because querying - /// whether a type is inhabited requires that it has been fully inferred, - /// which cannot be guaranteed at this point. + /// Here, it is not practical to perform such a check, because inhabitedness + /// queries require typeck results, and typeck requires closure capture analysis. + /// + /// Moreover, the language is moving towards uninhabited variants still semantically + /// causing a discriminant read, so we *shouldn't* perform any such check. + /// + /// FIXME(never_patterns): update this comment once the aforementioned MIR builder + /// code is changed to be insensitive to inhhabitedness. #[instrument(skip(self, span), level = "debug")] fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool { if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() { From ae19274fb290396849c12e2b059dfbe4170964ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Sun, 19 Oct 2025 16:13:50 +0200 Subject: [PATCH 0955/3801] Add more variations from the PR thread --- .../deref-mut-in-pattern.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs b/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs index 4839fc7d9192..b2c0eac9efa2 100644 --- a/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs +++ b/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs @@ -4,6 +4,7 @@ //@ check-pass #![allow(unused_assignments)] +// Reading the length as part of a pattern captures the pointee. fn f() { let mut x: &mut [u8] = &mut [1, 2, 3]; let c = || { @@ -16,6 +17,7 @@ fn f() { c(); } +// Plain old deref as part of pattern behaves similarly fn g() { let mut x: &mut bool = &mut false; let mut t = true; @@ -29,6 +31,23 @@ fn g() { c(); } +// Like f, but the lifetime implications are expressed in terms of +// returning a closure. +fn f2<'l: 's, 's>(x: &'s mut &'l [u8]) -> impl Fn() + 'l { + || match *x { + &[] => (), + _ => (), + } +} + +// Related testcase that was already accepted before +fn f3<'l: 's, 's>(x: &'s mut &'l [u8]) -> impl Fn() + 'l { + || match **x { + [] => (), + _ => (), + } +} + fn main() { f(); g(); From 9e98885a97094766293fbd0d5a0737d6e95f3b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Fri, 14 Nov 2025 23:53:46 +0100 Subject: [PATCH 0956/3801] re-bless miri tests --- src/tools/miri/tests/fail/closures/deref-in-pattern.stderr | 2 -- src/tools/miri/tests/fail/closures/partial-pattern.stderr | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr b/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr index ccdfad577315..1264f4e3fb95 100644 --- a/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr +++ b/src/tools/miri/tests/fail/closures/deref-in-pattern.stderr @@ -11,8 +11,6 @@ LL | | }; | = 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 - = note: BACKTRACE: - = note: inside `main` at tests/fail/closures/deref-in-pattern.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/closures/partial-pattern.stderr b/src/tools/miri/tests/fail/closures/partial-pattern.stderr index f26d6ffed54b..5b7ee35ecc73 100644 --- a/src/tools/miri/tests/fail/closures/partial-pattern.stderr +++ b/src/tools/miri/tests/fail/closures/partial-pattern.stderr @@ -11,8 +11,6 @@ LL | | }; | = 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 - = note: BACKTRACE: - = note: inside `main` at tests/fail/closures/partial-pattern.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace From de65837b5bda534a332041e9b1ae4bb0d779e968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Fri, 14 Nov 2025 23:53:58 +0100 Subject: [PATCH 0957/3801] `search_is_some`: move to nursery See clippy issue 16086 for context --- .../clippy/clippy_lints/src/methods/mod.rs | 2 +- src/tools/clippy/tests/ui/crashes/ice-9041.rs | 1 + .../clippy/tests/ui/crashes/ice-9041.stderr | 2 +- .../ui/search_is_some_fixable_some.fixed | 14 +++++---- .../tests/ui/search_is_some_fixable_some.rs | 7 +++-- .../ui/search_is_some_fixable_some.stderr | 29 +------------------ 6 files changed, 18 insertions(+), 37 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 48842c8739c0..248a147cfd77 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -889,7 +889,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "pre 1.29.0"] pub SEARCH_IS_SOME, - complexity, + nursery, "using an iterator or string search followed by `is_some()` or `is_none()`, which is more succinctly expressed as a call to `any()` or `contains()` (with negation in case of `is_none()`)" } diff --git a/src/tools/clippy/tests/ui/crashes/ice-9041.rs b/src/tools/clippy/tests/ui/crashes/ice-9041.rs index 4b2a0f953114..fae3233ba2f5 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-9041.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-9041.rs @@ -1,3 +1,4 @@ +#![warn(clippy::search_is_some)] pub struct Thing; //@no-rustfix pub fn has_thing(things: &[Thing]) -> bool { diff --git a/src/tools/clippy/tests/ui/crashes/ice-9041.stderr b/src/tools/clippy/tests/ui/crashes/ice-9041.stderr index dd9db71c5de8..256c8b833034 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-9041.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-9041.stderr @@ -1,5 +1,5 @@ error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/crashes/ice-9041.rs:5:19 + --> tests/ui/crashes/ice-9041.rs:6:19 | LL | things.iter().find(|p| is_thing_ready(p)).is_some() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|p| is_thing_ready(&p))` diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed b/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed index 1213fdcf6119..daae41c0c891 100644 --- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed +++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed @@ -311,19 +311,23 @@ mod issue9120 { } } +// skip this test due to rust-lang/rust-clippy#16086 +/* #[allow(clippy::match_like_matches_macro)] fn issue15102() { let values = [None, Some(3)]; - let has_even = values.iter().any(|v| matches!(&v, Some(x) if x % 2 == 0)); - //~^ search_is_some + let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some(); + ~^ search_is_some println!("{has_even}"); let has_even = values .iter() - .any(|v| match &v { - //~^ search_is_some + .find(|v| match v { + ~^ search_is_some Some(x) if x % 2 == 0 => true, _ => false, - }); + }) + .is_some(); println!("{has_even}"); } +*/ diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs b/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs index 4294a39333f2..ead101a491a6 100644 --- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs +++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs @@ -322,20 +322,23 @@ mod issue9120 { } } +// skip this test due to rust-lang/rust-clippy#16086 +/* #[allow(clippy::match_like_matches_macro)] fn issue15102() { let values = [None, Some(3)]; let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some(); - //~^ search_is_some + ~^ search_is_some println!("{has_even}"); let has_even = values .iter() .find(|v| match v { - //~^ search_is_some + ~^ search_is_some Some(x) if x % 2 == 0 => true, _ => false, }) .is_some(); println!("{has_even}"); } +*/ diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr b/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr index cee1eb08876b..c56fe859aac0 100644 --- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr +++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr @@ -346,32 +346,5 @@ error: called `is_some()` after searching an `Iterator` with `find` LL | let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| (*arg_no_deref_dyn)(&x))` -error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:328:34 - | -LL | let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| matches!(&v, Some(x) if x % 2 == 0))` - -error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:334:10 - | -LL | .find(|v| match v { - | __________^ -LL | | -LL | | Some(x) if x % 2 == 0 => true, -LL | | _ => false, -LL | | }) -LL | | .is_some(); - | |__________________^ - | -help: consider using - | -LL ~ .any(|v| match &v { -LL + -LL + Some(x) if x % 2 == 0 => true, -LL + _ => false, -LL ~ }); - | - -error: aborting due to 51 previous errors +error: aborting due to 49 previous errors From 55bbe0531a2d2f58daec7feb525b3eaa13063b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Fri, 12 Dec 2025 20:23:34 +0100 Subject: [PATCH 0958/3801] Re-bless tests --- tests/ui/closures/malformed-pattern-issue-140011.stderr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui/closures/malformed-pattern-issue-140011.stderr b/tests/ui/closures/malformed-pattern-issue-140011.stderr index 08122b8a7d2e..43beb7c58632 100644 --- a/tests/ui/closures/malformed-pattern-issue-140011.stderr +++ b/tests/ui/closures/malformed-pattern-issue-140011.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `D` in this scope +error[E0425]: cannot find type `D` in this scope --> $DIR/malformed-pattern-issue-140011.rs:3:7 | LL | C(D), @@ -25,12 +25,12 @@ LL | enum B { LL | C(D), | - not covered = note: the matched value is of type `B` -help: you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let...else` to handle the variant that isn't matched | LL | let B::E(a) = h else { todo!() }; | ++++++++++++++++ error: aborting due to 2 previous errors -Some errors have detailed explanations: E0005, E0412. +Some errors have detailed explanations: E0005, E0425. For more information about an error, try `rustc --explain E0005`. From cc2c59efa8777f2b8576a4e1316845d19fddd1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Fri, 14 Nov 2025 23:53:58 +0100 Subject: [PATCH 0959/3801] `search_is_some`: move to nursery See clippy issue 16086 for context --- clippy_lints/src/methods/mod.rs | 2 +- tests/ui/crashes/ice-9041.rs | 1 + tests/ui/crashes/ice-9041.stderr | 2 +- tests/ui/search_is_some_fixable_some.fixed | 14 ++++++---- tests/ui/search_is_some_fixable_some.rs | 7 +++-- tests/ui/search_is_some_fixable_some.stderr | 29 +-------------------- 6 files changed, 18 insertions(+), 37 deletions(-) diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 48842c8739c0..248a147cfd77 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -889,7 +889,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "pre 1.29.0"] pub SEARCH_IS_SOME, - complexity, + nursery, "using an iterator or string search followed by `is_some()` or `is_none()`, which is more succinctly expressed as a call to `any()` or `contains()` (with negation in case of `is_none()`)" } diff --git a/tests/ui/crashes/ice-9041.rs b/tests/ui/crashes/ice-9041.rs index 4b2a0f953114..fae3233ba2f5 100644 --- a/tests/ui/crashes/ice-9041.rs +++ b/tests/ui/crashes/ice-9041.rs @@ -1,3 +1,4 @@ +#![warn(clippy::search_is_some)] pub struct Thing; //@no-rustfix pub fn has_thing(things: &[Thing]) -> bool { diff --git a/tests/ui/crashes/ice-9041.stderr b/tests/ui/crashes/ice-9041.stderr index dd9db71c5de8..256c8b833034 100644 --- a/tests/ui/crashes/ice-9041.stderr +++ b/tests/ui/crashes/ice-9041.stderr @@ -1,5 +1,5 @@ error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/crashes/ice-9041.rs:5:19 + --> tests/ui/crashes/ice-9041.rs:6:19 | LL | things.iter().find(|p| is_thing_ready(p)).is_some() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|p| is_thing_ready(&p))` diff --git a/tests/ui/search_is_some_fixable_some.fixed b/tests/ui/search_is_some_fixable_some.fixed index 1213fdcf6119..daae41c0c891 100644 --- a/tests/ui/search_is_some_fixable_some.fixed +++ b/tests/ui/search_is_some_fixable_some.fixed @@ -311,19 +311,23 @@ mod issue9120 { } } +// skip this test due to rust-lang/rust-clippy#16086 +/* #[allow(clippy::match_like_matches_macro)] fn issue15102() { let values = [None, Some(3)]; - let has_even = values.iter().any(|v| matches!(&v, Some(x) if x % 2 == 0)); - //~^ search_is_some + let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some(); + ~^ search_is_some println!("{has_even}"); let has_even = values .iter() - .any(|v| match &v { - //~^ search_is_some + .find(|v| match v { + ~^ search_is_some Some(x) if x % 2 == 0 => true, _ => false, - }); + }) + .is_some(); println!("{has_even}"); } +*/ diff --git a/tests/ui/search_is_some_fixable_some.rs b/tests/ui/search_is_some_fixable_some.rs index 4294a39333f2..ead101a491a6 100644 --- a/tests/ui/search_is_some_fixable_some.rs +++ b/tests/ui/search_is_some_fixable_some.rs @@ -322,20 +322,23 @@ mod issue9120 { } } +// skip this test due to rust-lang/rust-clippy#16086 +/* #[allow(clippy::match_like_matches_macro)] fn issue15102() { let values = [None, Some(3)]; let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some(); - //~^ search_is_some + ~^ search_is_some println!("{has_even}"); let has_even = values .iter() .find(|v| match v { - //~^ search_is_some + ~^ search_is_some Some(x) if x % 2 == 0 => true, _ => false, }) .is_some(); println!("{has_even}"); } +*/ diff --git a/tests/ui/search_is_some_fixable_some.stderr b/tests/ui/search_is_some_fixable_some.stderr index cee1eb08876b..c56fe859aac0 100644 --- a/tests/ui/search_is_some_fixable_some.stderr +++ b/tests/ui/search_is_some_fixable_some.stderr @@ -346,32 +346,5 @@ error: called `is_some()` after searching an `Iterator` with `find` LL | let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| (*arg_no_deref_dyn)(&x))` -error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:328:34 - | -LL | let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| matches!(&v, Some(x) if x % 2 == 0))` - -error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some_fixable_some.rs:334:10 - | -LL | .find(|v| match v { - | __________^ -LL | | -LL | | Some(x) if x % 2 == 0 => true, -LL | | _ => false, -LL | | }) -LL | | .is_some(); - | |__________________^ - | -help: consider using - | -LL ~ .any(|v| match &v { -LL + -LL + Some(x) if x % 2 == 0 => true, -LL + _ => false, -LL ~ }); - | - -error: aborting due to 51 previous errors +error: aborting due to 49 previous errors From 78f52c1d127858c6d50751cd62876982b6708945 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 17 Dec 2025 20:16:02 +0000 Subject: [PATCH 0960/3801] Update tracking issue for PinCoerceUnsized --- library/alloc/src/boxed.rs | 2 +- library/alloc/src/rc.rs | 6 +++--- library/alloc/src/sync.rs | 6 +++--- library/core/src/cell.rs | 12 ++++++------ library/core/src/pin.rs | 2 +- library/core/src/ptr/unique.rs | 2 +- library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index f714a87c1868..60758551cc04 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2253,7 +2253,7 @@ impl + ?Sized, A: Allocator> AsyncFn for Box #[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized, A: Allocator> CoerceUnsized> for Box {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Box {} // It is quite crucial that we only allow the `Global` allocator here. diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index a3ebbbbaae05..8a72748668cc 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2417,14 +2417,14 @@ impl Deref for Rc { } } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Rc {} //#[unstable(feature = "unique_rc_arc", issue = "112566")] -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for UniqueRc {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Weak {} #[unstable(feature = "deref_pure_trait", issue = "87121")] diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 6a49017a8276..4180fe91cb55 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2423,10 +2423,10 @@ impl Deref for Arc { } } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Arc {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Weak {} #[unstable(feature = "deref_pure_trait", issue = "87121")] @@ -4852,7 +4852,7 @@ impl Deref for UniqueArc { } // #[unstable(feature = "unique_rc_arc", issue = "112566")] -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for UniqueArc {} #[unstable(feature = "unique_rc_arc", issue = "112566")] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index c8340c328be1..9a3f7166f1fc 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2696,20 +2696,20 @@ fn assert_coerce_unsized( let _: RefCell<&dyn Send> = d; } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for UnsafeCell {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for SyncUnsafeCell {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Cell {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for RefCell {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl<'b, T: ?Sized> PinCoerceUnsized for Ref<'b, T> {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl<'b, T: ?Sized> PinCoerceUnsized for RefMut<'b, T> {} diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 81c2dabf0d1d..74ecb5ee4946 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1825,7 +1825,7 @@ where { } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] /// Trait that indicates that this is a pointer or a wrapper for one, where /// unsizing can be performed on the pointee when it is pinned. /// diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 1bbe3ea242f6..3160c9de4b7e 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -176,7 +176,7 @@ impl CoerceUnsized> for Unique wh #[unstable(feature = "ptr_internals", issue = "none")] impl DispatchFromDyn> for Unique where T: Unsize {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Unique {} #[unstable(feature = "ptr_internals", issue = "none")] diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index fb410c285160..aaf380d1bef4 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs @@ -773,7 +773,7 @@ where #[unstable(feature = "sgx_platform", issue = "56975")] impl, U> CoerceUnsized> for UserRef {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for UserRef {} #[unstable(feature = "sgx_platform", issue = "56975")] From d28e41b981651e95d60ed95b66c78c4ebdce20eb Mon Sep 17 00:00:00 2001 From: Niko Kajula Date: Wed, 17 Dec 2025 22:41:21 +0200 Subject: [PATCH 0961/3801] Fix broken AMD Developer's Manual links --- library/stdarch/crates/core_arch/src/x86/abm.rs | 2 +- library/stdarch/crates/core_arch/src/x86/avx.rs | 2 +- library/stdarch/crates/core_arch/src/x86/avx2.rs | 2 +- library/stdarch/crates/core_arch/src/x86/cpuid.rs | 2 +- library/stdarch/crates/core_arch/src/x86/fma.rs | 2 +- library/stdarch/crates/core_arch/src/x86/tbm.rs | 2 +- library/stdarch/crates/core_arch/src/x86_64/abm.rs | 2 +- library/stdarch/crates/core_arch/src/x86_64/avx.rs | 2 +- library/stdarch/crates/core_arch/src/x86_64/tbm.rs | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/stdarch/crates/core_arch/src/x86/abm.rs b/library/stdarch/crates/core_arch/src/x86/abm.rs index 59f3877b4ace..7f46e1a8d06e 100644 --- a/library/stdarch/crates/core_arch/src/x86/abm.rs +++ b/library/stdarch/crates/core_arch/src/x86/abm.rs @@ -13,7 +13,7 @@ //! available. //! //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf -//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +//! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wikipedia_bmi]: //! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 diff --git a/library/stdarch/crates/core_arch/src/x86/avx.rs b/library/stdarch/crates/core_arch/src/x86/avx.rs index acba0a3db7c6..bda0b8ac5047 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx.rs @@ -10,7 +10,7 @@ //! [Wikipedia][wiki] provides a quick overview of the instructions available. //! //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf -//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +//! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wiki]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions use crate::{ diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index b3b2accd7338..e7fd19fa2e97 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -14,7 +14,7 @@ //! overview of the instructions available. //! //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf -//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +//! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wiki_avx]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions //! [wiki_fma]: https://en.wikipedia.org/wiki/Fused_multiply-accumulate diff --git a/library/stdarch/crates/core_arch/src/x86/cpuid.rs b/library/stdarch/crates/core_arch/src/x86/cpuid.rs index b35699bd7ab2..3f13ea8369bb 100644 --- a/library/stdarch/crates/core_arch/src/x86/cpuid.rs +++ b/library/stdarch/crates/core_arch/src/x86/cpuid.rs @@ -54,7 +54,7 @@ pub struct CpuidResult { /// /// [wiki_cpuid]: https://en.wikipedia.org/wiki/CPUID /// [intel64_ref]: https://cdrdv2-public.intel.com/671110/325383-sdm-vol-2abcd.pdf -/// [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +/// [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 #[inline] #[cfg_attr(test, assert_instr(cpuid))] #[stable(feature = "simd_x86", since = "1.27.0")] diff --git a/library/stdarch/crates/core_arch/src/x86/fma.rs b/library/stdarch/crates/core_arch/src/x86/fma.rs index abf79f4904fe..a8439935660f 100644 --- a/library/stdarch/crates/core_arch/src/x86/fma.rs +++ b/library/stdarch/crates/core_arch/src/x86/fma.rs @@ -15,7 +15,7 @@ //! instructions available. //! //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf -//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +//! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wiki_fma]: https://en.wikipedia.org/wiki/Fused_multiply-accumulate use crate::core_arch::x86::*; diff --git a/library/stdarch/crates/core_arch/src/x86/tbm.rs b/library/stdarch/crates/core_arch/src/x86/tbm.rs index d7769b916d4f..1e863fe15c0b 100644 --- a/library/stdarch/crates/core_arch/src/x86/tbm.rs +++ b/library/stdarch/crates/core_arch/src/x86/tbm.rs @@ -6,7 +6,7 @@ //! [Wikipedia][wikipedia_bmi] provides a quick overview of the available //! instructions. //! -//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +//! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wikipedia_bmi]: //! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 diff --git a/library/stdarch/crates/core_arch/src/x86_64/abm.rs b/library/stdarch/crates/core_arch/src/x86_64/abm.rs index 63e422864d3b..2b63cb5dc763 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/abm.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/abm.rs @@ -13,7 +13,7 @@ //! available. //! //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf -//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +//! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wikipedia_bmi]: //! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 diff --git a/library/stdarch/crates/core_arch/src/x86_64/avx.rs b/library/stdarch/crates/core_arch/src/x86_64/avx.rs index bb8d25620714..80ef7fbd60a6 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/avx.rs @@ -10,7 +10,7 @@ //! [Wikipedia][wiki] provides a quick overview of the instructions available. //! //! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf -//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +//! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wiki]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions use crate::{core_arch::x86::*, mem::transmute}; diff --git a/library/stdarch/crates/core_arch/src/x86_64/tbm.rs b/library/stdarch/crates/core_arch/src/x86_64/tbm.rs index e7d4b8d3e4c9..031bd320713e 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/tbm.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/tbm.rs @@ -6,7 +6,7 @@ //! [Wikipedia][wikipedia_bmi] provides a quick overview of the available //! instructions. //! -//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf +//! [amd64_ref]: https://docs.amd.com/v/u/en-US/24594_3.37 //! [wikipedia_bmi]: //! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29 From 901fe3f804a7adb4390b533a783ee00a89f25ad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heath=20Dutton=F0=9F=95=B4=EF=B8=8F?= Date: Tue, 16 Dec 2025 18:31:01 -0500 Subject: [PATCH 0962/3801] Fix `LinkedList::CursorMut::pop_front` to correctly update index When `pop_front` was called while the cursor pointed to the front element, `move_next` incremented the index but it was never decremented afterwards, causing the index to incorrectly report 1 instead of 0. Always decrement the index after popping from front using `saturating_sub` to handle edge cases safely. --- library/alloc/src/collections/linked_list.rs | 6 ++- .../src/collections/linked_list/tests.rs | 54 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index e738c29c237f..78e615ebb859 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1855,9 +1855,11 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { // node at index 0, which is expected. if self.list.head == self.current { self.move_next(); - } else { - self.index -= 1; } + // An element was removed before (or at) our current position, so + // the index must be decremented. `saturating_sub` handles the + // ghost node case where index could be 0. + self.index = self.index.saturating_sub(1); self.list.pop_front() } } diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index 3d6c740e80b3..a51af6345e20 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -748,6 +748,60 @@ fn test_cursor_pop_front_back() { assert_eq!(c.index, 2); } +#[test] +fn test_cursor_pop_front_index() { + // Regression test for issue #147616: `pop_front` was not correctly + // updating the cursor index when the cursor was pointing to the front. + + // Test case 1: pop_front when cursor is not at front, then at front + let mut ll: LinkedList = LinkedList::new(); + ll.extend(&[0, 1, 2]); + let mut c = ll.cursor_front_mut(); + + c.move_next(); + assert_eq!(c.index(), Some(1)); + assert_eq!(c.current(), Some(&mut 1)); + + // Pop front when cursor is not at front - index should decrement + c.pop_front(); + assert_eq!(c.index(), Some(0)); + assert_eq!(c.current(), Some(&mut 1)); + + // Now cursor is at front, pop_front again - index should remain 0 + c.pop_front(); + assert_eq!(c.index(), Some(0)); + assert_eq!(c.current(), Some(&mut 2)); + check_links(&ll); + + // Test case 2: minimal reproduction - cursor at front, pop_front + let mut ll: LinkedList = LinkedList::new(); + ll.extend(&[0, 1]); + let mut c = ll.cursor_front_mut(); + + assert_eq!(c.index(), Some(0)); + assert_eq!(c.current(), Some(&mut 0)); + + // Pop front when cursor is at front - should move to next and index stays 0 + c.pop_front(); + assert_eq!(c.index(), Some(0)); + assert_eq!(c.current(), Some(&mut 1)); + check_links(&ll); + + // Test case 3: single element list + let mut ll: LinkedList = LinkedList::new(); + ll.push_back(42); + let mut c = ll.cursor_front_mut(); + + assert_eq!(c.index(), Some(0)); + assert_eq!(c.current(), Some(&mut 42)); + + // Pop the only element - cursor should be at ghost node with index 0 + c.pop_front(); + assert_eq!(c.index(), None); + assert_eq!(c.current(), None); + check_links(&ll); +} + #[test] fn test_extend_ref() { let mut a = LinkedList::new(); From fd1a753d2b555ff91cbd7a0f552466a9137745b6 Mon Sep 17 00:00:00 2001 From: hulxv Date: Wed, 17 Dec 2025 22:54:51 +0200 Subject: [PATCH 0963/3801] Refactor CPU affinity tests to use errno_check for error handling --- .../miri/tests/pass-dep/libc/libc-affinity.rs | 54 ++++++++----------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-affinity.rs b/src/tools/miri/tests/pass-dep/libc/libc-affinity.rs index 400e3ca3d7db..87ef0510af4f 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-affinity.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-affinity.rs @@ -7,6 +7,10 @@ use std::mem::{size_of, size_of_val}; use libc::{cpu_set_t, sched_getaffinity, sched_setaffinity}; +#[path = "../../utils/libc.rs"] +mod libc_utils; +use libc_utils::errno_check; + // If pid is zero, then the calling thread is used. const PID: i32 = 0; @@ -41,8 +45,7 @@ fn configure_unavailable_cpu() { // Safety: valid value for this type let mut cpuset: cpu_set_t = unsafe { core::mem::MaybeUninit::zeroed().assume_init() }; - let err = unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }); // by default, only available CPUs are configured for i in 0..cpu_count { @@ -53,11 +56,9 @@ fn configure_unavailable_cpu() { // configure CPU that we don't have unsafe { libc::CPU_SET(cpu_count, &mut cpuset) }; - let err = unsafe { sched_setaffinity(PID, size_of::(), &cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_setaffinity(PID, size_of::(), &cpuset) }); - let err = unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }); // the CPU is not set because it is not available assert!(!unsafe { libc::CPU_ISSET(cpu_count, &cpuset) }); @@ -70,11 +71,11 @@ fn large_set() { // i.e. this has 2048 bits, twice the standard number let mut cpuset = [u64::MAX; 32]; - let err = unsafe { sched_setaffinity(PID, size_of_val(&cpuset), cpuset.as_ptr().cast()) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_setaffinity(PID, size_of_val(&cpuset), cpuset.as_ptr().cast()) }); - let err = unsafe { sched_getaffinity(PID, size_of_val(&cpuset), cpuset.as_mut_ptr().cast()) }; - assert_eq!(err, 0); + errno_check(unsafe { + sched_getaffinity(PID, size_of_val(&cpuset), cpuset.as_mut_ptr().cast()) + }); } fn get_small_cpu_mask() { @@ -91,8 +92,7 @@ fn get_small_cpu_mask() { assert_eq!(std::io::Error::last_os_error().kind(), std::io::ErrorKind::InvalidInput); } else { // other whole multiples of the size of c_ulong works - let err = unsafe { sched_getaffinity(PID, i, &mut cpuset) }; - assert_eq!(err, 0, "fail for {i}"); + errno_check(unsafe { sched_getaffinity(PID, i, &mut cpuset) }); } // anything else returns an error @@ -107,8 +107,7 @@ fn get_small_cpu_mask() { fn set_small_cpu_mask() { let mut cpuset: cpu_set_t = unsafe { core::mem::MaybeUninit::zeroed().assume_init() }; - let err = unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }); // setting a mask of size 0 is invalid let err = unsafe { sched_setaffinity(PID, 0, &cpuset) }; @@ -122,8 +121,7 @@ fn set_small_cpu_mask() { if cfg!(target_endian = "little") { 1 } else { core::mem::size_of::() }; for i in cpu_zero_included_length..24 { - let err = unsafe { sched_setaffinity(PID, i, &cpuset) }; - assert_eq!(err, 0, "fail for {i}"); + errno_check(unsafe { sched_setaffinity(PID, i, &cpuset) }); } } @@ -135,8 +133,7 @@ fn set_custom_cpu_mask() { let mut cpuset: cpu_set_t = unsafe { core::mem::MaybeUninit::zeroed().assume_init() }; // at the start, thread 1 should be set - let err = unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }); assert!(unsafe { libc::CPU_ISSET(1, &cpuset) }); // make a valid mask @@ -144,12 +141,10 @@ fn set_custom_cpu_mask() { unsafe { libc::CPU_SET(0, &mut cpuset) }; // giving a smaller mask is fine - let err = unsafe { sched_setaffinity(PID, 8, &cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_setaffinity(PID, 8, &cpuset) }); // and actually disables other threads - let err = unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }); assert!(unsafe { !libc::CPU_ISSET(1, &cpuset) }); // it is important that we reset the cpu mask now for future tests @@ -157,8 +152,7 @@ fn set_custom_cpu_mask() { unsafe { libc::CPU_SET(i, &mut cpuset) }; } - let err = unsafe { sched_setaffinity(PID, size_of::(), &cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_setaffinity(PID, size_of::(), &cpuset) }); } fn parent_child() { @@ -170,15 +164,13 @@ fn parent_child() { let mut parent_cpuset: cpu_set_t = unsafe { core::mem::MaybeUninit::zeroed().assume_init() }; unsafe { libc::CPU_SET(0, &mut parent_cpuset) }; - let err = unsafe { sched_setaffinity(PID, size_of::(), &parent_cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_setaffinity(PID, size_of::(), &parent_cpuset) }); std::thread::scope(|spawner| { spawner.spawn(|| { let mut cpuset: cpu_set_t = unsafe { core::mem::MaybeUninit::zeroed().assume_init() }; - let err = unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_getaffinity(PID, size_of::(), &mut cpuset) }); // the child inherits its parent's set assert!(unsafe { libc::CPU_ISSET(0, &cpuset) }); @@ -189,8 +181,7 @@ fn parent_child() { }); }); - let err = unsafe { sched_getaffinity(PID, size_of::(), &mut parent_cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_getaffinity(PID, size_of::(), &mut parent_cpuset) }); // the parent's set should be unaffected assert!(unsafe { !libc::CPU_ISSET(1, &parent_cpuset) }); @@ -201,8 +192,7 @@ fn parent_child() { unsafe { libc::CPU_SET(i, &mut cpuset) }; } - let err = unsafe { sched_setaffinity(PID, size_of::(), &cpuset) }; - assert_eq!(err, 0); + errno_check(unsafe { sched_setaffinity(PID, size_of::(), &cpuset) }); } fn main() { From d5d605acd46dd767c2aef0ff80c00328daf35b9f Mon Sep 17 00:00:00 2001 From: hulxv Date: Wed, 17 Dec 2025 23:05:04 +0200 Subject: [PATCH 0964/3801] Refactor libc time tests to use errno_check for error handling --- .../miri/tests/pass-dep/libc/libc-time.rs | 53 ++++++++----------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-time.rs b/src/tools/miri/tests/pass-dep/libc/libc-time.rs index 9e9fadfca9e7..b80fb0025530 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-time.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-time.rs @@ -1,8 +1,13 @@ //@ignore-target: windows # no libc time APIs on Windows //@compile-flags: -Zmiri-disable-isolation + +#[path = "../../utils/libc.rs"] +mod libc_utils; use std::time::{Duration, Instant}; use std::{env, mem, ptr}; +use libc_utils::errno_check; + fn main() { test_clocks(); test_posix_gettimeofday(); @@ -39,30 +44,23 @@ fn main() { /// Tests whether clock support exists at all fn test_clocks() { let mut tp = mem::MaybeUninit::::uninit(); - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); + errno_check(unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) }); + errno_check(unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, tp.as_mut_ptr()) }); #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "android"))] { - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); - let is_error = - unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); + errno_check(unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) }); + errno_check(unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) }); } #[cfg(target_os = "macos")] { - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_UPTIME_RAW, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); + errno_check(unsafe { libc::clock_gettime(libc::CLOCK_UPTIME_RAW, tp.as_mut_ptr()) }); } } fn test_posix_gettimeofday() { let mut tp = mem::MaybeUninit::::uninit(); let tz = ptr::null_mut::(); - let is_error = unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz.cast()) }; - assert_eq!(is_error, 0); + errno_check(unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz.cast()) }); let tv = unsafe { tp.assume_init() }; assert!(tv.tv_sec > 0); assert!(tv.tv_usec >= 0); // Theoretically this could be 0. @@ -334,15 +332,13 @@ fn test_nanosleep() { let start_test_sleep = Instant::now(); let duration_zero = libc::timespec { tv_sec: 0, tv_nsec: 0 }; let remainder = ptr::null_mut::(); - let is_error = unsafe { libc::nanosleep(&duration_zero, remainder) }; - assert_eq!(is_error, 0); + errno_check(unsafe { libc::nanosleep(&duration_zero, remainder) }); assert!(start_test_sleep.elapsed() < Duration::from_millis(100)); let start_test_sleep = Instant::now(); let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 }; let remainder = ptr::null_mut::(); - let is_error = unsafe { libc::nanosleep(&duration_100_millis, remainder) }; - assert_eq!(is_error, 0); + errno_check(unsafe { libc::nanosleep(&duration_100_millis, remainder) }); assert!(start_test_sleep.elapsed() > Duration::from_millis(100)); } @@ -371,8 +367,7 @@ mod test_clock_nanosleep { /// Helper function to get the current time for testing relative sleeps fn timespec_now(clock: libc::clockid_t) -> libc::timespec { let mut timespec = mem::MaybeUninit::::uninit(); - let is_error = unsafe { libc::clock_gettime(clock, timespec.as_mut_ptr()) }; - assert_eq!(is_error, 0); + errno_check(unsafe { libc::clock_gettime(clock, timespec.as_mut_ptr()) }); unsafe { timespec.assume_init() } } @@ -380,7 +375,7 @@ mod test_clock_nanosleep { let start_test_sleep = Instant::now(); let before_start = libc::timespec { tv_sec: 0, tv_nsec: 0 }; let remainder = ptr::null_mut::(); - let error = unsafe { + errno_check(unsafe { // this will not sleep since unix time zero is in the past libc::clock_nanosleep( libc::CLOCK_MONOTONIC, @@ -388,22 +383,20 @@ mod test_clock_nanosleep { &before_start, remainder, ) - }; - assert_eq!(error, 0); + }); assert!(start_test_sleep.elapsed() < Duration::from_millis(100)); let start_test_sleep = Instant::now(); let hunderd_millis_after_start = add_100_millis(timespec_now(libc::CLOCK_MONOTONIC)); let remainder = ptr::null_mut::(); - let error = unsafe { + errno_check(unsafe { libc::clock_nanosleep( libc::CLOCK_MONOTONIC, libc::TIMER_ABSTIME, &hunderd_millis_after_start, remainder, ) - }; - assert_eq!(error, 0); + }); assert!(start_test_sleep.elapsed() > Duration::from_millis(100)); } @@ -413,19 +406,17 @@ mod test_clock_nanosleep { let start_test_sleep = Instant::now(); let duration_zero = libc::timespec { tv_sec: 0, tv_nsec: 0 }; let remainder = ptr::null_mut::(); - let error = unsafe { + errno_check(unsafe { libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_zero, remainder) - }; - assert_eq!(error, 0); + }); assert!(start_test_sleep.elapsed() < Duration::from_millis(100)); let start_test_sleep = Instant::now(); let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 }; let remainder = ptr::null_mut::(); - let error = unsafe { + errno_check(unsafe { libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_100_millis, remainder) - }; - assert_eq!(error, 0); + }); assert!(start_test_sleep.elapsed() > Duration::from_millis(100)); } } From 011c5ed7ba0d20dec130609abafa7537d5ea199e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maja=20K=C4=85dzio=C5=82ka?= Date: Wed, 17 Dec 2025 22:11:55 +0100 Subject: [PATCH 0965/3801] Skip rust-analyzer closure layout tests for now --- .../crates/hir-ty/src/layout/tests/closure.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests/closure.rs index 6c76c6fed062..9e761aa98ff8 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests/closure.rs @@ -166,6 +166,9 @@ fn capture_specific_fields() { *a + x + (*b as i64) } } + // FIXME: These tests currently fail, because rust-analyzer hasn't yet implemented the changes + // introduced in rust-lang/rust#138961. See rust-lang/rust-analyzer#21274 for more discussion. + /* size_and_align_expr! { struct X(i64, i32, (u8, i128)); let y: X = X(2, 5, (7, 3)); @@ -183,6 +186,7 @@ fn capture_specific_fields() { a + x + (b as i64) } } + */ } #[test] @@ -194,6 +198,9 @@ fn match_pattern() { x } } + // FIXME: These tests currently fail, because rust-analyzer hasn't yet implemented the changes + // introduced in rust-lang/rust#138961. See rust-lang/rust-analyzer#21274 for more discussion. + /* size_and_align_expr! { minicore: copy; stmts: [ @@ -206,6 +213,7 @@ fn match_pattern() { } } } + */ size_and_align_expr! { minicore: copy; stmts: [ From 4ea5cac7d492e6b95e251b8a1f63a068186d74d7 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Wed, 29 Oct 2025 19:25:22 +0100 Subject: [PATCH 0966/3801] add `MaybeDangling` to `core` Co-authored-by: Ralf Jung --- library/core/src/mem/maybe_dangling.rs | 113 +++++++++++++++++++++++++ library/core/src/mem/mod.rs | 4 + 2 files changed, 117 insertions(+) create mode 100644 library/core/src/mem/maybe_dangling.rs diff --git a/library/core/src/mem/maybe_dangling.rs b/library/core/src/mem/maybe_dangling.rs new file mode 100644 index 000000000000..3a8af8cc7bd8 --- /dev/null +++ b/library/core/src/mem/maybe_dangling.rs @@ -0,0 +1,113 @@ +#![unstable(feature = "maybe_dangling", issue = "118166")] + +use crate::{mem, ptr}; + +/// Allows wrapped [references] and [boxes] to dangle. +/// +///